diff --git a/.circleci/config.yml b/.circleci/config.yml index 0ce68b36d901..eec1b4b1434c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,8 +4,8 @@ jobs: arm: resource_class: arm.medium docker: - - image: cimg/base:current-22.04 - - image: mysql:8.3 + - image: cimg/base:current-24.04 + - image: mysql:8.4 environment: MYSQL_ALLOW_EMPTY_PASSWORD: true MYSQL_ROOT_PASSWORD: '' @@ -60,7 +60,7 @@ jobs: libreadline-dev \ libldap2-dev \ libsodium-dev \ - libargon2-0-dev \ + libargon2-dev \ libmm-dev \ libsnmp-dev \ snmpd \ @@ -78,7 +78,7 @@ jobs: libqdbm-dev \ libjpeg-dev \ libpng-dev \ - libfreetype6-dev + libfreetype-dev - run: name: ./configure command: | @@ -90,7 +90,6 @@ jobs: --prefix=/usr \ --enable-phpdbg \ --enable-fpm \ - --enable-opcache \ --with-pdo-mysql=mysqlnd \ --with-mysqli=mysqlnd \ --with-pgsql \ @@ -167,8 +166,8 @@ jobs: name: Test no_output_timeout: 30m command: | + export RUN_RESOURCE_HEAVY_TESTS=1 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=tracing \ diff --git a/.gdbinit b/.gdbinit index c4705b2f59a9..4477828265e0 100644 --- a/.gdbinit +++ b/.gdbinit @@ -42,7 +42,7 @@ define print_cvs printf "Compiled variables count: %d\n\n", $cv_count while $cv_idx < $cv_count - printf "[%d] '%s'\n", $cv_idx, $cv[$cv_idx].val + printf "[%d] '$%s'\n", $cv_idx, $cv[$cv_idx].val@$cv[$cv_idx].len set $zvalue = ((zval *) $cv_ex_ptr) + $callFrameSize + $cv_idx printzv $zvalue set $cv_idx = $cv_idx + 1 diff --git a/.gitattributes b/.gitattributes index 8dea3f8bbafb..74fd9f995e8d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -21,6 +21,7 @@ # Collapse generated files within git and pull request diff. **/*_arginfo.h linguist-generated -diff +**/*_decl.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 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2bd2f6d94ef9..d5f4a8a6f4bb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -16,19 +16,19 @@ /.github @TimWolla /build/gen_stub.php @kocsismate -/ext/bcmath @Girgias @nielsdos @SakiTakamachi +/ext/bcmath @SakiTakamachi /ext/curl @adoy /ext/date @derickr /ext/dba @Girgias -/ext/dom @nielsdos +/ext/dom @devnexen /ext/ffi @dstogov /ext/gd @devnexen /ext/gettext @devnexen /ext/gmp @Girgias /ext/intl @devnexen +/ext/libxml @devnexen /ext/json @bukka -/ext/lexbor @kocsismate @nielsdos -/ext/libxml @nielsdos +/ext/lexbor @kocsismate /ext/mbstring @alexdowad @youkidearitai /ext/mysqli @bukka @kamil-tekiela /ext/mysqlnd @bukka @kamil-tekiela @SakiTakamachi @@ -47,16 +47,16 @@ /ext/random @TimWolla @zeriyoshi /ext/reflection @DanielEScherzer /ext/session @Girgias -/ext/simplexml @nielsdos -/ext/soap @nielsdos +/ext/simplexml @devnexen +/ext/soap @devnexen /ext/sockets @devnexen /ext/spl @Girgias /ext/standard @bukka -/ext/uri @kocsismate -/ext/xml @nielsdos -/ext/xmlreader @nielsdos -/ext/xmlwriter @nielsdos -/ext/xsl @nielsdos +/ext/uri @kocsismate @TimWolla +/ext/xml @devnexen +/ext/xmlreader @devnexen +/ext/xmlwriter @devnexen +/ext/xsl @devnexen /main @bukka /sapi/fpm @bukka /Zend/Optimizer @dstogov diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 53bd4df5a1ca..296835e02e0d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -26,14 +26,15 @@ body: 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 run PHP with the `-v` flag (e.g. `php -v`, `php8.5 -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 + PHP 8.5.2 (cli) (built: Jan 21 2026 17:35:28) (NTS) + Copyright © The PHP Group and Contributors + Built by Ubuntu + Zend Engine v4.5.2, Copyright © Zend by Perforce + with Zend OPcache v8.5.2, Copyright ©, Zend by Perforce render: plain validations: required: true diff --git a/.github/actions/apk/action.yml b/.github/actions/apk/action.yml index 039fc64a5491..0cda4963a6a9 100644 --- a/.github/actions/apk/action.yml +++ b/.github/actions/apk/action.yml @@ -6,6 +6,11 @@ runs: run: | set -x + OPCACHE_TLS_TESTS_DEPS="clang gcc binutils-gold lld" + # compiler-rt provides libclang_rt.asan-x86_64.a for clang20 + # https://pkgs.alpinelinux.org/contents?file=libclang_rt.asan-x86_64.a&path=&name=&branch=v3.22 + ASAN_DEPS="clang20 compiler-rt" + apk update -q apk add \ util-linux \ @@ -50,7 +55,9 @@ runs: net-snmp-dev \ openldap-dev \ unixodbc-dev \ - postgresql14-dev \ + postgresql-dev \ tzdata \ musl-locales \ - musl-locales-lang + musl-locales-lang \ + $OPCACHE_TLS_TESTS_DEPS \ + $ASAN_DEPS diff --git a/.github/actions/apt-x32/action.yml b/.github/actions/apt-x32/action.yml index 39ef1df6c2c8..14182e768795 100644 --- a/.github/actions/apt-x32/action.yml +++ b/.github/actions/apt-x32/action.yml @@ -6,6 +6,8 @@ runs: run: | set -x + OPCACHE_TLS_TESTS_DEPS="gcc clang lld" + export DEBIAN_FRONTEND=noninteractive dpkg --add-architecture i386 apt-get update -y | true @@ -35,7 +37,6 @@ runs: libssl-dev:i386 \ libwebp-dev:i386 \ libxml2-dev:i386 \ - libxml2-dev:i386 \ libxpm-dev:i386 \ libxslt1-dev:i386 \ firebird-dev:i386 \ @@ -45,4 +46,5 @@ runs: re2c \ unzip \ wget \ - zlib1g-dev:i386 + zlib1g-dev:i386 \ + $OPCACHE_TLS_TESTS_DEPS diff --git a/.github/actions/apt-x64/action.yml b/.github/actions/apt-x64/action.yml index a2ef014c5faa..7ae0a88ff755 100644 --- a/.github/actions/apt-x64/action.yml +++ b/.github/actions/apt-x64/action.yml @@ -10,6 +10,8 @@ runs: run: | set -x + OPCACHE_TLS_TESTS_DEPS="gcc clang lld" + export DEBIAN_FRONTEND=noninteractive # Install sudo in Docker for consistent actions @@ -74,4 +76,5 @@ runs: libqdbm-dev \ libjpeg-dev \ libpng-dev \ - libfreetype6-dev + libfreetype6-dev \ + $OPCACHE_TLS_TESTS_DEPS diff --git a/.github/actions/brew/action.yml b/.github/actions/brew/action.yml index 07595a5ada93..f90a66f239de 100644 --- a/.github/actions/brew/action.yml +++ b/.github/actions/brew/action.yml @@ -13,11 +13,18 @@ runs: # Some packages exist on x86 but not arm, or vice versa. # Install them with reinstall to avoid warnings. - brew reinstall autoconf webp tidy-html5 libzip libsodium icu4c curl - brew install \ + brew reinstall -v \ + autoconf \ + webp \ + tidy-html5 \ + libzip \ + libsodium \ + icu4c \ + curl + brew install -v \ bison \ re2c - brew install \ + brew install -v \ bzip2 \ enchant \ libffi \ diff --git a/.github/actions/build-libmysqlclient/action.yml b/.github/actions/build-libmysqlclient/action.yml index bab2bc544a12..632c1e8ea16b 100644 --- a/.github/actions/build-libmysqlclient/action.yml +++ b/.github/actions/build-libmysqlclient/action.yml @@ -5,8 +5,6 @@ inputs: required: false libmysql: required: true - withMysqli: - required: true runs: using: composite steps: @@ -21,13 +19,11 @@ runs: wget -nv $URL tar -xf $LIBMYSQL --strip-components=1 -C $MYSQL_DIR PDO_MYSQL=${MYSQL_DIR} - ${{ inputs.withMysqli == 'true' && 'MYSQLI=${MYSQL_DIR}/bin/mysql_config' || '' }} ./buildconf --force ./configure ${{ inputs.configurationParameters }} \ --enable-option-checking=fatal \ --disable-all \ --enable-pdo \ - --with-pdo-mysql=${PDO_MYSQL} \ - ${{ inputs.withMysqli == 'true' && '--with-mysqli=${MYSQLI}' || '' }} + --with-pdo-mysql=${PDO_MYSQL} make clean make -j$(/usr/bin/nproc) >/dev/null diff --git a/.github/actions/ccache/action.yml b/.github/actions/ccache/action.yml new file mode 100644 index 000000000000..a73a6cbe1e7d --- /dev/null +++ b/.github/actions/ccache/action.yml @@ -0,0 +1,39 @@ +name: ccache +inputs: + name: + required: true + php_directory: + required: false + default: '.' + cc: + required: false + default: 'gcc' + cxx: + required: false + default: 'g++' +runs: + using: composite + steps: + - name: Get cache key + shell: bash + id: cache_key + run: | + major=$(cat ${{ inputs.php_directory }}/main/php_version.h | sed -En 's/^#define PHP_MAJOR_VERSION ([0-9]+)/\1/p') + minor=$(cat ${{ inputs.php_directory }}/main/php_version.h | sed -En 's/^#define PHP_MINOR_VERSION ([0-9]+)/\1/p') + release=$(cat ${{ inputs.php_directory }}/main/php_version.h | sed -En 's/^#define PHP_RELEASE_VERSION ([0-9]+)/\1/p') + week=$(date +"%Y-%W") + prefix="${{ inputs.name }}-$major.$minor.$release" + echo "key=$prefix-$week" >> $GITHUB_OUTPUT + echo "prefix=$prefix-" >> $GITHUB_OUTPUT + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: "${{ steps.cache_key.outputs.key }}" + append-timestamp: false + restore-keys: "${{ steps.cache_key.outputs.prefix }}" + save: ${{ github.event_name != 'pull_request' }} + - name: Export CC/CXX + shell: bash + run: | + echo "CC=ccache ${{ inputs.cc }}" >> $GITHUB_ENV + echo "CXX=ccache ${{ inputs.cxx }}" >> $GITHUB_ENV diff --git a/.github/actions/configure-macos/action.yml b/.github/actions/configure-macos/action.yml index b318f2272515..f0af959d2102 100644 --- a/.github/actions/configure-macos/action.yml +++ b/.github/actions/configure-macos/action.yml @@ -11,7 +11,7 @@ runs: 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/openssl/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" diff --git a/.github/actions/configure-unit-tests/action.yml b/.github/actions/configure-unit-tests/action.yml new file mode 100644 index 000000000000..ef8239b7111c --- /dev/null +++ b/.github/actions/configure-unit-tests/action.yml @@ -0,0 +1,10 @@ +name: ./configure (unit tests) +description: Configure PHP with minimal settings for unit testing +runs: + using: composite + steps: + - shell: bash + run: | + set -x + ./buildconf --force + ./configure --disable-all --enable-embed=static diff --git a/.github/actions/extra-tests/action.yml b/.github/actions/extra-tests/action.yml new file mode 100644 index 000000000000..053749606400 --- /dev/null +++ b/.github/actions/extra-tests/action.yml @@ -0,0 +1,7 @@ +name: Extra tests +runs: + using: composite + steps: + - shell: sh + run: | + sapi/cli/php run-extra-tests.php diff --git a/.github/actions/freebsd/action.yml b/.github/actions/freebsd/action.yml index d375a51a6d17..197362d9f52b 100644 --- a/.github/actions/freebsd/action.yml +++ b/.github/actions/freebsd/action.yml @@ -1,18 +1,28 @@ name: FreeBSD +inputs: + configurationParameters: + default: '' + required: false + runExtraTests: + default: false + required: false runs: using: composite steps: - name: FreeBSD uses: vmactions/freebsd-vm@v1 with: - release: '13.3' + release: '13.5' usesh: true copyback: false + disable-cache: true # Temporarily disable sqlite, as FreeBSD ships it with disabled double quotes. We'll need to fix our tests. # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=269889 prepare: | cd $GITHUB_WORKSPACE + OPCACHE_TLS_TESTS_DEPS="gcc" + kldload accf_http pkg install -y \ autoconf \ @@ -36,18 +46,18 @@ runs: pkgconf \ webp \ libavif \ - `#sqlite3` \ - curl + sqlite3 \ + curl \ + $OPCACHE_TLS_TESTS_DEPS ./buildconf -f + CC=clang CXX=clang++ \ ./configure \ --prefix=/usr/local \ --enable-debug \ --enable-option-checking=fatal \ --enable-fpm \ - `#--with-pdo-sqlite` \ - --without-sqlite3 \ - --without-pdo-sqlite \ + --with-pdo-sqlite \ --without-pear \ --with-bz2 \ --with-avif \ @@ -80,7 +90,9 @@ runs: --with-sodium \ --enable-werror \ --with-config-file-path=/etc \ - --with-config-file-scan-dir=/etc/php.d + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.configurationParameters }} + gmake -j2 mkdir /etc/php.d gmake install > /dev/null @@ -93,6 +105,7 @@ runs: export SKIP_IO_CAPTURE_TESTS=1 export CI_NO_IPV6=1 export STACK_LIMIT_DEFAULTS_CHECK=1 + export RUN_RESOURCE_HEAVY_TESTS=1 sapi/cli/php run-tests.php \ -P -q -j2 \ -g FAIL,BORK,LEAK,XLEAK \ @@ -100,5 +113,8 @@ runs: --offline \ --show-diff \ --show-slow 1000 \ - --set-timeout 120 \ - -d zend_extension=opcache.so + --set-timeout 120 + + if test "${{ inputs.runExtraTests }}" = "true"; then + sapi/cli/php run-extra-tests.php + fi diff --git a/.github/actions/macos-update-clang/action.yml b/.github/actions/macos-update-clang/action.yml new file mode 100644 index 000000000000..916b4dfe41f4 --- /dev/null +++ b/.github/actions/macos-update-clang/action.yml @@ -0,0 +1,17 @@ +name: Update clang +runs: + using: composite + steps: + - shell: bash + run: | + softwareupdate -l + label=$((softwareupdate -l 2>/dev/null | grep 'Label:' | grep -o 'Command Line Tools for Xcode.*' | head -1) || echo '') + if [ -n "$label" ]; then + softwareupdate -i "$label" + xcode_path=$(ls -1 '/Applications' | grep 'Xcode_.*\.app' | sort -r | head -1) + sudo xcode-select -s "/Applications/$xcode_path" + else + echo "Not found." + fi + which clang + clang -v diff --git a/.github/actions/notify-slack/action.yml b/.github/actions/notify-slack/action.yml deleted file mode 100644 index 1ff425b51c6a..000000000000 --- a/.github/actions/notify-slack/action.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: Notify Slack -inputs: - token: - required: true -runs: - using: composite - steps: - - shell: bash - run: >- - curl -X POST -H 'Content-type: application/json' --data '{"attachments": [{"text": "Job in *nightly* failed", "footer": "", "color": "danger", "mrkdwn_in": ["text"]}]}' ${{ inputs.token }} diff --git a/.github/actions/setup-mssql/action.yml b/.github/actions/setup-mssql/action.yml index dd372a5637aa..cbd220d0b29e 100644 --- a/.github/actions/setup-mssql/action.yml +++ b/.github/actions/setup-mssql/action.yml @@ -11,4 +11,4 @@ runs: -p 1433:1433 \ --name sql1 \ -h sql1 \ - -d mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 + -d mcr.microsoft.com/mssql/server:2025-latest diff --git a/.github/actions/setup-windows/action.yml b/.github/actions/setup-windows/action.yml index e0a3fd4e7d31..a5fa4cdddcb1 100644 --- a/.github/actions/setup-windows/action.yml +++ b/.github/actions/setup-windows/action.yml @@ -16,5 +16,6 @@ runs: - name: Setup PostgreSQL shell: pwsh run: | - Set-Service -Name "postgresql-x64-14" -StartupType manual -Status Running + $postgresService = if ($env:PHP_BUILD_CRT -eq "vs18") { "postgresql-x64-17" } else { "postgresql-x64-14" } + Set-Service -Name $postgresService -StartupType manual -Status Running pwsh -Command { $env:PGPASSWORD="root"; & "$env:PGBIN\psql" -U postgres -c "ALTER USER postgres WITH PASSWORD 'Password12!';" } diff --git a/.github/actions/solaris/action.yml b/.github/actions/solaris/action.yml new file mode 100644 index 000000000000..ef7cffe32abc --- /dev/null +++ b/.github/actions/solaris/action.yml @@ -0,0 +1,88 @@ +name: Solaris +inputs: + configurationParameters: + default: '' + required: false + runExtraTests: + default: false + required: false +runs: + using: composite + steps: + - name: Solaris + uses: vmactions/solaris-vm@v1 + with: + release: "11.4-gcc" + usesh: true + copyback: false + disable-cache: true + prepare: | + cd $GITHUB_WORKSPACE + pkg install bison developer/icu libzip oniguruma re2c + + ./buildconf -f + CC=gcc CXX=g++ \ + CFLAGS="-Wno-char-subscripts" \ + PATH=/usr/gnu/bin:/usr/bin \ + PKG_CONFIG_PATH=/usr/lib/amd64/pkgconfig \ + ./configure \ + --prefix=/usr/local \ + --enable-debug \ + --enable-werror \ + --enable-option-checking=fatal \ + --enable-fpm \ + --without-pear \ + --with-bz2 \ + --with-jpeg \ + --with-webp \ + --with-freetype \ + --enable-gd \ + --enable-exif \ + --with-zip \ + --with-zlib \ + --enable-soap \ + --enable-xmlreader \ + --with-xsl \ + --with-libxml \ + --enable-shmop \ + --enable-pcntl \ + --enable-mbstring \ + --with-curl \ + --enable-sockets \ + --with-openssl \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + --enable-zend-test \ + --enable-dl-test=shared \ + --enable-intl \ + --with-mhash \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + ${{ inputs.configurationParameters }} + + gmake -j2 + mkdir /etc/php.d + gmake install > /dev/null + echo opcache.enable_cli=1 > /etc/php.d/opcache.ini + echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini + echo opcache.preload_user=root >> /etc/php.d/opcache.ini + run: | + cd $GITHUB_WORKSPACE + + export SKIP_IO_CAPTURE_TESTS=1 + export CI_NO_IPV6=1 + export STACK_LIMIT_DEFAULTS_CHECK=1 + PATH=/usr/gnu/bin:/usr/bin \ + sapi/cli/php run-tests.php \ + -P -q -j1 \ + -g FAIL,BORK,LEAK,XLEAK \ + --no-progress \ + --offline \ + --show-diff \ + --show-slow 1000 \ + --set-timeout 120 + + if test "${{ inputs.runExtraTests }}" = "true"; then + sapi/cli/php run-extra-tests.php + fi diff --git a/.github/actions/test-alpine/action.yml b/.github/actions/test-alpine/action.yml index e14e3176b8ef..5911c6ce57f2 100644 --- a/.github/actions/test-alpine/action.yml +++ b/.github/actions/test-alpine/action.yml @@ -3,6 +3,9 @@ inputs: runTestsParameters: default: '' required: false + enableOpcache: + default: 'false' + required: false jitType: default: 'disable' required: false @@ -15,6 +18,7 @@ runs: export SKIP_IO_CAPTURE_TESTS=1 export STACK_LIMIT_DEFAULTS_CHECK=1 sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + ${{ inputs.enableOpcache == 'true' && '-d opcache.enable_cli=1' || '' }} \ -d opcache.jit=${{ inputs.jitType }} \ -d opcache.jit_buffer_size=64M \ -j$(nproc) \ diff --git a/.github/actions/test-gentoo/action.yml b/.github/actions/test-gentoo/action.yml index ec9fb0b70c6a..f71738421800 100644 --- a/.github/actions/test-gentoo/action.yml +++ b/.github/actions/test-gentoo/action.yml @@ -25,6 +25,7 @@ runs: # Slow tests criteron is doubled because this runner isn't as fast as others export SKIP_IO_CAPTURE_TESTS=1 export STACK_LIMIT_DEFAULTS_CHECK=1 + export RUN_RESOURCE_HEAVY_TESTS=1 sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ -j$(nproc) \ -g FAIL,BORK,LEAK,XLEAK \ diff --git a/.github/actions/test-libmysqlclient/action.yml b/.github/actions/test-libmysqlclient/action.yml index 74474225e670..3ab4aeb43db9 100644 --- a/.github/actions/test-libmysqlclient/action.yml +++ b/.github/actions/test-libmysqlclient/action.yml @@ -1,19 +1,15 @@ name: Test libmysqlclient -inputs: - withMysqli: - required: true runs: using: composite steps: - shell: bash run: | set -x - ${{ inputs.withMysqli == 'true' && 'export MYSQL_TEST_USER=root' || '' }} - ${{ inputs.withMysqli == 'true' && 'export MYSQL_TEST_PASSWD=root' || '' }} export PDO_MYSQL_TEST_DSN="mysql:host=127.0.0.1;dbname=test" export PDO_MYSQL_TEST_HOST=127.0.0.1 export PDO_MYSQL_TEST_USER=root export PDO_MYSQL_TEST_PASS=root + export RUN_RESOURCE_HEAVY_TESTS=1 sapi/cli/php run-tests.php -P -q \ -g FAIL,BORK,LEAK,XLEAK \ --no-progress --offline --show-diff --show-slow 1000 --set-timeout 120 \ diff --git a/.github/actions/test-linux/action.yml b/.github/actions/test-linux/action.yml index a5bf49bd0015..e89c942d52e1 100644 --- a/.github/actions/test-linux/action.yml +++ b/.github/actions/test-linux/action.yml @@ -3,6 +3,9 @@ inputs: runTestsParameters: default: '' required: false + enableOpcache: + default: 'false' + required: false jitType: default: 'disable' required: false @@ -41,7 +44,9 @@ runs: export PDO_ODBC_TEST_DSN="odbc:Driver={ODBC Driver 17 for SQL Server};Server=127.0.0.1;Database=pdo_odbc;uid=$ODBC_TEST_USER;pwd=$ODBC_TEST_PASS" export SKIP_IO_CAPTURE_TESTS=1 export STACK_LIMIT_DEFAULTS_CHECK=1 + export RUN_RESOURCE_HEAVY_TESTS=1 sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + ${{ inputs.enableOpcache == 'true' && '-d opcache.enable_cli=1' || '' }} \ -d opcache.jit=${{ inputs.jitType }} \ -d opcache.protect_memory=1 \ -d opcache.jit_buffer_size=64M \ diff --git a/.github/actions/test-macos/action.yml b/.github/actions/test-macos/action.yml index e24190fef80a..166bb3103c08 100644 --- a/.github/actions/test-macos/action.yml +++ b/.github/actions/test-macos/action.yml @@ -3,6 +3,9 @@ inputs: runTestsParameters: default: '' required: false + enableOpcache: + default: 'false' + required: false jitType: default: 'disable' required: false @@ -15,7 +18,9 @@ runs: export SKIP_IO_CAPTURE_TESTS=1 export CI_NO_IPV6=1 export STACK_LIMIT_DEFAULTS_CHECK=1 + export RUN_RESOURCE_HEAVY_TESTS=1 sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ + ${{ inputs.enableOpcache == 'true' && '-d opcache.enable_cli=1' || '' }} \ -d opcache.jit=${{ inputs.jitType }} \ -d opcache.protect_memory=1 \ -d opcache.jit_buffer_size=64M \ diff --git a/.github/actions/verify-generated-files/action.yml b/.github/actions/verify-generated-files/action.yml index 5228105f2590..79c49dbfcfff 100644 --- a/.github/actions/verify-generated-files/action.yml +++ b/.github/actions/verify-generated-files/action.yml @@ -12,5 +12,5 @@ runs: Zend/zend_vm_gen.php ext/tokenizer/tokenizer_data_gen.php build/gen_stub.php -f --generate-optimizer-info --verify - # 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 + ext/phar/makestub.php + .github/scripts/test-directory-unchanged.sh . diff --git a/.github/labeler.yml b/.github/labeler.yml index 40ac864fd56c..e9731352c8cc 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -20,6 +20,18 @@ - scripts/**/* - win32/build/**/* +"Category: CI": + - changed-files: + - any-glob-to-any-file: + - .circleci/* + - .github/actions/**/* + - .github/scripts/**/* + - .github/workflows/* + - .github/CODEOWNERS + - .github/labeler.yml + - .github/setup_hmailserver.php + - .github/matrix.php + "Extension: bcmath": - changed-files: - any-glob-to-any-file: @@ -469,7 +481,6 @@ - 'ext/pdo/php_pdo.h' - 'ext/pdo/php_pdo_driver.h' - 'ext/pdo/php_pdo_error.h' - - 'ext/phar/php_phar.h' - 'ext/random/php_random.h' - 'ext/random/php_random_csprng.h' - 'ext/random/php_random_uint128.h' @@ -493,6 +504,7 @@ - 'ext/spl/spl_iterators.h' - 'ext/spl/spl_observer.h' - 'ext/standard/*.h' + - 'ext/uri/*.h' - 'ext/xml/expat_compat.h' - 'ext/xml/php_xml.h' - 'main/*.h' diff --git a/.github/matrix.php b/.github/matrix.php new file mode 100644 index 000000000000..7970442d7050 --- /dev/null +++ b/.github/matrix.php @@ -0,0 +1,204 @@ + 'master', 'ref' => 'master', 'version' => [8, 6]], + ['name' => 'PHP-8.5', 'ref' => 'PHP-8.5', 'version' => [8, 5]], + ['name' => 'PHP-8.4', 'ref' => 'PHP-8.4', 'version' => [8, 4]], + ['name' => 'PHP-8.3', 'ref' => 'PHP-8.3', 'version' => [8, 3]], + ['name' => 'PHP-8.2', 'ref' => 'PHP-8.2', 'version' => [8, 2]], +]; + +function get_branch_commit_cache_file_path(): string { + return dirname(__DIR__) . '/branch-commit-cache.json'; +} + +function get_branches() { + $branch_commit_cache_file = get_branch_commit_cache_file_path(); + $branch_commit_map = []; + if (file_exists($branch_commit_cache_file)) { + $branch_commit_map = json_decode(file_get_contents($branch_commit_cache_file), JSON_THROW_ON_ERROR); + } + + $changed_branches = []; + foreach (BRANCHES as $branch) { + $previous_commit_hash = $branch_commit_map[$branch['ref']] ?? null; + $current_commit_hash = trim(shell_exec('git rev-parse origin/' . $branch['ref'])); + + if ($previous_commit_hash !== $current_commit_hash) { + $changed_branches[] = $branch; + } + + $branch_commit_map[$branch['ref']] = $current_commit_hash; + } + + file_put_contents($branch_commit_cache_file, json_encode($branch_commit_map)); + + return $changed_branches; +} + +function get_current_version(): array { + $file = dirname(__DIR__) . '/main/php_version.h'; + $content = file_get_contents($file); + preg_match('(^#define PHP_MAJOR_VERSION (?\d+)$)m', $content, $matches); + $major = (int) $matches['num']; + preg_match('(^#define PHP_MINOR_VERSION (?\d+)$)m', $content, $matches); + $minor = (int) $matches['num']; + return [$major, $minor]; +} + +function select_jobs($repository, $trigger, $nightly, $labels, $php_version, $ref, $all_variations) { + $no_jobs = in_array('CI: No jobs', $labels, true); + $all_jobs = in_array('CI: All jobs', $labels, true) || $nightly; + $test_alpine = in_array('CI: Alpine', $labels, true); + $test_benchmarking = in_array('CI: Benchmarking', $labels, true); + $test_community = in_array('CI: Community', $labels, true); + $test_coverage = in_array('CI: Coverage', $labels, true); + $test_freebsd = in_array('CI: FreeBSD', $labels, true); + $test_libmysqlclient = in_array('CI: libmysqlclient', $labels, true); + $test_linux_ppc64 = in_array('CI: Linux PPC64', $labels, true); + $test_linux_x32 = in_array('CI: Linux X32', $labels, true); + $test_linux_x64 = in_array('CI: Linux X64', $labels, true); + $test_macos = in_array('CI: macOS', $labels, true); + $test_msan = in_array('CI: MSAN', $labels, true); + $test_opcache_variation = in_array('CI: Opcache Variation', $labels, true); + $test_solaris = in_array('CI: Solaris', $labels, true); + $test_windows = in_array('CI: Windows', $labels, true); + + $jobs = []; + if (version_compare($php_version, '8.4', '>=') && ($all_jobs || !$no_jobs || $test_alpine)) { + $jobs['ALPINE'] = true; + } + if (version_compare($php_version, '8.4', '>=') + && !$nightly + && ($all_jobs || !$no_jobs || $test_benchmarking) + // push trigger is restricted to official repository. + && ($repository === 'php/php-src' || $trigger === 'pull_request')) { + $jobs['BENCHMARKING']['config']['integrated_opcache'] = version_compare($php_version, '8.5', '>='); + } + if ($all_jobs || $test_community) { + $jobs['COMMUNITY']['matrix'] = version_compare($php_version, '8.4', '>=') + ? ['type' => ['asan', 'verify_type_inference']] + : ['type' => ['asan']]; + $jobs['COMMUNITY']['config']['symfony_version'] = match (true) { + version_compare($php_version, '8.3', '<=') => '7.4', + default => '', + }; + $jobs['COMMUNITY']['config']['laravel_version'] = match (true) { + version_compare($php_version, '8.2', '<=') => '12.x', + default => '', + }; + } + if (($all_jobs && $ref === 'master') || $test_coverage) { + $jobs['COVERAGE'] = true; + } + if ($all_jobs || $test_libmysqlclient) { + $jobs['LIBMYSQLCLIENT'] = true; + } + if (version_compare($php_version, '8.4', '>=') && ($all_jobs || $test_linux_ppc64)) { + $jobs['LINUX_PPC64'] = true; + } + if ($all_jobs || !$no_jobs || $test_linux_x64) { + $jobs['LINUX_X64']['matrix'] = $all_variations + ? [ + 'name' => [''], + 'asan' => [false], + 'debug' => [true, false], + 'repeat' => [false], + 'variation' => [false], + 'zts' => [true, false], + 'include' => [ + ['name' => '_ASAN', 'asan' => true, 'debug' => true, 'repeat' => false, 'variation' => false, 'zts' => true], + ['name' => '_REPEAT', 'asan' => false, 'debug' => true, 'repeat' => true, 'variation' => false, 'zts' => false], + ['name' => '_VARIATION', 'asan' => false, 'debug' => true, 'repeat' => false, 'variation' => true, 'zts' => true], + ], + ] + : ['include' => [ + ['name' => '', 'asan' => false, 'debug' => false, 'repeat' => false, 'variation' => false, 'zts' => false], + ['name' => '_ASAN', 'asan' => true, 'debug' => true, 'repeat' => false, 'variation' => false, 'zts' => true], + ]]; + $jobs['LINUX_X64']['config']['variation_enable_zend_max_execution_timers'] = version_compare($php_version, '8.3', '>='); + } + if ($all_jobs || !$no_jobs || $test_linux_x32) { + $jobs['LINUX_X32']['matrix'] = $all_variations + ? ['debug' => [true, false], 'zts' => [true, false]] + : ['debug' => [true], 'zts' => [true]]; + } + if ($all_jobs || !$no_jobs || $test_macos) { + $test_arm = version_compare($php_version, '8.4', '>='); + $jobs['MACOS']['matrix'] = $all_variations + ? ['arch' => $test_arm ? ['X64', 'ARM64'] : ['X64'], 'debug' => [true, false], 'zts' => [true, false]] + : ['include' => [['arch' => $test_arm ? 'ARM64' : 'X64', 'debug' => true, 'zts' => false]]]; + $jobs['MACOS']['config']['arm64_version'] = version_compare($php_version, '8.4', '>=') ? '15' : '14'; + } + if ($all_jobs || $test_msan) { + $jobs['MSAN'] = true; + } + if ($all_jobs || $test_opcache_variation) { + $jobs['OPCACHE_VARIATION'] = true; + } + if (version_compare($php_version, '8.6', '>=') && ($all_jobs || $test_solaris)) { + $jobs['SOLARIS'] = true; + } + if ($all_jobs || !$no_jobs || $test_windows) { + $matrix = [['asan' => false, 'opcache' => true, 'x64' => true, 'zts' => true]]; + if ($all_variations) { + $matrix[] = ['asan' => true, 'opcache' => true, 'x64' => true, 'zts' => true]; + $matrix[] = ['asan' => false, 'opcache' => false, 'x64' => false, 'zts' => false]; + if (version_compare($php_version, '8.6', '>=')) { + $matrix[] = ['asan' => false, 'opcache' => true, 'x64' => true, 'zts' => true, 'clang' => true]; + } + } + $jobs['WINDOWS']['matrix'] = ['include' => $matrix]; + $jobs['WINDOWS']['config'] = match (true) { + version_compare($php_version, '8.6', '>=') => ['vs_crt_version' => 'vs18', 'runs_on' => 'windows-2025-vs2026'], + version_compare($php_version, '8.4', '>=') => ['vs_crt_version' => 'vs17', 'runs_on' => 'windows-2022'], + default => ['vs_crt_version' => 'vs16', 'runs_on' => 'windows-2022'], + }; + } + if ($all_jobs || !$no_jobs || $test_freebsd) { + $jobs['FREEBSD']['matrix'] = $all_variations && version_compare($php_version, '8.3', '>=') + ? ['zts' => [true, false]] + : ['zts' => [false]]; + } + return $jobs; +} + +$trigger = $argv[1] ?? 'schedule'; +$attempt = (int) ($argv[2] ?? 1); +$sunday = date('w', time()) === '0'; +$discard_cache = $sunday + || ($trigger === 'schedule' && $attempt !== 1) + || $trigger === 'workflow_dispatch'; +if ($discard_cache) { + @unlink(get_branch_commit_cache_file_path()); +} +$branch = $argv[3] ?? 'master'; +$nightly = $trigger === 'schedule' || $trigger === 'workflow_dispatch'; +$branches = $nightly && $branch === 'master' + ? get_branches() + : [['name' => 'Suite', 'ref' => $branch, 'version' => get_current_version()]]; + +$labels = json_decode($argv[4] ?? '[]', true) ?? []; +$labels = array_column($labels, 'name'); +$all_variations = $nightly || in_array('CI: All variations', $labels, true); + +$repository = $argv[5] ?? null; + +foreach ($branches as &$branch) { + $php_version = $branch['version'][0] . '.' . $branch['version'][1]; + $branch['jobs'] = select_jobs($repository, $trigger, $nightly, $labels, $php_version, $branch['ref'], $all_variations); + $branch['config']['ubuntu_version'] = version_compare($php_version, '8.5', '>=') ? '24.04' : '22.04'; +} + +echo "All variations:"; +echo json_encode($all_variations, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT); +echo "\n\nBranches:\n"; +echo json_encode($branches, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT); +echo "\n"; + +if (false !== ($github_output = getenv('GITHUB_OUTPUT'))) { + $f = fopen($github_output, 'a'); + fwrite($f, 'branches=' . json_encode($branches, JSON_UNESCAPED_SLASHES) . "\n"); + fwrite($f, 'all_variations=' . json_encode($all_variations, JSON_UNESCAPED_SLASHES) . "\n"); + fclose($f); +} diff --git a/.github/nightly_matrix.php b/.github/nightly_matrix.php deleted file mode 100644 index 311176ef5e53..000000000000 --- a/.github/nightly_matrix.php +++ /dev/null @@ -1,65 +0,0 @@ - 'master', 'version' => [8, 5]], - ['ref' => 'PHP-8.4', 'version' => [8, 4]], - ['ref' => 'PHP-8.3', 'version' => [8, 3]], - ['ref' => 'PHP-8.2', 'version' => [8, 2]], - ['ref' => 'PHP-8.1', 'version' => [8, 1]], -]; - -function get_branch_commit_cache_file_path(): string { - return dirname(__DIR__) . '/branch-commit-cache.json'; -} - -function get_branches() { - $branch_commit_cache_file = get_branch_commit_cache_file_path(); - $branch_commit_map = []; - if (file_exists($branch_commit_cache_file)) { - $branch_commit_map = json_decode(file_get_contents($branch_commit_cache_file), JSON_THROW_ON_ERROR); - } - - $changed_branches = []; - foreach (BRANCHES as $branch) { - $previous_commit_hash = $branch_commit_map[$branch['ref']] ?? null; - $current_commit_hash = trim(shell_exec('git rev-parse origin/' . $branch['ref'])); - - if ($previous_commit_hash !== $current_commit_hash) { - $changed_branches[] = $branch; - } - - $branch_commit_map[$branch['ref']] = $current_commit_hash; - } - - file_put_contents($branch_commit_cache_file, json_encode($branch_commit_map)); - - return $changed_branches; -} - -function get_current_version(): array { - $file = dirname(__DIR__) . '/main/php_version.h'; - $content = file_get_contents($file); - preg_match('(^#define PHP_MAJOR_VERSION (?\d+)$)m', $content, $matches); - $major = (int) $matches['num']; - preg_match('(^#define PHP_MINOR_VERSION (?\d+)$)m', $content, $matches); - $minor = (int) $matches['num']; - return [$major, $minor]; -} - -$trigger = $argv[1] ?? 'schedule'; -$attempt = (int) ($argv[2] ?? 1); -$monday = date('w', time()) === '1'; -$discard_cache = $monday - || ($trigger === 'schedule' && $attempt !== 1) - || $trigger === 'workflow_dispatch'; -if ($discard_cache) { - @unlink(get_branch_commit_cache_file_path()); -} -$branch = $argv[3] ?? 'master'; -$branches = $branch === 'master' - ? get_branches() - : [['ref' => $branch, 'version' => get_current_version()]]; - -$f = fopen(getenv('GITHUB_OUTPUT'), 'a'); -fwrite($f, 'branches=' . json_encode($branches, JSON_UNESCAPED_SLASHES) . "\n"); -fclose($f); diff --git a/.github/scripts/download-bundled/.gitignore b/.github/scripts/download-bundled/.gitignore new file mode 100644 index 000000000000..69f1bf453095 --- /dev/null +++ b/.github/scripts/download-bundled/.gitignore @@ -0,0 +1 @@ +!*.patch diff --git a/.github/scripts/download-bundled/boost-context.sh b/.github/scripts/download-bundled/boost-context.sh new file mode 100755 index 000000000000..b1fd8708b85b --- /dev/null +++ b/.github/scripts/download-bundled/boost-context.sh @@ -0,0 +1,41 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/boost-context +rm -rf "$tmp_dir" + +revision=refs/tags/boost-1.86.0 + +git clone --depth 1 --revision="$revision" https://github.com/boostorg/context.git "$tmp_dir" + +rm -rf Zend/asm +cp -R "$tmp_dir"/src/asm Zend/asm + +cd Zend/asm + +# remove unneeded files +rm jump_arm_aapcs_pe_armasm.asm +rm jump_i386_ms_pe_clang_gas.S +rm jump_i386_ms_pe_gas.asm +rm jump_i386_x86_64_sysv_macho_gas.S +rm jump_ppc32_ppc64_sysv_macho_gas.S +rm jump_x86_64_ms_pe_clang_gas.S +rm make_arm_aapcs_pe_armasm.asm +rm make_i386_ms_pe_clang_gas.S +rm make_i386_ms_pe_gas.asm +rm make_i386_x86_64_sysv_macho_gas.S +rm make_ppc32_ppc64_sysv_macho_gas.S +rm make_x86_64_ms_pe_clang_gas.S +rm ontop_*.S +rm ontop_*.asm +rm tail_ontop_ppc32_sysv.cpp + +# move renamed files +# GH-13896 introduced these 2 files named as .S but since https://github.com/boostorg/context/pull/265 they are named as .asm +mv jump_x86_64_ms_pe_gas.asm jump_x86_64_ms_pe_gas.S +mv make_x86_64_ms_pe_gas.asm make_x86_64_ms_pe_gas.S + +# add extra files +git restore LICENSE +git restore save_xmm_x86_64_ms_masm.asm # added in GH-18352, not an upstream boost.context file diff --git a/.github/scripts/download-bundled/pcre2.sh b/.github/scripts/download-bundled/pcre2.sh new file mode 100755 index 000000000000..360cbb91db82 --- /dev/null +++ b/.github/scripts/download-bundled/pcre2.sh @@ -0,0 +1,35 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/pcre2 +rm -rf "$tmp_dir" + +revision=refs/tags/pcre2-10.44 + +git clone --depth 1 --recurse-submodules --revision="$revision" https://github.com/PCRE2Project/pcre2.git "$tmp_dir" + +rm -rf ext/pcre/pcre2lib +cp -R "$tmp_dir"/src ext/pcre/pcre2lib + +cd ext/pcre/pcre2lib + +# remove unneeded files +rm config.h.generic +rm pcre2.h.in +rm pcre2_dftables.c +rm pcre2_fuzzsupport.c +rm pcre2_jit_test.c +rm pcre2demo.c +rm pcre2grep.c +rm pcre2posix.c +rm pcre2posix.h +rm pcre2posix_test.c +rm pcre2test.c + +# move renamed files +mv pcre2.h.generic pcre2.h +mv pcre2_chartables.c.dist pcre2_chartables.c + +# add extra files +git restore config.h # based on config.h.generic but with many changes diff --git a/.github/scripts/download-bundled/uriparser.config.patch b/.github/scripts/download-bundled/uriparser.config.patch new file mode 100644 index 000000000000..9742154e5d7c --- /dev/null +++ b/.github/scripts/download-bundled/uriparser.config.patch @@ -0,0 +1,14 @@ +diff --git a/ext/uri/uriparser/src/UriConfig.h b/ext/uri/uriparser/src/UriConfig.h +index b9a85a8..ab78b96 100644 +--- a/ext/uri/uriparser/src/UriConfig.h ++++ b/ext/uri/uriparser/src/UriConfig.h +@@ -41,7 +41,9 @@ + + # define PACKAGE_VERSION "@PROJECT_VERSION@" + ++/* + #cmakedefine HAVE_WPRINTF + #cmakedefine HAVE_REALLOCARRAY ++*/ + + #endif /* !defined(URI_CONFIG_H) */ diff --git a/.github/scripts/download-bundled/uriparser.sh b/.github/scripts/download-bundled/uriparser.sh new file mode 100755 index 000000000000..2b8d61a2d56f --- /dev/null +++ b/.github/scripts/download-bundled/uriparser.sh @@ -0,0 +1,24 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/uriparser +rm -rf "$tmp_dir" + +revision=refs/tags/uriparser-1.0.2 + +git clone --depth 1 --revision="$revision" https://github.com/uriparser/uriparser.git "$tmp_dir" + +rm -rf ext/uri/uriparser +mkdir ext/uri/uriparser +cp -R "$tmp_dir"/src ext/uri/uriparser +cp -R "$tmp_dir"/include ext/uri/uriparser +cp "$tmp_dir"/COPYING.BSD-3-Clause ext/uri/uriparser + +cd ext/uri/uriparser + +# move renamed files +mv src/UriConfig.h.in src/UriConfig.h + +# patch customized files +git apply -v ../../../.github/scripts/download-bundled/uriparser.config.patch diff --git a/.github/scripts/setup-slapd.sh b/.github/scripts/setup-slapd.sh index fcaa67d0a5f7..f6b976783c77 100755 --- a/.github/scripts/setup-slapd.sh +++ b/.github/scripts/setup-slapd.sh @@ -72,6 +72,9 @@ 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 - diff --git a/.github/scripts/test-directory-unchanged.sh b/.github/scripts/test-directory-unchanged.sh new file mode 100755 index 000000000000..20ca410e4ec9 --- /dev/null +++ b/.github/scripts/test-directory-unchanged.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -ex + +# use the repo root directory as "--git-dir" +cd "$(dirname "$0")/../.." + +dir="$1" + +# notify git about untracked (except ignored) files +git add -N "$dir" + +# display overview of changed files +git status "$dir" + +# display diff of working directory vs HEAD commit and set exit code +git diff -a --exit-code HEAD "$dir" diff --git a/.github/scripts/windows/build.bat b/.github/scripts/windows/build.bat index 65f40fb9462a..b7beb3a7ef4b 100644 --- a/.github/scripts/windows/build.bat +++ b/.github/scripts/windows/build.bat @@ -41,7 +41,9 @@ if not exist "%SDK_RUNNER%" ( exit /b 3 ) -cmd /c %SDK_RUNNER% -t .github\scripts\windows\build_task.bat +for /f "delims=" %%T in ('call .github\scripts\windows\find-vs-toolset.bat %PHP_BUILD_CRT%') do set "VS_TOOLSET=%%T" +echo Got VS Toolset %VS_TOOLSET% +cmd /c %SDK_RUNNER% -s %VS_TOOLSET% -t .github\scripts\windows\build_task.bat if %errorlevel% neq 0 exit /b 3 exit /b 0 diff --git a/.github/scripts/windows/build_task.bat b/.github/scripts/windows/build_task.bat index b65479451849..1177cef3be4d 100644 --- a/.github/scripts/windows/build_task.bat +++ b/.github/scripts/windows/build_task.bat @@ -26,12 +26,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 +if "%CLANG_TOOLSET%" equ "1" set ADD_CONF=%ADD_CONF% --with-toolset=clang 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 +if "%CLANG_TOOLSET%" equ "1" ( + rem Clang is much stricter than MSVC, produces too many warnings that would fail the build with /WX + set CFLAGS=/W3 /wd4018 /wd4146 /wd4244 /wd4267 +) else ( + set CFLAGS=/W3 /WX /wd4018 /wd4146 /wd4244 /wd4267 +) cmd /c configure.bat ^ --enable-snapshot-build ^ diff --git a/.github/scripts/windows/find-target-branch.bat b/.github/scripts/windows/find-target-branch.bat index a0b47f248894..44b0bde1ec8c 100644 --- a/.github/scripts/windows/find-target-branch.bat +++ b/.github/scripts/windows/find-target-branch.bat @@ -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.6" ( set BRANCH=master ) diff --git a/.github/scripts/windows/find-vs-toolset.bat b/.github/scripts/windows/find-vs-toolset.bat new file mode 100644 index 000000000000..ecaca6775b07 --- /dev/null +++ b/.github/scripts/windows/find-vs-toolset.bat @@ -0,0 +1,52 @@ +@echo off + +setlocal enabledelayedexpansion + +if "%~1"=="" ( + echo ERROR: Usage: %~nx0 [vc14^|vc15^|vs16^|vs17^|vs18] + exit /b 1 +) + +set "toolsets_vc14=14.0" +set "toolsets_vc15=" +set "toolsets_vs16=" +set "toolsets_vs17=" +set "toolsets_vs18=" + + +for /f "usebackq tokens=*" %%I in (`vswhere.exe -latest -find "VC\Tools\MSVC"`) do set "MSVCDIR=%%I" + +if not defined MSVCDIR ( + echo ERROR: could not locate VC\Tools\MSVC + exit /b 1 +) + +for /f "delims=" %%D in ('dir /b /ad "%MSVCDIR%"') do ( + for /f "tokens=1,2 delims=." %%A in ("%%D") do ( + set "maj=%%A" & set "min=%%B" + if "!maj!"=="14" ( + if !min! LEQ 9 ( + set "toolsets_vc14=%%D" + ) else if !min! LEQ 19 ( + set "toolsets_vc15=%%D" + ) else if !min! LEQ 29 ( + set "toolsets_vs16=%%D" + ) else if !min! LEQ 49 ( + set "toolsets_vs17=%%D" + ) else ( + set "toolsets_vs18=%%D" + ) + ) + ) +) + +set "KEY=%~1" +set "VAR=toolsets_%KEY%" +call set "RESULT=%%%VAR%%%" +if defined RESULT ( + echo %RESULT% + exit /b 0 +) else ( + echo ERROR: no toolset found for %KEY% + exit /b 1 +) diff --git a/.github/scripts/windows/test.bat b/.github/scripts/windows/test.bat index 1a2456469721..b8cc501e0cf3 100644 --- a/.github/scripts/windows/test.bat +++ b/.github/scripts/windows/test.bat @@ -9,7 +9,8 @@ if not exist "%SDK_RUNNER%" ( exit /b 3 ) -cmd /c %SDK_RUNNER% -t .github\scripts\windows\test_task.bat +for /f "delims=" %%T in ('call .github\scripts\windows\find-vs-toolset.bat %PHP_BUILD_CRT%') do set "VS_TOOLSET=%%T" +cmd /c %SDK_RUNNER% -s %VS_TOOLSET% -t .github\scripts\windows\test_task.bat if %errorlevel% neq 0 exit /b 3 exit /b 0 diff --git a/.github/scripts/windows/test_task.bat b/.github/scripts/windows/test_task.bat index 43e7763e7029..4ce2bd96ce66 100644 --- a/.github/scripts/windows/test_task.bat +++ b/.github/scripts/windows/test_task.bat @@ -36,8 +36,7 @@ if %errorlevel% neq 0 exit /b 3 rem setup PostgreSQL related exts set PGUSER=postgres set PGPASSWORD=Password12! -rem set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=postgres password=Password12! -echo ^ >> "./ext/pgsql/tests/config.inc" +set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=%PGUSER% password=%PGPASSWORD% set PDO_PGSQL_TEST_DSN=pgsql:host=127.0.0.1 port=5432 dbname=test user=%PGUSER% password=%PGPASSWORD% set TMP_POSTGRESQL_BIN=%PGBIN% "%TMP_POSTGRESQL_BIN%\createdb.exe" test @@ -128,7 +127,7 @@ 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 -if "%OPCACHE%" equ "1" echo zend_extension=php_opcache.dll >> %PHP_BUILD_DIR%\php.ini +echo opcache.record_warnings=1 >> %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 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6ae972d92e49..ffb45c9a20cd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,14 +10,14 @@ on: - docs/** jobs: pages: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest permissions: pages: write id-token: write if: github.repository == 'php/php-src' steps: - name: git checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install dependencies run: pip install -r docs/requirements.txt - name: Check formatting diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index dbddbdc5d89b..4cf6357c491f 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -12,6 +12,6 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v5 + - uses: actions/labeler@v6 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/nightly-results.yml b/.github/workflows/nightly-results.yml new file mode 100644 index 000000000000..fea01e1b0264 --- /dev/null +++ b/.github/workflows/nightly-results.yml @@ -0,0 +1,16 @@ +name: Nightly results +on: + workflow_run: + workflows: + - Test + types: + - completed +jobs: + on-failure: + runs-on: ubuntu-latest + if: ${{ github.repository == 'php/php-src' && github.event.workflow_run.event == 'schedule' && github.event.workflow_run.conclusion == 'failure' }} + steps: + - run: | + export DEBIAN_FRONTEND=noninteractive + sudo apt-get install -y curl + curl -X POST -H 'Content-type: application/json' --data '{"attachments": [{"text": "Job(s) in *nightly* failed", "footer": "<${{ github.event.workflow_run.html_url }}|View Run>", "color": "danger", "mrkdwn_in": ["text"]}]}' ${{ secrets.ACTION_MONITORING_SLACK }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index 1b1532af7f79..000000000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,1063 +0,0 @@ -name: Test suite -on: - workflow_call: - inputs: - asan_ubuntu_version: - required: true - type: string - branch: - required: true - type: string - community_verify_type_inference: - required: true - type: boolean - libmysqlclient_with_mysqli: - required: true - type: boolean - run_alpine: - required: true - type: boolean - run_linux_ppc64: - required: true - type: boolean - run_macos_arm64: - required: true - type: boolean - ubuntu_version: - required: true - type: string - windows_version: - required: true - type: string - skip_laravel: - required: true - type: boolean - skip_symfony: - required: true - type: boolean - skip_wordpress: - required: true - type: boolean -permissions: - contents: read -jobs: - LINUX_PPC64: - if: inputs.run_linux_ppc64 - name: LINUX_PPC64_ASAN_UBSAN_DEBUG_ZTS - # This runs on a self-hosted runner; see https://wiki.php.net/systems/ci - runs-on: [self-hosted, gentoo, ppc64] - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: System info - run: | - echo "::group::Show host CPU info" - lscpu - echo "::endgroup::" - echo "::group::Show installed packages" - cat /var/lib/portage/world - echo "::endgroup::" - - name: ./configure - uses: ./.github/actions/configure-gentoo - with: - configurationParameters: >- - CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" - LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" - CC=clang-17 - CXX=clang++-17 - --enable-debug - --enable-zts - skipSlow: false # FIXME: This should likely include slow extensions - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - # Skip an install action for now - - name: Tests - uses: ./.github/actions/test-gentoo - # There is no PPC JIT, so rip this out - with: - runTestsParameters: >- - --asan -x - ALPINE: - if: inputs.run_alpine - name: ALPINE_X64_ASAN_UBSAN_DEBUG_ZTS - runs-on: ubuntu-22.04 - container: - image: 'alpine:3.20.1' - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: apk - uses: ./.github/actions/apk - - name: LLVM 17 (ASAN-only) - # libclang_rt.asan-x86_64.a is provided by compiler-rt, and only for clang17: - # https://pkgs.alpinelinux.org/contents?file=libclang_rt.asan-x86_64.a&path=&name=&branch=v3.20 - run: | - apk add clang17 compiler-rt - - name: System info - run: | - echo "::group::Show host CPU info" - lscpu - echo "::endgroup::" - echo "::group::Show installed package versions" - apk list - echo "::endgroup::" - - name: ./configure - uses: ./.github/actions/configure-alpine - with: - configurationParameters: >- - CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" - LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" - CC=clang-17 - CXX=clang++-17 - --enable-debug - --enable-zts - skipSlow: true # FIXME: This should likely include slow extensions - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-alpine - - name: Test Tracing JIT - uses: ./.github/actions/test-alpine - with: - jitType: tracing - runTestsParameters: >- - --asan -x - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - - LINUX_X64: - services: - mysql: - image: mysql:8.3 - ports: - - 3306:3306 - env: - MYSQL_DATABASE: test - MYSQL_ROOT_PASSWORD: root - postgres: - image: postgres - env: - 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: - configuration_parameters: [''] - debug: [true, false] - name: [''] - run_tests_parameters: [''] - test_function_jit: [true] - zts: [true, false] - include: - - name: _ASAN_UBSAN - debug: true - zts: true - configuration_parameters: >- - CFLAGS="-fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC" - LDFLAGS="-fsanitize=undefined,address" - run_tests_parameters: '--asan' - test_function_jit: false - asan: true - - name: _REPEAT - debug: true - zts: false - run_tests_parameters: --repeat 2 - timeout_minutes: 360 - test_function_jit: true - asan: false - - name: _VARIATION - debug: true - zts: true - configuration_parameters: >- - CFLAGS="-DZEND_RC_DEBUG=1 -DPROFITABILITY_CHECKS=0 -DZEND_VERIFY_FUNC_INFO=1 -DZEND_VERIFY_TYPE_INFERENCE" - run_tests_parameters: -d zend_test.observer.enabled=1 -d zend_test.observer.show_output=0 - timeout_minutes: 360 - test_function_jit: true - asan: false - name: "LINUX_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" - runs-on: ubuntu-${{ matrix.asan && inputs.asan_ubuntu_version || inputs.ubuntu_version }} - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: Create MSSQL container - uses: ./.github/actions/setup-mssql - - name: apt - uses: ./.github/actions/apt-x64 - with: - asan: ${{ matrix.asan && 'true' || 'false' }} - - name: System info - run: | - echo "::group::Show host CPU info" - lscpu - echo "::endgroup::" - echo "::group::Show installed package versions" - dpkg -l - echo "::endgroup::" - - name: ./configure - uses: ./.github/actions/configure-x64 - with: - configurationParameters: >- - ${{ matrix.configuration_parameters }} - --${{ matrix.debug && 'enable' || 'disable' }}-debug - --${{ matrix.zts && 'enable' || 'disable' }}-zts - asan: ${{ matrix.asan && 'true' || 'false' }} - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux - - name: Setup - uses: ./.github/actions/setup-x64 - - name: Test - uses: ./.github/actions/test-linux - with: - runTestsParameters: >- - ${{ matrix.run_tests_parameters }} - idleCpu: ${{ matrix.asan && 'true' || 'false' }} - - name: Test Tracing JIT - uses: ./.github/actions/test-linux - with: - 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 - # avoid running into the 6 hour timeout by skipping the function JIT. - if: matrix.test_function_jit - uses: ./.github/actions/test-linux - with: - jitType: function - runTestsParameters: >- - ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - - name: Verify generated files are up to date - uses: ./.github/actions/verify-generated-files - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - LINUX_X32: - strategy: - fail-fast: false - matrix: - debug: [true, false] - zts: [true, false] - name: "LINUX_X32_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" - runs-on: ubuntu-latest - container: - image: ubuntu:${{ inputs.ubuntu_version }} - env: - PDO_FIREBIRD_TEST_DSN: firebird:dbname=firebird:test.fdb - services: - mysql: - image: mysql:8.3 - ports: - - 3306:3306 - 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@v4 - with: - ref: ${{ inputs.branch }} - - name: apt - uses: ./.github/actions/apt-x32 - - name: System info - run: | - echo "::group::Show host CPU info" - lscpu - echo "::endgroup::" - echo "::group::Show installed package versions" - dpkg -l - echo "::endgroup::" - - name: ./configure - uses: ./.github/actions/configure-x32 - with: - configurationParameters: >- - --${{ matrix.debug && 'enable' || 'disable' }}-debug - --${{ matrix.zts && 'enable' || 'disable' }}-zts - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux-x32 - - name: Test - uses: ./.github/actions/test-linux - with: - runTestsParameters: >- - ${{ matrix.run_tests_parameters }} - - name: Test Tracing JIT - uses: ./.github/actions/test-linux - with: - 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 - with: - jitType: function - runTestsParameters: >- - ${{ matrix.run_tests_parameters }} - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - MACOS: - strategy: - fail-fast: false - matrix: - debug: [true, false] - zts: [true, false] - os: ['13', '14'] - exclude: - - os: ${{ !inputs.run_macos_arm64 && '14' || '*never*' }} - name: "MACOS_${{ matrix.os == '13' && 'X64' || 'ARM64' }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" - runs-on: macos-${{ matrix.os }} - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: brew - uses: ./.github/actions/brew - - name: ./configure - uses: ./.github/actions/configure-macos - with: - configurationParameters: >- - --${{ matrix.debug && 'enable' || 'disable' }}-debug - --${{ matrix.zts && 'enable' || 'disable' }}-zts - - name: make - run: |- - export PATH="$(brew --prefix)/opt/bison/bin:$PATH" - make -j$(sysctl -n hw.logicalcpu) >/dev/null - - name: make install - run: sudo make install - - name: Test - uses: ./.github/actions/test-macos - - name: Test Tracing JIT - if: matrix.os != '14' || !matrix.zts - uses: ./.github/actions/test-macos - 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 - uses: ./.github/actions/test-macos - with: - jitType: function - runTestsParameters: >- - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - - name: Verify generated files are up to date - uses: ./.github/actions/verify-generated-files - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - COVERAGE_DEBUG_NTS: - if: inputs.branch == 'master' - services: - mysql: - image: mysql:8.3 - ports: - - 3306:3306 - env: - MYSQL_DATABASE: test - MYSQL_ROOT_PASSWORD: root - postgres: - image: postgres - env: - 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 - runs-on: ubuntu-22.04 - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: Create MSSQL container - uses: ./.github/actions/setup-mssql - - name: apt - uses: ./.github/actions/apt-x64 - - name: Install gcovr - run: sudo -H pip install gcovr - - name: ./configure - uses: ./.github/actions/configure-x64 - with: - configurationParameters: --enable-debug --disable-zts --enable-gcov - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux - - name: Setup - uses: ./.github/actions/setup-x64 - # We only test with OpCache, the difference in coverage is negligible - - name: Test OpCache - uses: ./.github/actions/test-linux - with: - jitType: tracing - runTestsParameters: >- - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - - uses: codecov/codecov-action@v4 - if: ${{ !cancelled() }} - with: - fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - COMMUNITY: - strategy: - fail-fast: false - matrix: - type: ['asan', 'verify_type_inference'] - exclude: - - type: ${{ !inputs.community_verify_type_inference && 'verify_type_inference' || '*never*' }} - name: "COMMUNITY_${{ matrix.type }}" - runs-on: ubuntu-${{ inputs.ubuntu_version }} - env: - ASAN_OPTIONS: exitcode=139 - UBSAN_OPTIONS: print_stacktrace=1 - USE_ZEND_ALLOC: 0 - USE_TRACKED_ALLOC: 1 - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: apt - uses: ./.github/actions/apt-x64 - - name: ./configure - uses: ./.github/actions/configure-x64 - with: - # CFLAGS removes O2, so we have to add it again... - configurationParameters: >- - --enable-zts - ${{ matrix.type == 'asan' && '--enable-debug CFLAGS="-fsanitize=undefined,address -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address"' || '' }} - ${{ matrix.type == 'verify_type_inference' && 'CFLAGS="-DZEND_VERIFY_TYPE_INFERENCE -O2"' || '' }} - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux - - name: Setup - run: | - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" - mysql -uroot -proot -e "SET GLOBAL local_infile = true" - - 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 - echo opcache.memory_consumption=256M >> /etc/php.d/opcache.ini - echo opcache.file_update_protection=0 >> /etc/php.d/opcache.ini - echo opcache.interned_strings_buffer=64 >> /etc/php.d/opcache.ini - echo opcache.max_accelerated_files=100000 >> /etc/php.d/opcache.ini - - name: Enable JIT - if: matrix.type != 'verify_type_inference' - run: | - echo opcache.jit=tracing >> /etc/php.d/opcache.ini - echo opcache.jit_buffer_size=1G >> /etc/php.d/opcache.ini - echo opcache.jit_max_root_traces=100000 >> /etc/php.d/opcache.ini - echo opcache.jit_max_side_traces=100000 >> /etc/php.d/opcache.ini - echo opcache.jit_max_exit_counters=100000 >> /etc/php.d/opcache.ini - echo opcache.jit_hot_loop=1 >> /etc/php.d/opcache.ini - echo opcache.jit_hot_func=1 >> /etc/php.d/opcache.ini - echo opcache.jit_hot_return=1 >> /etc/php.d/opcache.ini - echo opcache.jit_hot_side_exit=1 >> /etc/php.d/opcache.ini - php -v - - name: Test AMPHP - if: ${{ !cancelled() }} - run: | - repositories="amp cache dns file http parallel parser pipeline process serialization socket sync websocket-client websocket-server" - X=0 - for repository in $repositories; do - 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+ - vendor/bin/phpunit || EXIT_CODE=$? - if [ ${EXIT_CODE:-0} -gt 128 ]; then - X=1; - fi - cd .. - done - exit $X - - name: Test Laravel - if: ${{ !cancelled() && !inputs.skip_laravel }} - run: | - git clone https://github.com/laravel/framework.git --depth=1 - cd framework - git rev-parse HEAD - php /usr/bin/composer install --no-progress --ignore-platform-req=php+ - # Hack to disable a test that hangs - php -r '$c = file_get_contents("tests/Filesystem/FilesystemTest.php"); $c = str_replace("public function testSharedGet()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testSharedGet()", $c); file_put_contents("tests/Filesystem/FilesystemTest.php", $c);' - php vendor/bin/phpunit --exclude-group skip || EXIT_CODE=$? - if [ ${EXIT_CODE:-0} -gt 128 ]; then - exit 1 - fi - - name: Test ReactPHP - if: ${{ !cancelled() }} - run: | - repositories="async cache child-process datagram dns event-loop promise promise-stream promise-timer stream" - X=0 - for repository in $repositories; do - 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+ - vendor/bin/phpunit || EXIT_CODE=$? - if [ $[EXIT_CODE:-0} -gt 128 ]; then - X=1; - fi - cd .. - done - exit $X - - name: Test Revolt PHP - if: ${{ !cancelled() }} - run: | - git clone https://github.com/revoltphp/event-loop.git --depth=1 - cd event-loop - git rev-parse HEAD - php /usr/bin/composer install --no-progress --ignore-platform-req=php+ - vendor/bin/phpunit || EXIT_CODE=$? - if [ ${EXIT_CODE:-0} -gt 128 ]; then - exit 1 - fi - - name: Test Symfony - if: ${{ !cancelled() && !inputs.skip_symfony }} - run: | - git clone https://github.com/symfony/symfony.git --depth=1 - cd symfony - git rev-parse HEAD - 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()", "/** @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()", "/** @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 - php ./phpunit $component --exclude-group tty,benchmark,intl-data,transient --exclude-group skip || EXIT_CODE=$? - if [ ${EXIT_CODE:-0} -gt 128 ]; then - X=1; - fi - done - exit $X - - name: Test PHPUnit - if: ${{ !cancelled() }} - run: | - git clone https://github.com/sebastianbergmann/phpunit.git --branch=main --depth=1 - cd phpunit - git rev-parse HEAD - php /usr/bin/composer install --no-progress --ignore-platform-req=php+ - php ./phpunit || EXIT_CODE=$? - if [ ${EXIT_CODE:-0} -gt 128 ]; then - exit 1 - fi - - name: 'Symfony Preloading' - if: ${{ !cancelled() && !inputs.skip_symfony }} - run: | - php /usr/bin/composer create-project symfony/symfony-demo symfony_demo --no-progress --ignore-platform-req=php+ - cd symfony_demo - git rev-parse HEAD - sed -i 's/PHP_SAPI/"cli-server"/g' var/cache/dev/App_KernelDevDebugContainer.preload.php - php -d opcache.preload=var/cache/dev/App_KernelDevDebugContainer.preload.php public/index.php - - name: Test Wordpress - if: ${{ !cancelled() && !inputs.skip_wordpress }} - run: | - git clone https://github.com/WordPress/wordpress-develop.git wordpress --depth=1 - cd wordpress - git rev-parse HEAD - php /usr/bin/composer install --no-progress --ignore-platform-req=php+ - cp wp-tests-config-sample.php wp-tests-config.php - sed -i 's/youremptytestdbnamehere/test/g' wp-tests-config.php - sed -i 's/yourusernamehere/root/g' wp-tests-config.php - sed -i 's/yourpasswordhere/root/g' wp-tests-config.php - php vendor/bin/phpunit || EXIT_CODE=$? - if [ $EXIT_CODE -gt 128 ]; then - exit 1 - fi - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - OPCACHE_VARIATION: - services: - mysql: - image: mysql:8.3 - ports: - - 3306:3306 - env: - MYSQL_DATABASE: test - MYSQL_ROOT_PASSWORD: root - postgres: - image: postgres - env: - 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 - name: OPCACHE_VARIATION - runs-on: ubuntu-${{ inputs.ubuntu_version }} - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: Create MSSQL container - uses: ./.github/actions/setup-mssql - - name: apt - uses: ./.github/actions/apt-x64 - - name: ./configure - uses: ./.github/actions/configure-x64 - with: - configurationParameters: >- - --enable-debug --disable-zts - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux - - name: Setup - uses: ./.github/actions/setup-x64 - - name: Test File Cache (prime shm) - 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 - - name: Test File Cache Only (prime) - 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 - - name: Test File Cache Only (use) - 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 - - name: Verify generated files are up to date - uses: ./.github/actions/verify-generated-files - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - MSAN: - name: MSAN - runs-on: ubuntu-${{ inputs.ubuntu_version }} - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: apt - uses: ./.github/actions/apt-x64 - - name: ./configure - run: | - export CC=clang - export CXX=clang++ - export CFLAGS="-DZEND_TRACK_ARENA_ALLOC" - ./buildconf --force - # msan requires all used libraries to be instrumented, - # so we should avoiding linking against anything but libc here - ./configure \ - --enable-debug \ - --enable-zts \ - --enable-option-checking=fatal \ - --prefix=/usr \ - --without-sqlite3 \ - --without-pdo-sqlite \ - --without-libxml \ - --disable-dom \ - --disable-simplexml \ - --disable-xml \ - --disable-xmlreader \ - --disable-xmlwriter \ - --without-pcre-jit \ - --disable-opcache-jit \ - --enable-phpdbg \ - --enable-fpm \ - --with-pdo-mysql=mysqlnd \ - --with-mysqli=mysqlnd \ - --disable-mysqlnd-compression-support \ - --without-pear \ - --enable-exif \ - --enable-sysvsem \ - --enable-sysvshm \ - --enable-shmop \ - --enable-pcntl \ - --enable-mbstring \ - --disable-mbregex \ - --enable-sockets \ - --enable-bcmath \ - --enable-calendar \ - --enable-ftp \ - --enable-zend-test \ - --enable-werror \ - --enable-memory-sanitizer \ - --with-config-file-path=/etc \ - --with-config-file-scan-dir=/etc/php.d \ - --enable-dl-test=shared - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - run: | - sudo make install - 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 pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini - - name: Setup - run: | - set -x - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" - # Ensure local_infile tests can run. - mysql -uroot -proot -e "SET GLOBAL local_infile = true" - sudo locale-gen de_DE - - name: Test - uses: ./.github/actions/test-linux - with: - runTestsParameters: >- - --msan - - name: Test Opcache - uses: ./.github/actions/test-linux - 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 - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - LIBMYSQLCLIENT: - name: LIBMYSQLCLIENT - runs-on: ubuntu-${{ inputs.ubuntu_version }} - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: apt - run: | - sudo apt-get update -y | true - sudo apt install bison re2c - - name: Setup - run: | - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" - # Ensure local_infile tests can run. - mysql -uroot -proot -e "SET GLOBAL local_infile = true" - - name: Build mysql-8.0 - uses: ./.github/actions/build-libmysqlclient - with: - configurationParameters: ${{ !inputs.libmysqlclient_with_mysqli && '--enable-werror' || '' }} - libmysql: mysql-8.0.37-linux-glibc2.28-x86_64.tar.xz - withMysqli: ${{ inputs.libmysqlclient_with_mysqli }} - - name: Test mysql-8.0 - uses: ./.github/actions/test-libmysqlclient - with: - withMysqli: ${{ inputs.libmysqlclient_with_mysqli }} - - name: Build mysql-8.4 - if: ${{ !inputs.libmysqlclient_with_mysqli }} - uses: ./.github/actions/build-libmysqlclient - with: - configurationParameters: ${{ !inputs.libmysqlclient_with_mysqli && '--enable-werror' || '' }} - libmysql: mysql-8.4.0-linux-glibc2.28-x86_64.tar.xz - withMysqli: ${{ inputs.libmysqlclient_with_mysqli }} - - name: Test mysql-8.4 - if: ${{ !inputs.libmysqlclient_with_mysqli }} - uses: ./.github/actions/test-libmysqlclient - with: - withMysqli: ${{ inputs.libmysqlclient_with_mysqli }} - - name: Verify generated files are up to date - uses: ./.github/actions/verify-generated-files - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - PECL: - if: inputs.branch == 'master' - runs-on: ubuntu-22.04 - env: - CC: ccache gcc - CXX: ccache g++ - steps: - - name: git checkout PHP - uses: actions/checkout@v4 - with: - path: php - ref: ${{ inputs.branch }} - - name: git checkout apcu - uses: actions/checkout@v4 - with: - repository: krakjoe/apcu - path: apcu - - name: git checkout imagick - uses: actions/checkout@v4 - with: - repository: Imagick/imagick - path: imagick - - name: git checkout memcached - uses: actions/checkout@v4 - with: - repository: php-memcached-dev/php-memcached - path: memcached - - name: git checkout redis - uses: actions/checkout@v4 - with: - repository: phpredis/phpredis - path: redis - - name: git checkout xdebug - if: false - uses: actions/checkout@v4 - with: - repository: xdebug/xdebug - path: xdebug - - name: git checkout yaml - uses: actions/checkout@v4 - with: - repository: php/pecl-file_formats-yaml - path: yaml - - name: apt - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - ccache \ - libmemcached-dev \ - bison \ - re2c - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: "${{github.job}}-${{hashFiles('php/main/php_version.h')}}" - append-timestamp: false - save: ${{ github.event_name != 'pull_request' }} - - name: build PHP - run: | - cd php - ./buildconf --force - ./configure \ - --enable-option-checking=fatal \ - --prefix=/opt/php \ - --enable-cli \ - --disable-all \ - --enable-session \ - --enable-werror - make -j$(/usr/bin/nproc) - sudo make install - - name: build apcu - run: | - cd apcu - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build imagick - run: | - cd imagick - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build memcached - run: | - cd memcached - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build redis - run: | - cd redis - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build xdebug - if: false - run: | - cd xdebug - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: build yaml - run: | - cd yaml - /opt/php/bin/phpize - ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config - make -j$(/usr/bin/nproc) - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - WINDOWS: - strategy: - fail-fast: false - matrix: - include: - - x64: true - zts: true - opcache: true - asan: false - - x64: false - zts: false - opcache: false - asan: false - - x64: true - zts: true - opcache: true - asan: true - branch: 'master' - timeout: 120 - name: "WINDOWS_${{ matrix.x64 && 'X64' || 'X86' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || ''}}" - runs-on: windows-${{ inputs.windows_version }} - 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: ${{ inputs.windows_version == '2022' && 'vs17' || 'vs16' }} - PLATFORM: ${{ matrix.x64 && 'x64' || 'x86' }} - THREAD_SAFE: "${{ matrix.zts && '1' || '0' }}" - INTRINSICS: "${{ matrix.zts && 'AVX2' || '' }}" - PARALLEL: -j2 - OPCACHE: "${{ matrix.opcache && '1' || '0' }}" - ASAN: "${{ matrix.asan && '1' || '0' }}" - steps: - - name: git config - run: git config --global core.autocrlf false && git config --global core.eol lf - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: Setup - uses: ./.github/actions/setup-windows - - name: Build - run: .github/scripts/windows/build.bat - - name: Test - run: .github/scripts/windows/test.bat - FREEBSD: - name: FREEBSD - runs-on: ubuntu-latest - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch }} - - name: FreeBSD - uses: ./.github/actions/freebsd diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml deleted file mode 100644 index 2f82179b90ec..000000000000 --- a/.github/workflows/push.yml +++ /dev/null @@ -1,378 +0,0 @@ -name: Push -on: - push: - paths-ignore: - - docs/** - - NEWS - - UPGRADING - - UPGRADING.INTERNALS - - '**/README.*' - - CONTRIBUTING.md - - CODING_STANDARDS.md - - .cirrus.yml - - .circleci/** - branches: - - PHP-8.1 - - PHP-8.2 - - PHP-8.3 - - PHP-8.4 - - master - pull_request: - paths-ignore: - - docs/** - - NEWS - - UPGRADING - - UPGRADING.INTERNALS - - '**/README.*' - - CONTRIBUTING.md - - CODING_STANDARDS.md - - .cirrus.yml - - .circleci/** - branches: - - '**' - workflow_dispatch: ~ -permissions: - contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.url || github.run_id }} - cancel-in-progress: true -env: - CC: ccache gcc - CXX: ccache g++ -jobs: - LINUX_X64: - if: github.repository == 'php/php-src' || github.event_name == 'pull_request' - services: - mysql: - image: mysql:8.3 - ports: - - 3306:3306 - env: - MYSQL_DATABASE: test - MYSQL_ROOT_PASSWORD: root - postgres: - image: postgres - ports: - - 5432:5432 - env: - 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: - include: - - debug: false - zts: false - asan: false - - debug: true - 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 - steps: - - name: git checkout - uses: actions/checkout@v4 - - name: apt - uses: ./.github/actions/apt-x64 - - name: System info - run: | - echo "::group::Show host CPU info" - lscpu - echo "::endgroup::" - echo "::group::Show installed package versions" - dpkg -l - echo "::endgroup::" - - name: Create MSSQL container - if: ${{ !matrix.asan }} - uses: ./.github/actions/setup-mssql - - name: Setup Caddy server - uses: ./.github/actions/setup-caddy - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - # This duplicates the "job.name" expression above because - # GitHub has no way to query the job name (github.job is the - # job id, not the job name) - key: "LINUX_X64_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || '' }}-${{hashFiles('main/php_version.h')}}" - append-timestamp: false - save: ${{ github.event_name != 'pull_request' }} - - name: ./configure - uses: ./.github/actions/configure-x64 - with: - 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++' || '' }} - skipSlow: ${{ matrix.asan }} - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux - - name: Setup - if: ${{ !matrix.asan }} - uses: ./.github/actions/setup-x64 - - name: Test - if: matrix.asan == false - uses: ./.github/actions/test-linux - - name: Test Tracing JIT - uses: ./.github/actions/test-linux - with: - jitType: tracing - runTestsParameters: >- - -d zend_extension=opcache.so - -d opcache.enable_cli=1 - ${{ matrix.asan && '--asan -x' || '' }} - - name: Verify generated files are up to date - if: ${{ !matrix.asan }} - uses: ./.github/actions/verify-generated-files - LINUX_X32: - 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 - 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 - ports: - - 3306:3306 - 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@v4 - - name: apt - uses: ./.github/actions/apt-x32 - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" - append-timestamp: false - - name: ./configure - uses: ./.github/actions/configure-x32 - with: - configurationParameters: >- - --enable-debug - --enable-zts - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - uses: ./.github/actions/install-linux-x32 - - name: Test Tracing JIT - uses: ./.github/actions/test-linux - 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: 14 - arch: ARM64 - name: MACOS_${{ matrix.arch }}_DEBUG_NTS - runs-on: macos-${{ matrix.os }} - timeout-minutes: 50 - steps: - - name: git checkout - 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')}}" - append-timestamp: false - save: ${{ github.event_name != 'pull_request' }} - - name: ./configure - uses: ./.github/actions/configure-macos - with: - configurationParameters: --enable-debug --disable-zts - - name: make - run: |- - export PATH="$(brew --prefix)/opt/bison/bin:$PATH" - make -j$(sysctl -n hw.logicalcpu) >/dev/null - - name: make install - run: sudo make install - - name: Test Tracing JIT - uses: ./.github/actions/test-macos - with: - jitType: tracing - runTestsParameters: >- - -d zend_extension=opcache.so - -d opcache.enable_cli=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 - PLATFORM: x64 - THREAD_SAFE: "1" - INTRINSICS: AVX2 - PARALLEL: -j2 - OPCACHE: "1" - steps: - - name: git config - run: git config --global core.autocrlf false && git config --global core.eol lf - - name: git checkout - uses: actions/checkout@v4 - - name: Setup - uses: ./.github/actions/setup-windows - - name: Build - run: .github/scripts/windows/build.bat - - name: Test - run: .github/scripts/windows/test.bat - BENCHMARKING: - name: BENCHMARKING - if: github.repository == 'php/php-src' || github.event_name == 'pull_request' - runs-on: ubuntu-24.04 - timeout-minutes: 50 - steps: - - name: git checkout - 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 - sudo apt-get update - sudo apt-get install \ - bison \ - libgmp-dev \ - libonig-dev \ - libsqlite3-dev \ - openssl \ - re2c \ - valgrind - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" - append-timestamp: false - save: ${{ github.event_name != 'pull_request' }} - - name: ./configure - run: | - set -x - ./buildconf --force - ./configure \ - --disable-debug \ - --enable-mbstring \ - --enable-opcache \ - --enable-option-checking=fatal \ - --enable-sockets \ - --enable-werror \ - --prefix=/usr \ - --with-config-file-scan-dir=/etc/php.d \ - --with-gmp \ - --with-mysqli=mysqlnd \ - --with-openssl \ - --with-pdo-sqlite \ - --with-valgrind - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - run: | - set -x - sudo make install - 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 - run: | - git config --global user.name "Benchmark" - git config --global user.email "benchmark@php.net" - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS wordpress" - 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@v4 - with: - repository: php/benchmarking-data - ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }} - path: benchmark/repos/data - - name: Benchmark - run: php benchmark/benchmark.php true - - name: Store result - if: github.event_name == 'push' - run: | - set -x - cd benchmark/repos/data - 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 0 - fi - git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}" - git push - - name: Show diff - if: github.event_name == 'pull_request' - run: |- - set -x - php benchmark/generate_diff.php \ - ${{ 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 - steps: - - name: git checkout - uses: actions/checkout@v4 - - name: FreeBSD - uses: ./.github/actions/freebsd diff --git a/.github/workflows/real-time-benchmark.yml b/.github/workflows/real-time-benchmark.yml index 9e1fa9fdbe6a..dc28e8438db2 100644 --- a/.github/workflows/real-time-benchmark.yml +++ b/.github/workflows/real-time-benchmark.yml @@ -2,17 +2,102 @@ 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" + collect_extended_perf_stats: + description: 'Whether to collect extended perf stats as artifacts' + required: true + default: "0" + type: choice + options: + - "0" + - "1" + debug_environment: + description: 'Whether to collect environment debug logs as artifacts' + required: true + default: "0" + type: choice + options: + - "0" + - "1" + run_micro_bench: + description: 'Whether to run the micro_bench.php test' + required: true + default: "0" + type: choice + options: + - "0" + - "1" permissions: contents: read + pull-requests: write +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }} + cancel-in-progress: false jobs: REAL_TIME_BENCHMARK: name: REAL_TIME_BENCHMARK - if: github.repository == 'php/php-src' - runs-on: ubuntu-22.04 + if: github.repository == 'php/php-src' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-24.04 + env: + REPOSITORY: ${{ github.repository }} + BRANCH: "master" + COMMIT: ${{ github.sha }} + BASELINE_COMMIT: "d5f6e56610c729710073350af318c4ea1b292cfe" + ID: "master" + JIT: "1" + COLLECT_EXTENDED_PERF_STATS: "0" + DEBUG_ENVIRONMENT: "0" + RUN_MICRO_BENCH: "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,baseRefName --repo ${{ github.repository }} | jq -r '.headRepositoryOwner.login, .headRepository.name, .headRefName, .headRefOid, .baseRefName') + + 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_BRANCH=$(echo "$PR_INFO" | sed -n '5p') + + BASELINE_COMMIT=$(gh api /repos/${{ github.repository }}/compare/$BASELINE_BRANCH...$COMMIT --jq '.merge_base_commit.sha') + echo "BASELINE_COMMIT=$BASELINE_COMMIT" >> $GITHUB_ENV + + echo "ID=benchmarked" >> $GITHUB_ENV + + echo "JIT=${{ inputs.jit }}" >> $GITHUB_ENV + echo "COLLECT_EXTENDED_PERF_STATS=${{ inputs.collect_extended_perf_stats }}" >> $GITHUB_ENV + echo "DEBUG_ENVIRONMENT=${{ inputs.debug_environment }}" >> $GITHUB_ENV + echo "RUN_MICRO_BENCH=${{ inputs.run_micro_bench }}" >> $GITHUB_ENV + fi + - name: Install dependencies run: | - set -ex + set -e sudo apt-get update sudo apt-get install gpg @@ -23,88 +108,196 @@ jobs: sudo apt-get update -y sudo apt-get install -y terraform=1.5.7-* - name: Checkout benchmark suite - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: 'kocsismate/php-version-benchmarks' ref: 'main' fetch-depth: 1 path: 'php-version-benchmarks' - - name: Checkout php-src - uses: actions/checkout@v4 + - name: Checkout php-src (benchmarked version) + uses: actions/checkout@v6 with: - repository: 'php/php-src' - ref: '${{ github.sha }}' + repository: '${{ env.REPOSITORY }}' + ref: '${{ env.COMMIT }}' fetch-depth: 100 - path: 'php-version-benchmarks/tmp/php_master' + path: 'php-version-benchmarks/tmp/php_${{ env.ID }}' + - name: Checkout php-src (baseline version) + uses: actions/checkout@v6 + 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 - uses: actions/checkout@v4 + if: github.event_name != 'workflow_dispatch' + uses: actions/checkout@v6 with: repository: php/real-time-benchmark-data ssh-key: ${{ secrets.PHP_VERSION_BENCHMARK_RESULTS_DEPLOY_KEY }} path: 'php-version-benchmarks/docs/results' - - name: Set benchmark config + - name: Setup PHP config - baseline PHP version run: | set -e - # Set infrastructure config - 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 - 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 + BASELINE_SHORT_SHA="$(echo "${{ env.BASELINE_COMMIT }}" | cut -c 1-7)" - YEAR="$(date '+%Y')" - DATABASE="./php-version-benchmarks/docs/results/$YEAR/database.tsv" + cat << EOF > ./php-version-benchmarks/config/php/baseline.ini + PHP_NAME="PHP - baseline@$BASELINE_SHORT_SHA" + PHP_ID=php_baseline + + PHP_REPO=${{ github.server_url }}/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.BASELINE_COMMIT }} + + 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 -c 1-7)" + + 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=${{ github.server_url }}/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.BASELINE_COMMIT }} + + 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_master/ && git --no-pager log --until="$YESTERDAY" -n 1 --pretty='%H')" + LAST_RESULT_SHA="$(cd ./php-version-benchmarks/tmp/php_${{ env.ID }}/ && git --no-pager log --until="$YESTERDAY" -n 1 --pretty='%H')" fi - BASELINE_SHA="d5f6e56610c729710073350af318c4ea1b292cfe" - BASELINE_SHORT_SHA="$(echo "$BASELINE_SHA" | cut -c1-4)" + echo "LAST_RESULT_SHA=$LAST_RESULT_SHA" >> $GITHUB_ENV - # Set config for the baseline PHP version - cp ./php-version-benchmarks/config/php/master.ini.dist ./php-version-benchmarks/config/php/master_baseline.ini - sed -i 's/PHP_NAME="PHP - master"/PHP_NAME="PHP - baseline@'"$BASELINE_SHORT_SHA"'"/g' ./php-version-benchmarks/config/php/master_baseline.ini - sed -i "s/PHP_ID=php_master/PHP_ID=php_master_baseline/g" ./php-version-benchmarks/config/php/master_baseline.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=$BASELINE_SHA/g" ./php-version-benchmarks/config/php/master_baseline.ini + cat << EOF > ./php-version-benchmarks/config/php/previous.ini + PHP_NAME="PHP - previous ${{ env.BRANCH }}" + PHP_ID=php_previous - # Set config for the previous PHP version - cp ./php-version-benchmarks/config/php/master.ini.dist ./php-version-benchmarks/config/php/master_last.ini - sed -i 's/PHP_NAME="PHP - master"/PHP_NAME="PHP - previous master"/g' ./php-version-benchmarks/config/php/master_last.ini - sed -i "s/PHP_ID=php_master/PHP_ID=php_master_previous/g" ./php-version-benchmarks/config/php/master_last.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=$LAST_RESULT_SHA/g" ./php-version-benchmarks/config/php/master_last.ini + PHP_REPO=${{ github.server_url }}/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=$LAST_RESULT_SHA - # Set config for the current PHP version - cp ./php-version-benchmarks/config/php/master.ini.dist ./php-version-benchmarks/config/php/master_now.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=${{ github.sha }}/g" ./php-version-benchmarks/config/php/master_now.ini + 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=${{ github.server_url }}/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.COMMIT }} + + 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=${{ github.server_url }}/${{ env.REPOSITORY }}.git + PHP_BRANCH=${{ env.BRANCH }} + PHP_COMMIT=${{ env.COMMIT }} - # Set config for current PHP version with JIT - git clone ./php-version-benchmarks/tmp/php_master/ ./php-version-benchmarks/tmp/php_master_jit - cp ./php-version-benchmarks/config/php/master_jit.ini.dist ./php-version-benchmarks/config/php/master_now_jit.ini - sed -i "s/PHP_COMMIT=/PHP_COMMIT=${{ github.sha }}/g" ./php-version-benchmarks/config/php/master_now_jit.ini + 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 - # Set test configs 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 + + if [ "${{ env.RUN_MICRO_BENCH }}" -eq "1" ]; then + cp ./php-version-benchmarks/config/test/6_micro_bench.php.ini.dist ./php-version-benchmarks/config/test/6_micro_bench.php.ini + fi + - name: Setup infra config + run: | + set -e + + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + WORKSPACE="manual" + BASE_COMMIT="$(echo "${{ env.BASELINE_COMMIT }}" | cut -c 1-10)" + else + WORKSPACE="nightly" + BASE_COMMIT="$(echo "${{ env.LAST_RESULT_SHA }}" | cut -c 1-10)" + fi + COMPARE_COMMIT="$(echo "${{ env.COMMIT }}" | cut -c 1-10)" + + cp ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini.dist ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini + sed -i "s|INFRA_DOCKER_REGISTRY=public.ecr.aws/abcdefgh|INFRA_DOCKER_REGISTRY=${{ secrets.PHP_VERSION_BENCHMARK_DOCKER_REGISTRY }}|g" ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini + sed -i "s|INFRA_WORKSPACE=|INFRA_WORKSPACE=$WORKSPACE|g" ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini + sed -i "s/INFRA_COLLECT_EXTENDED_PERF_STATS=0/INFRA_COLLECT_EXTENDED_PERF_STATS=${{ env.COLLECT_EXTENDED_PERF_STATS }}/g" ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini + sed -i "s/INFRA_DEBUG_ENVIRONMENT=0/INFRA_DEBUG_ENVIRONMENT=${{ env.DEBUG_ENVIRONMENT }}/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/state_bucket = ""/state_bucket = "${{ secrets.PHP_VERSION_BENCHMARK_STATE_BUCKET }}"/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 + + WORKFLOW_RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + sed -i "s|log_url = \"\"|log_url = \"$WORKFLOW_RUN_URL\"|g" ./php-version-benchmarks/build/infrastructure/config/aws.tfvars + sed -i 's|artifact_url = ""|artifact_url = "#ARTIFACT_URL#"|g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars + + CHANGESET_URL="${{ github.server_url }}/${{ github.repository }}/compare/$BASE_COMMIT..$COMPARE_COMMIT" + sed -i 's|extra_title = ""|extra_title = "Changeset"|g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars + sed -i "s|extra_text = \"\"|extra_text = \"$CHANGESET_URL\"|g" ./php-version-benchmarks/build/infrastructure/config/aws.tfvars - name: Run benchmark - run: ./php-version-benchmarks/benchmark.sh run aws - - name: Store results + run: | + set -e + + ./php-version-benchmarks/benchmark.sh run aws + + echo "NEWEST_RESULT_DIRECTORY=$(ls -td ${{ github.workspace }}/php-version-benchmarks/docs/results/${{ env.YEAR }}/*/ | head -1)" >> $GITHUB_ENV + - name: Upload artifacts + id: upload + uses: actions/upload-artifact@v6 + with: + name: results + path: | + ./php-version-benchmarks/tmp/results/${{ env.YEAR }}/**/* + retention-days: 30 + - name: Commit results + if: github.repository == 'php/php-src' && github.event_name != 'workflow_dispatch' run: | set -ex + sed -i "s|#ARTIFACT_URL#|${{ steps.upload.outputs.artifact-url }}|g" "${NEWEST_RESULT_DIRECTORY}result.md" + cd ./php-version-benchmarks/docs/results git pull --autostash if [ -e ".git/MERGE_HEAD" ]; then @@ -117,16 +310,10 @@ jobs: fi git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}" git push - - name: Cleanup - if: always() + - name: Comment results + if: github.event_name == 'workflow_dispatch' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 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 + cd ./php-version-benchmarks/tmp/php_${{ env.ID }} + gh pr comment ${{ inputs.pull_request }} --body-file "${NEWEST_RESULT_DIRECTORY}result.md" --repo ${{ github.repository }} diff --git a/.github/workflows/root.yml b/.github/workflows/root.yml deleted file mode 100644 index a98bb39ba0d9..000000000000 --- a/.github/workflows/root.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Nightly -on: - schedule: - - cron: "0 1 * * *" - workflow_dispatch: ~ -permissions: - contents: read -jobs: - GENERATE_MATRIX: - name: Generate Matrix - if: github.repository == 'php/php-src' || github.event_name == 'workflow_dispatch' - runs-on: ubuntu-latest - outputs: - branches: ${{ steps.set-matrix.outputs.branches }} - steps: - - uses: actions/checkout@v4 - with: - # Set fetch-depth to 0 to clone the full repository - # including all branches. This is required to find - # the correct commit hashes. - fetch-depth: 0 - - name: Grab the commit mapping - uses: actions/cache@v4 - with: - path: branch-commit-cache.json - # The cache key needs to change every time for the - # cache to be updated after this job finishes. - key: nightly-${{ github.run_id }}-${{ github.run_attempt }} - restore-keys: | - nightly- - - name: Generate Matrix - id: set-matrix - run: php .github/nightly_matrix.php "${{ github.event_name }}" "${{ github.run_attempt }}" "${{ github.head_ref || github.ref_name }}" - - name: Notify Slack - if: failure() - uses: ./.github/actions/notify-slack - with: - token: ${{ secrets.ACTION_MONITORING_SLACK }} - NIGHTLY: - needs: GENERATE_MATRIX - name: ${{ matrix.branch.ref }} - if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} - uses: ./.github/workflows/nightly.yml - strategy: - fail-fast: false - matrix: - branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} - with: - asan_ubuntu_version: ${{ - (((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 5) || matrix.branch.version[0] >= 9) && '24.04') - || '22.04' }} - branch: ${{ matrix.branch.ref }} - community_verify_type_inference: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} - libmysqlclient_with_mysqli: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1) }} - run_alpine: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} - run_linux_ppc64: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} - run_macos_arm64: ${{ (matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9 }} - ubuntu_version: ${{ - (((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 5) || matrix.branch.version[0] >= 9) && '24.04') - || '22.04' }} - windows_version: ${{ ((matrix.branch.version[0] == 8 && matrix.branch.version[1] >= 4) || matrix.branch.version[0] >= 9) && '2022' || '2019' }} - skip_laravel: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} - skip_symfony: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} - skip_wordpress: ${{ matrix.branch.version[0] == 8 && matrix.branch.version[1] == 1 }} - secrets: inherit diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml new file mode 100644 index 000000000000..7b1850aa1075 --- /dev/null +++ b/.github/workflows/test-suite.yml @@ -0,0 +1,1001 @@ +name: Test suite +on: + workflow_call: + inputs: + all_variations: + required: true + type: boolean + branch: + required: true + type: string +permissions: + contents: read +jobs: + LINUX_PPC64: + if: ${{ fromJson(inputs.branch).jobs.LINUX_PPC64 }} + name: LINUX_PPC64_ASAN_DEBUG_ZTS + # This runs on a self-hosted runner; see https://wiki.php.net/systems/ci + runs-on: [self-hosted, gentoo, ppc64] + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: System info + run: | + echo "::group::Show host CPU info" + lscpu + echo "::endgroup::" + echo "::group::Show installed packages" + cat /var/lib/portage/world + echo "::endgroup::" + - name: ./configure + uses: ./.github/actions/configure-gentoo + with: + configurationParameters: >- + CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" + LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" + CC=clang-17 + CXX=clang++-17 + --enable-debug + --enable-zts + skipSlow: false # FIXME: This should likely include slow extensions + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + # Skip an install action for now + - name: Tests + uses: ./.github/actions/test-gentoo + # There is no PPC JIT, so rip this out + with: + runTestsParameters: >- + --asan -x + - name: Extra tests + uses: ./.github/actions/extra-tests + ALPINE: + if: ${{ fromJson(inputs.branch).jobs.ALPINE }} + name: ALPINE_X64_ASAN_DEBUG_ZTS + runs-on: ubuntu-24.04 + container: + image: 'alpine:3.22' + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: apk + uses: ./.github/actions/apk + - name: System info + run: | + echo "::group::Show host CPU info" + lscpu + echo "::endgroup::" + echo "::group::Show installed package versions" + apk list + echo "::endgroup::" + - name: ccache + uses: ./.github/actions/ccache + with: + name: "${{ github.job }}" + cc: clang-20 + cxx: clang++-20 + - name: ./configure + uses: ./.github/actions/configure-alpine + with: + configurationParameters: >- + CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" + LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" + --enable-debug + --enable-zts + skipSlow: true # FIXME: This should likely include slow extensions + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-alpine + - name: Test Tracing JIT + uses: ./.github/actions/test-alpine + with: + enableOpcache: true + jitType: tracing + runTestsParameters: >- + --asan -x + - name: Extra tests + uses: ./.github/actions/extra-tests + LINUX_X64: + if: ${{ fromJson(inputs.branch).jobs.LINUX_X64 }} + services: + mysql: + image: mysql:8.4 + ports: + - 3306:3306 + env: + MYSQL_DATABASE: test + MYSQL_ROOT_PASSWORD: root + postgres: + image: postgres + env: + 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: ${{ fromJson(inputs.branch).jobs.LINUX_X64.matrix }} + name: "LINUX_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: Create MSSQL container + uses: ./.github/actions/setup-mssql + - name: apt + uses: ./.github/actions/apt-x64 + with: + asan: ${{ matrix.asan && 'true' || 'false' }} + - name: System info + run: | + echo "::group::Show host CPU info" + lscpu + echo "::endgroup::" + echo "::group::Show installed package versions" + dpkg -l + echo "::endgroup::" + - name: Setup Caddy server + uses: ./.github/actions/setup-caddy + - name: ccache + uses: ./.github/actions/ccache + with: + # This duplicates the "job.name" expression above because + # GitHub has no way to query the job name (github.job is the + # job id, not the job name) + name: "LINUX_X64${{ matrix.name }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + - name: ./configure + uses: ./.github/actions/configure-x64 + with: + configurationParameters: >- + ${{ matrix.asan && 'CFLAGS="-fsanitize=undefined,address -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address"' || '' }} + ${{ matrix.variation && 'CFLAGS="-DZEND_RC_DEBUG=1 -DPROFITABILITY_CHECKS=0 -DZEND_VERIFY_FUNC_INFO=1 -DZEND_VERIFY_TYPE_INFERENCE"' || '' }} + ${{ (matrix.variation && fromJson(inputs.branch).jobs.LINUX_X64.config.variation_enable_zend_max_execution_timers) && '--enable-zend-max-execution-timers' || '' }} + --${{ matrix.debug && 'enable' || 'disable' }}-debug + ${{ matrix.debug && 'CXXFLAGS="-D_GLIBCXX_ASSERTIONS"' || '' }} + --${{ matrix.zts && 'enable' || 'disable' }}-zts + asan: ${{ matrix.asan && 'true' || 'false' }} + skipSlow: ${{ (matrix.asan && !inputs.all_variations) && 'true' || 'false' }} + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + if: ${{ !matrix.asan || inputs.all_variations }} + uses: ./.github/actions/setup-x64 + - name: Test + if: ${{ inputs.all_variations || !matrix.asan }} + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + ${{ matrix.asan && '--asan' || '' }} + ${{ matrix.repeat && '--repeat 2' || '' }} + ${{ matrix.variation && '-d zend_test.observer.enabled=1 -d zend_test.observer.show_output=0' || '' }} + idleCpu: ${{ matrix.asan && 'true' || 'false' }} + - name: Test Tracing JIT + if: ${{ inputs.all_variations || matrix.asan }} + uses: ./.github/actions/test-linux + with: + enableOpcache: true + jitType: tracing + runTestsParameters: >- + ${{ matrix.asan && '--asan' || '' }} + ${{ (matrix.asan && !inputs.all_variations) && '-x' || '' }} + ${{ matrix.repeat && '--repeat 2' || '' }} + ${{ matrix.variation && '-d zend_test.observer.enabled=1 -d zend_test.observer.show_output=0' || '' }} + - name: Test OpCache + if: ${{ inputs.all_variations }} + uses: ./.github/actions/test-linux + with: + enableOpcache: true + runTestsParameters: >- + ${{ matrix.asan && '--asan' || '' }} + ${{ matrix.repeat && '--repeat 2' || '' }} + ${{ matrix.variation && '-d zend_test.observer.enabled=1 -d zend_test.observer.show_output=0' || '' }} + - name: Test Function JIT + # ASAN frequently timeouts. Each test run takes ~90 minutes, we can + # avoid running into the 6 hour timeout by skipping the function JIT. + if: ${{ !matrix.asan }} + uses: ./.github/actions/test-linux + with: + enableOpcache: true + jitType: function + runTestsParameters: >- + ${{ matrix.repeat && '--repeat 2' || '' }} + ${{ matrix.variation && '-d zend_test.observer.enabled=1 -d zend_test.observer.show_output=0' || '' }} + - name: Extra tests + uses: ./.github/actions/extra-tests + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files + LINUX_X32: + if: ${{ fromJson(inputs.branch).jobs.LINUX_X32 }} + strategy: + fail-fast: false + matrix: ${{ fromJson(inputs.branch).jobs.LINUX_X32.matrix }} + name: "LINUX_X32_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: ubuntu-latest + container: + image: ubuntu:${{ fromJson(inputs.branch).config.ubuntu_version }} + 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.4 + ports: + - 3306:3306 + 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@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: apt + uses: ./.github/actions/apt-x32 + - name: ccache + uses: ./.github/actions/ccache + with: + name: "LINUX_X32_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + - name: System info + run: | + echo "::group::Show host CPU info" + lscpu + echo "::endgroup::" + echo "::group::Show installed package versions" + dpkg -l + echo "::endgroup::" + - name: ./configure + uses: ./.github/actions/configure-x32 + with: + configurationParameters: >- + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux-x32 + - name: Test + if: ${{ inputs.all_variations }} + uses: ./.github/actions/test-linux + - name: Test Tracing JIT + uses: ./.github/actions/test-linux + with: + enableOpcache: true + jitType: tracing + - name: Test OpCache + if: ${{ inputs.all_variations }} + uses: ./.github/actions/test-linux + with: + enableOpcache: true + - name: Test Function JIT + if: ${{ inputs.all_variations }} + uses: ./.github/actions/test-linux + with: + enableOpcache: true + jitType: function + - name: Extra tests + uses: ./.github/actions/extra-tests + MACOS: + if: ${{ fromJson(inputs.branch).jobs.MACOS }} + strategy: + fail-fast: false + matrix: ${{ fromJson(inputs.branch).jobs.MACOS.matrix }} + name: "MACOS_${{ matrix.arch }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: macos-${{ matrix.arch == 'X64' && '15-intel' || fromJson(inputs.branch).jobs.MACOS.config.arm64_version }} + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: Update clang + timeout-minutes: 10 + uses: ./.github/actions/macos-update-clang + - name: brew + timeout-minutes: 10 + uses: ./.github/actions/brew + - name: ccache + uses: ./.github/actions/ccache + with: + name: "MACOS_${{ matrix.arch }}_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}" + - name: ./configure + uses: ./.github/actions/configure-macos + with: + configurationParameters: >- + --${{ matrix.debug && 'enable' || 'disable' }}-debug + --${{ matrix.zts && 'enable' || 'disable' }}-zts + - name: make + run: |- + export PATH="$(brew --prefix)/opt/bison/bin:$PATH" + make -j$(sysctl -n hw.logicalcpu) >/dev/null + - name: make install + run: sudo make install + - name: Test + if: ${{ inputs.all_variations }} + uses: ./.github/actions/test-macos + - name: Test Tracing JIT + if: ${{ matrix.arch == 'X64' || !matrix.zts }} + uses: ./.github/actions/test-macos + with: + enableOpcache: true + jitType: tracing + - name: Test OpCache + if: ${{ inputs.all_variations || (matrix.arch == 'ARM64' && matrix.zts) }} + uses: ./.github/actions/test-macos + with: + enableOpcache: true + - name: Test Function JIT + if: ${{ inputs.all_variations && (matrix.arch == 'X64' || !matrix.zts) }} + uses: ./.github/actions/test-macos + with: + enableOpcache: true + jitType: function + - name: Extra tests + uses: ./.github/actions/extra-tests + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files + COVERAGE: + if: ${{ fromJson(inputs.branch).jobs.COVERAGE }} + services: + mysql: + image: mysql:8.4 + ports: + - 3306:3306 + env: + MYSQL_DATABASE: test + MYSQL_ROOT_PASSWORD: root + postgres: + image: postgres + env: + 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 + runs-on: ubuntu-24.04 + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: Create MSSQL container + uses: ./.github/actions/setup-mssql + - name: apt + uses: ./.github/actions/apt-x64 + - name: Install gcovr + run: sudo -H pip install gcovr + - name: ./configure + uses: ./.github/actions/configure-x64 + with: + configurationParameters: --enable-debug --disable-zts --enable-gcov + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + uses: ./.github/actions/setup-x64 + # We only test with OpCache, the difference in coverage is negligible + - name: Test OpCache + uses: ./.github/actions/test-linux + with: + enableOpcache: true + jitType: tracing + - name: Generate coverage report + if: ${{ !cancelled() }} + run: make gcovr-xml + - uses: codecov/codecov-action@v6 + if: ${{ !cancelled() }} + with: + disable_search: true + fail_ci_if_error: true + files: gcovr.xml + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + COMMUNITY: + if: ${{ fromJson(inputs.branch).jobs.COMMUNITY }} + strategy: + fail-fast: false + matrix: ${{ fromJson(inputs.branch).jobs.COMMUNITY.matrix }} + name: "COMMUNITY_${{ matrix.type }}" + runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + env: + ASAN_OPTIONS: exitcode=139 + UBSAN_OPTIONS: print_stacktrace=1 + USE_ZEND_ALLOC: 0 + USE_TRACKED_ALLOC: 1 + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: apt + uses: ./.github/actions/apt-x64 + - name: ccache + uses: ./.github/actions/ccache + with: + name: "COMMUNITY_${{ matrix.type }}" + - name: ./configure + uses: ./.github/actions/configure-x64 + with: + # CFLAGS removes O2, so we have to add it again... + configurationParameters: >- + --enable-zts + ${{ matrix.type == 'asan' && '--enable-debug CFLAGS="-fsanitize=undefined,address -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address"' || '' }} + ${{ matrix.type == 'verify_type_inference' && 'CFLAGS="-DZEND_VERIFY_TYPE_INFERENCE -O2"' || '' }} + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + run: | + sudo service mysql start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + - name: Enable Opcache + run: | + echo memory_limit=-1 >> /etc/php.d/opcache.ini + echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini + echo opcache.enable=1 >> /etc/php.d/opcache.ini + echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini + echo opcache.memory_consumption=256M >> /etc/php.d/opcache.ini + echo opcache.file_update_protection=0 >> /etc/php.d/opcache.ini + echo opcache.interned_strings_buffer=64 >> /etc/php.d/opcache.ini + echo opcache.max_accelerated_files=100000 >> /etc/php.d/opcache.ini + - name: Enable JIT + if: ${{ matrix.type != 'verify_type_inference' }} + run: | + echo opcache.jit=tracing >> /etc/php.d/opcache.ini + echo opcache.jit_buffer_size=1G >> /etc/php.d/opcache.ini + echo opcache.jit_max_root_traces=100000 >> /etc/php.d/opcache.ini + echo opcache.jit_max_side_traces=100000 >> /etc/php.d/opcache.ini + echo opcache.jit_max_exit_counters=100000 >> /etc/php.d/opcache.ini + echo opcache.jit_hot_loop=1 >> /etc/php.d/opcache.ini + echo opcache.jit_hot_func=1 >> /etc/php.d/opcache.ini + echo opcache.jit_hot_return=1 >> /etc/php.d/opcache.ini + echo opcache.jit_hot_side_exit=1 >> /etc/php.d/opcache.ini + php -v + - name: Test AMPHP + if: ${{ !cancelled() }} + run: | + 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" + 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 + exit $X + - name: Test Laravel + if: ${{ !cancelled() }} + run: | + branch=${{ fromJson(inputs.branch).jobs.COMMUNITY.config.laravel_version }} + git clone https://github.com/laravel/framework.git --depth=1 ${branch:+--branch="$branch"} + cd framework + git rev-parse HEAD + php /usr/bin/composer install --no-progress --ignore-platform-req=php+ + # Hack to disable a test that hangs + php -r '$c = file_get_contents("tests/Filesystem/FilesystemTest.php"); $c = str_replace("public function testSharedGet()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testSharedGet()", $c); file_put_contents("tests/Filesystem/FilesystemTest.php", $c);' + php vendor/bin/phpunit --exclude-group skip || EXIT_CODE=$? + if [ ${EXIT_CODE:-0} -gt 128 ]; then + exit 1 + fi + - name: Test ReactPHP + if: ${{ !cancelled() }} + run: | + 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" + 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 + exit $X + - name: Test Revolt PHP + if: ${{ !cancelled() }} + run: | + git clone https://github.com/revoltphp/event-loop.git --depth=1 + cd event-loop + git rev-parse HEAD + php /usr/bin/composer install --no-progress --ignore-platform-req=php+ + vendor/bin/phpunit || EXIT_CODE=$? + if [ ${EXIT_CODE:-0} -gt 128 ]; then + exit 1 + fi + - name: Test Symfony + if: ${{ !cancelled() }} + run: | + branch=${{ fromJson(inputs.branch).jobs.COMMUNITY.config.symfony_version }} + git clone https://github.com/symfony/symfony.git --depth=1 ${branch:+--branch="$branch"} + cd symfony + git rev-parse HEAD + 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);' + # 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);' + 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::" + if [ ${EXIT_CODE:-0} -gt 128 ]; then + X=1; + echo "Failed" + fi + done + exit $X + - name: Test PHPUnit + if: ${{ !cancelled() }} + run: | + git clone https://github.com/sebastianbergmann/phpunit.git --branch=main --depth=1 + cd phpunit + git rev-parse HEAD + php /usr/bin/composer install --no-progress --ignore-platform-req=php+ + php ./phpunit || EXIT_CODE=$? + if [ ${EXIT_CODE:-0} -gt 128 ]; then + exit 1 + fi + - name: 'Symfony Preloading' + # composer create-project will automatically pick the right Symfony version for us. + if: ${{ !cancelled() }} + run: | + php /usr/bin/composer create-project symfony/symfony-demo symfony_demo --no-progress --ignore-platform-req=php+ + cd symfony_demo + git rev-parse HEAD + sed -i 's/PHP_SAPI/"cli-server"/g' var/cache/dev/App_KernelDevDebugContainer.preload.php + php -d opcache.preload=var/cache/dev/App_KernelDevDebugContainer.preload.php public/index.php + - name: Test Wordpress + if: ${{ !cancelled() }} + run: | + git clone https://github.com/WordPress/wordpress-develop.git wordpress --depth=1 + cd wordpress + git rev-parse HEAD + php /usr/bin/composer install --no-progress --ignore-platform-req=php+ + cp wp-tests-config-sample.php wp-tests-config.php + sed -i 's/youremptytestdbnamehere/test/g' wp-tests-config.php + sed -i 's/yourusernamehere/root/g' wp-tests-config.php + sed -i 's/yourpasswordhere/root/g' wp-tests-config.php + php vendor/bin/phpunit || EXIT_CODE=$? + if [ $EXIT_CODE -gt 128 ]; then + exit 1 + fi + OPCACHE_VARIATION: + if: ${{ fromJson(inputs.branch).jobs.OPCACHE_VARIATION }} + services: + mysql: + image: mysql:8.4 + ports: + - 3306:3306 + env: + MYSQL_DATABASE: test + MYSQL_ROOT_PASSWORD: root + postgres: + image: postgres + env: + 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 + name: OPCACHE_VARIATION + runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: Create MSSQL container + uses: ./.github/actions/setup-mssql + - name: apt + uses: ./.github/actions/apt-x64 + - name: ccache + uses: ./.github/actions/ccache + with: + name: "${{ github.job }}" + - name: ./configure + uses: ./.github/actions/configure-x64 + with: + configurationParameters: >- + --enable-debug --disable-zts + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + uses: ./.github/actions/install-linux + - name: Setup + uses: ./.github/actions/setup-x64 + - name: Test File Cache (prime shm) + uses: ./.github/actions/test-linux + with: + enableOpcache: true + runTestsParameters: >- + --file-cache-prime + - name: Test File Cache (prime shm, use shm) + uses: ./.github/actions/test-linux + with: + enableOpcache: true + runTestsParameters: >- + --file-cache-use + - name: Test File Cache (prime shm, use file) + uses: ./.github/actions/test-linux + with: + enableOpcache: true + runTestsParameters: >- + --file-cache-use + -d opcache.file_cache_only=1 + - name: Test File Cache Only (prime) + uses: ./.github/actions/test-linux + with: + enableOpcache: true + runTestsParameters: >- + --file-cache-prime + -d opcache.file_cache_only=1 + - name: Test File Cache Only (use) + uses: ./.github/actions/test-linux + with: + enableOpcache: true + runTestsParameters: >- + --file-cache-use + -d opcache.file_cache_only=1 + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files + MSAN: + if: ${{ fromJson(inputs.branch).jobs.MSAN }} + name: MSAN + runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: apt + uses: ./.github/actions/apt-x64 + - name: ccache + uses: ./.github/actions/ccache + with: + name: "${{ github.job }}" + cc: clang + cxx: clang++ + - name: ./configure + run: | + export CFLAGS="-DZEND_TRACK_ARENA_ALLOC" + ./buildconf --force + # msan requires all used libraries to be instrumented, + # so we should avoiding linking against anything but libc here + ./configure \ + --enable-debug \ + --enable-zts \ + --enable-option-checking=fatal \ + --prefix=/usr \ + --without-sqlite3 \ + --without-pdo-sqlite \ + --without-libxml \ + --disable-dom \ + --disable-simplexml \ + --disable-xml \ + --disable-xmlreader \ + --disable-xmlwriter \ + --without-pcre-jit \ + --disable-opcache-jit \ + --enable-phpdbg \ + --enable-fpm \ + --with-pdo-mysql=mysqlnd \ + --with-mysqli=mysqlnd \ + --disable-mysqlnd-compression-support \ + --without-pear \ + --enable-exif \ + --enable-sysvsem \ + --enable-sysvshm \ + --enable-shmop \ + --enable-pcntl \ + --enable-mbstring \ + --disable-mbregex \ + --enable-sockets \ + --enable-bcmath \ + --enable-calendar \ + --enable-ftp \ + --enable-zend-test \ + --enable-werror \ + --enable-memory-sanitizer \ + --with-config-file-path=/etc \ + --with-config-file-scan-dir=/etc/php.d \ + --enable-dl-test=shared + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + run: | + sudo make install + 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 pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/pdo_mysql.ini + - name: Setup + run: | + set -x + sudo service mysql start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + # Ensure local_infile tests can run. + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + sudo locale-gen de_DE + - name: Test + uses: ./.github/actions/test-linux + with: + runTestsParameters: >- + --msan + - name: Test Opcache + uses: ./.github/actions/test-linux + with: + enableOpcache: true + runTestsParameters: >- + --msan + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files + LIBMYSQLCLIENT: + if: ${{ fromJson(inputs.branch).jobs.LIBMYSQLCLIENT }} + name: LIBMYSQLCLIENT + runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: apt + run: | + sudo apt-get update -y | true + sudo apt install bison re2c + - name: Setup + run: | + sudo service mysql start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS test" + # Ensure local_infile tests can run. + mysql -uroot -proot -e "SET GLOBAL local_infile = true" + - name: Build mysql-8.0 + uses: ./.github/actions/build-libmysqlclient + with: + configurationParameters: '--enable-werror' + libmysql: mysql-8.0.37-linux-glibc2.28-x86_64.tar.xz + - name: Test mysql-8.0 + uses: ./.github/actions/test-libmysqlclient + - name: Build mysql-8.4 + uses: ./.github/actions/build-libmysqlclient + with: + configurationParameters: '--enable-werror' + libmysql: mysql-8.4.0-linux-glibc2.28-x86_64.tar.xz + - name: Test mysql-8.4 + uses: ./.github/actions/test-libmysqlclient + - name: Verify generated files are up to date + uses: ./.github/actions/verify-generated-files + WINDOWS: + if: ${{ fromJson(inputs.branch).jobs.WINDOWS }} + strategy: + fail-fast: false + matrix: ${{ fromJson(inputs.branch).jobs.WINDOWS.matrix }} + name: "WINDOWS_${{ matrix.x64 && 'X64' || 'X86' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || ''}}${{ matrix.clang && '_CLANG' || ''}}" + runs-on: ${{ fromJson(inputs.branch).jobs.WINDOWS.config.runs_on }} + 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.7.1 + PHP_BUILD_CRT: ${{ fromJson(inputs.branch).jobs.WINDOWS.config.vs_crt_version }} + PLATFORM: ${{ matrix.x64 && 'x64' || 'x86' }} + THREAD_SAFE: "${{ matrix.zts && '1' || '0' }}" + INTRINSICS: "${{ matrix.zts && 'AVX2' || '' }}" + PARALLEL: -j2 + OPCACHE: "${{ matrix.opcache && '1' || '0' }}" + ASAN: "${{ matrix.asan && '1' || '0' }}" + CLANG_TOOLSET: "${{ matrix.clang && '1' || '0' }}" + steps: + - name: git config + run: git config --global core.autocrlf false && git config --global core.eol lf + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: Setup + uses: ./.github/actions/setup-windows + - name: Build + run: .github/scripts/windows/build.bat + - name: Test + run: .github/scripts/windows/test.bat + FREEBSD: + if: ${{ fromJson(inputs.branch).jobs.FREEBSD }} + strategy: + fail-fast: false + matrix: ${{ fromJson(inputs.branch).jobs.FREEBSD.matrix }} + name: "FREEBSD_${{ matrix.zts && 'ZTS' || 'NTS' }}" + runs-on: ubuntu-latest + timeout-minutes: 50 + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: FreeBSD + uses: ./.github/actions/freebsd + with: + configurationParameters: >- + --${{ matrix.zts && 'enable' || 'disable' }}-zts + runExtraTests: true + SOLARIS: + if: ${{ fromJson(inputs.branch).jobs.SOLARIS }} + name: "SOLARIS" + runs-on: ubuntu-latest + timeout-minutes: 50 + steps: + - name: git checkout + uses: actions/checkout@v5 + with: + ref: ${{ fromJson(inputs.branch).ref }} + - name: Solaris + uses: ./.github/actions/solaris + with: + configurationParameters: --disable-zts + runExtraTests: true + BENCHMARKING: + name: BENCHMARKING + if: ${{ fromJson(inputs.branch).jobs.BENCHMARKING }} + runs-on: ubuntu-${{ fromJson(inputs.branch).config.ubuntu_version }} + timeout-minutes: 50 + steps: + - name: git checkout + uses: actions/checkout@v6 + with: + ref: ${{ fromJson(inputs.branch).ref }} + 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 + sudo apt-get update + sudo apt-get install \ + bison \ + libgmp-dev \ + libonig-dev \ + libsqlite3-dev \ + openssl \ + re2c \ + valgrind + - name: ccache + uses: ./.github/actions/ccache + with: + name: "${{ github.job }}" + - name: ./configure + run: | + set -x + ./buildconf --force + ./configure \ + --disable-debug \ + --enable-mbstring \ + --enable-option-checking=fatal \ + --enable-sockets \ + --enable-werror \ + --prefix=/usr \ + --with-config-file-scan-dir=/etc/php.d \ + --with-gmp \ + --with-mysqli=mysqlnd \ + --with-openssl \ + --with-pdo-sqlite \ + --with-valgrind + - name: make + run: make -j$(/usr/bin/nproc) >/dev/null + - name: make install + run: | + set -x + sudo make install + 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 + ${{ !fromJson(inputs.branch).jobs.BENCHMARKING.config.integrated_opcache && '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 + run: | + git config --global user.name "Benchmark" + git config --global user.email "benchmark@php.net" + sudo service mysql start + mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS wordpress" + 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@v6 + with: + repository: php/benchmarking-data + ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }} + path: benchmark/repos/data + - name: Benchmark + run: php benchmark/benchmark.php true + - name: Store result + if: github.event_name == 'push' + run: | + set -x + cd benchmark/repos/data + 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 0 + fi + git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}" + git push + - name: Show diff + if: github.event_name == 'pull_request' + run: |- + set -x + php benchmark/generate_diff.php \ + ${{ github.sha }} \ + ${{ github.event.pull_request.base.sha }} \ + > $GITHUB_STEP_SUMMARY + - uses: actions/upload-artifact@v6 + with: + name: profiles + path: ${{ github.workspace }}/benchmark/profiles + retention-days: 30 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000000..eafedec5eafa --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,74 @@ +name: Test +on: + push: + paths-ignore: &ignore_paths + - .circleci/** + - .github/CODEOWNERS + - .github/ISSUE_TEMPLATE/** + - '**/*.md' + - '**/*.rst' + - docs/** + - EXTENSIONS + - LICENSE + - NEWS + - UPGRADING + - UPGRADING.INTERNALS + branches: + - PHP-8.2 + - PHP-8.3 + - PHP-8.4 + - PHP-8.5 + - master + pull_request: + paths-ignore: *ignore_paths + branches: + - '**' + schedule: + - cron: "0 1 * * *" + workflow_dispatch: ~ +permissions: + contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.url || github.run_id }} + cancel-in-progress: true +jobs: + GENERATE_MATRIX: + name: Generate Matrix + if: github.repository == 'php/php-src' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + outputs: + all_variations: ${{ steps.set-matrix.outputs.all_variations }} + branches: ${{ steps.set-matrix.outputs.branches }} + steps: + - uses: actions/checkout@v6 + with: + # When running nightly, set fetch-depth to 0 to clone the full + # repository including all branches. This is required to find the + # correct commit hashes. + fetch-depth: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && '0' || '1' }} + - name: Grab the commit mapping + if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} + uses: actions/cache@v5 + with: + path: branch-commit-cache.json + # The cache key needs to change every time for the + # cache to be updated after this job finishes. + key: nightly-${{ github.run_id }}-${{ github.run_attempt }} + restore-keys: | + nightly- + - name: Generate Matrix + id: set-matrix + run: php .github/matrix.php "${{ github.event_name }}" "${{ github.run_attempt }}" "${{ github.event_name == 'pull_request' && github.ref || github.ref_name }}" '${{ toJSON(github.event.pull_request.labels) }}' "${{ github.repository }}" + TEST: + needs: GENERATE_MATRIX + if: ${{ needs.GENERATE_MATRIX.outputs.branches != '[]' }} + name: ${{ matrix.branch.name }} + uses: ./.github/workflows/test-suite.yml + strategy: + fail-fast: false + matrix: + branch: ${{ fromJson(needs.GENERATE_MATRIX.outputs.branches) }} + with: + all_variations: ${{ needs.GENERATE_MATRIX.outputs.all_variations == 'true' }} + branch: ${{ toJSON(matrix.branch) }} + secrets: inherit diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 000000000000..6338a1cb945d --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,75 @@ +name: Unit Tests +on: + push: + paths: + - 'main/network.c' + - 'tests/unit/**' + - '.github/workflows/unit-tests.yml' + branches: + - master + pull_request: + paths: + - 'main/network.c' + - 'tests/unit/**' + - '.github/workflows/unit-tests.yml' + branches: + - '**' + workflow_dispatch: ~ + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.url || github.run_id }} + cancel-in-progress: true + +env: + CC: ccache gcc + CXX: ccache g++ + +jobs: + UNIT_TESTS: + if: github.repository == 'php/php-src' || github.event_name == 'pull_request' + name: UNIT_TESTS_LINUX_X64 + runs-on: ubuntu-24.04 + timeout-minutes: 20 + steps: + - name: git checkout + uses: actions/checkout@v6 + + - name: Install dependencies + run: | + set -x + sudo apt-get update + sudo apt-get install -y \ + libcmocka-dev \ + autoconf \ + gcc \ + make \ + unzip \ + bison \ + re2c \ + locales \ + ccache + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: "unit-tests-${{hashFiles('main/php_version.h')}}" + append-timestamp: false + save: ${{ github.event_name != 'pull_request' }} + + - name: ./configure (minimal build) + uses: ./.github/actions/configure-unit-tests + + - name: make libphp.a + run: | + set -x + make -j$(/usr/bin/nproc) >/dev/null + + - name: Run unit tests + run: | + set -x + cd tests/unit + make test + diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml new file mode 100644 index 000000000000..473d6e2d8f4d --- /dev/null +++ b/.github/workflows/verify-bundled-files.yml @@ -0,0 +1,70 @@ +name: Verify Bundled Files + +on: + push: + paths: &paths + - '.github/scripts/download-bundled/**' + - 'Zend/asm/**' + - 'ext/pcre/pcre2lib/**' + - 'ext/uri/uriparser/**' + pull_request: + paths: *paths + schedule: + - cron: "0 1 * * *" + workflow_dispatch: ~ + +permissions: + contents: read + +jobs: + VERIFY_BUNDLED_FILES: + if: github.repository == 'php/php-src' || github.event_name == 'workflow_dispatch' + name: Verify Bundled Files + runs-on: ubuntu-24.04 + steps: + - name: git checkout + uses: actions/checkout@v6 + + - name: Detect changed files + if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} + uses: dorny/paths-filter@v3 + id: changes + with: + filters: | + 'boost-context': + - '.github/scripts/download-bundled/boost-context.*' + - 'Zend/asm/**' + pcre2: + - '.github/scripts/download-bundled/pcre2.*' + - 'ext/pcre/pcre2lib/**' + uriparser: + - '.github/scripts/download-bundled/uriparser.*' + - 'ext/uri/uriparser/**' + + - name: 'boost.context' + if: ${{ !cancelled() && (steps.changes.outputs.boost-context == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/boost-context.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh Zend/asm + echo "::endgroup::" + - name: PCRE2 + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/pcre2.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh ext/pcre/pcre2lib + echo "::endgroup::" + - name: uriparser + if: ${{ !cancelled() && (steps.changes.outputs.uriparser == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/uriparser.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh ext/uri/uriparser + echo "::endgroup::" diff --git a/.gitignore b/.gitignore index 3c4566ed663c..b76b5a787caa 100644 --- a/.gitignore +++ b/.gitignore @@ -131,6 +131,7 @@ config.h.in /sapi/cgi/php-cgi /sapi/fpm/php-fpm /sapi/phpdbg/phpdbg +/sapi/fuzzer/php-fuzz-* /scripts/php-config /scripts/phpize php @@ -294,6 +295,13 @@ tmp-php.ini /junit.out.xml /.ccache/ +# ------------------------------------------------------------------------------ +# Editor configuration directories +# ------------------------------------------------------------------------------ +/.idea/ +/.vscode/ +/.zed/ + # ------------------------------------------------------------------------------ # Additional test build files # ------------------------------------------------------------------------------ diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index c599194ed50e..3a53d0e258ca 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -79,6 +79,16 @@ rewritten to comply with these rules. return value for functions that perform some operation that may succeed or fail. +1. When throwing a `ValueError` or emitting a warning, use consistent + phrasing for error messages. Common patterns are: + + * Type errors: `must be of type int` (use the type name, not e.g. `must be an integer`) + * Range/boundary: `must be between X and Y` / `must be greater than [or equal to] X` / `must be less than X` / `must be finite` + * String constraints: `must not contain any null bytes` / `must not be empty` / `must be a single character` + * Valid value: `must be a valid X` (e.g. `must be a valid encoding`, `must be a valid calendar ID`) + * Enum-like: `must be one of X, Y, or Z` + * Structural: `must have X` / `must have key X` / `must have N elements` + ## User functions/methods naming conventions 1. Function names for user-level functions should be enclosed with in the @@ -276,7 +286,7 @@ rewritten to comply with these rules. 1. The length of constant string literals should be calculated via ``strlen()`` instead of using ``sizeof()-1`` as it is clearer and any modern compiler - will optimize it away. Legacy usages of the latter style exists within the + will optimize it away. Legacy usages of the latter style exist within the codebase but should not be refactored, unless larger refactoring around that code is taking place. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a91545fa9bd7..e6bff3d6a9ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,6 +26,8 @@ had several contributions accepted, commit privileges are often quickly granted. * [What happens when your contribution is applied?](#what-happens-when-your-contribution-is-applied) * [Git commit rules](#git-commit-rules) * [Copyright and license headers](#copyright-and-license-headers) +* [NEWS file](#news) +* [LLM usage in GitHub comments](#llm-usage-in-github-comments) ## Pull requests @@ -35,8 +37,8 @@ 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. +contribution under the [Modified BSD License](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 @@ -89,7 +91,7 @@ repository. Mailing list subscription is explained on the [mailing lists page](https://www.php.net/mailing-lists.php). You may also want to read -[The Mysterious PHP RFC Process](https://blogs.oracle.com/opal/post/the-mysterious-php-rfc-process-and-how-you-can-change-the-web) +[The Mysterious PHP RFC Process](https://web.archive.org/web/20210621140006/https://blogs.oracle.com/opal/the-mysterious-php-rfc-process-and-how-you-can-change-the-web) for additional notes on the best way to approach submitting an RFC. ## Technical resources @@ -99,6 +101,7 @@ scattered across different websites, and often outdated. Nonetheless, they can provide a good starting point for learning about the fundamentals of the code base. +* https://php.github.io/php-src/ * https://www.phpinternalsbook.com/ * https://www.npopov.com/ * [Internal value representation](https://www.npopov.com/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html), [part 2](https://www.npopov.com/2015/06/19/Internal-value-representation-in-PHP-7-part-2.html) @@ -174,6 +177,7 @@ locations. ├─ config.guess # https://git.savannah.gnu.org/cgit/config.git ├─ config.sub # https://git.savannah.gnu.org/cgit/config.git ├─ libtool.m4 # https://git.savannah.gnu.org/cgit/libtool.git + ├─ lt*.m4 # https://git.savannah.gnu.org/cgit/libtool.git ├─ ltmain.sh # https://git.savannah.gnu.org/cgit/libtool.git ├─ pkg.m4 # https://gitlab.freedesktop.org/pkg-config/pkg-config ├─ shtool # https://www.gnu.org/software/shtool/ @@ -352,29 +356,21 @@ Having said that, here are the organizational rules: `--enable-zts` switch to ensure your code handles TSRM correctly and doesn't break for those who need that. -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. | -| PHP-7.4 | This branch is closed. | -| PHP-7.3 | This branch is closed. | -| PHP-7.2 | This branch is closed. | -| PHP-7.1 | This branch is closed. | -| PHP-7.0 | This branch is closed. | -| PHP-5.6 | This branch is closed. | -| PHP-5.5 | This branch is closed. | -| PHP-5.4 | This branch is closed. | -| PHP-5.3 | This branch is closed. | -| PHP-5.2 | This branch is closed. | -| PHP-5.1 | This branch is closed. | -| PHP-4.4 | This branch is closed. | -| PHP-X.Y.Z | These branches are used for the release managers for tagging the releases, hence they are closed to the general public. | +The master branch is an active development branch for the newest version of PHP, +which is open for backwards incompatible changes and major internal API changes. + +For PHP-X.Y branches, they are used to release the PHP X.Y.z series. Please see +the [supported versions page](https://www.php.net/supported-versions.php) to get +the status of each version. + +If a version is described as "Active support", the corresponding branch is a +current stable version and is open for bugfixes only. If a version is described +as "Security fixes only", the corresponding branch is an old stable version +and is open for security fixes only. If a version is described as "End of life", +the corresponding branch is closed. + +Note that PHP-X.Y.Z branches are used for the release managers for tagging the +releases, hence they are closed to the general public. The next few rules are more of a technical nature: @@ -385,11 +381,8 @@ The next few rules are more of a technical nature: later branches) an empty merge should be done. 2. All news updates intended for public viewing, such as new features, bug - fixes, improvements, etc., should go into the NEWS file of *any stable - release* version with the given change. In other words, news about a bug fix - which went into PHP-5.4, PHP-5.5 and master should be noted in both - PHP-5.4/NEWS and PHP-5.5/NEWS but not master, which is not a public released - version yet. + fixes, improvements, etc., should go into the NEWS file. See the section on + [NEWS](#news) below. 3. Do not commit multiple files and dump all messages in one commit. If you modified several unrelated files, commit each group separately and provide a @@ -422,14 +415,13 @@ An Example from the git project (commit 2b34e486bc): 'arg' variable no longer is available. If you fix some bugs, you should note the bug ID numbers in your commit message. -Bug ID should be prefixed by `#`. Example: - Fixed bug #14016 (pgsql notice handler double free crash bug.) + Fixed GH-14009: Fix prototype for trait method. -When you change the NEWS file for a bug fix, then please keep the bugs sorted in -decreasing order under the fixed version. +When you change the NEWS file for a bug fix, then please keep the bugs sorted +under the fixed version. ## Copyright and license headers @@ -438,19 +430,109 @@ New source code files should include the following header block: ```c /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: | +----------------------------------------------------------------------+ */ ``` +## NEWS + +The purpose of the NEWS file is to record all the changes that are relevant for +users and developers alike. These could be bug fixes, feature additions, syntax +additions, or deprecations. + +### Format + +Each PHP version has a section, starting with the format: + + {DD} {MMM} {YYY}, PHP {version} + +Such as: + + 06 Jun 2024, PHP 8.1.29 + +In each section, entries are ordered by their extension. Extensions are listed +alphabetically, with the exception of "Core", which MUST be listed first. Each +extension's section starts with: `- {name}:\n` + +For each extension, entries are indented by two spaces, followed by `. ` (a +period and a space). + +Entries MUST start with a capital and end with a period (`.`). The period goes +outside of the `{issue-description}`. + +Each entry SHOULD be followed by the name of the contributor, their php.net +account name, or their GitHub handle if they so choose. + +Entries MUST be wrapped at 80 characters. + +If an entry pertains a bug fix, they MUST be formatted as: + + Fixed bug GH-{number} ({issue-description}). ({contributor}) + +Bug fix entries SHOULD be clustered together, and ordered according to their +issue number. The `{issue-description}` SHOULD represent what the actual bug +fix is about, and not necessarily what the user reported. Edit the description +in the GitHub ticket to match. + +On the rare occasion where a bug from our deprecated bug system is fixed, the +entry MUST be formatted as: + + Fixed bug #{number} ({issue-description}). ({contributor}) + +An example: + +``` +31 Jul 2025, PHP 8.5.0alpha4 + +- Core: + . Added PHP_BUILD_PROVIDER constant. (timwolla) + . Fixed bug GH-16665 (\array and \callable should not be usable in + class_alias). (nielsdos) + . Fixed bug GH-19326 (Calling Generator::throw() on a running generator with + a non-Generator delegate crashes). (Arnaud) + +- OPcache: + . Make OPcache non-optional. (Arnaud, timwolla) + +- OpenSSL: + . Add $digest_algo parameter to openssl_public_encrypt() and + openssl_private_decrypt() functions. (Jakub Zelenka) + ``` + +### Branches + +Depending on what sort of fix it is, or where in the release cycle we are, +different NEWS files must be updated. + +*Security fixes*: In the lowest security-supported branch which received the +security fix, and in each newer branch, except for master unless alpha releases +have been tagged, and a release branch has not been created. + +*Bug fixes*: In the lowest supported branch, and in each newer branch, except +for master unless alpha releases have been tagged, and a release branch has not +been created. + +*Feature additions*: In master only. + +If for some reason a feature is introduced in a branch lower than master, +although this is strictly prohibited by other policies, then the entry must +also be in master. + +## LLM usage in GitHub comments + +When using LLMs to generate comments to maintainers for any purpose other than +direct translation, we would highly appreciate it if you disclosed the relevant +paragraphs as such via markdown quote. + +## Thanks + Thank you for contributing to PHP! diff --git a/EXTENSIONS b/EXTENSIONS index d15401f37238..5a08a031e983 100644 --- a/EXTENSIONS +++ b/EXTENSIONS @@ -170,33 +170,33 @@ EXTENSION: dom PRIMARY MAINTAINER: Christian Stocker (2003 - 2011) Rob Richards (2003 - 2012) Marcus Börger (2003 - 2006) - Niels Dossche (2023 - 2025) -MAINTENANCE: Maintained + Nora Dossche (2023 - 2026) +MAINTENANCE: Orphan STATUS: Working SINCE: 5.0 ------------------------------------------------------------------------------- EXTENSION: simplexml PRIMARY MAINTAINER: Marcus Börger (2003 - 2008) - Niels Dossche (2023 - 2025) -MAINTENANCE: Maintained + Nora Dossche (2023 - 2026) +MAINTENANCE: Orphan STATUS: Working SINCE: 5.0 ------------------------------------------------------------------------------- EXTENSION: soap PRIMARY MAINTAINER: Dmitry Stogov (2004 - 2018) - Niels Dossche (2024 - 2025) -MAINTENANCE: Odd fixes + Nora Dossche (2024 - 2026) +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xml PRIMARY MAINTAINER: Thies C. Arntzen (1999 - 2002) Rob Richards (2003 - 2013) - Niels Dossche (2023 - 2025) -MAINTENANCE: Maintained + Nora Dossche (2023 - 2026) +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: lexbor -PRIMARY MAINTAINER: Niels Dossche (2023 - 2025) +PRIMARY MAINTAINER: Niels Dossche (2025 - 2025) Mate Kocsis (2025 - 2025) MAINTENANCE: Maintained STATUS: Working @@ -205,29 +205,29 @@ SINCE: 8.5 EXTENSION: libxml PRIMARY MAINTAINER: Rob Richards (2003 - 2009) Christian Stocker (2004 - 2011) - Niels Dossche (2023 - 2025) -MAINTENANCE: Maintained + Nora Dossche (2023 - 2026) +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xmlreader PRIMARY MAINTAINER: Rob Richards (2004 - 2010) Christian Stocker (2004 - 2004) - Niels Dossche (2023 - 2025) -MAINTENANCE: Maintained + Nora Dossche (2023 - 2026) +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xmlwriter PRIMARY MAINTAINER: Rob Richards (2004 - 2010) Pierre-Alain Joye (2005-2009) - Niels Dossche (2023 - 2025) -MAINTENANCE: Maintained + Nora Dossche (2023 - 2026) +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: xsl PRIMARY MAINTAINER: Christian Stocker (2003 - 2011) Rob Richards (2003 - 2010) - Niels Dossche (2023 - 2025) -MAINTENANCE: Maintained + Nora Dossche (2023 - 2026) +MAINTENANCE: Orphan STATUS: Working SINCE: 5.0 ------------------------------------------------------------------------------- @@ -372,8 +372,8 @@ STATUS: Working EXTENSION: mbstring PRIMARY MAINTAINER: Rui Hirokawa (2001 - 2013) Nikita Popov (2017 - 2020) - Alex Dowad (2021 - 2024) - Yuya Hamada (2024 - 2024) + Alex Dowad (2021 - 2026) + Yuya Hamada (2024 - 2026) MAINTENANCE: Maintained STATUS: Working ------------------------------------------------------------------------------- @@ -420,7 +420,7 @@ STATUS: Working ------------------------------------------------------------------------------- EXTENSION: random PRIMARY MAINTAINER Go Kudo (2022 - 2024) - Tim Düsterhus (2022 - 2025) + Tim Düsterhus (2022 - 2026) MAINTENANCE: Maintained STATUS: Working SINCE: 8.2.0 @@ -495,7 +495,8 @@ EXTENSION: tidy PRIMARY MAINTAINER: John Coggeshall (2003 - 2006) Ilia Alshanetsky (2003 - 2009) Nuno Lopes (2006 - 2012) -MAINTENANCE: Maintained + Nora Dossche (2025 - 2026) +MAINTENANCE: Orphan STATUS: Working ------------------------------------------------------------------------------- EXTENSION: tokenizer @@ -506,6 +507,7 @@ STATUS: Working ------------------------------------------------------------------------------- EXTENSION: uri PRIMARY MAINTAINER Máté Kocsis (2025 - 2025) + Tim Düsterhus (2025 - 2026) MAINTENANCE: Maintained STATUS: Working SINCE: 8.5.0 diff --git a/LICENSE b/LICENSE index 0815d7eb7911..ee42a57fffbb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,68 +1,27 @@ --------------------------------------------------------------------- - The PHP License, version 3.01 -Copyright (c) 1999 - 2024 The PHP Group. All rights reserved. --------------------------------------------------------------------- +Copyright © 1999–2026, The PHP Group and Contributors. +Copyright © 1999–2026, Zend Technologies Ltd., a subsidiary company of Perforce Software, Inc. Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. The name "PHP" must not be used to endorse or promote products - derived from this software without prior written permission. For - written permission, please contact group@php.net. - - 4. Products derived from this software may not be called "PHP", nor - may "PHP" appear in their name, without prior written permission - from group@php.net. You may indicate that your software works in - conjunction with PHP by saying "Foo for PHP" instead of calling - it "PHP Foo" or "phpfoo" - - 5. The PHP Group may publish revised and/or new versions of the - license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the terms - of that version. You may also choose to use such covered code - under the terms of any subsequent version of the license - published by the PHP Group. No one other than the PHP Group has - the right to modify the terms applicable to covered code created - under this License. - - 6. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes PHP software, freely available from - ". - -THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP -DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. - --------------------------------------------------------------------- - -This software consists of voluntary contributions made by many -individuals on behalf of the PHP Group. - -The PHP Group can be contacted via Email at group@php.net. - -For more information on the PHP Group and the PHP project, -please see . - -PHP includes the Zend Engine, freely available at -. +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/NEWS b/NEWS index 1ce8ce754adc..aca01cc8b010 100644 --- a/NEWS +++ b/NEWS @@ -1,294 +1,277 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.5.0alpha1 - -- BCMath: - . Simplify `bc_divide()` code. (SakiTakamachi) - . If the result is 0, n_scale is set to 0. (SakiTakamachi) - . If size of BC_VECTOR array is within 64 bytes, stack area is now used. - (SakiTakamachi) - -- CLI: - . Add --ini=diff to print INI settings changed from the builtin default. - (timwolla) - . Drop support for -z CLI/CGI flag. (nielsdos) - . Fixed GH-17956 - development server 404 page does not adapt to mobiles. - (pascalchevrel) - -- CURL: - . Added CURLFOLLOW_ALL, CURLFOLLOW_OBEYCODE and CURLFOLLOW_FIRSTONLY - values for CURLOPT_FOLLOLOCATION curl_easy_setopt option. (David Carlier) - -- COM: - . Fixed property access of PHP objects wrapped in variant. (cmb) - . Fixed method calls for PHP objects wrapped in variant. (cmb) +?? ??? ????, PHP 8.6.0alpha1 - Core: - . Fixed bug GH-16665 (\array and \callable should not be usable in - class_alias). (nielsdos) - . Added PHP_BUILD_DATE constant. (cmb) - . Added support for Closures and first class callables in constant - expressions. (timwolla, Volker Dusch) - . Use `clock_gettime_nsec_np()` for high resolution timer on macOS - if available. (timwolla) - . Implement GH-15680 (Enhance zend_dump_op_array to properly represent - non-printable characters in string literals). (nielsdos, WangYihang) - . Add support for backtraces for fatal errors. (enorris) - . Fixed bug GH-17442 (Engine UAF with reference assign and dtor). (nielsdos) - . Improved error message of UnhandledMatchError for - zend.exception_string_param_max_len=0. (timwolla) - . Fixed bug GH-17959 (Relax missing trait fatal error to error exception). - (ilutov) - . Fixed bug GH-18033 (NULL-ptr dereference when using register_tick_function - in destructor). (nielsdos) - . Fixed bug GH-18026 (Improve "expecting token" error for ampersand). (ilutov) - . Added the #[\NoDiscard] attribute to indicate that a function's return - value is important and should be consumed. (timwolla, Volker Dusch) - . Added the (void) cast to indicate that not using a value is intentional. - (timwolla, Volker Dusch) - . Added get_error_handler(), get_exception_handler() functions. (Arnaud) - . Fixed bug GH-15753 and GH-16198 (Bind traits before parent class). (ilutov) - . Added support for casts in constant expressions. (nielsdos) - . Fixed bugs GH-17711 and GH-18022 (Infinite recursion on deprecated attribute - evaluation) and GH-18464 (Recursion protection for deprecation constants not - released on bailout). (DanielEScherzer and ilutov) - . Fixed AST printing for immediately invoked Closure. (Dmitrii Derepko) - . Properly handle __debugInfo() returning an array reference. (nielsdos) - . Properly handle reference return value from __toString(). (nielsdos) - . Added the pipe (|>) operator. (crell) - . Added support for `final` with constructor property promotion. - (DanielEScherzer) - -- Curl: - . Added curl_multi_get_handles(). (timwolla) - . Added curl_share_init_persistent(). (enorris) - . Added CURLINFO_USED_PROXY, CURLINFO_HTTPAUTH_USED, and CURLINFO_PROXYAUTH_USED - support to curl_getinfo. (Ayesh Karunaratne) + . Added generics: type parameters on classes, interfaces, traits, functions, + methods, closures, and arrow functions, with optional bounds, defaults, + and variance markers; turbofish syntax (`f::()`) at call sites; and + type arguments on named types (`Box`, `array`, `iterable`, + `self`, `static`, `parent`). Type parameters erase to their bound + at runtime; type arguments are discarded. Pre-erasure metadata is preserved + for Reflection so static-analysis tools can consume generics without + re-parsing source. (azjezz) + . Added first-class callable cache to share instances for the duration of the + request. (ilutov) + . It is now possible to use reference assign on WeakMap without the key + needing to be present beforehand. (ndossche) + . Added `clamp()`. (kylekatarnls, thinkverse) + . Fix OSS-Fuzz #429429090 (Failed assertion on unset() with uninitialized + container). (ilutov) + . Fixed GH-20564 (Don't call autoloaders with pending exception). (ilutov) + . Fix deprecation now showing when accessing null key of an array with JIT. + (alexandre-daubois) + . Fixed bug GH-20174 (Assertion failure in + ReflectionProperty::skipLazyInitialization after failed LazyProxy + initialization). (Arnaud) + . Enabled the TAILCALL VM on Windows when compiling with Clang >= 19 x86_64. + (henderkes) + . Deprecate specifying a nullable return type for __debugInfo(). (timwolla) + . Fixed bug GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF). + (David Carlier) + +- BCMath: + . Added NUL-byte validation to BCMath functions. (jorgsowa) - Date: - . Fix undefined behaviour problems regarding integer overflow in extreme edge - cases. (nielsdos, cmb, ilutov) + . Update timelib to 2022.16. (Derick) - DOM: - . Added Dom\Element::$outerHTML. (nielsdos) - . Added Dom\Element::insertAdjacentHTML(). (nielsdos) - -- Enchant: - . Added enchant_dict_remove_from_session(). (nielsdos) - . Added enchant_dict_remove(). (nielsdos) - . Fix missing empty string checks. (nielsdos) - -- EXIF: - . Add OffsetTime* Exif tags. (acc987) + . Removed LIBXML_XINCLUDE from valid options for XMLDocument, + as it was a no-op. (ndossche) + . Readonly DOM properties are now declared with asymmetric visibility + (public private(set)). ReflectionProperty::isWritable() reports them + correctly, and external writes raise "Cannot modify private(set) + property" instead of the previous readonly modification error. + (David Carlier) + . Fixed Dom\Notation nodes missing tree connection, so that + ownerDocument, parentNode, isConnected and baseURI now return correct + values, and textContent returns NULL per the DOM specification. + (jordikroon) - Fileinfo: - . Upgrade to file 5.46. (nielsdos) - . Change return type of finfo_close() to true. (timwolla) - -- FPM: - . Fixed GH-17645 (FPM with httpd ProxyPass does not decode script path). - (Jakub Zelenka) + . Fixed bug GH-20679 (finfo_file() doesn't work on remote resources). + (ndossche) + . Fixed bug #66095 (Hide libmagic dynamic symbols). (orlitzky) - GD: - . Fixed bug #68629 (Transparent artifacts when using imagerotate). (pierre, - cmb) - . Fixed bug #64823 (ZTS GD fails to to find system TrueType font). (cmb) + . imagesetstyle()/imagefilter()/imagecrop() check array argument entries + types. (David Carlier) + +- GMP: + . gmp_fact() reject values larger than unsigned long. (David Carlier) + . gmp_pow/binomial/root/rootrem and shift/pow operators reject values + larger than unsigned long. (David Carlier) + . GMP exponentiation and shift operators now emit a deprecation warning + when converting a float right operand to int loses precision. (Weilin Du) + +- Hash: + . Upgrade xxHash to 0.8.2. (timwolla) - Intl: - . Bumped ICU requirement to ICU >= 57.1. (cmb) - . IntlDateFormatter::setTimeZone()/datefmt_set_timezone() throws an exception - with uninitialised classes or clone failure. (David Carlier) - . Added DECIMAL_COMPACT_SHORT/DECIMAL_COMPACT_LONG for NumberFormatter class. + . Added IntlNumberRangeFormatter class to format an interval of two numbers + with a given skeleton, locale, collapse type and identity fallback. (BogdanUngureanu) - . Added Locale::isRightToLeft to check if a locale is written right to left. - (David Carlier) - . Added null bytes presence in locale inputs for Locale class. (David Carlier) - . Added grapheme_levenshtein() function. (Yuya Hamada) - . Added Locale::addLikelySubtags/Locale::minimizeSubtags to handle - adding/removing likely subtags to a locale. (David Carlier) - . Added IntlListFormatter class to format a list of items with a locale - , operands types and units. (BogdanUngureanu) - . Fixed bug GH-18566 ([intl] Weird numeric sort in Collator). (nielsdos) - -- LDAP: - . Allow ldap_get_option to retrieve global option by allowing NULL for - connection instance ($ldap). (Remi) - -- MySQLi: - . Fixed bugs GH-17900 and GH-8084 (calling mysqli::__construct twice). - (nielsdos) - -- MySQLnd: - . Added mysqlnd.collect_memory_statistics to ini quick reference. - (hauk92) + . Fixed bug GH-20426 (Spoofchecker::setRestrictionLevel() error message + suggests missing constants). (DanielEScherzer) + . Added grapheme_strrev (Yuya Hamada) + . Passing a non-stringable object as a time zone to Intl time zone + argument handling now raises TypeError instead of Error. (Weilin Du) + . IntlBreakIterator::getLocale() now raises ValueError for invalid locale + types. (Weilin Du) + . Fixed MessageFormatter::parse() and parseMessage() returning PHP_INT_MIN + as float rather than int on 64-bit platforms. (Weilin Du) + +- JSON: + . Enriched JSON last error / exception message with error location. + (Juan Morales) + +- Fibers: + . Fixed bug GH-20483 (ASAN stack overflow with fiber.stack_size INI + small value). (David Carlier) + +- Mail: + . Fixed bug GH-20862 (null pointer dereference in + php_mail_detect_multiple_crlf via error_log (jordikroon) + +- Mbstring: + . ini_set() with mbstring.detect_order changes the order of mb_detect_order + as intended, since mbstring.detect_order is an INI_ALL setting. (tobee94) + . Added GB18030-2022 to default encoding list for zh-CN. (HeRaNO) + . Fixed bug GH-20836 (Stack overflow in mb_convert_variables with + recursive array references). (alexandre-daubois) + . Fixed bug GH-21223; mb_guess_encoding no longer crashes when passed huge + list of candidate encodings (with 200,000+ entries). (Jordi Kroon) + . mbregex has been deprecated. (youkidearitai) + +- Mysqli: + . Added mysqli_quote_string() and mysqli::quote_string(). (Kamil Tekiela) - Opcache: - . Fixed ZTS OPcache build on Cygwin. (cmb) - . Added opcache.file_cache_read_only. (Samuel Melrose) - . Updated default value of opcache.jit_hot_loop. (Arnaud) - . Log a warning when opcache lock file permissions could not be changed. - (Taavi Eomäe) + . Fixed bug GH-20051 (apache2 shutdowns when restart is requested during + preloading). (Arnaud, welcomycozyhom) + +- OpenSSL: + . Added AES-SIV support. (jordikroon) + . Implemented GH-20310 (No critical extension indication in + openssl_x509_parse() output). (StephenWall) + . Added TLS session resumption support for streams with new context options + and Openssl\Session class. (Jakub Zelenka) + . Added TLS external PSK support for streams with new context options and + Openssl\Psk class. (Jakub Zelenka) -- Output: - . Fixed calculation of aligned buffer size. (cmb) +- PCNTL: + . pcntl_exec() now throws a ValueError if the $args array is not a list + array. (Weilin Du) -- PCRE: - . Upgraded to pre2lib from 10.44 to 10.45. (nielsdos) - . Remove PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK from pcre compile options. - (mvorisek) +- PDO_DBLIB; + . Added dblib_handle_check_liveness handler. (freddy77) - PDO_PGSQL: - . Added Iterable support for PDO::pgsqlCopyFromArray. (KentarouTakeda) - . Implement GH-15387 Pdo\Pgsql::setAttribute(PDO::ATTR_PREFETCH, 0) or - Pdo\Pgsql::prepare(…, [ PDO::ATTR_PREFETCH => 0 ]) make fetch() lazy - instead of storing the whole result set in memory (Guillaume Outters) - -- PDO_SQLITE: - . throw on null bytes / resolve GH-13952 (divinity76). - . Implement GH-17321: Add setAuthorizer to Pdo\Sqlite. (nielsdos) - . PDO::sqliteCreateCollation now throws a TypeError if the callback - has a wrong return type. (David Carlier) - . Added Pdo_Sqlite::ATTR_BUSY_STATEMENT constant to check - if a statement is currently executing. (David Carlier) - . Added Pdo_Sqlite::ATTR_EXPLAIN_STATEMENT constant to set a statement - in either EXPLAIN_MODE_PREPARED, EXPLAIN_MODE_EXPLAIN, - EXPLAIN_MODE_EXPLAIN_QUERY_PLAN modes. (David Carlier) + . Clear session-local state disconnect-equivalent processing. + (KentarouTakeda) - PGSQL: - . Added pg_close_stmt to close a prepared statement while allowing - its name to be reused. (David Carlier) - . Added Iterable support for pgsql_copy_from. (David Carlier) - . pg_connect checks if connection_string contains any null byte, - pg_close_stmt check if the statement contains any null byte. - (David Carlier) - . Added pg_service to get the connection current service identifier. - (David Carlier) - -- POSIX: - . Added POSIX_SC_OPEN_MAX constant to get the number of file descriptors - a process can handle. (David Carlier) - . posix_ttyname() sets last_error to EBADF on invalid file descriptors, - posix_isatty() raises E_WARNING on invalid file descriptors, - posix_fpathconf checks invalid file descriptors. (David Carlier) - -- Random: - . Moves from /dev/urandom usage to arc4random_buf on Haiku. (David Carlier) + . Enabled 64 bits support for pg_lo_truncate()/pg_lo_tell() + if the server supports it. (KentarouTakeda) + . pg_fetch_object() now surfaces non-instantiable class errors + before fetching, resolves the constructor via the get_constructor + handler, and reports the empty-constructor ValueError on the + $constructor_args argument. (David Carlier) + +- Phar: + . Support reference values in Phar::mungServer(). (ndossche) + . Invalid values now throw in Phar::mungServer() instead of being silently + ignored. (ndossche) + . Fixed a bypass of the magic ".phar" directory protection in + Phar::addEmptyDir() for paths starting with "/.phar". (Weilin Du) + . Phar::addEmptyDir() now allows non-magic directory names that merely + share the ".phar" prefix. (Weilin Du) + . Support overridden methods in SplFileInfo for getMTime() and getPathname() + when building a phar. (ndossche) + . Mark Phar::buildFromIterator() base directory argument as a path. + (ndossche) + +- Posix: + . Added validity check to the flags argument for posix_access(). (arshidkv12) - Reflection: - . Added ReflectionConstant::getExtension() and ::getExtensionName(). - (DanielEScherzer) - . Fixed bug GH-12856 (ReflectionClass::getStaticPropertyValue() returns UNDEF - zval for uninitialized typed properties). (nielsdos) - . Fixed bug GH-15766 (ReflectionClass::toString() should have better output - for enums). (DanielEScherzer) + . Fixed bug GH-20217 (ReflectionClass::isIterable() incorrectly returns true + for classes with property hooks). (alexandre-daubois) + . Added ReflectionConstant::inNamespace(). (Khaled Alam) + . Added ReflectionProperty::isReadable() and ReflectionProperty::isWritable(). + (ilutov) + . Fixed bug GH-21362 (ReflectionMethod::invoke/invokeArgs() did not verify + Closure instance identity for Closure::__invoke()). (Ilia Alshanetsky) + . Added ReflectionParameter::getDocComment(). (chschneider) - Session: - . session_start() throws a ValueError on option argument if not a hashmap - or a TypeError if read_and_close value is not compatible with int. - (David Carlier) - -- SimpleXML: - . Fixed bug GH-12231 (SimpleXML xpath should warn when returning other return - types than node lists). (nielsdos) - -- SNMP: - . snmpget, snmpset, snmp_get2, snmp_set2, snmp_get3, snmp_set3 and - SNMP::__construct() throw an exception on invalid hostname, community - timeout and retries arguments. (David Carlier) - -- SOAP: - . Fixed bug #49169 (SoapServer calls wrong function, although "SOAP action" - header is correct). (nielsdos) - . Fix namespace handling of WSDL and XML schema in SOAP, - fixing at least GH-16320 and bug #68576. (nielsdos) - . Fixed bug #70951 (Segmentation fault on invalid WSDL cache). (nielsdos) - . Implement request #55503 (Extend __getTypes to support enumerations). - (nielsdos, datibbaw) - . Implement request #61105 (Support Soap 1.2 SoapFault Reason Text lang - attribute). (nielsdos) + . Fixed bug 71162 (updateTimestamp never called when session data is empty). + (Girgias) + . Null bytes in session.cookie_path, session.cookie_domain, and + session.cache_limiter are now rejected with a warning. (jorgsowa) + . session.cookie_samesite now rejects invalid values with a warning; only + "Strict", "Lax", "None", or "" are accepted. (jorgsowa) + . session.cookie_lifetime now rejects non-integer and out-of-range values + with a warning. (jorgsowa) + . Session file GC now recursively cleans nested subdirectories when + session.save_path uses the dirdepth prefix. (jorgsowa) + . Changed defaults of session.use_strict_mode (now 1), session.cookie_httponly + (now 1) and session.cookie_samesite (now "Lax"). (jorgsowa) + +- Soap: + . Soap::__setCookie() when cookie name is a digit is now not stored and + represented as a string anymore but a int. (David Carlier) + . Fixed bug GH-21421 (SoapClient typemap property breaks engine assumptions). + (ndossche) - Sockets: - . Added IPPROTO_ICMP/IPPROTO_ICMPV6 to create raw socket for ICMP usage. - (David Carlier) - . Added TCP_FUNCTION_BLK to change the TCP stack algorithm on FreeBSD. - (David Carlier) - . socket_set_option() catches possible overflow with SO_RCVTIMEO/SO_SNDTIMEO - with timeout setting on windows. (David Carlier) - . Added TCP_FUNCTION_ALIAS, TCP_REUSPORT_LB_NUMA, TCP_REUSPORT_LB_NUMA_NODOM, - TCP_REUSPORT_LB_CURDOM, TCP_BBR_ALGORITHM constants. - . socket_create_listen() throws an exception on invalid port value. - (David Carlier) - . socket_bind() throws an exception on invalid port value. - (David Carlier) - . socket_sendto() throws an exception on invalid port value. - (David Carlier) - . socket_addrinfo_lookup throws an exception on invalid hints value types. - (David Carlier) - . socket_addrinfo_lookup throws an exception if any of the hints value - overflows. (David Carlier) - . socket_addrinfo_lookup throws an exception if one or more hints entries - has an index as numeric. (David Carlier) - . socket_set_option with the options MCAST_LEAVE_GROUP/MCAST_LEAVE_SOURCE_GROUP - will throw an exception if its value is not a valid array/object. - (David Carlier) - . socket_getsockname/socket_create/socket_bind handled AF_PACKET family socket. - (David Carlier) - . Added IP_BINDANY for a socket to bind to any address. (David Carlier) - . Added SO_BUSY_POOL to reduce packets poll latency. (David Carlier) - - Added UDP_SEGMENT support to optimise multiple large datagrams over UDP - if the kernel and hardware supports it. (David Carlier) - - Added SHUT_RD, SHUT_WR and SHUT_RDWR constants for socket_shutdown(). - (David Carlier) + . Added the TCP_USER_TIMEOUT constant for Linux to set the maximum time in + milliseconds transmitted data can remain unacknowledged. (James Lucas) + . Added AF_UNSPEC support for sock_addrinfo_lookup() as a sole umbrella for + AF_INET* family only. (David Carlier) + . Fixed GH-20532 (socket_addrinfo_lookup gives the error code with a new + optional parameter). (David Carlier) - Sodium: - . Fix overall theorical overflows on zend_string buffer allocations. - (David Carlier/nielsdos) + . Added support for libsodium 1.0.21 IPcrypt and XOF APIs. (jedisct1) -- Sqlite: - . Added Sqlite3Stmt::busy to check if a statement is still being executed. - (David Carlier) - . Added Sqlite3Stmt::explain to produce a explain query plan from - the statement. (David Carlier) - . Added Sqlite3Result::fetchAll to returns all results at once from a query. - (David Carlier) +- SPL: + . DirectoryIterator key can now work better with filesystem supporting larger + directory indexing. (David Carlier) + . Fixed bug GH-21831 (SplObjectStorage::removeAllExcept() use-after-free + with re-entrant getHash()). (Pratik Bhujel) + . Fix bugs GH-8561, GH-8562, GH-8563, and GH-8564 (Fixing various + SplFileObject iterator desync bugs). (iliaal) + . Fix bug GH-22062 (SplDoublyLinkedList iterator UAF + via destructor releasing next node). (David Carlier) + +- Sqlite3: + . Fix NUL byte truncation in sqlite3 TEXT column handling. (ndossche) - Standard: - . Fixed crypt() tests on musl when using --with-external-libcrypt - (Michael Orlitzky). - . Fixed bug GH-18062 (is_callable(func(...), callable_name: $name) for first - class callables returns wrong name). (timwolla) - . Added array_first() and array_last(). (nielsdos) - . Fixed bug GH-18823 (setlocale's 2nd and 3rd argument ignores strict_types). - (nielsdos) + . Fixed bug GH-19926 (reset internal pointer earlier while splicing array + while COW violation flag is still set). (alexandre-daubois) + . Added form feed (\f) in the default trimmed characters of trim(), rtrim() + and ltrim(). (Weilin Du) + . Invalid mode values now throw in array_filter() instead of being silently + defaulted to 0. (Jorg Sowa) + . Fixed bug GH-21058 (error_log() crashes with message_type 3 and + null destination). (David Carlier) + . Fixed bug GH-13204 (glob() fails if square bracket is in current directory). + (ndossche) + . Add array size maximum to array_diff(). (ndossche) + . Add enum SortDirection. (timwolla) + . pathinfo() raises a ValueError with an invalid $flags argument. + (David Carlier) + . Passing an invalid flag value to the second argument of scandir() will now + throw a ValueError. (alexandre-daubois) + . array_change_key_case() now raises a ValueError when an invalid $case + argument value is passed. (Girgias) + . linkinfo() now raises a ValueError when the argument is an empty string. + (Weilin Du) + . getenv() and putenv() now raises a ValueError when the first argument + contains null bytes. (Weilin Du) + . parse_str() now raises a ValueError when the $string argument contains + null bytes. (Weilin Du) + . proc_open() now raises a ValueError when the $cwd argument contains + null bytes. (Weilin Du) + . ini_get_all() now includes the built-in default value in the details. + (sebastian) - Streams: - . Fixed bug GH-16889 (stream_select() timeout useless for pipes on Windows). - (cmb) - -- Tests: - . Allow to shuffle tests even in non-parallell mode. (dhuang00) - -- Tidy: - . tidy::__construct/parseFile/parseString methods throw an exception if - the configuration argument is invalid. (David Carlier) - -- Windows: - . Fixed bug GH-10992 (Improper long path support for relative paths). (cmb, - nielsdos) - . Fixed bug GH-16843 (Windows phpize builds ignore source subfolders). (cmb) - -- XMLWriter: - . Improved performance and reduce memory consumption. (nielsdos) - -- XSL: - . Implement request #30622 (make $namespace parameter functional). (nielsdos) + . Added so_keepalive, tcp_keepidle, tcp_keepintvl and tcp_keepcnt stream + socket context options. + . Added so_reuseaddr streams context socket option that allows disabling + address reuse. + . Fixed bug GH-20370 (User stream filters could violate typed property + constraints). (alexandre-daubois) + . Allowed filtered streams to be casted as fd for select. (Jakub Zelenka) + . Fixed bug GH-21221 (Prevent closing of innerstream of php://temp stream). + (ilutov) + . Improved stream_socket_server() bind failure error reporting. (ilutov) + . Fixed bug #49874 (ftell() and fseek() inconsistency when using stream + filters). (Jakub Zelenka) + +- URI: + . Added Uri\Rfc3986\Uri:getUriType() and Uri\WhatWg\Url:isSpecialScheme(). + (kocsismate) + . Added Uri\Rfc3986\Uri:getHostType() and Uri\WhatWg\Url:getHostType(). + (kocsismate) + +- Zip: + . Fixed ZipArchive callback being called after executor has shut down. + (ilutov) + . Support minimum version for libzip dependency updated to 1.0.0. + (David Carlier) + . Added ZipArchive::openString() method. + (Tim Starling, Soner Sayakci, Ghaith Olabi) - Zlib: - . gzfile, gzopen and readgzfile, their "use_include_path" argument - is now a boolean. (David Carlier) - . Fixed bug GH-16883 (gzopen() does not use the default stream context when - opening HTTP URLs). (nielsdos) - . Implemented GH-17668 (zlib streams should support locking). (nielsdos) - + . deflate_init() now raises a TypeError when the value for option + "level", "memory", "window", or "strategy" is not of type int. + (Weilin Du) + . inflate_init() now raises a TypeError when the value for option + "window" is not of type int. (Weilin Du) <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/README.md b/README.md index c5376f67725c..3f4e0534ede2 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,13 @@ PHP is a popular general-purpose scripting language that is especially suited to web development. Fast, flexible and pragmatic, PHP powers everything from your -blog to the most popular websites in the world. PHP is distributed under the -[PHP License v3.01](LICENSE). +blog to the most popular websites in the world. -[![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://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:php) +PHP is distributed under the [Modified BSD License](LICENSE) +(SPDX-License-Identifier: `BSD-3-Clause`). + +[![Test](https://github.com/php/php-src/actions/workflows/test.yml/badge.svg)](https://github.com/php/php-src/actions/workflows/test.yml) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://issues.oss-fuzz.com/issues?q=project:php) ## Documentation @@ -42,28 +44,50 @@ a default build, you will additionally need libxml2 and libsqlite3. On Ubuntu, you can install these using: - sudo apt install -y pkg-config build-essential autoconf bison re2c \ - libxml2-dev libsqlite3-dev +```shell +sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev libsqlite3-dev +``` On Fedora, you can install these using: - sudo dnf install re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel +```shell +sudo dnf install re2c bison autoconf make ccache libxml2-devel sqlite-devel +``` + +On MacOS, you can install these using `brew`: + +```shell +brew install autoconf bison re2c libiconv libxml2 sqlite +``` + +or with `MacPorts`: + +```shell +sudo port install autoconf bison re2c libiconv libxml2 sqlite3 +``` Generate configure: - ./buildconf +```shell +./buildconf +``` Configure your build. `--enable-debug` is recommended for development, see `./configure --help` for a full list of options. - # For development - ./configure --enable-debug - # For production - ./configure +```shell +# For development +./configure --enable-debug +# For production +./configure +``` -Build PHP. To speed up the build, specify the maximum number of jobs using `-j`: +Build PHP. To speed up the build, specify the maximum number of jobs using the +`-j` argument: - make -j4 +```shell +make -j4 +``` The number of jobs should usually match the number of available cores, which can be determined using `nproc`. @@ -74,13 +98,21 @@ 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`: +`TEST_PHP_ARGS` or `TESTS`: - make TEST_PHP_ARGS=-j4 test +```shell +make TEST_PHP_ARGS=-j4 test +``` Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum number of jobs should not exceed the number of cores available. +Use the `TEST_PHP_ARGS` or `TESTS` variable to test only specific directories: + +```shell +make TESTS=tests/lang/ test +``` + The [qa.php.net](https://qa.php.net) site provides more detailed info about testing and quality assurance. @@ -88,9 +120,11 @@ testing and quality assurance. After a successful build (and test), PHP may be installed with: - make install +```shell +make install +``` -Depending on your permissions and prefix, `make install` may need super user +Depending on your permissions and prefix, `make install` may need superuser permissions. ## PHP extensions diff --git a/SECURITY.md b/SECURITY.md index deb5a7a950a4..8a45d86049ee 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,6 +11,29 @@ Vulnerability reports remain private until published. When published, you will be credited as a contributor, and your contribution will reflect the MITRE Credit System. +# Classification + +Issues commonly reported that are _not_ considered security issues include (but +are not limited to): + +- Invocation of specially crafted, malicious code intended to cause memory + violations. This commonly includes malicious error handlers, destructors or + `__toString()` functions. PHP does not offer sandboxing, and the execution of + untrusted code is always considered unsafe. Such issues are bugs, but not + security issues. They may still be reported, though please avoid reporting + the known issues. + +- Passing malicious arguments to functions clearly not intended to receive + unsanitized values, e.g. `mysqli_query()`. `escapeshellarg()` on the other + hand should clearly be hardened against unsafe inputs. + +- The use of legacy APIs or settings known to be insecure, particularly those + documented as such, or those with a secure alternative. + +- The use of FFI. + +- `open_basedir` or `disable_functions` bypasses. + # Vulnerability Policy Our full policy is described at diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index 80d6cbad0443..ea13552c8374 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -175,9 +175,14 @@ TSRM_API bool tsrm_is_managed_thread(void); #define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)]) #define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element) #define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset))) +#ifdef __cplusplus +#define TSRMLS_MAIN_CACHE_EXTERN() extern "C" { extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR; } +#define TSRMLS_CACHE_EXTERN() extern "C" { extern TSRM_TLS void *TSRMLS_CACHE; } +#else #define TSRMLS_MAIN_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR; -#define TSRMLS_MAIN_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL; #define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE; +#endif +#define TSRMLS_MAIN_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL; #define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL; #define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache() #define TSRMLS_CACHE _tsrm_ls_cache diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c index 4c8fc9d19aa9..90317ab64b19 100644 --- a/TSRM/tsrm_win32.c +++ b/TSRM/tsrm_win32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Daniel Beulshausen | +----------------------------------------------------------------------+ diff --git a/TSRM/tsrm_win32.h b/TSRM/tsrm_win32.h index c5bdc492be1b..9c16bd7c654b 100644 --- a/TSRM/tsrm_win32.h +++ b/TSRM/tsrm_win32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Daniel Beulshausen | +----------------------------------------------------------------------+ diff --git a/UPGRADING b/UPGRADING index 4c6e40cfdeba..539a575d4604 100644 --- a/UPGRADING +++ b/UPGRADING @@ -1,4 +1,4 @@ -PHP 8.5 UPGRADE NOTES +PHP 8.6 UPGRADE NOTES 1. Backward Incompatible Changes 2. New Features @@ -19,408 +19,382 @@ PHP 8.5 UPGRADE NOTES 1. Backward Incompatible Changes ======================================== -- BZ2: - . bzcompress() now throws a ValueError when $block_size is not between - 1 and 9. - . bzcompress() now throws a ValueError when $work_factor is not between - 0 and 250. - -- Core: - . It is no longer possible to use "array" and "callable" as class alias names - in class_alias(). - . Loosely comparing uncomparable objects (e.g. enums, \CurlHandle and other - internal classes) to booleans was previously inconsistent. If compared to a - boolean literal $object == true, it would behave the same way as (bool) - $object. If compared to a statically unknown value $object == $true, it - would always return false. This behavior was consolidated to always follow - the behavior of (bool) $object. - . The return value of gc_collect_cycles() no longer includes strings and - resources that were indirectly collected through cycles. - . It is now allowed to substitute static with self or the concrete class name - in final subclasses. - . The tick handlers are now deactivated after all shutdown functions, destructors - have run and the output handlers have been cleaned up. - This is a consequence of fixing GH-18033. - . Traits are now bound before the parent class. This is a subtle behavioral - change, but should more closely match user expectations, demonstrated by - GH-15753 and GH-16198. - -- FileInfo: - . finfo_file() and finfo::file() now throws a ValueError instead of a - TypeError when $filename contains nul bytes. - This aligns the type of Error thrown to be consistent with the rest of - the language. +- DOM: + . Properties previously documented as @readonly (e.g. DOMNode::$nodeType, + DOMDocument::$xmlEncoding, DOMEntity::$actualEncoding, ::$encoding, + ::$version) are now declared with asymmetric visibility + (public private(set)). Attempts to write to them from outside the + class now raise "Cannot modify private(set) property ::$ + from global scope" instead of the prior readonly modification error. + ReflectionProperty::isWritable() also reports these properties + accurately. + +- GD: + . imagesetstyle(), imagefilter() and imagecrop() filter their + array arguments types/values and raise a TypeError/ValueError + accordingly. - Intl: - . The extension now requires at least ICU 57.1. - . The behaviour of Collator::SORT_REGULAR with respect to handling numeric - strings is now aligned with the behaviour of SORT_REGULAR in ext/standard. - This is a consequence of fixing bug GH-18566. - -- LDAP: - . ldap_get_option() and ldap_set_option() now throw a ValueError when - passing an invalid option. - -- MySQLi: - . Calling the mysqli constructor on an already-constructed object - is now no longer possible and throws an Error. + . Passing a non-stringable object as a time zone to Intl APIs that accept + time zone objects or strings now raises a TypeError instead of an Error. + . IntlBreakIterator::getLocale() now raises a ValueError when the type is + neither Locale::ACTUAL_LOCALE nor Locale::VALID_LOCALE instead of + returning false. + . MessageFormatter::parse() and parseMessage() now return PHP_INT_MIN as + int, rather than float, on 64-bit platforms when parsing integer values. + . The $type parameter of IntlBreakIterator::getPartsIterator() has been + changed from string to int to match the underlying implementation. - PCNTL: - . pcntl_exec() now throws ValueErrors when entries of the $args parameter - contain null bytes. - . pcntl_exec() now throws ValueErrors when entries or keys of the - $env_vars parameter contain null bytes. + . pcntl_alarm() now raises a ValueError if the seconds argument is + lower than zero or greater than platform's UINT_MAX. + . pcntl_exec() now raises a ValueError if the $args argument is not a list + array. - PCRE: - . The extension is compiled without semi-deprecated - PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK compile option. - https://github.com/PCRE2Project/pcre2/issues/736#issuecomment-2754024651 - -- PDO: - . The constructor arguments set in conjunction with PDO::FETCH_CLASS now - follow the usual CUFA (call_user_func_array) semantics. - This means string keys will act like a named argument. - Moreover, automatic wrapping for by-value arguments passed to a by-ref - parameter has been removed, and the usual E_WARNING about this is now - emitted. - To pass a variable by-ref to a constructor argument use the general - array value reference assignment: $ctor_args = [&$valByRef] - . Attempting to call PDOStatement::setFetchMode during a call to PDO::fetch(), - PDO::fetchObject(), PDO::fetchAll(), - for example using tricks such as passing the statement object as a constructor - argument when fetching into an object, will now throw an Error. - . The value of the constants PDO::FETCH_GROUP, PDO::FETCH_UNIQUE, - PDO::FETCH_CLASSTYPE, PDO::FETCH_PROPS_LATE, and PDO::FETCH_SERIALIZE - have changed. - . A ValueError is now thrown if PDO::FETCH_PROPS_LATE is used with a fetch - mode different than PDO::FETCH_CLASS, consistent with other fetch flags. - . A ValueError is now thrown if PDO::FETCH_INTO is used as a fetch mode in - PDO::fetchAll(), similar to PDO::FETCH_LAZY. - -- PDO_FIREBIRD: - . A ValueError is now thrown when trying to set a cursor name that is too - long on a PDOStatement resulting from the Firebird driver. + . preg_grep() now returns false instead of a partial array when a PCRE + execution error occurs (e.g. malformed UTF-8 input with the /u modifier). + This is consistent with other preg_* functions. + +- Phar: + . Phar::mungServer() now raises a ValueError when an invalid + argument value is passed instead of being silently ignored. + . Phar::addEmptyDir() now rejects `/.phar` paths in addition to `.phar` + paths, and raises the same BadMethodCallException for attempts to create + the reserved magic ".phar" directory through that form. + . Phar::addEmptyDir() now treats non-magic names that merely share the + `.phar` prefix as ordinary directories. -- Session: - . Attempting to write session data where $_SESSION has a key containing - the pipe character will now emit a warning instead of silently failing. +- PGSQL: + . pg_fetch_object() now reports the ValueError for a non-empty + $constructor_args on a class without a constructor on the + $constructor_args argument instead of $class. Errors raised when + the requested class is not instantiable (abstract, interface, enum) + now surface before the row is fetched. + +- Posix: + . posix_access() now raises a ValueError when an invalid $flags + argument value is passed. + . posix_mkfifo() now raises a ValueError when an invalid $permissions + argument value is passed. -- SimpleXML: - . Passing an XPath expression that returns something other than a node set - to SimpleXMLElement::xpath() will now emit a warning and return false, - instead of silently failing and returning an empty array. +- Session: + . Setting session.cookie_path, session.cookie_domain, or session.cache_limiter + to a value containing null bytes now emits a warning and leaves the setting + unchanged. Previously, null bytes were silently accepted: for cookie_path and + cookie_domain this caused the SAPI to drop the Set-Cookie header; for + cache_limiter the value was silently truncated at the null byte. + . A ValueError is not thrown if $name is a string containing null bytes in + session_module_name(). + . session_encode() now returns an empty string instead of false for empty + sessions. It only returns false now when the session data could not be + encoded. This mainly happens with the default serialization handler + if a key contains the pipe | character. + . When session.lazy_write is enabled and a session handler implements + SessionUpdateTimestampHandlerInterface, sessions that were read as empty + and remain empty at write time will now trigger updateTimestamp() instead + of write(). Previously, write() was always called for empty sessions + because session_encode() returned false, bypassing the lazy_write + comparison. Custom session handlers that rely on write() being called + with empty data (e.g. to destroy the session) should implement the same + logic in their updateTimestamp() method. + . The defaults of three session INI settings have changed to provide secure + behavior out of the box: + - session.use_strict_mode is now 1 (was 0). Strict mode rejects + uninitialized session IDs, mitigating session fixation. Custom session + handlers that previously relied on accepting externally supplied IDs + without a corresponding storage entry must either implement + validateId() / create_sid() or explicitly set this to 0. + - session.cookie_httponly is now 1 (was 0). Session cookies are no + longer accessible to JavaScript via document.cookie. Applications + that read the session cookie from JavaScript must explicitly set + this to 0. + - session.cookie_samesite is now "Lax" (was unset). Session cookies + are no longer sent on cross-site requests other than top-level + navigations using safe HTTP methods. Applications that depend on + session cookies being sent on cross-site POST submissions must + explicitly set this to "None" (and also set session.cookie_secure + to 1). + RFC: https://wiki.php.net/rfc/session_security_defaults - SPL: - . ArrayObject no longer accepts enums, as modifying the $name or $value - properties can break engine assumptions. - . SplFileObject::fwrite's parameter $length is now nullable. The default - value changed from 0 to null. + . SplObjectStorage::getHash() implementations may no longer mutate any + SplObjectStorage instance. Attempting to do so now throws an Error. + . SplFileObject::next() now advances the stream when no prior current() + call has cached a line. A subsequent current() call returns the new + line rather than the previous one. + . SplFileObject::fgets() no longer caches the returned line for + subsequent current() calls. current() now re-reads from the current + stream position instead of returning the line fgets() just returned. + . SplFileObject::next() past EOF no longer increments key() without + bound. SplFileObject::seek() past EOF now produces the same key() + value as SplTempFileObject; the two previously returned different + values. + +- Standard: + . Form feed (\f) is now added in the default trimmed characters of trim(), + rtrim() and ltrim(). RFC: https://wiki.php.net/rfc/trim_form_feed + . array_filter() now raises a ValueError when an invalid $mode + argument value is passed. + . array_change_key_case() now raises a ValueError when an invalid $case + argument value is passed. + . getenv() and putenv() now raises a ValueError when the first argument + contains null bytes. + . parse_str() now raises a ValueError when the $string argument contains + null bytes. + . linkinfo() now raises a ValueError when the $path argument is empty. + . pathinfo() now raises a ValueError when an invalid $flag + argument value is passed. + . scandir() now raises a ValueError when an invalid $sorting_order + argument value is passed. + . proc_open() now raises a ValueError when the $cwd argument contains + null bytes. + +- Zip: + . ZipArchive::extractTo now raises a TypeError for the + files argument if one or more of the entries is not + a string. + +- Zlib: + . deflate_init() now raises a TypeError when the value for option + "level", "memory", "window", or "strategy" is not of type int. + . inflate_init() now raises a TypeError when the value for option + "window" is not of type int. ======================================== 2. New Features ======================================== - Core: - . Closure is now a proper subtype of callable - . Added support for Closures and first class callables in constant - expressions. - RFC: https://wiki.php.net/rfc/closures_in_const_expr - RFC: https://wiki.php.net/rfc/fcc_in_const_expr - . Fatal Errors (such as an exceeded maximum execution time) now include a - backtrace. - RFC: https://wiki.php.net/rfc/error_backtraces_v2 - . Added the #[\NoDiscard] attribute to indicate that a function's return - value is important and should be consumed. - RFC: https://wiki.php.net/rfc/marking_return_value_as_important - . Added the (void) cast to indicate that not using a value is intentional. - The (void) cast has no effect on the program's execution by itself, but - it can be used to suppress warnings emitted by #[\NoDiscard] and possibly - also diagnostics emitted by external IDEs or static analysis tools. - RFC: https://wiki.php.net/rfc/marking_return_value_as_important - . Added asymmetric visibility support for static properties. - RFC: https://wiki.php.net/rfc/static-aviz - . Added support for casts in constant expressions. - . Added support for attributes on compile-time non-class constants. - RFC: https://wiki.php.net/rfc/attributes-on-constants - . The #[\Deprecated] attribute can now be used on constants. - RFC: https://wiki.php.net/rfc/attributes-on-constants - . Added the pipe (|>) operator. - RFC: https://wiki.php.net/rfc/pipe-operator-v3 - . Constructor property promotion can now be used for final properties. - RFC: https://wiki.php.net/rfc/final_promotion - -- Curl: - . Added support for share handles that are persisted across multiple PHP - requests, safely allowing for more effective connection reuse. - RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement - . Added support for CURLINFO_USED_PROXY (libcurl >= 8.7.0), - CURLINFO_HTTPAUTH_USED, and CURLINFO_PROXYAUTH_USED - (libcurl >= 8.12.0) to the curl_getinfo() function. - When curl_getinfo() returns an array, the same information - is available as "used_proxy", "httpauth_used", and "proxyauth_used" - keys. - CURLINFO_USED_PROXY gets zero set if no proxy was used in the - previous transfer or a non-zero value if a proxy was used. - CURLINFO_HTTPAUTH_USED and CURLINFO_PROXYAUTH_USED get bitmasks - indicating the HTTP and proxy authentication methods that were - used in the previous request. See CURLAUTH_* constants for - possible values. - . Added CURLOPT_INFILESIZE_LARGE Curl option, which is a safe - replacement for CURLOPT_INFILESIZE. On certain systems, - CURLOPT_INFILESIZE only accepts a 32-bit signed integer as the file - size (2.0 GiB) even on 64-bit systems. CURLOPT_INFILESIZE_LARGE - accepts the largest integer value the system can handle. - . Added CURLFOLLOW_OBEYCODE, CURLFOLLOW_FIRSTONLY and CURLFOLLOW_ALL values for - CURLOPT_FOLLOWLOCATION curl_easy_setopt option. - CURLFOLLOW_OBEYCODE to follow more strictly in regard to redirect - if they are allowed. CURLFOLLOW_FIRSTONLY to follow only the - first redirect thus if there is any follow up redirect, it won't go - any further. CURLFOLLOW_ALL is equivalent to setting CURLOPT_FOLLOWLOCATION - to true. - -- DOM: - . Added Dom\Element::$outerHTML. + . Added support for runtime-bound-checked generics. Classes, interfaces, + traits, functions, methods, closures, and arrow functions can now declare + type parameters with optional bounds (`T : Foo`), defaults (`T = int`), + and variance markers (`+T`, `-T`): + + class Box { + public T $value; + public function get(): T { return $this->value; } + } + + function id(T $x): T { return $x; } + + Call sites accept turbofish type arguments (`Box::::new()`, + `id::(7)`); use sites accept type arguments on named types + (`Box`, `array`, `iterable`, `self`, + `static`, `parent`). Recursive bounds (`T : Comparable`) + are supported. Anonymous classes cannot declare type parameters. + + Generics are reified along two axes. Class-like generics are + monomorphised: each distinct argument tuple (`Box`, + `Box`) synthesises a separate class entry whose canonical + name is spelled out (`"Box"`), registered in the class table, + and visible through `get_class()`, `var_dump`, and + `instanceof Box`. Function- and method-level generics are + reified per call frame: each call carries its own type-argument + table, with no persistent `id` function entry (avoiding + unbounded growth). Closures and generators preserve the table so + it survives suspension. + + Ordinary parameter, return, and property type-checks run against + each parameter's declared *bound* (or `mixed` when unbounded, or + when the bound is invalid in the target position - e.g. `callable` + on a property). The bound is the answer to "what can a caller + actually pass at this slot." Reified type arguments are kept on a + side table and consulted at well-defined runtime points: monomorph + synthesis, turbofish argument validation, deferred lookups for + `instanceof Box` / `catch (Box $e)`, bare `T`-ref resolution + (`instanceof T`, `catch (T $e)`, `new T()`, `T::method()`), + inheritance linking, and Reflection. + . It is now possible to use reference assign on WeakMap without the key + needing to be present beforehand. + . It is now possible to define the `__debugInfo()` magic method on enums. + RFC: https://wiki.php.net/rfc/debugable-enums -- EXIF: - . Add OffsetTime* Exif tags. +- Fileinfo: + . finfo_file() now works with remote streams. - Intl: - . Added class constants NumberFormatter::CURRENCY_ISO, - NumberFormatter::CURRENCY_PLURAL, NumberFormatter::CASH_CURRENCY, - and NumberFormatter::CURRENCY_STANDARD for various currency-related - number formats. - . Added Locale::addLikelySubtags and Locale::minimizeSubtags to - handle likely tags on a given locale. - . Added IntlListFormatter class to format, order, and punctuate - a list of items with a given locale, IntlListFormatter::TYPE_AND, - IntlListFormatter::TYPE_OR, IntlListFormatter::TYPE_UNITS operands and - IntlListFormatter::WIDTH_WIDE, IntlListFormatter::WIDTH_SHORT and - IntlListFormatter::WIDTH_NARROW widths. - It is supported from icu 67. - -- PDO_Sqlite: - . Added class constant Pdo_Sqlite::ATTR_BUSY_STATEMENT. - . Added class constants Pdo_Sqlite::ATTR_EXPLAIN_STATEMENT, - Pdo_Sqlite::EXPLAIN_MODE_PREPARED, Pdo_Sqlite::EXPLAIN_MODE_EXPLAIN, - Pdo_Sqlite::EXPLAIN_MODE_EXPLAIN_QUERY_PLAN. - -- SOAP: - . Enumeration cases are now dumped in __getTypes(). - . Implemented request #61105: - support for Soap 1.2 Reason Text xml:lang attribute. - The signature of SoapFault::__construct() and SoapServer::fault() therefore - now have an optional $lang parameter. - This support solves compatibility with .NET SOAP clients. - -- Sqlite: - . Added class constants Sqlite3Stmt::EXPLAIN_MODE_PREPARED, - Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN and - Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN_QUERY_PLAN. - -- XSL: - . The $namespace argument of XSLTProcessor::getParameter(), - XSLTProcessor::setParameter() and XSLTProcessor::removeParameter() - now actually works instead of being treated as empty. - This only works if the $name argument does not use Clark notation - and is not a QName because in those cases the namespace is taken - from the namespace href or prefix respectively. - -- Zlib: - . flock() is now supported on zlib streams. Previously, this always - failed to perform any locking action. + . Added IntlNumberRangeFormatter class to format an interval of two numbers + with a given skeleton, locale, IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::COLLAPSE_NONE, + IntlNumberRangeFormatter::COLLAPSE_UNIT, + IntlNumberRangeFormatter::COLLAPSE_ALL collapse and + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY and + IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE identity fallbacks. + It is supported from icu 63. + +- JSON: + . Added extra info about error location to the JSON error messages returned + from json_last_error_msg() and JsonException message. + +- OpenSSL: + . Added TLS session resumption support for streams with new stream context + options: session_data, session_new_cb, session_cache, session_cache_size, + session_timeout, session_id_context, session_get_cb, session_remove_cb, + and num_tickets. This allows saving and restoring client sessions across + requests, implementing custom server-side session storage, and controlling + session cache behavior. + RFC: https://wiki.php.net/rfc/tls_session_resumption + . Added TLS external PSK support for streams with new strem context options: + psk_client_cb and psk_server_cb. This allows setting and receiving PSK. + +- Phar: + . Overriding the getMTime() and getPathname() methods of SplFileInfo now + influences the result of the phar buildFrom family of functions. + This makes it possible to override the timestamp and names of files. + +- Streams: + . Added stream socket context option so_reuseaddr that allows disabling + address reuse (SO_REUSEADDR) and explicitly uses SO_EXCLUSIVEADDRUSE on + Windows. + . Added stream socket context options so_keepalive, tcp_keepidle, + tcp_keepintvl and tcp_keepcnt that allow setting socket keepalive + options. + . Allowed casting casting filtered streams as file descriptor for select. + +- URI: + . Added Uri\Rfc3986\Uri:getUriType() and Uri\WhatWg\Url:isSpecialScheme(). + RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection + . Added Uri\Rfc3986\Uri:getHostType() and Uri\WhatWg\Url:getHostType(). + RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection ======================================== 3. Changes in SAPI modules ======================================== -- CLI: - . Trying to set a process title that is too long with cli_set_process_title() - will now fail instead of silently truncating the given title. - . Added a new --ini=diff option to print INI settings changed from the builtin - default. - -- FPM: - . FPM with httpd ProxyPass decodes the full script path. Added - fastcgi.script_path_encoded INI setting to prevent this new behavior. - ======================================== 4. Deprecated Functionality ======================================== -- Hash: - . The MHASH_* constants have been deprecated. These have been overlooked - when the mhash*() function family has been deprecated per - https://wiki.php.net/rfc/deprecations_php_8_1#mhash_function_family +- Core: + . Specifying a return type of array|null / ?array for __debugInfo() is now + deprecated. Specify array instead. + +- GMP + . The shift (<<, >>) and exponentiation (**) operators on GMP objects now + emit a deprecation warning when converting a float right operand to int + loses precision. + +- Mbstring: + . Mbregex has been deprecated, because the underlying Oniguruma library + is no longer maintained. + RFC: https://wiki.php.net/rfc/eol-oniguruma ======================================== 5. Changed Functions ======================================== -- Intl: - . IntlDateFormatter::setTimeZone()/datefmt_set_timezone() - throws an IntlException on uninitialised classes/clone failures. - . grapheme_extract() properly assigns $next value when skipping over - invalid starting bytes. Previously there were cases where it would - point to the start of the grapheme boundary instead of the end. - . Locale:: methods throw a ValueError when locale inputs contain null - bytes. - . transliterator_get_error_code(), transliterator_get_error_message() - TransLiterator::getErrorCode(), and TransLiterator::getErrorMessage() - have dropped the false from the return type union. Returning false - was actually never possible. - -- LDAP: - . ldap_get_option() now accepts a NULL connection, as ldap_set_option(), - to allow retrieval of global options. - -- libxml: - . libxml_set_external_entity_loader() now has a formal return type of true. - -- PCNTL: - . pcntl_exec() now has a formal return type of false. - -- PDO_PGSQL: - . PDO::pgsqlCopyFromArray also supports inputs as Iterable. - . Pdo\Pgsql::setAttribute and Pdo\Pgsql::prepare supports - PDO::ATTR_PREFETCH sets to 0 which set to lazy fetch mode. - In this mode, statements cannot be run in parallel. - -- PDO_SQLITE: - . SQLite PDO::quote() will now throw an exception or emit a warning, - depending on the error mode, if the string contains a null byte. - . PDO::sqliteCreateCollation will now throw an exception - if the callback has the wrong return type, making it more - in line with Pdo_Sqlite::createCollation behavior. - -- PGSQL: - . pg_copy_from also supports inputs as Iterable. - . pg_connect checks if the connection_string argument contains - any null byte. - . pg_close_stmt checks if the statement_name argument contains - any null byte. - -- POSIX: - . posix_ttyname sets last_error to EBADF when encountering - an invalid file descriptor. - . posix_isatty raises an E_WARNING message when encountering - an invalid file descriptor. - . posix_fpathconf checks invalid file descriptors and sets - last_error to EBADF and raises an E_WARNING message. - -- Reflection: - . The output of ReflectionClass::toString() for enums has changed to - better indicate that the class is an enum, and that the enum cases - are enum cases rather than normal class constants. - -- Session: - . session_start is stricter in regard to the option argument. - It throws a ValueError if the whole is not a hashmap or - a TypeError if read_on_close value is not a valid type - compatible with int. - -- SNMP: - . snmpget, snmpset, snmp_get2, snmp_set2, snmp_get3, snmp_set3 - and SNMP::__construct() throw a ValueError when the hostname - is too large, contains any null byte or if the port is given - when negative or greater than 65535, timeout and retries values - are lower than -1 or too large. +- GMP: + . gmp_fact() now throws a ValueError() if $num does not fit into + a unsigned long. + . gmp_pow(), gmp_binomial(), gmp_root() and gmp_rootrem() now throw a + ValueError if their second argument does not fit into an unsigned long. + . The shift (<<, >>) and exponentiation (**) operators on GMP objects + now throw a ValueError if the right operand does not fit into an + unsigned long. + . gmp_powm() modulo-by-zero now raises a DivisionByZeroError whose + message includes the function name and argument index ($modulus). + +- mysqli: + . The return structure of mysqli_get_charset() no longer contains + the undocumented "comment" element. The value of "charsetnr" is + now set to a constant 0 as this number was an implementation detail + that should not have been exposed to the public. + +- OpenSSL: + . Output of openssl_x509_parse() contains criticalExtensions listing all + critical certificate extensions. + +- PDO_DBLIB: + . When using persistent connections, there is now a liveness check in the + constructor. + +- Phar: + . Phar::mungServer() now supports reference values. - Sockets: - . socket_create_listen, socket_bind and socket_sendto throw a - ValueError if the port is lower than 0 or greater than 65535, - also if any of the hints array entry is indexes numerically. - . socket_addrinfo_lookup throws a TypeError if any of the hints - values cannot be cast to int and can throw a ValueError if - any of these values overflow. - . socket_set_option with MCAST_LEAVE_GROUP/MCAST_LEAVE_SOURCE_GROUP - options will throw an exception if the value isn't a valid object - or array. - . socket_create/socket_bind can create AF_PACKET family sockets. - . socket_getsockname gets the interface index and its string - representation with AF_PACKET socket. - -- Tidy: - . tidy::__construct/parseFile/parseString now throws a ValueError - if the configuration contains an invalid or set a read-only - internal entry, a TypeError contains, at least, one element - when the key is not a string. + . socket_addrinfo_lookup() now has an additional optional argument $error + when not null, and on failure, gives the error code (one of the EAI_* + constants). -- Zlib: - . The "use_include_path" argument for the - gzfile, gzopen and readgzfile functions had been changed - from int to boolean. - . gzfile, gzopen and readgzfile functions now respect the default - stream context. +- Standard: + . ini_get_all() now includes a "builtin_default_value" element for each + directive when $details is true. It holds the built-in default value of + the directive (or null if it has none), independent of values set in + php.ini, on the command line, or at runtime. ======================================== 6. New Functions ======================================== -- Core: - . get_error_handler() allows retrieving the current user-defined error handler - function. - RFC: https://wiki.php.net/rfc/get-error-exception-handler - . get_exception_handler() allows retrieving the current user-defined exception - handler function. - RFC: https://wiki.php.net/rfc/get-error-exception-handler - -- Curl: - . curl_multi_get_handles() allows retrieving all CurlHandles current - attached to a CurlMultiHandle. This includes both handles added using - curl_multi_add_handle() and handles accepted by CURLMOPT_PUSHFUNCTION. - . curl_share_init_persistent() allows creating a share handle that is - persisted across multiple PHP requests. - RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement - -- DOM: - . Added Dom\Element::insertAdjacentHTML(). - -- Enchant: - . Added enchant_dict_remove_from_session() to remove a word added to the - spellcheck session via enchant_dict_add_to_session(). - . Added enchant_dict_remove() to put a word on the exclusion list and - remove it from the session dictionary. +- Reflection: + . ReflectionConstant::inNamespace() + . Added ReflectionProperty::isReadable() and ReflectionProperty::isWritable(). + RFC: https://wiki.php.net/rfc/isreadable-iswriteable + . Added ReflectionParameter::getDocComment(). + RFC: https://wiki.php.net/rfc/parameter-doccomments + . Added ReflectionFunctionAbstract::isGeneric() and + ReflectionFunctionAbstract::getGenericParameters() (covers + ReflectionFunction, ReflectionMethod, closures, and arrow functions). + . Added ReflectionClass::isGeneric() and + ReflectionClass::getGenericParameters(). + . Added ReflectionClass::getGenericArgumentsForParentClass(), + ReflectionClass::getGenericArgumentsForParentInterface(string $name), + and ReflectionClass::getGenericArgumentsForUsedTrait(string $name) for + inspecting the type arguments supplied at a class's own extends / + implements / use sites. Returns null when no type arguments were + specified for that ancestor at this class's clause site (consumers + enumerate ancestors via the existing getParentClass() / getInterfaces() + / getTraits() APIs). + . Added ReflectionNamedType::hasGenericArguments() and + ReflectionNamedType::getGenericArguments(). The arguments are returned + as ReflectionType instances in source order (reified form); + ReflectionNamedType::getName() returns the bound's name - i.e. the + type a caller can actually pass at the slot - so it stays useful for + runtime checks. Use getGenericArguments() to recover the reified + shape, and look for ReflectionTypeParameterReference inside the + returned list when a slot is itself a type-parameter reference. - Intl: - . Added locale_is_right_to_left/Locale::isRightToLeft, returns true if - the locale is written right to left (after its enrichment with likely subtags). - . Added grapheme_levenshtein() function. - RFC: https://wiki.php.net/rfc/grapheme_levenshtein + . `grapheme_strrev()` returns strrev for grapheme cluster unit. + RFC: https://wiki.php.net/rfc/grapheme_strrev -- Pdo\Sqlite: - . Added support for Pdo\Sqlite::setAuthorizer(), which is the equivalent of - SQLite3::setAuthorizer(). The only interface difference is that the - pdo version returns void. - -- PGSQL: - . pg_close_stmt offers an alternative way to close a prepared - statement from the DEALLOCATE sql command in that we can reuse - its name afterwards. - . pg_service returns the ongoing service name of the connection. - -- Reflection: - . ReflectionConstant::getFileName() was introduced. - . ReflectionConstant::getExtension() and - ReflectionConstant::getExtensionName() were introduced. - . ReflectionConstant::getAttributes() was introduced. - RFC: https://wiki.php.net/rfc/attributes-on-constants - -- Sqlite: - . Sqlite3Stmt::busy to check if a statement had been fetched - but not completely. +- mysqli: + . Added `mysqli::quote_string()` and `mysqli_quote_string()`. + RFC: https://wiki.php.net/rfc/mysqli_quote_string - Standard: - . Added array_first() and array_last(). - RFC: https://wiki.php.net/rfc/array_first_last + . `clamp()` returns the given value if in range, else return the nearest + bound. + RFC: https://wiki.php.net/rfc/clamp_v2 + +- Zip: + . Added ZipArchive::openString() method. ======================================== 7. New Classes and Interfaces ======================================== -- Curl: - . CurlSharePersistentHandle representing a share handle that is persisted - across multiple PHP requests. - RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement +- OpenSSL: + . Openssl\OpensslException + . Openssl\Session + RFC: https://wiki.php.net/rfc/tls_session_resumption + . Openssl\Psk + +- Reflection: + . ReflectionGenericTypeParameter (final, instances obtained via + ReflectionClass::getGenericParameters() and + ReflectionFunctionAbstract::getGenericParameters()). + . ReflectionTypeParameterReference (extends ReflectionType, appears only + inside reified type expressions: bounds, defaults, and the elements of + ReflectionNamedType::getGenericArguments()). + . enum ReflectionGenericVariance { Invariant; Covariant; Contravariant }. + +- Standard: + . enum SortDirection + RFC: https://wiki.php.net/rfc/sort_direction_enum ======================================== 8. Removed Extensions and SAPIs @@ -430,182 +404,107 @@ PHP 8.5 UPGRADE NOTES 9. Other Changes to Extensions ======================================== -- Curl: - . curl_easy_setopt with CURLOPT_FOLLOWLOCATION option's value no longer - is treated as boolean but integer to handle CURLFOLLOW_OBEYCODE and - CURLFOLLOW_FIRSTONLY. - -- Fileinfo: - . Upgraded to file 5.46. - . The return type of finfo_close() has been changed to true, rather - than bool. - -- Lexbor: - . An always enabled lexbor extension is added. It contains the lexbor - library that was separated from ext/dom for being reused among other - extensions. The new extension is not directly exposed to userland. - -- PCRE: - . Upgraded to pcre2lib from 10.44 to 10.45. - -- PDO_Sqlite: - . Increased minimum release version support from 3.7.7 to 3.7.17. +- Hash: + . The bundled version of xxHash was upgraded to 0.8.2. -- Readline: - . The return types of readline_add_history(), readline_clear_history(), and - readline_callback_handler_install() have been changed to true, rather - than bool. +- mysqli + . Added new constant MYSQLI_OPT_COMPRESS. ======================================== 10. New Global Constants ======================================== -- Core: - . PHP_BUILD_DATE. - -- Curl: - . CURLINFO_USED_PROXY. - . CURLINFO_HTTPAUTH_USED. - . CURLINFO_PROXYAUTH_USED. - . CURLOPT_INFILESIZE_LARGE. - . CURLFOLLOW_ALL. - . CURLFOLLOW_OBEYCODE. - . CURLFOLLOW_FIRSTONLY. - -- Intl: - . DECIMAL_COMPACT_SHORT. - . DECIMAL_COMPACT_LONG. - -- POSIX: - . POSIX_SC_OPEN_MAX. - - Sockets: - . IPPROTO_ICMP/IPPROTO_ICMPV6. - . TCP_FUNCTION_BLK (FreeBSD only). - . TCP_FUNCTION_ALIAS (FreeBSD only). - . TCP_REUSPORT_LB_NUMA (FreeBSD only). - . TCP_REUSPORT_LB_NUMA_NODOM (FreeBSD only). - . TCP_REUSPORT_LB_NUMA_CURDOM (FreeBSD only). - . TCP_BBR_ALGORITHM (FreeBSD only). - . AF_PACKET (Linux only). - . IP_BINDANY (FreeBSD/NetBSD/OpenBSD only). - . SO_BUSY_POLL (Linux only). - . UDP_SEGMENT (Linux only). - - SHUT_RD. - - SHUT_WR. - - SHUT_RDWR. - -- Tokenizer: - . T_VOID_CAST. - . T_PIPE. + . TCP_USER_TIMEOUT (Linux only). + . AF_UNSPEC. + . EAI_BADFLAGS. + . EAI_NONAME. + . EAI_AGAIN. + . EAI_FAIL. + . EAI_NODATA. + . EAI_FAMILY. + . EAI_SOCKTYPE. + . EAI_SERVICE. + . EAI_ADDRFAMILY. + . EAI_SYSTEM. + . EAI_OVERFLOW + . EAI_INPROGRESS. + . EAI_CANCELED. + . EAI_NOTCANCELED. + . EAI_ALLDONE. + . EAI_INTR. + . EAI_IDN_ENCODE. + +- Standard + . ARRAY_FILTER_USE_VALUE. ======================================== 11. Changes to INI File Handling ======================================== -- Core: - . Added fatal_error_backtraces to control whether fatal errors should include - a backtrace. - RFC: https://wiki.php.net/rfc/error_backtraces_v2 +- Mbstring: + . The mbstring.detect_order INI directive now updates the internal detection + order when changed at runtime via ini_set(). Previously, runtime changes + using ini_set() did not take effect for mb_detect_order(). Setting the + directive to NULL or an empty string at runtime now leaves the previously + configured detection order unchanged. + +- Mysqli: + . mysqli.default_port now checks the validity of the value which should be + between 0 and 65535 included. - Opcache: - . Added opcache.file_cache_read_only to support a read-only - opcache.file_cache directory, for use with read-only file systems - (e.g. read-only Docker containers). - Best used with opcache.validate_timestamps=0, - opcache.enable_file_override=1, - and opcache.file_cache_consistency_checks=0. - Note: A cache generated with a different build of PHP, a different file - path, or different settings (including which extensions are loaded), may be - ignored. - . The default value of opcache.jit_hot_loop is now 61 (a prime) to prevent it - from being a multiple of loop iteration counts. - It is recommended that this parameter is set to a prime number. + . opcache.jit_debug accepts a new flag: ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC. + When used along with ZEND_JIT_DEBUG_TRACE_EXIT_INFO, the source of exit + points is printed in exit info output, in debug builds. ======================================== 12. Windows Support ======================================== -* The configuration variables PHP_VERSION, PHP_MINOR_VERSION, and - PHP_RELEASE_VERSION are now always numbers. Previously, they have been - strings for buildconf builds. - -* phpize builds now reflect the source tree in the build dir (like that already - worked for in-tree builds); some extension builds (especially when using - Makefile.frag.w32) may need adjustments. - -* --enable-sanitizer is now supported for MSVC builds. This enables ASan and - debug assertions, and is supported as of MSVC 16.10 and Windows 10. - -* The --with-uncritical-warn-choke configuration option for clang builds is - no longer supported. Select warnings to suppress via CFLAGS instead. - -* COM: - . The extension is now build shared by default; previously it defaulted to a - static extension, although the official Windows binaries built a shared - extension. - -* FFI: - . It is no longer necessary to specify the library when using FFI::cdef() - and FFI::load(). However, this convenience feature should not be used in - production. - -* Streams: - . If only pipe streams are contained in the $read array, and the $write and - $except arrays are empty, stream_select() now behaves similar to POSIX - systems, i.e. the function only returns if at least one pipe is ready to be - read, or after the timeout expires. Previously, stream_select() returned - immediately, reporting all streams as ready to read. - ======================================== 13. Other Changes ======================================== -- Core: - . The high resolution timer (`hrtime()`) on macOS now uses the recommended - `clock_gettime_nsec_np(CLOCK_UPTIME_RAW)` API instead of - `mach_absolute_time()`. - -- CLI/CGI: - . The `-z` or `--zend-extension` option has been removed as it was - non-functional. Use `-d zend_extension=` instead. - ======================================== 14. Performance Improvements ======================================== - Core: - . Remove OPcodes for identity comparisons against booleans, particularly - for the match(true) pattern. - . Add OPcode specialization for `=== []` and `!== []` comparisons. - . Creating exception objects is now much faster. - . The parts of the code that used SSE2 have been adapted to use SIMD - with ARM NEON as well. - -- Intl: - . Now avoids creating extra string copies when converting strings - for use in the collator. + . `printf()` using only `%s` and `%d` will be compiled into the equivalent + string interpolation, avoiding the overhead of a function call and + repeatedly parsing the format string. + . Arguments are now passed more efficiently to known constructors (e.g. when + using new self()). + . array_map() using a first-class callable or partial function application + callback will be compiled into the equivalent foreach-loop, avoiding the + creation of intermediate Closures, the overhead of calling userland + callbacks from internal functions and providing for better insight for the + JIT. + . The performance of the TAILCALL VM has been improved. + . The TAILCALL VM is now enabled on Windows when compiling with Clang >= 19 + x86_64. -- MBString: - . The parts of the code that used SSE2 have been adapted to use SIMD - with ARM NEON as well. - -- ReflectionProperty: - . Improved performance of the following methods: getValue(), getRawValue(), - isInitialized(), setValue(), setRawValue(). +- DOM: + . Made splitText() faster and consume less memory. -- SPL: - . Improved performance of dimension accessors and methods of SplFixedArray. +- JSON: + . Improve performance of encoding arrays and objects. + . Improved performance of indentation generation in json_encode() + when using PHP_JSON_PRETTY_PRINT. - Standard: - . Improved performance of array functions with callbacks - (array_find, array_filter, array_map, usort, ...). - . Improved performance of urlencode() and rawurlencode(). - . Improved unpack() performance with nameless repetitions by avoiding - creating temporary strings and reparsing them. - -- XMLReader: - . Improved property access performance. - -- XMLWriter: - . Improved performance and reduce memory consumption. + . Improved performance of array_fill_keys(). + . Improved performance of array_map() with multiple arrays passed. + . Improved performance of array_sum() and array_product() for + integer-only arrays. + . Improved performance of array_unshift(). + . Improved performance of array_walk(). + . Improved performance of intval('+0b...', 2) and intval('0b...', 2). + . Improved performance of str_split(). + +- URI: + . Reduced allocations when reading RFC3986 IPv6/IPFuture hosts and paths. + +- Zip: + . Avoid string copies in ZipArchive::addFromString(). diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 432754528f09..f51602537bfa 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -1,4 +1,4 @@ -PHP 8.5 INTERNALS UPGRADE NOTES +PHP 8.6 INTERNALS UPGRADE NOTES 1. Internal API changes @@ -14,82 +14,317 @@ 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*`. - -- 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. + . ZSTR_INIT_LITERAL(), zend_string_starts_with_literal(), and + zend_string_starts_with_literal_ci() now support strings containing NUL + bytes. Passing non-literal char* is no longer supported. + . The misnamed ZVAL_IS_NULL() has been removed. Use Z_ISNULL() instead. + . New zend_class_entry.ce_flags2 and zend_function.fn_flags2 fields were + added, given the primary flags were running out of bits. + . The zval_is_true() alias of zend_is_true() has been removed. Call + zend_is_true() directly instead. + . The _zval_get_*() compatibility macros for PHP 7.2 have been removed + call the variant without the leading underscore instead. + Affected: _zval_get_long, _zval_get_double, _zval_get_string, + _zval_get_long_func, _zval_get_double_func, _zval_get_string_func + . CHECK_ZVAL_NULL_PATH() and CHECK_NULL_PATH() have been removed, use + zend_str_has_nul_byte(Z_STR_P(...)) and zend_char_has_nul_byte() + respectively. + . ZEND_LTOA() (and ZEND_LTOA_BUF_LEN) has been removed, as it was + unsafe. Directly use ZEND_LONG_FMT with a function from the + printf family. + . The zval_dtor() alias of zval_ptr_dtor_nogc() has been removed. + Call zval_ptr_dtor_nogc() directly instead. + . The internal zend_copy_parameters_array() function is no longer exposed. + . The zend_make_callable() function has been removed, if a callable zval + needs to be obtained use the zend_get_callable_zval_from_fcc() function + instead. If this was used to store a callable, then an FCC should be + stored instead. + . The zend_active_function{_ex}() functions now return a const zend_function + pointer. + . The zend_get_call_trampoline_func() API now takes the __call or + __callStatic zend_function* instead of a CE and a boolean argument. + . The zend_set_hash_symbol() API has been removed. + . Added zend_hash_str_lookup(). + . The WRONG_PARAM_COUNT and ZEND_WRONG_PARAM_COUNT() macros have been + removed. Call zend_wrong_param_count(); followed by RETURN_THROWS(); + instead. + . PHP_HAVE_STREAMS macro removed from . + . zend_function.arg_info is now always a zend_arg_info*. Before, it was a + zend_internal_arg_info on internal functions, unless the + ZEND_ACC_USER_ARG_INFO flag was set. + . Added zend_ast_call_get_args() to fetch the argument node from any call + node. + . The zend_exception_save() and zend_exception_restore() functions were + removed. + . Internal functions that return by reference are now expected to + automatically unwrap references when the result of the call is stored in an + IS_TMP_VAR variable. This may be achieved by calling the + zend_return_unwrap_ref() function. + . The php_math_round_mode_from_enum() function now takes a + zend_enum_RoundingMode parameter. + . Added Z_PARAM_ENUM(). + . Added zend_enum_fetch_case_id(). + . ZEND_INI_GET_ADDR() is now a void* pointer instead of a char* pointer. This + more correctly represents the generic nature of the returned pointer and + allows to remove explicit casts, but possibly breaks pointer arithmetic + performed on the result. + . The zend_dval_to_lval_cap() function no longer takes a second + zend_string* parameter. + . EG(in_autoload) was renamed to EG(autoload_current_classnames) and no + longer is a pointer, but a directly embedded HashTable struct. + . Added a C23_ENUM() helper macro to define forward-compatible fixed-size + enums. + . Extended php_stream_filter_ops with seek method. + . The INI_STR(), INI_INT(), INI_FLT(), and INI_BOOL() macros have been + removed. Instead new zend_ini_{bool|long|double|str|string}_literal() + macros have been added. This fixes an internal naming inconsistency as + "str" usually means zend_string*, and "string" means char*. + However INI_STR() returned a char* + . The INI_ORIG_{INT|STR|FLT|BOOL}() macros have been removed as they are + unused. If this behaviour is required fall back to the zend_ini_* + functions. + . The unused ZEND_AST_PARENT_PROPERTY_HOOK_CALL has been removed. + . ZEND_AST_METHOD_REFERENCE has been renamed to + ZEND_AST_TRAIT_METHOD_REFERENCE. + . The EMPTY_SWITCH_DEFAULT_CASE() macro has been removed. Use + default: ZEND_UNREACHABLE(); instead. + . Functions using zend_forbid_dynamic_call() *must* be flagged with + ZEND_ACC2_FORBID_DYN_CALLS (@forbid-dynamic-calls in stubs). In debug + builds, failing to include that flag will lead to assertion failures. + . The ZEND_RESULT_CODE type has been removed. Use zend_result directly. + . The zend_parse_parameters_none_throw(), zend_parse_parameters_throw(), + and ZEND_PARSE_PARAMS_THROW have been removed due to being misleading, + since ZPP always throws, unless ZEND_PARSE_PARAMS_QUIET is given. Use + the non-throw versions. + . The XtOffsetOf() alias of C’s offsetof() macro has been removed. Use + offsetof() directly. + . The deprecated Z_COPYABLE(), Z_COPYABLE_P(), Z_OPT_COPYABLE(), and + Z_OPT_COPYABLE_P() macros have been removed. Check for IS_ARRAY directly. + . The deprecated Z_IMMUTABLE(), Z_IMMUTABLE_P(), Z_OPT_IMMUTABLE(), and + Z_OPT_IMMUTABLE_P() macros have been removed. Check for + IS_ARRAY && !REFCOUNTED directly. + . Added zend_fcall_info.consumed_args together with + zend_fci_consumed_arg(), which allows moving a selected callback argument + instead of copying it in zend_call_function(). Currently only a single + consumed argument is supported. + . Added ZEND_CONTAINER_OF(). + . The OPENBASEDIR_CHECKPATH() compatibility macro has been removed, instead + use php_check_open_basedir() directly. + . Added support for reified generic type parameters. The main + additions: + . New types in zend_compile.h: zend_generic_parameter, + zend_generic_parameter_list, zend_generic_type_table, and + zend_generic_scope_entry. Allocate / destroy via + zend_generic_parameter_list_alloc(), + zend_generic_parameter_list_destroy(), + zend_generic_type_table_alloc(), and + zend_generic_type_table_destroy(). + . zend_op_array and zend_class_entry both gained an optional + `generic_parameters` (declared parameter list) and an optional + `generic_types` side table holding the reified forms of return + types, parameter types, property types, class-constant types, + the extends type, implements list, and trait-use list. The + runtime arg_info / property / class-constant slots continue to + hold the bound view (the parameter's declared bound, with T-refs + resolved); the reified side table is consulted at monomorph + synthesis, ZEND_VERIFY_GENERIC_ARGUMENTS, the new deferred + class-fetch path, inheritance linking, and Reflection. + . New AST kinds: ZEND_AST_GENERIC_TYPE_PARAMETER_LIST, + ZEND_AST_GENERIC_TYPE_PARAMETER, ZEND_AST_GENERIC_NAMED_TYPE, + ZEND_AST_GENERIC_TYPE_ARGUMENT_LIST, ZEND_AST_TURBOFISH. + . zend_ast_decl::child[] grew from 5 to 6 entries; the new slot + carries an optional generic-parameter-list AST. + . The child-count groups of ZEND_AST_CALL, ZEND_AST_NEW, + ZEND_AST_METHOD_CALL, ZEND_AST_NULLSAFE_METHOD_CALL, and + ZEND_AST_STATIC_CALL each gained one optional child holding the + call-site turbofish type-argument list. Code that walks these + nodes by hard-coded child count must be updated. + . zend_ast_export handles the new generic AST kinds. + . Two new bits on zend_type's type_mask: + _ZEND_TYPE_TYPE_PARAMETER_BIT (1u << 25) and + _ZEND_TYPE_NAMED_WITH_ARGS_BIT (1u << 31), with payload structs + zend_type_parameter_ref { zend_string *name; uint32_t index; + uint8_t origin; } and zend_type_named_with_args { zend_string + *name; uint32_t name_attr; uint32_t count; zend_type args[]; }. + These bits only ever appear in reified forms held by the side + table; runtime arg_info / property / class-constant types never + carry them. Helpers: ZEND_TYPE_HAS_TYPE_PARAMETER(), + ZEND_TYPE_TYPE_PARAMETER(), ZEND_TYPE_HAS_NAMED_WITH_ARGS(), + ZEND_TYPE_NAMED_WITH_ARGS(). + . Class-level reification (monomorphs). Each distinct argument + tuple at a generic class, interface, or trait synthesises a + separate zend_class_entry registered in EG(class_table) under a + canonical name ("Box", "Map>"). The + canonical encoding uses `<...>` in the class name, which is + otherwise invalid in user-declared classes; the bit is detected + with zend_class_name_is_monomorph() / zend_class_is_monomorph(). + New API: + - zend_synthesize_monomorph(base, args, arity): synthesise (or + return the cached) class entry; idempotent on canonical + tuples. + - zend_get_defaults_monomorph(base): the monomorph built from + the parameters' declared defaults; NULL when any parameter + has no default. Used by ZEND_NEW for `new static()` and + dynamic `new $name()`. + - zend_try_synthesize_monomorph_by_name(name, flags): parses a + canonical-shaped name and synthesises on demand. Hooked into + zend_lookup_class_ex so unserialize, dynamic new, and + class_exists() all materialise monomorphs transparently. + - zend_type_to_canonical_string(type), + zend_generic_canonical_class_name(base_name, args, arity), + zend_type_contains_type_parameter(type) — the canonical-name + builder is permutation-stable on union/intersection order so + equivalent type-arg lists hash to the same entry. + - zend_generic_get_or_create_class_table(ce) — exposed so + extensions can populate the side table during synthesis. + - ZEND_ACC_GENERIC_ALL_DEFAULTS (1u << 31) on ce_flags — hot + path bit for ZEND_NEW to skip the per-parameter default + scan. + . Function- and method-level reification (per call frame). Each + generic call installs a fresh table mapping parameter index to + bound class name: + typedef struct _zend_type_arg_table { + uint32_t count; + zend_string *names[1]; + } zend_type_arg_table; + Allocate / destroy via zend_type_arg_table_alloc(count) and + zend_type_arg_table_destroy(t). zend_execute_data gained a + `type_args` field initialised to NULL by + zend_vm_init_call_frame() and released by + zend_vm_stack_free_call_frame_ex(). The table survives closure + and generator suspension. There is no persistent function-level + monomorph — the binding lives on the frame. + Population API: + - zend_type_arg_canonical_name(type): canonical-name for a + single type-arg slot, including scalars (`"int"`, + `"?string"`). Returns NULL only for unset types. + - zend_build_generic_call_type_args(call, args_box): builds + the table from a turbofish NAMED_WITH_ARGS carrier (or from + declared defaults for unsupplied slots). + - zend_verify_generic_arg_types(call, args_box): validates + each arg against the corresponding parameter's bound. + - zend_resolve_generic_type_param(index, fetch_type): runtime + T-ref resolver. Walks EX(type_args) for function-level T + and the called scope -> lexical scope chain for class-level + T (the binding lives on the monomorph that is the direct + child of the lexical scope on cur->generic_type_args). + zend_generic_parameter_list gained an `inferable_mask` (bit i + set when some value-parameter's reified type is exactly param i + at a top-level position) so inference can short-circuit. + . Three new class-fetch sub-types on the class-fetch enum, + packed into op.num via zend_pack_*_fetch helpers: + - ZEND_FETCH_CLASS_TYPE_PARAM (7) — function/method- + level bare T-ref (`instanceof T`, `catch (T $e)`, + `new T()`, `T::method()`). + - ZEND_FETCH_CLASS_TYPE_PARAM_CLASS (8) — class-level bare + T-ref; resolves via the called-scope walk. + - ZEND_FETCH_CLASS_GENERIC_DEFERRED (9) — generic named type + whose args contain T-refs (`instanceof Box`, + `catch (Box $e)`). The args_id sits in the high bits of + op.num and points into the op_array's + generic_types->turbofish_args side table. + All three are detected with zend_fetch_is_type_param() (the + first two) or by the sub-type directly; packed with + zend_pack_type_param_fetch(idx, flags, class_level) and + zend_pack_generic_deferred_fetch(args_id, flags); unpacked with + zend_unpack_type_param_index(fetch_type). Routed through + zend_fetch_class, which dispatches to + zend_resolve_generic_type_param() or + zend_resolve_deferred_generic_class(). + . New compiler-globals fields: CG(type_arg_depth) (right-angle + split state used by the zendlex wrapper), CG(token_residual) + (single-token pushback slot), and CG(generic_scope) (linked + stack of in-scope type parameters). + . New T_TURBOFISH lexer token (literal `::<`). The zendlex wrapper + splits T_SR (`>>`), T_IS_GREATER_OR_EQUAL (`>=`), and T_SR_EQUAL + (`>>=`) into separate `>` tokens whenever CG(type_arg_depth) is + non-zero, with a single-token pushback slot. + . Module API bumped to 20260506; extension API bumped to + 420260506. All extensions must be recompiled. ======================== 2. Build system changes ======================== -- Windows build system changes - . SAPI() and ADD_SOURCES() now suport 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. +- Abstract: + . Minimum required PHP version found on the host system for running scripts + like build/gen_stub.php during development has been updated from 7.4 to 8.1. + . build/gen_stub.php may now generate a _decl.h file in addition to + the _arginfo.h file, if the stub declares enums and is annotated with + @generate-c-enums. For each enum the file will contain a C enum. Enum + values can be compared to the result of + zend_enum_fetch_case_id(zend_object*). -- Linux 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. +- Unix build system changes: + . scripts/dev/update-autoconf.sh has been added to update config.*/libtool. + . libtool has been upgraded to 2.5.4 (serial 63), which fixes many bugs. + . As part of the upgrade to the new libtool: + . libtool is now spread across multiple files. phpize has been updated to + handle this. + . On macOS, libtool now uses -undefined dynamic_lookup for shared objects, + instead of -undefined suppress -flat_namespace. + . --with-pic is now --enable-pic. The old flag will result in an error. + . Symbol HAVE_ST_BLOCKS has been removed from php_config.h (use + HAVE_STRUCT_STAT_ST_BLOCKS). + +- Windows build system changes: + . Function SETUP_OPENSSL() doesn't accept 6th argument anymore and doesn't + define the HAVE_OPENSSL_SSL_H preprocessor macro anymore. + . Function SETUP_SQLITE3() doesn't define HAVE_SQLITE3_H and HAVE_SQLITE3EXT_H + preprocessor macros anymore. + . Added a new function CHECK_HEADER() which is intended to be used instead of + the CHECK_HEADER_ADD_INCLUDE(). ======================== 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. +- ext/mbstring: + . Added GB18030-2022 to default encoding list for zh-CN. -- 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. +- ext/mysqlnd: + . Dropped session_options parameter from all methods in mysqlnd_auth. + The same information is present in conn->options and should be used + instead. + . Removed charsets plugin. -- ext/libxml - . The refcount APIs now return an `unsigned int` instead of an `int`. - . Removed php_libxml_xmlCheckUTF8(). Use xmlCheckUTF8() from libxml instead. +- ext/session: + . php_session_flush() now returns a bool rather than a zend_result. + . The mod_user_names global has been removed. + . The mod_user_uses_object_methods_as_handlers global has been added, + it indicates whether the session handlers are methods of an object or not. + . Removed session_adapt_url(). + . PS_OPEN_ARGS is now defined as + `void **mod_data, zend_string *save_path, zend_string *session_name` + rather than + `void **mod_data, const char *save_path, const char *session_name` + . PS_FUNCS() now includes the PS_VALIDATE_SID_FUNC() + . PS_MOD() now requires that the PS_CREATE_SID_FUNC() and + PS_VALIDATE_SID_FUNC() functions are defined. + . PS_FUNCS_SID() and PS_MOD_SID() have been removed. + Either use PS_FUNCS()/PS_MOD() or PS_FUNCS_UPDATE_TIMESTAMP()/ + PS_MOD_UPDATE_TIMESTAMP() if timestamp support exists. -- 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. +- ext/standard: + . _php_error_log() now has a formal return type of zend_result. + . _php_error_log() now accepts zend_string* values instead of char*. + . _php_error_log_ex() has been removed. + . php_mail()'s extra_cmd parameter is now a zend_string*. -- 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. +- ext/xml: + . Removed the XML_ExpatVersion() libxml compatibility wrapper, + as it was unused. + . Removed the XML_GetCurrentByteCount() libxml compatibility wrapper, + as it was unused and could return the wrong result. ======================== 4. OpCode changes ======================== +- Added ZEND_TYPE_ASSERT to check a value's type against the parameter + type of a function, throwing a TypeError on failure as if the function + was called. Used in optimizations that elide function calls. + ======================== 5. SAPI changes ======================== diff --git a/Zend/LICENSE b/Zend/LICENSE deleted file mode 100644 index 51f5cccde950..000000000000 --- a/Zend/LICENSE +++ /dev/null @@ -1,56 +0,0 @@ --------------------------------------------------------------------- - The Zend Engine License, Version 2.00 -Copyright (c) 1999-2006 Zend Technologies Ltd. All rights reserved. --------------------------------------------------------------------- - -Redistribution and use in source and binary forms, with or without -modification, is permitted provided that the following conditions -are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - 3. The names "Zend" and "Zend Engine" must not be used to endorse - or promote products derived from this software without prior - permission from Zend Technologies Ltd. For written permission, - please contact license@zend.com. - - 4. Zend Technologies Ltd. may publish revised and/or new versions - of the license from time to time. Each version will be given a - distinguishing version number. - Once covered code has been published under a particular version - of the license, you may always continue to use it under the - terms of that version. You may also choose to use such covered - code under the terms of any subsequent version of the license - published by Zend Technologies Ltd. No one other than Zend - Technologies Ltd. has the right to modify the terms applicable - to covered code created under this License. - - 5. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes the Zend Engine, freely available at - http://www.zend.com" - - 6. All advertising materials mentioning features or use of this - software must display the following acknowledgment: - "The Zend Engine is freely available at http://www.zend.com" - -THIS SOFTWARE IS PROVIDED BY ZEND TECHNOLOGIES LTD. ``AS IS'' AND -ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ZEND -TECHNOLOGIES LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - --------------------------------------------------------------------- diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 96a0e81f0382..02c28ead33e1 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -30,9 +28,9 @@ #include "zend_dump.h" /* Checks if a constant (like "true") may be replaced by its value */ -bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy) +bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, bool copy) { - zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name); + const zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name); if (c) { if ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) && !(ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) @@ -42,9 +40,9 @@ bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int if (copy) { Z_TRY_ADDREF_P(result); } - return 1; + return true; } else { - return 0; + return false; } } @@ -52,9 +50,9 @@ bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int c = zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name)); if (c) { ZVAL_COPY_VALUE(result, &c->value); - return 1; + return true; } - return 0; + return false; } /* Data dependencies macros */ @@ -62,9 +60,9 @@ bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int #define VAR_SOURCE(op) Tsource[VAR_NUM(op.var)] #define SET_VAR_SOURCE(opline) Tsource[VAR_NUM(opline->result.var)] = opline -static void strip_leading_nops(zend_op_array *op_array, zend_basic_block *b) +static void strip_leading_nops(const zend_op_array *op_array, zend_basic_block *b) { - zend_op *opcodes = op_array->opcodes; + const zend_op *opcodes = op_array->opcodes; do { b->start++; @@ -72,7 +70,7 @@ static void strip_leading_nops(zend_op_array *op_array, zend_basic_block *b) } while (b->len > 0 && opcodes[b->start].opcode == ZEND_NOP); } -static void strip_nops(zend_op_array *op_array, zend_basic_block *b) +static void strip_nops(const zend_op_array *op_array, zend_basic_block *b) { uint32_t i, j; @@ -106,7 +104,7 @@ static void strip_nops(zend_op_array *op_array, zend_basic_block *b) } } -static int get_const_switch_target(zend_cfg *cfg, zend_op_array *op_array, zend_basic_block *block, zend_op *opline, zval *val) { +static uint32_t get_const_switch_target(const zend_cfg *cfg, const zend_op_array *op_array, const zend_basic_block *block, zend_op *opline, const zval *val) { HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline)); zval *zv; if ((opline->opcode == ZEND_SWITCH_LONG && Z_TYPE_P(val) != IS_LONG) @@ -176,7 +174,9 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array && zend_optimizer_update_op1_const(op_array, opline, &c)) { VAR_SOURCE(op1) = NULL; if (opline->opcode != ZEND_JMP_NULL - && !zend_bitset_in(used_ext, VAR_NUM(src->result.var))) { + && !zend_bitset_in(used_ext, VAR_NUM(src->result.var)) + /* FETCH_W with ZEND_FETCH_GLOBAL_LOCK does not free op1, which will be used again. */ + && !(opline->opcode == ZEND_FETCH_W && (opline->extended_value & ZEND_FETCH_GLOBAL_LOCK))) { literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); } @@ -289,20 +289,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array MAKE_NOP(opline); ++(*opt_count); break; - case ZEND_ASSIGN: - case ZEND_ASSIGN_DIM: - case ZEND_ASSIGN_OBJ: - case ZEND_ASSIGN_STATIC_PROP: - case ZEND_ASSIGN_OP: - case ZEND_ASSIGN_DIM_OP: - case ZEND_ASSIGN_OBJ_OP: - case ZEND_ASSIGN_STATIC_PROP_OP: - case ZEND_PRE_INC: - case ZEND_PRE_DEC: - case ZEND_PRE_INC_OBJ: - case ZEND_PRE_DEC_OBJ: - case ZEND_PRE_INC_STATIC_PROP: - case ZEND_PRE_DEC_STATIC_PROP: + case ZEND_QM_ASSIGN: if (src < op_array->opcodes + block->start) { break; } @@ -310,8 +297,26 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array VAR_SOURCE(opline->op1) = NULL; MAKE_NOP(opline); ++(*opt_count); + if (src->op1_type & (IS_VAR|IS_TMP_VAR)) { + src->opcode = ZEND_FREE; + } else if (src->op1_type == IS_CONST) { + MAKE_NOP(src); + } else if (src->op1_type == IS_CV) { + src->opcode = ZEND_CHECK_VAR; + SET_UNUSED(src->result); + } break; default: + if (!zend_op_may_elide_result(src->opcode)) { + break; + } + if (src < op_array->opcodes + block->start) { + break; + } + src->result_type = IS_UNUSED; + VAR_SOURCE(opline->op1) = NULL; + MAKE_NOP(opline); + ++(*opt_count); break; } } @@ -339,59 +344,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } break; -#if 0 - /* pre-evaluate functions: - constant(x) - function_exists(x) - extension_loaded(x) - BAD: interacts badly with Accelerator - */ - if((opline->op1_type & IS_VAR) && - VAR_SOURCE(opline->op1) && VAR_SOURCE(opline->op1)->opcode == ZEND_DO_CF_FCALL && - VAR_SOURCE(opline->op1)->extended_value == 1) { - zend_op *fcall = VAR_SOURCE(opline->op1); - zend_op *sv = fcall-1; - if(sv >= block->start_opline && sv->opcode == ZEND_SEND_VAL && - sv->op1_type == IS_CONST && Z_TYPE(OPLINE_OP1_LITERAL(sv)) == IS_STRING && - Z_LVAL(OPLINE_OP2_LITERAL(sv)) == 1 - ) { - zval *arg = &OPLINE_OP1_LITERAL(sv); - char *fname = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].function_name; - size_t flen = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].name_len; - if((flen == sizeof("function_exists")-1 && zend_binary_strcasecmp(fname, flen, "function_exists", sizeof("function_exists")-1) == 0) || - (flen == sizeof("is_callable")-1 && zend_binary_strcasecmp(fname, flen, "is_callable", sizeof("is_callable")-1) == 0) - ) { - zend_function *function; - if((function = zend_hash_find_ptr(EG(function_table), Z_STR_P(arg))) != NULL) { - literal_dtor(arg); - MAKE_NOP(sv); - MAKE_NOP(fcall); - LITERAL_BOOL(opline->op1, 1); - opline->op1_type = IS_CONST; - } - } else if(flen == sizeof("constant")-1 && zend_binary_strcasecmp(fname, flen, "constant", sizeof("constant")-1) == 0) { - zval c; - if (zend_optimizer_get_persistent_constant(Z_STR_P(arg), &c, 1 ELS_CC)) { - literal_dtor(arg); - MAKE_NOP(sv); - MAKE_NOP(fcall); - ZEND_OP1_LITERAL(opline) = zend_optimizer_add_literal(op_array, &c); - /* no copy ctor - get already copied it */ - opline->op1_type = IS_CONST; - } - } else if(flen == sizeof("extension_loaded")-1 && zend_binary_strcasecmp(fname, flen, "extension_loaded", sizeof("extension_loaded")-1) == 0) { - if(zend_hash_exists(&module_registry, Z_STR_P(arg))) { - literal_dtor(arg); - MAKE_NOP(sv); - MAKE_NOP(fcall); - LITERAL_BOOL(opline->op1, 1); - opline->op1_type = IS_CONST; - } - } - } - } -#endif - case ZEND_FETCH_LIST_R: case ZEND_FETCH_LIST_W: if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { @@ -409,7 +361,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array break; } if (opline->op1_type == IS_CONST) { - int target = get_const_switch_target(cfg, op_array, block, opline, &ZEND_OP1_LITERAL(opline)); + uint32_t target = get_const_switch_target(cfg, op_array, block, opline, &ZEND_OP1_LITERAL(opline)); literal_dtor(&ZEND_OP1_LITERAL(opline)); literal_dtor(&ZEND_OP2_LITERAL(opline)); opline->opcode = ZEND_JMP; @@ -420,6 +372,14 @@ 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: @@ -428,18 +388,11 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array Tsource[VAR_NUM(opline->op1.var)] = NULL; break; } - ZEND_FALLTHROUGH; - - case ZEND_IS_EQUAL: - case ZEND_IS_NOT_EQUAL: if (opline->op1_type == IS_CONST && opline->op2_type == IS_CONST) { goto optimize_constant_binary_op; } - /* IS_EQ(TRUE, X) => BOOL(X) - * IS_EQ(FALSE, X) => BOOL_NOT(X) - * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X) - * IS_NOT_EQ(FALSE, X) => BOOL(X) + /* * CASE(TRUE, X) => BOOL(X) * CASE(FALSE, X) => BOOL_NOT(X) */ @@ -470,6 +423,21 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array goto optimize_bool; } break; + + case ZEND_IS_EQUAL: + case ZEND_IS_NOT_EQUAL: + if (opline->op1_type == IS_CONST && + opline->op2_type == IS_CONST) { + goto optimize_constant_binary_op; + } + /* IS_EQ(TRUE, X) => BOOL(X) + * IS_EQ(FALSE, X) => BOOL_NOT(X) + * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X) + * IS_NOT_EQ(FALSE, X) => BOOL(X) + * Those optimizations are not safe if the other operand ends up being NAN + * as BOOL/BOOL_NOT will warn, while IS_EQUAL/IS_NOT_EQUAL do not. + */ + break; case ZEND_IS_IDENTICAL: if (opline->op1_type == IS_CONST && opline->op2_type == IS_CONST) { @@ -806,7 +774,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array src->extended_value == IS_STRING && src->op1_type != IS_CONST) { /* convert T1 = CAST(STRING, X), T2 = CONCAT(Y, T1) to T2 = CONCAT(Y,X) */ - zend_op *src = VAR_SOURCE(opline->op2); VAR_SOURCE(opline->op2) = NULL; COPY_NODE(opline->op2, src->op1); MAKE_NOP(src); @@ -933,14 +900,14 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array src = VAR_SOURCE(opline->op1); if (src && src->opcode == ZEND_QM_ASSIGN) { zend_op *op = src + 1; - bool optimize = 1; + bool optimize = true; while (op < opline) { if ((op->op1_type == opline->op1_type && op->op1.var == opline->op1.var) || (op->op2_type == opline->op1_type && op->op2.var == opline->op1.var)) { - optimize = 0; + optimize = false; break; } op++; @@ -970,6 +937,8 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array src = VAR_SOURCE(opline->op1); if (src && src->opcode != ZEND_COPY_TMP && + /* See gh20628_borked_live_range_calc.phpt. */ + src->opcode != ZEND_NEW && src->opcode != ZEND_ADD_ARRAY_ELEMENT && src->opcode != ZEND_ADD_ARRAY_UNPACK && (src->opcode != ZEND_DECLARE_LAMBDA_FUNCTION || @@ -993,10 +962,10 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array } /* Rebuild plain (optimized) op_array from CFG */ -static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_optimizer_ctx *ctx) +static void assemble_code_blocks(const zend_cfg *cfg, zend_op_array *op_array, zend_optimizer_ctx *ctx) { zend_basic_block *blocks = cfg->blocks; - zend_basic_block *end = blocks + cfg->blocks_count; + const zend_basic_block *end = blocks + cfg->blocks_count; zend_basic_block *b; zend_op *new_opcodes; zend_op *opline; @@ -1009,7 +978,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { opline = op_array->opcodes + b->start + b->len - 1; if (opline->opcode == ZEND_JMP) { - zend_basic_block *next = b + 1; + const zend_basic_block *next = b + 1; while (next < end && !(next->flags & ZEND_BB_REACHABLE)) { next++; @@ -1026,9 +995,9 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op len += b->len; } else { /* this block will not be used, delete all constants there */ - zend_op *op = op_array->opcodes + b->start; - zend_op *end = op + b->len; - for (; op < end; op++) { + const zend_op *op = op_array->opcodes + b->start; + const zend_op *last_op = op + b->len; + for (; op < last_op; op++) { if (op->op1_type == IS_CONST) { literal_dtor(&ZEND_OP1_LITERAL(op)); } @@ -1093,7 +1062,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op case ZEND_SWITCH_STRING: case ZEND_MATCH: { - HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline)); + const HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline)); zval *zv; uint32_t s = 0; ZEND_ASSERT(b->successors_count == (opline->opcode == ZEND_MATCH ? 1 : 2) + zend_hash_num_elements(jumptable)); @@ -1109,7 +1078,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op /* adjust exception jump targets & remove unused try_catch_array entries */ if (op_array->last_try_catch) { - int i, j; + uint32_t i, j; uint32_t *map; ALLOCA_FLAG(use_heap); @@ -1144,15 +1113,15 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op } if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) { - zend_op *opline = new_opcodes; - zend_op *end = opline + len; - while (opline < end) { - if (opline->opcode == ZEND_FAST_RET && - opline->op2.num != (uint32_t)-1 && - opline->op2.num < (uint32_t)j) { - opline->op2.num = map[opline->op2.num]; + zend_op *finally_opline = new_opcodes; + const zend_op *last_finally_op = finally_opline + len; + while (finally_opline < last_finally_op) { + if (finally_opline->opcode == ZEND_FAST_RET && + finally_opline->op2.num != (uint32_t)-1 && + finally_opline->op2.num < j) { + finally_opline->op2.num = map[finally_opline->op2.num]; } - opline++; + finally_opline++; } } } @@ -1161,14 +1130,14 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op /* rebuild map (just for printing) */ memset(cfg->map, -1, sizeof(int) * op_array->last); - for (int n = 0; n < cfg->blocks_count; n++) { + for (uint32_t n = 0; n < cfg->blocks_count; n++) { if (cfg->blocks[n].flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { cfg->map[cfg->blocks[n].start] = n; } } } -static zend_always_inline zend_basic_block *get_target_block(const zend_cfg *cfg, zend_basic_block *block, int n, uint32_t *opt_count) +static zend_always_inline zend_basic_block *get_target_block(const zend_cfg *cfg, const zend_basic_block *block, int n, uint32_t *opt_count) { int b; zend_basic_block *target_block = cfg->blocks + block->successors[n]; @@ -1184,7 +1153,7 @@ static zend_always_inline zend_basic_block *get_target_block(const zend_cfg *cfg return target_block; } -static zend_always_inline zend_basic_block *get_follow_block(const zend_cfg *cfg, zend_basic_block *block, int n, uint32_t *opt_count) +static zend_always_inline zend_basic_block *get_follow_block(const zend_cfg *cfg, const zend_basic_block *block, int n, uint32_t *opt_count) { int b; zend_basic_block *target_block = cfg->blocks + block->successors[n]; @@ -1203,7 +1172,7 @@ static zend_always_inline zend_basic_block *get_follow_block(const zend_cfg *cfg static zend_always_inline zend_basic_block *get_next_block(const zend_cfg *cfg, zend_basic_block *block) { zend_basic_block *next_block = block + 1; - zend_basic_block *end = cfg->blocks + cfg->blocks_count; + const zend_basic_block *end = cfg->blocks + cfg->blocks_count; while (1) { if (next_block == end) { @@ -1213,7 +1182,7 @@ static zend_always_inline zend_basic_block *get_next_block(const zend_cfg *cfg, } next_block++; } - while (next_block->len == 0 && !(next_block->flags & ZEND_BB_PROTECTED)) { + while (next_block->len == 0 && !(next_block->flags & (ZEND_BB_TARGET|ZEND_BB_PROTECTED))) { next_block = cfg->blocks + next_block->successors[0]; } return next_block; @@ -1221,7 +1190,7 @@ static zend_always_inline zend_basic_block *get_next_block(const zend_cfg *cfg, /* we use "jmp_hitlist" to avoid infinity loops during jmp optimization */ -static zend_always_inline bool in_hitlist(int target, int *jmp_hitlist, int jmp_hitlist_count) +static zend_always_inline bool in_hitlist(int target, const int *jmp_hitlist, int jmp_hitlist_count) { int i; @@ -1467,9 +1436,9 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr /* Find a set of variables which are used outside of the block where they are * defined. We won't apply some optimization patterns for such variables. */ -static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset used_ext, zend_optimizer_ctx *ctx) +static void zend_t_usage(const zend_cfg *cfg, const zend_op_array *op_array, zend_bitset used_ext, zend_optimizer_ctx *ctx) { - int n; + uint32_t n; zend_basic_block *block, *next_block; uint32_t var_num; uint32_t bitset_len; @@ -1550,14 +1519,14 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use } if (ctx->debug_level & ZEND_DUMP_BLOCK_PASS_VARS) { - bool printed = 0; + bool printed = false; uint32_t i; for (i = op_array->last_var; i< op_array->T; i++) { if (zend_bitset_in(used_ext, i)) { if (!printed) { fprintf(stderr, "NON-LOCAL-VARS: %d", i); - printed = 1; + printed = true; } else { fprintf(stderr, ", %d", i); } @@ -1671,13 +1640,12 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use zend_arena_release(&ctx->arena, checkpoint); } -static void zend_merge_blocks(zend_op_array *op_array, zend_cfg *cfg, uint32_t *opt_count) +static void zend_merge_blocks(const zend_op_array *op_array, const zend_cfg *cfg, uint32_t *opt_count) { - int i; zend_basic_block *b, *bb; zend_basic_block *prev = NULL; - for (i = 0; i < cfg->blocks_count; i++) { + for (uint32_t i = 0; i < cfg->blocks_count; i++) { b = cfg->blocks + i; if (b->flags & ZEND_BB_REACHABLE) { if ((b->flags & ZEND_BB_FOLLOW) && @@ -1691,7 +1659,7 @@ static void zend_merge_blocks(zend_op_array *op_array, zend_cfg *cfg, uint32_t * for (bb = prev + 1; bb != b; bb++) { zend_op *op = op_array->opcodes + bb->start; - zend_op *end = op + bb->len; + const zend_op *end = op + bb->len; while (op < end) { if (op->op1_type == IS_CONST) { literal_dtor(&ZEND_OP1_LITERAL(op)); diff --git a/Zend/Optimizer/compact_literals.c b/Zend/Optimizer/compact_literals.c index d0aaccec7ce2..49bcf7b13196 100644 --- a/Zend/Optimizer/compact_literals.c +++ b/Zend/Optimizer/compact_literals.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -110,7 +108,7 @@ static zend_string *create_str_cache_key(zval *literal, uint8_t num_related) void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx) { zend_op *opline, *end; - int i, j, n, *map; + int n, *map; uint32_t cache_size; zval zv, *pos; literal_info *info; @@ -124,6 +122,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot, *jmp_slot; if (op_array->last_literal) { + uint32_t j; info = (literal_info*)zend_arena_calloc(&ctx->arena, op_array->last_literal, sizeof(literal_info)); /* Mark literals of specific types */ @@ -258,9 +257,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx op_array->function_name ? op_array->function_name->val : "main"); fprintf(stderr, "Literals table size %d\n", op_array->last_literal); - for (int i = 0; i < op_array->last_literal; i++) { + for (uint32_t i = 0; i < op_array->last_literal; i++) { zend_string *str = zval_get_string(op_array->literals + i); - fprintf(stderr, "Literal %d, val (%zu):%s\n", i, ZSTR_LEN(str), ZSTR_VAL(str)); + fprintf(stderr, "Literal %" PRIu32 ", val (%zu):%s\n", i, ZSTR_LEN(str), ZSTR_VAL(str)); zend_string_release(str); } fflush(stderr); @@ -272,7 +271,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx zend_hash_init(&hash, op_array->last_literal, NULL, NULL, 0); map = (int*)zend_arena_alloc(&ctx->arena, op_array->last_literal * sizeof(int)); memset(map, 0, op_array->last_literal * sizeof(int)); - for (i = 0; i < op_array->last_literal; i++) { + for (uint32_t i = 0; i < op_array->last_literal; i++) { if (!info[i].num_related) { /* unset literal */ zval_ptr_dtor_nogc(&op_array->literals[i]); @@ -675,6 +674,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx cache_size += sizeof(void *); class_slot[opline->op2.constant] = opline->extended_value; } + } else if (opline->opcode == ZEND_INSTANCEOF + && opline->op2_type == IS_UNUSED) { + /* instanceof T / instanceof Box: 3-slot PIC keyed on + * (type_args generation, called scope, resolved ce). */ + opline->extended_value = cache_size; + cache_size += 3 * sizeof(void *); } break; case ZEND_NEW: @@ -689,6 +694,18 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx } } break; + case ZEND_VERIFY_GENERIC_ARGUMENTS: + case ZEND_INSTALL_GENERIC_ARGS: + /* When this site has a turbofish (args_id in extended_value) + * or is a call (op1_type == IS_UNUSED, which caches its table + * regardless), the compiler allocated a 5-slot inline cache — + * re-allocate it here so the offset stays in sync with + * compact_literals' fresh cache_size. */ + if (opline->extended_value != 0 || opline->op1_type == IS_UNUSED) { + opline->result.num = cache_size; + cache_size += 5 * sizeof(void *); + } + break; case ZEND_CATCH: if (opline->op1_type == IS_CONST) { // op1 class @@ -699,6 +716,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx cache_size += sizeof(void *); class_slot[opline->op1.constant] = opline->extended_value & ~ZEND_LAST_CATCH; } + } else { + ZEND_ASSERT(opline->op1_type == IS_UNUSED); + /* T-ref / deferred-turbofish catch: 3-slot PIC keyed on + * (type_args generation, called scope, resolved ce). */ + opline->extended_value = cache_size | (opline->extended_value & ZEND_LAST_CATCH); + cache_size += 3 * sizeof(void *); } break; case ZEND_BIND_GLOBAL: @@ -740,6 +763,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx cache_size += 2 * sizeof(void *); } break; + case ZEND_CALLABLE_CONVERT: + if (opline->extended_value != (uint32_t)-1) { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + } + break; } opline++; } @@ -770,9 +799,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx { fprintf(stderr, "Optimized literals table size %d\n", op_array->last_literal); - for (int i = 0; i < op_array->last_literal; i++) { + for (uint32_t i = 0; i < op_array->last_literal; i++) { zend_string *str = zval_get_string(op_array->literals + i); - fprintf(stderr, "Literal %d, val (%zu):%s\n", i, ZSTR_LEN(str), ZSTR_VAL(str)); + fprintf(stderr, "Literal %" PRIu32 ", val (%zu):%s\n", i, ZSTR_LEN(str), ZSTR_VAL(str)); zend_string_release(str); } fflush(stderr); diff --git a/Zend/Optimizer/compact_vars.c b/Zend/Optimizer/compact_vars.c index 9898714a17c5..b4a861d3595c 100644 --- a/Zend/Optimizer/compact_vars.c +++ b/Zend/Optimizer/compact_vars.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Removing unused variables | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index a00fd8bc6ad3..0780ac190cdd 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, DCE - Dead Code Elimination | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Dmitry Stogov | @@ -62,17 +60,17 @@ typedef struct { static inline bool is_bad_mod(const zend_ssa *ssa, int use, int def) { if (def < 0) { /* This modification is not tracked by SSA, assume the worst */ - return 1; + return true; } if (ssa->var_info[use].type & MAY_BE_REF) { /* Modification of reference may have side-effect */ - return 1; + return true; } - return 0; + return false; } static inline bool may_have_side_effects( - zend_op_array *op_array, zend_ssa *ssa, + const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op, bool reorder_dtor_effects) { switch (opline->opcode) { @@ -124,19 +122,20 @@ static inline bool may_have_side_effects( case ZEND_FUNC_NUM_ARGS: case ZEND_FUNC_GET_ARGS: case ZEND_ARRAY_KEY_EXISTS: + case ZEND_COPY_TMP: /* No side effects */ - return 0; + return false; 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. "$b"]; */ if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && (opline->op2_type & (IS_VAR|IS_TMP_VAR))) { - return 1; + return true; } - return 0; + return false; case ZEND_ROPE_END: /* TODO: Rope dce optimization, see #76446 */ - return 1; + return true; case ZEND_JMP: case ZEND_JMPZ: case ZEND_JMPNZ: @@ -149,7 +148,7 @@ static inline bool may_have_side_effects( case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_JMP_FRAMELESS: /* For our purposes a jumps and branches are side effects. */ - return 1; + return true; case ZEND_BEGIN_SILENCE: case ZEND_END_SILENCE: case ZEND_ECHO: @@ -161,10 +160,16 @@ static inline bool may_have_side_effects( case ZEND_EXT_FCALL_END: case ZEND_TICKS: case ZEND_YIELD: - case ZEND_YIELD_FROM: case ZEND_VERIFY_NEVER_TYPE: /* Intrinsic side effects */ - return 1; + return true; + case ZEND_YIELD_FROM: { + uint32_t t1 = OP1_INFO(); + if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY && MAY_BE_EMPTY_ONLY(t1)) { + return false; + } + return true; + } case ZEND_DO_FCALL: case ZEND_DO_FCALL_BY_NAME: case ZEND_DO_ICALL: @@ -174,31 +179,31 @@ static inline bool may_have_side_effects( case ZEND_FRAMELESS_ICALL_2: case ZEND_FRAMELESS_ICALL_3: /* For now assume all calls have side effects */ - return 1; + return true; case ZEND_RECV: case ZEND_RECV_INIT: /* Even though RECV_INIT can be side-effect free, these cannot be simply dropped * due to the prologue skipping code. */ - return 1; + return true; case ZEND_ASSIGN_REF: - return 1; + return true; case ZEND_ASSIGN: { if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def)) { - return 1; + return true; } if (!reorder_dtor_effects) { if (opline->op2_type != IS_CONST && (OP2_INFO() & MAY_HAVE_DTOR) && ssa->vars[ssa_op->op2_use].escape_state != ESCAPE_STATE_NO_ESCAPE) { /* DCE might shorten lifetime */ - return 1; + return true; } } - return 0; + return false; } case ZEND_UNSET_VAR: - return 1; + return true; case ZEND_UNSET_CV: { uint32_t t1 = OP1_INFO(); @@ -207,9 +212,9 @@ static inline bool may_have_side_effects( * an unset may be considered dead even if there is a later assignment to the * variable. Removing the unset in this case would not be correct if the variable * is a reference, because unset breaks references. */ - return 1; + return true; } - return 0; + return false; } case ZEND_PRE_INC: case ZEND_POST_INC: @@ -223,7 +228,7 @@ static inline bool may_have_side_effects( case ZEND_ASSIGN_OBJ: if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def) || ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE) { - return 1; + return true; } if (!reorder_dtor_effects) { opline++; @@ -231,33 +236,33 @@ static inline bool may_have_side_effects( if (opline->op1_type != IS_CONST && (OP1_INFO() & MAY_HAVE_DTOR)) { /* DCE might shorten lifetime */ - return 1; + return true; } } - return 0; + return false; case ZEND_PRE_INC_OBJ: case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def) || ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE) { - return 1; + return true; } - return 0; + return false; case ZEND_BIND_STATIC: if (op_array->static_variables) { /* Implicit and Explicit bind static is effectively prologue of closure so report it has side effects like RECV, RECV_INIT; This allows us to reflect on the closure and discover used variable at runtime */ if ((opline->extended_value & (ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))) { - return 1; + return true; } /* Modifies static variables which are observable through reflection */ if ((opline->extended_value & ZEND_BIND_REF) && opline->op2_type != IS_UNUSED) { - return 1; + return true; } } - return 0; + return false; case ZEND_CHECK_VAR: return (OP1_INFO() & MAY_BE_UNDEF) != 0; case ZEND_FE_RESET_R: @@ -267,12 +272,12 @@ static inline bool may_have_side_effects( return (OP1_INFO() & MAY_BE_ANY) != MAY_BE_ARRAY; default: /* For everything we didn't handle, assume a side-effect */ - return 1; + return true; } } -static zend_always_inline void add_to_worklists(context *ctx, int var_num, int check) { - zend_ssa_var *var = &ctx->ssa->vars[var_num]; +static zend_always_inline void add_to_worklists(const context *ctx, int var_num, int check) { + const zend_ssa_var *var = &ctx->ssa->vars[var_num]; if (var->definition >= 0) { if (!check || zend_bitset_in(ctx->instr_dead, var->definition)) { zend_bitset_incl(ctx->instr_worklist, var->definition); @@ -284,14 +289,14 @@ static zend_always_inline void add_to_worklists(context *ctx, int var_num, int c } } -static inline void add_to_phi_worklist_no_val(context *ctx, int var_num) { - zend_ssa_var *var = &ctx->ssa->vars[var_num]; +static inline void add_to_phi_worklist_no_val(const context *ctx, int var_num) { + const zend_ssa_var *var = &ctx->ssa->vars[var_num]; if (var->definition_phi && zend_bitset_in(ctx->phi_dead, var_num)) { zend_bitset_incl(ctx->phi_worklist_no_val, var_num); } } -static zend_always_inline void add_operands_to_worklists(context *ctx, zend_op *opline, zend_ssa_op *ssa_op, zend_ssa *ssa, int check) { +static zend_always_inline void add_operands_to_worklists(const context *ctx, const zend_op *opline, const zend_ssa_op *ssa_op, const zend_ssa *ssa, int check) { if (ssa_op->result_use >= 0) { add_to_worklists(ctx, ssa_op->result_use, check); } @@ -315,16 +320,16 @@ static zend_always_inline void add_operands_to_worklists(context *ctx, zend_op * } } -static zend_always_inline void add_phi_sources_to_worklists(context *ctx, zend_ssa_phi *phi, int check) { - zend_ssa *ssa = ctx->ssa; +static zend_always_inline void add_phi_sources_to_worklists(const context *ctx, zend_ssa_phi *phi, int check) { + const zend_ssa *ssa = ctx->ssa; int source; FOREACH_PHI_SOURCE(phi, source) { add_to_worklists(ctx, source, check); } FOREACH_PHI_SOURCE_END(); } -static inline bool is_var_dead(context *ctx, int var_num) { - zend_ssa_var *var = &ctx->ssa->vars[var_num]; +static inline bool is_var_dead(const context *ctx, int var_num) { + const zend_ssa_var *var = &ctx->ssa->vars[var_num]; if (var->definition_phi) { return zend_bitset_in(ctx->phi_dead, var_num); } else if (var->definition >= 0) { @@ -338,9 +343,9 @@ static inline bool is_var_dead(context *ctx, int var_num) { } // Sometimes we can mark the var as EXT_UNUSED -static bool try_remove_var_def(context *ctx, int free_var, int use_chain, zend_op *opline) { +static bool try_remove_var_def(const context *ctx, int free_var, int use_chain, const zend_op *opline) { if (use_chain >= 0) { - return 0; + return false; } zend_ssa_var *var = &ctx->ssa->vars[free_var]; int def = var->definition; @@ -381,54 +386,56 @@ static bool try_remove_var_def(context *ctx, int free_var, int use_chain, zend_o def_opline->result.var = 0; def_op->result_def = -1; var->definition = -1; - return 1; + return true; default: break; } } } - return 0; + return false; } static zend_always_inline bool may_be_refcounted(uint32_t type) { return (type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) != 0; } -static inline bool is_free_of_live_var(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) { +static inline bool is_free_of_live_var(const context *ctx, const zend_op *opline, const zend_ssa_op *ssa_op) { switch (opline->opcode) { case ZEND_FREE: /* It is always safe to remove FREEs of non-refcounted values, even if they are live. */ if ((ctx->ssa->var_info[ssa_op->op1_use].type & (MAY_BE_REF|MAY_BE_ANY|MAY_BE_UNDEF)) != 0 && !may_be_refcounted(ctx->ssa->var_info[ssa_op->op1_use].type)) { - return 0; + return false; } ZEND_FALLTHROUGH; case ZEND_FE_FREE: return !is_var_dead(ctx, ssa_op->op1_use); default: - return 0; + return false; } } /* Returns whether the instruction has been DCEd */ -static bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) { - zend_ssa *ssa = ctx->ssa; +static bool dce_instr(const context *ctx, zend_op *opline, zend_ssa_op *ssa_op) { + const zend_ssa *ssa = ctx->ssa; int free_var = -1; uint8_t free_var_type; if (opline->opcode == ZEND_NOP) { - return 0; + return false; } /* We mark FREEs as dead, but they're only really dead if the destroyed var is dead */ if (is_free_of_live_var(ctx, opline, ssa_op)) { - return 0; + return false; } - if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))&& !is_var_dead(ctx, ssa_op->op1_use)) { + if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && !is_var_dead(ctx, ssa_op->op1_use)) { if (!try_remove_var_def(ctx, ssa_op->op1_use, ssa_op->op1_use_chain, opline)) { if (may_be_refcounted(ssa->var_info[ssa_op->op1_use].type) - && opline->opcode != ZEND_CASE && opline->opcode != ZEND_CASE_STRICT) { + && opline->opcode != ZEND_CASE + && opline->opcode != ZEND_CASE_STRICT + && opline->opcode != ZEND_COPY_TMP) { free_var = ssa_op->op1_use; free_var_type = opline->op1_type; } @@ -440,7 +447,7 @@ static bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) { if (free_var >= 0) { // TODO: We can't free two vars. Keep instruction alive. zend_bitset_excl(ctx->instr_dead, opline - ctx->op_array->opcodes); - return 0; + return false; } free_var = ssa_op->op2_use; free_var_type = opline->op2_type; @@ -459,12 +466,12 @@ static bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) { ssa_op->op1_use = free_var; ssa_op->op1_use_chain = ssa->vars[free_var].use_chain; ssa->vars[free_var].use_chain = ssa_op - ssa->ops; - return 0; + return false; } - return 1; + return true; } -static inline int get_common_phi_source(zend_ssa *ssa, zend_ssa_phi *phi) { +static inline int get_common_phi_source(const zend_ssa *ssa, zend_ssa_phi *phi) { int common_source = -1; int source; FOREACH_PHI_SOURCE(phi, source) { @@ -484,7 +491,7 @@ static inline int get_common_phi_source(zend_ssa *ssa, zend_ssa_phi *phi) { return common_source; } -static void try_remove_trivial_phi(context *ctx, zend_ssa_phi *phi) { +static void try_remove_trivial_phi(const context *ctx, zend_ssa_phi *phi) { zend_ssa *ssa = ctx->ssa; if (phi->pi < 0) { /* Phi assignment with identical source operands */ @@ -507,17 +514,17 @@ static void try_remove_trivial_phi(context *ctx, zend_ssa_phi *phi) { static inline bool may_break_varargs(const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_op *ssa_op) { if (ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].var < op_array->num_args) { - return 1; + return true; } if (ssa_op->op2_def >= 0 && ssa->vars[ssa_op->op2_def].var < op_array->num_args) { - return 1; + return true; } if (ssa_op->result_def >= 0 && ssa->vars[ssa_op->result_def].var < op_array->num_args) { - return 1; + return true; } - return 0; + return false; } static inline bool may_throw_dce_exception(const zend_op *opline) { @@ -562,12 +569,12 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer } FOREACH_PHI_END(); /* Mark reachable instruction without side effects as dead */ - int b = ssa->cfg.blocks_count; + uint32_t b = ssa->cfg.blocks_count; while (b > 0) { int op_data = -1; b--; - zend_basic_block *block = &ssa->cfg.blocks[b]; + const zend_basic_block *block = &ssa->cfg.blocks[b]; if (!(block->flags & ZEND_BB_REACHABLE)) { continue; } diff --git a/Zend/Optimizer/dfa_pass.c b/Zend/Optimizer/dfa_pass.c index bf85764c93b4..76ca8e5145f0 100644 --- a/Zend/Optimizer/dfa_pass.c +++ b/Zend/Optimizer/dfa_pass.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -226,7 +224,7 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op } /* update try/catch array */ - for (j = 0; j < op_array->last_try_catch; j++) { + for (uint32_t j = 0; j < op_array->last_try_catch; j++) { op_array->try_catch_array[j].try_op -= shiftlist[op_array->try_catch_array[j].try_op]; op_array->try_catch_array[j].catch_op -= shiftlist[op_array->try_catch_array[j].catch_op]; if (op_array->try_catch_array[j].finally_op) { @@ -256,11 +254,11 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op static bool safe_instanceof(const zend_class_entry *ce1, const zend_class_entry *ce2) { if (ce1 == ce2) { - return 1; + return true; } if (!(ce1->ce_flags & ZEND_ACC_LINKED)) { /* This case could be generalized, similarly to unlinked_instanceof */ - return 0; + return false; } return instanceof_function(ce1, ce2); } @@ -297,7 +295,14 @@ static inline bool can_elide_return_type_check( zend_ssa_var_info *use_info = &ssa->var_info[ssa_op->op1_use]; uint32_t use_type = use_info->type & (MAY_BE_ANY|MAY_BE_UNDEF); if (use_type & MAY_BE_REF) { - return 0; + return false; + } + /* When the declared return type contains a generic parameter, the + * compile-time arg_info is the erased type (typically mixed) but the + * effective type on a monomorph is the substituted one — eliding the + * VERIFY_RETURN_TYPE here would skip the per-monomorph runtime check. */ + if (op_array->generic_types && op_array->generic_types->return_type) { + return false; } if (use_type & MAY_BE_UNDEF) { @@ -322,20 +327,20 @@ static bool opline_supports_assign_contraction( zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, int src_var, uint32_t cv_var) { if (opline->opcode == ZEND_NEW) { /* see Zend/tests/generators/aborted_yield_during_new.phpt */ - return 0; + return false; } /* 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; + if ((opline + 1)->op1_type == IS_CV && (opline + 1)->op1.var == cv_var) return false; ZEND_FALLTHROUGH; case ZEND_FRAMELESS_ICALL_2: - if (opline->op2_type == IS_CV && opline->op2.var == cv_var) return 0; + if (opline->op2_type == IS_CV && opline->op2.var == cv_var) return false; ZEND_FALLTHROUGH; case ZEND_FRAMELESS_ICALL_1: - if (opline->op1_type == IS_CV && opline->op1.var == cv_var) return 0; - return 1; + if (opline->op1_type == IS_CV && opline->op1.var == cv_var) return false; + return true; } if (opline->opcode == ZEND_DO_ICALL || opline->opcode == ZEND_DO_UCALL @@ -374,10 +379,10 @@ static bool opline_supports_assign_contraction( && opline->op1_type == IS_CV && opline->op1.var == cv_var && zend_may_throw(opline, &ssa->ops[ssa->vars[src_var].definition], op_array, ssa)) { - return 0; + return false; } - return 1; + return true; } static bool variable_defined_or_used_in_range(zend_ssa *ssa, int var, int start, int end) @@ -391,20 +396,20 @@ static bool variable_defined_or_used_in_range(zend_ssa *ssa, int var, int start, (ssa_op->op2_use >= 0 && ssa->vars[ssa_op->op2_use].var == var) || (ssa_op->result_use >= 0 && ssa->vars[ssa_op->result_use].var == var) ) { - return 1; + return true; } start++; } - return 0; + return false; } -int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) +static uint32_t zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) { - zend_func_info *func_info = ZEND_FUNC_INFO(op_array); - int removed_ops = 0; + const zend_func_info *func_info = ZEND_FUNC_INFO(op_array); + uint32_t removed_ops = 0; if (func_info->callee_info) { - zend_call_info *call_info = func_info->callee_info; + const zend_call_info *call_info = func_info->callee_info; do { zend_op *op = call_info->caller_init_opline; @@ -413,22 +418,21 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) || (op->opcode == ZEND_FRAMELESS_ICALL_3 && (op + 1)->op1_type == IS_CONST)) && call_info->callee_func && zend_string_equals_literal_ci(call_info->callee_func->common.function_name, "in_array")) { - - bool strict = 0; + bool strict = false; 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))) { - strict = 1; + strict = true; } } if (op->op2_type == IS_CONST && Z_TYPE_P(CT_CONSTANT_EX(op_array, op->op2.constant)) == IS_ARRAY) { - bool ok = 1; + bool ok = true; - HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, op->op2.constant)); + const HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, op->op2.constant)); HashTable *dst; zval *val, tmp; zend_ulong idx; @@ -443,7 +447,7 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) zend_hash_index_add(dst, Z_LVAL_P(val), &tmp); } else { zend_array_destroy(dst); - ok = 0; + ok = false; break; } } ZEND_HASH_FOREACH_END(); @@ -451,7 +455,7 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) ZEND_HASH_FOREACH_VAL(src, val) { if (Z_TYPE_P(val) != IS_STRING || ZEND_HANDLE_NUMERIC(Z_STR_P(val), idx)) { zend_array_destroy(dst); - ok = 0; + ok = false; break; } zend_hash_add(dst, Z_STR_P(val), &tmp); @@ -479,7 +483,7 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa) return removed_ops; } -static zend_always_inline void take_successor_0(zend_ssa *ssa, int block_num, zend_basic_block *block) +static zend_always_inline void take_successor_0(zend_ssa *ssa, uint32_t block_num, zend_basic_block *block) { if (block->successors_count == 2) { if (block->successors[1] != block->successors[0]) { @@ -489,7 +493,7 @@ static zend_always_inline void take_successor_0(zend_ssa *ssa, int block_num, ze } } -static zend_always_inline void take_successor_1(zend_ssa *ssa, int block_num, zend_basic_block *block) +static zend_always_inline void take_successor_1(zend_ssa *ssa, uint32_t block_num, zend_basic_block *block) { if (block->successors_count == 2) { if (block->successors[1] != block->successors[0]) { @@ -500,11 +504,9 @@ static zend_always_inline void take_successor_1(zend_ssa *ssa, int block_num, ze } } -static zend_always_inline void take_successor_ex(zend_ssa *ssa, int block_num, zend_basic_block *block, int target_block) +static zend_always_inline void take_successor_ex(zend_ssa *ssa, uint32_t block_num, zend_basic_block *block, int target_block) { - int i; - - for (i = 0; i < block->successors_count; i++) { + for (uint32_t i = 0; i < block->successors_count; i++) { if (block->successors[i] != target_block) { zend_ssa_remove_predecessor(ssa, block_num, block->successors[i]); } @@ -531,10 +533,9 @@ static void replace_predecessor(zend_ssa *ssa, int block_id, int old_pred, int n int *predecessors = &ssa->cfg.predecessors[block->predecessor_offset]; zend_ssa_phi *phi; - int i; int old_pred_idx = -1; int new_pred_idx = -1; - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { if (predecessors[i] == old_pred) { old_pred_idx = i; } @@ -582,10 +583,9 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa zend_basic_block *src = &ssa->cfg.blocks[from]; zend_basic_block *old = &ssa->cfg.blocks[to]; zend_basic_block *dst = &ssa->cfg.blocks[new_to]; - int i; zend_op *opline; - for (i = 0; i < src->successors_count; i++) { + for (uint32_t i = 0; i < src->successors_count; i++) { if (src->successors[i] == to) { src->successors[i] = new_to; } @@ -650,10 +650,10 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa replace_predecessor(ssa, new_to, to, from); } -static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_basic_block *block, int block_num) +static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_basic_block *block, uint32_t block_num) { if (block->predecessors_count == 1 && ssa->blocks[block_num].phis == NULL) { - int *predecessors, i; + int *predecessors; zend_basic_block *fe_fetch_block = NULL; ZEND_ASSERT(block->successors_count == 1); @@ -669,7 +669,7 @@ static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_b } } } - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { zend_ssa_replace_control_link(op_array, ssa, predecessors[i], block_num, block->successors[0]); } zend_ssa_remove_block(op_array, ssa, block_num); @@ -686,7 +686,7 @@ static void zend_ssa_unlink_block(zend_op_array *op_array, zend_ssa *ssa, zend_b static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) { int removed_ops = 0; - int block_num = 0; + uint32_t block_num = 0; for (block_num = 1; block_num < ssa->cfg.blocks_count; block_num++) { zend_basic_block *block = &ssa->cfg.blocks[block_num]; @@ -706,17 +706,17 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) block_num++; } while (block_num < ssa->cfg.blocks_count) { - int next_block_num = block_num + 1; + uint32_t next_block_num = block_num + 1; zend_basic_block *block = &ssa->cfg.blocks[block_num]; uint32_t op_num; zend_op *opline; zend_ssa_op *ssa_op; - bool can_follow = 1; + bool can_follow = true; while (next_block_num < ssa->cfg.blocks_count && !(ssa->cfg.blocks[next_block_num].flags & ZEND_BB_REACHABLE)) { if (ssa->cfg.blocks[next_block_num].flags & ZEND_BB_UNREACHABLE_FREE) { - can_follow = 0; + can_follow = false; } next_block_num++; } @@ -941,11 +941,13 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) if (block_num > 0) { zend_ssa_unlink_block(op_array, ssa, block, block_num); /* backtrack to previous basic block */ + int backtracking_block_num = block_num; do { - block_num--; - } while (block_num >= 0 - && !(ssa->cfg.blocks[block_num].flags & ZEND_BB_REACHABLE)); - if (block_num >= 0) { + backtracking_block_num--; + } while (backtracking_block_num >= 0 + && !(ssa->cfg.blocks[backtracking_block_num].flags & ZEND_BB_REACHABLE)); + if (backtracking_block_num >= 0) { + block_num = backtracking_block_num; continue; } } @@ -989,7 +991,7 @@ static bool zend_dfa_try_to_replace_result(zend_op_array *op_array, zend_ssa *ss if ((opline->op1_type == IS_CV && opline->op1.var == cv) || (opline->op2_type == IS_CV && opline->op2.var == cv) || (opline->result_type == IS_CV && opline->result.var == cv)) { - return 0; + return false; } opline--; i--; @@ -1026,12 +1028,12 @@ static bool zend_dfa_try_to_replace_result(zend_op_array *op_array, zend_ssa *ss op_array->opcodes[use].result.var = cv; } - return 1; + return true; } } } - return 0; + return false; } void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa, zend_call_info **call_map) diff --git a/Zend/Optimizer/escape_analysis.c b/Zend/Optimizer/escape_analysis.c index 840a18341a0f..8dbd6855d68d 100644 --- a/Zend/Optimizer/escape_analysis.c +++ b/Zend/Optimizer/escape_analysis.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache, Escape Analysis | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -78,7 +76,7 @@ static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_ar zend_ssa_var *ssa_vars = ssa->vars; int ssa_vars_count = ssa->vars_count; zend_ssa_phi *p; - int i, j; + int i; int *size; ALLOCA_FLAG(use_heap) @@ -94,7 +92,7 @@ static zend_result zend_build_equi_escape_sets(int *parent, zend_op_array *op_ar if (p->pi >= 0) { union_find_unite(parent, size, i, p->sources[0]); } else { - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { union_find_unite(parent, size, i, p->sources[j]); } } @@ -155,7 +153,7 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i if (ssa_op->result_def == var) { switch (opline->opcode) { case ZEND_INIT_ARRAY: - return 1; + return true; case ZEND_NEW: { /* objects with destructors should escape */ zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( @@ -175,22 +173,22 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i && !ce->__set && !(ce->ce_flags & forbidden_flags) && (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - return 1; + return true; } break; } case ZEND_QM_ASSIGN: if (opline->op1_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op1)) == IS_ARRAY) { - return 1; + return true; } if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_ARRAY)) { - return 1; + return true; } break; case ZEND_ASSIGN: if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_ARRAY)) { - return 1; + return true; } break; } @@ -199,22 +197,22 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i case ZEND_ASSIGN: if (opline->op2_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_ARRAY) { - return 1; + return true; } if (opline->op2_type == IS_CV && (OP2_INFO() & MAY_BE_ARRAY)) { - return 1; + return true; } break; case ZEND_ASSIGN_DIM: if (OP1_INFO() & (MAY_BE_UNDEF | MAY_BE_NULL | MAY_BE_FALSE)) { /* implicit object/array allocation */ - return 1; + return true; } break; } } - return 0; + return false; } /* }}} */ @@ -229,7 +227,7 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va case ZEND_ADD_ARRAY_ELEMENT: case ZEND_QM_ASSIGN: case ZEND_ASSIGN: - return 1; + return true; case ZEND_NEW: { /* objects with destructors should escape */ zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( @@ -243,7 +241,7 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va && !ce->__get && !ce->__set && !ce->parent) { - return 1; + return true; } break; } @@ -260,11 +258,11 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: - return 1; + return true; } } - return 0; + return false; } /* }}} */ @@ -282,7 +280,7 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v if (opline->op1_type == IS_CV) { if (OP1_INFO() & MAY_BE_OBJECT) { /* object aliasing */ - return 1; + return true; } } break; @@ -294,7 +292,7 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v case ZEND_FETCH_OBJ_IS: break; case ZEND_ASSIGN_OP: - return 1; + return true; case ZEND_ASSIGN_DIM_OP: case ZEND_ASSIGN_OBJ_OP: case ZEND_ASSIGN_STATIC_PROP_OP: @@ -310,22 +308,22 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v case ZEND_INIT_ARRAY: case ZEND_ADD_ARRAY_ELEMENT: if (opline->extended_value & ZEND_ARRAY_ELEMENT_REF) { - return 1; + return true; } if (OP1_INFO() & MAY_BE_OBJECT) { /* object aliasing */ - return 1; + return true; } /* reference dependencies processed separately */ break; case ZEND_OP_DATA: if ((opline-1)->opcode != ZEND_ASSIGN_DIM && (opline-1)->opcode != ZEND_ASSIGN_OBJ) { - return 1; + return true; } if (OP1_INFO() & MAY_BE_OBJECT) { /* object aliasing */ - return 1; + return true; } opline--; ssa_op--; @@ -333,12 +331,12 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v || (OP1_INFO() & MAY_BE_REF) || (ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].alias)) { /* assignment into escaping structure */ - return 1; + return true; } /* reference dependencies processed separately */ break; default: - return 1; + return true; } } @@ -349,17 +347,17 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v || (OP1_INFO() & MAY_BE_REF) || (ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].alias)) { /* assignment into escaping variable */ - return 1; + return true; } if (opline->op2_type == IS_CV || opline->result_type != IS_UNUSED) { if (OP2_INFO() & MAY_BE_OBJECT) { /* object aliasing */ - return 1; + return true; } } break; default: - return 1; + return true; } } @@ -371,11 +369,11 @@ static bool is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int v case ZEND_ADD_ARRAY_ELEMENT: break; default: - return 1; + return true; } } - return 0; + return false; } /* }}} */ @@ -393,12 +391,12 @@ zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *o return SUCCESS; } - has_allocations = 0; + has_allocations = false; for (i = op_array->last_var; i < ssa_vars_count; i++) { if (ssa_vars[i].definition >= 0 && (ssa->var_info[i].type & (MAY_BE_ARRAY|MAY_BE_OBJECT)) && is_allocation_def(op_array, ssa, ssa_vars[i].definition, i, script)) { - has_allocations = 1; + has_allocations = true; break; } } @@ -470,7 +468,7 @@ zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *o bool changed; do { - changed = 0; + changed = false; for (i = 0; i < ssa_vars_count; i++) { if (ssa_vars[i].use_chain >= 0) { root = ees[i]; @@ -506,13 +504,13 @@ zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *o if (ssa_vars[root].escape_state == ESCAPE_STATE_GLOBAL_ESCAPE) { num_non_escaped--; if (num_non_escaped == 0) { - changed = 0; + changed = false; } else { - changed = 1; + changed = true; } break; } else { - changed = 1; + changed = true; } } } FOREACH_USE_END(); diff --git a/Zend/Optimizer/nop_removal.c b/Zend/Optimizer/nop_removal.c index fd5a87cbfb28..0a6a04fc4a9b 100644 --- a/Zend/Optimizer/nop_removal.c +++ b/Zend/Optimizer/nop_removal.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -32,21 +30,20 @@ void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx) { - zend_op *end, *opline; + zend_op *opline; uint32_t new_count, i, shift; - int j; uint32_t *shiftlist; ALLOCA_FLAG(use_heap); shiftlist = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last, use_heap); i = new_count = shift = 0; - end = op_array->opcodes + op_array->last; + const zend_op *end = op_array->opcodes + op_array->last; for (opline = op_array->opcodes; opline < end; opline++) { /* Kill JMP-over-NOP-s */ if (opline->opcode == ZEND_JMP && ZEND_OP1_JMP_ADDR(opline) > op_array->opcodes + i) { /* check if there are only NOPs under the branch */ - zend_op *target = ZEND_OP1_JMP_ADDR(opline) - 1; + const zend_op *target = ZEND_OP1_JMP_ADDR(opline) - 1; while (target->opcode == ZEND_NOP) { target--; @@ -81,7 +78,7 @@ void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx } /* update try/catch array */ - for (j = 0; j < op_array->last_try_catch; j++) { + for (uint32_t j = 0; j < op_array->last_try_catch; j++) { op_array->try_catch_array[j].try_op -= shiftlist[op_array->try_catch_array[j].try_op]; op_array->try_catch_array[j].catch_op -= shiftlist[op_array->try_catch_array[j].catch_op]; if (op_array->try_catch_array[j].finally_op) { diff --git a/Zend/Optimizer/optimize_func_calls.c b/Zend/Optimizer/optimize_func_calls.c index 8b29f47c9497..9995473f48ab 100644 --- a/Zend/Optimizer/optimize_func_calls.c +++ b/Zend/Optimizer/optimize_func_calls.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -37,7 +35,7 @@ typedef struct _optimizer_call_info { uint32_t func_arg_num; } optimizer_call_info; -static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opline) +static void zend_delete_call_instructions(const zend_op_array *op_array, zend_op *opline) { int call = 0; @@ -76,7 +74,113 @@ 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) +/* The compiler emits a speculative VERIFY_GENERIC_ARGUMENTS at call sites + * where the callee can't be resolved at compile time; the runtime handler + * short-circuits when the resolved callee turns out to be non-generic. Once + * the optimizer has resolved the callee here, that VERIFY (and any INSTALL, + * defensively) is provably dead — NOP it out so downstream passes (inline, + * DCE, JIT) don't have to model the extra opcode. + * + * For NEW the VERIFY also performs the class-level generic-arg arity/bound + * check against the *class*, not the constructor; in that case the + * constructor's func is irrelevant and we have to consult the class entry + * passed alongside it. */ +static void zend_nop_dead_generic_verify( + zend_op *do_opline, const zend_function *func, const zend_class_entry *new_ce) +{ + if (new_ce && new_ce->generic_parameters) { + return; /* `new GenericClass::<...>` VERIFY does class-arity check */ + } + if (func && ZEND_USER_CODE(func->common.type) && func->op_array.generic_parameters) { + return; /* genuinely generic — leave the verify alone */ + } + if (!func && !new_ce) return; + zend_op *opline = do_opline - 1; + int call = 0; + while (1) { + switch (opline->opcode) { + case ZEND_INIT_FCALL_BY_NAME: + case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_STATIC_METHOD_CALL: + case ZEND_INIT_METHOD_CALL: + case ZEND_INIT_FCALL: + case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL: + case ZEND_NEW: + case ZEND_INIT_DYNAMIC_CALL: + case ZEND_INIT_USER_CALL: + /* Hitting any call-setup at call==0 means we've reached the + * matching INIT/NEW for this DO_FCALL — no further VERIFY + * to scan; bail out before walking off the opcode array. */ + if (call == 0) return; + call--; + break; + case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: + call++; + break; + case ZEND_VERIFY_GENERIC_ARGUMENTS: + case ZEND_INSTALL_GENERIC_ARGS: + if (call == 0) { + /* Even when the callee is non-generic, VERIFY's arity + * check needs to fire if turbofish args were supplied + * (`f::()` on a non-generic `f` must error). The + * compiler stores the turbofish args_id in extended_value + * — non-zero means "user passed turbofish here." */ + if (opline->extended_value != 0) return; + MAKE_NOP(opline); + } + break; + } + opline--; + } +} + +/* Returns true if a VERIFY_GENERIC_ARGUMENTS sits between this call's INIT and + * DO opcodes; such a call cannot be inlined because the verify opcode reads + * EX(call), which goes away once the frame is dropped. */ +static bool zend_call_has_generic_arguments_check(zend_op *opline) +{ + int call = 0; + while (1) { + switch (opline->opcode) { + case ZEND_INIT_FCALL_BY_NAME: + case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_STATIC_METHOD_CALL: + case ZEND_INIT_METHOD_CALL: + case ZEND_INIT_FCALL: + case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL: + case ZEND_NEW: + case ZEND_INIT_DYNAMIC_CALL: + case ZEND_INIT_USER_CALL: + /* Same termination guard as zend_nop_dead_generic_verify + * — NEW also acts as the call setup for the constructor's + * DO_FCALL in `new Foo()` (no separate INIT). */ + if (call == 0) { + return false; + } + call--; + break; + case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: + call++; + break; + case ZEND_VERIFY_GENERIC_ARGUMENTS: + case ZEND_INSTALL_GENERIC_ARGS: + if (call == 0) { + return true; + } + break; + } + + opline--; + } +} + +static void zend_try_inline_call(zend_op_array *op_array, const zend_op *fcall, zend_op *opline, const zend_function *func) { const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD; @@ -99,6 +203,15 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o return; } + if (zend_call_has_generic_arguments_check(opline - 1)) { + /* The verify opcode must run; inlining would orphan it. The + * scan is cheap and handles both the turbofish path (where + * generic_types->turbofish_args is populated) and the + * speculative emit for unknown-at-compile-time callees + * (which has no turbofish args at all). */ + return; + } + for (i = 0; i < num_args; i++) { /* Don't inline functions with by-reference arguments. This would require * correct handling of INDIRECT arguments. */ @@ -153,7 +266,7 @@ static bool has_known_send_mode(const optimizer_call_info *info, uint32_t arg_nu void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) { zend_op *opline = op_array->opcodes; - zend_op *end = opline + op_array->last; + const zend_op *end = opline + op_array->last; int call = 0; void *checkpoint; optimizer_call_info *call_stack; @@ -194,6 +307,24 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) case ZEND_DO_FCALL_BY_NAME: case ZEND_CALLABLE_CONVERT: call--; + /* INIT_DYNAMIC_CALL / INIT_USER_CALL don't get their callee + * resolved in the upper switch (no specialized INIT rewrite is + * possible), but we can still resolve for VERIFY-elision purposes + * — get_called_func now infers a callee when the CV holds a + * known constant or NEW result. Use the result for VERIFY + * elision only; don't promote the INIT/DO opcodes or attempt + * inlining, since the call site must stay dynamic-shaped. */ + if (!call_stack[call].func && call_stack[call].opline + && (call_stack[call].opline->opcode == ZEND_INIT_DYNAMIC_CALL + || call_stack[call].opline->opcode == ZEND_INIT_USER_CALL) + && opline->opcode != ZEND_CALLABLE_CONVERT) { + bool is_prototype = false; + const zend_function *func = zend_optimizer_get_called_func( + ctx->script, op_array, call_stack[call].opline, &is_prototype); + if (func) { + zend_nop_dead_generic_verify(opline, func, NULL); + } + } if (call_stack[call].func && call_stack[call].opline) { zend_op *fcall = call_stack[call].opline; @@ -229,6 +360,22 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) opline->opcode = zend_get_call_op(fcall, call_stack[call].func, !RESULT_UNUSED(opline)); } + /* Strip the speculative generic-arg verify now that we + * know the callee — needs to happen before the inline + * attempt below, which bails out when a verify still + * sits between INIT and DO. For NEW, pass the class + * entry separately so the helper can spot a generic + * class with a non-generic constructor (the VERIFY's + * arity check is against the class, not the ctor). */ + if (opline->opcode != ZEND_CALLABLE_CONVERT) { + const zend_class_entry *new_ce = NULL; + if (fcall->opcode == ZEND_NEW) { + new_ce = zend_optimizer_get_class_entry_from_op1( + ctx->script, op_array, fcall); + } + zend_nop_dead_generic_verify(opline, call_stack[call].func, new_ce); + } + if ((ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level) && call_stack[call].try_inline && opline->opcode != ZEND_CALLABLE_CONVERT) { @@ -237,7 +384,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) } call_stack[call].func = NULL; call_stack[call].opline = NULL; - call_stack[call].try_inline = 0; + call_stack[call].try_inline = false; call_stack[call].func_arg_num = (uint32_t)-1; break; case ZEND_FETCH_FUNC_ARG: @@ -265,7 +412,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) && opline->op2_type == IS_UNUSED) { /* FETCH_DIM_FUNC_ARG supports UNUSED op2, while FETCH_DIM_R does not. * Performing the replacement would create an invalid opcode. */ - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; break; } @@ -279,7 +426,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; case ZEND_SEND_VAL_EX: if (opline->op2_type == IS_CONST) { - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; break; } @@ -291,7 +438,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; case ZEND_CHECK_FUNC_ARG: if (opline->op2_type == IS_CONST) { - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; call_stack[call - 1].func_arg_num = (uint32_t)-1; break; } @@ -305,7 +452,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) /* Don't transform SEND_FUNC_ARG if any FETCH opcodes weren't transformed. */ if (call_stack[call - 1].last_check_func_arg_opline == NULL) { if (opline->op2_type == IS_CONST) { - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; } break; } @@ -314,7 +461,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) ZEND_FALLTHROUGH; case ZEND_SEND_VAR_EX: if (opline->op2_type == IS_CONST) { - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; break; } @@ -329,7 +476,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; case ZEND_SEND_VAR_NO_REF_EX: if (opline->op2_type == IS_CONST) { - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; break; } @@ -347,14 +494,14 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) case ZEND_SEND_VAR: case ZEND_SEND_REF: if (opline->op2_type == IS_CONST) { - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; break; } break; case ZEND_SEND_UNPACK: case ZEND_SEND_USER: case ZEND_SEND_ARRAY: - call_stack[call - 1].try_inline = 0; + call_stack[call - 1].try_inline = false; break; default: break; diff --git a/Zend/Optimizer/optimize_temp_vars_5.c b/Zend/Optimizer/optimize_temp_vars_5.c index de0b189d5dca..6a5c99f4755b 100644 --- a/Zend/Optimizer/optimize_temp_vars_5.c +++ b/Zend/Optimizer/optimize_temp_vars_5.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index fe92db583fcd..962bdb6e4be3 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -149,7 +147,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) if (opline->op2_type == IS_CONST && Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { /* substitute persistent constants */ - if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP2_LITERAL(opline)), &result, 1)) { + if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP2_LITERAL(opline)), &result, true)) { if (!ctx->constants || !zend_optimizer_get_collected_constant(ctx->constants, &ZEND_OP2_LITERAL(opline), &result)) { break; } @@ -171,7 +169,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) 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) + || !zend_optimizer_get_persistent_constant(zend_ast_get_constant_name(ast), &result, true) || Z_TYPE(result) == IS_CONSTANT_AST) { break; } @@ -193,7 +191,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) if (send1_opline->opcode != ZEND_SEND_VAL || send1_opline->op1_type != IS_CONST) { /* don't collect constants after unknown function call */ - collect_constants = 0; + collect_constants = false; break; } if (send1_opline->op2.num == 2) { @@ -205,7 +203,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) if (send1_opline->opcode != ZEND_SEND_VAL || send1_opline->op1_type != IS_CONST) { /* don't collect constants after unknown function call */ - collect_constants = 0; + collect_constants = false; break; } } @@ -217,7 +215,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) init_opline->op2_type != IS_CONST || Z_TYPE(ZEND_OP2_LITERAL(init_opline)) != IS_STRING) { /* don't collect constants after unknown function call */ - collect_constants = 0; + collect_constants = false; break; } @@ -261,9 +259,19 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } /* don't collect constants after any other function call */ - collect_constants = 0; + collect_constants = false; break; } + case ZEND_DO_UCALL: + case ZEND_DO_FCALL: + case ZEND_DO_FCALL_BY_NAME: + case ZEND_FRAMELESS_ICALL_0: + case ZEND_FRAMELESS_ICALL_1: + case ZEND_FRAMELESS_ICALL_2: + case ZEND_FRAMELESS_ICALL_3: + /* don't collect constants after any UCALL/FCALL/FRAMELESS ICALL */ + collect_constants = 0; + break; case ZEND_STRLEN: if (opline->op1_type == IS_CONST && zend_optimizer_eval_strlen(&result, &ZEND_OP1_LITERAL(opline)) == SUCCESS) { @@ -271,7 +279,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } break; case ZEND_DEFINED: - if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &result, 0)) { + if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &result, false)) { break; } ZVAL_TRUE(&result); @@ -309,7 +317,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } } } - collect_constants = 0; + collect_constants = false; break; case ZEND_JMPZ: @@ -331,7 +339,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; } } - collect_constants = 0; + collect_constants = false; break; case ZEND_RETURN: @@ -354,7 +362,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) case ZEND_VERIFY_NEVER_TYPE: case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_JMP_FRAMELESS: - collect_constants = 0; + collect_constants = false; break; } opline++; diff --git a/Zend/Optimizer/pass3.c b/Zend/Optimizer/pass3.c index 2cbd0e340652..2d2a44685226 100644 --- a/Zend/Optimizer/pass3.c +++ b/Zend/Optimizer/pass3.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -37,10 +35,10 @@ static zend_always_inline bool in_hitlist(zend_op *target, zend_op **jmp_hitlist for (i = 0; i < jmp_hitlist_count; i++) { if (jmp_hitlist[i] == target) { - return 1; + return true; } } - return 0; + return false; } #define CHECK_LOOP(target) \ diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index c86672a8dd24..ba94e9b7b91f 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SCCP - Sparse Conditional Constant Propagation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Dmitry Stogov | @@ -244,7 +242,7 @@ static bool can_replace_op1( case ZEND_SEND_ARRAY: case ZEND_SEND_USER: case ZEND_FE_RESET_RW: - return 0; + return false; /* Do not accept CONST */ case ZEND_ROPE_ADD: case ZEND_ROPE_END: @@ -254,7 +252,7 @@ static bool can_replace_op1( case ZEND_MAKE_REF: case ZEND_UNSET_CV: case ZEND_ISSET_ISEMPTY_CV: - return 0; + return false; case ZEND_INIT_ARRAY: case ZEND_ADD_ARRAY_ELEMENT: return !(opline->extended_value & ZEND_ARRAY_ELEMENT_REF); @@ -262,18 +260,18 @@ static bool can_replace_op1( return !(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE); case ZEND_VERIFY_RETURN_TYPE: // TODO: This would require a non-local change ??? - return 0; + return false; case ZEND_OP_DATA: return (opline - 1)->opcode != ZEND_ASSIGN_OBJ_REF && (opline - 1)->opcode != ZEND_ASSIGN_STATIC_PROP_REF; default: if (ssa_op->op1_def != -1) { ZEND_UNREACHABLE(); - return 0; + return false; } } - return 1; + return true; } static bool can_replace_op2( @@ -284,9 +282,9 @@ static bool can_replace_op2( case ZEND_BIND_LEXICAL: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: - return 0; + return false; } - return 1; + return true; } static bool try_replace_op1( @@ -295,11 +293,11 @@ static bool try_replace_op1( zval zv; ZVAL_COPY(&zv, value); if (zend_optimizer_update_op1_const(ctx->scdf.op_array, opline, &zv)) { - return 1; + return true; } zval_ptr_dtor_nogc(&zv); } - return 0; + return false; } static bool try_replace_op2( @@ -308,11 +306,11 @@ static bool try_replace_op2( zval zv; ZVAL_COPY(&zv, value); if (zend_optimizer_update_op2_const(ctx->scdf.op_array, opline, &zv)) { - return 1; + return true; } zval_ptr_dtor_nogc(&zv); } - return 0; + return false; } static inline zend_result ct_eval_binary_op(zval *result, uint8_t binop, zval *op1, zval *op2) { @@ -335,6 +333,10 @@ static inline zend_result ct_eval_bool_cast(zval *result, zval *op) { ZVAL_TRUE(result); return SUCCESS; } + /* NAN warns when casting */ + if (Z_TYPE_P(op) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op))) { + return FAILURE; + } ZVAL_BOOL(result, zend_is_true(op)); return SUCCESS; @@ -359,8 +361,7 @@ static inline zend_result zval_to_string_offset(zend_long *result, zval *op) { static inline zend_result fetch_array_elem(zval **result, zval *op1, zval *op2) { switch (Z_TYPE_P(op2)) { case IS_NULL: - *result = zend_hash_find(Z_ARR_P(op1), ZSTR_EMPTY_ALLOC()); - return SUCCESS; + return FAILURE; case IS_FALSE: *result = zend_hash_index_find(Z_ARR_P(op1), 0); return SUCCESS; @@ -371,7 +372,7 @@ static inline zend_result fetch_array_elem(zval **result, zval *op1, zval *op2) *result = zend_hash_index_find(Z_ARR_P(op1), Z_LVAL_P(op2)); return SUCCESS; case IS_DOUBLE: { - zend_long lval = zend_dval_to_lval(Z_DVAL_P(op2)); + zend_long lval = zend_dval_to_lval_silent(Z_DVAL_P(op2)); if (!zend_is_long_compatible(Z_DVAL_P(op2), lval)) { return FAILURE; } @@ -399,7 +400,7 @@ static inline zend_result ct_eval_fetch_dim(zval *result, zval *op1, zval *op2, return FAILURE; } if (index >= 0 && index < Z_STRLEN_P(op1)) { - ZVAL_STR(result, zend_string_init(&Z_STRVAL_P(op1)[index], 1, 0)); + ZVAL_CHAR(result, Z_STRVAL_P(op1)[index]); return SUCCESS; } } @@ -459,7 +460,7 @@ static inline zend_result ct_eval_del_array_elem(zval *result, const zval *key) zend_hash_index_del(Z_ARR_P(result), Z_LVAL_P(key)); break; case IS_DOUBLE: { - zend_long lval = zend_dval_to_lval(Z_DVAL_P(key)); + zend_long lval = zend_dval_to_lval_silent(Z_DVAL_P(key)); if (!zend_is_long_compatible(Z_DVAL_P(key), lval)) { return FAILURE; } @@ -504,7 +505,7 @@ static inline zend_result ct_eval_add_array_elem(zval *result, zval *value, cons value = zend_hash_index_update(Z_ARR_P(result), Z_LVAL_P(key), value); break; case IS_DOUBLE: { - zend_long lval = zend_dval_to_lval(Z_DVAL_P(key)); + zend_long lval = zend_dval_to_lval_silent(Z_DVAL_P(key)); if (!zend_is_long_compatible(Z_DVAL_P(key), lval)) { return FAILURE; } @@ -714,7 +715,7 @@ static inline zend_result ct_eval_in_array(zval *result, uint32_t extended_value if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { res = zend_hash_index_exists(ht, Z_LVAL_P(op1)); } else { - res = 0; + res = false; } } else if (Z_TYPE_P(op1) <= IS_FALSE) { res = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); @@ -722,11 +723,11 @@ static inline zend_result ct_eval_in_array(zval *result, uint32_t extended_value zend_string *key; zval key_tmp; - res = 0; + res = false; ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&key_tmp, key); if (zend_compare(op1, &key_tmp) == 0) { - res = 1; + res = true; break; } } ZEND_HASH_FOREACH_END(); @@ -838,9 +839,7 @@ static inline zend_result ct_eval_func_call_ex( zval_ptr_dtor(result); zend_clear_exception(); retval = FAILURE; - } - - if (EG(capture_warnings_during_sccp) > 1) { + } else if (EG(capture_warnings_during_sccp) > 1) { zval_ptr_dtor(result); retval = FAILURE; } @@ -967,7 +966,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o SET_RESULT(op1, &zv); } else if (ct_eval_assign_dim(&zv, data, op2) == SUCCESS) { /* Mark array containing partial array as partial */ - if (IS_PARTIAL_ARRAY(data)) { + if (IS_PARTIAL_ARRAY(data) || IS_PARTIAL_OBJECT(data)) { MAKE_PARTIAL_ARRAY(&zv); } SET_RESULT(result, data); @@ -1104,6 +1103,11 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o if (op2) { SKIP_IF_TOP(op2); + if (Z_TYPE_P(op2) == IS_NULL) { + /* Emits deprecation at run-time. */ + SET_RESULT_BOT(result); + return; + } } /* We want to avoid keeping around intermediate arrays for each SSA variable in the @@ -1167,7 +1171,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o /* We can't add NEXT element into partial array (skip it) */ SET_RESULT(result, &zv); } else if (ct_eval_add_array_elem(&zv, op1, op2) == SUCCESS) { - if (IS_PARTIAL_ARRAY(op1)) { + if (IS_PARTIAL_ARRAY(op1) || IS_PARTIAL_OBJECT(op1)) { MAKE_PARTIAL_ARRAY(&zv); } SET_RESULT(result, &zv); @@ -1590,7 +1594,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o case ZEND_SHORT_CIRCUITING_CHAIN_EMPTY: ZVAL_TRUE(&zv); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } SET_RESULT(result, &zv); break; @@ -1648,7 +1652,6 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o { zend_call_info *call; zval *name, *args[3] = {NULL}; - int i; if (!ctx->call_map) { SET_RESULT_BOT(result); @@ -1670,7 +1673,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o break; } - for (i = 0; i < call->num_args; i++) { + for (uint32_t i = 0; i < call->num_args; i++) { zend_op *opline = call->arg_info[i].opline; if (opline->opcode != ZEND_SEND_VAL && opline->opcode != ZEND_SEND_VAR) { SET_RESULT_BOT(result); @@ -1827,7 +1830,7 @@ static void sccp_mark_feasible_successors( zend_op *opline, zend_ssa_op *ssa_op) { sccp_ctx *ctx = (sccp_ctx *) scdf; zval *op1, zv; - int s; + uint32_t s; /* We can't determine the branch target at compile-time for these */ switch (opline->opcode) { @@ -2036,7 +2039,7 @@ static void join_phi_values(zval *a, zval *b, bool escape) { } } -static void sccp_visit_phi(scdf_ctx *scdf, zend_ssa_phi *phi) { +static void sccp_visit_phi(scdf_ctx *scdf, const zend_ssa_phi *phi) { sccp_ctx *ctx = (sccp_ctx *) scdf; zend_ssa *ssa = scdf->ssa; ZEND_ASSERT(phi->ssa_var >= 0); @@ -2044,7 +2047,6 @@ static void sccp_visit_phi(scdf_ctx *scdf, zend_ssa_phi *phi) { zend_basic_block *block = &ssa->cfg.blocks[phi->block]; int *predecessors = &ssa->cfg.predecessors[block->predecessor_offset]; - int i; zval result; MAKE_TOP(&result); #if SCP_DEBUG @@ -2056,7 +2058,7 @@ static void sccp_visit_phi(scdf_ctx *scdf, zend_ssa_phi *phi) { join_phi_values(&result, &ctx->values[phi->sources[0]], ssa->vars[phi->ssa_var].escape_state != ESCAPE_STATE_NO_ESCAPE); } } else { - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { ZEND_ASSERT(phi->sources[i] >= 0); if (scdf_is_edge_feasible(scdf, predecessors[i], phi->block)) { #if SCP_DEBUG @@ -2086,7 +2088,6 @@ static int remove_call(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op) zend_ssa *ssa = ctx->scdf.ssa; zend_op_array *op_array = ctx->scdf.op_array; zend_call_info *call; - int i; ZEND_ASSERT(ctx->call_map); call = ctx->call_map[opline - op_array->opcodes]; @@ -2096,7 +2097,7 @@ static int remove_call(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op) zend_ssa_remove_instr(ssa, call->caller_init_opline, &ssa->ops[call->caller_init_opline - op_array->opcodes]); - for (i = 0; i < call->num_args; i++) { + for (uint32_t i = 0; i < call->num_args; i++) { zend_ssa_remove_instr(ssa, call->arg_info[i].opline, &ssa->ops[call->arg_info[i].opline - op_array->opcodes]); } @@ -2120,11 +2121,11 @@ static int remove_call(sccp_ctx *ctx, zend_op *opline, zend_ssa_op *ssa_op) * we need to collect. * d) The ordinary DCE pass cannot collect construction of dead non-escaping arrays and objects. */ -static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, zval *value) +static uint32_t try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, zval *value) { zend_ssa *ssa = ctx->scdf.ssa; zend_op_array *op_array = ctx->scdf.op_array; - int removed_ops = 0; + uint32_t removed_ops = 0; if (var->definition >= 0) { zend_op *opline = &op_array->opcodes[var->definition]; @@ -2368,12 +2369,12 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, /* This will try to replace uses of SSA variables we have determined to be constant. Not all uses * can be replaced, because some instructions don't accept constant operands or only accept them * if they have a certain type. */ -static int replace_constant_operands(sccp_ctx *ctx) { +static uint32_t replace_constant_operands(sccp_ctx *ctx) { zend_ssa *ssa = ctx->scdf.ssa; zend_op_array *op_array = ctx->scdf.op_array; int i; zval tmp; - int removed_ops = 0; + uint32_t removed_ops = 0; /* We iterate the variables backwards, so we can eliminate sequences like INIT_ROPE * and INIT_ARRAY. */ @@ -2466,10 +2467,10 @@ static void sccp_context_free(sccp_ctx *sccp) { } } -int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map) +uint32_t sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map) { sccp_ctx sccp; - int removed_ops = 0; + uint32_t removed_ops = 0; void *checkpoint = zend_arena_checkpoint(ctx->arena); sccp_context_init(ctx, &sccp, ssa, op_array, call_map); diff --git a/Zend/Optimizer/scdf.c b/Zend/Optimizer/scdf.c index 54925e8287b6..31f40a7ed9f9 100644 --- a/Zend/Optimizer/scdf.c +++ b/Zend/Optimizer/scdf.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Sparse Conditional Data Flow Propagation Framework | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ @@ -70,9 +68,8 @@ void scdf_mark_edge_feasible(scdf_ctx *scdf, int from, int to) { } else { /* Block is already executable, only a new edge became feasible. * Reevaluate phi nodes to account for changed source operands. */ - zend_ssa_block *ssa_block = &scdf->ssa->blocks[to]; - zend_ssa_phi *phi; - for (phi = ssa_block->phis; phi; phi = phi->next) { + const zend_ssa_block *ssa_block = &scdf->ssa->blocks[to]; + for (const zend_ssa_phi *phi = ssa_block->phis; phi; phi = phi->next) { zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var); scdf->handlers.visit_phi(scdf, phi); } @@ -101,7 +98,7 @@ void scdf_init(zend_optimizer_ctx *ctx, scdf_ctx *scdf, zend_op_array *op_array, } void scdf_solve(scdf_ctx *scdf, const char *name) { - zend_ssa *ssa = scdf->ssa; + const zend_ssa *ssa = scdf->ssa; DEBUG_PRINT("Start SCDF solve (%s)\n", name); while (!zend_bitset_empty(scdf->instr_worklist, scdf->instr_worklist_len) || !zend_bitset_empty(scdf->phi_var_worklist, scdf->phi_var_worklist_len) @@ -109,7 +106,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) { ) { int i; while ((i = zend_bitset_pop_first(scdf->phi_var_worklist, scdf->phi_var_worklist_len)) >= 0) { - zend_ssa_phi *phi = ssa->vars[i].definition_phi; + const zend_ssa_phi *phi = ssa->vars[i].definition_phi; ZEND_ASSERT(phi); if (zend_bitset_in(scdf->executable_blocks, phi->block)) { scdf->handlers.visit_phi(scdf, phi); @@ -140,17 +137,14 @@ void scdf_solve(scdf_ctx *scdf, const char *name) { while ((i = zend_bitset_pop_first(scdf->block_worklist, scdf->block_worklist_len)) >= 0) { /* This block is now live. Interpret phis and instructions in it. */ zend_basic_block *block = &ssa->cfg.blocks[i]; - zend_ssa_block *ssa_block = &ssa->blocks[i]; + const zend_ssa_block *ssa_block = &ssa->blocks[i]; DEBUG_PRINT("Pop block %d from worklist\n", i); zend_bitset_incl(scdf->executable_blocks, i); - { - zend_ssa_phi *phi; - for (phi = ssa_block->phis; phi; phi = phi->next) { - zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var); - scdf->handlers.visit_phi(scdf, phi); - } + for (const zend_ssa_phi *phi = ssa_block->phis; phi; phi = phi->next) { + zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var); + scdf->handlers.visit_phi(scdf, phi); } if (block->len == 0) { @@ -158,7 +152,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) { scdf_mark_edge_feasible(scdf, i, block->successors[0]); } else { zend_op *opline = NULL; - int j, end = block->start + block->len; + uint32_t j, end = block->start + block->len; for (j = block->start; j < end; j++) { opline = &scdf->op_array->opcodes[j]; zend_bitset_excl(scdf->instr_worklist, j); @@ -185,7 +179,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) { * not eliminate the latter. While it cannot be reached, the FREE opcode of the loop var * is necessary for the correctness of temporary compaction. */ static bool is_live_loop_var_free( - scdf_ctx *scdf, const zend_op *opline, const zend_ssa_op *ssa_op) { + const scdf_ctx *scdf, const zend_op *opline, const zend_ssa_op *ssa_op) { if (!zend_optimizer_is_loop_var_free(opline)) { return false; } @@ -195,7 +189,7 @@ static bool is_live_loop_var_free( return false; } - zend_ssa_var *ssa_var = &scdf->ssa->vars[var]; + const zend_ssa_var *ssa_var = &scdf->ssa->vars[var]; uint32_t def_block; if (ssa_var->definition >= 0) { def_block = scdf->ssa->cfg.map[ssa_var->definition]; @@ -205,7 +199,7 @@ static bool is_live_loop_var_free( return zend_bitset_in(scdf->executable_blocks, def_block); } -static bool kept_alive_by_loop_var_free(scdf_ctx *scdf, const zend_basic_block *block) { +static bool kept_alive_by_loop_var_free(const scdf_ctx *scdf, const zend_basic_block *block) { const zend_op_array *op_array = scdf->op_array; const zend_cfg *cfg = &scdf->ssa->cfg; if (!(cfg->flags & ZEND_FUNC_FREE_LOOP_VAR)) { @@ -220,7 +214,7 @@ static bool kept_alive_by_loop_var_free(scdf_ctx *scdf, const zend_basic_block * return false; } -static uint32_t cleanup_loop_var_free_block(scdf_ctx *scdf, zend_basic_block *block) { +static uint32_t cleanup_loop_var_free_block(const scdf_ctx *scdf, const zend_basic_block *block) { zend_ssa *ssa = scdf->ssa; const zend_op_array *op_array = scdf->op_array; const zend_cfg *cfg = &ssa->cfg; @@ -256,12 +250,11 @@ static uint32_t cleanup_loop_var_free_block(scdf_ctx *scdf, zend_basic_block *bl /* Removes unreachable blocks. This will remove both the instructions (and phis) in the * blocks, as well as remove them from the successor / predecessor lists and mark them * unreachable. Blocks already marked unreachable are not removed. */ -uint32_t scdf_remove_unreachable_blocks(scdf_ctx *scdf) { +uint32_t scdf_remove_unreachable_blocks(const scdf_ctx *scdf) { zend_ssa *ssa = scdf->ssa; - int i; uint32_t removed_ops = 0; - for (i = 0; i < ssa->cfg.blocks_count; i++) { - zend_basic_block *block = &ssa->cfg.blocks[i]; + for (uint32_t i = 0; i < ssa->cfg.blocks_count; i++) { + const zend_basic_block *block = &ssa->cfg.blocks[i]; if (!zend_bitset_in(scdf->executable_blocks, i) && (block->flags & ZEND_BB_REACHABLE)) { if (!kept_alive_by_loop_var_free(scdf, block)) { removed_ops += block->len; diff --git a/Zend/Optimizer/scdf.h b/Zend/Optimizer/scdf.h index 0d90147e84cb..d7bee4b73816 100644 --- a/Zend/Optimizer/scdf.h +++ b/Zend/Optimizer/scdf.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Call Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ @@ -39,7 +37,7 @@ typedef struct _scdf_ctx { void (*visit_instr)( struct _scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_op); void (*visit_phi)( - struct _scdf_ctx *scdf, zend_ssa_phi *phi); + struct _scdf_ctx *scdf, const zend_ssa_phi *phi); void (*mark_feasible_successors)( struct _scdf_ctx *scdf, int block_num, zend_basic_block *block, zend_op *opline, zend_ssa_op *ssa_op); @@ -49,10 +47,10 @@ typedef struct _scdf_ctx { void scdf_init(zend_optimizer_ctx *ctx, scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa); void scdf_solve(scdf_ctx *scdf, const char *name); -uint32_t scdf_remove_unreachable_blocks(scdf_ctx *scdf); +uint32_t scdf_remove_unreachable_blocks(const scdf_ctx *scdf); /* Add uses to worklist */ -static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) { +static inline void scdf_add_to_worklist(const scdf_ctx *scdf, int var_num) { const zend_ssa *ssa = scdf->ssa; const zend_ssa_var *var = &ssa->vars[var_num]; int use; @@ -66,7 +64,7 @@ static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) { } /* This should usually not be necessary, however it's used for type narrowing. */ -static inline void scdf_add_def_to_worklist(scdf_ctx *scdf, int var_num) { +static inline void scdf_add_def_to_worklist(const scdf_ctx *scdf, int var_num) { const zend_ssa_var *var = &scdf->ssa->vars[var_num]; if (var->definition >= 0) { zend_bitset_incl(scdf->instr_worklist, var->definition); @@ -75,11 +73,10 @@ static inline void scdf_add_def_to_worklist(scdf_ctx *scdf, int var_num) { } } -static inline uint32_t scdf_edge(const zend_cfg *cfg, int from, int to) { +static inline uint32_t scdf_edge(const zend_cfg *cfg, int from, uint32_t to) { const zend_basic_block *to_block = cfg->blocks + to; - int i; - for (i = 0; i < to_block->predecessors_count; i++) { + for (uint32_t i = 0; i < to_block->predecessors_count; i++) { uint32_t edge = to_block->predecessor_offset + i; if (cfg->predecessors[edge] == from) { @@ -89,7 +86,7 @@ static inline uint32_t scdf_edge(const zend_cfg *cfg, int from, int to) { ZEND_UNREACHABLE(); } -static inline bool scdf_is_edge_feasible(const scdf_ctx *scdf, int from, int to) { +static inline bool scdf_is_edge_feasible(const scdf_ctx *scdf, int from, uint32_t to) { uint32_t edge = scdf_edge(&scdf->ssa->cfg, from, to); return zend_bitset_in(scdf->feasible_edges, edge); } diff --git a/Zend/Optimizer/ssa_integrity.c b/Zend/Optimizer/ssa_integrity.c index b525f8d5ee22..34a2b3a9ef64 100644 --- a/Zend/Optimizer/ssa_integrity.c +++ b/Zend/Optimizer/ssa_integrity.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SSA validation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | +----------------------------------------------------------------------+ @@ -25,20 +23,20 @@ static inline bool is_in_use_chain(zend_ssa *ssa, int var, int check) { int use; FOREACH_USE(&ssa->vars[var], use) { if (use == check) { - return 1; + return true; } } FOREACH_USE_END(); - return 0; + return false; } static inline bool is_in_phi_use_chain(zend_ssa *ssa, int var, zend_ssa_phi *check) { zend_ssa_phi *phi; FOREACH_PHI_USE(&ssa->vars[var], phi) { if (phi == check) { - return 1; + return true; } } FOREACH_PHI_USE_END(); - return 0; + return false; } static inline bool is_used_by_op(zend_ssa *ssa, int op, int check) { @@ -59,30 +57,29 @@ static inline bool is_in_phi_sources(zend_ssa *ssa, zend_ssa_phi *phi, int check int source; FOREACH_PHI_SOURCE(phi, source) { if (source == check) { - return 1; + return true; } } FOREACH_PHI_SOURCE_END(); - return 0; + return false; } static inline bool is_in_predecessors(zend_cfg *cfg, zend_basic_block *block, int check) { - int i, *predecessors = &cfg->predecessors[block->predecessor_offset]; - for (i = 0; i < block->predecessors_count; i++) { + int *predecessors = &cfg->predecessors[block->predecessor_offset]; + for (uint32_t i = 0; i < block->predecessors_count; i++) { if (predecessors[i] == check) { - return 1; + return true; } } - return 0; + return false; } static inline bool is_in_successors(zend_basic_block *block, int check) { - int s; - for (s = 0; s < block->successors_count; s++) { + for (uint32_t s = 0; s < block->successors_count; s++) { if (block->successors[s] == check) { - return 1; + return true; } } - return 0; + return false; } static inline bool is_var_type(uint8_t type) { @@ -329,7 +326,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex /* Phis */ FOREACH_PHI(phi) { - unsigned num_sources = NUM_PHI_SOURCES(phi); + uint32_t num_sources = NUM_PHI_SOURCES(phi); for (i = 0; i < num_sources; i++) { int source = phi->sources[i]; if (source < 0) { @@ -360,7 +357,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex for (i = 0; i < cfg->blocks_count; i++) { zend_basic_block *block = &cfg->blocks[i]; int *predecessors = &cfg->predecessors[block->predecessor_offset]; - int s, j; + uint32_t j; if (i != 0 && block->start < (block-1)->start + (block-1)->len) { FAIL("Block %d start %d smaller previous end %d\n", @@ -384,7 +381,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex continue; } - for (s = 0; s < block->successors_count; s++) { + for (uint32_t s = 0; s < block->successors_count; s++) { zend_basic_block *next_block; if (block->successors[s] < 0) { FAIL("Successor number %d of %d negative", s, i); @@ -400,7 +397,6 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex for (j = 0; j < block->predecessors_count; j++) { if (predecessors[j] >= 0) { - int k; zend_basic_block *prev_block = &cfg->blocks[predecessors[j]]; if (!(prev_block->flags & ZEND_BB_REACHABLE)) { FAIL("Predecessor %d of %d not reachable\n", predecessors[j], i); @@ -408,7 +404,7 @@ void ssa_verify_integrity(zend_op_array *op_array, zend_ssa *ssa, const char *ex if (!is_in_successors(prev_block, i)) { FAIL("Block %d successors missing %d\n", predecessors[j], i); } - for (k = 0; k < block->predecessors_count; k++) { + for (uint32_t k = 0; k < block->predecessors_count; k++) { if (k != j && predecessors[k] == predecessors[j]) { FAIL("Block %d has duplicate predecessor %d\n", i, predecessors[j]); } diff --git a/Zend/Optimizer/zend_call_graph.c b/Zend/Optimizer/zend_call_graph.c index 8a2f8ea2a7e1..bb80e21a2465 100644 --- a/Zend/Optimizer/zend_call_graph.c +++ b/Zend/Optimizer/zend_call_graph.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Call Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -23,8 +21,6 @@ #include "zend_inference.h" #include "zend_call_graph.h" #include "zend_func_info.h" -#include "zend_inference.h" -#include "zend_call_graph.h" static void zend_op_array_calc(zend_op_array *op_array, void *context) { @@ -146,7 +142,7 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 case ZEND_SEND_USER: if (call_info) { if (opline->op2_type == IS_CONST) { - call_info->named_args = 1; + call_info->named_args = true; break; } @@ -160,7 +156,7 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 case ZEND_SEND_ARRAY: case ZEND_SEND_UNPACK: if (call_info) { - call_info->send_unpack = 1; + call_info->send_unpack = true; } break; } @@ -169,26 +165,26 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32 free_alloca(call_stack, use_heap); } -static bool zend_is_indirectly_recursive(zend_op_array *root, zend_op_array *op_array, zend_bitset visited) +static bool zend_is_indirectly_recursive(const zend_op_array *root, const zend_op_array *op_array, zend_bitset visited) { - zend_func_info *func_info; + const zend_func_info *func_info; zend_call_info *call_info; - bool ret = 0; + bool ret = false; if (op_array == root) { - return 1; + return true; } func_info = ZEND_FUNC_INFO(op_array); if (zend_bitset_in(visited, func_info->num)) { - return 0; + return false; } zend_bitset_incl(visited, func_info->num); call_info = func_info->caller_info; while (call_info) { if (zend_is_indirectly_recursive(root, call_info->caller_op_array, visited)) { - call_info->recursive = 1; - ret = 1; + call_info->recursive = true; + ret = true; } call_info = call_info->next_caller; } @@ -197,16 +193,15 @@ static bool zend_is_indirectly_recursive(zend_op_array *root, zend_op_array *op_ static void zend_analyze_recursion(zend_call_graph *call_graph) { - zend_op_array *op_array; + const zend_op_array *op_array; zend_func_info *func_info; zend_call_info *call_info; - int i; - int set_len = zend_bitset_len(call_graph->op_arrays_count); + uint32_t set_len = zend_bitset_len(call_graph->op_arrays_count); zend_bitset visited; ALLOCA_FLAG(use_heap); visited = ZEND_BITSET_ALLOCA(set_len, use_heap); - for (i = 0; i < call_graph->op_arrays_count; i++) { + for (uint32_t i = 0; i < call_graph->op_arrays_count; i++) { op_array = call_graph->op_arrays[i]; func_info = call_graph->func_infos + i; call_info = func_info->caller_info; @@ -216,12 +211,12 @@ static void zend_analyze_recursion(zend_call_graph *call_graph) continue; } if (call_info->caller_op_array == op_array) { - call_info->recursive = 1; + call_info->recursive = true; func_info->flags |= ZEND_FUNC_RECURSIVE | ZEND_FUNC_RECURSIVE_DIRECTLY; } else { memset(visited, 0, sizeof(zend_ulong) * set_len); if (zend_is_indirectly_recursive(op_array, call_info->caller_op_array, visited)) { - call_info->recursive = 1; + call_info->recursive = true; func_info->flags |= ZEND_FUNC_RECURSIVE | ZEND_FUNC_RECURSIVE_INDIRECTLY; } } @@ -252,9 +247,7 @@ ZEND_API void zend_build_call_graph(zend_arena **arena, zend_script *script, zen ZEND_API void zend_analyze_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph) /* {{{ */ { - int i; - - for (i = 0; i < call_graph->op_arrays_count; i++) { + for (uint32_t i = 0; i < call_graph->op_arrays_count; i++) { zend_analyze_calls(arena, script, 0, call_graph->op_arrays[i], call_graph->func_infos + i); } zend_analyze_recursion(call_graph); @@ -262,7 +255,7 @@ ZEND_API void zend_analyze_call_graph(zend_arena **arena, zend_script *script, z } /* }}} */ -ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info *info, const zend_op_array *op_array) /* {{{ */ +ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, const zend_func_info *info, const zend_op_array *op_array) /* {{{ */ { zend_call_info **map, *call; if (!info->callee_info) { @@ -272,13 +265,12 @@ ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info map = zend_arena_calloc(arena, sizeof(zend_call_info *), op_array->last); for (call = info->callee_info; call; call = call->next_callee) { - int i; map[call->caller_init_opline - op_array->opcodes] = call; 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++) { + for (uint32_t i = 0; i < call->num_args; i++) { if (call->arg_info[i].opline) { map[call->arg_info[i].opline - op_array->opcodes] = call; } diff --git a/Zend/Optimizer/zend_call_graph.h b/Zend/Optimizer/zend_call_graph.h index b2cbb6822bcf..57c6bdffe998 100644 --- a/Zend/Optimizer/zend_call_graph.h +++ b/Zend/Optimizer/zend_call_graph.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Call Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -39,12 +37,12 @@ struct _zend_call_info { 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 */ + uint32_t num_args; /* Number of arguments, excluding named and variadic arguments */ zend_send_arg_info arg_info[1]; }; struct _zend_func_info { - int num; + uint32_t num; uint32_t flags; zend_ssa ssa; /* Static Single Assignment Form */ zend_call_info *caller_info; /* where this function is called from */ @@ -54,7 +52,7 @@ struct _zend_func_info { }; typedef struct _zend_call_graph { - int op_arrays_count; + uint32_t op_arrays_count; zend_op_array **op_arrays; zend_func_info *func_infos; } zend_call_graph; @@ -63,7 +61,7 @@ BEGIN_EXTERN_C() ZEND_API void zend_build_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph); ZEND_API void zend_analyze_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph); -ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info *info, const zend_op_array *op_array); +ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, const zend_func_info *info, const zend_op_array *op_array); ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_op_array *op_array, zend_func_info *func_info); END_EXTERN_C() diff --git a/Zend/Optimizer/zend_cfg.c b/Zend/Optimizer/zend_cfg.c index a0d08b67aa70..837515169d70 100644 --- a/Zend/Optimizer/zend_cfg.c +++ b/Zend/Optimizer/zend_cfg.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, CFG - Control Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -35,7 +33,6 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc zend_worklist_push(&work, b - cfg->blocks); while (zend_worklist_len(&work)) { - int i; b = cfg->blocks + zend_worklist_pop(&work); b->flags |= ZEND_BB_REACHABLE; @@ -44,7 +41,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc continue; } - for (i = 0; i < b->successors_count; i++) { + for (uint32_t i = 0; i < b->successors_count; i++) { zend_basic_block *succ = blocks + b->successors[i]; if (b->len != 0) { @@ -104,7 +101,7 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc } /* }}} */ -static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg, int start) /* {{{ */ +static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg, uint32_t start) /* {{{ */ { zend_basic_block *blocks = cfg->blocks; @@ -113,14 +110,14 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * if (op_array->last_try_catch) { zend_basic_block *b; - int j, changed; + int changed; uint32_t *block_map = cfg->map; do { changed = 0; /* Add exception paths */ - for (j = 0; j < op_array->last_try_catch; j++) { + for (uint32_t j = 0; j < op_array->last_try_catch; j++) { /* check for jumps into the middle of try block */ b = blocks + block_map[op_array->try_catch_array[j].try_op]; @@ -202,7 +199,6 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * if (cfg->flags & ZEND_FUNC_FREE_LOOP_VAR) { zend_basic_block *b; - int j; uint32_t *block_map = cfg->map; /* Mark blocks that are unreachable, but free a loop var created in a reachable block. */ @@ -211,7 +207,7 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * continue; } - for (j = b->start; j < b->start + b->len; j++) { + for (uint32_t j = b->start; j < b->start + b->len; j++) { zend_op *opline = &op_array->opcodes[j]; if (zend_optimizer_is_loop_var_free(opline)) { zend_op *def_opline = zend_optimizer_get_loop_var_def(op_array, opline); @@ -232,8 +228,8 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg * void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { zend_basic_block *blocks = cfg->blocks; - int i; - int start = 0; + uint32_t i; + uint32_t start = 0; for (i = 0; i < cfg->blocks_count; i++) { if (blocks[i].flags & ZEND_BB_REACHABLE) { @@ -274,13 +270,12 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, { uint32_t flags = 0; uint32_t i; - int j; uint32_t *block_map; zend_function *fn; int blocks_count = 0; zend_basic_block *blocks; zval *zv; - bool extra_entry_block = 0; + bool extra_entry_block = false; cfg->flags = build_flags & (ZEND_CFG_STACKLESS|ZEND_CFG_RECV_ENTRY); @@ -445,11 +440,11 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, /* If the entry block has predecessors, we may need to split it */ if ((build_flags & ZEND_CFG_NO_ENTRY_PREDECESSORS) && op_array->last > 0 && block_map[0] > 1) { - extra_entry_block = 1; + extra_entry_block = true; } if (op_array->last_try_catch) { - for (j = 0; j < op_array->last_try_catch; j++) { + for (uint32_t j = 0; j < op_array->last_try_catch; j++) { BB_START(op_array->try_catch_array[j].try_op); if (op_array->try_catch_array[j].catch_op) { BB_START(op_array->try_catch_array[j].catch_op); @@ -494,7 +489,7 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, blocks_count++; /* Build CFG, Step 3: Calculate successors */ - for (j = 0; j < blocks_count; j++) { + for (int j = 0; j < blocks_count; j++) { zend_basic_block *block = &blocks[j]; zend_op *opline; if (block->len == 0) { @@ -594,13 +589,12 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* {{{ */ { - int j, s, edges; zend_basic_block *b; zend_basic_block *blocks = cfg->blocks; zend_basic_block *end = blocks + cfg->blocks_count; + uint32_t edges = 0; int *predecessors; - edges = 0; for (b = blocks; b < end; b++) { b->predecessors_count = 0; } @@ -609,7 +603,7 @@ ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* b->successors_count = 0; b->predecessors_count = 0; } else { - for (s = 0; s < b->successors_count; s++) { + for (uint32_t s = 0; s < b->successors_count; s++) { edges++; blocks[b->successors[s]].predecessors_count++; } @@ -628,14 +622,13 @@ ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* } } - for (j = 0; j < cfg->blocks_count; j++) { + for (uint32_t j = 0; j < cfg->blocks_count; j++) { if (blocks[j].flags & ZEND_BB_REACHABLE) { /* SWITCH_STRING/LONG may have few identical successors */ - for (s = 0; s < blocks[j].successors_count; s++) { + for (uint32_t s = 0; s < blocks[j].successors_count; s++) { int duplicate = 0; - int p; - for (p = 0; p < s; p++) { + for (uint32_t p = 0; p < s; p++) { if (blocks[j].successors[p] == blocks[j].successors[s]) { duplicate = 1; break; @@ -655,16 +648,15 @@ ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* /* Computes a postorder numbering of the CFG */ static void compute_postnum_recursive( - int *postnum, int *cur, const zend_cfg *cfg, int block_num) /* {{{ */ + int *postnum, uint32_t *cur, const zend_cfg *cfg, int block_num) /* {{{ */ { - int s; zend_basic_block *block = &cfg->blocks[block_num]; if (postnum[block_num] != -1) { return; } postnum[block_num] = -2; /* Marker for "currently visiting" */ - for (s = 0; s < block->successors_count; s++) { + for (uint32_t s = 0; s < block->successors_count; s++) { compute_postnum_recursive(postnum, cur, cfg, block->successors[s]); } postnum[block_num] = (*cur)++; @@ -676,8 +668,9 @@ static void compute_postnum_recursive( ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { zend_basic_block *blocks = cfg->blocks; - int blocks_count = cfg->blocks_count; - int j, k, changed; + uint32_t blocks_count = cfg->blocks_count; + uint32_t j; + int changed; if (cfg->blocks_count == 1) { blocks[0].level = 0; @@ -701,7 +694,7 @@ ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, ze if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) { continue; } - for (k = 0; k < blocks[j].predecessors_count; k++) { + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { int pred = cfg->predecessors[blocks[j].predecessor_offset + k]; if (blocks[pred].idom >= 0) { @@ -777,7 +770,7 @@ static bool dominates(zend_basic_block *blocks, int a, int b) /* {{{ */ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */ { - int i, j, k, n; + int i, j, n; int time; zend_basic_block *blocks = cfg->blocks; int *entry_times, *exit_times; @@ -891,7 +884,7 @@ ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *c continue; } blocks[j].loop_header = i; - for (k = 0; k < blocks[j].predecessors_count; k++) { + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { zend_worklist_push(&work, cfg->predecessors[blocks[j].predecessor_offset + k]); } } diff --git a/Zend/Optimizer/zend_cfg.h b/Zend/Optimizer/zend_cfg.h index 93d455060686..3ed635ecdedc 100644 --- a/Zend/Optimizer/zend_cfg.h +++ b/Zend/Optimizer/zend_cfg.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, CFG - Control Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -44,14 +42,14 @@ typedef struct _zend_basic_block { uint32_t flags; uint32_t start; /* first opcode number */ uint32_t len; /* number of opcodes */ - int successors_count; /* number of successors */ - int predecessors_count; /* number of predecessors */ - int predecessor_offset; /* offset of 1-st predecessor */ - int idom; /* immediate dominator block */ + uint32_t successors_count; /* number of successors */ + uint32_t predecessors_count; /* number of predecessors */ + int predecessor_offset; /* offset of 1-st predecessor, or -1 */ + int idom; /* immediate dominator block, or -1 */ int loop_header; /* closest loop header, or -1 */ - int level; /* steps away from the entry in the dom. tree */ - int children; /* list of dominated blocks */ - int next_child; /* next dominated block */ + int level; /* steps away from the entry in the dom. tree, or -1 */ + int children; /* list of dominated blocks, or -1 */ + int next_child; /* next dominated block, or -1 */ int successors_storage[2]; /* up to 2 successor blocks */ } zend_basic_block; @@ -82,8 +80,8 @@ typedef struct _zend_basic_block { */ typedef struct _zend_cfg { - int blocks_count; /* number of basic blocks */ - int edges_count; /* number of edges */ + uint32_t blocks_count; /* number of basic blocks */ + uint32_t edges_count; /* number of edges */ zend_basic_block *blocks; /* array of basic blocks */ int *predecessors; uint32_t *map; diff --git a/Zend/Optimizer/zend_dfg.c b/Zend/Optimizer/zend_dfg.c index 101523141be9..72e15693a844 100644 --- a/Zend/Optimizer/zend_dfg.c +++ b/Zend/Optimizer/zend_dfg.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, DFG - Data Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -19,7 +17,7 @@ #include "zend_compile.h" #include "zend_dfg.h" -static zend_always_inline void _zend_dfg_add_use_def_op(const zend_op_array *op_array, const zend_op *opline, uint32_t build_flags, zend_bitset use, zend_bitset def) /* {{{ */ +static zend_always_inline void zend_dfg_add_use_def_op_impl(const zend_op_array *op_array, const zend_op *opline, uint32_t build_flags, zend_bitset use, zend_bitset def) /* {{{ */ { uint32_t var_num; const zend_op *next; @@ -245,20 +243,18 @@ static zend_always_inline void _zend_dfg_add_use_def_op(const zend_op_array *op_ ZEND_API void zend_dfg_add_use_def_op(const zend_op_array *op_array, const zend_op *opline, uint32_t build_flags, zend_bitset use, zend_bitset def) /* {{{ */ { - _zend_dfg_add_use_def_op(op_array, opline, build_flags, use, def); + zend_dfg_add_use_def_op_impl(op_array, opline, build_flags, use, def); } /* }}} */ -void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg, uint32_t build_flags) /* {{{ */ +void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg, uint32_t build_flags) /* {{{ */ { - int set_size; + uint32_t set_size = dfg->size; zend_basic_block *blocks = cfg->blocks; - int blocks_count = cfg->blocks_count; + uint32_t blocks_count = cfg->blocks_count; zend_bitset tmp, def, use, in, out; - int k; - int j; + uint32_t j; - set_size = dfg->size; tmp = dfg->tmp; def = dfg->def; use = dfg->use; @@ -267,7 +263,7 @@ void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg /* Collect "def" and "use" sets */ for (j = 0; j < blocks_count; j++) { - zend_op *opline, *end; + const zend_op *opline, *end; zend_bitset b_use, b_def; if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) { @@ -280,7 +276,7 @@ void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg b_def = DFG_BITSET(def, set_size, j); for (; opline < end; opline++) { if (opline->opcode != ZEND_OP_DATA) { - _zend_dfg_add_use_def_op(op_array, opline, build_flags, b_use, b_def); + zend_dfg_add_use_def_op_impl(op_array, opline, build_flags, b_use, b_def); } } } @@ -306,7 +302,7 @@ void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg } if (blocks[j].successors_count != 0) { zend_bitset_copy(DFG_BITSET(out, set_size, j), DFG_BITSET(in, set_size, blocks[j].successors[0]), set_size); - for (k = 1; k < blocks[j].successors_count; k++) { + for (uint32_t k = 1; k < blocks[j].successors_count; k++) { zend_bitset_union(DFG_BITSET(out, set_size, j), DFG_BITSET(in, set_size, blocks[j].successors[k]), set_size); } } else { @@ -318,8 +314,8 @@ void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg /* Add predecessors of changed block to worklist */ { - int *predecessors = &cfg->predecessors[blocks[j].predecessor_offset]; - for (k = 0; k < blocks[j].predecessors_count; k++) { + const int *predecessors = &cfg->predecessors[blocks[j].predecessor_offset]; + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { zend_bitset_incl(worklist, predecessors[k]); } } diff --git a/Zend/Optimizer/zend_dfg.h b/Zend/Optimizer/zend_dfg.h index b59dc6279090..464ea6bb2ebe 100644 --- a/Zend/Optimizer/zend_dfg.h +++ b/Zend/Optimizer/zend_dfg.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, DFG - Data Flow Graph | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -43,7 +41,7 @@ typedef struct _zend_dfg { BEGIN_EXTERN_C() -void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg, uint32_t build_flags); +void zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg, uint32_t build_flags); ZEND_API void zend_dfg_add_use_def_op(const zend_op_array *op_array, const zend_op *opline, uint32_t build_flags, zend_bitset use, zend_bitset def); END_EXTERN_C() diff --git a/Zend/Optimizer/zend_dump.c b/Zend/Optimizer/zend_dump.c index 4e46b38a8eb5..c6cc5193b2dc 100644 --- a/Zend/Optimizer/zend_dump.c +++ b/Zend/Optimizer/zend_dump.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Bytecode Visualisation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -25,16 +23,16 @@ #include "zend_dump.h" #include "zend_smart_str.h" -void zend_dump_ht(HashTable *ht) +void zend_dump_ht(const HashTable *ht) { zend_ulong index; zend_string *key; zval *val; - bool first = 1; + bool first = true; ZEND_HASH_FOREACH_KEY_VAL(ht, index, key, val) { if (first) { - first = 0; + first = false; } else { fprintf(stderr, ", "); } @@ -136,6 +134,10 @@ static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t fla if (op.num != (uint32_t)-1) { fprintf(stderr, " try-catch(%u)", op.num); } + } else if (ZEND_VM_OP_LOOP_END == (flags & ZEND_VM_OP_MASK)) { + if (opline->extended_value & ZEND_FREE_ON_RETURN) { + fprintf(stderr, " loop-end(+%u)", op.num); + } } else if (ZEND_VM_OP_THIS == (flags & ZEND_VM_OP_MASK)) { fprintf(stderr, " THIS"); } else if (ZEND_VM_OP_NEXT == (flags & ZEND_VM_OP_MASK)) { @@ -186,38 +188,38 @@ static void zend_dump_range(const zend_ssa_range *r) } } -static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_instanceof, uint32_t dump_flags) +static void zend_dump_type_info(uint32_t info, const zend_class_entry *ce, bool is_instanceof, uint32_t dump_flags) { - bool first = 1; + bool first = true; fprintf(stderr, " ["); if (info & MAY_BE_GUARD) { fprintf(stderr, "!"); } if (info & MAY_BE_UNDEF) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "undef"); } if (info & MAY_BE_INDIRECT) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "ind"); } if (info & MAY_BE_REF) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "ref"); } if (dump_flags & ZEND_DUMP_RC_INFERENCE) { if (info & MAY_BE_RC1) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "rc1"); } if (info & MAY_BE_RCN) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "rcn"); } } if (info & MAY_BE_CLASS) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "class"); if (ce) { if (is_instanceof) { @@ -227,37 +229,37 @@ static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_inst } } } else if ((info & MAY_BE_ANY) == MAY_BE_ANY) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "any"); } else { if (info & MAY_BE_NULL) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "null"); } if ((info & MAY_BE_FALSE) && (info & MAY_BE_TRUE)) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "bool"); } else if (info & MAY_BE_FALSE) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "false"); } else if (info & MAY_BE_TRUE) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "true"); } if (info & MAY_BE_LONG) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "long"); } if (info & MAY_BE_DOUBLE) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "double"); } if (info & MAY_BE_STRING) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "string"); } if (info & MAY_BE_ARRAY) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); if (info & MAY_BE_PACKED_GUARD) { fprintf(stderr, "!"); } @@ -268,18 +270,18 @@ static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_inst } else if (MAY_BE_HASH_ONLY(info)) { fprintf(stderr, "hash "); } else if ((info & MAY_BE_ARRAY_KEY_ANY) != MAY_BE_ARRAY_KEY_ANY && (info & MAY_BE_ARRAY_KEY_ANY) != 0) { - bool afirst = 1; + bool afirst = true; fprintf(stderr, "["); if (info & MAY_BE_ARRAY_EMPTY) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "empty"); } if (MAY_BE_PACKED(info)) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "packed"); } if (MAY_BE_HASH(info)) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "hash"); } fprintf(stderr, "] "); @@ -288,71 +290,71 @@ static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_inst if ((info & (MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING)) != 0 && ((info & MAY_BE_ARRAY_KEY_LONG) == 0 || (info & MAY_BE_ARRAY_KEY_STRING) == 0)) { - bool afirst = 1; + bool afirst = true; fprintf(stderr, " ["); if (info & MAY_BE_ARRAY_KEY_LONG) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "long"); } if (info & MAY_BE_ARRAY_KEY_STRING) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "string"); } fprintf(stderr, "]"); } if (info & (MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF)) { - bool afirst = 1; + bool afirst = true; fprintf(stderr, " of ["); if ((info & MAY_BE_ARRAY_OF_ANY) == MAY_BE_ARRAY_OF_ANY) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "any"); } else { if (info & MAY_BE_ARRAY_OF_NULL) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "null"); } if (info & MAY_BE_ARRAY_OF_FALSE) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "false"); } if (info & MAY_BE_ARRAY_OF_TRUE) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "true"); } if (info & MAY_BE_ARRAY_OF_LONG) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "long"); } if (info & MAY_BE_ARRAY_OF_DOUBLE) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "double"); } if (info & MAY_BE_ARRAY_OF_STRING) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "string"); } if (info & MAY_BE_ARRAY_OF_ARRAY) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "array"); } if (info & MAY_BE_ARRAY_OF_OBJECT) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "object"); } if (info & MAY_BE_ARRAY_OF_RESOURCE) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "resource"); } } if (info & MAY_BE_ARRAY_OF_REF) { - if (afirst) afirst = 0; else fprintf(stderr, ", "); + if (afirst) afirst = false; else fprintf(stderr, ", "); fprintf(stderr, "ref"); } fprintf(stderr, "]"); } } if (info & MAY_BE_OBJECT) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "object"); if (ce) { if (is_instanceof) { @@ -363,7 +365,7 @@ static void zend_dump_type_info(uint32_t info, zend_class_entry *ce, int is_inst } } if (info & MAY_BE_RESOURCE) { - if (first) first = 0; else fprintf(stderr, ", "); + if (first) first = false; else fprintf(stderr, ", "); fprintf(stderr, "resource"); } } @@ -478,7 +480,7 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block } if (ZEND_OP_IS_FRAMELESS_ICALL(opline->opcode)) { - zend_function *func = ZEND_FLF_FUNC(opline); + const zend_function *func = ZEND_FLF_FUNC(opline); fprintf(stderr, "(%s)", ZSTR_VAL(func->common.function_name)); } @@ -670,13 +672,13 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block } if (opline->op2_type == IS_CONST) { - zval *op = CRT_CONSTANT(opline->op2); + const zval *op = CRT_CONSTANT(opline->op2); if ( opline->opcode == ZEND_SWITCH_LONG || opline->opcode == ZEND_SWITCH_STRING || opline->opcode == ZEND_MATCH ) { - HashTable *jumptable = Z_ARRVAL_P(op); + const HashTable *jumptable = Z_ARRVAL_P(op); zend_string *key; zend_ulong num_key; zval *zv; @@ -774,7 +776,7 @@ ZEND_API void zend_dump_op_line(const zend_op_array *op_array, const zend_basic_ { int len = 0; const zend_ssa *ssa = NULL; - zend_ssa_op *ssa_op = NULL; + const zend_ssa_op *ssa_op = NULL; if (dump_flags & ZEND_DUMP_LINE_NUMBERS) { fprintf(stderr, "L%04u ", opline->lineno); @@ -796,7 +798,7 @@ ZEND_API void zend_dump_op_line(const zend_op_array *op_array, const zend_basic_ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags) { - zend_basic_block *b = cfg->blocks + n; + const zend_basic_block *b = cfg->blocks + n; if (n > 0) { fprintf(stderr, "\n"); @@ -852,8 +854,8 @@ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags fprintf(stderr, "\n"); if (b->predecessors_count) { - int *p = cfg->predecessors + b->predecessor_offset; - int *end = p + b->predecessors_count; + const int *p = cfg->predecessors + b->predecessor_offset; + const int *end = p + b->predecessors_count; fprintf(stderr, " ; from=(BB%d", *p); for (p++; p < end; p++) { @@ -863,9 +865,8 @@ static void zend_dump_block_info(const zend_cfg *cfg, int n, uint32_t dump_flags } if (b->successors_count > 0) { - int s; fprintf(stderr, " ; to=(BB%d", b->successors[0]); - for (s = 1; s < b->successors_count; s++) { + for (uint32_t s = 1; s < b->successors_count; s++) { fprintf(stderr, ", BB%d", b->successors[s]); } fprintf(stderr, ")\n"); @@ -896,16 +897,14 @@ static void zend_dump_block_header(const zend_cfg *cfg, const zend_op_array *op_ { zend_dump_block_info(cfg, n, dump_flags); if (ssa && ssa->blocks && ssa->blocks[n].phis) { - zend_ssa_phi *p = ssa->blocks[n].phis; + const zend_ssa_phi *p = ssa->blocks[n].phis; do { - int j; - fprintf(stderr, " "); zend_dump_ssa_var(op_array, ssa, p->ssa_var, 0, p->var, dump_flags); if (p->pi < 0) { fprintf(stderr, " = Phi("); - for (j = 0; j < cfg->blocks[n].predecessors_count; j++) { + for (uint32_t j = 0; j < cfg->blocks[n].predecessors_count; j++) { if (j > 0) { fprintf(stderr, ", "); } @@ -945,7 +944,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl { const zend_cfg *cfg = NULL; const zend_ssa *ssa = NULL; - zend_func_info *func_info = NULL; + const zend_func_info *func_info = NULL; uint32_t func_flags = 0; if (dump_flags & (ZEND_DUMP_CFG|ZEND_DUMP_SSA)) { @@ -1036,11 +1035,8 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl } if (cfg) { - int n; - zend_basic_block *b; - - for (n = 0; n < cfg->blocks_count; n++) { - b = cfg->blocks + n; + for (uint32_t n = 0; n < cfg->blocks_count; n++) { + const zend_basic_block *b = cfg->blocks + n; if (!(dump_flags & ZEND_DUMP_HIDE_UNREACHABLE) || (b->flags & ZEND_BB_REACHABLE)) { const zend_op *opline; const zend_op *end; @@ -1056,7 +1052,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 (uint32_t 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 +1079,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 (uint32_t 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 +1112,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 (uint32_t 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 +1139,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 (uint32_t i = 0; i < op_array->last_try_catch; i++) { fprintf(stderr, " %04u", op_array->try_catch_array[i].try_op); @@ -1164,7 +1160,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl } if (op_array->try_catch_array[i].finally_end) { fprintf(stderr, - ", %04u", + ", %04u\n", op_array->try_catch_array[i].finally_end); } else { fprintf(stderr, ", -\n"); @@ -1176,13 +1172,11 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg) { - int j; - fprintf(stderr, "\nDOMINATORS-TREE for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < cfg->blocks_count; j++) { - zend_basic_block *b = cfg->blocks + j; + for (uint32_t j = 0; j < cfg->blocks_count; j++) { + const zend_basic_block *b = cfg->blocks + j; if (b->flags & ZEND_BB_REACHABLE) { zend_dump_block_info(cfg, j, 0); } @@ -1191,14 +1185,12 @@ void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg) void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags) { - int j; - if (ssa->vars) { fprintf(stderr, "\nSSA Variable for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < ssa->vars_count; j++) { + for (int j = 0; j < ssa->vars_count; j++) { fprintf(stderr, " "); zend_dump_ssa_var(op_array, ssa, j, IS_CV, ssa->vars[j].var, dump_flags); if (ssa->vars[j].scc >= 0) { @@ -1216,14 +1208,13 @@ void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, static void zend_dump_var_set(const zend_op_array *op_array, const char *name, zend_bitset set) { - bool first = 1; - uint32_t i; + bool first = true; fprintf(stderr, " ; %s = {", name); - for (i = 0; i < op_array->last_var + op_array->T; i++) { + for (uint32_t i = 0; i < op_array->last_var + op_array->T; i++) { if (zend_bitset_in(set, i)) { if (first) { - first = 0; + first = false; } else { fprintf(stderr, ", "); } @@ -1235,12 +1226,11 @@ static void zend_dump_var_set(const zend_op_array *op_array, const char *name, z void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg) { - int j; fprintf(stderr, "\nVariable Liveness for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < cfg->blocks_count; j++) { + for (uint32_t j = 0; j < cfg->blocks_count; j++) { fprintf(stderr, " BB%d:\n", j); zend_dump_var_set(op_array, "def", DFG_BITSET(dfg->def, dfg->size, j)); zend_dump_var_set(op_array, "use", DFG_BITSET(dfg->use, dfg->size, j)); @@ -1251,17 +1241,16 @@ void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zen void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa) { - int j; - zend_ssa_block *ssa_blocks = ssa->blocks; - int blocks_count = ssa->cfg.blocks_count; + const zend_ssa_block *ssa_blocks = ssa->blocks; + uint32_t blocks_count = ssa->cfg.blocks_count; fprintf(stderr, "\nSSA Phi() Placement for \""); zend_dump_op_array_name(op_array); fprintf(stderr, "\"\n"); - for (j = 0; j < blocks_count; j++) { + for (uint32_t j = 0; j < blocks_count; j++) { if (ssa_blocks && ssa_blocks[j].phis) { - zend_ssa_phi *p = ssa_blocks[j].phis; - int first = 1; + const zend_ssa_phi *p = ssa_blocks[j].phis; + bool first = true; fprintf(stderr, " BB%d:\n", j); if (p->pi >= 0) { @@ -1271,7 +1260,7 @@ void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa) } do { if (first) { - first = 0; + first = false; } else { fprintf(stderr, ", "); } diff --git a/Zend/Optimizer/zend_dump.h b/Zend/Optimizer/zend_dump.h index db8f762bfc49..45740d9609cb 100644 --- a/Zend/Optimizer/zend_dump.h +++ b/Zend/Optimizer/zend_dump.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Bytecode Visualisation | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -44,7 +42,7 @@ ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *s ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t 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); +void zend_dump_ht(const HashTable *ht); END_EXTERN_C() diff --git a/Zend/Optimizer/zend_func_info.c b/Zend/Optimizer/zend_func_info.c index 121d2d2cfe57..185fcc40be67 100644 --- a/Zend/Optimizer/zend_func_info.c +++ b/Zend/Optimizer/zend_func_info.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Func Info | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -24,7 +22,6 @@ #include "zend_inference.h" #include "zend_call_graph.h" #include "zend_func_info.h" -#include "zend_inference.h" #ifdef _WIN32 #include "win32/ioutil.h" #endif @@ -57,7 +54,7 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa && (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; + const 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); uint32_t t2 = _ssa_op1_info(op_array, ssa, call_info->arg_info[1].opline, @@ -116,7 +113,7 @@ uint32_t zend_get_internal_func_info( return 0; } - func_info_t *info = Z_PTR_P(zv); + const func_info_t *info = Z_PTR_P(zv); if (info->info_func) { return call_info ? info->info_func(call_info, ssa) : 0; } else { @@ -136,7 +133,7 @@ ZEND_API uint32_t zend_get_func_info( uint32_t ret = 0; const zend_function *callee_func = call_info->callee_func; *ce = NULL; - *ce_is_instanceof = 0; + *ce_is_instanceof = false; if (callee_func->type == ZEND_INTERNAL_FUNCTION) { uint32_t internal_ret = zend_get_internal_func_info(callee_func, call_info, ssa); @@ -178,7 +175,7 @@ ZEND_API uint32_t zend_get_func_info( } else { if (!call_info->is_prototype) { // FIXME: the order of functions matters!!! - zend_func_info *info = ZEND_FUNC_INFO((zend_op_array*)callee_func); + const zend_func_info *info = ZEND_FUNC_INFO((zend_op_array*)callee_func); if (info) { ret = info->return_info.type; *ce = info->return_info.ce; @@ -198,13 +195,13 @@ ZEND_API uint32_t zend_get_func_info( return ret; } -static void zend_func_info_add(const func_info_t *func_infos, size_t n) +static void zend_func_info_add(const func_info_t *new_func_infos, size_t n) { for (size_t i = 0; i < n; i++) { - zend_string *key = zend_string_init_interned(func_infos[i].name, func_infos[i].name_len, 1); + zend_string *key = zend_string_init_interned(new_func_infos[i].name, new_func_infos[i].name_len, 1); - if (zend_hash_add_ptr(&func_info, key, (void**)&func_infos[i]) == NULL) { - fprintf(stderr, "ERROR: Duplicate function info for \"%s\"\n", func_infos[i].name); + if (zend_hash_add_ptr(&func_info, key, (void**)&new_func_infos[i]) == NULL) { + fprintf(stderr, "ERROR: Duplicate function info for \"%s\"\n", new_func_infos[i].name); } zend_string_release_ex(key, 1); diff --git a/Zend/Optimizer/zend_func_info.h b/Zend/Optimizer/zend_func_info.h index b53683bdf5e7..6b5b51cac58b 100644 --- a/Zend/Optimizer/zend_func_info.h +++ b/Zend/Optimizer/zend_func_info.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, Func Info | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -39,7 +37,7 @@ #define ZEND_FUNC_JIT_ON_PROF_REQUEST (1<<14) /* used by JIT */ #define ZEND_FUNC_JIT_ON_HOT_COUNTERS (1<<15) /* used by JIT */ #define ZEND_FUNC_JIT_ON_HOT_TRACE (1<<16) /* used by JIT */ - +#define ZEND_FUNC_JITED (1<<17) /* used by JIT */ typedef struct _zend_func_info zend_func_info; typedef struct _zend_call_info zend_call_info; diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 3655e5fd21c3..b7b118c710c5 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -1,6 +1,7 @@ /* 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), @@ -130,9 +131,7 @@ 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) @@ -394,8 +393,6 @@ static const func_info_t func_infos[] = { F1("compact", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), FN("array_fill", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY), F1("array_fill_keys", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_replace", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_replace_recursive", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), FN("array_keys", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING), FN("array_values", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_count_values", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG), @@ -404,13 +401,8 @@ static const func_info_t func_infos[] = { F1("array_flip", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING), F1("array_change_key_case", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_intersect_key", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_intersect_ukey", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_intersect", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_uintersect", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_intersect_assoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_uintersect_assoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_intersect_uassoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), - F1("array_uintersect_uassoc", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_diff_key", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_diff_ukey", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), F1("array_udiff", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF), @@ -518,7 +510,7 @@ 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), - F1("glob", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE), + FN("glob", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE), F1("exec", MAY_BE_STRING|MAY_BE_FALSE), F1("system", MAY_BE_STRING|MAY_BE_FALSE), F1("escapeshellcmd", MAY_BE_STRING), diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index fc6b9b421b62..05d33d3d75fb 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, e-SSA based Type & Range Inference | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -266,7 +264,7 @@ typedef struct _zend_scc_iterator { }; } zend_scc_iterator; -static int zend_scc_next(const zend_op_array *op_array, zend_ssa *ssa, int var, zend_scc_iterator *iterator) /* {{{ */ +static int zend_scc_next(const zend_op_array *op_array, const zend_ssa *ssa, int var, zend_scc_iterator *iterator) /* {{{ */ { zend_ssa_phi *phi; int use, var2; @@ -487,14 +485,14 @@ ZEND_API void zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa) / #endif -ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ssa) /* {{{ */ +ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, const zend_ssa *ssa) /* {{{ */ { zend_ssa_var *ssa_vars = ssa->vars; - zend_ssa_op *ssa_ops = ssa->ops; + const zend_ssa_op *ssa_ops = ssa->ops; int ssa_vars_count = ssa->vars_count; zend_bitset worklist; - int i, j, use; - zend_ssa_phi *p; + int i, use; + const zend_ssa_phi *p; ALLOCA_FLAG(use_heap); if (!op_array->function_name || !ssa->vars || !ssa->ops) { @@ -527,7 +525,7 @@ ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, ze zend_bitset_incl(worklist, p->sources[0]); } } else { - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { ZEND_ASSERT(p->sources[j] >= 0); if (ssa->vars[p->sources[j]].no_val) { ssa_vars[p->sources[j]].no_val = 0; /* used indirectly */ @@ -1063,12 +1061,12 @@ static bool zend_inference_calc_binary_op_range( case ZEND_BW_XOR: // TODO break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return 0; } -static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ssa *ssa, int var, int widening, int narrowing, zend_ssa_range *tmp) +static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ssa *ssa, int var, int widening, bool narrowing, zend_ssa_range *tmp) { uint32_t line; const zend_op *opline; @@ -1076,7 +1074,6 @@ static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ if (ssa->vars[var].definition_phi) { const zend_ssa_phi *p = ssa->vars[var].definition_phi; - int i; tmp->underflow = 0; tmp->min = ZEND_LONG_MAX; @@ -1222,7 +1219,7 @@ static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ } } } else { - for (i = 0; i < ssa->cfg.blocks[p->block].predecessors_count; i++) { + for (uint32_t i = 0; i < ssa->cfg.blocks[p->block].predecessors_count; i++) { ZEND_ASSERT(p->sources[i] >= 0); if (ssa->var_info[p->sources[i]].has_range) { /* union */ @@ -1597,7 +1594,7 @@ ZEND_API bool zend_inference_propagate_range(const zend_op_array *op_array, cons return 0; } -static void zend_inference_init_range(const zend_op_array *op_array, zend_ssa *ssa, int var, bool underflow, zend_long min, zend_long max, bool overflow) +static void zend_inference_init_range(const zend_op_array *op_array, const zend_ssa *ssa, int var, bool underflow, zend_long min, zend_long max, bool overflow) { if (underflow) { min = ZEND_LONG_MIN; @@ -1623,12 +1620,16 @@ static bool zend_inference_widening_meet(zend_ssa_var_info *var_info, zend_ssa_r r->min < var_info->range.min) { r->underflow = 1; r->min = ZEND_LONG_MIN; + } else { + r->min = var_info->range.min; } if (r->overflow || var_info->range.overflow || r->max > var_info->range.max) { r->overflow = 1; r->max = ZEND_LONG_MAX; + } else { + r->max = var_info->range.max; } if (var_info->range.min == r->min && var_info->range.max == r->max && @@ -1641,7 +1642,7 @@ static bool zend_inference_widening_meet(zend_ssa_var_info *var_info, zend_ssa_r return 1; } -static bool zend_ssa_range_widening(const zend_op_array *op_array, zend_ssa *ssa, int var, int scc) +static bool zend_ssa_range_widening(const zend_op_array *op_array, const zend_ssa *ssa, int var, int scc) { zend_ssa_range tmp; @@ -1686,7 +1687,7 @@ static bool zend_inference_narrowing_meet(zend_ssa_var_info *var_info, zend_ssa_ return 1; } -static bool zend_ssa_range_narrowing(const zend_op_array *op_array, zend_ssa *ssa, int var, int scc) +static bool zend_ssa_range_narrowing(const zend_op_array *op_array, const zend_ssa *ssa, int var, int scc) { zend_ssa_range tmp; @@ -1731,7 +1732,7 @@ static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ss zend_bitset worklist = do_alloca(sizeof(zend_ulong) * worklist_len * 2, use_heap); zend_bitset visited = worklist + worklist_len; #ifdef NEG_RANGE - int has_inner_cycles = 0; + bool has_inner_cycles = false; memset(worklist, 0, sizeof(zend_ulong) * worklist_len); memset(visited, 0, sizeof(zend_ulong) * worklist_len); @@ -1739,7 +1740,7 @@ static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ss while (j >= 0) { if (!zend_bitset_in(visited, j) && zend_check_inner_cycles(op_array, ssa, worklist, visited, j)) { - has_inner_cycles = 1; + has_inner_cycles = true; break; } j = next_scc_var[j]; @@ -1858,7 +1859,7 @@ static void zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* { } else if (zend_inference_calc_range(op_array, ssa, j, 0, 1, &tmp)) { zend_inference_init_range(op_array, ssa, j, tmp.underflow, tmp.min, tmp.max, tmp.overflow); } else { - zend_inference_init_range(op_array, ssa, j, 1, ZEND_LONG_MIN, ZEND_LONG_MAX, 1); + zend_inference_init_range(op_array, ssa, j, true, ZEND_LONG_MIN, ZEND_LONG_MAX, true); } } else { /* Find SCC entry points */ @@ -1893,7 +1894,8 @@ static void zend_infer_ranges(const zend_op_array *op_array, zend_ssa *ssa) /* { for (j = scc_var[scc]; j >= 0; j = next_scc_var[j]) { if (!ssa->var_info[j].has_range && !(ssa->var_info[j].type & MAY_BE_REF)) { - zend_inference_init_range(op_array, ssa, j, 1, ZEND_LONG_MIN, ZEND_LONG_MAX, 1); + zend_inference_init_range(op_array, ssa, j, true, ZEND_LONG_MIN, ZEND_LONG_MAX, + true); FOR_EACH_VAR_USAGE(j, ADD_SCC_VAR); } } @@ -2024,10 +2026,10 @@ static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) { } \ } while (0) -static void add_usages(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset worklist, int var) +static void add_usages(const zend_op_array *op_array, const zend_ssa *ssa, zend_bitset worklist, int var) { if (ssa->vars[var].phi_use_chain) { - zend_ssa_phi *p = ssa->vars[var].phi_use_chain; + const zend_ssa_phi *p = ssa->vars[var].phi_use_chain; do { zend_bitset_incl(worklist, p->ssa_var); p = zend_ssa_next_use_phi(ssa, var, p); @@ -2035,7 +2037,7 @@ static void add_usages(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset } if (ssa->vars[var].use_chain >= 0) { int use = ssa->vars[var].use_chain; - zend_ssa_op *op; + const zend_ssa_op *op; do { op = ssa->ops + use; @@ -2077,7 +2079,7 @@ static void add_usages(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset } } -static void emit_type_narrowing_warning(const zend_op_array *op_array, zend_ssa *ssa, int var) +static void emit_type_narrowing_warning(const zend_op_array *op_array, const zend_ssa *ssa, int var) { int def_op_num = ssa->vars[var].definition; const zend_op *def_opline = def_op_num >= 0 ? &op_array->opcodes[def_op_num] : NULL; @@ -2125,7 +2127,7 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv) } -ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, int write, int insert) +ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool write, bool insert) { uint32_t tmp = 0; @@ -2253,7 +2255,7 @@ static uint32_t assign_dim_result_type( /* For binary ops that have compound assignment operators */ static uint32_t binary_op_result_type( - zend_ssa *ssa, uint8_t opcode, uint32_t t1, uint32_t t2, int result_var, + const zend_ssa *ssa, uint8_t opcode, uint32_t t1, uint32_t t2, int result_var, zend_long optimization_level) { uint32_t tmp = 0; uint32_t t1_type = (t1 & MAY_BE_ANY) | (t1 & MAY_BE_UNDEF ? MAY_BE_NULL : 0); @@ -2346,7 +2348,7 @@ static uint32_t binary_op_result_type( /* TODO: +MAY_BE_OBJECT ??? */ tmp = MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN; break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return tmp; } @@ -2409,7 +2411,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))) { - zend_class_entry *prev_scope = EG(fake_scope); + const 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; @@ -2430,7 +2432,7 @@ static const zend_property_info *lookup_prop_info(const zend_class_entry *ce, ze return NULL; } -static const zend_property_info *zend_fetch_prop_info(const zend_op_array *op_array, zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) +static const zend_property_info *zend_fetch_prop_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op *ssa_op) { const zend_property_info *prop_info = NULL; if (opline->op2_type == IS_CONST) { @@ -2457,9 +2459,9 @@ static const zend_property_info *zend_fetch_static_prop_info(const zend_script * { const zend_property_info *prop_info = NULL; if (opline->op1_type == IS_CONST) { - zend_class_entry *ce = NULL; + const zend_class_entry *ce = NULL; if (opline->op2_type == IS_UNUSED) { - int fetch_type = opline->op2.num & ZEND_FETCH_CLASS_MASK; + uint32_t fetch_type = opline->op2.num & ZEND_FETCH_CLASS_MASK; switch (fetch_type) { case ZEND_FETCH_CLASS_SELF: case ZEND_FETCH_CLASS_STATIC: @@ -2474,12 +2476,12 @@ static const zend_property_info *zend_fetch_static_prop_info(const zend_script * break; } } else if (opline->op2_type == IS_CONST) { - zval *zv = CRT_CONSTANT(opline->op2); + const zval *zv = CRT_CONSTANT(opline->op2); ce = zend_optimizer_get_class_entry(script, op_array, Z_STR_P(zv + 1)); } if (ce) { - zval *zv = CRT_CONSTANT(opline->op1); + const zval *zv = CRT_CONSTANT(opline->op1); prop_info = lookup_prop_info(ce, Z_STR_P(zv), op_array->scope); if (prop_info && !(prop_info->flags & ZEND_ACC_STATIC)) { prop_info = NULL; @@ -2501,13 +2503,13 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, const zend_prope return zend_convert_type(script, prop_info->type, pce); } -static bool result_may_be_separated(zend_ssa *ssa, zend_ssa_op *ssa_op) +static bool result_may_be_separated(const zend_ssa *ssa, const zend_ssa_op *ssa_op) { int tmp_var = ssa_op->result_def; if (ssa->vars[tmp_var].use_chain >= 0 && !ssa->vars[tmp_var].phi_use_chain) { - zend_ssa_op *use_op = &ssa->ops[ssa->vars[tmp_var].use_chain]; + const zend_ssa_op *use_op = &ssa->ops[ssa->vars[tmp_var].use_chain]; /* TODO: analyze instructions between ssa_op and use_op */ if (use_op == ssa_op + 1) { @@ -3023,7 +3025,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; + const 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. */ @@ -3704,7 +3706,7 @@ static zend_always_inline zend_result _zend_update_type_info( case ZEND_FREE: /* This may happen if the using opcode is DCEd. */ break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } j = zend_ssa_next_use(ssa->ops, ssa_op->result_def, j); if (j >= 0) { @@ -3835,7 +3837,7 @@ static zend_always_inline zend_result _zend_update_type_info( tmp &= ~MAY_BE_RC1; } if (opline->opcode == ZEND_FETCH_STATIC_PROP_IS) { - tmp |= MAY_BE_UNDEF; + tmp |= MAY_BE_NULL; } } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); @@ -4115,15 +4117,16 @@ ZEND_API zend_result zend_update_type_info( const zend_op_array *op_array, zend_ssa *ssa, const zend_script *script, - zend_op *opline, + const zend_op *opline, zend_ssa_op *ssa_op, const zend_op **ssa_opcodes, zend_long optimization_level) { - return _zend_update_type_info(op_array, ssa, script, NULL, opline, ssa_op, ssa_opcodes, optimization_level, 0); + return _zend_update_type_info(op_array, ssa, script, NULL, opline, ssa_op, ssa_opcodes, optimization_level, + false); } -static uint32_t get_class_entry_rank(zend_class_entry *ce) { +static uint32_t get_class_entry_rank(const zend_class_entry *ce) { uint32_t rank = 0; if (ce->ce_flags & ZEND_ACC_LINKED) { while (ce->parent) { @@ -4136,7 +4139,7 @@ static uint32_t get_class_entry_rank(zend_class_entry *ce) { /* Compute least common ancestor on class inheritance tree only */ static zend_class_entry *join_class_entries( - zend_class_entry *ce1, zend_class_entry *ce2, int *is_instanceof) { + zend_class_entry *ce1, zend_class_entry *ce2, bool *is_instanceof) { uint32_t rank1, rank2; if (ce1 == ce2) { return ce1; @@ -4164,12 +4167,12 @@ static zend_class_entry *join_class_entries( } if (ce1) { - *is_instanceof = 1; + *is_instanceof = true; } return ce1; } -static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) { +static bool safe_instanceof(const zend_class_entry *ce1, const zend_class_entry *ce2) { if (ce1 == ce2) { return 1; } @@ -4182,11 +4185,11 @@ static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) { static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_bitset worklist, zend_long optimization_level) { - zend_basic_block *blocks = ssa->cfg.blocks; + const zend_basic_block *blocks = ssa->cfg.blocks; zend_ssa_var *ssa_vars = ssa->vars; zend_ssa_var_info *ssa_var_info = ssa->var_info; int ssa_vars_count = ssa->vars_count; - int i, j; + int j; uint32_t tmp, worklist_len = zend_bitset_len(ssa_vars_count); bool update_worklist = 1; const zend_op **ssa_opcodes = NULL; @@ -4198,11 +4201,11 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend zend_ssa_phi *p = ssa_vars[j].definition_phi; if (p->pi >= 0) { zend_class_entry *ce = ssa_var_info[p->sources[0]].ce; - int is_instanceof = ssa_var_info[p->sources[0]].is_instanceof; + bool is_instanceof = ssa_var_info[p->sources[0]].is_instanceof; tmp = get_ssa_var_info(ssa, p->sources[0]); if (!p->has_range_constraint) { - zend_ssa_type_constraint *constraint = &p->constraint.type; + const zend_ssa_type_constraint *constraint = &p->constraint.type; tmp &= constraint->type_mask; if (!(tmp & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { tmp &= ~(MAY_BE_RC1|MAY_BE_RCN); @@ -4210,7 +4213,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend if ((tmp & MAY_BE_OBJECT) && constraint->ce && ce != constraint->ce) { if (!ce) { ce = constraint->ce; - is_instanceof = 1; + is_instanceof = true; } else if (is_instanceof && safe_instanceof(constraint->ce, ce)) { ce = constraint->ce; } else { @@ -4227,9 +4230,10 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend UPDATE_SSA_OBJ_TYPE(ce, is_instanceof, j); } } else { - int first = 1; - int is_instanceof = 0; + bool first = true; + bool is_instanceof = false; zend_class_entry *ce = NULL; + uint32_t i; tmp = 0; for (i = 0; i < blocks[p->block].predecessors_count; i++) { @@ -4245,7 +4249,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend if (first) { ce = info->ce; is_instanceof = info->is_instanceof; - first = 0; + first = false; } else { is_instanceof |= info->is_instanceof; ce = join_class_entries(ce, info->ce, &is_instanceof); @@ -4255,8 +4259,8 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend UPDATE_SSA_OBJ_TYPE(ce, ce ? is_instanceof : 0, j); } } else if (ssa_vars[j].definition >= 0) { - i = ssa_vars[j].definition; - if (_zend_update_type_info(op_array, ssa, script, worklist, op_array->opcodes + i, ssa->ops + i, NULL, optimization_level, 1) == FAILURE) { + int i = ssa_vars[j].definition; + if (_zend_update_type_info(op_array, ssa, script, worklist, op_array->opcodes + i, ssa->ops + i, NULL, optimization_level, true) == FAILURE) { return FAILURE; } } @@ -4264,18 +4268,18 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend return SUCCESS; } -static bool is_narrowable_instr(zend_op *opline) { +static bool is_narrowable_instr(const zend_op *opline) { return opline->opcode == ZEND_ADD || opline->opcode == ZEND_SUB || opline->opcode == ZEND_MUL || opline->opcode == ZEND_DIV; } -static bool is_effective_op1_double_cast(zend_op *opline, zval *op2) { +static bool is_effective_op1_double_cast(const zend_op *opline, const zval *op2) { return (opline->opcode == ZEND_ADD && Z_LVAL_P(op2) == 0) || (opline->opcode == ZEND_SUB && Z_LVAL_P(op2) == 0) || (opline->opcode == ZEND_MUL && Z_LVAL_P(op2) == 1) || (opline->opcode == ZEND_DIV && Z_LVAL_P(op2) == 1); } -static bool is_effective_op2_double_cast(zend_op *opline, zval *op1) { +static bool is_effective_op2_double_cast(const zend_op *opline, const zval *op1) { /* In PHP it holds that (double)(0-$int) is bitwise identical to 0.0-(double)$int, * so allowing SUB here is fine. */ return (opline->opcode == ZEND_ADD && Z_LVAL_P(op1) == 0) @@ -4487,19 +4491,18 @@ static zend_result zend_type_narrowing(const zend_op_array *op_array, const zend return SUCCESS; } -static bool is_recursive_tail_call(const zend_op_array *op_array, - zend_op *opline) +static bool is_recursive_tail_call(const zend_op_array *op_array, const zend_op *opline) { - zend_func_info *info = ZEND_FUNC_INFO(op_array); + const zend_func_info *info = ZEND_FUNC_INFO(op_array); if (info->ssa.ops && info->ssa.vars && info->call_map && info->ssa.ops[opline - op_array->opcodes].op1_use >= 0 && info->ssa.vars[info->ssa.ops[opline - op_array->opcodes].op1_use].definition >= 0) { - zend_op *op = op_array->opcodes + info->ssa.vars[info->ssa.ops[opline - op_array->opcodes].op1_use].definition; + const zend_op *op = op_array->opcodes + info->ssa.vars[info->ssa.ops[opline - op_array->opcodes].op1_use].definition; if (op->opcode == ZEND_DO_UCALL) { - zend_call_info *call_info = info->call_map[op - op_array->opcodes]; + const zend_call_info *call_info = info->call_map[op - op_array->opcodes]; if (call_info && op_array == &call_info->callee_func->op_array) { return 1; } @@ -4515,7 +4518,7 @@ uint32_t zend_get_return_info_from_signature_only( if (func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && (use_tentative_return_info || !ZEND_ARG_TYPE_IS_TENTATIVE(func->common.arg_info - 1)) ) { - zend_arg_info *ret_info = func->common.arg_info - 1; + const zend_arg_info *ret_info = func->common.arg_info - 1; type = zend_fetch_arg_info_type(script, ret_info, ce); *ce_is_instanceof = ce != NULL; } else { @@ -4530,7 +4533,7 @@ uint32_t zend_get_return_info_from_signature_only( && !(func->common.fn_flags & ZEND_ACC_GENERATOR)) { type |= MAY_BE_REF; *ce = NULL; - *ce_is_instanceof = 0; + *ce_is_instanceof = false; } return type; } @@ -4543,7 +4546,7 @@ ZEND_API void zend_init_func_return_info( zend_ssa_range tmp_range = {0, 0, 0, 0}; bool is_instanceof = false; ret->type = zend_get_return_info_from_signature_only( - (zend_function *) op_array, script, &ret->ce, &is_instanceof, /* use_tentative_return_info */ 1); + (zend_function *) op_array, script, &ret->ce, &is_instanceof, /* use_tentative_return_info */ true); ret->is_instanceof = is_instanceof; ret->range = tmp_range; ret->has_range = 0; @@ -4551,21 +4554,20 @@ ZEND_API void zend_init_func_return_info( static void zend_func_return_info(const zend_op_array *op_array, const zend_script *script, - int recursive, - int widening, + bool recursive, + bool widening, zend_ssa_var_info *ret) { - zend_func_info *info = ZEND_FUNC_INFO(op_array); - zend_ssa *ssa = &info->ssa; - int blocks_count = info->ssa.cfg.blocks_count; - zend_basic_block *blocks = info->ssa.cfg.blocks; - int j; + const zend_func_info *info = ZEND_FUNC_INFO(op_array); + const zend_ssa *ssa = &info->ssa; + uint32_t blocks_count = info->ssa.cfg.blocks_count; + const zend_basic_block *blocks = info->ssa.cfg.blocks; uint32_t t1; uint32_t tmp = 0; zend_class_entry *tmp_ce = NULL; int tmp_is_instanceof = -1; zend_class_entry *arg_ce; - int arg_is_instanceof; + bool arg_is_instanceof; zend_ssa_range tmp_range = {0, 0, 0, 0}; int tmp_has_range = -1; @@ -4584,12 +4586,12 @@ static void zend_func_return_info(const zend_op_array *op_array, | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF; } - for (j = 0; j < blocks_count; j++) { + for (uint32_t j = 0; j < blocks_count; j++) { if ((blocks[j].flags & ZEND_BB_REACHABLE) && blocks[j].len != 0) { zend_op *opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1; if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF) { - zend_ssa_op *ssa_op = ssa->ops ? &ssa->ops[opline - op_array->opcodes] : NULL; + const zend_ssa_op *ssa_op = ssa->ops ? &ssa->ops[opline - op_array->opcodes] : NULL; if (!recursive && ssa_op && info->ssa.var_info && ssa_op->op1_use >= 0 && info->ssa.var_info[ssa_op->op1_use].recursive) { @@ -4620,7 +4622,7 @@ static void zend_func_return_info(const zend_op_array *op_array, arg_is_instanceof = info->ssa.var_info[ssa_op->op1_use].is_instanceof; } else { arg_ce = NULL; - arg_is_instanceof = 0; + arg_is_instanceof = false; } if (tmp_is_instanceof < 0) { @@ -4636,7 +4638,7 @@ static void zend_func_return_info(const zend_op_array *op_array, } if (opline->op1_type == IS_CONST) { - zval *zv = CRT_CONSTANT(opline->op1); + const zval *zv = CRT_CONSTANT(opline->op1); if (Z_TYPE_P(zv) == IS_LONG) { if (tmp_has_range < 0) { @@ -4739,7 +4741,7 @@ static zend_result zend_infer_types(const zend_op_array *op_array, const zend_sc return SUCCESS; } -static void zend_mark_cv_references(const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa) +static void zend_mark_cv_references(const zend_op_array *op_array, const zend_script *script, const zend_ssa *ssa) { int var, def; const zend_op *opline; @@ -5105,14 +5107,16 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_PRE_DEC: case ZEND_POST_DEC: return (t1 & (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); - case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: - case ZEND_BOOL: case ZEND_JMP_SET: return (t1 & MAY_BE_OBJECT); + case ZEND_BOOL: + case ZEND_BOOL_NOT: + /* NAN Cast to bool will warn, but if we have a range it is fine */ + return (t1 & MAY_BE_OBJECT) || ((t1 & MAY_BE_DOUBLE) && !OP1_HAS_RANGE()); case ZEND_BOOL_XOR: return (t1 & MAY_BE_OBJECT) || (t2 & MAY_BE_OBJECT); case ZEND_IS_EQUAL: @@ -5246,7 +5250,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_INIT_ARRAY: return (opline->op2_type != IS_UNUSED) && (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); case ZEND_ADD_ARRAY_ELEMENT: - return (opline->op2_type == IS_UNUSED) || (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); + return (opline->op2_type == IS_UNUSED) || (t2 & (MAY_BE_NULL|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); case ZEND_STRLEN: return (t1 & MAY_BE_ANY) != MAY_BE_STRING; case ZEND_COUNT: @@ -5279,6 +5283,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_CAST: switch (opline->extended_value) { case IS_LONG: + return (t1 & (MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_OBJECT)); case IS_DOUBLE: return (t1 & MAY_BE_OBJECT); case IS_STRING: @@ -5287,10 +5292,10 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op return (t1 & MAY_BE_OBJECT); case IS_OBJECT: return 0; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } /* GCC is getting confused here for the Wimplicit-fallthrough warning with - * EMPTY_SWITCH_DEFAULT_CASE() macro */ + * default: ZEND_UNREACHABLE(); macro */ return 0; case ZEND_ARRAY_KEY_EXISTS: if ((t2 & MAY_BE_ANY) != MAY_BE_ARRAY) { @@ -5328,6 +5333,13 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op return 1; } return 0; + case ZEND_YIELD_FROM: { + uint32_t t1 = OP1_INFO(); + if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY && MAY_BE_EMPTY_ONLY(t1)) { + return false; + } + return true; + } default: return 1; } diff --git a/Zend/Optimizer/zend_inference.h b/Zend/Optimizer/zend_inference.h index 666abc586592..e6b4207c7494 100644 --- a/Zend/Optimizer/zend_inference.h +++ b/Zend/Optimizer/zend_inference.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, e-SSA based Type & Range Inference | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -217,11 +215,11 @@ static zend_always_inline bool zend_sub_will_overflow(zend_long a, zend_long b) BEGIN_EXTERN_C() -ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ssa); +ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, const zend_ssa *ssa); ZEND_API void zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa); ZEND_API zend_result zend_ssa_inference(zend_arena **raena, const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_long optimization_level); -ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, int write, int insert); +ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool write, bool insert); ZEND_API bool zend_inference_propagate_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp); @@ -238,7 +236,7 @@ ZEND_API bool zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, c ZEND_API zend_result zend_update_type_info( const zend_op_array *op_array, zend_ssa *ssa, const zend_script *script, - zend_op *opline, zend_ssa_op *ssa_op, const zend_op **ssa_opcodes, + const zend_op *opline, zend_ssa_op *ssa_op, const zend_op **ssa_opcodes, zend_long optimization_level); END_EXTERN_C() diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index 1c58d6b7372f..5ffdefac49a3 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -41,7 +39,7 @@ struct { int last; } zend_optimizer_registered_passes = {{NULL}, 0}; -void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value) +void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, const zval *name, zval* value) { if (!ctx->constants) { ctx->constants = zend_arena_alloc(&ctx->arena, sizeof(HashTable)); @@ -74,6 +72,9 @@ zend_result zend_optimizer_eval_unary_op(zval *result, uint8_t opcode, zval *op1 } return unary_op(result, op1); } else { /* ZEND_BOOL */ + if (Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1))) { + return FAILURE; + } ZVAL_BOOL(result, zend_is_true(op1)); return SUCCESS; } @@ -100,11 +101,11 @@ zend_result zend_optimizer_eval_strlen(zval *result, const zval *op1) /* {{{ */ /* }}} */ zend_result zend_optimizer_eval_special_func_call( - zval *result, zend_string *name, zend_string *arg) { + zval *result, const zend_string *name, zend_string *arg) { if (zend_string_equals_literal(name, "function_exists") || zend_string_equals_literal(name, "is_callable")) { zend_string *lc_name = zend_string_tolower(arg); - zend_internal_function *func = zend_hash_find_ptr(EG(function_table), lc_name); + const zend_internal_function *func = zend_hash_find_ptr(EG(function_table), lc_name); zend_string_release_ex(lc_name, 0); if (func && func->type == ZEND_INTERNAL_FUNCTION @@ -142,7 +143,7 @@ zend_result zend_optimizer_eval_special_func_call( return FAILURE; } if (zend_string_equals_literal(name, "constant")) { - return zend_optimizer_get_persistent_constant(arg, result, 1) ? SUCCESS : FAILURE; + return zend_optimizer_get_persistent_constant(arg, result, true) ? SUCCESS : FAILURE; } if (zend_string_equals_literal(name, "dirname")) { if (!IS_ABSOLUTE_PATH(ZSTR_VAL(arg), ZSTR_LEN(arg))) { @@ -177,18 +178,18 @@ zend_result zend_optimizer_eval_special_func_call( return FAILURE; } -bool zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value) +bool zend_optimizer_get_collected_constant(const HashTable *constants, const zval *name, zval* value) { zval *val; if ((val = zend_hash_find(constants, Z_STR_P(name))) != NULL) { ZVAL_COPY(value, val); - return 1; + return true; } - return 0; + return false; } -void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline) +void zend_optimizer_convert_to_free_op1(const zend_op_array *op_array, zend_op *opline) { if (opline->op1_type == IS_CV) { opline->opcode = ZEND_CHECK_VAR; @@ -207,9 +208,9 @@ void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline } } -int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv) +uint32_t zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv) { - int i = op_array->last_literal; + uint32_t i = op_array->last_literal; op_array->last_literal++; op_array->literals = (zval*)erealloc(op_array->literals, op_array->last_literal * sizeof(zval)); ZVAL_COPY_VALUE(&op_array->literals[i], zv); @@ -217,7 +218,7 @@ int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv) return i; } -static inline int zend_optimizer_add_literal_string(zend_op_array *op_array, zend_string *str) { +static inline uint32_t zend_optimizer_add_literal_string(zend_op_array *op_array, zend_string *str) { zval zv; ZVAL_STR(&zv, str); zend_string_hash_val(str); @@ -260,7 +261,7 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array, switch ((opline-1)->opcode) { case ZEND_ASSIGN_OBJ_REF: case ZEND_ASSIGN_STATIC_PROP_REF: - return 0; + return false; } opline->op1.constant = zend_optimizer_add_literal(op_array, val); break; @@ -268,7 +269,7 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_CHECK_VAR: MAKE_NOP(opline); zval_ptr_dtor_nogc(val); - return 1; + return true; case ZEND_SEND_VAR_EX: case ZEND_SEND_FUNC_ARG: case ZEND_FETCH_DIM_W: @@ -283,7 +284,7 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_SEPARATE: case ZEND_SEND_VAR_NO_REF: case ZEND_SEND_VAR_NO_REF_EX: - return 0; + return false; case ZEND_CATCH: REQUIRES_STRING(val); drop_leading_backslash(val); @@ -365,10 +366,10 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_VERIFY_RETURN_TYPE: /* This would require a non-local change. * zend_optimizer_replace_by_const() supports this. */ - return 0; + return false; case ZEND_COPY_TMP: case ZEND_FETCH_CLASS_NAME: - return 0; + return false; case ZEND_ECHO: { zval zv; @@ -379,7 +380,7 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array, opline->op1.constant = zend_optimizer_add_literal(op_array, val); if (Z_TYPE_P(val) == IS_STRING && Z_STRLEN_P(val) == 0) { MAKE_NOP(opline); - return 1; + return true; } /* TODO: In a subsequent pass, *after* this step and compacting nops, combine consecutive ZEND_ECHOs using the block information from ssa->cfg */ /* (e.g. for ext/opcache/tests/opt/sccp_010.phpt) */ @@ -409,7 +410,7 @@ bool zend_optimizer_update_op1_const(zend_op_array *op_array, if (Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING) { zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline))); } - return 1; + return true; } bool zend_optimizer_update_op2_const(zend_op_array *op_array, @@ -421,7 +422,7 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array, switch (opline->opcode) { case ZEND_ASSIGN_REF: case ZEND_FAST_CALL: - return 0; + return false; case ZEND_FETCH_CLASS: case ZEND_INSTANCEOF: REQUIRES_STRING(val); @@ -475,13 +476,13 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_INIT_DYNAMIC_CALL: if (Z_TYPE_P(val) == IS_STRING) { if (zend_memrchr(Z_STRVAL_P(val), ':', Z_STRLEN_P(val))) { - return 0; + return false; } if (zend_optimizer_classify_function(Z_STR_P(val), opline->extended_value)) { /* Dynamic call to various special functions must stay dynamic, * otherwise would drop a warning */ - return 0; + return false; } opline->opcode = ZEND_INIT_FCALL_BY_NAME; @@ -591,7 +592,7 @@ bool zend_optimizer_update_op2_const(zend_op_array *op_array, if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline))); } - return 1; + return true; } bool zend_optimizer_replace_by_const(zend_op_array *op_array, @@ -600,7 +601,7 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array, uint32_t var, zval *val) { - zend_op *end = op_array->opcodes + op_array->last; + const zend_op *end = op_array->opcodes + op_array->last; while (opline < end) { if (opline->op1_type == type && @@ -619,7 +620,7 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array, case ZEND_MATCH: case ZEND_MATCH_ERROR: case ZEND_JMP_NULL: { - zend_op *end = op_array->opcodes + op_array->last; + const zend_op *end = op_array->opcodes + op_array->last; while (opline < end) { if (opline->op1_type == type && opline->op1.var == var) { /* If this opcode doesn't keep the operand alive, we're done. Check @@ -638,7 +639,7 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array, Z_TRY_ADDREF_P(val); if (!zend_optimizer_update_op1_const(op_array, opline, val)) { zval_ptr_dtor(val); - return 0; + return false; } if (is_last) { break; @@ -647,13 +648,13 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array, opline++; } zval_ptr_dtor_nogc(val); - return 1; + return true; } case ZEND_VERIFY_RETURN_TYPE: { - zend_arg_info *ret_info = op_array->arg_info - 1; + const zend_arg_info *ret_info = op_array->arg_info - 1; if (!ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(val)) || (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - return 0; + return false; } MAKE_NOP(opline); @@ -678,11 +679,11 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array, opline++; } - return 1; + return true; } /* Update jump offsets after a jump was migrated to another opline */ -void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline) { +void zend_optimizer_migrate_jump(const zend_op_array *op_array, zend_op *new_opline, zend_op *opline) { switch (new_opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: @@ -715,7 +716,7 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z case ZEND_SWITCH_STRING: case ZEND_MATCH: { - HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline)); + const HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline)); zval *zv; ZEND_HASH_FOREACH_VAL(jumptable, zv) { Z_LVAL_P(zv) = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv))); @@ -727,7 +728,7 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z } /* Shift jump offsets based on shiftlist */ -void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist) { +void zend_optimizer_shift_jump(const zend_op_array *op_array, zend_op *opline, const uint32_t *shiftlist) { switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: @@ -760,7 +761,7 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_ case ZEND_SWITCH_STRING: case ZEND_MATCH: { - HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline)); + const HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline)); zval *zv; ZEND_HASH_FOREACH_VAL(jumptable, zv) { Z_LVAL_P(zv) = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv)) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv))]); @@ -771,12 +772,15 @@ 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) +static bool zend_optimizer_ignore_class(zval *ce_zv, const zend_string *filename) { - zend_class_entry *ce = Z_PTR_P(ce_zv); + const 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)); + if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) { + return true; + } + const Bucket *ce_bucket = ZEND_CONTAINER_OF(ce_zv, Bucket, val); size_t offset = ce_bucket - EG(class_table)->arData; if (offset < EG(persistent_classes_count)) { return false; @@ -786,15 +790,18 @@ static bool zend_optimizer_ignore_class(zval *ce_zv, zend_string *filename) && (!ce->info.user.filename || ce->info.user.filename != filename); } -static bool zend_optimizer_ignore_function(zval *fbc_zv, zend_string *filename) +static bool zend_optimizer_ignore_function(zval *fbc_zv, const zend_string *filename) { - zend_function *fbc = Z_PTR_P(fbc_zv); + const 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)); + if (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE) { + return true; + } + const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val); size_t offset = fbc_bucket - EG(function_table)->arData; if (offset < EG(persistent_functions_count)) { return false; @@ -829,7 +836,7 @@ zend_class_entry *zend_optimizer_get_class_entry( zend_class_entry *zend_optimizer_get_class_entry_from_op1( const zend_script *script, const zend_op_array *op_array, const zend_op *opline) { if (opline->op1_type == IS_CONST) { - zval *op1 = CRT_CONSTANT(opline->op1); + const zval *op1 = CRT_CONSTANT(opline->op1); if (Z_TYPE_P(op1) == IS_STRING) { return zend_optimizer_get_class_entry(script, op_array, Z_STR_P(op1 + 1)); } @@ -852,7 +859,7 @@ const zend_class_constant *zend_fetch_class_const_info( return NULL; } if (opline->op1_type == IS_CONST) { - zval *op1 = CRT_CONSTANT(opline->op1); + 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)); @@ -866,7 +873,7 @@ const zend_class_constant *zend_fetch_class_const_info( } 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; + uint32_t 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) { @@ -895,10 +902,91 @@ const zend_class_constant *zend_fetch_class_const_info( return const_info; } +/* Returns the unique opcode in this op_array that writes to the given CV, or + * NULL if there are zero or multiple writers, or if any operation could mutate + * the CV through a reference. This is sound enough to use as a single-value + * assumption for CV-based callsite resolution: if we conclude a CV holds X at + * the call, eliding the runtime VERIFY is safe because any other actual value + * at runtime would cause the call itself to fail before VERIFY ever ran. */ +static const zend_op *zend_find_unique_cv_writer( + const zend_op_array *op_array, uint32_t cv_var) +{ + const zend_op *end = op_array->opcodes + op_array->last; + const zend_op *unique = NULL; + + for (const zend_op *op = op_array->opcodes; op < end; op++) { + if (op->result_type == IS_CV && op->result.var == cv_var) { + if (op->opcode == ZEND_QM_ASSIGN) { + if (unique) return NULL; + unique = op; + continue; + } + return NULL; + } + + switch (op->opcode) { + case ZEND_ASSIGN: + if (op->op1_type == IS_CV && op->op1.var == cv_var) { + if (unique) return NULL; + unique = op; + } + break; + case ZEND_ASSIGN_REF: + case ZEND_BIND_GLOBAL: + case ZEND_BIND_INIT_STATIC_OR_JMP: + case ZEND_BIND_STATIC: + case ZEND_SEND_REF: + case ZEND_SEND_VAR_NO_REF: + case ZEND_SEND_VAR_NO_REF_EX: + case ZEND_SEND_USER: + case ZEND_SEND_UNPACK: + case ZEND_SEND_ARRAY: + case ZEND_FE_FETCH_RW: + case ZEND_FE_RESET_RW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM: + case ZEND_ASSIGN_OBJ: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_OBJ_REF: + case ZEND_ASSIGN_STATIC_PROP_OP: + case ZEND_PRE_INC: + case ZEND_PRE_DEC: + case ZEND_POST_INC: + case ZEND_POST_DEC: + case ZEND_UNSET_CV: + case ZEND_FETCH_W: + case ZEND_FETCH_REF: + case ZEND_FETCH_FUNC_ARG: + if (op->op1_type == IS_CV && op->op1.var == cv_var) { + return NULL; + } + break; + } + } + + return unique; +} + +/* Walks backward from `from` to find the most recent opcode whose result port + * wrote to the given TMP/VAR slot. Used to chain `ASSIGN CV = TMP`-style + * patterns through to the value-producing opcode (e.g. NEW). */ +static const zend_op *zend_find_recent_tmp_writer( + const zend_op_array *op_array, const zend_op *from, uint32_t tmp_var) +{ + for (const zend_op *op = from - 1; op >= op_array->opcodes; op--) { + if ((op->result_type == IS_TMP_VAR || op->result_type == IS_VAR) + && op->result.var == tmp_var) { + return op; + } + } + return NULL; +} + zend_function *zend_optimizer_get_called_func( - zend_script *script, zend_op_array *op_array, zend_op *opline, bool *is_prototype) + const zend_script *script, const zend_op_array *op_array, zend_op *opline, bool *is_prototype) { - *is_prototype = 0; + *is_prototype = false; switch (opline->opcode) { case ZEND_INIT_FCALL: { @@ -917,7 +1005,7 @@ zend_function *zend_optimizer_get_called_func( case ZEND_INIT_FCALL_BY_NAME: case ZEND_INIT_NS_FCALL_BY_NAME: if (opline->op2_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_STRING) { - zval *function_name = CRT_CONSTANT(opline->op2) + 1; + const 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)))) { @@ -931,12 +1019,12 @@ zend_function *zend_optimizer_get_called_func( break; case ZEND_INIT_STATIC_METHOD_CALL: if (opline->op2_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_STRING) { - zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( + const zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( script, op_array, opline); if (ce) { zend_string *func_name = Z_STR_P(CRT_CONSTANT(opline->op2) + 1); zend_function *fbc = zend_hash_find_ptr(&ce->function_table, func_name); - if (fbc) { + if (fbc && !(fbc->common.fn_flags & ZEND_ACC_ABSTRACT)) { bool is_public = (fbc->common.fn_flags & ZEND_ACC_PUBLIC) != 0; bool same_scope = fbc->common.scope == op_array->scope; if (is_public || same_scope) { @@ -972,16 +1060,75 @@ zend_function *zend_optimizer_get_called_func( } return fbc; } + } else if (opline->op1_type == IS_CV + && opline->op2_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_STRING) { + /* `$o->method()` where $o has a unique ASSIGN whose source is a + * NEW result. The instance class is then known exactly (not just + * a base class), so the resolved method isn't a prototype. */ + const zend_op *cv_writer = zend_find_unique_cv_writer(op_array, opline->op1.var); + if (cv_writer && cv_writer->opcode == ZEND_ASSIGN + && (cv_writer->op2_type == IS_TMP_VAR || cv_writer->op2_type == IS_VAR)) { + const zend_op *src = zend_find_recent_tmp_writer( + op_array, cv_writer, cv_writer->op2.var); + if (src && src->opcode == ZEND_NEW) { + const zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( + script, op_array, src); + if (ce && ce->type == ZEND_USER_CLASS) { + zend_string *method_name = Z_STR_P(CRT_CONSTANT(opline->op2) + 1); + zend_function *fbc = zend_hash_find_ptr(&ce->function_table, method_name); + if (fbc) { + uint32_t flags = fbc->common.fn_flags; + if (flags & ZEND_ACC_PRIVATE) { + if (fbc->common.scope != op_array->scope) return NULL; + } else if (flags & ZEND_ACC_PROTECTED) { + if (!op_array->scope + || !instanceof_function(op_array->scope, fbc->common.scope)) { + return NULL; + } + } + return fbc; + } + } + } + } + } + break; + case ZEND_INIT_DYNAMIC_CALL: + /* `$f(...)` where $f's unique writer is `ASSIGN $f = "name"`. The + * literal string isn't normalized at compile time the way an + * INIT_FCALL_BY_NAME literal is, so lowercase it for the lookup. */ + if (opline->op2_type == IS_CV) { + const zend_op *cv_writer = zend_find_unique_cv_writer(op_array, opline->op2.var); + if (cv_writer && cv_writer->opcode == ZEND_ASSIGN + && cv_writer->op2_type == IS_CONST) { + const zval *val = CRT_CONSTANT_EX(op_array, cv_writer, cv_writer->op2); + if (Z_TYPE_P(val) == IS_STRING && Z_STRLEN_P(val) > 0 + && Z_STRVAL_P(val)[0] != '\\') { + zend_string *lc_name = zend_string_tolower(Z_STR_P(val)); + zend_function *func; + zval *func_zv; + zend_function *result = NULL; + if (script && (func = zend_hash_find_ptr(&script->function_table, lc_name)) != NULL) { + result = func; + } else if ((func_zv = zend_hash_find(EG(function_table), lc_name)) != NULL) { + if (!zend_optimizer_ignore_function(func_zv, op_array->filename)) { + result = Z_PTR_P(func_zv); + } + } + zend_string_release_ex(lc_name, 0); + if (result) return result; + } + } } break; case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL: { - zend_class_entry *scope = op_array->scope; + const 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; + const 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); + const zend_property_info *prop_info = zend_get_property_info(parent_scope, prop_name, /* silent */ true); if (prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO @@ -998,7 +1145,7 @@ zend_function *zend_optimizer_get_called_func( } case ZEND_NEW: { - zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( + const zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( script, op_array, opline); if (ce && ce->type == ZEND_USER_CLASS) { return ce->constructor; @@ -1009,7 +1156,7 @@ zend_function *zend_optimizer_get_called_func( return NULL; } -uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args) { +uint32_t zend_optimizer_classify_function(const zend_string *name, uint32_t num_args) { if (zend_string_equals_literal(name, "extract")) { return ZEND_FUNC_INDIRECT_VAR_ACCESS; } else if (zend_string_equals_literal(name, "compact")) { @@ -1161,12 +1308,12 @@ static void zend_optimize(zend_op_array *op_array, static void zend_revert_pass_two(zend_op_array *op_array) { - zend_op *opline, *end; + zend_op *opline; ZEND_ASSERT((op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) != 0); opline = op_array->opcodes; - end = opline + op_array->last; + const zend_op *end = opline + op_array->last; while (opline < end) { if (opline->op1_type == IS_CONST) { ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline, opline->op1); @@ -1299,7 +1446,7 @@ static void zend_redo_pass_two(zend_op_array *op_array) op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO; } -static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) +static void zend_redo_pass_two_ex(zend_op_array *op_array, const zend_ssa *ssa) { zend_op *opline, *end; #if ZEND_USE_ABS_JMP_ADDR && !ZEND_USE_ABS_CONST_ADDR @@ -1328,7 +1475,7 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { - zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; + const zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; uint32_t op1_info = opline->op1_type == IS_UNUSED ? 0 : (OP1_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY)); uint32_t op2_info = opline->op1_type == IS_UNUSED ? 0 : (OP2_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY)); uint32_t res_info = @@ -1458,13 +1605,13 @@ static void zend_optimize_op_array(zend_op_array *op_array, } } -static void zend_adjust_fcall_stack_size(zend_op_array *op_array, zend_optimizer_ctx *ctx) +static void zend_adjust_fcall_stack_size(const zend_op_array *op_array, const zend_optimizer_ctx *ctx) { zend_function *func; - zend_op *opline, *end; + zend_op *opline; opline = op_array->opcodes; - end = opline + op_array->last; + const zend_op* end = opline + op_array->last; while (opline < end) { if (opline->opcode == ZEND_INIT_FCALL) { func = zend_hash_find_ptr( @@ -1478,12 +1625,12 @@ static void zend_adjust_fcall_stack_size(zend_op_array *op_array, zend_optimizer } } -static void zend_adjust_fcall_stack_size_graph(zend_op_array *op_array) +static void zend_adjust_fcall_stack_size_graph(const zend_op_array *op_array) { - zend_func_info *func_info = ZEND_FUNC_INFO(op_array); + const zend_func_info *func_info = ZEND_FUNC_INFO(op_array); if (func_info) { - zend_call_info *call_info =func_info->callee_info; + const zend_call_info *call_info =func_info->callee_info; while (call_info) { zend_op *opline = call_info->caller_init_opline; @@ -1497,13 +1644,13 @@ static void zend_adjust_fcall_stack_size_graph(zend_op_array *op_array) } } -static bool needs_live_range(zend_op_array *op_array, zend_op *def_opline) { - zend_func_info *func_info = ZEND_FUNC_INFO(op_array); - zend_ssa_op *ssa_op = &func_info->ssa.ops[def_opline - op_array->opcodes]; +static bool needs_live_range(const zend_op_array *op_array, const zend_op *def_opline) { + const zend_func_info *func_info = ZEND_FUNC_INFO(op_array); + const zend_ssa_op *ssa_op = &func_info->ssa.ops[def_opline - op_array->opcodes]; int ssa_var = ssa_op->result_def; if (ssa_var < 0) { /* Be conservative. */ - return 1; + return true; } /* If the variable is used by a PHI, this may be the assignment of the final branch of a @@ -1540,7 +1687,7 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void if (Z_TYPE_P(zv) == IS_ALIAS_PTR) { continue; } - zend_class_entry *ce = Z_CE_P(zv); + const zend_class_entry *ce = Z_CE_P(zv); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (op_array->scope == ce && op_array->type == ZEND_USER_FUNCTION @@ -1555,7 +1702,7 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void 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]; + const 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); } @@ -1606,7 +1753,7 @@ ZEND_API void zend_optimize_script(zend_script *script, zend_long optimization_l zend_call_graph call_graph; zend_build_call_graph(&ctx.arena, script, &call_graph); - int i; + uint32_t i; zend_func_info *func_info; for (i = 0; i < call_graph.op_arrays_count; i++) { @@ -1715,22 +1862,57 @@ ZEND_API void zend_optimize_script(zend_script *script, zend_long optimization_l if (Z_TYPE_P(zv) == IS_ALIAS_PTR) { continue; } - zend_class_entry *ce = Z_CE_P(zv); + const zend_class_entry *ce = Z_CE_P(zv); ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) { if (op_array->scope != ce && op_array->type == ZEND_USER_FUNCTION) { - zend_op_array *orig_op_array = + const zend_op_array *orig_op_array = zend_hash_find_ptr(&op_array->scope->function_table, name); ZEND_ASSERT(orig_op_array != NULL); if (orig_op_array != op_array) { uint32_t fn_flags = op_array->fn_flags; + uint32_t fn_flags2 = op_array->fn_flags2; zend_function *prototype = op_array->prototype; HashTable *ht = op_array->static_variables; + zend_arg_info *arg_info = op_array->arg_info; + bool arg_info_substituted = (arg_info != orig_op_array->arg_info); *op_array = *orig_op_array; op_array->fn_flags = fn_flags; + op_array->fn_flags2 = fn_flags2; op_array->prototype = prototype; op_array->static_variables = ht; + if (arg_info_substituted) { + op_array->arg_info = arg_info; + } + } + } + } ZEND_HASH_FOREACH_END(); + + zend_property_info *prop; + ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, name, prop) { + if (!(prop->flags & ZEND_ACC_GENERIC_CLONE) || !prop->hooks) { + continue; + } + + const zend_property_info *parent_prop = zend_hash_find_ptr(&prop->ce->properties_info, name); + if (!parent_prop || !parent_prop->hooks) { + continue; + } + + for (uint32_t hi = 0; hi < ZEND_PROPERTY_HOOK_COUNT; hi++) { + zend_function *clone_hook = prop->hooks[hi]; + zend_function *parent_hook = parent_prop->hooks[hi]; + if (!clone_hook || !parent_hook || clone_hook == parent_hook) { + continue; + } + + zend_arg_info *arg_info = clone_hook->op_array.arg_info; + bool arg_info_substituted = (arg_info != parent_hook->op_array.arg_info); + + clone_hook->op_array = parent_hook->op_array; + if (arg_info_substituted) { + clone_hook->op_array.arg_info = arg_info; } } } ZEND_HASH_FOREACH_END(); diff --git a/Zend/Optimizer/zend_optimizer.h b/Zend/Optimizer/zend_optimizer.h index 16bfd75520d8..d2847c92869c 100644 --- a/Zend/Optimizer/zend_optimizer.h +++ b/Zend/Optimizer/zend_optimizer.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -98,6 +96,10 @@ 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 diff --git a/Zend/Optimizer/zend_optimizer_internal.h b/Zend/Optimizer/zend_optimizer_internal.h index a1fc57092d17..d01df56260bc 100644 --- a/Zend/Optimizer/zend_optimizer_internal.h +++ b/Zend/Optimizer/zend_optimizer_internal.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -78,17 +76,17 @@ static inline bool zend_optimizer_is_loop_var_free(const zend_op *opline) { || (opline->opcode == ZEND_FREE && opline->extended_value == ZEND_FREE_SWITCH); } -void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline); -int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv); -bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy); -void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value); -bool zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value); +void zend_optimizer_convert_to_free_op1(const zend_op_array *op_array, zend_op *opline); +uint32_t zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv); +bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, bool copy); +void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, const zval *name, zval* value); +bool zend_optimizer_get_collected_constant(const HashTable *constants, const zval *name, zval* value); zend_result zend_optimizer_eval_binary_op(zval *result, uint8_t opcode, zval *op1, zval *op2); zend_result zend_optimizer_eval_unary_op(zval *result, uint8_t opcode, zval *op1); zend_result zend_optimizer_eval_cast(zval *result, uint32_t type, zval *op1); zend_result zend_optimizer_eval_strlen(zval *result, const zval *op1); zend_result zend_optimizer_eval_special_func_call( - zval *result, zend_string *name, zend_string *arg); + zval *result, const zend_string *name, zend_string *arg); bool zend_optimizer_update_op1_const(zend_op_array *op_array, zend_op *opline, zval *val); @@ -120,15 +118,12 @@ void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx); void zend_optimizer_compact_vars(zend_op_array *op_array); zend_function *zend_optimizer_get_called_func( - zend_script *script, zend_op_array *op_array, zend_op *opline, bool *is_prototype); -uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args); -void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline); -void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist); -int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map); + const zend_script *script, const zend_op_array *op_array, zend_op *opline, bool *is_prototype); +uint32_t zend_optimizer_classify_function(const zend_string *name, uint32_t num_args); +void zend_optimizer_migrate_jump(const zend_op_array *op_array, zend_op *new_opline, zend_op *opline); +void zend_optimizer_shift_jump(const zend_op_array *op_array, zend_op *opline, const uint32_t *shiftlist); +uint32_t sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, zend_call_info **call_map); 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 diff --git a/Zend/Optimizer/zend_ssa.c b/Zend/Optimizer/zend_ssa.c index 4c09e5e105b5..fa2901b89421 100644 --- a/Zend/Optimizer/zend_ssa.c +++ b/Zend/Optimizer/zend_ssa.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SSA - Static Single Assignment Form | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Nikita Popov | @@ -22,6 +20,7 @@ #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) { @@ -34,8 +33,7 @@ static bool dominates(const zend_basic_block *blocks, int a, int b) { static bool will_rejoin( const zend_cfg *cfg, const zend_dfg *dfg, const zend_basic_block *block, int other_successor, int exclude, int var) { - int i; - for (i = 0; i < block->predecessors_count; i++) { + for (uint32_t i = 0; i < block->predecessors_count; i++) { int predecessor = cfg->predecessors[block->predecessor_offset + i]; if (predecessor == exclude) { continue; @@ -51,10 +49,10 @@ static bool will_rejoin( /* The other successor dominates this predecessor, * so we will get the original value from it. */ if (dominates(cfg->blocks, other_successor, predecessor)) { - return 1; + return true; } } - return 0; + return false; } static bool needs_pi(const zend_op_array *op_array, const zend_dfg *dfg, const zend_ssa *ssa, int from, int to, int var) /* {{{ */ @@ -64,7 +62,7 @@ static bool needs_pi(const zend_op_array *op_array, const zend_dfg *dfg, const z if (!DFG_ISSET(dfg->in, dfg->size, to, var)) { /* Variable is not live, certainly won't benefit from pi */ - return 0; + return false; } /* Make sure that both successors of the from block aren't the same. Pi nodes are associated @@ -72,13 +70,13 @@ static bool needs_pi(const zend_op_array *op_array, const zend_dfg *dfg, const z from_block = &ssa->cfg.blocks[from]; ZEND_ASSERT(from_block->successors_count == 2); if (from_block->successors[0] == from_block->successors[1]) { - return 0; + return false; } to_block = &ssa->cfg.blocks[to]; if (to_block->predecessors_count == 1) { /* Always place pi if one predecessor (an if branch) */ - return 1; + return true; } /* Check whether we will rejoin with the original value coming from the other successor, @@ -90,7 +88,7 @@ static bool needs_pi(const zend_op_array *op_array, const zend_dfg *dfg, const z /* }}} */ static zend_ssa_phi *add_pi( - zend_arena **arena, const zend_op_array *op_array, zend_dfg *dfg, zend_ssa *ssa, + zend_arena **arena, const zend_op_array *op_array, const zend_dfg *dfg, const zend_ssa *ssa, int from, int to, int var) /* {{{ */ { zend_ssa_phi *phi; @@ -130,7 +128,7 @@ static zend_ssa_phi *add_pi( static void pi_range( zend_ssa_phi *phi, int min_var, int max_var, zend_long min, zend_long max, - char underflow, char overflow, char negative) /* {{{ */ + bool underflow, bool overflow, bool negative) /* {{{ */ { zend_ssa_range_constraint *constraint = &phi->constraint.range; constraint->min_var = min_var; @@ -147,16 +145,16 @@ static void pi_range( /* }}} */ static inline void pi_range_equals(zend_ssa_phi *phi, int var, zend_long val) { - pi_range(phi, var, var, val, val, 0, 0, 0); + pi_range(phi, var, var, val, val, false, false, false); } static inline void pi_range_not_equals(zend_ssa_phi *phi, int var, zend_long val) { - pi_range(phi, var, var, val, val, 0, 0, 1); + pi_range(phi, var, var, val, val, false, false, true); } static inline void pi_range_min(zend_ssa_phi *phi, int var, zend_long val) { - pi_range(phi, var, -1, val, ZEND_LONG_MAX, 0, 1, 0); + pi_range(phi, var, -1, val, ZEND_LONG_MAX, false, true, false); } static inline void pi_range_max(zend_ssa_phi *phi, int var, zend_long val) { - pi_range(phi, -1, var, ZEND_LONG_MIN, val, 1, 0, 0); + pi_range(phi, -1, var, ZEND_LONG_MIN, val, true, false, false); } static void pi_type_mask(zend_ssa_phi *phi, uint32_t type_mask) { @@ -240,10 +238,10 @@ static int find_adjusted_tmp_var(const zend_op_array *op_array, uint32_t build_f */ static void place_essa_pis( zend_arena **arena, const zend_script *script, const zend_op_array *op_array, - uint32_t build_flags, zend_ssa *ssa, zend_dfg *dfg) /* {{{ */ { - zend_basic_block *blocks = ssa->cfg.blocks; - int j, blocks_count = ssa->cfg.blocks_count; - for (j = 0; j < blocks_count; j++) { + uint32_t build_flags, const zend_ssa *ssa, const zend_dfg *dfg) /* {{{ */ { + const zend_basic_block *blocks = ssa->cfg.blocks; + uint32_t blocks_count = ssa->cfg.blocks_count; + for (uint32_t j = 0; j < blocks_count; j++) { zend_ssa_phi *pi; zend_op *opline = op_array->opcodes + blocks[j].start + blocks[j].len - 1; int bt; /* successor block number if a condition is true */ @@ -816,23 +814,13 @@ ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *op } /* }}} */ -static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */ +static void zend_ssa_rename_in_block(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; + const zend_basic_block *blocks = ssa->cfg.blocks; + const zend_ssa_block *ssa_blocks = ssa->blocks; zend_ssa_op *ssa_ops = ssa->ops; 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; - } + const zend_op *opline, *end; if (ssa_blocks[n].phis) { zend_ssa_phi *phi = ssa_blocks[n].phis; @@ -857,11 +845,11 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build } } - zend_ssa_op *fe_fetch_ssa_op = blocks[n].len != 0 + const zend_ssa_op *fe_fetch_ssa_op = blocks[n].len != 0 && ((end-1)->opcode == ZEND_FE_FETCH_R || (end-1)->opcode == ZEND_FE_FETCH_RW) && (end-1)->op2_type == IS_CV ? &ssa_ops[blocks[n].start + blocks[n].len - 1] : NULL; - for (i = 0; i < blocks[n].successors_count; i++) { + for (uint32_t i = 0; i < blocks[n].successors_count; i++) { int succ = blocks[n].successors[i]; zend_ssa_phi *p; for (p = ssa_blocks[succ].phis; p; p = p->next) { @@ -875,7 +863,7 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build p->constraint.range.max_ssa_var = var[p->constraint.range.max_var]; } } - for (j = 0; j < blocks[succ].predecessors_count; j++) { + for (uint32_t j = 0; j < blocks[succ].predecessors_count; j++) { p->sources[j] = var[p->var]; } if (p->ssa_var < 0) { @@ -884,6 +872,7 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build } } else if (p->pi < 0) { /* Normal Phi */ + uint32_t j; for (j = 0; j < blocks[succ].predecessors_count; j++) if (ssa->cfg.predecessors[blocks[succ].predecessor_offset + j] == n) { break; @@ -901,6 +890,7 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build zend_ssa_phi *q = p->next; while (q) { if (q->pi < 0 && q->var == p->var) { + uint32_t j; for (j = 0; j < blocks[succ].predecessors_count; j++) { if (ssa->cfg.predecessors[blocks[succ].predecessor_offset + j] == n) { break; @@ -916,32 +906,100 @@ static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build } ssa->vars_count = ssa_vars_count; +} +/* }}} */ - 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; +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--; + } + } } - if (tmp) { - free_alloca(tmp, use_heap); - } + free_alloca(save_vars, save_vars_use_heap); + ZEND_WORKLIST_STACK_FREE_ALLOCA(&work, work_use_heap); return SUCCESS; } -/* }}} */ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa) /* {{{ */ { - zend_basic_block *blocks = ssa->cfg.blocks; + const zend_basic_block *blocks = ssa->cfg.blocks; zend_ssa_block *ssa_blocks; - int blocks_count = ssa->cfg.blocks_count; + uint32_t blocks_count = ssa->cfg.blocks_count; uint32_t set_size; zend_bitset def, in, phi; int *var = NULL; - int i, j, k, changed; + int i, j, changed; zend_dfg dfg; ALLOCA_FLAG(dfg_use_heap) ALLOCA_FLAG(var_use_heap) @@ -996,7 +1054,7 @@ ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *scrip register allocator depends on this property. */ zend_bitset_union(phi_j, in + (j * set_size), set_size); } else { - for (k = 0; k < blocks[j].predecessors_count; k++) { + for (uint32_t k = 0; k < blocks[j].predecessors_count; k++) { i = ssa->cfg.predecessors[blocks[j].predecessor_offset + k]; while (i != -1 && i != blocks[j].idom) { zend_bitset_union_with_intersection( @@ -1163,9 +1221,7 @@ ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_ } } } else { - int j; - - for (j = 0; j < ssa->cfg.blocks[i].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[i].predecessors_count; j++) { zend_ssa_phi *p; ZEND_ASSERT(phi->sources[j] >= 0); @@ -1199,7 +1255,7 @@ ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_ } /* }}} */ -void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var) /* {{{ */ +void zend_ssa_unlink_use_chain(const zend_ssa *ssa, int op, int var) /* {{{ */ { if (ssa->vars[var].use_chain == op) { ssa->vars[var].use_chain = zend_ssa_next_use(ssa->ops, var, op); @@ -1238,7 +1294,7 @@ void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var) /* {{{ */ } /* }}} */ -void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var) /* {{{ */ +void zend_ssa_replace_use_chain(const zend_ssa *ssa, int op, int new_op, int var) /* {{{ */ { if (ssa->vars[var].use_chain == op) { ssa->vars[var].use_chain = new_op; @@ -1278,7 +1334,7 @@ void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var) /* { } /* }}} */ -void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op) /* {{{ */ +void zend_ssa_remove_instr(const zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op) /* {{{ */ { if (ssa_op->result_use >= 0) { zend_ssa_unlink_use_chain(ssa, ssa_op - ssa->ops, ssa_op->result_use); @@ -1309,13 +1365,12 @@ void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op) } /* }}} */ -static inline zend_ssa_phi **zend_ssa_next_use_phi_ptr(zend_ssa *ssa, int var, zend_ssa_phi *p) /* {{{ */ +static inline zend_ssa_phi **zend_ssa_next_use_phi_ptr(const zend_ssa *ssa, int var, zend_ssa_phi *p) /* {{{ */ { if (p->pi >= 0) { return &p->use_chains[0]; } else { - int j; - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { if (p->sources[j] == var) { return &p->use_chains[j]; } @@ -1328,7 +1383,7 @@ static inline zend_ssa_phi **zend_ssa_next_use_phi_ptr(zend_ssa *ssa, int var, z /* May be called even if source is not used in the phi (useful when removing uses in a phi * with multiple identical operands) */ -static inline void zend_ssa_remove_use_of_phi_source(zend_ssa *ssa, zend_ssa_phi *phi, int source, zend_ssa_phi *next_use_phi) /* {{{ */ +static inline void zend_ssa_remove_use_of_phi_source(const zend_ssa *ssa, const zend_ssa_phi *phi, int source, zend_ssa_phi *next_use_phi) /* {{{ */ { zend_ssa_phi **cur = &ssa->vars[source].phi_use_chain; while (*cur && *cur != phi) { @@ -1340,7 +1395,7 @@ static inline void zend_ssa_remove_use_of_phi_source(zend_ssa *ssa, zend_ssa_phi } /* }}} */ -static void zend_ssa_remove_uses_of_phi_sources(zend_ssa *ssa, zend_ssa_phi *phi) /* {{{ */ +static void zend_ssa_remove_uses_of_phi_sources(const zend_ssa *ssa, zend_ssa_phi *phi) /* {{{ */ { int source; FOREACH_PHI_SOURCE(phi, source) { @@ -1349,7 +1404,7 @@ static void zend_ssa_remove_uses_of_phi_sources(zend_ssa *ssa, zend_ssa_phi *phi } /* }}} */ -static void zend_ssa_remove_phi_from_block(zend_ssa *ssa, zend_ssa_phi *phi) /* {{{ */ +static void zend_ssa_remove_phi_from_block(const zend_ssa *ssa, const zend_ssa_phi *phi) /* {{{ */ { zend_ssa_block *block = &ssa->blocks[phi->block]; zend_ssa_phi **cur = &block->phis; @@ -1378,9 +1433,9 @@ void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op) /* {{{ */ } /* }}} */ -static inline void zend_ssa_remove_phi_source(zend_ssa *ssa, zend_ssa_phi *phi, int pred_offset, int predecessors_count) /* {{{ */ +static inline void zend_ssa_remove_phi_source(const zend_ssa *ssa, const zend_ssa_phi *phi, int pred_offset, uint32_t predecessors_count) /* {{{ */ { - int j, var_num = phi->sources[pred_offset]; + int var_num = phi->sources[pred_offset]; zend_ssa_phi *next_phi = phi->use_chains[pred_offset]; predecessors_count--; @@ -1391,7 +1446,7 @@ static inline void zend_ssa_remove_phi_source(zend_ssa *ssa, zend_ssa_phi *phi, /* Check if they same var is used in a different phi operand as well, in this case we don't * need to adjust the use chain (but may have to move the next pointer). */ - for (j = 0; j < predecessors_count; j++) { + for (uint32_t j = 0; j < predecessors_count; j++) { if (phi->sources[j] == var_num) { if (j < pred_offset) { ZEND_ASSERT(next_phi == NULL); @@ -1407,7 +1462,7 @@ static inline void zend_ssa_remove_phi_source(zend_ssa *ssa, zend_ssa_phi *phi, } /* }}} */ -void zend_ssa_remove_phi(zend_ssa *ssa, zend_ssa_phi *phi) /* {{{ */ +void zend_ssa_remove_phi(const zend_ssa *ssa, zend_ssa_phi *phi) /* {{{ */ { ZEND_ASSERT(phi->ssa_var >= 0); ZEND_ASSERT(ssa->vars[phi->ssa_var].use_chain < 0 @@ -1419,14 +1474,14 @@ void zend_ssa_remove_phi(zend_ssa *ssa, zend_ssa_phi *phi) /* {{{ */ } /* }}} */ -void zend_ssa_remove_uses_of_var(zend_ssa *ssa, int var_num) /* {{{ */ +void zend_ssa_remove_uses_of_var(const zend_ssa *ssa, int var_num) /* {{{ */ { zend_ssa_var *var = &ssa->vars[var_num]; zend_ssa_phi *phi; int use; FOREACH_PHI_USE(var, phi) { - int i, end = NUM_PHI_SOURCES(phi); - for (i = 0; i < end; i++) { + uint32_t end = NUM_PHI_SOURCES(phi); + for (uint32_t i = 0; i < end; i++) { if (phi->sources[i] == var_num) { phi->use_chains[i] = NULL; } @@ -1455,15 +1510,14 @@ void zend_ssa_remove_uses_of_var(zend_ssa *ssa, int var_num) /* {{{ */ void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to) /* {{{ */ { zend_basic_block *next_block = &ssa->cfg.blocks[to]; - zend_ssa_block *next_ssa_block = &ssa->blocks[to]; + const zend_ssa_block *next_ssa_block = &ssa->blocks[to]; zend_ssa_phi *phi; - int j; /* Find at which predecessor offset this block is referenced */ int pred_offset = -1; int *predecessors = &ssa->cfg.predecessors[next_block->predecessor_offset]; - for (j = 0; j < next_block->predecessors_count; j++) { + for (uint32_t j = 0; j < next_block->predecessors_count; j++) { if (predecessors[j] == from) { pred_offset = j; break; @@ -1480,7 +1534,7 @@ void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to) /* {{{ */ for (phi = next_ssa_block->phis; phi; phi = phi->next) { if (phi->pi >= 0) { if (phi->pi == from) { - zend_ssa_rename_var_uses(ssa, phi->ssa_var, phi->sources[0], /* update_types */ 0); + zend_ssa_rename_var_uses(ssa, phi->ssa_var, phi->sources[0], /* update_types */ false); zend_ssa_remove_phi(ssa, phi); } } else { @@ -1498,10 +1552,10 @@ void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to) /* {{{ */ } /* }}} */ -void zend_ssa_remove_block(zend_op_array *op_array, zend_ssa *ssa, int i) /* {{{ */ +void zend_ssa_remove_block(const zend_op_array *op_array, zend_ssa *ssa, uint32_t i) /* {{{ */ { zend_basic_block *block = &ssa->cfg.blocks[i]; - zend_ssa_block *ssa_block = &ssa->blocks[i]; + const zend_ssa_block *ssa_block = &ssa->blocks[i]; zend_ssa_phi *phi; int j; @@ -1531,7 +1585,8 @@ void zend_ssa_remove_block_from_cfg(zend_ssa *ssa, int i) /* {{{ */ { zend_basic_block *block = &ssa->cfg.blocks[i]; int *predecessors; - int j, s; + int j; + uint32_t s; for (s = 0; s < block->successors_count; s++) { zend_ssa_remove_predecessor(ssa, i, block->successors[s]); @@ -1611,15 +1666,15 @@ void zend_ssa_rename_var_uses(zend_ssa *ssa, int old, int new, bool update_types /* If the op already uses the new var, don't add the op to the use * list again. Instead move the use_chain to the correct operand. */ - bool add_to_use_chain = 1; + bool add_to_use_chain = true; if (ssa_op->result_use == new) { - add_to_use_chain = 0; + add_to_use_chain = false; } else if (ssa_op->op1_use == new) { if (ssa_op->result_use == old) { ssa_op->res_use_chain = ssa_op->op1_use_chain; ssa_op->op1_use_chain = -1; } - add_to_use_chain = 0; + add_to_use_chain = false; } else if (ssa_op->op2_use == new) { if (ssa_op->result_use == old) { ssa_op->res_use_chain = ssa_op->op2_use_chain; @@ -1628,7 +1683,7 @@ void zend_ssa_rename_var_uses(zend_ssa *ssa, int old, int new, bool update_types ssa_op->op1_use_chain = ssa_op->op2_use_chain; ssa_op->op2_use_chain = -1; } - add_to_use_chain = 0; + add_to_use_chain = false; } /* Perform the actual renaming */ @@ -1662,8 +1717,8 @@ void zend_ssa_rename_var_uses(zend_ssa *ssa, int old, int new, bool update_types /* Update phi use chains */ FOREACH_PHI_USE(old_var, phi) { - int j; - bool after_first_new_source = 0; + uint32_t j; + bool after_first_new_source = false; /* If the phi already uses the new var, find its use chain, as we may * need to move it to a different source operand. */ @@ -1677,7 +1732,7 @@ void zend_ssa_rename_var_uses(zend_ssa *ssa, int old, int new, bool update_types for (j = 0; j < ssa->cfg.blocks[phi->block].predecessors_count; j++) { if (phi->sources[j] == new) { - after_first_new_source = 1; + after_first_new_source = true; } else if (phi->sources[j] == old) { phi->sources[j] = new; @@ -1691,7 +1746,7 @@ void zend_ssa_rename_var_uses(zend_ssa *ssa, int old, int new, bool update_types phi->use_chains[j] = new_var->phi_use_chain; new_var->phi_use_chain = phi; } - after_first_new_source = 1; + after_first_new_source = true; } else { phi->use_chains[j] = NULL; } diff --git a/Zend/Optimizer/zend_ssa.h b/Zend/Optimizer/zend_ssa.h index 5995adcb1498..ee9faf9bfd23 100644 --- a/Zend/Optimizer/zend_ssa.h +++ b/Zend/Optimizer/zend_ssa.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine, SSA - Static Single Assignment Form | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -66,7 +64,7 @@ struct _zend_ssa_phi { zend_ssa_pi_constraint constraint; /* e-SSA Pi constraint */ int var; /* Original CV, VAR or TMP variable index */ int ssa_var; /* SSA variable index */ - int block; /* current BB index */ + uint32_t block; /* current BB index */ bool has_range_constraint; zend_ssa_phi **use_chains; zend_ssa_phi *sym_use_chain; @@ -147,15 +145,15 @@ BEGIN_EXTERN_C() ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa); ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa); ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *opline, uint32_t k, uint32_t build_flags, int ssa_vars_count, zend_ssa_op *ssa_ops, int *var); -void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var); -void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var); +void zend_ssa_unlink_use_chain(const zend_ssa *ssa, int op, int var); +void zend_ssa_replace_use_chain(const zend_ssa *ssa, int op, int new_op, int var); void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to); void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op); -void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op); -void zend_ssa_remove_phi(zend_ssa *ssa, zend_ssa_phi *phi); -void zend_ssa_remove_uses_of_var(zend_ssa *ssa, int var_num); -void zend_ssa_remove_block(zend_op_array *op_array, zend_ssa *ssa, int b); +void zend_ssa_remove_instr(const zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op); +void zend_ssa_remove_phi(const zend_ssa *ssa, zend_ssa_phi *phi); +void zend_ssa_remove_uses_of_var(const zend_ssa *ssa, int var_num); +void zend_ssa_remove_block(const zend_op_array *op_array, zend_ssa *ssa, uint32_t b); void zend_ssa_rename_var_uses(zend_ssa *ssa, int old_var, int new_var, bool update_types); void zend_ssa_remove_block_from_cfg(zend_ssa *ssa, int b); @@ -207,8 +205,7 @@ static zend_always_inline zend_ssa_phi* zend_ssa_next_use_phi(const zend_ssa *ss if (p->pi >= 0) { return p->use_chains[0]; } else { - int j; - for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { + for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) { if (p->sources[j] == var) { return p->use_chains[j]; } @@ -240,21 +237,21 @@ static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend /* Rename def to use if possible. Mark variable as not defined otherwise. */ if (ssa_op->op1_def >= 0) { if (ssa_op->op1_use >= 0) { - zend_ssa_rename_var_uses(ssa, ssa_op->op1_def, ssa_op->op1_use, 1); + zend_ssa_rename_var_uses(ssa, ssa_op->op1_def, ssa_op->op1_use, true); } ssa->vars[ssa_op->op1_def].definition = -1; ssa_op->op1_def = -1; } if (ssa_op->op2_def >= 0) { if (ssa_op->op2_use >= 0) { - zend_ssa_rename_var_uses(ssa, ssa_op->op2_def, ssa_op->op2_use, 1); + zend_ssa_rename_var_uses(ssa, ssa_op->op2_def, ssa_op->op2_use, true); } ssa->vars[ssa_op->op2_def].definition = -1; ssa_op->op2_def = -1; } if (ssa_op->result_def >= 0) { if (ssa_op->result_use >= 0) { - zend_ssa_rename_var_uses(ssa, ssa_op->result_def, ssa_op->result_use, 1); + zend_ssa_rename_var_uses(ssa, ssa_op->result_def, ssa_op->result_use, true); } ssa->vars[ssa_op->result_def].definition = -1; ssa_op->result_def = -1; @@ -285,7 +282,7 @@ static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend #define FOREACH_PHI_SOURCE(phi, source) do { \ zend_ssa_phi *_phi = (phi); \ - int _i, _end = NUM_PHI_SOURCES(phi); \ + uint32_t _i, _end = NUM_PHI_SOURCES(phi); \ for (_i = 0; _i < _end; _i++) { \ ZEND_ASSERT(_phi->sources[_i] >= 0); \ source = _phi->sources[_i]; @@ -294,8 +291,7 @@ static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend } while (0) #define FOREACH_PHI(phi) do { \ - int _i; \ - for (_i = 0; _i < ssa->cfg.blocks_count; _i++) { \ + for (uint32_t _i = 0; _i < ssa->cfg.blocks_count; _i++) { \ phi = ssa->blocks[_i].phis; \ for (; phi; phi = phi->next) { #define FOREACH_PHI_END() \ @@ -304,8 +300,7 @@ static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend } while (0) #define FOREACH_BLOCK(block) do { \ - int _i; \ - for (_i = 0; _i < ssa->cfg.blocks_count; _i++) { \ + for (uint32_t _i = 0; _i < ssa->cfg.blocks_count; _i++) { \ (block) = &ssa->cfg.blocks[_i]; \ if (!((block)->flags & ZEND_BB_REACHABLE)) { \ continue; \ diff --git a/Zend/Optimizer/zend_worklist.h b/Zend/Optimizer/zend_worklist.h index f47d01bd1579..ea03048e9756 100644 --- a/Zend/Optimizer/zend_worklist.h +++ b/Zend/Optimizer/zend_worklist.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andy Wingo | +----------------------------------------------------------------------+ @@ -97,12 +95,12 @@ static inline bool zend_worklist_push(zend_worklist *worklist, int i) ZEND_ASSERT(i >= 0 && i < worklist->stack.capacity); if (zend_bitset_in(worklist->visited, i)) { - return 0; + return false; } zend_bitset_incl(worklist->visited, i); zend_worklist_stack_push(&worklist->stack, i); - return 1; + return true; } static inline int zend_worklist_peek(const zend_worklist *worklist) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 45791a34c5f8..d0c682e8e659 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -118,7 +118,7 @@ dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name. dnl AC_DEFUN([ZEND_DLSYM_CHECK], [dnl AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names]) -_LT_AC_TRY_DLOPEN_SELF([AC_MSG_RESULT([no])], [ +_LT_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.]) @@ -149,6 +149,7 @@ AC_CHECK_FUNCS(m4_normalize([ pthread_get_stackaddr_np pthread_getattr_np pthread_stackseg_np + strnlen ])) AC_CHECK_DECL([clock_gettime_nsec_np], @@ -169,6 +170,7 @@ ZEND_CHECK_STACK_DIRECTION ZEND_CHECK_FLOAT_PRECISION ZEND_DLSYM_CHECK ZEND_CHECK_GLOBAL_REGISTER_VARIABLES +ZEND_CHECK_PRESERVE_NONE ZEND_CHECK_CPUID_COUNT AC_MSG_CHECKING([whether to enable thread safety]) @@ -192,28 +194,21 @@ AS_VAR_IF([GCC], [yes], dnl Check if compiler supports -Wno-clobbered (only GCC). AX_CHECK_COMPILE_FLAG([-Wno-clobbered], - [CFLAGS="-Wno-clobbered $CFLAGS"],, - [-Werror]) + [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"],, - [-Werror]) + [CFLAGS="$CFLAGS -Wimplicit-fallthrough=1"]) AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], - [CFLAGS="-Wduplicated-cond $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wduplicated-cond $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-Wlogical-op], - [CFLAGS="-Wlogical-op $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wlogical-op $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-Wformat-truncation], - [CFLAGS="-Wformat-truncation $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wformat-truncation $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], - [CFLAGS="-Wstrict-prototypes $CFLAGS"],, - [-Werror]) + [CFLAGS="-Wstrict-prototypes $CFLAGS"]) AX_CHECK_COMPILE_FLAG([-fno-common], - [CFLAGS="-fno-common $CFLAGS"],, - [-Werror]) + [CFLAGS="-fno-common $CFLAGS"]) ZEND_CHECK_ALIGNMENT ZEND_CHECK_SIGNALS @@ -470,3 +465,111 @@ AS_VAR_IF([ZEND_MAX_EXECUTION_TIMERS], [yes], AC_MSG_CHECKING([whether to enable Zend max execution timers]) AC_MSG_RESULT([$ZEND_MAX_EXECUTION_TIMERS]) ]) + +dnl +dnl ZEND_CHECK_PRESERVE_NONE +dnl +dnl Check if the preserve_none calling convention is supported and matches our +dnl expectations. +dnl +AC_DEFUN([ZEND_CHECK_PRESERVE_NONE], [dnl + AC_CACHE_CHECK([for preserve_none calling convention], + [php_cv_preserve_none], + [AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include + +const char * const1 = "str1"; +const char * const2 = "str2"; +const char * const3 = "str3"; +uint64_t key = UINT64_C(0x9d7f71d2bd296364); + +uintptr_t _a = 0; +uintptr_t _b = 0; + +uintptr_t __attribute__((preserve_none,noinline,used)) fun(uintptr_t a, uintptr_t b) { + _a = a; + _b = b; + return (uintptr_t)const3; +} + +uintptr_t __attribute__((preserve_none)) test(void) { + uintptr_t ret; + +#if defined(__x86_64__) + __asm__ __volatile__( + /* XORing to make it unlikely the value exists in any other register */ + "movq %1, %%r12\n" + "xorq %3, %%r12\n" + "movq %2, %%r13\n" + "xorq %3, %%r13\n" + "xorq %%rax, %%rax\n" +#if defined(__APPLE__) + "call _fun\n" +#else + "call fun\n" +#endif + : "=a" (ret) + : "r" (const1), "r" (const2), "r" (key) + : "r12", "r13" + ); +#elif defined(__aarch64__) + __asm__ __volatile__( + /* XORing to make it unlikely the value exists in any other register */ + "eor x20, %1, %3\n" + "eor x21, %2, %3\n" + "eor x0, x0, x0\n" +#if defined(__APPLE__) + "bl _fun\n" +#else + "bl fun\n" +#endif + "mov %0, x0\n" + : "=r" (ret) + : "r" (const1), "r" (const2), "r" (key) + : "x0", "x21", "x22", "x30" + ); +#else +# error +#endif + + return ret; +} + +int main(void) { + + /* JIT is making the following expectations about preserve_none: + * - The registers used for integer args 1 and 2 + * - The register used for a single integer return value + * + * We check these expectations here: + */ + + uintptr_t ret = test(); + + if (_a != ((uintptr_t)const1 ^ key)) { + fprintf(stderr, "arg1 mismatch\n"); + return 1; + } + if (_b != ((uintptr_t)const2 ^ key)) { + fprintf(stderr, "arg2 mismatch\n"); + return 2; + } + if (ret != (uintptr_t)const3) { + fprintf(stderr, "ret mismatch\n"); + return 3; + } + + fprintf(stderr, "OK\n"); + + return 0; +}]])], + [php_cv_preserve_none=yes], + [php_cv_preserve_none=no], + [php_cv_preserve_none=no]) + ]) + AS_VAR_IF([php_cv_preserve_none], [yes], [ + AC_DEFINE([HAVE_PRESERVE_NONE], [1], + [Define to 1 if you have preserve_none support.]) + ]) +]) diff --git a/Zend/asm/jump_s390x_sysv_elf_gas.S b/Zend/asm/jump_s390x_sysv_elf_gas.S index c2a578b2663e..fa71467756d2 100644 --- a/Zend/asm/jump_s390x_sysv_elf_gas.S +++ b/Zend/asm/jump_s390x_sysv_elf_gas.S @@ -49,11 +49,12 @@ .type jump_fcontext, @function #define ARG_OFFSET 0 -#define GR_OFFSET 16 -#define FP_OFFSET 96 -#define FPC_OFFSET 160 -#define PC_OFFSET 168 -#define CONTEXT_SIZE 176 +#define GR_OFFSET 16 +#define R14_OFFSET 88 +#define FP_OFFSET 96 +#define FPC_OFFSET 160 +#define PC_OFFSET 168 +#define CONTEXT_SIZE 176 #define REG_SAVE_AREA_SIZE 160 @@ -131,11 +132,14 @@ jump_fcontext: ltg %r2,GR_OFFSET(%r15) jnz use_return_slot - /* We restore a make_fcontext context. Use the function - argument slot in the context we just saved and allocate the - register save area for the target function. */ - la %r2,ARG_OFFSET(%r1) - aghi %r15,-REG_SAVE_AREA_SIZE + /* We're restoring a context created by make_fcontext. + This is going to be the argument of the entry point + of the fiber. We're placing it on top of the ABI + defined register save area of the fiber's own stack. */ + la %r2,REG_SAVE_AREA_SIZE(%r15) + + /* REG_SAVE_AREA_SIZE + sizeof(transfer_t) */ + aghi %r15,-(REG_SAVE_AREA_SIZE+16) use_return_slot: /* Save the two fields in transfer_t. When calling a diff --git a/Zend/asm/jump_sparc64_sysv_elf_gas.S b/Zend/asm/jump_sparc64_sysv_elf_gas.S index 727687aad804..61101fb1f629 100644 --- a/Zend/asm/jump_sparc64_sysv_elf_gas.S +++ b/Zend/asm/jump_sparc64_sysv_elf_gas.S @@ -6,12 +6,14 @@ */ /* - * typedef struct { - * void *handle; - * zend_fiber_transfer *transfer; - * } boost_context_data; + * typedef void* fcontext_t; * - * boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer); + * struct transfer_t { + * fcontext_t fctx; + * void * data; + * }; + * + * transfer_t jump_fcontext(fcontext_t const to, void *vp); */ #define CC64FSZ 176 #define BIAS 2047 diff --git a/Zend/asm/jump_x86_64_ms_pe_gas.S b/Zend/asm/jump_x86_64_ms_pe_gas.S index 5ebc46f36403..ec4ecfe946d3 100644 --- a/Zend/asm/jump_x86_64_ms_pe_gas.S +++ b/Zend/asm/jump_x86_64_ms_pe_gas.S @@ -89,6 +89,7 @@ .file "jump_x86_64_ms_pe_gas.asm" .text .p2align 4,,15 +.globl jump_fcontext .def jump_fcontext; .scl 2; .type 32; .endef .seh_proc jump_fcontext jump_fcontext: @@ -203,3 +204,6 @@ jump_fcontext: /* indirect jump to context */ jmp *%r10 .seh_endproc + +.section .drectve +.ascii " -export:\"jump_fcontext\"" diff --git a/Zend/asm/make_s390x_sysv_elf_gas.S b/Zend/asm/make_s390x_sysv_elf_gas.S index e7e2d5f6e0c9..4dd423e2a44c 100644 --- a/Zend/asm/make_s390x_sysv_elf_gas.S +++ b/Zend/asm/make_s390x_sysv_elf_gas.S @@ -49,12 +49,12 @@ .type make_fcontext, @function #define ARG_OFFSET 0 -#define GR_OFFSET 16 -#define R14_OFFSET 88 -#define FP_OFFSET 96 -#define FPC_OFFSET 160 -#define PC_OFFSET 168 -#define CONTEXT_SIZE 176 +#define GR_OFFSET 16 +#define R14_OFFSET 88 +#define FP_OFFSET 96 +#define FPC_OFFSET 160 +#define PC_OFFSET 168 +#define CONTEXT_SIZE 176 /* @@ -72,7 +72,7 @@ r4 - The address of the context function make_fcontext: .machine "z10" /* Align the stack to an 8 byte boundary. */ - nill %r2,0xfff0 + nill %r2,0xfff8 /* Allocate stack space for the context. */ aghi %r2,-CONTEXT_SIZE diff --git a/Zend/asm/make_sparc64_sysv_elf_gas.S b/Zend/asm/make_sparc64_sysv_elf_gas.S index 52ff70b996b6..3e7ee809c918 100644 --- a/Zend/asm/make_sparc64_sysv_elf_gas.S +++ b/Zend/asm/make_sparc64_sysv_elf_gas.S @@ -6,7 +6,7 @@ */ /* - * void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data)); + * fcontext_t *make_fcontext(void *sp, size_t size, void (*fn)(transfer_t)); */ #define CC64FSZ 176 #define BIAS 2047 @@ -56,7 +56,7 @@ make_fcontext: trampoline: ldx [%sp + BIAS + I7], %l0 - # no need to setup boost_context_data, already in %o0 and %o1 + # no need to setup transfer_t, already in %o0 and %o1 jmpl %l0, %o7 nop diff --git a/Zend/asm/make_x86_64_ms_pe_gas.S b/Zend/asm/make_x86_64_ms_pe_gas.S index 66a9bb395356..958a2a7b6d0e 100644 --- a/Zend/asm/make_x86_64_ms_pe_gas.S +++ b/Zend/asm/make_x86_64_ms_pe_gas.S @@ -89,6 +89,7 @@ .file "make_x86_64_ms_pe_gas.asm" .text .p2align 4,,15 +.globl make_fcontext .def make_fcontext; .scl 2; .type 32; .endef .seh_proc make_fcontext make_fcontext: @@ -168,3 +169,6 @@ finish: .seh_endproc .def _exit; .scl 2; .type 32; .endef /* standard C library function */ + +.section .drectve +.ascii " -export:\"make_fcontext\"" diff --git a/Zend/asm/save_xmm_x86_64_ms_masm.asm b/Zend/asm/save_xmm_x86_64_ms_masm.asm index 1569d6bdb0e8..0af7c346095d 100644 --- a/Zend/asm/save_xmm_x86_64_ms_masm.asm +++ b/Zend/asm/save_xmm_x86_64_ms_masm.asm @@ -9,34 +9,34 @@ EXTERN execute_ex_real:PROC ; save the preserved registers when re-entering the VM from JIT code. ; See GH-18136. execute_ex PROC EXPORT FRAME - ; 10 floating points numbers + ; 10 XMM registers ; 32 bytes shadow space ; 8 bytes to align after the return address - sub rsp, 8*10 + 32 + 8 - .allocstack 8*10 + 32 + 8 + sub rsp, 16*10 + 32 + 8 + .allocstack 16*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 + movaps xmmword ptr [rsp + 32 + 16*0], xmm6 + movaps xmmword ptr [rsp + 32 + 16*1], xmm7 + movaps xmmword ptr [rsp + 32 + 16*2], xmm8 + movaps xmmword ptr [rsp + 32 + 16*3], xmm9 + movaps xmmword ptr [rsp + 32 + 16*4], xmm10 + movaps xmmword ptr [rsp + 32 + 16*5], xmm11 + movaps xmmword ptr [rsp + 32 + 16*6], xmm12 + movaps xmmword ptr [rsp + 32 + 16*7], xmm13 + movaps xmmword ptr [rsp + 32 + 16*8], xmm14 + movaps xmmword ptr [rsp + 32 + 16*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 + movaps xmm6, xmmword ptr [rsp + 32 + 16*0] + movaps xmm7, xmmword ptr [rsp + 32 + 16*1] + movaps xmm8, xmmword ptr [rsp + 32 + 16*2] + movaps xmm9, xmmword ptr [rsp + 32 + 16*3] + movaps xmm10, xmmword ptr [rsp + 32 + 16*4] + movaps xmm11, xmmword ptr [rsp + 32 + 16*5] + movaps xmm12, xmmword ptr [rsp + 32 + 16*6] + movaps xmm13, xmmword ptr [rsp + 32 + 16*7] + movaps xmm14, xmmword ptr [rsp + 32 + 16*8] + movaps xmm15, xmmword ptr [rsp + 32 + 16*9] + add rsp, 16*10 + 32 + 8 ret execute_ex ENDP diff --git a/Zend/tests/002.phpt b/Zend/tests/002.phpt deleted file mode 100644 index 7c2ff7b4d389..000000000000 --- a/Zend/tests/002.phpt +++ /dev/null @@ -1,121 +0,0 @@ ---TEST-- -func_get_arg() tests ---FILE-- -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 diff --git a/Zend/tests/003.phpt b/Zend/tests/003.phpt deleted file mode 100644 index 3931628e9a9c..000000000000 --- a/Zend/tests/003.phpt +++ /dev/null @@ -1,82 +0,0 @@ ---TEST-- -func_get_args() tests ---FILE-- -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 diff --git a/Zend/tests/014.inc b/Zend/tests/014.inc deleted file mode 100644 index 69c9bc079025..000000000000 --- a/Zend/tests/014.inc +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/Zend/tests/014.phpt b/Zend/tests/014.phpt deleted file mode 100644 index c02fee93856f..000000000000 --- a/Zend/tests/014.phpt +++ /dev/null @@ -1,42 +0,0 @@ ---TEST-- -get_included_files() tests ---FILE-- - ---EXPECTF-- -array(1) { - [0]=> - string(%d) "%s" -} -array(2) { - [0]=> - string(%d) "%s" - [1]=> - string(%d) "%s" -} -array(2) { - [0]=> - string(%d) "%s" - [1]=> - string(%d) "%s" -} -array(2) { - [0]=> - string(%d) "%s" - [1]=> - string(%d) "%s" -} -Done diff --git a/Zend/tests/019.phpt b/Zend/tests/019.phpt deleted file mode 100644 index 4bc9d6be530c..000000000000 --- a/Zend/tests/019.phpt +++ /dev/null @@ -1,1321 +0,0 @@ ---TEST-- -Test unset(), empty() and isset() functions ---FILE-- - "One", 2 => "two"), - array("Name" => "Jack", "Age" => "30"), - array(1,2, "One" => "1", 2 => "two", ""=>"empty", "" => '') -); - -$outer_loop_counter = 1; -foreach ($array_variables as $array_var) { - echo "--- Outerloop Iteration $outer_loop_counter ---\n"; - - // check the isset and unset on non existing key - $var = 1; // a var which is defined - // try to unset the element which is non-existent - unset($array_var['non_existent']); - // check using isset() & empty() on a non_existent element in the array - var_dump( isset($array_var['non_existent']) ); - var_dump( isset($array_var['non_existent'], $var) ); - var_dump( isset($array_var['non_existent'], $array_var['none']) ); - var_dump( empty($array_var['non_existent']) ); - - // testing empty and isset on arrays - var_dump( empty($array_var) ); // expecting bool(false), except: array(), which is considered empty - var_dump( isset($array_var) ); // expecting bool(true), except: array(), which is not set - - // get the keys of the $array_var - $keys = array_keys($array_var); - // unset each element in the array and see the working of unset, isset & empty - $inner_loop_counter = 1; - foreach ($keys as $key_value) { - echo "-- Innerloop Iteration $inner_loop_counter of Outerloop Iteration $outer_loop_counter --\n"; - $inner_loop_counter++; - - // unset the element - unset($array_var[$key_value]); - // dump the array after element was unset - var_dump($array_var); - // check using isset for the element that was unset - var_dump( isset($array_var[$key_val]) ); // expected: bool(false) - // calling isset with more args - var_dump( isset($array_var[$key_val], $array_var) ); //expected: bool(false) - - // calling empty, expected bool(true) - var_dump( empty($array_var[$key_val]) ); - - // dump the array to see that that array did not get modified - // because of using isset, empty and unset on its element - var_dump($array_var); - } - - $outer_loop_counter++; - - // unset the whole array - unset($array_var); - // dump the array to see its unset - var_dump($array_var); - // use isset to see that array is not set - var_dump( isset($array_var) ); //expected: bool(false) - var_dump( isset($array_var, $array_var[$key_val]) ); // expected: bool(false) - - // empty() to see if the array is empty - var_dump( empty($array_var) ); // expected: bool(true) -} - -echo "\n*** Testing unset(), empty() & isset() with resource variables ***\n"; -$fp = fopen(__FILE__, "r"); -$dfp = opendir( __DIR__ ); -$resources = array ( - $fp, - $dfp -); -$loop_counter = 1; -foreach ($resources as $resource) { - $temp_var = 10; - echo "-- Iteration $loop_counter --\n"; $loop_counter++; - //dump the resource first - var_dump($resource); - - // check using isset() and empty() - var_dump( isset($resource) ); // expected: bool(true) - var_dump( empty($resource) ); // expected: bool(false) - // call isset() with two args, both set - var_dump( isset($resource, $temp_var) ); // expected: bool(true) - - // dump the resource to see using isset() and empty () had no effect on it - var_dump($resource); - - // unset the resource - unset($resource); - // check using isset() and empty() - var_dump( isset($resource) ); // expected: bool(false) - var_dump( empty($resource) ); // expected: bool(true) - // call isset() with two args, but one set - var_dump( isset($resource, $temp_var) ); // expected: bool(false) - // unset the temp_var - unset($temp_var); - // now the isset() with both the args as unset - var_dump( isset($resource, $temp_var) ); // expected: bool(false); - - // dump the resource to see if there any effect on it - var_dump($resource); -} -// unset and dump the array containing all the resources to see that -// unset works correctly -unset($resources); -var_dump($resources); -var_dump( isset($resources) ); //expected: bool(false) -var_dump( empty($resources) ); // expected: bool(true) - -echo "\n*** Testing unset(), empty() & isset() with objects ***\n"; -class Point -{ - var $x; - var $y; - var $lable; - - function __construct($x, $y) { - $this->x = $x; - $this->y = $y; - } - - function setLable($lable) { - $this->lable = $lable; - } - function testPoint() { - echo "\nPoint::testPoint() called\n"; - } -} -$point1 = new Point(30,40); - -// use unset/empty/isset to check the object -var_dump($point1); // dump the object - -// check the object and member that is not set -var_dump( isset($point1) ); // expected: bool(true) -var_dump( empty($point1) ); // expected: bool(false) -var_dump( isset($point1->$lable) ); //expected: bool(false) -var_dump( empty($point1->$lable) ); //expected: bool(true) - -//set the member variable lable and check -$point1->setLable("Point1"); -var_dump( isset($point1->$lable) ); //expected: bool(true) -var_dump( empty($point1->$lable) ); //expected: bool(false) - -// dump the object to see that obj was not harmed -// because of the usage of the isset & empty -var_dump($point1); - -//unset a member and check -unset($point1->x); -// dump the point to see that variable was unset -var_dump($point1); -var_dump( isset($point1->x) ); // expected: bool(false) -var_dump( empty($point1->x) ); // expected: bool(true) - -// unset all members and check -unset($point1->y); -unset($point1->lable); -// dump the object to check that all variables are unset -var_dump($point1); -var_dump( isset($point1) ); // expected: bool(ture) -var_dump( empty($point1) ); // expected: bool(false) - -//unset the object and check -unset($point1); -var_dump( isset($point1) ); // expected: bool(false) -var_dump( empty($point1) ); // expected: bool(true) -// dump to see that object is unset -var_dump($point1); - -// try isset/unset/empty on a member function -$point2 = new Point(5,6); -var_dump( isset($point2->testPoint) ); -var_dump( empty($point2->testPoint) ); -unset($point2->testPoint); -var_dump( isset($point2->testPoint) ); -var_dump( empty($point2->testPoint) ); - -// use get_class_methods to see effect if any -var_dump( get_class_methods($point2) ); -// dump the object to see the effect, none expected -var_dump($point2); - -/* testing variation in operation for isset(), empty() & unset(). -Note: Most of the variation for function unset() is testing by a - set of testcases named "Zend/tests/unset_cv??.phpt", only - variation not tested are attempted here */ - -echo "\n*** Testing possible variation in operation for isset(), empty() & unset() ***\n"; -/* unset() variation1: checking unset on static variable inside a function. - * unset() destroys the variable only in the context of the rest of a function - * Following calls will restore the previous value of a variable. - */ -echo "\n** Testing unset() variation 1: unset on static variable inside a function **\n"; -function test_unset1() { - static $static_var; - - // increment the value of the static. this change is in function context - $static_var ++; - - echo "value of static_var before unset: $static_var\n"; - // check using isset and empty - var_dump( isset($static_var) ); - var_dump( empty($static_var) ); - - // unset the static var - unset($static_var); - echo "value of static_var after unset: $static_var\n"; - // check using isset and empty - var_dump( isset($static_var) ); - var_dump( empty($static_var) ); - - // assign a value to static var - $static_var = 20; - echo "value of static_var after new assignment: $static_var\n"; -} -// call the function -test_unset1(); -test_unset1(); -test_unset1(); - - -echo "\n** Testing unset() variation 2: unset on a variable passed by ref. inside of a function **\n"; -/* unset() variation2: Pass by reference - * If a variable that is PASSED BY REFERENCE is unset() inside of a function, - * only the local variable is destroyed. The variable in the calling environment - * will retain the same value as before unset() was called. - */ -function test_unset2( &$ref_val ) { - // unset the variable passed - unset($ref_val); - // check using isset and empty to confirm - var_dump( isset($ref_val) ); - var_dump( empty($ref_val) ); - - // set the value ot a new one - $ref_val = "new value by ref"; -} - -$value = "value"; -var_dump($value); -test_unset2($value); -var_dump($value); - - -echo "\n** Testing unset() variation 3: unset on a global variable inside of a function **\n"; -/* unset() variation2: unset on a global variable inside a function - * If a globalized variable is unset() inside of a function, only the - * local variable is destroyed. The variable in the calling environment - * will retain the same value as before unset() was called. - */ -$global_var = 10; - -function test_unset3() { - global $global_var; - - // check the $global_var using isset and empty - var_dump( isset($global_var) ); - var_dump( empty($global_var) ); - - // unset the global var - unset($global_var); - - // check the $global_var using isset and empty - var_dump( isset($global_var) ); - var_dump( empty($global_var) ); -} - -var_dump($global_var); -test_unset3(); -var_dump($global_var); - -//Note: No error conditions relating to passing arguments can be tested -// because these are not functions but statements, it will result in syntax error. -?> ---EXPECTF-- -*** Testing unset(), empty() & isset() with scalar variables *** --- Iteration 1 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 2 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 3 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 4 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 5 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 6 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 7 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 8 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 9 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 10 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 11 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 12 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 13 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 14 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 15 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 16 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 17 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 18 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 19 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 20 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 21 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 22 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 23 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 24 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 25 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 26 -- -bool(true) -bool(true) -bool(false) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) --- Iteration 27 -- -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $scalar_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) -bool(false) -bool(false) - -*** Testing unset(), empty() & isset() with arrays *** ---- Outerloop Iteration 1 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(true) -bool(true) - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 2 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 2 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 3 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 3 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 4 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 4 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 5 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 5 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 6 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 6 -- -array(3) { - [1]=> - int(2) - [2]=> - int(3) - [3]=> - int(4) -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(3) { - [1]=> - int(2) - [2]=> - int(3) - [3]=> - int(4) -} --- Innerloop Iteration 2 of Outerloop Iteration 6 -- -array(2) { - [2]=> - int(3) - [3]=> - int(4) -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(2) { - [2]=> - int(3) - [3]=> - int(4) -} --- Innerloop Iteration 3 of Outerloop Iteration 6 -- -array(1) { - [3]=> - int(4) -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(1) { - [3]=> - int(4) -} --- Innerloop Iteration 4 of Outerloop Iteration 6 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 7 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 7 -- -array(2) { - [1]=> - float(2.5) - [2]=> - float(5.6) -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(2) { - [1]=> - float(2.5) - [2]=> - float(5.6) -} --- Innerloop Iteration 2 of Outerloop Iteration 7 -- -array(1) { - [2]=> - float(5.6) -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(1) { - [2]=> - float(5.6) -} --- Innerloop Iteration 3 of Outerloop Iteration 7 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 8 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 8 -- -array(1) { - [2]=> - string(3) "two" -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(1) { - [2]=> - string(3) "two" -} --- Innerloop Iteration 2 of Outerloop Iteration 8 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 9 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 9 -- -array(1) { - ["Age"]=> - string(2) "30" -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(1) { - ["Age"]=> - string(2) "30" -} --- Innerloop Iteration 2 of Outerloop Iteration 9 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) ---- Outerloop Iteration 10 --- -bool(false) -bool(false) -bool(false) -bool(true) -bool(false) -bool(true) --- Innerloop Iteration 1 of Outerloop Iteration 10 -- -array(4) { - [1]=> - int(2) - ["One"]=> - string(1) "1" - [2]=> - string(3) "two" - [""]=> - string(0) "" -} - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(4) { - [1]=> - int(2) - ["One"]=> - string(1) "1" - [2]=> - string(3) "two" - [""]=> - string(0) "" -} --- Innerloop Iteration 2 of Outerloop Iteration 10 -- -array(3) { - ["One"]=> - string(1) "1" - [2]=> - string(3) "two" - [""]=> - string(0) "" -} - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(3) { - ["One"]=> - string(1) "1" - [2]=> - string(3) "two" - [""]=> - string(0) "" -} --- Innerloop Iteration 3 of Outerloop Iteration 10 -- -array(2) { - [2]=> - string(3) "two" - [""]=> - string(0) "" -} - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(2) { - [2]=> - string(3) "two" - [""]=> - string(0) "" -} --- Innerloop Iteration 4 of Outerloop Iteration 10 -- -array(1) { - [""]=> - string(0) "" -} - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(1) { - [""]=> - string(0) "" -} --- Innerloop Iteration 5 of Outerloop Iteration 10 -- -array(0) { -} - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(false) - -Warning: Undefined variable $key_val in %s on line %d -bool(true) -array(0) { -} - -Warning: Undefined variable $array_var in %s on line %d -NULL -bool(false) -bool(false) -bool(true) - -*** Testing unset(), empty() & isset() with resource variables *** --- Iteration 1 -- -resource(%d) of type (stream) -bool(true) -bool(false) -bool(true) -resource(%d) of type (stream) -bool(false) -bool(true) -bool(false) -bool(false) - -Warning: Undefined variable $resource in %s on line %d -NULL --- Iteration 2 -- -resource(%d) of type (stream) -bool(true) -bool(false) -bool(true) -resource(%d) of type (stream) -bool(false) -bool(true) -bool(false) -bool(false) - -Warning: Undefined variable $resource in %s on line %d -NULL - -Warning: Undefined variable $resources in %s on line %d -NULL -bool(false) -bool(true) - -*** Testing unset(), empty() & isset() with objects *** -object(Point)#%d (3) { - ["x"]=> - int(30) - ["y"]=> - int(40) - ["lable"]=> - NULL -} -bool(true) -bool(false) - -Warning: Undefined variable $lable in %s on line %d -bool(false) - -Warning: Undefined variable $lable in %s on line %d -bool(true) - -Warning: Undefined variable $lable in %s on line %d -bool(false) - -Warning: Undefined variable $lable in %s on line %d -bool(true) -object(Point)#%d (3) { - ["x"]=> - int(30) - ["y"]=> - int(40) - ["lable"]=> - string(6) "Point1" -} -object(Point)#%d (2) { - ["y"]=> - int(40) - ["lable"]=> - string(6) "Point1" -} -bool(false) -bool(true) -object(Point)#%d (0) { -} -bool(true) -bool(false) -bool(false) -bool(true) - -Warning: Undefined variable $point1 in %s on line %d -NULL -bool(false) -bool(true) -bool(false) -bool(true) -array(3) { - [0]=> - string(11) "__construct" - [1]=> - string(8) "setLable" - [2]=> - string(9) "testPoint" -} -object(Point)#%d (3) { - ["x"]=> - int(5) - ["y"]=> - int(6) - ["lable"]=> - NULL -} - -*** Testing possible variation in operation for isset(), empty() & unset() *** - -** Testing unset() variation 1: unset on static variable inside a function ** -value of static_var before unset: 1 -bool(true) -bool(false) - -Warning: Undefined variable $static_var in %s on line %d -value of static_var after unset: -bool(false) -bool(true) -value of static_var after new assignment: 20 -value of static_var before unset: 2 -bool(true) -bool(false) - -Warning: Undefined variable $static_var in %s on line %d -value of static_var after unset: -bool(false) -bool(true) -value of static_var after new assignment: 20 -value of static_var before unset: 3 -bool(true) -bool(false) - -Warning: Undefined variable $static_var in %s on line %d -value of static_var after unset: -bool(false) -bool(true) -value of static_var after new assignment: 20 - -** Testing unset() variation 2: unset on a variable passed by ref. inside of a function ** -string(5) "value" -bool(false) -bool(true) -string(5) "value" - -** Testing unset() variation 3: unset on a global variable inside of a function ** -int(10) -bool(true) -bool(false) -bool(false) -bool(true) -int(10) diff --git a/Zend/tests/027.phpt b/Zend/tests/027.phpt deleted file mode 100644 index a862d689e1a8..000000000000 --- a/Zend/tests/027.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -Testing dynamic calls using variable variables with curly syntax ---FILE-- - ---EXPECT-- -bool(true) -bool(true) diff --git a/Zend/tests/GHSA-wm6j-2649-pv75.phpt b/Zend/tests/GHSA-wm6j-2649-pv75.phpt new file mode 100644 index 000000000000..c1035938bd7b --- /dev/null +++ b/Zend/tests/GHSA-wm6j-2649-pv75.phpt @@ -0,0 +1,24 @@ +--TEST-- +GHSA-wm6j-2649-pv75: Null pointer dereference in php_mb_check_encoding() via mb_ereg_search_init() +--CREDITS-- +vi3tL0u1s +--EXTENSIONS-- +mbstring +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Fatal error: Uncaught ValueError: mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "iso-8859-11" given in %s:%d +Stack trace: +#0 %s(%d): mb_regex_encoding('iso-8859-11') +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/022.phpt b/Zend/tests/abstract_method_optional_params.phpt similarity index 100% rename from Zend/tests/022.phpt rename to Zend/tests/abstract_method_optional_params.phpt diff --git a/Zend/tests/arginfo_zpp_mismatch.inc b/Zend/tests/arginfo_zpp_mismatch.inc index 5b2711fdb630..2eb8905f5d4a 100644 --- a/Zend/tests/arginfo_zpp_mismatch.inc +++ b/Zend/tests/arginfo_zpp_mismatch.inc @@ -9,6 +9,7 @@ function skipFunction($function): bool { /* terminates script */ || $function === 'exit' || $function === 'die' + || $function === 'zend_trigger_bailout' /* intentionally violate invariants */ || $function === 'zend_create_unterminated_string' || $function === 'zend_test_array_return' diff --git a/Zend/tests/032.phpt b/Zend/tests/array_append_by_reference.phpt similarity index 100% rename from Zend/tests/032.phpt rename to Zend/tests/array_append_by_reference.phpt diff --git a/Zend/tests/031.phpt b/Zend/tests/array_append_reading_error.phpt similarity index 100% rename from Zend/tests/031.phpt rename to Zend/tests/array_append_reading_error.phpt diff --git a/Zend/tests/array_unpack/gh19303.phpt b/Zend/tests/array_unpack/gh19303.phpt new file mode 100644 index 000000000000..af594c3740c2 --- /dev/null +++ b/Zend/tests/array_unpack/gh19303.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-19303 (Unpacking empty packed array into uninitialized array causes assertion failure) +--FILE-- + +--EXPECT-- +array(0) { +} diff --git a/Zend/tests/arrow_functions/gh7900.phpt b/Zend/tests/arrow_functions/gh7900.phpt index a4170fb1278f..d6465c312399 100644 --- a/Zend/tests/arrow_functions/gh7900.phpt +++ b/Zend/tests/arrow_functions/gh7900.phpt @@ -23,4 +23,4 @@ try { ?> --EXPECT-- Here -assert(fn(): never => 42 && false) +assert((fn(): never => 42) && false) diff --git a/Zend/tests/assert/expect_012.phpt b/Zend/tests/assert/expect_012.phpt index 71e2f96e629a..77a5e4852847 100644 --- a/Zend/tests/assert/expect_012.phpt +++ b/Zend/tests/assert/expect_012.phpt @@ -5,12 +5,12 @@ zend.assertions=1 assert.exception=1 --FILE-- diff --git a/Zend/tests/assert/expect_015.phpt b/Zend/tests/assert/expect_015.phpt index 695c4c166a83..9f8e9b77003b 100644 --- a/Zend/tests/assert/expect_015.phpt +++ b/Zend/tests/assert/expect_015.phpt @@ -183,7 +183,7 @@ assert(0 && ($a = function () { $x = $a ?? $b; [$a, $b, $c] = [1, 2 => 'x', 'z' => 'c']; @foo(); - $y = clone $x; + $y = \clone($x); yield 1 => 2; yield from $x; })) diff --git a/Zend/tests/029.phpt b/Zend/tests/assign_array_object_property.phpt similarity index 100% rename from Zend/tests/029.phpt rename to Zend/tests/assign_array_object_property.phpt diff --git a/Zend/tests/assign_dim_op_undef.phpt b/Zend/tests/assign_dim_op_undef.phpt index 187aed97857a..346311235435 100644 --- a/Zend/tests/assign_dim_op_undef.phpt +++ b/Zend/tests/assign_dim_op_undef.phpt @@ -10,6 +10,8 @@ Warning: Undefined variable $a in %s on line %d Warning: Undefined variable $b in %s on line %d +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + Warning: Undefined array key "" in %s on line %d array(1) { [""]=> diff --git a/Zend/tests/026.phpt b/Zend/tests/assign_property_null_object.phpt similarity index 100% rename from Zend/tests/026.phpt rename to Zend/tests/assign_property_null_object.phpt diff --git a/Zend/tests/ast/gh21072.phpt b/Zend/tests/ast/gh21072.phpt new file mode 100644 index 000000000000..1ffd0518eaea --- /dev/null +++ b/Zend/tests/ast/gh21072.phpt @@ -0,0 +1,17 @@ +--TEST-- +(unset) cast must not be allowed in constant expressions +--CREDITS-- +Viet Hoang Luu (@vi3tL0u1s) +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +Fatal error: The (unset) cast is no longer supported in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/gh19044.phpt b/Zend/tests/asymmetric_visibility/gh19044.phpt new file mode 100644 index 000000000000..253e315d5b94 --- /dev/null +++ b/Zend/tests/asymmetric_visibility/gh19044.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (protected(set) on non-hooked property) +--FILE-- + 42; } +} + +class C1 extends P { + public protected(set) mixed $foo = 1; +} + +class C2 extends P { + public protected(set) mixed $foo; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(43) diff --git a/Zend/tests/asymmetric_visibility/virtual_get_only.phpt b/Zend/tests/asymmetric_visibility/virtual_get_only.phpt index 3eaada70329d..a3f6f980bdfe 100644 --- a/Zend/tests/asymmetric_visibility/virtual_get_only.phpt +++ b/Zend/tests/asymmetric_visibility/virtual_get_only.phpt @@ -11,4 +11,4 @@ class Foo { ?> --EXPECTF-- -Fatal error: Read-only virtual property Foo::$bar must not specify asymmetric visibility in %s on line %d +Fatal error: get-only virtual property Foo::$bar must not specify asymmetric visibility in %s on line %d diff --git a/Zend/tests/asymmetric_visibility/virtual_set_only.phpt b/Zend/tests/asymmetric_visibility/virtual_set_only.phpt index 18abb7ac046a..7d1d2bc7cb99 100644 --- a/Zend/tests/asymmetric_visibility/virtual_set_only.phpt +++ b/Zend/tests/asymmetric_visibility/virtual_set_only.phpt @@ -11,4 +11,4 @@ class Foo { ?> --EXPECTF-- -Fatal error: Write-only virtual property Foo::$bar must not specify asymmetric visibility in %s on line %d +Fatal error: set-only virtual property Foo::$bar must not specify asymmetric visibility in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt b/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt new file mode 100644 index 000000000000..547946c4e130 --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_abstract.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an abstract class +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to abstract class Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt b/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt new file mode 100644 index 000000000000..c5545054dcff --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_enum.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an enum +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to enum Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt b/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt new file mode 100644 index 000000000000..4b9a87a2395d --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_interface.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on an interface +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to interface Demo in %s on line %d diff --git a/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt b/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt new file mode 100644 index 000000000000..7ea05543baa2 --- /dev/null +++ b/Zend/tests/attributes/Attribute/Attribute_on_trait.phpt @@ -0,0 +1,12 @@ +--TEST-- +#[Attribute] on a trait +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Attribute] to trait Demo in %s on line %d diff --git a/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt b/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt index b9ab745be9ae..f1ce8b055b0e 100644 --- a/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt +++ b/Zend/tests/attributes/allow_dynamic_properties_on_enum.phpt @@ -8,4 +8,4 @@ enum Test {} ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to enum Test in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to enum Test in %s on line %d diff --git a/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt b/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt index 0428256a18e4..16440a385db1 100644 --- a/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt +++ b/Zend/tests/attributes/allow_dynamic_properties_on_interface.phpt @@ -8,4 +8,4 @@ interface Test {} ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to interface Test in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to interface Test in %s on line %d diff --git a/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt b/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt index 9636dc03141e..bd18b3e71c8f 100644 --- a/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt +++ b/Zend/tests/attributes/allow_dynamic_properties_on_trait.phpt @@ -8,4 +8,4 @@ trait Test {} ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to trait Test in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to trait Test in %s on line %d diff --git a/Zend/tests/attributes/constants/constant_listed_as_target-internal.phpt b/Zend/tests/attributes/constants/constant_listed_as_target-internal.phpt index b0b88c2f6eda..8a979095e7b9 100644 --- a/Zend/tests/attributes/constants/constant_listed_as_target-internal.phpt +++ b/Zend/tests/attributes/constants/constant_listed_as_target-internal.phpt @@ -3,9 +3,10 @@ Constants listed in valid targets when used wrong (internal attribute) --FILE-- --EXPECTF-- -Fatal error: Attribute "Deprecated" cannot target class (allowed targets: function, method, class constant, constant) in %s on line %d +Fatal error: Attribute "Deprecated" cannot target parameter (allowed targets: class, function, method, class constant, constant) in %s on line %d diff --git a/Zend/tests/attributes/constants/constant_redefined_addition.phpt b/Zend/tests/attributes/constants/constant_redefined_addition.phpt index 08f967098962..5831332afdc5 100644 --- a/Zend/tests/attributes/constants/constant_redefined_addition.phpt +++ b/Zend/tests/attributes/constants/constant_redefined_addition.phpt @@ -15,7 +15,7 @@ var_dump($reflection->getAttributes()) ?> --EXPECTF-- -Warning: Constant MY_CONST already defined in %s on line %d +Warning: Constant MY_CONST already defined, this will be an error in PHP 9 in %s on line %d No attributes array(0) { } diff --git a/Zend/tests/attributes/constants/constant_redefined_change.phpt b/Zend/tests/attributes/constants/constant_redefined_change.phpt index 158753ee07d8..1682f9c2a299 100644 --- a/Zend/tests/attributes/constants/constant_redefined_change.phpt +++ b/Zend/tests/attributes/constants/constant_redefined_change.phpt @@ -16,7 +16,7 @@ var_dump($reflection->getAttributes()) ?> --EXPECTF-- -Warning: Constant MY_CONST already defined in %s on line %d +Warning: Constant MY_CONST already defined, this will be an error in PHP 9 in %s on line %d Has attributes (1) array(1) { [0]=> diff --git a/Zend/tests/attributes/constants/constant_redefined_removal.phpt b/Zend/tests/attributes/constants/constant_redefined_removal.phpt index 0b679a55985e..45476ab6f000 100644 --- a/Zend/tests/attributes/constants/constant_redefined_removal.phpt +++ b/Zend/tests/attributes/constants/constant_redefined_removal.phpt @@ -15,7 +15,7 @@ var_dump($reflection->getAttributes()) ?> --EXPECTF-- -Warning: Constant MY_CONST already defined in %s on line %d +Warning: Constant MY_CONST already defined, this will be an error in PHP 9 in %s on line %d Has attributes array(1) { [0]=> diff --git a/Zend/tests/attributes/constants/multiple_constants_error.phpt b/Zend/tests/attributes/constants/multiple_constants_error.phpt index d4258c9f4d08..b7ee91d3f1d9 100644 --- a/Zend/tests/attributes/constants/multiple_constants_error.phpt +++ b/Zend/tests/attributes/constants/multiple_constants_error.phpt @@ -5,7 +5,9 @@ Error trying to add attributes to multiple constants at once #[\Foo] const First = 1, - Second = 2; + Second = 2, + Third = 3, + Fourth = 4; ?> --EXPECTF-- diff --git a/Zend/tests/attributes/constants/oss_fuzz_428053935.phpt b/Zend/tests/attributes/constants/oss_fuzz_428053935.phpt new file mode 100644 index 000000000000..97747fd6194f --- /dev/null +++ b/Zend/tests/attributes/constants/oss_fuzz_428053935.phpt @@ -0,0 +1,19 @@ +--TEST-- +OSS-Fuzz #428053935 +--FILE-- +getAttributes()); +?> +--EXPECTF-- +array(1) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(8) "Foo\Attr" + } +} diff --git a/Zend/tests/attributes/delayed_target_validation/has_runtime_errors.phpt b/Zend/tests/attributes/delayed_target_validation/has_runtime_errors.phpt new file mode 100644 index 000000000000..b1efb538b328 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/has_runtime_errors.phpt @@ -0,0 +1,282 @@ +--TEST-- +#[\DelayedTargetValidation] has errors at runtime +--FILE-- + $this->v2; + #[DelayedTargetValidation] + #[Attribute] + set => $value; + } + + #[DelayedTargetValidation] + #[Attribute] + public function __construct( + #[DelayedTargetValidation] + #[Attribute] + public string $v3 + ) { + $this->v1 = $v3; + echo __METHOD__ . "\n"; + } +} + +#[DelayedTargetValidation] +#[Attribute] +function demoFn() { + echo __FUNCTION__ . "\n"; +} + +#[DelayedTargetValidation] +#[Attribute] +const EXAMPLE = true; + +$cases = [ + new ReflectionClass('Demo'), + new ReflectionClassConstant('Demo', 'FOO'), + new ReflectionProperty('Demo', 'v1'), + new ReflectionProperty('Demo', 'v2')->getHook(PropertyHookType::Get), + new ReflectionProperty('Demo', 'v2')->getHook(PropertyHookType::Set), + new ReflectionMethod('Demo', '__construct'), + new ReflectionParameter([ 'Demo', '__construct' ], 'v3'), + new ReflectionProperty('Demo', 'v3'), + new ReflectionFunction('demoFn'), + new ReflectionConstant('EXAMPLE'), +]; +foreach ($cases as $r) { + echo str_repeat("*", 20) . "\n"; + echo $r . "\n"; + $attributes = $r->getAttributes(); + var_dump($attributes); + try { + $attributes[1]->newInstance(); + } catch (Error $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; + } +} + +?> +--EXPECTF-- +******************** +Class [ class Demo ] { + @@ %s %d-%d + + - Constants [1] { + Constant [ public string FOO ] { BAR } + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ public string $v1 ] + Property [ public string $v2 { get; set; } ] + Property [ public string $v3 ] + } + + - Methods [1] { + Method [ public method __construct ] { + @@ %s %d - %d + + - Parameters [1] { + Parameter #0 [ string $v3 ] + } + } + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "NoDiscard" + } +} +Error: Attribute "NoDiscard" cannot target class (allowed targets: function, method) +******************** +Constant [ public string FOO ] { BAR } + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target class constant (allowed targets: class) +******************** +Property [ public string $v1 ] + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target property (allowed targets: class) +******************** +Method [ public method $v2::get ] { + @@ %s %d - %d + + - Parameters [0] { + } + - Return [ string ] +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target method (allowed targets: class) +******************** +Method [ public method $v2::set ] { + @@ %s %d - %d + + - Parameters [1] { + Parameter #0 [ string $value ] + } + - Return [ void ] +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target method (allowed targets: class) +******************** +Method [ public method __construct ] { + @@ %s %d - %d + + - Parameters [1] { + Parameter #0 [ string $v3 ] + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target method (allowed targets: class) +******************** +Parameter #0 [ string $v3 ] +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target parameter (allowed targets: class) +******************** +Property [ public string $v3 ] + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target property (allowed targets: class) +******************** +Function [ function demoFn ] { + @@ %s %d - %d +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target function (allowed targets: class) +******************** +Constant [ bool EXAMPLE ] { 1 } + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Attribute "Attribute" cannot target constant (allowed targets: class) diff --git a/Zend/tests/attributes/delayed_target_validation/no_compile_errors.phpt b/Zend/tests/attributes/delayed_target_validation/no_compile_errors.phpt new file mode 100644 index 000000000000..b2e14a235f8a --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/no_compile_errors.phpt @@ -0,0 +1,55 @@ +--TEST-- +#[\DelayedTargetValidation] prevents target errors at compile time +--FILE-- + $this->v2; + #[DelayedTargetValidation] + #[Attribute] + set => $value; + } + + #[DelayedTargetValidation] + #[Attribute] + public function __construct( + #[DelayedTargetValidation] + #[Attribute] + public string $v3 + ) { + $this->v1 = $v3; + echo __METHOD__ . "\n"; + } +} + +#[DelayedTargetValidation] +#[Attribute] +function demoFn() { + echo __FUNCTION__ . "\n"; +} + +$o = new Demo( "foo" ); +demoFn(); + +#[DelayedTargetValidation] +#[Attribute] +const EXAMPLE = true; + +?> +--EXPECT-- +Demo::__construct +demoFn diff --git a/Zend/tests/attributes/delayed_target_validation/opcache_validator_errors.inc b/Zend/tests/attributes/delayed_target_validation/opcache_validator_errors.inc new file mode 100644 index 000000000000..275df500c7e9 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/opcache_validator_errors.inc @@ -0,0 +1,5 @@ + +--FILE-- +getAttributes(); +var_dump($attributes); +try { + $attributes[1]->newInstance(); +} catch (Error $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Trait [ trait DemoTrait ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(22) "AllowDynamicProperties" + } +} +Error: Cannot apply #[\AllowDynamicProperties] to trait DemoTrait diff --git a/Zend/tests/attributes/delayed_target_validation/repetition_errors.phpt b/Zend/tests/attributes/delayed_target_validation/repetition_errors.phpt new file mode 100644 index 000000000000..5c8f9bfc9dde --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/repetition_errors.phpt @@ -0,0 +1,13 @@ +--TEST-- +#[\DelayedTargetValidation] does not prevent repetition errors +--FILE-- + +--EXPECTF-- +Fatal error: Attribute "NoDiscard" must not be repeated in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/validator_AllowDynamicProperties.phpt b/Zend/tests/attributes/delayed_target_validation/validator_AllowDynamicProperties.phpt new file mode 100644 index 000000000000..63add9e445a9 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/validator_AllowDynamicProperties.phpt @@ -0,0 +1,180 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\AllowDynamicProperties]: validator errors delayed +--FILE-- +getAttributes(); + var_dump($attributes); + try { + $attributes[1]->newInstance(); + } catch (Error $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; + } +} + +?> +--EXPECTF-- +******************** +Trait [ trait DemoTrait ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(22) "AllowDynamicProperties" + } +} +Error: Cannot apply #[\AllowDynamicProperties] to trait DemoTrait +******************** +Interface [ interface DemoInterface ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(22) "AllowDynamicProperties" + } +} +Error: Cannot apply #[\AllowDynamicProperties] to interface DemoInterface +******************** +Class [ readonly class DemoReadonly ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(22) "AllowDynamicProperties" + } +} +Error: Cannot apply #[\AllowDynamicProperties] to readonly class DemoReadonly +******************** +Enum [ enum DemoEnum implements UnitEnum ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [1] { + Method [ static public method cases ] { + + - Parameters [0] { + } + - Return [ array ] + } + } + + - Properties [1] { + Property [ public protected(set) readonly string $name ] + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(22) "AllowDynamicProperties" + } +} +Error: Cannot apply #[\AllowDynamicProperties] to enum DemoEnum diff --git a/Zend/tests/attributes/delayed_target_validation/validator_Attribute.phpt b/Zend/tests/attributes/delayed_target_validation/validator_Attribute.phpt new file mode 100644 index 000000000000..0571024f19ce --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/validator_Attribute.phpt @@ -0,0 +1,180 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Attribute]: validator errors delayed +--FILE-- +getAttributes(); + var_dump($attributes); + try { + $attributes[1]->newInstance(); + } catch (Error $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; + } +} + +?> +--EXPECTF-- +******************** +Trait [ trait DemoTrait ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Cannot apply #[\Attribute] to trait DemoTrait +******************** +Interface [ interface DemoInterface ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Cannot apply #[\Attribute] to interface DemoInterface +******************** +Class [ abstract class DemoAbstract ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Cannot apply #[\Attribute] to abstract class DemoAbstract +******************** +Enum [ enum DemoEnum implements UnitEnum ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [1] { + Method [ static public method cases ] { + + - Parameters [0] { + } + - Return [ array ] + } + } + + - Properties [1] { + Property [ public protected(set) readonly string $name ] + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "Attribute" + } +} +Error: Cannot apply #[\Attribute] to enum DemoEnum diff --git a/Zend/tests/attributes/delayed_target_validation/validator_Deprecated.phpt b/Zend/tests/attributes/delayed_target_validation/validator_Deprecated.phpt new file mode 100644 index 000000000000..f5fedb4ee68e --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/validator_Deprecated.phpt @@ -0,0 +1,142 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Deprecated]: validator errors delayed +--FILE-- +getAttributes(); + var_dump($attributes); + try { + $attributes[1]->newInstance(); + } catch (Error $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; + } +} + +?> +--EXPECTF-- +******************** +Interface [ interface DemoInterface ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(10) "Deprecated" + } +} +Error: Cannot apply #[\Deprecated] to interface DemoInterface +******************** +Class [ class DemoClass ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(10) "Deprecated" + } +} +Error: Cannot apply #[\Deprecated] to class DemoClass +******************** +Enum [ enum DemoEnum implements UnitEnum ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [1] { + Method [ static public method cases ] { + + - Parameters [0] { + } + - Return [ array ] + } + } + + - Properties [1] { + Property [ public protected(set) readonly string $name ] + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(10) "Deprecated" + } +} +Error: Cannot apply #[\Deprecated] to enum DemoEnum diff --git a/Zend/tests/attributes/delayed_target_validation/validator_NoDiscard.phpt b/Zend/tests/attributes/delayed_target_validation/validator_NoDiscard.phpt new file mode 100644 index 000000000000..e3cfe9d1c109 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/validator_NoDiscard.phpt @@ -0,0 +1,79 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\NoDiscard]: validator errors delayed +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[NoDiscard] // Does nothing here + set => $value; + } +} + +$cases = [ + new ReflectionProperty('DemoClass', 'hooked')->getHook(PropertyHookType::Get), + new ReflectionProperty('DemoClass', 'hooked')->getHook(PropertyHookType::Set), +]; +foreach ($cases as $r) { + echo str_repeat("*", 20) . "\n"; + echo $r . "\n"; + $attributes = $r->getAttributes(); + var_dump($attributes); + try { + $attributes[1]->newInstance(); + } catch (Error $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; + } +} + +?> +--EXPECTF-- +******************** +Method [ public method $hooked::get ] { + @@ %s %d - %d + + - Parameters [0] { + } + - Return [ string ] +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "NoDiscard" + } +} +Error: #[\NoDiscard] is not supported for property hooks +******************** +Method [ public method $hooked::set ] { + @@ %s %d - %d + + - Parameters [1] { + Parameter #0 [ string $value ] + } + - Return [ void ] +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(9) "NoDiscard" + } +} +Error: #[\NoDiscard] is not supported for property hooks diff --git a/Zend/tests/attributes/delayed_target_validation/validator_success.phpt b/Zend/tests/attributes/delayed_target_validation/validator_success.phpt new file mode 100644 index 000000000000..5e2a128dd431 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/validator_success.phpt @@ -0,0 +1,62 @@ +--TEST-- +#[\DelayedTargetValidation] with a successful validator +--FILE-- +dynamic = true; +var_dump($obj); + +$ref = new ReflectionClass('DemoClass'); +echo $ref . "\n"; +$attributes = $ref->getAttributes(); +var_dump($attributes); +var_dump($attributes[1]->newInstance()); + +?> +--EXPECTF-- +object(DemoClass)#%d (0) { +} +object(DemoClass)#%d (1) { + ["dynamic"]=> + bool(true) +} +Class [ class DemoClass ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [0] { + } +} + +array(2) { + [0]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(23) "DelayedTargetValidation" + } + [1]=> + object(ReflectionAttribute)#%d (1) { + ["name"]=> + string(22) "AllowDynamicProperties" + } +} +object(AllowDynamicProperties)#%d (0) { +} diff --git a/Zend/tests/attributes/delayed_target_validation/with_AllowDynamicProperties.phpt b/Zend/tests/attributes/delayed_target_validation/with_AllowDynamicProperties.phpt new file mode 100644 index 000000000000..83f738491c57 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_AllowDynamicProperties.phpt @@ -0,0 +1,81 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\AllowDynamicProperties]: invalid targets don't error +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[AllowDynamicProperties] // Does nothing here + set => $value; + } + + #[DelayedTargetValidation] + #[AllowDynamicProperties] // Does nothing here + public const CLASS_CONST = 'FOO'; + + public function __construct( + #[DelayedTargetValidation] + #[AllowDynamicProperties] // Does nothing here + $str + ) { + echo "Got: $str\n"; + $this->val = $str; + } + + #[DelayedTargetValidation] + #[AllowDynamicProperties] // Does nothing here + public function printVal() { + echo 'Value is: ' . $this->val . "\n"; + } + +} + +#[DelayedTargetValidation] +#[AllowDynamicProperties] // Does nothing here +function demoFn() { + echo __FUNCTION__ . "\n"; + return 456; +} + +#[DelayedTargetValidation] +#[AllowDynamicProperties] // Does nothing here +const GLOBAL_CONST = 'BAR'; + +$d = new DemoClass('example'); +$d->printVal(); +var_dump($d->val); +$d->hooked = "foo"; +var_dump($d->hooked); +var_dump(DemoClass::CLASS_CONST); +demoFn(); +var_dump(GLOBAL_CONST); + +$d->missingProp = 'foo'; +var_dump($d); +?> +--EXPECTF-- +Got: example +Value is: example +string(7) "example" +string(3) "foo" +string(3) "FOO" +demoFn +string(3) "BAR" +object(DemoClass)#%d (3) { + ["val"]=> + string(7) "example" + ["hooked"]=> + string(3) "foo" + ["missingProp"]=> + string(3) "foo" +} diff --git a/Zend/tests/attributes/delayed_target_validation/with_Attribute.phpt b/Zend/tests/attributes/delayed_target_validation/with_Attribute.phpt new file mode 100644 index 000000000000..edc7d2a7905f --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Attribute.phpt @@ -0,0 +1,95 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Attribute]: invalid targets don't error +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[Attribute] // Does nothing here + set => $value; + } + + #[DelayedTargetValidation] + #[Attribute] // Does nothing here + public const CLASS_CONST = 'FOO'; + + public function __construct( + #[DelayedTargetValidation] + #[Attribute] // Does nothing here + $str + ) { + echo "Got: $str\n"; + $this->val = $str; + } + + #[DelayedTargetValidation] + #[Attribute] // Does nothing here + public function printVal() { + echo 'Value is: ' . $this->val . "\n"; + } + +} + +#[DelayedTargetValidation] +#[Attribute] // Does nothing here +function demoFn() { + echo __FUNCTION__ . "\n"; + return 456; +} + +#[DelayedTargetValidation] +#[Attribute] // Does nothing here +const GLOBAL_CONST = 'BAR'; + +$d = new DemoClass('example'); +$d->printVal(); +var_dump($d->val); +$d->hooked = "foo"; +var_dump($d->hooked); +var_dump(DemoClass::CLASS_CONST); +demoFn(); +var_dump(GLOBAL_CONST); + +#[DemoClass('BAZ')] +#[NonAttribute] +class WithDemoAttribs {} + +$ref = new ReflectionClass(WithDemoAttribs::class); +$attribs = $ref->getAttributes(); +var_dump($attribs[0]->newInstance()); +var_dump($attribs[1]->newInstance()); + +?> +--EXPECTF-- +Got: example +Value is: example +string(7) "example" +string(3) "foo" +string(3) "FOO" +demoFn +string(3) "BAR" +Got: BAZ +object(DemoClass)#5 (1) { + ["val"]=> + string(3) "BAZ" + ["hooked"]=> + uninitialized(string) +} + +Fatal error: Uncaught Error: Attempting to use non-attribute class "NonAttribute" as attribute in %s:%d +Stack trace: +#0 %s(%d): ReflectionAttribute->newInstance() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/with_Deprecated.phpt b/Zend/tests/attributes/delayed_target_validation/with_Deprecated.phpt new file mode 100644 index 000000000000..e103f9d97389 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Deprecated.phpt @@ -0,0 +1,91 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Deprecated]: valid targets are deprecated +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[Deprecated] // Does something here + set => $value; + } + + #[DelayedTargetValidation] + #[Deprecated] // Does something here + public const CLASS_CONST = 'FOO'; + + public function __construct( + #[DelayedTargetValidation] + #[Deprecated] // Does nothing here + $str + ) { + echo "Got: $str\n"; + $this->val = $str; + } + + #[DelayedTargetValidation] + #[Deprecated] // Does something here + public function printVal() { + echo 'Value is: ' . $this->val . "\n"; + return 123; + } +} + +#[DelayedTargetValidation] +#[Deprecated] // Does something here +trait DeprecatedTrait {} + +class WithDeprecatedTrait { + use DeprecatedTrait; +} + +#[DelayedTargetValidation] +#[Deprecated] // Does something here +function demoFn() { + echo __FUNCTION__ . "\n"; + return 456; +} + +#[DelayedTargetValidation] +#[Deprecated] // Does something here +const GLOBAL_CONST = 'BAR'; + +$d = new DemoClass('example'); +$d->printVal(); +var_dump($d->val); +$d->hooked = "foo"; +var_dump($d->hooked); +var_dump(DemoClass::CLASS_CONST); +demoFn(); +var_dump(GLOBAL_CONST); +?> +--EXPECTF-- +Deprecated: Trait DeprecatedTrait used by WithDeprecatedTrait is deprecated in %s on line %d +Got: example + +Deprecated: Method DemoClass::printVal() is deprecated in %s on line %d +Value is: example +string(7) "example" + +Deprecated: Method DemoClass::$hooked::set() is deprecated in %s on line %d + +Deprecated: Method DemoClass::$hooked::get() is deprecated in %s on line %d +string(3) "foo" + +Deprecated: Constant DemoClass::CLASS_CONST is deprecated in %s on line %d +string(3) "FOO" + +Deprecated: Function demoFn() is deprecated in %s on line %d +demoFn + +Deprecated: Constant GLOBAL_CONST is deprecated in %s on line %d +string(3) "BAR" diff --git a/Zend/tests/attributes/delayed_target_validation/with_NoDiscard.phpt b/Zend/tests/attributes/delayed_target_validation/with_NoDiscard.phpt new file mode 100644 index 000000000000..f2571ec07c2f --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_NoDiscard.phpt @@ -0,0 +1,80 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\NoDiscard]: valid targets complain about discarding +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[NoDiscard] // Does nothing here + set => $value; + } + + #[DelayedTargetValidation] + #[NoDiscard] // Does nothing here + public const CLASS_CONST = 'FOO'; + + public function __construct( + #[DelayedTargetValidation] + #[NoDiscard] // Does nothing here + $str + ) { + echo "Got: $str\n"; + $this->val = $str; + } + + #[DelayedTargetValidation] + #[NoDiscard] // Does something here + public function printVal() { + echo 'Value is: ' . $this->val . "\n"; + return 123; + } +} + +#[DelayedTargetValidation] +#[NoDiscard] // Does something here +function demoFn() { + echo __FUNCTION__ . "\n"; + return 456; +} + +#[DelayedTargetValidation] +#[NoDiscard] // Does nothing here +const GLOBAL_CONST = 'BAR'; + +$d = new DemoClass('example'); +$d->printVal(); +$v = $d->printVal(); +var_dump($d->val); +$d->hooked = "foo"; +var_dump($d->hooked); +// NoDiscard does not support property hooks, this should not complain +$d->hooked; +var_dump(DemoClass::CLASS_CONST); +demoFn(); +$v = demoFn(); +var_dump(GLOBAL_CONST); +?> +--EXPECTF-- +Got: example + +Warning: The return value of method DemoClass::printVal() should either be used or intentionally ignored by casting it as (void) in %s on line %d +Value is: example +Value is: example +string(7) "example" +string(3) "foo" +string(3) "FOO" + +Warning: The return value of function demoFn() should either be used or intentionally ignored by casting it as (void) in %s on line %d +demoFn +demoFn +string(3) "BAR" diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_error_get.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_error_get.phpt new file mode 100644 index 000000000000..a33e83d517a3 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_error_get.phpt @@ -0,0 +1,18 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Override]: non-overrides still error (get hook) +--FILE-- + $this->hooked; + set => $value; + } +} + +?> +--EXPECTF-- +Fatal error: DemoClass::$hooked::get() has #[\Override] attribute, but no matching parent method exists in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_error_method.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_error_method.phpt new file mode 100644 index 000000000000..ecca1daff0fd --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_error_method.phpt @@ -0,0 +1,18 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Override]: non-overrides still error (method) +--FILE-- +val . "\n"; + return 123; + } +} + +?> +--EXPECTF-- +Fatal error: DemoClass::printVal() has #[\Override] attribute, but no matching parent method exists in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_error_prop.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_error_prop.phpt new file mode 100644 index 000000000000..3a44fa9b22cd --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_error_prop.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Override]: non-overrides still error (normal property) +--FILE-- + +--EXPECTF-- +Fatal error: DemoClass::$prop has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_error_set.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_error_set.phpt new file mode 100644 index 000000000000..d99580646c54 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_error_set.phpt @@ -0,0 +1,18 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Override]: non-overrides still error (set hook) +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[Override] // Does something here + set => $value; + } +} + +?> +--EXPECTF-- +Fatal error: DemoClass::$hooked::set() has #[\Override] attribute, but no matching parent method exists in %s on line %d diff --git a/Zend/tests/attributes/delayed_target_validation/with_Override_okay.phpt b/Zend/tests/attributes/delayed_target_validation/with_Override_okay.phpt new file mode 100644 index 000000000000..dd077f4b9cbd --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_Override_okay.phpt @@ -0,0 +1,84 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\Override]: invalid targets or actual overrides don't do anything +--FILE-- + $this->hooked; + set => $value; + } + + public function printVal() { + echo __METHOD__ . "\n"; + } +} + +#[DelayedTargetValidation] +#[Override] // Does nothing here +class DemoClass extends Base { + #[DelayedTargetValidation] + #[Override] // Does something here + public $val; + + public string $hooked { + #[DelayedTargetValidation] + #[Override] // Does something here + get => $this->hooked; + #[DelayedTargetValidation] + #[Override] // Does something here + set => $value; + } + + #[DelayedTargetValidation] + #[Override] // Does nothing here + public const CLASS_CONST = 'FOO'; + + public function __construct( + #[DelayedTargetValidation] + #[Override] // Does nothing here + $str + ) { + echo "Got: $str\n"; + $this->val = $str; + } + + #[DelayedTargetValidation] + #[Override] // Does something here + public function printVal() { + echo 'Value is: ' . $this->val . "\n"; + return 123; + } +} + +#[DelayedTargetValidation] +#[Override] // Does nothing here +function demoFn() { + echo __FUNCTION__ . "\n"; + return 456; +} + +#[DelayedTargetValidation] +#[Override] // Does nothing here +const GLOBAL_CONST = 'BAR'; + +$d = new DemoClass('example'); +$d->printVal(); +var_dump($d->val); +$d->hooked = "foo"; +var_dump($d->hooked); +var_dump(DemoClass::CLASS_CONST); +demoFn(); +var_dump(GLOBAL_CONST); +?> +--EXPECT-- +Got: example +Value is: example +string(7) "example" +string(3) "foo" +string(3) "FOO" +demoFn +string(3) "BAR" diff --git a/Zend/tests/attributes/delayed_target_validation/with_ReturnTypeWillChange.phpt b/Zend/tests/attributes/delayed_target_validation/with_ReturnTypeWillChange.phpt new file mode 100644 index 000000000000..c562075cd6c0 --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_ReturnTypeWillChange.phpt @@ -0,0 +1,82 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\ReturnTypeWillChange]: valid targets suppress return type warnings +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[ReturnTypeWillChange] // Does nothing here + set => $value; + } + + #[DelayedTargetValidation] + #[ReturnTypeWillChange] // Does nothing here + public const CLASS_CONST = 'FOO'; + + public function __construct( + #[DelayedTargetValidation] + #[ReturnTypeWillChange] // Does nothing here + $str + ) { + echo "Got: $str\n"; + $this->val = $str; + } + + #[DelayedTargetValidation] + #[ReturnTypeWillChange] // Does something here + public function printVal() { + echo 'Value is: ' . $this->val . "\n"; + } + + #[DelayedTargetValidation] + #[ReturnTypeWillChange] // Does something here + public function count() { + return 5; + } +} + +#[DelayedTargetValidation] +#[ReturnTypeWillChange] // Does nothing here +function demoFn() { + echo __FUNCTION__ . "\n"; + return 456; +} + +#[DelayedTargetValidation] +#[ReturnTypeWillChange] // Does nothing here +const GLOBAL_CONST = 'BAR'; + +$d = new DemoClass('example'); +$d->printVal(); +var_dump($d->val); +$d->hooked = "foo"; +var_dump($d->hooked); +var_dump(DemoClass::CLASS_CONST); +demoFn(); +var_dump(GLOBAL_CONST); +?> +--EXPECTF-- +Deprecated: Return type of WithoutAttrib::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s on line %d +Got: example +Value is: example +string(7) "example" +string(3) "foo" +string(3) "FOO" +demoFn +string(3) "BAR" diff --git a/Zend/tests/attributes/delayed_target_validation/with_SensitiveParameter.phpt b/Zend/tests/attributes/delayed_target_validation/with_SensitiveParameter.phpt new file mode 100644 index 000000000000..270c031f6bbf --- /dev/null +++ b/Zend/tests/attributes/delayed_target_validation/with_SensitiveParameter.phpt @@ -0,0 +1,82 @@ +--TEST-- +#[\DelayedTargetValidation] with #[\SensitiveParameter]: parameter still redacted +--FILE-- + $this->hooked; + #[DelayedTargetValidation] + #[SensitiveParameter] // Does nothing here + set => $value; + } + + #[DelayedTargetValidation] + #[SensitiveParameter] // Does nothing here + public const CLASS_CONST = 'FOO'; + + public function __construct( + #[DelayedTargetValidation] + #[SensitiveParameter] // Does something here + $str + ) { + echo "Got: $str\n"; + $this->val = $str; + } + + #[DelayedTargetValidation] + #[SensitiveParameter] // Does nothing here + public function printVal( + #[DelayedTargetValidation] + #[SensitiveParameter] + $sensitive // Does something here + ) { + throw new Exception('Testing backtrace'); + } + +} + +#[DelayedTargetValidation] +#[SensitiveParameter] // Does nothing here +function demoFn() { + echo __FUNCTION__ . "\n"; + return 456; +} + +#[DelayedTargetValidation] +#[SensitiveParameter] // Does nothing here +const GLOBAL_CONST = 'BAR'; + +$d = new DemoClass('example'); +var_dump($d->val); +$d->hooked = "foo"; +var_dump($d->hooked); +var_dump(DemoClass::CLASS_CONST); +demoFn(); +var_dump(GLOBAL_CONST); + +$d->printVal('BAZ'); + + +?> +--EXPECTF-- +Got: example +string(7) "example" +string(3) "foo" +string(3) "FOO" +demoFn +string(3) "BAR" + +Fatal error: Uncaught Exception: Testing backtrace in %s:%d +Stack trace: +#0 %s(%d): DemoClass->printVal(Object(SensitiveParameterValue)) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/attributes/deprecated/error_on_class.phpt b/Zend/tests/attributes/deprecated/error_on_class.phpt new file mode 100644 index 000000000000..97c48af1491f --- /dev/null +++ b/Zend/tests/attributes/deprecated/error_on_class.phpt @@ -0,0 +1,11 @@ +--TEST-- +#[\Deprecated]: Using on a class +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Deprecated] to class Demo in %s on line %d diff --git a/Zend/tests/attributes/deprecated/error_on_enum.phpt b/Zend/tests/attributes/deprecated/error_on_enum.phpt new file mode 100644 index 000000000000..0d998a238992 --- /dev/null +++ b/Zend/tests/attributes/deprecated/error_on_enum.phpt @@ -0,0 +1,11 @@ +--TEST-- +#[\Deprecated]: Using on an enum +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Deprecated] to enum Demo in %s on line %d diff --git a/Zend/tests/attributes/deprecated/error_on_interface.phpt b/Zend/tests/attributes/deprecated/error_on_interface.phpt new file mode 100644 index 000000000000..595181a7cecd --- /dev/null +++ b/Zend/tests/attributes/deprecated/error_on_interface.phpt @@ -0,0 +1,11 @@ +--TEST-- +#[\Deprecated]: Using on an interface +--FILE-- + +--EXPECTF-- +Fatal error: Cannot apply #[\Deprecated] to interface Demo in %s on line %d diff --git a/Zend/tests/attributes/deprecated/traits/basic.phpt b/Zend/tests/attributes/deprecated/traits/basic.phpt new file mode 100644 index 000000000000..77738058e2a5 --- /dev/null +++ b/Zend/tests/attributes/deprecated/traits/basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +#[\Deprecated]: Basic trait deprecation +--FILE-- + +--EXPECTF-- +Deprecated: Trait DemoTrait1 used by DemoClass is deprecated, please do not use in %s on line %d + +Deprecated: Trait DemoTrait2 used by DemoClass is deprecated since 2.7, will be removed in 3.0 in %s on line %d + +Deprecated: Trait DemoTrait3 used by DemoClass is deprecated, going away in %s on line %d + +Deprecated: Trait DemoTrait4 used by DemoClass is deprecated since 3.5 in %s on line %d diff --git a/Zend/tests/attributes/deprecated/traits/inheritance.phpt b/Zend/tests/attributes/deprecated/traits/inheritance.phpt new file mode 100644 index 000000000000..6a54a83e2e44 --- /dev/null +++ b/Zend/tests/attributes/deprecated/traits/inheritance.phpt @@ -0,0 +1,18 @@ +--TEST-- +#[\Deprecated]: Deprecated traits only apply to direct use, not inheritance +--FILE-- + +--EXPECTF-- +Deprecated: Trait DemoTrait used by DemoClass is deprecated in %s on line %d diff --git a/Zend/tests/attributes/deprecated/traits/insteadof_unused_warnings.phpt b/Zend/tests/attributes/deprecated/traits/insteadof_unused_warnings.phpt new file mode 100644 index 000000000000..390455f73ba7 --- /dev/null +++ b/Zend/tests/attributes/deprecated/traits/insteadof_unused_warnings.phpt @@ -0,0 +1,43 @@ +--TEST-- +#[\Deprecated]: `insteadof` rendering a trait unused still triggers deprecation messages +--FILE-- +lowerCase()); +var_dump($d->upperCase()); + +?> +--EXPECTF-- +Deprecated: Trait DemoTraitA used by DemoClass is deprecated in %s on line %d + +Deprecated: Trait DemoTraitB used by DemoClass is deprecated in %s on line %d +string(1) "a" +string(1) "A" diff --git a/Zend/tests/attributes/deprecated/traits/multiple_traits.phpt b/Zend/tests/attributes/deprecated/traits/multiple_traits.phpt new file mode 100644 index 000000000000..2d838493f451 --- /dev/null +++ b/Zend/tests/attributes/deprecated/traits/multiple_traits.phpt @@ -0,0 +1,22 @@ +--TEST-- +#[\Deprecated]: Using multiple traits +--FILE-- + +--EXPECTF-- +Deprecated: Trait DemoTraitA used by DemoClass is deprecated in %s on line %d + +Deprecated: Trait DemoTraitB used by DemoClass is deprecated in %s on line %d diff --git a/Zend/tests/attributes/deprecated/traits/throwing_error_handler.phpt b/Zend/tests/attributes/deprecated/traits/throwing_error_handler.phpt new file mode 100644 index 000000000000..2704ea68e5b3 --- /dev/null +++ b/Zend/tests/attributes/deprecated/traits/throwing_error_handler.phpt @@ -0,0 +1,25 @@ +--TEST-- +#[\Deprecated]: Deprecation converted to ErrorException does not break +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ErrorException: Trait DemoTrait used by DemoClass is deprecated in %s:%d +Stack trace: +#0 %s: my_error_handler(16384, 'Trait DemoTrait...', '%s', %d) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/attributes/deprecated/traits/trait_using_trait.phpt b/Zend/tests/attributes/deprecated/traits/trait_using_trait.phpt new file mode 100644 index 000000000000..851adeb232d3 --- /dev/null +++ b/Zend/tests/attributes/deprecated/traits/trait_using_trait.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Deprecated]: Trait using a deprecated trait +--FILE-- + +--EXPECTF-- +Deprecated: Trait DemoTraitA used by DemoTraitB is deprecated in %s on line %d diff --git a/Zend/tests/attributes/deprecated/traits/with_conflicts.phpt b/Zend/tests/attributes/deprecated/traits/with_conflicts.phpt new file mode 100644 index 000000000000..5adbb3c57d49 --- /dev/null +++ b/Zend/tests/attributes/deprecated/traits/with_conflicts.phpt @@ -0,0 +1,43 @@ +--TEST-- +#[\Deprecated]: Using multiple traits with conflict resolution +--FILE-- +lowerCase()); +var_dump($d->upperCase()); + +?> +--EXPECTF-- +Deprecated: Trait DemoTraitA used by DemoClass is deprecated in %s on line %d + +Deprecated: Trait DemoTraitB used by DemoClass is deprecated in %s on line %d +string(1) "a" +string(1) "B" diff --git a/Zend/tests/attributes/nodiscard/007.phpt b/Zend/tests/attributes/nodiscard/007.phpt index 1b72de8c22a0..de4604e15e48 100644 --- a/Zend/tests/attributes/nodiscard/007.phpt +++ b/Zend/tests/attributes/nodiscard/007.phpt @@ -12,6 +12,8 @@ zend_test_nodiscard(); ?> --EXPECTF-- + Warning: The return value of function zend_test_nodiscard() should either be used or intentionally ignored by casting it as (void), custom message in %s on line %d + diff --git a/Zend/tests/attributes/override/properties_01.phpt b/Zend/tests/attributes/override/properties_01.phpt new file mode 100644 index 000000000000..d83f935f8349 --- /dev/null +++ b/Zend/tests/attributes/override/properties_01.phpt @@ -0,0 +1,39 @@ +--TEST-- +#[\Override]: Properties +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_02.phpt b/Zend/tests/attributes/override/properties_02.phpt new file mode 100644 index 000000000000..aefe84f150db --- /dev/null +++ b/Zend/tests/attributes/override/properties_02.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Properties: No parent class. +--FILE-- + +--EXPECTF-- +Fatal error: C::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_03.phpt b/Zend/tests/attributes/override/properties_03.phpt new file mode 100644 index 000000000000..c2b2ea0acc2e --- /dev/null +++ b/Zend/tests/attributes/override/properties_03.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: No parent class, but child implements matching interface. +--FILE-- + +--EXPECTF-- +Fatal error: P::$i has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_04.phpt b/Zend/tests/attributes/override/properties_04.phpt new file mode 100644 index 000000000000..142a1d0c640a --- /dev/null +++ b/Zend/tests/attributes/override/properties_04.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: No parent class, but child implements matching interface (2). +--FILE-- + +--EXPECTF-- +Fatal error: P::$i has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_05.phpt b/Zend/tests/attributes/override/properties_05.phpt new file mode 100644 index 000000000000..71113dad60e4 --- /dev/null +++ b/Zend/tests/attributes/override/properties_05.phpt @@ -0,0 +1,26 @@ +--TEST-- +#[\Override]: Properties: No parent interface. +--FILE-- + +--EXPECTF-- +Fatal error: I::$i has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_06.phpt b/Zend/tests/attributes/override/properties_06.phpt new file mode 100644 index 000000000000..66309ac625c0 --- /dev/null +++ b/Zend/tests/attributes/override/properties_06.phpt @@ -0,0 +1,15 @@ +--TEST-- +#[\Override]: Properties: On trait. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_07.phpt b/Zend/tests/attributes/override/properties_07.phpt new file mode 100644 index 000000000000..ae9ed4b8dbf7 --- /dev/null +++ b/Zend/tests/attributes/override/properties_07.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: On used trait without parent property. +--FILE-- + +--EXPECTF-- +Fatal error: Foo::$t has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_08.phpt b/Zend/tests/attributes/override/properties_08.phpt new file mode 100644 index 000000000000..c976dcecdc14 --- /dev/null +++ b/Zend/tests/attributes/override/properties_08.phpt @@ -0,0 +1,23 @@ +--TEST-- +#[\Override]: Properties: On used trait with interface property. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_09.phpt b/Zend/tests/attributes/override/properties_09.phpt new file mode 100644 index 000000000000..85970ba11a42 --- /dev/null +++ b/Zend/tests/attributes/override/properties_09.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is private, child property is public. +--FILE-- + +--EXPECTF-- +Fatal error: C::$p has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_10.phpt b/Zend/tests/attributes/override/properties_10.phpt new file mode 100644 index 000000000000..ce1d7f46fd57 --- /dev/null +++ b/Zend/tests/attributes/override/properties_10.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is private, child property is private. +--FILE-- + +--EXPECTF-- +Fatal error: C::$p has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_11.phpt b/Zend/tests/attributes/override/properties_11.phpt new file mode 100644 index 000000000000..354e718505d1 --- /dev/null +++ b/Zend/tests/attributes/override/properties_11.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is protected, child property is public. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_12.phpt b/Zend/tests/attributes/override/properties_12.phpt new file mode 100644 index 000000000000..351ed26b0af8 --- /dev/null +++ b/Zend/tests/attributes/override/properties_12.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Parent property is protected, child property is protected. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_13.phpt b/Zend/tests/attributes/override/properties_13.phpt new file mode 100644 index 000000000000..d9ab0a6b9a29 --- /dev/null +++ b/Zend/tests/attributes/override/properties_13.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: Redeclared trait property. +--FILE-- + +--EXPECTF-- +Fatal error: C::$t has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_14.phpt b/Zend/tests/attributes/override/properties_14.phpt new file mode 100644 index 000000000000..4e098c6d7212 --- /dev/null +++ b/Zend/tests/attributes/override/properties_14.phpt @@ -0,0 +1,25 @@ +--TEST-- +#[\Override]: Properties: Redeclared trait property with interface. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_15.phpt b/Zend/tests/attributes/override/properties_15.phpt new file mode 100644 index 000000000000..37d46b2a170a --- /dev/null +++ b/Zend/tests/attributes/override/properties_15.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Valid anonymous class. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_16.phpt b/Zend/tests/attributes/override/properties_16.phpt new file mode 100644 index 000000000000..57ea17818c40 --- /dev/null +++ b/Zend/tests/attributes/override/properties_16.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: Invalid anonymous class. +--FILE-- + +--EXPECTF-- +Fatal error: I@anonymous::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_17.phpt b/Zend/tests/attributes/override/properties_17.phpt new file mode 100644 index 000000000000..389d66035ea4 --- /dev/null +++ b/Zend/tests/attributes/override/properties_17.phpt @@ -0,0 +1,16 @@ +--TEST-- +#[\Override]: Properties: Static property no parent class. +--FILE-- + +--EXPECTF-- +Fatal error: C::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/attributes/override/properties_18.phpt b/Zend/tests/attributes/override/properties_18.phpt new file mode 100644 index 000000000000..66731a69f8e8 --- /dev/null +++ b/Zend/tests/attributes/override/properties_18.phpt @@ -0,0 +1,19 @@ +--TEST-- +#[\Override]: Properties: Static property. +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_19.phpt b/Zend/tests/attributes/override/properties_19.phpt new file mode 100644 index 000000000000..1844664e3ca2 --- /dev/null +++ b/Zend/tests/attributes/override/properties_19.phpt @@ -0,0 +1,21 @@ +--TEST-- +#[\Override]: Properties: valid promoted property +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/attributes/override/properties_20.phpt b/Zend/tests/attributes/override/properties_20.phpt new file mode 100644 index 000000000000..fcfbfa727c84 --- /dev/null +++ b/Zend/tests/attributes/override/properties_20.phpt @@ -0,0 +1,17 @@ +--TEST-- +#[\Override]: Properties: invalid promoted property +--FILE-- + +--EXPECTF-- +Fatal error: C::$c has #[\Override] attribute, but no matching parent property exists in %s on line %d diff --git a/Zend/tests/bitwise_not_precision_exception.phpt b/Zend/tests/bitwise_not_precision_exception.phpt index fa821100464e..e28bf8f4e17b 100644 --- a/Zend/tests/bitwise_not_precision_exception.phpt +++ b/Zend/tests/bitwise_not_precision_exception.phpt @@ -12,4 +12,4 @@ try { } ?> --EXPECT-- -Implicit conversion from float INF to int loses precision +The float INF is not representable as an int, cast occurred diff --git a/Zend/tests/bug29890.phpt b/Zend/tests/bug29890.phpt index 6f1e874882e6..27cb1b311ea9 100644 --- a/Zend/tests/bug29890.phpt +++ b/Zend/tests/bug29890.phpt @@ -20,4 +20,4 @@ define("TEST",3); ?> --EXPECT-- -error :Constant TEST already defined +error :Constant TEST already defined, this will be an error in PHP 9 diff --git a/Zend/tests/bug34617.phpt b/Zend/tests/bug34617.phpt index a6f3ea8ca7f0..736f31d032e5 100644 --- a/Zend/tests/bug34617.phpt +++ b/Zend/tests/bug34617.phpt @@ -11,7 +11,6 @@ function boom() $thing = new Thing(); xml_set_object($reader, $thing); die("ok\n"); - xml_parser_free($reader); } boom(); ?> diff --git a/Zend/tests/bug40236.phpt b/Zend/tests/bug40236.phpt index 7ed298c1eed6..5fb3fddc573d 100644 --- a/Zend/tests/bug40236.phpt +++ b/Zend/tests/bug40236.phpt @@ -8,7 +8,7 @@ if (extension_loaded("readline")) die("skip Test doesn't support readline"); --EXPECT-- Interactive shell (-a) requires the readline extension. diff --git a/Zend/tests/bug40770.phpt b/Zend/tests/bug40770.phpt index f37d96d5ff33..bdbae4cf8f1a 100644 --- a/Zend/tests/bug40770.phpt +++ b/Zend/tests/bug40770.phpt @@ -4,6 +4,9 @@ Bug #40770 (Apache child exits when PHP memory limit reached) memory_limit=8M --SKIPIF-- ---EXPECTF-- -Warning: feof(): wrapper::stream_eof is not implemented! Assuming EOF in %s on line %d +try { + feof($fp); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} -Fatal error: Uncaught Exception in %s:%d -Stack trace: -#0 [internal function]: wrapper->stream_eof() -#1 %s(%d): feof(Resource id #%d) -#2 {main} - thrown in %s on line %d +?> +--EXPECT-- +Exception: cannot eof diff --git a/Zend/tests/bug46701.phpt b/Zend/tests/bug46701.phpt index e7cc823d85c5..620d5209443e 100644 --- a/Zend/tests/bug46701.phpt +++ b/Zend/tests/bug46701.phpt @@ -27,11 +27,11 @@ new foo; ?> --EXPECTF-- -Deprecated: Implicit conversion from float 3428599296 to int loses precision in %s on line %d +Warning: The float 3428599296 is not representable as an int, cast occurred in %s on line %d -Deprecated: Implicit conversion from float 3459455488 to int loses precision in %s on line %d +Warning: The float 3459455488 is not representable as an int, cast occurred in %s on line %d -Deprecated: Implicit conversion from float 3459616768 to int loses precision in %s on line %d +Warning: The float 3459616768 is not representable as an int, cast occurred in %s on line %d array(3) { [-866368000]=> int(1) @@ -41,10 +41,10 @@ array(3) { int(3) } -Deprecated: Implicit conversion from float 3459455488 to int loses precision in %s on line %d +Warning: The float 3459455488 is not representable as an int, cast occurred in %s on line %d int(2) -Deprecated: Implicit conversion from float 3459616768 to int loses precision in %s on line %d +Warning: The float 3459616768 is not representable as an int, cast occurred in %s on line %d array(1) { [-835350528]=> int(3) diff --git a/Zend/tests/bug55509.phpt b/Zend/tests/bug55509.phpt index b45150a4979e..bdb7da966a5b 100644 --- a/Zend/tests/bug55509.phpt +++ b/Zend/tests/bug55509.phpt @@ -2,6 +2,7 @@ Bug #55509 (segfault on x86_64 using more than 2G memory) --SKIPIF-- ---EXPECT-- +--EXPECTF-- +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d + +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d + +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d + +Deprecated: The backtick (`) operator is deprecated, use shell_exec() instead in %s on line %d Okey diff --git a/Zend/tests/bug67368.phpt b/Zend/tests/bug67368.phpt index f588270f5984..50ca00d36d40 100644 --- a/Zend/tests/bug67368.phpt +++ b/Zend/tests/bug67368.phpt @@ -1,7 +1,5 @@ --TEST-- Bug #67368 (Memory leak with immediately dereferenced array in class constant) ---INI-- -report_memleaks=1 --FILE-- --EXPECTF-- -Warning: Cannot unbind $this of method in %s on line %d +Warning: Cannot unbind $this of method, this will be an error in PHP 9 in %s on line %d int(3) diff --git a/Zend/tests/bug71300.phpt b/Zend/tests/bug71300.phpt index 40734b054933..abf9ebc5307c 100644 --- a/Zend/tests/bug71300.phpt +++ b/Zend/tests/bug71300.phpt @@ -22,7 +22,22 @@ function test2() { var_dump(test2()); ?> --EXPECTF-- +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(4) "test" +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + Warning: Array to string conversion in %s on line %d string(9) "Arraytest" diff --git a/Zend/tests/bug72543_2.phpt b/Zend/tests/bug72543_2.phpt index 2070d65bddc9..fb96cc55449d 100644 --- a/Zend/tests/bug72543_2.phpt +++ b/Zend/tests/bug72543_2.phpt @@ -9,7 +9,8 @@ unset($ref); $arr[0][$arr[0]] = null; var_dump($arr); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d array(1) { [0]=> array(1) { diff --git a/Zend/tests/bug74093.phpt b/Zend/tests/bug74093.phpt index c5fc9da8cbbf..d38d6e5109c4 100644 --- a/Zend/tests/bug74093.phpt +++ b/Zend/tests/bug74093.phpt @@ -1,7 +1,9 @@ --TEST-- Bug #74093 (Maximum execution time of n+2 seconds exceed not written in error_log) +--FLAKY-- --SKIPIF-- --EXPECTF-- diff --git a/Zend/tests/bug77494.phpt b/Zend/tests/bug77494.phpt deleted file mode 100644 index 7f808c2c0f52..000000000000 --- a/Zend/tests/bug77494.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -Bug #77494 (Disabling class causes segfault on member access) ---EXTENSIONS-- -curl ---INI-- -disable_classes=CURLFile,ErrorException ---FILE-- -name); -$b = new ErrorException(); -var_dump($b->message); -?> ---EXPECTF-- -Warning: CURLFile() has been disabled for security reasons in %sbug77494.php on line 2 - -Warning: Undefined property: CURLFile::$name in %s on line %d -NULL - -Warning: ErrorException() has been disabled for security reasons in %s on line %d - -Warning: Undefined property: ErrorException::$message in %s on line %d -NULL diff --git a/Zend/tests/bug78340.phpt b/Zend/tests/bug78340.phpt index 4012e83af6ac..22ea0c19353e 100644 --- a/Zend/tests/bug78340.phpt +++ b/Zend/tests/bug78340.phpt @@ -32,7 +32,7 @@ class lib { function stream_stat() { return [ - 'dev' => 3632233996, + 'dev' => PHP_INT_MAX, 'size' => strlen($this->bytes), 'ino' => $this->ino ]; diff --git a/Zend/tests/bug79668.phpt b/Zend/tests/bug79668.phpt deleted file mode 100644 index 5e73a7469b6f..000000000000 --- a/Zend/tests/bug79668.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Bug #79668 (get_defined_functions(true) may miss functions) ---INI-- -disable_functions=sha1_file,password_hash ---FILE-- - ---EXPECT-- -bool(true) -bool(false) -bool(true) -bool(false) diff --git a/Zend/tests/bug81104.phpt b/Zend/tests/bug81104.phpt index 8e7d7e7d7381..12c137170fe4 100644 --- a/Zend/tests/bug81104.phpt +++ b/Zend/tests/bug81104.phpt @@ -2,7 +2,6 @@ Bug #81104: Warning: "Failed to set memory limit to ... bytes" emitted after exit in debug --INI-- memory_limit=5M -report_memleaks=0 --FILE-- getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, )); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, $array)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, $array, $extraParameter, $trailingComma, )); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(object: $x, withProperties: [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone($x, withProperties: [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(object: $x)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(object: $x, [ "foo" => $foo, "bar" => $bar ])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(...["object" => $x, "withProperties" => [ "foo" => $foo, "bar" => $bar ]])); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + assert(false && $y = clone(...)); +} catch (Error $e) { + echo $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +assert(false && ($y = \clone($x))) +assert(false && ($y = \clone($x))) +assert(false && ($y = \clone($x))) +assert(false && ($y = \clone($x, ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone($x, $array))) +assert(false && ($y = \clone($x, $array, $extraParameter, $trailingComma))) +assert(false && ($y = \clone(object: $x, withProperties: ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone($x, withProperties: ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone(object: $x))) +assert(false && ($y = \clone(object: $x, ['foo' => $foo, 'bar' => $bar]))) +assert(false && ($y = \clone(...['object' => $x, 'withProperties' => ['foo' => $foo, 'bar' => $bar]]))) +assert(false && ($y = \clone(...))) diff --git a/Zend/tests/clone/bug36071.phpt b/Zend/tests/clone/bug36071.phpt index 945118fef375..e1a4baa7226e 100644 --- a/Zend/tests/clone/bug36071.phpt +++ b/Zend/tests/clone/bug36071.phpt @@ -4,11 +4,11 @@ Bug #36071 (Engine Crash related with 'clone') error_reporting=4095 --FILE-- b = 0; +try { + $a = clone 0; +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %sbug36071.php:2 -Stack trace: -#0 {main} - thrown in %sbug36071.php on line 2 +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, int given diff --git a/Zend/tests/clone/bug42817.phpt b/Zend/tests/clone/bug42817.phpt index a681d861d0c8..b5f53222d7ee 100644 --- a/Zend/tests/clone/bug42817.phpt +++ b/Zend/tests/clone/bug42817.phpt @@ -2,11 +2,11 @@ Bug #42817 (clone() on a non-object does not result in a fatal error) --FILE-- b, $c); +try { + $a = clone(null); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %sbug42817.php:2 -Stack trace: -#0 {main} - thrown in %sbug42817.php on line 2 +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, null given diff --git a/Zend/tests/clone/bug42818.phpt b/Zend/tests/clone/bug42818.phpt index b37ce13fd174..08ba05fcfaa2 100644 --- a/Zend/tests/clone/bug42818.phpt +++ b/Zend/tests/clone/bug42818.phpt @@ -2,10 +2,11 @@ Bug #42818 ($foo = clone(array()); leaks memory) --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %sbug42818.php:2 -Stack trace: -#0 {main} - thrown in %sbug42818.php on line 2 +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, array given diff --git a/Zend/tests/clone/clone_001.phpt b/Zend/tests/clone/clone_001.phpt index 87024c3cd561..91fa6f551176 100644 --- a/Zend/tests/clone/clone_001.phpt +++ b/Zend/tests/clone/clone_001.phpt @@ -3,11 +3,12 @@ Using clone statement on non-object --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: __clone method called on non-object in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d +--EXPECT-- +TypeError: clone(): Argument #1 ($object) must be of type object, array given diff --git a/Zend/tests/clone/clone_003.phpt b/Zend/tests/clone/clone_003.phpt index f163616a876d..b8bb2833dc25 100644 --- a/Zend/tests/clone/clone_003.phpt +++ b/Zend/tests/clone/clone_003.phpt @@ -3,13 +3,13 @@ Using clone statement on undefined variable --FILE-- getMessage(), PHP_EOL; +} ?> --EXPECTF-- Warning: Undefined variable $b in %s on line %d - -Fatal error: Uncaught Error: __clone method called on non-object in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d +TypeError: clone(): Argument #1 ($object) must be of type object, null given diff --git a/Zend/tests/clone/clone_005.phpt b/Zend/tests/clone/clone_005.phpt new file mode 100644 index 000000000000..e0366cae67cb --- /dev/null +++ b/Zend/tests/clone/clone_005.phpt @@ -0,0 +1,55 @@ +--TEST-- +Clone as a function. +--FILE-- +clone_me()[0]; + +var_dump($f !== $clone); + +?> +--EXPECTF-- +object(stdClass)#%d (0) { +} +array(3) { + [0]=> + object(stdClass)#%d (0) { + } + [1]=> + object(stdClass)#%d (0) { + } + [2]=> + object(stdClass)#%d (0) { + } +} +array(3) { + [0]=> + object(stdClass)#%d (0) { + } + [1]=> + object(stdClass)#%d (0) { + } + [2]=> + object(stdClass)#%d (0) { + } +} +bool(true) diff --git a/Zend/tests/clone/clone_with_001.phpt b/Zend/tests/clone/clone_with_001.phpt new file mode 100644 index 000000000000..3623706a980c --- /dev/null +++ b/Zend/tests/clone/clone_with_001.phpt @@ -0,0 +1,71 @@ +--TEST-- +Clone with basic +--FILE-- + 'BAZ', + 'array' => [1, 2, 3], +]; + +var_dump(clone $x); +var_dump(clone($x)); +var_dump(clone($x, [ 'foo' => $foo, 'bar' => $bar ])); +var_dump(clone($x, $array)); +var_dump(clone($x, [ 'obj' => $x ])); + +var_dump(clone($x, [ + 'abc', + 'def', + new Dummy(), + 'named' => 'value', +])); + +?> +--EXPECTF-- +object(stdClass)#%d (0) { +} +object(stdClass)#%d (0) { +} +object(stdClass)#%d (2) { + ["foo"]=> + string(3) "FOO" + ["bar"]=> + object(Dummy)#%d (0) { + } +} +object(stdClass)#%d (2) { + ["baz"]=> + string(3) "BAZ" + ["array"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +object(stdClass)#%d (1) { + ["obj"]=> + object(stdClass)#%d (0) { + } +} +object(stdClass)#%d (4) { + ["0"]=> + string(3) "abc" + ["1"]=> + string(3) "def" + ["2"]=> + object(Dummy)#%d (0) { + } + ["named"]=> + string(5) "value" +} diff --git a/Zend/tests/clone/clone_with_002.phpt b/Zend/tests/clone/clone_with_002.phpt new file mode 100644 index 000000000000..8b86e64c76aa --- /dev/null +++ b/Zend/tests/clone/clone_with_002.phpt @@ -0,0 +1,114 @@ +--TEST-- +Clone with respects visiblity +--FILE-- + 'updated A', 'b' => 'updated B', 'c' => 'updated C', 'd' => 'updated D' ]); + } +} + +class C extends P { + public function m2() { + return clone($this, [ 'a' => 'updated A', 'b' => 'updated B', 'c' => 'dynamic C' ]); + } + + public function m3() { + return clone($this, [ 'd' => 'inaccessible' ]); + } +} + +class Unrelated { + public function m3(P $p) { + return clone($p, [ 'b' => 'inaccessible' ]); + } +} + +$p = new P(); + +var_dump(clone($p, [ 'a' => 'updated A' ])); +var_dump($p->m1()); + +$c = new C(); +var_dump($c->m1()); +var_dump($c->m2()); +try { + var_dump($c->m3()); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump(clone($p, [ 'b' => 'inaccessible' ])); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump(clone($p, [ 'd' => 'inaccessible' ])); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump((new Unrelated())->m3($p)); +} catch (Error $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +object(P)#%d (4) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(7) "default" + ["c":"P":private]=> + string(7) "default" + ["d"]=> + string(7) "default" +} +object(P)#%d (4) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(9) "updated B" + ["c":"P":private]=> + string(9) "updated C" + ["d"]=> + string(9) "updated D" +} +object(C)#%d (4) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(9) "updated B" + ["c":"P":private]=> + string(9) "updated C" + ["d"]=> + string(9) "updated D" +} + +Deprecated: Creation of dynamic property C::$c is deprecated in %s on line %d +object(C)#%d (5) { + ["a"]=> + string(9) "updated A" + ["b":protected]=> + string(9) "updated B" + ["c":"P":private]=> + string(7) "default" + ["d"]=> + string(7) "default" + ["c"]=> + string(9) "dynamic C" +} +Error: Cannot modify private(set) property P::$d from scope C +Error: Cannot access protected property P::$b +Error: Cannot modify private(set) property P::$d from global scope +Error: Cannot access protected property P::$b diff --git a/Zend/tests/clone/clone_with_003.phpt b/Zend/tests/clone/clone_with_003.phpt new file mode 100644 index 000000000000..48fb2b1f6a3d --- /dev/null +++ b/Zend/tests/clone/clone_with_003.phpt @@ -0,0 +1,23 @@ +--TEST-- +Clone with supports property hooks +--FILE-- +hooked = strtoupper($value); + } + } +} + +$c = new Clazz(); + +var_dump(clone($c, [ 'hooked' => 'updated' ])); + +?> +--EXPECTF-- +object(Clazz)#%d (1) { + ["hooked"]=> + string(7) "UPDATED" +} diff --git a/Zend/tests/clone/clone_with_004.phpt b/Zend/tests/clone/clone_with_004.phpt new file mode 100644 index 000000000000..e9985d62bd04 --- /dev/null +++ b/Zend/tests/clone/clone_with_004.phpt @@ -0,0 +1,82 @@ +--TEST-- +Clone with evaluation order +--FILE-- +hooked = strtoupper($value); + } + } + + public string $maxLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) > 5) { + throw new \Exception('Length exceeded'); + } + + $this->maxLength = $value; + } + } + + public string $minLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) < 5) { + throw new \Exception('Length unsufficient'); + } + + $this->minLength = $value; + } + } +} + +$c = new Clazz(); + +var_dump(clone($c, [ 'hooked' => 'updated' ])); +echo PHP_EOL; +var_dump(clone($c, [ 'hooked' => 'updated', 'maxLength' => 'abc', 'minLength' => 'abcdef' ])); +echo PHP_EOL; +var_dump(clone($c, [ 'minLength' => 'abcdef', 'hooked' => 'updated', 'maxLength' => 'abc' ])); + +?> +--EXPECTF-- +$hooked::set +object(Clazz)#%d (1) { + ["hooked"]=> + string(7) "UPDATED" + ["maxLength"]=> + uninitialized(string) + ["minLength"]=> + uninitialized(string) +} + +$hooked::set +$maxLength::set +$minLength::set +object(Clazz)#%d (3) { + ["hooked"]=> + string(7) "UPDATED" + ["maxLength"]=> + string(3) "abc" + ["minLength"]=> + string(6) "abcdef" +} + +$minLength::set +$hooked::set +$maxLength::set +object(Clazz)#%d (3) { + ["hooked"]=> + string(7) "UPDATED" + ["maxLength"]=> + string(3) "abc" + ["minLength"]=> + string(6) "abcdef" +} diff --git a/Zend/tests/clone/clone_with_005.phpt b/Zend/tests/clone/clone_with_005.phpt new file mode 100644 index 000000000000..55ffb2423d7e --- /dev/null +++ b/Zend/tests/clone/clone_with_005.phpt @@ -0,0 +1,64 @@ +--TEST-- +Clone with error handling +--FILE-- +hooked = strtoupper($value); + } + } + + public string $maxLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) > 5) { + throw new \Exception('Length exceeded'); + } + + $this->maxLength = $value; + } + } + + public string $minLength { + set { + echo __FUNCTION__, PHP_EOL; + + if (strlen($value) < 5) { + throw new \Exception('Length insufficient'); + } + + $this->minLength = $value; + } + } +} + +$c = new Clazz(); + +try { + var_dump(clone($c, [ 'hooked' => 'updated', 'maxLength' => 'abcdef', 'minLength' => 'abc' ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +echo PHP_EOL; + +try { + var_dump(clone($c, [ 'hooked' => 'updated', 'minLength' => 'abc', 'maxLength' => 'abcdef' ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +$hooked::set +$maxLength::set +Exception: Length exceeded + +$hooked::set +$minLength::set +Exception: Length insufficient diff --git a/Zend/tests/clone/clone_with_006.phpt b/Zend/tests/clone/clone_with_006.phpt new file mode 100644 index 000000000000..7b0b8520b8a8 --- /dev/null +++ b/Zend/tests/clone/clone_with_006.phpt @@ -0,0 +1,16 @@ +--TEST-- +Clone with error cases +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +TypeError: clone(): Argument #2 ($withProperties) must be of type array, int given diff --git a/Zend/tests/clone/clone_with_007.phpt b/Zend/tests/clone/clone_with_007.phpt new file mode 100644 index 000000000000..08cefd7f8cbe --- /dev/null +++ b/Zend/tests/clone/clone_with_007.phpt @@ -0,0 +1,29 @@ +--TEST-- +Clone with supports __clone +--FILE-- +foo = 'foo updated in __clone'; + $this->bar = 'bar updated in __clone'; + } +} + +$c = new Clazz('foo', 'bar'); + +var_dump(clone($c, [ 'foo' => 'foo updated in clone-with' ])); + +?> +--EXPECTF-- +object(Clazz)#%d (2) { + ["foo"]=> + string(25) "foo updated in clone-with" + ["bar"]=> + string(22) "bar updated in __clone" +} diff --git a/Zend/tests/clone/clone_with_008.phpt b/Zend/tests/clone/clone_with_008.phpt new file mode 100644 index 000000000000..aa2c639fb7f1 --- /dev/null +++ b/Zend/tests/clone/clone_with_008.phpt @@ -0,0 +1,40 @@ +--TEST-- +Clone with readonly +--FILE-- +b = '__clone'; + } +} + +$c = new Clazz('default', 'default'); + +var_dump(clone($c, [ 'a' => "with" ])); + +try { + var_dump(clone($c, [ 'b' => "with" ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +object(Clazz)#%d (2) { + ["a"]=> + string(4) "with" + ["b"]=> + string(7) "__clone" +} +object(Clazz)#%d (2) { + ["a"]=> + string(7) "default" + ["b"]=> + string(4) "with" +} diff --git a/Zend/tests/clone/clone_with_009.phpt b/Zend/tests/clone/clone_with_009.phpt new file mode 100644 index 000000000000..c6a7d2d18b98 --- /dev/null +++ b/Zend/tests/clone/clone_with_009.phpt @@ -0,0 +1,72 @@ +--TEST-- +Clone with lazy objects +--FILE-- + 2 ]); + + var_dump($reflector->isUninitializedLazyObject($obj)); + var_dump($obj); + var_dump($reflector->isUninitializedLazyObject($clone)); + var_dump($clone); +} + +$reflector = new ReflectionClass(C::class); + +$obj = $reflector->newLazyGhost(function ($obj) { + var_dump("initializer"); + $obj->__construct(); +}); + +test('Ghost', $obj); + +$obj = $reflector->newLazyProxy(function ($obj) { + var_dump("initializer"); + return new C(); +}); + +test('Proxy', $obj); + +?> +--EXPECTF-- +# Ghost: +string(11) "initializer" +bool(false) +object(C)#%d (1) { + ["a"]=> + int(1) +} +bool(false) +object(C)#%d (1) { + ["a"]=> + int(2) +} +# Proxy: +string(11) "initializer" +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(1) + } +} +bool(false) +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(2) + } +} diff --git a/Zend/tests/clone/clone_with_010.phpt b/Zend/tests/clone/clone_with_010.phpt new file mode 100644 index 000000000000..29ecf714fc49 --- /dev/null +++ b/Zend/tests/clone/clone_with_010.phpt @@ -0,0 +1,21 @@ +--TEST-- +Clone with native classes +--FILE-- + "something" ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +try { + var_dump(clone(new \Random\Engine\Xoshiro256StarStar(), [ 'with' => "something" ])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Error: Trying to clone an uncloneable object of class Random\Engine\Secure +Error: Cannot create dynamic property Random\Engine\Xoshiro256StarStar::$with diff --git a/Zend/tests/clone/clone_with_011.phpt b/Zend/tests/clone/clone_with_011.phpt new file mode 100644 index 000000000000..5f8e99bb65f2 --- /dev/null +++ b/Zend/tests/clone/clone_with_011.phpt @@ -0,0 +1,18 @@ +--TEST-- +Clone with name mangling +--FILE-- + 'updated'])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Error: Cannot access property starting with "\0" diff --git a/Zend/tests/clone/clone_with_012.phpt b/Zend/tests/clone/clone_with_012.phpt new file mode 100644 index 000000000000..e24f0adad7c4 --- /dev/null +++ b/Zend/tests/clone/clone_with_012.phpt @@ -0,0 +1,35 @@ +--TEST-- +Clone with property hook updating readonly property +--FILE-- +foo = $value; + $this->bar = 'bar updated in hook'; + } + } + + public public(set) readonly string $bar; +} + +$f = new Clazz(); + +var_dump(clone($f, ['foo' => 'foo updated in clone-with'])); + +try { + var_dump(clone($f, ['foo' => 'foo updated in clone-with', 'bar' => 'bar updated in clone-with'])); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +object(Clazz)#%d (2) { + ["foo"]=> + string(25) "foo updated in clone-with" + ["bar"]=> + string(19) "bar updated in hook" +} +Error: Cannot modify readonly property Clazz::$bar diff --git a/Zend/tests/clone/clone_with_013.phpt b/Zend/tests/clone/clone_with_013.phpt new file mode 100644 index 000000000000..13f246325585 --- /dev/null +++ b/Zend/tests/clone/clone_with_013.phpt @@ -0,0 +1,31 @@ +--TEST-- +Clone with references +--FILE-- + &$ref]; + +try { + var_dump(clone($x, $with)); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +unset($ref); + +try { + var_dump(clone($x, $with)); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +Error: Cannot assign by reference when cloning with updated properties +object(stdClass)#%d (1) { + ["x"]=> + string(9) "reference" +} diff --git a/Zend/tests/closures/bug70630.phpt b/Zend/tests/closures/bug70630.phpt index 0e9e5449758f..c75920899652 100644 --- a/Zend/tests/closures/bug70630.phpt +++ b/Zend/tests/closures/bug70630.phpt @@ -7,4 +7,4 @@ $x = (new ReflectionFunction("substr"))->getClosure(); $x->call(new a); ?> --EXPECTF-- -Warning: Cannot rebind scope of closure created from function in %s on line %d +Warning: Cannot rebind scope of closure created from function, this will be an error in PHP 9 in %s on line %d diff --git a/Zend/tests/closures/bug70685.phpt b/Zend/tests/closures/bug70685.phpt index 737b4469fdbe..7cb6aa094de4 100644 --- a/Zend/tests/closures/bug70685.phpt +++ b/Zend/tests/closures/bug70685.phpt @@ -15,8 +15,8 @@ var_dump($c); ?> --EXPECTF-- -Warning: Cannot bind method SplDoublyLinkedList::count() to object of class cls in %s on line %d +Warning: Cannot bind method SplDoublyLinkedList::count() to object of class cls, this will be an error in PHP 9 in %s on line %d NULL -Warning: Cannot rebind scope of closure created from method in %s on line %d +Warning: Cannot rebind scope of closure created from method, this will be an error in PHP 9 in %s on line %d NULL diff --git a/Zend/tests/closures/closure_016.phpt b/Zend/tests/closures/closure_016.phpt index 0f87f20f435a..33860189a57e 100644 --- a/Zend/tests/closures/closure_016.phpt +++ b/Zend/tests/closures/closure_016.phpt @@ -42,9 +42,9 @@ Foo::__invoke bool(true) Foo::__invoke bool(true) -Closure::__invoke +{closure:foo():9} bool(true) -Closure::__invoke +{closure:foo():9} bool(true) Closure::__invoke bool(true) diff --git a/Zend/tests/closures/closure_040.phpt b/Zend/tests/closures/closure_040.phpt index 436c99939b1e..b733bdbef053 100644 --- a/Zend/tests/closures/closure_040.phpt +++ b/Zend/tests/closures/closure_040.phpt @@ -36,4 +36,4 @@ $cas->bindTo($a, 'A'); --EXPECTF-- Closure::bindTo(): Argument #2 ($newScope) must be of type object|string|null, array given -Warning: Cannot bind an instance to a static closure in %s on line %d +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d diff --git a/Zend/tests/closures/closure_041.phpt b/Zend/tests/closures/closure_041.phpt index d70925748411..64afde4ea22b 100644 --- a/Zend/tests/closures/closure_041.phpt +++ b/Zend/tests/closures/closure_041.phpt @@ -80,16 +80,16 @@ bound: no scoped to A: bool(true) bound: no -Warning: Cannot unbind $this of closure using $this in %s on line %d +Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d NULL After binding, with same-class instance for the bound ones -Warning: Cannot bind an instance to a static closure in %s on line %d +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d scoped to A: bool(false) bound: A (should be scoped to dummy class) -Warning: Cannot bind an instance to a static closure in %s on line %d +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d scoped to A: bool(true) bound: A After binding, with different instance for the bound ones diff --git a/Zend/tests/closures/closure_043.phpt b/Zend/tests/closures/closure_043.phpt index bfcd37b38e1f..8f60bd272469 100644 --- a/Zend/tests/closures/closure_043.phpt +++ b/Zend/tests/closures/closure_043.phpt @@ -56,9 +56,9 @@ bool(false) After binding, null scope, with instance -Warning: Cannot bind an instance to a static closure in %s on line %d +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d -Warning: Cannot bind an instance to a static closure in %s on line %d +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d After binding, with scope, no instance bool(true) bool(false) @@ -68,7 +68,7 @@ bool(false) After binding, with scope, with instance -Warning: Cannot bind an instance to a static closure in %s on line %d +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d -Warning: Cannot bind an instance to a static closure in %s on line %d +Warning: Cannot bind an instance to a static closure, this will be an error in PHP 9 in %s on line %d Done. diff --git a/Zend/tests/closures/closure_044.phpt b/Zend/tests/closures/closure_044.phpt index 544ad8bee844..624450c16881 100644 --- a/Zend/tests/closures/closure_044.phpt +++ b/Zend/tests/closures/closure_044.phpt @@ -52,7 +52,7 @@ bool(false) bool(false) -Warning: Cannot unbind $this of closure using $this in %s on line %d +Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d NULL After binding, null scope, with instance @@ -67,7 +67,7 @@ bool(true) bool(false) -Warning: Cannot unbind $this of closure using $this in %s on line %d +Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d NULL After binding, with scope, with instance diff --git a/Zend/tests/closures/closure_046.phpt b/Zend/tests/closures/closure_046.phpt index 9dbcba5ce544..19dd69e2a6fd 100644 --- a/Zend/tests/closures/closure_046.phpt +++ b/Zend/tests/closures/closure_046.phpt @@ -50,7 +50,7 @@ bool(false) bool(false) -Warning: Cannot unbind $this of closure using $this in %s on line %d +Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d NULL After binding, with same-class instance for the bound one diff --git a/Zend/tests/closures/closure_061.phpt b/Zend/tests/closures/closure_061.phpt index 240f22e036ef..23ab2f87a1c5 100644 --- a/Zend/tests/closures/closure_061.phpt +++ b/Zend/tests/closures/closure_061.phpt @@ -118,13 +118,13 @@ bindTo(new Cls, null): Success! bindTo(new Cls, Cls::class): -Cannot rebind scope of closure created from function +Cannot rebind scope of closure created from function, this will be an error in PHP 9 bindTo(null, Cls::class): -Cannot rebind scope of closure created from function +Cannot rebind scope of closure created from function, this will be an error in PHP 9 bindTo(null, stdClass::class): -Cannot bind closure to scope of internal class stdClass +Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9 bindTo(new stdClass, null): Success! @@ -139,13 +139,13 @@ bindTo(new Cls, null): Success! bindTo(new Cls, Cls::class): -Cannot rebind scope of closure created from function +Cannot rebind scope of closure created from function, this will be an error in PHP 9 bindTo(null, Cls::class): -Cannot rebind scope of closure created from function +Cannot rebind scope of closure created from function, this will be an error in PHP 9 bindTo(null, stdClass::class): -Cannot bind closure to scope of internal class stdClass +Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9 bindTo(new stdClass, null): Success! @@ -157,25 +157,25 @@ bindTo(null, Cls::class): Success! bindTo(new Cls, null): -Cannot bind an instance to a static closure +Cannot bind an instance to a static closure, this will be an error in PHP 9 bindTo(new Cls, Cls::class): -Cannot bind an instance to a static closure +Cannot bind an instance to a static closure, this will be an error in PHP 9 bindTo(null, null): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 bindTo(null, ClsChild::class): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 bindTo(null, ClsUnrelated::class): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 (new Cls)->method() ------------------- bindTo(null, Cls::class): -Cannot unbind $this of method +Cannot unbind $this of method, this will be an error in PHP 9 bindTo(new Cls, Cls::class): Success! @@ -184,16 +184,16 @@ bindTo(new ClsChild, Cls::class): Success! bindTo(new ClsUnrelated, Cls::class): -Cannot bind method Cls::method() to object of class ClsUnrelated +Cannot bind method Cls::method() to object of class ClsUnrelated, this will be an error in PHP 9 bindTo(new Cls, null): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 bindTo(new Cls, ClsUnrelated::class): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 bindTo(new Cls, ClsChild::class): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 (new SplDoublyLinkedList)->count() ---------------------------------- @@ -205,19 +205,19 @@ bindTo(new SplStack, SplDoublyLinkedList::class): Success! bindTo(new ClsUnrelated, SplDoublyLinkedList::class): -Cannot bind method SplDoublyLinkedList::count() to object of class ClsUnrelated +Cannot bind method SplDoublyLinkedList::count() to object of class ClsUnrelated, this will be an error in PHP 9 bindTo(null, null): -Cannot unbind $this of method +Cannot unbind $this of method, this will be an error in PHP 9 bindTo(null, SplDoublyLinkedList::class): -Cannot unbind $this of method +Cannot unbind $this of method, this will be an error in PHP 9 bindTo(new SplDoublyLinkedList, null): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 bindTo(new SplDoublyLinkedList, ClsUnrelated::class): -Cannot rebind scope of closure created from method +Cannot rebind scope of closure created from method, this will be an error in PHP 9 (function() {})() ----------------- @@ -235,7 +235,7 @@ bindTo(null, Cls::class): Success! bindTo(null, stdClass::class): -Cannot bind closure to scope of internal class stdClass +Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9 bindTo(new stdClass, null): Success! diff --git a/Zend/tests/closures/closure_062.phpt b/Zend/tests/closures/closure_062.phpt index b8c0a981be52..d3db7998eea1 100644 --- a/Zend/tests/closures/closure_062.phpt +++ b/Zend/tests/closures/closure_062.phpt @@ -48,7 +48,7 @@ Test::staticMethod(); --EXPECTF-- instance scoped, non-static, $this used -Warning: Cannot unbind $this of closure using $this in %s on line %d +Warning: Cannot unbind $this of closure using $this, this will be an error in PHP 9 in %s on line %d instance scoped, static, $this used instance scoped, non-static, $this not used static scoped, non-static, $this used diff --git a/Zend/tests/038.phpt b/Zend/tests/closures/closure_array_key_error.phpt similarity index 100% rename from Zend/tests/038.phpt rename to Zend/tests/closures/closure_array_key_error.phpt diff --git a/Zend/tests/036.phpt b/Zend/tests/closures/closure_array_offset_error.phpt similarity index 100% rename from Zend/tests/036.phpt rename to Zend/tests/closures/closure_array_offset_error.phpt diff --git a/Zend/tests/closures/closure_call.phpt b/Zend/tests/closures/closure_call.phpt index f665c67ff691..cfc5f51af966 100644 --- a/Zend/tests/closures/closure_call.phpt +++ b/Zend/tests/closures/closure_call.phpt @@ -61,7 +61,7 @@ int(0) int(0) int(3) -Warning: Cannot bind closure to scope of internal class stdClass in %s line %d +Warning: Cannot bind closure to scope of internal class stdClass, this will be an error in PHP 9 in %s line %d NULL int(21) int(3) diff --git a/Zend/tests/closures/closure_from_callable_rebinding.phpt b/Zend/tests/closures/closure_from_callable_rebinding.phpt index 6fb5c6ffc1d0..c23841a30c3a 100644 --- a/Zend/tests/closures/closure_from_callable_rebinding.phpt +++ b/Zend/tests/closures/closure_from_callable_rebinding.phpt @@ -17,4 +17,4 @@ $fn->call(new B); ?> --EXPECTF-- -Warning: Cannot bind method A::method() to object of class B in %s on line %d +Warning: Cannot bind method A::method() to object of class B, this will be an error in PHP 9 in %s on line %d diff --git a/Zend/tests/closures/closure_get_current.phpt b/Zend/tests/closures/closure_get_current.phpt new file mode 100644 index 000000000000..3024ff355b55 --- /dev/null +++ b/Zend/tests/closures/closure_get_current.phpt @@ -0,0 +1,64 @@ +--TEST-- +Closure::getCurrent() +--FILE-- +getMessage(), "\n"; +} + +function foo() { + var_dump(Closure::getCurrent()); +} + +try { + foo(...)(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +int(1) +int(1) +int(2) +int(2) +int(3) +int(3) +int(4) +int(4) +int(5) +int(5) +int(6) +int(6) +int(7) +int(7) +int(8) +int(8) +int(9) +int(9) +int(10) +int(10) +int(11) +Current function is not a closure +Current function is not a closure diff --git a/Zend/tests/037.phpt b/Zend/tests/closures/closure_static_property_error.phpt similarity index 100% rename from Zend/tests/037.phpt rename to Zend/tests/closures/closure_static_property_error.phpt diff --git a/Zend/tests/closures/fcc-cache.phpt b/Zend/tests/closures/fcc-cache.phpt new file mode 100644 index 000000000000..3b47a2410d14 --- /dev/null +++ b/Zend/tests/closures/fcc-cache.phpt @@ -0,0 +1,8 @@ +--TEST-- +FCCs are cached and shared +--FILE-- + +--EXPECT-- +bool(true) diff --git a/Zend/tests/closures/gh12073.phpt b/Zend/tests/closures/gh12073.phpt index ef115685ce7d..811da788d03f 100644 --- a/Zend/tests/closures/gh12073.phpt +++ b/Zend/tests/closures/gh12073.phpt @@ -2,6 +2,9 @@ GH-12073: Freeing of non-ZMM pointer of incompletely allocated closure --SKIPIF-- +--EXPECT-- +usage1() func1() a1=a1 a2=a2 a3=m3+ +usage1() [function] func1() a1=a1 a2=m2+ a3=m3+ diff --git a/Zend/tests/closures/gh19653_2.phpt b/Zend/tests/closures/gh19653_2.phpt new file mode 100644 index 000000000000..7eb837dd22c4 --- /dev/null +++ b/Zend/tests/closures/gh19653_2.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-19653 (Closure named argument unpacking between temporary closures can cause a crash) - eval variation +--CREDITS-- +arnaud-lb +--FILE-- + +--EXPECTF-- +int(1) + +Fatal error: Uncaught Error: Unknown named parameter $a in %s:%d +Stack trace: +#0 %s(%d): usage1(Object(Closure)) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/closures/gh19653_3.phpt b/Zend/tests/closures/gh19653_3.phpt new file mode 100644 index 000000000000..7a9ac589182c --- /dev/null +++ b/Zend/tests/closures/gh19653_3.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-19653 (Closure named argument unpacking between temporary closures can cause a crash) - temporary method variation +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Unknown named parameter $tmpMethodParamName in %s:%d +Stack trace: +#0 %s(%d): usage1(Object(Closure)) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/concat/bug79836.phpt b/Zend/tests/concat/bug79836.phpt index 5fb07396762f..87db27633709 100644 --- a/Zend/tests/concat/bug79836.phpt +++ b/Zend/tests/concat/bug79836.phpt @@ -8,6 +8,7 @@ $counter = 0; ob_start(function ($buffer) use (&$c, &$counter) { $c = 0; ++$counter; + return ''; }, 1); $c .= []; $c .= []; diff --git a/Zend/tests/concat/bug79836_1.phpt b/Zend/tests/concat/bug79836_1.phpt index 86e7f4767184..972b38723569 100644 --- a/Zend/tests/concat/bug79836_1.phpt +++ b/Zend/tests/concat/bug79836_1.phpt @@ -7,6 +7,7 @@ opcache.optimization_level = 0x7FFEBFFF & ~0x400 $x = 'non-empty'; ob_start(function () use (&$c) { $c = 0; + return ''; }, 1); $c = []; $x = $c . $x; diff --git a/Zend/tests/concat/bug79836_2.phpt b/Zend/tests/concat/bug79836_2.phpt index b02fcc13ea11..de528e5c42fa 100644 --- a/Zend/tests/concat/bug79836_2.phpt +++ b/Zend/tests/concat/bug79836_2.phpt @@ -6,6 +6,7 @@ $c = str_repeat("abcd", 10); ob_start(function () use (&$c) { $c = 0; + return ''; }, 1); class X { diff --git a/Zend/tests/concat/concat_003.phpt b/Zend/tests/concat/concat_003.phpt index dc22bae1a720..52594dffcfd2 100644 --- a/Zend/tests/concat/concat_003.phpt +++ b/Zend/tests/concat/concat_003.phpt @@ -11,7 +11,7 @@ if (getenv('SKIP_PERF_SENSITIVE')) die("skip performance sensitive test"); $time = microtime(TRUE); /* This might vary on Linux/Windows, so the worst case and also count in slow machines. */ -$t_max = 1.0; +$t_max = 2.0; $datas = array_fill(0, 220000, [ '000.000.000.000', diff --git a/Zend/tests/constants/008.phpt b/Zend/tests/constants/008.phpt index f690cee8e983..14e074e5d30a 100644 --- a/Zend/tests/constants/008.phpt +++ b/Zend/tests/constants/008.phpt @@ -27,13 +27,13 @@ echo "Done\n"; --EXPECTF-- TypeError: define(): Argument #1 ($constant_name) must be of type string, array given -Warning: Constant TRUE already defined in %s on line %d +Warning: Constant TRUE already defined, this will be an error in PHP 9 in %s on line %d bool(false) bool(true) bool(true) bool(true) -Warning: Constant test const already defined in %s on line %d +Warning: Constant test const already defined, this will be an error in PHP 9 in %s on line %d bool(false) bool(true) bool(true) diff --git a/Zend/tests/constants/class_constants_005.phpt b/Zend/tests/constants/class_constants_005.phpt index de53c2c0caa5..7accce13f208 100644 --- a/Zend/tests/constants/class_constants_005.phpt +++ b/Zend/tests/constants/class_constants_005.phpt @@ -4,7 +4,7 @@ String interning during constants substitution opcache.enable_cli=0 --FILE-- diff --git a/Zend/tests/constants/constants_001.phpt b/Zend/tests/constants/constants_001.phpt index 7b274d6fd9c3..95e22736c10e 100644 --- a/Zend/tests/constants/constants_001.phpt +++ b/Zend/tests/constants/constants_001.phpt @@ -17,7 +17,7 @@ var_dump(constant('1foo')); ?> --EXPECTF-- -Warning: Constant 1 already defined in %s on line %d +Warning: Constant 1 already defined, this will be an error in PHP 9 in %s on line %d int(2) int(2) int(2) diff --git a/Zend/tests/constants/constants_004.phpt b/Zend/tests/constants/constants_004.phpt index e98141536125..b1482a50ece1 100644 --- a/Zend/tests/constants/constants_004.phpt +++ b/Zend/tests/constants/constants_004.phpt @@ -10,4 +10,4 @@ const foo = 2; ?> --EXPECTF-- -Warning: Constant foo\foo already defined in %s on line %d +Warning: Constant foo\foo already defined, this will be an error in PHP 9 in %s on line %d diff --git a/Zend/tests/constants/constants_008.phpt b/Zend/tests/constants/constants_008.phpt index 17c6904579ca..857589ce23dd 100644 --- a/Zend/tests/constants/constants_008.phpt +++ b/Zend/tests/constants/constants_008.phpt @@ -13,5 +13,5 @@ if (defined('a')) { ?> --EXPECTF-- -Warning: Constant a already defined in %s on line %d +Warning: Constant a already defined, this will be an error in PHP 9 in %s on line %d 2 diff --git a/Zend/tests/constants/gh18850.inc b/Zend/tests/constants/gh18850.inc new file mode 100644 index 000000000000..08099278ea3f --- /dev/null +++ b/Zend/tests/constants/gh18850.inc @@ -0,0 +1,5 @@ + +--EXPECT-- +int(62) +int(62) diff --git a/Zend/tests/constants/halt_compiler/bug53305.phpt b/Zend/tests/constants/halt_compiler/bug53305.phpt index c76b582e244a..abf40d9fd620 100644 --- a/Zend/tests/constants/halt_compiler/bug53305.phpt +++ b/Zend/tests/constants/halt_compiler/bug53305.phpt @@ -14,6 +14,6 @@ var_dump(constant('__COMPILER_HALT_OFFSET__1'.chr(0))); ?> --EXPECTF-- -Warning: Constant __COMPILER_HALT_OFFSET__ already defined in %s on line %d +Warning: Constant __COMPILER_HALT_OFFSET__ already defined, this will be an error in PHP 9 in %s on line %d int(1) int(4) diff --git a/Zend/tests/constants/halt_compiler/halt_compiler3.phpt b/Zend/tests/constants/halt_compiler/halt_compiler3.phpt index ff25b1333363..412c8cf2220e 100644 --- a/Zend/tests/constants/halt_compiler/halt_compiler3.phpt +++ b/Zend/tests/constants/halt_compiler/halt_compiler3.phpt @@ -5,4 +5,4 @@ __HALT_COMPILER(); bad define() of __COMPILER_HALT_OFFSET__ 1 define ('__COMPILER_HALT_OFFSET__', 1); ?> --EXPECTF-- -Warning: Constant __COMPILER_HALT_OFFSET__ already defined in %s on line %d +Warning: Constant __COMPILER_HALT_OFFSET__ already defined, this will be an error in PHP 9 in %s on line %d diff --git a/Zend/tests/constants/halt_compiler/halt_compiler4.phpt b/Zend/tests/constants/halt_compiler/halt_compiler4.phpt index bb96f25ed96b..2a1997eca22d 100644 --- a/Zend/tests/constants/halt_compiler/halt_compiler4.phpt +++ b/Zend/tests/constants/halt_compiler/halt_compiler4.phpt @@ -7,4 +7,4 @@ __HALT_COMPILER(); ?> ==DONE== --EXPECTF-- -Warning: Constant __COMPILER_HALT_OFFSET__ already defined in %s on line %d +Warning: Constant __COMPILER_HALT_OFFSET__ already defined, this will be an error in PHP 9 in %s on line %d diff --git a/Zend/tests/constexpr/constant_expressions_dynamic.phpt b/Zend/tests/constexpr/constant_expressions_dynamic.phpt index c5c67248df90..c2f8ded98d9b 100644 --- a/Zend/tests/constexpr/constant_expressions_dynamic.phpt +++ b/Zend/tests/constexpr/constant_expressions_dynamic.phpt @@ -48,6 +48,8 @@ var_dump( Warning: A non-numeric value encountered in %s on line %d Deprecated: Implicit conversion from float 3.14 to int loses precision in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d int(3) string(4) "1foo" bool(false) diff --git a/Zend/tests/ctor_promotion/ctor_promotion_callable_type.phpt b/Zend/tests/ctor_promotion/ctor_promotion_callable_type.phpt index ae10512ad54a..85f36bc727bf 100644 --- a/Zend/tests/ctor_promotion/ctor_promotion_callable_type.phpt +++ b/Zend/tests/ctor_promotion/ctor_promotion_callable_type.phpt @@ -4,9 +4,11 @@ Type of promoted property may not be callable --EXPECTF-- -Fatal error: Property Test::$callable cannot have type callable in %s on line %d +Fatal error: Property Test::$callable cannot have type callable in %s on line 5 diff --git a/Zend/tests/ctor_promotion/ctor_promotion_final.phpt b/Zend/tests/ctor_promotion/ctor_promotion_final.phpt new file mode 100644 index 000000000000..abfb5b708808 --- /dev/null +++ b/Zend/tests/ctor_promotion/ctor_promotion_final.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-20377: Constructor promotion with a final property without visibility set +--FILE-- + +--EXPECTF-- +object(Demo)#%d (2) { + ["foo"]=> + string(5) "first" + ["bar"]=> + string(6) "second" +} diff --git a/Zend/tests/debug_info/debug_info.phpt b/Zend/tests/debug_info/debug_info.phpt index 6f559eb40b7a..e7bb4d48aec6 100644 --- a/Zend/tests/debug_info/debug_info.phpt +++ b/Zend/tests/debug_info/debug_info.phpt @@ -21,6 +21,12 @@ class Bar { } } +class Baz { + public function __debugInfo(): ?array { + return null; + } +} + $f = new Foo; var_dump($f); @@ -28,6 +34,7 @@ $b = new Bar; var_dump($b); ?> --EXPECTF-- +Deprecated: Returning null from Baz::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d object(Foo)#%d (3) { ["a"]=> int(1) @@ -36,5 +43,7 @@ object(Foo)#%d (3) { ["c":"Foo":private]=> int(3) } + +Deprecated: Returning null from Bar::__debugInfo() is deprecated, return an empty array instead in %s on line %d object(Bar)#%d (0) { } diff --git a/Zend/tests/debug_info/recursion_return_null.phpt b/Zend/tests/debug_info/recursion_return_null.phpt new file mode 100644 index 000000000000..b6ca9c824cb7 --- /dev/null +++ b/Zend/tests/debug_info/recursion_return_null.phpt @@ -0,0 +1,31 @@ +--TEST-- +Testing __debugInfo() magic method +--FILE-- + +--EXPECTF-- +in handler + +Deprecated: Returning null from Foo::__debugInfo() is deprecated, return an empty array instead in %s on line %d +object(Foo)#3 (0) { +} +object(Foo)#2 (0) { +} diff --git a/Zend/tests/declare/gh18033_2.phpt b/Zend/tests/declare/gh18033_2.phpt index 8fdcff1b51e6..39fb46144eed 100644 --- a/Zend/tests/declare/gh18033_2.phpt +++ b/Zend/tests/declare/gh18033_2.phpt @@ -11,6 +11,7 @@ ob_start(function() { register_tick_function( function() { } ); + return ''; }); ?> --EXPECT-- diff --git a/Zend/tests/disable_classes_warning.phpt b/Zend/tests/disable_classes_warning.phpt new file mode 100644 index 000000000000..c3692bf52972 --- /dev/null +++ b/Zend/tests/disable_classes_warning.phpt @@ -0,0 +1,27 @@ +--TEST-- +Check that warning is emitted when disabling classes +--INI-- +disable_classes=Exception +--FILE-- + +--EXPECTF-- +object(Exception)#1 (7) { + ["message":protected]=> + string(0) "" + ["string":"Exception":private]=> + string(0) "" + ["code":protected]=> + int(0) + ["file":protected]=> + string(%d) "%s" + ["line":protected]=> + int(2) + ["trace":"Exception":private]=> + array(0) { + } + ["previous":"Exception":private]=> + NULL +} diff --git a/Zend/tests/dval_to_lval_32.phpt b/Zend/tests/dval_to_lval_32.phpt deleted file mode 100644 index 89acf9076ad7..000000000000 --- a/Zend/tests/dval_to_lval_32.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -zend_dval_to_lval preserves low bits (32 bit long) ---SKIPIF-- - ---FILE-- - ---EXPECT-- -int(-2056257536) -int(-2055733248) -int(-2055208960) -int(-2054684672) -int(-2054160384) -int(2147483647) diff --git a/Zend/tests/dval_to_lval_64.phpt b/Zend/tests/dval_to_lval_64.phpt deleted file mode 100644 index b54f861bf55c..000000000000 --- a/Zend/tests/dval_to_lval_64.phpt +++ /dev/null @@ -1,29 +0,0 @@ ---TEST-- -zend_dval_to_lval preserves low bits (64 bit long) ---SKIPIF-- - ---FILE-- - ---EXPECT-- -int(2943463994971652096) -int(2943463994972176384) -int(2943463994972700672) -int(2943463994973224960) -int(2943463994973749248) diff --git a/Zend/tests/025.phpt b/Zend/tests/dynamic_call/dynamic_method_calls.phpt similarity index 100% rename from Zend/tests/025.phpt rename to Zend/tests/dynamic_call/dynamic_method_calls.phpt diff --git a/Zend/tests/dynamic_call/variable_variables_curly_syntax.phpt b/Zend/tests/dynamic_call/variable_variables_curly_syntax.phpt new file mode 100644 index 000000000000..217ad5a3a304 --- /dev/null +++ b/Zend/tests/dynamic_call/variable_variables_curly_syntax.phpt @@ -0,0 +1,24 @@ +--TEST-- +Testing dynamic calls using variable variables with curly syntax +--FILE-- + +--EXPECTF-- +bool(true) + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d +bool(true) diff --git a/Zend/tests/023.phpt b/Zend/tests/dynamic_call/variable_variables_function_names.phpt similarity index 100% rename from Zend/tests/023.phpt rename to Zend/tests/dynamic_call/variable_variables_function_names.phpt diff --git a/Zend/tests/enum/__debugInfo.phpt b/Zend/tests/enum/__debugInfo.phpt deleted file mode 100644 index 33e0f49851f9..000000000000 --- a/Zend/tests/enum/__debugInfo.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Enum __debugInfo ---FILE-- -cases(); - } -} - -?> ---EXPECTF-- -Fatal error: Enum Foo cannot include magic method __debugInfo in %s on line %d diff --git a/Zend/tests/enum/backed-from-unknown-hash.phpt b/Zend/tests/enum/backed-from-unknown-hash.phpt index eb5938d0d653..bc82a8d63350 100644 --- a/Zend/tests/enum/backed-from-unknown-hash.phpt +++ b/Zend/tests/enum/backed-from-unknown-hash.phpt @@ -13,5 +13,6 @@ $s++; var_dump(Foo::from($s)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d enum(Foo::Bar) diff --git a/Zend/tests/enum/backed-tryFrom-unknown-hash.phpt b/Zend/tests/enum/backed-tryFrom-unknown-hash.phpt index 80ffe1dc3908..133144edfac6 100644 --- a/Zend/tests/enum/backed-tryFrom-unknown-hash.phpt +++ b/Zend/tests/enum/backed-tryFrom-unknown-hash.phpt @@ -13,5 +13,6 @@ $s++; var_dump(Foo::tryFrom($s)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d enum(Foo::Bar) diff --git a/Zend/tests/enum/comparison-internal.phpt b/Zend/tests/enum/comparison-internal.phpt new file mode 100644 index 000000000000..b07c0e1dba8d --- /dev/null +++ b/Zend/tests/enum/comparison-internal.phpt @@ -0,0 +1,54 @@ +--TEST-- +Enum comparison (internal enum) +--EXTENSIONS-- +zend_test +--FILE-- + $foo); +var_dump($foo < $foo); +var_dump($foo >= $foo); +var_dump($foo <= $foo); + +var_dump($foo > $bar); +var_dump($foo < $bar); +var_dump($foo >= $bar); +var_dump($foo <= $bar); + +var_dump($foo > true); +var_dump($foo < true); +var_dump($foo >= true); +var_dump($foo <= true); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) diff --git a/Zend/tests/enum/debugInfo/backed_enum_value.phpt b/Zend/tests/enum/debugInfo/backed_enum_value.phpt new file mode 100644 index 000000000000..2bf56eb3a59e --- /dev/null +++ b/Zend/tests/enum/debugInfo/backed_enum_value.phpt @@ -0,0 +1,21 @@ +--TEST-- +Enum with __debugInfo() magic method - backed enum value accessible +--FILE-- +name . ' = ' . $this->value]; + } +} + +var_dump(Foo::Bar); + +?> +--EXPECT-- +enum(Foo::Bar) (1) { + [0]=> + string(14) "Foo::Bar = Baz" +} diff --git a/Zend/tests/enum/debugInfo/magic_method.phpt b/Zend/tests/enum/debugInfo/magic_method.phpt new file mode 100644 index 000000000000..4c5963f73b26 --- /dev/null +++ b/Zend/tests/enum/debugInfo/magic_method.phpt @@ -0,0 +1,21 @@ +--TEST-- +Enum supports __debugInfo() magic method +--FILE-- +name . ' is a case of the ' . __CLASS__ . ' enum']; + } +} + +var_dump(Foo::Bar); + +?> +--EXPECT-- +enum(Foo::Bar) (1) { + [0]=> + string(29) "Bar is a case of the Foo enum" +} diff --git a/Zend/tests/enum/debugInfo/missing_magic.phpt b/Zend/tests/enum/debugInfo/missing_magic.phpt new file mode 100644 index 000000000000..9cb5b0c69e52 --- /dev/null +++ b/Zend/tests/enum/debugInfo/missing_magic.phpt @@ -0,0 +1,14 @@ +--TEST-- +When an enum does not have __debugInfo() it is printed nicely +--FILE-- + +--EXPECT-- +enum(Foo::Bar) diff --git a/Zend/tests/enum/debugInfo/param_validation.phpt b/Zend/tests/enum/debugInfo/param_validation.phpt new file mode 100644 index 000000000000..84c60730822e --- /dev/null +++ b/Zend/tests/enum/debugInfo/param_validation.phpt @@ -0,0 +1,18 @@ +--TEST-- +Enum with __debugInfo() magic method - param validation +--FILE-- + +--EXPECTF-- +Fatal error: Method Foo::__debugInfo() cannot take arguments in %s on line %d diff --git a/Zend/tests/enum/debugInfo/return_validation.phpt b/Zend/tests/enum/debugInfo/return_validation.phpt new file mode 100644 index 000000000000..5583dcadf409 --- /dev/null +++ b/Zend/tests/enum/debugInfo/return_validation.phpt @@ -0,0 +1,18 @@ +--TEST-- +Enum with __debugInfo() magic method - return validation +--FILE-- + +--EXPECTF-- +Fatal error: Foo::__debugInfo(): Return type must be ?array when declared in %s on line %d diff --git a/Zend/tests/enum/debugInfo/visibility_validation.phpt b/Zend/tests/enum/debugInfo/visibility_validation.phpt new file mode 100644 index 000000000000..97e2f2c7456b --- /dev/null +++ b/Zend/tests/enum/debugInfo/visibility_validation.phpt @@ -0,0 +1,20 @@ +--TEST-- +Enum with __debugInfo() magic method - visibility validation +--FILE-- + +--EXPECTF-- +Warning: The magic method Foo::__debugInfo() must have public visibility in %s on line %d +enum(Foo::Bar) (0) { +} diff --git a/Zend/tests/enum/gh21760.phpt b/Zend/tests/enum/gh21760.phpt new file mode 100644 index 000000000000..0835e3ca937d --- /dev/null +++ b/Zend/tests/enum/gh21760.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-21760 (Trait with class constant name conflict against enum case causes SEGV) +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use trait X, because X::Up conflicts with enum case Direction::Up in %s on line %d diff --git a/Zend/tests/enum/implements-internal.phpt b/Zend/tests/enum/implements-internal.phpt new file mode 100644 index 000000000000..518602af97e1 --- /dev/null +++ b/Zend/tests/enum/implements-internal.phpt @@ -0,0 +1,14 @@ +--TEST-- +Enum implements (internal enum) +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +bool(false) +bool(true) diff --git a/Zend/tests/enum/instanceof-backed-enum.phpt b/Zend/tests/enum/instanceof-backed-enum.phpt index 4716835d1169..7087cfec74b4 100644 --- a/Zend/tests/enum/instanceof-backed-enum.phpt +++ b/Zend/tests/enum/instanceof-backed-enum.phpt @@ -1,5 +1,7 @@ --TEST-- Auto implement BackedEnum interface +--EXTENSIONS-- +zend_test --FILE-- --EXPECT-- bool(false) bool(true) +bool(false) +bool(true) diff --git a/Zend/tests/enum/instanceof-unitenum.phpt b/Zend/tests/enum/instanceof-unitenum.phpt index 552379632539..89b04b504662 100644 --- a/Zend/tests/enum/instanceof-unitenum.phpt +++ b/Zend/tests/enum/instanceof-unitenum.phpt @@ -1,5 +1,7 @@ --TEST-- Auto implement UnitEnum interface +--EXTENSIONS-- +zend_test --FILE-- --EXPECT-- bool(true) bool(false) +bool(true) diff --git a/Zend/tests/enum/no-class-implements-backed-enum.phpt b/Zend/tests/enum/no-class-implements-backed-enum.phpt index f6f37818da5a..f8d4fd13a423 100644 --- a/Zend/tests/enum/no-class-implements-backed-enum.phpt +++ b/Zend/tests/enum/no-class-implements-backed-enum.phpt @@ -7,4 +7,4 @@ class Foo implements BackedEnum {} ?> --EXPECTF-- -Fatal error: Non-enum class Foo cannot implement interface BackedEnum in %s on line %d +Fatal error: Non-enum class Foo cannot implement interface UnitEnum in %s on line %d diff --git a/Zend/tests/enum/no-clone-internal.phpt b/Zend/tests/enum/no-clone-internal.phpt new file mode 100644 index 000000000000..84b7ee2634d2 --- /dev/null +++ b/Zend/tests/enum/no-clone-internal.phpt @@ -0,0 +1,16 @@ +--TEST-- +Enum disallows cloning (internal enum) +--EXTENSIONS-- +zend_test +--FILE-- +getMessage() . "\n"; +} + +?> +--EXPECT-- +Trying to clone an uncloneable object of class ZendTestIntEnum diff --git a/Zend/tests/enum/no-dynamic-properties-internal.phpt b/Zend/tests/enum/no-dynamic-properties-internal.phpt new file mode 100644 index 000000000000..8d821a5f6292 --- /dev/null +++ b/Zend/tests/enum/no-dynamic-properties-internal.phpt @@ -0,0 +1,18 @@ +--TEST-- +Enum case disallows dynamic properties (internal enum) +--EXTENSIONS-- +zend_test +--FILE-- +baz = 'Baz'; +} catch (\Error $e) { + echo $e->getMessage(); +} + +?> +--EXPECT-- +Cannot create dynamic property ZendTestUnitEnum::$baz diff --git a/Zend/tests/enum/spl-object-storage.phpt b/Zend/tests/enum/spl-object-storage.phpt index 7c72299c348e..10da018b8426 100644 --- a/Zend/tests/enum/spl-object-storage.phpt +++ b/Zend/tests/enum/spl-object-storage.phpt @@ -16,8 +16,8 @@ $storage[Foo::Baz] = 'Baz'; var_dump($storage[Foo::Bar]); var_dump($storage[Foo::Baz]); -var_dump($storage->contains(Foo::Bar)); -var_dump($storage->contains(Foo::Qux)); +var_dump($storage->offsetExists(Foo::Bar)); +var_dump($storage->offsetExists(Foo::Qux)); $serialized = serialize($storage); var_dump($serialized); diff --git a/Zend/tests/errmsg/errmsg_021.phpt b/Zend/tests/errmsg/errmsg_021.phpt deleted file mode 100644 index 7514e6835904..000000000000 --- a/Zend/tests/errmsg/errmsg_021.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -errmsg: disabled class ---INI-- -disable_classes=stdclass ---FILE-- - ---EXPECTF-- -Warning: test() has been disabled for security reasons in %s on line %d -Done diff --git a/Zend/tests/exceptions/bug26698.phpt b/Zend/tests/exceptions/bug26698.phpt index 834e0b77c24f..8155f2090595 100644 --- a/Zend/tests/exceptions/bug26698.phpt +++ b/Zend/tests/exceptions/bug26698.phpt @@ -3,8 +3,6 @@ Bug #26698 (Thrown exceptions while evaluating argument to pass as parameter cra --FILE-- ---EXPECT-- +--EXPECTF-- string(4) "exit" string(3) "die" -object(Closure)#1 (2) { +object(Closure)#%d (2) { ["function"]=> string(4) "exit" ["parameter"]=> @@ -31,7 +31,7 @@ object(Closure)#1 (2) { string(10) "" } } -object(Closure)#2 (2) { +object(Closure)#%d (2) { ["function"]=> string(4) "exit" ["parameter"]=> diff --git a/Zend/tests/exit/exit_statements.phpt b/Zend/tests/exit/exit_statements.phpt index 6b3147156709..c64b6bedda94 100644 --- a/Zend/tests/exit/exit_statements.phpt +++ b/Zend/tests/exit/exit_statements.phpt @@ -17,7 +17,9 @@ TEMPLATE; $php = getenv('TEST_PHP_EXECUTABLE_ESCAPED'); -$command = $php . ' ' . escapeshellarg(FILE_PATH); +// Use -n so the spawned PHP doesn't inherit host php.ini extension +// configuration (otherwise missing extension warnings can pollute output). +$command = $php . ' -n ' . escapeshellarg(FILE_PATH); foreach (['exit', 'die'] as $value) { echo 'Using ', $value, ' as value:', PHP_EOL; diff --git a/Zend/tests/falsetoarray_003.phpt b/Zend/tests/falsetoarray_003.phpt index 11b32771e1fc..117e443ef958 100644 --- a/Zend/tests/falsetoarray_003.phpt +++ b/Zend/tests/falsetoarray_003.phpt @@ -11,6 +11,6 @@ $a=[]; ?> DONE --EXPECTF-- -Err: Implicit conversion from float %f to int loses precision +Err: The float %f is not representable as an int, cast occurred Err: Undefined array key %i DONE diff --git a/Zend/tests/fibers/gh19983.phpt b/Zend/tests/fibers/gh19983.phpt new file mode 100644 index 000000000000..554a7c8bf8ef --- /dev/null +++ b/Zend/tests/fibers/gh19983.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-19983 (GC Assertion Failure with fibers, generators and destructors) +--SKIPIF-- + +--INI-- +memory_limit=16M +--FILE-- +current(); + }); + $fiber->start(); + } +} +new a; +?> +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted%s diff --git a/Zend/tests/fibers/gh20483.phpt b/Zend/tests/fibers/gh20483.phpt new file mode 100644 index 000000000000..e06cf87258ea --- /dev/null +++ b/Zend/tests/fibers/gh20483.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-20483 (ASAN stack overflow with small fiber.stack_size INI value) +--INI-- +fiber.stack_size=1024 +--FILE-- +start(); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECTF-- +Fiber stack size is too small, it needs to be at least %d bytes diff --git a/Zend/tests/fibers/oss-fuzz-471533782-001.phpt b/Zend/tests/fibers/oss-fuzz-471533782-001.phpt new file mode 100644 index 000000000000..755f18449b00 --- /dev/null +++ b/Zend/tests/fibers/oss-fuzz-471533782-001.phpt @@ -0,0 +1,33 @@ +--TEST-- +OSS-Fuzz #471533782: Infinite loop in GC destructor fiber +--FILE-- +self = $this; + } + public function __destruct() { + try { + Fiber::suspend(); + } finally { + throw new Exception(); + } + } +} + +$f = new Fiber(function () { + new Cycle(); + gc_collect_cycles(); +}); +$f->start(); + +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 [internal function]: Cycle->__destruct() +#1 [internal function]: gc_destructor_fiber() +#2 {main} + thrown in %s on line %d diff --git a/Zend/tests/fibers/oss-fuzz-471533782-002.phpt b/Zend/tests/fibers/oss-fuzz-471533782-002.phpt new file mode 100644 index 000000000000..3dbac0aac75f --- /dev/null +++ b/Zend/tests/fibers/oss-fuzz-471533782-002.phpt @@ -0,0 +1,34 @@ +--TEST-- +OSS-Fuzz #471533782: Infinite loop in GC destructor fiber +--FILE-- +self = $this; + } + public function __destruct() { + try { + Fiber::suspend(); + } finally { + Fiber::suspend(); + } + } +} + +$f = new Fiber(function () { + new Cycle(); + gc_collect_cycles(); +}); +$f->start(); + +?> +--EXPECTF-- +Fatal error: Uncaught FiberError: Cannot suspend in a force-closed fiber in %s:%d +Stack trace: +#0 %s(%d): Fiber::suspend() +#1 [internal function]: Cycle->__destruct() +#2 [internal function]: gc_destructor_fiber() +#3 {main} + thrown in %s on line %d diff --git a/Zend/tests/first_class_callable/constexpr/autoload.phpt b/Zend/tests/first_class_callable/constexpr/autoload.phpt index 2dd2561f9a36..c962b77f12b6 100644 --- a/Zend/tests/first_class_callable/constexpr/autoload.phpt +++ b/Zend/tests/first_class_callable/constexpr/autoload.phpt @@ -26,6 +26,6 @@ var_dump(Closure); Autoloading AutoloadedClass object(Closure)#%d (1) { ["function"]=> - string(16) "withStaticMethod" + string(33) "AutoloadedClass::withStaticMethod" } Called AutoloadedClass::withStaticMethod diff --git a/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_001.phpt b/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_001.phpt index efffa4a1d366..54c96c915635 100644 --- a/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_001.phpt +++ b/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_001.phpt @@ -1,5 +1,5 @@ --TEST-- -FCC in initializer errors for static reference to instance method. +FCC in initializer warns for static reference to trait method. --FILE-- - string(8) "myMethod" + string(13) "Foo::myMethod" ["parameter"]=> array(1) { ["$foo"]=> diff --git a/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_002.phpt b/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_002.phpt index d36f7c97651e..97831a8d65f0 100644 --- a/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_002.phpt +++ b/Zend/tests/first_class_callable/constexpr/error_static_call_trait_method_002.phpt @@ -1,5 +1,5 @@ --TEST-- -FCC in initializer errors for static reference to instance method (Exception). +FCC in initializer emits deprecation for static reference to trait method (Exception). --FILE-- getClosureCalledClass()); + var_dump($r->getClosureScopeClass()); + } + } +} + +foreach ((new ReflectionClass(C::class))->getAttributes() as $reflectionAttribute) { + foreach ($reflectionAttribute->newInstance()->value as $fn) { + $r = new \ReflectionFunction($fn); + var_dump($r->getClosureCalledClass()); + var_dump($r->getClosureScopeClass()); + } +} +echo "=======\n"; +C::foo(); + +?> +--EXPECTF-- +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "F" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "F" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "G" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "F" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "C" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "C" +} +NULL +NULL +======= +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "F" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "F" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "G" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "F" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "C" +} +object(ReflectionClass)#%d (1) { + ["name"]=> + string(1) "C" +} +NULL +NULL diff --git a/Zend/tests/first_class_callable/constexpr/namespace_004.phpt b/Zend/tests/first_class_callable/constexpr/namespace_004.phpt index 0fc23422199d..6fe99593bf95 100644 --- a/Zend/tests/first_class_callable/constexpr/namespace_004.phpt +++ b/Zend/tests/first_class_callable/constexpr/namespace_004.phpt @@ -26,7 +26,7 @@ foo(); ?> --EXPECTF-- -object(Closure)#1 (2) { +object(Closure)#%d (2) { ["function"]=> string(6) "strrev" ["parameter"]=> @@ -36,7 +36,7 @@ object(Closure)#1 (2) { } } string(3) "cba" -object(Closure)#2 (2) { +object(Closure)#%d (2) { ["function"]=> string(6) "strrev" ["parameter"]=> @@ -46,7 +46,7 @@ object(Closure)#2 (2) { } } string(3) "cba" -object(Closure)#2 (2) { +object(Closure)#%d (2) { ["function"]=> string(6) "strrev" ["parameter"]=> @@ -56,7 +56,7 @@ object(Closure)#2 (2) { } } string(3) "cba" -object(Closure)#1 (2) { +object(Closure)#%d (2) { ["function"]=> string(6) "strrev" ["parameter"]=> diff --git a/Zend/tests/first_class_callable/constexpr/property_initializer_scope_003.phpt b/Zend/tests/first_class_callable/constexpr/property_initializer_scope_003.phpt index 3959efbd16a0..1776cd8f319d 100644 --- a/Zend/tests/first_class_callable/constexpr/property_initializer_scope_003.phpt +++ b/Zend/tests/first_class_callable/constexpr/property_initializer_scope_003.phpt @@ -23,7 +23,7 @@ var_dump(($c->d)("abc")); --EXPECTF-- object(Closure)#%d (2) { ["function"]=> - string(11) "C::myMethod" + string(11) "P::myMethod" ["parameter"]=> array(1) { ["$foo"]=> diff --git a/Zend/tests/first_class_callable/constexpr/static_call.phpt b/Zend/tests/first_class_callable/constexpr/static_call.phpt index 26761a041a4c..2c6d3aa92b52 100644 --- a/Zend/tests/first_class_callable/constexpr/static_call.phpt +++ b/Zend/tests/first_class_callable/constexpr/static_call.phpt @@ -19,7 +19,7 @@ var_dump(Closure); --EXPECTF-- object(Closure)#%d (2) { ["function"]=> - string(8) "myMethod" + string(13) "Foo::myMethod" ["parameter"]=> array(1) { ["$foo"]=> diff --git a/Zend/tests/first_class_callable/first_class_callable_non_unary_error.phpt b/Zend/tests/first_class_callable/first_class_callable_non_unary_error.phpt new file mode 100644 index 000000000000..74e36a9ad0df --- /dev/null +++ b/Zend/tests/first_class_callable/first_class_callable_non_unary_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +First class callable error: more than one argument +--FILE-- + +--EXPECTF-- +Fatal error: Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders in %s on line %d diff --git a/Zend/tests/first_class_callable/first_class_callable_non_variadic_error.phpt b/Zend/tests/first_class_callable/first_class_callable_non_variadic_error.phpt new file mode 100644 index 000000000000..efbd13b7593b --- /dev/null +++ b/Zend/tests/first_class_callable/first_class_callable_non_variadic_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +First class callable error: non-variadic placeholder +--FILE-- + +--EXPECTF-- +Fatal error: Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders in %s on line %d diff --git a/Zend/tests/first_class_callable/first_class_callable_optimization.phpt b/Zend/tests/first_class_callable/first_class_callable_optimization.phpt index 707b6a7299a4..169f6dfd62cc 100644 --- a/Zend/tests/first_class_callable/first_class_callable_optimization.phpt +++ b/Zend/tests/first_class_callable/first_class_callable_optimization.phpt @@ -10,12 +10,12 @@ var_dump(test1(...)); var_dump(test2(...)); ?> ---EXPECT-- -object(Closure)#1 (1) { +--EXPECTF-- +object(Closure)#%d (1) { ["function"]=> string(5) "test1" } -object(Closure)#1 (1) { +object(Closure)#%d (1) { ["function"]=> string(5) "test2" } diff --git a/Zend/tests/float_to_int/explicit_casts_should_not_warn.phpt b/Zend/tests/float_to_int/explicit_casts_should_not_warn.phpt deleted file mode 100644 index 71c68e57574b..000000000000 --- a/Zend/tests/float_to_int/explicit_casts_should_not_warn.phpt +++ /dev/null @@ -1,38 +0,0 @@ ---TEST-- -Explicit (int) cast must not warn ---SKIPIF-- - ---FILE-- - ---EXPECT-- -int(3) -int(3) -int(0) -int(0) -int(0) -int(3) -int(3) -int(9223372036854775807) -int(9223372036854775807) -int(0) diff --git a/Zend/tests/float_to_int/explicit_casts_should_not_warn_32bit.phpt b/Zend/tests/float_to_int/explicit_casts_should_not_warn_32bit.phpt deleted file mode 100644 index fee011df06ea..000000000000 --- a/Zend/tests/float_to_int/explicit_casts_should_not_warn_32bit.phpt +++ /dev/null @@ -1,38 +0,0 @@ ---TEST-- -Explicit (int) cast must not warn 32bit variation ---SKIPIF-- - ---FILE-- - ---EXPECT-- -int(3) -int(3) -int(0) -int(0) -int(0) -int(3) -int(3) -int(2147483647) -int(2147483647) -int(0) diff --git a/Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_arrays.phpt b/Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_arrays.phpt deleted file mode 100644 index bb27d1bb49dd..000000000000 --- a/Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_arrays.phpt +++ /dev/null @@ -1,55 +0,0 @@ ---TEST-- -Implicit float to int conversions when float too large should warn, array variant ---FILE-- - 'Large float', (string) 10e120 => 'String large float']; -$arrayDynamic = [$float => 'Large float', $string_float => 'String large float']; - -var_dump($arrayConstant); -var_dump($arrayDynamic); - -$array = ['0', '1', '2']; -var_dump($array[10e120]); -var_dump($array[(string) 10e120]); -var_dump($array[$float]); -var_dump($array[$string_float]); - -?> ---EXPECTF-- -int(0) -bool(true) - -Deprecated: Implicit conversion from float 1.0E+121 to int loses precision in %s on line %d - -Deprecated: Implicit conversion from float 1.0E+121 to int loses precision in %s on line %d -array(2) { - [0]=> - string(11) "Large float" - ["1.0E+121"]=> - string(18) "String large float" -} -array(2) { - [0]=> - string(11) "Large float" - ["1.0E+121"]=> - string(18) "String large float" -} - -Deprecated: Implicit conversion from float 1.0E+121 to int loses precision in %s on line %d -string(1) "0" - -Warning: Undefined array key "1.0E+121" in %s on line %d -NULL - -Deprecated: Implicit conversion from float 1.0E+121 to int loses precision in %s on line %d -string(1) "0" - -Warning: Undefined array key "1.0E+121" in %s on line %d -NULL diff --git a/Zend/tests/foreach/foreach_list_002.phpt b/Zend/tests/foreach/foreach_list_002.phpt index 1c693651fdc4..62231f847148 100644 --- a/Zend/tests/foreach/foreach_list_002.phpt +++ b/Zend/tests/foreach/foreach_list_002.phpt @@ -7,16 +7,48 @@ foreach (array(array(1,2), array(3,4)) as list($a, )) { var_dump($a); } +echo "Array of strings:\n"; $array = [['a', 'b'], 'c', 'd']; foreach($array as list(, $a)) { var_dump($a); } +echo "Array of ints:\n"; +$array = [[5, 6], 10, 20]; + +foreach($array as list(, $a)) { + var_dump($a); +} + +echo "Array of nulls:\n"; +$array = [[null, null], null, null]; + +foreach($array as list(, $a)) { + var_dump($a); +} + ?> ---EXPECT-- +--EXPECTF-- int(1) int(3) +Array of strings: string(1) "b" + +Warning: Cannot use string as array in %s on line %d +NULL + +Warning: Cannot use string as array in %s on line %d +NULL +Array of ints: +int(6) + +Warning: Cannot use int as array in %s on line %d +NULL + +Warning: Cannot use int as array in %s on line %d +NULL +Array of nulls: +NULL NULL NULL diff --git a/Zend/tests/func_get_arg_basic.phpt b/Zend/tests/func_get_arg_basic.phpt new file mode 100644 index 000000000000..ec06a5c20f4d --- /dev/null +++ b/Zend/tests/func_get_arg_basic.phpt @@ -0,0 +1,121 @@ +--TEST-- +func_get_arg() tests +--FILE-- +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 %s 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 diff --git a/Zend/tests/020.phpt b/Zend/tests/func_get_arg_invalid.phpt similarity index 100% rename from Zend/tests/020.phpt rename to Zend/tests/func_get_arg_invalid.phpt diff --git a/Zend/tests/func_get_args_basic.phpt b/Zend/tests/func_get_args_basic.phpt new file mode 100644 index 000000000000..54ddf1b40c92 --- /dev/null +++ b/Zend/tests/func_get_args_basic.phpt @@ -0,0 +1,82 @@ +--TEST-- +func_get_args() tests +--FILE-- +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 %s 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 %s 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 diff --git a/Zend/tests/001.phpt b/Zend/tests/func_num_args_basic.phpt similarity index 100% rename from Zend/tests/001.phpt rename to Zend/tests/func_num_args_basic.phpt diff --git a/Zend/tests/function_arguments/gh20435.phpt b/Zend/tests/function_arguments/gh20435.phpt new file mode 100644 index 000000000000..e360b873d3ce --- /dev/null +++ b/Zend/tests/function_arguments/gh20435.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-20435 (SensitiveParameter doesn't work for named argument passing to variadic parameter) +--FILE-- + +--EXPECTF-- +#0 %s(%d): test(2, b: Object(SensitiveParameterValue), c: Object(SensitiveParameterValue)) diff --git a/Zend/tests/function_arguments/gh20435_2.phpt b/Zend/tests/function_arguments/gh20435_2.phpt new file mode 100644 index 000000000000..a58c4d6be1ca --- /dev/null +++ b/Zend/tests/function_arguments/gh20435_2.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-20435: ZEND_CALL_HAS_EXTRA_NAMED_PARAMS & magic methods in debug_backtrace_get_args() +--FILE-- +__toString(), "\n\n"; + } + public function __call($name, $args) { + echo (new Exception())->__toString(), "\n\n"; + } + public function __invoke(...$args) { + echo (new Exception())->__toString(), "\n"; + } +} + +$c = new C(); +$c->foo(bar: 'bar'); +C::foo(bar: 'bar'); +$c(bar: 'bar'); + +?> +--EXPECTF-- +Exception in %s:%d +Stack trace: +#0 %s(%d): C->__call('foo', Array) +#1 {main} + +Exception in %s:%d +Stack trace: +#0 %s(%d): C::__callStatic('foo', Array) +#1 {main} + +Exception in %s:%d +Stack trace: +#0 %s(%d): C->__invoke(bar: 'bar') +#1 {main} diff --git a/Zend/tests/028.phpt b/Zend/tests/function_call_array_item.phpt similarity index 100% rename from Zend/tests/028.phpt rename to Zend/tests/function_call_array_item.phpt diff --git a/Zend/tests/functions/zend_call_function_deprecated_frame.phpt b/Zend/tests/functions/zend_call_function_deprecated_frame.phpt new file mode 100644 index 000000000000..83d05144c0bd --- /dev/null +++ b/Zend/tests/functions/zend_call_function_deprecated_frame.phpt @@ -0,0 +1,24 @@ +--TEST-- +Deprecated function notice promoted to exception within zend_call_function() +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception: Function foo() is deprecated in %s:%d +Stack trace: +#0 %s(%d): {closure:%s:%d}(16384, 'Function foo() ...', '%s', %d) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gc/bug67314.phpt b/Zend/tests/gc/bug67314.phpt index 8077b01881b0..33dc01e90c0a 100644 --- a/Zend/tests/gc/bug67314.phpt +++ b/Zend/tests/gc/bug67314.phpt @@ -17,7 +17,11 @@ echo "ok\n"; ?> --EXPECTF-- Warning: Undefined variable $i in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d made it once Warning: Undefined variable $i in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d ok diff --git a/Zend/tests/gc/bug78010.phpt b/Zend/tests/gc/bug78010.phpt index 6b266b77b667..35f2a1d49dab 100644 --- a/Zend/tests/gc/bug78010.phpt +++ b/Zend/tests/gc/bug78010.phpt @@ -2,6 +2,7 @@ Bug #78010: Segmentation fault during GC --SKIPIF-- --INI-- diff --git a/Zend/tests/gc/gc_046.phpt b/Zend/tests/gc/gc_046.phpt index d5024737365b..8d4843853521 100644 --- a/Zend/tests/gc/gc_046.phpt +++ b/Zend/tests/gc/gc_046.phpt @@ -20,5 +20,6 @@ $action->filter(); $action->filter(); ?> DONE ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d DONE diff --git a/Zend/tests/gc/gc_050.phpt b/Zend/tests/gc/gc_050.phpt index 858be7cbebd5..0bedc7220fd4 100644 --- a/Zend/tests/gc/gc_050.phpt +++ b/Zend/tests/gc/gc_050.phpt @@ -1,37 +1,40 @@ --TEST-- -GC 050: Destructor are never called twice +GC 050: Try/finally in foreach should create separate live ranges --FILE-- v = 1; + } + return new stdClass; } -class WithDestructor -{ - public function __destruct() - { - echo "d\n"; +for ($i = 0; $i < 100000; $i++) { + // Create cyclic garbage to trigger GC + $a = new stdClass; + $b = new stdClass; + $a->r = $b; + $b->r = $a; - G::$v = $this; - } + $r = f($i % 2 + 1); } - -$o = new WithDestructor(); -$weakO = \WeakReference::create($o); -echo "---\n"; -unset($o); -echo "---\n"; -var_dump($weakO->get() !== null); // verify if kept allocated -G::$v = null; -echo "---\n"; -var_dump($weakO->get() !== null); // verify if released +echo "OK\n"; ?> --EXPECT-- ---- -d ---- -bool(true) ---- -bool(false) +OK diff --git a/Zend/tests/gc_051.phpt b/Zend/tests/gc_051.phpt new file mode 100644 index 000000000000..575a25a108a1 --- /dev/null +++ b/Zend/tests/gc_051.phpt @@ -0,0 +1,29 @@ +--TEST-- +GC 048: FE_FREE should mark variable as UNDEF to prevent use-after-free during GC +--FILE-- +ref = $b; + $b->ref = $a; + + $result = test_foreach_early_return("x"); +} + +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/gc_052.phpt b/Zend/tests/gc_052.phpt new file mode 100644 index 000000000000..dd15c56bcbf5 --- /dev/null +++ b/Zend/tests/gc_052.phpt @@ -0,0 +1,36 @@ +--TEST-- +GC 049: Multiple early returns from foreach should create separate live ranges +--FILE-- +r = $b; + $b->r = $a; + + $r = f($i % 3 + 1); +} +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/gc_053.phpt b/Zend/tests/gc_053.phpt new file mode 100644 index 000000000000..858be7cbebd5 --- /dev/null +++ b/Zend/tests/gc_053.phpt @@ -0,0 +1,37 @@ +--TEST-- +GC 050: Destructor are never called twice +--FILE-- +get() !== null); // verify if kept allocated +G::$v = null; +echo "---\n"; +var_dump($weakO->get() !== null); // verify if released +?> +--EXPECT-- +--- +d +--- +bool(true) +--- +bool(false) diff --git a/Zend/tests/generics/declaration/default_satisfies_bound.phpt b/Zend/tests/generics/declaration/default_satisfies_bound.phpt new file mode 100644 index 000000000000..6aebf72326c5 --- /dev/null +++ b/Zend/tests/generics/declaration/default_satisfies_bound.phpt @@ -0,0 +1,18 @@ +--TEST-- +Declaration: type-parameter default that satisfies its bound is accepted +--FILE-- + {} +function f(): void {} +trait Tr {} +interface I {} + +new Box; +f(); +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/declaration/default_violates_bound_class.phpt b/Zend/tests/generics/declaration/default_violates_bound_class.phpt new file mode 100644 index 000000000000..17c79f43bd7d --- /dev/null +++ b/Zend/tests/generics/declaration/default_violates_bound_class.phpt @@ -0,0 +1,9 @@ +--TEST-- +Declaration: class type-parameter default that does not satisfy its bound is rejected +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Default int for type parameter T does not satisfy its bound Animal in %s on line %d diff --git a/Zend/tests/generics/declaration/default_violates_bound_function.phpt b/Zend/tests/generics/declaration/default_violates_bound_function.phpt new file mode 100644 index 000000000000..ad83c63395ec --- /dev/null +++ b/Zend/tests/generics/declaration/default_violates_bound_function.phpt @@ -0,0 +1,9 @@ +--TEST-- +Declaration: function type-parameter default that does not satisfy its bound is rejected +--FILE-- +(): void {} +?> +--EXPECTF-- +Fatal error: Default int for type parameter T does not satisfy its bound Animal in %s on line %d diff --git a/Zend/tests/generics/declaration/default_violates_bound_interface.phpt b/Zend/tests/generics/declaration/default_violates_bound_interface.phpt new file mode 100644 index 000000000000..0339c260e029 --- /dev/null +++ b/Zend/tests/generics/declaration/default_violates_bound_interface.phpt @@ -0,0 +1,9 @@ +--TEST-- +Declaration: interface type-parameter default that does not satisfy its bound is rejected +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Default int for type parameter T does not satisfy its bound Animal in %s on line %d diff --git a/Zend/tests/generics/declaration/default_violates_bound_trait.phpt b/Zend/tests/generics/declaration/default_violates_bound_trait.phpt new file mode 100644 index 000000000000..656fa275618d --- /dev/null +++ b/Zend/tests/generics/declaration/default_violates_bound_trait.phpt @@ -0,0 +1,9 @@ +--TEST-- +Declaration: trait type-parameter default that does not satisfy its bound is rejected +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Default int for type parameter T does not satisfy its bound Animal in %s on line %d diff --git a/Zend/tests/generics/declaration/default_with_intersection_bound.phpt b/Zend/tests/generics/declaration/default_with_intersection_bound.phpt new file mode 100644 index 000000000000..a493c0003646 --- /dev/null +++ b/Zend/tests/generics/declaration/default_with_intersection_bound.phpt @@ -0,0 +1,8 @@ +--TEST-- +Declaration: default checked against intersection bound when types are concrete +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Default int for type parameter T does not satisfy its bound Traversable&Countable in %s on line %d diff --git a/Zend/tests/generics/declaration/default_with_union_bound.phpt b/Zend/tests/generics/declaration/default_with_union_bound.phpt new file mode 100644 index 000000000000..5477170bca2d --- /dev/null +++ b/Zend/tests/generics/declaration/default_with_union_bound.phpt @@ -0,0 +1,8 @@ +--TEST-- +Declaration: default checked against union bound when types are concrete +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Default float for type parameter T does not satisfy its bound string|int in %s on line %d diff --git a/Zend/tests/generics/declaration/error_renders_default_args.phpt b/Zend/tests/generics/declaration/error_renders_default_args.phpt new file mode 100644 index 000000000000..e92783bbcfc3 --- /dev/null +++ b/Zend/tests/generics/declaration/error_renders_default_args.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bound error message: declaration-time default-vs-bound error renders NAMED_WITH_ARGS in the bound +--FILE-- + {} +class Box = int> {} +?> +--EXPECTF-- +Fatal error: Default int for type parameter T does not satisfy its bound Comparable in %s on line %d diff --git a/Zend/tests/generics/declaration/no_leak_dnf_bound.phpt b/Zend/tests/generics/declaration/no_leak_dnf_bound.phpt new file mode 100644 index 000000000000..14c7181fa8ce --- /dev/null +++ b/Zend/tests/generics/declaration/no_leak_dnf_bound.phpt @@ -0,0 +1,17 @@ +--TEST-- +Generics: declaring a class with a DNF-typed bound does not leak memory +--FILE-- + { + public function take(T $x): void {} + public function get(): T {} +} + +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/no_leak_intersection_bound.phpt b/Zend/tests/generics/declaration/no_leak_intersection_bound.phpt new file mode 100644 index 000000000000..19c8197a8612 --- /dev/null +++ b/Zend/tests/generics/declaration/no_leak_intersection_bound.phpt @@ -0,0 +1,15 @@ +--TEST-- +Generics: declaring a class with an intersection-typed bound does not leak memory +--FILE-- + { + public function take(T $x): void {} +} + +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/no_leak_union_bound.phpt b/Zend/tests/generics/declaration/no_leak_union_bound.phpt new file mode 100644 index 000000000000..de18838ff1eb --- /dev/null +++ b/Zend/tests/generics/declaration/no_leak_union_bound.phpt @@ -0,0 +1,15 @@ +--TEST-- +Generics: declaring a class with a union-typed bound does not leak memory +--FILE-- + { + public function take(T $x): void {} +} + +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/chain_forward.phpt b/Zend/tests/generics/declaration/recursive_bounds/chain_forward.phpt new file mode 100644 index 000000000000..9a5625588b06 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/chain_forward.phpt @@ -0,0 +1,11 @@ +--TEST-- +Recursive bounds: chain of forward references through three parameters +--FILE-- + {} +class Foo {} +function f, U: Box, V: Foo>(T $a, U $b, V $c): void {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/default_backward_ref_allowed.phpt b/Zend/tests/generics/declaration/recursive_bounds/default_backward_ref_allowed.phpt new file mode 100644 index 000000000000..239f16563044 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/default_backward_ref_allowed.phpt @@ -0,0 +1,11 @@ +--TEST-- +Recursive bounds: backward reference in a default is allowed +--FILE-- + {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/default_forward_ref_rejected.phpt b/Zend/tests/generics/declaration/recursive_bounds/default_forward_ref_rejected.phpt new file mode 100644 index 000000000000..206ae5157b64 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/default_forward_ref_rejected.phpt @@ -0,0 +1,9 @@ +--TEST-- +Recursive bounds: forward reference in a default is rejected +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Type parameter U referenced before declaration in %s on line %d diff --git a/Zend/tests/generics/declaration/recursive_bounds/direct_self_ref_still_rejected.phpt b/Zend/tests/generics/declaration/recursive_bounds/direct_self_ref_still_rejected.phpt new file mode 100644 index 000000000000..f6d669013f1a --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/direct_self_ref_still_rejected.phpt @@ -0,0 +1,8 @@ +--TEST-- +Recursive bounds: direct self-reference in a bound (not inside a type argument) is still rejected +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Type parameter T cannot reference itself in its own bound or default outside of a generic type argument in %s on line %d diff --git a/Zend/tests/generics/declaration/recursive_bounds/extends_with_mutual_bounds.phpt b/Zend/tests/generics/declaration/recursive_bounds/extends_with_mutual_bounds.phpt new file mode 100644 index 000000000000..f3b2c515d3f6 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/extends_with_mutual_bounds.phpt @@ -0,0 +1,17 @@ +--TEST-- +Recursive bounds: a child class can extend a parent that uses mutual bounds +--FILE-- + {} +class Pair, U: Box> { + public function __construct(public Box $left, public Box $right) {} +} + +class StrictPair, B: Box> extends Pair {} + +$p = new StrictPair::, Box>(new Box(), new Box()); +var_dump($p instanceof Pair, $p instanceof StrictPair); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/Zend/tests/generics/declaration/recursive_bounds/forward_bound_with_class_bound.phpt b/Zend/tests/generics/declaration/recursive_bounds/forward_bound_with_class_bound.phpt new file mode 100644 index 000000000000..51d7330fb619 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/forward_bound_with_class_bound.phpt @@ -0,0 +1,18 @@ +--TEST-- +Recursive bounds: forward reference where the target has a non-generic class bound +--FILE-- +(T $x): U { return $x; } +var_dump(f(new Foo())); +try { + f(new Bar()); +} catch (TypeError $e) { + echo "type error\n"; +} +?> +--EXPECTF-- +object(Foo)#%d (0) { +} +type error diff --git a/Zend/tests/generics/declaration/recursive_bounds/forward_in_generic_arg.phpt b/Zend/tests/generics/declaration/recursive_bounds/forward_in_generic_arg.phpt new file mode 100644 index 000000000000..86f7feb081f0 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/forward_in_generic_arg.phpt @@ -0,0 +1,10 @@ +--TEST-- +Recursive bounds: forward reference nested inside generic type argument +--FILE-- + {} +function g, T>(U $x): void {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/forward_simple.phpt b/Zend/tests/generics/declaration/recursive_bounds/forward_simple.phpt new file mode 100644 index 000000000000..7438e337627b --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/forward_simple.phpt @@ -0,0 +1,11 @@ +--TEST-- +Recursive bounds: simple forward reference in bound +--FILE-- +(U $x): T { return $x; } +var_dump(f(new Foo())); +?> +--EXPECTF-- +object(Foo)#%d (0) { +} diff --git a/Zend/tests/generics/declaration/recursive_bounds/four_way_cycle.phpt b/Zend/tests/generics/declaration/recursive_bounds/four_way_cycle.phpt new file mode 100644 index 000000000000..af67dbf89f66 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/four_way_cycle.phpt @@ -0,0 +1,10 @@ +--TEST-- +Recursive bounds: four-parameter cycle A -> B -> C -> D -> A +--FILE-- + {} +class Quad, B: Box, C: Box, D: Box> {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/hammer_combined.phpt b/Zend/tests/generics/declaration/recursive_bounds/hammer_combined.phpt new file mode 100644 index 000000000000..4dcbd2c34460 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/hammer_combined.phpt @@ -0,0 +1,34 @@ +--TEST-- +Recursive bounds: combined exercise — class, interface, generic methods, multi-cycle +--FILE-- + {} +class IntBox implements Box {} +class StrBox implements Box {} + +interface Pair, U: Box> { + public function left(): Box; + public function right(): Box; +} + +class IntStrPair implements Pair { + public function __construct(private Box $l, private Box $r) {} + public function left(): Box { return $this->l; } + public function right(): Box { return $this->r; } +} + +class Container { + public function swap, B: Box>(Pair $p): array { + return [$p->right(), $p->left()]; + } +} + +$p = new IntStrPair(new IntBox(), new StrBox()); +$c = new Container::(); +[$first, $second] = $c->swap($p); + +var_dump($first instanceof StrBox, $second instanceof IntBox); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/Zend/tests/generics/declaration/recursive_bounds/interface_with_mutual_bounds.phpt b/Zend/tests/generics/declaration/recursive_bounds/interface_with_mutual_bounds.phpt new file mode 100644 index 000000000000..9d767f9f7c73 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/interface_with_mutual_bounds.phpt @@ -0,0 +1,25 @@ +--TEST-- +Recursive bounds: an interface can declare mutual bounds +--FILE-- + {} +interface PairLike, U: Box> { + public function left(): Box; + public function right(): Box; +} + +class IntBox implements Box {} +class StrBox implements Box {} + +class Pair implements PairLike { + public function __construct(private Box $l, private Box $r) {} + public function left(): Box { return $this->l; } + public function right(): Box { return $this->r; } +} + +$p = new Pair(new IntBox(), new StrBox()); +var_dump($p->left() instanceof IntBox, $p->right() instanceof StrBox); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/Zend/tests/generics/declaration/recursive_bounds/mutual_class.phpt b/Zend/tests/generics/declaration/recursive_bounds/mutual_class.phpt new file mode 100644 index 000000000000..631c51afc2e5 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/mutual_class.phpt @@ -0,0 +1,10 @@ +--TEST-- +Recursive bounds: class with mutually recursive type parameters +--FILE-- + {} +class Pair, U: Box> {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/mutual_function.phpt b/Zend/tests/generics/declaration/recursive_bounds/mutual_function.phpt new file mode 100644 index 000000000000..28377df49805 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/mutual_function.phpt @@ -0,0 +1,10 @@ +--TEST-- +Recursive bounds: function with mutually recursive type parameters +--FILE-- + {} +function f, U: Box>(T $x, U $y): void {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/mutual_intersection_bound.phpt b/Zend/tests/generics/declaration/recursive_bounds/mutual_intersection_bound.phpt new file mode 100644 index 000000000000..6d6c3dea0a3c --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/mutual_intersection_bound.phpt @@ -0,0 +1,11 @@ +--TEST-- +Recursive bounds: mutual references inside intersection bounds +--FILE-- + {} +interface Tagged {} +class Pair&Tagged, U: Box&Tagged> {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/mutual_method.phpt b/Zend/tests/generics/declaration/recursive_bounds/mutual_method.phpt new file mode 100644 index 000000000000..cbe70255fc6e --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/mutual_method.phpt @@ -0,0 +1,12 @@ +--TEST-- +Recursive bounds: method with mutually recursive type parameters +--FILE-- + {} +class C { + public function f, U: Box>(T $x, U $y): void {} +} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/mutual_union_bound.phpt b/Zend/tests/generics/declaration/recursive_bounds/mutual_union_bound.phpt new file mode 100644 index 000000000000..ae95eb6e79c9 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/mutual_union_bound.phpt @@ -0,0 +1,10 @@ +--TEST-- +Recursive bounds: mutual references inside union bounds +--FILE-- + {} +class Pair|null, U: Box|null> {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/nested_mutual_in_outer.phpt b/Zend/tests/generics/declaration/recursive_bounds/nested_mutual_in_outer.phpt new file mode 100644 index 000000000000..d084c1274ad9 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/nested_mutual_in_outer.phpt @@ -0,0 +1,12 @@ +--TEST-- +Recursive bounds: outer-scope class param appears inside mutually recursive method bounds +--FILE-- + {} +class Carrier> { + public function pair, U: Box>(T $a, U $b, O $c): void {} +} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/outer_scope_param_in_recursive_bound.phpt b/Zend/tests/generics/declaration/recursive_bounds/outer_scope_param_in_recursive_bound.phpt new file mode 100644 index 000000000000..6638805dc595 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/outer_scope_param_in_recursive_bound.phpt @@ -0,0 +1,12 @@ +--TEST-- +Recursive bounds: an enclosing class's type parameter can appear inside a recursive method bound +--FILE-- + {} +class C { + public function f, U: Box>(T $a, U $b, O $c): void {} +} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/redeclare_still_rejected.phpt b/Zend/tests/generics/declaration/recursive_bounds/redeclare_still_rejected.phpt new file mode 100644 index 000000000000..1d3b690a63ff --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/redeclare_still_rejected.phpt @@ -0,0 +1,8 @@ +--TEST-- +Recursive bounds: duplicate parameter names are still rejected +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Cannot redeclare type parameter T in %s on line %d diff --git a/Zend/tests/generics/declaration/recursive_bounds/runtime_instantiation.phpt b/Zend/tests/generics/declaration/recursive_bounds/runtime_instantiation.phpt new file mode 100644 index 000000000000..53c310f5f629 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/runtime_instantiation.phpt @@ -0,0 +1,20 @@ +--TEST-- +Recursive bounds: a class with mutually recursive bounds can be instantiated and used +--FILE-- + { + public function __construct(public mixed $value) {} +} + +final class Pair, U: Box> { + public function __construct(public Box $left, public Box $right) {} +} + +$bx = new Box(1); +$by = new Box("hi"); +$p = new Pair::, Box>($bx, $by); +var_dump($p->left->value, $p->right->value); +?> +--EXPECT-- +int(1) +string(2) "hi" diff --git a/Zend/tests/generics/declaration/recursive_bounds/self_ref_through_generic_arg_allowed.phpt b/Zend/tests/generics/declaration/recursive_bounds/self_ref_through_generic_arg_allowed.phpt new file mode 100644 index 000000000000..ee81760af212 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/self_ref_through_generic_arg_allowed.phpt @@ -0,0 +1,17 @@ +--TEST-- +Recursive bounds: F-bounded polymorphism (T appears as a type argument inside its own bound) +--FILE-- +` — T isn't its own bound, it's a type +// *argument* to the bound. This is the pattern PHP supports for self-referential +// constraints (analogous to Java `>`). +class Box {} +class Foo> {} + +// A direct self-bound (`T: T`) would be rejected; verify the F-bounded form +// is in fact distinct by reflecting it. +$bound = (new ReflectionClass('Foo'))->getGenericParameters()[0]; +echo $bound, "\n"; +?> +--EXPECT-- +T : Box diff --git a/Zend/tests/generics/declaration/recursive_bounds/triple_cycle.phpt b/Zend/tests/generics/declaration/recursive_bounds/triple_cycle.phpt new file mode 100644 index 000000000000..fa89a02ab6b6 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/triple_cycle.phpt @@ -0,0 +1,10 @@ +--TEST-- +Recursive bounds: three-way cycle T -> U -> V -> T +--FILE-- + {} +class Cycle, U: Box, V: Box> {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/recursive_bounds/turbofish_satisfied.phpt b/Zend/tests/generics/declaration/recursive_bounds/turbofish_satisfied.phpt new file mode 100644 index 000000000000..22145614882e --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/turbofish_satisfied.phpt @@ -0,0 +1,12 @@ +--TEST-- +Recursive bounds: turbofish argument satisfying the head class is accepted +--FILE-- + {} +class Pair, U: Box> {} + +$p = new Pair::, Box>(); +var_dump($p instanceof Pair); +?> +--EXPECT-- +bool(true) diff --git a/Zend/tests/generics/declaration/recursive_bounds/turbofish_violation.phpt b/Zend/tests/generics/declaration/recursive_bounds/turbofish_violation.phpt new file mode 100644 index 000000000000..dd8c130d9792 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/turbofish_violation.phpt @@ -0,0 +1,15 @@ +--TEST-- +Recursive bounds: turbofish argument still must satisfy each parameter's bound +--FILE-- + {} +class Pair, U: Box> {} + +try { + $p = new Pair::(); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Type argument 1 to new Pair does not satisfy the bound Box on parameter T, int given diff --git a/Zend/tests/generics/declaration/recursive_bounds/with_variance_covariant_violation.phpt b/Zend/tests/generics/declaration/recursive_bounds/with_variance_covariant_violation.phpt new file mode 100644 index 000000000000..fc3189b3f784 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/with_variance_covariant_violation.phpt @@ -0,0 +1,9 @@ +--TEST-- +Recursive bounds: covariant marker in bound position is still rejected (bounds are invariant) +--FILE-- + {} +class Pair<+T: Box, +U: Box> {} +?> +--EXPECTF-- +Fatal error: Type parameter %s declared covariant (+%s) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/recursive_bounds/with_variance_invariant.phpt b/Zend/tests/generics/declaration/recursive_bounds/with_variance_invariant.phpt new file mode 100644 index 000000000000..9235476a5d82 --- /dev/null +++ b/Zend/tests/generics/declaration/recursive_bounds/with_variance_invariant.phpt @@ -0,0 +1,12 @@ +--TEST-- +Recursive bounds: invariant class params with mutual bounds are accepted +--FILE-- + {} +class Pair, U: Box> { + public function __construct(public Box $left, public Box $right) {} +} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/variance/arrow_violation_covariant_in_param.phpt b/Zend/tests/generics/declaration/variance/arrow_violation_covariant_in_param.phpt new file mode 100644 index 000000000000..c8ab23de97aa --- /dev/null +++ b/Zend/tests/generics/declaration/variance/arrow_violation_covariant_in_param.phpt @@ -0,0 +1,8 @@ +--TEST-- +Variance: +T on an arrow function in parameter position is rejected +--FILE-- +(T $x): T => $x; +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/autoload_unresolved_implements_forwarded.phpt b/Zend/tests/generics/declaration/variance/autoload_unresolved_implements_forwarded.phpt new file mode 100644 index 000000000000..4b3c255ce18a --- /dev/null +++ b/Zend/tests/generics/declaration/variance/autoload_unresolved_implements_forwarded.phpt @@ -0,0 +1,20 @@ +--TEST-- +Variance: covariant T forwarded into an `implements` arg whose target autoloads later is accepted +--FILE-- + 'interface AUI_Sequence<+T> {}', + 'AUI_ArraySequence' => 'final class AUI_ArraySequence<+T> implements AUI_Sequence {}', + ]; + + if (isset($sources[$class])) { + eval($sources[$class]); + } +}); + +class_exists('AUI_ArraySequence'); +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/variance/autoload_unresolved_implements_violation.phpt b/Zend/tests/generics/declaration/variance/autoload_unresolved_implements_violation.phpt new file mode 100644 index 000000000000..2f32f90a6cfc --- /dev/null +++ b/Zend/tests/generics/declaration/variance/autoload_unresolved_implements_violation.phpt @@ -0,0 +1,19 @@ +--TEST-- +Variance: covariant T forwarded into a contravariant `implements` arg is rejected at link time when the target autoloads later +--FILE-- + 'interface AUI2_Sink<-U> {}', + 'AUI2_Bad' => 'final class AUI2_Bad<+T> implements AUI2_Sink {}', + ]; + + if (isset($sources[$class])) { + eval($sources[$class]); + } +}); + +class_exists('AUI2_Bad'); +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/closure_violation_covariant_in_param.phpt b/Zend/tests/generics/declaration/variance/closure_violation_covariant_in_param.phpt new file mode 100644 index 000000000000..2edff154047b --- /dev/null +++ b/Zend/tests/generics/declaration/variance/closure_violation_covariant_in_param.phpt @@ -0,0 +1,8 @@ +--TEST-- +Variance: +T on a closure in parameter position is rejected +--FILE-- +(T $x): void {}; +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/function_happy_path.phpt b/Zend/tests/generics/declaration/variance/function_happy_path.phpt new file mode 100644 index 000000000000..5640a800ccb7 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/function_happy_path.phpt @@ -0,0 +1,29 @@ +--TEST-- +Variance: function-origin type parameters checked uniformly with class-origin +--FILE-- +(T $x): int { return 0; } +function make<+T>(): T { return null; } +function transform<-I, +O>(I $input): O { return null; } + +$closure_take = function <-T>(T $x): int { return 0; }; +$closure_make = function <+T>(): T { return null; }; +$arrow_take = fn<-T>(T $x): int => 0; +$arrow_make = fn<+T>(): T => null; + +class A<+T = mixed> { + public function map<-A_, +B>(A_ $a): B { return null; } +} + +take(42); +make(); +transform(1); +$closure_take(7); +$closure_make(); +$arrow_take(7); +$arrow_make(); +(new A)->map(42); +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/variance/function_violation_composed.phpt b/Zend/tests/generics/declaration/variance/function_violation_composed.phpt new file mode 100644 index 000000000000..7b789e03a84a --- /dev/null +++ b/Zend/tests/generics/declaration/variance/function_violation_composed.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: function-origin +T composed through Consumer<-U> in return is rejected +--FILE-- + { public function consume(U $x): void; } + +function f<+T>(): Consumer {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/function_violation_contravariant_in_return.phpt b/Zend/tests/generics/declaration/variance/function_violation_contravariant_in_return.phpt new file mode 100644 index 000000000000..2777162dfe41 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/function_violation_contravariant_in_return.phpt @@ -0,0 +1,8 @@ +--TEST-- +Variance: -T on a function in return position (covariant) is rejected +--FILE-- +(): T {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared contravariant (-T) cannot appear in covariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/function_violation_covariant_in_param.phpt b/Zend/tests/generics/declaration/variance/function_violation_covariant_in_param.phpt new file mode 100644 index 000000000000..8cbbac94eff8 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/function_violation_covariant_in_param.phpt @@ -0,0 +1,8 @@ +--TEST-- +Variance: +T on a function in parameter position (contravariant) is rejected +--FILE-- +(T $x): void {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/function_violation_own_bound.phpt b/Zend/tests/generics/declaration/variance/function_violation_own_bound.phpt new file mode 100644 index 000000000000..38bd9ad201c4 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/function_violation_own_bound.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T on a function appearing in its own bound (invariant position) is rejected +--FILE-- + {} + +function f<+T : Box>(): void {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/happy_path.phpt b/Zend/tests/generics/declaration/variance/happy_path.phpt new file mode 100644 index 000000000000..6dc0ed560b11 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/happy_path.phpt @@ -0,0 +1,87 @@ +--TEST-- +Variance: full happy-path showing every legal combination +--FILE-- + { public function produce(): T; } +interface Consumer<-T> { public function consume(T $x): void; } +interface Inv { public function rw(U $x): U; } + +class CoProducer<+T> { + public readonly T $tag; + public function __construct(T $tag) { $this->tag = $tag; } + public function get(): T {} + public function makeProducer(): Producer {} + public function makeConsumerOfConsumers(): Consumer> {} +} + +class ReadOnlyHooked<+T> { + private T $backing; + public function __construct(T $v) { $this->backing = $v; } + public T $val { get => $this->backing; } +} + +class CoConsumer<-T> { + public function take(T $x): void {} + public function takeMany(T ...$xs): void {} + public function makeConsumer(): Consumer {} + public function consumerOfProducers(Producer $p): void {} +} + +class Holder { + public T $val; + public function __construct(T $v) { $this->val = $v; } + public function get(): T { return $this->val; } + public function set(T $v): void { $this->val = $v; } + public T $hooked { + get => $this->val; + set(T $v) { $this->val = $v; } + } +} + +interface Source<+T> { public function fetch(): T; } +class StringSource implements Source { + public function fetch(): string { return "ok"; } +} + +class CovariantChain<+T> implements Source { + public function __construct(public readonly T $value) {} + public function fetch(): T { return $this->value; } +} + +class MethodLevel<+T> { + public function map(U $key): T {} +} + +trait TraitProducer<+U> { + public function produceU(): U {} +} +class UsesProducerTrait { + use TraitProducer; + public function produceU(): int { return 7; } +} + +$h = new Holder::(42); +$h->set(7); +echo $h->get(), "\n"; + +$rh = new ReadOnlyHooked::("hi"); +echo $rh->val, "\n"; + +$cp = new CoProducer::(new Dog()); +echo get_class($cp->tag), "\n"; + +echo (new UsesProducerTrait)->produceU(), "\n"; +echo (new StringSource)->fetch(), "\n"; + +echo "all variance combinations OK\n"; +?> +--EXPECT-- +7 +hi +Dog +7 +ok +all variance combinations OK diff --git a/Zend/tests/generics/declaration/variance/method_function_origin_violation.phpt b/Zend/tests/generics/declaration/variance/method_function_origin_violation.phpt new file mode 100644 index 000000000000..2d053516ebb8 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/method_function_origin_violation.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T on a method's own type parameter in parameter position is rejected +--FILE-- +(T $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/mixed_class_T_and_function_T.phpt b/Zend/tests/generics/declaration/variance/mixed_class_T_and_function_T.phpt new file mode 100644 index 000000000000..3e1b9bc8c0fa --- /dev/null +++ b/Zend/tests/generics/declaration/variance/mixed_class_T_and_function_T.phpt @@ -0,0 +1,13 @@ +--TEST-- +Variance: class-T and function-T variance markers are checked independently in the same method +--FILE-- + { + public function map<-A, +B>(A $a): B { return null; } +} + +(new C)->map(42); +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/variance/parent_keyword_ok.phpt b/Zend/tests/generics/declaration/variance/parent_keyword_ok.phpt new file mode 100644 index 000000000000..de3a72a07366 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/parent_keyword_ok.phpt @@ -0,0 +1,16 @@ +--TEST-- +Variance: parent from a generic child of a generic parent +--FILE-- + { + public function __construct(public T $value) {} +} +final readonly class B<+T> extends A { + public function asParent(): parent { return $this; } +} + +$b = new B::(7); +echo $b->asParent()->value, "\n"; +?> +--EXPECT-- +7 diff --git a/Zend/tests/generics/declaration/variance/parent_keyword_violation.phpt b/Zend/tests/generics/declaration/variance/parent_keyword_violation.phpt new file mode 100644 index 000000000000..47c5217e614f --- /dev/null +++ b/Zend/tests/generics/declaration/variance/parent_keyword_violation.phpt @@ -0,0 +1,13 @@ +--TEST-- +Variance: parent in a contravariant parameter position is rejected for +T +--FILE-- + { + public function __construct(public T $value) {} +} +class B<+T> extends A { + public function take(parent $other): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/rfc_example.phpt b/Zend/tests/generics/declaration/variance/rfc_example.phpt new file mode 100644 index 000000000000..e65c030b9369 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/rfc_example.phpt @@ -0,0 +1,45 @@ +--TEST-- +RFC example: covariant Pair/Box with self-referential return type, zip, map, identity +--FILE-- + { + public function __construct( + public L $left, + public R $right, + ) {} + + public function swap(): Pair { + return new Pair($this->right, $this->left); + } +} + +final readonly class Box<+T = mixed> { + public function __construct( + public T $value, + ) {} + + public function map(callable $fn): Box { + return new Box(($fn)($this->value)); + } + + public function zip(O $value): Box> { + return new Box(new Pair($this->value, $value)); + } +} + +function identity(T $value): T { + return $value; +} + +$greeting = new Box::("hello, world"); +$paired = $greeting->zip::(42); +$swapped = $paired->value->swap(); +$result = identity($swapped); + +var_dump($result->left); +var_dump($result->right); +?> +--EXPECT-- +int(42) +string(12) "hello, world" diff --git a/Zend/tests/generics/declaration/variance/self_keyword_ok.phpt b/Zend/tests/generics/declaration/variance/self_keyword_ok.phpt new file mode 100644 index 000000000000..62825c96bb2e --- /dev/null +++ b/Zend/tests/generics/declaration/variance/self_keyword_ok.phpt @@ -0,0 +1,14 @@ +--TEST-- +Variance: self in a covariant return position +--FILE-- + { + public function __construct(public T $value) {} + public function clone_(): self { return new self($this->value); } +} + +$c = new C::(42); +echo $c->clone_()->value, "\n"; +?> +--EXPECT-- +42 diff --git a/Zend/tests/generics/declaration/variance/self_keyword_through_invariant_class_violation.phpt b/Zend/tests/generics/declaration/variance/self_keyword_through_invariant_class_violation.phpt new file mode 100644 index 000000000000..7c579f8f4986 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/self_keyword_through_invariant_class_violation.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T cannot appear at an invariant slot of self<...> when the class param is invariant +--FILE-- + { + public function get(): self {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/self_keyword_violation.phpt b/Zend/tests/generics/declaration/variance/self_keyword_violation.phpt new file mode 100644 index 000000000000..cc90c2ad7d0c --- /dev/null +++ b/Zend/tests/generics/declaration/variance/self_keyword_violation.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: self in a contravariant parameter position is rejected for +T +--FILE-- + { + public function take(self $other): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/self_ref_class_name_ok.phpt b/Zend/tests/generics/declaration/variance/self_ref_class_name_ok.phpt new file mode 100644 index 000000000000..9c88343c7ab8 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/self_ref_class_name_ok.phpt @@ -0,0 +1,18 @@ +--TEST-- +Variance: a generic class referencing itself by name in a covariant return position +--FILE-- + { + public function __construct(public L $left, public R $right) {} + public function swap(): Pair { + return new Pair($this->right, $this->left); + } +} + +$p = new Pair::(7, "hi"); +$s = $p->swap(); +var_dump($s->left, $s->right); +?> +--EXPECT-- +string(2) "hi" +int(7) diff --git a/Zend/tests/generics/declaration/variance/self_ref_class_name_violation.phpt b/Zend/tests/generics/declaration/variance/self_ref_class_name_violation.phpt new file mode 100644 index 000000000000..505d5773102d --- /dev/null +++ b/Zend/tests/generics/declaration/variance/self_ref_class_name_violation.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: self-referenced class name in a violating position is still rejected +--FILE-- + { + public function take(C $other): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/static_keyword_ok.phpt b/Zend/tests/generics/declaration/variance/static_keyword_ok.phpt new file mode 100644 index 000000000000..0fac59480454 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/static_keyword_ok.phpt @@ -0,0 +1,14 @@ +--TEST-- +Variance: static in a covariant return position +--FILE-- + { + public function __construct(public T $value) {} + public function dup(): static { return new static($this->value); } +} + +$c = new C::("ok"); +echo $c->dup()->value, "\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/declaration/variance/static_method_function_origin_violation.phpt b/Zend/tests/generics/declaration/variance/static_method_function_origin_violation.phpt new file mode 100644 index 000000000000..f1998ace645a --- /dev/null +++ b/Zend/tests/generics/declaration/variance/static_method_function_origin_violation.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T on a static method's own type parameter in parameter position is rejected +--FILE-- +(T $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_contravariant_in_get_hook.phpt b/Zend/tests/generics/declaration/variance/violation_contravariant_in_get_hook.phpt new file mode 100644 index 000000000000..48809790c6ff --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_contravariant_in_get_hook.phpt @@ -0,0 +1,15 @@ +--TEST-- +Variance: -T in a hooked property with set hook (invariant position) is rejected +--FILE-- + { + private T $backing; + public function __construct(T $v) { $this->backing = $v; } + public T $val { + get => $this->backing; + set(T $v) { $this->backing = $v; } + } +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared contravariant (-T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_contravariant_in_readonly_property.phpt b/Zend/tests/generics/declaration/variance/violation_contravariant_in_readonly_property.phpt new file mode 100644 index 000000000000..4f5e19309fa3 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_contravariant_in_readonly_property.phpt @@ -0,0 +1,11 @@ +--TEST-- +Variance: -T in a readonly property (covariant position) is rejected +--FILE-- + { + public readonly T $val; + public function __construct(T $v) { $this->val = $v; } +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared contravariant (-T) cannot appear in covariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_contravariant_in_return.phpt b/Zend/tests/generics/declaration/variance/violation_contravariant_in_return.phpt new file mode 100644 index 000000000000..e70dd1668a48 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_contravariant_in_return.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: -T in method return (covariant position) is rejected +--FILE-- + { + public function get(): T {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared contravariant (-T) cannot appear in covariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_contravariant_in_rw_property.phpt b/Zend/tests/generics/declaration/variance/violation_contravariant_in_rw_property.phpt new file mode 100644 index 000000000000..4089e855215d --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_contravariant_in_rw_property.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: -T in a read/write typed property (invariant position) is rejected +--FILE-- + { + public T $val; +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared contravariant (-T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_contravariant_through_covariant_arg_in_return.phpt b/Zend/tests/generics/declaration/variance/violation_contravariant_through_covariant_arg_in_return.phpt new file mode 100644 index 000000000000..d546fc82ec56 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_contravariant_through_covariant_arg_in_return.phpt @@ -0,0 +1,12 @@ +--TEST-- +Variance: -T composed through Producer<+U> in return (+ × + = +) is rejected +--FILE-- + { public function produce(): U; } + +class A<-T> { + public function makeProducer(): Producer {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared contravariant (-T) cannot appear in covariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_in_byref_get_hook.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_in_byref_get_hook.phpt new file mode 100644 index 000000000000..d325cc358f94 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_in_byref_get_hook.phpt @@ -0,0 +1,14 @@ +--TEST-- +Variance: +T in a hooked property with by-ref get (effectively invariant) is rejected +--FILE-- + { + private T $backing; + public function __construct(T $v) { $this->backing = $v; } + public T $val { + &get => $this->backing; + } +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_in_default.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_in_default.phpt new file mode 100644 index 000000000000..917bdf2d3fbb --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_in_default.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T in a sibling type parameter's default (invariant position) is rejected +--FILE-- + { public function get(): U; } + +class A<+T, U = Container> {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_in_own_bound.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_in_own_bound.phpt new file mode 100644 index 000000000000..137641603c97 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_in_own_bound.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T appearing in its own bound (invariant position) is rejected +--FILE-- + { public function get(): U; } + +class A<+T : Box> {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_in_param.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_in_param.phpt new file mode 100644 index 000000000000..1beeba25176b --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_in_param.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T in method parameter (contravariant position) is rejected +--FILE-- + { + public function take(T $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_in_rw_property.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_in_rw_property.phpt new file mode 100644 index 000000000000..b03d1aff1fec --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_in_rw_property.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T in a read/write typed property (invariant position) is rejected +--FILE-- + { + public T $val; +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_in_set_hook.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_in_set_hook.phpt new file mode 100644 index 000000000000..28267341e6b5 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_in_set_hook.phpt @@ -0,0 +1,15 @@ +--TEST-- +Variance: +T in a hooked property's set hook (contravariant position) is rejected +--FILE-- + { + private T $backing; + public function __construct(T $v) { $this->backing = $v; } + public T $val { + get => $this->backing; + set(T $v) { $this->backing = $v; } + } +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_in_sibling_bound.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_in_sibling_bound.phpt new file mode 100644 index 000000000000..10880152c60f --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_in_sibling_bound.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T mentioned in a sibling type parameter's bound (invariant position) is rejected +--FILE-- + { public function get(): U; } + +class A<+T, U : Container> {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_through_contravariant_arg_in_return.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_through_contravariant_arg_in_return.phpt new file mode 100644 index 000000000000..ddd4f6825393 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_through_contravariant_arg_in_return.phpt @@ -0,0 +1,12 @@ +--TEST-- +Variance: +T composed through Consumer<-U> in return (+ × - = -) is rejected +--FILE-- + { public function consume(U $x): void; } + +class A<+T> { + public function makeConsumer(): Consumer {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_covariant_through_invariant_arg.phpt b/Zend/tests/generics/declaration/variance/violation_covariant_through_invariant_arg.phpt new file mode 100644 index 000000000000..10005ea1449c --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_covariant_through_invariant_arg.phpt @@ -0,0 +1,12 @@ +--TEST-- +Variance: +T composed through an invariant generic's slot (invariant) is rejected +--FILE-- + { public function rw(U $x): U; } + +class A<+T> { + public function get(): Inv {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_extends_contravariant_arg.phpt b/Zend/tests/generics/declaration/variance/violation_extends_contravariant_arg.phpt new file mode 100644 index 000000000000..d912f81535d3 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_extends_contravariant_arg.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T as the type-arg to a contravariant parent's parameter is rejected +--FILE-- + {} + +class A<+T> extends Cons {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in contravariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_extends_invariant_arg.phpt b/Zend/tests/generics/declaration/variance/violation_extends_invariant_arg.phpt new file mode 100644 index 000000000000..ac7524f9e28b --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_extends_invariant_arg.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T as the type-arg to an invariant parent's parameter is rejected +--FILE-- + {} + +class A<+T> extends Inv {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_implements_invariant_arg.phpt b/Zend/tests/generics/declaration/variance/violation_implements_invariant_arg.phpt new file mode 100644 index 000000000000..f4e63a3f78e9 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_implements_invariant_arg.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variance: +T as the type-arg to an invariant interface's parameter is rejected +--FILE-- + {} + +class A<+T> implements Inv {} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_line_points_at_method.phpt b/Zend/tests/generics/declaration/variance/violation_line_points_at_method.phpt new file mode 100644 index 000000000000..32b84d702a93 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_line_points_at_method.phpt @@ -0,0 +1,16 @@ +--TEST-- +Variance: a violation inside a method signature reports the method's line, not the class header +--FILE-- + { + public function ok(): T { + throw new RuntimeException(); + } + + public function bad(O $default): T|O { + return $default; + } +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line 7 diff --git a/Zend/tests/generics/declaration/variance/violation_method_T_bound_uses_class_T.phpt b/Zend/tests/generics/declaration/variance/violation_method_T_bound_uses_class_T.phpt new file mode 100644 index 000000000000..d1f12650b1cc --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_method_T_bound_uses_class_T.phpt @@ -0,0 +1,12 @@ +--TEST-- +Variance: +T appearing inside a method-level type parameter's bound (invariant) is rejected +--FILE-- + {} + +class A<+T> { + public function map>(W $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/declaration/variance/violation_use_trait_invariant_arg.phpt b/Zend/tests/generics/declaration/variance/violation_use_trait_invariant_arg.phpt new file mode 100644 index 000000000000..a5b8618683f7 --- /dev/null +++ b/Zend/tests/generics/declaration/variance/violation_use_trait_invariant_arg.phpt @@ -0,0 +1,14 @@ +--TEST-- +Variance: +T as the type-arg to an invariant trait's parameter is rejected +--FILE-- + { + public function rw(U $x): U { return $x; } +} + +class A<+T> { + use InvTrait; +} +?> +--EXPECTF-- +Fatal error: Type parameter T declared covariant (+T) cannot appear in invariant position in %s on line %d diff --git a/Zend/tests/generics/erasure/arrow_fn_erasure.phpt b/Zend/tests/generics/erasure/arrow_fn_erasure.phpt new file mode 100644 index 000000000000..d14f301d4cd4 --- /dev/null +++ b/Zend/tests/generics/erasure/arrow_fn_erasure.phpt @@ -0,0 +1,10 @@ +--TEST-- +Erasure: arrow function with type parameters erases to bound +--FILE-- +(T $x): T => $x; +$r = new ReflectionFunction($f); +echo $r->getParameters()[0]->getType()->__toString(), "\n"; +?> +--EXPECT-- +int diff --git a/Zend/tests/generics/erasure/bound_object.phpt b/Zend/tests/generics/erasure/bound_object.phpt new file mode 100644 index 000000000000..815dd1a5e92c --- /dev/null +++ b/Zend/tests/generics/erasure/bound_object.phpt @@ -0,0 +1,12 @@ +--TEST-- +Erasure: T : object erases to object +--FILE-- +(T $x): T { return $x; } +$r = new ReflectionFunction('id'); +echo $r->getParameters()[0]->getType()->__toString(), "\n"; +echo $r->getReturnType()->__toString(), "\n"; +?> +--EXPECT-- +object +object diff --git a/Zend/tests/generics/erasure/bound_to_class.phpt b/Zend/tests/generics/erasure/bound_to_class.phpt new file mode 100644 index 000000000000..7b1cfa50414e --- /dev/null +++ b/Zend/tests/generics/erasure/bound_to_class.phpt @@ -0,0 +1,13 @@ +--TEST-- +Erasure: T : Foo erases to Foo +--FILE-- +(T $x): T { return $x; } +$r = new ReflectionFunction('id'); +echo $r->getParameters()[0]->getType()->getName(), "\n"; +echo $r->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +Foo +Foo diff --git a/Zend/tests/generics/erasure/closure_erasure.phpt b/Zend/tests/generics/erasure/closure_erasure.phpt new file mode 100644 index 000000000000..6a533558b3aa --- /dev/null +++ b/Zend/tests/generics/erasure/closure_erasure.phpt @@ -0,0 +1,10 @@ +--TEST-- +Erasure: closure with type parameters erases to bound +--FILE-- +(T $x): T { return $x; }; +$r = new ReflectionFunction($f); +echo $r->getParameters()[0]->getType()->__toString(), "\n"; +?> +--EXPECT-- +object diff --git a/Zend/tests/generics/erasure/composite_bound.phpt b/Zend/tests/generics/erasure/composite_bound.phpt new file mode 100644 index 000000000000..5e38afba9a81 --- /dev/null +++ b/Zend/tests/generics/erasure/composite_bound.phpt @@ -0,0 +1,11 @@ +--TEST-- +Erasure: composite bound erased +--FILE-- +(T $x): T { return $x; } +$rt = (new ReflectionFunction('f'))->getReturnType(); +echo get_class($rt), "\n"; +?> +--EXPECT-- +ReflectionUnionType diff --git a/Zend/tests/generics/erasure/erased_signature_match.phpt b/Zend/tests/generics/erasure/erased_signature_match.phpt new file mode 100644 index 000000000000..64406feb72a6 --- /dev/null +++ b/Zend/tests/generics/erasure/erased_signature_match.phpt @@ -0,0 +1,20 @@ +--TEST-- +Erasure: generic signature matches hand-erased equivalent +--FILE-- + { + public function get(): T { return new Foo; } +} + +class Erased { + public function get(): Foo { return new Foo; } +} + +$rg = (new ReflectionClass('Generic'))->getMethod('get')->getReturnType()->__toString(); +$re = (new ReflectionClass('Erased'))->getMethod('get')->getReturnType()->__toString(); +var_dump($rg === $re); +?> +--EXPECT-- +bool(true) diff --git a/Zend/tests/generics/erasure/extends_args_discarded.phpt b/Zend/tests/generics/erasure/extends_args_discarded.phpt new file mode 100644 index 000000000000..1c46d8103850 --- /dev/null +++ b/Zend/tests/generics/erasure/extends_args_discarded.phpt @@ -0,0 +1,13 @@ +--TEST-- +Inheritance: `extends Base` makes the direct parent the synthesized monomorph +--FILE-- + {} +class Derived extends Base {} +echo (new ReflectionClass('Derived'))->getParentClass()->getName(), "\n"; +$d = new Derived; +var_dump($d instanceof Base); +?> +--EXPECT-- +Base +bool(true) diff --git a/Zend/tests/generics/erasure/generic_class_param.phpt b/Zend/tests/generics/erasure/generic_class_param.phpt new file mode 100644 index 000000000000..bde3ae6281c5 --- /dev/null +++ b/Zend/tests/generics/erasure/generic_class_param.phpt @@ -0,0 +1,13 @@ +--TEST-- +Erasure: generic class parameter type erased to bound +--FILE-- + { + public function set(T $x): void {} +} +$rm = (new ReflectionClass('Box'))->getMethod('set'); +echo $rm->getParameters()[0]->getType()->getName(), "\n"; +?> +--EXPECT-- +Iface diff --git a/Zend/tests/generics/erasure/get_class_returns_erased.phpt b/Zend/tests/generics/erasure/get_class_returns_erased.phpt new file mode 100644 index 000000000000..2a85a21c3e31 --- /dev/null +++ b/Zend/tests/generics/erasure/get_class_returns_erased.phpt @@ -0,0 +1,10 @@ +--TEST-- +Monomorphization: get_class returns the canonical monomorph name +--FILE-- + {} +$b = new Box::; +echo get_class($b), "\n"; +?> +--EXPECT-- +Box diff --git a/Zend/tests/generics/erasure/instanceof_args_discarded.phpt b/Zend/tests/generics/erasure/instanceof_args_discarded.phpt new file mode 100644 index 000000000000..d2a501d96193 --- /dev/null +++ b/Zend/tests/generics/erasure/instanceof_args_discarded.phpt @@ -0,0 +1,10 @@ +--TEST-- +Erasure: instanceof on a non-generic class with type arguments is a compile-time error +--FILE-- +); +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class C in %s on line %d diff --git a/Zend/tests/generics/erasure/intersection_t_bound_class.phpt b/Zend/tests/generics/erasure/intersection_t_bound_class.phpt new file mode 100644 index 000000000000..20421c878257 --- /dev/null +++ b/Zend/tests/generics/erasure/intersection_t_bound_class.phpt @@ -0,0 +1,20 @@ +--TEST-- +Erasure: T in intersection position with class-like bound erases cleanly +--FILE-- +(T & Foo $x): T & Foo { return $x; } + +$r = new ReflectionFunction('pickIface'); +echo "param: ", $r->getParameters()[0]->getType(), "\n"; +echo "return: ", $r->getReturnType(), "\n"; + +class BarFoo implements Bar, Foo {} +var_dump(pickIface(new BarFoo) instanceof BarFoo); +?> +--EXPECT-- +param: Bar&Foo +return: Bar&Foo +bool(true) diff --git a/Zend/tests/generics/erasure/method_bound.phpt b/Zend/tests/generics/erasure/method_bound.phpt new file mode 100644 index 000000000000..4562b258efad --- /dev/null +++ b/Zend/tests/generics/erasure/method_bound.phpt @@ -0,0 +1,13 @@ +--TEST-- +Erasure: method-level type parameter erased +--FILE-- +(U $x): U { return $x; } +} +$rt = (new ReflectionClass('C'))->getMethod('m')->getReturnType(); +echo $rt->getName(), "\n"; +?> +--EXPECT-- +Stringable2 diff --git a/Zend/tests/generics/erasure/method_inheritance_erased.phpt b/Zend/tests/generics/erasure/method_inheritance_erased.phpt new file mode 100644 index 000000000000..a94f25177bba --- /dev/null +++ b/Zend/tests/generics/erasure/method_inheritance_erased.phpt @@ -0,0 +1,19 @@ +--TEST-- +Erasure: child overriding generic parent method works on erased signature +--FILE-- +(T $x): T { return $x; } +} +class Child extends Parent2 { + public function f(U $x): U { return $x; } +} +$pm = (new ReflectionClass('Parent2'))->getMethod('f'); +$cm = (new ReflectionClass('Child'))->getMethod('f'); +echo $pm->getParameters()[0]->getType()->getName(), "\n"; +echo $cm->getParameters()[0]->getType()->getName(), "\n"; +?> +--EXPECT-- +Animal +Animal diff --git a/Zend/tests/generics/erasure/named_args_stripped.phpt b/Zend/tests/generics/erasure/named_args_stripped.phpt new file mode 100644 index 000000000000..066e6680ad72 --- /dev/null +++ b/Zend/tests/generics/erasure/named_args_stripped.phpt @@ -0,0 +1,9 @@ +--TEST-- +Erasure: type arguments on a non-generic class in a parameter/return type is a compile-time error +--FILE-- + $x): Container { return $x; } +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Container in %s on line %d diff --git a/Zend/tests/generics/erasure/property_type_erased.phpt b/Zend/tests/generics/erasure/property_type_erased.phpt new file mode 100644 index 000000000000..9b1e93e3d5a5 --- /dev/null +++ b/Zend/tests/generics/erasure/property_type_erased.phpt @@ -0,0 +1,16 @@ +--TEST-- +Erasure: generic property type erased to bound +--FILE-- + { + public T $value; +} +$rp = (new ReflectionClass('Box'))->getProperty('value'); +$rt = $rp->getType(); +echo get_class($rt), "\n"; +echo $rt->getName(), "\n"; +?> +--EXPECT-- +ReflectionNamedType +Foo diff --git a/Zend/tests/generics/erasure/runtime_bound_check.phpt b/Zend/tests/generics/erasure/runtime_bound_check.phpt new file mode 100644 index 000000000000..dc2b563701ec --- /dev/null +++ b/Zend/tests/generics/erasure/runtime_bound_check.phpt @@ -0,0 +1,21 @@ +--TEST-- +Erasure: bound is enforced at runtime +--FILE-- +(T $x): T { return $x; } + +echo get_class(f(new Dog)), "\n"; + +try { + f("not an animal"); + echo "FAIL\n"; +} catch (TypeError $e) { + echo "caught\n"; +} +?> +--EXPECT-- +Dog +caught diff --git a/Zend/tests/generics/erasure/runtime_unbounded.phpt b/Zend/tests/generics/erasure/runtime_unbounded.phpt new file mode 100644 index 000000000000..e86b52e60926 --- /dev/null +++ b/Zend/tests/generics/erasure/runtime_unbounded.phpt @@ -0,0 +1,20 @@ +--TEST-- +Erasure: unbounded T accepts anything (mixed) +--FILE-- +(T $x): T { return $x; } +var_dump(id(42)); +var_dump(id("hello")); +var_dump(id(null)); +var_dump(id([1, 2])); +?> +--EXPECT-- +int(42) +string(5) "hello" +NULL +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} diff --git a/Zend/tests/generics/erasure/t_in_nullable_and_union.phpt b/Zend/tests/generics/erasure/t_in_nullable_and_union.phpt new file mode 100644 index 000000000000..91f3959bce95 --- /dev/null +++ b/Zend/tests/generics/erasure/t_in_nullable_and_union.phpt @@ -0,0 +1,72 @@ +--TEST-- +Erasure: T inside nullable and union types collapses redundant nulls/mixed +--FILE-- +(?T $x): ?T { return $x; } +function nullableBounded(?T $x): ?T { return $x; } +function unionNullUnbounded(null|T $x): null|T { return $x; } +function unionMultiUnbounded(int|bool|T $x): int|bool|T { return $x; } +function unionNullBounded(null|T $x): null|T { return $x; } +function unionMultiBounded(int|T $x): int|T { return $x; } + +class Holder { + public function __construct(public ?T $value) {} + public function set(?T $v): void { $this->value = $v; } + public function get(): ?T { return $this->value; } +} + +var_dump(nullableUnbounded(42)); +var_dump(nullableUnbounded(null)); +var_dump(nullableUnbounded("hi")); +var_dump(nullableBounded(7)); +var_dump(nullableBounded(null)); +var_dump(unionNullUnbounded(null)); +var_dump(unionNullUnbounded("x")); +var_dump(unionMultiUnbounded(1)); +var_dump(unionMultiUnbounded(true)); +var_dump(unionMultiUnbounded(new stdClass)); +var_dump(unionNullBounded(null)); +var_dump(unionNullBounded(7)); +var_dump(unionMultiBounded(1)); + +echo "nullableUnbounded: ", (new ReflectionFunction('nullableUnbounded'))->getReturnType(), "\n"; +echo "nullableBounded: ", (new ReflectionFunction('nullableBounded'))->getReturnType(), "\n"; +echo "unionNullUnbounded: ", (new ReflectionFunction('unionNullUnbounded'))->getReturnType(), "\n"; +echo "unionMultiUnbounded: ", (new ReflectionFunction('unionMultiUnbounded'))->getReturnType(), "\n"; +echo "unionNullBounded: ", (new ReflectionFunction('unionNullBounded'))->getReturnType(), "\n"; +echo "unionMultiBounded: ", (new ReflectionFunction('unionMultiBounded'))->getReturnType(), "\n"; + +$rc = new ReflectionClass(Holder::class); +echo "Holder property: ", $rc->getProperty('value')->getType(), "\n"; +echo "Holder set param: ", $rc->getMethod('set')->getParameters()[0]->getType(), "\n"; +echo "Holder get return: ", $rc->getMethod('get')->getReturnType(), "\n"; + +$h = new Holder(1); +$h->set(null); +var_dump($h->get()); +?> +--EXPECT-- +int(42) +NULL +string(2) "hi" +int(7) +NULL +NULL +string(1) "x" +int(1) +bool(true) +object(stdClass)#1 (0) { +} +NULL +int(7) +int(1) +nullableUnbounded: mixed +nullableBounded: ?int +unionNullUnbounded: mixed +unionMultiUnbounded: mixed +unionNullBounded: ?int +unionMultiBounded: Stringable|int +Holder property: mixed +Holder set param: mixed +Holder get return: mixed +NULL diff --git a/Zend/tests/generics/erasure/turbofish_no_runtime_effect.phpt b/Zend/tests/generics/erasure/turbofish_no_runtime_effect.phpt new file mode 100644 index 000000000000..a41ecae4ace3 --- /dev/null +++ b/Zend/tests/generics/erasure/turbofish_no_runtime_effect.phpt @@ -0,0 +1,13 @@ +--TEST-- +Erasure: turbofish (with matching arity) has zero runtime effect +--FILE-- +($x) { return $x * 2; } +var_dump(f(5)); +var_dump(f::(5)); +var_dump(f::(5)); +?> +--EXPECT-- +int(10) +int(10) +int(10) diff --git a/Zend/tests/generics/erasure/unbounded_to_mixed.phpt b/Zend/tests/generics/erasure/unbounded_to_mixed.phpt new file mode 100644 index 000000000000..15ff253c3173 --- /dev/null +++ b/Zend/tests/generics/erasure/unbounded_to_mixed.phpt @@ -0,0 +1,12 @@ +--TEST-- +Erasure: unbounded T erases to mixed +--FILE-- +(T $x): T { return $x; } +$r = new ReflectionFunction('id'); +echo $r->getParameters()[0]->getType()->__toString(), "\n"; +echo $r->getReturnType()->__toString(), "\n"; +?> +--EXPECT-- +mixed +mixed diff --git a/Zend/tests/generics/erasure/var_dump_class_name.phpt b/Zend/tests/generics/erasure/var_dump_class_name.phpt new file mode 100644 index 000000000000..5852b3910887 --- /dev/null +++ b/Zend/tests/generics/erasure/var_dump_class_name.phpt @@ -0,0 +1,14 @@ +--TEST-- +Monomorphization: var_dump shows the canonical monomorph name +--FILE-- + { + public int $x = 1; +} +var_dump(new Box::); +?> +--EXPECT-- +object(Box)#1 (1) { + ["x"]=> + int(1) +} diff --git a/Zend/tests/generics/errors/anonymous_class_no_params.phpt b/Zend/tests/generics/errors/anonymous_class_no_params.phpt new file mode 100644 index 000000000000..6aca672cb9b2 --- /dev/null +++ b/Zend/tests/generics/errors/anonymous_class_no_params.phpt @@ -0,0 +1,12 @@ +--TEST-- +Errors: anonymous classes cannot declare type parameters +--FILE-- + {};'); +} catch (ParseError $e) { + echo "parse error: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +parse error: %s diff --git a/Zend/tests/generics/errors/closure_shadows_function.phpt b/Zend/tests/generics/errors/closure_shadows_function.phpt new file mode 100644 index 000000000000..29c6c8397605 --- /dev/null +++ b/Zend/tests/generics/errors/closure_shadows_function.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: closure type parameter shadows enclosing function type parameter +--FILE-- +(): void { + $cl = function (): void {}; +} +?> +--EXPECTF-- +Fatal error: Type parameter T shadows enclosing type parameter in %s on line %d diff --git a/Zend/tests/generics/errors/duplicate_in_method.phpt b/Zend/tests/generics/errors/duplicate_in_method.phpt new file mode 100644 index 000000000000..78fd038e233c --- /dev/null +++ b/Zend/tests/generics/errors/duplicate_in_method.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: duplicate type parameter inside a method's own list +--FILE-- +(): void {} } +?> +--EXPECTF-- +Fatal error: Cannot redeclare type parameter T in %s on line %d diff --git a/Zend/tests/generics/errors/duplicate_type_param.phpt b/Zend/tests/generics/errors/duplicate_type_param.phpt new file mode 100644 index 000000000000..77c148794173 --- /dev/null +++ b/Zend/tests/generics/errors/duplicate_type_param.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: duplicate type parameter name +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Cannot redeclare type parameter T in %s on line %d diff --git a/Zend/tests/generics/errors/duplicate_type_param_function.phpt b/Zend/tests/generics/errors/duplicate_type_param_function.phpt new file mode 100644 index 000000000000..f9ad4e8b270b --- /dev/null +++ b/Zend/tests/generics/errors/duplicate_type_param_function.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: duplicate type parameter name on function +--FILE-- +(): void {} +?> +--EXPECTF-- +Fatal error: Cannot redeclare type parameter U in %s on line %d diff --git a/Zend/tests/generics/errors/empty_arg_list.phpt b/Zend/tests/generics/errors/empty_arg_list.phpt new file mode 100644 index 000000000000..6ac10dcff2db --- /dev/null +++ b/Zend/tests/generics/errors/empty_arg_list.phpt @@ -0,0 +1,12 @@ +--TEST-- +Errors: empty type argument list +--FILE-- + $x): void {}'); +} catch (ParseError $e) { + echo "parse error\n"; +} +?> +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/empty_param_list.phpt b/Zend/tests/generics/errors/empty_param_list.phpt new file mode 100644 index 000000000000..918533b25f26 --- /dev/null +++ b/Zend/tests/generics/errors/empty_param_list.phpt @@ -0,0 +1,12 @@ +--TEST-- +Errors: empty type parameter list +--FILE-- + {}'); +} catch (ParseError $e) { + echo "parse error\n"; +} +?> +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/forward_ref_at_self.phpt b/Zend/tests/generics/errors/forward_ref_at_self.phpt new file mode 100644 index 000000000000..b4dd1601bd0a --- /dev/null +++ b/Zend/tests/generics/errors/forward_ref_at_self.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: bound `T : T` (top-level self-reference) is rejected +--FILE-- +(): void {} +?> +--EXPECTF-- +Fatal error: Type parameter T cannot reference itself in its own bound or default outside of a generic type argument in %s on line %d diff --git a/Zend/tests/generics/errors/forward_reference_in_default.phpt b/Zend/tests/generics/errors/forward_reference_in_default.phpt new file mode 100644 index 000000000000..915c0b4d09dd --- /dev/null +++ b/Zend/tests/generics/errors/forward_reference_in_default.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: forward reference in default of earlier parameter +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Type parameter T referenced before declaration in %s on line %d diff --git a/Zend/tests/generics/errors/intersection_t_bound_scalar.phpt b/Zend/tests/generics/errors/intersection_t_bound_scalar.phpt new file mode 100644 index 000000000000..4ce03e67f0dd --- /dev/null +++ b/Zend/tests/generics/errors/intersection_t_bound_scalar.phpt @@ -0,0 +1,9 @@ +--TEST-- +Errors: T in intersection position with scalar bound +--FILE-- +(): T & Foo {} +?> +--EXPECTF-- +Fatal error: Type parameter T with bound string cannot be part of an intersection type; use an object-shaped bound (e.g. T: object) in %s on line %d diff --git a/Zend/tests/generics/errors/intersection_t_unbounded.phpt b/Zend/tests/generics/errors/intersection_t_unbounded.phpt new file mode 100644 index 000000000000..940b218d2e5c --- /dev/null +++ b/Zend/tests/generics/errors/intersection_t_unbounded.phpt @@ -0,0 +1,9 @@ +--TEST-- +Errors: T in intersection position with unbounded T +--FILE-- +(): T & Foo {} +?> +--EXPECTF-- +Fatal error: Type parameter T with bound mixed cannot be part of an intersection type; use an object-shaped bound (e.g. T: object) in %s on line %d diff --git a/Zend/tests/generics/errors/method_shadows_class_param.phpt b/Zend/tests/generics/errors/method_shadows_class_param.phpt new file mode 100644 index 000000000000..6c8b3cfd7935 --- /dev/null +++ b/Zend/tests/generics/errors/method_shadows_class_param.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: method type parameter shadows class type parameter +--FILE-- + { + public function f(): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T shadows enclosing type parameter in %s on line %d diff --git a/Zend/tests/generics/errors/missing_close_angle.phpt b/Zend/tests/generics/errors/missing_close_angle.phpt new file mode 100644 index 000000000000..0ee4bae3581f --- /dev/null +++ b/Zend/tests/generics/errors/missing_close_angle.phpt @@ -0,0 +1,12 @@ +--TEST-- +Errors: missing closing angle in type parameter list +--FILE-- + +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/missing_param_after_comma.phpt b/Zend/tests/generics/errors/missing_param_after_comma.phpt new file mode 100644 index 000000000000..df223a838c29 --- /dev/null +++ b/Zend/tests/generics/errors/missing_param_after_comma.phpt @@ -0,0 +1,12 @@ +--TEST-- +Errors: missing parameter after trailing comma plus comma +--FILE-- + {}'); +} catch (ParseError $e) { + echo "parse error\n"; +} +?> +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/naked_new_without_defaults.phpt b/Zend/tests/generics/errors/naked_new_without_defaults.phpt new file mode 100644 index 000000000000..290ebd8f38bd --- /dev/null +++ b/Zend/tests/generics/errors/naked_new_without_defaults.phpt @@ -0,0 +1,9 @@ +--TEST-- +Errors: naked `new GenericClass()` is rejected if any type parameter has no default +--FILE-- + {} +new Box(); +?> +--EXPECTF-- +Fatal error: Cannot instantiate generic class Box without type arguments; type parameter T has no default in %s on line %d diff --git a/Zend/tests/generics/errors/optional_only_at_tail_ok.phpt b/Zend/tests/generics/errors/optional_only_at_tail_ok.phpt new file mode 100644 index 000000000000..101a3f0c6f85 --- /dev/null +++ b/Zend/tests/generics/errors/optional_only_at_tail_ok.phpt @@ -0,0 +1,15 @@ +--TEST-- +Errors: optional type parameters at the tail are accepted +--FILE-- + {} +class B {} +class C {} +class D {} +class E {} +function f(): void {} +function g(): void {} +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/errors/recursive_bound_ok.phpt b/Zend/tests/generics/errors/recursive_bound_ok.phpt new file mode 100644 index 000000000000..2b05466e6096 --- /dev/null +++ b/Zend/tests/generics/errors/recursive_bound_ok.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: recursive bound (T : Comparable) is allowed (positive test) +--FILE-- + {} +function f>(T $x): T { return $x; } +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/errors/required_after_optional.phpt b/Zend/tests/generics/errors/required_after_optional.phpt new file mode 100644 index 000000000000..65a48dad1157 --- /dev/null +++ b/Zend/tests/generics/errors/required_after_optional.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: required type parameter cannot follow an optional one +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Optional type parameter T cannot be declared before required type parameter U in %s on line %d diff --git a/Zend/tests/generics/errors/required_after_optional_function.phpt b/Zend/tests/generics/errors/required_after_optional_function.phpt new file mode 100644 index 000000000000..3bfefa731931 --- /dev/null +++ b/Zend/tests/generics/errors/required_after_optional_function.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: required type parameter cannot follow an optional one +--FILE-- +(): void {} +?> +--EXPECTF-- +Fatal error: Optional type parameter T cannot be declared before required type parameter U in %s on line %d diff --git a/Zend/tests/generics/errors/required_after_optional_three_params.phpt b/Zend/tests/generics/errors/required_after_optional_three_params.phpt new file mode 100644 index 000000000000..a4a5ad579ace --- /dev/null +++ b/Zend/tests/generics/errors/required_after_optional_three_params.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: required type parameter following two optional ones names the first optional +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Optional type parameter T cannot be declared before required type parameter V in %s on line %d diff --git a/Zend/tests/generics/errors/runtime_bound_violation.phpt b/Zend/tests/generics/errors/runtime_bound_violation.phpt new file mode 100644 index 000000000000..c6589429f414 --- /dev/null +++ b/Zend/tests/generics/errors/runtime_bound_violation.phpt @@ -0,0 +1,16 @@ +--TEST-- +Errors: runtime type error when bound is violated +--FILE-- +(T $x): T { return $x; } + +try { + f(42); + echo "no error\n"; +} catch (TypeError $e) { + echo "type error\n"; +} +?> +--EXPECT-- +type error diff --git a/Zend/tests/generics/errors/runtime_unbound_accepts_anything.phpt b/Zend/tests/generics/errors/runtime_unbound_accepts_anything.phpt new file mode 100644 index 000000000000..23084a77f8dd --- /dev/null +++ b/Zend/tests/generics/errors/runtime_unbound_accepts_anything.phpt @@ -0,0 +1,19 @@ +--TEST-- +Errors: runtime accepts anything for unbounded T (mixed) +--FILE-- +(T $x): T { return $x; } + +var_dump(f(42)); +var_dump(f("foo")); +var_dump(f(null)); +var_dump(f(new stdClass)); +echo "no errors\n"; +?> +--EXPECT-- +int(42) +string(3) "foo" +NULL +object(stdClass)#1 (0) { +} +no errors diff --git a/Zend/tests/generics/errors/self_ref_in_default.phpt b/Zend/tests/generics/errors/self_ref_in_default.phpt new file mode 100644 index 000000000000..d852a85d83a5 --- /dev/null +++ b/Zend/tests/generics/errors/self_ref_in_default.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: top-level self-reference in default is rejected +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Type parameter T cannot reference itself in its own bound or default outside of a generic type argument in %s on line %d diff --git a/Zend/tests/generics/errors/self_ref_in_intersection.phpt b/Zend/tests/generics/errors/self_ref_in_intersection.phpt new file mode 100644 index 000000000000..3a6970bf3a4a --- /dev/null +++ b/Zend/tests/generics/errors/self_ref_in_intersection.phpt @@ -0,0 +1,9 @@ +--TEST-- +Errors: top-level self-reference inside an intersection bound is rejected +--FILE-- +(): void {} +?> +--EXPECTF-- +Fatal error: Type parameter T cannot reference itself in its own bound or default outside of a generic type argument in %s on line %d diff --git a/Zend/tests/generics/errors/self_ref_in_union.phpt b/Zend/tests/generics/errors/self_ref_in_union.phpt new file mode 100644 index 000000000000..e40264a7b61d --- /dev/null +++ b/Zend/tests/generics/errors/self_ref_in_union.phpt @@ -0,0 +1,8 @@ +--TEST-- +Errors: top-level self-reference inside a union bound is rejected +--FILE-- +(): void {} +?> +--EXPECTF-- +Fatal error: Type parameter T cannot reference itself in its own bound or default outside of a generic type argument in %s on line %d diff --git a/Zend/tests/generics/errors/turbofish_no_call_target.phpt b/Zend/tests/generics/errors/turbofish_no_call_target.phpt new file mode 100644 index 000000000000..fd3c7fb8be6c --- /dev/null +++ b/Zend/tests/generics/errors/turbofish_no_call_target.phpt @@ -0,0 +1,12 @@ +--TEST-- +Errors: bare turbofish without function call +--FILE-- +;'); +} catch (ParseError $e) { + echo "parse error\n"; +} +?> +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/turbofish_with_space.phpt b/Zend/tests/generics/errors/turbofish_with_space.phpt new file mode 100644 index 000000000000..a7460772979a --- /dev/null +++ b/Zend/tests/generics/errors/turbofish_with_space.phpt @@ -0,0 +1,13 @@ +--TEST-- +Errors: whitespace between :: and < is not turbofish +--FILE-- +::f();'); +} catch (ParseError $e) { + echo "parse error\n"; +} +?> +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/type_args_in_class_const.phpt b/Zend/tests/generics/errors/type_args_in_class_const.phpt new file mode 100644 index 000000000000..8077a89c3e38 --- /dev/null +++ b/Zend/tests/generics/errors/type_args_in_class_const.phpt @@ -0,0 +1,13 @@ +--TEST-- +Errors: type arguments not allowed in expression position (Foo::class) +--FILE-- +::class;'); +} catch (ParseError $e) { + echo "parse error\n"; +} +?> +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/type_args_in_static_call.phpt b/Zend/tests/generics/errors/type_args_in_static_call.phpt new file mode 100644 index 000000000000..509cd35991a2 --- /dev/null +++ b/Zend/tests/generics/errors/type_args_in_static_call.phpt @@ -0,0 +1,13 @@ +--TEST-- +Errors: type arguments not allowed before :: (use ::<...> turbofish instead) +--FILE-- +::bar();'); +} catch (ParseError $e) { + echo "parse error\n"; +} +?> +--EXPECT-- +parse error diff --git a/Zend/tests/generics/errors/type_args_on_non_generic_catch.phpt b/Zend/tests/generics/errors/type_args_on_non_generic_catch.phpt new file mode 100644 index 000000000000..48bbd541521a --- /dev/null +++ b/Zend/tests/generics/errors/type_args_on_non_generic_catch.phpt @@ -0,0 +1,12 @@ +--TEST-- +Type arguments on a non-generic class in `catch` are a compile-time error +--FILE-- + $e) { +} +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class MyErr in %s on line %d diff --git a/Zend/tests/generics/errors/type_args_on_non_generic_implements.phpt b/Zend/tests/generics/errors/type_args_on_non_generic_implements.phpt new file mode 100644 index 000000000000..ec535974e86f --- /dev/null +++ b/Zend/tests/generics/errors/type_args_on_non_generic_implements.phpt @@ -0,0 +1,9 @@ +--TEST-- +Type arguments on a non-generic interface in `implements` are a compile-time error +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d diff --git a/Zend/tests/generics/errors/type_args_on_non_generic_instanceof.phpt b/Zend/tests/generics/errors/type_args_on_non_generic_instanceof.phpt new file mode 100644 index 000000000000..fe06732eed73 --- /dev/null +++ b/Zend/tests/generics/errors/type_args_on_non_generic_instanceof.phpt @@ -0,0 +1,10 @@ +--TEST-- +Type arguments on a non-generic class in `instanceof` are a compile-time error +--FILE-- +); +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d diff --git a/Zend/tests/generics/errors/type_args_on_non_generic_new.phpt b/Zend/tests/generics/errors/type_args_on_non_generic_new.phpt new file mode 100644 index 000000000000..2490ce2181cc --- /dev/null +++ b/Zend/tests/generics/errors/type_args_on_non_generic_new.phpt @@ -0,0 +1,9 @@ +--TEST-- +Type arguments on a non-generic class in `new` (turbofish) are a compile-time error +--FILE-- +(); +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d diff --git a/Zend/tests/generics/errors/type_args_on_non_generic_param.phpt b/Zend/tests/generics/errors/type_args_on_non_generic_param.phpt new file mode 100644 index 000000000000..d23d51ad3c49 --- /dev/null +++ b/Zend/tests/generics/errors/type_args_on_non_generic_param.phpt @@ -0,0 +1,9 @@ +--TEST-- +Type arguments on a non-generic class in a parameter type are a compile-time error +--FILE-- + $x): void {} +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d diff --git a/Zend/tests/generics/errors/type_args_on_non_generic_property.phpt b/Zend/tests/generics/errors/type_args_on_non_generic_property.phpt new file mode 100644 index 000000000000..49e1e7356012 --- /dev/null +++ b/Zend/tests/generics/errors/type_args_on_non_generic_property.phpt @@ -0,0 +1,11 @@ +--TEST-- +Type arguments on a non-generic class in a property type are a compile-time error +--FILE-- + $x; +} +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d diff --git a/Zend/tests/generics/errors/type_args_on_non_generic_return.phpt b/Zend/tests/generics/errors/type_args_on_non_generic_return.phpt new file mode 100644 index 000000000000..7a4b5d3d19b0 --- /dev/null +++ b/Zend/tests/generics/errors/type_args_on_non_generic_return.phpt @@ -0,0 +1,9 @@ +--TEST-- +Type arguments on a non-generic class in a return type are a compile-time error +--FILE-- + { return new Plain; } +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_catch.phpt b/Zend/tests/generics/errors/type_param_in_catch.phpt new file mode 100644 index 000000000000..7d46d8f88380 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_catch.phpt @@ -0,0 +1,17 @@ +--TEST-- +catch (T $e) silently does not match when T has no usable binding +--FILE-- +(): void { + // T has no class bound and no caller-supplied binding. catch (T $e) + // is therefore "catch nothing"; the thrown exception propagates out. + try { throw new Exception("boom"); } catch (T $e) { echo "caught\n"; } +} +try { + f(); +} catch (Throwable $e) { + echo "outer: ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +outer: boom diff --git a/Zend/tests/generics/errors/type_param_in_class_const.phpt b/Zend/tests/generics/errors/type_param_in_class_const.phpt new file mode 100644 index 000000000000..fc8c6410544a --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_class_const.phpt @@ -0,0 +1,11 @@ +--TEST-- +Errors: bare function-level type parameter used in `T::class` errors at runtime when nothing pins it +--FILE-- +(): string { + return T::class; +} +f(); +?> +--EXPECTF-- +Fatal error: Cannot resolve generic type parameter T at runtime: no binding was supplied and its bound is not a class in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_instanceof.phpt b/Zend/tests/generics/errors/type_param_in_instanceof.phpt new file mode 100644 index 000000000000..45644edbe8d4 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_instanceof.phpt @@ -0,0 +1,15 @@ +--TEST-- +Errors: bare function-level type parameter used in `instanceof T` errors at runtime when nothing pins it +--FILE-- +($x): bool { + return $x instanceof T; +} +f(new stdClass()); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot resolve generic type parameter T at runtime: no binding was supplied and its bound is not a class in %s:%d +Stack trace: +#0 %s(%d): f(Object(stdClass)) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_new_expression.phpt b/Zend/tests/generics/errors/type_param_in_new_expression.phpt new file mode 100644 index 000000000000..bd7a6bfc8d8b --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_new_expression.phpt @@ -0,0 +1,15 @@ +--TEST-- +Errors: bare function-level type parameter used in `new T()` errors at runtime when nothing pins it +--FILE-- +(): void { + new T(); +} +f(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot resolve generic type parameter T at runtime: no binding was supplied and its bound is not a class in %s:%d +Stack trace: +#0 %s(%d): f() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_new_turbofish.phpt b/Zend/tests/generics/errors/type_param_in_new_turbofish.phpt new file mode 100644 index 000000000000..ef408a982579 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_new_turbofish.phpt @@ -0,0 +1,40 @@ +--TEST-- +Errors: a forwarded TYPE_PARAMETER ref in a `new C::()` turbofish errors at the synth site when nothing pins T and its bound is not a class +--FILE-- +(...)` instead of +// being the class itself. Both must produce the same diagnostic, fired at the +// `new` site — not silently produce a broken-refs monomorph that crashes far +// from the cause when a method is later called on it. +final readonly class Box { + public function __construct(public array $items = []) {} +} + +function makeBox(): Box { + return new Box::([]); +} + +try { + makeBox(); + echo "no error??\n"; +} catch (Error $e) { + echo "ok: " . $e->getMessage() . "\n"; +} + +// A class-bound on the outer T gives a fallback target. +class Base {} +function makeBoxFromBound(): Box { + return new Box::([]); +} +$b = makeBoxFromBound(); +var_dump($b::class); + +// Turbofish supplied: no error, T resolves to the supplied type. +$b = makeBox::(); +var_dump($b::class); +?> +--EXPECT-- +ok: Cannot resolve generic type parameter T at runtime: no binding was supplied and its bound is not a class +string(9) "Box" +string(8) "Box" diff --git a/Zend/tests/generics/errors/type_param_in_static_call.phpt b/Zend/tests/generics/errors/type_param_in_static_call.phpt new file mode 100644 index 000000000000..66cd5ae9cab7 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_call.phpt @@ -0,0 +1,15 @@ +--TEST-- +Errors: bare function-level type parameter used as a static-call target errors at runtime when nothing pins it +--FILE-- +(): void { + T::foo(); +} +f(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot resolve generic type parameter T at runtime: no binding was supplied and its bound is not a class in %s:%d +Stack trace: +#0 %s(%d): f() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method.phpt b/Zend/tests/generics/errors/type_param_in_static_method.phpt new file mode 100644 index 000000000000..aa67becd88c9 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot be used in a static method signature +--FILE-- + { + public static function foo(T $a): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_bound.phpt b/Zend/tests/generics/errors/type_param_in_static_method_bound.phpt new file mode 100644 index 000000000000..ebb09bf3ddb4 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_bound.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot be used as a bound on a static method's own type parameter +--FILE-- + { + public static function foo(U $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_default.phpt b/Zend/tests/generics/errors/type_param_in_static_method_default.phpt new file mode 100644 index 000000000000..a2d5edbb94fa --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_default.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot be used as a default for a static method's own type parameter +--FILE-- + { + public static function foo(U $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_in_trait.phpt b/Zend/tests/generics/errors/type_param_in_static_method_in_trait.phpt new file mode 100644 index 000000000000..bff9674b4951 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_in_trait.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: trait type parameter cannot be used in a static method signature +--FILE-- + { + public static function make(T $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to Bag and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_intersection.phpt b/Zend/tests/generics/errors/type_param_in_static_method_intersection.phpt new file mode 100644 index 000000000000..afe7ee4a36c1 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_intersection.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot appear in an intersection type on a static method +--FILE-- + { + public static function foo(T&Countable $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_nested.phpt b/Zend/tests/generics/errors/type_param_in_static_method_nested.phpt new file mode 100644 index 000000000000..2c467f43333d --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_nested.phpt @@ -0,0 +1,14 @@ +--TEST-- +Errors: class type parameter cannot be nested inside a generic type in a static method signature +--FILE-- + { + public function __construct(public null|U $value) {} +} + +class Example { + public static function unwrap(Optional $value): mixed { return $value->value; } +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to Example and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_nullable.phpt b/Zend/tests/generics/errors/type_param_in_static_method_nullable.phpt new file mode 100644 index 000000000000..a021dd2ee9e4 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_nullable.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot appear in a nullable type on a static method +--FILE-- + { + public static function foo(?T $x): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_return.phpt b/Zend/tests/generics/errors/type_param_in_static_method_return.phpt new file mode 100644 index 000000000000..bbcd3b326094 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_return.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot be used as a static method return type +--FILE-- + { + public static function foo(): T {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_method_variadic.phpt b/Zend/tests/generics/errors/type_param_in_static_method_variadic.phpt new file mode 100644 index 000000000000..ea2297380515 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_method_variadic.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot be used in a variadic static method parameter +--FILE-- + { + public static function foo(T ...$xs): void {} +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_property.phpt b/Zend/tests/generics/errors/type_param_in_static_property.phpt new file mode 100644 index 000000000000..55429fe1de8c --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_property.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: class type parameter cannot be used in a static property type +--FILE-- + { + public static null|T $a = null; +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_property_in_trait.phpt b/Zend/tests/generics/errors/type_param_in_static_property_in_trait.phpt new file mode 100644 index 000000000000..ba1ba26c80c3 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_property_in_trait.phpt @@ -0,0 +1,10 @@ +--TEST-- +Errors: trait type parameter cannot be used as a static property type +--FILE-- + { + public static null|T $slot = null; +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to Bag and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/errors/type_param_in_static_property_nested.phpt b/Zend/tests/generics/errors/type_param_in_static_property_nested.phpt new file mode 100644 index 000000000000..a0bfbc78dd30 --- /dev/null +++ b/Zend/tests/generics/errors/type_param_in_static_property_nested.phpt @@ -0,0 +1,14 @@ +--TEST-- +Errors: class type parameter cannot be nested inside a generic type on a static property +--FILE-- + { + public function __construct(public U $value) {} +} + +class A { + public static ?Container $box = null; +} +?> +--EXPECTF-- +Fatal error: Type parameter T is bound to A and cannot be used in static context in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/extends_no_args_required.phpt b/Zend/tests/generics/inheritance/arity/extends_no_args_required.phpt new file mode 100644 index 000000000000..5e7e4c88737d --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/extends_no_args_required.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: extends without args, parent has required type parameter, is a compile error +--FILE-- + {} +class Bad extends Box {} +?> +--EXPECTF-- +Fatal error: Too few generic type arguments to extends Box in Bad, 0 passed and exactly 1 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/extends_non_generic.phpt b/Zend/tests/generics/inheritance/arity/extends_non_generic.phpt new file mode 100644 index 000000000000..79b2bfa12def --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/extends_non_generic.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: extends a non-generic class with type arguments is a compile error +--FILE-- + {} +?> +--EXPECTF-- +Fatal error: Type arguments are not allowed on non-generic class Plain in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/extends_over_default_max.phpt b/Zend/tests/generics/inheritance/arity/extends_over_default_max.phpt new file mode 100644 index 000000000000..ed07eb160fbf --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/extends_over_default_max.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: extends Pair with 3 args is a compile error +--FILE-- + {} +class Bad extends Pair {} +?> +--EXPECTF-- +Fatal error: Too many generic type arguments to extends Pair in Bad, 3 passed and at most 2 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/extends_too_few.phpt b/Zend/tests/generics/inheritance/arity/extends_too_few.phpt new file mode 100644 index 000000000000..ca15febd2da7 --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/extends_too_few.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: extends with too few type arguments is a compile error +--FILE-- + {} +class Bad extends Pair {} +?> +--EXPECTF-- +Fatal error: Too few generic type arguments to extends Pair in Bad, 1 passed and exactly 2 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/extends_too_many.phpt b/Zend/tests/generics/inheritance/arity/extends_too_many.phpt new file mode 100644 index 000000000000..d8e7cdc124ba --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/extends_too_many.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: extends with too many type arguments is a compile error +--FILE-- + {} +class Bad extends Box {} +?> +--EXPECTF-- +Fatal error: Too many generic type arguments to extends Box in Bad, 2 passed and exactly 1 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/implements_no_args_required.phpt b/Zend/tests/generics/inheritance/arity/implements_no_args_required.phpt new file mode 100644 index 000000000000..49ef6bdcffb2 --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/implements_no_args_required.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: implements without args, interface has required type parameter, is a compile error +--FILE-- + {} +class Bad implements I {} +?> +--EXPECTF-- +Fatal error: Too few generic type arguments to implements I in Bad, 0 passed and exactly 2 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/implements_too_few.phpt b/Zend/tests/generics/inheritance/arity/implements_too_few.phpt new file mode 100644 index 000000000000..1902c7df1a99 --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/implements_too_few.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: implements with too few type arguments is a compile error +--FILE-- + {} +class Bad implements Map {} +?> +--EXPECTF-- +Fatal error: Too few generic type arguments to implements Map in Bad, 1 passed and exactly 2 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/interface_extends_arity.phpt b/Zend/tests/generics/inheritance/arity/interface_extends_arity.phpt new file mode 100644 index 000000000000..1ebd7e7586e1 --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/interface_extends_arity.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: interface extends another interface with wrong arity is a compile error +--FILE-- + {} +interface IExt extends J {} +?> +--EXPECTF-- +Fatal error: Too many generic type arguments to extends J in IExt, 2 passed and exactly 1 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/no_args_with_defaults.phpt b/Zend/tests/generics/inheritance/arity/no_args_with_defaults.phpt new file mode 100644 index 000000000000..3c0019575e98 --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/no_args_with_defaults.phpt @@ -0,0 +1,16 @@ +--TEST-- +Inheritance arity: no args is OK when all type parameters have defaults +--FILE-- + {} +interface I {} +trait Holder { public T $v; } + +class A extends Box {} +class B implements I {} +class C { use Holder; } + +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/arity/use_trait_no_args_required.phpt b/Zend/tests/generics/inheritance/arity/use_trait_no_args_required.phpt new file mode 100644 index 000000000000..dbaed739f0cf --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/use_trait_no_args_required.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: use Trait without args, trait has required type parameter, is a compile error +--FILE-- + { public T $val; } +class Bad { use Holder; } +?> +--EXPECTF-- +Fatal error: Too few generic type arguments to use Holder in Bad, 0 passed and exactly 1 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/use_trait_too_many.phpt b/Zend/tests/generics/inheritance/arity/use_trait_too_many.phpt new file mode 100644 index 000000000000..1c9f085a4074 --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/use_trait_too_many.phpt @@ -0,0 +1,9 @@ +--TEST-- +Inheritance arity: use trait with too many type arguments is a compile error +--FILE-- + { public T $v; } +class Bad { use Holder; } +?> +--EXPECTF-- +Fatal error: Too many generic type arguments to use Holder in Bad, 2 passed and exactly 1 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/arity/with_defaults.phpt b/Zend/tests/generics/inheritance/arity/with_defaults.phpt new file mode 100644 index 000000000000..7420fbe70c36 --- /dev/null +++ b/Zend/tests/generics/inheritance/arity/with_defaults.phpt @@ -0,0 +1,19 @@ +--TEST-- +Inheritance arity: defaults extend the accepted range +--FILE-- + {} +interface Maybe {} +trait Slot {} + +// Required-only arity +class P1 extends Pair {} +// Including the optional +class P2 extends Pair {} +// Trait with default — works without args +class T1 { use Slot; } + +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/bounds/bound_on_bound_pass.phpt b/Zend/tests/generics/inheritance/bounds/bound_on_bound_pass.phpt new file mode 100644 index 000000000000..260e17395710 --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/bound_on_bound_pass.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bound check: forwarded T-ref where child's bound is at least as tight as parent's +--FILE-- + {} +interface B extends A {} +interface C extends A {} + +class IntBox {} +class IntSubBox extends IntBox {} + +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/bounds/bound_on_bound_too_loose.phpt b/Zend/tests/generics/inheritance/bounds/bound_on_bound_too_loose.phpt new file mode 100644 index 000000000000..714911b933fa --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/bound_on_bound_too_loose.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bound check: forwarded T-ref where child's bound is looser than parent's is rejected +--FILE-- + {} +interface B extends A {} +?> +--EXPECTF-- +Fatal error: Type argument 1 to extends A in B does not satisfy the bound Dog on parameter T, Y given in %s on line %d diff --git a/Zend/tests/generics/inheritance/bounds/bound_on_bound_unbounded_arg.phpt b/Zend/tests/generics/inheritance/bounds/bound_on_bound_unbounded_arg.phpt new file mode 100644 index 000000000000..be93b443b778 --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/bound_on_bound_unbounded_arg.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bound check: forwarded T-ref where child has no bound is rejected when parent requires one +--FILE-- + {} +interface B extends A {} +?> +--EXPECTF-- +Fatal error: Type argument 1 to extends A in B does not satisfy the bound Animal on parameter T, W given in %s on line %d diff --git a/Zend/tests/generics/inheritance/bounds/error_renders_args.phpt b/Zend/tests/generics/inheritance/bounds/error_renders_args.phpt new file mode 100644 index 000000000000..dd539770f094 --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/error_renders_args.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bound error message: link-time bound violation renders NAMED_WITH_ARGS with its type arguments +--FILE-- + {} + +interface Bag> {} + +class IntBag implements Bag {} +?> +--EXPECTF-- +Fatal error: Type argument 1 to implements Bag in IntBag does not satisfy the bound Comparable on parameter T, int given in %s on line %d diff --git a/Zend/tests/generics/inheritance/bounds/extends_concrete_satisfies.phpt b/Zend/tests/generics/inheritance/bounds/extends_concrete_satisfies.phpt new file mode 100644 index 000000000000..aa1517ccc37f --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/extends_concrete_satisfies.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bound check: class extends with a concrete arg satisfying the parent bound +--FILE-- + {} + +class DogBox extends Box {} +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/bounds/extends_violates.phpt b/Zend/tests/generics/inheritance/bounds/extends_violates.phpt new file mode 100644 index 000000000000..568a47a0f779 --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/extends_violates.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bound check: class extends with a concrete arg violating the parent bound +--FILE-- + {} + +class IntBox extends Box {} +?> +--EXPECTF-- +Fatal error: Type argument 1 to extends Box in IntBox does not satisfy the bound Animal on parameter T, int given in %s on line %d diff --git a/Zend/tests/generics/inheritance/bounds/implements_violates.phpt b/Zend/tests/generics/inheritance/bounds/implements_violates.phpt new file mode 100644 index 000000000000..ce909c2fa42f --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/implements_violates.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bound check: implements with a concrete arg violating the interface bound +--FILE-- + {} + +class IntBag implements Bag {} +?> +--EXPECTF-- +Fatal error: Type argument 1 to implements Bag in IntBag does not satisfy the bound Animal on parameter T, int given in %s on line %d diff --git a/Zend/tests/generics/inheritance/bounds/interface_extends_interface_violates.phpt b/Zend/tests/generics/inheritance/bounds/interface_extends_interface_violates.phpt new file mode 100644 index 000000000000..34910ac0040d --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/interface_extends_interface_violates.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bound check: interface extends another generic interface with violating arg +--FILE-- + {} + +interface B extends A {} +?> +--EXPECTF-- +Fatal error: Type argument 1 to extends A in B does not satisfy the bound Animal on parameter T, int given in %s on line %d diff --git a/Zend/tests/generics/inheritance/bounds/use_trait_violates.phpt b/Zend/tests/generics/inheritance/bounds/use_trait_violates.phpt new file mode 100644 index 000000000000..9381fbcc40fd --- /dev/null +++ b/Zend/tests/generics/inheritance/bounds/use_trait_violates.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bound check: use trait with a concrete arg violating the trait bound +--FILE-- + { public T $val; } + +class IntHolder { use Holder; } +?> +--EXPECTF-- +Fatal error: Type argument 1 to use Holder in IntHolder does not satisfy the bound Animal on parameter T, int given in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/conflicting_parent_and_interface.phpt b/Zend/tests/generics/inheritance/diamond/conflicting_parent_and_interface.phpt new file mode 100644 index 000000000000..3f520348eb81 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/conflicting_parent_and_interface.phpt @@ -0,0 +1,14 @@ +--TEST-- +Diamond: parent and direct interface providing different bindings for the same invariant ancestor (class case is deferred to per-path LSP) +--FILE-- + {} +class P implements Box {} + +class C extends P implements Box {} +$c = new C(); +var_dump($c instanceof Box, $c instanceof P); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/conflicting_via_two_interfaces.phpt b/Zend/tests/generics/inheritance/diamond/conflicting_via_two_interfaces.phpt new file mode 100644 index 000000000000..219ae6c215a9 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/conflicting_via_two_interfaces.phpt @@ -0,0 +1,16 @@ +--TEST-- +Diamond: class implementing two interfaces that bind the same invariant ancestor (accepted, LSP per path validates any actual methods) +--FILE-- + {} +interface ABox extends Box {} +interface BBox extends Box {} + +class C implements ABox, BBox {} +$c = new C(); +var_dump($c instanceof Box, $c instanceof ABox, $c instanceof BBox); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/forwarding_t_consistent.phpt b/Zend/tests/generics/inheritance/diamond/forwarding_t_consistent.phpt new file mode 100644 index 000000000000..bc413328885c --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/forwarding_t_consistent.phpt @@ -0,0 +1,12 @@ +--TEST-- +Diamond: generic class forwarding the same T into two paths is accepted +--FILE-- + {} +interface Wrapper extends Box {} + +class C implements Wrapper, Box {} +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/diamond/forwarding_t_vs_concrete.phpt b/Zend/tests/generics/inheritance/diamond/forwarding_t_vs_concrete.phpt new file mode 100644 index 000000000000..f0887f4b7523 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/forwarding_t_vs_concrete.phpt @@ -0,0 +1,14 @@ +--TEST-- +Diamond: a generic class forwarding T conflicts with a concrete arg on another path (accepted for the class form, LSP catches actual signature mismatches) +--FILE-- + {} +interface Wrapper extends Box {} + +class C implements Wrapper, Box {} +$c = new C(); +var_dump($c instanceof Box, $c instanceof Wrapper); +?> +--EXPECT-- +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/interface_diamond_class_impl_covariant_missing.phpt b/Zend/tests/generics/inheritance/diamond/interface_diamond_class_impl_covariant_missing.phpt new file mode 100644 index 000000000000..00cefe61d12e --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/interface_diamond_class_impl_covariant_missing.phpt @@ -0,0 +1,17 @@ +--TEST-- +Diamond + variance: class implementing a covariant interface diamond must return the intersection +--FILE-- + { public function get(): X; } +interface Flex extends Getter, Getter {} + +class Bad implements Flex { + public function get(): JustFoo { return new JustFoo(); } +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::get(): JustFoo must be compatible with %s::get(): IFoo&IBar in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/interface_diamond_class_impl_missing.phpt b/Zend/tests/generics/inheritance/diamond/interface_diamond_class_impl_missing.phpt new file mode 100644 index 000000000000..cbd41974f4dd --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/interface_diamond_class_impl_missing.phpt @@ -0,0 +1,13 @@ +--TEST-- +Diamond + variance: class implementing an interface diamond must satisfy the merged signature +--FILE-- + { public function set(X $v): void; } +interface Flex extends Setter, Setter {} + +class Bad implements Flex { + public function set(int $v): void {} +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::set(int $v): void must be compatible with %s::set(string|int $v): void in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/interface_diamond_variance.phpt b/Zend/tests/generics/inheritance/diamond/interface_diamond_variance.phpt new file mode 100644 index 000000000000..4405f1b4a691 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/interface_diamond_variance.phpt @@ -0,0 +1,121 @@ +--TEST-- +Diamond + variance: an interface can itself diamond-inherit a generic ancestor +--FILE-- + { public function set(X $v): void; } +interface I1IntSink extends I1Setter {} +interface I1StrSink extends I1Setter {} +interface I1Flex extends I1IntSink, I1StrSink {} + +final class I1Impl implements I1Flex { + public function set(int|string $v): void { echo "I1: ", var_export($v, true), "\n"; } +} + +interface I2Setter<-X> { public function set(X $v): void; } +interface I2Flex extends I2Setter, I2Setter {} + +final class I2Impl implements I2Flex { + public function set(int|string $v): void { echo "I2: ", var_export($v, true), "\n"; } +} + +interface I3Setter<-X> { public function set(X $v): void; } +interface I3Flex extends I3Setter, I3Setter, I3Setter {} + +final class I3Impl implements I3Flex { + public function set(int|string|float $v): void { echo "I3: ", var_export($v, true), "\n"; } +} + +interface I4Getter<+X : object> { public function get(): X; } +interface I4FooSrc extends I4Getter {} +interface I4BarSrc extends I4Getter {} +interface I4Flex extends I4FooSrc, I4BarSrc {} + +final class I4Impl implements I4Flex { + public function get(): IFoo&IBar { return new FooBar(); } +} + +interface I5Getter<+X : object> { public function get(): X; } +interface I5Flex extends I5Getter, I5Getter, I5Getter {} + +final class I5Impl implements I5Flex { + public function get(): IFoo&IBar&IBaz { return new FooBarBaz(); } +} + +interface I6IO<+X : object, -Y> { + public function get(): X; + public function set(Y $v): void; +} +interface I6Flex extends I6IO, I6IO {} + +final class I6Impl implements I6Flex { + public function get(): IFoo&IBar { return new FooBar(); } + public function set(int|string $v): void { echo "I6.set: ", var_export($v, true), "\n"; } +} + +interface I7Setter<-X> { public function set(X $v): void; } +interface I7L1A extends I7Setter {} +interface I7L2A extends I7L1A {} +interface I7L1B extends I7Setter {} +interface I7L2B extends I7L1B {} +interface I7Flex extends I7L2A, I7L2B {} + +final class I7Impl implements I7Flex { + public function set(int|string $v): void { echo "I7: ", var_export($v, true), "\n"; } +} + +interface I8Setter<-X> { public function set(X $v): void; } +interface I8Flex extends I8Setter, I8Setter {} + +final class I8Impl implements I8Flex { + public function set(mixed $v): void { echo "I8: ", var_export($v, true), "\n"; } +} + +interface I9Getter<+X : object> { public function get(): X; } +interface I9Flex extends I9Getter, I9Getter {} + +final class I9Impl implements I9Flex { + public function get(): FooBar { return new FooBar(); } +} + +(new I1Impl)->set(7); (new I1Impl)->set("hi"); +(new I2Impl)->set(7); (new I2Impl)->set("hi"); +(new I3Impl)->set(7); (new I3Impl)->set("hi"); (new I3Impl)->set(3.14); +var_dump((new I4Impl)->get() instanceof IFoo, (new I4Impl)->get() instanceof IBar); +var_dump((new I5Impl)->get() instanceof IFoo, (new I5Impl)->get() instanceof IBar, (new I5Impl)->get() instanceof IBaz); +$i6 = new I6Impl; var_dump($i6->get() instanceof FooBar); $i6->set(1); $i6->set("x"); +(new I7Impl)->set(7); (new I7Impl)->set("hi"); +(new I8Impl)->set(7); (new I8Impl)->set("hi"); (new I8Impl)->set(3.14); +var_dump((new I9Impl)->get() instanceof FooBar); + +echo "done\n"; +?> +--EXPECT-- +I1: 7 +I1: 'hi' +I2: 7 +I2: 'hi' +I3: 7 +I3: 'hi' +I3: 3.14 +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +I6.set: 1 +I6.set: 'x' +I7: 7 +I7: 'hi' +I8: 7 +I8: 'hi' +I8: 3.14 +bool(true) +done diff --git a/Zend/tests/generics/inheritance/diamond/interface_diamond_variance_invariant_rejected.phpt b/Zend/tests/generics/inheritance/diamond/interface_diamond_variance_invariant_rejected.phpt new file mode 100644 index 000000000000..e4a76aed950f --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/interface_diamond_variance_invariant_rejected.phpt @@ -0,0 +1,10 @@ +--TEST-- +Diamond + variance: invariant T interface diamond merges via use-site variance +--FILE-- + {} +interface FlexBox extends Box, Box {} +echo (new ReflectionClass(FlexBox::class))->getMethods() === [] ? "ok\n" : "unexpected\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/inheritance/diamond/invariant_class_diamond_bad_impl_rejected.phpt b/Zend/tests/generics/inheritance/diamond/invariant_class_diamond_bad_impl_rejected.phpt new file mode 100644 index 000000000000..0377755a4911 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/invariant_class_diamond_bad_impl_rejected.phpt @@ -0,0 +1,20 @@ +--TEST-- +Diamond + invariant T: bad concrete implementer is rejected by per-path LSP +--FILE-- + { + public function tap(T $object): T; +} + +interface FooTapper extends Tapper {} +interface BarTapper extends Tapper {} + +class Bad implements FooTapper, BarTapper { + public function tap(IFoo $object): IFoo { return $object; } +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::tap(IFoo $object): IFoo must be compatible with Tapper::tap(IBar $object): IBar in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/invariant_class_diamond_with_use_site_variance.phpt b/Zend/tests/generics/inheritance/diamond/invariant_class_diamond_with_use_site_variance.phpt new file mode 100644 index 000000000000..65176762e366 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/invariant_class_diamond_with_use_site_variance.phpt @@ -0,0 +1,34 @@ +--TEST-- +Diamond + invariant T: a concrete class can satisfy multiple bindings via use-site variance (param union, return intersection) +--FILE-- + { + public function tap(T $object): T; +} + +interface FooTapper extends Tapper {} +interface BarTapper extends Tapper {} + +final class FooBarTapper implements FooTapper, BarTapper, Tapper { + public function tap(IFoo | IBar $object): IFoo & IBar { + if ($object instanceof IFoo && $object instanceof IBar) { + return $object; + } + return new FooBar(); + } +} + +$t = new FooBarTapper(); +var_dump($t->tap(new FooBar()) instanceof FooBar); +var_dump($t instanceof FooTapper, $t instanceof BarTapper, $t instanceof Tapper); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_bad_impl_rejected.phpt b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_bad_impl_rejected.phpt new file mode 100644 index 000000000000..c7d735bcdd2a --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_bad_impl_rejected.phpt @@ -0,0 +1,19 @@ +--TEST-- +Diamond + invariant T: class missing a path of the use-site-merged interface contract is rejected +--FILE-- + { + public function tap(T $object): T; +} + +interface FlexTapper extends Tapper, Tapper {} + +class Bad implements FlexTapper { + public function tap(IFoo $o): IFoo { return $o; } +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::tap(IFoo $o): IFoo must be compatible with %s::tap(IFoo|IBar $object): IFoo&IBar in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_class_impl.phpt b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_class_impl.phpt new file mode 100644 index 000000000000..95fa0870079c --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_class_impl.phpt @@ -0,0 +1,31 @@ +--TEST-- +Diamond + invariant T: class implementing a use-site-merged interface diamond +--FILE-- + { + public function tap(T $object): T; +} + +interface FlexTapper extends Tapper, Tapper {} + +class Concrete implements FlexTapper { + public function tap(IFoo|IBar $o): IFoo&IBar { + if ($o instanceof IFoo && $o instanceof IBar) { + return $o; + } + return new FooBar(); + } +} + +$c = new Concrete(); +var_dump($c->tap(new FooBar()) instanceof FooBar); +var_dump($c instanceof FlexTapper, $c instanceof Tapper); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_merge.phpt b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_merge.phpt new file mode 100644 index 000000000000..ace90e13e289 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_merge.phpt @@ -0,0 +1,32 @@ +--TEST-- +Diamond + invariant T: interface diamond synthesises use-site-merged abstract contract +--FILE-- + { + public function tap(T $object): T; +} + +interface FooTapper extends Tapper {} +interface BarTapper extends Tapper {} + +interface FlexTapper extends FooTapper, BarTapper {} + +$r = new ReflectionClass(FlexTapper::class); +$m = $r->getMethod('tap'); +echo "param: ", (string)$m->getParameters()[0]->getType(), "\n"; +echo "return: ", (string)$m->getReturnType(), "\n"; + +interface FlexDirect extends Tapper, Tapper {} +$rd = new ReflectionClass(FlexDirect::class); +$md = $rd->getMethod('tap'); +echo "direct param: ", (string)$md->getParameters()[0]->getType(), "\n"; +echo "direct return: ", (string)$md->getReturnType(), "\n"; +?> +--EXPECT-- +param: IFoo|IBar +return: IFoo&IBar +direct param: IFoo|IBar +direct return: IFoo&IBar diff --git a/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_still_rejected.phpt b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_still_rejected.phpt new file mode 100644 index 000000000000..61476796c8a7 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/invariant_interface_diamond_still_rejected.phpt @@ -0,0 +1,10 @@ +--TEST-- +Diamond + invariant T: arity mismatch is the one remaining rejection at the diamond stage +--FILE-- + {} +interface Alpha extends Multi {} +interface Beta extends Multi {} +?> +--EXPECTF-- +Fatal error: Too many generic type arguments to extends Multi in Beta, 3 passed and exactly 2 expected in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/invariant_tapper_class_diamond.phpt b/Zend/tests/generics/inheritance/diamond/invariant_tapper_class_diamond.phpt new file mode 100644 index 000000000000..184f75bf62f5 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/invariant_tapper_class_diamond.phpt @@ -0,0 +1,52 @@ +--TEST-- +Diamond + invariant T: Tapper with T in both parameter and return positions, concrete class satisfies all paths via use-site variance +--FILE-- + { + public function tap(T $object): T; +} + +interface FooTapper extends Tapper {} +interface BarTapper extends Tapper {} + +class FooBarTapper implements FooTapper, BarTapper, Tapper { + public function tap(IFoo | IBar $object): IFoo & IBar { + if ($object instanceof IFoo) { + if ($object instanceof IBar) { + return $object; + } + + return new FooBar(); + } else { + return new FooBar(); + } + } +} + +$tapper = new FooBarTapper; +$a = $tapper->tap(new Foo()); +$b = $tapper->tap(new Bar()); +$c = $tapper->tap(new FooBar()); + +assert($a instanceof IFoo); +assert($a instanceof IBar); + +assert($b instanceof IFoo); +assert($b instanceof IBar); + +assert($c instanceof IFoo); +assert($c instanceof IBar); + +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/inheritance/diamond/matching_args_via_two_paths.phpt b/Zend/tests/generics/inheritance/diamond/matching_args_via_two_paths.phpt new file mode 100644 index 000000000000..189699e23766 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/matching_args_via_two_paths.phpt @@ -0,0 +1,13 @@ +--TEST-- +Diamond: same args via two paths is accepted +--FILE-- + {} +interface ABox extends Box {} +interface BBox extends Box {} + +class C implements ABox, BBox {} +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/diamond/nullable_intersection_merge.phpt b/Zend/tests/generics/inheritance/diamond/nullable_intersection_merge.phpt new file mode 100644 index 000000000000..ad7533afba24 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/nullable_intersection_merge.phpt @@ -0,0 +1,28 @@ +--TEST-- +Diamond + nullable: covariant intersection allows null only when every path does +--FILE-- + { public function get(): ?X; } + +interface Flex extends Getter, Getter {} +$r = new ReflectionClass(Flex::class); +echo "merged: ", (string)$r->getMethod('get')->getReturnType(), "\n"; + +class Good1 implements Flex { + public function get(): (IFoo&IBar)|null { return null; } +} + +class Good2 implements Flex { + public function get(): IFoo&IBar { return new FooBar(); } +} + +var_dump((new Good1())->get(), (new Good2())->get() instanceof FooBar); +?> +--EXPECT-- +merged: IFoo&IBar|null +NULL +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/nullable_intersection_missing_branch_rejected.phpt b/Zend/tests/generics/inheritance/diamond/nullable_intersection_missing_branch_rejected.phpt new file mode 100644 index 000000000000..b16a59c7ee28 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/nullable_intersection_missing_branch_rejected.phpt @@ -0,0 +1,16 @@ +--TEST-- +Diamond + nullable intersection: implementer missing one branch is rejected +--FILE-- + { public function get(): ?X; } +interface Flex extends Getter, Getter {} + +class Bad implements Flex { + public function get(): ?IFoo { return null; } +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::get(): ?IFoo must be compatible with Getter::get(): IFoo&IBar|null in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/nullable_union_merge.phpt b/Zend/tests/generics/inheritance/diamond/nullable_union_merge.phpt new file mode 100644 index 000000000000..157df44803ae --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/nullable_union_merge.phpt @@ -0,0 +1,18 @@ +--TEST-- +Diamond + nullable: contravariant union propagates null from any operand +--FILE-- + { public function set(X $v): void; } + +interface Flex extends Setter, Setter {} +$r = new ReflectionClass(Flex::class); +echo "merged: ", (string)$r->getMethod('set')->getParameters()[0]->getType(), "\n"; + +class Good implements Flex { + public function set(int|string|null $v): void {} +} +echo "good ok\n"; +?> +--EXPECT-- +merged: string|int|null +good ok diff --git a/Zend/tests/generics/inheritance/diamond/nullable_union_missing_null_rejected.phpt b/Zend/tests/generics/inheritance/diamond/nullable_union_missing_null_rejected.phpt new file mode 100644 index 000000000000..958b48a633c7 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/nullable_union_missing_null_rejected.phpt @@ -0,0 +1,13 @@ +--TEST-- +Diamond + nullable union: implementer missing null in param is rejected +--FILE-- + { public function set(X $v): void; } +interface Flex extends Setter, Setter {} + +class Bad implements Flex { + public function set(int|string $v): void {} +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::set(string|int $v): void must be compatible with Setter::set(string|int|null $v): void in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/parent_supplies_interface_matches.phpt b/Zend/tests/generics/inheritance/diamond/parent_supplies_interface_matches.phpt new file mode 100644 index 000000000000..94f575d47011 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/parent_supplies_interface_matches.phpt @@ -0,0 +1,12 @@ +--TEST-- +Diamond: parent's transitive binding matches a direct interface binding +--FILE-- + {} +class P implements Box {} + +class C extends P implements Box {} +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/diamond/property_hook_get_only_diamond.phpt b/Zend/tests/generics/inheritance/diamond/property_hook_get_only_diamond.phpt new file mode 100644 index 000000000000..ddef3637f995 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/property_hook_get_only_diamond.phpt @@ -0,0 +1,32 @@ +--TEST-- +Diamond + property hook (get-only): covariant T merges return type as intersection +--FILE-- + { + public T $x { get; } +} +interface IFoo {} +interface IBar {} +class FooBar implements IFoo, IBar {} + +interface FlexX extends HasX, HasX {} + +$r = new ReflectionClass(FlexX::class); +$prop = $r->getProperty('x'); +$hooks = $prop->getHooks(); +foreach ($hooks as $kind => $hook) { + if ($hook->hasReturnType()) { + echo "hook $kind return: ", (string)$hook->getReturnType(), "\n"; + } +} + +class C implements FlexX { + public IFoo&IBar $x { get => new FooBar(); } +} +$c = new C; +var_dump($c->x instanceof IFoo, $c->x instanceof IBar); +?> +--EXPECT-- +hook get return: IFoo&IBar +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/property_hook_get_only_diamond_bad.phpt b/Zend/tests/generics/inheritance/diamond/property_hook_get_only_diamond_bad.phpt new file mode 100644 index 000000000000..81cb4736a929 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/property_hook_get_only_diamond_bad.phpt @@ -0,0 +1,18 @@ +--TEST-- +Diamond + property hook (get-only): impl missing one branch of the merged intersection is rejected +--FILE-- + { + public T $x { get; } +} +interface IFoo {} +interface IBar {} + +interface FlexX extends HasX, HasX {} + +class Bad implements FlexX { + public IFoo $x { get => new class implements IFoo {}; } +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::$x::get(): IFoo must be compatible with HasX::$x::get(): IFoo&IBar in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/reflection_merged_signatures.phpt b/Zend/tests/generics/inheritance/diamond/reflection_merged_signatures.phpt new file mode 100644 index 000000000000..11b81a469813 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/reflection_merged_signatures.phpt @@ -0,0 +1,50 @@ +--TEST-- +Reflection: merged diamond signatures are visible through ReflectionMethod / ReflectionType +--FILE-- + { + public function tap(T $o): T; +} + +interface FlexTapper extends Tapper, Tapper {} + +class C implements FlexTapper { + public function tap(IFoo|IBar $o): IFoo&IBar { + if ($o instanceof IFoo && $o instanceof IBar) { + return $o; + } + return new FooBar(); + } +} + +$flex = (new ReflectionClass(FlexTapper::class))->getMethod('tap'); +echo "FlexTapper::tap return = ", (string)$flex->getReturnType(), "\n"; +echo "FlexTapper::tap param = ", (string)$flex->getParameters()[0]->getType(), "\n"; +echo "FlexTapper::tap return is intersection: ", + ($flex->getReturnType() instanceof ReflectionIntersectionType ? "yes" : "no"), "\n"; +echo "FlexTapper::tap param is union: ", + ($flex->getParameters()[0]->getType() instanceof ReflectionUnionType ? "yes" : "no"), "\n"; + +$c = (new ReflectionClass(C::class))->getMethod('tap'); +echo "C::tap return = ", (string)$c->getReturnType(), "\n"; +echo "C::tap param = ", (string)$c->getParameters()[0]->getType(), "\n"; +echo "C::tap prototype declaring class = ", $c->getPrototype()->getDeclaringClass()->getName(), "\n"; + +$base = (new ReflectionClass(Tapper::class))->getMethod('tap'); +echo "Tapper::tap return = ", (string)$base->getReturnType(), "\n"; +echo "Tapper::tap param = ", (string)$base->getParameters()[0]->getType(), "\n"; +?> +--EXPECT-- +FlexTapper::tap return = IFoo&IBar +FlexTapper::tap param = IFoo|IBar +FlexTapper::tap return is intersection: yes +FlexTapper::tap param is union: yes +C::tap return = IFoo&IBar +C::tap param = IFoo|IBar +C::tap prototype declaring class = Tapper +Tapper::tap return = object +Tapper::tap param = object diff --git a/Zend/tests/generics/inheritance/diamond/scalar_intersection_class_diamond_rejected.phpt b/Zend/tests/generics/inheritance/diamond/scalar_intersection_class_diamond_rejected.phpt new file mode 100644 index 000000000000..35a6ea166b58 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/scalar_intersection_class_diamond_rejected.phpt @@ -0,0 +1,16 @@ +--TEST-- +Diamond + invariant T: a class double-implementing with scalar bindings is caught by per-path LSP +--FILE-- + { + public function get(): T; +} +interface IntBox extends Box {} +interface StrBox extends Box {} + +class C implements IntBox, StrBox { + public function get() { return 0; } +} +?> +--EXPECTF-- +Fatal error: Declaration of C::get() must be compatible with Box::get(): int in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/scalar_intersection_covariant_rejected.phpt b/Zend/tests/generics/inheritance/diamond/scalar_intersection_covariant_rejected.phpt new file mode 100644 index 000000000000..b166332cdd6f --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/scalar_intersection_covariant_rejected.phpt @@ -0,0 +1,14 @@ +--TEST-- +Diamond + covariant +T: scalar bindings in a covariant return position are rejected +--FILE-- + { + public function make(): T; +} +interface IntProducer extends Producer {} +interface StrProducer extends Producer {} + +interface FlexProducer extends IntProducer, StrProducer {} +?> +--EXPECTF-- +Fatal error: Diamond inheritance of Producer::make() in FlexProducer would require return type int&string, which is uninhabited; constrain the type parameter with an object bound in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/scalar_intersection_invariant_use_site_rejected.phpt b/Zend/tests/generics/inheritance/diamond/scalar_intersection_invariant_use_site_rejected.phpt new file mode 100644 index 000000000000..ae752a8bd4b6 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/scalar_intersection_invariant_use_site_rejected.phpt @@ -0,0 +1,14 @@ +--TEST-- +Diamond + invariant T: scalar bindings at a use-site covariant return are rejected +--FILE-- + { + public function get(): T; +} +interface IntBox extends Box {} +interface StrBox extends Box {} + +interface FlexBox extends IntBox, StrBox {} +?> +--EXPECTF-- +Fatal error: Diamond inheritance of Box::get() in FlexBox would require return type int&string, which is uninhabited; constrain the type parameter with an object bound in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/scalar_intersection_trait_rejected.phpt b/Zend/tests/generics/inheritance/diamond/scalar_intersection_trait_rejected.phpt new file mode 100644 index 000000000000..0fc3de93172d --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/scalar_intersection_trait_rejected.phpt @@ -0,0 +1,14 @@ +--TEST-- +Diamond + trait-use: scalar bindings at a covariant return position are rejected +--FILE-- + { + public function make(): T { throw new Error('stub'); } +} + +class C { + use Producer, Producer; +} +?> +--EXPECTF-- +Fatal error: Diamond inheritance of Producer::make() in C would require return type int&string, which is uninhabited; constrain the type parameter with an object bound in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/scalar_union_param_accepted.phpt b/Zend/tests/generics/inheritance/diamond/scalar_union_param_accepted.phpt new file mode 100644 index 000000000000..91e8210c4e68 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/scalar_union_param_accepted.phpt @@ -0,0 +1,17 @@ +--TEST-- +Diamond + contravariant -T: scalar bindings at a parameter position merge as a union (no rejection) +--FILE-- + { + public function sink(T $v): void; +} +interface IntSink extends Sink {} +interface StrSink extends Sink {} + +interface FlexSink extends IntSink, StrSink {} + +$r = new ReflectionClass(FlexSink::class); +echo (string)$r->getMethod('sink')->getParameters()[0]->getType(), "\n"; +?> +--EXPECT-- +string|int diff --git a/Zend/tests/generics/inheritance/diamond/trait_diamond_compiles.phpt b/Zend/tests/generics/inheritance/diamond/trait_diamond_compiles.phpt new file mode 100644 index 000000000000..cef8ac7736fd --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/trait_diamond_compiles.phpt @@ -0,0 +1,26 @@ +--TEST-- +Diamond + trait-use: multiple uses of the same generic trait with different bindings merge use-site-variantly at the reflection level +--FILE-- + { + public function set(X $v): void { echo var_export($v, true), "\n"; } +} + +class C { + use Setter, Setter; +} + +$r = new ReflectionClass(C::class); +$type = $r->getMethod('set')->getParameters()[0]->getType(); +echo "param: ", (string)$type, "\n"; +echo "is union: ", ($type instanceof ReflectionUnionType ? "yes" : "no"), "\n"; + +$c = new C(); +$c->set(1); +$c->set("hello"); +?> +--EXPECT-- +param: string|int +is union: yes +1 +'hello' diff --git a/Zend/tests/generics/inheritance/diamond/trait_diamond_covariant.phpt b/Zend/tests/generics/inheritance/diamond/trait_diamond_covariant.phpt new file mode 100644 index 000000000000..f0f7645e0d28 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/trait_diamond_covariant.phpt @@ -0,0 +1,29 @@ +--TEST-- +Diamond + trait-use: covariant return merges as intersection +--FILE-- + { + public function get(): X { return new FooBar(); } +} + +class C { + use HasGetter, HasGetter; +} + +$r = new ReflectionClass(C::class); +$type = $r->getMethod('get')->getReturnType(); +echo "return: ", (string)$type, "\n"; +echo "is intersection: ", ($type instanceof ReflectionIntersectionType ? "yes" : "no"), "\n"; + +$c = new C(); +var_dump($c->get() instanceof IFoo, $c->get() instanceof IBar); +?> +--EXPECT-- +return: IFoo&IBar +is intersection: yes +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/trait_diamond_invariant_use_site.phpt b/Zend/tests/generics/inheritance/diamond/trait_diamond_invariant_use_site.phpt new file mode 100644 index 000000000000..dfc0f7b12403 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/trait_diamond_invariant_use_site.phpt @@ -0,0 +1,32 @@ +--TEST-- +Diamond + trait-use: invariant T (no marker) with T in both positions merges use-site +--FILE-- + { + public function pipe(T $x): T { return $x; } +} + +interface IFoo {} +interface IBar {} +class FooBar implements IFoo, IBar {} + +class C { + use Pipe, Pipe; +} + +$r = new ReflectionClass(C::class); +$m = $r->getMethod('pipe'); +echo "param: ", (string)$m->getParameters()[0]->getType(), "\n"; +echo "return: ", (string)$m->getReturnType(), "\n"; +echo "param is union: ", ($m->getParameters()[0]->getType() instanceof ReflectionUnionType ? "yes" : "no"), "\n"; +echo "return is intersection: ", ($m->getReturnType() instanceof ReflectionIntersectionType ? "yes" : "no"), "\n"; + +$c = new C(); +var_dump($c->pipe(new FooBar()) instanceof FooBar); +?> +--EXPECT-- +param: IFoo|IBar +return: IFoo&IBar +param is union: yes +return is intersection: yes +bool(true) diff --git a/Zend/tests/generics/inheritance/diamond/trait_diamond_mixed_methods.phpt b/Zend/tests/generics/inheritance/diamond/trait_diamond_mixed_methods.phpt new file mode 100644 index 000000000000..57e6dc64b11f --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/trait_diamond_mixed_methods.phpt @@ -0,0 +1,28 @@ +--TEST-- +Diamond + trait-use: only T-touching methods are merged; non-generic methods are unaffected +--FILE-- + { + public function set(X $v): void { echo "set ", var_export($v, true), "\n"; } + public function ping(): string { return "pong"; } +} + +class C { + use Box, Box; +} + +$r = new ReflectionClass(C::class); +echo "set param: ", (string)$r->getMethod('set')->getParameters()[0]->getType(), "\n"; +echo "ping return: ", (string)$r->getMethod('ping')->getReturnType(), "\n"; + +$c = new C; +$c->set(1); +$c->set("hi"); +echo $c->ping(), "\n"; +?> +--EXPECT-- +set param: string|int +ping return: string +set 1 +set 'hi' +pong diff --git a/Zend/tests/generics/inheritance/diamond/trait_diamond_multi_param_mixed.phpt b/Zend/tests/generics/inheritance/diamond/trait_diamond_multi_param_mixed.phpt new file mode 100644 index 000000000000..319c10de75ba --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/trait_diamond_multi_param_mixed.phpt @@ -0,0 +1,35 @@ +--TEST-- +Diamond + trait-use: multi-param mixed +T / -U, declared variance drives merge polarity +--FILE-- + { + public function get(): T { throw new Error('stub'); } + public function set(U $v): void { echo var_export($v, true), "\n"; } +} + +class C { + use IO, IO; + + public function get(): IFoo&IBar { return new FooBar(); } + public function set(int|string $v): void { echo "set: ", var_export($v, true), "\n"; } +} + +$r = new ReflectionClass(C::class); +echo "get return: ", (string)$r->getMethod('get')->getReturnType(), "\n"; +echo "set param: ", (string)$r->getMethod('set')->getParameters()[0]->getType(), "\n"; + +$c = new C(); +var_dump($c->get() instanceof FooBar); +$c->set(7); +$c->set("hi"); +?> +--EXPECT-- +get return: IFoo&IBar +set param: string|int +bool(true) +set: 7 +set: 'hi' diff --git a/Zend/tests/generics/inheritance/diamond/trait_diamond_three_uses.phpt b/Zend/tests/generics/inheritance/diamond/trait_diamond_three_uses.phpt new file mode 100644 index 000000000000..cd7ef2f08aab --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/trait_diamond_three_uses.phpt @@ -0,0 +1,26 @@ +--TEST-- +Diamond + trait-use: three uses of the same generic trait fold pairwise into one merged contract +--FILE-- + { + public function sink(X $v): void { echo var_export($v, true), "\n"; } +} + +class C { + use Sink, Sink, Sink; +} + +$r = new ReflectionClass(C::class); +$type = $r->getMethod('sink')->getParameters()[0]->getType(); +echo "param: ", (string)$type, "\n"; + +$c = new C; +$c->sink(1); +$c->sink("x"); +$c->sink(3.14); +?> +--EXPECT-- +param: string|int|float +1 +'x' +3.14 diff --git a/Zend/tests/generics/inheritance/diamond/trait_diamond_variadic.phpt b/Zend/tests/generics/inheritance/diamond/trait_diamond_variadic.phpt new file mode 100644 index 000000000000..df7fde63aa83 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/trait_diamond_variadic.phpt @@ -0,0 +1,28 @@ +--TEST-- +Diamond + trait-use: variadic contravariant param merges as union +--FILE-- + { + public function sink(X ...$xs): void { + foreach ($xs as $x) echo var_export($x, true), "\n"; + } +} + +class C { + use Sink, Sink; +} + +$r = new ReflectionClass(C::class); +$type = $r->getMethod('sink')->getParameters()[0]->getType(); +echo "param: ", (string)$type, "\n"; +echo "is union: ", ($type instanceof ReflectionUnionType ? "yes" : "no"), "\n"; + +(new C)->sink(1, "x", 2, "y"); +?> +--EXPECT-- +param: string|int +is union: yes +1 +'x' +2 +'y' diff --git a/Zend/tests/generics/inheritance/diamond/variadic_bad_impl_rejected.phpt b/Zend/tests/generics/inheritance/diamond/variadic_bad_impl_rejected.phpt new file mode 100644 index 000000000000..64bdeaab7a66 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/variadic_bad_impl_rejected.phpt @@ -0,0 +1,11 @@ +--TEST-- +Diamond + variadic: bad impl rejected by LSP with correctly substituted error message +--FILE-- + { public function sink(X ...$xs): void; } +class Bad implements Sink, Sink { + public function sink(int ...$xs): void {} +} +?> +--EXPECTF-- +Fatal error: Declaration of Bad::sink(int ...$xs): void must be compatible with Sink::sink(string ...$xs): void in %s on line %d diff --git a/Zend/tests/generics/inheritance/diamond/variadic_contravariant_diamond.phpt b/Zend/tests/generics/inheritance/diamond/variadic_contravariant_diamond.phpt new file mode 100644 index 000000000000..882b6c2c2093 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/variadic_contravariant_diamond.phpt @@ -0,0 +1,39 @@ +--TEST-- +Diamond + variadic: contravariant T variadic merges as union, exercised at runtime +--FILE-- + { public function sink(X ...$xs): void; } + +class A implements Sink, Sink { + public function sink(int|string ...$xs): void { + foreach ($xs as $x) echo "A: ", var_export($x, true), "\n"; + } +} + +interface IntSink extends Sink {} +interface StrSink extends Sink {} +class B implements IntSink, StrSink { + public function sink(int|string ...$xs): void { + foreach ($xs as $x) echo "B: ", var_export($x, true), "\n"; + } +} + +interface FlexSink extends IntSink, StrSink {} +class C implements FlexSink { + public function sink(int|string ...$xs): void { + foreach ($xs as $x) echo "C: ", var_export($x, true), "\n"; + } +} + +(new A)->sink(1, "x", 2); +(new B)->sink("y", 3); +(new C)->sink(4, "z"); +?> +--EXPECT-- +A: 1 +A: 'x' +A: 2 +B: 'y' +B: 3 +C: 4 +C: 'z' diff --git a/Zend/tests/generics/inheritance/diamond/variance_positive_all_paths.phpt b/Zend/tests/generics/inheritance/diamond/variance_positive_all_paths.phpt new file mode 100644 index 000000000000..3c71f2e55417 --- /dev/null +++ b/Zend/tests/generics/inheritance/diamond/variance_positive_all_paths.phpt @@ -0,0 +1,234 @@ +--TEST-- +Diamond + variance: all positive paths: contravariant union, covariant intersection +--FILE-- + { + public function set(X $v): void; +} + +final class A1Impl implements A1Setter, A1Setter { + public function set(int|string $v): void { echo "A1: ", var_export($v, true), "\n"; } +} + +interface A2Setter<-X> { + public function set(X $v): void; +} + +final class A2Impl implements A2Setter, A2Setter, A2Setter { + public function set(int|string|float $v): void { echo "A2: ", var_export($v, true), "\n"; } +} + +interface A3Setter<-X> { + public function set(X $v): void; +} + +interface A3IntSink extends A3Setter {} +interface A3StrSink extends A3Setter {} +final class A3Impl implements A3IntSink, A3StrSink { + public function set(int|string $v): void { echo "A3: ", var_export($v, true), "\n"; } +} + +interface A5Setter<-X> { + public function set(X $v): void; +} +interface A5IntL1 extends A5Setter {} +interface A5IntL2 extends A5IntL1 {} +interface A5StrL1 extends A5Setter {} +interface A5StrL2 extends A5StrL1 {} +final class A5Impl implements A5IntL2, A5StrL2 { + public function set(int|string $v): void { echo "A5: ", var_export($v, true), "\n"; } +} + +class A6Apple {} +class A6Orange {} +interface A6Setter<-X> { + public function set(X $v): void; +} +final class A6Impl implements A6Setter, A6Setter { + public function set(A6Apple|A6Orange $v): void { echo "A6: ", $v::class, "\n"; } +} + +interface A7Sink<-X> { + public function setOne(X $v): void; + public function setTwo(X $other): void; +} +final class A7Impl implements A7Sink, A7Sink { + public function setOne(int|string $v): void { echo "A7.setOne: ", var_export($v, true), "\n"; } + public function setTwo(int|string $other): void { echo "A7.setTwo: ", var_export($other, true), "\n"; } +} + +interface A8Setter<-X> { + public function set(X $v): void; +} +final class A8Impl implements A8Setter, A8Setter { + public function set(mixed $v): void { echo "A8: ", var_export($v, true), "\n"; } +} + + +interface B1Getter<+X : object> { + public function get(): X; +} +final class B1Impl implements B1Getter, B1Getter { + public function get(): IFoo&IBar { return new FooBar(); } +} + +interface B2Getter<+X : object> { + public function get(): X; +} +final class B2Impl implements B2Getter, B2Getter, B2Getter { + public function get(): IFoo&IBar&IBaz { return new FooBarBaz(); } +} + +interface B3Getter<+X : object> { + public function get(): X; +} +interface B3FooSrc extends B3Getter {} +interface B3BarSrc extends B3Getter {} +final class B3Impl implements B3FooSrc, B3BarSrc { + public function get(): IFoo&IBar { return new FooBar(); } +} + +interface B4Getter<+X : object> { + public function get(): X; +} +abstract class B4ParentSrc implements B4Getter { + public abstract function get(): IFoo; +} +final class B4Impl extends B4ParentSrc implements B4Getter { + public function get(): IFoo&IBar { return new FooBar(); } +} + +interface B5Getter<+X : object> { + public function get(): X; +} +interface B5FooL1 extends B5Getter {} +interface B5FooL2 extends B5FooL1 {} +interface B5BarL1 extends B5Getter {} +interface B5BarL2 extends B5BarL1 {} +final class B5Impl implements B5FooL2, B5BarL2 { + public function get(): IFoo&IBar { return new FooBar(); } +} + +interface B6Getter<+X : object> { + public function get(): X; +} +final class B6Impl implements B6Getter, B6Getter { + public function get(): FooBar { return new FooBar(); } +} + + +interface C1IO<+X : object, -Y> { + public function get(): X; + public function set(Y $v): void; +} +final class C1Impl implements C1IO, C1IO { + public function get(): IFoo&IBar { return new FooBar(); } + public function set(int|string $v): void { echo "C1.set: ", var_export($v, true), "\n"; } +} + +interface C2IO<+X : object, -Y> { + public function get(): X; + public function set(Y $v): void; +} +interface C2FooInt extends C2IO {} +interface C2BarStr extends C2IO {} +final class C2Impl implements C2FooInt, C2BarStr { + public function get(): IFoo&IBar { return new FooBar(); } + public function set(int|string $v): void { echo "C2.set: ", var_export($v, true), "\n"; } +} + +interface C3IO<+X : object, -Y> { + public function get(): X; + public function set(Y $v): void; +} +interface C3FooIntL1 extends C3IO {} +interface C3FooIntL2 extends C3FooIntL1 {} +interface C3BarStrL1 extends C3IO {} +interface C3BarStrL2 extends C3BarStrL1 {} +final class C3Impl implements C3FooIntL2, C3BarStrL2 { + public function get(): IFoo&IBar { return new FooBar(); } + public function set(int|string $v): void { echo "C3.set: ", var_export($v, true), "\n"; } +} + + +interface D1Setter<-X> { + public function set(X $v): void; +} +interface D1Wrap<-Y> extends D1Setter {} +final class D1Impl implements D1Wrap, D1Setter { + public function set(int|string $v): void { echo "D1: ", var_export($v, true), "\n"; } +} + + +$a1 = new A1Impl(); $a1->set(7); $a1->set("hi"); +$a2 = new A2Impl(); $a2->set(7); $a2->set("hi"); $a2->set(3.14); +$a3 = new A3Impl(); $a3->set(7); $a3->set("hi"); +$a5 = new A5Impl(); $a5->set(7); $a5->set("hi"); +$a6 = new A6Impl(); $a6->set(new A6Apple()); $a6->set(new A6Orange()); +$a7 = new A7Impl(); $a7->setOne(7); $a7->setTwo("hi"); +$a8 = new A8Impl(); $a8->set(7); $a8->set("hi"); $a8->set(3.14); + +$b1 = new B1Impl(); var_dump($b1->get() instanceof IFoo, $b1->get() instanceof IBar); +$b2 = new B2Impl(); var_dump($b2->get() instanceof IFoo, $b2->get() instanceof IBar, $b2->get() instanceof IBaz); +$b3 = new B3Impl(); var_dump($b3->get() instanceof IFoo, $b3->get() instanceof IBar); +$b4 = new B4Impl(); var_dump($b4->get() instanceof IFoo, $b4->get() instanceof IBar); +$b5 = new B5Impl(); var_dump($b5->get() instanceof IFoo, $b5->get() instanceof IBar); +$b6 = new B6Impl(); var_dump($b6->get() instanceof FooBar); + +$c1 = new C1Impl(); var_dump($c1->get() instanceof FooBar); $c1->set(7); $c1->set("hi"); +$c2 = new C2Impl(); var_dump($c2->get() instanceof FooBar); $c2->set(7); $c2->set("hi"); +$c3 = new C3Impl(); var_dump($c3->get() instanceof FooBar); $c3->set(7); $c3->set("hi"); + +$d1 = new D1Impl(); $d1->set(7); $d1->set("hi"); + +echo "done\n"; +?> +--EXPECT-- +A1: 7 +A1: 'hi' +A2: 7 +A2: 'hi' +A2: 3.14 +A3: 7 +A3: 'hi' +A5: 7 +A5: 'hi' +A6: A6Apple +A6: A6Orange +A7.setOne: 7 +A7.setTwo: 'hi' +A8: 7 +A8: 'hi' +A8: 3.14 +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +C1.set: 7 +C1.set: 'hi' +bool(true) +C2.set: 7 +C2.set: 'hi' +bool(true) +C3.set: 7 +C3.set: 'hi' +D1: 7 +D1: 'hi' +done diff --git a/Zend/tests/generics/inheritance/extends_args/instanceof_monomorph_parent.phpt b/Zend/tests/generics/inheritance/extends_args/instanceof_monomorph_parent.phpt new file mode 100644 index 000000000000..710f785f0ed8 --- /dev/null +++ b/Zend/tests/generics/inheritance/extends_args/instanceof_monomorph_parent.phpt @@ -0,0 +1,46 @@ +--TEST-- +Extends-with-args: subclass's direct parent is the canonical monomorph +--FILE-- + { + public function __construct(public mixed $value) {} +} + +class IntBox extends Box {} +class StrBox extends Box {} + +$i = new IntBox(42); +$s = new StrBox("hi"); + +// instanceof at the AST level discards type arguments, so we verify the +// monomorph parent via reflection and string class comparisons instead. +var_dump($i instanceof Box); +var_dump($i instanceof IntBox); + +$rcInt = new ReflectionClass(IntBox::class); +$rcStr = new ReflectionClass(StrBox::class); +var_dump($rcInt->getParentClass()->getName()); +var_dump($rcStr->getParentClass()->getName()); + +// Each subclass's direct parent is its own distinct monomorph. +var_dump($rcInt->getParentClass()->getName() !== $rcStr->getParentClass()->getName()); + +// The grandparent is the bare base, shared. +var_dump($rcInt->getParentClass()->getParentClass()->getName()); +var_dump($rcInt->getParentClass()->getParentClass()->getName() + === $rcStr->getParentClass()->getParentClass()->getName()); + +// And the canonical monomorphs are registered with their canonical names. +var_dump(class_exists("Box", false)); +var_dump(class_exists("Box", false)); +?> +--EXPECT-- +bool(true) +bool(true) +string(8) "Box" +string(11) "Box" +bool(true) +string(3) "Box" +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/extends_args/property_hook_on_inherited_T.phpt b/Zend/tests/generics/inheritance/extends_args/property_hook_on_inherited_T.phpt new file mode 100644 index 000000000000..8b694703ac69 --- /dev/null +++ b/Zend/tests/generics/inheritance/extends_args/property_hook_on_inherited_T.phpt @@ -0,0 +1,39 @@ +--TEST-- +Extends-with-args: property hook on inherited T-typed property survives monomorph link +--FILE-- + { + public T $value { + get => $this->value; + set(T $v) { $this->value = $v; } + } + public function __construct(T $v) { $this->value = $v; } +} + +class IntBox extends Box {} + +$b = new IntBox(42); +echo "type: ", (new ReflectionProperty($b, "value"))->getType(), "\n"; +echo "value: ", $b->value, "\n"; + +// Set hook with the substituted type accepts an int. +$b->value = 99; +echo "after set: ", $b->value, "\n"; + +// And the inherited typed property is monomorph-substituted to int. +$rc = new ReflectionClass($b); +echo "parent: ", $rc->getParentClass()->getName(), "\n"; + +$baseRC = new ReflectionClass(Box::class); +echo "base property type: ", $baseRC->getProperty('value')->getType(), "\n"; + +$monoRC = new ReflectionClass("Box"); +echo "mono property type: ", $monoRC->getProperty('value')->getType(), "\n"; +?> +--EXPECT-- +type: int +value: 42 +after set: 99 +parent: Box +base property type: mixed +mono property type: int diff --git a/Zend/tests/generics/inheritance/extends_args/recursive_bounds_extends.phpt b/Zend/tests/generics/inheritance/extends_args/recursive_bounds_extends.phpt new file mode 100644 index 000000000000..0930b9b017cb --- /dev/null +++ b/Zend/tests/generics/inheritance/extends_args/recursive_bounds_extends.phpt @@ -0,0 +1,37 @@ +--TEST-- +Extends-with-args: subclass with recursive-bound type parameters extending a generic parent +--FILE-- + {} + +class Pair, U: Box> { + public function __construct(public Box $left, public Box $right) {} +} + +// Subclass binds Pair's parameters to two concrete monomorphs. +class StrictPair, B: Box> extends Pair {} + +// Two further subclasses, both passing concrete args to StrictPair. +class IntFirst extends StrictPair, Box> {} +class StrFirst extends StrictPair, Box> {} + +$p1 = new IntFirst(new Box(), new Box()); +$p2 = new StrFirst(new Box(), new Box()); + +echo (new ReflectionClass($p1))->getParentClass()->getName(), "\n"; +echo (new ReflectionClass($p2))->getParentClass()->getName(), "\n"; + +// Distinct StrictPair monos. +var_dump((new ReflectionClass($p1))->getParentClass()->getName() + !== (new ReflectionClass($p2))->getParentClass()->getName()); + +// Both transitively extend Pair (bare base, two hops up). +var_dump($p1 instanceof Pair); +var_dump($p2 instanceof Pair); +?> +--EXPECT-- +StrictPair,Box> +StrictPair,Box> +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/extends_args/variance_through_synthesis.phpt b/Zend/tests/generics/inheritance/extends_args/variance_through_synthesis.phpt new file mode 100644 index 000000000000..b2657361e619 --- /dev/null +++ b/Zend/tests/generics/inheritance/extends_args/variance_through_synthesis.phpt @@ -0,0 +1,38 @@ +--TEST-- +Variance enforcement at synthesis: extends-with-args composes through the monomorph +--FILE-- + { + public function get(): T { return new Animal(); } +} + +class DogBox extends Box {} +$d = new DogBox(); +var_dump($d instanceof Box); +var_dump((new ReflectionClass($d))->getParentClass()->getName()); + +// Two synthesized monos extending the same base both succeed; their own +// concrete signatures honour covariance. +class AnimalBox extends Box {} +$rcAnimalMono = new ReflectionClass("Box"); +echo "Box::get returns: ", $rcAnimalMono->getMethod('get')->getReturnType(), "\n"; +$rcDogMono = new ReflectionClass("Box"); +echo "Box::get returns: ", $rcDogMono->getMethod('get')->getReturnType(), "\n"; + +// Bound violation at extends-with-args fires the standard error. +try { + eval('class IntBox extends Box {}'); +} catch (\Throwable $e) { + echo "bound violation: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +bool(true) +string(8) "Box" +Box::get returns: Animal +Box::get returns: Dog +%aType argument 1 to extends Box in IntBox does not satisfy the bound Animal on parameter T, int given%a diff --git a/Zend/tests/generics/inheritance/implements_args/implements_monomorph.phpt b/Zend/tests/generics/inheritance/implements_args/implements_monomorph.phpt new file mode 100644 index 000000000000..7af42f043164 --- /dev/null +++ b/Zend/tests/generics/inheritance/implements_args/implements_monomorph.phpt @@ -0,0 +1,61 @@ +--TEST-- +Implements-with-args: implementing class's direct interface is the canonical monomorph +--FILE-- + { + public function next(): T; +} + +class IntIter implements Iter { + public function __construct(public int $v) {} + public function next(): int { return ++$this->v; } +} + +class StrIter implements Iter { + public function next(): string { return "a"; } +} + +$i = new IntIter(0); + +// The monomorph is recorded as the directly-implemented interface; the bare +// base shows up transitively. +$rcInt = new ReflectionClass(IntIter::class); +$names = $rcInt->getInterfaceNames(); +sort($names); +var_dump($names); + +$rcStr = new ReflectionClass(StrIter::class); +$names = $rcStr->getInterfaceNames(); +sort($names); +var_dump($names); + +// instanceof against the bare base works transitively. +var_dump($i instanceof Iter); + +// The monomorph and its base are registered. +var_dump(interface_exists("Iter", false)); +var_dump(interface_exists("Iter", false)); +var_dump(interface_exists("Iter", false)); + +// The monomorph itself reports the correct kind. +$rcMono = new ReflectionClass("Iter"); +var_dump($rcMono->isInterface()); +?> +--EXPECT-- +array(2) { + [0]=> + string(4) "Iter" + [1]=> + string(9) "Iter" +} +array(2) { + [0]=> + string(4) "Iter" + [1]=> + string(12) "Iter" +} +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/generics/inheritance/lsp/abstract_class_chain.phpt b/Zend/tests/generics/inheritance/lsp/abstract_class_chain.phpt new file mode 100644 index 000000000000..674b98e12375 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/abstract_class_chain.phpt @@ -0,0 +1,20 @@ +--TEST-- +Parametric LSP: abstract generic class extended by another abstract class, then concretized +--FILE-- + { + abstract public function process(T $x): T; +} + +abstract class Middle extends Base { + public function double(U $x): U { return $this->process($this->process($x)); } +} + +class IntLeaf extends Middle { + public function process(int $x): int { return $x + 1; } +} + +echo (new IntLeaf)->double(10), "\n"; +?> +--EXPECT-- +12 diff --git a/Zend/tests/generics/inheritance/lsp/abstract_method.phpt b/Zend/tests/generics/inheritance/lsp/abstract_method.phpt new file mode 100644 index 000000000000..27773e88f331 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/abstract_method.phpt @@ -0,0 +1,17 @@ +--TEST-- +Parametric LSP: substitution applies to abstract methods inherited from a generic ancestor +--FILE-- + { + abstract public function unwrap(): T; +} + +class IntContainer extends Container { + public function __construct(private int $v) {} + public function unwrap(): int { return $this->v; } +} + +echo (new IntContainer(11))->unwrap(), "\n"; +?> +--EXPECT-- +11 diff --git a/Zend/tests/generics/inheritance/lsp/basic_param_and_return.phpt b/Zend/tests/generics/inheritance/lsp/basic_param_and_return.phpt new file mode 100644 index 000000000000..2b96fb813731 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/basic_param_and_return.phpt @@ -0,0 +1,29 @@ +--TEST-- +Parametric LSP: child overrides param and return with the bound argument +--FILE-- + { + public function put(T $value): void; + public function get(): T; +} + +class IntBag implements Bag { + private int $v = 0; + public function put(int $value): void { $this->v = $value; } + public function get(): int { return $this->v; } +} + +$b = new IntBag; +$b->put(42); +echo $b->get(), "\n"; + +try { + /** @phpstan-ignore-next-line */ + $b->put("no"); +} catch (TypeError) { + echo "TypeError\n"; +} +?> +--EXPECT-- +42 +TypeError diff --git a/Zend/tests/generics/inheritance/lsp/bounded_param.phpt b/Zend/tests/generics/inheritance/lsp/bounded_param.phpt new file mode 100644 index 000000000000..858387ac74b7 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/bounded_param.phpt @@ -0,0 +1,19 @@ +--TEST-- +Parametric LSP: substitution still composes with a bounded type parameter +--FILE-- + { + public function add(T $x): void; +} + +class DogBag implements Bag { + public function add(Dog $x): void { echo "added ", $x->name(), "\n"; } +} + +(new DogBag)->add(new Dog); +?> +--EXPECT-- +added dog diff --git a/Zend/tests/generics/inheritance/lsp/by_reference_substituted.phpt b/Zend/tests/generics/inheritance/lsp/by_reference_substituted.phpt new file mode 100644 index 000000000000..adbf9729176b --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/by_reference_substituted.phpt @@ -0,0 +1,18 @@ +--TEST-- +Parametric LSP: by-reference parameter substituted with the bound argument +--FILE-- + { + public function fill(T &$slot): void; +} + +class IntFiller implements Filler { + public function fill(int &$slot): void { $slot = 99; } +} + +$x = 0; +(new IntFiller)->fill($x); +echo $x, "\n"; +?> +--EXPECT-- +99 diff --git a/Zend/tests/generics/inheritance/lsp/contravariant_param.phpt b/Zend/tests/generics/inheritance/lsp/contravariant_param.phpt new file mode 100644 index 000000000000..e7420179aeb9 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/contravariant_param.phpt @@ -0,0 +1,21 @@ +--TEST-- +Parametric LSP: contravariant parameter — child accepts a supertype of the bound argument +--FILE-- + { + public function eat(T $x): void; +} + +class DogEater implements Eater { + public function eat(Animal $x): void { echo "ate ", get_class($x), "\n"; } +} + +(new DogEater)->eat(new Dog); +(new DogEater)->eat(new Animal); +?> +--EXPECT-- +ate Dog +ate Animal diff --git a/Zend/tests/generics/inheritance/lsp/covariant_return.phpt b/Zend/tests/generics/inheritance/lsp/covariant_return.phpt new file mode 100644 index 000000000000..0985b93de5a2 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/covariant_return.phpt @@ -0,0 +1,19 @@ +--TEST-- +Parametric LSP: covariant return — child returns a strict subtype of the bound argument +--FILE-- + { + public function produce(): T; +} + +class DogProducer implements Producer { + public function produce(): Dog { return new Dog; } +} + +echo get_class((new DogProducer)->produce()), "\n"; +?> +--EXPECT-- +Dog diff --git a/Zend/tests/generics/inheritance/lsp/default_param.phpt b/Zend/tests/generics/inheritance/lsp/default_param.phpt new file mode 100644 index 000000000000..648b477c78b2 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/default_param.phpt @@ -0,0 +1,16 @@ +--TEST-- +Parametric LSP: a default type parameter still allows the child's signature to be erased-compatible +--FILE-- + { + public function set(T $value): void; +} + +class IntHolder implements Holder { + public function set(int $value): void { echo "set $value\n"; } +} + +(new IntHolder)->set(5); +?> +--EXPECT-- +set 5 diff --git a/Zend/tests/generics/inheritance/lsp/diamond_via_interfaces.phpt b/Zend/tests/generics/inheritance/lsp/diamond_via_interfaces.phpt new file mode 100644 index 000000000000..2ac2872cafc7 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/diamond_via_interfaces.phpt @@ -0,0 +1,19 @@ +--TEST-- +Parametric LSP: diamond inheritance via two generic intermediaries with the same target +--FILE-- + { + public function id(T $x): T; +} + +interface LeftPath extends Base {} +interface RightPath extends Base {} + +class IntDiamond implements LeftPath, RightPath { + public function id(int $x): int { return $x; } +} + +echo (new IntDiamond)->id(99), "\n"; +?> +--EXPECT-- +99 diff --git a/Zend/tests/generics/inheritance/lsp/extends_and_implements_generic.phpt b/Zend/tests/generics/inheritance/lsp/extends_and_implements_generic.phpt new file mode 100644 index 000000000000..d2a7f87fccd2 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/extends_and_implements_generic.phpt @@ -0,0 +1,23 @@ +--TEST-- +Parametric LSP: a class extending a generic class while implementing an unrelated generic interface +--FILE-- + { + public function append(T $value): void { echo "append:$value\n"; } +} + +interface Counter { + public function count(): U; +} + +class IntListWithCount extends BaseList implements Counter { + public function count(): int { return 0; } +} + +$l = new IntListWithCount; +$l->append(7); +echo $l->count(), "\n"; +?> +--EXPECT-- +append:7 +0 diff --git a/Zend/tests/generics/inheritance/lsp/generic_class_extends_generic.phpt b/Zend/tests/generics/inheritance/lsp/generic_class_extends_generic.phpt new file mode 100644 index 000000000000..0705d638d7c2 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/generic_class_extends_generic.phpt @@ -0,0 +1,18 @@ +--TEST-- +Parametric LSP: a generic class extending a generic class forwards bindings to subclasses +--FILE-- + { + public function f(X $x): void {} +} + +class B extends A {} + +class C extends B { + public function f(int $x): void { echo "C::f($x)\n"; } +} + +(new C)->f(7); +?> +--EXPECT-- +C::f(7) diff --git a/Zend/tests/generics/inheritance/lsp/impl_with_identity_type_param_binding.phpt b/Zend/tests/generics/inheritance/lsp/impl_with_identity_type_param_binding.phpt new file mode 100644 index 000000000000..8aa381658bea --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/impl_with_identity_type_param_binding.phpt @@ -0,0 +1,24 @@ +--TEST-- +Parametric LSP: child implementing `I` with its own TN forwarded to parent's TN +--FILE-- + { + public function getEdgesFrom(TN $from): array; +} + +class DG implements GI { + public function getEdgesFrom(TN $from): array { return []; } +} + +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/lsp/method_level_param_bound_subst.phpt b/Zend/tests/generics/inheritance/lsp/method_level_param_bound_subst.phpt new file mode 100644 index 000000000000..c8b0fb55d328 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/method_level_param_bound_subst.phpt @@ -0,0 +1,31 @@ +--TEST-- +Parametric LSP: method-level type-parameter bound that references a class-scope T substitutes when the subclass binds T +--FILE-- + { function set(U $x) }` — the method's +// own U has a bound that's a class-scope T-ref. When `class B extends A` +// supplies T = string, the inheritance check on the inherited (or overridden) +// method must see U's bound substituted from T → string, otherwise the parent +// renders as `set(mixed $x)` (T erased) and the child's `set(U $x)` +// gets rejected as narrower than mixed. + +class A { + public function set(U $x): void {} +} + +class B extends A { + public function set(U $x): void {} +} + +class C { + public function set(U $x): void {} +} + +class D extends C { + public function set(U $x): void {} +} + +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/inheritance/lsp/method_param_separate_scope.phpt b/Zend/tests/generics/inheritance/lsp/method_param_separate_scope.phpt new file mode 100644 index 000000000000..ef2fbdc435b8 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/method_param_separate_scope.phpt @@ -0,0 +1,20 @@ +--TEST-- +Parametric LSP: a method-level generic parameter is not affected by class-level substitution +--FILE-- + { + public function get(): T; + public function map(callable $f): U; +} + +class IntContainer implements Container { + public function get(): int { return 5; } + public function map(callable $f): U { return $f(42); } +} + +echo (new IntContainer)->get(), "\n"; +echo (new IntContainer)->map(fn($x) => "v=$x"), "\n"; +?> +--EXPECT-- +5 +v=42 diff --git a/Zend/tests/generics/inheritance/lsp/method_substituted.phpt b/Zend/tests/generics/inheritance/lsp/method_substituted.phpt new file mode 100644 index 000000000000..ec3fd14778b5 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/method_substituted.phpt @@ -0,0 +1,16 @@ +--TEST-- +Parametric LSP: methods on the parent are substituted in the child +--FILE-- + { + abstract public function make(): T; +} + +class IntFactory extends Factory { + public function make(): int { return 7; } +} + +echo (new IntFactory())->make(), "\n"; +?> +--EXPECT-- +7 diff --git a/Zend/tests/generics/inheritance/lsp/multi_interface.phpt b/Zend/tests/generics/inheritance/lsp/multi_interface.phpt new file mode 100644 index 000000000000..12f6fbff896e --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/multi_interface.phpt @@ -0,0 +1,25 @@ +--TEST-- +Parametric LSP: implementing two distinct generic interfaces with different bindings +--FILE-- + { + public function read(): T; +} + +interface Writer { + public function write(U $value): void; +} + +class IntReaderStringWriter implements Reader, Writer { + private string $w = ""; + public function read(): int { return 42; } + public function write(string $value): void { $this->w = $value; echo "wrote: $value\n"; } +} + +$x = new IntReaderStringWriter; +echo $x->read(), "\n"; +$x->write("hello"); +?> +--EXPECT-- +42 +wrote: hello diff --git a/Zend/tests/generics/inheritance/lsp/multi_param.phpt b/Zend/tests/generics/inheritance/lsp/multi_param.phpt new file mode 100644 index 000000000000..36775f44b5e4 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/multi_param.phpt @@ -0,0 +1,23 @@ +--TEST-- +Parametric LSP: multi-parameter generic interface substitutes both parameters +--FILE-- + { + public function set(K $key, V $value): void; + public function lookup(K $key): V; +} + +class StrIntMap implements Map { + private array $items = []; + public function set(string $key, int $value): void { $this->items[$key] = $value; } + public function lookup(string $key): int { return $this->items[$key] ?? -1; } +} + +$m = new StrIntMap; +$m->set("a", 1); +echo $m->lookup("a"), "\n"; +echo $m->lookup("missing"), "\n"; +?> +--EXPECT-- +1 +-1 diff --git a/Zend/tests/generics/inheritance/lsp/non_generic_inherits_unrelated.phpt b/Zend/tests/generics/inheritance/lsp/non_generic_inherits_unrelated.phpt new file mode 100644 index 000000000000..19dc88618b12 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/non_generic_inherits_unrelated.phpt @@ -0,0 +1,16 @@ +--TEST-- +Parametric LSP: a non-generic class still uses standard LSP when the parent is non-generic +--FILE-- +f(3), "\n"; +?> +--EXPECT-- +8 diff --git a/Zend/tests/generics/inheritance/lsp/nullable_T_chain_subst.phpt b/Zend/tests/generics/inheritance/lsp/nullable_T_chain_subst.phpt new file mode 100644 index 000000000000..dad6ab6004df --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/nullable_T_chain_subst.phpt @@ -0,0 +1,18 @@ +--TEST-- +Parametric LSP: ?T return substitutes through a multi-level chain (interface extending interface) +--FILE-- + { + public function next(): ?T; +} + +interface J extends I {} + +class C implements J { + public function next(): ?int { return 7; } +} + +var_dump((new C)->next()); +?> +--EXPECT-- +int(7) diff --git a/Zend/tests/generics/inheritance/lsp/nullable_T_param_subst.phpt b/Zend/tests/generics/inheritance/lsp/nullable_T_param_subst.phpt new file mode 100644 index 000000000000..37c97e94b636 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/nullable_T_param_subst.phpt @@ -0,0 +1,14 @@ +--TEST-- +Parametric LSP: child param narrower than ?T (substituted to ?int) is rejected +--FILE-- + { + public function take(?T $x): void {} +} + +class B extends A { + public function take(int $x): void {} +} +?> +--EXPECTF-- +Fatal error: Declaration of B::take(int $x): void must be compatible with A::take(?int $x): void in %s on line %d diff --git a/Zend/tests/generics/inheritance/lsp/nullable_T_return_subst.phpt b/Zend/tests/generics/inheritance/lsp/nullable_T_return_subst.phpt new file mode 100644 index 000000000000..0760cc0b9a5a --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/nullable_T_return_subst.phpt @@ -0,0 +1,16 @@ +--TEST-- +Parametric LSP: ?T return type substitutes through implements with the nullable bit preserved +--FILE-- + { + public function f(): ?T; +} + +class B implements A { + public function f(): ?int { return 1; } +} + +var_dump((new B)->f()); +?> +--EXPECT-- +int(1) diff --git a/Zend/tests/generics/inheritance/lsp/optional_arg_substituted.phpt b/Zend/tests/generics/inheritance/lsp/optional_arg_substituted.phpt new file mode 100644 index 000000000000..4b89ae236d43 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/optional_arg_substituted.phpt @@ -0,0 +1,27 @@ +--TEST-- +Parametric LSP: optional parameter substituted with the bound argument +--FILE-- + { + public function set(T $value, bool $flag = false): void; +} + +class IntMaybe implements Maybe { + public function set(int $value, bool $flag = false): void { echo "$value/", (int)$flag, "\n"; } +} + +$m = new IntMaybe; +$m->set(5); +$m->set(6, true); + +try { + /** @phpstan-ignore-next-line */ + $m->set("x"); +} catch (TypeError) { + echo "TypeError\n"; +} +?> +--EXPECT-- +5/0 +6/1 +TypeError diff --git a/Zend/tests/generics/inheritance/lsp/parent_call.phpt b/Zend/tests/generics/inheritance/lsp/parent_call.phpt new file mode 100644 index 000000000000..89dee35e724b --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/parent_call.phpt @@ -0,0 +1,22 @@ +--TEST-- +Parametric LSP: calling parent::method() from substituted child still routes to the erased parent +--FILE-- + { + public function f(T $x): void { + echo "C::f got ", get_debug_type($x), "\n"; + } +} + +class IntC extends C { + public function f(int $x): void { + echo "IntC::f got $x\n"; + parent::f($x); + } +} + +(new IntC)->f(3); +?> +--EXPECT-- +IntC::f got 3 +C::f got int diff --git a/Zend/tests/generics/inheritance/lsp/reordered_params.phpt b/Zend/tests/generics/inheritance/lsp/reordered_params.phpt new file mode 100644 index 000000000000..a47500267117 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/reordered_params.phpt @@ -0,0 +1,32 @@ +--TEST-- +Parametric LSP: child reorders the parent's type parameters +--FILE-- + { + public function first(): A; + public function second(): B; +} + +class IntStrPair implements Pair { + public function __construct(private int $a, private string $b) {} + public function first(): int { return $this->a; } + public function second(): string { return $this->b; } +} + +class FlippedPair implements Pair { + public function __construct(private mixed $x, private mixed $y) {} + public function first(): Y { return $this->y; } + public function second(): X { return $this->x; } +} + +class StrIntFlipped extends FlippedPair {} + +$p = new IntStrPair(1, "hi"); +echo $p->first(), "/", $p->second(), "\n"; + +$f = new StrIntFlipped(7, "world"); +echo $f->first(), "/", $f->second(), "\n"; +?> +--EXPECT-- +1/hi +world/7 diff --git a/Zend/tests/generics/inheritance/lsp/transitive_three_level.phpt b/Zend/tests/generics/inheritance/lsp/transitive_three_level.phpt new file mode 100644 index 000000000000..99d541d5014d --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/transitive_three_level.phpt @@ -0,0 +1,18 @@ +--TEST-- +Parametric LSP: substitution composes across three levels of generic ancestors +--FILE-- + { + public function take(T $x): T; +} +interface M extends L {} +interface N extends M {} + +class IntN implements N { + public function take(int $x): int { return $x + 1; } +} + +echo (new IntN)->take(41), "\n"; +?> +--EXPECT-- +42 diff --git a/Zend/tests/generics/inheritance/lsp/transitive_through_class.phpt b/Zend/tests/generics/inheritance/lsp/transitive_through_class.phpt new file mode 100644 index 000000000000..9f02cefc3f9e --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/transitive_through_class.phpt @@ -0,0 +1,19 @@ +--TEST-- +Parametric LSP: substitution composes through a generic abstract class and a concrete leaf +--FILE-- + { + public function area(): T; +} + +abstract class Polygon implements Shape {} + +class IntSquare extends Polygon { + public function __construct(private int $side) {} + public function area(): int { return $this->side * $this->side; } +} + +echo (new IntSquare(4))->area(), "\n"; +?> +--EXPECT-- +16 diff --git a/Zend/tests/generics/inheritance/lsp/transitive_two_level.phpt b/Zend/tests/generics/inheritance/lsp/transitive_two_level.phpt new file mode 100644 index 000000000000..0a78e360a6e2 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/transitive_two_level.phpt @@ -0,0 +1,20 @@ +--TEST-- +Parametric LSP: substitution composes through a generic intermediate +--FILE-- + { + public function consume(T $value): void; +} + +interface Service extends Consumer {} + +class NullService implements Service { + public function consume(null $value): void { + echo "consumed null\n"; + } +} + +(new NullService)->consume(null); +?> +--EXPECT-- +consumed null diff --git a/Zend/tests/generics/inheritance/lsp/union_of_type_params_narrower_return.phpt b/Zend/tests/generics/inheritance/lsp/union_of_type_params_narrower_return.phpt new file mode 100644 index 000000000000..a11fba5996cd --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/union_of_type_params_narrower_return.phpt @@ -0,0 +1,25 @@ +--TEST-- +Parametric LSP: child narrowing Tl|Tr return down to a single Tl is accepted +--FILE-- + { + abstract public function get(): T; +} + +class LeftOnly extends Base { + public function __construct(private Tl $value) {} + public function get(): Tl { return $this->value; } +} + +$a = new LeftOnly::("hi"); +var_dump($a->get()); + +$b = new LeftOnly::(42); +var_dump($b->get()); +?> +--EXPECT-- +string(2) "hi" +int(42) diff --git a/Zend/tests/generics/inheritance/lsp/union_of_type_params_return_subst.phpt b/Zend/tests/generics/inheritance/lsp/union_of_type_params_return_subst.phpt new file mode 100644 index 000000000000..bb561a56edf1 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/union_of_type_params_return_subst.phpt @@ -0,0 +1,49 @@ +--TEST-- +Parametric LSP: child returning union of two type parameters (Tl|Tr) satisfies parent's T when parent is bound to Tl|Tr +--FILE-- + with overrides returning Tl|Tr. + +abstract class Base { + abstract public function get(): T; +} + +class Pair extends Base { + public function __construct(private Tl|Tr $value) {} + public function get(): Tl|Tr { return $this->value; } +} + +$p = new Pair::("hi"); +var_dump($p->get()); + +$q = new Pair::(42); +var_dump($q->get()); + +// Also exercise the interface-implements path, which is what the Psl +// failure actually hit (UnionType extends Type which implements TypeInterface). +interface I<+T> { + public function read(mixed $v): T; +} + +abstract class IBase implements I { + abstract public function read(mixed $v): T; +} + +class Union extends IBase { + public function read(mixed $v): Tl|Tr { + if ($v instanceof Tl || $v instanceof Tr) return $v; + throw new TypeError("nope"); + } +} + +echo "loaded\n"; +?> +--EXPECT-- +string(2) "hi" +int(42) +loaded diff --git a/Zend/tests/generics/inheritance/lsp/variadic_substituted.phpt b/Zend/tests/generics/inheritance/lsp/variadic_substituted.phpt new file mode 100644 index 000000000000..abc2f86c8db7 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/variadic_substituted.phpt @@ -0,0 +1,24 @@ +--TEST-- +Parametric LSP: variadic parameter substituted with the bound argument +--FILE-- + { + public function acceptAll(T ...$items): int; +} + +class IntAcceptor implements Acceptor { + public function acceptAll(int ...$items): int { return array_sum($items); } +} + +echo (new IntAcceptor)->acceptAll(1, 2, 3, 4), "\n"; + +try { + /** @phpstan-ignore-next-line */ + (new IntAcceptor)->acceptAll(1, "no"); +} catch (TypeError) { + echo "TypeError\n"; +} +?> +--EXPECT-- +10 +TypeError diff --git a/Zend/tests/generics/inheritance/lsp/violation_extends_return_sibling_of_bound.phpt b/Zend/tests/generics/inheritance/lsp/violation_extends_return_sibling_of_bound.phpt new file mode 100644 index 000000000000..e9a493b12132 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/violation_extends_return_sibling_of_bound.phpt @@ -0,0 +1,18 @@ +--TEST-- +Parametric LSP: child of `extends A` cannot override return type T with a sibling of the bound (Cat) +--FILE-- + { + public function get(): T {} +} + +class DogChild extends A { + public function get(): Cat { return new Cat(); } +} +?> +--EXPECTF-- +Fatal error: Declaration of DogChild::get(): Cat must be compatible with A::get(): Dog in %s on line %d diff --git a/Zend/tests/generics/inheritance/lsp/violation_extends_return_transitive.phpt b/Zend/tests/generics/inheritance/lsp/violation_extends_return_transitive.phpt new file mode 100644 index 000000000000..7dc31ae3607e --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/violation_extends_return_transitive.phpt @@ -0,0 +1,16 @@ +--TEST-- +Parametric LSP: violation propagates through a two-level extends chain +--FILE-- + { + abstract public function get(): T; +} + +abstract class B extends A {} + +class C extends B { + public function get(): bool { return true; } +} +?> +--EXPECTF-- +Fatal error: Declaration of C::get(): bool must be compatible with A::get(): int in %s on line %d diff --git a/Zend/tests/generics/inheritance/lsp/violation_extends_return_unbounded.phpt b/Zend/tests/generics/inheritance/lsp/violation_extends_return_unbounded.phpt new file mode 100644 index 000000000000..035ec8bd0538 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/violation_extends_return_unbounded.phpt @@ -0,0 +1,14 @@ +--TEST-- +Parametric LSP: child of `extends A` cannot override return type T with an unrelated type +--FILE-- + { + public function get(): T {} +} + +class IntChild extends A { + public function get(): bool { return true; } +} +?> +--EXPECTF-- +Fatal error: Declaration of IntChild::get(): bool must be compatible with A::get(): int in %s on line %d diff --git a/Zend/tests/generics/inheritance/lsp/violation_nullable_T_message.phpt b/Zend/tests/generics/inheritance/lsp/violation_nullable_T_message.phpt new file mode 100644 index 000000000000..93db9b0e7e96 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/violation_nullable_T_message.phpt @@ -0,0 +1,14 @@ +--TEST-- +Parametric LSP: error message for a ?T return violation shows the substituted nullable form +--FILE-- + { + public function f(): ?T {} +} + +class B extends A { + public function f(): bool { return true; } +} +?> +--EXPECTF-- +Fatal error: Declaration of B::f(): bool must be compatible with A::f(): ?int in %s on line %d diff --git a/Zend/tests/generics/inheritance/lsp/violation_param_too_specific.phpt b/Zend/tests/generics/inheritance/lsp/violation_param_too_specific.phpt new file mode 100644 index 000000000000..832a8c92bee0 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/violation_param_too_specific.phpt @@ -0,0 +1,17 @@ +--TEST-- +Parametric LSP: child param more specific than the bound argument is rejected (contravariance) +--FILE-- + { + public function eat(T $x): void; +} + +class TooSpecificEater implements Eater { + public function eat(Dog $x): void {} +} +?> +--EXPECTF-- +Fatal error: Declaration of TooSpecificEater::eat(Dog $x): void must be compatible with Eater::eat(Animal $x): void in %s on line %d diff --git a/Zend/tests/generics/inheritance/lsp/violation_return_too_general.phpt b/Zend/tests/generics/inheritance/lsp/violation_return_too_general.phpt new file mode 100644 index 000000000000..bfd442d0c484 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/violation_return_too_general.phpt @@ -0,0 +1,17 @@ +--TEST-- +Parametric LSP: child return more general than the bound argument is rejected (covariance) +--FILE-- + { + public function produce(): T; +} + +class TooGeneralProducer implements Producer { + public function produce(): Animal { return new Animal; } +} +?> +--EXPECTF-- +Fatal error: Declaration of TooGeneralProducer::produce(): Animal must be compatible with Producer::produce(): Dog in %s on line %d diff --git a/Zend/tests/generics/inheritance/lsp/violation_union_of_t_refs_widened.phpt b/Zend/tests/generics/inheritance/lsp/violation_union_of_t_refs_widened.phpt new file mode 100644 index 000000000000..0e83ce757c60 --- /dev/null +++ b/Zend/tests/generics/inheritance/lsp/violation_union_of_t_refs_widened.phpt @@ -0,0 +1,17 @@ +--TEST-- +Parametric LSP: child returning Tl|Tr|string (a widening of the parent's substituted Tl|Tr) is rejected +--FILE-- + { + abstract public function get(): T; +} + +class BadPair extends Base { + public function get(): Tl|Tr|string { throw new Exception(); } +} +?> +--EXPECTF-- +Fatal error: Declaration of BadPair::get(): Tl|Tr|string must be compatible with Base::get(): Tl|Tr in %s on line %d diff --git a/Zend/tests/generics/inheritance/method/inherited_concrete_unchanged.phpt b/Zend/tests/generics/inheritance/method/inherited_concrete_unchanged.phpt new file mode 100644 index 000000000000..9b08820032dc --- /dev/null +++ b/Zend/tests/generics/inheritance/method/inherited_concrete_unchanged.phpt @@ -0,0 +1,16 @@ +--TEST-- +Inherited methods: concretely typed parameters and returns are unaffected by substitution +--FILE-- + { + public function bare(int $x): string { return (string)$x; } +} + +class IntHelper extends Helper {} + +$rm = (new ReflectionClass('IntHelper'))->getMethod('bare'); +echo $rm->getParameters()[0]->getType()->getName(), " -> ", + $rm->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +int -> string diff --git a/Zend/tests/generics/inheritance/method/inherited_from_interface.phpt b/Zend/tests/generics/inheritance/method/inherited_from_interface.phpt new file mode 100644 index 000000000000..f01ef9796d5d --- /dev/null +++ b/Zend/tests/generics/inheritance/method/inherited_from_interface.phpt @@ -0,0 +1,15 @@ +--TEST-- +Inherited methods: abstract method inherited from a generic interface is substituted on the implementing class +--FILE-- + { + public function unwrap(): T; +} + +abstract class IntBoxImpl implements Box {} + +$rm = (new ReflectionClass('IntBoxImpl'))->getMethod('unwrap'); +echo $rm->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +int diff --git a/Zend/tests/generics/inheritance/method/inherited_method_with_named_with_args_return.phpt b/Zend/tests/generics/inheritance/method/inherited_method_with_named_with_args_return.phpt new file mode 100644 index 000000000000..9ceac319adf7 --- /dev/null +++ b/Zend/tests/generics/inheritance/method/inherited_method_with_named_with_args_return.phpt @@ -0,0 +1,20 @@ +--TEST-- +Inherited methods: substituted clone keeps the erased class-name view when the return type wraps a method-level type parameter +--FILE-- + { + private mixed $value; + public function __construct(mixed $val) { $this->value = $val; } + public static function create(O $value): Box { return new self($value); } +} + +class StringBox extends Box {} + +$b = StringBox::create("hello"); +var_dump($b instanceof Box); +$rm = (new ReflectionMethod(StringBox::class, 'create')); +echo "return type: ", (string)$rm->getReturnType(), "\n"; +?> +--EXPECT-- +bool(true) +return type: Box diff --git a/Zend/tests/generics/inheritance/method/inherited_signature_substituted.phpt b/Zend/tests/generics/inheritance/method/inherited_signature_substituted.phpt new file mode 100644 index 000000000000..c64ffc005ad9 --- /dev/null +++ b/Zend/tests/generics/inheritance/method/inherited_signature_substituted.phpt @@ -0,0 +1,21 @@ +--TEST-- +Inherited methods: param and return types are substituted on a class extending a generic parent +--FILE-- + { + public function take(T $x): T { return $x; } +} + +class IntBase extends Base {} +class StrBase extends Base {} + +foreach (['IntBase', 'StrBase'] as $cn) { + $rm = (new ReflectionClass($cn))->getMethod('take'); + echo "$cn::take: ", + $rm->getParameters()[0]->getType()->getName(), " -> ", + $rm->getReturnType()->getName(), "\n"; +} +?> +--EXPECT-- +IntBase::take: int -> int +StrBase::take: string -> string diff --git a/Zend/tests/generics/inheritance/method/inherited_signature_transitive.phpt b/Zend/tests/generics/inheritance/method/inherited_signature_transitive.phpt new file mode 100644 index 000000000000..42d27b7d7ffb --- /dev/null +++ b/Zend/tests/generics/inheritance/method/inherited_signature_transitive.phpt @@ -0,0 +1,17 @@ +--TEST-- +Inherited methods: substitution composes through a generic intermediate class +--FILE-- + { + public function take(T $x): T { return $x; } +} + +class Mid extends Base {} +class Leaf extends Mid {} + +$rm = (new ReflectionClass('Leaf'))->getMethod('take'); +echo $rm->getParameters()[0]->getType()->getName(), " -> ", + $rm->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +float -> float diff --git a/Zend/tests/generics/inheritance/method/inherited_variadic_substituted.phpt b/Zend/tests/generics/inheritance/method/inherited_variadic_substituted.phpt new file mode 100644 index 000000000000..c2dbc918e450 --- /dev/null +++ b/Zend/tests/generics/inheritance/method/inherited_variadic_substituted.phpt @@ -0,0 +1,15 @@ +--TEST-- +Inherited methods: variadic parameter typed T is substituted on the child class +--FILE-- + { + public function all(T ...$xs): int { return count($xs); } +} + +class IntBase extends Base {} + +$rm = (new ReflectionClass('IntBase'))->getMethod('all'); +echo "param: ", $rm->getParameters()[0]->getType()->getName(), "\n"; +?> +--EXPECT-- +param: int diff --git a/Zend/tests/generics/inheritance/method/runtime_check_transitive.phpt b/Zend/tests/generics/inheritance/method/runtime_check_transitive.phpt new file mode 100644 index 000000000000..d468988629b6 --- /dev/null +++ b/Zend/tests/generics/inheritance/method/runtime_check_transitive.phpt @@ -0,0 +1,24 @@ +--TEST-- +Inherited methods: runtime check fires across a multi-level generic chain +--FILE-- + { + public function take(T $x): T { return $x; } +} + +class Mid extends Base {} + +class Leaf extends Mid {} + +$l = new Leaf(); +var_dump($l->take(42)); + +try { + $l->take("nope"); +} catch (TypeError $e) { + echo "rejected: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(42) +rejected: Base::take(): Argument #1 ($x) must be of type int, string given, called in %s on line %d diff --git a/Zend/tests/generics/inheritance/method/runtime_param_check_unbounded.phpt b/Zend/tests/generics/inheritance/method/runtime_param_check_unbounded.phpt new file mode 100644 index 000000000000..a1561e6ec91f --- /dev/null +++ b/Zend/tests/generics/inheritance/method/runtime_param_check_unbounded.phpt @@ -0,0 +1,38 @@ +--TEST-- +Inherited methods: substituted unbounded T parameter is checked at runtime on the child +--FILE-- + { + public function take(T $x): T { return $x; } +} + +class IntBox extends Box {} +class StrBox extends Box {} + +$ib = new IntBox(); +$sb = new StrBox(); + +// Happy paths +var_dump($ib->take(42)); +var_dump($sb->take("hi")); + +// Cross-type rejections +try { + $ib->take("not an int"); +} catch (TypeError $e) { + echo "IntBox rejects string: ", $e->getMessage(), "\n"; +} + +try { + $sb->take(123); +} catch (TypeError $e) { + echo "StrBox rejects int: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(42) +string(2) "hi" +IntBox rejects string: Box::take(): Argument #1 ($x) must be of type int, string given, called in %s on line %d +StrBox rejects int: Box::take(): Argument #1 ($x) must be of type string, int given, called in %s on line %d diff --git a/Zend/tests/generics/inheritance/method/runtime_param_check_variadic.phpt b/Zend/tests/generics/inheritance/method/runtime_param_check_variadic.phpt new file mode 100644 index 000000000000..75858902e2ba --- /dev/null +++ b/Zend/tests/generics/inheritance/method/runtime_param_check_variadic.phpt @@ -0,0 +1,29 @@ +--TEST-- +Inherited methods: substituted variadic T parameter is checked at runtime on the child +--FILE-- + { + public function takeMany(T ...$xs): array { return $xs; } +} + +class IntBox extends Box {} + +$ib = new IntBox(); +var_dump($ib->takeMany(1, 2, 3)); + +try { + $ib->takeMany(1, "two", 3); +} catch (TypeError $e) { + echo "rejects mixed: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +rejects mixed: Box::takeMany(): Argument #2 must be of type int, string given, called in %s on line %d diff --git a/Zend/tests/generics/inheritance/method/runtime_param_check_weak_mode.phpt b/Zend/tests/generics/inheritance/method/runtime_param_check_weak_mode.phpt new file mode 100644 index 000000000000..b1357e3118d5 --- /dev/null +++ b/Zend/tests/generics/inheritance/method/runtime_param_check_weak_mode.phpt @@ -0,0 +1,30 @@ +--TEST-- +Inherited methods: substituted T parameter honors weak-mode coercion like any other type +--FILE-- + { + public function take(T $x): T { return $x; } +} + +class IntBox extends Box {} +class StrBox extends Box {} + +// Numeric strings coerce to int under weak mode +var_dump((new IntBox())->take("42")); + +// Scalars coerce to string under weak mode +var_dump((new StrBox())->take(123)); + +// Non-coercible still throws +try { + (new IntBox())->take("not a number"); +} catch (TypeError $e) { + echo "rejected: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(42) +string(3) "123" +rejected: Box::take(): Argument #1 ($x) must be of type int, string given, called in %s on line %d diff --git a/Zend/tests/generics/inheritance/method/runtime_param_check_with_default.phpt b/Zend/tests/generics/inheritance/method/runtime_param_check_with_default.phpt new file mode 100644 index 000000000000..0b87d4c936a2 --- /dev/null +++ b/Zend/tests/generics/inheritance/method/runtime_param_check_with_default.phpt @@ -0,0 +1,28 @@ +--TEST-- +Inherited methods: substituted T parameter with a default still rejects bad explicit args +--FILE-- + { + public function take(T $x = null): mixed { return $x; } +} + +class IntBox extends Box {} + +$ib = new IntBox(); + +// Default and matching values pass +var_dump($ib->take()); +var_dump($ib->take(7)); +var_dump($ib->take(null)); + +try { + $ib->take("nope"); +} catch (TypeError $e) { + echo "rejects string: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +NULL +int(7) +NULL +rejects string: Box::take(): Argument #1 ($x) must be of type ?int, string given, called in %s on line %d diff --git a/Zend/tests/generics/inheritance/method/runtime_return_check_unbounded.phpt b/Zend/tests/generics/inheritance/method/runtime_return_check_unbounded.phpt new file mode 100644 index 000000000000..be3b761fd686 --- /dev/null +++ b/Zend/tests/generics/inheritance/method/runtime_return_check_unbounded.phpt @@ -0,0 +1,42 @@ +--TEST-- +Inherited methods: substituted unbounded T return type is checked at runtime on the child +--FILE-- + { + public mixed $payload = null; + public function get(): T { return $this->payload; } +} + +class IntBox extends Box {} +class StrBox extends Box {} + +$ib = new IntBox(); +$ib->payload = 42; +var_dump($ib->get()); + +$sb = new StrBox(); +$sb->payload = "hi"; +var_dump($sb->get()); + +// Now return values that violate the substituted type +$ib->payload = "not an int"; +try { + $ib->get(); +} catch (TypeError $e) { + echo "IntBox return rejects string: ", $e->getMessage(), "\n"; +} + +$sb->payload = 123; +try { + $sb->get(); +} catch (TypeError $e) { + echo "StrBox return rejects int: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(42) +string(2) "hi" +IntBox return rejects string: Box::get(): Return value must be of type int, string returned +StrBox return rejects int: Box::get(): Return value must be of type string, int returned diff --git a/Zend/tests/generics/inheritance/property/extends_concrete_arg.phpt b/Zend/tests/generics/inheritance/property/extends_concrete_arg.phpt new file mode 100644 index 000000000000..1f685d3f0b00 --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_concrete_arg.phpt @@ -0,0 +1,27 @@ +--TEST-- +Property substitution: class extends generic parent with concrete arg substitutes property type +--FILE-- + { + public T $val; +} + +class IntBox extends Box {} + +$rp = (new ReflectionClass('IntBox'))->getProperty('val'); +echo $rp->getType()->getName(), "\n"; + +$ib = new IntBox; +$ib->val = 42; +echo $ib->val, "\n"; + +try { + $ib->val = []; +} catch (TypeError) { + echo "TypeError\n"; +} +?> +--EXPECT-- +int +42 +TypeError diff --git a/Zend/tests/generics/inheritance/property/extends_concrete_property_unchanged.phpt b/Zend/tests/generics/inheritance/property/extends_concrete_property_unchanged.phpt new file mode 100644 index 000000000000..74b04b7f8e72 --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_concrete_property_unchanged.phpt @@ -0,0 +1,17 @@ +--TEST-- +Property substitution: parent property already typed with a concrete type is unchanged +--FILE-- + { + public int $count = 0; + public T $val; +} + +class StrBox extends Box {} + +$rcCount = (new ReflectionClass('StrBox'))->getProperty('count'); +$rcVal = (new ReflectionClass('StrBox'))->getProperty('val'); +echo $rcCount->getType()->getName(), "/", $rcVal->getType()->getName(), "\n"; +?> +--EXPECT-- +int/string diff --git a/Zend/tests/generics/inheritance/property/extends_default_arg.phpt b/Zend/tests/generics/inheritance/property/extends_default_arg.phpt new file mode 100644 index 000000000000..2e809d906fc3 --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_default_arg.phpt @@ -0,0 +1,23 @@ +--TEST-- +Property substitution: extends without args uses parent's parameter default +--FILE-- + { + public T $val; +} + +class Bag extends Box {} + +$rp = (new ReflectionClass('Bag'))->getProperty('val'); +echo $rp->getType()->getName(), "\n"; + +$b = new Bag; +$b->val = 7; +echo $b->val, "\n"; + +try { $b->val = "x"; } catch (TypeError) { echo "TypeError\n"; } +?> +--EXPECT-- +int +7 +TypeError diff --git a/Zend/tests/generics/inheritance/property/extends_get_and_set_hook.phpt b/Zend/tests/generics/inheritance/property/extends_get_and_set_hook.phpt new file mode 100644 index 000000000000..7c71f594849a --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_get_and_set_hook.phpt @@ -0,0 +1,27 @@ +--TEST-- +Property substitution: get and set hook signatures are both substituted on a class extending a generic parent +--FILE-- + { + public T $val { + get => $this->val; + set => $this->val = $value; + } + public function __construct(T $v) { $this->val = $v; } +} + +class IntBox extends Box {} +class StrBox extends Box {} + +foreach (['IntBox', 'StrBox'] as $cn) { + $rp = (new ReflectionClass($cn))->getProperty('val'); + $g = $rp->getHook(PropertyHookType::Get); + $s = $rp->getHook(PropertyHookType::Set); + echo "$cn: prop=", $rp->getType()->getName(), + " get=", $g->getReturnType()->getName(), + " set=", $s->getParameters()[0]->getType()->getName(), "\n"; +} +?> +--EXPECT-- +IntBox: prop=int get=int set=int +StrBox: prop=string get=string set=string diff --git a/Zend/tests/generics/inheritance/property/extends_get_hook.phpt b/Zend/tests/generics/inheritance/property/extends_get_hook.phpt new file mode 100644 index 000000000000..3e8f46d8bbba --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_get_hook.phpt @@ -0,0 +1,24 @@ +--TEST-- +Property substitution: get hook return type is substituted on a class extending a generic parent +--FILE-- + { + public T $val { get => $this->val; } + public function __construct(T $v) { $this->val = $v; } +} + +class IntBox extends Box {} + +$rp = (new ReflectionClass('IntBox'))->getProperty('val'); +echo "prop type: ", $rp->getType()->getName(), "\n"; + +$get = $rp->getHook(PropertyHookType::Get); +echo "get return: ", $get->getReturnType()->getName(), "\n"; + +$ib = new IntBox(42); +echo "value: ", $ib->val, "\n"; +?> +--EXPECT-- +prop type: int +get return: int +value: 42 diff --git a/Zend/tests/generics/inheritance/property/extends_get_hook_transitive.phpt b/Zend/tests/generics/inheritance/property/extends_get_hook_transitive.phpt new file mode 100644 index 000000000000..98b021c591fb --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_get_hook_transitive.phpt @@ -0,0 +1,25 @@ +--TEST-- +Property substitution: get hook return type substitutes through a generic intermediate class +--FILE-- + { + public T $val { get => $this->val; } + public function __construct(T $v) { $this->val = $v; } +} + +class Mid extends Box {} +class Leaf extends Mid {} + +$rp = (new ReflectionClass('Leaf'))->getProperty('val'); +echo "prop type: ", $rp->getType()->getName(), "\n"; + +$get = $rp->getHook(PropertyHookType::Get); +echo "get return: ", $get->getReturnType()->getName(), "\n"; + +$leaf = new Leaf(3.14); +echo "value: ", $leaf->val, "\n"; +?> +--EXPECT-- +prop type: float +get return: float +value: 3.14 diff --git a/Zend/tests/generics/inheritance/property/extends_set_hook.phpt b/Zend/tests/generics/inheritance/property/extends_set_hook.phpt new file mode 100644 index 000000000000..a06399be4801 --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_set_hook.phpt @@ -0,0 +1,32 @@ +--TEST-- +Property substitution: set hook value parameter type is substituted on a class extending a generic parent +--FILE-- + { + public T $val { set => $this->val = $value; } + public function __construct(T $v) { $this->val = $v; } +} + +class IntBox extends Box {} + +$rp = (new ReflectionClass('IntBox'))->getProperty('val'); +echo "prop type: ", $rp->getType()->getName(), "\n"; + +$set = $rp->getHook(PropertyHookType::Set); +echo "set param: ", $set->getParameters()[0]->getType()->getName(), "\n"; + +$ib = new IntBox(5); +$ib->val = 10; +echo $ib->val, "\n"; + +try { + $ib->val = "no"; +} catch (TypeError) { + echo "TypeError\n"; +} +?> +--EXPECT-- +prop type: int +set param: int +10 +TypeError diff --git a/Zend/tests/generics/inheritance/property/extends_transitive.phpt b/Zend/tests/generics/inheritance/property/extends_transitive.phpt new file mode 100644 index 000000000000..7f9298efd8e4 --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_transitive.phpt @@ -0,0 +1,24 @@ +--TEST-- +Property substitution: substitution composes through a generic intermediate class +--FILE-- + { + public T $val; +} + +class Mid extends Box {} +class Leaf extends Mid {} + +$rp = (new ReflectionClass('Leaf'))->getProperty('val'); +echo $rp->getType()->getName(), "\n"; + +$leaf = new Leaf; +$leaf->val = 3.14; +echo $leaf->val, "\n"; + +try { $leaf->val = "x"; } catch (TypeError) { echo "TypeError\n"; } +?> +--EXPECT-- +float +3.14 +TypeError diff --git a/Zend/tests/generics/inheritance/property/extends_two_classes_distinct_types.phpt b/Zend/tests/generics/inheritance/property/extends_two_classes_distinct_types.phpt new file mode 100644 index 000000000000..cea7bcfdd921 --- /dev/null +++ b/Zend/tests/generics/inheritance/property/extends_two_classes_distinct_types.phpt @@ -0,0 +1,25 @@ +--TEST-- +Property substitution: two classes extending the same generic parent get distinct property types +--FILE-- + { + public T $val; +} + +class IntBox extends Box {} +class StrBox extends Box {} + +$rcInt = (new ReflectionClass('IntBox'))->getProperty('val'); +$rcStr = (new ReflectionClass('StrBox'))->getProperty('val'); +echo $rcInt->getType()->getName(), "/", $rcStr->getType()->getName(), "\n"; + +$ib = new IntBox; $ib->val = 1; +$sb = new StrBox; $sb->val = "x"; + +try { $ib->val = "no"; } catch (TypeError) { echo "TypeError IntBox\n"; } +try { $sb->val = []; } catch (TypeError) { echo "TypeError StrBox\n"; } +?> +--EXPECT-- +int/string +TypeError IntBox +TypeError StrBox diff --git a/Zend/tests/generics/inheritance/self_and_static_with_generics.phpt b/Zend/tests/generics/inheritance/self_and_static_with_generics.phpt new file mode 100644 index 000000000000..ac66243bdf06 --- /dev/null +++ b/Zend/tests/generics/inheritance/self_and_static_with_generics.phpt @@ -0,0 +1,36 @@ +--TEST-- +Inheritance: self / static in a generic ancestor compose with parametric LSP +--FILE-- + { + abstract public function build(): T; + public static function make(): static { return new static; } +} + +class IntBuilder extends Builder { + public function build(): int { return 42; } +} + +interface Box { + public function unwrap(): T; + public function self_clone(): self; +} + +class IntBox implements Box { + public function __construct(private int $v) {} + public function unwrap(): int { return $this->v; } + public function self_clone(): self { return new self($this->v); } +} + +$ib = IntBuilder::make(); +echo get_class($ib), ":", $ib->build(), "\n"; + +$b = new IntBox(7); +echo $b->unwrap(), "\n"; +$c = $b->self_clone(); +echo get_class($c), ":", $c->unwrap(), "\n"; +?> +--EXPECT-- +IntBuilder:42 +7 +IntBox:7 diff --git a/Zend/tests/generics/inheritance/trait_use_args/trait_monomorph.phpt b/Zend/tests/generics/inheritance/trait_use_args/trait_monomorph.phpt new file mode 100644 index 000000000000..a81e43d381ae --- /dev/null +++ b/Zend/tests/generics/inheritance/trait_use_args/trait_monomorph.phpt @@ -0,0 +1,64 @@ +--TEST-- +Trait-use-with-args: each `use Foo;` binds to the canonical monomorph trait +--FILE-- + { + public T $value; + public function get(): T { return $this->value; } + public function set(T $v): void { $this->value = $v; } +} + +class IntHolder { + use Box; +} + +class StrHolder { + use Box; +} + +$i = new IntHolder(); +$i->set(42); +var_dump($i->get()); + +$s = new StrHolder(); +$s->set("hi"); +var_dump($s->get()); + +// Substituted property type is visible per use-site. +$rcI = new ReflectionClass(IntHolder::class); +var_dump($rcI->getTraitNames()); +echo "IntHolder::value type: ", $rcI->getProperty('value')->getType(), "\n"; + +$rcS = new ReflectionClass(StrHolder::class); +var_dump($rcS->getTraitNames()); +echo "StrHolder::value type: ", $rcS->getProperty('value')->getType(), "\n"; + +// The trait monomorphs are registered as traits. +var_dump(trait_exists("Box", false)); +var_dump(trait_exists("Box", false)); +var_dump((new ReflectionClass("Box"))->isTrait()); + +// Wrong-type set throws TypeError on the substituted signature. +try { + $i->set("not int"); +} catch (TypeError $e) { + echo "ok: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(42) +string(2) "hi" +array(1) { + [0]=> + string(8) "Box" +} +IntHolder::value type: int +array(1) { + [0]=> + string(11) "Box" +} +StrHolder::value type: string +bool(true) +bool(true) +bool(true) +ok: %sset()%sint%s diff --git a/Zend/tests/generics/limit/arg_list_return_type_128_rejected.phpt b/Zend/tests/generics/limit/arg_list_return_type_128_rejected.phpt new file mode 100644 index 000000000000..bcfc3cf2cf14 --- /dev/null +++ b/Zend/tests/generics/limit/arg_list_return_type_128_rejected.phpt @@ -0,0 +1,16 @@ +--TEST-- +Generics: 127 type arguments on a function return type is OK; 128 is a compile error +--FILE-- + {}"); +echo "OK\n"; + +$N = implode(",", array_fill(0, 128, "int")); +eval("function f128(): Box<{$N}> {}"); +?> +--EXPECTF-- +OK + +Fatal error: Cannot specify more than 127 generic type arguments (got 128) in %s : eval()'d code on line %d diff --git a/Zend/tests/generics/limit/param_list_class_128_rejected.phpt b/Zend/tests/generics/limit/param_list_class_128_rejected.phpt new file mode 100644 index 000000000000..2897d63b7d17 --- /dev/null +++ b/Zend/tests/generics/limit/param_list_class_128_rejected.phpt @@ -0,0 +1,15 @@ +--TEST-- +Generics: 127 type parameters on a class is OK; 128 is a compile error +--FILE-- + "T{$i}", range(0, 126))); +eval("class C127<{$names127}> {}"); +echo "OK\n"; + +$names128 = implode(",", array_map(fn($i) => "T{$i}", range(0, 127))); +eval("class C128<{$names128}> {}"); +?> +--EXPECTF-- +OK + +Fatal error: Cannot declare more than 127 generic type parameters (got 128) in %s : eval()'d code on line %d diff --git a/Zend/tests/generics/limit/turbofish_function_call_128_rejected.phpt b/Zend/tests/generics/limit/turbofish_function_call_128_rejected.phpt new file mode 100644 index 000000000000..7ea201aada64 --- /dev/null +++ b/Zend/tests/generics/limit/turbofish_function_call_128_rejected.phpt @@ -0,0 +1,16 @@ +--TEST-- +Generics: 127 type arguments on a function call turbofish is OK; 128 is a compile error +--FILE-- +(); }"); +echo "OK\n"; + +$N = implode(",", array_fill(0, 128, "int")); +eval("function g128() { f::<{$N}>(); }"); +?> +--EXPECTF-- +OK + +Fatal error: Cannot specify more than 127 generic type arguments (got 128) in %s : eval()'d code on line %d diff --git a/Zend/tests/generics/reflection/namespace_relative_extends_implements_uses.phpt b/Zend/tests/generics/reflection/namespace_relative_extends_implements_uses.phpt new file mode 100644 index 000000000000..87bb2d4aaca4 --- /dev/null +++ b/Zend/tests/generics/reflection/namespace_relative_extends_implements_uses.phpt @@ -0,0 +1,64 @@ +--TEST-- +Reflection: namespace-relative `extends`/`implements`/`use` keep their generic arguments in the side table +--FILE-- + {} +interface Iface<+T> {} +trait Mixin<+T> {} + +class FqnExt extends \NSRelExtImpUse\Base {} +class NsExt extends namespace\Base {} +class RelExt extends Base {} + +class FqnImpl implements \NSRelExtImpUse\Iface {} +class NsImpl implements namespace\Iface {} +class RelImpl implements Iface {} + +class FqnUse { use \NSRelExtImpUse\Mixin; } +class NsUse { use namespace\Mixin; } +class RelUse { use Mixin; } + +$singles = [ + 'extends FQN' => (new \ReflectionClass(FqnExt::class))->getGenericArgumentsForParentClass(), + 'extends ns' => (new \ReflectionClass(NsExt::class))->getGenericArgumentsForParentClass(), + 'extends rel' => (new \ReflectionClass(RelExt::class))->getGenericArgumentsForParentClass(), + 'use FQN' => (new \ReflectionClass(FqnUse::class))->getGenericArgumentsForUsedTrait(Mixin::class), + 'use ns' => (new \ReflectionClass(NsUse::class))->getGenericArgumentsForUsedTrait(Mixin::class), + 'use rel' => (new \ReflectionClass(RelUse::class))->getGenericArgumentsForUsedTrait(Mixin::class), +]; + +foreach ($singles as $label => $args) { + $rendered = array_map(static fn(\ReflectionNamedType $t): string => $t->getName(), $args); + printf("%-12s count=%d args=[%s]\n", $label, count($args), implode(', ', $rendered)); +} + +$plural = [ + 'impl FQN' => (new \ReflectionClass(FqnImpl::class))->getGenericArgumentsForParentInterface(Iface::class), + 'impl ns' => (new \ReflectionClass(NsImpl::class))->getGenericArgumentsForParentInterface(Iface::class), + 'impl rel' => (new \ReflectionClass(RelImpl::class))->getGenericArgumentsForParentInterface(Iface::class), +]; + +foreach ($plural as $label => $bindings) { + $rendered = array_map( + static fn(array $b): string => '[' . implode(', ', array_map( + static fn(\ReflectionNamedType $t): string => $t->getName(), + $b, + )) . ']', + $bindings, + ); + printf("%-12s bindings=%d sets=[%s]\n", $label, count($bindings), implode(', ', $rendered)); +} +?> +--EXPECT-- +extends FQN count=1 args=[int] +extends ns count=1 args=[int] +extends rel count=1 args=[int] +use FQN count=1 args=[int] +use ns count=1 args=[int] +use rel count=1 args=[int] +impl FQN bindings=1 sets=[[int]] +impl ns bindings=1 sets=[[int]] +impl rel bindings=1 sets=[[int]] diff --git a/Zend/tests/generics/reification/T_keyed_access_forms.phpt b/Zend/tests/generics/reification/T_keyed_access_forms.phpt new file mode 100644 index 000000000000..87a961137ab2 --- /dev/null +++ b/Zend/tests/generics/reification/T_keyed_access_forms.phpt @@ -0,0 +1,54 @@ +--TEST-- +Reification: every T-keyed expression form resolves through the frame's T-table +--FILE-- +($x): array { + return [ + "new T()" => get_class(new T()), + "T::NAME" => T::NAME, + "T::class" => T::class, + "T::make()" => get_class(T::make()), + "instanceof"=> $x instanceof T, + ]; +} + +var_dump(show::(new Foo())); +var_dump(show::(new Foo())); +?> +--EXPECT-- +array(5) { + ["new T()"]=> + string(3) "Foo" + ["T::NAME"]=> + string(3) "Foo" + ["T::class"]=> + string(3) "Foo" + ["T::make()"]=> + string(3) "Foo" + ["instanceof"]=> + bool(true) +} +array(5) { + ["new T()"]=> + string(3) "Bar" + ["T::NAME"]=> + string(3) "Bar" + ["T::class"]=> + string(3) "Bar" + ["T::make()"]=> + string(3) "Bar" + ["instanceof"]=> + bool(false) +} diff --git a/Zend/tests/generics/reification/bound_fallback.phpt b/Zend/tests/generics/reification/bound_fallback.phpt new file mode 100644 index 000000000000..3021dd02ac12 --- /dev/null +++ b/Zend/tests/generics/reification/bound_fallback.phpt @@ -0,0 +1,27 @@ +--TEST-- +Reification: when no binding is supplied, the parameter's class bound is the fallback +--FILE-- +(): T { + // No turbofish, no default, no inferable arg. T falls back to its bound. + return new T(); +} + +var_dump(makeDefault()->kind); + +// Inference still wins over the bound. +function makeFromArg(T $hint): T { + return new T(); +} +var_dump(makeFromArg(new Derived())->kind); + +// Turbofish still wins over the bound. +var_dump(makeDefault::()->kind); +?> +--EXPECT-- +string(4) "base" +string(7) "derived" +string(7) "derived" diff --git a/Zend/tests/generics/reification/catch_with_args.phpt b/Zend/tests/generics/reification/catch_with_args.phpt new file mode 100644 index 000000000000..aa97c7e02395 --- /dev/null +++ b/Zend/tests/generics/reification/catch_with_args.phpt @@ -0,0 +1,27 @@ +--TEST-- +Reification: catch with concrete type arguments matches the corresponding monomorph +--FILE-- + extends Exception {} + +// Throw a synthesized monomorph of Bag and catch it via the canonical name. +try { + throw new Bag::("payload"); +} catch (Bag $e) { + echo "caught Bag: ", $e->getMessage(), "\n"; +} + +// Wrong arg in the catch — the canonical names differ, so no match. +try { + try { + throw new Bag::("payload"); + } catch (Bag $e) { + echo "inner caught\n"; + } +} catch (Bag $e) { + echo "outer caught Bag (parent): ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +caught Bag: payload +outer caught Bag (parent): payload diff --git a/Zend/tests/generics/reification/catch_with_t_ref.phpt b/Zend/tests/generics/reification/catch_with_t_ref.phpt new file mode 100644 index 000000000000..e72cf3af9438 --- /dev/null +++ b/Zend/tests/generics/reification/catch_with_t_ref.phpt @@ -0,0 +1,26 @@ +--TEST-- +Reification: catch (Box $e) matches only when the thrown exception's monomorph args agree with T +--FILE-- + extends Exception {} + +function tryCatch(Exception $e): string { + try { + throw $e; + } catch (BoxedError $caught) { + return "matched BoxedError"; + } catch (Exception $other) { + return "fell through"; + } +} + +echo tryCatch::(new BoxedError::('payload')), "\n"; // matched +echo tryCatch::(new BoxedError::('payload')), "\n"; // fell through: different mono +echo tryCatch::(new Exception('plain')), "\n"; // fell through: not a Box* +echo tryCatch::(new BoxedError::('s')), "\n"; // matched +?> +--EXPECT-- +matched BoxedError +fell through +fell through +matched BoxedError diff --git a/Zend/tests/generics/reification/class_level_T_in_catch.phpt b/Zend/tests/generics/reification/class_level_T_in_catch.phpt new file mode 100644 index 000000000000..d0f7c5513f15 --- /dev/null +++ b/Zend/tests/generics/reification/class_level_T_in_catch.phpt @@ -0,0 +1,29 @@ +--TEST-- +Reification: catch (T $e) inside a method body matches against the class-level T binding +--FILE-- + { + public function trap(callable $fn): string { + try { + $fn(); + return "no-throw"; + } catch (T $e) { + return "caught " . $e::class . ": " . $e->getMessage(); + } + } +} + +$h = new Handler::(); +echo $h->trap(fn() => throw new MyExc("hi")), "\n"; // T = MyExc → caught +try { + $h->trap(fn() => throw new OtherExc("bye")); // T = MyExc → rethrows +} catch (Throwable $e) { + echo "outer ", $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +caught MyExc: hi +outer OtherExc: bye diff --git a/Zend/tests/generics/reification/class_level_T_in_method_body.phpt b/Zend/tests/generics/reification/class_level_T_in_method_body.phpt new file mode 100644 index 000000000000..bba1bc1d0f47 --- /dev/null +++ b/Zend/tests/generics/reification/class_level_T_in_method_body.phpt @@ -0,0 +1,56 @@ +--TEST-- +Reification: class-level T resolves at runtime inside instance method bodies +--FILE-- + { + public function summary(object $x): array { + return [ + "new T()" => get_class(new T()), + "T::KIND" => T::KIND, + "T::class" => T::class, + "T::make()" => get_class(T::make()), + "instanceof" => $x instanceof T, + ]; + } +} + +var_dump((new Box::())->summary(new Foo())); +var_dump((new Box::())->summary(new Foo())); +?> +--EXPECT-- +array(5) { + ["new T()"]=> + string(3) "Foo" + ["T::KIND"]=> + string(3) "foo" + ["T::class"]=> + string(3) "Foo" + ["T::make()"]=> + string(3) "Foo" + ["instanceof"]=> + bool(true) +} +array(5) { + ["new T()"]=> + string(3) "Bar" + ["T::KIND"]=> + string(3) "bar" + ["T::class"]=> + string(3) "Bar" + ["T::make()"]=> + string(3) "Bar" + ["instanceof"]=> + bool(false) +} diff --git a/Zend/tests/generics/reification/class_level_T_inherited.phpt b/Zend/tests/generics/reification/class_level_T_inherited.phpt new file mode 100644 index 000000000000..0eab27084809 --- /dev/null +++ b/Zend/tests/generics/reification/class_level_T_inherited.phpt @@ -0,0 +1,21 @@ +--TEST-- +Reification: a subclass `extends Box` carries the parent's T binding through inherited method bodies +--FILE-- + { + public function make(): T { + return new T(); + } +} + +class FooBox extends Box {} + +// FooBox::make is inherited from Box; the binding T=Foo on FooBox's parent +// must be visible to the inherited body via the called scope. +$fb = new FooBox(); +var_dump(get_class($fb->make())); +?> +--EXPECT-- +string(3) "Foo" diff --git a/Zend/tests/generics/reification/closure_bind_preserves_T.phpt b/Zend/tests/generics/reification/closure_bind_preserves_T.phpt new file mode 100644 index 000000000000..ce3381902407 --- /dev/null +++ b/Zend/tests/generics/reification/closure_bind_preserves_T.phpt @@ -0,0 +1,53 @@ +--TEST-- +Reification: Closure::bind / Closure::bindTo carry the captured T-table to the rebound closure +--FILE-- +(): Closure { + return function (T $x): T { return $x; }; +} + +$f = maker::(); + +// Closure::bindTo to a new instance of A (compatible) — same scope. +$rb = $f->bindTo(new A); +var_dump(get_class($rb(new A))); // accepts A + +try { + $rb(new B); // wrong concrete class +} catch (TypeError $e) { + echo "bindTo wrong: ", $e->getMessage(), "\n"; +} + +// Closure::bind static form — also propagates. +$rb2 = Closure::bind($f, new A); +var_dump(get_class($rb2(new A))); + +try { + $rb2(new B); +} catch (TypeError $e) { + echo "bind wrong: ", $e->getMessage(), "\n"; +} + +// bindTo(null) — strip the $this — still keeps the T-table. +$rb3 = $f->bindTo(null); +var_dump(get_class($rb3(new A))); +try { + $rb3(new B); +} catch (TypeError $e) { + echo "bindTo(null) wrong: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +string(1) "A" +bindTo wrong: %s must be of type A, B given%S +string(1) "A" +bind wrong: %s must be of type A, B given%S +string(1) "A" +bindTo(null) wrong: %s must be of type A, B given%S diff --git a/Zend/tests/generics/reification/closure_call_preserves_T.phpt b/Zend/tests/generics/reification/closure_call_preserves_T.phpt new file mode 100644 index 000000000000..b94ab23d3682 --- /dev/null +++ b/Zend/tests/generics/reification/closure_call_preserves_T.phpt @@ -0,0 +1,57 @@ +--TEST-- +Reification: Closure::call propagates the captured T-table into the fake closure that actually runs the body +--FILE-- +(): Closure { + return function (T $x): string { + $this->store = $x; + return get_class($x); + }; +} + +$f = maker::(); +$h = new Holder; + +// Positive: A and its subclass B both satisfy T = A. +var_dump($f->call($h, new A)); +var_dump($f->call($h, new B)); + +// Negative: a value that doesn't satisfy T fires with the resolved T. +class Unrelated {} +try { + $f->call($h, new Unrelated); +} catch (TypeError $e) { + echo "rejected: ", $e->getMessage(), "\n"; +} + +// Variadic + call: every element checked against the captured T. +function vmaker(): Closure { + return function (T ...$xs): int { return count($xs); }; +} + +$vf = vmaker::(); +var_dump($vf->call($h, new A, new B, new A)); + +try { + $vf->call($h, new A, new Unrelated, new A); +} catch (TypeError $e) { + echo "rejected2: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +string(1) "A" +string(1) "B" +rejected: %s must be of type A, Unrelated given%S +int(3) +rejected2: %s must be of type A, Unrelated given%S diff --git a/Zend/tests/generics/reification/closure_captures_T.phpt b/Zend/tests/generics/reification/closure_captures_T.phpt new file mode 100644 index 000000000000..d53c5a2fc5a1 --- /dev/null +++ b/Zend/tests/generics/reification/closure_captures_T.phpt @@ -0,0 +1,44 @@ +--TEST-- +Reification: a closure created inside a generic frame captures that frame's T-table, so the closure's body resolves T to the binding in effect at creation time +--FILE-- +(): Closure { + return fn() => T::class; +} +echo nameOf::()(), "\n"; +echo nameOf::()(), "\n"; + +// A closure with a T-typed parameter rejects values that don't satisfy the +// CAPTURED binding, not just the parameter's erased bound. +function id(): Closure { + return function(T $x): T { return $x; }; +} +$fooId = id::(); +$f = $fooId(new Foo); +var_dump(get_class($f)); + +try { + $fooId(new Bar); +} catch (TypeError $e) { + echo "rejected wrong class: ", $e->getMessage(), "\n"; +} + +// Scalars are rejected against the resolved T (Foo) — the captured binding +// is more specific than the parameter's erased object bound. +try { + $fooId(42); +} catch (TypeError $e) { + echo "rejected scalar: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Foo +Bar +string(3) "Foo" +rejected wrong class: %s must be of type Foo, Bar given%S +rejected scalar: %s must be of type Foo, int given%S diff --git a/Zend/tests/generics/reification/closure_from_callable_preserves_T.phpt b/Zend/tests/generics/reification/closure_from_callable_preserves_T.phpt new file mode 100644 index 000000000000..063b4ddc9dce --- /dev/null +++ b/Zend/tests/generics/reification/closure_from_callable_preserves_T.phpt @@ -0,0 +1,27 @@ +--TEST-- +Reification: Closure::fromCallable on a generic closure preserves the captured T-table (returns the same closure) +--FILE-- +(): Closure { + return function (T $x): string { return get_class($x); }; +} + +$f = maker::(); +$wrapped = Closure::fromCallable($f); + +// Positive: behaves like the original — T is still A. +var_dump($wrapped(new A)); + +// Negative: wrong concrete class still fires with the resolved T. +try { + $wrapped(new B); +} catch (TypeError $e) { + echo "rejected: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +string(1) "A" +rejected: %s must be of type A, B given%S diff --git a/Zend/tests/generics/reification/forwarded_t_ref_value_check.phpt b/Zend/tests/generics/reification/forwarded_t_ref_value_check.phpt new file mode 100644 index 000000000000..08015a300682 --- /dev/null +++ b/Zend/tests/generics/reification/forwarded_t_ref_value_check.phpt @@ -0,0 +1,87 @@ +--TEST-- +Reification: forwarded T-ref in turbofish (id::(...) inside nested) resolves the value-arg check through the caller's bindings +--FILE-- +(T $x): T { return $x; } + +// Same-type forwarding: U binds to Dog at the outer call, the inner +// id::($x) forwards U into id's T, and id should accept Dog as Dog — +// not as a literal "U" type. +function nested(U $x): U { + return id::($x); +} +var_dump(nested::(new Dog)); + +// Mismatch caught against the *resolved* class, not the forwarded T-ref. +// The error message must name the bound class ("Dog"), not the parameter +// letter ("U"). +function pass_through(mixed $x): U { + return id::($x); +} +try { + pass_through::(new Cat); +} catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; +} + +// Forwarded scalar binding: U = int, the value 42 satisfies id's T = int. +function nested_scalar(U $x): U { + return id::($x); +} +var_dump(nested_scalar::(42)); + +// Forwarded scalar mismatch caught against the resolved scalar type: +// pass_through_scalar(mixed $x) doesn't constrain $x at its own +// boundary, so the string "hello" reaches the inner id::(...) call. +// id's T is resolved to int via U, and the value check fires with the +// resolved type ("int"), not the literal T-ref letter. +function pass_through_scalar(mixed $x): U { + return id::($x); +} +try { + pass_through_scalar::("hello"); +} catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; +} + +// Composite forwarded bindings: a union arg threaded through a forwarding +// wrapper still names the union ("int|string") in the error, not the +// T-ref letter. Same with intersection. +try { + pass_through_scalar::([1, 2]); +} catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; +} + +// Intersection forwarded through a wrapper: positive case (a value +// implementing both interfaces) passes; negative reports the resolved +// intersection ("Fooable&Barable"), not the T-ref letter. +interface Fooable {} +interface Barable {} +class Both implements Fooable, Barable {} +class FooOnly implements Fooable {} + +function pass_through_obj(object $x): U { + return id::($x); +} +var_dump(pass_through_obj::(new Both)); +try { + pass_through_obj::(new FooOnly); +} catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +object(Dog)#%d (0) { +} +caught: id(): Argument #1 ($x) must be of type Dog, Cat given +int(42) +caught: id(): Argument #1 ($x) must be of type int, string given +caught: id(): Argument #1 ($x) must be of type string|int, array given +object(Both)#%d (0) { +} +caught: id(): Argument #1 ($x) must be of type Fooable&Barable, FooOnly given diff --git a/Zend/tests/generics/reification/func_get_type_args.phpt b/Zend/tests/generics/reification/func_get_type_args.phpt new file mode 100644 index 000000000000..0730b21c6775 --- /dev/null +++ b/Zend/tests/generics/reification/func_get_type_args.phpt @@ -0,0 +1,34 @@ +--TEST-- +Reification: func_get_type_args() reflects turbofish, defaults, and inference +--FILE-- +(T $x): array { + return func_get_type_args(); +} + +var_dump(inspect::(new Foo())); // explicit turbofish for T and U +var_dump(inspect::(new Bar())); // U falls back to its default Foo +var_dump(inspect(new Bar())); // T inferred from arg, U default +?> +--EXPECT-- +array(2) { + ["T"]=> + string(3) "Foo" + ["U"]=> + string(3) "Bar" +} +array(2) { + ["T"]=> + string(3) "Bar" + ["U"]=> + string(3) "Foo" +} +array(2) { + ["T"]=> + string(3) "Bar" + ["U"]=> + string(3) "Foo" +} diff --git a/Zend/tests/generics/reification/function_level_T_in_catch.phpt b/Zend/tests/generics/reification/function_level_T_in_catch.phpt new file mode 100644 index 000000000000..2e9f3a43be55 --- /dev/null +++ b/Zend/tests/generics/reification/function_level_T_in_catch.phpt @@ -0,0 +1,26 @@ +--TEST-- +Reification: catch (T $e) inside a function body matches against the function-level T binding +--FILE-- +(callable $fn): string { + try { + $fn(); + return "no-throw"; + } catch (T $e) { + return "caught " . $e::class . ": " . $e->getMessage(); + } +} + +echo trap::(fn() => throw new MyExc("a")), "\n"; // matches +try { + trap::(fn() => throw new OtherExc("b")); // doesn't match +} catch (Throwable $e) { + echo "outer ", $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +caught MyExc: a +outer OtherExc: b diff --git a/Zend/tests/generics/reification/generator_preserves_T.phpt b/Zend/tests/generics/reification/generator_preserves_T.phpt new file mode 100644 index 000000000000..2c4d4c3e43d9 --- /dev/null +++ b/Zend/tests/generics/reification/generator_preserves_T.phpt @@ -0,0 +1,26 @@ +--TEST-- +Reification: a generator's T-table is preserved across yield/suspend and resume +--FILE-- +(): Generator { + yield T::class; + yield T::class; + yield T::class; +} + +$g = gen::(); +foreach ($g as $v) echo $v, "\n"; + +$g = gen::(); +foreach ($g as $v) echo $v, "\n"; +?> +--EXPECT-- +Foo +Foo +Foo +Bar +Bar +Bar diff --git a/Zend/tests/generics/reification/inference_basic.phpt b/Zend/tests/generics/reification/inference_basic.phpt new file mode 100644 index 000000000000..9c05c291b024 --- /dev/null +++ b/Zend/tests/generics/reification/inference_basic.phpt @@ -0,0 +1,24 @@ +--TEST-- +Reification: T is inferred from an argument whose declared type is exactly T; the substituted parameter type is enforced when turbofish disagrees with the value +--FILE-- +(T $x): string { + return T::class; +} + +echo kind(new Foo()), "\n"; +echo kind(new Bar()), "\n"; + +try { + kind::(new Bar()); +} catch (TypeError $e) { + echo "TypeError: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Foo +Bar +TypeError: kind(): Argument #1 ($x) must be of type Foo, Bar given, called in %s on line %d diff --git a/Zend/tests/generics/reification/instanceof_distinguishes_monos.phpt b/Zend/tests/generics/reification/instanceof_distinguishes_monos.phpt new file mode 100644 index 000000000000..9d71095bbc65 --- /dev/null +++ b/Zend/tests/generics/reification/instanceof_distinguishes_monos.phpt @@ -0,0 +1,25 @@ +--TEST-- +Reification: instanceof distinguishes monos by their canonical argument tuple +--FILE-- + {} + +$bd = new Box::(); +$ba = new Box::(); + +// Each mono extends the bare class but is otherwise distinct. +var_dump($bd instanceof Box); // true: parent-name chain +var_dump($bd instanceof Box); // true: same canonical mono +var_dump($bd instanceof Box); // false: invariant distinction +var_dump($ba instanceof Box); // false +var_dump($ba instanceof Box); // true +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) +bool(false) +bool(true) diff --git a/Zend/tests/generics/reification/instanceof_nested_t_ref.phpt b/Zend/tests/generics/reification/instanceof_nested_t_ref.phpt new file mode 100644 index 000000000000..eff113d3e711 --- /dev/null +++ b/Zend/tests/generics/reification/instanceof_nested_t_ref.phpt @@ -0,0 +1,26 @@ +--TEST-- +Reification: nested T-refs (instanceof Outer>) substitute through and resolve the outermost monomorph +--FILE-- + {} +class Outer {} + +class Holder { + public function isOuterOfBox(mixed $x): bool { + return $x instanceof Outer>; + } +} + +$intHolder = new Holder::(); +$strHolder = new Holder::(); + +var_dump($intHolder->isOuterOfBox(new Outer::>)); // true +var_dump($intHolder->isOuterOfBox(new Outer::>)); // false +var_dump($strHolder->isOuterOfBox(new Outer::>)); // true +var_dump($strHolder->isOuterOfBox(new Outer::)); // false: outer mono name differs +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) diff --git a/Zend/tests/generics/reification/instanceof_variance.phpt b/Zend/tests/generics/reification/instanceof_variance.phpt new file mode 100644 index 000000000000..6be079f63d10 --- /dev/null +++ b/Zend/tests/generics/reification/instanceof_variance.phpt @@ -0,0 +1,46 @@ +--TEST-- +Reification: instanceof respects variance markers on the generic base +--FILE-- + {} // invariant +class Producer<+T : object> {} // covariant +class Consumer<-T : object> {} // contravariant + +$dogBox = new Box::(); +$dogProd = new Producer::(); +$animalCons = new Consumer::(); + +// Invariant: only same-arg passes. +var_dump($dogBox instanceof Box); // true (identical) +var_dump($dogBox instanceof Box); // false +var_dump($dogBox instanceof Box); // false + +// Covariant: Dog <: Animal, so Producer <: Producer. +var_dump($dogProd instanceof Producer); // true +var_dump($dogProd instanceof Producer); // false +var_dump($dogProd instanceof Producer); // true + +// Contravariant: Animal :> Dog, so Consumer <: Consumer. +var_dump($animalCons instanceof Consumer); // true +var_dump($animalCons instanceof Consumer); // true +var_dump($animalCons instanceof Consumer);// true + +// Reverse contravariant fails. +$dogCons = new Consumer::(); +var_dump($dogCons instanceof Consumer); // false +?> +--EXPECT-- +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) diff --git a/Zend/tests/generics/reification/instanceof_with_t_ref_class_level.phpt b/Zend/tests/generics/reification/instanceof_with_t_ref_class_level.phpt new file mode 100644 index 000000000000..21a3bda926df --- /dev/null +++ b/Zend/tests/generics/reification/instanceof_with_t_ref_class_level.phpt @@ -0,0 +1,35 @@ +--TEST-- +Reification: instanceof Box with class-level T resolves against the called scope's monomorph args +--FILE-- + {} + +class Outer { + public function isBox(mixed $x): bool { + return $x instanceof Box; + } +} + +$animalOuter = new Outer::(); +$dogOuter = new Outer::(); +$intOuter = new Outer::(); + +class Animal {} +class Dog extends Animal {} + +var_dump($animalOuter->isBox(new Box::)); // true +var_dump($animalOuter->isBox(new Box::)); // false: nominal monos +var_dump($dogOuter->isBox(new Box::)); // true +var_dump($dogOuter->isBox(new Box::)); // false +var_dump($intOuter->isBox(new Box::)); // true +var_dump($intOuter->isBox(new Box::)); // false +var_dump($animalOuter->isBox(42)); // false: not an object +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) diff --git a/Zend/tests/generics/reification/instanceof_with_t_ref_function_level.phpt b/Zend/tests/generics/reification/instanceof_with_t_ref_function_level.phpt new file mode 100644 index 000000000000..8e9707cf117e --- /dev/null +++ b/Zend/tests/generics/reification/instanceof_with_t_ref_function_level.phpt @@ -0,0 +1,20 @@ +--TEST-- +Reification: instanceof Box with function-level T resolves against the current frame's turbofish bindings +--FILE-- + {} + +function isBoxOf(mixed $x): bool { + return $x instanceof Box; +} + +var_dump(isBoxOf::(new Box::)); // true +var_dump(isBoxOf::(new Box::)); // false +var_dump(isBoxOf::(new Box::));// true +var_dump(isBoxOf::(42)); // false: not an object +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(false) diff --git a/Zend/tests/generics/reification/interface_dispatched_method.phpt b/Zend/tests/generics/reification/interface_dispatched_method.phpt new file mode 100644 index 000000000000..3fc6ce4efa46 --- /dev/null +++ b/Zend/tests/generics/reification/interface_dispatched_method.phpt @@ -0,0 +1,27 @@ +--TEST-- +Reification: a generic method called via an interface-typed variable still resolves T +--FILE-- +(): U; +} + +class Factory implements Maker { + public function build(): U { + return new U(); + } +} + +class Foo {} +class Bar {} + +function callIt(Maker $m, string $which): object { + return $which === "foo" ? $m->build::() : $m->build::(); +} + +var_dump(get_class(callIt(new Factory(), "foo"))); +var_dump(get_class(callIt(new Factory(), "bar"))); +?> +--EXPECT-- +string(3) "Foo" +string(3) "Bar" diff --git a/Zend/tests/generics/reification/method_level_T.phpt b/Zend/tests/generics/reification/method_level_T.phpt new file mode 100644 index 000000000000..49c15ffbdffe --- /dev/null +++ b/Zend/tests/generics/reification/method_level_T.phpt @@ -0,0 +1,20 @@ +--TEST-- +Reification: a generic method on a non-generic class can use T inside its body +--FILE-- +(): T { + return new T(); + } +} + +$f = new Factory(); +var_dump($f->build::()->tag); +var_dump($f->build::()->tag); +?> +--EXPECT-- +string(3) "foo" +string(3) "bar" diff --git a/Zend/tests/generics/reification/monomorph_implements_substitution.phpt b/Zend/tests/generics/reification/monomorph_implements_substitution.phpt new file mode 100644 index 000000000000..f55fd47bd82f --- /dev/null +++ b/Zend/tests/generics/reification/monomorph_implements_substitution.phpt @@ -0,0 +1,41 @@ +--TEST-- +Reification: a monomorph of `B implements I` should report `is_a I` true +--FILE-- + implements I` is monomorphized as `B`, +// the implements binding has to be substituted so that `B` is also +// known to implement `I`. Otherwise `instanceof I` / +// `is_a(..., 'I')` returns false even though the type relationship +// holds, and property writes typed `I` reject `B` values. + +interface I<+T> {} +class B implements I {} + +// 1) Direct monomorph +$b = new B::(); +var_dump(is_a($b, 'I')); +var_dump(is_a($b, 'B')); +$mono = 'B'; +var_dump($b instanceof $mono); + +// 2) Non-generic subclass of a monomorph +class StrB extends B {} +$s = new StrB(); +var_dump(is_a($s, 'I')); +var_dump(is_a($s, 'B')); + +// 3) Assignment to a property typed I accepts a B +class Holder { + public I $val; +} +$h = new Holder::(); +$h->val = new B::(); +var_dump($h->val::class); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +string(9) "B" diff --git a/Zend/tests/generics/reification/multiple_inference_targets_agree.phpt b/Zend/tests/generics/reification/multiple_inference_targets_agree.phpt new file mode 100644 index 000000000000..a41442ee15b4 --- /dev/null +++ b/Zend/tests/generics/reification/multiple_inference_targets_agree.phpt @@ -0,0 +1,24 @@ +--TEST-- +Reification: T appearing in multiple arg positions — the first hit wins (subsequent objects of compatible types don't update) +--FILE-- +(T $a, T $b): string { + return T::class; +} + +// Both args are Foo — T inferred as Foo +var_dump(pair(new Foo(), new Foo())); + +// First arg pins T to Bar; second is also a Bar, fine +var_dump(pair(new Bar(), new Bar())); + +// First arg Foo, second Bar — T pinned to Foo (first wins) +var_dump(pair(new Foo(), new Bar())); +?> +--EXPECT-- +string(3) "Foo" +string(3) "Bar" +string(3) "Foo" diff --git a/Zend/tests/generics/reification/named_with_args_t_in_property.phpt b/Zend/tests/generics/reification/named_with_args_t_in_property.phpt new file mode 100644 index 000000000000..7c06d2f76ce3 --- /dev/null +++ b/Zend/tests/generics/reification/named_with_args_t_in_property.phpt @@ -0,0 +1,56 @@ +--TEST-- +Reification: a property typed `I` (T inside a generic class type arg) substitutes T → binding for the monomorph +--FILE-- + $val` on a generic class. When the class is +// monomorphized (e.g. `new Box::()`), the property type should +// substitute T → string and the runtime check should accept values that +// satisfy `I`. The bug was that `zend_substitute_leaf_type_param` +// didn't recurse into NAMED_WITH_ARGS payloads, so the property stayed +// typed as the unsubstituted `I` and any assignment failed with +// "Cannot assign ... of type I". + +interface I<+T> {} + +class StrImpl implements I {} +class IntImpl implements I {} + +class Box { + public I $val; +} + +// Direct monomorph use. +$b = new Box::(); +$b->val = new StrImpl(); +var_dump($b->val::class); + +// Wrong-arg implementation rejected. +try { + $b->val = new IntImpl(); +} catch (TypeError $e) { + echo "1: ", $e->getMessage(), "\n"; +} + +// Inherited subclass case: same substitution applies when the property is +// touched on an instance of a non-generic child. Use `mixed` on the ctor +// so the bad value reaches the property assignment site, exercising the +// inherited property's substituted type rather than the ctor's own type. +class StringBox extends Box { + public function __construct(mixed $val) { + $this->val = $val; + } +} +$sb = new StringBox(new StrImpl()); +var_dump($sb->val::class); + +try { + new StringBox(new IntImpl()); +} catch (TypeError $e) { + echo "2: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +string(7) "StrImpl" +1: Cannot assign IntImpl to property %s::$val of type I +string(7) "StrImpl" +2: Cannot assign IntImpl to property %s::$val of type I diff --git a/Zend/tests/generics/reification/new_turbofish_with_class_t_ref.phpt b/Zend/tests/generics/reification/new_turbofish_with_class_t_ref.phpt new file mode 100644 index 000000000000..f1d7b6274db4 --- /dev/null +++ b/Zend/tests/generics/reification/new_turbofish_with_class_t_ref.phpt @@ -0,0 +1,48 @@ +--TEST-- +Reification: `new SelfClass::(...)` inside a generic class method resolves T against the instance's monomorph args at synth time +--FILE-- +(...)` +// using its own class-level T's. Runtime synth must walk the called scope +// up to the lexical class's monomorph descendant to resolve the binding. + +final readonly class Bag { + public function __construct(public array $items = []) {} + + public function withItem(T $item): Bag { + $items = $this->items; + $items[] = $item; + // Forward T explicitly — must resolve against the current instance's + // monomorph (Bag stays Bag, not Bag). + return new Bag::($items); + } +} + +$b = new Bag::([1, 2, 3]); +var_dump($b::class); +$b = $b->withItem(4); +var_dump($b::class); +$b = $b->withItem(5); +var_dump($b::class); + +$s = new Bag::(['a']); +var_dump($s::class); +$s = $s->withItem('b'); +var_dump($s::class); + +// Calling withItem on a bare-default Bag still works — forwarding +// resolves T to its (default) mixed binding from the monomorph. +$d = new Bag(); +var_dump($d::class); +$d = $d->withItem(42); +var_dump($d::class); +?> +--EXPECT-- +string(8) "Bag" +string(8) "Bag" +string(8) "Bag" +string(11) "Bag" +string(11) "Bag" +string(10) "Bag" +string(10) "Bag" diff --git a/Zend/tests/generics/reification/new_turbofish_with_outer_t_ref.phpt b/Zend/tests/generics/reification/new_turbofish_with_outer_t_ref.phpt new file mode 100644 index 000000000000..7bdfb9ac92de --- /dev/null +++ b/Zend/tests/generics/reification/new_turbofish_with_outer_t_ref.phpt @@ -0,0 +1,61 @@ +--TEST-- +Reification: `new Box::(...)` inside `function(...)` resolves T against the caller frame's T-table at synth time, not the literal ref +--FILE-- +" class with un-resolvable +// arg_info and runtime TypeErrors mentioning the literal parameter name). + +final readonly class Box { + public function __construct(public array $items = []) {} + public function get(TNode $key): mixed { return $this->items[$key] ?? null; } +} + +function make(): Box { + return new Box::([]); +} + +function withItem(Box $b, TNode $key, mixed $val): Box { + $items = $b->items; + $items[$key] = $val; + return new Box::($items); +} + +// Concrete turbofish on the outer call — inner `new Box::(...)` +// must resolve to , not . +$b = make::(); +var_dump($b::class); + +$b = withItem::($b, 'a', 1); +$b = withItem::($b, 'b', 2); +var_dump($b::class); + +// Method that's substituted on the monomorph should accept the bound key type. +var_dump($b->get('a')); +var_dump($b->get('b')); + +// Repeat with different turbofish — distinct monomorph, no stale binding leak. +$s = make::(); +var_dump($s::class); +$s = withItem::($s, 0, 'zero'); +var_dump($s::class); +var_dump($s->get(0)); + +// Defaults case: turbofish-less call falls back to declared defaults +// (mixed, mixed), and inner `new Box::(...)` resolves against +// those — producing Box, not Box. +$m = make(); +var_dump($m::class); +?> +--EXPECT-- +string(15) "Box" +string(15) "Box" +int(1) +int(2) +string(15) "Box" +string(15) "Box" +string(4) "zero" +string(16) "Box" diff --git a/Zend/tests/generics/reification/property_t_reified.phpt b/Zend/tests/generics/reification/property_t_reified.phpt new file mode 100644 index 000000000000..f8da7dfec662 --- /dev/null +++ b/Zend/tests/generics/reification/property_t_reified.phpt @@ -0,0 +1,64 @@ +--TEST-- +Reification: typed properties whose declared type is `T` check the reified binding on assignment +--FILE-- +() — assignments to $value must +// check against int, not the erased "mixed" bound. + +class Box { + public T $value; +} + +$b = new Box::(); +$b->value = 42; +var_dump($b->value); + +try { + $b->value = "not-an-int"; +} catch (TypeError $e) { + echo "1: ", $e->getMessage(), "\n"; +} + +// Object T case. +class Item {} +class Other {} + +class Holder { + public T $thing; +} + +$h = new Holder::(); +$h->thing = new Item; +var_dump(get_class($h->thing)); + +try { + $h->thing = new Other; +} catch (TypeError $e) { + echo "2: ", $e->getMessage(), "\n"; +} + +// Nullable T. +class MaybeBox { + public ?T $value = null; +} + +$mb = new MaybeBox::(); +$mb->value = 7; +var_dump($mb->value); +$mb->value = null; +var_dump($mb->value); + +try { + $mb->value = "wrong"; +} catch (TypeError $e) { + echo "3: ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +int(42) +1: Cannot assign string to property Box::$value of type int +string(4) "Item" +2: Cannot assign Other to property Holder::$thing of type Item +int(7) +NULL +3: Cannot assign string to property MaybeBox::$value of type ?int diff --git a/Zend/tests/generics/reification/recursion_per_frame_table.phpt b/Zend/tests/generics/reification/recursion_per_frame_table.phpt new file mode 100644 index 000000000000..9bddb9205798 --- /dev/null +++ b/Zend/tests/generics/reification/recursion_per_frame_table.phpt @@ -0,0 +1,43 @@ +--TEST-- +Reification: each call frame has its own T-table; recursion across different bindings does not leak +--FILE-- +(int $depth): array { + if ($depth === 0) { + return ["T" => T::class, "U" => U::class]; + } + // Recurse with T and U swapped; on return our slot must still read A/B. + $inner = pair::($depth - 1); + return [ + "outer_T" => T::class, + "outer_U" => U::class, + "inner" => $inner, + ]; +} + +var_dump(pair::(2)); +?> +--EXPECT-- +array(3) { + ["outer_T"]=> + string(1) "A" + ["outer_U"]=> + string(1) "B" + ["inner"]=> + array(3) { + ["outer_T"]=> + string(1) "B" + ["outer_U"]=> + string(1) "A" + ["inner"]=> + array(2) { + ["T"]=> + string(1) "A" + ["U"]=> + string(1) "B" + } + } +} diff --git a/Zend/tests/generics/reification/return_type_reified.phpt b/Zend/tests/generics/reification/return_type_reified.phpt new file mode 100644 index 000000000000..04f3ba7f0aeb --- /dev/null +++ b/Zend/tests/generics/reification/return_type_reified.phpt @@ -0,0 +1,63 @@ +--TEST-- +Reification: VERIFY_RETURN_TYPE checks the reified T binding, not the erased bound +--FILE-- +(T $x): T { return $x; } +function ret_nonnumeric_string(T $x): T { return "abc"; } +function ret_array(T $x): T { return [1, 2]; } +function maybe(T $x): ?T { return null; } +function lift(T $x): array { return [$x]; } + +// Positive: returning the correct concrete T passes. +var_dump(id::(42)); +var_dump(id::("hi")); + +// Negative: returning a wrong, non-coercible concrete type fires with the +// resolved T, not the erased "mixed". +// - "abc" (non-numeric string) cannot coerce to int even in weak mode. +// - array cannot coerce to string at all. +try { + ret_nonnumeric_string::(1); +} catch (TypeError $e) { + echo "1: ", $e->getMessage(), "\n"; +} +try { + ret_array::("x"); +} catch (TypeError $e) { + echo "2: ", $e->getMessage(), "\n"; +} + +// `?T`: nullable return on a T-typed function still accepts null when bound +// to a non-nullable concrete type. The reified check preserves the nullable +// bit from the outer T-ref. +var_dump(maybe::(0)); + +// Non-T return type (`array`) is unaffected by the reified-return path — +// goes through the normal erased check. +var_dump(lift::(7)); + +// Object T: returning the wrong class names the bound class in the error. +class A {} +class B {} +function obj(T $x): T { return new B(); } +try { + obj::(new A()); +} catch (TypeError $e) { + echo "3: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(42) +string(2) "hi" +1: ret_nonnumeric_string(): Return value must be of type int, string returned +2: ret_array(): Return value must be of type string, array returned +NULL +array(1) { + [0]=> + int(7) +} +3: obj(): Return value must be of type A, B returned diff --git a/Zend/tests/generics/reification/return_type_reified_strict.phpt b/Zend/tests/generics/reification/return_type_reified_strict.phpt new file mode 100644 index 000000000000..16a9855f3fbe --- /dev/null +++ b/Zend/tests/generics/reification/return_type_reified_strict.phpt @@ -0,0 +1,44 @@ +--TEST-- +Reification: VERIFY_RETURN_TYPE under strict_types catches coercible mismatches the weak path would silently accept +--FILE-- +(T $x): T { return 999; } +function ret_str(T $x): T { return "1.5"; } +function ret_float(T $x): T { return 3.14; } + +// Under strict_types, an int return from a function bound to T=string must +// throw — weak mode would silently coerce to "999". +try { + ret_int::("a"); +} catch (TypeError $e) { + echo "1: ", $e->getMessage(), "\n"; +} + +// Numeric string returned where T=int — weak would coerce; strict throws. +try { + ret_str::(0); +} catch (TypeError $e) { + echo "2: ", $e->getMessage(), "\n"; +} + +// Float returned where T=int — weak would coerce; strict throws. +try { + ret_float::(0); +} catch (TypeError $e) { + echo "3: ", $e->getMessage(), "\n"; +} + +// Positive: correct concrete types still pass. +var_dump(ret_int::(0)); +var_dump(ret_str::("a")); +var_dump(ret_float::(0.0)); +?> +--EXPECTF-- +1: ret_int(): Return value must be of type string, int returned +2: ret_str(): Return value must be of type int, string returned +3: ret_float(): Return value must be of type int, float returned +int(999) +string(3) "1.5" +float(3.14) diff --git a/Zend/tests/generics/reification/turbofish_chains_through_outer.phpt b/Zend/tests/generics/reification/turbofish_chains_through_outer.phpt new file mode 100644 index 000000000000..ebb7567f28a0 --- /dev/null +++ b/Zend/tests/generics/reification/turbofish_chains_through_outer.phpt @@ -0,0 +1,21 @@ +--TEST-- +Reification: turbofish whose arg is an outer T resolves against the caller's T-table +--FILE-- +(): string { + return U::class; +} + +function outer(): string { + // The turbofish :: here doesn't have a literal class name; it names + // the enclosing parameter T. The runtime must look T up in the caller + // frame's T-table and pass that to inner. + return inner::(); +} + +echo outer::(), "\n"; +?> +--EXPECT-- +Foo diff --git a/Zend/tests/generics/reification/turbofish_new_T.phpt b/Zend/tests/generics/reification/turbofish_new_T.phpt new file mode 100644 index 000000000000..b70952227b79 --- /dev/null +++ b/Zend/tests/generics/reification/turbofish_new_T.phpt @@ -0,0 +1,17 @@ +--TEST-- +Reification: explicit turbofish populates the T-table; `new T()` in body resolves to the supplied class +--FILE-- +(): T { + return new T(); +} + +var_dump(make::()->kind); +var_dump(make::()->kind); +?> +--EXPECT-- +string(3) "foo" +string(3) "bar" diff --git a/Zend/tests/generics/reification/union_with_t_in_property.phpt b/Zend/tests/generics/reification/union_with_t_in_property.phpt new file mode 100644 index 000000000000..2d594bbeaf0b --- /dev/null +++ b/Zend/tests/generics/reification/union_with_t_in_property.phpt @@ -0,0 +1,63 @@ +--TEST-- +Reification: a union `T|null` (and other unions containing T) on a property reifies the T-ref the same way `?T` does +--FILE-- + { + public T|null $w; + public function __construct(T|null $w) { $this->w = $w; } +} + +class TInt { + public T|int $w; + public function __construct(T|int $w) { $this->w = $w; } +} + +class Foo {} +class Bar {} +class Baz {} + +class TFoo { + public T|Foo $w; + public function __construct(T|Foo $w) { $this->w = $w; } +} + +// T|null with primitive T accepts T and null and rejects others. +$a = new TNull::(5); +var_dump($a->w); +$a->w = null; +var_dump($a->w); +try { $a->w = "x"; } catch (TypeError $e) { echo "1: ", $e->getMessage(), "\n"; } + +// T|int: T=string accepts strings and ints; under strict_types, a float is +// rejected outright. +$b = new TInt::("hi"); +var_dump($b->w); +$b->w = 7; +var_dump($b->w); +try { $b->w = 1.5; } catch (TypeError $e) { echo "2: ", $e->getMessage(), "\n"; } + +// T|Foo: T=Bar accepts Bar or Foo, rejects an unrelated class. +$c = new TFoo::(new Bar); +var_dump($c->w::class); +$c->w = new Foo; +var_dump($c->w::class); +try { $c->w = new Baz; } catch (TypeError $e) { echo "3: ", $e->getMessage(), "\n"; } +?> +--EXPECT-- +int(5) +NULL +1: Cannot assign string to property TNull::$w of type ?int +string(2) "hi" +int(7) +2: Cannot assign float to property TInt::$w of type string|int +string(3) "Bar" +string(3) "Foo" +3: Cannot assign Baz to property TFoo::$w of type Bar|Foo diff --git a/Zend/tests/generics/reification/variadic_t_in_closure.phpt b/Zend/tests/generics/reification/variadic_t_in_closure.phpt new file mode 100644 index 000000000000..696944ae10ea --- /dev/null +++ b/Zend/tests/generics/reification/variadic_t_in_closure.phpt @@ -0,0 +1,55 @@ +--TEST-- +Reification: variadic T parameter is checked even when T comes from a closure's captured frame, not the closure's own turbofish +--FILE-- +(): Closure { + return function(T ...$xs): int { + return count($xs); + }; +} + +$intMaker = maker::(); +var_dump($intMaker(1, 2, 3)); // positive: all int + +try { + $intMaker(1, "bad", 3); +} catch (TypeError $e) { + echo "1: ", $e->getMessage(), "\n"; +} + +try { + $intMaker(1, 2, [4]); +} catch (TypeError $e) { + echo "2: ", $e->getMessage(), "\n"; +} + +class Animal {} +class Dog extends Animal {} +class Cat extends Animal {} + +function dogMaker(): Closure { + return function(T ...$xs): int { + return count($xs); + }; +} + +$dm = dogMaker::(); +var_dump($dm(new Dog, new Dog)); + +try { + $dm(new Dog, new Cat); +} catch (TypeError $e) { + echo "3: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(3) +1: {closure:maker():%d}(): Argument #2 ($xs) must be of type int, string given +2: {closure:maker():%d}(): Argument #3 ($xs) must be of type int, array given +int(2) +3: {closure:dogMaker():%d}(): Argument #2 ($xs) must be of type Dog, Cat given diff --git a/Zend/tests/generics/reification/variadic_t_reified.phpt b/Zend/tests/generics/reification/variadic_t_reified.phpt new file mode 100644 index 000000000000..9cdd17bcf6fb --- /dev/null +++ b/Zend/tests/generics/reification/variadic_t_reified.phpt @@ -0,0 +1,75 @@ +--TEST-- +Reification: variadic T parameter checks every element against the reified T binding, not just the first +--FILE-- +(T ...$xs): T { + $r = $xs[0]; + for ($i = 1; $i < count($xs); $i++) $r += $xs[$i]; + return $r; +} + +// Positive: all three elements are ints. +var_dump(sum::(1, 2, 3)); + +// Negative: the second element violates T; the error names that element +// (Argument #2) with the resolved T type ("int"). +try { + sum::(1, "abc", 3); +} catch (TypeError $e) { + echo "1: ", $e->getMessage(), "\n"; +} + +// Negative: the third element violates T. +try { + sum::(1, 2, "xyz"); +} catch (TypeError $e) { + echo "2: ", $e->getMessage(), "\n"; +} + +// Variadic with leading non-variadic param: positional 1 ($prefix) is a +// plain string, the variadic slot is `T ...`. The reified sweep starts at +// the variadic position and reports element index correctly. +function concat(string $prefix, T ...$xs): string { + $r = $prefix; + foreach ($xs as $x) $r .= (string) $x; + return $r; +} + +var_dump(concat::(":: ", 1, 2, 3)); + +try { + concat::(":: ", 1, [4, 5], 3); +} catch (TypeError $e) { + echo "3: ", $e->getMessage(), "\n"; +} + +// Object T over a variadic: a value of the wrong class fires with the bound +// class name, not the parameter letter. +class Animal {} +class Dog extends Animal {} +class Cat extends Animal {} + +function herd(T ...$xs): int { + return count($xs); +} + +var_dump(herd::(new Dog, new Dog, new Dog)); + +try { + herd::(new Dog, new Cat, new Dog); +} catch (TypeError $e) { + echo "4: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +int(6) +1: sum(): Argument #2 must be of type int, string given, called in %s on line %d +2: sum(): Argument #3 must be of type int, string given, called in %s on line %d +string(6) ":: 123" +3: concat(): Argument #3 must be of type int, array given, called in %s on line %d +int(3) +4: herd(): Argument #2 must be of type Dog, Cat given, called in %s on line %d diff --git a/Zend/tests/generics/reification/variance_reified.phpt b/Zend/tests/generics/reification/variance_reified.phpt new file mode 100644 index 000000000000..4f068d72d05b --- /dev/null +++ b/Zend/tests/generics/reification/variance_reified.phpt @@ -0,0 +1,54 @@ +--TEST-- +Reification: positive inheritance-variance cases — child signatures substituted against the reified T compile correctly +--FILE-- + { + public function get(): T { throw new Exception('abstract'); } + public function set(T $x): void {} +} + +// Child matches the substituted parent signature exactly. +class SubInt extends Base { + public function get(): int { return 42; } + public function set(int $x): void {} +} + +var_dump((new SubInt)->get()); +(new SubInt)->set(99); +echo "SubInt ok\n"; + +// Param contravariance: child accepts a WIDER param (mixed accepts int) +// than the parent's substituted int. This is allowed. +class SubParamWide extends Base { + public function set(mixed $x): void {} +} +(new SubParamWide)->set(7); +(new SubParamWide)->set("hello"); +echo "SubParamWide ok\n"; + +// Return-type covariance with class hierarchy: parent returns T = Animal, +// child returns Dog (a subclass of Animal). Allowed. +class Animal {} +class Dog extends Animal {} + +class AnimalSrc { + public function get(): T { throw new Exception('abstract'); } +} + +class DogSrc extends AnimalSrc { + public function get(): Dog { return new Dog; } +} +var_dump(get_class((new DogSrc)->get())); +?> +--EXPECT-- +int(42) +SubInt ok +SubParamWide ok +string(3) "Dog" diff --git a/Zend/tests/generics/reification/variance_reified_violation_param.phpt b/Zend/tests/generics/reification/variance_reified_violation_param.phpt new file mode 100644 index 000000000000..42e42625e700 --- /dev/null +++ b/Zend/tests/generics/reification/variance_reified_violation_param.phpt @@ -0,0 +1,15 @@ +--TEST-- +Reification: child narrowing a generic parent's reified parameter type (int → string) is rejected by variance (contravariance) +--FILE-- + { + public function set(T $x): void {} +} + +// Child accepts NARROWER (string) than parent's reified int — not contravariant. +class SubParam extends Base { + public function set(string $x): void {} +} +?> +--EXPECTF-- +Fatal error: Declaration of SubParam::set(string $x): void must be compatible with Base::set(int $x): void in %s on line %d diff --git a/Zend/tests/generics/reification/variance_reified_violation_return.phpt b/Zend/tests/generics/reification/variance_reified_violation_return.phpt new file mode 100644 index 000000000000..2997cdcaa5e9 --- /dev/null +++ b/Zend/tests/generics/reification/variance_reified_violation_return.phpt @@ -0,0 +1,15 @@ +--TEST-- +Reification: child overriding a generic parent method with a non-compatible return type fires the variance check against the reified T +--FILE-- + { + public function get(): T { throw new Exception('abstract'); } +} + +// Child says get(): string but parent's reified return is int. +class SubIntBroken extends Base { + public function get(): string { return "x"; } +} +?> +--EXPECTF-- +Fatal error: Declaration of SubIntBroken::get(): string must be compatible with Base::get(): int in %s on line %d diff --git a/Zend/tests/generics/reification/variance_reified_violation_widening.phpt b/Zend/tests/generics/reification/variance_reified_violation_widening.phpt new file mode 100644 index 000000000000..e48d75c1b578 --- /dev/null +++ b/Zend/tests/generics/reification/variance_reified_violation_widening.phpt @@ -0,0 +1,15 @@ +--TEST-- +Reification: child widening a generic parent's reified return type (int → mixed) is rejected by variance +--FILE-- + { + public function get(): T { throw new Exception('abstract'); } +} + +// Child can't widen the parent's reified int return to mixed. +class SubIntWiden extends Base { + public function get(): mixed { return 42; } +} +?> +--EXPECTF-- +Fatal error: Declaration of SubIntWiden::get(): mixed must be compatible with Base::get(): int in %s on line %d diff --git a/Zend/tests/generics/runtime/dynamic_new_synthesis.phpt b/Zend/tests/generics/runtime/dynamic_new_synthesis.phpt new file mode 100644 index 000000000000..952680530dc1 --- /dev/null +++ b/Zend/tests/generics/runtime/dynamic_new_synthesis.phpt @@ -0,0 +1,46 @@ +--TEST-- +Dynamic `new $name()`: bare generic with defaults synthesizes; without defaults throws +--FILE-- + { + public function __construct(public mixed $value) {} +} + +class NoDefault { + public function __construct(public mixed $value) {} +} + +// Dynamic new of a bare generic with defaults → defaults monomorph. +$cls = 'Box'; +$b = new $cls(42); +var_dump($b::class); + +// Dynamic new of a canonical name → that monomorph. +$cls2 = 'Box'; +$b2 = new $cls2("x"); +var_dump($b2::class); + +// Dynamic new with turbofish: the explicit args win. +$cls3 = 'Box'; +$b3 = new $cls3::(1.5); +var_dump($b3::class); + +// Dynamic new of a no-defaults bare generic → Error. +try { + $cls4 = 'NoDefault'; + new $cls4("oops"); +} catch (Error $e) { + echo "err: ", $e->getMessage(), "\n"; +} + +// But turbofish on the same bare name works. +$cls5 = 'NoDefault'; +$b5 = new $cls5::(7); +var_dump($b5::class); +?> +--EXPECT-- +string(8) "Box" +string(11) "Box" +string(10) "Box" +err: Cannot instantiate generic class NoDefault without type arguments via dynamic class name; no defaults declared +string(14) "NoDefault" diff --git a/Zend/tests/generics/runtime/lsb_through_monomorph.phpt b/Zend/tests/generics/runtime/lsb_through_monomorph.phpt new file mode 100644 index 000000000000..39b0d2c31e5b --- /dev/null +++ b/Zend/tests/generics/runtime/lsb_through_monomorph.phpt @@ -0,0 +1,59 @@ +--TEST-- +Late static binding from inside a monomorph: static::class / static::$prop / static::FOO +--FILE-- + { + public static int $count = 0; + const TAG = "Box"; + + public static function whoAmI(): string { return static::class; } + public static function bump(): void { static::$count++; } + public static function tag(): string { return static::TAG; } + public static function self_(): static { return new static(0); } + + public function __construct(public mixed $value) {} +} + +class StrBox extends Box { + public static int $count = 100; + const TAG = "StrBox"; +} + +$intCls = "Box"; +$strCls = "Box"; + +// static::class returns the late-bound class. +var_dump($intCls::whoAmI()); +var_dump($strCls::whoAmI()); +var_dump(StrBox::whoAmI()); + +// static::$prop sees the late-bound class's storage. +$intCls::bump(); +$intCls::bump(); +$strCls::bump(); +StrBox::bump(); +var_dump($intCls::$count); +var_dump($strCls::$count); +var_dump(StrBox::$count); + +// static::FOO honours overrides via LSB. +var_dump($intCls::tag()); +var_dump(StrBox::tag()); + +// new static() returns the late-bound monomorph instance. +$a = $intCls::self_(); +$b = StrBox::self_(); +var_dump($a::class); +var_dump($b::class); +?> +--EXPECT-- +string(8) "Box" +string(11) "Box" +string(6) "StrBox" +int(2) +int(1) +int(101) +string(3) "Box" +string(6) "StrBox" +string(8) "Box" +string(6) "StrBox" diff --git a/Zend/tests/generics/runtime/monomorph_canonical_unions.phpt b/Zend/tests/generics/runtime/monomorph_canonical_unions.phpt new file mode 100644 index 000000000000..9eabeadfd3d3 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_canonical_unions.phpt @@ -0,0 +1,44 @@ +--TEST-- +Monomorph canonicalization: union and intersection arguments collapse to the same monomorph regardless of source order +--FILE-- + { + public function __construct(public mixed $value) {} +} + +// Union args canonicalize: order doesn't matter. +$a = new Box::(0); +$b = new Box::(0); +var_dump($a::class); +var_dump($b::class); +var_dump($a::class === $b::class); + +// Intersection args canonicalize: order doesn't matter. +$c = new Box::(new class implements Stringable1, Stringable2 { + public function s1(): string { return "s1"; } + public function s2(): string { return "s2"; } +}); +$d = new Box::(new class implements Stringable1, Stringable2 { + public function s1(): string { return "s1"; } + public function s2(): string { return "s2"; } +}); +var_dump($c::class); +var_dump($d::class); +var_dump($c::class === $d::class); + +// Two equivalent canonical forms produce the same monomorph class. +$x = new Box::(1); +$y = new Box::(1); +var_dump($x::class === $y::class); +?> +--EXPECT-- +string(15) "Box" +string(15) "Box" +bool(true) +string(28) "Box" +string(28) "Box" +bool(true) +bool(true) diff --git a/Zend/tests/generics/runtime/monomorph_class_exists.phpt b/Zend/tests/generics/runtime/monomorph_class_exists.phpt new file mode 100644 index 000000000000..99bdbf12c32a --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_class_exists.phpt @@ -0,0 +1,25 @@ +--TEST-- +Monomorph lookup: class_exists synthesizes the monomorph on demand +--FILE-- + { + public function __construct(public mixed $value) {} +} + +// Before any synthesis, class_exists on a canonical name should synthesize. +var_dump(class_exists("Box")); +var_dump(class_exists("Box")); +var_dump(class_exists("Box")); + +// Once synthesized, subsequent lookups hit the cached entry. +var_dump(class_exists("Box")); + +// Base class still exists. +var_dump(class_exists("Box")); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/Zend/tests/generics/runtime/monomorph_dnf_canonicalization.phpt b/Zend/tests/generics/runtime/monomorph_dnf_canonicalization.phpt new file mode 100644 index 000000000000..3eda60d6ab58 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_dnf_canonicalization.phpt @@ -0,0 +1,50 @@ +--TEST-- +Monomorph canonicalization: DNF type-args sort to a canonical form (intersection-sorted, union-sorted) +--FILE-- + {} + +// Same canonical class entry regardless of source order. +$names = [ + new Box::<(A&B)|(C&D)>(), + new Box::<(B&A)|(D&C)>(), + new Box::<(C&D)|(A&B)>(), + new Box::<(A&B)|(D&C)>(), + new Box::<(B&A)|(C&D)>(), +]; + +$canonical = $names[0]::class; +echo "canonical: $canonical\n"; +foreach ($names as $i => $b) { + var_dump($b::class === $canonical); +} + +// Three-way union of intersections. +$x = new Box::<(A&B)|(C&D)|(D&E)>(); +$y = new Box::<(D&E)|(B&A)|(D&C)>(); +var_dump($x::class); +var_dump($y::class === $x::class); + +// Mixed scalars and intersections in a union. +$p = new Box::(); +$q = new Box::<(B&A)|string|int>(); +var_dump($p::class); +var_dump($q::class === $p::class); +?> +--EXPECT-- +canonical: Box<(A&B)|(C&D)> +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +string(22) "Box<(A&B)|(C&D)|(D&E)>" +bool(true) +string(21) "Box<(A&B)|int|string>" +bool(true) diff --git a/Zend/tests/generics/runtime/monomorph_dynamic_new.phpt b/Zend/tests/generics/runtime/monomorph_dynamic_new.phpt new file mode 100644 index 000000000000..ced054aa90a3 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_dynamic_new.phpt @@ -0,0 +1,34 @@ +--TEST-- +Monomorph lookup: `new $name()` with a canonical name string synthesizes on demand +--FILE-- + { + public function __construct(public mixed $value) {} +} + +// Pre-warm so the class entry exists for the explicit form too. +new Box::(0); + +$name = "Box"; +$obj = new $name(42); +var_dump($obj::class); +var_dump($obj instanceof Box); +var_dump($obj->value); + +// Names not yet synthesized are created on demand. +$other = "Box"; +$obj2 = new $other("hi"); +var_dump($obj2::class); +var_dump($obj2 instanceof Box); + +// Identity: two dynamic news of the same canonical name produce instances of the same class. +$obj3 = new $name(7); +var_dump($obj3::class === $obj::class); +?> +--EXPECT-- +string(8) "Box" +bool(true) +int(42) +string(11) "Box" +bool(true) +bool(true) diff --git a/Zend/tests/generics/runtime/monomorph_nested_args.phpt b/Zend/tests/generics/runtime/monomorph_nested_args.phpt new file mode 100644 index 000000000000..5510c3a59ddd --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_nested_args.phpt @@ -0,0 +1,37 @@ +--TEST-- +Monomorph nesting: type arguments may themselves be generic, canonicalized recursively +--FILE-- + { + public function __construct(public mixed $value) {} +} + +class Pair { + public function __construct(public mixed $left, public mixed $right) {} +} + +// Nested generic args canonicalize. +$a = new Container::>(new Container::(1)); +var_dump($a::class); +var_dump($a instanceof Container); +var_dump($a->value::class); + +// Mixed nesting and unions. +$b = new Container::>(new Pair::(1, "x")); +var_dump($b::class); + +// Same nested form yields the same monomorph. +$c = new Container::>(new Container::(2)); +var_dump($a::class === $c::class); + +// Deeply nested. +$d = new Container::>>(new Container::>(new Container::(3))); +var_dump($d::class); +?> +--EXPECT-- +string(25) "Container>" +bool(true) +string(14) "Container" +string(27) "Container>" +bool(true) +string(36) "Container>>" diff --git a/Zend/tests/generics/runtime/monomorph_observables_sweep.phpt b/Zend/tests/generics/runtime/monomorph_observables_sweep.phpt new file mode 100644 index 000000000000..842bfaa817c0 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_observables_sweep.phpt @@ -0,0 +1,100 @@ +--TEST-- +Monomorph observables sweep: var_dump/export, exceptions, __toString, WeakMap/WeakRef, FCC, class_parents, class_implements +--FILE-- + { + public function __construct(public T $value) {} + public function __toString(): string { return "Box(" . $this->value . ")"; } +} + +class IntBoxChild extends Box {} + +$b = new Box::(42); + +// var_dump and var_export use the canonical mono name. +var_dump($b); +var_export($b); echo "\n"; + +// __toString shows the substituted T-typed property. +echo "toString: ", $b, "\n"; + +// TypeError when the substituted constructor signature is violated. The error +// message references the property's declaring class (the bare base), not the +// monomorph — that's the standard PHP behaviour for typed-property errors and +// matches where the slot's metadata lives. +try { + new Box::("not int"); +} catch (TypeError $e) { + echo "type-err raised: int property rejects string\n"; +} + +// get_class / ::class / get_parent_class. +var_dump(get_class($b)); +var_dump($b::class); +var_dump(get_parent_class("Box")); + +// class_parents / class_implements walk the mono chain. +$c = new IntBoxChild(1); +$parents = class_parents($c); +ksort($parents); +print_r(array_keys($parents)); +print_r(array_keys(class_implements($c))); + +// WeakMap keyed by a mono instance. +$wm = new WeakMap(); +$wm[$b] = "tag"; +var_dump($wm[$b]); + +// WeakReference also. +$wr = WeakReference::create($b); +var_dump($wr->get() === $b); + +// First-class callable on a mono method. +$f = $b->__toString(...); +var_dump($f()); + +// get_object_vars / get_class_vars / get_class_methods. +print_r(get_object_vars($b)); +print_r(get_class_vars("Box")); +$methods = get_class_methods("Box"); +sort($methods); +print_r($methods); +?> +--EXPECTF-- +object(Box)#%d (1) { + ["value"]=> + int(42) +} +\Box::__set_state(array( + 'value' => 42, +)) +toString: Box(42) +type-err raised: int property rejects string +string(8) "Box" +string(8) "Box" +string(3) "Box" +Array +( + [0] => Box + [1] => Box +) +Array +( + [0] => Stringable +) +string(3) "tag" +bool(true) +string(7) "Box(42)" +Array +( + [value] => 42 +) +Array +( + [value] => %w +) +Array +( + [0] => __construct + [1] => __toString +) diff --git a/Zend/tests/generics/runtime/monomorph_opcache_file_cache.phpt b/Zend/tests/generics/runtime/monomorph_opcache_file_cache.phpt new file mode 100644 index 000000000000..c727fe5032c1 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_opcache_file_cache.phpt @@ -0,0 +1,35 @@ +--TEST-- +Opcache file_cache: monomorphs synthesize freshly on each request; cached classes preserve canonical parent_name +--EXTENSIONS-- +opcache +--INI-- +opcache.enable_cli=1 +opcache.file_cache={TMP} +opcache.file_cache_only=1 +--FILE-- + { + public function __construct(public mixed $value) {} +} + +class IntBox extends Box {} + +// Force the same set of synthesis events on every request. +$b = new IntBox(42); +echo "class: ", $b::class, "\n"; +echo "parent: ", (new ReflectionClass($b))->getParentClass()->getName(), "\n"; + +// Defaults monomorph also synthesizes. +$b2 = new Box(7); +echo "defaults: ", $b2::class, "\n"; + +// Dynamic name still hits the lookup hook on the second-load path. +$name = "Box"; +$b3 = new $name("hi"); +echo "dyn: ", $b3::class, "\n"; +?> +--EXPECT-- +class: IntBox +parent: Box +defaults: Box +dyn: Box diff --git a/Zend/tests/generics/runtime/monomorph_reflection.phpt b/Zend/tests/generics/runtime/monomorph_reflection.phpt new file mode 100644 index 000000000000..3605ef461108 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_reflection.phpt @@ -0,0 +1,32 @@ +--TEST-- +Monomorph reflection: ReflectionClass on a synthesized monomorph reports the canonical name and parent +--FILE-- + { + public function __construct(public mixed $value) {} + public function get(): mixed { return $this->value; } +} + +$b = new Box::(42); +$mono = $b::class; + +$rc = new ReflectionClass($mono); +var_dump($rc->getName()); + +$parent = $rc->getParentClass(); +var_dump($parent->getName()); + +// The monomorph carries the same method shape as the base. +var_dump($rc->hasMethod('get')); +var_dump($rc->getMethod('__construct')->getNumberOfParameters()); + +// Reflecting via the base name still works. +$rcBase = new ReflectionClass(Box::class); +var_dump($rcBase->getName()); +?> +--EXPECT-- +string(8) "Box" +string(3) "Box" +bool(true) +int(1) +string(3) "Box" diff --git a/Zend/tests/generics/runtime/monomorph_reflection_surface.phpt b/Zend/tests/generics/runtime/monomorph_reflection_surface.phpt new file mode 100644 index 000000000000..090d1b3ab0d6 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_reflection_surface.phpt @@ -0,0 +1,58 @@ +--TEST-- +Reflection surface for monomorphs: isGeneric, getGenericParameters, newInstance/Args/WithoutConstructor +--FILE-- + { + public function __construct(public mixed $value) {} + public function get(): T { return $this->value; } +} + +class NoDefault {} + +$rcBase = new ReflectionClass(Box::class); +$rcMono = new ReflectionClass("Box"); + +// Generic-template vs concrete-instantiation flags. +var_dump($rcBase->isGeneric()); +var_dump($rcMono->isGeneric()); +var_dump(count($rcBase->getGenericParameters())); +var_dump(count($rcMono->getGenericParameters())); + +// Reflecting the base class and calling newInstance synthesizes the defaults +// monomorph (same contract as `new Box()`). +$bb = $rcBase->newInstance(42); +var_dump($bb::class); + +// Reflecting a monomorph instantiates that monomorph. +$bm = $rcMono->newInstance(7); +var_dump($bm::class); + +// newInstanceArgs honours the same synthesis path. +$ba = $rcMono->newInstanceArgs([99]); +var_dump($ba::class); + +// newInstanceWithoutConstructor too. +$bw = (new ReflectionClass("Box"))->newInstanceWithoutConstructor(); +var_dump($bw::class); + +// And newInstance on a no-defaults generic throws. +try { + (new ReflectionClass(NoDefault::class))->newInstance(); +} catch (Error $e) { + echo "err: ", $e->getMessage(), "\n"; +} + +// Substituted method signature is visible on the monomorph. +echo "Box::get returns: ", $rcMono->getMethod('get')->getReturnType(), "\n"; +?> +--EXPECT-- +bool(true) +bool(false) +int(1) +int(0) +string(8) "Box" +string(8) "Box" +string(8) "Box" +string(11) "Box" +err: Cannot instantiate generic class NoDefault without type arguments; type parameter T has no default +Box::get returns: int diff --git a/Zend/tests/generics/runtime/monomorph_serialize.phpt b/Zend/tests/generics/runtime/monomorph_serialize.phpt new file mode 100644 index 000000000000..f6509147df63 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_serialize.phpt @@ -0,0 +1,29 @@ +--TEST-- +Monomorph serialization: serialize/unserialize round-trips through the canonical class name +--FILE-- + { + public function __construct(public mixed $value) {} +} + +$b = new Box::(42); +$s = serialize($b); + +// The serialized payload encodes the canonical class name. +echo $s, "\n"; + +// Unserialize materializes the monomorph (synthesizing if not yet present). +$b2 = unserialize($s); +var_dump($b2::class); +var_dump($b2 instanceof Box); +var_dump($b2->value); + +// Round-trip identity through the canonical name. +var_dump($b::class === $b2::class); +?> +--EXPECTF-- +O:8:"Box":1:{s:5:"value";i:42;} +string(8) "Box" +bool(true) +int(42) +bool(true) diff --git a/Zend/tests/generics/runtime/monomorph_typed_class_constants.phpt b/Zend/tests/generics/runtime/monomorph_typed_class_constants.phpt new file mode 100644 index 000000000000..384f5579513f --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_typed_class_constants.phpt @@ -0,0 +1,36 @@ +--TEST-- +Typed class constants: per-monomorph substituted type info +--FILE-- + { + const T DEFAULT_VALUE = 0; + const string TAG = "Box"; // non-generic, shared as-is +} + +$rcBase = new ReflectionClass(Box::class); +echo "Box::DEFAULT_VALUE type=", $rcBase->getReflectionConstant("DEFAULT_VALUE")->getType(), "\n"; +echo "Box::TAG type=", $rcBase->getReflectionConstant("TAG")->getType(), "\n"; + +$rcInt = new ReflectionClass("Box"); +echo "Box::DEFAULT_VALUE type=", $rcInt->getReflectionConstant("DEFAULT_VALUE")->getType(), "\n"; +echo "Box::TAG type=", $rcInt->getReflectionConstant("TAG")->getType(), "\n"; + +$rcStr = new ReflectionClass("Box"); +echo "Box::DEFAULT_VALUE type=", $rcStr->getReflectionConstant("DEFAULT_VALUE")->getType(), "\n"; + +$rcUnion = new ReflectionClass("Box"); +echo "Box::DEFAULT_VALUE type=", $rcUnion->getReflectionConstant("DEFAULT_VALUE")->getType(), "\n"; + +// Constant values stay shared (immutable) — substitution only changes the type. +var_dump(Box::DEFAULT_VALUE); +var_dump((new ReflectionClass("Box"))->getReflectionConstant("DEFAULT_VALUE")->getValue()); +?> +--EXPECT-- +Box::DEFAULT_VALUE type=mixed +Box::TAG type=string +Box::DEFAULT_VALUE type=int +Box::TAG type=string +Box::DEFAULT_VALUE type=?string +Box::DEFAULT_VALUE type=int|float +int(0) +int(0) diff --git a/Zend/tests/generics/runtime/monomorph_unserialize_fresh_process.phpt b/Zend/tests/generics/runtime/monomorph_unserialize_fresh_process.phpt new file mode 100644 index 000000000000..56eee80829e8 --- /dev/null +++ b/Zend/tests/generics/runtime/monomorph_unserialize_fresh_process.phpt @@ -0,0 +1,63 @@ +--TEST-- +Monomorph unserialize: a fresh process can unserialize a canonical generic name even when no instance has been constructed yet +--FILE-- +); unserialize() in a fresh process must +// be able to materialize that monomorph just from the name, without the +// caller priming it by constructing an instance first. + +class Box { + public function __construct(public T $value) {} +} + +// Produce the canonical payload from a primed process. +$payload = serialize(new Box::(42)); + +$tmp = tempnam(sys_get_temp_dir(), 'monomorph_unserialize_'); +file_put_contents($tmp, $payload); + +// Run the unserialize side in a fresh PHP process. The child declares the +// generic template but never constructs an instance, so the monomorph +// Box only exists as a name in the serialized payload. +$script = <<<'PHP' + { + public function __construct(public T $value) {} +} +$s = file_get_contents($argv[1]); +$b = unserialize($s); +$out = "###RESULT###\n"; +$out .= var_export($b instanceof Box, true) . "\n"; +$out .= var_export($b::class, true) . "\n"; +$out .= var_export($b->value, true) . "\n"; +file_put_contents($argv[2], $out); +PHP; + +$scriptFile = tempnam(sys_get_temp_dir(), 'monomorph_unserialize_script_'); +file_put_contents($scriptFile, $script); + +$resultFile = tempnam(sys_get_temp_dir(), 'monomorph_unserialize_result_'); + +$cmd = sprintf( + '%s -n %s %s %s >/dev/null 2>&1', + escapeshellarg(PHP_BINARY), + escapeshellarg($scriptFile), + escapeshellarg($tmp), + escapeshellarg($resultFile), +); +shell_exec($cmd); + +echo $payload, "\n"; +echo file_get_contents($resultFile); + +@unlink($tmp); +@unlink($scriptFile); +@unlink($resultFile); +?> +--EXPECT-- +O:8:"Box":1:{s:5:"value";i:42;} +###RESULT### +true +'Box' +42 diff --git a/Zend/tests/generics/runtime/naked_new_self_no_defaults_lenient.phpt b/Zend/tests/generics/runtime/naked_new_self_no_defaults_lenient.phpt new file mode 100644 index 000000000000..45be1e78404d --- /dev/null +++ b/Zend/tests/generics/runtime/naked_new_self_no_defaults_lenient.phpt @@ -0,0 +1,27 @@ +--TEST-- +Lexical `new self()` and `new ThisClass()` in a no-defaults generic class fall back to a bare instance +--FILE-- + with no default doesn't error — it creates a +// bare Box instance, preserving the lexical-self semantic where T is in scope +// but can't be statically bound to a concrete type at the call site. +final readonly class Box<+T> { + public function __construct(public T $value) {} + public function cloneSelf(): self { return new self($this->value); } + public function cloneByName(): Box { return new Box($this->value); } +} + +$b = new Box::(42); +$c1 = $b->cloneSelf(); +$c2 = $b->cloneByName(); + +var_dump($c1::class); +var_dump($c2::class); +var_dump($c1->value); +var_dump($c2->value); +?> +--EXPECT-- +string(3) "Box" +string(3) "Box" +int(42) +int(42) diff --git a/Zend/tests/generics/runtime/naked_new_self_static_parent.phpt b/Zend/tests/generics/runtime/naked_new_self_static_parent.phpt new file mode 100644 index 000000000000..c0bc09c4c1bf --- /dev/null +++ b/Zend/tests/generics/runtime/naked_new_self_static_parent.phpt @@ -0,0 +1,40 @@ +--TEST-- +Naked new self/static/parent inside generic class bodies +--FILE-- + { + public function __construct(public mixed $value) {} + public static function makeSelf(mixed $v): self { return new self($v); } + public static function makeStatic(mixed $v): static { return new static($v); } + public static function makeBare(mixed $v): Box { return new Box($v); } +} + +class IntBox extends Box { + public static function makeStatic(mixed $v): static { return new static($v); } + public function makeParent(): Box { return new parent($this->value); } +} + +class StrBox extends Box { + public function makeParent(): Box { return new parent($this->value); } +} + +// `new self()` → lexical class with defaults applied. +var_dump(Box::makeSelf(1)::class); +// `new Box()` (literal) inside Box's static method also routes through the +// same rewrite (lexical self-reference). +var_dump(Box::makeBare(2)::class); +// `new static()` from Box → defaults mono; from IntBox → IntBox (no params). +var_dump(Box::makeStatic(3)::class); +var_dump(IntBox::makeStatic(4)::class); + +// `new parent()` uses the extends args. +var_dump((new IntBox(5))->makeParent()::class); +var_dump((new StrBox("x"))->makeParent()::class); +?> +--EXPECT-- +string(8) "Box" +string(8) "Box" +string(8) "Box" +string(6) "IntBox" +string(8) "Box" +string(11) "Box" diff --git a/Zend/tests/generics/runtime/static_property_isolation.phpt b/Zend/tests/generics/runtime/static_property_isolation.phpt new file mode 100644 index 000000000000..8c40c14b3a25 --- /dev/null +++ b/Zend/tests/generics/runtime/static_property_isolation.phpt @@ -0,0 +1,47 @@ +--TEST-- +Monomorph isolation: each synthesized monomorph has its own static-property storage +--FILE-- + { + public static int $count = 0; + public static array $items = []; +} + +// Force synthesis of two distinct monomorphs. +new Counter::(); +new Counter::(); + +$intCls = "Counter"; +$strCls = "Counter"; + +$intCls::$count = 5; +$strCls::$count = 10; + +$intCls::$items[] = "int-a"; +$intCls::$items[] = "int-b"; +$strCls::$items[] = "string-only"; + +var_dump($intCls::$count); +var_dump($strCls::$count); +var_dump(Counter::$count); + +var_dump($intCls::$items); +var_dump($strCls::$items); +var_dump(Counter::$items); +?> +--EXPECT-- +int(5) +int(10) +int(0) +array(2) { + [0]=> + string(5) "int-a" + [1]=> + string(5) "int-b" +} +array(1) { + [0]=> + string(11) "string-only" +} +array(0) { +} diff --git a/Zend/tests/generics/scoping/closure_returned_visible_in_reflection.phpt b/Zend/tests/generics/scoping/closure_returned_visible_in_reflection.phpt new file mode 100644 index 000000000000..8ceeac6f49a9 --- /dev/null +++ b/Zend/tests/generics/scoping/closure_returned_visible_in_reflection.phpt @@ -0,0 +1,13 @@ +--TEST-- +Scoping: nested closure has its own ReflectionFunction view +--FILE-- +(): Closure { + return function (T $y): T { return $y; }; +} +$cl = f(); +$r = new ReflectionFunction($cl); +echo $r->getReturnType()->__toString(), "\n"; +?> +--EXPECT-- +object diff --git a/Zend/tests/generics/scoping/extends_clause.phpt b/Zend/tests/generics/scoping/extends_clause.phpt new file mode 100644 index 000000000000..d9839bf3d48f --- /dev/null +++ b/Zend/tests/generics/scoping/extends_clause.phpt @@ -0,0 +1,11 @@ +--TEST-- +Scoping: T is visible in extends clause +--FILE-- + {} +class Derived extends Base {} +$rc = new ReflectionClass('Derived'); +echo $rc->getParentClass()->getName(), "\n"; +?> +--EXPECT-- +Base diff --git a/Zend/tests/generics/scoping/file_scope_class_does_not_shadow.phpt b/Zend/tests/generics/scoping/file_scope_class_does_not_shadow.phpt new file mode 100644 index 000000000000..fcf1302bddf8 --- /dev/null +++ b/Zend/tests/generics/scoping/file_scope_class_does_not_shadow.phpt @@ -0,0 +1,17 @@ +--TEST-- +Scoping: a file-scope class does NOT shadow a generic type parameter +--FILE-- +(): T { + // Inside f, the bare name T refers to the generic parameter, not the + // file-scope class T. With no binding supplied, the resolver falls back + // to the parameter's bound (the file-scope class via \T) — proving the + // parameter name shadowed the class name in the body. + return new T(); +} +$obj = f(); +var_dump($obj->tag); +?> +--EXPECT-- +int(42) diff --git a/Zend/tests/generics/scoping/fq_name_bypasses_type_param.phpt b/Zend/tests/generics/scoping/fq_name_bypasses_type_param.phpt new file mode 100644 index 000000000000..032fad8b69b4 --- /dev/null +++ b/Zend/tests/generics/scoping/fq_name_bypasses_type_param.phpt @@ -0,0 +1,15 @@ +--TEST-- +Scoping: a fully qualified name `\T` bypasses the type-parameter rule +--FILE-- +(): int { + $x = new \T(); + return $x->v; +} +echo f(), "\n"; +?> +--EXPECT-- +5 diff --git a/Zend/tests/generics/scoping/implements_clause.phpt b/Zend/tests/generics/scoping/implements_clause.phpt new file mode 100644 index 000000000000..44de9db4b292 --- /dev/null +++ b/Zend/tests/generics/scoping/implements_clause.phpt @@ -0,0 +1,11 @@ +--TEST-- +Scoping: T is visible in implements clause +--FILE-- + {} +class Sink implements IConsumer {} +$rc = new ReflectionClass('Sink'); +echo $rc->getInterfaceNames()[0], "\n"; +?> +--EXPECT-- +IConsumer diff --git a/Zend/tests/generics/scoping/inner_class_shadowing_is_case_insensitive.phpt b/Zend/tests/generics/scoping/inner_class_shadowing_is_case_insensitive.phpt new file mode 100644 index 000000000000..0261f6a21b33 --- /dev/null +++ b/Zend/tests/generics/scoping/inner_class_shadowing_is_case_insensitive.phpt @@ -0,0 +1,15 @@ +--TEST-- +Scoping: inner-class shadowing of a type parameter is case-insensitive +--FILE-- +(): void { + class t { + public int $v = 9; + } + $x = new T(); + echo $x->v, "\n"; +} +f(); +?> +--EXPECT-- +9 diff --git a/Zend/tests/generics/scoping/inner_class_shadows_in_instanceof.phpt b/Zend/tests/generics/scoping/inner_class_shadows_in_instanceof.phpt new file mode 100644 index 000000000000..a4637ae93909 --- /dev/null +++ b/Zend/tests/generics/scoping/inner_class_shadows_in_instanceof.phpt @@ -0,0 +1,14 @@ +--TEST-- +Scoping: inner class shadows the type parameter for `instanceof` +--FILE-- +($x): bool { + class T {} + return $x instanceof T; +} +$called = false; +$result = f(new stdClass); +var_dump($result); +?> +--EXPECT-- +bool(false) diff --git a/Zend/tests/generics/scoping/inner_class_shadows_type_param.phpt b/Zend/tests/generics/scoping/inner_class_shadows_type_param.phpt new file mode 100644 index 000000000000..813387557be2 --- /dev/null +++ b/Zend/tests/generics/scoping/inner_class_shadows_type_param.phpt @@ -0,0 +1,15 @@ +--TEST-- +Scoping: a class declared inside a generic body shadows the type parameter +--FILE-- +(): void { + class T { + public int $v = 7; + } + $x = new T(); + echo $x->v, "\n"; +} +f(); +?> +--EXPECT-- +7 diff --git a/Zend/tests/generics/scoping/left_to_right_param_bounds.phpt b/Zend/tests/generics/scoping/left_to_right_param_bounds.phpt new file mode 100644 index 000000000000..479039281346 --- /dev/null +++ b/Zend/tests/generics/scoping/left_to_right_param_bounds.phpt @@ -0,0 +1,12 @@ +--TEST-- +Scoping: type parameters resolve in subsequent bounds (left to right) +--FILE-- + { + public U $val; +} +$rt = (new ReflectionClass('Box'))->getProperty('val')->getType(); +echo $rt->getName(), "\n"; +?> +--EXPECT-- +object diff --git a/Zend/tests/generics/scoping/method_introduces_own.phpt b/Zend/tests/generics/scoping/method_introduces_own.phpt new file mode 100644 index 000000000000..5c3ff1c900f2 --- /dev/null +++ b/Zend/tests/generics/scoping/method_introduces_own.phpt @@ -0,0 +1,18 @@ +--TEST-- +Scoping: method introduces its own type parameter +--FILE-- + { + public function morph(T $x, U $y): U { return $y; } +} +$rm = (new ReflectionClass('Box'))->getMethod('morph'); +echo $rm->getParameters()[0]->getType()->getName(), "\n"; +echo $rm->getParameters()[1]->getType()->getName(), "\n"; +echo $rm->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +A +B +B diff --git a/Zend/tests/generics/scoping/method_param_does_not_leak.phpt b/Zend/tests/generics/scoping/method_param_does_not_leak.phpt new file mode 100644 index 000000000000..ec5bd29b0eb5 --- /dev/null +++ b/Zend/tests/generics/scoping/method_param_does_not_leak.phpt @@ -0,0 +1,20 @@ +--TEST-- +Scoping: method type parameter does not leak to other methods +--FILE-- +(): int { + return 1; + } + public function m2(): T { + return new T; + } +} +$b = new Box; +echo $b->m2()->val, "\n"; +?> +--EXPECT-- +7 diff --git a/Zend/tests/generics/scoping/method_param_type.phpt b/Zend/tests/generics/scoping/method_param_type.phpt new file mode 100644 index 000000000000..3be048c7b36e --- /dev/null +++ b/Zend/tests/generics/scoping/method_param_type.phpt @@ -0,0 +1,13 @@ +--TEST-- +Scoping: T from class scope is visible in method parameter types +--FILE-- + { + public function set(T $x): void {} +} +$rm = (new ReflectionClass('Box'))->getMethod('set'); +echo $rm->getParameters()[0]->getType()->getName(), "\n"; +?> +--EXPECT-- +Iface diff --git a/Zend/tests/generics/scoping/method_return_type.phpt b/Zend/tests/generics/scoping/method_return_type.phpt new file mode 100644 index 000000000000..6951dcc9e65d --- /dev/null +++ b/Zend/tests/generics/scoping/method_return_type.phpt @@ -0,0 +1,13 @@ +--TEST-- +Scoping: T from class scope is visible in method return types +--FILE-- + { + public function get(): T { return new Animal; } +} +$rm = (new ReflectionClass('Container'))->getMethod('get'); +echo $rm->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +Animal diff --git a/Zend/tests/generics/scoping/nested_anon_class_captures.phpt b/Zend/tests/generics/scoping/nested_anon_class_captures.phpt new file mode 100644 index 000000000000..b7dd6bd3769f --- /dev/null +++ b/Zend/tests/generics/scoping/nested_anon_class_captures.phpt @@ -0,0 +1,21 @@ +--TEST-- +Scoping: nested anonymous class captures enclosing type parameter +--FILE-- +(T $x): object { + return new class($x) { + public T $val; + public function __construct(T $x) { $this->val = $x; } + public function get(): T { return $this->val; } + }; +} +class Dog implements Animal {} +$obj = makeAnimalBox(new Dog); +$r = new ReflectionClass($obj); +echo $r->getProperty('val')->getType()->getName(), "\n"; +echo $r->getMethod('get')->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +Animal +Animal diff --git a/Zend/tests/generics/scoping/nested_arrow_captures.phpt b/Zend/tests/generics/scoping/nested_arrow_captures.phpt new file mode 100644 index 000000000000..1dce854b025d --- /dev/null +++ b/Zend/tests/generics/scoping/nested_arrow_captures.phpt @@ -0,0 +1,15 @@ +--TEST-- +Scoping: nested arrow function captures enclosing type parameter +--FILE-- +(): Closure { + return fn(T $y): T => $y; +} +$cl = f(); +$r = new ReflectionFunction($cl); +echo $r->getParameters()[0]->getType()->getName(), "\n"; +echo $r->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +int +int diff --git a/Zend/tests/generics/scoping/nested_closure_captures.phpt b/Zend/tests/generics/scoping/nested_closure_captures.phpt new file mode 100644 index 000000000000..d0fcf8ec4118 --- /dev/null +++ b/Zend/tests/generics/scoping/nested_closure_captures.phpt @@ -0,0 +1,16 @@ +--TEST-- +Scoping: nested closure captures enclosing function's type parameter +--FILE-- +(T $x): Closure { + return function (T $y): T { return $y; }; +} +class Foo {} +$cl = f(new Foo); +$r = new ReflectionFunction($cl); +echo $r->getParameters()[0]->getType()->getName(), "\n"; +echo $r->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +object +object diff --git a/Zend/tests/generics/scoping/property_type.phpt b/Zend/tests/generics/scoping/property_type.phpt new file mode 100644 index 000000000000..898ecd1d96b9 --- /dev/null +++ b/Zend/tests/generics/scoping/property_type.phpt @@ -0,0 +1,12 @@ +--TEST-- +Scoping: T from class scope is visible in property types +--FILE-- + { + public T $value; +} +$rt = (new ReflectionClass('Box'))->getProperty('value')->getType(); +echo $rt->getName(), "\n"; +?> +--EXPECT-- +object diff --git a/Zend/tests/generics/scoping/trait_use_clause.phpt b/Zend/tests/generics/scoping/trait_use_clause.phpt new file mode 100644 index 000000000000..9c50c7a98a53 --- /dev/null +++ b/Zend/tests/generics/scoping/trait_use_clause.phpt @@ -0,0 +1,32 @@ +--TEST-- +Scoping: a trait `use Holder` flows the using class's T-bound into the trait method's signature +--FILE-- + { + public function tag(X $x): X { return $x; } +} +class Box { + use Holder; +} + +// The trait method's X gets substituted with Box's T, which is bounded to +// object. The erased signature reflects that bound — not the trait's +// original unbounded "mixed". +echo (new ReflectionClass('Box'))->getMethod('tag')->getReturnType()->getName(), "\n"; + +// On a bare (unmonomorphed) Box, the runtime check enforces the bound. +$b = new Box; +echo get_class($b), "\n"; +var_dump($b->tag(new stdClass) instanceof stdClass); + +try { + $b->tag(42); +} catch (TypeError $e) { + echo "rejected: ", $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +object +Box +bool(true) +rejected: Box::tag(): Argument #1 ($x) must be of type object, int given%S diff --git a/Zend/tests/generics/syntax/args_dnf.phpt b/Zend/tests/generics/syntax/args_dnf.phpt new file mode 100644 index 000000000000..e0903258189e --- /dev/null +++ b/Zend/tests/generics/syntax/args_dnf.phpt @@ -0,0 +1,15 @@ +--TEST-- +Generic syntax: type argument is DNF +--FILE-- + {} +function f(D<(A&B)|C> $x): void {} +$pt = (new ReflectionFunction('f'))->getParameters()[0]->getType(); +$arg = $pt->getGenericArguments()[0]; +echo get_class($arg), "\n"; +?> +--EXPECT-- +ReflectionUnionType diff --git a/Zend/tests/generics/syntax/args_intersection.phpt b/Zend/tests/generics/syntax/args_intersection.phpt new file mode 100644 index 000000000000..9842148e216e --- /dev/null +++ b/Zend/tests/generics/syntax/args_intersection.phpt @@ -0,0 +1,14 @@ +--TEST-- +Generic syntax: type argument is an intersection +--FILE-- + {} +function f(C $x): void {} +$pt = (new ReflectionFunction('f'))->getParameters()[0]->getType(); +$arg = $pt->getGenericArguments()[0]; +echo get_class($arg), "\n"; +?> +--EXPECT-- +ReflectionIntersectionType diff --git a/Zend/tests/generics/syntax/args_union.phpt b/Zend/tests/generics/syntax/args_union.phpt new file mode 100644 index 000000000000..1e424f8bf363 --- /dev/null +++ b/Zend/tests/generics/syntax/args_union.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: type argument is a union +--FILE-- + {} +function f(Container $x): void {} +$pt = (new ReflectionFunction('f'))->getParameters()[0]->getType(); +$arg = $pt->getGenericArguments()[0]; +echo get_class($arg), "\n"; +?> +--EXPECT-- +ReflectionUnionType diff --git a/Zend/tests/generics/syntax/arrow_fn_decl.phpt b/Zend/tests/generics/syntax/arrow_fn_decl.phpt new file mode 100644 index 000000000000..22790e280438 --- /dev/null +++ b/Zend/tests/generics/syntax/arrow_fn_decl.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: arrow function with type parameters +--FILE-- +(T $x): T => $x; +$r = new ReflectionFunction($f); +var_dump($r->isGeneric()); +echo $r->getGenericParameters()[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +T diff --git a/Zend/tests/generics/syntax/bound_and_default_with_args.phpt b/Zend/tests/generics/syntax/bound_and_default_with_args.phpt new file mode 100644 index 000000000000..832cdada25e4 --- /dev/null +++ b/Zend/tests/generics/syntax/bound_and_default_with_args.phpt @@ -0,0 +1,22 @@ +--TEST-- +Generic syntax: bound and default both carry type arguments, closing >> +--FILE-- + {} + +// class A has a generic parameter T with bound B and default B. +// Same args on both so the default satisfies the bound under invariant T — +// the test exercises the parser's `>>` splitting in bound + default position. +class A=B> {} + +$p = (new ReflectionClass('A'))->getGenericParameters()[0]; + +$b = $p->getBound(); +echo "bound: ", $b->getName(), "<", $b->getGenericArguments()[0]->getName(), ">\n"; + +$d = $p->getDefault(); +echo "default: ", $d->getName(), "<", $d->getGenericArguments()[0]->getName(), ">\n"; +?> +--EXPECT-- +bound: B +default: B diff --git a/Zend/tests/generics/syntax/bound_dnf.phpt b/Zend/tests/generics/syntax/bound_dnf.phpt new file mode 100644 index 000000000000..7d65ae2dcbd7 --- /dev/null +++ b/Zend/tests/generics/syntax/bound_dnf.phpt @@ -0,0 +1,13 @@ +--TEST-- +Generic syntax: bound is a DNF type +--FILE-- + {} +$p = (new ReflectionClass('Box'))->getGenericParameters()[0]; +echo get_class($p->getBound()), "\n"; +?> +--EXPECT-- +ReflectionUnionType diff --git a/Zend/tests/generics/syntax/bound_intersection.phpt b/Zend/tests/generics/syntax/bound_intersection.phpt new file mode 100644 index 000000000000..f73eeb2e4357 --- /dev/null +++ b/Zend/tests/generics/syntax/bound_intersection.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: bound is an intersection type +--FILE-- + {} +$p = (new ReflectionClass('Box'))->getGenericParameters()[0]; +echo get_class($p->getBound()), "\n"; +?> +--EXPECT-- +ReflectionIntersectionType diff --git a/Zend/tests/generics/syntax/bound_single_class.phpt b/Zend/tests/generics/syntax/bound_single_class.phpt new file mode 100644 index 000000000000..d6000909b072 --- /dev/null +++ b/Zend/tests/generics/syntax/bound_single_class.phpt @@ -0,0 +1,13 @@ +--TEST-- +Generic syntax: bound on a single class type +--FILE-- + {} +$p = (new ReflectionClass('Box'))->getGenericParameters()[0]; +var_dump($p->hasBound()); +echo $p->getBound()->getName(), "\n"; +?> +--EXPECT-- +bool(true) +Animal diff --git a/Zend/tests/generics/syntax/bound_union.phpt b/Zend/tests/generics/syntax/bound_union.phpt new file mode 100644 index 000000000000..2c9c71f9d4b1 --- /dev/null +++ b/Zend/tests/generics/syntax/bound_union.phpt @@ -0,0 +1,11 @@ +--TEST-- +Generic syntax: bound is a union type +--FILE-- + {} +$p = (new ReflectionClass('Box'))->getGenericParameters()[0]; +$b = $p->getBound(); +echo get_class($b), "\n"; +?> +--EXPECT-- +ReflectionUnionType diff --git a/Zend/tests/generics/syntax/builtin_self_parent_static.phpt b/Zend/tests/generics/syntax/builtin_self_parent_static.phpt new file mode 100644 index 000000000000..35934d41fa6e --- /dev/null +++ b/Zend/tests/generics/syntax/builtin_self_parent_static.phpt @@ -0,0 +1,20 @@ +--TEST-- +Generic syntax: self, parent, static +--FILE-- + {} + public function p(): parent {} + public function st(): static {} +} +$rc = new ReflectionClass('Foo'); +foreach (['s' => 'self', 'p' => 'parent', 'st' => 'static'] as $m => $expected) { + $rt = $rc->getMethod($m)->getReturnType(); + echo "$m: ", $rt->getName(), " hasArgs=", var_export($rt->hasGenericArguments(), true), "\n"; +} +?> +--EXPECT-- +s: Foo hasArgs=true +p: Base hasArgs=true +st: static hasArgs=true diff --git a/Zend/tests/generics/syntax/catch_with_args.phpt b/Zend/tests/generics/syntax/catch_with_args.phpt new file mode 100644 index 000000000000..bef722884955 --- /dev/null +++ b/Zend/tests/generics/syntax/catch_with_args.phpt @@ -0,0 +1,17 @@ +--TEST-- +Generic syntax: catch with type arguments compares against the monomorph canonical name +--FILE-- + extends Exception {} +// Throwing MyErr matches a `catch (MyErr)` block; a `catch (MyErr)` +// would not, because the two are distinct monomorphs. +try { + throw new MyErr::('boom'); +} catch (MyErr $e) { + echo "wrong-mono caught: ", $e->getMessage(), "\n"; +} catch (MyErr $e) { + echo "right-mono caught: ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +right-mono caught: boom diff --git a/Zend/tests/generics/syntax/class_multiple_params.phpt b/Zend/tests/generics/syntax/class_multiple_params.phpt new file mode 100644 index 000000000000..4f66e3173fe2 --- /dev/null +++ b/Zend/tests/generics/syntax/class_multiple_params.phpt @@ -0,0 +1,14 @@ +--TEST-- +Generic syntax: class with multiple type parameters +--FILE-- + {} +$r = new ReflectionClass('Map'); +$ps = $r->getGenericParameters(); +echo count($ps), "\n"; +foreach ($ps as $p) echo $p->getName(), "\n"; +?> +--EXPECT-- +2 +K +V diff --git a/Zend/tests/generics/syntax/class_single_param.phpt b/Zend/tests/generics/syntax/class_single_param.phpt new file mode 100644 index 000000000000..6a5a8bed0cef --- /dev/null +++ b/Zend/tests/generics/syntax/class_single_param.phpt @@ -0,0 +1,14 @@ +--TEST-- +Generic syntax: class with single type parameter +--FILE-- + {} +$r = new ReflectionClass('Box'); +var_dump($r->isGeneric()); +echo count($r->getGenericParameters()), "\n"; +echo $r->getGenericParameters()[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +1 +T diff --git a/Zend/tests/generics/syntax/closure_decl.phpt b/Zend/tests/generics/syntax/closure_decl.phpt new file mode 100644 index 000000000000..35620b3ae631 --- /dev/null +++ b/Zend/tests/generics/syntax/closure_decl.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: closure with type parameters +--FILE-- +(T $x): T { return $x; }; +$r = new ReflectionFunction($f); +var_dump($r->isGeneric()); +echo $r->getGenericParameters()[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +T diff --git a/Zend/tests/generics/syntax/default_value.phpt b/Zend/tests/generics/syntax/default_value.phpt new file mode 100644 index 000000000000..03f6a867fe3b --- /dev/null +++ b/Zend/tests/generics/syntax/default_value.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: type parameter with default +--FILE-- + {} +$p = (new ReflectionClass('Box'))->getGenericParameters()[0]; +var_dump($p->hasDefault()); +echo $p->getDefault(), "\n"; +?> +--EXPECT-- +bool(true) +mixed diff --git a/Zend/tests/generics/syntax/default_with_nested_args.phpt b/Zend/tests/generics/syntax/default_with_nested_args.phpt new file mode 100644 index 000000000000..ef09d58a7b47 --- /dev/null +++ b/Zend/tests/generics/syntax/default_with_nested_args.phpt @@ -0,0 +1,11 @@ +--TEST-- +Generic syntax: >>= splitting in default position +--FILE-- + {} +class C> {} +$p = (new ReflectionClass('C'))->getGenericParameters()[0]; +echo $p, "\n"; +?> +--EXPECT-- +T = MapT diff --git a/Zend/tests/generics/syntax/extends_with_args.phpt b/Zend/tests/generics/syntax/extends_with_args.phpt new file mode 100644 index 000000000000..9a475577183d --- /dev/null +++ b/Zend/tests/generics/syntax/extends_with_args.phpt @@ -0,0 +1,10 @@ +--TEST-- +Generic syntax: extends with type arguments +--FILE-- + {} +class Derived extends Base {} +echo (new ReflectionClass('Derived'))->getParentClass()->getName(), "\n"; +?> +--EXPECT-- +Base diff --git a/Zend/tests/generics/syntax/function_decl.phpt b/Zend/tests/generics/syntax/function_decl.phpt new file mode 100644 index 000000000000..8ba5cde4314a --- /dev/null +++ b/Zend/tests/generics/syntax/function_decl.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: function declaration with type parameters +--FILE-- +(T $x): T { return $x; } +$r = new ReflectionFunction('id'); +var_dump($r->isGeneric()); +echo $r->getGenericParameters()[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +T diff --git a/Zend/tests/generics/syntax/implements_with_args.phpt b/Zend/tests/generics/syntax/implements_with_args.phpt new file mode 100644 index 000000000000..5221dffc4f13 --- /dev/null +++ b/Zend/tests/generics/syntax/implements_with_args.phpt @@ -0,0 +1,11 @@ +--TEST-- +Generic syntax: implements with type arguments +--FILE-- + {} +class C implements Iface {} +$r = new ReflectionClass('C'); +foreach ($r->getInterfaceNames() as $n) echo $n, "\n"; +?> +--EXPECT-- +Iface diff --git a/Zend/tests/generics/syntax/instanceof_with_args.phpt b/Zend/tests/generics/syntax/instanceof_with_args.phpt new file mode 100644 index 000000000000..1722eff49681 --- /dev/null +++ b/Zend/tests/generics/syntax/instanceof_with_args.phpt @@ -0,0 +1,17 @@ +--TEST-- +Generic syntax: instanceof with type arguments resolves to the monomorph canonical name +--FILE-- + {} +$c = new C::(); +var_dump($c instanceof C); +var_dump($c instanceof C); +var_dump($c instanceof C); +$x = new stdClass; +var_dump($x instanceof C); +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) +bool(false) diff --git a/Zend/tests/generics/syntax/interface_decl.phpt b/Zend/tests/generics/syntax/interface_decl.phpt new file mode 100644 index 000000000000..e0dbb24a6457 --- /dev/null +++ b/Zend/tests/generics/syntax/interface_decl.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: interface with type parameters +--FILE-- + {} +$r = new ReflectionClass('Iter'); +var_dump($r->isGeneric()); +echo $r->getGenericParameters()[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +T diff --git a/Zend/tests/generics/syntax/method_decl.phpt b/Zend/tests/generics/syntax/method_decl.phpt new file mode 100644 index 000000000000..8a76b03588db --- /dev/null +++ b/Zend/tests/generics/syntax/method_decl.phpt @@ -0,0 +1,14 @@ +--TEST-- +Generic syntax: method declaration with type parameters +--FILE-- +(callable $f): U { return $f(); } +} +$r = (new ReflectionClass('C'))->getMethod('map'); +var_dump($r->isGeneric()); +echo $r->getGenericParameters()[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +U diff --git a/Zend/tests/generics/syntax/named_type_args.phpt b/Zend/tests/generics/syntax/named_type_args.phpt new file mode 100644 index 000000000000..7e4151ccd8e2 --- /dev/null +++ b/Zend/tests/generics/syntax/named_type_args.phpt @@ -0,0 +1,18 @@ +--TEST-- +Generic syntax: type arguments on a named type at use site +--FILE-- + {} +function f(Container $x): Container { return $x; } +$r = new ReflectionFunction('f'); +$pt = $r->getParameters()[0]->getType(); +// With reified params, the type's name is the canonical monomorph, not the +// bare base. Generic args are still queryable via getGenericArguments(). +echo $pt->getName(), "\n"; +var_dump($pt->hasGenericArguments()); +foreach ($pt->getGenericArguments() as $a) echo $a->getName(), "\n"; +?> +--EXPECT-- +Container +bool(true) +int diff --git a/Zend/tests/generics/syntax/nested_three_levels.phpt b/Zend/tests/generics/syntax/nested_three_levels.phpt new file mode 100644 index 000000000000..f68dae761c32 --- /dev/null +++ b/Zend/tests/generics/syntax/nested_three_levels.phpt @@ -0,0 +1,21 @@ +--TEST-- +Generic syntax: three levels of nesting (>>> splitting) +--FILE-- + {} +class B {} +class A {} +function f(): A>> { return new A::>>(); } +$rt = (new ReflectionFunction('f'))->getReturnType(); +echo $rt->getName(), "\n"; +$arg1 = $rt->getGenericArguments()[0]; +echo $arg1->getName(), "\n"; +$arg2 = $arg1->getGenericArguments()[0]; +echo $arg2->getName(), "\n"; +echo $arg2->getGenericArguments()[0]->getName(), "\n"; +?> +--EXPECT-- +A>> +B +C +int diff --git a/Zend/tests/generics/syntax/nested_two_levels.phpt b/Zend/tests/generics/syntax/nested_two_levels.phpt new file mode 100644 index 000000000000..d5c43c30a455 --- /dev/null +++ b/Zend/tests/generics/syntax/nested_two_levels.phpt @@ -0,0 +1,17 @@ +--TEST-- +Generic syntax: two levels of nesting (>> splitting) +--FILE-- + {} +class Outer {} +function f(): Outer> { return new Outer::>(); } +$rt = (new ReflectionFunction('f'))->getReturnType(); +echo $rt->getName(), "\n"; +$arg = $rt->getGenericArguments()[0]; +echo $arg->getName(), "\n"; +echo $arg->getGenericArguments()[0]->getName(), "\n"; +?> +--EXPECT-- +Outer> +Inner +int diff --git a/Zend/tests/generics/syntax/trailing_comma_args.phpt b/Zend/tests/generics/syntax/trailing_comma_args.phpt new file mode 100644 index 000000000000..1b8c2c93563f --- /dev/null +++ b/Zend/tests/generics/syntax/trailing_comma_args.phpt @@ -0,0 +1,11 @@ +--TEST-- +Generic syntax: trailing comma in type argument list +--FILE-- + {} +function f(C $x): void {} +$pt = (new ReflectionFunction('f'))->getParameters()[0]->getType(); +echo count($pt->getGenericArguments()), "\n"; +?> +--EXPECT-- +2 diff --git a/Zend/tests/generics/syntax/trailing_comma_params.phpt b/Zend/tests/generics/syntax/trailing_comma_params.phpt new file mode 100644 index 000000000000..3a386ffdeeae --- /dev/null +++ b/Zend/tests/generics/syntax/trailing_comma_params.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: trailing comma in type parameter list +--FILE-- + {} +class Pair {} +echo (new ReflectionClass('Box'))->isGeneric() ? 'ok' : 'fail', "\n"; +echo (new ReflectionClass('Pair'))->isGeneric() ? 'ok' : 'fail', "\n"; +?> +--EXPECT-- +ok +ok diff --git a/Zend/tests/generics/syntax/trait_decl.phpt b/Zend/tests/generics/syntax/trait_decl.phpt new file mode 100644 index 000000000000..32d46440ea81 --- /dev/null +++ b/Zend/tests/generics/syntax/trait_decl.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: trait with type parameters +--FILE-- + {} +$r = new ReflectionClass('Container'); +var_dump($r->isGeneric()); +echo $r->getGenericParameters()[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +T diff --git a/Zend/tests/generics/syntax/trait_use_args.phpt b/Zend/tests/generics/syntax/trait_use_args.phpt new file mode 100644 index 000000000000..acf319fb65ba --- /dev/null +++ b/Zend/tests/generics/syntax/trait_use_args.phpt @@ -0,0 +1,15 @@ +--TEST-- +Generic syntax: trait use with type arguments +--FILE-- + { + public T $tval; +} +class Box { + use Container; +} +$r = new ReflectionClass('Box'); +echo $r->isGeneric() ? 'ok' : 'fail', "\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/generics/syntax/turbofish_complex_args.phpt b/Zend/tests/generics/syntax/turbofish_complex_args.phpt new file mode 100644 index 000000000000..460f6d65fa1b --- /dev/null +++ b/Zend/tests/generics/syntax/turbofish_complex_args.phpt @@ -0,0 +1,11 @@ +--TEST-- +Generic syntax: turbofish with composite type arguments +--FILE-- +($x) { return $x; } +echo f::(42), "\n"; +echo f::('hi'), "\n"; +?> +--EXPECT-- +42 +hi diff --git a/Zend/tests/generics/syntax/turbofish_fcc.phpt b/Zend/tests/generics/syntax/turbofish_fcc.phpt new file mode 100644 index 000000000000..31080672c5b4 --- /dev/null +++ b/Zend/tests/generics/syntax/turbofish_fcc.phpt @@ -0,0 +1,24 @@ +--TEST-- +Generic syntax: turbofish on first-class callable creation +--FILE-- +(int $x): int { return $x * 2; } +class C { + public static function s(int $x): int { return $x + 100; } + public function m(int $x): int { return $x - 1; } +} + +$f = f::(...); +echo $f(5), "\n"; + +$g = C::s::(...); +echo $g(5), "\n"; + +$c = new C; +$h = $c->m::(...); +echo $h(5), "\n"; +?> +--EXPECT-- +10 +105 +4 diff --git a/Zend/tests/generics/syntax/turbofish_function_call.phpt b/Zend/tests/generics/syntax/turbofish_function_call.phpt new file mode 100644 index 000000000000..e397c8344643 --- /dev/null +++ b/Zend/tests/generics/syntax/turbofish_function_call.phpt @@ -0,0 +1,13 @@ +--TEST-- +Generic syntax: turbofish on function call +--FILE-- +($a, $b) { return $a + $b; } +echo add::(1, 2), "\n"; +echo add::(3, 4), "\n"; +echo add::(5, 6), "\n"; +?> +--EXPECT-- +3 +7 +11 diff --git a/Zend/tests/generics/syntax/turbofish_method_call.phpt b/Zend/tests/generics/syntax/turbofish_method_call.phpt new file mode 100644 index 000000000000..0bfe9f7a2230 --- /dev/null +++ b/Zend/tests/generics/syntax/turbofish_method_call.phpt @@ -0,0 +1,17 @@ +--TEST-- +Generic syntax: turbofish on instance method call (including nullsafe) +--FILE-- +($x) { return $x * 3; } +} +$c = new C; +echo $c->m::(5), "\n"; +echo $c?->m::(7), "\n"; +$null = null; +var_dump($null?->m::(9)); +?> +--EXPECT-- +15 +21 +NULL diff --git a/Zend/tests/generics/syntax/turbofish_new.phpt b/Zend/tests/generics/syntax/turbofish_new.phpt new file mode 100644 index 000000000000..c79c15f90a4b --- /dev/null +++ b/Zend/tests/generics/syntax/turbofish_new.phpt @@ -0,0 +1,32 @@ +--TEST-- +Generic syntax: turbofish on new with various class-ref forms +--FILE-- + { + public function __construct(public int $v) {} +} + +$b = new Box::(1); +echo $b->v, "\n"; + +$cls = 'Box'; +$b = new $cls::(2); +echo $b->v, "\n"; + +$expr = fn() => 'Box'; +$b = new ($expr())::(3); +echo $b->v, "\n"; + +class Container { + public static function make(): self { + return new self::; + } +} +$c = Container::make(); +echo get_class($c), "\n"; +?> +--EXPECT-- +1 +2 +3 +Container diff --git a/Zend/tests/generics/syntax/turbofish_static_call.phpt b/Zend/tests/generics/syntax/turbofish_static_call.phpt new file mode 100644 index 000000000000..b2a1d74d4b61 --- /dev/null +++ b/Zend/tests/generics/syntax/turbofish_static_call.phpt @@ -0,0 +1,13 @@ +--TEST-- +Generic syntax: turbofish on static method call +--FILE-- +($x) { return $x * 2; } +} +echo C::s::(5), "\n"; +echo C::s::(7), "\n"; +?> +--EXPECT-- +10 +14 diff --git a/Zend/tests/generics/syntax/variance_bound_default.phpt b/Zend/tests/generics/syntax/variance_bound_default.phpt new file mode 100644 index 000000000000..55c6460fef55 --- /dev/null +++ b/Zend/tests/generics/syntax/variance_bound_default.phpt @@ -0,0 +1,11 @@ +--TEST-- +Generic syntax: variance + bound + default combined +--FILE-- + {} +$p = (new ReflectionClass('Box'))->getGenericParameters()[0]; +echo $p, "\n"; +?> +--EXPECT-- ++T : Bar = Bar diff --git a/Zend/tests/generics/syntax/variance_contravariant.phpt b/Zend/tests/generics/syntax/variance_contravariant.phpt new file mode 100644 index 000000000000..97d1b4d07e91 --- /dev/null +++ b/Zend/tests/generics/syntax/variance_contravariant.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: contravariant type parameter (-T) +--FILE-- + {} +$p = (new ReflectionClass('Consumer'))->getGenericParameters()[0]; +echo $p->getName(), "\n"; +echo $p->getVariance()->name, "\n"; +?> +--EXPECT-- +T +Contravariant diff --git a/Zend/tests/generics/syntax/variance_covariant.phpt b/Zend/tests/generics/syntax/variance_covariant.phpt new file mode 100644 index 000000000000..ea3d76f8d2d4 --- /dev/null +++ b/Zend/tests/generics/syntax/variance_covariant.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: covariant type parameter (+T) +--FILE-- + {} +$p = (new ReflectionClass('Producer'))->getGenericParameters()[0]; +echo $p->getName(), "\n"; +echo $p->getVariance()->name, "\n"; +?> +--EXPECT-- +T +Covariant diff --git a/Zend/tests/generics/syntax/variance_invariant_default.phpt b/Zend/tests/generics/syntax/variance_invariant_default.phpt new file mode 100644 index 000000000000..3fd243c44a06 --- /dev/null +++ b/Zend/tests/generics/syntax/variance_invariant_default.phpt @@ -0,0 +1,12 @@ +--TEST-- +Generic syntax: type parameter without variance is invariant +--FILE-- + {} +$p = (new ReflectionClass('Box'))->getGenericParameters()[0]; +var_dump($p->getVariance() === ReflectionGenericVariance::Invariant); +echo $p->getVariance()->name, "\n"; +?> +--EXPECT-- +bool(true) +Invariant diff --git a/Zend/tests/generics/traits/abstract_method_implemented.phpt b/Zend/tests/generics/traits/abstract_method_implemented.phpt new file mode 100644 index 000000000000..269e70b752a1 --- /dev/null +++ b/Zend/tests/generics/traits/abstract_method_implemented.phpt @@ -0,0 +1,17 @@ +--TEST-- +Traits: an abstract trait method using T accepts an implementer matching the substituted type +--FILE-- + { + public abstract function foo(T $v): T; +} + +class A { + use Thing; + public function foo(string $v): string { return $v; } +} + +echo (new A)->foo("hi"), "\n"; +?> +--EXPECT-- +hi diff --git a/Zend/tests/generics/traits/abstract_method_two_classes.phpt b/Zend/tests/generics/traits/abstract_method_two_classes.phpt new file mode 100644 index 000000000000..1e5b4e67af64 --- /dev/null +++ b/Zend/tests/generics/traits/abstract_method_two_classes.phpt @@ -0,0 +1,24 @@ +--TEST-- +Traits: two classes using the same generic trait can implement the abstract method at distinct substituted types +--FILE-- + { + public abstract function foo(T $v): T; +} + +class StrThing { + use Thing; + public function foo(string $v): string { return $v; } +} + +class IntThing { + use Thing; + public function foo(int $v): int { return $v; } +} + +echo (new StrThing)->foo("a"), "\n"; +echo (new IntThing)->foo(7), "\n"; +?> +--EXPECT-- +a +7 diff --git a/Zend/tests/generics/traits/abstract_method_violates.phpt b/Zend/tests/generics/traits/abstract_method_violates.phpt new file mode 100644 index 000000000000..d1abe4e84cb0 --- /dev/null +++ b/Zend/tests/generics/traits/abstract_method_violates.phpt @@ -0,0 +1,15 @@ +--TEST-- +Traits: an abstract trait method using T rejects an implementer with the wrong substituted type +--FILE-- + { + public abstract function foo(T $v): T; +} + +class A { + use Thing; + public function foo(int $v): int { return $v; } +} +?> +--EXPECTF-- +Fatal error: Declaration of A::foo(int $v): int must be compatible with Thing::foo(string $v): string in %s on line %d diff --git a/Zend/tests/generics/traits/basic_trait.phpt b/Zend/tests/generics/traits/basic_trait.phpt new file mode 100644 index 000000000000..7f459bb5f002 --- /dev/null +++ b/Zend/tests/generics/traits/basic_trait.phpt @@ -0,0 +1,18 @@ +--TEST-- +Traits: trait declares its own type parameter +--FILE-- + { + public T $value; + public function get(): T { return $this->value; } +} +class Box { + use Holder; +} +$rc = new ReflectionClass('Box'); +echo $rc->getProperty('value')->getType()->getName(), "\n"; +echo $rc->getMethod('get')->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +object +object diff --git a/Zend/tests/generics/traits/method_concrete_unchanged.phpt b/Zend/tests/generics/traits/method_concrete_unchanged.phpt new file mode 100644 index 000000000000..ced7fe773e39 --- /dev/null +++ b/Zend/tests/generics/traits/method_concrete_unchanged.phpt @@ -0,0 +1,25 @@ +--TEST-- +Traits: concretely typed parameters and returns are unaffected by substitution +--FILE-- + { + public T $val; + public function takeT(T $x): T { return $x; } + public function bare(int $x): string { return (string)$x; } +} + +class StrHolder { use Holder; } + +$rm = (new ReflectionClass('StrHolder'))->getMethod('bare'); +echo "bare: ", + $rm->getParameters()[0]->getType()->getName(), " -> ", + $rm->getReturnType()->getName(), "\n"; + +$rm = (new ReflectionClass('StrHolder'))->getMethod('takeT'); +echo "takeT: ", + $rm->getParameters()[0]->getType()->getName(), " -> ", + $rm->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +bare: int -> string +takeT: string -> string diff --git a/Zend/tests/generics/traits/method_default_arg.phpt b/Zend/tests/generics/traits/method_default_arg.phpt new file mode 100644 index 000000000000..91eca8edefd1 --- /dev/null +++ b/Zend/tests/generics/traits/method_default_arg.phpt @@ -0,0 +1,20 @@ +--TEST-- +Traits: omitting use args fills the trait parameter defaults into method signatures +--FILE-- + { + public function f(T $x): T { return $x; } +} + +class Impl { use Defaulted; } + +$rm = (new ReflectionClass('Impl'))->getMethod('f'); +echo $rm->getParameters()[0]->getType()->getName(), " -> ", + $rm->getReturnType()->getName(), "\n"; + +$i = new Impl; +echo $i->f(42), "\n"; +?> +--EXPECT-- +int -> int +42 diff --git a/Zend/tests/generics/traits/method_signature_substituted.phpt b/Zend/tests/generics/traits/method_signature_substituted.phpt new file mode 100644 index 000000000000..578cf1d11976 --- /dev/null +++ b/Zend/tests/generics/traits/method_signature_substituted.phpt @@ -0,0 +1,25 @@ +--TEST-- +Traits: trait method param and return types are substituted from the use clause's bound arguments +--FILE-- + { + public function take(T $x): T { return $x; } +} + +class IntHolder { use Holder; } +class StrHolder { use Holder; } + +foreach (['IntHolder', 'StrHolder'] as $cn) { + $rm = (new ReflectionClass($cn))->getMethod('take'); + $p = $rm->getParameters()[0]->getType()->getName(); + $r = $rm->getReturnType()->getName(); + echo "$cn::take: $p -> $r\n"; +} + +$ih = new IntHolder; +echo $ih->take(7), "\n"; +?> +--EXPECT-- +IntHolder::take: int -> int +StrHolder::take: string -> string +7 diff --git a/Zend/tests/generics/traits/method_variadic_substituted.phpt b/Zend/tests/generics/traits/method_variadic_substituted.phpt new file mode 100644 index 000000000000..cf0cb4c50ede --- /dev/null +++ b/Zend/tests/generics/traits/method_variadic_substituted.phpt @@ -0,0 +1,19 @@ +--TEST-- +Traits: variadic parameter typed T is substituted in the using class +--FILE-- + { + public function all(T ...$items): int { return count($items); } +} + +class IntAcceptor { use Acceptor; } + +$rm = (new ReflectionClass('IntAcceptor'))->getMethod('all'); +echo "param type: ", $rm->getParameters()[0]->getType()->getName(), "\n"; + +$a = new IntAcceptor; +echo $a->all(1, 2, 3), "\n"; +?> +--EXPECT-- +param type: int +3 diff --git a/Zend/tests/generics/traits/multiple_traits.phpt b/Zend/tests/generics/traits/multiple_traits.phpt new file mode 100644 index 000000000000..b21a673dcab5 --- /dev/null +++ b/Zend/tests/generics/traits/multiple_traits.phpt @@ -0,0 +1,22 @@ +--TEST-- +Traits: class uses multiple generic traits +--FILE-- + { + public function a(): X { return $this->ax; } + public X $ax; +} +trait B { + public function b(): Y { return $this->by; } + public Y $by; +} +class C { + use A, B; +} +$rc = new ReflectionClass('C'); +echo $rc->getMethod('a')->getReturnType()->getName(), "\n"; +echo $rc->getMethod('b')->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +object +int diff --git a/Zend/tests/generics/traits/property_no_substitution_when_concrete.phpt b/Zend/tests/generics/traits/property_no_substitution_when_concrete.phpt new file mode 100644 index 000000000000..8d93cc907242 --- /dev/null +++ b/Zend/tests/generics/traits/property_no_substitution_when_concrete.phpt @@ -0,0 +1,17 @@ +--TEST-- +Traits: property already concretely typed in the trait is unaffected by `use` clause arguments +--FILE-- + { + public int $count = 0; + public T $val; +} + +class StrBox { use Holder; } + +$rcCount = (new ReflectionClass('StrBox'))->getProperty('count'); +$rcVal = (new ReflectionClass('StrBox'))->getProperty('val'); +echo $rcCount->getType()->getName(), "/", $rcVal->getType()->getName(), "\n"; +?> +--EXPECT-- +int/string diff --git a/Zend/tests/generics/traits/property_substituted_two_classes.phpt b/Zend/tests/generics/traits/property_substituted_two_classes.phpt new file mode 100644 index 000000000000..b0b3680f2d97 --- /dev/null +++ b/Zend/tests/generics/traits/property_substituted_two_classes.phpt @@ -0,0 +1,27 @@ +--TEST-- +Traits: two classes using the same generic trait with different bindings get distinct property types +--FILE-- + { + public T $val; +} + +class IntBox { use Holder; } +class StrBox { use Holder; } + +$ib = new IntBox; +$ib->val = 1; +$sb = new StrBox; +$sb->val = "x"; + +$rcInt = (new ReflectionClass('IntBox'))->getProperty('val'); +$rcStr = (new ReflectionClass('StrBox'))->getProperty('val'); +echo $rcInt->getType()->getName(), "/", $rcStr->getType()->getName(), "\n"; + +try { $ib->val = "no"; } catch (TypeError) { echo "TypeError IntBox\n"; } +try { $sb->val = []; } catch (TypeError) { echo "TypeError StrBox\n"; } +?> +--EXPECT-- +int/string +TypeError IntBox +TypeError StrBox diff --git a/Zend/tests/generics/traits/property_substituted_with_class_arg.phpt b/Zend/tests/generics/traits/property_substituted_with_class_arg.phpt new file mode 100644 index 000000000000..d2d8d39e370c --- /dev/null +++ b/Zend/tests/generics/traits/property_substituted_with_class_arg.phpt @@ -0,0 +1,29 @@ +--TEST-- +Traits: trait property substituted with a class type +--FILE-- + { + public T $val; +} + +class AnimalBox { use Holder; } + +$rp = (new ReflectionClass('AnimalBox'))->getProperty('val'); +echo $rp->getType()->getName(), "\n"; + +$b = new AnimalBox; +$b->val = new Animal; +echo get_class($b->val), "\n"; + +try { + $b->val = 5; +} catch (TypeError) { + echo "TypeError\n"; +} +?> +--EXPECT-- +Animal +Animal +TypeError diff --git a/Zend/tests/generics/traits/trait_constant_type.phpt b/Zend/tests/generics/traits/trait_constant_type.phpt new file mode 100644 index 000000000000..860a0cd34c75 --- /dev/null +++ b/Zend/tests/generics/traits/trait_constant_type.phpt @@ -0,0 +1,18 @@ +--TEST-- +Traits: trait class constant with type parameter +--FILE-- + { + const T MIN = 0; +} +class Box { + use Holder; +} +$rc = new ReflectionClass('Box'); +$consts = $rc->getReflectionConstants(); +foreach ($consts as $c) { + echo $c->getName(), ": ", $c->getValue(), "\n"; +} +?> +--EXPECT-- +MIN: 0 diff --git a/Zend/tests/generics/traits/trait_get_generic_params.phpt b/Zend/tests/generics/traits/trait_get_generic_params.phpt new file mode 100644 index 000000000000..0a437a414821 --- /dev/null +++ b/Zend/tests/generics/traits/trait_get_generic_params.phpt @@ -0,0 +1,14 @@ +--TEST-- +Traits: ReflectionClass::getGenericParameters on trait +--FILE-- + {} +$rc = new ReflectionClass('T'); +foreach ($rc->getGenericParameters() as $p) { + echo $p->getName(), "\n"; +} +?> +--EXPECT-- +A +B +C diff --git a/Zend/tests/generics/traits/trait_isgeneric.phpt b/Zend/tests/generics/traits/trait_isgeneric.phpt new file mode 100644 index 000000000000..b142dfe56deb --- /dev/null +++ b/Zend/tests/generics/traits/trait_isgeneric.phpt @@ -0,0 +1,12 @@ +--TEST-- +Traits: ReflectionClass::isGeneric on trait +--FILE-- + {} +trait U {} +echo (new ReflectionClass('T'))->isGeneric() ? "T:gen\n" : "T:not\n"; +echo (new ReflectionClass('U'))->isGeneric() ? "U:gen\n" : "U:not\n"; +?> +--EXPECT-- +T:gen +U:not diff --git a/Zend/tests/generics/traits/trait_method_isgeneric.phpt b/Zend/tests/generics/traits/trait_method_isgeneric.phpt new file mode 100644 index 000000000000..959155d68cfc --- /dev/null +++ b/Zend/tests/generics/traits/trait_method_isgeneric.phpt @@ -0,0 +1,17 @@ +--TEST-- +Traits: trait method's isGeneric and getGenericParameters +--FILE-- +(U $x): U { return $x; } +} +class C { use T; } +$rm = (new ReflectionClass('C'))->getMethod('f'); +echo $rm->isGeneric() ? "gen\n" : "not\n"; +foreach ($rm->getGenericParameters() as $p) { + echo $p->getName(), "\n"; +} +?> +--EXPECT-- +gen +U diff --git a/Zend/tests/generics/traits/trait_method_runtime.phpt b/Zend/tests/generics/traits/trait_method_runtime.phpt new file mode 100644 index 000000000000..324d473e45c9 --- /dev/null +++ b/Zend/tests/generics/traits/trait_method_runtime.phpt @@ -0,0 +1,26 @@ +--TEST-- +Traits: methods from trait work at runtime +--FILE-- + { + public function get(T $x): T { return $x; } +} +class Box { + use Holder; +} + +$a = new A; +$b = new Box; +echo get_class($b->get($a)), "\n"; + +try { + $b->get("string"); + echo "no error\n"; +} catch (TypeError $e) { + echo "type error\n"; +} +?> +--EXPECT-- +A +type error diff --git a/Zend/tests/generics/traits/trait_property_substituted.phpt b/Zend/tests/generics/traits/trait_property_substituted.phpt new file mode 100644 index 000000000000..a10364cf9450 --- /dev/null +++ b/Zend/tests/generics/traits/trait_property_substituted.phpt @@ -0,0 +1,32 @@ +--TEST-- +Traits: trait property type is substituted from the `use` clause's bound arguments +--FILE-- + { + public T $val; +} + +class IntBox { use Holder; } +class StringBox { use Holder; } + +$rp = (new ReflectionClass('IntBox'))->getProperty('val'); +echo "IntBox::\$val: ", $rp->getType()->getName(), "\n"; + +$rp = (new ReflectionClass('StringBox'))->getProperty('val'); +echo "StringBox::\$val: ", $rp->getType()->getName(), "\n"; + +$ib = new IntBox; +$ib->val = 7; +echo $ib->val, "\n"; + +try { + $ib->val = "x"; +} catch (TypeError $e) { + echo "TypeError\n"; +} +?> +--EXPECT-- +IntBox::$val: int +StringBox::$val: string +7 +TypeError diff --git a/Zend/tests/generics/traits/trait_property_type.phpt b/Zend/tests/generics/traits/trait_property_type.phpt new file mode 100644 index 000000000000..f6510a351ed3 --- /dev/null +++ b/Zend/tests/generics/traits/trait_property_type.phpt @@ -0,0 +1,16 @@ +--TEST-- +Traits: trait property type +--FILE-- + { + public T $val; +} +class Box { + use Holder; +} +$rp = (new ReflectionClass('Box'))->getProperty('val'); +echo $rp->getType()->getName(), "\n"; +?> +--EXPECT-- +Foo diff --git a/Zend/tests/generics/traits/trait_use_args_compile.phpt b/Zend/tests/generics/traits/trait_use_args_compile.phpt new file mode 100644 index 000000000000..84ae43ab0ff0 --- /dev/null +++ b/Zend/tests/generics/traits/trait_use_args_compile.phpt @@ -0,0 +1,17 @@ +--TEST-- +Traits: trait use clause with type arguments compiles +--FILE-- + { + public function tag(X $x): X { return $x; } +} +class Box { + use Holder; +} +$b = new Box; +echo get_class($b), "\n"; +echo "ok\n"; +?> +--EXPECT-- +Box +ok diff --git a/Zend/tests/generics/traits/trait_with_method_param.phpt b/Zend/tests/generics/traits/trait_with_method_param.phpt new file mode 100644 index 000000000000..2203f9b20431 --- /dev/null +++ b/Zend/tests/generics/traits/trait_with_method_param.phpt @@ -0,0 +1,17 @@ +--TEST-- +Traits: trait method declares its own type parameter +--FILE-- +(U $x): U { return $x; } +} +class C { + use T; +} +$rm = (new ReflectionClass('C'))->getMethod('f'); +echo $rm->getParameters()[0]->getType()->getName(), "\n"; +echo $rm->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +int +int diff --git a/Zend/tests/generics/turbofish/arity/attribute_arity.phpt b/Zend/tests/generics/turbofish/arity/attribute_arity.phpt new file mode 100644 index 000000000000..9f6fa044538e --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/attribute_arity.phpt @@ -0,0 +1,38 @@ +--TEST-- +Turbofish arity: ReflectionAttribute::newInstance() enforces arity against the attribute class +--FILE-- + { + public function __construct(public string $tag) {} +} + +#[TaggedAttr::(tag: "ok")] +class A {} + +#[TaggedAttr::(tag: "bad")] +class B {} + +#[TaggedAttr(tag: "no-turbo")] +class D {} + +$ra = (new ReflectionClass("A"))->getAttributes()[0]; +echo "A: ", $ra->newInstance()->tag, "\n"; + +$rb = (new ReflectionClass("B"))->getAttributes()[0]; +try { + $rb->newInstance(); +} catch (ArgumentCountError $e) { + echo "B: ", $e->getMessage(), "\n"; +} + +// no turbofish at all -> no arity check, defaults apply (here T has no default) +// but newInstance() doesn't supply type args, which is arity 0; required is 1 -> still fails? No. +// arity 0 is treated as "no turbofish" and skips the check entirely. +$rd = (new ReflectionClass("D"))->getAttributes()[0]; +echo "D: ", $rd->newInstance()->tag, "\n"; +?> +--EXPECT-- +A: ok +B: Too many generic type arguments to new TaggedAttr, 2 passed and exactly 1 expected +D: no-turbo diff --git a/Zend/tests/generics/turbofish/arity/below_required.phpt b/Zend/tests/generics/turbofish/arity/below_required.phpt new file mode 100644 index 000000000000..09514d55a338 --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/below_required.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish arity: providing fewer than required even with some defaults still throws +--FILE-- +($x) { return $x; } +try { + f::(1); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Too few generic type arguments to f(), 1 passed and at least 2 expected diff --git a/Zend/tests/generics/turbofish/arity/function_too_few.phpt b/Zend/tests/generics/turbofish/arity/function_too_few.phpt new file mode 100644 index 000000000000..d5469444288d --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/function_too_few.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish arity: too few type arguments to a function throws ArgumentCountError +--FILE-- +($x, $y) { return [$x, $y]; } +try { + f::(1, 2); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Too few generic type arguments to f(), 1 passed and exactly 2 expected diff --git a/Zend/tests/generics/turbofish/arity/function_too_many.phpt b/Zend/tests/generics/turbofish/arity/function_too_many.phpt new file mode 100644 index 000000000000..15747c2384fd --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/function_too_many.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish arity: too many type arguments to a function throws ArgumentCountError +--FILE-- +($x) { return $x; } +try { + f::(1); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Too many generic type arguments to f(), 2 passed and exactly 1 expected diff --git a/Zend/tests/generics/turbofish/arity/method_arity.phpt b/Zend/tests/generics/turbofish/arity/method_arity.phpt new file mode 100644 index 000000000000..81eb1cb37219 --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/method_arity.phpt @@ -0,0 +1,24 @@ +--TEST-- +Turbofish arity: instance method, static method, nullsafe call all enforce arity +--FILE-- +($x) { return $x; } + public static function s($x) { return $x; } +} + +$c = new C; + +try { $c->m::(1); } +catch (ArgumentCountError $e) { echo $e->getMessage(), "\n"; } + +try { $c?->m::(1); } +catch (ArgumentCountError $e) { echo $e->getMessage(), "\n"; } + +try { C::s::(1); } +catch (ArgumentCountError $e) { echo $e->getMessage(), "\n"; } +?> +--EXPECT-- +Too many generic type arguments to C::m(), 2 passed and exactly 1 expected +Too many generic type arguments to C::m(), 2 passed and exactly 1 expected +Too few generic type arguments to C::s(), 1 passed and exactly 2 expected diff --git a/Zend/tests/generics/turbofish/arity/new_arity.phpt b/Zend/tests/generics/turbofish/arity/new_arity.phpt new file mode 100644 index 000000000000..f7ff94b67a3e --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/new_arity.phpt @@ -0,0 +1,25 @@ +--TEST-- +Turbofish arity: new ::<...> enforces arity against class generic parameters +--FILE-- + { + public function __construct(public int $v) {} +} +class Pair {} + +try { new Box::(1); } +catch (ArgumentCountError $e) { echo $e->getMessage(), "\n"; } + +// Pair: K required, V has default - so 1 or 2 args is OK, 0 or 3 is not. +// With monomorphization, the missing trailing arg is filled from the default, +// so the canonical name reflects the substituted Pair. +$p = new Pair::(); +echo get_class($p), "\n"; + +try { new Pair::(); } +catch (ArgumentCountError $e) { echo $e->getMessage(), "\n"; } +?> +--EXPECT-- +Too many generic type arguments to new Box, 2 passed and exactly 1 expected +Pair +Too many generic type arguments to new Pair, 3 passed and at most 2 expected diff --git a/Zend/tests/generics/turbofish/arity/non_generic_callee.phpt b/Zend/tests/generics/turbofish/arity/non_generic_callee.phpt new file mode 100644 index 000000000000..5e7a6a622205 --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/non_generic_callee.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish arity: turbofish on a non-generic callee throws ArgumentCountError +--FILE-- +(42); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Too many generic type arguments to f(), 1 passed and exactly 0 expected diff --git a/Zend/tests/generics/turbofish/arity/with_defaults.phpt b/Zend/tests/generics/turbofish/arity/with_defaults.phpt new file mode 100644 index 000000000000..24509e622cb2 --- /dev/null +++ b/Zend/tests/generics/turbofish/arity/with_defaults.phpt @@ -0,0 +1,27 @@ +--TEST-- +Turbofish arity: defaults extend the accepted arity range +--FILE-- +($x) { return $x; } + +// arity 1, 2, 3 all valid +var_dump(f::(1)); +var_dump(f::(2)); +var_dump(f::(3)); + +// arity 0 (i.e., no turbofish) is also valid +var_dump(f(4)); + +// arity 4 exceeds total +try { + f::(5); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +int(1) +int(2) +int(3) +int(4) +Too many generic type arguments to f(), 4 passed and at most 3 expected diff --git a/Zend/tests/generics/turbofish/bounds/attribute_satisfies.phpt b/Zend/tests/generics/turbofish/bounds/attribute_satisfies.phpt new file mode 100644 index 000000000000..7d346132f2f6 --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/attribute_satisfies.phpt @@ -0,0 +1,22 @@ +--TEST-- +Turbofish bound check: attribute newInstance accepts an arg that satisfies the bound +--FILE-- + { + public function __construct() {} +} + +#[Bounded::] +function f(): void {} + +foreach ((new ReflectionFunction('f'))->getAttributes() as $attr) { + $attr->newInstance(); +} +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/turbofish/bounds/attribute_under_opcache.phpt b/Zend/tests/generics/turbofish/bounds/attribute_under_opcache.phpt new file mode 100644 index 000000000000..5cbc57dbd645 --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/attribute_under_opcache.phpt @@ -0,0 +1,28 @@ +--TEST-- +Turbofish bound check: attribute generic args are persisted across opcache file cache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +--FILE-- + { + public function __construct() {} +} + +#[Bounded::] +function f(): void {} + +foreach ((new ReflectionFunction('f'))->getAttributes() as $attr) { + try { + $attr->newInstance(); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } +} +?> +--EXPECT-- +Type argument 1 to new Bounded does not satisfy the bound Animal on parameter T, int given diff --git a/Zend/tests/generics/turbofish/bounds/attribute_violates.phpt b/Zend/tests/generics/turbofish/bounds/attribute_violates.phpt new file mode 100644 index 000000000000..c13cb4e0dd3a --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/attribute_violates.phpt @@ -0,0 +1,24 @@ +--TEST-- +Turbofish bound check: attribute newInstance rejects a type argument that violates the bound +--FILE-- + { + public function __construct() {} +} + +#[Bounded::] +function f(): void {} + +foreach ((new ReflectionFunction('f'))->getAttributes() as $attr) { + try { + $attr->newInstance(); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } +} +?> +--EXPECT-- +Type argument 1 to new Bounded does not satisfy the bound Animal on parameter T, int given diff --git a/Zend/tests/generics/turbofish/bounds/error_renders_args.phpt b/Zend/tests/generics/turbofish/bounds/error_renders_args.phpt new file mode 100644 index 000000000000..76993541f1ea --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/error_renders_args.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bound error message: NAMED_WITH_ARGS bound is rendered with its type arguments +--FILE-- + {} + +class Sorter> {} + +try { + new Sorter::; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Type argument 1 to new Sorter does not satisfy the bound Comparable on parameter T, int given diff --git a/Zend/tests/generics/turbofish/bounds/function_call_violates.phpt b/Zend/tests/generics/turbofish/bounds/function_call_violates.phpt new file mode 100644 index 000000000000..354e183508e4 --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/function_call_violates.phpt @@ -0,0 +1,15 @@ +--TEST-- +Turbofish bound check: function call with a concrete arg violating the bound +--FILE-- +(): void {} + +try { + id::(); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Type argument 1 to call id() does not satisfy the bound Animal on parameter T, string given diff --git a/Zend/tests/generics/turbofish/bounds/method_call_violates.phpt b/Zend/tests/generics/turbofish/bounds/method_call_violates.phpt new file mode 100644 index 000000000000..7abf3a3d42cf --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/method_call_violates.phpt @@ -0,0 +1,25 @@ +--TEST-- +Turbofish bound check: method call with a concrete arg violating the bound +--FILE-- +(): void {} + public static function spick(): void {} +} + +try { + (new Service)->pick::(); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +try { + Service::spick::(); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Type argument 1 to call Service::pick() does not satisfy the bound Animal on parameter T, int given +Type argument 1 to call Service::spick() does not satisfy the bound Animal on parameter T, int given diff --git a/Zend/tests/generics/turbofish/bounds/multi_param_first_violates.phpt b/Zend/tests/generics/turbofish/bounds/multi_param_first_violates.phpt new file mode 100644 index 000000000000..e0729fe4c0d8 --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/multi_param_first_violates.phpt @@ -0,0 +1,17 @@ +--TEST-- +Turbofish bound check: multi-parameter callee, first arg violates +--FILE-- +(): void {} + +try { + pair::(); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Type argument 1 to call pair() does not satisfy the bound Animal on parameter A, int given diff --git a/Zend/tests/generics/turbofish/bounds/multi_param_second_violates.phpt b/Zend/tests/generics/turbofish/bounds/multi_param_second_violates.phpt new file mode 100644 index 000000000000..83bfbede7afa --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/multi_param_second_violates.phpt @@ -0,0 +1,17 @@ +--TEST-- +Turbofish bound check: multi-parameter callee, second arg violates +--FILE-- +(): void {} + +try { + pair::(); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Type argument 2 to call pair() does not satisfy the bound Dog on parameter B, Animal given diff --git a/Zend/tests/generics/turbofish/bounds/new_satisfies.phpt b/Zend/tests/generics/turbofish/bounds/new_satisfies.phpt new file mode 100644 index 000000000000..a1bb8d8339d1 --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/new_satisfies.phpt @@ -0,0 +1,14 @@ +--TEST-- +Turbofish bound check: new with a concrete arg satisfying the bound +--FILE-- + {} + +new Box::; +new Box::; +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/turbofish/bounds/new_violates.phpt b/Zend/tests/generics/turbofish/bounds/new_violates.phpt new file mode 100644 index 000000000000..96734fb2c288 --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/new_violates.phpt @@ -0,0 +1,15 @@ +--TEST-- +Turbofish bound check: new with a concrete arg violating the bound throws TypeError +--FILE-- + {} + +try { + new Box::; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Type argument 1 to new Box does not satisfy the bound Animal on parameter T, int given diff --git a/Zend/tests/generics/turbofish/bounds/no_bound_no_check.phpt b/Zend/tests/generics/turbofish/bounds/no_bound_no_check.phpt new file mode 100644 index 000000000000..f2f586086d2a --- /dev/null +++ b/Zend/tests/generics/turbofish/bounds/no_bound_no_check.phpt @@ -0,0 +1,15 @@ +--TEST-- +Turbofish bound check: parameters without bounds accept any type +--FILE-- + {} +function id(): void {} + +new Box::; +new Box::; +id::(); +id::(); +echo "OK\n"; +?> +--EXPECT-- +OK diff --git a/Zend/tests/generics/turbofish/composite_args.phpt b/Zend/tests/generics/turbofish/composite_args.phpt new file mode 100644 index 000000000000..8c69b6555b8b --- /dev/null +++ b/Zend/tests/generics/turbofish/composite_args.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish: union and intersection type arguments +--FILE-- +($x) { return $x; } +var_dump(f::(42)); +var_dump(f::(42)); +var_dump(f::<(A&B)|C>(42)); +?> +--EXPECT-- +int(42) +int(42) +int(42) diff --git a/Zend/tests/generics/turbofish/fcc_function.phpt b/Zend/tests/generics/turbofish/fcc_function.phpt new file mode 100644 index 000000000000..c304fb7ceed2 --- /dev/null +++ b/Zend/tests/generics/turbofish/fcc_function.phpt @@ -0,0 +1,10 @@ +--TEST-- +Turbofish: first-class callable on function +--FILE-- +($x) { return $x; } +$cl = id::(...); +var_dump($cl(7)); +?> +--EXPECT-- +int(7) diff --git a/Zend/tests/generics/turbofish/fcc_method.phpt b/Zend/tests/generics/turbofish/fcc_method.phpt new file mode 100644 index 000000000000..48436c4faee5 --- /dev/null +++ b/Zend/tests/generics/turbofish/fcc_method.phpt @@ -0,0 +1,10 @@ +--TEST-- +Turbofish: first-class callable on instance method +--FILE-- +($x) { return $x * 2; } } +$cl = (new C)->m::(...); +var_dump($cl(5)); +?> +--EXPECT-- +int(10) diff --git a/Zend/tests/generics/turbofish/fcc_static_method.phpt b/Zend/tests/generics/turbofish/fcc_static_method.phpt new file mode 100644 index 000000000000..56eaf1d671cd --- /dev/null +++ b/Zend/tests/generics/turbofish/fcc_static_method.phpt @@ -0,0 +1,10 @@ +--TEST-- +Turbofish: first-class callable on static method +--FILE-- +($x) { return $x; } } +$cl = C::m::(...); +var_dump($cl(11)); +?> +--EXPECT-- +int(11) diff --git a/Zend/tests/generics/turbofish/function_call.phpt b/Zend/tests/generics/turbofish/function_call.phpt new file mode 100644 index 000000000000..8de497d7136e --- /dev/null +++ b/Zend/tests/generics/turbofish/function_call.phpt @@ -0,0 +1,9 @@ +--TEST-- +Turbofish: function call with single type argument +--FILE-- +($x) { return $x; } +var_dump(f::(42)); +?> +--EXPECT-- +int(42) diff --git a/Zend/tests/generics/turbofish/function_call_multi.phpt b/Zend/tests/generics/turbofish/function_call_multi.phpt new file mode 100644 index 000000000000..f9f921f6751f --- /dev/null +++ b/Zend/tests/generics/turbofish/function_call_multi.phpt @@ -0,0 +1,14 @@ +--TEST-- +Turbofish: function call with multiple type arguments +--FILE-- +($a, $b) { return [$a, $b]; } +var_dump(combine::(1, "x")); +?> +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + string(1) "x" +} diff --git a/Zend/tests/generics/turbofish/in_chain.phpt b/Zend/tests/generics/turbofish/in_chain.phpt new file mode 100644 index 000000000000..f11b82a5c847 --- /dev/null +++ b/Zend/tests/generics/turbofish/in_chain.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish: chained calls +--FILE-- +() { return $this; } + public function n($x) { return $x; } +} +$c = new C; +var_dump($c->m::()->n::("hello")); +?> +--EXPECT-- +string(5) "hello" diff --git a/Zend/tests/generics/turbofish/instance_method_call.phpt b/Zend/tests/generics/turbofish/instance_method_call.phpt new file mode 100644 index 000000000000..a93855b4fb14 --- /dev/null +++ b/Zend/tests/generics/turbofish/instance_method_call.phpt @@ -0,0 +1,12 @@ +--TEST-- +Turbofish: instance method call +--FILE-- +($x) { return $x; } +} +$c = new C; +var_dump($c->m::(99)); +?> +--EXPECT-- +int(99) diff --git a/Zend/tests/generics/turbofish/instanceof_with_args.phpt b/Zend/tests/generics/turbofish/instanceof_with_args.phpt new file mode 100644 index 000000000000..459885fcdfdf --- /dev/null +++ b/Zend/tests/generics/turbofish/instanceof_with_args.phpt @@ -0,0 +1,17 @@ +--TEST-- +Turbofish: instanceof with type arguments compares against the monomorph canonical name +--FILE-- + {} +class Animal {} +class Dog {} + +$b = new B::(); +var_dump($b instanceof B); // true: every mono extends the bare class +var_dump($b instanceof B); // true: same canonical mono +var_dump($b instanceof B); // false: distinct mono +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) diff --git a/Zend/tests/generics/turbofish/many_type_args.phpt b/Zend/tests/generics/turbofish/many_type_args.phpt new file mode 100644 index 000000000000..59d5193f5e1a --- /dev/null +++ b/Zend/tests/generics/turbofish/many_type_args.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish: arity must match callee's declared generic parameters +--FILE-- +($x) { return $x; } +try { + f::(7); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Too many generic type arguments to f(), 3 passed and exactly 1 expected diff --git a/Zend/tests/generics/turbofish/naked_new_with_defaults.phpt b/Zend/tests/generics/turbofish/naked_new_with_defaults.phpt new file mode 100644 index 000000000000..55afc9bc1f54 --- /dev/null +++ b/Zend/tests/generics/turbofish/naked_new_with_defaults.phpt @@ -0,0 +1,29 @@ +--TEST-- +Naked `new GenericClass()` synthesizes the monomorph when every parameter has a default +--FILE-- + { + public function __construct(public mixed $value) {} +} + +class Pair { + public function __construct(public mixed $left, public mixed $right) {} +} + +$b = new Box(42); +var_dump($b::class); +var_dump($b instanceof Box); + +$p = new Pair(1, "hi"); +var_dump($p::class); +var_dump($p instanceof Pair); + +// Identity: two naked-new's of the same class produce instances of the same monomorph. +var_dump((new Box(1))::class === (new Box(2))::class); +?> +--EXPECT-- +string(8) "Box" +bool(true) +string(16) "Pair" +bool(true) +bool(true) diff --git a/Zend/tests/generics/turbofish/nested_args.phpt b/Zend/tests/generics/turbofish/nested_args.phpt new file mode 100644 index 000000000000..ec9f4c25fcbf --- /dev/null +++ b/Zend/tests/generics/turbofish/nested_args.phpt @@ -0,0 +1,15 @@ +--TEST-- +Turbofish: nested type arguments +--FILE-- + {} +function f($x) { return $x; } +var_dump(f::>(["a", "b"])); +?> +--EXPECT-- +array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" +} diff --git a/Zend/tests/generics/turbofish/new_with_args.phpt b/Zend/tests/generics/turbofish/new_with_args.phpt new file mode 100644 index 000000000000..494aeb67dbe1 --- /dev/null +++ b/Zend/tests/generics/turbofish/new_with_args.phpt @@ -0,0 +1,13 @@ +--TEST-- +Turbofish: new with type arguments +--FILE-- + { + public int $x; + public function __construct(int $x) { $this->x = $x; } +} +$b = new Box::(42); +echo $b->x, "\n"; +?> +--EXPECT-- +42 diff --git a/Zend/tests/generics/turbofish/no_runtime_effect.phpt b/Zend/tests/generics/turbofish/no_runtime_effect.phpt new file mode 100644 index 000000000000..632fee88d045 --- /dev/null +++ b/Zend/tests/generics/turbofish/no_runtime_effect.phpt @@ -0,0 +1,15 @@ +--TEST-- +Turbofish: with matching arity has zero runtime effect on values +--FILE-- +(int $x): int { return $x * 2; } +var_dump(f(5)); +var_dump(f::(5)); +var_dump(f::(5)); +var_dump(f::(5)); +?> +--EXPECT-- +int(10) +int(10) +int(10) +int(10) diff --git a/Zend/tests/generics/turbofish/nullsafe_method_call.phpt b/Zend/tests/generics/turbofish/nullsafe_method_call.phpt new file mode 100644 index 000000000000..fe4d04782ecc --- /dev/null +++ b/Zend/tests/generics/turbofish/nullsafe_method_call.phpt @@ -0,0 +1,15 @@ +--TEST-- +Turbofish: nullsafe method call +--FILE-- +($x) { return $x; } +} +$c = new C; +var_dump($c?->m::(5)); +$null = null; +var_dump($null?->m::(5)); +?> +--EXPECT-- +int(5) +NULL diff --git a/Zend/tests/generics/turbofish/static_method_call.phpt b/Zend/tests/generics/turbofish/static_method_call.phpt new file mode 100644 index 000000000000..681b35adac81 --- /dev/null +++ b/Zend/tests/generics/turbofish/static_method_call.phpt @@ -0,0 +1,11 @@ +--TEST-- +Turbofish: static method call +--FILE-- +($x) { return $x; } +} +var_dump(C::m::(7)); +?> +--EXPECT-- +int(7) diff --git a/Zend/tests/generics/turbofish/turbofish_in_attribute.phpt b/Zend/tests/generics/turbofish/turbofish_in_attribute.phpt new file mode 100644 index 000000000000..c8822c08ccf7 --- /dev/null +++ b/Zend/tests/generics/turbofish/turbofish_in_attribute.phpt @@ -0,0 +1,39 @@ +--TEST-- +Turbofish: type arguments are accepted on attribute declarations +--FILE-- + { + public function __construct(public int $priority = 0) {} +} + +class UserCreated {} +class UserDeleted {} +class OrderPlaced {} + +class EventListener { + #[Listens::] + public function onUserCreated(object $event): void {} + + #[Listens::()] + public function onUserDeleted(object $event): void {} + + #[Listens::(priority: -1)] + public function onOrderPlaced(object $event): void {} +} + +$rc = new ReflectionClass(EventListener::class); +foreach ($rc->getMethods() as $method) { + foreach ($method->getAttributes() as $attr) { + $instance = $attr->newInstance(); + echo $method->getName(), ": #[", $attr->getName(), + "] priority=", $instance->priority, "\n"; + } +} +?> +--EXPECT-- +onUserCreated: #[Listens] priority=0 +onUserDeleted: #[Listens] priority=0 +onOrderPlaced: #[Listens] priority=-1 diff --git a/Zend/tests/generics/turbofish/with_named_args.phpt b/Zend/tests/generics/turbofish/with_named_args.phpt new file mode 100644 index 000000000000..3514c99fb2ed --- /dev/null +++ b/Zend/tests/generics/turbofish/with_named_args.phpt @@ -0,0 +1,11 @@ +--TEST-- +Turbofish: combined with named arguments +--FILE-- +($a, $b) { return "$a:$b"; } +echo f::(a: 1, b: 2), "\n"; +echo f::(b: "x", a: 5), "\n"; +?> +--EXPECT-- +1:2 +5:x diff --git a/Zend/tests/generics/turbofish/with_spread.phpt b/Zend/tests/generics/turbofish/with_spread.phpt new file mode 100644 index 000000000000..c35332c212a6 --- /dev/null +++ b/Zend/tests/generics/turbofish/with_spread.phpt @@ -0,0 +1,10 @@ +--TEST-- +Turbofish: combined with spread/unpacking +--FILE-- +($a, $b, $c) { return $a + $b + $c; } +$args = [1, 2, 3]; +echo f::(...$args), "\n"; +?> +--EXPECT-- +6 diff --git a/Zend/tests/009.phpt b/Zend/tests/get_class_basic.phpt similarity index 100% rename from Zend/tests/009.phpt rename to Zend/tests/get_class_basic.phpt diff --git a/Zend/tests/get_included_files_basic.inc b/Zend/tests/get_included_files_basic.inc new file mode 100644 index 000000000000..406acaee6e46 --- /dev/null +++ b/Zend/tests/get_included_files_basic.inc @@ -0,0 +1,3 @@ + diff --git a/Zend/tests/get_included_files_basic.phpt b/Zend/tests/get_included_files_basic.phpt new file mode 100644 index 000000000000..be595a592621 --- /dev/null +++ b/Zend/tests/get_included_files_basic.phpt @@ -0,0 +1,42 @@ +--TEST-- +get_included_files() tests +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + string(%d) "%s" +} +array(2) { + [0]=> + string(%d) "%s" + [1]=> + string(%d) "%s" +} +array(2) { + [0]=> + string(%d) "%s" + [1]=> + string(%d) "%s" +} +array(2) { + [0]=> + string(%d) "%s" + [1]=> + string(%d) "%s" +} +Done diff --git a/Zend/tests/010.phpt b/Zend/tests/get_parent_class_basic.phpt similarity index 100% rename from Zend/tests/010.phpt rename to Zend/tests/get_parent_class_basic.phpt diff --git a/Zend/tests/gh11189.phpt b/Zend/tests/gh11189.phpt index f1c877f20ee4..9f8202b6102b 100644 --- a/Zend/tests/gh11189.phpt +++ b/Zend/tests/gh11189.phpt @@ -2,6 +2,9 @@ GH-11189: Exceeding memory limit in zend_hash_do_resize leaves the array in an invalid state (packed array) --SKIPIF-- --INI-- @@ -15,6 +18,7 @@ ob_start(function() { $a[] = 2; } fwrite(STDOUT, "Success"); + return ''; }); $a = []; diff --git a/Zend/tests/gh11189_1.phpt b/Zend/tests/gh11189_1.phpt index 53727908e5e2..d5b4ee92b62d 100644 --- a/Zend/tests/gh11189_1.phpt +++ b/Zend/tests/gh11189_1.phpt @@ -2,6 +2,9 @@ GH-11189: Exceeding memory limit in zend_hash_do_resize leaves the array in an invalid state (not packed array) --SKIPIF-- --INI-- @@ -15,6 +18,7 @@ ob_start(function() { $a[] = 2; } fwrite(STDOUT, "Success"); + return ''; }); $a = ["not packed" => 1]; diff --git a/Zend/tests/gh14003.phpt b/Zend/tests/gh14003.phpt index 92a6c5919ab5..8d25cad863c1 100644 --- a/Zend/tests/gh14003.phpt +++ b/Zend/tests/gh14003.phpt @@ -18,7 +18,6 @@ array_filter( --EXPECTF-- Fatal error: Uncaught Exception: Test in %s:%d Stack trace: -#0 [internal function]: foo('a') -#1 %s(%d): array_map(Object(Closure), Array) -#2 {main} +#0 %s(%d): foo('a') +#1 {main} thrown in %s on line %d diff --git a/Zend/tests/gh16408.phpt b/Zend/tests/gh16408.phpt index f28c6435bfe7..09d9e8cbb524 100644 --- a/Zend/tests/gh16408.phpt +++ b/Zend/tests/gh16408.phpt @@ -6,6 +6,7 @@ $counter = 0; ob_start(function ($buffer) use (&$c, &$counter) { $c = 0; ++$counter; + return ''; }, 1); $c .= []; $c .= []; diff --git a/Zend/tests/gh16799.phpt b/Zend/tests/gh16799.phpt index ce1dbd5b1655..d31d1a5705c6 100644 --- a/Zend/tests/gh16799.phpt +++ b/Zend/tests/gh16799.phpt @@ -15,7 +15,12 @@ Test::test(); --EXPECTF-- Fatal error: Uncaught Exception: Use of "static" in callables is deprecated in %s:%d Stack trace: -#0 %s(%d): {closure:%s:%d}(8192, 'Use of "static"...', %s, %d) +#0 %s(%d): {closure:%s}(8192, 'Use of "static"%s', '%s', %d) #1 %s(%d): Test::test() #2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): Test::test() +#1 {main} thrown in %s on line %d diff --git a/Zend/tests/gh18581.phpt b/Zend/tests/gh18581.phpt new file mode 100644 index 000000000000..cc5c0fff02e9 --- /dev/null +++ b/Zend/tests/gh18581.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-18581: Coerce numeric string keys from iterators when argument unpacking +--FILE-- + 'first'; + yield '101' => 'second'; + yield '102' => 'third'; + yield 'named' => 'fourth'; +} + +function test($x = null, $y = null, ...$z) { + var_dump($x, $y, $z); + var_dump($z[0]); + var_dump($z['named']); +} + +test(...g()); + +?> +--EXPECT-- +string(5) "first" +string(6) "second" +array(2) { + [0]=> + string(5) "third" + ["named"]=> + string(6) "fourth" +} +string(5) "third" +string(6) "fourth" diff --git a/Zend/tests/gh18736.phpt b/Zend/tests/gh18736.phpt new file mode 100644 index 000000000000..f397ee39a310 --- /dev/null +++ b/Zend/tests/gh18736.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-18736: Circumvented type check with return by ref + finally +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +test(): Return value must be of type int, string returned diff --git a/Zend/tests/gh19044.phpt b/Zend/tests/gh19044.phpt new file mode 100644 index 000000000000..3477dd3c8b08 --- /dev/null +++ b/Zend/tests/gh19044.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype +--FILE-- +foo; } +} + +var_dump(C2::foo(new C2)); +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(2) +int(1) diff --git a/Zend/tests/gh19053.phpt b/Zend/tests/gh19053.phpt new file mode 100644 index 000000000000..7c82f1bc5f41 --- /dev/null +++ b/Zend/tests/gh19053.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19053: Incorrect properties_info_table for abstract properties +--FILE-- + 2; } +} + +$c = new C; +var_dump($c); + +?> +--EXPECTF-- +object(C)#%d (0) { + ["foo"]=> + uninitialized(mixed) +} diff --git a/Zend/tests/gh19280.phpt b/Zend/tests/gh19280.phpt new file mode 100644 index 000000000000..d73fc91b623f --- /dev/null +++ b/Zend/tests/gh19280.phpt @@ -0,0 +1,81 @@ +--TEST-- +GH-19280: Stale nInternalPosition on rehashing +--FILE-- += 0; $i--) { + $a[$i] = $i; + } + for ($i = 0; $i <= 47; $i++) { + next($a); + } + for ($i = 48; $i >= 2; $i--) { + unset($a[$i]); + } + var_dump(key($a)); + $a[64] = 64; + var_dump(key($a)); +} + +rehash_packed(); +rehash_packed_iterated(); +rehash_string(); +rehash_int(); + +?> +--EXPECT-- +int(62) +int(62) +int(62) +int(62) +string(32) "44f683a84163b3523afe57c2e008bc8c" +string(32) "44f683a84163b3523afe57c2e008bc8c" +int(1) +int(1) diff --git a/Zend/tests/gh19304.phpt b/Zend/tests/gh19304.phpt new file mode 100644 index 000000000000..47e20af64623 --- /dev/null +++ b/Zend/tests/gh19304.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-19304: Incorrect anonymous class type name assertion +--FILE-- +v = 0; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot assign int to property class@anonymous::$v of type self diff --git a/Zend/tests/gh19305-001.phpt b/Zend/tests/gh19305-001.phpt new file mode 100644 index 000000000000..4c9ee37473e3 --- /dev/null +++ b/Zend/tests/gh19305-001.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-19305 001: Operands may be released during comparison +--FILE-- + 'test', + 'bar' => 2, +]; +$b = (object)[ + 'foo' => new class { + public function __toString() { + global $a, $b; + $a = $b = null; + return ''; + } + }, + 'bar' => 2, +]; + +// Comparison of $a->foo and $b->foo calls __toString(), which releases +// both $a and $b. +var_dump($a > $b); + +?> +--EXPECT-- +bool(true) diff --git a/Zend/tests/gh19305-002.phpt b/Zend/tests/gh19305-002.phpt new file mode 100644 index 000000000000..790156191317 --- /dev/null +++ b/Zend/tests/gh19305-002.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-19305 002: Operands may be released during comparison +--FILE-- + 'test', + 'bar' => 2, +]; +$b = [ + 'foo' => new class { + public function __toString() { + global $a, $b; + $a = $b = null; + return ''; + } + }, + 'bar' => 2, +]; + +// Comparison of $a['foo'] and $b['foo'] calls __toString(), which releases +// both $a and $b. +var_dump($a > $b); + +?> +--EXPECT-- +bool(true) diff --git a/Zend/tests/gh19305-003.phpt b/Zend/tests/gh19305-003.phpt new file mode 100644 index 000000000000..7b071156ef8e --- /dev/null +++ b/Zend/tests/gh19305-003.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19305 003: Operands may be released during comparison +--SKIPIF-- + +--FILE-- +newLazyProxy(function () { return new C; }); + +// Comparison calls initializers, which releases $o +var_dump($o > +$r->newLazyGhost(function () { + global $o; + $o = null; +})); + +?> +--EXPECT-- +bool(false) diff --git a/Zend/tests/gh19306.phpt b/Zend/tests/gh19306.phpt new file mode 100644 index 000000000000..e19735d94c84 --- /dev/null +++ b/Zend/tests/gh19306.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-19306: Generator suspended in yield from may be resumed +--FILE-- +next(); + echo "Fiber return\n"; +}); +$fiber->start(); +echo "Fiber suspended\n"; +try { + $a->next(); +} catch (Throwable $t) { + echo $t->getMessage(), "\n"; +} +echo "Destroying fiber\n"; +$fiber = null; +echo "Shutdown\n"; +?> +--EXPECT-- +Fiber start +Fiber suspended +Cannot resume an already running generator +Destroying fiber +Shutdown diff --git a/Zend/tests/gh19326.phpt b/Zend/tests/gh19326.phpt new file mode 100644 index 000000000000..335fdd382ea6 --- /dev/null +++ b/Zend/tests/gh19326.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-19326: Calling Generator::throw() on a running generator with a non-Generator delegate crashes +--FILE-- +rewind(); + +$fiber = new Fiber(function () use ($b) { + $b->next(); +}); + +$fiber->start(); + +try { + $b->throw(new Exception('test')); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +$fiber->resume(); + +?> +--EXPECT-- +Cannot resume an already running generator diff --git a/Zend/tests/gh19543-001.phpt b/Zend/tests/gh19543-001.phpt new file mode 100644 index 000000000000..411140ea5d70 --- /dev/null +++ b/Zend/tests/gh19543-001.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-19543 001: GC treats ZEND_WEAKREF_TAG_MAP references as WeakMap references +--EXTENSIONS-- +zend_test +--FILE-- + +==DONE== +--EXPECT-- +==DONE== diff --git a/Zend/tests/gh19543-002.phpt b/Zend/tests/gh19543-002.phpt new file mode 100644 index 000000000000..4a77b9d823da --- /dev/null +++ b/Zend/tests/gh19543-002.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-19543 002: GC treats ZEND_WEAKREF_TAG_MAP references as WeakMap references +--EXTENSIONS-- +zend_test +--FILE-- + +==DONE== +--EXPECT-- +==DONE== diff --git a/Zend/tests/gh19613.phpt b/Zend/tests/gh19613.phpt new file mode 100644 index 000000000000..cd8360b681c7 --- /dev/null +++ b/Zend/tests/gh19613.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-19613: Invalidated array iterator pointer after array separation +--FILE-- + +--EXPECT-- +===DONE=== diff --git a/Zend/tests/gh19679.phpt b/Zend/tests/gh19679.phpt new file mode 100644 index 000000000000..ab7f3be344d2 --- /dev/null +++ b/Zend/tests/gh19679.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-19679: zend_ssa_range_widening does not converge +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/Zend/tests/gh19719.phpt b/Zend/tests/gh19719.phpt new file mode 100644 index 000000000000..715e847846fe --- /dev/null +++ b/Zend/tests/gh19719.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-19719: Allow empty expressions before declare(strict_types) +--FILE-- + +getMessage(), "\n"; +} + +?> +--EXPECTF-- +takesInt(): Argument #1 ($x) must be of type int, string given, called in %s on line %d diff --git a/Zend/tests/gh19839.phpt b/Zend/tests/gh19839.phpt new file mode 100644 index 000000000000..cc589ce0605f --- /dev/null +++ b/Zend/tests/gh19839.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-19839: Incorrect HASH_FLAG_HAS_EMPTY_IND flag on userland array +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/gh19844.phpt b/Zend/tests/gh19844.phpt new file mode 100644 index 000000000000..297864073535 --- /dev/null +++ b/Zend/tests/gh19844.phpt @@ -0,0 +1,46 @@ +--TEST-- +GH-19844: Bail from stream_close() in zend_shutdown_executor_values() +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Bail in %s on line %d + +Fatal error: Bail in %s on line %d + +Fatal error: Bail in %s on line %d diff --git a/Zend/tests/gh20113.phpt b/Zend/tests/gh20113.phpt new file mode 100644 index 000000000000..64e029a6cec1 --- /dev/null +++ b/Zend/tests/gh20113.phpt @@ -0,0 +1,8 @@ +--TEST-- +GH-20113: new Foo(...) error in constant expressions +--FILE-- + +--EXPECTF-- +Fatal error: Cannot create Closure for new expression in %s on line %d diff --git a/Zend/tests/gh20177.phpt b/Zend/tests/gh20177.phpt new file mode 100644 index 000000000000..fd69460067f9 --- /dev/null +++ b/Zend/tests/gh20177.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-20177: Access overridden private property in get_object_vars() +--FILE-- + +--EXPECT-- +array(1) { + ["prop"]=> + string(8) "A::$prop" +} diff --git a/Zend/tests/gh20183_001.phpt b/Zend/tests/gh20183_001.phpt new file mode 100644 index 000000000000..9468bcaea567 --- /dev/null +++ b/Zend/tests/gh20183_001.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-20183: Stale EG(opline_before_exception) pointer through eval +--CREDITS-- +Viet Hoang Luu (@vi3tL0u1s) +--FILE-- + +--EXPECTF-- +#0 %s(10): A->__destruct() + +Fatal error: Uncaught Error: Class "B" not found in %s:10 +Stack trace: +#0 {main} + thrown in %s on line 10 diff --git a/Zend/tests/gh20183_002.phpt b/Zend/tests/gh20183_002.phpt new file mode 100644 index 000000000000..ec4d62d0960d --- /dev/null +++ b/Zend/tests/gh20183_002.phpt @@ -0,0 +1,34 @@ +--TEST-- +GH-20183: Stale EG(opline_before_exception) pointer through eval +--CREDITS-- +Arnaud Le Blanc +--FILE-- +gen = gen(); + $this->gen->rewind(); + } +} + +B::$a = new A(); + +?> +--EXPECTF-- +#0 %s(20): gen() + +Fatal error: Uncaught Error: Class "B" not found in %s:20 +Stack trace: +#0 {main} + thrown in %s on line 20 diff --git a/Zend/tests/gh20564.phpt b/Zend/tests/gh20564.phpt new file mode 100644 index 000000000000..53311d952de7 --- /dev/null +++ b/Zend/tests/gh20564.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-20564: Don't call autoloaders with pending exception +--CREDITS-- +Viet Hoang Luu (@vi3tL0u1s) +--FILE-- +test(); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +array_map(): Argument #1 ($callback) must be a valid callback or null, class "B" not found diff --git a/Zend/tests/gh20628_001.phpt b/Zend/tests/gh20628_001.phpt new file mode 100644 index 000000000000..7b9534c9713b --- /dev/null +++ b/Zend/tests/gh20628_001.phpt @@ -0,0 +1,12 @@ +--TEST-- +Nullsafe operator does not support BP_VAR_W +--FILE-- +bar(); +} + +?> +--EXPECTF-- +Fatal error: Cannot take reference of a nullsafe chain in %s on line %d diff --git a/Zend/tests/gh20628_002.phpt b/Zend/tests/gh20628_002.phpt new file mode 100644 index 000000000000..509db5ff3d6c --- /dev/null +++ b/Zend/tests/gh20628_002.phpt @@ -0,0 +1,22 @@ +--TEST-- +Pipes support return-by-reference +--FILE-- + foo(...); +} + +$xRef = &bar(); +$xRef++; +var_dump($x); + +?> +--EXPECT-- +int(43) diff --git a/Zend/tests/gh20628_003.phpt b/Zend/tests/gh20628_003.phpt new file mode 100644 index 000000000000..ef23c8276b06 --- /dev/null +++ b/Zend/tests/gh20628_003.phpt @@ -0,0 +1,71 @@ +--TEST-- +Missing separation for ASSIGN_DIM with ref OP_DATA +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + NULL +} +array(1) { + [0]=> + &array(1) { + [0]=> + NULL + } +} +array(1) { + [0]=> + array(0) { + } +} +array(1) { + [0]=> + &array(1) { + [0]=> + array(0) { + } + } +} +array(1) { + [0]=> + NULL +} +array(1) { + [0]=> + NULL +} +NULL +array(1) { + [0]=> + &NULL +} diff --git a/Zend/tests/gh20628_004.inc b/Zend/tests/gh20628_004.inc new file mode 100644 index 000000000000..970b43ec1933 --- /dev/null +++ b/Zend/tests/gh20628_004.inc @@ -0,0 +1,3 @@ +bar(); diff --git a/Zend/tests/gh20628_004.phpt b/Zend/tests/gh20628_004.phpt new file mode 100644 index 000000000000..29851a717bc3 --- /dev/null +++ b/Zend/tests/gh20628_004.phpt @@ -0,0 +1,22 @@ +--TEST-- +Invalid opcode for method call with FETCH_THIS +--FILE-- +test(); + +?> +--EXPECTF-- +object(Foo)#%d (0) { +} +string(8) "Foo::bar" diff --git a/Zend/tests/gh20628_005.phpt b/Zend/tests/gh20628_005.phpt new file mode 100644 index 000000000000..43b49e0c18f2 --- /dev/null +++ b/Zend/tests/gh20628_005.phpt @@ -0,0 +1,20 @@ +--TEST-- +Failed assertion for assignment in expression context +--CREDITS-- +Matteo Beccati (mbeccati) +--FILE-- + 'baz']; +} + +var_dump(($v = foo())['bar'], $v); + +?> +--EXPECT-- +string(3) "baz" +array(1) { + ["bar"]=> + string(3) "baz" +} diff --git a/Zend/tests/gh20672.phpt b/Zend/tests/gh20672.phpt new file mode 100644 index 000000000000..416cd3e5a634 --- /dev/null +++ b/Zend/tests/gh20672.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-20672: Incorrect property_info sizing for locally shadowed trait properties +--CREDITS-- +Jonne Ransijn (yyny) +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/gh20714.phpt b/Zend/tests/gh20714.phpt new file mode 100644 index 000000000000..10ffde555f89 --- /dev/null +++ b/Zend/tests/gh20714.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-20714: Uncatchable exception thrown in generator +--CREDITS-- +Grégoire Paris (greg0ire) +--FILE-- + +--EXPECT-- +Caught diff --git a/Zend/tests/gh21504.inc b/Zend/tests/gh21504.inc new file mode 100644 index 000000000000..71dc5c2e61f6 --- /dev/null +++ b/Zend/tests/gh21504.inc @@ -0,0 +1,3 @@ + var_dump(...); diff --git a/Zend/tests/gh21504.phpt b/Zend/tests/gh21504.phpt new file mode 100644 index 000000000000..5fd9eaff91ab --- /dev/null +++ b/Zend/tests/gh21504.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-21504: Incorrect RC-handling for ZEND_EXT_STMT op1 +--FILE-- + +--EXPECT-- +string(4) "1234" diff --git a/Zend/tests/gh21603.phpt b/Zend/tests/gh21603.phpt new file mode 100644 index 000000000000..ab2fbc44e797 --- /dev/null +++ b/Zend/tests/gh21603.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-21603: Missing addref for __unset +--CREDITS-- +cnwangjihe +--FILE-- +prop); + +?> +--EXPECTF-- +object(C)#%d (0) { +} diff --git a/Zend/tests/gh21605.phpt b/Zend/tests/gh21605.phpt new file mode 100644 index 000000000000..973339ad3bb9 --- /dev/null +++ b/Zend/tests/gh21605.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-21605: Missing addref for Countable::count() +--CREDITS-- +cnwangjihe +--FILE-- + +--EXPECTF-- +object(C)#%d (0) { +} +int(42) diff --git a/Zend/tests/gh_21699.phpt b/Zend/tests/gh_21699.phpt new file mode 100644 index 000000000000..49b58365dabf --- /dev/null +++ b/Zend/tests/gh_21699.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21699: Assertion failure in shutdown_executor when error handler throws during self:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "self" i%s', '%s', %d) +#1 %s(%d): bar->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): bar->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh_21699_parent.phpt b/Zend/tests/gh_21699_parent.phpt new file mode 100644 index 000000000000..73cae41f3f5b --- /dev/null +++ b/Zend/tests/gh_21699_parent.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21699 (parent::): no shutdown_executor trampoline assertion when error handler throws during parent:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "parent"%s', '%s', %d) +#1 %s(%d): Child->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): Child->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh_21699_static.phpt b/Zend/tests/gh_21699_static.phpt new file mode 100644 index 000000000000..4d9604ebe77b --- /dev/null +++ b/Zend/tests/gh_21699_static.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21699 (static::): no shutdown_executor trampoline assertion when error handler throws during static:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "static"%s', '%s', %d) +#1 %s(%d): bar->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): bar->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/in-de-crement/incdec_strings.phpt b/Zend/tests/in-de-crement/incdec_strings.phpt index 9df89536140b..65b8adf7ee12 100644 --- a/Zend/tests/in-de-crement/incdec_strings.phpt +++ b/Zend/tests/in-de-crement/incdec_strings.phpt @@ -57,11 +57,11 @@ foreach ($values as $value) { Using increment: Initial value:string(0) "" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(1) "1" Initial value:string(1) " " -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(1) " " Initial value:string(1) "0" Result value:int(1) @@ -70,20 +70,28 @@ Result value:float(16.5) Initial value:string(4) "1e10" Result value:float(10000000001) Initial value:string(4) "199A" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(4) "199B" Initial value:string(4) "A199" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(4) "A200" Initial value:string(4) "199Z" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(4) "200A" Initial value:string(4) "Z199" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(4) "Z200" Initial value:string(11) "Hello world" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(11) "Hello worle" Initial value:string(4) "🐘" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(4) "🐘" Using decrement: Initial value:string(0) "" diff --git a/Zend/tests/in-de-crement/incdec_strings_exception.phpt b/Zend/tests/in-de-crement/incdec_strings_exception.phpt index 4214a6a45878..5acbb1041222 100644 --- a/Zend/tests/in-de-crement/incdec_strings_exception.phpt +++ b/Zend/tests/in-de-crement/incdec_strings_exception.phpt @@ -41,31 +41,35 @@ foreach ($values as $value) { } ?> --EXPECT-- -Deprecated: Increment on non-alphanumeric string is deprecated +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead string(0) "" Deprecated: Decrement on empty string is deprecated as non-numeric string(0) "" -Deprecated: Increment on non-alphanumeric string is deprecated +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead string(1) " " Deprecated: Decrement on non-numeric string has no effect and is deprecated string(1) " " -string(4) "199B" +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead +string(4) "199A" Deprecated: Decrement on non-numeric string has no effect and is deprecated -string(4) "199B" -string(4) "A200" +string(4) "199A" +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead +string(4) "A199" Deprecated: Decrement on non-numeric string has no effect and is deprecated -string(4) "A200" -string(4) "200A" +string(4) "A199" +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead +string(4) "199Z" Deprecated: Decrement on non-numeric string has no effect and is deprecated -string(4) "200A" -string(4) "Z200" +string(4) "199Z" +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead +string(4) "Z199" Deprecated: Decrement on non-numeric string has no effect and is deprecated -string(4) "Z200" -Deprecated: Increment on non-alphanumeric string is deprecated +string(4) "Z199" +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead string(11) "Hello world" Deprecated: Decrement on non-numeric string has no effect and is deprecated string(11) "Hello world" -Deprecated: Increment on non-alphanumeric string is deprecated +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead string(4) "🐘" Deprecated: Decrement on non-numeric string has no effect and is deprecated string(4) "🐘" diff --git a/Zend/tests/in-de-crement/incdec_types.phpt b/Zend/tests/in-de-crement/incdec_types.phpt index dfd850965146..755b63957ef3 100644 --- a/Zend/tests/in-de-crement/incdec_types.phpt +++ b/Zend/tests/in-de-crement/incdec_types.phpt @@ -63,11 +63,11 @@ Initial value:float(0) Result value:float(1) Initial value:string(0) "" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(1) "1" Initial value:string(1) " " -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Result value:string(1) " " Initial value:string(1) "0" Result value:int(1) diff --git a/Zend/tests/in-de-crement/increment_diagnostic_change_type.phpt b/Zend/tests/in-de-crement/increment_diagnostic_change_type.phpt index e124bfe907eb..11a0edac1917 100644 --- a/Zend/tests/in-de-crement/increment_diagnostic_change_type.phpt +++ b/Zend/tests/in-de-crement/increment_diagnostic_change_type.phpt @@ -31,8 +31,8 @@ var_dump($x); DONE --EXPECT-- string(1) "1" -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(4) "foo!" -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(1) "!" DONE diff --git a/Zend/tests/in-de-crement/increment_diagnostic_change_type_do_operator.phpt b/Zend/tests/in-de-crement/increment_diagnostic_change_type_do_operator.phpt index e20159a578cd..8e63ad6aeed4 100644 --- a/Zend/tests/in-de-crement/increment_diagnostic_change_type_do_operator.phpt +++ b/Zend/tests/in-de-crement/increment_diagnostic_change_type_do_operator.phpt @@ -23,8 +23,8 @@ var_dump($x); ?> DONE --EXPECT-- -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(4) "foo!" -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(1) "!" DONE diff --git a/Zend/tests/in-de-crement/oss-fuzz-62294_globals_unset_after_string_warning.phpt b/Zend/tests/in-de-crement/oss-fuzz-62294_globals_unset_after_string_warning.phpt index 7ca1100fbdde..f52dff52e631 100644 --- a/Zend/tests/in-de-crement/oss-fuzz-62294_globals_unset_after_string_warning.phpt +++ b/Zend/tests/in-de-crement/oss-fuzz-62294_globals_unset_after_string_warning.phpt @@ -31,8 +31,8 @@ PRE DEC Decrement on non-numeric string has no effect and is deprecated string(1) " " POST INC -Increment on non-alphanumeric string is deprecated +Increment on non-numeric string is deprecated, use str_increment() instead string(1) " " PRE INC -Increment on non-alphanumeric string is deprecated +Increment on non-numeric string is deprecated, use str_increment() instead string(1) " " diff --git a/Zend/tests/in-de-crement/string_increment_various.phpt b/Zend/tests/in-de-crement/string_increment_various.phpt index 8499d823042b..d1dd79a03f1b 100644 --- a/Zend/tests/in-de-crement/string_increment_various.phpt +++ b/Zend/tests/in-de-crement/string_increment_various.phpt @@ -53,55 +53,72 @@ var_dump(++$s); // string(3) "5e0" var_dump(++$s); // float(6) ?> --EXPECTF-- +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "Ba" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "bA" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "B0" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "b0" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(3) "AAa" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(3) "aaA" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(3) "10a" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(3) "10A" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(1) "1" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(3) "-cd" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "Z " -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) " A" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "é" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(15) "あいうえお" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "α" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "ω" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "Α" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(2) "Ω" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(8) "foo1.txu" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(4) "1f.6" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(9) "foo.1.txu" -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(5) "1.f.6" + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(3) "5e0" float(6) diff --git a/Zend/tests/in-de-crement/unset_globals_in_error_handler.phpt b/Zend/tests/in-de-crement/unset_globals_in_error_handler.phpt index d2f27ed32324..31ffea22467b 100644 --- a/Zend/tests/in-de-crement/unset_globals_in_error_handler.phpt +++ b/Zend/tests/in-de-crement/unset_globals_in_error_handler.phpt @@ -85,23 +85,23 @@ Decrement on type null has no effect, this will change in the next major version NULL Empty string POST INC -Increment on non-alphanumeric string is deprecated +Increment on non-numeric string is deprecated, use str_increment() instead string(0) "" POST DEC Decrement on empty string is deprecated as non-numeric string(0) "" PRE INC -Increment on non-alphanumeric string is deprecated +Increment on non-numeric string is deprecated, use str_increment() instead string(1) "1" PRE DEC Decrement on empty string is deprecated as non-numeric int(-1) Non fill ASCII (only ++) POST INC -Increment on non-alphanumeric string is deprecated +Increment on non-numeric string is deprecated, use str_increment() instead string(4) " ad " PRE INC -Increment on non-alphanumeric string is deprecated +Increment on non-numeric string is deprecated, use str_increment() instead string(4) " ad " Bool POST INC diff --git a/Zend/tests/in-de-crement/unset_object_property_in_error_handler.phpt b/Zend/tests/in-de-crement/unset_object_property_in_error_handler.phpt index 33d18b9a6279..4d2a4705588a 100644 --- a/Zend/tests/in-de-crement/unset_object_property_in_error_handler.phpt +++ b/Zend/tests/in-de-crement/unset_object_property_in_error_handler.phpt @@ -98,23 +98,23 @@ string(87) "Decrement on type null has no effect, this will change in the next m NULL Empty string POST INC -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(0) "" POST DEC string(54) "Decrement on empty string is deprecated as non-numeric" string(0) "" PRE INC -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(1) "1" PRE DEC string(54) "Decrement on empty string is deprecated as non-numeric" int(-1) Non fill ASCII (only ++) POST INC -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(4) " ad " PRE INC -string(50) "Increment on non-alphanumeric string is deprecated" +string(74) "Increment on non-numeric string is deprecated, use str_increment() instead" string(4) " ad " Bool POST INC diff --git a/Zend/tests/inheritance/argument_restriction_001.phpt b/Zend/tests/inheritance/argument_restriction_001.phpt index 2c54636a5817..6eb3ff8d2706 100644 --- a/Zend/tests/inheritance/argument_restriction_001.phpt +++ b/Zend/tests/inheritance/argument_restriction_001.phpt @@ -13,4 +13,4 @@ class Sub extends Base { } ?> --EXPECTF-- -Fatal error: Declaration of & Sub::test() must be compatible with & Base::test($foo, array $bar, $option = null, $extra = 'llllllllll...') in %s on line %d +Fatal error: Declaration of &Sub::test() must be compatible with &Base::test($foo, array $bar, $option = null, $extra = 'llllllllll...') in %s on line %d diff --git a/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt index 6e7e81cd2957..4bdf4b5d1b95 100644 --- a/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt +++ b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance.phpt @@ -1,5 +1,5 @@ --TEST-- -Deprecation promoted to exception should result in fatal error during inheritance +Deprecation promoted to exception during inheritance --SKIPIF-- --EXPECTF-- -Fatal error: During inheritance of DateTime: Uncaught Exception: Return type of DateTime@anonymous::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s:%d +Fatal error: Uncaught Exception: Return type of DateTime@anonymous::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s:%d Stack trace: #0 %s(%d): {closure:%s:%d}(8192, 'Return type of ...', '%s', 8) -#1 {main} in %s on line %d +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/inheritance/deprecation_to_exception_during_inheritance_can_be_caught.phpt b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance_can_be_caught.phpt new file mode 100644 index 000000000000..7a59cca70bd6 --- /dev/null +++ b/Zend/tests/inheritance/deprecation_to_exception_during_inheritance_can_be_caught.phpt @@ -0,0 +1,35 @@ +--TEST-- +Deprecation promoted to exception during inheritance +--SKIPIF-- + +--FILE-- +getMessage()); +} + +var_dump(new C()); + +?> +--EXPECTF-- +Exception: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice +object(C)#%d (3) { + ["date"]=> + string(%d) "%s" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" +} diff --git a/Zend/tests/inheritance/enum_only_interfaces_error_via_indirect_interface.phpt b/Zend/tests/inheritance/enum_only_interfaces_error_via_indirect_interface.phpt new file mode 100644 index 000000000000..66a921532055 --- /dev/null +++ b/Zend/tests/inheritance/enum_only_interfaces_error_via_indirect_interface.phpt @@ -0,0 +1,15 @@ +--TEST-- +Interface that is extended from Enum only interface shouldn't be implementable by non-enum class +--FILE-- + +--EXPECTF-- +Fatal error: Non-enum class C cannot implement interface UnitEnum in %s on line %d diff --git a/Zend/tests/inheritance/gh15907.phpt b/Zend/tests/inheritance/gh15907.phpt index 8d6dada36ad0..c92e40a4ba30 100644 --- a/Zend/tests/inheritance/gh15907.phpt +++ b/Zend/tests/inheritance/gh15907.phpt @@ -14,5 +14,8 @@ class C implements Serializable { ?> --EXPECTF-- -Fatal error: During inheritance of C, while implementing Serializable: Uncaught Exception: C implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s:%d -%a +Fatal error: Uncaught Exception: C implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in %s:%d +Stack trace: +#0 %s(%d): {closure:%s:%d}(8192, 'C implements th...', '%s', 7) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/int_overflow_32bit.phpt b/Zend/tests/int_overflow_32bit.phpt index 15dce6eea7dc..e337932bcd55 100644 --- a/Zend/tests/int_overflow_32bit.phpt +++ b/Zend/tests/int_overflow_32bit.phpt @@ -20,10 +20,19 @@ foreach ($doubles as $d) { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- +Warning: The float 2147483648 is not representable as an int, cast occurred in %s on line %d int(-2147483648) + +Warning: The float 2147483649 is not representable as an int, cast occurred in %s on line %d int(-2147483647) + +Warning: The float 2147483658 is not representable as an int, cast occurred in %s on line %d int(-2147483638) + +Warning: The float 2147483748 is not representable as an int, cast occurred in %s on line %d int(-2147483548) + +Warning: The float 2147484648 is not representable as an int, cast occurred in %s on line %d int(-2147482648) Done diff --git a/Zend/tests/int_overflow_64bit.phpt b/Zend/tests/int_overflow_64bit.phpt index 7c541250205c..cc14e14949ca 100644 --- a/Zend/tests/int_overflow_64bit.phpt +++ b/Zend/tests/int_overflow_64bit.phpt @@ -22,10 +22,16 @@ foreach ($doubles as $d) { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- int(9223372036854775807) + +Warning: The float %f is not representable as an int, cast occurred in %s on line %d int(-9223372036854775808) + +Warning: The float %f is not representable as an int, cast occurred in %s on line %d int(-9223372036854775808) + +Warning: The float %f is not representable as an int, cast occurred in %s on line %d int(0) int(-9223372036854775808) int(-9223372036854775808) diff --git a/Zend/tests/int_special_values.phpt b/Zend/tests/int_special_values.phpt deleted file mode 100644 index eedb9ab2c02a..000000000000 --- a/Zend/tests/int_special_values.phpt +++ /dev/null @@ -1,37 +0,0 @@ ---TEST-- -Conversion of special float values to int ---FILE-- - ---EXPECT-- -float(0) -int(0) - -float(INF) -int(0) - -float(-INF) -int(0) - -float(0) -int(0) - -float(-0) -int(0) - -float(NAN) -int(0) diff --git a/Zend/tests/int_underflow_32bit.phpt b/Zend/tests/int_underflow_32bit.phpt index 71464a758aee..88c0e79834b4 100644 --- a/Zend/tests/int_underflow_32bit.phpt +++ b/Zend/tests/int_underflow_32bit.phpt @@ -20,10 +20,18 @@ foreach ($doubles as $d) { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- int(-2147483648) + +Warning: The float -2147483649 is not representable as an int, cast occurred in %s on line %d int(2147483647) + +Warning: The float -2147483658 is not representable as an int, cast occurred in %s on line %d int(2147483638) + +Warning: The float -2147483748 is not representable as an int, cast occurred in %s on line %d int(2147483548) + +Warning: The float -2147484648 is not representable as an int, cast occurred in %s on line %d int(2147482648) Done diff --git a/Zend/tests/013.phpt b/Zend/tests/interface_exists_basic.phpt similarity index 100% rename from Zend/tests/013.phpt rename to Zend/tests/interface_exists_basic.phpt diff --git a/Zend/tests/isset/isset_array.phpt b/Zend/tests/isset/isset_array.phpt index dfa3fdef51dd..48e908a36d56 100644 --- a/Zend/tests/isset/isset_array.phpt +++ b/Zend/tests/isset/isset_array.phpt @@ -42,6 +42,8 @@ bool(true) Deprecated: Implicit conversion from float 0.6 to int loses precision in %s on line %d bool(true) bool(false) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d bool(false) Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d diff --git a/Zend/tests/016.phpt b/Zend/tests/isset_non_object.phpt similarity index 100% rename from Zend/tests/016.phpt rename to Zend/tests/isset_non_object.phpt diff --git a/Zend/tests/lazy_objects/gh18038-002.phpt b/Zend/tests/lazy_objects/gh18038-002.phpt index 4c12f21de811..d363731c62a0 100644 --- a/Zend/tests/lazy_objects/gh18038-002.phpt +++ b/Zend/tests/lazy_objects/gh18038-002.phpt @@ -34,5 +34,4 @@ var_dump($obj->prop); --EXPECT-- init string(19) "RealInstance::__set" -string(12) "Proxy::__set" int(2) diff --git a/Zend/tests/lazy_objects/gh18038-004.phpt b/Zend/tests/lazy_objects/gh18038-004.phpt index 8810efb6bec2..c1495c5a6d8d 100644 --- a/Zend/tests/lazy_objects/gh18038-004.phpt +++ b/Zend/tests/lazy_objects/gh18038-004.phpt @@ -36,7 +36,6 @@ var_dump($real->prop); --EXPECTF-- init string(19) "RealInstance::__get" -string(12) "Proxy::__get" Warning: Undefined property: RealInstance::$prop in %s on line %d NULL diff --git a/Zend/tests/lazy_objects/gh18038-007.phpt b/Zend/tests/lazy_objects/gh18038-007.phpt index 9925190a1980..4c7c0d0b4b0a 100644 --- a/Zend/tests/lazy_objects/gh18038-007.phpt +++ b/Zend/tests/lazy_objects/gh18038-007.phpt @@ -36,6 +36,5 @@ var_dump(isset($real->prop[''])); --EXPECT-- init string(21) "RealInstance::__isset" -string(14) "Proxy::__isset" bool(false) bool(false) diff --git a/Zend/tests/lazy_objects/gh18038-009.phpt b/Zend/tests/lazy_objects/gh18038-009.phpt index 3c165a71ccff..11067cdb970b 100644 --- a/Zend/tests/lazy_objects/gh18038-009.phpt +++ b/Zend/tests/lazy_objects/gh18038-009.phpt @@ -36,6 +36,5 @@ var_dump(isset($real->prop)); --EXPECT-- init string(21) "RealInstance::__isset" -string(14) "Proxy::__isset" bool(false) bool(false) diff --git a/Zend/tests/lazy_objects/gh20085.phpt b/Zend/tests/lazy_objects/gh20085.phpt new file mode 100644 index 000000000000..5624f71ea8b4 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20085.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-20085 (Assertion failure when combining lazy object get_properties exception with foreach loop) +--FILE-- +a = 1; + } +} +$obj = new C; +$reflector = new ReflectionClass(C::class); +foreach ($obj as &$value) { + $obj = $reflector->newLazyGhost(function ($obj) { + throw new Error; + }); +} +echo !obj; +?> +--EXPECTF-- +Fatal error: Uncaught Error in %s:%d +Stack trace: +#0 %s(%d): {closure:%s:%d}(Object(C)) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/lazy_objects/gh20174.phpt b/Zend/tests/lazy_objects/gh20174.phpt new file mode 100644 index 000000000000..2bce09b4dc71 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20174.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-20174: Assertion failure in ReflectionProperty::skipLazyInitialization after failed LazyProxy skipLazyInitialization +--CREDITS-- +vi3tL0u1s +--FILE-- +newLazyProxy(function ($obj) { + $obj->b = 4; + throw new Exception(); +}); + +try { + $reflector->initializeLazyObject($obj); +} catch (Exception $e) { + $reflector->getProperty('b')->skipLazyInitialization($obj); +} + +var_dump($obj); + +?> +--EXPECTF-- +lazy proxy object(C)#%d (1) { + ["b"]=> + NULL +} diff --git a/Zend/tests/lazy_objects/gh20504-001.phpt b/Zend/tests/lazy_objects/gh20504-001.phpt new file mode 100644 index 000000000000..c092e0f337fb --- /dev/null +++ b/Zend/tests/lazy_objects/gh20504-001.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - isset +--CREDITS-- +vi3tL0u1s +--FILE-- +$name['']); + } +} +$rc = new ReflectionClass(Proxy::class); +$obj = $rc->newLazyProxy(function () { + return new RealInstance; +}); +var_dump(isset($obj->name[''])); + +?> +--EXPECT-- +bool(false) diff --git a/Zend/tests/lazy_objects/gh20504-002.phpt b/Zend/tests/lazy_objects/gh20504-002.phpt new file mode 100644 index 000000000000..c9cb7e743af6 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20504-002.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - get +--FILE-- +$name; + } +} +$rc = new ReflectionClass(Proxy::class); +$obj = $rc->newLazyProxy(function () { + return new RealInstance; +}); +var_dump($obj->name); + +?> +--EXPECTF-- +Warning: Undefined property: RealInstance::$name in %s on line %d +NULL diff --git a/Zend/tests/lazy_objects/gh20504-003.phpt b/Zend/tests/lazy_objects/gh20504-003.phpt new file mode 100644 index 000000000000..df66e43a875a --- /dev/null +++ b/Zend/tests/lazy_objects/gh20504-003.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - set +--FILE-- +$name = $value; + } +} +$rc = new ReflectionClass(Proxy::class); +$obj = $rc->newLazyProxy(function () { + return new RealInstance; +}); +$obj->name = 0; + +var_dump($obj); + +?> +--EXPECTF-- +lazy proxy object(Proxy)#%d (1) { + ["instance"]=> + object(RealInstance)#%d (2) { + ["_"]=> + NULL + ["name"]=> + int(0) + } +} diff --git a/Zend/tests/lazy_objects/gh20504-004.phpt b/Zend/tests/lazy_objects/gh20504-004.phpt new file mode 100644 index 000000000000..a80964a9ae98 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20504-004.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - proxy defines __isset(), both have guards +--FILE-- +$name['']); + } +} +$rc = new ReflectionClass(Proxy::class); +$obj = $rc->newLazyProxy(function () { + return new RealInstance; +}); +var_dump(isset($obj->name[''])); + +?> +--EXPECT-- +Proxy::__isset +Proxy::__get +bool(false) diff --git a/Zend/tests/lazy_objects/gh20504-005.phpt b/Zend/tests/lazy_objects/gh20504-005.phpt new file mode 100644 index 000000000000..8a2519bde114 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20504-005.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-20504: Assertion failure in zend_get_property_guard() when lazy proxy adds magic method - unset +--FILE-- +$name); + } +} +$rc = new ReflectionClass(Proxy::class); +$obj = $rc->newLazyProxy(function () { + return new RealInstance; +}); +unset($obj->name); + +var_dump($obj); + +?> +--EXPECTF-- +lazy proxy object(Proxy)#%d (1) { + ["instance"]=> + object(RealInstance)#%d (1) { + ["_"]=> + NULL + } +} diff --git a/Zend/tests/lazy_objects/gh20657-001.phpt b/Zend/tests/lazy_objects/gh20657-001.phpt new file mode 100644 index 000000000000..ca3c70febca6 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20657-001.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-20657: GC during zend_lazy_object_realize() +--CREDITS-- +vi3tL0u1s +--FILE-- +newLazyGhost(function ($obj) {}); + + // Add to roots + $obj2 = $obj; + unset($obj2); + + // Initialize all props to mark object non-lazy. Also create a cycle. + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $obj); +} + +var_dump($obj); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["a"]=> + *RECURSION* +} diff --git a/Zend/tests/lazy_objects/gh20657-002.phpt b/Zend/tests/lazy_objects/gh20657-002.phpt new file mode 100644 index 000000000000..daf9b767ba97 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20657-002.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-20657 002: GC during zend_lazy_object_realize() - reset as lazy during realize() +--FILE-- +self = $this; + } + public function __destruct() { + global $obj, $reflector; + $reflector->resetAsLazyGhost($obj, function () {}); + } +} + +new D(); + +$reflector = new ReflectionClass(C::class); + +for ($i = 0; $i < 10000; $i++) { + $obj = $reflector->newLazyGhost(function ($obj) {}); + + // Add to roots + $obj2 = $obj; + unset($obj2); + + // Initialize all props to mark object non-lazy. Also create a cycle. + $reflector->getProperty('a')->setRawValueWithoutLazyInitialization($obj, $obj); +} + +var_dump($obj); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["a"]=> + *RECURSION* +} diff --git a/Zend/tests/lazy_objects/gh20854.phpt b/Zend/tests/lazy_objects/gh20854.phpt new file mode 100644 index 000000000000..26a69cfcbbf5 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20854.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-20854 (Assertion in ZEND_RETURN_BY_REF with lazy proxy and return-by-ref __get) +--FILE-- +x; + } +} + +$rc = new ReflectionClass(C::class); +$obj = $rc->newLazyProxy(function () { + return new C; +}); +$obj->x; +echo "Done\n"; +?> +--EXPECTF-- +Deprecated: Creation of dynamic property C::$x is deprecated in %s on line %d +Done diff --git a/Zend/tests/lazy_objects/gh20873.phpt b/Zend/tests/lazy_objects/gh20873.phpt new file mode 100644 index 000000000000..e5b8c31e9130 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20873.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-20873 (Assertion failure in _zendi_try_convert_scalar_to_number with lazy proxy) +--FILE-- +x =& $this->_; + static $a = $a; + $e =& $this->_ - $a; + } +} +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(fn() => new A); +$rc->initializeLazyObject($obj); +var_dump($obj->p); +?> +--EXPECTF-- +Deprecated: Creation of dynamic property A::$x is deprecated in %s on line %d + +Warning: Undefined variable $a in %s on line %d + +Notice: Indirect modification of overloaded property A::$x has no effect in %s on line %d + +Fatal error: Uncaught Error: Cannot assign by reference to overloaded object in %s:%d +Stack trace: +#0 %s(%d): A->__get('p') +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/lazy_objects/gh20875.phpt b/Zend/tests/lazy_objects/gh20875.phpt new file mode 100644 index 000000000000..ff036edabd59 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20875.phpt @@ -0,0 +1,41 @@ +--TEST-- +GH-20875 (Assertion failure in _get_zval_ptr_tmp with lazy proxy) +--FILE-- +f =& $this->b - $x > $y = new StdClass; + static $a = $a; + $t = 'x'; + foreach (get_defined_vars() as $key => $e) {} + if ($v ==!1) $x = $a ?: $t = "ok"; + } +} +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(function () { return new A; }); +$real = $rc->initializeLazyObject($obj); +var_dump($real->prop); +?> +--EXPECTF-- +Deprecated: Creation of dynamic property A::$b is deprecated in %s on line %d + +Deprecated: Creation of dynamic property A::$f is deprecated in %s on line %d + +Warning: Undefined variable $x in %s on line %d + +Notice: Object of class stdClass could not be converted to int in %s on line %d + +Warning: Undefined variable $a in %s on line %d + +Warning: Undefined variable $v in %s on line %d + +Notice: Indirect modification of overloaded property A::$f has no effect in %s on line %d + +Fatal error: Uncaught Error: Cannot assign by reference to overloaded object in %s:%d +Stack trace: +#0 %s(%d): A->__get('b') +#1 %s(%d): A->__get('prop') +#2 {main} + thrown in %s on line %d diff --git a/Zend/tests/lazy_objects/gh20875_proxy_get_no_init.phpt b/Zend/tests/lazy_objects/gh20875_proxy_get_no_init.phpt new file mode 100644 index 000000000000..d5d9754864b4 --- /dev/null +++ b/Zend/tests/lazy_objects/gh20875_proxy_get_no_init.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-20875 (Lazy proxy should not initialize when __get handles dynamic property access) +--FILE-- +newLazyProxy(function () { + echo "init\n"; + return new Foo(); +}); +$x = &$proxy->x; + +?> +--EXPECT-- +__get diff --git a/Zend/tests/lazy_objects/gh20905.phpt b/Zend/tests/lazy_objects/gh20905.phpt new file mode 100644 index 000000000000..318b44e6b82a --- /dev/null +++ b/Zend/tests/lazy_objects/gh20905.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-20905: Lazy proxy bailing __clone assertion +--CREDITS-- +Viet Hoang Luu (@vi3tL0u1s) +--FILE-- +newLazyProxy(fn() => new A); + +?> +--EXPECTF-- +Fatal error: Cannot redeclare function f() (previously declared in %s:%d) in %s on line %d diff --git a/Zend/tests/lazy_objects/gh21478-isset.phpt b/Zend/tests/lazy_objects/gh21478-isset.phpt new file mode 100644 index 000000000000..9138984af01b --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-isset.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21478: __isset on lazy proxy should not double-invoke when real instance guard is set +--FILE-- +{$name}); + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +isset($real->x); + +?> +--EXPECT-- +Init +__isset($x) on Foo diff --git a/Zend/tests/lazy_objects/gh21478-proxy-get-override.phpt b/Zend/tests/lazy_objects/gh21478-proxy-get-override.phpt new file mode 100644 index 000000000000..520c8f662353 --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-proxy-get-override.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21478: Proxy's own __get runs when accessed directly (not from real instance) +--FILE-- +newLazyProxy(function () { + return new Foo(); +}); +$rc->initializeLazyObject($proxy); + +$proxy->x; + +?> +--EXPECT-- +Bar x diff --git a/Zend/tests/lazy_objects/gh21478-proxy-get-ref-forward.phpt b/Zend/tests/lazy_objects/gh21478-proxy-get-ref-forward.phpt new file mode 100644 index 000000000000..fa737cf18f2e --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-proxy-get-ref-forward.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21478: No assertion failure when &__get forwards through initialized lazy proxy +--FILE-- +{$name}; + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +$a = &$real->x; +var_dump($a); +?> +--EXPECTF-- +Init +Foo::__get($x) on Foo + +Warning: Undefined property: Foo::$x in %s on line %d +NULL diff --git a/Zend/tests/lazy_objects/gh21478-set.phpt b/Zend/tests/lazy_objects/gh21478-set.phpt new file mode 100644 index 000000000000..0b2f872de11a --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-set.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21478: __set on lazy proxy should not double-invoke when real instance guard is set +--FILE-- +{$name} = $value; + } +} + +#[AllowDynamicProperties] +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +$real->x = 1; + +?> +--EXPECT-- +Init +__set($x) on Foo diff --git a/Zend/tests/lazy_objects/gh21478-unset.phpt b/Zend/tests/lazy_objects/gh21478-unset.phpt new file mode 100644 index 000000000000..5febbd235d82 --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478-unset.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21478: __unset on lazy proxy should not double-invoke when real instance guard is set +--FILE-- +{$name}); + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +unset($real->x); + +?> +--EXPECT-- +Init +__unset($x) on Foo diff --git a/Zend/tests/lazy_objects/gh21478.phpt b/Zend/tests/lazy_objects/gh21478.phpt new file mode 100644 index 000000000000..aaa226a9a09a --- /dev/null +++ b/Zend/tests/lazy_objects/gh21478.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21478 (Property access on lazy proxy may invoke magic method despite real instance guards) +--FILE-- +{$name}; + } +} + +class Bar extends Foo {} + +$rc = new ReflectionClass(Bar::class); +$proxy = $rc->newLazyProxy(function () { + echo "Init\n"; + return new Foo(); +}); + +$real = $rc->initializeLazyObject($proxy); +$real->x; + +?> +--EXPECTF-- +Init +__get($x) on Foo + +Warning: Undefined property: Foo::$x in %s on line %d diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt index 4edf9481ebc2..695da60229c7 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes.phpt @@ -46,7 +46,6 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the proxy are not reverted test('Proxy', $obj); --EXPECTF-- @@ -63,12 +62,10 @@ Is lazy: 1 # Proxy: string(11) "initializer" initializer exception -lazy proxy object(C)#%d (3) { - ["a"]=> - int(3) +lazy proxy object(C)#%d (1) { ["b"]=> - int(4) + uninitialized(int) ["c"]=> - int(5) + int(0) } Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt index ce94fc8b2ab7..19d3eac7a9f0 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props.phpt @@ -49,7 +49,6 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the proxy are not reverted test('Proxy', $obj); --EXPECTF-- @@ -66,14 +65,10 @@ Is lazy: 1 # Proxy: string(11) "initializer" initializer exception -lazy proxy object(C)#%d (4) { - ["a"]=> - int(3) +lazy proxy object(C)#%d (1) { ["b"]=> - int(4) + uninitialized(int) ["c"]=> - int(5) - ["d"]=> - int(6) + int(0) } Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt index 1bc3eb2cea8e..c11a0eda7aaa 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_dyn_props_and_ht.phpt @@ -52,7 +52,6 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the proxy are not reverted test('Proxy', $obj); --EXPECTF-- @@ -73,14 +72,10 @@ array(0) { } string(11) "initializer" initializer exception -lazy proxy object(C)#%d (4) { - ["a"]=> - int(3) +lazy proxy object(C)#%d (1) { ["b"]=> - int(4) + uninitialized(int) ["c"]=> - int(5) - ["d"]=> - int(6) + int(0) } Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt index c4f0bd98773f..7419a4a31da9 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht.phpt @@ -49,7 +49,6 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the proxy are not reverted test('Proxy', $obj); --EXPECTF-- @@ -74,12 +73,10 @@ array(1) { } string(11) "initializer" initializer exception -lazy proxy object(C)#%d (3) { - ["a"]=> - int(3) +lazy proxy object(C)#%d (1) { ["b"]=> - int(4) + uninitialized(int) ["c"]=> - int(5) + int(0) } Is lazy: 1 diff --git a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt index 094f5c9b8094..cea95c3c8a7b 100644 --- a/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt +++ b/Zend/tests/lazy_objects/init_exception_reverts_initializer_changes_props_ht_ref.phpt @@ -55,7 +55,6 @@ $obj = $reflector->newLazyProxy(function ($obj) { throw new Exception('initializer exception'); }); -// Initializer effects on the proxy are not reverted test('Proxy', $obj); --EXPECTF-- @@ -83,13 +82,11 @@ array(1) { } string(11) "initializer" initializer exception -lazy proxy object(C)#%d (3) { - ["a"]=> - int(3) +lazy proxy object(C)#%d (1) { ["b"]=> - int(4) + uninitialized(int) ["c"]=> - int(5) + int(0) } Is lazy: 1 diff --git a/Zend/tests/lazy_objects/skipLazyInitialization.phpt b/Zend/tests/lazy_objects/skipLazyInitialization.phpt index d4d564d9c653..4fc47b13db67 100644 --- a/Zend/tests/lazy_objects/skipLazyInitialization.phpt +++ b/Zend/tests/lazy_objects/skipLazyInitialization.phpt @@ -227,7 +227,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $hooked = NULL ] +## Property [ public $hooked = NULL { get; set; } ] skipInitializerForProperty(): getValue(): NULL @@ -235,7 +235,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $virtual ] +## Property [ public virtual $virtual { get; set; } ] skipInitializerForProperty(): ReflectionException: Can not use skipLazyInitialization on virtual property A::$virtual @@ -324,7 +324,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $hooked = NULL ] +## Property [ public $hooked = NULL { get; set; } ] skipInitializerForProperty(): getValue(): NULL @@ -332,7 +332,7 @@ getValue(): NULL setRawValueWithoutLazyInitialization(): getValue(): string(5) "value" -## Property [ public $virtual ] +## Property [ public virtual $virtual { get; set; } ] skipInitializerForProperty(): ReflectionException: Can not use skipLazyInitialization on virtual property A::$virtual diff --git a/Zend/tests/list/bug39304.phpt b/Zend/tests/list/bug39304.phpt index a5422d2f4f31..353baa5df01d 100644 --- a/Zend/tests/list/bug39304.phpt +++ b/Zend/tests/list/bug39304.phpt @@ -8,5 +8,9 @@ Bug #39304 (Segmentation fault with list unpacking of string offset) ?> --EXPECTF-- Warning: Uninitialized string offset 0 in %s on line %d + +Warning: Cannot use string as array in %s on line %d + +Warning: Cannot use string as array in %s on line %d NULL NULL diff --git a/Zend/tests/list/destruct_bool.phpt b/Zend/tests/list/destruct_bool.phpt new file mode 100644 index 000000000000..7553811220c9 --- /dev/null +++ b/Zend/tests/list/destruct_bool.phpt @@ -0,0 +1,18 @@ +--TEST-- +Destructuring with list() a value of type bool +--FILE-- + +--EXPECTF-- +Warning: Cannot use bool as array in %s on line %d + +Warning: Cannot use bool as array in %s on line %d +NULL +NULL diff --git a/Zend/tests/list/destruct_float.phpt b/Zend/tests/list/destruct_float.phpt new file mode 100644 index 000000000000..6423a5b5668a --- /dev/null +++ b/Zend/tests/list/destruct_float.phpt @@ -0,0 +1,18 @@ +--TEST-- +Destructuring with list() a value of type float +--FILE-- + +--EXPECTF-- +Warning: Cannot use float as array in %s on line %d + +Warning: Cannot use float as array in %s on line %d +NULL +NULL diff --git a/Zend/tests/list/destruct_int.phpt b/Zend/tests/list/destruct_int.phpt new file mode 100644 index 000000000000..e232ecb73982 --- /dev/null +++ b/Zend/tests/list/destruct_int.phpt @@ -0,0 +1,18 @@ +--TEST-- +Destructuring with list() a value of type int +--FILE-- + +--EXPECTF-- +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d +NULL +NULL diff --git a/Zend/tests/list/destruct_null.phpt b/Zend/tests/list/destruct_null.phpt new file mode 100644 index 000000000000..e89de45a28e8 --- /dev/null +++ b/Zend/tests/list/destruct_null.phpt @@ -0,0 +1,12 @@ +--TEST-- +Destructuring with list() a value of type null +--FILE-- + +--EXPECT-- +NULL diff --git a/Zend/tests/list/destruct_object_not_ArrayAccess.phpt b/Zend/tests/list/destruct_object_not_ArrayAccess.phpt new file mode 100644 index 000000000000..097c2cd2def3 --- /dev/null +++ b/Zend/tests/list/destruct_object_not_ArrayAccess.phpt @@ -0,0 +1,17 @@ +--TEST-- +Destructuring with list() a value of type object (that does not implement ArrayAccess) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Cannot use object of type stdClass as array in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/tests/list/destruct_resource.phpt b/Zend/tests/list/destruct_resource.phpt new file mode 100644 index 000000000000..8e5576767fe1 --- /dev/null +++ b/Zend/tests/list/destruct_resource.phpt @@ -0,0 +1,18 @@ +--TEST-- +Destructuring with list() a value of type resource +--FILE-- + +--EXPECTF-- +Warning: Cannot use resource as array in %s on line %d + +Warning: Cannot use resource as array in %s on line %d +NULL +NULL diff --git a/Zend/tests/list/destruct_string.phpt b/Zend/tests/list/destruct_string.phpt new file mode 100644 index 000000000000..b2ea88c65a6c --- /dev/null +++ b/Zend/tests/list/destruct_string.phpt @@ -0,0 +1,21 @@ +--TEST-- +Destructuring with list() a value of type string +--FILE-- + +--EXPECTF-- +Warning: Cannot use string as array in %s on line %d + +Warning: Cannot use string as array in %s on line %d + +Warning: Cannot use string as array in %s on line %d +NULL +NULL +NULL diff --git a/Zend/tests/list/list_003.phpt b/Zend/tests/list/list_003.phpt deleted file mode 100644 index 4a509f6a828b..000000000000 --- a/Zend/tests/list/list_003.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -list() with non-array ---FILE-- - ---EXPECT-- -NULL -NULL -NULL -NULL -NULL diff --git a/Zend/tests/list/list_005.phpt b/Zend/tests/list/list_005.phpt deleted file mode 100644 index 7dc3bf6fa36a..000000000000 --- a/Zend/tests/list/list_005.phpt +++ /dev/null @@ -1,50 +0,0 @@ ---TEST-- -Testing list() with several variables ---FILE-- - ---EXPECTF-- -NULL -NULL -NULL ----- -NULL -NULL -NULL ----- - -Fatal error: Uncaught Error: Cannot use object of type stdClass as array in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d diff --git a/Zend/tests/list/list_keyed_conversions.phpt b/Zend/tests/list/list_keyed_conversions.phpt index 9798be199894..637e517d51b9 100644 --- a/Zend/tests/list/list_keyed_conversions.phpt +++ b/Zend/tests/list/list_keyed_conversions.phpt @@ -21,6 +21,8 @@ list(STDIN => $resource) = []; ?> --EXPECTF-- +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + Deprecated: Implicit conversion from float 1.5 to int loses precision in %s on line %d string(0) "" int(1) diff --git a/Zend/tests/magic_methods/bug73288.phpt b/Zend/tests/magic_methods/bug73288.phpt index 52e8eedeaf01..5e1334cacd07 100644 --- a/Zend/tests/magic_methods/bug73288.phpt +++ b/Zend/tests/magic_methods/bug73288.phpt @@ -23,6 +23,7 @@ function test_clone() { $b = clone $c->x; } +// No catch, because we want to test Exception::__toString(). test_clone(); ?> --EXPECTF-- diff --git a/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt b/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt index 6bdcafb1bfb5..a4076ee00ce2 100644 --- a/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt +++ b/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt @@ -66,5 +66,6 @@ class WidenedArgumentType extends NarrowedReturnType { echo 'No problems!'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning null from ValidMagicMethods::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d No problems! diff --git a/Zend/tests/magic_methods/trampoline_closure_named_arguments.phpt b/Zend/tests/magic_methods/trampoline_closure_named_arguments.phpt index e4ccaf16e63a..3be14f6145ac 100644 --- a/Zend/tests/magic_methods/trampoline_closure_named_arguments.phpt +++ b/Zend/tests/magic_methods/trampoline_closure_named_arguments.phpt @@ -42,7 +42,7 @@ var_dump($type); var_dump($type->getName()); ?> ---EXPECT-- +--EXPECTF-- -- Non-static cases -- string(4) "test" array(3) { @@ -69,7 +69,7 @@ array(4) { ["a"]=> int(123) ["b"]=> - object(Test)#1 (0) { + object(Test)#%d (0) { } } string(4) "test" @@ -77,7 +77,7 @@ array(2) { ["a"]=> int(123) ["b"]=> - object(Test)#1 (0) { + object(Test)#%d (0) { } } string(4) "test" @@ -114,7 +114,7 @@ array(4) { ["a"]=> int(123) ["b"]=> - object(Test)#1 (0) { + object(Test)#%d (0) { } } string(10) "testStatic" @@ -122,7 +122,7 @@ array(2) { ["a"]=> int(123) ["b"]=> - object(Test)#1 (0) { + object(Test)#%d (0) { } } string(10) "testStatic" @@ -136,12 +136,12 @@ array(1) { -- Reflection tests -- array(1) { [0]=> - object(ReflectionParameter)#4 (1) { + object(ReflectionParameter)#%d (1) { ["name"]=> string(9) "arguments" } } bool(true) -object(ReflectionNamedType)#5 (0) { +object(ReflectionNamedType)#%d (0) { } string(5) "mixed" diff --git a/Zend/tests/named_params/internal_variadics.phpt b/Zend/tests/named_params/internal_variadics.phpt index 3599f644ac97..8312bde406d2 100644 --- a/Zend/tests/named_params/internal_variadics.phpt +++ b/Zend/tests/named_params/internal_variadics.phpt @@ -15,7 +15,14 @@ try { echo $e->getMessage(), "\n"; } +try { + $array = [1, 2]; + array_push($array, ...['values' => 3]); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECT-- -array_merge() does not accept unknown named parameters -array_diff_key() does not accept unknown named parameters +Internal function array_merge() does not accept named variadic arguments +Internal function array_diff_key() does not accept named variadic arguments +Internal function array_push() does not accept named variadic arguments diff --git a/Zend/tests/nullsafe_operator/013.phpt b/Zend/tests/nullsafe_operator/013.phpt index 883f6ac24aa8..ea3539954891 100644 Binary files a/Zend/tests/nullsafe_operator/013.phpt and b/Zend/tests/nullsafe_operator/013.phpt differ diff --git a/Zend/tests/numeric_strings/oss_fuzz_427814456.phpt b/Zend/tests/numeric_strings/oss_fuzz_427814456.phpt new file mode 100644 index 000000000000..f91563385e9f --- /dev/null +++ b/Zend/tests/numeric_strings/oss_fuzz_427814456.phpt @@ -0,0 +1,11 @@ +--TEST-- +OSS-Fuzz #427814456 +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/objects/objects_005.phpt b/Zend/tests/objects/objects_005.phpt index 9b9a41465f95..7749a39d986f 100644 --- a/Zend/tests/objects/objects_005.phpt +++ b/Zend/tests/objects/objects_005.phpt @@ -19,4 +19,4 @@ class test3 extends test { ?> --EXPECTF-- -Fatal error: Declaration of test3::foo() must be compatible with & test::foo() in %s on line %d +Fatal error: Declaration of test3::foo() must be compatible with &test::foo() in %s on line %d diff --git a/Zend/tests/oct_overflow.phpt b/Zend/tests/oct_overflow.phpt index 512a6abf6643..b8ce3f40fde1 100644 --- a/Zend/tests/oct_overflow.phpt +++ b/Zend/tests/oct_overflow.phpt @@ -5,7 +5,7 @@ precision=14 --FILE-- --EXPECT-- -Err: Implicit conversion from float 1.0E+20 to int loses precision +Err: The float 1.0E+20 is not representable as an int, cast occurred array(0) { } diff --git a/Zend/tests/offsets/false_container_offset_behaviour.phpt b/Zend/tests/offsets/false_container_offset_behaviour.phpt index 8a6cd93b7260..0647400baee0 100644 --- a/Zend/tests/offsets/false_container_offset_behaviour.phpt +++ b/Zend/tests/offsets/false_container_offset_behaviour.phpt @@ -135,6 +135,176 @@ OUTPUT; $EXPECTED_OUTPUT_FLOAT_OFFSETS_REGEX = '/^' . expectf_to_regex(EXPECTF_OUTPUT_FLOAT_OFFSETS) . '$/s'; +const EXPECTF_OUTPUT_FLOAT_OOB_OFFSETS = << 1]; + +echo $a[null]; + +?> +--EXPECTF-- +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +1 diff --git a/Zend/tests/offsets/null_container_offset_behaviour.phpt b/Zend/tests/offsets/null_container_offset_behaviour.phpt index 0fe02556d3e0..2ac51937a0fe 100644 --- a/Zend/tests/offsets/null_container_offset_behaviour.phpt +++ b/Zend/tests/offsets/null_container_offset_behaviour.phpt @@ -131,6 +131,172 @@ OUTPUT; $EXPECTED_OUTPUT_FLOAT_OFFSETS_REGEX = '/^' . expectf_to_regex(EXPECTF_OUTPUT_FLOAT_OFFSETS) . '$/s'; +const EXPECTF_OUTPUT_FLOAT_OOB_OFFSETS = << 'bar', null => new stdClass]; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +Exception: Using null as an array offset is deprecated, use an empty string instead diff --git a/Zend/tests/offsets/null_offset_no_uaf.phpt b/Zend/tests/offsets/null_offset_no_uaf.phpt new file mode 100644 index 000000000000..38a1b9868345 --- /dev/null +++ b/Zend/tests/offsets/null_offset_no_uaf.phpt @@ -0,0 +1,17 @@ +--TEST-- +No UAF on null offset +--FILE-- + +--EXPECTF-- +Using null as an array offset is deprecated, use an empty string instead +Success diff --git a/Zend/tests/offsets/null_offset_unset_via_error_handler.phpt b/Zend/tests/offsets/null_offset_unset_via_error_handler.phpt new file mode 100644 index 000000000000..cfaa2b3b20d9 --- /dev/null +++ b/Zend/tests/offsets/null_offset_unset_via_error_handler.phpt @@ -0,0 +1,19 @@ +--TEST-- +No UAF on null offset deprecation with unset value +--FILE-- + $a]; + +echo "\nSuccess\n"; +?> +--EXPECTF-- +string(72) "Using null as an array offset is deprecated, use an empty string instead" + +Success diff --git a/Zend/tests/offsets/string_container_offset_behaviour.phpt b/Zend/tests/offsets/string_container_offset_behaviour.phpt index dc4c95e5d9ec..9c752ebddd81 100644 --- a/Zend/tests/offsets/string_container_offset_behaviour.phpt +++ b/Zend/tests/offsets/string_container_offset_behaviour.phpt @@ -280,7 +280,7 @@ OUTPUT; $EXPECTED_OUTPUT_STRING_CAST_OFFSETS_OUT_OF_RANGE_REGEX = '/^' . expectf_to_regex(EXPECTED_OUTPUT_STRING_CAST_OFFSETS_OUT_OF_RANGE) . '$/s'; -const EXPECTF_OUTPUT_FLOAT_OFFSETS_OUT_OF_RANGE = << '\d+', '%x' => '[0-9a-fA-F]+', '%f' => '[+-]?(?:\d+|(?=\.\d))(?:\.\d+)?(?:[Ee][+-]?\d+)?', - '%F' => '([+-]?(?:\d+|(?=\.\d))(?:\.\d+)?(?:[Ee][+-]?\d+)?)|(NAN)|(INF)', + '%F' => '([+-]?(?:\d+|(?=\.\d))(?:\.\d+)?(?:[Ee][+-]?\d+)?)|(NAN)|(INF)|([+-]?\d+)', '%c' => '.', '%0' => '\x00', ]); diff --git a/Zend/tests/operator_unsupported_types.phpt b/Zend/tests/operator_unsupported_types.phpt index ef169bb39fc2..904ac402b372 100644 --- a/Zend/tests/operator_unsupported_types.phpt +++ b/Zend/tests/operator_unsupported_types.phpt @@ -287,7 +287,7 @@ Unsupported operand types: stdClass * stdClass Unsupported operand types: stdClass * resource Unsupported operand types: stdClass * string Unsupported operand types: resource * array -Unsupported operand types: stdClass * resource +Unsupported operand types: resource * stdClass Unsupported operand types: resource * resource Unsupported operand types: resource * string Unsupported operand types: string * array @@ -753,7 +753,7 @@ Unsupported operand types: stdClass & stdClass Unsupported operand types: stdClass & resource Unsupported operand types: stdClass & string Unsupported operand types: resource & array -Unsupported operand types: stdClass & resource +Unsupported operand types: resource & stdClass Unsupported operand types: resource & resource Unsupported operand types: resource & string Unsupported operand types: string & array @@ -828,7 +828,7 @@ Unsupported operand types: stdClass | stdClass Unsupported operand types: stdClass | resource Unsupported operand types: stdClass | string Unsupported operand types: resource | array -Unsupported operand types: stdClass | resource +Unsupported operand types: resource | stdClass Unsupported operand types: resource | resource Unsupported operand types: resource | string Unsupported operand types: string | array @@ -903,7 +903,7 @@ Unsupported operand types: stdClass ^ stdClass Unsupported operand types: stdClass ^ resource Unsupported operand types: stdClass ^ string Unsupported operand types: resource ^ array -Unsupported operand types: stdClass ^ resource +Unsupported operand types: resource ^ stdClass Unsupported operand types: resource ^ resource Unsupported operand types: resource ^ string Unsupported operand types: string ^ array @@ -2104,6 +2104,7 @@ Cannot increment stdClass Cannot decrement stdClass Cannot increment resource Cannot decrement resource +Warning: Increment on non-numeric string is deprecated, use str_increment() instead No error for fop++ Warning: Decrement on non-numeric string has no effect and is deprecated No error for foo-- diff --git a/Zend/tests/optimizer/nan_warning_switch.phpt b/Zend/tests/optimizer/nan_warning_switch.phpt new file mode 100644 index 000000000000..1b7b404201f4 --- /dev/null +++ b/Zend/tests/optimizer/nan_warning_switch.phpt @@ -0,0 +1,17 @@ +--TEST-- +Checking NAN in a switch statement with true/false +--FILE-- + +--EXPECT-- +true diff --git a/Zend/tests/oss-fuzz-465488618.phpt b/Zend/tests/oss-fuzz-465488618.phpt new file mode 100644 index 000000000000..517c481b33e0 --- /dev/null +++ b/Zend/tests/oss-fuzz-465488618.phpt @@ -0,0 +1,16 @@ +--TEST-- +OSS-Fuzz #465488618: Dump function signature with dynamic class const lookup default argument +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of B::test(string $x = ) must be compatible with A::test(int $x) in %s on line %d diff --git a/Zend/tests/oss-fuzz-471486164-001.phpt b/Zend/tests/oss-fuzz-471486164-001.phpt new file mode 100644 index 000000000000..a48a56398c1e --- /dev/null +++ b/Zend/tests/oss-fuzz-471486164-001.phpt @@ -0,0 +1,22 @@ +--TEST-- +OSS-Fuzz #471486164: get_property_ptr_ptr() on uninitialized hooked property +--FILE-- + $this->a; + set { $this->a = &$value; } + } + public $x = 1; +} + +$proxy = (new ReflectionClass(C::class))->newLazyProxy(function ($proxy) { + $proxy->a = 1; + return new C; +}); +var_dump($proxy->x); + +?> +--EXPECT-- +int(1) diff --git a/Zend/tests/oss-fuzz-471486164-002.phpt b/Zend/tests/oss-fuzz-471486164-002.phpt new file mode 100644 index 000000000000..688dd7612201 --- /dev/null +++ b/Zend/tests/oss-fuzz-471486164-002.phpt @@ -0,0 +1,26 @@ +--TEST-- +OSS-Fuzz #471486164: get_property_ptr_ptr() on uninitialized hooked property +--FILE-- + $this->a; + set { + global $ref; + $this->a = &$ref; + } + } +} + +$ref = 1; +$proxy = new C; +$proxy->a = 1; +var_dump($proxy->a); +$ref++; +var_dump($proxy->a); + +?> +--EXPECT-- +int(1) +int(2) diff --git a/Zend/tests/oss-fuzz-474613951.phpt b/Zend/tests/oss-fuzz-474613951.phpt new file mode 100644 index 000000000000..552be2e0116a --- /dev/null +++ b/Zend/tests/oss-fuzz-474613951.phpt @@ -0,0 +1,17 @@ +--TEST-- +OSS-Fuzz #474613951: Leaked parent property default value +--FILE-- + $this->prop; } +} + +class B extends A { + public $prop { get => 42; } +} + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/oss-fuzz-478009707.phpt b/Zend/tests/oss-fuzz-478009707.phpt new file mode 100644 index 000000000000..bd002fc3badf --- /dev/null +++ b/Zend/tests/oss-fuzz-478009707.phpt @@ -0,0 +1,27 @@ +--TEST-- +OSS-Fuzz #478009707: Assign-op/inc/dec on untyped hooked property backing value +--FILE-- +prop = $value; + $this->prop += 1; + $this->prop++; + ++$this->prop; + } + } +} + +$c = new C(1); +$c->prop = 1; +var_dump($c->prop); + +$c->prop = PHP_INT_MAX; +var_dump($c->prop); + +?> +--EXPECTF-- +int(4) +float(%s) diff --git a/Zend/tests/oss-fuzz-480111866.phpt b/Zend/tests/oss-fuzz-480111866.phpt new file mode 100644 index 000000000000..ba956f0f9ac6 --- /dev/null +++ b/Zend/tests/oss-fuzz-480111866.phpt @@ -0,0 +1,10 @@ +--TEST-- +OSS-Fuzz #480111866: Assignment to assignment through list operator +--FILE-- + +--EXPECTF-- +Fatal error: Assignments can only happen to writable values in %s on line %d diff --git a/Zend/tests/oss-fuzz-481017027.phpt b/Zend/tests/oss-fuzz-481017027.phpt new file mode 100644 index 000000000000..472133cfe845 --- /dev/null +++ b/Zend/tests/oss-fuzz-481017027.phpt @@ -0,0 +1,23 @@ +--TEST-- +OSS-Fuzz #481017027: Missing zend_fe_fetch_object_helper deref +--FILE-- +y = &$y; +test($obj, ''); + +?> +--EXPECT-- +int(42) diff --git a/Zend/tests/oss_fuzz_429429090.phpt b/Zend/tests/oss_fuzz_429429090.phpt new file mode 100644 index 000000000000..d5279c2806ac --- /dev/null +++ b/Zend/tests/oss_fuzz_429429090.phpt @@ -0,0 +1,20 @@ +--TEST-- +OSS-Fuzz #429429090: FETCH_OBJ_UNSET IS_UNDEF result +--FILE-- +x[0]->prop); +unset($c->x[0]->prop); +isset(C::$y[0]->prop); +unset(C::$y[0]->prop); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/oss_fuzz_434346548.phpt b/Zend/tests/oss_fuzz_434346548.phpt new file mode 100644 index 000000000000..139e36758bc4 --- /dev/null +++ b/Zend/tests/oss_fuzz_434346548.phpt @@ -0,0 +1,22 @@ +--TEST-- +OSS-Fuzz #434346548: Failed assertion with throwing __toString in binary const expr +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +Foo::__toString(): Return value must be of type string, none returned diff --git a/Zend/tests/oss_fuzz_438780145.phpt b/Zend/tests/oss_fuzz_438780145.phpt new file mode 100644 index 000000000000..4c6936a69a01 --- /dev/null +++ b/Zend/tests/oss_fuzz_438780145.phpt @@ -0,0 +1,27 @@ +--TEST-- +OSS-Fuzz #438780145: Nested finally with repeated return type check may uaf +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught TypeError: test(): Return value must be of type int, string returned in %s:%d +Stack trace: +#0 %s(%d): test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/oss_fuzz_447521098.phpt b/Zend/tests/oss_fuzz_447521098.phpt new file mode 100644 index 000000000000..09967ce0ae3a --- /dev/null +++ b/Zend/tests/oss_fuzz_447521098.phpt @@ -0,0 +1,13 @@ +--TEST-- +OSS-Fuzz #447521098: Fatal error during sccp shift eval +--FILE-- +> $y; +} +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/oss_fuzz_454273637.phpt b/Zend/tests/oss_fuzz_454273637.phpt new file mode 100644 index 000000000000..fbcdb57ed2a1 --- /dev/null +++ b/Zend/tests/oss_fuzz_454273637.phpt @@ -0,0 +1,8 @@ +--TEST-- +OSS-Fuzz #454273637 (UAF with printf optimization and const output) +--FILE-- + +--EXPECT-- +% diff --git a/Zend/tests/oss_fuzz_456317305.phpt b/Zend/tests/oss_fuzz_456317305.phpt new file mode 100644 index 000000000000..37e7c59e4651 --- /dev/null +++ b/Zend/tests/oss_fuzz_456317305.phpt @@ -0,0 +1,25 @@ +--TEST-- +OSS-Fuzz #456317305: EG(current_execute_data) NULL pointer violation +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 [internal function]: C->__destruct() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/pipe_operator/gh18965.phpt b/Zend/tests/pipe_operator/gh18965.phpt new file mode 100644 index 000000000000..8f9eaaebb08a --- /dev/null +++ b/Zend/tests/pipe_operator/gh18965.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-18965: ASSERT_CHECK avoids pipe lhs free +--INI-- +zend.assertions=0 +--FILE-- + assert(...); +echo "No leak\n"; +?> +--EXPECT-- +No leak diff --git a/Zend/tests/pipe_operator/mixed_callable_call.phpt b/Zend/tests/pipe_operator/mixed_callable_call.phpt index 55bae626f189..d577f3aaefe6 100644 --- a/Zend/tests/pipe_operator/mixed_callable_call.phpt +++ b/Zend/tests/pipe_operator/mixed_callable_call.phpt @@ -71,7 +71,7 @@ $res1 = 1 |> [StaticTest::class, 'times17'] |> new Times23() |> $times29 - |> fn($x) => times2($x) + |> (fn($x) => times2($x)) ; var_dump($res1); diff --git a/Zend/tests/pipe_operator/oss_fuzz_427814452.phpt b/Zend/tests/pipe_operator/oss_fuzz_427814452.phpt new file mode 100644 index 000000000000..2ecfbab6348f --- /dev/null +++ b/Zend/tests/pipe_operator/oss_fuzz_427814452.phpt @@ -0,0 +1,26 @@ +--TEST-- +OSS-Fuzz #427814452 +--FILE-- + assert(...); +} catch (\AssertionError $e) { + echo $e::class, ": '", $e->getMessage(), "'\n"; +} +try { + 0 |> "assert"(...); +} catch (\AssertionError $e) { + echo $e::class, ": '", $e->getMessage(), "'\n"; +} +try { + false |> ("a"."ssert")(...); +} catch (\AssertionError $e) { + echo $e::class, ": '", $e->getMessage(), "'\n"; +} + +?> +--EXPECT-- +AssertionError: '' +AssertionError: '' +AssertionError: '' diff --git a/Zend/tests/pipe_operator/oss_fuzz_439125710.phpt b/Zend/tests/pipe_operator/oss_fuzz_439125710.phpt new file mode 100644 index 000000000000..320f55a4e668 --- /dev/null +++ b/Zend/tests/pipe_operator/oss_fuzz_439125710.phpt @@ -0,0 +1,8 @@ +--TEST-- +OSS-Fuzz #439125710 (Pipe cannot be used in write context) +--FILE-- +y)=y; +?> +--EXPECTF-- +Fatal error: Can't use function return value in write context in %s on line %d diff --git a/Zend/tests/pipe_operator/prec_001.phpt b/Zend/tests/pipe_operator/prec_001.phpt new file mode 100644 index 000000000000..3bd3397fd361 --- /dev/null +++ b/Zend/tests/pipe_operator/prec_001.phpt @@ -0,0 +1,12 @@ +--TEST-- +Pipe precedence 001 +--FILE-- + fn($x) => $x < 42 + |> fn($x) => var_dump($x); + +?> +--EXPECTF-- +Fatal error: Arrow functions on the right hand side of |> must be parenthesized in %s on line %d diff --git a/Zend/tests/pipe_operator/prec_002.phpt b/Zend/tests/pipe_operator/prec_002.phpt new file mode 100644 index 000000000000..00a16e61fed4 --- /dev/null +++ b/Zend/tests/pipe_operator/prec_002.phpt @@ -0,0 +1,12 @@ +--TEST-- +Pipe precedence 002 +--FILE-- + (fn($x) => $x < 42) + |> (fn($x) => var_dump($x)); + +?> +--EXPECT-- +bool(false) diff --git a/Zend/tests/pipe_operator/prec_003.phpt b/Zend/tests/pipe_operator/prec_003.phpt new file mode 100644 index 000000000000..9200b8014e09 --- /dev/null +++ b/Zend/tests/pipe_operator/prec_003.phpt @@ -0,0 +1,12 @@ +--TEST-- +Pipe precedence 003 +--FILE-- + fn() => print (new Exception)->getTraceAsString() . "\n\n" + |> fn() => print (new Exception)->getTraceAsString() . "\n\n"; + +?> +--EXPECTF-- +Fatal error: Arrow functions on the right hand side of |> must be parenthesized in %s on line %d diff --git a/Zend/tests/pipe_operator/prec_004.phpt b/Zend/tests/pipe_operator/prec_004.phpt new file mode 100644 index 000000000000..c04f483cdd8d --- /dev/null +++ b/Zend/tests/pipe_operator/prec_004.phpt @@ -0,0 +1,16 @@ +--TEST-- +Pipe precedence 004 +--FILE-- + (fn() => print (new Exception)->getTraceAsString() . "\n\n") + |> (fn() => print (new Exception)->getTraceAsString() . "\n\n"); + +?> +--EXPECTF-- +#0 %s(%d): {closure:%s:%d}(NULL) +#1 {main} + +#0 %s(%d): {closure:%s:%d}(1) +#1 {main} diff --git a/Zend/tests/pipe_operator/prec_005.phpt b/Zend/tests/pipe_operator/prec_005.phpt new file mode 100644 index 000000000000..0dd262324e3d --- /dev/null +++ b/Zend/tests/pipe_operator/prec_005.phpt @@ -0,0 +1,14 @@ +--TEST-- +Pipe precedence 005 +--FILE-- + (fn() => 2)); +} catch (AssertionError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +assert(false && 1 |> (fn() => 2)) diff --git a/Zend/tests/pipe_operator/prec_006.phpt b/Zend/tests/pipe_operator/prec_006.phpt new file mode 100644 index 000000000000..d7fdf4c9b55b --- /dev/null +++ b/Zend/tests/pipe_operator/prec_006.phpt @@ -0,0 +1,13 @@ +--TEST-- +Pipe precedence 006 +--FILE-- + fn ($x) => $x ?? throw new Exception('Value may not be null') + |> fn ($x) => var_dump($x); + +?> +--EXPECTF-- +Fatal error: Arrow functions on the right hand side of |> must be parenthesized in %s on line %d diff --git a/Zend/tests/pipe_operator/prec_007.phpt b/Zend/tests/pipe_operator/prec_007.phpt new file mode 100644 index 000000000000..c29db8565008 --- /dev/null +++ b/Zend/tests/pipe_operator/prec_007.phpt @@ -0,0 +1,24 @@ +--TEST-- +Pipe precedence 007 +--FILE-- + (fn ($x) => $x ?? throw new Exception('Value may not be null')) + |> (fn ($x) => var_dump($x)); + +$value = null; +$value + |> (fn ($x) => $x ?? throw new Exception('Value may not be null')) + |> (fn ($x) => var_dump($x)); + +?> +--EXPECTF-- +int(42) + +Fatal error: Uncaught Exception: Value may not be null in %s:%d +Stack trace: +#0 %s(%d): {closure:%s:%d}(NULL) +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/pipe_operator_reference_context.phpt b/Zend/tests/pipe_operator_reference_context.phpt new file mode 100644 index 000000000000..7d7572e2b2e5 --- /dev/null +++ b/Zend/tests/pipe_operator_reference_context.phpt @@ -0,0 +1,26 @@ +--TEST-- +Fix GH-19476: Pipe operator with function returning by reference +--FILE-- + get_ref(...); +} + +$ref = &test_pipe_ref(); +echo "Before: " . $ref . "\n"; +$ref = "changed"; +echo "After: " . test_pipe_ref() . "\n"; + +?> +--EXPECT-- +Before: original input +After: changed input diff --git a/Zend/tests/011.phpt b/Zend/tests/property_exists_basic.phpt similarity index 100% rename from Zend/tests/011.phpt rename to Zend/tests/property_exists_basic.phpt diff --git a/Zend/tests/property_hooks/bug001.phpt b/Zend/tests/property_hooks/bug001.phpt index 5328506d476c..62291019b333 100644 --- a/Zend/tests/property_hooks/bug001.phpt +++ b/Zend/tests/property_hooks/bug001.phpt @@ -27,4 +27,4 @@ try { ?> --EXPECT-- bool(true) -Property C::$x is read-only +Cannot write to get-only virtual property C::$x diff --git a/Zend/tests/property_hooks/bug008.phpt b/Zend/tests/property_hooks/bug008.phpt index 9c321cfe16e1..38fe709a38a3 100644 --- a/Zend/tests/property_hooks/bug008.phpt +++ b/Zend/tests/property_hooks/bug008.phpt @@ -18,7 +18,7 @@ $foo->bar = 'bar'; ?> --EXPECTF-- -Fatal error: Uncaught Error: Property Foo::$bar is read-only in %s:%d +Fatal error: Uncaught Error: Cannot write to get-only virtual property Foo::$bar in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/Zend/tests/property_hooks/cpp.phpt b/Zend/tests/property_hooks/cpp.phpt index 082c182467bc..1f893d853b8c 100644 --- a/Zend/tests/property_hooks/cpp.phpt +++ b/Zend/tests/property_hooks/cpp.phpt @@ -24,11 +24,13 @@ var_dump($r->hasDefaultValue()); var_dump($r->getDefaultValue()); ?> ---EXPECT-- +--EXPECTF-- Pre-test Setting Constructor Getting Setting bool(false) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL diff --git a/Zend/tests/property_hooks/get.phpt b/Zend/tests/property_hooks/get.phpt index 0cb0a6b7c76b..6d4b005843ea 100644 --- a/Zend/tests/property_hooks/get.phpt +++ b/Zend/tests/property_hooks/get.phpt @@ -21,4 +21,4 @@ try { ?> --EXPECT-- int(42) -Property Test::$prop is read-only +Cannot write to get-only virtual property Test::$prop diff --git a/Zend/tests/property_hooks/get_by_ref_implemented_by_val.phpt b/Zend/tests/property_hooks/get_by_ref_implemented_by_val.phpt index 84eb96826354..2c507d862be6 100644 --- a/Zend/tests/property_hooks/get_by_ref_implemented_by_val.phpt +++ b/Zend/tests/property_hooks/get_by_ref_implemented_by_val.phpt @@ -15,4 +15,4 @@ class A implements I { ?> --EXPECTF-- -Fatal error: Declaration of A::$prop::get() must be compatible with & I::$prop::get() in %s on line %d +Fatal error: Declaration of A::$prop::get() must be compatible with &I::$prop::get() in %s on line %d diff --git a/Zend/tests/property_hooks/gh19044-1.phpt b/Zend/tests/property_hooks/gh19044-1.phpt new file mode 100644 index 000000000000..133727c73def --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-1.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (common ancestor has a protected setter) +--FILE-- + 1; set {} } +} + +class GrandC1 extends C1 { + public protected(set) mixed $foo { get => 2; set {} } +} + +class C2 extends C1 { + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new GrandC1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-2.phpt b/Zend/tests/property_hooks/gh19044-2.phpt new file mode 100644 index 000000000000..ed73c60dc5a3 --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-2.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (common ancestor does not have a setter) +--FILE-- + 1; } +} + +class GrandC1 extends C1 { + public protected(set) mixed $foo { get => 2; set {} } +} + +class C2 extends C1 { + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new GrandC1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-3.phpt b/Zend/tests/property_hooks/gh19044-3.phpt new file mode 100644 index 000000000000..3d4f6789a5a3 --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-3.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent defining visibility only takes precedence) +--FILE-- + 2; set {} } +} + +class C2 extends P { + public mixed $foo = 1; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-4.phpt b/Zend/tests/property_hooks/gh19044-4.phpt new file mode 100644 index 000000000000..e1abf4739083 --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-4.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent sets protected(set) with not having grandparent a setter - both inherit from parent) +--FILE-- + 2; set {} } +} + +class C2 extends P { + public mixed $foo = 1; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-5.phpt b/Zend/tests/property_hooks/gh19044-5.phpt new file mode 100644 index 000000000000..773682961ab4 --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-5.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent sets protected(set) with not having grandparent a setter - one inherits from grandparent) +--FILE-- + 2; set {} } +} + +class C2 extends GP { + public mixed $foo = 1; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(3) diff --git a/Zend/tests/property_hooks/gh19044-6.phpt b/Zend/tests/property_hooks/gh19044-6.phpt new file mode 100644 index 000000000000..43332698fe9f --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-6.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (abstract parent has implicit set hook) +--FILE-- + $this->foo; } +} + +class C1 extends P { + public protected(set) mixed $foo = 1; +} + +class C2 extends P { + public protected(set) mixed $foo; + + static function foo($c) { return $c->foo += 1; } +} + +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(2) diff --git a/Zend/tests/property_hooks/gh19044-8.phpt b/Zend/tests/property_hooks/gh19044-8.phpt new file mode 100644 index 000000000000..2fa62e4619f5 --- /dev/null +++ b/Zend/tests/property_hooks/gh19044-8.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19044: Protected properties must be scoped according to their prototype (hooks variation) +--FILE-- +foo; } +} + +var_dump(C2::foo(new C2)); +var_dump(C2::foo(new C1)); + +?> +--EXPECT-- +int(2) +int(1) diff --git a/Zend/tests/property_hooks/gh19548.phpt b/Zend/tests/property_hooks/gh19548.phpt new file mode 100644 index 000000000000..d34ed0a74bb2 --- /dev/null +++ b/Zend/tests/property_hooks/gh19548.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-19548: Segfault when using inherited properties and opcache +--FILE-- + +--EXPECT-- +Test passed - no segmentation fault diff --git a/Zend/tests/property_hooks/gh19548_002.phpt b/Zend/tests/property_hooks/gh19548_002.phpt new file mode 100644 index 000000000000..bba006b81032 --- /dev/null +++ b/Zend/tests/property_hooks/gh19548_002.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-19548: Segfault when using inherited properties and opcache (multiple properties) +--FILE-- + +--EXPECT-- +Multiple property test passed - no segmentation fault diff --git a/Zend/tests/property_hooks/gh20270.phpt b/Zend/tests/property_hooks/gh20270.phpt new file mode 100644 index 000000000000..173d21990e55 --- /dev/null +++ b/Zend/tests/property_hooks/gh20270.phpt @@ -0,0 +1,51 @@ +--TEST-- +GH-20270: Parent hook call with named arguments +--CREDITS-- +Viet Hoang Luu (@vi3tL0u1s) +--FILE-- + $custom; + } +} + +class B extends A { + public mixed $prop1 { + set { + parent::$prop1::set(value: 42); + parent::$prop1::set(unknown: 43); + } + } + public mixed $prop2 { + set { + parent::$prop2::set(custom: 42); + parent::$prop2::set(value: 43); + } + } +} + +$b = new B(); + +try { + $b->prop1 = 0; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($b->prop1); + +try { + $b->prop2 = 0; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($b->prop2); + +?> +--EXPECT-- +Unknown named parameter $unknown +int(42) +Unknown named parameter $value +int(42) diff --git a/Zend/tests/property_hooks/gh20479.phpt b/Zend/tests/property_hooks/gh20479.phpt new file mode 100644 index 000000000000..c53c4e4240c6 --- /dev/null +++ b/Zend/tests/property_hooks/gh20479.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-20479: Hooked object properties overflow +--CREDITS-- +Viet Hoang Luu (@vi3tL0u1s) +--FILE-- +g = $obj->h = 'x'; +var_export($obj); + +?> +--EXPECT-- +\Trigger::__set_state(array( + 'a' => 'x', + 'b' => 'x', + 'c' => 'x', + 'd' => 'x', + 'e' => 'x', + 'f' => 'x', + 'trigger' => 'trigger', + 'h' => 'x', + 'g' => 'x', +)) diff --git a/Zend/tests/property_hooks/override_add_get.phpt b/Zend/tests/property_hooks/override_add_get.phpt index 28dbd047c071..df2739e6086c 100644 --- a/Zend/tests/property_hooks/override_add_get.phpt +++ b/Zend/tests/property_hooks/override_add_get.phpt @@ -31,7 +31,7 @@ var_dump($b->prop); ?> --EXPECT-- A::A::$prop::set -Property A::$prop is write-only +Cannot read from set-only virtual property A::$prop B::B::$prop::set B::B::$prop::get int(42) diff --git a/Zend/tests/property_hooks/override_add_set.phpt b/Zend/tests/property_hooks/override_add_set.phpt index 6b490d4d87f9..e13de15f0b82 100644 --- a/Zend/tests/property_hooks/override_add_set.phpt +++ b/Zend/tests/property_hooks/override_add_set.phpt @@ -30,7 +30,7 @@ var_dump($b->prop); ?> --EXPECT-- -Property A::$prop is read-only +Cannot write to get-only virtual property A::$prop A::A::$prop::get int(42) B::B::$prop::set diff --git a/Zend/tests/property_hooks/set.phpt b/Zend/tests/property_hooks/set.phpt index 04e36ae85411..2928aee6cede 100644 --- a/Zend/tests/property_hooks/set.phpt +++ b/Zend/tests/property_hooks/set.phpt @@ -28,5 +28,5 @@ try { ?> --EXPECT-- int(42) -Property Test::$prop is write-only -Property Test::$prop is write-only +Cannot read from set-only virtual property Test::$prop +Cannot read from set-only virtual property Test::$prop diff --git a/Zend/tests/property_hooks/type_compatibility.phpt b/Zend/tests/property_hooks/type_compatibility.phpt index 8bfb7b0cadd5..def1fc77dc9c 100644 --- a/Zend/tests/property_hooks/type_compatibility.phpt +++ b/Zend/tests/property_hooks/type_compatibility.phpt @@ -1,5 +1,5 @@ --TEST-- -Relaxed type compatibility for read-only and write-only properties +Relaxed type compatibility for get-only and set-only properties --FILE-- --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class class@anonymous in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to readonly class class@anonymous in %s on line %d diff --git a/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt b/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt index ace50c572ace..fab37dccfbf6 100644 --- a/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt +++ b/Zend/tests/readonly_classes/readonly_class_dynamic_property_attribute.phpt @@ -10,4 +10,4 @@ readonly class Foo ?> --EXPECTF-- -Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo in %s on line %d +Fatal error: Cannot apply #[\AllowDynamicProperties] to readonly class Foo in %s on line %d diff --git a/Zend/tests/return_types/042.phpt b/Zend/tests/return_types/042.phpt index 069e0228ff99..21483047d4f2 100644 --- a/Zend/tests/return_types/042.phpt +++ b/Zend/tests/return_types/042.phpt @@ -20,5 +20,10 @@ class JustAnArray { echo 'No problems!'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning null from UnionType::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d + +Deprecated: Returning null from UnionType2::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d + +Deprecated: Returning null from UnionTypeOldStyle::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d No problems! diff --git a/Zend/tests/runtime_compile_time_binary_operands.phpt b/Zend/tests/runtime_compile_time_binary_operands.phpt index e18134283e83..948246f73b40 100644 --- a/Zend/tests/runtime_compile_time_binary_operands.phpt +++ b/Zend/tests/runtime_compile_time_binary_operands.phpt @@ -8,7 +8,7 @@ if (getenv("SKIP_SLOW_TESTS")) die('skip slow test'); ?> --FILE-- 16*1024*1024, // https://github.com/actions/runner-images/pull/3328 default => 8*1024*1024, }, - 'SunOS' => 10 * 1024 * 1024, + 'SunOS' => preg_match('/(omnios|illumos|smartos|oi-|openindiana|joyent)/i', php_uname('v')) + ? 10 * 1024 * 1024 + : 8 * 1024 * 1024, 'Windows NT' => 67108864 - 4*4096, // Set by sapi/cli/config.w32 }; diff --git a/Zend/tests/stack_limit/stack_limit_015.phpt b/Zend/tests/stack_limit/stack_limit_015.phpt index b725523b7840..88ff544e9f33 100644 --- a/Zend/tests/stack_limit/stack_limit_015.phpt +++ b/Zend/tests/stack_limit/stack_limit_015.phpt @@ -9,7 +9,7 @@ if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_ --EXTENSIONS-- zend_test --INI-- -zend.max_allowed_stack_size=128K +zend.max_allowed_stack_size=64K --FILE-- --FILE-- +--FILE-- + +--EXPECTF-- +Warning: The float -4.000000000000001E+21 is not representable as an int, cast occurred in %s on line %d +int(-2056257536) + +Warning: The float -4.0000000000000005E+21 is not representable as an int, cast occurred in %s on line %d +int(-2055733248) + +Warning: The float -4.0E+21 is not representable as an int, cast occurred in %s on line %d +int(-2055208960) + +Warning: The float -3.9999999999999995E+21 is not representable as an int, cast occurred in %s on line %d +int(-2054684672) + +Warning: The float -3.999999999999999E+21 is not representable as an int, cast occurred in %s on line %d +int(-2054160384) + +Warning: The float -2147483649.8 is not representable as an int, cast occurred in %s on line %d +int(2147483647) diff --git a/Zend/tests/type_coercion/float_to_int/dval_to_lval_64.phpt b/Zend/tests/type_coercion/float_to_int/dval_to_lval_64.phpt new file mode 100644 index 000000000000..993950534fc1 --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/dval_to_lval_64.phpt @@ -0,0 +1,38 @@ +--TEST-- +zend_dval_to_lval preserves low bits (64 bit long) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: The float -4.000000000000001E+21 is not representable as an int, cast occurred in %s on line %d +int(2943463994971652096) + +Warning: The float -4.0000000000000005E+21 is not representable as an int, cast occurred in %s on line %d +int(2943463994972176384) + +Warning: The float -4.0E+21 is not representable as an int, cast occurred in %s on line %d +int(2943463994972700672) + +Warning: The float -3.9999999999999995E+21 is not representable as an int, cast occurred in %s on line %d +int(2943463994973224960) + +Warning: The float -3.999999999999999E+21 is not representable as an int, cast occurred in %s on line %d +int(2943463994973749248) diff --git a/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn.phpt b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn.phpt new file mode 100644 index 000000000000..d62f8cd158e1 --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn.phpt @@ -0,0 +1,45 @@ +--TEST-- +Explicit (int) cast must not warn if value is representable +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: unexpected NAN value was coerced to string in %s on line %d +int(3) +int(3) + +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d +int(0) + +Warning: The float 1.0E+301 is not representable as an int, cast occurred in %s on line %d +int(0) + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d +int(0) +int(3) +int(3) +int(9223372036854775807) +int(9223372036854775807) +int(0) diff --git a/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn_32bit.phpt b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn_32bit.phpt new file mode 100644 index 000000000000..23cd2854ba45 --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn_32bit.phpt @@ -0,0 +1,45 @@ +--TEST-- +Explicit (int) cast must not warn if value is representable 32bit variation +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: unexpected NAN value was coerced to string in %s on line %d +int(3) +int(3) + +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d +int(0) + +Warning: The float 1.0E+301 is not representable as an int, cast occurred in %s on line %d +int(0) + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d +int(0) +int(3) +int(3) +int(2147483647) +int(2147483647) +int(0) diff --git a/Zend/tests/float_to_int/negative_zero_check.phpt b/Zend/tests/type_coercion/float_to_int/negative_zero_check.phpt similarity index 100% rename from Zend/tests/float_to_int/negative_zero_check.phpt rename to Zend/tests/type_coercion/float_to_int/negative_zero_check.phpt diff --git a/Zend/tests/float_to_int/no_warning_compatible_float_literals.phpt b/Zend/tests/type_coercion/float_to_int/no_warning_compatible_float_literals.phpt similarity index 100% rename from Zend/tests/float_to_int/no_warning_compatible_float_literals.phpt rename to Zend/tests/type_coercion/float_to_int/no_warning_compatible_float_literals.phpt diff --git a/Zend/tests/float_to_int/no_warning_compatible_string_float_literals.phpt b/Zend/tests/type_coercion/float_to_int/no_warning_compatible_string_float_literals.phpt similarity index 100% rename from Zend/tests/float_to_int/no_warning_compatible_string_float_literals.phpt rename to Zend/tests/type_coercion/float_to_int/no_warning_compatible_string_float_literals.phpt diff --git a/Zend/tests/float_to_int/no_warnings_compatible_float_literals_assignment_ops.phpt b/Zend/tests/type_coercion/float_to_int/no_warnings_compatible_float_literals_assignment_ops.phpt similarity index 100% rename from Zend/tests/float_to_int/no_warnings_compatible_float_literals_assignment_ops.phpt rename to Zend/tests/type_coercion/float_to_int/no_warnings_compatible_float_literals_assignment_ops.phpt diff --git a/Zend/tests/float_to_int/no_warnings_compatible_float_vars.phpt b/Zend/tests/type_coercion/float_to_int/no_warnings_compatible_float_vars.phpt similarity index 100% rename from Zend/tests/float_to_int/no_warnings_compatible_float_vars.phpt rename to Zend/tests/type_coercion/float_to_int/no_warnings_compatible_float_vars.phpt diff --git a/Zend/tests/float_to_int/no_warnings_compatible_string_float_vars.phpt b/Zend/tests/type_coercion/float_to_int/no_warnings_compatible_string_float_vars.phpt similarity index 100% rename from Zend/tests/float_to_int/no_warnings_compatible_string_float_vars.phpt rename to Zend/tests/type_coercion/float_to_int/no_warnings_compatible_string_float_vars.phpt diff --git a/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra1.phpt b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra1.phpt new file mode 100644 index 000000000000..42b91f4a656d --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Non rep float string to int conversions should not crash when modified +--FILE-- + +--EXPECTF-- +Implicit conversion from float-string "1.0E+4%d" to int loses precision +int(%d) diff --git a/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra2.phpt b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra2.phpt new file mode 100644 index 000000000000..0e96acfd182d --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Non rep float string to int conversions should not crash when modified +--FILE-- + +--EXPECT-- +The float 1.0E+42 is not representable as an int, cast occurred diff --git a/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra3.phpt b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra3.phpt new file mode 100644 index 000000000000..0bfbeb01a2d0 --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra3.phpt @@ -0,0 +1,18 @@ +--TEST-- +Non rep float string to int conversions should not crash when modified +--FILE-- + +--EXPECT-- +The float 1.0E+42 is not representable as an int, cast occurred +bool(false) diff --git a/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra4.phpt b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra4.phpt new file mode 100644 index 000000000000..8134ce08d2ee --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/non-rep-float-as-int-extra4.phpt @@ -0,0 +1,18 @@ +--TEST-- +Non rep float string to int conversions should not crash when modified +--FILE-- + +--EXPECT-- +The float 1.0E+42 is not representable as an int, cast occurred +bool(false) diff --git a/Zend/tests/float_to_int/union_int_string_type_arg.phpt b/Zend/tests/type_coercion/float_to_int/union_int_string_type_arg.phpt similarity index 85% rename from Zend/tests/float_to_int/union_int_string_type_arg.phpt rename to Zend/tests/type_coercion/float_to_int/union_int_string_type_arg.phpt index 3208b44e1ad2..9b1f057b7484 100644 --- a/Zend/tests/float_to_int/union_int_string_type_arg.phpt +++ b/Zend/tests/type_coercion/float_to_int/union_int_string_type_arg.phpt @@ -23,6 +23,8 @@ int(1) Deprecated: Implicit conversion from float 1.5 to int loses precision in %s on line %d int(1) + +Warning: unexpected NAN value was coerced to string in %s on line %d string(3) "NAN" string(8) "1.0E+121" string(3) "INF" diff --git a/Zend/tests/float_to_int/union_int_string_type_arg_promote_exception.phpt b/Zend/tests/type_coercion/float_to_int/union_int_string_type_arg_promote_exception.phpt similarity index 100% rename from Zend/tests/float_to_int/union_int_string_type_arg_promote_exception.phpt rename to Zend/tests/type_coercion/float_to_int/union_int_string_type_arg_promote_exception.phpt diff --git a/Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_arrays.phpt b/Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_arrays.phpt new file mode 100644 index 000000000000..13834e61c741 --- /dev/null +++ b/Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_arrays.phpt @@ -0,0 +1,56 @@ +--TEST-- +Implicit float to int conversions when float too large should warn, array variant +--FILE-- + 'Large float', (string) 10e120 => 'String large float']; +$arrayDynamic = [$float => 'Large float', $string_float => 'String large float']; + +var_dump($arrayConstant); +var_dump($arrayDynamic); + +$array = ['0', '1', '2']; +var_dump($array[10e120]); +var_dump($array[(string) 10e120]); +var_dump($array[$float]); +var_dump($array[$string_float]); + +?> +--EXPECTF-- +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d +int(0) +bool(true) + +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d + +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d +array(2) { + [0]=> + string(11) "Large float" + ["1.0E+121"]=> + string(18) "String large float" +} +array(2) { + [0]=> + string(11) "Large float" + ["1.0E+121"]=> + string(18) "String large float" +} + +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d +string(1) "0" + +Warning: Undefined array key "1.0E+121" in %s on line %d +NULL + +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d +string(1) "0" + +Warning: Undefined array key "1.0E+121" in %s on line %d +NULL diff --git a/Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_strings.phpt b/Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_strings.phpt similarity index 96% rename from Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_strings.phpt rename to Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_strings.phpt index 0c63cba1f5bc..284b96eb9233 100644 --- a/Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_strings.phpt +++ b/Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_strings.phpt @@ -75,6 +75,7 @@ var_dump($string); ?> --EXPECTF-- +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d int(0) int(9223372036854775807) Attempt to read diff --git a/Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_strings_32bit.phpt b/Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_strings_32bit.phpt similarity index 96% rename from Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_strings_32bit.phpt rename to Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_strings_32bit.phpt index cf2e396c311b..720614d62693 100644 --- a/Zend/tests/float_to_int/warning_float_does_not_fit_zend_long_strings_32bit.phpt +++ b/Zend/tests/type_coercion/float_to_int/warning_float_does_not_fit_zend_long_strings_32bit.phpt @@ -75,6 +75,7 @@ var_dump($string); ?> --EXPECTF-- +Warning: The float 1.0E+121 is not representable as an int, cast occurred in %s on line %d int(0) int(2147483647) Attempt to read diff --git a/Zend/tests/float_to_int/warnings_float_literals.phpt b/Zend/tests/type_coercion/float_to_int/warnings_float_literals.phpt similarity index 100% rename from Zend/tests/float_to_int/warnings_float_literals.phpt rename to Zend/tests/type_coercion/float_to_int/warnings_float_literals.phpt diff --git a/Zend/tests/float_to_int/warnings_float_literals_assignment_ops.phpt b/Zend/tests/type_coercion/float_to_int/warnings_float_literals_assignment_ops.phpt similarity index 100% rename from Zend/tests/float_to_int/warnings_float_literals_assignment_ops.phpt rename to Zend/tests/type_coercion/float_to_int/warnings_float_literals_assignment_ops.phpt diff --git a/Zend/tests/float_to_int/warnings_float_vars.phpt b/Zend/tests/type_coercion/float_to_int/warnings_float_vars.phpt similarity index 100% rename from Zend/tests/float_to_int/warnings_float_vars.phpt rename to Zend/tests/type_coercion/float_to_int/warnings_float_vars.phpt diff --git a/Zend/tests/float_to_int/warnings_string_float_literals.phpt b/Zend/tests/type_coercion/float_to_int/warnings_string_float_literals.phpt similarity index 100% rename from Zend/tests/float_to_int/warnings_string_float_literals.phpt rename to Zend/tests/type_coercion/float_to_int/warnings_string_float_literals.phpt diff --git a/Zend/tests/float_to_int/warnings_string_float_literals_assignment_ops.phpt b/Zend/tests/type_coercion/float_to_int/warnings_string_float_literals_assignment_ops.phpt similarity index 100% rename from Zend/tests/float_to_int/warnings_string_float_literals_assignment_ops.phpt rename to Zend/tests/type_coercion/float_to_int/warnings_string_float_literals_assignment_ops.phpt diff --git a/Zend/tests/float_to_int/warnings_string_float_vars.phpt b/Zend/tests/type_coercion/float_to_int/warnings_string_float_vars.phpt similarity index 100% rename from Zend/tests/float_to_int/warnings_string_float_vars.phpt rename to Zend/tests/type_coercion/float_to_int/warnings_string_float_vars.phpt diff --git a/Zend/tests/type_coercion/int_special_values.phpt b/Zend/tests/type_coercion/int_special_values.phpt new file mode 100644 index 000000000000..e536ff988e0a --- /dev/null +++ b/Zend/tests/type_coercion/int_special_values.phpt @@ -0,0 +1,43 @@ +--TEST-- +Conversion of special float values to int +--FILE-- + +--EXPECTF-- +float(0) +int(0) + +float(INF) + +Warning: The float INF is not representable as an int, cast occurred in %s on line %d +int(0) + +float(-INF) + +Warning: The float -INF is not representable as an int, cast occurred in %s on line %d +int(0) + +float(0) +int(0) + +float(-0) +int(0) + +float(NAN) + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d +int(0) diff --git a/Zend/tests/type_coercion/nan_comp_op.phpt b/Zend/tests/type_coercion/nan_comp_op.phpt new file mode 100644 index 000000000000..0be33cbb26ab --- /dev/null +++ b/Zend/tests/type_coercion/nan_comp_op.phpt @@ -0,0 +1,106 @@ +--TEST-- +NAN coerced to other types +--FILE-- + $right); + var_dump($nan >= $right); + var_dump($nan <=> $right); +} + +?> +--EXPECT-- +float(NAN) +Using 0 as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +int(1) +Using NULL as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +int(1) +Using false as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +int(1) +Using true as right op +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +int(0) +Using '' as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +int(1) +Using array ( +) as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) +bool(true) +bool(false) +bool(false) +int(-1) +Using NAN as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +int(1) diff --git a/Zend/tests/type_coercion/nan_to_other.phpt b/Zend/tests/type_coercion/nan_to_other.phpt new file mode 100644 index 000000000000..2918d1a8ccf4 --- /dev/null +++ b/Zend/tests/type_coercion/nan_to_other.phpt @@ -0,0 +1,93 @@ +--TEST-- +NAN coerced to other types +--FILE-- + +--EXPECTF-- +float(NAN) + +Warning: unexpected NAN value was coerced to bool in %s on line %d +bool(true) + +Warning: unexpected NAN value was coerced to string in %s on line %d +string(3) "NAN" + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d +int(0) + +Warning: unexpected NAN value was coerced to bool in %s on line %d +bool(true) + +Warning: unexpected NAN value was coerced to string in %s on line %d +string(3) "NAN" + +Warning: unexpected NAN value was coerced to array in %s on line %d +array(1) { + [0]=> + float(NAN) +} + +Warning: unexpected NAN value was coerced to object in %s on line %d +object(stdClass)#%d (1) { + ["scalar"]=> + float(NAN) +} + +Warning: unexpected NAN value was coerced to null in %s on line %d +NULL + +Warning: unexpected NAN value was coerced to bool in %s on line %d +bool(true) + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d +int(0) + +Warning: unexpected NAN value was coerced to string in %s on line %d +string(3) "NAN" + +Warning: unexpected NAN value was coerced to array in %s on line %d +array(1) { + [0]=> + float(NAN) +} + +Warning: unexpected NAN value was coerced to object in %s on line %d +object(stdClass)#%d (1) { + ["scalar"]=> + float(NAN) +} diff --git a/Zend/tests/settype/settype_array.phpt b/Zend/tests/type_coercion/settype/settype_array.phpt similarity index 100% rename from Zend/tests/settype/settype_array.phpt rename to Zend/tests/type_coercion/settype/settype_array.phpt diff --git a/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler.phpt new file mode 100644 index 000000000000..b07d975d7b2f --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to array +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to array +array(1) { + [0]=> + NULL +} diff --git a/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler2.phpt new file mode 100644 index 000000000000..681b01559302 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to array 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to array +array(1) { + [0]=> + float(NAN) +} diff --git a/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler3.phpt new file mode 100644 index 000000000000..1dae45a6ebec --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler3.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to array 3 +--FILE-- + +--EXPECTF-- +float(NAN) +unexpected NAN value was coerced to array +array(1) { + [0]=> + string(8) "%s" +} diff --git a/Zend/tests/settype/settype_bool.phpt b/Zend/tests/type_coercion/settype/settype_bool.phpt similarity index 100% rename from Zend/tests/settype/settype_bool.phpt rename to Zend/tests/type_coercion/settype/settype_bool.phpt diff --git a/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler.phpt new file mode 100644 index 000000000000..5f854c54ddbd --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to bool +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to bool +bool(true) diff --git a/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler2.phpt new file mode 100644 index 000000000000..1377228a9da6 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to bool 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to bool +bool(true) diff --git a/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler3.phpt new file mode 100644 index 000000000000..ceb17da96408 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to bool 3 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to bool +bool(true) diff --git a/Zend/tests/settype/settype_double.phpt b/Zend/tests/type_coercion/settype/settype_double.phpt similarity index 100% rename from Zend/tests/settype/settype_double.phpt rename to Zend/tests/type_coercion/settype/settype_double.phpt diff --git a/Zend/tests/settype/settype_int.phpt b/Zend/tests/type_coercion/settype/settype_int.phpt similarity index 100% rename from Zend/tests/settype/settype_int.phpt rename to Zend/tests/type_coercion/settype/settype_int.phpt diff --git a/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler.phpt new file mode 100644 index 000000000000..4f00f51331e0 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to int +--FILE-- + +--EXPECT-- +float(NAN) +The float NAN is not representable as an int, cast occurred +int(0) diff --git a/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler2.phpt new file mode 100644 index 000000000000..65c048158f8a --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to int 2 +--FILE-- + +--EXPECT-- +float(NAN) +The float NAN is not representable as an int, cast occurred +int(0) diff --git a/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler3.phpt new file mode 100644 index 000000000000..4e715bdcca1b --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to int 3 +--FILE-- + +--EXPECT-- +float(NAN) +The float NAN is not representable as an int, cast occurred +int(0) diff --git a/Zend/tests/settype/settype_null.phpt b/Zend/tests/type_coercion/settype/settype_null.phpt similarity index 100% rename from Zend/tests/settype/settype_null.phpt rename to Zend/tests/type_coercion/settype/settype_null.phpt diff --git a/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler.phpt new file mode 100644 index 000000000000..d89cb5544324 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to null +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to null +NULL diff --git a/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler2.phpt new file mode 100644 index 000000000000..41c095ff3f0b --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to null 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to null +NULL diff --git a/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler3.phpt new file mode 100644 index 000000000000..9a289b4151aa --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to null 3 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to null +NULL diff --git a/Zend/tests/settype/settype_object.phpt b/Zend/tests/type_coercion/settype/settype_object.phpt similarity index 100% rename from Zend/tests/settype/settype_object.phpt rename to Zend/tests/type_coercion/settype/settype_object.phpt diff --git a/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler.phpt new file mode 100644 index 000000000000..19e36fa3d4fc --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to object +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to object +object(stdClass)#2 (1) { + ["scalar"]=> + NULL +} diff --git a/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler2.phpt new file mode 100644 index 000000000000..b605d0ff9e7e --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to object 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to object +object(stdClass)#2 (1) { + ["scalar"]=> + float(NAN) +} diff --git a/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler3.phpt new file mode 100644 index 000000000000..b3789f2a9c57 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler3.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to object 3 +--FILE-- + +--EXPECTF-- +float(NAN) +unexpected NAN value was coerced to object +object(stdClass)#2 (1) { + ["scalar"]=> + string(8) "%s" +} diff --git a/Zend/tests/settype/settype_resource.phpt b/Zend/tests/type_coercion/settype/settype_resource.phpt similarity index 100% rename from Zend/tests/settype/settype_resource.phpt rename to Zend/tests/type_coercion/settype/settype_resource.phpt diff --git a/Zend/tests/settype/settype_string.phpt b/Zend/tests/type_coercion/settype/settype_string.phpt similarity index 100% rename from Zend/tests/settype/settype_string.phpt rename to Zend/tests/type_coercion/settype/settype_string.phpt diff --git a/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler.phpt new file mode 100644 index 000000000000..d3a52996f4dd --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to string +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to string +string(3) "NAN" diff --git a/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler2.phpt new file mode 100644 index 000000000000..17921e5ae530 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to string 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to string +string(3) "NAN" \ No newline at end of file diff --git a/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler3.phpt new file mode 100644 index 000000000000..0a8718780abd --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to string 3 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to string +string(3) "NAN" diff --git a/Zend/tests/type_casts/cast_to_array.phpt b/Zend/tests/type_coercion/type_casts/cast_to_array.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_array.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_array.phpt diff --git a/Zend/tests/type_casts/cast_to_bool.phpt b/Zend/tests/type_coercion/type_casts/cast_to_bool.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_bool.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_bool.phpt diff --git a/Zend/tests/type_casts/cast_to_double.phpt b/Zend/tests/type_coercion/type_casts/cast_to_double.phpt similarity index 90% rename from Zend/tests/type_casts/cast_to_double.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_double.phpt index 2972fbbe8027..69a625b09de8 100644 --- a/Zend/tests/type_casts/cast_to_double.phpt +++ b/Zend/tests/type_coercion/type_casts/cast_to_double.phpt @@ -1,5 +1,5 @@ --TEST-- -casting different variables to double +casting different variables to float --INI-- precision=14 --FILE-- @@ -32,7 +32,7 @@ $vars = array( ); foreach ($vars as $var) { - $tmp = (double)$var; + $tmp = (float)$var; var_dump($tmp); } diff --git a/Zend/tests/type_casts/cast_to_int.phpt b/Zend/tests/type_coercion/type_casts/cast_to_int.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_int.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_int.phpt diff --git a/Zend/tests/type_casts/cast_to_object.phpt b/Zend/tests/type_coercion/type_casts/cast_to_object.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_object.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_object.phpt diff --git a/Zend/tests/type_casts/cast_to_string.phpt b/Zend/tests/type_coercion/type_casts/cast_to_string.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_string.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_string.phpt diff --git a/Zend/tests/type_casts/cast_to_void.phpt b/Zend/tests/type_coercion/type_casts/cast_to_void.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_void.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_void.phpt diff --git a/Zend/tests/type_casts/cast_to_void_ast.phpt b/Zend/tests/type_coercion/type_casts/cast_to_void_ast.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_void_ast.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_void_ast.phpt diff --git a/Zend/tests/type_casts/cast_to_void_destructor.phpt b/Zend/tests/type_coercion/type_casts/cast_to_void_destructor.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_void_destructor.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_void_destructor.phpt diff --git a/Zend/tests/type_casts/cast_to_void_statement.phpt b/Zend/tests/type_coercion/type_casts/cast_to_void_statement.phpt similarity index 100% rename from Zend/tests/type_casts/cast_to_void_statement.phpt rename to Zend/tests/type_coercion/type_casts/cast_to_void_statement.phpt diff --git a/Zend/tests/type_casts/gh18301_cast_to_void_for.phpt b/Zend/tests/type_coercion/type_casts/gh18301_cast_to_void_for.phpt similarity index 100% rename from Zend/tests/type_casts/gh18301_cast_to_void_for.phpt rename to Zend/tests/type_coercion/type_casts/gh18301_cast_to_void_for.phpt diff --git a/Zend/tests/type_casts/gh18301_cast_to_void_statement_for_condition.phpt b/Zend/tests/type_coercion/type_casts/gh18301_cast_to_void_statement_for_condition.phpt similarity index 100% rename from Zend/tests/type_casts/gh18301_cast_to_void_statement_for_condition.phpt rename to Zend/tests/type_coercion/type_casts/gh18301_cast_to_void_statement_for_condition.phpt diff --git a/Zend/tests/type_coercion/type_casts/non_canonical_binary_cast.phpt b/Zend/tests/type_coercion/type_casts/non_canonical_binary_cast.phpt new file mode 100644 index 000000000000..fc7aa59ac908 --- /dev/null +++ b/Zend/tests/type_coercion/type_casts/non_canonical_binary_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (binary) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (binary) is deprecated, use the (string) cast instead in %s on line %d +string(2) "42" diff --git a/Zend/tests/type_coercion/type_casts/non_canonical_boolean_cast.phpt b/Zend/tests/type_coercion/type_casts/non_canonical_boolean_cast.phpt new file mode 100644 index 000000000000..e0db0eec475f --- /dev/null +++ b/Zend/tests/type_coercion/type_casts/non_canonical_boolean_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (boolean) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (boolean) is deprecated, use the (bool) cast instead in %s on line %d +bool(true) diff --git a/Zend/tests/type_coercion/type_casts/non_canonical_double_cast.phpt b/Zend/tests/type_coercion/type_casts/non_canonical_double_cast.phpt new file mode 100644 index 000000000000..91769a206a47 --- /dev/null +++ b/Zend/tests/type_coercion/type_casts/non_canonical_double_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (double) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (double) is deprecated, use the (float) cast instead in %s on line %d +float(42) diff --git a/Zend/tests/type_coercion/type_casts/non_canonical_integer_cast.phpt b/Zend/tests/type_coercion/type_casts/non_canonical_integer_cast.phpt new file mode 100644 index 000000000000..4f428ff9d53e --- /dev/null +++ b/Zend/tests/type_coercion/type_casts/non_canonical_integer_cast.phpt @@ -0,0 +1,11 @@ +--TEST-- +Non canonical (integer) cast +--FILE-- + +--EXPECTF-- +Deprecated: Non-canonical cast (integer) is deprecated, use the (int) cast instead in %s on line %d +int(42) diff --git a/Zend/tests/type_casts/real_cast.phpt b/Zend/tests/type_coercion/type_casts/real_cast.phpt similarity index 100% rename from Zend/tests/type_casts/real_cast.phpt rename to Zend/tests/type_coercion/type_casts/real_cast.phpt diff --git a/Zend/tests/type_casts/string_cast_reference_tostring.phpt b/Zend/tests/type_coercion/type_casts/string_cast_reference_tostring.phpt similarity index 100% rename from Zend/tests/type_casts/string_cast_reference_tostring.phpt rename to Zend/tests/type_coercion/type_casts/string_cast_reference_tostring.phpt diff --git a/Zend/tests/type_declarations/scalar_basic.phpt b/Zend/tests/type_declarations/scalar_basic.phpt index 6b2cf736edbf..352c48f8a9e0 100644 --- a/Zend/tests/type_declarations/scalar_basic.phpt +++ b/Zend/tests/type_declarations/scalar_basic.phpt @@ -194,6 +194,7 @@ string(0) "" string(%d) "%d" *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to string on line %d string(3) "NAN" *** Trying bool(true) @@ -247,6 +248,7 @@ bool(false) bool(true) *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to bool on line %d bool(true) *** Trying bool(true) diff --git a/Zend/tests/type_declarations/scalar_return_basic.phpt b/Zend/tests/type_declarations/scalar_return_basic.phpt index 8f827600328e..67af304ec2c6 100644 --- a/Zend/tests/type_declarations/scalar_return_basic.phpt +++ b/Zend/tests/type_declarations/scalar_return_basic.phpt @@ -156,6 +156,7 @@ string(0) "" *** Trying int(2147483647) string(10) "2147483647" *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to string on line %d string(3) "NAN" *** Trying bool(true) string(1) "1" @@ -193,6 +194,7 @@ bool(false) *** Trying int(2147483647) bool(true) *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to bool on line %d bool(true) *** Trying bool(true) bool(true) diff --git a/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt b/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt index 0a32dd3f16f2..498092e8ac54 100644 --- a/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt +++ b/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt @@ -156,6 +156,7 @@ string(0) "" *** Trying int(9223372036854775807) string(19) "9223372036854775807" *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to string on line %d string(3) "NAN" *** Trying bool(true) string(1) "1" @@ -193,6 +194,7 @@ bool(false) *** Trying int(9223372036854775807) bool(true) *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to bool on line %d bool(true) *** Trying bool(true) bool(true) diff --git a/Zend/tests/type_declarations/typed_properties_113.phpt b/Zend/tests/type_declarations/typed_properties_113.phpt index cb5c0f927645..0aecc76f758a 100644 --- a/Zend/tests/type_declarations/typed_properties_113.phpt +++ b/Zend/tests/type_declarations/typed_properties_113.phpt @@ -19,7 +19,8 @@ foreach ($obj as $k => &$v) { var_dump($obj); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d object(A)#1 (1) { ["foo"]=> &string(2) "42" diff --git a/Zend/tests/type_declarations/typed_properties_114.phpt b/Zend/tests/type_declarations/typed_properties_114.phpt index e771f4c1c1f8..5f3093dd3308 100644 --- a/Zend/tests/type_declarations/typed_properties_114.phpt +++ b/Zend/tests/type_declarations/typed_properties_114.phpt @@ -30,8 +30,11 @@ foreach ($obj as $k => &$v) { var_dump($obj); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Cannot assign array to reference held by property A::$foo of type string + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Cannot assign array to reference held by property A::$foo of type string object(A)#1 (1) { ["foo"]=> diff --git a/Zend/tests/type_declarations/typed_properties_115.phpt b/Zend/tests/type_declarations/typed_properties_115.phpt index eb96b3ee8864..6347ee0c35d6 100644 --- a/Zend/tests/type_declarations/typed_properties_115.phpt +++ b/Zend/tests/type_declarations/typed_properties_115.phpt @@ -22,7 +22,8 @@ try { var_dump($obj); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Cannot acquire reference to readonly property A::$foo object(A)#1 (1) { ["foo"]=> diff --git a/Zend/tests/033.phpt b/Zend/tests/undefined_multidimensional_array.phpt similarity index 100% rename from Zend/tests/033.phpt rename to Zend/tests/undefined_multidimensional_array.phpt diff --git a/Zend/tests/024.phpt b/Zend/tests/undefined_variables_operations.phpt similarity index 100% rename from Zend/tests/024.phpt rename to Zend/tests/undefined_variables_operations.phpt diff --git a/Zend/tests/unified_arg_infos_001.phpt b/Zend/tests/unified_arg_infos_001.phpt new file mode 100644 index 000000000000..d6699aa8d8cb --- /dev/null +++ b/Zend/tests/unified_arg_infos_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +Declaring non persistent method with arg info +--EXTENSIONS-- +zend_test +--FILE-- +testTmpMethodWithArgInfo(null); + +echo new ReflectionFunction($o->testTmpMethodWithArgInfo(...)); + +?> +--EXPECT-- +Closure [ public method testTmpMethodWithArgInfo ] { + + - Parameters [2] { + Parameter #0 [ Foo|Bar|null $tmpMethodParamName = null ] + Parameter #1 [ string $tmpMethodParamWithStringDefaultValue = "tmpMethodParamWithStringDefaultValue" ] + } +} diff --git a/Zend/tests/unset_empty_isset_comprehensive.phpt b/Zend/tests/unset_empty_isset_comprehensive.phpt new file mode 100644 index 000000000000..9a1aad99aa69 --- /dev/null +++ b/Zend/tests/unset_empty_isset_comprehensive.phpt @@ -0,0 +1,1441 @@ +--TEST-- +Test unset(), empty() and isset() functions +--FILE-- + "One", 2 => "two"), + array("Name" => "Jack", "Age" => "30"), + array(1,2, "One" => "1", 2 => "two", ""=>"empty", "" => '') +); + +$outer_loop_counter = 1; +foreach ($array_variables as $array_var) { + echo "--- Outerloop Iteration $outer_loop_counter ---\n"; + + // check the isset and unset on non existing key + $var = 1; // a var which is defined + // try to unset the element which is non-existent + unset($array_var['non_existent']); + // check using isset() & empty() on a non_existent element in the array + var_dump( isset($array_var['non_existent']) ); + var_dump( isset($array_var['non_existent'], $var) ); + var_dump( isset($array_var['non_existent'], $array_var['none']) ); + var_dump( empty($array_var['non_existent']) ); + + // testing empty and isset on arrays + var_dump( empty($array_var) ); // expecting bool(false), except: array(), which is considered empty + var_dump( isset($array_var) ); // expecting bool(true), except: array(), which is not set + + // get the keys of the $array_var + $keys = array_keys($array_var); + // unset each element in the array and see the working of unset, isset & empty + $inner_loop_counter = 1; + foreach ($keys as $key_value) { + echo "-- Innerloop Iteration $inner_loop_counter of Outerloop Iteration $outer_loop_counter --\n"; + $inner_loop_counter++; + + // unset the element + unset($array_var[$key_value]); + // dump the array after element was unset + var_dump($array_var); + // check using isset for the element that was unset + var_dump( isset($array_var[$key_val]) ); // expected: bool(false) + // calling isset with more args + var_dump( isset($array_var[$key_val], $array_var) ); //expected: bool(false) + + // calling empty, expected bool(true) + var_dump( empty($array_var[$key_val]) ); + + // dump the array to see that that array did not get modified + // because of using isset, empty and unset on its element + var_dump($array_var); + } + + $outer_loop_counter++; + + // unset the whole array + unset($array_var); + // dump the array to see its unset + var_dump($array_var); + // use isset to see that array is not set + var_dump( isset($array_var) ); //expected: bool(false) + var_dump( isset($array_var, $array_var[$key_val]) ); // expected: bool(false) + + // empty() to see if the array is empty + var_dump( empty($array_var) ); // expected: bool(true) +} + +echo "\n*** Testing unset(), empty() & isset() with resource variables ***\n"; +$fp = fopen(__FILE__, "r"); +$dfp = opendir( __DIR__ ); +$resources = array ( + $fp, + $dfp +); +$loop_counter = 1; +foreach ($resources as $resource) { + $temp_var = 10; + echo "-- Iteration $loop_counter --\n"; $loop_counter++; + //dump the resource first + var_dump($resource); + + // check using isset() and empty() + var_dump( isset($resource) ); // expected: bool(true) + var_dump( empty($resource) ); // expected: bool(false) + // call isset() with two args, both set + var_dump( isset($resource, $temp_var) ); // expected: bool(true) + + // dump the resource to see using isset() and empty () had no effect on it + var_dump($resource); + + // unset the resource + unset($resource); + // check using isset() and empty() + var_dump( isset($resource) ); // expected: bool(false) + var_dump( empty($resource) ); // expected: bool(true) + // call isset() with two args, but one set + var_dump( isset($resource, $temp_var) ); // expected: bool(false) + // unset the temp_var + unset($temp_var); + // now the isset() with both the args as unset + var_dump( isset($resource, $temp_var) ); // expected: bool(false); + + // dump the resource to see if there any effect on it + var_dump($resource); +} +// unset and dump the array containing all the resources to see that +// unset works correctly +unset($resources); +var_dump($resources); +var_dump( isset($resources) ); //expected: bool(false) +var_dump( empty($resources) ); // expected: bool(true) + +echo "\n*** Testing unset(), empty() & isset() with objects ***\n"; +class Point +{ + var $x; + var $y; + var $lable; + + function __construct($x, $y) { + $this->x = $x; + $this->y = $y; + } + + function setLable($lable) { + $this->lable = $lable; + } + function testPoint() { + echo "\nPoint::testPoint() called\n"; + } +} +$point1 = new Point(30,40); + +// use unset/empty/isset to check the object +var_dump($point1); // dump the object + +// check the object and member that is not set +var_dump( isset($point1) ); // expected: bool(true) +var_dump( empty($point1) ); // expected: bool(false) +var_dump( isset($point1->$lable) ); //expected: bool(false) +var_dump( empty($point1->$lable) ); //expected: bool(true) + +//set the member variable lable and check +$point1->setLable("Point1"); +var_dump( isset($point1->$lable) ); //expected: bool(true) +var_dump( empty($point1->$lable) ); //expected: bool(false) + +// dump the object to see that obj was not harmed +// because of the usage of the isset & empty +var_dump($point1); + +//unset a member and check +unset($point1->x); +// dump the point to see that variable was unset +var_dump($point1); +var_dump( isset($point1->x) ); // expected: bool(false) +var_dump( empty($point1->x) ); // expected: bool(true) + +// unset all members and check +unset($point1->y); +unset($point1->lable); +// dump the object to check that all variables are unset +var_dump($point1); +var_dump( isset($point1) ); // expected: bool(ture) +var_dump( empty($point1) ); // expected: bool(false) + +//unset the object and check +unset($point1); +var_dump( isset($point1) ); // expected: bool(false) +var_dump( empty($point1) ); // expected: bool(true) +// dump to see that object is unset +var_dump($point1); + +// try isset/unset/empty on a member function +$point2 = new Point(5,6); +var_dump( isset($point2->testPoint) ); +var_dump( empty($point2->testPoint) ); +unset($point2->testPoint); +var_dump( isset($point2->testPoint) ); +var_dump( empty($point2->testPoint) ); + +// use get_class_methods to see effect if any +var_dump( get_class_methods($point2) ); +// dump the object to see the effect, none expected +var_dump($point2); + +/* testing variation in operation for isset(), empty() & unset(). +Note: Most of the variation for function unset() is testing by a + set of testcases named "Zend/tests/unset_cv??.phpt", only + variation not tested are attempted here */ + +echo "\n*** Testing possible variation in operation for isset(), empty() & unset() ***\n"; +/* unset() variation1: checking unset on static variable inside a function. + * unset() destroys the variable only in the context of the rest of a function + * Following calls will restore the previous value of a variable. + */ +echo "\n** Testing unset() variation 1: unset on static variable inside a function **\n"; +function test_unset1() { + static $static_var; + + // increment the value of the static. this change is in function context + $static_var ++; + + echo "value of static_var before unset: $static_var\n"; + // check using isset and empty + var_dump( isset($static_var) ); + var_dump( empty($static_var) ); + + // unset the static var + unset($static_var); + echo "value of static_var after unset: $static_var\n"; + // check using isset and empty + var_dump( isset($static_var) ); + var_dump( empty($static_var) ); + + // assign a value to static var + $static_var = 20; + echo "value of static_var after new assignment: $static_var\n"; +} +// call the function +test_unset1(); +test_unset1(); +test_unset1(); + + +echo "\n** Testing unset() variation 2: unset on a variable passed by ref. inside of a function **\n"; +/* unset() variation2: Pass by reference + * If a variable that is PASSED BY REFERENCE is unset() inside of a function, + * only the local variable is destroyed. The variable in the calling environment + * will retain the same value as before unset() was called. + */ +function test_unset2( &$ref_val ) { + // unset the variable passed + unset($ref_val); + // check using isset and empty to confirm + var_dump( isset($ref_val) ); + var_dump( empty($ref_val) ); + + // set the value ot a new one + $ref_val = "new value by ref"; +} + +$value = "value"; +var_dump($value); +test_unset2($value); +var_dump($value); + + +echo "\n** Testing unset() variation 3: unset on a global variable inside of a function **\n"; +/* unset() variation2: unset on a global variable inside a function + * If a globalized variable is unset() inside of a function, only the + * local variable is destroyed. The variable in the calling environment + * will retain the same value as before unset() was called. + */ +$global_var = 10; + +function test_unset3() { + global $global_var; + + // check the $global_var using isset and empty + var_dump( isset($global_var) ); + var_dump( empty($global_var) ); + + // unset the global var + unset($global_var); + + // check the $global_var using isset and empty + var_dump( isset($global_var) ); + var_dump( empty($global_var) ); +} + +var_dump($global_var); +test_unset3(); +var_dump($global_var); + +//Note: No error conditions relating to passing arguments can be tested +// because these are not functions but statements, it will result in syntax error. +?> +--EXPECTF-- +*** Testing unset(), empty() & isset() with scalar variables *** +-- Iteration 1 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 2 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 3 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 4 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 5 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 6 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 7 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 8 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 9 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 10 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 11 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 12 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 13 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 14 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 15 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 16 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 17 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 18 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 19 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 20 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 21 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 22 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 23 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 24 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 25 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 26 -- +bool(true) +bool(true) +bool(false) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +-- Iteration 27 -- +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $scalar_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) + +*** Testing unset(), empty() & isset() with arrays *** +--- Outerloop Iteration 1 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) +bool(true) + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 2 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 2 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 3 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 3 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 4 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 4 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 5 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 5 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 6 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 6 -- +array(3) { + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(3) { + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} +-- Innerloop Iteration 2 of Outerloop Iteration 6 -- +array(2) { + [2]=> + int(3) + [3]=> + int(4) +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(2) { + [2]=> + int(3) + [3]=> + int(4) +} +-- Innerloop Iteration 3 of Outerloop Iteration 6 -- +array(1) { + [3]=> + int(4) +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(1) { + [3]=> + int(4) +} +-- Innerloop Iteration 4 of Outerloop Iteration 6 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 7 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 7 -- +array(2) { + [1]=> + float(2.5) + [2]=> + float(5.6) +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(2) { + [1]=> + float(2.5) + [2]=> + float(5.6) +} +-- Innerloop Iteration 2 of Outerloop Iteration 7 -- +array(1) { + [2]=> + float(5.6) +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(1) { + [2]=> + float(5.6) +} +-- Innerloop Iteration 3 of Outerloop Iteration 7 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 8 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 8 -- +array(1) { + [2]=> + string(3) "two" +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(1) { + [2]=> + string(3) "two" +} +-- Innerloop Iteration 2 of Outerloop Iteration 8 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 9 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 9 -- +array(1) { + ["Age"]=> + string(2) "30" +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(1) { + ["Age"]=> + string(2) "30" +} +-- Innerloop Iteration 2 of Outerloop Iteration 9 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) +--- Outerloop Iteration 10 --- +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +-- Innerloop Iteration 1 of Outerloop Iteration 10 -- +array(4) { + [1]=> + int(2) + ["One"]=> + string(1) "1" + [2]=> + string(3) "two" + [""]=> + string(0) "" +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(4) { + [1]=> + int(2) + ["One"]=> + string(1) "1" + [2]=> + string(3) "two" + [""]=> + string(0) "" +} +-- Innerloop Iteration 2 of Outerloop Iteration 10 -- +array(3) { + ["One"]=> + string(1) "1" + [2]=> + string(3) "two" + [""]=> + string(0) "" +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(3) { + ["One"]=> + string(1) "1" + [2]=> + string(3) "two" + [""]=> + string(0) "" +} +-- Innerloop Iteration 3 of Outerloop Iteration 10 -- +array(2) { + [2]=> + string(3) "two" + [""]=> + string(0) "" +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(2) { + [2]=> + string(3) "two" + [""]=> + string(0) "" +} +-- Innerloop Iteration 4 of Outerloop Iteration 10 -- +array(1) { + [""]=> + string(0) "" +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(1) { + [""]=> + string(0) "" +} +-- Innerloop Iteration 5 of Outerloop Iteration 10 -- +array(0) { +} + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(false) + +Warning: Undefined variable $key_val in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +bool(true) +array(0) { +} + +Warning: Undefined variable $array_var in %s on line %d +NULL +bool(false) +bool(false) +bool(true) + +*** Testing unset(), empty() & isset() with resource variables *** +-- Iteration 1 -- +resource(5) of type (stream) +bool(true) +bool(false) +bool(true) +resource(5) of type (stream) +bool(false) +bool(true) +bool(false) +bool(false) + +Warning: Undefined variable $resource in %s on line %d +NULL +-- Iteration 2 -- +resource(6) of type (stream) +bool(true) +bool(false) +bool(true) +resource(6) of type (stream) +bool(false) +bool(true) +bool(false) +bool(false) + +Warning: Undefined variable $resource in %s on line %d +NULL + +Warning: Undefined variable $resources in %s on line %d +NULL +bool(false) +bool(true) + +*** Testing unset(), empty() & isset() with objects *** +object(Point)#1 (3) { + ["x"]=> + int(30) + ["y"]=> + int(40) + ["lable"]=> + NULL +} +bool(true) +bool(false) + +Warning: Undefined variable $lable in %s on line %d +bool(false) + +Warning: Undefined variable $lable in %s on line %d +bool(true) + +Warning: Undefined variable $lable in %s on line %d +bool(false) + +Warning: Undefined variable $lable in %s on line %d +bool(true) +object(Point)#1 (3) { + ["x"]=> + int(30) + ["y"]=> + int(40) + ["lable"]=> + string(6) "Point1" +} +object(Point)#1 (2) { + ["y"]=> + int(40) + ["lable"]=> + string(6) "Point1" +} +bool(false) +bool(true) +object(Point)#1 (0) { +} +bool(true) +bool(false) +bool(false) +bool(true) + +Warning: Undefined variable $point1 in %s on line %d +NULL +bool(false) +bool(true) +bool(false) +bool(true) +array(3) { + [0]=> + string(11) "__construct" + [1]=> + string(8) "setLable" + [2]=> + string(9) "testPoint" +} +object(Point)#1 (3) { + ["x"]=> + int(5) + ["y"]=> + int(6) + ["lable"]=> + NULL +} + +*** Testing possible variation in operation for isset(), empty() & unset() *** + +** Testing unset() variation 1: unset on static variable inside a function ** +value of static_var before unset: 1 +bool(true) +bool(false) + +Warning: Undefined variable $static_var in %s on line %d +value of static_var after unset: +bool(false) +bool(true) +value of static_var after new assignment: 20 +value of static_var before unset: 2 +bool(true) +bool(false) + +Warning: Undefined variable $static_var in %s on line %d +value of static_var after unset: +bool(false) +bool(true) +value of static_var after new assignment: 20 +value of static_var before unset: 3 +bool(true) +bool(false) + +Warning: Undefined variable $static_var in %s on line %d +value of static_var after unset: +bool(false) +bool(true) +value of static_var after new assignment: 20 + +** Testing unset() variation 2: unset on a variable passed by ref. inside of a function ** +string(5) "value" +bool(false) +bool(true) +string(5) "value" + +** Testing unset() variation 3: unset on a global variable inside of a function ** +int(10) +bool(true) +bool(false) +bool(false) +bool(true) +int(10) diff --git a/Zend/tests/vm_kind_tailcall_clang_windows.phpt b/Zend/tests/vm_kind_tailcall_clang_windows.phpt new file mode 100644 index 000000000000..f66a17ae0daf --- /dev/null +++ b/Zend/tests/vm_kind_tailcall_clang_windows.phpt @@ -0,0 +1,25 @@ +--TEST-- +Tailcall VM is selected when compiled with Clang >= 19 on Windows x64 +--SKIPIF-- + clang version (\d+)/', $info, $m)) { + die('skip not compiled with clang'); +} + +if ((int)$m[1] < 19) { + die('skip requires clang >= 19'); +} +?> +--FILE-- + +--EXPECT-- +string(21) "ZEND_VM_KIND_TAILCALL" diff --git a/Zend/tests/weakrefs/gh20073.phpt b/Zend/tests/weakrefs/gh20073.phpt new file mode 100644 index 000000000000..b64c1a68d3cc --- /dev/null +++ b/Zend/tests/weakrefs/gh20073.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-20073 (Assertion failure in WeakMap offset operations on reference) +--FILE-- +offsetGet($obj)); +?> +--EXPECT-- +int(2) +int(2) diff --git a/Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt b/Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt new file mode 100644 index 000000000000..6444de7eea6b --- /dev/null +++ b/Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt @@ -0,0 +1,13 @@ +--TEST-- +By-ref assign of WeakMap dimension +--FILE-- + +--EXPECT-- +int(1) diff --git a/Zend/tests/zend_ini/oss_fuzz_428983568.phpt b/Zend/tests/zend_ini/oss_fuzz_428983568.phpt new file mode 100644 index 000000000000..80310fbd9287 --- /dev/null +++ b/Zend/tests/zend_ini/oss_fuzz_428983568.phpt @@ -0,0 +1,14 @@ +--TEST-- +OSS-Fuzz #428983568 +--FILE-- + +--EXPECTF-- +Warning: syntax error, unexpected end of file, expecting '}' in Unknown on line 1 + in %s on line %d +bool(false) diff --git a/Zend/zend.c b/Zend/zend.c index 2d8a0f455f8b..5ba3b49e49fb 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -38,6 +37,8 @@ #include "zend_call_stack.h" #include "zend_max_execution_timer.h" #include "zend_hrtime.h" +#include "zend_enum.h" +#include "zend_closures.h" #include "Optimizer/zend_optimizer.h" #include "php.h" #include "php_globals.h" @@ -76,7 +77,7 @@ ZEND_API bool zend_dtrace_enabled; /* version information */ static char *zend_version_info; static uint32_t zend_version_info_length; -#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) Zend Technologies\n" +#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright © Zend by Perforce\n" #define PRINT_ZVAL_INDENT 4 /* true multithread-shared globals */ @@ -155,7 +156,7 @@ static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */ { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); @@ -553,7 +554,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* } GC_PROTECT_RECURSION(Z_ARRVAL_P(expr)); } - print_hash(buf, Z_ARRVAL_P(expr), indent, 0); + print_hash(buf, Z_ARRVAL_P(expr), indent, false); GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr)); break; case IS_OBJECT: @@ -563,6 +564,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* zend_object *zobj = Z_OBJ_P(expr); uint32_t *guard = zend_get_recursion_guard(zobj); zend_string *class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(zobj); + /* cut off on NULL byte ... class@anonymous */ smart_str_appends(buf, ZSTR_VAL(class_name)); zend_string_release_ex(class_name, 0); @@ -583,12 +585,12 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* } if ((properties = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_DEBUG)) == NULL) { - print_hash(buf, (HashTable*) &zend_empty_array, indent, 1); + print_hash(buf, (HashTable*) &zend_empty_array, indent, true); break; } ZEND_GUARD_OR_GC_PROTECT_RECURSION(guard, DEBUG, zobj); - print_hash(buf, properties, indent, 1); + print_hash(buf, properties, indent, true); ZEND_GUARD_OR_GC_UNPROTECT_RECURSION(guard, DEBUG, zobj); zend_release_properties(properties); @@ -641,7 +643,7 @@ static FILE *zend_fopen_wrapper(zend_string *filename, zend_string **opened_path /* }}} */ #ifdef ZTS -static bool short_tags_default = 1; +static bool short_tags_default = true; static uint32_t compiler_options_default = ZEND_COMPILE_DEFAULT; #else # define short_tags_default 1 @@ -809,7 +811,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{ executor_globals->user_error_handler_error_reporting = 0; ZVAL_UNDEF(&executor_globals->user_error_handler); ZVAL_UNDEF(&executor_globals->user_exception_handler); - executor_globals->in_autoload = NULL; + ZVAL_UNDEF(&executor_globals->last_fatal_error_backtrace); executor_globals->current_execute_data = NULL; executor_globals->current_module = NULL; executor_globals->exit_status = 0; @@ -817,7 +819,8 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{ executor_globals->saved_fpu_cw = 0; #endif executor_globals->saved_fpu_cw_ptr = NULL; - executor_globals->active = 0; + executor_globals->active = false; + executor_globals->monomorph_synthesis_active = false; executor_globals->bailout = NULL; executor_globals->error_handling = EH_NORMAL; executor_globals->exception_class = NULL; @@ -831,8 +834,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{ #endif executor_globals->flags = EG_FLAGS_INITIAL; executor_globals->record_errors = false; - executor_globals->num_errors = 0; - executor_globals->errors = NULL; + memset(&executor_globals->errors, 0, sizeof(executor_globals->errors)); executor_globals->filename_override = NULL; executor_globals->lineno_override = -1; #ifdef ZEND_CHECK_STACK_LIMIT @@ -910,7 +912,7 @@ static bool php_auto_globals_create_globals(zend_string *name) /* {{{ */ { /* While we keep registering $GLOBALS as an auto-global, we do not create an * actual variable for it. Access to it handled specially by the compiler. */ - return 0; + return false; } /* }}} */ @@ -1026,7 +1028,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ executor_globals = ts_resource(executor_globals_id); compiler_globals_dtor(compiler_globals); - compiler_globals->in_compilation = 0; + compiler_globals->in_compilation = false; compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable)); compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable)); @@ -1054,6 +1056,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ ZVAL_UNDEF(&EG(last_fatal_error_backtrace)); zend_interned_strings_init(); + zend_object_handlers_startup(); zend_startup_builtin_functions(); zend_register_standard_constants(); zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals); @@ -1077,6 +1080,8 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ tsrm_set_new_thread_end_handler(zend_new_thread_end_handler); tsrm_set_shutdown_handler(zend_interned_strings_dtor); #endif + + zend_enum_startup(); } /* }}} */ @@ -1275,9 +1280,10 @@ ZEND_API size_t zend_get_page_size(void) SYSTEM_INFO system_info; GetSystemInfo(&system_info); return system_info.dwPageSize; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__APPLE__) /* This returns the value obtained from - * the auxv vector, avoiding a syscall. */ + * the auxv vector, avoiding a + * syscall (on FreeBSD)/function call (on macOS). */ return getpagesize(); #else return (size_t) sysconf(_SC_PAGESIZE); @@ -1299,7 +1305,7 @@ ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ * snprintf(new_info, new_info_length, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author); - zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length + 1); + zend_version_info = (char *) perealloc(zend_version_info, zend_version_info_length+new_info_length + 1, true); strncat(zend_version_info, new_info, new_info_length); zend_version_info_length += new_info_length; free(new_info); @@ -1440,8 +1446,7 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( zend_stack delayed_oplines_stack; int type = orig_type & E_ALL; bool orig_record_errors; - uint32_t orig_num_errors; - zend_error_info **orig_errors; + zend_err_buf orig_errors_buf; zend_result res; /* If we're executing a function during SCCP, count any warnings that may be emitted, @@ -1452,18 +1457,44 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( return; } + /* Emit any delayed error before handling fatal error */ + if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(errors).size) { + zend_err_buf errors_buf = EG(errors); + EG(errors).size = 0; + + bool orig_record_errors = EG(record_errors); + EG(record_errors) = false; + + /* Disable user error handler before emitting delayed errors, as + * it's unsafe to execute user code after a fatal error. */ + int orig_user_error_handler_error_reporting = EG(user_error_handler_error_reporting); + EG(user_error_handler_error_reporting) = 0; + + zend_emit_recorded_errors_ex(errors_buf.size, errors_buf.errors); + + EG(user_error_handler_error_reporting) = orig_user_error_handler_error_reporting; + EG(record_errors) = orig_record_errors; + EG(errors) = errors_buf; + } + if (EG(record_errors)) { zend_error_info *info = emalloc(sizeof(zend_error_info)); info->type = type; info->lineno = error_lineno; info->filename = zend_string_copy(error_filename); info->message = zend_string_copy(message); + EG(errors).size++; + if (EG(errors).size > EG(errors).capacity) { + uint32_t capacity = EG(errors).capacity ? EG(errors).capacity + (EG(errors).capacity >> 1) : 2; + EG(errors).errors = erealloc(EG(errors).errors, sizeof(zend_error_info *) * capacity); + EG(errors).capacity = capacity; + } + EG(errors).errors[EG(errors).size - 1] = info; - /* This is very inefficient for a large number of errors. - * Use pow2 realloc if it becomes a problem. */ - EG(num_errors)++; - EG(errors) = erealloc(EG(errors), sizeof(zend_error_info*) * EG(num_errors)); - EG(errors)[EG(num_errors)-1] = info; + /* Do not process non-fatal recorded error */ + if (!(type & E_FATAL_ERRORS) || (type & E_DONT_BAIL)) { + return; + } } // Always clear the last backtrace. @@ -1472,12 +1503,10 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( /* Report about uncaught exception in case of fatal errors */ if (EG(exception)) { - zend_execute_data *ex; - const zend_op *opline; - if (type & E_FATAL_ERRORS) { - ex = EG(current_execute_data); - opline = NULL; + zend_execute_data *ex = EG(current_execute_data); + const zend_op *opline = NULL; + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { ex = ex->prev_execute_data; } @@ -1543,17 +1572,15 @@ ZEND_API ZEND_COLD void zend_error_zstr_at( } orig_record_errors = EG(record_errors); - orig_num_errors = EG(num_errors); - orig_errors = EG(errors); EG(record_errors) = false; - EG(num_errors) = 0; - EG(errors) = NULL; + + orig_errors_buf = EG(errors); + memset(&EG(errors), 0, sizeof(EG(errors))); res = call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params); EG(record_errors) = orig_record_errors; - EG(num_errors) = orig_num_errors; - EG(errors) = orig_errors; + EG(errors) = orig_errors_buf; if (res == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { @@ -1748,34 +1775,37 @@ ZEND_API void zend_begin_record_errors(void) { ZEND_ASSERT(!EG(record_errors) && "Error recording already enabled"); EG(record_errors) = true; - EG(num_errors) = 0; - EG(errors) = NULL; + EG(errors).size = 0; } -ZEND_API void zend_emit_recorded_errors(void) +ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info **errors) { - EG(record_errors) = false; - for (uint32_t i = 0; i < EG(num_errors); i++) { - zend_error_info *error = EG(errors)[i]; + for (uint32_t i = 0; i < num_errors; i++) { + zend_error_info *error = errors[i]; zend_error_zstr_at(error->type, error->filename, error->lineno, error->message); } } +ZEND_API void zend_emit_recorded_errors(void) +{ + EG(record_errors) = false; + zend_emit_recorded_errors_ex(EG(errors).size, EG(errors).errors); +} + ZEND_API void zend_free_recorded_errors(void) { - if (!EG(num_errors)) { + if (!EG(errors).size) { return; } - for (uint32_t i = 0; i < EG(num_errors); i++) { - zend_error_info *info = EG(errors)[i]; + for (uint32_t i = 0; i < EG(errors).size; i++) { + zend_error_info *info = EG(errors).errors[i]; zend_string_release(info->filename); zend_string_release(info->message); - efree(info); + efree_size(info, sizeof(zend_error_info)); } - efree(EG(errors)); - EG(errors) = NULL; - EG(num_errors) = 0; + efree(EG(errors).errors); + memset(&EG(errors), 0, sizeof(EG(errors))); } ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */ @@ -1941,7 +1971,6 @@ ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handl zend_result ret = SUCCESS; if (op_array) { zend_execute(op_array, retval); - zend_exception_restore(); if (UNEXPECTED(EG(exception))) { if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { zend_user_exception_handler(); diff --git a/Zend/zend.h b/Zend/zend.h index 0cf1faeb653f..509dcc593577 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -20,7 +19,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.5.0-dev" +#define ZEND_VERSION "4.6.0-dev" #define ZEND_ENGINE_3 @@ -144,19 +143,25 @@ struct _zend_inheritance_cache_entry { zend_class_entry *traits_and_interfaces[1]; }; +C23_ENUM(zend_class_type, uint8_t) { + ZEND_INTERNAL_CLASS = 1, + ZEND_USER_CLASS = 2, +}; + struct _zend_class_entry { - char type; + zend_class_type type; zend_string *name; /* class_entry or string depending on ZEND_ACC_LINKED */ union { zend_class_entry *parent; zend_string *parent_name; }; - int refcount; + uint32_t refcount; uint32_t ce_flags; + uint32_t ce_flags2; int default_properties_count; - int default_static_members_count; + uint32_t default_static_members_count; zval *default_properties_table; zval *default_static_members_table; ZEND_MAP_PTR_DEF(zval *, static_members_table); @@ -223,6 +228,10 @@ struct _zend_class_entry { zend_string *doc_comment; + struct _zend_generic_parameter_list *generic_parameters; + struct _zend_generic_type_table *generic_types; + struct _zend_type_arg_table *generic_type_args; /* bindings on a monomorph; NULL on bases */ + union { struct { zend_string *filename; @@ -275,7 +284,9 @@ typedef size_t (*zend_write_func_t)(const char *str, size_t str_length); EG(bailout) = &__bailout; \ if (SETJMP(__bailout)==0) { #define zend_catch \ + ZEND_ASSERT(EG(bailout) == &__bailout); \ } else { \ + ZEND_ASSERT(EG(bailout) == &__bailout); \ EG(bailout) = __orig_bailout; #define zend_end_try() \ } \ @@ -441,9 +452,10 @@ typedef struct { BEGIN_EXTERN_C() ZEND_API void zend_save_error_handling(zend_error_handling *current); ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current); -ZEND_API void zend_restore_error_handling(zend_error_handling *saved); +ZEND_API void zend_restore_error_handling(const zend_error_handling *saved); ZEND_API void zend_begin_record_errors(void); ZEND_API void zend_emit_recorded_errors(void); +ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info **errors); ZEND_API void zend_free_recorded_errors(void); END_EXTERN_C() diff --git a/Zend/zend_API.c b/Zend/zend_API.c index e0006e7d7275..65834adbafff 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -20,6 +19,7 @@ */ #include "zend.h" +#include "zend_compile.h" #include "zend_execute.h" #include "zend_API.h" #include "zend_hash.h" @@ -40,6 +40,8 @@ /* these variables are true statics/globals, and have to be mutex'ed on every access */ ZEND_API HashTable module_registry; +ZEND_API bool zend_dl_use_deepbind = false; + static zend_module_entry **module_request_startup_handlers; static zend_module_entry **module_request_shutdown_handlers; static zend_module_entry **module_post_deactivate_handlers; @@ -47,29 +49,12 @@ static zend_module_entry **modules_dl_loaded; static zend_class_entry **class_cleanup_handlers; -ZEND_API zend_result zend_get_parameters_array_ex(uint32_t param_count, zval *argument_array) /* {{{ */ +ZEND_API void zend_set_dl_use_deepbind(bool use_deepbind) { - zval *param_ptr; - uint32_t arg_count; - - param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1); - arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); - - if (param_count>arg_count) { - return FAILURE; - } - - while (param_count-->0) { - ZVAL_COPY_VALUE(argument_array, param_ptr); - argument_array++; - param_ptr++; - } - - return SUCCESS; + zend_dl_use_deepbind = use_deepbind; } -/* }}} */ -ZEND_API zend_result zend_copy_parameters_array(uint32_t param_count, zval *argument_array) /* {{{ */ +ZEND_API zend_result zend_get_parameters_array_ex(uint32_t param_count, zval *argument_array) /* {{{ */ { zval *param_ptr; uint32_t arg_count; @@ -82,8 +67,8 @@ ZEND_API zend_result zend_copy_parameters_array(uint32_t param_count, zval *argu } while (param_count-->0) { - Z_TRY_ADDREF_P(param_ptr); - zend_hash_next_index_insert_new(Z_ARRVAL_P(argument_array), param_ptr); + ZVAL_COPY_VALUE(argument_array, param_ptr); + argument_array++; param_ptr++; } @@ -100,7 +85,7 @@ ZEND_API ZEND_COLD void zend_wrong_param_count(void) /* {{{ */ } /* }}} */ -ZEND_API ZEND_COLD void zend_wrong_property_read(zval *object, zval *property) +ZEND_API ZEND_COLD void zend_wrong_property_read(const zval *object, zval *property) { zend_string *tmp_property_name; zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); @@ -140,7 +125,7 @@ ZEND_API const char *zend_get_type_by_const(int type) /* {{{ */ return "mixed"; case _IS_NUMBER: return "int|float"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -240,7 +225,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(uint32_t } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, uint32_t num, char *name, zend_expected_type expected_type, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, uint32_t num, char *name, zend_expected_type expected_type, const zval *arg) /* {{{ */ { switch (error_code) { case ZPP_ERROR_WRONG_CALLBACK: @@ -276,12 +261,12 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, case ZPP_ERROR_FAILURE: ZEND_ASSERT(EG(exception) && "Should have produced an error already"); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, const zval *arg) /* {{{ */ { static const char * const expected_error[] = { Z_EXPECTED_TYPES(Z_EXPECTED_TYPE_STR) @@ -302,7 +287,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t n } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, const zval *arg) /* {{{ */ { if (EG(exception)) { return; @@ -312,7 +297,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, const zval *arg) /* {{{ */ { if (EG(exception)) { return; @@ -322,7 +307,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(u } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, const zval *arg) /* {{{ */ { if (EG(exception)) { return; @@ -332,7 +317,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(u } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, const zval *arg) /* {{{ */ { if (EG(exception)) { return; @@ -342,7 +327,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, const zval *arg) /* {{{ */ { if (EG(exception)) { return; @@ -352,7 +337,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_null_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_null_error(uint32_t num, const char *name, const zval *arg) /* {{{ */ { if (EG(exception)) { return; @@ -384,8 +369,9 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void) { const char *space; const char *class_name = get_active_class_name(&space); - zend_argument_count_error("%s%s%s() does not accept unknown named parameters", - class_name, space, get_active_function_name()); + zend_argument_count_error("Internal function %s%s%s() does not accept named variadic arguments", + class_name, space, get_active_function_name() + ); } ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va) /* {{{ */ @@ -445,7 +431,7 @@ ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num) zend_argument_value_error(arg_num, "must not be empty"); } -ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce) +ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, const zend_class_entry *old_ce) { if (old_ce->type == ZEND_INTERNAL_CLASS) { zend_error(type, "Cannot redeclare %s %s", @@ -460,7 +446,7 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string } } -ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, zend_class_entry *old_ce) +ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, const zend_class_entry *old_ce) { zend_class_redeclaration_error_ex(type, old_ce->name, old_ce); } @@ -495,7 +481,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **p /* }}} */ static ZEND_COLD bool zend_null_arg_deprecated(const char *fallback_type, uint32_t arg_num) { - zend_function *func = zend_active_function(); + const zend_function *func = zend_active_function(); ZEND_ASSERT(arg_num > 0); uint32_t arg_offset = arg_num - 1; if (arg_offset >= func->common.num_args) { @@ -503,7 +489,7 @@ static ZEND_COLD bool zend_null_arg_deprecated(const char *fallback_type, uint32 arg_offset = func->common.num_args; } - zend_arg_info *arg_info = &func->common.arg_info[arg_offset]; + const zend_arg_info *arg_info = &func->common.arg_info[arg_offset]; zend_string *func_name = get_active_function_or_method_name(); const char *arg_name = get_active_function_arg_name(arg_num); @@ -523,35 +509,33 @@ static ZEND_COLD bool zend_null_arg_deprecated(const char *fallback_type, uint32 return !EG(exception); } -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */ +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) { if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("bool", arg_num)) { - return 0; + return ZPP_PARSE_BOOL_STATUS_ERROR; } - *dest = zend_is_true(arg); - } else { - return 0; + return zend_is_true(arg); } - return 1; + return ZPP_PARSE_BOOL_STATUS_ERROR; } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num) /* {{{ */ +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num) /* {{{ */ { if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { - return 0; + return ZPP_PARSE_BOOL_STATUS_ERROR; } - return zend_parse_arg_bool_weak(arg, dest, arg_num); + return zend_parse_arg_bool_weak(arg, arg_num); } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num) +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num) { if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) { - return 0; + return ZPP_PARSE_BOOL_STATUS_ERROR; } - return zend_parse_arg_bool_weak(arg, dest, arg_num); + return zend_parse_arg_bool_weak(arg, arg_num); } ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num) /* {{{ */ @@ -607,9 +591,6 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long return 0; } } - if (UNEXPECTED(EG(exception))) { - return 0; - } } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("int", arg_num)) { return 0; @@ -641,47 +622,46 @@ ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_l return zend_parse_arg_long_weak(arg, dest, arg_num); } -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */ +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { - *dest = (double)Z_LVAL_P(arg); + return (double)Z_LVAL_P(arg); } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { zend_long l; + double dval; uint8_t type; - if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) { + if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, &dval)) != IS_DOUBLE)) { if (EXPECTED(type != 0)) { - *dest = (double)(l); + return (double)(l); } else { - return 0; + return NAN; } - } - if (UNEXPECTED(EG(exception))) { - return 0; + } else { + return dval; } } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("float", arg_num)) { - return 0; + return NAN; } - *dest = 0.0; + return 0.0; } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { - *dest = 1.0; + return 1.0; } else { - return 0; + return NAN; } - return 1; } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num) /* {{{ */ +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { /* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */ - *dest = (double)Z_LVAL_P(arg); + return (double)Z_LVAL_P(arg); } else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { - return 0; + return NAN; } - return zend_parse_arg_double_weak(arg, dest, arg_num); + return zend_parse_arg_double_weak(arg, arg_num); } /* }}} */ @@ -748,58 +728,58 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval ** return true; } -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */ +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num) /* {{{ */ { if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) { if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("string", arg_num)) { - return 0; + return NULL; } convert_to_string(arg); - *dest = Z_STR_P(arg); + return Z_STR_P(arg); } else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) { zend_object *zobj = Z_OBJ_P(arg); zval obj; if (zobj->handlers->cast_object(zobj, &obj, IS_STRING) == SUCCESS) { OBJ_RELEASE(zobj); ZVAL_COPY_VALUE(arg, &obj); - *dest = Z_STR_P(arg); - return 1; + return Z_STR_P(arg); } - return 0; + return NULL; } else { - return 0; + return NULL; } - return 1; } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */ +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num) /* {{{ */ { if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { - return 0; + return NULL; } - return zend_parse_arg_str_weak(arg, dest, arg_num); + return zend_parse_arg_str_weak(arg, arg_num); } /* }}} */ -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) +ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num) { if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) { - return 0; + return NULL; } - return zend_parse_arg_str_weak(arg, dest, arg_num); + return zend_parse_arg_str_weak(arg, arg_num); } ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num) /* {{{ */ { + zend_string *str; if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { return 0; } if (zend_parse_arg_long_weak(arg, dest_long, arg_num)) { *dest_str = NULL; return 1; - } else if (zend_parse_arg_str_weak(arg, dest_str, arg_num)) { + } else if ((str = zend_parse_arg_str_weak(arg, arg_num)) != NULL) { *dest_long = 0; + *dest_str = str; return 1; } else { return 0; @@ -811,8 +791,8 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec { const char *spec_walk = *spec; char c = *spec_walk++; - bool check_null = 0; - bool separate = 0; + bool check_null = false; + bool separate = false; zval *real_arg = arg; /* scan through modifiers */ @@ -821,9 +801,9 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec if (*spec_walk == '/') { SEPARATE_ZVAL_NOREF(arg); real_arg = arg; - separate = 1; + separate = true; } else if (*spec_walk == '!') { - check_null = 1; + check_null = true; } else { break; } @@ -1133,7 +1113,7 @@ ZEND_API zend_result zend_parse_parameter(int flags, uint32_t arg_num, zval *arg } static ZEND_COLD void zend_parse_parameters_debug_error(const char *msg) { - zend_function *active_function = EG(current_execute_data)->func; + const zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : ""; zend_error_noreturn(E_CORE_ERROR, "%s%s%s(): %s", @@ -1150,8 +1130,8 @@ static zend_result zend_parse_va_args(uint32_t num_args, const char *type_spec, uint32_t max_num_args = 0; uint32_t post_varargs = 0; zval *arg; - bool have_varargs = 0; - bool have_optional_args = 0; + bool have_varargs = false; + bool have_optional_args = false; zval **varargs = NULL; uint32_t *n_varargs = NULL; @@ -1173,7 +1153,7 @@ static zend_result zend_parse_va_args(uint32_t num_args, const char *type_spec, case '|': min_num_args = max_num_args; - have_optional_args = 1; + have_optional_args = true; break; case '/': @@ -1188,7 +1168,7 @@ static zend_result zend_parse_va_args(uint32_t num_args, const char *type_spec, "only one varargs specifier (* or +) is permitted"); return FAILURE; } - have_varargs = 1; + have_varargs = true; /* we expect at least one parameter in varargs */ if (c == '+') { max_num_args++; @@ -1389,17 +1369,18 @@ ZEND_API zend_result zend_parse_method_parameters_ex(int flags, uint32_t num_arg /* This function should be called after the constructor has been called * because it may call __set from the uninitialized object otherwise. */ -ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */ +ZEND_API void zend_merge_properties(const zval *obj, const HashTable *properties) /* {{{ */ { zend_object *zobj = Z_OBJ_P(obj); zend_object_write_property_t write_property = zobj->handlers->write_property; - zend_class_entry *old_scope = EG(fake_scope); zend_string *key; zval *value; if (HT_IS_PACKED(properties)) { return; } + + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = Z_OBJCE_P(obj); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(properties, key, value) { if (key) { @@ -1410,7 +1391,7 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */ } /* }}} */ -static zend_class_mutable_data *zend_allocate_mutable_data(zend_class_entry *class_type) /* {{{ */ +static zend_class_mutable_data *zend_allocate_mutable_data(const zend_class_entry *class_type) /* {{{ */ { zend_class_mutable_data *mutable_data; @@ -1426,7 +1407,7 @@ static zend_class_mutable_data *zend_allocate_mutable_data(zend_class_entry *cla } /* }}} */ -ZEND_API HashTable *zend_separate_class_constants_table(zend_class_entry *class_type) /* {{{ */ +ZEND_API HashTable *zend_separate_class_constants_table(const zend_class_entry *class_type) /* {{{ */ { zend_class_mutable_data *mutable_data; HashTable *constants_table; @@ -1466,7 +1447,7 @@ ZEND_API HashTable *zend_separate_class_constants_table(zend_class_entry *class_ return constants_table; } -static zend_result update_property(zval *val, zend_property_info *prop_info) { +static zend_result update_property(zval *val, const zend_property_info *prop_info) { if (ZEND_TYPE_IS_SET(prop_info->type)) { zval tmp; @@ -1512,6 +1493,9 @@ ZEND_API zend_result zend_update_class_constant(zend_class_constant *c, const ze zval_ptr_dtor(&c->value); ZVAL_COPY_VALUE(&c->value, &tmp); + /* may not return SUCCESS in case of an exception, + * should've returned FAILURE in zval_update_constant_ex! */ + ZEND_ASSERT(!EG(exception)); return SUCCESS; } @@ -1698,10 +1682,9 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti if (object->ce->default_properties_count) { zval *prop; zend_string *key; - zend_property_info *property_info; ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(properties, key, prop) { - property_info = zend_get_property_info(object->ce, key, 1); + const zend_property_info *property_info = zend_get_property_info(object->ce, key, 1); if (property_info != ZEND_WRONG_PROPERTY_INFO && property_info && (property_info->flags & ZEND_ACC_STATIC) == 0) { @@ -1725,12 +1708,12 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti } /* }}} */ -ZEND_API void object_properties_load(zend_object *object, HashTable *properties) /* {{{ */ +ZEND_API void object_properties_load(zend_object *object, const HashTable *properties) /* {{{ */ { zval *prop, tmp; zend_string *key; zend_long h; - zend_property_info *property_info; + const zend_property_info *property_info; ZEND_HASH_FOREACH_KEY_VAL(properties, h, key, prop) { if (key) { @@ -1739,7 +1722,7 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties) size_t prop_name_len; if (zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_name_len) == SUCCESS) { zend_string *pname = zend_string_init(prop_name, prop_name_len, 0); - zend_class_entry *prev_scope = EG(fake_scope); + const zend_class_entry *prev_scope = EG(fake_scope); if (class_name && class_name[0] != '*') { zend_string *cname = zend_string_init(class_name, strlen(class_name), 0); EG(fake_scope) = zend_lookup_class(cname); @@ -1758,6 +1741,14 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties) property_info && (property_info->flags & ZEND_ACC_STATIC) == 0) { zval *slot = OBJ_PROP(object, property_info->offset); + if (UNEXPECTED((property_info->flags & ZEND_ACC_READONLY) && !Z_ISUNDEF_P(slot))) { + if (Z_PROP_FLAG_P(slot) & IS_PROP_REINITABLE) { + Z_PROP_FLAG_P(slot) &= ~IS_PROP_REINITABLE; + } else { + zend_readonly_property_modification_error(property_info); + return; + } + } zval_ptr_dtor(slot); ZVAL_COPY_VALUE(slot, prop); zval_add_ref(slot); @@ -2236,9 +2227,6 @@ ZEND_API zend_result array_set_zval_key(HashTable *ht, zval *key, zval *value) / case IS_STRING: result = zend_symtable_update(ht, Z_STR_P(key), value); break; - case IS_NULL: - result = zend_hash_update(ht, ZSTR_EMPTY_ALLOC(), value); - break; case IS_RESOURCE: zend_use_resource_as_offset(key); result = zend_hash_index_update(ht, Z_RES_HANDLE_P(key), value); @@ -2255,6 +2243,13 @@ ZEND_API zend_result array_set_zval_key(HashTable *ht, zval *key, zval *value) / case IS_DOUBLE: result = zend_hash_index_update(ht, zend_dval_to_lval_safe(Z_DVAL_P(key)), value); break; + case IS_NULL: + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (UNEXPECTED(EG(exception))) { + return FAILURE; + } + result = zend_hash_update(ht, ZSTR_EMPTY_ALLOC(), value); + break; default: zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_ARRAY), key, BP_VAR_W); result = NULL; @@ -2434,8 +2429,6 @@ ZEND_API zend_result zend_startup_module_ex(zend_module_entry *module) /* {{{ */ EG(current_module) = module; if (module->module_startup_func(module->type, module->module_number)==FAILURE) { zend_error_noreturn(E_CORE_ERROR,"Unable to start %s module", module->name); - EG(current_module) = NULL; - return FAILURE; } EG(current_module) = NULL; } @@ -2511,19 +2504,19 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */ dl_loaded_count++; } } ZEND_HASH_FOREACH_END(); - module_request_startup_handlers = (zend_module_entry**)realloc( + module_request_startup_handlers = (zend_module_entry**)perealloc( module_request_startup_handlers, sizeof(zend_module_entry*) * (startup_count + 1 + shutdown_count + 1 + - post_deactivate_count + 1)); + post_deactivate_count + 1), true); module_request_startup_handlers[startup_count] = NULL; module_request_shutdown_handlers = module_request_startup_handlers + startup_count + 1; module_request_shutdown_handlers[shutdown_count] = NULL; module_post_deactivate_handlers = module_request_shutdown_handlers + shutdown_count + 1; module_post_deactivate_handlers[post_deactivate_count] = NULL; /* Cannot reuse module_request_startup_handlers because it is freed in zend_destroy_modules, which happens before zend_unload_modules. */ - modules_dl_loaded = realloc(modules_dl_loaded, sizeof(zend_module_entry*) * (dl_loaded_count + 1)); + modules_dl_loaded = perealloc(modules_dl_loaded, sizeof(zend_module_entry*) * (dl_loaded_count + 1), true); modules_dl_loaded[dl_loaded_count] = NULL; startup_count = 0; @@ -2550,10 +2543,10 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */ } } ZEND_HASH_FOREACH_END(); - class_cleanup_handlers = (zend_class_entry**)realloc( + class_cleanup_handlers = (zend_class_entry**)perealloc( class_cleanup_handlers, sizeof(zend_class_entry*) * - (class_count + 1)); + (class_count + 1), true); class_cleanup_handlers[class_count] = NULL; if (class_count) { @@ -2747,7 +2740,7 @@ static void zend_check_magic_method_static( } static void zend_check_magic_method_public( - const zend_class_entry *ce, const zend_function *fptr, int error_type) + const zend_class_entry *ce, const zend_function *fptr) { // TODO: Remove this warning after adding proper visibility handling. if (!(fptr->common.fn_flags & ZEND_ACC_PUBLIC)) { @@ -2769,7 +2762,7 @@ static void zend_check_magic_method_no_return_type( } } -ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type) /* {{{ */ +ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, const zend_string *lcname, int error_type) /* {{{ */ { if (ZSTR_VAL(lcname)[0] != '_' || ZSTR_VAL(lcname)[1] != '_') { @@ -2790,83 +2783,87 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, } else if (zend_string_equals_literal(lcname, ZEND_GET_FUNC_NAME)) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); } else if (zend_string_equals_literal(lcname, ZEND_SET_FUNC_NAME)) { zend_check_magic_method_args(2, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); } else if (zend_string_equals_literal(lcname, ZEND_UNSET_FUNC_NAME)) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); } else if (zend_string_equals_literal(lcname, ZEND_ISSET_FUNC_NAME)) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_BOOL); } else if (zend_string_equals_literal(lcname, ZEND_CALL_FUNC_NAME)) { zend_check_magic_method_args(2, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_ARRAY); } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) { zend_check_magic_method_args(2, ce, fptr, error_type); zend_check_magic_method_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_STRING); zend_check_magic_method_arg_type(1, ce, fptr, error_type, MAY_BE_ARRAY); } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_STRING); } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, (MAY_BE_ARRAY | MAY_BE_NULL)); + if ((fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && ZEND_TYPE_PURE_MASK(fptr->common.arg_info[-1].type) & MAY_BE_NULL) { + zend_error(E_DEPRECATED, "Returning null from %s::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead", + ZSTR_VAL(ce->name)); + } } else if (zend_string_equals_literal(lcname, "__serialize")) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_ARRAY); } else if (zend_string_equals_literal(lcname, "__unserialize")) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ARRAY); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); } else if (zend_string_equals_literal(lcname, "__set_state")) { zend_check_magic_method_args(1, ce, fptr, error_type); zend_check_magic_method_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_arg_type(0, ce, fptr, error_type, MAY_BE_ARRAY); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_OBJECT); } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE))) { zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_SLEEP))) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_ARRAY); } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_WAKEUP))) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); - zend_check_magic_method_public(ce, fptr, error_type); + zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_VOID); } } /* }}} */ -ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname) +ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, const zend_string *lcname) { if (ZSTR_VAL(lcname)[0] != '_' || ZSTR_VAL(lcname)[1] != '_') { /* pass */ @@ -2933,6 +2930,81 @@ static zend_always_inline void zend_normalize_internal_type(zend_type *type) { } ZEND_TYPE_FOREACH_END(); } +static void zend_convert_internal_arg_info_type(zend_type *type, bool persistent) +{ + if (ZEND_TYPE_HAS_LITERAL_NAME(*type)) { + // gen_stubs.php does not support codegen for compound types. As a + // temporary workaround, we support union types by splitting + // the type name on `|` characters if necessary. + const char *class_name = ZEND_TYPE_LITERAL_NAME(*type); + type->type_mask &= ~_ZEND_TYPE_LITERAL_NAME_BIT; + + size_t num_types = 1; + const char *p = class_name; + while ((p = strchr(p, '|'))) { + num_types++; + p++; + } + + if (num_types == 1) { + /* Simple class type */ + zend_string *str = zend_string_init_interned(class_name, strlen(class_name), persistent); + zend_alloc_ce_cache(str); + ZEND_TYPE_SET_PTR(*type, str); + type->type_mask |= _ZEND_TYPE_NAME_BIT; + } else { + /* Union type */ + zend_type_list *list = pemalloc(ZEND_TYPE_LIST_SIZE(num_types), persistent); + list->num_types = num_types; + ZEND_TYPE_SET_LIST(*type, list); + ZEND_TYPE_FULL_MASK(*type) |= _ZEND_TYPE_UNION_BIT; + + const char *start = class_name; + uint32_t j = 0; + while (true) { + const char *end = strchr(start, '|'); + zend_string *str = zend_string_init_interned(start, end ? end - start : strlen(start), persistent); + zend_alloc_ce_cache(str); + list->types[j] = (zend_type) ZEND_TYPE_INIT_CLASS(str, 0, 0); + if (!end) { + break; + } + start = end + 1; + j++; + } + } + } + if (ZEND_TYPE_IS_ITERABLE_FALLBACK(*type)) { + /* Warning generated an extension load warning which is emitted for every test + zend_error(E_CORE_WARNING, "iterable type is now a compile time alias for array|Traversable," + " regenerate the argument info via the php-src gen_stub build script"); + */ + zend_type legacy_iterable = ZEND_TYPE_INIT_CLASS_MASK( + ZSTR_KNOWN(ZEND_STR_TRAVERSABLE), + (type->type_mask | MAY_BE_ARRAY) + ); + *type = legacy_iterable; + } +} + +ZEND_API void zend_convert_internal_arg_info(zend_arg_info *new_arg_info, const zend_internal_arg_info *arg_info, bool is_return_info, bool persistent) +{ + if (!is_return_info) { + new_arg_info->name = zend_string_init_interned(arg_info->name, strlen(arg_info->name), persistent); + if (arg_info->default_value) { + new_arg_info->default_value = zend_string_init_interned(arg_info->default_value, strlen(arg_info->default_value), persistent); + } else { + new_arg_info->default_value = NULL; + } + } else { + new_arg_info->name = NULL; + new_arg_info->default_value = NULL; + } + new_arg_info->doc_comment = NULL; + new_arg_info->type = arg_info->type; + zend_convert_internal_arg_info_type(&new_arg_info->type, persistent); +} + /* registers all functions in *library_functions in the function hash */ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type) /* {{{ */ { @@ -2944,6 +3016,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend int error_type; zend_string *lowercase_name; size_t fname_len; + const zend_internal_arg_info *internal_arg_info; if (type==MODULE_PERSISTENT) { error_type = E_CORE_WARNING; @@ -2985,7 +3058,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend ZEND_MAP_PTR_INIT(internal_function->run_time_cache, NULL); #endif } - if (ptr->flags) { + if (ptr->flags & UINT32_MAX) { if (!(ptr->flags & ZEND_ACC_PPP_MASK)) { if (ptr->flags != ZEND_ACC_DEPRECATED && scope) { zend_error(error_type, "Invalid access level for %s::%s() - access must be exactly one of public, protected or private", ZSTR_VAL(scope->name), ptr->fname); @@ -2997,10 +3070,11 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend } else { internal_function->fn_flags = ZEND_ACC_PUBLIC; } + internal_function->fn_flags2 = ptr->flags >> 32; if (ptr->arg_info) { zend_internal_function_info *info = (zend_internal_function_info*)ptr->arg_info; - internal_function->arg_info = (zend_internal_arg_info*)ptr->arg_info+1; + internal_arg_info = ptr->arg_info+1; internal_function->num_args = ptr->num_args; /* Currently you cannot denote that the function can accept less arguments than num_args */ if (info->required_num_args == (uintptr_t)-1) { @@ -3030,7 +3104,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend zend_error(E_CORE_WARNING, "Missing arginfo for %s%s%s()", scope ? ZSTR_VAL(scope->name) : "", scope ? "::" : "", ptr->fname); - internal_function->arg_info = NULL; + internal_arg_info = NULL; internal_function->num_args = 0; internal_function->required_num_args = 0; } @@ -3041,13 +3115,11 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend !(internal_function->fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { zend_error(E_CORE_WARNING, "%s::__toString() implemented without string return type", ZSTR_VAL(scope->name)); - internal_function->arg_info = (zend_internal_arg_info *) arg_info_toString + 1; + internal_arg_info = (zend_internal_arg_info *) arg_info_toString + 1; internal_function->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE; internal_function->num_args = internal_function->required_num_args = 0; } - - zend_set_function_arg_flags((zend_function*)internal_function); if (ptr->flags & ZEND_ACC_ABSTRACT) { if (scope) { /* This is a class that must be abstract itself. Here we set the check info. */ @@ -3075,7 +3147,7 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend } lowercase_name = zend_string_tolower_ex(internal_function->function_name, type == MODULE_PERSISTENT); lowercase_name = zend_new_interned_string(lowercase_name); - reg_function = malloc(sizeof(zend_internal_function)); + reg_function = pemalloc(sizeof(zend_internal_function), true); memcpy(reg_function, &function, sizeof(zend_internal_function)); if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) { unload=1; @@ -3093,8 +3165,8 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend zend_flf_capacity *= 2; } /* +1 for NULL terminator */ - zend_flf_handlers = realloc(zend_flf_handlers, (zend_flf_capacity + 1) * sizeof(void *)); - zend_flf_functions = realloc(zend_flf_functions, (zend_flf_capacity + 1) * sizeof(zend_function *)); + zend_flf_handlers = perealloc(zend_flf_handlers, (zend_flf_capacity + 1) * sizeof(void *), true); + zend_flf_functions = perealloc(zend_flf_functions, (zend_flf_capacity + 1) * sizeof(zend_function *), true); } zend_flf_handlers[zend_flf_count] = flf_info->handler; zend_flf_functions[zend_flf_count] = (zend_function *)reg_function; @@ -3112,17 +3184,17 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend } /* If types of arguments have to be checked */ - if (reg_function->arg_info && num_args) { + if (internal_arg_info && num_args) { uint32_t i; for (i = 0; i < num_args; i++) { - zend_internal_arg_info *arg_info = ®_function->arg_info[i]; + const zend_internal_arg_info *arg_info = &internal_arg_info[i]; ZEND_ASSERT(arg_info->name && "Parameter must have a name"); if (ZEND_TYPE_IS_SET(arg_info->type)) { reg_function->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS; } #if ZEND_DEBUG for (uint32_t j = 0; j < i; j++) { - if (!strcmp(arg_info->name, reg_function->arg_info[j].name)) { + if (!strcmp(arg_info->name, internal_arg_info[j].name)) { zend_error_noreturn(E_CORE_ERROR, "Duplicate parameter name $%s for function %s%s%s()", arg_info->name, scope ? ZSTR_VAL(scope->name) : "", scope ? "::" : "", ptr->fname); @@ -3132,78 +3204,24 @@ ZEND_API zend_result zend_register_functions(zend_class_entry *scope, const zend } } - /* Rebuild arginfos if parameter/property types and/or a return type are used */ - if (reg_function->arg_info && - (reg_function->fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))) { - /* convert "const char*" class type names into "zend_string*" */ + /* Convert zend_internal_arg_info to zend_arg_info */ + if (internal_arg_info) { uint32_t i; - zend_internal_arg_info *arg_info = reg_function->arg_info - 1; - zend_internal_arg_info *new_arg_info; + const zend_internal_arg_info *arg_info = internal_arg_info - 1; + zend_arg_info *new_arg_info; /* Treat return type as an extra argument */ num_args++; - new_arg_info = malloc(sizeof(zend_internal_arg_info) * num_args); - memcpy(new_arg_info, arg_info, sizeof(zend_internal_arg_info) * num_args); + new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, true); reg_function->arg_info = new_arg_info + 1; for (i = 0; i < num_args; i++) { - if (ZEND_TYPE_HAS_LITERAL_NAME(new_arg_info[i].type)) { - // gen_stubs.php does not support codegen for DNF types in arg infos. - // As a temporary workaround, we split the type name on `|` characters, - // converting it to an union type if necessary. - const char *class_name = ZEND_TYPE_LITERAL_NAME(new_arg_info[i].type); - new_arg_info[i].type.type_mask &= ~_ZEND_TYPE_LITERAL_NAME_BIT; - - size_t num_types = 1; - const char *p = class_name; - while ((p = strchr(p, '|'))) { - num_types++; - p++; - } - - if (num_types == 1) { - /* Simple class type */ - zend_string *str = zend_string_init_interned(class_name, strlen(class_name), 1); - zend_alloc_ce_cache(str); - ZEND_TYPE_SET_PTR(new_arg_info[i].type, str); - new_arg_info[i].type.type_mask |= _ZEND_TYPE_NAME_BIT; - } else { - /* Union type */ - zend_type_list *list = malloc(ZEND_TYPE_LIST_SIZE(num_types)); - list->num_types = num_types; - ZEND_TYPE_SET_LIST(new_arg_info[i].type, list); - ZEND_TYPE_FULL_MASK(new_arg_info[i].type) |= _ZEND_TYPE_UNION_BIT; - - const char *start = class_name; - uint32_t j = 0; - while (true) { - const char *end = strchr(start, '|'); - zend_string *str = zend_string_init_interned(start, end ? end - start : strlen(start), 1); - zend_alloc_ce_cache(str); - list->types[j] = (zend_type) ZEND_TYPE_INIT_CLASS(str, 0, 0); - if (!end) { - break; - } - start = end + 1; - j++; - } - } - } - if (ZEND_TYPE_IS_ITERABLE_FALLBACK(new_arg_info[i].type)) { - /* Warning generated an extension load warning which is emitted for every test - zend_error(E_CORE_WARNING, "iterable type is now a compile time alias for array|Traversable," - " regenerate the argument info via the php-src gen_stub build script"); - */ - zend_type legacy_iterable = ZEND_TYPE_INIT_CLASS_MASK( - ZSTR_KNOWN(ZEND_STR_TRAVERSABLE), - (new_arg_info[i].type.type_mask | MAY_BE_ARRAY) - ); - new_arg_info[i].type = legacy_iterable; - } - - zend_normalize_internal_type(&new_arg_info[i].type); + zend_convert_internal_arg_info(&new_arg_info[i], &arg_info[i], + i == 0, true); } } + zend_set_function_arg_flags((zend_function*)reg_function); + if (scope) { zend_check_magic_method_implementation( scope, (zend_function *)reg_function, lowercase_name, E_CORE_ERROR); @@ -3283,7 +3301,7 @@ static void clean_module_classes(int module_number) /* {{{ */ /* Child classes may reuse structures from parent classes, so destroy in reverse order. */ Bucket *bucket; ZEND_HASH_REVERSE_FOREACH_BUCKET(EG(class_table), bucket) { - zend_class_entry *ce = Z_CE(bucket->val); + const zend_class_entry *ce = Z_CE(bucket->val); if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) { zend_hash_del_bucket(EG(class_table), bucket); } @@ -3294,8 +3312,8 @@ static void clean_module_classes(int module_number) /* {{{ */ static int clean_module_function(zval *el, void *arg) /* {{{ */ { - zend_function *fe = (zend_function *) Z_PTR_P(el); - zend_module_entry *module = (zend_module_entry *) arg; + const zend_function *fe = (zend_function *) Z_PTR_P(el); + const zend_module_entry *module = arg; if (fe->common.type == ZEND_INTERNAL_FUNCTION && fe->internal_function.module == module) { return ZEND_HASH_APPLY_REMOVE; } else { @@ -3383,7 +3401,7 @@ ZEND_API void zend_activate_modules(void) /* {{{ */ zend_module_entry **p = module_request_startup_handlers; while (*p) { - zend_module_entry *module = *p; + const zend_module_entry *module = *p; if (module->request_startup_func(module->type, module->module_number)==FAILURE) { zend_error(E_WARNING, "request_startup() for %s module failed", module->name); @@ -3412,7 +3430,7 @@ ZEND_API void zend_deactivate_modules(void) /* {{{ */ zend_module_entry **p = module_request_shutdown_handlers; while (*p) { - zend_module_entry *module = *p; + const zend_module_entry *module = *p; zend_try { module->request_shutdown_func(module->type, module->module_number); } zend_end_try(); @@ -3461,7 +3479,7 @@ ZEND_API void zend_post_deactivate_modules(void) /* {{{ */ zend_module_entry **p = module_post_deactivate_handlers; while (*p) { - zend_module_entry *module = *p; + const zend_module_entry *module = *p; module->post_deactivate_func(); p++; @@ -3477,9 +3495,9 @@ ZEND_API int zend_next_free_module(void) /* {{{ */ } /* }}} */ -static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, uint32_t ce_flags) /* {{{ */ +static zend_class_entry *do_register_internal_class(const zend_class_entry *orig_class_entry, uint32_t ce_flags) /* {{{ */ { - zend_class_entry *class_entry = malloc(sizeof(zend_class_entry)); + zend_class_entry *class_entry = pemalloc(sizeof(zend_class_entry), true); zend_string *lowercase_name; *class_entry = *orig_class_entry; @@ -3513,14 +3531,14 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class * If both parent_ce and parent_name are NULL it does a regular class registration * If parent_name is specified but not found NULL is returned */ -ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce) /* {{{ */ +ZEND_API zend_class_entry *zend_register_internal_class_ex(const zend_class_entry *class_entry, zend_class_entry *parent_ce) /* {{{ */ { return zend_register_internal_class_with_flags(class_entry, parent_ce, 0); } /* }}} */ ZEND_API zend_class_entry *zend_register_internal_class_with_flags( - zend_class_entry *class_entry, + const zend_class_entry *class_entry, zend_class_entry *parent_ce, uint32_t ce_flags ) { @@ -3558,13 +3576,13 @@ ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_inter /* A class that contains at least one abstract method automatically becomes an abstract class. */ -ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_class_entry) /* {{{ */ +ZEND_API zend_class_entry *zend_register_internal_class(const zend_class_entry *orig_class_entry) /* {{{ */ { return do_register_internal_class(orig_class_entry, 0); } /* }}} */ -ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry) /* {{{ */ +ZEND_API zend_class_entry *zend_register_internal_interface(const zend_class_entry *orig_class_entry) /* {{{ */ { return do_register_internal_class(orig_class_entry, ZEND_ACC_INTERFACE); } @@ -3577,7 +3595,7 @@ ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_ /* TODO: Move this out of here in 7.4. */ if (persistent && EG(current_module) && EG(current_module)->type == MODULE_TEMPORARY) { - persistent = 0; + persistent = false; } if (name[0] == '\\') { @@ -3611,29 +3629,6 @@ ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_ } /* }}} */ -// TODO num_symbol_tables as unsigned int? -ZEND_API zend_result zend_set_hash_symbol(zval *symbol, const char *name, size_t name_length, bool is_ref, int num_symbol_tables, ...) /* {{{ */ -{ - HashTable *symbol_table; - va_list symbol_table_list; - - if (num_symbol_tables <= 0) return FAILURE; - - if (is_ref) { - ZVAL_MAKE_REF(symbol); - } - - va_start(symbol_table_list, num_symbol_tables); - while (num_symbol_tables-- > 0) { - symbol_table = va_arg(symbol_table_list, HashTable *); - zend_hash_str_update(symbol_table, name, name_length, symbol); - Z_TRY_ADDREF_P(symbol); - } - va_end(symbol_table_list); - return SUCCESS; -} -/* }}} */ - /* Disabled functions support */ static void zend_disable_function(const char *function_name, size_t function_name_length) @@ -3641,6 +3636,7 @@ static void zend_disable_function(const char *function_name, size_t function_nam if (UNEXPECTED( (function_name_length == strlen("exit") && !memcmp(function_name, "exit", strlen("exit"))) || (function_name_length == strlen("die") && !memcmp(function_name, "die", strlen("die"))) + || (function_name_length == strlen("clone") && !memcmp(function_name, "clone", strlen("clone"))) )) { zend_error(E_WARNING, "Cannot disable function %s()", function_name); return; @@ -3683,85 +3679,14 @@ ZEND_API void zend_disable_functions(const char *function_list) /* {{{ */ } /* }}} */ -#ifdef ZEND_WIN32 -#pragma optimize("", off) -#endif -static ZEND_COLD zend_object *display_disabled_class(zend_class_entry *class_type) /* {{{ */ -{ - zend_object *intern; - - intern = zend_objects_new(class_type); - - /* Initialize default properties */ - if (EXPECTED(class_type->default_properties_count != 0)) { - zval *p = intern->properties_table; - zval *end = p + class_type->default_properties_count; - do { - ZVAL_UNDEF(p); - p++; - } while (p != end); - } - - zend_error(E_WARNING, "%s() has been disabled for security reasons", ZSTR_VAL(class_type->name)); - return intern; -} -#ifdef ZEND_WIN32 -#pragma optimize("", on) -#endif -/* }}} */ - -static const zend_function_entry disabled_class_new[] = { - ZEND_FE_END -}; - -ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length) /* {{{ */ -{ - zend_class_entry *disabled_class; - zend_string *key; - zend_function *fn; - zend_property_info *prop; - - key = zend_string_alloc(class_name_length, 0); - zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length); - disabled_class = zend_hash_find_ptr(CG(class_table), key); - zend_string_release_ex(key, 0); - if (!disabled_class) { - return FAILURE; - } - - /* Will be reset by INIT_CLASS_ENTRY. */ - free(disabled_class->interfaces); - - INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new); - disabled_class->create_object = display_disabled_class; - - ZEND_HASH_MAP_FOREACH_PTR(&disabled_class->function_table, fn) { - if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) && - fn->common.scope == disabled_class) { - zend_free_internal_arg_info(&fn->internal_function); - } - } ZEND_HASH_FOREACH_END(); - zend_hash_clean(&disabled_class->function_table); - ZEND_HASH_MAP_FOREACH_PTR(&disabled_class->properties_info, prop) { - if (prop->ce == disabled_class) { - zend_string_release(prop->name); - zend_type_release(prop->type, /* persistent */ 1); - free(prop); - } - } ZEND_HASH_FOREACH_END(); - zend_hash_clean(&disabled_class->properties_info); - return SUCCESS; -} -/* }}} */ - -static zend_always_inline zend_class_entry *get_scope(zend_execute_data *frame) +static zend_always_inline zend_class_entry *get_scope(const zend_execute_data *frame) { return frame && frame->func ? frame->func->common.scope : NULL; } -static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *scope, zend_execute_data *frame, zend_fcall_info_cache *fcc, bool *strict_class, char **error, bool suppress_deprecation) /* {{{ */ +static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *scope, const zend_execute_data *frame, zend_fcall_info_cache *fcc, bool *strict_class, char **error, bool suppress_deprecation) /* {{{ */ { - bool ret = 0; + bool ret = false; zend_class_entry *ce; size_t name_len = ZSTR_LEN(name); zend_string *lcname; @@ -3770,7 +3695,7 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc ZSTR_ALLOCA_ALLOC(lcname, name_len, use_heap); zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(name), name_len); - *strict_class = 0; + *strict_class = false; if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_SELF))) { if (!scope) { if (error) *error = estrdup("cannot access \"self\" when no class scope is active"); @@ -3786,7 +3711,7 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (!fcc->object) { fcc->object = zend_get_this_object(frame); } - ret = 1; + ret = true; } } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_PARENT))) { if (!scope) { @@ -3805,8 +3730,8 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (!fcc->object) { fcc->object = zend_get_this_object(frame); } - *strict_class = 1; - ret = 1; + *strict_class = true; + ret = true; } } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_STATIC))) { zend_class_entry *called_scope = zend_get_called_scope(frame); @@ -3822,18 +3747,18 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (!fcc->object) { fcc->object = zend_get_this_object(frame); } - *strict_class = 1; - ret = 1; + *strict_class = true; + ret = true; } } else if ((ce = zend_lookup_class(name)) != NULL) { - zend_class_entry *scope = get_scope(frame); + const zend_class_entry *frame_scope = get_scope(frame); fcc->calling_scope = ce; - if (scope && !fcc->object) { + if (frame_scope && !fcc->object) { zend_object *object = zend_get_this_object(frame); if (object && - instanceof_function(object->ce, scope) && - instanceof_function(scope, ce)) { + instanceof_function(object->ce, frame_scope) && + instanceof_function(frame_scope, ce)) { fcc->object = object; fcc->called_scope = object->ce; } else { @@ -3842,12 +3767,16 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc } else { fcc->called_scope = fcc->object ? fcc->object->ce : ce; } - *strict_class = 1; - ret = 1; + *strict_class = true; + ret = true; } else { if (error) zend_spprintf(error, 0, "class \"%.*s\" not found", (int)name_len, ZSTR_VAL(name)); } ZSTR_ALLOCA_FREE(lcname, use_heap); + /* User error handlers may throw from deprecations above; do not report callable as valid. */ + if (UNEXPECTED(EG(exception))) { + return false; + } return ret; } /* }}} */ @@ -3863,10 +3792,10 @@ ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc) { } } -static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_execute_data *frame, zend_fcall_info_cache *fcc, bool strict_class, char **error, bool suppress_deprecation) /* {{{ */ +static zend_always_inline bool zend_is_callable_check_func(const zval *callable, const zend_execute_data *frame, zend_fcall_info_cache *fcc, bool strict_class, char **error, bool suppress_deprecation) /* {{{ */ { zend_class_entry *ce_org = fcc->calling_scope; - bool retval = 0; + bool retval = false; zend_string *mname, *cname; zend_string *lmname; const char *colon; @@ -3948,7 +3877,7 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ } else { fcc->called_scope = fcc->object ? fcc->object->ce : fcc->calling_scope; } - strict_class = 1; + strict_class = true; } else if (!zend_is_callable_check_class(cname, scope, frame, fcc, &strict_class, error, suppress_deprecation || ce_org != NULL)) { zend_string_release_ex(cname, 0); return 0; @@ -3986,11 +3915,11 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ zend_string_equals_literal(lmname, ZEND_CONSTRUCTOR_FUNC_NAME)) { fcc->function_handler = fcc->calling_scope->constructor; if (fcc->function_handler) { - retval = 1; + retval = true; } } else if ((zv = zend_hash_find(ftable, lmname)) != NULL) { fcc->function_handler = Z_PTR_P(zv); - retval = 1; + retval = true; if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) && !strict_class) { scope = get_scope(frame); @@ -4013,22 +3942,20 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ ((fcc->object && fcc->calling_scope->__call) || (!fcc->object && fcc->calling_scope->__callstatic)))) { scope = get_scope(frame); - if (fcc->function_handler->common.scope != scope) { - if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PRIVATE) - || !zend_check_protected(zend_get_function_root_class(fcc->function_handler), scope)) { - retval = 0; - fcc->function_handler = NULL; - goto get_function_via_handler; - } + ZEND_ASSERT(!(fcc->function_handler->common.fn_flags & ZEND_ACC_PUBLIC)); + if (!zend_check_method_accessible(fcc->function_handler, scope)) { + retval = false; + fcc->function_handler = NULL; + goto get_function_via_handler; } } } else { get_function_via_handler: if (fcc->object && fcc->calling_scope == ce_org) { if (strict_class && ce_org->__call) { - fcc->function_handler = zend_get_call_trampoline_func(ce_org, mname, 0); + fcc->function_handler = zend_get_call_trampoline_func(ce_org->__call, mname); call_via_handler = 1; - retval = 1; + retval = true; } else { fcc->function_handler = fcc->object->handlers->get_method(&fcc->object, mname, NULL); if (fcc->function_handler) { @@ -4037,7 +3964,7 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ !instanceof_function(ce_org, fcc->function_handler->common.scope))) { zend_release_fcall_info_cache(fcc); } else { - retval = 1; + retval = true; call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; } } @@ -4049,7 +3976,7 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, mname, NULL); } if (fcc->function_handler) { - retval = 1; + retval = true; call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; if (call_via_handler && !fcc->object) { zend_object *object = zend_get_this_object(frame); @@ -4065,12 +3992,12 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ if (retval) { if (fcc->calling_scope && !call_via_handler) { if (fcc->function_handler->common.fn_flags & ZEND_ACC_ABSTRACT) { - retval = 0; + retval = false; if (error) { zend_spprintf(error, 0, "cannot call abstract method %s::%s()", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name)); } } else if (!fcc->object && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) { - retval = 0; + retval = false; if (error) { zend_spprintf(error, 0, "non-static method %s::%s() cannot be called statically", ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name)); } @@ -4078,17 +4005,15 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ if (retval && !(fcc->function_handler->common.fn_flags & ZEND_ACC_PUBLIC)) { scope = get_scope(frame); - if (fcc->function_handler->common.scope != scope) { - if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PRIVATE) - || (!zend_check_protected(zend_get_function_root_class(fcc->function_handler), scope))) { - if (error) { - if (*error) { - efree(*error); - } - zend_spprintf(error, 0, "cannot access %s method %s::%s()", zend_visibility_string(fcc->function_handler->common.fn_flags), ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name)); + ZEND_ASSERT(!(fcc->function_handler->common.fn_flags & ZEND_ACC_PUBLIC)); + if (!zend_check_method_accessible(fcc->function_handler, scope)) { + if (error) { + if (*error) { + efree(*error); } - retval = 0; + zend_spprintf(error, 0, "cannot access %s method %s::%s()", zend_visibility_string(fcc->function_handler->common.fn_flags), ZSTR_VAL(fcc->calling_scope->name), ZSTR_VAL(fcc->function_handler->common.function_name)); } + retval = false; } } } @@ -4113,7 +4038,7 @@ static zend_always_inline bool zend_is_callable_check_func(zval *callable, zend_ } /* }}} */ -ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *object) /* {{{ */ +ZEND_API zend_string *zend_get_callable_name_ex(const zval *callable, const zend_object *object) /* {{{ */ { try_again: switch (Z_TYPE_P(callable)) { @@ -4125,8 +4050,8 @@ ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *obj case IS_ARRAY: { - zval *method = NULL; - zval *obj = NULL; + const zval *method = NULL; + const zval *obj = NULL; if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) { obj = zend_hash_index_find_deref(Z_ARRVAL_P(callable), 0); @@ -4147,18 +4072,15 @@ ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *obj } case IS_OBJECT: { - zend_class_entry *ce = Z_OBJCE_P(callable); + const zend_class_entry *ce = Z_OBJCE_P(callable); if (ce == zend_ce_closure) { const zend_function *fn = zend_get_closure_method_def(Z_OBJ_P(callable)); - if (fn->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { - if (fn->common.scope) { - return zend_create_member_string(fn->common.scope->name, fn->common.function_name); - } else { - return zend_string_copy(fn->common.function_name); - } + if ((fn->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) && fn->common.scope) { + return zend_create_member_string(fn->common.scope->name, fn->common.function_name); } + return zend_string_copy(fn->common.function_name); } return zend_string_concat2( @@ -4174,19 +4096,19 @@ ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *obj } /* }}} */ -ZEND_API zend_string *zend_get_callable_name(zval *callable) /* {{{ */ +ZEND_API zend_string *zend_get_callable_name(const zval *callable) /* {{{ */ { return zend_get_callable_name_ex(callable, NULL); } /* }}} */ ZEND_API bool zend_is_callable_at_frame( - zval *callable, zend_object *object, zend_execute_data *frame, + const zval *callable, zend_object *object, const zend_execute_data *frame, uint32_t check_flags, zend_fcall_info_cache *fcc, char **error) /* {{{ */ { bool ret; zend_fcall_info_cache fcc_local; - bool strict_class = 0; + bool strict_class = false; if (fcc == NULL) { fcc = &fcc_local; @@ -4291,10 +4213,10 @@ ZEND_API bool zend_is_callable_at_frame( } /* }}} */ -ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error) /* {{{ */ +ZEND_API bool zend_is_callable_ex(const zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error) /* {{{ */ { /* Determine callability at the first parent user frame. */ - zend_execute_data *frame = EG(current_execute_data); + const zend_execute_data *frame = EG(current_execute_data); while (frame && (!frame->func || !ZEND_USER_CODE(frame->func->type))) { frame = frame->prev_execute_data; } @@ -4306,31 +4228,13 @@ ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t return ret; } -ZEND_API bool zend_is_callable(zval *callable, uint32_t check_flags, zend_string **callable_name) /* {{{ */ +ZEND_API bool zend_is_callable(const zval *callable, uint32_t check_flags, zend_string **callable_name) /* {{{ */ { return zend_is_callable_ex(callable, NULL, check_flags, callable_name, NULL, NULL); } /* }}} */ -ZEND_API bool zend_make_callable(zval *callable, zend_string **callable_name) /* {{{ */ -{ - zend_fcall_info_cache fcc; - - if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, callable_name, &fcc, NULL)) { - if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) { - zval_ptr_dtor_str(callable); - array_init(callable); - add_next_index_str(callable, zend_string_copy(fcc.calling_scope->name)); - add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name)); - } - zend_release_fcall_info_cache(&fcc); - return 1; - } - return 0; -} -/* }}} */ - -ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error) /* {{{ */ +ZEND_API zend_result zend_fcall_info_init(const zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error) /* {{{ */ { if (!zend_is_callable_ex(callable, NULL, check_flags, callable_name, fcc, error)) { return FAILURE; @@ -4343,6 +4247,7 @@ ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, fci->param_count = 0; fci->params = NULL; fci->named_params = NULL; + fci->consumed_args = 0; return SUCCESS; } @@ -4378,7 +4283,7 @@ ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, uint32_t *param_co ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, uint32_t param_count, zval *params) /* {{{ */ { - zend_fcall_info_args_clear(fci, 1); + zend_fcall_info_args_clear(fci, true); fci->param_count = param_count; fci->params = params; } @@ -4508,21 +4413,14 @@ ZEND_API void zend_get_callable_zval_from_fcc(const zend_fcall_info_cache *fcc, ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */ { - zend_string *lname; size_t name_len = strlen(module_name); - zend_module_entry *module; - - lname = zend_string_alloc(name_len, 0); - zend_str_tolower_copy(ZSTR_VAL(lname), module_name, name_len); - module = zend_hash_find_ptr(&module_registry, lname); - zend_string_efree(lname); + zend_module_entry *module = zend_hash_str_find_ptr_lc(&module_registry, module_name, name_len); return module ? module->version : NULL; } /* }}} */ -static zend_always_inline bool is_persistent_class(zend_class_entry *ce) { - return (ce->type & ZEND_INTERNAL_CLASS) - && ce->info.internal.module->type == MODULE_PERSISTENT; +static zend_always_inline bool is_persistent_class(const zend_class_entry *ce) { + return ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->type == MODULE_PERSISTENT; } ZEND_API zend_property_info *zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type) /* {{{ */ @@ -4645,7 +4543,7 @@ ZEND_API zend_property_info *zend_declare_typed_property(zend_class_entry *ce, z Z_PROP_FLAG_P(property_default_ptr) = Z_ISUNDEF_P(property) ? IS_PROP_UNINIT : 0; } skip_property_storage: - if (ce->type & ZEND_INTERNAL_CLASS) { + if (ce->type == ZEND_INTERNAL_CLASS) { /* Must be interned to avoid ZTS data races */ if (is_persistent_class(ce)) { name = zend_new_interned_string(zend_string_copy(name)); @@ -4864,7 +4762,7 @@ ZEND_API void zend_declare_property_string(zend_class_entry *ce, const char *nam { zval property; - ZVAL_NEW_STR(&property, zend_string_init(value, strlen(value), ce->type & ZEND_INTERNAL_CLASS)); + ZVAL_NEW_STR(&property, zend_string_init(value, strlen(value), ce->type == ZEND_INTERNAL_CLASS)); zend_declare_property(ce, name, name_length, &property, access_type); } /* }}} */ @@ -4873,7 +4771,7 @@ ZEND_API void zend_declare_property_stringl(zend_class_entry *ce, const char *na { zval property; - ZVAL_NEW_STR(&property, zend_string_init(value, value_len, ce->type & ZEND_INTERNAL_CLASS)); + ZVAL_NEW_STR(&property, zend_string_init(value, value_len, ce->type == ZEND_INTERNAL_CLASS)); zend_declare_property(ce, name, name_length, &property, access_type); } /* }}} */ @@ -4987,7 +4885,7 @@ ZEND_API void zend_declare_class_constant_stringl(zend_class_entry *ce, const ch { zval constant; - ZVAL_NEW_STR(&constant, zend_string_init(value, value_length, ce->type & ZEND_INTERNAL_CLASS)); + ZVAL_NEW_STR(&constant, zend_string_init(value, value_length, ce->type == ZEND_INTERNAL_CLASS)); zend_declare_class_constant(ce, name, name_length, &constant); } /* }}} */ @@ -4998,9 +4896,9 @@ ZEND_API void zend_declare_class_constant_string(zend_class_entry *ce, const cha } /* }}} */ -ZEND_API void zend_update_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, zval *value) /* {{{ */ +ZEND_API void zend_update_property_ex(const zend_class_entry *scope, zend_object *object, zend_string *name, zval *value) /* {{{ */ { - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = scope; @@ -5010,10 +4908,10 @@ ZEND_API void zend_update_property_ex(zend_class_entry *scope, zend_object *obje } /* }}} */ -ZEND_API void zend_update_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value) /* {{{ */ +ZEND_API void zend_update_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value) /* {{{ */ { zend_string *property; - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = scope; @@ -5025,7 +4923,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zend_object *object, } /* }}} */ -ZEND_API void zend_update_property_null(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ +ZEND_API void zend_update_property_null(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ { zval tmp; @@ -5034,10 +4932,10 @@ ZEND_API void zend_update_property_null(zend_class_entry *scope, zend_object *ob } /* }}} */ -ZEND_API void zend_unset_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ +ZEND_API void zend_unset_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length) /* {{{ */ { zend_string *property; - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = scope; @@ -5049,7 +4947,7 @@ ZEND_API void zend_unset_property(zend_class_entry *scope, zend_object *object, } /* }}} */ -ZEND_API void zend_update_property_bool(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ +ZEND_API void zend_update_property_bool(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ { zval tmp; @@ -5058,7 +4956,7 @@ ZEND_API void zend_update_property_bool(zend_class_entry *scope, zend_object *ob } /* }}} */ -ZEND_API void zend_update_property_long(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ +ZEND_API void zend_update_property_long(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value) /* {{{ */ { zval tmp; @@ -5067,7 +4965,7 @@ ZEND_API void zend_update_property_long(zend_class_entry *scope, zend_object *ob } /* }}} */ -ZEND_API void zend_update_property_double(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value) /* {{{ */ +ZEND_API void zend_update_property_double(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value) /* {{{ */ { zval tmp; @@ -5076,7 +4974,7 @@ ZEND_API void zend_update_property_double(zend_class_entry *scope, zend_object * } /* }}} */ -ZEND_API void zend_update_property_str(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value) /* {{{ */ +ZEND_API void zend_update_property_str(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value) /* {{{ */ { zval tmp; @@ -5085,7 +4983,7 @@ ZEND_API void zend_update_property_str(zend_class_entry *scope, zend_object *obj } /* }}} */ -ZEND_API void zend_update_property_string(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value) /* {{{ */ +ZEND_API void zend_update_property_string(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value) /* {{{ */ { zval tmp; @@ -5095,7 +4993,7 @@ ZEND_API void zend_update_property_string(zend_class_entry *scope, zend_object * } /* }}} */ -ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_len) /* {{{ */ +ZEND_API void zend_update_property_stringl(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_len) /* {{{ */ { zval tmp; @@ -5109,7 +5007,6 @@ ZEND_API zend_result zend_update_static_property_ex(zend_class_entry *scope, zen { zval *property, tmp; zend_property_info *prop_info; - zend_class_entry *old_scope = EG(fake_scope); if (UNEXPECTED(!(scope->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) { if (UNEXPECTED(zend_update_class_constants(scope) != SUCCESS)) { @@ -5117,6 +5014,7 @@ ZEND_API zend_result zend_update_static_property_ex(zend_class_entry *scope, zen } } + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = scope; property = zend_std_get_static_property_with_info(scope, name, BP_VAR_W, &prop_info); EG(fake_scope) = old_scope; @@ -5206,10 +5104,10 @@ ZEND_API zend_result zend_update_static_property_stringl(zend_class_entry *scope } /* }}} */ -ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv) /* {{{ */ +ZEND_API zval *zend_read_property_ex(const zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv) /* {{{ */ { zval *value; - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = scope; @@ -5220,7 +5118,7 @@ ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zend_object *objec } /* }}} */ -ZEND_API zval *zend_read_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, bool silent, zval *rv) /* {{{ */ +ZEND_API zval *zend_read_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, bool silent, zval *rv) /* {{{ */ { zval *value; zend_string *str; @@ -5235,7 +5133,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zend_object *object, ZEND_API zval *zend_read_static_property_ex(zend_class_entry *scope, zend_string *name, bool silent) /* {{{ */ { zval *property; - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = scope; property = zend_std_get_static_property(scope, name, silent ? BP_VAR_IS : BP_VAR_R); @@ -5272,7 +5170,7 @@ ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, } /* }}} */ -ZEND_API void zend_restore_error_handling(zend_error_handling *saved) /* {{{ */ +ZEND_API void zend_restore_error_handling(const zend_error_handling *saved) /* {{{ */ { EG(error_handling) = saved->handling; EG(exception_class) = saved->exception; @@ -5372,48 +5270,43 @@ static zend_string *try_parse_string(const char *str, size_t len, char quote) { } ZEND_API zend_result zend_get_default_from_internal_arg_info( - zval *default_value_zval, zend_internal_arg_info *arg_info) + zval *default_value_zval, const zend_arg_info *arg_info) { - const char *default_value = arg_info->default_value; + const zend_string *default_value = arg_info->default_value; if (!default_value) { return FAILURE; } /* Avoid going through the full AST machinery for some simple and common cases. */ - size_t default_value_len = strlen(default_value); zend_ulong lval; - if (default_value_len == sizeof("null")-1 - && !memcmp(default_value, "null", sizeof("null")-1)) { + if (zend_string_equals_literal(default_value, "null")) { ZVAL_NULL(default_value_zval); return SUCCESS; - } else if (default_value_len == sizeof("true")-1 - && !memcmp(default_value, "true", sizeof("true")-1)) { + } else if (zend_string_equals_literal(default_value, "true")) { ZVAL_TRUE(default_value_zval); return SUCCESS; - } else if (default_value_len == sizeof("false")-1 - && !memcmp(default_value, "false", sizeof("false")-1)) { + } else if (zend_string_equals_literal(default_value, "false")) { ZVAL_FALSE(default_value_zval); return SUCCESS; - } else if (default_value_len >= 2 - && (default_value[0] == '\'' || default_value[0] == '"') - && default_value[default_value_len - 1] == default_value[0]) { + } else if (ZSTR_LEN(default_value) >= 2 + && (ZSTR_VAL(default_value)[0] == '\'' || ZSTR_VAL(default_value)[0] == '"') + && ZSTR_VAL(default_value)[ZSTR_LEN(default_value) - 1] == ZSTR_VAL(default_value)[0]) { zend_string *str = try_parse_string( - default_value + 1, default_value_len - 2, default_value[0]); + ZSTR_VAL(default_value) + 1, ZSTR_LEN(default_value) - 2, ZSTR_VAL(default_value)[0]); if (str) { ZVAL_STR(default_value_zval, str); return SUCCESS; } - } else if (default_value_len == sizeof("[]")-1 - && !memcmp(default_value, "[]", sizeof("[]")-1)) { + } else if (zend_string_equals_literal(default_value, "[]")) { ZVAL_EMPTY_ARRAY(default_value_zval); return SUCCESS; - } else if (ZEND_HANDLE_NUMERIC_STR(default_value, default_value_len, lval)) { + } else if (ZEND_HANDLE_NUMERIC(default_value, lval)) { ZVAL_LONG(default_value_zval, lval); return SUCCESS; } #if 0 - fprintf(stderr, "Evaluating %s via AST\n", default_value); + fprintf(stderr, "Evaluating %s via AST\n", ZSTR_VAL(default_value)); #endif - return get_default_via_ast(default_value_zval, default_value); + return get_default_via_ast(default_value_zval, ZSTR_VAL(default_value)); } diff --git a/Zend/zend_API.h b/Zend/zend_API.h index a644de8e1513..2487c8b632f2 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -37,7 +36,7 @@ typedef struct _zend_function_entry { zif_handler handler; const struct _zend_internal_arg_info *arg_info; uint32_t num_args; - uint32_t flags; + uint64_t flags; const zend_frameless_function_info *frameless_function_infos; const char *doc_comment; } zend_function_entry; @@ -49,6 +48,7 @@ typedef struct _zend_fcall_info { zval *params; zend_object *object; uint32_t param_count; + uint32_t consumed_args; /* This hashtable can also contain positional arguments (with integer keys), * which will be appended to the normal params[]. This makes it easier to * integrate APIs like call_user_func_array(). The usual restriction that @@ -75,6 +75,8 @@ typedef struct _zend_fcall_info_cache { #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(zif_##name) #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(zim_##classname##_##name) +#define ZEND_FENTRY_FLAGS(flags, flags2) (((uint64_t)flags) | ((uint64_t)flags2 << 32)) + #define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags, NULL, NULL }, #define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags, frameless_function_infos, doc_comment) { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags, frameless_function_infos, doc_comment }, @@ -340,30 +342,30 @@ typedef struct _zend_fcall_info_cache { #define ZEND_FCI_INITIALIZED(fci) ((fci).size != 0) #define ZEND_FCC_INITIALIZED(fcc) ((fcc).function_handler != NULL) +static zend_always_inline uint32_t zend_fci_consumed_arg(uint32_t arg_index) { + return arg_index < 32 ? (UINT32_C(1) << arg_index) : UINT32_C(0); +} +static zend_always_inline bool zend_fci_is_consumed_arg(uint32_t consumed_args, uint32_t arg_index) { + return arg_index < 32 && (consumed_args & (UINT32_C(1) << arg_index)); +} + ZEND_API int zend_next_free_module(void); BEGIN_EXTERN_C() -ZEND_API zend_result zend_get_parameters_array_ex(uint32_t param_count, zval *argument_array); +ZEND_API void zend_set_dl_use_deepbind(bool use_deepbind); -/* internal function to efficiently copy parameters when executing __call() */ -ZEND_API zend_result zend_copy_parameters_array(uint32_t param_count, zval *argument_array); +ZEND_API zend_result zend_get_parameters_array_ex(uint32_t param_count, zval *argument_array); #define zend_get_parameters_array(ht, param_count, argument_array) \ zend_get_parameters_array_ex(param_count, argument_array) #define zend_parse_parameters_none() \ (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : (zend_wrong_parameters_none_error(), FAILURE)) -#define zend_parse_parameters_none_throw() \ - zend_parse_parameters_none() /* Parameter parsing API -- andrei */ -#define ZEND_PARSE_PARAMS_THROW 0 /* No longer used, zpp always uses exceptions */ #define ZEND_PARSE_PARAMS_QUIET (1<<1) ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec, ...); ZEND_API zend_result zend_parse_parameters_ex(int flags, uint32_t num_args, const char *type_spec, ...); -/* NOTE: This must have at least one value in __VA_ARGS__ for the expression to be valid */ -#define zend_parse_parameters_throw(num_args, ...) \ - zend_parse_parameters(num_args, __VA_ARGS__) ZEND_API const char *zend_zval_type_name(const zval *arg); ZEND_API const char *zend_zval_value_name(const zval *arg); ZEND_API zend_string *zend_zval_get_legacy_type(const zval *arg); @@ -385,13 +387,13 @@ ZEND_API void zend_startup_modules(void); ZEND_API void zend_collect_module_handlers(void); ZEND_API void zend_destroy_modules(void); ZEND_API void zend_check_magic_method_implementation( - const zend_class_entry *ce, const zend_function *fptr, zend_string *lcname, int error_type); -ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, zend_string *lcname); + const zend_class_entry *ce, const zend_function *fptr, const zend_string *lcname, int error_type); +ZEND_API void zend_add_magic_method(zend_class_entry *ce, zend_function *fptr, const zend_string *lcname); -ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry); -ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce); -ZEND_API zend_class_entry *zend_register_internal_class_with_flags(zend_class_entry *class_entry, zend_class_entry *parent_ce, uint32_t flags); -ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry); +ZEND_API zend_class_entry *zend_register_internal_class(const zend_class_entry *class_entry); +ZEND_API zend_class_entry *zend_register_internal_class_ex(const zend_class_entry *class_entry, zend_class_entry *parent_ce); +ZEND_API zend_class_entry *zend_register_internal_class_with_flags(const zend_class_entry *class_entry, zend_class_entry *parent_ce, uint32_t flags); +ZEND_API zend_class_entry *zend_register_internal_interface(const zend_class_entry *orig_class_entry); ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...); ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, bool persistent); @@ -403,23 +405,21 @@ static zend_always_inline zend_result zend_register_class_alias(const char *name zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce, 1) ZEND_API void zend_disable_functions(const char *function_list); -ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length); ZEND_API ZEND_COLD void zend_wrong_param_count(void); -ZEND_API ZEND_COLD void zend_wrong_property_read(zval *object, zval *property); +ZEND_API ZEND_COLD void zend_wrong_property_read(const zval *object, zval *property); #define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0) #define IS_CALLABLE_SUPPRESS_DEPRECATIONS (1<<1) ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc); -ZEND_API zend_string *zend_get_callable_name_ex(zval *callable, zend_object *object); -ZEND_API zend_string *zend_get_callable_name(zval *callable); +ZEND_API zend_string *zend_get_callable_name_ex(const zval *callable, const zend_object *object); +ZEND_API zend_string *zend_get_callable_name(const zval *callable); ZEND_API bool zend_is_callable_at_frame( - zval *callable, zend_object *object, zend_execute_data *frame, + const zval *callable, zend_object *object, const zend_execute_data *frame, uint32_t check_flags, zend_fcall_info_cache *fcc, char **error); -ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error); -ZEND_API bool zend_is_callable(zval *callable, uint32_t check_flags, zend_string **callable_name); -ZEND_API bool zend_make_callable(zval *callable, zend_string **callable_name); +ZEND_API bool zend_is_callable_ex(const zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error); +ZEND_API bool zend_is_callable(const zval *callable, uint32_t check_flags, zend_string **callable_name); ZEND_API const char *zend_get_module_version(const char *module_name); ZEND_API zend_result zend_get_module_started(const char *module_name); @@ -446,12 +446,12 @@ ZEND_API void zend_declare_class_constant_string(zend_class_entry *ce, const cha ZEND_API zend_result zend_update_class_constant(zend_class_constant *c, const zend_string *name, zend_class_entry *scope); ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type); -ZEND_API HashTable *zend_separate_class_constants_table(zend_class_entry *class_type); +ZEND_API HashTable *zend_separate_class_constants_table(const zend_class_entry *class_type); -static zend_always_inline HashTable *zend_class_constants_table(zend_class_entry *ce) { +static zend_always_inline const HashTable *zend_class_constants_table(const zend_class_entry *ce) { if ((ce->ce_flags & ZEND_ACC_HAS_AST_CONSTANTS) && ZEND_MAP_PTR(ce->mutable_data)) { - zend_class_mutable_data *mutable_data = - (zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); + const zend_class_mutable_data *mutable_data = + (const zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); if (mutable_data && mutable_data->constants_table) { return mutable_data->constants_table; } else { @@ -462,10 +462,10 @@ static zend_always_inline HashTable *zend_class_constants_table(zend_class_entry } } -static zend_always_inline zval *zend_class_default_properties_table(zend_class_entry *ce) { +static zend_always_inline zval *zend_class_default_properties_table(const zend_class_entry *ce) { if ((ce->ce_flags & ZEND_ACC_HAS_AST_PROPERTIES) && ZEND_MAP_PTR(ce->mutable_data)) { - zend_class_mutable_data *mutable_data = - (zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); + const zend_class_mutable_data *mutable_data = + (const zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); return mutable_data->default_properties_table; } else { return ce->default_properties_table; @@ -482,26 +482,26 @@ static zend_always_inline void zend_class_set_backed_enum_table(zend_class_entry } } -static zend_always_inline HashTable *zend_class_backed_enum_table(zend_class_entry *ce) +static zend_always_inline HashTable *zend_class_backed_enum_table(const zend_class_entry *ce) { if (ZEND_MAP_PTR(ce->mutable_data) && ce->type == ZEND_USER_CLASS) { - zend_class_mutable_data *mutable_data = (zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); + const zend_class_mutable_data *mutable_data = (const zend_class_mutable_data*)ZEND_MAP_PTR_GET_IMM(ce->mutable_data); return mutable_data->backed_enum_table; } else { return ce->backed_enum_table; } } -ZEND_API void zend_update_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, zval *value); -ZEND_API void zend_update_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value); -ZEND_API void zend_update_property_null(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); -ZEND_API void zend_update_property_bool(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); -ZEND_API void zend_update_property_long(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); -ZEND_API void zend_update_property_double(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value); -ZEND_API void zend_update_property_str(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value); -ZEND_API void zend_update_property_string(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value); -ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_length); -ZEND_API void zend_unset_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); +ZEND_API void zend_update_property_ex(const zend_class_entry *scope, zend_object *object, zend_string *name, zval *value); +ZEND_API void zend_update_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zval *value); +ZEND_API void zend_update_property_null(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); +ZEND_API void zend_update_property_bool(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); +ZEND_API void zend_update_property_long(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_long value); +ZEND_API void zend_update_property_double(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, double value); +ZEND_API void zend_update_property_str(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, zend_string *value); +ZEND_API void zend_update_property_string(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value); +ZEND_API void zend_update_property_stringl(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, const char *value, size_t value_length); +ZEND_API void zend_unset_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length); ZEND_API zend_result zend_update_static_property_ex(zend_class_entry *scope, zend_string *name, zval *value); ZEND_API zend_result zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value); @@ -512,8 +512,8 @@ ZEND_API zend_result zend_update_static_property_double(zend_class_entry *scope, ZEND_API zend_result zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value); ZEND_API zend_result zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_length); -ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv); -ZEND_API zval *zend_read_property(zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, bool silent, zval *rv); +ZEND_API zval *zend_read_property_ex(const zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv); +ZEND_API zval *zend_read_property(const zend_class_entry *scope, zend_object *object, const char *name, size_t name_length, bool silent, zval *rv); ZEND_API zval *zend_read_static_property_ex(zend_class_entry *scope, zend_string *name, bool silent); ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, bool silent); @@ -526,25 +526,31 @@ ZEND_API const char *zend_get_type_by_const(int type); #define getThis() (hasThis() ? ZEND_THIS : NULL) #define ZEND_IS_METHOD_CALL() (EX(func)->common.scope != NULL) -#define WRONG_PARAM_COUNT ZEND_WRONG_PARAM_COUNT() #define ZEND_NUM_ARGS() EX_NUM_ARGS() -#define ZEND_WRONG_PARAM_COUNT() { zend_wrong_param_count(); return; } #ifndef ZEND_WIN32 #define DLEXPORT #endif -#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0)) -#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size)) +static zend_always_inline void array_init_size(zval *arg, uint32_t size) +{ + ZVAL_ARR(arg, zend_new_array(size)); +} + +static zend_always_inline void array_init(zval *arg) +{ + array_init_size(arg, 0); +} + ZEND_API void object_init(zval *arg); ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *ce); ZEND_API zend_result object_init_with_constructor(zval *arg, zend_class_entry *class_type, uint32_t param_count, zval *params, HashTable *named_params); ZEND_API zend_result object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties); ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type); ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properties); -ZEND_API void object_properties_load(zend_object *object, HashTable *properties); +ZEND_API void object_properties_load(zend_object *object, const HashTable *properties); -ZEND_API void zend_merge_properties(zval *obj, HashTable *properties); +ZEND_API void zend_merge_properties(const zval *obj, const HashTable *properties); ZEND_API void add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n); ZEND_API void add_assoc_null_ex(zval *arg, const char *key, size_t key_len); @@ -694,8 +700,8 @@ ZEND_API zend_result _call_user_function_impl(zval *object, zval *function_name, # define empty_fcall_info (zend_fcall_info) {0} # define empty_fcall_info_cache (zend_fcall_info_cache) {0} #else -# define empty_fcall_info zend_fcall_info {0} -# define empty_fcall_info_cache zend_fcall_info_cache {0} +# define empty_fcall_info zend_fcall_info {} +# define empty_fcall_info_cache zend_fcall_info_cache {} #endif /** Build zend_call_info/cache from a zval* @@ -706,7 +712,7 @@ ZEND_API zend_result _call_user_function_impl(zval *object, zval *function_name, * fci->params = NULL; * The callable_name argument may be NULL. */ -ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error); +ZEND_API zend_result zend_fcall_info_init(const zval *callable, uint32_t check_flags, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_string **callable_name, char **error); /** Clear arguments connected with zend_fcall_info *fci * If free_mem is not zero then the params array gets free'd as well @@ -887,8 +893,6 @@ ZEND_API zend_result zend_call_method_if_exists( zend_object *object, zend_string *method_name, zval *retval, uint32_t param_count, zval *params); -ZEND_API zend_result zend_set_hash_symbol(zval *symbol, const char *name, size_t name_length, bool is_ref, int num_symbol_tables, ...); - ZEND_API zend_result zend_delete_global_variable(zend_string *name); ZEND_API zend_array *zend_rebuild_symbol_table(void); @@ -899,9 +903,11 @@ ZEND_API zend_result zend_set_local_var_str(const char *name, size_t len, zval * static zend_always_inline zend_result zend_forbid_dynamic_call(void) { - zend_execute_data *ex = EG(current_execute_data); + const zend_execute_data *ex = EG(current_execute_data); ZEND_ASSERT(ex != NULL && ex->func != NULL); + ZEND_ASSERT(ex->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS); + if (ZEND_CALL_INFO(ex) & ZEND_CALL_DYNAMIC) { zend_string *function_or_method_name = get_active_function_or_method_name(); zend_throw_error(NULL, "Cannot call %.*s() dynamically", @@ -929,8 +935,12 @@ ZEND_API bool zend_is_iterable(const zval *iterable); ZEND_API bool zend_is_countable(const zval *countable); +ZEND_API void zend_convert_internal_arg_info(zend_arg_info *new_arg_info, + const zend_internal_arg_info *arg_info, bool is_return_info, + bool permanent); + ZEND_API zend_result zend_get_default_from_internal_arg_info( - zval *default_value_zval, zend_internal_arg_info *arg_info); + zval *default_value_zval, const zend_arg_info *arg_info); END_EXTERN_C() @@ -950,10 +960,6 @@ static zend_always_inline bool zend_char_has_nul_byte(const char *s, size_t know return known_length != strlen(s); } -/* Compatibility with PHP 8.1 and below */ -#define CHECK_ZVAL_NULL_PATH(p) zend_str_has_nul_byte(Z_STR_P(p)) -#define CHECK_NULL_PATH(p, l) zend_char_has_nul_byte(p, l) - #define ZVAL_STRINGL(z, s, l) do { \ ZVAL_NEW_STR(z, zend_string_init(s, l, 0)); \ } while (0) @@ -1065,7 +1071,6 @@ static zend_always_inline bool zend_char_has_nul_byte(const char *s, size_t know #define RETURN_THROWS() do { ZEND_ASSERT(EG(exception)); (void) return_value; return; } while (0) #define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties(Z_OBJ_P(p)) : NULL))) -#define ZVAL_IS_NULL(z) (Z_TYPE_P(z) == IS_NULL) /* For compatibility */ #define ZEND_MINIT ZEND_MODULE_STARTUP_N @@ -1363,6 +1368,7 @@ ZEND_API zend_result zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval #define ZEND_TRY_ASSIGN_REF_ARR(zv, arr) do { \ ZEND_ASSERT(Z_ISREF_P(zv)); \ + ZEND_ASSERT(!(GC_FLAGS(arr) & GC_IMMUTABLE)); \ _ZEND_TRY_ASSIGN_ARR(zv, arr, 1); \ } while (0) @@ -1555,14 +1561,14 @@ typedef enum _zend_expected_type { ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_none_error(void); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(uint32_t min_num_args, uint32_t max_num_args); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, uint32_t num, char *name, zend_expected_type expected_type, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_null_error(uint32_t num, const char *name, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, uint32_t num, char *name, zend_expected_type expected_type, const zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, const zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, const zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, const zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, const zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, const zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, const zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_null_error(uint32_t num, const char *name, const zval *arg); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_or_null_error(uint32_t num, char *error); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void); @@ -1571,8 +1577,8 @@ ZEND_API ZEND_COLD void zend_argument_error(zend_class_entry *error_ce, uint32_t ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format, ...); ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num); -ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, zend_class_entry *old_ce); -ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, zend_class_entry *old_ce); +ZEND_API ZEND_COLD void zend_class_redeclaration_error(int type, const zend_class_entry *old_ce); +ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string *new_name, const zend_class_entry *old_ce); #define ZPP_ERROR_OK 0 #define ZPP_ERROR_FAILURE 1 @@ -2016,6 +2022,13 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string #define Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(dest_obj, _ce, dest_long, is_null) \ Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, 1) +#define Z_PARAM_ENUM(dest, _ce) \ + { \ + zend_object *_tmp = NULL; \ + Z_PARAM_OBJ_OF_CLASS(_tmp, _ce); \ + dest = zend_enum_fetch_case_id(_tmp); \ + } + /* old "p" */ #define Z_PARAM_PATH_EX(dest, dest_len, check_null, deref) \ Z_PARAM_PROLOGUE(deref, 0); \ @@ -2174,21 +2187,27 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string /* Inlined implementations shared by new and old parameter parsing APIs */ +typedef enum zpp_parse_bool_status { + ZPP_PARSE_BOOL_STATUS_FALSE = 0, + ZPP_PARSE_BOOL_STATUS_TRUE = 1, + ZPP_PARSE_BOOL_STATUS_ERROR = 2, +} zpp_parse_bool_status; + ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, uint32_t num, bool check_null); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest, uint32_t arg_num); +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_slow(const zval *arg, uint32_t arg_num); +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num); +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, uint32_t arg_num); +ZEND_API double ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, uint32_t arg_num); +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num); +ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num); -ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num); +ZEND_API zpp_parse_bool_status ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, uint32_t arg_num); +ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num); ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num); static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num, bool frameless) @@ -2204,11 +2223,16 @@ static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *des *is_null = 1; *dest = 0; } else { + zpp_parse_bool_status result; if (frameless) { - return zend_flf_parse_arg_bool_slow(arg, dest, arg_num); + result = zend_flf_parse_arg_bool_slow(arg, arg_num); } else { - return zend_parse_arg_bool_slow(arg, dest, arg_num); + result = zend_parse_arg_bool_slow(arg, arg_num); + } + if (UNEXPECTED(result == ZPP_PARSE_BOOL_STATUS_ERROR)) { + return false; } + *dest = result; } return 1; } @@ -2254,7 +2278,8 @@ static zend_always_inline bool zend_parse_arg_double(const zval *arg, double *de *is_null = 1; *dest = 0.0; } else { - return zend_parse_arg_double_slow(arg, dest, arg_num); + *dest = zend_parse_arg_double_slow(arg, arg_num); + return !zend_isnan(*dest); } return 1; } @@ -2291,12 +2316,13 @@ static zend_always_inline bool zend_parse_arg_str_ex(zval *arg, zend_string **de *dest = NULL; } else { if (frameless) { - return zend_flf_parse_arg_str_slow(arg, dest, arg_num); + *dest = zend_flf_parse_arg_str_slow(arg, arg_num); } else { - return zend_parse_arg_str_slow(arg, dest, arg_num); + *dest = zend_parse_arg_str_slow(arg, arg_num); } + return *dest != NULL; } - return 1; + return true; } static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num) @@ -2324,7 +2350,7 @@ static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, siz static zend_always_inline bool zend_parse_arg_path_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num) { if (!zend_parse_arg_str(arg, dest, check_null, arg_num) || - (*dest && UNEXPECTED(CHECK_NULL_PATH(ZSTR_VAL(*dest), ZSTR_LEN(*dest))))) { + (*dest && UNEXPECTED(zend_str_has_nul_byte(*dest)))) { return 0; } return 1; @@ -2482,7 +2508,7 @@ static zend_always_inline bool zend_parse_arg_resource(zval *arg, zval **dest, b return 1; } -static zend_always_inline bool zend_parse_arg_func(zval *arg, zend_fcall_info *dest_fci, zend_fcall_info_cache *dest_fcc, bool check_null, char **error, bool free_trampoline) +static zend_always_inline bool zend_parse_arg_func(const zval *arg, zend_fcall_info *dest_fci, zend_fcall_info_cache *dest_fcc, bool check_null, char **error, bool free_trampoline) { if (check_null && UNEXPECTED(Z_TYPE_P(arg) == IS_NULL)) { dest_fci->size = 0; @@ -2527,7 +2553,8 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_str( *dest_str = NULL; } else { *dest_ht = NULL; - return zend_parse_arg_str_slow(arg, dest_str, arg_num); + *dest_str = zend_parse_arg_str_slow(arg, arg_num); + return *dest_str != NULL; } return 1; } diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index f2f801db6339..942a8b8e1309 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -317,7 +316,9 @@ struct _zend_mm_heap { } debug; }; #endif +#if ZEND_DEBUG pid_t pid; +#endif zend_random_bytes_insecure_state rand_state; }; @@ -377,24 +378,6 @@ static const uint32_t bin_pages[] = { ZEND_MM_BINS_INFO(_BIN_DATA_PAGES, x, y) }; -#if ZEND_DEBUG -ZEND_COLD void zend_debug_alloc_output(char *format, ...) -{ - char output_buf[256]; - va_list args; - - va_start(args, format); - vsprintf(output_buf, format, args); - va_end(args); - -#ifdef ZEND_WIN32 - OutputDebugString(output_buf); -#else - fprintf(stderr, "%s", output_buf); -#endif -} -#endif - static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message) { fprintf(stderr, "%s\n", message); @@ -1310,15 +1293,20 @@ static zend_always_inline zend_mm_free_slot* zend_mm_encode_free_slot(const zend #endif } -static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot) +static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot_key(uintptr_t shadow_key, zend_mm_free_slot *slot) { #ifdef WORDS_BIGENDIAN - return (zend_mm_free_slot*)((uintptr_t)slot ^ heap->shadow_key); + return (zend_mm_free_slot*)((uintptr_t)slot ^ shadow_key); #else - return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ heap->shadow_key)); + return (zend_mm_free_slot*)(BSWAPPTR((uintptr_t)slot ^ shadow_key)); #endif } +static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_heap *heap, zend_mm_free_slot *slot) +{ + return zend_mm_decode_free_slot_key(heap->shadow_key, slot); +} + static zend_always_inline void zend_mm_set_next_free_slot(zend_mm_heap *heap, uint32_t bin_num, zend_mm_free_slot *slot, zend_mm_free_slot *next) { ZEND_ASSERT(bin_data_size[bin_num] >= ZEND_MM_MIN_USEABLE_BIN_SIZE); @@ -1491,7 +1479,6 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)); if (UNEXPECTED(size < real_size)) { zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info))); - return NULL; } #endif if (EXPECTED(size <= ZEND_MM_MAX_SMALL_SIZE)) { @@ -2027,6 +2014,34 @@ static void zend_mm_init_key(zend_mm_heap *heap) zend_mm_refresh_key(heap); } +ZEND_API void zend_mm_refresh_key_child(zend_mm_heap *heap) +{ + uintptr_t old_key = heap->shadow_key; + + zend_mm_init_key(heap); + + /* Update shadow pointers with new key */ + for (int i = 0; i < ZEND_MM_BINS; i++) { + zend_mm_free_slot *slot = heap->free_slot[i]; + if (!slot) { + continue; + } + zend_mm_free_slot *next; + while ((next = slot->next_free_slot)) { + zend_mm_free_slot *shadow = ZEND_MM_FREE_SLOT_PTR_SHADOW(slot, i); + if (UNEXPECTED(next != zend_mm_decode_free_slot_key(old_key, shadow))) { + zend_mm_panic("zend_mm_heap corrupted"); + } + zend_mm_set_next_free_slot(heap, i, slot, next); + slot = next; + } + } + +#if ZEND_DEBUG + heap->pid = getpid(); +#endif +} + static zend_mm_heap *zend_mm_init(void) { zend_mm_chunk *chunk = (zend_mm_chunk*)zend_mm_chunk_alloc_int(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE); @@ -2075,7 +2090,9 @@ static zend_mm_heap *zend_mm_init(void) heap->storage = NULL; #endif heap->huge_list = NULL; +#if ZEND_DEBUG heap->pid = getpid(); +#endif return heap; } @@ -2535,13 +2552,12 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent) p->free_map[0] = (1L << ZEND_MM_FIRST_PAGE) - 1; p->map[0] = ZEND_MM_LRUN(ZEND_MM_FIRST_PAGE); - pid_t pid = getpid(); - if (heap->pid != pid) { - zend_mm_init_key(heap); - heap->pid = pid; - } else { - zend_mm_refresh_key(heap); - } +#if ZEND_DEBUG + ZEND_ASSERT(getpid() == heap->pid + && "heap was re-used without calling zend_mm_refresh_key_child() after a fork"); +#endif + + zend_mm_refresh_key(heap); } } @@ -2609,7 +2625,7 @@ ZEND_API bool is_zend_mm(void) #if ZEND_MM_CUSTOM return !AG(mm_heap)->use_custom_heap; #else - return 1; + return true; #endif } @@ -2949,6 +2965,11 @@ ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown) zend_mm_shutdown(AG(mm_heap), full_shutdown, silent); } +ZEND_API void refresh_memory_manager(void) +{ + zend_mm_refresh_key_child(AG(mm_heap)); +} + static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void) { fprintf(stderr, "Out of memory\n"); @@ -3443,12 +3464,14 @@ ZEND_API zend_mm_heap *zend_mm_startup(void) ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void *data, size_t data_size) { #if ZEND_MM_STORAGE - zend_mm_storage tmp_storage, *storage; + zend_mm_storage *storage; + zend_mm_storage tmp_storage = { + .handlers = *handlers, + .data = data, + }; zend_mm_chunk *chunk; zend_mm_heap *heap; - memcpy((zend_mm_handlers*)&tmp_storage.handlers, handlers, sizeof(zend_mm_handlers)); - tmp_storage.data = data; chunk = (zend_mm_chunk*)handlers->chunk_alloc(&tmp_storage, ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE); if (UNEXPECTED(chunk == NULL)) { #if ZEND_MM_ERROR @@ -3506,7 +3529,9 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void memcpy(storage->data, data, data_size); } heap->storage = storage; +#if ZEND_DEBUG heap->pid = getpid(); +#endif return heap; #else return NULL; diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 541989a2a13e..ff51c4fe8652 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -220,6 +219,7 @@ ZEND_API bool zend_alloc_in_memory_limit_error_reporting(void); ZEND_API void start_memory_manager(void); ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown); +ZEND_API void refresh_memory_manager(void); ZEND_API bool is_zend_mm(void); ZEND_API bool is_zend_ptr(const void *ptr); @@ -316,6 +316,8 @@ struct _zend_mm_storage { ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap); ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void *data, size_t data_size); +ZEND_API void zend_mm_refresh_key_child(zend_mm_heap *heap); + /* // The following example shows how to use zend_mm_heap API with custom storage diff --git a/Zend/zend_alloc_sizes.h b/Zend/zend_alloc_sizes.h index 502b982a5052..f806056ad9d3 100644 --- a/Zend/zend_alloc_sizes.h +++ b/Zend/zend_alloc_sizes.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/zend_arena.h b/Zend/zend_arena.h index 37cda28f29db..9b917a47e927 100644 --- a/Zend/zend_arena.h +++ b/Zend/zend_arena.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index cdc86faa95aa..8282d33ecbe6 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bob Weinand | | Dmitry Stogov | @@ -33,7 +32,7 @@ static inline void *zend_ast_alloc(size_t size) { return zend_arena_alloc(&CG(ast_arena), size); } -static inline void *zend_ast_realloc(void *old, size_t old_size, size_t new_size) { +static inline void *zend_ast_realloc(const void *old, size_t old_size, size_t new_size) { void *new = zend_ast_alloc(new_size); memcpy(new, old, old_size); return new; @@ -43,7 +42,7 @@ static inline size_t zend_ast_list_size(uint32_t children) { return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(const znode *node) { zend_ast_znode *ast; ast = zend_ast_alloc(sizeof(zend_ast_znode)); @@ -54,19 +53,20 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) { return (zend_ast *) ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(void) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(zend_ast *args) { zend_ast_fcc *ast; ast = zend_ast_alloc(sizeof(zend_ast_fcc)); ast->kind = ZEND_AST_CALLABLE_CONVERT; ast->attr = 0; ast->lineno = CG(zend_lineno); + ast->args = args; ZEND_MAP_PTR_INIT(ast->fptr, NULL); return (zend_ast *) ast; } -static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) { +static zend_always_inline zend_ast * zend_ast_create_zval_int(const zval *zv, uint32_t attr, uint32_t lineno) { zend_ast_zval *ast; ast = zend_ast_alloc(sizeof(zend_ast_zval)); @@ -77,15 +77,15 @@ static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t return (zend_ast *) ast; } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(const zval *zv, uint32_t lineno) { return zend_ast_create_zval_int(zv, 0, lineno); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(const zval *zv, zend_ast_attr attr) { return zend_ast_create_zval_int(zv, attr, CG(zend_lineno)); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) { +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(const zval *zv) { return zend_ast_create_zval_int(zv, 0, CG(zend_lineno)); } @@ -136,7 +136,8 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast * ZEND_API zend_ast *zend_ast_create_decl( zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, - zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4 + zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, + zend_ast *child4, zend_ast *child5 ) { zend_ast_decl *ast; @@ -153,10 +154,17 @@ ZEND_API zend_ast *zend_ast_create_decl( ast->child[2] = child2; ast->child[3] = child3; ast->child[4] = child4; + ast->child[5] = child5; return (zend_ast *) ast; } +static bool zend_ast_is_placeholder_arg(zend_ast *arg) { + return arg->kind == ZEND_AST_PLACEHOLDER_ARG + || (arg->kind == ZEND_AST_NAMED_ARG + && arg->child[1]->kind == ZEND_AST_PLACEHOLDER_ARG); +} + #if ZEND_AST_SPEC ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) { zend_ast *ast; @@ -400,6 +408,30 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zen return ast; } + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_0(zend_ast_kind kind) { + return zend_ast_create_list(0, kind); +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_1(zend_ast_kind kind, zend_ast *arg) { + zend_ast *list = zend_ast_create_list(1, kind, arg); + + if (zend_ast_is_placeholder_arg(arg)) { + return zend_ast_create_fcc(list); + } + + return list; +} + +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_2(zend_ast_kind kind, zend_ast *arg1, zend_ast *arg2) { + zend_ast *list = zend_ast_create_list(2, kind, arg1, arg2); + + if (zend_ast_is_placeholder_arg(arg1) || zend_ast_is_placeholder_arg(arg2)) { + return zend_ast_create_fcc(list); + } + + return list; +} #else static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) { uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT; @@ -479,6 +511,41 @@ ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind ki return ast; } + +ZEND_API zend_ast *zend_ast_create_arg_list(uint32_t init_children, zend_ast_kind kind, ...) { + zend_ast *ast; + zend_ast_list *list; + bool has_placeholders = false; + + ast = zend_ast_alloc(zend_ast_list_size(4)); + list = (zend_ast_list *) ast; + list->kind = kind; + list->attr = 0; + list->lineno = CG(zend_lineno); + list->children = 0; + + { + va_list va; + uint32_t i; + va_start(va, kind); + for (i = 0; i < init_children; ++i) { + zend_ast *child = va_arg(va, zend_ast *); + ast = zend_ast_list_add(ast, child); + uint32_t lineno = zend_ast_get_lineno(child); + if (lineno < ast->lineno) { + ast->lineno = lineno; + } + has_placeholders = has_placeholders || zend_ast_is_placeholder_arg(child); + } + va_end(va); + } + + if (has_placeholders) { + return zend_ast_create_fcc(list); + } + + return ast; +} #endif zend_ast *zend_ast_create_concat_op(zend_ast *op0, zend_ast *op1) { @@ -498,7 +565,7 @@ static inline bool is_power_of_two(uint32_t n) { return ((n != 0) && (n == (n & (~n + 1)))); } -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op) { +ZEND_ATTRIBUTE_NODISCARD ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op) { zend_ast_list *list = zend_ast_get_list(ast); if (list->children >= 4 && is_power_of_two(list->children)) { list = zend_ast_realloc(list, @@ -508,7 +575,24 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op) return (zend_ast *) list; } -static zend_result zend_ast_add_array_element(zval *result, zval *offset, zval *expr) +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_arg_list_add(zend_ast *list, zend_ast *arg) +{ + if (list->kind == ZEND_AST_CALLABLE_CONVERT) { + zend_ast_fcc *fcc_ast = (zend_ast_fcc*)list; + fcc_ast->args = zend_ast_list_add(fcc_ast->args, arg); + return (zend_ast*)fcc_ast; + } + + ZEND_ASSERT(list->kind == ZEND_AST_ARG_LIST); + + if (zend_ast_is_placeholder_arg(arg)) { + return zend_ast_create_fcc(zend_ast_list_add(list, arg)); + } + + return zend_ast_list_add(list, arg); +} + +static zend_result zend_ast_add_array_element(const zval *result, zval *offset, zval *expr) { if (Z_TYPE_P(offset) == IS_UNDEF) { if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), expr)) { @@ -528,9 +612,9 @@ static zend_result zend_ast_add_array_element(zval *result, zval *offset, zval * return SUCCESS; } -static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) { +static zend_result zend_ast_add_unpacked_element(const zval *result, const zval *expr) { if (EXPECTED(Z_TYPE_P(expr) == IS_ARRAY)) { - HashTable *ht = Z_ARRVAL_P(expr); + const HashTable *ht = Z_ARRVAL_P(expr); zval *val; zend_string *key; @@ -558,7 +642,7 @@ static zend_class_entry *zend_ast_fetch_class(zend_ast *ast, zend_class_entry *s return zend_fetch_class_with_scope(zend_ast_get_str(ast), (ast->attr >> ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT) | ZEND_FETCH_CLASS_EXCEPTION, scope); } -ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( +static zend_result ZEND_FASTCALL zend_ast_evaluate_inner( zval *result, zend_ast *ast, zend_class_entry *scope, @@ -589,7 +673,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex( return r; } -ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( +static zend_result ZEND_FASTCALL zend_ast_evaluate_inner( zval *result, zend_ast *ast, zend_class_entry *scope, @@ -610,9 +694,10 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( ret = FAILURE; } else { binary_op_type op = get_binary_op(ast->attr); - ret = op(result, &op1, &op2); + op(result, &op1, &op2); zval_ptr_dtor_nogc(&op1); zval_ptr_dtor_nogc(&op2); + ret = EG(exception) ? FAILURE : SUCCESS; } break; case ZEND_AST_GREATER: @@ -730,7 +815,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( case IS_OBJECT: zend_cast_zval_to_object(result, &op1, IS_VAR); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } zval_ptr_dtor_nogc(&op1); if (UNEXPECTED(EG(exception))) { @@ -911,10 +996,13 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( zend_ast *class_name_ast = ast->child[0]; zend_string *class_name = zend_ast_get_str(class_name_ast); - zend_ast *case_name_ast = ast->child[1]; + zend_ast *case_id_ast = ast->child[1]; + int case_id = (int)Z_LVAL_P(zend_ast_get_zval(case_id_ast)); + + zend_ast *case_name_ast = ast->child[2]; zend_string *case_name = zend_ast_get_str(case_name_ast); - zend_ast *case_value_ast = ast->child[2]; + zend_ast *case_value_ast = ast->child[3]; zval case_value_zv; ZVAL_UNDEF(&case_value_zv); @@ -925,7 +1013,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( } zend_class_entry *ce = zend_lookup_class(class_name); - zend_enum_new(result, ce, case_name, case_value_ast != NULL ? &case_value_zv : NULL); + zend_enum_new(result, ce, case_id, case_name, case_value_ast != NULL ? &case_value_zv : NULL); zval_ptr_dtor_nogc(&case_value_zv); break; } @@ -1054,10 +1142,22 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( case ZEND_AST_STATIC_CALL: { zend_function *fptr; + zend_class_entry *called_scope = NULL; + + zend_ast *args_ast = zend_ast_call_get_args(ast); + ZEND_ASSERT(args_ast->kind == ZEND_AST_CALLABLE_CONVERT); + + zend_ast_fcc *fcc_ast = (zend_ast_fcc*)args_ast; + + zend_ast_list *args = zend_ast_get_list(fcc_ast->args); + ZEND_ASSERT(args->children > 0); + if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) { + /* TODO: PFAs */ + zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations"); + } + switch (ast->kind) { case ZEND_AST_CALL: { - ZEND_ASSERT(ast->child[1]->kind == ZEND_AST_CALLABLE_CONVERT); - zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast->child[1]; fptr = ZEND_MAP_PTR_GET(fcc_ast->fptr); if (!fptr) { @@ -1082,37 +1182,29 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( break; } case ZEND_AST_STATIC_CALL: { - ZEND_ASSERT(ast->child[2]->kind == ZEND_AST_CALLABLE_CONVERT); - zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast->child[2]; + zend_class_entry *ce = zend_ast_fetch_class(ast->child[0], scope); + if (!ce) { + return FAILURE; + } + called_scope = ce; fptr = ZEND_MAP_PTR_GET(fcc_ast->fptr); if (!fptr) { - zend_class_entry *ce = zend_ast_fetch_class(ast->child[0], scope); - if (!ce) { - return FAILURE; - } zend_string *method_name = zend_ast_get_str(ast->child[1]); if (ce->get_static_method) { fptr = ce->get_static_method(ce, method_name); } else { fptr = zend_hash_find_ptr_lc(&ce->function_table, method_name); if (fptr) { - if (!(fptr->common.fn_flags & ZEND_ACC_PUBLIC)) { - if (UNEXPECTED(fptr->common.scope != scope)) { - if ( - UNEXPECTED(fptr->op_array.fn_flags & ZEND_ACC_PRIVATE) - || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fptr), scope)) - ) { - if (ce->__callstatic) { - zend_throw_error(NULL, "Creating a callable for the magic __callStatic() method is not supported in constant expressions"); - } else { - zend_bad_method_call(fptr, method_name, scope); - } - - return FAILURE; - } + if (!zend_check_method_accessible(fptr, scope)) { + if (ce->__callstatic) { + zend_throw_error(NULL, "Creating a callable for the magic __callStatic() method is not supported in constant expressions"); + } else { + zend_bad_method_call(fptr, method_name, scope); } + + return FAILURE; } } else { if (ce->__callstatic) { @@ -1127,12 +1219,12 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( if (!(fptr->common.fn_flags & ZEND_ACC_STATIC)) { zend_non_static_method_call(fptr); - + return FAILURE; } if ((fptr->common.fn_flags & ZEND_ACC_ABSTRACT)) { zend_abstract_method_call(fptr); - + return FAILURE; } else if (fptr->common.scope->ce_flags & ZEND_ACC_TRAIT) { zend_error(E_DEPRECATED, @@ -1149,14 +1241,21 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner( break; } + default: ZEND_UNREACHABLE(); } - zend_create_fake_closure(result, fptr, scope, scope, NULL); + zend_create_fake_closure(result, fptr, fptr->common.scope, called_scope, NULL); return SUCCESS; } case ZEND_AST_OP_ARRAY: { + // Preloading will attempt to resolve constants but objects can't be stored in shm + // Aborting here to store the const AST instead + if (CG(in_compilation)) { + return FAILURE; + } + zend_function *func = (zend_function *)zend_ast_get_op_array(ast)->op_array; zend_create_closure(result, func, scope, scope, NULL); @@ -1246,10 +1345,11 @@ static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast) } else if (ast->kind == ZEND_AST_OP_ARRAY) { size = sizeof(zend_ast_op_array); } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { - size = sizeof(zend_ast_fcc); + zend_ast *args_ast = ((zend_ast_fcc*)ast)->args; + size = sizeof(zend_ast_fcc) + zend_ast_tree_size(args_ast); } else if (zend_ast_is_list(ast)) { uint32_t i; - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); size = zend_ast_list_size(list->children); for (i = 0; i < list->children; i++) { @@ -1290,7 +1390,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) Z_LINENO(new->val) = zend_ast_get_lineno(ast); buf = (void*)((char*)buf + sizeof(zend_ast_zval)); } else if (zend_ast_is_list(ast)) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_ast_list *new = (zend_ast_list*)buf; uint32_t i; new->kind = list->kind; @@ -1307,7 +1407,7 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) } } } else if (ast->kind == ZEND_AST_OP_ARRAY) { - zend_ast_op_array *old = zend_ast_get_op_array(ast); + const zend_ast_op_array *old = zend_ast_get_op_array(ast); zend_ast_op_array *new = (zend_ast_op_array*)buf; new->kind = old->kind; new->attr = old->attr; @@ -1316,13 +1416,15 @@ static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf) function_add_ref((zend_function *)new->op_array); buf = (void*)((char*)buf + sizeof(zend_ast_op_array)); } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { - zend_ast_fcc *old = (zend_ast_fcc*)ast; + const zend_ast_fcc *old = (zend_ast_fcc*)ast; zend_ast_fcc *new = (zend_ast_fcc*)buf; new->kind = old->kind; new->attr = old->attr; new->lineno = old->lineno; ZEND_MAP_PTR_INIT(new->fptr, ZEND_MAP_PTR(old->fptr)); buf = (void*)((char*)buf + sizeof(zend_ast_fcc)); + new->args = buf; + buf = zend_ast_tree_copy(old->args, buf); } else if (zend_ast_is_decl(ast)) { /* Not implemented. */ ZEND_UNREACHABLE(); @@ -1377,7 +1479,7 @@ ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast) } else if (EXPECTED(ast->kind == ZEND_AST_ZVAL)) { zval_ptr_dtor_nogc(zend_ast_get_zval(ast)); } else if (EXPECTED(zend_ast_is_list(ast))) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); if (list->children) { uint32_t i; @@ -1392,7 +1494,7 @@ ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast) } else if (EXPECTED(ast->kind == ZEND_AST_OP_ARRAY)) { destroy_op_array(zend_ast_get_op_array(ast)->op_array); } else if (EXPECTED(zend_ast_is_decl(ast))) { - zend_ast_decl *decl = (zend_ast_decl *) ast; + const zend_ast_decl *decl = (const zend_ast_decl *) ast; if (decl->name) { zend_string_release_ex(decl->name, 0); @@ -1404,7 +1506,13 @@ ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast) zend_ast_destroy(decl->child[1]); zend_ast_destroy(decl->child[2]); zend_ast_destroy(decl->child[3]); - ast = decl->child[4]; + zend_ast_destroy(decl->child[4]); + ast = decl->child[5]; + goto tail_call; + } else if (EXPECTED(ast->kind == ZEND_AST_CALLABLE_CONVERT)) { + zend_ast_fcc *fcc_ast = (zend_ast_fcc*) ast; + + ast = fcc_ast->args; goto tail_call; } } @@ -1471,7 +1579,7 @@ ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn, void *contex static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent); -static ZEND_COLD void zend_ast_export_str(smart_str *str, zend_string *s) +static ZEND_COLD void zend_ast_export_str(smart_str *str, const zend_string *s) { size_t i; @@ -1486,7 +1594,7 @@ static ZEND_COLD void zend_ast_export_str(smart_str *str, zend_string *s) } } -static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, zend_string *s) +static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, const zend_string *s) { size_t i; @@ -1542,7 +1650,7 @@ static ZEND_COLD void zend_ast_export_indent(smart_str *str, int indent) static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int priority, int indent) { if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); if (Z_TYPE_P(zv) == IS_STRING) { smart_str_append(str, Z_STR_P(zv)); @@ -1555,7 +1663,7 @@ static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int pr static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int priority, int indent) { if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); if (Z_TYPE_P(zv) == IS_STRING) { if (ast->attr == ZEND_NAME_FQ) { @@ -1578,9 +1686,9 @@ static ZEND_COLD bool zend_ast_valid_var_char(char ch) (c < '0' || c > '9') && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) { - return 0; + return false; } - return 1; + return true; } static ZEND_COLD bool zend_ast_valid_var_name(const char *s, size_t len) @@ -1589,13 +1697,13 @@ static ZEND_COLD bool zend_ast_valid_var_name(const char *s, size_t len) size_t i; if (len == 0) { - return 0; + return false; } c = (unsigned char)s[0]; if (c != '_' && c < 127 && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) { - return 0; + return false; } for (i = 1; i < len; i++) { c = (unsigned char)s[i]; @@ -1603,10 +1711,10 @@ static ZEND_COLD bool zend_ast_valid_var_name(const char *s, size_t len) (c < '0' || c > '9') && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) { - return 0; + return false; } } - return 1; + return true; } static ZEND_COLD bool zend_ast_var_needs_braces(char ch) @@ -1614,7 +1722,7 @@ static ZEND_COLD bool zend_ast_var_needs_braces(char ch) return ch == '[' || zend_ast_valid_var_char(ch); } -static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int priority, int indent) +static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int indent) { if (ast->kind == ZEND_AST_ZVAL) { zval *zv = zend_ast_get_zval(ast); @@ -1634,7 +1742,7 @@ static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int pri /* Use zend_ast_export_list() unless fewer than `list->children` children should * be exported. */ -static ZEND_COLD void zend_ast_export_list_ex(smart_str *str, zend_ast_list *list, bool separator, int priority, int indent, int children) +static ZEND_COLD void zend_ast_export_list_ex(smart_str *str, const zend_ast_list *list, bool separator, int priority, int indent, uint32_t children) { ZEND_ASSERT(children <= list->children); uint32_t i = 0; @@ -1648,12 +1756,12 @@ static ZEND_COLD void zend_ast_export_list_ex(smart_str *str, zend_ast_list *lis } } -static ZEND_COLD void zend_ast_export_list(smart_str *str, zend_ast_list *list, bool separator, int priority, int indent) +static ZEND_COLD void zend_ast_export_list(smart_str *str, const zend_ast_list *list, bool separator, int priority, int indent) { zend_ast_export_list_ex(str, list, separator, priority, indent, list->children); } -static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, zend_ast_list *list, int indent) +static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, const zend_ast_list *list, int indent) { uint32_t i = 0; zend_ast *ast; @@ -1661,7 +1769,7 @@ static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, ze while (i < list->children) { ast = list->child[i]; if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); zend_ast_export_qstr(str, quote, Z_STR_P(zv)); @@ -1682,7 +1790,7 @@ static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, ze } } -static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list *list, int indent, const char *separator) +static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, const zend_ast_list *list, int indent, const char *separator) { uint32_t i = 0; @@ -1698,7 +1806,7 @@ static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list #define zend_ast_export_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, ", ") #define zend_ast_export_catch_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, "|") -static ZEND_COLD void zend_ast_export_var_list(smart_str *str, zend_ast_list *list, int indent) +static ZEND_COLD void zend_ast_export_var_list(smart_str *str, const zend_ast_list *list, int indent) { uint32_t i = 0; @@ -1723,7 +1831,7 @@ static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int in if (ast->kind == ZEND_AST_STMT_LIST || ast->kind == ZEND_AST_TRAIT_ADAPTATIONS) { - zend_ast_list *list = (zend_ast_list*)ast; + const zend_ast_list *list = (const zend_ast_list*)ast; uint32_t i = 0; while (i < list->children) { @@ -1750,8 +1858,8 @@ static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int in case ZEND_AST_DECLARE: break; case ZEND_AST_PROP_GROUP: { - zend_ast *first_prop = zend_ast_get_list(ast->child[1])->child[0]; - zend_ast *hook_list = first_prop->child[3]; + const zend_ast *first_prop = zend_ast_get_list(ast->child[1])->child[0]; + const zend_ast *hook_list = first_prop->child[3]; if (hook_list == NULL) { smart_str_appendc(str, ';'); } @@ -1765,7 +1873,7 @@ static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int in } } -static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *list, int indent) +static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, const zend_ast_list *list, int indent) { uint32_t i; zend_ast *ast; @@ -1789,7 +1897,7 @@ static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *lis zend_ast_export_indent(str, indent); smart_str_appends(str, "} else "); if (ast->child[1] && ast->child[1]->kind == ZEND_AST_IF) { - list = (zend_ast_list*)ast->child[1]; + list = (const zend_ast_list*)ast->child[1]; goto tail_call; } else { smart_str_appends(str, "{\n"); @@ -1802,7 +1910,7 @@ static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *lis smart_str_appendc(str, '}'); } -static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int indent) +static ZEND_COLD void zend_ast_export_zval(smart_str *str, const zval *zv, int priority, int indent) { ZVAL_DEREF(zv); switch (Z_TYPE_P(zv)) { @@ -1855,11 +1963,11 @@ static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priorit case IS_CONSTANT_AST: zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } -static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_decl *decl, int indent) { +static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, const zend_ast_decl *decl, int indent) { if (decl->child[0]) { smart_str_appends(str, " extends "); zend_ast_export_ns_name(str, decl->child[0], 0, indent); @@ -1875,9 +1983,9 @@ static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_d } static ZEND_COLD void zend_ast_export_attribute_group(smart_str *str, zend_ast *ast, int indent) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); for (uint32_t i = 0; i < list->children; i++) { - zend_ast *attr = list->child[i]; + const zend_ast *attr = list->child[i]; if (i) { smart_str_appends(str, ", "); @@ -1893,7 +2001,7 @@ static ZEND_COLD void zend_ast_export_attribute_group(smart_str *str, zend_ast * } static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, bool newlines) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; i++) { @@ -1930,9 +2038,11 @@ static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags, } } +static ZEND_COLD void zend_ast_export_generic_type_argument_list(smart_str *str, zend_ast *list_ast, int indent); + static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) { if (ast->kind == ZEND_AST_TYPE_UNION) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); for (uint32_t i = 0; i < list->children; i++) { if (i != 0) { smart_str_appendc(str, '|'); @@ -1942,7 +2052,7 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in return; } if (ast->kind == ZEND_AST_TYPE_INTERSECTION) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); for (uint32_t i = 0; i < list->children; i++) { if (i != 0) { smart_str_appendc(str, '&'); @@ -1951,13 +2061,89 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in } return; } + if (ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + if (ast->attr & ZEND_TYPE_NULLABLE) { + smart_str_appendc(str, '?'); + } + + zend_ast *name_ast = ast->child[0]; + if (name_ast->kind == ZEND_AST_TYPE) { + zend_ast_export_type(str, name_ast, indent); + } else { + zend_ast_export_ns_name(str, name_ast, 0, indent); + } + zend_ast_export_generic_type_argument_list(str, ast->child[1], indent); + return; + } if (ast->attr & ZEND_TYPE_NULLABLE) { smart_str_appendc(str, '?'); } zend_ast_export_ns_name(str, ast, 0, indent); } -static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *hook_list, int indent) +static ZEND_COLD void zend_ast_export_generic_type_argument_list(smart_str *str, zend_ast *list_ast, int indent) +{ + const zend_ast_list *list = zend_ast_get_list(list_ast); + smart_str_appendc(str, '<'); + for (uint32_t i = 0; i < list->children; i++) { + if (i != 0) { + smart_str_appends(str, ", "); + } + zend_ast_export_type(str, list->child[i], indent); + } + smart_str_appendc(str, '>'); +} + +static ZEND_COLD void zend_ast_export_generic_call_type_argument_list(smart_str *str, zend_ast *list_ast, int indent) +{ + const zend_ast_list *list = zend_ast_get_list(list_ast); + smart_str_appends(str, "::<"); + for (uint32_t i = 0; i < list->children; i++) { + if (i != 0) { + smart_str_appends(str, ", "); + } + zend_ast_export_type(str, list->child[i], indent); + } + smart_str_appendc(str, '>'); +} + +static ZEND_COLD void zend_ast_export_generic_type_parameter(smart_str *str, zend_ast *ast, int indent) +{ + switch ((zend_generic_variance) ast->attr) { + case ZEND_GENERIC_VARIANCE_COVARIANT: + smart_str_appendc(str, '+'); + break; + case ZEND_GENERIC_VARIANCE_CONTRAVARIANT: + smart_str_appendc(str, '-'); + break; + case ZEND_GENERIC_VARIANCE_INVARIANT: + break; + } + smart_str_append(str, zend_ast_get_str(ast->child[0])); + if (ast->child[1]) { + smart_str_appends(str, " : "); + zend_ast_export_type(str, ast->child[1], indent); + } + if (ast->child[2]) { + smart_str_appends(str, " = "); + zend_ast_export_type(str, ast->child[2], indent); + } +} + +static ZEND_COLD void zend_ast_export_generic_type_parameter_list(smart_str *str, zend_ast *list_ast, int indent) +{ + const zend_ast_list *list = zend_ast_get_list(list_ast); + smart_str_appendc(str, '<'); + for (uint32_t i = 0; i < list->children; i++) { + if (i != 0) { + smart_str_appends(str, ", "); + } + zend_ast_export_generic_type_parameter(str, list->child[i], indent); + } + smart_str_appendc(str, '>'); +} + +static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, const zend_ast_list *hook_list, int indent) { smart_str_appends(str, " {"); smart_str_appendc(str, '\n'); @@ -1965,7 +2151,7 @@ static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *h zend_ast_export_indent(str, indent); for (uint32_t i = 0; i < hook_list->children; i++) { - zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i]; + const zend_ast_decl *hook = (const zend_ast_decl *)hook_list->child[i]; zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY); if (hook->flags & ZEND_ACC_FINAL) { smart_str_appends(str, "final "); @@ -2039,7 +2225,7 @@ static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *h static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent) { - zend_ast_decl *decl; + const zend_ast_decl *decl; int p, pl, pr; const char *op; @@ -2054,7 +2240,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio break; case ZEND_AST_CONSTANT: { zend_string *name = zend_ast_get_constant_name(ast); - smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name)); + smart_str_append(str, name); break; } case ZEND_AST_OP_ARRAY: @@ -2075,7 +2261,10 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_CLOSURE: case ZEND_AST_ARROW_FUNC: case ZEND_AST_METHOD: - decl = (zend_ast_decl *) ast; + decl = (const zend_ast_decl *) ast; + if (decl->kind == ZEND_AST_ARROW_FUNC && (decl->attr & ZEND_PARENTHESIZED_ARROW_FUNC)) { + smart_str_appendc(str, '('); + } if (decl->child[4]) { bool newlines = !(ast->kind == ZEND_AST_CLOSURE || ast->kind == ZEND_AST_ARROW_FUNC); zend_ast_export_attributes(str, decl->child[4], indent, newlines); @@ -2101,7 +2290,10 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appendc(str, '&'); } if (ast->kind != ZEND_AST_CLOSURE && ast->kind != ZEND_AST_ARROW_FUNC) { - smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name)); + smart_str_append(str, decl->name); + } + if (decl->child[5]) { + zend_ast_export_generic_type_parameter_list(str, decl->child[5], indent); } smart_str_appendc(str, '('); zend_ast_export_ex(str, decl->child[0], 0, indent); @@ -2119,6 +2311,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } smart_str_appends(str, " => "); zend_ast_export_ex(str, body, 0, indent); + if (decl->attr & ZEND_PARENTHESIZED_ARROW_FUNC) { + smart_str_appendc(str, ')'); + } break; } @@ -2134,9 +2329,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } break; case ZEND_AST_CLASS: - decl = (zend_ast_decl *) ast; + decl = (const zend_ast_decl *) ast; if (decl->child[3]) { - zend_ast_export_attributes(str, decl->child[3], indent, 1); + zend_ast_export_attributes(str, decl->child[3], indent, true); } if (decl->flags & ZEND_ACC_INTERFACE) { smart_str_appends(str, "interface "); @@ -2156,7 +2351,10 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } smart_str_appends(str, "class "); } - smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name)); + smart_str_append(str, decl->name); + if (decl->child[5]) { + zend_ast_export_generic_type_parameter_list(str, decl->child[5], indent); + } if (decl->flags & ZEND_ACC_ENUM && decl->child[4]) { smart_str_appends(str, ": "); zend_ast_export_type(str, decl->child[4], indent); @@ -2170,16 +2368,16 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_EXPR_LIST: case ZEND_AST_PARAM_LIST: simple_list: - zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent); + zend_ast_export_list(str, zend_ast_get_list(ast), true, 20, indent); break; case ZEND_AST_ARRAY: smart_str_appendc(str, '['); - zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent); + zend_ast_export_list(str, zend_ast_get_list(ast), true, 20, indent); smart_str_appendc(str, ']'); break; case ZEND_AST_ENCAPS_LIST: smart_str_appendc(str, '"'); - zend_ast_export_encaps_list(str, '"', (zend_ast_list*)ast, indent); + zend_ast_export_encaps_list(str, '"', zend_ast_get_list(ast), indent); smart_str_appendc(str, '"'); break; case ZEND_AST_STMT_LIST: @@ -2187,16 +2385,16 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_stmt(str, ast, indent); break; case ZEND_AST_IF: - zend_ast_export_if_stmt(str, (zend_ast_list*)ast, indent); + zend_ast_export_if_stmt(str, zend_ast_get_list(ast), indent); break; case ZEND_AST_SWITCH_LIST: case ZEND_AST_CATCH_LIST: case ZEND_AST_MATCH_ARM_LIST: - zend_ast_export_list(str, (zend_ast_list*)ast, 0, 0, indent); + zend_ast_export_list(str, zend_ast_get_list(ast), false, 0, indent); break; case ZEND_AST_CLOSURE_USES: smart_str_appends(str, " use("); - zend_ast_export_var_list(str, (zend_ast_list*)ast, indent); + zend_ast_export_var_list(str, zend_ast_get_list(ast), indent); smart_str_appendc(str, ')'); break; case ZEND_AST_PROP_GROUP: { @@ -2204,7 +2402,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast *prop_ast = ast->child[1]; if (ast->child[2]) { - zend_ast_export_attributes(str, ast->child[2], indent, 1); + zend_ast_export_attributes(str, ast->child[2], indent, true); } zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_PROPERTY); @@ -2233,13 +2431,13 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio str, ast_list->child[ast_list->children - 1], indent, - 1 + true ); /* So that the list printing doesn't try to print the attributes, * use zend_ast_export_list_ex() to override the number of children * to print. */ smart_str_appends(str, "const "); - zend_ast_export_list_ex(str, ast_list, 1, 20, indent, ast_list->children - 1); + zend_ast_export_list_ex(str, ast_list, true, 20, indent, ast_list->children - 1); break; } smart_str_appends(str, "const "); @@ -2247,7 +2445,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } case ZEND_AST_CLASS_CONST_GROUP: if (ast->child[1]) { - zend_ast_export_attributes(str, ast->child[1], indent, 1); + zend_ast_export_attributes(str, ast->child[1], indent, true); } zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CONSTANT); @@ -2261,7 +2459,16 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio goto simple_list; case ZEND_AST_NAME_LIST: - zend_ast_export_name_list(str, (zend_ast_list*)ast, indent); + zend_ast_export_name_list(str, zend_ast_get_list(ast), indent); + break; + case ZEND_AST_GENERIC_TYPE_PARAMETER_LIST: + zend_ast_export_generic_type_parameter_list(str, ast, indent); + break; + case ZEND_AST_GENERIC_TYPE_ARGUMENT_LIST: + zend_ast_export_generic_type_argument_list(str, ast, indent); + break; + case ZEND_AST_GENERIC_CALL_TYPE_ARGUMENT_LIST: + zend_ast_export_generic_call_type_argument_list(str, ast, indent); break; case ZEND_AST_USE: smart_str_appends(str, "use "); @@ -2284,7 +2491,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case T_PROPERTY_C: APPEND_STR("__PROPERTY__"); case T_NS_C: APPEND_STR("__NAMESPACE__"); case T_CLASS_C: APPEND_STR("__CLASS__"); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_TYPE: @@ -2293,14 +2500,21 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case IS_CALLABLE: APPEND_STR("callable"); case IS_STATIC: APPEND_STR("static"); case IS_MIXED: APPEND_STR("mixed"); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); + } + break; + case ZEND_AST_PLACEHOLDER_ARG: + if (ast->attr == ZEND_PLACEHOLDER_VARIADIC) { + APPEND_STR("..."); + } else { + APPEND_STR("?"); } break; /* 1 child node */ case ZEND_AST_VAR: smart_str_appendc(str, '$'); - zend_ast_export_var(str, ast->child[0], 0, indent); + zend_ast_export_var(str, ast->child[0], indent); break; case ZEND_AST_CONST: zend_ast_export_ns_name(str, ast->child[0], 0, indent); @@ -2316,11 +2530,11 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case IS_NULL: PREFIX_OP("(unset)", 240, 241); case _IS_BOOL: PREFIX_OP("(bool)", 240, 241); case IS_LONG: PREFIX_OP("(int)", 240, 241); - case IS_DOUBLE: PREFIX_OP("(double)", 240, 241); + case IS_DOUBLE: PREFIX_OP("(float)", 240, 241); case IS_STRING: PREFIX_OP("(string)", 240, 241); case IS_ARRAY: PREFIX_OP("(array)", 240, 241); case IS_OBJECT: PREFIX_OP("(object)", 240, 241); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_CAST_VOID: @@ -2335,7 +2549,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_SHELL_EXEC: smart_str_appendc(str, '`'); if (ast->child[0]->kind == ZEND_AST_ENCAPS_LIST) { - zend_ast_export_encaps_list(str, '`', (zend_ast_list*)ast->child[0], indent); + zend_ast_export_encaps_list(str, '`', zend_ast_get_list(ast->child[0]), indent); } else { zval *zv; ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_ZVAL); @@ -2345,8 +2559,6 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } smart_str_appendc(str, '`'); break; - case ZEND_AST_CLONE: - PREFIX_OP("clone ", 270, 271); case ZEND_AST_PRINT: PREFIX_OP("print ", 60, 61); case ZEND_AST_INCLUDE_OR_EVAL: @@ -2356,14 +2568,14 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_REQUIRE_ONCE: FUNC_OP("require_once"); case ZEND_REQUIRE: FUNC_OP("require"); case ZEND_EVAL: FUNC_OP("eval"); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_UNARY_OP: switch (ast->attr) { case ZEND_BW_NOT: PREFIX_OP("~", 240, 241); case ZEND_BOOL_NOT: PREFIX_OP("!", 240, 241); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_PRE_INC: @@ -2417,12 +2629,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_NULLSAFE_PROP: zend_ast_export_ex(str, ast->child[0], 0, indent); smart_str_appends(str, ast->kind == ZEND_AST_NULLSAFE_PROP ? "?->" : "->"); - zend_ast_export_var(str, ast->child[1], 0, indent); + zend_ast_export_var(str, ast->child[1], indent); break; case ZEND_AST_STATIC_PROP: zend_ast_export_ns_name(str, ast->child[0], 0, indent); smart_str_appends(str, "::$"); - zend_ast_export_var(str, ast->child[1], 0, indent); + zend_ast_export_var(str, ast->child[1], indent); break; case ZEND_AST_CALL: { zend_ast *left = ast->child[0]; @@ -2433,20 +2645,19 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } else { zend_ast_export_ns_name(str, left, 0, indent); } + if (ast->child[2]) { + zend_ast_export_generic_call_type_argument_list(str, ast->child[2], indent); + } smart_str_appendc(str, '('); zend_ast_export_ex(str, ast->child[1], 0, indent); smart_str_appendc(str, ')'); break; } - case ZEND_AST_PARENT_PROPERTY_HOOK_CALL: - smart_str_append(str, Z_STR_P(zend_ast_get_zval(ast->child[0]))); - smart_str_appendc(str, '('); - zend_ast_export_ex(str, ast->child[1], 0, indent); - smart_str_appendc(str, ')'); - break; - case ZEND_AST_CALLABLE_CONVERT: - smart_str_appends(str, "..."); - break; + case ZEND_AST_CALLABLE_CONVERT: { + zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast; + ast = fcc_ast->args; + goto simple_list; + } case ZEND_AST_CLASS_CONST: zend_ast_export_ns_name(str, ast->child[0], 0, indent); smart_str_appends(str, "::"); @@ -2462,7 +2673,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_FETCH_CLASS_PARENT: smart_str_append(str, ZSTR_KNOWN(ZEND_STR_PARENT)); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } else { zend_ast_export_ns_name(str, ast->child[0], 0, indent); @@ -2485,7 +2696,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_BW_AND: BINARY_OP(" &= ", 90, 91, 90); case ZEND_BW_XOR: BINARY_OP(" ^= ", 90, 91, 90); case ZEND_POW: BINARY_OP(" **= ", 90, 91, 90); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_ASSIGN_COALESCE: BINARY_OP(" \?\?= ", 90, 91, 90); @@ -2511,7 +2722,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250); case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41); case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; case ZEND_AST_GREATER: BINARY_OP(" > ", 180, 181, 181); @@ -2531,9 +2742,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_NEW: smart_str_appends(str, "new "); if (ast->child[0]->kind == ZEND_AST_CLASS) { - zend_ast_decl *decl = (zend_ast_decl *) ast->child[0]; + const zend_ast_decl *decl = (const zend_ast_decl *) ast->child[0]; if (decl->child[3]) { - zend_ast_export_attributes(str, decl->child[3], indent, 0); + zend_ast_export_attributes(str, decl->child[3], indent, false); } smart_str_appends(str, "class"); if (!zend_ast_is_list(ast->child[1]) @@ -2545,6 +2756,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_class_no_header(str, decl, indent); } else { zend_ast_export_ns_name(str, ast->child[0], 0, indent); + if (ast->child[2]) { + zend_ast_export_generic_call_type_argument_list(str, ast->child[2], indent); + } smart_str_appendc(str, '('); zend_ast_export_ex(str, ast->child[1], 0, indent); smart_str_appendc(str, ')'); @@ -2555,6 +2769,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appends(str, " instanceof "); zend_ast_export_ns_name(str, ast->child[1], 0, indent); break; + case ZEND_AST_GENERIC_NAMED_TYPE: + zend_ast_export_type(str, ast, indent); + break; case ZEND_AST_YIELD: if (priority > 70) smart_str_appendc(str, '('); smart_str_appends(str, "yield "); @@ -2634,7 +2851,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_MATCH_ARM: zend_ast_export_indent(str, indent); if (ast->child[0]) { - zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent); + zend_ast_export_list(str, zend_ast_get_list(ast->child[0]), true, 0, indent); smart_str_appends(str, " => "); } else { smart_str_appends(str, "default => "); @@ -2645,7 +2862,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_DECLARE: smart_str_appends(str, "declare("); ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_CONST_DECL); - zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent); + zend_ast_export_list(str, zend_ast_get_list(ast->child[0]), true, 0, indent); smart_str_appendc(str, ')'); if (ast->child[1]) { smart_str_appends(str, " {\n"); @@ -2690,7 +2907,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appends(str, " insteadof "); zend_ast_export_ex(str, ast->child[1], 0, indent); break; - case ZEND_AST_METHOD_REFERENCE: + case ZEND_AST_TRAIT_METHOD_REFERENCE: if (ast->child[0]) { zend_ast_export_name(str, ast->child[0], 0, indent); smart_str_appends(str, "::"); @@ -2735,12 +2952,15 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio ast = ast->child[1]; goto tail_call; - /* 3 child nodes */ + /* 4 child nodes */ case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: zend_ast_export_ex(str, ast->child[0], 0, indent); smart_str_appends(str, ast->kind == ZEND_AST_NULLSAFE_METHOD_CALL ? "?->" : "->"); - zend_ast_export_var(str, ast->child[1], 0, indent); + zend_ast_export_var(str, ast->child[1], indent); + if (ast->child[3]) { + zend_ast_export_generic_call_type_argument_list(str, ast->child[3], indent); + } smart_str_appendc(str, '('); zend_ast_export_ex(str, ast->child[2], 0, indent); smart_str_appendc(str, ')'); @@ -2748,7 +2968,10 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio case ZEND_AST_STATIC_CALL: zend_ast_export_ns_name(str, ast->child[0], 0, indent); smart_str_appends(str, "::"); - zend_ast_export_var(str, ast->child[1], 0, indent); + zend_ast_export_var(str, ast->child[1], indent); + if (ast->child[3]) { + zend_ast_export_generic_call_type_argument_list(str, ast->child[3], indent); + } smart_str_appendc(str, '('); zend_ast_export_ex(str, ast->child[2], 0, indent); smart_str_appendc(str, ')'); @@ -2784,7 +3007,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_catch_name_list(str, zend_ast_get_list(ast->child[0]), indent); if (ast->child[1]) { smart_str_appends(str, " $"); - zend_ast_export_var(str, ast->child[1], 0, indent); + zend_ast_export_var(str, ast->child[1], indent); } smart_str_appends(str, ") {\n"); zend_ast_export_stmt(str, ast->child[2], indent + 1); @@ -2792,7 +3015,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio break; case ZEND_AST_PARAM: if (ast->child[3]) { - zend_ast_export_attributes(str, ast->child[3], indent, 0); + zend_ast_export_attributes(str, ast->child[3], indent, false); } zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CPP); if (ast->attr & ZEND_ACC_FINAL) { @@ -2820,7 +3043,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio break; case ZEND_AST_ENUM_CASE: if (ast->child[3]) { - zend_ast_export_attributes(str, ast->child[3], indent, 1); + zend_ast_export_attributes(str, ast->child[3], indent, true); } smart_str_appends(str, "case "); zend_ast_export_name(str, ast->child[0], 0, indent); @@ -2829,6 +3052,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_ex(str, ast->child[1], 0, indent); } break; + case ZEND_AST_GENERIC_TYPE_PARAMETER: + zend_ast_export_generic_type_parameter(str, ast, indent); + break; /* 4 child nodes */ case ZEND_AST_FOR: @@ -2863,7 +3089,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_indent(str, indent); smart_str_appendc(str, '}'); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return; @@ -2958,10 +3184,22 @@ zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr) /* Since constants are already stored in a list, just add the attributes * to that list instead of storing them elsewhere; * zend_compile_const_decl() checks the kind of the list elements. */ - zend_ast_list_add(ast, attr); + ast = zend_ast_list_add(ast, attr); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return ast; } + +zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast) +{ + if (ast->kind == ZEND_AST_CALL) { + return ast->child[1]; + } else if (ast->kind == ZEND_AST_STATIC_CALL || ast->kind == ZEND_AST_METHOD_CALL) { + return ast->child[2]; + } + + ZEND_UNREACHABLE(); + return NULL; +} diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index c82ca66c9f57..77598f809f1c 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bob Weinand | | Dmitry Stogov | @@ -70,12 +69,16 @@ enum _zend_ast_kind { ZEND_AST_ATTRIBUTE_GROUP, ZEND_AST_MATCH_ARM_LIST, ZEND_AST_MODIFIER_LIST, + ZEND_AST_GENERIC_TYPE_PARAMETER_LIST, + ZEND_AST_GENERIC_TYPE_ARGUMENT_LIST, + ZEND_AST_GENERIC_CALL_TYPE_ARGUMENT_LIST, /* 0 child nodes */ ZEND_AST_MAGIC_CONST = 0 << ZEND_AST_NUM_CHILDREN_SHIFT, ZEND_AST_TYPE, ZEND_AST_CONSTANT_CLASS, ZEND_AST_CALLABLE_CONVERT, + ZEND_AST_PLACEHOLDER_ARG, /* 1 child node */ ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT, @@ -89,7 +92,6 @@ enum _zend_ast_kind { ZEND_AST_ISSET, ZEND_AST_SILENCE, ZEND_AST_SHELL_EXEC, - ZEND_AST_CLONE, ZEND_AST_PRINT, ZEND_AST_INCLUDE_OR_EVAL, ZEND_AST_UNARY_OP, @@ -118,7 +120,6 @@ enum _zend_ast_kind { ZEND_AST_PROP, ZEND_AST_NULLSAFE_PROP, ZEND_AST_STATIC_PROP, - ZEND_AST_CALL, ZEND_AST_CLASS_CONST, ZEND_AST_ASSIGN, ZEND_AST_ASSIGN_REF, @@ -129,7 +130,6 @@ enum _zend_ast_kind { ZEND_AST_AND, ZEND_AST_OR, ZEND_AST_ARRAY_ELEM, - ZEND_AST_NEW, ZEND_AST_INSTANCEOF, ZEND_AST_YIELD, ZEND_AST_COALESCE, @@ -144,32 +144,28 @@ enum _zend_ast_kind { ZEND_AST_DECLARE, ZEND_AST_USE_TRAIT, ZEND_AST_TRAIT_PRECEDENCE, - ZEND_AST_METHOD_REFERENCE, + ZEND_AST_TRAIT_METHOD_REFERENCE, ZEND_AST_NAMESPACE, ZEND_AST_USE_ELEM, ZEND_AST_TRAIT_ALIAS, ZEND_AST_GROUP_USE, - ZEND_AST_ATTRIBUTE, ZEND_AST_MATCH, ZEND_AST_MATCH_ARM, ZEND_AST_NAMED_ARG, - ZEND_AST_PARENT_PROPERTY_HOOK_CALL, ZEND_AST_PIPE, + ZEND_AST_GENERIC_NAMED_TYPE, /* 3 child nodes */ - ZEND_AST_METHOD_CALL = 3 << ZEND_AST_NUM_CHILDREN_SHIFT, - ZEND_AST_NULLSAFE_METHOD_CALL, - ZEND_AST_STATIC_CALL, - ZEND_AST_CONDITIONAL, - + ZEND_AST_CONDITIONAL = 3 << ZEND_AST_NUM_CHILDREN_SHIFT, ZEND_AST_TRY, ZEND_AST_CATCH, ZEND_AST_PROP_GROUP, ZEND_AST_CONST_ELEM, ZEND_AST_CLASS_CONST_GROUP, - - // Pseudo node for initializing enums - ZEND_AST_CONST_ENUM_INIT, + ZEND_AST_CALL, + ZEND_AST_NEW, + ZEND_AST_GENERIC_TYPE_PARAMETER, + ZEND_AST_ATTRIBUTE, /* 4 child nodes */ ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT, @@ -177,6 +173,14 @@ enum _zend_ast_kind { ZEND_AST_ENUM_CASE, ZEND_AST_PROP_ELEM, + // Pseudo node for initializing enums + ZEND_AST_CONST_ENUM_INIT, + + /* Method/static call forms with optional call_type_arguments slot. */ + ZEND_AST_METHOD_CALL, + ZEND_AST_NULLSAFE_METHOD_CALL, + ZEND_AST_STATIC_CALL, + /* 5 child nodes */ /* 6 child nodes */ @@ -221,28 +225,30 @@ typedef struct _zend_ast_op_array { /* Separate structure for function and class declaration, as they need extra information. */ typedef struct _zend_ast_decl { zend_ast_kind kind; - zend_ast_attr attr; /* Unused - for structure compatibility */ + zend_ast_attr attr; uint32_t start_lineno; uint32_t end_lineno; uint32_t flags; zend_string *doc_comment; zend_string *name; - zend_ast *child[5]; + zend_ast *child[6]; } zend_ast_decl; +// TODO: rename typedef struct _zend_ast_fcc { zend_ast_kind kind; /* Type of the node (ZEND_AST_* enum constant) */ zend_ast_attr attr; /* Additional attribute, use depending on node type */ uint32_t lineno; /* Line number */ + zend_ast *args; ZEND_MAP_PTR_DEF(zend_function *, fptr); } zend_ast_fcc; typedef void (*zend_ast_process_t)(zend_ast *ast); extern ZEND_API zend_ast_process_t zend_ast_process; -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(const zval *zv, uint32_t lineno); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(const zval *zv, zend_ast_attr attr); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(const zval *zv); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval); @@ -308,27 +314,40 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child); ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_0(zend_ast_kind kind); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_1(zend_ast_kind kind, zend_ast *child); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_arg_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2); + # define zend_ast_create(...) \ ZEND_AST_SPEC_CALL(zend_ast_create, __VA_ARGS__) # define zend_ast_create_ex(...) \ ZEND_AST_SPEC_CALL_EX(zend_ast_create_ex, __VA_ARGS__) # define zend_ast_create_list(init_children, ...) \ ZEND_AST_SPEC_CALL(zend_ast_create_list, __VA_ARGS__) +# define zend_ast_create_arg_list(init_children, ...) \ + ZEND_AST_SPEC_CALL(zend_ast_create_arg_list, __VA_ARGS__) #else ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...); ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...); ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...); +ZEND_API zend_ast *zend_ast_create_arg_list(uint32_t init_children, zend_ast_kind kind, ...); #endif -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *list, zend_ast *op); +ZEND_ATTRIBUTE_NODISCARD ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *list, zend_ast *op); + +/* Like zend_ast_list_add(), but wraps the list into a ZEND_AST_CALLABLE_CONVERT + * if any arg is a ZEND_AST_PLACEHOLDER_ARG. list can be a zend_ast_list, or a + * zend_ast_fcc. */ +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_arg_list_add(zend_ast *list, zend_ast *arg); ZEND_API zend_ast *zend_ast_create_decl( zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, - zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4 + zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, + zend_ast *child4, zend_ast *child5 ); -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(void); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_fcc(zend_ast *args); typedef struct { bool had_side_effects; @@ -346,18 +365,18 @@ typedef void (*zend_ast_apply_func)(zend_ast **ast_ptr, void *context); ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn, void *context); static zend_always_inline size_t zend_ast_size(uint32_t children) { - return XtOffsetOf(zend_ast, child) + (sizeof(zend_ast *) * children); + return offsetof(zend_ast, child) + (sizeof(zend_ast *) * children); } -static zend_always_inline bool zend_ast_is_special(zend_ast *ast) { +static zend_always_inline bool zend_ast_is_special(const zend_ast *ast) { return (ast->kind >> ZEND_AST_SPECIAL_SHIFT) & 1; } -static zend_always_inline bool zend_ast_is_decl(zend_ast *ast) { +static zend_always_inline bool zend_ast_is_decl(const zend_ast *ast) { return zend_ast_is_special(ast) && ast->kind >= ZEND_AST_FUNC_DECL; } -static zend_always_inline bool zend_ast_is_list(zend_ast *ast) { +static zend_always_inline bool zend_ast_is_list(const zend_ast *ast) { return (ast->kind >> ZEND_AST_IS_LIST_SHIFT) & 1; } static zend_always_inline zend_ast_list *zend_ast_get_list(zend_ast *ast) { @@ -370,7 +389,7 @@ static zend_always_inline zval *zend_ast_get_zval(zend_ast *ast) { return &((zend_ast_zval *) ast)->val; } static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); return Z_STR_P(zv); } @@ -386,7 +405,7 @@ static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast) return Z_STR(((zend_ast_zval *) ast)->val); } -static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) { +static zend_always_inline uint32_t zend_ast_get_num_children(const zend_ast *ast) { ZEND_ASSERT(!zend_ast_is_list(ast)); ZEND_ASSERT(!zend_ast_is_special(ast)); @@ -394,10 +413,10 @@ static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) { } static zend_always_inline uint32_t zend_ast_get_lineno(zend_ast *ast) { if (ast->kind == ZEND_AST_ZVAL) { - zval *zv = zend_ast_get_zval(ast); + const zval *zv = zend_ast_get_zval(ast); return Z_LINENO_P(zv); } else if (ast->kind == ZEND_AST_CONSTANT) { - zval *zv = &((zend_ast_zval *) ast)->val; + const zval *zv = &((const zend_ast_zval *) ast)->val; return Z_LINENO_P(zv); } else { return ast->lineno; @@ -426,4 +445,6 @@ static zend_always_inline zend_ast *zend_ast_list_rtrim(zend_ast *ast) { zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr); +zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast); + #endif diff --git a/Zend/zend_atomic.c b/Zend/zend_atomic.c index 5f6a7793beea..98a39c583437 100644 --- a/Zend/zend_atomic.c +++ b/Zend/zend_atomic.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Levi Morrison | +----------------------------------------------------------------------+ @@ -57,7 +57,7 @@ ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired) { zend_atomic_int_store_ex(obj, desired); } -#if defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS) +#if (defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS)) && !defined(HAVE_C11_ATOMICS) /* On these platforms it is non-const due to underlying APIs. */ ZEND_API bool zend_atomic_bool_load(zend_atomic_bool *obj) { return zend_atomic_bool_load_ex(obj); diff --git a/Zend/zend_atomic.h b/Zend/zend_atomic.h index 56422a721fdb..31558996c3c3 100644 --- a/Zend/zend_atomic.h +++ b/Zend/zend_atomic.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Levi Morrison | +----------------------------------------------------------------------+ @@ -39,7 +39,7 @@ * and alignment purposes. */ -#if defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS) +#if (defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS)) && !defined(HAVE_C11_ATOMICS) typedef struct zend_atomic_bool_s { volatile char value; } zend_atomic_bool; @@ -68,7 +68,7 @@ typedef struct zend_atomic_int_s { BEGIN_EXTERN_C() -#ifdef ZEND_WIN32 +#if defined(ZEND_WIN32) && !defined(HAVE_C11_ATOMICS) #ifndef InterlockedExchange8 #define InterlockedExchange8 _InterlockedExchange8 @@ -123,7 +123,7 @@ static zend_always_inline bool zend_atomic_int_compare_exchange_ex(zend_atomic_i } } -/* On this platform it is non-const due to Iterlocked API*/ +/* On this platform it is non-const due to Interlocked API */ static zend_always_inline bool zend_atomic_bool_load_ex(zend_atomic_bool *obj) { /* Or'ing with false won't change the value. */ return InterlockedOr8(&obj->value, false); @@ -376,7 +376,7 @@ ZEND_API bool zend_atomic_int_compare_exchange(zend_atomic_int *obj, int *expect ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired); ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired); -#if defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS) +#if (defined(ZEND_WIN32) && !defined(HAVE_C11_ATOMICS)) || defined(HAVE_SYNC_ATOMICS) /* On these platforms it is non-const due to underlying APIs. */ ZEND_API bool zend_atomic_bool_load(zend_atomic_bool *obj); ZEND_API int zend_atomic_int_load(zend_atomic_int *obj); diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index c3633801be83..416be8093ef2 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Benjamin Eberlei | | Martin Schröder | @@ -32,12 +31,13 @@ ZEND_API zend_class_entry *zend_ce_sensitive_parameter_value; ZEND_API zend_class_entry *zend_ce_override; ZEND_API zend_class_entry *zend_ce_deprecated; ZEND_API zend_class_entry *zend_ce_nodiscard; +ZEND_API zend_class_entry *zend_ce_delayed_target_validation; static zend_object_handlers attributes_object_handlers_sensitive_parameter_value; static HashTable internal_attributes; -uint32_t zend_attribute_attribute_get_flags(zend_attribute *attr, zend_class_entry *scope) +uint32_t zend_attribute_attribute_get_flags(const zend_attribute *attr, zend_class_entry *scope) { // TODO: More proper signature validation: Too many args, incorrect arg names. if (attr->argc > 0) { @@ -69,30 +69,63 @@ uint32_t zend_attribute_attribute_get_flags(zend_attribute *attr, zend_class_ent return ZEND_ATTRIBUTE_TARGET_ALL; } -static void validate_allow_dynamic_properties( +static zend_string *validate_allow_dynamic_properties( zend_attribute *attr, uint32_t target, zend_class_entry *scope) { + ZEND_ASSERT(scope != NULL); + const char *msg = NULL; if (scope->ce_flags & ZEND_ACC_TRAIT) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to trait %s", - ZSTR_VAL(scope->name) - ); + msg = "Cannot apply #[\\AllowDynamicProperties] to trait %s"; + } else if (scope->ce_flags & ZEND_ACC_INTERFACE) { + msg = "Cannot apply #[\\AllowDynamicProperties] to interface %s"; + } else if (scope->ce_flags & ZEND_ACC_READONLY_CLASS) { + msg = "Cannot apply #[\\AllowDynamicProperties] to readonly class %s"; + } else if (scope->ce_flags & ZEND_ACC_ENUM) { + msg = "Cannot apply #[\\AllowDynamicProperties] to enum %s"; } - if (scope->ce_flags & ZEND_ACC_INTERFACE) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to interface %s", - ZSTR_VAL(scope->name) - ); + if (msg != NULL) { + return zend_strpprintf(0, msg, ZSTR_VAL(scope->name)); } - if (scope->ce_flags & ZEND_ACC_READONLY_CLASS) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to readonly class %s", - ZSTR_VAL(scope->name) - ); + scope->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; + return NULL; +} + +static zend_string *validate_attribute( + zend_attribute *attr, uint32_t target, zend_class_entry *scope) +{ + const char *msg = NULL; + if (scope->ce_flags & ZEND_ACC_TRAIT) { + msg = "Cannot apply #[\\Attribute] to trait %s"; + } else if (scope->ce_flags & ZEND_ACC_INTERFACE) { + msg = "Cannot apply #[\\Attribute] to interface %s"; + } else if (scope->ce_flags & ZEND_ACC_ENUM) { + msg = "Cannot apply #[\\Attribute] to enum %s"; + } else if (scope->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) { + msg = "Cannot apply #[\\Attribute] to abstract class %s"; } - if (scope->ce_flags & ZEND_ACC_ENUM) { - zend_error_noreturn(E_ERROR, "Cannot apply #[AllowDynamicProperties] to enum %s", - ZSTR_VAL(scope->name) - ); + if (msg != NULL) { + return zend_strpprintf(0, msg, ZSTR_VAL(scope->name)); } - scope->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; + return NULL; +} + +static zend_string *validate_deprecated( + zend_attribute *attr, + uint32_t target, + zend_class_entry *scope +) { + if (target != ZEND_ATTRIBUTE_TARGET_CLASS) { + /* Being used for a method or something, validation does not apply */ + return NULL; + } + if (!(scope->ce_flags & ZEND_ACC_TRAIT)) { + const char *type = zend_get_object_type_case(scope, false); + return zend_strpprintf(0, "Cannot apply #[\\Deprecated] to %s %s", type, ZSTR_VAL(scope->name)); + } + + scope->ce_flags |= ZEND_ACC_DEPRECATED; + return NULL; + } ZEND_METHOD(Attribute, __construct) @@ -194,6 +227,20 @@ ZEND_METHOD(Deprecated, __construct) } } +static zend_string *validate_nodiscard( + zend_attribute *attr, uint32_t target, zend_class_entry *scope) +{ + ZEND_ASSERT(CG(in_compilation)); + const zend_string *prop_info_name = CG(context).active_property_info_name; + if (prop_info_name != NULL) { + // Applied to a hook + return ZSTR_INIT_LITERAL("#[\\NoDiscard] is not supported for property hooks", 0); + } + zend_op_array *op_array = CG(active_op_array); + op_array->fn_flags |= ZEND_ACC_NODISCARD; + return NULL; +} + ZEND_METHOD(NoDiscard, __construct) { zend_string *message = NULL; @@ -217,7 +264,7 @@ ZEND_METHOD(NoDiscard, __construct) } } -static zend_attribute *get_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset) +static zend_attribute *get_attribute(const HashTable *attributes, const zend_string *lcname, uint32_t offset) { if (attributes) { zend_attribute *attr; @@ -232,7 +279,7 @@ static zend_attribute *get_attribute(HashTable *attributes, zend_string *lcname, return NULL; } -static zend_attribute *get_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset) +static zend_attribute *get_attribute_str(const HashTable *attributes, const char *str, size_t len, uint32_t offset) { if (attributes) { zend_attribute *attr; @@ -247,27 +294,27 @@ static zend_attribute *get_attribute_str(HashTable *attributes, const char *str, return NULL; } -ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname) +ZEND_API zend_attribute *zend_get_attribute(const HashTable *attributes, const zend_string *lcname) { return get_attribute(attributes, lcname, 0); } -ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const char *str, size_t len) +ZEND_API zend_attribute *zend_get_attribute_str(const HashTable *attributes, const char *str, size_t len) { return get_attribute_str(attributes, str, len, 0); } -ZEND_API zend_attribute *zend_get_parameter_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset) +ZEND_API zend_attribute *zend_get_parameter_attribute(const HashTable *attributes, const zend_string *lcname, uint32_t offset) { return get_attribute(attributes, lcname, offset + 1); } -ZEND_API zend_attribute *zend_get_parameter_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset) +ZEND_API zend_attribute *zend_get_parameter_attribute_str(const HashTable *attributes, const char *str, size_t len, uint32_t offset) { return get_attribute_str(attributes, str, len, offset + 1); } -ZEND_API zend_result zend_get_attribute_value(zval *ret, zend_attribute *attr, uint32_t i, zend_class_entry *scope) +ZEND_API zend_result zend_get_attribute_value(zval *ret, const zend_attribute *attr, uint32_t i, zend_class_entry *scope) { if (i >= attr->argc) { return FAILURE; @@ -399,7 +446,7 @@ ZEND_API zend_string *zend_get_attribute_target_names(uint32_t flags) return smart_str_extract(&str); } -ZEND_API bool zend_is_attribute_repeated(HashTable *attributes, zend_attribute *attr) +ZEND_API bool zend_is_attribute_repeated(const HashTable *attributes, const zend_attribute *attr) { zend_attribute *other; @@ -421,6 +468,14 @@ static void attr_free(zval *v) zend_string_release(attr->name); zend_string_release(attr->lcname); + if (attr->validation_error != NULL) { + zend_string_release(attr->validation_error); + } + + if (attr->generic_args) { + zend_type_release(*attr->generic_args, persistent); + pefree(attr->generic_args, persistent); + } for (uint32_t i = 0; i < attr->argc; i++) { if (attr->args[i].name) { @@ -453,10 +508,13 @@ ZEND_API zend_attribute *zend_add_attribute(HashTable **attributes, zend_string } attr->lcname = zend_string_tolower_ex(attr->name, persistent); + attr->validation_error = NULL; attr->flags = flags; attr->lineno = lineno; attr->offset = offset; attr->argc = argc; + attr->generic_arity = 0; + attr->generic_args = NULL; /* Initialize arguments to avoid partial initialization in case of fatal errors. */ for (uint32_t i = 0; i < argc; i++) { @@ -522,6 +580,7 @@ void zend_register_attribute_ce(void) zend_ce_attribute = register_class_Attribute(); attr = zend_mark_internal_attribute(zend_ce_attribute); + attr->validator = validate_attribute; zend_ce_return_type_will_change_attribute = register_class_ReturnTypeWillChange(); zend_mark_internal_attribute(zend_ce_return_type_will_change_attribute); @@ -545,9 +604,14 @@ void zend_register_attribute_ce(void) zend_ce_deprecated = register_class_Deprecated(); attr = zend_mark_internal_attribute(zend_ce_deprecated); + attr->validator = validate_deprecated; zend_ce_nodiscard = register_class_NoDiscard(); attr = zend_mark_internal_attribute(zend_ce_nodiscard); + attr->validator = validate_nodiscard; + + zend_ce_delayed_target_validation = register_class_DelayedTargetValidation(); + attr = zend_mark_internal_attribute(zend_ce_delayed_target_validation); } void zend_attributes_shutdown(void) diff --git a/Zend/zend_attributes.h b/Zend/zend_attributes.h index a4d6b28c0094..628b557a6584 100644 --- a/Zend/zend_attributes.h +++ b/Zend/zend_attributes.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Benjamin Eberlei | | Martin Schröder | @@ -50,6 +49,7 @@ extern ZEND_API zend_class_entry *zend_ce_sensitive_parameter_value; extern ZEND_API zend_class_entry *zend_ce_override; extern ZEND_API zend_class_entry *zend_ce_deprecated; extern ZEND_API zend_class_entry *zend_ce_nodiscard; +extern ZEND_API zend_class_entry *zend_ce_delayed_target_validation; typedef struct { zend_string *name; @@ -59,31 +59,37 @@ typedef struct { typedef struct _zend_attribute { zend_string *name; zend_string *lcname; + /* Only non-null for internal attributes with validation errors that are + * delayed until runtime via #[\DelayedTargetValidation] */ + zend_string *validation_error; uint32_t flags; uint32_t lineno; /* Parameter offsets start at 1, everything else uses 0. */ uint32_t offset; uint32_t argc; + /* Number of generic type arguments at the attribute use-site. */ + uint8_t generic_arity; + zend_type *generic_args; zend_attribute_arg args[1]; } zend_attribute; typedef struct _zend_internal_attribute { zend_class_entry *ce; uint32_t flags; - void (*validator)(zend_attribute *attr, uint32_t target, zend_class_entry *scope); + zend_string* (*validator)(zend_attribute *attr, uint32_t target, zend_class_entry *scope); } zend_internal_attribute; -ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname); -ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const char *str, size_t len); +ZEND_API zend_attribute *zend_get_attribute(const HashTable *attributes, const zend_string *lcname); +ZEND_API zend_attribute *zend_get_attribute_str(const HashTable *attributes, const char *str, size_t len); -ZEND_API zend_attribute *zend_get_parameter_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset); -ZEND_API zend_attribute *zend_get_parameter_attribute_str(HashTable *attributes, const char *str, size_t len, uint32_t offset); +ZEND_API zend_attribute *zend_get_parameter_attribute(const HashTable *attributes, const zend_string *lcname, uint32_t offset); +ZEND_API zend_attribute *zend_get_parameter_attribute_str(const HashTable *attributes, const char *str, size_t len, uint32_t offset); -ZEND_API zend_result zend_get_attribute_value(zval *ret, zend_attribute *attr, uint32_t i, zend_class_entry *scope); +ZEND_API zend_result zend_get_attribute_value(zval *ret, const zend_attribute *attr, uint32_t i, zend_class_entry *scope); ZEND_API zend_result zend_get_attribute_object(zval *out, zend_class_entry *attribute_ce, zend_attribute *attribute_data, zend_class_entry *scope, zend_string *filename); ZEND_API zend_string *zend_get_attribute_target_names(uint32_t targets); -ZEND_API bool zend_is_attribute_repeated(HashTable *attributes, zend_attribute *attr); +ZEND_API bool zend_is_attribute_repeated(const HashTable *attributes, const zend_attribute *attr); ZEND_API zend_internal_attribute *zend_mark_internal_attribute(zend_class_entry *ce); ZEND_API zend_internal_attribute *zend_internal_attribute_register(zend_class_entry *ce, uint32_t flags); @@ -93,7 +99,7 @@ ZEND_API zend_attribute *zend_add_attribute( HashTable **attributes, zend_string *name, uint32_t argc, uint32_t flags, uint32_t offset, uint32_t lineno); -uint32_t zend_attribute_attribute_get_flags(zend_attribute *attr, zend_class_entry *scope); +uint32_t zend_attribute_attribute_get_flags(const zend_attribute *attr, zend_class_entry *scope); END_EXTERN_C() @@ -115,13 +121,13 @@ static zend_always_inline zend_attribute *zend_add_parameter_attribute(zend_func return zend_add_attribute(&func->common.attributes, name, argc, flags, offset + 1, 0); } -static zend_always_inline zend_attribute *zend_add_property_attribute(zend_class_entry *ce, zend_property_info *info, zend_string *name, uint32_t argc) +static zend_always_inline zend_attribute *zend_add_property_attribute(const zend_class_entry *ce, zend_property_info *info, zend_string *name, uint32_t argc) { uint32_t flags = ce->type != ZEND_USER_CLASS ? ZEND_ATTRIBUTE_PERSISTENT : 0; return zend_add_attribute(&info->attributes, name, argc, flags, 0, 0); } -static zend_always_inline zend_attribute *zend_add_class_constant_attribute(zend_class_entry *ce, zend_class_constant *c, zend_string *name, uint32_t argc) +static zend_always_inline zend_attribute *zend_add_class_constant_attribute(const zend_class_entry *ce, zend_class_constant *c, zend_string *name, uint32_t argc) { uint32_t flags = ce->type != ZEND_USER_CLASS ? ZEND_ATTRIBUTE_PERSISTENT : 0; return zend_add_attribute(&c->attributes, name, argc, flags, 0, 0); diff --git a/Zend/zend_attributes.stub.php b/Zend/zend_attributes.stub.php index fe70de83e4d2..ded9c89593a3 100644 --- a/Zend/zend_attributes.stub.php +++ b/Zend/zend_attributes.stub.php @@ -68,7 +68,7 @@ public function __debugInfo(): array {} /** * @strict-properties */ -#[Attribute(Attribute::TARGET_METHOD)] +#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_PROPERTY)] final class Override { public function __construct() {} @@ -77,7 +77,7 @@ public function __construct() {} /** * @strict-properties */ -#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_FUNCTION|Attribute::TARGET_CLASS_CONSTANT|Attribute::TARGET_CONSTANT)] +#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_FUNCTION|Attribute::TARGET_CLASS_CONSTANT|Attribute::TARGET_CONSTANT|Attribute::TARGET_CLASS)] final class Deprecated { public readonly ?string $message; @@ -97,3 +97,9 @@ final class NoDiscard public function __construct(?string $message = null) {} } + +/** + * @strict-properties + */ +#[Attribute(Attribute::TARGET_ALL)] +final class DelayedTargetValidation {} diff --git a/Zend/zend_attributes_arginfo.h b/Zend/zend_attributes_arginfo.h index 14afe40c01ad..54a66af29966 100644 --- a/Zend/zend_attributes_arginfo.h +++ b/Zend/zend_attributes_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9aee3d8f2ced376f5929048444eaa2529ff90311 */ +/* This is a generated file, edit zend_attributes.stub.php instead. + * Stub hash: b868cb33f41d9442f42d0cec84e33fcc09f5d88c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Attribute___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "Attribute::TARGET_ALL") @@ -95,70 +95,68 @@ static zend_class_entry *register_class_Attribute(void) zval const_TARGET_CLASS_value; ZVAL_LONG(&const_TARGET_CLASS_value, ZEND_ATTRIBUTE_TARGET_CLASS); - zend_string *const_TARGET_CLASS_name = zend_string_init_interned("TARGET_CLASS", sizeof("TARGET_CLASS") - 1, 1); + zend_string *const_TARGET_CLASS_name = zend_string_init_interned("TARGET_CLASS", sizeof("TARGET_CLASS") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_CLASS_name, &const_TARGET_CLASS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_CLASS_name); + zend_string_release_ex(const_TARGET_CLASS_name, true); zval const_TARGET_FUNCTION_value; ZVAL_LONG(&const_TARGET_FUNCTION_value, ZEND_ATTRIBUTE_TARGET_FUNCTION); - zend_string *const_TARGET_FUNCTION_name = zend_string_init_interned("TARGET_FUNCTION", sizeof("TARGET_FUNCTION") - 1, 1); + zend_string *const_TARGET_FUNCTION_name = zend_string_init_interned("TARGET_FUNCTION", sizeof("TARGET_FUNCTION") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_FUNCTION_name, &const_TARGET_FUNCTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_FUNCTION_name); + zend_string_release_ex(const_TARGET_FUNCTION_name, true); zval const_TARGET_METHOD_value; ZVAL_LONG(&const_TARGET_METHOD_value, ZEND_ATTRIBUTE_TARGET_METHOD); - zend_string *const_TARGET_METHOD_name = zend_string_init_interned("TARGET_METHOD", sizeof("TARGET_METHOD") - 1, 1); + zend_string *const_TARGET_METHOD_name = zend_string_init_interned("TARGET_METHOD", sizeof("TARGET_METHOD") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_METHOD_name, &const_TARGET_METHOD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_METHOD_name); + zend_string_release_ex(const_TARGET_METHOD_name, true); zval const_TARGET_PROPERTY_value; ZVAL_LONG(&const_TARGET_PROPERTY_value, ZEND_ATTRIBUTE_TARGET_PROPERTY); - zend_string *const_TARGET_PROPERTY_name = zend_string_init_interned("TARGET_PROPERTY", sizeof("TARGET_PROPERTY") - 1, 1); + zend_string *const_TARGET_PROPERTY_name = zend_string_init_interned("TARGET_PROPERTY", sizeof("TARGET_PROPERTY") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_PROPERTY_name, &const_TARGET_PROPERTY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_PROPERTY_name); + zend_string_release_ex(const_TARGET_PROPERTY_name, true); zval const_TARGET_CLASS_CONSTANT_value; ZVAL_LONG(&const_TARGET_CLASS_CONSTANT_value, ZEND_ATTRIBUTE_TARGET_CLASS_CONST); - zend_string *const_TARGET_CLASS_CONSTANT_name = zend_string_init_interned("TARGET_CLASS_CONSTANT", sizeof("TARGET_CLASS_CONSTANT") - 1, 1); + zend_string *const_TARGET_CLASS_CONSTANT_name = zend_string_init_interned("TARGET_CLASS_CONSTANT", sizeof("TARGET_CLASS_CONSTANT") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_CLASS_CONSTANT_name, &const_TARGET_CLASS_CONSTANT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_CLASS_CONSTANT_name); + zend_string_release_ex(const_TARGET_CLASS_CONSTANT_name, true); zval const_TARGET_PARAMETER_value; ZVAL_LONG(&const_TARGET_PARAMETER_value, ZEND_ATTRIBUTE_TARGET_PARAMETER); - zend_string *const_TARGET_PARAMETER_name = zend_string_init_interned("TARGET_PARAMETER", sizeof("TARGET_PARAMETER") - 1, 1); + zend_string *const_TARGET_PARAMETER_name = zend_string_init_interned("TARGET_PARAMETER", sizeof("TARGET_PARAMETER") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_PARAMETER_name, &const_TARGET_PARAMETER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_PARAMETER_name); + zend_string_release_ex(const_TARGET_PARAMETER_name, true); zval const_TARGET_CONSTANT_value; ZVAL_LONG(&const_TARGET_CONSTANT_value, ZEND_ATTRIBUTE_TARGET_CONST); - zend_string *const_TARGET_CONSTANT_name = zend_string_init_interned("TARGET_CONSTANT", sizeof("TARGET_CONSTANT") - 1, 1); + zend_string *const_TARGET_CONSTANT_name = zend_string_init_interned("TARGET_CONSTANT", sizeof("TARGET_CONSTANT") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_CONSTANT_name, &const_TARGET_CONSTANT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_CONSTANT_name); + zend_string_release_ex(const_TARGET_CONSTANT_name, true); zval const_TARGET_ALL_value; ZVAL_LONG(&const_TARGET_ALL_value, ZEND_ATTRIBUTE_TARGET_ALL); - zend_string *const_TARGET_ALL_name = zend_string_init_interned("TARGET_ALL", sizeof("TARGET_ALL") - 1, 1); + zend_string *const_TARGET_ALL_name = zend_string_init_interned("TARGET_ALL", sizeof("TARGET_ALL") - 1, true); zend_declare_typed_class_constant(class_entry, const_TARGET_ALL_name, &const_TARGET_ALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TARGET_ALL_name); + zend_string_release_ex(const_TARGET_ALL_name, true); zval const_IS_REPEATABLE_value; ZVAL_LONG(&const_IS_REPEATABLE_value, ZEND_ATTRIBUTE_IS_REPEATABLE); - zend_string *const_IS_REPEATABLE_name = zend_string_init_interned("IS_REPEATABLE", sizeof("IS_REPEATABLE") - 1, 1); + zend_string *const_IS_REPEATABLE_name = zend_string_init_interned("IS_REPEATABLE", sizeof("IS_REPEATABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_REPEATABLE_name, &const_IS_REPEATABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_REPEATABLE_name); + zend_string_release_ex(const_IS_REPEATABLE_name, true); zval property_flags_default_value; ZVAL_UNDEF(&property_flags_default_value); - zend_string *property_flags_name = zend_string_init("flags", sizeof("flags") - 1, 1); + zend_string *property_flags_name = zend_string_init("flags", sizeof("flags") - 1, true); zend_declare_typed_property(class_entry, property_flags_name, &property_flags_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_flags_name); + zend_string_release_ex(property_flags_name, true); - zend_string *attribute_name_Attribute_class_Attribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_Attribute_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_Attribute_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Attribute_0, 1); - zend_string_release(attribute_name_Attribute_class_Attribute_0); - zval attribute_Attribute_class_Attribute_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_Attribute_0_arg0, ZEND_ATTRIBUTE_TARGET_CLASS); - ZVAL_COPY_VALUE(&attribute_Attribute_class_Attribute_0->args[0].value, &attribute_Attribute_class_Attribute_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_Attribute_0, true); + ZVAL_LONG(&attribute_Attribute_class_Attribute_0->args[0].value, ZEND_ATTRIBUTE_TARGET_CLASS); return class_entry; } @@ -170,12 +168,10 @@ static zend_class_entry *register_class_ReturnTypeWillChange(void) INIT_CLASS_ENTRY(ce, "ReturnTypeWillChange", class_ReturnTypeWillChange_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); - zend_string *attribute_name_Attribute_class_ReturnTypeWillChange_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_ReturnTypeWillChange_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_ReturnTypeWillChange_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_ReturnTypeWillChange_0, 1); - zend_string_release(attribute_name_Attribute_class_ReturnTypeWillChange_0); - zval attribute_Attribute_class_ReturnTypeWillChange_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_ReturnTypeWillChange_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD); - ZVAL_COPY_VALUE(&attribute_Attribute_class_ReturnTypeWillChange_0->args[0].value, &attribute_Attribute_class_ReturnTypeWillChange_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_ReturnTypeWillChange_0, true); + ZVAL_LONG(&attribute_Attribute_class_ReturnTypeWillChange_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD); return class_entry; } @@ -187,12 +183,10 @@ static zend_class_entry *register_class_AllowDynamicProperties(void) INIT_CLASS_ENTRY(ce, "AllowDynamicProperties", class_AllowDynamicProperties_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL); - zend_string *attribute_name_Attribute_class_AllowDynamicProperties_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_AllowDynamicProperties_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_AllowDynamicProperties_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_AllowDynamicProperties_0, 1); - zend_string_release(attribute_name_Attribute_class_AllowDynamicProperties_0); - zval attribute_Attribute_class_AllowDynamicProperties_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_AllowDynamicProperties_0_arg0, ZEND_ATTRIBUTE_TARGET_CLASS); - ZVAL_COPY_VALUE(&attribute_Attribute_class_AllowDynamicProperties_0->args[0].value, &attribute_Attribute_class_AllowDynamicProperties_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_AllowDynamicProperties_0, true); + ZVAL_LONG(&attribute_Attribute_class_AllowDynamicProperties_0->args[0].value, ZEND_ATTRIBUTE_TARGET_CLASS); return class_entry; } @@ -204,12 +198,10 @@ static zend_class_entry *register_class_SensitiveParameter(void) INIT_CLASS_ENTRY(ce, "SensitiveParameter", class_SensitiveParameter_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); - zend_string *attribute_name_Attribute_class_SensitiveParameter_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_SensitiveParameter_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_SensitiveParameter_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_SensitiveParameter_0, 1); - zend_string_release(attribute_name_Attribute_class_SensitiveParameter_0); - zval attribute_Attribute_class_SensitiveParameter_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_SensitiveParameter_0_arg0, ZEND_ATTRIBUTE_TARGET_PARAMETER); - ZVAL_COPY_VALUE(&attribute_Attribute_class_SensitiveParameter_0->args[0].value, &attribute_Attribute_class_SensitiveParameter_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_SensitiveParameter_0, true); + ZVAL_LONG(&attribute_Attribute_class_SensitiveParameter_0->args[0].value, ZEND_ATTRIBUTE_TARGET_PARAMETER); return class_entry; } @@ -235,12 +227,10 @@ static zend_class_entry *register_class_Override(void) INIT_CLASS_ENTRY(ce, "Override", class_Override_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); - zend_string *attribute_name_Attribute_class_Override_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_Override_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_Override_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Override_0, 1); - zend_string_release(attribute_name_Attribute_class_Override_0); - zval attribute_Attribute_class_Override_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_Override_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD); - ZVAL_COPY_VALUE(&attribute_Attribute_class_Override_0->args[0].value, &attribute_Attribute_class_Override_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_Override_0, true); + ZVAL_LONG(&attribute_Attribute_class_Override_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_PROPERTY); return class_entry; } @@ -260,12 +250,10 @@ static zend_class_entry *register_class_Deprecated(void) ZVAL_UNDEF(&property_since_default_value); zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_SINCE), &property_since_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string *attribute_name_Attribute_class_Deprecated_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_Deprecated_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_Deprecated_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Deprecated_0, 1); - zend_string_release(attribute_name_Attribute_class_Deprecated_0); - zval attribute_Attribute_class_Deprecated_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_Deprecated_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION | ZEND_ATTRIBUTE_TARGET_CLASS_CONST | ZEND_ATTRIBUTE_TARGET_CONST); - ZVAL_COPY_VALUE(&attribute_Attribute_class_Deprecated_0->args[0].value, &attribute_Attribute_class_Deprecated_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_Deprecated_0, true); + ZVAL_LONG(&attribute_Attribute_class_Deprecated_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION | ZEND_ATTRIBUTE_TARGET_CLASS_CONST | ZEND_ATTRIBUTE_TARGET_CONST | ZEND_ATTRIBUTE_TARGET_CLASS); return class_entry; } @@ -281,12 +269,25 @@ static zend_class_entry *register_class_NoDiscard(void) ZVAL_UNDEF(&property_message_default_value); zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_MESSAGE), &property_message_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string *attribute_name_Attribute_class_NoDiscard_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1); + zend_string *attribute_name_Attribute_class_NoDiscard_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); zend_attribute *attribute_Attribute_class_NoDiscard_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_NoDiscard_0, 1); - zend_string_release(attribute_name_Attribute_class_NoDiscard_0); - zval attribute_Attribute_class_NoDiscard_0_arg0; - ZVAL_LONG(&attribute_Attribute_class_NoDiscard_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION); - ZVAL_COPY_VALUE(&attribute_Attribute_class_NoDiscard_0->args[0].value, &attribute_Attribute_class_NoDiscard_0_arg0); + zend_string_release_ex(attribute_name_Attribute_class_NoDiscard_0, true); + ZVAL_LONG(&attribute_Attribute_class_NoDiscard_0->args[0].value, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION); + + return class_entry; +} + +static zend_class_entry *register_class_DelayedTargetValidation(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "DelayedTargetValidation", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + zend_string *attribute_name_Attribute_class_DelayedTargetValidation_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, true); + zend_attribute *attribute_Attribute_class_DelayedTargetValidation_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_DelayedTargetValidation_0, 1); + zend_string_release_ex(attribute_name_Attribute_class_DelayedTargetValidation_0, true); + ZVAL_LONG(&attribute_Attribute_class_DelayedTargetValidation_0->args[0].value, ZEND_ATTRIBUTE_TARGET_ALL); return class_entry; } diff --git a/Zend/zend_autoload.c b/Zend/zend_autoload.c new file mode 100644 index 000000000000..2ca3d7eea022 --- /dev/null +++ b/Zend/zend_autoload.c @@ -0,0 +1,165 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gina Peter Banyard | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_API.h" +#include "zend_autoload.h" +#include "zend_hash.h" +#include "zend_types.h" +#include "zend_exceptions.h" +#include "zend_string.h" + +ZEND_TLS HashTable *zend_class_autoload_functions; + +static void zend_autoload_callback_zval_destroy(zval *element) +{ + zend_fcall_info_cache *fcc = Z_PTR_P(element); + zend_fcc_dtor(fcc); + efree(fcc); +} + +static Bucket *autoload_find_registered_function(const HashTable *autoloader_table, const zend_fcall_info_cache *function_entry) +{ + zend_fcall_info_cache *current_function_entry; + ZEND_HASH_MAP_FOREACH_PTR(autoloader_table, current_function_entry) { + if (zend_fcc_equals(current_function_entry, function_entry)) { + return _p; + } + } ZEND_HASH_FOREACH_END(); + return NULL; +} + +ZEND_API zend_class_entry *zend_perform_class_autoload(zend_string *class_name, zend_string *lc_name) +{ + if (!zend_class_autoload_functions) { + return NULL; + } + + zval zname; + ZVAL_STR(&zname, class_name); + + const HashTable *class_autoload_functions = zend_class_autoload_functions; + + /* Cannot use ZEND_HASH_MAP_FOREACH_PTR here as autoloaders may be + * added/removed during autoloading. */ + HashPosition pos; + zend_hash_internal_pointer_reset_ex(class_autoload_functions, &pos); + while (true) { + zend_fcall_info_cache *func_info = zend_hash_get_current_data_ptr_ex(class_autoload_functions, &pos); + if (!func_info) { + break; + } + zend_call_known_fcc(func_info, /* retval */ NULL, /* param_count */ 1, /* params */ &zname, /* named_params */ NULL); + + if (EG(exception)) { + return NULL; + } + if (ZSTR_HAS_CE_CACHE(class_name) && ZSTR_GET_CE_CACHE(class_name)) { + return (zend_class_entry*)ZSTR_GET_CE_CACHE(class_name); + } + + zend_class_entry *ce = zend_hash_find_ptr(EG(class_table), lc_name); + if (ce) { + return ce; + } + + zend_hash_move_forward_ex(class_autoload_functions, &pos); + } + return NULL; +} + +/* Needed for compatibility with spl_register_autoload() */ +ZEND_API void zend_autoload_register_class_loader(zend_fcall_info_cache *fcc, bool prepend) +{ + ZEND_ASSERT(ZEND_FCC_INITIALIZED(*fcc)); + + if (!zend_class_autoload_functions) { + ALLOC_HASHTABLE(zend_class_autoload_functions); + zend_hash_init(zend_class_autoload_functions, 1, NULL, zend_autoload_callback_zval_destroy, false); + /* Initialize as non-packed hash table for prepend functionality. */ + zend_hash_real_init_mixed(zend_class_autoload_functions); + } + + ZEND_ASSERT( + fcc->function_handler->type != ZEND_INTERNAL_FUNCTION + || !zend_string_equals_literal(fcc->function_handler->common.function_name, "spl_autoload_call") + ); + + /* If function is already registered, don't do anything */ + if (autoload_find_registered_function(zend_class_autoload_functions, fcc)) { + /* Release potential call trampoline */ + zend_release_fcall_info_cache(fcc); + return; + } + + zend_fcc_addref(fcc); + zend_hash_next_index_insert_mem(zend_class_autoload_functions, fcc, sizeof(zend_fcall_info_cache)); + if (prepend && zend_hash_num_elements(zend_class_autoload_functions) > 1) { + /* Move the newly created element to the head of the hashtable */ + ZEND_ASSERT(!HT_IS_PACKED(zend_class_autoload_functions)); + Bucket tmp = zend_class_autoload_functions->arData[zend_class_autoload_functions->nNumUsed-1]; + memmove(zend_class_autoload_functions->arData + 1, zend_class_autoload_functions->arData, sizeof(Bucket) * (zend_class_autoload_functions->nNumUsed - 1)); + zend_class_autoload_functions->arData[0] = tmp; + zend_hash_rehash(zend_class_autoload_functions); + } +} + +ZEND_API bool zend_autoload_unregister_class_loader(const zend_fcall_info_cache *fcc) { + if (zend_class_autoload_functions) { + Bucket *p = autoload_find_registered_function(zend_class_autoload_functions, fcc); + if (p) { + zend_hash_del_bucket(zend_class_autoload_functions, p); + return true; + } + } + return false; +} + +/* We do not return a HashTable* because zend_empty_array is not collectable, + * therefore the zval holding this value must do so. Something that ZVAL_EMPTY_ARRAY(); does. */ +ZEND_API void zend_autoload_fcc_map_to_callable_zval_map(zval *return_value) { + if (zend_class_autoload_functions) { + zend_fcall_info_cache *fcc; + + zend_array *map = zend_new_array(zend_hash_num_elements(zend_class_autoload_functions)); + ZEND_HASH_MAP_FOREACH_PTR(zend_class_autoload_functions, fcc) { + zval tmp; + zend_get_callable_zval_from_fcc(fcc, &tmp); + zend_hash_next_index_insert(map, &tmp); + } ZEND_HASH_FOREACH_END(); + RETURN_ARR(map); + } + RETURN_EMPTY_ARRAY(); +} + +/* Only for deprecated strange behaviour of spl_autoload_unregister() */ +ZEND_API void zend_autoload_clean_class_loaders(void) +{ + if (zend_class_autoload_functions) { + /* Don't destroy the hash table, as we might be iterating over it right now. */ + zend_hash_clean(zend_class_autoload_functions); + } +} + +void zend_autoload_shutdown(void) +{ + if (zend_class_autoload_functions) { + zend_hash_destroy(zend_class_autoload_functions); + FREE_HASHTABLE(zend_class_autoload_functions); + zend_class_autoload_functions = NULL; + } +} diff --git a/Zend/zend_autoload.h b/Zend/zend_autoload.h new file mode 100644 index 000000000000..84e6ab80b5af --- /dev/null +++ b/Zend/zend_autoload.h @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gina Peter Banyard | + +----------------------------------------------------------------------+ +*/ + +#ifndef _ZEND_AUTOLOAD_H +#define _ZEND_AUTOLOAD_H + +#include "zend_string.h" +#include "zend_hash.h" +#include "zend_API.h" +#include "zend.h" + +ZEND_API zend_class_entry *zend_perform_class_autoload(zend_string *class_name, zend_string *lc_name); +ZEND_API void zend_autoload_register_class_loader(zend_fcall_info_cache *fcc, bool prepend); +ZEND_API bool zend_autoload_unregister_class_loader(const zend_fcall_info_cache *fcc); +ZEND_API void zend_autoload_fcc_map_to_callable_zval_map(zval *return_value); +/* Only for deprecated strange behaviour of spl_autoload_unregister() */ +ZEND_API void zend_autoload_clean_class_loaders(void); +void zend_autoload_shutdown(void); + +#endif diff --git a/Zend/zend_bitset.h b/Zend/zend_bitset.h index d990b6a2a871..877f2aaabc05 100644 --- a/Zend/zend_bitset.h +++ b/Zend/zend_bitset.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/Zend/zend_build.h b/Zend/zend_build.h index c604fb311a74..8ba7064042e3 100644 --- a/Zend/zend_build.h +++ b/Zend/zend_build.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 7a07ceadce2e..a239736ed633 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -2,21 +2,21 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | +----------------------------------------------------------------------+ */ +#include "php_version.h" #include "zend.h" #include "zend_API.h" #include "zend_attributes.h" @@ -29,12 +29,14 @@ #include "zend_extensions.h" #include "zend_closures.h" #include "zend_generators.h" +#include "zend_autoload.h" #include "zend_builtin_functions_arginfo.h" #include "zend_smart_str.h" /* }}} */ ZEND_MINIT_FUNCTION(core) { /* {{{ */ + zend_autoload = zend_perform_class_autoload; zend_register_default_classes(); zend_standard_class_def = register_class_stdClass(); @@ -69,6 +71,52 @@ zend_result zend_startup_builtin_functions(void) /* {{{ */ } /* }}} */ +ZEND_FUNCTION(clone) +{ + zend_object *zobj; + HashTable *with = (HashTable*)&zend_empty_array; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJ(zobj) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT(with) + ZEND_PARSE_PARAMETERS_END(); + + /* clone() also exists as the ZEND_CLONE OPcode and both implementations must be kept in sync. */ + + const zend_class_entry *scope = zend_get_executed_scope(); + + const zend_class_entry *ce = zobj->ce; + const zend_function *clone = ce->clone; + + if (UNEXPECTED(zobj->handlers->clone_obj == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + RETURN_THROWS(); + } + + if (clone && !zend_check_method_accessible(clone, scope)) { + zend_bad_method_call(clone, clone->common.function_name, scope); + RETURN_THROWS(); + } + + zend_object *cloned; + if (zend_hash_num_elements(with) > 0) { + if (UNEXPECTED(!zobj->handlers->clone_obj_with)) { + zend_throw_error(NULL, "Cloning objects of class %s with updated properties is not supported", ZSTR_VAL(ce->name)); + RETURN_THROWS(); + } + + cloned = zobj->handlers->clone_obj_with(zobj, scope, with); + } else { + cloned = zobj->handlers->clone_obj(zobj); + } + + ZEND_ASSERT(cloned || EG(exception)); + if (EXPECTED(cloned)) { + RETURN_OBJ(cloned); + } +} + ZEND_FUNCTION(exit) { zend_string *str = NULL; @@ -191,7 +239,7 @@ ZEND_FUNCTION(gc_status) /* {{{ Get the number of arguments that were passed to the function */ ZEND_FUNCTION(func_num_args) { - zend_execute_data *ex = EX(prev_execute_data); + const zend_execute_data *ex = EX(prev_execute_data); ZEND_PARSE_PARAMETERS_NONE(); @@ -201,7 +249,7 @@ ZEND_FUNCTION(func_num_args) } if (zend_forbid_dynamic_call() == FAILURE) { - RETURN_LONG(-1); + RETURN_THROWS(); } RETURN_LONG(ZEND_CALL_NUM_ARGS(ex)); @@ -323,6 +371,47 @@ ZEND_FUNCTION(func_get_args) } /* }}} */ +/* {{{ Get an array mapping generic type-parameter names to their resolved + * class names for the currently-executed generic function call. Unbound slots + * (parameter has no turbofish, no default, and no inferable position) yield + * NULL — the caller can detect them and fall back to the parameter's bound. */ +ZEND_FUNCTION(func_get_type_args) +{ + zend_execute_data *ex = EX(prev_execute_data); + + ZEND_PARSE_PARAMETERS_NONE(); + + if (ex && (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE)) { + zend_throw_error(NULL, "func_get_type_args() cannot be called from the global scope"); + RETURN_THROWS(); + } + + if (zend_forbid_dynamic_call() == FAILURE) { + RETURN_THROWS(); + } + + const zend_generic_parameter_list *params = NULL; + if (ex && ZEND_USER_CODE(ex->func->type)) { + params = ex->func->op_array.generic_parameters; + } + if (!params || params->count == 0) { + RETURN_EMPTY_ARRAY(); + } + + zend_type_arg_table *table = ex->type_args; + array_init_size(return_value, params->count); + for (uint32_t i = 0; i < params->count; i++) { + zval entry; + if (table && i < table->count && table->entries[i].name) { + ZVAL_STR_COPY(&entry, table->entries[i].name); + } else { + ZVAL_NULL(&entry); + } + zend_hash_add(Z_ARRVAL_P(return_value), params->parameters[i].name, &entry); + } +} +/* }}} */ + /* {{{ Get string length Warning: This function is special-cased by zend_compile.c and so is usually bypassed */ ZEND_FUNCTION(strlen) @@ -455,9 +544,9 @@ ZEND_FUNCTION(error_reporting) } /* }}} */ -static bool validate_constant_array_argument(HashTable *ht, int argument_number) /* {{{ */ +static bool validate_constant_array_argument(HashTable *ht, uint32_t argument_number) /* {{{ */ { - bool ret = 1; + bool ret = true; zval *val; GC_PROTECT_RECURSION(ht); @@ -466,10 +555,10 @@ static bool validate_constant_array_argument(HashTable *ht, int argument_number) if (Z_TYPE_P(val) == IS_ARRAY && Z_REFCOUNTED_P(val)) { if (Z_IS_RECURSIVE_P(val)) { zend_argument_value_error(argument_number, "cannot be a recursive array"); - ret = 0; + ret = false; break; } else if (!validate_constant_array_argument(Z_ARRVAL_P(val), argument_number)) { - ret = 0; + ret = false; break; } } @@ -479,7 +568,7 @@ static bool validate_constant_array_argument(HashTable *ht, int argument_number) } /* }}} */ -static void copy_constant_array(zval *dst, zval *src) /* {{{ */ +static void copy_constant_array(zval *dst, const zval *src) /* {{{ */ { zend_string *key; zend_ulong idx; @@ -509,7 +598,7 @@ static void copy_constant_array(zval *dst, zval *src) /* {{{ */ ZEND_FUNCTION(define) { zend_string *name; - zval *val, val_free; + zval *val; bool non_cs = 0; zend_constant c; @@ -529,31 +618,20 @@ ZEND_FUNCTION(define) zend_error(E_WARNING, "define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported"); } - ZVAL_UNDEF(&val_free); - - if (Z_TYPE_P(val) == IS_ARRAY) { - if (Z_REFCOUNTED_P(val)) { - if (!validate_constant_array_argument(Z_ARRVAL_P(val), 2)) { - RETURN_THROWS(); - } else { - copy_constant_array(&c.value, val); - goto register_constant; - } + if (Z_TYPE_P(val) == IS_ARRAY && Z_REFCOUNTED_P(val)) { + if (!validate_constant_array_argument(Z_ARRVAL_P(val), 2)) { + RETURN_THROWS(); + } else { + copy_constant_array(&c.value, val); } + } else { + ZVAL_COPY(&c.value, val); } - ZVAL_COPY(&c.value, val); - zval_ptr_dtor(&val_free); - -register_constant: /* non persistent */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); c.name = zend_string_copy(name); - if (zend_register_constant(&c) == SUCCESS) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_register_constant(&c) != NULL); } /* }}} */ @@ -567,11 +645,7 @@ ZEND_FUNCTION(defined) Z_PARAM_STR(name) ZEND_PARSE_PARAMETERS_END(); - if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)); } /* }}} */ @@ -585,7 +659,7 @@ ZEND_FUNCTION(get_class) } if (!obj) { - zend_class_entry *scope = zend_get_executed_scope(); + const zend_class_entry *scope = zend_get_executed_scope(); if (scope) { zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); @@ -606,11 +680,9 @@ ZEND_FUNCTION(get_class) /* {{{ Retrieves the "Late Static Binding" class name */ ZEND_FUNCTION(get_called_class) { - zend_class_entry *called_scope; - ZEND_PARSE_PARAMETERS_NONE(); - called_scope = zend_get_called_scope(execute_data); + const zend_class_entry *called_scope = zend_get_called_scope(execute_data); if (!called_scope) { zend_throw_error(NULL, "get_called_class() must be called from within a class"); RETURN_THROWS(); @@ -650,10 +722,8 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, bool only_subclass) /* {{{ * { zval *obj; zend_string *class_name; - zend_class_entry *instance_ce; - zend_class_entry *ce; + const zend_class_entry *instance_ce; bool allow_string = only_subclass; - bool retval; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_ZVAL(obj) @@ -680,21 +750,19 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, bool only_subclass) /* {{{ * } if (!only_subclass && EXPECTED(zend_string_equals(instance_ce->name, class_name))) { - retval = 1; - } else { - ce = zend_lookup_class_ex(class_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (!ce) { - retval = 0; - } else { - if (only_subclass && instance_ce == ce) { - retval = 0; - } else { - retval = instanceof_function(instance_ce, ce); - } - } + RETURN_TRUE; + } + + const zend_class_entry *ce = zend_lookup_class_ex(class_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (!ce) { + RETURN_FALSE; } - RETURN_BOOL(retval); + if (only_subclass && instance_ce == ce) { + RETURN_FALSE; + } + + RETURN_BOOL(instanceof_function(instance_ce, ce)); } /* }}} */ @@ -713,7 +781,7 @@ ZEND_FUNCTION(is_a) /* }}} */ /* {{{ add_class_vars */ -static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool statics, zval *return_value) +static void add_class_vars(const zend_class_entry *scope, zend_class_entry *ce, bool statics, const zval *return_value) { zend_property_info *prop_info; zval *prop, prop_copy; @@ -764,7 +832,7 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool s /* {{{ Returns an array of default properties of the class. */ ZEND_FUNCTION(get_class_vars) { - zend_class_entry *ce = NULL, *scope; + zend_class_entry *ce = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "C", &ce) == FAILURE) { RETURN_THROWS(); @@ -777,9 +845,9 @@ ZEND_FUNCTION(get_class_vars) } } - scope = zend_get_executed_scope(); - add_class_vars(scope, ce, 0, return_value); - add_class_vars(scope, ce, 1, return_value); + const zend_class_entry *scope = zend_get_executed_scope(); + add_class_vars(scope, ce, false, return_value); + add_class_vars(scope, ce, true, return_value); } /* }}} */ @@ -903,7 +971,6 @@ ZEND_FUNCTION(get_class_methods) { zval method_name; zend_class_entry *ce = NULL; - zend_class_entry *scope; zend_function *mptr; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -911,16 +978,10 @@ ZEND_FUNCTION(get_class_methods) ZEND_PARSE_PARAMETERS_END(); array_init(return_value); - scope = zend_get_executed_scope(); + const zend_class_entry *scope = zend_get_executed_scope(); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, mptr) { - if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC) - || (scope && - (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) && - zend_check_protected(mptr->common.scope, scope)) - || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) && - scope == mptr->common.scope))) - ) { + if (zend_check_method_accessible(mptr, scope)) { ZVAL_STR_COPY(&method_name, mptr->common.function_name); zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name); } @@ -992,10 +1053,9 @@ ZEND_FUNCTION(method_exists) } /* }}} */ -static void _property_exists(zval *return_value, zval *object, zend_string *property) +static void _property_exists(zval *return_value, const zval *object, zend_string *property) { zend_class_entry *ce; - zend_property_info *property_info; if (Z_TYPE_P(object) == IS_STRING) { ce = zend_lookup_class(Z_STR_P(object)); @@ -1009,18 +1069,17 @@ static void _property_exists(zval *return_value, zval *object, zend_string *prop RETURN_THROWS(); } - property_info = zend_hash_find_ptr(&ce->properties_info, property); + const zend_property_info *property_info = zend_hash_find_ptr(&ce->properties_info, property); if (property_info != NULL && (!(property_info->flags & ZEND_ACC_PRIVATE) || property_info->ce == ce)) { RETURN_TRUE; } - if (Z_TYPE_P(object) == IS_OBJECT && - Z_OBJ_HANDLER_P(object, has_property)(Z_OBJ_P(object), property, ZEND_PROPERTY_EXISTS, NULL)) { - RETURN_TRUE; - } - RETURN_FALSE; + RETURN_BOOL( + Z_TYPE_P(object) == IS_OBJECT && + Z_OBJ_HANDLER_P(object, has_property)(Z_OBJ_P(object), property, ZEND_PROPERTY_EXISTS, NULL) + ); } /* {{{ Checks if the object or class has a property */ @@ -1053,10 +1112,10 @@ flf_clean:; Z_FLF_PARAM_FREE_STR(2, property_tmp) } -static inline void _class_exists_impl(zval *return_value, zend_string *name, bool autoload, int flags, int skip_flags) /* {{{ */ +static zend_always_inline void _class_exists_impl(zval *return_value, zend_string *name, bool autoload, int flags, int skip_flags) /* {{{ */ { zend_string *lcname; - zend_class_entry *ce; + const zend_class_entry *ce; if (ZSTR_HAS_CE_CACHE(name)) { ce = ZSTR_GET_CE_CACHE(name); @@ -1080,11 +1139,7 @@ static inline void _class_exists_impl(zval *return_value, zend_string *name, boo ce = zend_lookup_class(name); } - if (ce) { - RETURN_BOOL(((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags)); - } else { - RETURN_FALSE; - } + RETURN_BOOL(ce && ((ce->ce_flags & flags) == flags) && !(ce->ce_flags & skip_flags)); } /* {{{ */ @@ -1390,7 +1445,6 @@ static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int fla { zend_string *key; zval *zv; - zend_class_entry *ce; ZEND_PARSE_PARAMETERS_NONE(); @@ -1398,7 +1452,7 @@ static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int fla zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) { - ce = Z_PTR_P(zv); + const zend_class_entry *ce = Z_PTR_P(zv); if ((ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT)) == flags && key && ZSTR_VAL(key)[0] != 0) { @@ -1443,15 +1497,15 @@ ZEND_FUNCTION(get_defined_functions) zval internal, user; zend_string *key; zend_function *func; - bool exclude_disabled = 1; + bool exclude_disabled = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &exclude_disabled) == FAILURE) { RETURN_THROWS(); } - if (exclude_disabled == 0) { + if (ZEND_NUM_ARGS() == 1) { zend_error(E_DEPRECATED, - "get_defined_functions(): Setting $exclude_disabled to false has no effect"); + "get_defined_functions(): The $exclude_disabled parameter has no effect since PHP 8.0"); } array_init(&internal); @@ -1516,7 +1570,7 @@ ZEND_FUNCTION(get_resource_type) if (resource_type) { RETURN_STRING(resource_type); } else { - RETURN_STRING("Unknown"); + RETURN_INTERNED_STR(ZSTR_KNOWN(ZEND_STR_UNKNOWN_CAPITALIZED)); } } /* }}} */ @@ -1581,7 +1635,7 @@ ZEND_FUNCTION(get_resources) } /* }}} */ -static void add_zendext_info(zend_extension *ext, void *arg) /* {{{ */ +static void add_zendext_info(const zend_extension *ext, void *arg) /* {{{ */ { zval *name_array = (zval *)arg; add_next_index_string(name_array, ext->name); @@ -1591,7 +1645,7 @@ static void add_zendext_info(zend_extension *ext, void *arg) /* {{{ */ /* {{{ Return an array containing names of loaded extensions */ ZEND_FUNCTION(get_loaded_extensions) { - bool zendext = 0; + bool zendext = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &zendext) == FAILURE) { RETURN_THROWS(); @@ -1614,7 +1668,7 @@ ZEND_FUNCTION(get_loaded_extensions) /* {{{ Return an array containing the names and values of all defined constants */ ZEND_FUNCTION(get_defined_constants) { - bool categorize = 0; + bool categorize = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &categorize) == FAILURE) { RETURN_THROWS(); @@ -1682,6 +1736,18 @@ ZEND_FUNCTION(get_defined_constants) } /* }}} */ +static bool backtrace_is_arg_sensitive(const zend_execute_data *call, uint32_t offset) +{ + const zend_attribute *attribute = zend_get_parameter_attribute_str( + call->func->common.attributes, + "sensitiveparameter", + sizeof("sensitiveparameter") - 1, + offset + ); + + return attribute != NULL; +} + static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /* {{{ */ { uint32_t num_args = ZEND_CALL_NUM_ARGS(call); @@ -1705,14 +1771,7 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / zend_string *arg_name = call->func->op_array.vars[i]; zval original_arg; zval *arg = zend_hash_find_ex_ind(call->symbol_table, arg_name, 1); - zend_attribute *attribute = zend_get_parameter_attribute_str( - call->func->common.attributes, - "sensitiveparameter", - sizeof("sensitiveparameter") - 1, - i - ); - - bool is_sensitive = attribute != NULL; + bool is_sensitive = backtrace_is_arg_sensitive(call, i); if (arg) { ZVAL_DEREF(arg); @@ -1723,8 +1782,7 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / if (is_sensitive) { zval redacted_arg; - object_init_ex(&redacted_arg, zend_ce_sensitive_parameter_value); - zend_call_known_function(Z_OBJCE_P(&redacted_arg)->constructor, Z_OBJ_P(&redacted_arg), Z_OBJCE_P(&redacted_arg), NULL, 1, &original_arg, NULL); + object_init_with_constructor(&redacted_arg, zend_ce_sensitive_parameter_value, 1, &original_arg, NULL); ZEND_HASH_FILL_SET(&redacted_arg); } else { Z_TRY_ADDREF_P(&original_arg); @@ -1737,13 +1795,7 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / } else { while (i < first_extra_arg) { zval original_arg; - zend_attribute *attribute = zend_get_parameter_attribute_str( - call->func->common.attributes, - "sensitiveparameter", - sizeof("sensitiveparameter") - 1, - i - ); - bool is_sensitive = attribute != NULL; + bool is_sensitive = backtrace_is_arg_sensitive(call, i); if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) { zval *arg = p; @@ -1755,8 +1807,7 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / if (is_sensitive) { zval redacted_arg; - object_init_ex(&redacted_arg, zend_ce_sensitive_parameter_value); - zend_call_known_function(Z_OBJCE_P(&redacted_arg)->constructor, Z_OBJ_P(&redacted_arg), Z_OBJCE_P(&redacted_arg), NULL, 1, &original_arg, NULL); + object_init_with_constructor(&redacted_arg, zend_ce_sensitive_parameter_value, 1, &original_arg, NULL); ZEND_HASH_FILL_SET(&redacted_arg); } else { Z_TRY_ADDREF_P(&original_arg); @@ -1776,13 +1827,7 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / bool is_sensitive = 0; if (i < call->func->common.num_args || call->func->common.fn_flags & ZEND_ACC_VARIADIC) { - zend_attribute *attribute = zend_get_parameter_attribute_str( - call->func->common.attributes, - "sensitiveparameter", - sizeof("sensitiveparameter") - 1, - MIN(i, call->func->common.num_args) - ); - is_sensitive = attribute != NULL; + is_sensitive = backtrace_is_arg_sensitive(call, MIN(i, call->func->common.num_args)); } if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) { @@ -1795,8 +1840,7 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / if (is_sensitive) { zval redacted_arg; - object_init_ex(&redacted_arg, zend_ce_sensitive_parameter_value); - zend_call_known_function(Z_OBJCE_P(&redacted_arg)->constructor, Z_OBJ_P(&redacted_arg), Z_OBJCE_P(&redacted_arg), NULL, 1, &original_arg, NULL); + object_init_with_constructor(&redacted_arg, zend_ce_sensitive_parameter_value, 1, &original_arg, NULL); ZEND_HASH_FILL_SET(&redacted_arg); } else { Z_TRY_ADDREF_P(&original_arg); @@ -1813,14 +1857,27 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / ZVAL_EMPTY_ARRAY(arg_array); } - if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + if ((ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) + /* __call and __callStatic are non-variadic, potentially with + * HAS_EXTRA_NAMED_PARAMS set. Don't add extra args, as they're already + * contained in the 2nd param. */ + && (call->func->common.fn_flags & ZEND_ACC_VARIADIC)) { zend_string *name; zval *arg; + + bool is_sensitive = backtrace_is_arg_sensitive(call, call->func->common.num_args); + SEPARATE_ARRAY(arg_array); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(call->extra_named_params, name, arg) { ZVAL_DEREF(arg); - Z_TRY_ADDREF_P(arg); - zend_hash_add_new(Z_ARRVAL_P(arg_array), name, arg); + if (is_sensitive) { + zval redacted_arg; + object_init_with_constructor(&redacted_arg, zend_ce_sensitive_parameter_value, 1, arg, NULL); + zend_hash_add_new(Z_ARRVAL_P(arg_array), name, &redacted_arg); + } else { + Z_TRY_ADDREF_P(arg); + zend_hash_add_new(Z_ARRVAL_P(arg_array), name, arg); + } } ZEND_HASH_FOREACH_END(); } } @@ -1852,8 +1909,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int { zend_execute_data *call, *last_call = NULL; zend_object *object; - bool fake_frame = 0; - int lineno, frameno = 0; + bool fake_frame = false; + int frameno = 0; zend_function *func; zend_string *filename; zend_string *include_filename = NULL; @@ -1874,12 +1931,12 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int EG(filename_override) = NULL; EG(lineno_override) = -1; - zend_string *filename = zend_get_executed_filename_ex(); - zend_long lineno = zend_get_executed_lineno(); - if (filename && (!zend_string_equals(filename, filename_override) || lineno != lineno_override)) { + zend_string *executed_filename = zend_get_executed_filename_ex(); + uint32_t lineno = zend_get_executed_lineno(); + if (executed_filename && (!zend_string_equals(executed_filename, filename_override) || lineno != lineno_override)) { stack_frame = zend_new_array(8); zend_hash_real_init_mixed(stack_frame); - ZVAL_STR_COPY(&tmp, filename); + ZVAL_STR_COPY(&tmp, executed_filename); _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FILE), &tmp, 1); ZVAL_LONG(&tmp, lineno); _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_LINE), &tmp, 1); @@ -1942,20 +1999,21 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int zval *arg = zend_get_zval_ptr(op_data, op_data->op1_type, &op_data->op1, call); if (Z_TYPE_P(arg) == IS_UNDEF) goto not_frameless_call; } - zend_function *func = ZEND_FLF_FUNC(opline); + zend_function *frameless_func = ZEND_FLF_FUNC(opline); /* Assume frameless functions are not recursive with themselves. * This condition may be true when observers are enabled: * Observers will put a call frame on top of the frameless opcode. */ - if (last_call && last_call->func == func) { + if (last_call && last_call->func == frameless_func) { goto not_frameless_call; } stack_frame = zend_new_array(8); zend_hash_real_init_mixed(stack_frame); - zend_string *name = func->common.function_name; - ZVAL_STRINGL(&tmp, ZSTR_VAL(name), ZSTR_LEN(name)); + ZVAL_STR_COPY(&tmp, frameless_func->common.function_name); _zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1); /* Steal file and line from the previous frame. */ if (call->func && ZEND_USER_CODE(call->func->common.type)) { + uint32_t lineno; + filename = call->func->op_array.filename; if (call->opline->opcode == ZEND_HANDLE_EXCEPTION) { if (EG(opline_before_exception)) { @@ -2007,6 +2065,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int zend_hash_real_init_mixed(stack_frame); if (prev && prev->func && ZEND_USER_CODE(prev->func->common.type)) { + uint32_t lineno; + filename = prev->func->op_array.filename; if (prev->opline->opcode == ZEND_HANDLE_EXCEPTION) { if (EG(opline_before_exception)) { @@ -2089,7 +2149,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int } } else { /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */ - bool build_filename_arg = 1; + bool build_filename_arg = true; zend_string *pseudo_function_name; uint32_t include_kind = 0; if (prev && prev->func && ZEND_USER_CODE(prev->func->common.type) && prev->opline->opcode == ZEND_INCLUDE_OR_EVAL) { @@ -2099,7 +2159,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int switch (include_kind) { case ZEND_EVAL: pseudo_function_name = ZSTR_KNOWN(ZEND_STR_EVAL); - build_filename_arg = 0; + build_filename_arg = false; break; case ZEND_INCLUDE: pseudo_function_name = ZSTR_KNOWN(ZEND_STR_INCLUDE); @@ -2121,7 +2181,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int } pseudo_function_name = ZSTR_KNOWN(ZEND_STR_UNKNOWN); - build_filename_arg = 0; + build_filename_arg = false; break; } @@ -2155,9 +2215,9 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int && prev->func && ZEND_USER_CODE(prev->func->common.type) && prev->opline->opcode == ZEND_INCLUDE_OR_EVAL) { - fake_frame = 1; + fake_frame = true; } else { - fake_frame = 0; + fake_frame = false; include_filename = filename; last_call = call; call = prev; @@ -2191,11 +2251,7 @@ ZEND_FUNCTION(extension_loaded) } lcname = zend_string_tolower(extension_name); - if (zend_hash_exists(&module_registry, lcname)) { - RETVAL_TRUE; - } else { - RETVAL_FALSE; - } + RETVAL_BOOL(zend_hash_exists(&module_registry, lcname)); zend_string_release_ex(lcname, 0); } /* }}} */ @@ -2227,9 +2283,9 @@ ZEND_FUNCTION(get_extension_funcs) if (module->functions) { /* avoid BC break, if functions list is empty, will return an empty array */ array_init(return_value); - array = 1; + array = true; } else { - array = 0; + array = false; } ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), zif) { @@ -2237,7 +2293,7 @@ ZEND_FUNCTION(get_extension_funcs) && zif->internal_function.module == module) { if (!array) { array_init(return_value); - array = 1; + array = true; } add_next_index_str(return_value, zend_string_copy(zif->common.function_name)); } diff --git a/Zend/zend_builtin_functions.h b/Zend/zend_builtin_functions.h index 237b34b2927b..018d0cdb1c1d 100644 --- a/Zend/zend_builtin_functions.h +++ b/Zend/zend_builtin_functions.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index 7f316835aea6..1c587f9193fe 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -7,6 +7,9 @@ class stdClass { } +/** @refcount 1 */ +function clone(object $object, array $withProperties = []): object {} + function exit(string|int $status = 0): never {} /** @alias exit */ @@ -15,13 +18,24 @@ function die(string|int $status = 0): never {} /** @refcount 1 */ function zend_version(): string {} +/** @forbid-dynamic-calls */ function func_num_args(): int {} +/** @forbid-dynamic-calls */ function func_get_arg(int $position): mixed {} -/** @return array */ +/** + * @return array + * @forbid-dynamic-calls + */ function func_get_args(): array {} +/** + * @return array + * @forbid-dynamic-calls + */ +function func_get_type_args(): array {} + function strlen(string $string): int {} /** @compile-time-eval */ @@ -153,6 +167,7 @@ function get_defined_functions(bool $exclude_disabled = true): array {} /** * @return array * @refcount 1 + * @forbid-dynamic-calls */ function get_defined_vars(): array {} diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index 9498b8292f89..d4aab19bbb82 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,5 +1,10 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: a24761186f1ddf758e648b0a764826537cbd33b9 */ +/* This is a generated file, edit zend_builtin_functions.stub.php instead. + * Stub hash: b435953eed1678fa83dd72073c0e95e997ce1d07 */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_clone, 0, 1, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, withProperties, IS_ARRAY, 0, "[]") +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_exit, 0, 0, IS_NEVER, 0) ZEND_ARG_TYPE_MASK(0, status, MAY_BE_STRING|MAY_BE_LONG, "0") @@ -20,6 +25,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_func_get_args, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() +#define arginfo_func_get_type_args arginfo_func_get_args + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_strlen, 0, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -243,11 +250,13 @@ static const zend_frameless_function_info frameless_function_infos_class_exists[ { 0 }, }; +ZEND_FUNCTION(clone); ZEND_FUNCTION(exit); ZEND_FUNCTION(zend_version); ZEND_FUNCTION(func_num_args); ZEND_FUNCTION(func_get_arg); ZEND_FUNCTION(func_get_args); +ZEND_FUNCTION(func_get_type_args); ZEND_FUNCTION(strlen); ZEND_FUNCTION(strcmp); ZEND_FUNCTION(strncmp); @@ -306,12 +315,30 @@ ZEND_FUNCTION(gc_disable); ZEND_FUNCTION(gc_status); static const zend_function_entry ext_functions[] = { + ZEND_FE(clone, arginfo_clone) ZEND_FE(exit, arginfo_exit) ZEND_RAW_FENTRY("die", zif_exit, arginfo_die, 0, NULL, NULL) ZEND_FE(zend_version, arginfo_zend_version) - ZEND_FE(func_num_args, arginfo_func_num_args) - ZEND_FE(func_get_arg, arginfo_func_get_arg) - ZEND_FE(func_get_args, arginfo_func_get_args) +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("func_num_args", zif_func_num_args, arginfo_func_num_args, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("func_num_args", zif_func_num_args, arginfo_func_num_args, 0, NULL, NULL) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("func_get_arg", zif_func_get_arg, arginfo_func_get_arg, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("func_get_arg", zif_func_get_arg, arginfo_func_get_arg, 0, NULL, NULL) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("func_get_args", zif_func_get_args, arginfo_func_get_args, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("func_get_args", zif_func_get_args, arginfo_func_get_args, 0, NULL, NULL) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("func_get_type_args", zif_func_get_type_args, arginfo_func_get_type_args, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("func_get_type_args", zif_func_get_type_args, arginfo_func_get_type_args, 0, NULL, NULL) +#endif ZEND_FE(strlen, arginfo_strlen) ZEND_RAW_FENTRY("strcmp", zif_strcmp, arginfo_strcmp, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("strncmp", zif_strncmp, arginfo_strncmp, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) @@ -351,7 +378,11 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(get_declared_traits, arginfo_get_declared_traits) ZEND_FE(get_declared_interfaces, arginfo_get_declared_interfaces) ZEND_FE(get_defined_functions, arginfo_get_defined_functions) - ZEND_FE(get_defined_vars, arginfo_get_defined_vars) +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("get_defined_vars", zif_get_defined_vars, arginfo_get_defined_vars, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("get_defined_vars", zif_get_defined_vars, arginfo_get_defined_vars, 0, NULL, NULL) +#endif ZEND_FE(get_resource_type, arginfo_get_resource_type) ZEND_FE(get_resource_id, arginfo_get_resource_id) ZEND_FE(get_resources, arginfo_get_resources) @@ -380,9 +411,9 @@ static zend_class_entry *register_class_stdClass(void) INIT_CLASS_ENTRY(ce, "stdClass", NULL); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES); - zend_string *attribute_name_AllowDynamicProperties_class_stdClass_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, 1); + zend_string *attribute_name_AllowDynamicProperties_class_stdClass_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, true); zend_add_class_attribute(class_entry, attribute_name_AllowDynamicProperties_class_stdClass_0, 0); - zend_string_release(attribute_name_AllowDynamicProperties_class_stdClass_0); + zend_string_release_ex(attribute_name_AllowDynamicProperties_class_stdClass_0, true); return class_entry; } diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index ed86ecc74a23..aa23c2e3e2fa 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | +----------------------------------------------------------------------+ diff --git a/Zend/zend_call_stack.h b/Zend/zend_call_stack.h index fee528c150f0..c0b84334239d 100644 --- a/Zend/zend_call_stack.h +++ b/Zend/zend_call_stack.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | +----------------------------------------------------------------------+ @@ -21,6 +20,9 @@ #include "zend.h" #include "zend_portability.h" +#ifdef _MSC_VER +# include +#endif #ifdef __APPLE__ # include #endif diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 5777e1a34a2b..c0ceee2ea756 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | | Dmitry Stogov | @@ -28,13 +27,8 @@ #include "zend_globals.h" #include "zend_closures_arginfo.h" -typedef struct _zend_closure { - zend_object std; - zend_function func; - zval this_ptr; - zend_class_entry *called_scope; - zif_handler orig_internal_handler; -} zend_closure; +/* zend_closure struct is defined in zend_closures.h so VM hot paths can + * inline the captured_type_args propagation in zend_vm_init_call_frame. */ /* non-static since it needs to be referenced */ ZEND_API zend_class_entry *zend_ce_closure; @@ -81,46 +75,46 @@ static bool zend_valid_closure_binding( bool is_fake_closure = (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) != 0; if (newthis) { if (func->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_WARNING, "Cannot bind an instance to a static closure"); - return 0; + zend_error(E_WARNING, "Cannot bind an instance to a static closure, this will be an error in PHP 9"); + return false; } if (is_fake_closure && func->common.scope && !instanceof_function(Z_OBJCE_P(newthis), func->common.scope)) { /* Binding incompatible $this to an internal method is not supported. */ - zend_error(E_WARNING, "Cannot bind method %s::%s() to object of class %s", + zend_error(E_WARNING, "Cannot bind method %s::%s() to object of class %s, this will be an error in PHP 9", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name), ZSTR_VAL(Z_OBJCE_P(newthis)->name)); - return 0; + return false; } } else if (is_fake_closure && func->common.scope && !(func->common.fn_flags & ZEND_ACC_STATIC)) { - zend_error(E_WARNING, "Cannot unbind $this of method"); - return 0; + zend_error(E_WARNING, "Cannot unbind $this of method, this will be an error in PHP 9"); + return false; } else if (!is_fake_closure && !Z_ISUNDEF(closure->this_ptr) && (func->common.fn_flags & ZEND_ACC_USES_THIS)) { - zend_error(E_WARNING, "Cannot unbind $this of closure using $this"); - return 0; + zend_error(E_WARNING, "Cannot unbind $this of closure using $this, this will be an error in PHP 9"); + return false; } if (scope && scope != func->common.scope && scope->type == ZEND_INTERNAL_CLASS) { /* rebinding to internal class is not allowed */ - zend_error(E_WARNING, "Cannot bind closure to scope of internal class %s", + zend_error(E_WARNING, "Cannot bind closure to scope of internal class %s, this will be an error in PHP 9", ZSTR_VAL(scope->name)); - return 0; + return false; } if (is_fake_closure && scope != func->common.scope) { if (func->common.scope == NULL) { - zend_error(E_WARNING, "Cannot rebind scope of closure created from function"); + zend_error(E_WARNING, "Cannot rebind scope of closure created from function, this will be an error in PHP 9"); } else { - zend_error(E_WARNING, "Cannot rebind scope of closure created from method"); + zend_error(E_WARNING, "Cannot rebind scope of closure created from method, this will be an error in PHP 9"); } - return 0; + return false; } - return 1; + return true; } /* }}} */ @@ -155,6 +149,7 @@ ZEND_METHOD(Closure, call) fci_cache.object = fci.object = newobj; fci.size = sizeof(fci); + fci.consumed_args = 0; ZVAL_OBJ(&fci.function_name, &closure->std); ZVAL_UNDEF(&closure_result); fci.retval = &closure_result; @@ -174,11 +169,17 @@ ZEND_METHOD(Closure, call) zend_function *my_function; fake_closure = emalloc(sizeof(zend_closure)); - memset(&fake_closure->std, 0, sizeof(fake_closure->std)); + memset(fake_closure, 0, sizeof(zend_closure)); fake_closure->std.gc.refcount = 1; fake_closure->std.gc.u.type_info = GC_NULL; ZVAL_UNDEF(&fake_closure->this_ptr); fake_closure->called_scope = NULL; + /* The fake closure runs the source closure's body; that body still + * resolves outer T-refs against the source's captured T-table. Borrow + * the pointer (no clone) — the source closure outlives the fake, + * which is efree'd at the end of this method without running + * free_storage, so no double-destroy. */ + fake_closure->captured_type_args = closure->captured_type_args; my_function = &fake_closure->func; if (ZEND_USER_CODE(closure->func.type)) { memcpy(my_function, &closure->func, sizeof(zend_op_array)); @@ -252,6 +253,14 @@ static void do_closure_bind(zval *return_value, zval *zclosure, zval *newthis, z } zend_create_closure(return_value, &closure->func, ce, called_scope, newthis); + + /* Re-binding produces a new closure that runs the same body; the body + * still references the outer T-bindings captured at lambda declaration + * time, so carry the T-table over. Without this Closure::bind and + * Closure::bindTo silently erase the reified bindings. */ + if (closure->captured_type_args) { + zend_closure_capture_type_args(return_value, closure->captured_type_args); + } } /* {{{ Create a closure from another one and bind to another object and scope */ @@ -287,6 +296,19 @@ ZEND_METHOD(Closure, bindTo) do_closure_bind(return_value, ZEND_THIS, newthis, scope_obj, scope_str); } +static void zend_copy_parameters_array(const uint32_t param_count, HashTable *argument_array) /* {{{ */ +{ + zval *param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1); + + ZEND_ASSERT(param_count <= ZEND_CALL_NUM_ARGS(EG(current_execute_data))); + + for (uint32_t i = 0; i < param_count; i++) { + Z_TRY_ADDREF_P(param_ptr); + zend_hash_next_index_insert_new(argument_array, param_ptr); + param_ptr++; + } +} + static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ { zend_fcall_info fci; zend_fcall_info_cache fcc; @@ -310,14 +332,14 @@ static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ { array_init_size(&fci.params[1], ZEND_NUM_ARGS() + zend_hash_num_elements(EX(extra_named_params))); /* Avoid conversion from packed to mixed later. */ zend_hash_real_init_mixed(Z_ARRVAL(fci.params[1])); - zend_copy_parameters_array(ZEND_NUM_ARGS(), &fci.params[1]); + zend_copy_parameters_array(ZEND_NUM_ARGS(), Z_ARRVAL(fci.params[1])); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, named_param_zval) { Z_TRY_ADDREF_P(named_param_zval); zend_hash_add_new(Z_ARRVAL(fci.params[1]), name, named_param_zval); } ZEND_HASH_FOREACH_END(); } else if (ZEND_NUM_ARGS()) { array_init_size(&fci.params[1], ZEND_NUM_ARGS()); - zend_copy_parameters_array(ZEND_NUM_ARGS(), &fci.params[1]); + zend_copy_parameters_array(ZEND_NUM_ARGS(), Z_ARRVAL(fci.params[1])); } else { ZVAL_EMPTY_ARRAY(&fci.params[1]); } @@ -326,7 +348,7 @@ static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ { fcc.called_scope = zend_get_called_scope(EG(current_execute_data)); zend_call_function(&fci, &fcc); - + zend_return_unwrap_ref(EG(current_execute_data), return_value); zval_ptr_dtor(&fci.params[1]); } /* }}} */ @@ -418,6 +440,23 @@ ZEND_METHOD(Closure, fromCallable) } /* }}} */ +ZEND_METHOD(Closure, getCurrent) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + zend_execute_data *prev_ex = EX(prev_execute_data); + + if (!prev_ex + || !prev_ex->func + || (prev_ex->func->common.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) { + zend_throw_error(NULL, "Current function is not a closure"); + RETURN_THROWS(); + } + + zend_object *obj = ZEND_CLOSURE_OBJECT(prev_ex->func); + RETURN_OBJ_COPY(obj); +} + static ZEND_COLD zend_function *zend_closure_get_constructor(zend_object *object) /* {{{ */ { zend_throw_error(NULL, "Instantiation of class Closure is not allowed"); @@ -480,7 +519,7 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* { * ZEND_ACC_USER_ARG_INFO flag to prevent invalid usage by Reflection */ invoke->type = ZEND_INTERNAL_FUNCTION; invoke->internal_function.fn_flags = - ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | (closure->func.common.fn_flags & keep_flags); + ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_NEVER_CACHE | (closure->func.common.fn_flags & keep_flags); if (closure->func.type != ZEND_INTERNAL_FUNCTION || (closure->func.common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { invoke->internal_function.fn_flags |= ZEND_ACC_USER_ARG_INFO; @@ -537,6 +576,12 @@ static void zend_closure_free_storage(zend_object *object) /* {{{ */ if (Z_TYPE(closure->this_ptr) != IS_UNDEF) { zval_ptr_dtor(&closure->this_ptr); } + + if (closure->captured_type_args) { + closure->captured_type_args->persisted = false; + zend_type_arg_table_destroy(closure->captured_type_args); + closure->captured_type_args = NULL; + } } /* }}} */ @@ -560,6 +605,13 @@ static zend_object *zend_closure_clone(zend_object *zobject) /* {{{ */ zend_create_closure(&result, &closure->func, closure->func.common.scope, closure->called_scope, &closure->this_ptr); + + /* Carry over the source closure's captured T-table; the clone has the + * same body and resolves the same outer T-refs. */ + if (closure->captured_type_args) { + zend_closure_capture_type_args(&result, closure->captured_type_args); + } + return Z_OBJ(result); } /* }}} */ @@ -588,7 +640,6 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp) zval val; struct _zend_arg_info *arg_info = closure->func.common.arg_info; HashTable *debug_info; - bool zstr_args = (closure->func.type == ZEND_USER_FUNCTION) || (closure->func.common.fn_flags & ZEND_ACC_USER_ARG_INFO); *is_temp = 1; @@ -664,15 +715,9 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp) zend_string *name; zval info; ZEND_ASSERT(arg_info->name && "Argument should have name"); - if (zstr_args) { - name = zend_strpprintf(0, "%s$%s", - ZEND_ARG_SEND_MODE(arg_info) ? "&" : "", - ZSTR_VAL(arg_info->name)); - } else { - name = zend_strpprintf(0, "%s$%s", - ZEND_ARG_SEND_MODE(arg_info) ? "&" : "", - ((zend_internal_arg_info*)arg_info)->name); - } + name = zend_strpprintf(0, "%s$%s", + ZEND_ARG_SEND_MODE(arg_info) ? "&" : "", + ZSTR_VAL(arg_info->name)); ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "" : "")); zend_hash_update(Z_ARRVAL(val), name, &info); zend_string_release_ex(name, 0); @@ -727,6 +772,7 @@ static ZEND_NAMED_FUNCTION(zend_closure_internal_handler) /* {{{ */ { zend_closure *closure = (zend_closure*)ZEND_CLOSURE_OBJECT(EX(func)); closure->orig_internal_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + ZEND_ASSERT(!(closure->func.common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS) || EG(exception)); // Assign to EX(this) so that it is released after observer checks etc. ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_RELEASE_THIS); Z_OBJ(EX(This)) = &closure->std; @@ -806,7 +852,7 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en /* wrap internal function handler to avoid memory leak */ if (UNEXPECTED(closure->func.internal_function.handler == zend_closure_internal_handler)) { /* avoid infinity recursion, by taking handler from nested closure */ - zend_closure *nested = (zend_closure*)((char*)func - XtOffsetOf(zend_closure, func)); + zend_closure *nested = ZEND_CONTAINER_OF(func, zend_closure, func); ZEND_ASSERT(nested->std.ce == zend_ce_closure); closure->orig_internal_handler = nested->orig_internal_handler; } else { @@ -833,6 +879,19 @@ static void zend_create_closure_ex(zval *res, zend_function *func, zend_class_en } } } + +ZEND_API void zend_closure_capture_type_args(zval *closure_zv, zend_type_arg_table *src) +{ + zend_closure *closure = (zend_closure *) Z_OBJ_P(closure_zv); + if (closure->captured_type_args) { + closure->captured_type_args->persisted = false; + zend_type_arg_table_destroy(closure->captured_type_args); + closure->captured_type_args = NULL; + } + if (src) { + closure->captured_type_args = zend_type_arg_table_capture_clone(src); + } +} /* }}} */ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) @@ -849,13 +908,13 @@ ZEND_API void zend_create_fake_closure(zval *res, zend_function *func, zend_clas closure = (zend_closure *)Z_OBJ_P(res); closure->func.common.fn_flags |= ZEND_ACC_FAKE_CLOSURE; + if (Z_TYPE(closure->this_ptr) != IS_OBJECT) { + GC_ADD_FLAGS(&closure->std, GC_NOT_COLLECTABLE); + } } /* }}} */ -/* __call and __callStatic name the arguments "$arguments" in the docs. */ -static zend_internal_arg_info trampoline_arg_info[] = {ZEND_ARG_VARIADIC_TYPE_INFO(false, arguments, IS_MIXED, false)}; - -void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* {{{ */ +void zend_closure_from_frame(zval *return_value, const zend_execute_data *call) { /* {{{ */ zval instance; zend_internal_function trampoline; zend_function *mptr = call->func; @@ -879,9 +938,7 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* { trampoline.function_name = mptr->common.function_name; trampoline.scope = mptr->common.scope; trampoline.doc_comment = NULL; - if (trampoline.fn_flags & ZEND_ACC_VARIADIC) { - trampoline.arg_info = trampoline_arg_info; - } + trampoline.arg_info = mptr->common.arg_info; trampoline.attributes = mptr->common.attributes; zend_free_trampoline(mptr); diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h index ced1b5ba48c1..b7ca1edd65f5 100644 --- a/Zend/zend_closures.h +++ b/Zend/zend_closures.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | | Dmitry Stogov | @@ -24,6 +23,19 @@ BEGIN_EXTERN_C() +typedef struct _zend_closure { + zend_object std; + zend_function func; + zval this_ptr; + zend_class_entry *called_scope; + zif_handler orig_internal_handler; + /* Snapshot of the generic type-arg table from the frame that created + * the closure. The closure owns the allocation; it is marked persisted + * so call-frame teardown skips destroying it. Cleared on closure + * free_obj. NULL when the closure was created outside a generic frame. */ + struct _zend_type_arg_table *captured_type_args; +} zend_closure; + /* This macro depends on zend_closure structure layout */ #define ZEND_CLOSURE_OBJECT(op_array) \ ((zend_object*)((char*)(op_array) - sizeof(zend_object))) @@ -31,12 +43,13 @@ BEGIN_EXTERN_C() void zend_register_closure_ce(void); void zend_closure_bind_var(zval *closure_zv, zend_string *var_name, zval *var); void zend_closure_bind_var_ex(zval *closure_zv, uint32_t offset, zval *val); -void zend_closure_from_frame(zval *closure_zv, zend_execute_data *frame); +void zend_closure_from_frame(zval *closure_zv, const zend_execute_data *frame); extern ZEND_API zend_class_entry *zend_ce_closure; ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr); ZEND_API void zend_create_fake_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr); +ZEND_API void zend_closure_capture_type_args(zval *closure_zv, struct _zend_type_arg_table *src); ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *obj); ZEND_API const zend_function *zend_get_closure_method_def(zend_object *obj); ZEND_API zval* zend_get_closure_this_ptr(zval *obj); diff --git a/Zend/zend_closures.stub.php b/Zend/zend_closures.stub.php index daa92492b188..46b51617eef9 100644 --- a/Zend/zend_closures.stub.php +++ b/Zend/zend_closures.stub.php @@ -21,4 +21,6 @@ public function bindTo(?object $newThis, object|string|null $newScope = "static" public function call(object $newThis, mixed ...$args): mixed {} public static function fromCallable(callable $callback): Closure {} + + public static function getCurrent(): Closure {} } diff --git a/Zend/zend_closures_arginfo.h b/Zend/zend_closures_arginfo.h index 57066078a882..5bc983a97c2c 100644 --- a/Zend/zend_closures_arginfo.h +++ b/Zend/zend_closures_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: e3b480674671a698814db282c5ea34d438fe519d */ +/* This is a generated file, edit zend_closures.stub.php instead. + * Stub hash: e0626e52adb2d38dad1140c1a28cc7774cc84500 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Closure___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -24,11 +24,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_fromCallable, 0, 1, ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Closure_getCurrent, 0, 0, Closure, 0) +ZEND_END_ARG_INFO() + ZEND_METHOD(Closure, __construct); ZEND_METHOD(Closure, bind); ZEND_METHOD(Closure, bindTo); ZEND_METHOD(Closure, call); ZEND_METHOD(Closure, fromCallable); +ZEND_METHOD(Closure, getCurrent); static const zend_function_entry class_Closure_methods[] = { ZEND_ME(Closure, __construct, arginfo_class_Closure___construct, ZEND_ACC_PRIVATE) @@ -36,6 +40,7 @@ static const zend_function_entry class_Closure_methods[] = { ZEND_ME(Closure, bindTo, arginfo_class_Closure_bindTo, ZEND_ACC_PUBLIC) ZEND_ME(Closure, call, arginfo_class_Closure_call, ZEND_ACC_PUBLIC) ZEND_ME(Closure, fromCallable, arginfo_class_Closure_fromCallable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(Closure, getCurrent, arginfo_class_Closure_getCurrent, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_FE_END }; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 28bea1a21d75..602a63627d6d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -23,11 +22,13 @@ #include "zend_ast.h" #include "zend_attributes.h" #include "zend_compile.h" +#include "zend_smart_str.h" #include "zend_constants.h" #include "zend_llist.h" #include "zend_API.h" #include "zend_exceptions.h" #include "zend_interfaces.h" +#include "zend_types.h" #include "zend_virtual_cwd.h" #include "zend_multibyte.h" #include "zend_language_scanner.h" @@ -100,7 +101,8 @@ static zend_op *zend_compile_var(znode *result, zend_ast *ast, uint32_t type, bo static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type, bool by_ref); static void zend_compile_expr(znode *result, zend_ast *ast); static void zend_compile_stmt(zend_ast *ast); -static void zend_compile_assign(znode *result, zend_ast *ast); +static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt, uint32_t type); +static zend_type zend_compile_typename(zend_ast *ast); #ifdef ZEND_CHECK_STACK_LIMIT zend_never_inline static void zend_stack_limit_error(void) @@ -187,10 +189,10 @@ static bool zend_get_unqualified_name(const zend_string *name, const char **resu if (ns_separator != NULL) { *result = ns_separator + 1; *result_len = ZSTR_VAL(name) + ZSTR_LEN(name) - *result; - return 1; + return true; } - return 0; + return false; } /* }}} */ @@ -233,11 +235,11 @@ static bool zend_is_reserved_class_name(const zend_string *name) /* {{{ */ if (uqname_len == reserved->len && zend_binary_strcasecmp(uqname, uqname_len, reserved->name, reserved->len) == 0 ) { - return 1; + return true; } } - return 0; + return false; } /* }}} */ @@ -339,6 +341,7 @@ void zend_oparray_context_begin(zend_oparray_context *prev_context, zend_op_arra CG(context).try_catch_offset = -1; CG(context).current_brk_cont = -1; CG(context).last_brk_cont = 0; + CG(context).has_assigned_to_http_response_header = false; CG(context).brk_cont_array = NULL; CG(context).labels = NULL; CG(context).in_jmp_frameless_branch = false; @@ -347,7 +350,7 @@ void zend_oparray_context_begin(zend_oparray_context *prev_context, zend_op_arra } /* }}} */ -void zend_oparray_context_end(zend_oparray_context *prev_context) /* {{{ */ +void zend_oparray_context_end(const zend_oparray_context *prev_context) /* {{{ */ { if (CG(context).brk_cont_array) { efree(CG(context).brk_cont_array); @@ -408,28 +411,1762 @@ void zend_file_context_begin(zend_file_context *prev_context) /* {{{ */ FC(declarables).ticks = 0; zend_hash_init(&FC(seen_symbols), 8, NULL, NULL, 0); } -/* }}} */ +/* }}} */ + +void zend_file_context_end(const zend_file_context *prev_context) /* {{{ */ +{ + zend_end_namespace(); + zend_hash_destroy(&FC(seen_symbols)); + CG(file_context) = *prev_context; +} +/* }}} */ + +void zend_init_compiler_data_structures(void) /* {{{ */ +{ + zend_stack_init(&CG(loop_var_stack), sizeof(zend_loop_var)); + zend_stack_init(&CG(delayed_oplines_stack), sizeof(zend_op)); + zend_stack_init(&CG(short_circuiting_opnums), sizeof(uint32_t)); + CG(active_class_entry) = NULL; + CG(in_compilation) = 0; + CG(skip_shebang) = 0; + + CG(encoding_declared) = 0; + CG(memoized_exprs) = NULL; + CG(memoize_mode) = ZEND_MEMOIZE_NONE; + CG(type_arg_depth) = 0; + CG(type_arg_residual_token) = 0; + CG(generic_scope) = NULL; + CG(in_static_member_type) = false; + CG(inheritance_binding_cache) = NULL; +} +/* }}} */ + +static void zend_generic_scope_push(zend_generic_parameter_list *params, zend_generic_origin origin) /* {{{ */ +{ + zend_generic_scope_entry *entry = emalloc(sizeof(zend_generic_scope_entry)); + entry->params = params; + entry->visible_count = params ? params->count : 0; + entry->self_compiling = NULL; + entry->shadowing_classes = NULL; + entry->origin = origin; + entry->outer = CG(generic_scope); + CG(generic_scope) = entry; +} +/* }}} */ + +static void zend_generic_scope_pop(void) /* {{{ */ +{ + zend_generic_scope_entry *top = CG(generic_scope); + ZEND_ASSERT(top != NULL); + if (top->shadowing_classes) { + zend_hash_destroy(top->shadowing_classes); + FREE_HASHTABLE(top->shadowing_classes); + } + + CG(generic_scope) = top->outer; + efree(top); +} +/* }}} */ + +static zend_generic_parameter *zend_generic_lookup_full( + zend_string *name, zend_generic_origin *origin_out, uint32_t *index_out) /* {{{ */ +{ + zend_string *lc_name = NULL; + zend_generic_parameter *result = NULL; + for (zend_generic_scope_entry *e = CG(generic_scope); e; e = e->outer) { + if (e->shadowing_classes) { + if (!lc_name) { + lc_name = zend_string_tolower(name); + } + + if (zend_hash_exists(e->shadowing_classes, lc_name)) { + goto done; + } + } + + zend_generic_parameter_list *params = e->params; + for (uint32_t i = 0; i < e->visible_count; i++) { + if (zend_string_equals(params->parameters[i].name, name)) { + if (origin_out) *origin_out = e->origin; + if (index_out) *index_out = i; + result = ¶ms->parameters[i]; + goto done; + } + } + } + + done: + if (lc_name) { + zend_string_release(lc_name); + } + + return result; +} +/* }}} */ + +static void zend_check_class_origin_in_static_context(const zend_string *param_name) /* {{{ */ +{ + if (CG(in_static_member_type) && CG(active_class_entry)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Type parameter %s is bound to %s and cannot be used in static context", + ZSTR_VAL(param_name), ZSTR_VAL(CG(active_class_entry)->name)); + } +} +/* }}} */ + +/* Detects forward reference: a name that matches a parameter declared later in + * the innermost scope's parameter list. Returns the index of the not-yet-visible + * parameter, or -1 if no match. */ +static int zend_generic_lookup_forward(const zend_string *name) /* {{{ */ +{ + zend_generic_scope_entry *e = CG(generic_scope); + if (!e) { + return -1; + } + zend_generic_parameter_list *params = e->params; + for (uint32_t i = e->visible_count; i < params->count; i++) { + if (zend_string_equals(params->parameters[i].name, name)) { + return (int) i; + } + } + return -1; +} +/* }}} */ + +static bool zend_type_ast_has_generic_content(zend_ast *ast); +static zend_type zend_compile_pre_erasure_typename(zend_ast *ast); +static zend_string *zend_resolve_class_name(zend_string *name, uint32_t type); + +static zend_generic_parameter *zend_generic_lookup(zend_string *name) /* {{{ */ +{ + return zend_generic_lookup_full(name, NULL, NULL); +} +/* }}} */ + +ZEND_API void zend_check_generic_param_list_size(zend_ast *list_ast) /* {{{ */ +{ + if (list_ast == NULL) { + return; + } + + uint32_t children = zend_ast_get_list(list_ast)->children; + if (children > ZEND_GENERIC_MAX_PARAMS) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot declare more than %u generic type parameters (got %u)", + ZEND_GENERIC_MAX_PARAMS, children); + } +} +/* }}} */ + +ZEND_API void zend_check_generic_arg_list_size(zend_ast *list_ast) /* {{{ */ +{ + if (list_ast == NULL) { + return; + } + + uint32_t children = zend_ast_get_list(list_ast)->children; + if (children > ZEND_GENERIC_MAX_PARAMS) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot specify more than %u generic type arguments (got %u)", + ZEND_GENERIC_MAX_PARAMS, children); + } +} +/* }}} */ + +static zend_always_inline void zend_compute_generic_required_total( + const zend_generic_parameter_list *params, uint32_t *required, uint32_t *total) +{ + uint32_t t = params ? params->count : 0; + uint32_t r = 0; + if (params) { + while (r < t && !ZEND_TYPE_IS_SET(params->parameters[r].default_type)) { + r++; + } + } + + *required = r; + *total = t; +} + +static zend_generic_type_table *zend_generic_get_or_create_op_array_table(zend_op_array *op_array); + +ZEND_API const zend_type *zend_generic_get_turbofish_args(const zend_op_array *caller_op_array, uint32_t args_id) +{ + zend_turbofish_args_entry *entry = zend_generic_get_turbofish_call_entry(caller_op_array, args_id); + return entry ? &entry->args_box : NULL; +} + +ZEND_API zend_turbofish_args_entry *zend_generic_get_turbofish_call_entry(const zend_op_array *caller_op_array, uint32_t args_id) +{ + if (!caller_op_array || !caller_op_array->generic_types || !caller_op_array->generic_types->turbofish_args || args_id == 0) { + return NULL; + } + + return zend_hash_index_find_ptr(caller_op_array->generic_types->turbofish_args, args_id); +} + +static void zend_check_generic_argument_bounds( + const zend_generic_parameter_list *params, + const zend_type *args_box, + uint32_t arity, + const char *callee_kind, + const zend_function *callee_fbc, + const zend_class_entry *callee_ce) +{ + if (!params || !args_box || !ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + return; + } + + const zend_type_named_with_args *args = ZEND_TYPE_NAMED_WITH_ARGS(*args_box); + uint32_t check_count = arity < args->count ? arity : args->count; + if (check_count > params->count) check_count = params->count; + for (uint32_t i = 0; i < check_count; i++) { + zend_type bound = params->parameters[i].bound; + if (!ZEND_TYPE_IS_SET(bound)) { + continue; + } + if (zend_check_generic_arg_satisfies_bound(NULL, args->args[i], NULL, bound) != INHERITANCE_SUCCESS) { + zend_string *arg_str = zend_type_to_string(args->args[i]); + zend_type display = ZEND_TYPE_IS_SET(params->parameters[i].bound_pre_erasure) + ? params->parameters[i].bound_pre_erasure + : bound; + zend_string *bound_str = zend_type_to_string(display); + /* Build the callee's qualified display name only on the error + * path — the success path runs on every generic call. */ + zend_string *qname; + if (callee_fbc) { + qname = zend_strpprintf(0, "%s%s%s()", + callee_fbc->common.scope ? ZSTR_VAL(callee_fbc->common.scope->name) : "", + callee_fbc->common.scope ? "::" : "", + callee_fbc->common.function_name ? ZSTR_VAL(callee_fbc->common.function_name) : "{closure}"); + } else { + qname = zend_string_copy(callee_ce->name); + } + zend_throw_error(zend_ce_type_error, + "Type argument %u to %s %s does not satisfy the bound %s on parameter %s, %s given", + i + 1, callee_kind, ZSTR_VAL(qname), + ZSTR_VAL(bound_str), + params->parameters[i].name ? ZSTR_VAL(params->parameters[i].name) : "?", + ZSTR_VAL(arg_str)); + zend_string_release(qname); + zend_string_release(arg_str); + zend_string_release(bound_str); + return; + } + } +} + +/* Fingerprint the caller bindings that this args_box's T-refs resolve + * against, mixing in the interned-name pointers of each referenced caller + * entry. Used as the cache key on zend_turbofish_args_entry. Returns 0 when + * caching is unsafe (caller binding has only an owned_type — i.e., the + * type_ref would point into a frame-local zend_type that dies when the + * caller unwinds) or when there's no caller frame to read from. Concrete + * args_boxes (no T-refs) return the constant sentinel CONCRETE — the + * resulting table is invariant across calls and the cache slot acts as a + * once-built memo. */ +static uintptr_t zend_compute_call_cache_key( + const zend_type *args_box, const zend_execute_data *caller) +{ + if (!args_box || !ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + return ZEND_TURBOFISH_CACHE_KEY_CONCRETE; + } + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*args_box); + uintptr_t fp = 0; + bool has_tref = false; + for (uint32_t i = 0; i < nwa->count; i++) { + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(nwa->args[i])) continue; + has_tref = true; + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(nwa->args[i]); + if (ref->origin != ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) return 0; + if (!caller || !caller->type_args) return 0; + if (ref->index >= caller->type_args->count) return 0; + const zend_type_arg_entry *caller_entry = &caller->type_args->entries[ref->index]; + if (!caller_entry->name || !caller_entry->type_ref) return 0; + fp = fp * 0x9E3779B97F4A7C15ULL + (uintptr_t) caller_entry->name + i + 1; + } + if (!has_tref) { + return ZEND_TURBOFISH_CACHE_KEY_CONCRETE; + } + /* Steer clear of the sentinel values used to mean "empty" / "concrete". */ + if (fp == 0 || fp == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) { + fp = (uintptr_t) -1; + } + return fp; +} + +/* Returns true when the cache key fully determines the call's type_arg_table, + * i.e. no inference will fire that could plug an unset slot from a runtime + * value. Inference depends on argument classes — not part of the key — so a + * call that triggers it must be excluded from caching even if the + * caller-binding fingerprint matches. */ +static bool zend_call_is_cacheable_against_args( + const zend_function *fbc, const zend_type *args_box) +{ + if (!fbc || !ZEND_USER_CODE(fbc->common.type)) return false; + const zend_generic_parameter_list *params = fbc->op_array.generic_parameters; + if (!params) return false; + uint64_t inferable = params->inferable_mask; + if (!inferable) return true; + uint32_t passed = 0; + if (args_box && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + passed = ZEND_TYPE_NAMED_WITH_ARGS(*args_box)->count; + } + for (uint32_t i = 0; i < params->count && i < 64; i++) { + if (!(inferable & ((uint64_t) 1 << i))) continue; + if (i < passed) continue; + if (ZEND_TYPE_IS_SET(params->parameters[i].default_type)) continue; + return false; + } + return true; +} + +/* Cache-aware wrapper: VERIFY/INSTALL handlers route through this instead of + * zend_build_generic_call_type_args directly. On hit, returns the cached + * shared table (already marked persisted, so frame teardown leaves it + * alone). On miss, builds normally; if the call site is single-binding + * stable, the freshly built table is also stashed in the cache for future + * iterations. The "store on first miss, never replace" policy avoids + * dangling: a replaced cached_table could still be referenced by a live + * frame's call->type_args. + * + * `cache_slot` points to a 2-pointer runtime cache slot owned by the + * executing op_array — slot[0] = cached zend_type_arg_table*, slot[1] = + * cache key. Runtime cache memory is allocated per-process and writable + * even when the op_array's persistent metadata lives in opcache SHM. */ +/* Cache key for a generic call made WITHOUT turbofish (args_box == NULL). The + * resolved type-arg table is then a function only of the callee's declared + * defaults (plus bound fall-backs for unset slots) — provided no slot is + * filled by value-directed inference and no default itself references an outer + * type parameter (whose binding would make the table caller-dependent and, via + * the borrowed caller-frame type_ref, unsafe to persist). When both hold the + * table is invariant across every call at this site, so a constant key turns + * the per-call-site cache slot into a build-once memo. Returns 0 ("uncacheable") + * otherwise, falling back to the original rebuild-every-call behaviour. */ +static uintptr_t zend_compute_call_default_cache_key(const zend_function *fbc) +{ + if (!ZEND_USER_CODE(fbc->common.type)) { + return 0; + } + const zend_generic_parameter_list *params = fbc->op_array.generic_parameters; + if (!params) { + return 0; + } + for (uint32_t i = 0; i < params->count; i++) { + const zend_type *def = ¶ms->parameters[i].default_type; + if (ZEND_TYPE_IS_SET(*def) && ZEND_TYPE_HAS_TYPE_PARAMETER(*def)) { + /* default is `= T` of an outer param -> caller-dependent. */ + return 0; + } + } + return ZEND_TURBOFISH_CACHE_KEY_CONCRETE; +} + +ZEND_API zend_type_arg_table *zend_build_or_get_cached_type_args( + zend_execute_data *call, const zend_type *args_box, void **cache_slot) +{ + /* Concrete call site (no type-parameter refs in the turbofish, or an + * all-default non-turbofish call): the resolved table is invariant across + * every call here, recorded by the CONCRETE sentinel in slot[1]. Once it is + * cached, return it directly — skip recomputing the binding fingerprint key + * (which would only re-derive the same CONCRETE sentinel). */ + if (cache_slot && cache_slot[0] + && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) { + return (zend_type_arg_table *) cache_slot[0]; + } + if (!args_box) { + /* Non-turbofish generic call. The table is built from the callee's + * defaults (and any value inference). When inference won't fire and no + * default is caller-dependent, the result is invariant at this site — + * cache it the same way the turbofish path does so repeated calls (e.g. + * an internal `add_node($g, $x)`) stop rebuilding+freeing a table whose + * contents never change. */ + uintptr_t nkey = (cache_slot && zend_call_is_cacheable_against_args(call->func, NULL)) + ? zend_compute_call_default_cache_key(call->func) : 0; + if (nkey && cache_slot[0] && (uintptr_t)cache_slot[1] == nkey) { + return (zend_type_arg_table *)cache_slot[0]; + } + zend_type_arg_table *nt = zend_build_generic_call_type_args(call, NULL); + if (nt && nkey && !cache_slot[0]) { + cache_slot[0] = nt; + cache_slot[1] = (void *)nkey; + nt->persisted = true; + } + return nt; + } + zend_execute_data *caller = EG(current_execute_data); + uintptr_t key = zend_compute_call_cache_key(args_box, caller); + if (cache_slot && key && cache_slot[0] && (uintptr_t)cache_slot[1] == key) { + return (zend_type_arg_table *)cache_slot[0]; + } + zend_type_arg_table *t = zend_build_generic_call_type_args(call, args_box); + if (t && key && cache_slot && !cache_slot[0] + && zend_call_is_cacheable_against_args(call->func, args_box)) { + cache_slot[0] = t; + cache_slot[1] = (void *)key; + t->persisted = true; + } + return t; +} + +/* Resolve (and cache per call site) the concrete monomorph for a turbofish CALL + * with concrete args in `args_box`; *out_type_args gets the invariant type-arg + * table for body T-ref resolution. NULL when the site can't be monomorphized. */ +static zend_type_arg_table *zend_build_concrete_call_type_args( + const zend_function *fbc, const zend_type *args_box); + +ZEND_API zend_function *zend_get_or_synthesize_call_monomorph( + zend_execute_data *call, const zend_type *args_box, uint32_t arity, void **cache_slot, + zend_type_arg_table **out_type_args) +{ + zend_function *base = call->func; + + if (cache_slot + && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH + && cache_slot[3] == (void *) base) { + *out_type_args = (zend_type_arg_table *) cache_slot[4]; + return (zend_function *) cache_slot[0]; + } + + if (!args_box || !ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + return NULL; + } + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*args_box); + + /* Enforce arity + bounds as the erased VERIFY path does (first call only). */ + zend_check_generic_call_arguments(base, arity, args_box); + if (UNEXPECTED(EG(exception))) { + return NULL; + } + + zend_function *mono = zend_synthesize_function_monomorph(base, nwa->args, nwa->count); + if (!mono) { + return NULL; + } + + zend_type_arg_table *table = zend_build_concrete_call_type_args(base, args_box); + if (table) { + table->persisted = true; + } + + if (cache_slot) { + cache_slot[0] = mono; + cache_slot[1] = (void *) ZEND_TURBOFISH_CACHE_KEY_MONOMORPH; + cache_slot[3] = (void *) base; + cache_slot[4] = table; + } + *out_type_args = table; + return mono; +} + +/* Monomorphize a non-turbofish generic call once its per-frame type-arg table + * `resolved` is known concrete and invariant, swapping call->func to a plain + * monomorph to skip the per-call value check. NULL keeps the erased path. */ +ZEND_API zend_function *zend_try_monomorph_resolved_call( + zend_execute_data *call, zend_type_arg_table *resolved, void **cache_slot, + zend_type_arg_table **out_type_args) +{ + zend_function *base = call->func; + + if (cache_slot + && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH + && cache_slot[3] == (void *) base) { + *out_type_args = (zend_type_arg_table *) cache_slot[4]; + return (zend_function *) cache_slot[0]; + } + + if (!resolved || resolved->count == 0 + || !ZEND_USER_CODE(base->type) + || !base->op_array.generic_parameters) { + return NULL; + } + + /* All bindings must be concrete (free of T-refs). */ + ALLOCA_FLAG(use_heap) + zend_type *args = do_alloca(sizeof(zend_type) * resolved->count, use_heap); + bool ok = true; + for (uint32_t i = 0; i < resolved->count; i++) { + const zend_type *bt = zend_type_arg_entry_type(&resolved->entries[i]); + if (!bt || !ZEND_TYPE_IS_SET(*bt) || zend_type_contains_type_parameter(*bt)) { + ok = false; + break; + } + args[i] = *bt; + } + + zend_function *mono = ok + ? zend_synthesize_function_monomorph(base, args, resolved->count) + : NULL; + free_alloca(args, use_heap); + if (!mono) { + return NULL; + } + + if (cache_slot) { + cache_slot[0] = mono; + cache_slot[1] = (void *) ZEND_TURBOFISH_CACHE_KEY_MONOMORPH; + cache_slot[3] = (void *) base; + cache_slot[4] = resolved; + } + *out_type_args = resolved; + return mono; +} + +ZEND_API zend_class_entry *zend_get_called_scope(const zend_execute_data *ex); + +/* Cache key for a `new C::<...>` site's resolved monomorph. The monomorph is a + * pure function of (base ce, resolved type args). The args are a + * compile-time-constant side table for the opline; only TYPE_PARAMETER refs add + * runtime variability, resolved against the executing frame: + * - FUNCTION_LIKE ref -> the frame's type_args entry, keyed by its interned + * canonical-name pointer (stable per binding); + * - CLASS_LIKE ref -> the called scope's generic_type_args, fully + * determined by the called_scope ce pointer. + * The key is seeded with the base ce pointer so a cached monomorph for one base + * can never satisfy a different base (e.g. `new $dynamic::`). Returns 0 + * ("uncacheable") only when a needed binding is unavailable (error paths). */ +static uintptr_t zend_compute_new_mono_cache_key( + const zend_class_entry *base, const zend_type_named_with_args *nwa, + const zend_execute_data *ex) +{ + uintptr_t key = (uintptr_t) base * 0x9E3779B97F4A7C15ULL; + bool has_tref = false; + for (uint32_t i = 0; i < nwa->count; i++) { + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(nwa->args[i])) { + continue; + } + has_tref = true; + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(nwa->args[i]); + if (ref->origin == ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) { + if (!ex || !ex->type_args || ref->index >= ex->type_args->count) { + return 0; + } + zend_string *bound_name = ex->type_args->entries[ref->index].name; + if (!bound_name) { + return 0; + } + key = key * 0x100000001B3ULL + (uintptr_t) bound_name + i + 1; + } else { + zend_class_entry *cs = ex ? zend_get_called_scope(ex) : NULL; + if (!cs) { + return 0; + } + key = key * 0x100000001B3ULL + (uintptr_t) cs + i + 1; + } + } + /* No type-parameter refs: the monomorph is frame-independent. Return the + * CONCRETE sentinel so the caller can take a key-free fast path (validating + * only that the cached monomorph's base matches, which guards a dynamic + * `new $cls::<...>` whose resolved base varies between calls). */ + if (!has_tref) { + return ZEND_TURBOFISH_CACHE_KEY_CONCRETE; + } + if (key == 0) { + key = (uintptr_t) -1; + } + return key; +} + +static zend_always_inline void zend_generic_new_swap_ce( + zval *new_obj, zend_execute_data *call, zend_class_entry *ce, zend_class_entry *mono) +{ + if (mono && mono != ce) { + Z_OBJ_P(new_obj)->ce = mono; + if (mono->constructor && call->func == ce->constructor) { + call->func = mono->constructor; + } + } +} + +/* `new C::<...>` resolution with a call-site monomorph cache. Without the cache + * every instantiation rebuilds the canonical class name (smart_str + interning), + * lowercases it, and hashes EG(class_table) — all to rediscover the same + * monomorph. On a cache hit we skip the arity/bound check and the synthesis + * lookup entirely: the cached ce is swapped into the new object (and the pending + * constructor call) directly. On a miss we run the full path and, when the site + * is cacheable, stash the resolved monomorph keyed by the binding fingerprint. + * + * `do_checks` mirrors the VERIFY vs INSTALL split: VERIFY runs the runtime + * arity+bound check on a miss; INSTALL (statically pre-validated) does not. The + * cached `mono` lives in EG(class_table) for the whole request and the cache + * slot is request-local runtime-cache memory, so the two share a lifetime. */ +ZEND_API void zend_apply_generic_new( + zval *new_obj, zend_execute_data *call, const zend_type *args_box, + uint32_t arity, void **cache_slot, bool do_checks) +{ + zend_class_entry *ce = Z_OBJCE_P(new_obj); + const zend_type_named_with_args *nwa = + (args_box && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) + ? ZEND_TYPE_NAMED_WITH_ARGS(*args_box) : NULL; + + if (nwa && ce->generic_parameters && cache_slot) { + /* Concrete-args fast path: the monomorph is frame-independent, so a + * cached one whose base matches reuses directly — no key recomputation. + * The base check (`->parent == ce`: a monomorph's parent is its base) + * keeps a dynamic `new $cls::<...>` correct when $cls varies. */ + if (cache_slot[0] + && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE + && ((zend_class_entry *) cache_slot[0])->parent == ce) { + zend_generic_new_swap_ce(new_obj, call, ce, (zend_class_entry *) cache_slot[0]); + return; + } + uintptr_t key = zend_compute_new_mono_cache_key(ce, nwa, EG(current_execute_data)); + /* CONCRETE keys are handled by the fast path above; reusing here without + * the base check would mis-serve a dynamic base, so require a real + * (binding-fingerprint) key for the generic hit. */ + if (key && key != ZEND_TURBOFISH_CACHE_KEY_CONCRETE + && cache_slot[0] && (uintptr_t) cache_slot[1] == key) { + zend_generic_new_swap_ce(new_obj, call, ce, (zend_class_entry *) cache_slot[0]); + return; + } + if (do_checks) { + zend_check_generic_new_arguments(ce, arity, args_box); + if (EG(exception)) { + return; + } + } + zend_class_entry *mono = zend_synthesize_monomorph_resolved(ce, nwa->args, nwa->count); + if (!mono || EG(exception)) { + return; + } + if (key) { + cache_slot[0] = mono; + cache_slot[1] = (void *) key; + } + zend_generic_new_swap_ce(new_obj, call, ce, mono); + return; + } + + /* No turbofish args, or ce isn't generic, or no cache slot: preserve the + * original semantics (the arity check still fires to reject turbofish args + * passed to a non-generic class). */ + if (do_checks) { + zend_check_generic_new_arguments(ce, arity, args_box); + if (EG(exception)) { + return; + } + } + if (nwa && ce->generic_parameters) { + zend_class_entry *mono = zend_synthesize_monomorph_resolved(ce, nwa->args, nwa->count); + if (!EG(exception)) { + zend_generic_new_swap_ce(new_obj, call, ce, mono); + } + } +} + +/* Slots left NULL mean "fall back to the parameter's bound". Order of resolution + * for each slot: explicit turbofish arg → parameter's declared default → + * value-directed inference from any argument whose pre-erasure type is a + * direct TYPE_PARAMETER reference to this slot. */ +ZEND_API zend_type_arg_table *zend_build_generic_call_type_args( + zend_execute_data *call, const zend_type *args_box) +{ + const zend_function *fbc = call->func; + const zend_generic_parameter_list *params = NULL; + const zend_op_array *op_array = NULL; + if (ZEND_USER_CODE(fbc->common.type)) { + params = fbc->op_array.generic_parameters; + op_array = &fbc->op_array; + } + if (!params || params->count == 0) { + return NULL; + } + + zend_type_arg_table *table = zend_type_arg_table_alloc(params->count); + uint32_t passed = 0; + const zend_type *passed_args = NULL; + if (args_box && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*args_box); + passed = nwa->count; + passed_args = nwa->args; + } + + zend_execute_data *caller = EG(current_execute_data); + for (uint32_t i = 0; i < params->count; i++) { + const zend_type *src = NULL; + if (i < passed) { + src = &passed_args[i]; + } else if (ZEND_TYPE_IS_SET(params->parameters[i].default_type)) { + src = ¶ms->parameters[i].default_type; + } + if (!src || !ZEND_TYPE_IS_SET(*src)) { + continue; + } + /* A turbofish arg can itself name an outer generic parameter (e.g. + * `inner::(...)` inside `function outer`). Resolve those + * against the caller frame's T-table so the binding chains — + * borrow whatever the caller's entry resolved to (which is itself + * either another borrowed ref or an owned synthesised type), and + * copy the canonical name. Both source lifetimes outlive this + * frame because frames nest. */ + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*src)) { + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*src); + if (ref->origin == ZEND_GENERIC_ORIGIN_FUNCTION_LIKE + && caller && caller->type_args + && ref->index < caller->type_args->count + && caller->type_args->entries[ref->index].name) { + table->entries[i].name = zend_string_copy(caller->type_args->entries[ref->index].name); + table->entries[i].type_ref = zend_type_arg_entry_type(&caller->type_args->entries[ref->index]); + } + continue; + } + table->entries[i].name = zend_type_arg_canonical_name(*src); + /* Borrow the args_box's slot — args_box lives on a caller-chain + * op_array and outlives this frame's type_args. */ + table->entries[i].type_ref = src; + } + + /* Inference for unset slots. Composite shapes (array, Box, ?T) are + * skipped — only bare top-level T at a value-parameter position. The + * inferable_mask short-circuits when no inferable slot remains unset. */ + uint64_t unbound_inferable = params->inferable_mask; + for (uint32_t i = 0; i < params->count && i < 64; i++) { + if (table->entries[i].name) { + unbound_inferable &= ~((uint64_t) 1 << i); + } + } + if (unbound_inferable + && op_array + && op_array->generic_types + && op_array->generic_types->parameters) { + HashTable *pre = op_array->generic_types->parameters; + uint32_t num_args = ZEND_CALL_NUM_ARGS(call); + zend_ulong arg_idx; + zend_type *pe_type_ptr; + ZEND_HASH_FOREACH_NUM_KEY_PTR(pre, arg_idx, pe_type_ptr) { + if (arg_idx >= num_args) continue; + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(*pe_type_ptr)) continue; + if (ZEND_TYPE_FULL_MASK(*pe_type_ptr) & MAY_BE_NULL) continue; + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*pe_type_ptr); + if (ref->origin != ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) continue; + if (ref->index >= table->count) continue; + if (table->entries[ref->index].name) continue; + zval *arg = ZEND_CALL_ARG(call, (uint32_t) arg_idx + 1); + if (Z_TYPE_P(arg) == IS_OBJECT) { + zend_class_entry *arg_ce = Z_OBJCE_P(arg); + table->entries[ref->index].name = zend_string_copy(arg_ce->name); + /* No pre-existing zend_type to borrow — synthesise a + * class-name owned_type from the value's class so value-arg + * checks on forwarded T-refs compare instanceof correctly. */ + zend_string *inferred_name = zend_string_copy(arg_ce->name); + table->entries[ref->index].owned_type = + (zend_type) ZEND_TYPE_INIT_CLASS(inferred_name, 0, 0); + } + } ZEND_HASH_FOREACH_END(); + } + + return table; +} + +/* Recursive value check for a pre-erasure zend_type. Pre-erasure stores + * unions / intersections as a LIST with CODE-only / NAME / NAMED_WITH_ARGS + * members (one per branch), which is not the canonical shape that + * zend_check_type_slow understands — it expects scalar bits on the outer + * mask. Walk the shape directly here: + * + * - LIST with INTERSECTION_BIT: all members must match (object only). + * - LIST (union): any member matches. + * - NAMED_WITH_ARGS: instanceof against the canonical monomorph class; + * null also accepted if MAY_BE_NULL is set on the type's mask. + * - NAME: instanceof against the class; same null short-circuit. + * - Otherwise (CODE-only mask): scalar-hint check + null short-circuit. + * + * Returns true if the value satisfies the type. The `strict` argument + * controls scalar coercion at the leaf. */ +static bool zend_check_pre_erasure_type_value( + const zend_type *type, zval *arg, const zend_reference *ref, bool strict) +{ + uint32_t mask = ZEND_TYPE_FULL_MASK(*type); + + if (ZEND_TYPE_IS_INTERSECTION(*type)) { + if (Z_TYPE_P(arg) != IS_OBJECT) { + return (mask & MAY_BE_NULL) && Z_TYPE_P(arg) == IS_NULL; + } + const zend_type *member; + ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*type), member) { + if (!zend_check_pre_erasure_type_value(member, arg, NULL, strict)) { + return false; + } + } ZEND_TYPE_LIST_FOREACH_END(); + return true; + } + + if (ZEND_TYPE_HAS_LIST(*type)) { + if ((mask & MAY_BE_NULL) && Z_TYPE_P(arg) == IS_NULL) { + return true; + } + const zend_type *member; + ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(*type), member) { + if (zend_check_pre_erasure_type_value(member, arg, ref, strict)) { + return true; + } + } ZEND_TYPE_LIST_FOREACH_END(); + return false; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*type)) { + if ((mask & MAY_BE_NULL) && Z_TYPE_P(arg) == IS_NULL) return true; + if (Z_TYPE_P(arg) != IS_OBJECT) return false; + zend_string *canonical = zend_type_to_canonical_string(*type); + zend_class_entry *ce = zend_lookup_class_ex(canonical, NULL, + ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT); + zend_string_release(canonical); + return ce && instanceof_function(Z_OBJCE_P(arg), ce); + } + + if (ZEND_TYPE_HAS_NAME(*type)) { + if ((mask & MAY_BE_NULL) && Z_TYPE_P(arg) == IS_NULL) return true; + if (Z_TYPE_P(arg) != IS_OBJECT) return false; + zend_class_entry *ce = zend_lookup_class_ex(ZEND_TYPE_NAME(*type), NULL, + ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT); + return ce && instanceof_function(Z_OBJCE_P(arg), ce); + } + + /* Mask-only — single scalar (e.g. INT) or a combined scalar mask. */ + if (ZEND_TYPE_CONTAINS_CODE(*type, Z_TYPE_P(arg))) return true; + if (ref && ZEND_REF_HAS_TYPE_SOURCES(ref)) return false; + return zend_verify_scalar_type_hint(mask, arg, strict, /* is_internal */ false); +} + +/* Run PHP's normal arg-type machinery (coerce in weak mode, throw TypeError + * in strict mode) against the per-call substituted type for any value-parameter + * whose pre-erasure type is a direct TYPE_PARAMETER reference. Returns false + * and sets EG(exception) on the first failure. Only bare T at the top level is + * substituted in this pass — composite shapes (array, Box, ?T) fall back + * to the erased bound check at RECV. */ +/* Verify one value parameter whose pre-erasure type is a direct FUNCTION_LIKE + * T-ref (parameter position `arg_idx`, type-parameter index `tp_index`) against + * the per-call binding. Shared by both the plan-driven fast path and the hash + * fallback so the substitution / variadic-sweep / error semantics stay + * identical. Returns false (with EG(exception) set) on the first violation. */ +static zend_always_inline bool zend_verify_one_generic_param( + zend_execute_data *call, const zend_function *fbc, + const zend_type_named_with_args *nwa, + uint32_t arg_idx, uint32_t tp_index, uint32_t num_args, bool strict) +{ + zend_type substituted; + if (nwa) { + if (tp_index >= nwa->count) return true; + substituted = nwa->args[tp_index]; + } else { + /* No turbofish args_box for this call — resolve directly from the + * captured T-table (e.g., a closure with no turbofish at its own + * call site, whose body references the outer frame's T). */ + if (tp_index >= call->type_args->count) return true; + const zend_type *resolved = zend_type_arg_entry_type( + &call->type_args->entries[tp_index]); + if (!resolved) return true; + substituted = *resolved; + } + if (!ZEND_TYPE_IS_SET(substituted)) return true; + + /* If the turbofish arg is itself a forwarded TYPE_PARAMETER (e.g. + * `id::($x)` inside `nested`), the caller's binding has already been + * resolved into call->type_args by zend_build_generic_call_type_args. */ + if (ZEND_TYPE_HAS_TYPE_PARAMETER(substituted)) { + if (!call->type_args || tp_index >= call->type_args->count) { + return true; + } + const zend_type *resolved = zend_type_arg_entry_type( + &call->type_args->entries[tp_index]); + if (!resolved) { + return true; + } + substituted = *resolved; + } + + /* When the pre-erasure parameter slot is variadic (T ...$xs), the single + * key covers every value supplied at runtime. Sweep from arg_idx through + * num_args-1 so each variadic element gets the same reified T-check. */ + bool is_variadic_slot = (fbc->common.fn_flags & ZEND_ACC_VARIADIC) + && arg_idx == fbc->common.num_args; + uint32_t sweep_end = is_variadic_slot ? num_args : arg_idx + 1; + + for (uint32_t aidx = arg_idx; aidx < sweep_end; aidx++) { + zval *arg = ZEND_CALL_ARG(call, aidx + 1); + zval *target = arg; + const zend_reference *zref = NULL; + if (Z_ISREF_P(target)) { + zref = Z_REF_P(target); + target = Z_REFVAL_P(target); + } + + /* Pre-erasure shapes don't match the canonical PHP type layout + * (scalars sit as CODE-only list members instead of bits on the + * outer mask), so walk them directly. */ + bool ok = zend_check_pre_erasure_type_value(&substituted, target, zref, strict); + if (!ok) { + zend_string *expected = zend_type_to_string(substituted); + const zend_arg_info *ai; + if (is_variadic_slot) { + ai = &fbc->common.arg_info[fbc->common.num_args]; + } else { + ai = (aidx < fbc->common.num_args) + ? &fbc->common.arg_info[aidx] : NULL; + } + zend_throw_error(zend_ce_type_error, + "%s%s%s(): Argument #%u%s%s%s must be of type %s, %s given", + fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", + fbc->common.scope ? "::" : "", + fbc->common.function_name ? ZSTR_VAL(fbc->common.function_name) : "{closure}", + aidx + 1, + (ai && ai->name) ? " ($" : "", + (ai && ai->name) ? ZSTR_VAL(ai->name) : "", + (ai && ai->name) ? ")" : "", + ZSTR_VAL(expected), zend_zval_value_name(target)); + zend_string_release(expected); + return false; + } + } + return true; +} + +/* Count the direct FUNCTION_LIKE T-ref value parameters; the persister and the + * runtime builder share it so both size the plan identically. */ +ZEND_API uint32_t zend_count_generic_value_checks(const HashTable *parameters) +{ + uint32_t cnt = 0; + zend_ulong arg_idx; + zend_type *pe_type_ptr; + ZEND_HASH_FOREACH_NUM_KEY_PTR(parameters, arg_idx, pe_type_ptr) { + (void) arg_idx; + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(*pe_type_ptr)) continue; + if (ZEND_TYPE_TYPE_PARAMETER(*pe_type_ptr)->origin != ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) continue; + cnt++; + } ZEND_HASH_FOREACH_END(); + return cnt; +} + +/* Fill a plan buffer (sized for zend_count_generic_value_checks() entries): one + * entry per direct FUNCTION_LIKE T-ref value parameter, in hash order so the + * "first failing argument" diagnostic matches the legacy iteration. */ +ZEND_API void zend_fill_generic_value_check_plan( + zend_generic_value_check_plan *plan, const HashTable *parameters) +{ + zend_ulong arg_idx; + zend_type *pe_type_ptr; + uint32_t w = 0; + ZEND_HASH_FOREACH_NUM_KEY_PTR(parameters, arg_idx, pe_type_ptr) { + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(*pe_type_ptr)) continue; + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*pe_type_ptr); + if (ref->origin != ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) continue; + plan->checks[w].arg_idx = (uint32_t) arg_idx; + plan->checks[w].tp_index = ref->index; + w++; + } ZEND_HASH_FOREACH_END(); + plan->count = w; +} + +/* Build the packed value-check plan from a callee's `parameters` table into + * request-local memory. */ +static zend_generic_value_check_plan *zend_build_generic_value_check_plan( + const HashTable *parameters) +{ + uint32_t cnt = zend_count_generic_value_checks(parameters); + zend_generic_value_check_plan *plan = emalloc( + offsetof(zend_generic_value_check_plan, checks) + cnt * sizeof(zend_generic_value_check)); + zend_fill_generic_value_check_plan(plan, parameters); + return plan; +} + +ZEND_API bool zend_verify_generic_arg_types(zend_execute_data *call, const zend_type *args_box) +{ + const zend_type_named_with_args *nwa = NULL; + if (args_box && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + nwa = ZEND_TYPE_NAMED_WITH_ARGS(*args_box); + } + /* When neither args_box nor a captured frame T-table is available there + * is nothing to verify against. */ + if (!nwa && !call->type_args) { + return true; + } + const zend_function *fbc = call->func; + if (!ZEND_USER_CODE(fbc->common.type) + || !fbc->op_array.generic_types + || !fbc->op_array.generic_types->parameters) { + return true; + } + + uint32_t num_args = ZEND_CALL_NUM_ARGS(call); + /* Loop-invariant: strictness is a property of the calling frame. */ + bool strict = EG(current_execute_data) + && EG(current_execute_data)->func + && (EG(current_execute_data)->func->common.fn_flags & ZEND_ACC_STRICT_TYPES); + + zend_generic_type_table *gt = fbc->op_array.generic_types; + zend_generic_value_check_plan *plan = gt->value_check_plan; + if (!plan && !gt->persisted) { + plan = zend_build_generic_value_check_plan(fbc->op_array.generic_types->parameters); + gt->value_check_plan = plan; + } + + if (plan) { + for (uint32_t p = 0; p < plan->count; p++) { + uint32_t arg_idx = plan->checks[p].arg_idx; + if (arg_idx >= num_args) continue; + if (!zend_verify_one_generic_param(call, fbc, nwa, + arg_idx, plan->checks[p].tp_index, num_args, strict)) { + return false; + } + } + return true; + } + + /* Fallback for opcache-persisted tables (read-only SHM, no plan cached): + * iterate the parameters hash directly. */ + const HashTable *pre = gt->parameters; + zend_ulong arg_idx; + zend_type *pe_type_ptr; + ZEND_HASH_FOREACH_NUM_KEY_PTR(pre, arg_idx, pe_type_ptr) { + if (arg_idx >= num_args) continue; + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(*pe_type_ptr)) continue; + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*pe_type_ptr); + if (ref->origin != ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) continue; + if (!zend_verify_one_generic_param(call, fbc, nwa, + (uint32_t) arg_idx, ref->index, num_args, strict)) { + return false; + } + } ZEND_HASH_FOREACH_END(); + return true; +} + +/* Reified counterpart to zend_verify_return_error's erased check. Consults + * op_array->generic_types->return_type (pre-erasure) and, if it's a direct + * T-ref, substitutes via call->type_args and verifies the value. Only bare + * T at the top level is handled; composite shapes (array, Box) still + * fall through to the existing erased-bound check. Returns true when no + * reified check applies *or* the check passes; false (with EG(exception) + * set) when the value violates the reified type. */ +ZEND_API bool zend_verify_generic_return_type(zend_execute_data *call, zval *retval_ptr) +{ + if (!call->type_args) { + return true; + } + const zend_function *fbc = call->func; + if (!ZEND_USER_CODE(fbc->common.type) + || !fbc->op_array.generic_types + || !fbc->op_array.generic_types->return_type) { + return true; + } + const zend_type *pe_type = fbc->op_array.generic_types->return_type; + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(*pe_type)) { + return true; + } + const zend_type_parameter_ref *param_ref = ZEND_TYPE_TYPE_PARAMETER(*pe_type); + if (param_ref->origin != ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) { + return true; + } + if (param_ref->index >= call->type_args->count) { + return true; + } + const zend_type *resolved = zend_type_arg_entry_type( + &call->type_args->entries[param_ref->index]); + if (!resolved || !ZEND_TYPE_IS_SET(*resolved)) { + return true; + } + zend_type substituted = *resolved; + + zval *target = retval_ptr; + const zend_reference *zref = NULL; + if (Z_ISREF_P(target)) { + zref = Z_REF_P(target); + target = Z_REFVAL_P(target); + } + + /* `?T` carries the nullable bit on the outer T-ref; preserve it on the + * substituted type so a returned NULL still passes when declared `?T`. */ + if (ZEND_TYPE_FULL_MASK(*pe_type) & _ZEND_TYPE_NULLABLE_BIT) { + ZEND_TYPE_FULL_MASK(substituted) |= _ZEND_TYPE_NULLABLE_BIT; + } + + bool strict = EG(current_execute_data) + && EG(current_execute_data)->func + && (EG(current_execute_data)->func->common.fn_flags & ZEND_ACC_STRICT_TYPES); + bool ok = zend_check_pre_erasure_type_value(&substituted, target, zref, strict); + if (!ok) { + zend_string *expected = zend_type_to_string(substituted); + zend_throw_error(zend_ce_type_error, + "%s%s%s(): Return value must be of type %s, %s returned", + fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", + fbc->common.scope ? "::" : "", + fbc->common.function_name ? ZSTR_VAL(fbc->common.function_name) : "{closure}", + ZSTR_VAL(expected), zend_zval_value_name(target)); + zend_string_release(expected); + return false; + } + return true; +} + +ZEND_API void zend_check_generic_call_arguments(const zend_function *fbc, uint32_t arity, const zend_type *args_box) +{ + const zend_generic_parameter_list *params = NULL; + if (ZEND_USER_CODE(fbc->common.type)) { + params = fbc->op_array.generic_parameters; + } + + uint32_t required, total; + zend_compute_generic_required_total(params, &required, &total); + + if (arity > total) { + zend_throw_error(zend_ce_argument_count_error, + "Too many generic type arguments to %s%s%s(), %u passed and %s %u expected", + fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", + fbc->common.scope ? "::" : "", + fbc->common.function_name ? ZSTR_VAL(fbc->common.function_name) : "{closure}", + arity, + required == total ? "exactly" : "at most", + total); + return; + } + if (arity > 0 && arity < required) { + /* A missing slot is treated as supplied for arity purposes if a + * value-parameter can pin it via inference. The compile-time + * inferable_mask precomputes that set. */ + uint64_t inferable = params ? params->inferable_mask : 0; + uint32_t still_required = required; + for (uint32_t i = arity; i < required; i++) { + if (inferable & ((uint64_t) 1 << i)) { + still_required--; + } + } + if (arity < still_required) { + zend_throw_error(zend_ce_argument_count_error, + "Too few generic type arguments to %s%s%s(), %u passed and %s %u expected", + fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", + fbc->common.scope ? "::" : "", + fbc->common.function_name ? ZSTR_VAL(fbc->common.function_name) : "{closure}", + arity, + required == total ? "exactly" : "at least", + required); + return; + } + } + + if (args_box) { + zend_check_generic_argument_bounds(params, args_box, arity, "call", fbc, NULL); + } +} + +ZEND_API void zend_check_generic_new_arguments(const zend_class_entry *ce, uint32_t arity, const zend_type *args_box) +{ + uint32_t required, total; + zend_compute_generic_required_total(ce->generic_parameters, &required, &total); + + if (arity > total) { + zend_throw_error(zend_ce_argument_count_error, + "Too many generic type arguments to new %s, %u passed and %s %u expected", + ZSTR_VAL(ce->name), arity, + required == total ? "exactly" : "at most", total); + return; + } + if (arity < required) { + zend_throw_error(zend_ce_argument_count_error, + "Too few generic type arguments to new %s, %u passed and %s %u expected", + ZSTR_VAL(ce->name), arity, + required == total ? "exactly" : "at least", required); + return; + } + + if (args_box) { + zend_check_generic_argument_bounds(ce->generic_parameters, args_box, arity, "new", NULL, ce); + } +} + +#define ZEND_VERIFY_ARITY_KIND_CALL 0 +#define ZEND_VERIFY_ARITY_KIND_NEW 1 +/* Site dispatches directly to a monomorph by name; emit no VERIFY/INSTALL. */ +#define ZEND_VERIFY_ARITY_KIND_NONE 2 + +static zend_type zend_compile_turbofish_args_type(zend_ast *turbofish_ast) +{ + zend_ast_list *list = zend_ast_get_list(turbofish_ast); + zend_type_named_with_args *payload = emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(list->children)); + payload->name = NULL; + payload->name_attr = 0; + payload->count = list->children; + for (uint32_t i = 0; i < list->children; i++) { + payload->args[i] = zend_compile_pre_erasure_typename(list->child[i]); + } + zend_type result = ZEND_TYPE_INIT_NONE(0); + ZEND_TYPE_SET_PTR(result, payload); + ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NAMED_WITH_ARGS_BIT; + return result; +} + +/* Returns true when every supplied turbofish arg is concrete (no T-refs) + * and `zend_check_generic_arg_satisfies_bound` resolves to + * INHERITANCE_SUCCESS — i.e. the runtime arity+bound check is redundant + * and we can emit ZEND_INSTALL_GENERIC_ARGS in place of + * ZEND_VERIFY_GENERIC_ARGUMENTS. Returns false on T-refs, on a definite + * INHERITANCE_ERROR (so the runtime VERIFY can throw the catchable + * TypeError as before), or on INHERITANCE_UNRESOLVED (a class isn't + * loaded yet — the runtime retry may succeed). */ +static bool zend_static_check_generic_call_bounds( + const zend_generic_parameter_list *params, + const zend_type_named_with_args *args, uint32_t arity) +{ + uint32_t check_count = arity < args->count ? arity : args->count; + if (check_count > params->count) check_count = params->count; + for (uint32_t i = 0; i < check_count; i++) { + zend_type bound = params->parameters[i].bound; + bool has_bound = ZEND_TYPE_IS_SET(bound); + if (zend_type_contains_type_parameter(args->args[i])) { + /* Unbounded parameter accepts any T-ref trivially; we can elide + * the runtime arity+bound check (INSTALL instead of VERIFY). + * A T-ref against a bounded parameter still needs runtime + * resolution to compare against the bound. */ + if (!has_bound) continue; + return false; + } + if (!has_bound) continue; + zend_inheritance_status status = + zend_check_generic_arg_satisfies_bound(NULL, args->args[i], NULL, bound); + if (status != INHERITANCE_SUCCESS) { + return false; + } + } + return true; +} + +/* Can the runtime VERIFY be replaced with the cheaper INSTALL at this CALL + * site? Requires the callee to be statically known and generic, the arity + * to be within [required, total], and the turbofish args to be concrete + * and bound-satisfying. */ +static bool zend_can_install_call_args_statically( + const zend_function *fbc, const zend_type *args_box, uint32_t arity) +{ + if (!fbc || !ZEND_USER_CODE(fbc->common.type)) return false; + const zend_generic_parameter_list *params = fbc->op_array.generic_parameters; + if (!params) return false; + uint32_t required, total; + zend_compute_generic_required_total(params, &required, &total); + if (arity < required || arity > total) return false; + if (!args_box || !ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) return false; + return zend_static_check_generic_call_bounds( + params, ZEND_TYPE_NAMED_WITH_ARGS(*args_box), arity); +} + +/* Compile-time equivalent of zend_build_generic_call_type_args for a concrete + * call site: each entry borrows its type_ref into the args_box NWA (i=passed). NULL when any arg still contains a T-ref. */ +static zend_type_arg_table *zend_build_concrete_call_type_args( + const zend_function *fbc, const zend_type *args_box) +{ + if (!fbc || !ZEND_USER_CODE(fbc->common.type)) { + return NULL; + } + const zend_generic_parameter_list *params = fbc->op_array.generic_parameters; + if (!params || params->count == 0) { + return NULL; + } + + uint32_t passed = 0; + const zend_type *passed_args = NULL; + if (args_box && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*args_box); + passed = nwa->count; + passed_args = nwa->args; + } + + zend_type_arg_table *table = zend_type_arg_table_alloc(params->count); + for (uint32_t i = 0; i < params->count; i++) { + const zend_type *src = NULL; + if (i < passed) { + src = &passed_args[i]; + } else if (ZEND_TYPE_IS_SET(params->parameters[i].default_type)) { + src = ¶ms->parameters[i].default_type; + } + if (!src || !ZEND_TYPE_IS_SET(*src)) { + continue; + } + if (zend_type_contains_type_parameter(*src)) { + zend_type_arg_table_destroy(table); + return NULL; + } + table->entries[i].name = zend_type_arg_canonical_name(*src); + table->entries[i].type_ref = src; + } + + return table; +} + +/* If this turbofish CALL site is concrete, build the resolved type-arg table now + * and stash it on the turbofish entry so persist can relocate it into SHM. */ +static bool zend_try_attach_concrete_call_table( + const zend_function *fbc, const zend_type *args_box, uint32_t args_id) +{ + if (!fbc || !args_box || !ZEND_TYPE_HAS_NAMED_WITH_ARGS(*args_box)) { + return false; + } + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*args_box); + for (uint32_t i = 0; i < nwa->count; i++) { + if (zend_type_contains_type_parameter(nwa->args[i])) { + return false; + } + } + if (!zend_call_is_cacheable_against_args(fbc, args_box)) { + return false; + } + zend_type_arg_table *ct = zend_build_concrete_call_type_args(fbc, args_box); + if (!ct) { + return false; + } + zend_generic_type_table *gtt = CG(active_op_array)->generic_types; + zend_turbofish_args_entry *entry = + zend_hash_index_find_ptr(gtt->turbofish_args, args_id); + ZEND_ASSERT(entry != NULL); + entry->concrete_table = ct; + entry->concrete_skip_value_check = + fbc->op_array.generic_types + && fbc->op_array.generic_types->parameters + && zend_count_generic_value_checks( + fbc->op_array.generic_types->parameters) == 0; + return true; +} + +static void zend_emit_verify_generic_arguments(zend_ast *turbofish_ast, uint8_t kind, const znode *new_result, const zend_function *fbc) +{ + uint32_t arity = 0; + uint32_t args_id = 0; + const zend_type *args_box = NULL; + + if (turbofish_ast) { + arity = zend_ast_get_list(turbofish_ast)->children; + ZEND_ASSERT(arity > 0 && arity <= ZEND_GENERIC_MAX_PARAMS); + + zend_type args_type = zend_compile_turbofish_args_type(turbofish_ast); + zend_generic_type_table *table = + zend_generic_get_or_create_op_array_table(CG(active_op_array)); + args_id = (table->turbofish_args ? zend_hash_num_elements(table->turbofish_args) : 0) + 1; + zend_generic_type_table_set_turbofish_args(table, args_id, args_type); + args_box = zend_hash_index_find_ptr(table->turbofish_args, args_id); + } else { + /* No turbofish: only call sites get a defaults/inference-driven VERIFY + * (NEW already emitted it above the args). Skip when fbc is known and + * statically non-generic; emit speculatively otherwise — the runtime + * handler short-circuits when the resolved callee is non-generic. */ + if (kind != ZEND_VERIFY_ARITY_KIND_CALL) { + return; + } + if (fbc && (!ZEND_USER_CODE(fbc->common.type) + || !fbc->op_array.generic_parameters)) { + return; + } + } + + /* Replace the runtime VERIFY with INSTALL when arity+bound check is + * decidable (and passes) at compile time. Only CALL is handled for + * now — NEW's compile-time ce resolution path is more constrained. */ + uint8_t opcode = ZEND_VERIFY_GENERIC_ARGUMENTS; + if (kind == ZEND_VERIFY_ARITY_KIND_CALL + && zend_can_install_call_args_statically(fbc, args_box, arity)) { + opcode = ZEND_INSTALL_GENERIC_ARGS; + zend_try_attach_concrete_call_table(fbc, args_box, args_id); + } else if (kind == ZEND_VERIFY_ARITY_KIND_CALL && turbofish_ast && args_id) { + /* Concrete args but VERIFY stays (bounds not statically decidable); + * still attach the invariant table for the handler to install. */ + zend_try_attach_concrete_call_table(fbc, args_box, args_id); + } + + zend_op *opline = get_next_op(); + opline->opcode = opcode; + opline->op2_type = IS_UNUSED; + opline->op2.num = arity; + opline->extended_value = args_id; + if (kind == ZEND_VERIFY_ARITY_KIND_NEW) { + ZEND_ASSERT(new_result != NULL && new_result->op_type == IS_TMP_VAR); + opline->op1_type = new_result->op_type; + opline->op1.var = new_result->u.op.var; + } else { + opline->op1_type = IS_UNUSED; + opline->op1.num = 0; + } + opline->result_type = IS_UNUSED; + /* Reserve a 5-slot inline cache in the caller op_array's runtime cache: + * slot[0] = cached zend_type_arg_table* (CALL) / monomorph ce* (NEW), + * slot[1] = cache key (caller-binding fingerprint) / state sentinel, + * slot[2] = cached zend_turbofish_args_entry* (skips the per-call lookup), + * slot[3] = promotion/monomorph memo (resolved callee guard), + * slot[4] = monomorph type-arg table. + * The runtime cache is per-process and writable even when the op_array's + * side tables are persisted to opcache SHM. */ + opline->result.num = (args_id || kind == ZEND_VERIFY_ARITY_KIND_CALL) + ? zend_alloc_cache_slots(5) : 0; + + /* Mark so destroy_op_array scans opcodes for a CALL-form generic-args slot + * that may own a zend_type_arg_table; non-generic op_arrays skip the scan. */ + if (opline->op1_type == IS_UNUSED && opline->result.num) { + CG(active_op_array)->fn_flags2 |= ZEND_ACC2_HAS_GENERIC_CALL_OPS; + } +} + +static zend_generic_parameter_list *zend_compile_generic_type_parameter_list( + zend_ast *list_ast, zend_generic_origin origin) /* {{{ */ +{ + if (!list_ast) { + return NULL; + } + zend_ast_list *list = zend_ast_get_list(list_ast); + ZEND_ASSERT(list->children > 0); + + zend_generic_parameter_list *params = + zend_generic_parameter_list_alloc(list->children, /* persistent */ false); + + zend_string *prev_optional_name = NULL; + + for (uint32_t i = 0; i < list->children; i++) { + zend_ast *param_ast = list->child[i]; + ZEND_ASSERT(param_ast->kind == ZEND_AST_GENERIC_TYPE_PARAMETER); + zend_string *name = zval_make_interned_string(zend_ast_get_zval(param_ast->child[0])); + bool has_default = param_ast->child[2] != NULL; + + for (uint32_t j = 0; j < i; j++) { + if (zend_string_equals(params->parameters[j].name, name)) { + zend_string *dup = zend_string_copy(name); + zend_generic_parameter_list_destroy(params); + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot redeclare type parameter %s", ZSTR_VAL(dup)); + } + } + + if (zend_generic_lookup(name)) { + zend_string *dup = zend_string_copy(name); + zend_generic_parameter_list_destroy(params); + zend_error_noreturn(E_COMPILE_ERROR, + "Type parameter %s shadows enclosing type parameter", ZSTR_VAL(dup)); + } + + if (!has_default && prev_optional_name != NULL) { + zend_string *cur = zend_string_copy(name); + zend_string *prev = zend_string_copy(prev_optional_name); + zend_generic_parameter_list_destroy(params); + zend_error_noreturn(E_COMPILE_ERROR, + "Optional type parameter %s cannot be declared before required type parameter %s", + ZSTR_VAL(prev), ZSTR_VAL(cur)); + } + + if (has_default && prev_optional_name == NULL) { + prev_optional_name = name; + } + + params->parameters[i].name = zend_string_copy(name); + params->parameters[i].variance = (zend_generic_variance) param_ast->attr; + } + + params->count = list->children; + + zend_generic_scope_push(params, origin); + + CG(generic_scope)->visible_count = list->children; + for (uint32_t i = 0; i < list->children; i++) { + zend_ast *param_ast = list->child[i]; + if (!param_ast->child[1]) { + continue; + } + + CG(generic_scope)->self_compiling = ¶ms->parameters[i]; + params->parameters[i].bound = zend_compile_typename(param_ast->child[1]); + if (zend_type_ast_has_generic_content(param_ast->child[1])) { + params->parameters[i].bound_pre_erasure = zend_compile_pre_erasure_typename(param_ast->child[1]); + } + + CG(generic_scope)->self_compiling = NULL; + } + + CG(generic_scope)->visible_count = 0; + for (uint32_t i = 0; i < list->children; i++) { + zend_ast *param_ast = list->child[i]; + CG(generic_scope)->visible_count = i + 1; + if (!param_ast->child[2]) { + continue; + } + + CG(generic_scope)->self_compiling = ¶ms->parameters[i]; + params->parameters[i].default_type = zend_compile_typename(param_ast->child[2]); + if (zend_type_ast_has_generic_content(param_ast->child[2])) { + params->parameters[i].default_pre_erasure = zend_compile_pre_erasure_typename(param_ast->child[2]); + } + + if (ZEND_TYPE_IS_SET(params->parameters[i].bound) + && zend_check_generic_arg_satisfies_bound( + NULL, params->parameters[i].default_type, + NULL, params->parameters[i].bound) + == INHERITANCE_ERROR) { + zend_type bound_display = ZEND_TYPE_IS_SET(params->parameters[i].bound_pre_erasure) + ? params->parameters[i].bound_pre_erasure + : params->parameters[i].bound; + zend_type default_display = ZEND_TYPE_IS_SET(params->parameters[i].default_pre_erasure) + ? params->parameters[i].default_pre_erasure + : params->parameters[i].default_type; + zend_string *bound_str = zend_type_to_string(bound_display); + zend_string *default_str = zend_type_to_string(default_display); + zend_error_noreturn(E_COMPILE_ERROR, + "Default %s for type parameter %s does not satisfy its bound %s", + ZSTR_VAL(default_str), ZSTR_VAL(params->parameters[i].name), ZSTR_VAL(bound_str)); + } + + CG(generic_scope)->self_compiling = NULL; + } + + zend_generic_scope_pop(); + + return params; +} +/* }}} */ + +/* Returns true if the AST contains any generic-aware constructs (a type-parameter + * reference or a named type with type arguments) that need pre-erasure capture. */ +static bool zend_type_ast_has_generic_content(zend_ast *ast) +{ + if (!ast) { + return false; + } + zend_ast_attr orig = ast->attr; + ast->attr &= ~ZEND_TYPE_NULLABLE; + bool result = false; + + if (ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + result = true; + } else if (ast->kind == ZEND_AST_TYPE_UNION || ast->kind == ZEND_AST_TYPE_INTERSECTION) { + zend_ast_list *list = zend_ast_get_list(ast); + for (uint32_t i = 0; i < list->children; i++) { + if (zend_type_ast_has_generic_content(list->child[i])) { + result = true; + break; + } + } + } else if (ast->kind == ZEND_AST_ZVAL) { + if ((ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + const zval *zv = zend_ast_get_zval(ast); + if (Z_TYPE_P(zv) == IS_STRING && zend_generic_lookup(Z_STR_P(zv))) { + result = true; + } + } + } + + ast->attr = orig; + return result; +} + +static void zend_reject_typearg_on_iterable(zend_ast *ast) +{ + if (ast->kind != ZEND_AST_GENERIC_NAMED_TYPE) { + return; + } + + zend_ast *name_ast = ast->child[0]; + if (name_ast->kind != ZEND_AST_ZVAL) { + return; + } + + zval *zv = zend_ast_get_zval(name_ast); + if (Z_TYPE_P(zv) != IS_STRING) { + return; + } + + if ((name_ast->attr & ZEND_NAME_NOT_FQ) != ZEND_NAME_NOT_FQ) { + return; + } + + if (zend_string_equals_literal_ci(Z_STR_P(zv), "iterable")) { + zend_error_noreturn(E_COMPILE_ERROR, "Type arguments are not allowed on iterable"); + } +} + +/* When a named class type carries type arguments (Foo), the named class + * must actually be generic. If the class is already in CG(class_table) and + * has no generic_parameters, raise a hard compile-time error. Classes not yet + * seen by the compiler fall through; the runtime monomorph lookup raises the + * same error in that case. */ +static void zend_validate_class_accepts_type_args(zend_string *resolved_name) +{ + zend_string *lc = zend_string_tolower(resolved_name); + zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lc); + zend_string_release(lc); + if (ce && !ce->generic_parameters) { + zend_error_noreturn(E_COMPILE_ERROR, + "Type arguments are not allowed on non-generic class %s", + ZSTR_VAL(ce->name)); + } +} + +/* Build a pre-erasure zend_type from a type-expression AST. The returned type + * may carry type-parameter references (TYPE_PARAMETER bit) or named-with-args + * payloads (NAMED_WITH_ARGS bit). Used only for the side table; the runtime + * never sees this form. */ +static zend_type zend_compile_pre_erasure_typename(zend_ast *ast) +{ + zend_reject_typearg_on_iterable(ast); + bool is_marked_nullable = ast->attr & ZEND_TYPE_NULLABLE; + zend_ast_attr orig_attr = ast->attr; + if (is_marked_nullable) { + ast->attr &= ~ZEND_TYPE_NULLABLE; + } + + zend_type result = ZEND_TYPE_INIT_NONE(0); + + if (ast->kind == ZEND_AST_TYPE_UNION || ast->kind == ZEND_AST_TYPE_INTERSECTION) { + zend_ast_list *list = zend_ast_get_list(ast); + bool is_union = ast->kind == ZEND_AST_TYPE_UNION; + zend_type_list *type_list = emalloc(ZEND_TYPE_LIST_SIZE(list->children)); + uint32_t out_count = 0; + uint32_t merged_scalar_mask = 0; + for (uint32_t i = 0; i < list->children; i++) { + zend_type member = zend_compile_pre_erasure_typename(list->child[i]); + if (is_union) { + /* Mirror the erased form's normalization: aggregate scalar bits + * to the outer mask so covariance checks see them, and drop + * scalar-only members from the list. Complex members (T-refs, + * named-with-args, nested lists, plain class names) stay in + * the list with their scalar bits cleared. */ + bool is_complex = ZEND_TYPE_HAS_LIST(member) + || ZEND_TYPE_HAS_NAME(member) + || ZEND_TYPE_HAS_LITERAL_NAME(member) + || ZEND_TYPE_HAS_TYPE_PARAMETER(member) + || ZEND_TYPE_HAS_NAMED_WITH_ARGS(member); + merged_scalar_mask |= ZEND_TYPE_PURE_MASK(member); + if (is_complex) { + ZEND_TYPE_FULL_MASK(member) &= ~_ZEND_TYPE_MAY_BE_MASK; + type_list->types[out_count++] = member; + } + } else { + type_list->types[out_count++] = member; + } + } + if (out_count == 0) { + /* All members folded into the scalar mask. */ + efree(type_list); + ZEND_TYPE_FULL_MASK(result) |= merged_scalar_mask; + } else { + type_list->num_types = out_count; + ZEND_TYPE_SET_PTR(result, type_list); + ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_LIST_BIT | + (is_union ? _ZEND_TYPE_UNION_BIT : _ZEND_TYPE_INTERSECTION_BIT) | + merged_scalar_mask; + } + } else if (ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + zend_ast *name_ast = ast->child[0]; + zend_ast_list *args_list = zend_ast_get_list(ast->child[1]); + zend_type_named_with_args *payload = emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(args_list->children)); + if (name_ast->kind == ZEND_AST_TYPE) { + ZEND_ASSERT(name_ast->attr == IS_STATIC); + payload->name = zend_string_init_interned(ZEND_STRL("static"), 0); + payload->name_attr = 0; + } else { + zend_string *raw = zval_make_interned_string(zend_ast_get_zval(name_ast)); + if (zend_get_class_fetch_type(raw) != ZEND_FETCH_CLASS_DEFAULT) { + payload->name = zend_string_copy(raw); + } else { + bool is_type_param = ((name_ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) + && zend_generic_lookup(raw) != NULL; + payload->name = zend_resolve_class_name(raw, name_ast->attr); + if (!is_type_param) { + zend_validate_class_accepts_type_args(payload->name); + } + } + + payload->name_attr = name_ast->attr; + } + + payload->count = args_list->children; + for (uint32_t i = 0; i < args_list->children; i++) { + payload->args[i] = zend_compile_pre_erasure_typename(args_list->child[i]); + } + + ZEND_TYPE_SET_PTR(result, payload); + ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NAMED_WITH_ARGS_BIT; + } else if (ast->kind == ZEND_AST_TYPE) { + /* Builtin pseudo-type: same as erased. */ + result = (zend_type) ZEND_TYPE_INIT_CODE(ast->attr, 0, 0); + } else if (ast->kind == ZEND_AST_ZVAL) { + zend_generic_origin origin; + uint32_t index; + zend_generic_parameter *param = NULL; + if ((ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + const zval *zv = zend_ast_get_zval(ast); + if (Z_TYPE_P(zv) == IS_STRING) { + param = zend_generic_lookup_full(Z_STR_P(zv), &origin, &index); + } + } + if (param) { + if (origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE) { + zend_check_class_origin_in_static_context(param->name); + } + + zend_type_parameter_ref *ref = emalloc(sizeof(*ref)); + ref->name = zend_string_copy(param->name); + ref->index = index; + ref->origin = origin; + ZEND_TYPE_SET_PTR(result, ref); + ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_TYPE_PARAMETER_BIT; + } else { + if ((ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + const zval *zv = zend_ast_get_zval(ast); + if (Z_TYPE_P(zv) == IS_STRING + && zend_generic_lookup_forward(Z_STR_P(zv)) >= 0) { + zend_error_noreturn(E_COMPILE_ERROR, + "Type parameter %s referenced before declaration", + Z_STRVAL_P(zv)); + } + } + zend_string *name = zval_make_interned_string(zend_ast_get_zval(ast)); + uint8_t code = zend_lookup_builtin_type_by_name(name); + if (code != 0) { + if (code == IS_ITERABLE) { + zend_type iterable = (zend_type) ZEND_TYPE_INIT_CLASS_MASK( + ZSTR_KNOWN(ZEND_STR_TRAVERSABLE), + (MAY_BE_ARRAY|_ZEND_TYPE_ITERABLE_BIT)); + result = iterable; + } else { + result = (zend_type) ZEND_TYPE_INIT_CODE(code, 0, 0); + } + } else { + zend_string_addref(name); + result = (zend_type) ZEND_TYPE_INIT_CLASS(name, 0, 0); + } + } + } else { + ZEND_UNREACHABLE(); + } + + if (is_marked_nullable) { + ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NULLABLE_BIT; + } + ast->attr = orig_attr; + return result; +} -void zend_file_context_end(zend_file_context *prev_context) /* {{{ */ +/* Ensure op_array->generic_types is allocated, then return it. */ +static zend_generic_type_table *zend_generic_get_or_create_op_array_table(zend_op_array *op_array) { - zend_end_namespace(); - zend_hash_destroy(&FC(seen_symbols)); - CG(file_context) = *prev_context; + if (!op_array->generic_types) { + op_array->generic_types = zend_generic_type_table_alloc(); + } + return op_array->generic_types; } -/* }}} */ -void zend_init_compiler_data_structures(void) /* {{{ */ +/* Ensure ce->generic_types is allocated, then return it. */ +ZEND_API zend_generic_type_table *zend_generic_get_or_create_class_table(zend_class_entry *ce) { - zend_stack_init(&CG(loop_var_stack), sizeof(zend_loop_var)); - zend_stack_init(&CG(delayed_oplines_stack), sizeof(zend_op)); - zend_stack_init(&CG(short_circuiting_opnums), sizeof(uint32_t)); - CG(active_class_entry) = NULL; - CG(in_compilation) = 0; - CG(skip_shebang) = 0; + if (!ce->generic_types) { + ce->generic_types = zend_generic_type_table_alloc(); + } + return ce->generic_types; +} - CG(encoding_declared) = 0; - CG(memoized_exprs) = NULL; - CG(memoize_mode) = ZEND_MEMOIZE_NONE; +static zend_generic_parameter *zend_generic_lookup_name(zend_ast *ast) /* {{{ */ +{ + if (!CG(generic_scope) || ast->kind != ZEND_AST_ZVAL) { + return NULL; + } + if ((ast->attr & ZEND_NAME_NOT_FQ) != ZEND_NAME_NOT_FQ) { + return NULL; + } + zval *zv = zend_ast_get_zval(ast); + if (Z_TYPE_P(zv) != IS_STRING) { + return NULL; + } + return zend_generic_lookup(Z_STR_P(zv)); } /* }}} */ @@ -445,7 +2182,7 @@ static void zend_register_seen_symbol(zend_string *name, uint32_t kind) { } static bool zend_have_seen_symbol(zend_string *name, uint32_t kind) { - zval *zv = zend_hash_find(&FC(seen_symbols), name); + const zval *zv = zend_hash_find(&FC(seen_symbols), name); return zv && (Z_LVAL_P(zv) & kind) != 0; } @@ -517,7 +2254,7 @@ ZEND_API zend_string *zend_get_compiled_filename(void) /* {{{ */ } /* }}} */ -ZEND_API int zend_get_compiled_lineno(void) /* {{{ */ +ZEND_API uint32_t zend_get_compiled_lineno(void) /* {{{ */ { return CG(zend_lineno); } @@ -535,7 +2272,7 @@ static zend_always_inline uint32_t get_temporary_variable(void) /* {{{ */ } /* }}} */ -static int lookup_cv(zend_string *name) /* {{{ */{ +static uint32_t lookup_cv(zend_string *name) /* {{{ */{ zend_op_array *op_array = CG(active_op_array); int i = 0; zend_ulong hash_value = zend_string_hash_val(name); @@ -570,7 +2307,7 @@ zend_string *zval_make_interned_string(zval *zv) } /* Common part of zend_add_literal and zend_append_individual_literal */ -static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */ +static inline void zend_insert_literal(const zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */ { zval *lit = CT_CONSTANT_EX(op_array, literal_position); if (Z_TYPE_P(zv) == IS_STRING) { @@ -587,7 +2324,7 @@ static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int li static int zend_add_literal(zval *zv) /* {{{ */ { zend_op_array *op_array = CG(active_op_array); - int i = op_array->last_literal; + uint32_t i = op_array->last_literal; op_array->last_literal++; if (i >= CG(context).literals_size) { while (i >= CG(context).literals_size) { @@ -751,6 +2488,36 @@ static inline void zend_end_loop(int cont_addr, const znode *var_node) /* {{{ */ } /* }}} */ +bool zend_op_may_elide_result(uint8_t opcode) +{ + switch (opcode) { + case ZEND_ASSIGN: + case ZEND_ASSIGN_DIM: + case ZEND_ASSIGN_OBJ: + case ZEND_ASSIGN_STATIC_PROP: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: + case ZEND_PRE_INC_STATIC_PROP: + case ZEND_PRE_DEC_STATIC_PROP: + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_PRE_INC: + case ZEND_PRE_DEC: + case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: + case ZEND_YIELD: + case ZEND_YIELD_FROM: + case ZEND_INCLUDE_OR_EVAL: + return true; + default: + return false; + } +} + static void zend_do_free(znode *op1) /* {{{ */ { if (op1->op_type == IS_TMP_VAR) { @@ -777,22 +2544,12 @@ static void zend_do_free(znode *op1) /* {{{ */ opline->opcode -= 2; SET_UNUSED(opline->result); return; - case ZEND_ASSIGN: - case ZEND_ASSIGN_DIM: - case ZEND_ASSIGN_OBJ: - case ZEND_ASSIGN_STATIC_PROP: - case ZEND_ASSIGN_OP: - case ZEND_ASSIGN_DIM_OP: - case ZEND_ASSIGN_OBJ_OP: - case ZEND_ASSIGN_STATIC_PROP_OP: - case ZEND_PRE_INC_STATIC_PROP: - case ZEND_PRE_DEC_STATIC_PROP: - case ZEND_PRE_INC_OBJ: - case ZEND_PRE_DEC_OBJ: - case ZEND_PRE_INC: - case ZEND_PRE_DEC: - SET_UNUSED(opline->result); - return; + default: + if (zend_op_may_elide_result(opline->opcode)) { + SET_UNUSED(opline->result); + return; + } + break; } } @@ -814,14 +2571,13 @@ static void zend_do_free(znode *op1) /* {{{ */ } else { /* Frameless calls usually use the return value, so always emit a free. This should be * faster than checking RETURN_VALUE_USED inside the handler. */ - // FIXME: We may actually look at the function signature to determine whether a free - // is necessary. zend_emit_op(NULL, ZEND_FREE, op1, NULL); } } else { while (opline >= CG(active_op_array)->opcodes) { if ((opline->opcode == ZEND_FETCH_LIST_R || - opline->opcode == ZEND_FETCH_LIST_W) && + opline->opcode == ZEND_FETCH_LIST_W || + opline->opcode == ZEND_EXT_STMT) && opline->op1_type == IS_VAR && opline->op1.var == op1->u.op.var) { zend_emit_op(NULL, ZEND_FREE, op1, NULL); @@ -870,7 +2626,7 @@ static const char *zend_modifier_token_to_string(uint32_t token) return "protected(set)"; case T_PRIVATE_SET: return "private(set)"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -949,7 +2705,7 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token uint32_t zend_modifier_list_to_flags(zend_modifier_target target, zend_ast *modifiers) { uint32_t flags = 0; - zend_ast_list *modifier_list = zend_ast_get_list(modifiers); + const zend_ast_list *modifier_list = zend_ast_get_list(modifiers); for (uint32_t i = 0; i < modifier_list->children; i++) { uint32_t token = (uint32_t) Z_LVAL_P(zend_ast_get_zval(modifier_list->child[i])); @@ -1048,20 +2804,20 @@ uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag, zend_modifi } /* }}} */ -ZEND_API zend_string *zend_create_member_string(zend_string *class_name, zend_string *member_name) { +ZEND_API zend_string *zend_create_member_string(const zend_string *class_name, const zend_string *member_name) { return zend_string_concat3( ZSTR_VAL(class_name), ZSTR_LEN(class_name), "::", sizeof("::") - 1, ZSTR_VAL(member_name), ZSTR_LEN(member_name)); } -static zend_string *zend_concat_names(char *name1, size_t name1_len, char *name2, size_t name2_len) { +static zend_string *zend_concat_names(const char *name1, size_t name1_len, const char *name2, size_t name2_len) { return zend_string_concat3(name1, name1_len, "\\", 1, name2, name2_len); } static zend_string *zend_prefix_with_ns(zend_string *name) { if (FC(current_namespace)) { - zend_string *ns = FC(current_namespace); + const zend_string *ns = FC(current_namespace); return zend_concat_names(ZSTR_VAL(ns), ZSTR_LEN(ns), ZSTR_VAL(name), ZSTR_LEN(name)); } else { return zend_string_copy(name); @@ -1070,24 +2826,24 @@ static zend_string *zend_prefix_with_ns(zend_string *name) { static zend_string *zend_resolve_non_class_name( zend_string *name, uint32_t type, bool *is_fully_qualified, - bool case_sensitive, HashTable *current_import_sub + bool case_sensitive, const HashTable *current_import_sub ) { - char *compound; - *is_fully_qualified = 0; + const char *compound; + *is_fully_qualified = false; if (ZSTR_VAL(name)[0] == '\\') { /* Remove \ prefix (only relevant if this is a string rather than a label) */ - *is_fully_qualified = 1; + *is_fully_qualified = true; return zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0); } if (type == ZEND_NAME_FQ) { - *is_fully_qualified = 1; + *is_fully_qualified = true; return zend_string_copy(name); } if (type == ZEND_NAME_RELATIVE) { - *is_fully_qualified = 1; + *is_fully_qualified = true; return zend_prefix_with_ns(name); } @@ -1101,20 +2857,20 @@ static zend_string *zend_resolve_non_class_name( } if (import_name) { - *is_fully_qualified = 1; + *is_fully_qualified = true; return zend_string_copy(import_name); } } compound = memchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name)); if (compound) { - *is_fully_qualified = 1; + *is_fully_qualified = true; } if (compound && FC(imports)) { /* If the first part of a qualified name is an alias, substitute it. */ size_t len = compound - ZSTR_VAL(name); - zend_string *import_name = zend_hash_str_find_ptr_lc(FC(imports), ZSTR_VAL(name), len); + const zend_string *import_name = zend_hash_str_find_ptr_lc(FC(imports), ZSTR_VAL(name), len); if (import_name) { return zend_concat_names( @@ -1129,18 +2885,18 @@ static zend_string *zend_resolve_non_class_name( static zend_string *zend_resolve_function_name(zend_string *name, uint32_t type, bool *is_fully_qualified) { return zend_resolve_non_class_name( - name, type, is_fully_qualified, 0, FC(imports_function)); + name, type, is_fully_qualified, false, FC(imports_function)); } static zend_string *zend_resolve_const_name(zend_string *name, uint32_t type, bool *is_fully_qualified) { return zend_resolve_non_class_name( - name, type, is_fully_qualified, 1, FC(imports_const)); + name, type, is_fully_qualified, true, FC(imports_const)); } static zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */ { - char *compound; + const char *compound; if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) { if (type == ZEND_NAME_FQ) { @@ -1178,7 +2934,7 @@ static zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* if (compound) { /* If the first part of a qualified name is an alias, substitute it. */ size_t len = compound - ZSTR_VAL(name); - zend_string *import_name = + const zend_string *import_name = zend_hash_str_find_ptr_lc(FC(imports), ZSTR_VAL(name), len); if (import_name) { @@ -1203,10 +2959,15 @@ static zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* static zend_string *zend_resolve_class_name_ast(zend_ast *ast) /* {{{ */ { - zval *class_name = zend_ast_get_zval(ast); + if (ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + ast = ast->child[0]; + } + + const zval *class_name = zend_ast_get_zval(ast); if (Z_TYPE_P(class_name) != IS_STRING) { zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name"); } + return zend_resolve_class_name(Z_STR_P(class_name), ast->attr); } /* }}} */ @@ -1222,8 +2983,6 @@ static void str_dtor(zval *zv) /* {{{ */ { } /* }}} */ -static bool zend_is_call(zend_ast *ast); - static uint32_t zend_add_try_element(uint32_t try_op) /* {{{ */ { zend_op_array *op_array = CG(active_op_array); @@ -1261,14 +3020,14 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */ } /* }}} */ -static zend_never_inline ZEND_COLD ZEND_NORETURN void do_bind_function_error(zend_string *lcname, zend_op_array *op_array, bool compile_time) /* {{{ */ +static zend_never_inline ZEND_COLD ZEND_NORETURN void do_bind_function_error(const zend_string *lcname, const zend_op_array *op_array, bool compile_time) /* {{{ */ { - zval *zv = zend_hash_find_known_hash(compile_time ? CG(function_table) : EG(function_table), lcname); + const zval *zv = zend_hash_find_known_hash(compile_time ? CG(function_table) : EG(function_table), lcname); int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR; - zend_function *old_function; + const zend_function *old_function; ZEND_ASSERT(zv != NULL); - old_function = (zend_function*)Z_PTR_P(zv); + old_function = Z_PTR_P(zv); if (old_function->type == ZEND_USER_FUNCTION && old_function->op_array.last > 0) { zend_error_noreturn(error_level, "Cannot redeclare function %s() (previously declared in %s:%d)", @@ -1281,11 +3040,11 @@ static zend_never_inline ZEND_COLD ZEND_NORETURN void do_bind_function_error(zen } } -ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname) /* {{{ */ +ZEND_API zend_result do_bind_function(zend_function *func, const zval *lcname) /* {{{ */ { zend_function *added_func = zend_hash_add_ptr(EG(function_table), Z_STR_P(lcname), func); if (UNEXPECTED(!added_func)) { - do_bind_function_error(Z_STR_P(lcname), &func->op_array, 0); + do_bind_function_error(Z_STR_P(lcname), &func->op_array, false); return FAILURE; } @@ -1301,7 +3060,7 @@ ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname) /* {{{ /* }}} */ ZEND_API zend_class_entry *zend_bind_class_in_slot( - zval *class_table_slot, zval *lcname, zend_string *lc_parent_name) + zval *class_table_slot, const zval *lcname, zend_string *lc_parent_name) { zend_class_entry *ce = Z_PTR_P(class_table_slot); bool is_preloaded = @@ -1327,7 +3086,6 @@ ZEND_API zend_class_entry *zend_bind_class_in_slot( ce = zend_do_link_class(ce, lc_parent_name, Z_STR_P(lcname)); if (ce) { - ZEND_ASSERT(!EG(exception)); zend_observer_class_linked_notify(ce, Z_STR_P(lcname)); return ce; } @@ -1344,7 +3102,6 @@ ZEND_API zend_class_entry *zend_bind_class_in_slot( ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name) /* {{{ */ { - zend_class_entry *ce; zval *rtd_key, *zv; rtd_key = lcname + 1; @@ -1352,7 +3109,7 @@ ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name) /* zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(rtd_key)); if (UNEXPECTED(!zv)) { - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(lcname)); + const zend_class_entry *ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(lcname)); ZEND_ASSERT(ce); zend_class_redeclaration_error(E_COMPILE_ERROR, ce); return FAILURE; @@ -1381,7 +3138,7 @@ static zend_string *add_type_string(zend_string *type, zend_string *new_type, bo return result; } -static zend_string *resolve_class_name(zend_string *name, zend_class_entry *scope) { +static zend_string *resolve_class_name(zend_string *name, const zend_class_entry *scope) { if (scope) { if (zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_SELF))) { name = scope->name; @@ -1394,14 +3151,26 @@ static zend_string *resolve_class_name(zend_string *name, zend_class_entry *scop * null byte here, to avoid larger parts of the type being omitted by printing code later. */ size_t len = strlen(ZSTR_VAL(name)); if (len != ZSTR_LEN(name)) { - ZEND_ASSERT(scope && "This should only happen with resolved types"); return zend_string_init(ZSTR_VAL(name), len, 0); } return zend_string_copy(name); } +/* Render a single union / intersection list member. The list iteration used + * to assert NAME on every member, but reified types put scalar codes, + * TYPE_PARAMETER refs, and NAMED_WITH_ARGS payloads in list slots too — + * defer to the main renderer which already handles each case. The outer + * union absorbs nullability with a single trailing `|null`, so strip + * MAY_BE_NULL from the member's own mask to avoid emitting `?Member`. */ +static zend_string *render_list_member(const zend_type *member, const zend_class_entry *scope) +{ + zend_type clean = *member; + ZEND_TYPE_FULL_MASK(clean) &= ~MAY_BE_NULL; + return zend_type_to_string_resolved(clean, scope); +} + static zend_string *add_intersection_type(zend_string *str, - const zend_type_list *intersection_type_list, zend_class_entry *scope, + const zend_type_list *intersection_type_list, bool is_bracketed) { const zend_type *single_type; @@ -1409,9 +3178,11 @@ static zend_string *add_intersection_type(zend_string *str, ZEND_TYPE_LIST_FOREACH(intersection_type_list, single_type) { ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*single_type)); - ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*single_type)); - - intersection_str = add_type_string(intersection_str, ZEND_TYPE_NAME(*single_type), /* is_intersection */ true); + zend_string *piece = render_list_member(single_type, NULL); + if (piece) { + intersection_str = add_type_string(intersection_str, piece, /* is_intersection */ true); + zend_string_release(piece); + } } ZEND_TYPE_LIST_FOREACH_END(); ZEND_ASSERT(intersection_str); @@ -1426,29 +3197,55 @@ static zend_string *add_intersection_type(zend_string *str, return str; } -zend_string *zend_type_to_string_resolved(const zend_type type, zend_class_entry *scope) { +zend_string *zend_type_to_string_resolved(const zend_type type, const zend_class_entry *scope) { zend_string *str = NULL; /* Pure intersection type */ if (ZEND_TYPE_IS_INTERSECTION(type)) { ZEND_ASSERT(!ZEND_TYPE_IS_UNION(type)); - str = add_intersection_type(str, ZEND_TYPE_LIST(type), scope, /* is_bracketed */ false); + str = add_intersection_type(str, ZEND_TYPE_LIST(type), /* is_bracketed */ false); } else if (ZEND_TYPE_HAS_LIST(type)) { /* A union type might not be a list */ const zend_type *list_type; ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) { if (ZEND_TYPE_IS_INTERSECTION(*list_type)) { - str = add_intersection_type(str, ZEND_TYPE_LIST(*list_type), scope, /* is_bracketed */ true); + str = add_intersection_type(str, ZEND_TYPE_LIST(*list_type), /* is_bracketed */ true); continue; } ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type)); - ZEND_ASSERT(ZEND_TYPE_HAS_NAME(*list_type)); - - zend_string *name = ZEND_TYPE_NAME(*list_type); - zend_string *resolved = resolve_class_name(name, scope); - str = add_type_string(str, resolved, /* is_intersection */ false); - zend_string_release(resolved); + zend_string *piece = render_list_member(list_type, scope); + if (piece) { + str = add_type_string(str, piece, /* is_intersection */ false); + zend_string_release(piece); + } } ZEND_TYPE_LIST_FOREACH_END(); + } else if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) { + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(type); + smart_str buf = {0}; + if (nwa->name) { + zend_string *resolved = resolve_class_name(nwa->name, scope); + smart_str_append(&buf, resolved); + zend_string_release(resolved); + } + + smart_str_appendc(&buf, '<'); + for (uint32_t i = 0; i < nwa->count; i++) { + if (i > 0) smart_str_appends(&buf, ", "); + zend_string *piece = zend_type_to_string_resolved(nwa->args[i], scope); + if (piece) { + smart_str_append(&buf, piece); + zend_string_release(piece); + } + } + + smart_str_appendc(&buf, '>'); + smart_str_0(&buf); + str = buf.s; + } else if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) { + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(type); + if (ref->name) { + str = zend_string_copy(ref->name); + } } else if (ZEND_TYPE_HAS_NAME(type)) { str = resolve_class_name(ZEND_TYPE_NAME(type), scope); } @@ -1464,7 +3261,7 @@ zend_string *zend_type_to_string_resolved(const zend_type type, zend_class_entry zend_string *name = ZSTR_KNOWN(ZEND_STR_STATIC); // During compilation of eval'd code the called scope refers to the scope calling the eval if (scope && !zend_is_compiling()) { - zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data)); + const zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data)); if (called_scope) { name = called_scope->name; } @@ -1521,6 +3318,249 @@ ZEND_API zend_string *zend_type_to_string(zend_type type) { return zend_type_to_string_resolved(type, NULL); } +/* === Monomorph canonicalization === + * + * Produces a deterministic class-name string for a generic application. + * Properties: + * - No whitespace anywhere. + * - Class names appear in fully-resolved form (the caller is expected to + * pass already-resolved zend_types; type-param refs are not allowed). + * - Members of union and intersection lists are sorted by canonical + * sub-string, so int|string and string|int collapse to "int|string". + * - `?T` is normalized to the union form `T|null`. + * - Intersection branches inside a union are wrapped in parens: "(A&B)|C". + * - Nested generic applications recurse: Box>. + * + * Two type-arg lists that PHP would treat as equivalent types must produce + * the same canonical string. */ + +static int zend_canonical_strptr_cmp(const void *a, const void *b) +{ + const zend_string *const *sa = a; + const zend_string *const *sb = b; + return zend_binary_strcmp( + ZSTR_VAL(*sa), ZSTR_LEN(*sa), + ZSTR_VAL(*sb), ZSTR_LEN(*sb)); +} + +static zend_string *zend_canonical_join_sorted( + zend_string **pieces, uint32_t count, char sep) +{ + qsort(pieces, count, sizeof(zend_string *), zend_canonical_strptr_cmp); + smart_str buf = {0}; + for (uint32_t i = 0; i < count; i++) { + if (i > 0) smart_str_appendc(&buf, sep); + smart_str_append(&buf, pieces[i]); + } + smart_str_0(&buf); + return buf.s; +} + +static void zend_canonical_append_scalar_pieces( + uint32_t type_mask, zend_string ***pieces, uint32_t *count, uint32_t *cap) +{ + /* Fixed-order scalar emission so each scalar bit yields exactly one + * piece; the outer sort then merges these with class-name pieces. */ + struct { uint32_t bit; zend_string *str; } table[] = { + { MAY_BE_CALLABLE, ZSTR_KNOWN(ZEND_STR_CALLABLE) }, + { MAY_BE_OBJECT, ZSTR_KNOWN(ZEND_STR_OBJECT) }, + { MAY_BE_ARRAY, ZSTR_KNOWN(ZEND_STR_ARRAY) }, + { MAY_BE_STRING, ZSTR_KNOWN(ZEND_STR_STRING) }, + { MAY_BE_LONG, ZSTR_KNOWN(ZEND_STR_INT) }, + { MAY_BE_DOUBLE, ZSTR_KNOWN(ZEND_STR_FLOAT) }, + { MAY_BE_VOID, ZSTR_KNOWN(ZEND_STR_VOID) }, + { MAY_BE_NEVER, ZSTR_KNOWN(ZEND_STR_NEVER) }, + }; + for (size_t i = 0; i < sizeof(table)/sizeof(table[0]); i++) { + if (type_mask & table[i].bit) { + if (*count == *cap) { + *cap = *cap ? *cap * 2 : 4; + *pieces = erealloc(*pieces, sizeof(zend_string *) * (*cap)); + } + (*pieces)[(*count)++] = zend_string_copy(table[i].str); + } + } + if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL) { + if (*count == *cap) { *cap = *cap ? *cap * 2 : 4; *pieces = erealloc(*pieces, sizeof(zend_string *) * (*cap)); } + (*pieces)[(*count)++] = zend_string_copy(ZSTR_KNOWN(ZEND_STR_BOOL)); + } else { + if (type_mask & MAY_BE_FALSE) { + if (*count == *cap) { *cap = *cap ? *cap * 2 : 4; *pieces = erealloc(*pieces, sizeof(zend_string *) * (*cap)); } + (*pieces)[(*count)++] = zend_string_copy(ZSTR_KNOWN(ZEND_STR_FALSE)); + } + if (type_mask & MAY_BE_TRUE) { + if (*count == *cap) { *cap = *cap ? *cap * 2 : 4; *pieces = erealloc(*pieces, sizeof(zend_string *) * (*cap)); } + (*pieces)[(*count)++] = zend_string_copy(ZSTR_KNOWN(ZEND_STR_TRUE)); + } + } + if (type_mask & MAY_BE_NULL) { + if (*count == *cap) { *cap = *cap ? *cap * 2 : 4; *pieces = erealloc(*pieces, sizeof(zend_string *) * (*cap)); } + (*pieces)[(*count)++] = zend_string_copy(ZSTR_KNOWN(ZEND_STR_NULL_LOWERCASE)); + } +} + +static zend_string *zend_canonical_one(zend_type type); + +static zend_string *zend_canonical_intersection(const zend_type_list *list) +{ + zend_string **pieces = safe_emalloc(list->num_types, sizeof(zend_string *), 0); + uint32_t n = 0; + const zend_type *single; + ZEND_TYPE_LIST_FOREACH(list, single) { + /* Intersection branches are class-name leaves or NAMED_WITH_ARGS. */ + pieces[n++] = zend_canonical_one(*single); + } ZEND_TYPE_LIST_FOREACH_END(); + zend_string *result = zend_canonical_join_sorted(pieces, n, '&'); + for (uint32_t i = 0; i < n; i++) zend_string_release(pieces[i]); + efree(pieces); + return result; +} + +static zend_string *zend_canonical_one(zend_type type) +{ + uint32_t scalar_mask = ZEND_TYPE_PURE_MASK(type); + /* MAY_BE_ANY appearing alone is "mixed"; otherwise it's an unbounded + * bag of scalar bits we expand individually. */ + bool is_mixed_pure = scalar_mask == MAY_BE_ANY + && !ZEND_TYPE_HAS_LIST(type) + && !ZEND_TYPE_HAS_NAME(type) + && !ZEND_TYPE_HAS_NAMED_WITH_ARGS(type); + if (is_mixed_pure) { + return zend_string_copy(ZSTR_KNOWN(ZEND_STR_MIXED)); + } + + zend_string **pieces = NULL; + uint32_t n = 0, cap = 0; + + if (ZEND_TYPE_IS_INTERSECTION(type)) { + zend_string *s = zend_canonical_intersection(ZEND_TYPE_LIST(type)); + if (n == cap) { cap = cap ? cap * 2 : 4; pieces = erealloc(pieces, sizeof(zend_string *) * cap); } + pieces[n++] = s; + } else if (ZEND_TYPE_HAS_LIST(type)) { + const zend_type *list_type; + ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), list_type) { + zend_string *s; + if (ZEND_TYPE_IS_INTERSECTION(*list_type)) { + zend_string *inner = zend_canonical_intersection(ZEND_TYPE_LIST(*list_type)); + s = zend_string_concat3("(", 1, ZSTR_VAL(inner), ZSTR_LEN(inner), ")", 1); + zend_string_release(inner); + } else { + s = zend_canonical_one(*list_type); + } + if (n == cap) { cap = cap ? cap * 2 : 4; pieces = erealloc(pieces, sizeof(zend_string *) * cap); } + pieces[n++] = s; + } ZEND_TYPE_LIST_FOREACH_END(); + } else if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) { + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(type); + smart_str buf = {0}; + if (nwa->name) smart_str_append(&buf, nwa->name); + smart_str_appendc(&buf, '<'); + for (uint32_t i = 0; i < nwa->count; i++) { + if (i > 0) smart_str_appendc(&buf, ','); + zend_string *inner = zend_canonical_one(nwa->args[i]); + smart_str_append(&buf, inner); + zend_string_release(inner); + } + smart_str_appendc(&buf, '>'); + smart_str_0(&buf); + if (n == cap) { cap = cap ? cap * 2 : 4; pieces = erealloc(pieces, sizeof(zend_string *) * cap); } + pieces[n++] = buf.s; + } else if (ZEND_TYPE_HAS_NAME(type)) { + if (n == cap) { cap = cap ? cap * 2 : 4; pieces = erealloc(pieces, sizeof(zend_string *) * cap); } + pieces[n++] = zend_string_copy(ZEND_TYPE_NAME(type)); + } else if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) { + /* Canonicalization runs against already-substituted types; a stray + * T-ref means somebody handed us pre-erasure data by mistake. */ + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(type); + if (n == cap) { cap = cap ? cap * 2 : 4; pieces = erealloc(pieces, sizeof(zend_string *) * cap); } + pieces[n++] = ref->name ? zend_string_copy(ref->name) : ZSTR_EMPTY_ALLOC(); + } + + zend_canonical_append_scalar_pieces(scalar_mask, &pieces, &n, &cap); + + zend_string *result; + if (n == 0) { + result = ZSTR_EMPTY_ALLOC(); + } else if (n == 1) { + result = zend_string_copy(pieces[0]); + } else { + result = zend_canonical_join_sorted(pieces, n, '|'); + } + for (uint32_t i = 0; i < n; i++) zend_string_release(pieces[i]); + if (pieces) efree(pieces); + return result; +} + +ZEND_API zend_string *zend_type_to_canonical_string(zend_type type) +{ + /* Intern the result so equivalent type-arg lists share storage and the + * downstream class-table lookup (zend_fetch_class_by_name) hashes the + * same pointer each time. Safe at runtime — zend_new_interned_string + * falls back to a heap string if interning isn't available. */ + return zend_new_interned_string(zend_canonical_one(type)); +} + +ZEND_API bool zend_type_contains_type_parameter(zend_type type) +{ + if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) return true; + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) { + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(type); + for (uint32_t i = 0; i < nwa->count; i++) { + if (zend_type_contains_type_parameter(nwa->args[i])) return true; + } + } + if (ZEND_TYPE_HAS_LIST(type)) { + const zend_type *member; + ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), member) { + if (zend_type_contains_type_parameter(*member)) return true; + } ZEND_TYPE_LIST_FOREACH_END(); + } + return false; +} + +/* Like zend_type_contains_type_parameter, but only counts class-scope refs. + * Function-scope T-refs erase to their bound and aren't bound by class + * inheritance, so callers walking inheritance can ignore them. */ +ZEND_API bool zend_type_contains_class_scope_type_parameter(zend_type type) +{ + if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) { + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(type); + return ref->origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE; + } + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) { + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(type); + for (uint32_t i = 0; i < nwa->count; i++) { + if (zend_type_contains_class_scope_type_parameter(nwa->args[i])) return true; + } + } + if (ZEND_TYPE_HAS_LIST(type)) { + const zend_type *member; + ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), member) { + if (zend_type_contains_class_scope_type_parameter(*member)) return true; + } ZEND_TYPE_LIST_FOREACH_END(); + } + return false; +} + +ZEND_API zend_string *zend_generic_canonical_class_name( + zend_string *base_name, const zend_type *args, uint32_t arity) +{ + smart_str buf = {0}; + smart_str_append(&buf, base_name); + smart_str_appendc(&buf, '<'); + for (uint32_t i = 0; i < arity; i++) { + if (i > 0) smart_str_appendc(&buf, ','); + zend_string *piece = zend_canonical_one(args[i]); + smart_str_append(&buf, piece); + zend_string_release(piece); + } + smart_str_appendc(&buf, '>'); + smart_str_0(&buf); + /* Intern so repeat lookups of the same monomorph name share storage and + * EG(class_table) can dispatch on pointer identity. */ + return zend_new_interned_string(buf.s); +} + static bool is_generator_compatible_class_type(const zend_string *name) { return zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_TRAVERSABLE)) || zend_string_equals_literal_ci(name, "Iterator") @@ -1542,7 +3582,7 @@ static void zend_mark_function_as_generator(void) /* {{{ */ ZEND_TYPE_FOREACH(return_type, single_type) { if (ZEND_TYPE_HAS_NAME(*single_type) && is_generator_compatible_class_type(ZEND_TYPE_NAME(*single_type))) { - valid_type = 1; + valid_type = true; break; } } ZEND_TYPE_FOREACH_END(); @@ -1618,7 +3658,7 @@ ZEND_API zend_result zend_unmangle_property_name_ex(const zend_string *name, con } /* }}} */ -static bool array_is_const_ex(zend_array *array, uint32_t *max_checks) +static bool array_is_const_ex(const zend_array *array, uint32_t *max_checks) { if (zend_hash_num_elements(array) > *max_checks) { return false; @@ -1641,21 +3681,21 @@ static bool array_is_const_ex(zend_array *array, uint32_t *max_checks) return true; } -static bool array_is_const(zend_array *array) +static bool array_is_const(const zend_array *array) { uint32_t max_checks = 50; return array_is_const_ex(array, &max_checks); } -static bool can_ct_eval_const(zend_constant *c) { +static bool can_ct_eval_const(const zend_constant *c) { if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) { - return 0; + return false; } if ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) && !((ZEND_CONSTANT_FLAGS(c) & CONST_NO_FILE_CACHE) && (CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE))) { - return 1; + return true; } if (Z_TYPE(c->value) < IS_ARRAY && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) { @@ -1665,7 +3705,7 @@ static bool can_ct_eval_const(zend_constant *c) { && array_is_const(Z_ARR(c->value))) { return 1; } - return 0; + return false; } static bool zend_try_ct_eval_const(zval *zv, zend_string *name, bool is_fully_qualified) /* {{{ */ @@ -1682,14 +3722,14 @@ static bool zend_try_ct_eval_const(zval *zv, zend_string *name, bool is_fully_qu zend_constant *c; if ((c = zend_get_special_const(lookup_name, lookup_len))) { ZVAL_COPY_VALUE(zv, &c->value); - return 1; + return true; } c = zend_hash_find_ptr(EG(zend_constants), name); if (c && can_ct_eval_const(c)) { ZVAL_COPY_OR_DUP(zv, &c->value); - return 1; + return true; } - return 0; + return false; } /* }}} */ @@ -1697,12 +3737,12 @@ static inline bool zend_is_scope_known(void) /* {{{ */ { if (!CG(active_op_array)) { /* This can only happen when evaluating a default value string. */ - return 0; + return false; } if (CG(active_op_array)->fn_flags & ZEND_ACC_CLOSURE) { /* Closures can be rebound to a different scope */ - return 0; + return false; } if (!CG(active_class_entry)) { @@ -1716,13 +3756,13 @@ static inline bool zend_is_scope_known(void) /* {{{ */ } /* }}} */ -static inline bool class_name_refers_to_active_ce(zend_string *class_name, uint32_t fetch_type) /* {{{ */ +static inline bool class_name_refers_to_active_ce(const zend_string *class_name, uint32_t fetch_type) /* {{{ */ { if (!CG(active_class_entry)) { - return 0; + return false; } if (fetch_type == ZEND_FETCH_CLASS_SELF && zend_is_scope_known()) { - return 1; + return true; } return fetch_type == ZEND_FETCH_CLASS_DEFAULT && zend_string_equals_ci(class_name, CG(active_class_entry)->name); @@ -1756,6 +3796,9 @@ static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */ static zend_string *zend_resolve_const_class_name_reference(zend_ast *ast, const char *type) { + if (ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + ast = ast->child[0]; + } zend_string *class_name = zend_ast_get_str(ast); if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type_ast(ast)) { zend_error_noreturn(E_COMPILE_ERROR, @@ -1784,10 +3827,10 @@ static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */ static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast) /* {{{ */ { uint32_t fetch_type; - zval *class_name; + const zval *class_name; if (class_ast->kind != ZEND_AST_ZVAL) { - return 0; + return false; } class_name = zend_ast_get_zval(class_ast); @@ -1796,6 +3839,13 @@ static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *c zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name"); } + /* T::class resolves at runtime through the runtime T-table (frame for + * function-level T, called scope for class-level T). */ + if ((class_ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ + && zend_generic_lookup(Z_STR_P(class_name))) { + return false; + } + fetch_type = zend_get_class_fetch_type(Z_STR_P(class_name)); zend_ensure_valid_class_fetch_type(fetch_type); @@ -1803,28 +3853,28 @@ static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *c case ZEND_FETCH_CLASS_SELF: if (CG(active_class_entry) && zend_is_scope_known()) { ZVAL_STR_COPY(zv, CG(active_class_entry)->name); - return 1; + return true; } - return 0; + return false; case ZEND_FETCH_CLASS_PARENT: if (CG(active_class_entry) && CG(active_class_entry)->parent_name && zend_is_scope_known()) { ZVAL_STR_COPY(zv, CG(active_class_entry)->parent_name); - return 1; + return true; } - return 0; + return false; case ZEND_FETCH_CLASS_STATIC: - return 0; + return false; case ZEND_FETCH_CLASS_DEFAULT: ZVAL_STR(zv, zend_resolve_class_name_ast(class_ast)); - return 1; - EMPTY_SWITCH_DEFAULT_CASE() + return true; + default: ZEND_UNREACHABLE(); } } /* }}} */ /* We don't use zend_verify_const_access because we need to deal with unlinked classes. */ -static bool zend_verify_ct_const_access(zend_class_constant *c, zend_class_entry *scope) +static bool zend_verify_ct_const_access(const zend_class_constant *c, const zend_class_entry *scope) { if (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED) { return 0; @@ -1869,7 +3919,7 @@ static bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend if (class_name_refers_to_active_ce(class_name, fetch_type)) { cc = zend_hash_find_ptr(&CG(active_class_entry)->constants_table, name); } else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) { - zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), class_name); + const zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), class_name); if (ce) { cc = zend_hash_find_ptr(&ce->constants_table, name); } else { @@ -1880,11 +3930,11 @@ static bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend } if (CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) { - return 0; + return false; } if (!cc || !zend_verify_ct_const_access(cc, CG(active_class_entry))) { - return 0; + return false; } c = &cc->value; @@ -1898,7 +3948,7 @@ static bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend return 1; } - return 0; + return false; } /* }}} */ @@ -1922,7 +3972,7 @@ static void zend_add_to_list(void *result, void *item) /* {{{ */ } /* }}} */ -static void zend_do_extended_stmt(void) /* {{{ */ +static void zend_do_extended_stmt(znode* result) /* {{{ */ { zend_op *opline; @@ -1933,6 +3983,12 @@ static void zend_do_extended_stmt(void) /* {{{ */ opline = get_next_op(); opline->opcode = ZEND_EXT_STMT; + if (result) { + if (result->op_type == IS_CONST) { + Z_TRY_ADDREF(result->u.constant); + } + SET_NODE(opline->op1, result); + } } /* }}} */ @@ -2011,12 +4067,12 @@ ZEND_API void zend_activate_auto_globals(void) /* {{{ */ zend_auto_global *auto_global; ZEND_HASH_MAP_FOREACH_PTR(CG(auto_globals), auto_global) { - if (auto_global->jit) { - auto_global->armed = 1; - } else if (auto_global->auto_global_callback) { + auto_global->armed = auto_global->jit || auto_global->auto_global_callback; + } ZEND_HASH_FOREACH_END(); + + ZEND_HASH_MAP_FOREACH_PTR(CG(auto_globals), auto_global) { + if (auto_global->armed && !auto_global->jit) { auto_global->armed = auto_global->auto_global_callback(auto_global->name); - } else { - auto_global->armed = 0; } } ZEND_HASH_FOREACH_END(); } @@ -2027,6 +4083,12 @@ int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem) /* {{{ */ zval zv; int ret; + if (CG(type_arg_residual_token)) { + ret = CG(type_arg_residual_token); + CG(type_arg_residual_token) = 0; + return ret; + } + if (CG(increment_lineno)) { CG(zend_lineno)++; CG(increment_lineno) = 0; @@ -2034,8 +4096,22 @@ int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem) /* {{{ */ ret = lex_scan(&zv, elem); ZEND_ASSERT(!EG(exception) || ret == T_ERROR); - return ret; + if (CG(type_arg_depth) > 0) { + switch (ret) { + case T_SR: + CG(type_arg_residual_token) = '>'; + return '>'; + case T_IS_GREATER_OR_EQUAL: + CG(type_arg_residual_token) = '='; + return '>'; + case T_SR_EQUAL: + CG(type_arg_residual_token) = T_IS_GREATER_OR_EQUAL; + return '>'; + } + } + + return ret; } /* }}} */ @@ -2045,6 +4121,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand ce->refcount = 1; ce->ce_flags = ZEND_ACC_CONSTANTS_UPDATED; + ce->ce_flags2 = 0; if (CG(compiler_options) & ZEND_COMPILE_GUARDS) { ce->ce_flags |= ZEND_ACC_USE_GUARDS; @@ -2068,6 +4145,9 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand ce->attributes = NULL; ce->enum_backing_type = IS_UNDEF; ce->backed_enum_table = NULL; + ce->generic_parameters = NULL; + ce->generic_types = NULL; + ce->generic_type_args = NULL; if (nullify_handlers) { ce->constructor = NULL; @@ -2176,7 +4256,7 @@ ZEND_API size_t zend_dirname(char *path, size_t len) /* Note that on Win32 CWD is per drive (heritage from CP/M). * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive. */ - if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) { + if ((2 <= len) && isalpha((unsigned char)path[0]) && (':' == path[1])) { /* Skip over the drive spec (if any) so as not to change */ path += 2; len_adjust += 2; @@ -2258,7 +4338,7 @@ static void zend_adjust_for_fetch_type(zend_op *opline, znode *result, uint32_t case BP_VAR_UNSET: opline->opcode += 5 * factor; return; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -2421,7 +4501,7 @@ static inline void zend_update_jump_target(uint32_t opnum_jump, uint32_t opnum_t case ZEND_JMP_FRAMELESS: opline->op2.opline_num = opnum_target; break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -2490,9 +4570,9 @@ static bool zend_ast_kind_is_short_circuited(zend_ast_kind ast_kind) case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: case ZEND_AST_STATIC_CALL: - return 1; + return true; default: - return 0; + return false; } } @@ -2507,9 +4587,9 @@ static bool zend_ast_is_short_circuited(const zend_ast *ast) return zend_ast_is_short_circuited(ast->child[0]); case ZEND_AST_NULLSAFE_PROP: case ZEND_AST_NULLSAFE_METHOD_CALL: - return 1; + return true; default: - return 0; + return false; } } @@ -2537,7 +4617,7 @@ static uint32_t zend_short_circuiting_checkpoint(void) return zend_stack_count(&CG(short_circuiting_opnums)); } -static void zend_short_circuiting_commit(uint32_t checkpoint, znode *result, zend_ast *ast) +static void zend_short_circuiting_commit(uint32_t checkpoint, znode *result, const zend_ast *ast) { bool is_short_circuited = zend_ast_kind_is_short_circuited(ast->kind) || ast->kind == ZEND_AST_ISSET || ast->kind == ZEND_AST_EMPTY; @@ -2578,7 +4658,9 @@ static void zend_emit_jmp_null(znode *obj_node, uint32_t bp_type) zend_stack_push(&CG(short_circuiting_opnums), &jmp_null_opnum); } -static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */ +static inline bool zend_is_variable_or_call(const zend_ast *ast); + +static void zend_compile_memoized_expr(znode *result, zend_ast *expr, uint32_t type) /* {{{ */ { const zend_memoize_mode memoize_mode = CG(memoize_mode); if (memoize_mode == ZEND_MEMOIZE_COMPILE) { @@ -2586,7 +4668,11 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */ /* Go through normal compilation */ CG(memoize_mode) = ZEND_MEMOIZE_NONE; - zend_compile_expr(result, expr); + if (zend_is_variable_or_call(expr)) { + zend_compile_var(result, expr, type, /* by_ref */ false); + } else { + zend_compile_expr(result, expr); + } CG(memoize_mode) = ZEND_MEMOIZE_COMPILE; if (result->op_type == IS_VAR) { @@ -2603,7 +4689,7 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */ zend_hash_index_update_mem( CG(memoized_exprs), (uintptr_t) expr, &memoized_result, sizeof(znode)); } else if (memoize_mode == ZEND_MEMOIZE_FETCH) { - znode *memoized_result = zend_hash_index_find_ptr(CG(memoized_exprs), (uintptr_t) expr); + const znode *memoized_result = zend_hash_index_find_ptr(CG(memoized_exprs), (uintptr_t) expr); *result = *memoized_result; if (result->op_type == IS_CONST) { Z_TRY_ADDREF(result->u.constant); @@ -2615,7 +4701,7 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */ /* }}} */ static void zend_emit_return_type_check( - znode *expr, zend_arg_info *return_info, bool implicit) /* {{{ */ + znode *expr, const zend_arg_info *return_info, bool implicit) /* {{{ */ { zend_type type = return_info->type; if (ZEND_TYPE_IS_SET(type)) { @@ -2644,7 +4730,6 @@ static void zend_emit_return_type_check( ZEND_ASSERT(!implicit); zend_error_noreturn(E_COMPILE_ERROR, "A never-returning %s must not return", CG(active_class_entry) != NULL ? "method" : "function"); - return; } if (!expr && !implicit) { @@ -2660,12 +4745,28 @@ static void zend_emit_return_type_check( } } + /* Generic functions: if the return is a T-ref, the runtime opcode + * is the only place the reified binding gets checked. Detect that + * here so the two elision paths below don't drop the opcode. */ + zend_op_array *active = CG(active_op_array); + const zend_type *pre_return = + active->generic_types ? active->generic_types->return_type : NULL; + bool return_is_generic = pre_return + && ZEND_TYPE_HAS_TYPE_PARAMETER(*pre_return); + if (expr && ZEND_TYPE_PURE_MASK(type) == MAY_BE_ANY) { - /* we don't need run-time check for mixed return type */ - return; + /* Mixed normally needs no run-time check, but if the return is a + * generic parameter that erased to mixed, a child substituting T to + * a concrete type relies on this opcode being present in the shared + * body so its substituted arg_info gets checked. */ + if (!return_is_generic) { + return; + } } - if (expr && expr->op_type == IS_CONST && ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE(expr->u.constant))) { + if (!return_is_generic + && expr && expr->op_type == IS_CONST + && ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE(expr->u.constant))) { /* we don't need run-time check */ return; } @@ -2694,7 +4795,7 @@ void zend_emit_final_return(bool return_one) /* {{{ */ return; } - zend_emit_return_type_check(NULL, return_info, 1); + zend_emit_return_type_check(NULL, return_info, true); } zn.op_type = IS_CONST; @@ -2709,7 +4810,7 @@ void zend_emit_final_return(bool return_one) /* {{{ */ } /* }}} */ -static inline bool zend_is_variable(zend_ast *ast) /* {{{ */ +static inline bool zend_is_variable(const zend_ast *ast) /* {{{ */ { return ast->kind == ZEND_AST_VAR || ast->kind == ZEND_AST_DIM @@ -2719,22 +4820,38 @@ static inline bool zend_is_variable(zend_ast *ast) /* {{{ */ } /* }}} */ -static inline bool zend_is_call(zend_ast *ast) /* {{{ */ +static bool zend_propagate_list_refs(zend_ast *ast); + +static inline bool zend_is_passable_by_ref(const zend_ast *ast) +{ + if (zend_is_variable(ast) || ast->kind == ZEND_AST_ASSIGN_REF) { + return true; + } + if (ast->kind == ZEND_AST_ASSIGN + && UNEXPECTED(ast->child[0]->kind == ZEND_AST_ARRAY) + && zend_propagate_list_refs(ast->child[0])) { + return true; + } + return false; +} + +static inline bool zend_is_call(const zend_ast *ast) /* {{{ */ { return ast->kind == ZEND_AST_CALL || ast->kind == ZEND_AST_METHOD_CALL || ast->kind == ZEND_AST_NULLSAFE_METHOD_CALL - || ast->kind == ZEND_AST_STATIC_CALL; + || ast->kind == ZEND_AST_STATIC_CALL + || ast->kind == ZEND_AST_PIPE; } /* }}} */ -static inline bool zend_is_variable_or_call(zend_ast *ast) /* {{{ */ +static inline bool zend_is_variable_or_call(const zend_ast *ast) /* {{{ */ { return zend_is_variable(ast) || zend_is_call(ast); } /* }}} */ -static inline bool zend_is_unticked_stmt(zend_ast *ast) /* {{{ */ +static inline bool zend_is_unticked_stmt(const zend_ast *ast) /* {{{ */ { return ast->kind == ZEND_AST_STMT_LIST || ast->kind == ZEND_AST_LABEL || ast->kind == ZEND_AST_PROP_DECL || ast->kind == ZEND_AST_CLASS_CONST_GROUP @@ -2742,7 +4859,7 @@ static inline bool zend_is_unticked_stmt(zend_ast *ast) /* {{{ */ } /* }}} */ -static inline bool zend_can_write_to_variable(zend_ast *ast) /* {{{ */ +static inline bool zend_can_write_to_variable(const zend_ast *ast) /* {{{ */ { while ( ast->kind == ZEND_AST_DIM @@ -2757,8 +4874,11 @@ static inline bool zend_can_write_to_variable(zend_ast *ast) /* {{{ */ static inline bool zend_is_const_default_class_ref(zend_ast *name_ast) /* {{{ */ { + if (name_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + name_ast = name_ast->child[0]; + } if (name_ast->kind != ZEND_AST_ZVAL) { - return 0; + return false; } return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type_ast(name_ast); @@ -2778,7 +4898,7 @@ static inline void zend_handle_numeric_op(znode *node) /* {{{ */ } /* }}} */ -static inline void zend_handle_numeric_dim(zend_op *opline, znode *dim_node) /* {{{ */ +static inline void zend_handle_numeric_dim(const zend_op *opline, znode *dim_node) /* {{{ */ { if (Z_TYPE(dim_node->u.constant) == IS_STRING) { zend_ulong index; @@ -2809,10 +4929,62 @@ static inline void zend_set_class_name_op1(zend_op *opline, znode *class_node) / } /* }}} */ +/* At a compile-time canonical-name production site, try to register the + * monomorph in the class table now so opcache picks it up via the regular + * CG(class_table) → script.class_table persistence path. If the base isn't + * compiled yet (forward reference, autoloaded class, etc.) or synthesis + * fails for any other reason, the runtime lookup hook synthesises lazily + * on first reference. + * + * Exceptions raised by synthesis (e.g. a bound violation in the monomorph + * being created) are suppressed here — the runtime path will rethrow them + * as a catchable TypeError exactly where it would have without this + * optimisation. */ +static void zend_try_compile_time_synthesize_monomorph(zend_string *canonical) +{ + zend_object *saved_exception = EG(exception); + EG(exception) = NULL; + + (void) zend_try_synthesize_monomorph_by_name(canonical, ZEND_FETCH_CLASS_NO_AUTOLOAD); + + if (EG(exception)) { + OBJ_RELEASE(EG(exception)); + EG(exception) = NULL; + } + EG(exception) = saved_exception; +} + static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t fetch_flags) /* {{{ */ { uint32_t fetch_type; + /* Generic named type Box: when the args are concrete (no T-refs) + * we resolve to the monomorph's canonical name "Box" so callers + * like `instanceof Box` and `catch (Box $e)` distinguish + * monos. When the args contain T-refs (e.g. `instanceof Box`) we stash + * the pre-erasure type in the op_array's side table and emit a deferred + * fetch; the runtime substitutes T against the current frame's bindings + * and looks up (or synthesises) the resulting monomorph. */ + if (name_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + zend_type ty = zend_compile_pre_erasure_typename(name_ast); + if (!zend_type_contains_type_parameter(ty)) { + zend_string *canonical = zend_type_to_canonical_string(ty); + zend_try_compile_time_synthesize_monomorph(canonical); + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, canonical); + zend_type_release(ty, /* persistent */ false); + return; + } + zend_generic_type_table *table = + zend_generic_get_or_create_op_array_table(CG(active_op_array)); + uint32_t args_id = (table->turbofish_args + ? zend_hash_num_elements(table->turbofish_args) : 0) + 1; + zend_generic_type_table_set_turbofish_args(table, args_id, ty); + result->op_type = IS_UNUSED; + result->u.op.num = zend_pack_generic_deferred_fetch(args_id, fetch_flags); + return; + } + if (name_ast->kind != ZEND_AST_ZVAL) { znode name_node; @@ -2852,6 +5024,22 @@ static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t f return; } + /* T in expression position (new T(), T::FOO, instanceof T, T::method()) + * resolves through the runtime T-table — function/method-level T from the + * call frame, class-level T from the called scope's monomorph args. */ + if ((name_ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + zend_generic_origin origin; + uint32_t param_index = 0; + zend_generic_parameter *param = zend_generic_lookup_full( + zend_ast_get_str(name_ast), &origin, ¶m_index); + if (param) { + result->op_type = IS_UNUSED; + result->u.op.num = zend_pack_type_param_fetch(param_index, fetch_flags, + origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE); + return; + } + } + fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast)); if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) { result->op_type = IS_CONST; @@ -2864,7 +5052,7 @@ static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t f } /* }}} */ -static zend_result zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */ +static zend_result zend_try_compile_cv(znode *result, const zend_ast *ast, uint32_t type) /* {{{ */ { zend_ast *name_ast = ast->child[0]; if (name_ast->kind == ZEND_AST_ZVAL) { @@ -2881,6 +5069,16 @@ static zend_result zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */ return FAILURE; } + if (!CG(context).has_assigned_to_http_response_header && zend_string_equals_literal(name, "http_response_header")) { + if (type == BP_VAR_R) { + zend_error(E_DEPRECATED, + "The predefined locally scoped $http_response_header variable is deprecated," + " call http_get_last_response_headers() instead"); + } else if (type == BP_VAR_W) { + CG(context).has_assigned_to_http_response_header = true; + } + } + result->op_type = IS_CV; result->u.op.var = lookup_cv(name); @@ -2895,7 +5093,7 @@ static zend_result zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint32_t type, bool delayed) /* {{{ */ +static zend_op *zend_compile_simple_var_no_cv(znode *result, const zend_ast *ast, uint32_t type, bool delayed) /* {{{ */ { zend_ast *name_ast = ast->child[0]; znode name_node; @@ -2917,6 +5115,13 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint opline->extended_value = ZEND_FETCH_GLOBAL; } else { + if (name_node.op_type == IS_CONST + && type == BP_VAR_R + && zend_string_equals_literal(Z_STR(name_node.u.constant), "http_response_header")) { + zend_error(E_DEPRECATED, + "The predefined locally scoped $http_response_header variable is deprecated," + " call http_get_last_response_headers() instead"); + } opline->extended_value = ZEND_FETCH_LOCAL; } @@ -2925,39 +5130,39 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint } /* }}} */ -static bool is_this_fetch(zend_ast *ast) /* {{{ */ +static bool is_this_fetch(const zend_ast *ast) /* {{{ */ { if (ast->kind == ZEND_AST_VAR && ast->child[0]->kind == ZEND_AST_ZVAL) { - zval *name = zend_ast_get_zval(ast->child[0]); + const zval *name = zend_ast_get_zval(ast->child[0]); return Z_TYPE_P(name) == IS_STRING && zend_string_equals(Z_STR_P(name), ZSTR_KNOWN(ZEND_STR_THIS)); } - return 0; + return false; } /* }}} */ static bool is_globals_fetch(const zend_ast *ast) { if (ast->kind == ZEND_AST_VAR && ast->child[0]->kind == ZEND_AST_ZVAL) { - zval *name = zend_ast_get_zval(ast->child[0]); + const zval *name = zend_ast_get_zval(ast->child[0]); return Z_TYPE_P(name) == IS_STRING && zend_string_equals_literal(Z_STR_P(name), "GLOBALS"); } - return 0; + return false; } -static bool is_global_var_fetch(zend_ast *ast) +static bool is_global_var_fetch(const zend_ast *ast) { return ast->kind == ZEND_AST_DIM && is_globals_fetch(ast->child[0]); } static bool this_guaranteed_exists(void) /* {{{ */ { - zend_oparray_context *ctx = &CG(context); + const zend_oparray_context *ctx = &CG(context); while (ctx) { /* Instance methods always have a $this. * This also includes closures that have a scope and use $this. */ - zend_op_array *op_array = ctx->op_array; + const zend_op_array *op_array = ctx->op_array; if (op_array->fn_flags & ZEND_ACC_STATIC) { return false; } else if (op_array->scope) { @@ -2971,7 +5176,7 @@ static bool this_guaranteed_exists(void) /* {{{ */ } /* }}} */ -static zend_op *zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t type, bool delayed) /* {{{ */ +static zend_op *zend_compile_simple_var(znode *result, const zend_ast *ast, uint32_t type, bool delayed) /* {{{ */ { if (is_this_fetch(ast)) { zend_op *opline = zend_emit_op(result, ZEND_FETCH_THIS, NULL, NULL); @@ -2988,14 +5193,14 @@ static zend_op *zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t t result->op_type = IS_TMP_VAR; } return opline; - } else if (zend_try_compile_cv(result, ast) == FAILURE) { + } else if (zend_try_compile_cv(result, ast, type) == FAILURE) { return zend_compile_simple_var_no_cv(result, ast, type, delayed); } return NULL; } /* }}} */ -static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t type) /* {{{ */ +static void zend_separate_if_call_and_write(znode *node, const zend_ast *ast, uint32_t type) /* {{{ */ { if (type != BP_VAR_R && type != BP_VAR_IS @@ -3013,7 +5218,7 @@ static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t } /* }}} */ -static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node) /* {{{ */ +static inline void zend_emit_assign_znode(zend_ast *var_ast, const znode *value_node) /* {{{ */ { znode dummy_node; zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast, @@ -3047,7 +5252,7 @@ static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t return opline; } else { zend_short_circuiting_mark_inner(var_ast); - opline = zend_delayed_compile_var(&var_node, var_ast, type, 0); + opline = zend_delayed_compile_var(&var_node, var_ast, type, false); if (opline) { if (type == BP_VAR_W && (opline->opcode == ZEND_FETCH_STATIC_PROP_W || opline->opcode == ZEND_FETCH_OBJ_W)) { opline->extended_value |= ZEND_FETCH_DIM_WRITE; @@ -3107,7 +5312,11 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t if (this_guaranteed_exists()) { obj_node.op_type = IS_UNUSED; } else { - zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL); + opline = zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL); + if ((type == BP_VAR_R) || (type == BP_VAR_IS)) { + opline->result_type = IS_TMP_VAR; + obj_node.op_type = IS_TMP_VAR; + } } CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS; @@ -3115,7 +5324,7 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t * check for a nullsafe access. */ } else { zend_short_circuiting_mark_inner(obj_ast); - opline = zend_delayed_compile_var(&obj_node, obj_ast, type, 0); + opline = zend_delayed_compile_var(&obj_node, obj_ast, type, false); if (opline && (opline->opcode == ZEND_FETCH_DIM_W || opline->opcode == ZEND_FETCH_DIM_RW || opline->opcode == ZEND_FETCH_DIM_FUNC_ARG @@ -3221,7 +5430,7 @@ static zend_op *zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t } /* }}} */ -static void zend_verify_list_assign_target(zend_ast *var_ast, zend_ast_attr array_style) /* {{{ */ { +static void zend_verify_list_assign_target(const zend_ast *var_ast, zend_ast_attr array_style) /* {{{ */ { if (var_ast->kind == ZEND_AST_ARRAY) { if (var_ast->attr == ZEND_ARRAY_SYNTAX_LONG) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot assign to array(), use [] instead"); @@ -3235,12 +5444,12 @@ static void zend_verify_list_assign_target(zend_ast *var_ast, zend_ast_attr arra } /* }}} */ -static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_node); +static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, const znode *value_node); /* Propagate refs used on leaf elements to the surrounding list() structures. */ static bool zend_propagate_list_refs(zend_ast *ast) { /* {{{ */ - zend_ast_list *list = zend_ast_get_list(ast); - bool has_refs = 0; + const zend_ast_list *list = zend_ast_get_list(ast); + bool has_refs = false; uint32_t i; for (i = 0; i < list->children; ++i) { @@ -3259,10 +5468,10 @@ static bool zend_propagate_list_refs(zend_ast *ast) { /* {{{ */ } /* }}} */ -static bool list_is_keyed(zend_ast_list *list) +static bool list_is_keyed(const zend_ast_list *list) { for (uint32_t i = 0; i < list->children; i++) { - zend_ast *child = list->child[i]; + const zend_ast *child = list->child[i]; if (child) { return child->kind == ZEND_AST_ARRAY_ELEM && child->child[1] != NULL; } @@ -3271,11 +5480,11 @@ static bool list_is_keyed(zend_ast_list *list) } static void zend_compile_list_assign( - znode *result, zend_ast *ast, znode *expr_node, zend_ast_attr array_style) /* {{{ */ + znode *result, zend_ast *ast, znode *expr_node, zend_ast_attr array_style, uint32_t type) /* {{{ */ { zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; - bool has_elems = 0; + bool has_elems = false; bool is_keyed = list_is_keyed(list); if (list->children && expr_node->op_type == IS_CONST && Z_TYPE(expr_node->u.constant) == IS_STRING) { @@ -3304,7 +5513,7 @@ static void zend_compile_list_assign( var_ast = elem_ast->child[0]; key_ast = elem_ast->child[1]; - has_elems = 1; + has_elems = true; if (is_keyed) { if (key_ast == NULL) { @@ -3331,6 +5540,10 @@ static void zend_compile_list_assign( opline = zend_emit_op(&fetch_result, elem_ast->attr ? (expr_node->op_type == IS_CV ? ZEND_FETCH_DIM_W : ZEND_FETCH_LIST_W) : ZEND_FETCH_LIST_R, expr_node, &dim_node); + if (opline->opcode == ZEND_FETCH_LIST_R) { + opline->result_type = IS_TMP_VAR; + fetch_result.op_type = IS_TMP_VAR; + } if (dim_node.op_type == IS_CONST) { zend_handle_numeric_dim(opline, &dim_node); @@ -3340,7 +5553,7 @@ static void zend_compile_list_assign( zend_emit_op(&fetch_result, ZEND_MAKE_REF, &fetch_result, NULL); } if (var_ast->kind == ZEND_AST_ARRAY) { - zend_compile_list_assign(NULL, var_ast, &fetch_result, var_ast->attr); + zend_compile_list_assign(NULL, var_ast, &fetch_result, var_ast->attr, type); } else if (elem_ast->attr) { zend_emit_assign_ref_znode(var_ast, &fetch_result); } else { @@ -3353,7 +5566,12 @@ static void zend_compile_list_assign( } if (result) { - *result = *expr_node; + if ((type == BP_VAR_R || type == BP_VAR_IS) && expr_node->op_type == IS_VAR) { + /* Deref. */ + zend_emit_op_tmp(result, ZEND_QM_ASSIGN, expr_node, NULL); + } else { + *result = *expr_node; + } } else { zend_do_free(expr_node); } @@ -3362,7 +5580,7 @@ static void zend_compile_list_assign( static void zend_ensure_writable_variable(const zend_ast *ast) /* {{{ */ { - if (ast->kind == ZEND_AST_CALL) { + if (ast->kind == ZEND_AST_CALL || ast->kind == ZEND_AST_PIPE) { zend_error_noreturn(E_COMPILE_ERROR, "Can't use function return value in write context"); } if ( @@ -3383,10 +5601,10 @@ static void zend_ensure_writable_variable(const zend_ast *ast) /* {{{ */ /* }}} */ /* Detects $a... = $a pattern */ -static bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{ */ +static bool zend_is_assign_to_self(const zend_ast *var_ast, const zend_ast *expr_ast) /* {{{ */ { if (expr_ast->kind != ZEND_AST_VAR || expr_ast->child[0]->kind != ZEND_AST_ZVAL) { - return 0; + return false; } while (zend_is_variable(var_ast) && var_ast->kind != ZEND_AST_VAR) { @@ -3394,7 +5612,7 @@ static bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{ } if (var_ast->kind != ZEND_AST_VAR || var_ast->child[0]->kind != ZEND_AST_ZVAL) { - return 0; + return false; } { @@ -3409,13 +5627,13 @@ static bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{ /* }}} */ static void zend_compile_expr_with_potential_assign_to_self( - znode *expr_node, zend_ast *expr_ast, zend_ast *var_ast) { + znode *expr_node, zend_ast *expr_ast, const zend_ast *var_ast) { if (zend_is_assign_to_self(var_ast, expr_ast) && !is_this_fetch(expr_ast)) { /* $a[0] = $a should evaluate the right $a first */ znode cv_node; - if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) { - zend_compile_simple_var_no_cv(expr_node, expr_ast, BP_VAR_R, 0); + if (zend_try_compile_cv(&cv_node, expr_ast, BP_VAR_R) == FAILURE) { + zend_compile_simple_var_no_cv(expr_node, expr_ast, BP_VAR_R, false); } else { zend_emit_op_tmp(expr_node, ZEND_QM_ASSIGN, &cv_node, NULL); } @@ -3424,7 +5642,7 @@ static void zend_compile_expr_with_potential_assign_to_self( } } -static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt, uint32_t type) /* {{{ */ { zend_ast *var_ast = ast->child[0]; zend_ast *expr_ast = ast->child[1]; @@ -3443,7 +5661,7 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ switch (kind) { case ZEND_AST_VAR: offset = zend_delayed_compile_begin(); - zend_delayed_compile_var(&var_node, var_ast, BP_VAR_W, 0); + zend_delayed_compile_var(&var_node, var_ast, BP_VAR_W, false); zend_compile_expr(&expr_node, expr_ast); zend_delayed_compile_end(offset); CG(zend_lineno) = zend_ast_get_lineno(var_ast); @@ -3451,7 +5669,7 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ return; case ZEND_AST_STATIC_PROP: offset = zend_delayed_compile_begin(); - zend_delayed_compile_var(result, var_ast, BP_VAR_W, 0); + zend_delayed_compile_var(result, var_ast, BP_VAR_W, false); zend_compile_expr(&expr_node, expr_ast); opline = zend_delayed_compile_end(offset); @@ -3495,7 +5713,7 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ zend_assert_not_short_circuited(expr_ast); } - zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1); + zend_compile_var(&expr_node, expr_ast, BP_VAR_W, true); /* MAKE_REF is usually not necessary for CVs. However, if there are * self-assignments, this forces the RHS to evaluate first. */ zend_emit_op(&expr_node, ZEND_MAKE_REF, &expr_node, NULL); @@ -3504,8 +5722,8 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ /* list($a, $b) = $a should evaluate the right $a first */ znode cv_node; - if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) { - zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0); + if (zend_try_compile_cv(&cv_node, expr_ast, BP_VAR_R) == FAILURE) { + zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, false); } else { zend_emit_op_tmp(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL); } @@ -3514,14 +5732,17 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ } } - zend_compile_list_assign(result, var_ast, &expr_node, var_ast->attr); + zend_compile_list_assign(!stmt ? result : NULL, var_ast, &expr_node, var_ast->attr, type); + if (stmt) { + result->op_type = IS_UNUSED; + } return; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ -static void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_assign_ref(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ { zend_ast *target_ast = ast->child[0]; zend_ast *source_ast = ast->child[1]; @@ -3540,8 +5761,8 @@ static void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ } offset = zend_delayed_compile_begin(); - zend_delayed_compile_var(&target_node, target_ast, BP_VAR_W, 1); - zend_compile_var(&source_node, source_ast, BP_VAR_W, 1); + zend_delayed_compile_var(&target_node, target_ast, BP_VAR_W, true); + zend_compile_var(&source_node, source_ast, BP_VAR_W, true); if ((target_ast->kind != ZEND_AST_VAR || target_ast->child[0]->kind != ZEND_AST_ZVAL) @@ -3568,28 +5789,40 @@ static void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ opline->opcode = ZEND_ASSIGN_OBJ_REF; opline->extended_value &= ~ZEND_FETCH_REF; opline->extended_value |= flags; + if (result) { + *result = target_node; + } else { + SET_UNUSED(opline->result); + } zend_emit_op_data(&source_node); - *result = target_node; } else if (opline && opline->opcode == ZEND_FETCH_STATIC_PROP_W) { opline->opcode = ZEND_ASSIGN_STATIC_PROP_REF; opline->extended_value &= ~ZEND_FETCH_REF; opline->extended_value |= flags; + if (result) { + *result = target_node; + } else { + SET_UNUSED(opline->result); + } zend_emit_op_data(&source_node); - *result = target_node; } else { opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node); opline->extended_value = flags; } + + if (result && (type == BP_VAR_R || type == BP_VAR_IS)) { + /* Deref. */ + znode tmp_result = *result; + zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &tmp_result, NULL); + } } /* }}} */ -static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_node) /* {{{ */ +static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, const znode *value_node) /* {{{ */ { - znode dummy_node; zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN_REF, var_ast, zend_ast_create_znode(value_node)); - zend_compile_expr(&dummy_node, assign_ast); - zend_do_free(&dummy_node); + zend_compile_stmt(assign_ast); } /* }}} */ @@ -3610,7 +5843,7 @@ static void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */ switch (kind) { case ZEND_AST_VAR: offset = zend_delayed_compile_begin(); - zend_delayed_compile_var(&var_node, var_ast, BP_VAR_RW, 0); + zend_delayed_compile_var(&var_node, var_ast, BP_VAR_RW, false); zend_compile_expr(&expr_node, expr_ast); zend_delayed_compile_end(offset); opline = zend_emit_op_tmp(result, ZEND_ASSIGN_OP, &var_node, &expr_node); @@ -3618,7 +5851,7 @@ static void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */ return; case ZEND_AST_STATIC_PROP: offset = zend_delayed_compile_begin(); - zend_delayed_compile_var(result, var_ast, BP_VAR_RW, 0); + zend_delayed_compile_var(result, var_ast, BP_VAR_RW, false); zend_compile_expr(&expr_node, expr_ast); opline = zend_delayed_compile_end(offset); @@ -3660,28 +5893,17 @@ static void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */ opline = zend_emit_op_data(&expr_node); opline->extended_value = cache_slot; return; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ -static uint32_t zend_get_arg_num(zend_function *fn, zend_string *arg_name) { +static uint32_t zend_get_arg_num(const zend_function *fn, const zend_string *arg_name) { // TODO: Caching? - if (fn->type == ZEND_USER_FUNCTION) { - for (uint32_t i = 0; i < fn->common.num_args; i++) { - zend_arg_info *arg_info = &fn->op_array.arg_info[i]; - if (zend_string_equals(arg_info->name, arg_name)) { - return i + 1; - } - } - } else { - ZEND_ASSERT(fn->common.num_args == 0 || fn->internal_function.arg_info); - for (uint32_t i = 0; i < fn->common.num_args; i++) { - zend_internal_arg_info *arg_info = &fn->internal_function.arg_info[i]; - size_t len = strlen(arg_info->name); - if (zend_string_equals_cstr(arg_name, arg_info->name, len)) { - return i + 1; - } + for (uint32_t i = 0; i < fn->common.num_args; i++) { + zend_arg_info *arg_info = &fn->op_array.arg_info[i]; + if (zend_string_equals(arg_info->name, arg_name)) { + return i + 1; } } @@ -3690,20 +5912,20 @@ static uint32_t zend_get_arg_num(zend_function *fn, zend_string *arg_name) { } static uint32_t zend_compile_args( - zend_ast *ast, zend_function *fbc, bool *may_have_extra_named_args) /* {{{ */ + zend_ast *ast, const zend_function *fbc, bool *may_have_extra_named_args) /* {{{ */ { - zend_ast_list *args = zend_ast_get_list(ast); + const zend_ast_list *args = zend_ast_get_list(ast); uint32_t i; - bool uses_arg_unpack = 0; + bool uses_arg_unpack = false; uint32_t arg_count = 0; /* number of arguments not including unpacks */ /* Whether named arguments are used syntactically, to enforce language level limitations. * May not actually use named argument passing. */ - bool uses_named_args = 0; + bool uses_named_args = false; /* Whether there may be any undef arguments due to the use of named arguments. */ - bool may_have_undef = 0; + bool may_have_undef = false; /* Whether there may be any extra named arguments collected into a variadic. */ - *may_have_extra_named_args = 0; + *may_have_extra_named_args = false; for (i = 0; i < args->children; ++i) { zend_ast *arg = args->child[i]; @@ -3721,12 +5943,12 @@ static uint32_t zend_compile_args( } /* Unpack may contain named arguments. */ - may_have_undef = 1; + may_have_undef = true; if (!fbc || (fbc->common.fn_flags & ZEND_ACC_VARIADIC)) { - *may_have_extra_named_args = 1; + *may_have_extra_named_args = true; } - uses_arg_unpack = 1; + uses_arg_unpack = true; fbc = NULL; zend_compile_expr(&arg_node, arg->child[0]); @@ -3738,7 +5960,7 @@ static uint32_t zend_compile_args( } if (arg->kind == ZEND_AST_NAMED_ARG) { - uses_named_args = 1; + uses_named_args = true; arg_name = zval_make_interned_string(zend_ast_get_zval(arg->child[0])); arg = arg->child[1]; @@ -3750,15 +5972,15 @@ static uint32_t zend_compile_args( arg_count++; } else { // TODO: We could track which arguments were passed, even if out of order. - may_have_undef = 1; + may_have_undef = true; if (arg_num == (uint32_t) -1 && (fbc->common.fn_flags & ZEND_ACC_VARIADIC)) { - *may_have_extra_named_args = 1; + *may_have_extra_named_args = true; } } } else { arg_num = (uint32_t) -1; - may_have_undef = 1; - *may_have_extra_named_args = 1; + may_have_undef = true; + *may_have_extra_named_args = true; } } else { if (uses_arg_unpack) { @@ -3777,7 +5999,9 @@ static uint32_t zend_compile_args( /* Treat passing of $GLOBALS the same as passing a call. * This will error at runtime if the argument is by-ref. */ if (zend_is_call(arg) || is_globals_fetch(arg)) { - zend_compile_var(&arg_node, arg, BP_VAR_R, 0); + uint32_t type = is_globals_fetch(arg) || (fbc && !ARG_SHOULD_BE_SENT_BY_REF(fbc, arg_num)) + ? BP_VAR_R : BP_VAR_FUNC_ARG; + zend_compile_var(&arg_node, arg, type, /* by_ref */ false); if (arg_node.op_type & (IS_CONST|IS_TMP_VAR)) { /* Function call was converted into builtin instruction */ if (!fbc || ARG_MUST_BE_SENT_BY_REF(fbc, arg_num)) { @@ -3801,13 +6025,13 @@ static uint32_t zend_compile_args( opcode = ZEND_SEND_VAR_NO_REF_EX; } } - } else if (zend_is_variable(arg) && !zend_ast_is_short_circuited(arg)) { + } else if (zend_is_passable_by_ref(arg) && !zend_ast_is_short_circuited(arg)) { if (fbc && arg_num != (uint32_t) -1) { if (ARG_SHOULD_BE_SENT_BY_REF(fbc, arg_num)) { - zend_compile_var(&arg_node, arg, BP_VAR_W, 1); + zend_compile_var(&arg_node, arg, BP_VAR_W, true); opcode = ZEND_SEND_REF; } else { - zend_compile_var(&arg_node, arg, BP_VAR_R, 0); + zend_compile_var(&arg_node, arg, BP_VAR_R, false); opcode = (arg_node.op_type == IS_TMP_VAR) ? ZEND_SEND_VAL : ZEND_SEND_VAR; } } else { @@ -3819,7 +6043,7 @@ static uint32_t zend_compile_args( opcode = ZEND_SEND_VAR_EX; CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS; break; - } else if (zend_try_compile_cv(&arg_node, arg) == SUCCESS) { + } else if (zend_try_compile_cv(&arg_node, arg, BP_VAR_R) == SUCCESS) { opcode = ZEND_SEND_VAR_EX; break; } @@ -3833,7 +6057,7 @@ static uint32_t zend_compile_args( } else { opline->op2.num = arg_num; } - zend_compile_var(&arg_node, arg, BP_VAR_FUNC_ARG, 1); + zend_compile_var(&arg_node, arg, BP_VAR_FUNC_ARG, true); opcode = ZEND_SEND_FUNC_ARG; } while (0); } @@ -3892,7 +6116,7 @@ static uint32_t zend_compile_args( } /* }}} */ -ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, zend_function *fbc, bool result_used) /* {{{ */ +ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, const zend_function *fbc, bool result_used) /* {{{ */ { uint32_t no_discard = result_used ? 0 : ZEND_ACC_NODISCARD; @@ -3925,36 +6149,62 @@ ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, zend_function *fbc, bo } /* }}} */ -static bool zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc, uint32_t lineno) /* {{{ */ +static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const zend_function *fbc, uint32_t lineno, uint32_t type, zend_ast *turbofish_ast, uint8_t verify_kind, const znode *new_result) /* {{{ */ { zend_op *opline; uint32_t opnum_init = get_next_op_number() - 1; + /* NEW emits VERIFY before args so the constructor RECVs see the + * monomorph's substituted arg_info; CALL emits it after args so inference + * from arg values can fill type-parameter slots. */ + if (verify_kind == ZEND_VERIFY_ARITY_KIND_NEW) { + zend_emit_verify_generic_arguments(turbofish_ast, verify_kind, new_result, fbc); + } + if (args_ast->kind == ZEND_AST_CALLABLE_CONVERT) { opline = &CG(active_op_array)->opcodes[opnum_init]; opline->extended_value = 0; + /* opcode array may be reallocated, so don't access opcode field after zend_emit_op_tmp(). */ + uint8_t opcode = opline->opcode; + + if (opcode == ZEND_NEW) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot create Closure for new expression"); + } - if (opline->opcode == ZEND_NEW) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot create Closure for new expression"); + zend_ast_list *args = zend_ast_get_list(((zend_ast_fcc*)args_ast)->args); + if (args->children != 1 || args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot create a Closure for call expression with more than one argument, or non-variadic placeholders"); } - if (opline->opcode == ZEND_INIT_FCALL) { + if (opcode == ZEND_INIT_FCALL) { opline->op1.num = zend_vm_calc_used_stack(0, fbc); } - zend_emit_op_tmp(result, ZEND_CALLABLE_CONVERT, NULL, NULL); + zend_op *callable_convert_op = zend_emit_op_tmp(result, ZEND_CALLABLE_CONVERT, NULL, NULL); + if (opcode == ZEND_INIT_FCALL + || opcode == ZEND_INIT_FCALL_BY_NAME + || opcode == ZEND_INIT_NS_FCALL_BY_NAME) { + callable_convert_op->extended_value = zend_alloc_cache_slot(); + } else { + callable_convert_op->extended_value = (uint32_t)-1; + } return true; } bool may_have_extra_named_args; uint32_t arg_count = zend_compile_args(args_ast, fbc, &may_have_extra_named_args); + if (verify_kind == ZEND_VERIFY_ARITY_KIND_CALL) { + zend_emit_verify_generic_arguments(turbofish_ast, verify_kind, new_result, fbc); + } + zend_do_extended_fcall_begin(); opline = &CG(active_op_array)->opcodes[opnum_init]; opline->extended_value = arg_count; + uint8_t init_opcode = opline->opcode; - if (opline->opcode == ZEND_INIT_FCALL) { + if (init_opcode == ZEND_INIT_FCALL) { opline->op1.num = zend_vm_calc_used_stack(arg_count, fbc); } @@ -3968,6 +6218,12 @@ static bool zend_compile_call_common(znode *result, zend_ast *args_ast, zend_fun false ); opline = zend_emit_op(result, call_op, NULL, NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (init_opcode != ZEND_NEW && opline->result_type == IS_VAR) { + opline->result_type = IS_TMP_VAR; + result->op_type = IS_TMP_VAR; + } + } if (may_have_extra_named_args) { opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; } @@ -3990,7 +6246,7 @@ static bool zend_compile_function_name(znode *name_node, zend_ast *name_ast) /* } /* }}} */ -static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast, uint32_t lineno) /* {{{ */ +static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast, zend_ast *turbofish_ast, uint32_t lineno, uint32_t type) /* {{{ */ { if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) { const char *colon; @@ -4020,24 +6276,24 @@ static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast zend_emit_op(NULL, ZEND_INIT_DYNAMIC_CALL, NULL, name_node); } - zend_compile_call_common(result, args_ast, NULL, lineno); + zend_compile_call_common(result, args_ast, NULL, lineno, type, turbofish_ast, ZEND_VERIFY_ARITY_KIND_CALL, NULL); } /* }}} */ -static inline bool zend_args_contain_unpack_or_named(zend_ast_list *args) /* {{{ */ +static inline bool zend_args_contain_unpack_or_named(const zend_ast_list *args) /* {{{ */ { uint32_t i; for (i = 0; i < args->children; ++i) { - zend_ast *arg = args->child[i]; + const zend_ast *arg = args->child[i]; if (arg->kind == ZEND_AST_UNPACK || arg->kind == ZEND_AST_NAMED_ARG) { - return 1; + return true; } } - return 0; + return false; } /* }}} */ -static zend_result zend_compile_func_strlen(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_strlen(znode *result, const zend_ast_list *args) /* {{{ */ { znode arg_node; @@ -4057,7 +6313,7 @@ static zend_result zend_compile_func_strlen(znode *result, zend_ast_list *args) } /* }}} */ -static zend_result zend_compile_func_typecheck(znode *result, zend_ast_list *args, uint32_t type) /* {{{ */ +static zend_result zend_compile_func_typecheck(znode *result, const zend_ast_list *args, uint32_t type) /* {{{ */ { znode arg_node; zend_op *opline; @@ -4077,7 +6333,7 @@ static zend_result zend_compile_func_typecheck(znode *result, zend_ast_list *arg } /* }}} */ -static zend_result zend_compile_func_is_scalar(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_is_scalar(znode *result, const zend_ast_list *args) /* {{{ */ { znode arg_node; zend_op *opline; @@ -4092,7 +6348,7 @@ static zend_result zend_compile_func_is_scalar(znode *result, zend_ast_list *arg return SUCCESS; } -static zend_result zend_compile_func_cast(znode *result, zend_ast_list *args, uint32_t type) /* {{{ */ +static zend_result zend_compile_func_cast(znode *result, const zend_ast_list *args, uint32_t type) /* {{{ */ { znode arg_node; zend_op *opline; @@ -4112,7 +6368,7 @@ static zend_result zend_compile_func_cast(znode *result, zend_ast_list *args, ui } /* }}} */ -static zend_result zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_defined(znode *result, const zend_ast_list *args) /* {{{ */ { zend_string *name; zend_op *opline; @@ -4127,7 +6383,7 @@ static zend_result zend_compile_func_defined(znode *result, zend_ast_list *args) return FAILURE; } - if (zend_try_ct_eval_const(&result->u.constant, name, 0)) { + if (zend_try_ct_eval_const(&result->u.constant, name, false)) { zend_string_release_ex(name, 0); zval_ptr_dtor(&result->u.constant); ZVAL_TRUE(&result->u.constant); @@ -4144,17 +6400,19 @@ static zend_result zend_compile_func_defined(znode *result, zend_ast_list *args) } /* }}} */ -static zend_result zend_compile_func_chr(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_chr(znode *result, const zend_ast_list *args) /* {{{ */ { - - if (args->children == 1 && - args->child[0]->kind == ZEND_AST_ZVAL && - Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_LONG) { - - zend_long c = Z_LVAL_P(zend_ast_get_zval(args->child[0])) & 0xff; - + zval *zint; + if ( + args->children == 1 + && args->child[0]->kind == ZEND_AST_ZVAL + && (zint = zend_ast_get_zval(args->child[0])) + && Z_TYPE_P(zint) == IS_LONG + && Z_LVAL_P(zint) >= 0 + && Z_LVAL_P(zint) <= 255 + ) { result->op_type = IS_CONST; - ZVAL_CHAR(&result->u.constant, c); + ZVAL_CHAR(&result->u.constant, Z_LVAL_P(zint)); return SUCCESS; } else { return FAILURE; @@ -4162,14 +6420,18 @@ static zend_result zend_compile_func_chr(znode *result, zend_ast_list *args) /* } /* }}} */ -static zend_result zend_compile_func_ord(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_ord(znode *result, const zend_ast_list *args) /* {{{ */ { - if (args->children == 1 && - args->child[0]->kind == ZEND_AST_ZVAL && - Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_STRING) { - + zval *str; + if ( + args->children == 1 + && args->child[0]->kind == ZEND_AST_ZVAL + && (str = zend_ast_get_zval(args->child[0])) + && Z_TYPE_P(str) == IS_STRING + && Z_STRLEN_P(str) == 1 + ) { result->op_type = IS_CONST; - ZVAL_LONG(&result->u.constant, (unsigned char)Z_STRVAL_P(zend_ast_get_zval(args->child[0]))[0]); + ZVAL_LONG(&result->u.constant, (unsigned char)Z_STRVAL_P(str)[0]); return SUCCESS; } else { return FAILURE; @@ -4180,11 +6442,11 @@ static zend_result zend_compile_func_ord(znode *result, zend_ast_list *args) /* /* We can only calculate the stack size for functions that have been fully compiled, otherwise * additional CV or TMP slots may still be added. This prevents the use of INIT_FCALL for * directly or indirectly recursive function calls. */ -static bool fbc_is_finalized(zend_function *fbc) { +static bool fbc_is_finalized(const zend_function *fbc) { return !ZEND_USER_CODE(fbc->type) || (fbc->common.fn_flags & ZEND_ACC_DONE_PASS_TWO); } -static bool zend_compile_ignore_class(zend_class_entry *ce, zend_string *filename) +static bool zend_compile_ignore_class(const zend_class_entry *ce, const zend_string *filename) { if (ce->type == ZEND_INTERNAL_CLASS) { return CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES; @@ -4194,7 +6456,7 @@ static bool zend_compile_ignore_class(zend_class_entry *ce, zend_string *filenam } } -static bool zend_compile_ignore_function(zend_function *fbc, zend_string *filename) +static bool zend_compile_ignore_function(const zend_function *fbc, const zend_string *filename) { if (fbc->type == ZEND_INTERNAL_FUNCTION) { return CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS; @@ -4256,7 +6518,7 @@ static void zend_compile_init_user_func(zend_ast *name_ast, uint32_t num_args, z /* }}} */ /* cufa = call_user_func_array */ -static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */ +static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, zend_string *lcname, uint32_t type) /* {{{ */ { znode arg_node; zend_op *opline; @@ -4291,7 +6553,11 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze zend_compile_expr(&len_node, list->child[2]); opline = zend_emit_op(NULL, ZEND_SEND_ARRAY, &arg_node, &len_node); opline->extended_value = Z_LVAL_P(zv); - zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL); + opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + opline->result_type = IS_TMP_VAR; + result->op_type = IS_TMP_VAR; + } zend_string_release_ex(name, 0); return SUCCESS; } @@ -4302,6 +6568,10 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze zend_emit_op(NULL, ZEND_SEND_ARRAY, &arg_node, NULL); zend_emit_op(NULL, ZEND_CHECK_UNDEF_ARGS, NULL, NULL); opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + opline->result_type = IS_TMP_VAR; + result->op_type = IS_TMP_VAR; + } opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; return SUCCESS; @@ -4309,7 +6579,7 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze /* }}} */ /* cuf = call_user_func */ -static zend_result zend_compile_func_cuf(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */ +static zend_result zend_compile_func_cuf(znode *result, const zend_ast_list *args, zend_string *lcname, uint32_t type) /* {{{ */ { uint32_t i; @@ -4329,13 +6599,17 @@ static zend_result zend_compile_func_cuf(znode *result, zend_ast_list *args, zen opline->op2.num = i; opline->result.var = EX_NUM_TO_VAR(i - 1); } - zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL); + zend_op *opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + opline->result_type = IS_TMP_VAR; + result->op_type = IS_TMP_VAR; + } return SUCCESS; } /* }}} */ -static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, zend_function *fbc, uint32_t lineno) /* {{{ */ +static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, const zend_function *fbc, uint32_t lineno, uint32_t type) /* {{{ */ { if (EG(assertions) >= 0) { znode name_node; @@ -4367,10 +6641,10 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string ZSTR_INIT_LITERAL("description", 0)); arg = zend_ast_create(ZEND_AST_NAMED_ARG, name, arg); } - zend_ast_list_add((zend_ast *) args, arg); + args = (zend_ast_list *)zend_ast_list_add((zend_ast *) args, arg); } - zend_compile_call_common(result, (zend_ast*)args, fbc, lineno); + zend_compile_call_common(result, (zend_ast*)args, fbc, lineno, type, NULL, ZEND_VERIFY_ARITY_KIND_CALL, NULL); opline = &CG(active_op_array)->opcodes[check_op_number]; opline->op2.opline_num = get_next_op_number(); @@ -4387,7 +6661,7 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string static zend_result zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{ */ { - bool strict = 0; + bool strict = false; znode array, needly; zend_op *opline; @@ -4422,7 +6696,7 @@ static zend_result zend_compile_func_in_array(znode *result, zend_ast_list *args } if (zend_hash_num_elements(Z_ARRVAL(array.u.constant)) > 0) { - bool ok = 1; + bool ok = true; zval *val, tmp; HashTable *src = Z_ARRVAL(array.u.constant); HashTable *dst = zend_new_array(zend_hash_num_elements(src)); @@ -4437,7 +6711,7 @@ static zend_result zend_compile_func_in_array(znode *result, zend_ast_list *args zend_hash_index_add(dst, Z_LVAL_P(val), &tmp); } else { zend_array_destroy(dst); - ok = 0; + ok = false; break; } } ZEND_HASH_FOREACH_END(); @@ -4446,7 +6720,7 @@ static zend_result zend_compile_func_in_array(znode *result, zend_ast_list *args if (Z_TYPE_P(val) != IS_STRING || is_numeric_string(Z_STRVAL_P(val), Z_STRLEN_P(val), NULL, NULL, 0)) { zend_array_destroy(dst); - ok = 0; + ok = false; break; } zend_hash_add(dst, Z_STR_P(val), &tmp); @@ -4470,7 +6744,7 @@ static zend_result zend_compile_func_in_array(znode *result, zend_ast_list *args } /* }}} */ -static zend_result zend_compile_func_count(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */ +static zend_result zend_compile_func_count(znode *result, const zend_ast_list *args, const zend_string *lcname) /* {{{ */ { znode arg_node; zend_op *opline; @@ -4487,7 +6761,7 @@ static zend_result zend_compile_func_count(znode *result, zend_ast_list *args, z } /* }}} */ -static zend_result zend_compile_func_get_class(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_get_class(znode *result, const zend_ast_list *args) /* {{{ */ { if (args->children == 0) { zend_emit_op_tmp(result, ZEND_GET_CLASS, NULL, NULL); @@ -4505,7 +6779,7 @@ static zend_result zend_compile_func_get_class(znode *result, zend_ast_list *arg } /* }}} */ -static zend_result zend_compile_func_get_called_class(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_get_called_class(znode *result, const zend_ast_list *args) /* {{{ */ { if (args->children != 0) { return FAILURE; @@ -4516,7 +6790,7 @@ static zend_result zend_compile_func_get_called_class(znode *result, zend_ast_li } /* }}} */ -static zend_result zend_compile_func_gettype(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_gettype(znode *result, const zend_ast_list *args) /* {{{ */ { znode arg_node; @@ -4530,7 +6804,7 @@ static zend_result zend_compile_func_gettype(znode *result, zend_ast_list *args) } /* }}} */ -static zend_result zend_compile_func_num_args(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_num_args(znode *result, const zend_ast_list *args) /* {{{ */ { if (CG(active_op_array)->function_name && args->children == 0) { zend_emit_op_tmp(result, ZEND_FUNC_NUM_ARGS, NULL, NULL); @@ -4541,7 +6815,7 @@ static zend_result zend_compile_func_num_args(znode *result, zend_ast_list *args } /* }}} */ -static zend_result zend_compile_func_get_args(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_get_args(znode *result, const zend_ast_list *args) /* {{{ */ { if (CG(active_op_array)->function_name && args->children == 0) { zend_emit_op_tmp(result, ZEND_FUNC_GET_ARGS, NULL, NULL); @@ -4552,7 +6826,7 @@ static zend_result zend_compile_func_get_args(znode *result, zend_ast_list *args } /* }}} */ -static zend_result zend_compile_func_array_key_exists(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_array_key_exists(znode *result, const zend_ast_list *args) /* {{{ */ { znode subject, needle; @@ -4568,7 +6842,7 @@ static zend_result zend_compile_func_array_key_exists(znode *result, zend_ast_li } /* }}} */ -static zend_result zend_compile_func_array_slice(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_array_slice(znode *result, const zend_ast_list *args) /* {{{ */ { if (CG(active_op_array)->function_name && args->children == 2 @@ -4581,8 +6855,8 @@ static zend_result zend_compile_func_array_slice(znode *result, zend_ast_list *a zend_string *orig_name = zend_ast_get_str(args->child[0]->child[0]); bool is_fully_qualified; zend_string *name = zend_resolve_function_name(orig_name, args->child[0]->child[0]->attr, &is_fully_qualified); - zend_ast_list *list = zend_ast_get_list(args->child[0]->child[1]); - zval *zv = zend_ast_get_zval(args->child[1]); + const zend_ast_list *list = zend_ast_get_list(args->child[0]->child[1]); + const zval *zv = zend_ast_get_zval(args->child[1]); znode first; if (zend_string_equals_literal_ci(name, "func_get_args") @@ -4601,7 +6875,7 @@ static zend_result zend_compile_func_array_slice(znode *result, zend_ast_list *a } /* }}} */ -static uint32_t find_frameless_function_offset(uint32_t arity, void *handler) +static uint32_t find_frameless_function_offset(uint32_t arity, const void *handler) { void **handlers = zend_flf_handlers; void **current = handlers; @@ -4615,16 +6889,12 @@ static uint32_t find_frameless_function_offset(uint32_t arity, void *handler) return (uint32_t)-1; } -static const zend_frameless_function_info *find_frameless_function_info(zend_ast_list *args, zend_function *fbc, uint32_t type) +static const zend_frameless_function_info *find_frameless_function_info(const zend_ast_list *args, const zend_function *fbc, uint32_t type) { if (zend_execute_internal) { return NULL; } - if (type != BP_VAR_R) { - return NULL; - } - if (ZEND_USER_CODE(fbc->type)) { return NULL; } @@ -4656,9 +6926,9 @@ static const zend_frameless_function_info *find_frameless_function_info(zend_ast return NULL; } -static uint32_t zend_compile_frameless_icall_ex(znode *result, zend_ast_list *args, zend_function *fbc, const zend_frameless_function_info *frameless_function_info, uint32_t type) +static uint32_t zend_compile_frameless_icall_ex(znode *result, const zend_ast_list *args, const zend_function *fbc, const zend_frameless_function_info *frameless_function_info, uint32_t type) { - int lineno = CG(zend_lineno); + uint32_t lineno = CG(zend_lineno); uint32_t num_args = frameless_function_info->num_args; uint32_t offset = find_frameless_function_offset(num_args, frameless_function_info->handler); znode arg_zvs[3]; @@ -4666,7 +6936,7 @@ static uint32_t zend_compile_frameless_icall_ex(znode *result, zend_ast_list *ar if (i < args->children) { zend_compile_expr(&arg_zvs[i], args->child[i]); } else { - zend_internal_arg_info *arg_info = (zend_internal_arg_info *)&fbc->common.arg_info[i]; + const zend_arg_info *arg_info = &fbc->common.arg_info[i]; arg_zvs[i].op_type = IS_CONST; if (zend_get_default_from_internal_arg_info(&arg_zvs[i].u.constant, arg_info) == FAILURE) { ZEND_UNREACHABLE(); @@ -4690,7 +6960,7 @@ static uint32_t zend_compile_frameless_icall_ex(znode *result, zend_ast_list *ar return opnum; } -static uint32_t zend_compile_frameless_icall(znode *result, zend_ast_list *args, zend_function *fbc, uint32_t type) +static uint32_t zend_compile_frameless_icall(znode *result, const zend_ast_list *args, const zend_function *fbc, uint32_t type) { const zend_frameless_function_info *frameless_function_info = find_frameless_function_info(args, fbc, type); if (!frameless_function_info) { @@ -4700,12 +6970,115 @@ static uint32_t zend_compile_frameless_icall(znode *result, zend_ast_list *args, return zend_compile_frameless_icall_ex(result, args, fbc, frameless_function_info, type); } -static void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast, uint32_t lineno, uint32_t type) /* {{{ */ +/* For a turbofish call with only concrete args, return the lowercased mangled + * monomorph name (`base`) used as the by-name dispatch key, or NULL to + * keep the runtime VERIFY path. */ +static zend_string *zend_build_concrete_turbofish_monomorph_name( + zend_string *base_name, zend_ast *turbofish_ast) +{ + if (!turbofish_ast) { + return NULL; + } + zend_ast_list *list = zend_ast_get_list(turbofish_ast); + uint32_t arity = list->children; + if (arity == 0 || arity > ZEND_GENERIC_MAX_PARAMS) { + return NULL; + } + + /* Bail on any T-ref or class-name arg: the mangled name is lowercased and the + * synthesize-by-name path reparses it, which would lose class-name case. Only + * case-insensitive scalar args round-trip losslessly. */ + zend_type args[ZEND_GENERIC_MAX_PARAMS]; + bool ok = true; + uint32_t built = 0; + for (uint32_t i = 0; i < arity; i++) { + args[i] = zend_compile_pre_erasure_typename(list->child[i]); + built++; + if (zend_type_contains_type_parameter(args[i]) + || ZEND_TYPE_HAS_NAME(args[i]) + || ZEND_TYPE_HAS_LITERAL_NAME(args[i]) + || ZEND_TYPE_HAS_NAMED_WITH_ARGS(args[i]) + || ZEND_TYPE_HAS_LIST(args[i])) { + ok = false; + break; + } + } + + zend_string *result = NULL; + if (ok) { + zend_string *canonical = + zend_generic_canonical_class_name(base_name, args, arity); + result = zend_string_tolower(canonical); + zend_string_release(canonical); + } + + for (uint32_t i = 0; i < built; i++) { + zend_type_release(args[i], /* persistent */ false); + } + return result; +} + +/* Emit the literal triple for an INIT_NS_FCALL_BY_NAME targeting the mangled + * monomorph name (mirrors zend_add_ns_func_name_literal). -1 when not concrete. */ +static int zend_add_ns_monomorph_name_literal(zend_string *full_name, zend_ast *turbofish_ast) +{ + zend_string *mangled_lc_full = + zend_build_concrete_turbofish_monomorph_name(full_name, turbofish_ast); + if (!mangled_lc_full) { + return -1; + } + + /* slot[0]: original-case mangled full name (only used in diagnostics). */ + zend_string *orig = zend_string_dup(mangled_lc_full, 0); + int ret = zend_add_literal_string(&orig); + + /* slot[1]: lowercased mangled full name (primary lookup key). */ + zend_string *lc_full = zend_string_copy(mangled_lc_full); + zend_add_literal_string(&lc_full); + + /* slot[2]: lowercased mangled unqualified name (global fallback key). */ + const char *uq; + size_t uq_len; + if (zend_get_unqualified_name(full_name, &uq, &uq_len)) { + zend_string *base_uq = zend_string_init(uq, uq_len, 0); + zend_string *mangled_lc_uq = + zend_build_concrete_turbofish_monomorph_name(base_uq, turbofish_ast); + zend_string_release(base_uq); + if (mangled_lc_uq) { + zend_add_literal_string(&mangled_lc_uq); + } else { + zend_string *dup = zend_string_copy(mangled_lc_full); + zend_add_literal_string(&dup); + } + } + + zend_string_release(mangled_lc_full); + return ret; +} + +static void zend_compile_ns_call(znode *result, const znode *name_node, zend_ast *args_ast, zend_ast *turbofish_ast, uint32_t lineno, uint32_t type) /* {{{ */ { + /* Concrete turbofish ns call -> by-name dispatch to the monomorph, no VERIFY. + * Skip callable-convert (Closure creation needs the base generic function). */ + if (turbofish_ast != NULL + && args_ast->kind != ZEND_AST_CALLABLE_CONVERT) { + int mono_constants = + zend_add_ns_monomorph_name_literal(Z_STR(name_node->u.constant), turbofish_ast); + if (mono_constants != -1) { + zend_op *opline = get_next_op(); + opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME; + opline->op2_type = IS_CONST; + opline->op2.constant = mono_constants; + opline->result.num = zend_alloc_cache_slot(); + zend_compile_call_common(result, args_ast, NULL, lineno, type, NULL, ZEND_VERIFY_ARITY_KIND_NONE, NULL); + return; + } + } + int name_constants = zend_add_ns_func_name_literal(Z_STR(name_node->u.constant)); /* Find frameless function with same name. */ - zend_function *frameless_function = NULL; + const zend_function *frameless_function = NULL; if (args_ast->kind != ZEND_AST_CALLABLE_CONVERT && !zend_args_contain_unpack_or_named(zend_ast_get_list(args_ast)) /* Avoid blowing up op count with nested frameless branches. */ @@ -4735,7 +7108,7 @@ static void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args opline->op2_type = IS_CONST; opline->op2.constant = name_constants; opline->result.num = zend_alloc_cache_slot(); - zend_compile_call_common(result, args_ast, NULL, lineno); + zend_compile_call_common(result, args_ast, NULL, lineno, type, turbofish_ast, ZEND_VERIFY_ARITY_KIND_CALL, NULL); /* Compile frameless call. */ if (frameless_function_info) { @@ -4896,7 +7269,7 @@ static zend_result zend_compile_func_sprintf(znode *result, zend_ast_list *args) case 'd': zend_emit_op_tmp(&elements[placeholder_count], ZEND_CAST, &elements[placeholder_count], NULL)->extended_value = IS_LONG; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } if (rope_elements == 0) { @@ -4930,7 +7303,182 @@ static zend_result zend_compile_func_sprintf(znode *result, zend_ast_list *args) return SUCCESS; } -static zend_result zend_try_compile_special_func_ex(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */ +static zend_result zend_compile_func_printf(znode *result, zend_ast_list *args) /* {{{ */ +{ + /* Special case: printf with a single constant string argument and no format specifiers. + * In this case, just emit ECHO and return the string length if needed. */ + if (args->children == 1) { + zend_eval_const_expr(&args->child[0]); + if (args->child[0]->kind != ZEND_AST_ZVAL) { + return FAILURE; + } + zval *format_string = zend_ast_get_zval(args->child[0]); + if (Z_TYPE_P(format_string) != IS_STRING) { + return FAILURE; + } + /* Check if there are any format specifiers */ + if (!memchr(Z_STRVAL_P(format_string), '%', Z_STRLEN_P(format_string))) { + /* No format specifiers - just emit ECHO and return string length */ + znode format_node; + zend_compile_expr(&format_node, args->child[0]); + zend_emit_op(NULL, ZEND_ECHO, &format_node, NULL); + + /* Return the string length as a constant if the result is used */ + result->op_type = IS_CONST; + ZVAL_LONG(&result->u.constant, Z_STRLEN_P(format_string)); + return SUCCESS; + } + } + + /* Fall back to sprintf optimization for format strings with specifiers */ + znode rope_result; + if (zend_compile_func_sprintf(&rope_result, args) != SUCCESS) { + return FAILURE; + } + + /* printf() returns the amount of bytes written, so just an ECHO of the + * resulting sprintf() optimisation might not be enough. At this early + * stage we can't detect if the result is actually used, so we just emit + * the opcodes and let them be cleaned up by the dead code elimination + * pass in the Zend Optimizer if the result of the printf() is in fact + * unused */ + znode copy; + if (rope_result.op_type != IS_CONST) { + /* Note: ZEND_COPY_TMP is only valid for TMPVAR. */ + ZEND_ASSERT(rope_result.op_type == IS_TMP_VAR); + zend_emit_op_tmp(©, ZEND_COPY_TMP, &rope_result, NULL); + zend_emit_op(NULL, ZEND_ECHO, &rope_result, NULL); + zend_emit_op_tmp(result, ZEND_STRLEN, ©, NULL); + } else { + zend_emit_op(NULL, ZEND_ECHO, &rope_result, NULL); + result->op_type = IS_CONST; + ZVAL_LONG(&result->u.constant, Z_STRLEN(rope_result.u.constant)); + } + + return SUCCESS; +} + +static zend_result zend_compile_func_clone(znode *result, const zend_ast_list *args) +{ + znode arg_node; + + if (args->children != 1) { + return FAILURE; + } + + zend_compile_expr(&arg_node, args->child[0]); + zend_emit_op_tmp(result, ZEND_CLONE, &arg_node, NULL); + + return SUCCESS; +} + +static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *args, zend_string *lcname, uint32_t lineno) /* {{{ */ +{ + /* Bail out if we do not have exactly two parameters. */ + if (args->children != 2) { + return FAILURE; + } + + zend_ast *callback = args->child[0]; + + /* Bail out if the callback is not a FCC/PFA. */ + zend_ast *args_ast; + switch (callback->kind) { + case ZEND_AST_CALL: + case ZEND_AST_STATIC_CALL: + args_ast = zend_ast_call_get_args(callback); + if (args_ast->kind != ZEND_AST_CALLABLE_CONVERT) { + return FAILURE; + } + + break; + default: + return FAILURE; + } + + /* Bail out if the callback is assert() due to the AST stringification logic + * breaking for the generated call. + */ + if (callback->kind == ZEND_AST_CALL + && callback->child[0]->kind == ZEND_AST_ZVAL + && Z_TYPE_P(zend_ast_get_zval(callback->child[0])) == IS_STRING + && zend_string_equals_literal_ci(zend_ast_get_str(callback->child[0]), "assert")) { + return FAILURE; + } + + zend_ast_list *callback_args = zend_ast_get_list(((zend_ast_fcc*)args_ast)->args); + if (callback_args->children != 1 || callback_args->child[0]->attr != ZEND_PLACEHOLDER_VARIADIC) { + /* Full PFA is not yet implemented, will fail in zend_compile_call_common(). */ + return FAILURE; + } + + znode value; + value.op_type = IS_TMP_VAR; + value.u.op.var = get_temporary_variable(); + zend_ast *call_args = zend_ast_create_list(1, ZEND_AST_ARG_LIST, zend_ast_create_znode(&value)); + + zend_op *opline; + + znode array; + zend_compile_expr(&array, args->child[1]); + /* array is an argument to both ZEND_TYPE_ASSERT and to ZEND_FE_RESET_R. */ + if (array.op_type == IS_CONST) { + Z_TRY_ADDREF(array.u.constant); + } + + /* Verify that the input array actually is an array. */ + znode name; + name.op_type = IS_CONST; + ZVAL_STR_COPY(&name.u.constant, lcname); + opline = zend_emit_op(NULL, ZEND_TYPE_ASSERT, &name, &array); + opline->lineno = lineno; + opline->extended_value = (2 << 16) | IS_ARRAY; + const zval *fbc_zv = zend_hash_find(CG(function_table), lcname); + const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val); + Z_EXTRA_P(CT_CONSTANT(opline->op1)) = fbc_bucket - CG(function_table)->arData; + + /* Initialize the result array. */ + zend_emit_op_tmp(result, ZEND_INIT_ARRAY, NULL, NULL); + + /* foreach loop starts here. */ + znode key; + + uint32_t opnum_reset = get_next_op_number(); + znode reset_node; + zend_emit_op(&reset_node, ZEND_FE_RESET_R, &array, NULL); + zend_begin_loop(ZEND_FE_FREE, &reset_node, false); + uint32_t opnum_fetch = get_next_op_number(); + zend_emit_op_tmp(&key, ZEND_FE_FETCH_R, &reset_node, &value); + + /* loop body */ + znode call_result; + switch (callback->kind) { + case ZEND_AST_CALL: + zend_compile_expr(&call_result, zend_ast_create(ZEND_AST_CALL, callback->child[0], call_args, NULL)); + break; + case ZEND_AST_STATIC_CALL: + zend_compile_expr(&call_result, zend_ast_create(ZEND_AST_STATIC_CALL, callback->child[0], callback->child[1], call_args, NULL)); + break; + } + opline = zend_emit_op(NULL, ZEND_ADD_ARRAY_ELEMENT, &call_result, &key); + SET_NODE(opline->result, result); + /* end loop body */ + + zend_emit_jump(opnum_fetch); + + uint32_t opnum_loop_end = get_next_op_number(); + opline = &CG(active_op_array)->opcodes[opnum_reset]; + opline->op2.opline_num = opnum_loop_end; + opline = &CG(active_op_array)->opcodes[opnum_fetch]; + opline->extended_value = opnum_loop_end; + + zend_end_loop(opnum_fetch, &reset_node); + zend_emit_op(NULL, ZEND_FE_FREE, &reset_node, NULL); + + return SUCCESS; +} + +static zend_result zend_try_compile_special_func_ex(znode *result, zend_string *lcname, zend_ast_list *args, uint32_t type, uint32_t lineno) /* {{{ */ { if (zend_string_equals_literal(lcname, "strlen")) { return zend_compile_func_strlen(result, args); @@ -4974,9 +7522,9 @@ static zend_result zend_try_compile_special_func_ex(znode *result, zend_string * } else if (zend_string_equals_literal(lcname, "ord") && type == BP_VAR_R) { return zend_compile_func_ord(result, args); } else if (zend_string_equals_literal(lcname, "call_user_func_array")) { - return zend_compile_func_cufa(result, args, lcname); + return zend_compile_func_cufa(result, args, lcname, type); } else if (zend_string_equals_literal(lcname, "call_user_func")) { - return zend_compile_func_cuf(result, args, lcname); + return zend_compile_func_cuf(result, args, lcname, type); } else if (zend_string_equals_literal(lcname, "in_array")) { return zend_compile_func_in_array(result, args); } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_COUNT)) @@ -4998,12 +7546,18 @@ static zend_result zend_try_compile_special_func_ex(znode *result, zend_string * return zend_compile_func_array_key_exists(result, args); } else if (zend_string_equals_literal(lcname, "sprintf")) { return zend_compile_func_sprintf(result, args); + } else if (zend_string_equals_literal(lcname, "printf")) { + return zend_compile_func_printf(result, args); + } else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_CLONE))) { + return zend_compile_func_clone(result, args); + } else if (zend_string_equals_literal(lcname, "array_map")) { + return zend_compile_func_array_map(result, args, lcname, lineno); } else { return FAILURE; } } -static zend_result zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */ +static zend_result zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, const zend_function *fbc, uint32_t type, uint32_t lineno) /* {{{ */ { if (CG(compiler_options) & ZEND_COMPILE_NO_BUILTINS) { return FAILURE; @@ -5019,7 +7573,7 @@ static zend_result zend_try_compile_special_func(znode *result, zend_string *lcn return FAILURE; } - if (zend_try_compile_special_func_ex(result, lcname, args, fbc, type) == SUCCESS) { + if (zend_try_compile_special_func_ex(result, lcname, args, type, lineno) == SUCCESS) { return SUCCESS; } @@ -5032,7 +7586,7 @@ static const char *zend_get_cstring_from_property_hook_kind(zend_property_hook_k return "get"; case ZEND_PROPERTY_HOOK_SET: return "set"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -5046,11 +7600,11 @@ static zend_string *zend_copy_unmangled_prop_name(zend_string *prop_name) } } -static bool zend_compile_parent_property_hook_call(znode *result, zend_ast *ast, uint32_t type) +static bool zend_compile_parent_property_hook_call(znode *result, const zend_ast *ast, uint32_t type) { ZEND_ASSERT(ast->kind == ZEND_AST_STATIC_CALL); - zend_ast *class_ast = ast->child[0]; + const zend_ast *class_ast = ast->child[0]; zend_ast *method_ast = ast->child[1]; /* Recognize parent::$prop::get() pattern. */ @@ -5105,52 +7659,51 @@ static bool zend_compile_parent_property_hook_call(znode *result, zend_ast *ast, opline->op1.constant = zend_add_literal_string(&property_name); opline->op2.num = hook_kind; - zend_function *fbc = NULL; - zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast)); + zend_compile_call_common(result, args_ast, NULL, zend_ast_get_lineno(method_ast), BP_VAR_R, NULL, ZEND_VERIFY_ARITY_KIND_CALL, NULL); return true; } -static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ +static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type) /* {{{ */ { zend_ast *name_ast = ast->child[0]; zend_ast *args_ast = ast->child[1]; + zend_ast *turbofish_ast = ast->child[2]; bool is_callable_convert = args_ast->kind == ZEND_AST_CALLABLE_CONVERT; znode name_node; if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) { zend_compile_expr(&name_node, name_ast); - zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno); + zend_compile_dynamic_call(result, &name_node, args_ast, turbofish_ast, ast->lineno, type); return; } { bool runtime_resolution = zend_compile_function_name(&name_node, name_ast); if (runtime_resolution) { - if (zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "assert") + if (turbofish_ast == NULL + && zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "assert") && !is_callable_convert) { - zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL, ast->lineno); + zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL, ast->lineno, type); } else { - zend_compile_ns_call(result, &name_node, args_ast, ast->lineno, type); + zend_compile_ns_call(result, &name_node, args_ast, turbofish_ast, ast->lineno, type); } return; } } { - zval *name = &name_node.u.constant; - zend_string *lcname; - zend_function *fbc; - zend_op *opline; - - lcname = zend_string_tolower(Z_STR_P(name)); + const zval *name = &name_node.u.constant; + zend_string *lcname = zend_string_tolower(Z_STR_P(name)); zval *fbc_zv = zend_hash_find(CG(function_table), lcname); - fbc = fbc_zv ? Z_PTR_P(fbc_zv) : NULL; + const zend_function *fbc = fbc_zv ? Z_PTR_P(fbc_zv) : NULL; + zend_op *opline; /* Special assert() handling should apply independently of compiler flags. */ - if (fbc && zend_string_equals_literal(lcname, "assert") && !is_callable_convert) { - zend_compile_assert(result, zend_ast_get_list(args_ast), lcname, fbc, ast->lineno); + if (turbofish_ast == NULL + && fbc && zend_string_equals_literal(lcname, "assert") && !is_callable_convert) { + zend_compile_assert(result, zend_ast_get_list(args_ast), lcname, fbc, ast->lineno, type); zend_string_release(lcname); zval_ptr_dtor(&name_node.u.constant); return; @@ -5160,13 +7713,36 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{ || !fbc_is_finalized(fbc) || zend_compile_ignore_function(fbc, CG(active_op_array)->filename)) { zend_string_release_ex(lcname, 0); - zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno); + zend_compile_dynamic_call(result, &name_node, args_ast, turbofish_ast, ast->lineno, type); return; } - if (!is_callable_convert && - zend_try_compile_special_func(result, lcname, - zend_ast_get_list(args_ast), fbc, type) == SUCCESS + /* Concrete turbofish call to a known generic function -> by-name dispatch + * to the monomorph (synthesized on first INIT_FCALL_BY_NAME miss), no VERIFY. */ + if (turbofish_ast != NULL + && !is_callable_convert + && ZEND_USER_CODE(fbc->common.type) + && fbc->op_array.generic_parameters) { + zend_string *mono_lc = + zend_build_concrete_turbofish_monomorph_name(lcname, turbofish_ast); + if (mono_lc) { + zend_string_release_ex(lcname, 0); + zval_ptr_dtor(&name_node.u.constant); + zend_op *bn_opline = get_next_op(); + bn_opline->opcode = ZEND_INIT_FCALL_BY_NAME; + bn_opline->op2_type = IS_CONST; + /* zend_add_func_name_literal consumes the reference. */ + bn_opline->op2.constant = zend_add_func_name_literal(mono_lc); + bn_opline->result.num = zend_alloc_cache_slot(); + zend_compile_call_common(result, args_ast, NULL, ast->lineno, type, NULL, ZEND_VERIFY_ARITY_KIND_NONE, NULL); + return; + } + } + + if (turbofish_ast == NULL + && !is_callable_convert + && zend_try_compile_special_func(result, lcname, + zend_ast_get_list(args_ast), fbc, type, ast->lineno) == SUCCESS ) { zend_string_release_ex(lcname, 0); zval_ptr_dtor(&name_node.u.constant); @@ -5174,18 +7750,18 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{ } zval_ptr_dtor(&name_node.u.constant); - ZVAL_NEW_STR(&name_node.u.constant, lcname); + ZVAL_STR(&name_node.u.constant, lcname); opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node); opline->result.num = zend_alloc_cache_slot(); /* Store offset to function from symbol table in op2.extra. */ if (fbc->type == ZEND_INTERNAL_FUNCTION) { - Bucket *fbc_bucket = (Bucket*)((uintptr_t)fbc_zv - XtOffsetOf(Bucket, val)); + const Bucket *fbc_bucket = ZEND_CONTAINER_OF(fbc_zv, Bucket, val); Z_EXTRA_P(CT_CONSTANT(opline->op2)) = fbc_bucket - CG(function_table)->arData; } - zend_compile_call_common(result, args_ast, fbc, ast->lineno); + zend_compile_call_common(result, args_ast, fbc, ast->lineno, type, turbofish_ast, ZEND_VERIFY_ARITY_KIND_CALL, NULL); } } /* }}} */ @@ -5195,10 +7771,11 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type zend_ast *obj_ast = ast->child[0]; zend_ast *method_ast = ast->child[1]; zend_ast *args_ast = ast->child[2]; + zend_ast *turbofish_ast = ast->child[3]; znode obj_node, method_node; zend_op *opline; - zend_function *fbc = NULL; + const zend_function *fbc = NULL; bool nullsafe = ast->kind == ZEND_AST_NULLSAFE_METHOD_CALL; uint32_t short_circuiting_checkpoint = zend_short_circuiting_checkpoint(); @@ -5206,7 +7783,7 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type if (this_guaranteed_exists()) { obj_node.op_type = IS_UNUSED; } else { - zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL); + zend_emit_op_tmp(&obj_node, ZEND_FETCH_THIS, NULL, NULL); } CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS; @@ -5249,7 +7826,7 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type } } - if (zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast))) { + if (zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast), type, turbofish_ast, ZEND_VERIFY_ARITY_KIND_CALL, NULL)) { if (short_circuiting_checkpoint != zend_short_circuiting_checkpoint()) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot combine nullsafe operator with Closure creation"); @@ -5258,23 +7835,33 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type } /* }}} */ -static bool zend_is_constructor(zend_string *name) /* {{{ */ +static bool zend_is_constructor(const zend_string *name) /* {{{ */ { return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME); } /* }}} */ -static zend_function *zend_get_compatible_func_or_null(zend_class_entry *ce, zend_string *lcname) /* {{{ */ +static bool is_func_accessible(const zend_function *fbc) { - zend_function *fbc = zend_hash_find_ptr(&ce->function_table, lcname); - if (!fbc || (fbc->common.fn_flags & ZEND_ACC_PUBLIC) || ce == CG(active_class_entry)) { - return fbc; + if ((fbc->common.fn_flags & ZEND_ACC_PUBLIC) || fbc->common.scope == CG(active_class_entry)) { + return true; } if (!(fbc->common.fn_flags & ZEND_ACC_PRIVATE) && (fbc->common.scope->ce_flags & ZEND_ACC_LINKED) && (!CG(active_class_entry) || (CG(active_class_entry)->ce_flags & ZEND_ACC_LINKED)) && zend_check_protected(zend_get_function_root_class(fbc), CG(active_class_entry))) { + return true; + } + + return false; +} + +static const zend_function *zend_get_compatible_func_or_null(const zend_class_entry *ce, zend_string *lcname) /* {{{ */ +{ + const zend_function *fbc = zend_hash_find_ptr(&ce->function_table, lcname); + + if (!fbc || is_func_accessible(fbc)) { return fbc; } @@ -5287,10 +7874,11 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type zend_ast *class_ast = ast->child[0]; zend_ast *method_ast = ast->child[1]; zend_ast *args_ast = ast->child[2]; + zend_ast *turbofish_ast = ast->child[3]; znode class_node, method_node; zend_op *opline; - zend_function *fbc = NULL; + const zend_function *fbc = NULL; if (zend_compile_parent_property_hook_call(result, ast, type)) { return; @@ -5354,51 +7942,213 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type } } - zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast)); + zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast), type, turbofish_ast, ZEND_VERIFY_ARITY_KIND_CALL, NULL); } /* }}} */ -static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel); +static void zend_compile_class_decl(znode *result, const zend_ast *ast, bool toplevel); static void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *class_ast = ast->child[0]; zend_ast *args_ast = ast->child[1]; + zend_ast *turbofish_ast = ast->child[2]; znode class_node, ctor_result; zend_op *opline; if (class_ast->kind == ZEND_AST_CLASS) { /* anon class declaration */ - zend_compile_class_decl(&class_node, class_ast, 0); + zend_compile_class_decl(&class_node, class_ast, false); } else { zend_compile_class_ref(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); } - opline = zend_emit_op(result, ZEND_NEW, NULL, NULL); + opline = zend_emit_op_tmp(result, ZEND_NEW, NULL, NULL); - if (class_node.op_type == IS_CONST) { - opline->op1_type = IS_CONST; - opline->op1.constant = zend_add_class_name_literal( - Z_STR(class_node.u.constant)); + zend_set_class_name_op1(opline, &class_node); + + if (opline->op1_type == IS_CONST) { opline->op2.num = zend_alloc_cache_slot(); - } else { - SET_NODE(opline->op1, &class_node); } - zend_compile_call_common(&ctor_result, args_ast, NULL, ast->lineno); - zend_do_free(&ctor_result); -} -/* }}} */ + zend_class_entry *ce = NULL; + /* If parent_extends_args is non-NULL, we resolved `new parent()` where the + * active class's extends clause specified type arguments — in that case we + * use the user-supplied args directly rather than the parent's defaults. */ + const zend_type *parent_extends_args = NULL; + if (opline->op1_type == IS_CONST) { + zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op1) + 1); + ce = zend_hash_find_ptr(CG(class_table), lcname); + if (ce) { + if (zend_compile_ignore_class(ce, CG(active_op_array)->filename)) { + ce = NULL; + } + } else if (CG(active_class_entry) + && zend_string_equals_ci(CG(active_class_entry)->name, lcname)) { + ce = CG(active_class_entry); + } + } else if (opline->op1_type == IS_UNUSED + && zend_is_scope_known()) { + uint32_t fetch = opline->op1.num & ZEND_FETCH_CLASS_MASK; + if (fetch == ZEND_FETCH_CLASS_SELF) { + ce = CG(active_class_entry); + } else if (fetch == ZEND_FETCH_CLASS_PARENT + && CG(active_class_entry) + && CG(active_class_entry)->parent_name) { + zend_string *lc_parent = zend_string_tolower(CG(active_class_entry)->parent_name); + ce = zend_hash_find_ptr(CG(class_table), lc_parent); + zend_string_release(lc_parent); + /* `new parent()` honours the active class's `extends Box` args + * if present, so it instantiates the same monomorph the active + * class extends rather than the parent's defaults. */ + if (ce && CG(active_class_entry)->generic_types + && CG(active_class_entry)->generic_types->extends + && ZEND_TYPE_HAS_NAMED_WITH_ARGS( + *CG(active_class_entry)->generic_types->extends) + && !zend_type_contains_type_parameter( + *CG(active_class_entry)->generic_types->extends)) { + parent_extends_args = CG(active_class_entry)->generic_types->extends; + } + } + } + + /* Reject turbofish on a known non-generic class at compile time so the + * error matches the type-position behavior (rather than waiting for + * VERIFY_GENERIC_ARGUMENTS to throw ArgumentCountError at runtime). */ + if (ce && !ce->generic_parameters && turbofish_ast) { + zend_ast_list *tf_list = zend_ast_get_list(turbofish_ast); + if (tf_list->children > 0) { + zend_error_noreturn(E_COMPILE_ERROR, + "Type arguments are not allowed on non-generic class %s", + ZSTR_VAL(ce->name)); + } + } + + /* Compile-time monomorph synthesis for `new GenericClass(...)`. Builds the + * canonical name, synthesizes the monomorph, and rewrites op1 to the + * canonical so ZEND_NEW creates the monomorph directly. When this fires + * we also drop the runtime ZEND_VERIFY_GENERIC_ARGUMENTS opcode (the + * arity + bound check is now redundant) and swap fbc to the monomorph's + * constructor so RECV checks against the substituted arg_info. + * + * Three sources for the type args, in priority order: + * - concrete turbofish `new C::(...)` — synthesize when every arg + * is concrete (no T-refs) and bound-checks pass at compile time. + * - `new parent()` inside `class X extends Foo` — borrow the args + * from the extends clause. + * - declared parameter defaults (naked `new GenericClass()`). + * + * `static` and dynamic names are handled at runtime in ZEND_NEW. */ + bool ct_synthesized = false; + zend_class_entry *mono_ce = NULL; + if (ce && ce->generic_parameters) { + uint32_t count = ce->generic_parameters->count; + const zend_type *src_args = NULL; + uint32_t src_arity = 0; + zend_type tf_args_buf[ZEND_GENERIC_MAX_PARAMS]; + uint32_t tf_args_built_arity = 0; + bool tf_concrete = false; + + if (turbofish_ast) { + zend_ast_list *tf_list = zend_ast_get_list(turbofish_ast); + if (tf_list->children > 0 && tf_list->children <= count) { + tf_concrete = true; + for (uint32_t i = 0; i < tf_list->children; i++) { + tf_args_buf[i] = zend_compile_pre_erasure_typename(tf_list->child[i]); + tf_args_built_arity = i + 1; + if (zend_type_contains_type_parameter(tf_args_buf[i])) { + tf_concrete = false; + } + } + if (tf_concrete) { + src_args = tf_args_buf; + src_arity = tf_list->children; + } + } + } else if (parent_extends_args) { + const zend_type_named_with_args *nwa = + ZEND_TYPE_NAMED_WITH_ARGS(*parent_extends_args); + src_args = nwa->args; + src_arity = nwa->count; + } + + bool attempt_synth = (src_args != NULL) || !turbofish_ast; + if (attempt_synth) { + zend_type chosen[ZEND_GENERIC_MAX_PARAMS]; + bool ok = true; + /* Strict (compile-error on missing defaults) when the naked call + * site refers to a generic class from outside that class. Lenient + * (fall through to the bare class / runtime VERIFY) when it's a + * lexical self-reference or when turbofish is present — the + * runtime can still throw a catchable ArgumentCountError. */ + bool is_lexical_self = ce == CG(active_class_entry); + for (uint32_t i = 0; i < count; i++) { + if (i < src_arity) { + chosen[i] = src_args[i]; + continue; + } + const zend_generic_parameter *p = &ce->generic_parameters->parameters[i]; + if (!ZEND_TYPE_IS_SET(p->default_type)) { + if (!is_lexical_self && !turbofish_ast) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot instantiate generic class %s without type arguments; " + "type parameter %s has no default", + ZSTR_VAL(ce->name), ZSTR_VAL(p->name)); + } + ok = false; + break; + } + chosen[i] = ZEND_TYPE_IS_SET(p->default_pre_erasure) + ? p->default_pre_erasure : p->default_type; + } + /* Concrete turbofish args must satisfy each parameter's bound at + * compile time before we elide the runtime check. UNRESOLVED (a + * referenced class not yet loaded) and ERROR both fall through to + * runtime VERIFY so the user gets a catchable TypeError. */ + if (ok && tf_concrete) { + for (uint32_t i = 0; i < src_arity; i++) { + zend_type bound = ce->generic_parameters->parameters[i].bound; + if (!ZEND_TYPE_IS_SET(bound)) continue; + if (zend_check_generic_arg_satisfies_bound(NULL, src_args[i], NULL, bound) + != INHERITANCE_SUCCESS) { + ok = false; + break; + } + } + } + if (ok) { + zend_string *canonical = + zend_generic_canonical_class_name(ce->name, chosen, count); + zend_try_compile_time_synthesize_monomorph(canonical); + zend_string *lc = zend_string_tolower(canonical); + mono_ce = zend_hash_find_ptr(CG(class_table), lc); + zend_string_release(lc); + opline->op1_type = IS_CONST; + opline->op1.constant = zend_add_class_name_literal(canonical); + opline->op2.num = zend_alloc_cache_slot(); + ct_synthesized = true; + } + } -static void zend_compile_clone(znode *result, zend_ast *ast) /* {{{ */ -{ - zend_ast *obj_ast = ast->child[0]; + for (uint32_t i = 0; i < tf_args_built_arity; i++) { + zend_type_release(tf_args_buf[i], /* persistent */ false); + } + } - znode obj_node; - zend_compile_expr(&obj_node, obj_ast); + const zend_function *fbc = NULL; + zend_class_entry *ctor_ce = mono_ce ? mono_ce : ce; + if (ctor_ce + && ctor_ce->default_object_handlers->get_constructor == zend_std_get_constructor + && ctor_ce->constructor + && is_func_accessible(ctor_ce->constructor)) { + fbc = ctor_ce->constructor; + } - zend_emit_op_tmp(result, ZEND_CLONE, &obj_node, NULL); + zend_compile_call_common(&ctor_result, args_ast, fbc, ast->lineno, BP_VAR_R, + ct_synthesized ? NULL : turbofish_ast, + ZEND_VERIFY_ARITY_KIND_NEW, result); + zend_do_free(&ctor_result); } /* }}} */ @@ -5417,7 +8167,7 @@ static void zend_compile_global_var(zend_ast *ast) /* {{{ */ // TODO(GLOBALS) Forbid "global $GLOBALS"? if (is_this_fetch(var_ast)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as global variable"); - } else if (zend_try_compile_cv(&result, var_ast) == SUCCESS) { + } else if (zend_try_compile_cv(&result, var_ast, BP_VAR_R) == SUCCESS) { zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node); opline->extended_value = zend_alloc_cache_slot(); } else { @@ -5516,7 +8266,7 @@ static void zend_compile_static_var(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_unset(zend_ast *ast) /* {{{ */ +static void zend_compile_unset(const zend_ast *ast) /* {{{ */ { zend_ast *var_ast = ast->child[0]; znode var_node; @@ -5543,10 +8293,10 @@ static void zend_compile_unset(zend_ast *ast) /* {{{ */ case ZEND_AST_VAR: if (is_this_fetch(var_ast)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot unset $this"); - } else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) { + } else if (zend_try_compile_cv(&var_node, var_ast, BP_VAR_UNSET) == SUCCESS) { opline = zend_emit_op(NULL, ZEND_UNSET_CV, &var_node, NULL); } else { - opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET, 0); + opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET, false); opline->opcode = ZEND_UNSET_VAR; } return; @@ -5556,25 +8306,25 @@ static void zend_compile_unset(zend_ast *ast) /* {{{ */ return; case ZEND_AST_PROP: case ZEND_AST_NULLSAFE_PROP: - opline = zend_compile_prop(NULL, var_ast, BP_VAR_UNSET, 0); + opline = zend_compile_prop(NULL, var_ast, BP_VAR_UNSET, false); opline->opcode = ZEND_UNSET_OBJ; return; case ZEND_AST_STATIC_PROP: - opline = zend_compile_static_prop(NULL, var_ast, BP_VAR_UNSET, 0, 0); + opline = zend_compile_static_prop(NULL, var_ast, BP_VAR_UNSET, false, false); opline->opcode = ZEND_UNSET_STATIC_PROP; return; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ static bool zend_handle_loops_and_finally_ex(zend_long depth, znode *return_value) /* {{{ */ { - zend_loop_var *base; + const zend_loop_var *base; zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack)); if (!loop_var) { - return 1; + return true; } base = zend_stack_base(&CG(loop_var_stack)); for (; loop_var >= base; loop_var--) { @@ -5625,11 +8375,11 @@ static bool zend_handle_loops_and_finally(znode *return_value) /* {{{ */ static bool zend_has_finally_ex(zend_long depth) /* {{{ */ { - zend_loop_var *base; + const zend_loop_var *base; zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack)); if (!loop_var) { - return 0; + return false; } base = zend_stack_base(&CG(loop_var_stack)); for (; loop_var >= base; loop_var--) { @@ -5645,7 +8395,7 @@ static bool zend_has_finally_ex(zend_long depth) /* {{{ */ depth--; } } - return 0; + return false; } /* }}} */ @@ -5655,7 +8405,7 @@ static bool zend_has_finally(void) /* {{{ */ } /* }}} */ -static void zend_compile_return(zend_ast *ast) /* {{{ */ +static void zend_compile_return(const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; bool is_generator = (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0; @@ -5666,15 +8416,15 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */ if (is_generator) { /* For generators the by-ref flag refers to yields, not returns */ - by_ref = 0; + by_ref = false; } if (!expr_ast) { expr_node.op_type = IS_CONST; ZVAL_NULL(&expr_node.u.constant); - } else if (by_ref && zend_is_variable(expr_ast)) { + } else if (by_ref && zend_is_variable_or_call(expr_ast)) { zend_assert_not_short_circuited(expr_ast); - zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1); + zend_compile_var(&expr_node, expr_ast, BP_VAR_W, true); } else { zend_compile_expr(&expr_node, expr_ast); } @@ -5693,11 +8443,23 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */ /* Generator return types are handled separately */ if (!is_generator && (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { zend_emit_return_type_check( - expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, 0); + expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, false); } + uint32_t opnum_before_finally = get_next_op_number(); + zend_handle_loops_and_finally((expr_node.op_type & (IS_TMP_VAR | IS_VAR)) ? &expr_node : NULL); + /* Content of reference might have changed in finally, repeat type check. */ + if (by_ref + /* Check if any opcodes were emitted since the last return type check. */ + && opnum_before_finally != get_next_op_number() + && !is_generator + && (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { + zend_emit_return_type_check( + expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, false); + } + opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN, &expr_node, NULL); @@ -5711,7 +8473,7 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_void_cast(znode *result, zend_ast *ast) +static void zend_compile_void_cast(znode *result, const zend_ast *ast) { zend_ast *expr_ast = ast->child[0]; znode expr_node; @@ -5731,7 +8493,7 @@ static void zend_compile_void_cast(znode *result, zend_ast *ast) } } -static void zend_compile_echo(zend_ast *ast) /* {{{ */ +static void zend_compile_echo(const zend_ast *ast) /* {{{ */ { zend_op *opline; zend_ast *expr_ast = ast->child[0]; @@ -5744,7 +8506,7 @@ static void zend_compile_echo(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_throw(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_throw(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; @@ -5761,7 +8523,7 @@ static void zend_compile_throw(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_break_continue(zend_ast *ast) /* {{{ */ +static void zend_compile_break_continue(const zend_ast *ast) /* {{{ */ { zend_ast *depth_ast = ast->child[0]; @@ -5771,7 +8533,7 @@ static void zend_compile_break_continue(zend_ast *ast) /* {{{ */ ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE); if (depth_ast) { - zval *depth_zv; + const zval *depth_zv; if (depth_ast->kind != ZEND_AST_ZVAL) { zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-integer operand " "is no longer supported", ast->kind == ZEND_AST_BREAK ? "break" : "continue"); @@ -5841,7 +8603,7 @@ static void zend_compile_break_continue(zend_ast *ast) /* {{{ */ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline) /* {{{ */ { zend_label *dest; - int current, remove_oplines = opline->op1.num; + int remove_oplines = opline->op1.num; zval *label; uint32_t opnum = opline - op_array->opcodes; @@ -5858,7 +8620,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline) /* {{{ */ zval_ptr_dtor_str(label); ZVAL_NULL(label); - current = opline->extended_value; + uint32_t current = opline->extended_value; for (; current != dest->brk_cont; current = CG(context).brk_cont_array[current].parent) { if (current == -1) { CG(in_compilation) = 1; @@ -5872,7 +8634,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline) /* {{{ */ } for (current = 0; current < op_array->last_try_catch; ++current) { - zend_try_catch_element *elem = &op_array->try_catch_array[current]; + const zend_try_catch_element *elem = &op_array->try_catch_array[current]; if (elem->try_op > opnum) { break; } @@ -5899,7 +8661,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline) /* {{{ */ } /* }}} */ -static void zend_compile_goto(zend_ast *ast) /* {{{ */ +static void zend_compile_goto(const zend_ast *ast) /* {{{ */ { zend_ast *label_ast = ast->child[0]; znode label_node; @@ -5916,7 +8678,7 @@ static void zend_compile_goto(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_label(zend_ast *ast) /* {{{ */ +static void zend_compile_label(const zend_ast *ast) /* {{{ */ { zend_string *label = zend_ast_get_str(ast->child[0]); zend_label dest; @@ -5935,7 +8697,7 @@ static void zend_compile_label(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_while(zend_ast *ast) /* {{{ */ +static void zend_compile_while(const zend_ast *ast) /* {{{ */ { zend_ast *cond_ast = ast->child[0]; zend_ast *stmt_ast = ast->child[1]; @@ -5944,7 +8706,7 @@ static void zend_compile_while(zend_ast *ast) /* {{{ */ opnum_jmp = zend_emit_jump(0); - zend_begin_loop(ZEND_NOP, NULL, 0); + zend_begin_loop(ZEND_NOP, NULL, false); opnum_start = get_next_op_number(); zend_compile_stmt(stmt_ast); @@ -5959,7 +8721,7 @@ static void zend_compile_while(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_do_while(zend_ast *ast) /* {{{ */ +static void zend_compile_do_while(const zend_ast *ast) /* {{{ */ { zend_ast *stmt_ast = ast->child[0]; zend_ast *cond_ast = ast->child[1]; @@ -5967,7 +8729,7 @@ static void zend_compile_do_while(zend_ast *ast) /* {{{ */ znode cond_node; uint32_t opnum_start, opnum_cond; - zend_begin_loop(ZEND_NOP, NULL, 0); + zend_begin_loop(ZEND_NOP, NULL, false); opnum_start = get_next_op_number(); zend_compile_stmt(stmt_ast); @@ -5983,7 +8745,7 @@ static void zend_compile_do_while(zend_ast *ast) /* {{{ */ static void zend_compile_for_expr_list(znode *result, zend_ast *ast) /* {{{ */ { - zend_ast_list *list; + const zend_ast_list *list; uint32_t i; result->op_type = IS_CONST; @@ -6009,7 +8771,7 @@ static void zend_compile_for_expr_list(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_for(zend_ast *ast) /* {{{ */ +static void zend_compile_for(const zend_ast *ast) /* {{{ */ { zend_ast *init_ast = ast->child[0]; zend_ast *cond_ast = ast->child[1]; @@ -6024,7 +8786,7 @@ static void zend_compile_for(zend_ast *ast) /* {{{ */ opnum_jmp = zend_emit_jump(0); - zend_begin_loop(ZEND_NOP, NULL, 0); + zend_begin_loop(ZEND_NOP, NULL, false); opnum_start = get_next_op_number(); zend_compile_stmt(stmt_ast); @@ -6035,7 +8797,7 @@ static void zend_compile_for(zend_ast *ast) /* {{{ */ zend_update_jump_target_to_next(opnum_jmp); zend_compile_for_expr_list(&result, cond_ast); - zend_do_extended_stmt(); + zend_do_extended_stmt(NULL); zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start); @@ -6050,7 +8812,8 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */ zend_ast *key_ast = ast->child[2]; zend_ast *stmt_ast = ast->child[3]; bool by_ref = value_ast->kind == ZEND_AST_REF; - bool is_variable = zend_is_variable(expr_ast) && zend_can_write_to_variable(expr_ast); + bool is_variable = (zend_is_variable(expr_ast) && zend_can_write_to_variable(expr_ast)) + || zend_is_call(expr_ast); znode expr_node, reset_node, value_node, key_node; zend_op *opline; @@ -6070,11 +8833,11 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */ } if (value_ast->kind == ZEND_AST_ARRAY && zend_propagate_list_refs(value_ast)) { - by_ref = 1; + by_ref = true; } if (by_ref && is_variable) { - zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1); + zend_compile_var(&expr_node, expr_ast, BP_VAR_W, true); } else { zend_compile_expr(&expr_node, expr_ast); } @@ -6085,8 +8848,12 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */ opnum_reset = get_next_op_number(); opline = zend_emit_op(&reset_node, by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R, &expr_node, NULL); + if (!by_ref) { + opline->result_type = IS_TMP_VAR; + reset_node.op_type = IS_TMP_VAR; + } - zend_begin_loop(ZEND_FE_FREE, &reset_node, 0); + zend_begin_loop(ZEND_FE_FREE, &reset_node, false); opnum_fetch = get_next_op_number(); opline = zend_emit_op(NULL, by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R, &reset_node, NULL); @@ -6094,14 +8861,14 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */ if (is_this_fetch(value_ast)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } else if (value_ast->kind == ZEND_AST_VAR && - zend_try_compile_cv(&value_node, value_ast) == SUCCESS) { + zend_try_compile_cv(&value_node, value_ast, BP_VAR_R) == SUCCESS) { SET_NODE(opline->op2, &value_node); } else { - opline->op2_type = IS_VAR; + opline->op2_type = by_ref ? IS_VAR : IS_TMP_VAR; opline->op2.var = get_temporary_variable(); GET_NODE(&value_node, opline->op2); if (value_ast->kind == ZEND_AST_ARRAY) { - zend_compile_list_assign(NULL, value_ast, &value_node, value_ast->attr); + zend_compile_list_assign(NULL, value_ast, &value_node, value_ast->attr, BP_VAR_R); } else if (by_ref) { zend_emit_assign_ref_znode(value_ast, &value_node); } else { @@ -6137,7 +8904,7 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */ static void zend_compile_if(zend_ast *ast) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; uint32_t *jmp_opnums = NULL; @@ -6146,7 +8913,7 @@ static void zend_compile_if(zend_ast *ast) /* {{{ */ } for (i = 0; i < list->children; ++i) { - zend_ast *elem_ast = list->child[i]; + const zend_ast *elem_ast = list->child[i]; zend_ast *cond_ast = elem_ast->child[0]; zend_ast *stmt_ast = elem_ast->child[1]; @@ -6156,7 +8923,7 @@ static void zend_compile_if(zend_ast *ast) /* {{{ */ if (i > 0) { CG(zend_lineno) = cond_ast->lineno; - zend_do_extended_stmt(); + zend_do_extended_stmt(NULL); } zend_compile_expr(&cond_node, cond_ast); @@ -6187,13 +8954,13 @@ static void zend_compile_if(zend_ast *ast) /* {{{ */ } /* }}} */ -static uint8_t determine_switch_jumptable_type(zend_ast_list *cases) { +static uint8_t determine_switch_jumptable_type(const zend_ast_list *cases) { uint32_t i; uint8_t common_type = IS_UNDEF; for (i = 0; i < cases->children; i++) { zend_ast *case_ast = cases->child[i]; zend_ast **cond_ast = &case_ast->child[0]; - zval *cond_zv; + const zval *cond_zv; if (!case_ast->child[0]) { /* Skip default clause */ continue; @@ -6228,9 +8995,9 @@ static uint8_t determine_switch_jumptable_type(zend_ast_list *cases) { return common_type; } -static bool should_use_jumptable(zend_ast_list *cases, uint8_t jumptable_type) { +static bool should_use_jumptable(const zend_ast_list *cases, uint8_t jumptable_type) { if (CG(compiler_options) & ZEND_COMPILE_NO_JUMPTABLES) { - return 0; + return false; } /* Thresholds are chosen based on when the average switch time for equidistributed @@ -6249,7 +9016,7 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ zend_ast_list *cases = zend_ast_get_list(ast->child[1]); uint32_t i; - bool has_default_case = 0; + bool has_default_case = false; znode expr_node, case_node; zend_op *opline; @@ -6259,7 +9026,7 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ zend_compile_expr(&expr_node, expr_ast); - zend_begin_loop(ZEND_FREE, &expr_node, 1); + zend_begin_loop(ZEND_FREE, &expr_node, true); case_node.op_type = IS_TMP_VAR; case_node.u.op.var = get_temporary_variable(); @@ -6288,13 +9055,18 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ zend_ast *cond_ast = case_ast->child[0]; znode cond_node; + if (case_ast->attr == ZEND_ALT_CASE_SYNTAX) { + CG(zend_lineno) = case_ast->lineno; + zend_error(E_DEPRECATED, "Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead"); + } + if (!cond_ast) { if (has_default_case) { CG(zend_lineno) = case_ast->lineno; zend_error_noreturn(E_COMPILE_ERROR, "Switch statements may only contain one default clause"); } - has_default_case = 1; + has_default_case = true; continue; } @@ -6377,26 +9149,26 @@ static void zend_compile_switch(zend_ast *ast) /* {{{ */ } /* }}} */ -static uint32_t count_match_conds(zend_ast_list *arms) +static uint32_t count_match_conds(const zend_ast_list *arms) { uint32_t num_conds = 0; for (uint32_t i = 0; i < arms->children; i++) { - zend_ast *arm_ast = arms->child[i]; + const zend_ast *arm_ast = arms->child[i]; if (arm_ast->child[0] == NULL) { continue; } - zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]); + const zend_ast_list *conds = zend_ast_get_list(arm_ast->child[0]); num_conds += conds->children; } return num_conds; } -static bool can_match_use_jumptable(zend_ast_list *arms) { +static bool can_match_use_jumptable(const zend_ast_list *arms) { for (uint32_t i = 0; i < arms->children; i++) { - zend_ast *arm_ast = arms->child[i]; + const zend_ast *arm_ast = arms->child[i]; if (!arm_ast->child[0]) { /* Skip default arm */ continue; @@ -6408,24 +9180,41 @@ static bool can_match_use_jumptable(zend_ast_list *arms) { zend_eval_const_expr(cond_ast); if ((*cond_ast)->kind != ZEND_AST_ZVAL) { - return 0; + return false; + } + + const zval *cond_zv = zend_ast_get_zval(*cond_ast); + if (Z_TYPE_P(cond_zv) != IS_LONG && Z_TYPE_P(cond_zv) != IS_STRING) { + return false; } + } + } + + return true; +} - zval *cond_zv = zend_ast_get_zval(*cond_ast); - if (Z_TYPE_P(cond_zv) != IS_LONG && Z_TYPE_P(cond_zv) != IS_STRING) { - return 0; - } - } +static bool zend_is_pipe_optimizable_callable_name(zend_ast *ast) +{ + if (ast->kind == ZEND_AST_ZVAL && Z_TYPE_P(zend_ast_get_zval(ast)) == IS_STRING) { + /* Assert compilation adds a message operand, but this is incompatible with the + * pipe optimization that uses a temporary znode for the reference elimination. + * Therefore, disable the optimization for assert. + * Note that "assert" as a name is always treated as fully qualified. */ + return !zend_string_equals_literal_ci(zend_ast_get_str(ast), "assert"); } - return 1; + return true; } -static void zend_compile_pipe(znode *result, zend_ast *ast) +static void zend_compile_pipe(znode *result, zend_ast *ast, uint32_t type) { zend_ast *operand_ast = ast->child[0]; zend_ast *callable_ast = ast->child[1]; + if (callable_ast->kind == ZEND_AST_ARROW_FUNC && !(callable_ast->attr & ZEND_PARENTHESIZED_ARROW_FUNC)) { + zend_error_noreturn(E_COMPILE_ERROR, "Arrow functions on the right hand side of |> must be parenthesized"); + } + /* Compile the left hand side down to a value first. */ znode operand_result; zend_compile_expr(&operand_result, operand_ast); @@ -6448,35 +9237,38 @@ static void zend_compile_pipe(znode *result, zend_ast *ast) /* Turn $foo |> bar(...) into bar($foo). */ if (callable_ast->kind == ZEND_AST_CALL - && callable_ast->child[1]->kind == ZEND_AST_CALLABLE_CONVERT) { + && callable_ast->child[1]->kind == ZEND_AST_CALLABLE_CONVERT + && zend_is_pipe_optimizable_callable_name(callable_ast->child[0])) { fcall_ast = zend_ast_create(ZEND_AST_CALL, - callable_ast->child[0], arg_list_ast); + callable_ast->child[0], arg_list_ast, NULL); /* Turn $foo |> bar::baz(...) into bar::baz($foo). */ } else if (callable_ast->kind == ZEND_AST_STATIC_CALL && callable_ast->child[2]->kind == ZEND_AST_CALLABLE_CONVERT) { fcall_ast = zend_ast_create(ZEND_AST_STATIC_CALL, - callable_ast->child[0], callable_ast->child[1], arg_list_ast); + callable_ast->child[0], callable_ast->child[1], arg_list_ast, NULL); /* Turn $foo |> $bar->baz(...) into $bar->baz($foo). */ } else if (callable_ast->kind == ZEND_AST_METHOD_CALL && callable_ast->child[2]->kind == ZEND_AST_CALLABLE_CONVERT) { fcall_ast = zend_ast_create(ZEND_AST_METHOD_CALL, - callable_ast->child[0], callable_ast->child[1], arg_list_ast); + callable_ast->child[0], callable_ast->child[1], arg_list_ast, NULL); /* Turn $foo |> $expr into ($expr)($foo) */ } else { zend_compile_expr(&callable_result, callable_ast); callable_ast = zend_ast_create_znode(&callable_result); fcall_ast = zend_ast_create(ZEND_AST_CALL, - callable_ast, arg_list_ast); + callable_ast, arg_list_ast, NULL); } - zend_compile_expr(result, fcall_ast); + zend_do_extended_stmt(&operand_result); + + zend_compile_var(result, fcall_ast, type, /* by_ref */ false); } static void zend_compile_match(znode *result, zend_ast *ast) { zend_ast *expr_ast = ast->child[0]; zend_ast_list *arms = zend_ast_get_list(ast->child[1]); - bool has_default_arm = 0; + bool has_default_arm = false; uint32_t opnum_match = (uint32_t)-1; znode expr_node; @@ -6501,7 +9293,7 @@ static void zend_compile_match(znode *result, zend_ast *ast) zend_error_noreturn(E_COMPILE_ERROR, "Match expressions may only contain one default arm"); } - has_default_arm = 1; + has_default_arm = true; } } @@ -6554,7 +9346,7 @@ static void zend_compile_match(znode *result, zend_ast *ast) opnum_default_jmp = zend_emit_jump(0); } - bool is_first_case = 1; + bool is_first_case = true; uint32_t cond_count = 0; uint32_t *jmp_end_opnums = safe_emalloc(sizeof(uint32_t), arms->children, 0); @@ -6626,7 +9418,7 @@ static void zend_compile_match(znode *result, zend_ast *ast) if (is_first_case) { zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &body_node, NULL); - is_first_case = 0; + is_first_case = false; } else { zend_op *opline_qm_assign = zend_emit_op(NULL, ZEND_QM_ASSIGN, &body_node, NULL); SET_NODE(opline_qm_assign->result, result); @@ -6658,10 +9450,10 @@ static void zend_compile_match(znode *result, zend_ast *ast) efree(jmp_end_opnums); } -static void zend_compile_try(zend_ast *ast) /* {{{ */ +static void zend_compile_try(const zend_ast *ast) /* {{{ */ { zend_ast *try_ast = ast->child[0]; - zend_ast_list *catches = zend_ast_get_list(ast->child[1]); + const zend_ast_list *catches = zend_ast_get_list(ast->child[1]); zend_ast *finally_ast = ast->child[2]; uint32_t i, j; @@ -6712,8 +9504,8 @@ static void zend_compile_try(zend_ast *ast) /* {{{ */ } for (i = 0; i < catches->children; ++i) { - zend_ast *catch_ast = catches->child[i]; - zend_ast_list *classes = zend_ast_get_list(catch_ast->child[0]); + const zend_ast *catch_ast = catches->child[i]; + const zend_ast_list *classes = zend_ast_get_list(catch_ast->child[0]); zend_ast *var_ast = catch_ast->child[1]; zend_ast *stmt_ast = catch_ast->child[2]; zend_string *var_name = var_ast ? zval_make_interned_string(zend_ast_get_zval(var_ast)) : NULL; @@ -6739,10 +9531,60 @@ static void zend_compile_try(zend_ast *ast) /* {{{ */ opline = get_next_op(); opline->opcode = ZEND_CATCH; - opline->op1_type = IS_CONST; - opline->op1.constant = zend_add_class_name_literal( - zend_resolve_class_name_ast(class_ast)); - opline->extended_value = zend_alloc_cache_slot(); + + /* catch (T $e): resolve T at exception-throw time via the runtime + * T-table. Encoded the same way as ZEND_FETCH_CLASS — see + * zend_resolve_generic_type_param. Allocate 3 cache slots for the + * polymorphic inline cache (see zend_vm_def.h ZEND_CATCH handler). */ + bool emitted_type_param = false; + if (class_ast->kind == ZEND_AST_ZVAL + && (class_ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + zend_generic_origin origin; + uint32_t param_index = 0; + zend_generic_parameter *param = zend_generic_lookup_full( + zend_ast_get_str(class_ast), &origin, ¶m_index); + if (param) { + opline->op1_type = IS_UNUSED; + opline->op1.num = zend_pack_type_param_fetch(param_index, 0, + origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE); + opline->extended_value = zend_alloc_cache_slots(3); + emitted_type_param = true; + } + } + if (!emitted_type_param) { + zend_string *resolved_name = NULL; + /* catch (Box): canonical monomorph name when args are + * concrete, matching the semantics of `instanceof Box`. + * catch (Box $e) with T-refs: stash the pre-erasure type and + * emit a deferred fetch; the runtime substitutes T against the + * current frame's bindings and resolves the monomorph. */ + if (class_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + zend_type ty = zend_compile_pre_erasure_typename(class_ast); + if (!zend_type_contains_type_parameter(ty)) { + resolved_name = zend_type_to_canonical_string(ty); + zend_try_compile_time_synthesize_monomorph(resolved_name); + zend_type_release(ty, /* persistent */ false); + } else { + zend_generic_type_table *table = + zend_generic_get_or_create_op_array_table(CG(active_op_array)); + uint32_t args_id = (table->turbofish_args + ? zend_hash_num_elements(table->turbofish_args) : 0) + 1; + zend_generic_type_table_set_turbofish_args(table, args_id, ty); + opline->op1_type = IS_UNUSED; + opline->op1.num = zend_pack_generic_deferred_fetch(args_id, 0); + opline->extended_value = zend_alloc_cache_slots(3); + emitted_type_param = true; + } + } + if (!emitted_type_param) { + if (!resolved_name) { + resolved_name = zend_resolve_class_name_ast(class_ast); + } + opline->op1_type = IS_CONST; + opline->op1.constant = zend_add_class_name_literal(resolved_name); + opline->extended_value = zend_alloc_cache_slot(); + } + } if (var_name && zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); @@ -6835,18 +9677,18 @@ static void zend_compile_try(zend_ast *ast) /* {{{ */ /* Encoding declarations must already be handled during parsing */ bool zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */ { - zend_ast_list *declares = zend_ast_get_list(ast); + const zend_ast_list *declares = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < declares->children; ++i) { - zend_ast *declare_ast = declares->child[i]; + const zend_ast *declare_ast = declares->child[i]; zend_ast *name_ast = declare_ast->child[0]; zend_ast *value_ast = declare_ast->child[1]; - zend_string *name = zend_ast_get_str(name_ast); + const zend_string *name = zend_ast_get_str(name_ast); if (zend_string_equals_literal_ci(name, "encoding")) { if (value_ast->kind != ZEND_AST_ZVAL) { zend_throw_exception(zend_ce_compile_error, "Encoding must be a literal", 0); - return 0; + return false; } if (CG(multibyte)) { @@ -6880,15 +9722,15 @@ bool zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */ } } - return 1; + return true; } /* }}} */ /* Check whether this is the first statement, not counting declares. */ -static zend_result zend_is_first_statement(zend_ast *ast, bool allow_nop) /* {{{ */ +static zend_result zend_is_first_statement(const zend_ast *ast, bool allow_nop) /* {{{ */ { uint32_t i = 0; - zend_ast_list *file_ast = zend_ast_get_list(CG(ast)); + const zend_ast_list *file_ast = zend_ast_get_list(CG(ast)); while (i < file_ast->children) { if (file_ast->child[i] == ast) { @@ -6906,9 +9748,9 @@ static zend_result zend_is_first_statement(zend_ast *ast, bool allow_nop) /* {{{ } /* }}} */ -static void zend_compile_declare(zend_ast *ast) /* {{{ */ +static void zend_compile_declare(const zend_ast *ast) /* {{{ */ { - zend_ast_list *declares = zend_ast_get_list(ast->child[0]); + const zend_ast_list *declares = zend_ast_get_list(ast->child[0]); zend_ast *stmt_ast = ast->child[1]; zend_declarables orig_declarables = FC(declarables); uint32_t i; @@ -6930,14 +9772,14 @@ static void zend_compile_declare(zend_ast *ast) /* {{{ */ zval_ptr_dtor_nogc(&value_zv); } else if (zend_string_equals_literal_ci(name, "encoding")) { - if (FAILURE == zend_is_first_statement(ast, /* allow_nop */ 0)) { + if (FAILURE == zend_is_first_statement(ast, /* allow_nop */ false)) { zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be " "the very first statement in the script"); } } else if (zend_string_equals_literal_ci(name, "strict_types")) { zval value_zv; - if (FAILURE == zend_is_first_statement(ast, /* allow_nop */ 0)) { + if (FAILURE == zend_is_first_statement(ast, /* allow_nop */ true)) { zend_error_noreturn(E_COMPILE_ERROR, "strict_types declaration must be " "the very first statement in the script"); } @@ -6972,7 +9814,7 @@ static void zend_compile_declare(zend_ast *ast) /* {{{ */ static void zend_compile_stmt_list(zend_ast *ast) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; ++i) { zend_compile_stmt(list->child[i]); @@ -7005,9 +9847,112 @@ ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */ } /* }}} */ +static zend_type_list *zend_arena_deep_copy_type_list(zend_type_list *src) +{ + size_t list_size = ZEND_TYPE_LIST_SIZE(src->num_types); + zend_type_list *copy = zend_arena_alloc(&CG(arena), list_size); + memcpy(copy, src, list_size); + for (uint32_t i = 0; i < copy->num_types; i++) { + if (ZEND_TYPE_HAS_LIST(copy->types[i])) { + ZEND_TYPE_SET_PTR(copy->types[i], zend_arena_deep_copy_type_list(ZEND_TYPE_LIST(copy->types[i]))); + } else if (ZEND_TYPE_HAS_NAME(copy->types[i])) { + zend_string_addref(ZEND_TYPE_NAME(copy->types[i])); + } + } + + return copy; +} + static zend_type zend_compile_single_typename(zend_ast *ast) { ZEND_ASSERT(!(ast->attr & ZEND_TYPE_NULLABLE)); + zend_reject_typearg_on_iterable(ast); + if (ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + /* For concrete args (no T-refs), rewrite the named type as the + * canonical monomorph class — so the runtime arg_info-driven RECV + * check enforces `Box` identity, not just bare `Box`. T-ref + * args (`Box`) can't be resolved here and fall back to the + * erased base; the pre-erasure side table still carries the shape + * for reflection and inference. `self`/`parent`/`static` keep + * their lexical-scope meaning and also fall through. + * + * Builtin pseudo-types (`int`, `string`, ...) cannot carry type + * arguments — those are caught by the validation in + * zend_compile_pre_erasure_typename / the non-generic-class check. */ + zend_ast *name_ast = ast->child[0]; + bool is_relative_scope = false; + if (name_ast->kind == ZEND_AST_TYPE) { + is_relative_scope = true; + } else if (name_ast->kind == ZEND_AST_ZVAL) { + const zval *zv = zend_ast_get_zval(name_ast); + if (Z_TYPE_P(zv) == IS_STRING + && zend_get_class_fetch_type(Z_STR_P(zv)) != ZEND_FETCH_CLASS_DEFAULT) { + is_relative_scope = true; + } + } + if (!is_relative_scope) { + zend_type pre_erasure = zend_compile_pre_erasure_typename(ast); + if (!zend_type_contains_type_parameter(pre_erasure)) { + zend_string *canonical = zend_type_to_canonical_string(pre_erasure); + zend_try_compile_time_synthesize_monomorph(canonical); + zend_type_release(pre_erasure, /* persistent */ false); + return (zend_type) ZEND_TYPE_INIT_CLASS(canonical, 0, 0); + } + zend_type_release(pre_erasure, /* persistent */ false); + } + ast = ast->child[0]; + } + /* Generic type parameter reference: erase to the parameter's bound (or `mixed` when unbounded). */ + { + zend_generic_origin origin = ZEND_GENERIC_ORIGIN_CLASS_LIKE; + zend_generic_parameter *param = NULL; + if (CG(generic_scope) && ast->kind == ZEND_AST_ZVAL + && (ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + const zval *zv = zend_ast_get_zval(ast); + if (Z_TYPE_P(zv) == IS_STRING) { + param = zend_generic_lookup_full(Z_STR_P(zv), &origin, NULL); + } + } + + if (param) { + if (origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE) { + zend_check_class_origin_in_static_context(param->name); + } + + for (zend_generic_scope_entry *e = CG(generic_scope); e; e = e->outer) { + if (e->self_compiling == param) { + zend_string *self = zend_string_copy(param->name); + zend_error_noreturn(E_COMPILE_ERROR, + "Type parameter %s cannot reference itself in its own bound or default outside of a generic type argument", + ZSTR_VAL(self)); + } + } + + if (ZEND_TYPE_IS_SET(param->bound)) { + zend_type result = param->bound; + if (ZEND_TYPE_HAS_NAME(result)) { + zend_string_addref(ZEND_TYPE_NAME(result)); + } else if (ZEND_TYPE_HAS_LIST(result)) { + ZEND_TYPE_SET_PTR(result, zend_arena_deep_copy_type_list(ZEND_TYPE_LIST(result))); + } + + return result; + } + + return (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY); + } + + if (ast->kind == ZEND_AST_ZVAL + && (ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + const zval *zv = zend_ast_get_zval(ast); + if (Z_TYPE_P(zv) == IS_STRING + && zend_generic_lookup_forward(Z_STR_P(zv)) >= 0) { + zend_error_noreturn(E_COMPILE_ERROR, + "Type parameter %s referenced before declaration", + Z_STRVAL_P(zv)); + } + } + } if (ast->kind == ZEND_AST_TYPE) { if (ast->attr == IS_STATIC && !CG(active_class_entry) && zend_is_scope_known()) { zend_error_noreturn(E_COMPILE_ERROR, @@ -7047,16 +9992,20 @@ static zend_type zend_compile_single_typename(zend_ast *ast) ZEND_ASSERT(fetch_type == ZEND_FETCH_CLASS_SELF || fetch_type == ZEND_FETCH_CLASS_PARENT); zend_ensure_valid_class_fetch_type(fetch_type); + + bool substitute_self_parent = zend_is_scope_known() + && !(CG(active_class_entry)->ce_flags & ZEND_ACC_ANON_CLASS); + if (fetch_type == ZEND_FETCH_CLASS_SELF) { /* Scope might be unknown for unbound closures and traits */ - if (zend_is_scope_known()) { + if (substitute_self_parent) { class_name = CG(active_class_entry)->name; ZEND_ASSERT(class_name && "must know class name when resolving self type at compile time"); } } else { ZEND_ASSERT(fetch_type == ZEND_FETCH_CLASS_PARENT); /* Scope might be unknown for unbound closures and traits */ - if (zend_is_scope_known()) { + if (substitute_self_parent) { class_name = CG(active_class_entry)->parent_name; ZEND_ASSERT(class_name && "must know class name when resolving parent type at compile time"); } @@ -7094,9 +10043,9 @@ static void zend_are_intersection_types_redundant(const zend_type left_type, con { ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(left_type)); ZEND_ASSERT(ZEND_TYPE_IS_INTERSECTION(right_type)); - zend_type_list *l_type_list = ZEND_TYPE_LIST(left_type); - zend_type_list *r_type_list = ZEND_TYPE_LIST(right_type); - zend_type_list *smaller_type_list, *larger_type_list; + const zend_type_list *l_type_list = ZEND_TYPE_LIST(left_type); + const zend_type_list *r_type_list = ZEND_TYPE_LIST(right_type); + const zend_type_list *smaller_type_list, *larger_type_list; bool flipped = false; if (r_type_list->num_types < l_type_list->num_types) { @@ -7110,15 +10059,15 @@ static void zend_are_intersection_types_redundant(const zend_type left_type, con unsigned int sum = 0; const zend_type *outer_type; - ZEND_TYPE_LIST_FOREACH(smaller_type_list, outer_type) + ZEND_TYPE_LIST_FOREACH(smaller_type_list, outer_type) { const zend_type *inner_type; - ZEND_TYPE_LIST_FOREACH(larger_type_list, inner_type) + ZEND_TYPE_LIST_FOREACH(larger_type_list, inner_type) { if (zend_string_equals_ci(ZEND_TYPE_NAME(*inner_type), ZEND_TYPE_NAME(*outer_type))) { sum++; break; } - ZEND_TYPE_LIST_FOREACH_END(); - ZEND_TYPE_LIST_FOREACH_END(); + } ZEND_TYPE_LIST_FOREACH_END(); + } ZEND_TYPE_LIST_FOREACH_END(); if (sum == smaller_type_list->num_types) { zend_string *smaller_type_str; @@ -7146,14 +10095,14 @@ static void zend_is_intersection_type_redundant_by_single_type(const zend_type i ZEND_ASSERT(!ZEND_TYPE_IS_INTERSECTION(single_type)); const zend_type *single_intersection_type = NULL; - ZEND_TYPE_FOREACH(intersection_type, single_intersection_type) + ZEND_TYPE_FOREACH(intersection_type, single_intersection_type) { if (zend_string_equals_ci(ZEND_TYPE_NAME(*single_intersection_type), ZEND_TYPE_NAME(single_type))) { zend_string *single_type_str = zend_type_to_string(single_type); zend_string *complete_type = zend_type_to_string(intersection_type); zend_error_noreturn(E_COMPILE_ERROR, "Type %s is redundant as it is more restrictive than type %s", ZSTR_VAL(complete_type), ZSTR_VAL(single_type_str)); } - ZEND_TYPE_FOREACH_END(); + } ZEND_TYPE_FOREACH_END(); } /* Used by both intersection and union types prior to transforming the type list to a full zend_type */ @@ -7178,6 +10127,7 @@ static zend_type zend_compile_typename_ex( zend_ast *ast, bool force_allow_null, bool *forced_allow_null) /* {{{ */ { bool is_marked_nullable = ast->attr & ZEND_TYPE_NULLABLE; + bool is_t_ref_erasure = false; zend_ast_attr orig_ast_attr = ast->attr; zend_type type = ZEND_TYPE_INIT_NONE(0); @@ -7186,10 +10136,11 @@ static zend_type zend_compile_typename_ex( } if (ast->kind == ZEND_AST_TYPE_UNION) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_type_list *type_list; bool is_composite = false; bool has_only_iterable_class = true; + bool collapse_union_to_mixed = false; ALLOCA_FLAG(use_heap) type_list = do_alloca(ZEND_TYPE_LIST_SIZE(list->children), use_heap); @@ -7235,6 +10186,16 @@ static zend_type zend_compile_typename_ex( uint32_t single_type_mask = ZEND_TYPE_PURE_MASK(single_type); if (single_type_mask == MAY_BE_ANY) { + zend_ast *check_ast = type_ast; + if (check_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + check_ast = check_ast->child[0]; + } + + if (zend_generic_lookup_name(check_ast) != NULL) { + collapse_union_to_mixed = true; + break; + } + zend_error_noreturn(E_COMPILE_ERROR, "Type mixed can only be used as a standalone type"); } if (ZEND_TYPE_IS_COMPLEX(single_type) && !ZEND_TYPE_IS_ITERABLE_FALLBACK(single_type)) { @@ -7281,28 +10242,33 @@ static zend_type zend_compile_typename_ex( } } - if (type_list->num_types) { - zend_type_list *list = zend_arena_alloc( - &CG(arena), ZEND_TYPE_LIST_SIZE(type_list->num_types)); - memcpy(list, type_list, ZEND_TYPE_LIST_SIZE(type_list->num_types)); - ZEND_TYPE_SET_LIST(type, list); - ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ARENA_BIT; - /* Inform that the type list is a union type */ - ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_UNION_BIT; - } + if (collapse_union_to_mixed) { + free_alloca(type_list, use_heap); + type = (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY); + } else { + if (type_list->num_types) { + zend_type_list *list = zend_arena_alloc( + &CG(arena), ZEND_TYPE_LIST_SIZE(type_list->num_types)); + memcpy(list, type_list, ZEND_TYPE_LIST_SIZE(type_list->num_types)); + ZEND_TYPE_SET_LIST(type, list); + ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ARENA_BIT; + /* Inform that the type list is a union type */ + ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_UNION_BIT; + } - free_alloca(type_list, use_heap); + free_alloca(type_list, use_heap); - uint32_t type_mask = ZEND_TYPE_FULL_MASK(type); - if ((type_mask & MAY_BE_OBJECT) && - ((!has_only_iterable_class && ZEND_TYPE_IS_COMPLEX(type)) || (type_mask & MAY_BE_STATIC))) { - zend_string *type_str = zend_type_to_string(type); - zend_error_noreturn(E_COMPILE_ERROR, - "Type %s contains both object and a class type, which is redundant", - ZSTR_VAL(type_str)); + uint32_t type_mask = ZEND_TYPE_FULL_MASK(type); + if ((type_mask & MAY_BE_OBJECT) && + ((!has_only_iterable_class && ZEND_TYPE_IS_COMPLEX(type)) || (type_mask & MAY_BE_STATIC))) { + zend_string *type_str = zend_type_to_string(type); + zend_error_noreturn(E_COMPILE_ERROR, + "Type %s contains both object and a class type, which is redundant", + ZSTR_VAL(type_str)); + } } } else if (ast->kind == ZEND_AST_TYPE_INTERSECTION) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_type_list *type_list; /* Allocate the type list directly on the arena as it must be a type @@ -7314,22 +10280,39 @@ static zend_type zend_compile_typename_ex( for (uint32_t i = 0; i < list->children; i++) { zend_ast *type_ast = list->child[i]; + zend_ast *check_ast = type_ast; + if (check_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + check_ast = check_ast->child[0]; + } + zend_generic_parameter *t_param = zend_generic_lookup_name(check_ast); zend_type single_type = zend_compile_single_typename(type_ast); /* An intersection of union types cannot exist so invalidate it * Currently only can happen with iterable getting canonicalized to Traversable|array */ if (ZEND_TYPE_IS_ITERABLE_FALLBACK(single_type)) { zend_string *standard_type_str = zend_type_to_string(single_type); + if (t_param) { + zend_error_noreturn(E_COMPILE_ERROR, + "Type parameter %s with bound %s cannot be part of an intersection type; " + "use an object-shaped bound (e.g. %s: object)", + ZSTR_VAL(t_param->name), ZSTR_VAL(standard_type_str), + ZSTR_VAL(t_param->name)); + } zend_error_noreturn(E_COMPILE_ERROR, "Type %s cannot be part of an intersection type", ZSTR_VAL(standard_type_str)); - zend_string_release_ex(standard_type_str, false); } /* An intersection of standard types cannot exist so invalidate it */ if (ZEND_TYPE_IS_ONLY_MASK(single_type)) { zend_string *standard_type_str = zend_type_to_string(single_type); + if (t_param) { + zend_error_noreturn(E_COMPILE_ERROR, + "Type parameter %s with bound %s cannot be part of an intersection type; " + "use an object-shaped bound (e.g. %s: object)", + ZSTR_VAL(t_param->name), ZSTR_VAL(standard_type_str), + ZSTR_VAL(t_param->name)); + } zend_error_noreturn(E_COMPILE_ERROR, "Type %s cannot be part of an intersection type", ZSTR_VAL(standard_type_str)); - zend_string_release_ex(standard_type_str, false); } /* Check for "self" and "parent" too */ if ( @@ -7370,17 +10353,31 @@ static zend_type zend_compile_typename_ex( ZEND_TYPE_FULL_MASK(type) |= _ZEND_TYPE_ARENA_BIT; } } else { + zend_ast *check_ast = ast; + if (check_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + check_ast = check_ast->child[0]; + } + + is_t_ref_erasure = (zend_generic_lookup_name(check_ast) != NULL); type = zend_compile_single_typename(ast); } uint32_t type_mask = ZEND_TYPE_PURE_MASK(type); if (type_mask == MAY_BE_ANY && is_marked_nullable) { - zend_error_noreturn(E_COMPILE_ERROR, "Type mixed cannot be marked as nullable since mixed already includes null"); + if (!is_t_ref_erasure) { + zend_error_noreturn(E_COMPILE_ERROR, "Type mixed cannot be marked as nullable since mixed already includes null"); + } + + is_marked_nullable = false; } if ((type_mask & MAY_BE_NULL) && is_marked_nullable) { - zend_error_noreturn(E_COMPILE_ERROR, "null cannot be marked as nullable"); + if (!is_t_ref_erasure) { + zend_error_noreturn(E_COMPILE_ERROR, "null cannot be marked as nullable"); + } + + is_marked_nullable = false; } if (force_allow_null && !is_marked_nullable && !(type_mask & MAY_BE_NULL)) { @@ -7416,14 +10413,14 @@ static bool zend_is_valid_default_value(zend_type type, zval *value) { ZEND_ASSERT(ZEND_TYPE_IS_SET(type)); if (ZEND_TYPE_CONTAINS_CODE(type, Z_TYPE_P(value))) { - return 1; + return true; } if ((ZEND_TYPE_FULL_MASK(type) & MAY_BE_DOUBLE) && Z_TYPE_P(value) == IS_LONG) { /* Integers are allowed as initializers for floating-point values. */ convert_to_double(value); - return 1; + return true; } - return 0; + return false; } static void zend_compile_attributes( @@ -7432,20 +10429,20 @@ static void zend_compile_attributes( zend_attribute *attr; zend_internal_attribute *config; - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t g, i, j; ZEND_ASSERT(ast->kind == ZEND_AST_ATTRIBUTE_LIST); for (g = 0; g < list->children; g++) { - zend_ast_list *group = zend_ast_get_list(list->child[g]); + const zend_ast_list *group = zend_ast_get_list(list->child[g]); ZEND_ASSERT(group->kind == ZEND_AST_ATTRIBUTE_GROUP); for (i = 0; i < group->children; i++) { ZEND_ASSERT(group->child[i]->kind == ZEND_AST_ATTRIBUTE); - zend_ast *el = group->child[i]; + const zend_ast *el = group->child[i]; if (el->child[1] && el->child[1]->kind == ZEND_AST_CALLABLE_CONVERT) { @@ -7472,13 +10469,19 @@ static void zend_compile_attributes( ? ZEND_ATTRIBUTE_STRICT_TYPES : 0; attr = zend_add_attribute( attributes, name, args ? args->children : 0, flags, offset, el->lineno); + attr->generic_arity = (uint8_t) el->attr; + if (el->child[2]) { + zend_type compiled = zend_compile_turbofish_args_type(el->child[2]); + attr->generic_args = emalloc(sizeof(zend_type)); + *attr->generic_args = compiled; + } zend_string_release(name); /* Populate arguments */ if (args) { ZEND_ASSERT(args->kind == ZEND_AST_ARG_LIST); - bool uses_named_args = 0; + bool uses_named_args = false; for (j = 0; j < args->children; j++) { zend_ast **arg_ast_ptr = &args->child[j]; zend_ast *arg_ast = *arg_ast_ptr; @@ -7491,7 +10494,7 @@ static void zend_compile_attributes( if (arg_ast->kind == ZEND_AST_NAMED_ARG) { attr->args[j].name = zend_string_copy(zend_ast_get_str(arg_ast->child[0])); arg_ast_ptr = &arg_ast->child[1]; - uses_named_args = 1; + uses_named_args = true; for (uint32_t k = 0; k < j; k++) { if (attr->args[k].name && @@ -7513,19 +10516,41 @@ static void zend_compile_attributes( } if (*attributes != NULL) { + /* Allow delaying target validation for forward compatibility. */ + const zend_attribute *delayed_target_validation = NULL; + if (target == ZEND_ATTRIBUTE_TARGET_PARAMETER) { + ZEND_ASSERT(offset >= 1); + /* zend_get_parameter_attribute_str will add 1 too */ + delayed_target_validation = zend_get_parameter_attribute_str( + *attributes, + "delayedtargetvalidation", + strlen("delayedtargetvalidation"), + offset - 1 + ); + } else { + delayed_target_validation = zend_get_attribute_str( + *attributes, + "delayedtargetvalidation", + strlen("delayedtargetvalidation") + ); + } /* Validate attributes in a secondary loop (needed to detect repeated attributes). */ ZEND_HASH_PACKED_FOREACH_PTR(*attributes, attr) { if (attr->offset != offset || NULL == (config = zend_internal_attribute_get(attr->lcname))) { continue; } + bool run_validator = true; if (!(target & (config->flags & ZEND_ATTRIBUTE_TARGET_ALL))) { - zend_string *location = zend_get_attribute_target_names(target); - zend_string *allowed = zend_get_attribute_target_names(config->flags); + if (delayed_target_validation == NULL) { + zend_string *location = zend_get_attribute_target_names(target); + zend_string *allowed = zend_get_attribute_target_names(config->flags); - zend_error_noreturn(E_ERROR, "Attribute \"%s\" cannot target %s (allowed targets: %s)", - ZSTR_VAL(attr->name), ZSTR_VAL(location), ZSTR_VAL(allowed) - ); + zend_error_noreturn(E_ERROR, "Attribute \"%s\" cannot target %s (allowed targets: %s)", + ZSTR_VAL(attr->name), ZSTR_VAL(location), ZSTR_VAL(allowed) + ); + } + run_validator = false; } if (!(config->flags & ZEND_ATTRIBUTE_IS_REPEATABLE)) { @@ -7534,8 +10559,16 @@ static void zend_compile_attributes( } } - if (config->validator != NULL) { - config->validator(attr, target, CG(active_class_entry)); + /* Validators are not run if the target is already invalid */ + if (run_validator && config->validator != NULL) { + zend_string *error = config->validator(attr, target, CG(active_class_entry)); + if (error != NULL) { + if (delayed_target_validation == NULL) { + zend_error_noreturn(E_COMPILE_ERROR, "%s", ZSTR_VAL(error)); + } else { + attr->validation_error = error; + } + } } } ZEND_HASH_FOREACH_END(); } @@ -7544,10 +10577,10 @@ static void zend_compile_attributes( static void zend_compile_property_hooks( zend_property_info *prop_info, zend_string *prop_name, - zend_ast *prop_type_ast, zend_ast_list *hooks); + zend_ast *prop_type_ast, const zend_ast_list *hooks); typedef struct { - zend_string *property_name; + const zend_string *property_name; bool uses_property; } find_property_usage_context; @@ -7559,14 +10592,14 @@ static void zend_property_hook_find_property_usage(zend_ast **ast_ptr, void *_co if (ast == NULL) { return; } else if (ast->kind == ZEND_AST_PROP || ast->kind == ZEND_AST_NULLSAFE_PROP) { - zend_ast *object_ast = ast->child[0]; + const zend_ast *object_ast = ast->child[0]; zend_ast *property_ast = ast->child[1]; if (object_ast->kind == ZEND_AST_VAR && object_ast->child[0]->kind == ZEND_AST_ZVAL && property_ast->kind == ZEND_AST_ZVAL) { - zval *object = zend_ast_get_zval(object_ast->child[0]); - zval *property = zend_ast_get_zval(property_ast); + const zval *object = zend_ast_get_zval(object_ast->child[0]); + const zval *property = zend_ast_get_zval(property_ast); if (Z_TYPE_P(object) == IS_STRING && Z_TYPE_P(property) == IS_STRING && zend_string_equals_literal(Z_STR_P(object), "this") @@ -7584,7 +10617,7 @@ static void zend_property_hook_find_property_usage(zend_ast **ast_ptr, void *_co } } -static bool zend_property_hook_uses_property(zend_string *property_name, zend_string *hook_name, zend_ast *hook_ast) +static bool zend_property_hook_uses_property(const zend_string *property_name, const zend_string *hook_name, zend_ast *hook_ast) { if (zend_string_equals_literal_ci(hook_name, "set") && hook_ast->kind == ZEND_AST_PROPERTY_HOOK_SHORT_BODY) { @@ -7596,7 +10629,7 @@ static bool zend_property_hook_uses_property(zend_string *property_name, zend_st return context.uses_property; } -static bool zend_property_is_virtual(zend_class_entry *ce, zend_string *property_name, zend_ast *hooks_ast, uint32_t flags) +static bool zend_property_is_virtual(const zend_class_entry *ce, const zend_string *property_name, zend_ast *hooks_ast) { if (ce->ce_flags & ZEND_ACC_INTERFACE) { return true; @@ -7607,9 +10640,9 @@ static bool zend_property_is_virtual(zend_class_entry *ce, zend_string *property bool is_virtual = true; - zend_ast_list *hooks = zend_ast_get_list(hooks_ast); + const zend_ast_list *hooks = zend_ast_get_list(hooks_ast); for (uint32_t i = 0; i < hooks->children; i++) { - zend_ast_decl *hook = (zend_ast_decl *) hooks->child[i]; + const zend_ast_decl *hook = (const zend_ast_decl *) hooks->child[i]; zend_ast *body = hook->child[2]; if (body && zend_property_hook_uses_property(property_name, hook->name, body)) { is_virtual = false; @@ -7634,9 +10667,15 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 arg_infos->type = zend_compile_typename(return_type_ast); ZEND_TYPE_FULL_MASK(arg_infos->type) |= _ZEND_ARG_INFO_FLAGS( (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0, /* is_tentative */ 0); + if (zend_type_ast_has_generic_content(return_type_ast)) { + zend_type pre = zend_compile_pre_erasure_typename(return_type_ast); + zend_generic_type_table_set_return( + zend_generic_get_or_create_op_array_table(op_array), pre); + } } else { arg_infos->type = (zend_type) ZEND_TYPE_INIT_CODE(fallback_return_type, 0, 0); } + arg_infos->doc_comment = NULL; arg_infos++; op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE; @@ -7664,6 +10703,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 } } + const uint32_t promotion_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY | ZEND_ACC_FINAL; for (i = 0; i < list->children; ++i) { zend_ast *param_ast = list->child[i]; zend_ast *type_ast = param_ast->child[0]; @@ -7675,9 +10715,11 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 zend_string *name = zval_make_interned_string(zend_ast_get_zval(var_ast)); bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0; - uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY | ZEND_ACC_FINAL); + uint32_t property_flags = param_ast->attr & promotion_flags; bool is_promoted = property_flags || hooks_ast; + CG(zend_lineno) = param_ast->lineno; + znode var_node, default_node; uint8_t opcode; zend_op *opline; @@ -7696,6 +10738,8 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 ZSTR_VAL(name)); } else if (zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS))) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as parameter"); + } else if (zend_string_equals_literal(name, "http_response_header")) { + CG(context).has_assigned_to_http_response_header = true; } if (op_array->fn_flags & ZEND_ACC_VARIADIC) { @@ -7729,6 +10773,8 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 arg_info = &arg_infos[i]; arg_info->name = zend_string_copy(name); arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0); + arg_info->default_value = NULL; + arg_info->doc_comment = doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL; if (attributes_ast) { zend_compile_attributes( @@ -7744,6 +10790,26 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS; arg_info->type = zend_compile_typename_ex(type_ast, force_nullable, &forced_allow_nullable); + if (zend_type_ast_has_generic_content(type_ast)) { + zend_type pre = zend_compile_pre_erasure_typename(type_ast); + if (force_nullable || forced_allow_nullable) { + ZEND_TYPE_FULL_MASK(pre) |= _ZEND_TYPE_NULLABLE_BIT; + } + zend_generic_type_table_set_parameter( + zend_generic_get_or_create_op_array_table(op_array), i, pre); + /* Track which generic params can be inferred from a value + * argument: only bare, non-nullable T at the top level. */ + if (ZEND_TYPE_HAS_TYPE_PARAMETER(pre) + && !(ZEND_TYPE_FULL_MASK(pre) & MAY_BE_NULL)) { + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(pre); + if (ref->origin == ZEND_GENERIC_ORIGIN_FUNCTION_LIKE + && ref->index < 64 + && op_array->generic_parameters) { + op_array->generic_parameters->inferable_mask |= + (uint64_t) 1 << ref->index; + } + } + } if (forced_allow_nullable) { zend_string *func_name = get_function_or_method_name((zend_function *) op_array); zend_error(E_DEPRECATED, @@ -7805,16 +10871,16 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 } if (is_promoted) { - zend_op_array *op_array = CG(active_op_array); - zend_class_entry *scope = op_array->scope; + const zend_op_array *active_op_array = CG(active_op_array); + zend_class_entry *scope = active_op_array->scope; bool is_ctor = - scope && zend_is_constructor(op_array->function_name); + scope && zend_is_constructor(active_op_array->function_name); if (!is_ctor) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare promoted property outside a constructor"); } - if ((op_array->fn_flags & ZEND_ACC_ABSTRACT) + if ((active_op_array->fn_flags & ZEND_ACC_ABSTRACT) || (scope->ce_flags & ZEND_ACC_INTERFACE)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare promoted property in an abstract constructor"); @@ -7842,6 +10908,11 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 zend_type type = ZEND_TYPE_INIT_NONE(0); if (type_ast) { type = zend_compile_typename(type_ast); + if (zend_type_ast_has_generic_content(type_ast)) { + zend_type pre = zend_compile_pre_erasure_typename(type_ast); + zend_generic_type_table_set_property( + zend_generic_get_or_create_class_table(scope), name, pre); + } } /* Don't give the property an explicit default value. For typed properties this means @@ -7866,15 +10937,20 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL; zend_property_info *prop = zend_declare_typed_property( scope, name, &default_value, - property_flags | (zend_property_is_virtual(scope, name, hooks_ast, property_flags) ? ZEND_ACC_VIRTUAL : 0) | ZEND_ACC_PROMOTED, + property_flags | (zend_property_is_virtual(scope, name, hooks_ast) ? ZEND_ACC_VIRTUAL : 0) | ZEND_ACC_PROMOTED, doc_comment, type); if (hooks_ast) { - zend_ast_list *hooks = zend_ast_get_list(hooks_ast); + const zend_ast_list *hooks = zend_ast_get_list(hooks_ast); zend_compile_property_hooks(prop, name, type_ast, hooks); } if (attributes_ast) { zend_compile_attributes( &prop->attributes, attributes_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, ZEND_ATTRIBUTE_TARGET_PARAMETER); + + zend_attribute *override_attribute = zend_get_attribute_str(prop->attributes, "override", sizeof("override")-1); + if (override_attribute) { + prop->flags |= ZEND_ACC_OVERRIDE; + } } } } @@ -7893,12 +10969,14 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 zend_ast *param_ast = list->child[i]; zend_ast *hooks_ast = param_ast->child[5]; bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; - uint32_t flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY); + uint32_t flags = param_ast->attr & promotion_flags; bool is_promoted = flags || hooks_ast; if (!is_promoted) { continue; } + CG(zend_lineno) = param_ast->lineno; + /* Emit $this->prop = $prop for promoted properties. */ zend_string *name = zend_ast_get_str(param_ast->child[1]); znode name_node, value_node; @@ -7917,7 +10995,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32 static void zend_compile_closure_binding(znode *closure, zend_op_array *op_array, zend_ast *uses_ast) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(uses_ast); + const zend_ast_list *list = zend_ast_get_list(uses_ast); uint32_t i; if (!list->children) { @@ -7965,6 +11043,8 @@ typedef struct { bool varvars_used; } closure_info; +static void find_implicit_binds(closure_info *info, zend_ast *params_ast, zend_ast *stmt_ast); + static void find_implicit_binds_recursively(closure_info *info, zend_ast *ast) { if (!ast) { return; @@ -7986,21 +11066,21 @@ static void find_implicit_binds_recursively(closure_info *info, zend_ast *ast) { zend_hash_add_empty_element(&info->uses, name); } else { - info->varvars_used = 1; + info->varvars_used = true; find_implicit_binds_recursively(info, name_ast); } } else if (zend_ast_is_list(ast)) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; i++) { find_implicit_binds_recursively(info, list->child[i]); } } else if (ast->kind == ZEND_AST_CLOSURE) { /* For normal closures add the use() list. */ - zend_ast_decl *closure_ast = (zend_ast_decl *) ast; + const zend_ast_decl *closure_ast = (const zend_ast_decl *) ast; zend_ast *uses_ast = closure_ast->child[1]; if (uses_ast) { - zend_ast_list *uses_list = zend_ast_get_list(uses_ast); + const zend_ast_list *uses_list = zend_ast_get_list(uses_ast); uint32_t i; for (i = 0; i < uses_list->children; i++) { zend_hash_add_empty_element(&info->uses, zend_ast_get_str(uses_list->child[i])); @@ -8008,8 +11088,16 @@ static void find_implicit_binds_recursively(closure_info *info, zend_ast *ast) { } } else if (ast->kind == ZEND_AST_ARROW_FUNC) { /* For arrow functions recursively check the expression. */ - zend_ast_decl *closure_ast = (zend_ast_decl *) ast; - find_implicit_binds_recursively(info, closure_ast->child[2]); + const zend_ast_decl *closure_ast = (const zend_ast_decl *) ast; + closure_info inner_info; + find_implicit_binds(&inner_info, closure_ast->child[0], closure_ast->child[2]); + if (inner_info.varvars_used) { + info->varvars_used = true; + } + if (zend_hash_num_elements(&inner_info.uses)) { + zend_hash_copy(&info->uses, &inner_info.uses, NULL); + } + zend_hash_destroy(&inner_info.uses); } else if (!zend_ast_is_special(ast)) { uint32_t i, children = zend_ast_get_num_children(ast); for (i = 0; i < children; i++) { @@ -8020,22 +11108,23 @@ static void find_implicit_binds_recursively(closure_info *info, zend_ast *ast) { static void find_implicit_binds(closure_info *info, zend_ast *params_ast, zend_ast *stmt_ast) { - zend_ast_list *param_list = zend_ast_get_list(params_ast); + const zend_ast_list *param_list = zend_ast_get_list(params_ast); uint32_t i; zend_hash_init(&info->uses, param_list->children, NULL, NULL, 0); + info->varvars_used = false; find_implicit_binds_recursively(info, stmt_ast); /* Remove variables that are parameters */ for (i = 0; i < param_list->children; i++) { - zend_ast *param_ast = param_list->child[i]; + const zend_ast *param_ast = param_list->child[i]; zend_hash_del(&info->uses, zend_ast_get_str(param_ast->child[1])); } } static void compile_implicit_lexical_binds( - closure_info *info, znode *closure, zend_op_array *op_array) + const closure_info *info, znode *closure, zend_op_array *op_array) { zend_string *var_name; zend_op *opline; @@ -8049,7 +11138,7 @@ static void compile_implicit_lexical_binds( op_array->static_variables = zend_new_array(8); } - ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) + ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) { zval *value = zend_hash_add( op_array->static_variables, var_name, &EG(uninitialized_zval)); uint32_t offset = (uint32_t)((char*)value - (char*)op_array->static_variables->arData); @@ -8058,13 +11147,13 @@ static void compile_implicit_lexical_binds( opline->op2_type = IS_CV; opline->op2.var = lookup_cv(var_name); opline->extended_value = offset | ZEND_BIND_IMPLICIT; - ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } static void zend_compile_closure_uses(zend_ast *ast) /* {{{ */ { - zend_op_array *op_array = CG(active_op_array); - zend_ast_list *list = zend_ast_get_list(ast); + const zend_op_array *op_array = CG(active_op_array); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; ++i) { @@ -8095,14 +11184,14 @@ static void zend_compile_closure_uses(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_implicit_closure_uses(closure_info *info) +static void zend_compile_implicit_closure_uses(const closure_info *info) { zend_string *var_name; - ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) + ZEND_HASH_MAP_FOREACH_STR_KEY(&info->uses, var_name) { zval zv; ZVAL_NULL(&zv); zend_compile_static_var_common(var_name, &zv, ZEND_BIND_IMPLICIT); - ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } static void add_stringable_interface(zend_class_entry *ce) { @@ -8220,7 +11309,7 @@ enum func_decl_level { FUNC_DECL_LEVEL_CONSTEXPR, }; -static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl, enum func_decl_level level) /* {{{ */ +static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array, const zend_ast_decl *decl, enum func_decl_level level) /* {{{ */ { zend_string *unqualified_name, *name, *lcname; zend_op *opline; @@ -8232,7 +11321,7 @@ static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_string *class = zend_empty_string; zend_string *separator = zend_empty_string; zend_string *function = filename; - char *parens = ""; + const char *parens = ""; if (CG(active_op_array) && CG(active_op_array)->function_name) { if (CG(active_op_array)->fn_flags & ZEND_ACC_CLOSURE) { @@ -8270,7 +11359,7 @@ static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array, lcname = zend_string_tolower(name); if (FC(imports_function)) { - zend_string *import_name = + const zend_string *import_name = zend_hash_find_ptr_lc(FC(imports_function), unqualified_name); if (import_name && !zend_string_equals_ci(lcname, import_name)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare function %s() (previously declared as local import)", @@ -8324,6 +11413,7 @@ static zend_op_array *zend_compile_func_decl_ex( zend_ast *uses_ast = decl->child[1]; zend_ast *stmt_ast = decl->child[2]; zend_ast *return_type_ast = decl->child[3]; + zend_ast *generic_params_ast = decl->child[5]; bool is_method = decl->kind == ZEND_AST_METHOD; zend_string *lcname = NULL; bool is_hook = decl->kind == ZEND_AST_PROPERTY_HOOK; @@ -8333,7 +11423,6 @@ static zend_op_array *zend_compile_func_decl_ex( zend_op_array *op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array)); zend_oparray_context orig_oparray_context; closure_info info; - memset(&info, 0, sizeof(closure_info)); init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE); @@ -8372,6 +11461,10 @@ static zend_op_array *zend_compile_func_decl_ex( CG(active_op_array) = op_array; + zend_oparray_context_begin(&orig_oparray_context, op_array); + CG(context).active_property_info_name = property_info_name; + CG(context).active_property_hook_kind = hook_kind; + if (decl->child[4]) { int target = ZEND_ATTRIBUTE_TARGET_FUNCTION; @@ -8381,7 +11474,7 @@ static zend_op_array *zend_compile_func_decl_ex( zend_compile_attributes(&op_array->attributes, decl->child[4], 0, target, 0); - zend_attribute *override_attribute = zend_get_attribute_str( + const zend_attribute *override_attribute = zend_get_attribute_str( op_array->attributes, "override", sizeof("override")-1 @@ -8391,7 +11484,7 @@ static zend_op_array *zend_compile_func_decl_ex( op_array->fn_flags |= ZEND_ACC_OVERRIDE; } - zend_attribute *deprecated_attribute = zend_get_attribute_str( + const zend_attribute *deprecated_attribute = zend_get_attribute_str( op_array->attributes, "deprecated", sizeof("deprecated")-1 @@ -8401,15 +11494,7 @@ static zend_op_array *zend_compile_func_decl_ex( op_array->fn_flags |= ZEND_ACC_DEPRECATED; } - zend_attribute *nodiscard_attribute = zend_get_attribute_str( - op_array->attributes, - "nodiscard", - sizeof("nodiscard")-1 - ); - - if (nodiscard_attribute) { - op_array->fn_flags |= ZEND_ACC_NODISCARD; - } + // ZEND_ACC_NODISCARD is added via an attribute validator } /* Do not leak the class scope into free standing functions, even if they are dynamically @@ -8423,10 +11508,6 @@ static zend_op_array *zend_compile_func_decl_ex( op_array->fn_flags |= ZEND_ACC_TOP_LEVEL; } - zend_oparray_context_begin(&orig_oparray_context, op_array); - CG(context).active_property_info_name = property_info_name; - CG(context).active_property_hook_kind = hook_kind; - { /* Push a separator to the loop variable stack */ zend_loop_var dummy_var; @@ -8435,8 +11516,23 @@ static zend_op_array *zend_compile_func_decl_ex( zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var); } + bool save_in_static_member_type = CG(in_static_member_type); + CG(in_static_member_type) = is_method && (op_array->fn_flags & ZEND_ACC_STATIC); + + /* Harvest function/method generic type parameters and push them into scope + * so that parameter, return, and body type annotations erase correctly. + * See GENERICS.md §6.9. */ + if (generic_params_ast) { + op_array->generic_parameters = zend_compile_generic_type_parameter_list(generic_params_ast, ZEND_GENERIC_ORIGIN_FUNCTION_LIKE); + zend_generic_scope_push(op_array->generic_parameters, ZEND_GENERIC_ORIGIN_FUNCTION_LIKE); + } + zend_compile_params(params_ast, return_type_ast, is_method && zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME) ? IS_STRING : 0); + + zend_check_function_variance_markers(op_array); + + CG(in_static_member_type) = save_in_static_member_type; if (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { zend_mark_function_as_generator(); zend_emit_op(NULL, ZEND_GENERATOR_CREATE, NULL, NULL); @@ -8451,7 +11547,7 @@ static zend_op_array *zend_compile_func_decl_ex( if (ast->kind == ZEND_AST_ARROW_FUNC && decl->child[2]->kind != ZEND_AST_RETURN) { bool needs_return = true; if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { - zend_arg_info *return_info = CG(active_op_array)->arg_info - 1; + const zend_arg_info *return_info = CG(active_op_array)->arg_info - 1; needs_return = !ZEND_TYPE_CONTAINS_CODE(return_info->type, IS_NEVER); } if (needs_return) { @@ -8461,12 +11557,15 @@ static zend_op_array *zend_compile_func_decl_ex( } if (op_array->fn_flags & ZEND_ACC_NODISCARD) { - if (is_hook) { - zend_error_noreturn(E_COMPILE_ERROR, "#[\\NoDiscard] is not supported for property hooks"); - } + /* ZEND_ACC_NODISCARD gets added by the attribute validator, but only + * if the method is not a hook; if it is a hook, then the validator + * will have returned an error message, even if the error message was + * delayed with #[\DelayedTargetValidation] that ZEND_ACC_NODISCARD + * flag should not have been added. */ + ZEND_ASSERT(!is_hook); if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { - zend_arg_info *return_info = CG(active_op_array)->arg_info - 1; + const zend_arg_info *return_info = CG(active_op_array)->arg_info - 1; if (ZEND_TYPE_CONTAINS_CODE(return_info->type, IS_VOID)) { zend_error_noreturn(E_COMPILE_ERROR, "A void %s does not return a value, but #[\\NoDiscard] requires a return value", @@ -8498,8 +11597,8 @@ static zend_op_array *zend_compile_func_decl_ex( /* put the implicit return on the really last line */ CG(zend_lineno) = decl->end_lineno; - zend_do_extended_stmt(); - zend_emit_final_return(0); + zend_do_extended_stmt(NULL); + zend_emit_final_return(false); pass_two(CG(active_op_array)); zend_oparray_context_end(&orig_oparray_context); @@ -8515,6 +11614,10 @@ static zend_op_array *zend_compile_func_decl_ex( zend_string_release_ex(lcname, 0); } + if (op_array->generic_parameters) { + zend_generic_scope_pop(); + } + CG(active_op_array) = orig_op_array; CG(active_class_entry) = orig_class_entry; @@ -8526,7 +11629,7 @@ static zend_op_array *zend_compile_func_decl(znode *result, zend_ast *ast, enum return zend_compile_func_decl_ex(result, ast, level, /* property_info */ NULL, (zend_property_hook_kind)-1); } -zend_property_hook_kind zend_get_property_hook_kind_from_name(zend_string *name) { +zend_property_hook_kind zend_get_property_hook_kind_from_name(const zend_string *name) { if (zend_string_equals_literal_ci(name, "get")) { return ZEND_PROPERTY_HOOK_GET; } else if (zend_string_equals_literal_ci(name, "set")) { @@ -8538,7 +11641,7 @@ zend_property_hook_kind zend_get_property_hook_kind_from_name(zend_string *name) static void zend_compile_property_hooks( zend_property_info *prop_info, zend_string *prop_name, - zend_ast *prop_type_ast, zend_ast_list *hooks) + zend_ast *prop_type_ast, const zend_ast_list *hooks) { zend_class_entry *ce = CG(active_class_entry); @@ -8622,12 +11725,12 @@ static void zend_compile_property_hooks( *return_type_ast_ptr = prop_type_ast; } else if (hook_kind == ZEND_PROPERTY_HOOK_SET) { if (hook->child[0]) { - zend_ast_list *param_list = zend_ast_get_list(hook->child[0]); + const zend_ast_list *param_list = zend_ast_get_list(hook->child[0]); if (param_list->children != 1) { zend_error_noreturn(E_COMPILE_ERROR, "%s hook of property %s::$%s must accept exactly one parameters", ZSTR_VAL(name), ZSTR_VAL(ce->name), ZSTR_VAL(prop_name)); } - zend_ast *value_param_ast = param_list->child[0]; + const zend_ast *value_param_ast = param_list->child[0]; if (value_param_ast->attr & ZEND_PARAM_REF) { zend_error_noreturn(E_COMPILE_ERROR, "Parameter $%s of %s hook %s::$%s must not be pass-by-reference", ZSTR_VAL(zend_ast_get_str(value_param_ast->child[1])), ZSTR_VAL(name), ZSTR_VAL(ce->name), ZSTR_VAL(prop_name)); @@ -8652,8 +11755,8 @@ static void zend_compile_property_hooks( value_type_ast_ptr = ¶m->child[0]; hook->child[0] = zend_ast_create_list(1, ZEND_AST_PARAM_LIST, param); } - zend_ast *return_type = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_VOID)); - return_type->attr = ZEND_NAME_NOT_FQ; + zend_ast *return_type = zend_ast_create(ZEND_AST_TYPE); + return_type->attr = IS_VOID; hook->child[3] = return_type; } else { ZEND_UNREACHABLE(); @@ -8718,7 +11821,7 @@ static void zend_compile_property_hooks( static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t flags, zend_ast *attr_ast) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_class_entry *ce = CG(active_class_entry); uint32_t i, children = list->children; @@ -8756,7 +11859,7 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f zend_string *doc_comment = NULL; zval value_zv; zend_type type = ZEND_TYPE_INIT_NONE(0); - flags |= zend_property_is_virtual(ce, name, hooks_ast, flags) ? ZEND_ACC_VIRTUAL : 0; + flags |= zend_property_is_virtual(ce, name, hooks_ast) ? ZEND_ACC_VIRTUAL : 0; zend_string *old_active_property_info_name = CG(context).active_property_info_name; CG(context).active_property_info_name = name; @@ -8776,8 +11879,19 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f } if (type_ast) { + bool save_in_static_member_type = CG(in_static_member_type); + if (flags & ZEND_ACC_STATIC) { + CG(in_static_member_type) = true; + } + type = zend_compile_typename(type_ast); + if (zend_type_ast_has_generic_content(type_ast)) { + zend_type pre = zend_compile_pre_erasure_typename(type_ast); + zend_generic_type_table_set_property( + zend_generic_get_or_create_class_table(ce), name, pre); + } + CG(in_static_member_type) = save_in_static_member_type; if (ZEND_TYPE_FULL_MASK(type) & (MAY_BE_VOID|MAY_BE_NEVER|MAY_BE_CALLABLE)) { zend_string *str = zend_type_to_string(type); zend_error_noreturn(E_COMPILE_ERROR, @@ -8852,6 +11966,11 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f if (attr_ast) { zend_compile_attributes(&info->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, 0); + + const zend_attribute *override_attribute = zend_get_attribute_str(info->attributes, "override", sizeof("override")-1); + if (override_attribute) { + info->flags |= ZEND_ACC_OVERRIDE; + } } CG(context).active_property_info_name = old_active_property_info_name; @@ -8859,7 +11978,7 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f } /* }}} */ -static void zend_compile_prop_group(zend_ast *ast) /* {{{ */ +static void zend_compile_prop_group(const zend_ast *ast) /* {{{ */ { zend_ast *type_ast = ast->child[0]; zend_ast *prop_ast = ast->child[1]; @@ -8881,7 +12000,7 @@ static void zend_check_trait_alias_modifiers(uint32_t attr) /* {{{ */ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_ast *attr_ast, zend_ast *type_ast) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_class_entry *ce = CG(active_class_entry); uint32_t i, children = list->children; @@ -8907,6 +12026,15 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as zend_error_noreturn(E_COMPILE_ERROR, "Class constant %s::%s cannot have type %s", ZSTR_VAL(ce->name), ZSTR_VAL(name), ZSTR_VAL(type_str)); } + + /* Capture the pre-erasure type when the declared type references a + * generic type parameter, so monomorph synthesis can substitute + * T → arg in the mono's class-constant type. */ + if (zend_type_ast_has_generic_content(type_ast)) { + zend_type pre = zend_compile_pre_erasure_typename(type_ast); + zend_generic_type_table_set_class_constant( + zend_generic_get_or_create_class_table(ce), name, pre); + } } if (UNEXPECTED((flags & ZEND_ACC_PRIVATE) && (flags & ZEND_ACC_FINAL))) { @@ -8930,7 +12058,7 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as if (attr_ast) { zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST, 0); - zend_attribute *deprecated = zend_get_attribute_str(c->attributes, "deprecated", sizeof("deprecated")-1); + const zend_attribute *deprecated = zend_get_attribute_str(c->attributes, "deprecated", sizeof("deprecated")-1); if (deprecated) { ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED; @@ -8943,7 +12071,7 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as } } -static void zend_compile_class_const_group(zend_ast *ast) /* {{{ */ +static void zend_compile_class_const_group(const zend_ast *ast) /* {{{ */ { zend_ast *const_ast = ast->child[0]; zend_ast *attr_ast = ast->child[1]; @@ -8953,7 +12081,7 @@ static void zend_compile_class_const_group(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_method_ref(zend_ast *ast, zend_trait_method_reference *method_ref) /* {{{ */ +static void zend_compile_method_ref(const zend_ast *ast, zend_trait_method_reference *method_ref) /* {{{ */ { zend_ast *class_ast = ast->child[0]; zend_ast *method_ast = ast->child[1]; @@ -8968,11 +12096,11 @@ static void zend_compile_method_ref(zend_ast *ast, zend_trait_method_reference * } /* }}} */ -static void zend_compile_trait_precedence(zend_ast *ast) /* {{{ */ +static void zend_compile_trait_precedence(const zend_ast *ast) /* {{{ */ { - zend_ast *method_ref_ast = ast->child[0]; + const zend_ast *method_ref_ast = ast->child[0]; zend_ast *insteadof_ast = ast->child[1]; - zend_ast_list *insteadof_list = zend_ast_get_list(insteadof_ast); + const zend_ast_list *insteadof_list = zend_ast_get_list(insteadof_ast); uint32_t i; zend_trait_precedence *precedence = emalloc(sizeof(zend_trait_precedence) + (insteadof_list->children - 1) * sizeof(zend_string*)); @@ -8989,9 +12117,9 @@ static void zend_compile_trait_precedence(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_trait_alias(zend_ast *ast) /* {{{ */ +static void zend_compile_trait_alias(const zend_ast *ast) /* {{{ */ { - zend_ast *method_ref_ast = ast->child[0]; + const zend_ast *method_ref_ast = ast->child[0]; zend_ast *alias_ast = ast->child[1]; uint32_t modifiers = ast->attr; @@ -9013,9 +12141,9 @@ static void zend_compile_trait_alias(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_use_trait(zend_ast *ast) /* {{{ */ +static void zend_compile_use_trait(const zend_ast *ast) /* {{{ */ { - zend_ast_list *traits = zend_ast_get_list(ast->child[0]); + const zend_ast_list *traits = zend_ast_get_list(ast->child[0]); zend_ast_list *adaptations = ast->child[1] ? zend_ast_get_list(ast->child[1]) : NULL; zend_class_entry *ce = CG(active_class_entry); uint32_t i; @@ -9026,15 +12154,24 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */ zend_ast *trait_ast = traits->child[i]; if (ce->ce_flags & ZEND_ACC_INTERFACE) { - zend_string *name = zend_ast_get_str(trait_ast); + zend_string *name = trait_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE + ? zend_ast_get_str(trait_ast->child[0]) + : zend_ast_get_str(trait_ast); zend_error_noreturn(E_COMPILE_ERROR, "Cannot use traits inside of interfaces. " "%s is used in %s", ZSTR_VAL(name), ZSTR_VAL(ce->name)); } - ce->trait_names[ce->num_traits].name = + uint32_t trait_index = ce->num_traits; + ce->trait_names[trait_index].name = zend_resolve_const_class_name_reference(trait_ast, "trait name"); - ce->trait_names[ce->num_traits].lc_name = zend_string_tolower(ce->trait_names[ce->num_traits].name); + ce->trait_names[trait_index].lc_name = zend_string_tolower(ce->trait_names[trait_index].name); ce->num_traits++; + + if (trait_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + zend_type pre = zend_compile_pre_erasure_typename(trait_ast); + zend_generic_type_table_set_trait_use( + zend_generic_get_or_create_class_table(ce), trait_index, pre); + } } if (!adaptations) { @@ -9042,7 +12179,7 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */ } for (i = 0; i < adaptations->children; ++i) { - zend_ast *adaptation_ast = adaptations->child[i]; + const zend_ast *adaptation_ast = adaptations->child[i]; switch (adaptation_ast->kind) { case ZEND_AST_TRAIT_PRECEDENCE: zend_compile_trait_precedence(adaptation_ast); @@ -9050,7 +12187,7 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */ case ZEND_AST_TRAIT_ALIAS: zend_compile_trait_alias(adaptation_ast); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } } @@ -9058,7 +12195,7 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */ static void zend_compile_implements(zend_ast *ast) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_class_entry *ce = CG(active_class_entry); zend_class_name *interface_names; uint32_t i; @@ -9070,6 +12207,12 @@ static void zend_compile_implements(zend_ast *ast) /* {{{ */ interface_names[i].name = zend_resolve_const_class_name_reference(class_ast, "interface name"); interface_names[i].lc_name = zend_string_tolower(interface_names[i].name); + + if (class_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + zend_type pre = zend_compile_pre_erasure_typename(class_ast); + zend_generic_type_table_set_implements( + zend_generic_get_or_create_class_table(ce), i, pre); + } } ce->num_interfaces = list->children; @@ -9077,7 +12220,7 @@ static void zend_compile_implements(zend_ast *ast) /* {{{ */ } /* }}} */ -static zend_string *zend_generate_anon_class_name(zend_ast_decl *decl) +static zend_string *zend_generate_anon_class_name(const zend_ast_decl *decl) { zend_string *filename = CG(active_op_array)->filename; uint32_t start_lineno = decl->start_lineno; @@ -9087,7 +12230,7 @@ static zend_string *zend_generate_anon_class_name(zend_ast_decl *decl) if (decl->child[0]) { prefix = zend_resolve_const_class_name_reference(decl->child[0], "class name"); } else if (decl->child[1]) { - zend_ast_list *list = zend_ast_get_list(decl->child[1]); + const zend_ast_list *list = zend_ast_get_list(decl->child[1]); prefix = zend_resolve_const_class_name_reference(list->child[0], "interface name"); } @@ -9117,9 +12260,9 @@ static void zend_compile_enum_backing_type(zend_class_entry *ce, zend_ast *enum_ zend_type_release(type, 0); } -static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) /* {{{ */ +static void zend_compile_class_decl(znode *result, const zend_ast *ast, bool toplevel) /* {{{ */ { - zend_ast_decl *decl = (zend_ast_decl *) ast; + const zend_ast_decl *decl = (const zend_ast_decl *) ast; zend_ast *extends_ast = decl->child[0]; zend_ast *implements_ast = decl->child[1]; zend_ast *stmt_ast = decl->child[2]; @@ -9160,6 +12303,20 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) } zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS); + + /* If a generic scope is active, this declaration shadows any generic + * type parameter with the same (case-insensitive) name. Register the + * unqualified lc_name in the innermost scope so subsequent lookups + * resolve to the class instead of the type parameter. */ + if (CG(generic_scope)) { + zend_string *unqualified_lc = zend_string_tolower(unqualified_name); + if (!CG(generic_scope)->shadowing_classes) { + ALLOC_HASHTABLE(CG(generic_scope)->shadowing_classes); + zend_hash_init(CG(generic_scope)->shadowing_classes, 4, NULL, NULL, 0); + } + zend_hash_add_empty_element(CG(generic_scope)->shadowing_classes, unqualified_lc); + zend_string_release(unqualified_lc); + } } else { /* Find an anon class name that is not in use yet. */ name = NULL; @@ -9175,7 +12332,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) ce->type = ZEND_USER_CLASS; ce->name = name; - zend_initialize_class_data(ce, 1); + zend_initialize_class_data(ce, true); if (!(decl->flags & ZEND_ACC_ANON_CLASS)) { zend_alloc_ce_cache(ce->name); } @@ -9200,9 +12357,36 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) ce->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE; } + if (decl->child[5]) { + ZEND_ASSERT(!(decl->flags & ZEND_ACC_ANON_CLASS)); + ce->generic_parameters = zend_compile_generic_type_parameter_list(decl->child[5], ZEND_GENERIC_ORIGIN_CLASS_LIKE); + zend_generic_scope_push(ce->generic_parameters, ZEND_GENERIC_ORIGIN_CLASS_LIKE); + bool all_defaults = true; + for (uint32_t i = 0; i < ce->generic_parameters->count; i++) { + if (!ZEND_TYPE_IS_SET(ce->generic_parameters->parameters[i].default_type)) { + all_defaults = false; + break; + } + } + if (all_defaults) { + ce->ce_flags |= ZEND_ACC_GENERIC_ALL_DEFAULTS; + } + } + if (extends_ast) { ce->parent_name = zend_resolve_const_class_name_reference(extends_ast, "class name"); + /* Capture the pre-erasure type when the extends clause specifies type + * arguments (e.g. `extends Box`). At link time + * (`zend_do_link_class`) this side-table entry triggers + * pre-synthesis of the `Box` monomorph and a rewrite of + * `parent_name` to the canonical name, so this class's direct + * parent is the monomorph and `instanceof Box` holds. */ + if (extends_ast->kind == ZEND_AST_GENERIC_NAMED_TYPE) { + zend_type pre = zend_compile_pre_erasure_typename(extends_ast); + zend_generic_type_table_set_extends( + zend_generic_get_or_create_class_table(ce), pre); + } } CG(active_class_entry) = ce; @@ -9232,6 +12416,12 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel) zend_verify_abstract_class(ce); } + zend_check_generic_variance_markers(ce); + + if (ce->generic_parameters) { + zend_generic_scope_pop(); + } + CG(active_class_entry) = original_ce; if (toplevel) { @@ -9350,6 +12540,11 @@ static void zend_compile_enum_case(zend_ast *ast) ZVAL_STR_COPY(&class_name_zval, enum_class_name); zend_ast *class_name_ast = zend_ast_create_zval(&class_name_zval); + zval case_id_zval; + int case_id = zend_enum_next_case_id(enum_class); + ZVAL_LONG(&case_id_zval, case_id); + zend_ast *case_id_ast = zend_ast_create_zval(&case_id_zval); + zval case_name_zval; ZVAL_STR_COPY(&case_name_zval, enum_case_name); zend_ast *case_name_ast = zend_ast_create_zval(&case_name_zval); @@ -9367,7 +12562,8 @@ static void zend_compile_enum_case(zend_ast *ast) ZSTR_VAL(enum_class_name)); } - zend_ast *const_enum_init_ast = zend_ast_create(ZEND_AST_CONST_ENUM_INIT, class_name_ast, case_name_ast, case_value_ast); + zend_ast *const_enum_init_ast = zend_ast_create(ZEND_AST_CONST_ENUM_INIT, + class_name_ast, case_id_ast, case_name_ast, case_value_ast); zval value_zv; zend_const_expr_to_zval(&value_zv, &const_enum_init_ast, /* allow_dynamic */ false); @@ -9416,7 +12612,7 @@ static HashTable *zend_get_import_ht(uint32_t type) /* {{{ */ zend_hash_init(FC(imports_const), 8, NULL, str_dtor, 0); } return FC(imports_const); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return NULL; @@ -9432,14 +12628,14 @@ static char *zend_get_use_type_str(uint32_t type) /* {{{ */ return " function"; case ZEND_SYMBOL_CONST: return " const"; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return " unknown"; } /* }}} */ -static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend_string *new_name, zend_string *check_name) /* {{{ */ +static void zend_check_already_in_use(uint32_t type, const zend_string *old_name, const zend_string *new_name, const zend_string *check_name) /* {{{ */ { if (zend_string_equals_ci(old_name, check_name)) { return; @@ -9452,7 +12648,7 @@ static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend static void zend_compile_use(zend_ast *ast) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; zend_string *current_ns = FC(current_namespace); uint32_t type = ast->attr; @@ -9460,7 +12656,7 @@ static void zend_compile_use(zend_ast *ast) /* {{{ */ bool case_sensitive = type == ZEND_SYMBOL_CONST; for (i = 0; i < list->children; ++i) { - zend_ast *use_ast = list->child[i]; + const zend_ast *use_ast = list->child[i]; zend_ast *old_name_ast = use_ast->child[0]; zend_ast *new_name_ast = use_ast->child[1]; zend_string *old_name = zend_ast_get_str(old_name_ast); @@ -9523,11 +12719,11 @@ static void zend_compile_use(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_group_use(zend_ast *ast) /* {{{ */ +static void zend_compile_group_use(const zend_ast *ast) /* {{{ */ { uint32_t i; - zend_string *ns = zend_ast_get_str(ast->child[0]); - zend_ast_list *list = zend_ast_get_list(ast->child[1]); + const zend_string *ns = zend_ast_get_str(ast->child[0]); + const zend_ast_list *list = zend_ast_get_list(ast->child[1]); for (i = 0; i < list->children; i++) { zend_ast *inline_use, *use = list->child[i]; @@ -9617,7 +12813,7 @@ static void zend_compile_const_decl(zend_ast *ast) /* {{{ */ } /* }}}*/ -static void zend_compile_namespace(zend_ast *ast) /* {{{ */ +static void zend_compile_namespace(const zend_ast *ast) /* {{{ */ { zend_ast *name_ast = ast->child[0]; zend_ast *stmt_ast = ast->child[1]; @@ -9645,7 +12841,7 @@ static void zend_compile_namespace(zend_ast *ast) /* {{{ */ bool is_first_namespace = (!with_bracket && !FC(current_namespace)) || (with_bracket && !FC(has_bracketed_namespaces)); - if (is_first_namespace && FAILURE == zend_is_first_statement(ast, /* allow_nop */ 1)) { + if (is_first_namespace && FAILURE == zend_is_first_statement(ast, /* allow_nop */ true)) { zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be " "the very first statement or after any declare call in the script"); } @@ -9680,12 +12876,11 @@ static void zend_compile_namespace(zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_halt_compiler(zend_ast *ast) /* {{{ */ +static void zend_compile_halt_compiler(const zend_ast *ast) /* {{{ */ { zend_ast *offset_ast = ast->child[0]; zend_long offset = Z_LVAL_P(zend_ast_get_zval(offset_ast)); - zend_string *filename, *name; const char const_name[] = "__COMPILER_HALT_OFFSET__"; if (FC(has_bracketed_namespaces) && FC(in_namespace)) { @@ -9693,19 +12888,23 @@ static void zend_compile_halt_compiler(zend_ast *ast) /* {{{ */ "__HALT_COMPILER() can only be used from the outermost scope"); } - filename = zend_get_compiled_filename(); - name = zend_mangle_property_name(const_name, sizeof(const_name) - 1, - ZSTR_VAL(filename), ZSTR_LEN(filename), 0); + const zend_string *filename = zend_get_compiled_filename(); + zend_string *name = zend_mangle_property_name(const_name, sizeof(const_name) - 1, + ZSTR_VAL(filename), ZSTR_LEN(filename), false); - zend_register_long_constant(ZSTR_VAL(name), ZSTR_LEN(name), offset, 0, 0); + /* Avoid repeated declaration of the __COMPILER_HALT_OFFSET__ constant in + * case this file was already included. */ + if (!zend_hash_find(EG(zend_constants), name)) { + zend_register_long_constant(ZSTR_VAL(name), ZSTR_LEN(name), offset, 0, 0); + } zend_string_release_ex(name, 0); } /* }}} */ -static bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */ +static bool zend_try_ct_eval_magic_const(zval *zv, const zend_ast *ast) /* {{{ */ { - zend_op_array *op_array = CG(active_op_array); - zend_class_entry *ce = CG(active_class_entry); + const zend_op_array *op_array = CG(active_op_array); + const zend_class_entry *ce = CG(active_class_entry); switch (ast->attr) { case T_LINE: @@ -9716,7 +12915,7 @@ static bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */ break; case T_DIR: { - zend_string *filename = CG(compiled_filename); + const zend_string *filename = CG(compiled_filename); zend_string *dirname = zend_string_init(ZSTR_VAL(filename), ZSTR_LEN(filename), 0); #ifdef ZEND_WIN32 ZSTR_LEN(dirname) = php_win32_ioutil_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname)); @@ -9795,10 +12994,10 @@ static bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */ ZVAL_EMPTY_STRING(zv); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } - return 1; + return true; } /* }}} */ @@ -9809,14 +13008,14 @@ ZEND_API bool zend_is_op_long_compatible(const zval *op) } if (Z_TYPE_P(op) == IS_DOUBLE - && !zend_is_long_compatible(Z_DVAL_P(op), zend_dval_to_lval(Z_DVAL_P(op)))) { + && !zend_is_long_compatible(Z_DVAL_P(op), zend_dval_to_lval_silent(Z_DVAL_P(op)))) { return false; } if (Z_TYPE_P(op) == IS_STRING) { double dval = 0; uint8_t is_num = is_numeric_str_function(Z_STR_P(op), NULL, &dval); - if (is_num == 0 || (is_num == IS_DOUBLE && !zend_is_long_compatible(dval, zend_dval_to_lval(dval)))) { + if (is_num == 0 || (is_num == IS_DOUBLE && !zend_is_long_compatible(dval, zend_dval_to_lval_silent(dval)))) { return false; } } @@ -9865,11 +13064,27 @@ ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, const zval *op1, co return 1; } - if ((opcode == ZEND_MOD && zval_get_long(op2) == 0) - || (opcode == ZEND_DIV && zval_get_double(op2) == 0.0)) { + /* Operation which cast float/float-strings to integers might produce incompatible float to int errors */ + if (opcode == ZEND_SL || opcode == ZEND_SR || opcode == ZEND_BW_OR + || opcode == ZEND_BW_AND || opcode == ZEND_BW_XOR) { + if (!zend_is_op_long_compatible(op1) || !zend_is_op_long_compatible(op2)) { + return 1; + } + } + + if (opcode == ZEND_DIV && zval_get_double(op2) == 0.0) { /* Division by zero throws an error. */ return 1; } + + /* Mod is an operation that will cast float/float-strings to integers which might + produce float to int incompatible errors, and also cannot be divided by 0 */ + if (opcode == ZEND_MOD) { + if (!zend_is_op_long_compatible(op1) || !zend_is_op_long_compatible(op2) || zval_get_long(op2) == 0) { + return 1; + } + } + if ((opcode == ZEND_POW) && zval_get_double(op1) == 0 && zval_get_double(op2) < 0) { /* 0 ** (<0) throws a division by zero error. */ return 1; @@ -9879,12 +13094,6 @@ ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, const zval *op1, co return 1; } - /* Operation which cast float/float-strings to integers might produce incompatible float to int errors */ - if (opcode == ZEND_SL || opcode == ZEND_SR || opcode == ZEND_BW_OR - || opcode == ZEND_BW_AND || opcode == ZEND_BW_XOR || opcode == ZEND_MOD) { - return !zend_is_op_long_compatible(op1) || !zend_is_op_long_compatible(op2); - } - return 0; } /* }}} */ @@ -9892,12 +13101,12 @@ ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, const zval *op1, co static inline bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode, zval *op1, zval *op2) /* {{{ */ { if (zend_binary_op_produces_error(opcode, op1, op2)) { - return 0; + return false; } - binary_op_type fn = get_binary_op(opcode); + const binary_op_type fn = get_binary_op(opcode); fn(result, op1, op2); - return 1; + return true; } /* }}} */ @@ -9910,6 +13119,11 @@ ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, const zval *op) } return Z_TYPE_P(op) <= IS_TRUE || !zend_is_op_long_compatible(op); } + /* Can happen when called from zend_optimizer_eval_unary_op() */ + if (opcode == ZEND_BOOL || opcode == ZEND_BOOL_NOT) { + /* ZEND_BOOL/ZEND_BOOL_NOT warns when casting NAN. */ + return Z_TYPE_P(op) == IS_DOUBLE; + } return 0; } @@ -9917,12 +13131,12 @@ ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, const zval *op) static inline bool zend_try_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op) /* {{{ */ { if (zend_unary_op_produces_error(opcode, op)) { - return 0; + return false; } - unary_op_type fn = get_unary_op(opcode); + const unary_op_type fn = get_unary_op(opcode); fn(result, op); - return 1; + return true; } /* }}} */ @@ -9936,7 +13150,7 @@ static inline bool zend_try_ct_eval_unary_pm(zval *result, zend_ast_kind kind, z static inline void zend_ct_eval_greater(zval *result, zend_ast_kind kind, zval *op1, zval *op2) /* {{{ */ { - binary_op_type fn = kind == ZEND_AST_GREATER + const binary_op_type fn = kind == ZEND_AST_GREATER ? is_smaller_function : is_smaller_or_equal_function; fn(result, op2, op1); } @@ -9944,10 +13158,10 @@ static inline void zend_ct_eval_greater(zval *result, zend_ast_kind kind, zval * static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); zend_ast *last_elem_ast = NULL; uint32_t i; - bool is_constant = 1; + bool is_constant = true; if (ast->attr == ZEND_ARRAY_SYNTAX_LIST) { zend_error(E_COMPILE_ERROR, "Cannot use list() as standalone expression"); @@ -9972,13 +13186,13 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ if (elem_ast->attr /* by_ref */ || elem_ast->child[0]->kind != ZEND_AST_ZVAL || (elem_ast->child[1] && elem_ast->child[1]->kind != ZEND_AST_ZVAL) ) { - is_constant = 0; + is_constant = false; } } else { zend_eval_const_expr(&elem_ast->child[0]); if (elem_ast->child[0]->kind != ZEND_AST_ZVAL) { - is_constant = 0; + is_constant = false; } } @@ -9986,24 +13200,24 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ } if (!is_constant) { - return 0; + return false; } if (!list->children) { ZVAL_EMPTY_ARRAY(result); - return 1; + return true; } array_init_size(result, list->children); for (i = 0; i < list->children; ++i) { - zend_ast *elem_ast = list->child[i]; + const zend_ast *elem_ast = list->child[i]; zend_ast *value_ast = elem_ast->child[0]; zend_ast *key_ast; zval *value = zend_ast_get_zval(value_ast); if (elem_ast->kind == ZEND_AST_UNPACK) { if (Z_TYPE_P(value) == IS_ARRAY) { - HashTable *ht = Z_ARRVAL_P(value); + const HashTable *ht = Z_ARRVAL_P(value); zval *val; zend_string *key; @@ -10027,7 +13241,7 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ key_ast = elem_ast->child[1]; if (key_ast) { - zval *key = zend_ast_get_zval(key_ast); + const zval *key = zend_ast_get_zval(key_ast); switch (Z_TYPE_P(key)) { case IS_LONG: zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(key), value); @@ -10036,12 +13250,10 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ zend_symtable_update(Z_ARRVAL_P(result), Z_STR_P(key), value); break; case IS_DOUBLE: { - zend_long lval = zend_dval_to_lval(Z_DVAL_P(key)); + zend_long lval = zend_dval_to_lval_silent(Z_DVAL_P(key)); /* Incompatible float will generate an error, leave this to run-time */ if (!zend_is_long_compatible(Z_DVAL_P(key), lval)) { - zval_ptr_dtor_nogc(value); - zval_ptr_dtor(result); - return 0; + goto fail; } zend_hash_index_update(Z_ARRVAL_P(result), lval, value); break; @@ -10053,20 +13265,20 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ zend_hash_index_update(Z_ARRVAL_P(result), 1, value); break; case IS_NULL: - zend_hash_update(Z_ARRVAL_P(result), ZSTR_EMPTY_ALLOC(), value); - break; + /* Null key will generate a warning at run-time. */ + goto fail; default: zend_error_noreturn(E_COMPILE_ERROR, "Illegal offset type"); - break; } } else if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), value)) { +fail: zval_ptr_dtor_nogc(value); zval_ptr_dtor(result); return 0; } } - return 1; + return true; } /* }}} */ @@ -10093,29 +13305,7 @@ static void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */ } do { - if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) { - if (left_node.op_type == IS_CONST) { - if (Z_TYPE(left_node.u.constant) == IS_FALSE) { - opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &right_node, NULL); - break; - } else if (Z_TYPE(left_node.u.constant) == IS_TRUE) { - opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &right_node, NULL); - break; - } - } else if (right_node.op_type == IS_CONST) { - if (Z_TYPE(right_node.u.constant) == IS_FALSE) { - opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &left_node, NULL); - break; - } else if (Z_TYPE(right_node.u.constant) == IS_TRUE) { - opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &left_node, NULL); - break; - } - } - } else if (opcode == ZEND_IS_IDENTICAL || opcode == ZEND_IS_NOT_IDENTICAL) { + if (opcode == ZEND_IS_IDENTICAL || opcode == ZEND_IS_NOT_IDENTICAL) { /* convert $x === null to is_null($x) (i.e. ZEND_TYPE_CHECK opcode). Do the same thing for false/true. (covers IS_NULL, IS_FALSE, and IS_TRUE) */ if (left_node.op_type == IS_CONST) { if (Z_TYPE(left_node.u.constant) <= IS_TRUE && Z_TYPE(left_node.u.constant) >= IS_NULL) { @@ -10189,7 +13379,7 @@ static void zend_compile_greater(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_unary_op(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; uint32_t opcode = ast->attr; @@ -10285,7 +13475,7 @@ static void zend_compile_short_circuiting(znode *result, zend_ast *ast) /* {{{ * } /* }}} */ -static void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_post_incdec(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *var_ast = ast->child[0]; ZEND_ASSERT(ast->kind == ZEND_AST_POST_INC || ast->kind == ZEND_AST_POST_DEC); @@ -10293,16 +13483,16 @@ static void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */ zend_ensure_writable_variable(var_ast); if (var_ast->kind == ZEND_AST_PROP || var_ast->kind == ZEND_AST_NULLSAFE_PROP) { - zend_op *opline = zend_compile_prop(NULL, var_ast, BP_VAR_RW, 0); + zend_op *opline = zend_compile_prop(NULL, var_ast, BP_VAR_RW, false); opline->opcode = ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC_OBJ : ZEND_POST_DEC_OBJ; zend_make_tmp_result(result, opline); } else if (var_ast->kind == ZEND_AST_STATIC_PROP) { - zend_op *opline = zend_compile_static_prop(NULL, var_ast, BP_VAR_RW, 0, 0); + zend_op *opline = zend_compile_static_prop(NULL, var_ast, BP_VAR_RW, false, false); opline->opcode = ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC_STATIC_PROP : ZEND_POST_DEC_STATIC_PROP; zend_make_tmp_result(result, opline); } else { znode var_node; - zend_op *opline = zend_compile_var(&var_node, var_ast, BP_VAR_RW, 0); + zend_op *opline = zend_compile_var(&var_node, var_ast, BP_VAR_RW, false); if (opline && opline->opcode == ZEND_FETCH_DIM_RW) { opline->extended_value = ZEND_FETCH_DIM_INCDEC; } @@ -10312,7 +13502,7 @@ static void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_pre_incdec(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *var_ast = ast->child[0]; ZEND_ASSERT(ast->kind == ZEND_AST_PRE_INC || ast->kind == ZEND_AST_PRE_DEC); @@ -10320,18 +13510,18 @@ static void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */ zend_ensure_writable_variable(var_ast); if (var_ast->kind == ZEND_AST_PROP || var_ast->kind == ZEND_AST_NULLSAFE_PROP) { - zend_op *opline = zend_compile_prop(result, var_ast, BP_VAR_RW, 0); + zend_op *opline = zend_compile_prop(result, var_ast, BP_VAR_RW, false); opline->opcode = ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC_OBJ : ZEND_PRE_DEC_OBJ; opline->result_type = IS_TMP_VAR; result->op_type = IS_TMP_VAR; } else if (var_ast->kind == ZEND_AST_STATIC_PROP) { - zend_op *opline = zend_compile_static_prop(result, var_ast, BP_VAR_RW, 0, 0); + zend_op *opline = zend_compile_static_prop(result, var_ast, BP_VAR_RW, false, false); opline->opcode = ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC_STATIC_PROP : ZEND_PRE_DEC_STATIC_PROP; opline->result_type = IS_TMP_VAR; result->op_type = IS_TMP_VAR; } else { znode var_node; - zend_op *opline = zend_compile_var(&var_node, var_ast, BP_VAR_RW, 0); + zend_op *opline = zend_compile_var(&var_node, var_ast, BP_VAR_RW, false); if (opline && opline->opcode == ZEND_FETCH_DIM_RW) { opline->extended_value = ZEND_FETCH_DIM_INCDEC; } @@ -10341,7 +13531,7 @@ static void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_cast(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_cast(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; znode expr_node; @@ -10438,7 +13628,7 @@ static void zend_compile_conditional(znode *result, zend_ast *ast) /* {{{ */ zend_compile_expr(&false_node, false_ast); - opline_qm_assign2 = zend_emit_op(NULL, ZEND_QM_ASSIGN, &false_node, NULL); + opline_qm_assign2 = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &false_node, NULL); SET_NODE(opline_qm_assign2->result, result); zend_update_jump_target_to_next(opnum_jmp); @@ -10454,7 +13644,7 @@ static void zend_compile_coalesce(znode *result, zend_ast *ast) /* {{{ */ zend_op *opline; uint32_t opnum; - zend_compile_var(&expr_node, expr_ast, BP_VAR_IS, 0); + zend_compile_var(&expr_node, expr_ast, BP_VAR_IS, false); opnum = get_next_op_number(); zend_emit_op_tmp(result, ZEND_COALESCE, &expr_node, NULL); @@ -10485,7 +13675,7 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ znode var_node_is, var_node_w, default_node, assign_node, *node; zend_op *opline; uint32_t coalesce_opnum; - bool need_frees = 0; + bool need_frees = false; /* Remember expressions compiled during the initial BP_VAR_IS lookup, * to avoid double-evaluation when we compile again with BP_VAR_W. */ @@ -10501,7 +13691,7 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ zend_hash_init(CG(memoized_exprs), 0, NULL, znode_dtor, 0); CG(memoize_mode) = ZEND_MEMOIZE_COMPILE; - zend_compile_var(&var_node_is, var_ast, BP_VAR_IS, 0); + zend_compile_var(&var_node_is, var_ast, BP_VAR_IS, false); coalesce_opnum = get_next_op_number(); zend_emit_op_tmp(result, ZEND_COALESCE, &var_node_is, NULL); @@ -10514,7 +13704,7 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ } CG(memoize_mode) = ZEND_MEMOIZE_FETCH; - zend_compile_var(&var_node_w, var_ast, BP_VAR_W, 0); + zend_compile_var(&var_node_w, var_ast, BP_VAR_W, false); /* Reproduce some of the zend_compile_assign() opcode fixup logic here. */ opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1]; @@ -10546,7 +13736,7 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ zend_emit_op_data(&default_node); assign_node = var_node_w; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } opline = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &assign_node, NULL); @@ -10554,7 +13744,7 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ ZEND_HASH_FOREACH_PTR(CG(memoized_exprs), node) { if (node->op_type == IS_TMP_VAR || node->op_type == IS_VAR) { - need_frees = 1; + need_frees = true; break; } } ZEND_HASH_FOREACH_END(); @@ -10580,7 +13770,7 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_print(znode *result, const zend_ast *ast) /* {{{ */ { zend_op *opline; zend_ast *expr_ast = ast->child[0]; @@ -10614,16 +13804,16 @@ static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */ } if (value_ast) { - if (returns_by_ref && zend_is_variable(value_ast)) { + if (returns_by_ref && zend_is_variable_or_call(value_ast)) { zend_assert_not_short_circuited(value_ast); - zend_compile_var(&value_node, value_ast, BP_VAR_W, 1); + zend_compile_var(&value_node, value_ast, BP_VAR_W, true); } else { zend_compile_expr(&value_node, value_ast); } value_node_ptr = &value_node; } - opline = zend_emit_op(result, ZEND_YIELD, value_node_ptr, key_node_ptr); + opline = zend_emit_op_tmp(result, ZEND_YIELD, value_node_ptr, key_node_ptr); if (value_ast && returns_by_ref && zend_is_call(value_ast)) { opline->extended_value = ZEND_RETURNS_FUNCTION; @@ -10631,7 +13821,7 @@ static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_yield_from(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_yield_from(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; znode expr_node; @@ -10676,11 +13866,19 @@ static void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */ opline->extended_value = zend_alloc_cache_slot(); } else { SET_NODE(opline->op2, &class_node); + /* Generic / T-ref class refs resolve through zend_fetch_class against + * the current frame's bindings, which are stable within a frame but + * vary across frames. Allocate a 3-slot polymorphic inline cache — + * keys (EX(type_args), called_scope), value resolved CE — so a hot + * loop inside one frame skips the resolver after the first hit. */ + if (class_node.op_type == IS_UNUSED) { + opline->extended_value = zend_alloc_cache_slots(3); + } } } /* }}} */ -static void zend_compile_include_or_eval(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_include_or_eval(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; znode expr_node; @@ -10689,14 +13887,14 @@ static void zend_compile_include_or_eval(znode *result, zend_ast *ast) /* {{{ */ zend_do_extended_fcall_begin(); zend_compile_expr(&expr_node, expr_ast); - opline = zend_emit_op(result, ZEND_INCLUDE_OR_EVAL, &expr_node, NULL); + opline = zend_emit_op_tmp(result, ZEND_INCLUDE_OR_EVAL, &expr_node, NULL); opline->extended_value = ast->attr; zend_do_extended_fcall_end(); } /* }}} */ -static void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_isset_or_empty(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *var_ast = ast->child[0]; @@ -10746,10 +13944,10 @@ static void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ if (is_this_fetch(var_ast)) { opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_THIS, NULL, NULL); CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS; - } else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) { + } else if (zend_try_compile_cv(&var_node, var_ast, BP_VAR_IS) == SUCCESS) { opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_CV, &var_node, NULL); } else { - opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS, 0); + opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS, false); opline->opcode = ZEND_ISSET_ISEMPTY_VAR; } break; @@ -10759,14 +13957,14 @@ static void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ break; case ZEND_AST_PROP: case ZEND_AST_NULLSAFE_PROP: - opline = zend_compile_prop(result, var_ast, BP_VAR_IS, 0); + opline = zend_compile_prop(result, var_ast, BP_VAR_IS, false); opline->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ; break; case ZEND_AST_STATIC_PROP: - opline = zend_compile_static_prop(result, var_ast, BP_VAR_IS, 0, 0); + opline = zend_compile_static_prop(result, var_ast, BP_VAR_IS, false, false); opline->opcode = ZEND_ISSET_ISEMPTY_STATIC_PROP; break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } result->op_type = opline->result_type = IS_TMP_VAR; @@ -10776,7 +13974,7 @@ static void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_silence(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; znode silence_node; @@ -10786,7 +13984,7 @@ static void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */ if (expr_ast->kind == ZEND_AST_VAR) { /* For @$var we need to force a FETCH instruction, otherwise the CV access will * happen outside the silenced section. */ - zend_compile_simple_var_no_cv(result, expr_ast, BP_VAR_R, 0 ); + zend_compile_simple_var_no_cv(result, expr_ast, BP_VAR_R, false ); } else { zend_compile_expr(result, expr_ast); } @@ -10795,17 +13993,19 @@ static void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_shell_exec(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_shell_exec(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; zval fn_name; zend_ast *name_ast, *args_ast, *call_ast; + zend_error(E_DEPRECATED, "The backtick (`) operator is deprecated, use shell_exec() instead"); + ZVAL_STRING(&fn_name, "shell_exec"); name_ast = zend_ast_create_zval(&fn_name); args_ast = zend_ast_create_list(1, ZEND_AST_ARG_LIST, expr_ast); - call_ast = zend_ast_create(ZEND_AST_CALL, name_ast, args_ast); + call_ast = zend_ast_create(ZEND_AST_CALL, name_ast, args_ast, NULL); zend_compile_expr(result, call_ast); @@ -10818,7 +14018,7 @@ static void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */ zend_ast_list *list = zend_ast_get_list(ast); zend_op *opline; uint32_t i, opnum_init = -1; - bool packed = 1; + bool packed = true; if (zend_try_ct_eval_array(&result->u.constant, ast)) { result->op_type = IS_CONST; @@ -10862,7 +14062,7 @@ static void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */ if (by_ref) { zend_ensure_writable_variable(value_ast); - zend_compile_var(&value_node, value_ast, BP_VAR_W, 1); + zend_compile_var(&value_node, value_ast, BP_VAR_W, true); } else { zend_compile_expr(&value_node, value_ast); } @@ -10879,7 +14079,7 @@ static void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */ opline->extended_value |= by_ref; if (key_ast && key_node.op_type == IS_CONST && Z_TYPE(key_node.u.constant) == IS_STRING) { - packed = 0; + packed = false; } } @@ -10892,7 +14092,7 @@ static void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_const(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *name_ast = ast->child[0]; @@ -10906,7 +14106,7 @@ static void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */ zend_ast *last = CG(ast); while (last && last->kind == ZEND_AST_STMT_LIST) { - zend_ast_list *list = zend_ast_get_list(last); + const zend_ast_list *list = zend_ast_get_list(last); if (list->children == 0) { break; } @@ -10932,11 +14132,11 @@ static void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */ if (is_fully_qualified || !FC(current_namespace)) { opline->op1.num = 0; opline->op2.constant = zend_add_const_name_literal( - resolved_name, 0); + resolved_name, false); } else { opline->op1.num = IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE; opline->op2.constant = zend_add_const_name_literal( - resolved_name, 1); + resolved_name, true); } opline->extended_value = zend_alloc_cache_slot(); } @@ -10983,7 +14183,7 @@ static void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_class_name(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_class_name(znode *result, const zend_ast *ast) /* {{{ */ { zend_ast *class_ast = ast->child[0]; @@ -10994,7 +14194,19 @@ static void zend_compile_class_name(znode *result, zend_ast *ast) /* {{{ */ if (class_ast->kind == ZEND_AST_ZVAL) { zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL); - opline->op1.num = zend_get_class_fetch_type(zend_ast_get_str(class_ast)); + uint32_t op1_num = zend_get_class_fetch_type(zend_ast_get_str(class_ast)); + if (op1_num == ZEND_FETCH_CLASS_DEFAULT + && (class_ast->attr & ZEND_NAME_NOT_FQ) == ZEND_NAME_NOT_FQ) { + zend_generic_origin origin; + uint32_t param_index = 0; + zend_generic_parameter *param = zend_generic_lookup_full( + zend_ast_get_str(class_ast), &origin, ¶m_index); + if (param) { + op1_num = zend_pack_type_param_fetch(param_index, 0, + origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE); + } + } + opline->op1.num = op1_num; } else { znode expr_node; zend_compile_expr(&expr_node, class_ast); @@ -11178,7 +14390,7 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */ +static void zend_compile_magic_const(znode *result, const zend_ast *ast) /* {{{ */ { zend_op *opline; @@ -11280,8 +14492,7 @@ static void zend_compile_const_expr_class_name(zend_ast **ast_ptr) /* {{{ */ case ZEND_FETCH_CLASS_STATIC: zend_error_noreturn(E_COMPILE_ERROR, "static::class cannot be used for compile-time class name resolution"); - return; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -11352,12 +14563,17 @@ static void zend_compile_const_expr_new(zend_ast **ast_ptr) { zend_ast *class_ast = (*ast_ptr)->child[0]; zend_compile_const_expr_class_reference(class_ast); + + const zend_ast *args_ast = (*ast_ptr)->child[1]; + if (args_ast->kind == ZEND_AST_CALLABLE_CONVERT) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot create Closure for new expression"); + } } static void zend_compile_const_expr_closure(zend_ast **ast_ptr) { zend_ast_decl *closure_ast = (zend_ast_decl *) *ast_ptr; - zend_ast *uses_ast = closure_ast->child[1]; + const zend_ast *uses_ast = closure_ast->child[1]; if (!(closure_ast->flags & ZEND_ACC_STATIC)) { zend_error_noreturn(E_COMPILE_ERROR, "Closures in constant expressions must be static"); @@ -11384,7 +14600,7 @@ static void zend_compile_const_expr_fcc(zend_ast **ast_ptr) case ZEND_AST_STATIC_CALL: args_ast = &(*ast_ptr)->child[2]; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } if ((*args_ast)->kind != ZEND_AST_CALLABLE_CONVERT) { zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations"); @@ -11422,7 +14638,7 @@ static void zend_compile_const_expr_fcc(zend_ast **ast_ptr) } break; } - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -11431,7 +14647,7 @@ static void zend_compile_const_expr_args(zend_ast **ast_ptr) zend_ast_list *list = zend_ast_get_list(*ast_ptr); bool uses_named_args = false; for (uint32_t i = 0; i < list->children; i++) { - zend_ast *arg = list->child[i]; + const zend_ast *arg = list->child[i]; if (arg->kind == ZEND_AST_UNPACK) { zend_error_noreturn(E_COMPILE_ERROR, "Argument unpacking in constant expressions is not supported"); @@ -11455,7 +14671,7 @@ typedef struct { static void zend_compile_const_expr(zend_ast **ast_ptr, void *context) /* {{{ */ { - const_expr_context *ctx = (const_expr_context *) context; + const const_expr_context *ctx = context; zend_ast *ast = *ast_ptr; if (ast == NULL || ast->kind == ZEND_AST_ZVAL) { return; @@ -11534,7 +14750,7 @@ void zend_compile_top_stmt(zend_ast *ast) /* {{{ */ } if (ast->kind == ZEND_AST_STMT_LIST) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; ++i) { zend_compile_top_stmt(list->child[i]); @@ -11548,7 +14764,7 @@ void zend_compile_top_stmt(zend_ast *ast) /* {{{ */ CG(zend_lineno) = ((zend_ast_decl *) ast)->end_lineno; } else if (ast->kind == ZEND_AST_CLASS) { CG(zend_lineno) = ast->lineno; - zend_compile_class_decl(NULL, ast, 1); + zend_compile_class_decl(NULL, ast, true); CG(zend_lineno) = ((zend_ast_decl *) ast)->end_lineno; } else { zend_compile_stmt(ast); @@ -11568,7 +14784,7 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ CG(zend_lineno) = ast->lineno; if ((CG(compiler_options) & ZEND_COMPILE_EXTENDED_STMT) && !zend_is_unticked_stmt(ast)) { - zend_do_extended_stmt(); + zend_do_extended_stmt(NULL); } switch (ast->kind) { @@ -11641,7 +14857,7 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ zend_compile_use_trait(ast); break; case ZEND_AST_CLASS: - zend_compile_class_decl(NULL, ast, 0); + zend_compile_class_decl(NULL, ast, false); break; case ZEND_AST_GROUP_USE: zend_compile_group_use(ast); @@ -11664,6 +14880,15 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ case ZEND_AST_CAST_VOID: zend_compile_void_cast(NULL, ast); break; + case ZEND_AST_ASSIGN: { + znode result; + zend_compile_assign(&result, ast, /* stmt */ true, BP_VAR_R); + zend_do_free(&result); + return; + } + case ZEND_AST_ASSIGN_REF: + zend_compile_assign_ref(NULL, ast, BP_VAR_R); + return; default: { znode result; @@ -11684,7 +14909,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ CG(zend_lineno) = zend_ast_get_lineno(ast); if (CG(memoize_mode) != ZEND_MEMOIZE_NONE) { - zend_compile_memoized_expr(result, ast); + zend_compile_memoized_expr(result, ast, BP_VAR_R); return; } @@ -11705,21 +14930,18 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: case ZEND_AST_STATIC_CALL: - case ZEND_AST_PARENT_PROPERTY_HOOK_CALL: - zend_compile_var(result, ast, BP_VAR_R, 0); + case ZEND_AST_PIPE: + zend_compile_var(result, ast, BP_VAR_R, false); return; case ZEND_AST_ASSIGN: - zend_compile_assign(result, ast); + zend_compile_assign(result, ast, /* stmt */ false, BP_VAR_R); return; case ZEND_AST_ASSIGN_REF: - zend_compile_assign_ref(result, ast); + zend_compile_assign_ref(result, ast, BP_VAR_R); return; case ZEND_AST_NEW: zend_compile_new(result, ast); return; - case ZEND_AST_CLONE: - zend_compile_clone(result, ast); - return; case ZEND_AST_ASSIGN_OP: zend_compile_compound_assign(result, ast); return; @@ -11814,9 +15036,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ case ZEND_AST_MATCH: zend_compile_match(result, ast); return; - case ZEND_AST_PIPE: - zend_compile_pipe(result, ast); - return; default: ZEND_ASSERT(0 /* not supported */); } @@ -11830,6 +15049,12 @@ static void zend_compile_expr(znode *result, zend_ast *ast) uint32_t checkpoint = zend_short_circuiting_checkpoint(); zend_compile_expr_inner(result, ast); zend_short_circuiting_commit(checkpoint, result, ast); +#if ZEND_DEBUG + if (result) { + /* BP_VAR_R is not allowed to produce IS_VAR. */ + ZEND_ASSERT(result->op_type != IS_VAR); + } +#endif } static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t type, bool by_ref) @@ -11842,7 +15067,7 @@ static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t ty case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: case ZEND_AST_STATIC_CALL: - zend_compile_memoized_expr(result, ast); + zend_compile_memoized_expr(result, ast, BP_VAR_W); /* This might not actually produce an opcode, e.g. for expressions evaluated at comptime. */ return NULL; } @@ -11850,20 +15075,17 @@ static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t ty switch (ast->kind) { case ZEND_AST_VAR: - return zend_compile_simple_var(result, ast, type, 0); + return zend_compile_simple_var(result, ast, type, false); case ZEND_AST_DIM: return zend_compile_dim(result, ast, type, by_ref); case ZEND_AST_PROP: case ZEND_AST_NULLSAFE_PROP: return zend_compile_prop(result, ast, type, by_ref); case ZEND_AST_STATIC_PROP: - return zend_compile_static_prop(result, ast, type, by_ref, 0); + return zend_compile_static_prop(result, ast, type, by_ref, false); case ZEND_AST_CALL: zend_compile_call(result, ast, type); return NULL; - case ZEND_AST_PARENT_PROPERTY_HOOK_CALL: - zend_compile_parent_property_hook_call(result, ast, type); - return NULL; case ZEND_AST_METHOD_CALL: case ZEND_AST_NULLSAFE_METHOD_CALL: zend_compile_method_call(result, ast, type); @@ -11871,9 +15093,18 @@ static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t ty case ZEND_AST_STATIC_CALL: zend_compile_static_call(result, ast, type); return NULL; + case ZEND_AST_PIPE: + zend_compile_pipe(result, ast, type); + return NULL; case ZEND_AST_ZNODE: *result = *zend_ast_get_znode(ast); return NULL; + case ZEND_AST_ASSIGN_REF: + zend_compile_assign_ref(result, ast, type); + return NULL; + case ZEND_AST_ASSIGN: + zend_compile_assign(result, ast, false, type); + return NULL; default: if (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) { zend_error_noreturn(E_COMPILE_ERROR, @@ -11892,6 +15123,16 @@ static zend_op *zend_compile_var(znode *result, zend_ast *ast, uint32_t type, bo uint32_t checkpoint = zend_short_circuiting_checkpoint(); zend_op *opcode = zend_compile_var_inner(result, ast, type, by_ref); zend_short_circuiting_commit(checkpoint, result, ast); +#if ZEND_DEBUG + if (result + && (type == BP_VAR_R || type == BP_VAR_IS) + /* Don't check memoized result, as it will force BP_VAR_W even for BP_VAR_IS. */ + && CG(memoize_mode) == ZEND_MEMOIZE_NONE + ) { + /* BP_VAR_{R,IS} is not allowed to produce IS_VAR. */ + ZEND_ASSERT(result->op_type != IS_VAR); + } +#endif return opcode; } @@ -11901,7 +15142,7 @@ static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t switch (ast->kind) { case ZEND_AST_VAR: - return zend_compile_simple_var(result, ast, type, 1); + return zend_compile_simple_var(result, ast, type, true); case ZEND_AST_DIM: return zend_delayed_compile_dim(result, ast, type, by_ref); case ZEND_AST_PROP: @@ -11914,20 +15155,27 @@ static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t return opline; } case ZEND_AST_STATIC_PROP: - return zend_compile_static_prop(result, ast, type, by_ref, 1); + return zend_compile_static_prop(result, ast, type, by_ref, true); default: - return zend_compile_var(result, ast, type, 0); + return zend_compile_var(result, ast, type, false); } } /* }}} */ bool zend_try_ct_eval_cast(zval *result, uint32_t type, zval *op1) { + /* NAN warns when casting */ + if (UNEXPECTED(Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1)))) { + return false; + } switch (type) { case _IS_BOOL: - ZVAL_BOOL(result, zval_is_true(op1)); + ZVAL_BOOL(result, zend_is_true(op1)); return true; case IS_LONG: + if (Z_TYPE_P(op1) == IS_DOUBLE && !ZEND_DOUBLE_FITS_LONG(Z_DVAL_P((op1)))) { + return false; + } ZVAL_LONG(result, zval_get_long(op1)); return true; case IS_DOUBLE: @@ -12085,7 +15333,7 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ case ZEND_AST_DIM: { /* constant expression should be always read context ... */ - zval *container, *dim; + const zval *container, *dim; if (ast->child[1] == NULL) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading"); @@ -12227,7 +15475,7 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ zend_eval_const_expr(&ast->child[1]); return; case ZEND_AST_CONST_ENUM_INIT: - zend_eval_const_expr(&ast->child[2]); + zend_eval_const_expr(&ast->child[3]); return; case ZEND_AST_PROP: case ZEND_AST_NULLSAFE_PROP: @@ -12235,6 +15483,9 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ zend_eval_const_expr(&ast->child[1]); return; case ZEND_AST_CAST: + if (ast->attr == IS_NULL) { + zend_error_noreturn(E_COMPILE_ERROR, "The (unset) cast is no longer supported"); + } zend_eval_const_expr(&ast->child[0]); if (ast->child[0]->kind == ZEND_AST_ZVAL && zend_try_ct_eval_cast(&result, ast->attr, zend_ast_get_zval(ast->child[0]))) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 62d0fbcded2e..b224ff6dd7ec 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -24,6 +23,7 @@ #include "zend_types.h" #include "zend_map_ptr.h" #include "zend_alloc.h" +#include "zend_vm_opcodes.h" #include #include @@ -96,7 +96,7 @@ typedef struct _zend_ast_znode { znode node; } zend_ast_znode; -ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node); +ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(const znode *node); static zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) { return &((zend_ast_znode *) ast)->node; @@ -121,6 +121,223 @@ typedef struct _zend_file_context { HashTable seen_symbols; } zend_file_context; +/* Maximum number of generic type parameters or arguments at any single + * position. Capped at 7 bits so a uint8_t count leaves its top bit + * available for future runtime-model flags. */ +#define ZEND_GENERIC_MAX_PARAMS 127 + +C23_ENUM(zend_generic_variance, uint8_t) { + ZEND_GENERIC_VARIANCE_INVARIANT = 0, + ZEND_GENERIC_VARIANCE_COVARIANT = 1, + ZEND_GENERIC_VARIANCE_CONTRAVARIANT = 2, +}; + +C23_ENUM(zend_generic_origin, uint8_t) { + ZEND_GENERIC_ORIGIN_CLASS_LIKE = 0, /* class, interface, trait, enum */ + ZEND_GENERIC_ORIGIN_FUNCTION_LIKE = 1, /* function, method, closure, arrow function */ +}; + +typedef struct _zend_generic_parameter { + zend_string *name; /* type-parameter name */ + zend_generic_variance variance; + zend_type bound; /* runtime erased; ZEND_TYPE_NONE if unbounded */ + zend_type bound_pre_erasure; /* pre-erasure; ZEND_TYPE_NONE if same as `bound` */ + zend_type default_type; /* runtime erased; ZEND_TYPE_NONE if no default */ + zend_type default_pre_erasure; /* pre-erasure; ZEND_TYPE_NONE if same as `default_type` */ +} zend_generic_parameter; + +typedef struct _zend_generic_parameter_list { + uint32_t count; + uint64_t inferable_mask; /* bit i set when some value-parameter's pre-erasure type is exactly param i */ + zend_generic_parameter parameters[1]; +} zend_generic_parameter_list; + +#define ZEND_GENERIC_PARAMETER_LIST_SIZE(count) \ + (sizeof(zend_generic_parameter_list) + ((count) - 1) * sizeof(zend_generic_parameter)) + +/* Packed, callee-static list of the direct FUNCTION_LIKE type-parameter value + * parameters that zend_verify_generic_arg_types must runtime-check. Derived once + * from `parameters`, it replaces a per-call HashTable iteration (+ per-entry + * TYPE_PARAMETER/origin filtering) with a tight array walk. Built lazily on the + * first verify; left NULL on opcache-persisted tables (which are read-only), in + * which case verify falls back to iterating `parameters` directly. */ +typedef struct _zend_generic_value_check { + uint32_t arg_idx; /* parameter position (0-based) */ + uint32_t tp_index; /* type-parameter index to substitute (ref->index) */ +} zend_generic_value_check; + +typedef struct _zend_generic_value_check_plan { + uint32_t count; + zend_generic_value_check checks[1]; /* flexible array */ +} zend_generic_value_check_plan; + +typedef struct _zend_generic_type_table { + zend_type *return_type; /* function/method return; NULL if equal to erased */ + zend_type *extends; /* class extends; NULL if equal */ + HashTable *parameters; /* parameter index -> zend_type * */ + HashTable *properties; /* zend_string * -> zend_type * */ + HashTable *class_constants; /* zend_string * -> zend_type * */ + HashTable *implements; /* implements index -> zend_type * */ + HashTable *trait_uses; /* trait-use index -> zend_type * */ + HashTable *turbofish_args; /* opline->extended_value -> zend_type * (NAMED_WITH_ARGS holding the call-site type arguments); index is stable across optimizer reorderings */ + bool persisted; /* set by opcache when the table lives in SHM/file-cache memory; suppresses destruction */ + zend_generic_value_check_plan *value_check_plan; /* lazily built; request-local; NULL on persisted tables */ + struct _zend_type_arg_table *monomorph_type_args; /* on a monomorph op_array: invariant concrete type-args installed onto the call frame by dispatch; NULL otherwise */ +} zend_generic_type_table; + +/* Compile-time linked stack of in-scope generic type parameters. */ +typedef struct _zend_generic_scope_entry { + zend_generic_parameter_list *params; + uint32_t visible_count; /* number of parameters in `params` already declared */ + struct _zend_generic_parameter *self_compiling; /* param whose bound/default is being compiled, or NULL */ + HashTable *shadowing_classes; /* lc_names of class-likes declared inside this scope; lazy-allocated */ + zend_generic_origin origin; + struct _zend_generic_scope_entry *outer; +} zend_generic_scope_entry; + +ZEND_API zend_generic_parameter_list *zend_generic_parameter_list_alloc(uint32_t count, bool persistent); +ZEND_API void zend_generic_parameter_list_destroy(zend_generic_parameter_list *list); +ZEND_API zend_generic_type_table *zend_generic_type_table_alloc(void); +ZEND_API void zend_generic_type_table_destroy(zend_generic_type_table *table); +ZEND_API uint32_t zend_count_generic_value_checks(const HashTable *parameters); +ZEND_API void zend_fill_generic_value_check_plan(zend_generic_value_check_plan *plan, const HashTable *parameters); +ZEND_API void zend_generic_type_table_set_return(zend_generic_type_table *t, zend_type type); +ZEND_API void zend_generic_type_table_set_extends(zend_generic_type_table *t, zend_type type); +ZEND_API zend_generic_type_table *zend_generic_get_or_create_class_table(zend_class_entry *ce); +ZEND_API void zend_generic_type_table_set_parameter(zend_generic_type_table *t, uint32_t idx, zend_type type); +ZEND_API void zend_generic_type_table_set_property(zend_generic_type_table *t, zend_string *name, zend_type type); +ZEND_API void zend_generic_type_table_set_class_constant(zend_generic_type_table *t, zend_string *name, zend_type type); +ZEND_API void zend_generic_type_table_set_implements(zend_generic_type_table *t, uint32_t idx, zend_type type); +ZEND_API void zend_generic_type_table_set_trait_use(zend_generic_type_table *t, uint32_t idx, zend_type type); +ZEND_API void zend_generic_type_table_set_turbofish_args(zend_generic_type_table *t, uint32_t op_num, zend_type type); + +ZEND_API void zend_check_generic_param_list_size(zend_ast *list_ast); +ZEND_API void zend_check_generic_arg_list_size(zend_ast *list_ast); + +ZEND_API void zend_check_generic_call_arguments(const zend_function *fbc, uint32_t arity, const zend_type *args_box); +ZEND_API void zend_check_generic_new_arguments(const zend_class_entry *ce, uint32_t arity, const zend_type *args_box); +ZEND_API void zend_apply_generic_new(zval *new_obj, zend_execute_data *call, const zend_type *args_box, uint32_t arity, void **cache_slot, bool do_checks); +ZEND_API const zend_type *zend_generic_get_turbofish_args(const zend_op_array *caller_op_array, uint32_t args_id); +ZEND_API struct _zend_turbofish_args_entry *zend_generic_get_turbofish_call_entry(const zend_op_array *caller_op_array, uint32_t args_id); + +/* Per-call-frame mapping of generic type parameters to their bindings. + * `name` is the canonical class name (or scalar/composite canonical string) + * for the bound type, used for class lookups and equality. The bound type + * itself is reachable via: + * - `type_ref`: a borrowed pointer to a zend_type in longer-lived + * storage — typically a turbofish args_box (held by some op_array's + * side table) or a parent frame's entry. Frames nest, so the source + * is guaranteed to outlive the entry. + * - `owned_type`: a zend_type owned by this entry. Used when no + * pre-existing zend_type can be borrowed — currently only for + * value-directed inference, where the inferred class-name zend_type + * is synthesised fresh. Released by zend_type_arg_table_destroy. + * Reads prefer `type_ref` when non-NULL, otherwise `owned_type`. When both + * are unset the parameter is unbound — consumers fall back to the + * parameter's declared bound. + * + * Lifetime: allocated by VERIFY_GENERIC_ARGUMENTS for a function call (or + * inferred at RECV time), freed when the frame unwinds. `generation` is a + * monotonically-increasing nonce assigned at allocation time so cache + * slots that key off the table pointer can detect ABA reuse. */ +typedef struct _zend_type_arg_entry { + zend_string *name; + const zend_type *type_ref; + zend_type owned_type; +} zend_type_arg_entry; + +typedef struct _zend_type_arg_table { + uint32_t count; + uint32_t generation; + /* True when the table has been relocated into opcache SHM / file cache + * as part of a persisted class entry's `generic_type_args`. Tells the + * destroy path to leave the table and its name/type contents alone. */ + bool persisted; + zend_type_arg_entry entries[1]; +} zend_type_arg_table; + +#define ZEND_TYPE_ARG_TABLE_SIZE(count) \ + (sizeof(zend_type_arg_table) + ((count) - 1) * sizeof(zend_type_arg_entry)) + +/* Read the bound type for an entry — returns NULL if unbound. */ +static zend_always_inline const zend_type *zend_type_arg_entry_type(const zend_type_arg_entry *entry) { + if (entry->type_ref) return entry->type_ref; + if (ZEND_TYPE_IS_SET(entry->owned_type)) return &entry->owned_type; + return NULL; +} + +/* Per-call-site side entry: stores the compile-time args_box. The one-slot + * runtime cache that pairs with this (cached zend_type_arg_table* keyed on + * the caller's binding identities) lives in the caller op_array's runtime + * cache, addressed by opline->result.num — that storage is per-process and + * writable even when the entry itself is persisted to opcache SHM. */ +typedef struct _zend_turbofish_args_entry { + zend_type args_box; + struct _zend_type_arg_table *concrete_table; /* precomputed read-only table for a concrete INSTALL site; NULL when the handler must rebuild at runtime */ + bool concrete_skip_value_check; /* callee has no direct T-ref value params, so the value check is a no-op */ +} zend_turbofish_args_entry; + +/* Resolve a generic call site's turbofish args_box, memoizing the (static per + * site) turbofish_args lookup in cache_slot[2] so the VERIFY/INSTALL handlers + * skip the hash lookup after the first call. Returns NULL when the site has no + * turbofish (args_id == 0 / no entry). */ +static zend_always_inline const zend_type *zend_generic_get_or_cache_args_box( + const zend_op_array *op_array, uint32_t args_id, void **cache_slot) +{ + zend_turbofish_args_entry *entry; + if (cache_slot && cache_slot[2]) { + entry = (zend_turbofish_args_entry *) cache_slot[2]; + } else { + entry = zend_generic_get_turbofish_call_entry(op_array, args_id); + if (cache_slot && entry) { + cache_slot[2] = entry; + } + } + return entry ? &entry->args_box : NULL; +} + +/* Like zend_generic_get_or_cache_args_box, but returns the whole entry. */ +static zend_always_inline zend_turbofish_args_entry *zend_generic_get_or_cache_args_entry( + const zend_op_array *op_array, uint32_t args_id, void **cache_slot) +{ + zend_turbofish_args_entry *entry; + if (cache_slot && cache_slot[2]) { + entry = (zend_turbofish_args_entry *) cache_slot[2]; + } else { + entry = zend_generic_get_turbofish_call_entry(op_array, args_id); + if (cache_slot && entry) { + cache_slot[2] = entry; + } + } + return entry; +} + +/* Cache key sentinel for concrete-arg call sites (no T-refs in the args). + * Cache key 0 means empty; CONCRETE means "args fully resolved at compile + * time, table is invariant across calls." */ +#define ZEND_TURBOFISH_CACHE_KEY_CONCRETE ((uintptr_t)1) + +/* Runtime-promoted site: cache_slot[0] = invariant table, cache_slot[3] = + * memoized callee (low bit = value check is a no-op). */ +#define ZEND_TURBOFISH_CACHE_KEY_PROMOTED ((uintptr_t)2) + +/* Monomorphized site: cache_slot[0] = monomorph func, [3] = base func guard, + * [4] = shared invariant type-arg table. */ +#define ZEND_TURBOFISH_CACHE_KEY_MONOMORPH ((uintptr_t)3) + +ZEND_API zend_type_arg_table *zend_type_arg_table_alloc(uint32_t count); +ZEND_API void zend_type_arg_table_destroy(zend_type_arg_table *table); +ZEND_API zend_type_arg_table *zend_type_arg_table_capture_clone(const zend_type_arg_table *src); +ZEND_API zend_string *zend_type_arg_canonical_name(zend_type type); +ZEND_API zend_type_arg_table *zend_build_generic_call_type_args(zend_execute_data *call, const zend_type *args_box); +ZEND_API zend_type_arg_table *zend_build_or_get_cached_type_args(zend_execute_data *call, const zend_type *args_box, void **cache_slot); +ZEND_API zend_class_entry *zend_resolve_generic_type_param(uint32_t param_index, uint32_t fetch_type); +ZEND_API zend_class_entry *zend_resolve_deferred_generic_class(uint32_t args_id, uint32_t fetch_type); +ZEND_API bool zend_verify_generic_arg_types(zend_execute_data *call, const zend_type *args_box); +ZEND_API zend_function *zend_get_or_synthesize_call_monomorph(zend_execute_data *call, const zend_type *args_box, uint32_t arity, void **cache_slot, zend_type_arg_table **out_type_args); +ZEND_API zend_function *zend_try_monomorph_resolved_call(zend_execute_data *call, zend_type_arg_table *resolved, void **cache_slot, zend_type_arg_table **out_type_args); +ZEND_API bool zend_verify_generic_return_type(zend_execute_data *call, zval *retval_ptr); + typedef union _zend_parser_stack_elem { zend_ast *ast; zend_string *str; @@ -135,7 +352,7 @@ void zend_const_expr_to_zval(zval *result, zend_ast **ast_ptr, bool allow_dynami typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data); struct _zend_op { - const void *handler; + zend_vm_opcode_handler_t handler; znode_op op1; znode_op op2; znode_op result; @@ -196,8 +413,8 @@ typedef struct _zend_oparray_context { struct _zend_oparray_context *prev; zend_op_array *op_array; uint32_t opcodes_size; - int vars_size; - int literals_size; + uint32_t vars_size; + uint32_t literals_size; uint32_t fast_call_var; uint32_t try_catch_offset; int current_brk_cont; @@ -207,6 +424,7 @@ typedef struct _zend_oparray_context { zend_string *active_property_info_name; zend_property_hook_kind active_property_hook_kind; bool in_jmp_frameless_branch; + bool has_assigned_to_http_response_header; } zend_oparray_context; /* Class, property and method flags class|meth.|prop.|const*/ @@ -251,9 +469,15 @@ typedef struct _zend_oparray_context { /* Flag to differentiate cases from constants. | | | */ /* Must not conflict with ZEND_ACC_ visibility flags | | | */ /* or IS_CONSTANT_VISITED_MARK | | | */ -#define ZEND_CLASS_CONST_IS_CASE (1 << 6) /* | | | X */ +#define ZEND_CLASS_CONST_IS_CASE (1 << 6) /* | | | X */ +/* | | | */ +/* deprecation flag | | | */ +#define ZEND_ACC_DEPRECATED (1 << 11) /* X | X | | X */ /* | | | */ -/* Property Flags (unused: 13...) | | | */ +/* has #[\Override] attribute | | | */ +#define ZEND_ACC_OVERRIDE (1 << 28) /* | X | X | */ +/* | | | */ +/* Property Flags (unused: 14-27,29...) | | | */ /* =========== | | | */ /* | | | */ /* Promoted property / parameter | | | */ @@ -267,7 +491,10 @@ typedef struct _zend_oparray_context { #define ZEND_ACC_PROTECTED_SET (1 << 11) /* | | X | */ #define ZEND_ACC_PRIVATE_SET (1 << 12) /* | | X | */ /* | | | */ -/* Class Flags (unused: 30,31) | | | */ +/* Parametric LSP substitution clone owned by a child | | | */ +#define ZEND_ACC_GENERIC_CLONE (1 << 13) /* | | X | */ +/* | | | */ +/* Class Flags (unused: 31) | | | */ /* =========== | | | */ /* | | | */ /* Special class types | | | */ @@ -285,7 +512,7 @@ typedef struct _zend_oparray_context { /* | | | */ /* Class has magic methods __get/__set/__unset/ | | | */ /* __isset that use guards | | | */ -#define ZEND_ACC_USE_GUARDS (1 << 11) /* X | | | */ +#define ZEND_ACC_USE_GUARDS (1 << 30) /* X | | | */ /* | | | */ /* Class constants updated | | | */ #define ZEND_ACC_CONSTANTS_UPDATED (1 << 12) /* X | | | */ @@ -333,12 +560,19 @@ typedef struct _zend_oparray_context { /* Class cannot be serialized or unserialized | | | */ #define ZEND_ACC_NOT_SERIALIZABLE (1 << 29) /* X | | | */ /* | | | */ +/* Generic class whose every parameter has a default — | | | */ +/* hot-path bit for ZEND_NEW to skip the per-parameter | | | */ +/* default scan when synthesizing a defaults monomorph. | | | */ +#define ZEND_ACC_GENERIC_ALL_DEFAULTS (1u << 31) /* X | | | */ +/* | | | */ +/* Class Flags 2 (ce_flags2) (unused: 0-31) | | | */ +/* ========================= | | | */ +/* | | | */ +/* #define ZEND_ACC2_EXAMPLE (1 << 0) X | | | */ +/* | | | */ /* Function Flags (unused: 30) | | | */ /* ============== | | | */ /* | | | */ -/* deprecation flag | | | */ -#define ZEND_ACC_DEPRECATED (1 << 11) /* | X | | X */ -/* | | | */ /* Function returning by reference | | | */ #define ZEND_ACC_RETURN_REFERENCE (1 << 12) /* | X | | */ /* | | | */ @@ -392,9 +626,6 @@ typedef struct _zend_oparray_context { /* supports opcache compile-time evaluation (funcs) | | | */ #define ZEND_ACC_COMPILE_TIME_EVAL (1 << 27) /* | X | | */ /* | | | */ -/* has #[\Override] attribute | | | */ -#define ZEND_ACC_OVERRIDE (1 << 28) /* | X | | */ -/* | | | */ /* Has IS_PTR operands that needs special cleaning; same | | | */ /* value as ZEND_ACC_OVERRIDE but override is for class | | | */ /* methods and this is for the top level op array | | | */ @@ -405,6 +636,18 @@ typedef struct _zend_oparray_context { /* | | | */ /* op_array uses strict mode types | | | */ #define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */ +/* | | | */ +/* Function Flags 2 (fn_flags2) (unused: 1-31) | | | */ +/* ============================ | | | */ +/* | | | */ +/* Function forbids dynamic calls | | | */ +#define ZEND_ACC2_FORBID_DYN_CALLS (1 << 0) /* | X | | */ +/* | | | */ +/* op_array has generic CALL opcodes (scanned at teardown)| | | */ +#define ZEND_ACC2_HAS_GENERIC_CALL_OPS (1 << 1) /* | X | | */ +/* | | | */ +/* synthesized monomorph carrying concrete type-args | | | */ +#define ZEND_ACC2_MONOMORPH_TYPE_ARGS (1 << 2) /* | X | | */ #define ZEND_ACC_PPP_MASK (ZEND_ACC_PUBLIC | ZEND_ACC_PROTECTED | ZEND_ACC_PRIVATE) #define ZEND_ACC_PPP_SET_MASK (ZEND_ACC_PUBLIC_SET | ZEND_ACC_PROTECTED_SET | ZEND_ACC_PRIVATE_SET) @@ -418,7 +661,7 @@ static zend_always_inline uint32_t zend_visibility_to_set_visibility(uint32_t vi return ZEND_ACC_PROTECTED_SET; case ZEND_ACC_PRIVATE: return ZEND_ACC_PRIVATE_SET; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -441,7 +684,7 @@ static zend_always_inline uint32_t zend_visibility_to_set_visibility(uint32_t vi // Must not clash with ZEND_SHORT_CIRCUITING_CHAIN_MASK #define ZEND_JMP_NULL_BP_VAR_IS 4 -char *zend_visibility_string(uint32_t fn_flags); +const char *zend_visibility_string(uint32_t fn_flags); #define ZEND_PROPERTY_HOOK_COUNT 2 #define ZEND_PROPERTY_HOOK_STRUCT_SIZE (sizeof(zend_function*) * ZEND_PROPERTY_HOOK_COUNT) @@ -449,7 +692,7 @@ char *zend_visibility_string(uint32_t fn_flags); /* Stored in zend_property_info.offset, not returned by zend_get_property_offset(). */ #define ZEND_VIRTUAL_PROPERTY_OFFSET ((uint32_t)-1) -zend_property_hook_kind zend_get_property_hook_kind_from_name(zend_string *name); +zend_property_hook_kind zend_get_property_hook_kind_from_name(const zend_string *name); typedef struct _zend_property_info { uint32_t offset; /* property offset for object properties or @@ -469,7 +712,7 @@ typedef struct _zend_property_info { #define OBJ_PROP_NUM(obj, num) \ (&(obj)->properties_table[(num)]) #define OBJ_PROP_TO_OFFSET(num) \ - ((uint32_t)(XtOffsetOf(zend_object, properties_table) + sizeof(zval) * (num))) + ((uint32_t)(offsetof(zend_object, properties_table) + sizeof(zval) * (num))) #define OBJ_PROP_TO_NUM(offset) \ (((offset) - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) #define OBJ_PROP_SLOT_TO_OFFSET(obj, slot) \ @@ -485,6 +728,12 @@ typedef struct _zend_class_constant { #define ZEND_CLASS_CONST_FLAGS(c) Z_CONSTANT_FLAGS((c)->value) +C23_ENUM(zend_function_type, uint8_t) { + ZEND_INTERNAL_FUNCTION = 1, + ZEND_USER_FUNCTION = 2, + ZEND_EVAL_CODE = 4, +}; + /* arg_info for internal functions */ typedef struct _zend_internal_arg_info { const char *name; @@ -497,6 +746,7 @@ typedef struct _zend_arg_info { zend_string *name; zend_type type; zend_string *default_value; + zend_string *doc_comment; } zend_arg_info; /* the following structure repeats the layout of zend_internal_arg_info, @@ -512,7 +762,7 @@ typedef struct _zend_internal_function_info { struct _zend_op_array { /* Common elements */ - uint8_t type; + zend_function_type type; uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string *function_name; @@ -525,12 +775,13 @@ struct _zend_op_array { ZEND_MAP_PTR_DEF(void **, run_time_cache); zend_string *doc_comment; uint32_t T; /* number of temporary variables */ + uint32_t fn_flags2; const zend_property_info *prop_info; /* The corresponding prop_info if this is a hook. */ /* END of common elements */ - int cache_size; /* number of run_time_cache_slots * sizeof(void*) */ - int last_var; /* number of CV variables */ - uint32_t last; /* number of opcodes */ + uint32_t cache_size; /* number of run_time_cache_slots * sizeof(void*) */ + int last_var; /* number of CV variables */ + uint32_t last; /* number of opcodes */ zend_op *opcodes; ZEND_MAP_PTR_DEF(HashTable *, static_variables_ptr); @@ -539,8 +790,8 @@ struct _zend_op_array { uint32_t *refcount; - int last_live_range; - int last_try_catch; + uint32_t last_live_range; + uint32_t last_try_catch; zend_live_range *live_range; zend_try_catch_element *try_catch_array; @@ -548,7 +799,7 @@ struct _zend_op_array { uint32_t line_start; uint32_t line_end; - int last_literal; + uint32_t last_literal; uint32_t num_dynamic_func_defs; zval *literals; @@ -556,6 +807,10 @@ struct _zend_op_array { * referenced by index from opcodes. */ zend_op_array **dynamic_func_defs; + /* Generic-syntax metadata. NULL on non-generic functions/methods. */ + zend_generic_parameter_list *generic_parameters; + zend_generic_type_table *generic_types; + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; @@ -571,7 +826,7 @@ typedef void (ZEND_FASTCALL *zif_handler)(INTERNAL_FUNCTION_PARAMETERS); typedef struct _zend_internal_function { /* Common elements */ - uint8_t type; + zend_function_type type; uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string* function_name; @@ -579,11 +834,12 @@ typedef struct _zend_internal_function { zend_function *prototype; uint32_t num_args; uint32_t required_num_args; - zend_internal_arg_info *arg_info; + zend_arg_info *arg_info; HashTable *attributes; ZEND_MAP_PTR_DEF(void **, run_time_cache); zend_string *doc_comment; uint32_t T; /* number of temporary variables */ + uint32_t fn_flags2; const zend_property_info *prop_info; /* The corresponding prop_info if this is a hook. */ /* END of common elements */ @@ -596,11 +852,11 @@ typedef struct _zend_internal_function { #define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? ZSTR_VAL((function)->common.scope->name) : "") union _zend_function { - uint8_t type; /* MUST be the first element of this struct! */ + zend_function_type type; /* MUST be the first element of this struct! */ uint32_t quick_arg_flags; struct { - uint8_t type; /* never used */ + zend_function_type type; /* never used */ uint8_t arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string *function_name; @@ -613,6 +869,7 @@ union _zend_function { ZEND_MAP_PTR_DEF(void **, run_time_cache); zend_string *doc_comment; uint32_t T; /* number of temporary variables */ + uint32_t fn_flags2; const zend_property_info *prop_info; /* The corresponding prop_info if this is a hook. */ } common; @@ -630,6 +887,7 @@ struct _zend_execute_data { zend_array *symbol_table; void **run_time_cache; /* cache op_array->run_time_cache */ zend_array *extra_named_params; + zend_type_arg_table *type_args; /* generic type-argument table; NULL when none */ }; #define ZEND_CALL_HAS_THIS IS_OBJECT_EX @@ -865,9 +1123,9 @@ void shutdown_compiler(void); void zend_init_compiler_data_structures(void); void zend_oparray_context_begin(zend_oparray_context *prev_context, zend_op_array *op_array); -void zend_oparray_context_end(zend_oparray_context *prev_context); +void zend_oparray_context_end(const zend_oparray_context *prev_context); void zend_file_context_begin(zend_file_context *prev_context); -void zend_file_context_end(zend_file_context *prev_context); +void zend_file_context_end(const zend_file_context *prev_context); extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type); extern ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename, zend_compile_position position); @@ -879,14 +1137,13 @@ void shutdown_scanner(void); ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename); ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename); ZEND_API zend_string *zend_get_compiled_filename(void); -ZEND_API int zend_get_compiled_lineno(void); +ZEND_API uint32_t zend_get_compiled_lineno(void); ZEND_API size_t zend_get_scanned_file_offset(void); ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var); #ifdef ZTS const char *zend_get_zendtext(void); -int zend_get_zendleng(void); #endif typedef zend_result (ZEND_FASTCALL *unary_op_type)(zval *, zval *); @@ -919,8 +1176,8 @@ uint32_t zend_modifier_list_to_flags(zend_modifier_target target, zend_ast *modi bool zend_handle_encoding_declaration(zend_ast *ast); ZEND_API zend_class_entry *zend_bind_class_in_slot( - zval *class_table_slot, zval *lcname, zend_string *lc_parent_name); -ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname); + zval *class_table_slot, const zval *lcname, zend_string *lc_parent_name); +ZEND_API zend_result do_bind_function(zend_function *func, const zval *lcname); ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name); void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline); @@ -942,14 +1199,14 @@ ZEND_API zend_ast *zend_compile_string_to_ast( ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...); ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handle *file_handle); ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle); -ZEND_API void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size); +ZEND_API void init_op_array(zend_op_array *op_array, zend_function_type type, int initial_ops_size); ZEND_API void destroy_op_array(zend_op_array *op_array); ZEND_API void zend_destroy_static_vars(zend_op_array *op_array); ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle); ZEND_API void zend_cleanup_mutable_class_data(zend_class_entry *ce); ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce); ZEND_API void zend_type_release(zend_type type, bool persistent); -ZEND_API zend_string *zend_create_member_string(zend_string *class_name, zend_string *member_name); +ZEND_API zend_string *zend_create_member_string(const zend_string *class_name, const zend_string *member_name); ZEND_API ZEND_COLD void zend_user_exception_handler(void); @@ -962,7 +1219,8 @@ ZEND_API ZEND_COLD void zend_user_exception_handler(void); } \ } while (0) -void zend_free_internal_arg_info(zend_internal_function *function); +ZEND_API void zend_free_internal_arg_info(zend_internal_function *function, + bool permanent); ZEND_API void destroy_zend_function(zend_function *function); ZEND_API void zend_function_dtor(zval *zv); ZEND_API void destroy_zend_class(zval *zv); @@ -982,7 +1240,7 @@ static zend_always_inline const char *zend_get_unmangled_property_name(const zen #define ZEND_FUNCTION_DTOR zend_function_dtor #define ZEND_CLASS_DTOR destroy_zend_class -typedef bool (*zend_needs_live_range_cb)(zend_op_array *op_array, zend_op *opline); +typedef bool (*zend_needs_live_range_cb)(const zend_op_array *op_array, const zend_op *opline); ZEND_API void zend_recalc_live_ranges( zend_op_array *op_array, zend_needs_live_range_cb needs_live_range); @@ -991,7 +1249,7 @@ ZEND_API bool zend_is_compiling(void); ZEND_API char *zend_make_compiled_string_description(const char *name); ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_handlers); uint32_t zend_get_class_fetch_type(const zend_string *name); -ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, zend_function *fbc, bool result_used); +ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, const zend_function *fbc, bool result_used); ZEND_API bool zend_is_smart_branch(const zend_op *opline); typedef bool (*zend_auto_global_callback)(zend_string *name); @@ -1013,14 +1271,18 @@ int ZEND_FASTCALL zendlex(zend_parser_stack_elem *elem); void zend_assert_valid_class_name(const zend_string *const_name, const char *type); -zend_string *zend_type_to_string_resolved(zend_type type, zend_class_entry *scope); +zend_string *zend_type_to_string_resolved(zend_type type, const zend_class_entry *scope); ZEND_API zend_string *zend_type_to_string(zend_type type); -/* BEGIN: OPCODES */ - -#include "zend_vm_opcodes.h" - -/* END: OPCODES */ +/* Monomorphization: a canonical form of a generic class application like + * "Box>". Stable across permutations of union/intersection + * order so that semantically equivalent type-arg lists hash to the same name + * and resolve to the same synthesized class entry. */ +ZEND_API zend_string *zend_type_to_canonical_string(zend_type type); +ZEND_API zend_string *zend_generic_canonical_class_name( + zend_string *base_name, const zend_type *args, uint32_t arity); +ZEND_API bool zend_type_contains_type_parameter(zend_type type); +ZEND_API bool zend_type_contains_class_scope_type_parameter(zend_type type); /* class fetches */ #define ZEND_FETCH_CLASS_DEFAULT 0 @@ -1030,7 +1292,31 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define ZEND_FETCH_CLASS_AUTO 4 #define ZEND_FETCH_CLASS_INTERFACE 5 #define ZEND_FETCH_CLASS_TRAIT 6 +#define ZEND_FETCH_CLASS_TYPE_PARAM 7 /* function/method-level T */ +#define ZEND_FETCH_CLASS_TYPE_PARAM_CLASS 8 /* class-level T (read from called scope's mono args) */ +#define ZEND_FETCH_CLASS_GENERIC_DEFERRED 9 /* generic application with T-refs (e.g. Box); resolves to a monomorph at runtime */ #define ZEND_FETCH_CLASS_MASK 0x0f +#define ZEND_FETCH_CLASS_TYPE_PARAM_SHIFT 16 + +static zend_always_inline bool zend_fetch_is_type_param(uint32_t fetch_type) { + uint32_t sub = fetch_type & ZEND_FETCH_CLASS_MASK; + return sub == ZEND_FETCH_CLASS_TYPE_PARAM || sub == ZEND_FETCH_CLASS_TYPE_PARAM_CLASS; +} + +static zend_always_inline uint32_t zend_pack_type_param_fetch(uint32_t param_index, uint32_t flags, bool class_level) { + ZEND_ASSERT(param_index < (1u << (32 - ZEND_FETCH_CLASS_TYPE_PARAM_SHIFT))); + uint32_t code = class_level ? ZEND_FETCH_CLASS_TYPE_PARAM_CLASS : ZEND_FETCH_CLASS_TYPE_PARAM; + return code | (param_index << ZEND_FETCH_CLASS_TYPE_PARAM_SHIFT) | flags; +} + +static zend_always_inline uint32_t zend_pack_generic_deferred_fetch(uint32_t args_id, uint32_t flags) { + ZEND_ASSERT(args_id < (1u << (32 - ZEND_FETCH_CLASS_TYPE_PARAM_SHIFT))); + return ZEND_FETCH_CLASS_GENERIC_DEFERRED | (args_id << ZEND_FETCH_CLASS_TYPE_PARAM_SHIFT) | flags; +} + +static zend_always_inline uint32_t zend_unpack_type_param_index(uint32_t fetch_type) { + return fetch_type >> ZEND_FETCH_CLASS_TYPE_PARAM_SHIFT; +} #define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80 #define ZEND_FETCH_CLASS_SILENT 0x0100 #define ZEND_FETCH_CLASS_EXCEPTION 0x0200 @@ -1062,15 +1348,8 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); #define BP_VAR_FUNC_ARG 4 #define BP_VAR_UNSET 5 -#define ZEND_INTERNAL_FUNCTION 1 -#define ZEND_USER_FUNCTION 2 -#define ZEND_EVAL_CODE 4 - #define ZEND_USER_CODE(type) ((type) != ZEND_INTERNAL_FUNCTION) -#define ZEND_INTERNAL_CLASS 1 -#define ZEND_USER_CLASS 2 - #define ZEND_EVAL (1<<0) #define ZEND_INCLUDE (1<<1) #define ZEND_INCLUDE_ONCE (1<<2) @@ -1127,6 +1406,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type); ((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_TENTATIVE_BIT) != 0) #define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce. Set in zend_compile.c for ZEND_AST_DIM nested within ZEND_AST_COALESCE. */ +#define ZEND_ALT_CASE_SYNTAX (1 << 1) /* deprecated switch case terminated by semicolon */ /* Attributes for ${} encaps var in strings (ZEND_AST_DIM or ZEND_AST_VAR node) */ /* ZEND_AST_VAR nodes can have any of the ZEND_ENCAPS_VAR_* flags */ @@ -1206,6 +1486,9 @@ static zend_always_inline bool zend_check_arg_send_type(const zend_function *zf, /* Used to distinguish (parent::$prop)::get() from parent hook call. */ #define ZEND_PARENTHESIZED_STATIC_PROP 1 +/* Used to disallow pipes with arrow functions that lead to confusing parse trees. */ +#define ZEND_PARENTHESIZED_ARROW_FUNC 1 + /* For "use" AST nodes and the seen symbol table */ #define ZEND_SYMBOL_CLASS (1<<0) #define ZEND_SYMBOL_FUNCTION (1<<1) @@ -1217,6 +1500,9 @@ static zend_always_inline bool zend_check_arg_send_type(const zend_function *zf, #define ZEND_IS_BINARY_ASSIGN_OP_OPCODE(opcode) \ (((opcode) >= ZEND_ADD) && ((opcode) <= ZEND_POW)) +/* PFAs/FCCs */ +#define ZEND_PLACEHOLDER_VARIADIC (1<<0) + /* Pseudo-opcodes that are used only temporarily during compilation */ #define ZEND_GOTO 253 #define ZEND_BRK 254 @@ -1308,4 +1594,6 @@ ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, const zval *op); bool zend_try_ct_eval_cast(zval *result, uint32_t type, zval *op1); +bool zend_op_may_elide_result(uint8_t opcode); + #endif /* ZEND_COMPILE_H */ diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h index a44a8b9f70d2..629d7b4437f2 100644 --- a/Zend/zend_config.w32.h +++ b/Zend/zend_config.w32.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index ffad8315ae40..18292203bee9 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -136,62 +135,62 @@ void zend_register_standard_constants(void) null_const = zend_hash_str_find_ptr(EG(zend_constants), "NULL", sizeof("NULL")-1); } -ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number) +ZEND_API zend_constant *zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number) { zend_constant c; ZVAL_NULL(&c.value); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + return zend_register_constant(&c); } -ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, bool bval, int flags, int module_number) +ZEND_API zend_constant *zend_register_bool_constant(const char *name, size_t name_len, bool bval, int flags, int module_number) { zend_constant c; ZVAL_BOOL(&c.value, bval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + return zend_register_constant(&c); } -ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number) +ZEND_API zend_constant *zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number) { zend_constant c; ZVAL_LONG(&c.value, lval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + return zend_register_constant(&c); } -ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number) +ZEND_API zend_constant *zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number) { zend_constant c; ZVAL_DOUBLE(&c.value, dval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + return zend_register_constant(&c); } -ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number) +ZEND_API zend_constant *zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number) { zend_constant c; ZVAL_STR(&c.value, zend_string_init_interned(strval, strlen, flags & CONST_PERSISTENT)); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); - zend_register_constant(&c); + return zend_register_constant(&c); } -ZEND_API void zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number) +ZEND_API zend_constant *zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number) { - zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number); + return zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number); } static zend_constant *zend_get_halt_offset_constant(const char *name, size_t name_len) @@ -251,7 +250,7 @@ ZEND_API zend_constant *_zend_get_special_const(const char *name, size_t len) /* } /* }}} */ -ZEND_API bool zend_verify_const_access(zend_class_constant *c, zend_class_entry *scope) /* {{{ */ +ZEND_API bool zend_verify_const_access(const zend_class_constant *c, const zend_class_entry *scope) /* {{{ */ { if (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_PUBLIC) { return 1; @@ -312,9 +311,9 @@ ZEND_API zval *zend_get_constant(zend_string *name) return NULL; } -ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, zend_class_entry *scope, uint32_t flags) +ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, const zend_class_entry *scope, uint32_t flags) { - zend_class_entry *ce = NULL; + const zend_class_entry *ce = NULL; zend_class_constant *c = NULL; zval *ret_constant = NULL; @@ -413,7 +412,7 @@ ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string * return ret_constant; } -ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags) +ZEND_API zval *zend_get_constant_ex(zend_string *cname, const zend_class_entry *scope, uint32_t flags) { zend_constant *c; const char *colon; @@ -487,12 +486,15 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, CONST_PROTECT_RECURSION(c); zend_deprecated_constant(c, c->name); CONST_UNPROTECT_RECURSION(c); + if (UNEXPECTED(EG(exception))) { + return NULL; + } } } return &c->value; } -static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c) +static void* zend_hash_add_constant(HashTable *ht, zend_string *key, const zend_constant *c) { void *ret; zend_constant *copy = pemalloc(sizeof(zend_constant), ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); @@ -505,11 +507,11 @@ static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_consta return ret; } -ZEND_API zend_result zend_register_constant(zend_constant *c) +ZEND_API zend_constant *zend_register_constant(zend_constant *c) { zend_string *lowercase_name = NULL; zend_string *name; - zend_result ret = SUCCESS; + zend_constant *ret = NULL; bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0; #if 0 @@ -539,9 +541,9 @@ ZEND_API zend_result zend_register_constant(zend_constant *c) /* Check if the user is trying to define any special constant */ if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__") || (!persistent && zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name))) - || zend_hash_add_constant(EG(zend_constants), name, c) == NULL + || (ret = zend_hash_add_constant(EG(zend_constants), name, c)) == NULL ) { - zend_error(E_WARNING, "Constant %s already defined", ZSTR_VAL(name)); + zend_error(E_WARNING, "Constant %s already defined, this will be an error in PHP 9", ZSTR_VAL(name)); zend_string_release(c->name); if (c->filename) { zend_string_release(c->filename); @@ -550,7 +552,6 @@ ZEND_API zend_result zend_register_constant(zend_constant *c) if (!persistent) { zval_ptr_dtor_nogc(&c->value); } - ret = FAILURE; } if (lowercase_name) { zend_string_release(lowercase_name); diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 3912215d8077..9461ac764c90 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -85,19 +84,19 @@ void clean_module_constants(int module_number); void free_zend_constant(zval *zv); void zend_startup_constants(void); void zend_register_standard_constants(void); -ZEND_API bool zend_verify_const_access(zend_class_constant *c, zend_class_entry *ce); +ZEND_API bool zend_verify_const_access(const zend_class_constant *c, const zend_class_entry *ce); ZEND_API zval *zend_get_constant(zend_string *name); ZEND_API zend_constant *zend_get_constant_ptr(zend_string *name); ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len); -ZEND_API zval *zend_get_constant_ex(zend_string *name, zend_class_entry *scope, uint32_t flags); -ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, zend_class_entry *scope, uint32_t flags); -ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, bool bval, int flags, int module_number); -ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number); -ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number); -ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number); -ZEND_API void zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number); -ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number); -ZEND_API zend_result zend_register_constant(zend_constant *c); +ZEND_API zval *zend_get_constant_ex(zend_string *name, const zend_class_entry *scope, uint32_t flags); +ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, const zend_class_entry *scope, uint32_t flags); +ZEND_API zend_constant *zend_register_bool_constant(const char *name, size_t name_len, bool bval, int flags, int module_number); +ZEND_API zend_constant *zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number); +ZEND_API zend_constant *zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number); +ZEND_API zend_constant *zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number); +ZEND_API zend_constant *zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number); +ZEND_API zend_constant *zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number); +ZEND_API zend_constant *zend_register_constant(zend_constant *c); void zend_constant_add_attributes(zend_constant *c, HashTable *attributes); #ifdef ZTS void zend_copy_constants(HashTable *target, HashTable *source); diff --git a/Zend/zend_constants.stub.php b/Zend/zend_constants.stub.php index 763b207641f6..e511dc880866 100644 --- a/Zend/zend_constants.stub.php +++ b/Zend/zend_constants.stub.php @@ -121,20 +121,23 @@ */ const ZEND_DEBUG_BUILD = UNKNOWN; +/** + * @var string + * @cvalue zend_vm_kind_name[ZEND_VM_KIND] + */ +const ZEND_VM_KIND = UNKNOWN; + /* Special constants true/false/null. */ /** - * @var bool * @undocumentable */ const TRUE = true; /** - * @var bool * @undocumentable */ const FALSE = false; /** - * @var null * @undocumentable */ const NULL = null; diff --git a/Zend/zend_constants_arginfo.h b/Zend/zend_constants_arginfo.h index d381bcf64ee1..b10adc02d28a 100644 --- a/Zend/zend_constants_arginfo.h +++ b/Zend/zend_constants_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 5e224893a5fb72b3f93249235c2a1634233ce505 */ +/* This is a generated file, edit zend_constants.stub.php instead. + * Stub hash: 569ccba4e0a93a9ce49c81c76955413188df390e */ static void register_zend_constants_symbols(int module_number) { @@ -14,7 +14,7 @@ static void register_zend_constants_symbols(int module_number) REGISTER_LONG_CONSTANT("E_USER_ERROR", E_USER_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("E_USER_WARNING", E_USER_WARNING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("E_STRICT", E_STRICT, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_E_STRICT = REGISTER_LONG_CONSTANT("E_STRICT", E_STRICT, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("E_RECOVERABLE_ERROR", E_RECOVERABLE_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("E_DEPRECATED", E_DEPRECATED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("E_USER_DEPRECATED", E_USER_DEPRECATED, CONST_PERSISTENT); @@ -23,21 +23,16 @@ static void register_zend_constants_symbols(int module_number) REGISTER_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT); REGISTER_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT); REGISTER_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("ZEND_VM_KIND", zend_vm_kind_name[ZEND_VM_KIND], CONST_PERSISTENT); REGISTER_BOOL_CONSTANT("TRUE", true, CONST_PERSISTENT); REGISTER_BOOL_CONSTANT("FALSE", false, CONST_PERSISTENT); REGISTER_NULL_CONSTANT("NULL", CONST_PERSISTENT); - zend_constant *const_E_STRICT = zend_hash_str_find_ptr(EG(zend_constants), "E_STRICT", sizeof("E_STRICT") - 1); zend_attribute *attribute_Deprecated_const_E_STRICT_0 = zend_add_global_constant_attribute(const_E_STRICT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_const_E_STRICT_0_arg0; - zend_string *attribute_Deprecated_const_E_STRICT_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_const_E_STRICT_0_arg0, attribute_Deprecated_const_E_STRICT_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_E_STRICT_0->args[0].value, &attribute_Deprecated_const_E_STRICT_0_arg0); + ZVAL_STR(&attribute_Deprecated_const_E_STRICT_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_const_E_STRICT_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_const_E_STRICT_0_arg1; zend_string *attribute_Deprecated_const_E_STRICT_0_arg1_str = zend_string_init("the error level was removed", strlen("the error level was removed"), 1); - ZVAL_STR(&attribute_Deprecated_const_E_STRICT_0_arg1, attribute_Deprecated_const_E_STRICT_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_E_STRICT_0->args[1].value, &attribute_Deprecated_const_E_STRICT_0_arg1); + ZVAL_STR(&attribute_Deprecated_const_E_STRICT_0->args[1].value, attribute_Deprecated_const_E_STRICT_0_arg1_str); attribute_Deprecated_const_E_STRICT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/Zend/zend_cpuinfo.c b/Zend/zend_cpuinfo.c index 6264031ceba4..6fc42ca39e6c 100644 --- a/Zend/zend_cpuinfo.c +++ b/Zend/zend_cpuinfo.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Xinchen Hui | +----------------------------------------------------------------------+ @@ -93,21 +92,21 @@ static unsigned get_xcr0_eax(void) { static bool is_avx_supported(void) { if (!(cpuinfo.ecx & ZEND_CPU_FEATURE_AVX)) { /* No support for AVX */ - return 0; + return false; } if (!(cpuinfo.ecx & ZEND_CPU_FEATURE_OSXSAVE)) { /* The operating system does not support XSAVE. */ - return 0; + return false; } if ((get_xcr0_eax() & 0x6) != 0x6) { /* XCR0 SSE and AVX bits must be set. */ - return 0; + return false; } - return 1; + return true; } #else static bool is_avx_supported(void) { - return 0; + return false; } #endif diff --git a/Zend/zend_cpuinfo.h b/Zend/zend_cpuinfo.h index 7e53ba654dd4..513dacfd08f5 100644 --- a/Zend/zend_cpuinfo.h +++ b/Zend/zend_cpuinfo.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Xinchen Hui | +----------------------------------------------------------------------+ @@ -272,8 +271,8 @@ static zend_always_inline int zend_cpu_supports_avx512_vbmi(void) { } #endif -/* __builtin_cpu_supports has pclmul from gcc9 */ -#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) +/* __builtin_cpu_supports has pclmul from gcc9 and clang 19 */ +#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && (!defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 19) || (ZEND_GCC_VERSION >= 9000)) ZEND_NO_SANITIZE_ADDRESS static inline int zend_cpu_supports_pclmul(void) { #ifdef PHP_HAVE_BUILTIN_CPU_INIT @@ -287,8 +286,9 @@ static inline int zend_cpu_supports_pclmul(void) { } #endif -/* __builtin_cpu_supports has cldemote from gcc11 */ -#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(__GNUC__) && (ZEND_GCC_VERSION >= 11000) +/* __builtin_cpu_supports has cldemote from gcc11 and clang 19 */ +#if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && ((defined(__clang__) && (__clang_major__ >= 19)) || (!defined(__clang__) && defined(__GNUC__) && (ZEND_GCC_VERSION >= 11000))) +#define HAVE_ZEND_CPU_SUPPORTS_CLDEMOTE 1 ZEND_NO_SANITIZE_ADDRESS static inline int zend_cpu_supports_cldemote(void) { #ifdef PHP_HAVE_BUILTIN_CPU_INIT diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c index 7ab9b8325a39..cc534e04549d 100644 --- a/Zend/zend_default_classes.c +++ b/Zend/zend_default_classes.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sterling Hughes | | Marcus Boerger | diff --git a/Zend/zend_dtrace.c b/Zend/zend_dtrace.c index dfc43a85139b..1052022f3bed 100644 --- a/Zend/zend_dtrace.c +++ b/Zend/zend_dtrace.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Soria Parra | +----------------------------------------------------------------------+ diff --git a/Zend/zend_dtrace.d b/Zend/zend_dtrace.d index 6920d0e3602a..9ff085031178 100644 --- a/Zend/zend_dtrace.d +++ b/Zend/zend_dtrace.d @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Soria Parra | +----------------------------------------------------------------------+ diff --git a/Zend/zend_dtrace.h b/Zend/zend_dtrace.h index 53ccaca4e407..ada77ce664e3 100644 --- a/Zend/zend_dtrace.h +++ b/Zend/zend_dtrace.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Soria Parra | +----------------------------------------------------------------------+ diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 6baa34cc5012..a5091f6c1b6f 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ilija Tovilo | +----------------------------------------------------------------------+ @@ -36,9 +35,21 @@ ZEND_API zend_class_entry *zend_ce_unit_enum; ZEND_API zend_class_entry *zend_ce_backed_enum; ZEND_API zend_object_handlers zend_enum_object_handlers; -zend_object *zend_enum_new(zval *result, zend_class_entry *ce, zend_string *case_name, zval *backing_value_zv) +static zend_arg_info zarginfo_class_UnitEnum_cases[sizeof(arginfo_class_UnitEnum_cases)/sizeof(zend_internal_arg_info)]; +static zend_arg_info zarginfo_class_BackedEnum_from[sizeof(arginfo_class_BackedEnum_from)/sizeof(zend_internal_arg_info)]; +static zend_arg_info zarginfo_class_BackedEnum_tryFrom[sizeof(arginfo_class_BackedEnum_tryFrom)/sizeof(zend_internal_arg_info)]; + +zend_object *zend_enum_new(zval *result, zend_class_entry *ce, int case_id, zend_string *case_name, zval *backing_value_zv) { - zend_object *zobj = zend_objects_new(ce); + zend_enum_obj *intern = zend_object_alloc(sizeof(*intern), ce); + + zend_object_std_init(&intern->std, ce); + object_properties_init(&intern->std, ce); + + intern->case_id = case_id; + + zend_object *zobj = &intern->std; + GC_ADD_FLAGS(zobj, GC_NOT_COLLECTABLE); ZVAL_OBJ(result, zobj); zval *zname = OBJ_PROP_NUM(zobj, 0); @@ -79,7 +90,7 @@ static void zend_verify_enum_properties(const zend_class_entry *ce) static void zend_verify_enum_magic_methods(const zend_class_entry *ce) { - // Only __get, __call and __invoke are allowed + // Only __get, __call, __debugInfo and __invoke are allowed ZEND_ENUM_DISALLOW_MAGIC_METHOD(constructor, "__construct"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(destructor, "__destruct"); @@ -89,7 +100,6 @@ static void zend_verify_enum_magic_methods(const zend_class_entry *ce) ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unset, "__unset"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__isset, "__isset"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__tostring, "__toString"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__debugInfo, "__debugInfo"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__serialize, "__serialize"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unserialize, "__unserialize"); @@ -165,6 +175,7 @@ void zend_register_enum_ce(void) zend_ce_backed_enum->interface_gets_implemented = zend_implement_backed_enum; memcpy(&zend_enum_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + zend_enum_object_handlers.offset = offsetof(zend_enum_obj, std); zend_enum_object_handlers.clone_obj = NULL; zend_enum_object_handlers.compare = zend_objects_not_comparable; } @@ -445,7 +456,7 @@ void zend_enum_register_funcs(zend_class_entry *ce) cases_function->function_name = ZSTR_KNOWN(ZEND_STR_CASES); cases_function->fn_flags = fn_flags; cases_function->doc_comment = NULL; - cases_function->arg_info = (zend_internal_arg_info *) (arginfo_class_UnitEnum_cases + 1); + cases_function->arg_info = zarginfo_class_UnitEnum_cases + 1; zend_enum_register_func(ce, ZEND_STR_CASES, cases_function); if (ce->enum_backing_type != IS_UNDEF) { @@ -456,7 +467,7 @@ void zend_enum_register_funcs(zend_class_entry *ce) from_function->doc_comment = NULL; from_function->num_args = 1; from_function->required_num_args = 1; - from_function->arg_info = (zend_internal_arg_info *) (arginfo_class_BackedEnum_from + 1); + from_function->arg_info = zarginfo_class_BackedEnum_from + 1; zend_enum_register_func(ce, ZEND_STR_FROM, from_function); zend_internal_function *try_from_function = zend_arena_calloc(&CG(arena), sizeof(zend_internal_function), 1); @@ -466,7 +477,7 @@ void zend_enum_register_funcs(zend_class_entry *ce) try_from_function->doc_comment = NULL; try_from_function->num_args = 1; try_from_function->required_num_args = 1; - try_from_function->arg_info = (zend_internal_arg_info *) (arginfo_class_BackedEnum_tryFrom + 1); + try_from_function->arg_info = zarginfo_class_BackedEnum_tryFrom + 1; zend_enum_register_func(ce, ZEND_STR_TRYFROM_LOWERCASE, try_from_function); } } @@ -528,20 +539,24 @@ ZEND_API zend_class_entry *zend_register_internal_enum( zend_class_implements(ce, 1, zend_ce_backed_enum); } + ce->default_object_handlers = &zend_enum_object_handlers; + return ce; } static zend_ast_ref *create_enum_case_ast( - zend_string *class_name, zend_string *case_name, zval *value) { + zend_string *class_name, int case_id, zend_string *case_name, + zval *value) { // TODO: Use custom node type for enum cases? - size_t size = sizeof(zend_ast_ref) + zend_ast_size(3) - + (value ? 3 : 2) * sizeof(zend_ast_zval); + const size_t num_children = ZEND_AST_CONST_ENUM_INIT >> ZEND_AST_NUM_CHILDREN_SHIFT; + size_t size = sizeof(zend_ast_ref) + zend_ast_size(num_children) + + (value ? num_children : num_children-1) * sizeof(zend_ast_zval); char *p = pemalloc(size, 1); zend_ast_ref *ref = (zend_ast_ref *) p; p += sizeof(zend_ast_ref); GC_SET_REFCOUNT(ref, 1); GC_TYPE_INFO(ref) = GC_CONSTANT_AST | GC_PERSISTENT | GC_IMMUTABLE; - zend_ast *ast = (zend_ast *) p; p += zend_ast_size(3); + zend_ast *ast = (zend_ast *) p; p += zend_ast_size(num_children); ast->kind = ZEND_AST_CONST_ENUM_INIT; ast->attr = 0; ast->lineno = 0; @@ -556,24 +571,47 @@ static zend_ast_ref *create_enum_case_ast( ast->child[1] = (zend_ast *) p; p += sizeof(zend_ast_zval); ast->child[1]->kind = ZEND_AST_ZVAL; ast->child[1]->attr = 0; - ZEND_ASSERT(ZSTR_IS_INTERNED(case_name)); - ZVAL_STR(zend_ast_get_zval(ast->child[1]), case_name); + ZVAL_LONG(zend_ast_get_zval(ast->child[1]), case_id); Z_LINENO_P(zend_ast_get_zval(ast->child[1])) = 0; + ast->child[2] = (zend_ast *) p; p += sizeof(zend_ast_zval); + ast->child[2]->kind = ZEND_AST_ZVAL; + ast->child[2]->attr = 0; + ZEND_ASSERT(ZSTR_IS_INTERNED(case_name)); + ZVAL_STR(zend_ast_get_zval(ast->child[2]), case_name); + Z_LINENO_P(zend_ast_get_zval(ast->child[2])) = 0; + if (value) { - ast->child[2] = (zend_ast *) p; p += sizeof(zend_ast_zval); - ast->child[2]->kind = ZEND_AST_ZVAL; - ast->child[2]->attr = 0; + ast->child[3] = (zend_ast *) p; p += sizeof(zend_ast_zval); + ast->child[3]->kind = ZEND_AST_ZVAL; + ast->child[3]->attr = 0; ZEND_ASSERT(!Z_REFCOUNTED_P(value)); - ZVAL_COPY_VALUE(zend_ast_get_zval(ast->child[2]), value); - Z_LINENO_P(zend_ast_get_zval(ast->child[2])) = 0; + ZVAL_COPY_VALUE(zend_ast_get_zval(ast->child[3]), value); + Z_LINENO_P(zend_ast_get_zval(ast->child[3])) = 0; } else { - ast->child[2] = NULL; + ast->child[3] = NULL; } return ref; } +int zend_enum_next_case_id(zend_class_entry *enum_class) +{ + ZEND_HASH_REVERSE_FOREACH_VAL(&enum_class->constants_table, zval *zv) { + zend_class_constant *c = Z_PTR_P(zv); + if (!(ZEND_CLASS_CONST_FLAGS(c) & ZEND_CLASS_CONST_IS_CASE)) { + continue; + } + ZEND_ASSERT(Z_TYPE(c->value) == IS_CONSTANT_AST); + zend_ast *ast = Z_ASTVAL(c->value); + + ZEND_ASSERT(ast->kind == ZEND_AST_CONST_ENUM_INIT); + return Z_LVAL_P(zend_ast_get_zval(ast->child[1])) + 1; + } ZEND_HASH_FOREACH_END(); + + return 1; +} + ZEND_API void zend_enum_add_case(zend_class_entry *ce, zend_string *case_name, zval *value) { if (value) { @@ -595,9 +633,11 @@ ZEND_API void zend_enum_add_case(zend_class_entry *ce, zend_string *case_name, z ZEND_ASSERT(ce->enum_backing_type == IS_UNDEF); } + int case_id = zend_enum_next_case_id(ce); + zval ast_zv; Z_TYPE_INFO(ast_zv) = IS_CONSTANT_AST; - Z_AST(ast_zv) = create_enum_case_ast(ce->name, case_name, value); + Z_AST(ast_zv) = create_enum_case_ast(ce->name, case_id, case_name, value); zend_class_constant *c = zend_declare_class_constant_ex( ce, case_name, &ast_zv, ZEND_ACC_PUBLIC, NULL); ZEND_CLASS_CONST_FLAGS(c) |= ZEND_CLASS_CONST_IS_CASE; @@ -632,3 +672,16 @@ ZEND_API zend_object *zend_enum_get_case_cstr(zend_class_entry *ce, const char * zend_class_constant *c = zend_hash_str_find_ptr(CE_CONSTANTS_TABLE(ce), name, strlen(name)); return zend_enum_case_from_class_constant(c); } + +void zend_enum_startup(void) +{ + for (size_t i = 0; i < sizeof(zarginfo_class_UnitEnum_cases)/sizeof(zend_arg_info); i++) { + zend_convert_internal_arg_info(&zarginfo_class_UnitEnum_cases[i], &arginfo_class_UnitEnum_cases[i], i == 0, true); + } + for (size_t i = 0; i < sizeof(zarginfo_class_BackedEnum_from)/sizeof(zend_arg_info); i++) { + zend_convert_internal_arg_info(&zarginfo_class_BackedEnum_from[i], &arginfo_class_BackedEnum_from[i], i == 0, true); + } + for (size_t i = 0; i < sizeof(zarginfo_class_BackedEnum_tryFrom)/sizeof(zend_arg_info); i++) { + zend_convert_internal_arg_info(&zarginfo_class_BackedEnum_tryFrom[i], &arginfo_class_BackedEnum_tryFrom[i], i == 0, true); + } +} diff --git a/Zend/zend_enum.h b/Zend/zend_enum.h index 7b3b0184b4eb..6bffb8866507 100644 --- a/Zend/zend_enum.h +++ b/Zend/zend_enum.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ilija Tovilo | +----------------------------------------------------------------------+ @@ -30,13 +29,25 @@ extern ZEND_API zend_class_entry *zend_ce_unit_enum; extern ZEND_API zend_class_entry *zend_ce_backed_enum; extern ZEND_API zend_object_handlers zend_enum_object_handlers; +typedef struct zend_enum_obj { + int case_id; + zend_object std; +} zend_enum_obj; + +static inline zend_enum_obj *zend_enum_obj_from_obj(zend_object *zobj) { + ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM); + return ZEND_CONTAINER_OF(zobj, zend_enum_obj, std); +} + +void zend_enum_startup(void); void zend_register_enum_ce(void); void zend_enum_add_interfaces(zend_class_entry *ce); zend_result zend_enum_build_backed_enum_table(zend_class_entry *ce); -zend_object *zend_enum_new(zval *result, zend_class_entry *ce, zend_string *case_name, zval *backing_value_zv); +zend_object *zend_enum_new(zval *result, zend_class_entry *ce, int case_id, zend_string *case_name, zval *backing_value_zv); void zend_verify_enum(const zend_class_entry *ce); void zend_enum_register_funcs(zend_class_entry *ce); void zend_enum_register_props(zend_class_entry *ce); +int zend_enum_next_case_id(zend_class_entry *enum_class); ZEND_API zend_class_entry *zend_register_internal_enum( const char *name, uint8_t type, const zend_function_entry *functions); @@ -46,10 +57,19 @@ ZEND_API zend_object *zend_enum_get_case(zend_class_entry *ce, zend_string *name ZEND_API zend_object *zend_enum_get_case_cstr(zend_class_entry *ce, const char *name); ZEND_API zend_result zend_enum_get_case_by_value(zend_object **result, zend_class_entry *ce, zend_long long_key, zend_string *string_key, bool try_from); +static zend_always_inline int zend_enum_fetch_case_id(zend_object *zobj) +{ + ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM); + return zend_enum_obj_from_obj(zobj)->case_id; +} + static zend_always_inline zval *zend_enum_fetch_case_name(zend_object *zobj) { ZEND_ASSERT(zobj->ce->ce_flags & ZEND_ACC_ENUM); - return OBJ_PROP_NUM(zobj, 0); + + zval *name = OBJ_PROP_NUM(zobj, 0); + ZEND_ASSERT(Z_TYPE_P(name) == IS_STRING); + return name; } static zend_always_inline zval *zend_enum_fetch_case_value(zend_object *zobj) diff --git a/Zend/zend_enum_arginfo.h b/Zend/zend_enum_arginfo.h index 64c36ff3c33a..d86191e9afbb 100644 --- a/Zend/zend_enum_arginfo.h +++ b/Zend/zend_enum_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit zend_enum.stub.php instead. * Stub hash: 7092f1d4ba651f077cff37050899f090f00abf22 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_UnitEnum_cases, 0, 0, IS_ARRAY, 0) diff --git a/Zend/zend_errors.h b/Zend/zend_errors.h index 954be61a0aec..831e4a9b912a 100644 --- a/Zend/zend_errors.h +++ b/Zend/zend_errors.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 212fe3cb7ab6..d23fb647af9d 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Marcus Boerger | @@ -36,7 +35,6 @@ #define ZEND_EXCEPTION_LINE_OFF 4 #define ZEND_EXCEPTION_TRACE_OFF 5 #define ZEND_EXCEPTION_PREVIOUS_OFF 6 -#define ZEND_EXCEPTION_SEVERITY_OFF 7 ZEND_API zend_class_entry *zend_ce_throwable; ZEND_API zend_class_entry *zend_ce_exception; @@ -67,7 +65,7 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr { /* zend_ce_exception and zend_ce_error may not be initialized yet when this is called (e.g when * implementing Throwable for Exception itself). Perform a manual inheritance check. */ - zend_class_entry *root = class_type; + const zend_class_entry *root = class_type; while (root->parent) { root = root->parent; } @@ -89,13 +87,13 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr } /* }}} */ -static inline zend_class_entry *i_get_exception_base(zend_object *object) /* {{{ */ +static inline zend_class_entry *i_get_exception_base(const zend_object *object) /* {{{ */ { return instanceof_function(object->ce, zend_ce_exception) ? zend_ce_exception : zend_ce_error; } /* }}} */ -ZEND_API zend_class_entry *zend_get_exception_base(zend_object *object) /* {{{ */ +ZEND_API zend_class_entry *zend_get_exception_base(const zend_object *object) /* {{{ */ { return i_get_exception_base(object); } @@ -146,31 +144,6 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo } /* }}} */ -void zend_exception_save(void) /* {{{ */ -{ - if (EG(prev_exception)) { - zend_exception_set_previous(EG(exception), EG(prev_exception)); - } - if (EG(exception)) { - EG(prev_exception) = EG(exception); - } - EG(exception) = NULL; -} -/* }}} */ - -void zend_exception_restore(void) /* {{{ */ -{ - if (EG(prev_exception)) { - if (EG(exception)) { - zend_exception_set_previous(EG(exception), EG(prev_exception)); - } else { - EG(exception) = EG(prev_exception); - } - EG(prev_exception) = NULL; - } -} -/* }}} */ - static zend_always_inline bool is_handle_exception_set(void) { zend_execute_data *execute_data = EG(current_execute_data); return !execute_data @@ -192,7 +165,7 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /* #endif /* HAVE_DTRACE */ if (exception != NULL) { - zend_object *previous = EG(exception); + const zend_object *previous = EG(exception); if (previous && zend_is_unwind_exit(previous)) { /* Don't replace unwinding exception with different exception. */ OBJ_RELEASE(exception); @@ -242,10 +215,6 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception) /* ZEND_API void zend_clear_exception(void) /* {{{ */ { zend_object *exception; - if (EG(prev_exception)) { - OBJ_RELEASE(EG(prev_exception)); - EG(prev_exception) = NULL; - } if (!EG(exception)) { return; } @@ -274,7 +243,7 @@ static void zend_update_property_num_checked(zend_class_entry *scope, zend_objec return; } #if ZEND_DEBUG - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = i_get_exception_base(object); const zend_property_info *prop_info = zend_get_property_info(object->ce, member, true); ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == prop_num); @@ -401,7 +370,7 @@ ZEND_METHOD(ErrorException, __construct) { zend_string *message = NULL, *filename = NULL; zend_long code = 0, severity = E_ERROR, lineno; - bool lineno_is_null = 1; + bool lineno_is_null = true; zval tmp, *object, *previous = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|SllS!l!O!", &message, &code, &severity, &filename, &lineno, &lineno_is_null, &previous, zend_ce_throwable) == FAILURE) { @@ -415,7 +384,7 @@ ZEND_METHOD(ErrorException, __construct) } ZVAL_LONG(&tmp, severity); - zend_update_property_num_checked(NULL, Z_OBJ_P(object), ZEND_EXCEPTION_SEVERITY_OFF, ZSTR_KNOWN(ZEND_STR_SEVERITY), &tmp); + zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_SEVERITY), &tmp); if (UNEXPECTED(EG(exception))) { RETURN_THROWS(); } @@ -527,12 +496,12 @@ ZEND_METHOD(ErrorException, getSeverity) #define TRACE_APPEND_KEY(key) do { \ tmp = zend_hash_find(ht, key); \ if (tmp) { \ - if (Z_TYPE_P(tmp) != IS_STRING) { \ + if (UNEXPECTED(Z_TYPE_P(tmp) != IS_STRING)) { \ zend_error(E_WARNING, "Value for %s is not a string", \ ZSTR_VAL(key)); \ smart_str_appends(str, "[unknown]"); \ } else { \ - smart_str_appends(str, Z_STRVAL_P(tmp)); \ + smart_str_append(str, Z_STR_P(tmp)); \ } \ } \ } while (0) @@ -562,6 +531,7 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ case IS_OBJECT: { zend_string *class_name = Z_OBJ_HANDLER_P(arg, get_class_name)(Z_OBJ_P(arg)); smart_str_appends(str, "Object("); + /* cut off on NULL byte ... class@anonymous */ smart_str_appends(str, ZSTR_VAL(class_name)); smart_str_appends(str, "), "); zend_string_release_ex(class_name, 0); @@ -603,7 +573,16 @@ static void _build_trace_string(smart_str *str, const HashTable *ht, uint32_t nu } else { smart_str_appends(str, "[internal function]: "); } - TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_CLASS)); + const zval *class_name = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_CLASS)); + if (class_name) { + if (UNEXPECTED(Z_TYPE_P(class_name) != IS_STRING)) { + zend_error(E_WARNING, "Value for class is not a string"); + smart_str_appends(str, "[unknown]"); + } else { + /* cut off on NULL byte ... class@anonymous */ + smart_str_appends(str, Z_STRVAL_P(class_name)); + } + } TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_TYPE)); TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_FUNCTION)); smart_str_appendc(str, '('); @@ -695,16 +674,33 @@ ZEND_METHOD(Exception, __toString) zval trace, *exception; zend_class_entry *base_ce; zend_string *str; - zend_fcall_info fci; zval rv, tmp; - zend_string *fname; ZEND_PARSE_PARAMETERS_NONE(); str = ZSTR_EMPTY_ALLOC(); exception = ZEND_THIS; - fname = ZSTR_INIT_LITERAL("gettraceasstring", 0); + base_ce = i_get_exception_base(Z_OBJ_P(exception)); + + /* As getTraceAsString method is final we can grab it once */ + zend_function *getTraceAsString = zend_hash_str_find_ptr(&base_ce->function_table, ZEND_STRL("gettraceasstring")); + ZEND_ASSERT(getTraceAsString && "Method getTraceAsString must exist"); + + + zend_fcall_info fci; + fci.size = sizeof(fci); + ZVAL_UNDEF(&fci.function_name); + fci.retval = &trace; + fci.param_count = 0; + fci.params = NULL; + fci.object = NULL; + fci.named_params = NULL; + + zend_fcall_info_cache fcc; + fcc.function_handler = getTraceAsString; + fcc.called_scope = base_ce; + fcc.closure = NULL; while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) { zend_string *prev_str = str; @@ -712,15 +708,9 @@ ZEND_METHOD(Exception, __toString) zend_string *file = zval_get_string(GET_PROPERTY(exception, ZEND_STR_FILE)); zend_long line = zval_get_long(GET_PROPERTY(exception, ZEND_STR_LINE)); - fci.size = sizeof(fci); - ZVAL_STR(&fci.function_name, fname); - fci.object = Z_OBJ_P(exception); - fci.retval = &trace; - fci.param_count = 0; - fci.params = NULL; - fci.named_params = NULL; - - zend_call_function(&fci, NULL); + fcc.object = Z_OBJ_P(exception); + fcc.calling_scope = Z_OBJCE_P(exception); + zend_call_function(&fci, &fcc); if (Z_TYPE(trace) != IS_STRING) { zval_ptr_dtor(&trace); @@ -765,11 +755,11 @@ ZEND_METHOD(Exception, __toString) break; } } - zend_string_release_ex(fname, 0); exception = ZEND_THIS; /* Reset apply counts */ - while (Z_TYPE_P(exception) == IS_OBJECT && (base_ce = i_get_exception_base(Z_OBJ_P(exception))) && instanceof_function(Z_OBJCE_P(exception), base_ce)) { + zend_class_entry *previous_base_ce; + while (Z_TYPE_P(exception) == IS_OBJECT && (previous_base_ce = i_get_exception_base(Z_OBJ_P(exception))) && instanceof_function(Z_OBJCE_P(exception), previous_base_ce)) { if (Z_IS_RECURSIVE_P(exception)) { Z_UNPROTECT_RECURSION_P(exception); } else { @@ -779,13 +769,10 @@ ZEND_METHOD(Exception, __toString) ZVAL_DEREF(exception); } - exception = ZEND_THIS; - base_ce = i_get_exception_base(Z_OBJ_P(exception)); - /* We store the result in the private property string so we can access * the result in uncaught exception handlers without memleaks. */ ZVAL_STR(&tmp, str); - zend_update_property_ex(base_ce, Z_OBJ_P(exception), ZSTR_KNOWN(ZEND_STR_STRING), &tmp); + zend_update_property_ex(base_ce, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_STRING), &tmp); RETURN_STR(str); } @@ -846,20 +833,6 @@ void zend_register_default_exception(void) /* {{{ */ } /* }}} */ -/* {{{ Deprecated - Use zend_ce_exception directly instead */ -ZEND_API zend_class_entry *zend_exception_get_default(void) -{ - return zend_ce_exception; -} -/* }}} */ - -/* {{{ Deprecated - Use zend_ce_error_exception directly instead */ -ZEND_API zend_class_entry *zend_get_error_exception(void) -{ - return zend_ce_error_exception; -} -/* }}} */ - static zend_object *zend_throw_exception_zstr(zend_class_entry *exception_ce, zend_string *message, zend_long code) /* {{{ */ { zval ex, tmp; diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index 35f669955942..f9b472598012 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Marcus Boerger | @@ -41,20 +40,12 @@ extern ZEND_API zend_class_entry *zend_ce_unhandled_match_error; extern ZEND_API zend_class_entry *zend_ce_request_parse_body_exception; ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *add_previous); -ZEND_API void zend_exception_save(void); -ZEND_API void zend_exception_restore(void); ZEND_API ZEND_COLD void zend_throw_exception_internal(zend_object *exception); void zend_register_default_exception(void); -ZEND_API zend_class_entry *zend_get_exception_base(zend_object *object); - -/* Deprecated - Use zend_ce_exception directly instead */ -ZEND_API zend_class_entry *zend_exception_get_default(void); - -/* Deprecated - Use zend_ce_error_exception directly instead */ -ZEND_API zend_class_entry *zend_get_error_exception(void); +ZEND_API zend_class_entry *zend_get_exception_base(const zend_object *object); ZEND_API void zend_register_default_classes(void); diff --git a/Zend/zend_exceptions_arginfo.h b/Zend/zend_exceptions_arginfo.h index cef37a1f0f0b..4706161a09af 100644 --- a/Zend/zend_exceptions_arginfo.h +++ b/Zend/zend_exceptions_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit zend_exceptions.stub.php instead. * Stub hash: ba1562ca8fe2fe48c40bc52d10545aa989afd86c */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Throwable_getMessage, 0, 0, IS_STRING, 0) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 5d8d9f4caeb8..89a83e3c678f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -136,8 +135,7 @@ static ZEND_FUNCTION(pass) { } -ZEND_BEGIN_ARG_INFO_EX(zend_pass_function_arg_info, 0, 0, 0) -ZEND_END_ARG_INFO() +static zend_arg_info zend_pass_function_arg_info[1] = {0}; ZEND_API const zend_internal_function zend_pass_function = { ZEND_INTERNAL_FUNCTION, /* type */ @@ -148,11 +146,12 @@ ZEND_API const zend_internal_function zend_pass_function = { NULL, /* prototype */ 0, /* num_args */ 0, /* required_num_args */ - (zend_internal_arg_info *) zend_pass_function_arg_info + 1, /* arg_info */ + zend_pass_function_arg_info + 1, /* arg_info */ NULL, /* attributes */ NULL, /* run_time_cache */ NULL, /* doc_comment */ 0, /* T */ + 0, /* fn_flags2 */ NULL, /* prop_info */ ZEND_FN(pass), /* handler */ NULL, /* module */ @@ -605,7 +604,7 @@ static zend_never_inline ZEND_COLD zval *zend_wrong_assign_to_variable_reference return zend_assign_to_variable_ex(variable_ptr, value_ptr, IS_TMP_VAR, EX_USES_STRICT_TYPES(), garbage_ptr); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num) { const zend_execute_data *execute_data = EG(current_execute_data); zend_string *func_name = get_function_or_method_name(EX(call)->func); @@ -647,7 +646,7 @@ static zend_never_inline ZEND_COLD void zend_throw_access_uninit_prop_by_ref_err } /* this should modify object only if it's empty */ -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(const zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(const zval *object, const zval *property OPLINE_DC EXECUTE_DATA_DC) { zend_string *tmp_property_name; zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); @@ -681,7 +680,7 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_erro } } -static ZEND_COLD void zend_verify_type_error_common( +static zend_never_inline ZEND_COLD void zend_verify_type_error_common( const zend_function *zf, const zend_arg_info *arg_info, const zval *value, const char **fname, const char **fsep, const char **fclass, zend_string **need_msg, const char **given_kind) @@ -704,7 +703,7 @@ static ZEND_COLD void zend_verify_type_error_common( } } -ZEND_API ZEND_COLD void zend_verify_arg_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value) { const zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; @@ -734,8 +733,6 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg) { zend_long lval; double dval; - zend_string *str; - bool bval; /* Type preference order: int -> float -> string -> bool */ if (type_mask & MAY_BE_LONG) { @@ -746,36 +743,43 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg) if (type == IS_LONG) { zend_string_release(Z_STR_P(arg)); ZVAL_LONG(arg, lval); - return 1; + return true; } if (type == IS_DOUBLE) { zend_string_release(Z_STR_P(arg)); ZVAL_DOUBLE(arg, dval); - return 1; + return true; } } else if (zend_parse_arg_long_weak(arg, &lval, 0)) { zval_ptr_dtor(arg); ZVAL_LONG(arg, lval); - return 1; + return true; } else if (UNEXPECTED(EG(exception))) { - return 0; + return false; } } - if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, 0)) { - zval_ptr_dtor(arg); - ZVAL_DOUBLE(arg, dval); - return 1; + if (type_mask & MAY_BE_DOUBLE) { + dval = zend_parse_arg_double_weak(arg, 0); + if (EXPECTED(!zend_isnan(dval))) { + zval_ptr_dtor(arg); + ZVAL_DOUBLE(arg, dval); + return true; + } } - if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, &str, 0)) { + if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, 0)) { /* on success "arg" is converted to IS_STRING */ - return 1; + return true; } - if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, 0)) { + if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL) { + zpp_parse_bool_status bval = zend_parse_arg_bool_weak(arg, 0); + if (UNEXPECTED(bval == ZPP_PARSE_BOOL_STATUS_ERROR)) { + return false; + } zval_ptr_dtor(arg); ZVAL_BOOL(arg, bval); - return 1; + return true; } - return 0; + return false; } #if ZEND_DEBUG @@ -794,24 +798,22 @@ static bool can_convert_to_string(const zval *zv) { static bool zend_verify_weak_scalar_type_hint_no_sideeffect(uint32_t type_mask, const zval *arg) { zend_long lval; - double dval; - bool bval; /* Pass (uint32_t)-1 as arg_num to indicate to ZPP not to emit any deprecation notice, * this is needed because the version with side effects also uses 0 (e.g. for typed properties) */ if ((type_mask & MAY_BE_LONG) && zend_parse_arg_long_weak(arg, &lval, (uint32_t)-1)) { - return 1; + return true; } - if ((type_mask & MAY_BE_DOUBLE) && zend_parse_arg_double_weak(arg, &dval, (uint32_t)-1)) { - return 1; + if ((type_mask & MAY_BE_DOUBLE) && !zend_isnan(zend_parse_arg_double_weak(arg, (uint32_t)-1))) { + return true; } if ((type_mask & MAY_BE_STRING) && can_convert_to_string(arg)) { - return 1; + return true; } - if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, &bval, (uint32_t)-1)) { - return 1; + if ((type_mask & MAY_BE_BOOL) == MAY_BE_BOOL && zend_parse_arg_bool_weak(arg, (uint32_t)-1) != ZPP_PARSE_BOOL_STATUS_ERROR) { + return true; } - return 0; + return false; } #endif @@ -836,7 +838,7 @@ ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool s return zend_verify_weak_scalar_type_hint(type_mask, arg); } -ZEND_COLD zend_never_inline void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant) +static zend_never_inline ZEND_COLD void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant) { zend_string *type_str = zend_type_to_string(c->type); @@ -846,7 +848,7 @@ ZEND_COLD zend_never_inline void zend_verify_class_constant_type_error(const zen zend_string_release(type_str); } -ZEND_COLD zend_never_inline void zend_verify_property_type_error(const zend_property_info *info, const zval *property) +static zend_never_inline ZEND_COLD void zend_verify_property_type_error(const zend_property_info *info, const zval *property) { zend_string *type_str; @@ -864,7 +866,7 @@ ZEND_COLD zend_never_inline void zend_verify_property_type_error(const zend_prop zend_string_release(type_str); } -ZEND_COLD zend_never_inline void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property) +static zend_never_inline ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property) { /* we _may_ land here in case reading already errored and runtime cache thus has not been updated (i.e. it contains a valid but unrelated info) */ if (EG(exception)) { @@ -881,7 +883,7 @@ ZEND_COLD zend_never_inline void zend_magic_get_property_type_inconsistency_erro zend_string_release(type_str); } -ZEND_COLD void zend_match_unhandled_error(const zval *value) +zend_never_inline ZEND_COLD void zend_match_unhandled_error(const zval *value) { zend_long max_len = EG(exception_string_param_max_len); smart_str msg = {0}; @@ -901,38 +903,38 @@ ZEND_COLD void zend_match_unhandled_error(const zval *value) smart_str_free(&msg); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error( const zend_property_info *info) { zend_readonly_property_modification_error_ex( ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex( const char *class_name, const char *prop_name) { zend_throw_error(NULL, "Cannot modify readonly property %s::$%s", class_name, prop_name); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info) { zend_throw_error(NULL, "Cannot indirectly modify readonly property %s::$%s", ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(const uint8_t type) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(const uint8_t type) { zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(type)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info) { zend_throw_error(NULL, "Object was released while assigning to property %s::$%s", ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( const zend_property_info *prop_info, const char *operation ) { - zend_class_entry *scope; + const zend_class_entry *scope; if (EG(fake_scope)) { scope = EG(fake_scope); } else { @@ -1051,7 +1053,7 @@ static zend_always_inline bool i_zend_check_property_type(const zend_property_in uint32_t type_mask = ZEND_TYPE_FULL_MASK(info->type); ZEND_ASSERT(!(type_mask & (MAY_BE_CALLABLE|MAY_BE_STATIC|MAY_BE_NEVER|MAY_BE_VOID))); - return zend_verify_scalar_type_hint(type_mask, property, strict, 0); + return zend_verify_scalar_type_hint(type_mask, property, strict, false); } static zend_always_inline bool i_zend_verify_property_type(const zend_property_info *info, zval *property, bool strict) @@ -1213,8 +1215,7 @@ static zend_always_inline bool zend_check_type_slow( } static zend_always_inline bool zend_check_type( - const zend_type *type, zval *arg, zend_class_entry *scope, - bool is_return_type, bool is_internal) + const zend_type *type, zval *arg, bool is_return_type, bool is_internal) { const zend_reference *ref = NULL; ZEND_ASSERT(ZEND_TYPE_IS_SET(*type)); @@ -1246,7 +1247,7 @@ static zend_always_inline bool zend_verify_recv_arg_type(const zend_function *zf cur_arg_info = &zf->common.arg_info[arg_num-1]; if (ZEND_TYPE_IS_SET(cur_arg_info->type) - && UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, zf->common.scope, 0, 0))) { + && UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, false, false))) { zend_verify_arg_error(zf, cur_arg_info, arg_num, arg); return 0; } @@ -1258,7 +1259,7 @@ static zend_always_inline bool zend_verify_variadic_arg_type( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, zval *arg) { ZEND_ASSERT(ZEND_TYPE_IS_SET(arg_info->type)); - if (UNEXPECTED(!zend_check_type(&arg_info->type, arg, zf->common.scope, 0, 0))) { + if (UNEXPECTED(!zend_check_type(&arg_info->type, arg, false, false))) { zend_verify_arg_error(zf, arg_info, arg_num, arg); return 0; } @@ -1283,7 +1284,7 @@ static zend_never_inline ZEND_ATTRIBUTE_UNUSED bool zend_verify_internal_arg_typ } if (ZEND_TYPE_IS_SET(cur_arg_info->type) - && UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, fbc->common.scope, 0, /* is_internal */ 1))) { + && UNEXPECTED(!zend_check_type(&cur_arg_info->type, arg, false, /* is_internal */ true))) { return 0; } arg++; @@ -1316,13 +1317,14 @@ ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_exe if ((fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) && !zend_verify_internal_arg_types(fbc, call)) { + zend_clear_exception(); return 1; } return 0; } -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc) +ZEND_API zend_never_inline ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc) { zend_error_noreturn(E_ERROR, "Arginfo / zpp mismatch during call of %s%s%s()", fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", @@ -1393,7 +1395,7 @@ static void zend_verify_internal_func_info(const zend_function *fn, const zval * } #endif -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data) { const zend_execute_data *ptr = EX(prev_execute_data); @@ -1418,7 +1420,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_ } } -ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value) +ZEND_API zend_never_inline ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1434,7 +1436,7 @@ ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zend_string_release(need_msg); } -ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf) +ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error(const zend_function *zf) { zend_string *func_name = get_function_or_method_name(zf); @@ -1445,7 +1447,7 @@ ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf) } #if ZEND_DEBUG -static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value) +static zend_never_inline ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1459,7 +1461,7 @@ static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, fclass, fsep, fname, ZSTR_VAL(need_msg), given_msg); } -static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind) +static zend_never_inline ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind) { const char *fname = ZSTR_VAL(zf->common.function_name); const char *fsep; @@ -1479,7 +1481,7 @@ static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, con ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *ret) { - const zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1; + const zend_arg_info *ret_info = zf->internal_function.arg_info - 1; if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_VOID) { if (UNEXPECTED(Z_TYPE_P(ret) != IS_NULL)) { @@ -1489,7 +1491,7 @@ ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *re return 1; } - if (UNEXPECTED(!zend_check_type(&ret_info->type, ret, NULL, 1, /* is_internal */ 1))) { + if (UNEXPECTED(!zend_check_type(&ret_info->type, ret, true, /* is_internal */ true))) { zend_verify_internal_return_error(zf, ret); return 0; } @@ -1498,7 +1500,7 @@ ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *re } #endif -static ZEND_COLD void zend_verify_missing_return_type(const zend_function *zf) +static zend_never_inline ZEND_COLD void zend_verify_missing_return_type(const zend_function *zf) { /* VERIFY_RETURN_TYPE is not emitted for "void" functions, so this is always an error. */ zend_verify_return_error(zf, NULL); @@ -1710,7 +1712,7 @@ static zend_never_inline void zend_binary_assign_op_typed_prop(const zend_proper } } -static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type EXECUTE_DATA_DC) +static zend_never_inline zend_long zend_check_string_offset(const zval *dim, int type EXECUTE_DATA_DC) { zend_long offset; @@ -1732,10 +1734,13 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type zend_illegal_string_offset(dim, type); return 0; } + case IS_DOUBLE: + /* Suppress potential double warning */ + zend_error(E_WARNING, "String offset cast occurred"); + return zend_dval_to_lval_silent(Z_DVAL_P(dim)); case IS_UNDEF: ZVAL_UNDEFINED_OP2(); ZEND_FALLTHROUGH; - case IS_DOUBLE: case IS_NULL: case IS_FALSE: case IS_TRUE: @@ -1752,7 +1757,7 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type return zval_get_long_func(dim, /* is_strict */ false); } -ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void) +ZEND_API zend_never_inline ZEND_COLD void zend_wrong_string_offset_error(void) { const char *msg = NULL; const zend_execute_data *execute_data = EG(current_execute_data); @@ -1786,10 +1791,10 @@ ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void) case ZEND_FETCH_DIM_INCDEC: msg = "Cannot increment/decrement string offsets"; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } ZEND_ASSERT(msg != NULL); zend_throw_error(NULL, "%s", msg); @@ -2006,6 +2011,27 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_constant(const zend_consta zend_string_release(message_suffix); } +ZEND_API ZEND_COLD void zend_use_of_deprecated_trait( + zend_class_entry *trait, + const zend_string *used_by +) { + zend_string *message_suffix = ZSTR_EMPTY_ALLOC(); + + if (get_deprecation_suffix_from_attribute(trait->attributes, trait, &message_suffix) == FAILURE) { + return; + } + + int code = trait->type == ZEND_INTERNAL_CLASS ? E_DEPRECATED : E_USER_DEPRECATED; + + zend_error_unchecked(code, "Trait %s used by %s is deprecated%S", + ZSTR_VAL(trait->name), + ZSTR_VAL(used_by), + message_suffix + ); + + zend_string_release(message_suffix); +} + ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void) { zend_error(E_DEPRECATED, "Automatic conversion of false to array is deprecated"); @@ -2161,8 +2187,7 @@ static zend_property_info *zend_get_prop_not_accepting_double(zend_reference *re return NULL; } -static ZEND_COLD zend_long zend_throw_incdec_ref_error( - zend_reference *ref, zend_property_info *error_prop OPLINE_DC) +static zend_never_inline ZEND_COLD zend_long zend_throw_incdec_ref_error(const zend_property_info *error_prop OPLINE_DC) { zend_string *type_str = zend_type_to_string(error_prop->type); if (ZEND_IS_INCREMENT(opline->opcode)) { @@ -2184,7 +2209,7 @@ static ZEND_COLD zend_long zend_throw_incdec_ref_error( } } -static ZEND_COLD zend_long zend_throw_incdec_prop_error(zend_property_info *prop OPLINE_DC) { +static zend_never_inline ZEND_COLD zend_long zend_throw_incdec_prop_error(const zend_property_info *prop OPLINE_DC) { zend_string *type_str = zend_type_to_string(prop->type); if (ZEND_IS_INCREMENT(opline->opcode)) { zend_type_error("Cannot increment property %s::$%s of type %s past its maximal value", @@ -2223,7 +2248,7 @@ static void zend_incdec_typed_ref(zend_reference *ref, zval *copy OPLINE_DC EXEC if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(copy) == IS_LONG) { zend_property_info *error_prop = zend_get_prop_not_accepting_double(ref); if (UNEXPECTED(error_prop)) { - zend_long val = zend_throw_incdec_ref_error(ref, error_prop OPLINE_CC); + zend_long val = zend_throw_incdec_ref_error(error_prop OPLINE_CC); ZVAL_LONG(var_ptr, val); } } else if (UNEXPECTED(!zend_verify_ref_assignable_zval(ref, var_ptr, EX_USES_STRICT_TYPES()))) { @@ -2235,7 +2260,7 @@ static void zend_incdec_typed_ref(zend_reference *ref, zval *copy OPLINE_DC EXEC } } -static void zend_incdec_typed_prop(zend_property_info *prop_info, zval *var_ptr, zval *copy OPLINE_DC EXECUTE_DATA_DC) +static void zend_incdec_typed_prop(const zend_property_info *prop_info, zval *var_ptr, zval *copy OPLINE_DC EXECUTE_DATA_DC) { zval tmp; @@ -2265,7 +2290,7 @@ static void zend_incdec_typed_prop(zend_property_info *prop_info, zval *var_ptr, } } -static void zend_pre_incdec_property_zval(zval *prop, zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) +static void zend_pre_incdec_property_zval(zval *prop, const zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) { if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { if (ZEND_IS_INCREMENT(opline->opcode)) { @@ -2303,7 +2328,7 @@ static void zend_pre_incdec_property_zval(zval *prop, zend_property_info *prop_i } } -static void zend_post_incdec_property_zval(zval *prop, zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) +static void zend_post_incdec_property_zval(zval *prop, const zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) { if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(prop)); @@ -2531,13 +2556,13 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(co zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(method)); } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_method_call(zval *object, zval *function_name) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_method_call(const zval *object, const zval *function_name) { zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_zval_value_name(object)); } -ZEND_API void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc) { zend_throw_error( zend_ce_error, @@ -2595,7 +2620,7 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_err } #endif /* ZEND_CHECK_STACK_LIMIT */ -static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) +static ZEND_COLD void zend_binary_assign_op_dim_slow(const zval *container, const zval *dim OPLINE_DC EXECUTE_DATA_DC) { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (opline->op2_type == IS_UNUSED) { @@ -2629,24 +2654,36 @@ static zend_never_inline uint8_t slow_index_convert(HashTable *ht, const zval *d ZEND_FALLTHROUGH; } case IS_NULL: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return IS_NULL; + } + + if (EG(exception)) { + return IS_NULL; + } + value->str = ZSTR_EMPTY_ALLOC(); return IS_STRING; case IS_DOUBLE: - value->lval = zend_dval_to_lval(Z_DVAL_P(dim)); - if (!zend_is_long_compatible(Z_DVAL_P(dim), value->lval)) { - /* The array may be destroyed while throwing the notice. - * Temporarily increase the refcount to detect this situation. */ - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - return IS_NULL; - } - if (EG(exception)) { - return IS_NULL; - } + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value->lval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; } return IS_LONG; case IS_RESOURCE: @@ -2699,26 +2736,38 @@ static zend_never_inline uint8_t slow_index_convert_w(HashTable *ht, const zval ZEND_FALLTHROUGH; } case IS_NULL: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; + } value->str = ZSTR_EMPTY_ALLOC(); return IS_STRING; case IS_DOUBLE: - value->lval = zend_dval_to_lval(Z_DVAL_P(dim)); - if (!zend_is_long_compatible(Z_DVAL_P(dim), value->lval)) { - /* The array may be destroyed while throwing the notice. - * Temporarily increase the refcount to detect this situation. */ - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { - if (!GC_REFCOUNT(ht)) { - zend_array_destroy(ht); - } - return IS_NULL; - } - if (EG(exception)) { - return IS_NULL; + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value->lval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); } + return IS_NULL; + } + if (EG(exception)) { + return IS_NULL; } return IS_LONG; case IS_RESOURCE: @@ -3005,7 +3054,7 @@ static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_UNSET(z zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET EXECUTE_DATA_CC); } -static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, bool is_list, int slow EXECUTE_DATA_DC) +static zend_always_inline void zend_fetch_dimension_address_read(zval *result, const zval *container, zval *dim, int dim_type, int type, bool is_list, bool slow EXECUTE_DATA_DC) { zval *retval; @@ -3078,6 +3127,11 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z return; } } + /* To prevent double warning */ + if (Z_TYPE_P(dim) == IS_DOUBLE) { + offset = zend_dval_to_lval_silent(Z_DVAL_P(dim)); + goto out; + } break; case IS_REFERENCE: dim = Z_REFVAL_P(dim); @@ -3143,6 +3197,9 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z if (ZEND_CONST_COND(dim_type == IS_CV, 1) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } + if (is_list && Z_TYPE_P(container) > IS_NULL) { + zend_error(E_WARNING, "Cannot use %s as array", zend_zval_type_name(container)); + } if (!is_list && type != BP_VAR_IS) { zend_error(E_WARNING, "Trying to access array offset on %s", zend_zval_value_name(container)); @@ -3151,45 +3208,70 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z } } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 0, 0 EXECUTE_DATA_CC); } -static zend_never_inline void zend_fetch_dimension_address_read_R_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_fetch_dimension_address_read_R_slow(const zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, IS_CV, BP_VAR_R, 0, 1 EXECUTE_DATA_CC); } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_IS(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_IS(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 0, 0 EXECUTE_DATA_CC); } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_LIST_r(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_LIST_r(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1, 0 EXECUTE_DATA_CC); } -ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type) +ZEND_API void zend_fetch_dimension_const(zval *result, const zval *container, zval *dim, int type) { zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, type, 0, 0 NO_EXECUTE_DATA_CC); } -static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable *ht, zval *offset EXECUTE_DATA_DC) +static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable *ht, const zval *offset EXECUTE_DATA_DC) { zend_ulong hval; if (Z_TYPE_P(offset) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return NULL; + } + if (EG(exception)) { + return NULL; + } num_idx: return zend_hash_index_find(ht, hval); } else if (Z_TYPE_P(offset) == IS_NULL) { -str_idx: +null_undef_idx: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return NULL; + } + + if (EG(exception)) { + return NULL; + } + return zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); } else if (Z_TYPE_P(offset) == IS_FALSE) { hval = 0; @@ -3203,14 +3285,14 @@ static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable goto num_idx; } else if (/*OP2_TYPE == IS_CV &&*/ Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); - goto str_idx; + goto null_undef_idx; } else { zend_illegal_array_offset_isset(offset); return NULL; } } -static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(zval *container, zval *offset EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(const zval *container, zval *offset EXECUTE_DATA_DC) { if (/*OP2_TYPE == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); @@ -3249,7 +3331,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(zval *container, } } -static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(zval *container, zval *offset EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(const zval *container, zval *offset EXECUTE_DATA_DC) { if (/*OP2_TYPE == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); @@ -3288,7 +3370,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(zval *containe } } -static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, zval *key OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, const zval *key OPLINE_DC EXECUTE_DATA_DC) { zend_string *str; zend_ulong hval; @@ -3309,7 +3391,17 @@ static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable key = Z_REFVAL_P(key); goto try_again; } else if (Z_TYPE_P(key) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); hval = zend_dval_to_lval_safe(Z_DVAL_P(key)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return false; + } + if (EG(exception)) { + return false; + } goto num_key; } else if (Z_TYPE_P(key) == IS_FALSE) { hval = 0; @@ -3324,6 +3416,9 @@ static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable } else if (Z_TYPE_P(key) <= IS_NULL) { if (UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); + } else { + ZEND_ASSERT(Z_TYPE_P(key) == IS_NULL); + zend_error(E_DEPRECATED, "Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead"); } str = ZSTR_EMPTY_ALLOC(); goto str_key; @@ -3333,8 +3428,8 @@ static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable } } -static ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( - zval *subject, zval *key OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( + const zval *subject, const zval *key OPLINE_DC EXECUTE_DATA_DC) { if (Z_TYPE_P(key) == IS_UNDEF) { ZVAL_UNDEFINED_OP1(); @@ -3348,7 +3443,7 @@ static ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( } } -static zend_always_inline bool promotes_to_array(zval *val) { +static zend_always_inline bool promotes_to_array(const zval *val) { return Z_TYPE_P(val) <= IS_FALSE || (Z_ISREF_P(val) && Z_TYPE_P(Z_REFVAL_P(val)) <= IS_FALSE); } @@ -3407,13 +3502,23 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(ptr), prop_info); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return 1; } -static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags, zend_property_info **prop_info_p OPLINE_DC EXECUTE_DATA_DC) -{ +static zend_always_inline void zend_fetch_property_address( + zval *result, + const zval *container, + uint32_t container_op_type, + const zval *prop_ptr, + uint32_t prop_op_type, + void **cache_slot, + int type, + uint32_t flags, + zend_property_info **prop_info_p + OPLINE_DC EXECUTE_DATA_DC +) { zval *ptr; zend_object *zobj; zend_string *name, *tmp_name; @@ -3533,6 +3638,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } else if (UNEXPECTED(Z_ISERROR_P(ptr))) { ZVAL_ERROR(result); goto end; + } else if (type == BP_VAR_UNSET && UNEXPECTED(Z_TYPE_P(ptr) == IS_UNDEF)) { + ZVAL_NULL(result); + goto end; } ZVAL_INDIRECT(result, ptr); @@ -3555,8 +3663,14 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } -static zend_always_inline void zend_assign_to_property_reference(zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) -{ +static zend_always_inline void zend_assign_to_property_reference( + const zval *container, + uint32_t container_op_type, + const zval *prop_ptr, + uint32_t prop_op_type, + zval *value_ptr + OPLINE_DC EXECUTE_DATA_DC +) { zval variable, *variable_ptr = &variable; void **cache_addr = (prop_op_type == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_RETURNS_FUNCTION) : NULL; zend_refcounted *garbage = NULL; @@ -3594,25 +3708,25 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container } } -static zend_never_inline void zend_assign_to_property_reference_this_const(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_this_const(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_UNUSED, prop_ptr, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_var_const(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_var_const(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_VAR, prop_ptr, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_this_var(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_this_var(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_UNUSED, prop_ptr, IS_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_var_var(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_var_var(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_VAR, prop_ptr, IS_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); @@ -3684,6 +3798,11 @@ static zend_never_inline zval* zend_fetch_static_property_address_ex(zend_proper return NULL; } + if (UNEXPECTED(Z_TYPE_P(result) == IS_UNDEF) + && (fetch_type == BP_VAR_IS || fetch_type == BP_VAR_UNSET)) { + return NULL; + } + *prop_info = property_info; if (EXPECTED(op1_type == IS_CONST) @@ -3778,7 +3897,7 @@ ZEND_API zval* ZEND_FASTCALL zend_fetch_static_property(zend_execute_data *ex, i return result; } -ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { zend_string *type1_str = zend_type_to_string(prop1->type); zend_string *type2_str = zend_type_to_string(prop2->type); zend_type_error("Reference with value of type %s held by property %s::$%s of type %s is not compatible with property %s::$%s of type %s", @@ -3794,7 +3913,7 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info zend_string_release(type2_str); } -ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv) { +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv) { zend_string *type_str = zend_type_to_string(prop->type); zend_type_error("Cannot assign %s to reference held by property %s::$%s of type %s", zend_zval_value_name(zv), @@ -3805,7 +3924,7 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info zend_string_release(type_str); } -ZEND_API ZEND_COLD void zend_throw_conflicting_coercion_error(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { +static zend_never_inline ZEND_COLD void zend_throw_conflicting_coercion_error(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { zend_string *type1_str = zend_type_to_string(prop1->type); zend_string *type2_str = zend_type_to_string(prop2->type); zend_type_error("Cannot assign %s to reference held by property %s::$%s of type %s and property %s::$%s of type %s, as this would result in an inconsistent type conversion", @@ -4119,19 +4238,10 @@ static zend_never_inline void zend_fetch_this_var(int type OPLINE_DC EXECUTE_DAT ZVAL_UNDEF(result); zend_throw_error(NULL, "Cannot unset $this"); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_clone_call(zend_function *clone, zend_class_entry *scope) -{ - zend_throw_error(NULL, "Call to %s %s::__clone() from %s%s", - zend_visibility_string(clone->common.fn_flags), ZSTR_VAL(clone->common.scope->name), - scope ? "scope " : "global scope", - scope ? ZSTR_VAL(scope->name) : "" - ); -} - #if ZEND_INTENSIVE_DEBUGGING #define CHECK_SYMBOL_TABLES() \ @@ -4192,6 +4302,10 @@ static zend_always_inline void i_free_compiled_variables(zend_execute_data *exec cv++; count--; } + if (UNEXPECTED(execute_data->type_args)) { + zend_type_arg_table_destroy(execute_data->type_args); + execute_data->type_args = NULL; + } } /* }}} */ @@ -4260,7 +4374,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_fcall_interrupt(zend_execute_data *ca */ static zend_never_inline void zend_copy_extra_args(EXECUTE_DATA_D) { - zend_op_array *op_array = &EX(func)->op_array; + const zend_op_array *op_array = &EX(func)->op_array; uint32_t first_extra_arg = op_array->num_args; uint32_t num_args = EX_NUM_ARGS(); zval *src; @@ -4372,6 +4486,19 @@ static zend_never_inline void ZEND_FASTCALL init_func_run_time_cache(zend_op_arr } /* }}} */ +/* Synthesize a monomorph from a mangled name (`base`) on by-name dispatch + * miss; returns NULL when the name isn't a synthesizable generic shape. */ +ZEND_API zend_function * ZEND_FASTCALL zend_resolve_monomorph_by_name(zend_string *lc_name) /* {{{ */ +{ + zend_function *fbc = zend_try_synthesize_function_monomorph_by_name(lc_name); + if (fbc) { + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache_i(&fbc->op_array); + } + } + return fbc; +} /* }}} */ + ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /* {{{ */ { zval *zv = zend_hash_find(EG(function_table), name); @@ -4389,7 +4516,7 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /* ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len) /* {{{ */ { - zval *zv = zend_hash_str_find(EG(function_table), name, len); + const zval *zv = zend_hash_str_find(EG(function_table), name, len); if (EXPECTED(zv != NULL)) { zend_function *fbc = Z_FUNC_P(zv); @@ -4796,25 +4923,9 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o } /* }}} */ -static const zend_live_range *find_live_range(const zend_op_array *op_array, uint32_t op_num, uint32_t var_num) /* {{{ */ -{ - int i; - for (i = 0; i < op_array->last_live_range; i++) { - const zend_live_range *range = &op_array->live_range[i]; - if (op_num >= range->start && op_num < range->end - && var_num == (range->var & ~ZEND_LIVE_MASK)) { - return range; - } - } - return NULL; -} -/* }}} */ - static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) /* {{{ */ { - int i; - - for (i = 0; i < EX(func)->op_array.last_live_range; i++) { + for (uint32_t i = 0; i < EX(func)->op_array.last_live_range; i++) { const zend_live_range *range = &EX(func)->op_array.live_range[i]; if (range->start > op_num) { /* further blocks will not be relevant... */ @@ -4825,6 +4936,16 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, uint32_t var_num = range->var & ~ZEND_LIVE_MASK; zval *var = EX_VAR(var_num); + /* Handle the split range for loop vars */ + if (catch_op_num) { + const zend_op *final_op = EX(func)->op_array.opcodes + range->end; + if (final_op->extended_value & ZEND_FREE_ON_RETURN && (final_op->opcode == ZEND_FE_FREE || final_op->opcode == ZEND_FREE)) { + if (catch_op_num < range->end + final_op->op2.num) { + continue; + } + } + } + if (kind == ZEND_LIVE_TMPVAR) { zval_ptr_dtor_nogc(var); } else if (kind == ZEND_LIVE_NEW) { @@ -4840,7 +4961,7 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, zval_ptr_dtor_nogc(var); } else if (kind == ZEND_LIVE_ROPE) { zend_string **rope = (zend_string **)var; - zend_op *last = EX(func)->op_array.opcodes + op_num; + const zend_op *last = EX(func)->op_array.opcodes + op_num; while ((last->opcode != ZEND_ROPE_ADD && last->opcode != ZEND_ROPE_INIT) || last->result.var != var_num) { ZEND_ASSERT(last >= EX(func)->op_array.opcodes); @@ -4849,7 +4970,7 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, if (last->opcode == ZEND_ROPE_INIT) { zend_string_release_ex(*rope, 0); } else { - int j = last->extended_value; + uint32_t j = last->extended_value; do { zend_string_release_ex(rope[j], 0); } while (j--); @@ -4896,7 +5017,7 @@ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_d return NULL; } - zend_op_array *op_array = &EX(func)->op_array; + const zend_op_array *op_array = &EX(func)->op_array; if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) { uint32_t i, num_cvs = EX(func)->op_array.last_var; @@ -4907,7 +5028,7 @@ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_d if (EX_CALL_INFO() & ZEND_CALL_FREE_EXTRA_ARGS) { zval *zv = EX_VAR_NUM(op_array->last_var + op_array->T); - zval *end = zv + (EX_NUM_ARGS() - op_array->num_args); + const zval *end = zv + (EX_NUM_ARGS() - op_array->num_args); while (zv != end) { zend_get_gc_buffer_add_zval(gc_buffer, zv++); } @@ -5105,7 +5226,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zend_o } /* }}} */ -static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_array *function, uint32_t num_args) /* {{{ */ +static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(const zend_array *function, uint32_t num_args) /* {{{ */ { zend_function *fbc; void *object_or_called_scope; @@ -5196,7 +5317,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar #define ZEND_FAKE_OP_ARRAY ((zend_op_array*)(intptr_t)-1) -static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval *inc_filename_zv, int type) /* {{{ */ +static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(const zval *inc_filename_zv, int type) /* {{{ */ { zend_op_array *new_op_array = NULL; zend_string *tmp_inc_filename; @@ -5220,7 +5341,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval } } else if (UNEXPECTED(EG(exception))) { break; - } else if (UNEXPECTED(strlen(ZSTR_VAL(inc_filename)) != ZSTR_LEN(inc_filename))) { + } else if (UNEXPECTED(zend_str_has_nul_byte(inc_filename))) { zend_message_dispatcher( (type == ZEND_INCLUDE_ONCE) ? ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN, @@ -5254,7 +5375,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval break; case ZEND_INCLUDE: case ZEND_REQUIRE: - if (UNEXPECTED(strlen(ZSTR_VAL(inc_filename)) != ZSTR_LEN(inc_filename))) { + if (UNEXPECTED(zend_str_has_nul_byte(inc_filename))) { zend_message_dispatcher( (type == ZEND_INCLUDE) ? ZMSG_FAILED_INCLUDE_FOPEN : ZMSG_FAILED_REQUIRE_FOPEN, @@ -5269,7 +5390,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval efree(eval_desc); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } zend_tmp_string_release(tmp_inc_filename); @@ -5376,39 +5497,40 @@ static zend_never_inline zend_result ZEND_FASTCALL zend_quick_check_constant( } /* }}} */ static zend_always_inline uint32_t zend_get_arg_offset_by_name( - zend_function *fbc, zend_string *arg_name, void **cache_slot) { - if (EXPECTED(*cache_slot == fbc)) { + const zend_function *fbc, const zend_string *arg_name, void **cache_slot) { + /* Due to closures, the `fbc` address isn't unique if the memory address is reused. + * The argument info will be however and uniquely positions the arguments. + * We do support NULL arg_info, so we have to distinguish that from an uninitialized cache slot. */ + void *unique_id = (void *) ((uintptr_t) fbc->common.arg_info | 1); + + if (EXPECTED(*cache_slot == unique_id)) { return *(uintptr_t *)(cache_slot + 1); } // TODO: Use a hash table? uint32_t num_args = fbc->common.num_args; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) - || EXPECTED(fbc->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { - for (uint32_t i = 0; i < num_args; i++) { - zend_arg_info *arg_info = &fbc->op_array.arg_info[i]; - if (zend_string_equals(arg_name, arg_info->name)) { - *cache_slot = fbc; - *(uintptr_t *)(cache_slot + 1) = i; - return i; - } - } - } else { - ZEND_ASSERT(num_args == 0 || fbc->internal_function.arg_info); - for (uint32_t i = 0; i < num_args; i++) { - zend_internal_arg_info *arg_info = &fbc->internal_function.arg_info[i]; - size_t len = strlen(arg_info->name); - if (zend_string_equals_cstr(arg_name, arg_info->name, len)) { - *cache_slot = fbc; + for (uint32_t i = 0; i < num_args; i++) { + const zend_arg_info *arg_info = &fbc->common.arg_info[i]; + if (zend_string_equals(arg_name, arg_info->name)) { + if ((fbc->type == ZEND_USER_FUNCTION + && (!fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE))) + || (fbc->type == ZEND_INTERNAL_FUNCTION + && !(fbc->common.fn_flags & ZEND_ACC_NEVER_CACHE))) { + *cache_slot = unique_id; *(uintptr_t *)(cache_slot + 1) = i; - return i; } + return i; } } if (fbc->common.fn_flags & ZEND_ACC_VARIADIC) { - *cache_slot = fbc; - *(uintptr_t *)(cache_slot + 1) = fbc->common.num_args; + if ((fbc->type == ZEND_USER_FUNCTION + && (!fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE))) + || (fbc->type == ZEND_INTERNAL_FUNCTION + && !(fbc->common.fn_flags & ZEND_ACC_NEVER_CACHE))) { + *cache_slot = unique_id; + *(uintptr_t *)(cache_slot + 1) = fbc->common.num_args; + } return fbc->common.num_args; } @@ -5419,7 +5541,7 @@ zval * ZEND_FASTCALL zend_handle_named_arg( zend_execute_data **call_ptr, zend_string *arg_name, uint32_t *arg_num_ptr, void **cache_slot) { zend_execute_data *call = *call_ptr; - zend_function *fbc = call->func; + const zend_function *fbc = call->func; uint32_t arg_offset = zend_get_arg_offset_by_name(fbc, arg_name, cache_slot); if (UNEXPECTED(arg_offset == (uint32_t) -1)) { zend_throw_error(NULL, "Unknown named parameter $%s", ZSTR_VAL(arg_name)); @@ -5505,7 +5627,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal continue; } - zend_op *opline = &op_array->opcodes[i]; + const zend_op *opline = &op_array->opcodes[i]; if (EXPECTED(opline->opcode == ZEND_RECV_INIT)) { zval *default_value = RT_CONSTANT(opline, opline->op2); if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) { @@ -5563,7 +5685,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal continue; } - zend_internal_arg_info *arg_info = &fbc->internal_function.arg_info[i]; + zend_arg_info *arg_info = &fbc->internal_function.arg_info[i]; if (i < fbc->common.required_num_args) { zend_execute_data *old = start_fake_frame(call, NULL); zend_argument_error(zend_ce_argument_count_error, i + 1, "not passed"); @@ -5849,3 +5971,29 @@ ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, int op_type, const znode } return ret; } + +ZEND_API void zend_return_unwrap_ref(zend_execute_data *execute_data, zval *return_value) +{ + if (!return_value || !Z_ISREF_P(return_value)) { + return; + } + + zend_execute_data *prev_ex = EX(prev_execute_data); + if (!prev_ex || !prev_ex->func || !ZEND_USER_CODE(prev_ex->func->type)) { + return; + } + + const zend_op *do_opline = prev_ex->opline; + if (do_opline->result_type != IS_TMP_VAR) { + return; + } + + if (do_opline->opcode != ZEND_DO_FCALL + && do_opline->opcode != ZEND_DO_FCALL_BY_NAME + && do_opline->opcode != ZEND_DO_ICALL + && do_opline->opcode != ZEND_DO_UCALL) { + return; + } + + zend_unwrap_reference(return_value); +} diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index cf15c9e3b2db..ff9aff51b9d9 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -22,6 +21,7 @@ #define ZEND_EXECUTE_H #include "zend_compile.h" +#include "zend_closures.h" #include "zend_hash.h" #include "zend_operators.h" #include "zend_variables.h" @@ -48,11 +48,11 @@ ZEND_API void zend_init_code_execute_data(zend_execute_data *execute_data, zend_ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value); ZEND_API void execute_ex(zend_execute_data *execute_data); ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value); -ZEND_API bool zend_is_valid_class_name(zend_string *name); +ZEND_API bool zend_is_valid_class_name(const zend_string *name); ZEND_API zend_class_entry *zend_lookup_class(zend_string *name); ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *lcname, uint32_t flags); -ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex); -ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex); +ZEND_API zend_class_entry *zend_get_called_scope(const zend_execute_data *ex); +ZEND_API zend_object *zend_get_this_object(const zend_execute_data *ex); ZEND_API zend_result zend_eval_string(const char *str, zval *retval_ptr, const char *string_name); ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *retval_ptr, const char *string_name); ZEND_API zend_result zend_eval_string_ex(const char *str, zval *retval_ptr, const char *string_name, bool handle_exceptions); @@ -61,11 +61,12 @@ ZEND_API zend_result zend_eval_stringl_ex(const char *str, size_t str_len, zval /* export zend_pass_function to allow comparisons against it */ extern ZEND_API const zend_internal_function zend_pass_function; -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_nodiscard_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_class_constant *c, const zend_string *constant_name); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_constant(const zend_constant *c, const zend_string *constant_name); +ZEND_API ZEND_COLD void zend_use_of_deprecated_trait(zend_class_entry *trait, const zend_string *used_by); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void); ZEND_COLD void ZEND_FASTCALL zend_param_must_be_ref(const zend_function *func, uint32_t arg_num); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_use_resource_as_offset(const zval *dim); @@ -80,31 +81,31 @@ typedef enum { ZEND_API bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref_ex(const zend_property_info *prop_info, zval *orig_val, bool strict, zend_verify_prop_assignable_by_ref_context context); ZEND_API bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref(const zend_property_info *prop_info, zval *orig_val, bool strict); -ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv); -ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv); +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv); +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv); ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht, zend_long lval); ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, zend_string *offset); -ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void); +ZEND_API zend_never_inline ZEND_COLD void zend_wrong_string_offset_error(void); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex(const char *class_name, const char *prop_name); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex(const char *class_name, const char *prop_name); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *prop_info, const char *operation); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *prop_info, const char *operation); ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool strict, bool is_internal_arg); -ZEND_API ZEND_COLD void zend_verify_arg_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value); -ZEND_API ZEND_COLD void zend_verify_return_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_return_error( const zend_function *zf, const zval *value); -ZEND_API ZEND_COLD void zend_verify_never_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error( const zend_function *zf); ZEND_API bool zend_verify_ref_array_assignable(zend_reference *ref); ZEND_API bool zend_check_user_type_slow( @@ -112,7 +113,7 @@ ZEND_API bool zend_check_user_type_slow( #if ZEND_DEBUG ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_execute_data *call); -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc); +ZEND_API zend_never_inline ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc); ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *ret); #endif @@ -134,7 +135,7 @@ ZEND_API void ZEND_FASTCALL zend_ref_del_type_source(zend_property_info_source_l ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *value, uint8_t value_type, bool strict); ZEND_API zval* zend_assign_to_typed_ref_ex(zval *variable_ptr, zval *value, uint8_t value_type, bool strict, zend_refcounted **garbage_ptr); -static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, zval *value, uint8_t value_type) +static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, const zval *value, uint8_t value_type) { zend_refcounted *ref = NULL; @@ -210,7 +211,7 @@ static zend_always_inline zval* zend_assign_to_variable_ex(zval *variable_ptr, z return variable_ptr; } -static zend_always_inline void zend_safe_assign_to_variable_noref(zval *variable_ptr, zval *value) { +static zend_always_inline void zend_safe_assign_to_variable_noref(zval *variable_ptr, const zval *value) { if (Z_REFCOUNTED_P(variable_ptr)) { ZEND_ASSERT(Z_TYPE_P(variable_ptr) != IS_REFERENCE); zend_refcounted *ref = Z_COUNTED_P(variable_ptr); @@ -233,6 +234,9 @@ static zend_always_inline void zend_cast_zval_to_object(zval *result, zval *expr } Z_OBJ_P(result)->properties = ht; } else if (Z_TYPE_P(expr) != IS_NULL) { + if (UNEXPECTED(Z_TYPE_P(expr) == IS_DOUBLE && zend_isnan(Z_DVAL_P(expr)))) { + zend_nan_coerced_to_type_warning(IS_OBJECT); + } Z_OBJ_P(result)->properties = ht = zend_new_array(1); expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr); if (op1_type == IS_CONST) { @@ -244,9 +248,12 @@ static zend_always_inline void zend_cast_zval_to_object(zval *result, zval *expr } static zend_always_inline void zend_cast_zval_to_array(zval *result, zval *expr, uint8_t op1_type) { - extern zend_class_entry *zend_ce_closure; + extern ZEND_API zend_class_entry *zend_ce_closure; if (op1_type == IS_CONST || Z_TYPE_P(expr) != IS_OBJECT || Z_OBJCE_P(expr) == zend_ce_closure) { if (Z_TYPE_P(expr) != IS_NULL) { + if (UNEXPECTED(Z_TYPE_P(expr) == IS_DOUBLE && zend_isnan(Z_DVAL_P(expr)))) { + zend_nan_coerced_to_type_warning(IS_ARRAY); + } ZVAL_ARR(result, zend_new_array(1)); expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); if (op1_type == IS_CONST) { @@ -332,6 +339,22 @@ static zend_always_inline void zend_vm_init_call_frame(zend_execute_data *call, Z_PTR(call->This) = object_or_called_scope; ZEND_CALL_INFO(call) = call_info; ZEND_CALL_NUM_ARGS(call) = num_args; + /* Closures created inside a generic frame capture that frame's T-table. + * Propagate it onto the call frame so the body's RECV-time checks + * resolve outer T-refs. The closure owns the table (persisted=true); + * call-frame teardown skips destroying it. VERIFY_GENERIC_ARGUMENTS may + * still overwrite type_args later for explicit-turbofish calls. */ + if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CLOSURE)) { + const zend_closure *closure = + (const zend_closure *) ZEND_CLOSURE_OBJECT(func); + call->type_args = closure->captured_type_args; + } else if (UNEXPECTED(ZEND_USER_CODE(func->type) + && (func->op_array.fn_flags2 & ZEND_ACC2_MONOMORPH_TYPE_ARGS))) { + /* Monomorph reached via by-name dispatch: bind its concrete type-arg table. */ + call->type_args = func->op_array.generic_types->monomorph_type_args; + } else { + call->type_args = NULL; + } } static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(uint32_t used_stack, uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) @@ -352,7 +375,7 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(ui } } -static zend_always_inline uint32_t zend_vm_calc_used_stack(uint32_t num_args, zend_function *func) +static zend_always_inline uint32_t zend_vm_calc_used_stack(uint32_t num_args, const zend_function *func) { uint32_t used_stack = ZEND_CALL_FRAME_SLOT + num_args + func->common.T; @@ -405,6 +428,11 @@ static zend_always_inline void zend_vm_stack_free_call_frame_ex(uint32_t call_in { ZEND_ASSERT_VM_STACK_GLOBAL; + if (UNEXPECTED(call->type_args != NULL)) { + zend_type_arg_table_destroy(call->type_args); + call->type_args = NULL; + } + if (UNEXPECTED(call_info & ZEND_CALL_ALLOCATED)) { zend_vm_stack p = EG(vm_stack); zend_vm_stack prev = p->prev; @@ -446,11 +474,11 @@ ZEND_API const char *get_active_class_name(const char **space); ZEND_API const char *get_active_function_name(void); ZEND_API const char *get_active_function_arg_name(uint32_t arg_num); ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t arg_num); -ZEND_API zend_function *zend_active_function_ex(zend_execute_data *execute_data); +ZEND_API const zend_function *zend_active_function_ex(const zend_execute_data *execute_data); -static zend_always_inline zend_function *zend_active_function(void) +static zend_always_inline const zend_function *zend_active_function(void) { - zend_function *func = EG(current_execute_data)->func; + const zend_function *func = EG(current_execute_data)->func; if (ZEND_USER_CODE(func->type)) { return zend_active_function_ex(EG(current_execute_data)); } else { @@ -465,7 +493,7 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void); ZEND_API uint32_t zend_get_executed_lineno(void); ZEND_API zend_class_entry *zend_get_executed_scope(void); ZEND_API bool zend_is_executing(void); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num); ZEND_API void zend_set_timeout(zend_long seconds, bool reset_signals); ZEND_API void zend_unset_timeout(void); @@ -475,10 +503,11 @@ ZEND_API zend_class_entry *zend_fetch_class_with_scope(zend_string *class_name, ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, zend_string *lcname, uint32_t fetch_type); ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name); +ZEND_API zend_function * ZEND_FASTCALL zend_resolve_monomorph_by_name(zend_string *lc_name); ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len); ZEND_API void ZEND_FASTCALL zend_init_func_run_time_cache(zend_op_array *op_array); -ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type); +ZEND_API void zend_fetch_dimension_const(zval *result, const zval *container, zval *dim, int type); ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var); @@ -505,7 +534,7 @@ ZEND_API ZEND_ATTRIBUTE_DEPRECATED HashTable *zend_unfinished_execution_gc(zend_ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_data, zend_execute_data *call, zend_get_gc_buffer *gc_buffer, bool suspended_by_yield); ZEND_API zval* ZEND_FASTCALL zend_fetch_static_property(zend_execute_data *ex, int fetch_type); ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method); -ZEND_API void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc); ZEND_API void zend_frameless_observed_call(zend_execute_data *execute_data); @@ -579,11 +608,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal ZEND_API bool zend_verify_class_constant_type(const zend_class_constant *c, const zend_string *name, zval *constant); -ZEND_COLD void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant); ZEND_API bool zend_verify_property_type(const zend_property_info *info, zval *property, bool strict); -ZEND_COLD void zend_verify_property_type_error(const zend_property_info *info, const zval *property); -ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property); #define ZEND_REF_ADD_TYPE_SOURCE(ref, source) \ zend_ref_add_type_source(&ZEND_REF_TYPE_SOURCES(ref), source) @@ -612,7 +638,7 @@ ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_prope } \ } while (0) -ZEND_COLD void zend_match_unhandled_error(const zval *value); +zend_never_inline ZEND_COLD void zend_match_unhandled_error(const zval *value); /* Call this to handle the timeout or the interrupt function. It will set * EG(vm_interrupt) to false. @@ -625,6 +651,8 @@ static zend_always_inline void *zend_get_bad_ptr(void) return NULL; } +ZEND_API void zend_return_unwrap_ref(zend_execute_data *call, zval *return_value); + END_EXTERN_C() #endif /* ZEND_EXECUTE_H */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9a7803e44e66..e09f42b58a14 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -39,6 +38,7 @@ #include "zend_observer.h" #include "zend_call_stack.h" #include "zend_frameless_function.h" +#include "zend_smart_str.h" #ifdef HAVE_SYS_TIME_H #include #endif @@ -88,7 +88,7 @@ static void zend_handle_sigsegv(void) /* {{{ */ /* }}} */ #endif -static void zend_extension_activator(zend_extension *extension) /* {{{ */ +static void zend_extension_activator(const zend_extension *extension) /* {{{ */ { if (extension->activate) { extension->activate(); @@ -96,7 +96,7 @@ static void zend_extension_activator(zend_extension *extension) /* {{{ */ } /* }}} */ -static void zend_extension_deactivator(zend_extension *extension) /* {{{ */ +static void zend_extension_deactivator(const zend_extension *extension) /* {{{ */ { if (extension->deactivate) { extension->deactivate(); @@ -113,14 +113,14 @@ static int clean_non_persistent_constant_full(zval *zv) /* {{{ */ static int clean_non_persistent_function_full(zval *zv) /* {{{ */ { - zend_function *function = Z_PTR_P(zv); + const zend_function *function = Z_PTR_P(zv); return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ static int clean_non_persistent_class_full(zval *zv) /* {{{ */ { - zend_class_entry *ce = Z_PTR_P(zv); + const zend_class_entry *ce = Z_PTR_P(zv); return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ @@ -145,7 +145,6 @@ void init_executor(void) /* {{{ */ EG(function_table) = CG(function_table); EG(class_table) = CG(class_table); - EG(in_autoload) = NULL; EG(error_handling) = EH_NORMAL; EG(flags) = EG_FLAGS_INITIAL; @@ -156,6 +155,7 @@ void init_executor(void) /* {{{ */ zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator); zend_hash_init(&EG(included_files), 8, NULL, NULL, 0); + zend_hash_init(&EG(autoload_current_classnames), 8, NULL, NULL, 0); EG(ticks_count) = 0; @@ -176,7 +176,6 @@ void init_executor(void) /* {{{ */ ZEND_ATOMIC_BOOL_INIT(&EG(timed_out), false); EG(exception) = NULL; - EG(prev_exception) = NULL; EG(fake_scope) = NULL; EG(trampoline).common.function_name = NULL; @@ -193,8 +192,7 @@ void init_executor(void) /* {{{ */ EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL; EG(record_errors) = false; - EG(num_errors) = 0; - EG(errors) = NULL; + memset(&EG(errors), 0, sizeof(EG(errors))); EG(filename_override) = NULL; EG(lineno_override) = -1; @@ -203,6 +201,8 @@ void init_executor(void) /* {{{ */ zend_fiber_init(); zend_weakrefs_init(); + zend_hash_init(&EG(callable_convert_cache), 8, NULL, ZVAL_PTR_DTOR, 0); + EG(active) = 1; } /* }}} */ @@ -229,7 +229,7 @@ static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */ } /* }}} */ -static ZEND_COLD void zend_throw_or_error(int fetch_type, zend_class_entry *exception_ce, const char *format, ...) /* {{{ */ +static ZEND_COLD void zend_throw_or_error(uint32_t fetch_type, zend_class_entry *exception_ce, const char *format, ...) /* {{{ */ { va_list va; char *message = NULL; @@ -270,24 +270,22 @@ void shutdown_destructors(void) /* {{{ */ /* Free values held by the executor. */ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) { - zend_string *key; - zval *zv; - EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN; - zend_try { - zend_close_rsrc_list(&EG(regular_list)); - } zend_end_try(); + zend_close_rsrc_list(&EG(regular_list)); /* No PHP callback functions should be called after this point. */ EG(active) = 0; if (!fast_shutdown) { + zval *zv; + zend_hash_graceful_reverse_destroy(&EG(symbol_table)); /* Constants may contain objects, destroy them before the object store. */ if (EG(full_tables_cleanup)) { zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant_full); } else { + zend_string *key; ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) { zend_constant *c = Z_PTR_P(zv); if (_idx == EG(persistent_constants_count)) { @@ -420,6 +418,8 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1); zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1); + zend_hash_clean(&EG(callable_convert_cache)); + #if ZEND_DEBUG if (!CG(unclean_shutdown)) { gc_collect_cycles(); @@ -434,10 +434,14 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) void shutdown_executor(void) /* {{{ */ { - zend_string *key; - zval *zv; #if ZEND_DEBUG bool fast_shutdown = 0; +#elif defined(__SANITIZE_ADDRESS__) + char *force_fast_shutdown = getenv("ZEND_ASAN_FORCE_FAST_SHUTDOWN"); + bool fast_shutdown = ( + is_zend_mm() + || (force_fast_shutdown && ZEND_ATOL(force_fast_shutdown)) + ) && !EG(full_tables_cleanup); #else bool fast_shutdown = is_zend_mm() && !EG(full_tables_cleanup); #endif @@ -471,6 +475,8 @@ void shutdown_executor(void) /* {{{ */ zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full); zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full); } else { + zend_string *key; + zval *zv; ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(EG(function_table), key, zv) { zend_function *func = Z_PTR_P(zv); if (_idx == EG(persistent_functions_count)) { @@ -496,20 +502,19 @@ void shutdown_executor(void) /* {{{ */ } zend_hash_destroy(&EG(included_files)); + zend_hash_destroy(&EG(autoload_current_classnames)); zend_stack_destroy(&EG(user_error_handlers_error_reporting)); zend_stack_destroy(&EG(user_error_handlers)); zend_stack_destroy(&EG(user_exception_handlers)); zend_lazy_objects_destroy(&EG(lazy_objects_store)); zend_objects_store_destroy(&EG(objects_store)); - if (EG(in_autoload)) { - zend_hash_destroy(EG(in_autoload)); - FREE_HASHTABLE(EG(in_autoload)); - } if (EG(ht_iterators) != EG(ht_iterators_slots)) { efree(EG(ht_iterators)); } + + zend_hash_destroy(&EG(callable_convert_cache)); } #if ZEND_DEBUG @@ -530,7 +535,7 @@ void shutdown_executor(void) /* {{{ */ /* return class name and "::" or "". */ ZEND_API const char *get_active_class_name(const char **space) /* {{{ */ { - zend_function *func; + const zend_function *func; if (!zend_is_executing()) { if (space) { @@ -545,7 +550,7 @@ ZEND_API const char *get_active_class_name(const char **space) /* {{{ */ case ZEND_USER_FUNCTION: case ZEND_INTERNAL_FUNCTION: { - zend_class_entry *ce = func->common.scope; + const zend_class_entry *ce = func->common.scope; if (space) { *space = ce ? "::" : ""; @@ -563,7 +568,7 @@ ZEND_API const char *get_active_class_name(const char **space) /* {{{ */ ZEND_API const char *get_active_function_name(void) /* {{{ */ { - zend_function *func; + const zend_function *func; if (!zend_is_executing()) { return NULL; @@ -573,7 +578,7 @@ ZEND_API const char *get_active_function_name(void) /* {{{ */ switch (func->type) { case ZEND_USER_FUNCTION: { - zend_string *function_name = func->common.function_name; + const zend_string *function_name = func->common.function_name; if (function_name) { return ZSTR_VAL(function_name); @@ -591,9 +596,9 @@ ZEND_API const char *get_active_function_name(void) /* {{{ */ } /* }}} */ -ZEND_API zend_function *zend_active_function_ex(zend_execute_data *execute_data) +ZEND_API const zend_function *zend_active_function_ex(const zend_execute_data *execute_data) { - zend_function *func = EX(func); + const zend_function *func = EX(func); /* Resolve function if op is a frameless call. */ if (ZEND_USER_CODE(func->type)) { @@ -630,7 +635,7 @@ ZEND_API const char *get_active_function_arg_name(uint32_t arg_num) /* {{{ */ return NULL; } - zend_function *func = zend_active_function(); + const zend_function *func = zend_active_function(); return get_function_arg_name(func, arg_num); } @@ -642,17 +647,13 @@ ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t a return NULL; } - if (func->type == ZEND_USER_FUNCTION || (func->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) { - return ZSTR_VAL(func->common.arg_info[arg_num - 1].name); - } else { - return ((zend_internal_arg_info*) func->common.arg_info)[arg_num - 1].name; - } + return ZSTR_VAL(func->common.arg_info[arg_num - 1].name); } /* }}} */ ZEND_API const char *zend_get_executed_filename(void) /* {{{ */ { - zend_string *filename = zend_get_executed_filename_ex(); + const zend_string *filename = zend_get_executed_filename_ex(); return filename != NULL ? ZSTR_VAL(filename) : "[no active file]"; } /* }}} */ @@ -664,7 +665,7 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */ return filename_override; } - zend_execute_data *ex = EG(current_execute_data); + const zend_execute_data *ex = EG(current_execute_data); while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { ex = ex->prev_execute_data; @@ -684,7 +685,7 @@ ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */ return lineno_override; } - zend_execute_data *ex = EG(current_execute_data); + const zend_execute_data *ex = EG(current_execute_data); while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { ex = ex->prev_execute_data; @@ -707,7 +708,7 @@ ZEND_API uint32_t zend_get_executed_lineno(void) /* {{{ */ ZEND_API zend_class_entry *zend_get_executed_scope(void) /* {{{ */ { - zend_execute_data *ex = EG(current_execute_data); + const zend_execute_data *ex = EG(current_execute_data); while (1) { if (!ex) { @@ -733,7 +734,7 @@ ZEND_API zend_result ZEND_FASTCALL zval_update_constant_with_ctx(zval *p, zend_c if (ast->kind == ZEND_AST_CONSTANT) { zend_string *name = zend_ast_get_constant_name(ast); - zval *zv = zend_get_constant_ex(name, scope, ast->attr); + const zval *zv = zend_get_constant_ex(name, scope, ast->attr); if (UNEXPECTED(zv == NULL)) { return FAILURE; } @@ -795,6 +796,7 @@ zend_result _call_user_function_impl(zval *object, zval *function_name, zval *re fci.param_count = param_count; fci.params = params; fci.named_params = named_params; + fci.consumed_args = 0; return zend_call_function(&fci, NULL); } @@ -802,13 +804,11 @@ zend_result _call_user_function_impl(zval *object, zval *function_name, zval *re zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */ { - uint32_t i; zend_execute_data *call; zend_fcall_info_cache fci_cache_local; zend_function *func; uint32_t call_info; void *object_or_called_scope; - zend_class_entry *orig_fake_scope; ZVAL_UNDEF(fci->retval); @@ -854,22 +854,24 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ call_info = ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_HAS_THIS; } - call = zend_vm_stack_push_call_frame(call_info, - func, fci->param_count, object_or_called_scope); - if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_DEPRECATED)) { zend_deprecated_function(func); if (UNEXPECTED(EG(exception))) { - zend_vm_stack_free_call_frame(call); return SUCCESS; } } - for (i=0; iparam_count; i++) { + call = zend_vm_stack_push_call_frame(call_info, + func, fci->param_count, object_or_called_scope); + uint32_t consumed_args = fci->param_count ? fci->consumed_args : 0; + + ZEND_ASSERT((consumed_args & (consumed_args - 1)) == 0); + + for (uint32_t i = 0; i < fci->param_count; i++) { zval *param = ZEND_CALL_ARG(call, i+1); zval *arg = &fci->params[i]; - bool must_wrap = 0; + bool must_wrap = false; if (UNEXPECTED(Z_ISUNDEF_P(arg))) { /* Allow forwarding undef slots. This is only used by Closure::__invoke(). */ ZVAL_UNDEF(param); @@ -883,7 +885,7 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ /* By-value send is not allowed -- emit a warning, * and perform the call with the value wrapped in a reference. */ zend_param_must_be_ref(func, i + 1); - must_wrap = 1; + must_wrap = true; if (UNEXPECTED(EG(exception))) { ZEND_CALL_NUM_ARGS(call) = i; cleanup_args: @@ -906,7 +908,15 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ } if (EXPECTED(!must_wrap)) { - ZVAL_COPY(param, arg); + if (EXPECTED(consumed_args == 0) + || !zend_fci_is_consumed_arg(consumed_args, i) + || Z_ISREF_P(arg) + || arg != &fci->params[i]) { + ZVAL_COPY(param, arg); + } else { + ZVAL_COPY_VALUE(param, arg); + ZVAL_UNDEF(arg); + } } else { Z_TRY_ADDREF_P(arg); ZVAL_NEW_REF(param, arg); @@ -917,13 +927,13 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ zend_string *name; zval *arg; uint32_t arg_num = ZEND_CALL_NUM_ARGS(call) + 1; - bool have_named_params = 0; + bool have_named_params = false; ZEND_HASH_FOREACH_STR_KEY_VAL(fci->named_params, name, arg) { - bool must_wrap = 0; + bool must_wrap = false; zval *target; if (name) { void *cache_slot[2] = {NULL, NULL}; - have_named_params = 1; + have_named_params = true; target = zend_handle_named_arg(&call, name, &arg_num, cache_slot); if (!target) { goto cleanup_args; @@ -945,7 +955,7 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ /* By-value send is not allowed -- emit a warning, * and perform the call with the value wrapped in a reference. */ zend_param_must_be_ref(func, arg_num); - must_wrap = 1; + must_wrap = true; if (UNEXPECTED(EG(exception))) { goto cleanup_args; } @@ -997,11 +1007,31 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ fci_cache->function_handler = NULL; } - orig_fake_scope = EG(fake_scope); + const zend_class_entry *orig_fake_scope = EG(fake_scope); EG(fake_scope) = NULL; if (func->type == ZEND_USER_FUNCTION) { uint32_t orig_jit_trace_num = EG(jit_trace_num); + /* C-dispatched calls (usort, array_map, Closure::call, etc.) don't go + * through DO_FCALL, so the closure-side reified arg check that lives + * there is bypassed. Run it here for closures whose captured T-table + * was propagated by zend_vm_init_call_frame. Must fire before + * zend_init_func_execute_data, because that relocates variadic args + * past the CV slots and the helper would then read UNDEF positions. */ + if (UNEXPECTED(call->type_args + && (func->common.fn_flags & ZEND_ACC_CLOSURE))) { + if (!zend_verify_generic_arg_types(call, NULL)) { + zend_vm_stack_free_args(call); + if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) { + OBJ_RELEASE(Z_OBJ(call->This)); + } + zend_vm_stack_free_call_frame(call); + EG(fake_scope) = orig_fake_scope; + zend_release_fcall_info_cache(fci_cache); + return SUCCESS; + } + } + zend_init_func_execute_data(call, &func->op_array, fci->retval); ZEND_OBSERVER_FCALL_BEGIN(call); zend_execute_ex(call); @@ -1027,10 +1057,13 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_ if (should_throw) { zend_internal_call_arginfo_violation(call->func); } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, fci->retval)); + if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + bool result = zend_verify_internal_return_type(call->func, fci->retval); + ZEND_ASSERT(result); + } ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? Z_ISREF_P(fci->retval) : !Z_ISREF_P(fci->retval)); + ZEND_ASSERT(!(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS)); } #endif ZEND_OBSERVER_FCALL_END(call, fci->retval); @@ -1092,6 +1125,7 @@ ZEND_API void zend_call_known_function( fci.param_count = param_count; fci.params = params; fci.named_params = named_params; + fci.consumed_args = 0; ZVAL_UNDEF(&fci.function_name); /* Unused */ fcic.function_handler = fn; @@ -1125,22 +1159,20 @@ ZEND_API zend_result zend_call_method_if_exists( zend_object *object, zend_string *method_name, zval *retval, uint32_t param_count, zval *params) { - zend_fcall_info fci; - fci.size = sizeof(zend_fcall_info); - fci.object = object; - ZVAL_STR(&fci.function_name, method_name); - fci.retval = retval; - fci.param_count = param_count; - fci.params = params; - fci.named_params = NULL; - + zval zval_method; zend_fcall_info_cache fcc; - if (!zend_is_callable_ex(&fci.function_name, fci.object, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL)) { + + ZVAL_STR(&zval_method, method_name); + + if (UNEXPECTED(!zend_is_callable_ex(&zval_method, object, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL))) { ZVAL_UNDEF(retval); return FAILURE; } - return zend_call_function(&fci, &fcc); + zend_call_known_fcc(&fcc, retval, param_count, params, NULL); + /* Need to free potential trampoline (__call/__callStatic) copied function handler before releasing the closure */ + zend_release_fcall_info_cache(&fcc); + return SUCCESS; } /* 0-9 a-z A-Z _ \ 0x80-0xff */ @@ -1155,7 +1187,7 @@ static const uint32_t valid_chars[8] = { 0xffffffff, }; -ZEND_API bool zend_is_valid_class_name(zend_string *name) { +ZEND_API bool zend_is_valid_class_name(const zend_string *name) { for (size_t i = 0; i < ZSTR_LEN(name); i++) { unsigned char c = ZSTR_VAL(name)[i]; if (!ZEND_BIT_TEST(valid_chars, c)) { @@ -1210,7 +1242,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * ALLOC_HASHTABLE(CG(unlinked_uses)); zend_hash_init(CG(unlinked_uses), 0, NULL, NULL, 0); } - zend_hash_index_add_empty_element(CG(unlinked_uses), (zend_long)(uintptr_t)ce); + zend_hash_index_add_empty_element(CG(unlinked_uses), (zend_ulong)(uintptr_t)ce); return ce; } return NULL; @@ -1224,6 +1256,26 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * return ce; } + /* Monomorphization hook: if the requested name has generic shape + * ("Box"), parse it and synthesize the monomorph. This makes + * unserialize, dynamic `new $name`, `class_exists`, and `instanceof + * "Foo"` all transparently materialize the monomorph on demand. + * Runs before autoload so a Box name doesn't trigger a doomed + * autoload for "Box" itself. The synthesizer only succeeds when + * the base class exists and is generic. */ + if (!zend_is_compiling() && zend_class_name_is_monomorph(name)) { + zend_class_entry *mono = zend_try_synthesize_monomorph_by_name(name, flags); + if (mono) { + if (!key) zend_string_release_ex(lc_name, 0); + if (ce_cache) SET_CE_CACHE(ce_cache, mono); + return mono; + } + if (EG(exception)) { + if (!key) zend_string_release_ex(lc_name, 0); + return NULL; + } + } + /* The compiler is not-reentrant. Make sure we autoload only during run-time. */ if ((flags & ZEND_FETCH_CLASS_NO_AUTOLOAD) || zend_is_compiling()) { if (!key) { @@ -1245,12 +1297,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * return NULL; } - if (EG(in_autoload) == NULL) { - ALLOC_HASHTABLE(EG(in_autoload)); - zend_hash_init(EG(in_autoload), 8, NULL, NULL, 0); - } - - if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) { + if (zend_hash_add_empty_element(&EG(autoload_current_classnames), lc_name) == NULL) { if (!key) { zend_string_release_ex(lc_name, 0); } @@ -1267,14 +1314,12 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * zend_long previous_lineno = EG(lineno_override); EG(filename_override) = NULL; EG(lineno_override) = -1; - zend_exception_save(); ce = zend_autoload(autoload_name, lc_name); - zend_exception_restore(); EG(filename_override) = previous_filename; EG(lineno_override) = previous_lineno; zend_string_release_ex(autoload_name, 0); - zend_hash_del(EG(in_autoload), lc_name); + zend_hash_del(&EG(autoload_current_classnames), lc_name); if (!key) { zend_string_release_ex(lc_name, 0); @@ -1295,7 +1340,7 @@ ZEND_API zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */ } /* }}} */ -ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex) /* {{{ */ +ZEND_API zend_class_entry *zend_get_called_scope(const zend_execute_data *ex) /* {{{ */ { while (ex) { if (Z_TYPE(ex->This) == IS_OBJECT) { @@ -1313,7 +1358,7 @@ ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex) /* {{{ * } /* }}} */ -ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex) /* {{{ */ +ZEND_API zend_object *zend_get_this_object(const zend_execute_data *ex) /* {{{ */ { while (ex) { if (Z_TYPE(ex->This) == IS_OBJECT) { @@ -1427,14 +1472,14 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */ function. */ if (EG(hard_timeout) > 0) { zend_atomic_bool_store_ex(&EG(timed_out), false); - zend_set_timeout_ex(EG(hard_timeout), 1); + zend_set_timeout_ex(EG(hard_timeout), true); /* XXX Abused, introduce an additional flag if the value needs to be kept. */ EG(hard_timeout) = 0; } # endif #else zend_atomic_bool_store_ex(&EG(timed_out), false); - zend_set_timeout_ex(0, 1); + zend_set_timeout_ex(0, true); #endif zend_error_noreturn(E_ERROR, "Maximum execution time of " ZEND_LONG_FMT " second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s"); @@ -1519,7 +1564,7 @@ static void zend_timeout_handler(int dummy) /* {{{ */ #ifndef ZTS if (EG(hard_timeout) > 0) { /* Set hard timeout */ - zend_set_timeout_ex(EG(hard_timeout), 1); + zend_set_timeout_ex(EG(hard_timeout), true); } #endif } @@ -1564,7 +1609,6 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */ if (!DeleteTimerQueueTimer(NULL, tq_timer, INVALID_HANDLE_VALUE)) { tq_timer = NULL; zend_error_noreturn(E_ERROR, "Could not delete queued timer"); - return; } tq_timer = NULL; } @@ -1574,10 +1618,11 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */ if (!CreateTimerQueueTimer(&tq_timer, NULL, (WAITORTIMERCALLBACK)tq_timer_cb, (VOID*)eg, seconds*1000, 0, WT_EXECUTEONLYONCE)) { tq_timer = NULL; zend_error_noreturn(E_ERROR, "Could not queue new timer"); - return; } #elif defined(ZEND_MAX_EXECUTION_TIMERS) - zend_max_execution_timer_settime(seconds); + if (seconds > 0) { + zend_max_execution_timer_settime(seconds); + } if (reset_signals) { sigset_t sigset; @@ -1659,12 +1704,13 @@ void zend_unset_timeout(void) /* {{{ */ zend_atomic_bool_store_ex(&EG(timed_out), false); tq_timer = NULL; zend_error_noreturn(E_ERROR, "Could not delete queued timer"); - return; } tq_timer = NULL; } #elif defined(ZEND_MAX_EXECUTION_TIMERS) - zend_max_execution_timer_settime(0); + if (EG(timeout_seconds)) { + zend_max_execution_timer_settime(0); + } #elif defined(HAVE_SETITIMER) if (EG(timeout_seconds)) { struct itimerval no_timeout; @@ -1682,7 +1728,7 @@ void zend_unset_timeout(void) /* {{{ */ } /* }}} */ -static ZEND_COLD void report_class_fetch_error(zend_string *class_name, uint32_t fetch_type) +static ZEND_COLD void report_class_fetch_error(const zend_string *class_name, uint32_t fetch_type) { if (fetch_type & ZEND_FETCH_CLASS_SILENT) { return; @@ -1704,6 +1750,218 @@ static ZEND_COLD void report_class_fetch_error(zend_string *class_name, uint32_t } } +/* Resolve a function/method-level generic type parameter at runtime by reading + * the current frame's T-table. Falls back to the parameter's declared bound when + * no concrete binding was supplied (e.g. the function was called without + * turbofish and inference produced nothing). Throws when neither a binding nor + * a usable class bound is available. */ +ZEND_API zend_class_entry *zend_resolve_generic_type_param(uint32_t param_index, uint32_t fetch_type) +{ + zend_execute_data *ex = EG(current_execute_data); + bool class_level = (fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TYPE_PARAM_CLASS; + zend_type_arg_table *table = NULL; + zend_generic_parameter_list *params = NULL; + + if (class_level) { + /* Class-level T's binding lives on the *monomorph* of the lexical + * scope — that may BE the called scope (`new Box::()`) or live + * deeper in the chain (`class IntBox extends Box`). Walk up + * from the called scope until we hit a direct child of the lexical + * scope, which is the mono that holds the binding. */ + zend_class_entry *lexical = ex ? ex->func->common.scope : NULL; + zend_class_entry *cur = ex ? zend_get_called_scope(ex) : NULL; + while (cur && cur->parent != lexical) { + cur = cur->parent; + } + if (cur) { + table = cur->generic_type_args; + } + if (lexical) { + params = lexical->generic_parameters; + } + } else if (ex && ZEND_USER_CODE(ex->func->type)) { + table = ex->type_args; + params = ex->func->op_array.generic_parameters; + } + + if (table && param_index < table->count && table->entries[param_index].name) { + /* Try the bound binding as a class name. If it isn't a class (e.g. + * scalar T-arg like `int`) the lookup returns NULL silently and we + * fall through to the parameter's declared bound — which is the only + * remaining thing a bare T-ref can resolve to. */ + uint32_t silent_fetch = (fetch_type & ~ZEND_FETCH_CLASS_EXCEPTION) + | ZEND_FETCH_CLASS_SILENT | ZEND_FETCH_CLASS_NO_AUTOLOAD; + zend_class_entry *ce = zend_fetch_class_by_name(table->entries[param_index].name, NULL, silent_fetch); + if (ce) return ce; + /* Not in the class table yet — retry with autoload before giving up, + * but only if the original fetch allowed it. */ + if (!(fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD)) { + ce = zend_fetch_class_by_name(table->entries[param_index].name, NULL, + (fetch_type & ~ZEND_FETCH_CLASS_EXCEPTION) | ZEND_FETCH_CLASS_SILENT); + if (ce) return ce; + } + } + + /* Resolution failed. Suppress the diagnostic when SILENT and no thrown + * exception is expected (catch path passes SILENT without EXCEPTION; the + * caller treats NULL as "no match" and proceeds). */ + bool suppress = (fetch_type & ZEND_FETCH_CLASS_SILENT) + && !(fetch_type & ZEND_FETCH_CLASS_EXCEPTION); + + if (params && param_index < params->count) { + zend_type bound = params->parameters[param_index].bound; + if (ZEND_TYPE_HAS_NAME(bound)) { + return zend_fetch_class_by_name(ZEND_TYPE_NAME(bound), NULL, fetch_type); + } + if (suppress) { + return NULL; + } + ZEND_ASSERT(params->parameters[param_index].name); + zend_throw_or_error(fetch_type, NULL, + "Cannot resolve generic type parameter %s at runtime: no binding was supplied and its bound is not a class", + ZSTR_VAL(params->parameters[param_index].name)); + return NULL; + } + + if (suppress) { + return NULL; + } + zend_throw_or_error(fetch_type, NULL, "Cannot resolve generic type parameter at runtime: not in a generic function or class scope"); + return NULL; +} + +/* Look up the function-level T-ref binding (current frame's T-table); returns + * NULL when the table is missing the slot, in which case the caller should + * fall back to the parameter's declared bound. */ +static zend_string *zend_resolve_fn_type_param_name(uint32_t index) +{ + zend_execute_data *ex = EG(current_execute_data); + if (!ex || !ZEND_USER_CODE(ex->func->type)) return NULL; + zend_type_arg_table *table = ex->type_args; + if (table && index < table->count && table->entries[index].name) { + return table->entries[index].name; + } + return NULL; +} + +/* Look up the class-level T-ref binding. The binding lives on the monomorph + * of the lexical scope — see the matching walk in zend_resolve_generic_type_param. */ +static zend_string *zend_resolve_class_type_param_name(uint32_t index) +{ + zend_execute_data *ex = EG(current_execute_data); + zend_class_entry *lexical = ex ? ex->func->common.scope : NULL; + zend_class_entry *cur = ex ? zend_get_called_scope(ex) : NULL; + while (cur && cur->parent != lexical) { + cur = cur->parent; + } + if (cur && cur->generic_type_args && index < cur->generic_type_args->count) { + return cur->generic_type_args->entries[index].name; + } + return NULL; +} + +/* Resolve a function/method-level generic type parameter's name to its bound's + * class name; for class-level params the bound is consulted on the lexical + * scope's parameter list. Used by deferred-generic substitution to fall back + * when no concrete binding was supplied at the call site. */ +static zend_string *zend_resolve_type_param_bound_name(const zend_type_parameter_ref *ref) +{ + zend_generic_parameter_list *params = NULL; + zend_execute_data *ex = EG(current_execute_data); + if (ref->origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE) { + zend_class_entry *lexical = ex ? ex->func->common.scope : NULL; + if (lexical) params = lexical->generic_parameters; + } else if (ex && ZEND_USER_CODE(ex->func->type)) { + params = ex->func->op_array.generic_parameters; + } + if (!params || ref->index >= params->count) return NULL; + zend_type bound = params->parameters[ref->index].bound; + if (ZEND_TYPE_HAS_NAME(bound)) return ZEND_TYPE_NAME(bound); + return NULL; +} + +/* Recursively append the canonical text for a substituted type fragment. The + * walk mirrors zend_generic_canonical_class_name, but substitutes T-refs + * against the current frame's bindings as it goes. Sets *failed when a + * binding is missing and no class bound is available. */ +static void zend_append_substituted_canonical(smart_str *buf, const zend_type *t, bool *failed) +{ + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*t)) { + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*t); + zend_string *name = (ref->origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE) + ? zend_resolve_class_type_param_name(ref->index) + : zend_resolve_fn_type_param_name(ref->index); + if (!name) name = zend_resolve_type_param_bound_name(ref); + if (!name) { + *failed = true; + return; + } + smart_str_append(buf, name); + return; + } + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*t)) { + const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*t); + if (nwa->name) smart_str_append(buf, nwa->name); + smart_str_appendc(buf, '<'); + for (uint32_t i = 0; i < nwa->count; i++) { + if (i > 0) smart_str_appendc(buf, ','); + zend_append_substituted_canonical(buf, &nwa->args[i], failed); + if (*failed) return; + } + smart_str_appendc(buf, '>'); + return; + } + /* Plain leaf (class name or pure scalar): defer to the canonical formatter. */ + zend_string *piece = zend_type_to_canonical_string(*t); + smart_str_append(buf, piece); + zend_string_release(piece); +} + +/* Resolve `instanceof Box` / `catch (Box $e)` and friends at runtime. + * Reads the compile-time pre-erasure type from the executing op_array's + * side table, substitutes T-refs against the current frame's bindings, and + * looks up the resulting monomorph (synthesizing it if needed via the + * standard class-lookup path). */ +ZEND_API zend_class_entry *zend_resolve_deferred_generic_class(uint32_t args_id, uint32_t fetch_type) +{ + zend_execute_data *ex = EG(current_execute_data); + bool suppress = (fetch_type & ZEND_FETCH_CLASS_SILENT) + && !(fetch_type & ZEND_FETCH_CLASS_EXCEPTION); + if (!ex || !ZEND_USER_CODE(ex->func->type)) { + if (suppress) return NULL; + zend_throw_or_error(fetch_type, NULL, + "Cannot resolve deferred generic type at runtime: not in a user function"); + return NULL; + } + + const zend_type *boxed = zend_generic_get_turbofish_args(&ex->func->op_array, args_id); + if (!boxed || !ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) { + if (suppress) return NULL; + zend_throw_or_error(fetch_type, NULL, + "Cannot resolve deferred generic type at runtime: missing side-table entry"); + return NULL; + } + + smart_str buf = {0}; + bool failed = false; + zend_append_substituted_canonical(&buf, boxed, &failed); + if (failed) { + smart_str_free(&buf); + if (suppress) return NULL; + zend_throw_or_error(fetch_type, NULL, + "Cannot resolve deferred generic type at runtime: no binding supplied for one of its type parameters and the parameter has no class bound"); + return NULL; + } + smart_str_0(&buf); + /* Intern the canonical name so EG(class_table) lookups can dispatch on + * pointer identity and repeat executions of the same opline with the + * same bindings hit a stable, shared string. */ + zend_string *canonical = zend_new_interned_string(buf.s); + zend_class_entry *ce = zend_fetch_class_by_name(canonical, NULL, fetch_type); + zend_string_release(canonical); + return ce; +} + zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type) /* {{{ */ { zend_class_entry *ce, *scope; @@ -1711,6 +1969,13 @@ zend_class_entry *zend_fetch_class(zend_string *class_name, uint32_t fetch_type) check_fetch_type: switch (fetch_sub_type) { + case ZEND_FETCH_CLASS_TYPE_PARAM: + case ZEND_FETCH_CLASS_TYPE_PARAM_CLASS: + return zend_resolve_generic_type_param( + zend_unpack_type_param_index(fetch_type), fetch_type); + case ZEND_FETCH_CLASS_GENERIC_DEFERRED: + return zend_resolve_deferred_generic_class( + zend_unpack_type_param_index(fetch_type), fetch_type); case ZEND_FETCH_CLASS_SELF: scope = zend_get_executed_scope(); if (UNEXPECTED(!scope)) { @@ -1774,7 +2039,7 @@ zend_class_entry *zend_fetch_class_with_scope( case 0: break; /* Other fetch types are not supported by this function. */ - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } ce = zend_lookup_class_ex(class_name, NULL, fetch_type); @@ -1851,7 +2116,7 @@ ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */ { - zend_op_array *op_array = &execute_data->func->op_array; + const zend_op_array *op_array = &execute_data->func->op_array; HashTable *ht = execute_data->symbol_table; /* copy real values from symbol table into CV slots and create @@ -1866,7 +2131,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ * if (zv) { if (Z_TYPE_P(zv) == IS_INDIRECT) { - zval *val = Z_INDIRECT_P(zv); + const zval *val = Z_INDIRECT_P(zv); ZVAL_COPY_VALUE(var, val); } else { @@ -1886,7 +2151,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ * ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */ { - zend_op_array *op_array = &execute_data->func->op_array; + const zend_op_array *op_array = &execute_data->func->op_array; HashTable *ht = execute_data->symbol_table; /* copy real values from CV slots into symbol table */ @@ -1920,7 +2185,7 @@ ZEND_API zend_result zend_set_local_var(zend_string *name, zval *value, bool for if (execute_data) { if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_ulong h = zend_string_hash_val(name); - zend_op_array *op_array = &execute_data->func->op_array; + const zend_op_array *op_array = &execute_data->func->op_array; if (EXPECTED(op_array->last_var)) { zend_string **str = op_array->vars; @@ -1963,7 +2228,7 @@ ZEND_API zend_result zend_set_local_var_str(const char *name, size_t len, zval * if (execute_data) { if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_ulong h = zend_hash_func(name, len); - zend_op_array *op_array = &execute_data->func->op_array; + const zend_op_array *op_array = &execute_data->func->op_array; if (EXPECTED(op_array->last_var)) { zend_string **str = op_array->vars; zend_string **end = str + op_array->last_var; diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index a4e5a38f90d8..4459c3015d15 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index becd53d7d08b..1e6887e444a6 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -44,7 +43,7 @@ You can use the following macro to check the extension API version for compatibi /* The first number is the engine version and the rest is the date (YYYYMMDD). * This way engine 2/3 API no. is always greater than engine 1 API no.. */ -#define ZEND_EXTENSION_API_NO 420240925 +#define ZEND_EXTENSION_API_NO 420250926 typedef struct _zend_extension_version_info { int zend_extension_api_no; diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index 97b7cdcc911b..c91436050856 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Aaron Piotrowski | | Martin Schröder | @@ -207,7 +206,12 @@ static zend_fiber_stack *zend_fiber_stack_allocate(size_t size) { void *pointer; const size_t page_size = zend_fiber_get_page_size(); - const size_t minimum_stack_size = page_size + ZEND_FIBER_GUARD_PAGES * page_size; + const size_t minimum_stack_size = page_size + ZEND_FIBER_GUARD_PAGES * page_size +#ifdef __SANITIZE_ADDRESS__ + // necessary correction due to ASAN redzones + * 6 +#endif + ; if (size < minimum_stack_size) { zend_throw_exception_ex(NULL, 0, "Fiber stack size is too small, it needs to be at least %zu bytes", minimum_stack_size); @@ -567,9 +571,9 @@ static ZEND_STACK_ALIGNED void zend_fiber_execute(zend_fiber_transfer *transfer) zend_fiber *fiber = EG(active_fiber); /* Determine the current error_reporting ini setting. */ - zend_long error_reporting = INI_INT("error_reporting"); - /* If error_reporting is 0 and not explicitly set to 0, INI_STR returns a null pointer. */ - if (!error_reporting && !INI_STR("error_reporting")) { + zend_long error_reporting = zend_ini_long_literal("error_reporting"); + /* If error_reporting is 0 and not explicitly set to 0, zend_ini_str returns a null pointer. */ + if (!error_reporting && !zend_ini_str_literal("error_reporting")) { error_reporting = E_ALL; } diff --git a/Zend/zend_fibers.h b/Zend/zend_fibers.h index 9442019bfa25..c72ffdc8f18e 100644 --- a/Zend/zend_fibers.h +++ b/Zend/zend_fibers.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Aaron Piotrowski | | Martin Schröder | @@ -155,7 +154,7 @@ static zend_always_inline zend_fiber *zend_fiber_from_context(zend_fiber_context { ZEND_ASSERT(context->kind == zend_ce_fiber && "Fiber context does not belong to a Zend fiber"); - return (zend_fiber *)(((char *) context) - XtOffsetOf(zend_fiber, context)); + return ZEND_CONTAINER_OF(context, zend_fiber, context); } static zend_always_inline zend_fiber_context *zend_fiber_get_context(zend_fiber *fiber) diff --git a/Zend/zend_fibers_arginfo.h b/Zend/zend_fibers_arginfo.h index 9db4db8d802a..31af8db130c6 100644 --- a/Zend/zend_fibers_arginfo.h +++ b/Zend/zend_fibers_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit zend_fibers.stub.php instead. * Stub hash: e82bbc8e81fe98873a9a5697a4b38e63a24379da */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Fiber___construct, 0, 0, 1) diff --git a/Zend/zend_float.c b/Zend/zend_float.c index 90af0c4a5f90..12fd0fd74f7f 100644 --- a/Zend/zend_float.c +++ b/Zend/zend_float.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | +----------------------------------------------------------------------+ diff --git a/Zend/zend_float.h b/Zend/zend_float.h index 63e0f6f7f69b..12aa02005c2a 100644 --- a/Zend/zend_float.h +++ b/Zend/zend_float.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Seiler | +----------------------------------------------------------------------+ diff --git a/Zend/zend_frameless_function.c b/Zend/zend_frameless_function.c index 7ccda0cfb570..be390744fd92 100644 --- a/Zend/zend_frameless_function.c +++ b/Zend/zend_frameless_function.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/Zend/zend_frameless_function.h b/Zend/zend_frameless_function.h index d64ca7ee15e2..b6f361f104b0 100644 --- a/Zend/zend_frameless_function.h +++ b/Zend/zend_frameless_function.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -65,7 +64,7 @@ dest_ht = NULL; \ ZVAL_COPY(&str_tmp, arg ## arg_num); \ arg ## arg_num = &str_tmp; \ - if (!zend_flf_parse_arg_str_slow(arg ## arg_num, &dest_str, arg_num)) { \ + if (!(dest_str = zend_flf_parse_arg_str_slow(arg ## arg_num, arg_num))) { \ zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY_OR_STRING, arg ## arg_num); \ goto flf_clean; \ } \ diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 8da55fcd48f6..5de2b69bf568 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Wang | | Dmitry Stogov | @@ -76,6 +75,7 @@ #include "zend_types.h" #include "zend_weakrefs.h" #include "zend_string.h" +#include "zend_exceptions.h" #ifndef GC_BENCH # define GC_BENCH 0 @@ -172,7 +172,9 @@ #define GC_IDX2PTR(idx) (GC_G(buf) + (idx)) #define GC_PTR2IDX(ptr) ((ptr) - GC_G(buf)) +/* Get the value to be placed in an unused buffer entry with the specified next unused list index */ #define GC_IDX2LIST(idx) ((void*)(uintptr_t)(((idx) * sizeof(void*)) | GC_UNUSED)) +/* Get the index of the next item in the unused list from the given root buffer entry. */ #define GC_LIST2IDX(list) (((uint32_t)(uintptr_t)(list)) / sizeof(void*)) /* GC buffers */ @@ -228,10 +230,16 @@ } while (0) /* unused buffers */ + +/* Are there any unused root buffer entries? */ #define GC_HAS_UNUSED() \ (GC_G(unused) != GC_INVALID) + +/* Get the next unused entry and remove it from the list */ #define GC_FETCH_UNUSED() \ gc_fetch_unused() + +/* Add a root buffer entry to the unused list */ #define GC_LINK_UNUSED(root) \ gc_link_unused(root) @@ -244,12 +252,23 @@ ZEND_API int (*gc_collect_cycles)(void); +/* The type of a root buffer entry. + * + * The lower two bits are used for flags and need to be masked out to + * reconstruct a pointer. + * + * When a node in the root buffer is removed, the non-flag bits of the + * unused entry are used to store the index of the next entry in the unused + * list. */ typedef struct _gc_root_buffer { zend_refcounted *ref; } gc_root_buffer; typedef struct _zend_gc_globals { - gc_root_buffer *buf; /* preallocated arrays of buffers */ + /* The root buffer, which stores possible roots of reference cycles. It is + * also used to store garbage to be collected at the end of a run. + * A single array which is reallocated as necessary. */ + gc_root_buffer *buf; bool gc_enabled; bool gc_active; /* GC currently running, forbid nested GC */ @@ -262,13 +281,13 @@ typedef struct _zend_gc_globals { uint32_t buf_size; /* size of the GC buffer */ uint32_t num_roots; /* number of roots in GC buffer */ - uint32_t gc_runs; - uint32_t collected; + uint32_t gc_runs; /* number of GC runs since reset */ + uint32_t collected; /* number of collected nodes since reset */ - zend_hrtime_t activated_at; - zend_hrtime_t collector_time; - zend_hrtime_t dtor_time; - zend_hrtime_t free_time; + zend_hrtime_t activated_at; /* the timestamp of the last reset */ + zend_hrtime_t collector_time; /* time spent running GC (ns) */ + zend_hrtime_t dtor_time; /* time spent calling destructors (ns) */ + zend_hrtime_t free_time; /* time spent destroying nodes and freeing memory (ns) */ uint32_t dtor_idx; /* root buffer index */ uint32_t dtor_end; @@ -313,6 +332,7 @@ static zend_gc_globals gc_globals; typedef struct _gc_stack gc_stack; +/* The stack used for graph traversal is stored as a linked list of segments */ struct _gc_stack { gc_stack *prev; gc_stack *next; @@ -375,6 +395,11 @@ static void gc_stack_free(gc_stack *stack) } } +/* Map a full index to a compressed index. + * + * The root buffer can have up to 2^30 entries, but we only have 20 bits to + * store the index. So we use the 1<<19 bit as a compression flag and use the + * other 19 bits to store the index modulo 2^19. */ static zend_always_inline uint32_t gc_compress(uint32_t idx) { if (EXPECTED(idx < GC_MAX_UNCOMPRESSED)) { @@ -383,6 +408,9 @@ static zend_always_inline uint32_t gc_compress(uint32_t idx) return (idx % GC_MAX_UNCOMPRESSED) | GC_MAX_UNCOMPRESSED; } +/* Find the root buffer entry given a pointer and a compressed index. + * Iterate through the root buffer in steps of 2^19 until the pointer + * matches. */ static zend_always_inline gc_root_buffer* gc_decompress(zend_refcounted *ref, uint32_t idx) { gc_root_buffer *root = GC_IDX2PTR(idx); @@ -401,6 +429,8 @@ static zend_always_inline gc_root_buffer* gc_decompress(zend_refcounted *ref, ui } } +/* Get the index of the next unused root buffer entry, and remove it from the + * unused list. GC_HAS_UNUSED() must be true before calling this. */ static zend_always_inline uint32_t gc_fetch_unused(void) { uint32_t idx; @@ -414,6 +444,7 @@ static zend_always_inline uint32_t gc_fetch_unused(void) return idx; } +/* Add a root buffer entry to the unused list */ static zend_always_inline void gc_link_unused(gc_root_buffer *root) { root->ref = GC_IDX2LIST(GC_G(unused)); @@ -463,6 +494,7 @@ static void gc_trace_ref(zend_refcounted *ref) { } #endif +/* Mark a root buffer entry unused */ static zend_always_inline void gc_remove_from_roots(gc_root_buffer *root) { GC_LINK_UNUSED(root); @@ -480,10 +512,10 @@ static void root_buffer_dtor(zend_gc_globals *gc_globals) static void gc_globals_ctor_ex(zend_gc_globals *gc_globals) { - gc_globals->gc_enabled = 0; - gc_globals->gc_active = 0; - gc_globals->gc_protected = 1; - gc_globals->gc_full = 0; + gc_globals->gc_enabled = false; + gc_globals->gc_active = false; + gc_globals->gc_protected = true; + gc_globals->gc_full = false; gc_globals->buf = NULL; gc_globals->unused = GC_INVALID; @@ -565,6 +597,8 @@ void gc_reset(void) GC_G(activated_at) = zend_hrtime(); } +/* Enable/disable the garbage collector. + * Initialize globals if necessary. */ ZEND_API bool gc_enable(bool enable) { bool old_enabled = GC_G(gc_enabled); @@ -584,6 +618,7 @@ ZEND_API bool gc_enabled(void) return GC_G(gc_enabled); } +/* Protect the GC root buffer (prevent additions) */ ZEND_API bool gc_protect(bool protect) { bool old_protected = GC_G(gc_protected); @@ -621,6 +656,7 @@ static void gc_grow_root_buffer(void) GC_G(buf_size) = new_size; } +/* Adjust the GC activation threshold given the number of nodes collected by the last run */ static void gc_adjust_threshold(int count) { uint32_t new_threshold; @@ -651,6 +687,7 @@ static void gc_adjust_threshold(int count) } } +/* Perform a GC run and then add a node as a possible root. */ static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full(zend_refcounted *ref) { uint32_t idx; @@ -695,6 +732,8 @@ static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full(zend_refc GC_BENCH_PEAK(root_buf_peak, root_buf_length); } +/* Add a possible root node to the buffer. + * Maybe perform a GC run. */ ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref) { uint32_t idx; @@ -731,6 +770,7 @@ ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref) GC_BENCH_PEAK(root_buf_peak, root_buf_length); } +/* Add an extra root during a GC run */ static void ZEND_FASTCALL gc_extra_root(zend_refcounted *ref) { uint32_t idx; @@ -764,6 +804,7 @@ static void ZEND_FASTCALL gc_extra_root(zend_refcounted *ref) GC_BENCH_PEAK(root_buf_peak, root_buf_length); } +/* Remove a node from the root buffer given its compressed index */ static zend_never_inline void ZEND_FASTCALL gc_remove_compressed(zend_refcounted *ref, uint32_t idx) { gc_root_buffer *root = gc_decompress(ref, idx); @@ -793,6 +834,10 @@ ZEND_API void ZEND_FASTCALL gc_remove_from_buffer(zend_refcounted *ref) gc_remove_from_roots(root); } +/* Mark all nodes reachable from ref as black (live). Restore the reference + * counts decremented by gc_mark_grey(). See ScanBlack() in Bacon & Rajan. + * To implement a depth-first search, discovered nodes are added to a stack + * which is processed iteratively. */ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack) { HashTable *ht; @@ -992,6 +1037,8 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack) } } +/* Traverse the graph of nodes referred to by ref. Decrement the reference + * counts and mark visited nodes grey. See MarkGray() in Bacon & Rajan. */ static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack) { HashTable *ht; @@ -1204,6 +1251,9 @@ static void gc_compact(void) } } +/* For all roots marked purple, traverse the graph, decrementing the reference + * count of their child nodes. Mark visited nodes grey so that they are not + * visited again. See MarkRoots() in Bacon & Rajan. */ static void gc_mark_roots(gc_stack *stack) { gc_root_buffer *current, *last; @@ -1223,6 +1273,10 @@ static void gc_mark_roots(gc_stack *stack) } } +/* Traverse the reference graph of ref. Evaluate grey nodes and mark them + * black (to keep) or white (to free). Note that nodes initially marked white + * may later become black if they are visited from a live node. + * See Scan() in Bacon & Rajan. */ static void gc_scan(zend_refcounted *ref, gc_stack *stack) { HashTable *ht; @@ -1376,6 +1430,7 @@ static void gc_scan(zend_refcounted *ref, gc_stack *stack) } } +/* Scan all roots, coloring grey nodes black or white */ static void gc_scan_roots(gc_stack *stack) { uint32_t idx, end; @@ -1409,6 +1464,8 @@ static void gc_scan_roots(gc_stack *stack) } } +/* Add a node to the buffer with the garbage flag, so that it will be + * destroyed and freed when the scan is complete. */ static void gc_add_garbage(zend_refcounted *ref) { uint32_t idx; @@ -1434,6 +1491,7 @@ static void gc_add_garbage(zend_refcounted *ref) GC_G(num_roots)++; } +/* Traverse the reference graph from ref, marking any white nodes as garbage. */ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *stack) { int count = 0; @@ -1622,6 +1680,7 @@ static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *sta return count; } +/* Traverse the reference graph from all roots, marking white nodes as garbage. */ static int gc_collect_roots(uint32_t *flags, gc_stack *stack) { uint32_t idx, end; @@ -1808,6 +1867,7 @@ static ZEND_COLD ZEND_NORETURN void gc_start_destructor_fiber_error(void) zend_error_noreturn(E_ERROR, "Unable to start destructor fiber"); } +/* Call destructors for garbage in the buffer. */ static zend_always_inline zend_result gc_call_destructors(uint32_t idx, uint32_t end, zend_fiber *fiber) { gc_root_buffer *current; @@ -1872,7 +1932,18 @@ static zend_fiber *gc_create_destructor_fiber(void) return fiber; } -static zend_never_inline void gc_call_destructors_in_fiber(uint32_t end) +static void remember_prev_exception(zend_object **prev_exception) +{ + if (EG(exception)) { + if (*prev_exception) { + zend_exception_set_previous(EG(exception), *prev_exception); + } + *prev_exception = EG(exception); + EG(exception) = NULL; + } +} + +static zend_never_inline void gc_call_destructors_in_fiber(void) { ZEND_ASSERT(!GC_G(dtor_fiber_running)); @@ -1881,12 +1952,17 @@ static zend_never_inline void gc_call_destructors_in_fiber(uint32_t end) GC_G(dtor_idx) = GC_FIRST_ROOT; GC_G(dtor_end) = GC_G(first_unused); + zend_object *exception = NULL; + remember_prev_exception(&exception); + if (UNEXPECTED(!fiber)) { fiber = gc_create_destructor_fiber(); } else { zend_fiber_resume(fiber, NULL, NULL); } + remember_prev_exception(&exception); + for (;;) { /* At this point, fiber has executed until suspension */ GC_TRACE("resumed from destructor fiber"); @@ -1900,7 +1976,9 @@ static zend_never_inline void gc_call_destructors_in_fiber(uint32_t end) /* We do not own the fiber anymore. It may be collected if the * application does not reference it. */ zend_object_release(&fiber->std); + remember_prev_exception(&exception); fiber = gc_create_destructor_fiber(); + remember_prev_exception(&exception); continue; } else { /* Fiber suspended itself after calling all destructors */ @@ -1908,13 +1986,16 @@ static zend_never_inline void gc_call_destructors_in_fiber(uint32_t end) break; } } + + EG(exception) = exception; } +/* Perform a garbage collection run. The default implementation of gc_collect_cycles. */ ZEND_API int zend_gc_collect_cycles(void) { int total_count = 0; - bool should_rerun_gc = 0; - bool did_rerun_gc = 0; + bool should_rerun_gc = false; + bool did_rerun_gc = false; zend_hrtime_t start_time = zend_hrtime(); if (GC_G(num_roots) && !GC_G(gc_active)) { @@ -1968,7 +2049,7 @@ ZEND_API int zend_gc_collect_cycles(void) * modify any refcounts, so we have no real way to detect this situation * short of rerunning full GC tracing. What we do instead is to only run * destructors at this point and automatically re-run GC afterwards. */ - should_rerun_gc = 1; + should_rerun_gc = true; /* Mark all roots for which a dtor will be invoked as DTOR_GARBAGE. Additionally * color them purple. This serves a double purpose: First, they should be @@ -2013,7 +2094,7 @@ ZEND_API int zend_gc_collect_cycles(void) if (EXPECTED(!EG(active_fiber))) { gc_call_destructors(GC_FIRST_ROOT, end, NULL); } else { - gc_call_destructors_in_fiber(end); + gc_call_destructors_in_fiber(); } GC_G(dtor_time) += zend_hrtime() - dtor_start_time; @@ -2094,7 +2175,7 @@ ZEND_API int zend_gc_collect_cycles(void) * up. We do this only once: If we encounter more destructors on the second run, we'll not * run GC another time. */ if (should_rerun_gc && !did_rerun_gc) { - did_rerun_gc = 1; + did_rerun_gc = true; goto rerun_gc; } diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index 06f550647bd7..b72b90ccd5ef 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: David Wang | | Dmitry Stogov | diff --git a/Zend/zend_gdb.c b/Zend/zend_gdb.c index 102b0b318199..0c2a82a144c0 100644 --- a/Zend/zend_gdb.c +++ b/Zend/zend_gdb.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -109,7 +108,7 @@ ZEND_API void zend_gdb_unregister_all(void) ZEND_API bool zend_gdb_present(void) { - bool ret = 0; + bool ret = false; #if defined(__linux__) /* netbsd while having this procfs part, does not hold the tracer pid */ int fd = open("/proc/self/status", O_RDONLY); @@ -133,7 +132,7 @@ ZEND_API bool zend_gdb_present(void) snprintf(buf, sizeof(buf), "/proc/%d/exe", (int)pid); if (readlink(buf, out, sizeof(out) - 1) > 0) { if (strstr(out, "gdb")) { - ret = 1; + ret = true; } } } diff --git a/Zend/zend_gdb.h b/Zend/zend_gdb.h index aad0fefb097b..554791f5255a 100644 --- a/Zend/zend_gdb.h +++ b/Zend/zend_gdb.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index a6ea91a7425b..50504be4ea36 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Bob Weinand | @@ -47,6 +46,7 @@ ZEND_API void zend_generator_restore_call_stack(zend_generator *generator) /* {{ Z_PTR(call->This)); memcpy(((zval*)new_call) + ZEND_CALL_FRAME_SLOT, ((zval*)call) + ZEND_CALL_FRAME_SLOT, ZEND_CALL_NUM_ARGS(call) * sizeof(zval)); new_call->extra_named_params = call->extra_named_params; + new_call->type_args = call->type_args; new_call->prev_execute_data = prev_call; prev_call = new_call; @@ -85,6 +85,10 @@ ZEND_API zend_execute_data* zend_generator_freeze_call_stack(zend_execute_data * new_call->prev_execute_data = prev_call; prev_call = new_call; + /* Frozen copy owns type_args; null the original so frame teardown + * below does not free what the generator still needs on resume. */ + call->type_args = NULL; + new_call = call->prev_execute_data; zend_vm_stack_free_call_frame(call); call = new_call; @@ -147,6 +151,10 @@ ZEND_API void zend_generator_close(zend_generator *generator, bool finished_exec if (EX_CALL_INFO() & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { zend_free_extra_named_params(execute_data->extra_named_params); } + if (execute_data->type_args) { + zend_type_arg_table_destroy(execute_data->type_args); + execute_data->type_args = NULL; + } if (EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) { OBJ_RELEASE(Z_OBJ(execute_data->This)); @@ -179,7 +187,7 @@ static void zend_generator_remove_child(zend_generator_node *node, zend_generato node->child.single = NULL; } else { HashTable *ht = node->child.ht; - zend_hash_index_del(ht, (zend_ulong) child); + zend_hash_index_del(ht, (zend_ulong)(uintptr_t) child); if (node->children == 2) { zend_generator *other_child; ZEND_HASH_FOREACH_PTR(ht, other_child) { @@ -244,7 +252,6 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ zend_generator *current_generator = zend_generator_get_current(generator); zend_execute_data *ex = generator->execute_data; uint32_t op_num, try_catch_offset; - int i; /* If current_generator is running in a fiber, there are 2 cases to consider: * - If generator is also marked with ZEND_GENERATOR_IN_FIBER, then the @@ -281,7 +288,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ if (EXPECTED(!ex) || EXPECTED(!(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) || CG(unclean_shutdown)) { - zend_generator_close(generator, 0); + zend_generator_close(generator, false); return; } @@ -289,7 +296,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ try_catch_offset = -1; /* Find the innermost try/catch that we are inside of. */ - for (i = 0; i < ex->func->op_array.last_try_catch; i++) { + for (uint32_t i = 0; i < ex->func->op_array.last_try_catch; i++) { zend_try_catch_element *try_catch = &ex->func->op_array.try_catch_array[i]; if (op_num < try_catch->try_op) { break; @@ -309,9 +316,20 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ ZEND_CALL_VAR(ex, ex->func->op_array.opcodes[try_catch->finally_end].op1.var); zend_generator_cleanup_unfinished_execution(generator, ex, try_catch->finally_op); - zend_object *old_exception = EG(exception); - const zend_op *old_opline_before_exception = EG(opline_before_exception); - EG(exception) = NULL; + + zend_object *old_exception = NULL; + const zend_op *old_opline_before_exception = NULL; + if (EG(exception)) { + if (EG(current_execute_data) + && EG(current_execute_data)->opline + && EG(current_execute_data)->opline->opcode == ZEND_HANDLE_EXCEPTION) { + EG(current_execute_data)->opline = EG(opline_before_exception); + old_opline_before_exception = EG(opline_before_exception); + } + old_exception = EG(exception); + EG(exception) = NULL; + } + Z_OBJ_P(fast_call) = NULL; Z_OPLINE_NUM_P(fast_call) = (uint32_t)-1; @@ -321,7 +339,10 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ zend_generator_resume(generator); if (old_exception) { - EG(opline_before_exception) = old_opline_before_exception; + if (old_opline_before_exception) { + EG(current_execute_data)->opline = EG(exception_op); + EG(opline_before_exception) = old_opline_before_exception; + } if (EG(exception)) { zend_exception_set_previous(EG(exception), old_exception); } else { @@ -351,7 +372,7 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ try_catch_offset--; } - zend_generator_close(generator, 0); + zend_generator_close(generator, false); } /* }}} */ @@ -359,7 +380,7 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */ { zend_generator *generator = (zend_generator*) object; - zend_generator_close(generator, 0); + zend_generator_close(generator, false); if (generator->func && (generator->func->common.fn_flags & ZEND_ACC_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(generator->func)); @@ -498,8 +519,14 @@ ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_ return ptr; } -static void zend_generator_throw_exception(zend_generator *generator, zval *exception) +static zend_result zend_generator_throw_exception(zend_generator *generator, zval *exception) { + if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) { + zval_ptr_dtor(exception); + zend_throw_error(NULL, "Cannot resume an already running generator"); + return FAILURE; + } + zend_execute_data *original_execute_data = EG(current_execute_data); /* Throw the exception in the context of the generator. Decrementing the opline @@ -520,6 +547,8 @@ static void zend_generator_throw_exception(zend_generator *generator, zval *exce } EG(current_execute_data) = original_execute_data; + + return SUCCESS; } static void zend_generator_add_child(zend_generator *generator, zend_generator *child) @@ -537,7 +566,7 @@ static void zend_generator_add_child(zend_generator *generator, zend_generator * node->child.ht = ht; } - zend_hash_index_add_new_ptr(node->child.ht, (zend_ulong) child, child); + zend_hash_index_add_new_ptr(node->child.ht, (zend_ulong)(uintptr_t) child, child); } ++node->children; @@ -633,7 +662,9 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator } else { zval_ptr_dtor(&new_root->value); ZVAL_COPY(&new_root->value, &new_root_parent->value); - ZVAL_COPY(ZEND_CALL_VAR(new_root->execute_data, yield_from->result.var), &new_root_parent->retval); + if (yield_from->result_type != IS_UNUSED) { + ZVAL_COPY(ZEND_CALL_VAR(new_root->execute_data, yield_from->result.var), &new_root_parent->retval); + } } } } @@ -786,6 +817,8 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */ orig_generator->execute_fake.prev_execute_data = original_execute_data; } + generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING; + /* Ensure this is run after executor_data swap to have a proper stack trace */ if (UNEXPECTED(!Z_ISUNDEF(generator->values))) { if (EXPECTED(zend_generator_get_next_delegated_value(generator) == SUCCESS)) { @@ -794,7 +827,7 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */ EG(jit_trace_num) = original_jit_trace_num; orig_generator->flags &= ~(ZEND_GENERATOR_DO_INIT | ZEND_GENERATOR_IN_FIBER); - generator->flags &= ~ZEND_GENERATOR_IN_FIBER; + generator->flags &= ~(ZEND_GENERATOR_CURRENTLY_RUNNING | ZEND_GENERATOR_IN_FIBER); return; } /* If there are no more delegated values, resume the generator @@ -817,7 +850,6 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */ * account for the following increment */ || (generator->flags & ZEND_GENERATOR_FORCED_CLOSE)); generator->execute_data->opline++; - generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING; if (!ZEND_OBSERVER_ENABLED) { zend_execute_ex(generator->execute_data); } else { @@ -847,7 +879,7 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */ * its calling frame (see above in if (check_yield_from). */ if (UNEXPECTED(EG(exception) != NULL)) { if (generator == orig_generator) { - zend_generator_close(generator, 0); + zend_generator_close(generator, false); if (!EG(current_execute_data)) { zend_throw_exception_internal(NULL); } else if (EG(current_execute_data)->func && @@ -1025,7 +1057,9 @@ ZEND_METHOD(Generator, throw) if (generator->execute_data) { zend_generator *root = zend_generator_get_current(generator); - zend_generator_throw_exception(root, exception); + if (zend_generator_throw_exception(root, exception) == FAILURE) { + return; + } zend_generator_resume(generator); diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index e7b01fb20ad7..73dd9ddc1f91 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Nikita Popov | | Bob Weinand | diff --git a/Zend/zend_generators_arginfo.h b/Zend/zend_generators_arginfo.h index 54a6744af1b6..6d8d7989c423 100644 --- a/Zend/zend_generators_arginfo.h +++ b/Zend/zend_generators_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit zend_generators.stub.php instead. * Stub hash: d376e984db0db6ccd9356f632f9d7e1382b2afb7 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Generator_rewind, 0, 0, IS_VOID, 0) diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 079bfb99cacc..4ae7660c42f8 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -74,6 +73,7 @@ typedef struct _zend_vm_stack *zend_vm_stack; typedef struct _zend_ini_entry zend_ini_entry; typedef struct _zend_fiber_context zend_fiber_context; typedef struct _zend_fiber zend_fiber; +typedef struct _zend_error_info zend_error_info; typedef enum { ZEND_MEMOIZE_NONE, @@ -81,6 +81,12 @@ typedef enum { ZEND_MEMOIZE_FETCH, } zend_memoize_mode; +typedef struct zend_err_buf { + uint32_t size; + uint32_t capacity; + zend_error_info **errors; +} zend_err_buf; + struct _zend_compiler_globals { zend_stack loop_var_stack; @@ -88,7 +94,7 @@ struct _zend_compiler_globals { zend_string *compiled_filename; - int zend_lineno; + uint32_t zend_lineno; zend_op_array *active_op_array; @@ -158,6 +164,25 @@ struct _zend_compiler_globals { uint32_t internal_run_time_cache_size; zend_stack short_circuiting_opnums; + + uint32_t type_arg_depth; + int type_arg_residual_token; + + struct _zend_generic_scope_entry *generic_scope; + + /* Set while compiling a type expression that has no instance binding for + * the enclosing class's type parameters (i.e. a static method's + * parameter/return types or a static property's type). Class-origin type + * parameter references resolved in this context are a compile error. */ + bool in_static_member_type; + + struct _zend_inheritance_binding_cache *inheritance_binding_cache; + + struct { + zend_class_entry *target; + const zend_type *args; + uint32_t arity; + } inheritance_binding_hint; #ifdef ZTS uint32_t copied_functions_count; #endif @@ -198,13 +223,21 @@ struct _zend_executor_globals { size_t vm_stack_page_size; struct _zend_execute_data *current_execute_data; - zend_class_entry *fake_scope; /* used to avoid checks accessing properties */ + const zend_class_entry *fake_scope; /* used to avoid checks accessing properties */ + + /* Set while a monomorph (e.g. Box) is being linked against its base. + * Bypasses the FINAL/READONLY checks the linker would otherwise raise + * on a user `extends FinalClass`, since monomorph synthesis is engine- + * internal and the resulting monomorph re-acquires the suppressed bits. + * Replaces a previous design that mutated base->ce_flags in place, which + * would SIGSEGV when base lived in read-only opcache SHM. */ + bool monomorph_synthesis_active; uint32_t jit_trace_num; /* Used by tracing JIT to reference the currently running trace */ zend_execute_data *current_observed_frame; - int ticks_count; + uint32_t ticks_count; zend_long precision; @@ -220,7 +253,7 @@ struct _zend_executor_globals { zend_atomic_bool vm_interrupt; zend_atomic_bool timed_out; - HashTable *in_autoload; + HashTable autoload_current_classnames; zend_long hard_timeout; void *stack_base; @@ -255,7 +288,7 @@ struct _zend_executor_globals { zend_objects_store objects_store; zend_lazy_objects_store lazy_objects_store; - zend_object *exception, *prev_exception; + zend_object *exception; const zend_op *opline_before_exception; zend_op exception_op[3]; @@ -295,10 +328,10 @@ struct _zend_executor_globals { size_t fiber_stack_size; /* If record_errors is enabled, all emitted diagnostics will be recorded, - * in addition to being processed as usual. */ + * and their processing is delayed until zend_emit_recorded_errors() + * is called or a fatal diagnostic is emitted. */ bool record_errors; - uint32_t num_errors; - zend_error_info **errors; + zend_err_buf errors; /* Override filename or line number of thrown errors and exceptions */ zend_string *filename_override; @@ -318,6 +351,8 @@ struct _zend_executor_globals { zend_strtod_state strtod_state; + HashTable callable_convert_cache; + void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; @@ -340,7 +375,7 @@ struct _zend_ini_scanner_globals { zend_stack state_stack; zend_string *filename; - int lineno; + uint32_t lineno; /* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */ int scanner_mode; diff --git a/Zend/zend_globals_macros.h b/Zend/zend_globals_macros.h index d3cd9f923eee..bde10a0989d1 100644 --- a/Zend/zend_globals_macros.h +++ b/Zend/zend_globals_macros.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 66cfb250d1fe..2913af9c2b5f 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -168,7 +167,7 @@ static zend_always_inline void zend_hash_real_init_mixed_ex(HashTable *ht) void *data; uint32_t nSize = ht->nTableSize; - ZEND_ASSERT(HT_SIZE_TO_MASK(nSize)); + ZEND_ASSERT(HT_SIZE_TO_MASK(nSize) != 0); if (UNEXPECTED(GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)) { data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), 1); @@ -281,14 +280,14 @@ ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_ ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void) { HashTable *ht = emalloc(sizeof(HashTable)); - _zend_hash_init_int(ht, HT_MIN_SIZE, ZVAL_PTR_DTOR, 0); + _zend_hash_init_int(ht, HT_MIN_SIZE, ZVAL_PTR_DTOR, false); return ht; } ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize) { HashTable *ht = emalloc(sizeof(HashTable)); - _zend_hash_init_int(ht, nSize, ZVAL_PTR_DTOR, 0); + _zend_hash_init_int(ht, nSize, ZVAL_PTR_DTOR, false); return ht; } @@ -296,7 +295,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_new_pair(const zval *val1, const zval *va { zval *zv; HashTable *ht = emalloc(sizeof(HashTable)); - _zend_hash_init_int(ht, HT_MIN_SIZE, ZVAL_PTR_DTOR, 0); + _zend_hash_init_int(ht, HT_MIN_SIZE, ZVAL_PTR_DTOR, false); ht->nNumUsed = ht->nNumOfElements = ht->nNextFreeElement = 2; zend_hash_real_init_packed_ex(ht); @@ -350,7 +349,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht) uint32_t i; uint32_t nSize = ht->nTableSize; - ZEND_ASSERT(HT_SIZE_TO_MASK(nSize)); + ZEND_ASSERT(HT_SIZE_TO_MASK(nSize) != 0); HT_ASSERT_RC1(ht); // Alloc before assign to avoid inconsistencies on OOM @@ -398,7 +397,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, bool if (nSize == 0) return; - ZEND_ASSERT(HT_SIZE_TO_MASK(nSize)); + ZEND_ASSERT(HT_SIZE_TO_MASK(nSize) != 0); if (UNEXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) { if (nSize > ht->nTableSize) { @@ -634,8 +633,15 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval && EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) { HT_DEC_ITERATORS_COUNT(iter->ht); } - SEPARATE_ARRAY(array); - ht = Z_ARRVAL_P(array); + + /* Inlined SEPARATE_ARRAY() with updating of iterator when EG(ht_iterators) grows. */ + if (UNEXPECTED(GC_REFCOUNT(ht) > 1)) { + ZVAL_ARR(array, zend_array_dup(ht)); + GC_TRY_DELREF(ht); + iter = EG(ht_iterators) + idx; + ht = Z_ARRVAL_P(array); + } + if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) { HT_INC_ITERATORS_COUNT(ht); } @@ -1055,6 +1061,13 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_str_add_new(HashTable *ht, const char *st return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_ADD_NEW); } +ZEND_API zval* ZEND_FASTCALL zend_hash_str_lookup(HashTable *ht, const char *str, size_t len) +{ + zend_ulong h = zend_hash_func(str, len); + + return _zend_hash_str_add_or_update_i(ht, str, len, h, NULL, HASH_LOOKUP); +} + ZEND_API zval* ZEND_FASTCALL zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h) { zval dummy; @@ -1097,7 +1110,10 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, if ((flag & (HASH_ADD_NEW|HASH_ADD_NEXT)) != (HASH_ADD_NEW|HASH_ADD_NEXT) && h < ht->nNumUsed) { zv = ht->arPacked + h; - if (Z_TYPE_P(zv) != IS_UNDEF) { + if (flag & HASH_ADD_NEW) { + ZEND_ASSERT(Z_TYPE_P(zv) == IS_UNDEF); + goto convert_to_hash; + } else if (Z_TYPE_P(zv) != IS_UNDEF) { if (flag & HASH_LOOKUP) { return zv; } @@ -1310,7 +1326,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht) uint32_t nSize = ht->nTableSize + ht->nTableSize; Bucket *old_buckets = ht->arData; - ZEND_ASSERT(HT_SIZE_TO_MASK(nSize)); + ZEND_ASSERT(HT_SIZE_TO_MASK(nSize) != 0); new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); ht->nTableSize = nSize; @@ -1378,7 +1394,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht) q->key = p->key; Z_NEXT(q->val) = HT_HASH(ht, nIndex); HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j); - if (UNEXPECTED(ht->nInternalPointer == i)) { + if (UNEXPECTED(ht->nInternalPointer > j && ht->nInternalPointer <= i)) { ht->nInternalPointer = j; } q++; @@ -1397,7 +1413,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht) q->key = p->key; Z_NEXT(q->val) = HT_HASH(ht, nIndex); HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j); - if (UNEXPECTED(ht->nInternalPointer == i)) { + if (UNEXPECTED(ht->nInternalPointer > j && ht->nInternalPointer <= i)) { ht->nInternalPointer = j; } if (UNEXPECTED(i >= iter_pos)) { @@ -2368,7 +2384,7 @@ static zend_always_inline void zend_array_dup_packed_elements(const HashTable *s const zval *end = p + source->nNumUsed; do { - if (!zend_array_dup_value(source, p, q, 1, with_holes)) { + if (!zend_array_dup_value(source, p, q, true, with_holes)) { if (with_holes) { ZVAL_UNDEF(q); } @@ -2393,13 +2409,13 @@ static zend_always_inline uint32_t zend_array_dup_elements(const HashTable *sour } do { - if (!zend_array_dup_element(source, target, idx, p, q, 0, static_keys, with_holes)) { + if (!zend_array_dup_element(source, target, idx, p, q, false, static_keys, with_holes)) { uint32_t target_idx = idx; idx++; p++; if (EXPECTED(!HT_HAS_ITERATORS(target))) { while (p != end) { - if (zend_array_dup_element(source, target, target_idx, p, q, 0, static_keys, with_holes)) { + if (zend_array_dup_element(source, target, target_idx, p, q, false, static_keys, with_holes)) { if (source->nInternalPointer == idx) { target->nInternalPointer = target_idx; } @@ -2412,7 +2428,7 @@ static zend_always_inline uint32_t zend_array_dup_elements(const HashTable *sour uint32_t iter_pos = zend_hash_iterators_lower_pos(target, idx); while (p != end) { - if (zend_array_dup_element(source, target, target_idx, p, q, 0, static_keys, with_holes)) { + if (zend_array_dup_element(source, target, target_idx, p, q, false, static_keys, with_holes)) { if (source->nInternalPointer == idx) { target->nInternalPointer = target_idx; } @@ -2457,6 +2473,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(const HashTable *source) target->nTableSize = HT_MIN_SIZE; HT_SET_DATA_ADDR(target, &uninitialized_bucket); } else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) { + ZEND_ASSERT(!(HT_FLAGS(source) & HASH_FLAG_HAS_EMPTY_IND)); HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK; target->nTableMask = source->nTableMask; target->nNumUsed = source->nNumUsed; @@ -2473,6 +2490,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(const HashTable *source) memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source)); } } else if (HT_IS_PACKED(source)) { + ZEND_ASSERT(!(HT_FLAGS(source) & HASH_FLAG_HAS_EMPTY_IND)); HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK; target->nTableMask = HT_MIN_MASK; target->nNumUsed = source->nNumUsed; @@ -2487,12 +2505,13 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(const HashTable *source) HT_HASH_RESET_PACKED(target); if (HT_IS_WITHOUT_HOLES(target)) { - zend_array_dup_packed_elements(source, target, 0); + zend_array_dup_packed_elements(source, target, false); } else { - zend_array_dup_packed_elements(source, target, 1); + zend_array_dup_packed_elements(source, target, true); } } else { - HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK; + /* Indirects are removed during duplication, remove HASH_FLAG_HAS_EMPTY_IND accordingly. */ + HT_FLAGS(target) = HT_FLAGS(source) & (HASH_FLAG_MASK & ~HASH_FLAG_HAS_EMPTY_IND); target->nTableMask = source->nTableMask; target->nNextFreeElement = source->nNextFreeElement; target->nInternalPointer = @@ -2505,15 +2524,15 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(const HashTable *source) if (HT_HAS_STATIC_KEYS_ONLY(target)) { if (HT_IS_WITHOUT_HOLES(source)) { - idx = zend_array_dup_elements(source, target, 1, 0); + idx = zend_array_dup_elements(source, target, true, false); } else { - idx = zend_array_dup_elements(source, target, 1, 1); + idx = zend_array_dup_elements(source, target, true, true); } } else { if (HT_IS_WITHOUT_HOLES(source)) { - idx = zend_array_dup_elements(source, target, 0, 0); + idx = zend_array_dup_elements(source, target, false, false); } else { - idx = zend_array_dup_elements(source, target, 0, 1); + idx = zend_array_dup_elements(source, target, false, true); } } target->nNumUsed = idx; @@ -2841,8 +2860,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_hash_move_backwards_ex(const HashTable * } -/* This function should be made binary safe */ -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos) +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos) { uint32_t idx; Bucket *p; @@ -2889,7 +2907,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *h } } -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos) +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos) { uint32_t idx; Bucket *p; @@ -3193,7 +3211,7 @@ static zend_always_inline int zend_hash_compare_impl(const HashTable *ht1, const return 0; } -ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, bool ordered) +ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_func_t compar, bool ordered) { int result; IS_CONSISTENT(ht1); diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index b2aaecce0d27..6a695aeef449 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -26,9 +25,11 @@ #include "zend_string.h" #include "zend_sort.h" -#define HASH_KEY_IS_STRING 1 -#define HASH_KEY_IS_LONG 2 -#define HASH_KEY_NON_EXISTENT 3 +typedef enum { + HASH_KEY_IS_STRING = 1, + HASH_KEY_IS_LONG, + HASH_KEY_NON_EXISTENT +} zend_hash_key_type; #define HASH_UPDATE (1<<0) /* Create new entry, or update the existing one. */ #define HASH_ADD (1<<1) /* Create new entry, or fail if it exists. */ @@ -216,6 +217,7 @@ static zend_always_inline zval *zend_hash_find_ex(const HashTable *ht, zend_stri /* Find or add NULL, if doesn't exist */ ZEND_API zval* ZEND_FASTCALL zend_hash_lookup(HashTable *ht, zend_string *key); ZEND_API zval* ZEND_FASTCALL zend_hash_index_lookup(HashTable *ht, zend_ulong h); +ZEND_API zval* ZEND_FASTCALL zend_hash_str_lookup(HashTable *ht, const char *str, size_t len); #define ZEND_HASH_INDEX_LOOKUP(_ht, _h, _ret) do { \ if (EXPECTED(HT_IS_PACKED(_ht))) { \ @@ -251,9 +253,9 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos(const HashTable *h ZEND_API zend_result ZEND_FASTCALL zend_hash_move_forward_ex(const HashTable *ht, HashPosition *pos); ZEND_API zend_result ZEND_FASTCALL zend_hash_move_backwards_ex(const HashTable *ht, HashPosition *pos); -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos); +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos); ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, const HashPosition *pos); -ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos); +ZEND_API zend_hash_key_type ZEND_FASTCALL zend_hash_get_current_key_type_ex(const HashTable *ht, const HashPosition *pos); ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(const HashTable *ht, const HashPosition *pos); ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(const HashTable *ht, HashPosition *pos); ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(const HashTable *ht, HashPosition *pos); @@ -270,13 +272,13 @@ static zend_always_inline zend_result zend_hash_move_forward(HashTable *ht) { static zend_always_inline zend_result zend_hash_move_backwards(HashTable *ht) { return zend_hash_move_backwards_ex(ht, &ht->nInternalPointer); } -static zend_always_inline int zend_hash_get_current_key(const HashTable *ht, zend_string **str_index, zend_ulong *num_index) { +static zend_always_inline zend_hash_key_type zend_hash_get_current_key(const HashTable *ht, zend_string **str_index, zend_ulong *num_index) { return zend_hash_get_current_key_ex(ht, str_index, num_index, &ht->nInternalPointer); } static zend_always_inline void zend_hash_get_current_key_zval(const HashTable *ht, zval *key) { zend_hash_get_current_key_zval_ex(ht, key, &ht->nInternalPointer); } -static zend_always_inline int zend_hash_get_current_key_type(const HashTable *ht) { +static zend_always_inline zend_hash_key_type zend_hash_get_current_key_type(const HashTable *ht) { return zend_hash_get_current_key_type_ex(ht, &ht->nInternalPointer); } static zend_always_inline zval* zend_hash_get_current_data(const HashTable *ht) { @@ -298,7 +300,7 @@ ZEND_API void zend_hash_bucket_renum_swap(Bucket *p, Bucket *q); ZEND_API void zend_hash_bucket_packed_swap(Bucket *p, Bucket *q); typedef int (*bucket_compare_func_t)(Bucket *a, Bucket *b); -ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, bool ordered); +ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_func_t compar, bool ordered); ZEND_API void ZEND_FASTCALL zend_hash_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber); ZEND_API void ZEND_FASTCALL zend_array_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber); ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag); @@ -471,6 +473,17 @@ static zend_always_inline bool zend_hash_str_exists_ind(const HashTable *ht, con Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF); } +static zend_always_inline zval *zend_symtable_add(HashTable *ht, zend_string *key, zval *pData) +{ + zend_ulong idx; + + if (ZEND_HANDLE_NUMERIC(key, idx)) { + return zend_hash_index_add(ht, idx, pData); + } else { + return zend_hash_add(ht, key, pData); + } +} + static zend_always_inline zval *zend_symtable_add_new(HashTable *ht, zend_string *key, zval *pData) { zend_ulong idx; @@ -1619,14 +1632,15 @@ static zend_always_inline bool zend_array_is_list(const zend_array *array) } -static zend_always_inline zval *_zend_hash_append_ex(HashTable *ht, zend_string *key, zval *zv, bool interned) +static zend_always_inline zval *_zend_hash_append_ex(HashTable *ht, zend_string *key, zval *zv, bool key_guaranteed_interned) { uint32_t idx = ht->nNumUsed++; uint32_t nIndex; Bucket *p = ht->arData + idx; ZVAL_COPY_VALUE(&p->val, zv); - if (!interned && !ZSTR_IS_INTERNED(key)) { + ZEND_ASSERT(!key_guaranteed_interned || ZSTR_IS_INTERNED(key)); + if (!key_guaranteed_interned && !ZSTR_IS_INTERNED(key)) { HT_FLAGS(ht) &= ~HASH_FLAG_STATIC_KEYS; zend_string_addref(key); zend_string_hash_val(key); @@ -1645,14 +1659,15 @@ static zend_always_inline zval *_zend_hash_append(HashTable *ht, zend_string *ke return _zend_hash_append_ex(ht, key, zv, 0); } -static zend_always_inline zval *_zend_hash_append_ptr_ex(HashTable *ht, zend_string *key, void *ptr, bool interned) +static zend_always_inline zval *_zend_hash_append_ptr_ex(HashTable *ht, zend_string *key, void *ptr, bool key_guaranteed_interned) { uint32_t idx = ht->nNumUsed++; uint32_t nIndex; Bucket *p = ht->arData + idx; ZVAL_PTR(&p->val, ptr); - if (!interned && !ZSTR_IS_INTERNED(key)) { + ZEND_ASSERT(!key_guaranteed_interned || ZSTR_IS_INTERNED(key)); + if (!key_guaranteed_interned && !ZSTR_IS_INTERNED(key)) { HT_FLAGS(ht) &= ~HASH_FLAG_STATIC_KEYS; zend_string_addref(key); zend_string_hash_val(key); diff --git a/Zend/zend_highlight.c b/Zend/zend_highlight.c index 5c3cd136d580..a3c65932ca4d 100644 --- a/Zend/zend_highlight.c +++ b/Zend/zend_highlight.c @@ -2,15 +2,14 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + | Copyright © Zend Technologies Ltd., a subsidiary company of | + | Perforce Software, Inc., and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -79,8 +78,8 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini { zval token; int token_type; - char *last_color = syntax_highlighter_ini->highlight_html; - char *next_color; + const char *last_color = syntax_highlighter_ini->highlight_html; + const char *next_color; zend_printf("
", last_color);
 	/* highlight stuff coming back from zendlex() */
diff --git a/Zend/zend_highlight.h b/Zend/zend_highlight.h
index 04688d65132b..2e399f408063 100644
--- a/Zend/zend_highlight.h
+++ b/Zend/zend_highlight.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -30,11 +29,11 @@
 
 
 typedef struct _zend_syntax_highlighter_ini {
-	char *highlight_html;
-	char *highlight_comment;
-	char *highlight_default;
-	char *highlight_string;
-	char *highlight_keyword;
+	const char *highlight_html;
+	const char *highlight_comment;
+	const char *highlight_default;
+	const char *highlight_string;
+	const char *highlight_keyword;
 } zend_syntax_highlighter_ini;
 
 
diff --git a/Zend/zend_hrtime.c b/Zend/zend_hrtime.c
index 7fa36b1b654f..819f95c47662 100644
--- a/Zend/zend_hrtime.c
+++ b/Zend/zend_hrtime.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Niklas Keller                               |
    | Author: Anatol Belski                                    |
@@ -27,6 +25,8 @@
 # include 
 # include 
 
+ZEND_API clockid_t zend_hrtime_posix_clock_id = CLOCK_MONOTONIC;
+
 #elif ZEND_HRTIME_PLATFORM_WINDOWS
 
 # define WIN32_LEAN_AND_MEAN
@@ -66,5 +66,24 @@ void zend_startup_hrtime(void)
 
 	mach_timebase_info(&zend_hrtime_timerlib_info);
 
+#elif ZEND_HRTIME_PLATFORM_POSIX
+
+	struct timespec ts;
+
+#ifdef CLOCK_MONOTONIC_RAW
+	if (EXPECTED(0 == clock_gettime(CLOCK_MONOTONIC_RAW, &ts))) {
+		zend_hrtime_posix_clock_id = CLOCK_MONOTONIC_RAW;
+		return;
+	}
+#endif
+
+	if (EXPECTED(0 == clock_gettime(zend_hrtime_posix_clock_id, &ts))) {
+		return;
+	}
+
+	// zend_error mechanism is not initialized at that point
+	fprintf(stderr, "No working CLOCK_MONOTONIC* found, this should never happen\n");
+	abort();
+
 #endif
 }
diff --git a/Zend/zend_hrtime.h b/Zend/zend_hrtime.h
index 994dd6da169e..464c7e571d5b 100644
--- a/Zend/zend_hrtime.h
+++ b/Zend/zend_hrtime.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Niklas Keller                               |
    | Author: Anatol Belski                                    |
@@ -72,6 +70,10 @@ ZEND_API extern double zend_hrtime_timer_scale;
 # include 
 ZEND_API extern mach_timebase_info_data_t zend_hrtime_timerlib_info;
 
+#elif ZEND_HRTIME_PLATFORM_POSIX
+
+ZEND_API extern clockid_t zend_hrtime_posix_clock_id;
+
 #endif
 
 #define ZEND_NANO_IN_SEC UINT64_C(1000000000)
@@ -92,10 +94,8 @@ static zend_always_inline zend_hrtime_t zend_hrtime(void)
 	return (zend_hrtime_t)mach_absolute_time() * zend_hrtime_timerlib_info.numer / zend_hrtime_timerlib_info.denom;
 #elif ZEND_HRTIME_PLATFORM_POSIX
 	struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
-	if (EXPECTED(0 == clock_gettime(CLOCK_MONOTONIC, &ts))) {
-		return ((zend_hrtime_t) ts.tv_sec * (zend_hrtime_t)ZEND_NANO_IN_SEC) + ts.tv_nsec;
-	}
-	return 0;
+	clock_gettime(zend_hrtime_posix_clock_id, &ts);
+	return ((zend_hrtime_t) ts.tv_sec * (zend_hrtime_t)ZEND_NANO_IN_SEC) + ts.tv_nsec;
 #elif ZEND_HRTIME_PLATFORM_HPUX
 	return (zend_hrtime_t) gethrtime();
 #elif  ZEND_HRTIME_PLATFORM_AIX
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index d27cca5b7618..00520d2d3774 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -35,6 +34,21 @@
 ZEND_API zend_class_entry* (*zend_inheritance_cache_get)(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces) = NULL;
 ZEND_API zend_class_entry* (*zend_inheritance_cache_add)(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies) = NULL;
 
+static void zend_check_generic_link_arity(
+		const zend_class_entry *target_ce, uint32_t arity,
+		const char *clause, zend_string *child_name);
+static void zend_check_generic_link_bounds(
+		zend_class_entry *target_ce, const zend_type *args_box,
+		const char *clause, zend_class_entry *ce);
+static void zend_substitute_trait_method_arg_info(
+		zend_function *new_fn, const zend_function *orig_fn,
+		const zend_class_entry *using_ce,
+		const zend_type *bind_args, uint32_t bind_arity);
+static zend_arg_info *zend_clone_arg_info_block(
+		const zend_arg_info *orig_block, uint32_t total);
+static bool zend_diamond_types_equal(zend_type a, zend_type b);
+static const zend_type_named_with_args *zend_get_implements_binding(const zend_class_entry *ce, uint32_t idx);
+
 /* Unresolved means that class declarations that are currently not available are needed to
  * determine whether the inheritance is valid or not. At runtime UNRESOLVED should be treated
  * as an ERROR. */
@@ -60,11 +74,11 @@ static void add_property_hook_obligation(
 		zend_class_entry *ce, const zend_property_info *hooked_prop, const zend_function *hook_func);
 
 static void ZEND_COLD emit_incompatible_method_error(
-		const zend_function *child, zend_class_entry *child_scope,
-		const zend_function *parent, zend_class_entry *parent_scope,
+		const zend_function *child, const zend_class_entry *child_scope,
+		const zend_function *parent, const zend_class_entry *parent_scope,
 		inheritance_status status);
 
-static void zend_type_copy_ctor(zend_type *const type, bool use_arena, bool persistent);
+ZEND_API void zend_type_copy_ctor(zend_type *const type, bool use_arena, bool persistent);
 
 static void zend_type_list_copy_ctor(
 	zend_type *const parent_type,
@@ -88,9 +102,48 @@ static void zend_type_list_copy_ctor(
 	} ZEND_TYPE_LIST_FOREACH_END();
 }
 
-static void zend_type_copy_ctor(zend_type *const type, bool use_arena, bool persistent) {
+static void zend_type_named_with_args_copy_ctor(
+	zend_type *const parent_type, bool use_arena, bool persistent)
+{
+	const zend_type_named_with_args *src = ZEND_TYPE_NAMED_WITH_ARGS(*parent_type);
+	size_t size = ZEND_TYPE_NAMED_WITH_ARGS_SIZE(src->count);
+	zend_type_named_with_args *dst = use_arena
+		? zend_arena_alloc(&CG(arena), size) : pemalloc(size, persistent);
+	memcpy(dst, src, size);
+	if (dst->name) {
+		zend_string_addref(dst->name);
+	}
+	ZEND_TYPE_SET_PTR(*parent_type, dst);
+	for (uint32_t i = 0; i < dst->count; i++) {
+		zend_type_copy_ctor(&dst->args[i], use_arena, persistent);
+	}
+}
+
+static void zend_type_parameter_ref_copy_ctor(
+	zend_type *const parent_type, bool persistent)
+{
+	const zend_type_parameter_ref *src = ZEND_TYPE_TYPE_PARAMETER(*parent_type);
+	zend_type_parameter_ref *dst = pemalloc(sizeof(*dst), persistent);
+	*dst = *src;
+	if (dst->name) {
+		zend_string_addref(dst->name);
+	}
+	ZEND_TYPE_SET_PTR(*parent_type, dst);
+}
+
+ZEND_API void zend_type_copy_ctor(zend_type *const type, bool use_arena, bool persistent) {
 	if (ZEND_TYPE_HAS_LIST(*type)) {
 		zend_type_list_copy_ctor(type, use_arena, persistent);
+	} else if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*type)) {
+		/* Deep-clone the NWA payload + recurse into args. Without this,
+		 * a copied type shares the source's heap-allocated NWA and either
+		 * dangles (when the source frees it) or double-frees (when both
+		 * release paths run). */
+		zend_type_named_with_args_copy_ctor(type, use_arena, persistent);
+	} else if (ZEND_TYPE_HAS_TYPE_PARAMETER(*type)) {
+		/* Same story for type-parameter refs: each clone needs its own
+		 * heap-allocated ref so release paths don't collide. */
+		zend_type_parameter_ref_copy_ctor(type, persistent);
 	} else if (ZEND_TYPE_HAS_NAME(*type)) {
 		zend_string_addref(ZEND_TYPE_NAME(*type));
 	}
@@ -100,7 +153,7 @@ static zend_function *zend_duplicate_internal_function(const zend_function *func
 {
 	zend_function *new_function;
 
-	if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
+	if (UNEXPECTED(ce->type == ZEND_INTERNAL_CLASS)) {
 		new_function = (zend_function *)pemalloc(sizeof(zend_internal_function), 1);
 		memcpy(new_function, func, sizeof(zend_internal_function));
 	} else {
@@ -189,9 +242,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
 
 	if (ce->constructor) {
 		if (parent->constructor && UNEXPECTED(parent->constructor->common.fn_flags & ZEND_ACC_FINAL)) {
-			zend_error_noreturn(E_ERROR, "Cannot override final %s::%s() with %s::%s()",
-				ZSTR_VAL(parent->name), ZSTR_VAL(parent->constructor->common.function_name),
-				ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name));
+			zend_error_noreturn(E_ERROR, "Cannot override final %s::__construct() with %s::__construct()",
+				ZSTR_VAL(parent->name),
+				ZSTR_VAL(ce->name));
 		}
 		return;
 	}
@@ -200,7 +253,7 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
 }
 /* }}} */
 
-char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
+const char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
 {
 	if (fn_flags & ZEND_ACC_PUBLIC) {
 		return "public";
@@ -297,7 +350,7 @@ static zend_class_entry *lookup_class_ex(
 		}
 
 		/* The current class may not be registered yet, so check for it explicitly. */
-		if (zend_string_equals_ci(scope->name, name)) {
+		if (scope && zend_string_equals_ci(scope->name, name)) {
 			return scope;
 		}
 	}
@@ -312,7 +365,7 @@ static zend_class_entry *lookup_class(zend_class_entry *scope, zend_string *name
 /* Instanceof that's safe to use on unlinked classes. */
 static bool unlinked_instanceof(const zend_class_entry *ce1, const zend_class_entry *ce2) {
 	if (ce1 == ce2) {
-		return 1;
+		return true;
 	}
 
 	if (ce1->ce_flags & ZEND_ACC_LINKED) {
@@ -320,7 +373,7 @@ static bool unlinked_instanceof(const zend_class_entry *ce1, const zend_class_en
 	}
 
 	if (ce1->parent) {
-		zend_class_entry *parent_ce;
+		const zend_class_entry *parent_ce;
 		if (ce1->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
 			parent_ce = ce1->parent;
 		} else {
@@ -331,7 +384,7 @@ static bool unlinked_instanceof(const zend_class_entry *ce1, const zend_class_en
 		/* It's not sufficient to only check the parent chain itself, as need to do a full
 		 * recursive instanceof in case the parent interfaces haven't been copied yet. */
 		if (parent_ce && unlinked_instanceof(parent_ce, ce2)) {
-			return 1;
+			return true;
 		}
 	}
 
@@ -342,7 +395,7 @@ static bool unlinked_instanceof(const zend_class_entry *ce1, const zend_class_en
 			 * check here, as the parent interfaces might not have been fully copied yet. */
 			for (i = 0; i < ce1->num_interfaces; i++) {
 				if (unlinked_instanceof(ce1->interfaces[i], ce2)) {
-					return 1;
+					return true;
 				}
 			}
 		} else {
@@ -352,19 +405,19 @@ static bool unlinked_instanceof(const zend_class_entry *ce1, const zend_class_en
 					ZEND_FETCH_CLASS_ALLOW_UNLINKED | ZEND_FETCH_CLASS_NO_AUTOLOAD);
 				/* Avoid recursing if class implements itself. */
 				if (ce && ce != ce1 && unlinked_instanceof(ce, ce2)) {
-					return 1;
+					return true;
 				}
 			}
 		}
 	}
 
-	return 0;
+	return false;
 }
 
 static bool zend_type_permits_self(
 		const zend_type type, const zend_class_entry *scope, zend_class_entry *self) {
 	if (ZEND_TYPE_FULL_MASK(type) & MAY_BE_OBJECT) {
-		return 1;
+		return true;
 	}
 
 	/* Any types that may satisfy self must have already been loaded at this point
@@ -373,14 +426,16 @@ static bool zend_type_permits_self(
 	const zend_type *single_type;
 	ZEND_TYPE_FOREACH(type, single_type) {
 		if (ZEND_TYPE_HAS_NAME(*single_type)) {
-			zend_string *name = resolve_class_name(scope, ZEND_TYPE_NAME(*single_type));
+			zend_string *name = scope
+				? resolve_class_name(scope, ZEND_TYPE_NAME(*single_type))
+				: ZEND_TYPE_NAME(*single_type);
 			const zend_class_entry *ce = lookup_class(self, name);
 			if (ce && unlinked_instanceof(self, ce)) {
-				return 1;
+				return true;
 			}
 		}
 	} ZEND_TYPE_FOREACH_END();
-	return 0;
+	return false;
 }
 
 static void track_class_dependency(zend_class_entry *ce, zend_string *class_name)
@@ -441,8 +496,9 @@ static inheritance_status zend_is_intersection_subtype_of_class(
 		zend_class_entry *fe_ce;
 		zend_string *fe_class_name = NULL;
 		if (ZEND_TYPE_HAS_NAME(*single_type)) {
-			fe_class_name =
-				resolve_class_name(fe_scope, ZEND_TYPE_NAME(*single_type));
+			fe_class_name = fe_scope
+				? resolve_class_name(fe_scope, ZEND_TYPE_NAME(*single_type))
+				: ZEND_TYPE_NAME(*single_type);
 			if (zend_string_equals_ci(fe_class_name, proto_class_name)) {
 				return INHERITANCE_SUCCESS;
 			}
@@ -475,7 +531,7 @@ static inheritance_status zend_is_class_subtype_of_type(
 		zend_class_entry *fe_scope, zend_string *fe_class_name,
 		zend_class_entry *proto_scope, const zend_type proto_type) {
 	zend_class_entry *fe_ce = NULL;
-	bool have_unresolved = 0;
+	bool have_unresolved = false;
 
 	/* If the parent has 'object' as a return type, any class satisfies the co-variant check */
 	if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_OBJECT) {
@@ -484,7 +540,7 @@ static inheritance_status zend_is_class_subtype_of_type(
 		 * are not classes (such as typedefs). */
 		if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
 		if (!fe_ce) {
-			have_unresolved = 1;
+			have_unresolved = true;
 		} else {
 			track_class_dependency(fe_ce, fe_class_name);
 			return INHERITANCE_SUCCESS;
@@ -495,7 +551,7 @@ static inheritance_status zend_is_class_subtype_of_type(
 	if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_CALLABLE) {
 		if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
 		if (!fe_ce) {
-			have_unresolved = 1;
+			have_unresolved = true;
 		} else if (fe_ce == zend_ce_closure) {
 			track_class_dependency(fe_ce, fe_class_name);
 			return INHERITANCE_SUCCESS;
@@ -506,7 +562,7 @@ static inheritance_status zend_is_class_subtype_of_type(
 	if ((ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_STATIC) && (fe_scope->ce_flags & ZEND_ACC_FINAL)) {
 		if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
 		if (!fe_ce) {
-			have_unresolved = 1;
+			have_unresolved = true;
 		} else if (fe_ce == fe_scope) {
 			track_class_dependency(fe_ce, fe_class_name);
 			return INHERITANCE_SUCCESS;
@@ -530,22 +586,23 @@ static inheritance_status zend_is_class_subtype_of_type(
 					}
 					continue;
 				case INHERITANCE_UNRESOLVED:
-					have_unresolved = 1;
+					have_unresolved = true;
 					continue;
 				case INHERITANCE_SUCCESS:
 					if (!is_intersection) {
 						return INHERITANCE_SUCCESS;
 					}
 					continue;
-				EMPTY_SWITCH_DEFAULT_CASE();
+				default: ZEND_UNREACHABLE();
 			}
 		}
 
 		zend_class_entry *proto_ce;
 		zend_string *proto_class_name = NULL;
 		if (ZEND_TYPE_HAS_NAME(*single_type)) {
-			proto_class_name =
-				resolve_class_name(proto_scope, ZEND_TYPE_NAME(*single_type));
+			proto_class_name = proto_scope
+				? resolve_class_name(proto_scope, ZEND_TYPE_NAME(*single_type))
+				: ZEND_TYPE_NAME(*single_type);
 			if (zend_string_equals_ci(fe_class_name, proto_class_name)) {
 				if (!is_intersection) {
 					return INHERITANCE_SUCCESS;
@@ -562,7 +619,7 @@ static inheritance_status zend_is_class_subtype_of_type(
 		}
 
 		if (!fe_ce || !proto_ce) {
-			have_unresolved = 1;
+			have_unresolved = true;
 			continue;
 		}
 		if (unlinked_instanceof(fe_ce, proto_ce)) {
@@ -586,7 +643,9 @@ static inheritance_status zend_is_class_subtype_of_type(
 
 static zend_string *get_class_from_type(const zend_class_entry *scope, const zend_type single_type) {
 	if (ZEND_TYPE_HAS_NAME(single_type)) {
-		return resolve_class_name(scope, ZEND_TYPE_NAME(single_type));
+		return scope
+			? resolve_class_name(scope, ZEND_TYPE_NAME(single_type))
+			: ZEND_TYPE_NAME(single_type);
 	}
 	return NULL;
 }
@@ -671,11 +730,12 @@ static inheritance_status zend_is_intersection_subtype_of_type(
 	return early_exit_status == INHERITANCE_ERROR ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
 }
 
-ZEND_API inheritance_status zend_perform_covariant_type_check(
+static inheritance_status zend_perform_covariant_type_check(
 		zend_class_entry *fe_scope, const zend_type fe_type,
 		zend_class_entry *proto_scope, const zend_type proto_type)
 {
 	ZEND_ASSERT(ZEND_TYPE_IS_SET(fe_type) && ZEND_TYPE_IS_SET(proto_type));
+	ZEND_ASSERT((fe_scope == NULL) == (proto_scope == NULL));
 
 	/* Apart from void, everything is trivially covariant to the mixed type.
 	 * Handle this case separately to ensure it never requires class loading. */
@@ -757,21 +817,643 @@ ZEND_API inheritance_status zend_perform_covariant_type_check(
 		return early_exit_status == INHERITANCE_ERROR ? INHERITANCE_SUCCESS : INHERITANCE_ERROR;
 	}
 
-	register_unresolved_classes(fe_scope, fe_type);
-	register_unresolved_classes(proto_scope, proto_type);
+	if (fe_scope) {
+		register_unresolved_classes(fe_scope, fe_type);
+		register_unresolved_classes(proto_scope, proto_type);
+	}
+
 	return INHERITANCE_UNRESOLVED;
 }
 
+/* Direct binding only: the args ce supplies at its own extends/implements
+ * site. For transitive lookups, use zend_get_inheritance_binding_full. */
+static bool zend_get_inheritance_binding(
+		const zend_class_entry *ce,
+		const zend_class_entry *target_ce,
+		const zend_type **out_args,
+		uint32_t *out_arity)
+{
+	if (!ce->generic_types) {
+		return false;
+	}
+
+	if (ce->generic_types->extends && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)) {
+		const zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*ce->generic_types->extends);
+		bool matches = (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT)
+			? ce->parent == target_ce
+			: (named->name && target_ce->name && zend_string_equals_ci(named->name, target_ce->name));
+
+		if (matches) {
+			*out_args = named->args;
+			*out_arity = named->count;
+			return true;
+		}
+	}
+
+	if (ce->generic_types->implements) {
+		zval *zv;
+		ZEND_HASH_FOREACH_VAL(ce->generic_types->implements, zv) {
+			zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+			if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) continue;
+			zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*boxed);
+			if (zend_string_equals_ci(named->name, target_ce->name)) {
+				*out_args = named->args;
+				*out_arity = named->count;
+				return true;
+			}
+		} ZEND_HASH_FOREACH_END();
+	}
+
+	if (ce->generic_types->trait_uses) {
+		zval *zv;
+		ZEND_HASH_FOREACH_VAL(ce->generic_types->trait_uses, zv) {
+			zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+			if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) continue;
+			zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*boxed);
+			if (named->name && zend_string_equals_ci(named->name, target_ce->name)) {
+				*out_args = named->args;
+				*out_arity = named->count;
+				return true;
+			}
+		} ZEND_HASH_FOREACH_END();
+	}
+
+	return false;
+}
+
+/* Substitutes class-scope T-refs with their bound arguments.
+ *
+ * Handles three shapes:
+ *   - a bare T-ref ("T" or "?T") — return the substituted leaf;
+ *   - a union/intersection list — walk the list and substitute any class-scope
+ *     T-refs found inside, folding scalar bindings into the outer scalar mask
+ *     and keeping named/intersection bindings in the list;
+ *   - anything else — return unchanged.
+ *
+ * This is what makes property types like `T|null` reify correctly. Without the
+ * recursive walk, a T living inside a union stays literal at runtime and the
+ * property type check rejects valid assignments with "of type T".
+ *
+ * `origin` selects which type-parameter refs to substitute: CLASS_LIKE for the
+ * class monomorphizer, FUNCTION_LIKE for the function monomorphizer. */
+static zend_type zend_substitute_leaf_type_param_origin(zend_type t, const zend_type *args, uint32_t arity, uint8_t origin)
+{
+	if (ZEND_TYPE_HAS_TYPE_PARAMETER(t)) {
+		const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(t);
+		if (ref->origin != origin || ref->index >= arity) {
+			return t;
+		}
+
+		zend_type result = args[ref->index];
+		if (ZEND_TYPE_FULL_MASK(t) & _ZEND_TYPE_NULLABLE_BIT) {
+			ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NULLABLE_BIT;
+		}
+
+		return result;
+	}
+
+	/* Named-with-args (e.g. `I`): recurse into args. If every arg ends up
+	 * ground, materialize the monomorph and return a plain CLASS type — that's
+	 * the shape the runtime property/arg type checks already understand. If
+	 * any T-ref remains, return a new NWA with the partially-substituted args. */
+	if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(t)) {
+		const zend_type_named_with_args *src_nwa = ZEND_TYPE_NAMED_WITH_ARGS(t);
+		bool needs_rebuild = false;
+		for (uint32_t i = 0; i < src_nwa->count; i++) {
+			zend_type probe = zend_substitute_leaf_type_param_origin(src_nwa->args[i], args, arity, origin);
+			if (memcmp(&probe, &src_nwa->args[i], sizeof(zend_type)) != 0) {
+				needs_rebuild = true;
+				break;
+			}
+		}
+		if (!needs_rebuild) {
+			return t;
+		}
+
+		ALLOCA_FLAG(use_heap)
+		zend_type *new_args = (zend_type *) do_alloca(sizeof(zend_type) * src_nwa->count, use_heap);
+		bool all_concrete = true;
+		for (uint32_t i = 0; i < src_nwa->count; i++) {
+			new_args[i] = zend_substitute_leaf_type_param_origin(src_nwa->args[i], args, arity, origin);
+			if (zend_type_contains_type_parameter(new_args[i])) {
+				all_concrete = false;
+			}
+		}
+
+		zend_type result;
+		if (all_concrete) {
+			/* All bound — fold to a plain CLASS reference to the monomorph.
+			 * The class-lookup hook synthesizes it on demand if needed. */
+			zend_string *canonical = zend_generic_canonical_class_name(
+				src_nwa->name, new_args, src_nwa->count);
+			result = (zend_type) ZEND_TYPE_INIT_CLASS(canonical, 0, 0);
+		} else {
+			/* Partial substitution — keep as NWA with substituted args. */
+			size_t size = ZEND_TYPE_NAMED_WITH_ARGS_SIZE(src_nwa->count);
+			zend_type_named_with_args *new_nwa = zend_arena_alloc(&CG(arena), size);
+			new_nwa->name = zend_string_copy(src_nwa->name);
+			new_nwa->name_attr = src_nwa->name_attr;
+			new_nwa->count = src_nwa->count;
+			for (uint32_t i = 0; i < src_nwa->count; i++) {
+				new_nwa->args[i] = new_args[i];
+				zend_type_copy_ctor(&new_nwa->args[i], /* use_arena */ true, /* persistent */ false);
+			}
+			ZEND_TYPE_SET_PTR(result, new_nwa);
+			ZEND_TYPE_FULL_MASK(result) = ZEND_TYPE_FULL_MASK(t);
+		}
+
+		if (ZEND_TYPE_FULL_MASK(t) & _ZEND_TYPE_NULLABLE_BIT) {
+			ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NULLABLE_BIT;
+		}
+		free_alloca(new_args, use_heap);
+		return result;
+	}
+
+	if (!ZEND_TYPE_HAS_LIST(t)) {
+		return t;
+	}
+
+	const zend_type_list *src_list = ZEND_TYPE_LIST(t);
+	bool needs_rebuild = false;
+	for (uint32_t i = 0; i < src_list->num_types; i++) {
+		const zend_type *elem = &src_list->types[i];
+		if (ZEND_TYPE_HAS_TYPE_PARAMETER(*elem)) {
+			const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*elem);
+			if (ref->origin == origin && ref->index < arity) {
+				needs_rebuild = true;
+				break;
+			}
+		} else if (ZEND_TYPE_HAS_LIST(*elem) || ZEND_TYPE_HAS_NAMED_WITH_ARGS(*elem)) {
+			/* Nested list (DNF) or named-with-args (`I`) — recurse to
+			 * see if there's a T-ref buried in there. */
+			zend_type probe = zend_substitute_leaf_type_param_origin(*elem, args, arity, origin);
+			if (memcmp(&probe, elem, sizeof(zend_type)) != 0) {
+				needs_rebuild = true;
+				break;
+			}
+		}
+	}
+	if (!needs_rebuild) {
+		return t;
+	}
+
+	bool is_intersection = (ZEND_TYPE_FULL_MASK(t) & _ZEND_TYPE_INTERSECTION_BIT) != 0;
+	uint32_t carried_flags = ZEND_TYPE_FULL_MASK(t) & ~_ZEND_TYPE_KIND_MASK
+		& ~_ZEND_TYPE_LIST_BIT & ~_ZEND_TYPE_ARENA_BIT
+		& ~_ZEND_TYPE_UNION_BIT & ~_ZEND_TYPE_INTERSECTION_BIT;
+	uint32_t merged_mask = carried_flags;
+
+	ALLOCA_FLAG(use_heap)
+	zend_type *out = (zend_type *) do_alloca(sizeof(zend_type) * src_list->num_types, use_heap);
+	uint32_t out_count = 0;
+
+	for (uint32_t i = 0; i < src_list->num_types; i++) {
+		zend_type substituted = zend_substitute_leaf_type_param_origin(src_list->types[i], args, arity, origin);
+
+		/* Keep complex elements (named types, intersection sublists, unresolved
+		 * T-refs) in the list; their scalar contribution is also OR'd into the
+		 * outer mask in case the substituted type carries a NULLABLE bit. */
+		bool keeps_complex = ZEND_TYPE_HAS_LIST(substituted)
+			|| ZEND_TYPE_HAS_NAME(substituted)
+			|| ZEND_TYPE_HAS_LITERAL_NAME(substituted)
+			|| ZEND_TYPE_HAS_TYPE_PARAMETER(substituted)
+			|| ZEND_TYPE_HAS_NAMED_WITH_ARGS(substituted);
+
+		if (keeps_complex) {
+			out[out_count++] = substituted;
+		}
+		merged_mask |= ZEND_TYPE_PURE_MASK(substituted);
+	}
+
+	zend_type result;
+	if (out_count == 0) {
+		result = (zend_type) ZEND_TYPE_INIT_NONE(0);
+		ZEND_TYPE_FULL_MASK(result) |= merged_mask;
+	} else if (out_count == 1 && !is_intersection
+			&& (merged_mask & _ZEND_TYPE_MAY_BE_MASK & ~_ZEND_TYPE_NULLABLE_BIT) == 0) {
+		/* Degenerate union "Foo" or "?Foo" — represent as a single name with
+		 * the nullable bit, matching how the parser builds the same shape. */
+		result = out[0];
+		zend_type_copy_ctor(&result, /* use_arena */ true, /* persistent */ false);
+		if (merged_mask & _ZEND_TYPE_NULLABLE_BIT) {
+			ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NULLABLE_BIT;
+		}
+	} else {
+		zend_type_list *new_list = zend_arena_alloc(&CG(arena), ZEND_TYPE_LIST_SIZE(out_count));
+		new_list->num_types = out_count;
+		for (uint32_t i = 0; i < out_count; i++) {
+			new_list->types[i] = out[i];
+			zend_type_copy_ctor(&new_list->types[i], /* use_arena */ true, /* persistent */ false);
+		}
+		result = (zend_type) ZEND_TYPE_INIT_NONE(0);
+		ZEND_TYPE_SET_PTR(result, new_list);
+		uint32_t kind_bit = is_intersection ? _ZEND_TYPE_INTERSECTION_BIT : _ZEND_TYPE_UNION_BIT;
+		ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_LIST_BIT | _ZEND_TYPE_ARENA_BIT | kind_bit | merged_mask;
+	}
+
+	free_alloca(out, use_heap);
+	return result;
+}
+
+static zend_type zend_substitute_leaf_type_param(zend_type t, const zend_type *args, uint32_t arity)
+{
+	return zend_substitute_leaf_type_param_origin(t, args, arity, ZEND_GENERIC_ORIGIN_CLASS_LIKE);
+}
+
+ZEND_API zend_type zend_substitute_function_type_param(zend_type t, const zend_type *args, uint32_t arity)
+{
+	return zend_substitute_leaf_type_param_origin(t, args, arity, ZEND_GENERIC_ORIGIN_FUNCTION_LIKE);
+}
+
+static bool zend_get_trait_use_binding(
+		const zend_class_entry *ce, uint32_t trait_index,
+		const zend_type **out_args, uint32_t *out_arity)
+{
+	if (!ce->generic_types || !ce->generic_types->trait_uses) return false;
+	zval *zv = zend_hash_index_find(ce->generic_types->trait_uses, trait_index);
+	if (!zv) return false;
+	zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+	if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) return false;
+	const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*boxed);
+	*out_args = nwa->args;
+	*out_arity = nwa->count;
+	return true;
+}
+
+static const zend_type *zend_get_trait_property_pre_erasure(
+		const zend_class_entry *trait_ce, zend_string *prop_name)
+{
+	if (!trait_ce->generic_types || !trait_ce->generic_types->properties) return NULL;
+	zval *zv = zend_hash_find(trait_ce->generic_types->properties, prop_name);
+	if (!zv) return NULL;
+	return (const zend_type *) Z_PTR_P(zv);
+}
+
+static zend_class_entry *zend_find_interface_by_name(
+		const zend_class_entry *ce, const zend_string *name)
+{
+	/* ce->interfaces[] is only meaningful once resolution has populated it. */
+	if (!(ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES)) {
+		return NULL;
+	}
+	for (uint32_t i = 0; i < ce->num_interfaces; i++) {
+		if (ce->interfaces[i] && zend_string_equals_ci(ce->interfaces[i]->name, name)) {
+			return ce->interfaces[i];
+		}
+	}
+	return NULL;
+}
+
+/* Walks the inheritance chain and composes substitutions when ce's binding
+ * for `target` is transitive. */
+ZEND_API bool zend_get_inheritance_binding_full(
+		const zend_class_entry *ce,
+		const zend_class_entry *target,
+		zend_type *out_args,
+		uint32_t out_capacity,
+		uint32_t *out_arity)
+{
+	const zend_type *direct_args;
+	if (zend_get_inheritance_binding(ce, target, &direct_args, out_arity)) {
+		if (*out_arity > out_capacity) return false;
+		for (uint32_t i = 0; i < *out_arity; i++) {
+			out_args[i] = direct_args[i];
+		}
+		return true;
+	}
+
+	if (!ce->generic_types) return false;
+
+	uint32_t intermediate_cap = (target && target->generic_parameters) ? target->generic_parameters->count : 0;
+	if (intermediate_cap == 0) return false;
+	ALLOCA_FLAG(use_heap)
+	zend_type *intermediate_args = (zend_type *) do_alloca(sizeof(zend_type) * intermediate_cap, use_heap);
+	bool found = false;
+
+	if (ce->generic_types->extends && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)) {
+		zend_class_entry *parent_ce = (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT)
+			? ce->parent
+			: zend_lookup_class_ex(
+				ZEND_TYPE_NAMED_WITH_ARGS(*ce->generic_types->extends)->name,
+				NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
+		if (parent_ce) {
+			uint32_t intermediate_arity;
+			if (zend_get_inheritance_binding_full(parent_ce, target, intermediate_args, intermediate_cap, &intermediate_arity)) {
+				const zend_type *ce_to_parent;
+				uint32_t ce_to_parent_arity;
+				if (zend_get_inheritance_binding(ce, parent_ce, &ce_to_parent, &ce_to_parent_arity)) {
+					if (intermediate_arity > out_capacity) {
+						goto done;
+					}
+
+					for (uint32_t i = 0; i < intermediate_arity; i++) {
+						out_args[i] = zend_substitute_leaf_type_param(intermediate_args[i], ce_to_parent, ce_to_parent_arity);
+					}
+
+					*out_arity = intermediate_arity;
+					found = true;
+					goto done;
+				}
+			}
+		}
+	}
+
+	if (ce->generic_types->implements) {
+		zval *zv;
+		ZEND_HASH_FOREACH_VAL(ce->generic_types->implements, zv) {
+			zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+			if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) continue;
+			zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*boxed);
+			zend_class_entry *intermediate = zend_find_interface_by_name(ce, named->name);
+			if (!intermediate || intermediate == target) continue;
+
+			uint32_t intermediate_arity;
+			if (!zend_get_inheritance_binding_full(intermediate, target,
+					intermediate_args, intermediate_cap, &intermediate_arity)) {
+				continue;
+			}
+
+			if (intermediate_arity > out_capacity) {
+				goto done;
+			}
+
+			for (uint32_t i = 0; i < intermediate_arity; i++) {
+				out_args[i] = zend_substitute_leaf_type_param(
+					intermediate_args[i], named->args, named->count);
+			}
+			*out_arity = intermediate_arity;
+			found = true;
+			goto done;
+		} ZEND_HASH_FOREACH_END();
+	}
+
+	done:
+		free_alloca(intermediate_args, use_heap);
+		return found;
+}
+
+static bool zend_get_inheritance_binding_full_cached(
+		const zend_class_entry *ce,
+		const zend_class_entry *target,
+		zend_type *out_args,
+		uint32_t out_capacity,
+		uint32_t *out_arity)
+{
+	if (CG(inheritance_binding_hint).target == target && CG(inheritance_binding_hint).args) {
+		uint32_t arity = CG(inheritance_binding_hint).arity;
+		if (arity > out_capacity) {
+			return false;
+		}
+
+		const zend_type *hint_args = CG(inheritance_binding_hint).args;
+		for (uint32_t i = 0; i < arity; i++) {
+			out_args[i] = hint_args[i];
+		}
+
+		*out_arity = arity;
+		return true;
+	}
+
+	zend_inheritance_binding_cache *cache = CG(inheritance_binding_cache);
+	if (cache && cache->present && cache->ce == ce && cache->target == target) {
+		if (!cache->valid) {
+			return false;
+		}
+
+		if (cache->arity > out_capacity) {
+			return false;
+		}
+
+		for (uint32_t i = 0; i < cache->arity; i++) {
+			out_args[i] = cache->args[i];
+		}
+
+		*out_arity = cache->arity;
+		return true;
+	}
+
+	bool result = zend_get_inheritance_binding_full(
+		ce, target, out_args, out_capacity, out_arity);
+
+	if (cache) {
+		cache->ce = ce;
+		cache->target = target;
+		cache->present = true;
+		cache->valid = result;
+		if (result && *out_arity <= ZEND_GENERIC_MAX_PARAMS) {
+			cache->arity = *out_arity;
+			for (uint32_t i = 0; i < *out_arity; i++) {
+				cache->args[i] = out_args[i];
+			}
+		}
+	}
+
+	return result;
+}
+
+/* Fills out_args with target_ce's parameter defaults if every parameter
+ * has one. */
+static bool zend_get_target_default_args(
+		const zend_class_entry *target_ce,
+		zend_type *out_args, uint32_t out_capacity, uint32_t *out_arity)
+{
+	if (!target_ce->generic_parameters) return false;
+	uint32_t total = target_ce->generic_parameters->count;
+	if (total > out_capacity) return false;
+	for (uint32_t i = 0; i < total; i++) {
+		zend_type d = target_ce->generic_parameters->parameters[i].default_type;
+		if (!ZEND_TYPE_IS_SET(d)) return false;
+		out_args[i] = d;
+	}
+	*out_arity = total;
+	return true;
+}
+
+/* Internal: substitute proto's pre-erasure against ce's binding without
+ * applying the top-level type-parameter fallback. May return a type that
+ * still has TYPE_PARAMETER refs at the top — callers use this to detect
+ * the "would fall back" case so the child side can mirror it. Returns
+ * `fallback` (unchanged) when no substitution applies at all. */
+static zend_type zend_substitute_proto_type_raw(
+		zend_type fallback,
+		const zend_type *pre_erasure,
+		const zend_function *proto,
+		zend_class_entry *ce)
+{
+	if (!ce || !pre_erasure) {
+		return fallback;
+	}
+
+	/* Top-level type-param ref of function-scope origin: dereference to the
+	 * param's bound's pre-erasure. This lets `set(U $x)` substitute
+	 * T → ce's binding in U's bound, so the inheritance check compares the
+	 * substituted bound rather than the erased mixed. */
+	if (ZEND_TYPE_HAS_TYPE_PARAMETER(*pre_erasure)
+			&& ZEND_TYPE_TYPE_PARAMETER(*pre_erasure)->origin != ZEND_GENERIC_ORIGIN_CLASS_LIKE) {
+		const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*pre_erasure);
+		if (!ZEND_USER_CODE(proto->common.type)) return fallback;
+		const zend_op_array *op = &proto->op_array;
+		if (!op->generic_parameters || ref->index >= op->generic_parameters->count) {
+			return fallback;
+		}
+		const zend_generic_parameter *p = &op->generic_parameters->parameters[ref->index];
+		const zend_type *bound_pre = ZEND_TYPE_IS_SET(p->bound_pre_erasure)
+			? &p->bound_pre_erasure
+			: (ZEND_TYPE_IS_SET(p->bound) ? &p->bound : NULL);
+		if (!bound_pre || !zend_type_contains_type_parameter(*bound_pre)) {
+			return fallback;
+		}
+		/* Recurse with the bound as the pre-erasure. The recursive call may
+		 * also need to deref (chained method-level bounds), but loop detection
+		 * isn't needed for inheritance because the user-visible bound is a
+		 * finite expression. */
+		return zend_substitute_proto_type_raw(fallback, bound_pre, proto, ce);
+	}
+	if (!zend_type_contains_type_parameter(*pre_erasure)) {
+		return fallback;
+	}
+
+	zend_class_entry *proto_scope = proto->common.scope;
+	if (!proto_scope || !proto_scope->generic_parameters) {
+		return fallback;
+	}
+
+	uint32_t cap = proto_scope->generic_parameters->count;
+	if (cap == 0) {
+		return fallback;
+	}
+
+	ALLOCA_FLAG(use_heap)
+	zend_type *args = (zend_type *) do_alloca(sizeof(zend_type) * cap, use_heap);
+	uint32_t arity;
+	zend_type result;
+	if (!zend_get_inheritance_binding_full_cached(ce, proto_scope, args, cap, &arity)
+			&& !zend_get_target_default_args(proto_scope, args, cap, &arity)) {
+		result = fallback;
+	} else {
+		result = zend_substitute_leaf_type_param(*pre_erasure, args, arity);
+	}
+
+	free_alloca(args, use_heap);
+	return result;
+}
+
+/* If ce supplies type arguments to proto's declaring scope (directly,
+ * transitively, or via parameter defaults), returns proto's pre-erasure type
+ * with class-scope T-refs substituted. Applies a top-level fallback when the
+ * substituted result is still a bare TYPE_PARAMETER (couldn't be ground). */
+static zend_type zend_substitute_proto_type(
+		zend_type fallback,
+		const zend_type *pre_erasure,
+		const zend_function *proto,
+		zend_class_entry *ce)
+{
+	zend_type result = zend_substitute_proto_type_raw(fallback, pre_erasure, proto, ce);
+	/* If the result is *still* a bare type-parameter (couldn't be ground),
+	 * fall back to the erased form. Compound types containing leftover
+	 * type-param leaves are kept — the structural comparison handles them
+	 * by identity. */
+	return ZEND_TYPE_HAS_TYPE_PARAMETER(result) ? fallback : result;
+}
+
+/* Returns the type the inheritance check should use for the child (fe) side.
+ * When the child has a pre-erasure stash and that stash carries class-scope
+ * shape the arg_info erased away (e.g. `Tl|Tr` collapsed to mixed because
+ * both members are unbounded class-scope type parameters), prefer the
+ * pre-erasure so the check sees the same structure that's substituted in
+ * for the parent side. Function-scope refs aren't bound by inheritance —
+ * they erase to their bound and we keep using the erased form.
+ *
+ * `proto_substituted_had_type_param` tells us whether the parent's
+ * substitution would have fallen back to its erased form (its substituted
+ * result was a bare TYPE_PARAMETER). When that's true and the child's
+ * pre-erasure is also a bare TYPE_PARAMETER, the child falls back too —
+ * keeping both sides at the erased mixed so the comparison stays symmetric.
+ * Otherwise the child uses its pre-erasure so structural compounds (unions
+ * like `Tl|Tr`, named-with-args like `I`) line up with the parent's
+ * substituted form. */
+static zend_type zend_resolve_fe_type(
+		zend_type fallback,
+		const zend_type *pre_erasure,
+		const zend_function *fe,
+		zend_class_entry *ce,
+		bool proto_substituted_had_type_param)
+{
+	if (!pre_erasure || !ZEND_TYPE_IS_SET(*pre_erasure)) {
+		return fallback;
+	}
+	/* Function-scope TYPE_PARAMETER ref: deref to the param's bound's
+	 * pre-erasure so its class-scope content can still drive the comparison.
+	 * Mirrors the symmetric deref in zend_substitute_proto_type_raw. */
+	if (ZEND_TYPE_HAS_TYPE_PARAMETER(*pre_erasure)
+			&& ZEND_TYPE_TYPE_PARAMETER(*pre_erasure)->origin != ZEND_GENERIC_ORIGIN_CLASS_LIKE) {
+		const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*pre_erasure);
+		if (!ZEND_USER_CODE(fe->common.type)) return fallback;
+		const zend_op_array *op = &fe->op_array;
+		if (!op->generic_parameters || ref->index >= op->generic_parameters->count) {
+			return fallback;
+		}
+		const zend_generic_parameter *p = &op->generic_parameters->parameters[ref->index];
+		const zend_type *bound_pre = ZEND_TYPE_IS_SET(p->bound_pre_erasure)
+			? &p->bound_pre_erasure
+			: (ZEND_TYPE_IS_SET(p->bound) ? &p->bound : NULL);
+		if (!bound_pre) return fallback;
+		return zend_resolve_fe_type(fallback, bound_pre, fe, ce, proto_substituted_had_type_param);
+	}
+	if (!zend_type_contains_class_scope_type_parameter(*pre_erasure)) {
+		/* Pre-erasure has structure but no class-scope refs to substitute.
+		 * If proto fell back (its substituted result was still a bare type
+		 * param), fall back here too for symmetric mixed-vs-mixed compare;
+		 * otherwise use the pre-erasure structure directly so unions like
+		 * `string|int` compare properly. */
+		if (proto_substituted_had_type_param
+				&& ZEND_TYPE_HAS_TYPE_PARAMETER(*pre_erasure)) {
+			return fallback;
+		}
+		return *pre_erasure;
+	}
+	/* Mirror the parent's fall-back: if proto fell back AND fe's pre-erasure
+	 * is itself a bare TYPE_PARAMETER, fall back to the erased form too. */
+	if (proto_substituted_had_type_param
+			&& ZEND_TYPE_HAS_TYPE_PARAMETER(*pre_erasure)) {
+		return fallback;
+	}
+	/* Immediate-child case: the pre-erasure type-param refs are already in
+	 * fe_scope, which is the same scope the comparison runs in. */
+	if (ce == fe->common.scope) {
+		return *pre_erasure;
+	}
+	/* Transitive: substitute the child's class-scope refs against ce's
+	 * binding to fe's scope. */
+	return zend_substitute_proto_type(fallback, pre_erasure, fe, ce);
+}
+
+static const zend_type *zend_get_param_pre_erasure(const zend_function *proto, uint32_t param_idx)
+{
+	if (!ZEND_USER_CODE(proto->common.type)) return NULL;
+	const zend_op_array *op_array = &proto->op_array;
+	if (!op_array->generic_types || !op_array->generic_types->parameters) return NULL;
+	return zend_hash_index_find_ptr(op_array->generic_types->parameters, param_idx);
+}
+
+static const zend_type *zend_get_return_pre_erasure(const zend_function *proto)
+{
+	if (!ZEND_USER_CODE(proto->common.type)) return NULL;
+	const zend_op_array *op_array = &proto->op_array;
+	if (!op_array->generic_types) return NULL;
+	return op_array->generic_types->return_type;
+}
+
 static inheritance_status zend_do_perform_arg_type_hint_check(
-		zend_class_entry *fe_scope, zend_arg_info *fe_arg_info,
-		zend_class_entry *proto_scope, zend_arg_info *proto_arg_info) /* {{{ */
+		zend_class_entry *fe_scope, zend_type fe_type,
+		zend_class_entry *proto_scope, zend_type proto_type) /* {{{ */
 {
-	if (!ZEND_TYPE_IS_SET(fe_arg_info->type) || ZEND_TYPE_PURE_MASK(fe_arg_info->type) == MAY_BE_ANY) {
+	if (!ZEND_TYPE_IS_SET(fe_type) || ZEND_TYPE_PURE_MASK(fe_type) == MAY_BE_ANY) {
 		/* Child with no type or mixed type is always compatible */
 		return INHERITANCE_SUCCESS;
 	}
 
-	if (!ZEND_TYPE_IS_SET(proto_arg_info->type)) {
+	if (!ZEND_TYPE_IS_SET(proto_type)) {
 		/* Child defines a type, but parent doesn't, violates LSP */
 		return INHERITANCE_ERROR;
 	}
@@ -779,7 +1461,7 @@ static inheritance_status zend_do_perform_arg_type_hint_check(
 	/* Contravariant type check is performed as a covariant type check with swapped
 	 * argument order. */
 	return zend_perform_covariant_type_check(
-		proto_scope, proto_arg_info->type, fe_scope, fe_arg_info->type);
+		proto_scope, proto_type, fe_scope, fe_type);
 }
 /* }}} */
 
@@ -788,7 +1470,8 @@ static inheritance_status zend_do_perform_arg_type_hint_check(
  * the method was declared in. */
 static inheritance_status zend_do_perform_implementation_check(
 		const zend_function *fe, zend_class_entry *fe_scope,
-		const zend_function *proto, zend_class_entry *proto_scope) /* {{{ */
+		const zend_function *proto, zend_class_entry *proto_scope,
+		zend_class_entry *ce) /* {{{ */
 {
 	uint32_t num_args, proto_num_args, fe_num_args;
 	inheritance_status status, local_status;
@@ -849,8 +1532,20 @@ static inheritance_status zend_do_perform_implementation_check(
 			return INHERITANCE_ERROR;
 		}
 
+		uint32_t proto_param_idx = i < proto_num_args ? i : proto_num_args - 1;
+		zend_type proto_raw = zend_substitute_proto_type_raw(
+			proto_arg_info->type,
+			zend_get_param_pre_erasure(proto, proto_param_idx),
+			proto, ce);
+		bool proto_fell_back = ZEND_TYPE_HAS_TYPE_PARAMETER(proto_raw);
+		zend_type proto_type = proto_fell_back ? proto_arg_info->type : proto_raw;
+		uint32_t fe_param_idx = i < fe_num_args ? i : fe_num_args - 1;
+		zend_type fe_type = zend_resolve_fe_type(
+			fe_arg_info->type,
+			zend_get_param_pre_erasure(fe, fe_param_idx),
+			fe, ce, proto_fell_back);
 		local_status = zend_do_perform_arg_type_hint_check(
-			fe_scope, fe_arg_info, proto_scope, proto_arg_info);
+			fe_scope, fe_type, proto_scope, proto_type);
 
 		if (UNEXPECTED(local_status != INHERITANCE_SUCCESS)) {
 			if (UNEXPECTED(local_status == INHERITANCE_ERROR)) {
@@ -880,8 +1575,19 @@ static inheritance_status zend_do_perform_implementation_check(
 			return status;
 		}
 
+		zend_type proto_raw_ret = zend_substitute_proto_type_raw(
+			proto->common.arg_info[-1].type,
+			zend_get_return_pre_erasure(proto),
+			proto, ce);
+		bool proto_ret_fell_back = ZEND_TYPE_HAS_TYPE_PARAMETER(proto_raw_ret);
+		zend_type proto_return_type = proto_ret_fell_back
+			? proto->common.arg_info[-1].type : proto_raw_ret;
+		zend_type fe_return_type = zend_resolve_fe_type(
+			fe->common.arg_info[-1].type,
+			zend_get_return_pre_erasure(fe),
+			fe, ce, proto_ret_fell_back);
 		local_status = zend_perform_covariant_type_check(
-			fe_scope, fe->common.arg_info[-1].type, proto_scope, proto->common.arg_info[-1].type);
+			fe_scope, fe_return_type, proto_scope, proto_return_type);
 
 		if (UNEXPECTED(local_status != INHERITANCE_SUCCESS)) {
 			if (local_status == INHERITANCE_ERROR
@@ -897,10 +1603,11 @@ static inheritance_status zend_do_perform_implementation_check(
 /* }}} */
 
 static ZEND_COLD void zend_append_type_hint(
-		smart_str *str, zend_class_entry *scope, const zend_arg_info *arg_info, bool return_hint) /* {{{ */
+		smart_str *str, const zend_class_entry *scope, const zend_arg_info *arg_info,
+		zend_type display_type, bool return_hint) /* {{{ */
 {
-	if (ZEND_TYPE_IS_SET(arg_info->type)) {
-		zend_string *type_str = zend_type_to_string_resolved(arg_info->type, scope);
+	if (ZEND_TYPE_IS_SET(display_type)) {
+		zend_string *type_str = zend_type_to_string_resolved(display_type, scope);
 		smart_str_append(str, type_str);
 		zend_string_release(type_str);
 		if (!return_hint) {
@@ -911,12 +1618,13 @@ static ZEND_COLD void zend_append_type_hint(
 /* }}} */
 
 static ZEND_COLD zend_string *zend_get_function_declaration(
-		const zend_function *fptr, zend_class_entry *scope) /* {{{ */
+		const zend_function *fptr, const zend_class_entry *scope,
+		zend_class_entry *subst_ce) /* {{{ */
 {
 	smart_str str = {0};
 
 	if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
-		smart_str_appends(&str, "& ");
+		smart_str_appendc(&str, '&');
 	}
 
 	if (fptr->common.scope) {
@@ -924,7 +1632,7 @@ static ZEND_COLD zend_string *zend_get_function_declaration(
 			/* cut off on NULL byte ... class@anonymous */
 			smart_str_appends(&str, ZSTR_VAL(fptr->common.scope->name));
 		} else {
-			smart_str_appendl(&str, ZSTR_VAL(fptr->common.scope->name), ZSTR_LEN(fptr->common.scope->name));
+			smart_str_append(&str, fptr->common.scope->name);
 		}
 		smart_str_appends(&str, "::");
 	}
@@ -942,8 +1650,22 @@ static ZEND_COLD zend_string *zend_get_function_declaration(
 			num_args++;
 		}
 		for (uint32_t i = 0; i < num_args;) {
-			zend_append_type_hint(&str, scope, arg_info, 0);
-
+			uint32_t param_idx = i < fptr->common.num_args ? i : fptr->common.num_args;
+			const zend_type *param_pre = zend_get_param_pre_erasure(fptr, param_idx);
+			zend_type display_type;
+			if (subst_ce) {
+				display_type = zend_substitute_proto_type(arg_info->type, param_pre, fptr, subst_ce);
+			} else if (param_pre && ZEND_TYPE_IS_SET(*param_pre)
+					&& zend_type_contains_class_scope_type_parameter(*param_pre)) {
+				/* Render the pre-erasure shape so messages mirror what the
+				 * inheritance check actually compared. Function-scope refs
+				 * erase to their bound and aren't bound by inheritance, so
+				 * we keep the erased rendering for those. */
+				display_type = *param_pre;
+			} else {
+				display_type = arg_info->type;
+			}
+			zend_append_type_hint(&str, scope, arg_info, display_type, false);
 			if (ZEND_ARG_SEND_MODE(arg_info)) {
 				smart_str_appendc(&str, '&');
 			}
@@ -953,18 +1675,14 @@ static ZEND_COLD zend_string *zend_get_function_declaration(
 			}
 
 			smart_str_appendc(&str, '$');
-			if (fptr->type == ZEND_INTERNAL_FUNCTION) {
-				smart_str_appends(&str, ((zend_internal_arg_info*)arg_info)->name);
-			} else {
-				smart_str_appendl(&str, ZSTR_VAL(arg_info->name), ZSTR_LEN(arg_info->name));
-			}
+			smart_str_append(&str, arg_info->name);
 
 			if (i >= required && !ZEND_ARG_IS_VARIADIC(arg_info)) {
 				smart_str_appends(&str, " = ");
 
 				if (fptr->type == ZEND_INTERNAL_FUNCTION) {
-					if (((zend_internal_arg_info*)arg_info)->default_value) {
-						smart_str_appends(&str, ((zend_internal_arg_info*)arg_info)->default_value);
+					if (arg_info->default_value) {
+						smart_str_append(&str, arg_info->default_value);
 					} else {
 						smart_str_appends(&str, "");
 					}
@@ -1011,7 +1729,9 @@ static ZEND_COLD zend_string *zend_get_function_declaration(
 							zend_ast *ast = Z_ASTVAL_P(zv);
 							if (ast->kind == ZEND_AST_CONSTANT) {
 								smart_str_append(&str, zend_ast_get_constant_name(ast));
-							} else if (ast->kind == ZEND_AST_CLASS_CONST) {
+							} else if (ast->kind == ZEND_AST_CLASS_CONST
+							 && ast->child[1]->kind == ZEND_AST_ZVAL
+							 && Z_TYPE_P(zend_ast_get_zval(ast->child[1])) == IS_STRING) {
 								smart_str_append(&str, zend_ast_get_str(ast->child[0]));
 								smart_str_appends(&str, "::");
 								smart_str_append(&str, zend_ast_get_str(ast->child[1]));
@@ -1039,7 +1759,20 @@ static ZEND_COLD zend_string *zend_get_function_declaration(
 
 	if (fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
 		smart_str_appends(&str, ": ");
-		zend_append_type_hint(&str, scope, fptr->common.arg_info - 1, 1);
+		const zend_arg_info *ret_info = fptr->common.arg_info - 1;
+		const zend_type *ret_pre = zend_get_return_pre_erasure(fptr);
+		zend_type ret_display;
+		if (subst_ce) {
+			ret_display = zend_substitute_proto_type(ret_info->type, ret_pre, fptr, subst_ce);
+		} else if (ret_pre && ZEND_TYPE_IS_SET(*ret_pre)
+				&& zend_type_contains_class_scope_type_parameter(*ret_pre)) {
+			/* Mirror the pre-erasure shape so messages match what the
+			 * inheritance check actually compared. */
+			ret_display = *ret_pre;
+		} else {
+			ret_display = ret_info->type;
+		}
+		zend_append_type_hint(&str, scope, ret_info, ret_display, true);
 	}
 	smart_str_0(&str);
 
@@ -1056,11 +1789,14 @@ static zend_always_inline uint32_t func_lineno(const zend_function *fn) {
 }
 
 static void ZEND_COLD emit_incompatible_method_error(
-		const zend_function *child, zend_class_entry *child_scope,
-		const zend_function *parent, zend_class_entry *parent_scope,
+		const zend_function *child, const zend_class_entry *child_scope,
+		const zend_function *parent, const zend_class_entry *parent_scope,
 		inheritance_status status) {
-	zend_string *parent_prototype = zend_get_function_declaration(parent, parent_scope);
-	zend_string *child_prototype = zend_get_function_declaration(child, child_scope);
+	/* When the child class binds the parent's type parameters (extends/implements
+	 * with type args), display the parent signature in its substituted form so
+	 * the message matches the form being checked. */
+	zend_string *parent_prototype = zend_get_function_declaration(parent, parent_scope, (zend_class_entry *) child_scope);
+	zend_string *child_prototype = zend_get_function_declaration(child, child_scope, NULL);
 	if (status == INHERITANCE_UNRESOLVED) {
 		// TODO Improve error message if first unresolved class is present in child and parent?
 		/* Fetch the first unresolved class from registered autoloads */
@@ -1085,10 +1821,7 @@ static void ZEND_COLD emit_incompatible_method_error(
 				"Return type of %s should either be compatible with %s, "
 				"or the #[\\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice",
 				ZSTR_VAL(child_prototype), ZSTR_VAL(parent_prototype));
-			if (EG(exception)) {
-				zend_exception_uncaught_error(
-					"During inheritance of %s", ZSTR_VAL(parent_scope->name));
-			}
+			ZEND_ASSERT(!EG(exception));
 		}
 	} else {
 		zend_error_at(E_COMPILE_ERROR, func_filename(child), func_lineno(child),
@@ -1105,7 +1838,7 @@ static void perform_delayable_implementation_check(
 		const zend_function *proto, zend_class_entry *proto_scope)
 {
 	inheritance_status status =
-		zend_do_perform_implementation_check(fe, fe_scope, proto, proto_scope);
+		zend_do_perform_implementation_check(fe, fe_scope, proto, proto_scope, ce);
 	if (UNEXPECTED(status != INHERITANCE_SUCCESS)) {
 		if (EXPECTED(status == INHERITANCE_UNRESOLVED)) {
 			add_compatibility_obligation(ce, fe, fe_scope, proto, proto_scope);
@@ -1234,8 +1967,9 @@ static inheritance_status do_inheritance_check_on_method(
 
 	if (flags & ZEND_INHERITANCE_CHECK_PROTO) {
 		if (flags & ZEND_INHERITANCE_CHECK_SILENT) {
-			return zend_do_perform_implementation_check(child, child_scope, parent, parent_scope);
+			return zend_do_perform_implementation_check(child, child_scope, parent, parent_scope, ce);
 		}
+
 		perform_delayable_implementation_check(ce, child, child_scope, parent, parent_scope);
 	}
 
@@ -1251,53 +1985,498 @@ static inheritance_status do_inheritance_check_on_method(
 }
 /* }}} */
 
-static void do_inherit_method(zend_string *key, zend_function *parent, zend_class_entry *ce, bool is_interface, uint32_t flags) /* {{{ */
+static zend_function *zend_maybe_substitute_inherited_method(
+		zend_function *parent_fn, zend_class_entry *ce)
 {
-	zval *child = zend_hash_find_known_hash(&ce->function_table, key);
+	if (parent_fn->type != ZEND_USER_FUNCTION) {
+		return NULL;
+	}
 
-	if (child) {
-		zend_function *func = (zend_function*)Z_PTR_P(child);
+	if (!parent_fn->common.scope || !parent_fn->common.scope->generic_parameters) {
+		return NULL;
+	}
 
-		if (is_interface && UNEXPECTED(func == parent)) {
-			/* The same method in interface may be inherited few times */
-			return;
-		}
+	const zend_op_array *op = &parent_fn->op_array;
+	if (!op->generic_types) {
+		return NULL;
+	}
 
-		do_inheritance_check_on_method(
-			func, func->common.scope, parent, parent->common.scope, ce, child, flags);
-	} else {
+	if (!op->generic_types->parameters && !op->generic_types->return_type) {
+		return NULL;
+	}
 
-		if (is_interface || (parent->common.fn_flags & (ZEND_ACC_ABSTRACT))) {
-			ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
-		}
+	zend_class_entry *defining_ce = parent_fn->common.scope;
+	uint32_t cap = defining_ce->generic_parameters->count;
+	if (cap == 0) {
+		return NULL;
+	}
 
-		parent = zend_duplicate_function(parent, ce);
+	ALLOCA_FLAG(use_heap)
+	zend_type *bound_args = (zend_type *) do_alloca(sizeof(zend_type) * cap, use_heap);
+	uint32_t bound_arity = 0;
+	bool have = zend_get_inheritance_binding_full_cached(ce, defining_ce, bound_args, cap, &bound_arity);
 
-		if (!is_interface) {
-			_zend_hash_append_ptr(&ce->function_table, key, parent);
-		} else {
-			zend_hash_add_new_ptr(&ce->function_table, key, parent);
-		}
+	if (!have) {
+		have = zend_get_target_default_args(defining_ce, bound_args, cap, &bound_arity);
+	}
+
+	if (!have) {
+		free_alloca(bound_args, use_heap);
+		return NULL;
 	}
+
+	zend_function *clone = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
+	memcpy(clone, parent_fn, sizeof(zend_op_array));
+	clone->op_array.fn_flags &= ~ZEND_ACC_IMMUTABLE;
+
+	zend_substitute_trait_method_arg_info(clone, parent_fn, ce, bound_args, bound_arity);
+	free_alloca(bound_args, use_heap);
+	if (clone->op_array.arg_info == parent_fn->op_array.arg_info) {
+		return NULL;
+	}
+
+	/* The clone shares the parent's opcode stream but holds tightened arg_info
+	 * from generic substitution. Mark it like a trait-method clone so opcache
+	 * persistence and the RECV handler can detect that the inline RECV type
+	 * mask may be looser than the live arg_info. */
+	clone->common.fn_flags |= ZEND_ACC_TRAIT_CLONE;
+
+	function_add_ref(clone);
+	return clone;
 }
-/* }}} */
 
-static inheritance_status full_property_types_compatible(
-		const zend_property_info *parent_info, const zend_property_info *child_info,
-		prop_variance variance) {
-	if (ZEND_TYPE_PURE_MASK(parent_info->type) == ZEND_TYPE_PURE_MASK(child_info->type)
-			&& ZEND_TYPE_NAME(parent_info->type) == ZEND_TYPE_NAME(child_info->type)) {
-		return INHERITANCE_SUCCESS;
+/* True iff `t` can be a component of an intersection: a class-name leaf,
+ * or an already-built intersection of class-name leaves. */
+static bool zend_type_intersectable(zend_type t)
+{
+	if (ZEND_TYPE_HAS_NAME(t)) {
+		return ZEND_TYPE_PURE_MASK(t) == 0 || (ZEND_TYPE_PURE_MASK(t) & ~MAY_BE_NULL) == 0;
 	}
 
-	if (ZEND_TYPE_IS_SET(parent_info->type) != ZEND_TYPE_IS_SET(child_info->type)) {
-		return INHERITANCE_ERROR;
+	if (ZEND_TYPE_HAS_LIST(t) && (ZEND_TYPE_FULL_MASK(t) & _ZEND_TYPE_INTERSECTION_BIT)) {
+		return true;
 	}
 
-	/* Perform a covariant type check in both directions to determined invariance. */
-	inheritance_status status1 = variance == PROP_CONTRAVARIANT ? INHERITANCE_SUCCESS :
-		zend_perform_covariant_type_check(
-			child_info->ce, child_info->type, parent_info->ce, parent_info->type);
+	return false;
+}
+
+static ZEND_COLD ZEND_NORETURN void zend_diamond_uninhabited_intersection_error(
+		const zend_class_entry *ce,
+		const zend_class_entry *defining_ce,
+		const zend_function *fn,
+		bool is_return_slot,
+		uint32_t param_slot_idx,
+		zend_type a, zend_type b)
+{
+	zend_string *a_str = zend_type_to_string_resolved(a, (zend_class_entry *) defining_ce);
+	zend_string *b_str = zend_type_to_string_resolved(b, (zend_class_entry *) defining_ce);
+	if (is_return_slot) {
+		zend_error_noreturn(E_COMPILE_ERROR,
+			"Diamond inheritance of %s::%s() in %s would require return type %s&%s, which is uninhabited; constrain the type parameter with an object bound",
+			ZSTR_VAL(defining_ce->name), ZSTR_VAL(fn->common.function_name),
+			ZSTR_VAL(ce->name), ZSTR_VAL(a_str), ZSTR_VAL(b_str));
+	} else {
+		zend_error_noreturn(E_COMPILE_ERROR,
+			"Diamond inheritance of %s::%s() in %s would require parameter #%u type %s&%s, which is uninhabited; constrain the type parameter with an object bound",
+			ZSTR_VAL(defining_ce->name), ZSTR_VAL(fn->common.function_name),
+			ZSTR_VAL(ce->name), param_slot_idx + 1, ZSTR_VAL(a_str), ZSTR_VAL(b_str));
+	}
+}
+
+static zend_type zend_synth_variance_merged_type(zend_type a, zend_type b, bool intersect)
+{
+	if (intersect) {
+		uint32_t total = 0;
+		if (ZEND_TYPE_HAS_LIST(a) && (ZEND_TYPE_FULL_MASK(a) & _ZEND_TYPE_INTERSECTION_BIT)) {
+			total += ZEND_TYPE_LIST(a)->num_types;
+		} else {
+			total += 1;
+		}
+
+		if (ZEND_TYPE_HAS_LIST(b) && (ZEND_TYPE_FULL_MASK(b) & _ZEND_TYPE_INTERSECTION_BIT)) {
+			total += ZEND_TYPE_LIST(b)->num_types;
+		} else {
+			total += 1;
+		}
+
+		zend_type_list *list = zend_arena_alloc(&CG(arena), ZEND_TYPE_LIST_SIZE(total));
+		uint32_t idx = 0;
+		if (ZEND_TYPE_HAS_LIST(a) && (ZEND_TYPE_FULL_MASK(a) & _ZEND_TYPE_INTERSECTION_BIT)) {
+			const zend_type_list *al = ZEND_TYPE_LIST(a);
+			for (uint32_t k = 0; k < al->num_types; k++) {
+				list->types[idx] = al->types[k];
+				zend_type_copy_ctor(&list->types[idx], /* use_arena */ true, /* persistent */ false);
+				idx++;
+			}
+		} else {
+			list->types[idx] = a;
+			zend_type_copy_ctor(&list->types[idx], /* use_arena */ true, /* persistent */ false);
+			idx++;
+		}
+
+		if (ZEND_TYPE_HAS_LIST(b) && (ZEND_TYPE_FULL_MASK(b) & _ZEND_TYPE_INTERSECTION_BIT)) {
+			const zend_type_list *bl = ZEND_TYPE_LIST(b);
+			for (uint32_t k = 0; k < bl->num_types; k++) {
+				list->types[idx] = bl->types[k];
+				zend_type_copy_ctor(&list->types[idx], /* use_arena */ true, /* persistent */ false);
+				idx++;
+			}
+		} else {
+			list->types[idx] = b;
+			zend_type_copy_ctor(&list->types[idx], /* use_arena */ true, /* persistent */ false);
+			idx++;
+		}
+
+		list->num_types = idx;
+		zend_type result = ZEND_TYPE_INIT_NONE(0);
+		ZEND_TYPE_SET_PTR(result, list);
+		ZEND_TYPE_FULL_MASK(result) |=
+			_ZEND_TYPE_LIST_BIT | _ZEND_TYPE_ARENA_BIT | _ZEND_TYPE_INTERSECTION_BIT;
+		if (ZEND_TYPE_ALLOW_NULL(a) && ZEND_TYPE_ALLOW_NULL(b)) {
+			ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NULLABLE_BIT;
+		}
+
+		return result;
+	}
+
+	uint32_t mask = ZEND_TYPE_PURE_MASK(a) | ZEND_TYPE_PURE_MASK(b);
+
+	const zend_type *a_complex_arr = NULL;
+	uint32_t a_complex_count = 0;
+	zend_type a_single = ZEND_TYPE_INIT_NONE(0);
+	if (ZEND_TYPE_HAS_LIST(a) && (ZEND_TYPE_FULL_MASK(a) & _ZEND_TYPE_UNION_BIT)) {
+		a_complex_arr = ZEND_TYPE_LIST(a)->types;
+		a_complex_count = ZEND_TYPE_LIST(a)->num_types;
+	} else if (ZEND_TYPE_HAS_NAME(a)) {
+		a_single = a;
+		a_single.type_mask &= ~_ZEND_TYPE_MAY_BE_MASK;
+		a_complex_arr = &a_single;
+		a_complex_count = 1;
+	}
+
+	const zend_type *b_complex_arr = NULL;
+	uint32_t b_complex_count = 0;
+	zend_type b_single = ZEND_TYPE_INIT_NONE(0);
+	if (ZEND_TYPE_HAS_LIST(b) && (ZEND_TYPE_FULL_MASK(b) & _ZEND_TYPE_UNION_BIT)) {
+		b_complex_arr = ZEND_TYPE_LIST(b)->types;
+		b_complex_count = ZEND_TYPE_LIST(b)->num_types;
+	} else if (ZEND_TYPE_HAS_NAME(b)) {
+		b_single = b;
+		b_single.type_mask &= ~_ZEND_TYPE_MAY_BE_MASK;
+		b_complex_arr = &b_single;
+		b_complex_count = 1;
+	}
+
+	uint32_t total = a_complex_count + b_complex_count;
+	zend_type result = ZEND_TYPE_INIT_NONE(0);
+	if (total == 0) {
+		ZEND_TYPE_FULL_MASK(result) |= mask;
+		return result;
+	}
+
+	if (total == 1) {
+		const zend_type *only = a_complex_count ? a_complex_arr : b_complex_arr;
+		result = *only;
+		zend_type_copy_ctor(&result, /* use_arena */ true, /* persistent */ false);
+		ZEND_TYPE_FULL_MASK(result) |= mask;
+		return result;
+	}
+
+	zend_type_list *list = zend_arena_alloc(&CG(arena), ZEND_TYPE_LIST_SIZE(total));
+	list->num_types = total;
+	uint32_t idx = 0;
+	for (uint32_t k = 0; k < a_complex_count; k++) {
+		list->types[idx] = a_complex_arr[k];
+		zend_type_copy_ctor(&list->types[idx], /* use_arena */ true, /* persistent */ false);
+		idx++;
+	}
+
+	for (uint32_t k = 0; k < b_complex_count; k++) {
+		list->types[idx] = b_complex_arr[k];
+		zend_type_copy_ctor(&list->types[idx], /* use_arena */ true, /* persistent */ false);
+		idx++;
+	}
+
+	ZEND_TYPE_SET_PTR(result, list);
+	ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_LIST_BIT | _ZEND_TYPE_ARENA_BIT | _ZEND_TYPE_UNION_BIT | mask;
+	return result;
+}
+
+/* Declared covariant merges as intersection; contravariant as union; invariant
+ * falls back to use-site variance (return: intersection, param: union).
+ * Returns true and writes `*intersect_out` when `pre` is a class-origin T-ref. */
+static bool zend_generic_merge_polarity(
+		const zend_class_entry *defining_ce,
+		const zend_type *pre,
+		bool is_return_slot,
+		bool *intersect_out)
+{
+	if (!ZEND_TYPE_HAS_TYPE_PARAMETER(*pre)) {
+		return false;
+	}
+	const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*pre);
+	if (ref->origin != ZEND_GENERIC_ORIGIN_CLASS_LIKE
+			|| ref->index >= defining_ce->generic_parameters->count) {
+		return false;
+	}
+	switch (defining_ce->generic_parameters->parameters[ref->index].variance) {
+		case ZEND_GENERIC_VARIANCE_COVARIANT:
+			*intersect_out = true;
+			return true;
+		case ZEND_GENERIC_VARIANCE_CONTRAVARIANT:
+			*intersect_out = false;
+			return true;
+		default:
+			*intersect_out = is_return_slot;
+			return true;
+	}
+}
+
+static bool zend_iface_merge_slot_decision(
+		const zend_class_entry *defining_ce,
+		const zend_type *pre,
+		zend_type existing_type,
+		zend_type incoming_type,
+		const zend_type *hint_args, uint32_t hint_arity,
+		bool is_return_slot,
+		zend_type *b_out, bool *intersect_out)
+{
+	if (!zend_generic_merge_polarity(defining_ce, pre, is_return_slot, intersect_out)) {
+		return false;
+	}
+
+	zend_type b = incoming_type;
+	if (hint_args) {
+		zend_type substituted = zend_substitute_leaf_type_param(*pre, hint_args, hint_arity);
+		if (!ZEND_TYPE_HAS_TYPE_PARAMETER(substituted)) {
+			b = substituted;
+		}
+	}
+
+	if (zend_diamond_types_equal(existing_type, b)) {
+		return false;
+	}
+
+	*b_out = b;
+	return true;
+}
+
+static zend_function *zend_iface_build_merged_clone(
+		zend_function *existing, zend_function *incoming,
+		zend_class_entry *ce)
+{
+	if (!(ce->ce_flags & ZEND_ACC_INTERFACE)
+			|| existing->type != ZEND_USER_FUNCTION
+			|| incoming->type != ZEND_USER_FUNCTION
+			|| existing->common.scope != incoming->common.scope) {
+		return NULL;
+	}
+
+	zend_class_entry *defining_ce = existing->common.scope;
+	if (!defining_ce || !defining_ce->generic_parameters) {
+		return NULL;
+	}
+
+	const zend_op_array *eop = &existing->op_array;
+	if (!eop->generic_types) {
+		return NULL;
+	}
+
+	if (existing->common.num_args != incoming->common.num_args
+			|| (existing->common.fn_flags & ZEND_ACC_VARIADIC)
+				!= (incoming->common.fn_flags & ZEND_ACC_VARIADIC)) {
+		return NULL;
+	}
+
+	uint32_t num_args = existing->common.num_args + ((existing->common.fn_flags & ZEND_ACC_VARIADIC) ? 1 : 0);
+	bool has_return = (existing->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) != 0;
+	uint32_t total = num_args + (has_return ? 1 : 0);
+	if (total == 0) {
+		return NULL;
+	}
+
+	const zend_arg_info *e_block = has_return ? existing->op_array.arg_info - 1 : existing->op_array.arg_info;
+	const zend_arg_info *i_block = has_return ? incoming->op_array.arg_info - 1 : incoming->op_array.arg_info;
+	uint32_t return_slot_offset = has_return ? 1 : 0;
+
+	const zend_type *hint_args = NULL;
+	uint32_t hint_arity = 0;
+	if (CG(inheritance_binding_hint).target == defining_ce) {
+		hint_args = CG(inheritance_binding_hint).args;
+		hint_arity = CG(inheritance_binding_hint).arity;
+	}
+
+	bool any_needs_merge = false;
+	if (has_return && eop->generic_types->return_type) {
+		zend_type b; bool intersect;
+		any_needs_merge = zend_iface_merge_slot_decision(
+			defining_ce, eop->generic_types->return_type,
+			e_block[0].type, i_block[0].type,
+			hint_args, hint_arity, /* is_return_slot */ true,
+			&b, &intersect);
+	}
+
+	if (!any_needs_merge && eop->generic_types->parameters) {
+		zval *zv;
+		zend_ulong idx;
+		ZEND_HASH_FOREACH_NUM_KEY_VAL(eop->generic_types->parameters, idx, zv) {
+			if (idx >= num_args) continue;
+			zend_type b; bool intersect;
+			if (zend_iface_merge_slot_decision(
+					defining_ce, (const zend_type *) Z_PTR_P(zv),
+					e_block[return_slot_offset + idx].type,
+					i_block[return_slot_offset + idx].type,
+					hint_args, hint_arity, /* is_return_slot */ false,
+					&b, &intersect)) {
+				any_needs_merge = true;
+				break;
+			}
+		} ZEND_HASH_FOREACH_END();
+
+		(void) idx;
+	}
+
+	if (!any_needs_merge) {
+		return NULL;
+	}
+
+	zend_arg_info *new_block = zend_clone_arg_info_block(e_block, total);
+
+	if (has_return && eop->generic_types->return_type) {
+		zend_type b; bool intersect;
+		if (zend_iface_merge_slot_decision(
+				defining_ce, eop->generic_types->return_type,
+				e_block[0].type, i_block[0].type,
+				hint_args, hint_arity, /* is_return_slot */ true,
+				&b, &intersect)) {
+			if (intersect && (!zend_type_intersectable(new_block[0].type) || !zend_type_intersectable(b))) {
+				zend_diamond_uninhabited_intersection_error(
+					ce, defining_ce, existing,
+					/* is_return_slot */ true, 0,
+					new_block[0].type, b);
+			}
+
+			new_block[0].type = zend_synth_variance_merged_type(new_block[0].type, b, intersect);
+		}
+	}
+
+	if (eop->generic_types->parameters) {
+		zval *zv;
+		zend_ulong idx;
+		ZEND_HASH_FOREACH_NUM_KEY_VAL(eop->generic_types->parameters, idx, zv) {
+			if (idx >= num_args) continue;
+			zend_type b; bool intersect;
+			if (!zend_iface_merge_slot_decision(
+					defining_ce, (const zend_type *) Z_PTR_P(zv),
+					e_block[return_slot_offset + idx].type,
+					i_block[return_slot_offset + idx].type,
+					hint_args, hint_arity, /* is_return_slot */ false,
+					&b, &intersect)) {
+				continue;
+			}
+
+			uint32_t slot = return_slot_offset + idx;
+			if (intersect && (!zend_type_intersectable(new_block[slot].type) || !zend_type_intersectable(b))) {
+				zend_diamond_uninhabited_intersection_error(
+					ce, defining_ce, existing,
+					/* is_return_slot */ false, (uint32_t) idx,
+					new_block[slot].type, b);
+			}
+
+			new_block[slot].type = zend_synth_variance_merged_type(new_block[slot].type, b, intersect);
+		} ZEND_HASH_FOREACH_END();
+
+		(void) idx;
+	}
+
+	zend_function *merged_fn = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
+	memcpy(merged_fn, existing, sizeof(zend_op_array));
+	merged_fn->op_array.fn_flags &= ~ZEND_ACC_IMMUTABLE;
+	merged_fn->op_array.arg_info = has_return ? new_block + 1 : new_block;
+	ZEND_MAP_PTR_INIT(merged_fn->op_array.run_time_cache, NULL);
+	ZEND_MAP_PTR_INIT(merged_fn->op_array.static_variables_ptr, NULL);
+	return merged_fn;
+}
+
+static bool zend_iface_merge_generic_inherited_method(
+		zend_function *existing, zend_function *incoming,
+		zval *existing_zv, zend_class_entry *ce)
+{
+	zend_function *merged = zend_iface_build_merged_clone(existing, incoming, ce);
+	if (!merged) {
+		return false;
+	}
+
+	Z_PTR_P(existing_zv) = merged;
+	return true;
+}
+
+static bool zend_iface_merge_generic_inherited_hook(
+		zend_function *existing, zend_function *incoming,
+		zend_property_info *child_info, zend_property_hook_kind kind,
+		zend_class_entry *ce)
+{
+	zend_function *merged = zend_iface_build_merged_clone(existing, incoming, ce);
+	if (!merged) {
+		return false;
+	}
+
+	child_info->hooks[kind] = merged;
+	return true;
+}
+
+static void do_inherit_method(zend_string *key, zend_function *parent, zend_class_entry *ce, bool is_interface, uint32_t flags) /* {{{ */
+{
+	zval *child = zend_hash_find_known_hash(&ce->function_table, key);
+
+	if (child) {
+		zend_function *func = (zend_function*)Z_PTR_P(child);
+
+		if (is_interface && UNEXPECTED(func == parent)) {
+			/* The same method in interface may be inherited few times */
+			return;
+		}
+
+		if (is_interface && zend_iface_merge_generic_inherited_method(func, parent, child, ce)) {
+			return;
+		}
+
+		do_inheritance_check_on_method(
+			func, func->common.scope, parent, parent->common.scope, ce, child, flags);
+	} else {
+
+		if (is_interface || (parent->common.fn_flags & (ZEND_ACC_ABSTRACT))) {
+			ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
+		}
+
+		zend_function *substituted = zend_maybe_substitute_inherited_method(parent, ce);
+		parent = substituted ? substituted : zend_duplicate_function(parent, ce);
+
+		if (!is_interface) {
+			_zend_hash_append_ptr(&ce->function_table, key, parent);
+		} else {
+			zend_hash_add_new_ptr(&ce->function_table, key, parent);
+		}
+	}
+}
+/* }}} */
+
+static inheritance_status full_property_types_compatible(
+		const zend_property_info *parent_info, const zend_property_info *child_info,
+		prop_variance variance) {
+	if (ZEND_TYPE_PURE_MASK(parent_info->type) == ZEND_TYPE_PURE_MASK(child_info->type)
+			&& ZEND_TYPE_NAME(parent_info->type) == ZEND_TYPE_NAME(child_info->type)) {
+		return INHERITANCE_SUCCESS;
+	}
+
+	if (ZEND_TYPE_IS_SET(parent_info->type) != ZEND_TYPE_IS_SET(child_info->type)) {
+		return INHERITANCE_ERROR;
+	}
+
+	/* Perform a covariant type check in both directions to determined invariance. */
+	inheritance_status status1 = variance == PROP_CONTRAVARIANT ? INHERITANCE_SUCCESS :
+		zend_perform_covariant_type_check(
+			child_info->ce, child_info->type, parent_info->ce, parent_info->type);
 	inheritance_status status2 = variance == PROP_COVARIANT ? INHERITANCE_SUCCESS :
 		zend_perform_covariant_type_check(
 			parent_info->ce, parent_info->type, child_info->ce, child_info->type);
@@ -1424,6 +2603,10 @@ static void inherit_property_hook(
 			ZSTR_VAL(parent->common.function_name));
 	}
 
+	if ((ce->ce_flags & ZEND_ACC_INTERFACE) && zend_iface_merge_generic_inherited_hook(child, parent, child_info, kind, ce)) {
+		return;
+	}
+
 	do_inheritance_check_on_method(
 		child, child->common.scope, parent, parent->common.scope, ce, /* child */ NULL,
 		ZEND_INHERITANCE_CHECK_PROTO | ZEND_INHERITANCE_CHECK_VISIBILITY
@@ -1520,10 +2703,9 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
 				}
 
 				int parent_num = OBJ_PROP_TO_NUM(parent_info->offset);
+				/* Don't keep default properties in GC (they may be freed by opcache) */
+				zval_ptr_dtor_nogc(&(ce->default_properties_table[parent_num]));
 				if (child_info->offset != ZEND_VIRTUAL_PROPERTY_OFFSET) {
-					/* Don't keep default properties in GC (they may be freed by opcache) */
-					zval_ptr_dtor_nogc(&(ce->default_properties_table[parent_num]));
-
 					if (use_child_prop) {
 						ZVAL_UNDEF(&ce->default_properties_table[parent_num]);
 					} else {
@@ -1566,6 +2748,10 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
 						ZSTR_VAL(key),
 						ZSTR_VAL(parent_info->ce->name));
 			}
+
+			if (child_info->ce == ce) {
+				child_info->flags &= ~ZEND_ACC_OVERRIDE;
+			}
 		}
 	} else {
 		zend_function **hooks = parent_info->hooks;
@@ -1576,7 +2762,78 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
 			}
 		}
 
-		_zend_hash_append_ptr(&ce->properties_info, key, parent_info);
+		zend_property_info *info = parent_info;
+		if (parent_info->ce->generic_types && parent_info->ce->generic_types->properties) {
+			zval *zv = zend_hash_find(parent_info->ce->generic_types->properties, key);
+			if (zv && parent_info->ce->generic_parameters && parent_info->ce->generic_parameters->count > 0) {
+				const zend_type *pre_erasure = (const zend_type *) Z_PTR_P(zv);
+				uint32_t cap = parent_info->ce->generic_parameters->count;
+				ALLOCA_FLAG(use_heap)
+				zend_type *bound_args = (zend_type *) do_alloca(sizeof(zend_type) * cap, use_heap);
+				uint32_t bound_arity = 0;
+				bool have_args = zend_get_inheritance_binding_full_cached(ce, parent_info->ce, bound_args, cap, &bound_arity);
+				if (!have_args) {
+					have_args = zend_get_target_default_args(parent_info->ce, bound_args, cap, &bound_arity);
+				}
+
+				zend_type sub = have_args
+					? zend_substitute_leaf_type_param(*pre_erasure, bound_args, bound_arity)
+					: (zend_type) ZEND_TYPE_INIT_NONE(0);
+				free_alloca(bound_args, use_heap);
+				if (have_args) {
+					if (!ZEND_TYPE_HAS_TYPE_PARAMETER(sub)) {
+						zend_property_info *clone = zend_arena_alloc(&CG(arena), sizeof(*clone));
+						*clone = *parent_info;
+						clone->flags |= ZEND_ACC_GENERIC_CLONE;
+						clone->type = sub;
+						zend_type_copy_ctor(&clone->type, /* use_arena */ true, /* persistent */ false);
+						/* The shallow copy borrows the name pointer from
+						 * parent_info but doesn't addref it. zend_strings are
+						 * refcounted and downstream paths (e.g. when this
+						 * clone is destroyed) release the name, which would
+						 * underflow the parent's count and corrupt the
+						 * string. Take our own reference. */
+						if (clone->name) {
+							zend_string_addref(clone->name);
+						}
+
+						if (hooks && (hooks[ZEND_PROPERTY_HOOK_GET] || hooks[ZEND_PROPERTY_HOOK_SET])) {
+							zend_function **clone_hooks = zend_arena_alloc(
+								&CG(arena), ZEND_PROPERTY_HOOK_STRUCT_SIZE);
+							memcpy(clone_hooks, hooks, ZEND_PROPERTY_HOOK_STRUCT_SIZE);
+
+							for (uint32_t hi = 0; hi < ZEND_PROPERTY_HOOK_COUNT; hi++) {
+								zend_function *orig = hooks[hi];
+								if (!orig) continue;
+
+								uint32_t num_args = orig->op_array.num_args;
+								if (orig->op_array.fn_flags & ZEND_ACC_VARIADIC) num_args++;
+								uint32_t total = num_args + 1;
+
+								zend_arg_info *new_arg_info = zend_clone_arg_info_block(orig->op_array.arg_info - 1, total);
+
+								uint32_t slot = (hi == ZEND_PROPERTY_HOOK_GET) ? 0 : 1;
+								new_arg_info[slot].type = sub;
+								zend_type_copy_ctor(&new_arg_info[slot].type, /* use_arena */ true, /* persistent */ false);
+
+								zend_function *clone_fn = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
+								memcpy(clone_fn, orig, sizeof(zend_op_array));
+								clone_fn->op_array.arg_info = new_arg_info + 1;
+								function_add_ref(clone_fn);
+
+								clone_hooks[hi] = clone_fn;
+							}
+
+							clone->hooks = clone_hooks;
+						}
+
+						info = clone;
+					}
+				}
+			}
+		}
+
+		_zend_hash_append_ptr(&ce->properties_info, key, info);
 	}
 }
 /* }}} */
@@ -1598,11 +2855,7 @@ static void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_en
 
 	ce_num = ce->num_interfaces;
 
-	if (ce->type == ZEND_INTERNAL_CLASS) {
-		ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
-	} else {
-		ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
-	}
+	ce->interfaces = (zend_class_entry **) perealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num), ce->type == ZEND_INTERNAL_CLASS);
 
 	/* Inherit the interfaces, only if they're not already inherited by the class */
 	while (if_num--) {
@@ -1671,7 +2924,7 @@ static void do_inherit_class_constant(zend_string *name, zend_class_constant *pa
 				Z_CONSTANT_FLAGS(c->value) |= CONST_OWNED;
 			}
 		}
-		if (ce->type & ZEND_INTERNAL_CLASS) {
+		if (ce->type == ZEND_INTERNAL_CLASS) {
 			c = pemalloc(sizeof(zend_class_constant), 1);
 			memcpy(c, parent_const, sizeof(zend_class_constant));
 			parent_const = c;
@@ -1713,10 +2966,25 @@ void zend_build_properties_info_table(zend_class_entry *ce)
 		}
 	}
 
-	ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
+	ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&ce->properties_info, zend_string *key, prop) {
 		if (prop->ce == ce && (prop->flags & ZEND_ACC_STATIC) == 0
 		 && !(prop->flags & ZEND_ACC_VIRTUAL)) {
-			uint32_t prop_table_offset = OBJ_PROP_TO_NUM(!(prop->prototype->flags & ZEND_ACC_VIRTUAL) ? prop->prototype->offset : prop->offset);
+			const zend_property_info *root_prop = prop->prototype;
+			if (UNEXPECTED(root_prop->flags & ZEND_ACC_VIRTUAL)) {
+				/* Prototype is virtual, we need to manually hunt down the first backed property. */
+				root_prop = prop;
+				zend_class_entry *parent_ce;
+				while ((parent_ce = root_prop->ce->parent)) {
+					zend_property_info *parent_prop = zend_hash_find_ptr(&parent_ce->properties_info, key);
+					if (!parent_prop
+					 || parent_prop->prototype != prop->prototype
+					 || (parent_prop->flags & ZEND_ACC_VIRTUAL)) {
+						break;
+					}
+					root_prop = parent_prop;
+				}
+			}
+			uint32_t prop_table_offset = OBJ_PROP_TO_NUM(root_prop->offset);
 			table[prop_table_offset] = prop;
 		}
 	} ZEND_HASH_FOREACH_END();
@@ -1768,7 +3036,7 @@ ZEND_API void zend_verify_hooked_property(const zend_class_entry *ce, zend_prope
 	 && (prop_info->flags & ZEND_ACC_PPP_SET_MASK)
 	 && (!prop_info->hooks[ZEND_PROPERTY_HOOK_GET] || !prop_info->hooks[ZEND_PROPERTY_HOOK_SET])) {
 		const char *prefix = !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]
-			? "Write-only" : "Read-only";
+			? "set-only" : "get-only";
 		zend_error_noreturn(E_COMPILE_ERROR,
 			"%s virtual property %s::$%s must not specify asymmetric visibility",
 			prefix, ZSTR_VAL(ce->name), ZSTR_VAL(prop_name));
@@ -1830,6 +3098,41 @@ ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *par
 	zend_property_info *property_info;
 	zend_string *key;
 
+	zend_inheritance_binding_cache binding_cache;
+	binding_cache.present = false;
+	zend_inheritance_binding_cache *prev_binding_cache = CG(inheritance_binding_cache);
+	CG(inheritance_binding_cache) = &binding_cache;
+
+	if (parent_ce && !(ce->ce_flags & ZEND_ACC_INTERFACE)) {
+		const zend_type *extends_args = NULL;
+		uint32_t arity = 0;
+		if (ce->generic_types
+				&& ce->generic_types->extends
+				&& ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)) {
+			extends_args = ce->generic_types->extends;
+			arity = ZEND_TYPE_NAMED_WITH_ARGS(*extends_args)->count;
+		}
+
+		/* If parent_ce is a synthesized monomorph (its name carries `<`),
+		 * the type args were already validated against the base's bounds
+		 * during synthesis. The side-table args we have here refer to the
+		 * original base, not the mono — re-checking them against the
+		 * mono's (empty) generic_parameters would spuriously fail. */
+		if (!zend_class_is_monomorph(parent_ce)) {
+			if (arity > 0 || parent_ce->generic_parameters) {
+				zend_check_generic_link_arity(parent_ce, arity, "extends", ce->name);
+			}
+
+			zend_check_generic_link_bounds(parent_ce, extends_args, "extends", ce);
+		}
+	}
+
+	/* Monomorph synthesis (Box extending Box) is engine-internal and
+	 * needs to bypass FINAL / READONLY-mismatch errors that would block a
+	 * user `extends FinalClass`. The synthesized child re-acquires those
+	 * bits after linking via the propagated/suppressed logic in
+	 * zend_synthesize_monomorph. */
+	bool mono_link = EG(monomorph_synthesis_active);
 	if (UNEXPECTED(ce->ce_flags & ZEND_ACC_INTERFACE)) {
 		/* Interface can only inherit other interfaces */
 		if (UNEXPECTED(!(parent_ce->ce_flags & ZEND_ACC_INTERFACE))) {
@@ -1842,7 +3145,7 @@ ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *par
 			zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend enum %s", ZSTR_VAL(ce->name), ZSTR_VAL(parent_ce->name));
 		}
 		/* Class must not extend a final class */
-		if (parent_ce->ce_flags & ZEND_ACC_FINAL) {
+		if (!mono_link && (parent_ce->ce_flags & ZEND_ACC_FINAL)) {
 			zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend final class %s", ZSTR_VAL(ce->name), ZSTR_VAL(parent_ce->name));
 		}
 
@@ -1854,7 +3157,7 @@ ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *par
 		}
 	}
 
-	if (UNEXPECTED((ce->ce_flags & ZEND_ACC_READONLY_CLASS) != (parent_ce->ce_flags & ZEND_ACC_READONLY_CLASS))) {
+	if (!mono_link && UNEXPECTED((ce->ce_flags & ZEND_ACC_READONLY_CLASS) != (parent_ce->ce_flags & ZEND_ACC_READONLY_CLASS))) {
 		zend_error_noreturn(E_COMPILE_ERROR, "%s class %s cannot extend %s class %s",
 			ce->ce_flags & ZEND_ACC_READONLY_CLASS ? "Readonly" : "Non-readonly", ZSTR_VAL(ce->name),
 			parent_ce->ce_flags & ZEND_ACC_READONLY_CLASS ? "readonly" : "non-readonly", ZSTR_VAL(parent_ce->name)
@@ -2020,7 +3323,7 @@ ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *par
 		}
 		zend_function *func;
 		ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&parent_ce->function_table, key, func) {
-			do_inherit_method(key, func, ce, 0, flags);
+			do_inherit_method(key, func, ce, false, flags);
 		} ZEND_HASH_FOREACH_END();
 	}
 
@@ -2036,6 +3339,8 @@ ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *par
 		}
 	}
 	ce->ce_flags |= parent_ce->ce_flags & (ZEND_HAS_STATIC_IN_METHODS | ZEND_ACC_HAS_TYPE_HINTS | ZEND_ACC_HAS_READONLY_PROPS | ZEND_ACC_USE_GUARDS | ZEND_ACC_NOT_SERIALIZABLE | ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES);
+
+	CG(inheritance_binding_cache) = prev_binding_cache;
 }
 /* }}} */
 
@@ -2138,7 +3443,7 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c,
 				Z_CONSTANT_FLAGS(c->value) |= CONST_OWNED;
 			}
 		}
-		if (ce->type & ZEND_INTERNAL_CLASS) {
+		if (ce->type == ZEND_INTERNAL_CLASS) {
 			ct = pemalloc(sizeof(zend_class_constant), 1);
 			memcpy(ct, c, sizeof(zend_class_constant));
 			c = ct;
@@ -2155,6 +3460,10 @@ static void do_interface_implementation(zend_class_entry *ce, zend_class_entry *
 	zend_class_constant *c;
 	uint32_t flags = ZEND_INHERITANCE_CHECK_PROTO | ZEND_INHERITANCE_CHECK_VISIBILITY;
 
+	if (iface->num_interfaces) {
+		zend_do_inherit_interfaces(ce, iface);
+	}
+
 	if (!(ce->ce_flags & ZEND_ACC_INTERFACE)) {
 		/* We are not setting the prototype of overridden interface methods because of abstract
 		 * constructors. See Zend/tests/interface_constructor_prototype_001.phpt. */
@@ -2173,7 +3482,7 @@ static void do_interface_implementation(zend_class_entry *ce, zend_class_entry *
 	} ZEND_HASH_FOREACH_END();
 
 	ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&iface->function_table, key, func) {
-		do_inherit_method(key, func, ce, 1, flags);
+		do_inherit_method(key, func, ce, true, flags);
 	} ZEND_HASH_FOREACH_END();
 
 	zend_hash_extend(&ce->properties_info,
@@ -2186,9 +3495,6 @@ static void do_interface_implementation(zend_class_entry *ce, zend_class_entry *
 	} ZEND_HASH_FOREACH_END();
 
 	do_implement_interface(ce, iface);
-	if (iface->num_interfaces) {
-		zend_do_inherit_interfaces(ce, iface);
-	}
 }
 /* }}} */
 
@@ -2221,11 +3527,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
 		} ZEND_HASH_FOREACH_END();
 	} else {
 		if (ce->num_interfaces >= current_iface_num) {
-			if (ce->type == ZEND_INTERNAL_CLASS) {
-				ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
-			} else {
-				ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
-			}
+			ce->interfaces = (zend_class_entry **) perealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num), ce->type == ZEND_INTERNAL_CLASS);
 		}
 		ce->interfaces[ce->num_interfaces++] = iface;
 
@@ -2234,6 +3536,64 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
 }
 /* }}} */
 
+static bool zend_iface_diamond_bindings_allowed(
+		const zend_class_entry *iface,
+		const zend_type *prior_args, uint32_t prior_arity,
+		const zend_type *cur_args, uint32_t cur_arity)
+{
+	if (!iface->generic_parameters || prior_arity != cur_arity) {
+		return false;
+	}
+
+	for (uint32_t k = 0; k < prior_arity; k++) {
+		if (!zend_diamond_types_equal(prior_args[k], cur_args[k])) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static bool zend_iface_diamond_direct_dup_allowed(
+		const zend_class_entry *ce, const zend_class_entry *iface,
+		uint32_t prior_clause_idx, uint32_t cur_clause_idx)
+{
+	const zend_type_named_with_args *prior = zend_get_implements_binding(ce, prior_clause_idx);
+	const zend_type_named_with_args *cur   = zend_get_implements_binding(ce, cur_clause_idx);
+	if (!prior || !cur) {
+		return false;
+	}
+
+	return zend_iface_diamond_bindings_allowed(iface, prior->args, prior->count, cur->args, cur->count);
+}
+
+static bool zend_iface_diamond_parent_vs_own_allowed(
+		const zend_class_entry *ce, const zend_class_entry *iface,
+		uint32_t cur_clause_idx)
+{
+	if (!ce->parent || !iface->generic_parameters) {
+		return false;
+	}
+
+	const zend_type_named_with_args *cur = zend_get_implements_binding(ce, cur_clause_idx);
+	if (!cur) {
+		return false;
+	}
+
+	uint32_t cap = iface->generic_parameters->count;
+	if (cap == 0) {
+		return false;
+	}
+
+	ALLOCA_FLAG(use_heap)
+	zend_type *prior_args = (zend_type *) do_alloca(sizeof(zend_type) * cap, use_heap);
+	uint32_t prior_arity;
+	bool allowed = zend_get_inheritance_binding_full(ce->parent, iface, prior_args, cap, &prior_arity)
+		&& zend_iface_diamond_bindings_allowed(iface, prior_args, prior_arity, cur->args, cur->count);
+	free_alloca(prior_args, use_heap);
+	return allowed;
+}
+
 static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry **interfaces) /* {{{ */
 {
 	uint32_t num_parent_interfaces = ce->parent ? ce->parent->num_interfaces : 0;
@@ -2250,17 +3610,23 @@ static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry
 		if (UNEXPECTED(!(iface->ce_flags & ZEND_ACC_INTERFACE))) {
 			efree(interfaces);
 			zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ZSTR_VAL(ce->name), ZSTR_VAL(iface->name));
-			return;
 		}
 		for (uint32_t j = 0; j < num_interfaces; j++) {
 			if (interfaces[j] == iface) {
 				if (j >= num_parent_interfaces) {
+					if (zend_iface_diamond_direct_dup_allowed(ce, iface, j - num_parent_interfaces, i)) {
+						break;
+					}
+
 					efree(interfaces);
 					zend_error_noreturn(E_COMPILE_ERROR, "%s %s cannot implement previously implemented interface %s",
 						zend_get_object_type_uc(ce),
 						ZSTR_VAL(ce->name),
 						ZSTR_VAL(iface->name));
-					return;
+				}
+
+				if (zend_iface_diamond_parent_vs_own_allowed(ce, iface, i)) {
+					break;
 				}
 				/* skip duplications */
 				ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&iface->constants_table, key, c) {
@@ -2292,10 +3658,25 @@ static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry
 	for (i = 0; i < num_parent_interfaces; i++) {
 		do_implement_interface(ce, ce->interfaces[i]);
 	}
+
 	/* Note that new interfaces can be added during this loop due to interface inheritance.
 	 * Use num_interfaces rather than ce->num_interfaces to not re-process the new ones. */
 	for (; i < num_interfaces; i++) {
-		do_interface_implementation(ce, ce->interfaces[i]);
+		zend_class_entry *iface_ce = ce->interfaces[i];
+		const zend_type_named_with_args *binding = iface_ce->generic_parameters
+			? zend_get_implements_binding(ce, i - num_parent_interfaces)
+			: NULL;
+
+		if (binding) {
+			CG(inheritance_binding_hint).target = iface_ce;
+			CG(inheritance_binding_hint).args = binding->args;
+			CG(inheritance_binding_hint).arity = binding->count;
+		}
+
+		do_interface_implementation(ce, iface_ce);
+		CG(inheritance_binding_hint).target = NULL;
+		CG(inheritance_binding_hint).args = NULL;
+		CG(inheritance_binding_hint).arity = 0;
 	}
 }
 /* }}} */
@@ -2303,13 +3684,11 @@ static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry
 
 void zend_inheritance_check_override(const zend_class_entry *ce)
 {
-	zend_function *f;
-
 	if (ce->ce_flags & ZEND_ACC_TRAIT) {
 		return;
 	}
 
-	ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, f) {
+	ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zend_function *f) {
 		if (f->common.fn_flags & ZEND_ACC_OVERRIDE) {
 			ZEND_ASSERT(f->type != ZEND_INTERNAL_FUNCTION);
 
@@ -2320,14 +3699,17 @@ void zend_inheritance_check_override(const zend_class_entry *ce)
 		}
 	} ZEND_HASH_FOREACH_END();
 
-	if (ce->num_hooked_props) {
-		zend_property_info *prop;
-		ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
-			if (!prop->hooks) {
-				continue;
-			}
+	ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *prop) {
+		if (prop->flags & ZEND_ACC_OVERRIDE) {
+			zend_error_noreturn(
+				E_COMPILE_ERROR,
+				"%s::$%s has #[\\Override] attribute, but no matching parent property exists",
+				ZSTR_VAL(ce->name), zend_get_unmangled_property_name(prop->name));
+		}
+
+		if (prop->hooks) {
 			for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
-				f = prop->hooks[i];
+				zend_function *f = prop->hooks[i];
 				if (f && f->common.fn_flags & ZEND_ACC_OVERRIDE) {
 					ZEND_ASSERT(f->type != ZEND_INTERNAL_FUNCTION);
 
@@ -2337,8 +3719,8 @@ void zend_inheritance_check_override(const zend_class_entry *ce)
 						ZEND_FN_SCOPE_NAME(f), ZSTR_VAL(f->common.function_name));
 				}
 			}
-		} ZEND_HASH_FOREACH_END();
-	}
+		}
+	} ZEND_HASH_FOREACH_END();
 }
 
 
@@ -2348,18 +3730,331 @@ static zend_class_entry *fixup_trait_scope(const zend_function *fn, zend_class_e
 	return fn->common.scope->ce_flags & ZEND_ACC_TRAIT ? ce : fn->common.scope;
 }
 
-static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_string *key, zend_function *fn) /* {{{ */
+static const zend_type_named_with_args *zend_find_trait_use_binding_by_name(
+		const zend_class_entry *ce, zend_string *trait_name)
 {
-	zend_function *existing_fn = NULL;
-	zend_function *new_fn;
-
-	if ((existing_fn = zend_hash_find_ptr(&ce->function_table, key)) != NULL) {
-		/* if it is the same function with the same visibility and has not been assigned a class scope yet, regardless
-		 * of where it is coming from there is no conflict and we do not need to add it again */
-		if (existing_fn->op_array.opcodes == fn->op_array.opcodes &&
-			(existing_fn->common.fn_flags & ZEND_ACC_PPP_MASK) == (fn->common.fn_flags & ZEND_ACC_PPP_MASK) &&
-			(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) {
-			return;
+	if (!ce->generic_types || !ce->generic_types->trait_uses) return NULL;
+	zval *zv;
+	ZEND_HASH_FOREACH_VAL(ce->generic_types->trait_uses, zv) {
+		zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+		if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) continue;
+		const zend_type_named_with_args *nwa = ZEND_TYPE_NAMED_WITH_ARGS(*boxed);
+		if (nwa->name && zend_string_equals_ci(nwa->name, trait_name)) {
+			return nwa;
+		}
+	} ZEND_HASH_FOREACH_END();
+
+	return NULL;
+}
+
+static zend_arg_info *zend_clone_arg_info_block(const zend_arg_info *orig_block, uint32_t total)
+{
+	zend_arg_info *new_block = zend_arena_alloc(&CG(arena), sizeof(zend_arg_info) * total);
+	memcpy(new_block, orig_block, sizeof(zend_arg_info) * total);
+	for (uint32_t i = 0; i < total; i++) {
+		if (new_block[i].name) {
+			zend_string_addref(new_block[i].name);
+		}
+
+		if (new_block[i].doc_comment) {
+			zend_string_addref(new_block[i].doc_comment);
+		}
+
+		zend_type_copy_ctor(&new_block[i].type, /* use_arena */ true, /* persistent */ false);
+	}
+
+	return new_block;
+}
+
+/* After substitution lands on a CLASS_LIKE T-ref into the using class itself
+ * (e.g., `use Holder` in `class Box` rewrites Holder's X to
+ * Box's T), the substituted T-ref must be erased to the using class's
+ * declared bound. Without this, the trait's original "unbound X → mixed"
+ * erasure leaks into the using class's signature and the runtime
+ * type-check accepts values that violate the bound. Returns the original
+ * type when the ref isn't a using-class T-ref we can erase. */
+static zend_type zend_erase_using_class_t_ref(
+		zend_type t, const zend_class_entry *using_ce)
+{
+	if (!ZEND_TYPE_HAS_TYPE_PARAMETER(t)) {
+		return t;
+	}
+	const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(t);
+	if (ref->origin != ZEND_GENERIC_ORIGIN_CLASS_LIKE
+			|| !using_ce->generic_parameters
+			|| ref->index >= using_ce->generic_parameters->count) {
+		return t;
+	}
+	const zend_generic_parameter *gp =
+		&using_ce->generic_parameters->parameters[ref->index];
+	zend_type erased = ZEND_TYPE_IS_SET(gp->bound)
+		? gp->bound
+		: (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY);
+	if (ZEND_TYPE_FULL_MASK(t) & _ZEND_TYPE_NULLABLE_BIT) {
+		ZEND_TYPE_FULL_MASK(erased) |= _ZEND_TYPE_NULLABLE_BIT;
+	}
+	return erased;
+}
+
+static void zend_substitute_trait_method_arg_info(
+		zend_function *new_fn, const zend_function *orig_fn,
+		const zend_class_entry *using_ce,
+		const zend_type *bind_args, uint32_t bind_arity)
+{
+	if (orig_fn->type != ZEND_USER_FUNCTION) return;
+	const zend_op_array *orig_op = &orig_fn->op_array;
+	if (!orig_op->generic_types) {
+		return;
+	}
+
+	if (!orig_op->generic_types->parameters && !orig_op->generic_types->return_type) {
+		return;
+	}
+
+	uint32_t num_args = orig_op->num_args;
+	if (orig_op->fn_flags & ZEND_ACC_VARIADIC) num_args++;
+	bool has_return = (orig_op->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) != 0;
+	uint32_t total = num_args + (has_return ? 1 : 0);
+	if (total == 0) {
+		return;
+	}
+
+	const zend_arg_info *orig_block = has_return ? orig_op->arg_info - 1 : orig_op->arg_info;
+	zend_arg_info *new_block = NULL;
+
+	uint32_t return_slot_offset = has_return ? 1 : 0;
+
+	/* The substituted `sub` zend_type comes from compiling the pre-erasure
+	 * AST and carries only the type bits — none of the arg_info-level flags
+	 * (send mode / by-ref, variadic, promoted, tentative) which live in the
+	 * type_mask's extra-flag region. Preserve those from the original slot. */
+	const uint32_t arg_extra_flags_mask =
+		(3u << _ZEND_SEND_MODE_SHIFT)
+		| _ZEND_IS_VARIADIC_BIT
+		| _ZEND_IS_PROMOTED_BIT
+		| _ZEND_IS_TENTATIVE_BIT;
+
+	if (has_return && orig_op->generic_types->return_type) {
+		const zend_type *pre = orig_op->generic_types->return_type;
+		if (ZEND_TYPE_HAS_TYPE_PARAMETER(*pre)) {
+			zend_type sub = zend_substitute_leaf_type_param(*pre, bind_args, bind_arity);
+			sub = zend_erase_using_class_t_ref(sub, using_ce);
+			if (!ZEND_TYPE_HAS_TYPE_PARAMETER(sub)) {
+				if (!new_block) {
+					new_block = zend_clone_arg_info_block(orig_block, total);
+				}
+				uint32_t carry = ZEND_TYPE_FULL_MASK(new_block[0].type) & arg_extra_flags_mask;
+				new_block[0].type = sub;
+				ZEND_TYPE_FULL_MASK(new_block[0].type) |= carry;
+				zend_type_copy_ctor(&new_block[0].type, /* use_arena */ true, /* persistent */ false);
+			}
+		}
+	}
+
+	if (orig_op->generic_types->parameters) {
+		zval *zv;
+		zend_ulong idx;
+		ZEND_HASH_FOREACH_NUM_KEY_VAL(orig_op->generic_types->parameters, idx, zv) {
+			if (idx >= num_args) {
+				continue;
+			}
+
+			zend_type *pre_erasure = (zend_type *) Z_PTR_P(zv);
+			if (!ZEND_TYPE_HAS_TYPE_PARAMETER(*pre_erasure)) {
+				continue;
+			}
+
+			zend_type sub = zend_substitute_leaf_type_param(*pre_erasure, bind_args, bind_arity);
+			sub = zend_erase_using_class_t_ref(sub, using_ce);
+			if (ZEND_TYPE_HAS_TYPE_PARAMETER(sub)) {
+				continue;
+			}
+
+			if (!new_block) {
+				new_block = zend_clone_arg_info_block(orig_block, total);
+			}
+			uint32_t carry = ZEND_TYPE_FULL_MASK(new_block[return_slot_offset + idx].type) & arg_extra_flags_mask;
+			new_block[return_slot_offset + idx].type = sub;
+			ZEND_TYPE_FULL_MASK(new_block[return_slot_offset + idx].type) |= carry;
+			zend_type_copy_ctor(&new_block[return_slot_offset + idx].type, /* use_arena */ true, /* persistent */ false);
+		} ZEND_HASH_FOREACH_END();
+	}
+
+	if (new_block) {
+		new_fn->op_array.arg_info = has_return ? new_block + 1 : new_block;
+	}
+}
+
+static const zend_type_named_with_args *zend_get_trait_use_binding_by_index(
+		const zend_class_entry *ce, uint32_t trait_idx)
+{
+	if (!ce->generic_types || !ce->generic_types->trait_uses) {
+		 return NULL;
+	}
+
+	zval *zv = zend_hash_index_find(ce->generic_types->trait_uses, trait_idx);
+	if (!zv) {
+		 return NULL;
+	}
+
+	zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+	if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) {
+		 return NULL;
+	}
+
+	return ZEND_TYPE_NAMED_WITH_ARGS(*boxed);
+}
+
+static void zend_trait_diamond_merge_method(
+		zend_class_entry *ce, zend_string *key,
+		zend_function *existing, zend_function *fn,
+		const zend_type_named_with_args *binding)
+{
+	if (!binding || existing->type != ZEND_USER_FUNCTION) {
+		return;
+	}
+
+	zend_class_entry *defining_ce = existing->common.scope;
+	if (!defining_ce || !defining_ce->generic_parameters) {
+		return;
+	}
+
+	const zend_op_array *eop = &existing->op_array;
+	if (!eop->generic_types) {
+		return;
+	}
+
+	uint32_t num_args = existing->common.num_args + ((existing->common.fn_flags & ZEND_ACC_VARIADIC) ? 1 : 0);
+	bool has_return = (existing->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) != 0;
+	uint32_t total = num_args + (has_return ? 1 : 0);
+	if (total == 0) {
+		return;
+	}
+
+	const zend_arg_info *e_block = has_return ? existing->op_array.arg_info - 1 : existing->op_array.arg_info;
+	uint32_t return_slot_offset = has_return ? 1 : 0;
+
+	bool any_needs_merge = false;
+	if (has_return && eop->generic_types->return_type) {
+		const zend_type *pre = eop->generic_types->return_type;
+		bool intersect;
+		if (zend_generic_merge_polarity(defining_ce, pre, /* is_return_slot */ true, &intersect)) {
+			zend_type sub = zend_substitute_leaf_type_param(*pre, binding->args, binding->count);
+			if (!ZEND_TYPE_HAS_TYPE_PARAMETER(sub) && !zend_diamond_types_equal(e_block[0].type, sub)) {
+				any_needs_merge = true;
+			}
+		}
+	}
+
+	if (!any_needs_merge && eop->generic_types->parameters) {
+		zval *zv;
+		zend_ulong idx;
+		ZEND_HASH_FOREACH_NUM_KEY_VAL(eop->generic_types->parameters, idx, zv) {
+			if (idx >= num_args) {
+				continue;
+			}
+
+			const zend_type *pre = (const zend_type *) Z_PTR_P(zv);
+			bool intersect;
+			if (!zend_generic_merge_polarity(defining_ce, pre, /* is_return_slot */ false, &intersect)) {
+				continue;
+			}
+
+			zend_type sub = zend_substitute_leaf_type_param(*pre, binding->args, binding->count);
+			if (!ZEND_TYPE_HAS_TYPE_PARAMETER(sub) && !zend_diamond_types_equal(e_block[return_slot_offset + idx].type, sub)) {
+				any_needs_merge = true;
+				break;
+			}
+		} ZEND_HASH_FOREACH_END();
+
+		(void) idx;
+	}
+
+	if (!any_needs_merge) {
+		return;
+	}
+
+	zend_arg_info *new_block = zend_clone_arg_info_block(e_block, total);
+
+	if (has_return && eop->generic_types->return_type) {
+		const zend_type *pre = eop->generic_types->return_type;
+		bool intersect;
+		if (zend_generic_merge_polarity(defining_ce, pre, /* is_return_slot */ true, &intersect)) {
+			zend_type sub = zend_substitute_leaf_type_param(*pre, binding->args, binding->count);
+			if (!ZEND_TYPE_HAS_TYPE_PARAMETER(sub) && !zend_diamond_types_equal(new_block[0].type, sub)) {
+				if (intersect && (!zend_type_intersectable(new_block[0].type) || !zend_type_intersectable(sub))) {
+					zend_diamond_uninhabited_intersection_error(
+						ce, defining_ce, existing,
+						/* is_return_slot */ true, 0,
+						new_block[0].type, sub);
+				}
+
+				new_block[0].type = zend_synth_variance_merged_type(new_block[0].type, sub, intersect);
+			}
+		}
+	}
+
+	if (eop->generic_types->parameters) {
+		zval *zv;
+		zend_ulong idx;
+		ZEND_HASH_FOREACH_NUM_KEY_VAL(eop->generic_types->parameters, idx, zv) {
+			if (idx >= num_args) {
+				continue;
+			}
+
+			const zend_type *pre = (const zend_type *) Z_PTR_P(zv);
+			bool intersect;
+			if (!zend_generic_merge_polarity(defining_ce, pre, /* is_return_slot */ false, &intersect)) {
+				continue;
+			}
+
+			zend_type sub = zend_substitute_leaf_type_param(*pre, binding->args, binding->count);
+			if (ZEND_TYPE_HAS_TYPE_PARAMETER(sub)) {
+				continue;
+			}
+
+			uint32_t slot = return_slot_offset + idx;
+			if (zend_diamond_types_equal(new_block[slot].type, sub)) {
+				continue;
+			}
+
+			if (intersect && (!zend_type_intersectable(new_block[slot].type) || !zend_type_intersectable(sub))) {
+				zend_diamond_uninhabited_intersection_error(
+					ce, defining_ce, existing,
+					/* is_return_slot */ false, (uint32_t) idx,
+					new_block[slot].type, sub);
+			}
+
+			new_block[slot].type = zend_synth_variance_merged_type(new_block[slot].type, sub, intersect);
+		} ZEND_HASH_FOREACH_END();
+		(void) idx;
+	}
+
+	zend_function *merged_fn = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
+	memcpy(merged_fn, existing, sizeof(zend_op_array));
+	merged_fn->op_array.fn_flags &= ~ZEND_ACC_IMMUTABLE;
+	merged_fn->op_array.arg_info = has_return ? new_block + 1 : new_block;
+	ZEND_MAP_PTR_INIT(merged_fn->op_array.run_time_cache, NULL);
+	ZEND_MAP_PTR_INIT(merged_fn->op_array.static_variables_ptr, NULL);
+	zval *slot = zend_hash_find_known_hash(&ce->function_table, key);
+	ZEND_ASSERT(slot != NULL && Z_PTR_P(slot) == existing);
+	Z_PTR_P(slot) = merged_fn;
+}
+
+static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_string *key, zend_function *fn, uint32_t trait_idx) /* {{{ */
+{
+	zend_function *existing_fn = NULL;
+	zend_function *new_fn;
+
+	if ((existing_fn = zend_hash_find_ptr(&ce->function_table, key)) != NULL) {
+		/* if it is the same function with the same visibility and has not been assigned a class scope yet, regardless
+		 * of where it is coming from there is no conflict and we do not need to add it again */
+		if (existing_fn->op_array.opcodes == fn->op_array.opcodes &&
+			(existing_fn->common.fn_flags & ZEND_ACC_PPP_MASK) == (fn->common.fn_flags & ZEND_ACC_PPP_MASK) &&
+			(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) {
+			const zend_type_named_with_args *binding = zend_get_trait_use_binding_by_index(ce, trait_idx);
+			zend_trait_diamond_merge_method(ce, key, existing_fn, fn, binding);
+			return;
 		}
 
 		/* Abstract method signatures from the trait must be satisfied. */
@@ -2402,6 +4097,28 @@ static void zend_add_trait_method(zend_class_entry *ce, zend_string *name, zend_
 	/* Reassign method name, in case it is an alias. */
 	new_fn->common.function_name = name;
 	function_add_ref(new_fn);
+
+	if (fn->type == ZEND_USER_FUNCTION && fn->common.scope && fn->common.scope->generic_parameters) {
+		const zend_type_named_with_args *binding = zend_find_trait_use_binding_by_name(ce, fn->common.scope->name);
+		uint32_t cap = fn->common.scope->generic_parameters->count;
+		ALLOCA_FLAG(use_heap)
+		zend_type *default_args = (zend_type *) do_alloca(sizeof(zend_type) * cap, use_heap);
+		const zend_type *bind_args = NULL;
+		uint32_t bind_arity = 0;
+		if (binding) {
+			bind_args = binding->args;
+			bind_arity = binding->count;
+		} else if (zend_get_target_default_args(fn->common.scope, default_args, cap, &bind_arity)) {
+			bind_args = default_args;
+		}
+
+		if (bind_args) {
+			zend_substitute_trait_method_arg_info(new_fn, fn, ce, bind_args, bind_arity);
+		}
+
+		free_alloca(default_args, use_heap);
+	}
+
 	fn = zend_hash_update_ptr(&ce->function_table, key, new_fn);
 	zend_add_magic_method(ce, fn, key);
 }
@@ -2436,7 +4153,7 @@ static void zend_traits_check_private_final_inheritance(uint32_t original_fn_fla
 	}
 }
 
-static void zend_traits_copy_functions(zend_string *fnname, zend_function *fn, zend_class_entry *ce, HashTable *exclude_table, zend_class_entry **aliases) /* {{{ */
+static void zend_traits_copy_functions(zend_string *fnname, zend_function *fn, zend_class_entry *ce, HashTable *exclude_table, zend_class_entry **aliases, uint32_t trait_idx) /* {{{ */
 {
 	zend_trait_alias  *alias, **alias_ptr;
 	zend_function      fn_copy;
@@ -2463,7 +4180,7 @@ static void zend_traits_copy_functions(zend_string *fnname, zend_function *fn, z
 				zend_traits_check_private_final_inheritance(fn->common.fn_flags, &fn_copy, alias->alias);
 
 				zend_string *lcname = zend_string_tolower(alias->alias);
-				zend_add_trait_method(ce, alias->alias, lcname, &fn_copy);
+				zend_add_trait_method(ce, alias->alias, lcname, &fn_copy, trait_idx);
 				zend_string_release_ex(lcname, 0);
 			}
 			alias_ptr++;
@@ -2501,7 +4218,7 @@ static void zend_traits_copy_functions(zend_string *fnname, zend_function *fn, z
 
 		zend_traits_check_private_final_inheritance(fn->common.fn_flags, &fn_copy, fnname);
 
-		zend_add_trait_method(ce, fn->common.function_name, fnname, &fn_copy);
+		zend_add_trait_method(ce, fn->common.function_name, fnname, &fn_copy, trait_idx);
 	}
 }
 /* }}} */
@@ -2510,7 +4227,6 @@ static uint32_t zend_check_trait_usage(const zend_class_entry *ce, const zend_cl
 {
 	if (UNEXPECTED((trait->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT)) {
 		zend_error_noreturn(E_COMPILE_ERROR, "Class %s is not a trait, Only traits may be used in 'as' and 'insteadof' statements", ZSTR_VAL(trait->name));
-		return 0;
 	}
 
 	for (uint32_t i = 0; i < ce->num_traits; i++) {
@@ -2519,7 +4235,6 @@ static uint32_t zend_check_trait_usage(const zend_class_entry *ce, const zend_cl
 		}
 	}
 	zend_error_noreturn(E_COMPILE_ERROR, "Required Trait %s wasn't added to %s", ZSTR_VAL(trait->name), ZSTR_VAL(ce->name));
-	return 0;
 }
 /* }}} */
 
@@ -2693,7 +4408,7 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
 					if (verify_abstract != is_abstract) {
 						continue;
 					}
-					zend_traits_copy_functions(key, fn, ce, exclude_tables[i], aliases);
+					zend_traits_copy_functions(key, fn, ce, exclude_tables[i], aliases, i);
 				} ZEND_HASH_FOREACH_END();
 
 				if (exclude_tables[i]) {
@@ -2712,7 +4427,7 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
 					if (verify_abstract != is_abstract) {
 						continue;
 					}
-					zend_traits_copy_functions(key, fn, ce, NULL, aliases);
+					zend_traits_copy_functions(key, fn, ce, NULL, aliases, i);
 				} ZEND_HASH_FOREACH_END();
 			}
 		}
@@ -2755,6 +4470,19 @@ static void emit_incompatible_trait_constant_error(
 	);
 }
 
+static void emit_trait_constant_enum_case_conflict_error(
+	const zend_class_entry *ce, const zend_class_constant *trait_constant, zend_string *name
+) {
+	zend_error_noreturn(E_COMPILE_ERROR,
+		"Cannot use trait %s, because %s::%s conflicts with enum case %s::%s",
+		ZSTR_VAL(trait_constant->ce->name),
+		ZSTR_VAL(trait_constant->ce->name),
+		ZSTR_VAL(name),
+		ZSTR_VAL(ce->name),
+		ZSTR_VAL(name)
+	);
+}
+
 static bool do_trait_constant_check(
 	zend_class_entry *ce, zend_class_constant *trait_constant, zend_string *name, zend_class_entry **traits, size_t current_trait
 ) {
@@ -2768,6 +4496,11 @@ static bool do_trait_constant_check(
 
 	zend_class_constant *existing_constant = Z_PTR_P(zv);
 
+	if (UNEXPECTED(ZEND_CLASS_CONST_FLAGS(existing_constant) & ZEND_CLASS_CONST_IS_CASE)) {
+		emit_trait_constant_enum_case_conflict_error(ce, trait_constant, name);
+		return false;
+	}
+
 	if ((ZEND_CLASS_CONST_FLAGS(trait_constant) & flags_mask) != (ZEND_CLASS_CONST_FLAGS(existing_constant) & flags_mask)) {
 		emit_incompatible_trait_constant_error(ce, existing_constant, trait_constant, name, traits, current_trait);
 		return false;
@@ -2915,9 +4648,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
 								ZSTR_VAL(prop_name),
 								ZSTR_VAL(ce->name));
 					}
-					if (!(flags & ZEND_ACC_STATIC)) {
-						continue;
-					}
+					continue;
 				}
 			}
 
@@ -2948,6 +4679,25 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
 			zend_string *doc_comment = property_info->doc_comment ? zend_string_copy(property_info->doc_comment) : NULL;
 
 			zend_type type = property_info->type;
+			const zend_type *pre_erasure = zend_get_trait_property_pre_erasure(traits[i], prop_name);
+			if (pre_erasure && traits[i]->generic_parameters && traits[i]->generic_parameters->count > 0) {
+				const zend_type *bind_args;
+				uint32_t bind_arity;
+				uint32_t cap = traits[i]->generic_parameters->count;
+				ALLOCA_FLAG(use_heap)
+				zend_type *default_args = (zend_type *) do_alloca(sizeof(zend_type) * cap, use_heap);
+				if (zend_get_trait_use_binding(ce, i, &bind_args, &bind_arity)) {
+					type = zend_substitute_leaf_type_param(*pre_erasure, bind_args, bind_arity);
+				} else if (zend_get_target_default_args(traits[i], default_args, cap, &bind_arity)) {
+					type = zend_substitute_leaf_type_param(*pre_erasure, default_args, bind_arity);
+				}
+
+				free_alloca(default_args, use_heap);
+				if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) {
+					type = property_info->type;
+				}
+			}
+
 			/* Assumption: only userland classes can use traits, as such the type must be arena allocated */
 			zend_type_copy_ctor(&type, /* use arena */ true, /* persistent */ false);
 			zend_property_info *new_prop = zend_declare_typed_property(ce, prop_name, prop_value, flags, doc_comment, type);
@@ -3206,7 +4956,7 @@ static void add_property_hook_obligation(
 
 static void resolve_delayed_variance_obligations(zend_class_entry *ce);
 
-static void check_variance_obligation(const variance_obligation *obligation) {
+static void check_variance_obligation(zend_class_entry *ce, const variance_obligation *obligation) {
 	if (obligation->type == OBLIGATION_DEPENDENCY) {
 		zend_class_entry *dependency_ce = obligation->dependency_ce;
 		if (dependency_ce->ce_flags & ZEND_ACC_UNRESOLVED_VARIANCE) {
@@ -3220,7 +4970,7 @@ static void check_variance_obligation(const variance_obligation *obligation) {
 	} else if (obligation->type == OBLIGATION_COMPATIBILITY) {
 		inheritance_status status = zend_do_perform_implementation_check(
 			&obligation->child_fn, obligation->child_scope,
-			&obligation->parent_fn, obligation->parent_scope);
+			&obligation->parent_fn, obligation->parent_scope, ce);
 		if (UNEXPECTED(status != INHERITANCE_SUCCESS)) {
 			emit_incompatible_method_error(
 				&obligation->child_fn, obligation->child_scope,
@@ -3283,7 +5033,7 @@ static void resolve_delayed_variance_obligations(zend_class_entry *ce) {
 
 	variance_obligation *obligation;
 	ZEND_HASH_FOREACH_PTR(obligations, obligation) {
-		check_variance_obligation(obligation);
+		check_variance_obligation(ce, obligation);
 	} ZEND_HASH_FOREACH_END();
 
 	zend_inheritance_check_override(ce);
@@ -3299,7 +5049,7 @@ static void check_unrecoverable_load_failure(const zend_class_entry *ce) {
 	 * a dependence on the inheritance hierarchy of this specific class. Instead we fall back to
 	 * a fatal error, as would happen if we did not allow exceptions in the first place. */
 	if (CG(unlinked_uses)
-			&& zend_hash_index_del(CG(unlinked_uses), (zend_long)(uintptr_t)ce) == SUCCESS) {
+			&& zend_hash_index_del(CG(unlinked_uses), (zend_ulong)(uintptr_t)ce) == SUCCESS) {
 		zend_exception_uncaught_error(
 			"During inheritance of %s with variance dependencies", ZSTR_VAL(ce->name));
 	}
@@ -3464,127 +5214,1163 @@ static zend_class_entry *zend_lazy_class_load(const zend_class_entry *pce)
 		} while (0)
 #endif
 
-ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_name, const zend_string *key) /* {{{ */
+static void zend_check_generic_link_arity(
+		const zend_class_entry *target_ce,
+		uint32_t arity,
+		const char *clause,
+		zend_string *child_name)
 {
-	/* Load parent/interface dependencies first, so we can still gracefully abort linking
-	 * with an exception and remove the class from the class table. This is only possible
-	 * if no variance obligations on the current class have been added during autoloading. */
-	zend_class_entry *parent = NULL;
-	zend_class_entry **traits_and_interfaces = NULL;
-	zend_class_entry *proto = NULL;
-	zend_class_entry *orig_linking_class;
-	uint32_t is_cacheable = ce->ce_flags & ZEND_ACC_IMMUTABLE;
-	uint32_t i, j;
-	zval *zv;
-	ALLOCA_FLAG(use_heap)
-
-	SET_ALLOCA_FLAG(use_heap);
-	ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
-
-	if (ce->parent_name) {
-		parent = zend_fetch_class_by_name(
-			ce->parent_name, lc_parent_name,
-			ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION);
-		if (!parent) {
-			check_unrecoverable_load_failure(ce);
-			return NULL;
+	uint32_t total = target_ce->generic_parameters ? target_ce->generic_parameters->count : 0;
+	uint32_t required = 0;
+	if (target_ce->generic_parameters) {
+		while (required < total
+				&& !ZEND_TYPE_IS_SET(target_ce->generic_parameters->parameters[required].default_type)) {
+			required++;
 		}
-		UPDATE_IS_CACHEABLE(parent);
 	}
 
-	if (ce->num_traits || ce->num_interfaces) {
-		traits_and_interfaces = do_alloca(sizeof(zend_class_entry*) * (ce->num_traits + ce->num_interfaces), use_heap);
+	if (arity > total) {
+		zend_error_noreturn(E_COMPILE_ERROR,
+			"Too many generic type arguments to %s %s in %s, %u passed and %s %u expected",
+			clause, ZSTR_VAL(target_ce->name), ZSTR_VAL(child_name), arity,
+			required == total ? "exactly" : "at most", total);
+	}
 
-		for (i = 0; i < ce->num_traits; i++) {
-			zend_class_entry *trait = zend_fetch_class_by_name(ce->trait_names[i].name,
-				ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT | ZEND_FETCH_CLASS_EXCEPTION);
-			if (UNEXPECTED(trait == NULL)) {
-				free_alloca(traits_and_interfaces, use_heap);
-				return NULL;
-			}
-			if (UNEXPECTED(!(trait->ce_flags & ZEND_ACC_TRAIT))) {
-				zend_throw_error(NULL, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name));
-				free_alloca(traits_and_interfaces, use_heap);
-				return NULL;
-			}
-			for (j = 0; j < i; j++) {
-				if (traits_and_interfaces[j] == trait) {
-					/* skip duplications */
-					trait = NULL;
-					break;
-				}
-			}
-			traits_and_interfaces[i] = trait;
-			if (trait) {
-				UPDATE_IS_CACHEABLE(trait);
-			}
-		}
+	if (arity < required) {
+		zend_error_noreturn(E_COMPILE_ERROR,
+			"Too few generic type arguments to %s %s in %s, %u passed and %s %u expected",
+			clause, ZSTR_VAL(target_ce->name), ZSTR_VAL(child_name), arity,
+			required == total ? "exactly" : "at least", required);
 	}
+}
 
-	if (ce->num_interfaces) {
-		for (i = 0; i < ce->num_interfaces; i++) {
-			zend_class_entry *iface = zend_fetch_class_by_name(
-				ce->interface_names[i].name, ce->interface_names[i].lc_name,
-				ZEND_FETCH_CLASS_INTERFACE |
-				ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION);
-			if (!iface) {
-				check_unrecoverable_load_failure(ce);
-				free_alloca(traits_and_interfaces, use_heap);
-				return NULL;
-			}
-			traits_and_interfaces[ce->num_traits + i] = iface;
-			if (iface) {
-				UPDATE_IS_CACHEABLE(iface);
-			}
-		}
+static const zend_type *zend_lookup_inheritance_args(const HashTable *side_table, zend_ulong idx)
+{
+	if (!side_table) {
+		return NULL;
 	}
 
-#ifndef ZEND_WIN32
-	if (ce->ce_flags & ZEND_ACC_ENUM) {
-		/* We will add internal methods. */
-		is_cacheable = false;
+	zval *zv = zend_hash_index_find(side_table, idx);
+	if (!zv) {
+		return NULL;
 	}
-#endif
 
-	bool orig_record_errors = EG(record_errors);
+	const zend_type *boxed = (const zend_type *) Z_PTR_P(zv);
+	if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) {
+		return NULL;
+	}
 
-	if (ce->ce_flags & ZEND_ACC_IMMUTABLE && is_cacheable) {
-		if (zend_inheritance_cache_get && zend_inheritance_cache_add) {
-			zend_class_entry *ret = zend_inheritance_cache_get(ce, parent, traits_and_interfaces);
-			if (ret) {
-				if (traits_and_interfaces) {
-					free_alloca(traits_and_interfaces, use_heap);
-				}
-				zv = zend_hash_find_known_hash(CG(class_table), key);
-				Z_CE_P(zv) = ret;
-				return ret;
-			}
+	return boxed;
+}
 
-			/* Make sure warnings (such as deprecations) thrown during inheritance
-			 * will be recorded in the inheritance cache. */
-			zend_begin_record_errors();
-		} else {
-			is_cacheable = 0;
-		}
-		proto = ce;
+typedef enum _zend_variance_polarity {
+	ZEND_VAR_POL_COVARIANT,
+	ZEND_VAR_POL_CONTRAVARIANT,
+	ZEND_VAR_POL_INVARIANT,
+} zend_variance_polarity;
+
+static zend_variance_polarity zend_variance_compose(
+		zend_variance_polarity outer, zend_variance_polarity slot)
+{
+	if (outer == ZEND_VAR_POL_INVARIANT || slot == ZEND_VAR_POL_INVARIANT) {
+		return ZEND_VAR_POL_INVARIANT;
 	}
+	return (outer == slot) ? ZEND_VAR_POL_COVARIANT : ZEND_VAR_POL_CONTRAVARIANT;
+}
 
-	zend_try {
-		if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
-			/* Lazy class loading */
-			ce = zend_lazy_class_load(ce);
-			zv = zend_hash_find_known_hash(CG(class_table), key);
-			Z_CE_P(zv) = ce;
-		} else if (ce->ce_flags & ZEND_ACC_FILE_CACHED) {
-			/* Lazy class loading */
-			ce = zend_lazy_class_load(ce);
+static zend_variance_polarity zend_variance_polarity_from(zend_generic_variance v)
+{
+	switch (v) {
+		case ZEND_GENERIC_VARIANCE_COVARIANT:     return ZEND_VAR_POL_COVARIANT;
+		case ZEND_GENERIC_VARIANCE_CONTRAVARIANT: return ZEND_VAR_POL_CONTRAVARIANT;
+		default:                                  return ZEND_VAR_POL_INVARIANT;
+	}
+}
+
+static const char *zend_variance_polarity_name(zend_variance_polarity p)
+{
+	switch (p) {
+		case ZEND_VAR_POL_COVARIANT:     return "covariant";
+		case ZEND_VAR_POL_CONTRAVARIANT: return "contravariant";
+		default:                         return "invariant";
+	}
+}
+
+static const char *zend_variance_marker(zend_generic_variance v)
+{
+	switch (v) {
+		case ZEND_GENERIC_VARIANCE_COVARIANT:     return "+";
+		case ZEND_GENERIC_VARIANCE_CONTRAVARIANT: return "-";
+		default:                                  return "";
+	}
+}
+
+static bool zend_variance_compatible(
+		zend_generic_variance declared, zend_variance_polarity at)
+{
+	if (declared == ZEND_GENERIC_VARIANCE_INVARIANT) {
+		return true;
+	}
+
+	if (at == ZEND_VAR_POL_INVARIANT) {
+		return false;
+	}
+
+	return zend_variance_polarity_from(declared) == at;
+}
+
+static void zend_variance_walk(
+		const zend_generic_parameter_list *class_params,
+		const zend_generic_parameter_list *func_params,
+		zend_type t,
+		zend_variance_polarity pol)
+{
+	if (ZEND_TYPE_HAS_TYPE_PARAMETER(t)) {
+		const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(t);
+		const zend_generic_parameter_list *params =
+			(ref->origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE) ? class_params : func_params;
+		if (!params) {
+			return;
+		}
+
+		ZEND_ASSERT(ref->index < params->count);
+		zend_generic_variance declared = params->parameters[ref->index].variance;
+		if (!zend_variance_compatible(declared, pol)) {
+			zend_error_noreturn(E_COMPILE_ERROR,
+				"Type parameter %s declared %s (%sT) cannot appear in %s position",
+				ZSTR_VAL(ref->name),
+				zend_variance_polarity_name(zend_variance_polarity_from(declared)),
+				zend_variance_marker(declared),
+				zend_variance_polarity_name(pol));
+		}
+
+		return;
+	}
+
+	if (ZEND_TYPE_HAS_LIST(t)) {
+		const zend_type_list *list = ZEND_TYPE_LIST(t);
+		for (uint32_t i = 0; i < list->num_types; i++) {
+			zend_variance_walk(class_params, func_params, list->types[i], pol);
+		}
+
+		return;
+	}
+
+	if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(t)) {
+		const zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(t);
+		zend_class_entry *target = NULL;
+		if (named->name) {
+			zend_class_entry *active = CG(active_class_entry);
+			if (active) {
+				if (zend_string_equals_literal_ci(named->name, "self")
+						|| zend_string_equals_literal_ci(named->name, "static")
+						|| (active->name && zend_string_equals_ci(named->name, active->name))) {
+					target = active;
+				} else if (zend_string_equals_literal_ci(named->name, "parent")) {
+					if (active->ce_flags & ZEND_ACC_RESOLVED_PARENT) {
+						target = active->parent;
+					} else if (active->parent_name) {
+						target = zend_lookup_class_ex(active->parent_name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
+					}
+				}
+			}
+
+			if (!target) {
+				target = zend_lookup_class_ex(named->name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);
+			}
+		}
+
+		if (!target || !target->generic_parameters) {
+			return;
+		}
+
+		for (uint32_t i = 0; i < named->count; i++) {
+			zend_variance_polarity slot = i < target->generic_parameters->count
+				? zend_variance_polarity_from(target->generic_parameters->parameters[i].variance)
+				: ZEND_VAR_POL_INVARIANT;
+
+			zend_variance_walk(class_params, func_params, named->args[i], zend_variance_compose(pol, slot));
+		}
+
+		return;
+	}
+}
+
+static void zend_variance_walk_function(
+		const zend_generic_parameter_list *class_params,
+		const zend_generic_parameter_list *func_params,
+		const zend_op_array *op_array)
+{
+	if (!op_array->generic_types && !op_array->generic_parameters) {
+		return;
+	}
+
+	if (op_array->generic_types) {
+		if (op_array->generic_types->parameters) {
+			zval *zv;
+			zend_ulong h;
+			ZEND_HASH_FOREACH_NUM_KEY_VAL(op_array->generic_types->parameters, h, zv) {
+				const zend_type *t = (const zend_type *) Z_PTR_P(zv);
+				zend_variance_walk(class_params, func_params, *t, ZEND_VAR_POL_CONTRAVARIANT);
+			} ZEND_HASH_FOREACH_END();
+			(void) h;
+		}
+
+		if (op_array->generic_types->return_type) {
+			zend_variance_walk(class_params, func_params, *op_array->generic_types->return_type, ZEND_VAR_POL_COVARIANT);
+		}
+	}
+
+	if (op_array->generic_parameters) {
+		for (uint32_t i = 0; i < op_array->generic_parameters->count; i++) {
+			const zend_generic_parameter *p = &op_array->generic_parameters->parameters[i];
+			if (ZEND_TYPE_IS_SET(p->bound_pre_erasure)) {
+				zend_variance_walk(class_params, func_params, p->bound_pre_erasure, ZEND_VAR_POL_INVARIANT);
+			}
+
+			if (ZEND_TYPE_IS_SET(p->default_pre_erasure)) {
+				zend_variance_walk(class_params, func_params, p->default_pre_erasure, ZEND_VAR_POL_INVARIANT);
+			}
+		}
+	}
+}
+
+static zend_variance_polarity zend_variance_polarity_for_property(const zend_property_info *prop)
+{
+	if (prop->hooks) {
+		const zend_function *get = prop->hooks[ZEND_PROPERTY_HOOK_GET];
+		const zend_function *set = prop->hooks[ZEND_PROPERTY_HOOK_SET];
+		bool by_ref_get = get && (get->common.fn_flags & ZEND_ACC_RETURN_REFERENCE);
+		if (by_ref_get || (get && set)) {
+			return ZEND_VAR_POL_INVARIANT;
+		}
+
+		if (get) {
+			return ZEND_VAR_POL_COVARIANT;
+		}
+
+		if (set) {
+			return ZEND_VAR_POL_CONTRAVARIANT;
+		}
+
+		return ZEND_VAR_POL_INVARIANT;
+	}
+
+	if (prop->flags & ZEND_ACC_READONLY) {
+		return ZEND_VAR_POL_COVARIANT;
+	}
+
+	return ZEND_VAR_POL_INVARIANT;
+}
+
+void zend_check_generic_variance_markers(zend_class_entry *ce)
+{
+	if (!ce->generic_parameters) {
+		return;
+	}
+
+	bool any_marked = false;
+	for (uint32_t i = 0; i < ce->generic_parameters->count; i++) {
+		if (ce->generic_parameters->parameters[i].variance != ZEND_GENERIC_VARIANCE_INVARIANT) {
+			any_marked = true;
+			break;
+		}
+	}
+
+	if (!any_marked) {
+		return;
+	}
+
+	const zend_generic_parameter_list *class_params = ce->generic_parameters;
+	uint32_t orig_lineno = CG(zend_lineno);
+
+	for (uint32_t i = 0; i < class_params->count; i++) {
+		const zend_generic_parameter *p = &class_params->parameters[i];
+		if (ZEND_TYPE_IS_SET(p->bound_pre_erasure)) {
+			zend_variance_walk(class_params, NULL, p->bound_pre_erasure, ZEND_VAR_POL_INVARIANT);
+		}
+
+		if (ZEND_TYPE_IS_SET(p->default_pre_erasure)) {
+			zend_variance_walk(class_params, NULL, p->default_pre_erasure, ZEND_VAR_POL_INVARIANT);
+		}
+	}
+
+	zend_function *fn;
+	ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
+		if (fn->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_CTOR)) {
+			continue;
+		}
+
+		if (fn->common.scope != ce) {
+			continue;
+		}
+
+		if (!ZEND_USER_CODE(fn->common.type)) {
+			continue;
+		}
+
+		CG(zend_lineno) = fn->op_array.line_start;
+		zend_variance_walk_function(class_params, NULL, &fn->op_array);
+	} ZEND_HASH_FOREACH_END();
+	CG(zend_lineno) = orig_lineno;
+
+	if (ce->generic_types && ce->generic_types->properties) {
+		zend_property_info *prop_info;
+		ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
+			if (prop_info->ce != ce) {
+				continue;
+			}
+
+			zend_variance_polarity prop_pol = zend_variance_polarity_for_property(prop_info);
+			zval *pre_zv = zend_hash_find(ce->generic_types->properties, prop_info->name);
+			if (pre_zv) {
+				const zend_type *pre = (const zend_type *) Z_PTR_P(pre_zv);
+				zend_variance_walk(class_params, NULL, *pre, prop_pol);
+			}
+
+			if (prop_info->hooks) {
+				for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
+					zend_function *hook = prop_info->hooks[i];
+					if (hook && ZEND_USER_CODE(hook->common.type)) {
+						CG(zend_lineno) = hook->op_array.line_start;
+						zend_variance_walk_function(class_params, NULL, &hook->op_array);
+					}
+				}
+
+				CG(zend_lineno) = orig_lineno;
+			}
+		} ZEND_HASH_FOREACH_END();
+	}
+
+	if (ce->generic_types) {
+		if (ce->generic_types->extends) {
+			zend_variance_walk(class_params, NULL, *ce->generic_types->extends, ZEND_VAR_POL_COVARIANT);
+		}
+
+		if (ce->generic_types->implements) {
+			zval *zv;
+			ZEND_HASH_FOREACH_VAL(ce->generic_types->implements, zv) {
+				zend_variance_walk(class_params, NULL, *(const zend_type *) Z_PTR_P(zv), ZEND_VAR_POL_COVARIANT);
+			} ZEND_HASH_FOREACH_END();
+		}
+
+		if (ce->generic_types->trait_uses) {
+			zval *zv;
+			ZEND_HASH_FOREACH_VAL(ce->generic_types->trait_uses, zv) {
+				zend_variance_walk(class_params, NULL, *(const zend_type *) Z_PTR_P(zv), ZEND_VAR_POL_COVARIANT);
+			} ZEND_HASH_FOREACH_END();
+		}
+	}
+}
+
+void zend_check_function_variance_markers(zend_op_array *op_array)
+{
+	if (!op_array->generic_parameters) {
+		return;
+	}
+
+	bool any_marked = false;
+	for (uint32_t i = 0; i < op_array->generic_parameters->count; i++) {
+		if (op_array->generic_parameters->parameters[i].variance != ZEND_GENERIC_VARIANCE_INVARIANT) {
+			any_marked = true;
+			break;
+		}
+	}
+
+	if (!any_marked) {
+		return;
+	}
+
+	zend_variance_walk_function(NULL, op_array->generic_parameters, op_array);
+}
+
+static void zend_check_generic_link_bounds(
+		zend_class_entry *target_ce,
+		const zend_type *args_box,
+		const char *clause,
+		zend_class_entry *ce)
+{
+	if (!args_box || !target_ce->generic_parameters) {
+		return;
+	}
+
+	const zend_type_named_with_args *args = ZEND_TYPE_NAMED_WITH_ARGS(*args_box);
+	uint32_t check_count = args->count;
+	if (check_count > target_ce->generic_parameters->count) {
+		check_count = target_ce->generic_parameters->count;
+	}
+
+	for (uint32_t i = 0; i < check_count; i++) {
+		zend_type bound = target_ce->generic_parameters->parameters[i].bound;
+		if (!ZEND_TYPE_IS_SET(bound)) {
+			continue;
+		}
+
+		zend_type arg = args->args[i];
+		zend_type effective = arg;
+		bool ce_bound_unset = false;
+
+		if (ZEND_TYPE_HAS_TYPE_PARAMETER(arg)) {
+			const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(arg);
+			if (ref->origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE
+					&& ce->generic_parameters
+					&& ref->index < ce->generic_parameters->count) {
+				zend_type ce_bound = ce->generic_parameters->parameters[ref->index].bound;
+				if (ZEND_TYPE_IS_SET(ce_bound)) {
+					effective = ce_bound;
+				} else {
+					ce_bound_unset = true;
+				}
+			}
+		}
+
+		if (ce_bound_unset || zend_check_generic_arg_satisfies_bound(ce, effective, target_ce, bound) != INHERITANCE_SUCCESS) {
+			zend_type bound_display = ZEND_TYPE_IS_SET(target_ce->generic_parameters->parameters[i].bound_pre_erasure)
+				? target_ce->generic_parameters->parameters[i].bound_pre_erasure
+				: bound;
+			zend_string *bound_str = zend_type_to_string(bound_display);
+			zend_string *arg_str;
+			if (ZEND_TYPE_HAS_TYPE_PARAMETER(arg)) {
+				const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(arg);
+				arg_str = ref->name ? zend_string_copy(ref->name) : zend_string_init("T", 1, 0);
+			} else {
+				arg_str = zend_type_to_string(arg);
+			}
+
+			const char *param_name =
+				target_ce->generic_parameters->parameters[i].name
+					? ZSTR_VAL(target_ce->generic_parameters->parameters[i].name)
+					: "?";
+			zend_error_noreturn(E_COMPILE_ERROR,
+				"Type argument %u to %s %s in %s does not satisfy the bound %s on parameter %s, %s given",
+				i + 1, clause, ZSTR_VAL(target_ce->name), ZSTR_VAL(ce->name),
+				ZSTR_VAL(bound_str), param_name, ZSTR_VAL(arg_str));
+			zend_string_release(bound_str);
+			zend_string_release(arg_str);
+		}
+	}
+}
+
+static uint32_t zend_lookup_inheritance_arity(const HashTable *side_table, zend_ulong idx)
+{
+	if (!side_table) {
+		return 0;
+	}
+
+	zval *zv = zend_hash_index_find(side_table, idx);
+	if (!zv) {
+		return 0;
+	}
+
+	zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+	if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) {
+		return 0;
+	}
+
+	return ZEND_TYPE_NAMED_WITH_ARGS(*boxed)->count;
+}
+
+static bool zend_diamond_types_equal(zend_type a, zend_type b)
+{
+	if (ZEND_TYPE_PURE_MASK(a) != ZEND_TYPE_PURE_MASK(b)) {
+		return false;
+	}
+
+	if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(a)) {
+		if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(b)) {
+			return false;
+		}
+		const zend_type_named_with_args *na = ZEND_TYPE_NAMED_WITH_ARGS(a);
+		const zend_type_named_with_args *nb = ZEND_TYPE_NAMED_WITH_ARGS(b);
+		if (na->count != nb->count) {
+			return false;
+		}
+
+		if ((na->name == NULL) != (nb->name == NULL)) {
+			return false;
+		}
+
+		if (na->name && !zend_string_equals_ci(na->name, nb->name)) {
+			return false;
+		}
+
+		for (uint32_t i = 0; i < na->count; i++) {
+			if (!zend_diamond_types_equal(na->args[i], nb->args[i])) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	if (ZEND_TYPE_HAS_LIST(a)) {
+		if (!ZEND_TYPE_HAS_LIST(b)) {
+			return false;
+		}
+
+		const zend_type_list *la = ZEND_TYPE_LIST(a);
+		const zend_type_list *lb = ZEND_TYPE_LIST(b);
+		if (la->num_types != lb->num_types) {
+			return false;
+		}
+
+		for (uint32_t i = 0; i < la->num_types; i++) {
+			if (!zend_diamond_types_equal(la->types[i], lb->types[i])) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	if (ZEND_TYPE_HAS_NAME(a)) {
+		if (!ZEND_TYPE_HAS_NAME(b)) {
+			return false;
+		}
+
+		return zend_string_equals_ci(ZEND_TYPE_NAME(a), ZEND_TYPE_NAME(b));
+	}
+
+	if (ZEND_TYPE_HAS_TYPE_PARAMETER(a)) {
+		if (!ZEND_TYPE_HAS_TYPE_PARAMETER(b)) {
+			return false;
+		}
+
+		const zend_type_parameter_ref *ra = ZEND_TYPE_TYPE_PARAMETER(a);
+		const zend_type_parameter_ref *rb = ZEND_TYPE_TYPE_PARAMETER(b);
+		return ra->origin == rb->origin && ra->index == rb->index;
+	}
+
+	return true;
+}
+
+typedef struct {
+	uint32_t arity;
+	zend_string *first_source_name;
+	zend_type args[1];
+} zend_diamond_record;
+
+#define ZEND_DIAMOND_RECORD_SIZE(arity) \
+	(offsetof(zend_diamond_record, args) + sizeof(zend_type) * (arity))
+
+static zend_string *zend_diamond_format_args(const zend_type *args, uint32_t arity)
+{
+	smart_str buf = {0};
+	smart_str_appendc(&buf, '<');
+	for (uint32_t j = 0; j < arity; j++) {
+		if (j > 0) smart_str_appends(&buf, ", ");
+		if (ZEND_TYPE_HAS_TYPE_PARAMETER(args[j])) {
+			const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(args[j]);
+			smart_str_append(&buf, ref->name ? ref->name : ZSTR_KNOWN(ZEND_STR_MIXED));
+		} else {
+			zend_string *piece = zend_type_to_string(args[j]);
+			if (piece) {
+				smart_str_append(&buf, piece);
+				zend_string_release(piece);
+			} else {
+				smart_str_appendc(&buf, '?');
+			}
+		}
+	}
+
+	smart_str_appendc(&buf, '>');
+	smart_str_0(&buf);
+	return buf.s;
+}
+
+static void zend_diamond_record_dtor(zval *zv)
+{
+	efree(Z_PTR_P(zv));
+}
+
+static void zend_diamond_record_or_check(
+		zend_class_entry *ce,
+		zend_class_entry *target,
+		const zend_type *args, uint32_t arity,
+		zend_string *source_name,
+		HashTable *records)
+{
+	zend_ulong key = (zend_ulong)(uintptr_t) target;
+	zend_diamond_record *prior = zend_hash_index_find_ptr(records, key);
+	if (prior) {
+		if (prior->arity == arity) {
+			return;
+		}
+
+		zend_string *first_args = zend_diamond_format_args(prior->args, prior->arity);
+		zend_string *next_args = zend_diamond_format_args(args, arity);
+		zend_error_noreturn(E_COMPILE_ERROR,
+			"%s inherits %s%s via %s and %s%s via %s",
+			ZSTR_VAL(ce->name),
+			ZSTR_VAL(target->name), ZSTR_VAL(first_args), ZSTR_VAL(prior->first_source_name),
+			ZSTR_VAL(target->name), ZSTR_VAL(next_args), ZSTR_VAL(source_name));
+	}
+
+	zend_diamond_record *record = emalloc(ZEND_DIAMOND_RECORD_SIZE(arity));
+	record->arity = arity;
+	record->first_source_name = source_name;
+	for (uint32_t j = 0; j < arity; j++) {
+		record->args[j] = args[j];
+	}
+
+	zend_hash_index_add_new_ptr(records, key, record);
+}
+
+static const zend_type_named_with_args *zend_get_extends_binding(const zend_class_entry *ce)
+{
+	if (!ce->generic_types || !ce->generic_types->extends) return NULL;
+	if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)) return NULL;
+	return ZEND_TYPE_NAMED_WITH_ARGS(*ce->generic_types->extends);
+}
+
+static const zend_type_named_with_args *zend_get_implements_binding(const zend_class_entry *ce, uint32_t idx)
+{
+	if (!ce->generic_types || !ce->generic_types->implements) return NULL;
+	zval *zv = zend_hash_index_find(ce->generic_types->implements, idx);
+	if (!zv) return NULL;
+	zend_type *boxed = (zend_type *) Z_PTR_P(zv);
+	if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) return NULL;
+	return ZEND_TYPE_NAMED_WITH_ARGS(*boxed);
+}
+
+static void zend_diamond_collect_via_provider(
+		zend_class_entry *ce,
+		zend_class_entry *provider,
+		const zend_type *ce_to_provider,
+		uint32_t ce_to_provider_arity,
+		zend_string *source_name,
+		HashTable *records)
+{
+	if (!provider) return;
+
+	if (provider->generic_parameters && ce_to_provider) {
+		zend_diamond_record_or_check(ce, provider, ce_to_provider, ce_to_provider_arity,
+			source_name, records);
+	}
+
+	for (uint32_t i = 0; i < provider->num_interfaces; i++) {
+		zend_class_entry *target = provider->interfaces[i];
+		if (!target || !target->generic_parameters) continue;
+
+		uint32_t cap = target->generic_parameters->count;
+		if (cap == 0) continue;
+		ALLOCA_FLAG(use_heap)
+		zend_type *via = (zend_type *) do_alloca(sizeof(zend_type) * cap, use_heap);
+		uint32_t via_arity;
+		if (!zend_get_inheritance_binding_full_cached(provider, target, via, cap, &via_arity)) {
+			free_alloca(via, use_heap);
+			continue;
+		}
+
+		if (ce_to_provider) {
+			for (uint32_t j = 0; j < via_arity; j++) {
+				via[j] = zend_substitute_leaf_type_param(via[j], ce_to_provider, ce_to_provider_arity);
+			}
+		}
+
+		zend_diamond_record_or_check(ce, target, via, via_arity,
+			source_name, records);
+		free_alloca(via, use_heap);
+	}
+}
+
+static void zend_validate_generic_diamond_bindings(
+		zend_class_entry *ce,
+		zend_class_entry *parent_ce,
+		zend_class_entry **traits_and_interfaces)
+{
+	if (!parent_ce && (!traits_and_interfaces || ce->num_interfaces == 0)) return;
+
+	HashTable records;
+	zend_hash_init(&records, 8, NULL, zend_diamond_record_dtor, /* persistent */ 0);
+
+	if (parent_ce) {
+		const zend_type_named_with_args *binding = zend_get_extends_binding(ce);
+		zend_diamond_collect_via_provider(ce, parent_ce,
+			binding ? binding->args : NULL,
+			binding ? binding->count : 0,
+			parent_ce->name, &records);
+	}
+
+	if (traits_and_interfaces) {
+		for (uint32_t i = 0; i < ce->num_interfaces; i++) {
+			zend_class_entry *DI = traits_and_interfaces[ce->num_traits + i];
+			if (!DI) continue;
+			const zend_type_named_with_args *binding = zend_get_implements_binding(ce, i);
+			zend_diamond_collect_via_provider(ce, DI,
+				binding ? binding->args : NULL,
+				binding ? binding->count : 0,
+				DI->name, &records);
+		}
+	}
+
+	zend_hash_destroy(&records);
+}
+
+static void zend_validate_generic_inheritance_arities(
+		zend_class_entry *ce,
+		zend_class_entry *parent_ce,
+		zend_class_entry **traits_and_interfaces)
+{
+	if (!traits_and_interfaces && !parent_ce) {
+		return;
+	}
+
+	zend_validate_generic_diamond_bindings(ce, parent_ce, traits_and_interfaces);
+	if (!traits_and_interfaces) {
+		return;
+	}
+
+	const HashTable *trait_uses_table = ce->generic_types ? ce->generic_types->trait_uses : NULL;
+	for (uint32_t i = 0; i < ce->num_traits; i++) {
+		zend_class_entry *trait_ce = traits_and_interfaces[i];
+		if (!trait_ce) continue;
+		/* Skip when the resolved trait is a synthesized monomorph — its args
+		 * were already validated against the base trait's bounds at synthesis
+		 * time and the side-table args are pre-rewrite (refer to the base). */
+		if (zend_class_is_monomorph(trait_ce)) {
+			continue;
+		}
+		uint32_t arity = zend_lookup_inheritance_arity(trait_uses_table, i);
+		if (arity > 0 || trait_ce->generic_parameters) {
+			zend_check_generic_link_arity(trait_ce, arity, "use", ce->name);
+		}
+
+		zend_check_generic_link_bounds(trait_ce, zend_lookup_inheritance_args(trait_uses_table, i), "use", ce);
+	}
+
+	const HashTable *implements_table = ce->generic_types ? ce->generic_types->implements : NULL;
+	const char *clause = (ce->ce_flags & ZEND_ACC_INTERFACE) ? "extends" : "implements";
+	for (uint32_t i = 0; i < ce->num_interfaces; i++) {
+		zend_class_entry *iface_ce = traits_and_interfaces[ce->num_traits + i];
+		if (!iface_ce) continue;
+		/* Same monomorph-skip as the trait loop above. */
+		if (zend_class_is_monomorph(iface_ce)) {
+			continue;
+		}
+		uint32_t arity = zend_lookup_inheritance_arity(implements_table, i);
+		if (arity > 0 || iface_ce->generic_parameters) {
+			zend_check_generic_link_arity(iface_ce, arity, clause, ce->name);
+		}
+
+		zend_check_generic_link_bounds(iface_ce, zend_lookup_inheritance_args(implements_table, i), clause, ce);
+	}
+}
+
+/* Mark entries in `names` that share an lc_name with another entry — the
+ * diamond-of-same-base case for `implements Sink, Sink` and
+ * `use Box, Box`. The marked indices fall back to the bare-base
+ * + side-table inheritance path so the existing diamond-merge machinery in
+ * `do_inherit_method` can compute the merged signature. Skipped entirely when
+ * count <= 1 (the common case). */
+static void zend_mark_duplicate_lc_names(
+		const zend_class_name *names, uint32_t count, bool *out)
+{
+	if (count <= 1) {
+		memset(out, 0, sizeof(bool) * count);
+		return;
+	}
+	memset(out, 0, sizeof(bool) * count);
+	for (uint32_t a = 0; a < count; a++) {
+		for (uint32_t b = a + 1; b < count; b++) {
+			if (zend_string_equals(names[a].lc_name, names[b].lc_name)) {
+				out[a] = true;
+				out[b] = true;
+			}
+		}
+	}
+}
+
+ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_name, const zend_string *key) /* {{{ */
+{
+	/* Load parent/interface dependencies first, so we can still gracefully abort linking
+	 * with an exception and remove the class from the class table. This is only possible
+	 * if no variance obligations on the current class have been added during autoloading. */
+	zend_class_entry *parent = NULL;
+	zend_class_entry **traits_and_interfaces = NULL;
+	zend_class_entry *proto = NULL;
+	zend_class_entry *orig_linking_class;
+	uint32_t is_cacheable = ce->ce_flags & ZEND_ACC_IMMUTABLE;
+	uint32_t i, j;
+	zval *zv;
+	zend_string *synthesized_lc_parent = NULL;
+	zend_class_entry *cache_key_proto = NULL;
+	ALLOCA_FLAG(use_heap)
+
+	SET_ALLOCA_FLAG(use_heap);
+	ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
+
+	/* When this link will rewrite ce->parent_name or ce->interface_names
+	 * during monomorph synthesis (extends/implements/use with concrete
+	 * generic args), the writes happen below — but ce may live in read-only
+	 * opcache SHM under opcache.protect_memory=1. Lazy-load the mutable copy
+	 * now and remember the immutable pointer so the inheritance cache lookup
+	 * further down still keys against the same proto opcache stored under.
+	 * Limited to classes that actually carry a generic side-table so we don't
+	 * pay the copy cost on every link. */
+	if ((ce->ce_flags & ZEND_ACC_IMMUTABLE)
+			&& ce->generic_types
+			&& (ce->generic_types->extends
+				|| ce->generic_types->implements
+				|| ce->generic_types->trait_uses)) {
+		cache_key_proto = ce;
+		ce = zend_lazy_class_load(ce);
+		zv = zend_hash_find_known_hash(CG(class_table), key);
+		Z_CE_P(zv) = ce;
+		/* zend_lazy_class_load deep-copies properties/methods/etc. but the
+		 * interface_names/trait_names arrays themselves still point into the
+		 * immutable SHM. Monomorph synthesis below rewrites entries in
+		 * those arrays, so detach them into emalloc'd copies first. The
+		 * name strings are interned, so addref/release stays a no-op. */
+		if (ce->num_interfaces) {
+			zend_class_name *src = ce->interface_names;
+			ce->interface_names = emalloc(sizeof(zend_class_name) * ce->num_interfaces);
+			memcpy(ce->interface_names, src, sizeof(zend_class_name) * ce->num_interfaces);
+			for (uint32_t k = 0; k < ce->num_interfaces; k++) {
+				zend_string_addref(ce->interface_names[k].name);
+				zend_string_addref(ce->interface_names[k].lc_name);
+			}
+		}
+		if (ce->num_traits) {
+			zend_class_name *src = ce->trait_names;
+			ce->trait_names = emalloc(sizeof(zend_class_name) * ce->num_traits);
+			memcpy(ce->trait_names, src, sizeof(zend_class_name) * ce->num_traits);
+			for (uint32_t k = 0; k < ce->num_traits; k++) {
+				zend_string_addref(ce->trait_names[k].name);
+				zend_string_addref(ce->trait_names[k].lc_name);
+			}
+		}
+	}
+
+	/* Bound-erased generics, extends-with-args: when this class declared
+	 * `extends Box`, its compile-time side table holds the pre-erasure
+	 * `Box` payload while `parent_name` is the bare base name. Before
+	 * touching anything else, synthesize the `Box` monomorph as a
+	 * fully separate top-level link and rewrite `parent_name` to the
+	 * canonical name. That makes this class's direct parent be the
+	 * monomorph entry, so `$this instanceof Box` holds and inherited
+	 * substituted member types come through the normal inheritance
+	 * pipeline. Doing it here (rather than inline during compile) keeps
+	 * the synthesizer's recursive link sequential — it completes before
+	 * we begin linking ce, which is what fixes the property-hook
+	 * corruption seen in the earlier inline attempt.
+	 *
+	 * Skip when ce is itself a synthesized monomorph (its name carries `<`,
+	 * which is invalid in user class names) — in that case the side-table
+	 * extends entry exists for substitution, not for redirection. */
+	if (ce->parent_name && ce->generic_types && ce->generic_types->extends
+			&& ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)
+			&& !zend_class_is_monomorph(ce)
+			&& !zend_type_contains_type_parameter(*ce->generic_types->extends)) {
+		const zend_type_named_with_args *nwa =
+			ZEND_TYPE_NAMED_WITH_ARGS(*ce->generic_types->extends);
+		zend_class_entry *base = zend_fetch_class_by_name(
+			ce->parent_name, lc_parent_name,
+			ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION);
+		if (!base) {
+			check_unrecoverable_load_failure(ce);
+			return NULL;
+		}
+		if (base->generic_parameters) {
+			/* Validate arity and bounds against the base's parameters first
+			 * (so the user gets the contextual "extends X in Y" error wording
+			 * rather than a generic synthesizer error). */
+			zend_check_generic_link_arity(base, nwa->count, "extends", ce->name);
+			zend_check_generic_link_bounds(base, ce->generic_types->extends,
+				"extends", ce);
+			if (EG(exception)) {
+				check_unrecoverable_load_failure(ce);
+				return NULL;
+			}
+			zend_class_entry *mono = zend_synthesize_monomorph(base, nwa->args, nwa->count);
+			if (!mono) {
+				check_unrecoverable_load_failure(ce);
+				return NULL;
+			}
+			zend_string_release(ce->parent_name);
+			ce->parent_name = zend_string_copy(mono->name);
+			synthesized_lc_parent = zend_string_tolower(mono->name);
+			lc_parent_name = synthesized_lc_parent;
+		}
+	}
+
+	if (ce->parent_name) {
+		parent = zend_fetch_class_by_name(
+			ce->parent_name, lc_parent_name,
+			ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION);
+		if (!parent) {
+			check_unrecoverable_load_failure(ce);
+			if (synthesized_lc_parent) zend_string_release(synthesized_lc_parent);
+			return NULL;
+		}
+		UPDATE_IS_CACHEABLE(parent);
+	}
+	if (synthesized_lc_parent) {
+		zend_string_release(synthesized_lc_parent);
+		synthesized_lc_parent = NULL;
+	}
+
+	if (ce->num_traits || ce->num_interfaces) {
+		traits_and_interfaces = do_alloca(sizeof(zend_class_entry*) * (ce->num_traits + ce->num_interfaces), use_heap);
+
+		const HashTable *trait_uses_table_for_synth =
+			(ce->generic_types && ce->generic_types->trait_uses)
+				? ce->generic_types->trait_uses : NULL;
+		bool ce_is_mono_for_trait = zend_class_is_monomorph(ce);
+		bool *trait_skip_mono = NULL;
+		ALLOCA_FLAG(trait_skip_use_heap)
+		if (trait_uses_table_for_synth && ce->num_traits > 1) {
+			trait_skip_mono = do_alloca(sizeof(bool) * ce->num_traits, trait_skip_use_heap);
+			zend_mark_duplicate_lc_names(ce->trait_names, ce->num_traits, trait_skip_mono);
+		}
+
+		for (i = 0; i < ce->num_traits; i++) {
+			/* Bound-erased generics, trait-use-with-args: if the use clause is
+			 * `use Foo;`, synthesize the Foo mono trait now and
+			 * rewrite trait_names[i] to the canonical name. Skip when ce is
+			 * itself a mono, when args carry a type-parameter ref (still
+			 * symbolic), or when the same base trait is used multiple times
+			 * with different args (diamond fallback). */
+			const zend_type *trait_args = trait_uses_table_for_synth
+				? (const zend_type *) zend_hash_index_find_ptr(trait_uses_table_for_synth, i)
+				: NULL;
+			if (!ce_is_mono_for_trait && trait_args
+					&& ZEND_TYPE_HAS_NAMED_WITH_ARGS(*trait_args)
+					&& !zend_type_contains_type_parameter(*trait_args)
+					&& !(trait_skip_mono && trait_skip_mono[i])) {
+				const zend_type_named_with_args *nwa =
+					ZEND_TYPE_NAMED_WITH_ARGS(*trait_args);
+				zend_class_entry *base_trait = zend_fetch_class_by_name(
+					ce->trait_names[i].name, ce->trait_names[i].lc_name,
+					ZEND_FETCH_CLASS_TRAIT | ZEND_FETCH_CLASS_EXCEPTION);
+				if (UNEXPECTED(base_trait == NULL)) {
+					free_alloca(traits_and_interfaces, use_heap);
+					if (trait_skip_mono) free_alloca(trait_skip_mono, trait_skip_use_heap);
+					return NULL;
+				}
+				if (UNEXPECTED(!(base_trait->ce_flags & ZEND_ACC_TRAIT))) {
+					zend_throw_error(NULL, "%s cannot use %s - it is not a trait",
+						ZSTR_VAL(ce->name), ZSTR_VAL(base_trait->name));
+					free_alloca(traits_and_interfaces, use_heap);
+					if (trait_skip_mono) free_alloca(trait_skip_mono, trait_skip_use_heap);
+					return NULL;
+				}
+				if (base_trait->generic_parameters) {
+					zend_check_generic_link_arity(base_trait, nwa->count, "use", ce->name);
+					zend_check_generic_link_bounds(base_trait, trait_args, "use", ce);
+					if (EG(exception)) {
+						check_unrecoverable_load_failure(ce);
+						free_alloca(traits_and_interfaces, use_heap);
+						if (trait_skip_mono) free_alloca(trait_skip_mono, trait_skip_use_heap);
+						return NULL;
+					}
+					zend_class_entry *mono = zend_synthesize_monomorph(
+						base_trait, nwa->args, nwa->count);
+					if (!mono) {
+						check_unrecoverable_load_failure(ce);
+						free_alloca(traits_and_interfaces, use_heap);
+						if (trait_skip_mono) free_alloca(trait_skip_mono, trait_skip_use_heap);
+						return NULL;
+					}
+					zend_string_release(ce->trait_names[i].name);
+					zend_string_release(ce->trait_names[i].lc_name);
+					ce->trait_names[i].name = zend_string_copy(mono->name);
+					ce->trait_names[i].lc_name = zend_string_tolower(mono->name);
+				}
+			}
+
+			zend_class_entry *trait = zend_fetch_class_by_name(ce->trait_names[i].name,
+				ce->trait_names[i].lc_name, ZEND_FETCH_CLASS_TRAIT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(trait == NULL)) {
+				free_alloca(traits_and_interfaces, use_heap);
+				if (trait_skip_mono) free_alloca(trait_skip_mono, trait_skip_use_heap);
+				return NULL;
+			}
+			if (UNEXPECTED(!(trait->ce_flags & ZEND_ACC_TRAIT))) {
+				zend_throw_error(NULL, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name));
+				free_alloca(traits_and_interfaces, use_heap);
+				if (trait_skip_mono) free_alloca(trait_skip_mono, trait_skip_use_heap);
+				return NULL;
+			}
+			if (UNEXPECTED(trait->ce_flags & ZEND_ACC_DEPRECATED)) {
+				zend_use_of_deprecated_trait(trait, ce->name);
+				if (UNEXPECTED(EG(exception))) {
+					free_alloca(traits_and_interfaces, use_heap);
+					if (trait_skip_mono) free_alloca(trait_skip_mono, trait_skip_use_heap);
+					return NULL;
+				}
+			}
+			for (j = 0; j < i; j++) {
+				if (traits_and_interfaces[j] == trait) {
+					bool keep_for_diamond = false;
+					if (trait->generic_parameters) {
+						const zend_type_named_with_args *prior = zend_get_trait_use_binding_by_index(ce, j);
+						const zend_type_named_with_args *cur = zend_get_trait_use_binding_by_index(ce, i);
+						if (prior && cur
+								&& zend_iface_diamond_bindings_allowed(
+									trait, prior->args, prior->count,
+									cur->args, cur->count)) {
+							keep_for_diamond = true;
+						}
+					}
+
+					if (!keep_for_diamond) {
+						trait = NULL;
+					}
+
+					break;
+				}
+			}
+			traits_and_interfaces[i] = trait;
+			if (trait) {
+				UPDATE_IS_CACHEABLE(trait);
+			}
+		}
+		if (trait_skip_mono) {
+			free_alloca(trait_skip_mono, trait_skip_use_heap);
+		}
+	}
+
+	if (ce->num_interfaces) {
+		const HashTable *impl_table = (ce->generic_types && ce->generic_types->implements)
+			? ce->generic_types->implements : NULL;
+		bool ce_is_mono = zend_class_is_monomorph(ce);
+		bool *skip_mono = NULL;
+		ALLOCA_FLAG(skip_mono_use_heap)
+		if (impl_table && ce->num_interfaces > 1) {
+			skip_mono = do_alloca(sizeof(bool) * ce->num_interfaces, skip_mono_use_heap);
+			zend_mark_duplicate_lc_names(ce->interface_names, ce->num_interfaces, skip_mono);
+		}
+		for (i = 0; i < ce->num_interfaces; i++) {
+			/* Bound-erased generics, implements-with-args: if this interface was
+			 * declared as `implements Iter`, the side-table holds the
+			 * pre-erasure args. Synthesize Iter as a sequential top-level
+			 * link, then rewrite ce->interface_names[i] to the canonical name
+			 * so the existing fetch+inheritance machinery sees the monomorph as
+			 * the implemented interface (and `$obj instanceof Iter`
+			 * resolves correctly via the inheritance chain). Skip when ce is
+			 * itself a monomorph or when args contain a type-parameter ref. */
+			const zend_type *impl_args = impl_table
+				? (const zend_type *) zend_hash_index_find_ptr(impl_table, i)
+				: NULL;
+			if (!ce_is_mono && impl_args && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*impl_args)
+					&& !zend_type_contains_type_parameter(*impl_args)
+					&& !(skip_mono && skip_mono[i])) {
+				const zend_type_named_with_args *nwa =
+					ZEND_TYPE_NAMED_WITH_ARGS(*impl_args);
+				zend_class_entry *base_iface = zend_fetch_class_by_name(
+					ce->interface_names[i].name, ce->interface_names[i].lc_name,
+					ZEND_FETCH_CLASS_INTERFACE | ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED
+						| ZEND_FETCH_CLASS_EXCEPTION);
+				if (!base_iface) {
+					check_unrecoverable_load_failure(ce);
+					free_alloca(traits_and_interfaces, use_heap);
+					return NULL;
+				}
+				if (base_iface->generic_parameters) {
+					const char *clause = (ce->ce_flags & ZEND_ACC_INTERFACE)
+						? "extends" : "implements";
+					zend_check_generic_link_arity(base_iface, nwa->count,
+						clause, ce->name);
+					zend_check_generic_link_bounds(base_iface, impl_args,
+						clause, ce);
+					if (EG(exception)) {
+						check_unrecoverable_load_failure(ce);
+						free_alloca(traits_and_interfaces, use_heap);
+						return NULL;
+					}
+					zend_class_entry *mono = zend_synthesize_monomorph(
+						base_iface, nwa->args, nwa->count);
+					if (!mono) {
+						check_unrecoverable_load_failure(ce);
+						free_alloca(traits_and_interfaces, use_heap);
+						return NULL;
+					}
+					zend_string_release(ce->interface_names[i].name);
+					zend_string_release(ce->interface_names[i].lc_name);
+					ce->interface_names[i].name = zend_string_copy(mono->name);
+					ce->interface_names[i].lc_name = zend_string_tolower(mono->name);
+				}
+			}
+
+			zend_class_entry *iface = zend_fetch_class_by_name(
+				ce->interface_names[i].name, ce->interface_names[i].lc_name,
+				ZEND_FETCH_CLASS_INTERFACE |
+				ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED | ZEND_FETCH_CLASS_EXCEPTION);
+			if (!iface) {
+				check_unrecoverable_load_failure(ce);
+				free_alloca(traits_and_interfaces, use_heap);
+				return NULL;
+			}
+			traits_and_interfaces[ce->num_traits + i] = iface;
+			if (iface) {
+				UPDATE_IS_CACHEABLE(iface);
+			}
+		}
+		if (skip_mono) {
+			free_alloca(skip_mono, skip_mono_use_heap);
+		}
+	}
+
+	zend_validate_generic_inheritance_arities(ce, parent, traits_and_interfaces);
+
+	zend_class_entry *orig_active = CG(active_class_entry);
+	CG(active_class_entry) = ce;
+	zend_check_generic_variance_markers(ce);
+	CG(active_class_entry) = orig_active;
+
+#ifndef ZEND_WIN32
+	if (ce->ce_flags & ZEND_ACC_ENUM) {
+		/* We will add internal methods. */
+		is_cacheable = false;
+	}
+#endif
+
+	if ((ce->ce_flags & ZEND_ACC_IMMUTABLE || cache_key_proto) && is_cacheable) {
+		if (zend_inheritance_cache_get && zend_inheritance_cache_add) {
+			/* When we lazy-loaded early (cache_key_proto != NULL), the
+			 * immutable original is the cache key opcache stored under. */
+			zend_class_entry *key_ce = cache_key_proto ? cache_key_proto : ce;
+			zend_class_entry *ret = zend_inheritance_cache_get(key_ce, parent, traits_and_interfaces);
+			if (ret) {
+				if (traits_and_interfaces) {
+					free_alloca(traits_and_interfaces, use_heap);
+				}
+				zv = zend_hash_find_known_hash(CG(class_table), key);
+				Z_CE_P(zv) = ret;
+				return ret;
+			}
+		} else {
+			is_cacheable = 0;
+		}
+		proto = cache_key_proto ? cache_key_proto : ce;
+	}
+
+	/* Delay and record warnings (such as deprecations) thrown during
+	 * inheritance, so they will be recorded in the inheritance cache.
+	 * Warnings must be delayed in all cases so that we get a consistent
+	 * behavior regardless of cacheability. */
+	bool orig_record_errors = EG(record_errors);
+	if (!orig_record_errors) {
+		zend_begin_record_errors();
+	}
+
+	zend_try {
+		if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
+			/* Lazy class loading */
+			ce = zend_lazy_class_load(ce);
+			zv = zend_hash_find_known_hash(CG(class_table), key);
+			Z_CE_P(zv) = ce;
+		} else if (ce->ce_flags & ZEND_ACC_FILE_CACHED) {
+			/* Lazy class loading */
+			ce = zend_lazy_class_load(ce);
 			ce->ce_flags &= ~ZEND_ACC_FILE_CACHED;
 			zv = zend_hash_find_known_hash(CG(class_table), key);
 			Z_CE_P(zv) = ce;
 		}
 
 		if (CG(unlinked_uses)) {
-			zend_hash_index_del(CG(unlinked_uses), (zend_long)(uintptr_t) ce);
+			zend_hash_index_del(CG(unlinked_uses), (zend_ulong)(uintptr_t) ce);
 		}
 
 		orig_linking_class = CG(current_linking_class);
@@ -3759,6 +6545,7 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
 	}
 
 	if (!orig_record_errors) {
+		zend_emit_recorded_errors();
 		zend_free_recorded_errors();
 	}
 	if (traits_and_interfaces) {
@@ -3880,6 +6667,37 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
 		return ce;
 	}
 
+	/* Bound-erased generics, extends-with-args: same redirect as in
+	 * zend_do_link_class but for the early-binding path. Validate arity
+	 * against the base's parameter list (so we keep the original "Too
+	 * few/many type arguments to extends" error wording), then synthesize
+	 * the canonical monomorph as a completed top-level link before ce's
+	 * link begins, then rewrite parent_ce (local) and ce->parent_name to
+	 * point at the monomorph. Skip when any arg contains a type-parameter
+	 * ref (e.g. `class Derived extends Base`) — the args are still
+	 * symbolic and would only become concrete when Derived itself is
+	 * monomorphized. */
+	if (parent_ce && parent_ce->generic_parameters
+			&& ce->generic_types && ce->generic_types->extends
+			&& ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)
+			&& !zend_class_is_monomorph(ce)
+			&& !zend_type_contains_type_parameter(*ce->generic_types->extends)) {
+		const zend_type_named_with_args *nwa =
+			ZEND_TYPE_NAMED_WITH_ARGS(*ce->generic_types->extends);
+		zend_check_generic_link_arity(parent_ce, nwa->count, "extends", ce->name);
+		zend_check_generic_link_bounds(parent_ce, ce->generic_types->extends,
+			"extends", ce);
+		zend_class_entry *mono = zend_synthesize_monomorph(parent_ce, nwa->args, nwa->count);
+		if (!mono) {
+			return NULL;
+		}
+		if (ce->parent_name) {
+			zend_string_release(ce->parent_name);
+		}
+		ce->parent_name = zend_string_copy(mono->name);
+		parent_ce = mono;
+	}
+
 	uint32_t is_cacheable = ce->ce_flags & ZEND_ACC_IMMUTABLE;
 	UPDATE_IS_CACHEABLE(parent_ce);
 	if (is_cacheable) {
@@ -3919,10 +6737,12 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
 		orig_linking_class = CG(current_linking_class);
 		CG(current_linking_class) = is_cacheable ? ce : NULL;
 
+		bool orig_record_errors = EG(record_errors);
+
 		zend_try{
 			CG(zend_lineno) = ce->info.user.line_start;
 
-			if (is_cacheable) {
+			if (!orig_record_errors) {
 				zend_begin_record_errors();
 			}
 
@@ -3944,13 +6764,13 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
 
 			CG(current_linking_class) = orig_linking_class;
 		} zend_catch {
-			EG(record_errors) = false;
-			zend_free_recorded_errors();
+			if (!orig_record_errors) {
+				EG(record_errors) = false;
+				zend_free_recorded_errors();
+			}
 			zend_bailout();
 		} zend_end_try();
 
-		EG(record_errors) = false;
-
 		if (is_cacheable) {
 			HashTable *ht = (HashTable*)ce->inheritance_cache;
 			zend_class_entry *new_ce;
@@ -3968,6 +6788,11 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
 			}
 		}
 
+		if (!orig_record_errors) {
+			zend_emit_recorded_errors();
+			zend_free_recorded_errors();
+		}
+
 		if (ZSTR_HAS_CE_CACHE(ce->name)) {
 			ZSTR_SET_CE_CACHE(ce->name, ce);
 		}
@@ -3978,3 +6803,1065 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_
 	return NULL;
 }
 /* }}} */
+
+ZEND_API zend_inheritance_status zend_check_generic_arg_satisfies_bound(
+		zend_class_entry *arg_scope, zend_type arg,
+		zend_class_entry *bound_scope, zend_type bound)
+{
+	if (!ZEND_TYPE_IS_SET(bound)) {
+		return INHERITANCE_SUCCESS;
+	}
+
+	return zend_perform_covariant_type_check(arg_scope, arg, bound_scope, bound);
+}
+
+/* === Monomorph synthesis ===
+ *
+ * Builds a real class_entry for a generic application like `Box` and
+ * registers it in EG(class_table) under the canonical name. The synthesized
+ * class extends the base with the supplied type args; inheritance does the
+ * rest (substituted arg_info via the TRAIT_CLONE machinery, substituted
+ * property types, etc.). */
+
+static zend_type zend_monomorph_dup_type(zend_type t)
+{
+	zend_type_copy_ctor(&t, /* use_arena */ false, /* persistent */ false);
+	return t;
+}
+
+static zend_type zend_monomorph_build_extends_payload(
+	zend_class_entry *base, const zend_type *args, uint32_t arity)
+{
+	zend_type_named_with_args *payload = emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(arity));
+	payload->name = zend_string_copy(base->name);
+	payload->name_attr = 0;
+	payload->count = arity;
+	for (uint32_t i = 0; i < arity; i++) {
+		payload->args[i] = zend_monomorph_dup_type(args[i]);
+	}
+	zend_type result = ZEND_TYPE_INIT_NONE(0);
+	ZEND_TYPE_SET_PTR(result, payload);
+	ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NAMED_WITH_ARGS_BIT;
+	return result;
+}
+
+ZEND_API zend_class_entry *zend_get_defaults_monomorph(zend_class_entry *base)
+{
+	if (!base->generic_parameters) {
+		return base;
+	}
+	if (EXPECTED(base->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS)) {
+		return zend_synthesize_monomorph(base, NULL, 0);
+	}
+	uint32_t total = base->generic_parameters->count;
+	for (uint32_t i = 0; i < total; i++) {
+		if (!ZEND_TYPE_IS_SET(base->generic_parameters->parameters[i].default_type)) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments; "
+				"type parameter %s has no default",
+				ZSTR_VAL(base->name),
+				ZSTR_VAL(base->generic_parameters->parameters[i].name));
+			return NULL;
+		}
+	}
+	ZEND_UNREACHABLE();
+}
+
+/* When `new C::<...>(...)` is compiled inside a generic function/class, the
+ * turbofish args may reference enclosing-scope T parameters by ref. The op_array
+ * side-table stores those refs verbatim — at synth time they must be resolved
+ * against the executing frame's bindings, or the monomorph would carry literal
+ * "Box"-style args and its method arg_info would never resolve to a concrete
+ * type. Walks args[i]; for top-level T-refs, substitutes via the frame's
+ * function-level type_args (FUNCTION_LIKE) or the lexical class's monomorph
+ * descendant's generic_type_args (CLASS_LIKE). When the frame has no binding,
+ * falls back to the referenced parameter's class bound (matching the runtime
+ * fallback used by `new T()` / `instanceof T` resolution). Throws and returns
+ * NULL when neither a binding nor a class-bound fallback is available — same
+ * shape and message as the existing zend_resolve_generic_type_param error so
+ * users see one consistent diagnostic across `new T()` and `new C::()`. */
+static bool zend_resolve_synth_args_against_frame(
+	const zend_type *args, uint32_t arity, zend_type *out)
+{
+	zend_execute_data *ex = EG(current_execute_data);
+	for (uint32_t i = 0; i < arity; i++) {
+		if (!ZEND_TYPE_HAS_TYPE_PARAMETER(args[i])) {
+			out[i] = args[i];
+			continue;
+		}
+		const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(args[i]);
+		const zend_type *resolved = NULL;
+		const zend_generic_parameter_list *params = NULL;
+		if (ref->origin == ZEND_GENERIC_ORIGIN_FUNCTION_LIKE) {
+			if (ex && ZEND_USER_CODE(ex->func->type)) {
+				if (ex->type_args && ref->index < ex->type_args->count) {
+					resolved = zend_type_arg_entry_type(&ex->type_args->entries[ref->index]);
+				}
+				params = ex->func->op_array.generic_parameters;
+			}
+		} else {
+			/* Walk from called scope up to the direct child of the lexical
+			 * class — that's the monomorph carrying the binding (see the
+			 * matching walk in zend_resolve_generic_type_param). */
+			if (ex) {
+				zend_class_entry *lexical = ex->func->common.scope;
+				zend_class_entry *cur = zend_get_called_scope(ex);
+				while (cur && cur->parent != lexical) {
+					cur = cur->parent;
+				}
+				if (cur && cur->generic_type_args
+						&& ref->index < cur->generic_type_args->count) {
+					resolved = zend_type_arg_entry_type(
+						&cur->generic_type_args->entries[ref->index]);
+				}
+				if (lexical) {
+					params = lexical->generic_parameters;
+				}
+			}
+		}
+		if (resolved && ZEND_TYPE_IS_SET(*resolved)) {
+			out[i] = *resolved;
+			continue;
+		}
+		/* No binding from the frame. Fall back to the referenced parameter's
+		 * class bound — same fallback as `new T()` / `instanceof T`. A
+		 * non-class bound (default `mixed`, scalar, union, etc.) has no
+		 * class name to substitute, so synth cannot proceed: throw. */
+		if (params && ref->index < params->count) {
+			zend_type bound = params->parameters[ref->index].bound;
+			if (ZEND_TYPE_HAS_NAME(bound)) {
+				out[i] = bound;
+				continue;
+			}
+			zend_throw_error(NULL,
+				"Cannot resolve generic type parameter %s at runtime: "
+				"no binding was supplied and its bound is not a class",
+				ZSTR_VAL(params->parameters[ref->index].name));
+		} else {
+			zend_throw_error(NULL,
+				"Cannot resolve generic type parameter at runtime: "
+				"no binding was supplied and no parameter scope is available");
+		}
+		return false;
+	}
+	return true;
+}
+
+/* Same as zend_synthesize_monomorph, but resolves TYPE_PARAMETER refs in args
+ * against the executing frame's T-tables first. Use this at runtime `new`
+ * sites where the args originate from a compile-time side-table that may
+ * reference enclosing-scope T's. Static callers (class-build extends/implements
+ * with already-resolved args) keep using zend_synthesize_monomorph directly. */
+ZEND_API zend_class_entry *zend_synthesize_monomorph_resolved(
+	zend_class_entry *base, const zend_type *args, uint32_t arity)
+{
+	if (arity == 0) {
+		return zend_synthesize_monomorph(base, args, arity);
+	}
+	zend_type resolved[ZEND_GENERIC_MAX_PARAMS];
+	if (!zend_resolve_synth_args_against_frame(args, arity, resolved)) {
+		return NULL;
+	}
+	return zend_synthesize_monomorph(base, resolved, arity);
+}
+
+ZEND_API zend_class_entry *zend_synthesize_monomorph(
+	zend_class_entry *base, const zend_type *args, uint32_t arity)
+{
+	if (!base->generic_parameters) {
+		zend_throw_error(NULL,
+			"Cannot monomorphize non-generic class %s",
+			ZSTR_VAL(base->name));
+		return NULL;
+	}
+	uint32_t total = base->generic_parameters->count;
+	if (arity > total) {
+		zend_throw_error(NULL,
+			"Cannot monomorphize %s: expected at most %u type argument(s), got %u",
+			ZSTR_VAL(base->name), total, arity);
+		return NULL;
+	}
+	/* Fill in defaults for any trailing parameters not supplied. */
+	zend_type filled[ZEND_GENERIC_MAX_PARAMS];
+	if (arity < total) {
+		for (uint32_t i = 0; i < arity; i++) {
+			filled[i] = args[i];
+		}
+		for (uint32_t i = arity; i < total; i++) {
+			const zend_generic_parameter *p = &base->generic_parameters->parameters[i];
+			if (!ZEND_TYPE_IS_SET(p->default_type)) {
+				zend_throw_error(NULL,
+					"Cannot monomorphize %s: type parameter %s has no default and was not supplied",
+					ZSTR_VAL(base->name), ZSTR_VAL(p->name));
+				return NULL;
+			}
+			filled[i] = p->default_type;
+		}
+		args = filled;
+		arity = total;
+	}
+
+	zend_string *canonical = zend_generic_canonical_class_name(base->name, args, arity);
+	zend_string *lc_canonical = zend_string_tolower(canonical);
+
+	zend_class_entry *existing = zend_hash_find_ptr(EG(class_table), lc_canonical);
+	if (existing) {
+		zend_string_release(canonical);
+		zend_string_release(lc_canonical);
+		return existing;
+	}
+
+	/* Validate bounds before committing to a class entry. */
+	zend_type extends_payload = zend_monomorph_build_extends_payload(base, args, arity);
+	{
+		zend_class_entry tmp_scope;
+		memset(&tmp_scope, 0, sizeof(tmp_scope));
+		tmp_scope.name = canonical;
+		tmp_scope.type = ZEND_USER_CLASS;
+		zend_check_generic_link_bounds(base, &extends_payload, "new", &tmp_scope);
+		if (EG(exception)) {
+			zend_type_release(extends_payload, /* persistent */ false);
+			zend_string_release(canonical);
+			zend_string_release(lc_canonical);
+			return NULL;
+		}
+	}
+
+	zend_class_entry *ce = zend_arena_alloc(&CG(arena), sizeof(zend_class_entry));
+	ce->type = ZEND_USER_CLASS;
+	zend_initialize_class_data(ce, /* nullify_handlers */ true);
+	ce->ce_flags &= ~ZEND_ACC_IMMUTABLE;
+	ce->ce_flags |= ZEND_ACC_TOP_LEVEL;
+	/* Carry the base's class-shape flags (interface, trait, enum) so the
+	 * monomorph is the same kind of class-like as the base. Without this,
+	 * an interface base would synthesize a class trying to extend the
+	 * interface, which the linker rejects. */
+	ce->ce_flags |= base->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_ENUM);
+	ce->info.user.filename = base->info.user.filename
+		? zend_string_copy(base->info.user.filename)
+		: ZSTR_EMPTY_ALLOC();
+	ce->info.user.line_start = base->info.user.line_start;
+	ce->info.user.line_end = base->info.user.line_end;
+	ce->name = canonical;
+
+	/* Stash the bindings the runtime needs when method bodies reference the
+	 * class-level T directly (e.g. `new T()` inside `class Box`'s body).
+	 * The bound type is borrowed from extends_payload's NWA — that payload
+	 * gets installed into ce->generic_types below, so it has the same
+	 * lifetime as ce itself, and ce->generic_type_args has the same
+	 * lifetime as ce too. The canonical name is owned by the entry. */
+	const zend_type_named_with_args *binding_nwa =
+		ZEND_TYPE_NAMED_WITH_ARGS(extends_payload);
+	ce->generic_type_args = zend_type_arg_table_alloc(arity);
+	for (uint32_t i = 0; i < arity; i++) {
+		ce->generic_type_args->entries[i].name = zend_type_arg_canonical_name(binding_nwa->args[i]);
+		ce->generic_type_args->entries[i].type_ref = &binding_nwa->args[i];
+	}
+
+	bool base_is_interface = (base->ce_flags & ZEND_ACC_INTERFACE) != 0;
+	bool base_is_trait = (base->ce_flags & ZEND_ACC_TRAIT) != 0;
+	if (base_is_interface) {
+		/* Interface inheritance in PHP goes through `interface_names[]`, not
+		 * `parent_name`. Wire the mono to the base interface via one entry in
+		 * `interfaces[]` and store the substitution args in the `implements`
+		 * side-table so the inheritance pipeline can substitute T → arg in
+		 * the inherited methods. */
+		ce->num_interfaces = 1;
+		ce->interface_names = emalloc(sizeof(zend_class_name));
+		ce->interface_names[0].name = zend_string_copy(base->name);
+		ce->interface_names[0].lc_name = zend_string_tolower(base->name);
+		zend_generic_type_table_set_implements(
+			zend_generic_get_or_create_class_table(ce), 0, extends_payload);
+	} else if (base_is_trait) {
+		/* Trait composition in PHP goes through `trait_names[]`/`num_traits`.
+		 * The mono `uses` the base trait with the substitution args recorded
+		 * in `trait_uses` so the trait-method import path picks them up. */
+		ce->num_traits = 1;
+		ce->trait_names = emalloc(sizeof(zend_class_name));
+		ce->trait_names[0].name = zend_string_copy(base->name);
+		ce->trait_names[0].lc_name = zend_string_tolower(base->name);
+		zend_generic_type_table_set_trait_use(
+			zend_generic_get_or_create_class_table(ce), 0, extends_payload);
+	} else {
+		ce->parent_name = zend_string_copy(base->name);
+		zend_generic_type_table_set_extends(
+			zend_generic_get_or_create_class_table(ce), extends_payload);
+	}
+
+	zval ce_zv;
+	ZVAL_PTR(&ce_zv, ce);
+	if (zend_hash_add(EG(class_table), lc_canonical, &ce_zv) == NULL) {
+		/* Race: another path registered this canonical name first. */
+		zend_class_entry *winner = zend_hash_find_ptr(EG(class_table), lc_canonical);
+		destroy_zend_class(&ce_zv);
+		zend_string_release(lc_canonical);
+		return winner;
+	}
+
+	zend_string *parent_lc = (base_is_interface || base_is_trait)
+		? NULL : zend_string_tolower(base->name);
+
+	/* Monomorph synthesis is an engine-internal child of the base, not a
+	 * user-declared subclass. final/readonly restrictions that gate
+	 * user-level extension are bypassed via EG(monomorph_synthesis_active)
+	 * for the duration of the link, then propagated to the monomorph so user
+	 * code still can't `extends Box` if Box itself was final. Abstract
+	 * is propagated so the monomorph of an abstract class stays abstract
+	 * (and a concrete subclass can implement its methods). Note: we don't
+	 * mutate base->ce_flags here because base may live in read-only opcache
+	 * SHM (opcache.protect_memory=1). */
+	uint32_t inherited = base->ce_flags & (ZEND_ACC_FINAL | ZEND_ACC_READONLY_CLASS);
+	uint32_t propagated = base->ce_flags & (ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
+	ce->ce_flags |= propagated;
+	bool prev_mono_active = EG(monomorph_synthesis_active);
+	EG(monomorph_synthesis_active) = true;
+	zend_class_entry *linked = zend_do_link_class(ce, parent_lc, lc_canonical);
+	EG(monomorph_synthesis_active) = prev_mono_active;
+	if (linked) {
+		linked->ce_flags |= inherited;
+	}
+	if (parent_lc) zend_string_release(parent_lc);
+
+	if (!linked) {
+		zend_hash_del(EG(class_table), lc_canonical);
+		zend_string_release(lc_canonical);
+		return NULL;
+	}
+
+	/* Isolate static-property storage from the base class. Inheritance normally
+	 * makes the child's `default_static_members_table` slots IS_INDIRECT back to
+	 * the parent so that all subclasses share the same live storage. For
+	 * monomorphs that's the wrong semantic: `Box::$count` and
+	 * `Box::$count` should be independent counters. Convert each
+	 * INDIRECT slot to a direct copy of the underlying default; at first access
+	 * `zend_class_init_statics` will then allocate the monomorph its own live
+	 * slot and `ZVAL_COPY_OR_DUP` the default into it. */
+	if (linked->default_static_members_count) {
+		for (uint32_t i = 0; i < linked->default_static_members_count; i++) {
+			zval *slot = &linked->default_static_members_table[i];
+			if (Z_TYPE_P(slot) == IS_INDIRECT) {
+				zval *src = Z_INDIRECT_P(slot);
+				ZVAL_DEINDIRECT(src);
+				ZVAL_COPY_OR_DUP(slot, src);
+			}
+		}
+	}
+
+	/* Substitute T-typed implements on the inherited interface chain. When
+	 * the base declares `class B implements I` and is monomorphized as
+	 * `B`, the inherited interfaces[] still points at the erased
+	 * base interface I — so `instanceof I` returns false. Walk the
+	 * base's parent chain too, since `class B extends A` where
+	 * `class A implements I` needs the same substitution for B.
+	 * For each generic ancestor, resolve the binding from `base` to that
+	 * ancestor, substitute each implements entry's args, synthesize the
+	 * corresponding interface monomorph, and add it to linked->interfaces.
+	 * The standard `instanceof` walks both the parent chain and interfaces[],
+	 * so the substituted forms become discoverable and the erased base
+	 * interfaces stay reachable transitively. */
+	{
+		ALLOCA_FLAG(extras_use_heap)
+		SET_ALLOCA_FLAG(extras_use_heap);
+		uint32_t max_extras = 0;
+		for (zend_class_entry *a = base; a; a = a->parent) {
+			max_extras += a->num_interfaces;
+		}
+		zend_class_entry **extras = max_extras
+			? do_alloca(sizeof(zend_class_entry *) * max_extras, extras_use_heap)
+			: NULL;
+		uint32_t extra_count = 0;
+
+		for (zend_class_entry *ancestor = base; ancestor; ancestor = ancestor->parent) {
+			if (!ancestor->generic_types || !ancestor->generic_types->implements
+					|| !ancestor->generic_parameters) {
+				continue;
+			}
+			uint32_t a_cap = ancestor->generic_parameters->count;
+			if (a_cap == 0) continue;
+
+			/* Resolve the binding from the synthesized monomorph (whose direct
+			 * binding is to `base`) to `ancestor`. For the immediate-base case,
+			 * the binding is the args we were called with. For deeper ancestors,
+			 * compose base→ancestor's binding and then substitute its T-refs
+			 * with the args we hold. */
+			zend_type bound_args[ZEND_GENERIC_MAX_PARAMS];
+			uint32_t bound_arity = 0;
+			if (ancestor == base) {
+				if (arity > ZEND_GENERIC_MAX_PARAMS) continue;
+				for (uint32_t k = 0; k < arity; k++) bound_args[k] = args[k];
+				bound_arity = arity;
+			} else {
+				bool have = zend_get_inheritance_binding_full_cached(
+					base, ancestor, bound_args, ZEND_GENERIC_MAX_PARAMS, &bound_arity);
+				if (!have) continue;
+				for (uint32_t k = 0; k < bound_arity; k++) {
+					bound_args[k] = zend_substitute_leaf_type_param(
+						bound_args[k], args, arity);
+				}
+			}
+
+			const HashTable *impl_table = ancestor->generic_types->implements;
+			for (uint32_t i = 0; i < ancestor->num_interfaces; i++) {
+				const zend_type *impl_args_t = (const zend_type *) zend_hash_index_find_ptr(impl_table, i);
+				if (!impl_args_t || !ZEND_TYPE_HAS_NAMED_WITH_ARGS(*impl_args_t)) {
+					continue;
+				}
+				const zend_type_named_with_args *impl_nwa = ZEND_TYPE_NAMED_WITH_ARGS(*impl_args_t);
+
+				ALLOCA_FLAG(sub_use_heap)
+				zend_type *sub_args = do_alloca(
+					sizeof(zend_type) * impl_nwa->count, sub_use_heap);
+				bool all_ground = true;
+				for (uint32_t j = 0; j < impl_nwa->count; j++) {
+					sub_args[j] = zend_substitute_leaf_type_param(
+						impl_nwa->args[j], bound_args, bound_arity);
+					if (zend_type_contains_type_parameter(sub_args[j])) {
+						all_ground = false;
+						break;
+					}
+				}
+				if (!all_ground) {
+					free_alloca(sub_args, sub_use_heap);
+					continue;
+				}
+				zend_class_entry *iface_base = ancestor->interfaces
+					? ancestor->interfaces[i] : NULL;
+				if (!iface_base) {
+					iface_base = zend_lookup_class(impl_nwa->name);
+				}
+				zend_class_entry *iface_mono = NULL;
+				if (iface_base && iface_base->generic_parameters) {
+					iface_mono = zend_synthesize_monomorph(
+						iface_base, sub_args, impl_nwa->count);
+				}
+				free_alloca(sub_args, sub_use_heap);
+				if (!iface_mono) continue;
+
+				bool already = false;
+				for (uint32_t k = 0; k < linked->num_interfaces; k++) {
+					if (linked->interfaces[k] == iface_mono) { already = true; break; }
+				}
+				if (already) continue;
+				for (uint32_t k = 0; k < extra_count; k++) {
+					if (extras[k] == iface_mono) { already = true; break; }
+				}
+				if (already) continue;
+				extras[extra_count++] = iface_mono;
+			}
+		}
+
+		if (extra_count > 0) {
+			uint32_t new_count = linked->num_interfaces + extra_count;
+			linked->interfaces = perealloc(
+				linked->interfaces,
+				sizeof(zend_class_entry *) * new_count,
+				linked->type == ZEND_INTERNAL_CLASS);
+			for (uint32_t k = 0; k < extra_count; k++) {
+				linked->interfaces[linked->num_interfaces + k] = extras[k];
+				do_implement_interface(linked, extras[k]);
+			}
+			linked->num_interfaces = new_count;
+		}
+		if (extras) free_alloca(extras, extras_use_heap);
+	}
+
+	/* Substitute T-typed class constants. When the base declares `const T FOO`,
+	 * the inherited entry in the mono is a shared pointer to the base's
+	 * `zend_class_constant` with type T (erased to mixed). For the mono,
+	 * clone any entry whose pre-erasure side-table type references a generic
+	 * parameter, and substitute T → arg so reflection and assignability
+	 * checks see the concrete type for this monomorph. */
+	if (base->generic_types && base->generic_types->class_constants) {
+		zend_string *cname;
+		zval *zv;
+		ZEND_HASH_FOREACH_STR_KEY_VAL(base->generic_types->class_constants, cname, zv) {
+			const zend_type *pre = (const zend_type *) Z_PTR_P(zv);
+			if (!ZEND_TYPE_IS_SET(*pre) || !zend_type_contains_type_parameter(*pre)) {
+				continue;
+			}
+			zend_type sub = zend_substitute_leaf_type_param(*pre, args, arity);
+			if (ZEND_TYPE_HAS_TYPE_PARAMETER(sub)) {
+				continue;
+			}
+			zval *cv = zend_hash_find_known_hash(&linked->constants_table, cname);
+			if (!cv) continue;
+			zend_class_constant *orig = (zend_class_constant *) Z_PTR_P(cv);
+			zend_class_constant *clone = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant));
+			memcpy(clone, orig, sizeof(zend_class_constant));
+			clone->type = sub;
+			zend_type_copy_ctor(&clone->type, /* use_arena */ true, /* persistent */ false);
+			Z_PTR_P(cv) = clone;
+		} ZEND_HASH_FOREACH_END();
+	}
+
+	zend_string_release(lc_canonical);
+	return linked;
+}
+
+/* === Monomorph name parser ===
+ *
+ * Parses class-name strings like "Box>" into a base
+ * class name plus a type-args list. Used by the class-lookup hook so that
+ * unserialize, dynamic `new $name`, and `class_exists` all synthesize the
+ * monomorph on demand if it hasn't been materialized in this request yet.
+ *
+ * Accepts the same shape the canonicalizer produces, plus generally any
+ * type-expression syntax: unions with `|`, intersections with `&`, DNF
+ * parens, nested generics, fully-qualified namespaced names, scalar
+ * keywords (int, string, bool, float, array, object, callable, mixed,
+ * void, never, null, true, false). Whitespace is permitted.
+ *
+ * The parser is intentionally permissive about input form; the synthesizer
+ * canonicalizes anyway, so semantically-equivalent inputs collapse to one
+ * class entry. */
+
+typedef struct {
+	const char *p;
+	const char *end;
+	bool error;
+} zend_monomorph_parser;
+
+static void zend_mp_skip_ws(zend_monomorph_parser *s) {
+	while (s->p < s->end && (*s->p == ' ' || *s->p == '\t')) s->p++;
+}
+
+static bool zend_mp_eat(zend_monomorph_parser *s, char c) {
+	zend_mp_skip_ws(s);
+	if (s->p < s->end && *s->p == c) { s->p++; return true; }
+	return false;
+}
+
+static bool zend_mp_peek(zend_monomorph_parser *s, char c) {
+	zend_mp_skip_ws(s);
+	return s->p < s->end && *s->p == c;
+}
+
+static zend_string *zend_mp_read_ident(zend_monomorph_parser *s) {
+	zend_mp_skip_ws(s);
+	const char *start = s->p;
+	while (s->p < s->end) {
+		unsigned char ch = (unsigned char)*s->p;
+		bool ok = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')
+			|| (ch >= '0' && ch <= '9') || ch == '_' || ch == '\\' || ch >= 0x80;
+		if (!ok) break;
+		s->p++;
+	}
+	if (s->p == start) return NULL;
+	return zend_string_init(start, s->p - start, 0);
+}
+
+static struct { const char *kw; uint32_t bit; } zend_mp_scalars[] = {
+	{ "int", MAY_BE_LONG },
+	{ "string", MAY_BE_STRING },
+	{ "float", MAY_BE_DOUBLE },
+	{ "bool", MAY_BE_BOOL },
+	{ "true", MAY_BE_TRUE },
+	{ "false", MAY_BE_FALSE },
+	{ "null", MAY_BE_NULL },
+	{ "array", MAY_BE_ARRAY },
+	{ "object", MAY_BE_OBJECT },
+	{ "callable", MAY_BE_CALLABLE },
+	{ "void", MAY_BE_VOID },
+	{ "never", MAY_BE_NEVER },
+	{ "mixed", MAY_BE_ANY },
+	{ NULL, 0 }
+};
+
+static uint32_t zend_mp_scalar_bit(const zend_string *ident) {
+	for (size_t i = 0; zend_mp_scalars[i].kw; i++) {
+		size_t kwlen = strlen(zend_mp_scalars[i].kw);
+		if (ZSTR_LEN(ident) == kwlen
+			&& zend_binary_strcasecmp(
+				ZSTR_VAL(ident), ZSTR_LEN(ident),
+				zend_mp_scalars[i].kw, kwlen) == 0) {
+			return zend_mp_scalars[i].bit;
+		}
+	}
+	return 0;
+}
+
+static zend_type zend_mp_parse_type(zend_monomorph_parser *s);
+
+/* Single atomic type: scalar keyword, class name (with optional <...>),
+ * or a parenthesized intersection used inside a union (DNF). */
+static zend_type zend_mp_parse_atom(zend_monomorph_parser *s)
+{
+	zend_mp_skip_ws(s);
+	if (zend_mp_eat(s, '(')) {
+		/* DNF intersection branch */
+		zend_type inner = zend_mp_parse_type(s);
+		if (s->error || !zend_mp_eat(s, ')')) {
+			s->error = true;
+			zend_type_release(inner, /* persistent */ false);
+			return (zend_type) ZEND_TYPE_INIT_NONE(0);
+		}
+		return inner;
+	}
+
+	zend_string *ident = zend_mp_read_ident(s);
+	if (!ident) { s->error = true; return (zend_type) ZEND_TYPE_INIT_NONE(0); }
+
+	/* Nested generic? */
+	if (zend_mp_peek(s, '<')) {
+		s->p++;  /* consume '<' */
+		uint32_t cap = 4, count = 0;
+		zend_type *args = emalloc(sizeof(zend_type) * cap);
+		do {
+			if (count == cap) {
+				cap *= 2;
+				args = erealloc(args, sizeof(zend_type) * cap);
+			}
+			args[count++] = zend_mp_parse_type(s);
+			if (s->error) break;
+		} while (zend_mp_eat(s, ','));
+		if (!s->error && !zend_mp_eat(s, '>')) s->error = true;
+		if (s->error) {
+			for (uint32_t i = 0; i < count; i++) {
+				zend_type_release(args[i], false);
+			}
+			efree(args);
+			zend_string_release(ident);
+			return (zend_type) ZEND_TYPE_INIT_NONE(0);
+		}
+		zend_type_named_with_args *payload = emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(count));
+		payload->name = ident;
+		payload->name_attr = 0;
+		payload->count = count;
+		for (uint32_t i = 0; i < count; i++) payload->args[i] = args[i];
+		efree(args);
+		zend_type result = ZEND_TYPE_INIT_NONE(0);
+		ZEND_TYPE_SET_PTR(result, payload);
+		ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NAMED_WITH_ARGS_BIT;
+		return result;
+	}
+
+	uint32_t scalar = zend_mp_scalar_bit(ident);
+	if (scalar) {
+		zend_string_release(ident);
+		zend_type t = ZEND_TYPE_INIT_NONE(0);
+		ZEND_TYPE_FULL_MASK(t) = scalar;
+		return t;
+	}
+	return (zend_type) ZEND_TYPE_INIT_CLASS(ident, 0, 0);
+}
+
+/* `atom (& atom)*` -- a single intersection branch.
+ * Returns either a single atom or an intersection list. */
+static zend_type zend_mp_parse_intersection(zend_monomorph_parser *s)
+{
+	zend_type first = zend_mp_parse_atom(s);
+	if (s->error || !zend_mp_peek(s, '&')) return first;
+
+	uint32_t cap = 4, count = 1;
+	zend_type *parts = emalloc(sizeof(zend_type) * cap);
+	parts[0] = first;
+	while (zend_mp_eat(s, '&')) {
+		if (count == cap) { cap *= 2; parts = erealloc(parts, sizeof(zend_type) * cap); }
+		parts[count++] = zend_mp_parse_atom(s);
+		if (s->error) break;
+	}
+	if (s->error) {
+		for (uint32_t i = 0; i < count; i++) zend_type_release(parts[i], false);
+		efree(parts);
+		return (zend_type) ZEND_TYPE_INIT_NONE(0);
+	}
+	zend_type_list *list = emalloc(ZEND_TYPE_LIST_SIZE(count));
+	list->num_types = count;
+	for (uint32_t i = 0; i < count; i++) list->types[i] = parts[i];
+	efree(parts);
+	zend_type result = ZEND_TYPE_INIT_INTERSECTION(list, 0);
+	return result;
+}
+
+/* `intersection ('|' intersection)*` -- top-level type expression.
+ * Returns either a single intersection, a single atom, or a union list. */
+static zend_type zend_mp_parse_type(zend_monomorph_parser *s)
+{
+	zend_type first = zend_mp_parse_intersection(s);
+	if (s->error || !zend_mp_peek(s, '|')) return first;
+
+	uint32_t cap = 4, count = 1;
+	zend_type *parts = emalloc(sizeof(zend_type) * cap);
+	parts[0] = first;
+	while (zend_mp_eat(s, '|')) {
+		if (count == cap) { cap *= 2; parts = erealloc(parts, sizeof(zend_type) * cap); }
+		parts[count++] = zend_mp_parse_intersection(s);
+		if (s->error) break;
+	}
+	if (s->error) {
+		for (uint32_t i = 0; i < count; i++) zend_type_release(parts[i], false);
+		efree(parts);
+		return (zend_type) ZEND_TYPE_INIT_NONE(0);
+	}
+
+	/* Collapse scalar-bit-only parts into the type_mask of the resulting list
+	 * so e.g. "int|string" lands as a single zend_type with both bits set, no
+	 * list needed. */
+	uint32_t scalar_mask = 0;
+	uint32_t complex_count = 0;
+	for (uint32_t i = 0; i < count; i++) {
+		bool is_pure_scalar = !ZEND_TYPE_HAS_NAME(parts[i])
+			&& !ZEND_TYPE_HAS_LIST(parts[i])
+			&& !ZEND_TYPE_HAS_NAMED_WITH_ARGS(parts[i]);
+		if (is_pure_scalar) {
+			scalar_mask |= ZEND_TYPE_FULL_MASK(parts[i]);
+		} else {
+			complex_count++;
+		}
+	}
+	if (complex_count == 0) {
+		efree(parts);
+		zend_type t = ZEND_TYPE_INIT_NONE(0);
+		ZEND_TYPE_FULL_MASK(t) = scalar_mask;
+		return t;
+	}
+	if (complex_count == 1 && scalar_mask == 0) {
+		zend_type only = (zend_type) ZEND_TYPE_INIT_NONE(0);
+		for (uint32_t i = 0; i < count; i++) {
+			if (ZEND_TYPE_HAS_NAME(parts[i]) || ZEND_TYPE_HAS_LIST(parts[i])
+				|| ZEND_TYPE_HAS_NAMED_WITH_ARGS(parts[i])) {
+				only = parts[i];
+				break;
+			}
+		}
+		efree(parts);
+		return only;
+	}
+	zend_type_list *list = emalloc(ZEND_TYPE_LIST_SIZE(complex_count));
+	list->num_types = complex_count;
+	uint32_t li = 0;
+	for (uint32_t i = 0; i < count; i++) {
+		bool is_pure_scalar = !ZEND_TYPE_HAS_NAME(parts[i])
+			&& !ZEND_TYPE_HAS_LIST(parts[i])
+			&& !ZEND_TYPE_HAS_NAMED_WITH_ARGS(parts[i]);
+		if (!is_pure_scalar) {
+			list->types[li++] = parts[i];
+		}
+	}
+	efree(parts);
+	zend_type result = ZEND_TYPE_INIT_UNION(list, 0);
+	ZEND_TYPE_FULL_MASK(result) |= scalar_mask;
+	return result;
+}
+
+/* Find the matching `>` for the outermost `<` in `name`. Returns the offset
+ * of `<` (in bytes from the start) and the length of the args span. Returns
+ * false if `name` doesn't have generic shape or has unbalanced angles. */
+static bool zend_mp_split_name(
+	const zend_string *name, size_t *out_lt_pos, size_t *out_args_len)
+{
+	const char *s = ZSTR_VAL(name);
+	size_t n = ZSTR_LEN(name);
+	if (n < 4) return false;  /* shortest possible: X */
+	if (s[n - 1] != '>') return false;
+
+	int depth = 0;
+	size_t lt = SIZE_MAX;
+	for (size_t i = 0; i < n; i++) {
+		if (s[i] == '<') {
+			if (depth == 0) lt = i;
+			depth++;
+		} else if (s[i] == '>') {
+			depth--;
+			if (depth == 0 && i != n - 1) return false;  /* trailing data after closing */
+		}
+	}
+	if (depth != 0 || lt == SIZE_MAX || lt == 0) return false;
+	*out_lt_pos = lt;
+	*out_args_len = n - lt - 2;  /* exclude '<' and '>' */
+	return true;
+}
+
+ZEND_API zend_class_entry *zend_try_synthesize_monomorph_by_name(
+	zend_string *name, uint32_t flags)
+{
+	size_t lt_pos, args_len;
+	if (!zend_mp_split_name(name, <_pos, &args_len)) return NULL;
+
+	zend_string *base_name = zend_string_init(ZSTR_VAL(name), lt_pos, 0);
+
+	/* Recursively look up the base class. If the base is itself a monomorph
+	 * name, the lookup hook will be reentrant and synthesize it first. */
+	uint32_t lookup_flags = flags | ZEND_FETCH_CLASS_NO_AUTOLOAD;
+	zend_class_entry *base = zend_lookup_class_ex(base_name, NULL, lookup_flags);
+	if (!base && !(flags & ZEND_FETCH_CLASS_NO_AUTOLOAD)) {
+		/* Allow autoload for the base name only, in case it isn't loaded yet. */
+		base = zend_lookup_class_ex(base_name, NULL, flags & ~ZEND_FETCH_CLASS_NO_AUTOLOAD);
+	}
+	zend_string_release(base_name);
+	if (!base) return NULL;
+	if (!base->generic_parameters) {
+		zend_throw_error(NULL,
+			"Type arguments are not allowed on non-generic class %s",
+			ZSTR_VAL(base->name));
+		return NULL;
+	}
+
+	zend_monomorph_parser parser = {
+		.p = ZSTR_VAL(name) + lt_pos + 1,
+		.end = ZSTR_VAL(name) + ZSTR_LEN(name) - 1,
+		.error = false,
+	};
+	uint32_t cap = 4, count = 0;
+	zend_type *args = emalloc(sizeof(zend_type) * cap);
+	do {
+		if (count == cap) { cap *= 2; args = erealloc(args, sizeof(zend_type) * cap); }
+		args[count++] = zend_mp_parse_type(&parser);
+		if (parser.error) break;
+	} while (zend_mp_eat(&parser, ','));
+	zend_mp_skip_ws(&parser);
+	if (parser.error || parser.p != parser.end) {
+		for (uint32_t i = 0; i < count; i++) zend_type_release(args[i], false);
+		efree(args);
+		return NULL;
+	}
+
+	zend_class_entry *mono = zend_synthesize_monomorph(base, args, count);
+	for (uint32_t i = 0; i < count; i++) zend_type_release(args[i], false);
+	efree(args);
+	return mono;
+}
+
+/* Function monomorphization: synthesize a concrete op_array for a generic
+ * function. The clone shares the base's refcounted body buffers (refcount==NULL
+ * so destroy_op_array never frees them) and only its arg_info differs. */
+
+/* Build a concrete arg_info block by substituting the FUNCTION_LIKE T-refs in
+ * the base's pre-erasure generic types with the concrete args. */
+static zend_arg_info *zend_monomorph_build_arg_info(
+		const zend_op_array *base, const zend_type *args, uint32_t arity)
+{
+	uint32_t num_args = base->num_args;
+	bool has_return = (base->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) != 0;
+	bool variadic = (base->fn_flags & ZEND_ACC_VARIADIC) != 0;
+	uint32_t total = num_args + (has_return ? 1 : 0) + (variadic ? 1 : 0);
+	if (total == 0 || !base->arg_info) {
+		return NULL;
+	}
+
+	const zend_arg_info *orig_block = base->arg_info - (has_return ? 1 : 0);
+	zend_arg_info *new_block = zend_arena_alloc(&CG(arena), sizeof(zend_arg_info) * total);
+	memcpy(new_block, orig_block, sizeof(zend_arg_info) * total);
+
+	const HashTable *pre_params = base->generic_types ? base->generic_types->parameters : NULL;
+	const zend_type *pre_return = base->generic_types ? base->generic_types->return_type : NULL;
+
+	for (uint32_t slot = 0; slot < total; slot++) {
+		/* slot 0 is the return type when has_return; UINT32_MAX marks it. */
+		uint32_t param_index = has_return ? (slot == 0 ? UINT32_MAX : slot - 1) : slot;
+
+		const zend_type *pre = NULL;
+		if (param_index == UINT32_MAX) {
+			pre = pre_return;
+		} else if (pre_params) {
+			zval *zv = zend_hash_index_find(pre_params, param_index);
+			pre = zv ? (const zend_type *) Z_PTR_P(zv) : NULL;
+		}
+
+		/* Only specialize a BARE FUNCTION_LIKE type-parameter leaf (`T $x`).
+		 * Composite generic types keep the base's erased arg_info: the erased model
+		 * represents generic instances by their plain class, so folding to a
+		 * monomorph name would make RECV reject the plain instances the body emits. */
+		bool is_bare_leaf = pre && ZEND_TYPE_IS_SET(*pre)
+			&& ZEND_TYPE_HAS_TYPE_PARAMETER(*pre)
+			&& ZEND_TYPE_TYPE_PARAMETER(*pre)->origin == ZEND_GENERIC_ORIGIN_FUNCTION_LIKE;
+		if (is_bare_leaf) {
+			zend_type sub = zend_substitute_function_type_param(*pre, args, arity);
+			zend_type_copy_ctor(&sub, /* use_arena */ true, /* persistent */ false);
+			new_block[slot].type = sub;
+		} else {
+			zend_type_copy_ctor(&new_block[slot].type, /* use_arena */ true, /* persistent */ false);
+		}
+		if (new_block[slot].name) {
+			zend_string_addref(new_block[slot].name);
+		}
+		if (new_block[slot].doc_comment) {
+			zend_string_addref(new_block[slot].doc_comment);
+		}
+	}
+
+	return new_block + (has_return ? 1 : 0);
+}
+
+ZEND_API zend_function *zend_synthesize_function_monomorph(
+		zend_function *base, const zend_type *args, uint32_t arity)
+{
+	if (!base || base->type != ZEND_USER_FUNCTION) {
+		return NULL;
+	}
+	const zend_generic_parameter_list *params = base->op_array.generic_parameters;
+	if (!params || params->count == 0) {
+		return NULL;
+	}
+
+	/* Fill trailing defaults so the args array covers every parameter. */
+	zend_type filled[ZEND_GENERIC_MAX_PARAMS];
+	uint32_t total = params->count;
+	if (arity > total) {
+		return NULL;
+	}
+	if (arity < total) {
+		for (uint32_t i = 0; i < arity; i++) filled[i] = args[i];
+		for (uint32_t i = arity; i < total; i++) {
+			const zend_generic_parameter *p = ¶ms->parameters[i];
+			const zend_type *def = ZEND_TYPE_IS_SET(p->default_pre_erasure)
+				? &p->default_pre_erasure
+				: (ZEND_TYPE_IS_SET(p->default_type) ? &p->default_type : NULL);
+			if (!def) {
+				return NULL;
+			}
+			filled[i] = *def;
+		}
+		args = filled;
+		arity = total;
+	}
+
+	/* A remaining type parameter means this isn't a concrete instantiation. */
+	for (uint32_t i = 0; i < arity; i++) {
+		if (zend_type_contains_type_parameter(args[i])) {
+			return NULL;
+		}
+	}
+
+	zend_string *display_name = zend_generic_canonical_class_name(
+		base->common.function_name, args, arity);
+	zend_string *lc_name = zend_string_tolower(display_name);
+
+	zend_function *existing = zend_hash_find_ptr(EG(function_table), lc_name);
+	if (existing) {
+		zend_string_release(display_name);
+		zend_string_release(lc_name);
+		return existing;
+	}
+
+	zend_arg_info *new_arg_info = zend_monomorph_build_arg_info(&base->op_array, args, arity);
+
+	zend_op_array *mono = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
+	memcpy(mono, &base->op_array, sizeof(zend_op_array));
+
+	/* Invariant concrete type-arg table, shared across all calls to this monomorph
+	 * so the body's own T-refs resolve under by-name dispatch. Arena-allocated and
+	 * marked persisted so the refcount==NULL monomorph teardown never frees it. */
+	zend_type_arg_table *mono_targs = NULL;
+	{
+		uint32_t tcount = params->count;
+		mono_targs = zend_arena_alloc(&CG(arena), ZEND_TYPE_ARG_TABLE_SIZE(tcount));
+		mono_targs->count = tcount;
+		mono_targs->generation = 0;
+		mono_targs->persisted = true;
+		for (uint32_t i = 0; i < tcount; i++) {
+			mono_targs->entries[i].name = NULL;
+			mono_targs->entries[i].type_ref = NULL;
+			mono_targs->entries[i].owned_type = (zend_type) ZEND_TYPE_INIT_NONE(0);
+			if (i < arity && ZEND_TYPE_IS_SET(args[i])) {
+				zend_type owned = args[i];
+				zend_type_copy_ctor(&owned, /* use_arena */ true, /* persistent */ false);
+				mono_targs->entries[i].owned_type = owned;
+				zend_string *cname = zend_type_arg_canonical_name(args[i]);
+				mono_targs->entries[i].name = cname;
+			}
+		}
+	}
+
+	{
+		zend_generic_type_table *gt = zend_arena_alloc(&CG(arena), sizeof(zend_generic_type_table));
+		memset(gt, 0, sizeof(*gt));
+		if (base->op_array.generic_types && base->op_array.generic_types->turbofish_args) {
+			gt->turbofish_args = base->op_array.generic_types->turbofish_args;
+		}
+		gt->persisted = true;
+		gt->monomorph_type_args = mono_targs;
+		mono->generic_types = gt;
+	}
+	mono->fn_flags2 |= ZEND_ACC2_MONOMORPH_TYPE_ARGS;
+
+	/* refcount==NULL: destroy_op_array won't free the shared body buffers. */
+	mono->refcount = NULL;
+	mono->fn_flags &= ~(ZEND_ACC_IMMUTABLE | ZEND_ACC_HEAP_RT_CACHE | ZEND_ACC_PRELOADED);
+	/* TRAIT_CLONE forces RECV onto the slow path that checks the substituted
+	 * arg_info (the shared RECV opcodes carry the base's erased type mask). */
+	mono->fn_flags |= ZEND_ACC_TRAIT_CLONE;
+
+	/* Keep the base name so TypeError messages match the erased path; the mangled
+	 * name is only the EG(function_table) key. */
+	mono->function_name = zend_string_copy(base->op_array.function_name);
+	if (new_arg_info) {
+		mono->arg_info = new_arg_info;
+	}
+
+	ZEND_MAP_PTR_INIT(mono->run_time_cache, NULL);
+	ZEND_MAP_PTR_INIT(mono->static_variables_ptr, NULL);
+
+	/* Allocate the runtime cache now: the call swaps to this op_array before
+	 * DO_FCALL, whose hot path reads RUN_TIME_CACHE without lazy allocation. */
+	zend_init_func_run_time_cache(mono);
+
+	zend_function *mono_fn = (zend_function *) mono;
+	if (!zend_hash_add_ptr(EG(function_table), lc_name, mono_fn)) {
+		existing = zend_hash_find_ptr(EG(function_table), lc_name);
+		zend_string_release(display_name);
+		zend_string_release(lc_name);
+		zend_string_release(mono->function_name);
+		return existing;
+	}
+
+	zend_string_release(display_name);
+	zend_string_release(lc_name);
+	return mono_fn;
+}
+
+ZEND_API zend_function *zend_try_synthesize_function_monomorph_by_name(zend_string *lc_name)
+{
+	size_t lt_pos, args_len;
+	if (!zend_mp_split_name(lc_name, <_pos, &args_len)) return NULL;
+
+	zend_string *base_lc = zend_string_init(ZSTR_VAL(lc_name), lt_pos, 0);
+	zend_function *base = zend_hash_find_ptr(EG(function_table), base_lc);
+	zend_string_release(base_lc);
+	if (!base || base->type != ZEND_USER_FUNCTION || !base->op_array.generic_parameters) {
+		return NULL;
+	}
+
+	zend_monomorph_parser parser = {
+		.p = ZSTR_VAL(lc_name) + lt_pos + 1,
+		.end = ZSTR_VAL(lc_name) + ZSTR_LEN(lc_name) - 1,
+		.error = false,
+	};
+	uint32_t cap = 4, count = 0;
+	zend_type *args = emalloc(sizeof(zend_type) * cap);
+	do {
+		if (count == cap) { cap *= 2; args = erealloc(args, sizeof(zend_type) * cap); }
+		args[count++] = zend_mp_parse_type(&parser);
+		if (parser.error) break;
+	} while (zend_mp_eat(&parser, ','));
+	zend_mp_skip_ws(&parser);
+	if (parser.error || parser.p != parser.end) {
+		for (uint32_t i = 0; i < count; i++) zend_type_release(args[i], false);
+		efree(args);
+		return NULL;
+	}
+
+	/* The by-name call skipped ZEND_VERIFY_GENERIC_ARGUMENTS, so enforce arity and
+	 * bounds here (once); the monomorph's RECV opcodes cover per-argument checks. */
+	zend_type args_box = ZEND_TYPE_INIT_NONE(0);
+	zend_type_named_with_args *nwa =
+		emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(count));
+	nwa->name = NULL;
+	nwa->name_attr = 0;
+	nwa->count = count;
+	for (uint32_t i = 0; i < count; i++) nwa->args[i] = args[i];
+	ZEND_TYPE_SET_PTR(args_box, nwa);
+	ZEND_TYPE_FULL_MASK(args_box) |= _ZEND_TYPE_NAMED_WITH_ARGS_BIT;
+	zend_check_generic_call_arguments(base, count, &args_box);
+	efree(nwa);
+	if (UNEXPECTED(EG(exception))) {
+		for (uint32_t i = 0; i < count; i++) zend_type_release(args[i], false);
+		efree(args);
+		return NULL;
+	}
+
+	zend_function *mono = zend_synthesize_function_monomorph(base, args, count);
+	for (uint32_t i = 0; i < count; i++) zend_type_release(args[i], false);
+	efree(args);
+	return mono;
+}
diff --git a/Zend/zend_inheritance.h b/Zend/zend_inheritance.h
index 7171a9385f3b..86f1460bbba0 100644
--- a/Zend/zend_inheritance.h
+++ b/Zend/zend_inheritance.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -25,8 +24,34 @@
 
 BEGIN_EXTERN_C()
 
+typedef enum {
+	INHERITANCE_UNRESOLVED = -1,
+	INHERITANCE_ERROR = 0,
+	INHERITANCE_WARNING = 1,
+	INHERITANCE_SUCCESS = 2,
+} zend_inheritance_status;
+
+typedef struct _zend_inheritance_binding_cache {
+	const zend_class_entry *ce;
+	const zend_class_entry *target;
+	uint32_t arity;
+	bool present;
+	bool valid;
+	zend_type args[ZEND_GENERIC_MAX_PARAMS];
+} zend_inheritance_binding_cache;
+
 ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface);
 ZEND_API void zend_do_inheritance_ex(zend_class_entry *ce, zend_class_entry *parent_ce, bool checked);
+ZEND_API void zend_type_copy_ctor(zend_type *const type, bool use_arena, bool persistent);
+ZEND_API zend_inheritance_status zend_check_generic_arg_satisfies_bound(
+		zend_class_entry *arg_scope, zend_type arg,
+		zend_class_entry *bound_scope, zend_type bound);
+ZEND_API bool zend_get_inheritance_binding_full(
+		const zend_class_entry *ce,
+		const zend_class_entry *target,
+		zend_type *out_args,
+		uint32_t out_capacity,
+		uint32_t *out_arity);
 
 static zend_always_inline void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce) {
 	zend_do_inheritance_ex(ce, parent_ce, 0);
@@ -34,22 +59,77 @@ static zend_always_inline void zend_do_inheritance(zend_class_entry *ce, zend_cl
 
 ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string *lc_parent_name, const zend_string *key);
 
+/* Monomorphization: synthesize a generic class application as a real
+ * class_entry registered in EG(class_table) under the canonical name. The
+ * synthesized class extends `base` with the supplied type args, inheriting
+ * all methods/properties/constants with proper substitution.
+ *
+ * Idempotent: a second call with the same (base, args) canonicalizing to an
+ * existing entry returns that entry. Returns NULL on failure (exception will
+ * be set). The args array is copied; the caller retains ownership. */
+ZEND_API zend_class_entry *zend_synthesize_monomorph(
+	zend_class_entry *base, const zend_type *args, uint32_t arity);
+
+/* Same as zend_synthesize_monomorph, but first resolves any TYPE_PARAMETER refs
+ * in args[] against the currently executing frame's bindings (function-level
+ * via EX()->type_args; class-level via the lexical class's monomorph descendant).
+ * Use at runtime `new` sites where the args originate from an op_array side-table
+ * compiled inside a generic scope and may name enclosing-scope T's by ref.
+ * Static-build callers with already-resolved args keep using the base. */
+ZEND_API zend_class_entry *zend_synthesize_monomorph_resolved(
+	zend_class_entry *base, const zend_type *args, uint32_t arity);
+
+/* For a bare generic class `base`, synthesize (or return the cached) monomorph
+ * built from the parameters' declared defaults. Returns NULL and throws Error
+ * if any parameter has no default. If `base` is itself a monomorph (no
+ * generic_parameters), returns `base` unchanged. Used by ZEND_NEW for the
+ * `new static()` and dynamic `new $name()` paths. */
+ZEND_API zend_class_entry *zend_get_defaults_monomorph(zend_class_entry *base);
+
+/* True when the name has monomorph-canonical shape (contains `<`). The canonical
+ * encoding for synthesized monomorphs embeds `<...>` in the class name, which is
+ * invalid in any user-declared class. Use these helpers rather than open-coding
+ * the memchr check so the encoding stays in one place. */
+static zend_always_inline bool zend_class_name_is_monomorph(const zend_string *name)
+{
+	return memchr(ZSTR_VAL(name), '<', ZSTR_LEN(name)) != NULL;
+}
+
+static zend_always_inline bool zend_class_is_monomorph(const zend_class_entry *ce)
+{
+	return zend_class_name_is_monomorph(ce->name);
+}
+
+/* Parses a generic-shaped class-name string ("Box", etc.), looks
+ * up the base class, and synthesizes the monomorph. Returns NULL if the
+ * name doesn't have generic shape, the base isn't generic, or parsing fails.
+ * Used by `zend_lookup_class_ex` to make unserialize, dynamic
+ * `new $name()`, and `class_exists()` all transparently materialize
+ * monomorphs on demand. */
+ZEND_API zend_class_entry *zend_try_synthesize_monomorph_by_name(
+	zend_string *name, uint32_t flags);
+
+ZEND_API zend_type zend_substitute_function_type_param(zend_type t, const zend_type *args, uint32_t arity);
+
+/* Synthesize (or return the cached) concrete specialization of generic function
+ * `base` for the given type args, registered in EG(function_table) as
+ * `base`. Returns NULL when args are not concrete or base isn't generic. */
+ZEND_API zend_function *zend_synthesize_function_monomorph(
+	zend_function *base, const zend_type *args, uint32_t arity);
+
+ZEND_API zend_function *zend_try_synthesize_function_monomorph_by_name(zend_string *lc_name);
+
 void zend_verify_abstract_class(zend_class_entry *ce);
 void zend_build_properties_info_table(zend_class_entry *ce);
 ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_entry *parent_ce, zend_string *lcname, zval *delayed_early_binding);
 
 void zend_inheritance_check_override(const zend_class_entry *ce);
+void zend_check_generic_variance_markers(zend_class_entry *ce);
+void zend_check_function_variance_markers(zend_op_array *op_array);
 
 ZEND_API extern zend_class_entry* (*zend_inheritance_cache_get)(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces);
 ZEND_API extern zend_class_entry* (*zend_inheritance_cache_add)(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies);
 
-typedef enum {
-	INHERITANCE_UNRESOLVED = -1,
-	INHERITANCE_ERROR = 0,
-	INHERITANCE_WARNING = 1,
-	INHERITANCE_SUCCESS = 2,
-} zend_inheritance_status;
-
 ZEND_API zend_inheritance_status zend_verify_property_hook_variance(const zend_property_info *prop_info, const zend_function *func);
 ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error(const zend_property_info *prop_info);
 ZEND_API ZEND_COLD ZEND_NORETURN void zend_hooked_property_variance_error_ex(zend_string *value_param_name, zend_string *class_name, zend_string *prop_name);
diff --git a/Zend/zend_ini.c b/Zend/zend_ini.c
index 199ebfb2e9b4..99df90486632 100644
--- a/Zend/zend_ini.c
+++ b/Zend/zend_ini.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Zeev Suraski                                   |
    +----------------------------------------------------------------------+
@@ -41,7 +40,7 @@ static inline bool zend_is_whitespace(char c) {
  */
 static int zend_remove_ini_entries(zval *el, void *arg) /* {{{ */
 {
-	zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
+	const zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
 	int module_number = *(int *)arg;
 
 	return ini_entry->module_number == module_number;
@@ -70,9 +69,9 @@ static zend_result zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stag
 		}
 		ini_entry->value = ini_entry->orig_value;
 		ini_entry->modifiable = ini_entry->orig_modifiable;
-		ini_entry->modified = 0;
+		ini_entry->modified = false;
 		ini_entry->orig_value = NULL;
-		ini_entry->orig_modifiable = 0;
+		ini_entry->orig_modifiable = false;
 	}
 	return SUCCESS;
 }
@@ -82,12 +81,12 @@ static void free_ini_entry(zval *zv) /* {{{ */
 {
 	zend_ini_entry *entry = (zend_ini_entry*)Z_PTR_P(zv);
 
-	zend_string_release_ex(entry->name, 1);
+	zend_string_release_ex(entry->name, true);
 	if (entry->value) {
 		zend_string_release(entry->value);
 	}
 	if (entry->orig_value) {
-		zend_string_release_ex(entry->orig_value, 1);
+		zend_string_release_ex(entry->orig_value, true);
 	}
 	free(entry);
 }
@@ -103,7 +102,7 @@ ZEND_API void zend_ini_startup(void) /* {{{ */
 	EG(ini_directives) = registered_zend_ini_directives;
 	EG(modified_ini_directives) = NULL;
 	EG(error_reporting_ini_entry) = NULL;
-	zend_hash_init(registered_zend_ini_directives, 128, NULL, free_ini_entry, 1);
+	zend_hash_init(registered_zend_ini_directives, 128, NULL, free_ini_entry, true);
 }
 /* }}} */
 
@@ -146,18 +145,18 @@ ZEND_API void zend_ini_deactivate(void) /* {{{ */
 static void copy_ini_entry(zval *zv) /* {{{ */
 {
 	zend_ini_entry *old_entry = (zend_ini_entry*)Z_PTR_P(zv);
-	zend_ini_entry *new_entry = pemalloc(sizeof(zend_ini_entry), 1);
+	zend_ini_entry *new_entry = pemalloc(sizeof(zend_ini_entry), true);
 
 	Z_PTR_P(zv) = new_entry;
 	memcpy(new_entry, old_entry, sizeof(zend_ini_entry));
 	if (old_entry->name) {
-		new_entry->name = zend_string_dup(old_entry->name, 1);
+		new_entry->name = zend_string_dup(old_entry->name, true);
 	}
 	if (old_entry->value) {
-		new_entry->value = zend_string_dup(old_entry->value, 1);
+		new_entry->value = zend_string_dup(old_entry->value, true);
 	}
 	if (old_entry->orig_value) {
-		new_entry->orig_value = zend_string_dup(old_entry->orig_value, 1);
+		new_entry->orig_value = zend_string_dup(old_entry->orig_value, true);
 	}
 }
 /* }}} */
@@ -167,7 +166,7 @@ ZEND_API void zend_copy_ini_directives(void) /* {{{ */
 	EG(modified_ini_directives) = NULL;
 	EG(error_reporting_ini_entry) = NULL;
 	EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
-	zend_hash_init(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, free_ini_entry, 1);
+	zend_hash_init(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, free_ini_entry, true);
 	zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, copy_ini_entry);
 }
 /* }}} */
@@ -194,7 +193,7 @@ static int ini_key_compare(Bucket *f, Bucket *s) /* {{{ */
 
 ZEND_API void zend_ini_sort_entries(void) /* {{{ */
 {
-	zend_hash_sort(EG(ini_directives), ini_key_compare, 0);
+	zend_hash_sort(EG(ini_directives), ini_key_compare, false);
 }
 /* }}} */
 
@@ -224,9 +223,9 @@ ZEND_API zend_result zend_register_ini_entries_ex(const zend_ini_entry_def *ini_
 #endif
 
 	while (ini_entry->name) {
-		p = pemalloc(sizeof(zend_ini_entry), 1);
+		p = pemalloc(sizeof(zend_ini_entry), true);
 		p->def = ini_entry;
-		p->name = zend_string_init_interned(ini_entry->name, ini_entry->name_length, 1);
+		p->name = zend_string_init_interned(ini_entry->name, ini_entry->name_length, true);
 		p->on_modify = ini_entry->on_modify;
 		p->mh_arg1 = ini_entry->mh_arg1;
 		p->mh_arg2 = ini_entry->mh_arg2;
@@ -236,25 +235,31 @@ ZEND_API zend_result zend_register_ini_entries_ex(const zend_ini_entry_def *ini_
 		p->displayer = ini_entry->displayer;
 		p->modifiable = ini_entry->modifiable;
 
-		p->orig_modifiable = 0;
-		p->modified = 0;
+		p->orig_modifiable = false;
+		p->modified = false;
 		p->module_number = module_number;
 
 		if (zend_hash_add_ptr(directives, p->name, (void*)p) == NULL) {
 			if (p->name) {
-				zend_string_release_ex(p->name, 1);
+				zend_string_release_ex(p->name, true);
 			}
 			pefree(p, true);
 			zend_unregister_ini_entries_ex(module_number, module_type);
 			return FAILURE;
 		}
+
+		zend_string *prev_value = p->value;
+
 		if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
 		    (!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP) == SUCCESS)) {
 
-			p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
+			/* Skip assigning the value if the handler has already done so. */
+			if (p->value == prev_value) {
+				p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
+			}
 		} else {
 			p->value = ini_entry->value ?
-				zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL;
+				zend_string_init_interned(ini_entry->value, ini_entry->value_length, true) : NULL;
 
 			if (p->on_modify) {
 				p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP);
@@ -326,7 +331,7 @@ ZEND_API void zend_ini_refresh_caches(int stage) /* {{{ */
 ZEND_API zend_result zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage) /* {{{ */
 {
 
-	return zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0);
+	return zend_alter_ini_entry_ex(name, new_value, modify_type, stage, false);
 }
 /* }}} */
 
@@ -336,13 +341,13 @@ ZEND_API zend_result zend_alter_ini_entry_chars(zend_string *name, const char *v
 	zend_string *new_value;
 
 	new_value = zend_string_init(value, value_length, !(stage & ZEND_INI_STAGE_IN_REQUEST));
-	ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0);
+	ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, false);
 	zend_string_release(new_value);
 	return ret;
 }
 /* }}} */
 
-ZEND_API zend_result zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, int force_change) /* {{{ */
+ZEND_API zend_result zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, bool force_change) /* {{{ */
 {
 	zend_result ret;
 	zend_string *new_value;
@@ -380,23 +385,29 @@ ZEND_API zend_result zend_alter_ini_entry_ex(zend_string *name, zend_string *new
 
 	if (!EG(modified_ini_directives)) {
 		ALLOC_HASHTABLE(EG(modified_ini_directives));
-		zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
+		zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, false);
 	}
 	if (!modified) {
 		ini_entry->orig_value = ini_entry->value;
 		ini_entry->orig_modifiable = modifiable;
-		ini_entry->modified = 1;
+		ini_entry->modified = true;
 		zend_hash_add_ptr(EG(modified_ini_directives), ini_entry->name, ini_entry);
 	}
 
+	zend_string *prev_value = ini_entry->value;
 	duplicate = zend_string_copy(new_value);
 
 	if (!ini_entry->on_modify
 		|| ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) {
-		if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
-			zend_string_release(ini_entry->value);
+		if (modified && ini_entry->orig_value != prev_value) { /* we already changed the value, free the changed value */
+			zend_string_release(prev_value);
+		}
+		/* Skip assigning the value if the handler has already done so. */
+		if (ini_entry->value == prev_value) {
+			ini_entry->value = duplicate;
+		} else {
+			zend_string_release(duplicate);
 		}
-		ini_entry->value = duplicate;
 	} else {
 		zend_string_release(duplicate);
 		return FAILURE;
@@ -416,7 +427,7 @@ ZEND_API zend_result zend_restore_ini_entry(zend_string *name, int stage) /* {{{
 	}
 
 	if (EG(modified_ini_directives)) {
-		if (zend_restore_ini_entry_cb(ini_entry, stage) == 0) {
+		if (zend_restore_ini_entry_cb(ini_entry, stage) == SUCCESS) {
 			zend_hash_del(EG(modified_ini_directives), name);
 		} else {
 			return FAILURE;
@@ -445,7 +456,7 @@ ZEND_API zend_result zend_ini_register_displayer(const char *name, uint32_t name
  * Data retrieval
  */
 
-ZEND_API zend_long zend_ini_long(const char *name, size_t name_length, int orig) /* {{{ */
+ZEND_API zend_long zend_ini_long(const char *name, size_t name_length, bool orig) /* {{{ */
 {
 	zend_ini_entry *ini_entry;
 
@@ -462,7 +473,7 @@ ZEND_API zend_long zend_ini_long(const char *name, size_t name_length, int orig)
 }
 /* }}} */
 
-ZEND_API double zend_ini_double(const char *name, size_t name_length, int orig) /* {{{ */
+ZEND_API double zend_ini_double(const char *name, size_t name_length, bool orig) /* {{{ */
 {
 	zend_ini_entry *ini_entry;
 
@@ -479,7 +490,7 @@ ZEND_API double zend_ini_double(const char *name, size_t name_length, int orig)
 }
 /* }}} */
 
-ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, int orig, bool *exists) /* {{{ */
+ZEND_API const char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists) /* {{{ */
 {
 	zend_string *str = zend_ini_str_ex(name, name_length, orig, exists);
 
@@ -487,7 +498,7 @@ ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, int orig
 }
 /* }}} */
 
-ZEND_API char *zend_ini_string(const char *name, size_t name_length, int orig) /* {{{ */
+ZEND_API const char *zend_ini_string(const char *name, size_t name_length, bool orig) /* {{{ */
 {
 	zend_string *str = zend_ini_str(name, name_length, orig);
 
@@ -503,7 +514,7 @@ ZEND_API zend_string *zend_ini_str_ex(const char *name, size_t name_length, bool
 	ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
 	if (ini_entry) {
 		if (exists) {
-			*exists = 1;
+			*exists = true;
 		}
 
 		if (orig && ini_entry->modified) {
@@ -513,7 +524,7 @@ ZEND_API zend_string *zend_ini_str_ex(const char *name, size_t name_length, bool
 		}
 	} else {
 		if (exists) {
-			*exists = 0;
+			*exists = false;
 		}
 		return NULL;
 	}
@@ -522,7 +533,7 @@ ZEND_API zend_string *zend_ini_str_ex(const char *name, size_t name_length, bool
 
 ZEND_API zend_string *zend_ini_str(const char *name, size_t name_length, bool orig) /* {{{ */
 {
-	bool exists = 1;
+	bool exists = true;
 	zend_string *return_value;
 
 	return_value = zend_ini_str_ex(name, name_length, orig, &exists);
@@ -548,13 +559,13 @@ ZEND_API zend_string *zend_ini_get_value(zend_string *name) /* {{{ */
 }
 /* }}} */
 
-ZEND_API bool zend_ini_parse_bool(zend_string *str)
+ZEND_API bool zend_ini_parse_bool(const zend_string *str)
 {
 	if (zend_string_equals_literal_ci(str, "true")
 			|| zend_string_equals_literal_ci(str, "yes")
 			|| zend_string_equals_literal_ci(str, "on")
 	) {
-		return 1;
+		return true;
 	} else {
 		return atoi(ZSTR_VAL(str)) != 0;
 	}
@@ -573,7 +584,7 @@ static const char *zend_ini_consume_quantity_prefix(const char *const digits, co
 		++digits_consumed;
 	}
 
-	if (digits_consumed[0] == '0' && !isdigit(digits_consumed[1])) {
+	if (digits_consumed[0] == '0' && !isdigit((unsigned char)digits_consumed[1])) {
 		/* Value is just 0 */
 		if ((digits_consumed+1) == str_end) {
 			return digits_consumed;
@@ -598,12 +609,12 @@ static const char *zend_ini_consume_quantity_prefix(const char *const digits, co
 	return digits_consumed;
 }
 
-static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_parse_quantity_signed_result_t signed_result, zend_string **errstr) /* {{{ */
+static zend_ulong zend_ini_parse_quantity_internal(const zend_string *value, zend_ini_parse_quantity_signed_result_t signed_result, zend_string **errstr) /* {{{ */
 {
 	char *digits_end = NULL;
-	char *str = ZSTR_VAL(value);
-	char *str_end = &str[ZSTR_LEN(value)];
-	char *digits = str;
+	const char *str = ZSTR_VAL(value);
+	const char *str_end = &str[ZSTR_LEN(value)];
+	const char *digits = str;
 	bool overflow = false;
 	zend_ulong factor;
 	smart_str invalid = {0};
@@ -631,7 +642,7 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
 	}
 
 	/* if there is no digit after +/- */
-	if (!isdigit(digits[0])) {
+	if (!isdigit((unsigned char)digits[0])) {
 		/* Escape the string to avoid null bytes and to make non-printable chars
 		 * visible */
 		smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
@@ -645,7 +656,7 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
 	}
 
 	int base = 0;
-	if (digits[0] == '0' && !isdigit(digits[1])) {
+	if (digits[0] == '0' && !isdigit((unsigned char)digits[1])) {
 		/* Value is just 0 */
 		if ((digits+1) == str_end) {
 			*errstr = NULL;
@@ -832,19 +843,19 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
 }
 /* }}} */
 
-ZEND_API zend_long zend_ini_parse_quantity(zend_string *value, zend_string **errstr) /* {{{ */
+ZEND_API zend_long zend_ini_parse_quantity(const zend_string *value, zend_string **errstr) /* {{{ */
 {
 	return (zend_long) zend_ini_parse_quantity_internal(value, ZEND_INI_PARSE_QUANTITY_SIGNED, errstr);
 }
 /* }}} */
 
-ZEND_API zend_ulong zend_ini_parse_uquantity(zend_string *value, zend_string **errstr) /* {{{ */
+ZEND_API zend_ulong zend_ini_parse_uquantity(const zend_string *value, zend_string **errstr) /* {{{ */
 {
 	return zend_ini_parse_quantity_internal(value, ZEND_INI_PARSE_QUANTITY_UNSIGNED, errstr);
 }
 /* }}} */
 
-ZEND_API zend_long zend_ini_parse_quantity_warn(zend_string *value, zend_string *setting) /* {{{ */
+ZEND_API zend_long zend_ini_parse_quantity_warn(const zend_string *value, zend_string *setting) /* {{{ */
 {
 	zend_string *errstr;
 	zend_long retval = zend_ini_parse_quantity(value, &errstr);
@@ -858,7 +869,7 @@ ZEND_API zend_long zend_ini_parse_quantity_warn(zend_string *value, zend_string
 }
 /* }}} */
 
-ZEND_API zend_ulong zend_ini_parse_uquantity_warn(zend_string *value, zend_string *setting) /* {{{ */
+ZEND_API zend_ulong zend_ini_parse_uquantity_warn(const zend_string *value, zend_string *setting) /* {{{ */
 {
 	zend_string *errstr;
 	zend_ulong retval = zend_ini_parse_uquantity(value, &errstr);
@@ -874,21 +885,14 @@ ZEND_API zend_ulong zend_ini_parse_uquantity_warn(zend_string *value, zend_strin
 
 ZEND_INI_DISP(zend_ini_boolean_displayer_cb) /* {{{ */
 {
-	int value;
-	zend_string *tmp_value;
+	bool value;
 
 	if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
-		tmp_value = (ini_entry->orig_value ? ini_entry->orig_value : NULL );
+		value = zend_ini_parse_bool(ini_entry->orig_value);
 	} else if (ini_entry->value) {
-		tmp_value = ini_entry->value;
-	} else {
-		tmp_value = NULL;
-	}
-
-	if (tmp_value) {
-		value = zend_ini_parse_bool(tmp_value);
+		value = zend_ini_parse_bool(ini_entry->value);
 	} else {
-		value = 0;
+		value = false;
 	}
 
 	if (value) {
@@ -901,7 +905,7 @@ ZEND_INI_DISP(zend_ini_boolean_displayer_cb) /* {{{ */
 
 ZEND_INI_DISP(zend_ini_color_displayer_cb) /* {{{ */
 {
-	char *value;
+	const char *value;
 
 	if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
 		value = ZSTR_VAL(ini_entry->orig_value);
@@ -928,7 +932,7 @@ ZEND_INI_DISP(zend_ini_color_displayer_cb) /* {{{ */
 
 ZEND_INI_DISP(display_link_numbers) /* {{{ */
 {
-	char *value;
+	const char *value;
 
 	if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
 		value = ZSTR_VAL(ini_entry->orig_value);
@@ -951,7 +955,7 @@ ZEND_INI_DISP(display_link_numbers) /* {{{ */
 /* Standard message handlers */
 ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
 {
-	bool *p = (bool *) ZEND_INI_GET_ADDR();
+	bool *p = ZEND_INI_GET_ADDR();
 	*p = zend_ini_parse_bool(new_value);
 	return SUCCESS;
 }
@@ -959,7 +963,7 @@ ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
 
 ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
 {
-	zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
+	zend_long *p = ZEND_INI_GET_ADDR();
 	*p = zend_ini_parse_quantity_warn(new_value, entry->name);
 	return SUCCESS;
 }
@@ -972,7 +976,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
 		return FAILURE;
 	}
 
-	zend_long *p = (zend_long *) ZEND_INI_GET_ADDR();
+	zend_long *p = ZEND_INI_GET_ADDR();
 	*p = tmp;
 
 	return SUCCESS;
@@ -981,7 +985,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
 
 ZEND_API ZEND_INI_MH(OnUpdateReal) /* {{{ */
 {
-	double *p = (double *) ZEND_INI_GET_ADDR();
+	double *p = ZEND_INI_GET_ADDR();
 	*p = zend_strtod(ZSTR_VAL(new_value), NULL);
 	return SUCCESS;
 }
@@ -989,7 +993,7 @@ ZEND_API ZEND_INI_MH(OnUpdateReal) /* {{{ */
 
 ZEND_API ZEND_INI_MH(OnUpdateString) /* {{{ */
 {
-	char **p = (char **) ZEND_INI_GET_ADDR();
+	char **p = ZEND_INI_GET_ADDR();
 	*p = new_value ? ZSTR_VAL(new_value) : NULL;
 	return SUCCESS;
 }
@@ -1001,7 +1005,7 @@ ZEND_API ZEND_INI_MH(OnUpdateStringUnempty) /* {{{ */
 		return FAILURE;
 	}
 
-	char **p = (char **) ZEND_INI_GET_ADDR();
+	char **p = ZEND_INI_GET_ADDR();
 	*p = new_value ? ZSTR_VAL(new_value) : NULL;
 	return SUCCESS;
 }
@@ -1009,7 +1013,7 @@ ZEND_API ZEND_INI_MH(OnUpdateStringUnempty) /* {{{ */
 
 ZEND_API ZEND_INI_MH(OnUpdateStr) /* {{{ */
 {
-	zend_string **p = (zend_string **) ZEND_INI_GET_ADDR();
+	zend_string **p = ZEND_INI_GET_ADDR();
 	*p = new_value;
 	return SUCCESS;
 }
@@ -1021,7 +1025,7 @@ ZEND_API ZEND_INI_MH(OnUpdateStrNotEmpty) /* {{{ */
 		return FAILURE;
 	}
 
-	zend_string **p = (zend_string **) ZEND_INI_GET_ADDR();
+	zend_string **p = ZEND_INI_GET_ADDR();
 	*p = new_value;
 	return SUCCESS;
 }
diff --git a/Zend/zend_ini.h b/Zend/zend_ini.h
index 5a7377f1181d..dbe650675b66 100644
--- a/Zend/zend_ini.h
+++ b/Zend/zend_ini.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Zeev Suraski                                   |
    +----------------------------------------------------------------------+
@@ -58,7 +57,7 @@ struct _zend_ini_entry {
 
 	uint8_t modifiable;
 	uint8_t orig_modifiable;
-	uint8_t modified;
+	bool modified;
 
 	const zend_ini_entry_def *def;
 };
@@ -82,18 +81,24 @@ ZEND_API void zend_ini_refresh_caches(int stage);
 ZEND_API zend_result zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage);
 ZEND_API zend_result zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, bool force_change);
 ZEND_API zend_result zend_alter_ini_entry_chars(zend_string *name, const char *value, size_t value_length, int modify_type, int stage);
-ZEND_API zend_result zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, int force_change);
+ZEND_API zend_result zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, bool force_change);
 ZEND_API zend_result zend_restore_ini_entry(zend_string *name, int stage);
 ZEND_API void display_ini_entries(zend_module_entry *module);
 
-ZEND_API zend_long zend_ini_long(const char *name, size_t name_length, int orig);
-ZEND_API double zend_ini_double(const char *name, size_t name_length, int orig);
-ZEND_API char *zend_ini_string(const char *name, size_t name_length, int orig);
-ZEND_API char *zend_ini_string_ex(const char *name, size_t name_length, int orig, bool *exists);
+ZEND_API zend_long zend_ini_long(const char *name, size_t name_length, bool orig);
+ZEND_API double zend_ini_double(const char *name, size_t name_length, bool orig);
+ZEND_API const char *zend_ini_string(const char *name, size_t name_length, bool orig);
+ZEND_API const char *zend_ini_string_ex(const char *name, size_t name_length, bool orig, bool *exists);
 ZEND_API zend_string *zend_ini_str(const char *name, size_t name_length, bool orig);
 ZEND_API zend_string *zend_ini_str_ex(const char *name, size_t name_length, bool orig, bool *exists);
 ZEND_API zend_string *zend_ini_get_value(zend_string *name);
-ZEND_API bool zend_ini_parse_bool(zend_string *str);
+ZEND_API bool zend_ini_parse_bool(const zend_string *str);
+
+#define zend_ini_bool_literal(name) zend_ini_parse_bool(zend_ini_str((name), sizeof("" name) - 1, false))
+#define zend_ini_long_literal(name) zend_ini_long((name), sizeof("" name) - 1, false)
+#define zend_ini_double_literal(name) zend_ini_double((name), sizeof("" name) - 1, false)
+#define zend_ini_str_literal(name) zend_ini_str((name), sizeof("" name) - 1, false)
+#define zend_ini_string_literal(name) zend_ini_string((name), sizeof("" name) - 1, false)
 
 /**
  * Parses an ini quantity
@@ -130,16 +135,16 @@ ZEND_API bool zend_ini_parse_bool(zend_string *str);
  * In any of these cases an error string is stored in *errstr (caller must
  * release it), otherwise *errstr is set to NULL.
  */
-ZEND_API zend_long zend_ini_parse_quantity(zend_string *value, zend_string **errstr);
+ZEND_API zend_long zend_ini_parse_quantity(const zend_string *value, zend_string **errstr);
 
 /**
  * Unsigned variant of zend_ini_parse_quantity
  */
-ZEND_API zend_ulong zend_ini_parse_uquantity(zend_string *value, zend_string **errstr);
+ZEND_API zend_ulong zend_ini_parse_uquantity(const zend_string *value, zend_string **errstr);
 
-ZEND_API zend_long zend_ini_parse_quantity_warn(zend_string *value, zend_string *setting);
+ZEND_API zend_long zend_ini_parse_quantity_warn(const zend_string *value, zend_string *setting);
 
-ZEND_API zend_ulong zend_ini_parse_uquantity_warn(zend_string *value, zend_string *setting);
+ZEND_API zend_ulong zend_ini_parse_uquantity_warn(const zend_string *value, zend_string *setting);
 
 ZEND_API zend_result zend_ini_register_displayer(const char *name, uint32_t name_length, void (*displayer)(zend_ini_entry *ini_entry, int type));
 
@@ -177,30 +182,20 @@ END_EXTERN_C()
 
 #ifdef ZTS
 #define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id)
+	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr##_id)
 #define STD_ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr, displayer) \
-	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id, displayer)
+	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr##_id, displayer)
 #define STD_ZEND_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id, NULL, zend_ini_boolean_displayer_cb)
+	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr##_id, NULL, zend_ini_boolean_displayer_cb)
 #else
 #define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr)
+	ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr)
 #define STD_ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr, displayer) \
-	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, displayer)
+	ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr, displayer)
 #define STD_ZEND_INI_BOOLEAN(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
-	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr, NULL, zend_ini_boolean_displayer_cb)
+	ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, (void *) offsetof(struct_type, property_name), (void *) &struct_ptr, NULL, zend_ini_boolean_displayer_cb)
 #endif
 
-#define INI_INT(name) zend_ini_long((name), strlen(name), 0)
-#define INI_FLT(name) zend_ini_double((name), strlen(name), 0)
-#define INI_STR(name) zend_ini_string_ex((name), strlen(name), 0, NULL)
-#define INI_BOOL(name) ((bool) INI_INT(name))
-
-#define INI_ORIG_INT(name)	zend_ini_long((name), strlen(name), 1)
-#define INI_ORIG_FLT(name)	zend_ini_double((name), strlen(name), 1)
-#define INI_ORIG_STR(name)	zend_ini_string((name), strlen(name), 1)
-#define INI_ORIG_BOOL(name) ((bool) INI_ORIG_INT(name))
-
 #define REGISTER_INI_ENTRIES() zend_register_ini_entries_ex(ini_entries, module_number, type)
 #define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries_ex(module_number, type)
 #define DISPLAY_INI_ENTRIES() display_ini_entries(zend_module)
@@ -257,6 +252,6 @@ typedef struct _zend_ini_parser_param {
 # define ZEND_INI_GET_BASE() ((char *) ts_resource(*((int *) mh_arg2)))
 #endif
 
-#define ZEND_INI_GET_ADDR() (ZEND_INI_GET_BASE() + (size_t) mh_arg1)
+#define ZEND_INI_GET_ADDR() ((void*)(ZEND_INI_GET_BASE() + (size_t) mh_arg1))
 
 #endif /* ZEND_INI_H */
diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y
index 07df7be88e8c..d35853ab5acd 100644
--- a/Zend/zend_ini_parser.y
+++ b/Zend/zend_ini_parser.y
@@ -4,15 +4,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Zeev Suraski                                  |
    |          Jani Taskinen                                 |
@@ -57,7 +56,7 @@ static int get_int_val(zval *op) {
 			zend_string_free(Z_STR_P(op));
 			return val;
 		}
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 
@@ -205,7 +204,7 @@ static ZEND_COLD void ini_error(const char *msg)
 		error_buf_len = 128 + (int)strlen(msg) + (int)strlen(currently_parsed_filename); /* should be more than enough */
 		error_buf = (char *) emalloc(error_buf_len);
 
-		sprintf(error_buf, "%s in %s on line %d\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno());
+		sprintf(error_buf, "%s in %s on line %" PRIu32 "\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno());
 	} else {
 		error_buf = estrdup("Invalid configuration directive\n");
 	}
@@ -353,7 +352,7 @@ static void normalize_value(zval *zv)
 %left '|' '&' '^'
 %precedence '~' '!'
 
-%destructor { zval_ini_dtor(&$$); } TC_RAW TC_CONSTANT TC_NUMBER TC_STRING TC_WHITESPACE TC_LABEL TC_OFFSET TC_VARNAME BOOL_TRUE BOOL_FALSE NULL_NULL cfg_var_ref constant_literal constant_string encapsed_list expr option_offset section_string_or_value string_or_value var_string_list var_string_list_section
+%destructor { zval_ini_dtor(&$$); } TC_RAW TC_CONSTANT TC_NUMBER TC_STRING TC_WHITESPACE TC_LABEL TC_OFFSET TC_VARNAME BOOL_TRUE BOOL_FALSE NULL_NULL cfg_var_ref constant_literal constant_string encapsed_list expr fallback option_offset section_string_or_value string_or_value var_string_list var_string_list_section
 
 %%
 
diff --git a/Zend/zend_ini_scanner.h b/Zend/zend_ini_scanner.h
index 62546413c7cb..c013564a10f4 100644
--- a/Zend/zend_ini_scanner.h
+++ b/Zend/zend_ini_scanner.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -30,7 +29,7 @@ typedef struct _zend_file_handle zend_file_handle;
 #define ZEND_INI_SCANNER_TYPED  2 /* Typed mode. */
 
 BEGIN_EXTERN_C()
-ZEND_COLD int zend_ini_scanner_get_lineno(void);
+ZEND_COLD uint32_t zend_ini_scanner_get_lineno(void);
 ZEND_COLD const char *zend_ini_scanner_get_filename(void);
 zend_result zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode);
 zend_result zend_ini_prepare_string_for_scanning(const char *str, int scanner_mode);
diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l
index 44159297a04e..7fd51654ac82 100644
--- a/Zend/zend_ini_scanner.l
+++ b/Zend/zend_ini_scanner.l
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Zeev Suraski                                  |
    |          Jani Taskinen                                 |
@@ -145,10 +144,10 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
 	if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED &&            \
 		(YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW))) {\
 		zend_ini_copy_typed_value(ini_lval, type, str, len);       \
-		Z_EXTRA_P(ini_lval) = 0;                                   \
 	} else {                                                       \
 		zend_ini_copy_value(ini_lval, str, len);                   \
 	}                                                              \
+	Z_EXTRA_P(ini_lval) = 0;                                       \
 	return type;                                                   \
 }
 
@@ -230,7 +229,7 @@ void shutdown_ini_scanner(void)
 /* }}} */
 
 /* {{{ zend_ini_scanner_get_lineno() */
-ZEND_COLD int zend_ini_scanner_get_lineno(void)
+ZEND_COLD uint32_t zend_ini_scanner_get_lineno(void)
 {
 	return SCNG(lineno);
 }
@@ -352,16 +351,16 @@ restart:
 /*!re2c
 re2c:yyfill:check = 0;
 LNUM [0-9]+
-DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
+DNUM ([0-9]*[.][0-9]+)|([0-9]+[.][0-9]*)
 NUMBER [-]?{LNUM}|{DNUM}
 ANY_CHAR (.|[\n\t])
 NEWLINE	("\r"|"\n"|"\r\n")
 TABS_AND_SPACES [ \t]
 WHITESPACE [ \t]+
 CONSTANT [a-zA-Z_][a-zA-Z0-9_]*
-LABEL_CHAR [^=\n\r\t;&|^$~(){}!"\[\]\x00]
+LABEL_CHAR [^=\n\r\t;&|^$~(){}!"[\]\x00]
 LABEL ({LABEL_CHAR}+)
-TOKENS [:,.\[\]"'()&|^+-/*=%$!~<>?@{}]
+TOKENS [:,.[\]"'()&|^+-/*=%$!~<>?@{}]
 OPERATORS [&|^~()!]
 DOLLAR_CURLY "${"
 
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index ce9cc00fdfb9..49169dfca234 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    +----------------------------------------------------------------------+
@@ -496,7 +495,7 @@ static zend_object *zend_internal_iterator_create(zend_class_entry *ce) {
 	zend_internal_iterator *intern = emalloc(sizeof(zend_internal_iterator));
 	zend_object_std_init(&intern->std, ce);
 	intern->iter = NULL;
-	intern->rewind_called = 0;
+	intern->rewind_called = false;
 	return &intern->std;
 }
 
@@ -537,7 +536,7 @@ static zend_internal_iterator *zend_internal_iterator_fetch(zval *This) {
 static zend_result zend_internal_iterator_ensure_rewound(zend_internal_iterator *intern) {
 	if (!intern->rewind_called) {
 		zend_object_iterator *iter = intern->iter;
-		intern->rewind_called = 1;
+		intern->rewind_called = true;
 		if (iter->funcs->rewind) {
 			iter->funcs->rewind(iter);
 			if (UNEXPECTED(EG(exception))) {
@@ -630,7 +629,7 @@ ZEND_METHOD(InternalIterator, rewind) {
 		RETURN_THROWS();
 	}
 
-	intern->rewind_called = 1;
+	intern->rewind_called = true;
 	if (!intern->iter->funcs->rewind) {
 		/* Allow calling rewind() if no iteration has happened yet,
 		 * even if the iterator does not support rewinding. */
diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h
index 883e482f510c..3aeac4fc8146 100644
--- a/Zend/zend_interfaces.h
+++ b/Zend/zend_interfaces.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_interfaces_arginfo.h b/Zend/zend_interfaces_arginfo.h
index 8a90166b2d80..836313e4f41b 100644
--- a/Zend/zend_interfaces_arginfo.h
+++ b/Zend/zend_interfaces_arginfo.h
@@ -1,4 +1,4 @@
-/* This is a generated file, edit the .stub.php file instead.
+/* This is a generated file, edit zend_interfaces.stub.php instead.
  * Stub hash: a9c915c11e5989d8c7cf2d704ada09ca765670c3 */
 
 ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IteratorAggregate_getIterator, 0, 0, Traversable, 0)
diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c
index f67033b11161..c05434486f89 100644
--- a/Zend/zend_iterators.c
+++ b/Zend/zend_iterators.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    |         Marcus Boerger                                |
@@ -31,6 +30,7 @@ static const zend_object_handlers iterator_object_handlers = {
 	iter_wrapper_free,
 	iter_wrapper_dtor,
 	NULL, /* clone_obj */
+	NULL, /* clone_obj_with */
 	NULL, /* prop read */
 	NULL, /* prop write */
 	NULL, /* read dim */
diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h
index 75549188ed6b..973903768405 100644
--- a/Zend/zend_iterators.h
+++ b/Zend/zend_iterators.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Wez Furlong                            |
    |         Marcus Boerger                                |
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 816b8126cbf2..96bf9f015e5b 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -3,15 +3,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -51,6 +50,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %destructor { zend_ast_destroy($$); } 
 %destructor { if ($$) zend_string_release_ex($$, 0); } 
 
+%precedence PREC_NO_TYPE_ARGS
 %precedence T_THROW
 %precedence PREC_ARROW_FUNCTION
 %precedence T_INCLUDE T_INCLUDE_ONCE T_REQUIRE T_REQUIRE_ONCE
@@ -212,7 +212,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %token T_INC "'++'"
 %token T_DEC "'--'"
 %token T_INT_CAST    "'(int)'"
-%token T_DOUBLE_CAST "'(double)'"
+%token T_DOUBLE_CAST "'(float)'"
 %token T_STRING_CAST "'(string)'"
 %token T_ARRAY_CAST  "'(array)'"
 %token T_OBJECT_CAST "'(object)'"
@@ -233,6 +233,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %token T_DOLLAR_OPEN_CURLY_BRACES "'${'"
 %token T_CURLY_OPEN      "'{$'"
 %token T_PAAMAYIM_NEKUDOTAYIM "'::'"
+%token T_TURBOFISH       "'::<'"
 %token T_NS_SEPARATOR    "'\\'"
 %token T_ELLIPSIS        "'...'"
 %token T_COALESCE        "'??'"
@@ -259,7 +260,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %type  unprefixed_use_declarations const_decl inner_statement
 %type  expr optional_expr while_statement for_statement foreach_variable
 %type  foreach_statement declare_statement finally_statement unset_variable variable
-%type  extends_from parameter optional_type_without_static argument global_var
+%type  extends_from parameter optional_type_without_static argument argument_no_expr global_var
 %type  static_var class_statement trait_adaptation trait_precedence trait_alias
 %type  absolute_trait_method_reference trait_method_reference property echo_expr
 %type  new_dereferenceable new_non_dereferenceable anonymous_class class_name class_name_reference simple_variable
@@ -287,7 +288,17 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %type  enum_declaration_statement enum_backing_type enum_case enum_case_expr
 %type  function_name non_empty_member_modifiers
 %type  property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body
-%type  optional_parameter_list
+%type  optional_parameter_list clone_argument_list non_empty_clone_argument_list
+
+%type  optional_generic_type_parameter_list generic_type_parameter_list
+%type  generic_type_parameter_list_inner generic_type_parameter
+%type  optional_generic_type_parameter_bound optional_generic_type_parameter_default
+%type  optional_generic_type_argument_list generic_type_argument_list
+%type  generic_type_argument_list_inner
+%type  optional_call_type_argument_list call_type_argument_list call_type_argument_list_inner
+%type  bound_class_name bound_class_name_reference
+
+%type  optional_generic_variance
 
 %type  returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers
 %type  method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers
@@ -365,10 +376,18 @@ name:
 ;
 
 attribute_decl:
-		class_name
-			{ $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, NULL); }
-	|	class_name argument_list
-			{ $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, $2); }
+		class_name optional_call_type_argument_list
+			{
+				uint32_t _ga = $2 ? zend_ast_get_list($2)->children : 0;
+				$$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, NULL, $2);
+				$$->attr = (zend_ast_attr) _ga;
+			}
+	|	class_name optional_call_type_argument_list argument_list
+			{
+				uint32_t _ga = $2 ? zend_ast_get_list($2)->children : 0;
+				$$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, $3, $2);
+				$$->attr = (zend_ast_attr) _ga;
+			}
 ;
 
 attribute_group:
@@ -379,7 +398,7 @@ attribute_group:
 ;
 
 attribute:
-		T_ATTRIBUTE attribute_group possible_comma ']'	{ $$ = $2; }
+		T_ATTRIBUTE backup_doc_comment attribute_group possible_comma ']'	{ $$ = $3; CG(doc_comment) = $2; }
 ;
 
 attributes:
@@ -552,8 +571,8 @@ catch_list:
 ;
 
 catch_name_list:
-		class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
-	|	catch_name_list '|' class_name { $$ = zend_ast_list_add($1, $3); }
+		bound_class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
+	|	catch_name_list '|' bound_class_name { $$ = zend_ast_list_add($1, $3); }
 ;
 
 optional_variable:
@@ -585,10 +604,10 @@ function_name:
 ;
 
 function_declaration_statement:
-	function returns_ref function_name backup_doc_comment '(' parameter_list ')' return_type
+	function returns_ref function_name optional_generic_type_parameter_list backup_doc_comment '(' parameter_list ')' return_type
 	backup_fn_flags '{' inner_statement_list '}' backup_fn_flags
-		{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4,
-		      zend_ast_get_str($3), $6, NULL, $11, $8, NULL); CG(extra_fn_flags) = $9; }
+		{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $14, $1, $5,
+		      zend_ast_get_str($3), $7, NULL, $12, $9, NULL, $4); CG(extra_fn_flags) = $10; }
 ;
 
 is_reference:
@@ -603,11 +622,11 @@ is_variadic:
 
 class_declaration_statement:
 		class_modifiers T_CLASS { $$ = CG(zend_lineno); }
-		T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
-			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $3, $7, zend_ast_get_str($4), $5, $6, $9, NULL, NULL); }
+		T_STRING optional_generic_type_parameter_list extends_from implements_list backup_doc_comment '{' class_statement_list '}'
+			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $3, $8, zend_ast_get_str($4), $6, $7, $10, NULL, NULL, $5); }
 	|	T_CLASS { $$ = CG(zend_lineno); }
-		T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
-			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $2, $6, zend_ast_get_str($3), $4, $5, $8, NULL, NULL); }
+		T_STRING optional_generic_type_parameter_list extends_from implements_list backup_doc_comment '{' class_statement_list '}'
+			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $2, $7, zend_ast_get_str($3), $5, $6, $9, NULL, NULL, $4); }
 ;
 
 class_modifiers:
@@ -636,20 +655,20 @@ class_modifier:
 
 trait_declaration_statement:
 		T_TRAIT { $$ = CG(zend_lineno); }
-		T_STRING backup_doc_comment '{' class_statement_list '}'
-			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, $2, $4, zend_ast_get_str($3), NULL, NULL, $6, NULL, NULL); }
+		T_STRING optional_generic_type_parameter_list backup_doc_comment '{' class_statement_list '}'
+			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_TRAIT, $2, $5, zend_ast_get_str($3), NULL, NULL, $7, NULL, NULL, $4); }
 ;
 
 interface_declaration_statement:
 		T_INTERFACE { $$ = CG(zend_lineno); }
-		T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}'
-			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $2, $5, zend_ast_get_str($3), NULL, $4, $7, NULL, NULL); }
+		T_STRING optional_generic_type_parameter_list interface_extends_list backup_doc_comment '{' class_statement_list '}'
+			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_INTERFACE, $2, $6, zend_ast_get_str($3), NULL, $5, $8, NULL, NULL, $4); }
 ;
 
 enum_declaration_statement:
 		T_ENUM { $$ = CG(zend_lineno); }
 		T_STRING enum_backing_type implements_list backup_doc_comment '{' class_statement_list '}'
-			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_ENUM|ZEND_ACC_FINAL, $2, $6, zend_ast_get_str($3), NULL, $5, $8, NULL, $4); }
+			{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_ENUM|ZEND_ACC_FINAL, $2, $6, zend_ast_get_str($3), NULL, $5, $8, NULL, $4, NULL); }
 ;
 
 enum_backing_type:
@@ -669,7 +688,7 @@ enum_case_expr:
 
 extends_from:
 		%empty				{ $$ = NULL; }
-	|	T_EXTENDS class_name	{ $$ = $2; }
+	|	T_EXTENDS bound_class_name	{ $$ = $2; }
 ;
 
 interface_extends_list:
@@ -713,21 +732,20 @@ switch_case_list:
 
 case_list:
 		%empty { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); }
-	|	case_list T_CASE expr case_separator inner_statement_list
+	|	case_list T_CASE expr ':' inner_statement_list
 			{ $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); }
-	|	case_list T_DEFAULT case_separator inner_statement_list
+	|	case_list T_CASE expr ';' inner_statement_list
+			{ $$ = zend_ast_list_add($1, zend_ast_create_ex(ZEND_AST_SWITCH_CASE, ZEND_ALT_CASE_SYNTAX, $3, $5)); }
+	|	case_list T_DEFAULT ':' inner_statement_list
 			{ $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, NULL, $4)); }
-;
-
-case_separator:
-		':'
-	|	';'
+	|	case_list T_DEFAULT ';' inner_statement_list
+			{ $$ = zend_ast_list_add($1, zend_ast_create_ex(ZEND_AST_SWITCH_CASE, ZEND_ALT_CASE_SYNTAX, NULL, $4)); }
 ;
 
 
 match:
 		T_MATCH '(' expr ')' '{' match_arm_list '}'
-			{ $$ = zend_ast_create(ZEND_AST_MATCH, $3, $6); };
+			{ $$ = zend_ast_create(ZEND_AST_MATCH, $3, $6); }
 ;
 
 match_arm_list:
@@ -822,9 +840,9 @@ parameter:
 			{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, NULL,
 					NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $7); }
 	|	optional_cpp_modifiers optional_type_without_static
-		is_reference is_variadic T_VARIABLE backup_doc_comment '=' expr optional_property_hook_list
-			{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $8,
-					NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $9); }
+		is_reference is_variadic T_VARIABLE '=' expr backup_doc_comment optional_property_hook_list
+			{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $7,
+					NULL, $8 ? zend_ast_create_zval_from_str($8) : NULL, $9); }
 ;
 
 optional_type_without_static:
@@ -832,6 +850,94 @@ optional_type_without_static:
 	|	type_expr_without_static	{ $$ = $1; }
 ;
 
+optional_generic_type_parameter_list:
+		%empty                                       { $$ = NULL; }
+	|	generic_type_parameter_list                  { $$ = $1; }
+;
+
+generic_type_parameter_list:
+		'<' { CG(type_arg_depth)++; }
+		generic_type_parameter_list_inner possible_comma '>'
+			{ CG(type_arg_depth)--; zend_check_generic_param_list_size($3); $$ = $3; }
+;
+
+generic_type_parameter_list_inner:
+		generic_type_parameter
+			{ $$ = zend_ast_create_list(1, ZEND_AST_GENERIC_TYPE_PARAMETER_LIST, $1); }
+	|	generic_type_parameter_list_inner ',' generic_type_parameter
+			{ $$ = zend_ast_list_add($1, $3); }
+;
+
+generic_type_parameter:
+		optional_generic_variance T_STRING optional_generic_type_parameter_bound
+		optional_generic_type_parameter_default
+			{ $$ = zend_ast_create_ex(ZEND_AST_GENERIC_TYPE_PARAMETER, $1, $2, $3, $4); }
+;
+
+optional_generic_variance:
+		%empty   { $$ = 0; }
+	|	'+'      { $$ = 1; }
+	|	'-'      { $$ = 2; }
+;
+
+optional_generic_type_parameter_bound:
+		%empty               { $$ = NULL; }
+	|	':' type_expr        { $$ = $2; }
+;
+
+optional_generic_type_parameter_default:
+		%empty               { $$ = NULL; }
+	|	'=' type_expr        { $$ = $2; }
+;
+
+optional_generic_type_argument_list:
+		%empty %prec PREC_NO_TYPE_ARGS               { $$ = NULL; }
+	|	generic_type_argument_list                   { $$ = $1; }
+;
+
+generic_type_argument_list:
+		'<' { CG(type_arg_depth)++; }
+		generic_type_argument_list_inner possible_comma '>'
+			{ CG(type_arg_depth)--; zend_check_generic_arg_list_size($3); $$ = $3; }
+;
+
+generic_type_argument_list_inner:
+		type_expr
+			{ $$ = zend_ast_create_list(1, ZEND_AST_GENERIC_TYPE_ARGUMENT_LIST, $1); }
+	|	generic_type_argument_list_inner ',' type_expr
+			{ $$ = zend_ast_list_add($1, $3); }
+;
+
+optional_call_type_argument_list:
+		%empty                                       { $$ = NULL; }
+	|	call_type_argument_list                      { $$ = $1; }
+;
+
+call_type_argument_list:
+		T_TURBOFISH { CG(type_arg_depth)++; }
+		call_type_argument_list_inner possible_comma '>'
+			{ CG(type_arg_depth)--; zend_check_generic_arg_list_size($3); $$ = $3; }
+;
+
+call_type_argument_list_inner:
+		type_expr
+			{ $$ = zend_ast_create_list(1, ZEND_AST_GENERIC_CALL_TYPE_ARGUMENT_LIST, $1); }
+	|	call_type_argument_list_inner ',' type_expr
+			{ $$ = zend_ast_list_add($1, $3); }
+;
+
+bound_class_name:
+		class_name optional_generic_type_argument_list
+			{ $$ = $2 ? zend_ast_create(ZEND_AST_GENERIC_NAMED_TYPE, $1, $2) : $1; }
+;
+
+bound_class_name_reference:
+		class_name optional_generic_type_argument_list
+			{ $$ = $2 ? zend_ast_create(ZEND_AST_GENERIC_NAMED_TYPE, $1, $2) : $1; }
+	|	new_variable                                      { $$ = $1; }
+	|	'(' expr ')'                                      { $$ = $2; }
+;
+
 type_expr:
 		type				{ $$ = $1; }
 	|	'?' type			{ $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; }
@@ -841,7 +947,9 @@ type_expr:
 
 type:
 		type_without_static	{ $$ = $1; }
-	|	T_STATIC			{ $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_STATIC); }
+	|	T_STATIC optional_generic_type_argument_list
+			{ zend_ast *bare = zend_ast_create_ex(ZEND_AST_TYPE, IS_STATIC);
+			  $$ = $2 ? zend_ast_create(ZEND_AST_GENERIC_NAMED_TYPE, bare, $2) : bare; }
 ;
 
 union_type_element:
@@ -874,7 +982,8 @@ type_expr_without_static:
 type_without_static:
 		T_ARRAY		{ $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); }
 	|	T_CALLABLE	{ $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); }
-	|	name		{ $$ = $1; }
+	|	name optional_generic_type_argument_list
+			{ $$ = $2 ? zend_ast_create(ZEND_AST_GENERIC_NAMED_TYPE, $1, $2) : $1; }
 ;
 
 union_type_without_static_element:
@@ -902,23 +1011,57 @@ return_type:
 ;
 
 argument_list:
-		'(' ')'	{ $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); }
+		'(' ')'	{ $$ = zend_ast_create_arg_list(0, ZEND_AST_ARG_LIST); }
 	|	'(' non_empty_argument_list possible_comma ')' { $$ = $2; }
-	|	'(' T_ELLIPSIS ')' { $$ = zend_ast_create_fcc(); }
 ;
 
 non_empty_argument_list:
 		argument
-			{ $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); }
+			{ $$ = zend_ast_create_arg_list(1, ZEND_AST_ARG_LIST, $1); }
 	|	non_empty_argument_list ',' argument
-			{ $$ = zend_ast_list_add($1, $3); }
+			{ $$ = zend_ast_arg_list_add($1, $3); }
+;
+
+/* `clone_argument_list` is necessary to resolve a parser ambiguity (shift-reduce conflict)
+ * of `clone($expr)`, which could either be parsed as a function call with `$expr` as the first
+ * argument or as a use of the `clone` language construct with an expression with useless
+ * parenthesis. Both would be valid and result in the same AST / the same semantics.
+ * `clone_argument_list` is defined in a way that an `expr` in the first position needs to
+ * be followed by a `,` which is not valid syntax for a parenthesized `expr`, ensuring
+ * that calling `clone()` with a single unnamed parameter is handled by the language construct
+ * syntax.
+ */
+clone_argument_list:
+		'(' ')'	{ $$ = zend_ast_create_arg_list(0, ZEND_AST_ARG_LIST); }
+	|	'(' non_empty_clone_argument_list possible_comma ')' { $$ = $2; }
+	|	'(' expr ',' ')' { $$ = zend_ast_create_arg_list(1, ZEND_AST_ARG_LIST, $2); }
+;
+
+non_empty_clone_argument_list:
+		expr ',' argument
+			{ $$ = zend_ast_create_arg_list(2, ZEND_AST_ARG_LIST, $1, $3); }
+	|	argument_no_expr
+			{ $$ = zend_ast_create_arg_list(1, ZEND_AST_ARG_LIST, $1); }
+	|	non_empty_clone_argument_list ',' argument
+			{ $$ = zend_ast_arg_list_add($1, $3); }
+;
+
+argument_no_expr:
+		identifier ':' expr
+			{ $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); }
+	|	T_ELLIPSIS
+			{ $$ = zend_ast_create_ex(ZEND_AST_PLACEHOLDER_ARG, ZEND_PLACEHOLDER_VARIADIC); }
+	|	'?'
+			{ $$ = zend_ast_create(ZEND_AST_PLACEHOLDER_ARG); }
+	|	identifier ':' '?'
+			{ $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, zend_ast_create(ZEND_AST_PLACEHOLDER_ARG)); }
+	|	T_ELLIPSIS expr
+			{ $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
 ;
 
 argument:
-		expr				{ $$ = $1; }
-	|	identifier ':' expr
-			{ $$ = zend_ast_create(ZEND_AST_NAMED_ARG, $1, $3); }
-	|	T_ELLIPSIS expr	{ $$ = zend_ast_create(ZEND_AST_UNPACK, $2); }
+		expr { $$ = $1; }
+	|	argument_no_expr { $$ = $1; }
 ;
 
 global_var_list:
@@ -963,10 +1106,10 @@ attributed_class_statement:
 	|	class_const_modifiers T_CONST type_expr class_const_list ';'
 			{ $$ = zend_ast_create(ZEND_AST_CLASS_CONST_GROUP, $4, NULL, $3);
 			  $$->attr = $1; }
-	|	method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')'
+	|	method_modifiers function returns_ref identifier optional_generic_type_parameter_list backup_doc_comment '(' parameter_list ')'
 		return_type backup_fn_flags method_body backup_fn_flags
-			{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5,
-				  zend_ast_get_str($4), $7, NULL, $11, $9, NULL); CG(extra_fn_flags) = $10; }
+			{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $13, $2, $6,
+				  zend_ast_get_str($4), $8, NULL, $12, $10, NULL, $5); CG(extra_fn_flags) = $11; }
 	|	enum_case { $$ = $1; }
 ;
 
@@ -978,8 +1121,8 @@ class_statement:
 ;
 
 class_name_list:
-		class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
-	|	class_name_list ',' class_name { $$ = zend_ast_list_add($1, $3); }
+		bound_class_name { $$ = zend_ast_create_list(1, ZEND_AST_NAME_LIST, $1); }
+	|	class_name_list ',' bound_class_name { $$ = zend_ast_list_add($1, $3); }
 ;
 
 trait_adaptations:
@@ -1026,13 +1169,13 @@ trait_alias:
 
 trait_method_reference:
 		identifier
-			{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, NULL, $1); }
+			{ $$ = zend_ast_create(ZEND_AST_TRAIT_METHOD_REFERENCE, NULL, $1); }
 	|	absolute_trait_method_reference { $$ = $1; }
 ;
 
 absolute_trait_method_reference:
 	class_name T_PAAMAYIM_NEKUDOTAYIM identifier
-		{ $$ = zend_ast_create(ZEND_AST_METHOD_REFERENCE, $1, $3); }
+		{ $$ = zend_ast_create(ZEND_AST_TRAIT_METHOD_REFERENCE, $1, $3); }
 ;
 
 method_body:
@@ -1132,7 +1275,7 @@ property_hook:
 		optional_parameter_list backup_fn_flags property_hook_body backup_fn_flags {
 			$$ = zend_ast_create_decl(
 				ZEND_AST_PROPERTY_HOOK, $1 | $2 | $9, $5, $4, zend_ast_get_str($3),
-				$6, NULL, $8, NULL, NULL);
+				$6, NULL, $8, NULL, NULL, NULL);
 			CG(extra_fn_flags) = $7;
 		}
 ;
@@ -1198,14 +1341,14 @@ anonymous_class:
 		extends_from implements_list backup_doc_comment '{' class_statement_list '}' {
 			zend_ast *decl = zend_ast_create_decl(
 				ZEND_AST_CLASS, ZEND_ACC_ANON_CLASS | $1, $3, $7, NULL,
-				$5, $6, $9, NULL, NULL);
-			$$ = zend_ast_create(ZEND_AST_NEW, decl, $4);
+				$5, $6, $9, NULL, NULL, NULL);
+			$$ = zend_ast_create(ZEND_AST_NEW, decl, $4, NULL);
 		}
 ;
 
 new_dereferenceable:
-		T_NEW class_name_reference argument_list
-			{ $$ = zend_ast_create(ZEND_AST_NEW, $2, $3); }
+		T_NEW class_name_reference optional_call_type_argument_list argument_list
+			{ $$ = zend_ast_create(ZEND_AST_NEW, $2, $4, $3); }
 	|	T_NEW anonymous_class
 			{ $$ = $2; }
 	|	T_NEW attributes anonymous_class
@@ -1213,8 +1356,8 @@ new_dereferenceable:
 ;
 
 new_non_dereferenceable:
-		T_NEW class_name_reference
-			{ $$ = zend_ast_create(ZEND_AST_NEW, $2, zend_ast_create_list(0, ZEND_AST_ARG_LIST)); }
+		T_NEW class_name_reference optional_call_type_argument_list
+			{ $$ = zend_ast_create(ZEND_AST_NEW, $2, zend_ast_create_list(0, ZEND_AST_ARG_LIST), $3); }
 ;
 
 expr:
@@ -1228,7 +1371,16 @@ expr:
 			{ $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); }
 	|	variable '=' ampersand variable
 			{ $$ = zend_ast_create(ZEND_AST_ASSIGN_REF, $1, $4); }
-	|	T_CLONE expr { $$ = zend_ast_create(ZEND_AST_CLONE, $2); }
+	|	T_CLONE clone_argument_list {
+			zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CLONE));
+			name->attr = ZEND_NAME_FQ;
+			$$ = zend_ast_create(ZEND_AST_CALL, name, $2, NULL);
+		}
+	|	T_CLONE expr {
+			zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CLONE));
+			name->attr = ZEND_NAME_FQ;
+			$$ = zend_ast_create(ZEND_AST_CALL, name, zend_ast_create_list(1, ZEND_AST_ARG_LIST, $2), NULL);
+		}
 	|	variable T_PLUS_EQUAL expr
 			{ $$ = zend_ast_create_assign_op(ZEND_ADD, $1, $3); }
 	|	variable T_MINUS_EQUAL expr
@@ -1306,11 +1458,12 @@ expr:
 			{ $$ = zend_ast_create(ZEND_AST_GREATER_EQUAL, $1, $3); }
 	|	expr T_SPACESHIP expr
 			{ $$ = zend_ast_create_binary_op(ZEND_SPACESHIP, $1, $3); }
-	|	expr T_INSTANCEOF class_name_reference
+	|	expr T_INSTANCEOF bound_class_name_reference
 			{ $$ = zend_ast_create(ZEND_AST_INSTANCEOF, $1, $3); }
 	|	'(' expr ')' {
 			$$ = $2;
 			if ($$->kind == ZEND_AST_CONDITIONAL) $$->attr = ZEND_PARENTHESIZED_CONDITIONAL;
+			if ($$->kind == ZEND_AST_ARROW_FUNC) $$->attr = ZEND_PARENTHESIZED_ARROW_FUNC;
 		}
 	|	new_dereferenceable { $$ = $1; }
 	|	new_non_dereferenceable { $$ = $1; }
@@ -1331,7 +1484,7 @@ expr:
 	|	T_EXIT ctor_arguments {
 			zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_EXIT));
 			name->attr = ZEND_NAME_FQ;
-			$$ = zend_ast_create(ZEND_AST_CALL, name, $2);
+			$$ = zend_ast_create(ZEND_AST_CALL, name, $2, NULL);
 		}
 	|	'@' expr			{ $$ = zend_ast_create(ZEND_AST_SILENCE, $2); }
 	|	scalar { $$ = $1; }
@@ -1352,16 +1505,16 @@ expr:
 
 
 inline_function:
-		function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type
+		function returns_ref backup_doc_comment optional_generic_type_parameter_list '(' parameter_list ')' lexical_vars return_type
 		backup_fn_flags '{' inner_statement_list '}' backup_fn_flags
-			{ $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, $1, $3,
+			{ $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $14, $1, $3,
 				  NULL,
-				  $5, $7, $11, $8, NULL); CG(extra_fn_flags) = $9; }
-	|	fn returns_ref backup_doc_comment '(' parameter_list ')' return_type
+				  $6, $8, $12, $9, NULL, $4); CG(extra_fn_flags) = $10; }
+	|	fn returns_ref backup_doc_comment optional_generic_type_parameter_list '(' parameter_list ')' return_type
 		T_DOUBLE_ARROW backup_fn_flags backup_lex_pos expr backup_fn_flags
-			{ $$ = zend_ast_create_decl(ZEND_AST_ARROW_FUNC, $2 | $12, $1, $3,
-				  NULL, $5, NULL, $11, $7, NULL);
-				  CG(extra_fn_flags) = $9; }
+			{ $$ = zend_ast_create_decl(ZEND_AST_ARROW_FUNC, $2 | $13, $1, $3,
+				  NULL, $6, NULL, $12, $8, NULL, $4);
+				  CG(extra_fn_flags) = $10; }
 ;
 
 fn:
@@ -1405,20 +1558,20 @@ lexical_var:
 ;
 
 function_call:
-		name argument_list
-			{ $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
+		name optional_call_type_argument_list argument_list
+			{ $$ = zend_ast_create(ZEND_AST_CALL, $1, $3, $2); }
 	|	T_READONLY argument_list {
 			zval zv;
 			if (zend_lex_tstring(&zv, $1) == FAILURE) { YYABORT; }
-			$$ = zend_ast_create(ZEND_AST_CALL, zend_ast_create_zval(&zv), $2);
+			$$ = zend_ast_create(ZEND_AST_CALL, zend_ast_create_zval(&zv), $2, NULL);
 		}
-	|	class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
-			{ $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
-	|	variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
-			{ $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
-	|	callable_expr { $$ = CG(zend_lineno); } argument_list {
-			$$ = zend_ast_create(ZEND_AST_CALL, $1, $3);
-			$$->lineno = $2;
+	|	class_name T_PAAMAYIM_NEKUDOTAYIM member_name optional_call_type_argument_list argument_list
+			{ $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $5, $4); }
+	|	variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name optional_call_type_argument_list argument_list
+			{ $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $5, $4); }
+	|	callable_expr optional_call_type_argument_list { $$ = CG(zend_lineno); } argument_list {
+			$$ = zend_ast_create(ZEND_AST_CALL, $1, $4, $2);
+			$$->lineno = $3;
 		}
 ;
 
@@ -1529,10 +1682,10 @@ callable_variable:
 			{ $$ = zend_ast_create(ZEND_AST_VAR, $1); }
 	|	array_object_dereferenceable '[' optional_expr ']'
 			{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
-	|	array_object_dereferenceable T_OBJECT_OPERATOR property_name argument_list
-			{ $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); }
-	|	array_object_dereferenceable T_NULLSAFE_OBJECT_OPERATOR property_name argument_list
-			{ $$ = zend_ast_create(ZEND_AST_NULLSAFE_METHOD_CALL, $1, $3, $4); }
+	|	array_object_dereferenceable T_OBJECT_OPERATOR property_name optional_call_type_argument_list argument_list
+			{ $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $5, $4); }
+	|	array_object_dereferenceable T_NULLSAFE_OBJECT_OPERATOR property_name optional_call_type_argument_list argument_list
+			{ $$ = zend_ast_create(ZEND_AST_NULLSAFE_METHOD_CALL, $1, $3, $5, $4); }
 	|	function_call { $$ = $1; }
 ;
 
diff --git a/Zend/zend_language_scanner.h b/Zend/zend_language_scanner.h
index 612c84547927..e502d91411b5 100644
--- a/Zend/zend_language_scanner.h
+++ b/Zend/zend_language_scanner.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -20,6 +19,7 @@
 #ifndef ZEND_SCANNER_H
 #define ZEND_SCANNER_H
 
+/* The zend_php_scanner_event enum is declared in zend_globals and we don't want everything to include zend_language_scanner.h */
 #include "zend_globals.h"
 
 typedef struct _zend_lex_state {
@@ -71,7 +71,7 @@ typedef struct _zend_heredoc_label {
 /* Track locations of unclosed {, [, (, etc. for better syntax error reporting */
 typedef struct _zend_nest_location {
 	char text;
-	int  lineno;
+	uint32_t lineno;
 } zend_nest_location;
 
 BEGIN_EXTERN_C()
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index 5e377249422a..cf6ccfe8bbe7 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Marcus Boerger                               |
    |          Nuno Lopes                                 |
@@ -30,6 +29,7 @@
 #include "zend_language_scanner_defs.h"
 
 #include 
+#include 
 #include "zend.h"
 #ifdef ZEND_WIN32
 # include 
@@ -210,6 +210,7 @@ void shutdown_scanner(void)
 	zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
 	SCNG(heredoc_scan_ahead) = 0;
 	SCNG(on_event) = NULL;
+	SCNG(on_event_context) = NULL;
 }
 
 ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state)
@@ -581,13 +582,15 @@ ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle)
 	zend_set_compiled_filename(compiled_filename);
 	zend_string_release_ex(compiled_filename, 0);
 
+	SCNG(on_event) = NULL;
+	SCNG(on_event_context) = NULL;
 	RESET_DOC_COMMENT();
 	CG(zend_lineno) = 1;
 	CG(increment_lineno) = 0;
 	return SUCCESS;
 }
 
-static zend_op_array *zend_compile(int type)
+static zend_op_array *zend_compile(zend_function_type type)
 {
 	zend_op_array *op_array = NULL;
 	bool original_in_compilation = CG(in_compilation);
@@ -597,7 +600,7 @@ static zend_op_array *zend_compile(int type)
 	CG(ast_arena) = zend_arena_create(1024 * 32);
 
 	if (!zendparse()) {
-		int last_lineno = CG(zend_lineno);
+		uint32_t last_lineno = CG(zend_lineno);
 		zend_file_context original_file_context;
 		zend_oparray_context original_oparray_context;
 		zend_op_array *original_active_op_array = CG(active_op_array);
@@ -650,7 +653,17 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type)
 			}
 		}
 	} else {
+		bool orig_record_errors = EG(record_errors);
+		if (!orig_record_errors) {
+			zend_begin_record_errors();
+		}
+
 		op_array = zend_compile(ZEND_USER_FUNCTION);
+
+		if (!orig_record_errors) {
+			zend_emit_recorded_errors();
+			zend_free_recorded_errors();
+		}
 	}
 
 	zend_restore_lexical_state(&original_lex_state);
@@ -756,6 +769,8 @@ ZEND_API void zend_prepare_string_for_scanning(zval *str, zend_string *filename)
 	zend_set_compiled_filename(filename);
 	CG(zend_lineno) = 1;
 	CG(increment_lineno) = 0;
+	SCNG(on_event) = NULL;
+	SCNG(on_event_context) = NULL;
 	RESET_DOC_COMMENT();
 }
 
@@ -911,7 +926,7 @@ ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter
 		ZVAL_STRINGL(zendlval, yytext, yyleng); \
 	}
 
-static zend_result zend_scan_escape_string(zval *zendlval, char *str, int len, char quote_type)
+static zend_result zend_scan_escape_string(zval *zendlval, char *str, size_t len, char quote_type)
 {
 	char *s, *t;
 	char *end;
@@ -921,9 +936,7 @@ static zend_result zend_scan_escape_string(zval *zendlval, char *str, int len, c
 			ZVAL_EMPTY_STRING(zendlval);
 		} else {
 			zend_uchar c = (zend_uchar)*str;
-			if (c == '\n' || c == '\r') {
-				CG(zend_lineno)++;
-			}
+			HANDLE_NEWLINE(c);
 			ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR(c));
 		}
 		goto skip_escape_conversion;
@@ -1127,7 +1140,7 @@ skip_escape_conversion:
 		unsigned char *str;
 		// TODO: avoid realocation ???
 		s = Z_STRVAL_P(zendlval);
-		SCNG(output_filter)(&str, &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval));
+		SCNG(output_filter)(&str, &sz, (unsigned char *)s, Z_STRLEN_P(zendlval));
 		zval_ptr_dtor(zendlval);
 		ZVAL_STRINGL(zendlval, (char *) str, sz);
 		efree(str);
@@ -1159,7 +1172,7 @@ static bool strip_multiline_string_indentation(
 	const char *str = Z_STRVAL_P(zendlval), *end = str + Z_STRLEN_P(zendlval);
 	char *copy = Z_STRVAL_P(zendlval);
 
-	int newline_count = 0;
+	uint32_t newline_count = 0;
 	size_t newline_len;
 	const char *nl;
 
@@ -1240,7 +1253,7 @@ static void copy_heredoc_label_stack(void *void_heredoc_label)
 }
 
 /* Check that { }, [ ], ( ) are nested correctly */
-static void report_bad_nesting(char opening, int opening_lineno, char closing)
+static void report_bad_nesting(char opening, uint32_t opening_lineno, char closing)
 {
 	char   buf[256];
 	size_t used = 0;
@@ -1348,7 +1361,7 @@ int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem)
 {
 int token;
 int offset;
-int start_line = CG(zend_lineno);
+uint32_t start_line = CG(zend_lineno);
 
 	ZVAL_UNDEF(zendlval);
 restart:
@@ -1597,6 +1610,10 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
 	RETURN_TOKEN_WITH_STR(T_STRING, 0);
 }
 
+"::<" {
+	RETURN_TOKEN(T_TURBOFISH);
+}
+
 "::" {
 	RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM);
 }
@@ -1621,11 +1638,31 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
 	RETURN_TOKEN_WITH_IDENT(T_VAR);
 }
 
-"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" {
+"("{TABS_AND_SPACES}("int"){TABS_AND_SPACES}")" {
 	RETURN_TOKEN(T_INT_CAST);
 }
 
-"("{TABS_AND_SPACES}("double"|"float"){TABS_AND_SPACES}")" {
+"("{TABS_AND_SPACES}("integer"){TABS_AND_SPACES}")" {
+	if (PARSER_MODE()) {
+		zend_error(E_DEPRECATED, "Non-canonical cast (integer) is deprecated, use the (int) cast instead");
+		if (EG(exception)) {
+			RETURN_TOKEN(T_ERROR);
+		}
+	}
+	RETURN_TOKEN(T_INT_CAST);
+}
+
+"("{TABS_AND_SPACES}("float"){TABS_AND_SPACES}")" {
+	RETURN_TOKEN(T_DOUBLE_CAST);
+}
+
+"("{TABS_AND_SPACES}("double"){TABS_AND_SPACES}")" {
+	if (PARSER_MODE()) {
+		zend_error(E_DEPRECATED, "Non-canonical cast (double) is deprecated, use the (float) cast instead");
+		if (EG(exception)) {
+			RETURN_TOKEN(T_ERROR);
+		}
+	}
 	RETURN_TOKEN(T_DOUBLE_CAST);
 }
 
@@ -1637,7 +1674,17 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
 	RETURN_TOKEN(T_DOUBLE_CAST);
 }
 
-"("{TABS_AND_SPACES}("string"|"binary"){TABS_AND_SPACES}")" {
+"("{TABS_AND_SPACES}("string"){TABS_AND_SPACES}")" {
+	RETURN_TOKEN(T_STRING_CAST);
+}
+
+"("{TABS_AND_SPACES}("binary"){TABS_AND_SPACES}")" {
+	if (PARSER_MODE()) {
+		zend_error(E_DEPRECATED, "Non-canonical cast (binary) is deprecated, use the (string) cast instead");
+		if (EG(exception)) {
+			RETURN_TOKEN(T_ERROR);
+		}
+	}
 	RETURN_TOKEN(T_STRING_CAST);
 }
 
@@ -1649,7 +1696,17 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
 	RETURN_TOKEN(T_OBJECT_CAST);
 }
 
-"("{TABS_AND_SPACES}("bool"|"boolean"){TABS_AND_SPACES}")" {
+"("{TABS_AND_SPACES}("bool"){TABS_AND_SPACES}")" {
+	RETURN_TOKEN(T_BOOL_CAST);
+}
+
+"("{TABS_AND_SPACES}("boolean"){TABS_AND_SPACES}")" {
+	if (PARSER_MODE()) {
+		zend_error(E_DEPRECATED, "Non-canonical cast (boolean) is deprecated, use the (bool) cast instead");
+		if (EG(exception)) {
+			RETURN_TOKEN(T_ERROR);
+		}
+	}
 	RETURN_TOKEN(T_BOOL_CAST);
 }
 
@@ -1817,11 +1874,11 @@ OPTIONAL_WHITESPACE_OR_COMMENTS ({WHITESPACE}|{MULTI_LINE_COMMENT}|{SINGLE_LINE_
 	RETURN_TOKEN(T_MUL_EQUAL);
 }
 
-"*\*" {
+"**" {
 	RETURN_TOKEN(T_POW);
 }
 
-"*\*=" {
+"**=" {
 	RETURN_TOKEN(T_POW_EQUAL);
 }
 
@@ -2446,7 +2503,7 @@ inline_char_handler:
 	if (YYCURSOR < YYLIMIT) {
 		YYCURSOR++;
 	} else {
-		zend_throw_exception_ex(zend_ce_parse_error, 0, "Unterminated comment starting line %d", CG(zend_lineno));
+		zend_throw_exception_ex(zend_ce_parse_error, 0, "Unterminated comment starting line %" PRIu32, CG(zend_lineno));
 		if (PARSER_MODE()) {
 			RETURN_TOKEN(T_ERROR);
 		}
@@ -2512,9 +2569,7 @@ inline_char_handler:
 			ZVAL_EMPTY_STRING(zendlval);
 		} else {
 			zend_uchar c = (zend_uchar)*(yytext+bprefix+1);
-			if (c == '\n' || c == '\r') {
-				CG(zend_lineno)++;
-			}
+			HANDLE_NEWLINE(c);
 			ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR(c));
 		}
 		goto skip_escape_conversion;
@@ -2565,7 +2620,7 @@ skip_escape_conversion:
 		zend_string *new_str;
 		s = Z_STRVAL_P(zendlval);
 		// TODO: avoid reallocation ???
-		SCNG(output_filter)((unsigned char **)&str, &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval));
+		SCNG(output_filter)((unsigned char **)&str, &sz, (unsigned char *)s, Z_STRLEN_P(zendlval));
 		new_str = zend_string_init(str, sz, 0);
 		if (str != s) {
 			efree(str);
@@ -2707,12 +2762,14 @@ skip_escape_conversion:
 		SCNG(heredoc_scan_ahead) = 1;
 		SCNG(heredoc_indentation) = 0;
 		SCNG(heredoc_indentation_uses_spaces) = 0;
+		SCNG(on_event_context) = NULL;
 		LANG_SCNG(on_event) = NULL;
 		CG(doc_comment) = NULL;
 
 		zend_ptr_stack_reverse_apply(¤t_state.heredoc_label_stack, copy_heredoc_label_stack);
 
-		zend_exception_save();
+		zend_object *prev_exception = EG(exception);
+		EG(exception) = NULL;
 		while (heredoc_nesting_level) {
 			zval zv;
 			int retval;
@@ -2741,7 +2798,7 @@ skip_escape_conversion:
 					heredoc_nesting_level = 0;
 			}
 		}
-		zend_exception_restore();
+		EG(exception) = prev_exception;
 
 		if (
 		    (first_token == T_VARIABLE
diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c
index d1b950160e1c..a8316768ef5f 100644
--- a/Zend/zend_lazy_objects.c
+++ b/Zend/zend_lazy_objects.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Arnaud Le Blanc                        |
    +----------------------------------------------------------------------+
@@ -93,7 +92,7 @@ void zend_lazy_objects_destroy(zend_lazy_objects_store *store)
 	zend_hash_destroy(&store->infos);
 }
 
-static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *info)
+static void zend_lazy_object_set_info(const zend_object *obj, zend_lazy_object_info *info)
 {
 	ZEND_ASSERT(zend_object_is_lazy(obj));
 
@@ -102,7 +101,7 @@ static void zend_lazy_object_set_info(zend_object *obj, zend_lazy_object_info *i
 	(void)zv;
 }
 
-static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj)
+static zend_lazy_object_info* zend_lazy_object_get_info(const zend_object *obj)
 {
 	ZEND_ASSERT(zend_object_is_lazy(obj));
 
@@ -112,7 +111,7 @@ static zend_lazy_object_info* zend_lazy_object_get_info(zend_object *obj)
 	return info;
 }
 
-static bool zend_lazy_object_has_stale_info(zend_object *obj)
+static bool zend_lazy_object_has_stale_info(const zend_object *obj)
 {
 	return zend_hash_index_find_ptr(&EG(lazy_objects_store).infos, obj->handle);
 }
@@ -154,18 +153,18 @@ zend_object* zend_lazy_object_get_instance(zend_object *obj)
 	return obj;
 }
 
-zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj)
+zend_lazy_object_flags_t zend_lazy_object_get_flags(const zend_object *obj)
 {
 	return zend_lazy_object_get_info(obj)->flags;
 }
 
-void zend_lazy_object_del_info(zend_object *obj)
+void zend_lazy_object_del_info(const zend_object *obj)
 {
 	zend_result res = zend_hash_index_del(&EG(lazy_objects_store).infos, obj->handle);
 	ZEND_ASSERT(res == SUCCESS);
 }
 
-bool zend_lazy_object_decr_lazy_props(zend_object *obj)
+bool zend_lazy_object_decr_lazy_props(const zend_object *obj)
 {
 	ZEND_ASSERT(zend_object_is_lazy(obj));
 	ZEND_ASSERT(!zend_lazy_object_initialized(obj));
@@ -183,7 +182,7 @@ bool zend_lazy_object_decr_lazy_props(zend_object *obj)
  * Making objects lazy
  */
 
-ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce)
+ZEND_API bool zend_class_can_be_lazy(const zend_class_entry *ce)
 {
 	/* Internal classes are not supported */
 	if (UNEXPECTED(ce->type == ZEND_INTERNAL_CLASS && ce != zend_standard_class_def)) {
@@ -444,7 +443,7 @@ static void zend_lazy_object_revert_init(zend_object *obj, zval *properties_tabl
 	OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED;
 }
 
-static bool zend_lazy_object_compatible(zend_object *real_object, zend_object *lazy_object)
+static bool zend_lazy_object_compatible(const zend_object *real_object, const zend_object *lazy_object)
 {
 	if (EXPECTED(real_object->ce == lazy_object->ce)) {
 		return true;
@@ -479,6 +478,24 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
 	/* prevent reentrant initialization */
 	OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY);
 
+	zval *properties_table_snapshot = NULL;
+
+	/* Snapshot dynamic properties */
+	HashTable *properties_snapshot = obj->properties;
+	if (properties_snapshot) {
+		GC_TRY_ADDREF(properties_snapshot);
+	}
+
+	/* Snapshot declared properties */
+	if (obj->ce->default_properties_count) {
+		zval *properties_table = obj->properties_table;
+		properties_table_snapshot = emalloc(sizeof(*properties_table_snapshot) * obj->ce->default_properties_count);
+
+		for (int i = 0; i < obj->ce->default_properties_count; i++) {
+			ZVAL_COPY_PROP(&properties_table_snapshot[i], &properties_table[i]);
+		}
+	}
+
 	/* Call factory */
 	zval retval;
 	int argc = 1;
@@ -492,33 +509,29 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
 	zend_call_known_fcc(initializer, &retval, argc, &zobj, named_params);
 
 	if (UNEXPECTED(EG(exception))) {
-		OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY;
-		goto exit;
+		goto fail;
 	}
 
 	if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT)) {
-		OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY;
 		zend_type_error("Lazy proxy factory must return an instance of a class compatible with %s, %s returned",
 				ZSTR_VAL(obj->ce->name),
 				zend_zval_value_name(&retval));
 		zval_ptr_dtor(&retval);
-		goto exit;
+		goto fail;
 	}
 
 	if (UNEXPECTED(Z_TYPE(retval) != IS_OBJECT || !zend_lazy_object_compatible(Z_OBJ(retval), obj))) {
-		OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY;
 		zend_type_error("The real instance class %s is not compatible with the proxy class %s. The proxy must be a instance of the same class as the real instance, or a sub-class with no additional properties, and no overrides of the __destructor or __clone methods.",
 				zend_zval_value_name(&retval),
 				ZSTR_VAL(obj->ce->name));
 		zval_ptr_dtor(&retval);
-		goto exit;
+		goto fail;
 	}
 
 	if (UNEXPECTED(Z_OBJ(retval) == obj || zend_object_is_lazy(Z_OBJ(retval)))) {
-		OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY;
 		zend_throw_error(NULL, "Lazy proxy factory must return a non-lazy object");
 		zval_ptr_dtor(&retval);
-		goto exit;
+		goto fail;
 	}
 
 	zend_fcc_dtor(&info->u.initializer.fcc);
@@ -542,6 +555,21 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
 		}
 	}
 
+	if (properties_table_snapshot) {
+		for (int i = 0; i < obj->ce->default_properties_count; i++) {
+			zval *p = &properties_table_snapshot[i];
+			/* Use zval_ptr_dtor directly here (not zend_object_dtor_property),
+			 * as any reference type_source will have already been deleted in
+			 * case the prop is not bound to this value anymore. */
+			i_zval_ptr_dtor(p);
+		}
+		efree(properties_table_snapshot);
+	}
+
+	if (properties_snapshot) {
+		zend_release_properties(properties_snapshot);
+	}
+
 	instance = Z_OBJ(retval);
 
 exit:
@@ -554,6 +582,11 @@ static zend_object *zend_lazy_object_init_proxy(zend_object *obj)
 	}
 
 	return instance;
+
+fail:
+	OBJ_EXTRA_FLAGS(obj) |= IS_OBJ_LAZY_UNINITIALIZED|IS_OBJ_LAZY_PROXY;
+	zend_lazy_object_revert_init(obj, properties_table_snapshot, properties_snapshot);
+	goto exit;
 }
 
 /* Initialize a lazy object. */
@@ -678,8 +711,6 @@ void zend_lazy_object_realize(zend_object *obj)
 	ZEND_ASSERT(zend_object_is_lazy(obj));
 	ZEND_ASSERT(!zend_lazy_object_initialized(obj));
 
-	zend_lazy_object_del_info(obj);
-
 #if ZEND_DEBUG
 	for (int i = 0; i < obj->ce->default_properties_count; i++) {
 		ZEND_ASSERT(!(Z_PROP_FLAG_P(&obj->properties_table[i]) & IS_PROP_LAZY));
@@ -687,6 +718,7 @@ void zend_lazy_object_realize(zend_object *obj)
 #endif
 
 	OBJ_EXTRA_FLAGS(obj) &= ~(IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY);
+	zend_lazy_object_del_info(obj);
 }
 
 ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object)
@@ -744,12 +776,11 @@ zend_object *zend_lazy_object_clone(zend_object *old_obj)
 		}
 	}
 
-	OBJ_EXTRA_FLAGS(new_proxy) = OBJ_EXTRA_FLAGS(old_obj);
-
 	zend_lazy_object_info *new_info = emalloc(sizeof(*info));
 	*new_info = *info;
 	new_info->u.instance = zend_objects_clone_obj(info->u.instance);
 
+	OBJ_EXTRA_FLAGS(new_proxy) = OBJ_EXTRA_FLAGS(old_obj);
 	zend_lazy_object_set_info(new_proxy, new_info);
 
 	return new_proxy;
diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h
index 64f68d66360c..8e66ee3facd6 100644
--- a/Zend/zend_lazy_objects.h
+++ b/Zend/zend_lazy_objects.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Arnaud Le Blanc                        |
    +----------------------------------------------------------------------+
@@ -57,7 +56,7 @@ typedef struct _zend_property_info zend_property_info;
 typedef struct _zend_fcall_info zend_fcall_info;
 typedef struct _zend_fcall_info_cache zend_fcall_info_cache;
 
-ZEND_API bool zend_class_can_be_lazy(zend_class_entry *ce);
+ZEND_API bool zend_class_can_be_lazy(const zend_class_entry *ce);
 ZEND_API zend_object *zend_object_make_lazy(zend_object *obj,
 		zend_class_entry *class_type, zval *initializer_zv,
 		zend_fcall_info_cache *initializer_fcc, zend_lazy_object_flags_t flags);
@@ -68,39 +67,39 @@ void zend_lazy_objects_init(zend_lazy_objects_store *store);
 void zend_lazy_objects_destroy(zend_lazy_objects_store *store);
 zval* zend_lazy_object_get_initializer_zv(zend_object *obj);
 zend_object *zend_lazy_object_get_instance(zend_object *obj);
-zend_lazy_object_flags_t zend_lazy_object_get_flags(zend_object *obj);
-void zend_lazy_object_del_info(zend_object *obj);
+zend_lazy_object_flags_t zend_lazy_object_get_flags(const zend_object *obj);
+void zend_lazy_object_del_info(const zend_object *obj);
 ZEND_API HashTable *zend_lazy_object_get_properties(zend_object *object);
 zend_object *zend_lazy_object_clone(zend_object *old_obj);
 HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp);
 HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n);
-bool zend_lazy_object_decr_lazy_props(zend_object *obj);
+bool zend_lazy_object_decr_lazy_props(const zend_object *obj);
 void zend_lazy_object_realize(zend_object *obj);
 ZEND_API zend_property_info *zend_lazy_object_get_property_info_for_slot(zend_object *obj, zval *slot);
 
-static zend_always_inline bool zend_object_is_lazy(zend_object *obj)
+static zend_always_inline bool zend_object_is_lazy(const zend_object *obj)
 {
 	return (OBJ_EXTRA_FLAGS(obj) & (IS_OBJ_LAZY_UNINITIALIZED | IS_OBJ_LAZY_PROXY));
 }
 
-static zend_always_inline bool zend_object_is_lazy_proxy(zend_object *obj)
+static zend_always_inline bool zend_object_is_lazy_proxy(const zend_object *obj)
 {
 	return (OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_PROXY);
 }
 
-static zend_always_inline bool zend_lazy_object_initialized(zend_object *obj)
+static zend_always_inline bool zend_lazy_object_initialized(const zend_object *obj)
 {
 	return !(OBJ_EXTRA_FLAGS(obj) & IS_OBJ_LAZY_UNINITIALIZED);
 }
 
 /* True if accessing a lazy prop on obj mandates a call to
  * zend_lazy_object_init() */
-static zend_always_inline bool zend_lazy_object_must_init(zend_object *obj)
+static zend_always_inline bool zend_lazy_object_must_init(const zend_object *obj)
 {
 	return zend_object_is_lazy(obj);
 }
 
-static inline bool zend_lazy_object_initialize_on_serialize(zend_object *obj)
+static inline bool zend_lazy_object_initialize_on_serialize(const zend_object *obj)
 {
 	return !(zend_lazy_object_get_flags(obj) & ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE);
 }
diff --git a/Zend/zend_list.c b/Zend/zend_list.c
index bf599a2efca9..4e96ce0ec7da 100644
--- a/Zend/zend_list.c
+++ b/Zend/zend_list.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -214,18 +213,41 @@ void zend_init_rsrc_plist(void)
 
 void zend_close_rsrc_list(HashTable *ht)
 {
-	/* Reload ht->arData on each iteration, as it may be reallocated. */
 	uint32_t i = ht->nNumUsed;
-
-	while (i-- > 0) {
-		zval *p = ZEND_HASH_ELEMENT(ht, i);
-		if (Z_TYPE_P(p) != IS_UNDEF) {
-			zend_resource *res = Z_PTR_P(p);
-			if (res->type >= 0) {
-				zend_resource_dtor(res);
+	uint32_t num = ht->nNumUsed;
+
+retry:
+	zend_try {
+		while (i-- > 0) {
+			/* Reload ht->arData on each iteration, as it may be reallocated. */
+			zval *p = ZEND_HASH_ELEMENT(ht, i);
+			if (Z_TYPE_P(p) != IS_UNDEF) {
+				zend_resource *res = Z_PTR_P(p);
+				if (res->type >= 0) {
+					zend_resource_dtor(res);
+
+					if (UNEXPECTED(ht->nNumUsed != num)) {
+						/* New resources were added, reloop from the start.
+						 * We need to keep the top->down order to avoid freeing resources
+						 * in use by the newly created resources. */
+						i = num = ht->nNumUsed;
+					}
+				}
 			}
 		}
-	}
+	} zend_catch {
+		if (UNEXPECTED(ht->nNumUsed != num)) {
+			/* See above */
+			i = num = ht->nNumUsed;
+		}
+
+		/* If we have bailed, we probably executed user code (e.g. user stream
+		 * API). Keep closing resources so they don't leak. User handlers must be
+		 * called now so they aren't called in zend_deactivate() on
+		 * zend_destroy_rsrc_list(&EG(regular_list)). At that point, the executor
+		 * has already shut down and the process would crash. */
+		goto retry;
+	} zend_end_try();
 }
 
 
diff --git a/Zend/zend_list.h b/Zend/zend_list.h
index 55ccf78dca10..108bd3fc3e7f 100644
--- a/Zend/zend_list.h
+++ b/Zend/zend_list.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
index 8c42b2494ea0..95ce31764bfc 100644
--- a/Zend/zend_llist.c
+++ b/Zend/zend_llist.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -121,7 +120,6 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
 ZEND_API void zend_llist_clean(zend_llist *l)
 {
 	zend_llist_destroy(l);
-	l->head = l->tail = NULL;
 }
 
 
diff --git a/Zend/zend_llist.h b/Zend/zend_llist.h
index 848543eba0a6..a92b8a59648c 100644
--- a/Zend/zend_llist.h
+++ b/Zend/zend_llist.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_long.h b/Zend/zend_long.h
index 3796f1c5abab..303bacd03d4c 100644
--- a/Zend/zend_long.h
+++ b/Zend/zend_long.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Anatol Belski                                   |
    +----------------------------------------------------------------------+
@@ -51,9 +50,6 @@ typedef int32_t zend_off_t;
 #endif
 
 
-/* Conversion macros. */
-#define ZEND_LTOA_BUF_LEN 65
-
 #ifdef ZEND_ENABLE_ZVAL_LONG64
 # define ZEND_LONG_FMT "%" PRId64
 # define ZEND_ULONG_FMT "%" PRIu64
@@ -61,7 +57,6 @@ typedef int32_t zend_off_t;
 # define ZEND_LONG_FMT_SPEC PRId64
 # define ZEND_ULONG_FMT_SPEC PRIu64
 # ifdef ZEND_WIN32
-#  define ZEND_LTOA(i, s, len) _i64toa_s((i), (s), (len), 10)
 #  define ZEND_ATOL(s) _atoi64((s))
 #  define ZEND_STRTOL(s0, s1, base) _strtoi64((s0), (s1), (base))
 #  define ZEND_STRTOUL(s0, s1, base) _strtoui64((s0), (s1), (base))
@@ -69,11 +64,6 @@ typedef int32_t zend_off_t;
 #  define ZEND_STRTOUL_PTR _strtoui64
 #  define ZEND_ABS _abs64
 # else
-#  define ZEND_LTOA(i, s, len) \
-	do { \
-		int st = snprintf((s), (len), ZEND_LONG_FMT, (i)); \
-		(s)[st] = '\0'; \
- 	} while (0)
 #  define ZEND_ATOL(s) atoll((s))
 #  define ZEND_STRTOL(s0, s1, base) strtoll((s0), (s1), (base))
 #  define ZEND_STRTOUL(s0, s1, base) strtoull((s0), (s1), (base))
@@ -90,14 +80,8 @@ typedef int32_t zend_off_t;
 # define ZEND_LONG_FMT_SPEC PRId32
 # define ZEND_ULONG_FMT_SPEC PRIu32
 # ifdef ZEND_WIN32
-#  define ZEND_LTOA(i, s, len) _ltoa_s((i), (s), (len), 10)
 #  define ZEND_ATOL(s) atol((s))
 # else
-#  define ZEND_LTOA(i, s, len) \
-	do { \
-		int st = snprintf((s), (len), ZEND_LONG_FMT, (i)); \
-		(s)[st] = '\0'; \
- 	} while (0)
 #  define ZEND_ATOL(s) atol((s))
 # endif
 # define ZEND_STRTOL_PTR strtol
diff --git a/Zend/zend_map_ptr.h b/Zend/zend_map_ptr.h
index 4dfa0e5043ef..af3b5178aa4a 100644
--- a/Zend/zend_map_ptr.h
+++ b/Zend/zend_map_ptr.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_max_execution_timer.c b/Zend/zend_max_execution_timer.c
index 005ce14868a0..5d0eb1219c0b 100644
--- a/Zend/zend_max_execution_timer.c
+++ b/Zend/zend_max_execution_timer.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Kévin Dunglas                             |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_max_execution_timer.h b/Zend/zend_max_execution_timer.h
index 6557d6c91845..3839ea4cf676 100644
--- a/Zend/zend_max_execution_timer.h
+++ b/Zend/zend_max_execution_timer.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Kévin Dunglas                             |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_mmap.h b/Zend/zend_mmap.h
index 201fd84d074d..d56196c24687 100644
--- a/Zend/zend_mmap.h
+++ b/Zend/zend_mmap.h
@@ -1,12 +1,15 @@
 /*
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
+   +----------------------------------------------------------------------+
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Max Kellermann                    |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h
index efc04a63bb36..3a98b1c06e29 100644
--- a/Zend/zend_modules.h
+++ b/Zend/zend_modules.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -31,7 +30,7 @@
 #define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module
 #define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module
 
-#define ZEND_MODULE_API_NO 20240925
+#define ZEND_MODULE_API_NO 20250926
 #ifdef ZTS
 #define USING_ZTS 1
 #else
diff --git a/Zend/zend_multibyte.c b/Zend/zend_multibyte.c
index 9459920b6332..28be8126b117 100644
--- a/Zend/zend_multibyte.c
+++ b/Zend/zend_multibyte.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at                              |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Masaki Fujimoto                           |
    |          Rui Hirokawa                              |
@@ -35,7 +34,7 @@ static const char *dummy_encoding_name_getter(const zend_encoding *encoding)
 
 static bool dummy_encoding_lexer_compatibility_checker(const zend_encoding *encoding)
 {
-	return 0;
+	return false;
 }
 
 static const zend_encoding *dummy_encoding_detector(const unsigned char *string, size_t length, const zend_encoding **list, size_t list_size)
@@ -114,8 +113,8 @@ ZEND_API zend_result zend_multibyte_set_functions(const zend_multibyte_functions
 	 * populated, we need to reinitialize script_encoding here.
 	 */
 	{
-		const char *value = zend_ini_string("zend.script_encoding", sizeof("zend.script_encoding") - 1, 0);
-		zend_multibyte_set_script_encoding_by_string(value, strlen(value));
+		const zend_string *value = zend_ini_str_literal("zend.script_encoding");
+		zend_multibyte_set_script_encoding_by_string(ZSTR_VAL(value), ZSTR_LEN(value));
 	}
 	return SUCCESS;
 }
@@ -195,7 +194,7 @@ ZEND_API zend_result zend_multibyte_set_script_encoding_by_string(const char *ne
 		return SUCCESS;
 	}
 
-	if (FAILURE == zend_multibyte_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) {
+	if (FAILURE == zend_multibyte_parse_encoding_list(new_value, new_value_length, &list, &size, true)) {
 		return FAILURE;
 	}
 
diff --git a/Zend/zend_multibyte.h b/Zend/zend_multibyte.h
index 16ba56ec69fd..41480ed6f86b 100644
--- a/Zend/zend_multibyte.h
+++ b/Zend/zend_multibyte.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at                              |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Masaki Fujimoto                           |
    |          Rui Hirokawa                              |
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
index bdeb435d4431..6457f85f64fb 100644
--- a/Zend/zend_multiply.h
+++ b/Zend/zend_multiply.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Sascha Schumann                         |
    |          Ard Biesheuvel                   |
@@ -155,13 +154,15 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si
 		__asm__ ("mull %3\n\tadcl $0,%1"
 	     : "=&a"(res), "=&d" (m_overflow)
 	     : "%0"(res),
-	       "rm"(size));
+	       "rm"(size)
+	     : "cc");
 	} else {
 		__asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1"
 	     : "=&a"(res), "=&d" (m_overflow)
 	     : "%0"(res),
 	       "rm"(size),
-	       "rm"(offset));
+	       "rm"(offset)
+	     : "cc");
 	}
 
 	if (UNEXPECTED(m_overflow)) {
@@ -176,7 +177,7 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si
 
 static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, size_t offset, bool *overflow)
 {
-	size_t res = nmemb;
+	size_t res;
 	zend_ulong m_overflow = 0;
 
 #ifdef __ILP32__ /* x32 */
@@ -186,19 +187,30 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si
 #endif
 
 	if (ZEND_CONST_COND(offset == 0, 0)) {
+		res = nmemb;
 		__asm__ ("mul" LP_SUFF  " %3\n\t"
 			"adc $0,%1"
 			: "=&a"(res), "=&d" (m_overflow)
 			: "%0"(res),
-			  "rm"(size));
+			  "rm"(size)
+			: "cc");
+	} else if (ZEND_CONST_COND(nmemb == 1, 0)) {
+		res = size;
+		__asm__ ("add %2, %0\n\t"
+			"adc $0,%1"
+			: "+r"(res), "+r" (m_overflow)
+			: "rm"(offset)
+			: "cc");
 	} else {
+		res = nmemb;
 		__asm__ ("mul" LP_SUFF  " %3\n\t"
 			"add %4,%0\n\t"
 			"adc $0,%1"
 			: "=&a"(res), "=&d" (m_overflow)
 			: "%0"(res),
 			  "rm"(size),
-			  "rm"(offset));
+			  "rm"(offset)
+			: "cc");
 	}
 #undef LP_SUFF
 	if (UNEXPECTED(m_overflow)) {
@@ -242,7 +254,8 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si
 		: "=&r"(res), "=&r"(m_overflow)
 		: "r"(nmemb),
 		  "r"(size),
-		  "r"(offset));
+		  "r"(offset)
+		: "cc");
 
 	if (UNEXPECTED(m_overflow)) {
 		*overflow = 1;
@@ -266,7 +279,8 @@ static zend_always_inline size_t zend_safe_address(size_t nmemb, size_t size, si
              : "=&r"(res), "=&r"(m_overflow)
              : "r"(nmemb),
                "r"(size),
-               "r"(offset));
+               "r"(offset)
+             : "xer");
 
         if (UNEXPECTED(m_overflow)) {
                 *overflow = 1;
@@ -327,7 +341,6 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t
 
 	if (UNEXPECTED(overflow)) {
 		zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
-		return 0;
 	}
 	return ret;
 }
@@ -340,7 +353,6 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si
 
 	if (UNEXPECTED(overflow)) {
 		zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset);
-		return 0;
 	}
 	return ret;
 }
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 3d782b03fe17..e7ddd466a51a 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -46,6 +45,9 @@
 #define IN_ISSET	ZEND_GUARD_PROPERTY_ISSET
 #define IN_HOOK		ZEND_GUARD_PROPERTY_HOOK
 
+static zend_arg_info zend_call_trampoline_arginfo[1] = {{0}};
+static zend_arg_info zend_property_hook_arginfo[1] = {{0}};
+
 static zend_always_inline bool zend_objects_check_stack_limit(void)
 {
 #ifdef ZEND_CHECK_STACK_LIMIT
@@ -106,8 +108,7 @@ ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj) /* {{{
 /* Implements the fast path for array cast */
 ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* {{{ */
 {
-	zend_property_info *prop_info;
-	zend_class_entry *ce = zobj->ce;
+	const zend_class_entry *ce = zobj->ce;
 	HashTable *ht;
 	zval* prop;
 	int i;
@@ -118,7 +119,7 @@ ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /*
 	if (ce->default_properties_count) {
 		zend_hash_real_init_mixed(ht);
 		for (i = 0; i < ce->default_properties_count; i++) {
-			prop_info = ce->properties_info_table[i];
+			const zend_property_info *prop_info = ce->properties_info_table[i];
 
 			if (!prop_info) {
 				continue;
@@ -192,7 +193,7 @@ ZEND_API HashTable *zend_std_get_gc(zend_object *zobj, zval **table, int *n) /*
 
 ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) /* {{{ */
 {
-	zend_class_entry *ce = object->ce;
+	const zend_class_entry *ce = object->ce;
 	zval retval;
 	HashTable *ht;
 
@@ -223,6 +224,8 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) /
 			return Z_ARRVAL(retval);
 		}
 	} else if (Z_TYPE(retval) == IS_NULL) {
+		zend_error(E_DEPRECATED, "Returning null from %s::__debugInfo() is deprecated, return an empty array instead",
+			ZSTR_VAL(ce->name));
 		*is_temp = 1;
 		ht = zend_new_array(0);
 		return ht;
@@ -285,11 +288,11 @@ static zend_always_inline bool is_derived_class(const zend_class_entry *child_cl
 static zend_never_inline int is_protected_compatible_scope(const zend_class_entry *ce, const zend_class_entry *scope) /* {{{ */
 {
 	return scope &&
-		(is_derived_class(ce, scope) || is_derived_class(scope, ce));
+		(ce == scope || is_derived_class(ce, scope) || is_derived_class(scope, ce));
 }
 /* }}} */
 
-static zend_never_inline zend_property_info *zend_get_parent_private_property(zend_class_entry *scope, const zend_class_entry *ce, zend_string *member) /* {{{ */
+static zend_never_inline zend_property_info *zend_get_parent_private_property(const zend_class_entry *scope, const zend_class_entry *ce, zend_string *member) /* {{{ */
 {
 	zval *zv;
 	zend_property_info *prop_info;
@@ -332,7 +335,7 @@ static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property(
 	zend_error(E_DEPRECATED, "Creation of dynamic property %s::$%s is deprecated",
 		ZSTR_VAL(obj->ce->name), ZSTR_VAL(member));
 	if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-		zend_class_entry *ce = obj->ce;
+		const zend_class_entry *ce = obj->ce;
 		zend_objects_store_del(obj);
 		if (!EG(exception)) {
 			/* We cannot continue execution and have to throw an exception */
@@ -345,12 +348,12 @@ static ZEND_COLD zend_never_inline bool zend_deprecated_dynamic_property(
 }
 
 static ZEND_COLD zend_never_inline void zend_readonly_property_unset_error(
-		zend_class_entry *ce, zend_string *member) {
+		const zend_class_entry *ce, const zend_string *member) {
 	zend_throw_error(NULL, "Cannot unset readonly property %s::$%s",
 		ZSTR_VAL(ce->name), ZSTR_VAL(member));
 }
 
-static zend_always_inline zend_class_entry *get_fake_or_executed_scope(void)
+static zend_always_inline const zend_class_entry *get_fake_or_executed_scope(void)
 {
 	if (UNEXPECTED(EG(fake_scope))) {
 		return EG(fake_scope);
@@ -391,7 +394,7 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c
 	flags = property_info->flags;
 
 	if (flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
-		zend_class_entry *scope = get_fake_or_executed_scope();
+		const zend_class_entry *scope = get_fake_or_executed_scope();
 
 		if (property_info->ce != scope) {
 			if (flags & ZEND_ACC_CHANGED) {
@@ -422,7 +425,7 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c
 				}
 			} else {
 				ZEND_ASSERT(flags & ZEND_ACC_PROTECTED);
-				if (UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) {
+				if (UNEXPECTED(!is_protected_compatible_scope(property_info->prototype->ce, scope))) {
 					goto wrong;
 				}
 			}
@@ -491,7 +494,7 @@ ZEND_API zend_property_info *zend_get_property_info(const zend_class_entry *ce,
 	flags = property_info->flags;
 
 	if (flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
-		zend_class_entry *scope = get_fake_or_executed_scope();
+		const zend_class_entry *scope = get_fake_or_executed_scope();
 		if (property_info->ce != scope) {
 			if (flags & ZEND_ACC_CHANGED) {
 				zend_property_info *p = zend_get_parent_private_property(scope, ce, member);
@@ -517,7 +520,7 @@ ZEND_API zend_property_info *zend_get_property_info(const zend_class_entry *ce,
 				}
 			} else {
 				ZEND_ASSERT(flags & ZEND_ACC_PROTECTED);
-				if (UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) {
+				if (UNEXPECTED(!is_protected_compatible_scope(property_info->prototype->ce, scope))) {
 					goto wrong;
 				}
 			}
@@ -564,6 +567,11 @@ ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_st
 				return FAILURE;
 			}
 		} else {
+			/* We were looking for a protected property but found a private one
+			 * belonging to the parent class. */
+			if (property_info->flags & ZEND_ACC_PRIVATE) {
+				return FAILURE;
+			}
 			ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
 		}
 		return SUCCESS;
@@ -583,12 +591,12 @@ ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_st
 ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info) {
 	ZEND_ASSERT(prop_info->flags & ZEND_ACC_PPP_SET_MASK);
 	ZEND_ASSERT(!(prop_info->flags & ZEND_ACC_PUBLIC_SET));
-	zend_class_entry *scope = get_fake_or_executed_scope();
+	const zend_class_entry *scope = get_fake_or_executed_scope();
 	if (prop_info->ce == scope) {
 		return true;
 	}
 	return EXPECTED((prop_info->flags & ZEND_ACC_PROTECTED_SET)
-		&& is_protected_compatible_scope(prop_info->ce, scope));
+		&& is_protected_compatible_scope(prop_info->prototype->ce, scope));
 }
 
 static void zend_property_guard_dtor(zval *el) /* {{{ */ {
@@ -673,7 +681,7 @@ static ZEND_FUNCTION(zend_parent_hook_set_trampoline);
 
 static bool zend_is_in_hook(const zend_property_info *prop_info)
 {
-	zend_execute_data *execute_data = EG(current_execute_data);
+	const zend_execute_data *execute_data = EG(current_execute_data);
 	if (!execute_data || !EX(func) || !EX(func)->common.prop_info) {
 		return false;
 	}
@@ -704,7 +712,7 @@ static bool zend_should_call_hook(const zend_property_info *prop_info, const zen
 	return true;
 }
 
-static ZEND_COLD void zend_throw_no_prop_backing_value_access(zend_string *class_name, zend_string *prop_name, bool is_read)
+static ZEND_COLD void zend_throw_no_prop_backing_value_access(const zend_string *class_name, const zend_string *prop_name, bool is_read)
 {
 	zend_throw_error(NULL, "Must not %s virtual property %s::$%s",
 		is_read ? "read from" : "write to",
@@ -712,7 +720,7 @@ static ZEND_COLD void zend_throw_no_prop_backing_value_access(zend_string *class
 }
 
 static bool zend_call_get_hook(
-	const zend_property_info *prop_info, zend_string *prop_name,
+	const zend_property_info *prop_info, const zend_string *prop_name,
 	zend_function *get, zend_object *zobj, zval *rv)
 {
 	if (!zend_should_call_hook(prop_info, zobj)) {
@@ -807,7 +815,7 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 		zend_function *get = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
 		if (!get) {
 			if (prop_info->flags & ZEND_ACC_VIRTUAL) {
-				zend_throw_error(NULL, "Property %s::$%s is write-only",
+				zend_throw_error(NULL, "Cannot read from set-only virtual property %s::$%s",
 					ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
 				return &EG(uninitialized_zval);
 			}
@@ -835,7 +843,7 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 			goto exit;
 		}
 
-		zend_class_entry *ce = zobj->ce;
+		const zend_class_entry *ce = zobj->ce;
 
 		if (!zend_call_get_hook(prop_info, name, get, zobj, rv)) {
 			if (EG(exception)) {
@@ -843,7 +851,7 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 			}
 
 			/* Reads from backing store can only occur in hooks, and hence will always remain simple. */
-			zend_execute_data *execute_data = EG(current_execute_data);
+			const zend_execute_data *execute_data = EG(current_execute_data);
 			if (cache_slot && EX(opline) && EX(opline)->opcode == ZEND_FETCH_OBJ_R && EX(opline)->op1_type == IS_UNUSED) {
 				ZEND_SET_PROPERTY_HOOK_SIMPLE_READ(cache_slot);
 			}
@@ -884,6 +892,28 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 
 	retval = &EG(uninitialized_zval);
 
+	/* For initialized lazy proxies: if the real instance's magic method
+	 * guard is already set for this property, we are inside a recursive
+	 * call from the real instance's __get/__isset. Forward directly to
+	 * the real instance to avoid double invocation. (GH-21478) */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			uint32_t guard_type = ((type == BP_VAR_IS) && zobj->ce->__isset)
+				? IN_ISSET : IN_GET;
+			if ((*instance_guard) & guard_type) {
+				retval = zend_std_read_property(instance, name, type, cache_slot, rv);
+				if (retval == &EG(uninitialized_zval)) {
+					ZVAL_NULL(rv);
+					retval = rv;
+				}
+				return retval;
+			}
+		}
+	}
+
 	/* magic isset */
 	if ((type == BP_VAR_IS) && zobj->ce->__isset) {
 		zval tmp_result;
@@ -953,25 +983,27 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 uninit_error:
 	if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 		if (!prop_info || (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY)) {
-			zobj = zend_lazy_object_init(zobj);
-			if (!zobj) {
+			zend_object *instance = zend_lazy_object_init(zobj);
+			if (!instance) {
 				retval = &EG(uninitialized_zval);
 				goto exit;
 			}
 
-			if (UNEXPECTED(guard)) {
+			if (UNEXPECTED(guard && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS))) {
+				/* Find which guard was used on zobj, so we can set the same
+				 * guard on instance. */
 				uint32_t guard_type = (type == BP_VAR_IS) && zobj->ce->__isset
 					? IN_ISSET : IN_GET;
-				guard = zend_get_property_guard(zobj, name);
+				guard = zend_get_property_guard(instance, name);
 				if (!((*guard) & guard_type)) {
 					(*guard) |= guard_type;
-					retval = zend_std_read_property(zobj, name, type, cache_slot, rv);
+					retval = zend_std_read_property(instance, name, type, cache_slot, rv);
 					(*guard) &= ~guard_type;
 					return retval;
 				}
 			}
 
-			return zend_std_read_property(zobj, name, type, cache_slot, rv);
+			return zend_std_read_property(instance, name, type, cache_slot, rv);
 		}
 	}
 	if (type != BP_VAR_IS) {
@@ -989,7 +1021,7 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
 /* }}} */
 
 static zend_always_inline bool property_uses_strict_types(void) {
-	zend_execute_data *execute_data = EG(current_execute_data);
+	const zend_execute_data *execute_data = EG(current_execute_data);
 	return execute_data
 		&& execute_data->func
 		&& ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data));
@@ -1010,7 +1042,7 @@ static zval *forward_write_to_lazy_object(zend_object *zobj,
 		return &EG(error_zval);
 	}
 
-	if (UNEXPECTED(guarded)) {
+	if (UNEXPECTED(guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS))) {
 		uint32_t *guard = zend_get_property_guard(instance, name);
 		if (!((*guard) & IN_SET)) {
 			(*guard) |= IN_SET;
@@ -1148,7 +1180,7 @@ found:;
 
 		if (!set) {
 			if (prop_info->flags & ZEND_ACC_VIRTUAL) {
-				zend_throw_error(NULL, "Property %s::$%s is read-only", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
+				zend_throw_error(NULL, "Cannot write to get-only virtual property %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
 				variable_ptr = &EG(error_zval);
 				goto exit;
 			}
@@ -1198,6 +1230,20 @@ found:;
 		goto exit;
 	}
 
+	/* For initialized lazy proxies: if the real instance's __set guard
+	 * is already set, we are inside a recursive call from the real
+	 * instance's __set. Forward directly to avoid double invocation. */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			if ((*instance_guard) & IN_SET) {
+				return zend_std_write_property(instance, name, value, cache_slot);
+			}
+		}
+	}
+
 	/* magic set */
 	if (zobj->ce->__set) {
 		if (!guard) {
@@ -1267,7 +1313,7 @@ found:;
 }
 /* }}} */
 
-static ZEND_COLD zend_never_inline void zend_bad_array_access(zend_class_entry *ce) /* {{{ */
+static ZEND_COLD zend_never_inline void zend_bad_array_access(const zend_class_entry *ce) /* {{{ */
 {
 	zend_throw_error(NULL, "Cannot use object of type %s as array", ZSTR_VAL(ce->name));
 }
@@ -1275,7 +1321,7 @@ static ZEND_COLD zend_never_inline void zend_bad_array_access(zend_class_entry *
 
 ZEND_API zval *zend_std_read_dimension(zend_object *object, zval *offset, int type, zval *rv) /* {{{ */
 {
-	zend_class_entry *ce = object->ce;
+	const zend_class_entry *ce = object->ce;
 	zval tmp_offset;
 
 	/* arrayaccess_funcs_ptr is set if (and only if) the class implements zend_ce_arrayaccess */
@@ -1326,7 +1372,7 @@ ZEND_API zval *zend_std_read_dimension(zend_object *object, zval *offset, int ty
 
 ZEND_API void zend_std_write_dimension(zend_object *object, zval *offset, zval *value) /* {{{ */
 {
-	zend_class_entry *ce = object->ce;
+	const zend_class_entry *ce = object->ce;
 	zval tmp_offset;
 
 	zend_class_arrayaccess_funcs *funcs = ce->arrayaccess_funcs_ptr;
@@ -1349,7 +1395,7 @@ ZEND_API void zend_std_write_dimension(zend_object *object, zval *offset, zval *
 // todo: make zend_std_has_dimension return bool as well
 ZEND_API int zend_std_has_dimension(zend_object *object, zval *offset, int check_empty) /* {{{ */
 {
-	zend_class_entry *ce = object->ce;
+	const zend_class_entry *ce = object->ce;
 	zval retval, tmp_offset;
 	bool result;
 
@@ -1382,6 +1428,8 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
 	uintptr_t property_offset;
 	const zend_property_info *prop_info = NULL;
 
+	ZEND_ASSERT(type != BP_VAR_R && type != BP_VAR_IS);
+
 #if DEBUG_OBJECT_HANDLERS
 	fprintf(stderr, "Ptr object #%d property: %s\n", zobj->handle, ZSTR_VAL(name));
 #endif
@@ -1389,20 +1437,33 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
 	property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__get != NULL), cache_slot, &prop_info);
 
 	if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) {
+try_again:
 		retval = OBJ_PROP(zobj, property_offset);
 		if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
 			if (EXPECTED(!zobj->ce->__get) ||
 			    UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET) ||
 			    UNEXPECTED(prop_info && (Z_PROP_FLAG_P(retval) & IS_PROP_UNINIT))) {
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj) && (Z_PROP_FLAG_P(retval) & IS_PROP_LAZY))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
+					bool guarded = zobj->ce->__get
+						&& (*zend_get_property_guard(zobj, name) & IN_GET);
+					zend_object *instance = zend_lazy_object_init(zobj);
+					if (!instance) {
 						return &EG(error_zval);
 					}
 
-					return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot);
+					if (guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
+						uint32_t *guard = zend_get_property_guard(instance, name);
+						if (!(*guard & IN_GET)) {
+							(*guard) |= IN_GET;
+							retval = zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
+							(*guard) &= ~IN_GET;
+							return retval;
+						}
+					}
+
+					return zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
 				}
-				if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) {
+				if (UNEXPECTED(type == BP_VAR_RW)) {
 					if (prop_info) {
 						zend_typed_property_uninitialized_access(prop_info, name);
 						retval = &EG(error_zval);
@@ -1443,6 +1504,25 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
 		}
 		if (EXPECTED(!zobj->ce->__get) ||
 		    UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) {
+			if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+				bool guarded = (zobj->ce->__get != NULL);
+				zend_object *instance = zend_lazy_object_init(zobj);
+				if (!instance) {
+					return &EG(error_zval);
+				}
+
+				if (guarded && (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
+					uint32_t *guard = zend_get_property_guard(instance, name);
+					if (!(*guard & IN_GET)) {
+						(*guard) |= IN_GET;
+						retval = zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
+						(*guard) &= ~IN_GET;
+						return retval;
+					}
+				}
+
+				return zend_std_get_property_ptr_ptr(instance, name, type, cache_slot);
+			}
 			if (UNEXPECTED(zobj->ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
 				zend_forbidden_dynamic_property(zobj->ce, name);
 				return &EG(error_zval);
@@ -1452,23 +1532,23 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
 					return &EG(error_zval);
 				}
 			}
-			if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-				zobj = zend_lazy_object_init(zobj);
-				if (!zobj) {
-					return &EG(error_zval);
-				}
-
-				return zend_std_get_property_ptr_ptr(zobj, name, type, cache_slot);
-			}
 			if (UNEXPECTED(!zobj->properties)) {
 				rebuild_object_properties_internal(zobj);
 			}
-			if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) {
+			if (UNEXPECTED(type == BP_VAR_RW)) {
 				zend_error(E_WARNING, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
 			}
 			retval = zend_hash_add(zobj->properties, name, &EG(uninitialized_zval));
 		}
-	} else if (!IS_HOOKED_PROPERTY_OFFSET(property_offset) && zobj->ce->__get == NULL) {
+	} else if (IS_HOOKED_PROPERTY_OFFSET(property_offset)) {
+		if (!(prop_info->flags & ZEND_ACC_VIRTUAL) && !zend_should_call_hook(prop_info, zobj)) {
+			property_offset = prop_info->offset;
+			if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+				prop_info = NULL;
+			}
+			goto try_again;
+		}
+	} else if (zobj->ce->__get == NULL) {
 		retval = &EG(error_zval);
 	}
 
@@ -1558,6 +1638,21 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
 		return;
 	}
 
+	/* For initialized lazy proxies: if the real instance's __unset guard
+	 * is already set, we are inside a recursive call from the real
+	 * instance's __unset. Forward directly to avoid double invocation. */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			if ((*instance_guard) & IN_UNSET) {
+				zend_std_unset_property(instance, name, cache_slot);
+				return;
+			}
+		}
+	}
+
 	/* magic unset */
 	if (zobj->ce->__unset) {
 		if (!guard) {
@@ -1565,9 +1660,11 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
 		}
 		if (!((*guard) & IN_UNSET)) {
 			/* have unsetter - try with it! */
+			GC_ADDREF(zobj);
 			(*guard) |= IN_UNSET; /* prevent circular unsetting */
 			zend_std_call_unsetter(zobj, name);
 			(*guard) &= ~IN_UNSET;
+			OBJ_RELEASE(zobj);
 			return;
 		} else if (UNEXPECTED(IS_WRONG_PROPERTY_OFFSET(property_offset))) {
 			/* Trigger the correct error */
@@ -1585,7 +1682,7 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
 			return;
 		}
 
-		if (UNEXPECTED(guard)) {
+		if (UNEXPECTED(guard && zobj->ce->ce_flags & ZEND_ACC_USE_GUARDS)) {
 			guard = zend_get_property_guard(zobj, name);
 			if (!((*guard) & IN_UNSET)) {
 				(*guard) |= IN_UNSET;
@@ -1603,7 +1700,7 @@ ZEND_API void zend_std_unset_property(zend_object *zobj, zend_string *name, void
 
 ZEND_API void zend_std_unset_dimension(zend_object *object, zval *offset) /* {{{ */
 {
-	zend_class_entry *ce = object->ce;
+	const zend_class_entry *ce = object->ce;
 	zval tmp_offset;
 
 	zend_class_arrayaccess_funcs *funcs = ce->arrayaccess_funcs_ptr;
@@ -1619,7 +1716,7 @@ ZEND_API void zend_std_unset_dimension(zend_object *object, zval *offset) /* {{{
 }
 /* }}} */
 
-static zend_never_inline zend_function *zend_get_parent_private_method(zend_class_entry *scope, zend_class_entry *ce, zend_string *function_name) /* {{{ */
+static zend_never_inline zend_function *zend_get_parent_private_method(const zend_class_entry *scope, const zend_class_entry *ce, zend_string *function_name) /* {{{ */
 {
 	zval *func;
 	zend_function *fbc;
@@ -1667,18 +1764,15 @@ ZEND_API bool zend_check_protected(const zend_class_entry *ce, const zend_class_
 }
 /* }}} */
 
-ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce, zend_string *method_name, bool is_static) /* {{{ */
+ZEND_API ZEND_ATTRIBUTE_NONNULL zend_function *zend_get_call_trampoline_func(
+	const zend_function *fbc, zend_string *method_name) /* {{{ */
 {
 	size_t mname_len;
 	zend_op_array *func;
-	zend_function *fbc = is_static ? ce->__callstatic : ce->__call;
 	/* We use non-NULL value to avoid useless run_time_cache allocation.
 	 * The low bit must be zero, to not be interpreted as a MAP_PTR offset.
 	 */
 	static const void *dummy = (void*)(intptr_t)2;
-	static const zend_arg_info arg_info[1] = {{0}};
-
-	ZEND_ASSERT(fbc);
 
 	if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
 		func = &EG(trampoline).op_array;
@@ -1693,12 +1787,10 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce
 	func->fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE
 		| ZEND_ACC_PUBLIC
 		| ZEND_ACC_VARIADIC
-		| (fbc->common.fn_flags & (ZEND_ACC_RETURN_REFERENCE|ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_NODISCARD));
+		| (fbc->common.fn_flags & (ZEND_ACC_RETURN_REFERENCE|ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_NODISCARD|ZEND_ACC_STATIC));
+	func->fn_flags2 = 0;
 	/* Attributes outlive the trampoline because they are created by the compiler. */
 	func->attributes = fbc->common.attributes;
-	if (is_static) {
-		func->fn_flags |= ZEND_ACC_STATIC;
-	}
 	func->opcodes = &EG(call_trampoline_op);
 	ZEND_MAP_PTR_INIT(func->run_time_cache, (void**)dummy);
 	func->scope = fbc->common.scope;
@@ -1727,7 +1819,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce
 	func->prop_info = NULL;
 	func->num_args = 0;
 	func->required_num_args = 0;
-	func->arg_info = (zend_arg_info *) arg_info;
+	func->arg_info = zend_call_trampoline_arginfo;
 
 	return (zend_function*)func;
 }
@@ -1744,7 +1836,7 @@ static ZEND_FUNCTION(zend_parent_hook_get_trampoline)
 	}
 
 	zval rv;
-	zval *retval = obj->handlers->read_property(obj, prop_name, BP_VAR_R, NULL, &rv);
+	const zval *retval = obj->handlers->read_property(obj, prop_name, BP_VAR_R, NULL, &rv);
 	if (retval == &rv) {
 		RETVAL_COPY_VALUE(retval);
 	} else {
@@ -1780,7 +1872,6 @@ ZEND_API zend_function *zend_get_property_hook_trampoline(
 	const zend_property_info *prop_info,
 	zend_property_hook_kind kind, zend_string *prop_name)
 {
-	static const zend_arg_info arg_info[1] = {{0}};
 	zend_function *func;
 	if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
 		func = &EG(trampoline);
@@ -1795,6 +1886,7 @@ ZEND_API zend_function *zend_get_property_hook_trampoline(
 	func->common.arg_flags[1] = 0;
 	func->common.arg_flags[2] = 0;
 	func->common.fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE;
+	func->common.fn_flags2 = 0;
 	func->common.function_name = zend_string_concat3(
 		"$", 1, ZSTR_VAL(prop_name), ZSTR_LEN(prop_name),
 		kind == ZEND_PROPERTY_HOOK_GET ? "::get" : "::set", 5);
@@ -1805,7 +1897,7 @@ ZEND_API zend_function *zend_get_property_hook_trampoline(
 	func->common.scope = prop_info->ce;
 	func->common.prototype = NULL;
 	func->common.prop_info = prop_info;
-	func->common.arg_info = (zend_arg_info *) arg_info;
+	func->common.arg_info = zend_property_hook_arginfo;
 	func->internal_function.handler = kind == ZEND_PROPERTY_HOOK_GET
 		? ZEND_FN(zend_parent_hook_get_trampoline)
 		: ZEND_FN(zend_parent_hook_set_trampoline);
@@ -1817,13 +1909,7 @@ ZEND_API zend_function *zend_get_property_hook_trampoline(
 	return func;
 }
 
-static zend_always_inline zend_function *zend_get_user_call_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
-{
-	return zend_get_call_trampoline_func(ce, method_name, 0);
-}
-/* }}} */
-
-ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(zend_function *fbc, zend_string *method_name, zend_class_entry *scope) /* {{{ */
+ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(const zend_function *fbc, const zend_string *method_name, const zend_class_entry *scope) /* {{{ */
 {
 	zend_throw_error(NULL, "Call to %s method %s::%s() from %s%s",
 		zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(method_name),
@@ -1833,7 +1919,7 @@ ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(zend_function *fb
 }
 /* }}} */
 
-ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(zend_function *fbc) /* {{{ */
+ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(const zend_function *fbc) /* {{{ */
 {
 	zend_throw_error(NULL, "Cannot call abstract method %s::%s()",
 		ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
@@ -1846,7 +1932,6 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
 	zval *func;
 	zend_function *fbc;
 	zend_string *lc_method_name;
-	zend_class_entry *scope;
 	ALLOCA_FLAG(use_heap);
 
 	if (EXPECTED(key != NULL)) {
@@ -1864,7 +1949,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
 			ZSTR_ALLOCA_FREE(lc_method_name, use_heap);
 		}
 		if (zobj->ce->__call) {
-			return zend_get_user_call_function(zobj->ce, method_name);
+			return zend_get_call_trampoline_func(zobj->ce->__call, method_name);
 		} else {
 			return NULL;
 		}
@@ -1874,7 +1959,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
 
 	/* Check access level */
 	if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
-		scope = zend_get_executed_scope();
+		const zend_class_entry *scope = zend_get_executed_scope();
 
 		if (fbc->common.scope != scope) {
 			if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
@@ -1890,7 +1975,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
 			if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
 			 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
 				if (zobj->ce->__call) {
-					fbc = zend_get_user_call_function(zobj->ce, method_name);
+					fbc = zend_get_call_trampoline_func(zobj->ce->__call, method_name);
 				} else {
 					zend_bad_method_call(fbc, method_name, scope);
 					fbc = NULL;
@@ -1911,14 +1996,8 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
 }
 /* }}} */
 
-static zend_always_inline zend_function *zend_get_user_callstatic_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
-{
-	return zend_get_call_trampoline_func(ce, method_name, 1);
-}
-/* }}} */
-
 static zend_always_inline zend_function *get_static_method_fallback(
-		zend_class_entry *ce, zend_string *function_name)
+		const zend_class_entry *ce, zend_string *function_name)
 {
 	zend_object *object;
 	if (ce->__call &&
@@ -1928,15 +2007,15 @@ static zend_always_inline zend_function *get_static_method_fallback(
 		 * see: tests/classes/__call_004.phpt  */
 
 		ZEND_ASSERT(object->ce->__call);
-		return zend_get_user_call_function(object->ce, function_name);
+		return zend_get_call_trampoline_func(object->ce->__call, function_name);
 	} else if (ce->__callstatic) {
-		return zend_get_user_callstatic_function(ce, function_name);
+		return zend_get_call_trampoline_func(ce->__callstatic, function_name);
 	} else {
 		return NULL;
 	}
 }
 
-ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name, const zval *key) /* {{{ */
+ZEND_API zend_function *zend_std_get_static_method(const zend_class_entry *ce, zend_string *function_name, const zval *key) /* {{{ */
 {
 	zend_string *lc_function_name;
 	if (EXPECTED(key != NULL)) {
@@ -1949,17 +2028,15 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
 	zval *func = zend_hash_find(&ce->function_table, lc_function_name);
 	if (EXPECTED(func)) {
 		fbc = Z_FUNC_P(func);
-		if (!(fbc->op_array.fn_flags & ZEND_ACC_PUBLIC)) {
-			zend_class_entry *scope = zend_get_executed_scope();
-			if (UNEXPECTED(fbc->common.scope != scope)) {
-				if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
-				 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
-					zend_function *fallback_fbc = get_static_method_fallback(ce, function_name);
-					if (!fallback_fbc) {
-						zend_bad_method_call(fbc, function_name, scope);
-					}
-					fbc = fallback_fbc;
+		if (!(fbc->common.fn_flags & ZEND_ACC_PUBLIC)) {
+			const zend_class_entry *scope = zend_get_executed_scope();
+			ZEND_ASSERT(!(fbc->common.fn_flags & ZEND_ACC_PUBLIC));
+			if (!zend_check_method_accessible(fbc, scope)) {
+				zend_function *fallback_fbc = get_static_method_fallback(ce, function_name);
+				if (!fallback_fbc) {
+					zend_bad_method_call(fbc, function_name, scope);
 				}
+				fbc = fallback_fbc;
 			}
 		}
 	} else {
@@ -1999,7 +2076,6 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
 
 ZEND_API void zend_class_init_statics(zend_class_entry *class_type) /* {{{ */
 {
-	int i;
 	zval *p;
 
 	if (class_type->default_static_members_count && !CE_STATIC_MEMBERS(class_type)) {
@@ -2008,7 +2084,7 @@ ZEND_API void zend_class_init_statics(zend_class_entry *class_type) /* {{{ */
 		}
 
 		ZEND_MAP_PTR_SET(class_type->static_members_table, emalloc(sizeof(zval) * class_type->default_static_members_count));
-		for (i = 0; i < class_type->default_static_members_count; i++) {
+		for (uint32_t i = 0; i < class_type->default_static_members_count; i++) {
 			p = &class_type->default_static_members_table[i];
 			if (Z_TYPE_P(p) == IS_INDIRECT) {
 				zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i];
@@ -2032,10 +2108,10 @@ ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend
 	}
 
 	if (!(property_info->flags & ZEND_ACC_PUBLIC)) {
-		zend_class_entry *scope = get_fake_or_executed_scope();
+		const zend_class_entry *scope = get_fake_or_executed_scope();
 		if (property_info->ce != scope) {
 			if (UNEXPECTED(property_info->flags & ZEND_ACC_PRIVATE)
-			 || UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) {
+			 || UNEXPECTED(!is_protected_compatible_scope(property_info->prototype->ce, scope))) {
 				if (type != BP_VAR_IS) {
 					zend_bad_property_access(property_info, ce, property_name);
 				}
@@ -2090,22 +2166,26 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
 	return zend_std_get_static_property_with_info(ce, property_name, type, &prop_info);
 }
 
-ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name) /* {{{ */
+ZEND_API ZEND_COLD bool zend_std_unset_static_property(const zend_class_entry *ce, const zend_string *property_name) /* {{{ */
 {
 	zend_throw_error(NULL, "Attempt to unset static property %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(property_name));
 	return 0;
 }
 /* }}} */
 
-static ZEND_COLD zend_never_inline void zend_bad_constructor_call(zend_function *constructor, zend_class_entry *scope) /* {{{ */
+static ZEND_COLD zend_never_inline void zend_bad_constructor_call(const zend_function *constructor, const zend_class_entry *scope) /* {{{ */
 {
 	if (scope) {
-		zend_throw_error(NULL, "Call to %s %s::%s() from scope %s",
-			zend_visibility_string(constructor->common.fn_flags), ZSTR_VAL(constructor->common.scope->name),
-			ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name)
+		zend_throw_error(NULL, "Call to %s %s::__construct() from scope %s",
+			zend_visibility_string(constructor->common.fn_flags),
+			ZSTR_VAL(constructor->common.scope->name),
+			ZSTR_VAL(scope->name)
 		);
 	} else {
-		zend_throw_error(NULL, "Call to %s %s::%s() from global scope", zend_visibility_string(constructor->common.fn_flags), ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
+		zend_throw_error(NULL, "Call to %s %s::__construct() from global scope",
+			zend_visibility_string(constructor->common.fn_flags),
+			ZSTR_VAL(constructor->common.scope->name)
+		);
 	}
 }
 /* }}} */
@@ -2115,15 +2195,13 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
 	zend_function *constructor = zobj->ce->constructor;
 
 	if (constructor) {
-		if (UNEXPECTED(!(constructor->op_array.fn_flags & ZEND_ACC_PUBLIC))) {
-			zend_class_entry *scope = get_fake_or_executed_scope();
-			if (UNEXPECTED(constructor->common.scope != scope)) {
-				if (UNEXPECTED(constructor->op_array.fn_flags & ZEND_ACC_PRIVATE)
-				 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
-					zend_bad_constructor_call(constructor, scope);
-					zend_object_store_ctor_failed(zobj);
-					constructor = NULL;
-				}
+		if (UNEXPECTED(!(constructor->common.fn_flags & ZEND_ACC_PUBLIC))) {
+			const zend_class_entry *scope = get_fake_or_executed_scope();
+			ZEND_ASSERT(!(constructor->common.fn_flags & ZEND_ACC_PUBLIC));
+			if (!zend_check_method_accessible(constructor, scope)) {
+				zend_bad_constructor_call(constructor, scope);
+				zend_object_store_ctor_failed(zobj);
+				constructor = NULL;
 			}
 		}
 	}
@@ -2208,6 +2286,10 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
 		}
 		Z_PROTECT_RECURSION_P(o1);
 
+		GC_ADDREF(zobj1);
+		GC_ADDREF(zobj2);
+		int ret;
+
 		for (i = 0; i < zobj1->ce->default_properties_count; i++) {
 			zval *p1, *p2;
 
@@ -2222,31 +2304,45 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
 
 			if (Z_TYPE_P(p1) != IS_UNDEF) {
 				if (Z_TYPE_P(p2) != IS_UNDEF) {
-					int ret;
-
 					ret = zend_compare(p1, p2);
 					if (ret != 0) {
 						Z_UNPROTECT_RECURSION_P(o1);
-						return ret;
+						goto done;
 					}
 				} else {
 					Z_UNPROTECT_RECURSION_P(o1);
-					return 1;
+					ret = 1;
+					goto done;
 				}
 			} else {
 				if (Z_TYPE_P(p2) != IS_UNDEF) {
 					Z_UNPROTECT_RECURSION_P(o1);
-					return 1;
+					ret = 1;
+					goto done;
 				}
 			}
 		}
 
 		Z_UNPROTECT_RECURSION_P(o1);
-		return 0;
+		ret = 0;
+
+done:
+		OBJ_RELEASE(zobj1);
+		OBJ_RELEASE(zobj2);
+
+		return ret;
 	} else {
-		return zend_compare_symbol_tables(
+		GC_ADDREF(zobj1);
+		GC_ADDREF(zobj2);
+
+		int ret = zend_compare_symbol_tables(
 				zend_std_get_properties_ex(zobj1),
 				zend_std_get_properties_ex(zobj2));
+
+		OBJ_RELEASE(zobj1);
+		OBJ_RELEASE(zobj2);
+
+		return ret;
 	}
 }
 /* }}} */
@@ -2327,7 +2423,7 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
 
 		if (!get) {
 			if (prop_info->flags & ZEND_ACC_VIRTUAL) {
-				zend_throw_error(NULL, "Property %s::$%s is write-only",
+				zend_throw_error(NULL, "Cannot read from set-only virtual property %s::$%s",
 					ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
 				return 0;
 			} else {
@@ -2359,6 +2455,20 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
 		goto exit;
 	}
 
+	/* For initialized lazy proxies: if the real instance's __isset guard
+	 * is already set, we are inside a recursive call from the real
+	 * instance's __isset. Forward directly to avoid double invocation. */
+	if (UNEXPECTED(zend_object_is_lazy_proxy(zobj)
+			&& zend_lazy_object_initialized(zobj))) {
+		zend_object *instance = zend_lazy_object_get_instance(zobj);
+		if (instance->ce->ce_flags & ZEND_ACC_USE_GUARDS) {
+			uint32_t *instance_guard = zend_get_property_guard(instance, name);
+			if ((*instance_guard) & IN_ISSET) {
+				return zend_std_has_property(instance, name, has_set_exists, cache_slot);
+			}
+		}
+	}
+
 	if (!zobj->ce->__isset) {
 		goto lazy_init;
 	}
@@ -2402,7 +2512,7 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
 		if (!value || (Z_PROP_FLAG_P(value) & IS_PROP_LAZY)) {
 			zobj = zend_lazy_object_init(zobj);
 			if (!zobj) {
-				result = 0;
+				result = false;
 				goto exit;
 			}
 
@@ -2420,7 +2530,7 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
 		}
 	}
 
-	result = 0;
+	result = false;
 	goto exit;
 }
 /* }}} */
@@ -2435,7 +2545,7 @@ ZEND_API zend_result zend_std_cast_object_tostring(zend_object *readobj, zval *w
 {
 	switch (type) {
 		case IS_STRING: {
-			zend_class_entry *ce = readobj->ce;
+			const zend_class_entry *ce = readobj->ce;
 			if (ce->__tostring) {
 				zval retval;
 				GC_ADDREF(readobj);
@@ -2468,7 +2578,7 @@ ZEND_API zend_result zend_std_cast_object_tostring(zend_object *readobj, zval *w
 ZEND_API zend_result zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, bool check_only) /* {{{ */
 {
 	zend_class_entry *ce = obj->ce;
-	zval *func = zend_hash_find_known_hash(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE));
+	const zval *func = zend_hash_find_known_hash(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE));
 
 	if (func == NULL) {
 		return FAILURE;
@@ -2545,6 +2655,7 @@ ZEND_API const zend_object_handlers std_object_handlers = {
 	zend_object_std_dtor,					/* free_obj */
 	zend_objects_destroy_object,			/* dtor_obj */
 	zend_objects_clone_obj,					/* clone_obj */
+	zend_objects_clone_obj_with,			/* clone_obj_with */
 
 	zend_std_read_property,					/* read_property */
 	zend_std_write_property,				/* write_property */
@@ -2568,3 +2679,9 @@ ZEND_API const zend_object_handlers std_object_handlers = {
 	zend_std_compare_objects,				/* compare */
 	NULL,									/* get_properties_for */
 };
+
+void zend_object_handlers_startup(void) {
+	zend_call_trampoline_arginfo[0].name = ZSTR_KNOWN(ZEND_STR_ARGUMENTS);
+	zend_call_trampoline_arginfo[0].type = (zend_type)ZEND_TYPE_INIT_CODE(IS_MIXED, false, _ZEND_ARG_INFO_FLAGS(false, 1, 0));
+	zend_property_hook_arginfo[0].name = ZSTR_KNOWN(ZEND_STR_VALUE);
+}
diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h
index 7e7d3df37a6a..d0dd804e8a41 100644
--- a/Zend/zend_object_handlers.h
+++ b/Zend/zend_object_handlers.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -180,6 +179,7 @@ typedef void (*zend_object_free_obj_t)(zend_object *object);
 typedef void (*zend_object_dtor_obj_t)(zend_object *object);
 
 typedef zend_object* (*zend_object_clone_obj_t)(zend_object *object);
+typedef zend_object* (*zend_object_clone_obj_with_t)(zend_object *object, const zend_class_entry *scope, const HashTable *properties);
 
 /* Get class name for display in var_dump and other debugging functions.
  * Must be defined and must return a non-NULL value. */
@@ -204,11 +204,12 @@ typedef zend_result (*zend_object_do_operation_t)(uint8_t opcode, zval *result,
 
 struct _zend_object_handlers {
 	/* offset of real object header (usually zero) */
-	int										offset;
+	size_t										offset;
 	/* object handlers */
 	zend_object_free_obj_t					free_obj;             /* required */
 	zend_object_dtor_obj_t					dtor_obj;             /* required */
 	zend_object_clone_obj_t					clone_obj;            /* optional */
+	zend_object_clone_obj_with_t			clone_obj_with;       /* optional */
 	zend_object_read_property_t				read_property;        /* required */
 	zend_object_write_property_t			write_property;       /* required */
 	zend_object_read_dimension_t			read_dimension;       /* required */
@@ -246,10 +247,10 @@ extern const ZEND_API zend_object_handlers std_object_handlers;
 #define ZEND_PROPERTY_EXISTS    0x2          /* Property exists */
 
 ZEND_API void zend_class_init_statics(zend_class_entry *ce);
-ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name_strval, const zval *key);
+ZEND_API zend_function *zend_std_get_static_method(const zend_class_entry *ce, zend_string *function_name_strval, const zval *key);
 ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend_string *property_name, int type, struct _zend_property_info **prop_info);
 ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, int type);
-ZEND_API ZEND_COLD bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name);
+ZEND_API ZEND_COLD bool zend_std_unset_static_property(const zend_class_entry *ce, const zend_string *property_name);
 ZEND_API zend_function *zend_std_get_constructor(zend_object *object);
 ZEND_API struct _zend_property_info *zend_get_property_info(const zend_class_entry *ce, zend_string *member, int silent);
 ZEND_API HashTable *zend_std_get_properties(zend_object *object);
@@ -272,8 +273,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2);
 ZEND_API zend_result zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, bool check_only);
 /* Use zend_std_get_properties_ex() */
 ZEND_API HashTable *rebuild_object_properties_internal(zend_object *zobj);
-ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(zend_function *fbc, zend_string *method_name, zend_class_entry *scope);
-ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(zend_function *fbc);
+ZEND_API ZEND_COLD zend_never_inline void zend_bad_method_call(const zend_function *fbc, const zend_string *method_name, const zend_class_entry *scope);
+ZEND_API ZEND_COLD zend_never_inline void zend_abstract_method_call(const zend_function *fbc);
 
 static zend_always_inline HashTable *zend_std_get_properties_ex(zend_object *object)
 {
@@ -310,9 +311,7 @@ ZEND_API bool zend_check_protected(const zend_class_entry *ce, const zend_class_
 
 ZEND_API zend_result zend_check_property_access(const zend_object *zobj, zend_string *prop_info_name, bool is_dynamic);
 
-ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce, zend_string *method_name, bool is_static);
-
-ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *member);
+ZEND_API ZEND_ATTRIBUTE_NONNULL zend_function *zend_get_call_trampoline_func(const zend_function *fbc, zend_string *method_name);
 
 ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *member);
 
@@ -334,6 +333,8 @@ ZEND_API zend_function *zend_get_property_hook_trampoline(
 
 ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info);
 
+void zend_object_handlers_startup(void);
+
 #define zend_release_properties(ht) do { \
 	if (ht) { \
 		zend_array_release(ht); \
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index fd0e97c5f413..2fc264742cd1 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -121,51 +120,27 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
 		}
 
 		zend_object *old_exception;
-		const zend_op *old_opline_before_exception;
-
-		if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
-			if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
-				/* Ensure that if we're calling a private function, we're allowed to do so.
-				 */
-				if (EG(current_execute_data)) {
-					zend_class_entry *scope = zend_get_executed_scope();
-
-					if (object->ce != scope) {
-						zend_throw_error(NULL,
-							"Call to private %s::__destruct() from %s%s",
-							ZSTR_VAL(object->ce->name),
-							scope ? "scope " : "global scope",
-							scope ? ZSTR_VAL(scope->name) : ""
-						);
-						return;
-					}
-				} else {
-					zend_error(E_WARNING,
-						"Call to private %s::__destruct() from global scope during shutdown ignored",
-						ZSTR_VAL(object->ce->name));
+		const zend_op *old_opline_before_exception = NULL;
+
+		if (destructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
+			if (EG(current_execute_data)) {
+				zend_class_entry *scope = zend_get_executed_scope();
+				/* Ensure that if we're calling a protected or private function, we're allowed to do so. */
+				ZEND_ASSERT(!(destructor->common.fn_flags & ZEND_ACC_PUBLIC));
+				if (!zend_check_method_accessible(destructor, scope)) {
+					zend_throw_error(NULL,
+						"Call to %s %s::__destruct() from %s%s",
+						zend_visibility_string(destructor->common.fn_flags), ZSTR_VAL(object->ce->name),
+						scope ? "scope " : "global scope",
+						scope ? ZSTR_VAL(scope->name) : ""
+					);
 					return;
 				}
 			} else {
-				/* Ensure that if we're calling a protected function, we're allowed to do so.
-				 */
-				if (EG(current_execute_data)) {
-					zend_class_entry *scope = zend_get_executed_scope();
-
-					if (!zend_check_protected(zend_get_function_root_class(destructor), scope)) {
-						zend_throw_error(NULL,
-							"Call to protected %s::__destruct() from %s%s",
-							ZSTR_VAL(object->ce->name),
-							scope ? "scope " : "global scope",
-							scope ? ZSTR_VAL(scope->name) : ""
-						);
-						return;
-					}
-				} else {
-					zend_error(E_WARNING,
-						"Call to protected %s::__destruct() from global scope during shutdown ignored",
-						ZSTR_VAL(object->ce->name));
-					return;
-				}
+				zend_error(E_WARNING,
+					"Call to %s %s::__destruct() from global scope during shutdown ignored",
+					zend_visibility_string(destructor->common.fn_flags), ZSTR_VAL(object->ce->name));
+				return;
 			}
 		}
 
@@ -180,13 +155,15 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
 			if (EG(exception) == object) {
 				zend_error_noreturn(E_CORE_ERROR, "Attempt to destruct pending exception");
 			} else {
-				if (EG(current_execute_data)
-				 && EG(current_execute_data)->func
-				 && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
-					zend_rethrow_exception(EG(current_execute_data));
+				if (EG(current_execute_data)) {
+					if (EG(current_execute_data)->func
+					 && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
+						zend_rethrow_exception(EG(current_execute_data));
+					}
+					EG(current_execute_data)->opline = EG(opline_before_exception);
+					old_opline_before_exception = EG(opline_before_exception);
 				}
 				old_exception = EG(exception);
-				old_opline_before_exception = EG(opline_before_exception);
 				EG(exception) = NULL;
 			}
 		}
@@ -194,7 +171,10 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
 		zend_call_known_instance_method_with_0_params(destructor, object, NULL);
 
 		if (old_exception) {
-			EG(opline_before_exception) = old_opline_before_exception;
+			if (EG(current_execute_data)) {
+				EG(current_execute_data)->opline = EG(exception_op);
+				EG(opline_before_exception) = old_opline_before_exception;
+			}
 			if (EG(exception)) {
 				zend_exception_set_previous(EG(exception), old_exception);
 			} else {
@@ -213,14 +193,14 @@ ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce)
 	return object;
 }
 
-ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, zend_object *old_object)
+ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, const zend_object *old_object)
 {
 	bool has_clone_method = old_object->ce->clone != NULL;
 
 	if (old_object->ce->default_properties_count) {
-		zval *src = old_object->properties_table;
+		const zval *src = old_object->properties_table;
 		zval *dst = new_object->properties_table;
-		zval *end = src + old_object->ce->default_properties_count;
+		const zval *end = src + old_object->ce->default_properties_count;
 
 		do {
 			i_zval_ptr_dtor(dst);
@@ -288,7 +268,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object,
 	}
 
 	if (has_clone_method) {
-		GC_ADDREF(new_object);
 		zend_call_known_instance_method_with_0_params(new_object->ce->clone, new_object, NULL);
 
 		if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) {
@@ -298,9 +277,53 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object,
 				Z_PROP_FLAG_P(prop) &= ~IS_PROP_REINITABLE;
 			}
 		}
+	}
+}
+
+ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *old_object, const zend_class_entry *scope, const HashTable *properties)
+{
+	zend_object *new_object = old_object->handlers->clone_obj(old_object);
+
+	if (EXPECTED(!EG(exception))) {
+		/* Unlock readonly properties once more. */
+		if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) {
+			for (uint32_t i = 0; i < new_object->ce->default_properties_count; i++) {
+				zval* prop = OBJ_PROP_NUM(new_object, i);
+				Z_PROP_FLAG_P(prop) |= IS_PROP_REINITABLE;
+			}
+		}
+
+		const zend_class_entry *old_scope = EG(fake_scope);
+
+		EG(fake_scope) = scope;
+
+		ZEND_HASH_FOREACH_KEY_VAL(properties, zend_ulong num_key, zend_string *key, zval *val) {
+			if (UNEXPECTED(Z_ISREF_P(val))) {
+				if (Z_REFCOUNT_P(val) == 1) {
+					val = Z_REFVAL_P(val);
+				} else {
+					zend_throw_error(NULL, "Cannot assign by reference when cloning with updated properties");
+					break;
+				}
+			}
 
-		OBJ_RELEASE(new_object);
+			if (UNEXPECTED(key == NULL)) {
+				key = zend_long_to_str(num_key);
+				new_object->handlers->write_property(new_object, key, val, NULL);
+				zend_string_release_ex(key, false);
+			} else {
+				new_object->handlers->write_property(new_object, key, val, NULL);
+			}
+
+			if (UNEXPECTED(EG(exception))) {
+				break;
+			}
+		} ZEND_HASH_FOREACH_END();
+
+		EG(fake_scope) = old_scope;
 	}
+
+	return new_object;
 }
 
 ZEND_API zend_object *zend_objects_clone_obj(zend_object *old_object)
diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h
index 41e3bcd9594b..0930fa043101 100644
--- a/Zend/zend_objects.h
+++ b/Zend/zend_objects.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -25,11 +24,12 @@
 BEGIN_EXTERN_C()
 ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce);
 ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce);
-ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, zend_object *old_object);
+ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, const zend_object *old_object);
 
 ZEND_API void zend_object_std_dtor(zend_object *object);
 ZEND_API void zend_objects_destroy_object(zend_object *object);
 ZEND_API zend_object *zend_objects_clone_obj(zend_object *object);
+ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *object, const zend_class_entry *scope, const HashTable *properties);
 
 void zend_object_dtor_dynamic_properties(zend_object *object);
 void zend_object_dtor_property(zend_object *object, zval *p);
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index c19873cf3be3..537cad8a3644 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -44,8 +43,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_sto
 {
 	EG(flags) |= EG_FLAGS_OBJECT_STORE_NO_REUSE;
 	if (objects->top > 1) {
-		uint32_t i;
-		for (i = 1; i < objects->top; i++) {
+		for (uint32_t i = 1; i < objects->top; i++) {
 			zend_object *obj = objects->object_buckets[i];
 			if (IS_OBJ_VALID(obj)) {
 				if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
@@ -128,20 +126,19 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_
 /* Store objects API */
 static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_objects_store_put_cold(zend_object *object)
 {
-	int handle;
 	uint32_t new_size = 2 * EG(objects_store).size;
 
 	EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, new_size * sizeof(zend_object*));
 	/* Assign size after realloc, in case it fails */
 	EG(objects_store).size = new_size;
-	handle = EG(objects_store).top++;
+	uint32_t handle = EG(objects_store).top++;
 	object->handle = handle;
 	EG(objects_store).object_buckets[handle] = object;
 }
 
 ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
 {
-	int handle;
+	uint32_t handle;
 
 	/* When in shutdown sequence - do not reuse previously freed handles, to make sure
 	 * the dtors for newly created objects are called in zend_objects_store_call_destructors() loop
diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h
index 242bf212ba9c..694ef398e374 100644
--- a/Zend/zend_objects_API.h
+++ b/Zend/zend_objects_API.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -80,7 +79,7 @@ static zend_always_inline void zend_object_release(zend_object *obj)
 	}
 }
 
-static zend_always_inline size_t zend_object_properties_size(zend_class_entry *ce)
+static zend_always_inline size_t zend_object_properties_size(const zend_class_entry *ce)
 {
 	return sizeof(zval) *
 		(ce->default_properties_count -
@@ -90,7 +89,7 @@ static zend_always_inline size_t zend_object_properties_size(zend_class_entry *c
 /* Allocates object type and zeros it, but not the standard zend_object and properties.
  * Standard object MUST be initialized using zend_object_std_init().
  * Properties MUST be initialized using object_properties_init(). */
-static zend_always_inline void *zend_object_alloc(size_t obj_size, zend_class_entry *ce) {
+static zend_always_inline void *zend_object_alloc(size_t obj_size, const zend_class_entry *ce) {
 	void *obj = emalloc(obj_size + zend_object_properties_size(ce));
 	memset(obj, 0, obj_size - sizeof(zend_object));
 	return obj;
@@ -137,5 +136,16 @@ static inline zend_property_info *zend_get_typed_property_info_for_slot(zend_obj
 	return NULL;
 }
 
+static zend_always_inline bool zend_check_method_accessible(const zend_function *fn, const zend_class_entry *scope)
+{
+	if (!(fn->common.fn_flags & ZEND_ACC_PUBLIC)
+		&& fn->common.scope != scope
+		&& (UNEXPECTED(fn->common.fn_flags & ZEND_ACC_PRIVATE)
+			|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fn), scope)))) {
+		return false;
+	}
+
+	return true;
+}
 
 #endif /* ZEND_OBJECTS_H */
diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c
index 15722eb6b2eb..1cb4373f4c07 100644
--- a/Zend/zend_observer.c
+++ b/Zend/zend_observer.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Levi Morrison                                |
    |          Sammy Kaye Powers                           |
@@ -115,8 +114,8 @@ ZEND_API void zend_observer_shutdown(void)
 
 static void zend_observer_fcall_install(zend_execute_data *execute_data)
 {
-	zend_llist *list = &zend_observers_fcall_list;
-	zend_function *function = execute_data->func;
+	const zend_llist *list = &zend_observers_fcall_list;
+	const zend_function *function = execute_data->func;
 
 	ZEND_ASSERT(RUN_TIME_CACHE(&function->common));
 	zend_observer_fcall_begin_handler *begin_handlers = ZEND_OBSERVER_DATA(function), *begin_handlers_start = begin_handlers;
@@ -126,7 +125,7 @@ static void zend_observer_fcall_install(zend_execute_data *execute_data)
 	*end_handlers = ZEND_OBSERVER_NOT_OBSERVED;
 	bool has_handlers = false;
 
-	for (zend_llist_element *element = list->head; element; element = element->next) {
+	for (const zend_llist_element *element = list->head; element; element = element->next) {
 		zend_observer_fcall_init init;
 		memcpy(&init, element->data, sizeof init);
 		zend_observer_fcall_handlers handlers = init(execute_data);
@@ -157,7 +156,7 @@ static void zend_observer_fcall_install(zend_execute_data *execute_data)
  * the previous next handler is now at the place where the current handler was.
  * Hence, the next handler executed will be the one after the next handler.
  * Callees must thus invoke the next handler themselves, with the same arguments they were passed. */
-static bool zend_observer_remove_handler(void **first_handler, void *old_handler, void **next_handler) {
+static bool zend_observer_remove_handler(void **first_handler, const void *old_handler, void **next_handler) {
 	size_t registered_observers = zend_observers_fcall_list.count;
 
 	void **last_handler = first_handler + registered_observers - 1;
@@ -168,7 +167,7 @@ static bool zend_observer_remove_handler(void **first_handler, void *old_handler
 				*next_handler = NULL;
 			} else {
 				if (cur_handler != last_handler) {
-					memmove(cur_handler, cur_handler + 1, sizeof(cur_handler) * (last_handler - cur_handler));
+					memmove(cur_handler, cur_handler + 1, sizeof(*cur_handler) * (last_handler - cur_handler));
 				}
 				*last_handler = NULL;
 				*next_handler = *cur_handler;
@@ -179,7 +178,7 @@ static bool zend_observer_remove_handler(void **first_handler, void *old_handler
 	return false;
 }
 
-ZEND_API void zend_observer_add_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin) {
+ZEND_API void zend_observer_add_begin_handler(const zend_function *function, zend_observer_fcall_begin_handler begin) {
 	size_t registered_observers = zend_observers_fcall_list.count;
 	zend_observer_fcall_begin_handler *first_handler = ZEND_OBSERVER_DATA(function), *last_handler = first_handler + registered_observers - 1;
 	if (*first_handler == ZEND_OBSERVER_NOT_OBSERVED || *first_handler == ZEND_OBSERVER_NONE_OBSERVED) {
@@ -196,7 +195,7 @@ ZEND_API void zend_observer_add_begin_handler(zend_function *function, zend_obse
 	}
 }
 
-ZEND_API bool zend_observer_remove_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin, zend_observer_fcall_begin_handler *next) {
+ZEND_API bool zend_observer_remove_begin_handler(const zend_function *function, zend_observer_fcall_begin_handler begin, zend_observer_fcall_begin_handler *next) {
 	void **begin_handlers = (void **)ZEND_OBSERVER_DATA(function);
 	if (zend_observer_remove_handler(begin_handlers, begin, (void**)next)) {
 		// Ensure invariant: ZEND_OBSERVER_NONE_OBSERVED in begin_handlers if both are not observed
@@ -211,7 +210,7 @@ ZEND_API bool zend_observer_remove_begin_handler(zend_function *function, zend_o
 	return false;
 }
 
-ZEND_API void zend_observer_add_end_handler(zend_function *function, zend_observer_fcall_end_handler end) {
+ZEND_API void zend_observer_add_end_handler(const zend_function *function, zend_observer_fcall_end_handler end) {
 	size_t registered_observers = zend_observers_fcall_list.count;
 	void **begin_handler = (void **)ZEND_OBSERVER_DATA(function);
 	zend_observer_fcall_end_handler *end_handler = (zend_observer_fcall_end_handler *)begin_handler + registered_observers;
@@ -219,14 +218,14 @@ ZEND_API void zend_observer_add_end_handler(zend_function *function, zend_observ
 	if (*end_handler != ZEND_OBSERVER_NOT_OBSERVED) {
 		// there's no space for new handlers, then it's forbidden to call this function
 		ZEND_ASSERT(end_handler[registered_observers - 1] == NULL);
-		memmove(end_handler + 1, end_handler, sizeof(end_handler) * (registered_observers - 1));
+		memmove(end_handler + 1, end_handler, sizeof(*end_handler) * (registered_observers - 1));
 	} else if (*begin_handler == ZEND_OBSERVER_NONE_OBSERVED) {
 		*begin_handler = ZEND_OBSERVER_NOT_OBSERVED;
 	}
 	*end_handler = end;
 }
 
-ZEND_API bool zend_observer_remove_end_handler(zend_function *function, zend_observer_fcall_end_handler end, zend_observer_fcall_end_handler *next) {
+ZEND_API bool zend_observer_remove_end_handler(const zend_function *function, zend_observer_fcall_end_handler end, zend_observer_fcall_end_handler *next) {
 	size_t registered_observers = zend_observers_fcall_list.count;
 	void **begin_handlers = (void **)ZEND_OBSERVER_DATA(function);
 	void **end_handlers = begin_handlers + registered_observers;
@@ -241,7 +240,7 @@ ZEND_API bool zend_observer_remove_end_handler(zend_function *function, zend_obs
 }
 
 static inline zend_execute_data **prev_observed_frame(zend_execute_data *execute_data) {
-	zend_function *func = EX(func);
+	const zend_function *func = EX(func);
 	ZEND_ASSERT(func);
 	return (zend_execute_data **)&Z_PTR_P(EX_VAR_NUM((ZEND_USER_CODE(func->type) ? func->op_array.last_var : ZEND_CALL_NUM_ARGS(execute_data)) + func->common.T - 1));
 }
@@ -256,7 +255,7 @@ static void ZEND_FASTCALL _zend_observe_fcall_begin(zend_execute_data *execute_d
 
 ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin_prechecked(zend_execute_data *execute_data, zend_observer_fcall_begin_handler *handler)
 {
-	zend_observer_fcall_begin_handler *possible_handlers_end = handler + zend_observers_fcall_list.count;
+	const zend_observer_fcall_begin_handler *possible_handlers_end = handler + zend_observers_fcall_list.count;
 
 	if (!*handler) {
 		zend_observer_fcall_install(execute_data);
@@ -265,7 +264,7 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin_prechecked(zend_execute_da
 		}
 	}
 
-	zend_observer_fcall_end_handler *end_handler = (zend_observer_fcall_end_handler *)possible_handlers_end;
+	const zend_observer_fcall_end_handler *end_handler = (const zend_observer_fcall_end_handler *)possible_handlers_end;
 	if (*end_handler != ZEND_OBSERVER_NOT_OBSERVED) {
 		*prev_observed_frame(execute_data) = EG(current_observed_frame);
 		EG(current_observed_frame) = execute_data;
@@ -294,7 +293,7 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin(zend_execute_data *execute
 }
 
 static inline void call_end_observers(zend_execute_data *execute_data, zval *return_value) {
-	zend_function *func = EX(func);
+	const zend_function *func = EX(func);
 	ZEND_ASSERT(func);
 
 	zend_observer_fcall_end_handler *handler = (zend_observer_fcall_end_handler *)ZEND_OBSERVER_DATA(func) + zend_observers_fcall_list.count;
@@ -340,7 +339,7 @@ ZEND_API void ZEND_FASTCALL _zend_observer_function_declared_notify(zend_op_arra
 		return;
 	}
 
-	for (zend_llist_element *element = zend_observer_function_declared_callbacks.head; element; element = element->next) {
+	for (const zend_llist_element *element = zend_observer_function_declared_callbacks.head; element; element = element->next) {
 		zend_observer_function_declared_cb callback = *(zend_observer_function_declared_cb *) (element->data);
 		callback(op_array, name);
 	}
@@ -358,7 +357,7 @@ ZEND_API void ZEND_FASTCALL _zend_observer_class_linked_notify(zend_class_entry
 		return;
 	}
 
-	for (zend_llist_element *element = zend_observer_class_linked_callbacks.head; element; element = element->next) {
+	for (const zend_llist_element *element = zend_observer_class_linked_callbacks.head; element; element = element->next) {
 		zend_observer_class_linked_cb callback = *(zend_observer_class_linked_cb *) (element->data);
 		callback(ce, name);
 	}
@@ -372,7 +371,7 @@ ZEND_API void zend_observer_error_register(zend_observer_error_cb cb)
 
 ZEND_API void _zend_observer_error_notify(int type, zend_string *error_filename, uint32_t error_lineno, zend_string *message)
 {
-	for (zend_llist_element *element = zend_observer_error_callbacks.head; element; element = element->next) {
+	for (const zend_llist_element *element = zend_observer_error_callbacks.head; element; element = element->next) {
 		zend_observer_error_cb callback = *(zend_observer_error_cb *) (element->data);
 		callback(type, error_filename, error_lineno, message);
 	}
@@ -395,12 +394,11 @@ ZEND_API void zend_observer_fiber_destroy_register(zend_observer_fiber_destroy_h
 
 ZEND_API void ZEND_FASTCALL zend_observer_fiber_init_notify(zend_fiber_context *initializing)
 {
-	zend_llist_element *element;
 	zend_observer_fiber_init_handler callback;
 
 	initializing->top_observed_frame = NULL;
 
-	for (element = zend_observer_fiber_init.head; element; element = element->next) {
+	for (const zend_llist_element *element = zend_observer_fiber_init.head; element; element = element->next) {
 		callback = *(zend_observer_fiber_init_handler *) element->data;
 		callback(initializing);
 	}
@@ -408,14 +406,13 @@ ZEND_API void ZEND_FASTCALL zend_observer_fiber_init_notify(zend_fiber_context *
 
 ZEND_API void ZEND_FASTCALL zend_observer_fiber_switch_notify(zend_fiber_context *from, zend_fiber_context *to)
 {
-	zend_llist_element *element;
 	zend_observer_fiber_switch_handler callback;
 
 	if (from->status == ZEND_FIBER_STATUS_DEAD) {
 		zend_observer_fcall_end_all(); // fiber is either finished (call will do nothing) or has bailed out
 	}
 
-	for (element = zend_observer_fiber_switch.head; element; element = element->next) {
+	for (const zend_llist_element *element = zend_observer_fiber_switch.head; element; element = element->next) {
 		callback = *(zend_observer_fiber_switch_handler *) element->data;
 		callback(from, to);
 	}
@@ -426,10 +423,9 @@ ZEND_API void ZEND_FASTCALL zend_observer_fiber_switch_notify(zend_fiber_context
 
 ZEND_API void ZEND_FASTCALL zend_observer_fiber_destroy_notify(zend_fiber_context *destroying)
 {
-	zend_llist_element *element;
 	zend_observer_fiber_destroy_handler callback;
 
-	for (element = zend_observer_fiber_destroy.head; element; element = element->next) {
+	for (const zend_llist_element *element = zend_observer_fiber_destroy.head; element; element = element->next) {
 		callback = *(zend_observer_fiber_destroy_handler *) element->data;
 		callback(destroying);
 	}
diff --git a/Zend/zend_observer.h b/Zend/zend_observer.h
index bb8964692c37..f4ade29285db 100644
--- a/Zend/zend_observer.h
+++ b/Zend/zend_observer.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Levi Morrison                                |
    |          Sammy Kaye Powers                           |
@@ -74,10 +73,10 @@ ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init);
 
 // Call during runtime, but only if you have used zend_observer_fcall_register.
 // You must not have more than one begin and one end handler active at the same time. Remove the old one first, if there is an existing one.
-ZEND_API void zend_observer_add_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin);
-ZEND_API bool zend_observer_remove_begin_handler(zend_function *function, zend_observer_fcall_begin_handler begin, zend_observer_fcall_begin_handler *next);
-ZEND_API void zend_observer_add_end_handler(zend_function *function, zend_observer_fcall_end_handler end);
-ZEND_API bool zend_observer_remove_end_handler(zend_function *function, zend_observer_fcall_end_handler end, zend_observer_fcall_end_handler *next);
+ZEND_API void zend_observer_add_begin_handler(const zend_function *function, zend_observer_fcall_begin_handler begin);
+ZEND_API bool zend_observer_remove_begin_handler(const zend_function *function, zend_observer_fcall_begin_handler begin, zend_observer_fcall_begin_handler *next);
+ZEND_API void zend_observer_add_end_handler(const zend_function *function, zend_observer_fcall_end_handler end);
+ZEND_API bool zend_observer_remove_end_handler(const zend_function *function, zend_observer_fcall_end_handler end, zend_observer_fcall_end_handler *next);
 
 ZEND_API void zend_observer_startup(void); // Called by engine before MINITs
 ZEND_API void zend_observer_post_startup(void); // Called by engine after MINITs
@@ -88,13 +87,13 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin(zend_execute_data *execute
 /* prechecked: the call is actually observed. */
 ZEND_API void ZEND_FASTCALL zend_observer_fcall_begin_prechecked(zend_execute_data *execute_data, zend_observer_fcall_begin_handler *observer_data);
 
-static zend_always_inline bool zend_observer_handler_is_unobserved(zend_observer_fcall_begin_handler *handler) {
+static zend_always_inline bool zend_observer_handler_is_unobserved(const zend_observer_fcall_begin_handler *handler) {
 	return *handler == ZEND_OBSERVER_NONE_OBSERVED;
 }
 
 /* Initial check for observers has not happened yet or no observers are installed. */
-static zend_always_inline bool zend_observer_fcall_has_no_observers(zend_execute_data *execute_data, bool allow_generator, zend_observer_fcall_begin_handler **handler) {
-	zend_function *function = EX(func);
+static zend_always_inline bool zend_observer_fcall_has_no_observers(const zend_execute_data *execute_data, bool allow_generator, zend_observer_fcall_begin_handler **handler) {
+	const zend_function *function = EX(func);
 	void *ZEND_MAP_PTR(runtime_cache) = ZEND_MAP_PTR(function->common.run_time_cache);
 
 	if (function->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE | (allow_generator ? 0 : ZEND_ACC_GENERATOR))) {
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 6e7d31e15a40..8c1dcd7c0fc0 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -25,6 +24,7 @@
 #include "zend_compile.h"
 #include "zend_extensions.h"
 #include "zend_API.h"
+#include "zend_inheritance.h"
 #include "zend_sort.h"
 #include "zend_constants.h"
 #include "zend_observer.h"
@@ -45,7 +45,7 @@ static void zend_extension_op_array_dtor_handler(zend_extension *extension, zend
 	}
 }
 
-void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size)
+void init_op_array(zend_op_array *op_array, zend_function_type type, int initial_ops_size)
 {
 	op_array->type = type;
 	op_array->arg_flags[0] = 0;
@@ -84,6 +84,7 @@ void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size)
 	op_array->last_try_catch = 0;
 
 	op_array->fn_flags = 0;
+	op_array->fn_flags2 = 0;
 
 	op_array->last_literal = 0;
 	op_array->literals = NULL;
@@ -91,6 +92,9 @@ void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size)
 	op_array->num_dynamic_func_defs = 0;
 	op_array->dynamic_func_defs = NULL;
 
+	op_array->generic_parameters = NULL;
+	op_array->generic_types = NULL;
+
 	ZEND_MAP_PTR_INIT(op_array->run_time_cache, NULL);
 	op_array->cache_size = zend_op_array_extension_handles * sizeof(void*);
 
@@ -118,26 +122,308 @@ ZEND_API void zend_type_release(zend_type type, bool persistent) {
 		if (!ZEND_TYPE_USES_ARENA(type)) {
 			pefree(ZEND_TYPE_LIST(type), persistent);
 		}
+	} else if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) {
+		zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(type);
+		if (named->name) {
+			zend_string_release(named->name);
+		}
+		for (uint32_t i = 0; i < named->count; i++) {
+			zend_type_release(named->args[i], persistent);
+		}
+		pefree(named, persistent);
+	} else if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) {
+		zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(type);
+		if (ref->name) {
+			zend_string_release(ref->name);
+		}
+		pefree(ref, persistent);
 	} else if (ZEND_TYPE_HAS_NAME(type)) {
 		zend_string_release(ZEND_TYPE_NAME(type));
 	}
 }
 
-void zend_free_internal_arg_info(zend_internal_function *function) {
-	if ((function->fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
-		function->arg_info) {
+ZEND_API zend_generic_parameter_list *zend_generic_parameter_list_alloc(uint32_t count, bool persistent) {
+	ZEND_ASSERT(count > 0);
+	zend_generic_parameter_list *list = pemalloc(ZEND_GENERIC_PARAMETER_LIST_SIZE(count), persistent);
+	list->count = count;
+	list->inferable_mask = 0;
+	for (uint32_t i = 0; i < count; i++) {
+		list->parameters[i].name = NULL;
+		list->parameters[i].variance = 0;
+		list->parameters[i].bound = (zend_type) ZEND_TYPE_INIT_NONE(0);
+		list->parameters[i].bound_pre_erasure = (zend_type) ZEND_TYPE_INIT_NONE(0);
+		list->parameters[i].default_type = (zend_type) ZEND_TYPE_INIT_NONE(0);
+		list->parameters[i].default_pre_erasure = (zend_type) ZEND_TYPE_INIT_NONE(0);
+	}
+	return list;
+}
+
+ZEND_API void zend_generic_parameter_list_destroy(zend_generic_parameter_list *list) {
+	if (!list) {
+		return;
+	}
+	for (uint32_t i = 0; i < list->count; i++) {
+		zend_generic_parameter *param = &list->parameters[i];
+		if (param->name) {
+			zend_string_release(param->name);
+		}
+		zend_type_release(param->bound, /* persistent */ false);
+		zend_type_release(param->bound_pre_erasure, /* persistent */ false);
+		zend_type_release(param->default_type, /* persistent */ false);
+		zend_type_release(param->default_pre_erasure, /* persistent */ false);
+	}
+	efree(list);
+}
+
+static void zend_generic_type_table_value_dtor(zval *zv) {
+	zend_type *type = Z_PTR_P(zv);
+	zend_type_release(*type, /* persistent */ false);
+	efree(type);
+}
+
+/* Dtor for turbofish_args entries: each one owns an inline args_box.
+ * The per-call-site runtime cache that stashes the most recently built
+ * zend_type_arg_table for this entry lives in the caller op_array's
+ * runtime cache slot, so it's released by the op_array runtime-cache
+ * teardown — not here. */
+static void zend_turbofish_args_entry_dtor(zval *zv) {
+	zend_turbofish_args_entry *entry = Z_PTR_P(zv);
+	zend_type_release(entry->args_box, /* persistent */ false);
+	/* Free the heap concrete table; SHM-relocated tables have persisted set. */
+	if (entry->concrete_table && !entry->concrete_table->persisted) {
+		zend_type_arg_table_destroy(entry->concrete_table);
+	}
+	efree(entry);
+}
+
+ZEND_API zend_generic_type_table *zend_generic_type_table_alloc(void) {
+	zend_generic_type_table *table = ecalloc(1, sizeof(zend_generic_type_table));
+	return table;
+}
+
+ZEND_API void zend_generic_type_table_destroy(zend_generic_type_table *table) {
+	if (!table || table->persisted) {
+		return;
+	}
+
+	if (table->return_type) {
+		zend_type_release(*table->return_type, /* persistent */ false);
+		efree(table->return_type);
+	}
+	if (table->extends) {
+		zend_type_release(*table->extends, /* persistent */ false);
+		efree(table->extends);
+	}
+	if (table->parameters) {
+		zend_hash_destroy(table->parameters);
+		FREE_HASHTABLE(table->parameters);
+	}
+	if (table->properties) {
+		zend_hash_destroy(table->properties);
+		FREE_HASHTABLE(table->properties);
+	}
+	if (table->class_constants) {
+		zend_hash_destroy(table->class_constants);
+		FREE_HASHTABLE(table->class_constants);
+	}
+	if (table->implements) {
+		zend_hash_destroy(table->implements);
+		FREE_HASHTABLE(table->implements);
+	}
+	if (table->trait_uses) {
+		zend_hash_destroy(table->trait_uses);
+		FREE_HASHTABLE(table->trait_uses);
+	}
+	if (table->turbofish_args) {
+		zend_hash_destroy(table->turbofish_args);
+		FREE_HASHTABLE(table->turbofish_args);
+	}
+	if (table->value_check_plan) {
+		efree(table->value_check_plan);
+	}
+	efree(table);
+}
+
+static HashTable *zend_generic_type_table_ensure_indexed(HashTable **slot) {
+	if (!*slot) {
+		HashTable *ht;
+		ALLOC_HASHTABLE(ht);
+		zend_hash_init(ht, 4, NULL, zend_generic_type_table_value_dtor, /* persistent */ false);
+		*slot = ht;
+	}
+	return *slot;
+}
+
+static HashTable *zend_generic_type_table_ensure_turbofish(HashTable **slot) {
+	if (!*slot) {
+		HashTable *ht;
+		ALLOC_HASHTABLE(ht);
+		zend_hash_init(ht, 4, NULL, zend_turbofish_args_entry_dtor, /* persistent */ false);
+		*slot = ht;
+	}
+	return *slot;
+}
+
+static HashTable *zend_generic_type_table_ensure_named(HashTable **slot) {
+	if (!*slot) {
+		HashTable *ht;
+		ALLOC_HASHTABLE(ht);
+		zend_hash_init(ht, 4, NULL, zend_generic_type_table_value_dtor, /* persistent */ false);
+		*slot = ht;
+	}
+	return *slot;
+}
+
+static zend_type *zend_type_box(zend_type type) {
+	zend_type *boxed = emalloc(sizeof(zend_type));
+	*boxed = type;
+	return boxed;
+}
+
+ZEND_API void zend_generic_type_table_set_return(zend_generic_type_table *t, zend_type type) {
+	if (t->return_type) {
+		zend_type_release(*t->return_type, /* persistent */ false);
+		efree(t->return_type);
+	}
+	t->return_type = zend_type_box(type);
+}
+
+ZEND_API void zend_generic_type_table_set_extends(zend_generic_type_table *t, zend_type type) {
+	if (t->extends) {
+		zend_type_release(*t->extends, /* persistent */ false);
+		efree(t->extends);
+	}
+	t->extends = zend_type_box(type);
+}
+
+ZEND_API void zend_generic_type_table_set_parameter(zend_generic_type_table *t, uint32_t idx, zend_type type) {
+	zend_hash_index_update_ptr(zend_generic_type_table_ensure_indexed(&t->parameters), idx, zend_type_box(type));
+}
+
+ZEND_API void zend_generic_type_table_set_property(zend_generic_type_table *t, zend_string *name, zend_type type) {
+	zend_hash_update_ptr(zend_generic_type_table_ensure_named(&t->properties), name, zend_type_box(type));
+}
+
+ZEND_API void zend_generic_type_table_set_class_constant(zend_generic_type_table *t, zend_string *name, zend_type type) {
+	zend_hash_update_ptr(zend_generic_type_table_ensure_named(&t->class_constants), name, zend_type_box(type));
+}
+
+ZEND_API void zend_generic_type_table_set_implements(zend_generic_type_table *t, uint32_t idx, zend_type type) {
+	zend_hash_index_update_ptr(zend_generic_type_table_ensure_indexed(&t->implements), idx, zend_type_box(type));
+}
+
+ZEND_API void zend_generic_type_table_set_trait_use(zend_generic_type_table *t, uint32_t idx, zend_type type) {
+	zend_hash_index_update_ptr(zend_generic_type_table_ensure_indexed(&t->trait_uses), idx, zend_type_box(type));
+}
+
+ZEND_API void zend_generic_type_table_set_turbofish_args(zend_generic_type_table *t, uint32_t op_num, zend_type type) {
+	zend_turbofish_args_entry *entry = emalloc(sizeof(*entry));
+	entry->args_box = type;
+	entry->concrete_table = NULL;
+	entry->concrete_skip_value_check = false;
+	zend_hash_index_update_ptr(zend_generic_type_table_ensure_turbofish(&t->turbofish_args), op_num, entry);
+}
+
+/* Monotonic nonce stamped onto every allocated zend_type_arg_table so PIC
+ * slots can distinguish "same table" from "same address, reused table." 32
+ * bits gives ~4 billion allocations between potential rollovers, which is
+ * fine for in-request scope. */
+static uint32_t zend_type_arg_table_generation_counter = 1;
+
+ZEND_API zend_type_arg_table *zend_type_arg_table_alloc(uint32_t count) {
+	zend_type_arg_table *table = emalloc(ZEND_TYPE_ARG_TABLE_SIZE(count));
+	table->count = count;
+	table->generation = zend_type_arg_table_generation_counter++;
+	table->persisted = false;
+	for (uint32_t i = 0; i < count; i++) {
+		table->entries[i].name = NULL;
+		table->entries[i].type_ref = NULL;
+		table->entries[i].owned_type = (zend_type) ZEND_TYPE_INIT_NONE(0);
+	}
+	return table;
+}
+
+ZEND_API void zend_type_arg_table_destroy(zend_type_arg_table *table) {
+	if (!table || table->persisted) {
+		return;
+	}
+	for (uint32_t i = 0; i < table->count; i++) {
+		if (table->entries[i].name) {
+			zend_string_release(table->entries[i].name);
+		}
+		/* type_ref is borrowed — never released here. owned_type is the
+		 * locally-synthesised fallback (inference) and is. */
+		if (ZEND_TYPE_IS_SET(table->entries[i].owned_type)) {
+			zend_type_release(table->entries[i].owned_type, /* persistent */ false);
+		}
+	}
+	efree(table);
+}
+
+/* Clone a type-arg table for long-lived capture (e.g., closure capture). All
+ * entries are materialised into `owned_type` so the resulting table owns its
+ * type contents and doesn't depend on the source's lifetime. Returned table
+ * is marked persisted so frame teardown leaves it alone; the holder is
+ * responsible for clearing persisted and destroying when it's done. */
+ZEND_API zend_type_arg_table *zend_type_arg_table_capture_clone(const zend_type_arg_table *src) {
+	if (!src) {
+		return NULL;
+	}
+	zend_type_arg_table *dst = zend_type_arg_table_alloc(src->count);
+	dst->persisted = true;
+	for (uint32_t i = 0; i < src->count; i++) {
+		const zend_type_arg_entry *se = &src->entries[i];
+		zend_type_arg_entry *de = &dst->entries[i];
+		if (se->name) {
+			de->name = zend_string_copy(se->name);
+		}
+		const zend_type *src_type = zend_type_arg_entry_type(se);
+		if (src_type && ZEND_TYPE_IS_SET(*src_type)) {
+			zend_type owned = *src_type;
+			zend_type_copy_ctor(&owned, /* use_arena */ false, /* persistent */ false);
+			de->owned_type = owned;
+		}
+	}
+	return dst;
+}
+
+/* Always returns the canonical name of the bound type — class names, monomorph
+ * applications (`Box`), scalars (`int`, `string`), and unions/intersections.
+ * Callers that only care about class-name dispatch should themselves check
+ * whether the lookup succeeded. Returns NULL only for unset/empty types. */
+ZEND_API zend_string *zend_type_arg_canonical_name(zend_type type) {
+	if (!ZEND_TYPE_IS_SET(type)) {
+		return NULL;
+	}
+	return zend_type_to_canonical_string(type);
+}
+
+ZEND_API void zend_free_internal_arg_info(zend_internal_function *function,
+		bool persistent) {
+	if (function->arg_info) {
+		ZEND_ASSERT((persistent || (function->fn_flags & ZEND_ACC_NEVER_CACHE))
+				&& "Functions with non-persistent arg_info must be flagged ZEND_ACC_NEVER_CACHE");
 
 		uint32_t i;
 		uint32_t num_args = function->num_args + 1;
-		zend_internal_arg_info *arg_info = function->arg_info - 1;
+		zend_arg_info *arg_info = function->arg_info - 1;
 
 		if (function->fn_flags & ZEND_ACC_VARIADIC) {
 			num_args++;
 		}
 		for (i = 0 ; i < num_args; i++) {
-			zend_type_release(arg_info[i].type, /* persistent */ 1);
+			bool is_return_info = i == 0;
+			if (!is_return_info) {
+				zend_string_release_ex(arg_info[i].name, persistent);
+				if (arg_info[i].default_value) {
+					zend_string_release_ex(arg_info[i].default_value,
+							persistent);
+				}
+			}
+			zend_type_release(arg_info[i].type, persistent);
 		}
-		free(arg_info);
+
+		pefree(arg_info, persistent);
 	}
 }
 
@@ -156,7 +442,7 @@ ZEND_API void zend_function_dtor(zval *zv)
 
 		/* For methods this will be called explicitly. */
 		if (!function->common.scope) {
-			zend_free_internal_arg_info(&function->internal_function);
+			zend_free_internal_arg_info(&function->internal_function, true);
 
 			if (function->common.attributes) {
 				zend_hash_release(function->common.attributes);
@@ -324,6 +610,13 @@ ZEND_API void destroy_zend_class(zval *zv)
 				p++;
 			}
 		}
+		/* Monomorph args are heap-allocated per request, not relocated into
+		 * the opcache file cache; free them even when the rest of the ce is
+		 * cache-resident. */
+		if (ce->generic_type_args) {
+			zend_type_arg_table_destroy(ce->generic_type_args);
+			ce->generic_type_args = NULL;
+		}
 		return;
 	}
 
@@ -396,7 +689,15 @@ ZEND_API void destroy_zend_class(zval *zv)
 					if (prop_info->attributes) {
 						zend_hash_release(prop_info->attributes);
 					}
-					zend_type_release(prop_info->type, /* persistent */ 0);
+					zend_type_release(prop_info->type, /* persistent */ false);
+					if (prop_info->hooks) {
+						for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
+							if (prop_info->hooks[i]) {
+								destroy_op_array(&prop_info->hooks[i]->op_array);
+							}
+						}
+					}
+				} else if (prop_info->flags & ZEND_ACC_GENERIC_CLONE) {
 					if (prop_info->hooks) {
 						for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
 							if (prop_info->hooks[i]) {
@@ -430,6 +731,15 @@ ZEND_API void destroy_zend_class(zval *zv)
 			if (ce->backed_enum_table) {
 				zend_hash_release(ce->backed_enum_table);
 			}
+			if (ce->generic_parameters) {
+				zend_generic_parameter_list_destroy(ce->generic_parameters);
+			}
+			if (ce->generic_types) {
+				zend_generic_type_table_destroy(ce->generic_types);
+			}
+			if (ce->generic_type_args) {
+				zend_type_arg_table_destroy(ce->generic_type_args);
+			}
 			break;
 		case ZEND_INTERNAL_CLASS:
 			if (ce->doc_comment) {
@@ -463,22 +773,27 @@ ZEND_API void destroy_zend_class(zval *zv)
 			ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop_info) {
 				if (prop_info->ce == ce) {
 					zend_string_release(prop_info->name);
-					zend_type_release(prop_info->type, /* persistent */ 1);
+					zend_type_release(prop_info->type, /* persistent */ true);
 					if (prop_info->attributes) {
 						zend_hash_release(prop_info->attributes);
 					}
 					free(prop_info);
+				} else if (prop_info->flags & ZEND_ACC_GENERIC_CLONE) {
+					/* Cross-class generic clones (e.g., Holder's property
+					 * cloned into the Holder monomorph) take their own
+					 * reference on the borrowed name string in
+					 * do_inherit_property; release it here on the holder's
+					 * destruction so the count balances. The prop_info struct
+					 * itself is arena-allocated and freed in bulk. */
+					zend_string_release(prop_info->name);
 				}
 			} ZEND_HASH_FOREACH_END();
 			zend_hash_destroy(&ce->properties_info);
 			zend_string_release_ex(ce->name, 1);
 
-			/* TODO: eliminate this loop for classes without functions with arg_info / attributes */
 			ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
 				if (fn->common.scope == ce) {
-					if (fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) {
-						zend_free_internal_arg_info(&fn->internal_function);
-					}
+					zend_free_internal_arg_info(&fn->internal_function, true);
 
 					if (fn->common.attributes) {
 						zend_hash_release(fn->common.attributes);
@@ -556,6 +871,52 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
 {
 	uint32_t i;
 
+	/* VERIFY/INSTALL_GENERIC_ARGS on a CALL site (op1_type == IS_UNUSED) may
+	 * have stashed a zend_type_arg_table* in their cache slot, marked persisted
+	 * so per-frame teardown leaves it alone. The cache slot owns that
+	 * allocation; release the contained tables for every op_array, regardless
+	 * of whether the cache buffer itself is heap- or arena-allocated.
+	 *
+	 * The NEW form of the same opcodes (op1_type != IS_UNUSED) instead caches a
+	 * resolved monomorph zend_class_entry* in slot[0]. That entry is owned by
+	 * EG(class_table), NOT by the cache slot, so it must be left untouched here
+	 * — freeing it as a type_arg_table corrupts the heap. */
+	if ((op_array->fn_flags2 & ZEND_ACC2_HAS_GENERIC_CALL_OPS)
+	 && op_array->opcodes && ZEND_MAP_PTR(op_array->run_time_cache)) {
+		char *cache_buf = (char *) ZEND_MAP_PTR_GET(op_array->run_time_cache);
+		if (cache_buf) {
+			for (uint32_t op_idx = 0; op_idx < op_array->last; op_idx++) {
+				const zend_op *op = &op_array->opcodes[op_idx];
+				if ((op->opcode == ZEND_VERIFY_GENERIC_ARGUMENTS
+						|| op->opcode == ZEND_INSTALL_GENERIC_ARGS)
+						&& op->op1_type == IS_UNUSED
+						&& op->result.num) {
+					void **cache_slot = (void **) (cache_buf + op->result.num);
+					/* Monomorphized site: slot[0] is a function* owned by
+					 * EG(function_table); free only slot[4]'s type_arg table. */
+					if ((uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH) {
+						zend_type_arg_table *mt = (zend_type_arg_table *) cache_slot[4];
+						if (mt) {
+							mt->persisted = false;
+							zend_type_arg_table_destroy(mt);
+							cache_slot[4] = NULL;
+						}
+						cache_slot[0] = NULL;
+						cache_slot[1] = NULL;
+						continue;
+					}
+					zend_type_arg_table *t = (zend_type_arg_table *) cache_slot[0];
+					if (t) {
+						t->persisted = false;
+						zend_type_arg_table_destroy(t);
+						cache_slot[0] = NULL;
+						cache_slot[1] = NULL;
+					}
+				}
+			}
+		}
+	}
+
 	if ((op_array->fn_flags & ZEND_ACC_HEAP_RT_CACHE)
 	 && ZEND_MAP_PTR(op_array->run_time_cache)) {
 		efree(ZEND_MAP_PTR(op_array->run_time_cache));
@@ -639,7 +1000,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
 			if (arg_info[i].name) {
 				zend_string_release_ex(arg_info[i].name, 0);
 			}
-			zend_type_release(arg_info[i].type, /* persistent */ 0);
+			if (arg_info[i].doc_comment) {
+				zend_string_release_ex(arg_info[i].doc_comment, 0);
+			}
+			zend_type_release(arg_info[i].type, /* persistent */ false);
 		}
 		efree(arg_info);
 	}
@@ -652,6 +1016,12 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
 		}
 		efree(op_array->dynamic_func_defs);
 	}
+	if (op_array->generic_parameters) {
+		zend_generic_parameter_list_destroy(op_array->generic_parameters);
+	}
+	if (op_array->generic_types) {
+		zend_generic_type_table_destroy(op_array->generic_types);
+	}
 }
 
 static void zend_update_extended_stmts(zend_op_array *op_array)
@@ -686,9 +1056,7 @@ static void zend_extension_op_array_handler(zend_extension *extension, zend_op_a
 
 static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num, uint32_t dst_num)
 {
-	int i;
-
-	for (i = 0; i < op_array->last_try_catch; i++) {
+	for (uint32_t i = 0; i < op_array->last_try_catch; i++) {
 		if ((op_num < op_array->try_catch_array[i].finally_op ||
 					op_num >= op_array->try_catch_array[i].finally_end)
 				&& (dst_num >= op_array->try_catch_array[i].finally_op &&
@@ -709,7 +1077,7 @@ static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num
 	}
 }
 
-static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const zend_op *opline) {
+static uint32_t zend_get_brk_cont_target(const zend_op *opline) {
 	int nest_levels = opline->op2.num;
 	int array_offset = opline->op1.num;
 	zend_brk_cont_element *jmp_to;
@@ -903,15 +1271,16 @@ static bool keeps_op1_alive(zend_op *opline) {
 	 || opline->opcode == ZEND_MATCH_ERROR
 	 || opline->opcode == ZEND_FETCH_LIST_R
 	 || opline->opcode == ZEND_FETCH_LIST_W
-	 || opline->opcode == ZEND_COPY_TMP) {
-		return 1;
+	 || opline->opcode == ZEND_COPY_TMP
+	 || opline->opcode == ZEND_EXT_STMT) {
+		return true;
 	}
 	ZEND_ASSERT(opline->opcode != ZEND_FE_FETCH_R
 		&& opline->opcode != ZEND_FE_FETCH_RW
 		&& opline->opcode != ZEND_VERIFY_RETURN_TYPE
 		&& opline->opcode != ZEND_BIND_LEXICAL
 		&& opline->opcode != ZEND_ROPE_ADD);
-	return 0;
+	return false;
 }
 
 /* Live ranges must be sorted by increasing start opline */
@@ -986,6 +1355,35 @@ static void zend_calc_live_ranges(
 					/* OP_DATA is really part of the previous opcode. */
 					last_use[var_num] = opnum - (opline->opcode == ZEND_OP_DATA);
 				}
+			} else if ((opline->opcode == ZEND_FREE || opline->opcode == ZEND_FE_FREE) && opline->extended_value & ZEND_FREE_ON_RETURN) {
+				int jump_offset = 1;
+				while (((opline + jump_offset)->opcode == ZEND_FREE || (opline + jump_offset)->opcode == ZEND_FE_FREE)
+					&& (opline + jump_offset)->extended_value & ZEND_FREE_ON_RETURN) {
+					++jump_offset;
+				}
+				// loop var frees directly precede the jump (or return) operand, except that ZEND_VERIFY_RETURN_TYPE may happen first.
+				if ((opline + jump_offset)->opcode == ZEND_VERIFY_RETURN_TYPE) {
+					++jump_offset;
+				}
+				/* FREE with ZEND_FREE_ON_RETURN immediately followed by RETURN frees
+				 * the loop variable on early return. We need to split the live range
+				 * so GC doesn't access the freed variable after this FREE. */
+				uint32_t opnum_last_use = last_use[var_num];
+				zend_op *opline_last_use = op_array->opcodes + opnum_last_use;
+				ZEND_ASSERT(opline_last_use->opcode == opline->opcode); // any ZEND_FREE_ON_RETURN must be followed by a FREE without
+				if (opnum + jump_offset + 1 != opnum_last_use) {
+					emit_live_range_raw(op_array, var_num, opline->opcode == ZEND_FE_FREE ? ZEND_LIVE_LOOP : ZEND_LIVE_TMPVAR,
+							opnum + jump_offset + 1, opnum_last_use);
+				}
+
+				/* Update last_use so next range includes this FREE */
+				last_use[var_num] = opnum;
+
+				/* Store opline offset to loop end */
+				opline->op2.opline_num = opnum_last_use - opnum;
+				if (opline_last_use->extended_value & ZEND_FREE_ON_RETURN) {
+					opline->op2.opline_num += opline_last_use->op2.opline_num;
+				}
 			}
 		}
 		if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
@@ -1120,7 +1518,7 @@ ZEND_API void pass_two(zend_op_array *op_array)
 			case ZEND_BRK:
 			case ZEND_CONT:
 				{
-					uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline);
+					uint32_t jmp_target = zend_get_brk_cont_target(opline);
 
 					if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
 						zend_check_finally_breakout(op_array, opline - op_array->opcodes, jmp_target);
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 712a6039dfb1..f5cfed3d5e26 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -359,7 +358,7 @@ static zend_never_inline zend_result ZEND_FASTCALL _zendi_try_convert_scalar_to_
 		case IS_RESOURCE:
 		case IS_ARRAY:
 			return FAILURE;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -377,7 +376,7 @@ static zend_always_inline zend_result zendi_try_convert_scalar_to_number(zval *o
 
 static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *op, bool *failed) /* {{{ */
 {
-	*failed = 0;
+	*failed = false;
 try_again:
 	switch (Z_TYPE_P(op)) {
 		case IS_NULL:
@@ -387,12 +386,9 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
 			return 1;
 		case IS_DOUBLE: {
 			double dval = Z_DVAL_P(op);
-			zend_long lval = zend_dval_to_lval(dval);
-			if (!zend_is_long_compatible(dval, lval)) {
-				zend_incompatible_double_to_long_error(dval);
-				if (UNEXPECTED(EG(exception))) {
-					*failed = 1;
-				}
+			zend_long lval = zend_dval_to_lval_safe(dval);
+			if (UNEXPECTED(EG(exception))) {
+				*failed = true;
 			}
 			return lval;
 		}
@@ -402,18 +398,24 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
 				zend_long lval;
 				double dval;
 				bool trailing_data = false;
+				zend_string *op_str = NULL; /* protect against error handlers */
 
 				/* For BC reasons we allow errors so that we can warn on leading numeric string */
 				type = is_numeric_string_ex(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval,
 					/* allow errors */ true, NULL, &trailing_data);
 				if (type == 0) {
-					*failed = 1;
+					*failed = true;
 					return 0;
 				}
 				if (UNEXPECTED(trailing_data)) {
+					if (type != IS_LONG) {
+						op_str = zend_string_copy(Z_STR_P(op));
+					}
 					zend_error(E_WARNING, "A non-numeric value encountered");
 					if (UNEXPECTED(EG(exception))) {
-						*failed = 1;
+						*failed = true;
+						zend_tmp_string_release(op_str);
+						return 0;
 					}
 				}
 				if (EXPECTED(type == IS_LONG)) {
@@ -426,11 +428,12 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
 					 */
 					lval = zend_dval_to_lval_cap(dval);
 					if (!zend_is_long_compatible(dval, lval)) {
-						zend_incompatible_string_to_long_error(Z_STR_P(op));
+						zend_incompatible_string_to_long_error(op_str ? op_str : Z_STR_P(op));
 						if (UNEXPECTED(EG(exception))) {
-							*failed = 1;
+							*failed = true;
 						}
 					}
+					zend_tmp_string_release(op_str);
 					return lval;
 				}
 			}
@@ -439,15 +442,16 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
 				zval dst;
 				if (Z_OBJ_HT_P(op)->cast_object(Z_OBJ_P(op), &dst, IS_LONG) == FAILURE
 						|| EG(exception)) {
-					*failed = 1;
+					*failed = true;
 					return 0;
 				}
 				ZEND_ASSERT(Z_TYPE(dst) == IS_LONG);
 				return Z_LVAL(dst);
 			}
+		case IS_UNDEF:
 		case IS_RESOURCE:
 		case IS_ARRAY:
-			*failed = 1;
+			*failed = true;
 			return 0;
 		case IS_REFERENCE:
 			op = Z_REFVAL_P(op);
@@ -457,7 +461,7 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
 				goto try_again;
 			}
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -566,9 +570,13 @@ ZEND_API void ZEND_FASTCALL convert_to_long(zval *op) /* {{{ */
 			break;
 		case IS_LONG:
 			break;
-		case IS_DOUBLE:
-			ZVAL_LONG(op, zend_dval_to_lval(Z_DVAL_P(op)));
+		case IS_DOUBLE: {
+			/* NAN might emit a warning */
+			zend_long new_value = zend_dval_to_lval(Z_DVAL_P(op));
+			zval_ptr_dtor(op);
+			ZVAL_LONG(op, new_value);
 			break;
+		}
 		case IS_STRING:
 			{
 				zend_string *str = Z_STR_P(op);
@@ -598,7 +606,7 @@ ZEND_API void ZEND_FASTCALL convert_to_long(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -657,13 +665,16 @@ ZEND_API void ZEND_FASTCALL convert_to_double(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
 
 ZEND_API void ZEND_FASTCALL convert_to_null(zval *op) /* {{{ */
 {
+	if (UNEXPECTED(Z_TYPE_P(op) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op)))) {
+		zend_nan_coerced_to_type_warning(IS_NULL);
+	}
 	zval_ptr_dtor(op);
 	ZVAL_NULL(op);
 }
@@ -691,9 +702,16 @@ ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */
 		case IS_LONG:
 			ZVAL_BOOL(op, Z_LVAL_P(op) ? 1 : 0);
 			break;
-		case IS_DOUBLE:
-			ZVAL_BOOL(op, Z_DVAL_P(op) ? 1 : 0);
+		case IS_DOUBLE: {
+			/* We compute the new value before emitting the warning as the zval may change */
+			bool new_value = Z_DVAL_P(op) ? true : false;
+			if (UNEXPECTED(zend_isnan(Z_DVAL_P(op)))) {
+				zend_nan_coerced_to_type_warning(_IS_BOOL);
+				zval_ptr_dtor(op);
+			}
+			ZVAL_BOOL(op, new_value);
 			break;
+		}
 		case IS_STRING:
 			{
 				zend_string *str = Z_STR_P(op);
@@ -729,7 +747,7 @@ ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -758,9 +776,13 @@ ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op) /* {{{ */
 		case IS_LONG:
 			ZVAL_STR(op, zend_long_to_str(Z_LVAL_P(op)));
 			break;
-		case IS_DOUBLE:
-			ZVAL_NEW_STR(op, zend_double_to_str(Z_DVAL_P(op)));
+		case IS_DOUBLE: {
+			/* Casting NAN will cause a warning */
+			zend_string *new_value = zend_double_to_str(Z_DVAL_P(op));
+			zval_ptr_dtor(op);
+			ZVAL_NEW_STR(op, new_value);
 			break;
+		}
 		case IS_ARRAY:
 			zend_error(E_WARNING, "Array to string conversion");
 			zval_ptr_dtor(op);
@@ -783,7 +805,7 @@ ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 }
 /* }}} */
@@ -805,6 +827,9 @@ ZEND_API bool ZEND_FASTCALL _try_convert_to_string(zval *op) /* {{{ */
 
 static void convert_scalar_to_array(zval *op) /* {{{ */
 {
+	if (UNEXPECTED(Z_TYPE_P(op) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op)))) {
+		zend_nan_coerced_to_type_warning(IS_ARRAY);
+	}
 	HashTable *ht = zend_new_array(1);
 	zend_hash_index_add_new(ht, 0, op);
 	ZVAL_ARR(op, ht);
@@ -887,6 +912,11 @@ ZEND_API void ZEND_FASTCALL convert_to_object(zval *op) /* {{{ */
 		case IS_REFERENCE:
 			zend_unwrap_reference(op);
 			goto try_again;
+		case IS_DOUBLE:
+			if (UNEXPECTED(zend_isnan(Z_DVAL_P(op)))) {
+				zend_nan_coerced_to_type_warning(IS_OBJECT);
+			}
+			ZEND_FALLTHROUGH;
 		default: {
 			zval tmp;
 			ZVAL_COPY_VALUE(&tmp, op);
@@ -906,6 +936,19 @@ ZEND_API void ZEND_COLD zend_incompatible_string_to_long_error(const zend_string
 {
 	zend_error(E_DEPRECATED, "Implicit conversion from float-string \"%s\" to int loses precision", ZSTR_VAL(s));
 }
+ZEND_API void ZEND_COLD zend_oob_double_to_long_error(double d)
+{
+	zend_error_unchecked(E_WARNING, "The float %.*H is not representable as an int, cast occurred", -1, d);
+}
+ZEND_API void ZEND_COLD zend_oob_string_to_long_error(const zend_string *s)
+{
+	zend_error_unchecked(E_WARNING, "The float-string \"%s\" is not representable as an int, cast occurred", ZSTR_VAL(s));
+}
+
+ZEND_API void ZEND_COLD zend_nan_coerced_to_type_warning(uint8_t type)
+{
+	zend_error(E_WARNING, "unexpected NAN value was coerced to %s", zend_get_type_by_const(type));
+}
 
 ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(const zval *op, bool is_strict) /* {{{ */
 {
@@ -971,7 +1014,7 @@ ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(const zval *op, bool is_stri
 		case IS_REFERENCE:
 			op = Z_REFVAL_P(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return 0;
 }
@@ -1010,13 +1053,13 @@ ZEND_API double ZEND_FASTCALL zval_get_double_func(const zval *op) /* {{{ */
 		case IS_REFERENCE:
 			op = Z_REFVAL_P(op);
 			goto try_again;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return 0.0;
 }
 /* }}} */
 
-static zend_always_inline zend_string* __zval_get_string_func(zval *op, bool try) /* {{{ */
+static zend_always_inline zend_string* __zval_get_string_func(const zval *op, bool try) /* {{{ */
 {
 try_again:
 	switch (Z_TYPE_P(op)) {
@@ -1051,25 +1094,25 @@ static zend_always_inline zend_string* __zval_get_string_func(zval *op, bool try
 			goto try_again;
 		case IS_STRING:
 			return zend_string_copy(Z_STR_P(op));
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return NULL;
 }
 /* }}} */
 
-ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(zval *op) /* {{{ */
+ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(const zval *op) /* {{{ */
 {
-	return __zval_get_string_func(op, 0);
+	return __zval_get_string_func(op, false);
 }
 /* }}} */
 
-ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(zval *op) /* {{{ */
+ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(const zval *op) /* {{{ */
 {
-	return __zval_get_string_func(op, 1);
+	return __zval_get_string_func(op, true);
 }
 /* }}} */
 
-static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const char *operator, zval *op1, zval *op2) /* {{{ */ {
+static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const char *operator, const zval *op1, const zval *op2) /* {{{ */ {
 	if (EG(exception)) {
 		return;
 	}
@@ -1079,7 +1122,7 @@ static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const cha
 }
 /* }}} */
 
-static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, zval *op1, zval *op2) /* {{{ */
+static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, const zval *op1, const zval *op2) /* {{{ */
 {
 	if (result == op1 && Z_ARR_P(op1) == Z_ARR_P(op2)) {
 		/* $a += $a */
@@ -1546,7 +1589,7 @@ ZEND_API zend_result ZEND_FASTCALL boolean_xor_function(zval *result, zval *op1,
 				}
 			}
 			ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BOOL_XOR);
-			op1_val = zval_is_true(op1);
+			op1_val = zend_is_true(op1);
 		}
 	} while (0);
 	do {
@@ -1566,7 +1609,7 @@ ZEND_API zend_result ZEND_FASTCALL boolean_xor_function(zval *result, zval *op1,
 				}
 			}
 			ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BOOL_XOR);
-			op2_val = zval_is_true(op2);
+			op2_val = zend_is_true(op2);
 		}
 	} while (0);
 
@@ -1594,7 +1637,7 @@ ZEND_API zend_result ZEND_FASTCALL boolean_not_function(zval *result, zval *op1)
 		}
 		ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
 
-		ZVAL_BOOL(result, !zval_is_true(op1));
+		ZVAL_BOOL(result, !zend_is_true(op1));
 	}
 	return SUCCESS;
 }
@@ -1608,15 +1651,12 @@ ZEND_API zend_result ZEND_FASTCALL bitwise_not_function(zval *result, zval *op1)
 			ZVAL_LONG(result, ~Z_LVAL_P(op1));
 			return SUCCESS;
 		case IS_DOUBLE: {
-			zend_long lval = zend_dval_to_lval(Z_DVAL_P(op1));
-			if (!zend_is_long_compatible(Z_DVAL_P(op1), lval)) {
-				zend_incompatible_double_to_long_error(Z_DVAL_P(op1));
-				if (EG(exception)) {
-					if (result != op1) {
-						ZVAL_UNDEF(result);
-					}
-					return FAILURE;
+			zend_long lval = zend_dval_to_lval_safe(Z_DVAL_P(op1));
+			if (EG(exception)) {
+				if (result != op1) {
+					ZVAL_UNDEF(result);
 				}
+				return FAILURE;
 			}
 			ZVAL_LONG(result, ~lval);
 			return SUCCESS;
@@ -2119,7 +2159,7 @@ has_op2_string:;
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, bool case_insensitive) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_compare_function_ex(const zval *op1, const zval *op2, bool case_insensitive) /* {{{ */
 {
 	zend_string *tmp_str1, *tmp_str2;
 	zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1);
@@ -2138,7 +2178,7 @@ ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, bool
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
 	    EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
@@ -2160,7 +2200,7 @@ ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_case_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
 	    EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
@@ -2182,7 +2222,7 @@ ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /*
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_locale_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	zend_string *tmp_str1, *tmp_str2;
 	zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1);
@@ -2195,7 +2235,7 @@ ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2)
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL numeric_compare_function(const zval *op1, const zval *op2) /* {{{ */
 {
 	double d1, d2;
 
@@ -2213,7 +2253,7 @@ ZEND_API zend_result ZEND_FASTCALL compare_function(zval *result, zval *op1, zva
 }
 /* }}} */
 
-static int compare_long_to_string(zend_long lval, zend_string *str) /* {{{ */
+static int compare_long_to_string(zend_long lval, const zend_string *str) /* {{{ */
 {
 	zend_long str_lval;
 	double str_dval;
@@ -2235,12 +2275,14 @@ static int compare_long_to_string(zend_long lval, zend_string *str) /* {{{ */
 }
 /* }}} */
 
-static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
+static int compare_double_to_string(double dval, const zend_string *str) /* {{{ */
 {
 	zend_long str_lval;
 	double str_dval;
 	uint8_t type = is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &str_lval, &str_dval, 0);
 
+	ZEND_ASSERT(!zend_isnan(dval));
+
 	if (type == IS_LONG) {
 		return ZEND_THREEWAY_COMPARE(dval, (double) str_lval);
 	}
@@ -2259,7 +2301,7 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
 
 ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
 {
-	int converted = 0;
+	bool converted = false;
 	zval op1_copy, op2_copy;
 
 	while (1) {
@@ -2366,21 +2408,41 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
 				}
 
 				if (!converted) {
-					if (Z_TYPE_P(op1) < IS_TRUE) {
-						return zval_is_true(op2) ? -1 : 0;
+					/* Handle NAN */
+					if (UNEXPECTED(
+						(Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1)))
+						|| (Z_TYPE_P(op2) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op2)))
+					)) {
+						// TODO: NAN should always be uncomparable
+						/* NAN used be cast to TRUE so handle this manually for the time being */
+						if (Z_TYPE_P(op1) < IS_TRUE) {
+							return -1;
+						} else if (Z_TYPE_P(op1) == IS_TRUE || Z_TYPE_P(op2) == IS_TRUE) {
+							return 0;
+						} else if (Z_TYPE_P(op2) < IS_TRUE) {
+							return 1;
+						} else if (Z_TYPE_P(op1) != IS_DOUBLE) {
+							op1 = _zendi_convert_scalar_to_number_silent(op1, &op1_copy);
+							converted = true;
+						} else if (Z_TYPE_P(op2) != IS_DOUBLE) {
+							op2 = _zendi_convert_scalar_to_number_silent(op2, &op2_copy);
+							converted = true;
+						}
+					} else if (Z_TYPE_P(op1) < IS_TRUE) {
+						return zend_is_true(op2) ? -1 : 0;
 					} else if (Z_TYPE_P(op1) == IS_TRUE) {
-						return zval_is_true(op2) ? 0 : 1;
+						return zend_is_true(op2) ? 0 : 1;
 					} else if (Z_TYPE_P(op2) < IS_TRUE) {
-						return zval_is_true(op1) ? 1 : 0;
+						return zend_is_true(op1) ? 1 : 0;
 					} else if (Z_TYPE_P(op2) == IS_TRUE) {
-						return zval_is_true(op1) ? 0 : -1;
+						return zend_is_true(op1) ? 0 : -1;
 					} else {
 						op1 = _zendi_convert_scalar_to_number_silent(op1, &op1_copy);
 						op2 = _zendi_convert_scalar_to_number_silent(op2, &op2_copy);
 						if (EG(exception)) {
 							return 1; /* to stop comparison of arrays */
 						}
-						converted = 1;
+						converted = true;
 					}
 				} else if (Z_TYPE_P(op1)==IS_ARRAY) {
 					return 1;
@@ -2397,7 +2459,7 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
 /* }}} */
 
 /* return int to be compatible with compare_func_t */
-static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */
+static int hash_zval_identical_function(const zval *z1, const zval *z2) /* {{{ */
 {
 	/* is_identical_function() returns 1 in case of identity and 0 in case
 	 * of a difference;
@@ -2439,14 +2501,14 @@ ZEND_API bool ZEND_FASTCALL zend_is_identical(const zval *op1, const zval *op2)
 }
 /* }}} */
 
-ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, const zval *op1, const zval *op2) /* {{{ */
 {
 	ZVAL_BOOL(result, zend_is_identical(op1, op2));
 	return SUCCESS;
 }
 /* }}} */
 
-ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, const zval *op1, const zval *op2) /* {{{ */
 {
 	ZVAL_BOOL(result, !zend_is_identical(op1, op2));
 	return SUCCESS;
@@ -2498,6 +2560,56 @@ ZEND_API bool ZEND_FASTCALL zend_class_implements_interface(const zend_class_ent
 }
 /* }}} */
 
+/* Variance-aware comparison of two siblings monos `a` and `b` of the same
+ * generic base. Returns true if `a` is a subtype of `b` under the base's
+ * declared variance markers. Both monos must have generic_type_args populated
+ * with the same arity as base->generic_parameters. */
+static bool zend_mono_subtype_under_variance(const zend_class_entry *base,
+		const zend_class_entry *a, const zend_class_entry *b)
+{
+	if (!base->generic_parameters
+			|| !a->generic_type_args
+			|| !b->generic_type_args) {
+		return false;
+	}
+	uint32_t count = base->generic_parameters->count;
+	if (a->generic_type_args->count != count
+			|| b->generic_type_args->count != count) {
+		return false;
+	}
+	for (uint32_t i = 0; i < count; i++) {
+		zend_string *a_name = a->generic_type_args->entries[i].name;
+		zend_string *b_name = b->generic_type_args->entries[i].name;
+		if (!a_name || !b_name) {
+			return false;
+		}
+		if (zend_string_equals(a_name, b_name)) {
+			continue;
+		}
+		zend_generic_variance variance = base->generic_parameters->parameters[i].variance;
+		if (variance == ZEND_GENERIC_VARIANCE_INVARIANT) {
+			return false;
+		}
+		zend_class_entry *a_ce = zend_lookup_class_ex(a_name, NULL,
+			ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+		zend_class_entry *b_ce = zend_lookup_class_ex(b_name, NULL,
+			ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+		if (!a_ce || !b_ce) {
+			return false;
+		}
+		bool ok;
+		if (variance == ZEND_GENERIC_VARIANCE_COVARIANT) {
+			ok = instanceof_function(a_ce, b_ce);
+		} else { /* CONTRAVARIANT */
+			ok = instanceof_function(b_ce, a_ce);
+		}
+		if (!ok) {
+			return false;
+		}
+	}
+	return true;
+}
+
 ZEND_API bool ZEND_FASTCALL instanceof_function_slow(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
 {
 	ZEND_ASSERT(instance_ce != ce && "Should have been checked already");
@@ -2514,12 +2626,24 @@ ZEND_API bool ZEND_FASTCALL instanceof_function_slow(const zend_class_entry *ins
 		}
 		return 0;
 	} else {
+		/* When the target is a monomorph (e.g. Box), the instance may
+		 * be a sibling monomorph of the same base (Box) — siblings via
+		 * the parent chain are not subtypes via `==`, so check the variance
+		 * markers on the shared base. */
+		const zend_class_entry *target_base = ce->generic_type_args ? ce->parent : NULL;
+		const zend_class_entry *walker = instance_ce;
 		while (1) {
-			instance_ce = instance_ce->parent;
-			if (instance_ce == ce) {
+			if (target_base
+					&& walker->parent == target_base
+					&& walker->generic_type_args
+					&& zend_mono_subtype_under_variance(target_base, walker, ce)) {
+				return 1;
+			}
+			walker = walker->parent;
+			if (walker == ce) {
 				return 1;
 			}
-			if (instance_ce == NULL) {
+			if (walker == NULL) {
 				return 0;
 			}
 		}
@@ -2553,29 +2677,23 @@ static bool ZEND_FASTCALL increment_string(zval *str) /* {{{ */
 	int last=0; /* Shut up the compiler warning */
 	int ch;
 
+	zend_string *zstr = Z_STR_P(str);
+	zend_string_addref(zstr);
+	zend_error(E_DEPRECATED, "Increment on non-numeric string is deprecated, use str_increment() instead");
+	if (EG(exception)) {
+		zend_string_release(zstr);
+		return false;
+	}
+	/* A userland error handler can change the type from string to something else */
+	zval_ptr_dtor(str);
+	ZVAL_STR(str, zstr);
+
 	if (UNEXPECTED(Z_STRLEN_P(str) == 0)) {
-		zend_error(E_DEPRECATED, "Increment on non-alphanumeric string is deprecated");
-		if (EG(exception)) {
-			return false;
-		}
-		/* A userland error handler can change the type from string to something else */
 		zval_ptr_dtor(str);
 		ZVAL_CHAR(str, '1');
 		return true;
 	}
 
-	if (UNEXPECTED(!zend_string_only_has_ascii_alphanumeric(Z_STR_P(str)))) {
-		zend_string *zstr = Z_STR_P(str);
-		zend_string_addref(zstr);
-		zend_error(E_DEPRECATED, "Increment on non-alphanumeric string is deprecated");
-		if (EG(exception)) {
-			zend_string_release(zstr);
-			return false;
-		}
-		zval_ptr_dtor(str);
-		ZVAL_STR(str, zstr);
-	}
-
 	if (!Z_REFCOUNTED_P(str)) {
 		Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
 		Z_TYPE_INFO_P(str) = IS_STRING_EX;
@@ -2728,7 +2846,7 @@ ZEND_API zend_result ZEND_FASTCALL increment_function(zval *op1) /* {{{ */
 		case IS_ARRAY:
 			zend_type_error("Cannot increment %s", zend_zval_value_name(op1));
 			return FAILURE;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	return SUCCESS;
 }
@@ -2835,7 +2953,7 @@ ZEND_API zend_result ZEND_FASTCALL decrement_function(zval *op1) /* {{{ */
 		case IS_ARRAY:
 			zend_type_error("Cannot decrement %s", zend_zval_value_name(op1));
 			return FAILURE;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 
 	return SUCCESS;
@@ -3266,8 +3384,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1,
 
 	len = MIN(len1, len2);
 	while (len--) {
-		c1 = zend_tolower((int)*(unsigned char *)s1++);
-		c2 = zend_tolower((int)*(unsigned char *)s2++);
+		c1 = zend_tolower((unsigned char)*(s1++));
+		c2 = zend_tolower((unsigned char)*(s2++));
 		if (c1 != c2) {
 			return c1 - c2;
 		}
@@ -3287,8 +3405,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1
 	}
 	len = MIN(length, MIN(len1, len2));
 	while (len--) {
-		c1 = zend_tolower((int)*(unsigned char *)s1++);
-		c2 = zend_tolower((int)*(unsigned char *)s2++);
+		c1 = zend_tolower((unsigned char)*(s1++));
+		c2 = zend_tolower((unsigned char)*(s2++));
 		if (c1 != c2) {
 			return c1 - c2;
 		}
@@ -3298,19 +3416,19 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
+ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(const zval *s1, const zval *s2) /* {{{ */
 {
 	return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
+ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(const zval *s1, const zval *s2, const zval *s3) /* {{{ */
 {
 	return zend_binary_strncmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
 }
 /* }}} */
 
-ZEND_API bool ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2) /* {{{ */
+ZEND_API bool ZEND_FASTCALL zendi_smart_streq(const zend_string *s1, const zend_string *s2) /* {{{ */
 {
 	uint8_t ret1, ret2;
 	int oflow1, oflow2;
@@ -3358,7 +3476,7 @@ ZEND_API bool ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2)
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */
+ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(const zend_string *s1, const zend_string *s2) /* {{{ */
 {
 	uint8_t ret1, ret2;
 	int oflow1, oflow2;
@@ -3417,11 +3535,23 @@ static int hash_zval_compare_function(zval *z1, zval *z2) /* {{{ */
 
 ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2) /* {{{ */
 {
-	return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0);
+	if (ht1 == ht2) {
+		return 0;
+	}
+
+	GC_TRY_ADDREF(ht1);
+	GC_TRY_ADDREF(ht2);
+
+	int ret = zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0);
+
+	GC_TRY_DTOR_NO_REF(ht1);
+	GC_TRY_DTOR_NO_REF(ht2);
+
+	return ret;
 }
 /* }}} */
 
-ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2) /* {{{ */
+ZEND_API int ZEND_FASTCALL zend_compare_arrays(const zval *a1, const zval *a2) /* {{{ */
 {
 	return zend_compare_symbol_tables(Z_ARRVAL_P(a1), Z_ARRVAL_P(a2));
 }
@@ -3532,6 +3662,9 @@ ZEND_API zend_string* ZEND_FASTCALL zend_double_to_str(double num)
 	int precision = (int) EG(precision);
 	zend_gcvt(num, precision ? precision : 1, '.', 'E', buf);
 	zend_string *str =  zend_string_init(buf, strlen(buf), 0);
+	if (UNEXPECTED(zend_isnan(num))) {
+		zend_nan_coerced_to_type_warning(IS_STRING);
+	}
 	GC_ADD_FLAGS(str, IS_STR_VALID_UTF8);
 	return str;
 }
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index db86345b6996..83cfe447dcea 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -71,8 +70,8 @@ ZEND_API zend_result ZEND_FASTCALL concat_function(zval *result, zval *op1, zval
 ZEND_API bool ZEND_FASTCALL zend_is_identical(const zval *op1, const zval *op2);
 
 ZEND_API zend_result ZEND_FASTCALL is_equal_function(zval *result, zval *op1, zval *op2);
-ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, zval *op1, zval *op2);
-ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zval *op2);
+ZEND_API zend_result ZEND_FASTCALL is_identical_function(zval *result, const zval *op1, const zval *op2);
+ZEND_API zend_result ZEND_FASTCALL is_not_identical_function(zval *result, const zval *op1, const zval *op2);
 ZEND_API zend_result ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1, zval *op2);
 ZEND_API zend_result ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2);
 ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2);
@@ -82,7 +81,16 @@ ZEND_API bool ZEND_FASTCALL instanceof_function_slow(const zend_class_entry *ins
 
 static zend_always_inline bool instanceof_function(
 		const zend_class_entry *instance_ce, const zend_class_entry *ce) {
-	return instance_ce == ce || instanceof_function_slow(instance_ce, ce);
+	/* `instance_ce->parent == ce` is a cheap second-level fast path for the
+	 * direct-subclass case: it always implies `instance_ce instanceof ce`
+	 * (parent is a class, never an interface). It is the common shape for a
+	 * generic monomorph checked against its erased base (e.g. a
+	 * `DirectedGraph` value flowing into a `DirectedGraph`-typed
+	 * parameter), which would otherwise pay a full slow-path call on every
+	 * boundary check. */
+	return instance_ce == ce
+		|| instance_ce->parent == ce
+		|| instanceof_function_slow(instance_ce, ce);
 }
 
 ZEND_API bool zend_string_only_has_ascii_alphanumeric(const zend_string *str);
@@ -115,11 +123,29 @@ ZEND_API const char* ZEND_FASTCALL zend_memnrstr_ex(const char *haystack, const
 #	define ZEND_DOUBLE_FITS_LONG(d) (!((d) >= (double)ZEND_LONG_MAX || (d) < (double)ZEND_LONG_MIN))
 #endif
 
+ZEND_API void zend_incompatible_double_to_long_error(double d);
+ZEND_API void zend_incompatible_string_to_long_error(const zend_string *s);
+ZEND_API void ZEND_COLD zend_oob_double_to_long_error(double d);
+ZEND_API void ZEND_COLD zend_oob_string_to_long_error(const zend_string *s);
+ZEND_API void ZEND_COLD zend_nan_coerced_to_type_warning(uint8_t type);
+
 ZEND_API zend_long ZEND_FASTCALL zend_dval_to_lval_slow(double d);
 
 static zend_always_inline zend_long zend_dval_to_lval(double d)
 {
-	if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
+	if (UNEXPECTED(!zend_finite(d))) {
+		zend_oob_double_to_long_error(d);
+		return 0;
+	} else if (!ZEND_DOUBLE_FITS_LONG(d)) {
+		zend_oob_double_to_long_error(d);
+		return zend_dval_to_lval_slow(d);
+	}
+	return (zend_long)d;
+}
+
+static zend_always_inline zend_long zend_dval_to_lval_silent(double d)
+{
+	if (UNEXPECTED(!zend_finite(d))) {
 		return 0;
 	} else if (!ZEND_DOUBLE_FITS_LONG(d)) {
 		return zend_dval_to_lval_slow(d);
@@ -130,7 +156,7 @@ static zend_always_inline zend_long zend_dval_to_lval(double d)
 /* Used to convert a string float to integer during an (int) cast */
 static zend_always_inline zend_long zend_dval_to_lval_cap(double d)
 {
-	if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
+	if (UNEXPECTED(!zend_finite(d))) {
 		return 0;
 	} else if (!ZEND_DOUBLE_FITS_LONG(d)) {
 		return (d > 0 ? ZEND_LONG_MAX : ZEND_LONG_MIN);
@@ -143,20 +169,16 @@ static zend_always_inline bool zend_is_long_compatible(double d, zend_long l) {
 	return (double)l == d;
 }
 
-ZEND_API void zend_incompatible_double_to_long_error(double d);
-ZEND_API void zend_incompatible_string_to_long_error(const zend_string *s);
-
 static zend_always_inline zend_long zend_dval_to_lval_safe(double d)
 {
 	zend_long l = zend_dval_to_lval(d);
-	if (!zend_is_long_compatible(d, l)) {
+	if (!zend_is_long_compatible(d, l) && ZEND_DOUBLE_FITS_LONG(d)) {
 		zend_incompatible_double_to_long_error(d);
 	}
 	return l;
 }
 
 #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
-#define ZEND_IS_XDIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
 
 static zend_always_inline uint8_t is_numeric_string_ex(const char *str, size_t length, zend_long *lval,
 	double *dval, bool allow_errors, int *oflow_info, bool *trailing_data)
@@ -216,7 +238,7 @@ zend_memnstr(const char *haystack, const char *needle, size_t needle_len, const
 
 static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t n)
 {
-#if defined(HAVE_MEMRCHR) && !defined(i386)
+#if defined(HAVE_MEMRCHR) && !defined(__i386__)
 	/* On x86 memrchr() doesn't use SSE/AVX, so inlined version is faster */
 	return (const void*)memrchr(s, c, n);
 #else
@@ -311,8 +333,8 @@ ZEND_API void ZEND_FASTCALL convert_to_object(zval *op);
 ZEND_API zend_long    ZEND_FASTCALL zval_get_long_func(const zval *op, bool is_strict);
 ZEND_API zend_long    ZEND_FASTCALL zval_try_get_long(const zval *op, bool *failed);
 ZEND_API double       ZEND_FASTCALL zval_get_double_func(const zval *op);
-ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(zval *op);
-ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(zval *op);
+ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(const zval *op);
+ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(const zval *op);
 
 static zend_always_inline zend_long zval_get_long(const zval *op) {
 	return EXPECTED(Z_TYPE_P(op) == IS_LONG) ? Z_LVAL_P(op) : zval_get_long_func(op, false);
@@ -323,11 +345,11 @@ static zend_always_inline zend_long zval_get_long_ex(const zval *op, bool is_str
 static zend_always_inline double zval_get_double(const zval *op) {
 	return EXPECTED(Z_TYPE_P(op) == IS_DOUBLE) ? Z_DVAL_P(op) : zval_get_double_func(op);
 }
-static zend_always_inline zend_string *zval_get_string(zval *op) {
+static zend_always_inline zend_string *zval_get_string(const zval *op) {
 	return EXPECTED(Z_TYPE_P(op) == IS_STRING) ? zend_string_copy(Z_STR_P(op)) : zval_get_string_func(op);
 }
 
-static zend_always_inline zend_string *zval_get_tmp_string(zval *op, zend_string **tmp) {
+static zend_always_inline zend_string *zval_get_tmp_string(const zval *op, zend_string **tmp) {
 	if (EXPECTED(Z_TYPE_P(op) == IS_STRING)) {
 		*tmp = NULL;
 		return Z_STR_P(op);
@@ -342,7 +364,7 @@ static zend_always_inline void zend_tmp_string_release(zend_string *tmp) {
 }
 
 /* Like zval_get_string, but returns NULL if the conversion fails with an exception. */
-static zend_always_inline zend_string *zval_try_get_string(zval *op) {
+static zend_always_inline zend_string *zval_try_get_string(const zval *op) {
 	if (EXPECTED(Z_TYPE_P(op) == IS_STRING)) {
 		zend_string *ret = zend_string_copy(Z_STR_P(op));
 		ZEND_ASSUME(ret != NULL);
@@ -353,7 +375,7 @@ static zend_always_inline zend_string *zval_try_get_string(zval *op) {
 }
 
 /* Like zval_get_tmp_string, but returns NULL if the conversion fails with an exception. */
-static zend_always_inline zend_string *zval_try_get_tmp_string(zval *op, zend_string **tmp) {
+static zend_always_inline zend_string *zval_try_get_tmp_string(const zval *op, zend_string **tmp) {
 	if (EXPECTED(Z_TYPE_P(op) == IS_STRING)) {
 		zend_string *ret = Z_STR_P(op);
 		*tmp = NULL;
@@ -374,23 +396,12 @@ static zend_always_inline bool try_convert_to_string(zval *op) {
 	return _try_convert_to_string(op);
 }
 
-/* Compatibility macros for 7.2 and below */
-#define _zval_get_long(op) zval_get_long(op)
-#define _zval_get_double(op) zval_get_double(op)
-#define _zval_get_string(op) zval_get_string(op)
-#define _zval_get_long_func(op) zval_get_long_func(op)
-#define _zval_get_double_func(op) zval_get_double_func(op)
-#define _zval_get_string_func(op) zval_get_string_func(op)
-
 #define convert_to_string(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_string((op)); }
 
 
 ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op);
 ZEND_API bool ZEND_FASTCALL zend_object_is_true(const zval *op);
 
-#define zval_is_true(op) \
-	zend_is_true(op)
-
 static zend_always_inline bool i_zend_is_true(const zval *op)
 {
 	bool result = 0;
@@ -406,6 +417,9 @@ static zend_always_inline bool i_zend_is_true(const zval *op)
 			}
 			break;
 		case IS_DOUBLE:
+			if (UNEXPECTED(zend_isnan(Z_DVAL_P(op)))) {
+				zend_nan_coerced_to_type_warning(_IS_BOOL);
+			}
 			if (Z_DVAL_P(op)) {
 				result = 1;
 			}
@@ -452,11 +466,11 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2);
 
 ZEND_API zend_result ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2);
 
-ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2);
-ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, bool case_insensitive);
-ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2);
-ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2);
-ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2);
+ZEND_API int ZEND_FASTCALL numeric_compare_function(const zval *op1, const zval *op2);
+ZEND_API int ZEND_FASTCALL string_compare_function_ex(const zval *op1, const zval *op2, bool case_insensitive);
+ZEND_API int ZEND_FASTCALL string_compare_function(const zval *op1, const zval *op2);
+ZEND_API int ZEND_FASTCALL string_case_compare_function(const zval *op1, const zval *op2);
+ZEND_API int ZEND_FASTCALL string_locale_compare_function(const zval *op1, const zval *op2);
 
 ZEND_API extern const unsigned char zend_tolower_map[256];
 ZEND_API extern const unsigned char zend_toupper_map[256];
@@ -482,8 +496,8 @@ static zend_always_inline zend_string* zend_string_toupper(zend_string *str) {
 	return zend_string_toupper_ex(str, false);
 }
 
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2);
-ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
+ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(const zval *s1, const zval *s2);
+ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(const zval *s1, const zval *s2, const zval *s3);
 ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2);
 ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
 ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2);
@@ -491,10 +505,10 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1,
 ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2);
 ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
 
-ZEND_API bool ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2);
-ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2);
+ZEND_API bool ZEND_FASTCALL zendi_smart_streq(const zend_string *s1, const zend_string *s2);
+ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(const zend_string *s1, const zend_string *s2);
 ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2);
-ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2);
+ZEND_API int ZEND_FASTCALL zend_compare_arrays(const zval *a1, const zval *a2);
 ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2);
 
 /** Deprecated in favor of ZEND_STRTOL() */
@@ -941,7 +955,7 @@ static zend_always_inline bool fast_equal_check_string(zval *op1, zval *op2)
 	return zend_compare(op1, op2) == 0;
 }
 
-static zend_always_inline bool fast_is_identical_function(zval *op1, zval *op2)
+static zend_always_inline bool fast_is_identical_function(const zval *op1, const zval *op2)
 {
 	if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
 		return 0;
@@ -951,7 +965,7 @@ static zend_always_inline bool fast_is_identical_function(zval *op1, zval *op2)
 	return zend_is_identical(op1, op2);
 }
 
-static zend_always_inline bool fast_is_not_identical_function(zval *op1, zval *op2)
+static zend_always_inline bool fast_is_not_identical_function(const zval *op1, const zval *op2)
 {
 	if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
 		return 1;
diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h
index 65ce533c753b..ccad24682fdb 100644
--- a/Zend/zend_portability.h
+++ b/Zend/zend_portability.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -89,6 +88,9 @@
 #ifndef __has_feature
 # define __has_feature(x) 0
 #endif
+#ifndef __has_include
+# define __has_include(x) 0
+#endif
 
 #if defined(ZEND_WIN32) && !defined(__clang__)
 # define ZEND_ASSUME(c)	__assume(c)
@@ -103,13 +105,19 @@
 # define ZEND_ASSUME(c)
 #endif
 
-#if ZEND_DEBUG
+#ifdef HAVE_GCOV
+/* Disable assert() when compiling with gcov to avoid untested branch warning. */
+# define ZEND_ASSERT(c) ((void)sizeof(c))
+#elif ZEND_DEBUG
 # define ZEND_ASSERT(c)	assert(c)
 #else
 # define ZEND_ASSERT(c) ZEND_ASSUME(c)
 #endif
 
-#ifdef PHP_HAVE_BUILTIN_UNREACHABLE
+/* use C23 unreachable() from  if possible */
+#ifdef unreachable
+# define _ZEND_UNREACHABLE() unreachable()
+#elif defined(PHP_HAVE_BUILTIN_UNREACHABLE)
 # define _ZEND_UNREACHABLE() __builtin_unreachable()
 #else
 # define _ZEND_UNREACHABLE() ZEND_ASSUME(0)
@@ -122,16 +130,14 @@
 #endif
 
 /* pseudo fallthrough keyword; */
-#if defined(__GNUC__) && __GNUC__ >= 7
+#if __STDC_VERSION__ >= 202311L || defined(__cplusplus)
+# define ZEND_FALLTHROUGH [[fallthrough]]
+#elif defined(__GNUC__) && __GNUC__ >= 7
 # define ZEND_FALLTHROUGH __attribute__((__fallthrough__))
 #else
 # define ZEND_FALLTHROUGH ((void)0)
 #endif
 
-/* Only use this macro if you know for sure that all of the switches values
-   are covered by its case statements */
-#define EMPTY_SWITCH_DEFAULT_CASE() default: ZEND_UNREACHABLE(); break;
-
 #if defined(__GNUC__) && __GNUC__ >= 4
 # define ZEND_IGNORE_VALUE(x) (({ __typeof__ (x) __x = (x); (void) __x; }))
 #else
@@ -140,6 +146,19 @@
 
 #define zend_quiet_write(...) ZEND_IGNORE_VALUE(write(__VA_ARGS__))
 
+/* Define an enum with a fixed underlying type as C23_ENUM(name, underlying_type) { }. */
+#if __STDC_VERSION__ >= 202311L || defined(__cplusplus)
+# define C23_ENUM(name, underlying_type) \
+    enum name: underlying_type; \
+    typedef enum name name; \
+    enum name: underlying_type
+#else
+# define C23_ENUM(name, underlying_type) \
+    enum name; \
+    typedef underlying_type name; \
+    enum name
+#endif
+
 /* all HAVE_XXX test have to be after the include of zend_config above */
 
 #if defined(HAVE_LIBDL) && !defined(ZEND_WIN32)
@@ -165,7 +184,12 @@
 # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
 #  define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
 # elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__) && !__has_feature(memory_sanitizer)
-#  define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_DEEPBIND)
+#  if defined(LM_ID_NEWLM)
+     ZEND_API extern bool zend_dl_use_deepbind;
+#    define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | (zend_dl_use_deepbind ? RTLD_DEEPBIND : 0))
+#  else
+#    define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL | RTLD_DEEPBIND)
+#  endif
 # else
 #  define DL_LOAD(libname)			dlopen(libname, PHP_RTLD_MODE | RTLD_GLOBAL)
 # endif
@@ -240,7 +264,15 @@ char *alloca();
 # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y)
 #endif
 
-#if ZEND_GCC_VERSION >= 3000
+#if __STDC_VERSION__ >= 202311L || (defined(__cplusplus) && __cplusplus >= 201703L)
+# define ZEND_ATTRIBUTE_NODISCARD [[nodiscard]]
+#elif __has_attribute(__warn_unused_result__)
+# define ZEND_ATTRIBUTE_NODISCARD __attribute__((__warn_unused_result__))
+#else
+# define ZEND_ATTRIBUTE_NODISCARD
+#endif
+
+#if ZEND_GCC_VERSION >= 3000 || __has_attribute(const)
 # define ZEND_ATTRIBUTE_CONST __attribute__((const))
 #else
 # define ZEND_ATTRIBUTE_CONST
@@ -282,22 +314,21 @@ char *alloca();
 # define ZEND_ATTRIBUTE_NONNULL_ARGS(...)
 #endif
 
-#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003
+#if (defined(__GNUC__) && ZEND_GCC_VERSION >= 4003) || __has_attribute(cold)
 # define ZEND_COLD __attribute__((cold))
-# ifdef __OPTIMIZE__
-#  define ZEND_OPT_SIZE  __attribute__((optimize("Os")))
-#  define ZEND_OPT_SPEED __attribute__((optimize("Ofast")))
-# else
-#  define ZEND_OPT_SIZE
-#  define ZEND_OPT_SPEED
-# endif
 #else
 # define ZEND_COLD
+#endif
+
+#if ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4003) || __has_attribute(optimize)) && defined(__OPTIMIZE__)
+# define ZEND_OPT_SIZE  __attribute__((optimize("Os")))
+# define ZEND_OPT_SPEED __attribute__((optimize("Ofast")))
+#else
 # define ZEND_OPT_SIZE
 # define ZEND_OPT_SPEED
 #endif
 
-#if defined(__GNUC__) && ZEND_GCC_VERSION >= 5000
+#if (defined(__GNUC__) && ZEND_GCC_VERSION >= 5000)
 # define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((unused));
 # define ZEND_ATTRIBUTE_COLD_LABEL __attribute__((cold));
 #else
@@ -313,6 +344,18 @@ char *alloca();
 # define ZEND_FASTCALL
 #endif
 
+#ifdef HAVE_PRESERVE_NONE
+# define ZEND_PRESERVE_NONE __attribute__((preserve_none))
+#endif
+
+
+#if !defined(__apple_build_version__) || (defined(__apple_build_version__) && __apple_build_version__ >= 17000404)
+# if __has_attribute(musttail)
+#  define HAVE_MUSTTAIL
+#  define ZEND_MUSTTAIL __attribute__((musttail))
+# endif
+#endif
+
 #if (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(__APPLE__) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)) || __has_attribute(noreturn)
 # define HAVE_NORETURN
 # define ZEND_NORETURN __attribute__((noreturn))
@@ -344,6 +387,34 @@ char *alloca();
 #define ZEND_ELEMENT_COUNT(m)
 #endif
 
+#if __cplusplus
+extern "C++" {
+# include 
+	template
+	const T* zend_container_of(const M *ptr, size_t offset) {
+		return reinterpret_cast(reinterpret_cast(ptr) - offset);
+	}
+	template
+	T* zend_container_of(M *ptr, size_t offset) {
+		return reinterpret_cast(reinterpret_cast(ptr) - offset);
+	}
+
+# define ZEND_CONTAINER_OF(ptr, Type, member) zend_container_of(ptr, offsetof(Type, member))
+}
+#elif __STDC_VERSION__ >= 202311L || ZEND_GCC_VERSION
+/* typeof is C23 or a GCC extension */
+# define ZEND_CONTAINER_OF(ptr, Type, member) \
+	_Generic( \
+		(ptr), \
+		const typeof(((Type*)0)->member) *: ((const Type*)((char*)(ptr) - offsetof(Type, member))), \
+		typeof(((Type*)0)->member) *: ((Type*)((char*)(ptr) - offsetof(Type, member))) \
+	)
+#else
+/* Define a variant that does not keep const-ness for older compilers. Mismatches
+ * are expected to be caught by CI running modern compilers. */
+# define ZEND_CONTAINER_OF(ptr, Type, member) ((Type*)((char*)(ptr) - offsetof(Type, member)))
+#endif
+
 #ifdef HAVE_BUILTIN_CONSTANT_P
 # define ZEND_CONST_COND(_condition, _default) \
 	(__builtin_constant_p(_condition) ? (_condition) : (_default))
@@ -389,10 +460,6 @@ char *alloca();
 # define UNEXPECTED(condition) (condition)
 #endif
 
-#ifndef XtOffsetOf
-# define XtOffsetOf(s_type, field) offsetof(s_type, field)
-#endif
-
 #ifndef ZEND_WIN32
 # define SETJMP(a) sigsetjmp(a, 0)
 # define LONGJMP(a,b) siglongjmp(a, b)
@@ -491,6 +558,8 @@ extern "C++" {
 
 #ifdef ZEND_WIN32
 #define ZEND_SECURE_ZERO(var, size) RtlSecureZeroMemory((var), (size))
+#elif defined(HAVE_MEMSET_EXPLICIT)
+#define ZEND_SECURE_ZERO(var, size) memset_explicit((var), 0, (size))
 #else
 #define ZEND_SECURE_ZERO(var, size) explicit_bzero((var), (size))
 #endif
@@ -607,8 +676,8 @@ extern "C++" {
 #endif
 
 /* Do not use for conditional declaration of API functions! */
-#if defined(ZEND_INTRIN_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
-/* __builtin_cpu_supports has pclmul from gcc9 */
+#if defined(ZEND_INTRIN_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 19) || (ZEND_GCC_VERSION >= 9000))
+/* __builtin_cpu_supports has pclmul from gcc9 and clang 19 */
 # define ZEND_INTRIN_PCLMUL_FUNC_PROTO 1
 #elif defined(ZEND_INTRIN_PCLMUL_RESOLVER)
 # define ZEND_INTRIN_PCLMUL_FUNC_PTR 1
@@ -633,8 +702,8 @@ extern "C++" {
 #endif
 
 /* Do not use for conditional declaration of API functions! */
-#if defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
-/* __builtin_cpu_supports has pclmul from gcc9 */
+#if defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (defined(__clang__) && __clang_major__ >= 19) || (ZEND_GCC_VERSION >= 9000))
+/* __builtin_cpu_supports has pclmul from gcc9 and clang 19 */
 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PROTO 1
 #elif defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER)
 # define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR 1
@@ -723,6 +792,10 @@ extern "C++" {
 # define ZEND_SET_ALIGNED(alignment, decl) decl
 #endif
 
+#if __has_attribute(section)
+# define HAVE_ATTRIBUTE_SECTION
+#endif
+
 #define ZEND_SLIDE_TO_ALIGNED(alignment, ptr) (((uintptr_t)(ptr) + ((alignment)-1)) & ~((alignment)-1))
 #define ZEND_SLIDE_TO_ALIGNED16(ptr) ZEND_SLIDE_TO_ALIGNED(Z_UL(16), ptr)
 
@@ -759,7 +832,7 @@ extern "C++" {
 # define ZEND_INDIRECT_RETURN
 #endif
 
-#if __has_attribute(nonstring) && defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 15
+#if __has_attribute(nonstring) && defined(__GNUC__) && ((!defined(__clang__) && __GNUC__ >= 15) || (defined(__clang_major__) && __clang_major__ >= 20))
 # define ZEND_NONSTRING __attribute__((nonstring))
 #else
 # define ZEND_NONSTRING
@@ -789,7 +862,9 @@ extern "C++" {
 /** @deprecated */
 #define ZEND_CGG_DIAGNOSTIC_IGNORED_END ZEND_DIAGNOSTIC_IGNORED_END
 
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
+#if defined(__cplusplus)
+# define ZEND_STATIC_ASSERT(c, m) static_assert((c), m)
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
 # define ZEND_STATIC_ASSERT(c, m) _Static_assert((c), m)
 #else
 # define ZEND_STATIC_ASSERT(c, m)
diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c
index 01a8afb16937..dd6fe95ef57a 100644
--- a/Zend/zend_property_hooks.c
+++ b/Zend/zend_property_hooks.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Ilija Tovilo                                |
    +----------------------------------------------------------------------+
@@ -121,7 +120,7 @@ static zend_array *zho_build_properties_ex(zend_object *zobj, bool check_access,
 			if (Z_TYPE_P(prop_value) == IS_INDIRECT) {
 				continue;
 			}
-			zval *tmp = _zend_hash_append(properties, prop_name, prop_value);
+			zval *tmp = zend_hash_add_new(properties, prop_name, prop_value);
 			Z_TRY_ADDREF_P(tmp);
 		} ZEND_HASH_FOREACH_END();
 	}
diff --git a/Zend/zend_property_hooks.h b/Zend/zend_property_hooks.h
index 3793fa1a683c..9c88cccb0c07 100644
--- a/Zend/zend_property_hooks.h
+++ b/Zend/zend_property_hooks.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Ilija Tovilo                                |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c
index 80c77e11d73e..67cc836a240c 100644
--- a/Zend/zend_ptr_stack.c
+++ b/Zend/zend_ptr_stack.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -30,7 +29,7 @@ ZEND_API void zend_ptr_stack_init_ex(zend_ptr_stack *stack, bool persistent)
 
 ZEND_API void zend_ptr_stack_init(zend_ptr_stack *stack)
 {
-	zend_ptr_stack_init_ex(stack, 0);
+	zend_ptr_stack_init_ex(stack, false);
 }
 
 
diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h
index 3ef1478fe4c3..6a6376f79dae 100644
--- a/Zend/zend_ptr_stack.h
+++ b/Zend/zend_ptr_stack.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_range_check.h b/Zend/zend_range_check.h
index 9c822493fa3e..8db867434399 100644
--- a/Zend/zend_range_check.h
+++ b/Zend/zend_range_check.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Anatol Belski                                   |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c
index 83f8aa0852db..2e4b398aa965 100644
--- a/Zend/zend_signal.c
+++ b/Zend/zend_signal.c
@@ -2,15 +2,13 @@
   +----------------------------------------------------------------------+
   | Zend Signal Handling                                                 |
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | This source file is subject to version 3.01 of the PHP license,      |
-  | that is bundled with this package in the file LICENSE, and is        |
-  | available through the world-wide-web at the following url:           |
-  | https://www.php.net/license/3_01.txt                                 |
-  | If you did not receive a copy of the PHP license and are unable to   |
-  | obtain it through the world-wide-web, please send a note to          |
-  | license@php.net so we can mail you a copy immediately.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Authors: Lucas Nealan                                 |
   |          Arnaud Le Blanc                           |
@@ -22,8 +20,9 @@
    Facebook Inc. as the original contributor of this module by leaving
    this note intact in the source code.
 
-   All other licensing and usage conditions are those of the PHP Group.
-*/
+   All other licensing and usage conditions are those of the PHP Group and
+   Contributors.
+ */
 
 #ifndef _GNU_SOURCE
 # define _GNU_SOURCE
diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h
index e88892da35aa..973f0c302b21 100644
--- a/Zend/zend_signal.h
+++ b/Zend/zend_signal.h
@@ -2,20 +2,17 @@
   +----------------------------------------------------------------------+
   | Zend Signal Handling                                                 |
   +----------------------------------------------------------------------+
-  | Copyright (c) The PHP Group                                          |
+  | Copyright © The PHP Group and Contributors.                          |
   +----------------------------------------------------------------------+
-  | This source file is subject to version 3.01 of the PHP license,      |
-  | that is bundled with this package in the file LICENSE, and is        |
-  | available through the world-wide-web at the following url:           |
-  | https://www.php.net/license/3_01.txt                                 |
-  | If you did not receive a copy of the PHP license and are unable to   |
-  | obtain it through the world-wide-web, please send a note to          |
-  | license@php.net so we can mail you a copy immediately.               |
+  | This source file is subject to the Modified BSD License that is      |
+  | bundled with this package in the file LICENSE, and is available      |
+  | through the World Wide Web at .        |
+  |                                                                      |
+  | SPDX-License-Identifier: BSD-3-Clause                                |
   +----------------------------------------------------------------------+
   | Authors: Lucas Nealan                                 |
   |          Arnaud Le Blanc                           |
   +----------------------------------------------------------------------+
-
  */
 
 #ifndef ZEND_SIGNAL_H
diff --git a/Zend/zend_simd.h b/Zend/zend_simd.h
index 9bd16ce9e9af..2f0df203733c 100644
--- a/Zend/zend_simd.h
+++ b/Zend/zend_simd.h
@@ -1,17 +1,17 @@
 /********************************************************************************
  * MIT License
  * Copyright (c) 2025 Saki Takamachi 
- *
+ * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
- *
+ * 
  * The above copyright notice and this permission notice shall be included in all
  * copies or substantial portions of the Software.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -22,389 +22,389 @@
  *********************************************************************************/
 
 
- #ifndef XSSE_H
- #define XSSE_H
-
- #define XSSE_VERSION 10000
-
- #ifdef _MSC_VER
- #  define XSSE_FORCE_INLINE __forceinline
- #elif defined(__GNUC__) || defined(__clang__)
- #  define XSSE_FORCE_INLINE inline __attribute__((always_inline))
- #  define XSSE_HAS_MACRO_EXTENSION
- #else
- #  define XSSE_FORCE_INLINE inline
- #endif
-
-
- #if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64)
- #include 
- #define XSSE2
-
-
- #elif defined(__aarch64__) || defined(_M_ARM64)
- #include 
- #define XSSE2
-
- typedef int8x16_t __m128i;
-
-
- /*****************************************************************************
-  * Load / Store                                                              *
-  *****************************************************************************/
-
- #define _mm_set_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \
-	 ((int8x16_t) { \
-		 (int8_t) (x15), (int8_t) (x14), (int8_t) (x13), (int8_t) (x12), \
-		 (int8_t) (x11), (int8_t) (x10), (int8_t) (x9),  (int8_t) (x8), \
-		 (int8_t) (x7),  (int8_t) (x6),  (int8_t) (x5),  (int8_t) (x4), \
-		 (int8_t) (x3),  (int8_t) (x2),  (int8_t) (x1),  (int8_t) (x0) })
- #define _mm_set_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \
-	 (vreinterpretq_s8_s16((int16x8_t) { \
-		 (int16_t) (x7), (int16_t) (x6), (int16_t) (x5), (int16_t) (x4), \
-		 (int16_t) (x3), (int16_t) (x2), (int16_t) (x1), (int16_t) (x0) }))
- #define _mm_set_epi32(x0, x1, x2, x3) \
-	 (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x3), (int32_t) (x2), (int32_t) (x1), (int32_t) (x0) }))
- #define _mm_set_epi64x(x0, x1) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x1), (int64_t) (x0) }))
- #define _mm_set1_epi8(x) (vdupq_n_s8((int8_t) (x)))
- #define _mm_set1_epi16(x) (vreinterpretq_s8_s16(vdupq_n_s16((int16_t) (x))))
- #define _mm_set1_epi32(x) (vreinterpretq_s8_s32(vdupq_n_s32((int32_t) (x))))
- #define _mm_set1_epi64x(x) (vreinterpretq_s8_s64(vdupq_n_s64((int64_t) (x))))
-
- #define _mm_setr_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \
-	 ((int8x16_t) { \
-		 (int8_t) (x0), (int8_t) (x1), (int8_t) (x2), (int8_t) (x3), \
-		 (int8_t) (x4), (int8_t) (x5), (int8_t) (x6), (int8_t) (x7), \
-		 (int8_t) (x8), (int8_t) (x9), (int8_t) (x10), (int8_t) (x11), \
-		 (int8_t) (x12), (int8_t) (x13), (int8_t) (x14), (int8_t) (x15) })
- #define _mm_setr_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \
-	 (vreinterpretq_s8_s16((int16x8_t) { \
-		 (int16_t) (x0), (int16_t) (x1), (int16_t) (x2), (int16_t) (x3), \
-		 (int16_t) (x4), (int16_t) (x5), (int16_t) (x6), (int16_t) (x7) }))
- #define _mm_setr_epi32(x0, x1, x2, x3) \
-	 (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x0), (int32_t) (x1), (int32_t) (x2), (int32_t) (x3) }))
-
- #define _mm_setzero_si128() (vdupq_n_s8(0))
-
- #define _mm_load_si128(x) (vld1q_s8((const int8_t *) (x)))
- #define _mm_loadu_si128(x) _mm_load_si128(x)
-
- #define _mm_store_si128(to, x) (vst1q_s8((int8_t *) (to), x))
- #define _mm_storeu_si128(to, x) _mm_store_si128(to, x)
- #define _mm_stream_si128(to, x) _mm_store_si128(to, x)
- #define _mm_stream_si32(to, x) (*(volatile int32_t *)(to) = (int32_t)(x))
-
-
- /*****************************************************************************
-  * Bit shift / Bit wise                                                      *
-  *****************************************************************************/
-
- #define _mm_or_si128(a, b) (vorrq_s8((a), (b)))
- #define _mm_xor_si128(a, b) (veorq_s8((a), (b)))
- #define _mm_and_si128(a, b) (vandq_s8((a), (b)))
- #define _mm_andnot_si128(a, b) (vbicq_s8((b), (a)))
-
- #define _mm_slli_epi16(x, count) (vreinterpretq_s8_u16(vshlq_n_u16(vreinterpretq_u16_s8(x), (count))))
- #define _mm_slli_epi32(x, count) (vreinterpretq_s8_u32(vshlq_n_u32(vreinterpretq_u32_s8(x), (count))))
- #define _mm_slli_epi64(x, count) (vreinterpretq_s8_u64(vshlq_n_u64(vreinterpretq_u64_s8(x), (count))))
- static XSSE_FORCE_INLINE __m128i _mm_sll_epi16(__m128i x, __m128i count)
- {
-	 uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF);
-	 return vreinterpretq_s8_u16(
-		 vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16((int16_t) shift))
-	 );
- }
- static XSSE_FORCE_INLINE __m128i _mm_sll_epi32(__m128i x, __m128i count)
- {
-	 uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF);
-	 return vreinterpretq_s8_u32(
-		 vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32((int32_t) shift))
-	 );
- }
- static XSSE_FORCE_INLINE __m128i _mm_sll_epi64(__m128i x, __m128i count)
- {
-	 uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0);
-	 return vreinterpretq_s8_u64(
-		 vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64((int64_t) shift))
-	 );
- }
-
- #define _mm_slli_si128(x, imm) \
-	 ((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vdupq_n_u8(0), vreinterpretq_u8_s8(x), 16 - (imm))))
-
- #define _mm_srai_epi16(x, count) (vreinterpretq_s8_s16(vshrq_n_s16(vreinterpretq_s16_s8(x), (count))))
- #define _mm_srai_epi32(x, count) (vreinterpretq_s8_s32(vshrq_n_s32(vreinterpretq_s32_s8(x), (count))))
- static inline __m128i _mm_sra_epi16(__m128i x, __m128i count)
- {
-	 uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF);
-	 return vreinterpretq_s8_s16(
-		 vshlq_s16(vreinterpretq_s16_s8(x), vdupq_n_s16(-(int16_t) shift))
-	 );
- }
- static inline __m128i _mm_sra_epi32(__m128i x, __m128i count)
- {
-	 uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF);
-	 return vreinterpretq_s8_s32(
-		 vshlq_s32(vreinterpretq_s32_s8(x), vdupq_n_s32(-(int32_t) shift))
-	 );
- }
-
- #define _mm_srli_epi16(x, count) (vreinterpretq_s8_u16(vshrq_n_u16(vreinterpretq_u16_s8(x), (count))))
- #define _mm_srli_epi32(x, count) (vreinterpretq_s8_u32(vshrq_n_u32(vreinterpretq_u32_s8(x), (count))))
- #define _mm_srli_epi64(x, count) (vreinterpretq_s8_u64(vshrq_n_u64(vreinterpretq_u64_s8(x), (count))))
- static XSSE_FORCE_INLINE __m128i _mm_srl_epi16(__m128i x, __m128i count)
- {
-	 uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF);
-	 return vreinterpretq_s8_u16(
-		 vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16(-(int16_t) shift))
-	 );
- }
- static XSSE_FORCE_INLINE __m128i _mm_srl_epi32(__m128i x, __m128i count)
- {
-	 uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF);
-	 return vreinterpretq_s8_u32(
-		 vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32(-(int32_t) shift))
-	 );
- }
- static XSSE_FORCE_INLINE __m128i _mm_srl_epi64(__m128i x, __m128i count)
- {
-	 uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0);
-	 return vreinterpretq_s8_u64(
-		 vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64(-(int64_t) shift))
-	 );
- }
-
- #define _mm_srli_si128(x, imm) \
-	 ((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vreinterpretq_u8_s8(x), vdupq_n_u8(0), (imm))))
-
-
- /*****************************************************************************
-  * Integer Arithmetic Operations                                             *
-  *****************************************************************************/
-
- /**
-  * In practice, there is no problem, but a runtime error for signed integer overflow is triggered by UBSAN,
-  * so perform the calculation as unsigned. Since it is optimized at compile time, there are no unnecessary casts at runtime.
-  */
- #define _mm_add_epi8(a, b) (vreinterpretq_s8_u8(vaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
- #define _mm_add_epi16(a, b) (vreinterpretq_s8_u16(vaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
- #define _mm_add_epi32(a, b) (vreinterpretq_s8_u32(vaddq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b))))
- #define _mm_add_epi64(a, b) (vreinterpretq_s8_u64(vaddq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b))))
-
- #define _mm_adds_epi8(a, b) (vqaddq_s8((a), (b)))
- #define _mm_adds_epi16(a, b) (vreinterpretq_s8_s16(vqaddq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_adds_epu8(a, b) (vreinterpretq_s8_u8(vqaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
- #define _mm_adds_epu16(a, b) (vreinterpretq_s8_u16(vqaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
-
- #define _mm_avg_epu8(a, b) (vreinterpretq_s8_u8(vrhaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
- #define _mm_avg_epu16(a, b) (vreinterpretq_s8_u16(vrhaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
-
- static XSSE_FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b)
- {
-	 int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b)));
-	 int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b)));
-
-	 return vreinterpretq_s8_s32(vcombine_s32(
-		 vpadd_s32(vget_low_s32(mul_lo), vget_high_s32(mul_lo)),
-		 vpadd_s32(vget_low_s32(mul_hi), vget_high_s32(mul_hi))
-	 ));
- }
-
- #define _mm_max_epu8(a, b) (vreinterpretq_s8_u8(vmaxq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
- #define _mm_max_epi16(a, b) (vreinterpretq_s8_s16(vmaxq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_min_epu8(a, b) (vreinterpretq_s8_u8(vminq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
- #define _mm_min_epi16(a, b) (vreinterpretq_s8_s16(vminq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
-
- static XSSE_FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b)
- {
-	 int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b)));
-	 int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b)));
-	 return vreinterpretq_s8_s16(vcombine_s16(vshrn_n_s32(lo, 16), vshrn_n_s32(hi, 16)));
- }
- static XSSE_FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b)
- {
-	 uint32x4_t lo = vmull_u16(vget_low_u16(vreinterpretq_u16_s8(a)), vget_low_u16(vreinterpretq_u16_s8(b)));
-	 uint32x4_t hi = vmull_u16(vget_high_u16(vreinterpretq_u16_s8(a)), vget_high_u16(vreinterpretq_u16_s8(b)));
-	 return vreinterpretq_s8_u16(vcombine_u16(vshrn_n_u32(lo, 16), vshrn_n_u32(hi, 16)));
- }
- static XSSE_FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b)
- {
-	 int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b)));
-	 int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b)));
-	 return vreinterpretq_s8_s16(vcombine_s16(vmovn_s32(lo), vmovn_s32(hi)));
- }
- static XSSE_FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b)
- {
-	 uint32x4_t evens = vuzpq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)).val[0];
-	 return vreinterpretq_s8_u64(vmull_u32(vget_low_u32(evens), vget_high_u32(evens)));
- }
- static XSSE_FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b)
- {
-	 uint16x8_t abs_diffs_16 = vpaddlq_u8(vabdq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)));
-	 uint32x4_t abs_diffs_32 = vpaddlq_u16(abs_diffs_16);
-	 uint64x2_t abs_diffs_64 = vpaddlq_u32(abs_diffs_32);
-
-	 return vreinterpretq_s8_u16((uint16x8_t) {
-		 (int16_t) vgetq_lane_u64(abs_diffs_64, 0), 0, 0, 0,
-		 (int16_t) vgetq_lane_u64(abs_diffs_64, 1), 0, 0, 0
-	 });
- }
-
- #define _mm_sub_epi8(a, b) (vreinterpretq_s8_u8(vsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
- #define _mm_sub_epi16(a, b) (vreinterpretq_s8_u16(vsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
- #define _mm_sub_epi32(a, b) (vreinterpretq_s8_u32(vsubq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b))))
- #define _mm_sub_epi64(a, b) (vreinterpretq_s8_u64(vsubq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b))))
-
- #define _mm_subs_epi8(a, b) (vqsubq_s8((a), (b)))
- #define _mm_subs_epi16(a, b) (vreinterpretq_s8_s16(vqsubq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_subs_epu8(a, b) (vreinterpretq_s8_u8(vqsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
- #define _mm_subs_epu16(a, b) (vreinterpretq_s8_u16(vqsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
-
-
- /*****************************************************************************
-  * Comparison                                                                *
-  *****************************************************************************/
-
- #define _mm_cmpeq_epi8(a, b) (vreinterpretq_s8_u8(vceqq_s8((a), (b))))
- #define _mm_cmpeq_epi16(a, b) (vreinterpretq_s8_u16(vceqq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_cmpeq_epi32(a, b) (vreinterpretq_s8_u32(vceqq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
-
- #define _mm_cmplt_epi8(a, b) (vreinterpretq_s8_u8(vcltq_s8((a), (b))))
- #define _mm_cmplt_epi16(a, b) (vreinterpretq_s8_u16(vcltq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_cmplt_epi32(a, b) (vreinterpretq_s8_u32(vcltq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
-
- #define _mm_cmpgt_epi8(a, b) (vreinterpretq_s8_u8(vcgtq_s8((a), (b))))
- #define _mm_cmpgt_epi16(a, b) (vreinterpretq_s8_u16(vcgtq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_cmpgt_epi32(a, b) (vreinterpretq_s8_u32(vcgtq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
-
-
- /*****************************************************************************
-  * Convert                                                                   *
-  *****************************************************************************/
-
- #define _mm_cvtsi32_si128(x) (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x), 0, 0, 0 }))
- #define _mm_cvtsi64_si128(x) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x), 0 }))
- #define _mm_cvtsi128_si32(x) (vgetq_lane_s32(vreinterpretq_s32_s8(x), 0))
- #define _mm_cvtsi128_si64(x) (vgetq_lane_s64(vreinterpretq_s64_s8(x), 0))
-
-
- /*****************************************************************************
-  * Others                                                                    *
-  *****************************************************************************/
-
- #define _mm_packs_epi16(a, b) (vcombine_s8(vqmovn_s16(vreinterpretq_s16_s8(a)), vqmovn_s16(vreinterpretq_s16_s8(b))))
- #define _mm_packs_epi32(a, b) \
-	 (vreinterpretq_s8_s16(vcombine_s16(vqmovn_s32(vreinterpretq_s32_s8(a)), vqmovn_s32(vreinterpretq_s32_s8(b)))))
- #define _mm_packus_epi16(a, b) \
-	 (vreinterpretq_s8_u8(vcombine_u8(vqmovun_s16(vreinterpretq_s16_s8(a)), vqmovun_s16(vreinterpretq_s16_s8(b)))))
-
- #define _mm_extract_epi16(x, imm) (vgetq_lane_s16(vreinterpretq_s16_s8(x), (imm)))
- #define _mm_insert_epi16(x, val, imm) (vreinterpretq_s8_s16(vsetq_lane_s16((int16_t) (val), vreinterpretq_s16_s8(x), (imm))))
-
- static XSSE_FORCE_INLINE int _mm_movemask_epi8(__m128i x)
- {
-	 /**
-	  * based on code from
-	  * https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
-	  */
-	 uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(vreinterpretq_u8_s8(x), 7));
-	 uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7));
-	 uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));
-	 uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));
-	 return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8);
- }
-
- #define _MM_SHUFFLE(a, b, c, d) (((a) << 6) | ((b) << 4) | ((c) << 2) | (d))
- #ifdef XSSE_HAS_MACRO_EXTENSION
- #define _mm_shuffle_epi32(x, imm) __extension__({ \
-		 int32x4_t __xsse_tmp = vreinterpretq_s32_s8(x); \
-		 vreinterpretq_s8_s32((int32x4_t) { \
-			 (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 0) & 0x3), \
-			 (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 2) & 0x3), \
-			 (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 4) & 0x3), \
-			 (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 6) & 0x3) \
-		 }); \
-	 })
- #define _mm_shufflehi_epi16(x, imm) __extension__({ \
-		 int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \
-		 vreinterpretq_s8_s16(vcombine_s16( \
-			 vget_low_s16(__xsse_tmp), \
-			 (int16x4_t) { \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3) + 4), \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3) + 4), \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3) + 4), \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3) + 4) \
-			 } \
-		 )); \
-	 })
- #define _mm_shufflelo_epi16(x, imm) __extension__({ \
-		 int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \
-		 vreinterpretq_s8_s16(vcombine_s16( \
-			 (int16x4_t) { \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3)), \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3)), \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3)), \
-				 (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3)) \
-			 }, \
-			 vget_high_s16(__xsse_tmp) \
-		 )); \
-	 })
- #else
- static XSSE_FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i x, int imm)
- {
-	 int32x4_t vec = vreinterpretq_s32_s8(x);
-	 int32_t arr[4];
-	 vst1q_s32(arr, vec);
-
-	 return vreinterpretq_s8_s32((int32x4_t) {
-		 arr[(imm >> 0) & 0x3],
-		 arr[(imm >> 2) & 0x3],
-		 arr[(imm >> 4) & 0x3],
-		 arr[(imm >> 6) & 0x3]
-	 });
- }
- static XSSE_FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i x, int imm)
- {
-	 int16x8_t vec = vreinterpretq_s16_s8(x);
-	 int16_t arr[8];
-	 vst1q_s16(arr, vec);
-
-	 return vreinterpretq_s8_s16((int16x8_t) {
-		 arr[0], arr[1], arr[2], arr[3],
-		 arr[((imm >> 0) & 0x3) + 4],
-		 arr[((imm >> 2) & 0x3) + 4],
-		 arr[((imm >> 4) & 0x3) + 4],
-		 arr[((imm >> 6) & 0x3) + 4]
-	 });
- }
- static XSSE_FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i x, int imm)
- {
-	 int16x8_t vec = vreinterpretq_s16_s8(x);
-	 int16_t arr[8];
-	 vst1q_s16(arr, vec);
-
-	 return vreinterpretq_s8_s16((int16x8_t) {
-		 arr[((imm >> 0) & 0x3)],
-		 arr[((imm >> 2) & 0x3)],
-		 arr[((imm >> 4) & 0x3)],
-		 arr[((imm >> 6) & 0x3)],
-		 arr[4], arr[5], arr[6], arr[7]
-	 });
- }
- #endif
-
- #define _mm_unpackhi_epi8(a, b) (vzip2q_s8((a), (b)))
- #define _mm_unpackhi_epi16(a, b) (vreinterpretq_s8_s16(vzip2q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_unpackhi_epi32(a, b) (vreinterpretq_s8_s32(vzip2q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
- #define _mm_unpackhi_epi64(a, b) (vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b))))
-
- #define _mm_unpacklo_epi8(a, b) (vzip1q_s8((a), (b)))
- #define _mm_unpacklo_epi16(a, b) (vreinterpretq_s8_s16(vzip1q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
- #define _mm_unpacklo_epi32(a, b) (vreinterpretq_s8_s32(vzip1q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
- #define _mm_unpacklo_epi64(a, b) (vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b))))
-
- #define _mm_move_epi64(x) (vreinterpretq_s8_s64((int64x2_t) { vgetq_lane_s64(vreinterpretq_s64_s8(x), 0), 0 }))
-
- #endif
-
- #endif /* XSSE_H */
+#ifndef XSSE_H
+#define XSSE_H
+
+#define XSSE_VERSION 10000
+
+#ifdef _MSC_VER
+#  define XSSE_FORCE_INLINE __forceinline
+#elif defined(__GNUC__) || defined(__clang__)
+#  define XSSE_FORCE_INLINE inline __attribute__((always_inline))
+#  define XSSE_HAS_MACRO_EXTENSION
+#else
+#  define XSSE_FORCE_INLINE inline
+#endif
+
+
+#if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64)
+#include 
+#define XSSE2
+
+
+#elif defined(__aarch64__) || defined(_M_ARM64)
+#include 
+#define XSSE2
+
+typedef int8x16_t __m128i;
+
+
+/*****************************************************************************
+ * Load / Store                                                              *
+ *****************************************************************************/
+
+#define _mm_set_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \
+	((int8x16_t) { \
+		(int8_t) (x15), (int8_t) (x14), (int8_t) (x13), (int8_t) (x12), \
+		(int8_t) (x11), (int8_t) (x10), (int8_t) (x9),  (int8_t) (x8), \
+		(int8_t) (x7),  (int8_t) (x6),  (int8_t) (x5),  (int8_t) (x4), \
+		(int8_t) (x3),  (int8_t) (x2),  (int8_t) (x1),  (int8_t) (x0) })
+#define _mm_set_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \
+	(vreinterpretq_s8_s16((int16x8_t) { \
+		(int16_t) (x7), (int16_t) (x6), (int16_t) (x5), (int16_t) (x4), \
+		(int16_t) (x3), (int16_t) (x2), (int16_t) (x1), (int16_t) (x0) }))
+#define _mm_set_epi32(x0, x1, x2, x3) \
+	(vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x3), (int32_t) (x2), (int32_t) (x1), (int32_t) (x0) }))
+#define _mm_set_epi64x(x0, x1) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x1), (int64_t) (x0) }))
+#define _mm_set1_epi8(x) (vdupq_n_s8((int8_t) (x)))
+#define _mm_set1_epi16(x) (vreinterpretq_s8_s16(vdupq_n_s16((int16_t) (x))))
+#define _mm_set1_epi32(x) (vreinterpretq_s8_s32(vdupq_n_s32((int32_t) (x))))
+#define _mm_set1_epi64x(x) (vreinterpretq_s8_s64(vdupq_n_s64((int64_t) (x))))
+
+#define _mm_setr_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \
+	((int8x16_t) { \
+		(int8_t) (x0), (int8_t) (x1), (int8_t) (x2), (int8_t) (x3), \
+		(int8_t) (x4), (int8_t) (x5), (int8_t) (x6), (int8_t) (x7), \
+		(int8_t) (x8), (int8_t) (x9), (int8_t) (x10), (int8_t) (x11), \
+		(int8_t) (x12), (int8_t) (x13), (int8_t) (x14), (int8_t) (x15) })
+#define _mm_setr_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \
+	(vreinterpretq_s8_s16((int16x8_t) { \
+		(int16_t) (x0), (int16_t) (x1), (int16_t) (x2), (int16_t) (x3), \
+		(int16_t) (x4), (int16_t) (x5), (int16_t) (x6), (int16_t) (x7) }))
+#define _mm_setr_epi32(x0, x1, x2, x3) \
+	(vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x0), (int32_t) (x1), (int32_t) (x2), (int32_t) (x3) }))
+
+#define _mm_setzero_si128() (vdupq_n_s8(0))
+
+#define _mm_load_si128(x) (vld1q_s8((const int8_t *) (x)))
+#define _mm_loadu_si128(x) _mm_load_si128(x)
+
+#define _mm_store_si128(to, x) (vst1q_s8((int8_t *) (to), x))
+#define _mm_storeu_si128(to, x) _mm_store_si128(to, x)
+#define _mm_stream_si128(to, x) _mm_store_si128(to, x)
+#define _mm_stream_si32(to, x) (*(volatile int32_t *)(to) = (int32_t)(x))
+
+
+/*****************************************************************************
+ * Bit shift / Bit wise                                                      *
+ *****************************************************************************/
+
+#define _mm_or_si128(a, b) (vorrq_s8((a), (b)))
+#define _mm_xor_si128(a, b) (veorq_s8((a), (b)))
+#define _mm_and_si128(a, b) (vandq_s8((a), (b)))
+#define _mm_andnot_si128(a, b) (vbicq_s8((b), (a)))
+
+#define _mm_slli_epi16(x, count) (vreinterpretq_s8_u16(vshlq_n_u16(vreinterpretq_u16_s8(x), (count))))
+#define _mm_slli_epi32(x, count) (vreinterpretq_s8_u32(vshlq_n_u32(vreinterpretq_u32_s8(x), (count))))
+#define _mm_slli_epi64(x, count) (vreinterpretq_s8_u64(vshlq_n_u64(vreinterpretq_u64_s8(x), (count))))
+static XSSE_FORCE_INLINE __m128i _mm_sll_epi16(__m128i x, __m128i count)
+{
+	uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF);
+	return vreinterpretq_s8_u16(
+		vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16((int16_t) shift))
+	);
+}
+static XSSE_FORCE_INLINE __m128i _mm_sll_epi32(__m128i x, __m128i count)
+{
+	uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF);
+	return vreinterpretq_s8_u32(
+		vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32((int32_t) shift))
+	);
+}
+static XSSE_FORCE_INLINE __m128i _mm_sll_epi64(__m128i x, __m128i count)
+{
+	uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0);
+	return vreinterpretq_s8_u64(
+		vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64((int64_t) shift))
+	);
+}
+
+#define _mm_slli_si128(x, imm) \
+	((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vdupq_n_u8(0), vreinterpretq_u8_s8(x), 16 - (imm))))
+
+#define _mm_srai_epi16(x, count) (vreinterpretq_s8_s16(vshrq_n_s16(vreinterpretq_s16_s8(x), (count))))
+#define _mm_srai_epi32(x, count) (vreinterpretq_s8_s32(vshrq_n_s32(vreinterpretq_s32_s8(x), (count))))
+static inline __m128i _mm_sra_epi16(__m128i x, __m128i count)
+{
+	uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF);
+	return vreinterpretq_s8_s16(
+		vshlq_s16(vreinterpretq_s16_s8(x), vdupq_n_s16(-(int16_t) shift))
+	);
+}
+static inline __m128i _mm_sra_epi32(__m128i x, __m128i count)
+{
+	uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF);
+	return vreinterpretq_s8_s32(
+		vshlq_s32(vreinterpretq_s32_s8(x), vdupq_n_s32(-(int32_t) shift))
+	);
+}
+
+#define _mm_srli_epi16(x, count) (vreinterpretq_s8_u16(vshrq_n_u16(vreinterpretq_u16_s8(x), (count))))
+#define _mm_srli_epi32(x, count) (vreinterpretq_s8_u32(vshrq_n_u32(vreinterpretq_u32_s8(x), (count))))
+#define _mm_srli_epi64(x, count) (vreinterpretq_s8_u64(vshrq_n_u64(vreinterpretq_u64_s8(x), (count))))
+static XSSE_FORCE_INLINE __m128i _mm_srl_epi16(__m128i x, __m128i count)
+{
+	uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF);
+	return vreinterpretq_s8_u16(
+		vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16(-(int16_t) shift))
+	);
+}
+static XSSE_FORCE_INLINE __m128i _mm_srl_epi32(__m128i x, __m128i count)
+{
+	uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF);
+	return vreinterpretq_s8_u32(
+		vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32(-(int32_t) shift))
+	);
+}
+static XSSE_FORCE_INLINE __m128i _mm_srl_epi64(__m128i x, __m128i count)
+{
+	uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0);
+	return vreinterpretq_s8_u64(
+		vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64(-(int64_t) shift))
+	);
+}
+
+#define _mm_srli_si128(x, imm) \
+	((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vreinterpretq_u8_s8(x), vdupq_n_u8(0), (imm))))
+
+
+/*****************************************************************************
+ * Integer Arithmetic Operations                                             *
+ *****************************************************************************/
+
+/**
+ * In practice, there is no problem, but a runtime error for signed integer overflow is triggered by UBSAN,
+ * so perform the calculation as unsigned. Since it is optimized at compile time, there are no unnecessary casts at runtime.
+ */
+#define _mm_add_epi8(a, b) (vreinterpretq_s8_u8(vaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
+#define _mm_add_epi16(a, b) (vreinterpretq_s8_u16(vaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
+#define _mm_add_epi32(a, b) (vreinterpretq_s8_u32(vaddq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b))))
+#define _mm_add_epi64(a, b) (vreinterpretq_s8_u64(vaddq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b))))
+
+#define _mm_adds_epi8(a, b) (vqaddq_s8((a), (b)))
+#define _mm_adds_epi16(a, b) (vreinterpretq_s8_s16(vqaddq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_adds_epu8(a, b) (vreinterpretq_s8_u8(vqaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
+#define _mm_adds_epu16(a, b) (vreinterpretq_s8_u16(vqaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
+
+#define _mm_avg_epu8(a, b) (vreinterpretq_s8_u8(vrhaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
+#define _mm_avg_epu16(a, b) (vreinterpretq_s8_u16(vrhaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
+
+static XSSE_FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b)
+{
+	int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b)));
+	int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b)));
+
+	return vreinterpretq_s8_s32(vcombine_s32(
+		vpadd_s32(vget_low_s32(mul_lo), vget_high_s32(mul_lo)),
+		vpadd_s32(vget_low_s32(mul_hi), vget_high_s32(mul_hi))
+	));
+}
+
+#define _mm_max_epu8(a, b) (vreinterpretq_s8_u8(vmaxq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
+#define _mm_max_epi16(a, b) (vreinterpretq_s8_s16(vmaxq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_min_epu8(a, b) (vreinterpretq_s8_u8(vminq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
+#define _mm_min_epi16(a, b) (vreinterpretq_s8_s16(vminq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+
+static XSSE_FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b)
+{
+	int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b)));
+	int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b)));
+	return vreinterpretq_s8_s16(vcombine_s16(vshrn_n_s32(lo, 16), vshrn_n_s32(hi, 16)));
+}
+static XSSE_FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b)
+{
+	uint32x4_t lo = vmull_u16(vget_low_u16(vreinterpretq_u16_s8(a)), vget_low_u16(vreinterpretq_u16_s8(b)));
+	uint32x4_t hi = vmull_u16(vget_high_u16(vreinterpretq_u16_s8(a)), vget_high_u16(vreinterpretq_u16_s8(b)));
+	return vreinterpretq_s8_u16(vcombine_u16(vshrn_n_u32(lo, 16), vshrn_n_u32(hi, 16)));
+}
+static XSSE_FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b)
+{
+	int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b)));
+	int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b)));
+	return vreinterpretq_s8_s16(vcombine_s16(vmovn_s32(lo), vmovn_s32(hi)));
+}
+static XSSE_FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b)
+{
+	uint32x4_t evens = vuzpq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)).val[0];
+	return vreinterpretq_s8_u64(vmull_u32(vget_low_u32(evens), vget_high_u32(evens)));
+}
+static XSSE_FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b)
+{
+	uint16x8_t abs_diffs_16 = vpaddlq_u8(vabdq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)));
+	uint32x4_t abs_diffs_32 = vpaddlq_u16(abs_diffs_16);
+	uint64x2_t abs_diffs_64 = vpaddlq_u32(abs_diffs_32);
+
+	return vreinterpretq_s8_u16((uint16x8_t) {
+		(int16_t) vgetq_lane_u64(abs_diffs_64, 0), 0, 0, 0,
+		(int16_t) vgetq_lane_u64(abs_diffs_64, 1), 0, 0, 0
+	});
+}
+
+#define _mm_sub_epi8(a, b) (vreinterpretq_s8_u8(vsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
+#define _mm_sub_epi16(a, b) (vreinterpretq_s8_u16(vsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
+#define _mm_sub_epi32(a, b) (vreinterpretq_s8_u32(vsubq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b))))
+#define _mm_sub_epi64(a, b) (vreinterpretq_s8_u64(vsubq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b))))
+
+#define _mm_subs_epi8(a, b) (vqsubq_s8((a), (b)))
+#define _mm_subs_epi16(a, b) (vreinterpretq_s8_s16(vqsubq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_subs_epu8(a, b) (vreinterpretq_s8_u8(vqsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))))
+#define _mm_subs_epu16(a, b) (vreinterpretq_s8_u16(vqsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b))))
+
+
+/*****************************************************************************
+ * Comparison                                                                *
+ *****************************************************************************/
+
+#define _mm_cmpeq_epi8(a, b) (vreinterpretq_s8_u8(vceqq_s8((a), (b))))
+#define _mm_cmpeq_epi16(a, b) (vreinterpretq_s8_u16(vceqq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_cmpeq_epi32(a, b) (vreinterpretq_s8_u32(vceqq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
+
+#define _mm_cmplt_epi8(a, b) (vreinterpretq_s8_u8(vcltq_s8((a), (b))))
+#define _mm_cmplt_epi16(a, b) (vreinterpretq_s8_u16(vcltq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_cmplt_epi32(a, b) (vreinterpretq_s8_u32(vcltq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
+
+#define _mm_cmpgt_epi8(a, b) (vreinterpretq_s8_u8(vcgtq_s8((a), (b))))
+#define _mm_cmpgt_epi16(a, b) (vreinterpretq_s8_u16(vcgtq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_cmpgt_epi32(a, b) (vreinterpretq_s8_u32(vcgtq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
+
+
+/*****************************************************************************
+ * Convert                                                                   *
+ *****************************************************************************/
+
+#define _mm_cvtsi32_si128(x) (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x), 0, 0, 0 }))
+#define _mm_cvtsi64_si128(x) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x), 0 }))
+#define _mm_cvtsi128_si32(x) (vgetq_lane_s32(vreinterpretq_s32_s8(x), 0))
+#define _mm_cvtsi128_si64(x) (vgetq_lane_s64(vreinterpretq_s64_s8(x), 0))
+
+
+/*****************************************************************************
+ * Others                                                                    *
+ *****************************************************************************/
+
+#define _mm_packs_epi16(a, b) (vcombine_s8(vqmovn_s16(vreinterpretq_s16_s8(a)), vqmovn_s16(vreinterpretq_s16_s8(b))))
+#define _mm_packs_epi32(a, b) \
+	(vreinterpretq_s8_s16(vcombine_s16(vqmovn_s32(vreinterpretq_s32_s8(a)), vqmovn_s32(vreinterpretq_s32_s8(b)))))
+#define _mm_packus_epi16(a, b) \
+	(vreinterpretq_s8_u8(vcombine_u8(vqmovun_s16(vreinterpretq_s16_s8(a)), vqmovun_s16(vreinterpretq_s16_s8(b)))))
+
+#define _mm_extract_epi16(x, imm) (vgetq_lane_s16(vreinterpretq_s16_s8(x), (imm)))
+#define _mm_insert_epi16(x, val, imm) (vreinterpretq_s8_s16(vsetq_lane_s16((int16_t) (val), vreinterpretq_s16_s8(x), (imm))))
+
+static XSSE_FORCE_INLINE int _mm_movemask_epi8(__m128i x)
+{
+	/**
+	 * based on code from
+	 * https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
+	 */
+	uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(vreinterpretq_u8_s8(x), 7));
+	uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7));
+	uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));
+	uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));
+	return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8);
+}
+
+#define _MM_SHUFFLE(a, b, c, d) (((a) << 6) | ((b) << 4) | ((c) << 2) | (d))
+#ifdef XSSE_HAS_MACRO_EXTENSION
+#define _mm_shuffle_epi32(x, imm) __extension__({ \
+		int32x4_t __xsse_tmp = vreinterpretq_s32_s8(x); \
+		vreinterpretq_s8_s32((int32x4_t) { \
+			(int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 0) & 0x3), \
+			(int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 2) & 0x3), \
+			(int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 4) & 0x3), \
+			(int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 6) & 0x3) \
+		}); \
+	})
+#define _mm_shufflehi_epi16(x, imm) __extension__({ \
+		int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \
+		vreinterpretq_s8_s16(vcombine_s16( \
+			vget_low_s16(__xsse_tmp), \
+			(int16x4_t) { \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3) + 4), \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3) + 4), \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3) + 4), \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3) + 4) \
+			} \
+		)); \
+	})
+#define _mm_shufflelo_epi16(x, imm) __extension__({ \
+		int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \
+		vreinterpretq_s8_s16(vcombine_s16( \
+			(int16x4_t) { \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3)), \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3)), \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3)), \
+				(int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3)) \
+			}, \
+			vget_high_s16(__xsse_tmp) \
+		)); \
+	})
+#else
+static XSSE_FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i x, int imm)
+{
+	int32x4_t vec = vreinterpretq_s32_s8(x);
+	int32_t arr[4];
+	vst1q_s32(arr, vec);
+
+	return vreinterpretq_s8_s32((int32x4_t) {
+		arr[(imm >> 0) & 0x3],
+		arr[(imm >> 2) & 0x3],
+		arr[(imm >> 4) & 0x3],
+		arr[(imm >> 6) & 0x3]
+	});
+}
+static XSSE_FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i x, int imm)
+{
+	int16x8_t vec = vreinterpretq_s16_s8(x);
+	int16_t arr[8];
+	vst1q_s16(arr, vec);
+
+	return vreinterpretq_s8_s16((int16x8_t) {
+		arr[0], arr[1], arr[2], arr[3],
+		arr[((imm >> 0) & 0x3) + 4],
+		arr[((imm >> 2) & 0x3) + 4],
+		arr[((imm >> 4) & 0x3) + 4],
+		arr[((imm >> 6) & 0x3) + 4]
+	});
+}
+static XSSE_FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i x, int imm)
+{
+	int16x8_t vec = vreinterpretq_s16_s8(x);
+	int16_t arr[8];
+	vst1q_s16(arr, vec);
+
+	return vreinterpretq_s8_s16((int16x8_t) {
+		arr[((imm >> 0) & 0x3)],
+		arr[((imm >> 2) & 0x3)],
+		arr[((imm >> 4) & 0x3)],
+		arr[((imm >> 6) & 0x3)],
+		arr[4], arr[5], arr[6], arr[7]
+	});
+}
+#endif
+
+#define _mm_unpackhi_epi8(a, b) (vzip2q_s8((a), (b)))
+#define _mm_unpackhi_epi16(a, b) (vreinterpretq_s8_s16(vzip2q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_unpackhi_epi32(a, b) (vreinterpretq_s8_s32(vzip2q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
+#define _mm_unpackhi_epi64(a, b) (vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b))))
+
+#define _mm_unpacklo_epi8(a, b) (vzip1q_s8((a), (b)))
+#define _mm_unpacklo_epi16(a, b) (vreinterpretq_s8_s16(vzip1q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b))))
+#define _mm_unpacklo_epi32(a, b) (vreinterpretq_s8_s32(vzip1q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b))))
+#define _mm_unpacklo_epi64(a, b) (vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b))))
+
+#define _mm_move_epi64(x) (vreinterpretq_s8_s64((int64x2_t) { vgetq_lane_s64(vreinterpretq_s64_s8(x), 0), 0 }))
+
+#endif
+
+#endif /* XSSE_H */
diff --git a/Zend/zend_smart_str.c b/Zend/zend_smart_str.c
index 501f6e6176c8..e6475c1dd626 100644
--- a/Zend/zend_smart_str.c
+++ b/Zend/zend_smart_str.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Dmitry Stogov                                |
    +----------------------------------------------------------------------+
@@ -208,8 +206,11 @@ ZEND_API void ZEND_FASTCALL smart_str_append_scalar(smart_str *dest, const zval
 		break;
 
 		case IS_TRUE:
+			smart_str_appendl(dest, "true", sizeof("true")-1);
+		break;
+
 		case IS_FALSE:
-			smart_str_appends(dest, Z_TYPE_P(value) == IS_TRUE ? "true" : "false");
+			smart_str_appendl(dest, "false", sizeof("false")-1);
 		break;
 
 		case IS_DOUBLE:
@@ -226,7 +227,7 @@ ZEND_API void ZEND_FASTCALL smart_str_append_scalar(smart_str *dest, const zval
 			smart_str_appendc(dest, '\'');
 		break;
 
-		EMPTY_SWITCH_DEFAULT_CASE();
+		default: ZEND_UNREACHABLE();
 	}
 }
 
diff --git a/Zend/zend_smart_str.h b/Zend/zend_smart_str.h
index affbb5c50ac2..cb81cd2361c8 100644
--- a/Zend/zend_smart_str.h
+++ b/Zend/zend_smart_str.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_smart_str_public.h b/Zend/zend_smart_str_public.h
index 6a3b526254e4..d08ee49e47e0 100644
--- a/Zend/zend_smart_str_public.h
+++ b/Zend/zend_smart_str_public.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_smart_string.h b/Zend/zend_smart_string.h
index 9f04e1a340ad..e8655681186b 100644
--- a/Zend/zend_smart_string.h
+++ b/Zend/zend_smart_string.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    |         Xinchen Hui                                |
diff --git a/Zend/zend_smart_string_public.h b/Zend/zend_smart_string_public.h
index 543e1d37a4ef..8b2bfbedb271 100644
--- a/Zend/zend_smart_string_public.h
+++ b/Zend/zend_smart_string_public.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sascha Schumann                          |
    |         Xinchen Hui                                |
diff --git a/Zend/zend_sort.c b/Zend/zend_sort.c
index 355d2d1bad58..ac559141dd97 100644
--- a/Zend/zend_sort.c
+++ b/Zend/zend_sort.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Xinchen Hui                               |
    |          Sterling Hughes                           |
diff --git a/Zend/zend_sort.h b/Zend/zend_sort.h
index 5954575dbc25..03c63bb12e17 100644
--- a/Zend/zend_sort.h
+++ b/Zend/zend_sort.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Xinchen Hui                               |
    |          Sterling Hughes                           |
diff --git a/Zend/zend_stack.c b/Zend/zend_stack.c
index 5d9cc166367e..d999d684d05d 100644
--- a/Zend/zend_stack.c
+++ b/Zend/zend_stack.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_stack.h b/Zend/zend_stack.h
index a2edc12b1fb4..66c90f0b5217 100644
--- a/Zend/zend_stack.h
+++ b/Zend/zend_stack.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c
index 8e11841ad265..0627ae145939 100644
--- a/Zend/zend_stream.c
+++ b/Zend/zend_stream.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Wez Furlong                           |
    |          Scott MacVicar                            |
diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h
index 33d8656dad5e..ed2bef941e2a 100644
--- a/Zend/zend_stream.h
+++ b/Zend/zend_stream.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Wez Furlong                           |
    |          Scott MacVicar                            |
diff --git a/Zend/zend_string.c b/Zend/zend_string.c
index dfe059359aa5..52fca0cd4346 100644
--- a/Zend/zend_string.c
+++ b/Zend/zend_string.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -18,6 +17,7 @@
 
 #include "zend.h"
 #include "zend_globals.h"
+#include "zend_multiply.h"
 
 #ifdef HAVE_VALGRIND
 # include "valgrind/callgrind.h"
@@ -86,8 +86,6 @@ static zend_always_inline void zend_init_interned_strings_ht(HashTable *interned
 ZEND_API void zend_interned_strings_init(void)
 {
 	char s[2];
-	unsigned int i;
-	zend_string *str;
 
 	interned_string_request_handler = zend_new_interned_string_request;
 	interned_string_init_request_handler = zend_string_init_interned_request;
@@ -96,22 +94,20 @@ ZEND_API void zend_interned_strings_init(void)
 	zend_empty_string = NULL;
 	zend_known_strings = NULL;
 
-	zend_init_interned_strings_ht(&interned_strings_permanent, 1);
+	zend_init_interned_strings_ht(&interned_strings_permanent, true);
 
 	zend_new_interned_string = zend_new_interned_string_permanent;
 	zend_string_init_interned = zend_string_init_interned_permanent;
 	zend_string_init_existing_interned = zend_string_init_existing_interned_permanent;
 
 	/* interned empty string */
-	str = zend_string_alloc(sizeof("")-1, 1);
-	ZSTR_VAL(str)[0] = '\000';
-	zend_empty_string = zend_new_interned_string_permanent(str);
+	zend_empty_string = zend_string_init_interned_permanent("", 0, true);
 	GC_ADD_FLAGS(zend_empty_string, IS_STR_VALID_UTF8);
 
 	s[1] = 0;
-	for (i = 0; i < 256; i++) {
+	for (size_t i = 0; i < 256; i++) {
 		s[0] = i;
-		zend_one_char_string[i] = zend_new_interned_string_permanent(zend_string_init(s, 1, 1));
+		zend_one_char_string[i] = zend_string_init_interned_permanent(s, 1, true);
 		if (i < 0x80) {
 			GC_ADD_FLAGS(zend_one_char_string[i], IS_STR_VALID_UTF8);
 		}
@@ -119,9 +115,8 @@ ZEND_API void zend_interned_strings_init(void)
 
 	/* known strings */
 	zend_known_strings = pemalloc(sizeof(zend_string*) * ((sizeof(known_strings) / sizeof(known_strings[0]) - 1)), 1);
-	for (i = 0; i < (sizeof(known_strings) / sizeof(known_strings[0])) - 1; i++) {
-		str = zend_string_init(known_strings[i], strlen(known_strings[i]), 1);
-		zend_known_strings[i] = zend_new_interned_string_permanent(str);
+	for (size_t i = 0; i < (sizeof(known_strings) / sizeof(known_strings[0])) - 1; i++) {
+		zend_known_strings[i] = zend_string_init_interned_permanent(known_strings[i], strlen(known_strings[i]), true);
 		GC_ADD_FLAGS(zend_known_strings[i], IS_STR_VALID_UTF8);
 	}
 }
@@ -350,7 +345,7 @@ static zend_string* ZEND_FASTCALL zend_string_init_existing_interned_request(con
 
 ZEND_API void zend_interned_strings_activate(void)
 {
-	zend_init_interned_strings_ht(&CG(interned_strings), 0);
+	zend_init_interned_strings_ht(&CG(interned_strings), false);
 }
 
 ZEND_API void zend_interned_strings_deactivate(void)
@@ -479,12 +474,12 @@ ZEND_API zend_string *zend_string_concat2(
 		const char *str1, size_t str1_len,
 		const char *str2, size_t str2_len)
 {
-	size_t len = str1_len + str2_len;
-	zend_string *res = zend_string_alloc(len, 0);
+	zend_string *res = zend_string_safe_alloc(1, str1_len, str2_len, 0);
 
-	memcpy(ZSTR_VAL(res), str1, str1_len);
-	memcpy(ZSTR_VAL(res) + str1_len, str2, str2_len);
-	ZSTR_VAL(res)[len] = '\0';
+	char *p = ZSTR_VAL(res);
+	p = zend_mempcpy(p, str1, str1_len);
+	p = zend_mempcpy(p, str2, str2_len);
+	*p++ = '\0';
 
 	return res;
 }
@@ -494,19 +489,23 @@ ZEND_API zend_string *zend_string_concat3(
 		const char *str2, size_t str2_len,
 		const char *str3, size_t str3_len)
 {
-	size_t len = str1_len + str2_len + str3_len;
+	size_t tmp_len = zend_safe_address_guarded(1, str1_len, str2_len);
+	size_t len = zend_safe_address_guarded(1, tmp_len, str3_len);
 	zend_string *res = zend_string_alloc(len, 0);
 
-	memcpy(ZSTR_VAL(res), str1, str1_len);
-	memcpy(ZSTR_VAL(res) + str1_len, str2, str2_len);
-	memcpy(ZSTR_VAL(res) + str1_len + str2_len, str3, str3_len);
-	ZSTR_VAL(res)[len] = '\0';
+	char *p = ZSTR_VAL(res);
+	p = zend_mempcpy(p, str1, str1_len);
+	p = zend_mempcpy(p, str2, str2_len);
+	p = zend_mempcpy(p, str3, str3_len);
+	*p++ = '\0';
 
 	return res;
 }
 
-/* strlcpy and strlcat are not intercepted by msan, so we need to do it ourselves. */
-#if __has_feature(memory_sanitizer)
+/* strlcpy and strlcat are not always intercepted by msan, so we need to do it
+ * ourselves. Apply a simple heuristic to determine the platforms that need it.
+ * See https://github.com/php/php-src/issues/20002. */
+#if __has_feature(memory_sanitizer) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__APPLE__)
 static size_t (*libc_strlcpy)(char *__restrict, const char *__restrict, size_t);
 size_t strlcpy(char *__restrict dest, const char *__restrict src, size_t n)
 {
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
index 0b2a484016ec..3f0c9abd2596 100644
--- a/Zend/zend_string.h
+++ b/Zend/zend_string.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -70,46 +69,53 @@ END_EXTERN_C()
 #define ZSTR_H(zstr)    (zstr)->h
 #define ZSTR_HASH(zstr) zend_string_hash_val(zstr)
 
-/* Compatibility macros */
-
-#define IS_INTERNED(s)	ZSTR_IS_INTERNED(s)
-#define STR_EMPTY_ALLOC()	ZSTR_EMPTY_ALLOC()
-#define _STR_HEADER_SIZE _ZSTR_HEADER_SIZE
-#define STR_ALLOCA_ALLOC(str, _len, use_heap) ZSTR_ALLOCA_ALLOC(str, _len, use_heap)
-#define STR_ALLOCA_INIT(str, s, len, use_heap) ZSTR_ALLOCA_INIT(str, s, len, use_heap)
-#define STR_ALLOCA_FREE(str, use_heap) ZSTR_ALLOCA_FREE(str, use_heap)
-
 /*---*/
 
-#define ZSTR_IS_INTERNED(s)					(GC_FLAGS(s) & IS_STR_INTERNED)
-#define ZSTR_IS_VALID_UTF8(s)				(GC_FLAGS(s) & IS_STR_VALID_UTF8)
+static zend_always_inline bool ZSTR_IS_INTERNED(const zend_string *s) {
+	return GC_FLAGS(s) & IS_STR_INTERNED;
+}
+
+static inline bool ZSTR_IS_VALID_UTF8(const zend_string *s) {
+	return GC_FLAGS(s) & IS_STR_VALID_UTF8;
+}
 
 /* These are properties, encoded as flags, that will hold on the resulting string
  * after concatenating two strings that have these property.
  * Example: concatenating two UTF-8 strings yields another UTF-8 string. */
 #define ZSTR_COPYABLE_CONCAT_PROPERTIES		(IS_STR_VALID_UTF8)
 
-#define ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s) 				(GC_FLAGS(s) & ZSTR_COPYABLE_CONCAT_PROPERTIES)
-/* This macro returns the copyable concat properties which hold on both strings. */
-#define ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(s1, s2)	(GC_FLAGS(s1) & GC_FLAGS(s2) & ZSTR_COPYABLE_CONCAT_PROPERTIES)
+static inline uint32_t ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(const zend_string *s) {
+	return GC_FLAGS(s) & ZSTR_COPYABLE_CONCAT_PROPERTIES;
+}
 
-#define ZSTR_COPY_CONCAT_PROPERTIES(out, in) do { \
-	zend_string *_out = (out); \
-	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES((in)); \
-	GC_ADD_FLAGS(_out, properties); \
-} while (0)
+/* This function returns the copyable concat properties which hold on both strings. */
+static inline uint32_t ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(const zend_string *s1, const zend_string *s2) {
+	return ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s1) & ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s2);
+}
 
-#define ZSTR_COPY_CONCAT_PROPERTIES_BOTH(out, in1, in2) do { \
-	zend_string *_out = (out); \
-	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH((in1), (in2)); \
-	GC_ADD_FLAGS(_out, properties); \
-} while (0)
+static inline void ZSTR_COPY_CONCAT_PROPERTIES(zend_string *out, const zend_string *in) {
+	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(in);
+	GC_ADD_FLAGS(out, properties);
+}
+
+static inline void ZSTR_COPY_CONCAT_PROPERTIES_BOTH(zend_string *out, const zend_string *in1, const zend_string *in2) {
+	uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(in1, in2);
+	GC_ADD_FLAGS(out, properties);
+}
+
+static zend_always_inline zend_string *ZSTR_EMPTY_ALLOC(void) {
+	return zend_empty_string;
+}
+
+static zend_always_inline zend_string *ZSTR_CHAR(unsigned char c) {
+	return zend_one_char_string[c];
+}
 
-#define ZSTR_EMPTY_ALLOC() zend_empty_string
-#define ZSTR_CHAR(c) zend_one_char_string[c]
-#define ZSTR_KNOWN(idx) zend_known_strings[idx]
+static zend_always_inline zend_string *ZSTR_KNOWN(size_t idx) {
+	return zend_known_strings[idx];
+}
 
-#define _ZSTR_HEADER_SIZE XtOffsetOf(zend_string, val)
+#define _ZSTR_HEADER_SIZE offsetof(zend_string, val)
 
 #define _ZSTR_STRUCT_SIZE(len) (_ZSTR_HEADER_SIZE + len + 1)
 
@@ -132,7 +138,7 @@ END_EXTERN_C()
 
 #define ZSTR_ALLOCA_FREE(str, use_heap) free_alloca(str, use_heap)
 
-#define ZSTR_INIT_LITERAL(s, persistent) (zend_string_init((s), strlen(s), (persistent)))
+#define ZSTR_INIT_LITERAL(s, persistent) (zend_string_init(("" s), sizeof(s) - 1, (persistent)))
 
 /*---*/
 
@@ -411,7 +417,7 @@ static zend_always_inline bool zend_string_starts_with(const zend_string *str, c
 }
 
 #define zend_string_starts_with_literal(str, prefix) \
-	zend_string_starts_with_cstr(str, prefix, strlen(prefix))
+	zend_string_starts_with_cstr(str, "" prefix, sizeof(prefix) - 1)
 
 static zend_always_inline bool zend_string_starts_with_cstr_ci(const zend_string *str, const char *prefix, size_t prefix_length)
 {
@@ -424,7 +430,7 @@ static zend_always_inline bool zend_string_starts_with_ci(const zend_string *str
 }
 
 #define zend_string_starts_with_literal_ci(str, prefix) \
-	zend_string_starts_with_cstr_ci(str, prefix, strlen(prefix))
+	zend_string_starts_with_cstr_ci(str, "" prefix, sizeof(prefix) - 1)
 
 /*
  * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
@@ -546,7 +552,7 @@ static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size
 		case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
 		case 1: hash = ((hash << 5) + hash) + *str++; break;
 		case 0: break;
-EMPTY_SWITCH_DEFAULT_CASE()
+default: ZEND_UNREACHABLE();
 	}
 #endif
 
@@ -572,9 +578,11 @@ EMPTY_SWITCH_DEFAULT_CASE()
 	_(ZEND_STR_OBJECT_OPERATOR,        "->") \
 	_(ZEND_STR_PAAMAYIM_NEKUDOTAYIM,   "::") \
 	_(ZEND_STR_ARGS,                   "args") \
+	_(ZEND_STR_ARGUMENTS,              "arguments") \
 	_(ZEND_STR_UNKNOWN,                "unknown") \
 	_(ZEND_STR_UNKNOWN_CAPITALIZED,    "Unknown") \
 	_(ZEND_STR_EXIT,                   "exit") \
+	_(ZEND_STR_CLONE,                  "clone") \
 	_(ZEND_STR_EVAL,                   "eval") \
 	_(ZEND_STR_INCLUDE,                "include") \
 	_(ZEND_STR_REQUIRE,                "require") \
@@ -644,6 +652,12 @@ EMPTY_SWITCH_DEFAULT_CASE()
 	_(ZEND_STR_SINCE,                  "since") \
 	_(ZEND_STR_GET,                    "get") \
 	_(ZEND_STR_SET,                    "set") \
+	_(ZEND_STR_8_DOT_0,                "8.0") \
+	_(ZEND_STR_8_DOT_1,                "8.1") \
+	_(ZEND_STR_8_DOT_2,                "8.2") \
+	_(ZEND_STR_8_DOT_3,                "8.3") \
+	_(ZEND_STR_8_DOT_4,                "8.4") \
+	_(ZEND_STR_8_DOT_5,                "8.5") \
 
 
 typedef enum _zend_known_string_id {
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
index 88b905ffeab4..f0a15a2f4f47 100644
--- a/Zend/zend_strtod.c
+++ b/Zend/zend_strtod.c
@@ -4535,10 +4535,10 @@ ZEND_API char *zend_gcvt(double value, int ndigit, char dec_point, char exponent
 	if ((decpt >= 0 && decpt > ndigit) || decpt < -3) { /* use E-style */
 		/* exponential format (e.g. 1.2345e+13) */
 		if (--decpt < 0) {
-			sign = 1;
+			sign = true;
 			decpt = -decpt;
 		} else {
-			sign = 0;
+			sign = false;
 		}
 		src = digits;
 		*dst++ = *src++;
diff --git a/Zend/zend_strtod.h b/Zend/zend_strtod.h
index 4e0d85a7d216..fa557ed2a0c3 100644
--- a/Zend/zend_strtod.h
+++ b/Zend/zend_strtod.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Derick Rethans                              |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_strtod_int.h b/Zend/zend_strtod_int.h
index 06a02618e9e6..4de5c225ccd8 100644
--- a/Zend/zend_strtod_int.h
+++ b/Zend/zend_strtod_int.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Anatol Belski                                   |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_system_id.c b/Zend/zend_system_id.c
index 2c3ebab0f480..ead694375b6d 100644
--- a/Zend/zend_system_id.c
+++ b/Zend/zend_system_id.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Sammy Kaye Powers                           |
    |          Dmitry Stogov                               |
diff --git a/Zend/zend_system_id.h b/Zend/zend_system_id.h
index b6785f8d7b67..ae39381a52a3 100644
--- a/Zend/zend_system_id.h
+++ b/Zend/zend_system_id.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Author: Sammy Kaye Powers                            |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_type_info.h b/Zend/zend_type_info.h
index eeab7bf0431d..1e0045558383 100644
--- a/Zend/zend_type_info.h
+++ b/Zend/zend_type_info.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 4a6d00b9d73e..85a5857d20c2 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -55,26 +54,13 @@
 
 typedef unsigned char zend_uchar;
 
-typedef enum {
+typedef enum zend_result {
   SUCCESS =  0,
   FAILURE = -1,		/* this MUST stay a negative number, or it may affect functions! */
-} ZEND_RESULT_CODE;
+} zend_result;
 
-typedef ZEND_RESULT_CODE zend_result;
-
-#ifdef ZEND_ENABLE_ZVAL_LONG64
-# ifdef ZEND_WIN32
-#  define ZEND_SIZE_MAX  _UI64_MAX
-# else
-#  define ZEND_SIZE_MAX  SIZE_MAX
-# endif
-#else
-# if defined(ZEND_WIN32)
-#  define ZEND_SIZE_MAX  _UI32_MAX
-# else
-#  define ZEND_SIZE_MAX SIZE_MAX
-# endif
-#endif
+/* This constant is deprecated, use SIZE_MAX instead */
+#define ZEND_SIZE_MAX SIZE_MAX
 
 #ifdef ZTS
 #define ZEND_TLS static TSRM_TLS
@@ -141,14 +127,42 @@ typedef struct {
 	zend_type types[1];
 } zend_type_list;
 
-#define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 25
-#define _ZEND_TYPE_MASK ((1u << 25) - 1)
+/* Generic type-parameter reference. */
+typedef struct _zend_type_parameter_ref {
+	zend_string *name;       /* type-parameter source name (e.g. "T") */
+	uint32_t     index;      /* position in declaring entity's parameter list */
+	uint8_t      origin;     /* one of zend_generic_origin (see zend_compile.h) */
+} zend_type_parameter_ref;
+
+/* List of pre-erasure type arguments attached to a named pre-erasure zend_type. */
+typedef struct _zend_type_arguments {
+	uint32_t count;
+	zend_type arguments[1];
+} zend_type_arguments;
+
+/* Pre-erasure named type with type arguments. */
+typedef struct _zend_type_named_with_args {
+	zend_string *name;       /* class name */
+	uint32_t     name_attr;  /* ZEND_NAME_NOT_FQ / ZEND_NAME_FQ / ZEND_NAME_RELATIVE */
+	uint32_t     count;      /* number of type arguments */
+	zend_type    args[1];    /* flexible array of pre-erasure type arguments */
+} zend_type_named_with_args;
+
+#define ZEND_TYPE_NAMED_WITH_ARGS_SIZE(count) \
+	(sizeof(zend_type_named_with_args) + ((count) - 1) * sizeof(zend_type))
+
+#define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 26
+#define _ZEND_TYPE_MASK (((1u << 26) - 1) | _ZEND_TYPE_NAMED_WITH_ARGS_BIT)
+/* Pre-erasure named type with type arguments. Side-table only. */
+#define _ZEND_TYPE_NAMED_WITH_ARGS_BIT (1u << 31)
+/* Generic type-parameter reference. */
+#define _ZEND_TYPE_TYPE_PARAMETER_BIT (1u << 25)
 /* Only one of these bits may be set. */
 #define _ZEND_TYPE_NAME_BIT (1u << 24)
 // Used to signify that type.ptr is not a `zend_string*` but a `const char*`,
 #define _ZEND_TYPE_LITERAL_NAME_BIT (1u << 23)
 #define _ZEND_TYPE_LIST_BIT (1u << 22)
-#define _ZEND_TYPE_KIND_MASK (_ZEND_TYPE_LIST_BIT|_ZEND_TYPE_NAME_BIT|_ZEND_TYPE_LITERAL_NAME_BIT)
+#define _ZEND_TYPE_KIND_MASK (_ZEND_TYPE_LIST_BIT|_ZEND_TYPE_NAME_BIT|_ZEND_TYPE_LITERAL_NAME_BIT|_ZEND_TYPE_TYPE_PARAMETER_BIT|_ZEND_TYPE_NAMED_WITH_ARGS_BIT)
 /* For BC behaviour with iterable type */
 #define _ZEND_TYPE_ITERABLE_BIT (1u << 21)
 /* Whether the type list is arena allocated */
@@ -179,6 +193,18 @@ typedef struct {
 #define ZEND_TYPE_HAS_LIST(t) \
 	((((t).type_mask) & _ZEND_TYPE_LIST_BIT) != 0)
 
+#define ZEND_TYPE_HAS_TYPE_PARAMETER(t) \
+	((((t).type_mask) & _ZEND_TYPE_TYPE_PARAMETER_BIT) != 0)
+
+#define ZEND_TYPE_TYPE_PARAMETER(t) \
+	((zend_type_parameter_ref *) (t).ptr)
+
+#define ZEND_TYPE_HAS_NAMED_WITH_ARGS(t) \
+	((((t).type_mask) & _ZEND_TYPE_NAMED_WITH_ARGS_BIT) != 0)
+
+#define ZEND_TYPE_NAMED_WITH_ARGS(t) \
+	((zend_type_named_with_args *) (t).ptr)
+
 #define ZEND_TYPE_IS_ITERABLE_FALLBACK(t) \
 	((((t).type_mask) & _ZEND_TYPE_ITERABLE_BIT) != 0)
 
@@ -649,6 +675,9 @@ struct _zend_ast_ref {
 #define _IS_BOOL					18
 #define _IS_NUMBER					19
 
+/* used for PFAs/FCCs */
+#define _IS_PLACEHOLDER             20
+
 /* guard flags */
 #define ZEND_GUARD_PROPERTY_GET		(1<<0)
 #define ZEND_GUARD_PROPERTY_SET		(1<<1)
@@ -753,6 +782,18 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) {
 		} \
 	} while (0)
 
+#define GC_TRY_DTOR_NO_REF(p) \
+	do { \
+		zend_refcounted_h *_p = &(p)->gc; \
+		if (!(_p->u.type_info & GC_IMMUTABLE)) { \
+			if (zend_gc_delref(_p) == 0) { \
+				rc_dtor_func((zend_refcounted *)_p); \
+			} else { \
+				gc_check_possible_root_no_ref((zend_refcounted *)_p); \
+			} \
+		} \
+	} while (0)
+
 #define GC_TYPE_MASK				0x0000000f
 #define GC_FLAGS_MASK				0x000003f0
 #define GC_INFO_MASK				0xfffffc00
@@ -943,16 +984,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
 #define Z_COLLECTABLE(zval)			((Z_TYPE_FLAGS(zval) & IS_TYPE_COLLECTABLE) != 0)
 #define Z_COLLECTABLE_P(zval_p)		Z_COLLECTABLE(*(zval_p))
 
-/* deprecated: (COPYABLE is the same as IS_ARRAY) */
-#define Z_COPYABLE(zval)			(Z_TYPE(zval) == IS_ARRAY)
-#define Z_COPYABLE_P(zval_p)		Z_COPYABLE(*(zval_p))
-
-/* deprecated: (IMMUTABLE is the same as IS_ARRAY && !REFCOUNTED) */
-#define Z_IMMUTABLE(zval)			(Z_TYPE_INFO(zval) == IS_ARRAY)
-#define Z_IMMUTABLE_P(zval_p)		Z_IMMUTABLE(*(zval_p))
-#define Z_OPT_IMMUTABLE(zval)		Z_IMMUTABLE(zval_p)
-#define Z_OPT_IMMUTABLE_P(zval_p)	Z_IMMUTABLE(*(zval_p))
-
 /* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */
 #define Z_OPT_TYPE(zval)			(Z_TYPE_INFO(zval) & Z_TYPE_MASK)
 #define Z_OPT_TYPE_P(zval_p)		Z_OPT_TYPE(*(zval_p))
@@ -966,10 +997,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
 #define Z_OPT_COLLECTABLE(zval)		((Z_TYPE_INFO(zval) & (IS_TYPE_COLLECTABLE << Z_TYPE_FLAGS_SHIFT)) != 0)
 #define Z_OPT_COLLECTABLE_P(zval_p)	Z_OPT_COLLECTABLE(*(zval_p))
 
-/* deprecated: (COPYABLE is the same as IS_ARRAY) */
-#define Z_OPT_COPYABLE(zval)		(Z_OPT_TYPE(zval) == IS_ARRAY)
-#define Z_OPT_COPYABLE_P(zval_p)	Z_OPT_COPYABLE(*(zval_p))
-
 #define Z_OPT_ISREF(zval)			(Z_OPT_TYPE(zval) == IS_REFERENCE)
 #define Z_OPT_ISREF_P(zval_p)		Z_OPT_ISREF(*(zval_p))
 
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c
index 00f10b08f80a..02c286ac486a 100644
--- a/Zend/zend_variables.c
+++ b/Zend/zend_variables.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h
index 1cb745ca1b1d..9c6040a75bcb 100644
--- a/Zend/zend_variables.h
+++ b/Zend/zend_variables.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -81,9 +80,6 @@ ZEND_API void zval_ptr_dtor(zval *zval_ptr);
 ZEND_API void zval_ptr_safe_dtor(zval *zval_ptr);
 ZEND_API void zval_internal_ptr_dtor(zval *zvalue);
 
-/* Kept for compatibility */
-#define zval_dtor(zvalue) zval_ptr_dtor_nogc(zvalue)
-
 ZEND_API void zval_add_ref(zval *p);
 
 END_EXTERN_C()
diff --git a/Zend/zend_verify_type_inference.h b/Zend/zend_verify_type_inference.h
index 0add01933495..807bf21e3910 100644
--- a/Zend/zend_verify_type_inference.h
+++ b/Zend/zend_verify_type_inference.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
 */
 
@@ -156,7 +155,7 @@ static void zend_verify_inference_def(zend_execute_data *execute_data, const zen
 	}
 	if (opline->op1_def_type
 	 && (opline->op1_type & (IS_TMP_VAR|IS_VAR|IS_CV))
-	 // array is actually changed by the the following instruction(s)
+	 // array is actually changed by the following instruction(s)
 	 && opline->opcode != ZEND_FETCH_DIM_W
 	 && opline->opcode != ZEND_FETCH_DIM_RW
 	 && opline->opcode != ZEND_FETCH_DIM_FUNC_ARG
diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c
index 366e13ce9b6b..da27e9fd5426 100644
--- a/Zend/zend_virtual_cwd.c
+++ b/Zend/zend_virtual_cwd.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Sascha Schumann                         |
@@ -195,7 +193,7 @@ void virtual_cwd_main_cwd_init(uint8_t reinit) /* {{{ */
 	main_cwd_state.cwd_length = strlen(cwd);
 #ifdef ZEND_WIN32
 	if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') {
-		cwd[0] = toupper(cwd[0]);
+		cwd[0] = toupper((unsigned char)cwd[0]);
 	}
 #endif
 	main_cwd_state.cwd = strdup(cwd);
@@ -271,7 +269,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length) /* {{{ */
 		*length = state->cwd_length+1;
 		retval = (char *) emalloc(*length+1);
 		memcpy(retval, state->cwd, *length);
-		retval[0] = toupper(retval[0]);
+		retval[0] = toupper((unsigned char)retval[0]);
 		retval[*length-1] = DEFAULT_SLASH;
 		retval[*length] = '\0';
 		return retval;
@@ -524,18 +522,18 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
 			(i + 1 == len && path[i] == '.')) {
 			/* remove double slashes and '.' */
 			len = EXPECTED(i > 0) ? i - 1 : 0;
-			is_dir = 1;
+			is_dir = true;
 			continue;
 		} else if (i + 2 == len && path[i] == '.' && path[i+1] == '.') {
 			/* remove '..' and previous directory */
-			is_dir = 1;
+			is_dir = true;
 			if (link_is_dir) {
 				*link_is_dir = 1;
 			}
 			if (i <= start + 1) {
 				return start ? start : len;
 			}
-			j = tsrm_realpath_r(path, start, i-1, ll, t, use_realpath, 1, NULL);
+			j = tsrm_realpath_r(path, start, i-1, ll, t, use_realpath, true, NULL);
 			if (j > start && j != (size_t)-1) {
 				j--;
 				assert(i < MAXPATHLEN);
@@ -948,7 +946,8 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
 				j = start;
 			} else {
 				/* some leading directories may be inaccessible */
-				j = tsrm_realpath_r(path, start, i-1, ll, t, save ? CWD_FILEPATH : use_realpath, 1, NULL);
+				j = tsrm_realpath_r(path, start, i-1, ll, t, save ? CWD_FILEPATH : use_realpath, true,
+						    NULL);
 				if (j > start && j != (size_t)-1) {
 					path[j++] = DEFAULT_SLASH;
 				}
@@ -1113,7 +1112,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
 			if (resolved_path[start] == 0) {
 				goto verify;
 			}
-			resolved_path[start] = toupper(resolved_path[start]);
+			resolved_path[start] = toupper((unsigned char)resolved_path[start]);
 			start++;
 		}
 		resolved_path[start++] = DEFAULT_SLASH;
@@ -1121,13 +1120,13 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
 			if (resolved_path[start] == 0) {
 				goto verify;
 			}
-			resolved_path[start] = toupper(resolved_path[start]);
+			resolved_path[start] = toupper((unsigned char)resolved_path[start]);
 			start++;
 		}
 		resolved_path[start++] = DEFAULT_SLASH;
 	} else if (IS_ABSOLUTE_PATH(resolved_path, path_length)) {
 		/* skip DRIVE name */
-		resolved_path[0] = toupper(resolved_path[0]);
+		resolved_path[0] = toupper((unsigned char)resolved_path[0]);
 		resolved_path[2] = DEFAULT_SLASH;
 		if (path_length == 2) {
 			resolved_path[3] = '\0';
@@ -1138,7 +1137,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
 
 	add_slash = (use_realpath != CWD_REALPATH) && path_length > 0 && IS_SLASH(resolved_path[path_length-1]);
 	t = CWDG(realpath_cache_ttl) ? 0 : -1;
-	path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL);
+	path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, false, NULL);
 
 	if (path_length == (size_t)-1) {
 #ifdef ZEND_WIN32
@@ -1417,7 +1416,7 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li
 	int ret;
 
 	CWD_STATE_COPY(&new_state, &CWDG(cwd));
-	if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH)) {
+	if (virtual_file_ex(&new_state, filename, NULL, link ? CWD_EXPAND : CWD_REALPATH)) {
 		CWD_STATE_FREE_ERR(&new_state);
 		return -1;
 	}
diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h
index 21735f6dfae5..ad30c0323892 100644
--- a/Zend/zend_virtual_cwd.h
+++ b/Zend/zend_virtual_cwd.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | https://www.php.net/license/3_01.txt                                 |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Sascha Schumann                         |
@@ -87,7 +85,7 @@ typedef unsigned short mode_t;
 #define IS_UNC_PATH(path, len) \
 	(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
 #define IS_ABSOLUTE_PATH(path, len) \
-	(len >= 2 && (/* is local */isalpha(path[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))
+	(len >= 2 && (/* is local */isalpha((unsigned char)(path)[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))
 
 #else
 #ifdef HAVE_DIRENT_H
diff --git a/Zend/zend_vm.h b/Zend/zend_vm.h
index c9c41c75c72a..4f4a48c92205 100644
--- a/Zend/zend_vm.h
+++ b/Zend/zend_vm.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -32,6 +31,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op);
 ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op);
 ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *op);
 ZEND_API const zend_op *zend_get_halt_op(void);
+ZEND_API const zend_op *zend_get_interrupt_op(void);
 ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data *ex);
 ZEND_API int zend_vm_kind(void);
 ZEND_API bool zend_gcc_global_regs(void);
@@ -39,6 +39,10 @@ ZEND_API bool zend_gcc_global_regs(void);
 void zend_vm_init(void);
 void zend_vm_dtor(void);
 
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+const struct _zend_op *ZEND_FASTCALL zend_vm_handle_interrupt(struct _zend_execute_data *execute_data, const struct _zend_op *opline);
+#endif
+
 END_EXTERN_C()
 
 #define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 617e114dd05d..1a3a5e317231 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -203,7 +202,7 @@ ZEND_VM_C_LABEL(mul_double):
 	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper, op_1, op1, op_2, op2);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(4, ZEND_DIV, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_COLD_CONSTCONST_HANDLER(4, ZEND_DIV, CONST|TMP|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -357,7 +356,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(7, ZEND_SR, CONST|TMPVARCV, CONST|TMPVARCV)
 	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper, op_1, op1, op_2, op2);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMP|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -371,7 +370,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_CONST))
+ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMP|CV, CONST|TMP|CV, SPEC(NO_CONST_CONST))
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -448,7 +447,7 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_
 	}
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
+ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(COMMUTATIVE))
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -463,7 +462,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|T
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-ZEND_VM_HANDLER(196, ZEND_CASE_STRICT, TMP|VAR, CONST|TMP|VAR|CV)
+ZEND_VM_HANDLER(196, ZEND_CASE_STRICT, TMP, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -477,7 +476,7 @@ ZEND_VM_HANDLER(196, ZEND_CASE_STRICT, TMP|VAR, CONST|TMP|VAR|CV)
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
+ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(COMMUTATIVE))
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -514,7 +513,7 @@ ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
 	ZEND_VM_SMART_BRANCH(ret == 0, 1);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(18, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
+ZEND_VM_COLD_CONSTCONST_HANDLER(18, ZEND_IS_EQUAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -594,7 +593,7 @@ ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
 	ZEND_VM_SMART_BRANCH(ret != 0, 1);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(19, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
+ZEND_VM_COLD_CONSTCONST_HANDLER(19, ZEND_IS_NOT_EQUAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -786,7 +785,7 @@ ZEND_VM_C_LABEL(is_smaller_or_equal_double):
 	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper, op_1, op1, op_2, op2);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_COLD_CONSTCONST_HANDLER(170, ZEND_SPACESHIP, CONST|TMP|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -917,7 +916,7 @@ ZEND_VM_HOT_NOCONSTCONST_HANDLER(11, ZEND_BW_XOR, CONST|TMPVARCV, CONST|TMPVARCV
 	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper, op_1, op1, op_2, op2);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(15, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE))
+ZEND_VM_COLD_CONSTCONST_HANDLER(15, ZEND_BOOL_XOR, CONST|TMP|CV, CONST|TMP|CV, SPEC(COMMUTATIVE))
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -958,7 +957,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(13, ZEND_BW_NOT, CONST|TMPVARCV, ANY)
 	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper, op_1, op1);
 }
 
-ZEND_VM_COLD_CONST_HANDLER(14, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
+ZEND_VM_COLD_CONST_HANDLER(14, ZEND_BOOL_NOT, CONST|TMP|CV, ANY)
 {
 	USE_OPLINE
 	zval *val;
@@ -1005,7 +1004,7 @@ ZEND_VM_COLD_HELPER(zend_undefined_function_helper, ANY, ANY)
 	HANDLE_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, OP)
+ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMP|CV, OP)
 {
 	USE_OPLINE
 	zval *object;
@@ -1070,7 +1069,7 @@ ZEND_VM_C_LABEL(assign_op_object):
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -1097,7 +1096,7 @@ ZEND_VM_C_LABEL(assign_op_object):
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
 ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP)
 {
 	/* This helper actually never will receive IS_VAR as second op, and has the same handling for VAR and TMP in the first op, but for interoperability with the other binary_assign_op helpers, it is necessary to "include" it */
@@ -1153,7 +1152,7 @@ ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP)
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP)
+ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMP|UNUSED|NEXT|CV, OP)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -1254,7 +1253,7 @@ ZEND_VM_C_LABEL(assign_dim_op_ret_null):
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP)
+ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMP|CV, OP)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -1285,7 +1284,7 @@ ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *object;
@@ -1335,7 +1334,8 @@ ZEND_VM_C_LABEL(pre_incdec_object):
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -1350,12 +1350,12 @@ ZEND_VM_C_LABEL(pre_incdec_object):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_OBJ);
 }
 
-ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *object;
@@ -1403,7 +1403,8 @@ ZEND_VM_C_LABEL(post_incdec_object):
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -1418,12 +1419,12 @@ ZEND_VM_C_LABEL(post_incdec_object):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_OBJ);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
 ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 {
 	USE_OPLINE
@@ -1451,13 +1452,13 @@ ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
 ZEND_VM_HANDLER(39, ZEND_PRE_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_STATIC_PROP);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
 ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 {
 	USE_OPLINE
@@ -1485,7 +1486,7 @@ ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
 ZEND_VM_HANDLER(41, ZEND_POST_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_STATIC_PROP);
@@ -1690,7 +1691,7 @@ ZEND_VM_HOT_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
 	ZEND_VM_DISPATCH_TO_HELPER(zend_post_dec_helper);
 }
 
-ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
+ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMP|CV, ANY)
 {
 	USE_OPLINE
 	zval *z;
@@ -1719,7 +1720,7 @@ ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
+ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMP|CV, UNUSED, int type)
 {
 	USE_OPLINE
 	zval *varname;
@@ -1820,22 +1821,22 @@ ZEND_VM_C_LABEL(fetch_this):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
+ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMP|CV, UNUSED, VAR_FETCH)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
 }
 
-ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
+ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMP|CV, UNUSED, VAR_FETCH)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
 }
 
-ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
+ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMP|CV, UNUSED, VAR_FETCH)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW);
 }
 
-ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
+ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|CV, UNUSED, VAR_FETCH)
 {
 	int fetch_type =
 		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
@@ -1843,17 +1844,17 @@ ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, fetch_type);
 }
 
-ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
+ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|CV, UNUSED, VAR_FETCH)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
 }
 
-ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
+ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|CV, UNUSED, VAR_FETCH)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
 ZEND_VM_INLINE_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)
 {
 	USE_OPLINE
@@ -1866,7 +1867,7 @@ ZEND_VM_INLINE_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)
 		&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
 		type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
 	if (UNEXPECTED(!prop)) {
-		ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
+		ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS) || (type == BP_VAR_UNSET));
 		prop = &EG(uninitialized_zval);
 	} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
 	 && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
@@ -1888,25 +1889,25 @@ ZEND_VM_C_LABEL(copy_deref):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, ANY, CLASS_FETCH, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, ANY, CLASS_FETCH, FETCH_REF|DIM_WRITE|CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, ANY, CLASS_FETCH, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, ANY, CLASS_FETCH, FETCH_REF|CACHE_SLOT)
 {
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
@@ -1916,32 +1917,36 @@ ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, ANY, CLASS_FETCH, FETCH_RE
 	}
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, ANY, CLASS_FETCH, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, ANY, CLASS_FETCH, CACHE_SLOT)
 {
 	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_COLD_CONSTCONST_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
 	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+	if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 	dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
 	if (OP1_TYPE != IS_CONST) {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 ZEND_VM_C_LABEL(fetch_dim_r_array):
 			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, OP2_TYPE, BP_VAR_R EXECUTE_DATA_CC);
 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		} else if (OP1_TYPE == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
 			container = Z_REFVAL_P(container);
 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 				ZEND_VM_C_GOTO(fetch_dim_r_array);
@@ -1963,7 +1968,7 @@ ZEND_VM_C_LABEL(fetch_dim_r_slow):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
+ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|UNUSED|NEXT|CV)
 {
 	USE_OPLINE
 	zval *container;
@@ -1978,7 +1983,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
+ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|UNUSED|NEXT|CV)
 {
 	USE_OPLINE
 	zval *container;
@@ -1993,13 +1998,15 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_COLD_CONSTCONST_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_IS);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
 	zend_fetch_dimension_address_read_IS(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
 	FREE_OP2();
 	FREE_OP1();
@@ -2030,7 +2037,7 @@ ZEND_VM_COLD_HELPER(zend_use_undef_in_read_context_helper, ANY, ANY)
 	HANDLE_EXCEPTION();
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
+ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|UNUSED|NEXT|CV)
 {
 #if !ZEND_VM_SPEC
 	USE_OPLINE
@@ -2045,11 +2052,17 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, C
 		if (OP2_TYPE == IS_UNUSED) {
 			ZEND_VM_DISPATCH_TO_HELPER(zend_use_undef_in_read_context_helper);
 		}
+		if (OP1_TYPE & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_R);
 	}
 }
 
-ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *container;
@@ -2064,7 +2077,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *container;
@@ -2072,11 +2085,15 @@ ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST
 
 	SAVE_OPLINE();
 	container = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
+	if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (OP1_TYPE == IS_CONST ||
 	    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((OP1_TYPE & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -2233,7 +2250,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_finish):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|DIM_WRITE|CACHE_SLOT)
+ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMP|CV, FETCH_REF|DIM_WRITE|CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -2254,7 +2271,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -2271,7 +2288,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACH
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *container;
@@ -2279,6 +2296,8 @@ ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, C
 
 	SAVE_OPLINE();
 	container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (OP1_TYPE == IS_CONST ||
 	    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -2392,7 +2411,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_finish):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|CACHE_SLOT)
+ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMP|CV, FETCH_REF|CACHE_SLOT)
 {
 #if !ZEND_VM_SPEC
 	USE_OPLINE
@@ -2405,11 +2424,17 @@ ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THI
 		}
 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_W);
 	} else {
+		if (OP1_TYPE == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
 		ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R);
 	}
 }
 
-ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
@@ -2426,7 +2451,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMPVAR|CV)
+ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *container;
@@ -2438,7 +2463,7 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMPVAR|CV)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
+ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *container, *dim;
@@ -2461,7 +2486,7 @@ ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
+ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|CV))
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -2614,8 +2639,8 @@ ZEND_VM_C_LABEL(exit_assign_obj):
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|CV))
 {
 	USE_OPLINE
 	zval *prop, *value;
@@ -2652,7 +2677,7 @@ ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-ZEND_VM_HANDLER(23, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV))
+ZEND_VM_HANDLER(23, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|CV))
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -2805,7 +2830,7 @@ ZEND_VM_C_LABEL(assign_dim_error):
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
+ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|CV, SPEC(RETVAL))
 {
 	USE_OPLINE
 	zval *value;
@@ -2873,7 +2898,7 @@ ZEND_VM_HANDLER(30, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT|SRC, SPEC(OP_DATA=VAR|CV))
+ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT|SRC, SPEC(OP_DATA=VAR|CV))
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -2909,7 +2934,7 @@ ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CA
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
 ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
 {
 	USE_OPLINE
@@ -2962,7 +2987,10 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
 {
 	zend_execute_data *old_execute_data;
 	uint32_t call_info = EX_CALL_INFO();
+#if ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL
+	/* zend_leave_helper may be called with opline=call_leave_op in TAILCALL VM */
 	SAVE_OPLINE();
+#endif
 
 	if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) == 0)) {
 		EG(current_execute_data) = EX(prev_execute_data);
@@ -3104,7 +3132,7 @@ ZEND_VM_HOT_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY)
 	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
 }
 
-ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
+ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *val;
@@ -3138,7 +3166,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
 	ZEND_VM_JMP(opline);
 }
 
-ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
+ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *val;
@@ -3172,7 +3200,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
 	ZEND_VM_JMP(opline);
 }
 
-ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
+ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *val;
@@ -3208,7 +3236,7 @@ ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
 	ZEND_VM_JMP(opline);
 }
 
-ZEND_VM_COLD_CONST_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
+ZEND_VM_COLD_CONST_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *val;
@@ -3243,7 +3271,7 @@ ZEND_VM_COLD_CONST_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
 	ZEND_VM_JMP(opline);
 }
 
-ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, ANY)
+ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, LOOP_END)
 {
 	USE_OPLINE
 
@@ -3252,7 +3280,7 @@ ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, ANY)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HOT_HANDLER(127, ZEND_FE_FREE, TMPVAR, ANY)
+ZEND_VM_HOT_HANDLER(127, ZEND_FE_FREE, TMPVAR, LOOP_END)
 {
 	zval *var;
 	USE_OPLINE
@@ -3277,7 +3305,7 @@ ZEND_VM_HOT_HANDLER(127, ZEND_FE_FREE, TMPVAR, ANY)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMP|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -3402,7 +3430,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM)
+ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMP|CV, NUM)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -3437,7 +3465,7 @@ ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM)
+ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMP|CV, NUM)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -3472,7 +3500,7 @@ ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
+ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMP|CV, NUM)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -3532,7 +3560,7 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMPVAR|UNUSED|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMP|UNUSED|CV, CACHE_SLOT)
 {
 	zval *class_name;
 	USE_OPLINE
@@ -3575,7 +3603,7 @@ ZEND_VM_C_LABEL(try_class_name):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM|CACHE_SLOT)
+ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMP|UNUSED|THIS|CV, CONST|TMP|CV, NUM|CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -3730,7 +3758,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM|CACHE_SLOT)
+ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMP|UNUSED|CONSTRUCTOR|CV, NUM|CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -3875,7 +3903,17 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
 		function_name = (zval*)RT_CONSTANT(opline, opline->op2);
 		func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(function_name+1));
 		if (UNEXPECTED(func == NULL)) {
-			ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper);
+			/* Mangled monomorph name: synthesize on first reference (may throw). */
+			SAVE_OPLINE();
+			fbc = zend_resolve_monomorph_by_name(Z_STR_P(function_name+1));
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+			if (UNEXPECTED(fbc == NULL)) {
+				ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper);
+			}
+			CACHE_PTR(opline->result.num, fbc);
+			goto ZEND_VM_C_LABEL(fcall_by_name_push);
 		}
 		fbc = Z_FUNC_P(func);
 		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
@@ -3883,6 +3921,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
 		}
 		CACHE_PTR(opline->result.num, fbc);
 	}
+ZEND_VM_C_LABEL(fcall_by_name_push):
 	call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
 		fbc, opline->extended_value, NULL);
 	call->prev_execute_data = EX(call);
@@ -3891,7 +3930,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV, NUM)
+ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMP|CV, NUM)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -3944,7 +3983,7 @@ ZEND_VM_C_LABEL(try_function_name):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM)
+ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMP|CV, NUM)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -4031,7 +4070,21 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
 		if (func == NULL) {
 			func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 2));
 			if (UNEXPECTED(func == NULL)) {
-				ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper);
+				/* Mangled monomorph name: synthesize on first reference (qualified
+				 * then unqualified; may throw). */
+				SAVE_OPLINE();
+				fbc = zend_resolve_monomorph_by_name(Z_STR_P(func_name + 1));
+				if (fbc == NULL && !EG(exception)) {
+					fbc = zend_resolve_monomorph_by_name(Z_STR_P(func_name + 2));
+				}
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+				if (UNEXPECTED(fbc == NULL)) {
+					ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper);
+				}
+				CACHE_PTR(opline->result.num, fbc);
+				goto ZEND_VM_C_LABEL(ns_fcall_by_name_push);
 			}
 		}
 		fbc = Z_FUNC_P(func);
@@ -4041,6 +4094,7 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
 		CACHE_PTR(opline->result.num, fbc);
 	}
 
+ZEND_VM_C_LABEL(ns_fcall_by_name_push):
 	call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
 		fbc, opline->extended_value, NULL);
 	call->prev_execute_data = EX(call);
@@ -4125,11 +4179,15 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 	ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
@@ -4254,12 +4312,17 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 		ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
@@ -4336,6 +4399,33 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
 			ret = EX_VAR(opline->result.var);
 		}
 
+		/* Closures created inside a generic frame carry that frame's T-table
+		 * via zend_vm_init_call_frame. Run the T-ref value-arg check against
+		 * the captured bindings now, before i_init_func_execute_data relocates
+		 * variadic args past the CV slots (which would leave the original arg
+		 * positions UNDEF and silently make every check pass). The cleanup on
+		 * failure matches ZEND_VERIFY_GENERIC_ARGUMENTS — at this point
+		 * call->prev_execute_data is still its zend_vm_init_call_frame value
+		 * (typically NULL), so EX(call) is the right slot to clear. */
+		if (UNEXPECTED(call->type_args
+				&& (fbc->common.fn_flags & ZEND_ACC_CLOSURE))) {
+			SAVE_OPLINE();
+			zend_verify_generic_arg_types(call, NULL);
+			if (UNEXPECTED(EG(exception))) {
+				zend_vm_stack_free_args(call);
+				if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+					OBJ_RELEASE(Z_OBJ(call->This));
+				}
+				EX(call) = call->prev_execute_data;
+				zend_vm_stack_free_call_frame(call);
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		call->prev_execute_data = execute_data;
 		execute_data = call;
 		i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
@@ -4382,12 +4472,17 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 		ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
@@ -4449,6 +4544,18 @@ ZEND_VM_COLD_CONST_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV
 			ZVAL_DEREF(retval_ptr);
 		}
 
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
@@ -4497,7 +4604,7 @@ ZEND_VM_COLD_HANDLER(201, ZEND_VERIFY_NEVER_TYPE, UNUSED, UNUSED)
 	HANDLE_EXCEPTION();
 }
 
-ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER))
+ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|CV, ANY, SPEC(OBSERVER))
 {
 	USE_OPLINE
 	zval *retval_ptr;
@@ -4638,6 +4745,9 @@ ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC,
 
 	ZEND_OBSERVER_FCALL_END(execute_data, return_value);
 	ZEND_OBSERVER_FREE_RETVAL();
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
 	ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
 }
 
@@ -4766,7 +4876,7 @@ ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER
 	ZEND_VM_RETURN();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMPVAR|CV, ANY)
+ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMP|CV, ANY)
 {
 	USE_OPLINE
 	zval *value;
@@ -4794,15 +4904,13 @@ ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMPVAR|CV, ANY)
 		}
 	} while (0);
 
-	zend_exception_save();
 	Z_TRY_ADDREF_P(value);
 	zend_throw_exception_object(value);
-	zend_exception_restore();
 	FREE_OP1();
 	HANDLE_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
+ZEND_VM_HANDLER(107, ZEND_CATCH, CONST|UNUSED, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
 {
 	USE_OPLINE
 	zend_class_entry *ce, *catch_ce;
@@ -4810,15 +4918,41 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH|CACHE_SLOT)
 
 	SAVE_OPLINE();
 	/* Check whether an exception has been thrown, if not, jump over code */
-	zend_exception_restore();
 	if (EG(exception) == NULL) {
 		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 	}
-	catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
-	if (UNEXPECTED(catch_ce == NULL)) {
-		catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+	if (OP1_TYPE == IS_UNUSED) {
+		/* catch (T $e) / catch (Box $e): polymorphic inline cache keyed on
+		 * (type_args generation, called_scope). The generation is a monotonic
+		 * nonce per zend_type_arg_table allocation, so it's ABA-safe across
+		 * calls that reuse the same heap address. NULL type_args maps to
+		 * generation 0 (the counter starts at 1). zend_fetch_class dispatches
+		 * to the right resolver based on the packed sub-type on miss. */
+		void **slot = CACHE_ADDR(opline->extended_value & ~ZEND_LAST_CATCH);
+		uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+		zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+		/* slot[2] != NULL distinguishes a populated entry from an
+		 * uninitialized (all-zeros) slot, which otherwise matches
+		 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+		if (EXPECTED(slot[2] != NULL
+				&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+			catch_ce = (zend_class_entry*)slot[2];
+		} else {
+			catch_ce = zend_fetch_class(NULL,
+				opline->op1.num | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+			if (EXPECTED(catch_ce)) {
+				slot[0] = (void*)cur_gen;
+				slot[1] = (void*)cur_scope;
+				slot[2] = (void*)catch_ce;
+			}
+		}
+	} else {
+		catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
+		if (UNEXPECTED(catch_ce == NULL)) {
+			catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
 
-		CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
+			CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
+		}
 	}
 	ce = EG(exception)->ce;
 
@@ -4917,7 +5051,7 @@ ZEND_VM_HOT_SEND_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, CONST|UNUSED|NUM, SPE
 			ZEND_VM_C_GOTO(send_val_by_ref);
 		}
 	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-ZEND_VM_C_LABEL(send_val_by_ref):
+ZEND_VM_C_LABEL(send_val_by_ref):;
 		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper, _arg_num, arg_num, _arg, arg);
 	}
 	value = GET_OP1_ZVAL_PTR(BP_VAR_R);
@@ -5392,6 +5526,11 @@ ZEND_VM_C_LABEL(send_again):
 						}
 
 						name = Z_STR_P(&key);
+
+						zend_ulong tmp;
+						if (ZEND_HANDLE_NUMERIC(name, tmp)) {
+							name = NULL;
+						}
 					}
 				}
 
@@ -5619,7 +5758,7 @@ ZEND_VM_C_LABEL(send_array):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(120, ZEND_SEND_USER, CONST|TMP|VAR|CV, NUM)
+ZEND_VM_HANDLER(120, ZEND_SEND_USER, CONST|TMP|CV, NUM)
 {
 	USE_OPLINE
 	zval *arg, *param;
@@ -5692,6 +5831,14 @@ ZEND_VM_HOT_HANDLER(63, ZEND_RECV, NUM, UNUSED)
 		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper, op_1, param);
 	}
 
+	/* The inline op2.num mask was baked in at the origin's compile time. A
+	 * generic-inheritance clone may carry a tighter substituted arg_info that
+	 * the mask doesn't reflect, so force the slow path when the function is a
+	 * clone with substituted types. */
+	if (UNEXPECTED(EX(func)->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper, op_1, param);
+	}
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5704,6 +5851,14 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_RECV, op->op2.num == MAY_BE_ANY, ZEND_RECV_NO
 		ZEND_VM_DISPATCH_TO_HELPER(zend_missing_arg_helper);
 	}
 
+	/* Origin compiled this parameter as mixed (MAY_BE_ANY), but a generic
+	 * inheritance clone may carry a substituted type in arg_info that we must
+	 * verify against. */
+	if (UNEXPECTED(EX(func)->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
+		zval *param = EX_VAR(opline->result.var);
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper, op_1, param);
+	}
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5829,7 +5984,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
+ZEND_VM_COLD_CONST_HANDLER(52, ZEND_BOOL, CONST|TMP|CV, ANY)
 {
 	USE_OPLINE
 	zval *val;
@@ -5874,7 +6029,7 @@ ZEND_VM_HELPER(zend_case_helper, ANY, ANY, zval *op_1, zval *op_2)
 	ZEND_VM_SMART_BRANCH(ret == 0, 1);
 }
 
-ZEND_VM_HANDLER(48, ZEND_CASE, TMPVAR, CONST|TMPVAR|CV)
+ZEND_VM_HANDLER(48, ZEND_CASE, TMP, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -5954,6 +6109,38 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N
 		ce = Z_CE_P(EX_VAR(opline->op1.var));
 	}
 
+	/* Naked `new` of a bare generic class (via `new static()`, `new $name`,
+	 * or any path that didn't go through compile-time canonical-name rewrite).
+	 * Skip when ZEND_VERIFY_GENERIC_ARGUMENTS follows — that opcode handles
+	 * the synthesis-and-swap for the turbofish path. Otherwise: if every
+	 * type parameter has a default, synthesize and use the defaults monomorph.
+	 * For `new static()` / lexical paths with no defaults, fall back to a
+	 * bare instance (preserves the lexical-self semantic for generic classes
+	 * whose authors didn't declare defaults). For dynamic `new $name()` we
+	 * throw — the caller spelled out a generic class by name and a bare
+	 * instance with erased T is almost never what they want.
+	 *
+	 * OP1_TYPE distinguishes: IS_UNUSED → static/self/parent (lenient);
+	 * IS_VAR → dynamic name resolved via FETCH_CLASS (strict). */
+	if (UNEXPECTED(OP1_TYPE != IS_CONST && ce->generic_parameters
+			&& (opline + 1)->opcode != ZEND_VERIFY_GENERIC_ARGUMENTS)) {
+		if (ce->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS) {
+			ce = zend_synthesize_monomorph(ce, NULL, 0);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else if (OP1_TYPE == IS_VAR) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments "
+				"via dynamic class name; no defaults declared",
+				ZSTR_VAL(ce->name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		/* IS_UNUSED with no defaults: fall through with the bare ce. */
+	}
+
 	result = EX_VAR(opline->result.var);
 	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
 		ZVAL_UNDEF(result);
@@ -5994,7 +6181,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
+ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMP|UNUSED|THIS|CV, ANY)
 {
 	USE_OPLINE
 	zval *obj;
@@ -6006,6 +6193,9 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
 	SAVE_OPLINE();
 	obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
 
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
 	do {
 		if (OP1_TYPE == IS_CONST ||
 		    (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
@@ -6022,7 +6212,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
 					HANDLE_EXCEPTION();
 				}
 			}
-			zend_throw_error(NULL, "__clone method called on non-object");
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
 			FREE_OP1();
 			HANDLE_EXCEPTION();
 		}
@@ -6041,14 +6231,12 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
 
 	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
 		scope = EX(func)->op_array.scope;
-		if (clone->common.scope != scope) {
-			if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
-			 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
-				zend_wrong_clone_call(clone, scope);
-				FREE_OP1();
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
-			}
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
+			FREE_OP1();
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
 		}
 	}
 
@@ -6156,7 +6344,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
 			}
 
 			bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
-			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {			
+			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
 				if (c->ce->type == ZEND_USER_CLASS) {
 					/* Recursion protection only applied to user constants, GH-18463 */
 					CONST_PROTECT_RECURSION(c);
@@ -6207,7 +6395,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, REF)
+ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|UNUSED|NEXT|CV, REF)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -6269,7 +6457,21 @@ ZEND_VM_C_LABEL(num_index):
 		} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			ZEND_VM_C_GOTO(add_again);
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			ZEND_VM_C_GOTO(str_index);
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -6319,17 +6521,22 @@ ZEND_VM_C_LABEL(add_unpack_again):
 		zval *val;
 
 		if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
-			zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
-			ZEND_HASH_FILL_PACKED(result_ht) {
-				ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
-					if (UNEXPECTED(Z_ISREF_P(val)) &&
-						UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
-						val = Z_REFVAL_P(val);
-					}
-					Z_TRY_ADDREF_P(val);
-					ZEND_HASH_FILL_ADD(val);
-				} ZEND_HASH_FOREACH_END();
-			} ZEND_HASH_FILL_END();
+			/* zend_hash_extend() skips initialization when the number of elements is 0,
+			 * but the code below expects that result_ht is initialized as packed.
+			 * We can just skip the work in that case. */
+			if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) {
+				zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
+				ZEND_HASH_FILL_PACKED(result_ht) {
+					ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
+						if (UNEXPECTED(Z_ISREF_P(val)) &&
+							UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
+							val = Z_REFVAL_P(val);
+						}
+						Z_TRY_ADDREF_P(val);
+						ZEND_HASH_FILL_ADD(val);
+					} ZEND_HASH_FOREACH_END();
+				} ZEND_HASH_FILL_END();
+			}
 		} else {
 			zend_string *key;
 
@@ -6437,7 +6644,7 @@ ZEND_VM_C_LABEL(add_unpack_again):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF)
+ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|UNUSED|NEXT|CV, ARRAY_INIT|REF)
 {
 	zval *array;
 	uint32_t size;
@@ -6459,7 +6666,7 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|UNUSE
 	}
 }
 
-ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
+ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|CV, ANY, TYPE)
 {
 	USE_OPLINE
 	zval *expr;
@@ -6508,7 +6715,7 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL, SPEC(OBSERVER))
+ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|CV, ANY, EVAL, SPEC(OBSERVER))
 {
 	USE_OPLINE
 	zend_op_array *new_op_array;
@@ -6646,7 +6853,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_COLD_HANDLER(179, ZEND_UNSET_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 {
 	USE_OPLINE
@@ -6699,7 +6906,7 @@ ZEND_VM_COLD_HANDLER(179, ZEND_UNSET_STATIC_PROP, ANY, ANY, CACHE_SLOT)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|CV, CONST|TMPVAR|CV)
+ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|CV, CONST|TMP|CV)
 {
 	USE_OPLINE
 	zval *container;
@@ -6737,7 +6944,17 @@ ZEND_VM_C_LABEL(num_index_dim):
 				offset = Z_REFVAL_P(offset);
 				ZEND_VM_C_GOTO(offset_again);
 			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
 				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
 				ZEND_VM_C_GOTO(num_index_dim);
 			} else if (Z_TYPE_P(offset) == IS_NULL) {
 				key = ZSTR_EMPTY_ALLOC();
@@ -6791,7 +7008,7 @@ ZEND_VM_C_LABEL(num_index_dim):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
+ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *container;
@@ -6836,7 +7053,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_S
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
+ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *array_ptr, *result;
@@ -7119,6 +7336,10 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit):
 		zval *variable_ptr = EX_VAR(opline->op2.var);
 		zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
 	} else {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			value = Z_REFVAL_P(value);
+			value_type = Z_TYPE_INFO_P(value);
+		}
 		zval *res = EX_VAR(opline->op2.var);
 		zend_refcounted *gc = Z_COUNTED_P(value);
 
@@ -7130,7 +7351,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit):
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HOT_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
+ZEND_VM_HOT_HANDLER(78, ZEND_FE_FETCH_R, TMP, ANY, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *array;
@@ -7199,6 +7420,10 @@ ZEND_VM_HOT_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
 		zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	} else {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			value = Z_REFVAL_P(value);
+			value_type = Z_TYPE_INFO_P(value);
+		}
 		zval *res = EX_VAR(opline->op2.var);
 		zend_refcounted *gc = Z_COUNTED_P(value);
 
@@ -7283,7 +7508,7 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR)
 			while (1) {
 				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
 					/* reached end of iteration */
-					ZEND_VM_C_GOTO(fe_fetch_w_exit);
+					ZEND_VM_C_GOTO(fe_fetch_w_exit_exc);
 				}
 				pos++;
 				value = &p->val;
@@ -7379,6 +7604,7 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR)
 		}
 	} else {
 		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array));
+ZEND_VM_C_LABEL(fe_fetch_w_exit_exc):
 		if (UNEXPECTED(EG(exception))) {
 			UNDEF_RESULT();
 			HANDLE_EXCEPTION();
@@ -7434,7 +7660,7 @@ ZEND_VM_HOT_HANDLER(154, ZEND_ISSET_ISEMPTY_CV, CV, UNUSED, ISSET, SPEC(ISSET))
 	}
 }
 
-ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
+ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|CV, UNUSED, VAR_FETCH|ISSET)
 {
 	USE_OPLINE
 	zval *value;
@@ -7478,7 +7704,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|
 	ZEND_VM_SMART_BRANCH(result, true);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
 ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, ANY, CLASS_FETCH, ISSET|CACHE_SLOT)
 {
 	USE_OPLINE
@@ -7499,7 +7725,7 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, ANY, CLASS_FETCH, ISSET|CAC
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|CV, CONST|TMPVAR|CV, ISSET)
+ZEND_VM_COLD_CONSTCONST_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMP|CV, CONST|TMP|CV, ISSET)
 {
 	USE_OPLINE
 	zval *container;
@@ -7578,7 +7804,7 @@ ZEND_VM_C_LABEL(isset_dim_obj_exit):
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-ZEND_VM_COLD_CONST_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET|CACHE_SLOT)
+ZEND_VM_COLD_CONST_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMP|UNUSED|THIS|CV, CONST|TMP|CV, ISSET|CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *container;
@@ -7628,7 +7854,7 @@ ZEND_VM_C_LABEL(isset_object_finish):
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-ZEND_VM_HANDLER(194, ZEND_ARRAY_KEY_EXISTS, CV|TMPVAR|CONST, CV|TMPVAR|CONST)
+ZEND_VM_HANDLER(194, ZEND_ARRAY_KEY_EXISTS, CV|TMP|CONST, CV|TMP|CONST)
 {
 	USE_OPLINE
 
@@ -7706,7 +7932,7 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
+ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *value;
@@ -7753,7 +7979,7 @@ ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
+ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *value;
@@ -7794,7 +8020,7 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMP|VAR|CV, JMP_ADDR)
+ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMP|CV, JMP_ADDR)
 {
 	USE_OPLINE
 	zval *val, *result;
@@ -7932,7 +8158,7 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST)
 		if (zv) {
 			SAVE_OPLINE();
 			ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2)));
-			if (!ce) {
+			if (EG(exception)) {
 				HANDLE_EXCEPTION();
 			}
 		}
@@ -7956,7 +8182,7 @@ ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, CACHE_SLOT)
 		if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
 			SAVE_OPLINE();
 			ce = zend_do_link_class(ce, (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key);
-			if (!ce) {
+			if (EG(exception)) {
 				HANDLE_EXCEPTION();
 			}
 		}
@@ -7981,7 +8207,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM)
 {
 	USE_OPLINE
 
-	if ((uint32_t)++EG(ticks_count) >= opline->extended_value) {
+	if (++EG(ticks_count) >= opline->extended_value) {
 		EG(ticks_count) = 0;
 		if (zend_ticks_function) {
 			SAVE_OPLINE();
@@ -7994,7 +8220,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT)
+ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT)
 {
 	USE_OPLINE
 	zval *expr;
@@ -8016,7 +8242,28 @@ ZEND_VM_C_LABEL(try_instanceof):
 				}
 			}
 		} else if (OP2_TYPE == IS_UNUSED) {
-			ce = zend_fetch_class(NULL, opline->op2.num);
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
 			if (UNEXPECTED(ce == NULL)) {
 				FREE_OP1();
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
@@ -8140,34 +8387,21 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 	}
 
 	uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
-	int i, current_try_catch_offset = -1;
+	uint32_t current_try_catch_offset = -1;
 
 	if ((throw_op->opcode == ZEND_FREE || throw_op->opcode == ZEND_FE_FREE)
 		&& throw_op->extended_value & ZEND_FREE_ON_RETURN) {
 		/* exceptions thrown because of loop var destruction on return/break/...
 		 * are logically thrown at the end of the foreach loop, so adjust the
-		 * throw_op_num.
+		 * throw_op_num to the final loop variable FREE.
 		 */
-		const zend_live_range *range = find_live_range(
-			&EX(func)->op_array, throw_op_num, throw_op->op1.var);
-		/* free op1 of the corresponding RETURN */
-		for (i = throw_op_num; i < range->end; i++) {
-			if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE
-			 || EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) {
-				/* pass */
-			} else {
-				if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN
-				 && (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) {
-					zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var));
-				}
-				break;
-			}
-		}
-		throw_op_num = range->end;
+		uint32_t new_throw_op_num = throw_op_num + throw_op->op2.opline_num;
+		cleanup_live_vars(execute_data, throw_op_num, new_throw_op_num);
+		throw_op_num = new_throw_op_num;
 	}
 
 	/* Find the innermost try/catch/finally the exception was thrown in */
-	for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
+	for (uint32_t i = 0; i < EX(func)->op_array.last_try_catch; i++) {
 		zend_try_catch_element *try_catch = &EX(func)->op_array.try_catch_array[i];
 		if (try_catch->try_op > throw_op_num) {
 			/* further blocks will not be relevant... */
@@ -8259,7 +8493,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
 	ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
 	c.name = zend_string_copy(Z_STR_P(name));
 
-	if (zend_register_constant(&c) == FAILURE) {
+	if (zend_register_constant(&c) == NULL) {
 	}
 
 	FREE_OP1();
@@ -8272,7 +8506,7 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST)
 	USE_OPLINE
 	zval *name;
 	zval *val;
-	zend_constant c;
+	zend_constant c, *registered;
 
 	SAVE_OPLINE();
 	name  = GET_OP1_ZVAL_PTR(BP_VAR_R);
@@ -8291,7 +8525,8 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST)
 	ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
 	c.name = zend_string_copy(Z_STR_P(name));
 
-	if (zend_register_constant(&c) == FAILURE) {
+	registered = zend_register_constant(&c);
+	if (registered == NULL) {
 		FREE_OP1();
 		FREE_OP2();
 		/* two opcodes used, second one is the data with attributes */
@@ -8299,9 +8534,7 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST)
 	}
 
 	HashTable *attributes = Z_PTR_P(GET_OP_DATA_ZVAL_PTR(BP_VAR_R));
-	zend_constant *registered = zend_get_constant_ptr(c.name);
 	ZEND_ASSERT(attributes != NULL);
-	ZEND_ASSERT(registered != NULL);
 	zend_constant_add_attributes(registered, attributes);
 
 	FREE_OP1();
@@ -8334,6 +8567,13 @@ ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, NUM)
 	zend_create_closure(EX_VAR(opline->result.var), func,
 		EX(func)->op_array.scope, called_scope, object);
 
+	/* If we're inside a generic frame, snapshot its T-table onto the new
+	 * closure so the closure body resolves outer T-refs against the
+	 * binding in effect at lambda-declaration time. */
+	if (UNEXPECTED(EX(type_args) != NULL)) {
+		zend_closure_capture_type_args(EX_VAR(opline->result.var), EX(type_args));
+	}
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
@@ -8364,7 +8604,7 @@ ZEND_VM_COLD_HELPER(zend_yield_in_closed_generator_helper, ANY, ANY)
 	HANDLE_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|CV|UNUSED, SRC)
+ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|CV|UNUSED, SRC)
 {
 	USE_OPLINE
 
@@ -8485,7 +8725,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|CV|UNUSED
 	ZEND_VM_RETURN();
 }
 
-ZEND_VM_HANDLER(166, ZEND_YIELD_FROM, CONST|TMPVAR|CV, ANY)
+ZEND_VM_HANDLER(166, ZEND_YIELD_FROM, CONST|TMP|CV, ANY)
 {
 	USE_OPLINE
 	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
@@ -8599,6 +8839,10 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
 		zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var);
 
 		zval_ptr_dtor(return_value);
+		/* Clear return value in case we hit both DISCARD_EXCEPTION and
+		 * zend_dispatch_try_catch_finally_helper, which will free the return
+		 * value again. See OSS-Fuzz #438780145. */
+		ZVAL_NULL(return_value);
 	}
 
 	/* cleanup delayed exception */
@@ -8722,7 +8966,7 @@ ZEND_VM_C_LABEL(check_indirect):
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
+ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMP|CV, ANY)
 {
 	USE_OPLINE
 	zval *value;
@@ -8767,7 +9011,7 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -8784,7 +9028,7 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMPVAR|CV, ANY, TYPE_MASK)
+ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|CV, ANY, TYPE_MASK)
 {
 	USE_OPLINE
 	zval *value;
@@ -8820,6 +9064,277 @@ ZEND_VM_C_LABEL(type_check_resource):
 	}
 }
 
+ZEND_VM_HOT_HANDLER(211, ZEND_TYPE_ASSERT, CONST, ANY, NUM)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *value = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+
+	uint8_t actual_type = Z_TYPE_P(value);
+	uint8_t expected_type = opline->extended_value & 0xff;
+	/* Simple types can be checked directly. */
+	if (UNEXPECTED(actual_type != expected_type)) {
+		zend_function *fbc;
+		{
+			zval *fname = (zval*)RT_CONSTANT(opline, opline->op1);
+			ZEND_ASSERT(Z_EXTRA_P(fname) != 0);
+			fbc = Z_FUNC(EG(function_table)->arData[Z_EXTRA_P(fname)].val);
+			ZEND_ASSERT(fbc->type != ZEND_USER_FUNCTION);
+		}
+		uint16_t argno = opline->extended_value >> 16;
+		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
+
+		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
+			const char *param_name = get_function_arg_name(fbc, argno);
+			zend_string *expected = zend_type_to_string(arginfo->type);
+			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_string_release(expected);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+ZEND_VM_HANDLER(212, ZEND_VERIFY_GENERIC_ARGUMENTS, TMP|UNUSED, UNUSED)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	uint32_t arity = opline->op2.num;
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	/* Skip the entry lookup for speculative sites (args_id == 0). */
+	zend_turbofish_args_entry *tf_entry =
+		(OP1_TYPE == IS_UNUSED && opline->extended_value)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (OP1_TYPE == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (OP1_TYPE == IS_UNUSED) {
+		/* Erased fast path: non-generic speculative site, nothing to verify. */
+		if (args_box == NULL
+				&& (!ZEND_USER_CODE(call->func->type)
+					|| !call->func->op_array.generic_parameters)) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Concrete turbofish args: dispatch to a synthesized plain monomorph and
+		 * skip generic verification (the monomorph's RECV does concrete checks). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, arity, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_verify_check_exception;
+			}
+		}
+		/* Runtime-promoted site: install the cached invariant table after a func
+		 * guard (cache_slot[3], bit1 = value check is a no-op). */
+		if (cache_slot && cache_slot[3]
+				&& ((uintptr_t) cache_slot[3] & ~(uintptr_t)3) == (uintptr_t) call->func) {
+			call->type_args = (zend_type_arg_table *) cache_slot[0];
+			if (((uintptr_t) cache_slot[3] & 2) == 0) {
+				zend_verify_generic_arg_types(call, args_box);
+				if (UNEXPECTED(EG(exception))) {
+					goto generic_verify_check_exception;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Inner/inference call already monomorphized: swap func + reinstall table. */
+		if (cache_slot && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH) {
+			zend_type_arg_table *ma = NULL;
+			zend_function *mono = zend_try_monomorph_resolved_call(call, NULL, cache_slot, &ma);
+			if (mono) {
+				call->func = mono;
+				call->type_args = ma;
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete turbofish VERIFY: install the precomputed SHM table after
+			 * the arity/bound check (memoized in cache_slot[0] per resolved func).
+			 * The persisted guard excludes the no-opcache heap-table case. */
+			bool checked = (cache_slot && cache_slot[0] == (void *) call->func);
+			if (!checked) {
+				zend_check_generic_call_arguments(call->func, arity, args_box);
+			}
+			if (EXPECTED(!EG(exception))) {
+				if (!checked && cache_slot) {
+					cache_slot[0] = (void *) call->func;
+				}
+				call->type_args = tf_entry->concrete_table;
+				if (!tf_entry->concrete_skip_value_check) {
+					zend_verify_generic_arg_types(call, args_box);
+				}
+			}
+		} else {
+			zend_check_generic_call_arguments(call->func, arity, args_box);
+			if (!EG(exception)) {
+				zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+				if (t) {
+					if (call->type_args) {
+						zend_type_arg_table_destroy(call->type_args);
+					}
+					call->type_args = t;
+				}
+				/* If the resolved table is invariant (CONCRETE sentinel), try to
+				 * monomorphize so later calls take the mono fast path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					zend_type_arg_table *ma = NULL;
+					zend_function *mono = zend_try_monomorph_resolved_call(call, t, cache_slot, &ma);
+					if (mono) {
+						call->func = mono;
+						call->type_args = ma;
+						ZEND_VM_NEXT_OPCODE();
+					}
+				}
+				zend_verify_generic_arg_types(call, args_box);
+				/* Promote the invariant site: record the resolved callee in
+				 * cache_slot[3] so later calls take the minimal install path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					/* Tag bits (func is >=8-aligned): bit0 = PROMOTED, bit1 = value
+					 * check is a no-op. slot[1] stays CONCRETE so the build cache
+					 * keeps returning the table on a func-guard miss. */
+					uintptr_t fn = (uintptr_t) call->func | 1u;
+					if (ZEND_USER_CODE(call->func->type)
+							&& call->func->op_array.generic_types
+							&& call->func->op_array.generic_types->parameters
+							&& zend_count_generic_value_checks(
+								call->func->op_array.generic_types->parameters) == 0) {
+						fn |= 2; /* value check is a no-op for this callee */
+					}
+					cache_slot[3] = (void *) fn;
+				}
+			}
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Monomorphize: synthesize (or look up) Box and swap both the
+		 * object's class entry and the pending constructor call. The monomorph
+		 * shares Box's property layout, so swapping ce is safe; swapping
+		 * call->func ensures the constructor's RECV opcodes verify against the
+		 * monomorph's substituted arg_info. The call-site inline cache (incl. the
+		 * concrete-args fast path) lives in zend_apply_generic_new. */
+		zend_apply_generic_new(new_obj, call, args_box, arity, cache_slot, /* do_checks */ true);
+	}
+
+generic_verify_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		/* Args have already been pushed by the SEND opcodes preceding the
+		 * VERIFY emission for call kind; release them so refcounted values
+		 * don't leak. */
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+/* Installs the type-arg table (and, for `new`, swaps the object's class to
+ * its monomorph) without running the runtime arity + bound checks that
+ * VERIFY does. Emitted by the compiler when the callee/ce is statically
+ * known, the turbofish args are concrete, and bounds were validated at
+ * compile time — so the runtime checks are pure overhead. The value-arg
+ * type-check (zend_verify_generic_arg_types) still runs since value
+ * arguments are runtime values. */
+ZEND_VM_HANDLER(213, ZEND_INSTALL_GENERIC_ARGS, TMP|UNUSED, UNUSED)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	zend_turbofish_args_entry *tf_entry =
+		(OP1_TYPE == IS_UNUSED)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (OP1_TYPE == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (OP1_TYPE == IS_UNUSED) {
+		/* Dispatch to a synthesized plain monomorph (see ZEND_VERIFY_GENERIC_ARGUMENTS). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, opline->op2.num, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_install_check_exception;
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete INSTALL: install the precomputed SHM table directly. The
+			 * persisted guard excludes the no-opcache heap-table case (whose table
+			 * is owned by the turbofish entry and must not be freed at teardown). */
+			call->type_args = tf_entry->concrete_table;
+			if (!tf_entry->concrete_skip_value_check) {
+				zend_verify_generic_arg_types(call, args_box);
+			}
+		} else {
+			zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+			if (t) {
+				if (call->type_args) {
+					zend_type_arg_table_destroy(call->type_args);
+				}
+				call->type_args = t;
+			}
+			zend_verify_generic_arg_types(call, args_box);
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Statically pre-validated: skip the runtime arity/bound check, but
+		 * still cache the resolved monomorph at the call site. */
+		zend_apply_generic_new(new_obj, call, args_box, opline->op2.num, cache_slot, /* do_checks */ false);
+	}
+
+generic_install_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_HOT_HANDLER(122, ZEND_DEFINED, CONST, ANY, CACHE_SLOT)
 {
 	USE_OPLINE
@@ -8858,7 +9373,7 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR)
 	}
 }
 
-ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, CV|TMPVAR|UNUSED|CLASS_FETCH, ANY)
+ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, CV|TMP|UNUSED|CLASS_FETCH, ANY)
 {
 	uint32_t fetch_type;
 	zend_class_entry *called_scope, *scope;
@@ -8883,6 +9398,17 @@ ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, CV|TMPVAR|UNUSED|CLASS_FETCH, ANY)
 	}
 
 	fetch_type = opline->op1.num;
+	if (zend_fetch_is_type_param(fetch_type)) {
+		SAVE_OPLINE();
+		zend_class_entry *resolved = zend_resolve_generic_type_param(
+			zend_unpack_type_param_index(fetch_type), fetch_type);
+		if (UNEXPECTED(!resolved)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), resolved->name);
+		ZEND_VM_NEXT_OPCODE();
+	}
 	scope = EX(func)->op_array.scope;
 	if (UNEXPECTED(scope == NULL)) {
 		SAVE_OPLINE();
@@ -8915,7 +9441,7 @@ ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, CV|TMPVAR|UNUSED|CLASS_FETCH, ANY)
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
@@ -9022,11 +9548,15 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 		ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
@@ -9371,7 +9901,7 @@ ZEND_VM_COLD_CONST_HANDLER(197, ZEND_MATCH_ERROR, CONST|TMPVARCV, UNUSED)
 	HANDLE_EXCEPTION();
 }
 
-ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM)
+ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|CV, CONST, NUM)
 {
 	USE_OPLINE
 	zval *op1;
@@ -9443,7 +9973,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM
 	ZEND_VM_SMART_BRANCH(0, 1);
 }
 
-ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
+ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMP|CV, UNUSED)
 {
 	USE_OPLINE
 	zval *op1;
@@ -9475,7 +10005,9 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -9498,7 +10030,7 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-ZEND_VM_TYPE_SPEC_HANDLER(ZEND_COUNT, (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY, ZEND_COUNT_ARRAY, CV|TMPVAR, UNUSED)
+ZEND_VM_TYPE_SPEC_HANDLER(ZEND_COUNT, (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY, ZEND_COUNT_ARRAY, CV|TMP, UNUSED)
 {
 	USE_OPLINE
 	zend_array *ht = Z_ARRVAL_P(GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R));
@@ -9513,7 +10045,7 @@ ZEND_VM_TYPE_SPEC_HANDLER(ZEND_COUNT, (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_B
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(191, ZEND_GET_CLASS, UNUSED|CONST|TMPVAR|CV, UNUSED)
+ZEND_VM_COLD_CONST_HANDLER(191, ZEND_GET_CLASS, UNUSED|CONST|TMP|CV, UNUSED)
 {
 	USE_OPLINE
 
@@ -9574,7 +10106,7 @@ ZEND_VM_HANDLER(192, ZEND_GET_CALLED_CLASS, UNUSED, UNUSED)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_COLD_CONST_HANDLER(193, ZEND_GET_TYPE, CONST|TMP|VAR|CV, UNUSED)
+ZEND_VM_COLD_CONST_HANDLER(193, ZEND_GET_TYPE, CONST|TMP|CV, UNUSED)
 {
 	USE_OPLINE
 	zval *op1;
@@ -9686,12 +10218,32 @@ ZEND_VM_HANDLER(167, ZEND_COPY_TMP, TMPVAR, UNUSED)
 	ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(202, ZEND_CALLABLE_CONVERT, UNUSED, UNUSED)
+ZEND_VM_HANDLER(202, ZEND_CALLABLE_CONVERT, UNUSED, UNUSED, NUM|CACHE_SLOT)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
 
-	zend_closure_from_frame(EX_VAR(opline->result.var), call);
+	if (opline->extended_value != (uint32_t)-1) {
+		zend_object *closure = CACHED_PTR(opline->extended_value);
+		if (closure) {
+			ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure);
+		} else {
+			/* Rotate the key for better hash distribution. */
+			const int shift = sizeof(size_t) == 4 ? 6 : 7;
+			zend_ulong key = (zend_ulong)(uintptr_t)call->func;
+			key = (key >> shift) | (key << ((sizeof(key) * 8) - shift));
+			zval *closure_zv = zend_hash_index_lookup(&EG(callable_convert_cache), key);
+			if (Z_TYPE_P(closure_zv) == IS_NULL) {
+				zend_closure_from_frame(closure_zv, call);
+			}
+			ZEND_ASSERT(Z_TYPE_P(closure_zv) == IS_OBJECT);
+			closure = Z_OBJ_P(closure_zv);
+			ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure);
+			CACHE_PTR(opline->extended_value, closure);
+		}
+	} else {
+		zend_closure_from_frame(EX_VAR(opline->result.var), call);
+	}
 
 	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
 		OBJ_RELEASE(Z_OBJ(call->This));
@@ -9742,7 +10294,7 @@ ZEND_VM_HANDLER(204, ZEND_FRAMELESS_ICALL_0, UNUSED, UNUSED, SPEC(OBSERVER))
 #endif
 	{
 		zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline);
-		function(EX_VAR(opline->result.var));
+		function(result);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
@@ -10490,7 +11042,12 @@ ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
 ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY)
 {
 	zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	/* opline is &call_interrupt_op. Load orig opline. */
+	LOAD_OPLINE();
+#else
 	SAVE_OPLINE();
+#endif
 	if (zend_atomic_bool_load_ex(&EG(timed_out))) {
 		zend_timeout();
 	} else if (zend_interrupt_function) {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 791e4b4e8843..3598c62060af 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -321,18 +320,27 @@ static uint8_t zend_user_opcodes[256] = {0,
 #define SPEC_RULE_OBSERVER     0x02000000
 
 static const uint32_t *zend_spec_handlers;
-static const void * const *zend_opcode_handlers;
+static zend_vm_opcode_handler_t const *zend_opcode_handlers;
 static int zend_handlers_count;
 #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
-static const void * const * zend_opcode_handler_funcs;
+static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;
 static zend_op hybrid_halt_op;
 #endif
-#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC
-static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);
+#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+
+static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;
 #endif
 
-#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
-static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op);
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+static const zend_op call_interrupt_op;
+#endif
+
+#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC
+static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);
+#endif
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+static zend_vm_opcode_handler_func_t zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op);
 #else
 # define zend_vm_get_opcode_handler_func zend_vm_get_opcode_handler
 #endif
@@ -381,11 +389,7 @@ static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op
 #if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)
 # define ZEND_OPCODE_HANDLER_RET void
 # define ZEND_VM_TAIL_CALL(call) call; return
-# ifdef ZEND_VM_TAIL_CALL_DISPATCH
-#  define ZEND_VM_CONTINUE()     ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); return
-# else
-#  define ZEND_VM_CONTINUE()     return
-# endif
+# define ZEND_VM_CONTINUE()      return
 # if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
 #  define ZEND_VM_RETURN()        opline = &hybrid_halt_op; return
 #  define ZEND_VM_HOT             zend_always_inline ZEND_COLD ZEND_OPT_SIZE
@@ -403,8 +407,7 @@ static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op
 # define ZEND_VM_HOT
 # define ZEND_VM_COLD            ZEND_COLD ZEND_OPT_SIZE
 #endif
-
-typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);
+#define ZEND_VM_DISPATCH_TO_HELPER(call) ZEND_VM_TAIL_CALL(call)
 
 #ifdef ZEND_VM_IP_GLOBAL_REG
 # define DCL_OPLINE
@@ -442,13 +445,17 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H
 # define ZEND_VM_LEAVE()           return (zend_op*)((uintptr_t)opline | ZEND_VM_ENTER_BIT)
 #endif
 #define ZEND_VM_INTERRUPT()      ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+#ifdef ZEND_VM_FP_GLOBAL_REG
 #define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler_func(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+#else
+#define ZEND_VM_LOOP_INTERRUPT() opline = (zend_op*)((uintptr_t)zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU) & ~ZEND_VM_ENTER_BIT);
+#endif
+#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler_func(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS);
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -469,7 +476,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_add_helper_S
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -490,7 +497,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_sub_helper_S
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -511,7 +518,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mul_helper_S
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mod_by_zero_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_mod_by_zero_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -521,7 +528,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mo
 	HANDLE_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -542,7 +549,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mod_helper_S
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -563,7 +570,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_shift_left_h
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -584,7 +591,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_shift_right_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	int ret;
 	USE_OPLINE
@@ -606,7 +613,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel
 	ZEND_VM_SMART_BRANCH(ret == 0, 1);
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	int ret;
 	USE_OPLINE
@@ -628,7 +635,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal
 	ZEND_VM_SMART_BRANCH(ret != 0, 1);
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	int ret;
 	USE_OPLINE
@@ -650,7 +657,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_h
 	ZEND_VM_SMART_BRANCH(ret < 0, 1);
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	int ret;
 	USE_OPLINE
@@ -672,7 +679,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_o
 	ZEND_VM_SMART_BRANCH(ret <= 0, 1);
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -693,7 +700,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_or_helper
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -714,7 +721,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_and_helpe
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
 
@@ -735,7 +742,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_xor_helpe
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_not_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_bw_not_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1)
 {
 	USE_OPLINE
 
@@ -748,7 +755,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_bw_not_helpe
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -758,7 +765,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_th
 	HANDLE_EXCEPTION();
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_undefined_function_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_undefined_function_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -769,7 +776,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_un
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	/* This helper actually never will receive IS_VAR as second op, and has the same handling for VAR and TMP in the first op, but for interoperability with the other binary_assign_op helpers, it is necessary to "include" it */
 
@@ -824,7 +831,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HAN
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *prop;
@@ -851,8 +858,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_STATIC_PROP_SPEC_HANDL
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *prop;
@@ -879,7 +886,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_STATIC_PROP_SPEC_HAND
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
 static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX int type)
 {
 	USE_OPLINE
@@ -892,7 +899,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_
 		&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
 		type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
 	if (UNEXPECTED(!prop)) {
-		ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
+		ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS) || (type == BP_VAR_UNSET));
 		prop = &EG(uninitialized_zval);
 	} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
 	 && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
@@ -914,26 +921,26 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_R_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_W_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_RW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		ZEND_VM_TAIL_CALL(ZEND_FETCH_STATIC_PROP_W_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
@@ -942,19 +949,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
 	}
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_UNSET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_IS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -966,7 +973,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_us
 	HANDLE_EXCEPTION();
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -978,7 +985,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_us
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *prop, *value;
@@ -990,6 +997,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT
 	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
 	if (UNEXPECTED(!prop)) {
 
+
 		UNDEF_RESULT();
 		HANDLE_EXCEPTION();
 	}
@@ -999,6 +1007,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT
 	if (ZEND_TYPE_IS_SET(prop_info->type)) {
 		value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC);
 
+
 	} else {
 		value = zend_assign_to_variable_ex(prop, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
 	}
@@ -1015,7 +1024,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *prop, *value;
@@ -1052,7 +1061,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *prop, *value;
@@ -1063,43 +1072,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT
 
 	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
 	if (UNEXPECTED(!prop)) {
-		zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-		UNDEF_RESULT();
-		HANDLE_EXCEPTION();
-	}
-
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (ZEND_TYPE_IS_SET(prop_info->type)) {
-		value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC);
-		zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-	} else {
-		value = zend_assign_to_variable_ex(prop, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-	}
 
-	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-		ZVAL_COPY(EX_VAR(opline->result.var), value);
-	}
-
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
-
-	/* assign_static_prop has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *prop, *value;
-	zend_property_info *prop_info;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-
-	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
-	if (UNEXPECTED(!prop)) {
 
 		UNDEF_RESULT();
 		HANDLE_EXCEPTION();
@@ -1110,6 +1083,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT
 	if (ZEND_TYPE_IS_SET(prop_info->type)) {
 		value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC);
 
+
 	} else {
 		value = zend_assign_to_variable_ex(prop, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
 	}
@@ -1126,7 +1100,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DAT
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_REF_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC_PROP_REF_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *prop, *value_ptr;
@@ -1174,11 +1148,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_REF_SPEC_HA
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_execute_data *old_execute_data;
 	uint32_t call_info = EX_CALL_INFO();
+#if ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL
+	/* zend_leave_helper may be called with opline=call_leave_op in TAILCALL VM */
 	SAVE_OPLINE();
+#endif
 
 	if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) == 0)) {
 		EG(current_execute_data) = EX(prev_execute_data);
@@ -1313,14 +1290,14 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
 	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1341,6 +1318,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
 	ret = 0 ? EX_VAR(opline->result.var) : &retval;
 	ZVAL_NULL(ret);
 
+
 	fbc->internal_function.handler(call, ret);
 
 #if ZEND_DEBUG
@@ -1348,14 +1326,19 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 
+
 	ZEND_VM_FCALL_INTERRUPT_CHECK(call);
 
 	EG(current_execute_data) = execute_data;
@@ -1384,7 +1367,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1405,6 +1388,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
 	ret = 1 ? EX_VAR(opline->result.var) : &retval;
 	ZVAL_NULL(ret);
 
+
 	fbc->internal_function.handler(call, ret);
 
 #if ZEND_DEBUG
@@ -1412,14 +1396,19 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 
+
 	ZEND_VM_FCALL_INTERRUPT_CHECK(call);
 
 	EG(current_execute_data) = execute_data;
@@ -1448,7 +1437,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_ICALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1477,11 +1466,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_OBS
 		if (should_throw) {
 			zend_internal_call_arginfo_violation(call->func);
 		}
-		ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-			zend_verify_internal_return_type(call->func, ret));
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
 		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 	}
 #endif
 	zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
@@ -1513,7 +1506,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_OBS
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1534,10 +1527,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV
 	LOAD_OPLINE_EX();
 
 
+
+
 	ZEND_VM_ENTER_EX();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_UCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1558,10 +1553,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV
 	LOAD_OPLINE_EX();
 
 
+
+
 	ZEND_VM_ENTER_EX();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_UCALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1586,7 +1583,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_OBS
 	ZEND_VM_ENTER_EX();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1628,6 +1625,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 		LOAD_OPLINE_EX();
 
 
+
+
 		ZEND_VM_ENTER_EX();
 	} else {
 		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -1645,6 +1644,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 		ret = 0 ? EX_VAR(opline->result.var) : &retval;
 		ZVAL_NULL(ret);
 
+
 		fbc->internal_function.handler(call, ret);
 
 #if ZEND_DEBUG
@@ -1652,14 +1652,20 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 
+
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
 
 		EG(current_execute_data) = execute_data;
@@ -1695,7 +1701,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1737,6 +1743,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 		LOAD_OPLINE_EX();
 
 
+
+
 		ZEND_VM_ENTER_EX();
 	} else {
 		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -1754,6 +1762,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 		ret = 1 ? EX_VAR(opline->result.var) : &retval;
 		ZVAL_NULL(ret);
 
+
 		fbc->internal_function.handler(call, ret);
 
 #if ZEND_DEBUG
@@ -1761,14 +1770,20 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 
+
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
 
 		EG(current_execute_data) = execute_data;
@@ -1804,7 +1819,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1872,12 +1887,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
@@ -1915,7 +1935,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -1954,6 +1974,33 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 			ret = EX_VAR(opline->result.var);
 		}
 
+		/* Closures created inside a generic frame carry that frame's T-table
+		 * via zend_vm_init_call_frame. Run the T-ref value-arg check against
+		 * the captured bindings now, before i_init_func_execute_data relocates
+		 * variadic args past the CV slots (which would leave the original arg
+		 * positions UNDEF and silently make every check pass). The cleanup on
+		 * failure matches ZEND_VERIFY_GENERIC_ARGUMENTS — at this point
+		 * call->prev_execute_data is still its zend_vm_init_call_frame value
+		 * (typically NULL), so EX(call) is the right slot to clear. */
+		if (UNEXPECTED(call->type_args
+				&& (fbc->common.fn_flags & ZEND_ACC_CLOSURE))) {
+			SAVE_OPLINE();
+			zend_verify_generic_arg_types(call, NULL);
+			if (UNEXPECTED(EG(exception))) {
+				zend_vm_stack_free_args(call);
+				if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+					OBJ_RELEASE(Z_OBJ(call->This));
+				}
+				EX(call) = call->prev_execute_data;
+				zend_vm_stack_free_call_frame(call);
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		call->prev_execute_data = execute_data;
 		execute_data = call;
 		i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
@@ -1962,10 +2009,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 			LOAD_OPLINE_EX();
 
 
+
+
 			ZEND_VM_ENTER_EX();
 		} else {
 			SAVE_OPLINE_EX();
 
+
 			execute_data = EX(prev_execute_data);
 			LOAD_OPLINE();
 			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
@@ -1987,6 +2037,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 		ret = 0 ? EX_VAR(opline->result.var) : &retval;
 		ZVAL_NULL(ret);
 
+
 		if (!zend_execute_internal) {
 			/* saves one function call if zend_execute_internal is not used */
 			fbc->internal_function.handler(call, ret);
@@ -1999,14 +2050,20 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 
+
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
 
 		EG(current_execute_data) = execute_data;
@@ -2040,7 +2097,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -2079,6 +2136,33 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 			ret = EX_VAR(opline->result.var);
 		}
 
+		/* Closures created inside a generic frame carry that frame's T-table
+		 * via zend_vm_init_call_frame. Run the T-ref value-arg check against
+		 * the captured bindings now, before i_init_func_execute_data relocates
+		 * variadic args past the CV slots (which would leave the original arg
+		 * positions UNDEF and silently make every check pass). The cleanup on
+		 * failure matches ZEND_VERIFY_GENERIC_ARGUMENTS — at this point
+		 * call->prev_execute_data is still its zend_vm_init_call_frame value
+		 * (typically NULL), so EX(call) is the right slot to clear. */
+		if (UNEXPECTED(call->type_args
+				&& (fbc->common.fn_flags & ZEND_ACC_CLOSURE))) {
+			SAVE_OPLINE();
+			zend_verify_generic_arg_types(call, NULL);
+			if (UNEXPECTED(EG(exception))) {
+				zend_vm_stack_free_args(call);
+				if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+					OBJ_RELEASE(Z_OBJ(call->This));
+				}
+				EX(call) = call->prev_execute_data;
+				zend_vm_stack_free_call_frame(call);
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		call->prev_execute_data = execute_data;
 		execute_data = call;
 		i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
@@ -2087,10 +2171,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 			LOAD_OPLINE_EX();
 
 
+
+
 			ZEND_VM_ENTER_EX();
 		} else {
 			SAVE_OPLINE_EX();
 
+
 			execute_data = EX(prev_execute_data);
 			LOAD_OPLINE();
 			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
@@ -2112,6 +2199,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 		ret = 1 ? EX_VAR(opline->result.var) : &retval;
 		ZVAL_NULL(ret);
 
+
 		if (!zend_execute_internal) {
 			/* saves one function call if zend_execute_internal is not used */
 			fbc->internal_function.handler(call, ret);
@@ -2124,14 +2212,20 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 
+
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
 
 		EG(current_execute_data) = execute_data;
@@ -2165,7 +2259,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DO_FCALL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
@@ -2204,6 +2298,33 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
 			ret = EX_VAR(opline->result.var);
 		}
 
+		/* Closures created inside a generic frame carry that frame's T-table
+		 * via zend_vm_init_call_frame. Run the T-ref value-arg check against
+		 * the captured bindings now, before i_init_func_execute_data relocates
+		 * variadic args past the CV slots (which would leave the original arg
+		 * positions UNDEF and silently make every check pass). The cleanup on
+		 * failure matches ZEND_VERIFY_GENERIC_ARGUMENTS — at this point
+		 * call->prev_execute_data is still its zend_vm_init_call_frame value
+		 * (typically NULL), so EX(call) is the right slot to clear. */
+		if (UNEXPECTED(call->type_args
+				&& (fbc->common.fn_flags & ZEND_ACC_CLOSURE))) {
+			SAVE_OPLINE();
+			zend_verify_generic_arg_types(call, NULL);
+			if (UNEXPECTED(EG(exception))) {
+				zend_vm_stack_free_args(call);
+				if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+					OBJ_RELEASE(Z_OBJ(call->This));
+				}
+				EX(call) = call->prev_execute_data;
+				zend_vm_stack_free_call_frame(call);
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		call->prev_execute_data = execute_data;
 		execute_data = call;
 		i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
@@ -2250,12 +2371,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
 #endif
 		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
 		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
@@ -2291,7 +2417,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
 	ZEND_VM_CONTINUE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_CREATE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *return_value = EX(return_value);
 
@@ -2369,7 +2495,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER(
 	}
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t _arg_num, zval *_arg)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t _arg_num, zval *_arg)
 {
 	USE_OPLINE
 
@@ -2381,7 +2507,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_ca
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *args;
@@ -2518,6 +2644,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
 						}
 
 						name = Z_STR_P(&key);
+
+						zend_ulong tmp;
+						if (ZEND_HANDLE_NUMERIC(name, tmp)) {
+							name = NULL;
+						}
 					}
 				}
 
@@ -2594,7 +2725,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *args;
@@ -2745,7 +2876,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_missing_arg_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_missing_arg_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -2755,7 +2886,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mi
 	HANDLE_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_verify_recv_arg_type_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_verify_recv_arg_type_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1)
 {
 	USE_OPLINE
 
@@ -2767,7 +2898,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_verify_recv_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_NOTYPE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RECV_NOTYPE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	uint32_t arg_num = opline->op1.num;
@@ -2776,10 +2907,18 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_NOTYPE_SPEC_H
 		ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
+	/* Origin compiled this parameter as mixed (MAY_BE_ANY), but a generic
+	 * inheritance clone may carry a substituted type in arg_info that we must
+	 * verify against. */
+	if (UNEXPECTED(EX(func)->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
+		zval *param = EX_VAR(opline->result.var);
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param));
+	}
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	int ret;
 	USE_OPLINE
@@ -2798,7 +2937,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_case_helper_
 	ZEND_VM_SMART_BRANCH(ret == 0, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -2814,17 +2953,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER(
 		zval *val;
 
 		if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
-			zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
-			ZEND_HASH_FILL_PACKED(result_ht) {
-				ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
-					if (UNEXPECTED(Z_ISREF_P(val)) &&
-						UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
-						val = Z_REFVAL_P(val);
-					}
-					Z_TRY_ADDREF_P(val);
-					ZEND_HASH_FILL_ADD(val);
-				} ZEND_HASH_FOREACH_END();
-			} ZEND_HASH_FILL_END();
+			/* zend_hash_extend() skips initialization when the number of elements is 0,
+			 * but the code below expects that result_ht is initialized as packed.
+			 * We can just skip the work in that case. */
+			if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) {
+				zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
+				ZEND_HASH_FILL_PACKED(result_ht) {
+					ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
+						if (UNEXPECTED(Z_ISREF_P(val)) &&
+							UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
+							val = Z_REFVAL_P(val);
+						}
+						Z_TRY_ADDREF_P(val);
+						ZEND_HASH_FILL_ADD(val);
+					} ZEND_HASH_FOREACH_END();
+				} ZEND_HASH_FILL_END();
+			}
 		} else {
 			zend_string *key;
 
@@ -2932,7 +3076,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER(
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varname;
@@ -2984,7 +3128,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array;
@@ -3091,6 +3235,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fe_fetch_obj
 		zval *variable_ptr = EX_VAR(opline->op2.var);
 		zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
 	} else {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			value = Z_REFVAL_P(value);
+			value_type = Z_TYPE_INFO_P(value);
+		}
 		zval *res = EX_VAR(opline->op2.var);
 		zend_refcounted *gc = Z_COUNTED_P(value);
 
@@ -3102,7 +3250,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fe_fetch_obj
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -3122,7 +3270,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -3156,7 +3304,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEN
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXT_STMT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_EXT_STMT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -3168,7 +3316,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXT_STMT_SPEC_HAN
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -3180,7 +3328,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXT_FCALL_BEGIN_S
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXT_FCALL_END_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_EXT_FCALL_END_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -3192,7 +3340,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXT_FCALL_END_SPE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *zv;
 	zend_class_entry *ce;
@@ -3207,7 +3355,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE
 		if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
 			SAVE_OPLINE();
 			ce = zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key);
-			if (!ce) {
+			if (EG(exception)) {
 				HANDLE_EXCEPTION();
 			}
 		}
@@ -3217,7 +3365,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_function *func;
 	USE_OPLINE
@@ -3228,11 +3376,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_FUNCTION_SPEC_HANDLER(
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TICKS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TICKS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
-	if ((uint32_t)++EG(ticks_count) >= opline->extended_value) {
+	if (++EG(ticks_count) >= opline->extended_value) {
 		EG(ticks_count) = 0;
 		if (zend_ticks_function) {
 			SAVE_OPLINE();
@@ -3245,21 +3393,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TICKS_SPEC_HANDLER(ZEND_OPCODE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXT_NOP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_EXT_NOP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NOP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NOP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t try_catch_offset, uint32_t op_num)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t try_catch_offset, uint32_t op_num)
 {
 	/* May be NULL during generator closing (only finally blocks are executed) */
 	zend_object *ex = EG(exception);
@@ -3336,44 +3484,31 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	const zend_op *throw_op = EG(opline_before_exception);
 
 	/* Exception was thrown before executing any op */
 	if (UNEXPECTED(!throw_op)) {
-		ZEND_VM_TAIL_CALL(zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX -1, 0));
+		ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX -1, 0));
 	}
 
 	uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
-	int i, current_try_catch_offset = -1;
+	uint32_t current_try_catch_offset = -1;
 
 	if ((throw_op->opcode == ZEND_FREE || throw_op->opcode == ZEND_FE_FREE)
 		&& throw_op->extended_value & ZEND_FREE_ON_RETURN) {
 		/* exceptions thrown because of loop var destruction on return/break/...
 		 * are logically thrown at the end of the foreach loop, so adjust the
-		 * throw_op_num.
+		 * throw_op_num to the final loop variable FREE.
 		 */
-		const zend_live_range *range = find_live_range(
-			&EX(func)->op_array, throw_op_num, throw_op->op1.var);
-		/* free op1 of the corresponding RETURN */
-		for (i = throw_op_num; i < range->end; i++) {
-			if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE
-			 || EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) {
-				/* pass */
-			} else {
-				if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN
-				 && (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) {
-					zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var));
-				}
-				break;
-			}
-		}
-		throw_op_num = range->end;
+		uint32_t new_throw_op_num = throw_op_num + throw_op->op2.opline_num;
+		cleanup_live_vars(execute_data, throw_op_num, new_throw_op_num);
+		throw_op_num = new_throw_op_num;
 	}
 
 	/* Find the innermost try/catch/finally the exception was thrown in */
-	for (i = 0; i < EX(func)->op_array.last_try_catch; i++) {
+	for (uint32_t i = 0; i < EX(func)->op_array.last_try_catch; i++) {
 		zend_try_catch_element *try_catch = &EX(func)->op_array.try_catch_array[i];
 		if (try_catch->try_op > throw_op_num) {
 			/* further blocks will not be relevant... */
@@ -3406,10 +3541,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, throw_op_num));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, throw_op_num));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	int ret;
@@ -3441,7 +3576,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_
 	}
 }
 
-static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -3453,7 +3588,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_yi
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *fast_call = EX_VAR(opline->op1.var);
@@ -3465,6 +3600,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER
 		zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var);
 
 		zval_ptr_dtor(return_value);
+		/* Clear return value in case we hit both DISCARD_EXCEPTION and
+		 * zend_dispatch_try_catch_finally_helper, which will free the return
+		 * value again. See OSS-Fuzz #438780145. */
+		ZVAL_NULL(return_value);
 	}
 
 	/* cleanup delayed exception */
@@ -3477,7 +3616,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *fast_call = EX_VAR(opline->result.var);
@@ -3488,7 +3627,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OP
 	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *fast_call = EX_VAR(opline->op1.var);
@@ -3505,10 +3644,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC
 	Z_OBJ_P(fast_call) = NULL;
 	current_try_catch_offset = opline->op2.num;
 	current_op_num = opline - EX(func)->op_array.opcodes;
-	ZEND_VM_TAIL_CALL(zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, current_op_num));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, current_op_num));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -3523,7 +3662,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_array *args = NULL;
 	zend_function *fbc = EX(func);
@@ -3585,10 +3724,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
 			LOAD_OPLINE_EX();
 
 
+
+
 			ZEND_VM_ENTER_EX();
 		} else {
 			SAVE_OPLINE_EX();
 
+
 			execute_data = EX(prev_execute_data);
 			if (execute_data) {
 				LOAD_OPLINE();
@@ -3613,6 +3755,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
 
 		ZVAL_NULL(ret);
 
+
 		if (!zend_execute_internal) {
 			/* saves one function call if zend_execute_internal is not used */
 			fbc->internal_function.handler(call, ret);
@@ -3625,14 +3768,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 
+
 		EG(current_execute_data) = call->prev_execute_data;
 
 		zend_vm_stack_free_args(call);
@@ -3666,7 +3814,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
 	ZEND_VM_LEAVE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_array *args = NULL;
 	zend_function *fbc = EX(func);
@@ -3768,11 +3916,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_
 			if (should_throw) {
 				zend_internal_call_arginfo_violation(call->func);
 			}
-			ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
-				zend_verify_internal_return_type(call->func, ret));
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
 			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
 				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
 			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
 		}
 #endif
 		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
@@ -3810,7 +3962,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_
 	ZEND_VM_LEAVE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_2_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -3844,7 +3996,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_2_SPEC_HANDLER
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -3878,7 +4030,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVE
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_3_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -3918,7 +4070,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_3_SPEC_HANDLER
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -3958,7 +4110,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVE
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_FORWARD_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_FORWARD_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -3966,10 +4118,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_FORWARD_SPEC_H
 	ZEND_VM_CONTINUE();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	/* opline is &call_interrupt_op. Load orig opline. */
+	LOAD_OPLINE();
+#else
 	SAVE_OPLINE();
+#endif
 	if (zend_atomic_bool_load_ex(&EG(timed_out))) {
 		zend_timeout();
 	} else if (zend_interrupt_function) {
@@ -3992,7 +4149,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_he
 	}
 	ZEND_VM_CONTINUE();
 }
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_function *fbc;
@@ -4004,7 +4161,17 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME
 		function_name = (zval*)RT_CONSTANT(opline, opline->op2);
 		func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(function_name+1));
 		if (UNEXPECTED(func == NULL)) {
-			ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			/* Mangled monomorph name: synthesize on first reference (may throw). */
+			SAVE_OPLINE();
+			fbc = zend_resolve_monomorph_by_name(Z_STR_P(function_name+1));
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+			if (UNEXPECTED(fbc == NULL)) {
+				ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			}
+			CACHE_PTR(opline->result.num, fbc);
+			goto fcall_by_name_push;
 		}
 		fbc = Z_FUNC_P(func);
 		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
@@ -4012,6 +4179,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME
 		}
 		CACHE_PTR(opline->result.num, fbc);
 	}
+fcall_by_name_push:
 	call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
 		fbc, opline->extended_value, NULL);
 	call->prev_execute_data = EX(call);
@@ -4020,7 +4188,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -4053,6 +4221,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_H
 
 	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
 
+
 		if (UNEXPECTED(EG(exception))) {
 			if (call) {
 				 if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
@@ -4073,7 +4242,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_H
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *func_name;
@@ -4088,7 +4257,21 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N
 		if (func == NULL) {
 			func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 2));
 			if (UNEXPECTED(func == NULL)) {
-				ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+				/* Mangled monomorph name: synthesize on first reference (qualified
+				 * then unqualified; may throw). */
+				SAVE_OPLINE();
+				fbc = zend_resolve_monomorph_by_name(Z_STR_P(func_name + 1));
+				if (fbc == NULL && !EG(exception)) {
+					fbc = zend_resolve_monomorph_by_name(Z_STR_P(func_name + 2));
+				}
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+				if (UNEXPECTED(fbc == NULL)) {
+					ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+				}
+				CACHE_PTR(opline->result.num, fbc);
+				goto ns_fcall_by_name_push;
 			}
 		}
 		fbc = Z_FUNC_P(func);
@@ -4098,6 +4281,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N
 		CACHE_PTR(opline->result.num, fbc);
 	}
 
+ns_fcall_by_name_push:
 	call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
 		fbc, opline->extended_value, NULL);
 	call->prev_execute_data = EX(call);
@@ -4106,7 +4290,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *fname;
@@ -4135,7 +4319,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_function *fbc;
@@ -4153,7 +4337,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_OFFSET_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	uint32_t arg_num;
@@ -4203,27 +4387,27 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
 	zend_execute_data *call;
 
 	SAVE_OPLINE();
-	function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 try_function_name:
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+	if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 		call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value);
-	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) {
+	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) {
 		call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value);
 	} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) {
 		call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value);
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) {
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) {
 		function_name = Z_REFVAL_P(function_name);
 		goto try_function_name;
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 			function_name = ZVAL_UNDEFINED_OP2();
 			if (UNEXPECTED(EG(exception) != NULL)) {
 				HANDLE_EXCEPTION();
@@ -4234,7 +4418,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_
 		call = NULL;
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+	if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 		if (UNEXPECTED(EG(exception))) {
 			if (call) {
@@ -4256,7 +4440,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RECV_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	uint32_t arg_num = opline->op1.num;
@@ -4269,13 +4453,21 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_SPEC_UNUSED_H
 	param = EX_VAR(opline->result.var);
 
 	if (UNEXPECTED(!(opline->op2.num & (1u << Z_TYPE_P(param))))) {
-		ZEND_VM_TAIL_CALL(zend_verify_recv_arg_type_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param));
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param));
+	}
+
+	/* The inline op2.num mask was baked in at the origin's compile time. A
+	 * generic-inheritance clone may carry a tighter substituted arg_info that
+	 * the mask doesn't reflect, so force the slow path when the function is a
+	 * clone with substituted types. */
+	if (UNEXPECTED(EX(func)->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param));
 	}
 
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	uint32_t arg_num = opline->op1.num;
@@ -4347,7 +4539,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -4373,7 +4565,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -4399,7 +4591,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVE
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -4432,6 +4624,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HAND
 
 	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
 
+
 		if (UNEXPECTED(EG(exception))) {
 			if (call) {
 				 if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
@@ -4452,7 +4645,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HAND
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -4463,10 +4656,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_not_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -4487,12 +4680,13 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CON
 		SAVE_OPLINE();
 		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *z;
@@ -4517,10 +4711,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_O
 		zend_string_release_ex(str, 0);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -4554,7 +4749,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_H
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -4588,7 +4783,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -4614,6 +4809,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONS
 	SAVE_OPLINE();
 	ret = i_zend_is_true(val);
 
+
 	if (ret) {
 		ZVAL_TRUE(EX_VAR(opline->result.var));
 		opline++;
@@ -4624,7 +4820,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONS
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -4649,6 +4845,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CON
 	SAVE_OPLINE();
 	ret = i_zend_is_true(val);
 
+
 	if (ret) {
 		ZVAL_TRUE(EX_VAR(opline->result.var));
 		opline = OP_JMP_ADDR(opline, opline->op2);
@@ -4659,15 +4856,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CON
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval_ptr;
 	zval *return_value;
 
+
 	retval_ptr = RT_CONSTANT(opline, opline->op1);
 	return_value = EX(return_value);
 
+
 	if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
 		SAVE_OPLINE();
 		retval_ptr = ZVAL_UNDEFINED_OP1();
@@ -4733,10 +4932,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_
 
 
 
+
+
+
 	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval_ptr;
@@ -4814,16 +5016,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_OBSER
 	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval_ptr;
 	zval *return_value;
 
+
 	SAVE_OPLINE();
 
 	return_value = EX(return_value);
 
+
 	do {
 		if ((IS_CONST & (IS_CONST|IS_TMP_VAR)) ||
 		    (IS_CONST == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
@@ -4833,6 +5037,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
 			retval_ptr = RT_CONSTANT(opline, opline->op1);
 			if (!return_value) {
 
+
 			} else {
 				if (IS_CONST == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
 					ZVAL_COPY_VALUE(return_value, retval_ptr);
@@ -4857,6 +5062,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
 					ZVAL_NEW_REF(return_value, retval_ptr);
 				} else {
 
+
 				}
 				break;
 			}
@@ -4871,13 +5077,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
 			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
 		}
 
+
 	} while (0);
 
 
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
 	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval_ptr;
@@ -4940,10 +5151,13 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
 
 	zend_observer_fcall_end(execute_data, return_value);
 	if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); };
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
 	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval;
@@ -4979,6 +5193,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CONST_HA
 		}
 	}
 
+
 	EG(current_execute_data) = EX(prev_execute_data);
 
 	/* Close the generator to free up resources */
@@ -4988,7 +5203,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CONST_HA
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval;
@@ -5035,7 +5250,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_OBSERVER
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -5059,19 +5274,19 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_
 			}
 			zend_throw_error(NULL, "Can only throw objects");
 
+
 			HANDLE_EXCEPTION();
 		}
 	} while (0);
 
-	zend_exception_save();
 	Z_TRY_ADDREF_P(value);
 	zend_throw_exception_object(value);
-	zend_exception_restore();
+
 
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_class_entry *ce, *catch_ce;
@@ -5079,15 +5294,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_
 
 	SAVE_OPLINE();
 	/* Check whether an exception has been thrown, if not, jump over code */
-	zend_exception_restore();
 	if (EG(exception) == NULL) {
 		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 	}
-	catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
-	if (UNEXPECTED(catch_ce == NULL)) {
-		catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+	if (IS_CONST == IS_UNUSED) {
+		/* catch (T $e) / catch (Box $e): polymorphic inline cache keyed on
+		 * (type_args generation, called_scope). The generation is a monotonic
+		 * nonce per zend_type_arg_table allocation, so it's ABA-safe across
+		 * calls that reuse the same heap address. NULL type_args maps to
+		 * generation 0 (the counter starts at 1). zend_fetch_class dispatches
+		 * to the right resolver based on the packed sub-type on miss. */
+		void **slot = CACHE_ADDR(opline->extended_value & ~ZEND_LAST_CATCH);
+		uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+		zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+		/* slot[2] != NULL distinguishes a populated entry from an
+		 * uninitialized (all-zeros) slot, which otherwise matches
+		 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+		if (EXPECTED(slot[2] != NULL
+				&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+			catch_ce = (zend_class_entry*)slot[2];
+		} else {
+			catch_ce = zend_fetch_class(NULL,
+				opline->op1.num | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+			if (EXPECTED(catch_ce)) {
+				slot[0] = (void*)cur_gen;
+				slot[1] = (void*)cur_scope;
+				slot[2] = (void*)catch_ce;
+			}
+		}
+	} else {
+		catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
+		if (UNEXPECTED(catch_ce == NULL)) {
+			catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
 
-		CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
+			CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
+		}
 	}
 	ce = EG(exception)->ce;
 
@@ -5122,7 +5363,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *arg, *param;
@@ -5139,10 +5380,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CONST_HANDLER(Z
 		ZVAL_COPY(param, arg);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -5163,12 +5405,13 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_H
 		SAVE_OPLINE();
 		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *obj;
@@ -5180,6 +5423,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_
 	SAVE_OPLINE();
 	obj = RT_CONSTANT(opline, opline->op1);
 
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
 	do {
 		if (IS_CONST == IS_CONST ||
 		    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
@@ -5196,7 +5442,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_
 					HANDLE_EXCEPTION();
 				}
 			}
-			zend_throw_error(NULL, "__clone method called on non-object");
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+
 
 			HANDLE_EXCEPTION();
 		}
@@ -5209,29 +5456,30 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_
 	if (UNEXPECTED(clone_call == NULL)) {
 		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
 
+
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		HANDLE_EXCEPTION();
 	}
 
 	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
 		scope = EX(func)->op_array.scope;
-		if (clone->common.scope != scope) {
-			if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
-			 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
-				zend_wrong_clone_call(clone, scope);
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
 
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
-			}
+
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
 		}
 	}
 
 	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr;
@@ -5264,6 +5512,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H
 					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
 				}
 
+
 				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 			}
 
@@ -5275,10 +5524,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H
 			}
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_op_array *new_op_array;
@@ -5289,6 +5539,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
 	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
 	if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
 			destroy_op_array(new_op_array);
 			efree_size(new_op_array, sizeof(zend_op_array));
@@ -5338,8 +5589,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
 		call->prev_execute_data = execute_data;
 		i_init_code_execute_data(call, new_op_array, return_value);
 
+
 		if (EXPECTED(zend_execute_ex == execute_ex)) {
 
+
 			ZEND_VM_ENTER();
 		} else {
 			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
@@ -5353,15 +5606,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
 		if (UNEXPECTED(EG(exception) != NULL)) {
 			zend_rethrow_exception(execute_data);
 
+
 			UNDEF_RESULT();
 			HANDLE_EXCEPTION();
 		}
 	}
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_op_array *new_op_array;
@@ -5444,7 +5699,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array_ptr, *result;
@@ -5460,6 +5715,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
 		}
 		Z_FE_POS_P(result) = 0;
 
+
 		ZEND_VM_NEXT_OPCODE();
 	} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
 		zend_object *zobj = Z_OBJ_P(array_ptr);
@@ -5469,6 +5725,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
 				if (UNEXPECTED(EG(exception))) {
 					UNDEF_RESULT();
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -5493,15 +5750,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
 			if (zend_hash_num_elements(properties) == 0) {
 				Z_FE_ITER_P(result) = (uint32_t) -1;
 
+
 				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 			}
 
 			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
 			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(EG(exception))) {
 				HANDLE_EXCEPTION();
 			} else if (is_empty) {
@@ -5515,11 +5775,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
 
+
 		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array_ptr, *array_ref;
@@ -5555,6 +5816,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
 		}
 		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
 
+
 		ZEND_VM_NEXT_OPCODE();
 	} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
 		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
@@ -5565,6 +5827,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
 				if (UNEXPECTED(EG(exception))) {
 					UNDEF_RESULT();
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -5591,15 +5854,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
 			if (zend_hash_num_elements(properties) == 0) {
 				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
 
+
 				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 			}
 
 			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
 			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(EG(exception))) {
 				HANDLE_EXCEPTION();
 			} else if (is_empty) {
@@ -5613,11 +5879,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
 
+
 		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -5638,6 +5905,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONS
 
 	if (UNEXPECTED(EG(exception))) {
 
+
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		HANDLE_EXCEPTION();
 	}
@@ -5660,10 +5928,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONS
 		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -5704,7 +5973,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CON
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val, *result;
@@ -5717,6 +5986,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CON
 				val = Z_REFVAL_P(val);
 				if (Z_TYPE_P(val) <= IS_NULL) {
 
+
 					break;
 				}
 			}
@@ -5748,7 +6018,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CON
 	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -5786,7 +6056,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CON
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -5795,7 +6065,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_SPEC_CONST_HANDL
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_function *func;
@@ -5819,10 +6089,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C
 	zend_create_closure(EX_VAR(opline->result.var), func,
 		EX(func)->op_array.scope, called_scope, object);
 
+	/* If we're inside a generic frame, snapshot its T-table onto the new
+	 * closure so the closure body resolves outer T-refs against the
+	 * binding in effect at lambda-declaration time. */
+	if (UNEXPECTED(EX(type_args) != NULL)) {
+		zend_closure_capture_type_args(EX_VAR(opline->result.var), EX(type_args));
+	}
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
@@ -5834,6 +6111,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
 		zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
 
+
 		UNDEF_RESULT();
 		HANDLE_EXCEPTION();
 	}
@@ -5846,6 +6124,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
 		}
 		Z_FE_POS(generator->values) = 0;
 
+
 	} else if (IS_CONST != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
 		zend_class_entry *ce = Z_OBJCE_P(val);
 		if (ce == zend_ce_generator) {
@@ -5853,6 +6132,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
 
 			Z_ADDREF_P(val);
 
+
 			if (UNEXPECTED(new_gen->execute_data == NULL)) {
 				zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
 				zval_ptr_dtor(val);
@@ -5876,6 +6156,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
 		} else {
 			zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
 
+
 			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
 				if (!EG(exception)) {
 					zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
@@ -5902,6 +6183,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
 	} else {
 		zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
 
+
 		UNDEF_RESULT();
 		HANDLE_EXCEPTION();
 	}
@@ -5922,7 +6204,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -5942,6 +6224,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST
 			if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
 				ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
 
+
 				ZEND_VM_NEXT_OPCODE();
 			}
 		}
@@ -5967,7 +6250,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -5981,10 +6264,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST
 		} while (0);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_CHECK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -6014,13 +6298,46 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_C
 	if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 		SAVE_OPLINE();
 
+
 		ZEND_VM_SMART_BRANCH(result, 1);
 	} else {
 		ZEND_VM_SMART_BRANCH(result, 0);
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_ASSERT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *value = get_zval_ptr_undef(opline->op2_type, opline->op2, BP_VAR_R);
+
+	uint8_t actual_type = Z_TYPE_P(value);
+	uint8_t expected_type = opline->extended_value & 0xff;
+	/* Simple types can be checked directly. */
+	if (UNEXPECTED(actual_type != expected_type)) {
+		zend_function *fbc;
+		{
+			zval *fname = (zval*)RT_CONSTANT(opline, opline->op1);
+			ZEND_ASSERT(Z_EXTRA_P(fname) != 0);
+			fbc = Z_FUNC(EG(function_table)->arData[Z_EXTRA_P(fname)].val);
+			ZEND_ASSERT(fbc->type != ZEND_USER_FUNCTION);
+		}
+		uint16_t argno = opline->extended_value >> 16;
+		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
+
+		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
+			const char *param_name = get_function_arg_name(fbc, argno);
+			zend_string *expected = zend_type_to_string(arginfo->type);
+			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_string_release(expected);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DEFINED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_constant *c;
@@ -6043,7 +6360,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_FRAMELESS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_FRAMELESS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_jmp_fl_result result = (uintptr_t)CACHED_PTR(opline->extended_value);
@@ -6066,7 +6383,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_FRAMELESS_SPEC_CONST_HANDL
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_LONG_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_LONG_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -6076,7 +6393,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_LONG_SPE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -6086,7 +6403,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_S
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -6096,7 +6413,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SP
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SIMPLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SIMPLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -6107,7 +6424,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SIMPLE_SP
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -6115,14 +6432,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SIMPLE
 
 	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
 	if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-		ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
 	}
 	value = RT_CONSTANT(opline, opline->op1);
 	ZVAL_COPY_VALUE(arg, value);
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -6157,10 +6474,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CO
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -6195,10 +6512,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CO
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -6236,10 +6553,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CO
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6250,10 +6567,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CO
 	div_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MOD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -6277,10 +6596,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CO
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6298,10 +6617,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CON
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6317,10 +6636,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CON
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6331,10 +6650,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CO
 	pow_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6346,10 +6667,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC
 	result = fast_is_identical_function(op1, op2);
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6361,10 +6684,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_
 	result = fast_is_not_identical_function(op1, op2);
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6419,10 +6744,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CON
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6477,10 +6802,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6520,10 +6845,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_C
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6567,10 +6892,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQU
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6581,10 +6906,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CO
 	compare_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_OR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6599,10 +6926,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_AND_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6617,10 +6944,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6635,10 +6962,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -6649,23 +6976,29 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CON
 	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 	dim = RT_CONSTANT(opline, opline->op2);
 	if (IS_CONST != IS_CONST) {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 fetch_dim_r_array:
 			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC);
 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		} else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
 			container = Z_REFVAL_P(container);
 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 				goto fetch_dim_r_array;
@@ -6684,23 +7017,29 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
 	zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -6715,11 +7054,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_AR
 		if (IS_CONST == IS_UNUSED) {
 			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
 		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -6727,11 +7072,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_CONST == IS_CONST ||
 	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -6805,6 +7154,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
@@ -6884,10 +7235,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 fetch_obj_r_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -6895,6 +7248,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_CONST == IS_CONST ||
 	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -7005,10 +7360,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 fetch_obj_is_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -7021,11 +7378,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_AR
 		}
 		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
+		if (IS_CONST == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
 		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -7034,10 +7397,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CONST_
 	container = RT_CONSTANT(opline, opline->op1);
 	zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -7159,10 +7523,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -7193,12 +7559,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 
 
+
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -7231,6 +7600,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 					if (UNEXPECTED(EG(exception) != NULL)) {
 						if (IS_CONST != IS_CONST) {
 
+
 						}
 						HANDLE_EXCEPTION();
 					}
@@ -7241,6 +7611,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 				zend_invalid_method_call(object, function_name);
 
 
+
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -7265,6 +7637,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
 			}
 
+
 			if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
 				zend_objects_store_del(orig_obj);
 			}
@@ -7288,6 +7661,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 
 	if (IS_CONST != IS_CONST) {
 
+
 	}
 
 	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
@@ -7317,7 +7691,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -7335,6 +7709,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_CONST != IS_CONST) {
@@ -7345,6 +7720,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -7377,6 +7753,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -7392,6 +7769,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_CONST == IS_CONST &&
@@ -7404,6 +7782,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		}
 		if (IS_CONST != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -7450,7 +7829,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -7472,6 +7851,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
 		 * to make sure we don't increase VM size too much. */
 		if (!(IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
 
+
 			HANDLE_EXCEPTION();
 		}
 
@@ -7494,6 +7874,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
 			call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
 		}
 
+
 		if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
 			if (call_info & ZEND_CALL_CLOSURE) {
 				zend_object_release(ZEND_CLOSURE_OBJECT(func));
@@ -7510,6 +7891,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
 		zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error);
 		efree(error);
 
+
 		HANDLE_EXCEPTION();
 	}
 
@@ -7521,7 +7903,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -7533,6 +7915,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONS
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -7549,7 +7932,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -7561,6 +7944,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_CONST_H
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -7573,8 +7957,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_CONST_H
 			goto send_val_by_ref;
 		}
 	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-send_val_by_ref:
-		ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
 	}
 	value = RT_CONSTANT(opline, opline->op1);
 	ZVAL_COPY_VALUE(arg, value);
@@ -7586,7 +7970,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_CONST_H
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_class_entry *ce, *scope;
 	zend_class_constant *c;
@@ -7611,6 +7995,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 				if (UNEXPECTED(ce == NULL)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 				CACHE_PTR(opline->extended_value, ce);
@@ -7620,6 +8005,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 			if (UNEXPECTED(ce == NULL)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		} else {
@@ -7637,6 +8023,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
 			ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 			HANDLE_EXCEPTION();
 		}
 		constant_name = Z_STR_P(constant_zv);
@@ -7644,6 +8031,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 		if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
 
+
 			ZEND_VM_NEXT_OPCODE();
 		}
 		zv = IS_CONST == IS_CONST
@@ -7657,6 +8045,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 
@@ -7664,6 +8053,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 
@@ -7681,6 +8071,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 				if (EG(exception)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -7691,6 +8082,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -7698,6 +8090,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -7709,16 +8102,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 			ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 			HANDLE_EXCEPTION();
 		}
 	} while (0);
 
 	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -7733,6 +8128,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 			ZVAL_MAKE_REF_EX(expr_ptr, 2);
 		}
 
+
 	} else {
 		expr_ptr = RT_CONSTANT(opline, opline->op1);
 		if (IS_CONST == IS_TMP_VAR) {
@@ -7780,7 +8176,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -7805,6 +8215,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -7814,7 +8225,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -7836,7 +8247,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HA
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -7887,6 +8298,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM
 			if (IS_CONST & (IS_CONST|IS_CV)) {
 				/* avoid exception check */
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		} else {
@@ -7912,10 +8324,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM
 isset_dim_obj_exit:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -7962,10 +8376,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO
 isset_object_finish:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -7994,10 +8410,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO
 	}
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -8008,7 +8426,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CON
 		if (zv) {
 			SAVE_OPLINE();
 			ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2)));
-			if (!ce) {
+			if (EG(exception)) {
 				HANDLE_EXCEPTION();
 			}
 		}
@@ -8017,7 +8435,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CON
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *name;
@@ -8034,6 +8452,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST
 			zval_ptr_dtor_nogc(&c.value);
 
 
+
+
 			HANDLE_EXCEPTION();
 		}
 	}
@@ -8041,19 +8461,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST
 	ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
 	c.name = zend_string_copy(Z_STR_P(name));
 
-	if (zend_register_constant(&c) == FAILURE) {
+	if (zend_register_constant(&c) == NULL) {
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *name;
 	zval *val;
-	zend_constant c;
+	zend_constant c, *registered;
 
 	SAVE_OPLINE();
 	name  = RT_CONSTANT(opline, opline->op1);
@@ -8065,6 +8487,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_
 			zval_ptr_dtor_nogc(&c.value);
 
 
+
+
 			HANDLE_EXCEPTION();
 		}
 	}
@@ -8072,7 +8496,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_
 	ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
 	c.name = zend_string_copy(Z_STR_P(name));
 
-	if (zend_register_constant(&c) == FAILURE) {
+	registered = zend_register_constant(&c);
+	if (registered == NULL) {
+
+
 
 
 		/* two opcodes used, second one is the data with attributes */
@@ -8080,17 +8507,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_
 	}
 
 	HashTable *attributes = Z_PTR_P(get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1));
-	zend_constant *registered = zend_get_constant_ptr(c.name);
 	ZEND_ASSERT(attributes != NULL);
-	ZEND_ASSERT(registered != NULL);
 	zend_constant_add_attributes(registered, attributes);
 
 
+
+
 	/* two opcodes used, second one is the data with attributes */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -8147,6 +8574,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = RT_CONSTANT(opline, opline->op1);
@@ -8162,6 +8590,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
 			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_CONST == IS_CV) {
@@ -8182,6 +8611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -8209,7 +8639,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SWITCH_LONG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op, *jump_zv;
@@ -8237,7 +8667,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SWITCH_STRING_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op, *jump_zv;
@@ -8270,7 +8700,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPE
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MATCH_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op, *jump_zv;
@@ -8311,7 +8741,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_SPEC_CONST_
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -8338,10 +8768,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CON
 			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
 				result = zend_hash_find(ht, Z_STR_P(op1));
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
@@ -8366,6 +8798,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CON
 			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
 				result = zend_hash_find(ht, Z_STR_P(op1));
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		}
@@ -8375,15 +8808,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CON
 			ZVAL_STR(&key_tmp, key);
 			if (zend_compare(op1, &key_tmp) == 0) {
 
+
 				ZEND_VM_SMART_BRANCH(1, 1);
 			}
 		} ZEND_HASH_FOREACH_END();
 	}
 
+
 	ZEND_VM_SMART_BRANCH(0, 1);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -8418,10 +8853,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -8456,10 +8891,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMP
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MOD_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -8483,10 +8918,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMPVARCV_HANDLE
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SL_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8504,10 +8939,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVARCV_HANDLER
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SR_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8523,10 +8958,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMPVARCV_HANDLER
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8566,10 +9001,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8609,10 +9044,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CO
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8652,10 +9087,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CO
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8699,10 +9134,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8746,10 +9181,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8793,10 +9228,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_class_entry *ce, *scope;
 	zend_class_constant *c;
@@ -8929,7 +9364,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -8941,7 +9376,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -8953,7 +9388,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_CONS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -8965,7 +9400,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_CO
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8977,7 +9412,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMP
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -8989,7 +9424,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SP
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9001,7 +9436,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SP
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9013,7 +9448,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_T
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9025,7 +9460,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9037,7 +9472,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9049,7 +9484,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9061,7 +9496,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9073,7 +9508,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9085,7 +9520,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPE
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9097,7 +9532,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9109,7 +9544,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
@@ -9126,6 +9561,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 			SAVE_OPLINE();
 			zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
 		ht = Z_ARRVAL_P(container);
@@ -9134,6 +9570,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 		if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 			SAVE_OPLINE();
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
 			ZEND_VM_NEXT_OPCODE();
@@ -9153,6 +9590,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 		}
 		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 
@@ -9161,54 +9599,57 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 	SAVE_OPLINE();
 	zend_undefined_offset(offset);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
 	op1 = RT_CONSTANT(opline, opline->op1);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	div_function(EX_VAR(opline->result.var), op1, op2);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
 	op1 = RT_CONSTANT(opline, opline->op1);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	pow_function(EX_VAR(opline->result.var), op1, op2);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	op1 = RT_CONSTANT(opline, opline->op1);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
 		zend_string *op1_str = Z_STR_P(op1);
 		zend_string *op2_str = Z_STR_P(op2);
 		zend_string *str;
 		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
 
 		if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
@@ -9216,13 +9657,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
 			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
 			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
@@ -9236,7 +9677,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
 			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else {
@@ -9248,7 +9689,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
 			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		}
@@ -9259,44 +9700,50 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL
 		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
 			op1 = ZVAL_UNDEFINED_OP1();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
 			op2 = ZVAL_UNDEFINED_OP2();
 		}
 		concat_function(EX_VAR(opline->result.var), op1, op2);
 
+
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
 	op1 = RT_CONSTANT(opline, opline->op1);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	compare_function(EX_VAR(opline->result.var), op1, op2);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
-	dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	if (IS_CONST != IS_CONST) {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 fetch_dim_r_array:
-			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC);
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC);
 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		} else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
 			container = Z_REFVAL_P(container);
 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 				goto fetch_dim_r_array;
@@ -9305,33 +9752,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_
 			}
 		} else {
 fetch_dim_r_slow:
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 		}
 	} else {
-		zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+		zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
-	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -9343,14 +9794,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
 		}
 		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+		if (IS_TMP_VAR == IS_UNUSED) {
 			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -9358,11 +9815,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_CONST == IS_CONST ||
 	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -9371,7 +9832,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP1();
 			}
-			zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 			ZVAL_NULL(EX_VAR(opline->result.var));
 			goto fetch_obj_r_finish;
 		} while (0);
@@ -9383,7 +9844,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 		zend_string *name, *tmp_name;
 		zval *retval;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
 
 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
@@ -9436,12 +9897,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -9474,9 +9937,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 					}
 				}
 			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -9500,7 +9963,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 		}
 #endif
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -9515,10 +9978,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 fetch_obj_r_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -9526,6 +9990,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_CONST == IS_CONST ||
 	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -9536,7 +10002,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 					break;
 				}
 			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
 				ZVAL_UNDEFINED_OP2();
 			}
 			ZVAL_NULL(EX_VAR(opline->result.var));
@@ -9550,7 +10016,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 		zend_string *name, *tmp_name;
 		zval *retval;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			cache_slot = CACHE_ADDR(opline->extended_value);
 
 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
@@ -9577,7 +10043,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -9610,9 +10076,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 					}
 				}
 			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -9621,7 +10087,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 
 		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -9636,10 +10102,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 fetch_obj_is_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -9652,23 +10119,29 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_AR
 		}
 		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CONST == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
-	zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -9676,16 +10149,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 
 
 	op1 = RT_CONSTANT(opline, opline->op1);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
 		zend_string *op1_str = Z_STR_P(op1);
 		zend_string *op2_str = Z_STR_P(op2);
 		zend_string *str;
 		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
 
 		if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
@@ -9693,13 +10166,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
 			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
@@ -9710,7 +10183,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else {
@@ -9722,7 +10195,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		}
@@ -9740,12 +10213,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 		}
 		op1_str = zval_get_string_func(op1);
 	}
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		op2_str = Z_STR_P(op2);
 	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
 		op2_str = zend_string_copy(Z_STR_P(op2));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
 			ZVAL_UNDEFINED_OP2();
 		}
 		op2_str = zval_get_string_func(op2);
@@ -9753,7 +10226,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 	do {
 		if (IS_CONST != IS_CONST) {
 			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+				if (IS_TMP_VAR == IS_CONST) {
 					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
 						GC_ADDREF(op2_str);
 					}
@@ -9763,7 +10236,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 				break;
 			}
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
 				if (IS_CONST == IS_CONST) {
 					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
@@ -9784,16 +10257,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_
 		if (IS_CONST != IS_CONST) {
 			zend_string_release_ex(op1_str, 0);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_string_release_ex(op2_str, 0);
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -9808,28 +10282,30 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 
 	object = RT_CONSTANT(opline, opline->op1);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
+	if (IS_TMP_VAR != IS_CONST &&
 	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
 		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
 				function_name = Z_REFVAL_P(function_name);
 				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 					break;
 				}
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -9860,18 +10336,19 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 				if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
 					object = ZVAL_UNDEFINED_OP1();
 					if (UNEXPECTED(EG(exception) != NULL)) {
-						if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+						if (IS_TMP_VAR != IS_CONST) {
 							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 						}
 						HANDLE_EXCEPTION();
 					}
 				}
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-					function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 				}
 				zend_invalid_method_call(object, function_name);
 				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -9879,18 +10356,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 
 	called_scope = obj->ce;
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	if (IS_TMP_VAR == IS_CONST &&
 	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
 		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
 	} else {
 		zend_object *orig_obj = obj;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-			function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		}
 
 		/* First, locate the function. */
-		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
 		if (UNEXPECTED(fbc == NULL)) {
 			if (EXPECTED(!EG(exception))) {
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
@@ -9901,7 +10378,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 			}
 			HANDLE_EXCEPTION();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+		if (IS_TMP_VAR == IS_CONST &&
 		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
 		    EXPECTED(obj == orig_obj)) {
 			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
@@ -9917,7 +10394,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 
@@ -9948,7 +10425,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -9968,7 +10445,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 				HANDLE_EXCEPTION();
 			}
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				CACHE_PTR(opline->result.num, ce);
 			}
 		}
@@ -9983,24 +10460,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 	}
 
 	if (IS_CONST == IS_CONST &&
-	    (IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	    IS_TMP_VAR == IS_CONST &&
 	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
 		/* nothing to do */
 	} else if (IS_CONST != IS_CONST &&
-	           (IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	           IS_TMP_VAR == IS_CONST &&
 	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
 		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
-	} else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	} else if (IS_TMP_VAR != IS_UNUSED) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR != IS_CONST) {
 			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
 				do {
-					if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+					if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
 						function_name = Z_REFVAL_P(function_name);
 						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 							break;
 						}
-					} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+					} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 						ZVAL_UNDEFINED_OP2();
 						if (UNEXPECTED(EG(exception) != NULL)) {
 							HANDLE_EXCEPTION();
@@ -10016,7 +10493,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		if (ce->get_static_method) {
 			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
 		} else {
-			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
 		}
 		if (UNEXPECTED(fbc == NULL)) {
 			if (EXPECTED(!EG(exception))) {
@@ -10025,7 +10502,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 			HANDLE_EXCEPTION();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+		if (IS_TMP_VAR == IS_CONST &&
 		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
 			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
 			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
@@ -10033,7 +10510,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
 			init_func_run_time_cache(&fbc->op_array);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 		}
 	} else {
@@ -10081,7 +10558,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -10093,7 +10570,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
 	uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
 
 	SAVE_OPLINE();
-	function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
 		ZEND_ASSERT(!error);
 
@@ -10101,7 +10578,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
 		 * invoke a user error handler and throw an exception.
 		 * For the CONST and CV case we reuse the same exception block below
 		 * to make sure we don't increase VM size too much. */
-		if (!((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+		if (!(IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 			HANDLE_EXCEPTION();
 		}
@@ -10126,7 +10603,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
 		}
 
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-		if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+		if ((IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
 			if (call_info & ZEND_CALL_CLOSURE) {
 				zend_object_release(ZEND_CLOSURE_OBJECT(func));
 			} else if (call_info & ZEND_CALL_RELEASE_THIS) {
@@ -10153,7 +10630,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -10168,6 +10645,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
 			ZVAL_MAKE_REF_EX(expr_ptr, 2);
 		}
 
+
 	} else {
 		expr_ptr = RT_CONSTANT(opline, opline->op1);
 		if (IS_CONST == IS_TMP_VAR) {
@@ -10193,15 +10671,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		zend_string *str;
 		zend_ulong hval;
 
 add_again:
 		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 			str = Z_STR_P(offset);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				if (ZEND_HANDLE_NUMERIC(str, hval)) {
 					goto num_index;
 				}
@@ -10212,10 +10690,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
 			hval = Z_LVAL_P(offset);
 num_index:
 			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -10231,7 +10723,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
 			zend_use_resource_as_offset(offset);
 			hval = Z_RES_HANDLE_P(offset);
 			goto num_index;
-		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
 			ZVAL_UNDEFINED_OP2();
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
@@ -10249,7 +10741,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -10264,14 +10756,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_H
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -10281,7 +10773,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 		HashTable *ht;
@@ -10293,17 +10785,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
 isset_again:
 		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 			str = Z_STR_P(offset);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				if (ZEND_HANDLE_NUMERIC(str, hval)) {
 					goto num_index_prop;
 				}
 			}
-			value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST);
+			value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST);
 		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
 			hval = Z_LVAL_P(offset);
 num_index_prop:
 			value = zend_hash_index_find(ht, hval);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
 			offset = Z_REFVAL_P(offset);
 			goto isset_again;
 		} else {
@@ -10335,7 +10827,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+	if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
 		offset++;
 	}
 	if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -10347,10 +10839,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
 isset_dim_obj_exit:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -10360,7 +10853,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (IS_CONST == IS_CONST ||
 	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -10376,7 +10869,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		name = Z_STR_P(offset);
 	} else {
 		name = zval_try_get_tmp_string(offset, &tmp_name);
@@ -10388,19 +10881,20 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO
 
 	result =
 		(opline->extended_value & ZEND_ISEMPTY) ^
-		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
 isset_object_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -10411,14 +10905,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM
 	SAVE_OPLINE();
 
 	key = RT_CONSTANT(opline, opline->op1);
-	subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
 array_key_exists_array:
 		ht = Z_ARRVAL_P(subject);
 		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
 	} else {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
 			subject = Z_REFVAL_P(subject);
 			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
 				goto array_key_exists_array;
@@ -10430,10 +10924,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -10490,6 +10985,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLE
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = RT_CONSTANT(opline, opline->op1);
@@ -10505,6 +11001,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLE
 			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_CONST == IS_CV) {
@@ -10518,9 +11015,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLE
 	}
 
 	/* Set the new yielded key */
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
 			key = Z_REFVAL_P(key);
 		}
 		ZVAL_COPY(&generator->key, key);
@@ -10553,7 +11050,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLE
 	ZEND_VM_RETURN();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type)
 {
 	USE_OPLINE
 	zval *varname;
@@ -10577,6 +11074,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_ad
 		if (UNEXPECTED(!name)) {
 			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
 
+
 			}
 			ZVAL_UNDEF(EX_VAR(opline->result.var));
 			HANDLE_EXCEPTION();
@@ -10639,6 +11137,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_ad
 
 	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
 
+
 	}
 
 	if (IS_CONST != IS_CONST) {
@@ -10654,41 +11153,41 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_ad
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_W_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_RW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	int fetch_type =
 		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
 			BP_VAR_W : BP_VAR_R;
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -10703,11 +11202,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
 		if (IS_UNUSED == IS_UNUSED) {
 			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
 		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -10725,6 +11230,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_UNUSED != IS_CONST) {
@@ -10735,6 +11241,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -10767,6 +11274,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -10782,6 +11290,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_UNUSED == IS_CONST &&
@@ -10794,6 +11303,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		}
 		if (IS_UNUSED != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -10840,7 +11350,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	if (IS_CONST == IS_UNUSED) {
 		SAVE_OPLINE();
@@ -10866,6 +11376,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP
 			ZVAL_DEREF(retval_ptr);
 		}
 
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
@@ -10907,7 +11429,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -10919,6 +11441,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONS
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -10935,7 +11458,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -10947,6 +11470,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -10959,8 +11483,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_
 			goto send_val_by_ref;
 		}
 	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-send_val_by_ref:
-		ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
 	}
 	value = RT_CONSTANT(opline, opline->op1);
 	ZVAL_COPY_VALUE(arg, value);
@@ -10972,7 +11496,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -10984,6 +11508,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_C
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -10996,8 +11521,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_C
 			goto send_val_by_ref;
 		}
 	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-send_val_by_ref:
-		ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
 	}
 	value = RT_CONSTANT(opline, opline->op1);
 	ZVAL_COPY_VALUE(arg, value);
@@ -11009,7 +11534,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *result;
@@ -11038,6 +11563,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER(
 		ce = Z_CE_P(EX_VAR(opline->op1.var));
 	}
 
+	/* Naked `new` of a bare generic class (via `new static()`, `new $name`,
+	 * or any path that didn't go through compile-time canonical-name rewrite).
+	 * Skip when ZEND_VERIFY_GENERIC_ARGUMENTS follows — that opcode handles
+	 * the synthesis-and-swap for the turbofish path. Otherwise: if every
+	 * type parameter has a default, synthesize and use the defaults monomorph.
+	 * For `new static()` / lexical paths with no defaults, fall back to a
+	 * bare instance (preserves the lexical-self semantic for generic classes
+	 * whose authors didn't declare defaults). For dynamic `new $name()` we
+	 * throw — the caller spelled out a generic class by name and a bare
+	 * instance with erased T is almost never what they want.
+	 *
+	 * IS_CONST distinguishes: IS_UNUSED → static/self/parent (lenient);
+	 * IS_VAR → dynamic name resolved via FETCH_CLASS (strict). */
+	if (UNEXPECTED(IS_CONST != IS_CONST && ce->generic_parameters
+			&& (opline + 1)->opcode != ZEND_VERIFY_GENERIC_ARGUMENTS)) {
+		if (ce->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS) {
+			ce = zend_synthesize_monomorph(ce, NULL, 0);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else if (IS_CONST == IS_VAR) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments "
+				"via dynamic class name; no defaults declared",
+				ZSTR_VAL(ce->name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		/* IS_UNUSED with no defaults: fall through with the bare ce. */
+	}
+
 	result = EX_VAR(opline->result.var);
 	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
 		ZVAL_UNDEF(result);
@@ -11078,7 +11635,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER(
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -11093,6 +11650,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
 			ZVAL_MAKE_REF_EX(expr_ptr, 2);
 		}
 
+
 	} else {
 		expr_ptr = RT_CONSTANT(opline, opline->op1);
 		if (IS_CONST == IS_TMP_VAR) {
@@ -11140,7 +11698,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
 		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -11165,6 +11737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -11174,7 +11747,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -11196,7 +11769,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_H
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varname;
@@ -11219,6 +11792,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA
 		name = zval_try_get_tmp_string(varname, &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	}
@@ -11230,11 +11804,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA
 		zend_tmp_string_release(tmp_name);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -11258,6 +11833,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U
 		zend_tmp_string_release(tmp_name);
 	}
 
+
 	if (!value) {
 		result = (opline->extended_value & ZEND_ISEMPTY);
 	} else {
@@ -11277,8 +11853,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U
 	ZEND_VM_SMART_BRANCH(result, true);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -11335,6 +11911,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = RT_CONSTANT(opline, opline->op1);
@@ -11350,6 +11927,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
 			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_CONST == IS_CV) {
@@ -11370,6 +11948,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -11397,7 +11976,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op;
@@ -11408,7 +11987,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -11440,7 +12019,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -11460,10 +12041,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_
 
 	ZVAL_LONG(EX_VAR(opline->result.var), count);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -11502,11 +12084,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CO
 			break;
 		}
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -11521,10 +12104,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CON
 		ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_array *ht;
@@ -11601,7 +12185,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE
 }
 
 /* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -11657,7 +12241,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_PARENT_PROPERTY_HOOK_CALL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -11668,10 +12252,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND
 	div_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -11682,10 +12268,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CV_HANDLER(ZEND
 	pow_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -11758,11 +12346,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z
 		concat_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -11773,23 +12363,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLE
 	compare_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 	dim = EX_VAR(opline->op2.var);
 	if (IS_CONST != IS_CONST) {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 fetch_dim_r_array:
 			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC);
 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		} else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
 			container = Z_REFVAL_P(container);
 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 				goto fetch_dim_r_array;
@@ -11808,23 +12404,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HAND
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
 	zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -11839,11 +12441,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
 		if (IS_CV == IS_UNUSED) {
 			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
 		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -11851,11 +12459,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_CONST == IS_CONST ||
 	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -11929,6 +12541,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
@@ -12008,10 +12622,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_
 fetch_obj_r_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -12019,6 +12635,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 
 	SAVE_OPLINE();
 	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_CONST == IS_CONST ||
 	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -12129,10 +12747,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC
 fetch_obj_is_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -12145,11 +12765,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_AR
 		}
 		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
+		if (IS_CONST == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
 		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -12158,10 +12784,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CV_HAN
 	container = RT_CONSTANT(opline, opline->op1);
 	zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -12283,10 +12910,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -12317,12 +12946,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 
 
+
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -12355,6 +12987,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 					if (UNEXPECTED(EG(exception) != NULL)) {
 						if (IS_CV != IS_CONST) {
 
+
 						}
 						HANDLE_EXCEPTION();
 					}
@@ -12365,6 +12998,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 				zend_invalid_method_call(object, function_name);
 
 
+
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -12389,6 +13024,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
 			}
 
+
 			if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
 				zend_objects_store_del(orig_obj);
 			}
@@ -12412,6 +13048,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 
 	if (IS_CV != IS_CONST) {
 
+
 	}
 
 	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
@@ -12441,7 +13078,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -12459,6 +13096,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_CV != IS_CONST) {
@@ -12469,6 +13107,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -12501,6 +13140,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -12516,6 +13156,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_CV == IS_CONST &&
@@ -12528,6 +13169,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 		}
 		if (IS_CV != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -12574,7 +13216,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -12596,6 +13238,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
 		 * to make sure we don't increase VM size too much. */
 		if (!(IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
 
+
 			HANDLE_EXCEPTION();
 		}
 
@@ -12618,6 +13261,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
 			call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
 		}
 
+
 		if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
 			if (call_info & ZEND_CALL_CLOSURE) {
 				zend_object_release(ZEND_CLOSURE_OBJECT(func));
@@ -12634,6 +13278,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
 		zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error);
 		efree(error);
 
+
 		HANDLE_EXCEPTION();
 	}
 
@@ -12645,7 +13290,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -12660,6 +13305,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 			ZVAL_MAKE_REF_EX(expr_ptr, 2);
 		}
 
+
 	} else {
 		expr_ptr = RT_CONSTANT(opline, opline->op1);
 		if (IS_CONST == IS_TMP_VAR) {
@@ -12707,7 +13353,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -12732,6 +13392,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -12741,7 +13402,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -12763,7 +13424,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDL
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -12814,6 +13475,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
 			if (IS_CONST & (IS_CONST|IS_CV)) {
 				/* avoid exception check */
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		} else {
@@ -12839,10 +13501,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
 isset_dim_obj_exit:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -12889,10 +13553,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO
 isset_object_finish:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -12921,10 +13587,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV
 	}
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -12981,6 +13649,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = RT_CONSTANT(opline, opline->op1);
@@ -12996,6 +13665,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
 			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_CONST == IS_CV) {
@@ -13016,6 +13686,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -13043,7 +13714,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_NOT_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -13054,10 +13725,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_not_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -13067,7 +13738,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_LONG_SPE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -13077,7 +13748,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_S
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -13087,7 +13758,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SP
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13122,10 +13793,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVARCV_
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13160,10 +13831,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVARCV_
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13201,10 +13872,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVARCV_CONST_HANDLE
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MOD_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13228,10 +13899,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVARCV_CONST_HANDLE
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13249,10 +13920,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVARCV_CONST_HANDLER
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13268,10 +13939,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVARCV_CONST_HANDLER
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13311,10 +13982,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13354,10 +14025,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TM
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13397,10 +14068,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TM
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13444,10 +14115,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13491,10 +14162,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13538,10 +14209,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_OR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13556,10 +14227,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVARC
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_AND_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13574,10 +14245,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13592,10 +14263,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -13604,10 +14275,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CON
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op, *jump_zv;
@@ -13635,7 +14307,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONS
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op, *jump_zv;
@@ -13668,7 +14340,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_TMPVARCV_CO
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MATCH_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op, *jump_zv;
@@ -13709,7 +14381,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_SPEC_TMPVARCV_CONST_HAND
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13721,7 +14393,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13733,7 +14405,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_TMPV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13745,7 +14417,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_TM
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13757,7 +14429,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13769,7 +14441,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13781,7 +14453,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TM
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13793,7 +14465,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13807,7 +14479,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_TMPV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -13819,7 +14491,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_TM
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13831,7 +14503,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CO
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13843,7 +14515,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13855,7 +14527,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13867,7 +14539,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13879,7 +14551,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SP
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13891,7 +14563,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SP
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13903,7 +14575,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARC
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13915,7 +14587,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13927,7 +14599,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13939,7 +14611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVA
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13951,7 +14623,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBL
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -13963,7 +14635,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBL
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -13973,10 +14645,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_
 	result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0;
 	FREE_OP(opline->op1_type, opline->op1.var);
 
+
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -13986,10 +14659,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_
 	result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0;
 	FREE_OP(opline->op1_type, opline->op1.var);
 
+
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -13999,10 +14673,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_
 	result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0;
 	FREE_OP(opline->op1_type, opline->op1.var);
 
+
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -14012,10 +14687,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_S
 	result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0;
 	FREE_OP(opline->op1_type, opline->op1.var);
 
+
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -14025,10 +14701,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_S
 	result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0;
 	FREE_OP(opline->op1_type, opline->op1.var);
 
+
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -14038,10 +14715,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_S
 	result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0;
 	FREE_OP(opline->op1_type, opline->op1.var);
 
+
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14053,7 +14731,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14065,7 +14743,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SP
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14077,7 +14755,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SP
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14089,7 +14767,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARC
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14101,7 +14779,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14113,7 +14791,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14125,7 +14803,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14137,7 +14815,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14149,7 +14827,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14161,7 +14839,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPE
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14173,7 +14851,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14185,7 +14863,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14220,10 +14898,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVARCV_
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14258,10 +14936,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVARCV_
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14299,10 +14977,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_HAN
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14326,10 +15004,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_HAN
 		}
 	}
 
-	ZEND_VM_TAIL_CALL(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14347,10 +15025,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVARCV_TMPVARCV_HAND
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14366,10 +15044,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVARCV_TMPVARCV_HAND
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14409,10 +15087,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVA
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14452,10 +15130,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TM
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14495,10 +15173,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TM
 			goto is_smaller_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14542,10 +15220,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14589,10 +15267,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14636,10 +15314,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 			goto is_smaller_or_equal_double;
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14654,10 +15332,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVARC
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14672,10 +15350,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14690,10 +15368,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14705,7 +15383,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14717,7 +15395,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_TMPV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14729,7 +15407,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_TM
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14741,7 +15419,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14753,7 +15431,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14765,7 +15443,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TM
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14777,7 +15455,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14791,7 +15469,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_TMPV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2, *result;
@@ -14803,7 +15481,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_TM
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14815,7 +15493,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TM
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14827,7 +15505,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14839,7 +15517,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14851,7 +15529,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14863,7 +15541,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SP
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14875,7 +15553,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SP
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14887,7 +15565,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARC
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14899,7 +15577,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14911,7 +15589,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14923,7 +15601,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVA
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14935,7 +15613,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBL
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14947,7 +15625,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBL
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14959,7 +15637,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14971,7 +15649,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SP
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14983,7 +15661,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SP
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -14995,7 +15673,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARC
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15007,7 +15685,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15019,7 +15697,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15031,7 +15709,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15043,7 +15721,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15055,7 +15733,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15067,7 +15745,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPE
 	ZEND_VM_SMART_BRANCH_NONE(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15079,7 +15757,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -15091,19 +15769,19 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUA
 	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op;
@@ -15114,7 +15792,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUS
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -15123,204 +15801,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *val;
-
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
-		ZVAL_FALSE(EX_VAR(opline->result.var));
-	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
-		/* The result and op1 can be the same cv zval */
-		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
-		ZVAL_TRUE(EX_VAR(opline->result.var));
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		}
-	} else {
-		SAVE_OPLINE();
-		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-	}
-	ZEND_VM_NEXT_OPCODE();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *z;
-
-	SAVE_OPLINE();
-	z = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (Z_TYPE_P(z) == IS_STRING) {
-		zend_string *str = Z_STR_P(z);
-
-		if (ZSTR_LEN(str) != 0) {
-			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
-		}
-	} else {
-		zend_string *str = zval_get_string_func(z);
-
-		if (ZSTR_LEN(str) != 0) {
-			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
-		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-		zend_string_release_ex(str, 0);
-	}
 
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *val;
-	uint8_t op1_type;
-
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
-		ZEND_VM_NEXT_OPCODE();
-	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			}
-		}
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-	}
-
-	SAVE_OPLINE();
-	op1_type = (IS_TMP_VAR|IS_VAR);
-	if (i_zend_is_true(val)) {
-		opline++;
-	} else {
-		opline = OP_JMP_ADDR(opline, opline->op2);
-	}
-	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
-		zval_ptr_dtor_nogc(val);
-	}
-	ZEND_VM_JMP(opline);
-}
-
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *val;
-	uint8_t op1_type;
-
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			}
-		}
-		ZEND_VM_NEXT_OPCODE();
-	}
-
-	SAVE_OPLINE();
-	op1_type = (IS_TMP_VAR|IS_VAR);
-	if (i_zend_is_true(val)) {
-		opline = OP_JMP_ADDR(opline, opline->op2);
-	} else {
-		opline++;
-	}
-	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
-		zval_ptr_dtor_nogc(val);
-	}
-	ZEND_VM_JMP(opline);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *val;
-	bool ret;
-
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
-		ZVAL_TRUE(EX_VAR(opline->result.var));
-		ZEND_VM_NEXT_OPCODE();
-	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
-		ZVAL_FALSE(EX_VAR(opline->result.var));
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			}
-		}
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-	}
-
-	SAVE_OPLINE();
-	ret = i_zend_is_true(val);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	if (ret) {
-		ZVAL_TRUE(EX_VAR(opline->result.var));
-		opline++;
-	} else {
-		ZVAL_FALSE(EX_VAR(opline->result.var));
-		opline = OP_JMP_ADDR(opline, opline->op2);
-	}
-	ZEND_VM_JMP(opline);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *val;
-	bool ret;
-
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
-		ZVAL_TRUE(EX_VAR(opline->result.var));
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
-		ZVAL_FALSE(EX_VAR(opline->result.var));
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		} else {
-			ZEND_VM_NEXT_OPCODE();
-		}
-	}
-
-	SAVE_OPLINE();
-	ret = i_zend_is_true(val);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	if (ret) {
-		ZVAL_TRUE(EX_VAR(opline->result.var));
-		opline = OP_JMP_ADDR(opline, opline->op2);
-	} else {
-		ZVAL_FALSE(EX_VAR(opline->result.var));
-		opline++;
-	}
-	ZEND_VM_JMP(opline);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -15329,7 +15814,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *var;
 	USE_OPLINE
@@ -15354,1044 +15839,595 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FREE_SPEC_TMPVA
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value;
+	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	do {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
-				value = Z_REFVAL_P(value);
-				if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
-					break;
-				}
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = RT_CONSTANT(opline, opline->op2);
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
 			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP1();
-				if (UNEXPECTED(EG(exception) != NULL)) {
-					HANDLE_EXCEPTION();
-				}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
 			}
-			zend_throw_error(NULL, "Can only throw objects");
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 		}
-	} while (0);
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+	}
+
 
-	zend_exception_save();
-	Z_TRY_ADDREF_P(value);
-	zend_throw_exception_object(value);
-	zend_exception_restore();
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	HANDLE_EXCEPTION();
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *val;
+	zval *container;
 
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
-		ZVAL_TRUE(EX_VAR(opline->result.var));
-	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
-		/* The result and op1 can be the same cv zval */
-		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
-		ZVAL_FALSE(EX_VAR(opline->result.var));
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		}
-	} else {
-		SAVE_OPLINE();
-		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-	}
-	ZEND_VM_NEXT_OPCODE();
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *obj;
-	zend_object *zobj;
-	zend_class_entry *ce, *scope;
-	zend_function *clone;
-	zend_object_clone_obj_t clone_call;
+	zval *container;
+	void **cache_slot = NULL;
 
 	SAVE_OPLINE();
-	obj = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
-	do {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-		    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
-				obj = Z_REFVAL_P(obj);
-				if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
 				}
 			}
-			ZVAL_UNDEF(EX_VAR(opline->result.var));
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP1();
-				if (UNEXPECTED(EG(exception) != NULL)) {
-					HANDLE_EXCEPTION();
-				}
 			}
-			zend_throw_error(NULL, "__clone method called on non-object");
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
-		}
-	} while (0);
-
-	zobj = Z_OBJ_P(obj);
-	ce = zobj->ce;
-	clone = ce->clone;
-	clone_call = zobj->handlers->clone_obj;
-	if (UNEXPECTED(clone_call == NULL)) {
-		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZVAL_UNDEF(EX_VAR(opline->result.var));
-		HANDLE_EXCEPTION();
+			zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
 	}
 
-	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
-		scope = EX(func)->op_array.scope;
-		if (clone->common.scope != scope) {
-			if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
-			 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
-				zend_wrong_clone_call(clone, scope);
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
-			}
-		}
-	}
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
 
-	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
 
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zend_op_array *new_op_array;
-	zval *inc_filename;
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
 
-	SAVE_OPLINE();
-	inc_filename = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
-	if (UNEXPECTED(EG(exception) != NULL)) {
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
-			destroy_op_array(new_op_array);
-			efree_size(new_op_array, sizeof(zend_op_array));
-		}
-		UNDEF_RESULT();
-		HANDLE_EXCEPTION();
-	} else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
-		if (RETURN_VALUE_USED(opline)) {
-			ZVAL_TRUE(EX_VAR(opline->result.var));
-		}
-	} else if (UNEXPECTED(new_op_array == NULL)) {
-		if (RETURN_VALUE_USED(opline)) {
-			ZVAL_FALSE(EX_VAR(opline->result.var));
-		}
-	} else if (new_op_array->last == 1
-			&& new_op_array->opcodes[0].opcode == ZEND_RETURN
-			&& new_op_array->opcodes[0].op1_type == IS_CONST
-			&& EXPECTED(zend_execute_ex == execute_ex)) {
-		if (RETURN_VALUE_USED(opline)) {
-			const zend_op *op = new_op_array->opcodes;
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if ((IS_TMP_VAR|IS_VAR) & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
 
-			ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1));
-		}
-		zend_destroy_static_vars(new_op_array);
-		destroy_op_array(new_op_array);
-		efree_size(new_op_array, sizeof(zend_op_array));
-	} else {
-		zval *return_value = NULL;
-		zend_execute_data *call;
-		if (RETURN_VALUE_USED(opline)) {
-			return_value = EX_VAR(opline->result.var);
-		}
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
 
-		new_op_array->scope = EX(func)->op_array.scope;
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
 
-		call = zend_vm_stack_push_call_frame(
-			(Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
-			(zend_function*)new_op_array, 0,
-			Z_PTR(EX(This)));
 
-		if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
-			call->symbol_table = EX(symbol_table);
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
 		} else {
-			call->symbol_table = zend_rebuild_symbol_table();
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
 		}
 
-		call->prev_execute_data = execute_data;
-		i_init_code_execute_data(call, new_op_array, return_value);
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
 
-		if (EXPECTED(zend_execute_ex == execute_ex)) {
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			ZEND_VM_ENTER();
-		} else {
-			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
-			zend_execute_ex(call);
-			zend_vm_stack_free_call_frame(call);
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
 		}
 
-		zend_destroy_static_vars(new_op_array);
-		destroy_op_array(new_op_array);
-		efree_size(new_op_array, sizeof(zend_op_array));
-		if (UNEXPECTED(EG(exception) != NULL)) {
-			zend_rethrow_exception(execute_data);
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			UNDEF_RESULT();
-			HANDLE_EXCEPTION();
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
 		}
-	}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE();
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
-	zval *val;
+	zval *container;
+	void **cache_slot = NULL;
 
 	SAVE_OPLINE();
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		UNDEF_RESULT();
-		HANDLE_EXCEPTION();
-	}
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
-yield_from_try_again:
-	if (Z_TYPE_P(val) == IS_ARRAY) {
-		ZVAL_COPY_VALUE(&generator->values, val);
-		if (Z_OPT_REFCOUNTED_P(val)) {
-			Z_ADDREF_P(val);
-		}
-		Z_FE_POS(generator->values) = 0;
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
-		zend_class_entry *ce = Z_OBJCE_P(val);
-		if (ce == zend_ce_generator) {
-			zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val);
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
 
-			Z_ADDREF_P(val);
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
 
-			if (UNEXPECTED(new_gen->execute_data == NULL)) {
-				zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
-				zval_ptr_dtor(val);
-				UNDEF_RESULT();
-				HANDLE_EXCEPTION();
-			} else if (Z_ISUNDEF(new_gen->retval)) {
-				if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) {
-					zend_throw_error(NULL, "Impossible to yield from the Generator being currently run");
-					zval_ptr_dtor(val);
-					UNDEF_RESULT();
-					HANDLE_EXCEPTION();
-				} else {
-					zend_generator_yield_from(generator, new_gen);
-				}
-			} else {
-				if (RETURN_VALUE_USED(opline)) {
-					ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval);
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
 				}
-				ZEND_VM_NEXT_OPCODE();
 			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
 		} else {
-			zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
-			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
-				if (!EG(exception)) {
-					zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
-				}
-				UNDEF_RESULT();
-				HANDLE_EXCEPTION();
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
 			}
+		}
 
-			iter->index = 0;
-			if (iter->funcs->rewind) {
-				iter->funcs->rewind(iter);
-				if (UNEXPECTED(EG(exception) != NULL)) {
-					OBJ_RELEASE(&iter->std);
-					UNDEF_RESULT();
-					HANDLE_EXCEPTION();
-				}
-			}
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
 
-			ZVAL_OBJ(&generator->values, &iter->std);
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
 		}
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) {
-		val = Z_REFVAL_P(val);
-		goto yield_from_try_again;
-	} else {
-		zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		UNDEF_RESULT();
-		HANDLE_EXCEPTION();
-	}
 
-	/* This is the default return value
-	 * when the expression is a Generator, it will be overwritten in zend_generator_resume() */
-	if (RETURN_VALUE_USED(opline)) {
-		ZVAL_NULL(EX_VAR(opline->result.var));
-	}
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
 
-	/* This generator has no send target (though the generator we delegate to might have one) */
-	generator->send_target = NULL;
+fetch_obj_is_finish:
 
-	/* The GOTO VM uses a local opline variable. We need to set the opline
-	 * variable in execute_data so we don't resume at an old position. */
-	SAVE_OPLINE();
 
-	ZEND_VM_RETURN();
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value;
+	zval *value, *arg;
 
-	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
-		ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
-		if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-			zval_ptr_dtor_str(value);
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
 		}
-		ZEND_VM_NEXT_OPCODE();
 	} else {
-		bool strict;
-
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
-			value = Z_REFVAL_P(value);
-			if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
-				ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_NEXT_OPCODE();
-			}
-		}
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
 
-		SAVE_OPLINE();
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-			value = ZVAL_UNDEFINED_OP1();
+	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
 		}
-		strict = EX_USES_STRICT_TYPES();
-		do {
-			if (EXPECTED(!strict)) {
-				zend_string *str;
-				zval tmp;
-
-				if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
-					zend_error(E_DEPRECATED,
-						"strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
-					ZVAL_LONG(EX_VAR(opline->result.var), 0);
-					if (UNEXPECTED(EG(exception))) {
-						HANDLE_EXCEPTION();
-					}
-					break;
-				}
-
-				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
-					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
-					zval_ptr_dtor(&tmp);
-					break;
-				}
-				zval_ptr_dtor(&tmp);
-			}
-			if (!EG(exception)) {
-				zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value));
-			}
-			ZVAL_UNDEF(EX_VAR(opline->result.var));
-		} while (0);
 	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value;
-	int result = 0;
+	zval *container, *dim, *value;
+	zend_long offset;
+	HashTable *ht;
 
-	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
-type_check_resource:
-		if (opline->extended_value != MAY_BE_RESOURCE
-		 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
-			result = 1;
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	dim = RT_CONSTANT(opline, opline->op2);
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+			offset = Z_LVAL_P(dim);
+		} else {
+			SAVE_OPLINE();
+			zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) {
-		value = Z_REFVAL_P(value);
-		if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
-			goto type_check_resource;
+		ht = Z_ARRVAL_P(container);
+		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			SAVE_OPLINE();
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
 		}
-	} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-		result = ((1 << IS_NULL) & opline->extended_value) != 0;
-		SAVE_OPLINE();
-		ZVAL_UNDEFINED_OP1();
-		if (UNEXPECTED(EG(exception))) {
-			ZVAL_UNDEF(EX_VAR(opline->result.var));
-			HANDLE_EXCEPTION();
+	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto fetch_dim_r_index_array;
+		} else {
+			goto fetch_dim_r_index_slow;
 		}
-	}
-	if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+	} else {
+fetch_dim_r_index_slow:
 		SAVE_OPLINE();
+		if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim++;
+		}
+		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_SMART_BRANCH(result, 1);
-	} else {
-		ZEND_VM_SMART_BRANCH(result, 0);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
+
+fetch_dim_r_index_undef:
+	ZVAL_NULL(EX_VAR(opline->result.var));
+	SAVE_OPLINE();
+	zend_undefined_offset(offset);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	uint32_t fetch_type;
-	zend_class_entry *called_scope, *scope;
 	USE_OPLINE
+	zval *container, *dim, *value;
+	zend_long offset;
+	HashTable *ht;
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	dim = EX_VAR(opline->op2.var);
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+			offset = Z_LVAL_P(dim);
+		} else {
+			SAVE_OPLINE();
+			zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		ht = Z_ARRVAL_P(container);
+		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			SAVE_OPLINE();
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto fetch_dim_r_index_array;
+		} else {
+			goto fetch_dim_r_index_slow;
+		}
+	} else {
+fetch_dim_r_index_slow:
 		SAVE_OPLINE();
-		zval *op = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-		if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) {
-			ZVAL_DEREF(op);
-			if (Z_TYPE_P(op) != IS_OBJECT) {
-				zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op));
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				HANDLE_EXCEPTION();
-			}
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim++;
 		}
-
-		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name);
+		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 
-	fetch_type = opline->op1.num;
-	scope = EX(func)->op_array.scope;
-	if (UNEXPECTED(scope == NULL)) {
-		SAVE_OPLINE();
-		zend_throw_error(NULL, "Cannot use \"%s\" in the global scope",
-			fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
-			fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
-		ZVAL_UNDEF(EX_VAR(opline->result.var));
-		HANDLE_EXCEPTION();
-	}
-
-	switch (fetch_type) {
-		case ZEND_FETCH_CLASS_SELF:
-			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
-			break;
-		case ZEND_FETCH_CLASS_PARENT:
-			if (UNEXPECTED(scope->parent == NULL)) {
-				SAVE_OPLINE();
-				zend_throw_error(NULL,
-					"Cannot use \"parent\" when current class scope has no parent");
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
-			}
-			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
-			break;
-		case ZEND_FETCH_CLASS_STATIC:
-			if (Z_TYPE(EX(This)) == IS_OBJECT) {
-				called_scope = Z_OBJCE(EX(This));
-			} else {
-				called_scope = Z_CE(EX(This));
-			}
-			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
-			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
-	}
-	ZEND_VM_NEXT_OPCODE();
+fetch_dim_r_index_undef:
+	ZVAL_NULL(EX_VAR(opline->result.var));
+	SAVE_OPLINE();
+	zend_undefined_offset(offset);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
+	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	div_function(EX_VAR(opline->result.var), op1, op2);
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
+	zval *container;
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	pow_function(EX_VAR(opline->result.var), op1, op2);
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-
-	if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
-		zend_string *op1_str = Z_STR_P(op1);
-		zend_string *op2_str = Z_STR_P(op2);
-		zend_string *str;
-		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+	zval *container;
+	void **cache_slot = NULL;
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
-		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
-			size_t len = ZSTR_LEN(op1_str);
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
-			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
-				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
-			}
-			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else {
-			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
 			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
+			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
 			}
-		}
-		ZEND_VM_NEXT_OPCODE();
-	} else {
-		SAVE_OPLINE();
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			op1 = ZVAL_UNDEFINED_OP1();
-		}
-		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
-			op2 = ZVAL_UNDEFINED_OP2();
-		}
-		concat_function(EX_VAR(opline->result.var), op1, op2);
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
 
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-	}
-}
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-is_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_NONE();
-			} else {
-is_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_NONE();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_equal_double:
-			if (d1 == d2) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (result) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
-			}
-		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-is_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
-			} else {
-is_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_equal_double:
-			if (d1 == d2) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (result) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
-			}
-		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-is_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
-			} else {
-is_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_equal_double:
-			if (d1 == d2) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (result) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
-			}
-		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
-is_not_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_NONE();
-			} else {
-is_not_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_NONE();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_not_equal_double:
-			if (d1 != d2) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (!result) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
-is_not_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
-			} else {
-is_not_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_not_equal_double:
-			if (d1 != d2) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (!result) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
-is_not_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
-			} else {
-is_not_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_not_equal_double:
-			if (d1 != d2) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (!result) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	compare_function(EX_VAR(opline->result.var), op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *container, *dim, *value;
-
-	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	dim = RT_CONSTANT(opline, opline->op2);
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-fetch_dim_r_array:
-			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC);
-			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
-			container = Z_REFVAL_P(container);
-			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-				goto fetch_dim_r_array;
-			} else {
-				goto fetch_dim_r_slow;
-			}
-		} else {
-fetch_dim_r_slow:
-			if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
-		}
-	} else {
-		zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
-	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *container;
-
-	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *container;
-	void **cache_slot = NULL;
-
-	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-				container = Z_REFVAL_P(container);
-				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-					break;
-				}
-			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP1();
-			}
-			zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2));
-			ZVAL_NULL(EX_VAR(opline->result.var));
-			goto fetch_obj_r_finish;
-		} while (0);
-	}
-
-	/* here we are sure we are dealing with an object */
-	do {
-		zend_object *zobj = Z_OBJ_P(container);
-		zend_string *name, *tmp_name;
-		zval *retval;
-
-		if (IS_CONST == IS_CONST) {
-			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
-
-			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
-				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
 
 				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
 fetch_obj_r_simple:
@@ -16440,12 +16476,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -16478,9 +16516,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_
 					}
 				}
 			}
-			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -16504,7 +16542,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_
 		}
 #endif
 
-		if (IS_CONST != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -16517,12 +16555,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_
 	} while (0);
 
 fetch_obj_r_finish:
-
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -16530,6 +16568,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
 	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -16540,7 +16580,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
 					break;
 				}
 			}
-			if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
 				ZVAL_UNDEFINED_OP2();
 			}
 			ZVAL_NULL(EX_VAR(opline->result.var));
@@ -16554,7 +16594,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
 		zend_string *name, *tmp_name;
 		zval *retval;
 
-		if (IS_CONST == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			cache_slot = CACHE_ADDR(opline->extended_value);
 
 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
@@ -16581,7 +16621,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -16614,9 +16654,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
 					}
 				}
 			}
-			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -16625,7 +16665,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
 
 		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
 
-		if (IS_CONST != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -16638,2517 +16678,1896 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST
 	} while (0);
 
 fetch_obj_is_finish:
-
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	zend_string *op1_str, *op2_str, *str;
-
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
-		zend_string *op1_str = Z_STR_P(op1);
-		zend_string *op2_str = Z_STR_P(op2);
-		zend_string *str;
-		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
-
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
-		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
-			size_t len = ZSTR_LEN(op1_str);
+	zval *value, *arg;
 
-			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else {
-			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
 		}
-		ZEND_VM_NEXT_OPCODE();
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
 	}
 
-	SAVE_OPLINE();
+	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
 	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		op1_str = Z_STR_P(op1);
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		op1_str = zend_string_copy(Z_STR_P(op1));
-	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
 		}
-		op1_str = zval_get_string_func(op1);
 	}
-	if (IS_CONST == IS_CONST) {
-		op2_str = Z_STR_P(op2);
-	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-		op2_str = zend_string_copy(Z_STR_P(op2));
-	} else {
-		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP2();
-		}
-		op2_str = zval_get_string_func(op2);
-	}
-	do {
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-				if (IS_CONST == IS_CONST) {
-					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
-						GC_ADDREF(op2_str);
-					}
-				}
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-				zend_string_release_ex(op1_str, 0);
-				break;
-			}
-		}
-		if (IS_CONST != IS_CONST) {
-			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
-						GC_ADDREF(op1_str);
-					}
-				}
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
-				zend_string_release_ex(op2_str, 0);
-				break;
-			}
-		}
-		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-
-		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
-		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			zend_string_release_ex(op1_str, 0);
-		}
-		if (IS_CONST != IS_CONST) {
-			zend_string_release_ex(op2_str, 0);
-		}
-	} while (0);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *function_name;
-	zval *object;
-	zend_function *fbc;
-	zend_class_entry *called_scope;
-	zend_object *obj;
-	zend_execute_data *call;
-	uint32_t call_info;
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
 
 	SAVE_OPLINE();
 
-	object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (IS_CONST != IS_CONST) {
-		function_name = RT_CONSTANT(opline, opline->op2);
-	}
-
-	if (IS_CONST != IS_CONST &&
-	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
-		do {
-			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
-				function_name = Z_REFVAL_P(function_name);
-				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
-					break;
-				}
-			} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP2();
-				if (UNEXPECTED(EG(exception) != NULL)) {
-					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-					HANDLE_EXCEPTION();
-				}
-			}
-			zend_throw_error(NULL, "Method name must be a string");
-
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
-		} while (0);
-	}
-
-	if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-		obj = Z_OBJ_P(object);
-	} else {
-		do {
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
-				obj = Z_OBJ_P(object);
-			} else {
-				if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
-					zend_reference *ref = Z_REF_P(object);
-
-					object = &ref->val;
-					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
-						obj = Z_OBJ_P(object);
-						if ((IS_TMP_VAR|IS_VAR) & IS_VAR) {
-							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-								efree_size(ref, sizeof(zend_reference));
-							} else {
-								Z_ADDREF_P(object);
-							}
-						}
-						break;
-					}
-				}
-				if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
-					object = ZVAL_UNDEFINED_OP1();
-					if (UNEXPECTED(EG(exception) != NULL)) {
-						if (IS_CONST != IS_CONST) {
-
-						}
-						HANDLE_EXCEPTION();
-					}
-				}
-				if (IS_CONST == IS_CONST) {
-					function_name = RT_CONSTANT(opline, opline->op2);
-				}
-				zend_invalid_method_call(object, function_name);
-
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				HANDLE_EXCEPTION();
-			}
-		} while (0);
-	}
-
-	called_scope = obj->ce;
+	varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 
-	if (IS_CONST == IS_CONST &&
-	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
-		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
 	} else {
-		zend_object *orig_obj = obj;
-
-		if (IS_CONST == IS_CONST) {
-			function_name = RT_CONSTANT(opline, opline->op2);
+		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			varname = ZVAL_UNDEFINED_OP1();
 		}
-
-		/* First, locate the function. */
-		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
-		if (UNEXPECTED(fbc == NULL)) {
-			if (EXPECTED(!EG(exception))) {
-				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
-			}
-
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
-				zend_objects_store_del(orig_obj);
-			}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 			HANDLE_EXCEPTION();
 		}
-		if (IS_CONST == IS_CONST &&
-		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
-		    EXPECTED(obj == orig_obj)) {
-			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
-		}
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
-			GC_ADDREF(obj); /* For $this pointer */
-			if (GC_DELREF(orig_obj) == 0) {
-				zend_objects_store_del(orig_obj);
-			}
-		}
-		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
-			init_func_run_time_cache(&fbc->op_array);
-		}
 	}
 
-	if (IS_CONST != IS_CONST) {
-
-	}
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	zend_hash_del_ind(target_symbol_table, name);
 
-	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
-	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
-			zend_objects_store_del(obj);
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			}
-		}
-		/* call static method */
-		obj = (zend_object*)called_scope;
-		call_info = ZEND_CALL_NESTED_FUNCTION;
-	} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
-			GC_ADDREF(obj); /* For $this pointer */
-		}
-		/* CV may be changed indirectly (e.g. when it's a reference) */
-		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
 	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	call = zend_vm_stack_push_call_frame(call_info,
-		fbc, opline->extended_value, obj);
-	call->prev_execute_data = EX(call);
-	EX(call) = call;
-
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_COPY(result, value);
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value, *arg;
+	zval *container, *dim, *value;
 
-	if (IS_CONST == IS_CONST) {
-		SAVE_OPLINE();
-		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-		uint32_t arg_num;
-		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
-		if (UNEXPECTED(!arg)) {
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = EX_VAR(opline->op2.var);
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 		}
 	} else {
-		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
 	}
 
-	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	ZVAL_COPY_VALUE(arg, value);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
-			Z_ADDREF_P(arg);
-		}
-	}
-	ZEND_VM_NEXT_OPCODE();
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
+	zval *container;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-case_true:
-				ZEND_VM_SMART_BRANCH_TRUE();
-			} else {
-case_false:
-				ZEND_VM_SMART_BRANCH_FALSE();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto case_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-case_double:
-			if (d1 == d2) {
-				goto case_true;
-			} else {
-				goto case_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto case_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
-			if (result) {
-				goto case_true;
-			} else {
-				goto case_false;
-			}
-		}
-	}
-	ZEND_VM_TAIL_CALL(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
-	bool result;
-	zend_ulong hval;
-	zval *offset;
+	void **cache_slot = NULL;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = RT_CONSTANT(opline, opline->op2);
-
-	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-		HashTable *ht;
-		zval *value;
-		zend_string *str;
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
-isset_dim_obj_array:
-		ht = Z_ARRVAL_P(container);
-isset_again:
-		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
-			str = Z_STR_P(offset);
-			if (IS_CONST != IS_CONST) {
-				if (ZEND_HANDLE_NUMERIC(str, hval)) {
-					goto num_index_prop;
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
 				}
 			}
-			value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST);
-		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
-			hval = Z_LVAL_P(offset);
-num_index_prop:
-			value = zend_hash_index_find(ht, hval);
-		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
-			offset = Z_REFVAL_P(offset);
-			goto isset_again;
-		} else {
-			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
-			if (UNEXPECTED(EG(exception))) {
-				result = 0;
-				goto isset_dim_obj_exit;
+			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
 			}
-		}
+			zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
 
-		if (!(opline->extended_value & ZEND_ISEMPTY)) {
-			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
-			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
-			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
 
-			if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) {
-				/* avoid exception check */
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
 
-				ZEND_VM_SMART_BRANCH(result, 0);
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if ((IS_TMP_VAR|IS_VAR) & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
 			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			result = (value == NULL || !i_zend_is_true(value));
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
 		}
-		goto isset_dim_obj_exit;
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
-		container = Z_REFVAL_P(container);
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-			goto isset_dim_obj_array;
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
 		}
-	}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
 
-	if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
-		offset++;
-	}
-	if (!(opline->extended_value & ZEND_ISEMPTY)) {
-		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
-	} else {
-		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
-	}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
 
-isset_dim_obj_exit:
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
-	int result;
-	zval *offset;
-	zend_string *name, *tmp_name;
+	void **cache_slot = NULL;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = RT_CONSTANT(opline, opline->op2);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
 	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-			container = Z_REFVAL_P(container);
-			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
-				result = (opline->extended_value & ZEND_ISEMPTY);
-				goto isset_object_finish;
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
 			}
-		} else {
-			result = (opline->extended_value & ZEND_ISEMPTY);
-			goto isset_object_finish;
-		}
+			if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
 	}
 
-	if (IS_CONST == IS_CONST) {
-		name = Z_STR_P(offset);
-	} else {
-		name = zval_try_get_tmp_string(offset, &tmp_name);
-		if (UNEXPECTED(!name)) {
-			result = 0;
-			goto isset_object_finish;
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
 		}
-	}
 
-	result =
-		(opline->extended_value & ZEND_ISEMPTY) ^
-		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
 
-	if (IS_CONST != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
 
-isset_object_finish:
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
+	zval *val;
 
-	zval *key, *subject;
-	HashTable *ht;
-	bool result;
-
-	SAVE_OPLINE();
-
-	key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	subject = RT_CONSTANT(opline, opline->op2);
-
-	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-array_key_exists_array:
-		ht = Z_ARRVAL_P(subject);
-		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
-	} else {
-		if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
-			subject = Z_REFVAL_P(subject);
-			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-				goto array_key_exists_array;
-			}
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
-		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
-		result = 0;
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *expr;
-	bool result;
+	zval *z;
 
 	SAVE_OPLINE();
-	expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	z = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-try_instanceof:
-	if (Z_TYPE_P(expr) == IS_OBJECT) {
-		zend_class_entry *ce;
+	if (Z_TYPE_P(z) == IS_STRING) {
+		zend_string *str = Z_STR_P(z);
 
-		if (IS_CONST == IS_CONST) {
-			ce = CACHED_PTR(opline->extended_value);
-			if (UNEXPECTED(ce == NULL)) {
-				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
-				if (EXPECTED(ce)) {
-					CACHE_PTR(opline->extended_value, ce);
-				}
-			}
-		} else if (IS_CONST == IS_UNUSED) {
-			ce = zend_fetch_class(NULL, opline->op2.num);
-			if (UNEXPECTED(ce == NULL)) {
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
-			}
-		} else {
-			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
 		}
-		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
-		expr = Z_REFVAL_P(expr);
-		goto try_instanceof;
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+		zend_string *str = zval_get_string_func(z);
+
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
+		} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
 			ZVAL_UNDEFINED_OP1();
 		}
-		result = 0;
+		zend_string_release_ex(str, 0);
 	}
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container, *dim, *value;
-	zend_long offset;
-	HashTable *ht;
+	zval *val;
+	uint8_t op1_type;
 
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	dim = RT_CONSTANT(opline, opline->op2);
-	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-fetch_dim_r_index_array:
-		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
-			offset = Z_LVAL_P(dim);
-		} else {
-			SAVE_OPLINE();
-			zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		}
-		ht = Z_ARRVAL_P(container);
-		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
 			SAVE_OPLINE();
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		} else {
-			ZEND_VM_NEXT_OPCODE();
-		}
-	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
-		container = Z_REFVAL_P(container);
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-			goto fetch_dim_r_index_array;
-		} else {
-			goto fetch_dim_r_index_slow;
-		}
-	} else {
-fetch_dim_r_index_slow:
-		SAVE_OPLINE();
-		if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-			dim++;
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
 		}
-		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 	}
 
-fetch_dim_r_index_undef:
-	ZVAL_NULL(EX_VAR(opline->result.var));
 	SAVE_OPLINE();
-	zend_undefined_offset(offset);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	op1_type = IS_TMP_VAR;
+	if (i_zend_is_true(val)) {
+		opline++;
+	} else {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container, *dim, *value;
-	zend_long offset;
-	HashTable *ht;
+	zval *val;
+	uint8_t op1_type;
 
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	dim = EX_VAR(opline->op2.var);
-	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-fetch_dim_r_index_array:
-		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
-			offset = Z_LVAL_P(dim);
-		} else {
-			SAVE_OPLINE();
-			zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		}
-		ht = Z_ARRVAL_P(container);
-		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
 			SAVE_OPLINE();
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		} else {
-			ZEND_VM_NEXT_OPCODE();
-		}
-	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
-		container = Z_REFVAL_P(container);
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-			goto fetch_dim_r_index_array;
-		} else {
-			goto fetch_dim_r_index_slow;
-		}
-	} else {
-fetch_dim_r_index_slow:
-		SAVE_OPLINE();
-		if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-			dim++;
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
 		}
-		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		ZEND_VM_NEXT_OPCODE();
 	}
 
-fetch_dim_r_index_undef:
-	ZVAL_NULL(EX_VAR(opline->result.var));
 	SAVE_OPLINE();
-	zend_undefined_offset(offset);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	op1_type = IS_TMP_VAR;
+	if (i_zend_is_true(val)) {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		opline++;
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
+	zval *val;
+	bool ret;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	div_function(EX_VAR(opline->result.var), op1, op2);
+	ret = i_zend_is_true(val);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline++;
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	ZEND_VM_JMP(opline);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
+	zval *val;
+	bool ret;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	pow_function(EX_VAR(opline->result.var), op1, op2);
+	ret = i_zend_is_true(val);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline++;
+	}
+	ZEND_VM_JMP(opline);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
+	zval *retval_ptr;
+	zval *return_value;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
 
-	if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
-		zend_string *op1_str = Z_STR_P(op1);
-		zend_string *op2_str = Z_STR_P(op2);
-		zend_string *str;
-		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+	retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	return_value = EX(return_value);
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
-		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
-			size_t len = ZSTR_LEN(op1_str);
 
-			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
-				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
-			}
-			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else {
-			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
+	if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		retval_ptr = ZVAL_UNDEFINED_OP1();
+		if (return_value) {
+			ZVAL_NULL(return_value);
+		}
+	} else if (!return_value) {
+		if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) {
+			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
+				SAVE_OPLINE();
+				rc_dtor_func(Z_COUNTED_P(retval_ptr));
 			}
 		}
-		ZEND_VM_NEXT_OPCODE();
 	} else {
-		SAVE_OPLINE();
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZVAL_COPY_VALUE(return_value, retval_ptr);
+			if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+					Z_ADDREF_P(return_value);
+				}
+			}
+		} else if (IS_TMP_VAR == IS_CV) {
+			do {
+				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
+							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+							ZVAL_COPY_VALUE(return_value, retval_ptr);
+							if (GC_MAY_LEAK(ref)) {
+								SAVE_OPLINE();
+								gc_possible_root(ref);
+							}
+							ZVAL_NULL(retval_ptr);
+							break;
+						} else {
+							Z_ADDREF_P(retval_ptr);
+						}
+					} else {
+						retval_ptr = Z_REFVAL_P(retval_ptr);
+						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+							Z_ADDREF_P(retval_ptr);
+						}
+					}
+				}
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			} while (0);
+		} else /* if (IS_TMP_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			op1 = ZVAL_UNDEFINED_OP1();
-		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
-			op2 = ZVAL_UNDEFINED_OP2();
+				retval_ptr = Z_REFVAL_P(retval_ptr);
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					Z_ADDREF_P(retval_ptr);
+				}
+			} else {
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			}
 		}
-		concat_function(EX_VAR(opline->result.var), op1, op2);
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
+
+
+
+
+
+
+	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
+	zval *retval_ptr;
+	zval *return_value;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-is_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+
+	SAVE_OPLINE();
+
+	return_value = EX(return_value);
+
+
+	do {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) ||
+		    (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
+			/* Not supposed to happen, but we'll allow it */
+			zend_error(E_NOTICE, "Only variable references should be returned by reference");
+
+			retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+			if (!return_value) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 			} else {
-is_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+					ZVAL_COPY_VALUE(return_value, retval_ptr);
+					break;
+				}
+
+				ZVAL_NEW_REF(return_value, retval_ptr);
+				if (IS_TMP_VAR == IS_CONST) {
+					Z_TRY_ADDREF_P(retval_ptr);
+				}
 			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_equal_double;
+			break;
 		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_equal_double:
-			if (d1 == d2) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
+
+		retval_ptr = zend_get_bad_ptr();
+
+		if (IS_TMP_VAR == IS_VAR) {
+			ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
+			if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
+				zend_error(E_NOTICE, "Only variable references should be returned by reference");
+				if (return_value) {
+					ZVAL_NEW_REF(return_value, retval_ptr);
+				} else {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				}
+				break;
 			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_equal_double;
 		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (result) {
-				goto is_equal_true;
+
+		if (return_value) {
+			if (Z_ISREF_P(retval_ptr)) {
+				Z_ADDREF_P(retval_ptr);
 			} else {
-				goto is_equal_false;
+				ZVAL_MAKE_REF_EX(retval_ptr, 2);
 			}
+			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
 		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} while (0);
+
+
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
+	zval *retval;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-is_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
-			} else {
-is_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_equal_double:
-			if (d1 == d2) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	retval = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	/* Copy return value into generator->retval */
+	if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+		ZVAL_COPY_VALUE(&generator->retval, retval);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
+				Z_ADDREF(generator->retval);
 			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_equal_double;
 		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (result) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
+	} else if (IS_TMP_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(&generator->retval, retval);
+	} else /* if (IS_TMP_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_refcounted *ref = Z_COUNTED_P(retval);
+
+			retval = Z_REFVAL_P(retval);
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(retval)) {
+				Z_ADDREF_P(retval);
 			}
+		} else {
+			ZVAL_COPY_VALUE(&generator->retval, retval);
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+
+
+	EG(current_execute_data) = EX(prev_execute_data);
+
+	/* Close the generator to free up resources */
+	zend_generator_close(generator, 1);
+
+	/* Pass execution back to handling code */
+	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
+	zval *value;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-is_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
-			} else {
-is_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_equal_double:
-			if (d1 == d2) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+				if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+					break;
+				}
 			}
-			if (result) {
-				goto is_equal_true;
-			} else {
-				goto is_equal_false;
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
 			}
+			zend_throw_error(NULL, "Can only throw objects");
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
 		}
-	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	} while (0);
+
+	Z_TRY_ADDREF_P(value);
+	zend_throw_exception_object(value);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
+	zval *arg, *param;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
-is_not_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_NONE();
-			} else {
-is_not_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_NONE();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_not_equal_double:
-			if (d1 != d2) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (!result) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		}
+	SAVE_OPLINE();
+
+	arg = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	param = ZEND_CALL_VAR(EX(call), opline->result.var);
+	if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
+		zend_param_must_be_ref(EX(call)->func, opline->op2.num);
+		Z_TRY_ADDREF_P(arg);
+		ZVAL_NEW_REF(param, arg);
+	} else {
+		ZVAL_COPY(param, arg);
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
+	zval *val;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
-is_not_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
-			} else {
-is_not_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_not_equal_double:
-			if (d1 != d2) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (!result) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
+	zval *obj;
+	zend_object *zobj;
+	zend_class_entry *ce, *scope;
+	zend_function *clone;
+	zend_object_clone_obj_t clone_call;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		/* pass */
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
-is_not_equal_true:
-				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
-			} else {
-is_not_equal_false:
-				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+	SAVE_OPLINE();
+	obj = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
+	do {
+		if (IS_TMP_VAR == IS_CONST ||
+		    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
+				obj = Z_REFVAL_P(obj);
+				if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
+					break;
+				}
 			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto is_not_equal_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-is_not_equal_double:
-			if (d1 != d2) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
 			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto is_not_equal_double;
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
 		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op1);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zval_ptr_dtor_str(op2);
-			}
-			if (!result) {
-				goto is_not_equal_true;
-			} else {
-				goto is_not_equal_false;
-			}
+	} while (0);
+
+	zobj = Z_OBJ_P(obj);
+	ce = zobj->ce;
+	clone = ce->clone;
+	clone_call = zobj->handlers->clone_obj;
+	if (UNEXPECTED(clone_call == NULL)) {
+		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+		scope = EX(func)->op_array.scope;
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
-}
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
+	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
 
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	compare_function(EX_VAR(opline->result.var), op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
+	zval *expr;
+	zval *result = EX_VAR(opline->result.var);
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *container, *dim, *value;
+	switch (opline->extended_value) {
+		case IS_LONG:
+			ZVAL_LONG(result, zval_get_long(expr));
+			break;
+		case IS_DOUBLE:
+			ZVAL_DOUBLE(result, zval_get_double(expr));
+			break;
+		case IS_STRING:
+			ZVAL_STR(result, zval_get_string(expr));
+			break;
+		default:
+			ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead");
+			if (IS_TMP_VAR & (IS_VAR|IS_CV)) {
+				ZVAL_DEREF(expr);
+			}
+			/* If value is already of correct type, return it directly */
+			if (Z_TYPE_P(expr) == opline->extended_value) {
+				ZVAL_COPY_VALUE(result, expr);
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+				} else if (IS_TMP_VAR != IS_TMP_VAR) {
+					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+				}
 
-	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-fetch_dim_r_array:
-			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC);
-			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
-			container = Z_REFVAL_P(container);
-			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-				goto fetch_dim_r_array;
-			} else {
-				goto fetch_dim_r_slow;
+
+				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 			}
-		} else {
-fetch_dim_r_slow:
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
+
+			if (opline->extended_value == IS_ARRAY) {
+				zend_cast_zval_to_array(result, expr, IS_TMP_VAR);
+			} else {
+				ZEND_ASSERT(opline->extended_value == IS_OBJECT);
+				zend_cast_zval_to_object(result, expr, IS_TMP_VAR);
 			}
-			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
-		}
-	} else {
-		zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
 	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *container;
 
-	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container;
-	void **cache_slot = NULL;
+	zend_op_array *new_op_array;
+	zval *inc_filename;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-				container = Z_REFVAL_P(container);
-				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-					break;
-				}
-			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP1();
-			}
-			zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-			ZVAL_NULL(EX_VAR(opline->result.var));
-			goto fetch_obj_r_finish;
-		} while (0);
-	}
-
-	/* here we are sure we are dealing with an object */
-	do {
-		zend_object *zobj = Z_OBJ_P(container);
-		zend_string *name, *tmp_name;
-		zval *retval;
-
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
-
-			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
-				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-
-				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-fetch_obj_r_simple:
-					retval = OBJ_PROP(zobj, prop_offset);
-					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_r_copy;
-						} else {
-fetch_obj_r_fast_copy:
-							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-							ZEND_VM_NEXT_OPCODE();
-						}
-					}
-				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
-					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
-					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
-						prop_offset = prop_info->offset;
-						goto fetch_obj_r_simple;
-					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
-						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
-						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
-						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
-
-						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
-						if ((IS_TMP_VAR|IS_VAR) & IS_CV) {
-							GC_ADDREF(zobj);
-						}
-						if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) {
-							call_info |= ZEND_CALL_RELEASE_THIS;
-						}
-						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
-						call->prev_execute_data = execute_data;
-						call->call = NULL;
-						call->return_value = EX_VAR(opline->result.var);
-						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
-
-						execute_data = call;
-						EG(current_execute_data) = execute_data;
-						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
-
-#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
-						opline = hook->op_array.opcodes;
-#else
-						EX(opline) = hook->op_array.opcodes;
-#endif
-						LOAD_OPLINE_EX();
+	inc_filename = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
+			destroy_op_array(new_op_array);
+			efree_size(new_op_array, sizeof(zend_op_array));
+		}
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	} else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_TRUE(EX_VAR(opline->result.var));
+		}
+	} else if (UNEXPECTED(new_op_array == NULL)) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_FALSE(EX_VAR(opline->result.var));
+		}
+	} else if (new_op_array->last == 1
+			&& new_op_array->opcodes[0].opcode == ZEND_RETURN
+			&& new_op_array->opcodes[0].op1_type == IS_CONST
+			&& EXPECTED(zend_execute_ex == execute_ex)) {
+		if (RETURN_VALUE_USED(opline)) {
+			const zend_op *op = new_op_array->opcodes;
 
+			ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1));
+		}
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+	} else {
+		zval *return_value = NULL;
+		zend_execute_data *call;
+		if (RETURN_VALUE_USED(opline)) {
+			return_value = EX_VAR(opline->result.var);
+		}
 
-						ZEND_VM_ENTER_EX();
-					}
-					/* Fall through to read_property for hooks. */
-				} else if (EXPECTED(zobj->properties != NULL)) {
-					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
-						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+		new_op_array->scope = EX(func)->op_array.scope;
 
-						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
-							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+		call = zend_vm_stack_push_call_frame(
+			(Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+			(zend_function*)new_op_array, 0,
+			Z_PTR(EX(This)));
 
-							if (EXPECTED(p->key == name) ||
-							    (EXPECTED(p->h == ZSTR_H(name)) &&
-							     EXPECTED(p->key != NULL) &&
-							     EXPECTED(zend_string_equal_content(p->key, name)))) {
-								retval = &p->val;
-								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-									goto fetch_obj_r_copy;
-								} else {
-									goto fetch_obj_r_fast_copy;
-								}
-							}
-						}
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
-					}
-					retval = zend_hash_find_known_hash(zobj->properties, name);
-					if (EXPECTED(retval)) {
-						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_r_copy;
-						} else {
-							goto fetch_obj_r_fast_copy;
-						}
-					}
-				}
-			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
+			call->symbol_table = EX(symbol_table);
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-			if (UNEXPECTED(!name)) {
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				break;
-			}
+			call->symbol_table = zend_rebuild_symbol_table();
 		}
 
-#if ZEND_DEBUG
-		/* For non-standard object handlers, verify a declared property type in debug builds.
-		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
-		zend_property_info *prop_info = NULL;
-		if (zobj->handlers->read_property != zend_std_read_property) {
-			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
-		}
-#endif
-		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
-#if ZEND_DEBUG
-		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
-				&& ZEND_TYPE_IS_SET(prop_info->type)) {
-			ZVAL_OPT_DEREF(retval);
-			zend_verify_property_type(prop_info, retval, /* strict */ true);
-		}
-#endif
+		call->prev_execute_data = execute_data;
+		i_init_code_execute_data(call, new_op_array, return_value);
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			zend_tmp_string_release(tmp_name);
-		}
 
-		if (retval != EX_VAR(opline->result.var)) {
-fetch_obj_r_copy:
-			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
-			zend_unwrap_reference(retval);
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_ENTER();
+		} else {
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+			zend_vm_stack_free_call_frame(call);
 		}
-	} while (0);
 
-fetch_obj_r_finish:
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			UNDEF_RESULT();
+			HANDLE_EXCEPTION();
+		}
+	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container;
-	void **cache_slot = NULL;
+	zval *array_ptr, *result;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-				container = Z_REFVAL_P(container);
-				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-					break;
+	array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, array_ptr);
+		if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+			Z_ADDREF_P(array_ptr);
+		}
+		Z_FE_POS_P(result) = 0;
+
+
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		zend_object *zobj = Z_OBJ_P(array_ptr);
+		if (!zobj->ce->get_iterator) {
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+
+
+					HANDLE_EXCEPTION();
 				}
 			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
-				ZVAL_UNDEFINED_OP2();
+			HashTable *properties = zobj->properties;
+			if (properties) {
+				if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+					if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+						GC_DELREF(properties);
+					}
+					properties = zobj->properties = zend_array_dup(properties);
+				}
+			} else {
+				properties = zobj->handlers->get_properties(zobj);
 			}
-			ZVAL_NULL(EX_VAR(opline->result.var));
-			goto fetch_obj_is_finish;
-		} while (0);
-	}
 
-	/* here we are sure we are dealing with an object */
-	do {
-		zend_object *zobj = Z_OBJ_P(container);
-		zend_string *name, *tmp_name;
-		zval *retval;
+			result = EX_VAR(opline->result.var);
+			ZVAL_COPY_VALUE(result, array_ptr);
+			if (IS_TMP_VAR != IS_TMP_VAR) {
+				Z_ADDREF_P(array_ptr);
+			}
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-			cache_slot = CACHE_ADDR(opline->extended_value);
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(result) = (uint32_t) -1;
 
-			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
-				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
 
-				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-fetch_obj_is_simple:
-					retval = OBJ_PROP(zobj, prop_offset);
-					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_is_copy;
-						} else {
-fetch_obj_is_fast_copy:
-							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-							ZEND_VM_NEXT_OPCODE();
-						}
-					}
-				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
-					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
-						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
-						prop_offset = prop_info->offset;
-						goto fetch_obj_is_simple;
-					}
-					/* Fall through to read_property for hooks. */
-				} else if (EXPECTED(zobj->properties != NULL)) {
-					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
-						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
 
-						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
-							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
 
-							if (EXPECTED(p->key == name) ||
-							    (EXPECTED(p->h == ZSTR_H(name)) &&
-							     EXPECTED(p->key != NULL) &&
-							     EXPECTED(zend_string_equal_content(p->key, name)))) {
-								retval = &p->val;
-								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-									goto fetch_obj_is_copy;
-								} else {
-									goto fetch_obj_is_fast_copy;
-								}
-							}
-						}
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
-					}
-					retval = zend_hash_find_known_hash(zobj->properties, name);
-					if (EXPECTED(retval)) {
-						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_is_copy;
-						} else {
-							goto fetch_obj_is_fast_copy;
-						}
-					}
-				}
-			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-			if (UNEXPECTED(!name)) {
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				break;
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
 			}
 		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
 
-		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *array_ref;
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			zend_tmp_string_release(tmp_name);
-		}
+	SAVE_OPLINE();
 
-		if (retval != EX_VAR(opline->result.var)) {
-fetch_obj_is_copy:
-			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
-			zend_unwrap_reference(retval);
+	if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+		array_ref = array_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(array_ref)) {
+			array_ptr = Z_REFVAL_P(array_ref);
 		}
-	} while (0);
+	} else {
+		array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	}
 
-fetch_obj_is_finish:
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+			if (array_ptr == array_ref) {
+				ZVAL_NEW_REF(array_ref, array_ref);
+				array_ptr = Z_REFVAL_P(array_ref);
+			}
+			Z_ADDREF_P(array_ref);
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+		} else {
+			array_ref = EX_VAR(opline->result.var);
+			ZVAL_NEW_REF(array_ref, array_ptr);
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+		if (IS_TMP_VAR == IS_CONST) {
+			ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr)));
+		} else {
+			SEPARATE_ARRAY(array_ptr);
+		}
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	zend_string *op1_str, *op2_str, *str;
 
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+			zend_object *zobj = Z_OBJ_P(array_ptr);
+			HashTable *properties;
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
-		zend_string *op1_str = Z_STR_P(op1);
-		zend_string *op2_str = Z_STR_P(op2);
-		zend_string *str;
-		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
+					HANDLE_EXCEPTION();
+				}
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+				if (array_ptr == array_ref) {
+					ZVAL_NEW_REF(array_ref, array_ref);
+					array_ptr = Z_REFVAL_P(array_ref);
+				}
+				Z_ADDREF_P(array_ref);
+				ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
 			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				array_ptr = EX_VAR(opline->result.var);
+				ZVAL_COPY_VALUE(array_ptr, array_ref);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
+			if (Z_OBJ_P(array_ptr)->properties
+			 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
+				if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
+					GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+				}
+				Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
-		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
-			size_t len = ZSTR_LEN(op1_str);
 
-			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
+			properties = Z_OBJPROP_P(array_ptr);
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
+
+
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 			}
+
+			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
-			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
 			}
 		}
-		ZEND_VM_NEXT_OPCODE();
-	}
-
-	SAVE_OPLINE();
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		op1_str = Z_STR_P(op1);
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		op1_str = zend_string_copy(Z_STR_P(op1));
-	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-		op1_str = zval_get_string_func(op1);
-	}
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		op2_str = Z_STR_P(op2);
-	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-		op2_str = zend_string_copy(Z_STR_P(op2));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP2();
-		}
-		op2_str = zval_get_string_func(op2);
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 	}
-	do {
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
-						GC_ADDREF(op2_str);
-					}
-				}
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-				zend_string_release_ex(op1_str, 0);
-				break;
-			}
-		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
-						GC_ADDREF(op1_str);
-					}
-				}
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
-				zend_string_release_ex(op2_str, 0);
-				break;
-			}
-		}
-		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-
-		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
-		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			zend_string_release_ex(op1_str, 0);
-		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-			zend_string_release_ex(op2_str, 0);
-		}
-	} while (0);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *function_name;
-	zval *object;
-	zend_function *fbc;
-	zend_class_entry *called_scope;
-	zend_object *obj;
-	zend_execute_data *call;
-	uint32_t call_info;
+	zval *array;
+	zval *value;
+	uint32_t value_type;
+	HashTable *fe_ht;
+	HashPosition pos;
 
-	SAVE_OPLINE();
-
-	object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	array = EX_VAR(opline->op1.var);
+	if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) {
+		ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
-	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
-		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
-				function_name = Z_REFVAL_P(function_name);
-				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
-					break;
-				}
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP2();
-				if (UNEXPECTED(EG(exception) != NULL)) {
-					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-					HANDLE_EXCEPTION();
-				}
+	fe_ht = Z_ARRVAL_P(array);
+	pos = Z_FE_POS_P(array);
+	if (HT_IS_PACKED(fe_ht)) {
+		value = fe_ht->arPacked + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
 			}
-			zend_throw_error(NULL, "Method name must be a string");
-			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
-		} while (0);
-	}
-
-	if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-		obj = Z_OBJ_P(object);
-	} else {
-		do {
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
-				obj = Z_OBJ_P(object);
-			} else {
-				if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
-					zend_reference *ref = Z_REF_P(object);
-
-					object = &ref->val;
-					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
-						obj = Z_OBJ_P(object);
-						if ((IS_TMP_VAR|IS_VAR) & IS_VAR) {
-							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-								efree_size(ref, sizeof(zend_reference));
-							} else {
-								Z_ADDREF_P(object);
-							}
-						}
-						break;
-					}
-				}
-				if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
-					object = ZVAL_UNDEFINED_OP1();
-					if (UNEXPECTED(EG(exception) != NULL)) {
-						if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-						}
-						HANDLE_EXCEPTION();
-					}
-				}
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-					function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				}
-				zend_invalid_method_call(object, function_name);
-				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				HANDLE_EXCEPTION();
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
 			}
-		} while (0);
-	}
-
-	called_scope = obj->ce;
-
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
-		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
-	} else {
-		zend_object *orig_obj = obj;
-
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-			function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			pos++;
+			value++;
+		}
+		Z_FE_POS_P(array) = pos + 1;
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_LONG(EX_VAR(opline->result.var), pos);
 		}
+	} else {
+		Bucket *p;
 
-		/* First, locate the function. */
-		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
-		if (UNEXPECTED(fbc == NULL)) {
-			if (EXPECTED(!EG(exception))) {
-				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+		p = fe_ht->arData + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
 			}
-			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
-				zend_objects_store_del(orig_obj);
+			pos++;
+			value = &p->val;
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
 			}
-			HANDLE_EXCEPTION();
-		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
-		    EXPECTED(obj == orig_obj)) {
-			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+			p++;
 		}
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
-			GC_ADDREF(obj); /* For $this pointer */
-			if (GC_DELREF(orig_obj) == 0) {
-				zend_objects_store_del(orig_obj);
+		Z_FE_POS_P(array) = pos;
+		if (RETURN_VALUE_USED(opline)) {
+			if (!p->key) {
+				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
+			} else {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
 			}
 		}
-		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
-			init_func_run_time_cache(&fbc->op_array);
-		}
-	}
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
-
-	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
-	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
-			zend_objects_store_del(obj);
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			}
+	if (EXPECTED(opline->op2_type == IS_CV)) {
+		zval *variable_ptr = EX_VAR(opline->op2.var);
+		SAVE_OPLINE();
+		zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	} else {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			value = Z_REFVAL_P(value);
+			value_type = Z_TYPE_INFO_P(value);
 		}
-		/* call static method */
-		obj = (zend_object*)called_scope;
-		call_info = ZEND_CALL_NESTED_FUNCTION;
-	} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
-			GC_ADDREF(obj); /* For $this pointer */
+		zval *res = EX_VAR(opline->op2.var);
+		zend_refcounted *gc = Z_COUNTED_P(value);
+
+		ZVAL_COPY_VALUE_EX(res, value, gc, value_type);
+		if (Z_TYPE_INFO_REFCOUNTED(value_type)) {
+			GC_ADDREF(gc);
 		}
-		/* CV may be changed indirectly (e.g. when it's a reference) */
-		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+		ZEND_VM_NEXT_OPCODE();
 	}
-
-	call = zend_vm_stack_push_call_frame(call_info,
-		fbc, opline->extended_value, obj);
-	call->prev_execute_data = EX(call);
-	EX(call) = call;
-
-	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
-	double d1, d2;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
-case_true:
-				ZEND_VM_SMART_BRANCH_TRUE();
-			} else {
-case_false:
-				ZEND_VM_SMART_BRANCH_FALSE();
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = (double)Z_LVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-			goto case_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = Z_DVAL_P(op2);
-case_double:
-			if (d1 == d2) {
-				goto case_true;
-			} else {
-				goto case_false;
-			}
-		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
-			d1 = Z_DVAL_P(op1);
-			d2 = (double)Z_LVAL_P(op2);
-			goto case_double;
-		}
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
-			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-			if (result) {
-				goto case_true;
-			} else {
-				goto case_false;
-			}
-		}
+	if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))
+			&& !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) {
+		EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
 	}
-	ZEND_VM_TAIL_CALL(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container;
-	bool result;
-	zend_ulong hval;
-	zval *offset;
+	zval *value;
+	zend_reference *ref = NULL;
+	bool ret;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-
-	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-		HashTable *ht;
-		zval *value;
-		zend_string *str;
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-isset_dim_obj_array:
-		ht = Z_ARRVAL_P(container);
-isset_again:
-		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
-			str = Z_STR_P(offset);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-				if (ZEND_HANDLE_NUMERIC(str, hval)) {
-					goto num_index_prop;
-				}
-			}
-			value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST);
-		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
-			hval = Z_LVAL_P(offset);
-num_index_prop:
-			value = zend_hash_index_find(ht, hval);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
-			offset = Z_REFVAL_P(offset);
-			goto isset_again;
-		} else {
-			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
-			if (UNEXPECTED(EG(exception))) {
-				result = 0;
-				goto isset_dim_obj_exit;
-			}
+	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) {
+		if (IS_TMP_VAR == IS_VAR) {
+			ref = Z_REF_P(value);
 		}
+		value = Z_REFVAL_P(value);
+	}
 
-		if (!(opline->extended_value & ZEND_ISEMPTY)) {
-			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
-			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
-			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+	ret = i_zend_is_true(value);
 
-			if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) {
-				/* avoid exception check */
-				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-				ZEND_VM_SMART_BRANCH(result, 0);
-			}
-		} else {
-			result = (value == NULL || !i_zend_is_true(value));
-		}
-		goto isset_dim_obj_exit;
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
-		container = Z_REFVAL_P(container);
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-			goto isset_dim_obj_array;
-		}
+	if (UNEXPECTED(EG(exception))) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
-		offset++;
-	}
-	if (!(opline->extended_value & ZEND_ISEMPTY)) {
-		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
-	} else {
-		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	if (ret) {
+		zval *result = EX_VAR(opline->result.var);
+
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_TMP_VAR == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if (IS_TMP_VAR == IS_VAR && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 	}
 
-isset_dim_obj_exit:
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container;
-	int result;
-	zval *offset;
-	zend_string *name, *tmp_name;
+	zval *value;
+	zend_reference *ref = NULL;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-			container = Z_REFVAL_P(container);
-			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
-				result = (opline->extended_value & ZEND_ISEMPTY);
-				goto isset_object_finish;
-			}
-		} else {
-			result = (opline->extended_value & ZEND_ISEMPTY);
-			goto isset_object_finish;
+	if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+		if (IS_TMP_VAR & IS_VAR) {
+			ref = Z_REF_P(value);
 		}
+		value = Z_REFVAL_P(value);
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		name = Z_STR_P(offset);
-	} else {
-		name = zval_try_get_tmp_string(offset, &tmp_name);
-		if (UNEXPECTED(!name)) {
-			result = 0;
-			goto isset_object_finish;
+	if (Z_TYPE_P(value) > IS_NULL) {
+		zval *result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_TMP_VAR == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if ((IS_TMP_VAR & IS_VAR) && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
 		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 	}
 
-	result =
-		(opline->extended_value & ZEND_ISEMPTY) ^
-		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
+	if ((IS_TMP_VAR & IS_VAR) && ref) {
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		}
 	}
-
-isset_object_finish:
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
+	zval *val, *result;
 
-	zval *key, *subject;
-	HashTable *ht;
-	bool result;
-
-	SAVE_OPLINE();
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-	key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (Z_TYPE_P(val) > IS_NULL) {
+		do {
+			if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) {
+				val = Z_REFVAL_P(val);
+				if (Z_TYPE_P(val) <= IS_NULL) {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					break;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		} while (0);
+	}
 
-	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-array_key_exists_array:
-		ht = Z_ARRVAL_P(subject);
-		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
-	} else {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
-			subject = Z_REFVAL_P(subject);
-			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-				goto array_key_exists_array;
+	result = EX_VAR(opline->result.var);
+	uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK;
+	if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) {
+		ZVAL_NULL(result);
+		if (IS_TMP_VAR == IS_CV
+			&& UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)
+			&& (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0
+		) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
 			}
 		}
-		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
-		result = 0;
+	} else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) {
+		ZVAL_FALSE(result);
+	} else {
+		ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY);
+		ZVAL_TRUE(result);
 	}
 
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *expr;
-	bool result;
-
-	SAVE_OPLINE();
-	expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zval *value;
+	zval *result = EX_VAR(opline->result.var);
 
-try_instanceof:
-	if (Z_TYPE_P(expr) == IS_OBJECT) {
-		zend_class_entry *ce;
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(result);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
 
-		if (IS_VAR == IS_CONST) {
-			ce = CACHED_PTR(opline->extended_value);
-			if (UNEXPECTED(ce == NULL)) {
-				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
-				if (EXPECTED(ce)) {
-					CACHE_PTR(opline->extended_value, ce);
-				}
-			}
-		} else if (IS_VAR == IS_UNUSED) {
-			ce = zend_fetch_class(NULL, opline->op2.num);
-			if (UNEXPECTED(ce == NULL)) {
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
+	if (IS_TMP_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(result, value);
+	} else if (IS_TMP_VAR == IS_VAR) {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			ZVAL_COPY_VALUE(result, Z_REFVAL_P(value));
+			if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
+				efree_size(Z_REF_P(value), sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
 			}
 		} else {
-			ce = Z_CE_P(EX_VAR(opline->op2.var));
+			ZVAL_COPY_VALUE(result, value);
 		}
-		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
-		expr = Z_REFVAL_P(expr);
-		goto try_instanceof;
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) {
+				Z_ADDREF_P(result);
+			}
 		}
-		result = 0;
 	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *varname;
-	zval *retval;
-	zend_string *name, *tmp_name;
-	HashTable *target_symbol_table;
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+	zval *val;
 
 	SAVE_OPLINE();
-	varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		name = Z_STR_P(varname);
-	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
-		name = Z_STR_P(varname);
-		tmp_name = NULL;
-	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-		name = zval_try_get_tmp_string(varname, &tmp_name);
-		if (UNEXPECTED(!name)) {
-			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			}
-			ZVAL_UNDEF(EX_VAR(opline->result.var));
-			HANDLE_EXCEPTION();
-		}
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
 	}
 
-	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
-	retval = zend_hash_find_ex(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST);
-	if (retval == NULL) {
-		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
-fetch_this:
-			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-				zend_tmp_string_release(tmp_name);
-			}
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+yield_from_try_again:
+	if (Z_TYPE_P(val) == IS_ARRAY) {
+		ZVAL_COPY_VALUE(&generator->values, val);
+		if (Z_OPT_REFCOUNTED_P(val)) {
+			Z_ADDREF_P(val);
 		}
-		if (type == BP_VAR_W) {
-			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
-		} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
-			retval = &EG(uninitialized_zval);
-		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
-				/* Keep name alive in case an error handler tries to free it. */
-				zend_string_addref(name);
-			}
-			zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
-				(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
-			if (type == BP_VAR_RW && !EG(exception)) {
-				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
-			} else {
-				retval = &EG(uninitialized_zval);
-			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
-				zend_string_release(name);
-			}
-		}
-	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
-	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
-		retval = Z_INDIRECT_P(retval);
-		if (Z_TYPE_P(retval) == IS_UNDEF) {
-			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
-				goto fetch_this;
-			}
-			if (type == BP_VAR_W) {
-				ZVAL_NULL(retval);
-			} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
-				retval = &EG(uninitialized_zval);
-			} else {
-				zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
-					(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
-				if (type == BP_VAR_RW && !EG(exception)) {
-					ZVAL_NULL(retval);
-				} else {
-					retval = &EG(uninitialized_zval);
-				}
-			}
-		}
-	}
-
-	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+		Z_FE_POS(generator->values) = 0;
 		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	}
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-	ZEND_ASSERT(retval != NULL);
-	if (type == BP_VAR_R || type == BP_VAR_IS) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-	} else {
-		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
-	}
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
-}
+	} else if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
+		zend_class_entry *ce = Z_OBJCE_P(val);
+		if (ce == zend_ce_generator) {
+			zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val);
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	int fetch_type =
-		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
-			BP_VAR_W : BP_VAR_R;
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
-}
+			Z_ADDREF_P(val);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
-}
+			if (UNEXPECTED(new_gen->execute_data == NULL)) {
+				zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
+				zval_ptr_dtor(val);
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			} else if (Z_ISUNDEF(new_gen->retval)) {
+				if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) {
+					zend_throw_error(NULL, "Impossible to yield from the Generator being currently run");
+					zval_ptr_dtor(val);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				} else {
+					zend_generator_yield_from(generator, new_gen);
+				}
+			} else {
+				if (RETURN_VALUE_USED(opline)) {
+					ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval);
+				}
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else {
+			zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
-}
+			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+				if (!EG(exception)) {
+					zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
+				}
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			}
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value, *arg;
+			iter->index = 0;
+			if (iter->funcs->rewind) {
+				iter->funcs->rewind(iter);
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					OBJ_RELEASE(&iter->std);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				}
+			}
 
-	if (IS_UNUSED == IS_CONST) {
-		SAVE_OPLINE();
-		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-		uint32_t arg_num;
-		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
-		if (UNEXPECTED(!arg)) {
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
+			ZVAL_OBJ(&generator->values, &iter->std);
 		}
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) {
+		val = Z_REFVAL_P(val);
+		goto yield_from_try_again;
 	} else {
-		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
 	}
 
-	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	ZVAL_COPY_VALUE(arg, value);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
-			Z_ADDREF_P(arg);
-		}
+	/* This is the default return value
+	 * when the expression is a Generator, it will be overwritten in zend_generator_resume() */
+	if (RETURN_VALUE_USED(opline)) {
+		ZVAL_NULL(EX_VAR(opline->result.var));
 	}
-	ZEND_VM_NEXT_OPCODE();
-}
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *varname;
-	zend_string *name, *tmp_name;
-	HashTable *target_symbol_table;
+	/* This generator has no send target (though the generator we delegate to might have one) */
+	generator->send_target = NULL;
 
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
 	SAVE_OPLINE();
 
-	varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		name = Z_STR_P(varname);
-	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
-		name = Z_STR_P(varname);
-		tmp_name = NULL;
-	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
-			varname = ZVAL_UNDEFINED_OP1();
-		}
-		name = zval_try_get_tmp_string(varname, &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
-		}
-	}
-
-	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
-	zend_hash_del_ind(target_symbol_table, name);
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	ZEND_VM_RETURN();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
-	bool result;
-	zval *varname;
-	zend_string *name, *tmp_name;
-	HashTable *target_symbol_table;
-
-	SAVE_OPLINE();
-	varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		name = Z_STR_P(varname);
-	} else {
-		name = zval_get_tmp_string(varname, &tmp_name);
-	}
-
-	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
-	value = zend_hash_find_ex(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST);
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-	if (!value) {
-		result = (opline->extended_value & ZEND_ISEMPTY);
-	} else {
-		if (Z_TYPE_P(value) == IS_INDIRECT) {
-			value = Z_INDIRECT_P(value);
-		}
-		if (!(opline->extended_value & ZEND_ISEMPTY)) {
-			if (Z_ISREF_P(value)) {
-				value = Z_REFVAL_P(value);
-			}
-			result = Z_TYPE_P(value) > IS_NULL;
-		} else {
-			result = !i_zend_is_true(value);
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+		if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(value);
 		}
-	}
-
-	ZEND_VM_SMART_BRANCH(result, true);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *expr;
-	bool result;
-
-	SAVE_OPLINE();
-	expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-try_instanceof:
-	if (Z_TYPE_P(expr) == IS_OBJECT) {
-		zend_class_entry *ce;
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		bool strict;
 
-		if (IS_UNUSED == IS_CONST) {
-			ce = CACHED_PTR(opline->extended_value);
-			if (UNEXPECTED(ce == NULL)) {
-				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
-				if (EXPECTED(ce)) {
-					CACHE_PTR(opline->extended_value, ce);
-				}
-			}
-		} else if (IS_UNUSED == IS_UNUSED) {
-			ce = zend_fetch_class(NULL, opline->op2.num);
-			if (UNEXPECTED(ce == NULL)) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
+			value = Z_REFVAL_P(value);
+			if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+				ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
 				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
+				ZEND_VM_NEXT_OPCODE();
 			}
-		} else {
-			ce = Z_CE_P(EX_VAR(opline->op2.var));
-		}
-		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
-		expr = Z_REFVAL_P(expr);
-		goto try_instanceof;
-	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
 		}
-		result = 0;
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1;
-	zend_long count;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 
-	while (1) {
-		if (Z_TYPE_P(op1) == IS_ARRAY) {
-			count = zend_hash_num_elements(Z_ARRVAL_P(op1));
-			break;
-		} else if (Z_TYPE_P(op1) == IS_OBJECT) {
-			zend_object *zobj = Z_OBJ_P(op1);
+		SAVE_OPLINE();
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+			value = ZVAL_UNDEFINED_OP1();
+		}
+		strict = EX_USES_STRICT_TYPES();
+		do {
+			if (EXPECTED(!strict)) {
+				zend_string *str;
+				zval tmp;
 
-			/* first, we check if the handler is defined */
-			if (zobj->handlers->count_elements) {
-				if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) {
+				if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+					zend_error(E_DEPRECATED,
+						"strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+					ZVAL_LONG(EX_VAR(opline->result.var), 0);
+					if (UNEXPECTED(EG(exception))) {
+						HANDLE_EXCEPTION();
+					}
 					break;
 				}
-				if (UNEXPECTED(EG(exception))) {
-					count = 0;
+
+				ZVAL_COPY(&tmp, value);
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
+					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
+					zval_ptr_dtor(&tmp);
 					break;
 				}
+				zval_ptr_dtor(&tmp);
 			}
-
-			/* if not and the object implements Countable we call its count() method */
-			if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
-				zval retval;
-
-				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
-				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
-				count = zval_get_long(&retval);
-				zval_ptr_dtor(&retval);
-				break;
+			if (!EG(exception)) {
+				zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value));
 			}
-
-			/* If There's no handler and it doesn't implement Countable then emit a TypeError */
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
-			op1 = Z_REFVAL_P(op1);
-			continue;
-		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-		count = 0;
-		zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1));
-		break;
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+		} while (0);
 	}
-
-	ZVAL_LONG(EX_VAR(opline->result.var), count);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zend_array *ht = Z_ARRVAL_P(_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC));
-	ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht));
-	if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+	zval *value;
+	int result = 0;
+
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+type_check_resource:
+		if (opline->extended_value != MAY_BE_RESOURCE
+		 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
+			result = 1;
+		}
+	} else if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) {
+		value = Z_REFVAL_P(value);
+		if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+			goto type_check_resource;
+		}
+	} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		result = ((1 << IS_NULL) & opline->extended_value) != 0;
 		SAVE_OPLINE();
-		zend_array_destroy(ht);
-		if (EG(exception)) {
+		ZVAL_UNDEFINED_OP1();
+		if (UNEXPECTED(EG(exception))) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
 			HANDLE_EXCEPTION();
 		}
 	}
-	ZEND_VM_NEXT_OPCODE();
+	if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+		SAVE_OPLINE();
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_SMART_BRANCH(result, 1);
+	} else {
+		ZEND_VM_SMART_BRANCH(result, 0);
+	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
+	uint32_t fetch_type;
+	zend_class_entry *called_scope, *scope;
 	USE_OPLINE
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+	if (IS_TMP_VAR != IS_UNUSED) {
 		SAVE_OPLINE();
-		if (UNEXPECTED(!EX(func)->common.scope)) {
-			zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
-			ZVAL_UNDEF(EX_VAR(opline->result.var));
-			HANDLE_EXCEPTION();
-		} else {
-			zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
-			ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
-			if (UNEXPECTED(EG(exception))) {
+		zval *op = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) {
+			ZVAL_DEREF(op);
+			if (Z_TYPE_P(op) != IS_OBJECT) {
+				zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 				HANDLE_EXCEPTION();
 			}
-			ZEND_VM_NEXT_OPCODE();
 		}
-	} else {
-		zval *op1;
 
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	fetch_type = opline->op1.num;
+	if (zend_fetch_is_type_param(fetch_type)) {
 		SAVE_OPLINE();
-		op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-		while (1) {
-			if (Z_TYPE_P(op1) == IS_OBJECT) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
-			} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
-				op1 = Z_REFVAL_P(op1);
-				continue;
-			} else {
-				if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-					ZVAL_UNDEFINED_OP1();
-				}
-				zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1));
+		zend_class_entry *resolved = zend_resolve_generic_type_param(
+			zend_unpack_type_param_index(fetch_type), fetch_type);
+		if (UNEXPECTED(!resolved)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), resolved->name);
+		ZEND_VM_NEXT_OPCODE();
+	}
+	scope = EX(func)->op_array.scope;
+	if (UNEXPECTED(scope == NULL)) {
+		SAVE_OPLINE();
+		zend_throw_error(NULL, "Cannot use \"%s\" in the global scope",
+			fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+			fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	switch (fetch_type) {
+		case ZEND_FETCH_CLASS_SELF:
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
+			break;
+		case ZEND_FETCH_CLASS_PARENT:
+			if (UNEXPECTED(scope->parent == NULL)) {
+				SAVE_OPLINE();
+				zend_throw_error(NULL,
+					"Cannot use \"parent\" when current class scope has no parent");
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
 			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
 			break;
-		}
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		case ZEND_FETCH_CLASS_STATIC:
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				called_scope = Z_OBJCE(EX(This));
+			} else {
+				called_scope = Z_CE(EX(This));
+			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
+			break;
+		default: ZEND_UNREACHABLE();
 	}
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	zval *result = EX_VAR(opline->result.var);
-	ZVAL_COPY(result, value);
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
 	div_function(EX_VAR(opline->result.var), op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
 	pow_function(EX_VAR(opline->result.var), op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = EX_VAR(opline->op2.var);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
 
-	if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
 		zend_string *op1_str = Z_STR_P(op1);
 		zend_string *op2_str = Z_STR_P(op2);
 		zend_string *str;
 		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
+		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
 			}
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
 		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
 			size_t len = ZSTR_LEN(op1_str);
 
@@ -19159,7 +18578,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
 			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else {
@@ -19168,10 +18587,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
 			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		}
@@ -19179,405 +18598,54127 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(
 	} else {
 		SAVE_OPLINE();
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
 			op1 = ZVAL_UNDEFINED_OP1();
 		}
-		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
 			op2 = ZVAL_UNDEFINED_OP2();
 		}
 		concat_function(EX_VAR(opline->result.var), op1, op2);
 		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
+	bool result;
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-	compare_function(EX_VAR(opline->result.var), op1, op2);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container, *dim, *value;
+	zval *op1, *op2;
+	bool result;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	dim = EX_VAR(opline->op2.var);
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-fetch_dim_r_array:
-			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC);
-			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
-			container = Z_REFVAL_P(container);
-			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-				goto fetch_dim_r_array;
-			} else {
-				goto fetch_dim_r_slow;
-			}
-		} else {
-fetch_dim_r_slow:
-			if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
-		}
-	} else {
-		zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
-	}
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
 
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container;
+	zval *op1, *op2;
+	bool result;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
-
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_not_identical_function(op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container;
-	void **cache_slot = NULL;
-
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_TMP_VAR == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CONST == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var;
+
+	/* op1 and result are the same */
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_CONST == IS_CONST) {
+		var = RT_CONSTANT(opline, opline->op2);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = RT_CONSTANT(opline, opline->op2);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CONST == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var, *ret;
+	uint32_t i;
+
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_CONST == IS_CONST) {
+		var = RT_CONSTANT(opline, opline->op2);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = RT_CONSTANT(opline, opline->op2);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CONST == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+
+
+			if (UNEXPECTED(EG(exception))) {
+				for (i = 0; i <= opline->extended_value; i++) {
+					zend_string_release_ex(rope[i], 0);
+				}
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		}
+	}
+
+	size_t len = 0;
+	uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
+	for (i = 0; i <= opline->extended_value; i++) {
+		flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
+		len += ZSTR_LEN(rope[i]);
+	}
+	ret = EX_VAR(opline->result.var);
+	ZVAL_STR(ret, zend_string_alloc(len, 0));
+	GC_ADD_FLAGS(Z_STR_P(ret), flags);
+
+	char *target = Z_STRVAL_P(ret);
+	for (i = 0; i <= opline->extended_value; i++) {
+		memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
+		target += ZSTR_LEN(rope[i]);
+		zend_string_release_ex(rope[i], 0);
+	}
+	*target = '\0';
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CONST != IS_CONST) {
+		function_name = RT_CONSTANT(opline, opline->op2);
+	}
+
+	if (IS_CONST != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_TMP_VAR & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CONST != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CONST == IS_CONST) {
+					function_name = RT_CONSTANT(opline, opline->op2);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CONST == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CONST == IS_CONST) {
+			function_name = RT_CONSTANT(opline, opline->op2);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CONST == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CONST != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_TMP_VAR == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_val_by_ref;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+case_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+case_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+case_double:
+			if (d1 == d2) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+
+
+			if (result) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_TMP_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_TMP_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_TMP_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CONST != IS_UNUSED) {
+		zval *offset = RT_CONSTANT(opline, opline->op2);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_TMP_VAR & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	if (IS_TMP_VAR == IS_CONST ||
+	    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CONST == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	subject = RT_CONSTANT(opline, opline->op2);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
+
+	SAVE_OPLINE();
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_CONST == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_CONST == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_TMP_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_TMP_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+		zval *key = RT_CONSTANT(opline, opline->op2);
+		if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	zval *result;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST);
+		if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(op1);
+		}
+		ZEND_VM_SMART_BRANCH(result, 0);
+	}
+
+	if (opline->extended_value) {
+		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+			result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+			ZEND_VM_SMART_BRANCH(result, 0);
+		}
+		SAVE_OPLINE();
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+	} else if (Z_TYPE_P(op1) <= IS_FALSE) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC());
+		ZEND_VM_SMART_BRANCH(result, 0);
+	} else {
+		zend_string *key;
+		zval key_tmp;
+
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		}
+
+		SAVE_OPLINE();
+		ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) {
+			ZVAL_STR(&key_tmp, key);
+			if (zend_compare(op1, &key_tmp) == 0) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(1, 1);
+			}
+		} ZEND_HASH_FOREACH_END();
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(0, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_identical_function(op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_identical_function(op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_not_identical_function(op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_TMP_VAR == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_TMP_VAR == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var;
+
+	/* op1 and result are the same */
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_TMP_VAR == IS_CONST) {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var, *ret;
+	uint32_t i;
+
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_TMP_VAR == IS_CONST) {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if (UNEXPECTED(EG(exception))) {
+				for (i = 0; i <= opline->extended_value; i++) {
+					zend_string_release_ex(rope[i], 0);
+				}
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		}
+	}
+
+	size_t len = 0;
+	uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
+	for (i = 0; i <= opline->extended_value; i++) {
+		flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
+		len += ZSTR_LEN(rope[i]);
+	}
+	ret = EX_VAR(opline->result.var);
+	ZVAL_STR(ret, zend_string_alloc(len, 0));
+	GC_ADD_FLAGS(Z_STR_P(ret), flags);
+
+	char *target = Z_STRVAL_P(ret);
+	for (i = 0; i <= opline->extended_value; i++) {
+		memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
+		target += ZSTR_LEN(rope[i]);
+		zend_string_release_ex(rope[i], 0);
+	}
+	*target = '\0';
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	}
+
+	if (IS_TMP_VAR != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_TMP_VAR & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_TMP_VAR != IS_CONST) {
+							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				}
+				zend_invalid_method_call(object, function_name);
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_TMP_VAR == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_TMP_VAR == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+case_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+case_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+case_double:
+			if (d1 == d2) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if (result) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_TMP_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_TMP_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_TMP_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_TMP_VAR & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_TMP_VAR == IS_CONST ||
+	    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_TMP_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_TMP_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
+
+	SAVE_OPLINE();
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_VAR == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_VAR == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type)
+{
+	USE_OPLINE
+	zval *varname;
+	zval *retval;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+	varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	retval = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST);
+	if (retval == NULL) {
+		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+fetch_this:
+			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
+			if (IS_TMP_VAR != IS_CONST) {
+				zend_tmp_string_release(tmp_name);
+			}
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		if (type == BP_VAR_W) {
+			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
+		} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+			retval = &EG(uninitialized_zval);
+		} else {
+			if (IS_TMP_VAR == IS_CV) {
+				/* Keep name alive in case an error handler tries to free it. */
+				zend_string_addref(name);
+			}
+			zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+				(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+			if (type == BP_VAR_RW && !EG(exception)) {
+				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+			} else {
+				retval = &EG(uninitialized_zval);
+			}
+			if (IS_TMP_VAR == IS_CV) {
+				zend_string_release(name);
+			}
+		}
+	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
+	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
+		retval = Z_INDIRECT_P(retval);
+		if (Z_TYPE_P(retval) == IS_UNDEF) {
+			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+				goto fetch_this;
+			}
+			if (type == BP_VAR_W) {
+				ZVAL_NULL(retval);
+			} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+				retval = &EG(uninitialized_zval);
+			} else {
+				zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+					(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+				if (type == BP_VAR_RW && !EG(exception)) {
+					ZVAL_NULL(retval);
+				} else {
+					retval = &EG(uninitialized_zval);
+				}
+			}
+		}
+	}
+
+	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+	ZEND_ASSERT(retval != NULL);
+	if (type == BP_VAR_R || type == BP_VAR_IS) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+	} else {
+		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_R_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_W_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_RW_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	int fetch_type =
+		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
+			BP_VAR_W : BP_VAR_R;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_UNUSED == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	if (IS_TMP_VAR == IS_UNUSED) {
+		SAVE_OPLINE();
+		zend_verify_missing_return_type(EX(func));
+		HANDLE_EXCEPTION();
+	} else {
+/* prevents "undefined variable opline" errors */
+#if 0 || (IS_TMP_VAR != IS_UNUSED)
+		USE_OPLINE
+		zval *retval_ref, *retval_ptr;
+		zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
+		retval_ref = retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+		if (IS_TMP_VAR == IS_CONST) {
+			ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
+			retval_ref = retval_ptr = EX_VAR(opline->result.var);
+		} else if (IS_TMP_VAR == IS_VAR) {
+			if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+				retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr);
+			}
+			ZVAL_DEREF(retval_ptr);
+		} else if (IS_TMP_VAR == IS_CV) {
+			ZVAL_DEREF(retval_ptr);
+		}
+
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+			SAVE_OPLINE();
+			retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		zend_reference *ref = NULL;
+		if (UNEXPECTED(retval_ref != retval_ptr)) {
+			if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+				ref = Z_REF_P(retval_ref);
+			} else {
+				/* A cast might happen - unwrap the reference if this is a by-value return */
+				if (Z_REFCOUNT_P(retval_ref) == 1) {
+					ZVAL_UNREF(retval_ref);
+				} else {
+					Z_DELREF_P(retval_ref);
+					ZVAL_COPY(retval_ref, retval_ptr);
+				}
+				retval_ptr = retval_ref;
+			}
+		}
+
+		SAVE_OPLINE();
+		if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) {
+			zend_verify_return_error(EX(func), retval_ptr);
+			HANDLE_EXCEPTION();
+		}
+		ZEND_VM_NEXT_OPCODE();
+#endif
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(0)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_val_by_ref;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(1)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_val_by_ref;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_TMP_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_TMP_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_TMP_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *offset = NULL;
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_UNUSED != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	bool result;
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+	varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else {
+		name = zval_get_tmp_string(varname, &tmp_name);
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	value = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+	if (!value) {
+		result = (opline->extended_value & ZEND_ISEMPTY);
+	} else {
+		if (Z_TYPE_P(value) == IS_INDIRECT) {
+			value = Z_INDIRECT_P(value);
+		}
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			if (Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+			}
+			result = Z_TYPE_P(value) > IS_NULL;
+		} else {
+			result = !i_zend_is_true(value);
+		}
+	}
+
+	ZEND_VM_SMART_BRANCH(result, true);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
+
+	SAVE_OPLINE();
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_UNUSED == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_UNUSED == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_TMP_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_TMP_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *key = NULL;
+		if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	uint32_t arity = opline->op2.num;
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	/* Skip the entry lookup for speculative sites (args_id == 0). */
+	zend_turbofish_args_entry *tf_entry =
+		(IS_TMP_VAR == IS_UNUSED && opline->extended_value)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_TMP_VAR == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		/* Erased fast path: non-generic speculative site, nothing to verify. */
+		if (args_box == NULL
+				&& (!ZEND_USER_CODE(call->func->type)
+					|| !call->func->op_array.generic_parameters)) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Concrete turbofish args: dispatch to a synthesized plain monomorph and
+		 * skip generic verification (the monomorph's RECV does concrete checks). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, arity, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_verify_check_exception;
+			}
+		}
+		/* Runtime-promoted site: install the cached invariant table after a func
+		 * guard (cache_slot[3], bit1 = value check is a no-op). */
+		if (cache_slot && cache_slot[3]
+				&& ((uintptr_t) cache_slot[3] & ~(uintptr_t)3) == (uintptr_t) call->func) {
+			call->type_args = (zend_type_arg_table *) cache_slot[0];
+			if (((uintptr_t) cache_slot[3] & 2) == 0) {
+				zend_verify_generic_arg_types(call, args_box);
+				if (UNEXPECTED(EG(exception))) {
+					goto generic_verify_check_exception;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Inner/inference call already monomorphized: swap func + reinstall table. */
+		if (cache_slot && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH) {
+			zend_type_arg_table *ma = NULL;
+			zend_function *mono = zend_try_monomorph_resolved_call(call, NULL, cache_slot, &ma);
+			if (mono) {
+				call->func = mono;
+				call->type_args = ma;
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete turbofish VERIFY: install the precomputed SHM table after
+			 * the arity/bound check (memoized in cache_slot[0] per resolved func).
+			 * The persisted guard excludes the no-opcache heap-table case. */
+			bool checked = (cache_slot && cache_slot[0] == (void *) call->func);
+			if (!checked) {
+				zend_check_generic_call_arguments(call->func, arity, args_box);
+			}
+			if (EXPECTED(!EG(exception))) {
+				if (!checked && cache_slot) {
+					cache_slot[0] = (void *) call->func;
+				}
+				call->type_args = tf_entry->concrete_table;
+				if (!tf_entry->concrete_skip_value_check) {
+					zend_verify_generic_arg_types(call, args_box);
+				}
+			}
+		} else {
+			zend_check_generic_call_arguments(call->func, arity, args_box);
+			if (!EG(exception)) {
+				zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+				if (t) {
+					if (call->type_args) {
+						zend_type_arg_table_destroy(call->type_args);
+					}
+					call->type_args = t;
+				}
+				/* If the resolved table is invariant (CONCRETE sentinel), try to
+				 * monomorphize so later calls take the mono fast path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					zend_type_arg_table *ma = NULL;
+					zend_function *mono = zend_try_monomorph_resolved_call(call, t, cache_slot, &ma);
+					if (mono) {
+						call->func = mono;
+						call->type_args = ma;
+						ZEND_VM_NEXT_OPCODE();
+					}
+				}
+				zend_verify_generic_arg_types(call, args_box);
+				/* Promote the invariant site: record the resolved callee in
+				 * cache_slot[3] so later calls take the minimal install path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					/* Tag bits (func is >=8-aligned): bit0 = PROMOTED, bit1 = value
+					 * check is a no-op. slot[1] stays CONCRETE so the build cache
+					 * keeps returning the table on a func-guard miss. */
+					uintptr_t fn = (uintptr_t) call->func | 1u;
+					if (ZEND_USER_CODE(call->func->type)
+							&& call->func->op_array.generic_types
+							&& call->func->op_array.generic_types->parameters
+							&& zend_count_generic_value_checks(
+								call->func->op_array.generic_types->parameters) == 0) {
+						fn |= 2; /* value check is a no-op for this callee */
+					}
+					cache_slot[3] = (void *) fn;
+				}
+			}
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Monomorphize: synthesize (or look up) Box and swap both the
+		 * object's class entry and the pending constructor call. The monomorph
+		 * shares Box's property layout, so swapping ce is safe; swapping
+		 * call->func ensures the constructor's RECV opcodes verify against the
+		 * monomorph's substituted arg_info. The call-site inline cache (incl. the
+		 * concrete-args fast path) lives in zend_apply_generic_new. */
+		zend_apply_generic_new(new_obj, call, args_box, arity, cache_slot, /* do_checks */ true);
+	}
+
+generic_verify_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		/* Args have already been pushed by the SEND opcodes preceding the
+		 * VERIFY emission for call kind; release them so refcounted values
+		 * don't leak. */
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+/* Installs the type-arg table (and, for `new`, swaps the object's class to
+ * its monomorph) without running the runtime arity + bound checks that
+ * VERIFY does. Emitted by the compiler when the callee/ce is statically
+ * known, the turbofish args are concrete, and bounds were validated at
+ * compile time — so the runtime checks are pure overhead. The value-arg
+ * type-check (zend_verify_generic_arg_types) still runs since value
+ * arguments are runtime values. */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	zend_turbofish_args_entry *tf_entry =
+		(IS_TMP_VAR == IS_UNUSED)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_TMP_VAR == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		/* Dispatch to a synthesized plain monomorph (see ZEND_VERIFY_GENERIC_ARGUMENTS). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, opline->op2.num, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_install_check_exception;
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete INSTALL: install the precomputed SHM table directly. The
+			 * persisted guard excludes the no-opcache heap-table case (whose table
+			 * is owned by the turbofish entry and must not be freed at teardown). */
+			call->type_args = tf_entry->concrete_table;
+			if (!tf_entry->concrete_skip_value_check) {
+				zend_verify_generic_arg_types(call, args_box);
+			}
+		} else {
+			zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+			if (t) {
+				if (call->type_args) {
+					zend_type_arg_table_destroy(call->type_args);
+				}
+				call->type_args = t;
+			}
+			zend_verify_generic_arg_types(call, args_box);
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Statically pre-validated: skip the runtime arity/bound check, but
+		 * still cache the resolved monomorph at the call site. */
+		zend_apply_generic_new(new_obj, call, args_box, opline->op2.num, cache_slot, /* do_checks */ false);
+	}
+
+generic_install_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	zend_long count;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	while (1) {
+		if (Z_TYPE_P(op1) == IS_ARRAY) {
+			count = zend_hash_num_elements(Z_ARRVAL_P(op1));
+			break;
+		} else if (Z_TYPE_P(op1) == IS_OBJECT) {
+			zend_object *zobj = Z_OBJ_P(op1);
+
+			/* first, we check if the handler is defined */
+			if (zobj->handlers->count_elements) {
+				if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) {
+					break;
+				}
+				if (UNEXPECTED(EG(exception))) {
+					count = 0;
+					break;
+				}
+			}
+
+			/* if not and the object implements Countable we call its count() method */
+			if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
+				zval retval;
+
+				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
+				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
+				count = zval_get_long(&retval);
+				zval_ptr_dtor(&retval);
+				break;
+			}
+
+			/* If There's no handler and it doesn't implement Countable then emit a TypeError */
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			continue;
+		} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		count = 0;
+		zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1));
+		break;
+	}
+
+	ZVAL_LONG(EX_VAR(opline->result.var), count);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_array *ht = Z_ARRVAL_P(_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC));
+	ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht));
+	if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+		SAVE_OPLINE();
+		zend_array_destroy(ht);
+		if (EG(exception)) {
+			HANDLE_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		SAVE_OPLINE();
+		if (UNEXPECTED(!EX(func)->common.scope)) {
+			zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		} else {
+			zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		zval *op1;
+
+		SAVE_OPLINE();
+		op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		while (1) {
+			if (Z_TYPE_P(op1) == IS_OBJECT) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+				op1 = Z_REFVAL_P(op1);
+				continue;
+			} else {
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+					ZVAL_UNDEFINED_OP1();
+				}
+				zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+			}
+			break;
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	zend_string *type;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	type = zend_zval_get_legacy_type(op1);
+	if (EXPECTED(type)) {
+		ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type);
+	} else {
+		ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = EX_VAR(opline->op2.var);
+
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_identical_function(op1, op2);
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CV == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = EX_VAR(opline->op2.var);
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_TMP_VAR == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CV == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var;
+
+	/* op1 and result are the same */
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CONST) {
+		var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = EX_VAR(opline->op2.var);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CV == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var, *ret;
+	uint32_t i;
+
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CONST) {
+		var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = EX_VAR(opline->op2.var);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CV == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+
+
+			if (UNEXPECTED(EG(exception))) {
+				for (i = 0; i <= opline->extended_value; i++) {
+					zend_string_release_ex(rope[i], 0);
+				}
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		}
+	}
+
+	size_t len = 0;
+	uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
+	for (i = 0; i <= opline->extended_value; i++) {
+		flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
+		len += ZSTR_LEN(rope[i]);
+	}
+	ret = EX_VAR(opline->result.var);
+	ZVAL_STR(ret, zend_string_alloc(len, 0));
+	GC_ADD_FLAGS(Z_STR_P(ret), flags);
+
+	char *target = Z_STRVAL_P(ret);
+	for (i = 0; i <= opline->extended_value; i++) {
+		memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
+		target += ZSTR_LEN(rope[i]);
+		zend_string_release_ex(rope[i], 0);
+	}
+	*target = '\0';
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_CONST) {
+		function_name = EX_VAR(opline->op2.var);
+	}
+
+	if (IS_CV != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_TMP_VAR & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CV != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CV == IS_CONST) {
+					function_name = EX_VAR(opline->op2.var);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CV == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CV == IS_CONST) {
+			function_name = EX_VAR(opline->op2.var);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CV != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_TMP_VAR == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = EX_VAR(opline->op2.var);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+case_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+case_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+case_double:
+			if (d1 == d2) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+
+
+			if (result) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_TMP_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_TMP_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_TMP_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CV != IS_UNUSED) {
+		zval *offset = EX_VAR(opline->op2.var);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_TMP_VAR & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_TMP_VAR == IS_CONST ||
+	    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	subject = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_TMP_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_TMP_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *closure, *var;
+
+	closure = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (opline->extended_value & ZEND_BIND_REF) {
+		/* By-ref binding */
+		var = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(var)) {
+			Z_ADDREF_P(var);
+		} else {
+			ZVAL_MAKE_REF_EX(var, 2);
+		}
+	} else {
+		var = EX_VAR(opline->op2.var);
+		if (UNEXPECTED(Z_ISUNDEF_P(var)) && !(opline->extended_value & ZEND_BIND_IMPLICIT)) {
+			SAVE_OPLINE();
+			var = ZVAL_UNDEFINED_OP2();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZVAL_DEREF(var);
+		Z_TRY_ADDREF_P(var);
+	}
+
+	zend_closure_bind_var_ex(closure,
+		(opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)), var);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	SAVE_OPLINE();
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		increment_function(var_ptr);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_increment_function(var_ptr);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_increment_function(var_ptr);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	SAVE_OPLINE();
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		decrement_function(var_ptr);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_decrement_function(var_ptr);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_decrement_function(var_ptr);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	SAVE_OPLINE();
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+
+		increment_function(var_ptr);
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+		fast_long_increment_function(var_ptr);
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	SAVE_OPLINE();
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+
+		decrement_function(var_ptr);
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+		fast_long_decrement_function(var_ptr);
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+
+
+	SAVE_OPLINE();
+
+	return_value = EX(return_value);
+
+
+	do {
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR)) ||
+		    (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
+			/* Not supposed to happen, but we'll allow it */
+			zend_error(E_NOTICE, "Only variable references should be returned by reference");
+
+			retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+			if (!return_value) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			} else {
+				if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+					ZVAL_COPY_VALUE(return_value, retval_ptr);
+					break;
+				}
+
+				ZVAL_NEW_REF(return_value, retval_ptr);
+				if (IS_VAR == IS_CONST) {
+					Z_TRY_ADDREF_P(retval_ptr);
+				}
+			}
+			break;
+		}
+
+		retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+		if (IS_VAR == IS_VAR) {
+			ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
+			if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
+				zend_error(E_NOTICE, "Only variable references should be returned by reference");
+				if (return_value) {
+					ZVAL_NEW_REF(return_value, retval_ptr);
+				} else {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				}
+				break;
+			}
+		}
+
+		if (return_value) {
+			if (Z_ISREF_P(retval_ptr)) {
+				Z_ADDREF_P(retval_ptr);
+			} else {
+				ZVAL_MAKE_REF_EX(retval_ptr, 2);
+			}
+			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
+		}
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} while (0);
+
+
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval;
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	retval = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	/* Copy return value into generator->retval */
+	if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+		ZVAL_COPY_VALUE(&generator->retval, retval);
+		if (IS_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
+				Z_ADDREF(generator->retval);
+			}
+		}
+	} else if (IS_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(&generator->retval, retval);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_refcounted *ref = Z_COUNTED_P(retval);
+
+			retval = Z_REFVAL_P(retval);
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(retval)) {
+				Z_ADDREF_P(retval);
+			}
+		} else {
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+		}
+	}
+
+
+	EG(current_execute_data) = EX(prev_execute_data);
+
+	/* Close the generator to free up resources */
+	zend_generator_close(generator, 1);
+
+	/* Pass execution back to handling code */
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *array_ref;
+
+	SAVE_OPLINE();
+
+	if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
+		array_ref = array_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(array_ref)) {
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+	} else {
+		array_ref = array_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	}
+
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
+			if (array_ptr == array_ref) {
+				ZVAL_NEW_REF(array_ref, array_ref);
+				array_ptr = Z_REFVAL_P(array_ref);
+			}
+			Z_ADDREF_P(array_ref);
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+		} else {
+			array_ref = EX_VAR(opline->result.var);
+			ZVAL_NEW_REF(array_ref, array_ptr);
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+		if (IS_VAR == IS_CONST) {
+			ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr)));
+		} else {
+			SEPARATE_ARRAY(array_ptr);
+		}
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+			zend_object *zobj = Z_OBJ_P(array_ptr);
+			HashTable *properties;
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
+				if (array_ptr == array_ref) {
+					ZVAL_NEW_REF(array_ref, array_ref);
+					array_ptr = Z_REFVAL_P(array_ref);
+				}
+				Z_ADDREF_P(array_ref);
+				ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+			} else {
+				array_ptr = EX_VAR(opline->result.var);
+				ZVAL_COPY_VALUE(array_ptr, array_ref);
+			}
+			if (Z_OBJ_P(array_ptr)->properties
+			 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
+				if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
+					GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+				}
+				Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+			}
+
+			properties = Z_OBJPROP_P(array_ptr);
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
+
+			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array;
+	zval *value;
+	uint32_t value_type;
+	HashTable *fe_ht;
+	HashPosition pos;
+	Bucket *p;
+
+	array = EX_VAR(opline->op1.var);
+	SAVE_OPLINE();
+
+	ZVAL_DEREF(array);
+	if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) {
+		pos = zend_hash_iterator_pos_ex(Z_FE_ITER_P(EX_VAR(opline->op1.var)), array);
+		fe_ht = Z_ARRVAL_P(array);
+		if (HT_IS_PACKED(fe_ht)) {
+			value = fe_ht->arPacked + pos;
+			while (1) {
+				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+					/* reached end of iteration */
+					goto fe_fetch_w_exit;
+				}
+				value_type = Z_TYPE_INFO_P(value);
+				ZEND_ASSERT(value_type != IS_INDIRECT);
+				if (EXPECTED(value_type != IS_UNDEF)) {
+					break;
+				}
+				pos++;
+				value++;
+			}
+			EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1;
+			if (RETURN_VALUE_USED(opline)) {
+				ZVAL_LONG(EX_VAR(opline->result.var), pos);
+			}
+		} else {
+			p = fe_ht->arData + pos;
+			while (1) {
+				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+					/* reached end of iteration */
+					goto fe_fetch_w_exit;
+				}
+				pos++;
+				value = &p->val;
+				value_type = Z_TYPE_INFO_P(value);
+				ZEND_ASSERT(value_type != IS_INDIRECT);
+				if (EXPECTED(value_type != IS_UNDEF)) {
+					break;
+				}
+				p++;
+			}
+			EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos;
+			if (RETURN_VALUE_USED(opline)) {
+				if (!p->key) {
+					ZVAL_LONG(EX_VAR(opline->result.var), p->h);
+				} else {
+					ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
+				}
+			}
+		}
+	} else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) {
+		zend_object_iterator *iter;
+
+		if ((iter = zend_iterator_unwrap(array)) == NULL) {
+			/* plain object */
+
+			fe_ht = Z_OBJPROP_P(array);
+			pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht);
+			p = fe_ht->arData + pos;
+			while (1) {
+				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+					/* reached end of iteration */
+					goto fe_fetch_w_exit_exc;
+				}
+				pos++;
+				value = &p->val;
+				value_type = Z_TYPE_INFO_P(value);
+				if (EXPECTED(value_type != IS_UNDEF)) {
+					if (UNEXPECTED(value_type == IS_INDIRECT)) {
+						value = Z_INDIRECT_P(value);
+						value_type = Z_TYPE_INFO_P(value);
+						if (EXPECTED(value_type != IS_UNDEF)
+						 && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) {
+							if ((value_type & Z_TYPE_MASK) != IS_REFERENCE) {
+								zend_property_info *prop_info =
+									zend_get_property_info_for_slot(Z_OBJ_P(array), value);
+								if (prop_info) {
+									if (UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) {
+										zend_throw_error(NULL,
+											"Cannot acquire reference to readonly property %s::$%s",
+											ZSTR_VAL(prop_info->ce->name), ZSTR_VAL(p->key));
+										UNDEF_RESULT();
+										HANDLE_EXCEPTION();
+									}
+									if (ZEND_TYPE_IS_SET(prop_info->type)) {
+										ZVAL_NEW_REF(value, value);
+										ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(value), prop_info);
+										value_type = IS_REFERENCE_EX;
+									}
+								}
+							}
+							break;
+						}
+					} else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
+							|| !p->key
+							|| zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) {
+						break;
+					}
+				}
+				p++;
+			}
+			EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos;
+			if (RETURN_VALUE_USED(opline)) {
+				if (UNEXPECTED(!p->key)) {
+					ZVAL_LONG(EX_VAR(opline->result.var), p->h);
+				} else if (ZSTR_VAL(p->key)[0]) {
+					ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
+				} else {
+					const char *class_name, *prop_name;
+					size_t prop_name_len;
+					zend_unmangle_property_name_ex(
+						p->key, &class_name, &prop_name, &prop_name_len);
+					ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len);
+				}
+			}
+		} else {
+			const zend_object_iterator_funcs *funcs = iter->funcs;
+			if (++iter->index > 0) {
+				/* This could cause an endless loop if index becomes zero again.
+				 * In case that ever happens we need an additional flag. */
+				funcs->move_forward(iter);
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				}
+				if (UNEXPECTED(funcs->valid(iter) == FAILURE)) {
+					/* reached end of iteration */
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						UNDEF_RESULT();
+						HANDLE_EXCEPTION();
+					}
+					goto fe_fetch_w_exit;
+				}
+			}
+			value = funcs->get_current_data(iter);
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			}
+			if (!value) {
+				/* failure in get_current_data */
+				goto fe_fetch_w_exit;
+			}
+			if (RETURN_VALUE_USED(opline)) {
+				if (funcs->get_current_key) {
+					funcs->get_current_key(iter, EX_VAR(opline->result.var));
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						UNDEF_RESULT();
+						HANDLE_EXCEPTION();
+					}
+				} else {
+					ZVAL_LONG(EX_VAR(opline->result.var), iter->index);
+				}
+			}
+			value_type = Z_TYPE_INFO_P(value);
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array));
+fe_fetch_w_exit_exc:
+		if (UNEXPECTED(EG(exception))) {
+			UNDEF_RESULT();
+			HANDLE_EXCEPTION();
+		}
+fe_fetch_w_exit:
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+		ZEND_VM_CONTINUE();
+	}
+
+	if (EXPECTED((value_type & Z_TYPE_MASK) != IS_REFERENCE)) {
+		zend_refcounted *gc = Z_COUNTED_P(value);
+		zval *ref;
+		ZVAL_NEW_EMPTY_REF(value);
+		ref = Z_REFVAL_P(value);
+		ZVAL_COPY_VALUE_EX(ref, value, gc, value_type);
+	}
+	if (EXPECTED(opline->op2_type == IS_CV)) {
+		zval *variable_ptr = EX_VAR(opline->op2.var);
+		if (EXPECTED(variable_ptr != value)) {
+			zend_reference *ref;
+
+			ref = Z_REF_P(value);
+			GC_ADDREF(ref);
+			i_zval_ptr_dtor(variable_ptr);
+			ZVAL_REF(variable_ptr, ref);
+		}
+	} else {
+		Z_ADDREF_P(value);
+		ZVAL_REF(EX_VAR(opline->op2.var), Z_REF_P(value));
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *result = EX_VAR(opline->result.var);
+
+	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(result);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(result, value);
+	} else if (IS_VAR == IS_VAR) {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			ZVAL_COPY_VALUE(result, Z_REFVAL_P(value));
+			if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
+				efree_size(Z_REF_P(value), sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		} else {
+			ZVAL_COPY_VALUE(result, value);
+		}
+	} else {
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) {
+				Z_ADDREF_P(result);
+			}
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY(arg, varptr);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = RT_CONSTANT(opline, opline->op2);
+		if (IS_CONST == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op2);
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_VAR, property, IS_CONST,
+		((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	dim = RT_CONSTANT(opline, opline->op2);
+
+	if (IS_VAR == IS_VAR
+		&& Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT
+		&& UNEXPECTED(!Z_ISREF_P(container))
+	) {
+		zend_error(E_NOTICE, "Attempting to set reference to non referenceable value");
+		zend_fetch_dimension_address_LIST_r(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_fetch_dimension_address_W(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CONST == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CONST == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = RT_CONSTANT(opline, opline->op2);
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = RT_CONSTANT(opline, opline->op2);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = RT_CONSTANT(opline, opline->op2);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CONST != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CONST == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CONST == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = RT_CONSTANT(opline, opline->op2);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = RT_CONSTANT(opline, opline->op2);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = RT_CONSTANT(opline, opline->op2);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CONST != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CONST == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CONST == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = RT_CONSTANT(opline, opline->op2);
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = RT_CONSTANT(opline, opline->op2);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = RT_CONSTANT(opline, opline->op2);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CONST != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op2);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES());
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op2);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES());
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_VAR == IS_UNUSED) {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_VAR == IS_UNUSED) {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_VAR == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_CONST != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_VAR == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_VAR == IS_CONST &&
+	    IS_CONST == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_VAR != IS_CONST &&
+	           IS_CONST == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_CONST != IS_UNUSED) {
+		function_name = RT_CONSTANT(opline, opline->op2);
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CONST == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_CONST != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_VAR == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, varptr);
+
+	if (EXPECTED(Z_ISREF_P(varptr))) {
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	ZVAL_NEW_REF(arg, arg);
+	zend_error(E_NOTICE, "Only variables should be passed by reference");
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var;
+		}
+
+		varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		ZVAL_COPY_VALUE(arg, varptr);
+
+		if (EXPECTED(Z_ISREF_P(varptr) ||
+		    QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var;
+		}
+
+		varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		ZVAL_COPY_VALUE(arg, varptr);
+
+		if (EXPECTED(Z_ISREF_P(varptr) ||
+		    ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	SAVE_OPLINE();
+	ZVAL_NEW_REF(arg, arg);
+	zend_error(E_NOTICE, "Only variables should be passed by reference");
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+send_var:
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (UNEXPECTED(Z_ISREF_P(varptr))) {
+		zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+		varptr = Z_REFVAL_P(varptr);
+		ZVAL_COPY_VALUE(arg, varptr);
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		} else if (Z_OPT_REFCOUNTED_P(arg)) {
+			Z_ADDREF_P(arg);
+		}
+	} else {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	SAVE_OPLINE();
+	if (IS_CONST == IS_CONST) {
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_ISREF_P(varptr)) {
+		Z_ADDREF_P(varptr);
+	} else {
+		ZVAL_MAKE_REF_EX(varptr, 2);
+	}
+	ZVAL_REF(arg, Z_REF_P(varptr));
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var_by_ref;
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+		varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_CONST == IS_CONST) {
+		// TODO: Would it make sense to share the cache slot with CHECK_FUNC_ARG?
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (UNEXPECTED(Z_ISREF_P(varptr))) {
+		zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+		varptr = Z_REFVAL_P(varptr);
+		ZVAL_COPY_VALUE(arg, varptr);
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		} else if (Z_OPT_REFCOUNTED_P(arg)) {
+			Z_ADDREF_P(arg);
+		}
+	} else {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_class_entry *ce, *scope;
+	zend_class_constant *c;
+	zval *value, *zv, *constant_zv;
+	zend_string *constant_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+
+	do {
+		if (IS_VAR == IS_CONST && IS_CONST == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) {
+				value = CACHED_PTR(opline->extended_value + sizeof(void*));
+				break;
+			}
+		}
+		if (IS_VAR == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value))) {
+				ce = CACHED_PTR(opline->extended_value);
+			} else {
+				ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+				if (UNEXPECTED(ce == NULL)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+				CACHE_PTR(opline->extended_value, ce);
+			}
+		} else if (IS_VAR == IS_UNUSED) {
+			ce = zend_fetch_class(NULL, opline->op1.num);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op1.var));
+		}
+		if (IS_VAR != IS_CONST
+			&& IS_CONST == IS_CONST
+			&& EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
+			value = CACHED_PTR(opline->extended_value + sizeof(void*));
+			break;
+		}
+
+		constant_zv = RT_CONSTANT(opline, opline->op2);
+		if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
+			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+			HANDLE_EXCEPTION();
+		}
+		constant_name = Z_STR_P(constant_zv);
+		/* Magic 'class' for constant OP2 is caught at compile-time */
+		if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
+
+
+			ZEND_VM_NEXT_OPCODE();
+		}
+		zv = IS_CONST == IS_CONST
+			? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name)
+			: zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name);
+
+		if (EXPECTED(zv != NULL)) {
+			c = Z_PTR_P(zv);
+			scope = EX(func)->op_array.scope;
+			if (!zend_verify_const_access(c, scope)) {
+				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+
+			if (ce->ce_flags & ZEND_ACC_TRAIT) {
+				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+
+			bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
+			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
+				if (c->ce->type == ZEND_USER_CLASS) {
+					/* Recursion protection only applied to user constants, GH-18463 */
+					CONST_PROTECT_RECURSION(c);
+				}
+				zend_deprecated_class_constant(c, constant_name);
+				if (c->ce->type == ZEND_USER_CLASS) {
+					CONST_UNPROTECT_RECURSION(c);
+				}
+
+				if (EG(exception)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			value = &c->value;
+			// Enums require loading of all class constants to build the backed enum table
+			if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
+				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (IS_CONST == IS_CONST && !is_constant_deprecated) {
+				CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
+			}
+		} else {
+			zend_throw_error(NULL, "Undefined constant %s::%s",
+				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CONST != IS_UNUSED) {
+		zval *offset = RT_CONSTANT(opline, opline->op2);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_ulong hval;
+	zend_string *key;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			HashTable *ht;
+
+unset_dim_array:
+			SEPARATE_ARRAY(container);
+			ht = Z_ARRVAL_P(container);
+offset_again:
+			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+				key = Z_STR_P(offset);
+				if (IS_CONST != IS_CONST) {
+					if (ZEND_HANDLE_NUMERIC(key, hval)) {
+						goto num_index_dim;
+					}
+				}
+str_index_dim:
+				ZEND_ASSERT(ht != &EG(symbol_table));
+				zend_hash_del(ht, key);
+			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+				hval = Z_LVAL_P(offset);
+num_index_dim:
+				zend_hash_index_del(ht, hval);
+			} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+				offset = Z_REFVAL_P(offset);
+				goto offset_again;
+			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
+				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_NULL) {
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_FALSE) {
+				hval = 0;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_TRUE) {
+				hval = 1;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+				zend_use_resource_as_offset(offset);
+				hval = Z_RES_HANDLE_P(offset);
+				goto num_index_dim;
+			} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else {
+				zend_illegal_array_offset_unset(offset);
+			}
+			break;
+		} else if (Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto unset_dim_array;
+			}
+		}
+		if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+			container = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+			offset = ZVAL_UNDEFINED_OP2();
+		}
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+				offset++;
+			}
+			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+			zend_throw_error(NULL, "Cannot unset string offsets");
+		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
+			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
+			zend_false_to_array_deprecated();
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_VAR == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+		zval *key = RT_CONSTANT(opline, opline->op2);
+		if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_class_entry *ce, *scope;
+	zend_class_constant *c;
+	zval *value, *zv, *constant_zv;
+	zend_string *constant_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+
+	do {
+		if (IS_VAR == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) {
+				value = CACHED_PTR(opline->extended_value + sizeof(void*));
+				break;
+			}
+		}
+		if (IS_VAR == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value))) {
+				ce = CACHED_PTR(opline->extended_value);
+			} else {
+				ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+				if (UNEXPECTED(ce == NULL)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+				CACHE_PTR(opline->extended_value, ce);
+			}
+		} else if (IS_VAR == IS_UNUSED) {
+			ce = zend_fetch_class(NULL, opline->op1.num);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op1.var));
+		}
+		if (IS_VAR != IS_CONST
+			&& (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST
+			&& EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
+			value = CACHED_PTR(opline->extended_value + sizeof(void*));
+			break;
+		}
+
+		constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC);
+		if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
+			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			FREE_OP(opline->op2_type, opline->op2.var);
+			HANDLE_EXCEPTION();
+		}
+		constant_name = Z_STR_P(constant_zv);
+		/* Magic 'class' for constant OP2 is caught at compile-time */
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
+			FREE_OP(opline->op2_type, opline->op2.var);
+			ZEND_VM_NEXT_OPCODE();
+		}
+		zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST
+			? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name)
+			: zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name);
+
+		if (EXPECTED(zv != NULL)) {
+			c = Z_PTR_P(zv);
+			scope = EX(func)->op_array.scope;
+			if (!zend_verify_const_access(c, scope)) {
+				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+
+			if (ce->ce_flags & ZEND_ACC_TRAIT) {
+				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+
+			bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
+			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
+				if (c->ce->type == ZEND_USER_CLASS) {
+					/* Recursion protection only applied to user constants, GH-18463 */
+					CONST_PROTECT_RECURSION(c);
+				}
+				zend_deprecated_class_constant(c, constant_name);
+				if (c->ce->type == ZEND_USER_CLASS) {
+					CONST_UNPROTECT_RECURSION(c);
+				}
+
+				if (EG(exception)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			value = &c->value;
+			// Enums require loading of all class constants to build the backed enum table
+			if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
+				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+			if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) {
+				CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
+			}
+		} else {
+			zend_throw_error(NULL, "Undefined constant %s::%s",
+				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			FREE_OP(opline->op2_type, opline->op2.var);
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
+
+	FREE_OP(opline->op2_type, opline->op2.var);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_VAR, property, IS_TMP_VAR,
+		((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_VAR == IS_VAR
+		&& Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT
+		&& UNEXPECTED(!Z_ISREF_P(container))
+	) {
+		zend_error(E_NOTICE, "Attempting to set reference to non referenceable value");
+		zend_fetch_dimension_address_LIST_r(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_fetch_dimension_address_W(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_VAR == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_VAR == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_VAR == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				HANDLE_EXCEPTION();
+			}
+			if (IS_TMP_VAR != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_VAR == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_VAR == IS_CONST &&
+	    IS_TMP_VAR == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_VAR != IS_CONST &&
+	           IS_TMP_VAR == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_TMP_VAR != IS_UNUSED) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+					zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_VAR == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_ulong hval;
+	zend_string *key;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			HashTable *ht;
+
+unset_dim_array:
+			SEPARATE_ARRAY(container);
+			ht = Z_ARRVAL_P(container);
+offset_again:
+			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+				key = Z_STR_P(offset);
+				if (IS_TMP_VAR != IS_CONST) {
+					if (ZEND_HANDLE_NUMERIC(key, hval)) {
+						goto num_index_dim;
+					}
+				}
+str_index_dim:
+				ZEND_ASSERT(ht != &EG(symbol_table));
+				zend_hash_del(ht, key);
+			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+				hval = Z_LVAL_P(offset);
+num_index_dim:
+				zend_hash_index_del(ht, hval);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+				offset = Z_REFVAL_P(offset);
+				goto offset_again;
+			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
+				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_NULL) {
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_FALSE) {
+				hval = 0;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_TRUE) {
+				hval = 1;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+				zend_use_resource_as_offset(offset);
+				hval = Z_RES_HANDLE_P(offset);
+				goto num_index_dim;
+			} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else {
+				zend_illegal_array_offset_unset(offset);
+			}
+			break;
+		} else if (Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto unset_dim_array;
+			}
+		}
+		if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+			container = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+			offset = ZVAL_UNDEFINED_OP2();
+		}
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+				offset++;
+			}
+			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+			zend_throw_error(NULL, "Cannot unset string offsets");
+		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
+			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
+			zend_false_to_array_deprecated();
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_VAR == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *variable_ptr;
+	zval *value_ptr;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	value_ptr = _get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR == IS_VAR &&
+	           UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+
+		zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object");
+		variable_ptr = &EG(uninitialized_zval);
+	} else if (IS_VAR == IS_VAR &&
+	           opline->extended_value == ZEND_RETURNS_FUNCTION &&
+			   UNEXPECTED(!Z_ISREF_P(value_ptr))) {
+
+		variable_ptr = zend_wrong_assign_to_variable_reference(
+			variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
+	}
+
+	if (garbage) {
+		GC_DTOR(garbage);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = NULL;
+		if (IS_UNUSED == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_UNUSED == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = NULL;
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_UNUSED == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_UNUSED == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = NULL;
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_UNUSED == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = NULL;
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = NULL;
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = NULL;
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_UNUSED == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = NULL;
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_UNUSED == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = NULL;
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = NULL;
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = NULL;
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_UNUSED == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = NULL;
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_UNUSED == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = NULL;
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = NULL;
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = NULL;
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_VAR == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_UNUSED != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_VAR == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_VAR == IS_CONST &&
+	    IS_UNUSED == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_VAR != IS_CONST &&
+	           IS_UNUSED == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_UNUSED != IS_UNUSED) {
+		function_name = NULL;
+		if (IS_UNUSED != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_UNUSED == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_UNUSED != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_VAR == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	if (IS_VAR == IS_UNUSED) {
+		SAVE_OPLINE();
+		zend_verify_missing_return_type(EX(func));
+		HANDLE_EXCEPTION();
+	} else {
+/* prevents "undefined variable opline" errors */
+#if 0 || (IS_VAR != IS_UNUSED)
+		USE_OPLINE
+		zval *retval_ref, *retval_ptr;
+		zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
+		retval_ref = retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+		if (IS_VAR == IS_CONST) {
+			ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
+			retval_ref = retval_ptr = EX_VAR(opline->result.var);
+		} else if (IS_VAR == IS_VAR) {
+			if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+				retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr);
+			}
+			ZVAL_DEREF(retval_ptr);
+		} else if (IS_VAR == IS_CV) {
+			ZVAL_DEREF(retval_ptr);
+		}
+
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+
+		if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+			SAVE_OPLINE();
+			retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		zend_reference *ref = NULL;
+		if (UNEXPECTED(retval_ref != retval_ptr)) {
+			if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+				ref = Z_REF_P(retval_ref);
+			} else {
+				/* A cast might happen - unwrap the reference if this is a by-value return */
+				if (Z_REFCOUNT_P(retval_ref) == 1) {
+					ZVAL_UNREF(retval_ref);
+				} else {
+					Z_DELREF_P(retval_ref);
+					ZVAL_COPY(retval_ref, retval_ptr);
+				}
+				retval_ptr = retval_ref;
+			}
+		}
+
+		SAVE_OPLINE();
+		if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) {
+			zend_verify_return_error(EX(func), retval_ptr);
+			HANDLE_EXCEPTION();
+		}
+		ZEND_VM_NEXT_OPCODE();
+#endif
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, varptr);
+
+	if (EXPECTED(Z_ISREF_P(varptr))) {
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	ZVAL_NEW_REF(arg, arg);
+	zend_error(E_NOTICE, "Only variables should be passed by reference");
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(0)) {
+		if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var;
+		}
+
+		varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		ZVAL_COPY_VALUE(arg, varptr);
+
+		if (EXPECTED(Z_ISREF_P(varptr) ||
+		    QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var;
+		}
+
+		varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		ZVAL_COPY_VALUE(arg, varptr);
+
+		if (EXPECTED(Z_ISREF_P(varptr) ||
+		    ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	SAVE_OPLINE();
+	ZVAL_NEW_REF(arg, arg);
+	zend_error(E_NOTICE, "Only variables should be passed by reference");
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+send_var:
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (UNEXPECTED(Z_ISREF_P(varptr))) {
+		zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+		varptr = Z_REFVAL_P(varptr);
+		ZVAL_COPY_VALUE(arg, varptr);
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		} else if (Z_OPT_REFCOUNTED_P(arg)) {
+			Z_ADDREF_P(arg);
+		}
+	} else {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(1)) {
+		if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var;
+		}
+
+		varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		ZVAL_COPY_VALUE(arg, varptr);
+
+		if (EXPECTED(Z_ISREF_P(varptr) ||
+		    QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var;
+		}
+
+		varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		ZVAL_COPY_VALUE(arg, varptr);
+
+		if (EXPECTED(Z_ISREF_P(varptr) ||
+		    ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	SAVE_OPLINE();
+	ZVAL_NEW_REF(arg, arg);
+	zend_error(E_NOTICE, "Only variables should be passed by reference");
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+send_var:
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (UNEXPECTED(Z_ISREF_P(varptr))) {
+		zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+		varptr = Z_REFVAL_P(varptr);
+		ZVAL_COPY_VALUE(arg, varptr);
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		} else if (Z_OPT_REFCOUNTED_P(arg)) {
+			Z_ADDREF_P(arg);
+		}
+	} else {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	SAVE_OPLINE();
+	if (IS_UNUSED == IS_CONST) {
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_ISREF_P(varptr)) {
+		Z_ADDREF_P(varptr);
+	} else {
+		ZVAL_MAKE_REF_EX(varptr, 2);
+	}
+	ZVAL_REF(arg, Z_REF_P(varptr));
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(0)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var_by_ref;
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+		varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(1)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var_by_ref;
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+		varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		// TODO: Would it make sense to share the cache slot with CHECK_FUNC_ARG?
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (UNEXPECTED(Z_ISREF_P(varptr))) {
+		zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+		varptr = Z_REFVAL_P(varptr);
+		ZVAL_COPY_VALUE(arg, varptr);
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		} else if (Z_OPT_REFCOUNTED_P(arg)) {
+			Z_ADDREF_P(arg);
+		}
+	} else {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *result;
+	zend_function *constructor;
+	zend_class_entry *ce;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+	if (IS_VAR == IS_CONST) {
+		ce = CACHED_PTR(opline->op2.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+			CACHE_PTR(opline->op2.num, ce);
+		}
+	} else if (IS_VAR == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	/* Naked `new` of a bare generic class (via `new static()`, `new $name`,
+	 * or any path that didn't go through compile-time canonical-name rewrite).
+	 * Skip when ZEND_VERIFY_GENERIC_ARGUMENTS follows — that opcode handles
+	 * the synthesis-and-swap for the turbofish path. Otherwise: if every
+	 * type parameter has a default, synthesize and use the defaults monomorph.
+	 * For `new static()` / lexical paths with no defaults, fall back to a
+	 * bare instance (preserves the lexical-self semantic for generic classes
+	 * whose authors didn't declare defaults). For dynamic `new $name()` we
+	 * throw — the caller spelled out a generic class by name and a bare
+	 * instance with erased T is almost never what they want.
+	 *
+	 * IS_VAR distinguishes: IS_UNUSED → static/self/parent (lenient);
+	 * IS_VAR → dynamic name resolved via FETCH_CLASS (strict). */
+	if (UNEXPECTED(IS_VAR != IS_CONST && ce->generic_parameters
+			&& (opline + 1)->opcode != ZEND_VERIFY_GENERIC_ARGUMENTS)) {
+		if (ce->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS) {
+			ce = zend_synthesize_monomorph(ce, NULL, 0);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else if (IS_VAR == IS_VAR) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments "
+				"via dynamic class name; no defaults declared",
+				ZSTR_VAL(ce->name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		/* IS_UNUSED with no defaults: fall through with the bare ce. */
+	}
+
+	result = EX_VAR(opline->result.var);
+	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
+		ZVAL_UNDEF(result);
+		HANDLE_EXCEPTION();
+	}
+
+	constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
+	if (constructor == NULL) {
+		/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
+		 * opcode is DO_FCALL in case EXT instructions are used. */
+		if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
+			ZEND_VM_NEXT_OPCODE_EX(1, 2);
+		}
+
+		if (UNEXPECTED(EG(exception))) {
+			HANDLE_EXCEPTION();
+		}
+
+		/* Perform a dummy function call */
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
+			opline->extended_value, NULL);
+	} else {
+		if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
+			init_func_run_time_cache(&constructor->op_array);
+		}
+		/* We are not handling overloaded classes right now */
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS,
+			constructor,
+			opline->extended_value,
+			Z_OBJ_P(result));
+		Z_ADDREF_P(result);
+	}
+
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *offset = NULL;
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_UNUSED != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	if (UNEXPECTED(Z_ISREF_P(var_ptr))) {
+		if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) {
+			ZVAL_UNREF(var_ptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *key = NULL;
+		if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1 = EX_VAR(opline->op1.var);
+
+	if (IS_VAR == IS_CV) {
+		if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_NEW_EMPTY_REF(op1);
+			Z_SET_REFCOUNT_P(op1, 2);
+			ZVAL_NULL(Z_REFVAL_P(op1));
+			ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
+		} else {
+			if (Z_ISREF_P(op1)) {
+				Z_ADDREF_P(op1);
+			} else {
+				ZVAL_MAKE_REF_EX(op1, 2);
+			}
+			ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) {
+		op1 = Z_INDIRECT_P(op1);
+		if (EXPECTED(!Z_ISREF_P(op1))) {
+			ZVAL_MAKE_REF_EX(op1, 2);
+		} else {
+			GC_ADDREF(Z_REF_P(op1));
+		}
+		ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
+	} else {
+		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num = opline->op2.num;
+
+	if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+		ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+	if (IS_VAR == IS_CV) {
+		ZVAL_COPY(arg, varptr);
+	} else /* if (IS_VAR == IS_VAR) */ {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = EX_VAR(opline->op2.var);
+		if (IS_CV == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_VAR == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CV == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_VAR, property, IS_CV,
+		((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_VAR == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	dim = EX_VAR(opline->op2.var);
+
+	if (IS_VAR == IS_VAR
+		&& Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT
+		&& UNEXPECTED(!Z_ISREF_P(container))
+	) {
+		zend_error(E_NOTICE, "Attempting to set reference to non referenceable value");
+		zend_fetch_dimension_address_LIST_r(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_fetch_dimension_address_W(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CV == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CV == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = EX_VAR(opline->op2.var);
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CV != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CV == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CV == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = EX_VAR(opline->op2.var);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CV != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CV == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CV == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = EX_VAR(opline->op2.var);
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CV != IS_UNUSED) {
+
+
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *variable_ptr;
+	zval *value_ptr;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_VAR == IS_VAR &&
+	           UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+
+		zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object");
+		variable_ptr = &EG(uninitialized_zval);
+	} else if (IS_CV == IS_VAR &&
+	           opline->extended_value == ZEND_RETURNS_FUNCTION &&
+			   UNEXPECTED(!Z_ISREF_P(value_ptr))) {
+
+		variable_ptr = zend_wrong_assign_to_variable_reference(
+			variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
+	}
+
+	if (garbage) {
+		GC_DTOR(garbage);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_VAR == IS_UNUSED) {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_VAR == IS_UNUSED) {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_VAR == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_CV != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_VAR == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_VAR == IS_CONST &&
+	    IS_CV == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_VAR != IS_CONST &&
+	           IS_CV == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_CV != IS_UNUSED) {
+		function_name = EX_VAR(opline->op2.var);
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_CV != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_VAR == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CV != IS_UNUSED) {
+		zval *offset = EX_VAR(opline->op2.var);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_ulong hval;
+	zend_string *key;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	offset = EX_VAR(opline->op2.var);
+
+	do {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			HashTable *ht;
+
+unset_dim_array:
+			SEPARATE_ARRAY(container);
+			ht = Z_ARRVAL_P(container);
+offset_again:
+			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+				key = Z_STR_P(offset);
+				if (IS_CV != IS_CONST) {
+					if (ZEND_HANDLE_NUMERIC(key, hval)) {
+						goto num_index_dim;
+					}
+				}
+str_index_dim:
+				ZEND_ASSERT(ht != &EG(symbol_table));
+				zend_hash_del(ht, key);
+			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+				hval = Z_LVAL_P(offset);
+num_index_dim:
+				zend_hash_index_del(ht, hval);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+				offset = Z_REFVAL_P(offset);
+				goto offset_again;
+			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
+				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_NULL) {
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_FALSE) {
+				hval = 0;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_TRUE) {
+				hval = 1;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+				zend_use_resource_as_offset(offset);
+				hval = Z_RES_HANDLE_P(offset);
+				goto num_index_dim;
+			} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else {
+				zend_illegal_array_offset_unset(offset);
+			}
+			break;
+		} else if (Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto unset_dim_array;
+			}
+		}
+		if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+			container = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+			offset = ZVAL_UNDEFINED_OP2();
+		}
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+				offset++;
+			}
+			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+			zend_throw_error(NULL, "Cannot unset string offsets");
+		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
+			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
+			zend_false_to_array_deprecated();
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_VAR == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array;
+	zval *value, *variable_ptr;
+	uint32_t value_type;
+	HashTable *fe_ht;
+	HashPosition pos;
+
+	array = EX_VAR(opline->op1.var);
+	SAVE_OPLINE();
+	fe_ht = Z_ARRVAL_P(array);
+	pos = Z_FE_POS_P(array);
+	if (HT_IS_PACKED(fe_ht)) {
+		value = fe_ht->arPacked + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
+			}
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
+			}
+			pos++;
+			value++;
+		}
+		Z_FE_POS_P(array) = pos + 1;
+		if (0) {
+			ZVAL_LONG(EX_VAR(opline->result.var), pos);
+		}
+	} else {
+		Bucket *p;
+
+		p = fe_ht->arData + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
+			}
+			pos++;
+			value = &p->val;
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
+			}
+			p++;
+		}
+		Z_FE_POS_P(array) = pos;
+		if (0) {
+			if (!p->key) {
+				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
+			} else {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
+			}
+		}
+	}
+
+	variable_ptr = EX_VAR(opline->op2.var);
+	zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array;
+	zval *value, *variable_ptr;
+	uint32_t value_type;
+	HashTable *fe_ht;
+	HashPosition pos;
+
+	array = EX_VAR(opline->op1.var);
+	SAVE_OPLINE();
+	fe_ht = Z_ARRVAL_P(array);
+	pos = Z_FE_POS_P(array);
+	if (HT_IS_PACKED(fe_ht)) {
+		value = fe_ht->arPacked + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
+			}
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
+			}
+			pos++;
+			value++;
+		}
+		Z_FE_POS_P(array) = pos + 1;
+		if (1) {
+			ZVAL_LONG(EX_VAR(opline->result.var), pos);
+		}
+	} else {
+		Bucket *p;
+
+		p = fe_ht->arData + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
+			}
+			pos++;
+			value = &p->val;
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
+			}
+			p++;
+		}
+		Z_FE_POS_P(array) = pos;
+		if (1) {
+			if (!p->key) {
+				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
+			} else {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
+			}
+		}
+	}
+
+	variable_ptr = EX_VAR(opline->op2.var);
+	zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CATCH_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_class_entry *ce, *catch_ce;
+	zend_object *exception;
+
+	SAVE_OPLINE();
+	/* Check whether an exception has been thrown, if not, jump over code */
+	if (EG(exception) == NULL) {
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+	if (IS_UNUSED == IS_UNUSED) {
+		/* catch (T $e) / catch (Box $e): polymorphic inline cache keyed on
+		 * (type_args generation, called_scope). The generation is a monotonic
+		 * nonce per zend_type_arg_table allocation, so it's ABA-safe across
+		 * calls that reuse the same heap address. NULL type_args maps to
+		 * generation 0 (the counter starts at 1). zend_fetch_class dispatches
+		 * to the right resolver based on the packed sub-type on miss. */
+		void **slot = CACHE_ADDR(opline->extended_value & ~ZEND_LAST_CATCH);
+		uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+		zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+		/* slot[2] != NULL distinguishes a populated entry from an
+		 * uninitialized (all-zeros) slot, which otherwise matches
+		 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+		if (EXPECTED(slot[2] != NULL
+				&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+			catch_ce = (zend_class_entry*)slot[2];
+		} else {
+			catch_ce = zend_fetch_class(NULL,
+				opline->op1.num | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+			if (EXPECTED(catch_ce)) {
+				slot[0] = (void*)cur_gen;
+				slot[1] = (void*)cur_scope;
+				slot[2] = (void*)catch_ce;
+			}
+		}
+	} else {
+		catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
+		if (UNEXPECTED(catch_ce == NULL)) {
+			catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+
+			CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
+		}
+	}
+	ce = EG(exception)->ce;
+
+#ifdef HAVE_DTRACE
+	if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
+		DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
+	}
+#endif /* HAVE_DTRACE */
+
+	if (ce != catch_ce) {
+		if (!catch_ce || !instanceof_function(ce, catch_ce)) {
+			if (opline->extended_value & ZEND_LAST_CATCH) {
+				zend_rethrow_exception(execute_data);
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+		}
+	}
+
+	exception = EG(exception);
+	EG(exception) = NULL;
+	if (RETURN_VALUE_USED(opline)) {
+		/* Always perform a strict assignment. There is a reasonable expectation that if you
+		 * write "catch (Exception $e)" then $e will actually be instanceof Exception. As such,
+		 * we should not permit coercion to string here. */
+		zval tmp;
+		ZVAL_OBJ(&tmp, exception);
+		zend_assign_to_variable(EX_VAR(opline->result.var), &tmp, IS_TMP_VAR, /* strict */ 1);
+	} else {
+		OBJ_RELEASE(exception);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *obj;
+	zend_object *zobj;
+	zend_class_entry *ce, *scope;
+	zend_function *clone;
+	zend_object_clone_obj_t clone_call;
+
+	SAVE_OPLINE();
+	obj = &EX(This);
+
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
+	do {
+		if (IS_UNUSED == IS_CONST ||
+		    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
+			if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
+				obj = Z_REFVAL_P(obj);
+				if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
+					break;
+				}
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	zobj = Z_OBJ_P(obj);
+	ce = zobj->ce;
+	clone = ce->clone;
+	clone_call = zobj->handlers->clone_obj;
+	if (UNEXPECTED(clone_call == NULL)) {
+		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
+
+
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+		scope = EX(func)->op_array.scope;
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
+
+
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	uint32_t fetch_type;
+	zend_class_entry *called_scope, *scope;
+	USE_OPLINE
+
+	if (IS_UNUSED != IS_UNUSED) {
+		SAVE_OPLINE();
+		zval *op = NULL;
+		if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) {
+			ZVAL_DEREF(op);
+			if (Z_TYPE_P(op) != IS_OBJECT) {
+				zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name);
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	fetch_type = opline->op1.num;
+	if (zend_fetch_is_type_param(fetch_type)) {
+		SAVE_OPLINE();
+		zend_class_entry *resolved = zend_resolve_generic_type_param(
+			zend_unpack_type_param_index(fetch_type), fetch_type);
+		if (UNEXPECTED(!resolved)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), resolved->name);
+		ZEND_VM_NEXT_OPCODE();
+	}
+	scope = EX(func)->op_array.scope;
+	if (UNEXPECTED(scope == NULL)) {
+		SAVE_OPLINE();
+		zend_throw_error(NULL, "Cannot use \"%s\" in the global scope",
+			fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+			fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	switch (fetch_type) {
+		case ZEND_FETCH_CLASS_SELF:
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
+			break;
+		case ZEND_FETCH_CLASS_PARENT:
+			if (UNEXPECTED(scope->parent == NULL)) {
+				SAVE_OPLINE();
+				zend_throw_error(NULL,
+					"Cannot use \"parent\" when current class scope has no parent");
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
+			break;
+		case ZEND_FETCH_CLASS_STATIC:
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				called_scope = Z_OBJCE(EX(This));
+			} else {
+				called_scope = Z_CE(EX(This));
+			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
+			break;
+		default: ZEND_UNREACHABLE();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_UNUSED & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_UNUSED & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_UNUSED, property, IS_CONST,
+		((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_UNUSED == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_UNUSED == IS_UNUSED) {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_UNUSED == IS_UNUSED) {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var;
+
+	/* Compiler allocates the necessary number of zval slots to keep the rope */
+	rope = (zend_string**)EX_VAR(opline->result.var);
+	if (IS_CONST == IS_CONST) {
+		var = RT_CONSTANT(opline, opline->op2);
+		rope[0] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = RT_CONSTANT(opline, opline->op2);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CONST == IS_CV) {
+				rope[0] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[0] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[0] = zval_get_string_func(var);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *class_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	if (IS_CONST == IS_UNUSED) {
+		Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	} else if (IS_CONST == IS_CONST) {
+		zend_class_entry *ce = CACHED_PTR(opline->extended_value);
+
+		if (UNEXPECTED(ce == NULL)) {
+			class_name = RT_CONSTANT(opline, opline->op2);
+			ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num);
+			CACHE_PTR(opline->extended_value, ce);
+		}
+		Z_CE_P(EX_VAR(opline->result.var)) = ce;
+	} else {
+		class_name = RT_CONSTANT(opline, opline->op2);
+try_class_name:
+		if (Z_TYPE_P(class_name) == IS_OBJECT) {
+			Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
+		} else if (Z_TYPE_P(class_name) == IS_STRING) {
+			Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
+			class_name = Z_REFVAL_P(class_name);
+			goto try_class_name;
+		} else {
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Class name must be a valid object or a string");
+		}
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = &EX(This);
+
+	if (IS_CONST != IS_CONST) {
+		function_name = RT_CONSTANT(opline, opline->op2);
+	}
+
+	if (IS_CONST != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_UNUSED == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_UNUSED & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CONST != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CONST == IS_CONST) {
+					function_name = RT_CONSTANT(opline, opline->op2);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CONST == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CONST == IS_CONST) {
+			function_name = RT_CONSTANT(opline, opline->op2);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CONST == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CONST != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_UNUSED == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_CONST != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_UNUSED == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_UNUSED == IS_CONST &&
+	    IS_CONST == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_UNUSED != IS_CONST &&
+	           IS_CONST == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_CONST != IS_UNUSED) {
+		function_name = RT_CONSTANT(opline, opline->op2);
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CONST == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_CONST != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_UNUSED == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	uint32_t arg_num;
+
+	if (IS_CONST == IS_CONST) {
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg_num = zend_get_arg_offset_by_name(
+			EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1;
+		if (UNEXPECTED(arg_num == 0)) {
+			/* Treat this as a by-value argument, and throw an error during SEND. */
+			ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+		} else {
+			ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+		ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+	} else {
+		ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_constant *c;
+
+	c = CACHED_PTR(opline->extended_value);
+	if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
+		ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_class_entry *ce, *scope;
+	zend_class_constant *c;
+	zval *value, *zv, *constant_zv;
+	zend_string *constant_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+
+	do {
+		if (IS_UNUSED == IS_CONST && IS_CONST == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) {
+				value = CACHED_PTR(opline->extended_value + sizeof(void*));
+				break;
+			}
+		}
+		if (IS_UNUSED == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value))) {
+				ce = CACHED_PTR(opline->extended_value);
+			} else {
+				ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+				if (UNEXPECTED(ce == NULL)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+				CACHE_PTR(opline->extended_value, ce);
+			}
+		} else if (IS_UNUSED == IS_UNUSED) {
+			ce = zend_fetch_class(NULL, opline->op1.num);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op1.var));
+		}
+		if (IS_UNUSED != IS_CONST
+			&& IS_CONST == IS_CONST
+			&& EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
+			value = CACHED_PTR(opline->extended_value + sizeof(void*));
+			break;
+		}
+
+		constant_zv = RT_CONSTANT(opline, opline->op2);
+		if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
+			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+			HANDLE_EXCEPTION();
+		}
+		constant_name = Z_STR_P(constant_zv);
+		/* Magic 'class' for constant OP2 is caught at compile-time */
+		if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
+
+
+			ZEND_VM_NEXT_OPCODE();
+		}
+		zv = IS_CONST == IS_CONST
+			? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name)
+			: zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name);
+
+		if (EXPECTED(zv != NULL)) {
+			c = Z_PTR_P(zv);
+			scope = EX(func)->op_array.scope;
+			if (!zend_verify_const_access(c, scope)) {
+				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+
+			if (ce->ce_flags & ZEND_ACC_TRAIT) {
+				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+
+			bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
+			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
+				if (c->ce->type == ZEND_USER_CLASS) {
+					/* Recursion protection only applied to user constants, GH-18463 */
+					CONST_PROTECT_RECURSION(c);
+				}
+				zend_deprecated_class_constant(c, constant_name);
+				if (c->ce->type == ZEND_USER_CLASS) {
+					CONST_UNPROTECT_RECURSION(c);
+				}
+
+				if (EG(exception)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			value = &c->value;
+			// Enums require loading of all class constants to build the backed enum table
+			if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
+				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (IS_CONST == IS_CONST && !is_constant_deprecated) {
+				CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
+			}
+		} else {
+			zend_throw_error(NULL, "Undefined constant %s::%s",
+				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_UNUSED != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_UNUSED == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CONST == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = NULL;
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_UNUSED == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_UNUSED == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+		zval *key = RT_CONSTANT(opline, opline->op2);
+		if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_class_entry *ce, *scope;
+	zend_class_constant *c;
+	zval *value, *zv, *constant_zv;
+	zend_string *constant_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+
+	do {
+		if (IS_UNUSED == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) {
+				value = CACHED_PTR(opline->extended_value + sizeof(void*));
+				break;
+			}
+		}
+		if (IS_UNUSED == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value))) {
+				ce = CACHED_PTR(opline->extended_value);
+			} else {
+				ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+				if (UNEXPECTED(ce == NULL)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+				CACHE_PTR(opline->extended_value, ce);
+			}
+		} else if (IS_UNUSED == IS_UNUSED) {
+			ce = zend_fetch_class(NULL, opline->op1.num);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op1.var));
+		}
+		if (IS_UNUSED != IS_CONST
+			&& (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST
+			&& EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
+			value = CACHED_PTR(opline->extended_value + sizeof(void*));
+			break;
+		}
+
+		constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC);
+		if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
+			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			FREE_OP(opline->op2_type, opline->op2.var);
+			HANDLE_EXCEPTION();
+		}
+		constant_name = Z_STR_P(constant_zv);
+		/* Magic 'class' for constant OP2 is caught at compile-time */
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
+			FREE_OP(opline->op2_type, opline->op2.var);
+			ZEND_VM_NEXT_OPCODE();
+		}
+		zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST
+			? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name)
+			: zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name);
+
+		if (EXPECTED(zv != NULL)) {
+			c = Z_PTR_P(zv);
+			scope = EX(func)->op_array.scope;
+			if (!zend_verify_const_access(c, scope)) {
+				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+
+			if (ce->ce_flags & ZEND_ACC_TRAIT) {
+				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+
+			bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
+			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
+				if (c->ce->type == ZEND_USER_CLASS) {
+					/* Recursion protection only applied to user constants, GH-18463 */
+					CONST_PROTECT_RECURSION(c);
+				}
+				zend_deprecated_class_constant(c, constant_name);
+				if (c->ce->type == ZEND_USER_CLASS) {
+					CONST_UNPROTECT_RECURSION(c);
+				}
+
+				if (EG(exception)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			value = &c->value;
+			// Enums require loading of all class constants to build the backed enum table
+			if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
+				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+			if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) {
+				CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
+			}
+		} else {
+			zend_throw_error(NULL, "Undefined constant %s::%s",
+				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			FREE_OP(opline->op2_type, opline->op2.var);
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
+
+	FREE_OP(opline->op2_type, opline->op2.var);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_UNUSED & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_UNUSED & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_UNUSED, property, IS_TMP_VAR,
+		((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_UNUSED == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_UNUSED == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_UNUSED == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var;
+
+	/* Compiler allocates the necessary number of zval slots to keep the rope */
+	rope = (zend_string**)EX_VAR(opline->result.var);
+	if (IS_TMP_VAR == IS_CONST) {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		rope[0] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_CV) {
+				rope[0] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[0] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[0] = zval_get_string_func(var);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *class_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	if (IS_TMP_VAR == IS_UNUSED) {
+		Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	} else if (IS_TMP_VAR == IS_CONST) {
+		zend_class_entry *ce = CACHED_PTR(opline->extended_value);
+
+		if (UNEXPECTED(ce == NULL)) {
+			class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num);
+			CACHE_PTR(opline->extended_value, ce);
+		}
+		Z_CE_P(EX_VAR(opline->result.var)) = ce;
+	} else {
+		class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+try_class_name:
+		if (Z_TYPE_P(class_name) == IS_OBJECT) {
+			Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
+		} else if (Z_TYPE_P(class_name) == IS_STRING) {
+			Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
+			class_name = Z_REFVAL_P(class_name);
+			goto try_class_name;
+		} else {
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Class name must be a valid object or a string");
+		}
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = &EX(This);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	}
+
+	if (IS_TMP_VAR != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_UNUSED == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_UNUSED & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_TMP_VAR != IS_CONST) {
+							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				}
+				zend_invalid_method_call(object, function_name);
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_TMP_VAR == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_UNUSED == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				HANDLE_EXCEPTION();
+			}
+			if (IS_TMP_VAR != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_UNUSED == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_UNUSED == IS_CONST &&
+	    IS_TMP_VAR == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_UNUSED != IS_CONST &&
+	           IS_TMP_VAR == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_TMP_VAR != IS_UNUSED) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+					zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_UNUSED == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_UNUSED != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_UNUSED == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = NULL;
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_UNUSED == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_UNUSED == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *class_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	if (IS_UNUSED == IS_UNUSED) {
+		Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	} else if (IS_UNUSED == IS_CONST) {
+		zend_class_entry *ce = CACHED_PTR(opline->extended_value);
+
+		if (UNEXPECTED(ce == NULL)) {
+			class_name = NULL;
+			ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num);
+			CACHE_PTR(opline->extended_value, ce);
+		}
+		Z_CE_P(EX_VAR(opline->result.var)) = ce;
+	} else {
+		class_name = NULL;
+try_class_name:
+		if (Z_TYPE_P(class_name) == IS_OBJECT) {
+			Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
+		} else if (Z_TYPE_P(class_name) == IS_STRING) {
+			Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num);
+		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
+			class_name = Z_REFVAL_P(class_name);
+			goto try_class_name;
+		} else {
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Class name must be a valid object or a string");
+		}
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_UNUSED != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_UNUSED == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_UNUSED == IS_CONST &&
+	    IS_UNUSED == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_UNUSED != IS_CONST &&
+	           IS_UNUSED == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_UNUSED != IS_UNUSED) {
+		function_name = NULL;
+		if (IS_UNUSED != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_UNUSED == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_UNUSED != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_UNUSED == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	if (IS_UNUSED == IS_UNUSED) {
+		SAVE_OPLINE();
+		zend_verify_missing_return_type(EX(func));
+		HANDLE_EXCEPTION();
+	} else {
+/* prevents "undefined variable opline" errors */
+#if 0 || (IS_UNUSED != IS_UNUSED)
+		USE_OPLINE
+		zval *retval_ref, *retval_ptr;
+		zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
+		retval_ref = retval_ptr = NULL;
+
+		if (IS_UNUSED == IS_CONST) {
+			ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
+			retval_ref = retval_ptr = EX_VAR(opline->result.var);
+		} else if (IS_UNUSED == IS_VAR) {
+			if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+				retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr);
+			}
+			ZVAL_DEREF(retval_ptr);
+		} else if (IS_UNUSED == IS_CV) {
+			ZVAL_DEREF(retval_ptr);
+		}
+
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+
+		if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+			SAVE_OPLINE();
+			retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		zend_reference *ref = NULL;
+		if (UNEXPECTED(retval_ref != retval_ptr)) {
+			if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+				ref = Z_REF_P(retval_ref);
+			} else {
+				/* A cast might happen - unwrap the reference if this is a by-value return */
+				if (Z_REFCOUNT_P(retval_ref) == 1) {
+					ZVAL_UNREF(retval_ref);
+				} else {
+					Z_DELREF_P(retval_ref);
+					ZVAL_COPY(retval_ref, retval_ptr);
+				}
+				retval_ptr = retval_ref;
+			}
+		}
+
+		SAVE_OPLINE();
+		if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) {
+			zend_verify_return_error(EX(func), retval_ptr);
+			HANDLE_EXCEPTION();
+		}
+		ZEND_VM_NEXT_OPCODE();
+#endif
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	SAVE_OPLINE();
+	zend_verify_never_error(EX(func));
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg_num = zend_get_arg_offset_by_name(
+			EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1;
+		if (UNEXPECTED(arg_num == 0)) {
+			/* Treat this as a by-value argument, and throw an error during SEND. */
+			ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(0)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+		} else {
+			ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+		ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+	} else {
+		ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg_num = zend_get_arg_offset_by_name(
+			EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1;
+		if (UNEXPECTED(arg_num == 0)) {
+			/* Treat this as a by-value argument, and throw an error during SEND. */
+			ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(1)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+		} else {
+			ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+		ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+	} else {
+		ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_execute_data *call = execute_data->call;
+	if (EXPECTED(!(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF))) {
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	zend_handle_undef_args(call);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *result;
+	zend_function *constructor;
+	zend_class_entry *ce;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+	if (IS_UNUSED == IS_CONST) {
+		ce = CACHED_PTR(opline->op2.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+			CACHE_PTR(opline->op2.num, ce);
+		}
+	} else if (IS_UNUSED == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	/* Naked `new` of a bare generic class (via `new static()`, `new $name`,
+	 * or any path that didn't go through compile-time canonical-name rewrite).
+	 * Skip when ZEND_VERIFY_GENERIC_ARGUMENTS follows — that opcode handles
+	 * the synthesis-and-swap for the turbofish path. Otherwise: if every
+	 * type parameter has a default, synthesize and use the defaults monomorph.
+	 * For `new static()` / lexical paths with no defaults, fall back to a
+	 * bare instance (preserves the lexical-self semantic for generic classes
+	 * whose authors didn't declare defaults). For dynamic `new $name()` we
+	 * throw — the caller spelled out a generic class by name and a bare
+	 * instance with erased T is almost never what they want.
+	 *
+	 * IS_UNUSED distinguishes: IS_UNUSED → static/self/parent (lenient);
+	 * IS_VAR → dynamic name resolved via FETCH_CLASS (strict). */
+	if (UNEXPECTED(IS_UNUSED != IS_CONST && ce->generic_parameters
+			&& (opline + 1)->opcode != ZEND_VERIFY_GENERIC_ARGUMENTS)) {
+		if (ce->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS) {
+			ce = zend_synthesize_monomorph(ce, NULL, 0);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else if (IS_UNUSED == IS_VAR) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments "
+				"via dynamic class name; no defaults declared",
+				ZSTR_VAL(ce->name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		/* IS_UNUSED with no defaults: fall through with the bare ce. */
+	}
+
+	result = EX_VAR(opline->result.var);
+	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
+		ZVAL_UNDEF(result);
+		HANDLE_EXCEPTION();
+	}
+
+	constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
+	if (constructor == NULL) {
+		/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
+		 * opcode is DO_FCALL in case EXT instructions are used. */
+		if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
+			ZEND_VM_NEXT_OPCODE_EX(1, 2);
+		}
+
+		if (UNEXPECTED(EG(exception))) {
+			HANDLE_EXCEPTION();
+		}
+
+		/* Perform a dummy function call */
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
+			opline->extended_value, NULL);
+	} else {
+		if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
+			init_func_run_time_cache(&constructor->op_array);
+		}
+		/* We are not handling overloaded classes right now */
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS,
+			constructor,
+			opline->extended_value,
+			Z_OBJ_P(result));
+		Z_ADDREF_P(result);
+	}
+
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_UNUSED != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = NULL;
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_UNUSED == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_UNUSED == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *key = NULL;
+		if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	uint32_t arity = opline->op2.num;
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	/* Skip the entry lookup for speculative sites (args_id == 0). */
+	zend_turbofish_args_entry *tf_entry =
+		(IS_UNUSED == IS_UNUSED && opline->extended_value)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_UNUSED == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_UNUSED) {
+		/* Erased fast path: non-generic speculative site, nothing to verify. */
+		if (args_box == NULL
+				&& (!ZEND_USER_CODE(call->func->type)
+					|| !call->func->op_array.generic_parameters)) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Concrete turbofish args: dispatch to a synthesized plain monomorph and
+		 * skip generic verification (the monomorph's RECV does concrete checks). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, arity, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_verify_check_exception;
+			}
+		}
+		/* Runtime-promoted site: install the cached invariant table after a func
+		 * guard (cache_slot[3], bit1 = value check is a no-op). */
+		if (cache_slot && cache_slot[3]
+				&& ((uintptr_t) cache_slot[3] & ~(uintptr_t)3) == (uintptr_t) call->func) {
+			call->type_args = (zend_type_arg_table *) cache_slot[0];
+			if (((uintptr_t) cache_slot[3] & 2) == 0) {
+				zend_verify_generic_arg_types(call, args_box);
+				if (UNEXPECTED(EG(exception))) {
+					goto generic_verify_check_exception;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Inner/inference call already monomorphized: swap func + reinstall table. */
+		if (cache_slot && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH) {
+			zend_type_arg_table *ma = NULL;
+			zend_function *mono = zend_try_monomorph_resolved_call(call, NULL, cache_slot, &ma);
+			if (mono) {
+				call->func = mono;
+				call->type_args = ma;
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete turbofish VERIFY: install the precomputed SHM table after
+			 * the arity/bound check (memoized in cache_slot[0] per resolved func).
+			 * The persisted guard excludes the no-opcache heap-table case. */
+			bool checked = (cache_slot && cache_slot[0] == (void *) call->func);
+			if (!checked) {
+				zend_check_generic_call_arguments(call->func, arity, args_box);
+			}
+			if (EXPECTED(!EG(exception))) {
+				if (!checked && cache_slot) {
+					cache_slot[0] = (void *) call->func;
+				}
+				call->type_args = tf_entry->concrete_table;
+				if (!tf_entry->concrete_skip_value_check) {
+					zend_verify_generic_arg_types(call, args_box);
+				}
+			}
+		} else {
+			zend_check_generic_call_arguments(call->func, arity, args_box);
+			if (!EG(exception)) {
+				zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+				if (t) {
+					if (call->type_args) {
+						zend_type_arg_table_destroy(call->type_args);
+					}
+					call->type_args = t;
+				}
+				/* If the resolved table is invariant (CONCRETE sentinel), try to
+				 * monomorphize so later calls take the mono fast path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					zend_type_arg_table *ma = NULL;
+					zend_function *mono = zend_try_monomorph_resolved_call(call, t, cache_slot, &ma);
+					if (mono) {
+						call->func = mono;
+						call->type_args = ma;
+						ZEND_VM_NEXT_OPCODE();
+					}
+				}
+				zend_verify_generic_arg_types(call, args_box);
+				/* Promote the invariant site: record the resolved callee in
+				 * cache_slot[3] so later calls take the minimal install path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					/* Tag bits (func is >=8-aligned): bit0 = PROMOTED, bit1 = value
+					 * check is a no-op. slot[1] stays CONCRETE so the build cache
+					 * keeps returning the table on a func-guard miss. */
+					uintptr_t fn = (uintptr_t) call->func | 1u;
+					if (ZEND_USER_CODE(call->func->type)
+							&& call->func->op_array.generic_types
+							&& call->func->op_array.generic_types->parameters
+							&& zend_count_generic_value_checks(
+								call->func->op_array.generic_types->parameters) == 0) {
+						fn |= 2; /* value check is a no-op for this callee */
+					}
+					cache_slot[3] = (void *) fn;
+				}
+			}
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Monomorphize: synthesize (or look up) Box and swap both the
+		 * object's class entry and the pending constructor call. The monomorph
+		 * shares Box's property layout, so swapping ce is safe; swapping
+		 * call->func ensures the constructor's RECV opcodes verify against the
+		 * monomorph's substituted arg_info. The call-site inline cache (incl. the
+		 * concrete-args fast path) lives in zend_apply_generic_new. */
+		zend_apply_generic_new(new_obj, call, args_box, arity, cache_slot, /* do_checks */ true);
+	}
+
+generic_verify_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		/* Args have already been pushed by the SEND opcodes preceding the
+		 * VERIFY emission for call kind; release them so refcounted values
+		 * don't leak. */
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+/* Installs the type-arg table (and, for `new`, swaps the object's class to
+ * its monomorph) without running the runtime arity + bound checks that
+ * VERIFY does. Emitted by the compiler when the callee/ce is statically
+ * known, the turbofish args are concrete, and bounds were validated at
+ * compile time — so the runtime checks are pure overhead. The value-arg
+ * type-check (zend_verify_generic_arg_types) still runs since value
+ * arguments are runtime values. */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	zend_turbofish_args_entry *tf_entry =
+		(IS_UNUSED == IS_UNUSED)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_UNUSED == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_UNUSED) {
+		/* Dispatch to a synthesized plain monomorph (see ZEND_VERIFY_GENERIC_ARGUMENTS). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, opline->op2.num, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_install_check_exception;
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete INSTALL: install the precomputed SHM table directly. The
+			 * persisted guard excludes the no-opcache heap-table case (whose table
+			 * is owned by the turbofish entry and must not be freed at teardown). */
+			call->type_args = tf_entry->concrete_table;
+			if (!tf_entry->concrete_skip_value_check) {
+				zend_verify_generic_arg_types(call, args_box);
+			}
+		} else {
+			zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+			if (t) {
+				if (call->type_args) {
+					zend_type_arg_table_destroy(call->type_args);
+				}
+				call->type_args = t;
+			}
+			zend_verify_generic_arg_types(call, args_box);
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Statically pre-validated: skip the runtime arity/bound check, but
+		 * still cache the resolved monomorph at the call site. */
+		zend_apply_generic_new(new_obj, call, args_box, opline->op2.num, cache_slot, /* do_checks */ false);
+	}
+
+generic_install_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
+		zval *result = EX_VAR(opline->result.var);
+
+		ZVAL_OBJ(result, Z_OBJ(EX(This)));
+		Z_ADDREF_P(result);
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	/* For symbol tables we need to deal with exactly the same problems as for property tables. */
+	ZVAL_ARR(EX_VAR(opline->result.var),
+		zend_proptable_to_symtable(&EG(symbol_table), /* always_duplicate */ 1));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	ZVAL_BOOL(EX_VAR(opline->result.var),
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		 (Z_TYPE(EX(This)) == IS_OBJECT));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (IS_UNUSED == IS_UNUSED) {
+		SAVE_OPLINE();
+		if (UNEXPECTED(!EX(func)->common.scope)) {
+			zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		} else {
+			zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		zval *op1;
+
+		SAVE_OPLINE();
+		op1 = NULL;
+		while (1) {
+			if (Z_TYPE_P(op1) == IS_OBJECT) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
+			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+				op1 = Z_REFVAL_P(op1);
+				continue;
+			} else {
+				if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+					ZVAL_UNDEFINED_OP1();
+				}
+				zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+			}
+			break;
+		}
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (Z_TYPE(EX(This)) == IS_OBJECT) {
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE(EX(This))->name);
+	} else if (Z_CE(EX(This))) {
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_CE(EX(This))->name);
+	} else {
+		ZEND_ASSERT(!EX(func)->common.scope);
+		SAVE_OPLINE();
+		zend_throw_error(NULL, "get_called_class() must be called from within a class");
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	ZVAL_LONG(EX_VAR(opline->result.var), EX_NUM_ARGS());
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_array *ht;
+	uint32_t arg_count, result_size, skip;
+
+	arg_count = EX_NUM_ARGS();
+	if (IS_UNUSED == IS_CONST) {
+		skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1));
+		if (arg_count < skip) {
+			result_size = 0;
+		} else {
+			result_size = arg_count - skip;
+		}
+	} else {
+		skip = 0;
+		result_size = arg_count;
+	}
+
+	if (result_size) {
+		SAVE_OPLINE();
+		uint32_t first_extra_arg = EX(func)->op_array.num_args;
+
+		ht = zend_new_array(result_size);
+		ZVAL_ARR(EX_VAR(opline->result.var), ht);
+		zend_hash_real_init_packed(ht);
+		ZEND_HASH_FILL_PACKED(ht) {
+			zval *p, *q;
+			uint32_t i = skip;
+			p = EX_VAR_NUM(i);
+			if (arg_count > first_extra_arg) {
+				while (i < first_extra_arg) {
+					q = p;
+					if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
+						ZVAL_DEREF(q);
+						if (Z_OPT_REFCOUNTED_P(q)) {
+							Z_ADDREF_P(q);
+						}
+						ZEND_HASH_FILL_SET(q);
+					} else {
+						ZEND_HASH_FILL_SET_NULL();
+					}
+					ZEND_HASH_FILL_NEXT();
+					p++;
+					i++;
+				}
+				if (skip < first_extra_arg) {
+					skip = 0;
+				} else {
+					skip -= first_extra_arg;
+				}
+				p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip);
+			}
+			while (i < arg_count) {
+				q = p;
+				if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
+					ZVAL_DEREF(q);
+					if (Z_OPT_REFCOUNTED_P(q)) {
+						Z_ADDREF_P(q);
+					}
+					ZEND_HASH_FILL_SET(q);
+				} else {
+					ZEND_HASH_FILL_SET_NULL();
+				}
+				ZEND_HASH_FILL_NEXT();
+				p++;
+				i++;
+			}
+		} ZEND_HASH_FILL_END();
+		ht->nNumOfElements = result_size;
+	} else {
+		ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var));
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+/* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+
+	if (opline->extended_value != (uint32_t)-1) {
+		zend_object *closure = CACHED_PTR(opline->extended_value);
+		if (closure) {
+			ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure);
+		} else {
+			/* Rotate the key for better hash distribution. */
+			const int shift = sizeof(size_t) == 4 ? 6 : 7;
+			zend_ulong key = (zend_ulong)(uintptr_t)call->func;
+			key = (key >> shift) | (key << ((sizeof(key) * 8) - shift));
+			zval *closure_zv = zend_hash_index_lookup(&EG(callable_convert_cache), key);
+			if (Z_TYPE_P(closure_zv) == IS_NULL) {
+				zend_closure_from_frame(closure_zv, call);
+			}
+			ZEND_ASSERT(Z_TYPE_P(closure_zv) == IS_OBJECT);
+			closure = Z_OBJ_P(closure_zv);
+			ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure);
+			CACHE_PTR(opline->extended_value, closure);
+		}
+	} else {
+		zend_closure_from_frame(EX_VAR(opline->result.var), call);
+	}
+
+	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	}
+
+	EX(call) = call->prev_execute_data;
+
+	zend_vm_stack_free_call_frame(call);
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+
+#if 0 || 0
+	if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline);
+		function(result);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+
+#if 0 || 1
+	if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline);
+		function(result);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_UNUSED == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_UNUSED & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_UNUSED & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_UNUSED, property, IS_CV,
+		((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_UNUSED == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_UNUSED == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = &EX(This);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_UNUSED == IS_UNUSED) {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = &EX(This);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_UNUSED == IS_UNUSED) {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var;
+
+	/* Compiler allocates the necessary number of zval slots to keep the rope */
+	rope = (zend_string**)EX_VAR(opline->result.var);
+	if (IS_CV == IS_CONST) {
+		var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		rope[0] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = EX_VAR(opline->op2.var);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CV == IS_CV) {
+				rope[0] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[0] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[0] = zval_get_string_func(var);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *class_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_UNUSED) {
+		Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	} else if (IS_CV == IS_CONST) {
+		zend_class_entry *ce = CACHED_PTR(opline->extended_value);
+
+		if (UNEXPECTED(ce == NULL)) {
+			class_name = EX_VAR(opline->op2.var);
+			ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num);
+			CACHE_PTR(opline->extended_value, ce);
+		}
+		Z_CE_P(EX_VAR(opline->result.var)) = ce;
+	} else {
+		class_name = EX_VAR(opline->op2.var);
+try_class_name:
+		if (Z_TYPE_P(class_name) == IS_OBJECT) {
+			Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
+		} else if (Z_TYPE_P(class_name) == IS_STRING) {
+			Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
+			class_name = Z_REFVAL_P(class_name);
+			goto try_class_name;
+		} else {
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Class name must be a valid object or a string");
+		}
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = &EX(This);
+
+	if (IS_CV != IS_CONST) {
+		function_name = EX_VAR(opline->op2.var);
+	}
+
+	if (IS_CV != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_UNUSED == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_UNUSED & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CV != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CV == IS_CONST) {
+					function_name = EX_VAR(opline->op2.var);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CV == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CV == IS_CONST) {
+			function_name = EX_VAR(opline->op2.var);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CV != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_UNUSED == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_CV != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_UNUSED == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_UNUSED == IS_CONST &&
+	    IS_CV == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_UNUSED != IS_CONST &&
+	           IS_CV == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_CV != IS_UNUSED) {
+		function_name = EX_VAR(opline->op2.var);
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_CV != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_UNUSED == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_UNUSED != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_UNUSED == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = &EX(This);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_UNUSED == IS_CONST ||
+	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_UNUSED != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = NULL;
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = NULL;
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_UNUSED == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = NULL;
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_UNUSED == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_UNUSED == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_UNUSED == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+
+	val = EX_VAR(opline->op1.var);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		increment_function(var_ptr);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_increment_function(var_ptr);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_increment_function(var_ptr);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		decrement_function(var_ptr);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_decrement_function(var_ptr);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		fast_long_decrement_function(var_ptr);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+
+		increment_function(var_ptr);
+	} while (0);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+		fast_long_increment_function(var_ptr);
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV  zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(var_ptr);
+	}
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+
+		decrement_function(var_ptr);
+	} while (0);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+		fast_long_decrement_function(var_ptr);
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *z;
+
+	SAVE_OPLINE();
+	z = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_P(z) == IS_STRING) {
+		zend_string *str = Z_STR_P(z);
+
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
+		}
+	} else {
+		zend_string *str = zval_get_string_func(z);
+
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
+		} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		zend_string_release_ex(str, 0);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	uint8_t op1_type;
+
+	val = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	SAVE_OPLINE();
+	op1_type = IS_CV;
+	if (i_zend_is_true(val)) {
+		opline++;
+	} else {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	uint8_t op1_type;
+
+	val = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	op1_type = IS_CV;
+	if (i_zend_is_true(val)) {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		opline++;
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	bool ret;
+
+	val = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	SAVE_OPLINE();
+	ret = i_zend_is_true(val);
+
+
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline++;
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	bool ret;
+
+	val = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	SAVE_OPLINE();
+	ret = i_zend_is_true(val);
+
+
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline++;
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+
+
+	retval_ptr = EX_VAR(opline->op1.var);
+	return_value = EX(return_value);
+
+
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		retval_ptr = ZVAL_UNDEFINED_OP1();
+		if (return_value) {
+			ZVAL_NULL(return_value);
+		}
+	} else if (!return_value) {
+		if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
+				SAVE_OPLINE();
+				rc_dtor_func(Z_COUNTED_P(retval_ptr));
+			}
+		}
+	} else {
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZVAL_COPY_VALUE(return_value, retval_ptr);
+			if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+					Z_ADDREF_P(return_value);
+				}
+			}
+		} else if (IS_CV == IS_CV) {
+			do {
+				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
+							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+							ZVAL_COPY_VALUE(return_value, retval_ptr);
+							if (GC_MAY_LEAK(ref)) {
+								SAVE_OPLINE();
+								gc_possible_root(ref);
+							}
+							ZVAL_NULL(retval_ptr);
+							break;
+						} else {
+							Z_ADDREF_P(retval_ptr);
+						}
+					} else {
+						retval_ptr = Z_REFVAL_P(retval_ptr);
+						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+							Z_ADDREF_P(retval_ptr);
+						}
+					}
+				}
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			} while (0);
+		} else /* if (IS_CV == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+				retval_ptr = Z_REFVAL_P(retval_ptr);
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					Z_ADDREF_P(retval_ptr);
+				}
+			} else {
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			}
+		}
+	}
+
+
+
+
+
+
+	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+
+
+	SAVE_OPLINE();
+
+	return_value = EX(return_value);
+
+
+	do {
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR)) ||
+		    (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
+			/* Not supposed to happen, but we'll allow it */
+			zend_error(E_NOTICE, "Only variable references should be returned by reference");
+
+			retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+			if (!return_value) {
+
+
+			} else {
+				if (IS_CV == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+					ZVAL_COPY_VALUE(return_value, retval_ptr);
+					break;
+				}
+
+				ZVAL_NEW_REF(return_value, retval_ptr);
+				if (IS_CV == IS_CONST) {
+					Z_TRY_ADDREF_P(retval_ptr);
+				}
+			}
+			break;
+		}
+
+		retval_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+
+		if (IS_CV == IS_VAR) {
+			ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
+			if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
+				zend_error(E_NOTICE, "Only variable references should be returned by reference");
+				if (return_value) {
+					ZVAL_NEW_REF(return_value, retval_ptr);
+				} else {
+
+
+				}
+				break;
+			}
+		}
+
+		if (return_value) {
+			if (Z_ISREF_P(retval_ptr)) {
+				Z_ADDREF_P(retval_ptr);
+			} else {
+				ZVAL_MAKE_REF_EX(retval_ptr, 2);
+			}
+			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
+		}
+
+
+	} while (0);
+
+
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval;
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	retval = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+	/* Copy return value into generator->retval */
+	if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+		ZVAL_COPY_VALUE(&generator->retval, retval);
+		if (IS_CV == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
+				Z_ADDREF(generator->retval);
+			}
+		}
+	} else if (IS_CV == IS_CV) {
+		ZVAL_COPY_DEREF(&generator->retval, retval);
+	} else /* if (IS_CV == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_refcounted *ref = Z_COUNTED_P(retval);
+
+			retval = Z_REFVAL_P(retval);
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(retval)) {
+				Z_ADDREF_P(retval);
+			}
+		} else {
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+		}
+	}
+
+
+	EG(current_execute_data) = EX(prev_execute_data);
+
+	/* Close the generator to free up resources */
+	zend_generator_close(generator, 1);
+
+	/* Pass execution back to handling code */
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	SAVE_OPLINE();
+	value = EX_VAR(opline->op1.var);
+
+	do {
+		if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+				if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Can only throw objects");
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	Z_TRY_ADDREF_P(value);
+	zend_throw_exception_object(value);
+
+
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *arg, *param;
+
+	SAVE_OPLINE();
+
+	arg = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	param = ZEND_CALL_VAR(EX(call), opline->result.var);
+	if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
+		zend_param_must_be_ref(EX(call)->func, opline->op2.num);
+		Z_TRY_ADDREF_P(arg);
+		ZVAL_NEW_REF(param, arg);
+	} else {
+		ZVAL_COPY(param, arg);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+
+	val = EX_VAR(opline->op1.var);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *obj;
+	zend_object *zobj;
+	zend_class_entry *ce, *scope;
+	zend_function *clone;
+	zend_object_clone_obj_t clone_call;
+
+	SAVE_OPLINE();
+	obj = EX_VAR(opline->op1.var);
+
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
+	do {
+		if (IS_CV == IS_CONST ||
+		    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
+				obj = Z_REFVAL_P(obj);
+				if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
+					break;
+				}
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	zobj = Z_OBJ_P(obj);
+	ce = zobj->ce;
+	clone = ce->clone;
+	clone_call = zobj->handlers->clone_obj;
+	if (UNEXPECTED(clone_call == NULL)) {
+		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
+
+
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+		scope = EX(func)->op_array.scope;
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
+
+
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	zval *result = EX_VAR(opline->result.var);
+
+	SAVE_OPLINE();
+	expr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+	switch (opline->extended_value) {
+		case IS_LONG:
+			ZVAL_LONG(result, zval_get_long(expr));
+			break;
+		case IS_DOUBLE:
+			ZVAL_DOUBLE(result, zval_get_double(expr));
+			break;
+		case IS_STRING:
+			ZVAL_STR(result, zval_get_string(expr));
+			break;
+		default:
+			ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead");
+			if (IS_CV & (IS_VAR|IS_CV)) {
+				ZVAL_DEREF(expr);
+			}
+			/* If value is already of correct type, return it directly */
+			if (Z_TYPE_P(expr) == opline->extended_value) {
+				ZVAL_COPY_VALUE(result, expr);
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+				} else if (IS_CV != IS_TMP_VAR) {
+					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+				}
+
+
+				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+			}
+
+			if (opline->extended_value == IS_ARRAY) {
+				zend_cast_zval_to_array(result, expr, IS_CV);
+			} else {
+				ZEND_ASSERT(opline->extended_value == IS_OBJECT);
+				zend_cast_zval_to_object(result, expr, IS_CV);
+			}
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_op_array *new_op_array;
+	zval *inc_filename;
+
+	SAVE_OPLINE();
+	inc_filename = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
+			destroy_op_array(new_op_array);
+			efree_size(new_op_array, sizeof(zend_op_array));
+		}
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	} else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_TRUE(EX_VAR(opline->result.var));
+		}
+	} else if (UNEXPECTED(new_op_array == NULL)) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_FALSE(EX_VAR(opline->result.var));
+		}
+	} else if (new_op_array->last == 1
+			&& new_op_array->opcodes[0].opcode == ZEND_RETURN
+			&& new_op_array->opcodes[0].op1_type == IS_CONST
+			&& EXPECTED(zend_execute_ex == execute_ex)) {
+		if (RETURN_VALUE_USED(opline)) {
+			const zend_op *op = new_op_array->opcodes;
+
+			ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1));
+		}
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+	} else {
+		zval *return_value = NULL;
+		zend_execute_data *call;
+		if (RETURN_VALUE_USED(opline)) {
+			return_value = EX_VAR(opline->result.var);
+		}
+
+		new_op_array->scope = EX(func)->op_array.scope;
+
+		call = zend_vm_stack_push_call_frame(
+			(Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+			(zend_function*)new_op_array, 0,
+			Z_PTR(EX(This)));
+
+		if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
+			call->symbol_table = EX(symbol_table);
+		} else {
+			call->symbol_table = zend_rebuild_symbol_table();
+		}
+
+		call->prev_execute_data = execute_data;
+		i_init_code_execute_data(call, new_op_array, return_value);
+
+
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+
+
+			ZEND_VM_ENTER();
+		} else {
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+			zend_vm_stack_free_call_frame(call);
+		}
+
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+
+
+			UNDEF_RESULT();
+			HANDLE_EXCEPTION();
+		}
+	}
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *result;
+
+	SAVE_OPLINE();
+
+	array_ptr = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, array_ptr);
+		if (IS_CV != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+			Z_ADDREF_P(array_ptr);
+		}
+		Z_FE_POS_P(result) = 0;
+
+
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		zend_object *zobj = Z_OBJ_P(array_ptr);
+		if (!zobj->ce->get_iterator) {
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			HashTable *properties = zobj->properties;
+			if (properties) {
+				if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+					if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+						GC_DELREF(properties);
+					}
+					properties = zobj->properties = zend_array_dup(properties);
+				}
+			} else {
+				properties = zobj->handlers->get_properties(zobj);
+			}
+
+			result = EX_VAR(opline->result.var);
+			ZVAL_COPY_VALUE(result, array_ptr);
+			if (IS_CV != IS_TMP_VAR) {
+				Z_ADDREF_P(array_ptr);
+			}
+
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(result) = (uint32_t) -1;
+
+
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
+
+			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+
+
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *array_ref;
+
+	SAVE_OPLINE();
+
+	if (IS_CV == IS_VAR || IS_CV == IS_CV) {
+		array_ref = array_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(array_ref)) {
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+	} else {
+		array_ref = array_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	}
+
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		if (IS_CV == IS_VAR || IS_CV == IS_CV) {
+			if (array_ptr == array_ref) {
+				ZVAL_NEW_REF(array_ref, array_ref);
+				array_ptr = Z_REFVAL_P(array_ref);
+			}
+			Z_ADDREF_P(array_ref);
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+		} else {
+			array_ref = EX_VAR(opline->result.var);
+			ZVAL_NEW_REF(array_ref, array_ptr);
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+		if (IS_CV == IS_CONST) {
+			ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr)));
+		} else {
+			SEPARATE_ARRAY(array_ptr);
+		}
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
+
+
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+			zend_object *zobj = Z_OBJ_P(array_ptr);
+			HashTable *properties;
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (IS_CV == IS_VAR || IS_CV == IS_CV) {
+				if (array_ptr == array_ref) {
+					ZVAL_NEW_REF(array_ref, array_ref);
+					array_ptr = Z_REFVAL_P(array_ref);
+				}
+				Z_ADDREF_P(array_ref);
+				ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+			} else {
+				array_ptr = EX_VAR(opline->result.var);
+				ZVAL_COPY_VALUE(array_ptr, array_ref);
+			}
+			if (Z_OBJ_P(array_ptr)->properties
+			 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
+				if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
+					GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+				}
+				Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+			}
+
+			properties = Z_OBJPROP_P(array_ptr);
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
+
+
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
+
+			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+
+
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zend_reference *ref = NULL;
+	bool ret;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+	if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(value)) {
+		if (IS_CV == IS_VAR) {
+			ref = Z_REF_P(value);
+		}
+		value = Z_REFVAL_P(value);
+	}
+
+	ret = i_zend_is_true(value);
+
+	if (UNEXPECTED(EG(exception))) {
+
+
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (ret) {
+		zval *result = EX_VAR(opline->result.var);
+
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_CV == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_CV == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if (IS_CV == IS_VAR && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zend_reference *ref = NULL;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+
+	if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+		if (IS_CV & IS_VAR) {
+			ref = Z_REF_P(value);
+		}
+		value = Z_REFVAL_P(value);
+	}
+
+	if (Z_TYPE_P(value) > IS_NULL) {
+		zval *result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_CV == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_CV == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if ((IS_CV & IS_VAR) && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	if ((IS_CV & IS_VAR) && ref) {
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val, *result;
+
+	val = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_P(val) > IS_NULL) {
+		do {
+			if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) {
+				val = Z_REFVAL_P(val);
+				if (Z_TYPE_P(val) <= IS_NULL) {
+
+
+					break;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		} while (0);
+	}
+
+	result = EX_VAR(opline->result.var);
+	uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK;
+	if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) {
+		ZVAL_NULL(result);
+		if (IS_CV == IS_CV
+			&& UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)
+			&& (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0
+		) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+	} else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) {
+		ZVAL_FALSE(result);
+	} else {
+		ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY);
+		ZVAL_TRUE(result);
+	}
+
+	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *result = EX_VAR(opline->result.var);
+
+	value = EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(result);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY_DEREF(result, value);
+	} else if (IS_CV == IS_VAR) {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			ZVAL_COPY_VALUE(result, Z_REFVAL_P(value));
+			if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
+				efree_size(Z_REF_P(value), sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		} else {
+			ZVAL_COPY_VALUE(result, value);
+		}
+	} else {
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_CV == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) {
+				Z_ADDREF_P(result);
+			}
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+	zval *val;
+
+	SAVE_OPLINE();
+	val = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+
+
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+yield_from_try_again:
+	if (Z_TYPE_P(val) == IS_ARRAY) {
+		ZVAL_COPY_VALUE(&generator->values, val);
+		if (Z_OPT_REFCOUNTED_P(val)) {
+			Z_ADDREF_P(val);
+		}
+		Z_FE_POS(generator->values) = 0;
+
+
+	} else if (IS_CV != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
+		zend_class_entry *ce = Z_OBJCE_P(val);
+		if (ce == zend_ce_generator) {
+			zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val);
+
+			Z_ADDREF_P(val);
+
+
+			if (UNEXPECTED(new_gen->execute_data == NULL)) {
+				zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
+				zval_ptr_dtor(val);
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			} else if (Z_ISUNDEF(new_gen->retval)) {
+				if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) {
+					zend_throw_error(NULL, "Impossible to yield from the Generator being currently run");
+					zval_ptr_dtor(val);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				} else {
+					zend_generator_yield_from(generator, new_gen);
+				}
+			} else {
+				if (RETURN_VALUE_USED(opline)) {
+					ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval);
+				}
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else {
+			zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
+
+
+			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+				if (!EG(exception)) {
+					zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
+				}
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			}
+
+			iter->index = 0;
+			if (iter->funcs->rewind) {
+				iter->funcs->rewind(iter);
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					OBJ_RELEASE(&iter->std);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			ZVAL_OBJ(&generator->values, &iter->std);
+		}
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) {
+		val = Z_REFVAL_P(val);
+		goto yield_from_try_again;
+	} else {
+		zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
+
+
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	/* This is the default return value
+	 * when the expression is a Generator, it will be overwritten in zend_generator_resume() */
+	if (RETURN_VALUE_USED(opline)) {
+		ZVAL_NULL(EX_VAR(opline->result.var));
+	}
+
+	/* This generator has no send target (though the generator we delegate to might have one) */
+	generator->send_target = NULL;
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = EX_VAR(opline->op1.var);
+	if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+		if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(value);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		bool strict;
+
+		if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
+			value = Z_REFVAL_P(value);
+			if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+				ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+
+
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		SAVE_OPLINE();
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+			value = ZVAL_UNDEFINED_OP1();
+		}
+		strict = EX_USES_STRICT_TYPES();
+		do {
+			if (EXPECTED(!strict)) {
+				zend_string *str;
+				zval tmp;
+
+				if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+					zend_error(E_DEPRECATED,
+						"strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+					ZVAL_LONG(EX_VAR(opline->result.var), 0);
+					if (UNEXPECTED(EG(exception))) {
+						HANDLE_EXCEPTION();
+					}
+					break;
+				}
+
+				ZVAL_COPY(&tmp, value);
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
+					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
+					zval_ptr_dtor(&tmp);
+					break;
+				}
+				zval_ptr_dtor(&tmp);
+			}
+			if (!EG(exception)) {
+				zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value));
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+		} while (0);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	int result = 0;
+
+	value = EX_VAR(opline->op1.var);
+	if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+type_check_resource:
+		if (opline->extended_value != MAY_BE_RESOURCE
+		 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
+			result = 1;
+		}
+	} else if ((IS_CV & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) {
+		value = Z_REFVAL_P(value);
+		if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+			goto type_check_resource;
+		}
+	} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		result = ((1 << IS_NULL) & opline->extended_value) != 0;
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		if (UNEXPECTED(EG(exception))) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+	if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+		SAVE_OPLINE();
+
+
+		ZEND_VM_SMART_BRANCH(result, 1);
+	} else {
+		ZEND_VM_SMART_BRANCH(result, 0);
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	uint32_t fetch_type;
+	zend_class_entry *called_scope, *scope;
+	USE_OPLINE
+
+	if (IS_CV != IS_UNUSED) {
+		SAVE_OPLINE();
+		zval *op = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+		if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) {
+			ZVAL_DEREF(op);
+			if (Z_TYPE_P(op) != IS_OBJECT) {
+				zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name);
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	fetch_type = opline->op1.num;
+	if (zend_fetch_is_type_param(fetch_type)) {
+		SAVE_OPLINE();
+		zend_class_entry *resolved = zend_resolve_generic_type_param(
+			zend_unpack_type_param_index(fetch_type), fetch_type);
+		if (UNEXPECTED(!resolved)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), resolved->name);
+		ZEND_VM_NEXT_OPCODE();
+	}
+	scope = EX(func)->op_array.scope;
+	if (UNEXPECTED(scope == NULL)) {
+		SAVE_OPLINE();
+		zend_throw_error(NULL, "Cannot use \"%s\" in the global scope",
+			fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+			fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	switch (fetch_type) {
+		case ZEND_FETCH_CLASS_SELF:
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
+			break;
+		case ZEND_FETCH_CLASS_PARENT:
+			if (UNEXPECTED(scope->parent == NULL)) {
+				SAVE_OPLINE();
+				zend_throw_error(NULL,
+					"Cannot use \"parent\" when current class scope has no parent");
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
+			break;
+		case ZEND_FETCH_CLASS_STATIC:
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				called_scope = Z_OBJCE(EX(This));
+			} else {
+				called_scope = Z_CE(EX(This));
+			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
+			break;
+		default: ZEND_UNREACHABLE();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_STATIC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	HashTable *ht;
+	zval *value;
+	zval *variable_ptr;
+
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	SAVE_OPLINE();
+
+	ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
+	if (!ht) {
+		ht = zend_array_dup(EX(func)->op_array.static_variables);
+		ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
+	}
+	ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
+
+	value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT)));
+
+	if (opline->extended_value & ZEND_BIND_REF) {
+		if (UNEXPECTED(!Z_ISREF_P(value))) {
+			zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
+			GC_SET_REFCOUNT(ref, 2);
+			GC_TYPE_INFO(ref) = GC_REFERENCE;
+			if (opline->op2_type == IS_UNUSED) {
+				ZVAL_COPY_VALUE(&ref->val, value);
+			} else {
+				ZEND_ASSERT(!Z_REFCOUNTED_P(value));
+				ZVAL_COPY(&ref->val, get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R));
+				FREE_OP(opline->op2_type, opline->op2.var);
+			}
+			ref->sources.ptr = NULL;
+			Z_REF_P(value) = ref;
+			Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
+			i_zval_ptr_dtor(variable_ptr);
+			ZVAL_REF(variable_ptr, ref);
+		} else {
+			Z_ADDREF_P(value);
+			i_zval_ptr_dtor(variable_ptr);
+			ZVAL_REF(variable_ptr, Z_REF_P(value));
+			if (opline->op2_type != IS_UNUSED) {
+				FREE_OP(opline->op2_type, opline->op2.var);
+			}
+		}
+	} else {
+		i_zval_ptr_dtor(variable_ptr);
+		ZVAL_COPY(variable_ptr, value);
+	}
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	HashTable *ht;
+	zval *value;
+	zval *variable_ptr;
+
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
+	if (!ht) {
+		ZEND_VM_NEXT_OPCODE();
+	}
+	ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
+
+	value = (zval*)((char*)ht->arData + opline->extended_value);
+	if (Z_TYPE_P(value) == IS_NULL) {
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+		zval_ptr_dtor(variable_ptr);
+		ZEND_ASSERT(Z_TYPE_P(value) == IS_REFERENCE);
+		Z_ADDREF_P(value);
+		ZVAL_REF(variable_ptr, Z_REF_P(value));
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 1);
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	Z_LVAL_P(var_ptr)++;
+	if (UNEXPECTED(0)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	Z_LVAL_P(var_ptr)++;
+	if (UNEXPECTED(1)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	fast_long_increment_function(var_ptr);
+	if (UNEXPECTED(0)) {
+		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	fast_long_increment_function(var_ptr);
+	if (UNEXPECTED(1)) {
+		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	Z_LVAL_P(var_ptr)--;
+	if (UNEXPECTED(0)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	Z_LVAL_P(var_ptr)--;
+	if (UNEXPECTED(1)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	fast_long_decrement_function(var_ptr);
+	if (UNEXPECTED(0)) {
+		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	fast_long_decrement_function(var_ptr);
+	if (UNEXPECTED(1)) {
+		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	Z_LVAL_P(var_ptr)++;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	fast_long_increment_function(var_ptr);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	Z_LVAL_P(var_ptr)--;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+
+	var_ptr = EX_VAR(opline->op1.var);
+	ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
+	fast_long_decrement_function(var_ptr);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	varptr = EX_VAR(opline->op1.var);
+	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY(arg, varptr);
+	} else /* if (IS_CV == IS_VAR) */ {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+
+	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_not_identical_function(op1, op2);
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = RT_CONSTANT(opline, opline->op2);
+		if (IS_CONST == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op2);
+	var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = RT_CONSTANT(opline, opline->op2);
+	if (IS_CV != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CV & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_CV & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_CV, property, IS_CONST,
+		((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CV == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CONST == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+	} else {
+		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CONST == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CONST == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = RT_CONSTANT(opline, opline->op2);
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = RT_CONSTANT(opline, opline->op2);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = RT_CONSTANT(opline, opline->op2);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CONST != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CONST == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CONST == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = RT_CONSTANT(opline, opline->op2);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = RT_CONSTANT(opline, opline->op2);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = RT_CONSTANT(opline, opline->op2);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CONST != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CONST == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = RT_CONSTANT(opline, opline->op2);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CONST == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = RT_CONSTANT(opline, opline->op2);
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = RT_CONSTANT(opline, opline->op2);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = RT_CONSTANT(opline, opline->op2);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CONST != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op2);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op2);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_CV == IS_UNUSED) {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = RT_CONSTANT(opline, opline->op2);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_CV == IS_UNUSED) {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CONST == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CONST == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = EX_VAR(opline->op1.var);
+
+	if (IS_CONST != IS_CONST) {
+		function_name = RT_CONSTANT(opline, opline->op2);
+	}
+
+	if (IS_CONST != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_CV == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_CV & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CONST != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CONST == IS_CONST) {
+					function_name = RT_CONSTANT(opline, opline->op2);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CONST == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CONST == IS_CONST) {
+			function_name = RT_CONSTANT(opline, opline->op2);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CONST == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CONST != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_CV == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_CV == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	SAVE_OPLINE();
+	if (IS_CONST == IS_CONST) {
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_ISREF_P(varptr)) {
+		Z_ADDREF_P(varptr);
+	} else {
+		ZVAL_MAKE_REF_EX(varptr, 2);
+	}
+	ZVAL_REF(arg, Z_REF_P(varptr));
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var_by_ref;
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+		varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_CV == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_CV == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CV == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CV == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CV == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CONST != IS_UNUSED) {
+		zval *offset = RT_CONSTANT(opline, opline->op2);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CV != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_ulong hval;
+	zend_string *key;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			HashTable *ht;
+
+unset_dim_array:
+			SEPARATE_ARRAY(container);
+			ht = Z_ARRVAL_P(container);
+offset_again:
+			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+				key = Z_STR_P(offset);
+				if (IS_CONST != IS_CONST) {
+					if (ZEND_HANDLE_NUMERIC(key, hval)) {
+						goto num_index_dim;
+					}
+				}
+str_index_dim:
+				ZEND_ASSERT(ht != &EG(symbol_table));
+				zend_hash_del(ht, key);
+			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+				hval = Z_LVAL_P(offset);
+num_index_dim:
+				zend_hash_index_del(ht, hval);
+			} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+				offset = Z_REFVAL_P(offset);
+				goto offset_again;
+			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
+				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_NULL) {
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_FALSE) {
+				hval = 0;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_TRUE) {
+				hval = 1;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+				zend_use_resource_as_offset(offset);
+				hval = Z_RES_HANDLE_P(offset);
+				goto num_index_dim;
+			} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else {
+				zend_illegal_array_offset_unset(offset);
+			}
+			break;
+		} else if (Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto unset_dim_array;
+			}
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+			container = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+			offset = ZVAL_UNDEFINED_OP2();
+		}
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+				offset++;
+			}
+			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+			zend_throw_error(NULL, "Cannot unset string offsets");
+		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
+			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
+			zend_false_to_array_deprecated();
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_CV == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_CONST == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_CV & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CONST == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = EX_VAR(opline->op1.var);
+	subject = RT_CONSTANT(opline, opline->op2);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
+
+	SAVE_OPLINE();
+	expr = EX_VAR(opline->op1.var);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_CONST == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_CONST == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CV & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CV == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CV == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+		zval *key = RT_CONSTANT(opline, opline->op2);
+		if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string *varname;
+	zval *value;
+	zval *variable_ptr;
+	uintptr_t idx;
+	zend_reference *ref;
+
+	ZEND_VM_REPEATABLE_OPCODE
+
+	varname = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+
+	/* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
+	idx = (uintptr_t)CACHED_PTR(opline->extended_value) - 1;
+	if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) {
+		Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx);
+
+		if (EXPECTED(p->key == varname) ||
+		    (EXPECTED(p->h == ZSTR_H(varname)) &&
+		     EXPECTED(p->key != NULL) &&
+		     EXPECTED(zend_string_equal_content(p->key, varname)))) {
+
+			value = (zval*)p; /* value = &p->val; */
+			goto check_indirect;
+		}
+	}
+
+	value = zend_hash_find_known_hash(&EG(symbol_table), varname);
+	if (UNEXPECTED(value == NULL)) {
+		value = zend_hash_add_new(&EG(symbol_table), varname, &EG(uninitialized_zval));
+		idx = (char*)value - (char*)EG(symbol_table).arData;
+		/* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
+		CACHE_PTR(opline->extended_value, (void*)(idx + 1));
+	} else {
+		idx = (char*)value - (char*)EG(symbol_table).arData;
+		/* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
+		CACHE_PTR(opline->extended_value, (void*)(idx + 1));
+check_indirect:
+		/* GLOBAL variable may be an INDIRECT pointer to CV */
+		if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
+			value = Z_INDIRECT_P(value);
+			if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				ZVAL_NULL(value);
+			}
+		}
+	}
+
+	if (UNEXPECTED(!Z_ISREF_P(value))) {
+		ZVAL_MAKE_REF_EX(value, 2);
+		ref = Z_REF_P(value);
+	} else {
+		ref = Z_REF_P(value);
+		GC_ADDREF(ref);
+	}
+
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) {
+		zend_refcounted *garbage = Z_COUNTED_P(variable_ptr);
+
+		ZVAL_REF(variable_ptr, ref);
+		SAVE_OPLINE();
+		if (GC_DELREF(garbage) == 0) {
+			rc_dtor_func(garbage);
+			if (UNEXPECTED(EG(exception))) {
+				ZVAL_NULL(variable_ptr);
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			gc_check_possible_root(garbage);
+		}
+	} else {
+		ZVAL_REF(variable_ptr, ref);
+	}
+
+	ZEND_VM_REPEAT_OPCODE(ZEND_BIND_GLOBAL);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	zval *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CV == IS_CONST);
+		if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(op1);
+		}
+		ZEND_VM_SMART_BRANCH(result, 0);
+	}
+
+	if (opline->extended_value) {
+		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+			result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+			ZEND_VM_SMART_BRANCH(result, 0);
+		}
+		SAVE_OPLINE();
+		if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+	} else if (Z_TYPE_P(op1) <= IS_FALSE) {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC());
+		ZEND_VM_SMART_BRANCH(result, 0);
+	} else {
+		zend_string *key;
+		zval key_tmp;
+
+		if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		}
+
+		SAVE_OPLINE();
+		ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) {
+			ZVAL_STR(&key_tmp, key);
+			if (zend_compare(op1, &key_tmp) == 0) {
+
+
+				ZEND_VM_SMART_BRANCH(1, 1);
+			}
+		} ZEND_HASH_FOREACH_END();
+	}
+
+
+	ZEND_VM_SMART_BRANCH(0, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	/* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
+	/* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
+	/* (Infinite recursion when comparing arrays is an uncatchable fatal error) */
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
+	/* Free is a no-op for const/cv */
+	ZEND_VM_SMART_BRANCH(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
+	/* Free is a no-op for const/cv */
+	ZEND_VM_SMART_BRANCH(!result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+	zend_long offset;
+	HashTable *ht;
+
+	container = EX_VAR(opline->op1.var);
+	dim = RT_CONSTANT(opline, opline->op2);
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+			offset = Z_LVAL_P(dim);
+		} else {
+			SAVE_OPLINE();
+			zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		ht = Z_ARRVAL_P(container);
+		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			SAVE_OPLINE();
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto fetch_dim_r_index_array;
+		} else {
+			goto fetch_dim_r_index_slow;
+		}
+	} else {
+fetch_dim_r_index_slow:
+		SAVE_OPLINE();
+		if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim++;
+		}
+		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+fetch_dim_r_index_undef:
+	ZVAL_NULL(EX_VAR(opline->result.var));
+	SAVE_OPLINE();
+	zend_undefined_offset(offset);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+	zend_long offset;
+	HashTable *ht;
+
+	container = EX_VAR(opline->op1.var);
+	dim = EX_VAR(opline->op2.var);
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+			offset = Z_LVAL_P(dim);
+		} else {
+			SAVE_OPLINE();
+			zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		ht = Z_ARRVAL_P(container);
+		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			SAVE_OPLINE();
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto fetch_dim_r_index_array;
+		} else {
+			goto fetch_dim_r_index_slow;
+		}
+	} else {
+fetch_dim_r_index_slow:
+		SAVE_OPLINE();
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim++;
+		}
+		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+fetch_dim_r_index_undef:
+	ZVAL_NULL(EX_VAR(opline->result.var));
+	SAVE_OPLINE();
+	zend_undefined_offset(offset);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_identical_function(op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_not_identical_function(op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_CV != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CV & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_CV & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_CV, property, IS_TMP_VAR,
+		((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CV == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_CV == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_CV == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_TMP_VAR == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_TMP_VAR == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = EX_VAR(opline->op1.var);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	}
+
+	if (IS_TMP_VAR != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_CV == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_CV & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_TMP_VAR != IS_CONST) {
+							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				}
+				zend_invalid_method_call(object, function_name);
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_TMP_VAR == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_CV == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_CV == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CV == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CV == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CV == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CV != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_ulong hval;
+	zend_string *key;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			HashTable *ht;
+
+unset_dim_array:
+			SEPARATE_ARRAY(container);
+			ht = Z_ARRVAL_P(container);
+offset_again:
+			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+				key = Z_STR_P(offset);
+				if (IS_TMP_VAR != IS_CONST) {
+					if (ZEND_HANDLE_NUMERIC(key, hval)) {
+						goto num_index_dim;
+					}
+				}
+str_index_dim:
+				ZEND_ASSERT(ht != &EG(symbol_table));
+				zend_hash_del(ht, key);
+			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+				hval = Z_LVAL_P(offset);
+num_index_dim:
+				zend_hash_index_del(ht, hval);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+				offset = Z_REFVAL_P(offset);
+				goto offset_again;
+			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
+				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_NULL) {
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_FALSE) {
+				hval = 0;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_TRUE) {
+				hval = 1;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+				zend_use_resource_as_offset(offset);
+				hval = Z_RES_HANDLE_P(offset);
+				goto num_index_dim;
+			} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else {
+				zend_illegal_array_offset_unset(offset);
+			}
+			break;
+		} else if (Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto unset_dim_array;
+			}
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+			container = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+			offset = ZVAL_UNDEFINED_OP2();
+		}
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+				offset++;
+			}
+			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+			zend_throw_error(NULL, "Cannot unset string offsets");
+		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
+			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
+			zend_false_to_array_deprecated();
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_CV == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_TMP_VAR == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_CV & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = EX_VAR(opline->op1.var);
+	subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CV & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CV == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CV == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *variable_ptr;
+	zval *value_ptr;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	value_ptr = _get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (IS_CV == IS_VAR &&
+	           UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+
+		zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object");
+		variable_ptr = &EG(uninitialized_zval);
+	} else if (IS_VAR == IS_VAR &&
+	           opline->extended_value == ZEND_RETURNS_FUNCTION &&
+			   UNEXPECTED(!Z_ISREF_P(value_ptr))) {
+
+		variable_ptr = zend_wrong_assign_to_variable_reference(
+			variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
+	}
+
+	if (garbage) {
+		GC_DTOR(garbage);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
+
+	SAVE_OPLINE();
+	expr = EX_VAR(opline->op1.var);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_VAR == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_VAR == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = NULL;
+		if (IS_UNUSED == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_UNUSED == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = NULL;
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX  zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type)
+{
+	USE_OPLINE
+	zval *varname;
+	zval *retval;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+	varname = EX_VAR(opline->op1.var);
+
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+
+
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	retval = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST);
+	if (retval == NULL) {
+		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+fetch_this:
+			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
+			if (IS_CV != IS_CONST) {
+				zend_tmp_string_release(tmp_name);
+			}
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		if (type == BP_VAR_W) {
+			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
+		} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+			retval = &EG(uninitialized_zval);
+		} else {
+			if (IS_CV == IS_CV) {
+				/* Keep name alive in case an error handler tries to free it. */
+				zend_string_addref(name);
+			}
+			zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+				(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+			if (type == BP_VAR_RW && !EG(exception)) {
+				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+			} else {
+				retval = &EG(uninitialized_zval);
+			}
+			if (IS_CV == IS_CV) {
+				zend_string_release(name);
+			}
+		}
+	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
+	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
+		retval = Z_INDIRECT_P(retval);
+		if (Z_TYPE_P(retval) == IS_UNDEF) {
+			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+				goto fetch_this;
+			}
+			if (type == BP_VAR_W) {
+				ZVAL_NULL(retval);
+			} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+				retval = &EG(uninitialized_zval);
+			} else {
+				zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+					(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+				if (type == BP_VAR_RW && !EG(exception)) {
+					ZVAL_NULL(retval);
+				} else {
+					retval = &EG(uninitialized_zval);
+				}
+			}
+		}
+	}
+
+	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+
+
+	}
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+	ZEND_ASSERT(retval != NULL);
+	if (type == BP_VAR_R || type == BP_VAR_IS) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+	} else {
+		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	int fetch_type =
+		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
+			BP_VAR_W : BP_VAR_R;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_UNUSED == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_UNUSED == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = NULL;
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_UNUSED == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = NULL;
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = NULL;
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = NULL;
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_UNUSED == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = NULL;
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_UNUSED == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = NULL;
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = NULL;
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = NULL;
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_UNUSED == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = NULL;
+			if (IS_UNUSED == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = NULL;
+			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_UNUSED == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = NULL;
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = NULL;
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = NULL;
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_UNUSED != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	if (IS_CV == IS_UNUSED) {
+		SAVE_OPLINE();
+		zend_verify_missing_return_type(EX(func));
+		HANDLE_EXCEPTION();
+	} else {
+/* prevents "undefined variable opline" errors */
+#if 0 || (IS_CV != IS_UNUSED)
+		USE_OPLINE
+		zval *retval_ref, *retval_ptr;
+		zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
+		retval_ref = retval_ptr = EX_VAR(opline->op1.var);
+
+		if (IS_CV == IS_CONST) {
+			ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
+			retval_ref = retval_ptr = EX_VAR(opline->result.var);
+		} else if (IS_CV == IS_VAR) {
+			if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+				retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr);
+			}
+			ZVAL_DEREF(retval_ptr);
+		} else if (IS_CV == IS_CV) {
+			ZVAL_DEREF(retval_ptr);
+		}
+
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+
+		if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+			SAVE_OPLINE();
+			retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		zend_reference *ref = NULL;
+		if (UNEXPECTED(retval_ref != retval_ptr)) {
+			if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+				ref = Z_REF_P(retval_ref);
+			} else {
+				/* A cast might happen - unwrap the reference if this is a by-value return */
+				if (Z_REFCOUNT_P(retval_ref) == 1) {
+					ZVAL_UNREF(retval_ref);
+				} else {
+					Z_DELREF_P(retval_ref);
+					ZVAL_COPY(retval_ref, retval_ptr);
+				}
+				retval_ptr = retval_ref;
+			}
+		}
+
+		SAVE_OPLINE();
+		if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) {
+			zend_verify_return_error(EX(func), retval_ptr);
+			HANDLE_EXCEPTION();
+		}
+		ZEND_VM_NEXT_OPCODE();
+#endif
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_CV == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+
+	SAVE_OPLINE();
+	if (IS_UNUSED == IS_CONST) {
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_ISREF_P(varptr)) {
+		Z_ADDREF_P(varptr);
+	} else {
+		ZVAL_MAKE_REF_EX(varptr, 2);
+	}
+	ZVAL_REF(arg, Z_REF_P(varptr));
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(0)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var_by_ref;
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+		varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_CV == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(1)) {
+		if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_var_by_ref;
+		}
+	} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_var_by_ref:
+		varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(varptr)) {
+			Z_ADDREF_P(varptr);
+		} else {
+			ZVAL_MAKE_REF_EX(varptr, 2);
+		}
+		ZVAL_REF(arg, Z_REF_P(varptr));
+
+
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	varptr = EX_VAR(opline->op1.var);
+	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(arg);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY_DEREF(arg, varptr);
+	} else /* if (IS_CV == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(varptr))) {
+			zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+			varptr = Z_REFVAL_P(varptr);
+			ZVAL_COPY_VALUE(arg, varptr);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(arg)) {
+				Z_ADDREF_P(arg);
+			}
+		} else {
+			ZVAL_COPY_VALUE(arg, varptr);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_CV == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CV == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CV == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CV == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *offset = NULL;
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_UNUSED != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CV != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var = EX_VAR(opline->op1.var);
+
+	if (Z_REFCOUNTED_P(var)) {
+		zend_refcounted *garbage = Z_COUNTED_P(var);
+
+		ZVAL_UNDEF(var);
+		SAVE_OPLINE();
+		GC_DTOR(garbage);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	} else {
+		ZVAL_UNDEF(var);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+
+	varname = EX_VAR(opline->op1.var);
+
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			varname = ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	zend_hash_del_ind(target_symbol_table, name);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = EX_VAR(opline->op1.var);
+	if (!(0)) {
+		if (Z_TYPE_P(value) > IS_NULL &&
+		    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL)) {
+			ZEND_VM_SMART_BRANCH_TRUE();
+		} else {
+			ZEND_VM_SMART_BRANCH_FALSE();
+		}
+	} else {
+		bool result;
+
+		SAVE_OPLINE();
+		result = !i_zend_is_true(value);
+		ZEND_VM_SMART_BRANCH(result, 1);
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = EX_VAR(opline->op1.var);
+	if (!(1)) {
+		if (Z_TYPE_P(value) > IS_NULL &&
+		    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL)) {
+			ZEND_VM_SMART_BRANCH_TRUE();
+		} else {
+			ZEND_VM_SMART_BRANCH_FALSE();
+		}
+	} else {
+		bool result;
+
+		SAVE_OPLINE();
+		result = !i_zend_is_true(value);
+		ZEND_VM_SMART_BRANCH(result, 1);
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	bool result;
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+	varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else {
+		name = zval_get_tmp_string(varname, &tmp_name);
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	value = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+
+	if (!value) {
+		result = (opline->extended_value & ZEND_ISEMPTY);
+	} else {
+		if (Z_TYPE_P(value) == IS_INDIRECT) {
+			value = Z_INDIRECT_P(value);
+		}
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			if (Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+			}
+			result = Z_TYPE_P(value) > IS_NULL;
+		} else {
+			result = !i_zend_is_true(value);
+		}
+	}
+
+	ZEND_VM_SMART_BRANCH(result, true);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
+
+	SAVE_OPLINE();
+	expr = EX_VAR(opline->op1.var);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_UNUSED == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_UNUSED == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CV & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CV == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CV == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *key = NULL;
+		if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1 = EX_VAR(opline->op1.var);
+
+	if (UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1 = EX_VAR(opline->op1.var);
+
+	if (IS_CV == IS_CV) {
+		if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_NEW_EMPTY_REF(op1);
+			Z_SET_REFCOUNT_P(op1, 2);
+			ZVAL_NULL(Z_REFVAL_P(op1));
+			ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
+		} else {
+			if (Z_ISREF_P(op1)) {
+				Z_ADDREF_P(op1);
+			} else {
+				ZVAL_MAKE_REF_EX(op1, 2);
+			}
+			ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) {
+		op1 = Z_INDIRECT_P(op1);
+		if (EXPECTED(!Z_ISREF_P(op1))) {
+			ZVAL_MAKE_REF_EX(op1, 2);
+		} else {
+			GC_ADDREF(Z_REF_P(op1));
+		}
+		ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
+	} else {
+		ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	zend_long count;
+
+	SAVE_OPLINE();
+	op1 = EX_VAR(opline->op1.var);
+
+	while (1) {
+		if (Z_TYPE_P(op1) == IS_ARRAY) {
+			count = zend_hash_num_elements(Z_ARRVAL_P(op1));
+			break;
+		} else if (Z_TYPE_P(op1) == IS_OBJECT) {
+			zend_object *zobj = Z_OBJ_P(op1);
+
+			/* first, we check if the handler is defined */
+			if (zobj->handlers->count_elements) {
+				if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) {
+					break;
+				}
+				if (UNEXPECTED(EG(exception))) {
+					count = 0;
+					break;
+				}
+			}
+
+			/* if not and the object implements Countable we call its count() method */
+			if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
+				zval retval;
+
+				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
+				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
+				count = zval_get_long(&retval);
+				zval_ptr_dtor(&retval);
+				break;
+			}
+
+			/* If There's no handler and it doesn't implement Countable then emit a TypeError */
+		} else if ((IS_CV & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			continue;
+		} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		count = 0;
+		zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1));
+		break;
+	}
+
+	ZVAL_LONG(EX_VAR(opline->result.var), count);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_array *ht = Z_ARRVAL_P(EX_VAR(opline->op1.var));
+	ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht));
+	if (IS_CV & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+		SAVE_OPLINE();
+		zend_array_destroy(ht);
+		if (EG(exception)) {
+			HANDLE_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (IS_CV == IS_UNUSED) {
+		SAVE_OPLINE();
+		if (UNEXPECTED(!EX(func)->common.scope)) {
+			zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		} else {
+			zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		zval *op1;
+
+		SAVE_OPLINE();
+		op1 = EX_VAR(opline->op1.var);
+		while (1) {
+			if (Z_TYPE_P(op1) == IS_OBJECT) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+				op1 = Z_REFVAL_P(op1);
+				continue;
+			} else {
+				if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+					ZVAL_UNDEFINED_OP1();
+				}
+				zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+			}
+			break;
+		}
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	zend_string *type;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	type = zend_zval_get_legacy_type(op1);
+	if (EXPECTED(type)) {
+		ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type);
+	} else {
+		ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varptr, *arg;
+	uint32_t arg_num = opline->op2.num;
+
+	if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+		ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	varptr = EX_VAR(opline->op1.var);
+	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+	if (IS_CV == IS_CV) {
+		ZVAL_COPY(arg, varptr);
+	} else /* if (IS_CV == IS_VAR) */ {
+		ZVAL_COPY_VALUE(arg, varptr);
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+
+	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_identical_function(op1, op2);
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_not_identical_function(op1, op2);
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *value;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto assign_op_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+assign_op_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				zend_reference *ref;
+
+				do {
+					if (UNEXPECTED(Z_ISREF_P(zptr))) {
+						ref = Z_REF_P(zptr);
+						zptr = Z_REFVAL_P(zptr);
+						if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+							zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+							break;
+						}
+					}
+
+					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
+						/* special case for typed properties */
+						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
+					} else {
+						zend_binary_op(zptr, zptr, value OPLINE_CC);
+					}
+				} while (0);
+
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+				}
+			}
+		} else {
+			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value, *container, *dim;
+	HashTable *ht;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+		SEPARATE_ARRAY(container);
+		ht = Z_ARRVAL_P(container);
+assign_dim_op_new_array:
+		dim = EX_VAR(opline->op2.var);
+		if (IS_CV == IS_UNUSED) {
+			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
+			if (UNEXPECTED(!var_ptr)) {
+				zend_cannot_add_element();
+				goto assign_dim_op_ret_null;
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
+			} else {
+				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(!var_ptr)) {
+				goto assign_dim_op_ret_null;
+			}
+		}
+
+		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+		do {
+			if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+				zend_reference *ref = Z_REF_P(var_ptr);
+				var_ptr = Z_REFVAL_P(var_ptr);
+				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+					zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+					break;
+				}
+			}
+			zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+		} while (0);
+
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+		}
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	} else {
+		if (EXPECTED(Z_ISREF_P(container))) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto assign_dim_op_array;
+			}
+		}
+
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(container);
+
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
+		} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+			uint8_t old_type;
+
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			ht = zend_new_array(8);
+			old_type = Z_TYPE_P(container);
+			ZVAL_ARR(container, ht);
+			if (UNEXPECTED(old_type == IS_FALSE)) {
+				GC_ADDREF(ht);
+				zend_false_to_array_deprecated();
+				if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+					zend_array_destroy(ht);
+					goto assign_dim_op_ret_null;
+				}
+			}
+			goto assign_dim_op_new_array;
+		} else {
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+assign_dim_op_ret_null:
+			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *var_ptr;
+	zval *value;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) {
+			zend_reference *ref = Z_REF_P(var_ptr);
+			var_ptr = Z_REFVAL_P(var_ptr);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+		zend_binary_op(var_ptr, var_ptr, value OPLINE_CC);
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto pre_incdec_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+pre_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				UNDEF_RESULT();
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+					ZVAL_NULL(EX_VAR(opline->result.var));
+				}
+			} else {
+				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object;
+	zval *property;
+	zval *zptr;
+	void *_cache_slot[3] = {0};
+	void **cache_slot;
+	zend_property_info *prop_info;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+			if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+				object = Z_REFVAL_P(object);
+				goto post_incdec_object;
+			}
+			if (IS_CV == IS_CV
+			 && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC);
+			break;
+		}
+
+post_incdec_object:
+		/* here we are sure we are dealing with an object */
+		zobj = Z_OBJ_P(object);
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(property);
+		} else {
+			name = zval_try_get_tmp_string(property, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+		cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
+			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			} else {
+				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = EX_VAR(opline->op2.var);
+	if (IS_CV != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CV == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CV & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_CV & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(
+		result, container, IS_CV, property, IS_CV,
+		((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *result;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CV == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *property, *result;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	result = EX_VAR(opline->result.var);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+
+
+	if (IS_CV == IS_VAR) {
+		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CONST == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CONST != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CONST == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CONST == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_TMP_VAR == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_TMP_VAR != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_TMP_VAR == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_TMP_VAR == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object, *value, tmp;
+	zend_object *zobj;
+	zend_string *name, *tmp_name;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	object = EX_VAR(opline->op1.var);
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
+			object = Z_REFVAL_P(object);
+			goto assign_object;
+		}
+		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		value = &EG(uninitialized_zval);
+		goto free_and_exit_assign_obj;
+	}
+
+assign_object:
+	zobj = Z_OBJ_P(object);
+	if (IS_CV == IS_CONST) {
+		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
+			void **cache_slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+			zval *property_val;
+			zend_property_info *prop_info;
+
+			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
+
+assign_obj_simple:
+				property_val = OBJ_PROP(zobj, prop_offset);
+				if (Z_TYPE_P(property_val) != IS_UNDEF) {
+					if (prop_info != NULL) {
+						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
+						goto free_and_exit_assign_obj;
+					} else {
+fast_assign_obj:
+						value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+							ZVAL_COPY(EX_VAR(opline->result.var), value);
+						}
+						goto exit_assign_obj;
+					}
+				}
+			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
+				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
+					zobj = zend_lazy_object_init(zobj);
+					if (!zobj) {
+						value = &EG(uninitialized_zval);
+						goto free_and_exit_assign_obj;
+					}
+				}
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					rebuild_object_properties_internal(zobj);
+				}
+				if (EXPECTED(zobj->properties != NULL)) {
+					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
+						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
+							GC_DELREF(zobj->properties);
+						}
+						zobj->properties = zend_array_dup(zobj->properties);
+					}
+					property_val = zend_hash_find_known_hash(zobj->properties, name);
+					if (property_val) {
+						goto fast_assign_obj;
+					}
+				}
+
+				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
+					if (IS_CV == IS_CONST) {
+						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
+							Z_ADDREF_P(value);
+						}
+					} else if (IS_CV != IS_TMP_VAR) {
+						if (Z_ISREF_P(value)) {
+							if (IS_CV == IS_VAR) {
+								zend_reference *ref = Z_REF_P(value);
+								if (GC_DELREF(ref) == 0) {
+									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
+									efree_size(ref, sizeof(zend_reference));
+									value = &tmp;
+								} else {
+									value = Z_REFVAL_P(value);
+									Z_TRY_ADDREF_P(value);
+								}
+							} else {
+								value = Z_REFVAL_P(value);
+								Z_TRY_ADDREF_P(value);
+							}
+						} else if (IS_CV == IS_CV) {
+							Z_TRY_ADDREF_P(value);
+						}
+					}
+					zend_hash_add_new(zobj->properties, name, value);
+					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+						ZVAL_COPY(EX_VAR(opline->result.var), value);
+					}
+					goto exit_assign_obj;
+				}
+			} else {
+				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
+				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
+					prop_info = CACHED_PTR_EX(cache_slot + 2);
+					prop_offset = prop_info->offset;
+					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
+						prop_info = NULL;
+					}
+					goto assign_obj_simple;
+				}
+				/* Fall through to write_property for hooks. */
+			}
+		}
+		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+	} else {
+		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			UNDEF_RESULT();
+			goto exit_assign_obj;
+		}
+	}
+
+	if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+		ZVAL_DEREF(value);
+	}
+
+	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+free_and_exit_assign_obj:
+	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+	}
+
+
+exit_assign_obj:
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+
+
+
+	/* assign_obj has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CV == IS_UNUSED) {
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CONST == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CONST == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = RT_CONSTANT((opline+1), (opline+1)->op1);
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CONST & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CV == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = EX_VAR(opline->op2.var);
+				value = RT_CONSTANT((opline+1), (opline+1)->op1);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CV != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CV == IS_UNUSED) {
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_TMP_VAR == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_TMP_VAR == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CV == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = EX_VAR(opline->op2.var);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CV != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CV == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CV == IS_UNUSED) {
+				zend_use_new_element_for_string();
+
+
+				UNDEF_RESULT();
+			} else {
+				dim = EX_VAR(opline->op2.var);
+				value = EX_VAR((opline+1)->op1.var);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+
+
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CV != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *variable_ptr;
+	zval *value_ptr;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (IS_CV == IS_VAR &&
+	           UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+
+		zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object");
+		variable_ptr = &EG(uninitialized_zval);
+	} else if (IS_CV == IS_VAR &&
+	           opline->extended_value == ZEND_RETURNS_FUNCTION &&
+			   UNEXPECTED(!Z_ISREF_P(value_ptr))) {
+
+		variable_ptr = zend_wrong_assign_to_variable_reference(
+			variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
+	}
+
+	if (garbage) {
+		GC_DTOR(garbage);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_CV == IS_UNUSED) {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_CV == IS_UNUSED) {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CV == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = EX_VAR(opline->op1.var);
+
+	if (IS_CV != IS_CONST) {
+		function_name = EX_VAR(opline->op2.var);
+	}
+
+	if (IS_CV != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_CV == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_CV & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CV != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CV == IS_CONST) {
+					function_name = EX_VAR(opline->op2.var);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CV == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CV == IS_CONST) {
+			function_name = EX_VAR(opline->op2.var);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CV != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_CV == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_CV == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CV == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CV == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CV == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CV != IS_UNUSED) {
+		zval *offset = EX_VAR(opline->op2.var);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CV != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_ulong hval;
+	zend_string *key;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = EX_VAR(opline->op2.var);
+
+	do {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			HashTable *ht;
+
+unset_dim_array:
+			SEPARATE_ARRAY(container);
+			ht = Z_ARRVAL_P(container);
+offset_again:
+			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+				key = Z_STR_P(offset);
+				if (IS_CV != IS_CONST) {
+					if (ZEND_HANDLE_NUMERIC(key, hval)) {
+						goto num_index_dim;
+					}
+				}
+str_index_dim:
+				ZEND_ASSERT(ht != &EG(symbol_table));
+				zend_hash_del(ht, key);
+			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+				hval = Z_LVAL_P(offset);
+num_index_dim:
+				zend_hash_index_del(ht, hval);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+				offset = Z_REFVAL_P(offset);
+				goto offset_again;
+			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
+				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_NULL) {
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_FALSE) {
+				hval = 0;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_TRUE) {
+				hval = 1;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+				zend_use_resource_as_offset(offset);
+				hval = Z_RES_HANDLE_P(offset);
+				goto num_index_dim;
+			} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else {
+				zend_illegal_array_offset_unset(offset);
+			}
+			break;
+		} else if (Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto unset_dim_array;
+			}
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+			container = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+			offset = ZVAL_UNDEFINED_OP2();
+		}
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+				offset++;
+			}
+			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+			zend_throw_error(NULL, "Cannot unset string offsets");
+		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
+			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
+			zend_false_to_array_deprecated();
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_CV == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
+					}
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(offset);
+		} else {
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
+			}
+		}
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_CV & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = EX_VAR(opline->op1.var);
+	subject = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CV & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CV == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CV == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CV == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	/* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
+	/* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
+	/* (Infinite recursion when comparing arrays is an uncatchable fatal error) */
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = fast_is_identical_function(op1, op2);
+	/* Free is a no-op for const/cv */
+	ZEND_VM_SMART_BRANCH(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = fast_is_identical_function(op1, op2);
+	/* Free is a no-op for const/cv */
+	ZEND_VM_SMART_BRANCH(!result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
+}
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS) {
+	SAVE_OPLINE();
+	return &call_interrupt_op;
+}
+#endif
+
+#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
+# undef ZEND_VM_TAIL_CALL
+# undef ZEND_VM_CONTINUE
+# undef ZEND_VM_RETURN
+
+# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE()
+# define ZEND_VM_CONTINUE()      HYBRID_NEXT()
+# define ZEND_VM_RETURN()        goto HYBRID_HALT_LABEL
+#endif
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+
+# undef ZEND_VM_TAIL_CALL
+# undef ZEND_VM_CONTINUE
+# undef ZEND_VM_RETURN
+# undef ZEND_VM_DISPATCH_TO_HELPER
+# undef ZEND_VM_INTERRUPT
+# undef ZEND_VM_ENTER_EX
+# undef ZEND_VM_LEAVE
+
+# define ZEND_VM_TAIL_CALL(call)               ZEND_MUSTTAIL return call
+# define ZEND_VM_CONTINUE()                    ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))
+# define ZEND_VM_RETURN()                      opline = &call_halt_op; ZEND_VM_CONTINUE()
+# define ZEND_VM_DISPATCH_TO_HELPER(call) \
+    do { \
+        opline = call; \
+        ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \
+    } while (0)
+# define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE()
+# define ZEND_VM_INTERRUPT()        ZEND_VM_TAIL_CALL(zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))
+# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()
+# define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);
+static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline);
+
+static const zend_op call_halt_op = {
+    .handler = ZEND_HALT_TAILCALL_HANDLER,
+};
+static const zend_op call_leave_op = {
+    .handler = zend_leave_helper_SPEC_TAILCALL,
+};
+static const zend_op call_interrupt_op = {
+    .handler = zend_interrupt_helper_SPEC_TAILCALL,
+};
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
+	ZVAL_UNDEF(EX_VAR(opline->result.var));
+	HANDLE_EXCEPTION();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1);
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_this_not_in_object_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	zend_throw_error(NULL, "Using $this when not in object context");
+	UNDEF_RESULT();
+	HANDLE_EXCEPTION();
+}
+
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+
+	SAVE_OPLINE();
+	function_name = RT_CONSTANT(opline, opline->op2);
+	zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name));
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_OP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	/* This helper actually never will receive IS_VAR as second op, and has the same handling for VAR and TMP in the first op, but for interoperability with the other binary_assign_op helpers, it is necessary to "include" it */
+
+	USE_OPLINE
+	zval *prop, *value;
+	zend_property_info *prop_info;
+	zend_reference *ref;
+
+	SAVE_OPLINE();
+
+	prop = zend_fetch_static_property_address(&prop_info, (opline+1)->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+		UNDEF_RESULT();
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+		HANDLE_EXCEPTION();
+	}
+
+	if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
+	 && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) {
+		zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify");
+		UNDEF_RESULT();
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+		HANDLE_EXCEPTION();
+	}
+
+	value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
+
+	do {
+		if (UNEXPECTED(Z_ISREF_P(prop))) {
+			ref = Z_REF_P(prop);
+			prop = Z_REFVAL_P(prop);
+			if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
+				zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC);
+				break;
+			}
+		}
+
+		if (ZEND_TYPE_IS_SET(prop_info->type)) {
+			/* special case for typed properties */
+			zend_binary_assign_op_typed_prop(prop_info, prop, value OPLINE_CC EXECUTE_DATA_CC);
+		} else {
+			zend_binary_op(prop, prop, value OPLINE_CC);
+		}
+	} while (0);
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), prop);
+	}
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	/* assign_static_prop has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *prop;
+	zend_property_info *prop_info;
+
+	SAVE_OPLINE();
+
+	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
+	 && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) {
+		zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify");
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	zend_pre_incdec_property_zval(prop,
+		ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *prop;
+	zend_property_info *prop_info;
+
+	SAVE_OPLINE();
+
+	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
+	 && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) {
+		zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify");
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	zend_post_incdec_property_zval(prop,
+		ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_R_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_W_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_RW_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_STATIC_PROP_W_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_STATIC_PROP_R_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_IS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
+}
+
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	zend_throw_error(NULL, "Cannot use temporary expression in write context");
+	FREE_OP(opline->op2_type, opline->op2.var);
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZVAL_UNDEF(EX_VAR(opline->result.var));
+	HANDLE_EXCEPTION();
+}
+
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	zend_throw_error(NULL, "Cannot use [] for reading");
+	FREE_OP(opline->op2_type, opline->op2.var);
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZVAL_UNDEF(EX_VAR(opline->result.var));
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *prop, *value;
+	zend_property_info *prop_info;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+
+	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+
+
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	value = RT_CONSTANT((opline+1), (opline+1)->op1);
+
+	if (ZEND_TYPE_IS_SET(prop_info->type)) {
+		value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC);
+
+
+	} else {
+		value = zend_assign_to_variable_ex(prop, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), value);
+	}
+
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+	/* assign_static_prop has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *prop, *value;
+	zend_property_info *prop_info;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+
+	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+		zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (ZEND_TYPE_IS_SET(prop_info->type)) {
+		value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC);
+		zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	} else {
+		value = zend_assign_to_variable_ex(prop, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), value);
+	}
+
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+	/* assign_static_prop has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *prop, *value;
+	zend_property_info *prop_info;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+
+	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+
+
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (ZEND_TYPE_IS_SET(prop_info->type)) {
+		value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC);
+
+
+	} else {
+		value = zend_assign_to_variable_ex(prop, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), value);
+	}
+
+	if (garbage) {
+		GC_DTOR_NO_REF(garbage);
+	}
+
+	/* assign_static_prop has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_REF_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *prop, *value_ptr;
+	zend_property_info *prop_info;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+
+	prop = zend_fetch_static_property_address(&prop_info, opline->extended_value & ~ZEND_RETURNS_FUNCTION, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
+	 && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) {
+		zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify");
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	value_ptr = get_zval_ptr_ptr((opline+1)->op1_type, (opline+1)->op1, BP_VAR_W);
+
+	if ((opline+1)->op1_type == IS_VAR && (opline->extended_value & ZEND_RETURNS_FUNCTION) && UNEXPECTED(!Z_ISREF_P(value_ptr))) {
+		if (UNEXPECTED(!zend_wrong_assign_to_variable_reference(prop, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC))) {
+			prop = &EG(uninitialized_zval);
+		}
+	} else if (ZEND_TYPE_IS_SET(prop_info->type)) {
+		prop = zend_assign_to_typed_property_reference(prop_info, prop, value_ptr, &garbage EXECUTE_DATA_CC);
+	} else {
+		zend_assign_to_variable_reference(prop, value_ptr, &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), prop);
+	}
+
+	if (garbage) {
+		GC_DTOR(garbage);
+	}
+
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_leave_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_execute_data *old_execute_data;
+	uint32_t call_info = EX_CALL_INFO();
+#if ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL
+	/* zend_leave_helper may be called with opline=call_leave_op in TAILCALL VM */
+	SAVE_OPLINE();
+#endif
+
+	if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) == 0)) {
+		EG(current_execute_data) = EX(prev_execute_data);
+		i_free_compiled_variables(execute_data);
+
+#ifdef ZEND_PREFER_RELOAD
+		call_info = EX_CALL_INFO();
+#endif
+		if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+			OBJ_RELEASE(Z_OBJ(execute_data->This));
+		} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+			OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+		}
+		EG(vm_stack_top) = (zval*)execute_data;
+		execute_data = EX(prev_execute_data);
+
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+			HANDLE_EXCEPTION_LEAVE();
+		}
+
+		LOAD_NEXT_OPLINE();
+		ZEND_VM_LEAVE();
+	} else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) {
+		EG(current_execute_data) = EX(prev_execute_data);
+		i_free_compiled_variables(execute_data);
+
+#ifdef ZEND_PREFER_RELOAD
+		call_info = EX_CALL_INFO();
+#endif
+		if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+			zend_clean_and_cache_symbol_table(EX(symbol_table));
+		}
+
+		if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+			zend_free_extra_named_params(EX(extra_named_params));
+		}
+
+		/* Free extra args before releasing the closure,
+		 * as that may free the op_array. */
+		zend_vm_stack_free_extra_args_ex(call_info, execute_data);
+
+		if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+			OBJ_RELEASE(Z_OBJ(execute_data->This));
+		} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+			OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+		}
+
+		old_execute_data = execute_data;
+		execute_data = EX(prev_execute_data);
+		zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
+
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+			HANDLE_EXCEPTION_LEAVE();
+		}
+
+		LOAD_NEXT_OPLINE();
+		ZEND_VM_LEAVE();
+	} else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) {
+		if (EX(func)->op_array.last_var > 0) {
+			zend_detach_symbol_table(execute_data);
+			call_info |= ZEND_CALL_NEEDS_REATTACH;
+		}
+		zend_destroy_static_vars(&EX(func)->op_array);
+		destroy_op_array(&EX(func)->op_array);
+		efree_size(EX(func), sizeof(zend_op_array));
+		old_execute_data = execute_data;
+		execute_data = EG(current_execute_data) = EX(prev_execute_data);
+		zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
+
+		if (call_info & ZEND_CALL_NEEDS_REATTACH) {
+			if (EX(func)->op_array.last_var > 0) {
+				zend_attach_symbol_table(execute_data);
+			} else {
+				ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_NEEDS_REATTACH);
+			}
+		}
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+			HANDLE_EXCEPTION_LEAVE();
+		}
+
+		LOAD_NEXT_OPLINE();
+		ZEND_VM_LEAVE();
+	} else {
+		if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) {
+			EG(current_execute_data) = EX(prev_execute_data);
+			i_free_compiled_variables(execute_data);
+#ifdef ZEND_PREFER_RELOAD
+			call_info = EX_CALL_INFO();
+#endif
+			if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS))) {
+				if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+					zend_clean_and_cache_symbol_table(EX(symbol_table));
+				}
+				zend_vm_stack_free_extra_args_ex(call_info, execute_data);
+				if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+					zend_free_extra_named_params(EX(extra_named_params));
+				}
+			}
+			if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
+				OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
+			}
+			ZEND_VM_RETURN();
+		} else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
+			zend_array *symbol_table = EX(symbol_table);
+
+			if (EX(func)->op_array.last_var > 0) {
+				zend_detach_symbol_table(execute_data);
+				call_info |= ZEND_CALL_NEEDS_REATTACH;
+			}
+			if (call_info & ZEND_CALL_NEEDS_REATTACH) {
+				old_execute_data = EX(prev_execute_data);
+				while (old_execute_data) {
+					if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
+						if (old_execute_data->symbol_table == symbol_table) {
+							if (old_execute_data->func->op_array.last_var > 0) {
+								zend_attach_symbol_table(old_execute_data);
+							} else {
+								ZEND_ADD_CALL_FLAG(old_execute_data, ZEND_CALL_NEEDS_REATTACH);
+							}
+						}
+						break;
+					}
+					old_execute_data = old_execute_data->prev_execute_data;
+				}
+			}
+			EG(current_execute_data) = EX(prev_execute_data);
+			ZEND_VM_RETURN();
+		}
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	call->prev_execute_data = execute_data;
+	EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+	bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+	ret = 0 ? EX_VAR(opline->result.var) : &retval;
+	ZVAL_NULL(ret);
+
+
+	fbc->internal_function.handler(call, ret);
+
+#if ZEND_DEBUG
+	if (!EG(exception) && call->func) {
+		if (should_throw) {
+			zend_internal_call_arginfo_violation(call->func);
+		}
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
+		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+	}
+#endif
+
+
+	ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+	EG(current_execute_data) = execute_data;
+	zend_vm_stack_free_args(call);
+
+	uint32_t call_info = ZEND_CALL_INFO(call);
+	if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) {
+		if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+		zend_vm_stack_free_call_frame_ex(call_info, call);
+	} else {
+		EG(vm_stack_top) = (zval*)call;
+	}
+
+	if (!0) {
+		i_zval_ptr_dtor(ret);
+	}
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	call->prev_execute_data = execute_data;
+	EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+	bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+	ret = 1 ? EX_VAR(opline->result.var) : &retval;
+	ZVAL_NULL(ret);
+
+
+	fbc->internal_function.handler(call, ret);
+
+#if ZEND_DEBUG
+	if (!EG(exception) && call->func) {
+		if (should_throw) {
+			zend_internal_call_arginfo_violation(call->func);
+		}
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
+		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+	}
+#endif
+
+
+	ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+	EG(current_execute_data) = execute_data;
+	zend_vm_stack_free_args(call);
+
+	uint32_t call_info = ZEND_CALL_INFO(call);
+	if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) {
+		if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+		zend_vm_stack_free_call_frame_ex(call_info, call);
+	} else {
+		EG(vm_stack_top) = (zval*)call;
+	}
+
+	if (!1) {
+		i_zval_ptr_dtor(ret);
+	}
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	call->prev_execute_data = execute_data;
+	EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+	bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+	ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
+	ZVAL_NULL(ret);
+
+	zend_observer_fcall_begin_specialized(call, false);
+	fbc->internal_function.handler(call, ret);
+
+#if ZEND_DEBUG
+	if (!EG(exception) && call->func) {
+		if (should_throw) {
+			zend_internal_call_arginfo_violation(call->func);
+		}
+		if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+			bool result = zend_verify_internal_return_type(call->func, ret);
+			ZEND_ASSERT(result);
+		}
+		ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+			? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+		zend_verify_internal_func_info(call->func, ret);
+		ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+				|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+	}
+#endif
+	zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
+	ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+	EG(current_execute_data) = execute_data;
+	zend_vm_stack_free_args(call);
+
+	uint32_t call_info = ZEND_CALL_INFO(call);
+	if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) {
+		if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+		zend_vm_stack_free_call_frame_ex(call_info, call);
+	} else {
+		EG(vm_stack_top) = (zval*)call;
+	}
+
+	if (!RETURN_VALUE_USED(opline)) {
+		i_zval_ptr_dtor(ret);
+	}
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	ret = NULL;
+	if (0) {
+		ret = EX_VAR(opline->result.var);
+	}
+
+	call->prev_execute_data = execute_data;
+	execute_data = call;
+	i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+	LOAD_OPLINE_EX();
+
+
+
+
+	ZEND_VM_ENTER_EX();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	ret = NULL;
+	if (1) {
+		ret = EX_VAR(opline->result.var);
+	}
+
+	call->prev_execute_data = execute_data;
+	execute_data = call;
+	i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+	LOAD_OPLINE_EX();
+
+
+
+
+	ZEND_VM_ENTER_EX();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	ret = NULL;
+	if (RETURN_VALUE_USED(opline)) {
+		ret = EX_VAR(opline->result.var);
+	}
+
+	call->prev_execute_data = execute_data;
+	execute_data = call;
+	i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+	LOAD_OPLINE_EX();
+	SAVE_OPLINE();
+	zend_observer_fcall_begin_specialized(execute_data, false);
+
+	ZEND_VM_ENTER_EX();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	const uint32_t no_discard = 0 ? 0 : ZEND_ACC_NODISCARD;
+
+	if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) {
+		if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) {
+			zend_deprecated_function(fbc);
+		}
+		if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) {
+			zend_nodiscard_function(fbc);
+		}
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			UNDEF_RESULT();
+			if (!0) {
+				ret = &retval;
+				ZVAL_UNDEF(ret);
+			}
+			goto fcall_by_name_end;
+		}
+	}
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		ret = NULL;
+		if (0) {
+			ret = EX_VAR(opline->result.var);
+		}
+
+		call->prev_execute_data = execute_data;
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+		LOAD_OPLINE_EX();
+
+
+
+
+		ZEND_VM_ENTER_EX();
+	} else {
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+		if (0) {
+			ret = NULL;
+		}
+
+		call->prev_execute_data = execute_data;
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		ret = 0 ? EX_VAR(opline->result.var) : &retval;
+		ZVAL_NULL(ret);
+
+
+		fbc->internal_function.handler(call, ret);
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
+#endif
+
+
+		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+		EG(current_execute_data) = execute_data;
+
+		goto fcall_by_name_end;
+	}
+
+	if (0) {
+fcall_by_name_end:
+
+		zend_vm_stack_free_args(call);
+
+		uint32_t call_info = ZEND_CALL_INFO(call);
+		if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) {
+			if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+				zend_free_extra_named_params(call->extra_named_params);
+			}
+			zend_vm_stack_free_call_frame_ex(call_info, call);
+		} else {
+			EG(vm_stack_top) = (zval*)call;
+		}
+
+		if (!0) {
+			i_zval_ptr_dtor(ret);
+		}
+	}
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	const uint32_t no_discard = 1 ? 0 : ZEND_ACC_NODISCARD;
+
+	if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) {
+		if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) {
+			zend_deprecated_function(fbc);
+		}
+		if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) {
+			zend_nodiscard_function(fbc);
+		}
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			UNDEF_RESULT();
+			if (!1) {
+				ret = &retval;
+				ZVAL_UNDEF(ret);
+			}
+			goto fcall_by_name_end;
+		}
+	}
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		ret = NULL;
+		if (1) {
+			ret = EX_VAR(opline->result.var);
+		}
+
+		call->prev_execute_data = execute_data;
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+		LOAD_OPLINE_EX();
+
+
+
+
+		ZEND_VM_ENTER_EX();
+	} else {
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+		if (0) {
+			ret = NULL;
+		}
+
+		call->prev_execute_data = execute_data;
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		ret = 1 ? EX_VAR(opline->result.var) : &retval;
+		ZVAL_NULL(ret);
+
+
+		fbc->internal_function.handler(call, ret);
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
+#endif
+
+
+		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+		EG(current_execute_data) = execute_data;
+
+		goto fcall_by_name_end;
+	}
+
+	if (0) {
+fcall_by_name_end:
+
+		zend_vm_stack_free_args(call);
+
+		uint32_t call_info = ZEND_CALL_INFO(call);
+		if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) {
+			if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+				zend_free_extra_named_params(call->extra_named_params);
+			}
+			zend_vm_stack_free_call_frame_ex(call_info, call);
+		} else {
+			EG(vm_stack_top) = (zval*)call;
+		}
+
+		if (!1) {
+			i_zval_ptr_dtor(ret);
+		}
+	}
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD;
+
+	if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) {
+		if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) {
+			zend_deprecated_function(fbc);
+		}
+		if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) {
+			zend_nodiscard_function(fbc);
+		}
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			UNDEF_RESULT();
+			if (!RETURN_VALUE_USED(opline)) {
+				ret = &retval;
+				ZVAL_UNDEF(ret);
+			}
+			goto fcall_by_name_end;
+		}
+	}
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		ret = NULL;
+		if (RETURN_VALUE_USED(opline)) {
+			ret = EX_VAR(opline->result.var);
+		}
+
+		call->prev_execute_data = execute_data;
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+		LOAD_OPLINE_EX();
+		SAVE_OPLINE();
+		zend_observer_fcall_begin_specialized(execute_data, false);
+
+		ZEND_VM_ENTER_EX();
+	} else {
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+		if (1) {
+			ret = NULL;
+		}
+
+		call->prev_execute_data = execute_data;
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
+		ZVAL_NULL(ret);
+
+		zend_observer_fcall_begin_specialized(call, false);
+		fbc->internal_function.handler(call, ret);
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
+#endif
+		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
+		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+		EG(current_execute_data) = execute_data;
+
+		goto fcall_by_name_end;
+	}
+
+	if (0) {
+fcall_by_name_end:
+
+		zend_vm_stack_free_args(call);
+
+		uint32_t call_info = ZEND_CALL_INFO(call);
+		if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) {
+			if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+				zend_free_extra_named_params(call->extra_named_params);
+			}
+			zend_vm_stack_free_call_frame_ex(call_info, call);
+		} else {
+			EG(vm_stack_top) = (zval*)call;
+		}
+
+		if (!RETURN_VALUE_USED(opline)) {
+			i_zval_ptr_dtor(ret);
+		}
+	}
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	const uint32_t no_discard = 0 ? 0 : ZEND_ACC_NODISCARD;
+
+	if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) {
+		if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) {
+			zend_deprecated_function(fbc);
+		}
+		if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) {
+			zend_nodiscard_function(fbc);
+		}
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
+				OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+			}
+			UNDEF_RESULT();
+			if (!0) {
+				ret = &retval;
+				ZVAL_UNDEF(ret);
+			}
+			goto fcall_end;
+		}
+	}
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		ret = NULL;
+		if (0) {
+			ret = EX_VAR(opline->result.var);
+		}
+
+		/* Closures created inside a generic frame carry that frame's T-table
+		 * via zend_vm_init_call_frame. Run the T-ref value-arg check against
+		 * the captured bindings now, before i_init_func_execute_data relocates
+		 * variadic args past the CV slots (which would leave the original arg
+		 * positions UNDEF and silently make every check pass). The cleanup on
+		 * failure matches ZEND_VERIFY_GENERIC_ARGUMENTS — at this point
+		 * call->prev_execute_data is still its zend_vm_init_call_frame value
+		 * (typically NULL), so EX(call) is the right slot to clear. */
+		if (UNEXPECTED(call->type_args
+				&& (fbc->common.fn_flags & ZEND_ACC_CLOSURE))) {
+			SAVE_OPLINE();
+			zend_verify_generic_arg_types(call, NULL);
+			if (UNEXPECTED(EG(exception))) {
+				zend_vm_stack_free_args(call);
+				if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+					OBJ_RELEASE(Z_OBJ(call->This));
+				}
+				EX(call) = call->prev_execute_data;
+				zend_vm_stack_free_call_frame(call);
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		call->prev_execute_data = execute_data;
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
+
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			LOAD_OPLINE_EX();
+
+
+
+
+			ZEND_VM_ENTER_EX();
+		} else {
+			SAVE_OPLINE_EX();
+
+
+			execute_data = EX(prev_execute_data);
+			LOAD_OPLINE();
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+		}
+	} else {
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+		if (0) {
+			ret = NULL;
+		}
+
+		call->prev_execute_data = execute_data;
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		ret = 0 ? EX_VAR(opline->result.var) : &retval;
+		ZVAL_NULL(ret);
+
+
+		if (!zend_execute_internal) {
+			/* saves one function call if zend_execute_internal is not used */
+			fbc->internal_function.handler(call, ret);
+		} else {
+			zend_execute_internal(call, ret);
+		}
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
+#endif
+
+
+		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+		EG(current_execute_data) = execute_data;
+
+		goto fcall_end;
+	}
+
+	if (0) {
+fcall_end:
+
+		zend_vm_stack_free_args(call);
+		if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+
+		if (!0) {
+			i_zval_ptr_dtor(ret);
+		}
+	}
+
+	if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	}
+
+	zend_vm_stack_free_call_frame(call);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	const uint32_t no_discard = 1 ? 0 : ZEND_ACC_NODISCARD;
+
+	if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) {
+		if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) {
+			zend_deprecated_function(fbc);
+		}
+		if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) {
+			zend_nodiscard_function(fbc);
+		}
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
+				OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+			}
+			UNDEF_RESULT();
+			if (!1) {
+				ret = &retval;
+				ZVAL_UNDEF(ret);
+			}
+			goto fcall_end;
+		}
+	}
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		ret = NULL;
+		if (1) {
+			ret = EX_VAR(opline->result.var);
+		}
+
+		/* Closures created inside a generic frame carry that frame's T-table
+		 * via zend_vm_init_call_frame. Run the T-ref value-arg check against
+		 * the captured bindings now, before i_init_func_execute_data relocates
+		 * variadic args past the CV slots (which would leave the original arg
+		 * positions UNDEF and silently make every check pass). The cleanup on
+		 * failure matches ZEND_VERIFY_GENERIC_ARGUMENTS — at this point
+		 * call->prev_execute_data is still its zend_vm_init_call_frame value
+		 * (typically NULL), so EX(call) is the right slot to clear. */
+		if (UNEXPECTED(call->type_args
+				&& (fbc->common.fn_flags & ZEND_ACC_CLOSURE))) {
+			SAVE_OPLINE();
+			zend_verify_generic_arg_types(call, NULL);
+			if (UNEXPECTED(EG(exception))) {
+				zend_vm_stack_free_args(call);
+				if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+					OBJ_RELEASE(Z_OBJ(call->This));
+				}
+				EX(call) = call->prev_execute_data;
+				zend_vm_stack_free_call_frame(call);
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		call->prev_execute_data = execute_data;
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
+
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			LOAD_OPLINE_EX();
+
+
+
+
+			ZEND_VM_ENTER_EX();
+		} else {
+			SAVE_OPLINE_EX();
+
+
+			execute_data = EX(prev_execute_data);
+			LOAD_OPLINE();
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+		}
+	} else {
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+		if (0) {
+			ret = NULL;
+		}
+
+		call->prev_execute_data = execute_data;
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		ret = 1 ? EX_VAR(opline->result.var) : &retval;
+		ZVAL_NULL(ret);
+
+
+		if (!zend_execute_internal) {
+			/* saves one function call if zend_execute_internal is not used */
+			fbc->internal_function.handler(call, ret);
+		} else {
+			zend_execute_internal(call, ret);
+		}
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
+#endif
+
+
+		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+		EG(current_execute_data) = execute_data;
+
+		goto fcall_end;
+	}
+
+	if (0) {
+fcall_end:
+
+		zend_vm_stack_free_args(call);
+		if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+
+		if (!1) {
+			i_zval_ptr_dtor(ret);
+		}
+	}
+
+	if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	}
+
+	zend_vm_stack_free_call_frame(call);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	zend_function *fbc = call->func;
+	zval *ret;
+	zval retval;
+
+	SAVE_OPLINE();
+	EX(call) = call->prev_execute_data;
+
+	const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD;
+
+	if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) {
+		if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) {
+			zend_deprecated_function(fbc);
+		}
+		if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) {
+			zend_nodiscard_function(fbc);
+		}
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
+				OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
+			}
+			UNDEF_RESULT();
+			if (!RETURN_VALUE_USED(opline)) {
+				ret = &retval;
+				ZVAL_UNDEF(ret);
+			}
+			goto fcall_end;
+		}
+	}
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		ret = NULL;
+		if (RETURN_VALUE_USED(opline)) {
+			ret = EX_VAR(opline->result.var);
+		}
+
+		/* Closures created inside a generic frame carry that frame's T-table
+		 * via zend_vm_init_call_frame. Run the T-ref value-arg check against
+		 * the captured bindings now, before i_init_func_execute_data relocates
+		 * variadic args past the CV slots (which would leave the original arg
+		 * positions UNDEF and silently make every check pass). The cleanup on
+		 * failure matches ZEND_VERIFY_GENERIC_ARGUMENTS — at this point
+		 * call->prev_execute_data is still its zend_vm_init_call_frame value
+		 * (typically NULL), so EX(call) is the right slot to clear. */
+		if (UNEXPECTED(call->type_args
+				&& (fbc->common.fn_flags & ZEND_ACC_CLOSURE))) {
+			SAVE_OPLINE();
+			zend_verify_generic_arg_types(call, NULL);
+			if (UNEXPECTED(EG(exception))) {
+				zend_vm_stack_free_args(call);
+				if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+					OBJ_RELEASE(Z_OBJ(call->This));
+				}
+				EX(call) = call->prev_execute_data;
+				zend_vm_stack_free_call_frame(call);
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		call->prev_execute_data = execute_data;
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
+
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			LOAD_OPLINE_EX();
+			SAVE_OPLINE();
+			zend_observer_fcall_begin_specialized(execute_data, false);
+			ZEND_VM_ENTER_EX();
+		} else {
+			SAVE_OPLINE_EX();
+			zend_observer_fcall_begin_specialized(execute_data, false);
+			execute_data = EX(prev_execute_data);
+			LOAD_OPLINE();
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+		}
+	} else {
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+		if (1) {
+			ret = NULL;
+		}
+
+		call->prev_execute_data = execute_data;
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
+		ZVAL_NULL(ret);
+
+		zend_observer_fcall_begin_specialized(call, false);
+		if (!zend_execute_internal) {
+			/* saves one function call if zend_execute_internal is not used */
+			fbc->internal_function.handler(call, ret);
+		} else {
+			zend_execute_internal(call, ret);
+		}
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+		ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
+#endif
+		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
+		ZEND_VM_FCALL_INTERRUPT_CHECK(call);
+
+		EG(current_execute_data) = execute_data;
+
+		goto fcall_end;
+	}
+
+	if (0) {
+fcall_end:
+
+		zend_vm_stack_free_args(call);
+		if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+
+		if (!RETURN_VALUE_USED(opline)) {
+			i_zval_ptr_dtor(ret);
+		}
+	}
+
+	if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
+		OBJ_RELEASE(Z_OBJ(call->This));
+	}
+
+	zend_vm_stack_free_call_frame(call);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION();
+	}
+	ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1);
+	ZEND_VM_CONTINUE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_CREATE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *return_value = EX(return_value);
+
+	if (EXPECTED(return_value)) {
+		USE_OPLINE
+		zend_generator *generator;
+		zend_execute_data *gen_execute_data;
+		uint32_t num_args, used_stack, call_info;
+
+		SAVE_OPLINE();
+		object_init_ex(return_value, zend_ce_generator);
+
+		/*
+		 * Normally the execute_data is allocated on the VM stack (because it does
+		 * not actually do any allocation and thus is faster). For generators
+		 * though this behavior would be suboptimal, because the (rather large)
+		 * structure would have to be copied back and forth every time execution is
+		 * suspended or resumed. That's why for generators the execution context
+		 * is allocated on heap.
+		 */
+		num_args = EX_NUM_ARGS();
+		if (EXPECTED(num_args <= EX(func)->op_array.num_args)) {
+			used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var + EX(func)->op_array.T) * sizeof(zval);
+			gen_execute_data = (zend_execute_data*)emalloc(used_stack);
+			used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var) * sizeof(zval);
+		} else {
+			used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - EX(func)->op_array.num_args) * sizeof(zval);
+			gen_execute_data = (zend_execute_data*)emalloc(used_stack);
+		}
+		memcpy(gen_execute_data, execute_data, used_stack);
+
+		/* Save execution context in generator object. */
+		generator = (zend_generator *) Z_OBJ_P(EX(return_value));
+		generator->func = gen_execute_data->func;
+		generator->execute_data = gen_execute_data;
+		generator->frozen_call_stack = NULL;
+		generator->execute_fake.opline = NULL;
+		generator->execute_fake.func = NULL;
+		generator->execute_fake.prev_execute_data = NULL;
+		ZVAL_OBJ(&generator->execute_fake.This, (zend_object *) generator);
+
+		gen_execute_data->opline = opline;
+		/* EX(return_value) keeps pointer to zend_object (not a real zval) */
+		gen_execute_data->return_value = (zval*)generator;
+		call_info = Z_TYPE_INFO(EX(This));
+		if ((call_info & Z_TYPE_MASK) == IS_OBJECT
+		 && (!(call_info & (ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS))
+			 /* Bug #72523 */
+			|| UNEXPECTED(zend_execute_ex != execute_ex))) {
+			ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS);
+			Z_ADDREF(gen_execute_data->This);
+		}
+		ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR));
+		Z_TYPE_INFO(gen_execute_data->This) = call_info;
+		gen_execute_data->prev_execute_data = NULL;
+
+		call_info = EX_CALL_INFO();
+		EG(current_execute_data) = EX(prev_execute_data);
+		if (EXPECTED(!(call_info & (ZEND_CALL_TOP|ZEND_CALL_ALLOCATED)))) {
+			EG(vm_stack_top) = (zval*)execute_data;
+			execute_data = EX(prev_execute_data);
+			LOAD_NEXT_OPLINE();
+			ZEND_VM_LEAVE();
+		} else if (EXPECTED(!(call_info & ZEND_CALL_TOP))) {
+			zend_execute_data *old_execute_data = execute_data;
+			execute_data = EX(prev_execute_data);
+			zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
+			LOAD_NEXT_OPLINE();
+			ZEND_VM_LEAVE();
+		} else {
+			ZEND_VM_RETURN();
+		}
+	} else {
+		ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+	}
+}
+
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t _arg_num, zval *_arg);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_UNPACK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *args;
+	uint32_t arg_num;
+
+	SAVE_OPLINE();
+	args = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R);
+	arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1;
+
+send_again:
+	if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
+		HashTable *ht = Z_ARRVAL_P(args);
+		zval *arg, *top;
+		zend_string *name;
+		bool have_named_params = 0;
+
+		zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
+
+		// TODO: Speed this up using a flag that specifies whether there are any ref parameters.
+		if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_REFCOUNT_P(args) > 1) {
+			uint32_t tmp_arg_num = arg_num;
+			bool separate = 0;
+
+			/* check if any of arguments are going to be passed by reference */
+			ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
+				if (UNEXPECTED(name)) {
+					void *cache_slot[2] = {NULL, NULL};
+					tmp_arg_num = zend_get_arg_offset_by_name(
+						EX(call)->func, name, cache_slot) + 1;
+				}
+				if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, tmp_arg_num)) {
+					separate = 1;
+					break;
+				}
+				tmp_arg_num++;
+			} ZEND_HASH_FOREACH_END();
+			if (separate) {
+				SEPARATE_ARRAY(args);
+				ht = Z_ARRVAL_P(args);
+			}
+		}
+
+		ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
+			if (UNEXPECTED(name)) {
+				void *cache_slot[2] = {NULL, NULL};
+				have_named_params = 1;
+				top = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot);
+				if (UNEXPECTED(!top)) {
+					FREE_OP(opline->op1_type, opline->op1.var);
+					HANDLE_EXCEPTION();
+				}
+			} else {
+				if (have_named_params) {
+					zend_throw_error(NULL,
+						"Cannot use positional argument after named argument during unpacking");
+					FREE_OP(opline->op1_type, opline->op1.var);
+					HANDLE_EXCEPTION();
+				}
+
+				top = ZEND_CALL_ARG(EX(call), arg_num);
+				ZEND_CALL_NUM_ARGS(EX(call))++;
+			}
+
+			if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+				if (Z_ISREF_P(arg)) {
+					Z_ADDREF_P(arg);
+					ZVAL_REF(top, Z_REF_P(arg));
+				} else if (opline->op1_type & (IS_VAR|IS_CV)) {
+					/* array is already separated above */
+					ZVAL_MAKE_REF_EX(arg, 2);
+					ZVAL_REF(top, Z_REF_P(arg));
+				} else {
+					Z_TRY_ADDREF_P(arg);
+					ZVAL_NEW_REF(top, arg);
+				}
+			} else {
+				ZVAL_COPY_DEREF(top, arg);
+			}
+
+			arg_num++;
+		} ZEND_HASH_FOREACH_END();
+
+	} else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) {
+		zend_class_entry *ce = Z_OBJCE_P(args);
+		zend_object_iterator *iter;
+		bool have_named_params = 0;
+
+		if (!ce || !ce->get_iterator) {
+			zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(args));
+		} else {
+
+			iter = ce->get_iterator(ce, args, 0);
+			if (UNEXPECTED(!iter)) {
+				FREE_OP(opline->op1_type, opline->op1.var);
+				if (!EG(exception)) {
+					zend_throw_exception_ex(
+						NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)
+					);
+				}
+				HANDLE_EXCEPTION();
+			}
+
+			const zend_object_iterator_funcs *funcs = iter->funcs;
+			if (funcs->rewind) {
+				funcs->rewind(iter);
+			}
+
+			for (; funcs->valid(iter) == SUCCESS; ++arg_num) {
+				zval *arg, *top;
+
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					break;
+				}
+
+				arg = funcs->get_current_data(iter);
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					break;
+				}
+
+				zend_string *name = NULL;
+				if (funcs->get_current_key) {
+					zval key;
+					funcs->get_current_key(iter, &key);
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						break;
+					}
+
+					if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) {
+						if (UNEXPECTED(Z_TYPE(key) != IS_STRING)) {
+							zend_throw_error(NULL,
+								"Keys must be of type int|string during argument unpacking");
+							zval_ptr_dtor(&key);
+							break;
+						}
+
+						name = Z_STR_P(&key);
+
+						zend_ulong tmp;
+						if (ZEND_HANDLE_NUMERIC(name, tmp)) {
+							name = NULL;
+						}
+					}
+				}
+
+				if (UNEXPECTED(name)) {
+					void *cache_slot[2] = {NULL, NULL};
+					have_named_params = 1;
+					top = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot);
+					if (UNEXPECTED(!top)) {
+						zend_string_release(name);
+						break;
+					}
+
+					ZVAL_DEREF(arg);
+					Z_TRY_ADDREF_P(arg);
+
+					if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+						zend_error(
+							E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
+							" by unpacking a Traversable, passing by-value instead", arg_num,
+							EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
+							EX(call)->func->common.scope ? "::" : "",
+							ZSTR_VAL(EX(call)->func->common.function_name)
+						);
+						ZVAL_NEW_REF(top, arg);
+					} else {
+						ZVAL_COPY_VALUE(top, arg);
+					}
+
+					zend_string_release(name);
+				} else {
+					if (have_named_params) {
+						zend_throw_error(NULL,
+							"Cannot use positional argument after named argument during unpacking");
+						break;
+					}
+
+					zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1);
+					top = ZEND_CALL_ARG(EX(call), arg_num);
+					ZVAL_DEREF(arg);
+					Z_TRY_ADDREF_P(arg);
+
+					if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+						zend_error(
+							E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()"
+							" by unpacking a Traversable, passing by-value instead", arg_num,
+							EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "",
+							EX(call)->func->common.scope ? "::" : "",
+							ZSTR_VAL(EX(call)->func->common.function_name)
+						);
+						ZVAL_NEW_REF(top, arg);
+					} else {
+						ZVAL_COPY_VALUE(top, arg);
+					}
+
+					ZEND_CALL_NUM_ARGS(EX(call))++;
+				}
+
+				funcs->move_forward(iter);
+			}
+
+			zend_iterator_dtor(iter);
+		}
+	} else if (EXPECTED(Z_ISREF_P(args))) {
+		args = Z_REFVAL_P(args);
+		goto send_again;
+	} else {
+		if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_P(args) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(args));
+	}
+
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_ARRAY_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *args;
+
+	SAVE_OPLINE();
+	args = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
+
+	if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) {
+		if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_ISREF_P(args)) {
+			args = Z_REFVAL_P(args);
+			if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
+				goto send_array;
+			}
+		}
+		zend_type_error("call_user_func_array(): Argument #2 ($args) must be of type array, %s given", zend_zval_value_name(args));
+		FREE_OP(opline->op2_type, opline->op2.var);
+		FREE_OP(opline->op1_type, opline->op1.var);
+		HANDLE_EXCEPTION();
+	} else {
+		uint32_t arg_num;
+		HashTable *ht;
+		zval *arg, *param;
+
+send_array:
+		ht = Z_ARRVAL_P(args);
+		if (opline->op2_type != IS_UNUSED) {
+			/* We don't need to handle named params in this case,
+			 * because array_slice() is called with $preserve_keys == false. */
+			zval *op2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R);
+			uint32_t skip = opline->extended_value;
+			uint32_t count = zend_hash_num_elements(ht);
+			zend_long len;
+			if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+				len = Z_LVAL_P(op2);
+			} else if (Z_TYPE_P(op2) == IS_NULL) {
+				len = count - skip;
+			} else if (EX_USES_STRICT_TYPES()
+					|| !zend_parse_arg_long_weak(op2, &len, /* arg_num */ 3)) {
+				zend_type_error(
+					"array_slice(): Argument #3 ($length) must be of type ?int, %s given",
+					zend_zval_value_name(op2));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				FREE_OP(opline->op1_type, opline->op1.var);
+				HANDLE_EXCEPTION();
+			}
+
+			if (len < 0) {
+				len += (zend_long)(count - skip);
+			}
+			if (skip < count && len > 0) {
+				if (len > (zend_long)(count - skip)) {
+					len = (zend_long)(count - skip);
+				}
+				zend_vm_stack_extend_call_frame(&EX(call), 0, len);
+				arg_num = 1;
+				param = ZEND_CALL_ARG(EX(call), 1);
+				ZEND_HASH_FOREACH_VAL(ht, arg) {
+					bool must_wrap = 0;
+					if (skip > 0) {
+						skip--;
+						continue;
+					} else if ((zend_long)(arg_num - 1) >= len) {
+						break;
+					} else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+						if (UNEXPECTED(!Z_ISREF_P(arg))) {
+							if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+								/* By-value send is not allowed -- emit a warning,
+								 * but still perform the call. */
+								zend_param_must_be_ref(EX(call)->func, arg_num);
+								must_wrap = 1;
+							}
+						}
+					} else {
+						if (Z_ISREF_P(arg) &&
+						    !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+							/* don't separate references for __call */
+							arg = Z_REFVAL_P(arg);
+						}
+					}
+					if (EXPECTED(!must_wrap)) {
+						ZVAL_COPY(param, arg);
+					} else {
+						Z_TRY_ADDREF_P(arg);
+						ZVAL_NEW_REF(param, arg);
+					}
+					ZEND_CALL_NUM_ARGS(EX(call))++;
+					arg_num++;
+					param++;
+				} ZEND_HASH_FOREACH_END();
+			}
+			FREE_OP(opline->op2_type, opline->op2.var);
+		} else {
+			zend_string *name;
+			bool have_named_params;
+			zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
+			arg_num = 1;
+			param = ZEND_CALL_ARG(EX(call), 1);
+			have_named_params = 0;
+			ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
+				if (name) {
+					void *cache_slot[2] = {NULL, NULL};
+					have_named_params = 1;
+					param = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot);
+					if (!param) {
+						FREE_OP(opline->op1_type, opline->op1.var);
+						HANDLE_EXCEPTION();
+					}
+				} else if (have_named_params) {
+					zend_throw_error(NULL,
+						"Cannot use positional argument after named argument");
+					FREE_OP(opline->op1_type, opline->op1.var);
+					HANDLE_EXCEPTION();
+				}
+
+				bool must_wrap = 0;
+				if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+					if (UNEXPECTED(!Z_ISREF_P(arg))) {
+						if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+							/* By-value send is not allowed -- emit a warning,
+							 * but still perform the call. */
+							zend_param_must_be_ref(EX(call)->func, arg_num);
+							must_wrap = 1;
+						}
+					}
+				} else {
+					if (Z_ISREF_P(arg) &&
+					    !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+						/* don't separate references for __call */
+						arg = Z_REFVAL_P(arg);
+					}
+				}
+
+				if (EXPECTED(!must_wrap)) {
+					ZVAL_COPY(param, arg);
+				} else {
+					Z_TRY_ADDREF_P(arg);
+					ZVAL_NEW_REF(param, arg);
+				}
+				if (!name) {
+					ZEND_CALL_NUM_ARGS(EX(call))++;
+					arg_num++;
+					param++;
+				}
+			} ZEND_HASH_FOREACH_END();
+		}
+	}
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+
+	zend_missing_arg_error(execute_data);
+	HANDLE_EXCEPTION();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1);
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_NOTYPE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	uint32_t arg_num = opline->op1.num;
+
+	if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
+		ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Origin compiled this parameter as mixed (MAY_BE_ANY), but a generic
+	 * inheritance clone may carry a substituted type in arg_info that we must
+	 * verify against. */
+	if (UNEXPECTED(EX(func)->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
+		zval *param = EX_VAR(opline->result.var);
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param));
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_UNPACK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	HashTable *result_ht;
+
+	SAVE_OPLINE();
+	op1 = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
+	result_ht = Z_ARRVAL_P(EX_VAR(opline->result.var));
+
+add_unpack_again:
+	if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) {
+		HashTable *ht = Z_ARRVAL_P(op1);
+		zval *val;
+
+		if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
+			/* zend_hash_extend() skips initialization when the number of elements is 0,
+			 * but the code below expects that result_ht is initialized as packed.
+			 * We can just skip the work in that case. */
+			if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) {
+				zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
+				ZEND_HASH_FILL_PACKED(result_ht) {
+					ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
+						if (UNEXPECTED(Z_ISREF_P(val)) &&
+							UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
+							val = Z_REFVAL_P(val);
+						}
+						Z_TRY_ADDREF_P(val);
+						ZEND_HASH_FILL_ADD(val);
+					} ZEND_HASH_FOREACH_END();
+				} ZEND_HASH_FILL_END();
+			}
+		} else {
+			zend_string *key;
+
+			ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
+				if (UNEXPECTED(Z_ISREF_P(val)) &&
+					UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
+					val = Z_REFVAL_P(val);
+				}
+				Z_TRY_ADDREF_P(val);
+				if (key) {
+					zend_hash_update(result_ht, key, val);
+				} else {
+					if (!zend_hash_next_index_insert(result_ht, val)) {
+						zend_cannot_add_element();
+						zval_ptr_dtor_nogc(val);
+						break;
+					}
+				}
+			} ZEND_HASH_FOREACH_END();
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_OBJECT)) {
+		zend_class_entry *ce = Z_OBJCE_P(op1);
+		zend_object_iterator *iter;
+
+		if (!ce || !ce->get_iterator) {
+			zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(op1));
+		} else {
+			iter = ce->get_iterator(ce, op1, 0);
+			if (UNEXPECTED(!iter)) {
+				FREE_OP(opline->op1_type, opline->op1.var);
+				if (!EG(exception)) {
+					zend_throw_exception_ex(
+						NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)
+					);
+				}
+				HANDLE_EXCEPTION();
+			}
+
+			const zend_object_iterator_funcs *funcs = iter->funcs;
+			if (funcs->rewind) {
+				funcs->rewind(iter);
+			}
+
+			for (; funcs->valid(iter) == SUCCESS; ) {
+				zval *val;
+
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					break;
+				}
+
+				val = funcs->get_current_data(iter);
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					break;
+				}
+
+				zval key;
+				if (funcs->get_current_key) {
+					funcs->get_current_key(iter, &key);
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						break;
+					}
+
+					if (UNEXPECTED(Z_TYPE(key) != IS_LONG && Z_TYPE(key) != IS_STRING)) {
+						zend_throw_error(NULL,
+							"Keys must be of type int|string during array unpacking");
+						zval_ptr_dtor(&key);
+						break;
+					}
+				} else {
+					ZVAL_UNDEF(&key);
+				}
+
+				ZVAL_DEREF(val);
+				Z_TRY_ADDREF_P(val);
+
+				zend_ulong num_key;
+				if (Z_TYPE(key) == IS_STRING && !ZEND_HANDLE_NUMERIC(Z_STR(key), num_key)) {
+					zend_hash_update(result_ht, Z_STR(key), val);
+					zval_ptr_dtor_str(&key);
+				} else {
+					zval_ptr_dtor(&key);
+					if (!zend_hash_next_index_insert(result_ht, val)) {
+						zend_cannot_add_element();
+						zval_ptr_dtor_nogc(val);
+						break;
+					}
+				}
+
+				funcs->move_forward(iter);
+				if (UNEXPECTED(EG(exception))) {
+					break;
+				}
+			}
+
+			zend_iterator_dtor(iter);
+		}
+	} else if (EXPECTED(Z_ISREF_P(op1))) {
+		op1 = Z_REFVAL_P(op1);
+		goto add_unpack_again;
+	} else {
+		zend_throw_error(NULL, "Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(op1));
+	}
+
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varname;
+	zend_string *name, *tmp_name = NULL;
+	zend_class_entry *ce;
+
+	SAVE_OPLINE();
+
+	if (opline->op2_type == IS_CONST) {
+		ce = CACHED_PTR(opline->extended_value);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+				FREE_OP(opline->op1_type, opline->op1.var);
+				HANDLE_EXCEPTION();
+			}
+			/*CACHE_PTR(opline->extended_value, ce);*/
+		}
+	} else if (opline->op2_type == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op2.num);
+		if (UNEXPECTED(ce == NULL)) {
+			FREE_OP(opline->op1_type, opline->op1.var);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op2.var));
+	}
+
+	varname = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R);
+	if (opline->op1_type == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+	} else {
+		if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			varname = ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			FREE_OP(opline->op1_type, opline->op1.var);
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	zend_std_unset_static_property(ce, name);
+
+	zend_tmp_string_release(tmp_name);
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_fe_fetch_object_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array;
+	zval *value;
+	uint32_t value_type;
+	HashTable *fe_ht;
+	HashPosition pos;
+	Bucket *p;
+	zend_object_iterator *iter;
+
+	array = EX_VAR(opline->op1.var);
+	SAVE_OPLINE();
+
+	ZEND_ASSERT(Z_TYPE_P(array) == IS_OBJECT);
+	if ((iter = zend_iterator_unwrap(array)) == NULL) {
+		/* plain object */
+
+		fe_ht = Z_OBJPROP_P(array);
+		pos = zend_hash_iterator_pos(Z_FE_ITER_P(array), fe_ht);
+		p = fe_ht->arData + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				goto fe_fetch_r_exit;
+			}
+			pos++;
+			value = &p->val;
+			value_type = Z_TYPE_INFO_P(value);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				if (UNEXPECTED(value_type == IS_INDIRECT)) {
+					value = Z_INDIRECT_P(value);
+					value_type = Z_TYPE_INFO_P(value);
+					if (EXPECTED(value_type != IS_UNDEF)
+					 && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) {
+						break;
+					}
+				} else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0)
+						|| !p->key
+						|| zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) {
+					break;
+				}
+			}
+			p++;
+		}
+		EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos;
+		if (RETURN_VALUE_USED(opline)) {
+			if (UNEXPECTED(!p->key)) {
+				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
+			} else if (ZSTR_VAL(p->key)[0]) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
+			} else {
+				const char *class_name, *prop_name;
+				size_t prop_name_len;
+				zend_unmangle_property_name_ex(
+					p->key, &class_name, &prop_name, &prop_name_len);
+				ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len);
+			}
+		}
+	} else {
+		const zend_object_iterator_funcs *funcs = iter->funcs;
+		if (EXPECTED(++iter->index > 0)) {
+			/* This could cause an endless loop if index becomes zero again.
+			 * In case that ever happens we need an additional flag. */
+			funcs->move_forward(iter);
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			}
+			if (UNEXPECTED(funcs->valid(iter) == FAILURE)) {
+				/* reached end of iteration */
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				}
+fe_fetch_r_exit:
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
+			}
+		}
+		value = funcs->get_current_data(iter);
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			UNDEF_RESULT();
+			HANDLE_EXCEPTION();
+		}
+		if (!value) {
+			/* failure in get_current_data */
+			goto fe_fetch_r_exit;
+		}
+		if (RETURN_VALUE_USED(opline)) {
+			if (funcs->get_current_key) {
+				funcs->get_current_key(iter, EX_VAR(opline->result.var));
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				}
+			} else {
+				ZVAL_LONG(EX_VAR(opline->result.var), iter->index);
+			}
+		}
+		value_type = Z_TYPE_INFO_P(value);
+	}
+
+	if (EXPECTED(opline->op2_type == IS_CV)) {
+		zval *variable_ptr = EX_VAR(opline->op2.var);
+		zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	} else {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			value = Z_REFVAL_P(value);
+			value_type = Z_TYPE_INFO_P(value);
+		}
+		zval *res = EX_VAR(opline->op2.var);
+		zend_refcounted *gc = Z_COUNTED_P(value);
+
+		ZVAL_COPY_VALUE_EX(res, value, gc, value_type);
+		if (Z_TYPE_INFO_REFCOUNTED(value_type)) {
+			GC_ADDREF(gc);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	bool result;
+
+	SAVE_OPLINE();
+
+	value = zend_fetch_static_property_address(NULL, opline->extended_value & ~ZEND_ISEMPTY, BP_VAR_IS, 0 OPLINE_CC EXECUTE_DATA_CC);
+
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+		    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+	} else {
+		result = value == NULL || !i_zend_is_true(value);
+	}
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BEGIN_SILENCE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting));
+
+	if (!E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))) {
+		do {
+			/* Do not silence fatal errors */
+			EG(error_reporting) &= E_FATAL_ERRORS;
+			if (!EG(error_reporting_ini_entry)) {
+				zval *zv = zend_hash_find_known_hash(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING));
+				if (zv) {
+					EG(error_reporting_ini_entry) = (zend_ini_entry *)Z_PTR_P(zv);
+				} else {
+					break;
+				}
+			}
+			if (!EG(error_reporting_ini_entry)->modified) {
+				if (!EG(modified_ini_directives)) {
+					ALLOC_HASHTABLE(EG(modified_ini_directives));
+					zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
+				}
+				if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), EG(error_reporting_ini_entry)) != NULL)) {
+					EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
+					EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
+					EG(error_reporting_ini_entry)->modified = 1;
+				}
+			}
+		} while (0);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_STMT_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (!EG(no_extensions)) {
+		SAVE_OPLINE();
+		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, execute_data);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_FCALL_BEGIN_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (!EG(no_extensions)) {
+		SAVE_OPLINE();
+		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, execute_data);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_FCALL_END_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (!EG(no_extensions)) {
+		SAVE_OPLINE();
+		zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, execute_data);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_ANON_CLASS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *zv;
+	zend_class_entry *ce;
+	USE_OPLINE
+
+	ce = CACHED_PTR(opline->extended_value);
+	if (UNEXPECTED(ce == NULL)) {
+		zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1));
+		zv = zend_hash_find_known_hash(EG(class_table), rtd_key);
+		ZEND_ASSERT(zv != NULL);
+		ce = Z_CE_P(zv);
+		if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
+			SAVE_OPLINE();
+			ce = zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key);
+			if (EG(exception)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		CACHE_PTR(opline->extended_value, ce);
+	}
+	Z_CE_P(EX_VAR(opline->result.var)) = ce;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_FUNCTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_function *func;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num];
+	do_bind_function(func, RT_CONSTANT(opline, opline->op1));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TICKS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (++EG(ticks_count) >= opline->extended_value) {
+		EG(ticks_count) = 0;
+		if (zend_ticks_function) {
+			SAVE_OPLINE();
+			zend_fiber_switch_block();
+			zend_ticks_function(opline->extended_value);
+			zend_fiber_switch_unblock();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_NOP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NOP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t try_catch_offset, uint32_t op_num);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HANDLE_EXCEPTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	const zend_op *throw_op = EG(opline_before_exception);
+
+	/* Exception was thrown before executing any op */
+	if (UNEXPECTED(!throw_op)) {
+		ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX -1, 0));
+	}
+
+	uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes;
+	uint32_t current_try_catch_offset = -1;
+
+	if ((throw_op->opcode == ZEND_FREE || throw_op->opcode == ZEND_FE_FREE)
+		&& throw_op->extended_value & ZEND_FREE_ON_RETURN) {
+		/* exceptions thrown because of loop var destruction on return/break/...
+		 * are logically thrown at the end of the foreach loop, so adjust the
+		 * throw_op_num to the final loop variable FREE.
+		 */
+		uint32_t new_throw_op_num = throw_op_num + throw_op->op2.opline_num;
+		cleanup_live_vars(execute_data, throw_op_num, new_throw_op_num);
+		throw_op_num = new_throw_op_num;
+	}
+
+	/* Find the innermost try/catch/finally the exception was thrown in */
+	for (uint32_t i = 0; i < EX(func)->op_array.last_try_catch; i++) {
+		zend_try_catch_element *try_catch = &EX(func)->op_array.try_catch_array[i];
+		if (try_catch->try_op > throw_op_num) {
+			/* further blocks will not be relevant... */
+			break;
+		}
+		if (throw_op_num < try_catch->catch_op || throw_op_num < try_catch->finally_end) {
+			current_try_catch_offset = i;
+		}
+	}
+
+	cleanup_unfinished_calls(execute_data, throw_op_num);
+
+	if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) {
+		switch (throw_op->opcode) {
+			case ZEND_ADD_ARRAY_ELEMENT:
+			case ZEND_ADD_ARRAY_UNPACK:
+			case ZEND_ROPE_INIT:
+			case ZEND_ROPE_ADD:
+				break; /* exception while building structures, live range handling will free those */
+
+			case ZEND_FETCH_CLASS:
+			case ZEND_DECLARE_ANON_CLASS:
+				break; /* return value is zend_class_entry pointer */
+
+			default:
+				/* smart branch opcodes may not initialize result */
+				if (!zend_is_smart_branch(throw_op)) {
+					zval_ptr_dtor_nogc(EX_VAR(throw_op->result.var));
+				}
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, throw_op_num));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_USER_OPCODE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	int ret;
+
+	SAVE_OPLINE();
+	ret = zend_user_opcode_handlers[opline->opcode](execute_data);
+	opline = EX(opline);
+
+	switch (ret) {
+		case ZEND_USER_OPCODE_CONTINUE:
+			ZEND_VM_CONTINUE();
+		case ZEND_USER_OPCODE_RETURN:
+			if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
+				zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+				EG(current_execute_data) = EX(prev_execute_data);
+				zend_generator_close(generator, 1);
+				ZEND_VM_RETURN();
+			} else {
+				ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+			}
+		case ZEND_USER_OPCODE_ENTER:
+			ZEND_VM_ENTER();
+		case ZEND_USER_OPCODE_LEAVE:
+			ZEND_VM_LEAVE();
+		case ZEND_USER_OPCODE_DISPATCH:
+			ZEND_VM_DISPATCH(opline->opcode, opline);
+		default:
+			ZEND_VM_DISPATCH((uint8_t)(ret & 0xff), opline);
+	}
+}
+
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator");
+	FREE_OP(opline->op2_type, opline->op2.var);
+	FREE_OP(opline->op1_type, opline->op1.var);
+	UNDEF_RESULT();
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DISCARD_EXCEPTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *fast_call = EX_VAR(opline->op1.var);
+	SAVE_OPLINE();
+
+	/* cleanup incomplete RETURN statement */
+	if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1
+	 && (EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2_type & (IS_TMP_VAR | IS_VAR))) {
+		zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var);
+
+		zval_ptr_dtor(return_value);
+		/* Clear return value in case we hit both DISCARD_EXCEPTION and
+		 * zend_dispatch_try_catch_finally_helper, which will free the return
+		 * value again. See OSS-Fuzz #438780145. */
+		ZVAL_NULL(return_value);
+	}
+
+	/* cleanup delayed exception */
+	if (Z_OBJ_P(fast_call) != NULL) {
+		/* discard the previously thrown exception */
+		OBJ_RELEASE(Z_OBJ_P(fast_call));
+		Z_OBJ_P(fast_call) = NULL;
+	}
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CALL_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *fast_call = EX_VAR(opline->result.var);
+
+	Z_OBJ_P(fast_call) = NULL;
+	/* set return address */
+	Z_OPLINE_NUM_P(fast_call) = opline - EX(func)->op_array.opcodes;
+	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_RET_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *fast_call = EX_VAR(opline->op1.var);
+	uint32_t current_try_catch_offset, current_op_num;
+
+	if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1) {
+		const zend_op *fast_ret = EX(func)->op_array.opcodes + Z_OPLINE_NUM_P(fast_call);
+
+		ZEND_VM_JMP_EX(fast_ret + 1, 0);
+	}
+
+	/* special case for unhandled exceptions */
+	EG(exception) = Z_OBJ_P(fast_call);
+	Z_OBJ_P(fast_call) = NULL;
+	current_try_catch_offset = opline->op2.num;
+	current_op_num = opline - EX(func)->op_array.opcodes;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, current_op_num));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSERT_CHECK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (EG(assertions) <= 0) {
+		zend_op *target = OP_JMP_ADDR(opline, opline->op2);
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_TRUE(EX_VAR(opline->result.var));
+		}
+		ZEND_VM_JMP_EX(target, 0);
+	} else {
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_array *args = NULL;
+	zend_function *fbc = EX(func);
+	zval *ret = EX(return_value);
+	uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_EXTRA_NAMED_PARAMS);
+	uint32_t num_args = EX_NUM_ARGS();
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (num_args) {
+		zval *p = ZEND_CALL_ARG(execute_data, 1);
+		zval *end = p + num_args;
+
+		args = zend_new_array(num_args);
+		zend_hash_real_init_packed(args);
+		ZEND_HASH_FILL_PACKED(args) {
+			do {
+				ZEND_HASH_FILL_ADD(p);
+				p++;
+			} while (p != end);
+		} ZEND_HASH_FILL_END();
+	}
+
+	call = execute_data;
+	execute_data = EG(current_execute_data) = EX(prev_execute_data);
+
+	call->func = (fbc->op_array.fn_flags & ZEND_ACC_STATIC) ? fbc->op_array.scope->__callstatic : fbc->op_array.scope->__call;
+	ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
+	ZEND_CALL_NUM_ARGS(call) = 2;
+
+	ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);
+
+	zval *call_args = ZEND_CALL_ARG(call, 2);
+	if (args) {
+		ZVAL_ARR(call_args, args);
+	} else {
+		ZVAL_EMPTY_ARRAY(call_args);
+	}
+	if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+		if (zend_hash_num_elements(Z_ARRVAL_P(call_args)) == 0) {
+			GC_ADDREF(call->extra_named_params);
+			ZVAL_ARR(call_args, call->extra_named_params);
+		} else {
+			SEPARATE_ARRAY(call_args);
+			zend_hash_copy(Z_ARRVAL_P(call_args), call->extra_named_params, zval_add_ref);
+		}
+	}
+	zend_free_trampoline(fbc);
+	fbc = call->func;
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			LOAD_OPLINE_EX();
+
+
+
+
+			ZEND_VM_ENTER_EX();
+		} else {
+			SAVE_OPLINE_EX();
+
+
+			execute_data = EX(prev_execute_data);
+			if (execute_data) {
+				LOAD_OPLINE();
+			}
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+		}
+	} else {
+		zval retval;
+
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		if (ret == NULL) {
+			ret = &retval;
+		}
+
+		ZVAL_NULL(ret);
+
+
+		if (!zend_execute_internal) {
+			/* saves one function call if zend_execute_internal is not used */
+			fbc->internal_function.handler(call, ret);
+		} else {
+			zend_execute_internal(call, ret);
+		}
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+#endif
+
+
+		EG(current_execute_data) = call->prev_execute_data;
+
+		zend_vm_stack_free_args(call);
+		if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+		if (ret == &retval) {
+			zval_ptr_dtor(ret);
+		}
+	}
+
+	execute_data = EG(current_execute_data);
+
+	if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
+		ZEND_VM_RETURN();
+	}
+
+	if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+		zend_object *object = Z_OBJ(call->This);
+		OBJ_RELEASE(object);
+	}
+	zend_vm_stack_free_call_frame(call);
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION_LEAVE();
+	}
+
+	LOAD_OPLINE();
+	ZEND_VM_INC_OPCODE();
+	ZEND_VM_LEAVE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_array *args = NULL;
+	zend_function *fbc = EX(func);
+	zval *ret = EX(return_value);
+	uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_EXTRA_NAMED_PARAMS);
+	uint32_t num_args = EX_NUM_ARGS();
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (num_args) {
+		zval *p = ZEND_CALL_ARG(execute_data, 1);
+		zval *end = p + num_args;
+
+		args = zend_new_array(num_args);
+		zend_hash_real_init_packed(args);
+		ZEND_HASH_FILL_PACKED(args) {
+			do {
+				ZEND_HASH_FILL_ADD(p);
+				p++;
+			} while (p != end);
+		} ZEND_HASH_FILL_END();
+	}
+
+	call = execute_data;
+	execute_data = EG(current_execute_data) = EX(prev_execute_data);
+
+	call->func = (fbc->op_array.fn_flags & ZEND_ACC_STATIC) ? fbc->op_array.scope->__callstatic : fbc->op_array.scope->__call;
+	ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
+	ZEND_CALL_NUM_ARGS(call) = 2;
+
+	ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);
+
+	zval *call_args = ZEND_CALL_ARG(call, 2);
+	if (args) {
+		ZVAL_ARR(call_args, args);
+	} else {
+		ZVAL_EMPTY_ARRAY(call_args);
+	}
+	if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+		if (zend_hash_num_elements(Z_ARRVAL_P(call_args)) == 0) {
+			GC_ADDREF(call->extra_named_params);
+			ZVAL_ARR(call_args, call->extra_named_params);
+		} else {
+			SEPARATE_ARRAY(call_args);
+			zend_hash_copy(Z_ARRVAL_P(call_args), call->extra_named_params, zval_add_ref);
+		}
+	}
+	zend_free_trampoline(fbc);
+	fbc = call->func;
+
+	if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+		if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		execute_data = call;
+		i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			LOAD_OPLINE_EX();
+			SAVE_OPLINE();
+			zend_observer_fcall_begin_specialized(execute_data, false);
+			ZEND_VM_ENTER_EX();
+		} else {
+			SAVE_OPLINE_EX();
+			zend_observer_fcall_begin_specialized(execute_data, false);
+			execute_data = EX(prev_execute_data);
+			if (execute_data) {
+				LOAD_OPLINE();
+			}
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+		}
+	} else {
+		zval retval;
+
+		ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+
+		EG(current_execute_data) = call;
+
+#if ZEND_DEBUG
+		bool should_throw = zend_internal_call_should_throw(fbc, call);
+#endif
+
+		if (ret == NULL) {
+			ret = &retval;
+		}
+
+		ZVAL_NULL(ret);
+		zend_observer_fcall_begin_specialized(call, false);
+		if (!zend_execute_internal) {
+			/* saves one function call if zend_execute_internal is not used */
+			fbc->internal_function.handler(call, ret);
+		} else {
+			zend_execute_internal(call, ret);
+		}
+
+#if ZEND_DEBUG
+		if (!EG(exception) && call->func) {
+			if (should_throw) {
+				zend_internal_call_arginfo_violation(call->func);
+			}
+			if (call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
+				bool result = zend_verify_internal_return_type(call->func, ret);
+				ZEND_ASSERT(result);
+			}
+			ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+				? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
+			zend_verify_internal_func_info(call->func, ret);
+			ZEND_ASSERT(!(ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC)
+					|| !(call->func->common.fn_flags2 & ZEND_ACC2_FORBID_DYN_CALLS));
+		}
+#endif
+		zend_observer_fcall_end(call, EG(exception) ? NULL : ret);
+
+		EG(current_execute_data) = call->prev_execute_data;
+
+		zend_vm_stack_free_args(call);
+		if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
+			zend_free_extra_named_params(call->extra_named_params);
+		}
+		if (ret == &retval) {
+			zval_ptr_dtor(ret);
+		}
+	}
+
+	execute_data = EG(current_execute_data);
+
+	if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
+		ZEND_VM_RETURN();
+	}
+
+	if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
+		zend_object *object = Z_OBJ(call->This);
+		OBJ_RELEASE(object);
+	}
+	zend_vm_stack_free_call_frame(call);
+
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zend_rethrow_exception(execute_data);
+		HANDLE_EXCEPTION_LEAVE();
+	}
+
+	LOAD_OPLINE();
+	ZEND_VM_INC_OPCODE();
+	ZEND_VM_LEAVE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+	zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R);
+	zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R);
+	if (EG(exception)) {
+		FREE_OP(opline->op1_type, opline->op1.var);
+		FREE_OP(opline->op2_type, opline->op2.var);
+		HANDLE_EXCEPTION();
+	}
+
+#if 0 || 0
+	if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_2 function = (zend_frameless_function_2)ZEND_FLF_HANDLER(opline);
+		function(result, arg1, arg2);
+	}
+
+	FREE_OP(opline->op1_type, opline->op1.var);
+	/* Set OP1 to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */
+	if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
+		ZVAL_UNDEF(EX_VAR(opline->op1.var));
+	}
+	FREE_OP(opline->op2_type, opline->op2.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+	zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R);
+	zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R);
+	if (EG(exception)) {
+		FREE_OP(opline->op1_type, opline->op1.var);
+		FREE_OP(opline->op2_type, opline->op2.var);
+		HANDLE_EXCEPTION();
+	}
+
+#if 0 || 1
+	if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_2 function = (zend_frameless_function_2)ZEND_FLF_HANDLER(opline);
+		function(result, arg1, arg2);
+	}
+
+	FREE_OP(opline->op1_type, opline->op1.var);
+	/* Set OP1 to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */
+	if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
+		ZVAL_UNDEF(EX_VAR(opline->op1.var));
+	}
+	FREE_OP(opline->op2_type, opline->op2.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+	zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R);
+	zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R);
+	zval *arg3 = get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1);
+	if (EG(exception)) {
+		FREE_OP(opline->op1_type, opline->op1.var);
+		FREE_OP(opline->op2_type, opline->op2.var);
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+		HANDLE_EXCEPTION();
+	}
+
+#if 0 || 0
+	if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_3 function = (zend_frameless_function_3)ZEND_FLF_HANDLER(opline);
+		function(result, arg1, arg2, arg3);
+	}
+
+	FREE_OP(opline->op1_type, opline->op1.var);
+	/* Set to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */
+	if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
+		ZVAL_UNDEF(EX_VAR(opline->op1.var));
+	}
+	FREE_OP(opline->op2_type, opline->op2.var);
+	if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
+		ZVAL_UNDEF(EX_VAR(opline->op2.var));
+	}
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+	zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R);
+	zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R);
+	zval *arg3 = get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1);
+	if (EG(exception)) {
+		FREE_OP(opline->op1_type, opline->op1.var);
+		FREE_OP(opline->op2_type, opline->op2.var);
+		FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+		HANDLE_EXCEPTION();
+	}
+
+#if 0 || 1
+	if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_3 function = (zend_frameless_function_3)ZEND_FLF_HANDLER(opline);
+		function(result, arg1, arg2, arg3);
+	}
+
+	FREE_OP(opline->op1_type, opline->op1.var);
+	/* Set to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */
+	if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
+		ZVAL_UNDEF(EX_VAR(opline->op1.var));
+	}
+	FREE_OP(opline->op2_type, opline->op2.var);
+	if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
+		ZVAL_UNDEF(EX_VAR(opline->op2.var));
+	}
+	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FORWARD_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	OPLINE = OP_JMP_ADDR(opline, opline->op1);
+	ZEND_VM_CONTINUE();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_atomic_bool_store_ex(&EG(vm_interrupt), false);
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	/* opline is &call_interrupt_op. Load orig opline. */
+	LOAD_OPLINE();
+#else
+	SAVE_OPLINE();
+#endif
+	if (zend_atomic_bool_load_ex(&EG(timed_out))) {
+		zend_timeout();
+	} else if (zend_interrupt_function) {
+		zend_interrupt_function(execute_data);
+		if (EG(exception)) {
+			/* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */
+			const zend_op *throw_op = EG(opline_before_exception);
+
+			if (throw_op
+			 && throw_op->result_type & (IS_TMP_VAR|IS_VAR)
+			 && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT
+			 && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK
+			 && throw_op->opcode != ZEND_ROPE_INIT
+			 && throw_op->opcode != ZEND_ROPE_ADD) {
+				ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var));
+
+			}
+		}
+		ZEND_VM_ENTER();
+	}
+	ZEND_VM_CONTINUE();
+}
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_function *fbc;
+	zval *function_name, *func;
+	zend_execute_data *call;
+
+	fbc = CACHED_PTR(opline->result.num);
+	if (UNEXPECTED(fbc == NULL)) {
+		function_name = (zval*)RT_CONSTANT(opline, opline->op2);
+		func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(function_name+1));
+		if (UNEXPECTED(func == NULL)) {
+			/* Mangled monomorph name: synthesize on first reference (may throw). */
+			SAVE_OPLINE();
+			fbc = zend_resolve_monomorph_by_name(Z_STR_P(function_name+1));
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+			if (UNEXPECTED(fbc == NULL)) {
+				ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			}
+			CACHE_PTR(opline->result.num, fbc);
+			goto fcall_by_name_push;
+		}
+		fbc = Z_FUNC_P(func);
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		CACHE_PTR(opline->result.num, fbc);
+	}
+fcall_by_name_push:
+	call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+		fbc, opline->extended_value, NULL);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+	function_name = RT_CONSTANT(opline, opline->op2);
+
+try_function_name:
+	if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+		call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value);
+	} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) {
+		call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value);
+	} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) {
+		call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value);
+	} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) {
+		function_name = Z_REFVAL_P(function_name);
+		goto try_function_name;
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+			function_name = ZVAL_UNDEFINED_OP2();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		zend_throw_error(NULL, "Value of type %s is not callable",
+			zend_zval_type_name(function_name));
+		call = NULL;
+	}
+
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+
+
+		if (UNEXPECTED(EG(exception))) {
+			if (call) {
+				 if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				zend_vm_stack_free_call_frame(call);
+			}
+			HANDLE_EXCEPTION();
+		}
+	} else if (!call) {
+		HANDLE_EXCEPTION();
+	}
+
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *func_name;
+	zval *func;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	fbc = CACHED_PTR(opline->result.num);
+	if (UNEXPECTED(fbc == NULL)) {
+		func_name = (zval *)RT_CONSTANT(opline, opline->op2);
+		func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 1));
+		if (func == NULL) {
+			func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 2));
+			if (UNEXPECTED(func == NULL)) {
+				/* Mangled monomorph name: synthesize on first reference (qualified
+				 * then unqualified; may throw). */
+				SAVE_OPLINE();
+				fbc = zend_resolve_monomorph_by_name(Z_STR_P(func_name + 1));
+				if (fbc == NULL && !EG(exception)) {
+					fbc = zend_resolve_monomorph_by_name(Z_STR_P(func_name + 2));
+				}
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+				if (UNEXPECTED(fbc == NULL)) {
+					ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+				}
+				CACHE_PTR(opline->result.num, fbc);
+				goto ns_fcall_by_name_push;
+			}
+		}
+		fbc = Z_FUNC_P(func);
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		CACHE_PTR(opline->result.num, fbc);
+	}
+
+ns_fcall_by_name_push:
+	call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
+		fbc, opline->extended_value, NULL);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *fname;
+	zval *func;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	fbc = CACHED_PTR(opline->result.num);
+	if (UNEXPECTED(fbc == NULL)) {
+		fname = (zval*)RT_CONSTANT(opline, opline->op2);
+		func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(fname));
+		ZEND_ASSERT(func != NULL && "Function existence must be checked at compile time");
+		fbc = Z_FUNC_P(func);
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		CACHE_PTR(opline->result.num, fbc);
+	}
+
+	call = _zend_vm_stack_push_call_frame_ex(
+		opline->op1.num, ZEND_CALL_NESTED_FUNCTION,
+		fbc, opline->extended_value, NULL);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_OFFSET_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_function *fbc;
+	zend_execute_data *call;
+	fbc = CACHED_PTR(opline->result.num);
+	if (UNEXPECTED(fbc == NULL)) {
+		fbc = Z_PTR(EG(function_table)->arData[Z_EXTRA_P(RT_CONSTANT(opline, opline->op2))].val);
+		CACHE_PTR(opline->result.num, fbc);
+	}
+	call = _zend_vm_stack_push_call_frame_ex(
+		opline->op1.num, ZEND_CALL_NESTED_FUNCTION,
+		fbc, opline->extended_value, NULL);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_INIT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	uint32_t arg_num;
+	zval *param;
+
+	ZEND_VM_REPEATABLE_OPCODE
+
+	arg_num = opline->op1.num;
+	param = EX_VAR(opline->result.var);
+	if (arg_num > EX_NUM_ARGS()) {
+		zval *default_value = RT_CONSTANT(opline, opline->op2);
+
+		if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) {
+			zval *cache_val = (zval*)CACHE_ADDR(Z_CACHE_SLOT_P(default_value));
+
+			/* we keep in cache only not refcounted values */
+			if (Z_TYPE_P(cache_val) != IS_UNDEF) {
+				ZVAL_COPY_VALUE(param, cache_val);
+			} else {
+				SAVE_OPLINE();
+				ZVAL_COPY(param, default_value);
+				zend_ast_evaluate_ctx ctx = {0};
+				if (UNEXPECTED(zval_update_constant_with_ctx(param, EX(func)->op_array.scope, &ctx) != SUCCESS)) {
+					zval_ptr_dtor_nogc(param);
+					ZVAL_UNDEF(param);
+					HANDLE_EXCEPTION();
+				}
+				if (!Z_REFCOUNTED_P(param) && !ctx.had_side_effects) {
+					ZVAL_COPY_VALUE(cache_val, param);
+				}
+			}
+			goto recv_init_check_type;
+		} else {
+			ZVAL_COPY(param, default_value);
+		}
+	} else {
+recv_init_check_type:
+		if ((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+	}
+
+	ZEND_VM_REPEAT_OPCODE(ZEND_RECV_INIT);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+	function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+try_function_name:
+	if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+		call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value);
+	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) {
+		call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value);
+	} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) {
+		call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value);
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) {
+		function_name = Z_REFVAL_P(function_name);
+		goto try_function_name;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+			function_name = ZVAL_UNDEFINED_OP2();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		zend_throw_error(NULL, "Value of type %s is not callable",
+			zend_zval_type_name(function_name));
+		call = NULL;
+	}
+
+	if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		if (UNEXPECTED(EG(exception))) {
+			if (call) {
+				 if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				zend_vm_stack_free_call_frame(call);
+			}
+			HANDLE_EXCEPTION();
+		}
+	} else if (!call) {
+		HANDLE_EXCEPTION();
+	}
+
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	uint32_t arg_num = opline->op1.num;
+	zval *param;
+
+	if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
+		ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	param = EX_VAR(opline->result.var);
+
+	if (UNEXPECTED(!(opline->op2.num & (1u << Z_TYPE_P(param))))) {
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param));
+	}
+
+	/* The inline op2.num mask was baked in at the origin's compile time. A
+	 * generic-inheritance clone may carry a tighter substituted arg_info that
+	 * the mask doesn't reflect, so force the slow path when the function is a
+	 * clone with substituted types. */
+	if (UNEXPECTED(EX(func)->common.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
+		ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param));
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_VARIADIC_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	uint32_t arg_num = opline->op1.num;
+	uint32_t arg_count = EX_NUM_ARGS();
+	zval *params;
+
+	SAVE_OPLINE();
+
+	params = EX_VAR(opline->result.var);
+
+	if (arg_num <= arg_count) {
+		ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_VARIADIC);
+		ZEND_ASSERT(EX(func)->common.num_args == arg_num - 1);
+		zend_arg_info *arg_info = &EX(func)->common.arg_info[arg_num - 1];
+
+		array_init_size(params, arg_count - arg_num + 1);
+		zend_hash_real_init_packed(Z_ARRVAL_P(params));
+		ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) {
+			zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
+			if (ZEND_TYPE_IS_SET(arg_info->type)) {
+				ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS);
+				do {
+					if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) {
+						ZEND_HASH_FILL_FINISH();
+						HANDLE_EXCEPTION();
+					}
+
+					if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
+					ZEND_HASH_FILL_ADD(param);
+					param++;
+				} while (++arg_num <= arg_count);
+			} else {
+				do {
+					if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param);
+					ZEND_HASH_FILL_ADD(param);
+					param++;
+				} while (++arg_num <= arg_count);
+			}
+		} ZEND_HASH_FILL_END();
+	} else {
+		ZVAL_EMPTY_ARRAY(params);
+	}
+
+	if (EX_CALL_INFO() & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+		zend_string *name;
+		zval *param;
+		zend_arg_info *arg_info = &EX(func)->common.arg_info[EX(func)->common.num_args];
+		if (ZEND_TYPE_IS_SET(arg_info->type)) {
+			SEPARATE_ARRAY(params);
+			ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) {
+				if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) {
+					HANDLE_EXCEPTION();
+				}
+				Z_TRY_ADDREF_P(param);
+				zend_hash_add_new(Z_ARRVAL_P(params), name, param);
+			} ZEND_HASH_FOREACH_END();
+		} else if (zend_hash_num_elements(Z_ARRVAL_P(params)) == 0) {
+			GC_ADDREF(EX(extra_named_params));
+			ZVAL_ARR(params, EX(extra_named_params));
+		} else {
+			SEPARATE_ARRAY(params);
+			ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) {
+				Z_TRY_ADDREF_P(param);
+				zend_hash_add_new(Z_ARRVAL_P(params), name, param);
+			} ZEND_HASH_FOREACH_END();
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+	zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R);
+	if (EG(exception)) {
+		FREE_OP(opline->op1_type, opline->op1.var);
+		HANDLE_EXCEPTION();
+	}
+
+#if 0 || 0
+	if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_1 function = (zend_frameless_function_1)ZEND_FLF_HANDLER(opline);
+		function(result, arg1);
+	}
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_NULL(result);
+	zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R);
+	if (EG(exception)) {
+		FREE_OP(opline->op1_type, opline->op1.var);
+		HANDLE_EXCEPTION();
+	}
+
+#if 0 || 1
+	if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) {
+		zend_frameless_observed_call(execute_data);
+	} else
+#endif
+	{
+		zend_frameless_function_1 function = (zend_frameless_function_1)ZEND_FLF_HANDLER(opline);
+		function(result, arg1);
+	}
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+	function_name = EX_VAR(opline->op2.var);
+
+try_function_name:
+	if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+		call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value);
+	} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) {
+		call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value);
+	} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) {
+		call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value);
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) {
+		function_name = Z_REFVAL_P(function_name);
+		goto try_function_name;
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+			function_name = ZVAL_UNDEFINED_OP2();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		zend_throw_error(NULL, "Value of type %s is not callable",
+			zend_zval_type_name(function_name));
+		call = NULL;
+	}
+
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+
+
+		if (UNEXPECTED(EG(exception))) {
+			if (call) {
+				 if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+					zend_string_release_ex(call->func->common.function_name, 0);
+					zend_free_trampoline(call->func);
+				}
+				zend_vm_stack_free_call_frame(call);
+			}
+			HANDLE_EXCEPTION();
+		}
+	} else if (!call) {
+		HANDLE_EXCEPTION();
+	}
+
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_NOT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_NOT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+
+	val = RT_CONSTANT(opline, opline->op1);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ECHO_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *z;
+
+	SAVE_OPLINE();
+	z = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_P(z) == IS_STRING) {
+		zend_string *str = Z_STR_P(z);
+
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
+		}
+	} else {
+		zend_string *str = zval_get_string_func(z);
+
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
+		} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		zend_string_release_ex(str, 0);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	uint8_t op1_type;
+
+	val = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	SAVE_OPLINE();
+	op1_type = IS_CONST;
+	if (i_zend_is_true(val)) {
+		opline++;
+	} else {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	uint8_t op1_type;
+
+	val = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	op1_type = IS_CONST;
+	if (i_zend_is_true(val)) {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		opline++;
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_EX_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	bool ret;
+
+	val = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	SAVE_OPLINE();
+	ret = i_zend_is_true(val);
+
+
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline++;
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_EX_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	bool ret;
+
+	val = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	SAVE_OPLINE();
+	ret = i_zend_is_true(val);
+
+
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline++;
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+
+
+	retval_ptr = RT_CONSTANT(opline, opline->op1);
+	return_value = EX(return_value);
+
+
+	if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		retval_ptr = ZVAL_UNDEFINED_OP1();
+		if (return_value) {
+			ZVAL_NULL(return_value);
+		}
+	} else if (!return_value) {
+		if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
+				SAVE_OPLINE();
+				rc_dtor_func(Z_COUNTED_P(retval_ptr));
+			}
+		}
+	} else {
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZVAL_COPY_VALUE(return_value, retval_ptr);
+			if (IS_CONST == IS_CONST) {
+				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+					Z_ADDREF_P(return_value);
+				}
+			}
+		} else if (IS_CONST == IS_CV) {
+			do {
+				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
+							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+							ZVAL_COPY_VALUE(return_value, retval_ptr);
+							if (GC_MAY_LEAK(ref)) {
+								SAVE_OPLINE();
+								gc_possible_root(ref);
+							}
+							ZVAL_NULL(retval_ptr);
+							break;
+						} else {
+							Z_ADDREF_P(retval_ptr);
+						}
+					} else {
+						retval_ptr = Z_REFVAL_P(retval_ptr);
+						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+							Z_ADDREF_P(retval_ptr);
+						}
+					}
+				}
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			} while (0);
+		} else /* if (IS_CONST == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+				retval_ptr = Z_REFVAL_P(retval_ptr);
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					Z_ADDREF_P(retval_ptr);
+				}
+			} else {
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			}
+		}
+	}
+
+
+
+
+
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+	zval observer_retval;
+
+	retval_ptr = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R);
+	return_value = EX(return_value);
+	if (!return_value) { return_value = &observer_retval; };
+	if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		retval_ptr = ZVAL_UNDEFINED_OP1();
+		if (return_value) {
+			ZVAL_NULL(return_value);
+		}
+	} else if (!return_value) {
+		if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
+			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
+				SAVE_OPLINE();
+				rc_dtor_func(Z_COUNTED_P(retval_ptr));
+			}
+		}
+	} else {
+		if ((opline->op1_type & (IS_CONST|IS_TMP_VAR))) {
+			ZVAL_COPY_VALUE(return_value, retval_ptr);
+			if (opline->op1_type == IS_CONST) {
+				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+					Z_ADDREF_P(return_value);
+				}
+			}
+		} else if (opline->op1_type == IS_CV) {
+			do {
+				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
+							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+							ZVAL_COPY_VALUE(return_value, retval_ptr);
+							if (GC_MAY_LEAK(ref)) {
+								SAVE_OPLINE();
+								gc_possible_root(ref);
+							}
+							ZVAL_NULL(retval_ptr);
+							break;
+						} else {
+							Z_ADDREF_P(retval_ptr);
+						}
+					} else {
+						retval_ptr = Z_REFVAL_P(retval_ptr);
+						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+							Z_ADDREF_P(retval_ptr);
+						}
+					}
+				}
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			} while (0);
+		} else /* if (opline->op1_type == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+				retval_ptr = Z_REFVAL_P(retval_ptr);
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					Z_ADDREF_P(retval_ptr);
+				}
+			} else {
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			}
+		}
+	}
+	SAVE_OPLINE();
+	zend_observer_fcall_end(execute_data, return_value);
+	if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); };
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+
+
+	SAVE_OPLINE();
+
+	return_value = EX(return_value);
+
+
+	do {
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR)) ||
+		    (IS_CONST == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
+			/* Not supposed to happen, but we'll allow it */
+			zend_error(E_NOTICE, "Only variable references should be returned by reference");
+
+			retval_ptr = RT_CONSTANT(opline, opline->op1);
+			if (!return_value) {
+
+
+			} else {
+				if (IS_CONST == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+					ZVAL_COPY_VALUE(return_value, retval_ptr);
+					break;
+				}
+
+				ZVAL_NEW_REF(return_value, retval_ptr);
+				if (IS_CONST == IS_CONST) {
+					Z_TRY_ADDREF_P(retval_ptr);
+				}
+			}
+			break;
+		}
+
+		retval_ptr = zend_get_bad_ptr();
+
+		if (IS_CONST == IS_VAR) {
+			ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
+			if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
+				zend_error(E_NOTICE, "Only variable references should be returned by reference");
+				if (return_value) {
+					ZVAL_NEW_REF(return_value, retval_ptr);
+				} else {
+
+
+				}
+				break;
+			}
+		}
+
+		if (return_value) {
+			if (Z_ISREF_P(retval_ptr)) {
+				Z_ADDREF_P(retval_ptr);
+			} else {
+				ZVAL_MAKE_REF_EX(retval_ptr, 2);
+			}
+			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
+		}
+
+
+	} while (0);
+
+
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+	zval observer_retval;
+
+	SAVE_OPLINE();
+
+	return_value = EX(return_value);
+	if (!return_value) { return_value = &observer_retval; };
+	do {
+		if ((opline->op1_type & (IS_CONST|IS_TMP_VAR)) ||
+		    (opline->op1_type == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
+			/* Not supposed to happen, but we'll allow it */
+			zend_error(E_NOTICE, "Only variable references should be returned by reference");
+
+			retval_ptr = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
+			if (!return_value) {
+				FREE_OP(opline->op1_type, opline->op1.var);
+			} else {
+				if (opline->op1_type == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+					ZVAL_COPY_VALUE(return_value, retval_ptr);
+					break;
+				}
+
+				ZVAL_NEW_REF(return_value, retval_ptr);
+				if (opline->op1_type == IS_CONST) {
+					Z_TRY_ADDREF_P(retval_ptr);
+				}
+			}
+			break;
+		}
+
+		retval_ptr = get_zval_ptr_ptr(opline->op1_type, opline->op1, BP_VAR_W);
+
+		if (opline->op1_type == IS_VAR) {
+			ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
+			if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
+				zend_error(E_NOTICE, "Only variable references should be returned by reference");
+				if (return_value) {
+					ZVAL_NEW_REF(return_value, retval_ptr);
+				} else {
+					FREE_OP(opline->op1_type, opline->op1.var);
+				}
+				break;
+			}
+		}
+
+		if (return_value) {
+			if (Z_ISREF_P(retval_ptr)) {
+				Z_ADDREF_P(retval_ptr);
+			} else {
+				ZVAL_MAKE_REF_EX(retval_ptr, 2);
+			}
+			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
+		}
+
+		FREE_OP(opline->op1_type, opline->op1.var);
+	} while (0);
+
+	zend_observer_fcall_end(execute_data, return_value);
+	if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); };
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval;
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	retval = RT_CONSTANT(opline, opline->op1);
+
+	/* Copy return value into generator->retval */
+	if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+		ZVAL_COPY_VALUE(&generator->retval, retval);
+		if (IS_CONST == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
+				Z_ADDREF(generator->retval);
+			}
+		}
+	} else if (IS_CONST == IS_CV) {
+		ZVAL_COPY_DEREF(&generator->retval, retval);
+	} else /* if (IS_CONST == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_refcounted *ref = Z_COUNTED_P(retval);
+
+			retval = Z_REFVAL_P(retval);
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(retval)) {
+				Z_ADDREF_P(retval);
+			}
+		} else {
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+		}
+	}
+
+
+	EG(current_execute_data) = EX(prev_execute_data);
+
+	/* Close the generator to free up resources */
+	zend_generator_close(generator, 1);
+
+	/* Pass execution back to handling code */
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval;
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	retval = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
+
+	/* Copy return value into generator->retval */
+	if ((opline->op1_type & (IS_CONST|IS_TMP_VAR))) {
+		ZVAL_COPY_VALUE(&generator->retval, retval);
+		if (opline->op1_type == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
+				Z_ADDREF(generator->retval);
+			}
+		}
+	} else if (opline->op1_type == IS_CV) {
+		ZVAL_COPY_DEREF(&generator->retval, retval);
+	} else /* if (opline->op1_type == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_refcounted *ref = Z_COUNTED_P(retval);
+
+			retval = Z_REFVAL_P(retval);
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(retval)) {
+				Z_ADDREF_P(retval);
+			}
+		} else {
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+		}
+	}
+
+	zend_observer_fcall_end(generator->execute_data, &generator->retval);
+
+	EG(current_execute_data) = EX(prev_execute_data);
+
+	/* Close the generator to free up resources */
+	zend_generator_close(generator, 1);
+
+	/* Pass execution back to handling code */
+	ZEND_VM_RETURN();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op1);
+
+	do {
+		if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+				if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Can only throw objects");
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	Z_TRY_ADDREF_P(value);
+	zend_throw_exception_object(value);
+
+
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CATCH_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_class_entry *ce, *catch_ce;
+	zend_object *exception;
+
+	SAVE_OPLINE();
+	/* Check whether an exception has been thrown, if not, jump over code */
+	if (EG(exception) == NULL) {
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+	if (IS_CONST == IS_UNUSED) {
+		/* catch (T $e) / catch (Box $e): polymorphic inline cache keyed on
+		 * (type_args generation, called_scope). The generation is a monotonic
+		 * nonce per zend_type_arg_table allocation, so it's ABA-safe across
+		 * calls that reuse the same heap address. NULL type_args maps to
+		 * generation 0 (the counter starts at 1). zend_fetch_class dispatches
+		 * to the right resolver based on the packed sub-type on miss. */
+		void **slot = CACHE_ADDR(opline->extended_value & ~ZEND_LAST_CATCH);
+		uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+		zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+		/* slot[2] != NULL distinguishes a populated entry from an
+		 * uninitialized (all-zeros) slot, which otherwise matches
+		 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+		if (EXPECTED(slot[2] != NULL
+				&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+			catch_ce = (zend_class_entry*)slot[2];
+		} else {
+			catch_ce = zend_fetch_class(NULL,
+				opline->op1.num | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+			if (EXPECTED(catch_ce)) {
+				slot[0] = (void*)cur_gen;
+				slot[1] = (void*)cur_scope;
+				slot[2] = (void*)catch_ce;
+			}
+		}
+	} else {
+		catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
+		if (UNEXPECTED(catch_ce == NULL)) {
+			catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+
+			CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
+		}
+	}
+	ce = EG(exception)->ce;
+
+#ifdef HAVE_DTRACE
+	if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
+		DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
+	}
+#endif /* HAVE_DTRACE */
+
+	if (ce != catch_ce) {
+		if (!catch_ce || !instanceof_function(ce, catch_ce)) {
+			if (opline->extended_value & ZEND_LAST_CATCH) {
+				zend_rethrow_exception(execute_data);
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+		}
+	}
+
+	exception = EG(exception);
+	EG(exception) = NULL;
+	if (RETURN_VALUE_USED(opline)) {
+		/* Always perform a strict assignment. There is a reasonable expectation that if you
+		 * write "catch (Exception $e)" then $e will actually be instanceof Exception. As such,
+		 * we should not permit coercion to string here. */
+		zval tmp;
+		ZVAL_OBJ(&tmp, exception);
+		zend_assign_to_variable(EX_VAR(opline->result.var), &tmp, IS_TMP_VAR, /* strict */ 1);
+	} else {
+		OBJ_RELEASE(exception);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *arg, *param;
+
+	SAVE_OPLINE();
+
+	arg = RT_CONSTANT(opline, opline->op1);
+	param = ZEND_CALL_VAR(EX(call), opline->result.var);
+	if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
+		zend_param_must_be_ref(EX(call)->func, opline->op2.num);
+		Z_TRY_ADDREF_P(arg);
+		ZVAL_NEW_REF(param, arg);
+	} else {
+		ZVAL_COPY(param, arg);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+
+	val = RT_CONSTANT(opline, opline->op1);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *obj;
+	zend_object *zobj;
+	zend_class_entry *ce, *scope;
+	zend_function *clone;
+	zend_object_clone_obj_t clone_call;
+
+	SAVE_OPLINE();
+	obj = RT_CONSTANT(opline, opline->op1);
+
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
+	do {
+		if (IS_CONST == IS_CONST ||
+		    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
+				obj = Z_REFVAL_P(obj);
+				if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
+					break;
+				}
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	zobj = Z_OBJ_P(obj);
+	ce = zobj->ce;
+	clone = ce->clone;
+	clone_call = zobj->handlers->clone_obj;
+	if (UNEXPECTED(clone_call == NULL)) {
+		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
+
+
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+		scope = EX(func)->op_array.scope;
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
+
+
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	zval *result = EX_VAR(opline->result.var);
+
+	SAVE_OPLINE();
+	expr = RT_CONSTANT(opline, opline->op1);
+
+	switch (opline->extended_value) {
+		case IS_LONG:
+			ZVAL_LONG(result, zval_get_long(expr));
+			break;
+		case IS_DOUBLE:
+			ZVAL_DOUBLE(result, zval_get_double(expr));
+			break;
+		case IS_STRING:
+			ZVAL_STR(result, zval_get_string(expr));
+			break;
+		default:
+			ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead");
+			if (IS_CONST & (IS_VAR|IS_CV)) {
+				ZVAL_DEREF(expr);
+			}
+			/* If value is already of correct type, return it directly */
+			if (Z_TYPE_P(expr) == opline->extended_value) {
+				ZVAL_COPY_VALUE(result, expr);
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+				} else if (IS_CONST != IS_TMP_VAR) {
+					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+				}
+
+
+				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+			}
+
+			if (opline->extended_value == IS_ARRAY) {
+				zend_cast_zval_to_array(result, expr, IS_CONST);
+			} else {
+				ZEND_ASSERT(opline->extended_value == IS_OBJECT);
+				zend_cast_zval_to_object(result, expr, IS_CONST);
+			}
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_op_array *new_op_array;
+	zval *inc_filename;
+
+	SAVE_OPLINE();
+	inc_filename = RT_CONSTANT(opline, opline->op1);
+	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
+			destroy_op_array(new_op_array);
+			efree_size(new_op_array, sizeof(zend_op_array));
+		}
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	} else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_TRUE(EX_VAR(opline->result.var));
+		}
+	} else if (UNEXPECTED(new_op_array == NULL)) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_FALSE(EX_VAR(opline->result.var));
+		}
+	} else if (new_op_array->last == 1
+			&& new_op_array->opcodes[0].opcode == ZEND_RETURN
+			&& new_op_array->opcodes[0].op1_type == IS_CONST
+			&& EXPECTED(zend_execute_ex == execute_ex)) {
+		if (RETURN_VALUE_USED(opline)) {
+			const zend_op *op = new_op_array->opcodes;
+
+			ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1));
+		}
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+	} else {
+		zval *return_value = NULL;
+		zend_execute_data *call;
+		if (RETURN_VALUE_USED(opline)) {
+			return_value = EX_VAR(opline->result.var);
+		}
+
+		new_op_array->scope = EX(func)->op_array.scope;
+
+		call = zend_vm_stack_push_call_frame(
+			(Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+			(zend_function*)new_op_array, 0,
+			Z_PTR(EX(This)));
+
+		if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
+			call->symbol_table = EX(symbol_table);
+		} else {
+			call->symbol_table = zend_rebuild_symbol_table();
+		}
+
+		call->prev_execute_data = execute_data;
+		i_init_code_execute_data(call, new_op_array, return_value);
+
+
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+
+
+			ZEND_VM_ENTER();
+		} else {
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+			zend_vm_stack_free_call_frame(call);
+		}
+
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+
+
+			UNDEF_RESULT();
+			HANDLE_EXCEPTION();
+		}
+	}
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_op_array *new_op_array;
+	zval *inc_filename;
+
+	SAVE_OPLINE();
+	inc_filename = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
+	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		FREE_OP(opline->op1_type, opline->op1.var);
+		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
+			destroy_op_array(new_op_array);
+			efree_size(new_op_array, sizeof(zend_op_array));
+		}
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	} else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_TRUE(EX_VAR(opline->result.var));
+		}
+	} else if (UNEXPECTED(new_op_array == NULL)) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_FALSE(EX_VAR(opline->result.var));
+		}
+	} else if (new_op_array->last == 1
+			&& new_op_array->opcodes[0].opcode == ZEND_RETURN
+			&& new_op_array->opcodes[0].op1_type == IS_CONST
+			&& EXPECTED(zend_execute_ex == execute_ex)) {
+		if (RETURN_VALUE_USED(opline)) {
+			const zend_op *op = new_op_array->opcodes;
+
+			ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1));
+		}
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+	} else {
+		zval *return_value = NULL;
+		zend_execute_data *call;
+		if (RETURN_VALUE_USED(opline)) {
+			return_value = EX_VAR(opline->result.var);
+		}
+
+		new_op_array->scope = EX(func)->op_array.scope;
+
+		call = zend_vm_stack_push_call_frame(
+			(Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+			(zend_function*)new_op_array, 0,
+			Z_PTR(EX(This)));
+
+		if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
+			call->symbol_table = EX(symbol_table);
+		} else {
+			call->symbol_table = zend_rebuild_symbol_table();
+		}
+
+		call->prev_execute_data = execute_data;
+		i_init_code_execute_data(call, new_op_array, return_value);
+		zend_observer_fcall_begin_specialized(call, false);
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			FREE_OP(opline->op1_type, opline->op1.var);
+			ZEND_VM_ENTER();
+		} else {
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+			zend_vm_stack_free_call_frame(call);
+		}
+
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+			FREE_OP(opline->op1_type, opline->op1.var);
+			UNDEF_RESULT();
+			HANDLE_EXCEPTION();
+		}
+	}
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *result;
+
+	SAVE_OPLINE();
+
+	array_ptr = RT_CONSTANT(opline, opline->op1);
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, array_ptr);
+		if (IS_CONST != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+			Z_ADDREF_P(array_ptr);
+		}
+		Z_FE_POS_P(result) = 0;
+
+
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		zend_object *zobj = Z_OBJ_P(array_ptr);
+		if (!zobj->ce->get_iterator) {
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			HashTable *properties = zobj->properties;
+			if (properties) {
+				if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+					if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+						GC_DELREF(properties);
+					}
+					properties = zobj->properties = zend_array_dup(properties);
+				}
+			} else {
+				properties = zobj->handlers->get_properties(zobj);
+			}
+
+			result = EX_VAR(opline->result.var);
+			ZVAL_COPY_VALUE(result, array_ptr);
+			if (IS_CONST != IS_TMP_VAR) {
+				Z_ADDREF_P(array_ptr);
+			}
+
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(result) = (uint32_t) -1;
+
+
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
+
+			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+
+
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *array_ref;
+
+	SAVE_OPLINE();
+
+	if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
+		array_ref = array_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(array_ref)) {
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+	} else {
+		array_ref = array_ptr = RT_CONSTANT(opline, opline->op1);
+	}
+
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
+			if (array_ptr == array_ref) {
+				ZVAL_NEW_REF(array_ref, array_ref);
+				array_ptr = Z_REFVAL_P(array_ref);
+			}
+			Z_ADDREF_P(array_ref);
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+		} else {
+			array_ref = EX_VAR(opline->result.var);
+			ZVAL_NEW_REF(array_ref, array_ptr);
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+		if (IS_CONST == IS_CONST) {
+			ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr)));
+		} else {
+			SEPARATE_ARRAY(array_ptr);
+		}
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
+
+
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+			zend_object *zobj = Z_OBJ_P(array_ptr);
+			HashTable *properties;
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
+				if (array_ptr == array_ref) {
+					ZVAL_NEW_REF(array_ref, array_ref);
+					array_ptr = Z_REFVAL_P(array_ref);
+				}
+				Z_ADDREF_P(array_ref);
+				ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+			} else {
+				array_ptr = EX_VAR(opline->result.var);
+				ZVAL_COPY_VALUE(array_ptr, array_ref);
+			}
+			if (Z_OBJ_P(array_ptr)->properties
+			 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
+				if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
+					GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+				}
+				Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+			}
+
+			properties = Z_OBJPROP_P(array_ptr);
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
+
+
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
+
+			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
+
+
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+
+
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zend_reference *ref = NULL;
+	bool ret;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op1);
+
+	if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) {
+		if (IS_CONST == IS_VAR) {
+			ref = Z_REF_P(value);
+		}
+		value = Z_REFVAL_P(value);
+	}
+
+	ret = i_zend_is_true(value);
+
+	if (UNEXPECTED(EG(exception))) {
+
+
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (ret) {
+		zval *result = EX_VAR(opline->result.var);
+
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_CONST == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_CONST == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if (IS_CONST == IS_VAR && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zend_reference *ref = NULL;
+
+	SAVE_OPLINE();
+	value = RT_CONSTANT(opline, opline->op1);
+
+	if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+		if (IS_CONST & IS_VAR) {
+			ref = Z_REF_P(value);
+		}
+		value = Z_REFVAL_P(value);
+	}
+
+	if (Z_TYPE_P(value) > IS_NULL) {
+		zval *result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_CONST == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_CONST == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if ((IS_CONST & IS_VAR) && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	if ((IS_CONST & IS_VAR) && ref) {
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val, *result;
+
+	val = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_P(val) > IS_NULL) {
+		do {
+			if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) {
+				val = Z_REFVAL_P(val);
+				if (Z_TYPE_P(val) <= IS_NULL) {
+
+
+					break;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		} while (0);
+	}
+
+	result = EX_VAR(opline->result.var);
+	uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK;
+	if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) {
+		ZVAL_NULL(result);
+		if (IS_CONST == IS_CV
+			&& UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)
+			&& (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0
+		) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+	} else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) {
+		ZVAL_FALSE(result);
+	} else {
+		ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY);
+		ZVAL_TRUE(result);
+	}
+
+	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *result = EX_VAR(opline->result.var);
+
+	value = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(result);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_CONST == IS_CV) {
+		ZVAL_COPY_DEREF(result, value);
+	} else if (IS_CONST == IS_VAR) {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			ZVAL_COPY_VALUE(result, Z_REFVAL_P(value));
+			if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
+				efree_size(Z_REF_P(value), sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		} else {
+			ZVAL_COPY_VALUE(result, value);
+		}
+	} else {
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_CONST == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) {
+				Z_ADDREF_P(result);
+			}
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CLASS_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	do_bind_class(RT_CONSTANT(opline, opline->op1), (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_function *func;
+	zval *object;
+	zend_class_entry *called_scope;
+
+	func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num];
+	if (Z_TYPE(EX(This)) == IS_OBJECT) {
+		called_scope = Z_OBJCE(EX(This));
+		if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) ||
+				(EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
+			object = NULL;
+		} else {
+			object = &EX(This);
+		}
+	} else {
+		called_scope = Z_CE(EX(This));
+		object = NULL;
+	}
+	SAVE_OPLINE();
+	zend_create_closure(EX_VAR(opline->result.var), func,
+		EX(func)->op_array.scope, called_scope, object);
+
+	/* If we're inside a generic frame, snapshot its T-table onto the new
+	 * closure so the closure body resolves outer T-refs against the
+	 * binding in effect at lambda-declaration time. */
+	if (UNEXPECTED(EX(type_args) != NULL)) {
+		zend_closure_capture_type_args(EX_VAR(opline->result.var), EX(type_args));
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+	zval *val;
+
+	SAVE_OPLINE();
+	val = RT_CONSTANT(opline, opline->op1);
+
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+
+
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+yield_from_try_again:
+	if (Z_TYPE_P(val) == IS_ARRAY) {
+		ZVAL_COPY_VALUE(&generator->values, val);
+		if (Z_OPT_REFCOUNTED_P(val)) {
+			Z_ADDREF_P(val);
+		}
+		Z_FE_POS(generator->values) = 0;
+
+
+	} else if (IS_CONST != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
+		zend_class_entry *ce = Z_OBJCE_P(val);
+		if (ce == zend_ce_generator) {
+			zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val);
+
+			Z_ADDREF_P(val);
+
+
+			if (UNEXPECTED(new_gen->execute_data == NULL)) {
+				zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
+				zval_ptr_dtor(val);
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			} else if (Z_ISUNDEF(new_gen->retval)) {
+				if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) {
+					zend_throw_error(NULL, "Impossible to yield from the Generator being currently run");
+					zval_ptr_dtor(val);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				} else {
+					zend_generator_yield_from(generator, new_gen);
+				}
+			} else {
+				if (RETURN_VALUE_USED(opline)) {
+					ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval);
+				}
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else {
+			zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
+
+
+			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+				if (!EG(exception)) {
+					zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
+				}
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			}
+
+			iter->index = 0;
+			if (iter->funcs->rewind) {
+				iter->funcs->rewind(iter);
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					OBJ_RELEASE(&iter->std);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			ZVAL_OBJ(&generator->values, &iter->std);
+		}
+	} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) {
+		val = Z_REFVAL_P(val);
+		goto yield_from_try_again;
+	} else {
+		zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
+
+
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	/* This is the default return value
+	 * when the expression is a Generator, it will be overwritten in zend_generator_resume() */
+	if (RETURN_VALUE_USED(opline)) {
+		ZVAL_NULL(EX_VAR(opline->result.var));
+	}
+
+	/* This generator has no send target (though the generator we delegate to might have one) */
+	generator->send_target = NULL;
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = RT_CONSTANT(opline, opline->op1);
+	if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+		if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(value);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		bool strict;
+
+		if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
+			value = Z_REFVAL_P(value);
+			if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+				ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+
+
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		SAVE_OPLINE();
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+			value = ZVAL_UNDEFINED_OP1();
+		}
+		strict = EX_USES_STRICT_TYPES();
+		do {
+			if (EXPECTED(!strict)) {
+				zend_string *str;
+				zval tmp;
+
+				if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+					zend_error(E_DEPRECATED,
+						"strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+					ZVAL_LONG(EX_VAR(opline->result.var), 0);
+					if (UNEXPECTED(EG(exception))) {
+						HANDLE_EXCEPTION();
+					}
+					break;
+				}
+
+				ZVAL_COPY(&tmp, value);
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
+					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
+					zval_ptr_dtor(&tmp);
+					break;
+				}
+				zval_ptr_dtor(&tmp);
+			}
+			if (!EG(exception)) {
+				zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value));
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+		} while (0);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_CHECK_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	int result = 0;
+
+	value = RT_CONSTANT(opline, opline->op1);
+	if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+type_check_resource:
+		if (opline->extended_value != MAY_BE_RESOURCE
+		 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
+			result = 1;
+		}
+	} else if ((IS_CONST & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) {
+		value = Z_REFVAL_P(value);
+		if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+			goto type_check_resource;
+		}
+	} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		result = ((1 << IS_NULL) & opline->extended_value) != 0;
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		if (UNEXPECTED(EG(exception))) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+	if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+		SAVE_OPLINE();
+
+
+		ZEND_VM_SMART_BRANCH(result, 1);
+	} else {
+		ZEND_VM_SMART_BRANCH(result, 0);
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_ASSERT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zval *value = get_zval_ptr_undef(opline->op2_type, opline->op2, BP_VAR_R);
+
+	uint8_t actual_type = Z_TYPE_P(value);
+	uint8_t expected_type = opline->extended_value & 0xff;
+	/* Simple types can be checked directly. */
+	if (UNEXPECTED(actual_type != expected_type)) {
+		zend_function *fbc;
+		{
+			zval *fname = (zval*)RT_CONSTANT(opline, opline->op1);
+			ZEND_ASSERT(Z_EXTRA_P(fname) != 0);
+			fbc = Z_FUNC(EG(function_table)->arData[Z_EXTRA_P(fname)].val);
+			ZEND_ASSERT(fbc->type != ZEND_USER_FUNCTION);
+		}
+		uint16_t argno = opline->extended_value >> 16;
+		zend_arg_info *arginfo = &fbc->common.arg_info[argno - 1];
+
+		if (!zend_check_type(&arginfo->type, value, /* is_return_type */ false, /* is_internal */ true)) {
+			const char *param_name = get_function_arg_name(fbc, argno);
+			zend_string *expected = zend_type_to_string(arginfo->type);
+			zend_type_error("%s(): Argument #%d%s%s%s must be of type %s, %s given", ZSTR_VAL(fbc->common.function_name), argno, param_name ? " ($" : "", param_name ? param_name : "", param_name ? ")" : "", ZSTR_VAL(expected), zend_zval_value_name(value));
+			zend_string_release(expected);
+		}
+	}
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DEFINED_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_constant *c;
+
+	c = CACHED_PTR(opline->extended_value);
+	if (EXPECTED(c != NULL)) {
+		if (!IS_SPECIAL_CACHE_VAL(c)) {
+defined_true:
+			ZEND_VM_SMART_BRANCH_TRUE();
+		} else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) {
+defined_false:
+			ZEND_VM_SMART_BRANCH_FALSE();
+		}
+	}
+	if (zend_quick_check_constant(RT_CONSTANT(opline, opline->op1) OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) {
+		CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
+		goto defined_false;
+	} else {
+		goto defined_true;
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FRAMELESS_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_jmp_fl_result result = (uintptr_t)CACHED_PTR(opline->extended_value);
+try_again:
+	if (EXPECTED(result == ZEND_JMP_FL_HIT)) {
+		OPLINE = OP_JMP_ADDR(opline, opline->op2);
+		ZEND_VM_CONTINUE();
+	} else if (EXPECTED(result == ZEND_JMP_FL_MISS)) {
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		ZEND_ASSERT(result == ZEND_JMP_FL_UNPRIMED);
+		/* func_name refers to the function in the local namespace, e.g. foo\substr. */
+		zval *func_name = (zval *)RT_CONSTANT(opline, opline->op1);
+		/* If it cannot be found locally, we must be referring to the global function. */
+		zval *func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name));
+		/* ZEND_JMP_FL_MISS = 1, ZEND_JMP_FL_HIT = 2 */
+		result = (func == NULL) + 1;
+		CACHE_PTR(opline->extended_value, (void *)result);
+		goto try_again;
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_LONG_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(value));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SIMPLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+
+	value = RT_CONSTANT(opline, opline->op1);
+	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	ZVAL_COPY_VALUE(arg, value);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num = opline->op2.num;
+
+	arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_COPY_VALUE(arg, value);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_add_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto add_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+add_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 + d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto add_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_sub_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto sub_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+sub_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 - d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto sub_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			zend_long overflow;
+
+			result = EX_VAR(opline->result.var);
+			ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+			Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto mul_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+mul_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 * d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto mul_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+				ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+				/* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+				ZVAL_LONG(result, 0);
+			} else {
+				ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+		ZVAL_LONG(EX_VAR(opline->result.var),
+			(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_not_identical_function(op1, op2);
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = RT_CONSTANT(opline, opline->op2);
+	if (IS_CONST != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_CONST & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_CONST & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_CONST == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CONST == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_CONST != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CONST != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = RT_CONSTANT(opline, opline->op1);
+
+	if (IS_CONST != IS_CONST) {
+		function_name = RT_CONSTANT(opline, opline->op2);
+	}
+
+	if (IS_CONST != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_CONST == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_CONST & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CONST != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CONST == IS_CONST) {
+					function_name = RT_CONSTANT(opline, opline->op2);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CONST == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CONST == IS_CONST) {
+			function_name = RT_CONSTANT(opline, opline->op2);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CONST == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CONST != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_CONST == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_CONST == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_CONST != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_CONST == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_CONST == IS_CONST &&
+	    IS_CONST == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_CONST != IS_CONST &&
+	           IS_CONST == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_CONST != IS_UNUSED) {
+		function_name = RT_CONSTANT(opline, opline->op2);
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CONST == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_CONST != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_CONST == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_fcall_info_cache fcc;
+	char *error = NULL;
+	zend_function *func;
+	void *object_or_called_scope;
+	zend_execute_data *call;
+	uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
+
+	SAVE_OPLINE();
+	function_name = RT_CONSTANT(opline, opline->op2);
+	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
+		ZEND_ASSERT(!error);
+
+		/* Deprecation can be emitted from zend_is_callable_ex(), which can
+		 * invoke a user error handler and throw an exception.
+		 * For the CONST and CV case we reuse the same exception block below
+		 * to make sure we don't increase VM size too much. */
+		if (!(IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+
+
+			HANDLE_EXCEPTION();
+		}
+
+		func = fcc.function_handler;
+		object_or_called_scope = fcc.called_scope;
+		if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
+			/* Delay closure destruction until its invocation */
+			GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+			call_info |= ZEND_CALL_CLOSURE;
+			if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+				call_info |= ZEND_CALL_FAKE_CLOSURE;
+			}
+			if (fcc.object) {
+				object_or_called_scope = fcc.object;
+				call_info |= ZEND_CALL_HAS_THIS;
+			}
+		} else if (fcc.object) {
+			GC_ADDREF(fcc.object); /* For $this pointer */
+			object_or_called_scope = fcc.object;
+			call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
+		}
+
+
+		if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+			if (call_info & ZEND_CALL_CLOSURE) {
+				zend_object_release(ZEND_CLOSURE_OBJECT(func));
+			} else if (call_info & ZEND_CALL_RELEASE_THIS) {
+				zend_object_release(fcc.object);
+			}
+			HANDLE_EXCEPTION();
+		}
+
+		if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
+			init_func_run_time_cache(&func->op_array);
+		}
+	} else {
+		zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error);
+		efree(error);
+
+
+		HANDLE_EXCEPTION();
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		func, opline->extended_value, object_or_called_scope);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_CONST == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_val_by_ref;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_CONST == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_class_entry *ce, *scope;
+	zend_class_constant *c;
+	zval *value, *zv, *constant_zv;
+	zend_string *constant_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+
+	do {
+		if (IS_CONST == IS_CONST && IS_CONST == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) {
+				value = CACHED_PTR(opline->extended_value + sizeof(void*));
+				break;
+			}
+		}
+		if (IS_CONST == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value))) {
+				ce = CACHED_PTR(opline->extended_value);
+			} else {
+				ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+				if (UNEXPECTED(ce == NULL)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+				CACHE_PTR(opline->extended_value, ce);
+			}
+		} else if (IS_CONST == IS_UNUSED) {
+			ce = zend_fetch_class(NULL, opline->op1.num);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op1.var));
+		}
+		if (IS_CONST != IS_CONST
+			&& IS_CONST == IS_CONST
+			&& EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
+			value = CACHED_PTR(opline->extended_value + sizeof(void*));
+			break;
+		}
+
+		constant_zv = RT_CONSTANT(opline, opline->op2);
+		if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
+			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+			HANDLE_EXCEPTION();
+		}
+		constant_name = Z_STR_P(constant_zv);
+		/* Magic 'class' for constant OP2 is caught at compile-time */
+		if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
+
+
+			ZEND_VM_NEXT_OPCODE();
+		}
+		zv = IS_CONST == IS_CONST
+			? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name)
+			: zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name);
+
+		if (EXPECTED(zv != NULL)) {
+			c = Z_PTR_P(zv);
+			scope = EX(func)->op_array.scope;
+			if (!zend_verify_const_access(c, scope)) {
+				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+
+			if (ce->ce_flags & ZEND_ACC_TRAIT) {
+				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+
+			bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
+			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
+				if (c->ce->type == ZEND_USER_CLASS) {
+					/* Recursion protection only applied to user constants, GH-18463 */
+					CONST_PROTECT_RECURSION(c);
+				}
+				zend_deprecated_class_constant(c, constant_name);
+				if (c->ce->type == ZEND_USER_CLASS) {
+					CONST_UNPROTECT_RECURSION(c);
+				}
+
+				if (EG(exception)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			value = &c->value;
+			// Enums require loading of all class constants to build the backed enum table
+			if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
+				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (IS_CONST == IS_CONST && !is_constant_deprecated) {
+				CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
+			}
+		} else {
+			zend_throw_error(NULL, "Undefined constant %s::%s",
+				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+
+
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
+
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = RT_CONSTANT(opline, opline->op1);
+		if (IS_CONST == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CONST == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CONST == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CONST == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CONST != IS_UNUSED) {
+		zval *offset = RT_CONSTANT(opline, opline->op2);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CONST != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_CONST & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	offset = RT_CONSTANT(opline, opline->op2);
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CONST == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = RT_CONSTANT(opline, opline->op1);
+	subject = RT_CONSTANT(opline, opline->op2);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_class_entry *ce = CACHED_PTR(opline->extended_value);
+	if (ce == NULL) {
+		zval *lcname = RT_CONSTANT(opline, opline->op1);
+		zval *zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
+		if (zv) {
+			SAVE_OPLINE();
+			ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2)));
+			if (EG(exception)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		CACHE_PTR(opline->extended_value, ce);
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *name;
+	zval *val;
+	zend_constant c;
+
+	SAVE_OPLINE();
+	name  = RT_CONSTANT(opline, opline->op1);
+	val   = RT_CONSTANT(opline, opline->op2);
+
+	ZVAL_COPY(&c.value, val);
+	if (Z_OPT_CONSTANT(c.value)) {
+		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
+			zval_ptr_dtor_nogc(&c.value);
+
+
+
+
+			HANDLE_EXCEPTION();
+		}
+	}
+	/* non persistent, case sensitive */
+	ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
+	c.name = zend_string_copy(Z_STR_P(name));
+
+	if (zend_register_constant(&c) == NULL) {
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *name;
+	zval *val;
+	zend_constant c, *registered;
+
+	SAVE_OPLINE();
+	name  = RT_CONSTANT(opline, opline->op1);
+	val   = RT_CONSTANT(opline, opline->op2);
+
+	ZVAL_COPY(&c.value, val);
+	if (Z_OPT_CONSTANT(c.value)) {
+		if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
+			zval_ptr_dtor_nogc(&c.value);
+
+
+
+
+			HANDLE_EXCEPTION();
+		}
+	}
+	/* non persistent, case sensitive */
+	ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
+	c.name = zend_string_copy(Z_STR_P(name));
+
+	registered = zend_register_constant(&c);
+	if (registered == NULL) {
+
+
+
+
+		/* two opcodes used, second one is the data with attributes */
+		ZEND_VM_NEXT_OPCODE_EX(1, 2);
+	}
+
+	HashTable *attributes = Z_PTR_P(get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1));
+	ZEND_ASSERT(attributes != NULL);
+	zend_constant_add_attributes(registered, attributes);
+
+
+
+
+	/* two opcodes used, second one is the data with attributes */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CONST & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = RT_CONSTANT(opline, opline->op1);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CONST == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = RT_CONSTANT(opline, opline->op1);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CONST == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+		zval *key = RT_CONSTANT(opline, opline->op2);
+		if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_LONG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op, *jump_zv;
+	HashTable *jumptable;
+
+	op = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_P(op) != IS_LONG) {
+		ZVAL_DEREF(op);
+		if (Z_TYPE_P(op) != IS_LONG) {
+			/* Wrong type, fall back to ZEND_CASE chain */
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
+	if (jump_zv != NULL) {
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
+		ZEND_VM_CONTINUE();
+	} else {
+		/* default */
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+		ZEND_VM_CONTINUE();
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_STRING_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op, *jump_zv;
+	HashTable *jumptable;
+
+	op = RT_CONSTANT(opline, opline->op1);
+
+	if (Z_TYPE_P(op) != IS_STRING) {
+		if (IS_CONST == IS_CONST) {
+			/* Wrong type, fall back to ZEND_CASE chain */
+			ZEND_VM_NEXT_OPCODE();
+		} else {
+			ZVAL_DEREF(op);
+			if (Z_TYPE_P(op) != IS_STRING) {
+				/* Wrong type, fall back to ZEND_CASE chain */
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	}
+
+	jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST);
+	if (jump_zv != NULL) {
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
+		ZEND_VM_CONTINUE();
+	} else {
+		/* default */
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+		ZEND_VM_CONTINUE();
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op, *jump_zv;
+	HashTable *jumptable;
+
+	op = RT_CONSTANT(opline, opline->op1);
+	jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+
+match_try_again:
+	if (Z_TYPE_P(op) == IS_LONG) {
+		jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
+	} else if (Z_TYPE_P(op) == IS_STRING) {
+		jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST);
+	} else if (Z_TYPE_P(op) == IS_REFERENCE) {
+		op = Z_REFVAL_P(op);
+		goto match_try_again;
+	} else {
+		if (UNEXPECTED((IS_CONST & IS_CV) && Z_TYPE_P(op) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			op = ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			goto match_try_again;
+		}
+
+		goto default_branch;
+	}
+
+	if (jump_zv != NULL) {
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
+		ZEND_VM_CONTINUE();
+	} else {
+default_branch:
+		/* default */
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+		ZEND_VM_CONTINUE();
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IN_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	zval *result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CONST == IS_CONST);
+		if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(op1);
+		}
+		ZEND_VM_SMART_BRANCH(result, 0);
+	}
+
+	if (opline->extended_value) {
+		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+			result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+			ZEND_VM_SMART_BRANCH(result, 0);
+		}
+		SAVE_OPLINE();
+		if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+	} else if (Z_TYPE_P(op1) <= IS_FALSE) {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC());
+		ZEND_VM_SMART_BRANCH(result, 0);
+	} else {
+		zend_string *key;
+		zval key_tmp;
+
+		if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		}
+
+		SAVE_OPLINE();
+		ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) {
+			ZVAL_STR(&key_tmp, key);
+			if (zend_compare(op1, &key_tmp) == 0) {
+
+
+				ZEND_VM_SMART_BRANCH(1, 1);
+			}
+		} ZEND_HASH_FOREACH_END();
+	}
+
+
+	ZEND_VM_SMART_BRANCH(0, 1);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_add_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto add_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+add_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 + d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto add_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_sub_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto sub_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+sub_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 - d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto sub_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+				ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+				/* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+				ZVAL_LONG(result, 0);
+			} else {
+				ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+		ZVAL_LONG(EX_VAR(opline->result.var),
+			(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_class_entry *ce, *scope;
+	zend_class_constant *c;
+	zval *value, *zv, *constant_zv;
+	zend_string *constant_name;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+
+	do {
+		if (IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) {
+				value = CACHED_PTR(opline->extended_value + sizeof(void*));
+				break;
+			}
+		}
+		if (IS_CONST == IS_CONST) {
+			if (EXPECTED(CACHED_PTR(opline->extended_value))) {
+				ce = CACHED_PTR(opline->extended_value);
+			} else {
+				ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+				if (UNEXPECTED(ce == NULL)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+				CACHE_PTR(opline->extended_value, ce);
+			}
+		} else if (IS_CONST == IS_UNUSED) {
+			ce = zend_fetch_class(NULL, opline->op1.num);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op1.var));
+		}
+		if (IS_CONST != IS_CONST
+			&& (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST
+			&& EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
+			value = CACHED_PTR(opline->extended_value + sizeof(void*));
+			break;
+		}
+
+		constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC);
+		if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
+			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			FREE_OP(opline->op2_type, opline->op2.var);
+			HANDLE_EXCEPTION();
+		}
+		constant_name = Z_STR_P(constant_zv);
+		/* Magic 'class' for constant OP2 is caught at compile-time */
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
+			FREE_OP(opline->op2_type, opline->op2.var);
+			ZEND_VM_NEXT_OPCODE();
+		}
+		zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST
+			? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name)
+			: zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name);
+
+		if (EXPECTED(zv != NULL)) {
+			c = Z_PTR_P(zv);
+			scope = EX(func)->op_array.scope;
+			if (!zend_verify_const_access(c, scope)) {
+				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+
+			if (ce->ce_flags & ZEND_ACC_TRAIT) {
+				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				FREE_OP(opline->op2_type, opline->op2.var);
+				HANDLE_EXCEPTION();
+			}
+
+			bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
+			if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) {
+				if (c->ce->type == ZEND_USER_CLASS) {
+					/* Recursion protection only applied to user constants, GH-18463 */
+					CONST_PROTECT_RECURSION(c);
+				}
+				zend_deprecated_class_constant(c, constant_name);
+				if (c->ce->type == ZEND_USER_CLASS) {
+					CONST_UNPROTECT_RECURSION(c);
+				}
+
+				if (EG(exception)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			value = &c->value;
+			// Enums require loading of all class constants to build the backed enum table
+			if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
+				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
+					ZVAL_UNDEF(EX_VAR(opline->result.var));
+					FREE_OP(opline->op2_type, opline->op2.var);
+					HANDLE_EXCEPTION();
+				}
+			}
+			if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) {
+				CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
+			}
+		} else {
+			zend_throw_error(NULL, "Undefined constant %s::%s",
+				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			FREE_OP(opline->op2_type, opline->op2.var);
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
+
+	FREE_OP(opline->op2_type, opline->op2.var);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	fast_long_sub_function(result, op1, op2);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+	zend_long offset;
+	HashTable *ht;
+
+	container = RT_CONSTANT(opline, opline->op1);
+	dim = EX_VAR(opline->op2.var);
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+			offset = Z_LVAL_P(dim);
+		} else {
+			SAVE_OPLINE();
+			zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		ht = Z_ARRVAL_P(container);
+		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+			SAVE_OPLINE();
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto fetch_dim_r_index_array;
+		} else {
+			goto fetch_dim_r_index_slow;
+		}
+	} else {
+fetch_dim_r_index_slow:
+		SAVE_OPLINE();
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim++;
+		}
+		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+fetch_dim_r_index_undef:
+	ZVAL_NULL(EX_VAR(opline->result.var));
+	SAVE_OPLINE();
+	zend_undefined_offset(offset);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_CONST != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_CONST & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_CONST & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_CONST == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_TMP_VAR == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_CONST != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = RT_CONSTANT(opline, opline->op1);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	}
+
+	if (IS_TMP_VAR != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_CONST == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_CONST & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_TMP_VAR != IS_CONST) {
+							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				}
+				zend_invalid_method_call(object, function_name);
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_TMP_VAR == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_CONST == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_CONST == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				HANDLE_EXCEPTION();
+			}
+			if (IS_TMP_VAR != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_CONST == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_CONST == IS_CONST &&
+	    IS_TMP_VAR == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_CONST != IS_CONST &&
+	           IS_TMP_VAR == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_TMP_VAR != IS_UNUSED) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+					zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_CONST == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_fcall_info_cache fcc;
+	char *error = NULL;
+	zend_function *func;
+	void *object_or_called_scope;
+	zend_execute_data *call;
+	uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
+
+	SAVE_OPLINE();
+	function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
+		ZEND_ASSERT(!error);
+
+		/* Deprecation can be emitted from zend_is_callable_ex(), which can
+		 * invoke a user error handler and throw an exception.
+		 * For the CONST and CV case we reuse the same exception block below
+		 * to make sure we don't increase VM size too much. */
+		if (!(IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			HANDLE_EXCEPTION();
+		}
+
+		func = fcc.function_handler;
+		object_or_called_scope = fcc.called_scope;
+		if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
+			/* Delay closure destruction until its invocation */
+			GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+			call_info |= ZEND_CALL_CLOSURE;
+			if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+				call_info |= ZEND_CALL_FAKE_CLOSURE;
+			}
+			if (fcc.object) {
+				object_or_called_scope = fcc.object;
+				call_info |= ZEND_CALL_HAS_THIS;
+			}
+		} else if (fcc.object) {
+			GC_ADDREF(fcc.object); /* For $this pointer */
+			object_or_called_scope = fcc.object;
+			call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
+		}
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		if ((IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+			if (call_info & ZEND_CALL_CLOSURE) {
+				zend_object_release(ZEND_CLOSURE_OBJECT(func));
+			} else if (call_info & ZEND_CALL_RELEASE_THIS) {
+				zend_object_release(fcc.object);
+			}
+			HANDLE_EXCEPTION();
+		}
+
+		if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
+			init_func_run_time_cache(&func->op_array);
+		}
+	} else {
+		zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error);
+		efree(error);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		HANDLE_EXCEPTION();
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		func, opline->extended_value, object_or_called_scope);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = RT_CONSTANT(opline, opline->op1);
+		if (IS_CONST == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CONST == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CONST == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CONST == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CONST != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_CONST & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = RT_CONSTANT(opline, opline->op1);
+	subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CONST & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = RT_CONSTANT(opline, opline->op1);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CONST == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = RT_CONSTANT(opline, opline->op1);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CONST == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_R_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_W_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_RW_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	int fetch_type =
+		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
+			BP_VAR_W : BP_VAR_R;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_UNUSED == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_CONST == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_UNUSED != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_CONST == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_CONST == IS_CONST &&
+	    IS_UNUSED == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_CONST != IS_CONST &&
+	           IS_UNUSED == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_UNUSED != IS_UNUSED) {
+		function_name = NULL;
+		if (IS_UNUSED != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_UNUSED == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_UNUSED != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_CONST == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	if (IS_CONST == IS_UNUSED) {
+		SAVE_OPLINE();
+		zend_verify_missing_return_type(EX(func));
+		HANDLE_EXCEPTION();
+	} else {
+/* prevents "undefined variable opline" errors */
+#if 0 || (IS_CONST != IS_UNUSED)
+		USE_OPLINE
+		zval *retval_ref, *retval_ptr;
+		zend_arg_info *ret_info = EX(func)->common.arg_info - 1;
+		retval_ref = retval_ptr = RT_CONSTANT(opline, opline->op1);
+
+		if (IS_CONST == IS_CONST) {
+			ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr);
+			retval_ref = retval_ptr = EX_VAR(opline->result.var);
+		} else if (IS_CONST == IS_VAR) {
+			if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) {
+				retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr);
+			}
+			ZVAL_DEREF(retval_ptr);
+		} else if (IS_CONST == IS_CV) {
+			ZVAL_DEREF(retval_ptr);
+		}
+
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) {
+			SAVE_OPLINE();
+			retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		zend_reference *ref = NULL;
+		if (UNEXPECTED(retval_ref != retval_ptr)) {
+			if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+				ref = Z_REF_P(retval_ref);
+			} else {
+				/* A cast might happen - unwrap the reference if this is a by-value return */
+				if (Z_REFCOUNT_P(retval_ref) == 1) {
+					ZVAL_UNREF(retval_ref);
+				} else {
+					Z_DELREF_P(retval_ref);
+					ZVAL_COPY(retval_ref, retval_ptr);
+				}
+				retval_ptr = retval_ref;
+			}
+		}
+
+		SAVE_OPLINE();
+		if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) {
+			zend_verify_return_error(EX(func), retval_ptr);
+			HANDLE_EXCEPTION();
+		}
+		ZEND_VM_NEXT_OPCODE();
+#endif
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_CONST == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(0)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_val_by_ref;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_CONST == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(1)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_val_by_ref;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = RT_CONSTANT(opline, opline->op1);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_CONST == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *result;
+	zend_function *constructor;
+	zend_class_entry *ce;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+	if (IS_CONST == IS_CONST) {
+		ce = CACHED_PTR(opline->op2.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+			CACHE_PTR(opline->op2.num, ce);
+		}
+	} else if (IS_CONST == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	/* Naked `new` of a bare generic class (via `new static()`, `new $name`,
+	 * or any path that didn't go through compile-time canonical-name rewrite).
+	 * Skip when ZEND_VERIFY_GENERIC_ARGUMENTS follows — that opcode handles
+	 * the synthesis-and-swap for the turbofish path. Otherwise: if every
+	 * type parameter has a default, synthesize and use the defaults monomorph.
+	 * For `new static()` / lexical paths with no defaults, fall back to a
+	 * bare instance (preserves the lexical-self semantic for generic classes
+	 * whose authors didn't declare defaults). For dynamic `new $name()` we
+	 * throw — the caller spelled out a generic class by name and a bare
+	 * instance with erased T is almost never what they want.
+	 *
+	 * IS_CONST distinguishes: IS_UNUSED → static/self/parent (lenient);
+	 * IS_VAR → dynamic name resolved via FETCH_CLASS (strict). */
+	if (UNEXPECTED(IS_CONST != IS_CONST && ce->generic_parameters
+			&& (opline + 1)->opcode != ZEND_VERIFY_GENERIC_ARGUMENTS)) {
+		if (ce->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS) {
+			ce = zend_synthesize_monomorph(ce, NULL, 0);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else if (IS_CONST == IS_VAR) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments "
+				"via dynamic class name; no defaults declared",
+				ZSTR_VAL(ce->name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		/* IS_UNUSED with no defaults: fall through with the bare ce. */
+	}
+
+	result = EX_VAR(opline->result.var);
+	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
+		ZVAL_UNDEF(result);
+		HANDLE_EXCEPTION();
+	}
+
+	constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
+	if (constructor == NULL) {
+		/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
+		 * opcode is DO_FCALL in case EXT instructions are used. */
+		if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
+			ZEND_VM_NEXT_OPCODE_EX(1, 2);
+		}
+
+		if (UNEXPECTED(EG(exception))) {
+			HANDLE_EXCEPTION();
+		}
+
+		/* Perform a dummy function call */
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
+			opline->extended_value, NULL);
+	} else {
+		if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
+			init_func_run_time_cache(&constructor->op_array);
+		}
+		/* We are not handling overloaded classes right now */
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS,
+			constructor,
+			opline->extended_value,
+			Z_OBJ_P(result));
+		Z_ADDREF_P(result);
+	}
+
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = RT_CONSTANT(opline, opline->op1);
+		if (IS_CONST == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CONST == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CONST == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CONST == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *offset = NULL;
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_UNUSED != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CONST != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+
+	varname = RT_CONSTANT(opline, opline->op1);
+
+	if (IS_CONST == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			varname = ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	zend_hash_del_ind(target_symbol_table, name);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	bool result;
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+	varname = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else {
+		name = zval_get_tmp_string(varname, &tmp_name);
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	value = zend_hash_find_ex(target_symbol_table, name, IS_CONST == IS_CONST);
+
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+
+	if (!value) {
+		result = (opline->extended_value & ZEND_ISEMPTY);
+	} else {
+		if (Z_TYPE_P(value) == IS_INDIRECT) {
+			value = Z_INDIRECT_P(value);
+		}
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			if (Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+			}
+			result = Z_TYPE_P(value) > IS_NULL;
+		} else {
+			result = !i_zend_is_true(value);
+		}
+	}
+
+	ZEND_VM_SMART_BRANCH(result, true);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CONST & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = RT_CONSTANT(opline, opline->op1);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CONST == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = RT_CONSTANT(opline, opline->op1);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CONST == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_UNUSED != IS_UNUSED) {
+		zval *key = NULL;
+		if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op;
+
+	SAVE_OPLINE();
+	op = RT_CONSTANT(opline, opline->op1);
+	zend_match_unhandled_error(op);
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	zend_long count;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+
+	while (1) {
+		if (Z_TYPE_P(op1) == IS_ARRAY) {
+			count = zend_hash_num_elements(Z_ARRVAL_P(op1));
+			break;
+		} else if (Z_TYPE_P(op1) == IS_OBJECT) {
+			zend_object *zobj = Z_OBJ_P(op1);
+
+			/* first, we check if the handler is defined */
+			if (zobj->handlers->count_elements) {
+				if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) {
+					break;
+				}
+				if (UNEXPECTED(EG(exception))) {
+					count = 0;
+					break;
+				}
+			}
+
+			/* if not and the object implements Countable we call its count() method */
+			if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
+				zval retval;
+
+				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
+				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
+				count = zval_get_long(&retval);
+				zval_ptr_dtor(&retval);
+				break;
+			}
+
+			/* If There's no handler and it doesn't implement Countable then emit a TypeError */
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			continue;
+		} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		count = 0;
+		zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1));
+		break;
+	}
+
+	ZVAL_LONG(EX_VAR(opline->result.var), count);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (IS_CONST == IS_UNUSED) {
+		SAVE_OPLINE();
+		if (UNEXPECTED(!EX(func)->common.scope)) {
+			zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		} else {
+			zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		zval *op1;
+
+		SAVE_OPLINE();
+		op1 = RT_CONSTANT(opline, opline->op1);
+		while (1) {
+			if (Z_TYPE_P(op1) == IS_OBJECT) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
+			} else if ((IS_CONST & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+				op1 = Z_REFVAL_P(op1);
+				continue;
+			} else {
+				if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+					ZVAL_UNDEFINED_OP1();
+				}
+				zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+			}
+			break;
+		}
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	zend_string *type;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	type = zend_zval_get_legacy_type(op1);
+	if (EXPECTED(type)) {
+		ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type);
+	} else {
+		ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
+	}
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_array *ht;
+	uint32_t arg_count, result_size, skip;
+
+	arg_count = EX_NUM_ARGS();
+	if (IS_CONST == IS_CONST) {
+		skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1));
+		if (arg_count < skip) {
+			result_size = 0;
+		} else {
+			result_size = arg_count - skip;
+		}
+	} else {
+		skip = 0;
+		result_size = arg_count;
+	}
+
+	if (result_size) {
+		SAVE_OPLINE();
+		uint32_t first_extra_arg = EX(func)->op_array.num_args;
+
+		ht = zend_new_array(result_size);
+		ZVAL_ARR(EX_VAR(opline->result.var), ht);
+		zend_hash_real_init_packed(ht);
+		ZEND_HASH_FILL_PACKED(ht) {
+			zval *p, *q;
+			uint32_t i = skip;
+			p = EX_VAR_NUM(i);
+			if (arg_count > first_extra_arg) {
+				while (i < first_extra_arg) {
+					q = p;
+					if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
+						ZVAL_DEREF(q);
+						if (Z_OPT_REFCOUNTED_P(q)) {
+							Z_ADDREF_P(q);
+						}
+						ZEND_HASH_FILL_SET(q);
+					} else {
+						ZEND_HASH_FILL_SET_NULL();
+					}
+					ZEND_HASH_FILL_NEXT();
+					p++;
+					i++;
+				}
+				if (skip < first_extra_arg) {
+					skip = 0;
+				} else {
+					skip -= first_extra_arg;
+				}
+				p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip);
+			}
+			while (i < arg_count) {
+				q = p;
+				if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) {
+					ZVAL_DEREF(q);
+					if (Z_OPT_REFCOUNTED_P(q)) {
+						Z_ADDREF_P(q);
+					}
+					ZEND_HASH_FILL_SET(q);
+				} else {
+					ZEND_HASH_FILL_SET_NULL();
+				}
+				ZEND_HASH_FILL_NEXT();
+				p++;
+				i++;
+			}
+		} ZEND_HASH_FILL_END();
+		ht->nNumOfElements = result_size;
+	} else {
+		ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var));
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+/* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	SAVE_OPLINE();
+
+	zend_class_entry *ce = EX(func)->common.scope;
+	ZEND_ASSERT(ce);
+
+	zend_class_entry *parent_ce = ce->parent;
+	if (!parent_ce) {
+		zend_throw_error(NULL, "Cannot use \"parent\" when current class scope has no parent");
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	zend_string *property_name = Z_STR_P(RT_CONSTANT(opline, opline->op1));
+	zend_property_hook_kind hook_kind = opline->op2.num;
+
+	zend_property_info *prop_info = zend_hash_find_ptr(&parent_ce->properties_info, property_name);
+	if (!prop_info) {
+		zend_throw_error(NULL, "Undefined property %s::$%s", ZSTR_VAL(parent_ce->name), ZSTR_VAL(property_name));
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+	if (prop_info->flags & ZEND_ACC_PRIVATE) {
+		zend_throw_error(NULL, "Cannot access private property %s::$%s", ZSTR_VAL(parent_ce->name), ZSTR_VAL(property_name));
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	zend_function **hooks = prop_info->hooks;
+	zend_function *hook = hooks ? hooks[hook_kind] : NULL;
+
+	zend_execute_data *call;
+	if (hook) {
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS,
+			hook, opline->extended_value, Z_OBJ_P(ZEND_THIS));
+		if (EXPECTED(hook->type == ZEND_USER_FUNCTION)) {
+			if (UNEXPECTED(!RUN_TIME_CACHE(&hook->op_array))) {
+				init_func_run_time_cache(&hook->op_array);
+			}
+			call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+		}
+	} else {
+		zend_function *fbc = zend_get_property_hook_trampoline(prop_info, hook_kind, property_name);
+		call = zend_vm_stack_push_call_frame(
+			ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS,
+			fbc, opline->extended_value, Z_OBJ_P(ZEND_THIS));
+	}
+
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+
+	if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = EX_VAR(opline->op2.var);
+	if (IS_CONST != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CV == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_CONST & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	if (IS_CONST & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if (IS_CONST & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if (IS_CONST & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
+
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = RT_CONSTANT(opline, opline->op1);
+	op2 = EX_VAR(opline->op2.var);
+	if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CONST != IS_CONST && IS_CONST != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_CONST == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CV == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_CONST != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_CONST != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = RT_CONSTANT(opline, opline->op1);
+
+	if (IS_CV != IS_CONST) {
+		function_name = EX_VAR(opline->op2.var);
+	}
+
+	if (IS_CV != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_CONST == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_CONST & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CV != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CV == IS_CONST) {
+					function_name = EX_VAR(opline->op2.var);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+
+
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CV == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CV == IS_CONST) {
+			function_name = EX_VAR(opline->op2.var);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CV != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_CONST == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_class_entry *ce;
+	uint32_t call_info;
+	zend_function *fbc;
+	zend_execute_data *call;
+
+	SAVE_OPLINE();
+
+	if (IS_CONST == IS_CONST) {
+		/* no function found. try a static method in class */
+		ce = CACHED_PTR(opline->result.num);
+		if (UNEXPECTED(ce == NULL)) {
+			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
+			if (UNEXPECTED(ce == NULL)) {
+
+
+				HANDLE_EXCEPTION();
+			}
+			if (IS_CV != IS_CONST) {
+				CACHE_PTR(opline->result.num, ce);
+			}
+		}
+	} else if (IS_CONST == IS_UNUSED) {
+		ce = zend_fetch_class(NULL, opline->op1.num);
+		if (UNEXPECTED(ce == NULL)) {
+
+
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		ce = Z_CE_P(EX_VAR(opline->op1.var));
+	}
+
+	if (IS_CONST == IS_CONST &&
+	    IS_CV == IS_CONST &&
+	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
+		/* nothing to do */
+	} else if (IS_CONST != IS_CONST &&
+	           IS_CV == IS_CONST &&
+	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else if (IS_CV != IS_UNUSED) {
+		function_name = EX_VAR(opline->op2.var);
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+				do {
+					if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+						function_name = Z_REFVAL_P(function_name);
+						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+							break;
+						}
+					} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP2();
+						if (UNEXPECTED(EG(exception) != NULL)) {
+							HANDLE_EXCEPTION();
+						}
+					}
+					zend_throw_error(NULL, "Method name must be a string");
+
+
+					HANDLE_EXCEPTION();
+				} while (0);
+			}
+		}
+
+		if (ce->get_static_method) {
+			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
+		} else {
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		}
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(ce, Z_STR_P(function_name));
+			}
+
+
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+		if (IS_CV != IS_CONST) {
+
+
+		}
+	} else {
+		if (UNEXPECTED(ce->constructor == NULL)) {
+			zend_throw_error(NULL, "Cannot call constructor");
+			HANDLE_EXCEPTION();
+		}
+		if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
+			zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name));
+			HANDLE_EXCEPTION();
+		}
+		fbc = ce->constructor;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
+		if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) {
+			ce = (zend_class_entry*)Z_OBJ(EX(This));
+			call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+		} else {
+			zend_non_static_method_call(fbc);
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		/* previous opcode is ZEND_FETCH_CLASS */
+		if (IS_CONST == IS_UNUSED
+		 && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT ||
+		     (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) {
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				ce = Z_OBJCE(EX(This));
+			} else {
+				ce = Z_CE(EX(This));
+			}
+		}
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, ce);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zend_fcall_info_cache fcc;
+	char *error = NULL;
+	zend_function *func;
+	void *object_or_called_scope;
+	zend_execute_data *call;
+	uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
+
+	SAVE_OPLINE();
+	function_name = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
+		ZEND_ASSERT(!error);
+
+		/* Deprecation can be emitted from zend_is_callable_ex(), which can
+		 * invoke a user error handler and throw an exception.
+		 * For the CONST and CV case we reuse the same exception block below
+		 * to make sure we don't increase VM size too much. */
+		if (!(IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+
+
+			HANDLE_EXCEPTION();
+		}
+
+		func = fcc.function_handler;
+		object_or_called_scope = fcc.called_scope;
+		if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
+			/* Delay closure destruction until its invocation */
+			GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
+			call_info |= ZEND_CALL_CLOSURE;
+			if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) {
+				call_info |= ZEND_CALL_FAKE_CLOSURE;
+			}
+			if (fcc.object) {
+				object_or_called_scope = fcc.object;
+				call_info |= ZEND_CALL_HAS_THIS;
+			}
+		} else if (fcc.object) {
+			GC_ADDREF(fcc.object); /* For $this pointer */
+			object_or_called_scope = fcc.object;
+			call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS;
+		}
+
+
+		if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+			if (call_info & ZEND_CALL_CLOSURE) {
+				zend_object_release(ZEND_CLOSURE_OBJECT(func));
+			} else if (call_info & ZEND_CALL_RELEASE_THIS) {
+				zend_object_release(fcc.object);
+			}
+			HANDLE_EXCEPTION();
+		}
+
+		if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
+			init_func_run_time_cache(&func->op_array);
+		}
+	} else {
+		zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error);
+		efree(error);
+
+
+		HANDLE_EXCEPTION();
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		func, opline->extended_value, object_or_called_scope);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+
+
+	} else {
+		expr_ptr = RT_CONSTANT(opline, opline->op1);
+		if (IS_CONST == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CONST == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CONST == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CONST == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CV != IS_UNUSED) {
+		zval *offset = EX_VAR(opline->op2.var);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CONST != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	offset = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_CONST & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = RT_CONSTANT(opline, opline->op1);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_CONST == IS_CONST ||
+	    (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = RT_CONSTANT(opline, opline->op1);
+	subject = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_CONST != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CONST & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = RT_CONSTANT(opline, opline->op1);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CONST == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
+			}
+		} else {
+			zval *value = RT_CONSTANT(opline, opline->op1);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_CONST == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CONST == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CONST == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
+			}
+		}
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
+	}
+
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_NOT_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+
+	op1 = EX_VAR(opline->op1.var);
+	if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = EX_VAR(opline->op1.var);
+	ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(value));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = EX_VAR(opline->op1.var);
+	ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = EX_VAR(opline->op1.var);
+	ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_add_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto add_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+add_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 + d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto add_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_sub_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto sub_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+sub_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 - d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto sub_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			zend_long overflow;
+
+			result = EX_VAR(opline->result.var);
+			ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+			Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto mul_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+mul_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 * d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto mul_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+				ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+				/* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+				ZVAL_LONG(result, 0);
+			} else {
+				ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+		ZVAL_LONG(EX_VAR(opline->result.var),
+			(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op, *jump_zv;
+	HashTable *jumptable;
+
+	op = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_P(op) != IS_LONG) {
+		ZVAL_DEREF(op);
+		if (Z_TYPE_P(op) != IS_LONG) {
+			/* Wrong type, fall back to ZEND_CASE chain */
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
+	if (jump_zv != NULL) {
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
+		ZEND_VM_CONTINUE();
+	} else {
+		/* default */
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+		ZEND_VM_CONTINUE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op, *jump_zv;
+	HashTable *jumptable;
+
+	op = EX_VAR(opline->op1.var);
+
+	if (Z_TYPE_P(op) != IS_STRING) {
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+			/* Wrong type, fall back to ZEND_CASE chain */
+			ZEND_VM_NEXT_OPCODE();
+		} else {
+			ZVAL_DEREF(op);
+			if (Z_TYPE_P(op) != IS_STRING) {
+				/* Wrong type, fall back to ZEND_CASE chain */
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	}
+
+	jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST);
+	if (jump_zv != NULL) {
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
+		ZEND_VM_CONTINUE();
+	} else {
+		/* default */
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+		ZEND_VM_CONTINUE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op, *jump_zv;
+	HashTable *jumptable;
+
+	op = EX_VAR(opline->op1.var);
+	jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+
+match_try_again:
+	if (Z_TYPE_P(op) == IS_LONG) {
+		jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op));
+	} else if (Z_TYPE_P(op) == IS_STRING) {
+		jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST);
+	} else if (Z_TYPE_P(op) == IS_REFERENCE) {
+		op = Z_REFVAL_P(op);
+		goto match_try_again;
+	} else {
+		if (UNEXPECTED(((IS_TMP_VAR|IS_VAR|IS_CV) & IS_CV) && Z_TYPE_P(op) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			op = ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			goto match_try_again;
+		}
+
+		goto default_branch;
+	}
+
+	if (jump_zv != NULL) {
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv));
+		ZEND_VM_CONTINUE();
+	} else {
+default_branch:
+		/* default */
+		ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+		ZEND_VM_CONTINUE();
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	fast_long_add_function(result, op1, op2);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	fast_long_sub_function(result, op1, op2);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	zend_long overflow;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+	Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = EX_VAR(opline->result.var);
+	ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	bool result;
+
+	op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC);
+	result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0;
+	FREE_OP(opline->op1_type, opline->op1.var);
+
+
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	bool result;
+
+	op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC);
+	result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0;
+	FREE_OP(opline->op1_type, opline->op1.var);
+
+
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	bool result;
+
+	op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC);
+	result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0;
+	FREE_OP(opline->op1_type, opline->op1.var);
+
+
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	bool result;
+
+	op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC);
+	result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0;
+	FREE_OP(opline->op1_type, opline->op1.var);
+
+
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	bool result;
+
+	op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC);
+	result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0;
+	FREE_OP(opline->op1_type, opline->op1.var);
+
+
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	bool result;
+
+	op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC);
+	result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0;
+	FREE_OP(opline->op1_type, opline->op1.var);
+
+
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_add_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto add_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+add_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 + d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto add_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			fast_long_sub_function(result, op1, op2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto sub_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+sub_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 - d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto sub_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			zend_long overflow;
+
+			result = EX_VAR(opline->result.var);
+			ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+			Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto mul_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+mul_double:
+			result = EX_VAR(opline->result.var);
+			ZVAL_DOUBLE(result, d1 * d2);
+			ZEND_VM_NEXT_OPCODE();
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto mul_double;
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			result = EX_VAR(opline->result.var);
+			if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+				ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+				/* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+				ZVAL_LONG(result, 0);
+			} else {
+				ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+		ZVAL_LONG(EX_VAR(opline->result.var),
+			(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
+			&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) {
+is_smaller_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_smaller_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_double:
+			if (d1 < d2) {
+				goto is_smaller_true;
+			} else {
+				goto is_smaller_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) {
+is_smaller_or_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+				ZVAL_TRUE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			} else {
+is_smaller_or_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+				ZVAL_FALSE(EX_VAR(opline->result.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_smaller_or_equal_double:
+			if (d1 <= d2) {
+				goto is_smaller_or_equal_true;
+			} else {
+				goto is_smaller_or_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_smaller_or_equal_double;
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
+			&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	fast_long_add_function(result, op1, op2);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	fast_long_sub_function(result, op1, op2);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+	zend_long overflow;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+	Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2, *result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = EX_VAR(opline->result.var);
+	ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_NONE(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPZ(result, 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+	ZEND_VM_SMART_BRANCH_JMPNZ(result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op;
+
+	SAVE_OPLINE();
+	op = EX_VAR(opline->op1.var);
+	zend_match_unhandled_error(op);
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FREE_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FREE_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *var;
+	USE_OPLINE
+
+	var = EX_VAR(opline->op1.var);
+	if (Z_TYPE_P(var) != IS_ARRAY) {
+		SAVE_OPLINE();
+		if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+			zend_hash_iterator_del(Z_FE_ITER_P(var));
+		}
+		zval_ptr_dtor_nogc(var);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	/* This is freeing an array. Use an inlined version of zval_ptr_dtor_nogc. */
+	/* PHP only needs to save the opline and check for an exception if the last reference to the array was garbage collected (destructors of elements in the array could throw an exception) */
+	if (Z_REFCOUNTED_P(var) && !Z_DELREF_P(var)) {
+		SAVE_OPLINE();
+		rc_dtor_func(Z_COUNTED_P(var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = RT_CONSTANT(opline, opline->op2);
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if ((IS_TMP_VAR|IS_VAR) & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CONST == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		} else {
+			name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CONST != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+	zend_long offset;
+	HashTable *ht;
+
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	dim = RT_CONSTANT(opline, opline->op2);
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+			offset = Z_LVAL_P(dim);
+		} else {
+			SAVE_OPLINE();
+			zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		ht = Z_ARRVAL_P(container);
+		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			SAVE_OPLINE();
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto fetch_dim_r_index_array;
+		} else {
+			goto fetch_dim_r_index_slow;
+		}
+	} else {
+fetch_dim_r_index_slow:
+		SAVE_OPLINE();
+		if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim++;
+		}
+		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+fetch_dim_r_index_undef:
+	ZVAL_NULL(EX_VAR(opline->result.var));
+	SAVE_OPLINE();
+	zend_undefined_offset(offset);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+	zend_long offset;
+	HashTable *ht;
+
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	dim = EX_VAR(opline->op2.var);
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+		if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+			offset = Z_LVAL_P(dim);
+		} else {
+			SAVE_OPLINE();
+			zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		ht = Z_ARRVAL_P(container);
+		ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			SAVE_OPLINE();
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto fetch_dim_r_index_array;
+		} else {
+			goto fetch_dim_r_index_slow;
+		}
+	} else {
+fetch_dim_r_index_slow:
+		SAVE_OPLINE();
+		if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim++;
+		}
+		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+fetch_dim_r_index_undef:
+	ZVAL_NULL(EX_VAR(opline->result.var));
+	SAVE_OPLINE();
+	zend_undefined_offset(offset);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if ((IS_TMP_VAR|IS_VAR) & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+
+	if (IS_UNUSED == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		uint32_t arg_num;
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+	}
+
+	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+
+	varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
+	} else {
+		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			varname = ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	zend_hash_del_ind(target_symbol_table, name);
+
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	zval *result = EX_VAR(opline->result.var);
+	ZVAL_COPY(result, value);
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container, *dim, *value;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = EX_VAR(opline->op2.var);
+	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_array:
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC);
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
+		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto fetch_dim_r_array;
+			} else {
+				goto fetch_dim_r_slow;
+			}
+		} else {
+fetch_dim_r_slow:
+			if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
+		}
+	} else {
+		zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+			}
+			zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_r_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_r_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+fetch_obj_r_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						prop_offset = prop_info->offset;
+						goto fetch_obj_r_simple;
+					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
+						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
+						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
+						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+
+						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+						if ((IS_TMP_VAR|IS_VAR) & IS_CV) {
+							GC_ADDREF(zobj);
+						}
+						if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) {
+							call_info |= ZEND_CALL_RELEASE_THIS;
+						}
+						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
+						call->prev_execute_data = execute_data;
+						call->call = NULL;
+						call->return_value = EX_VAR(opline->result.var);
+						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+
+						execute_data = call;
+						EG(current_execute_data) = execute_data;
+						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+
+#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
+						opline = hook->op_array.opcodes;
+#else
+						EX(opline) = hook->op_array.opcodes;
+#endif
+						LOAD_OPLINE_EX();
+
+
+
+
+						ZEND_VM_ENTER_EX();
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_r_copy;
+								} else {
+									goto fetch_obj_r_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_r_copy;
+						} else {
+							goto fetch_obj_r_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+#if ZEND_DEBUG
+		/* For non-standard object handlers, verify a declared property type in debug builds.
+		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
+		zend_property_info *prop_info = NULL;
+		if (zobj->handlers->read_property != zend_std_read_property) {
+			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+		}
+#endif
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
+#if ZEND_DEBUG
+		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
+				&& ZEND_TYPE_IS_SET(prop_info->type)) {
+			ZVAL_OPT_DEREF(retval);
+			zend_verify_property_type(prop_info, retval, /* strict */ true);
+		}
+#endif
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_r_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_r_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	void **cache_slot = NULL;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
+
+	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
+	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		do {
+			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			ZVAL_NULL(EX_VAR(opline->result.var));
+			goto fetch_obj_is_finish;
+		} while (0);
+	}
+
+	/* here we are sure we are dealing with an object */
+	do {
+		zend_object *zobj = Z_OBJ_P(container);
+		zend_string *name, *tmp_name;
+		zval *retval;
+
+		if (IS_CV == IS_CONST) {
+			cache_slot = CACHE_ADDR(opline->extended_value);
+
+			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
+				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
+
+				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
+fetch_obj_is_simple:
+					retval = OBJ_PROP(zobj, prop_offset);
+					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+fetch_obj_is_fast_copy:
+							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+							ZEND_VM_NEXT_OPCODE();
+						}
+					}
+				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
+					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
+						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
+						prop_offset = prop_info->offset;
+						goto fetch_obj_is_simple;
+					}
+					/* Fall through to read_property for hooks. */
+				} else if (EXPECTED(zobj->properties != NULL)) {
+					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
+					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
+						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+
+						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
+							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+
+							if (EXPECTED(p->key == name) ||
+							    (EXPECTED(p->h == ZSTR_H(name)) &&
+							     EXPECTED(p->key != NULL) &&
+							     EXPECTED(zend_string_equal_content(p->key, name)))) {
+								retval = &p->val;
+								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+									goto fetch_obj_is_copy;
+								} else {
+									goto fetch_obj_is_fast_copy;
+								}
+							}
+						}
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
+					}
+					retval = zend_hash_find_known_hash(zobj->properties, name);
+					if (EXPECTED(retval)) {
+						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
+						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
+						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
+							goto fetch_obj_is_copy;
+						} else {
+							goto fetch_obj_is_fast_copy;
+						}
+					}
+				}
+			}
+			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
+		} else {
+			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			if (UNEXPECTED(!name)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				break;
+			}
+		}
+
+		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+
+		if (retval != EX_VAR(opline->result.var)) {
+fetch_obj_is_copy:
+			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_unwrap_reference(retval);
+		}
+	} while (0);
+
+fetch_obj_is_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_NOT_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ECHO_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *z;
+
+	SAVE_OPLINE();
+	z = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_P(z) == IS_STRING) {
+		zend_string *str = Z_STR_P(z);
+
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
+		}
+	} else {
+		zend_string *str = zval_get_string_func(z);
+
+		if (ZSTR_LEN(str) != 0) {
+			zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
+		} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		zend_string_release_ex(str, 0);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	uint8_t op1_type;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	SAVE_OPLINE();
+	op1_type = IS_TMP_VAR;
+	if (i_zend_is_true(val)) {
+		opline++;
+	} else {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	uint8_t op1_type;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	op1_type = IS_TMP_VAR;
+	if (i_zend_is_true(val)) {
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		opline++;
+	}
+	if (op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(val);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_EX_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	bool ret;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_NEXT_OPCODE();
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	SAVE_OPLINE();
+	ret = i_zend_is_true(val);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline++;
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_EX_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+	bool ret;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			ZEND_VM_NEXT_OPCODE();
+		}
+	}
+
+	SAVE_OPLINE();
+	ret = i_zend_is_true(val);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	if (ret) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+		opline = OP_JMP_ADDR(opline, opline->op2);
+	} else {
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		opline++;
+	}
+	ZEND_VM_JMP(opline);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+
+
+	retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	return_value = EX(return_value);
+
+
+	if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		retval_ptr = ZVAL_UNDEFINED_OP1();
+		if (return_value) {
+			ZVAL_NULL(return_value);
+		}
+	} else if (!return_value) {
+		if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) {
+			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
+				SAVE_OPLINE();
+				rc_dtor_func(Z_COUNTED_P(retval_ptr));
+			}
+		}
+	} else {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZVAL_COPY_VALUE(return_value, retval_ptr);
+			if (IS_TMP_VAR == IS_CONST) {
+				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
+					Z_ADDREF_P(return_value);
+				}
+			}
+		} else if (IS_TMP_VAR == IS_CV) {
+			do {
+				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
+						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
+							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+							ZVAL_COPY_VALUE(return_value, retval_ptr);
+							if (GC_MAY_LEAK(ref)) {
+								SAVE_OPLINE();
+								gc_possible_root(ref);
+							}
+							ZVAL_NULL(retval_ptr);
+							break;
+						} else {
+							Z_ADDREF_P(retval_ptr);
+						}
+					} else {
+						retval_ptr = Z_REFVAL_P(retval_ptr);
+						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+							Z_ADDREF_P(retval_ptr);
+						}
+					}
+				}
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			} while (0);
+		} else /* if (IS_TMP_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
+
+				retval_ptr = Z_REFVAL_P(retval_ptr);
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
+					Z_ADDREF_P(retval_ptr);
+				}
+			} else {
+				ZVAL_COPY_VALUE(return_value, retval_ptr);
+			}
+		}
+	}
+
+
+
+
+
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval_ptr;
+	zval *return_value;
+
+
+	SAVE_OPLINE();
+
+	return_value = EX(return_value);
+
+
+	do {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) ||
+		    (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
+			/* Not supposed to happen, but we'll allow it */
+			zend_error(E_NOTICE, "Only variable references should be returned by reference");
+
+			retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+			if (!return_value) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			} else {
+				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
+					ZVAL_COPY_VALUE(return_value, retval_ptr);
+					break;
+				}
+
+				ZVAL_NEW_REF(return_value, retval_ptr);
+				if (IS_TMP_VAR == IS_CONST) {
+					Z_TRY_ADDREF_P(retval_ptr);
+				}
+			}
+			break;
+		}
+
+		retval_ptr = zend_get_bad_ptr();
+
+		if (IS_TMP_VAR == IS_VAR) {
+			ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
+			if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
+				zend_error(E_NOTICE, "Only variable references should be returned by reference");
+				if (return_value) {
+					ZVAL_NEW_REF(return_value, retval_ptr);
+				} else {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				}
+				break;
+			}
+		}
+
+		if (return_value) {
+			if (Z_ISREF_P(retval_ptr)) {
+				Z_ADDREF_P(retval_ptr);
+			} else {
+				ZVAL_MAKE_REF_EX(retval_ptr, 2);
+			}
+			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
+		}
+
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} while (0);
+
+
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *retval;
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+	SAVE_OPLINE();
+	retval = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	/* Copy return value into generator->retval */
+	if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+		ZVAL_COPY_VALUE(&generator->retval, retval);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
+				Z_ADDREF(generator->retval);
+			}
+		}
+	} else if (IS_TMP_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(&generator->retval, retval);
+	} else /* if (IS_TMP_VAR == IS_VAR) */ {
+		if (UNEXPECTED(Z_ISREF_P(retval))) {
+			zend_refcounted *ref = Z_COUNTED_P(retval);
+
+			retval = Z_REFVAL_P(retval);
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(retval)) {
+				Z_ADDREF_P(retval);
+			}
+		} else {
+			ZVAL_COPY_VALUE(&generator->retval, retval);
+		}
+	}
+
+
+	EG(current_execute_data) = EX(prev_execute_data);
+
+	/* Close the generator to free up resources */
+	zend_generator_close(generator, 1);
+
+	/* Pass execution back to handling code */
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	do {
+		if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+				if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
+					break;
+				}
+			}
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Can only throw objects");
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	Z_TRY_ADDREF_P(value);
+	zend_throw_exception_object(value);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	HANDLE_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *arg, *param;
+
+	SAVE_OPLINE();
+
+	arg = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	param = ZEND_CALL_VAR(EX(call), opline->result.var);
+	if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
+		zend_param_must_be_ref(EX(call)->func, opline->op2.num);
+		Z_TRY_ADDREF_P(arg);
+		ZVAL_NEW_REF(param, arg);
+	} else {
+		ZVAL_COPY(param, arg);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (Z_TYPE_INFO_P(val) == IS_TRUE) {
+		ZVAL_TRUE(EX_VAR(opline->result.var));
+	} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+		/* The result and op1 can be the same cv zval */
+		const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
+		ZVAL_FALSE(EX_VAR(opline->result.var));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	} else {
+		SAVE_OPLINE();
+		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *obj;
+	zend_object *zobj;
+	zend_class_entry *ce, *scope;
+	zend_function *clone;
+	zend_object_clone_obj_t clone_call;
+
+	SAVE_OPLINE();
+	obj = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
+	do {
+		if (IS_TMP_VAR == IS_CONST ||
+		    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) {
+				obj = Z_REFVAL_P(obj);
+				if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) {
+					break;
+				}
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP1();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} while (0);
+
+	zobj = Z_OBJ_P(obj);
+	ce = zobj->ce;
+	clone = ce->clone;
+	clone_call = zobj->handlers->clone_obj;
+	if (UNEXPECTED(clone_call == NULL)) {
+		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
+		scope = EX(func)->op_array.scope;
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+
+	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	zval *result = EX_VAR(opline->result.var);
+
+	SAVE_OPLINE();
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	switch (opline->extended_value) {
+		case IS_LONG:
+			ZVAL_LONG(result, zval_get_long(expr));
+			break;
+		case IS_DOUBLE:
+			ZVAL_DOUBLE(result, zval_get_double(expr));
+			break;
+		case IS_STRING:
+			ZVAL_STR(result, zval_get_string(expr));
+			break;
+		default:
+			ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead");
+			if (IS_TMP_VAR & (IS_VAR|IS_CV)) {
+				ZVAL_DEREF(expr);
+			}
+			/* If value is already of correct type, return it directly */
+			if (Z_TYPE_P(expr) == opline->extended_value) {
+				ZVAL_COPY_VALUE(result, expr);
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+				} else if (IS_TMP_VAR != IS_TMP_VAR) {
+					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+				}
+
+
+				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+			}
+
+			if (opline->extended_value == IS_ARRAY) {
+				zend_cast_zval_to_array(result, expr, IS_TMP_VAR);
+			} else {
+				ZEND_ASSERT(opline->extended_value == IS_OBJECT);
+				zend_cast_zval_to_object(result, expr, IS_TMP_VAR);
+			}
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_op_array *new_op_array;
+	zval *inc_filename;
+
+	SAVE_OPLINE();
+	inc_filename = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
+	if (UNEXPECTED(EG(exception) != NULL)) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
+			destroy_op_array(new_op_array);
+			efree_size(new_op_array, sizeof(zend_op_array));
+		}
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	} else if (new_op_array == ZEND_FAKE_OP_ARRAY) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_TRUE(EX_VAR(opline->result.var));
+		}
+	} else if (UNEXPECTED(new_op_array == NULL)) {
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_FALSE(EX_VAR(opline->result.var));
+		}
+	} else if (new_op_array->last == 1
+			&& new_op_array->opcodes[0].opcode == ZEND_RETURN
+			&& new_op_array->opcodes[0].op1_type == IS_CONST
+			&& EXPECTED(zend_execute_ex == execute_ex)) {
+		if (RETURN_VALUE_USED(opline)) {
+			const zend_op *op = new_op_array->opcodes;
+
+			ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1));
+		}
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+	} else {
+		zval *return_value = NULL;
+		zend_execute_data *call;
+		if (RETURN_VALUE_USED(opline)) {
+			return_value = EX_VAR(opline->result.var);
+		}
+
+		new_op_array->scope = EX(func)->op_array.scope;
+
+		call = zend_vm_stack_push_call_frame(
+			(Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE,
+			(zend_function*)new_op_array, 0,
+			Z_PTR(EX(This)));
+
+		if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
+			call->symbol_table = EX(symbol_table);
+		} else {
+			call->symbol_table = zend_rebuild_symbol_table();
+		}
+
+		call->prev_execute_data = execute_data;
+		i_init_code_execute_data(call, new_op_array, return_value);
+
+
+		if (EXPECTED(zend_execute_ex == execute_ex)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			ZEND_VM_ENTER();
+		} else {
+			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
+			zend_execute_ex(call);
+			zend_vm_stack_free_call_frame(call);
+		}
+
+		zend_destroy_static_vars(new_op_array);
+		destroy_op_array(new_op_array);
+		efree_size(new_op_array, sizeof(zend_op_array));
+		if (UNEXPECTED(EG(exception) != NULL)) {
+			zend_rethrow_exception(execute_data);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			UNDEF_RESULT();
+			HANDLE_EXCEPTION();
+		}
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *result;
+
+	SAVE_OPLINE();
+
+	array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, array_ptr);
+		if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+			Z_ADDREF_P(array_ptr);
+		}
+		Z_FE_POS_P(result) = 0;
+
+
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		zend_object *zobj = Z_OBJ_P(array_ptr);
+		if (!zobj->ce->get_iterator) {
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			HashTable *properties = zobj->properties;
+			if (properties) {
+				if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+					if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+						GC_DELREF(properties);
+					}
+					properties = zobj->properties = zend_array_dup(properties);
+				}
+			} else {
+				properties = zobj->handlers->get_properties(zobj);
+			}
+
+			result = EX_VAR(opline->result.var);
+			ZVAL_COPY_VALUE(result, array_ptr);
+			if (IS_TMP_VAR != IS_TMP_VAR) {
+				Z_ADDREF_P(array_ptr);
+			}
+
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(result) = (uint32_t) -1;
+
+
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
+
+			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array_ptr, *array_ref;
+
+	SAVE_OPLINE();
+
+	if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+		array_ref = array_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(array_ref)) {
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+	} else {
+		array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	}
+
+	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+		if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+			if (array_ptr == array_ref) {
+				ZVAL_NEW_REF(array_ref, array_ref);
+				array_ptr = Z_REFVAL_P(array_ref);
+			}
+			Z_ADDREF_P(array_ref);
+			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+		} else {
+			array_ref = EX_VAR(opline->result.var);
+			ZVAL_NEW_REF(array_ref, array_ptr);
+			array_ptr = Z_REFVAL_P(array_ref);
+		}
+		if (IS_TMP_VAR == IS_CONST) {
+			ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr)));
+		} else {
+			SEPARATE_ARRAY(array_ptr);
+		}
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
+
+
+		ZEND_VM_NEXT_OPCODE();
+	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+			zend_object *zobj = Z_OBJ_P(array_ptr);
+			HashTable *properties;
+			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
+				zobj = zend_lazy_object_init(zobj);
+				if (UNEXPECTED(EG(exception))) {
+					UNDEF_RESULT();
+
+
+					HANDLE_EXCEPTION();
+				}
+			}
+			if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+				if (array_ptr == array_ref) {
+					ZVAL_NEW_REF(array_ref, array_ref);
+					array_ptr = Z_REFVAL_P(array_ref);
+				}
+				Z_ADDREF_P(array_ref);
+				ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+			} else {
+				array_ptr = EX_VAR(opline->result.var);
+				ZVAL_COPY_VALUE(array_ptr, array_ref);
+			}
+			if (Z_OBJ_P(array_ptr)->properties
+			 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
+				if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
+					GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+				}
+				Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+			}
+
+			properties = Z_OBJPROP_P(array_ptr);
+			if (zend_hash_num_elements(properties) == 0) {
+				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
+
+
+				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			}
+
+			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		} else {
+			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			} else if (is_empty) {
+				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+			} else {
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+	} else {
+		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+	}
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_R_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *array;
+	zval *value;
+	uint32_t value_type;
+	HashTable *fe_ht;
+	HashPosition pos;
+
+	array = EX_VAR(opline->op1.var);
+	if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) {
+		ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+	fe_ht = Z_ARRVAL_P(array);
+	pos = Z_FE_POS_P(array);
+	if (HT_IS_PACKED(fe_ht)) {
+		value = fe_ht->arPacked + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
+			}
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
+			}
+			pos++;
+			value++;
+		}
+		Z_FE_POS_P(array) = pos + 1;
+		if (RETURN_VALUE_USED(opline)) {
+			ZVAL_LONG(EX_VAR(opline->result.var), pos);
+		}
+	} else {
+		Bucket *p;
+
+		p = fe_ht->arData + pos;
+		while (1) {
+			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
+				/* reached end of iteration */
+				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+				ZEND_VM_CONTINUE();
+			}
+			pos++;
+			value = &p->val;
+			value_type = Z_TYPE_INFO_P(value);
+			ZEND_ASSERT(value_type != IS_INDIRECT);
+			if (EXPECTED(value_type != IS_UNDEF)) {
+				break;
+			}
+			p++;
+		}
+		Z_FE_POS_P(array) = pos;
+		if (RETURN_VALUE_USED(opline)) {
+			if (!p->key) {
+				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
+			} else {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
+			}
+		}
+	}
+	if (EXPECTED(opline->op2_type == IS_CV)) {
+		zval *variable_ptr = EX_VAR(opline->op2.var);
+		SAVE_OPLINE();
+		zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	} else {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			value = Z_REFVAL_P(value);
+			value_type = Z_TYPE_INFO_P(value);
+		}
+		zval *res = EX_VAR(opline->op2.var);
+		zend_refcounted *gc = Z_COUNTED_P(value);
+
+		ZVAL_COPY_VALUE_EX(res, value, gc, value_type);
+		if (Z_TYPE_INFO_REFCOUNTED(value_type)) {
+			GC_ADDREF(gc);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_END_SILENCE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))
+			&& !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) {
+		EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zend_reference *ref = NULL;
+	bool ret;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) {
+		if (IS_TMP_VAR == IS_VAR) {
+			ref = Z_REF_P(value);
+		}
+		value = Z_REFVAL_P(value);
+	}
+
+	ret = i_zend_is_true(value);
+
+	if (UNEXPECTED(EG(exception))) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	if (ret) {
+		zval *result = EX_VAR(opline->result.var);
+
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_TMP_VAR == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if (IS_TMP_VAR == IS_VAR && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zend_reference *ref = NULL;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+		if (IS_TMP_VAR & IS_VAR) {
+			ref = Z_REF_P(value);
+		}
+		value = Z_REFVAL_P(value);
+	}
+
+	if (Z_TYPE_P(value) > IS_NULL) {
+		zval *result = EX_VAR(opline->result.var);
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
+		} else if (IS_TMP_VAR == IS_CV) {
+			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
+		} else if ((IS_TMP_VAR & IS_VAR) && ref) {
+			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+				efree_size(ref, sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		}
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+
+	if ((IS_TMP_VAR & IS_VAR) && ref) {
+		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+			efree_size(ref, sizeof(zend_reference));
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *val, *result;
+
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (Z_TYPE_P(val) > IS_NULL) {
+		do {
+			if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) {
+				val = Z_REFVAL_P(val);
+				if (Z_TYPE_P(val) <= IS_NULL) {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					break;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		} while (0);
+	}
+
+	result = EX_VAR(opline->result.var);
+	uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK;
+	if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) {
+		ZVAL_NULL(result);
+		if (IS_TMP_VAR == IS_CV
+			&& UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)
+			&& (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0
+		) {
+			SAVE_OPLINE();
+			ZVAL_UNDEFINED_OP1();
+			if (UNEXPECTED(EG(exception) != NULL)) {
+				HANDLE_EXCEPTION();
+			}
+		}
+	} else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) {
+		ZVAL_FALSE(result);
+	} else {
+		ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY);
+		ZVAL_TRUE(result);
+	}
+
+	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *result = EX_VAR(opline->result.var);
+
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		ZVAL_NULL(result);
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	if (IS_TMP_VAR == IS_CV) {
+		ZVAL_COPY_DEREF(result, value);
+	} else if (IS_TMP_VAR == IS_VAR) {
+		if (UNEXPECTED(Z_ISREF_P(value))) {
+			ZVAL_COPY_VALUE(result, Z_REFVAL_P(value));
+			if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
+				efree_size(Z_REF_P(value), sizeof(zend_reference));
+			} else if (Z_OPT_REFCOUNTED_P(result)) {
+				Z_ADDREF_P(result);
+			}
+		} else {
+			ZVAL_COPY_VALUE(result, value);
+		}
+	} else {
+		ZVAL_COPY_VALUE(result, value);
+		if (IS_TMP_VAR == IS_CONST) {
+			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) {
+				Z_ADDREF_P(result);
+			}
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+	zval *val;
+
+	SAVE_OPLINE();
+	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+yield_from_try_again:
+	if (Z_TYPE_P(val) == IS_ARRAY) {
+		ZVAL_COPY_VALUE(&generator->values, val);
+		if (Z_OPT_REFCOUNTED_P(val)) {
+			Z_ADDREF_P(val);
+		}
+		Z_FE_POS(generator->values) = 0;
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
+		zend_class_entry *ce = Z_OBJCE_P(val);
+		if (ce == zend_ce_generator) {
+			zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val);
+
+			Z_ADDREF_P(val);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+			if (UNEXPECTED(new_gen->execute_data == NULL)) {
+				zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
+				zval_ptr_dtor(val);
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			} else if (Z_ISUNDEF(new_gen->retval)) {
+				if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) {
+					zend_throw_error(NULL, "Impossible to yield from the Generator being currently run");
+					zval_ptr_dtor(val);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				} else {
+					zend_generator_yield_from(generator, new_gen);
+				}
+			} else {
+				if (RETURN_VALUE_USED(opline)) {
+					ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval);
+				}
+				ZEND_VM_NEXT_OPCODE();
+			}
+		} else {
+			zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+				if (!EG(exception)) {
+					zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
+				}
+				UNDEF_RESULT();
+				HANDLE_EXCEPTION();
+			}
+
+			iter->index = 0;
+			if (iter->funcs->rewind) {
+				iter->funcs->rewind(iter);
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					OBJ_RELEASE(&iter->std);
+					UNDEF_RESULT();
+					HANDLE_EXCEPTION();
+				}
+			}
+
+			ZVAL_OBJ(&generator->values, &iter->std);
+		}
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) {
+		val = Z_REFVAL_P(val);
+		goto yield_from_try_again;
+	} else {
+		zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		UNDEF_RESULT();
+		HANDLE_EXCEPTION();
+	}
+
+	/* This is the default return value
+	 * when the expression is a Generator, it will be overwritten in zend_generator_resume() */
+	if (RETURN_VALUE_USED(opline)) {
+		ZVAL_NULL(EX_VAR(opline->result.var));
+	}
+
+	/* This generator has no send target (though the generator we delegate to might have one) */
+	generator->send_target = NULL;
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+		ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+		if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(value);
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		bool strict;
+
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) {
+			value = Z_REFVAL_P(value);
+			if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
+				ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+
+		SAVE_OPLINE();
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+			value = ZVAL_UNDEFINED_OP1();
+		}
+		strict = EX_USES_STRICT_TYPES();
+		do {
+			if (EXPECTED(!strict)) {
+				zend_string *str;
+				zval tmp;
+
+				if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
+					zend_error(E_DEPRECATED,
+						"strlen(): Passing null to parameter #1 ($string) of type string is deprecated");
+					ZVAL_LONG(EX_VAR(opline->result.var), 0);
+					if (UNEXPECTED(EG(exception))) {
+						HANDLE_EXCEPTION();
+					}
+					break;
+				}
+
+				ZVAL_COPY(&tmp, value);
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
+					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
+					zval_ptr_dtor(&tmp);
+					break;
+				}
+				zval_ptr_dtor(&tmp);
+			}
+			if (!EG(exception)) {
+				zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value));
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+		} while (0);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_CHECK_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	int result = 0;
+
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+type_check_resource:
+		if (opline->extended_value != MAY_BE_RESOURCE
+		 || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
+			result = 1;
+		}
+	} else if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) {
+		value = Z_REFVAL_P(value);
+		if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
+			goto type_check_resource;
+		}
+	} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		result = ((1 << IS_NULL) & opline->extended_value) != 0;
+		SAVE_OPLINE();
+		ZVAL_UNDEFINED_OP1();
+		if (UNEXPECTED(EG(exception))) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
+	if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+		SAVE_OPLINE();
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_SMART_BRANCH(result, 1);
+	} else {
+		ZEND_VM_SMART_BRANCH(result, 0);
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	uint32_t fetch_type;
+	zend_class_entry *called_scope, *scope;
+	USE_OPLINE
+
+	if (IS_TMP_VAR != IS_UNUSED) {
+		SAVE_OPLINE();
+		zval *op = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) {
+			ZVAL_DEREF(op);
+			if (Z_TYPE_P(op) != IS_OBJECT) {
+				zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				HANDLE_EXCEPTION();
+			}
+		}
+
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+
+	fetch_type = opline->op1.num;
+	if (zend_fetch_is_type_param(fetch_type)) {
+		SAVE_OPLINE();
+		zend_class_entry *resolved = zend_resolve_generic_type_param(
+			zend_unpack_type_param_index(fetch_type), fetch_type);
+		if (UNEXPECTED(!resolved)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), resolved->name);
+		ZEND_VM_NEXT_OPCODE();
+	}
+	scope = EX(func)->op_array.scope;
+	if (UNEXPECTED(scope == NULL)) {
+		SAVE_OPLINE();
+		zend_throw_error(NULL, "Cannot use \"%s\" in the global scope",
+			fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
+			fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
+		ZVAL_UNDEF(EX_VAR(opline->result.var));
+		HANDLE_EXCEPTION();
+	}
+
+	switch (fetch_type) {
+		case ZEND_FETCH_CLASS_SELF:
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
+			break;
+		case ZEND_FETCH_CLASS_PARENT:
+			if (UNEXPECTED(scope->parent == NULL)) {
+				SAVE_OPLINE();
+				zend_throw_error(NULL,
+					"Cannot use \"parent\" when current class scope has no parent");
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
+			break;
+		case ZEND_FETCH_CLASS_STATIC:
+			if (Z_TYPE(EX(This)) == IS_OBJECT) {
+				called_scope = Z_OBJCE(EX(This));
+			} else {
+				called_scope = Z_CE(EX(This));
+			}
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
+			break;
+		default: ZEND_UNREACHABLE();
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-				container = Z_REFVAL_P(container);
-				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-					break;
-				}
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
 			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP1();
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
 			}
-			zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-			ZVAL_NULL(EX_VAR(opline->result.var));
-			goto fetch_obj_r_finish;
-		} while (0);
+		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
+}
 
-	/* here we are sure we are dealing with an object */
-	do {
-		zend_object *zobj = Z_OBJ_P(container);
-		zend_string *name, *tmp_name;
-		zval *retval;
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
 
-		if (IS_CV == IS_CONST) {
-			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
-				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
 
-				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-fetch_obj_r_simple:
-					retval = OBJ_PROP(zobj, prop_offset);
-					if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_r_copy;
-						} else {
-fetch_obj_r_fast_copy:
-							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-							ZEND_VM_NEXT_OPCODE();
-						}
-					}
-				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
-					zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
-					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
-						prop_offset = prop_info->offset;
-						goto fetch_obj_r_simple;
-					} else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) {
-						zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET];
-						ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION);
-						ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
 
-						uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
-						if ((IS_TMP_VAR|IS_VAR) & IS_CV) {
-							GC_ADDREF(zobj);
-						}
-						if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) {
-							call_info |= ZEND_CALL_RELEASE_THIS;
-						}
-						zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj);
-						call->prev_execute_data = execute_data;
-						call->call = NULL;
-						call->return_value = EX_VAR(opline->result.var);
-						call->run_time_cache = RUN_TIME_CACHE(&hook->op_array);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
 
-						execute_data = call;
-						EG(current_execute_data) = execute_data;
-						zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC);
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_identical_function(op1, op2);
 
-#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
-						opline = hook->op_array.opcodes;
-#else
-						EX(opline) = hook->op_array.opcodes;
-#endif
-						LOAD_OPLINE_EX();
 
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
 
-						ZEND_VM_ENTER_EX();
-					}
-					/* Fall through to read_property for hooks. */
-				} else if (EXPECTED(zobj->properties != NULL)) {
-					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
-						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
 
-						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
-							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	result = fast_is_not_identical_function(op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-							if (EXPECTED(p->key == name) ||
-							    (EXPECTED(p->h == ZSTR_H(name)) &&
-							     EXPECTED(p->key != NULL) &&
-							     EXPECTED(zend_string_equal_content(p->key, name)))) {
-								retval = &p->val;
-								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-									goto fetch_obj_r_copy;
-								} else {
-									goto fetch_obj_r_fast_copy;
-								}
-							}
-						}
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
-					}
-					retval = zend_hash_find_known_hash(zobj->properties, name);
-					if (EXPECTED(retval)) {
-						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_r_copy;
-						} else {
-							goto fetch_obj_r_fast_copy;
-						}
-					}
-				}
+
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
 			}
-			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-			if (UNEXPECTED(!name)) {
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				break;
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
 			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
 		}
-
-#if ZEND_DEBUG
-		/* For non-standard object handlers, verify a declared property type in debug builds.
-		 * Fetch prop_info before calling read_property(), as it may deallocate the object. */
-		zend_property_info *prop_info = NULL;
-		if (zobj->handlers->read_property != zend_std_read_property) {
-			prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
 		}
-#endif
-		retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
-#if ZEND_DEBUG
-		if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
-				&& ZEND_TYPE_IS_SET(prop_info->type)) {
-			ZVAL_OPT_DEREF(retval);
-			zend_verify_property_type(prop_info, retval, /* strict */ true);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
 		}
-#endif
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
 
-		if (IS_CV != IS_CONST) {
-			zend_tmp_string_release(tmp_name);
-		}
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
 
-		if (retval != EX_VAR(opline->result.var)) {
-fetch_obj_r_copy:
-			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
-			zend_unwrap_reference(retval);
-		}
-	} while (0);
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-fetch_obj_r_finish:
 
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *container;
-	void **cache_slot = NULL;
+	zval *op1, *op2;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-				container = Z_REFVAL_P(container);
-				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-					break;
-				}
-			}
-			if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
-				ZVAL_UNDEFINED_OP2();
-			}
-			ZVAL_NULL(EX_VAR(opline->result.var));
-			goto fetch_obj_is_finish;
-		} while (0);
-	}
-
-	/* here we are sure we are dealing with an object */
-	do {
-		zend_object *zobj = Z_OBJ_P(container);
-		zend_string *name, *tmp_name;
-		zval *retval;
-
-		if (IS_CV == IS_CONST) {
-			cache_slot = CACHE_ADDR(opline->extended_value);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
-			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
-				uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
 
-				if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-fetch_obj_is_simple:
-					retval = OBJ_PROP(zobj, prop_offset);
-					if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_is_copy;
-						} else {
-fetch_obj_is_fast_copy:
-							ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-							ZEND_VM_NEXT_OPCODE();
-						}
-					}
-				} else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) {
-					if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) {
-						zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
-						prop_offset = prop_info->offset;
-						goto fetch_obj_is_simple;
-					}
-					/* Fall through to read_property for hooks. */
-				} else if (EXPECTED(zobj->properties != NULL)) {
-					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
-						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-						if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
-							Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
 
-							if (EXPECTED(p->key == name) ||
-							    (EXPECTED(p->h == ZSTR_H(name)) &&
-							     EXPECTED(p->key != NULL) &&
-							     EXPECTED(zend_string_equal_content(p->key, name)))) {
-								retval = &p->val;
-								if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-									goto fetch_obj_is_copy;
-								} else {
-									goto fetch_obj_is_fast_copy;
-								}
-							}
-						}
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
-					}
-					retval = zend_hash_find_known_hash(zobj->properties, name);
-					if (EXPECTED(retval)) {
-						uintptr_t idx = (char*)retval - (char*)zobj->properties->arData;
-						CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
-						if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) {
-							goto fetch_obj_is_copy;
-						} else {
-							goto fetch_obj_is_fast_copy;
-						}
-					}
-				}
-			}
-			name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-			if (UNEXPECTED(!name)) {
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				break;
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_CONST == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
 			}
 		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
 
-		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+#if 0
+	USE_OPLINE
+#endif
 
-		if (IS_CV != IS_CONST) {
-			zend_tmp_string_release(tmp_name);
+	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+		/* Behave like FETCH_OBJ_W */
+		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-
-		if (retval != EX_VAR(opline->result.var)) {
-fetch_obj_is_copy:
-			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-		} else if (UNEXPECTED(Z_ISREF_P(retval))) {
-			zend_unwrap_reference(retval);
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
 		}
-	} while (0);
-
-fetch_obj_is_finish:
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	zend_string *op1_str, *op2_str, *str;
 
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = EX_VAR(opline->op2.var);
-	if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
 		zend_string *op1_str = Z_STR_P(op1);
 		zend_string *op2_str = Z_STR_P(op2);
 		zend_string *str;
 		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CONST == IS_CONST || IS_CONST == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
+		} else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
 			}
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV &&
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
 		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
 			size_t len = ZSTR_LEN(op1_str);
 
@@ -19585,7 +72726,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
 			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else {
@@ -19594,10 +72735,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
 			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		}
@@ -19605,30 +72746,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
 	}
 
 	SAVE_OPLINE();
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		op1_str = Z_STR_P(op1);
 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
 		op1_str = zend_string_copy(Z_STR_P(op1));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
 			ZVAL_UNDEFINED_OP1();
 		}
 		op1_str = zval_get_string_func(op1);
 	}
-	if (IS_CV == IS_CONST) {
+	if (IS_CONST == IS_CONST) {
 		op2_str = Z_STR_P(op2);
 	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
 		op2_str = zend_string_copy(Z_STR_P(op2));
 	} else {
-		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
 			ZVAL_UNDEFINED_OP2();
 		}
 		op2_str = zval_get_string_func(op2);
 	}
 	do {
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-				if (IS_CV == IS_CONST) {
+				if (IS_CONST == IS_CONST) {
 					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
 						GC_ADDREF(op2_str);
 					}
@@ -19638,9 +72779,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
 				break;
 			}
 		}
-		if (IS_CV != IS_CONST) {
+		if (IS_CONST != IS_CONST) {
 			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+				if (IS_TMP_VAR == IS_CONST) {
 					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
 						GC_ADDREF(op1_str);
 					}
@@ -19656,19 +72797,117 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN
 
 		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
 		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_string_release_ex(op1_str, 0);
 		}
-		if (IS_CV != IS_CONST) {
+		if (IS_CONST != IS_CONST) {
 			zend_string_release_ex(op2_str, 0);
 		}
 	} while (0);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var;
+
+	/* op1 and result are the same */
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_CONST == IS_CONST) {
+		var = RT_CONSTANT(opline, opline->op2);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = RT_CONSTANT(opline, opline->op2);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CONST == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+
+
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_string **rope;
+	zval *var, *ret;
+	uint32_t i;
+
+	rope = (zend_string**)EX_VAR(opline->op1.var);
+	if (IS_CONST == IS_CONST) {
+		var = RT_CONSTANT(opline, opline->op2);
+		rope[opline->extended_value] = Z_STR_P(var);
+		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
+			Z_ADDREF_P(var);
+		}
+	} else {
+		var = RT_CONSTANT(opline, opline->op2);
+		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
+			if (IS_CONST == IS_CV) {
+				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+			} else {
+				rope[opline->extended_value] = Z_STR_P(var);
+			}
+		} else {
+			SAVE_OPLINE();
+			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+			}
+			rope[opline->extended_value] = zval_get_string_func(var);
+
+
+			if (UNEXPECTED(EG(exception))) {
+				for (i = 0; i <= opline->extended_value; i++) {
+					zend_string_release_ex(rope[i], 0);
+				}
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		}
+	}
+
+	size_t len = 0;
+	uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
+	for (i = 0; i <= opline->extended_value; i++) {
+		flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
+		len += ZSTR_LEN(rope[i]);
+	}
+	ret = EX_VAR(opline->result.var);
+	ZVAL_STR(ret, zend_string_alloc(len, 0));
+	GC_ADD_FLAGS(Z_STR_P(ret), flags);
+
+	char *target = Z_STRVAL_P(ret);
+	for (i = 0; i <= opline->extended_value; i++) {
+		memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
+		target += ZSTR_LEN(rope[i]);
+		zend_string_release_ex(rope[i], 0);
+	}
+	*target = '\0';
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -19681,21 +72920,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
 
 	SAVE_OPLINE();
 
-	object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-	if (IS_CV != IS_CONST) {
-		function_name = EX_VAR(opline->op2.var);
+	if (IS_CONST != IS_CONST) {
+		function_name = RT_CONSTANT(opline, opline->op2);
 	}
 
-	if (IS_CV != IS_CONST &&
+	if (IS_CONST != IS_CONST &&
 	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
 		do {
-			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+			if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
 				function_name = Z_REFVAL_P(function_name);
 				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 					break;
 				}
-			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+			} else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -19704,25 +72943,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 
+
 			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+	if (IS_TMP_VAR == IS_UNUSED) {
 		obj = Z_OBJ_P(object);
 	} else {
 		do {
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+			if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
 				obj = Z_OBJ_P(object);
 			} else {
-				if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+				if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
 					zend_reference *ref = Z_REF_P(object);
 
 					object = &ref->val;
 					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
 						obj = Z_OBJ_P(object);
-						if ((IS_TMP_VAR|IS_VAR) & IS_VAR) {
+						if (IS_TMP_VAR & IS_VAR) {
 							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
 								efree_size(ref, sizeof(zend_reference));
 							} else {
@@ -19732,20 +72972,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
 						break;
 					}
 				}
-				if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
 					object = ZVAL_UNDEFINED_OP1();
 					if (UNEXPECTED(EG(exception) != NULL)) {
-						if (IS_CV != IS_CONST) {
+						if (IS_CONST != IS_CONST) {
+
 
 						}
 						HANDLE_EXCEPTION();
 					}
 				}
-				if (IS_CV == IS_CONST) {
-					function_name = EX_VAR(opline->op2.var);
+				if (IS_CONST == IS_CONST) {
+					function_name = RT_CONSTANT(opline, opline->op2);
 				}
 				zend_invalid_method_call(object, function_name);
 
+
 				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 				HANDLE_EXCEPTION();
 			}
@@ -19754,34 +72996,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
 
 	called_scope = obj->ce;
 
-	if (IS_CV == IS_CONST &&
+	if (IS_CONST == IS_CONST &&
 	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
 		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
 	} else {
 		zend_object *orig_obj = obj;
 
-		if (IS_CV == IS_CONST) {
-			function_name = EX_VAR(opline->op2.var);
+		if (IS_CONST == IS_CONST) {
+			function_name = RT_CONSTANT(opline, opline->op2);
 		}
 
 		/* First, locate the function. */
-		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
 		if (UNEXPECTED(fbc == NULL)) {
 			if (EXPECTED(!EG(exception))) {
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
 			}
 
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+
+			if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
 				zend_objects_store_del(orig_obj);
 			}
 			HANDLE_EXCEPTION();
 		}
-		if (IS_CV == IS_CONST &&
+		if (IS_CONST == IS_CONST &&
 		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
 		    EXPECTED(obj == orig_obj)) {
 			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
 		}
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
 			GC_ADDREF(obj); /* For $this pointer */
 			if (GC_DELREF(orig_obj) == 0) {
 				zend_objects_store_del(orig_obj);
@@ -19792,13 +73035,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
 		}
 	}
 
-	if (IS_CV != IS_CONST) {
+	if (IS_CONST != IS_CONST) {
+
 
 	}
 
 	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
 	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
 			zend_objects_store_del(obj);
 			if (UNEXPECTED(EG(exception))) {
 				HANDLE_EXCEPTION();
@@ -19807,8 +73051,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
 		/* call static method */
 		obj = (zend_object*)called_scope;
 		call_info = ZEND_CALL_NESTED_FUNCTION;
-	} else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+	} else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_TMP_VAR == IS_CV) {
 			GC_ADDREF(obj); /* For $this pointer */
 		}
 		/* CV may be changed indirectly (e.g. when it's a reference) */
@@ -19823,14 +73067,51 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value, *arg;
+	uint32_t arg_num;
+
+	if (IS_CONST == IS_CONST) {
+		SAVE_OPLINE();
+		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
+		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
+		if (UNEXPECTED(!arg)) {
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		}
+	} else {
+		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+		arg_num = opline->op2.num;
+	}
+
+	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+			goto send_val_by_ref;
+		}
+	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+	}
+	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	ZVAL_COPY_VALUE(arg, value);
+	if (IS_TMP_VAR == IS_CONST) {
+		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
+			Z_ADDREF_P(arg);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	double d1, d2;
 
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	op2 = EX_VAR(opline->op2.var);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = RT_CONSTANT(opline, opline->op2);
 	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
 			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
@@ -19864,17 +73145,151 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE
 		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
 			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
 
-			if (result) {
-				goto case_true;
-			} else {
-				goto case_false;
-			}
+
+			if (result) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = zend_get_bad_ptr();
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	} else {
+		expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_TMP_VAR == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_TMP_VAR == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_TMP_VAR == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
+			}
+		}
+	}
+
+	if (IS_CONST != IS_UNUSED) {
+		zval *offset = RT_CONSTANT(opline, opline->op2);
+		zend_string *str;
+		zend_ulong hval;
+
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CONST != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
+			}
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
 	}
-	ZEND_VM_TAIL_CALL(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -19883,8 +73298,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
 	zval *offset;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = EX_VAR(opline->op2.var);
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = RT_CONSTANT(opline, opline->op2);
 
 	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 		HashTable *ht;
@@ -19896,17 +73311,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
 isset_again:
 		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 			str = Z_STR_P(offset);
-			if (IS_CV != IS_CONST) {
+			if (IS_CONST != IS_CONST) {
 				if (ZEND_HANDLE_NUMERIC(str, hval)) {
 					goto num_index_prop;
 				}
 			}
-			value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST);
+			value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST);
 		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
 			hval = Z_LVAL_P(offset);
 num_index_prop:
 			value = zend_hash_index_find(ht, hval);
-		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
 			offset = Z_REFVAL_P(offset);
 			goto isset_again;
 		} else {
@@ -19922,23 +73337,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
 			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
 			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
 
-			if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) {
+			if (IS_TMP_VAR & (IS_CONST|IS_CV)) {
 				/* avoid exception check */
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		} else {
 			result = (value == NULL || !i_zend_is_true(value));
 		}
 		goto isset_dim_obj_exit;
-	} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
 		container = Z_REFVAL_P(container);
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 			goto isset_dim_obj_array;
 		}
 	}
 
-	if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+	if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
 		offset++;
 	}
 	if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -19949,11 +73365,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
 
 isset_dim_obj_exit:
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -19962,12 +73379,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
 	zend_string *name, *tmp_name;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = RT_CONSTANT(opline, opline->op2);
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST ||
-	    ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+	if (IS_TMP_VAR == IS_CONST ||
+	    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
 			container = Z_REFVAL_P(container);
 			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
 				result = (opline->extended_value & ZEND_ISEMPTY);
@@ -19979,673 +73396,430 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM
 		}
 	}
 
-	if (IS_CV == IS_CONST) {
+	if (IS_CONST == IS_CONST) {
 		name = Z_STR_P(offset);
 	} else {
 		name = zval_try_get_tmp_string(offset, &tmp_name);
 		if (UNEXPECTED(!name)) {
 			result = 0;
-			goto isset_object_finish;
-		}
-	}
-
-	result =
-		(opline->extended_value & ZEND_ISEMPTY) ^
-		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
-
-	if (IS_CV != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-isset_object_finish:
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-
-	zval *key, *subject;
-	HashTable *ht;
-	bool result;
-
-	SAVE_OPLINE();
-
-	key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	subject = EX_VAR(opline->op2.var);
-
-	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-array_key_exists_array:
-		ht = Z_ARRVAL_P(subject);
-		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
-	} else {
-		if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
-			subject = Z_REFVAL_P(subject);
-			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-				goto array_key_exists_array;
-			}
-		}
-		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
-		result = 0;
-	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *retval_ptr;
-	zval *return_value;
-
-	retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	return_value = EX(return_value);
-
-	if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
-		SAVE_OPLINE();
-		retval_ptr = ZVAL_UNDEFINED_OP1();
-		if (return_value) {
-			ZVAL_NULL(return_value);
-		}
-	} else if (!return_value) {
-		if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) {
-			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
-				SAVE_OPLINE();
-				rc_dtor_func(Z_COUNTED_P(retval_ptr));
-			}
-		}
-	} else {
-		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZVAL_COPY_VALUE(return_value, retval_ptr);
-			if (IS_TMP_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
-					Z_ADDREF_P(return_value);
-				}
-			}
-		} else if (IS_TMP_VAR == IS_CV) {
-			do {
-				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
-						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
-							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
-							ZVAL_COPY_VALUE(return_value, retval_ptr);
-							if (GC_MAY_LEAK(ref)) {
-								SAVE_OPLINE();
-								gc_possible_root(ref);
-							}
-							ZVAL_NULL(retval_ptr);
-							break;
-						} else {
-							Z_ADDREF_P(retval_ptr);
-						}
-					} else {
-						retval_ptr = Z_REFVAL_P(retval_ptr);
-						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-							Z_ADDREF_P(retval_ptr);
-						}
-					}
-				}
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-			} while (0);
-		} else /* if (IS_TMP_VAR == IS_VAR) */ {
-			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
-				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
-
-				retval_ptr = Z_REFVAL_P(retval_ptr);
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-					efree_size(ref, sizeof(zend_reference));
-				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-					Z_ADDREF_P(retval_ptr);
-				}
-			} else {
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-			}
-		}
-	}
-
-
-
-	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *retval_ptr;
-	zval *return_value;
-
-	SAVE_OPLINE();
-
-	return_value = EX(return_value);
-
-	do {
-		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) ||
-		    (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
-			/* Not supposed to happen, but we'll allow it */
-			zend_error(E_NOTICE, "Only variable references should be returned by reference");
-
-			retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-			if (!return_value) {
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			} else {
-				if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
-					ZVAL_COPY_VALUE(return_value, retval_ptr);
-					break;
-				}
-
-				ZVAL_NEW_REF(return_value, retval_ptr);
-				if (IS_TMP_VAR == IS_CONST) {
-					Z_TRY_ADDREF_P(retval_ptr);
-				}
-			}
-			break;
-		}
-
-		retval_ptr = zend_get_bad_ptr();
-
-		if (IS_TMP_VAR == IS_VAR) {
-			ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
-			if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
-				zend_error(E_NOTICE, "Only variable references should be returned by reference");
-				if (return_value) {
-					ZVAL_NEW_REF(return_value, retval_ptr);
-				} else {
-					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				}
-				break;
-			}
-		}
-
-		if (return_value) {
-			if (Z_ISREF_P(retval_ptr)) {
-				Z_ADDREF_P(retval_ptr);
-			} else {
-				ZVAL_MAKE_REF_EX(retval_ptr, 2);
-			}
-			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
-		}
-
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	} while (0);
-
-
-	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *retval;
-
-	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
-
-	SAVE_OPLINE();
-	retval = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-
-	/* Copy return value into generator->retval */
-	if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-		ZVAL_COPY_VALUE(&generator->retval, retval);
-		if (IS_TMP_VAR == IS_CONST) {
-			if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) {
-				Z_ADDREF(generator->retval);
-			}
-		}
-	} else if (IS_TMP_VAR == IS_CV) {
-		ZVAL_COPY_DEREF(&generator->retval, retval);
-	} else /* if (IS_TMP_VAR == IS_VAR) */ {
-		if (UNEXPECTED(Z_ISREF_P(retval))) {
-			zend_refcounted *ref = Z_COUNTED_P(retval);
-
-			retval = Z_REFVAL_P(retval);
-			ZVAL_COPY_VALUE(&generator->retval, retval);
-			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-				efree_size(ref, sizeof(zend_reference));
-			} else if (Z_OPT_REFCOUNTED_P(retval)) {
-				Z_ADDREF_P(retval);
-			}
-		} else {
-			ZVAL_COPY_VALUE(&generator->retval, retval);
-		}
-	}
-
-	EG(current_execute_data) = EX(prev_execute_data);
-
-	/* Close the generator to free up resources */
-	zend_generator_close(generator, 1);
-
-	/* Pass execution back to handling code */
-	ZEND_VM_RETURN();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *arg, *param;
-
-	SAVE_OPLINE();
-
-	arg = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	param = ZEND_CALL_VAR(EX(call), opline->result.var);
-	if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
-		zend_param_must_be_ref(EX(call)->func, opline->op2.num);
-		Z_TRY_ADDREF_P(arg);
-		ZVAL_NEW_REF(param, arg);
-	} else {
-		ZVAL_COPY(param, arg);
-	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *expr;
-	zval *result = EX_VAR(opline->result.var);
-
-	SAVE_OPLINE();
-	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-
-	switch (opline->extended_value) {
-		case IS_LONG:
-			ZVAL_LONG(result, zval_get_long(expr));
-			break;
-		case IS_DOUBLE:
-			ZVAL_DOUBLE(result, zval_get_double(expr));
-			break;
-		case IS_STRING:
-			ZVAL_STR(result, zval_get_string(expr));
-			break;
-		default:
-			ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead");
-			if (IS_TMP_VAR & (IS_VAR|IS_CV)) {
-				ZVAL_DEREF(expr);
-			}
-			/* If value is already of correct type, return it directly */
-			if (Z_TYPE_P(expr) == opline->extended_value) {
-				ZVAL_COPY_VALUE(result, expr);
-				if (IS_TMP_VAR == IS_CONST) {
-					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
-				} else if (IS_TMP_VAR != IS_TMP_VAR) {
-					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
-				}
-
-				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-			}
-
-			if (opline->extended_value == IS_ARRAY) {
-				zend_cast_zval_to_array(result, expr, IS_TMP_VAR);
-			} else {
-				ZEND_ASSERT(opline->extended_value == IS_OBJECT);
-				zend_cast_zval_to_object(result, expr, IS_TMP_VAR);
-			}
-	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *array_ptr, *result;
-
-	SAVE_OPLINE();
-
-	array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
-		result = EX_VAR(opline->result.var);
-		ZVAL_COPY_VALUE(result, array_ptr);
-		if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
-			Z_ADDREF_P(array_ptr);
-		}
-		Z_FE_POS_P(result) = 0;
-
-		ZEND_VM_NEXT_OPCODE();
-	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
-		zend_object *zobj = Z_OBJ_P(array_ptr);
-		if (!zobj->ce->get_iterator) {
-			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
-				zobj = zend_lazy_object_init(zobj);
-				if (UNEXPECTED(EG(exception))) {
-					UNDEF_RESULT();
-
-					HANDLE_EXCEPTION();
-				}
-			}
-			HashTable *properties = zobj->properties;
-			if (properties) {
-				if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
-					if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
-						GC_DELREF(properties);
-					}
-					properties = zobj->properties = zend_array_dup(properties);
-				}
-			} else {
-				properties = zobj->handlers->get_properties(zobj);
-			}
-
-			result = EX_VAR(opline->result.var);
-			ZVAL_COPY_VALUE(result, array_ptr);
-			if (IS_TMP_VAR != IS_TMP_VAR) {
-				Z_ADDREF_P(array_ptr);
-			}
-
-			if (zend_hash_num_elements(properties) == 0) {
-				Z_FE_ITER_P(result) = (uint32_t) -1;
-
-				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
-			}
-
-			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
-
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		} else {
-			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			} else if (is_empty) {
-				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-			} else {
-				ZEND_VM_NEXT_OPCODE();
-			}
-		}
-	} else {
-		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
-		ZVAL_UNDEF(EX_VAR(opline->result.var));
-		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
-	}
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *array_ptr, *array_ref;
-
-	SAVE_OPLINE();
-
-	if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-		array_ref = array_ptr = zend_get_bad_ptr();
-		if (Z_ISREF_P(array_ref)) {
-			array_ptr = Z_REFVAL_P(array_ref);
-		}
-	} else {
-		array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	}
-
-	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
-		if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-			if (array_ptr == array_ref) {
-				ZVAL_NEW_REF(array_ref, array_ref);
-				array_ptr = Z_REFVAL_P(array_ref);
-			}
-			Z_ADDREF_P(array_ref);
-			ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
-		} else {
-			array_ref = EX_VAR(opline->result.var);
-			ZVAL_NEW_REF(array_ref, array_ptr);
-			array_ptr = Z_REFVAL_P(array_ref);
-		}
-		if (IS_TMP_VAR == IS_CONST) {
-			ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr)));
-		} else {
-			SEPARATE_ARRAY(array_ptr);
-		}
-		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
-
-		ZEND_VM_NEXT_OPCODE();
-	} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
-		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
-			zend_object *zobj = Z_OBJ_P(array_ptr);
-			HashTable *properties;
-			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
-				zobj = zend_lazy_object_init(zobj);
-				if (UNEXPECTED(EG(exception))) {
-					UNDEF_RESULT();
-
-					HANDLE_EXCEPTION();
-				}
-			}
-			if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
-				if (array_ptr == array_ref) {
-					ZVAL_NEW_REF(array_ref, array_ref);
-					array_ptr = Z_REFVAL_P(array_ref);
-				}
-				Z_ADDREF_P(array_ref);
-				ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
-			} else {
-				array_ptr = EX_VAR(opline->result.var);
-				ZVAL_COPY_VALUE(array_ptr, array_ref);
-			}
-			if (Z_OBJ_P(array_ptr)->properties
-			 && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
-				if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
-					GC_DELREF(Z_OBJ_P(array_ptr)->properties);
-				}
-				Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
-			}
-
-			properties = Z_OBJPROP_P(array_ptr);
-			if (zend_hash_num_elements(properties) == 0) {
-				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
-
-				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
-			}
-
-			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
-
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		} else {
-			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			} else if (is_empty) {
-				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-			} else {
-				ZEND_VM_NEXT_OPCODE();
-			}
-		}
-	} else {
-		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
-		ZVAL_UNDEF(EX_VAR(opline->result.var));
-		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+			goto isset_object_finish;
+		}
 	}
-}
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
 
-	if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))
-			&& !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) {
-		EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var));
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
 	}
-	ZEND_VM_NEXT_OPCODE();
+
+isset_object_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value;
-	zend_reference *ref = NULL;
-	bool ret;
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
 
 	SAVE_OPLINE();
-	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) {
-		if (IS_TMP_VAR == IS_VAR) {
-			ref = Z_REF_P(value);
+	key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	subject = RT_CONSTANT(opline, opline->op2);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
 		}
-		value = Z_REFVAL_P(value);
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
 	}
 
-	ret = i_zend_is_true(value);
 
-	if (UNEXPECTED(EG(exception))) {
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZVAL_UNDEF(EX_VAR(opline->result.var));
-		HANDLE_EXCEPTION();
-	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
 
-	if (ret) {
-		zval *result = EX_VAR(opline->result.var);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
 
-		ZVAL_COPY_VALUE(result, value);
-		if (IS_TMP_VAR == IS_CONST) {
-			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
-		} else if (IS_TMP_VAR == IS_CV) {
-			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
-		} else if (IS_TMP_VAR == IS_VAR && ref) {
-			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-				efree_size(ref, sizeof(zend_reference));
-			} else if (Z_OPT_REFCOUNTED_P(result)) {
-				Z_ADDREF_P(result);
+	SAVE_OPLINE();
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_CONST == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_CONST == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
 			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
 		}
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
 	}
-
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE();
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value;
-	zend_reference *ref = NULL;
 
-	SAVE_OPLINE();
-	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
 
-	if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
-		if (IS_TMP_VAR & IS_VAR) {
-			ref = Z_REF_P(value);
-		}
-		value = Z_REFVAL_P(value);
+	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
-	if (Z_TYPE_P(value) > IS_NULL) {
-		zval *result = EX_VAR(opline->result.var);
-		ZVAL_COPY_VALUE(result, value);
-		if (IS_TMP_VAR == IS_CONST) {
-			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
-		} else if (IS_TMP_VAR == IS_CV) {
-			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
-		} else if ((IS_TMP_VAR & IS_VAR) && ref) {
-			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-				efree_size(ref, sizeof(zend_reference));
-			} else if (Z_OPT_REFCOUNTED_P(result)) {
-				Z_ADDREF_P(result);
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
+
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
+
+	/* Set the new yielded value */
+	if (IS_TMP_VAR != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
+			} else {
+				zval *value_ptr = zend_get_bad_ptr();
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_TMP_VAR == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			}
+		} else {
+			zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
+			if (IS_TMP_VAR == IS_CONST) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_TMP_VAR == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
+			} else {
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_TMP_VAR == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
 			}
 		}
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	} else {
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
 	}
 
-	if ((IS_TMP_VAR & IS_VAR) && ref) {
-		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-			efree_size(ref, sizeof(zend_reference));
+	/* Set the new yielded key */
+	if (IS_CONST != IS_UNUSED) {
+		zval *key = RT_CONSTANT(opline, opline->op2);
+		if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
+
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
 		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
 	}
-	ZEND_VM_NEXT_OPCODE();
+
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IN_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *val, *result;
-
-	val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	zval *op1;
+	HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
+	zval *result;
 
-	if (Z_TYPE_P(val) > IS_NULL) {
-		do {
-			if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) {
-				val = Z_REFVAL_P(val);
-				if (Z_TYPE_P(val) <= IS_NULL) {
-					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-					break;
-				}
-			}
-			ZEND_VM_NEXT_OPCODE();
-		} while (0);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST);
+		if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+			zval_ptr_dtor_str(op1);
+		}
+		ZEND_VM_SMART_BRANCH(result, 0);
 	}
 
-	result = EX_VAR(opline->result.var);
-	uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK;
-	if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) {
-		ZVAL_NULL(result);
-		if (IS_TMP_VAR == IS_CV
-			&& UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)
-			&& (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0
-		) {
+	if (opline->extended_value) {
+		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+			result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+			ZEND_VM_SMART_BRANCH(result, 0);
+		}
+		SAVE_OPLINE();
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+	} else if (Z_TYPE_P(op1) <= IS_FALSE) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
 			SAVE_OPLINE();
 			ZVAL_UNDEFINED_OP1();
 			if (UNEXPECTED(EG(exception) != NULL)) {
 				HANDLE_EXCEPTION();
 			}
 		}
-	} else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) {
-		ZVAL_FALSE(result);
+		result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC());
+		ZEND_VM_SMART_BRANCH(result, 0);
 	} else {
-		ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY);
-		ZVAL_TRUE(result);
+		zend_string *key;
+		zval key_tmp;
+
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+				result = zend_hash_find(ht, Z_STR_P(op1));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		}
+
+		SAVE_OPLINE();
+		ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) {
+			ZVAL_STR(&key_tmp, key);
+			if (zend_compare(op1, &key_tmp) == 0) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZEND_VM_SMART_BRANCH(1, 1);
+			}
+		} ZEND_HASH_FOREACH_END();
 	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(0, 1);
+}
 
-	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value;
-	zval *result = EX_VAR(opline->result.var);
+	zval *op1, *op2;
 
-	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-		SAVE_OPLINE();
-		ZVAL_UNDEFINED_OP1();
-		ZVAL_NULL(result);
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-	}
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	if (IS_TMP_VAR == IS_CV) {
-		ZVAL_COPY_DEREF(result, value);
-	} else if (IS_TMP_VAR == IS_VAR) {
-		if (UNEXPECTED(Z_ISREF_P(value))) {
-			ZVAL_COPY_VALUE(result, Z_REFVAL_P(value));
-			if (UNEXPECTED(Z_DELREF_P(value) == 0)) {
-				efree_size(Z_REF_P(value), sizeof(zend_reference));
-			} else if (Z_OPT_REFCOUNTED_P(result)) {
-				Z_ADDREF_P(result);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
 			}
 		} else {
-			ZVAL_COPY_VALUE(result, value);
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
 		}
+		ZEND_VM_NEXT_OPCODE();
 	} else {
-		ZVAL_COPY_VALUE(result, value);
-		if (IS_TMP_VAR == IS_CONST) {
-			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) {
-				Z_ADDREF_P(result);
-			}
+		SAVE_OPLINE();
+
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
 		}
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
-	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -20653,14 +73827,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HA
 
 	SAVE_OPLINE();
 	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = fast_is_identical_function(op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -20668,13 +73842,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_CONST_HAN
 
 	SAVE_OPLINE();
 	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = fast_is_identical_function(op1, op2);
-
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -20682,492 +73856,390 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONS
 
 	SAVE_OPLINE();
 	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = fast_is_not_identical_function(op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-#if 0
-	USE_OPLINE
-#endif
-
-	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
-		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	} else {
-		if (IS_CONST == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	}
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-#if 0
-	USE_OPLINE
-#endif
-
-	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
-		/* Behave like FETCH_OBJ_W */
-		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	}
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zend_string **rope;
-	zval *var;
+	zval *op1, *op2;
+	double d1, d2;
 
-	/* op1 and result are the same */
-	rope = (zend_string**)EX_VAR(opline->op1.var);
-	if (IS_CONST == IS_CONST) {
-		var = RT_CONSTANT(opline, opline->op2);
-		rope[opline->extended_value] = Z_STR_P(var);
-		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
-			Z_ADDREF_P(var);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
 		}
-	} else {
-		var = RT_CONSTANT(opline, opline->op2);
-		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
-			if (IS_CONST == IS_CV) {
-				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
 			} else {
-				rope[opline->extended_value] = Z_STR_P(var);
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
 			}
-		} else {
-			SAVE_OPLINE();
-			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP2();
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
 			}
-			rope[opline->extended_value] = zval_get_string_func(var);
-
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
 	}
-	ZEND_VM_NEXT_OPCODE();
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zend_string **rope;
-	zval *var, *ret;
-	uint32_t i;
+	zval *op1, *op2;
+	double d1, d2;
 
-	rope = (zend_string**)EX_VAR(opline->op1.var);
-	if (IS_CONST == IS_CONST) {
-		var = RT_CONSTANT(opline, opline->op2);
-		rope[opline->extended_value] = Z_STR_P(var);
-		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
-			Z_ADDREF_P(var);
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
 		}
-	} else {
-		var = RT_CONSTANT(opline, opline->op2);
-		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
-			if (IS_CONST == IS_CV) {
-				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
 			} else {
-				rope[opline->extended_value] = Z_STR_P(var);
+				goto is_equal_false;
 			}
-		} else {
-			SAVE_OPLINE();
-			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP2();
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
 			}
-			rope[opline->extended_value] = zval_get_string_func(var);
-
-			if (UNEXPECTED(EG(exception))) {
-				for (i = 0; i <= opline->extended_value; i++) {
-					zend_string_release_ex(rope[i], 0);
-				}
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
 			}
 		}
 	}
-
-	size_t len = 0;
-	uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
-	for (i = 0; i <= opline->extended_value; i++) {
-		flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
-		len += ZSTR_LEN(rope[i]);
-	}
-	ret = EX_VAR(opline->result.var);
-	ZVAL_STR(ret, zend_string_alloc(len, 0));
-	GC_ADD_FLAGS(Z_STR_P(ret), flags);
-
-	char *target = Z_STRVAL_P(ret);
-	for (i = 0; i <= opline->extended_value; i++) {
-		memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
-		target += ZSTR_LEN(rope[i]);
-		zend_string_release_ex(rope[i], 0);
-	}
-	*target = '\0';
-
-	ZEND_VM_NEXT_OPCODE();
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value, *arg;
-	uint32_t arg_num;
+	zval *op1, *op2;
+	double d1, d2;
 
-	if (IS_CONST == IS_CONST) {
-		SAVE_OPLINE();
-		zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
-		if (UNEXPECTED(!arg)) {
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			HANDLE_EXCEPTION();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+is_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
+			} else {
+is_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_equal_double;
 		}
-	} else {
-		arg = ZEND_CALL_VAR(EX(call), opline->result.var);
-		arg_num = opline->op2.num;
-	}
-
-	if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
-		if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-			goto send_val_by_ref;
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_equal_double:
+			if (d1 == d2) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_equal_double;
 		}
-	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-send_val_by_ref:
-		ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
-	}
-	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	ZVAL_COPY_VALUE(arg, value);
-	if (IS_TMP_VAR == IS_CONST) {
-		if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) {
-			Z_ADDREF_P(arg);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (result) {
+				goto is_equal_true;
+			} else {
+				goto is_equal_false;
+			}
 		}
 	}
-	ZEND_VM_NEXT_OPCODE();
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *expr_ptr, new_expr;
-
-	SAVE_OPLINE();
-	if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
-	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
-		expr_ptr = zend_get_bad_ptr();
-		if (Z_ISREF_P(expr_ptr)) {
-			Z_ADDREF_P(expr_ptr);
-		} else {
-			ZVAL_MAKE_REF_EX(expr_ptr, 2);
-		}
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	} else {
-		expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-		if (IS_TMP_VAR == IS_TMP_VAR) {
-			/* pass */
-		} else if (IS_TMP_VAR == IS_CONST) {
-			Z_TRY_ADDREF_P(expr_ptr);
-		} else if (IS_TMP_VAR == IS_CV) {
-			ZVAL_DEREF(expr_ptr);
-			Z_TRY_ADDREF_P(expr_ptr);
-		} else /* if (IS_TMP_VAR == IS_VAR) */ {
-			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
-				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+	zval *op1, *op2;
+	double d1, d2;
 
-				expr_ptr = Z_REFVAL_P(expr_ptr);
-				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
-					expr_ptr = &new_expr;
-					efree_size(ref, sizeof(zend_reference));
-				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
-					Z_ADDREF_P(expr_ptr);
-				}
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_NONE();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_NONE();
 			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
 		}
-	}
-
-	if (IS_CONST != IS_UNUSED) {
-		zval *offset = RT_CONSTANT(opline, opline->op2);
-		zend_string *str;
-		zend_ulong hval;
-
-add_again:
-		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
-			str = Z_STR_P(offset);
-			if (IS_CONST != IS_CONST) {
-				if (ZEND_HANDLE_NUMERIC(str, hval)) {
-					goto num_index;
-				}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
 			}
-str_index:
-			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
-		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
-			hval = Z_LVAL_P(offset);
-num_index:
-			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
-		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
-			offset = Z_REFVAL_P(offset);
-			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
-			str = ZSTR_EMPTY_ALLOC();
-			goto str_index;
-		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
-			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
-			goto num_index;
-		} else if (Z_TYPE_P(offset) == IS_FALSE) {
-			hval = 0;
-			goto num_index;
-		} else if (Z_TYPE_P(offset) == IS_TRUE) {
-			hval = 1;
-			goto num_index;
-		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
-			zend_use_resource_as_offset(offset);
-			hval = Z_RES_HANDLE_P(offset);
-			goto num_index;
-		} else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
-			ZVAL_UNDEFINED_OP2();
-			str = ZSTR_EMPTY_ALLOC();
-			goto str_index;
-		} else {
-			zend_illegal_array_offset_access(offset);
-			zval_ptr_dtor_nogc(expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
 		}
-
-	} else {
-		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
-			zend_cannot_add_element();
-			zval_ptr_dtor_nogc(expr_ptr);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
 		}
 	}
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	zval *array;
-	uint32_t size;
 	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
 
-	SAVE_OPLINE();
-	array = EX_VAR(opline->result.var);
-	if (IS_TMP_VAR != IS_UNUSED) {
-		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-		ZVAL_ARR(array, zend_new_array(size));
-		/* Explicitly initialize array as not-packed if flag is set */
-		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
-			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPZ();
+			} else {
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPZ();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	} else {
-		ZVAL_ARR(array, zend_new_array(0));
-		ZEND_VM_NEXT_OPCODE();
 	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
 
-	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
-
-	SAVE_OPLINE();
-	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	}
-
-	/* Destroy the previously yielded value */
-	zval_ptr_dtor(&generator->value);
-
-	/* Destroy the previously yielded key */
-	zval_ptr_dtor(&generator->key);
-
-	/* Set the new yielded value */
-	if (IS_TMP_VAR != IS_UNUSED) {
-		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
-			/* Constants and temporary variables aren't yieldable by reference,
-			 * but we still allow them with a notice. */
-			if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) {
-				zval *value;
-
-				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
-
-				value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-				ZVAL_COPY_VALUE(&generator->value, value);
-				if (IS_TMP_VAR == IS_CONST) {
-					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
-						Z_ADDREF(generator->value);
-					}
-				}
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) {
+		/* pass */
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) {
+is_not_equal_true:
+				ZEND_VM_SMART_BRANCH_TRUE_JMPNZ();
 			} else {
-				zval *value_ptr = zend_get_bad_ptr();
-
-				/* If a function call result is yielded and the function did
-				 * not return by reference we throw a notice. */
-				do {
-					if (IS_TMP_VAR == IS_VAR) {
-						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
-						if (opline->extended_value == ZEND_RETURNS_FUNCTION
-						 && !Z_ISREF_P(value_ptr)) {
-							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
-							ZVAL_COPY(&generator->value, value_ptr);
-							break;
-						}
-					}
-					if (Z_ISREF_P(value_ptr)) {
-						Z_ADDREF_P(value_ptr);
-					} else {
-						ZVAL_MAKE_REF_EX(value_ptr, 2);
-					}
-					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
-				} while (0);
-
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+is_not_equal_false:
+				ZEND_VM_SMART_BRANCH_FALSE_JMPNZ();
 			}
-		} else {
-			zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-
-			/* Consts, temporary variables and references need copying */
-			if (IS_TMP_VAR == IS_CONST) {
-				ZVAL_COPY_VALUE(&generator->value, value);
-				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
-					Z_ADDREF(generator->value);
-				}
-			} else if (IS_TMP_VAR == IS_TMP_VAR) {
-				ZVAL_COPY_VALUE(&generator->value, value);
-			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
-				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
-
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto is_not_equal_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+is_not_equal_double:
+			if (d1 != d2) {
+				goto is_not_equal_true;
 			} else {
-				ZVAL_COPY_VALUE(&generator->value, value);
-				if (IS_TMP_VAR == IS_CV) {
-					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
-				}
+				goto is_not_equal_false;
 			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto is_not_equal_double;
 		}
-	} else {
-		/* If no value was specified yield null */
-		ZVAL_NULL(&generator->value);
-	}
-
-	/* Set the new yielded key */
-	if (IS_CONST != IS_UNUSED) {
-		zval *key = RT_CONSTANT(opline, opline->op2);
-		if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
-			key = Z_REFVAL_P(key);
-		}
-		ZVAL_COPY(&generator->key, key);
-
-		if (Z_TYPE(generator->key) == IS_LONG
-		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
-		) {
-			generator->largest_used_integer_key = Z_LVAL(generator->key);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op1);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zval_ptr_dtor_str(op2);
+			}
+			if (!result) {
+				goto is_not_equal_true;
+			} else {
+				goto is_not_equal_false;
+			}
 		}
-	} else {
-		/* If no key was specified we use auto-increment keys */
-		generator->largest_used_integer_key++;
-		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
-	}
-
-	if (RETURN_VALUE_USED(opline)) {
-		/* If the return value of yield is used set the send
-		 * target and initialize it to NULL */
-		generator->send_target = EX_VAR(opline->result.var);
-		ZVAL_NULL(generator->send_target);
-	} else {
-		generator->send_target = NULL;
 	}
-
-	/* The GOTO VM uses a local opline variable. We need to set the opline
-	 * variable in execute_data so we don't resume at an old position. */
-	SAVE_OPLINE();
-
-	ZEND_VM_RETURN();
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1;
-	HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
-	zval *result;
+	zval *op1, *op2;
 
+	SAVE_OPLINE();
 	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST);
-		if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
-			zval_ptr_dtor_str(op1);
-		}
-		ZEND_VM_SMART_BRANCH(result, 0);
-	}
-
-	if (opline->extended_value) {
-		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-			result = zend_hash_index_find(ht, Z_LVAL_P(op1));
-			ZEND_VM_SMART_BRANCH(result, 0);
-		}
-		SAVE_OPLINE();
-		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
-			op1 = Z_REFVAL_P(op1);
-			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-				result = zend_hash_find(ht, Z_STR_P(op1));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(result, 0);
-			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(result, 0);
-			}
-		} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-	} else if (Z_TYPE_P(op1) <= IS_FALSE) {
-		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			if (UNEXPECTED(EG(exception) != NULL)) {
-				HANDLE_EXCEPTION();
-			}
-		}
-		result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC());
-		ZEND_VM_SMART_BRANCH(result, 0);
-	} else {
-		zend_string *key;
-		zval key_tmp;
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
-			op1 = Z_REFVAL_P(op1);
-			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-				result = zend_hash_find(ht, Z_STR_P(op1));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(result, 0);
-			}
-		}
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
 
-		SAVE_OPLINE();
-		ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) {
-			ZVAL_STR(&key_tmp, key);
-			if (zend_compare(op1, &key_tmp) == 0) {
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(1, 1);
-			}
-		} ZEND_HASH_FOREACH_END();
-	}
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(0, 1);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -21175,18 +74247,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TM
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_TMP_VAR == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -21195,15 +74273,146 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TM
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		if (IS_TMP_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_TMP_VAR == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_TMP_VAR == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
 	}
+	do {
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -21211,23 +74420,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDL
 
 	/* op1 and result are the same */
 	rope = (zend_string**)EX_VAR(opline->op1.var);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CONST) {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		rope[opline->extended_value] = Z_STR_P(var);
 		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
 			Z_ADDREF_P(var);
 		}
 	} else {
-		var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+			if (IS_TMP_VAR == IS_CV) {
 				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
 			} else {
 				rope[opline->extended_value] = Z_STR_P(var);
 			}
 		} else {
 			SAVE_OPLINE();
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 			}
 			rope[opline->extended_value] = zval_get_string_func(var);
@@ -21238,7 +74447,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -21246,23 +74455,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDL
 	uint32_t i;
 
 	rope = (zend_string**)EX_VAR(opline->op1.var);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CONST) {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		rope[opline->extended_value] = Z_STR_P(var);
 		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
 			Z_ADDREF_P(var);
 		}
 	} else {
-		var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+			if (IS_TMP_VAR == IS_CV) {
 				rope[opline->extended_value] = zend_string_copy(Z_STR_P(var));
 			} else {
 				rope[opline->extended_value] = Z_STR_P(var);
 			}
 		} else {
 			SAVE_OPLINE();
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 			}
 			rope[opline->extended_value] = zval_get_string_func(var);
@@ -21298,7 +74507,213 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	}
+
+	if (IS_TMP_VAR != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_TMP_VAR & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_TMP_VAR != IS_CONST) {
+							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				}
+				zend_invalid_method_call(object, function_name);
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_TMP_VAR == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_TMP_VAR == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_TMP_VAR == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+case_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+case_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+case_double:
+			if (d1 == d2) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+			if (result) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -21338,15 +74753,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		zend_string *str;
 		zend_ulong hval;
 
 add_again:
 		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 			str = Z_STR_P(offset);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				if (ZEND_HANDLE_NUMERIC(str, hval)) {
 					goto num_index;
 				}
@@ -21357,10 +74772,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
 			hval = Z_LVAL_P(offset);
 num_index:
 			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -21376,7 +74805,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
 			zend_use_resource_as_offset(offset);
 			hval = Z_RES_HANDLE_P(offset);
 			goto num_index;
-		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
 			ZVAL_UNDEFINED_OP2();
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
@@ -21391,32 +74820,194 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 	}
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_TMP_VAR != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_TMP_VAR & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_TMP_VAR == IS_CONST ||
+	    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	zval *array;
-	uint32_t size;
 	USE_OPLINE
 
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
 	SAVE_OPLINE();
-	array = EX_VAR(opline->result.var);
-	if (IS_TMP_VAR != IS_UNUSED) {
-		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-		ZVAL_ARR(array, zend_new_array(size));
-		/* Explicitly initialize array as not-packed if flag is set */
-		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
-			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
-		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+
+	key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
 	} else {
-		ZVAL_ARR(array, zend_new_array(0));
-		ZEND_VM_NEXT_OPCODE();
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
 	}
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -21424,7 +75015,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -21489,6 +75080,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(
 			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_TMP_VAR == IS_CV) {
@@ -21502,9 +75094,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(
 	}
 
 	/* Set the new yielded key */
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
 			key = Z_REFVAL_P(key);
 		}
 		ZVAL_COPY(&generator->key, key);
@@ -21537,65 +75129,108 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMP_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *op1, *op2;
+	zval *expr;
 	bool result;
 
 	SAVE_OPLINE();
-	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_VAR == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_VAR == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_R_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+}
 
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_W_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_RW_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+}
 
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_not_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	int fetch_type =
+		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
+			BP_VAR_W : BP_VAR_R;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+}
 
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -21603,18 +75238,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UN
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_UNUSED == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	if (IS_TMP_VAR == IS_UNUSED) {
 		SAVE_OPLINE();
@@ -21640,6 +75281,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN
 			ZVAL_DEREF(retval_ptr);
 		}
 
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
@@ -21681,7 +75334,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -21705,8 +75358,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_HA
 			goto send_val_by_ref;
 		}
 	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-send_val_by_ref:
-		ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
 	}
 	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 	ZVAL_COPY_VALUE(arg, value);
@@ -21718,7 +75371,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_HA
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value, *arg;
@@ -21742,8 +75395,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_T
 			goto send_val_by_ref;
 		}
 	} else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-send_val_by_ref:
-		ZEND_VM_TAIL_CALL(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
+send_val_by_ref:;
+		ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg));
 	}
 	value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 	ZVAL_COPY_VALUE(arg, value);
@@ -21755,7 +75408,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_T
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -21817,7 +75470,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
 		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -21842,6 +75509,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -21851,7 +75519,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -21866,14 +75534,125 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HAN
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	bool result;
+	zval *varname;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
+
+	SAVE_OPLINE();
+	varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else {
+		name = zval_get_tmp_string(varname, &tmp_name);
+	}
+
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	value = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST);
+
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+	if (!value) {
+		result = (opline->extended_value & ZEND_ISEMPTY);
+	} else {
+		if (Z_TYPE_P(value) == IS_INDIRECT) {
+			value = Z_INDIRECT_P(value);
+		}
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			if (Z_ISREF_P(value)) {
+				value = Z_REFVAL_P(value);
+			}
+			result = Z_TYPE_P(value) > IS_NULL;
+		} else {
+			result = !i_zend_is_true(value);
+		}
+	}
+
+	ZEND_VM_SMART_BRANCH(result, true);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr;
+	bool result;
+
+	SAVE_OPLINE();
+	expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+try_instanceof:
+	if (Z_TYPE_P(expr) == IS_OBJECT) {
+		zend_class_entry *ce;
+
+		if (IS_UNUSED == IS_CONST) {
+			ce = CACHED_PTR(opline->extended_value);
+			if (UNEXPECTED(ce == NULL)) {
+				ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD);
+				if (EXPECTED(ce)) {
+					CACHE_PTR(opline->extended_value, ce);
+				}
+			}
+		} else if (IS_UNUSED == IS_UNUSED) {
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
+			if (UNEXPECTED(ce == NULL)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else {
+			ce = Z_CE_P(EX_VAR(opline->op2.var));
+		}
+		result = ce && instanceof_function(Z_OBJCE_P(expr), ce);
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) {
+		expr = Z_REFVAL_P(expr);
+		goto try_instanceof;
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		result = 0;
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -21881,7 +75660,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -21946,6 +75725,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
 			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_TMP_VAR == IS_CV) {
@@ -21966,6 +75746,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -21993,7 +75774,361 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	uint32_t arity = opline->op2.num;
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	/* Skip the entry lookup for speculative sites (args_id == 0). */
+	zend_turbofish_args_entry *tf_entry =
+		(IS_TMP_VAR == IS_UNUSED && opline->extended_value)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_TMP_VAR == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		/* Erased fast path: non-generic speculative site, nothing to verify. */
+		if (args_box == NULL
+				&& (!ZEND_USER_CODE(call->func->type)
+					|| !call->func->op_array.generic_parameters)) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Concrete turbofish args: dispatch to a synthesized plain monomorph and
+		 * skip generic verification (the monomorph's RECV does concrete checks). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, arity, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_verify_check_exception;
+			}
+		}
+		/* Runtime-promoted site: install the cached invariant table after a func
+		 * guard (cache_slot[3], bit1 = value check is a no-op). */
+		if (cache_slot && cache_slot[3]
+				&& ((uintptr_t) cache_slot[3] & ~(uintptr_t)3) == (uintptr_t) call->func) {
+			call->type_args = (zend_type_arg_table *) cache_slot[0];
+			if (((uintptr_t) cache_slot[3] & 2) == 0) {
+				zend_verify_generic_arg_types(call, args_box);
+				if (UNEXPECTED(EG(exception))) {
+					goto generic_verify_check_exception;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Inner/inference call already monomorphized: swap func + reinstall table. */
+		if (cache_slot && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH) {
+			zend_type_arg_table *ma = NULL;
+			zend_function *mono = zend_try_monomorph_resolved_call(call, NULL, cache_slot, &ma);
+			if (mono) {
+				call->func = mono;
+				call->type_args = ma;
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete turbofish VERIFY: install the precomputed SHM table after
+			 * the arity/bound check (memoized in cache_slot[0] per resolved func).
+			 * The persisted guard excludes the no-opcache heap-table case. */
+			bool checked = (cache_slot && cache_slot[0] == (void *) call->func);
+			if (!checked) {
+				zend_check_generic_call_arguments(call->func, arity, args_box);
+			}
+			if (EXPECTED(!EG(exception))) {
+				if (!checked && cache_slot) {
+					cache_slot[0] = (void *) call->func;
+				}
+				call->type_args = tf_entry->concrete_table;
+				if (!tf_entry->concrete_skip_value_check) {
+					zend_verify_generic_arg_types(call, args_box);
+				}
+			}
+		} else {
+			zend_check_generic_call_arguments(call->func, arity, args_box);
+			if (!EG(exception)) {
+				zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+				if (t) {
+					if (call->type_args) {
+						zend_type_arg_table_destroy(call->type_args);
+					}
+					call->type_args = t;
+				}
+				/* If the resolved table is invariant (CONCRETE sentinel), try to
+				 * monomorphize so later calls take the mono fast path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					zend_type_arg_table *ma = NULL;
+					zend_function *mono = zend_try_monomorph_resolved_call(call, t, cache_slot, &ma);
+					if (mono) {
+						call->func = mono;
+						call->type_args = ma;
+						ZEND_VM_NEXT_OPCODE();
+					}
+				}
+				zend_verify_generic_arg_types(call, args_box);
+				/* Promote the invariant site: record the resolved callee in
+				 * cache_slot[3] so later calls take the minimal install path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					/* Tag bits (func is >=8-aligned): bit0 = PROMOTED, bit1 = value
+					 * check is a no-op. slot[1] stays CONCRETE so the build cache
+					 * keeps returning the table on a func-guard miss. */
+					uintptr_t fn = (uintptr_t) call->func | 1u;
+					if (ZEND_USER_CODE(call->func->type)
+							&& call->func->op_array.generic_types
+							&& call->func->op_array.generic_types->parameters
+							&& zend_count_generic_value_checks(
+								call->func->op_array.generic_types->parameters) == 0) {
+						fn |= 2; /* value check is a no-op for this callee */
+					}
+					cache_slot[3] = (void *) fn;
+				}
+			}
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Monomorphize: synthesize (or look up) Box and swap both the
+		 * object's class entry and the pending constructor call. The monomorph
+		 * shares Box's property layout, so swapping ce is safe; swapping
+		 * call->func ensures the constructor's RECV opcodes verify against the
+		 * monomorph's substituted arg_info. The call-site inline cache (incl. the
+		 * concrete-args fast path) lives in zend_apply_generic_new. */
+		zend_apply_generic_new(new_obj, call, args_box, arity, cache_slot, /* do_checks */ true);
+	}
+
+generic_verify_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		/* Args have already been pushed by the SEND opcodes preceding the
+		 * VERIFY emission for call kind; release them so refcounted values
+		 * don't leak. */
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+/* Installs the type-arg table (and, for `new`, swaps the object's class to
+ * its monomorph) without running the runtime arity + bound checks that
+ * VERIFY does. Emitted by the compiler when the callee/ce is statically
+ * known, the turbofish args are concrete, and bounds were validated at
+ * compile time — so the runtime checks are pure overhead. The value-arg
+ * type-check (zend_verify_generic_arg_types) still runs since value
+ * arguments are runtime values. */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	zend_turbofish_args_entry *tf_entry =
+		(IS_TMP_VAR == IS_UNUSED)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_TMP_VAR == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		/* Dispatch to a synthesized plain monomorph (see ZEND_VERIFY_GENERIC_ARGUMENTS). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, opline->op2.num, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_install_check_exception;
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete INSTALL: install the precomputed SHM table directly. The
+			 * persisted guard excludes the no-opcache heap-table case (whose table
+			 * is owned by the turbofish entry and must not be freed at teardown). */
+			call->type_args = tf_entry->concrete_table;
+			if (!tf_entry->concrete_skip_value_check) {
+				zend_verify_generic_arg_types(call, args_box);
+			}
+		} else {
+			zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+			if (t) {
+				if (call->type_args) {
+					zend_type_arg_table_destroy(call->type_args);
+				}
+				call->type_args = t;
+			}
+			zend_verify_generic_arg_types(call, args_box);
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Statically pre-validated: skip the runtime arity/bound check, but
+		 * still cache the resolved monomorph at the call site. */
+		zend_apply_generic_new(new_obj, call, args_box, opline->op2.num, cache_slot, /* do_checks */ false);
+	}
+
+generic_install_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1;
+	zend_long count;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	while (1) {
+		if (Z_TYPE_P(op1) == IS_ARRAY) {
+			count = zend_hash_num_elements(Z_ARRVAL_P(op1));
+			break;
+		} else if (Z_TYPE_P(op1) == IS_OBJECT) {
+			zend_object *zobj = Z_OBJ_P(op1);
+
+			/* first, we check if the handler is defined */
+			if (zobj->handlers->count_elements) {
+				if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) {
+					break;
+				}
+				if (UNEXPECTED(EG(exception))) {
+					count = 0;
+					break;
+				}
+			}
+
+			/* if not and the object implements Countable we call its count() method */
+			if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) {
+				zval retval;
+
+				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
+				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
+				count = zval_get_long(&retval);
+				zval_ptr_dtor(&retval);
+				break;
+			}
+
+			/* If There's no handler and it doesn't implement Countable then emit a TypeError */
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+			op1 = Z_REFVAL_P(op1);
+			continue;
+		} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		count = 0;
+		zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1));
+		break;
+	}
+
+	ZVAL_LONG(EX_VAR(opline->result.var), count);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_array *ht = Z_ARRVAL_P(_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC));
+	ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht));
+	if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+		SAVE_OPLINE();
+		zend_array_destroy(ht);
+		if (EG(exception)) {
+			HANDLE_EXCEPTION();
+		}
+	}
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		SAVE_OPLINE();
+		if (UNEXPECTED(!EX(func)->common.scope)) {
+			zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		} else {
+			zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
+			ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+	} else {
+		zval *op1;
+
+		SAVE_OPLINE();
+		op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+		while (1) {
+			if (Z_TYPE_P(op1) == IS_OBJECT) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name);
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) {
+				op1 = Z_REFVAL_P(op1);
+				continue;
+			} else {
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+					ZVAL_UNDEFINED_OP1();
+				}
+				zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1));
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+			}
+			break;
+		}
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -22007,11 +76142,119 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDL
 	} else {
 		ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
 	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	div_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	pow_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = EX_VAR(opline->op2.var);
+
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) {
+				zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation");
+			}
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	} else {
+		SAVE_OPLINE();
+
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			op1 = ZVAL_UNDEFINED_OP1();
+		}
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			op2 = ZVAL_UNDEFINED_OP2();
+		}
+		concat_function(EX_VAR(opline->result.var), op1, op2);
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -22022,10 +76265,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLE
 	op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 	result = fast_is_identical_function(op1, op2);
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	compare_function(EX_VAR(opline->result.var), op1, op2);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -22033,18 +76292,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_CV == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_TMP_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -22053,15 +76318,147 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_TMP_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = EX_VAR(opline->op2.var);
+	if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_TMP_VAR == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CV == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
 	}
+	do {
+		if (IS_TMP_VAR != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_TMP_VAR == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
+				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
+			}
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_TMP_VAR != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -22090,13 +76487,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(Z
 			}
 			rope[opline->extended_value] = zval_get_string_func(var);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -22125,6 +76523,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(Z
 			}
 			rope[opline->extended_value] = zval_get_string_func(var);
 
+
 			if (UNEXPECTED(EG(exception))) {
 				for (i = 0; i <= opline->extended_value; i++) {
 					zend_string_release_ex(rope[i], 0);
@@ -22156,7 +76555,219 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(Z
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+
+	if (IS_CV != IS_CONST) {
+		function_name = EX_VAR(opline->op2.var);
+	}
+
+	if (IS_CV != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+					HANDLE_EXCEPTION();
+				}
+			}
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_TMP_VAR == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_TMP_VAR & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
+				}
+				if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CV != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
+					}
+				}
+				if (IS_CV == IS_CONST) {
+					function_name = EX_VAR(opline->op2.var);
+				}
+				zend_invalid_method_call(object, function_name);
+
+
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+				HANDLE_EXCEPTION();
+			}
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CV == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CV == IS_CONST) {
+			function_name = EX_VAR(opline->op2.var);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
+			}
+
+
+			if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+			HANDLE_EXCEPTION();
+		}
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
+		}
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
+		}
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CV != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_TMP_VAR == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	double d1, d2;
+
+	op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	op2 = EX_VAR(opline->op2.var);
+	if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) {
+case_true:
+				ZEND_VM_SMART_BRANCH_TRUE();
+			} else {
+case_false:
+				ZEND_VM_SMART_BRANCH_FALSE();
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = (double)Z_LVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = Z_DVAL_P(op2);
+case_double:
+			if (d1 == d2) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+			d1 = Z_DVAL_P(op1);
+			d2 = (double)Z_LVAL_P(op2);
+			goto case_double;
+		}
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+			bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
+
+
+			if (result) {
+				goto case_true;
+			} else {
+				goto case_false;
+			}
+		}
+	}
+	ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -22218,7 +76829,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
 		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -22243,6 +76868,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -22252,7 +76878,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -22267,14 +76893,179 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
+
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
+		}
+
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+
+			if (IS_TMP_VAR & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
+
+
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
+		}
+		goto isset_dim_obj_exit;
+	} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
+		}
+	}
+
+	if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
+	} else {
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+	}
+
+isset_dim_obj_exit:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
+
+	SAVE_OPLINE();
+	container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	if (IS_TMP_VAR == IS_CONST ||
+	    (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
+
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(offset);
+	} else {
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
+	}
+
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+isset_object_finish:
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
+
+	SAVE_OPLINE();
+
+	key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
+	subject = EX_VAR(opline->op2.var);
+
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
+			}
+		}
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
+	}
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -22282,7 +77073,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -22347,6 +77138,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
 			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_TMP_VAR == IS_CV) {
@@ -22367,6 +77159,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -22394,7 +77187,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BIND_LEXICAL_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *closure, *var;
@@ -22426,7 +77219,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_pre_inc_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22459,7 +77252,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_inc_help
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22474,10 +77267,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_R
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22492,10 +77285,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_R
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_pre_dec_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22529,7 +77322,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_dec_help
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22544,10 +77337,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_R
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22562,10 +77355,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_R
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_post_inc_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22597,7 +77390,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_inc_hel
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22610,10 +77403,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_post_dec_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22645,7 +77438,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_dec_hel
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_DEC_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -22658,96 +77451,21 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval_ptr;
 	zval *return_value;
 
-	retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	return_value = EX(return_value);
-
-	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
-		SAVE_OPLINE();
-		retval_ptr = ZVAL_UNDEFINED_OP1();
-		if (return_value) {
-			ZVAL_NULL(return_value);
-		}
-	} else if (!return_value) {
-		if (IS_VAR & (IS_VAR|IS_TMP_VAR)) {
-			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
-				SAVE_OPLINE();
-				rc_dtor_func(Z_COUNTED_P(retval_ptr));
-			}
-		}
-	} else {
-		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZVAL_COPY_VALUE(return_value, retval_ptr);
-			if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
-					Z_ADDREF_P(return_value);
-				}
-			}
-		} else if (IS_VAR == IS_CV) {
-			do {
-				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
-						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
-							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
-							ZVAL_COPY_VALUE(return_value, retval_ptr);
-							if (GC_MAY_LEAK(ref)) {
-								SAVE_OPLINE();
-								gc_possible_root(ref);
-							}
-							ZVAL_NULL(retval_ptr);
-							break;
-						} else {
-							Z_ADDREF_P(retval_ptr);
-						}
-					} else {
-						retval_ptr = Z_REFVAL_P(retval_ptr);
-						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-							Z_ADDREF_P(retval_ptr);
-						}
-					}
-				}
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-			} while (0);
-		} else /* if (IS_VAR == IS_VAR) */ {
-			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
-				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
-
-				retval_ptr = Z_REFVAL_P(retval_ptr);
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-					efree_size(ref, sizeof(zend_reference));
-				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-					Z_ADDREF_P(retval_ptr);
-				}
-			} else {
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-			}
-		}
-	}
-
-
-
-	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *retval_ptr;
-	zval *return_value;
 
 	SAVE_OPLINE();
 
 	return_value = EX(return_value);
 
+
 	do {
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR)) ||
 		    (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
@@ -22799,10 +77517,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
 	} while (0);
 
 
-	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval;
@@ -22838,6 +77560,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_VAR_HAND
 		}
 	}
 
+
 	EG(current_execute_data) = EX(prev_execute_data);
 
 	/* Close the generator to free up resources */
@@ -22847,154 +77570,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_VAR_HAND
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *arg, *param;
-
-	SAVE_OPLINE();
-
-	arg = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	param = ZEND_CALL_VAR(EX(call), opline->result.var);
-	if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) {
-		zend_param_must_be_ref(EX(call)->func, opline->op2.num);
-		Z_TRY_ADDREF_P(arg);
-		ZVAL_NEW_REF(param, arg);
-	} else {
-		ZVAL_COPY(param, arg);
-	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *expr;
-	zval *result = EX_VAR(opline->result.var);
-
-	SAVE_OPLINE();
-	expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	switch (opline->extended_value) {
-		case IS_LONG:
-			ZVAL_LONG(result, zval_get_long(expr));
-			break;
-		case IS_DOUBLE:
-			ZVAL_DOUBLE(result, zval_get_double(expr));
-			break;
-		case IS_STRING:
-			ZVAL_STR(result, zval_get_string(expr));
-			break;
-		default:
-			ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead");
-			if (IS_VAR & (IS_VAR|IS_CV)) {
-				ZVAL_DEREF(expr);
-			}
-			/* If value is already of correct type, return it directly */
-			if (Z_TYPE_P(expr) == opline->extended_value) {
-				ZVAL_COPY_VALUE(result, expr);
-				if (IS_VAR == IS_CONST) {
-					if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
-				} else if (IS_VAR != IS_TMP_VAR) {
-					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
-				}
-
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-			}
-
-			if (opline->extended_value == IS_ARRAY) {
-				zend_cast_zval_to_array(result, expr, IS_VAR);
-			} else {
-				ZEND_ASSERT(opline->extended_value == IS_OBJECT);
-				zend_cast_zval_to_object(result, expr, IS_VAR);
-			}
-	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *array_ptr, *result;
-
-	SAVE_OPLINE();
-
-	array_ptr = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
-		result = EX_VAR(opline->result.var);
-		ZVAL_COPY_VALUE(result, array_ptr);
-		if (IS_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
-			Z_ADDREF_P(array_ptr);
-		}
-		Z_FE_POS_P(result) = 0;
-
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_NEXT_OPCODE();
-	} else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
-		zend_object *zobj = Z_OBJ_P(array_ptr);
-		if (!zobj->ce->get_iterator) {
-			if (UNEXPECTED(zend_object_is_lazy(zobj))) {
-				zobj = zend_lazy_object_init(zobj);
-				if (UNEXPECTED(EG(exception))) {
-					UNDEF_RESULT();
-					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-					HANDLE_EXCEPTION();
-				}
-			}
-			HashTable *properties = zobj->properties;
-			if (properties) {
-				if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
-					if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
-						GC_DELREF(properties);
-					}
-					properties = zobj->properties = zend_array_dup(properties);
-				}
-			} else {
-				properties = zobj->handlers->get_properties(zobj);
-			}
-
-			result = EX_VAR(opline->result.var);
-			ZVAL_COPY_VALUE(result, array_ptr);
-			if (IS_VAR != IS_TMP_VAR) {
-				Z_ADDREF_P(array_ptr);
-			}
-
-			if (zend_hash_num_elements(properties) == 0) {
-				Z_FE_ITER_P(result) = (uint32_t) -1;
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
-			}
-
-			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		} else {
-			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			} else if (is_empty) {
-				ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-			} else {
-				ZEND_VM_NEXT_OPCODE();
-			}
-		}
-	} else {
-		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr));
-		ZVAL_UNDEF(EX_VAR(opline->result.var));
-		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
-	}
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array_ptr, *array_ref;
@@ -23093,87 +77669,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *array;
-	zval *value;
-	uint32_t value_type;
-	HashTable *fe_ht;
-	HashPosition pos;
-
-	array = EX_VAR(opline->op1.var);
-	if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) {
-		ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	}
-	fe_ht = Z_ARRVAL_P(array);
-	pos = Z_FE_POS_P(array);
-	if (HT_IS_PACKED(fe_ht)) {
-		value = fe_ht->arPacked + pos;
-		while (1) {
-			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
-				/* reached end of iteration */
-				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
-				ZEND_VM_CONTINUE();
-			}
-			value_type = Z_TYPE_INFO_P(value);
-			ZEND_ASSERT(value_type != IS_INDIRECT);
-			if (EXPECTED(value_type != IS_UNDEF)) {
-				break;
-			}
-			pos++;
-			value++;
-		}
-		Z_FE_POS_P(array) = pos + 1;
-		if (RETURN_VALUE_USED(opline)) {
-			ZVAL_LONG(EX_VAR(opline->result.var), pos);
-		}
-	} else {
-		Bucket *p;
-
-		p = fe_ht->arData + pos;
-		while (1) {
-			if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
-				/* reached end of iteration */
-				ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
-				ZEND_VM_CONTINUE();
-			}
-			pos++;
-			value = &p->val;
-			value_type = Z_TYPE_INFO_P(value);
-			ZEND_ASSERT(value_type != IS_INDIRECT);
-			if (EXPECTED(value_type != IS_UNDEF)) {
-				break;
-			}
-			p++;
-		}
-		Z_FE_POS_P(array) = pos;
-		if (RETURN_VALUE_USED(opline)) {
-			if (!p->key) {
-				ZVAL_LONG(EX_VAR(opline->result.var), p->h);
-			} else {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key);
-			}
-		}
-	}
-	if (EXPECTED(opline->op2_type == IS_CV)) {
-		zval *variable_ptr = EX_VAR(opline->op2.var);
-		SAVE_OPLINE();
-		zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
-		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-	} else {
-		zval *res = EX_VAR(opline->op2.var);
-		zend_refcounted *gc = Z_COUNTED_P(value);
-
-		ZVAL_COPY_VALUE_EX(res, value, gc, value_type);
-		if (Z_TYPE_INFO_REFCOUNTED(value_type)) {
-			GC_ADDREF(gc);
-		}
-		ZEND_VM_NEXT_OPCODE();
-	}
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_RW_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array;
@@ -23246,7 +77742,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z
 			while (1) {
 				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
 					/* reached end of iteration */
-					goto fe_fetch_w_exit;
+					goto fe_fetch_w_exit_exc;
 				}
 				pos++;
 				value = &p->val;
@@ -23342,6 +77838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z
 		}
 	} else {
 		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array));
+fe_fetch_w_exit_exc:
 		if (UNEXPECTED(EG(exception))) {
 			UNDEF_RESULT();
 			HANDLE_EXCEPTION();
@@ -23375,139 +77872,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zend_reference *ref = NULL;
-	bool ret;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) {
-		if (IS_VAR == IS_VAR) {
-			ref = Z_REF_P(value);
-		}
-		value = Z_REFVAL_P(value);
-	}
-
-	ret = i_zend_is_true(value);
-
-	if (UNEXPECTED(EG(exception))) {
-		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-		ZVAL_UNDEF(EX_VAR(opline->result.var));
-		HANDLE_EXCEPTION();
-	}
-
-	if (ret) {
-		zval *result = EX_VAR(opline->result.var);
-
-		ZVAL_COPY_VALUE(result, value);
-		if (IS_VAR == IS_CONST) {
-			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
-		} else if (IS_VAR == IS_CV) {
-			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
-		} else if (IS_VAR == IS_VAR && ref) {
-			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-				efree_size(ref, sizeof(zend_reference));
-			} else if (Z_OPT_REFCOUNTED_P(result)) {
-				Z_ADDREF_P(result);
-			}
-		}
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-	}
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zend_reference *ref = NULL;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
-		if (IS_VAR & IS_VAR) {
-			ref = Z_REF_P(value);
-		}
-		value = Z_REFVAL_P(value);
-	}
-
-	if (Z_TYPE_P(value) > IS_NULL) {
-		zval *result = EX_VAR(opline->result.var);
-		ZVAL_COPY_VALUE(result, value);
-		if (IS_VAR == IS_CONST) {
-			if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result);
-		} else if (IS_VAR == IS_CV) {
-			if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
-		} else if ((IS_VAR & IS_VAR) && ref) {
-			if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-				efree_size(ref, sizeof(zend_reference));
-			} else if (Z_OPT_REFCOUNTED_P(result)) {
-				Z_ADDREF_P(result);
-			}
-		}
-		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-	}
-
-	if ((IS_VAR & IS_VAR) && ref) {
-		if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-			efree_size(ref, sizeof(zend_reference));
-		}
-	}
-	ZEND_VM_NEXT_OPCODE();
-}
-
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *val, *result;
-
-	val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (Z_TYPE_P(val) > IS_NULL) {
-		do {
-			if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) {
-				val = Z_REFVAL_P(val);
-				if (Z_TYPE_P(val) <= IS_NULL) {
-					zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-					break;
-				}
-			}
-			ZEND_VM_NEXT_OPCODE();
-		} while (0);
-	}
-
-	result = EX_VAR(opline->result.var);
-	uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK;
-	if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) {
-		ZVAL_NULL(result);
-		if (IS_VAR == IS_CV
-			&& UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF)
-			&& (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0
-		) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			if (UNEXPECTED(EG(exception) != NULL)) {
-				HANDLE_EXCEPTION();
-			}
-		}
-	} else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) {
-		ZVAL_FALSE(result);
-	} else {
-		ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY);
-		ZVAL_TRUE(result);
-	}
-
-	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
-}
-
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -23545,7 +77910,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -23562,51 +77927,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SP
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	result = fast_is_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	result = fast_is_identical_function(op1, op2);
-
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = RT_CONSTANT(opline, opline->op2);
-	result = fast_is_not_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -23671,7 +77992,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_H
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -23693,13 +78014,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_H
 
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -23795,11 +78117,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H
 		}
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -23825,11 +78148,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDL
 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -23879,7 +78203,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HAN
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -23889,11 +78214,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HAN
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -23941,7 +78267,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HA
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -23951,11 +78278,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HA
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -23964,13 +78292,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HAN
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -23979,13 +78308,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HA
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -23993,18 +78323,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CO
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_CONST == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -24013,13 +78349,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -24034,13 +78371,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HAN
 		((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -24051,13 +78389,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HA
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -24066,15 +78405,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CO
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
@@ -24085,13 +78430,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim;
@@ -24110,10 +78456,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HA
 		zend_fetch_dimension_address_W(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -24236,6 +78583,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D
 		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -24256,18 +78604,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -24415,167 +78765,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D
 		GC_DTOR_NO_REF(garbage);
 	}
 
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if (IS_CONST == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-	} else {
-		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if (IS_CONST != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -24698,6 +78895,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D
 		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -24718,18 +78916,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -24827,6 +79027,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -24834,12 +79035,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 			if (IS_CONST == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = RT_CONSTANT(opline, opline->op2);
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -24847,6 +79050,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = RT_CONSTANT(opline, opline->op2);
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -24868,6 +79072,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 			dim = RT_CONSTANT(opline, opline->op2);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -24875,13 +79080,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 	}
 	if (IS_CONST != IS_UNUSED) {
 
+
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -25028,158 +79234,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 	}
 	if (IS_CONST != IS_UNUSED) {
 
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
-	zval *value;
-	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if (IS_CONST == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_VAR == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = RT_CONSTANT(opline, opline->op2);
-			if (IS_CONST == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = RT_CONSTANT(opline, opline->op2);
-			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
-
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if (IS_CONST == IS_UNUSED) {
-				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				dim = RT_CONSTANT(opline, opline->op2);
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = RT_CONSTANT(opline, opline->op2);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
-
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = RT_CONSTANT(opline, opline->op2);
-assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
-		}
-	}
-	if (IS_CONST != IS_UNUSED) {
 
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -25187,7 +79241,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -25285,6 +79339,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -25292,12 +79347,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 			if (IS_CONST == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = RT_CONSTANT(opline, opline->op2);
 				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -25305,6 +79362,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = RT_CONSTANT(opline, opline->op2);
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -25326,6 +79384,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 			dim = RT_CONSTANT(opline, opline->op2);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -25333,13 +79392,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D
 	}
 	if (IS_CONST != IS_UNUSED) {
 
+
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -25368,7 +79428,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_U
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -25397,7 +79457,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_U
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -25429,12 +79489,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
+
 	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -25467,11 +79528,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -25489,6 +79552,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_CONST != IS_CONST) {
@@ -25499,6 +79563,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -25531,6 +79596,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -25546,6 +79612,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_CONST == IS_CONST &&
@@ -25558,6 +79625,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		}
 		if (IS_CONST != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -25604,7 +79672,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -25651,7 +79719,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -25682,7 +79750,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -25750,7 +79818,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CO
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_REF_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -25780,7 +79848,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_CONST_HANDLE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -25846,7 +79914,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_CONST_HAN
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -25897,7 +79965,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_FUNC_ARG_SPEC
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_class_entry *ce, *scope;
 	zend_class_constant *c;
@@ -25922,6 +79990,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 				if (UNEXPECTED(ce == NULL)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 				CACHE_PTR(opline->extended_value, ce);
@@ -25931,6 +80000,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 			if (UNEXPECTED(ce == NULL)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		} else {
@@ -25948,6 +80018,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
 			ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 			HANDLE_EXCEPTION();
 		}
 		constant_name = Z_STR_P(constant_zv);
@@ -25955,6 +80026,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 		if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
 
+
 			ZEND_VM_NEXT_OPCODE();
 		}
 		zv = IS_CONST == IS_CONST
@@ -25968,6 +80040,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 
@@ -25975,6 +80048,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 
@@ -25992,6 +80066,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 				if (EG(exception)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -26002,6 +80077,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -26009,6 +80085,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -26020,16 +80097,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 			ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 			HANDLE_EXCEPTION();
 		}
 	} while (0);
 
 	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -26091,7 +80170,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
 		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -26116,6 +80209,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -26125,7 +80219,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -26140,14 +80234,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CONST_HAND
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -26185,7 +80279,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDL
 				offset = Z_REFVAL_P(offset);
 				goto offset_again;
 			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
 				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
 				goto num_index_dim;
 			} else if (Z_TYPE_P(offset) == IS_NULL) {
 				key = ZSTR_EMPTY_ALLOC();
@@ -26234,11 +80338,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDL
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -26278,11 +80383,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDL
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -26290,7 +80396,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -26375,6 +80481,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -26402,79 +80509,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1;
-	HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2));
-	zval *result;
-
-	op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_VAR == IS_CONST);
-		if (IS_VAR & (IS_TMP_VAR|IS_VAR)) {
-			zval_ptr_dtor_str(op1);
-		}
-		ZEND_VM_SMART_BRANCH(result, 0);
-	}
-
-	if (opline->extended_value) {
-		if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-			result = zend_hash_index_find(ht, Z_LVAL_P(op1));
-			ZEND_VM_SMART_BRANCH(result, 0);
-		}
-		SAVE_OPLINE();
-		if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
-			op1 = Z_REFVAL_P(op1);
-			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-				result = zend_hash_find(ht, Z_STR_P(op1));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(result, 0);
-			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
-				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(result, 0);
-			}
-		} else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-	} else if (Z_TYPE_P(op1) <= IS_FALSE) {
-		if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			SAVE_OPLINE();
-			ZVAL_UNDEFINED_OP1();
-			if (UNEXPECTED(EG(exception) != NULL)) {
-				HANDLE_EXCEPTION();
-			}
-		}
-		result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC());
-		ZEND_VM_SMART_BRANCH(result, 0);
-	} else {
-		zend_string *key;
-		zval key_tmp;
-
-		if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) {
-			op1 = Z_REFVAL_P(op1);
-			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-				result = zend_hash_find(ht, Z_STR_P(op1));
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(result, 0);
-			}
-		}
-
-		SAVE_OPLINE();
-		ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) {
-			ZVAL_STR(&key_tmp, key);
-			if (zend_compare(op1, &key_tmp) == 0) {
-				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-				ZEND_VM_SMART_BRANCH(1, 1);
-			}
-		} ZEND_HASH_FOREACH_END();
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_SMART_BRANCH(0, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_class_entry *ce, *scope;
 	zend_class_constant *c;
@@ -26607,7 +80642,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -26622,7 +80657,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_
 
 	SAVE_OPLINE();
 	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
@@ -26643,7 +80678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_
 assign_op_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -26652,7 +80687,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
@@ -26672,7 +80707,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -26687,7 +80722,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_
 		} else {
 			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
@@ -26699,8 +80734,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -26715,15 +80750,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_
 		SEPARATE_ARRAY(container);
 		ht = Z_ARRVAL_P(container);
 assign_dim_op_new_array:
-		dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+		dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_UNUSED) {
 			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
 			if (UNEXPECTED(!var_ptr)) {
 				zend_cannot_add_element();
 				goto assign_dim_op_ret_null;
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
 			} else {
 				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
@@ -26736,7 +80771,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_
 		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
 
 		do {
-			if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+			if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
 				zend_reference *ref = Z_REF_P(var_ptr);
 				var_ptr = Z_REFVAL_P(var_ptr);
 				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
@@ -26762,8 +80797,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_
 		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 			zend_object *obj = Z_OBJ_P(container);
 
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
@@ -26786,7 +80821,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_
 			}
 			goto assign_dim_op_new_array;
 		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
 			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
@@ -26801,14 +80836,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
 	zval *value;
 
 	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 
 	do {
@@ -26832,7 +80867,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HAND
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -26846,7 +80881,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HA
 
 	SAVE_OPLINE();
 	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -26865,7 +80900,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HA
 pre_incdec_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -26874,7 +80909,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HA
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
@@ -26882,12 +80917,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HA
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
@@ -26897,7 +80933,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -26911,7 +80947,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_H
 
 	SAVE_OPLINE();
 	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -26930,7 +80966,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_H
 post_incdec_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -26939,18 +80975,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_H
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
@@ -26960,14 +80997,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_H
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	zend_fetch_dimension_address_W(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -26975,14 +81012,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	zend_fetch_dimension_address_RW(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -26990,7 +81027,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_H
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -26998,25 +81035,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TM
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_TMP_VAR == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		}
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -27024,7 +81067,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -27032,11 +81075,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HA
 	SAVE_OPLINE();
 
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(
-		result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR),
-		(((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		result, container, IS_VAR, property, IS_TMP_VAR,
+		((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_VAR == IS_VAR) {
@@ -27045,16 +81088,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
-	zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -27062,7 +81105,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_H
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -27071,24 +81114,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TM
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
-	zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -27096,30 +81145,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim;
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (IS_VAR == IS_VAR
 		&& Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT
 		&& UNEXPECTED(!Z_ISREF_P(container))
 	) {
 		zend_error(E_NOTICE, "Attempting to set reference to non referenceable value");
-		zend_fetch_dimension_address_LIST_r(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+		zend_fetch_dimension_address_LIST_r(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	} else {
-		zend_fetch_dimension_address_W(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+		zend_fetch_dimension_address_W(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	}
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -27136,14 +81185,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -27169,7 +81218,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -27237,11 +81286,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -27251,9 +81301,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -27262,6 +81312,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
@@ -27272,8 +81323,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -27290,14 +81341,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -27323,7 +81374,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -27391,9 +81442,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 			UNDEF_RESULT();
@@ -27405,9 +81456,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -27426,162 +81477,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -27598,14 +81495,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -27631,7 +81528,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -27699,11 +81596,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -27713,9 +81611,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -27724,6 +81622,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
@@ -27734,8 +81633,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -27750,7 +81649,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
 try_assign_dim_array:
 		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+		if (IS_TMP_VAR == IS_UNUSED) {
 			value = RT_CONSTANT((opline+1), (opline+1)->op1);
 			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
 				HashTable *ht = Z_ARRVAL_P(object_ptr);
@@ -27788,8 +81687,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 				}
 			}
 		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
 				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
 			} else {
 				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
@@ -27817,10 +81716,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 			zend_object *obj = Z_OBJ_P(object_ptr);
 
 			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
 				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 
@@ -27833,25 +81732,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
 			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
 
 				UNDEF_RESULT();
 			} else {
@@ -27871,15 +81774,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 			}
 		} else {
 			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
 		}
 	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
+	if (IS_TMP_VAR != IS_UNUSED) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -27887,7 +81791,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -27902,7 +81806,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
 try_assign_dim_array:
 		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+		if (IS_TMP_VAR == IS_UNUSED) {
 			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
 			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
 				HashTable *ht = Z_ARRVAL_P(object_ptr);
@@ -27940,8 +81844,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 				}
 			}
 		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
 				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
 			} else {
 				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
@@ -27969,43 +81873,199 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 			zend_object *obj = Z_OBJ_P(object_ptr);
 
 			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_TMP_VAR == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	}
+	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
 				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 
-			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
 				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
 				ZVAL_DEREF(value);
 			}
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_UNUSED) {
 				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 				UNDEF_RESULT();
 			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
 			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -28024,15 +82084,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 			}
 		} else {
 			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
 		}
 	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
+	if (IS_TMP_VAR != IS_UNUSED) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -28040,312 +82101,65 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
 	zval *value;
 	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
 
 	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_VAR == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
 			ZVAL_COPY(EX_VAR(opline->result.var), value);
 		}
 		if (garbage) {
 			GC_DTOR_NO_REF(garbage);
 		}
 	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
-
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
-
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
-		}
-	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
 	zval *value;
 	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
 
 	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-			value = EX_VAR((opline+1)->op1.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_CV == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_CV == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_CV == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
 			ZVAL_COPY(EX_VAR(opline->result.var), value);
 		}
 		if (garbage) {
 			GC_DTOR_NO_REF(garbage);
 		}
 	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = EX_VAR((opline+1)->op1.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_CV & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
-
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-				zend_use_new_element_for_string();
-
-				UNDEF_RESULT();
-			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				value = EX_VAR((opline+1)->op1.var);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
-
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-assign_dim_error:
-
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
-		}
-	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -28353,26 +82167,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR
 	SAVE_OPLINE();
 
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
 
 	if (1) {
 		if (IS_VAR == IS_UNUSED) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		}
 	} else {
-		zend_assign_to_property_reference(container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 	}
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -28381,8 +82195,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -28390,36 +82204,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR
 	SAVE_OPLINE();
 
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
 
 	if (1) {
 		if (IS_VAR == IS_UNUSED) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		}
 	} else {
-		zend_assign_to_property_reference(container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 	}
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -28439,7 +82254,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 				HANDLE_EXCEPTION();
 			}
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				CACHE_PTR(opline->result.num, ce);
 			}
 		}
@@ -28454,24 +82269,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 	}
 
 	if (IS_VAR == IS_CONST &&
-	    (IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	    IS_TMP_VAR == IS_CONST &&
 	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
 		/* nothing to do */
 	} else if (IS_VAR != IS_CONST &&
-	           (IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	           IS_TMP_VAR == IS_CONST &&
 	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
 		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
-	} else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	} else if (IS_TMP_VAR != IS_UNUSED) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR != IS_CONST) {
 			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
 				do {
-					if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+					if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
 						function_name = Z_REFVAL_P(function_name);
 						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 							break;
 						}
-					} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+					} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 						ZVAL_UNDEFINED_OP2();
 						if (UNEXPECTED(EG(exception) != NULL)) {
 							HANDLE_EXCEPTION();
@@ -28487,7 +82302,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		if (ce->get_static_method) {
 			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
 		} else {
-			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
 		}
 		if (UNEXPECTED(fbc == NULL)) {
 			if (EXPECTED(!EG(exception))) {
@@ -28496,7 +82311,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 			HANDLE_EXCEPTION();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+		if (IS_TMP_VAR == IS_CONST &&
 		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
 			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
 			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
@@ -28504,7 +82319,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
 			init_func_run_time_cache(&fbc->op_array);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 		}
 	} else {
@@ -28552,7 +82367,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -28592,15 +82407,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		zend_string *str;
 		zend_ulong hval;
 
 add_again:
 		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 			str = Z_STR_P(offset);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				if (ZEND_HANDLE_NUMERIC(str, hval)) {
 					goto num_index;
 				}
@@ -28611,10 +82426,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
 			hval = Z_LVAL_P(offset);
 num_index:
 			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -28630,7 +82459,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
 			zend_use_resource_as_offset(offset);
 			hval = Z_RES_HANDLE_P(offset);
 			goto num_index;
-		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
 			ZVAL_UNDEFINED_OP2();
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
@@ -28648,7 +82477,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -28663,14 +82492,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HAN
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -28680,7 +82509,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
@@ -28692,7 +82521,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
 offset_again:
 			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 				key = Z_STR_P(offset);
-				if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+				if (IS_TMP_VAR != IS_CONST) {
 					if (ZEND_HANDLE_NUMERIC(key, hval)) {
 						goto num_index_dim;
 					}
@@ -28704,11 +82533,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
 				hval = Z_LVAL_P(offset);
 num_index_dim:
 				zend_hash_index_del(ht, hval);
-			} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 				offset = Z_REFVAL_P(offset);
 				goto offset_again;
 			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
 				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
 				goto num_index_dim;
 			} else if (Z_TYPE_P(offset) == IS_NULL) {
 				key = ZSTR_EMPTY_ALLOC();
@@ -28723,7 +82562,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
 				zend_use_resource_as_offset(offset);
 				hval = Z_RES_HANDLE_P(offset);
 				goto num_index_dim;
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
 				ZVAL_UNDEFINED_OP2();
 				key = ZSTR_EMPTY_ALLOC();
 				goto str_index_dim;
@@ -28740,11 +82579,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
 		if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
 			container = ZVAL_UNDEFINED_OP1();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
 			offset = ZVAL_UNDEFINED_OP2();
 		}
 		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
 				offset++;
 			}
 			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
@@ -28762,7 +82601,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -28771,7 +82610,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -28788,7 +82627,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND
 				break;
 			}
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(offset);
 		} else {
 			name = zval_try_get_tmp_string(offset, &tmp_name);
@@ -28796,8 +82635,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND
 				break;
 			}
 		}
-		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
@@ -28807,7 +82646,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -28815,7 +82654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER(
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -28893,9 +82732,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER(
 	}
 
 	/* Set the new yielded key */
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
 			key = Z_REFVAL_P(key);
 		}
 		ZVAL_COPY(&generator->key, key);
@@ -28928,211 +82767,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER(
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_not_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (0 || UNEXPECTED(0)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(0)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (0 || UNEXPECTED(1)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(1)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_not_identical_function(op1, op2);
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (0 || UNEXPECTED(0)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(0)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES());
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (0 || UNEXPECTED(1)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(1)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES());
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_REF_SPEC_VAR_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *variable_ptr;
@@ -29171,7 +82806,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLE
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -29267,11 +82902,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_
 		}
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -29280,13 +82916,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HA
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -29295,13 +82932,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_H
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -29309,18 +82947,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UN
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_UNUSED == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -29418,6 +83062,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -29425,12 +83070,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 			if (IS_UNUSED == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = NULL;
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -29438,6 +83085,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = NULL;
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -29459,6 +83107,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 			dim = NULL;
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -29466,13 +83115,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 	}
 	if (IS_UNUSED != IS_UNUSED) {
 
+
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -29619,158 +83269,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 	}
 	if (IS_UNUSED != IS_UNUSED) {
 
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
-	zval *value;
-	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if (IS_UNUSED == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_VAR == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = NULL;
-			if (IS_UNUSED == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = NULL;
-			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
-
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if (IS_UNUSED == IS_UNUSED) {
-				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				dim = NULL;
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = NULL;
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
-
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = NULL;
-assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
-		}
-	}
-	if (IS_UNUSED != IS_UNUSED) {
 
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -29778,7 +83276,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -29876,6 +83374,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -29883,12 +83382,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 			if (IS_UNUSED == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = NULL;
 				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -29896,6 +83397,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = NULL;
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -29917,6 +83419,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 			dim = NULL;
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -29924,13 +83427,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_
 	}
 	if (IS_UNUSED != IS_UNUSED) {
 
+
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -29948,6 +83452,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_UNUSED != IS_CONST) {
@@ -29958,6 +83463,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -29990,6 +83496,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -30005,6 +83512,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_UNUSED == IS_CONST &&
@@ -30017,6 +83525,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		}
 		if (IS_UNUSED != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -30063,7 +83572,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	if (IS_VAR == IS_UNUSED) {
 		SAVE_OPLINE();
@@ -30089,6 +83598,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN
 			ZVAL_DEREF(retval_ptr);
 		}
 
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
@@ -30130,7 +83651,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30177,7 +83698,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30208,7 +83729,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSE
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30276,7 +83797,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UN
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30344,7 +83865,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_EX
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_REF_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30374,7 +83895,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30440,7 +83961,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_HA
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30506,7 +84027,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_V
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -30557,7 +84078,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_FUNC_ARG_SPEC
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *result;
@@ -30586,6 +84107,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZE
 		ce = Z_CE_P(EX_VAR(opline->op1.var));
 	}
 
+	/* Naked `new` of a bare generic class (via `new static()`, `new $name`,
+	 * or any path that didn't go through compile-time canonical-name rewrite).
+	 * Skip when ZEND_VERIFY_GENERIC_ARGUMENTS follows — that opcode handles
+	 * the synthesis-and-swap for the turbofish path. Otherwise: if every
+	 * type parameter has a default, synthesize and use the defaults monomorph.
+	 * For `new static()` / lexical paths with no defaults, fall back to a
+	 * bare instance (preserves the lexical-self semantic for generic classes
+	 * whose authors didn't declare defaults). For dynamic `new $name()` we
+	 * throw — the caller spelled out a generic class by name and a bare
+	 * instance with erased T is almost never what they want.
+	 *
+	 * IS_VAR distinguishes: IS_UNUSED → static/self/parent (lenient);
+	 * IS_VAR → dynamic name resolved via FETCH_CLASS (strict). */
+	if (UNEXPECTED(IS_VAR != IS_CONST && ce->generic_parameters
+			&& (opline + 1)->opcode != ZEND_VERIFY_GENERIC_ARGUMENTS)) {
+		if (ce->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS) {
+			ce = zend_synthesize_monomorph(ce, NULL, 0);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else if (IS_VAR == IS_VAR) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments "
+				"via dynamic class name; no defaults declared",
+				ZSTR_VAL(ce->name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		/* IS_UNUSED with no defaults: fall through with the bare ce. */
+	}
+
 	result = EX_VAR(opline->result.var);
 	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
 		ZVAL_UNDEF(result);
@@ -30626,7 +84179,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -30688,7 +84241,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
 		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -30713,6 +84280,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -30722,7 +84290,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -30737,14 +84305,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HAN
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEPARATE_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -30759,7 +84327,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -30767,7 +84335,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -30852,6 +84420,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -30879,7 +84448,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MAKE_REF_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1 = EX_VAR(opline->op1.var);
@@ -30912,32 +84481,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1;
-	zend_string *type;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	type = zend_zval_get_legacy_type(op1);
-	if (EXPECTED(type)) {
-		ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type);
-	} else {
-		ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
 	uint32_t arg_num = opline->op2.num;
 
 	if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-		ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
@@ -30952,21 +84503,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -31031,7 +84568,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HAND
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -31053,13 +84590,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HAND
 
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -31155,11 +84693,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND
 		}
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -31185,11 +84724,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER(
 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -31239,7 +84779,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLE
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -31249,11 +84790,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLE
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -31301,7 +84843,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDL
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -31311,11 +84854,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDL
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -31324,13 +84868,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLE
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -31339,13 +84884,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDL
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -31353,18 +84899,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_CV == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_VAR & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -31373,13 +84925,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HA
 	container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
 	zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -31394,13 +84947,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLE
 		((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -31411,13 +84965,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDL
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -31426,15 +84981,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_VAR == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
@@ -31445,13 +85006,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HA
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_VAR == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim;
@@ -31470,10 +85032,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDL
 		zend_fetch_dimension_address_W(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -31596,6 +85159,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA
 		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -31616,18 +85180,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -31775,167 +85341,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA
 		GC_DTOR_NO_REF(garbage);
 	}
 
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if (IS_CV == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if (IS_CV != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -32058,6 +85471,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA
 		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -32078,18 +85492,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -32187,6 +85603,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -32194,12 +85611,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 			if (IS_CV == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = EX_VAR(opline->op2.var);
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -32207,6 +85626,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -32228,6 +85648,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -32235,13 +85656,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 	}
 	if (IS_CV != IS_UNUSED) {
 
+
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -32388,158 +85810,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 	}
 	if (IS_CV != IS_UNUSED) {
 
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
-	zval *value;
-	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if (IS_CV == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_VAR == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = EX_VAR(opline->op2.var);
-			if (IS_CV == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = EX_VAR(opline->op2.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
-
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if (IS_CV == IS_UNUSED) {
-				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				dim = EX_VAR(opline->op2.var);
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
-
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
-		}
-	}
-	if (IS_CV != IS_UNUSED) {
 
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -32547,7 +85817,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -32645,6 +85915,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -32652,12 +85923,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 			if (IS_CV == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = EX_VAR(opline->op2.var);
 				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -32665,6 +85938,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -32686,6 +85960,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -32693,13 +85968,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA
 	}
 	if (IS_CV != IS_UNUSED) {
 
+
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -32728,7 +86004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUS
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -32757,7 +86033,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_REF_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *variable_ptr;
@@ -32791,11 +86067,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER
 		GC_DTOR(garbage);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -32827,12 +86104,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
+
 	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -32865,11 +86143,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -32887,6 +86167,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_CV != IS_CONST) {
@@ -32897,6 +86178,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -32929,6 +86211,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -32944,6 +86227,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_CV == IS_CONST &&
@@ -32956,6 +86240,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 		}
 		if (IS_CV != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -33002,7 +86287,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -33064,7 +86349,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
 		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -33089,6 +86388,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -33098,7 +86398,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -33113,14 +86413,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -33158,7 +86458,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(
 				offset = Z_REFVAL_P(offset);
 				goto offset_again;
 			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
 				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
 				goto num_index_dim;
 			} else if (Z_TYPE_P(offset) == IS_NULL) {
 				key = ZSTR_EMPTY_ALLOC();
@@ -33207,11 +86517,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -33251,11 +86562,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -33263,7 +86575,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -33348,6 +86660,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -33375,7 +86688,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array;
@@ -33443,7 +86756,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_
 }
 
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array;
@@ -33511,7 +86824,84 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_
 }
 
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CATCH_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_class_entry *ce, *catch_ce;
+	zend_object *exception;
+
+	SAVE_OPLINE();
+	/* Check whether an exception has been thrown, if not, jump over code */
+	if (EG(exception) == NULL) {
+		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+	}
+	if (IS_UNUSED == IS_UNUSED) {
+		/* catch (T $e) / catch (Box $e): polymorphic inline cache keyed on
+		 * (type_args generation, called_scope). The generation is a monotonic
+		 * nonce per zend_type_arg_table allocation, so it's ABA-safe across
+		 * calls that reuse the same heap address. NULL type_args maps to
+		 * generation 0 (the counter starts at 1). zend_fetch_class dispatches
+		 * to the right resolver based on the packed sub-type on miss. */
+		void **slot = CACHE_ADDR(opline->extended_value & ~ZEND_LAST_CATCH);
+		uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+		zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+		/* slot[2] != NULL distinguishes a populated entry from an
+		 * uninitialized (all-zeros) slot, which otherwise matches
+		 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+		if (EXPECTED(slot[2] != NULL
+				&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+			catch_ce = (zend_class_entry*)slot[2];
+		} else {
+			catch_ce = zend_fetch_class(NULL,
+				opline->op1.num | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+			if (EXPECTED(catch_ce)) {
+				slot[0] = (void*)cur_gen;
+				slot[1] = (void*)cur_scope;
+				slot[2] = (void*)catch_ce;
+			}
+		}
+	} else {
+		catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH);
+		if (UNEXPECTED(catch_ce == NULL)) {
+			catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT);
+
+			CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce);
+		}
+	}
+	ce = EG(exception)->ce;
+
+#ifdef HAVE_DTRACE
+	if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
+		DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
+	}
+#endif /* HAVE_DTRACE */
+
+	if (ce != catch_ce) {
+		if (!catch_ce || !instanceof_function(ce, catch_ce)) {
+			if (opline->extended_value & ZEND_LAST_CATCH) {
+				zend_rethrow_exception(execute_data);
+				HANDLE_EXCEPTION();
+			}
+			ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
+		}
+	}
+
+	exception = EG(exception);
+	EG(exception) = NULL;
+	if (RETURN_VALUE_USED(opline)) {
+		/* Always perform a strict assignment. There is a reasonable expectation that if you
+		 * write "catch (Exception $e)" then $e will actually be instanceof Exception. As such,
+		 * we should not permit coercion to string here. */
+		zval tmp;
+		ZVAL_OBJ(&tmp, exception);
+		zend_assign_to_variable(EX_VAR(opline->result.var), &tmp, IS_TMP_VAR, /* strict */ 1);
+	} else {
+		OBJ_RELEASE(exception);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *obj;
@@ -33523,6 +86913,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
 	SAVE_OPLINE();
 	obj = &EX(This);
 
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
 	do {
 		if (IS_UNUSED == IS_CONST ||
 		    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
@@ -33539,7 +86932,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
 					HANDLE_EXCEPTION();
 				}
 			}
-			zend_throw_error(NULL, "__clone method called on non-object");
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+
 
 			HANDLE_EXCEPTION();
 		}
@@ -33552,29 +86946,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
 	if (UNEXPECTED(clone_call == NULL)) {
 		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
 
+
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		HANDLE_EXCEPTION();
 	}
 
 	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
 		scope = EX(func)->op_array.scope;
-		if (clone->common.scope != scope) {
-			if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
-			 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
-				zend_wrong_clone_call(clone, scope);
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
 
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
-			}
+
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
 		}
 	}
 
 	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	uint32_t fetch_type;
 	zend_class_entry *called_scope, *scope;
@@ -33589,16 +86984,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_H
 				zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		}
 
 		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name);
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 
 	fetch_type = opline->op1.num;
+	if (zend_fetch_is_type_param(fetch_type)) {
+		SAVE_OPLINE();
+		zend_class_entry *resolved = zend_resolve_generic_type_param(
+			zend_unpack_type_param_index(fetch_type), fetch_type);
+		if (UNEXPECTED(!resolved)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), resolved->name);
+		ZEND_VM_NEXT_OPCODE();
+	}
 	scope = EX(func)->op_array.scope;
 	if (UNEXPECTED(scope == NULL)) {
 		SAVE_OPLINE();
@@ -33631,12 +87039,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_H
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -33701,7 +87109,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONS
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -33724,12 +87132,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONS
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -33779,7 +87189,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -33790,10 +87201,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -33841,7 +87254,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -33852,10 +87266,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -33863,11 +87279,15 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
 
 	SAVE_OPLINE();
 	container = &EX(This);
+	if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_UNUSED == IS_CONST ||
 	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -33941,6 +87361,8 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
@@ -34020,15 +87442,17 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
 fetch_obj_r_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -34043,13 +87467,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_
 		((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -34060,13 +87485,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -34074,6 +87500,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST
 
 	SAVE_OPLINE();
 	container = &EX(This);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_UNUSED == IS_CONST ||
 	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -34184,10 +87612,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST
 fetch_obj_is_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -34196,15 +87626,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_UNUSED == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
@@ -34215,13 +87651,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -34344,6 +87781,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O
 		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -34364,18 +87802,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -34524,166 +87965,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O
 	}
 
 
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = &EX(This);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if (IS_CONST == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-	} else {
-		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if (IS_CONST != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
 
 
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -34806,6 +88095,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O
 		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -34826,18 +88116,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -34868,12 +88161,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CON
 	}
 
 
+
+
 	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -34905,11 +88200,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CON
 
 
 
+
+
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -34938,13 +88236,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HA
 			}
 			rope[0] = zval_get_string_func(var);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *class_name;
 	USE_OPLINE
@@ -34983,10 +88282,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_
 		}
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -35017,12 +88317,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 
 
+
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -35055,6 +88358,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 					if (UNEXPECTED(EG(exception) != NULL)) {
 						if (IS_CONST != IS_CONST) {
 
+
 						}
 						HANDLE_EXCEPTION();
 					}
@@ -35065,6 +88369,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 				zend_invalid_method_call(object, function_name);
 
 
+
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -35089,6 +88395,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
 			}
 
+
 			if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
 				zend_objects_store_del(orig_obj);
 			}
@@ -35112,6 +88419,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 
 	if (IS_CONST != IS_CONST) {
 
+
 	}
 
 	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
@@ -35141,7 +88449,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -35159,6 +88467,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_CONST != IS_CONST) {
@@ -35169,6 +88478,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -35201,6 +88511,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -35216,6 +88527,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_CONST == IS_CONST &&
@@ -35228,6 +88540,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		}
 		if (IS_CONST != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -35274,7 +88587,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	uint32_t arg_num;
@@ -35306,7 +88619,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CON
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_constant *c;
@@ -35322,7 +88635,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPE
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_class_entry *ce, *scope;
 	zend_class_constant *c;
@@ -35347,6 +88660,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 				if (UNEXPECTED(ce == NULL)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 				CACHE_PTR(opline->extended_value, ce);
@@ -35356,6 +88670,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 			if (UNEXPECTED(ce == NULL)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		} else {
@@ -35373,6 +88688,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 			zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
 			ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 			HANDLE_EXCEPTION();
 		}
 		constant_name = Z_STR_P(constant_zv);
@@ -35380,6 +88696,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 		if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) {
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
 
+
 			ZEND_VM_NEXT_OPCODE();
 		}
 		zv = IS_CONST == IS_CONST
@@ -35393,6 +88710,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 				zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 
@@ -35400,6 +88718,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 				zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 
@@ -35417,6 +88736,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 				if (EG(exception)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -35427,6 +88747,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 				if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -35434,6 +88755,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 				if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) {
 					ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -35445,16 +88767,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 				ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
 			ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 			HANDLE_EXCEPTION();
 		}
 	} while (0);
 
 	ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -35469,14 +88793,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_H
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -35517,10 +88841,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -35567,10 +88893,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
 isset_object_finish:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -35578,7 +88906,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -35627,6 +88955,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = NULL;
@@ -35642,6 +88971,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
 			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_UNUSED == IS_CV) {
@@ -35662,6 +88992,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -35689,7 +89020,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zend_class_entry *ce, *scope;
 	zend_class_constant *c;
@@ -35822,7 +89153,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -35837,7 +89168,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPV
 
 	SAVE_OPLINE();
 	object = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
@@ -35858,7 +89189,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPV
 assign_op_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -35867,7 +89198,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPV
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
@@ -35887,7 +89218,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPV
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -35902,7 +89233,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPV
 		} else {
 			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
@@ -35910,12 +89241,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPV
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -35929,7 +89261,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR
 
 	SAVE_OPLINE();
 	object = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -35948,7 +89280,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR
 pre_incdec_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -35957,7 +89289,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
@@ -35965,22 +89297,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -35994,7 +89328,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVA
 
 	SAVE_OPLINE();
 	object = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -36013,7 +89347,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVA
 post_incdec_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -36022,28 +89356,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVA
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -36051,11 +89387,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
 
 	SAVE_OPLINE();
 	container = &EX(This);
+	if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_UNUSED == IS_CONST ||
 	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -36064,7 +89404,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
 			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP1();
 			}
-			zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 			ZVAL_NULL(EX_VAR(opline->result.var));
 			goto fetch_obj_r_finish;
 		} while (0);
@@ -36076,7 +89416,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
 		zend_string *name, *tmp_name;
 		zval *retval;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
 
 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
@@ -36129,12 +89469,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -36167,9 +89509,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
 					}
 				}
 			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -36193,7 +89535,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
 		}
 #endif
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -36208,10 +89550,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR
 fetch_obj_r_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -36219,11 +89562,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR
 	SAVE_OPLINE();
 
 	container = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(
-		result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR),
-		(((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		result, container, IS_UNUSED, property, IS_TMP_VAR,
+		((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_UNUSED == IS_VAR) {
@@ -36232,16 +89575,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
 
 	SAVE_OPLINE();
 	container = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
-	zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -36249,7 +89592,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -36257,6 +89600,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
 
 	SAVE_OPLINE();
 	container = &EX(This);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_UNUSED == IS_CONST ||
 	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -36267,7 +89612,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
 					break;
 				}
 			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
 				ZVAL_UNDEFINED_OP2();
 			}
 			ZVAL_NULL(EX_VAR(opline->result.var));
@@ -36281,7 +89626,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
 		zend_string *name, *tmp_name;
 		zval *retval;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			cache_slot = CACHE_ADDR(opline->extended_value);
 
 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
@@ -36308,7 +89653,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -36341,9 +89686,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
 					}
 				}
 			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -36352,7 +89697,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
 
 		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -36367,10 +89712,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA
 fetch_obj_is_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -36379,24 +89725,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_UNUSED == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
 
 	SAVE_OPLINE();
 	container = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
-	zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -36404,7 +89756,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TM
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -36421,14 +89773,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -36454,7 +89806,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -36522,11 +89874,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -36536,9 +89889,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -36547,18 +89900,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -36575,14 +89930,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -36608,7 +89963,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -36676,9 +90031,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 			UNDEF_RESULT();
@@ -36690,9 +90045,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -36707,166 +90062,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = &EX(This);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -36883,14 +90085,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -36916,7 +90118,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -36984,11 +90186,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -36998,9 +90201,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -37009,18 +90212,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -37028,35 +90233,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP
 	SAVE_OPLINE();
 
 	container = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
 
 	if (1) {
 		if (IS_UNUSED == IS_UNUSED) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		}
 	} else {
-		zend_assign_to_property_reference(container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -37064,35 +90270,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP
 	SAVE_OPLINE();
 
 	container = &EX(This);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
 
 	if (1) {
 		if (IS_UNUSED == IS_UNUSED) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		}
 	} else {
-		zend_assign_to_property_reference(container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -37100,23 +90308,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_H
 
 	/* Compiler allocates the necessary number of zval slots to keep the rope */
 	rope = (zend_string**)EX_VAR(opline->result.var);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CONST) {
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		rope[0] = Z_STR_P(var);
 		if (UNEXPECTED(Z_REFCOUNTED_P(var))) {
 			Z_ADDREF_P(var);
 		}
 	} else {
-		var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+		var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
+			if (IS_TMP_VAR == IS_CV) {
 				rope[0] = zend_string_copy(Z_STR_P(var));
 			} else {
 				rope[0] = Z_STR_P(var);
 			}
 		} else {
 			SAVE_OPLINE();
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 			}
 			rope[0] = zval_get_string_func(var);
@@ -37127,36 +90335,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_H
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *class_name;
 	USE_OPLINE
 
 	SAVE_OPLINE();
-	if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+	if (IS_TMP_VAR == IS_UNUSED) {
 		Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num);
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-	} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	} else if (IS_TMP_VAR == IS_CONST) {
 		zend_class_entry *ce = CACHED_PTR(opline->extended_value);
 
 		if (UNEXPECTED(ce == NULL)) {
-			class_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 			ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num);
 			CACHE_PTR(opline->extended_value, ce);
 		}
 		Z_CE_P(EX_VAR(opline->result.var)) = ce;
 	} else {
-		class_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+		class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 try_class_name:
 		if (Z_TYPE_P(class_name) == IS_OBJECT) {
 			Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
 		} else if (Z_TYPE_P(class_name) == IS_STRING) {
 			Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) {
 			class_name = Z_REFVAL_P(class_name);
 			goto try_class_name;
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 					HANDLE_EXCEPTION();
@@ -37170,7 +90378,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -37185,28 +90393,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
 
 	object = &EX(This);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
+	if (IS_TMP_VAR != IS_CONST &&
 	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
 		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
 				function_name = Z_REFVAL_P(function_name);
 				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 					break;
 				}
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -37237,18 +90447,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
 				if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
 					object = ZVAL_UNDEFINED_OP1();
 					if (UNEXPECTED(EG(exception) != NULL)) {
-						if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+						if (IS_TMP_VAR != IS_CONST) {
 							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 						}
 						HANDLE_EXCEPTION();
 					}
 				}
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-					function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 				}
 				zend_invalid_method_call(object, function_name);
 				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -37256,18 +90467,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
 
 	called_scope = obj->ce;
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	if (IS_TMP_VAR == IS_CONST &&
 	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
 		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
 	} else {
 		zend_object *orig_obj = obj;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-			function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		}
 
 		/* First, locate the function. */
-		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
 		if (UNEXPECTED(fbc == NULL)) {
 			if (EXPECTED(!EG(exception))) {
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
@@ -37278,7 +90489,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
 			}
 			HANDLE_EXCEPTION();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+		if (IS_TMP_VAR == IS_CONST &&
 		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
 		    EXPECTED(obj == orig_obj)) {
 			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
@@ -37294,7 +90505,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 
@@ -37325,7 +90536,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -37345,7 +90556,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 				HANDLE_EXCEPTION();
 			}
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				CACHE_PTR(opline->result.num, ce);
 			}
 		}
@@ -37360,24 +90571,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 	}
 
 	if (IS_UNUSED == IS_CONST &&
-	    (IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	    IS_TMP_VAR == IS_CONST &&
 	    EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) {
 		/* nothing to do */
 	} else if (IS_UNUSED != IS_CONST &&
-	           (IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	           IS_TMP_VAR == IS_CONST &&
 	           EXPECTED(CACHED_PTR(opline->result.num) == ce)) {
 		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
-	} else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	} else if (IS_TMP_VAR != IS_UNUSED) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR != IS_CONST) {
 			if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
 				do {
-					if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
+					if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) {
 						function_name = Z_REFVAL_P(function_name);
 						if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 							break;
 						}
-					} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+					} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 						ZVAL_UNDEFINED_OP2();
 						if (UNEXPECTED(EG(exception) != NULL)) {
 							HANDLE_EXCEPTION();
@@ -37393,7 +90604,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		if (ce->get_static_method) {
 			fbc = ce->get_static_method(ce, Z_STR_P(function_name));
 		} else {
-			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+			fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
 		}
 		if (UNEXPECTED(fbc == NULL)) {
 			if (EXPECTED(!EG(exception))) {
@@ -37402,7 +90613,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 			HANDLE_EXCEPTION();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+		if (IS_TMP_VAR == IS_CONST &&
 		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
 			EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) {
 			CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
@@ -37410,7 +90621,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
 			init_func_run_time_cache(&fbc->op_array);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 		}
 	} else {
@@ -37458,7 +90669,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -37473,14 +90684,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -37489,7 +90700,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_H
 
 	SAVE_OPLINE();
 	container = &EX(This);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -37506,7 +90717,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_H
 				break;
 			}
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(offset);
 		} else {
 			name = zval_try_get_tmp_string(offset, &tmp_name);
@@ -37514,18 +90725,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_H
 				break;
 			}
 		}
-		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -37535,7 +90747,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
 
 	SAVE_OPLINE();
 	container = &EX(This);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (IS_UNUSED == IS_CONST ||
 	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -37551,7 +90763,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		name = Z_STR_P(offset);
 	} else {
 		name = zval_try_get_tmp_string(offset, &tmp_name);
@@ -37563,19 +90775,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
 
 	result =
 		(opline->extended_value & ZEND_ISEMPTY) ^
-		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
 isset_object_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -37583,7 +90796,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDL
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -37632,6 +90845,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDL
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = NULL;
@@ -37647,6 +90861,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDL
 			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_UNUSED == IS_CV) {
@@ -37660,9 +90875,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDL
 	}
 
 	/* Set the new yielded key */
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
 			key = Z_REFVAL_P(key);
 		}
 		ZVAL_COPY(&generator->key, key);
@@ -37695,7 +90910,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDL
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *class_name;
 	USE_OPLINE
@@ -37734,10 +90949,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED
 		}
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -37755,6 +90971,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_UNUSED != IS_CONST) {
@@ -37765,6 +90982,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -37797,6 +91015,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -37812,6 +91031,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_UNUSED == IS_CONST &&
@@ -37824,6 +91044,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		}
 		if (IS_UNUSED != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -37870,7 +91091,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	if (IS_UNUSED == IS_UNUSED) {
 		SAVE_OPLINE();
@@ -37896,6 +91117,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED
 			ZVAL_DEREF(retval_ptr);
 		}
 
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
@@ -37937,14 +91170,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED
 	}
 }
 
-static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	SAVE_OPLINE();
 	zend_verify_never_error(EX(func));
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	uint32_t arg_num;
@@ -37976,7 +91209,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNU
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	uint32_t arg_num;
@@ -38008,7 +91241,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38022,7 +91255,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_UNDEF_ARGS_S
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *result;
@@ -38051,6 +91284,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER
 		ce = Z_CE_P(EX_VAR(opline->op1.var));
 	}
 
+	/* Naked `new` of a bare generic class (via `new static()`, `new $name`,
+	 * or any path that didn't go through compile-time canonical-name rewrite).
+	 * Skip when ZEND_VERIFY_GENERIC_ARGUMENTS follows — that opcode handles
+	 * the synthesis-and-swap for the turbofish path. Otherwise: if every
+	 * type parameter has a default, synthesize and use the defaults monomorph.
+	 * For `new static()` / lexical paths with no defaults, fall back to a
+	 * bare instance (preserves the lexical-self semantic for generic classes
+	 * whose authors didn't declare defaults). For dynamic `new $name()` we
+	 * throw — the caller spelled out a generic class by name and a bare
+	 * instance with erased T is almost never what they want.
+	 *
+	 * IS_UNUSED distinguishes: IS_UNUSED → static/self/parent (lenient);
+	 * IS_VAR → dynamic name resolved via FETCH_CLASS (strict). */
+	if (UNEXPECTED(IS_UNUSED != IS_CONST && ce->generic_parameters
+			&& (opline + 1)->opcode != ZEND_VERIFY_GENERIC_ARGUMENTS)) {
+		if (ce->ce_flags & ZEND_ACC_GENERIC_ALL_DEFAULTS) {
+			ce = zend_synthesize_monomorph(ce, NULL, 0);
+			if (UNEXPECTED(ce == NULL)) {
+				ZVAL_UNDEF(EX_VAR(opline->result.var));
+				HANDLE_EXCEPTION();
+			}
+		} else if (IS_UNUSED == IS_VAR) {
+			zend_throw_error(NULL,
+				"Cannot instantiate generic class %s without type arguments "
+				"via dynamic class name; no defaults declared",
+				ZSTR_VAL(ce->name));
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		/* IS_UNUSED with no defaults: fall through with the bare ce. */
+	}
+
 	result = EX_VAR(opline->result.var);
 	if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) {
 		ZVAL_UNDEF(result);
@@ -38091,7 +91356,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -38106,14 +91371,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38121,7 +91386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -38170,6 +91435,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = NULL;
@@ -38185,6 +91451,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
 			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_UNUSED == IS_CV) {
@@ -38205,6 +91472,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -38232,7 +91500,246 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	uint32_t arity = opline->op2.num;
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	/* Skip the entry lookup for speculative sites (args_id == 0). */
+	zend_turbofish_args_entry *tf_entry =
+		(IS_UNUSED == IS_UNUSED && opline->extended_value)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_UNUSED == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_UNUSED) {
+		/* Erased fast path: non-generic speculative site, nothing to verify. */
+		if (args_box == NULL
+				&& (!ZEND_USER_CODE(call->func->type)
+					|| !call->func->op_array.generic_parameters)) {
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Concrete turbofish args: dispatch to a synthesized plain monomorph and
+		 * skip generic verification (the monomorph's RECV does concrete checks). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, arity, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_verify_check_exception;
+			}
+		}
+		/* Runtime-promoted site: install the cached invariant table after a func
+		 * guard (cache_slot[3], bit1 = value check is a no-op). */
+		if (cache_slot && cache_slot[3]
+				&& ((uintptr_t) cache_slot[3] & ~(uintptr_t)3) == (uintptr_t) call->func) {
+			call->type_args = (zend_type_arg_table *) cache_slot[0];
+			if (((uintptr_t) cache_slot[3] & 2) == 0) {
+				zend_verify_generic_arg_types(call, args_box);
+				if (UNEXPECTED(EG(exception))) {
+					goto generic_verify_check_exception;
+				}
+			}
+			ZEND_VM_NEXT_OPCODE();
+		}
+		/* Inner/inference call already monomorphized: swap func + reinstall table. */
+		if (cache_slot && (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_MONOMORPH) {
+			zend_type_arg_table *ma = NULL;
+			zend_function *mono = zend_try_monomorph_resolved_call(call, NULL, cache_slot, &ma);
+			if (mono) {
+				call->func = mono;
+				call->type_args = ma;
+				ZEND_VM_NEXT_OPCODE();
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete turbofish VERIFY: install the precomputed SHM table after
+			 * the arity/bound check (memoized in cache_slot[0] per resolved func).
+			 * The persisted guard excludes the no-opcache heap-table case. */
+			bool checked = (cache_slot && cache_slot[0] == (void *) call->func);
+			if (!checked) {
+				zend_check_generic_call_arguments(call->func, arity, args_box);
+			}
+			if (EXPECTED(!EG(exception))) {
+				if (!checked && cache_slot) {
+					cache_slot[0] = (void *) call->func;
+				}
+				call->type_args = tf_entry->concrete_table;
+				if (!tf_entry->concrete_skip_value_check) {
+					zend_verify_generic_arg_types(call, args_box);
+				}
+			}
+		} else {
+			zend_check_generic_call_arguments(call->func, arity, args_box);
+			if (!EG(exception)) {
+				zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+				if (t) {
+					if (call->type_args) {
+						zend_type_arg_table_destroy(call->type_args);
+					}
+					call->type_args = t;
+				}
+				/* If the resolved table is invariant (CONCRETE sentinel), try to
+				 * monomorphize so later calls take the mono fast path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					zend_type_arg_table *ma = NULL;
+					zend_function *mono = zend_try_monomorph_resolved_call(call, t, cache_slot, &ma);
+					if (mono) {
+						call->func = mono;
+						call->type_args = ma;
+						ZEND_VM_NEXT_OPCODE();
+					}
+				}
+				zend_verify_generic_arg_types(call, args_box);
+				/* Promote the invariant site: record the resolved callee in
+				 * cache_slot[3] so later calls take the minimal install path. */
+				if (EXPECTED(!EG(exception)) && t
+						&& cache_slot && cache_slot[0] == (void *) t
+						&& (uintptr_t) cache_slot[1] == ZEND_TURBOFISH_CACHE_KEY_CONCRETE) {
+					/* Tag bits (func is >=8-aligned): bit0 = PROMOTED, bit1 = value
+					 * check is a no-op. slot[1] stays CONCRETE so the build cache
+					 * keeps returning the table on a func-guard miss. */
+					uintptr_t fn = (uintptr_t) call->func | 1u;
+					if (ZEND_USER_CODE(call->func->type)
+							&& call->func->op_array.generic_types
+							&& call->func->op_array.generic_types->parameters
+							&& zend_count_generic_value_checks(
+								call->func->op_array.generic_types->parameters) == 0) {
+						fn |= 2; /* value check is a no-op for this callee */
+					}
+					cache_slot[3] = (void *) fn;
+				}
+			}
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Monomorphize: synthesize (or look up) Box and swap both the
+		 * object's class entry and the pending constructor call. The monomorph
+		 * shares Box's property layout, so swapping ce is safe; swapping
+		 * call->func ensures the constructor's RECV opcodes verify against the
+		 * monomorph's substituted arg_info. The call-site inline cache (incl. the
+		 * concrete-args fast path) lives in zend_apply_generic_new. */
+		zend_apply_generic_new(new_obj, call, args_box, arity, cache_slot, /* do_checks */ true);
+	}
+
+generic_verify_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		/* Args have already been pushed by the SEND opcodes preceding the
+		 * VERIFY emission for call kind; release them so refcounted values
+		 * don't leak. */
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+/* Installs the type-arg table (and, for `new`, swaps the object's class to
+ * its monomorph) without running the runtime arity + bound checks that
+ * VERIFY does. Emitted by the compiler when the callee/ce is statically
+ * known, the turbofish args are concrete, and bounds were validated at
+ * compile time — so the runtime checks are pure overhead. The value-arg
+ * type-check (zend_verify_generic_arg_types) still runs since value
+ * arguments are runtime values. */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zend_execute_data *call = EX(call);
+	void **cache_slot = opline->result.num ? CACHE_ADDR(opline->result.num) : NULL;
+	zend_turbofish_args_entry *tf_entry =
+		(IS_UNUSED == IS_UNUSED)
+			? zend_generic_get_or_cache_args_entry(&EX(func)->op_array, opline->extended_value, cache_slot)
+			: NULL;
+	const zend_type *args_box = (IS_UNUSED == IS_UNUSED)
+		? (tf_entry ? &tf_entry->args_box : NULL)
+		: zend_generic_get_or_cache_args_box(&EX(func)->op_array, opline->extended_value, cache_slot);
+
+	SAVE_OPLINE();
+
+	if (IS_UNUSED == IS_UNUSED) {
+		/* Dispatch to a synthesized plain monomorph (see ZEND_VERIFY_GENERIC_ARGUMENTS). */
+		{
+			zend_type_arg_table *mono_args = NULL;
+			zend_function *mono = zend_get_or_synthesize_call_monomorph(call, args_box, opline->op2.num, cache_slot, &mono_args);
+			if (mono) {
+				call->func = mono;
+				call->type_args = mono_args;
+				ZEND_VM_NEXT_OPCODE();
+			}
+			if (UNEXPECTED(EG(exception))) {
+				goto generic_install_check_exception;
+			}
+		}
+		if (tf_entry && tf_entry->concrete_table && tf_entry->concrete_table->persisted) {
+			/* Concrete INSTALL: install the precomputed SHM table directly. The
+			 * persisted guard excludes the no-opcache heap-table case (whose table
+			 * is owned by the turbofish entry and must not be freed at teardown). */
+			call->type_args = tf_entry->concrete_table;
+			if (!tf_entry->concrete_skip_value_check) {
+				zend_verify_generic_arg_types(call, args_box);
+			}
+		} else {
+			zend_type_arg_table *t = zend_build_or_get_cached_type_args(call, args_box, cache_slot);
+			if (t) {
+				if (call->type_args) {
+					zend_type_arg_table_destroy(call->type_args);
+				}
+				call->type_args = t;
+			}
+			zend_verify_generic_arg_types(call, args_box);
+		}
+	} else {
+		zval *new_obj = EX_VAR(opline->op1.var);
+		/* Statically pre-validated: skip the runtime arity/bound check, but
+		 * still cache the resolved monomorph at the call site. */
+		zend_apply_generic_new(new_obj, call, args_box, opline->op2.num, cache_slot, /* do_checks */ false);
+	}
+
+generic_install_check_exception:
+	if (UNEXPECTED(EG(exception))) {
+		zend_vm_stack_free_args(call);
+
+		if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+			zend_string_release_ex(call->func->common.function_name, 0);
+			zend_free_trampoline(call->func);
+		}
+
+		if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
+			OBJ_RELEASE(Z_OBJ(call->This));
+		}
+
+		EX(call) = call->prev_execute_data;
+		zend_vm_stack_free_call_frame(call);
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38243,11 +91750,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_THIS_SPEC_UN
 		Z_ADDREF_P(result);
 		ZEND_VM_NEXT_OPCODE();
 	} else {
-		ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38257,7 +91764,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38267,7 +91774,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38306,11 +91813,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_H
 			break;
 		}
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38328,7 +91836,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CALLED_CLASS_SPEC_UNUSED_U
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -38336,7 +91844,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUS
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_array *ht;
@@ -38413,12 +91921,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS
 }
 
 /* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_execute_data *call = EX(call);
 
-	zend_closure_from_frame(EX_VAR(opline->result.var), call);
+	if (opline->extended_value != (uint32_t)-1) {
+		zend_object *closure = CACHED_PTR(opline->extended_value);
+		if (closure) {
+			ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure);
+		} else {
+			/* Rotate the key for better hash distribution. */
+			const int shift = sizeof(size_t) == 4 ? 6 : 7;
+			zend_ulong key = (zend_ulong)(uintptr_t)call->func;
+			key = (key >> shift) | (key << ((sizeof(key) * 8) - shift));
+			zval *closure_zv = zend_hash_index_lookup(&EG(callable_convert_cache), key);
+			if (Z_TYPE_P(closure_zv) == IS_NULL) {
+				zend_closure_from_frame(closure_zv, call);
+			}
+			ZEND_ASSERT(Z_TYPE_P(closure_zv) == IS_OBJECT);
+			closure = Z_OBJ_P(closure_zv);
+			ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure);
+			CACHE_PTR(opline->extended_value, closure);
+		}
+	} else {
+		zend_closure_from_frame(EX_VAR(opline->result.var), call);
+	}
 
 	if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
 		OBJ_RELEASE(Z_OBJ(call->This));
@@ -38431,7 +91959,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALLABLE_CONVERT_SPEC_UNUSED_U
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -38446,12 +91974,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_
 #endif
 	{
 		zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline);
-		function(EX_VAR(opline->result.var));
+		function(result);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	SAVE_OPLINE();
@@ -38466,12 +91994,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVE
 #endif
 	{
 		zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline);
-		function(EX_VAR(opline->result.var));
+		function(result);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -38536,7 +92064,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_H
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -38559,12 +92087,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_H
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -38614,7 +92144,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HAN
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -38625,10 +92156,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HAN
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -38676,7 +92209,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HA
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -38687,10 +92221,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HA
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -38698,11 +92234,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN
 
 	SAVE_OPLINE();
 	container = &EX(This);
+	if (IS_UNUSED & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_UNUSED == IS_CONST ||
 	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -38776,6 +92316,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
@@ -38855,10 +92397,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN
 fetch_obj_r_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -38873,13 +92417,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HAN
 		((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -38890,13 +92435,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HA
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -38904,6 +92450,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA
 
 	SAVE_OPLINE();
 	container = &EX(This);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_UNUSED == IS_CONST ||
 	    (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -39014,10 +92562,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA
 fetch_obj_is_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -39026,15 +92576,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_UNUSED == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
@@ -39045,13 +92601,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_UNUSED == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -39174,6 +92731,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D
 		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -39194,18 +92752,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -39354,166 +92915,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D
 	}
 
 
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = &EX(This);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if (IS_CV == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if (IS_CV != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
 
 
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -39636,6 +93045,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D
 		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -39656,18 +93066,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -39698,12 +93111,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_
 	}
 
 
+
+
 	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -39735,11 +93150,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_
 
 
 
+
+
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string **rope;
@@ -39768,13 +93186,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDL
 			}
 			rope[0] = zval_get_string_func(var);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *class_name;
 	USE_OPLINE
@@ -39813,10 +93232,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HAN
 		}
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -39847,12 +93267,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 
 
+
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -39885,6 +93308,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
 					if (UNEXPECTED(EG(exception) != NULL)) {
 						if (IS_CV != IS_CONST) {
 
+
 						}
 						HANDLE_EXCEPTION();
 					}
@@ -39895,6 +93319,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
 				zend_invalid_method_call(object, function_name);
 
 
+
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -39919,6 +93345,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
 			}
 
+
 			if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
 				zend_objects_store_del(orig_obj);
 			}
@@ -39942,6 +93369,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
 
 	if (IS_CV != IS_CONST) {
 
+
 	}
 
 	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
@@ -39971,7 +93399,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -39989,6 +93417,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 			ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				HANDLE_EXCEPTION();
 			}
 			if (IS_CV != IS_CONST) {
@@ -39999,6 +93428,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		ce = zend_fetch_class(NULL, opline->op1.num);
 		if (UNEXPECTED(ce == NULL)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -40031,6 +93461,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 					}
 					zend_throw_error(NULL, "Method name must be a string");
 
+
 					HANDLE_EXCEPTION();
 				} while (0);
 			}
@@ -40046,6 +93477,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 				zend_undefined_method(ce, Z_STR_P(function_name));
 			}
 
+
 			HANDLE_EXCEPTION();
 		}
 		if (IS_CV == IS_CONST &&
@@ -40058,6 +93490,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 		}
 		if (IS_CV != IS_CONST) {
 
+
 		}
 	} else {
 		if (UNEXPECTED(ce->constructor == NULL)) {
@@ -40104,7 +93537,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -40119,14 +93552,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HAND
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -40167,10 +93600,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDL
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -40217,10 +93652,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN
 isset_object_finish:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -40228,7 +93665,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -40277,6 +93714,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = NULL;
@@ -40292,6 +93730,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
 			} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_UNUSED == IS_CV) {
@@ -40312,6 +93751,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -40339,7 +93779,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_NOT_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -40360,12 +93800,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_
 		SAVE_OPLINE();
 		ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_pre_inc_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40394,10 +93835,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_inc_help
 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40412,10 +93854,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RE
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40430,10 +93872,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RE
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_pre_dec_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40463,10 +93905,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_dec_help
 		ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40481,10 +93924,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RE
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40499,10 +93942,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RE
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_post_inc_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40530,10 +93973,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_inc_hel
 		increment_function(var_ptr);
 	} while (0);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40546,10 +93990,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_H
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV  zend_post_dec_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40577,10 +94021,11 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_dec_hel
 		decrement_function(var_ptr);
 	} while (0);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_DEC_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -40593,10 +94038,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_H
 		ZEND_VM_NEXT_OPCODE();
 	}
 
-	ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_CV_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ECHO_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *z;
@@ -40621,10 +94066,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCO
 		zend_string_release_ex(str, 0);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -40658,7 +94104,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDL
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -40692,7 +94138,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HAND
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_EX_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -40718,6 +94164,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_O
 	SAVE_OPLINE();
 	ret = i_zend_is_true(val);
 
+
 	if (ret) {
 		ZVAL_TRUE(EX_VAR(opline->result.var));
 		opline++;
@@ -40728,7 +94175,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_O
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_EX_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -40753,6 +94200,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_
 	SAVE_OPLINE();
 	ret = i_zend_is_true(val);
 
+
 	if (ret) {
 		ZVAL_TRUE(EX_VAR(opline->result.var));
 		opline = OP_JMP_ADDR(opline, opline->op2);
@@ -40763,15 +94211,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_
 	ZEND_VM_JMP(opline);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval_ptr;
 	zval *return_value;
 
+
 	retval_ptr = EX_VAR(opline->op1.var);
 	return_value = EX(return_value);
 
+
 	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
 		SAVE_OPLINE();
 		retval_ptr = ZVAL_UNDEFINED_OP1();
@@ -40837,19 +94287,24 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN
 
 
 
-	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+
+
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval_ptr;
 	zval *return_value;
 
+
 	SAVE_OPLINE();
 
 	return_value = EX(return_value);
 
+
 	do {
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR)) ||
 		    (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
@@ -40859,6 +94314,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
 			retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
 			if (!return_value) {
 
+
 			} else {
 				if (IS_CV == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
 					ZVAL_COPY_VALUE(return_value, retval_ptr);
@@ -40883,6 +94339,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
 					ZVAL_NEW_REF(return_value, retval_ptr);
 				} else {
 
+
 				}
 				break;
 			}
@@ -40897,13 +94354,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
 			ZVAL_REF(return_value, Z_REF_P(retval_ptr));
 		}
 
+
 	} while (0);
 
 
-	ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+
+
+	zend_return_unwrap_ref(execute_data, return_value);
+
+	ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *retval;
@@ -40939,6 +94401,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CV_HANDL
 		}
 	}
 
+
 	EG(current_execute_data) = EX(prev_execute_data);
 
 	/* Close the generator to free up resources */
@@ -40948,7 +94411,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CV_HANDL
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -40972,19 +94435,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPC
 			}
 			zend_throw_error(NULL, "Can only throw objects");
 
+
 			HANDLE_EXCEPTION();
 		}
 	} while (0);
 
-	zend_exception_save();
 	Z_TRY_ADDREF_P(value);
 	zend_throw_exception_object(value);
-	zend_exception_restore();
+
 
 	HANDLE_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *arg, *param;
@@ -41001,10 +94464,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND
 		ZVAL_COPY(param, arg);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val;
@@ -41025,12 +94489,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO
 		SAVE_OPLINE();
 		ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val));
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *obj;
@@ -41042,6 +94507,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
 	SAVE_OPLINE();
 	obj = EX_VAR(opline->op1.var);
 
+	/* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
+	 * The OPcode intentionally does not support a clone-with property list to keep it simple. */
+
 	do {
 		if (IS_CV == IS_CONST ||
 		    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) {
@@ -41058,7 +94526,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
 					HANDLE_EXCEPTION();
 				}
 			}
-			zend_throw_error(NULL, "__clone method called on non-object");
+			zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj));
+
 
 			HANDLE_EXCEPTION();
 		}
@@ -41071,29 +94540,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
 	if (UNEXPECTED(clone_call == NULL)) {
 		zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
 
+
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		HANDLE_EXCEPTION();
 	}
 
 	if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) {
 		scope = EX(func)->op_array.scope;
-		if (clone->common.scope != scope) {
-			if (UNEXPECTED(clone->common.fn_flags & ZEND_ACC_PRIVATE)
-			 || UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
-				zend_wrong_clone_call(clone, scope);
+		ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC));
+		if (!zend_check_method_accessible(clone, scope)) {
+			zend_bad_method_call(clone, clone->common.function_name, scope);
 
-				ZVAL_UNDEF(EX_VAR(opline->result.var));
-				HANDLE_EXCEPTION();
-			}
+
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
 		}
 	}
 
 	ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr;
@@ -41126,6 +94596,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
 					if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result);
 				}
 
+
 				ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 			}
 
@@ -41137,10 +94608,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
 			}
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_op_array *new_op_array;
@@ -41151,6 +94623,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
 	new_op_array = zend_include_or_eval(inc_filename, opline->extended_value);
 	if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 		if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) {
 			destroy_op_array(new_op_array);
 			efree_size(new_op_array, sizeof(zend_op_array));
@@ -41200,8 +94673,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
 		call->prev_execute_data = execute_data;
 		i_init_code_execute_data(call, new_op_array, return_value);
 
+
 		if (EXPECTED(zend_execute_ex == execute_ex)) {
 
+
 			ZEND_VM_ENTER();
 		} else {
 			ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
@@ -41215,15 +94690,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
 		if (UNEXPECTED(EG(exception) != NULL)) {
 			zend_rethrow_exception(execute_data);
 
+
 			UNDEF_RESULT();
 			HANDLE_EXCEPTION();
 		}
 	}
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array_ptr, *result;
@@ -41239,6 +94716,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
 		}
 		Z_FE_POS_P(result) = 0;
 
+
 		ZEND_VM_NEXT_OPCODE();
 	} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
 		zend_object *zobj = Z_OBJ_P(array_ptr);
@@ -41248,6 +94726,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
 				if (UNEXPECTED(EG(exception))) {
 					UNDEF_RESULT();
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -41272,15 +94751,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
 			if (zend_hash_num_elements(properties) == 0) {
 				Z_FE_ITER_P(result) = (uint32_t) -1;
 
+
 				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 			}
 
 			Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
 			bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(EG(exception))) {
 				HANDLE_EXCEPTION();
 			} else if (is_empty) {
@@ -41294,11 +94776,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
 
+
 		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *array_ptr, *array_ref;
@@ -41334,6 +94817,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
 		}
 		Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0);
 
+
 		ZEND_VM_NEXT_OPCODE();
 	} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
 		if (!Z_OBJCE_P(array_ptr)->get_iterator) {
@@ -41344,6 +94828,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
 				if (UNEXPECTED(EG(exception))) {
 					UNDEF_RESULT();
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
@@ -41370,15 +94855,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
 			if (zend_hash_num_elements(properties) == 0) {
 				Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
 
+
 				ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 			}
 
 			Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
 			bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(EG(exception))) {
 				HANDLE_EXCEPTION();
 			} else if (is_empty) {
@@ -41392,11 +94880,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
 
+
 		ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -41417,6 +94906,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_O
 
 	if (UNEXPECTED(EG(exception))) {
 
+
 		ZVAL_UNDEF(EX_VAR(opline->result.var));
 		HANDLE_EXCEPTION();
 	}
@@ -41439,10 +94929,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_O
 		ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -41483,7 +94974,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *val, *result;
@@ -41496,6 +94987,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CV_H
 				val = Z_REFVAL_P(val);
 				if (Z_TYPE_P(val) <= IS_NULL) {
 
+
 					break;
 				}
 			}
@@ -41527,7 +95019,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CV_H
 	ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -41565,7 +95057,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
@@ -41577,6 +95069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
 		zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
 
+
 		UNDEF_RESULT();
 		HANDLE_EXCEPTION();
 	}
@@ -41589,6 +95082,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
 		}
 		Z_FE_POS(generator->values) = 0;
 
+
 	} else if (IS_CV != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) {
 		zend_class_entry *ce = Z_OBJCE_P(val);
 		if (ce == zend_ce_generator) {
@@ -41596,6 +95090,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
 
 			Z_ADDREF_P(val);
 
+
 			if (UNEXPECTED(new_gen->execute_data == NULL)) {
 				zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue");
 				zval_ptr_dtor(val);
@@ -41619,6 +95114,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
 		} else {
 			zend_object_iterator *iter = ce->get_iterator(ce, val, 0);
 
+
 			if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
 				if (!EG(exception)) {
 					zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name));
@@ -41645,6 +95141,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
 	} else {
 		zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables");
 
+
 		UNDEF_RESULT();
 		HANDLE_EXCEPTION();
 	}
@@ -41665,7 +95162,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -41685,6 +95182,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP
 			if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) {
 				ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value));
 
+
 				ZEND_VM_NEXT_OPCODE();
 			}
 		}
@@ -41710,7 +95208,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP
 				}
 
 				ZVAL_COPY(&tmp, value);
-				if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
+				if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
 					ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
 					zval_ptr_dtor(&tmp);
 					break;
@@ -41724,10 +95222,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP
 		} while (0);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_CHECK_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -41757,13 +95256,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV
 	if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 		SAVE_OPLINE();
 
+
 		ZEND_VM_SMART_BRANCH(result, 1);
 	} else {
 		ZEND_VM_SMART_BRANCH(result, 0);
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	uint32_t fetch_type;
 	zend_class_entry *called_scope, *scope;
@@ -41778,16 +95278,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDL
 				zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op));
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		}
 
 		ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name);
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 
 	fetch_type = opline->op1.num;
+	if (zend_fetch_is_type_param(fetch_type)) {
+		SAVE_OPLINE();
+		zend_class_entry *resolved = zend_resolve_generic_type_param(
+			zend_unpack_type_param_index(fetch_type), fetch_type);
+		if (UNEXPECTED(!resolved)) {
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+		ZVAL_STR_COPY(EX_VAR(opline->result.var), resolved->name);
+		ZEND_VM_NEXT_OPCODE();
+	}
 	scope = EX(func)->op_array.scope;
 	if (UNEXPECTED(scope == NULL)) {
 		SAVE_OPLINE();
@@ -41820,12 +95333,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDL
 			}
 			ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name);
 			break;
-		EMPTY_SWITCH_DEFAULT_CASE()
+		default: ZEND_UNREACHABLE();
 	}
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BIND_STATIC_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	HashTable *ht;
@@ -41878,7 +95391,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_HANDLER(ZE
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	HashTable *ht;
@@ -41906,7 +95419,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_C
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -41919,7 +95432,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -41932,7 +95445,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -41945,7 +95458,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -41958,7 +95471,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -41971,7 +95484,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -41984,7 +95497,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OV
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -41997,7 +95510,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -42010,7 +95523,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -42021,7 +95534,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_NO_O
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_LONG_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -42032,7 +95545,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_SPEC
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -42043,7 +95556,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_NO_O
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_DEC_LONG_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -42054,7 +95567,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_SPEC
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -42071,7 +95584,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SP
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42082,10 +95595,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND
 	div_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42096,10 +95611,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND
 	pow_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42172,11 +95689,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z
 		concat_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42188,10 +95707,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HAN
 	result = fast_is_identical_function(op1, op2);
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42203,10 +95724,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST
 	result = fast_is_not_identical_function(op1, op2);
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42261,10 +95784,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42319,10 +95842,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_HA
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42377,10 +95900,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_H
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42435,10 +95958,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42493,10 +96016,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMP
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42551,10 +96074,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMP
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42565,10 +96088,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CONST_HANDLE
 	compare_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -42579,10 +96104,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER
 	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -42647,7 +96174,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HA
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -42670,12 +96197,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HA
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -42772,10 +96301,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -42802,10 +96333,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLE
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -42855,7 +96388,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HAND
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -42866,10 +96400,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HAND
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -42917,7 +96453,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CONST_HAN
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -42928,23 +96465,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CONST_HAN
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 	dim = RT_CONSTANT(opline, opline->op2);
 	if (IS_CV != IS_CONST) {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 fetch_dim_r_array:
 			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC);
 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		} else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
 			container = Z_REFVAL_P(container);
 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 				goto fetch_dim_r_array;
@@ -42963,10 +96506,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HAND
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -42975,13 +96520,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HAND
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -42990,26 +96536,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HAN
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
 	zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -43017,18 +96568,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CON
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_CONST == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -43037,13 +96594,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -43051,11 +96609,15 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_CV == IS_CONST ||
 	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_CV & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -43129,6 +96691,8 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
@@ -43208,15 +96772,17 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R
 fetch_obj_r_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -43231,13 +96797,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HAND
 		((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -43248,13 +96815,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HAN
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -43262,6 +96830,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_CV == IS_CONST ||
 	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -43372,10 +96942,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN
 fetch_obj_is_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -43384,15 +96956,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CON
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CV == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
@@ -43403,13 +96981,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -43532,6 +97111,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA
 		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -43552,18 +97132,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -43712,166 +97295,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA
 	}
 
 
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = EX_VAR(opline->op1.var);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if (IS_CONST == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
-	} else {
-		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if (IS_CONST != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
 
 
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -43994,6 +97425,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA
 		name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -44014,18 +97446,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -44123,6 +97558,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -44130,12 +97566,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 			if (IS_CONST == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = RT_CONSTANT(opline, opline->op2);
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -44143,6 +97581,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = RT_CONSTANT(opline, opline->op2);
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -44164,6 +97603,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 			dim = RT_CONSTANT(opline, opline->op2);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -44171,13 +97611,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 	}
 	if (IS_CONST != IS_UNUSED) {
 
+
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -44324,166 +97766,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 	}
 	if (IS_CONST != IS_UNUSED) {
 
-	}
-
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
-	zval *value;
-	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
-
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if (IS_CONST == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_VAR == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = RT_CONSTANT(opline, opline->op2);
-			if (IS_CONST == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = RT_CONSTANT(opline, opline->op2);
-			if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
-
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if (IS_CONST == IS_UNUSED) {
-				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				dim = RT_CONSTANT(opline, opline->op2);
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = RT_CONSTANT(opline, opline->op2);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
 
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = RT_CONSTANT(opline, opline->op2);
-assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
-		}
 	}
-	if (IS_CONST != IS_UNUSED) {
 
-	}
 
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -44581,6 +97872,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -44588,12 +97880,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 			if (IS_CONST == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = RT_CONSTANT(opline, opline->op2);
 				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -44601,6 +97895,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = RT_CONSTANT(opline, opline->op2);
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -44622,6 +97917,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 			dim = RT_CONSTANT(opline, opline->op2);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -44629,13 +97925,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA
 	}
 	if (IS_CONST != IS_UNUSED) {
 
+
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -44659,12 +97957,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UN
 		value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES());
 	}
 
+
 	/* zend_assign_to_variable() always takes care of op2, never free it! */
 
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -44688,12 +97987,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_US
 		value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES());
 	}
 
+
 	/* zend_assign_to_variable() always takes care of op2, never free it! */
 
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -44724,12 +98024,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_O
 	}
 
 
+
+
 	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -44761,11 +98063,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_O
 
 
 
+
+
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -44887,10 +98192,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -44921,12 +98228,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 
 
+
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -44959,6 +98269,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 					if (UNEXPECTED(EG(exception) != NULL)) {
 						if (IS_CONST != IS_CONST) {
 
+
 						}
 						HANDLE_EXCEPTION();
 					}
@@ -44969,6 +98280,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 				zend_invalid_method_call(object, function_name);
 
 
+
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -44993,6 +98306,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
 			}
 
+
 			if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
 				zend_objects_store_del(orig_obj);
 			}
@@ -45016,6 +98330,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 
 	if (IS_CONST != IS_CONST) {
 
+
 	}
 
 	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
@@ -45045,7 +98360,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -45057,6 +98372,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_C
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -45092,7 +98408,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_REF_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -45104,6 +98420,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_CONST_HANDLER
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -45118,10 +98435,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_CONST_HANDLER
 	}
 	ZVAL_REF(arg, Z_REF_P(varptr));
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -45133,6 +98451,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_CONST_HAND
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -45154,6 +98473,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_CONST_HAND
 		}
 		ZVAL_REF(arg, Z_REF_P(varptr));
 
+
 		ZEND_VM_NEXT_OPCODE();
 	}
 
@@ -45186,7 +98506,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_CONST_HAND
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -45201,6 +98521,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
 			ZVAL_MAKE_REF_EX(expr_ptr, 2);
 		}
 
+
 	} else {
 		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
 		if (IS_CV == IS_TMP_VAR) {
@@ -45248,7 +98569,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
 		} else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -45273,6 +98608,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -45282,7 +98618,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -45297,14 +98633,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDL
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -45342,7 +98678,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLE
 				offset = Z_REFVAL_P(offset);
 				goto offset_again;
 			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
 				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
 				goto num_index_dim;
 			} else if (Z_TYPE_P(offset) == IS_NULL) {
 				key = ZSTR_EMPTY_ALLOC();
@@ -45392,10 +98738,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLE
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -45436,10 +98784,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -45490,6 +98840,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
 			if (IS_CV & (IS_CONST|IS_CV)) {
 				/* avoid exception check */
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		} else {
@@ -45515,10 +98866,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
 isset_dim_obj_exit:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -45565,10 +98918,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
 isset_object_finish:
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -45597,10 +98952,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST
 	}
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr;
@@ -45622,9 +98979,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDL
 				}
 			}
 		} else if (IS_CONST == IS_UNUSED) {
-			ce = zend_fetch_class(NULL, opline->op2.num);
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				HANDLE_EXCEPTION();
 			}
@@ -45642,10 +99021,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDL
 		result = 0;
 	}
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -45653,7 +99033,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -45702,6 +99082,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@@ -45717,6 +99098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
 			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_CV == IS_CV) {
@@ -45737,6 +99119,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -45764,7 +99147,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
 	ZEND_VM_RETURN();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BIND_GLOBAL_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_string *varname;
@@ -45844,7 +99227,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IN_ARRAY_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -45871,10 +99254,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER
 			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
 				result = zend_hash_find(ht, Z_STR_P(op1));
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 				result = zend_hash_index_find(ht, Z_LVAL_P(op1));
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
@@ -45899,6 +99284,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER
 			if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
 				result = zend_hash_find(ht, Z_STR_P(op1));
 
+
 				ZEND_VM_SMART_BRANCH(result, 0);
 			}
 		}
@@ -45908,15 +99294,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER
 			ZVAL_STR(&key_tmp, key);
 			if (zend_compare(op1, &key_tmp) == 0) {
 
+
 				ZEND_VM_SMART_BRANCH(1, 1);
 			}
 		} ZEND_HASH_FOREACH_END();
 	}
 
+
 	ZEND_VM_SMART_BRANCH(0, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	/* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
 	/* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
@@ -45932,7 +99320,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_C
 	ZEND_VM_SMART_BRANCH(result, 0);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -45945,7 +99333,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_
 	ZEND_VM_SMART_BRANCH(!result, 0);
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
@@ -45962,6 +99350,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 			SAVE_OPLINE();
 			zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
 		ht = Z_ARRVAL_P(container);
@@ -45970,6 +99359,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 		if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 			SAVE_OPLINE();
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
 			ZEND_VM_NEXT_OPCODE();
@@ -45989,6 +99379,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 		}
 		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 
@@ -45997,10 +99388,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 	SAVE_OPLINE();
 	zend_undefined_offset(offset);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
@@ -46017,6 +99409,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 			SAVE_OPLINE();
 			zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		}
 		ht = Z_ARRVAL_P(container);
@@ -46025,6 +99418,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 		if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 			SAVE_OPLINE();
 
+
 			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 		} else {
 			ZEND_VM_NEXT_OPCODE();
@@ -46044,6 +99438,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 		}
 		zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 
@@ -46052,54 +99447,57 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
 	SAVE_OPLINE();
 	zend_undefined_offset(offset);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
 	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	div_function(EX_VAR(opline->result.var), op1, op2);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
 	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	pow_function(EX_VAR(opline->result.var), op1, op2);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
 		zend_string *op1_str = Z_STR_P(op1);
 		zend_string *op2_str = Z_STR_P(op2);
 		zend_string *str;
 		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
 
 		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
@@ -46107,13 +99505,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
 			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
@@ -46127,7 +99525,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
 			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else {
@@ -46139,7 +99537,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		}
@@ -46150,25 +99548,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(
 		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
 			op1 = ZVAL_UNDEFINED_OP1();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
 			op2 = ZVAL_UNDEFINED_OP2();
 		}
 		concat_function(EX_VAR(opline->result.var), op1, op2);
 
+
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_identical_function(op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
+
+	SAVE_OPLINE();
+	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	result = fast_is_not_identical_function(op1, op2);
+
+
+	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+	ZEND_VM_SMART_BRANCH(result, 1);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	double d1, d2;
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
 		/* pass */
 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
@@ -46205,7 +99636,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op1);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op2);
 			}
 			if (result) {
@@ -46215,18 +99646,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	double d1, d2;
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
 		/* pass */
 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
@@ -46263,7 +99694,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_H
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op1);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op2);
 			}
 			if (result) {
@@ -46273,18 +99704,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_H
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	double d1, d2;
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
 		/* pass */
 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
@@ -46321,7 +99752,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op1);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op2);
 			}
 			if (result) {
@@ -46331,18 +99762,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	double d1, d2;
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
 		/* pass */
 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
@@ -46379,7 +99810,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op1);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op2);
 			}
 			if (!result) {
@@ -46389,18 +99820,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	double d1, d2;
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
 		/* pass */
 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
@@ -46437,7 +99868,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JM
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op1);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op2);
 			}
 			if (!result) {
@@ -46447,18 +99878,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JM
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 	double d1, d2;
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) {
 		/* pass */
 	} else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
 		if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
@@ -46495,7 +99926,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JM
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op1);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zval_ptr_dtor_str(op2);
 			}
 			if (!result) {
@@ -46505,38 +99936,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JM
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
 	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	compare_function(EX_VAR(opline->result.var), op1, op2);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
 
 	SAVE_OPLINE();
 	op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -46551,7 +99984,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_H
 
 	SAVE_OPLINE();
 	object = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
@@ -46572,7 +100005,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_H
 assign_op_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -46581,7 +100014,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_H
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
@@ -46601,7 +100034,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_H
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -46616,7 +100049,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_H
 		} else {
 			zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
@@ -46624,12 +100057,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_H
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -46644,15 +100078,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H
 		SEPARATE_ARRAY(container);
 		ht = Z_ARRVAL_P(container);
 assign_dim_op_new_array:
-		dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+		dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_UNUSED) {
 			var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
 			if (UNEXPECTED(!var_ptr)) {
 				zend_cannot_add_element();
 				goto assign_dim_op_ret_null;
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC);
 			} else {
 				var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC);
@@ -46665,7 +100099,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H
 		value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1);
 
 		do {
-			if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
+			if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) {
 				zend_reference *ref = Z_REF_P(var_ptr);
 				var_ptr = Z_REFVAL_P(var_ptr);
 				if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) {
@@ -46691,8 +100125,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H
 		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 			zend_object *obj = Z_OBJ_P(container);
 
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 			zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC);
@@ -46715,7 +100149,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H
 			}
 			goto assign_dim_op_new_array;
 		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 			zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
 			FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
@@ -46727,17 +100161,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
 	zval *value;
 
 	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
 
 	do {
@@ -46758,10 +100193,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDL
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -46775,7 +100211,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HAN
 
 	SAVE_OPLINE();
 	object = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -46794,7 +100230,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HAN
 pre_incdec_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -46803,7 +100239,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HAN
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
@@ -46811,22 +100247,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HAN
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -46840,7 +100278,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HA
 
 	SAVE_OPLINE();
 	object = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -46859,7 +100297,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HA
 post_incdec_object:
 		/* here we are sure we are dealing with an object */
 		zobj = Z_OBJ_P(object);
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(property);
 		} else {
 			name = zval_try_get_tmp_string(property, &tmp_name);
@@ -46868,41 +100306,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HA
 				break;
 			}
 		}
-		cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
+		cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot;
 		if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) {
 			if (UNEXPECTED(Z_ISERROR_P(zptr))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
+	dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	if (IS_CV != IS_CONST) {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 fetch_dim_r_array:
-			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC);
+			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC);
 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		} else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
 			container = Z_REFVAL_P(container);
 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 				goto fetch_dim_r_array;
@@ -46911,27 +100355,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HAN
 			}
 		} else {
 fetch_dim_r_slow:
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 			zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 		}
 	} else {
-		zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+		zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	zend_fetch_dimension_address_W(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -46939,14 +100384,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HAN
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	zend_fetch_dimension_address_RW(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -46954,20 +100399,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
+	zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -46975,25 +100423,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_TMP_VAR == IS_UNUSED) {
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -47001,7 +100455,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -47009,11 +100463,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_CV == IS_CONST ||
 	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_CV & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -47022,7 +100480,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
 			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP1();
 			}
-			zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 			ZVAL_NULL(EX_VAR(opline->result.var));
 			goto fetch_obj_r_finish;
 		} while (0);
@@ -47034,7 +100492,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
 		zend_string *name, *tmp_name;
 		zval *retval;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */);
 
 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
@@ -47087,12 +100545,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -47125,9 +100585,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
 					}
 				}
 			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -47151,7 +100611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
 		}
 #endif
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -47166,10 +100626,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN
 fetch_obj_r_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -47177,11 +100638,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN
 	SAVE_OPLINE();
 
 	container = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(
-		result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR),
-		(((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
+		result, container, IS_CV, property, IS_TMP_VAR,
+		((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_CV == IS_VAR) {
@@ -47190,16 +100651,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
-	zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -47207,7 +100668,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -47215,6 +100676,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_CV == IS_CONST ||
 	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -47225,7 +100688,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
 					break;
 				}
 			}
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
+			if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) {
 				ZVAL_UNDEFINED_OP2();
 			}
 			ZVAL_NULL(EX_VAR(opline->result.var));
@@ -47239,7 +100702,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
 		zend_string *name, *tmp_name;
 		zval *retval;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			cache_slot = CACHE_ADDR(opline->extended_value);
 
 			if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
@@ -47266,7 +100729,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
 					/* Fall through to read_property for hooks. */
 				} else if (EXPECTED(zobj->properties != NULL)) {
 					ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset));
-					name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+					name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 					if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
 						uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
 
@@ -47299,9 +100762,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
 					}
 				}
 			}
-			name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+			name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 		} else {
-			name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+			name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 			if (UNEXPECTED(!name)) {
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				break;
@@ -47310,7 +100773,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
 
 		retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
 
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 
@@ -47325,10 +100788,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA
 fetch_obj_is_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -47337,24 +100801,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CV == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	result = EX_VAR(opline->result.var);
-	zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
+	zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
@@ -47362,7 +100832,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -47379,14 +100849,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -47412,7 +100882,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -47480,11 +100950,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -47494,9 +100965,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -47505,18 +100976,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -47533,14 +101006,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -47566,7 +101039,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -47634,9 +101107,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 			UNDEF_RESULT();
@@ -47648,9 +101121,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -47665,166 +101138,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = EX_VAR(opline->op1.var);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
-	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -47841,14 +101161,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 			object = Z_REFVAL_P(object);
 			goto assign_object;
 		}
-		zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
+		zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
 		value = &EG(uninitialized_zval);
 		goto free_and_exit_assign_obj;
 	}
 
 assign_object:
 	zobj = Z_OBJ_P(object);
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
 			void **cache_slot = CACHE_ADDR(opline->extended_value);
 			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -47874,7 +101194,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 					}
 				}
 			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+				name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
 					zobj = zend_lazy_object_init(zobj);
 					if (!zobj) {
@@ -47942,11 +101262,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 				/* Fall through to write_property for hooks. */
 			}
 		}
-		name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC));
+		name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC));
 	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
+		name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -47956,9 +101277,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 		ZVAL_DEREF(value);
 	}
 
-	value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
+	value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
@@ -47967,18 +101288,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -47993,7 +101316,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
 try_assign_dim_array:
 		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+		if (IS_TMP_VAR == IS_UNUSED) {
 			value = RT_CONSTANT((opline+1), (opline+1)->op1);
 			if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
 				HashTable *ht = Z_ARRVAL_P(object_ptr);
@@ -48031,8 +101354,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 				}
 			}
 		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
 				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
 			} else {
 				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
@@ -48060,10 +101383,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			zend_object *obj = Z_OBJ_P(object_ptr);
 
 			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
 				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 
@@ -48076,25 +101399,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
 			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
 
 				UNDEF_RESULT();
 			} else {
@@ -48114,23 +101441,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			}
 		} else {
 			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
 		}
 	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
+	if (IS_TMP_VAR != IS_UNUSED) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -48145,7 +101474,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
 try_assign_dim_array:
 		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+		if (IS_TMP_VAR == IS_UNUSED) {
 			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
 			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
 				HashTable *ht = Z_ARRVAL_P(object_ptr);
@@ -48183,8 +101512,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 				}
 			}
 		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
 				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
 			} else {
 				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
@@ -48212,10 +101541,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			zend_object *obj = Z_OBJ_P(object_ptr);
 
 			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
 				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 
@@ -48233,12 +101562,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 				zend_objects_store_del(obj);
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_UNUSED) {
 				zend_use_new_element_for_string();
 				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 				UNDEF_RESULT();
 			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
@@ -48247,7 +101576,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			if (Z_ISREF_P(orig_object_ptr)
 			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 				UNDEF_RESULT();
 			} else {
@@ -48267,7 +101596,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			}
 		} else {
 			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
 			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
@@ -48275,15 +101604,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			}
 		}
 	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
+	if (IS_TMP_VAR != IS_UNUSED) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -48298,9 +101628,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
 try_assign_dim_array:
 		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
 				HashTable *ht = Z_ARRVAL_P(object_ptr);
 				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
 					GC_ADDREF(ht);
@@ -48311,18 +101641,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 					goto assign_dim_error;
 				}
 			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
 				ZVAL_DEREF(value);
 			}
 			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
 			if (UNEXPECTED(value == NULL)) {
 				zend_cannot_add_element();
 				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
+			} else if (IS_CV == IS_CV) {
 				if (Z_REFCOUNTED_P(value)) {
 					Z_ADDREF_P(value);
 				}
-			} else if (IS_VAR == IS_VAR) {
+			} else if (IS_CV == IS_VAR) {
 				zval *free_op_data = EX_VAR((opline+1)->op1.var);
 				if (Z_ISREF_P(free_op_data)) {
 					if (Z_REFCOUNTED_P(value)) {
@@ -48330,14 +101660,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 					}
 					zval_ptr_dtor_nogc(free_op_data);
 				}
-			} else if (IS_VAR == IS_CONST) {
+			} else if (IS_CV == IS_CONST) {
 				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
 					Z_ADDREF_P(value);
 				}
 			}
 		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CONST) {
 				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
 			} else {
 				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
@@ -48345,8 +101675,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			if (UNEXPECTED(variable_ptr == NULL)) {
 				goto assign_dim_error;
 			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
 		}
 		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 			ZVAL_COPY(EX_VAR(opline->result.var), value);
@@ -48365,43 +101695,46 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			zend_object *obj = Z_OBJ_P(object_ptr);
 
 			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
 				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+			} else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
 				dim++;
 			}
 
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
 				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
 				ZVAL_DEREF(value);
 			}
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+			if (IS_TMP_VAR == IS_UNUSED) {
 				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 				UNDEF_RESULT();
 			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
 			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -48420,175 +101753,85 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D
 			}
 		} else {
 			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+			dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
 		}
 	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
+	if (IS_TMP_VAR != IS_UNUSED) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
 	zval *value;
 	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
 
 	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
 
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-			value = EX_VAR((opline+1)->op1.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_CV == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_CV == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_CV == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
 			ZVAL_COPY(EX_VAR(opline->result.var), value);
 		}
 		if (garbage) {
 			GC_DTOR_NO_REF(garbage);
 		}
 	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-			if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = EX_VAR((opline+1)->op1.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_CV & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
+	}
 
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
-				zend_use_new_element_for_string();
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
 
-				UNDEF_RESULT();
-			} else {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-				value = EX_VAR((opline+1)->op1.var);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
 
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
+	SAVE_OPLINE();
+	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
 
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-assign_dim_error:
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
 
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
 		}
-	}
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
 	}
 
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -48596,35 +101839,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_
 	SAVE_OPLINE();
 
 	container = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
 
 	if (1) {
 		if (IS_CV == IS_UNUSED) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		}
 	} else {
-		zend_assign_to_property_reference(container, IS_CV, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *value_ptr;
@@ -48632,35 +101876,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_
 	SAVE_OPLINE();
 
 	container = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
 
 	if (1) {
 		if (IS_CV == IS_UNUSED) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+			if (IS_TMP_VAR == IS_CONST) {
 				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			} else {
 				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 			}
 		}
 	} else {
-		zend_assign_to_property_reference(container, IS_CV, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC);
 	}
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -48668,16 +101914,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 
 
 	op1 = EX_VAR(opline->op1.var);
-	op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+	    (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
 		zend_string *op1_str = Z_STR_P(op1);
 		zend_string *op2_str = Z_STR_P(op2);
 		zend_string *str;
 		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
 
 		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) {
+			if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
@@ -48685,13 +101931,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-		} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+		} else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
 			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
 				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
 			} else {
 				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
@@ -48702,7 +101948,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
 			GC_ADD_FLAGS(str, flags);
 			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		} else {
@@ -48714,7 +101960,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op1_str, 0);
 			}
-			if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+			if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) {
 				zend_string_release_ex(op2_str, 0);
 			}
 		}
@@ -48732,12 +101978,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 		}
 		op1_str = zval_get_string_func(op1);
 	}
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		op2_str = Z_STR_P(op2);
 	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
 		op2_str = zend_string_copy(Z_STR_P(op2));
 	} else {
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
 			ZVAL_UNDEFINED_OP2();
 		}
 		op2_str = zval_get_string_func(op2);
@@ -48745,7 +101991,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 	do {
 		if (IS_CV != IS_CONST) {
 			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+				if (IS_TMP_VAR == IS_CONST) {
 					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
 						GC_ADDREF(op2_str);
 					}
@@ -48755,7 +102001,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 				break;
 			}
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
 				if (IS_CV == IS_CONST) {
 					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
@@ -48776,16 +102022,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN
 		if (IS_CV != IS_CONST) {
 			zend_string_release_ex(op1_str, 0);
 		}
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_string_release_ex(op2_str, 0);
 		}
 	} while (0);
 
+
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *function_name;
@@ -48800,28 +102047,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
 
 	object = EX_VAR(opline->op1.var);
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
-		function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR != IS_CONST) {
+		function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
+	if (IS_TMP_VAR != IS_CONST &&
 	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
 		do {
-			if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+			if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
 				function_name = Z_REFVAL_P(function_name);
 				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
 					break;
 				}
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+			} else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
 				ZVAL_UNDEFINED_OP2();
 				if (UNEXPECTED(EG(exception) != NULL)) {
 
+
 					HANDLE_EXCEPTION();
 				}
 			}
 			zend_throw_error(NULL, "Method name must be a string");
 			zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 			HANDLE_EXCEPTION();
 		} while (0);
 	}
@@ -48852,18 +102101,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
 				if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
 					object = ZVAL_UNDEFINED_OP1();
 					if (UNEXPECTED(EG(exception) != NULL)) {
-						if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+						if (IS_TMP_VAR != IS_CONST) {
 							zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 						}
 						HANDLE_EXCEPTION();
 					}
 				}
-				if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-					function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+				if (IS_TMP_VAR == IS_CONST) {
+					function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 				}
 				zend_invalid_method_call(object, function_name);
 				zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 				HANDLE_EXCEPTION();
 			}
 		} while (0);
@@ -48871,18 +102121,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
 
 	called_scope = obj->ce;
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+	if (IS_TMP_VAR == IS_CONST &&
 	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
 		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
 	} else {
 		zend_object *orig_obj = obj;
 
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
-			function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+		if (IS_TMP_VAR == IS_CONST) {
+			function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		}
 
 		/* First, locate the function. */
-		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
 		if (UNEXPECTED(fbc == NULL)) {
 			if (EXPECTED(!EG(exception))) {
 				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
@@ -48893,7 +102143,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
 			}
 			HANDLE_EXCEPTION();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+		if (IS_TMP_VAR == IS_CONST &&
 		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
 		    EXPECTED(obj == orig_obj)) {
 			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
@@ -48909,7 +102159,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 	}
 
@@ -48940,7 +102190,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -48955,6 +102205,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
 			ZVAL_MAKE_REF_EX(expr_ptr, 2);
 		}
 
+
 	} else {
 		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
 		if (IS_CV == IS_TMP_VAR) {
@@ -48980,15 +102231,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 		zend_string *str;
 		zend_ulong hval;
 
 add_again:
 		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 			str = Z_STR_P(offset);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				if (ZEND_HANDLE_NUMERIC(str, hval)) {
 					goto num_index;
 				}
@@ -48999,10 +102250,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
 			hval = Z_LVAL_P(offset);
 num_index:
 			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -49018,7 +102283,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
 			zend_use_resource_as_offset(offset);
 			hval = Z_RES_HANDLE_P(offset);
 			goto num_index;
-		} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+		} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
 			ZVAL_UNDEFINED_OP2();
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
@@ -49036,7 +102301,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -49051,14 +102316,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HAND
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -49068,7 +102333,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
@@ -49080,7 +102345,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
 offset_again:
 			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 				key = Z_STR_P(offset);
-				if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+				if (IS_TMP_VAR != IS_CONST) {
 					if (ZEND_HANDLE_NUMERIC(key, hval)) {
 						goto num_index_dim;
 					}
@@ -49092,11 +102357,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
 				hval = Z_LVAL_P(offset);
 num_index_dim:
 				zend_hash_index_del(ht, hval);
-			} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 				offset = Z_REFVAL_P(offset);
 				goto offset_again;
 			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
 				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					break;
+				}
+				if (EG(exception)) {
+					break;
+				}
 				goto num_index_dim;
 			} else if (Z_TYPE_P(offset) == IS_NULL) {
 				key = ZSTR_EMPTY_ALLOC();
@@ -49111,7 +102386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
 				zend_use_resource_as_offset(offset);
 				hval = Z_RES_HANDLE_P(offset);
 				goto num_index_dim;
-			} else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			} else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
 				ZVAL_UNDEFINED_OP2();
 				key = ZSTR_EMPTY_ALLOC();
 				goto str_index_dim;
@@ -49128,11 +102403,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
 		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
 			container = ZVAL_UNDEFINED_OP1();
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
 			offset = ZVAL_UNDEFINED_OP2();
 		}
 		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-			if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+			if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
 				offset++;
 			}
 			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
@@ -49147,10 +102422,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -49159,7 +102435,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	do {
 		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
@@ -49176,7 +102452,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL
 				break;
 			}
 		}
-		if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+		if (IS_TMP_VAR == IS_CONST) {
 			name = Z_STR_P(offset);
 		} else {
 			name = zval_try_get_tmp_string(offset, &tmp_name);
@@ -49184,18 +102460,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL
 				break;
 			}
 		}
-		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
-		if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_TMP_VAR != IS_CONST) {
 			zend_tmp_string_release(tmp_name);
 		}
 	} while (0);
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -49205,7 +102482,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 		HashTable *ht;
@@ -49217,17 +102494,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
 isset_again:
 		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
 			str = Z_STR_P(offset);
-			if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+			if (IS_TMP_VAR != IS_CONST) {
 				if (ZEND_HANDLE_NUMERIC(str, hval)) {
 					goto num_index_prop;
 				}
 			}
-			value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST);
+			value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST);
 		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
 			hval = Z_LVAL_P(offset);
 num_index_prop:
 			value = zend_hash_index_find(ht, hval);
-		} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+		} else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
 			offset = Z_REFVAL_P(offset);
 			goto isset_again;
 		} else {
@@ -49259,7 +102536,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+	if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
 		offset++;
 	}
 	if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -49271,10 +102548,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
 isset_dim_obj_exit:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -49284,7 +102562,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
-	offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (IS_CV == IS_CONST ||
 	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -49300,7 +102578,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
 		}
 	}
 
-	if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+	if (IS_TMP_VAR == IS_CONST) {
 		name = Z_STR_P(offset);
 	} else {
 		name = zval_try_get_tmp_string(offset, &tmp_name);
@@ -49312,19 +102590,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV
 
 	result =
 		(opline->extended_value & ZEND_ISEMPTY) ^
-		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
 
-	if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
+	if (IS_TMP_VAR != IS_CONST) {
 		zend_tmp_string_release(tmp_name);
 	}
 
 isset_object_finish:
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -49335,14 +102614,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA
 	SAVE_OPLINE();
 
 	key = EX_VAR(opline->op1.var);
-	subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
+	subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
 
 	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
 array_key_exists_array:
 		ht = Z_ARRVAL_P(subject);
 		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
 	} else {
-		if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+		if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
 			subject = Z_REFVAL_P(subject);
 			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
 				goto array_key_exists_array;
@@ -49354,10 +102633,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -49365,7 +102645,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(Z
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -49414,6 +102694,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(Z
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@@ -49429,6 +102710,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(Z
 			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_CV == IS_CV) {
@@ -49442,9 +102724,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(Z
 	}
 
 	/* Set the new yielded key */
-	if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) {
-		zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-		if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+	if (IS_TMP_VAR != IS_UNUSED) {
+		zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
 			key = Z_REFVAL_P(key);
 		}
 		ZVAL_COPY(&generator->key, key);
@@ -49477,183 +102759,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(Z
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_not_identical_function(op1, op2);
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = EX_VAR(opline->op1.var);
-
-	if (0 || UNEXPECTED(0)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(0)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
-	}
-
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = EX_VAR(opline->op1.var);
-
-	if (0 || UNEXPECTED(1)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(1)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES());
-	}
-
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_identical_function(op1, op2);
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
-
-	SAVE_OPLINE();
-	op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-	op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC);
-	result = fast_is_not_identical_function(op1, op2);
-
-	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = EX_VAR(opline->op1.var);
-
-	if (0 || UNEXPECTED(0)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(0)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES());
-	}
-
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
-
-	SAVE_OPLINE();
-	value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = EX_VAR(opline->op1.var);
-
-	if (0 || UNEXPECTED(1)) {
-		zend_refcounted *garbage = NULL;
-
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(1)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES());
-	}
-
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_REF_SPEC_CV_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *variable_ptr;
@@ -49689,10 +102795,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER
 
 	zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_CV_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr;
@@ -49714,9 +102821,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER
 				}
 			}
 		} else if (IS_VAR == IS_UNUSED) {
-			ce = zend_fetch_class(NULL, opline->op2.num);
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				HANDLE_EXCEPTION();
 			}
@@ -49734,10 +102863,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER
 		result = 0;
 	}
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -49834,145 +102964,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H
 	}
 
 
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type)
-{
-	USE_OPLINE
-	zval *varname;
-	zval *retval;
-	zend_string *name, *tmp_name;
-	HashTable *target_symbol_table;
-
-	SAVE_OPLINE();
-	varname = EX_VAR(opline->op1.var);
 
-	if (IS_CV == IS_CONST) {
-		name = Z_STR_P(varname);
-	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
-		name = Z_STR_P(varname);
-		tmp_name = NULL;
-	} else {
-		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-		name = zval_try_get_tmp_string(varname, &tmp_name);
-		if (UNEXPECTED(!name)) {
-			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
 
-			}
-			ZVAL_UNDEF(EX_VAR(opline->result.var));
-			HANDLE_EXCEPTION();
-		}
-	}
-
-	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
-	retval = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST);
-	if (retval == NULL) {
-		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
-fetch_this:
-			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
-			if (IS_CV != IS_CONST) {
-				zend_tmp_string_release(tmp_name);
-			}
-			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-		}
-		if (type == BP_VAR_W) {
-			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
-		} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
-			retval = &EG(uninitialized_zval);
-		} else {
-			if (IS_CV == IS_CV) {
-				/* Keep name alive in case an error handler tries to free it. */
-				zend_string_addref(name);
-			}
-			zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
-				(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
-			if (type == BP_VAR_RW && !EG(exception)) {
-				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
-			} else {
-				retval = &EG(uninitialized_zval);
-			}
-			if (IS_CV == IS_CV) {
-				zend_string_release(name);
-			}
-		}
-	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
-	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
-		retval = Z_INDIRECT_P(retval);
-		if (Z_TYPE_P(retval) == IS_UNDEF) {
-			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
-				goto fetch_this;
-			}
-			if (type == BP_VAR_W) {
-				ZVAL_NULL(retval);
-			} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
-				retval = &EG(uninitialized_zval);
-			} else {
-				zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
-					(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
-				if (type == BP_VAR_RW && !EG(exception)) {
-					ZVAL_NULL(retval);
-				} else {
-					retval = &EG(uninitialized_zval);
-				}
-			}
-		}
-	}
-
-	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
-
-	}
-
-	if (IS_CV != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-	ZEND_ASSERT(retval != NULL);
-	if (type == BP_VAR_R || type == BP_VAR_IS) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
-	} else {
-		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
-	}
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_R_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_W_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_RW_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	int fetch_type =
 		(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
 			BP_VAR_W : BP_VAR_R;
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_UNSET_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-	ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS));
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -49981,13 +103013,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HAN
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -49996,13 +103029,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HA
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -50010,18 +103044,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNU
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_UNUSED == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -50119,6 +103159,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -50126,12 +103167,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 			if (IS_UNUSED == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = NULL;
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -50139,6 +103182,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = NULL;
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -50160,6 +103204,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 			dim = NULL;
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -50167,13 +103212,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 	}
 	if (IS_UNUSED != IS_UNUSED) {
 
+
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -50320,166 +103367,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 	}
 	if (IS_UNUSED != IS_UNUSED) {
 
-	}
-
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
-	zval *value;
-	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
-
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if (IS_UNUSED == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
-				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_VAR == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
-				}
-			} else if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
-				}
-			}
-		} else {
-			dim = NULL;
-			if (IS_UNUSED == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
-			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
-		}
-	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
-			}
-		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = NULL;
-			if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
-
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
-
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
-
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if (IS_UNUSED == IS_UNUSED) {
-				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				dim = NULL;
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = NULL;
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
 
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
-			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = NULL;
-assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
-			}
-		}
 	}
-	if (IS_UNUSED != IS_UNUSED) {
 
-	}
 
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -50577,6 +103473,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -50584,12 +103481,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 			if (IS_UNUSED == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = NULL;
 				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -50597,6 +103496,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = NULL;
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -50618,6 +103518,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 			dim = NULL;
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -50625,13 +103526,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D
 	}
 	if (IS_UNUSED != IS_UNUSED) {
 
+
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	if (IS_CV == IS_UNUSED) {
 		SAVE_OPLINE();
@@ -50657,6 +103560,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
 			ZVAL_DEREF(retval_ptr);
 		}
 
+		/* If the return is a generic T-ref erased to a wider bound, the
+		 * inline ZEND_TYPE_CONTAINS_CODE fast-path may falsely accept (e.g.
+		 * mixed for unbounded T). Consult the reified binding first; the
+		 * erased check still runs after for non-T returns and composite
+		 * shapes that the reified helper leaves untouched. */
+		if (UNEXPECTED(execute_data->type_args != NULL)) {
+			SAVE_OPLINE();
+			if (UNEXPECTED(!zend_verify_generic_return_type(execute_data, retval_ptr))) {
+				HANDLE_EXCEPTION();
+			}
+		}
+
 		if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) {
 			ZEND_VM_NEXT_OPCODE();
 		}
@@ -50698,7 +103613,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -50710,6 +103625,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_U
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -50745,7 +103661,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_U
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_REF_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -50757,6 +103673,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLE
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -50771,10 +103688,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLE
 	}
 	ZVAL_REF(arg, Z_REF_P(varptr));
 
+
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -50786,6 +103704,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_HAN
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -50807,6 +103726,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_HAN
 		}
 		ZVAL_REF(arg, Z_REF_P(varptr));
 
+
 		ZEND_VM_NEXT_OPCODE();
 	}
 
@@ -50839,7 +103759,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_HAN
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
@@ -50851,6 +103771,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_C
 		arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num));
 		if (UNEXPECTED(!arg)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	} else {
@@ -50872,6 +103793,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_C
 		}
 		ZVAL_REF(arg, Z_REF_P(varptr));
 
+
 		ZEND_VM_NEXT_OPCODE();
 	}
 
@@ -50904,7 +103826,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_C
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr_ptr, new_expr;
@@ -50919,6 +103841,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
 			ZVAL_MAKE_REF_EX(expr_ptr, 2);
 		}
 
+
 	} else {
 		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
 		if (IS_CV == IS_TMP_VAR) {
@@ -50966,7 +103889,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
 		} else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
 			offset = Z_REFVAL_P(offset);
 			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
+			}
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
+			}
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
+			}
 			str = ZSTR_EMPTY_ALLOC();
 			goto str_index;
 		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
@@ -50991,6 +103928,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
 			zval_ptr_dtor_nogc(expr_ptr);
 		}
 
+
 	} else {
 		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
 			zend_cannot_add_element();
@@ -51000,7 +103938,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	zval *array;
 	uint32_t size;
@@ -51015,14 +103953,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HAND
 		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
 			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		ZVAL_ARR(array, zend_new_array(0));
 		ZEND_VM_NEXT_OPCODE();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_CV_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var = EX_VAR(opline->op1.var);
@@ -51040,7 +103978,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varname;
@@ -51063,6 +104001,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL
 		name = zval_try_get_tmp_string(varname, &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			HANDLE_EXCEPTION();
 		}
 	}
@@ -51074,11 +104013,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL
 		zend_tmp_string_release(tmp_name);
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -51100,7 +104040,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_S
 	}
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -51122,7 +104062,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_S
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *value;
@@ -51146,6 +104086,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS
 		zend_tmp_string_release(tmp_name);
 	}
 
+
 	if (!value) {
 		result = (opline->extended_value & ZEND_ISEMPTY);
 	} else {
@@ -51165,8 +104106,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS
 	ZEND_VM_SMART_BRANCH(result, true);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *expr;
@@ -51188,9 +104129,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HAND
 				}
 			}
 		} else if (IS_UNUSED == IS_UNUSED) {
-			ce = zend_fetch_class(NULL, opline->op2.num);
+			/* Polymorphic inline cache for T-ref / deferred-generic fetches:
+			 * key on (type_args generation, called_scope). The generation is
+			 * a monotonic nonce per zend_type_arg_table allocation, so it's
+			 * ABA-safe across calls that reuse the same heap address. NULL
+			 * type_args maps to generation 0 (the counter starts at 1). */
+			void **slot = CACHE_ADDR(opline->extended_value);
+			uintptr_t cur_gen = EX(type_args) ? EX(type_args)->generation : 0;
+			zend_class_entry *cur_scope = zend_get_called_scope(execute_data);
+			/* slot[2] != NULL distinguishes a populated entry from an
+			 * uninitialized (all-zeros) slot, which otherwise matches
+			 * cur_gen=0 / cur_scope=NULL and would return a spurious NULL ce. */
+			if (EXPECTED(slot[2] != NULL
+					&& (uintptr_t)slot[0] == cur_gen && slot[1] == (void*)cur_scope)) {
+				ce = (zend_class_entry*)slot[2];
+			} else {
+				ce = zend_fetch_class(NULL, opline->op2.num);
+				if (EXPECTED(ce)) {
+					slot[0] = (void*)cur_gen;
+					slot[1] = (void*)cur_scope;
+					slot[2] = (void*)ce;
+				}
+			}
 			if (UNEXPECTED(ce == NULL)) {
 
+
 				ZVAL_UNDEF(EX_VAR(opline->result.var));
 				HANDLE_EXCEPTION();
 			}
@@ -51208,10 +104171,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HAND
 		result = 0;
 	}
 
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -51219,7 +104183,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
 
 	SAVE_OPLINE();
 	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	/* Destroy the previously yielded value */
@@ -51268,6 +104232,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
 					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
 				} while (0);
 
+
 			}
 		} else {
 			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@@ -51283,6 +104248,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
 			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
 				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
 
+
 			} else {
 				ZVAL_COPY_VALUE(&generator->value, value);
 				if (IS_CV == IS_CV) {
@@ -51303,6 +104269,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
 		}
 		ZVAL_COPY(&generator->key, key);
 
+
 		if (Z_TYPE(generator->key) == IS_LONG
 		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
 		) {
@@ -51330,7 +104297,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
 	ZEND_VM_RETURN();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CHECK_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1 = EX_VAR(opline->op1.var);
@@ -51343,7 +104310,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDL
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MAKE_REF_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1 = EX_VAR(opline->op1.var);
@@ -51376,7 +104343,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -51408,7 +104375,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z
 				zval retval;
 
 				zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT));
+				GC_ADDREF(zobj);
 				zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval);
+				OBJ_RELEASE(zobj);
 				count = zval_get_long(&retval);
 				zval_ptr_dtor(&retval);
 				break;
@@ -51428,10 +104397,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z
 
 	ZVAL_LONG(EX_VAR(opline->result.var), count);
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zend_array *ht = Z_ARRVAL_P(EX_VAR(opline->op1.var));
@@ -51446,7 +104416,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_HAN
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 
@@ -51485,11 +104455,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDL
 			break;
 		}
 
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1;
@@ -51504,17 +104475,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLE
 		ZVAL_STRING(EX_VAR(opline->result.var), "unknown type");
 	}
 
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *varptr, *arg;
 	uint32_t arg_num = opline->op2.num;
 
 	if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
-		ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
 	varptr = EX_VAR(opline->op1.var);
@@ -51529,7 +104501,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE
 	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51540,10 +104512,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OP
 	div_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51554,10 +104528,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OP
 	pow_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51630,11 +104606,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND
 		concat_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 		ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51646,10 +104624,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLE
 	result = fast_is_identical_function(op1, op2);
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51661,10 +104641,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HA
 	result = fast_is_not_identical_function(op1, op2);
 
 
+
+
 	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51719,10 +104701,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51777,10 +104759,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ_HANDL
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51835,10 +104817,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ_HAND
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51893,10 +104875,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -51951,10 +104933,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ_H
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -52009,10 +104991,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ_
 			}
 		}
 	}
-	ZEND_VM_TAIL_CALL(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
+	ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2));
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -52023,10 +105005,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(Z
 	compare_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *op1, *op2;
@@ -52037,10 +105021,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZE
 	boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -52105,7 +105091,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDL
 					}
 
 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -52128,12 +105114,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDL
 	FREE_OP((opline+1)->op1_type, (opline+1)->op1.var);
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -52230,10 +105218,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *var_ptr;
@@ -52260,10 +105250,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER(Z
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -52313,7 +105305,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -52324,10 +105317,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object;
@@ -52375,7 +105370,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLE
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -52386,23 +105382,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLE
 	} while (0);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *dim, *value;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 	dim = EX_VAR(opline->op2.var);
 	if (IS_CV != IS_CONST) {
 		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 fetch_dim_r_array:
 			value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC);
 			ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-		} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+		} else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
 			container = Z_REFVAL_P(container);
 			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
 				goto fetch_dim_r_array;
@@ -52421,10 +105423,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER
 	}
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -52433,13 +105437,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -52448,26 +105453,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLE
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
+	/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()['bar'] ??= baz. */
 	zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -52475,18 +105485,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_
 
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
 		if (IS_CV == IS_UNUSED) {
-			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CV & IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -52495,13 +105511,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HAN
 	container = EX_VAR(opline->op1.var);
 	zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -52509,11 +105526,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER
 
 	SAVE_OPLINE();
 	container = EX_VAR(opline->op1.var);
+	if (IS_CV & (IS_VAR|IS_TMP_VAR)) {
+		/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
+		ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
+	}
 
 	if (IS_CV == IS_CONST ||
 	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
 		do {
-			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			if ((IS_CV & IS_CV) && Z_ISREF_P(container)) {
 				container = Z_REFVAL_P(container);
 				if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
 					break;
@@ -52587,6 +105608,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER
 						LOAD_OPLINE_EX();
 
 
+
+
 						ZEND_VM_ENTER_EX();
 					}
 					/* Fall through to read_property for hooks. */
@@ -52666,10 +105689,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER
 fetch_obj_r_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -52684,13 +105709,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER
 		((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL),
 		BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *property, *container, *result;
@@ -52701,13 +105727,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container;
@@ -52715,6 +105742,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE
 
 	SAVE_OPLINE();
 	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
+	 * calls using ??=, i.e. foo()->bar ??= baz. */
 
 	if (IS_CV == IS_CONST ||
 	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -52825,10 +105854,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE
 fetch_obj_is_finish:
 
 
+
+
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 #if 0
 	USE_OPLINE
@@ -52837,15 +105868,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_
 	if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
 		/* Behave like FETCH_OBJ_W */
 		if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
-			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+			ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 		}
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	} else {
-		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+		if (IS_CV == IS_VAR) {
+			zval *op1 = EX_VAR(opline->op1.var);
+			if (Z_TYPE_P(op1) == IS_REFERENCE) {
+				zend_unwrap_reference(op1);
+			}
+		}
+		ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *container, *property, *result;
@@ -52856,13 +105893,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN
 	result = EX_VAR(opline->result.var);
 	zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC);
 
+
 	if (IS_CV == IS_VAR) {
 		FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -52985,6 +106023,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_
 		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -53005,18 +106044,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -53165,166 +106207,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_
 	}
 
 
-	/* assign_obj has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
-
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *object, *value, tmp;
-	zend_object *zobj;
-	zend_string *name, *tmp_name;
-	zend_refcounted *garbage = NULL;
-
-	SAVE_OPLINE();
-	object = EX_VAR(opline->op1.var);
-	value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-
-	if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
-		if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) {
-			object = Z_REFVAL_P(object);
-			goto assign_object;
-		}
-		zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC);
-		value = &EG(uninitialized_zval);
-		goto free_and_exit_assign_obj;
-	}
-
-assign_object:
-	zobj = Z_OBJ_P(object);
-	if (IS_CV == IS_CONST) {
-		if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) {
-			void **cache_slot = CACHE_ADDR(opline->extended_value);
-			uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
-			zval *property_val;
-			zend_property_info *prop_info;
-
-			if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
-				prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
-
-assign_obj_simple:
-				property_val = OBJ_PROP(zobj, prop_offset);
-				if (Z_TYPE_P(property_val) != IS_UNDEF) {
-					if (prop_info != NULL) {
-						value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
-						goto free_and_exit_assign_obj;
-					} else {
-fast_assign_obj:
-						value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
-						if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-							ZVAL_COPY(EX_VAR(opline->result.var), value);
-						}
-						goto exit_assign_obj;
-					}
-				}
-			} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) {
-				name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-				if (UNEXPECTED(zend_lazy_object_must_init(zobj))) {
-					zobj = zend_lazy_object_init(zobj);
-					if (!zobj) {
-						value = &EG(uninitialized_zval);
-						goto free_and_exit_assign_obj;
-					}
-				}
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					rebuild_object_properties_internal(zobj);
-				}
-				if (EXPECTED(zobj->properties != NULL)) {
-					if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
-						if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
-							GC_DELREF(zobj->properties);
-						}
-						zobj->properties = zend_array_dup(zobj->properties);
-					}
-					property_val = zend_hash_find_known_hash(zobj->properties, name);
-					if (property_val) {
-						goto fast_assign_obj;
-					}
-				}
-
-				if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) {
-					if (IS_VAR == IS_CONST) {
-						if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
-							Z_ADDREF_P(value);
-						}
-					} else if (IS_VAR != IS_TMP_VAR) {
-						if (Z_ISREF_P(value)) {
-							if (IS_VAR == IS_VAR) {
-								zend_reference *ref = Z_REF_P(value);
-								if (GC_DELREF(ref) == 0) {
-									ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
-									efree_size(ref, sizeof(zend_reference));
-									value = &tmp;
-								} else {
-									value = Z_REFVAL_P(value);
-									Z_TRY_ADDREF_P(value);
-								}
-							} else {
-								value = Z_REFVAL_P(value);
-								Z_TRY_ADDREF_P(value);
-							}
-						} else if (IS_VAR == IS_CV) {
-							Z_TRY_ADDREF_P(value);
-						}
-					}
-					zend_hash_add_new(zobj->properties, name, value);
-					if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-						ZVAL_COPY(EX_VAR(opline->result.var), value);
-					}
-					goto exit_assign_obj;
-				}
-			} else {
-				ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
-				if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
-					prop_info = CACHED_PTR_EX(cache_slot + 2);
-					prop_offset = prop_info->offset;
-					if (!ZEND_TYPE_IS_SET(prop_info->type)) {
-						prop_info = NULL;
-					}
-					goto assign_obj_simple;
-				}
-				/* Fall through to write_property for hooks. */
-			}
-		}
-		name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC));
-	} else {
-		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
-		if (UNEXPECTED(!name)) {
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			UNDEF_RESULT();
-			goto exit_assign_obj;
-		}
-	}
-
-	if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-		ZVAL_DEREF(value);
-	}
-
-	value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
-
-	if (IS_CV != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
-
-free_and_exit_assign_obj:
-	if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) {
-		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
-	}
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-exit_assign_obj:
-	if (garbage) {
-		GC_DTOR_NO_REF(garbage);
-	}
 
 
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object, *value, tmp;
@@ -53447,6 +106337,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_
 		name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name);
 		if (UNEXPECTED(!name)) {
 
+
 			UNDEF_RESULT();
 			goto exit_assign_obj;
 		}
@@ -53467,18 +106358,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_
 		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
 	}
 
+
 exit_assign_obj:
 	if (garbage) {
 		GC_DTOR_NO_REF(garbage);
 	}
 
 
+
+
 	/* assign_obj has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -53576,6 +106470,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
@@ -53583,12 +106478,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 			if (IS_CV == IS_UNUSED) {
 				zend_use_new_element_for_string();
 
+
 				UNDEF_RESULT();
 			} else {
 				dim = EX_VAR(opline->op2.var);
 				value = RT_CONSTANT((opline+1), (opline+1)->op1);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
@@ -53596,6 +106493,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -53617,6 +106515,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
 
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -53624,13 +106523,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 	}
 	if (IS_CV != IS_UNUSED) {
 
+
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
 	zval *object_ptr, *orig_object_ptr;
@@ -53722,33 +106623,191 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 			value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
 			if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
 				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+			} else if (IS_TMP_VAR & (IS_CV|IS_VAR)) {
+				ZVAL_DEREF(value);
+			}
+
+			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
+				zend_objects_store_del(obj);
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
+			if (IS_CV == IS_UNUSED) {
+				zend_use_new_element_for_string();
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				dim = EX_VAR(opline->op2.var);
+				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			}
+		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
+			if (Z_ISREF_P(orig_object_ptr)
+			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
+			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
+				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+				UNDEF_RESULT();
+			} else {
+				HashTable *ht = zend_new_array(8);
+				uint8_t old_type = Z_TYPE_P(object_ptr);
+
+				ZVAL_ARR(object_ptr, ht);
+				if (UNEXPECTED(old_type == IS_FALSE)) {
+					GC_ADDREF(ht);
+					zend_false_to_array_deprecated();
+					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
+						zend_array_destroy(ht);
+						goto assign_dim_error;
+					}
+				}
+				goto try_assign_dim_array;
+			}
+		} else {
+			zend_use_scalar_as_array();
+			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+assign_dim_error:
+			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+				ZVAL_NULL(EX_VAR(opline->result.var));
+			}
+		}
+	}
+	if (IS_CV != IS_UNUSED) {
+
+
+	}
+
+
+	/* assign_dim has two opcodes! */
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *object_ptr, *orig_object_ptr;
+	zval *value;
+	zval *variable_ptr;
+	zval *dim;
+	zend_refcounted *garbage = NULL;
+
+	SAVE_OPLINE();
+	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+
+	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+try_assign_dim_array:
+		SEPARATE_ARRAY(object_ptr);
+		if (IS_CV == IS_UNUSED) {
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
+				HashTable *ht = Z_ARRVAL_P(object_ptr);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+					GC_ADDREF(ht);
+				}
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
+					zend_array_destroy(ht);
+					goto assign_dim_error;
+				}
+			}
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_DEREF(value);
+			}
+			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+			if (UNEXPECTED(value == NULL)) {
+				zend_cannot_add_element();
+				goto assign_dim_error;
+			} else if (IS_CV == IS_CV) {
+				if (Z_REFCOUNTED_P(value)) {
+					Z_ADDREF_P(value);
+				}
+			} else if (IS_CV == IS_VAR) {
+				zval *free_op_data = EX_VAR((opline+1)->op1.var);
+				if (Z_ISREF_P(free_op_data)) {
+					if (Z_REFCOUNTED_P(value)) {
+						Z_ADDREF_P(value);
+					}
+					zval_ptr_dtor_nogc(free_op_data);
+				}
+			} else if (IS_CV == IS_CONST) {
+				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
+					Z_ADDREF_P(value);
+				}
+			}
+		} else {
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CONST) {
+				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			} else {
+				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+			}
+			if (UNEXPECTED(variable_ptr == NULL)) {
+				goto assign_dim_error;
+			}
+			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
+			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		}
+		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		if (EXPECTED(Z_ISREF_P(object_ptr))) {
+			object_ptr = Z_REFVAL_P(object_ptr);
+			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
+				goto try_assign_dim_array;
+			}
+		}
+		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
+			zend_object *obj = Z_OBJ_P(object_ptr);
+
+			GC_ADDREF(obj);
+			dim = EX_VAR(opline->op2.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
+				dim = ZVAL_UNDEFINED_OP2();
+			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
+				dim++;
+			}
+
+			value = EX_VAR((opline+1)->op1.var);
+			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
+				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+			} else if (IS_CV & (IS_CV|IS_VAR)) {
 				ZVAL_DEREF(value);
 			}
 
 			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
 			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
 				zend_objects_store_del(obj);
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
 			if (IS_CV == IS_UNUSED) {
 				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 				UNDEF_RESULT();
 			} else {
 				dim = EX_VAR(opline->op2.var);
-				value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC);
+				value = EX_VAR((opline+1)->op1.var);
 				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 			}
 		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
 			if (Z_ISREF_P(orig_object_ptr)
 			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
 			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
 				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 				UNDEF_RESULT();
 			} else {
 				HashTable *ht = zend_new_array(8);
@@ -53769,7 +106828,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 			zend_use_scalar_as_array();
 			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+
+
 			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			}
@@ -53777,1354 +106837,1869 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_
 	}
 	if (IS_CV != IS_UNUSED) {
 
+
 	}
 
+
 	/* assign_dim has two opcodes! */
 	ZEND_VM_NEXT_OPCODE_EX(1, 2);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
 	zval *value;
 	zval *variable_ptr;
-	zval *dim;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(0)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(0)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *value;
+	zval *variable_ptr;
+
+	SAVE_OPLINE();
+	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
+
+	if (0 || UNEXPECTED(1)) {
+		zend_refcounted *garbage = NULL;
+
+		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
+		if (UNEXPECTED(1)) {
+			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		}
+		if (garbage) {
+			GC_DTOR_NO_REF(garbage);
+		}
+	} else {
+		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+	}
+
+
+	/* zend_assign_to_variable() always takes care of op2, never free it! */
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_REF_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *variable_ptr;
+	zval *value_ptr;
 	zend_refcounted *garbage = NULL;
 
 	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
+	variable_ptr = EX_VAR(opline->op1.var);
 
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
+	if (IS_CV == IS_VAR &&
+	           UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+
+		zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object");
+		variable_ptr = &EG(uninitialized_zval);
+	} else if (IS_CV == IS_VAR &&
+	           opline->extended_value == ZEND_RETURNS_FUNCTION &&
+			   UNEXPECTED(!Z_ISREF_P(value_ptr))) {
+
+		variable_ptr = zend_wrong_assign_to_variable_reference(
+			variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage);
+	}
+
+	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+		ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
+	}
+
+	if (garbage) {
+		GC_DTOR(garbage);
+	}
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
 		if (IS_CV == IS_UNUSED) {
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *property, *container, *value_ptr;
+
+	SAVE_OPLINE();
+
+	container = EX_VAR(opline->op1.var);
+	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+
+	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+
+	if (1) {
+		if (IS_CV == IS_UNUSED) {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		} else {
+			if (IS_CV == IS_CONST) {
+				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			} else {
+				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+			}
+		}
+	} else {
+		zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	}
+
+
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+}
+
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	zend_string *op1_str, *op2_str, *str;
+
+
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
+	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
+		zend_string *op1_str = Z_STR_P(op1);
+		zend_string *op2_str = Z_STR_P(op2);
+		zend_string *str;
+		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+
+		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
+				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
+			} else {
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
+		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
+			size_t len = ZSTR_LEN(op1_str);
+
+			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		} else {
+			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+			GC_ADD_FLAGS(str, flags);
+			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op1_str, 0);
+			}
+			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+				zend_string_release_ex(op2_str, 0);
+			}
+		}
+		ZEND_VM_NEXT_OPCODE();
+	}
+
+	SAVE_OPLINE();
+	if (IS_CV == IS_CONST) {
+		op1_str = Z_STR_P(op1);
+	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+		op1_str = zend_string_copy(Z_STR_P(op1));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		op1_str = zval_get_string_func(op1);
+	}
+	if (IS_CV == IS_CONST) {
+		op2_str = Z_STR_P(op2);
+	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+		op2_str = zend_string_copy(Z_STR_P(op2));
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP2();
+		}
+		op2_str = zval_get_string_func(op2);
+	}
+	do {
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
+						GC_ADDREF(op2_str);
+					}
 				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
-					zend_array_destroy(ht);
-					goto assign_dim_error;
+				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
+				zend_string_release_ex(op1_str, 0);
+				break;
+			}
+		}
+		if (IS_CV != IS_CONST) {
+			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
+						GC_ADDREF(op1_str);
+					}
 				}
+				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
+				zend_string_release_ex(op2_str, 0);
+				break;
 			}
-			if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
-				ZVAL_DEREF(value);
+		}
+		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
+		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
+		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+
+		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
+		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op1_str, 0);
+		}
+		if (IS_CV != IS_CONST) {
+			zend_string_release_ex(op2_str, 0);
+		}
+	} while (0);
+
+
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *function_name;
+	zval *object;
+	zend_function *fbc;
+	zend_class_entry *called_scope;
+	zend_object *obj;
+	zend_execute_data *call;
+	uint32_t call_info;
+
+	SAVE_OPLINE();
+
+	object = EX_VAR(opline->op1.var);
+
+	if (IS_CV != IS_CONST) {
+		function_name = EX_VAR(opline->op2.var);
+	}
+
+	if (IS_CV != IS_CONST &&
+	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+		do {
+			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
+				function_name = Z_REFVAL_P(function_name);
+				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
+					break;
+				}
+			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
+				ZVAL_UNDEFINED_OP2();
+				if (UNEXPECTED(EG(exception) != NULL)) {
+
+
+					HANDLE_EXCEPTION();
+				}
 			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_VAR == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
+			zend_throw_error(NULL, "Method name must be a string");
+
+
+
+
+			HANDLE_EXCEPTION();
+		} while (0);
+	}
+
+	if (IS_CV == IS_UNUSED) {
+		obj = Z_OBJ_P(object);
+	} else {
+		do {
+			if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+				obj = Z_OBJ_P(object);
+			} else {
+				if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
+					zend_reference *ref = Z_REF_P(object);
+
+					object = &ref->val;
+					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+						obj = Z_OBJ_P(object);
+						if (IS_CV & IS_VAR) {
+							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+								efree_size(ref, sizeof(zend_reference));
+							} else {
+								Z_ADDREF_P(object);
+							}
+						}
+						break;
+					}
 				}
-			} else if (IS_VAR == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
+				if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+					object = ZVAL_UNDEFINED_OP1();
+					if (UNEXPECTED(EG(exception) != NULL)) {
+						if (IS_CV != IS_CONST) {
+
+
+						}
+						HANDLE_EXCEPTION();
 					}
-					zval_ptr_dtor_nogc(free_op_data);
 				}
-			} else if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
+				if (IS_CV == IS_CONST) {
+					function_name = EX_VAR(opline->op2.var);
 				}
+				zend_invalid_method_call(object, function_name);
+
+
+
+
+				HANDLE_EXCEPTION();
 			}
-		} else {
-			dim = EX_VAR(opline->op2.var);
-			if (IS_CV == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
-			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+		} while (0);
+	}
+
+	called_scope = obj->ce;
+
+	if (IS_CV == IS_CONST &&
+	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
+		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
+	} else {
+		zend_object *orig_obj = obj;
+
+		if (IS_CV == IS_CONST) {
+			function_name = EX_VAR(opline->op2.var);
+		}
+
+		/* First, locate the function. */
+		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
+		if (UNEXPECTED(fbc == NULL)) {
+			if (EXPECTED(!EG(exception))) {
+				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
 			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
+
+
+			if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
 			}
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage);
+			HANDLE_EXCEPTION();
 		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		if (IS_CV == IS_CONST &&
+		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
+		    EXPECTED(obj == orig_obj)) {
+			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
 		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
+			GC_ADDREF(obj); /* For $this pointer */
+			if (GC_DELREF(orig_obj) == 0) {
+				zend_objects_store_del(orig_obj);
+			}
 		}
-	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
+		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
+			init_func_run_time_cache(&fbc->op_array);
+		}
+	}
+
+	if (IS_CV != IS_CONST) {
+
+
+	}
+
+	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
+	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
+		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
+			zend_objects_store_del(obj);
+			if (UNEXPECTED(EG(exception))) {
+				HANDLE_EXCEPTION();
 			}
 		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
+		/* call static method */
+		obj = (zend_object*)called_scope;
+		call_info = ZEND_CALL_NESTED_FUNCTION;
+	} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
+		if (IS_CV == IS_CV) {
+			GC_ADDREF(obj); /* For $this pointer */
+		}
+		/* CV may be changed indirectly (e.g. when it's a reference) */
+		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	}
+
+	call = zend_vm_stack_push_call_frame(call_info,
+		fbc, opline->extended_value, obj);
+	call->prev_execute_data = EX(call);
+	EX(call) = call;
+
+	ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *expr_ptr, new_expr;
+
+	SAVE_OPLINE();
+	if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
+	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+		if (Z_ISREF_P(expr_ptr)) {
+			Z_ADDREF_P(expr_ptr);
+		} else {
+			ZVAL_MAKE_REF_EX(expr_ptr, 2);
+		}
 
-			GC_ADDREF(obj);
-			dim = EX_VAR(opline->op2.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
 
-			value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-			if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_VAR & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
+	} else {
+		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+		if (IS_CV == IS_TMP_VAR) {
+			/* pass */
+		} else if (IS_CV == IS_CONST) {
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else if (IS_CV == IS_CV) {
+			ZVAL_DEREF(expr_ptr);
+			Z_TRY_ADDREF_P(expr_ptr);
+		} else /* if (IS_CV == IS_VAR) */ {
+			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
+				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+
+				expr_ptr = Z_REFVAL_P(expr_ptr);
+				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
+					expr_ptr = &new_expr;
+					efree_size(ref, sizeof(zend_reference));
+				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
+					Z_ADDREF_P(expr_ptr);
+				}
 			}
+		}
+	}
 
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
+	if (IS_CV != IS_UNUSED) {
+		zval *offset = EX_VAR(opline->op2.var);
+		zend_string *str;
+		zend_ulong hval;
 
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
+add_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index;
+				}
 			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if (IS_CV == IS_UNUSED) {
-				zend_use_new_element_for_string();
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				dim = EX_VAR(opline->op2.var);
-				value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+str_index:
+			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index:
+			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+			offset = Z_REFVAL_P(offset);
+			goto add_again;
+		} else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) {
+			zval tmp;
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				ZVAL_COPY(&tmp, expr_ptr);
 			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-				zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
-
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
-					}
-				}
-				goto try_assign_dim_array;
+			zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead");
+			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
+				/* A userland error handler can do funky things to the expression, so reset it */
+				zval_ptr_dtor(expr_ptr);
+				ZVAL_COPY_VALUE(expr_ptr, &tmp);
 			}
-		} else {
-			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-assign_dim_error:
-			zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
+			if (UNEXPECTED(EG(exception))) {
+				zval_ptr_dtor_nogc(expr_ptr);
+				HANDLE_EXCEPTION();
 			}
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_FALSE) {
+			hval = 0;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_TRUE) {
+			hval = 1;
+			goto num_index;
+		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+			zend_use_resource_as_offset(offset);
+			hval = Z_RES_HANDLE_P(offset);
+			goto num_index;
+		} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+			ZVAL_UNDEFINED_OP2();
+			str = ZSTR_EMPTY_ALLOC();
+			goto str_index;
+		} else {
+			zend_illegal_array_offset_access(offset);
+			zval_ptr_dtor_nogc(expr_ptr);
 		}
-	}
-	if (IS_CV != IS_UNUSED) {
 
+
+	} else {
+		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
+			zend_cannot_add_element();
+			zval_ptr_dtor_nogc(expr_ptr);
+		}
 	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zval *array;
+	uint32_t size;
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	array = EX_VAR(opline->result.var);
+	if (IS_CV != IS_UNUSED) {
+		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
+		ZVAL_ARR(array, zend_new_array(size));
+		/* Explicitly initialize array as not-packed if flag is set */
+		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
+			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
+		}
+		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	} else {
+		ZVAL_ARR(array, zend_new_array(0));
+		ZEND_VM_NEXT_OPCODE();
+	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *object_ptr, *orig_object_ptr;
-	zval *value;
-	zval *variable_ptr;
-	zval *dim;
-	zend_refcounted *garbage = NULL;
+	zval *container;
+	zval *offset;
+	zend_ulong hval;
+	zend_string *key;
 
 	SAVE_OPLINE();
-	orig_object_ptr = object_ptr = EX_VAR(opline->op1.var);
+	container = EX_VAR(opline->op1.var);
+	offset = EX_VAR(opline->op2.var);
 
-	if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-try_assign_dim_array:
-		SEPARATE_ARRAY(object_ptr);
-		if (IS_CV == IS_UNUSED) {
-			value = EX_VAR((opline+1)->op1.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
-				HashTable *ht = Z_ARRVAL_P(object_ptr);
-				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-					GC_ADDREF(ht);
+	do {
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			HashTable *ht;
+
+unset_dim_array:
+			SEPARATE_ARRAY(container);
+			ht = Z_ARRVAL_P(container);
+offset_again:
+			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+				key = Z_STR_P(offset);
+				if (IS_CV != IS_CONST) {
+					if (ZEND_HANDLE_NUMERIC(key, hval)) {
+						goto num_index_dim;
+					}
 				}
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
+str_index_dim:
+				ZEND_ASSERT(ht != &EG(symbol_table));
+				zend_hash_del(ht, key);
+			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+				hval = Z_LVAL_P(offset);
+num_index_dim:
+				zend_hash_index_del(ht, hval);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
+				offset = Z_REFVAL_P(offset);
+				goto offset_again;
+			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
+				/* The array may be destroyed while throwing a warning in case the float is not representable as an int.
+				 * Temporarily increase the refcount to detect this situation. */
+				GC_TRY_ADDREF(ht);
+				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
 				if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
 					zend_array_destroy(ht);
-					goto assign_dim_error;
-				}
-			}
-			if (IS_CV == IS_CV || IS_CV == IS_VAR) {
-				ZVAL_DEREF(value);
-			}
-			value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
-			if (UNEXPECTED(value == NULL)) {
-				zend_cannot_add_element();
-				goto assign_dim_error;
-			} else if (IS_CV == IS_CV) {
-				if (Z_REFCOUNTED_P(value)) {
-					Z_ADDREF_P(value);
-				}
-			} else if (IS_CV == IS_VAR) {
-				zval *free_op_data = EX_VAR((opline+1)->op1.var);
-				if (Z_ISREF_P(free_op_data)) {
-					if (Z_REFCOUNTED_P(value)) {
-						Z_ADDREF_P(value);
-					}
-					zval_ptr_dtor_nogc(free_op_data);
+					break;
 				}
-			} else if (IS_CV == IS_CONST) {
-				if (UNEXPECTED(Z_REFCOUNTED_P(value))) {
-					Z_ADDREF_P(value);
+				if (EG(exception)) {
+					break;
 				}
-			}
-		} else {
-			dim = EX_VAR(opline->op2.var);
-			if (IS_CV == IS_CONST) {
-				variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_NULL) {
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_FALSE) {
+				hval = 0;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_TRUE) {
+				hval = 1;
+				goto num_index_dim;
+			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
+				zend_use_resource_as_offset(offset);
+				hval = Z_RES_HANDLE_P(offset);
+				goto num_index_dim;
+			} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
+				ZVAL_UNDEFINED_OP2();
+				key = ZSTR_EMPTY_ALLOC();
+				goto str_index_dim;
 			} else {
-				variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC);
+				zend_illegal_array_offset_unset(offset);
 			}
-			if (UNEXPECTED(variable_ptr == NULL)) {
-				goto assign_dim_error;
+			break;
+		} else if (Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+				goto unset_dim_array;
 			}
-			value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC);
-			value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
 		}
-		if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+			container = ZVAL_UNDEFINED_OP1();
 		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
+			offset = ZVAL_UNDEFINED_OP2();
 		}
-	} else {
-		if (EXPECTED(Z_ISREF_P(object_ptr))) {
-			object_ptr = Z_REFVAL_P(object_ptr);
-			if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
-				goto try_assign_dim_array;
+		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+			if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+				offset++;
 			}
+			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+			zend_throw_error(NULL, "Cannot unset string offsets");
+		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
+			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
+		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
+			zend_false_to_array_deprecated();
 		}
-		if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
-			zend_object *obj = Z_OBJ_P(object_ptr);
-
-			GC_ADDREF(obj);
-			dim = EX_VAR(opline->op2.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) {
-				dim = ZVAL_UNDEFINED_OP2();
-			} else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
-				dim++;
-			}
+	} while (0);
 
-			value = EX_VAR((opline+1)->op1.var);
-			if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) {
-				value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC);
-			} else if (IS_CV & (IS_CV|IS_VAR)) {
-				ZVAL_DEREF(value);
-			}
 
-			zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC);
 
-			if (UNEXPECTED(GC_DELREF(obj) == 0)) {
-				zend_objects_store_del(obj);
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
-			if (IS_CV == IS_UNUSED) {
-				zend_use_new_element_for_string();
 
-				UNDEF_RESULT();
-			} else {
-				dim = EX_VAR(opline->op2.var);
-				value = EX_VAR((opline+1)->op1.var);
-				zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-			}
-		} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
-			if (Z_ISREF_P(orig_object_ptr)
-			 && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
-			 && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
-				dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *container;
+	zval *offset;
+	zend_string *name, *tmp_name;
 
-				UNDEF_RESULT();
-			} else {
-				HashTable *ht = zend_new_array(8);
-				uint8_t old_type = Z_TYPE_P(object_ptr);
+	SAVE_OPLINE();
+	container = EX_VAR(opline->op1.var);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 
-				ZVAL_ARR(object_ptr, ht);
-				if (UNEXPECTED(old_type == IS_FALSE)) {
-					GC_ADDREF(ht);
-					zend_false_to_array_deprecated();
-					if (UNEXPECTED(GC_DELREF(ht) == 0)) {
-						zend_array_destroy(ht);
-						goto assign_dim_error;
+	do {
+		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+			if (Z_ISREF_P(container)) {
+				container = Z_REFVAL_P(container);
+				if (Z_TYPE_P(container) != IS_OBJECT) {
+					if (IS_CV == IS_CV
+					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
+						ZVAL_UNDEFINED_OP1();
 					}
+					break;
 				}
-				goto try_assign_dim_array;
+			} else {
+				break;
 			}
+		}
+		if (IS_CV == IS_CONST) {
+			name = Z_STR_P(offset);
 		} else {
-			zend_use_scalar_as_array();
-			dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-assign_dim_error:
-
-			if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-				ZVAL_NULL(EX_VAR(opline->result.var));
+			name = zval_try_get_tmp_string(offset, &tmp_name);
+			if (UNEXPECTED(!name)) {
+				break;
 			}
 		}
-	}
-	if (IS_CV != IS_UNUSED) {
+		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
+		if (IS_CV != IS_CONST) {
+			zend_tmp_string_release(tmp_name);
+		}
+	} while (0);
 
-	}
 
-	/* assign_dim has two opcodes! */
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+
+
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
+	zval *container;
+	bool result;
+	zend_ulong hval;
+	zval *offset;
 
 	SAVE_OPLINE();
-	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = EX_VAR(opline->op1.var);
+	container = EX_VAR(opline->op1.var);
+	offset = EX_VAR(opline->op2.var);
 
-	if (0 || UNEXPECTED(0)) {
-		zend_refcounted *garbage = NULL;
+	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+		HashTable *ht;
+		zval *value;
+		zend_string *str;
 
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(0)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
-		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
+isset_dim_obj_array:
+		ht = Z_ARRVAL_P(container);
+isset_again:
+		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
+			str = Z_STR_P(offset);
+			if (IS_CV != IS_CONST) {
+				if (ZEND_HANDLE_NUMERIC(str, hval)) {
+					goto num_index_prop;
+				}
+			}
+			value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST);
+		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
+			hval = Z_LVAL_P(offset);
+num_index_prop:
+			value = zend_hash_index_find(ht, hval);
+		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
+			offset = Z_REFVAL_P(offset);
+			goto isset_again;
+		} else {
+			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
+			if (UNEXPECTED(EG(exception))) {
+				result = 0;
+				goto isset_dim_obj_exit;
+			}
 		}
-	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
-	}
-
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
-
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *value;
-	zval *variable_ptr;
+		if (!(opline->extended_value & ZEND_ISEMPTY)) {
+			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
+			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
+			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
 
-	SAVE_OPLINE();
-	value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = EX_VAR(opline->op1.var);
+			if (IS_CV & (IS_CONST|IS_CV)) {
+				/* avoid exception check */
 
-	if (0 || UNEXPECTED(1)) {
-		zend_refcounted *garbage = NULL;
 
-		value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage);
-		if (UNEXPECTED(1)) {
-			ZVAL_COPY(EX_VAR(opline->result.var), value);
+				ZEND_VM_SMART_BRANCH(result, 0);
+			}
+		} else {
+			result = (value == NULL || !i_zend_is_true(value));
 		}
-		if (garbage) {
-			GC_DTOR_NO_REF(garbage);
+		goto isset_dim_obj_exit;
+	} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
+		container = Z_REFVAL_P(container);
+		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+			goto isset_dim_obj_array;
 		}
+	}
+
+	if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
+		offset++;
+	}
+	if (!(opline->extended_value & ZEND_ISEMPTY)) {
+		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
 	} else {
-		value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
+		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
 	}
 
-	/* zend_assign_to_variable() always takes care of op2, never free it! */
+isset_dim_obj_exit:
 
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *variable_ptr;
-	zval *value_ptr;
-	zend_refcounted *garbage = NULL;
+	zval *container;
+	int result;
+	zval *offset;
+	zend_string *name, *tmp_name;
 
 	SAVE_OPLINE();
-	value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
-	variable_ptr = EX_VAR(opline->op1.var);
-
-	if (IS_CV == IS_VAR &&
-	           UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
+	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 
-		zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object");
-		variable_ptr = &EG(uninitialized_zval);
-	} else if (IS_CV == IS_VAR &&
-	           opline->extended_value == ZEND_RETURNS_FUNCTION &&
-			   UNEXPECTED(!Z_ISREF_P(value_ptr))) {
+	if (IS_CV == IS_CONST ||
+	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
+		if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
+			container = Z_REFVAL_P(container);
+			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+				result = (opline->extended_value & ZEND_ISEMPTY);
+				goto isset_object_finish;
+			}
+		} else {
+			result = (opline->extended_value & ZEND_ISEMPTY);
+			goto isset_object_finish;
+		}
+	}
 
-		variable_ptr = zend_wrong_assign_to_variable_reference(
-			variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC);
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(offset);
 	} else {
-		zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage);
+		name = zval_try_get_tmp_string(offset, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			result = 0;
+			goto isset_object_finish;
+		}
 	}
 
-	if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
-		ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
-	}
+	result =
+		(opline->extended_value & ZEND_ISEMPTY) ^
+		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
 
-	if (garbage) {
-		GC_DTOR(garbage);
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
 	}
 
+isset_object_finish:
+
 
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *property, *container, *value_ptr;
 
-	SAVE_OPLINE();
+	zval *key, *subject;
+	HashTable *ht;
+	bool result;
 
-	container = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	SAVE_OPLINE();
 
-	value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC);
+	key = EX_VAR(opline->op1.var);
+	subject = EX_VAR(opline->op2.var);
 
-	if (1) {
-		if (IS_CV == IS_UNUSED) {
-			if (IS_CV == IS_CONST) {
-				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
-			} else {
-				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
-			}
-		} else {
-			if (IS_CV == IS_CONST) {
-				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
-			} else {
-				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+array_key_exists_array:
+		ht = Z_ARRVAL_P(subject);
+		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	} else {
+		if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
+			subject = Z_REFVAL_P(subject);
+			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
+				goto array_key_exists_array;
 			}
 		}
-	} else {
-		zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
+		result = 0;
 	}
 
 
-	zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+
+
+	ZEND_VM_SMART_BRANCH(result, 1);
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
-	zval *property, *container, *value_ptr;
+
+	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
 
 	SAVE_OPLINE();
+	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+	}
 
-	container = EX_VAR(opline->op1.var);
-	property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	/* Destroy the previously yielded value */
+	zval_ptr_dtor(&generator->value);
 
-	value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC);
+	/* Destroy the previously yielded key */
+	zval_ptr_dtor(&generator->key);
 
-	if (1) {
-		if (IS_CV == IS_UNUSED) {
-			if (IS_CV == IS_CONST) {
-				zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+	/* Set the new yielded value */
+	if (IS_CV != IS_UNUSED) {
+		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+			/* Constants and temporary variables aren't yieldable by reference,
+			 * but we still allow them with a notice. */
+			if (IS_CV & (IS_CONST|IS_TMP_VAR)) {
+				zval *value;
+
+				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+				value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CONST) {
+					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+						Z_ADDREF(generator->value);
+					}
+				}
 			} else {
-				zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+				zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+
+				/* If a function call result is yielded and the function did
+				 * not return by reference we throw a notice. */
+				do {
+					if (IS_CV == IS_VAR) {
+						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
+						if (opline->extended_value == ZEND_RETURNS_FUNCTION
+						 && !Z_ISREF_P(value_ptr)) {
+							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+							ZVAL_COPY(&generator->value, value_ptr);
+							break;
+						}
+					}
+					if (Z_ISREF_P(value_ptr)) {
+						Z_ADDREF_P(value_ptr);
+					} else {
+						ZVAL_MAKE_REF_EX(value_ptr, 2);
+					}
+					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+				} while (0);
+
+
 			}
 		} else {
+			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+
+			/* Consts, temporary variables and references need copying */
 			if (IS_CV == IS_CONST) {
-				zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+					Z_ADDREF(generator->value);
+				}
+			} else if (IS_CV == IS_TMP_VAR) {
+				ZVAL_COPY_VALUE(&generator->value, value);
+			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+
+
 			} else {
-				zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+				ZVAL_COPY_VALUE(&generator->value, value);
+				if (IS_CV == IS_CV) {
+					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				}
 			}
 		}
 	} else {
-		zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC);
+		/* If no value was specified yield null */
+		ZVAL_NULL(&generator->value);
 	}
 
+	/* Set the new yielded key */
+	if (IS_CV != IS_UNUSED) {
+		zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+		if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
+			key = Z_REFVAL_P(key);
+		}
+		ZVAL_COPY(&generator->key, key);
+
 
+		if (Z_TYPE(generator->key) == IS_LONG
+		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
+		) {
+			generator->largest_used_integer_key = Z_LVAL(generator->key);
+		}
+	} else {
+		/* If no key was specified we use auto-increment keys */
+		generator->largest_used_integer_key++;
+		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	}
 
-	ZEND_VM_NEXT_OPCODE_EX(1, 2);
+	if (RETURN_VALUE_USED(opline)) {
+		/* If the return value of yield is used set the send
+		 * target and initialize it to NULL */
+		generator->send_target = EX_VAR(opline->result.var);
+		ZVAL_NULL(generator->send_target);
+	} else {
+		generator->send_target = NULL;
+	}
+
+	/* The GOTO VM uses a local opline variable. We need to set the opline
+	 * variable in execute_data so we don't resume at an old position. */
+	SAVE_OPLINE();
+
+	ZEND_VM_RETURN();
 }
 
-/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
+	/* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
+	/* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
+	/* (Infinite recursion when comparing arrays is an uncatchable fatal error) */
 	USE_OPLINE
 	zval *op1, *op2;
-	zend_string *op1_str, *op2_str, *str;
-
+	bool result;
 
 	op1 = EX_VAR(opline->op1.var);
 	op2 = EX_VAR(opline->op2.var);
-	if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
-	    (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
-		zend_string *op1_str = Z_STR_P(op1);
-		zend_string *op2_str = Z_STR_P(op2);
-		zend_string *str;
-		uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str);
+	result = fast_is_identical_function(op1, op2);
+	/* Free is a no-op for const/cv */
+	ZEND_VM_SMART_BRANCH(result, 0);
+}
 
-		if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-			}
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-		} else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-			if (IS_CV == IS_CONST || IS_CV == IS_CV) {
-				ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
-			} else {
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
-			}
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else if (IS_CV != IS_CONST && IS_CV != IS_CV &&
-		    !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
-			size_t len = ZSTR_LEN(op1_str);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
+	zval *op1, *op2;
+	bool result;
 
-			str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		} else {
-			str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-			memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-			memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
-			GC_ADD_FLAGS(str, flags);
-			ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op1_str, 0);
-			}
-			if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
-				zend_string_release_ex(op2_str, 0);
-			}
-		}
-		ZEND_VM_NEXT_OPCODE();
-	}
+	op1 = EX_VAR(opline->op1.var);
+	op2 = EX_VAR(opline->op2.var);
+	result = fast_is_identical_function(op1, op2);
+	/* Free is a no-op for const/cv */
+	ZEND_VM_SMART_BRANCH(!result, 0);
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	USE_OPLINE
 
 	SAVE_OPLINE();
-	if (IS_CV == IS_CONST) {
-		op1_str = Z_STR_P(op1);
-	} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
-		op1_str = zend_string_copy(Z_STR_P(op1));
-	} else {
-		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP1();
-		}
-		op1_str = zval_get_string_func(op1);
-	}
-	if (IS_CV == IS_CONST) {
-		op2_str = Z_STR_P(op2);
-	} else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
-		op2_str = zend_string_copy(Z_STR_P(op2));
-	} else {
-		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
-			ZVAL_UNDEFINED_OP2();
-		}
-		op2_str = zval_get_string_func(op2);
-	}
-	do {
-		if (IS_CV != IS_CONST) {
-			if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
-				if (IS_CV == IS_CONST) {
-					if (UNEXPECTED(Z_REFCOUNTED_P(op2))) {
-						GC_ADDREF(op2_str);
-					}
-				}
-				ZVAL_STR(EX_VAR(opline->result.var), op2_str);
-				zend_string_release_ex(op1_str, 0);
-				break;
-			}
-		}
-		if (IS_CV != IS_CONST) {
-			if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
-				if (IS_CV == IS_CONST) {
-					if (UNEXPECTED(Z_REFCOUNTED_P(op1))) {
-						GC_ADDREF(op1_str);
-					}
-				}
-				ZVAL_STR(EX_VAR(opline->result.var), op1_str);
-				zend_string_release_ex(op2_str, 0);
-				break;
-			}
-		}
-		str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0);
-		memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str));
-		memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
+	zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
+}
 
-		ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str);
-		ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
-		if (IS_CV != IS_CONST) {
-			zend_string_release_ex(op1_str, 0);
-		}
-		if (IS_CV != IS_CONST) {
-			zend_string_release_ex(op2_str, 0);
-		}
-	} while (0);
+static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	return (zend_op*) ZEND_VM_ENTER_BIT;
+}
 
+static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) {
+	SAVE_OPLINE();
+	ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+}
+/* The following helpers can not tailcall due to signature mismatch. Redefine some macros so they do not enforce tailcall. */
+#pragma push_macro("ZEND_VM_CONTINUE")
+#undef  ZEND_VM_CONTINUE
+#pragma push_macro("ZEND_VM_INTERRUPT")
+#undef  ZEND_VM_INTERRUPT
+#define ZEND_VM_CONTINUE(handler) return opline
+#define ZEND_VM_INTERRUPT()       return zend_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	USE_OPLINE
 
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	add_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
 	USE_OPLINE
-	zval *function_name;
-	zval *object;
-	zend_function *fbc;
-	zend_class_entry *called_scope;
-	zend_object *obj;
-	zend_execute_data *call;
-	uint32_t call_info;
 
 	SAVE_OPLINE();
-
-	object = EX_VAR(opline->op1.var);
-
-	if (IS_CV != IS_CONST) {
-		function_name = EX_VAR(opline->op2.var);
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
 	}
-
-	if (IS_CV != IS_CONST &&
-	    UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
-		do {
-			if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) {
-				function_name = Z_REFVAL_P(function_name);
-				if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
-					break;
-				}
-			} else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) {
-				ZVAL_UNDEFINED_OP2();
-				if (UNEXPECTED(EG(exception) != NULL)) {
-
-					HANDLE_EXCEPTION();
-				}
-			}
-			zend_throw_error(NULL, "Method name must be a string");
-
-
-			HANDLE_EXCEPTION();
-		} while (0);
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
 	}
+	sub_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	if (IS_CV == IS_UNUSED) {
-		obj = Z_OBJ_P(object);
-	} else {
-		do {
-			if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
-				obj = Z_OBJ_P(object);
-			} else {
-				if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) {
-					zend_reference *ref = Z_REF_P(object);
-
-					object = &ref->val;
-					if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
-						obj = Z_OBJ_P(object);
-						if (IS_CV & IS_VAR) {
-							if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-								efree_size(ref, sizeof(zend_reference));
-							} else {
-								Z_ADDREF_P(object);
-							}
-						}
-						break;
-					}
-				}
-				if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
-					object = ZVAL_UNDEFINED_OP1();
-					if (UNEXPECTED(EG(exception) != NULL)) {
-						if (IS_CV != IS_CONST) {
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	USE_OPLINE
 
-						}
-						HANDLE_EXCEPTION();
-					}
-				}
-				if (IS_CV == IS_CONST) {
-					function_name = EX_VAR(opline->op2.var);
-				}
-				zend_invalid_method_call(object, function_name);
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	mul_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	USE_OPLINE
 
-				HANDLE_EXCEPTION();
-			}
-		} while (0);
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
 	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	mod_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	called_scope = obj->ce;
-
-	if (IS_CV == IS_CONST &&
-	    EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) {
-		fbc = CACHED_PTR(opline->result.num + sizeof(void*));
-	} else {
-		zend_object *orig_obj = obj;
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	USE_OPLINE
 
-		if (IS_CV == IS_CONST) {
-			function_name = EX_VAR(opline->op2.var);
-		}
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	shift_left_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-		/* First, locate the function. */
-		fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
-		if (UNEXPECTED(fbc == NULL)) {
-			if (EXPECTED(!EG(exception))) {
-				zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
-			}
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	USE_OPLINE
 
-			if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
-				zend_objects_store_del(orig_obj);
-			}
-			HANDLE_EXCEPTION();
-		}
-		if (IS_CV == IS_CONST &&
-		    EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) &&
-		    EXPECTED(obj == orig_obj)) {
-			CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
-		}
-		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) {
-			GC_ADDREF(obj); /* For $this pointer */
-			if (GC_DELREF(orig_obj) == 0) {
-				zend_objects_store_del(orig_obj);
-			}
-		}
-		if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
-			init_func_run_time_cache(&fbc->op_array);
-		}
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	shift_right_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
 	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	if (IS_CV != IS_CONST) {
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	int ret;
+	USE_OPLINE
 
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
 	}
-
-	call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS;
-	if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) {
-		if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) {
-			zend_objects_store_del(obj);
-			if (UNEXPECTED(EG(exception))) {
-				HANDLE_EXCEPTION();
-			}
-		}
-		/* call static method */
-		obj = (zend_object*)called_scope;
-		call_info = ZEND_CALL_NESTED_FUNCTION;
-	} else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) {
-		if (IS_CV == IS_CV) {
-			GC_ADDREF(obj); /* For $this pointer */
-		}
-		/* CV may be changed indirectly (e.g. when it's a reference) */
-		call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS;
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	ret = zend_compare(op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
 	}
+	ZEND_VM_SMART_BRANCH(ret == 0, 1);
+}
 
-	call = zend_vm_stack_push_call_frame(call_info,
-		fbc, opline->extended_value, obj);
-	call->prev_execute_data = EX(call);
-	EX(call) = call;
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	int ret;
+	USE_OPLINE
 
-	ZEND_VM_NEXT_OPCODE();
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	ret = zend_compare(op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_SMART_BRANCH(ret != 0, 1);
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
+	int ret;
 	USE_OPLINE
-	zval *expr_ptr, new_expr;
 
 	SAVE_OPLINE();
-	if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
-	    UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
-		expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
-		if (Z_ISREF_P(expr_ptr)) {
-			Z_ADDREF_P(expr_ptr);
-		} else {
-			ZVAL_MAKE_REF_EX(expr_ptr, 2);
-		}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	ret = zend_compare(op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_SMART_BRANCH(ret < 0, 1);
+}
 
-	} else {
-		expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-		if (IS_CV == IS_TMP_VAR) {
-			/* pass */
-		} else if (IS_CV == IS_CONST) {
-			Z_TRY_ADDREF_P(expr_ptr);
-		} else if (IS_CV == IS_CV) {
-			ZVAL_DEREF(expr_ptr);
-			Z_TRY_ADDREF_P(expr_ptr);
-		} else /* if (IS_CV == IS_VAR) */ {
-			if (UNEXPECTED(Z_ISREF_P(expr_ptr))) {
-				zend_refcounted *ref = Z_COUNTED_P(expr_ptr);
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	int ret;
+	USE_OPLINE
 
-				expr_ptr = Z_REFVAL_P(expr_ptr);
-				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-					ZVAL_COPY_VALUE(&new_expr, expr_ptr);
-					expr_ptr = &new_expr;
-					efree_size(ref, sizeof(zend_reference));
-				} else if (Z_OPT_REFCOUNTED_P(expr_ptr)) {
-					Z_ADDREF_P(expr_ptr);
-				}
-			}
-		}
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	ret = zend_compare(op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
 	}
+	ZEND_VM_SMART_BRANCH(ret <= 0, 1);
+}
 
-	if (IS_CV != IS_UNUSED) {
-		zval *offset = EX_VAR(opline->op2.var);
-		zend_string *str;
-		zend_ulong hval;
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	USE_OPLINE
 
-add_again:
-		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
-			str = Z_STR_P(offset);
-			if (IS_CV != IS_CONST) {
-				if (ZEND_HANDLE_NUMERIC(str, hval)) {
-					goto num_index;
-				}
-			}
-str_index:
-			zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr);
-		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
-			hval = Z_LVAL_P(offset);
-num_index:
-			zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr);
-		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
-			offset = Z_REFVAL_P(offset);
-			goto add_again;
-		} else if (Z_TYPE_P(offset) == IS_NULL) {
-			str = ZSTR_EMPTY_ALLOC();
-			goto str_index;
-		} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
-			hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
-			goto num_index;
-		} else if (Z_TYPE_P(offset) == IS_FALSE) {
-			hval = 0;
-			goto num_index;
-		} else if (Z_TYPE_P(offset) == IS_TRUE) {
-			hval = 1;
-			goto num_index;
-		} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
-			zend_use_resource_as_offset(offset);
-			hval = Z_RES_HANDLE_P(offset);
-			goto num_index;
-		} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
-			ZVAL_UNDEFINED_OP2();
-			str = ZSTR_EMPTY_ALLOC();
-			goto str_index;
-		} else {
-			zend_illegal_array_offset_access(offset);
-			zval_ptr_dtor_nogc(expr_ptr);
-		}
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	bitwise_or_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	} else {
-		if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) {
-			zend_cannot_add_element();
-			zval_ptr_dtor_nogc(expr_ptr);
-		}
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
+{
+	USE_OPLINE
+
+	SAVE_OPLINE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	bitwise_and_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
+	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
 	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
-	zval *array;
-	uint32_t size;
 	USE_OPLINE
 
 	SAVE_OPLINE();
-	array = EX_VAR(opline->result.var);
-	if (IS_CV != IS_UNUSED) {
-		size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT;
-		ZVAL_ARR(array, zend_new_array(size));
-		/* Explicitly initialize array as not-packed if flag is set */
-		if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) {
-			zend_hash_real_init_mixed(Z_ARRVAL_P(array));
-		}
-		ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
-	} else {
-		ZVAL_ARR(array, zend_new_array(0));
-		ZEND_VM_NEXT_OPCODE();
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	bitwise_xor_function(EX_VAR(opline->result.var), op_1, op_2);
+	if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_1);
 	}
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1)
 {
 	USE_OPLINE
-	zval *container;
-	zval *offset;
-	zend_ulong hval;
-	zend_string *key;
 
 	SAVE_OPLINE();
-	container = EX_VAR(opline->op1.var);
-	offset = EX_VAR(opline->op2.var);
+	if (UNEXPECTED(Z_TYPE_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	bitwise_not_function(EX_VAR(opline->result.var), op_1);
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
-	do {
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-			HashTable *ht;
+static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type)
+{
+	USE_OPLINE
+	zval *prop;
+	zend_property_info *prop_info;
 
-unset_dim_array:
-			SEPARATE_ARRAY(container);
-			ht = Z_ARRVAL_P(container);
-offset_again:
-			if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
-				key = Z_STR_P(offset);
-				if (IS_CV != IS_CONST) {
-					if (ZEND_HANDLE_NUMERIC(key, hval)) {
-						goto num_index_dim;
-					}
-				}
-str_index_dim:
-				ZEND_ASSERT(ht != &EG(symbol_table));
-				zend_hash_del(ht, key);
-			} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
-				hval = Z_LVAL_P(offset);
-num_index_dim:
-				zend_hash_index_del(ht, hval);
-			} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
-				offset = Z_REFVAL_P(offset);
-				goto offset_again;
-			} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
-				hval = zend_dval_to_lval_safe(Z_DVAL_P(offset));
-				goto num_index_dim;
-			} else if (Z_TYPE_P(offset) == IS_NULL) {
-				key = ZSTR_EMPTY_ALLOC();
-				goto str_index_dim;
-			} else if (Z_TYPE_P(offset) == IS_FALSE) {
-				hval = 0;
-				goto num_index_dim;
-			} else if (Z_TYPE_P(offset) == IS_TRUE) {
-				hval = 1;
-				goto num_index_dim;
-			} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
-				zend_use_resource_as_offset(offset);
-				hval = Z_RES_HANDLE_P(offset);
-				goto num_index_dim;
-			} else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) {
-				ZVAL_UNDEFINED_OP2();
-				key = ZSTR_EMPTY_ALLOC();
-				goto str_index_dim;
-			} else {
-				zend_illegal_array_offset_unset(offset);
-			}
-			break;
-		} else if (Z_ISREF_P(container)) {
-			container = Z_REFVAL_P(container);
-			if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-				goto unset_dim_array;
-			}
-		}
-		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
-			container = ZVAL_UNDEFINED_OP1();
-		}
-		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
-			offset = ZVAL_UNDEFINED_OP2();
-		}
-		if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
-			if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
-				offset++;
-			}
-			Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset);
-		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
-			zend_throw_error(NULL, "Cannot unset string offsets");
-		} else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) {
-			zend_throw_error(NULL, "Cannot unset offset in a non-array variable");
-		} else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
-			zend_false_to_array_deprecated();
-		}
-	} while (0);
+	SAVE_OPLINE();
 
+	prop = zend_fetch_static_property_address(
+		&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
+		type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
+	if (UNEXPECTED(!prop)) {
+		ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS) || (type == BP_VAR_UNSET));
+		prop = &EG(uninitialized_zval);
+	} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
+	 && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
+	 && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) {
+		if (Z_TYPE_P(prop) == IS_OBJECT) {
+			goto copy_deref;
+		} else if (type != BP_VAR_UNSET || Z_TYPE_P(prop) != IS_UNDEF) {
+			zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify");
+		}
+		prop = &EG(uninitialized_zval);
+	}
 
+	if (type == BP_VAR_R || type == BP_VAR_IS) {
+copy_deref:
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), prop);
+	} else {
+		ZVAL_INDIRECT(EX_VAR(opline->result.var), prop);
+	}
 	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
+static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t _arg_num, zval *_arg)
 {
 	USE_OPLINE
-	zval *container;
-	zval *offset;
-	zend_string *name, *tmp_name;
 
 	SAVE_OPLINE();
-	container = EX_VAR(opline->op1.var);
-	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
 
-	do {
-		if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
-			if (Z_ISREF_P(container)) {
-				container = Z_REFVAL_P(container);
-				if (Z_TYPE_P(container) != IS_OBJECT) {
-					if (IS_CV == IS_CV
-					 && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
-						ZVAL_UNDEFINED_OP1();
-					}
-					break;
-				}
-			} else {
-				break;
-			}
-		}
-		if (IS_CV == IS_CONST) {
-			name = Z_STR_P(offset);
-		} else {
-			name = zval_try_get_tmp_string(offset, &tmp_name);
-			if (UNEXPECTED(!name)) {
-				break;
-			}
-		}
-		Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL));
-		if (IS_CV != IS_CONST) {
-			zend_tmp_string_release(tmp_name);
-		}
-	} while (0);
+	zend_cannot_pass_by_reference(_arg_num);
+	FREE_OP(opline->op1_type, opline->op1.var);
+	ZVAL_UNDEF(_arg);
+	HANDLE_EXCEPTION();
+}
 
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1)
+{
+	USE_OPLINE
 
-	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+	SAVE_OPLINE();
+	if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), opline->op1.num, op_1))) {
+		HANDLE_EXCEPTION();
+	}
+
+	ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2)
 {
+	int ret;
 	USE_OPLINE
-	zval *container;
-	bool result;
-	zend_ulong hval;
-	zval *offset;
 
 	SAVE_OPLINE();
-	container = EX_VAR(opline->op1.var);
-	offset = EX_VAR(opline->op2.var);
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_1) == IS_UNDEF)) {
+		op_1 = ZVAL_UNDEFINED_OP1();
+	}
+	if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
+		op_2 = ZVAL_UNDEFINED_OP2();
+	}
+	ret = zend_compare(op_1, op_2);
+	if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+		zval_ptr_dtor_nogc(op_2);
+	}
+	ZEND_VM_SMART_BRANCH(ret == 0, 1);
+}
 
-	if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-		HashTable *ht;
-		zval *value;
-		zend_string *str;
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t try_catch_offset, uint32_t op_num)
+{
+	/* May be NULL during generator closing (only finally blocks are executed) */
+	zend_object *ex = EG(exception);
 
-isset_dim_obj_array:
-		ht = Z_ARRVAL_P(container);
-isset_again:
-		if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
-			str = Z_STR_P(offset);
-			if (IS_CV != IS_CONST) {
-				if (ZEND_HANDLE_NUMERIC(str, hval)) {
-					goto num_index_prop;
-				}
-			}
-			value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST);
-		} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
-			hval = Z_LVAL_P(offset);
-num_index_prop:
-			value = zend_hash_index_find(ht, hval);
-		} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
-			offset = Z_REFVAL_P(offset);
-			goto isset_again;
-		} else {
-			value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
-			if (UNEXPECTED(EG(exception))) {
-				result = 0;
-				goto isset_dim_obj_exit;
+	/* Walk try/catch/finally structures upwards, performing the necessary actions */
+	for (; try_catch_offset != (uint32_t) -1; try_catch_offset--) {
+		zend_try_catch_element *try_catch =
+			&EX(func)->op_array.try_catch_array[try_catch_offset];
+
+		if (op_num < try_catch->catch_op && ex) {
+			/* Go to catch block */
+			cleanup_live_vars(execute_data, op_num, try_catch->catch_op);
+			ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->catch_op], 0);
+
+		} else if (op_num < try_catch->finally_op) {
+			if (ex && zend_is_unwind_exit(ex)) {
+				/* Don't execute finally blocks on exit (for now) */
+				continue;
 			}
-		}
 
-		if (!(opline->extended_value & ZEND_ISEMPTY)) {
-			/* > IS_NULL means not IS_UNDEF and not IS_NULL */
-			result = value != NULL && Z_TYPE_P(value) > IS_NULL &&
-			    (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+			/* Go to finally block */
+			zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[try_catch->finally_end].op1.var);
+			cleanup_live_vars(execute_data, op_num, try_catch->finally_op);
+			Z_OBJ_P(fast_call) = EG(exception);
+			EG(exception) = NULL;
+			Z_OPLINE_NUM_P(fast_call) = (uint32_t)-1;
+			ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->finally_op], 0);
 
-			if (IS_CV & (IS_CONST|IS_CV)) {
-				/* avoid exception check */
+		} else if (op_num < try_catch->finally_end) {
+			zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[try_catch->finally_end].op1.var);
 
-				ZEND_VM_SMART_BRANCH(result, 0);
+			/* cleanup incomplete RETURN statement */
+			if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1
+			 && (EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2_type & (IS_TMP_VAR | IS_VAR))) {
+				zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var);
+
+				zval_ptr_dtor(return_value);
 			}
-		} else {
-			result = (value == NULL || !i_zend_is_true(value));
-		}
-		goto isset_dim_obj_exit;
-	} else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) {
-		container = Z_REFVAL_P(container);
-		if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
-			goto isset_dim_obj_array;
-		}
-	}
 
-	if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
-		offset++;
-	}
-	if (!(opline->extended_value & ZEND_ISEMPTY)) {
-		result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC);
-	} else {
-		result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC);
+			/* Chain potential exception from wrapping finally block */
+			if (Z_OBJ_P(fast_call)) {
+				if (ex) {
+					if (zend_is_unwind_exit(ex) || zend_is_graceful_exit(ex)) {
+						/* discard the previously thrown exception */
+						OBJ_RELEASE(Z_OBJ_P(fast_call));
+					} else {
+						zend_exception_set_previous(ex, Z_OBJ_P(fast_call));
+					}
+				} else {
+					ex = EG(exception) = Z_OBJ_P(fast_call);
+				}
+			}
+		}
 	}
 
-isset_dim_obj_exit:
-
+	/* Uncaught exception */
 
-	ZEND_VM_SMART_BRANCH(result, 1);
+	/* Don't use 0 because it gets replaced by zend_vm_gen.php. */
+	if (zend_observer_fcall_op_array_extension != -1) {
+		zend_observer_fcall_end(execute_data, NULL);
+	}
+	cleanup_live_vars(execute_data, op_num, 0);
+	if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
+		zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+		EG(current_execute_data) = EX(prev_execute_data);
+		zend_generator_close(generator, 1);
+		ZEND_VM_RETURN();
+	} else {
+		/* We didn't execute RETURN, and have to initialize return_value */
+		if (EX(return_value)) {
+			ZVAL_UNDEF(EX(return_value));
+		}
+		ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL);
+	}
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type)
 {
 	USE_OPLINE
-	zval *container;
-	int result;
-	zval *offset;
+	zval *varname;
+	zval *retval;
 	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
 
 	SAVE_OPLINE();
-	container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC);
-	offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+	varname = RT_CONSTANT(opline, opline->op1);
+
+	if (IS_CONST == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
+	} else {
+		if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+
 
-	if (IS_CV == IS_CONST ||
-	    (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
-		if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
-			container = Z_REFVAL_P(container);
-			if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
-				result = (opline->extended_value & ZEND_ISEMPTY);
-				goto isset_object_finish;
 			}
-		} else {
-			result = (opline->extended_value & ZEND_ISEMPTY);
-			goto isset_object_finish;
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
 		}
 	}
 
-	if (IS_CV == IS_CONST) {
-		name = Z_STR_P(offset);
-	} else {
-		name = zval_try_get_tmp_string(offset, &tmp_name);
-		if (UNEXPECTED(!name)) {
-			result = 0;
-			goto isset_object_finish;
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	retval = zend_hash_find_ex(target_symbol_table, name, IS_CONST == IS_CONST);
+	if (retval == NULL) {
+		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+fetch_this:
+			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
+			if (IS_CONST != IS_CONST) {
+				zend_tmp_string_release(tmp_name);
+			}
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		if (type == BP_VAR_W) {
+			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
+		} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+			retval = &EG(uninitialized_zval);
+		} else {
+			if (IS_CONST == IS_CV) {
+				/* Keep name alive in case an error handler tries to free it. */
+				zend_string_addref(name);
+			}
+			zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+				(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+			if (type == BP_VAR_RW && !EG(exception)) {
+				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+			} else {
+				retval = &EG(uninitialized_zval);
+			}
+			if (IS_CONST == IS_CV) {
+				zend_string_release(name);
+			}
+		}
+	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
+	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
+		retval = Z_INDIRECT_P(retval);
+		if (Z_TYPE_P(retval) == IS_UNDEF) {
+			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+				goto fetch_this;
+			}
+			if (type == BP_VAR_W) {
+				ZVAL_NULL(retval);
+			} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+				retval = &EG(uninitialized_zval);
+			} else {
+				zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+					(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+				if (type == BP_VAR_RW && !EG(exception)) {
+					ZVAL_NULL(retval);
+				} else {
+					retval = &EG(uninitialized_zval);
+				}
+			}
 		}
 	}
 
-	result =
-		(opline->extended_value & ZEND_ISEMPTY) ^
-		Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL));
+	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
 
-	if (IS_CV != IS_CONST) {
-		zend_tmp_string_release(tmp_name);
-	}
 
-isset_object_finish:
+	}
 
+	if (IS_CONST != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
 
-	ZEND_VM_SMART_BRANCH(result, 1);
+	ZEND_ASSERT(retval != NULL);
+	if (type == BP_VAR_R || type == BP_VAR_IS) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+	} else {
+		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type)
 {
 	USE_OPLINE
-
-	zval *key, *subject;
-	HashTable *ht;
-	bool result;
+	zval *varname;
+	zval *retval;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
 
 	SAVE_OPLINE();
+	varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 
-	key = EX_VAR(opline->op1.var);
-	subject = EX_VAR(opline->op2.var);
-
-	if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-array_key_exists_array:
-		ht = Z_ARRVAL_P(subject);
-		result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC);
+	if (IS_TMP_VAR == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
 	} else {
-		if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) {
-			subject = Z_REFVAL_P(subject);
-			if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) {
-				goto array_key_exists_array;
+		if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+				zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
 			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
 		}
-		zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC);
-		result = 0;
-	}
-
-
-	ZEND_VM_SMART_BRANCH(result, 1);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-
-	zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
-
-	SAVE_OPLINE();
-	if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
-		ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
 	}
 
-	/* Destroy the previously yielded value */
-	zval_ptr_dtor(&generator->value);
-
-	/* Destroy the previously yielded key */
-	zval_ptr_dtor(&generator->key);
-
-	/* Set the new yielded value */
-	if (IS_CV != IS_UNUSED) {
-		if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
-			/* Constants and temporary variables aren't yieldable by reference,
-			 * but we still allow them with a notice. */
-			if (IS_CV & (IS_CONST|IS_TMP_VAR)) {
-				zval *value;
-
-				zend_error(E_NOTICE, "Only variable references should be yielded by reference");
-
-				value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-				ZVAL_COPY_VALUE(&generator->value, value);
-				if (IS_CV == IS_CONST) {
-					if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
-						Z_ADDREF(generator->value);
-					}
-				}
-			} else {
-				zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
-
-				/* If a function call result is yielded and the function did
-				 * not return by reference we throw a notice. */
-				do {
-					if (IS_CV == IS_VAR) {
-						ZEND_ASSERT(value_ptr != &EG(uninitialized_zval));
-						if (opline->extended_value == ZEND_RETURNS_FUNCTION
-						 && !Z_ISREF_P(value_ptr)) {
-							zend_error(E_NOTICE, "Only variable references should be yielded by reference");
-							ZVAL_COPY(&generator->value, value_ptr);
-							break;
-						}
-					}
-					if (Z_ISREF_P(value_ptr)) {
-						Z_ADDREF_P(value_ptr);
-					} else {
-						ZVAL_MAKE_REF_EX(value_ptr, 2);
-					}
-					ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
-				} while (0);
-
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	retval = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST);
+	if (retval == NULL) {
+		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+fetch_this:
+			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
+			if (IS_TMP_VAR != IS_CONST) {
+				zend_tmp_string_release(tmp_name);
 			}
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		if (type == BP_VAR_W) {
+			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
+		} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+			retval = &EG(uninitialized_zval);
 		} else {
-			zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
-
-			/* Consts, temporary variables and references need copying */
-			if (IS_CV == IS_CONST) {
-				ZVAL_COPY_VALUE(&generator->value, value);
-				if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
-					Z_ADDREF(generator->value);
-				}
-			} else if (IS_CV == IS_TMP_VAR) {
-				ZVAL_COPY_VALUE(&generator->value, value);
-			} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
-				ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
-
+			if (IS_TMP_VAR == IS_CV) {
+				/* Keep name alive in case an error handler tries to free it. */
+				zend_string_addref(name);
+			}
+			zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+				(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+			if (type == BP_VAR_RW && !EG(exception)) {
+				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
 			} else {
-				ZVAL_COPY_VALUE(&generator->value, value);
-				if (IS_CV == IS_CV) {
-					if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+				retval = &EG(uninitialized_zval);
+			}
+			if (IS_TMP_VAR == IS_CV) {
+				zend_string_release(name);
+			}
+		}
+	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
+	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
+		retval = Z_INDIRECT_P(retval);
+		if (Z_TYPE_P(retval) == IS_UNDEF) {
+			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+				goto fetch_this;
+			}
+			if (type == BP_VAR_W) {
+				ZVAL_NULL(retval);
+			} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+				retval = &EG(uninitialized_zval);
+			} else {
+				zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+					(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+				if (type == BP_VAR_RW && !EG(exception)) {
+					ZVAL_NULL(retval);
+				} else {
+					retval = &EG(uninitialized_zval);
 				}
 			}
 		}
-	} else {
-		/* If no value was specified yield null */
-		ZVAL_NULL(&generator->value);
 	}
 
-	/* Set the new yielded key */
-	if (IS_CV != IS_UNUSED) {
-		zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-		if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) {
-			key = Z_REFVAL_P(key);
-		}
-		ZVAL_COPY(&generator->key, key);
+	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
+		zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
+	}
 
-		if (Z_TYPE(generator->key) == IS_LONG
-		    && Z_LVAL(generator->key) > generator->largest_used_integer_key
-		) {
-			generator->largest_used_integer_key = Z_LVAL(generator->key);
-		}
-	} else {
-		/* If no key was specified we use auto-increment keys */
-		generator->largest_used_integer_key++;
-		ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+	if (IS_TMP_VAR != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
 	}
 
-	if (RETURN_VALUE_USED(opline)) {
-		/* If the return value of yield is used set the send
-		 * target and initialize it to NULL */
-		generator->send_target = EX_VAR(opline->result.var);
-		ZVAL_NULL(generator->send_target);
+	ZEND_ASSERT(retval != NULL);
+	if (type == BP_VAR_R || type == BP_VAR_IS) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
 	} else {
-		generator->send_target = NULL;
+		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
 	}
-
-	/* The GOTO VM uses a local opline variable. We need to set the opline
-	 * variable in execute_data so we don't resume at an old position. */
-	SAVE_OPLINE();
-
-	ZEND_VM_RETURN();
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX  zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type)
 {
-	/* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
-	/* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
-	/* (Infinite recursion when comparing arrays is an uncatchable fatal error) */
 	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
+	zval *varname;
+	zval *retval;
+	zend_string *name, *tmp_name;
+	HashTable *target_symbol_table;
 
-	op1 = EX_VAR(opline->op1.var);
-	op2 = EX_VAR(opline->op2.var);
-	result = fast_is_identical_function(op1, op2);
-	/* Free is a no-op for const/cv */
-	ZEND_VM_SMART_BRANCH(result, 0);
-}
+	SAVE_OPLINE();
+	varname = EX_VAR(opline->op1.var);
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
-	zval *op1, *op2;
-	bool result;
+	if (IS_CV == IS_CONST) {
+		name = Z_STR_P(varname);
+	} else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) {
+		name = Z_STR_P(varname);
+		tmp_name = NULL;
+	} else {
+		if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) {
+			ZVAL_UNDEFINED_OP1();
+		}
+		name = zval_try_get_tmp_string(varname, &tmp_name);
+		if (UNEXPECTED(!name)) {
+			if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
 
-	op1 = EX_VAR(opline->op1.var);
-	op2 = EX_VAR(opline->op2.var);
-	result = fast_is_identical_function(op1, op2);
-	/* Free is a no-op for const/cv */
-	ZEND_VM_SMART_BRANCH(!result, 0);
-}
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-	USE_OPLINE
+			}
+			ZVAL_UNDEF(EX_VAR(opline->result.var));
+			HANDLE_EXCEPTION();
+		}
+	}
 
-	SAVE_OPLINE();
-	zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
-	ZEND_VM_NEXT_OPCODE(); /* Never reached */
-}
+	target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC);
+	retval = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST);
+	if (retval == NULL) {
+		if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+fetch_this:
+			zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC);
+			if (IS_CV != IS_CONST) {
+				zend_tmp_string_release(tmp_name);
+			}
+			ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+		}
+		if (type == BP_VAR_W) {
+			retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
+		} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+			retval = &EG(uninitialized_zval);
+		} else {
+			if (IS_CV == IS_CV) {
+				/* Keep name alive in case an error handler tries to free it. */
+				zend_string_addref(name);
+			}
+			zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+				(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+			if (type == BP_VAR_RW && !EG(exception)) {
+				retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+			} else {
+				retval = &EG(uninitialized_zval);
+			}
+			if (IS_CV == IS_CV) {
+				zend_string_release(name);
+			}
+		}
+	/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
+	} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
+		retval = Z_INDIRECT_P(retval);
+		if (Z_TYPE_P(retval) == IS_UNDEF) {
+			if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) {
+				goto fetch_this;
+			}
+			if (type == BP_VAR_W) {
+				ZVAL_NULL(retval);
+			} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
+				retval = &EG(uninitialized_zval);
+			} else {
+				zend_error_unchecked(E_WARNING, "Undefined %svariable $%S",
+					(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name);
+				if (type == BP_VAR_RW && !EG(exception)) {
+					ZVAL_NULL(retval);
+				} else {
+					retval = &EG(uninitialized_zval);
+				}
+			}
+		}
+	}
 
+	if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) {
 
-#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
-# undef ZEND_VM_TAIL_CALL
-# undef ZEND_VM_CONTINUE
-# undef ZEND_VM_RETURN
 
-# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE()
-# define ZEND_VM_CONTINUE()      HYBRID_NEXT()
-# define ZEND_VM_RETURN()        goto HYBRID_HALT_LABEL
-#endif
+	}
+
+	if (IS_CV != IS_CONST) {
+		zend_tmp_string_release(tmp_name);
+	}
+
+	ZEND_ASSERT(retval != NULL);
+	if (type == BP_VAR_R || type == BP_VAR_IS) {
+		ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
+	} else {
+		ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
+	}
+	ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
 
+#pragma pop_macro("ZEND_VM_INTERRUPT")
+#pragma pop_macro("ZEND_VM_CONTINUE")
+#endif /* ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL */
 
 #if (ZEND_VM_KIND != ZEND_VM_KIND_CALL) && (ZEND_GCC_VERSION >= 4000) && !defined(__clang__)
 # pragma GCC push_options
 # pragma GCC optimize("no-gcse")
 # pragma GCC optimize("no-ivopts")
 #endif
-#ifdef _WIN64
+#if defined(_WIN64) && defined(_M_X64)
 /* See save_xmm_x86_64_ms_masm.asm */
 void execute_ex_real(zend_execute_data *ex)
 #else
@@ -55162,7 +108737,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 
 #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
 	if (UNEXPECTED(execute_data == NULL)) {
-		static const void * const labels[] = {
+		static zend_vm_opcode_handler_t const labels[] = {
 			(void*)&&ZEND_NOP_SPEC_LABEL,
 			(void*)&&ZEND_ADD_SPEC_CONST_CONST_LABEL,
 			(void*)&&ZEND_ADD_SPEC_CONST_TMPVARCV_LABEL,
@@ -55240,28 +108815,28 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_LABEL,
 			(void*)&&ZEND_DIV_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_DIV_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_DIV_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_DIV_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_DIV_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_DIV_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_DIV_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_DIV_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_DIV_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_DIV_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_DIV_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_DIV_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_DIV_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_DIV_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_MOD_SPEC_CONST_CONST_LABEL,
@@ -55340,28 +108915,28 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_SR_SPEC_TMPVARCV_TMPVARCV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_CONCAT_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CONCAT_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_CONCAT_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_CONCAT_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_CONCAT_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CONCAT_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_CONCAT_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_CONCAT_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CONCAT_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_BW_OR_SPEC_CONST_CONST_LABEL,
@@ -55440,28 +109015,28 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_LABEL,
 			(void*)&&ZEND_POW_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_POW_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_POW_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_POW_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_POW_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_POW_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_POW_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_POW_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_POW_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_POW_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_POW_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_POW_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_POW_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_POW_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_BW_NOT_SPEC_CONST_LABEL,
@@ -55470,8 +109045,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_BW_NOT_SPEC_TMPVARCV_LABEL,
 			(void*)&&ZEND_BOOL_NOT_SPEC_CONST_LABEL,
-			(void*)&&ZEND_BOOL_NOT_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_BOOL_NOT_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_BOOL_NOT_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_BOOL_NOT_SPEC_CV_LABEL,
 			(void*)&&ZEND_BOOL_XOR_SPEC_CONST_CONST_LABEL,
@@ -55479,14 +109054,14 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_BOOL_XOR_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_BOOL_XOR_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -55495,8 +109070,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_BOOL_XOR_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_BOOL_XOR_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_BOOL_XOR_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_BOOL_XOR_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_IS_IDENTICAL_SPEC_CONST_CONST_LABEL,
@@ -55509,9 +109084,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_TMP_LABEL,
-			(void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -55521,7 +109096,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_IS_IDENTICAL_SPEC_CV_CONST_LABEL,
 			(void*)&&ZEND_IS_IDENTICAL_SPEC_CV_TMP_LABEL,
-			(void*)&&ZEND_IS_IDENTICAL_SPEC_CV_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_IS_IDENTICAL_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_LABEL,
@@ -55534,9 +109109,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_LABEL,
-			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -55546,7 +109121,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_LABEL,
 			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_LABEL,
-			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_IS_EQUAL_SPEC_CONST_CONST_LABEL,
@@ -55564,30 +109139,30 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -55612,12 +109187,12 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_IS_EQUAL_SPEC_CV_CONST_LABEL,
 			(void*)&&ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_LABEL,
 			(void*)&&ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_LABEL,
+			(void*)&&ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -55639,30 +109214,30 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -55687,12 +109262,12 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_LABEL,
 			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_LABEL,
 			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL,
-			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_LABEL,
+			(void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -55873,8 +109448,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_LABEL,
 			(void*)&&ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_LABEL,
 			(void*)&&ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_LABEL,
-			(void*)&&ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_LABEL,
-			(void*)&&ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_LABEL,
@@ -55893,8 +109468,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_LABEL,
 			(void*)&&ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_LABEL,
 			(void*)&&ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_LABEL,
-			(void*)&&ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_LABEL,
-			(void*)&&ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_LABEL,
@@ -55951,27 +109526,27 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56001,27 +109576,27 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56076,19 +109651,19 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56096,24 +109671,24 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56121,24 +109696,24 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56146,12 +109721,12 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_LABEL,
 			(void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_LABEL,
-			(void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56165,8 +109740,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OP_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OP_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OP_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56175,8 +109750,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OP_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OP_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OP_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56190,8 +109765,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56200,8 +109775,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56215,18 +109790,18 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_ASSIGN_STATIC_PROP_OP_SPEC_LABEL,
@@ -56317,14 +109892,14 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56342,14 +109917,14 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56367,14 +109942,14 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56420,30 +109995,30 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_POST_INC_STATIC_PROP_SPEC_LABEL,
 			(void*)&&ZEND_JMP_SPEC_LABEL,
 			(void*)&&ZEND_JMPZ_SPEC_CONST_LABEL,
-			(void*)&&ZEND_JMPZ_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_JMPZ_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_JMPZ_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_JMPZ_SPEC_CV_LABEL,
 			(void*)&&ZEND_JMPNZ_SPEC_CONST_LABEL,
-			(void*)&&ZEND_JMPNZ_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_JMPNZ_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_JMPNZ_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_JMPNZ_SPEC_CV_LABEL,
 			(void*)&&ZEND_JMPZ_EX_SPEC_CONST_LABEL,
-			(void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_JMPZ_EX_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_JMPZ_EX_SPEC_CV_LABEL,
 			(void*)&&ZEND_JMPNZ_EX_SPEC_CONST_LABEL,
-			(void*)&&ZEND_JMPNZ_EX_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_JMPNZ_EX_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_JMPNZ_EX_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_JMPNZ_EX_SPEC_CV_LABEL,
-			(void*)&&ZEND_CASE_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_CASE_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_CASE_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_CASE_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_CASE_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_CASE_SPEC_TMPVAR_CV_LABEL,
+			(void*)&&ZEND_CASE_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_CHECK_VAR_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_LABEL,
 			(void*)&&ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_LABEL,
@@ -56457,52 +110032,52 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CAST_SPEC_CONST_LABEL,
 			(void*)&&ZEND_CAST_SPEC_TMP_LABEL,
-			(void*)&&ZEND_CAST_SPEC_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CAST_SPEC_CV_LABEL,
 			(void*)&&ZEND_BOOL_SPEC_CONST_LABEL,
-			(void*)&&ZEND_BOOL_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_BOOL_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_BOOL_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_BOOL_SPEC_CV_LABEL,
 			(void*)&&ZEND_FAST_CONCAT_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FAST_CONCAT_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FAST_CONCAT_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FAST_CONCAT_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_FAST_CONCAT_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_FAST_CONCAT_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FAST_CONCAT_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FAST_CONCAT_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FAST_CONCAT_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_ROPE_ADD_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_LABEL,
-			(void*)&&ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_LABEL,
+			(void*)&&ZEND_ROPE_ADD_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ROPE_ADD_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_ROPE_END_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_ROPE_END_SPEC_TMP_TMPVAR_LABEL,
-			(void*)&&ZEND_ROPE_END_SPEC_TMP_TMPVAR_LABEL,
+			(void*)&&ZEND_ROPE_END_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ROPE_END_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_BEGIN_SILENCE_SPEC_LABEL,
@@ -56517,8 +110092,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_RETURN_SPEC_OBSERVER_LABEL,
 			(void*)&&ZEND_RETURN_SPEC_TMP_LABEL,
 			(void*)&&ZEND_RETURN_SPEC_OBSERVER_LABEL,
-			(void*)&&ZEND_RETURN_SPEC_VAR_LABEL,
-			(void*)&&ZEND_RETURN_SPEC_OBSERVER_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_RETURN_SPEC_CV_LABEL,
@@ -56633,43 +110208,43 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_LABEL,
 			(void*)&&ZEND_FREE_SPEC_TMPVAR_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_ARRAY_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_ARRAY_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_ARRAY_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_ARRAY_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_LABEL,
+			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56678,18 +110253,18 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_CONST_LABEL,
 			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL,
-			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL,
-			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_TMP_LABEL,
 			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_CV_LABEL,
 			(void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL,
 			(void*)&&ZEND_UNSET_VAR_SPEC_CONST_UNUSED_LABEL,
@@ -56708,8 +110283,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_DIM_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_UNSET_DIM_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_DIM_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56718,8 +110293,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_DIM_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_UNSET_DIM_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_UNSET_DIM_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_UNSET_DIM_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_DIM_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56733,44 +110308,44 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_OBJ_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_UNSET_OBJ_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_OBJ_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_UNSET_OBJ_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_UNSET_OBJ_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_UNSET_OBJ_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FE_RESET_R_SPEC_CONST_LABEL,
 			(void*)&&ZEND_FE_RESET_R_SPEC_TMP_LABEL,
-			(void*)&&ZEND_FE_RESET_R_SPEC_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FE_RESET_R_SPEC_CV_LABEL,
-			(void*)&&ZEND_FE_FETCH_R_SPEC_VAR_LABEL,
+			(void*)&&ZEND_FE_FETCH_R_SPEC_TMP_LABEL,
 			(void*)&&ZEND_FETCH_R_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_FETCH_R_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_R_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56779,38 +110354,38 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_R_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_R_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_W_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_FETCH_W_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_W_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56824,8 +110399,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56834,8 +110409,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_W_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_W_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_W_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56849,23 +110424,23 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_RW_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_FETCH_RW_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_RW_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56879,8 +110454,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56889,8 +110464,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56904,38 +110479,38 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_IS_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_FETCH_IS_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_IS_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56944,53 +110519,53 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -56999,38 +110574,38 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_UNSET_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57044,8 +110619,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57054,8 +110629,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57069,33 +110644,33 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57104,8 +110679,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_LABEL,
 			(void*)&&ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_LABEL,
@@ -57130,19 +110705,23 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CATCH_SPEC_CONST_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_CATCH_SPEC_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_THROW_SPEC_CONST_LABEL,
-			(void*)&&ZEND_THROW_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_THROW_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_THROW_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_THROW_SPEC_CV_LABEL,
 			(void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_CLONE_SPEC_CONST_LABEL,
-			(void*)&&ZEND_CLONE_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_CLONE_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_CLONE_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CLONE_SPEC_UNUSED_LABEL,
 			(void*)&&ZEND_CLONE_SPEC_CV_LABEL,
 			(void*)&&ZEND_RETURN_BY_REF_SPEC_CONST_LABEL,
@@ -57156,33 +110735,33 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_RETURN_BY_REF_SPEC_CV_LABEL,
 			(void*)&&ZEND_RETURN_BY_REF_SPEC_OBSERVER_LABEL,
 			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57191,13 +110770,13 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_LABEL,
 			(void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57206,33 +110785,33 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_SEND_VAL_EX_SPEC_CONST_CONST_LABEL,
@@ -57311,25 +110890,25 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_SEND_VAR_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_SEND_ARRAY_SPEC_LABEL,
 			(void*)&&ZEND_SEND_USER_SPEC_CONST_LABEL,
 			(void*)&&ZEND_SEND_USER_SPEC_TMP_LABEL,
-			(void*)&&ZEND_SEND_USER_SPEC_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_SEND_USER_SPEC_CV_LABEL,
 			(void*)&&ZEND_STRLEN_SPEC_CONST_LABEL,
-			(void*)&&ZEND_STRLEN_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_STRLEN_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_STRLEN_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_STRLEN_SPEC_CV_LABEL,
 			(void*)&&ZEND_DEFINED_SPEC_CONST_LABEL,
 			(void*)&&ZEND_TYPE_CHECK_SPEC_CONST_LABEL,
-			(void*)&&ZEND_TYPE_CHECK_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_TYPE_CHECK_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_TYPE_CHECK_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_TYPE_CHECK_SPEC_CV_LABEL,
 			(void*)&&ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_LABEL,
@@ -57345,8 +110924,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_FE_FETCH_RW_SPEC_VAR_LABEL,
 			(void*)&&ZEND_FE_FREE_SPEC_TMPVAR_LABEL,
 			(void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_LABEL,
-			(void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_CV_LABEL,
 			(void*)&&ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_LABEL,
@@ -57372,18 +110951,18 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57397,23 +110976,23 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_POST_INC_OBJ_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_POST_INC_OBJ_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_POST_INC_OBJ_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_ECHO_SPEC_CONST_LABEL,
-			(void*)&&ZEND_ECHO_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_ECHO_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_ECHO_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ECHO_SPEC_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57422,15 +111001,15 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_LABEL,
+			(void*)&&ZEND_INSTANCEOF_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_INSTANCEOF_SPEC_TMP_VAR_LABEL,
+			(void*)&&ZEND_INSTANCEOF_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_LABEL,
-			(void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_LABEL,
-			(void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
@@ -57456,28 +111035,28 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_DECLARE_ANON_CLASS_SPEC_LABEL,
 			(void*)&&ZEND_ADD_ARRAY_UNPACK_SPEC_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_HANDLE_EXCEPTION_SPEC_LABEL,
@@ -57485,49 +111064,49 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_ASSERT_CHECK_SPEC_LABEL,
 			(void*)&&ZEND_JMP_SET_SPEC_CONST_LABEL,
 			(void*)&&ZEND_JMP_SET_SPEC_TMP_LABEL,
-			(void*)&&ZEND_JMP_SET_SPEC_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_JMP_SET_SPEC_CV_LABEL,
 			(void*)&&ZEND_UNSET_CV_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_LABEL,
 			(void*)&&ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_LABEL,
 			(void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_SEPARATE_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_FETCH_CLASS_NAME_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_LABEL,
 			(void*)&&ZEND_FETCH_CLASS_NAME_SPEC_CV_LABEL,
 			(void*)&&ZEND_CALL_TRAMPOLINE_SPEC_LABEL,
 			(void*)&&ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_LABEL,
 			(void*)&&ZEND_DISCARD_EXCEPTION_SPEC_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_YIELD_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_CONST_CV_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_TMP_TMPVAR_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_TMP_TMPVAR_LABEL,
+			(void*)&&ZEND_YIELD_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_TMP_UNUSED_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_VAR_TMPVAR_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_VAR_TMPVAR_LABEL,
+			(void*)&&ZEND_YIELD_SPEC_VAR_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_VAR_UNUSED_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_VAR_CV_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_UNUSED_CONST_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_UNUSED_TMPVAR_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_UNUSED_TMPVAR_LABEL,
+			(void*)&&ZEND_YIELD_SPEC_UNUSED_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_UNUSED_UNUSED_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_UNUSED_CV_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_YIELD_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_YIELD_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_YIELD_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_GENERATOR_RETURN_SPEC_CONST_LABEL,
@@ -57545,40 +111124,40 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_RECV_VARIADIC_SPEC_UNUSED_LABEL,
 			(void*)&&ZEND_SEND_UNPACK_SPEC_LABEL,
 			(void*)&&ZEND_YIELD_FROM_SPEC_CONST_LABEL,
-			(void*)&&ZEND_YIELD_FROM_SPEC_TMPVAR_LABEL,
-			(void*)&&ZEND_YIELD_FROM_SPEC_TMPVAR_LABEL,
+			(void*)&&ZEND_YIELD_FROM_SPEC_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_YIELD_FROM_SPEC_CV_LABEL,
 			(void*)&&ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_LABEL,
 			(void*)&&ZEND_BIND_GLOBAL_SPEC_CV_CONST_LABEL,
 			(void*)&&ZEND_COALESCE_SPEC_CONST_LABEL,
 			(void*)&&ZEND_COALESCE_SPEC_TMP_LABEL,
-			(void*)&&ZEND_COALESCE_SPEC_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_COALESCE_SPEC_CV_LABEL,
 			(void*)&&ZEND_SPACESHIP_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_SPACESHIP_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_SPACESHIP_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_SPACESHIP_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_SPACESHIP_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_SPACESHIP_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_SPACESHIP_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_SPACESHIP_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_SPACESHIP_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_SPACESHIP_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_LABEL,
@@ -57641,48 +111220,48 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_LABEL,
 			(void*)&&ZEND_IN_ARRAY_SPEC_CONST_CONST_LABEL,
 			(void*)&&ZEND_IN_ARRAY_SPEC_TMP_CONST_LABEL,
-			(void*)&&ZEND_IN_ARRAY_SPEC_VAR_CONST_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_IN_ARRAY_SPEC_CV_CONST_LABEL,
 			(void*)&&ZEND_COUNT_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_COUNT_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_COUNT_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_COUNT_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_COUNT_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_GET_CLASS_SPEC_CONST_UNUSED_LABEL,
-			(void*)&&ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_GET_CLASS_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_LABEL,
 			(void*)&&ZEND_GET_CLASS_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_LABEL,
 			(void*)&&ZEND_GET_TYPE_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_GET_TYPE_SPEC_TMP_UNUSED_LABEL,
-			(void*)&&ZEND_GET_TYPE_SPEC_VAR_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_GET_TYPE_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_LABEL,
+			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL,
+			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_LABEL,
+			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_LABEL,
-			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_LABEL,
+			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_LABEL,
 			(void*)&&ZEND_MATCH_SPEC_CONST_CONST_LABEL,
@@ -57690,31 +111269,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_MATCH_SPEC_TMPVARCV_CONST_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_MATCH_SPEC_TMPVARCV_CONST_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_CASE_STRICT_SPEC_TMP_CONST_LABEL,
 			(void*)&&ZEND_CASE_STRICT_SPEC_TMP_TMP_LABEL,
-			(void*)&&ZEND_CASE_STRICT_SPEC_TMP_VAR_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_CASE_STRICT_SPEC_TMP_CV_LABEL,
-			(void*)&&ZEND_CASE_STRICT_SPEC_VAR_CONST_LABEL,
-			(void*)&&ZEND_CASE_STRICT_SPEC_VAR_TMP_LABEL,
-			(void*)&&ZEND_CASE_STRICT_SPEC_VAR_VAR_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_CASE_STRICT_SPEC_VAR_CV_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_CASE_STRICT_SPEC_TMP_CV_LABEL,
 			(void*)&&ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL,
 			(void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL,
@@ -57722,7 +111281,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL,
 			(void*)&&ZEND_JMP_NULL_SPEC_CONST_LABEL,
 			(void*)&&ZEND_JMP_NULL_SPEC_TMP_LABEL,
-			(void*)&&ZEND_JMP_NULL_SPEC_VAR_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_JMP_NULL_SPEC_CV_LABEL,
 			(void*)&&ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_LABEL,
@@ -57741,11 +111300,22 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_JMP_FRAMELESS_SPEC_CONST_LABEL,
 			(void*)&&ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_LABEL,
 			(void*)&&ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_LABEL,
+			(void*)&&ZEND_TYPE_ASSERT_SPEC_CONST_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
+			(void*)&&ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_INIT_FCALL_OFFSET_SPEC_CONST_LABEL,
 			(void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
-			(void*)&&ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_LABEL,
-			(void*)&&ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_LABEL,
+			(void*)&&ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_LABEL,
+			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_NULL_LABEL,
 			(void*)&&ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_LABEL,
 			(void*)&&ZEND_JMP_FORWARD_SPEC_LABEL,
@@ -58658,8 +112228,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 			(void*)&&ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_LABEL,
 			(void*)&&ZEND_NULL_LABEL
 		};
-		zend_opcode_handlers = (const void **) labels;
-		zend_handlers_count = sizeof(labels) / sizeof(void*);
+		zend_opcode_handlers = (zend_vm_opcode_handler_t*) labels;
+		zend_handlers_count = sizeof(labels) / sizeof(labels[0]);
 		memset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));
 		hybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;
 #ifdef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE
@@ -58690,10 +112260,10 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 		HYBRID_SWITCH() {
 #else /* ZEND_VM_KIND != ZEND_VM_KIND_HYBRID */
 #if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)
-		((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+		(OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 		if (UNEXPECTED(!OPLINE)) {
 #else
-		opline = ((opcode_handler_t)opline->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+		opline = (opline->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 		if (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT))) {
 #endif
 #endif /* ZEND_VM_KIND != ZEND_VM_KIND_HYBRID */
@@ -58753,11 +112323,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR)
-				ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV)
 				ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -58772,7 +112337,10 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 {
 	zend_execute_data *old_execute_data;
 	uint32_t call_info = EX_CALL_INFO();
+#if ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL
+	/* zend_leave_helper may be called with opline=call_leave_op in TAILCALL VM */
 	SAVE_OPLINE();
+#endif
 
 	if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) == 0)) {
 		EG(current_execute_data) = EX(prev_execute_data);
@@ -59147,10 +112715,10 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_RECV_INIT_SPEC_CONST)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR):
-				VM_TRACE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR)
-				ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR)
+			HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP):
+				VM_TRACE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP)
+				ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_RECV_SPEC_UNUSED):
 				VM_TRACE(ZEND_RECV_SPEC_UNUSED)
@@ -59219,9 +112787,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 	zval *retval_ptr;
 	zval *return_value;
 
+
 	retval_ptr = RT_CONSTANT(opline, opline->op1);
 	return_value = EX(return_value);
 
+
 	if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
 		SAVE_OPLINE();
 		retval_ptr = ZVAL_UNDEFINED_OP1();
@@ -59287,6 +112857,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 
 
 
+
+
+
 	goto zend_leave_helper_SPEC_LABEL;
 }
 
@@ -59486,6 +113059,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_TYPE_CHECK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_TYPE_CHECK_SPEC_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_TYPE_ASSERT_SPEC_CONST):
+				VM_TRACE(ZEND_TYPE_ASSERT_SPEC_CONST)
+				ZEND_TYPE_ASSERT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_TYPE_ASSERT_SPEC_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_DEFINED_SPEC_CONST):
 				VM_TRACE(ZEND_DEFINED_SPEC_CONST)
 				ZEND_DEFINED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -59891,110 +113469,110 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_DIV_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_DIV_SPEC_CONST_TMPVAR)
-				ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_DIV_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POW_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_POW_SPEC_CONST_TMPVAR)
-				ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POW_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_CONCAT_SPEC_CONST_TMPVAR)
-				ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_SPACESHIP_SPEC_CONST_TMPVAR)
-				ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR)
-				ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR)
-				ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR)
-				ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR)
-				ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR)
-				ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR)
-				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR)
-				ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR)
-				ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR)
-				ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR)
-				ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR)
-				ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR)
-				ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR)
-				ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR)
-				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR)
-				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR)
-				ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_YIELD_SPEC_CONST_TMPVAR):
-				VM_TRACE(ZEND_YIELD_SPEC_CONST_TMPVAR)
-				ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_YIELD_SPEC_CONST_TMPVAR)
+			HYBRID_CASE(ZEND_DIV_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_DIV_SPEC_CONST_TMP)
+				ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_DIV_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POW_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_POW_SPEC_CONST_TMP)
+				ZEND_POW_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POW_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_CONCAT_SPEC_CONST_TMP)
+				ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_SPACESHIP_SPEC_CONST_TMP)
+				ZEND_SPACESHIP_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CONST_TMP)
+				ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMP)
+				ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP)
+				ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP)
+				ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP)
+				ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP)
+				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FETCH_LIST_R_SPEC_CONST_TMP)
+				ZEND_FETCH_LIST_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_FAST_CONCAT_SPEC_CONST_TMP)
+				ZEND_FAST_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP)
+				ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP)
+				ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_USER_CALL_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_INIT_USER_CALL_SPEC_CONST_TMP)
+				ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_USER_CALL_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP)
+				ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_INIT_ARRAY_SPEC_CONST_TMP)
+				ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP)
+				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP)
+				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP)
+				ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_YIELD_SPEC_CONST_TMP):
+				VM_TRACE(ZEND_YIELD_SPEC_CONST_TMP)
+				ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_YIELD_SPEC_CONST_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_R_SPEC_CONST_UNUSED):
 				VM_TRACE(ZEND_FETCH_R_SPEC_CONST_UNUSED)
@@ -60771,10 +114349,10 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR)
-				ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR)
+			HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP):
+				VM_TRACE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP)
+				ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED):
 				VM_TRACE(ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED)
@@ -60786,36 +114364,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_BOOL_NOT_SPEC_TMPVAR):
-				VM_TRACE(ZEND_BOOL_NOT_SPEC_TMPVAR)
-				ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_BOOL_NOT_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ECHO_SPEC_TMPVAR):
-				VM_TRACE(ZEND_ECHO_SPEC_TMPVAR)
-				ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ECHO_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_JMPZ_SPEC_TMPVAR):
-				VM_TRACE(ZEND_JMPZ_SPEC_TMPVAR)
-				ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_JMPZ_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_JMPNZ_SPEC_TMPVAR):
-				VM_TRACE(ZEND_JMPNZ_SPEC_TMPVAR)
-				ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_JMPNZ_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMPVAR):
-				VM_TRACE(ZEND_JMPZ_EX_SPEC_TMPVAR)
-				ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_JMPZ_EX_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_JMPNZ_EX_SPEC_TMPVAR):
-				VM_TRACE(ZEND_JMPNZ_EX_SPEC_TMPVAR)
-				ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_JMPNZ_EX_SPEC_TMPVAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FREE_SPEC_TMPVAR):
 				VM_TRACE(ZEND_FREE_SPEC_TMPVAR)
 				ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -60826,101 +114374,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FE_FREE_SPEC_TMPVAR)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_THROW_SPEC_TMPVAR):
-				VM_TRACE(ZEND_THROW_SPEC_TMPVAR)
-				ZEND_THROW_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_THROW_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_BOOL_SPEC_TMPVAR):
-				VM_TRACE(ZEND_BOOL_SPEC_TMPVAR)
-				ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_BOOL_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CLONE_SPEC_TMPVAR):
-				VM_TRACE(ZEND_CLONE_SPEC_TMPVAR)
-				ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CLONE_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR):
-				VM_TRACE(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR)
-				ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_YIELD_FROM_SPEC_TMPVAR):
-				VM_TRACE(ZEND_YIELD_FROM_SPEC_TMPVAR)
-				ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_YIELD_FROM_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_STRLEN_SPEC_TMPVAR):
-				VM_TRACE(ZEND_STRLEN_SPEC_TMPVAR)
-				ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_STRLEN_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_TYPE_CHECK_SPEC_TMPVAR):
-				VM_TRACE(ZEND_TYPE_CHECK_SPEC_TMPVAR)
-				ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_TYPE_CHECK_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR):
-				VM_TRACE(ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR)
-				ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_DIV_SPEC_TMPVAR_CONST)
-				ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_DIV_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_POW_SPEC_TMPVAR_CONST)
-				ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POW_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_CONCAT_SPEC_TMPVAR_CONST)
-				ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST)
-				ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ)
-				ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ)
-				ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST)
-				ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ)
-				ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ)
-				ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_SPACESHIP_SPEC_TMPVAR_CONST)
-				ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST)
-				ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST):
 				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST)
 				ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -60941,46 +114394,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST)
-				ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST)
-				ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_SEND_VAL_SPEC_TMPVAR_CONST):
 				VM_TRACE(ZEND_SEND_VAL_SPEC_TMPVAR_CONST)
 				ZEND_SEND_VAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_SEND_VAL_SPEC_TMPVAR_CONST)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_CASE_SPEC_TMPVAR_CONST)
-				ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST)
-				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST)
-				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST)
-				ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST):
-				VM_TRACE(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST)
-				ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST):
 				VM_TRACE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST)
 				ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -60991,145 +114409,25 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_DIV_SPEC_TMPVAR_TMPVAR)
-				ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_DIV_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_POW_SPEC_TMPVAR_TMPVAR)
-				ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POW_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR)
-				ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR)
-				ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ)
-				ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ)
-				ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR)
-				ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ)
-				ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ)
-				ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR)
-				ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR)
-				ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR)
-				ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR)
-				ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR)
-				ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR)
-				ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR)
-				ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR)
-				ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_CASE_SPEC_TMPVAR_TMPVAR)
-				ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR)
-				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR)
-				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR):
-				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR)
-				ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR):
-				VM_TRACE(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR)
-				ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED)
-				ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED)
-				ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED)
-				ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED)
-				ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED)
-				ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED)
-				ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED)
+			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP)
+				ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP)
+				ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP)
+				ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP)
+				ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED):
 				VM_TRACE(ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED)
@@ -61141,56 +114439,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED)
-				ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED)
-				ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_COUNT_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_COUNT_SPEC_TMPVAR_UNUSED)
-				ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_COUNT_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED)
-				ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED):
-				VM_TRACE(ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED)
-				ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED):
 				VM_TRACE(ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED)
 				ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_DIV_SPEC_TMPVAR_CV)
-				ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_DIV_SPEC_TMPVAR_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_POW_SPEC_TMPVAR_CV)
-				ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POW_SPEC_TMPVAR_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_CONCAT_SPEC_TMPVAR_CV)
-				ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMPVAR_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_SPACESHIP_SPEC_TMPVAR_CV)
-				ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMPVAR_CV)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV):
 				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV)
 				ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61211,35 +114464,35 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV)
-				ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV)
+			HYBRID_CASE(ZEND_BOOL_NOT_SPEC_TMP):
+				VM_TRACE(ZEND_BOOL_NOT_SPEC_TMP)
+				ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_BOOL_NOT_SPEC_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV)
-				ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV)
+			HYBRID_CASE(ZEND_ECHO_SPEC_TMP):
+				VM_TRACE(ZEND_ECHO_SPEC_TMP)
+				ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ECHO_SPEC_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_CASE_SPEC_TMPVAR_CV)
-				ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_SPEC_TMPVAR_CV)
+			HYBRID_CASE(ZEND_JMPZ_SPEC_TMP):
+				VM_TRACE(ZEND_JMPZ_SPEC_TMP)
+				ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_JMPZ_SPEC_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV)
-				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV)
+			HYBRID_CASE(ZEND_JMPNZ_SPEC_TMP):
+				VM_TRACE(ZEND_JMPNZ_SPEC_TMP)
+				ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_JMPNZ_SPEC_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV)
-				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV)
+			HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMP):
+				VM_TRACE(ZEND_JMPZ_EX_SPEC_TMP)
+				ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_JMPZ_EX_SPEC_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV):
-				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV)
-				ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV)
+			HYBRID_CASE(ZEND_JMPNZ_EX_SPEC_TMP):
+				VM_TRACE(ZEND_JMPNZ_EX_SPEC_TMP)
+				ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_JMPNZ_EX_SPEC_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_RETURN_SPEC_TMP):
 				VM_TRACE(ZEND_RETURN_SPEC_TMP)
@@ -61248,9 +114501,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 	zval *retval_ptr;
 	zval *return_value;
 
+
 	retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
 	return_value = EX(return_value);
 
+
 	if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
 		SAVE_OPLINE();
 		retval_ptr = ZVAL_UNDEFINED_OP1();
@@ -61316,6 +114571,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 
 
 
+
+
+
 	goto zend_leave_helper_SPEC_LABEL;
 }
 
@@ -61330,16 +114588,36 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_GENERATOR_RETURN_SPEC_TMP)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_THROW_SPEC_TMP):
+				VM_TRACE(ZEND_THROW_SPEC_TMP)
+				ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_THROW_SPEC_TMP)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_SEND_USER_SPEC_TMP):
 				VM_TRACE(ZEND_SEND_USER_SPEC_TMP)
 				ZEND_SEND_USER_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_SEND_USER_SPEC_TMP)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_BOOL_SPEC_TMP):
+				VM_TRACE(ZEND_BOOL_SPEC_TMP)
+				ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_BOOL_SPEC_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CLONE_SPEC_TMP):
+				VM_TRACE(ZEND_CLONE_SPEC_TMP)
+				ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CLONE_SPEC_TMP)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_CAST_SPEC_TMP):
 				VM_TRACE(ZEND_CAST_SPEC_TMP)
 				ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_CAST_SPEC_TMP)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INCLUDE_OR_EVAL_SPEC_TMP):
+				VM_TRACE(ZEND_INCLUDE_OR_EVAL_SPEC_TMP)
+				ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INCLUDE_OR_EVAL_SPEC_TMP)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FE_RESET_R_SPEC_TMP):
 				VM_TRACE(ZEND_FE_RESET_R_SPEC_TMP)
 				ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61350,6 +114628,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FE_RESET_RW_SPEC_TMP)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FE_FETCH_R_SPEC_TMP):
+				VM_TRACE(ZEND_FE_FETCH_R_SPEC_TMP)
+				ZEND_FE_FETCH_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FE_FETCH_R_SPEC_TMP)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_END_SILENCE_SPEC_TMP):
 				VM_TRACE(ZEND_END_SILENCE_SPEC_TMP)
 				ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61375,6 +114658,41 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_QM_ASSIGN_SPEC_TMP)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_YIELD_FROM_SPEC_TMP):
+				VM_TRACE(ZEND_YIELD_FROM_SPEC_TMP)
+				ZEND_YIELD_FROM_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_YIELD_FROM_SPEC_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_STRLEN_SPEC_TMP):
+				VM_TRACE(ZEND_STRLEN_SPEC_TMP)
+				ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_STRLEN_SPEC_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_TYPE_CHECK_SPEC_TMP):
+				VM_TRACE(ZEND_TYPE_CHECK_SPEC_TMP)
+				ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_TYPE_CHECK_SPEC_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_CLASS_NAME_SPEC_TMP):
+				VM_TRACE(ZEND_FETCH_CLASS_NAME_SPEC_TMP)
+				ZEND_FETCH_CLASS_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_CLASS_NAME_SPEC_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_DIV_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_DIV_SPEC_TMP_CONST)
+				ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_DIV_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POW_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_POW_SPEC_TMP_CONST)
+				ZEND_POW_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POW_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CONCAT_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_CONCAT_SPEC_TMP_CONST)
+				ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMP_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_CONST):
 				VM_TRACE(ZEND_IS_IDENTICAL_SPEC_TMP_CONST)
 				ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61390,6 +114708,46 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_CONST)
+				ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ)
+				ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ)
+				ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST)
+				ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ)
+				ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ)
+				ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_SPACESHIP_SPEC_TMP_CONST)
+				ZEND_SPACESHIP_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_BOOL_XOR_SPEC_TMP_CONST)
+				ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMP_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST):
 				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST)
 				ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61400,6 +114758,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMP_CONST)
+				ZEND_FAST_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMP_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_CONST):
 				VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_CONST)
 				ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61410,11 +114773,21 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST)
+				ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_SEND_VAL_EX_SPEC_TMP_CONST):
 				VM_TRACE(ZEND_SEND_VAL_EX_SPEC_TMP_CONST)
 				ZEND_SEND_VAL_EX_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_SEND_VAL_EX_SPEC_TMP_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CASE_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_CASE_SPEC_TMP_CONST)
+				ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CASE_SPEC_TMP_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST):
 				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST)
 				ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61425,6 +114798,26 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_CONST)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST)
+				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST)
+				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST)
+				ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMP_CONST):
+				VM_TRACE(ZEND_INSTANCEOF_SPEC_TMP_CONST)
+				ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMP_CONST)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_YIELD_SPEC_TMP_CONST):
 				VM_TRACE(ZEND_YIELD_SPEC_TMP_CONST)
 				ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61435,40 +114828,20 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_IN_ARRAY_SPEC_TMP_CONST)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR)
-				ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR)
-				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR):
-				VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR)
-				ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ROPE_END_SPEC_TMP_TMPVAR):
-				VM_TRACE(ZEND_ROPE_END_SPEC_TMP_TMPVAR)
-				ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR):
-				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR)
-				ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR):
-				VM_TRACE(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR)
-				ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_YIELD_SPEC_TMP_TMPVAR):
-				VM_TRACE(ZEND_YIELD_SPEC_TMP_TMPVAR)
-				ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_YIELD_SPEC_TMP_TMPVAR)
+			HYBRID_CASE(ZEND_DIV_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_DIV_SPEC_TMP_TMP)
+				ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_DIV_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POW_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_POW_SPEC_TMP_TMP)
+				ZEND_POW_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POW_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CONCAT_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_CONCAT_SPEC_TMP_TMP)
+				ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMP_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_TMP):
 				VM_TRACE(ZEND_IS_IDENTICAL_SPEC_TMP_TMP)
@@ -61485,10 +114858,145 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_STRICT_SPEC_TMP_VAR):
-				VM_TRACE(ZEND_CASE_STRICT_SPEC_TMP_VAR)
-				ZEND_CASE_STRICT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_TMP_VAR)
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_TMP)
+				ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ)
+				ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ)
+				ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP)
+				ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ)
+				ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ)
+				ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_SPACESHIP_SPEC_TMP_TMP)
+				ZEND_SPACESHIP_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_BOOL_XOR_SPEC_TMP_TMP)
+				ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP)
+				ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP)
+				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMP_TMP)
+				ZEND_FAST_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_TMP)
+				ZEND_ROPE_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ROPE_ADD_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ROPE_END_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_ROPE_END_SPEC_TMP_TMP)
+				ZEND_ROPE_END_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP)
+				ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CASE_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_CASE_SPEC_TMP_TMP)
+				ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CASE_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP)
+				ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_INIT_ARRAY_SPEC_TMP_TMP)
+				ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP)
+				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP)
+				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP)
+				ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_YIELD_SPEC_TMP_TMP):
+				VM_TRACE(ZEND_YIELD_SPEC_TMP_TMP)
+				ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_YIELD_SPEC_TMP_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMP_VAR):
+				VM_TRACE(ZEND_INSTANCEOF_SPEC_TMP_VAR)
+				ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMP_VAR)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_R_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_FETCH_R_SPEC_TMP_UNUSED)
+				ZEND_FETCH_R_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_R_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_W_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_FETCH_W_SPEC_TMP_UNUSED)
+				ZEND_FETCH_W_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_W_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_RW_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_FETCH_RW_SPEC_TMP_UNUSED)
+				ZEND_FETCH_RW_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_RW_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED)
+				ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_UNSET_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_FETCH_UNSET_SPEC_TMP_UNUSED)
+				ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_UNSET_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_IS_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_FETCH_IS_SPEC_TMP_UNUSED)
+				ZEND_FETCH_IS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_IS_SPEC_TMP_UNUSED)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED):
 				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED)
@@ -61520,21 +115028,76 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_UNUSED)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED)
+				ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_INSTANCEOF_SPEC_TMP_UNUSED)
+				ZEND_INSTANCEOF_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_YIELD_SPEC_TMP_UNUSED):
 				VM_TRACE(ZEND_YIELD_SPEC_TMP_UNUSED)
 				ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_YIELD_SPEC_TMP_UNUSED)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED)
+				ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED)
+				ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_COUNT_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_COUNT_SPEC_TMP_UNUSED)
+				ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_COUNT_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED)
+				ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_GET_CLASS_SPEC_TMP_UNUSED):
+				VM_TRACE(ZEND_GET_CLASS_SPEC_TMP_UNUSED)
+				ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_GET_CLASS_SPEC_TMP_UNUSED)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_GET_TYPE_SPEC_TMP_UNUSED):
 				VM_TRACE(ZEND_GET_TYPE_SPEC_TMP_UNUSED)
 				ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_GET_TYPE_SPEC_TMP_UNUSED)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_DIV_SPEC_TMP_CV):
+				VM_TRACE(ZEND_DIV_SPEC_TMP_CV)
+				ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_DIV_SPEC_TMP_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POW_SPEC_TMP_CV):
+				VM_TRACE(ZEND_POW_SPEC_TMP_CV)
+				ZEND_POW_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POW_SPEC_TMP_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CONCAT_SPEC_TMP_CV):
+				VM_TRACE(ZEND_CONCAT_SPEC_TMP_CV)
+				ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMP_CV)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_CASE_STRICT_SPEC_TMP_CV):
 				VM_TRACE(ZEND_CASE_STRICT_SPEC_TMP_CV)
 				ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_TMP_CV)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMP_CV):
+				VM_TRACE(ZEND_SPACESHIP_SPEC_TMP_CV)
+				ZEND_SPACESHIP_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMP_CV)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV):
 				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV)
 				ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61545,6 +115108,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMP_CV):
+				VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMP_CV)
+				ZEND_FAST_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMP_CV)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_CV):
 				VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_CV)
 				ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61555,6 +115123,16 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_CV)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CV):
+				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CV)
+				ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMP_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CASE_SPEC_TMP_CV):
+				VM_TRACE(ZEND_CASE_SPEC_TMP_CV)
+				ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CASE_SPEC_TMP_CV)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV):
 				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV)
 				ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61565,6 +115143,21 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_CV)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV)
+				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV)
+				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV):
+				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV)
+				ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_YIELD_SPEC_TMP_CV):
 				VM_TRACE(ZEND_YIELD_SPEC_TMP_CV)
 				ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61605,85 +115198,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_POST_DEC_SPEC_VAR)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_RETURN_SPEC_VAR):
-				VM_TRACE(ZEND_RETURN_SPEC_VAR)
-{
-	USE_OPLINE
-	zval *retval_ptr;
-	zval *return_value;
-
-	retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
-	return_value = EX(return_value);
-
-	if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
-		SAVE_OPLINE();
-		retval_ptr = ZVAL_UNDEFINED_OP1();
-		if (return_value) {
-			ZVAL_NULL(return_value);
-		}
-	} else if (!return_value) {
-		if (IS_VAR & (IS_VAR|IS_TMP_VAR)) {
-			if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) {
-				SAVE_OPLINE();
-				rc_dtor_func(Z_COUNTED_P(retval_ptr));
-			}
-		}
-	} else {
-		if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
-			ZVAL_COPY_VALUE(return_value, retval_ptr);
-			if (IS_VAR == IS_CONST) {
-				if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) {
-					Z_ADDREF_P(return_value);
-				}
-			}
-		} else if (IS_VAR == IS_CV) {
-			do {
-				if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-					if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) {
-						if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) {
-							zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
-							ZVAL_COPY_VALUE(return_value, retval_ptr);
-							if (GC_MAY_LEAK(ref)) {
-								SAVE_OPLINE();
-								gc_possible_root(ref);
-							}
-							ZVAL_NULL(retval_ptr);
-							break;
-						} else {
-							Z_ADDREF_P(retval_ptr);
-						}
-					} else {
-						retval_ptr = Z_REFVAL_P(retval_ptr);
-						if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-							Z_ADDREF_P(retval_ptr);
-						}
-					}
-				}
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-			} while (0);
-		} else /* if (IS_VAR == IS_VAR) */ {
-			if (UNEXPECTED(Z_ISREF_P(retval_ptr))) {
-				zend_refcounted *ref = Z_COUNTED_P(retval_ptr);
-
-				retval_ptr = Z_REFVAL_P(retval_ptr);
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-				if (UNEXPECTED(GC_DELREF(ref) == 0)) {
-					efree_size(ref, sizeof(zend_reference));
-				} else if (Z_OPT_REFCOUNTED_P(retval_ptr)) {
-					Z_ADDREF_P(retval_ptr);
-				}
-			} else {
-				ZVAL_COPY_VALUE(return_value, retval_ptr);
-			}
-		}
-	}
-
-
-
-	goto zend_leave_helper_SPEC_LABEL;
-}
-
-				VM_TRACE_OP_END(ZEND_RETURN_SPEC_VAR)
 			HYBRID_CASE(ZEND_RETURN_BY_REF_SPEC_VAR):
 				VM_TRACE(ZEND_RETURN_BY_REF_SPEC_VAR)
 				ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61694,51 +115208,16 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_GENERATOR_RETURN_SPEC_VAR)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_SEND_USER_SPEC_VAR):
-				VM_TRACE(ZEND_SEND_USER_SPEC_VAR)
-				ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_SEND_USER_SPEC_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CAST_SPEC_VAR):
-				VM_TRACE(ZEND_CAST_SPEC_VAR)
-				ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CAST_SPEC_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FE_RESET_R_SPEC_VAR):
-				VM_TRACE(ZEND_FE_RESET_R_SPEC_VAR)
-				ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FE_RESET_R_SPEC_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FE_RESET_RW_SPEC_VAR):
 				VM_TRACE(ZEND_FE_RESET_RW_SPEC_VAR)
 				ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FE_RESET_RW_SPEC_VAR)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FE_FETCH_R_SPEC_VAR):
-				VM_TRACE(ZEND_FE_FETCH_R_SPEC_VAR)
-				ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FE_FETCH_R_SPEC_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FE_FETCH_RW_SPEC_VAR):
 				VM_TRACE(ZEND_FE_FETCH_RW_SPEC_VAR)
 				ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FE_FETCH_RW_SPEC_VAR)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_JMP_SET_SPEC_VAR):
-				VM_TRACE(ZEND_JMP_SET_SPEC_VAR)
-				ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_JMP_SET_SPEC_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_COALESCE_SPEC_VAR):
-				VM_TRACE(ZEND_COALESCE_SPEC_VAR)
-				ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_COALESCE_SPEC_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_JMP_NULL_SPEC_VAR):
-				VM_TRACE(ZEND_JMP_NULL_SPEC_VAR)
-				ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_JMP_NULL_SPEC_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_VAR):
 				VM_TRACE(ZEND_QM_ASSIGN_SPEC_VAR)
 				ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61749,21 +115228,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_SEND_VAR_SIMPLE_SPEC_VAR)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_CONST):
-				VM_TRACE(ZEND_IS_IDENTICAL_SPEC_VAR_CONST)
-				ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_VAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_CONST):
-				VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_CONST)
-				ZEND_CASE_STRICT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST):
-				VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST)
-				ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST):
 				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST)
 				ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61844,11 +115308,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV)
 				ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61864,11 +115323,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV)
 				ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -61959,180 +115413,110 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_YIELD_SPEC_VAR_CONST)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IN_ARRAY_SPEC_VAR_CONST):
-				VM_TRACE(ZEND_IN_ARRAY_SPEC_VAR_CONST)
-				ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IN_ARRAY_SPEC_VAR_CONST)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV):
 				VM_TRACE(ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV)
 				ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR)
-				ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR)
-				ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR)
-				ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR)
-				ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR)
-				ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR)
-				ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST)
-				ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP)
-				ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST)
-				ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP)
-				ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR)
-				ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR)
-				ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR)
-				ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR)
-				ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR)
-				ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_YIELD_SPEC_VAR_TMPVAR):
-				VM_TRACE(ZEND_YIELD_SPEC_VAR_TMPVAR)
-				ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_YIELD_SPEC_VAR_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_TMP):
-				VM_TRACE(ZEND_IS_IDENTICAL_SPEC_VAR_TMP)
-				ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_VAR_TMP)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_TMP):
-				VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_TMP)
-				ZEND_CASE_STRICT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_TMP)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP):
-				VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP)
-				ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP)
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP)
+				ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP)
+				ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_ASSIGN_OP_SPEC_VAR_TMP)
+				ZEND_ASSIGN_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMP)
+				ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_POST_INC_OBJ_SPEC_VAR_TMP)
+				ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_W_SPEC_VAR_TMP)
+				ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMP)
+				ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP)
+				ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP)
+				ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP)
+				ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP)
+				ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP)
+				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP)
+				ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_FETCH_LIST_W_SPEC_VAR_TMP)
+				ZEND_FETCH_LIST_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_LIST_W_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST)
+				ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP)
+				ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST):
+				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST)
+				ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP):
+				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP)
+				ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED):
 				VM_TRACE(ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED)
@@ -62144,30 +115528,45 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_VAR):
-				VM_TRACE(ZEND_IS_IDENTICAL_SPEC_VAR_VAR)
-				ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_VAR_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_VAR):
-				VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_VAR)
-				ZEND_CASE_STRICT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR):
-				VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR)
-				ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED):
-				VM_TRACE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED)
-				ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED):
-				VM_TRACE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED)
-				ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED)
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR):
+				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR)
+				ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP)
+				ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP)
+				ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_INIT_ARRAY_SPEC_VAR_TMP)
+				ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_UNSET_DIM_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_UNSET_DIM_SPEC_VAR_TMP)
+				ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_UNSET_OBJ_SPEC_VAR_TMP)
+				ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_VAR_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_YIELD_SPEC_VAR_TMP):
+				VM_TRACE(ZEND_YIELD_SPEC_VAR_TMP)
+				ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_YIELD_SPEC_VAR_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_REF_SPEC_VAR_VAR):
 				VM_TRACE(ZEND_ASSIGN_REF_SPEC_VAR_VAR)
@@ -62204,11 +115603,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV)
 				ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -62294,21 +115688,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_MAKE_REF_SPEC_VAR_UNUSED)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_GET_TYPE_SPEC_VAR_UNUSED):
-				VM_TRACE(ZEND_GET_TYPE_SPEC_VAR_UNUSED)
-				ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_GET_TYPE_SPEC_VAR_UNUSED)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED):
 				VM_TRACE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED)
 				ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_CV):
-				VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_CV)
-				ZEND_CASE_STRICT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_CV)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV):
 				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV)
 				ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -62389,11 +115773,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV)
 				ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -62409,11 +115788,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV)
 				ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -62484,6 +115858,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CATCH_SPEC_UNUSED):
+				VM_TRACE(ZEND_CATCH_SPEC_UNUSED)
+				ZEND_CATCH_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CATCH_SPEC_UNUSED)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_CLONE_SPEC_UNUSED):
 				VM_TRACE(ZEND_CLONE_SPEC_UNUSED)
 				ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -62549,11 +115928,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV)
 				ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -62629,120 +116003,115 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR)
-				ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR)
-				ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR)
-				ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR)
-				ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR)
-				ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR)
-				ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR)
-				ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR)
-				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR)
-				ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST)
-				ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP)
-				ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR)
-				ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR)
-				ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR)
-				ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR)
-				ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR)
-				ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR)
-				ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR)
-				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_TMPVAR):
-				VM_TRACE(ZEND_YIELD_SPEC_UNUSED_TMPVAR)
-				ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_YIELD_SPEC_UNUSED_TMPVAR)
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP)
+				ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP)
+				ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP)
+				ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP)
+				ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP)
+				ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP)
+				ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP)
+				ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP)
+				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP)
+				ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST)
+				ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP)
+				ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR):
+				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR)
+				ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ROPE_INIT_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_ROPE_INIT_SPEC_UNUSED_TMP)
+				ZEND_ROPE_INIT_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ROPE_INIT_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMP)
+				ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_CLASS_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP)
+				ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP)
+				ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMP)
+				ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMP)
+				ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP)
+				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_TMP):
+				VM_TRACE(ZEND_YIELD_SPEC_UNUSED_TMP)
+				ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_YIELD_SPEC_UNUSED_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED):
 				VM_TRACE(ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED)
@@ -62794,6 +116163,16 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_YIELD_SPEC_UNUSED_UNUSED)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED):
+				VM_TRACE(ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED)
+				ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED):
+				VM_TRACE(ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED)
+				ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED):
 				VM_TRACE(ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED)
 				ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -62899,11 +116278,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV)
 				ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -63026,9 +116400,11 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 	zval *retval_ptr;
 	zval *return_value;
 
+
 	retval_ptr = EX_VAR(opline->op1.var);
 	return_value = EX(return_value);
 
+
 	if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
 		SAVE_OPLINE();
 		retval_ptr = ZVAL_UNDEFINED_OP1();
@@ -63094,6 +116470,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 
 
 
+
+
+
 	goto zend_leave_helper_SPEC_LABEL;
 }
 
@@ -63423,11 +116802,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV)
 				ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -63443,11 +116817,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV)
 				ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -63573,245 +116942,20 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_DIV_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_DIV_SPEC_CV_TMPVAR)
-				ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_DIV_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POW_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_POW_SPEC_CV_TMPVAR)
-				ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POW_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_CONCAT_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_CONCAT_SPEC_CV_TMPVAR)
-				ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR)
-				ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ)
-				ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ):
-				VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ)
-				ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR)
-				ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ)
-				ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ):
-				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ)
-				ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_SPACESHIP_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_SPACESHIP_SPEC_CV_TMPVAR)
-				ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_BOOL_XOR_SPEC_CV_TMPVAR)
-				ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR)
-				ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR)
-				ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_ASSIGN_OP_SPEC_CV_TMPVAR)
-				ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR)
-				ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR)
-				ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR)
-				ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR)
-				ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR)
-				ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR)
-				ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR)
-				ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR)
-				ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR)
-				ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR)
-				ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR)
-				ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR)
-				ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR)
-				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR)
-				ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST)
-				ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP)
-				ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST)
-				ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP)
-				ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV):
-				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV)
-				ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR)
-				ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR)
-				ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR)
-				ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR)
-				ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_UNSET_DIM_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_UNSET_DIM_SPEC_CV_TMPVAR)
-				ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR)
-				ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR)
-				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR)
-				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR)
-				ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_YIELD_SPEC_CV_TMPVAR):
-				VM_TRACE(ZEND_YIELD_SPEC_CV_TMPVAR)
-				ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_YIELD_SPEC_CV_TMPVAR)
+			HYBRID_CASE(ZEND_DIV_SPEC_CV_TMP):
+				VM_TRACE(ZEND_DIV_SPEC_CV_TMP)
+				ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_DIV_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POW_SPEC_CV_TMP):
+				VM_TRACE(ZEND_POW_SPEC_CV_TMP)
+				ZEND_POW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POW_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_CONCAT_SPEC_CV_TMP):
+				VM_TRACE(ZEND_CONCAT_SPEC_CV_TMP)
+				ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CV_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CV_TMP):
 				VM_TRACE(ZEND_IS_IDENTICAL_SPEC_CV_TMP)
@@ -63823,6 +116967,161 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP)
 				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMP):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMP)
+				ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ)
+				ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ):
+				VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ)
+				ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP)
+				ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ)
+				ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ):
+				VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ)
+				ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_SPACESHIP_SPEC_CV_TMP):
+				VM_TRACE(ZEND_SPACESHIP_SPEC_CV_TMP)
+				ZEND_SPACESHIP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CV_TMP):
+				VM_TRACE(ZEND_BOOL_XOR_SPEC_CV_TMP)
+				ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP):
+				VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP)
+				ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP):
+				VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP)
+				ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_CV_TMP):
+				VM_TRACE(ZEND_ASSIGN_OP_SPEC_CV_TMP)
+				ZEND_ASSIGN_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_CV_TMP):
+				VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_CV_TMP)
+				ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_CV_TMP):
+				VM_TRACE(ZEND_POST_INC_OBJ_SPEC_CV_TMP)
+				ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CV_TMP)
+				ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_W_SPEC_CV_TMP)
+				ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_CV_TMP)
+				ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CV_TMP)
+				ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP)
+				ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP)
+				ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CV_TMP)
+				ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_CV_TMP)
+				ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMP)
+				ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMP)
+				ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP)
+				ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP)
+				ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST)
+				ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP)
+				ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST):
+				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST)
+				ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP):
+				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP)
+				ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV)
+				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED):
 				VM_TRACE(ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED)
 				ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -63833,25 +117132,65 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CV_VAR):
-				VM_TRACE(ZEND_IS_IDENTICAL_SPEC_CV_VAR)
-				ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_CV_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR):
-				VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR)
-				ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED):
-				VM_TRACE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED)
-				ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED)
-				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED):
-				VM_TRACE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED)
-				ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED)
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR):
+				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR)
+				ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV):
+				VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV)
+				ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CV_TMP):
+				VM_TRACE(ZEND_FAST_CONCAT_SPEC_CV_TMP)
+				ZEND_FAST_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMP):
+				VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMP)
+				ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP):
+				VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP)
+				ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CV_TMP):
+				VM_TRACE(ZEND_INIT_ARRAY_SPEC_CV_TMP)
+				ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_UNSET_DIM_SPEC_CV_TMP):
+				VM_TRACE(ZEND_UNSET_DIM_SPEC_CV_TMP)
+				ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_CV_TMP):
+				VM_TRACE(ZEND_UNSET_OBJ_SPEC_CV_TMP)
+				ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP)
+				ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP):
+				VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP)
+				ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP):
+				VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP)
+				ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP)
+				HYBRID_BREAK();
+			HYBRID_CASE(ZEND_YIELD_SPEC_CV_TMP):
+				VM_TRACE(ZEND_YIELD_SPEC_CV_TMP)
+				ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+				VM_TRACE_OP_END(ZEND_YIELD_SPEC_CV_TMP)
 				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_REF_SPEC_CV_VAR):
 				VM_TRACE(ZEND_ASSIGN_REF_SPEC_CV_VAR)
@@ -63923,11 +117262,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV)
 				ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -64198,11 +117532,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR)
-				ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV)
 				ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -64218,11 +117547,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
 				ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP)
 				HYBRID_BREAK();
-			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR):
-				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR)
-				ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-				VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR)
-				HYBRID_BREAK();
 			HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV):
 				VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV)
 				ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -64390,7 +117714,7 @@ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value)
 
 void zend_vm_init(void)
 {
-	static const void * const labels[] = {
+	static zend_vm_opcode_handler_func_t const funcs[] = {
 		ZEND_NOP_SPEC_HANDLER,
 		ZEND_ADD_SPEC_CONST_CONST_HANDLER,
 		ZEND_ADD_SPEC_CONST_TMPVARCV_HANDLER,
@@ -64468,28 +117792,28 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_HANDLER,
 		ZEND_DIV_SPEC_CONST_CONST_HANDLER,
-		ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_DIV_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_DIV_SPEC_CONST_CV_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_DIV_SPEC_TMP_CONST_HANDLER,
+		ZEND_DIV_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_DIV_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_DIV_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_DIV_SPEC_CV_CONST_HANDLER,
-		ZEND_DIV_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_DIV_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_DIV_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_DIV_SPEC_CV_CV_HANDLER,
 		ZEND_MOD_SPEC_CONST_CONST_HANDLER,
@@ -64568,28 +117892,28 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_CONCAT_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_CONCAT_SPEC_CONST_CV_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_CONCAT_SPEC_TMP_CONST_HANDLER,
+		ZEND_CONCAT_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_CONCAT_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_CONCAT_SPEC_CV_CONST_HANDLER,
-		ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_CONCAT_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_CONCAT_SPEC_CV_CV_HANDLER,
 		ZEND_BW_OR_SPEC_CONST_CONST_HANDLER,
@@ -64668,28 +117992,28 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_HANDLER,
 		ZEND_POW_SPEC_CONST_CONST_HANDLER,
-		ZEND_POW_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_POW_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_POW_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_POW_SPEC_CONST_CV_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_POW_SPEC_TMP_CONST_HANDLER,
+		ZEND_POW_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_POW_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_POW_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_POW_SPEC_CV_CONST_HANDLER,
-		ZEND_POW_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_POW_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_POW_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_POW_SPEC_CV_CV_HANDLER,
 		ZEND_BW_NOT_SPEC_CONST_HANDLER,
@@ -64698,8 +118022,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_BW_NOT_SPEC_TMPVARCV_HANDLER,
 		ZEND_BOOL_NOT_SPEC_CONST_HANDLER,
-		ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER,
-		ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER,
+		ZEND_BOOL_NOT_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_BOOL_NOT_SPEC_CV_HANDLER,
 		ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER,
@@ -64707,14 +118031,14 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER,
+		ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -64723,8 +118047,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER,
-		ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER,
 		ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER,
@@ -64737,9 +118061,9 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER,
-		ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER,
-		ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -64749,7 +118073,7 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER,
 		ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER,
-		ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER,
 		ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER,
@@ -64762,9 +118086,9 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER,
-		ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER,
-		ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -64774,7 +118098,7 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER,
 		ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER,
-		ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER,
 		ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER,
@@ -64792,30 +118116,30 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -64840,12 +118164,12 @@ void zend_vm_init(void)
 		ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER,
 		ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER,
 		ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -64867,30 +118191,30 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -64915,12 +118239,12 @@ void zend_vm_init(void)
 		ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER,
 		ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER,
 		ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER,
-		ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65101,8 +118425,8 @@ void zend_vm_init(void)
 		ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_HANDLER,
 		ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER,
 		ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER,
-		ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER,
-		ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER,
@@ -65121,8 +118445,8 @@ void zend_vm_init(void)
 		ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER,
 		ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER,
 		ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER,
-		ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER,
-		ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER,
@@ -65179,27 +118503,27 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65229,27 +118553,27 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65302,46 +118626,46 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65349,24 +118673,24 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65374,12 +118698,12 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER,
 		ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_HANDLER,
 		ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_HANDLER,
-		ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65393,8 +118717,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDLER,
-		ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65403,8 +118727,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLER,
-		ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65418,8 +118742,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_HANDLER,
-		ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65428,8 +118752,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HANDLER,
-		ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_HANDLER,
 		ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65443,18 +118767,18 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER,
 		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_HANDLER,
 		ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HANDLER,
-		ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER,
 		ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HANDLER,
@@ -65545,14 +118869,14 @@ void zend_vm_init(void)
 		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65570,14 +118894,14 @@ void zend_vm_init(void)
 		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65595,14 +118919,14 @@ void zend_vm_init(void)
 		ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65648,30 +118972,30 @@ void zend_vm_init(void)
 		ZEND_POST_INC_STATIC_PROP_SPEC_HANDLER,
 		ZEND_JMP_SPEC_HANDLER,
 		ZEND_JMPZ_SPEC_CONST_HANDLER,
-		ZEND_JMPZ_SPEC_TMPVAR_HANDLER,
-		ZEND_JMPZ_SPEC_TMPVAR_HANDLER,
+		ZEND_JMPZ_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_JMPZ_SPEC_CV_HANDLER,
 		ZEND_JMPNZ_SPEC_CONST_HANDLER,
-		ZEND_JMPNZ_SPEC_TMPVAR_HANDLER,
-		ZEND_JMPNZ_SPEC_TMPVAR_HANDLER,
+		ZEND_JMPNZ_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_JMPNZ_SPEC_CV_HANDLER,
 		ZEND_JMPZ_EX_SPEC_CONST_HANDLER,
-		ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER,
-		ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER,
+		ZEND_JMPZ_EX_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_JMPZ_EX_SPEC_CV_HANDLER,
 		ZEND_JMPNZ_EX_SPEC_CONST_HANDLER,
-		ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER,
-		ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER,
+		ZEND_JMPNZ_EX_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_JMPNZ_EX_SPEC_CV_HANDLER,
-		ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_CASE_SPEC_TMP_CONST_HANDLER,
+		ZEND_CASE_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_CASE_SPEC_TMPVAR_CV_HANDLER,
+		ZEND_CASE_SPEC_TMP_CV_HANDLER,
 		ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER,
 		ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER,
 		ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER,
@@ -65685,52 +119009,52 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_CAST_SPEC_CONST_HANDLER,
 		ZEND_CAST_SPEC_TMP_HANDLER,
-		ZEND_CAST_SPEC_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_CAST_SPEC_CV_HANDLER,
 		ZEND_BOOL_SPEC_CONST_HANDLER,
-		ZEND_BOOL_SPEC_TMPVAR_HANDLER,
-		ZEND_BOOL_SPEC_TMPVAR_HANDLER,
+		ZEND_BOOL_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_BOOL_SPEC_CV_HANDLER,
 		ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_TMP_CONST_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER,
 		ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_ROPE_INIT_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDLER,
 		ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER,
-		ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER,
-		ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER,
+		ZEND_ROPE_ADD_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER,
 		ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER,
-		ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER,
-		ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER,
+		ZEND_ROPE_END_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ROPE_END_SPEC_TMP_CV_HANDLER,
 		ZEND_BEGIN_SILENCE_SPEC_HANDLER,
@@ -65745,8 +119069,8 @@ void zend_vm_init(void)
 		ZEND_RETURN_SPEC_OBSERVER_HANDLER,
 		ZEND_RETURN_SPEC_TMP_HANDLER,
 		ZEND_RETURN_SPEC_OBSERVER_HANDLER,
-		ZEND_RETURN_SPEC_VAR_HANDLER,
-		ZEND_RETURN_SPEC_OBSERVER_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_RETURN_SPEC_CV_HANDLER,
@@ -65861,43 +119185,43 @@ void zend_vm_init(void)
 		ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
 		ZEND_FREE_SPEC_TMPVAR_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER,
 		ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65906,18 +119230,18 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER,
 		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER,
 		ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER,
 		ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER,
-		ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER,
-		ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER,
-		ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER,
+		ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER,
 		ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER,
 		ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER,
 		ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER,
@@ -65936,8 +119260,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER,
-		ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65946,8 +119270,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER,
-		ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -65961,44 +119285,44 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER,
-		ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER,
 		ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER,
 		ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER,
-		ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER,
 		ZEND_FE_RESET_R_SPEC_CONST_HANDLER,
 		ZEND_FE_RESET_R_SPEC_TMP_HANDLER,
-		ZEND_FE_RESET_R_SPEC_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FE_RESET_R_SPEC_CV_HANDLER,
-		ZEND_FE_FETCH_R_SPEC_VAR_HANDLER,
+		ZEND_FE_FETCH_R_SPEC_TMP_HANDLER,
 		ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_FETCH_R_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66007,38 +119331,38 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_W_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_FETCH_W_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66052,8 +119376,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66062,8 +119386,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66077,23 +119401,23 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER,
 		ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_RW_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_FETCH_RW_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66107,8 +119431,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66117,8 +119441,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66132,38 +119456,38 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER,
 		ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_IS_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_FETCH_IS_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66172,53 +119496,53 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66227,38 +119551,38 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER,
 		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66272,8 +119596,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66282,8 +119606,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66297,33 +119621,33 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER,
 		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER,
 		ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER,
-		ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66332,8 +119656,8 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER,
-		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER,
 		ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER,
@@ -66358,19 +119682,23 @@ void zend_vm_init(void)
 		ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_CATCH_SPEC_CONST_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_CATCH_SPEC_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_THROW_SPEC_CONST_HANDLER,
-		ZEND_THROW_SPEC_TMPVAR_HANDLER,
-		ZEND_THROW_SPEC_TMPVAR_HANDLER,
+		ZEND_THROW_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_THROW_SPEC_CV_HANDLER,
 		ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER,
 		ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER,
 		ZEND_CLONE_SPEC_CONST_HANDLER,
-		ZEND_CLONE_SPEC_TMPVAR_HANDLER,
-		ZEND_CLONE_SPEC_TMPVAR_HANDLER,
+		ZEND_CLONE_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_CLONE_SPEC_UNUSED_HANDLER,
 		ZEND_CLONE_SPEC_CV_HANDLER,
 		ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER,
@@ -66384,33 +119712,33 @@ void zend_vm_init(void)
 		ZEND_RETURN_BY_REF_SPEC_CV_HANDLER,
 		ZEND_RETURN_BY_REF_SPEC_OBSERVER_HANDLER,
 		ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER,
 		ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER,
-		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66419,13 +119747,13 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER,
-		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER,
 		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66434,33 +119762,33 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER,
 		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER,
 		ZEND_SEND_VAL_EX_SPEC_CONST_CONST_HANDLER,
@@ -66539,25 +119867,25 @@ void zend_vm_init(void)
 		ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER,
-		ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER,
 		ZEND_SEND_ARRAY_SPEC_HANDLER,
 		ZEND_SEND_USER_SPEC_CONST_HANDLER,
 		ZEND_SEND_USER_SPEC_TMP_HANDLER,
-		ZEND_SEND_USER_SPEC_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_SEND_USER_SPEC_CV_HANDLER,
 		ZEND_STRLEN_SPEC_CONST_HANDLER,
-		ZEND_STRLEN_SPEC_TMPVAR_HANDLER,
-		ZEND_STRLEN_SPEC_TMPVAR_HANDLER,
+		ZEND_STRLEN_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_STRLEN_SPEC_CV_HANDLER,
 		ZEND_DEFINED_SPEC_CONST_HANDLER,
 		ZEND_TYPE_CHECK_SPEC_CONST_HANDLER,
-		ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER,
-		ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER,
+		ZEND_TYPE_CHECK_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_TYPE_CHECK_SPEC_CV_HANDLER,
 		ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER,
@@ -66573,8 +119901,8 @@ void zend_vm_init(void)
 		ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER,
 		ZEND_FE_FREE_SPEC_TMPVAR_HANDLER,
 		ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER,
-		ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
-		ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
+		ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
 		ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER,
@@ -66600,18 +119928,18 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER,
-		ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER,
 		ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER,
 		ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER,
-		ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66625,23 +119953,23 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER,
-		ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER,
 		ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER,
 		ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER,
-		ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER,
 		ZEND_ECHO_SPEC_CONST_HANDLER,
-		ZEND_ECHO_SPEC_TMPVAR_HANDLER,
-		ZEND_ECHO_SPEC_TMPVAR_HANDLER,
+		ZEND_ECHO_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ECHO_SPEC_CV_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66650,15 +119978,15 @@ void zend_vm_init(void)
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER,
+		ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER,
+		ZEND_INSTANCEOF_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER,
-		ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER,
-		ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
@@ -66684,28 +120012,28 @@ void zend_vm_init(void)
 		ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER,
 		ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER,
 		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER,
 		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER,
 		ZEND_HANDLE_EXCEPTION_SPEC_HANDLER,
@@ -66713,49 +120041,49 @@ void zend_vm_init(void)
 		ZEND_ASSERT_CHECK_SPEC_HANDLER,
 		ZEND_JMP_SET_SPEC_CONST_HANDLER,
 		ZEND_JMP_SET_SPEC_TMP_HANDLER,
-		ZEND_JMP_SET_SPEC_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_JMP_SET_SPEC_CV_HANDLER,
 		ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER,
 		ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_HANDLER,
 		ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_HANDLER,
 		ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER,
-		ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_FETCH_LIST_W_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER,
 		ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER,
-		ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER,
+		ZEND_FETCH_CLASS_NAME_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_HANDLER,
 		ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDLER,
 		ZEND_CALL_TRAMPOLINE_SPEC_HANDLER,
 		ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_HANDLER,
 		ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
 		ZEND_YIELD_SPEC_CONST_CONST_HANDLER,
-		ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_YIELD_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_YIELD_SPEC_CONST_CV_HANDLER,
 		ZEND_YIELD_SPEC_TMP_CONST_HANDLER,
-		ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER,
-		ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER,
+		ZEND_YIELD_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER,
 		ZEND_YIELD_SPEC_TMP_CV_HANDLER,
 		ZEND_YIELD_SPEC_VAR_CONST_HANDLER,
-		ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER,
-		ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER,
+		ZEND_YIELD_SPEC_VAR_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER,
 		ZEND_YIELD_SPEC_VAR_CV_HANDLER,
 		ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER,
-		ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER,
-		ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER,
+		ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER,
 		ZEND_YIELD_SPEC_UNUSED_CV_HANDLER,
 		ZEND_YIELD_SPEC_CV_CONST_HANDLER,
-		ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_YIELD_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_YIELD_SPEC_CV_UNUSED_HANDLER,
 		ZEND_YIELD_SPEC_CV_CV_HANDLER,
 		ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER,
@@ -66773,40 +120101,40 @@ void zend_vm_init(void)
 		ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER,
 		ZEND_SEND_UNPACK_SPEC_HANDLER,
 		ZEND_YIELD_FROM_SPEC_CONST_HANDLER,
-		ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER,
-		ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER,
+		ZEND_YIELD_FROM_SPEC_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_YIELD_FROM_SPEC_CV_HANDLER,
 		ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER,
 		ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER,
 		ZEND_COALESCE_SPEC_CONST_HANDLER,
 		ZEND_COALESCE_SPEC_TMP_HANDLER,
-		ZEND_COALESCE_SPEC_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_COALESCE_SPEC_CV_HANDLER,
 		ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER,
-		ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_SPACESHIP_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_SPACESHIP_SPEC_TMP_CONST_HANDLER,
+		ZEND_SPACESHIP_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_SPACESHIP_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER,
-		ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_SPACESHIP_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_SPACESHIP_SPEC_CV_CV_HANDLER,
 		ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_HANDLER,
@@ -66869,48 +120197,48 @@ void zend_vm_init(void)
 		ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_HANDLER,
 		ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER,
 		ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER,
-		ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER,
 		ZEND_COUNT_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_COUNT_SPEC_CV_UNUSED_HANDLER,
 		ZEND_GET_CLASS_SPEC_CONST_UNUSED_HANDLER,
-		ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER,
 		ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER,
 		ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER,
 		ZEND_GET_TYPE_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER,
-		ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER,
 		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER,
-		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HANDLER,
 		ZEND_MATCH_SPEC_CONST_CONST_HANDLER,
@@ -66918,31 +120246,11 @@ void zend_vm_init(void)
 		ZEND_MATCH_SPEC_TMPVARCV_CONST_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_MATCH_SPEC_TMPVARCV_CONST_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
 		ZEND_CASE_STRICT_SPEC_TMP_CONST_HANDLER,
 		ZEND_CASE_STRICT_SPEC_TMP_TMP_HANDLER,
-		ZEND_CASE_STRICT_SPEC_TMP_VAR_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER,
-		ZEND_CASE_STRICT_SPEC_VAR_CONST_HANDLER,
-		ZEND_CASE_STRICT_SPEC_VAR_TMP_HANDLER,
-		ZEND_CASE_STRICT_SPEC_VAR_VAR_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_CASE_STRICT_SPEC_VAR_CV_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
-		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
+		ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER,
 		ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER,
 		ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER,
@@ -66950,7 +120258,7 @@ void zend_vm_init(void)
 		ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER,
 		ZEND_JMP_NULL_SPEC_CONST_HANDLER,
 		ZEND_JMP_NULL_SPEC_TMP_HANDLER,
-		ZEND_JMP_NULL_SPEC_VAR_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_JMP_NULL_SPEC_CV_HANDLER,
 		ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER,
@@ -66969,11 +120277,22 @@ void zend_vm_init(void)
 		ZEND_JMP_FRAMELESS_SPEC_CONST_HANDLER,
 		ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER,
 		ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_HANDLER,
+		ZEND_TYPE_ASSERT_SPEC_CONST_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
+		ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER,
 		ZEND_RECV_NOTYPE_SPEC_HANDLER,
 		ZEND_NULL_HANDLER,
-		ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER,
-		ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER,
+		ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_HANDLER,
+		ZEND_NULL_HANDLER,
 		ZEND_NULL_HANDLER,
 		ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_HANDLER,
 		ZEND_JMP_FORWARD_SPEC_HANDLER,
@@ -67886,6 +121205,3503 @@ void zend_vm_init(void)
 		ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER,
 		ZEND_NULL_HANDLER
 	};
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL || ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
+	static zend_vm_opcode_handler_t const handlers[] = {
+		ZEND_NOP_SPEC_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_DIV_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CONCAT_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POW_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_BW_NOT_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_BW_NOT_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BW_NOT_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BW_NOT_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_BOOL_NOT_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_BOOL_NOT_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BOOL_NOT_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_BOOL_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BOOL_XOR_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_BOOL_XOR_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BOOL_XOR_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_BOOL_XOR_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BOOL_XOR_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OP_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_STATIC_PROP_OP_SPEC_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_REF_SPEC_VAR_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_REF_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_REF_SPEC_CV_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_REF_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER,
+		ZEND_ASSIGN_STATIC_PROP_REF_SPEC_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_INC_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_INC_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_INC_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_DEC_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_DEC_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_PRE_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER,
+		ZEND_POST_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER,
+		ZEND_JMP_SPEC_TAILCALL_HANDLER,
+		ZEND_JMPZ_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_JMPZ_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_JMPZ_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_JMPNZ_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_JMPNZ_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_JMPNZ_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_JMPZ_EX_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_JMPZ_EX_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_JMPZ_EX_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_JMPNZ_EX_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_JMPNZ_EX_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_JMPNZ_EX_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_CASE_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_CASE_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CASE_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_CHECK_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CAST_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_CAST_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CAST_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_BOOL_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_BOOL_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BOOL_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FAST_CONCAT_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_ROPE_INIT_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_ROPE_INIT_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ROPE_INIT_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_ROPE_ADD_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_ROPE_ADD_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ROPE_ADD_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_ROPE_END_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_ROPE_END_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ROPE_END_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_BEGIN_SILENCE_SPEC_TAILCALL_HANDLER,
+		ZEND_END_SILENCE_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_INIT_FCALL_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_RETURN_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_RETURN_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_RETURN_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_RECV_SPEC_UNUSED_TAILCALL_HANDLER,
+		ZEND_RECV_INIT_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_REF_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_REF_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_REF_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_REF_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NEW_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NEW_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NEW_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_FREE_SPEC_TMPVAR_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_ARRAY_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_INCLUDE_OR_EVAL_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_INCLUDE_OR_EVAL_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INCLUDE_OR_EVAL_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_UNSET_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_DIM_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_UNSET_DIM_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_DIM_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_DIM_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_UNSET_DIM_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_DIM_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_UNSET_OBJ_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FE_RESET_R_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_FE_RESET_R_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FE_RESET_R_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_FE_FETCH_R_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_FETCH_R_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_R_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_R_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_R_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_W_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_W_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_W_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_W_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_W_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_RW_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_RW_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_RW_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_RW_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_RW_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_IS_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_IS_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_IS_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_IS_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_IS_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_UNSET_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_EXT_STMT_SPEC_TAILCALL_HANDLER,
+		ZEND_EXT_FCALL_BEGIN_SPEC_TAILCALL_HANDLER,
+		ZEND_EXT_FCALL_END_SPEC_TAILCALL_HANDLER,
+		ZEND_EXT_NOP_SPEC_TAILCALL_HANDLER,
+		ZEND_TICKS_SPEC_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CATCH_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CATCH_SPEC_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_THROW_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_THROW_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_THROW_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_CLONE_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_CLONE_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CLONE_SPEC_UNUSED_TAILCALL_HANDLER,
+		ZEND_CLONE_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_METHOD_CALL_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_USER_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_USER_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_USER_CALL_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_SEND_ARRAY_SPEC_TAILCALL_HANDLER,
+		ZEND_SEND_USER_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_USER_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_USER_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_STRLEN_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_STRLEN_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_STRLEN_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_DEFINED_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_TYPE_CHECK_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_TYPE_CHECK_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_TYPE_CHECK_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_FE_RESET_RW_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_FE_RESET_RW_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_FE_RESET_RW_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FE_RESET_RW_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_FE_FETCH_RW_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_FE_FREE_SPEC_TMPVAR_TAILCALL_HANDLER,
+		ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_DYNAMIC_CALL_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_DO_ICALL_SPEC_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_DO_ICALL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_DO_ICALL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_DO_UCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_DO_UCALL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_DO_UCALL_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_PRE_INC_OBJ_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_POST_INC_OBJ_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_ECHO_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_ECHO_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ECHO_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INSTANCEOF_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INSTANCEOF_SPEC_TMP_VAR_TAILCALL_HANDLER,
+		ZEND_INSTANCEOF_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INSTANCEOF_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INSTANCEOF_SPEC_CV_VAR_TAILCALL_HANDLER,
+		ZEND_INSTANCEOF_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_GENERATOR_CREATE_SPEC_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MAKE_REF_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MAKE_REF_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_DECLARE_FUNCTION_SPEC_TAILCALL_HANDLER,
+		ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_DECLARE_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_DECLARE_CLASS_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_DECLARE_ANON_CLASS_SPEC_TAILCALL_HANDLER,
+		ZEND_ADD_ARRAY_UNPACK_SPEC_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_HANDLE_EXCEPTION_SPEC_TAILCALL_HANDLER,
+		ZEND_USER_OPCODE_SPEC_TAILCALL_HANDLER,
+		ZEND_ASSERT_CHECK_SPEC_TAILCALL_HANDLER,
+		ZEND_JMP_SET_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_JMP_SET_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_JMP_SET_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_UNSET_CV_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_W_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_W_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_LIST_W_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_SEPARATE_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_NAME_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_NAME_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_CALL_TRAMPOLINE_SPEC_TAILCALL_HANDLER,
+		ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_DISCARD_EXCEPTION_SPEC_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_VAR_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_VAR_CV_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_UNUSED_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_UNUSED_CV_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_YIELD_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_GENERATOR_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_FAST_CALL_SPEC_TAILCALL_HANDLER,
+		ZEND_FAST_RET_SPEC_TAILCALL_HANDLER,
+		ZEND_RECV_VARIADIC_SPEC_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_UNPACK_SPEC_TAILCALL_HANDLER,
+		ZEND_YIELD_FROM_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_YIELD_FROM_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_YIELD_FROM_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_BIND_GLOBAL_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_COALESCE_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_COALESCE_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_COALESCE_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SPACESHIP_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_STATIC_PROP_R_SPEC_TAILCALL_HANDLER,
+		ZEND_FETCH_STATIC_PROP_W_SPEC_TAILCALL_HANDLER,
+		ZEND_FETCH_STATIC_PROP_RW_SPEC_TAILCALL_HANDLER,
+		ZEND_FETCH_STATIC_PROP_IS_SPEC_TAILCALL_HANDLER,
+		ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TAILCALL_HANDLER,
+		ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TAILCALL_HANDLER,
+		ZEND_UNSET_STATIC_PROP_SPEC_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_BIND_LEXICAL_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_BIND_STATIC_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_SWITCH_LONG_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SWITCH_STRING_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IN_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_IN_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IN_ARRAY_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_COUNT_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_COUNT_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_COUNT_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_GET_CLASS_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_GET_CLASS_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_GET_CLASS_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_GET_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_GET_TYPE_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_GET_TYPE_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_MATCH_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_CASE_STRICT_SPEC_TMP_CONST_TAILCALL_HANDLER,
+		ZEND_CASE_STRICT_SPEC_TMP_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_CASE_STRICT_SPEC_TMP_CV_TAILCALL_HANDLER,
+		ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER,
+		ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER,
+		ZEND_JMP_NULL_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_JMP_NULL_SPEC_TMP_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_JMP_NULL_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_2_SPEC_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_3_SPEC_TAILCALL_HANDLER,
+		ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_TAILCALL_HANDLER,
+		ZEND_JMP_FRAMELESS_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER,
+		ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER,
+		ZEND_TYPE_ASSERT_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_INIT_FCALL_OFFSET_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_RECV_NOTYPE_SPEC_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_JMP_FORWARD_SPEC_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER,
+		ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER,
+		ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_POST_INC_LONG_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_POST_DEC_LONG_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_LONG_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_NOREF_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_SIMPLE_SPEC_VAR_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_SIMPLE_SPEC_CV_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER,
+		ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_SIMPLE_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_TAILCALL_HANDLER,
+		ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_TAILCALL_HANDLER,
+		ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_TAILCALL_HANDLER,
+		ZEND_NULL_TAILCALL_HANDLER
+	};
+	zend_handlers_count = sizeof(handlers) / sizeof(handlers[0]);
+#elif ZEND_VM_KIND != ZEND_VM_KIND_HYBRID
+	static zend_vm_opcode_handler_t const *handlers = funcs;
+	zend_handlers_count = sizeof(funcs) / sizeof(funcs[0]);
+#endif
 	static const uint32_t specs[] = {
 		0,
 		1 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
@@ -67932,7 +124748,7 @@ void zend_vm_init(void)
 		1255,
 		1256 | SPEC_RULE_OP1,
 		1261 | SPEC_RULE_OP1,
-		3493,
+		3488,
 		1266 | SPEC_RULE_OP1,
 		1271 | SPEC_RULE_OP1,
 		1276 | SPEC_RULE_OP2,
@@ -67966,7 +124782,7 @@ void zend_vm_init(void)
 		1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
 		1584 | SPEC_RULE_OP1,
 		1589,
-		3493,
+		3488,
 		1590 | SPEC_RULE_OP1,
 		1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
 		1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
@@ -67994,163 +124810,167 @@ void zend_vm_init(void)
 		1959,
 		1960,
 		1961 | SPEC_RULE_OP2,
-		1966,
-		1967 | SPEC_RULE_OP1,
-		1972 | SPEC_RULE_OP2,
-		1977 | SPEC_RULE_OP1,
-		1982 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
-		1992 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2017 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2042 | SPEC_RULE_OP1,
-		2047 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2072 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG,
-		2122 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2147 | SPEC_RULE_OP2,
-		2152,
-		2153 | SPEC_RULE_OP1,
-		2158 | SPEC_RULE_OP1,
-		2163,
-		2164 | SPEC_RULE_OP1,
-		2169 | SPEC_RULE_OP1,
-		2174 | SPEC_RULE_OP1,
-		2179,
-		2180,
-		2181 | SPEC_RULE_OP2,
-		2186 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
+		1966 | SPEC_RULE_OP1,
+		1971 | SPEC_RULE_OP1,
+		1976 | SPEC_RULE_OP2,
+		1981 | SPEC_RULE_OP1,
+		1986 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
+		1996 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2021 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2046 | SPEC_RULE_OP1,
+		2051 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2076 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG,
+		2126 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2151 | SPEC_RULE_OP2,
+		2156,
+		2157 | SPEC_RULE_OP1,
+		2162 | SPEC_RULE_OP1,
+		2167,
+		2168 | SPEC_RULE_OP1,
+		2173 | SPEC_RULE_OP1,
+		2178 | SPEC_RULE_OP1,
+		2183,
+		2184,
+		2185 | SPEC_RULE_OP2,
 		2190 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
 		2194 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
-		2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2248 | SPEC_RULE_OP1,
-		2253,
-		2254 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2279,
-		2280 | SPEC_RULE_OP1,
-		2285,
-		2286,
-		2287,
-		2288,
+		2198 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
+		2202 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2202 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2227 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2227 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2252 | SPEC_RULE_OP1,
+		2257,
+		2258 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2283,
+		2284 | SPEC_RULE_OP1,
 		2289,
 		2290,
 		2291,
-		2292 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2317,
-		2318,
-		2319,
-		2320 | SPEC_RULE_OP1,
-		2325,
-		2326 | SPEC_RULE_ISSET,
-		2328 | SPEC_RULE_OP2,
-		2333,
-		2334 | SPEC_RULE_OP1,
-		2339 | SPEC_RULE_OBSERVER,
-		2341,
-		2342 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2367 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
-		2377,
-		2378,
-		2379,
-		2380,
-		2381 | SPEC_RULE_OP1,
-		2386,
-		2387,
-		2388 | SPEC_RULE_OP1,
-		2393 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2418,
-		2419 | SPEC_RULE_OP1,
-		2424,
-		2425,
-		2426,
-		2427,
+		2292,
+		2293,
+		2294,
+		2295,
+		2296 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2321,
+		2322,
+		2323,
+		2324 | SPEC_RULE_OP1,
+		2329,
+		2330 | SPEC_RULE_ISSET,
+		2332 | SPEC_RULE_OP2,
+		2337,
+		2338 | SPEC_RULE_OP1,
+		2343 | SPEC_RULE_OBSERVER,
+		2345,
+		2346 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2371 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
+		2381,
+		2382,
+		2383,
+		2384,
+		2385 | SPEC_RULE_OP1,
+		2390,
+		2391,
+		2392 | SPEC_RULE_OP1,
+		2397 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2422,
+		2423 | SPEC_RULE_OP1,
 		2428,
 		2429,
 		2430,
 		2431,
-		2432 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2457,
-		2458,
-		2459,
-		2460 | SPEC_RULE_OP2,
-		2465,
-		2466 | SPEC_RULE_OP1,
-		2471 | SPEC_RULE_OP1,
-		2476 | SPEC_RULE_OP1,
-		2481 | SPEC_RULE_OP1,
-		2486 | SPEC_RULE_OP1,
-		2491,
-		2492 | SPEC_RULE_OP1,
-		2497 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2522 | SPEC_RULE_OP1,
-		2527 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-		2552 | SPEC_RULE_OP1,
-		2557 | SPEC_RULE_OP1,
+		2432,
+		2433,
+		2434,
+		2435,
+		2436 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2461,
+		2462,
+		2463,
+		2464 | SPEC_RULE_OP2,
+		2469,
+		2470 | SPEC_RULE_OP1,
+		2475 | SPEC_RULE_OP1,
+		2480 | SPEC_RULE_OP1,
+		2485 | SPEC_RULE_OP1,
+		2490 | SPEC_RULE_OP1,
+		2495,
+		2496 | SPEC_RULE_OP1,
+		2501 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+		2526 | SPEC_RULE_OP1,
+		2531 | SPEC_RULE_OP2,
+		2536 | SPEC_RULE_OP1,
+		2541 | SPEC_RULE_OP1,
+		2546,
+		2547,
+		2548,
+		2549,
+		2550,
+		2551 | SPEC_RULE_OBSERVER,
+		2553 | SPEC_RULE_OBSERVER,
+		2555 | SPEC_RULE_OBSERVER,
+		2557 | SPEC_RULE_OBSERVER,
+		2559,
+		2560,
+		2561,
 		2562,
-		2563,
-		2564,
-		2565,
-		2566,
-		2567 | SPEC_RULE_OBSERVER,
-		2569 | SPEC_RULE_OBSERVER,
-		2571 | SPEC_RULE_OBSERVER,
-		2573 | SPEC_RULE_OBSERVER,
-		2575,
-		2576,
-		2577,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
-		3493,
+		2563 | SPEC_RULE_OP1,
+		2568 | SPEC_RULE_OP1,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
+		3488,
 	};
-#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
-	zend_opcode_handler_funcs = labels;
+#if 0
+#elif (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
+	zend_opcode_handler_funcs = funcs;
 	zend_spec_handlers = specs;
 	execute_ex(NULL);
+#elif ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	zend_opcode_handler_funcs = funcs;
+	zend_opcode_handlers = handlers;
+	zend_spec_handlers = specs;
 #else
-	zend_opcode_handlers = labels;
-	zend_handlers_count = sizeof(labels) / sizeof(void*);
+	zend_opcode_handlers = handlers;
 	zend_spec_handlers = specs;
 #endif
 	VM_TRACE_START();
@@ -68179,7 +124999,7 @@ static void init_opcode_serialiser(void)
 	Z_TYPE_INFO(tmp) = IS_LONG;
 	for (i = 0; i < zend_handlers_count; i++) {
 		Z_LVAL(tmp) = i;
-		zend_hash_index_add(zend_handlers_table, (zend_long)(uintptr_t)zend_opcode_handlers[i], &tmp);
+		zend_hash_index_add(zend_handlers_table, (zend_ulong)(uintptr_t)zend_opcode_handlers[i], &tmp);
 	}
 }
 
@@ -68190,9 +125010,9 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
-	op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv);
+	op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
 }
 
 ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)
@@ -68202,17 +125022,17 @@ ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)
 
 ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *op)
 {
-#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
-	return op->handler;
-#elif ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
+#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
 	zval *zv;
 
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
 	return zend_opcode_handler_funcs[Z_LVAL_P(zv)];
+#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL
+	return op->handler;
 #else
 	return NULL;
 #endif
@@ -68227,6 +125047,22 @@ ZEND_API const zend_op *zend_get_halt_op(void)
 #endif
 }
 
+ZEND_API const zend_op *zend_get_interrupt_op(void)
+{
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	return &call_interrupt_op;
+#else
+	return NULL;
+#endif
+}
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS)
+{
+	return zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+#endif
+
 ZEND_API int zend_vm_kind(void)
 {
 	return ZEND_VM_KIND;
@@ -68277,15 +125113,15 @@ static uint32_t ZEND_FASTCALL zend_vm_get_opcode_handler_idx(uint32_t spec, cons
 	return (spec & SPEC_START_MASK) + offset;
 }
 
-#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC
-static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)
+#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC
+static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)
 {
 	return zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];
 }
 #endif
 
-#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
-static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op)
+#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+static zend_vm_opcode_handler_func_t zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op)
 {
 	uint32_t spec = zend_spec_handlers[opcode];
 	return zend_opcode_handler_funcs[zend_vm_get_opcode_handler_idx(spec, op)];
@@ -68315,7 +125151,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2586 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2581 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 				if (op->op1_type < op->op2_type) {
 					zend_swap_operands(op);
 				}
@@ -68323,7 +125159,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2611 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2606 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 				if (op->op1_type < op->op2_type) {
 					zend_swap_operands(op);
 				}
@@ -68331,7 +125167,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2636 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2631 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 				if (op->op1_type < op->op2_type) {
 					zend_swap_operands(op);
 				}
@@ -68342,17 +125178,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2661 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 2656 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2686 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 2681 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2711 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 2706 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			}
 			break;
 		case ZEND_MUL:
@@ -68363,17 +125199,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2736 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2731 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2761 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2756 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2786 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 2781 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_IDENTICAL:
@@ -68384,16 +125220,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2806 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2881 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) {
-				spec = 3111 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3106 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
-				spec = 3117 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 3112 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_NOT_IDENTICAL:
@@ -68404,16 +125240,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2956 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3031 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) {
-				spec = 3114 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3109 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
-				spec = 3122 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+				spec = 3117 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_EQUAL:
@@ -68424,12 +125260,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2806 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2881 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_NOT_EQUAL:
@@ -68440,12 +125276,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 2956 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+				spec = 3031 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
 			}
 			break;
 		case ZEND_IS_SMALLER:
@@ -68453,12 +125289,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3127 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3122 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3202 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3197 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			}
 			break;
 		case ZEND_IS_SMALLER_OR_EQUAL:
@@ -68466,79 +125302,79 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3277 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3272 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3352 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+				spec = 3347 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
 			}
 			break;
 		case ZEND_QM_ASSIGN:
 			if (op1_info == MAY_BE_LONG) {
-				spec = 3439 | SPEC_RULE_OP1;
+				spec = 3434 | SPEC_RULE_OP1;
 			} else if (op1_info == MAY_BE_DOUBLE) {
-				spec = 3444 | SPEC_RULE_OP1;
+				spec = 3439 | SPEC_RULE_OP1;
 			} else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) {
-				spec = 3449 | SPEC_RULE_OP1;
+				spec = 3444 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_PRE_INC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3427 | SPEC_RULE_RETVAL;
+				spec = 3422 | SPEC_RULE_RETVAL;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3429 | SPEC_RULE_RETVAL;
+				spec = 3424 | SPEC_RULE_RETVAL;
 			}
 			break;
 		case ZEND_PRE_DEC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3431 | SPEC_RULE_RETVAL;
+				spec = 3426 | SPEC_RULE_RETVAL;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3433 | SPEC_RULE_RETVAL;
+				spec = 3428 | SPEC_RULE_RETVAL;
 			}
 			break;
 		case ZEND_POST_INC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3435;
+				spec = 3430;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3436;
+				spec = 3431;
 			}
 			break;
 		case ZEND_POST_DEC:
 			if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
-				spec = 3437;
+				spec = 3432;
 			} else if (op1_info == MAY_BE_LONG) {
-				spec = 3438;
+				spec = 3433;
 			}
 			break;
 		case ZEND_JMP:
 			if (OP_JMP_ADDR(op, op->op1) > op) {
-				spec = 2585;
+				spec = 2580;
 			}
 			break;
 		case ZEND_INIT_FCALL:
 			if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) {
-				spec = 2578;
+				spec = 2573;
 			}
 			break;
 		case ZEND_RECV:
 			if (op->op2.num == MAY_BE_ANY) {
-				spec = 2579;
+				spec = 2574;
 			}
 			break;
 		case ZEND_SEND_VAL:
 			if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
-				spec = 3489;
+				spec = 3484;
 			}
 			break;
 		case ZEND_SEND_VAR_EX:
 			if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
-				spec = 3484 | SPEC_RULE_OP1;
+				spec = 3479 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_FE_FETCH_R:
 			if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
-				spec = 3491 | SPEC_RULE_RETVAL;
+				spec = 3486 | SPEC_RULE_RETVAL;
 			}
 			break;
 		case ZEND_FETCH_DIM_R:
@@ -68546,22 +125382,22 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 				if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
 					break;
 				}
-				spec = 3454 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+				spec = 3449 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
 			}
 			break;
 		case ZEND_SEND_VAL_EX:
 			if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
-				spec = 3490;
+				spec = 3485;
 			}
 			break;
 		case ZEND_SEND_VAR:
 			if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
-				spec = 3479 | SPEC_RULE_OP1;
+				spec = 3474 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_COUNT:
 			if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) {
-				spec = 2580 | SPEC_RULE_OP1;
+				spec = 2575 | SPEC_RULE_OP1;
 			}
 			break;
 		case ZEND_BW_OR:
@@ -68587,8 +125423,8 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
 
 ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)
 {
-#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
-	opcode_handler_t handler;
+#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL)
+	zend_vm_opcode_handler_func_t handler;
 #endif
 	DCL_OPLINE;
 	int ret;
@@ -68605,11 +125441,11 @@ ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)
 	LOAD_OPLINE();
 #if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)
 #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
-	handler = (opcode_handler_t)zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);
+	handler = zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);
 	handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 	if (EXPECTED(opline != &hybrid_halt_op)) {
 #else
-	((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+	(OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 	if (EXPECTED(opline)) {
 #endif
 		ret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;
@@ -68618,8 +125454,13 @@ ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)
 		ret = -1;
 	}
 #else
-	opline = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-if (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT))) {
+# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	handler = zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);
+	opline = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+# else
+	opline = (OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+# endif
+	if (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT))) {
 		opline = (const zend_op*)((uintptr_t)opline & ~ZEND_VM_ENTER_BIT);
 		if (EXPECTED(opline)) {
 			/* ZEND_VM_ENTER() or ZEND_VM_LEAVE() */
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index 6fecd39346a7..beabe36688df 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -7,7 +7,7 @@
 # pragma GCC optimize("no-gcse")
 # pragma GCC optimize("no-ivopts")
 #endif
-#ifdef _WIN64
+#if defined(_WIN64) && defined(_M_X64)
 /* See save_xmm_x86_64_ms_masm.asm */
 void {%EXECUTOR_NAME%}_ex_real(zend_execute_data *ex)
 #else
@@ -113,7 +113,7 @@ static void init_opcode_serialiser(void)
 	Z_TYPE_INFO(tmp) = IS_LONG;
 	for (i = 0; i < zend_handlers_count; i++) {
 		Z_LVAL(tmp) = i;
-		zend_hash_index_add(zend_handlers_table, (zend_long)(uintptr_t)zend_opcode_handlers[i], &tmp);
+		zend_hash_index_add(zend_handlers_table, (zend_ulong)(uintptr_t)zend_opcode_handlers[i], &tmp);
 	}
 }
 
@@ -124,9 +124,9 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
-	op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv);
+	op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
 }
 
 ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)
@@ -136,17 +136,17 @@ ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)
 
 ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *op)
 {
-#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
-	return op->handler;
-#elif ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
+#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
 	zval *zv;
 
 	if (!zend_handlers_table) {
 		init_opcode_serialiser();
 	}
-	zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
+	zv = zend_hash_index_find(zend_handlers_table, (zend_ulong)(uintptr_t)op->handler);
 	ZEND_ASSERT(zv != NULL);
 	return zend_opcode_handler_funcs[Z_LVAL_P(zv)];
+#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL
+	return op->handler;
 #else
 	return NULL;
 #endif
@@ -161,6 +161,22 @@ ZEND_API const zend_op *zend_get_halt_op(void)
 #endif
 }
 
+ZEND_API const zend_op *zend_get_interrupt_op(void)
+{
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+	return &call_interrupt_op;
+#else
+	return NULL;
+#endif
+}
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS)
+{
+	return zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+#endif
+
 ZEND_API int zend_vm_kind(void)
 {
 	return ZEND_VM_KIND;
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index dbd7da0430f1..8e65bc0a28ea 100755
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -4,15 +4,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
@@ -23,15 +22,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -49,10 +47,11 @@
 
 error_reporting(E_ALL);
 
-const ZEND_VM_KIND_CALL   = 1;
-const ZEND_VM_KIND_SWITCH = 2;
-const ZEND_VM_KIND_GOTO   = 3;
-const ZEND_VM_KIND_HYBRID = 4;
+const ZEND_VM_KIND_CALL     = 1;
+const ZEND_VM_KIND_SWITCH   = 2;
+const ZEND_VM_KIND_GOTO     = 3;
+const ZEND_VM_KIND_HYBRID   = 4;
+const ZEND_VM_KIND_TAILCALL = 5;
 
 $vm_op_flags = array(
     "ZEND_VM_OP_SPEC"         => 1<<0,
@@ -63,7 +62,7 @@
     "ZEND_VM_OP_NUM"          => 0x10,
     "ZEND_VM_OP_JMP_ADDR"     => 0x20,
     "ZEND_VM_OP_TRY_CATCH"    => 0x30,
-    // unused 0x40
+    "ZEND_VM_OP_LOOP_END"     => 0x40,
     "ZEND_VM_OP_THIS"         => 0x50,
     "ZEND_VM_OP_NEXT"         => 0x60,
     "ZEND_VM_OP_CLASS_FETCH"  => 0x70,
@@ -111,6 +110,7 @@
     "NUM"                  => ZEND_VM_OP_NUM,
     "JMP_ADDR"             => ZEND_VM_OP_JMP_ADDR,
     "TRY_CATCH"            => ZEND_VM_OP_TRY_CATCH,
+    "LOOP_END"             => ZEND_VM_OP_LOOP_END,
     "THIS"                 => ZEND_VM_OP_THIS,
     "NEXT"                 => ZEND_VM_OP_NEXT,
     "CLASS_FETCH"          => ZEND_VM_OP_CLASS_FETCH,
@@ -142,6 +142,7 @@
     ZEND_VM_KIND_SWITCH    => "ZEND_VM_KIND_SWITCH",
     ZEND_VM_KIND_GOTO      => "ZEND_VM_KIND_GOTO",
     ZEND_VM_KIND_HYBRID    => "ZEND_VM_KIND_HYBRID",
+    ZEND_VM_KIND_TAILCALL  => "ZEND_VM_KIND_TAILCALL",
 );
 
 $op_types = array(
@@ -543,24 +544,28 @@
 $helpers = array(); // opcode helpers by name
 $params  = array(); // parameters of helpers
 $opnames = array(); // opcode name to code mapping
-$line_no = 1;
+$line_nos = [];
 
 $used_extra_spec = array();
 
 // Writes $s into resulting executor
 function out($f, $s) {
-    global $line_no;
+    global $line_nos;
 
     fputs($f,$s);
-    $line_no += substr_count($s, "\n");
+
+    $line_nos[(int)$f] ??= 1;
+    $line_nos[(int)$f] += substr_count($s, "\n");
 }
 
 // Resets #line directives in resulting executor
 function out_line($f) {
-    global $line_no, $executor_file;
+    global $line_nos, $executor_file;
+
+    $line_nos[(int)$f] ??= 1;
+    $line_nos[(int)$f]++;
 
-    fputs($f,"#line ".($line_no+1)." \"".$executor_file."\"\n");
-    ++$line_no;
+    fputs($f,"#line ".$line_nos[(int)$f]." \"".$executor_file."\"\n");
 }
 
 function is_hot_helper($name) {
@@ -574,7 +579,7 @@ function is_hot_helper($name) {
 }
 
 // Returns name of specialized helper
-function helper_name($name, $spec, $op1, $op2, $extra_spec) {
+function helper_name($name, $spec, $op1, $op2, $extra_spec, $kind) {
     global $prefix, $helpers;
 
     $extra = "";
@@ -616,13 +621,15 @@ function helper_name($name, $spec, $op1, $op2, $extra_spec) {
         }
     }
 
-    return $name . ($spec ? "_SPEC" : "") . $prefix[$op1] . $prefix[$op2] . $extra;
+    $variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
+    return $name . ($spec ? "_SPEC" : "") . $prefix[$op1] . $prefix[$op2] . $extra . $variant;
 }
 
-function opcode_name($name, $spec, $op1, $op2, $extra_spec) {
+function opcode_name($name, $spec, $op1, $op2, $extra_spec, $kind) {
     global $prefix, $opnames, $opcodes;
 
     $extra = "";
+    $variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
 
     if (isset($opnames[$name])) {
         $opcode = $opcodes[$opnames[$name]];
@@ -642,7 +649,7 @@ function opcode_name($name, $spec, $op1, $op2, $extra_spec) {
                 $op1 = "ANY";
             } else if ($spec) {
                 /* dispatch to invalid handler from unreachable code */
-                return "ZEND_NULL";
+                return "ZEND_NULL$variant";
             }
         }
         if (!isset($opcode["op2"][$op2])) {
@@ -659,7 +666,7 @@ function opcode_name($name, $spec, $op1, $op2, $extra_spec) {
                 $op2 = "ANY";
             } else if ($spec) {
                 /* dispatch to unknown handler in unreachable code */
-                return "ZEND_NULL";
+                return "ZEND_NULL$variant";
             }
         }
         /* forward common specs (e.g. in ZEND_VM_DISPATCH_TO_HANDLER) */
@@ -668,7 +675,7 @@ function opcode_name($name, $spec, $op1, $op2, $extra_spec) {
         }
     }
 
-    return $name . ($spec ? "_SPEC" : "") . $prefix[$op1] . $prefix[$op2] . $extra;
+    return $name . ($spec ? "_SPEC" : "") . $prefix[$op1] . $prefix[$op2] . $extra . $variant;
 }
 
 // Formats condition, protecting it by parentheses when needed.
@@ -732,8 +739,8 @@ function gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec=null)
         "/FREE_OP2_IF_VAR\(\)/" => $op2_free_op_if_var[$op2],
         "/\!ZEND_VM_SPEC/m" => ($op1!="ANY"||$op2!="ANY"||$extra_spec)?"0":"1",
         "/ZEND_VM_SPEC/m" => ($op1!="ANY"||$op2!="ANY"||$extra_spec)?"1":"0",
-        "/ZEND_VM_C_LABEL\(\s*([A-Za-z_]*)\s*\)/m" => "\\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
-        "/ZEND_VM_C_GOTO\(\s*([A-Za-z_]*)\s*\)/m" => "goto \\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
+        "/ZEND_VM_C_LABEL\(\s*([A-Za-z_]*)\s*\)/m" => "\\1".(($spec && $kind != ZEND_VM_KIND_CALL && $kind != ZEND_VM_KIND_TAILCALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
+        "/ZEND_VM_C_GOTO\(\s*([A-Za-z_]*)\s*\)/m" => "goto \\1".(($spec && $kind != ZEND_VM_KIND_CALL && $kind != ZEND_VM_KIND_TAILCALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
         "/^#(\s*)if\s+1\s*\\|\\|.*[^\\\\]$/m" => "#\\1if 1",
         "/^#(\s*)if\s+0\s*&&.*[^\\\\]$/m" => "#\\1if 0",
         "/^#(\s*)elif\s+1\s*\\|\\|.*[^\\\\]$/m" => "#\\1elif 1",
@@ -796,7 +803,7 @@ function gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec=null)
                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
                 ),
-                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
+                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $kind) {
                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
                         return "execute_data";
                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
@@ -804,35 +811,36 @@ function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
 
                         $name = $matches[1];
                         $opcode = $opcodes[$opnames[$name]];
-                        return "goto " . opcode_name($name, $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                        return "goto " . opcode_name($name, $spec, $op1, $op2, $extra_spec, $kind) . "_LABEL";
                     } else {
                         // ZEND_VM_DISPATCH_TO_HELPER
                         if (is_hot_helper($matches[1])) {
                             if (isset($matches[2])) {
                                 // extra args
                                 $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
-                                return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                                return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "_LABEL";
                             }
-                            return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                            return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "_LABEL";
                         }
                         if (isset($matches[2])) {
                             // extra args
                             $args = substr(preg_replace("/,\s*[A-Za-z0-9_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
-                            return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX " . $args . "))";
+                            return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX " . $args . "))";
                         }
-                        return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
+                        return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
                     }
                 },
                 $code);
             break;
         case ZEND_VM_KIND_CALL:
+        case ZEND_VM_KIND_TAILCALL:
             $code = preg_replace_callback(
                 array(
                     "/EXECUTE_DATA(?=[^_])/m",
                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
                 ),
-                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $name) {
+                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $name, $kind) {
                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
                         return "execute_data";
                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
@@ -841,20 +849,24 @@ function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $name) {
                         $handler = $matches[1];
                         $opcode = $opcodes[$opnames[$handler]];
                         $inline =
-                            ZEND_VM_KIND == ZEND_VM_KIND_HYBRID &&
+                            ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID &&
                             isset($opcode["use"]) &&
                             is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec) &&
                             is_hot_handler($opcodes[$opnames[$name]]["hot"], $op1, $op2, $extra_spec) ?
                             "_INLINE" : "";
-                        return "ZEND_VM_TAIL_CALL(" . opcode_name($handler, $spec, $op1, $op2, $extra_spec) . $inline . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
+                        return "ZEND_VM_TAIL_CALL(" . opcode_name($handler, $spec, $op1, $op2, $extra_spec, $kind) . $inline . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
                     } else {
                         // ZEND_VM_DISPATCH_TO_HELPER
                         if (isset($matches[2])) {
                             // extra args
                             $args = substr(preg_replace("/,\s*[A-Za-z0-9_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
-                            return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX " . $args . "))";
+                            return "ZEND_VM_DISPATCH_TO_HELPER(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX " . $args . "))";
+                        }
+                        if ($kind === ZEND_VM_KIND_TAILCALL && $matches[1] === 'zend_leave_helper') {
+                            return "ZEND_VM_DISPATCH_TO_LEAVE_HELPER(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . ")";
+                        } else {
+                            return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
                         }
-                        return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
                     }
                 },
                 $code);
@@ -866,19 +878,19 @@ function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $name) {
                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
                 ),
-                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
+                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $kind) {
                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
                         return "execute_data";
                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
-                        return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                        return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "_LABEL";
                     } else {
                         // ZEND_VM_DISPATCH_TO_HELPER
                         if (isset($matches[2])) {
                             // extra args
                             $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
-                            return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                            return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind);
                         }
-                        return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                        return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind);
                     }
                 },
                     $code);
@@ -890,19 +902,19 @@ function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
                 ),
-                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
+                function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $kind) {
                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
                         return "execute_data";
                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
-                        return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                        return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind) . "_LABEL";
                     } else {
                         // ZEND_VM_DISPATCH_TO_HELPER
                         if (isset($matches[2])) {
                             // extra args
                             $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
-                            return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                            return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind);
                         }
-                        return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                        return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec, $kind);
                     }
                 },
                     $code);
@@ -910,10 +922,7 @@ function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
     }
 
     /* Remove unnecessary ';' */
-    $code = preg_replace('/^\s*;\s*$/m', '', $code);
-
-    /* Remove WS */
-    $code = preg_replace('/[ \t]+\n/m', "\n", $code);
+    $code = preg_replace('/^\s*;\s*$/m', "\n", $code);
 
     out($f, $code);
 }
@@ -1047,7 +1056,8 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
 
     // Generate opcode handler's entry point according to selected threading model
     $additional_func = false;
-    $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
+    $variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
+    $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"").$variant;
     switch ($kind) {
         case ZEND_VM_KIND_HYBRID:
             if (is_inline_hybrid_handler($name, $opcode["hot"], $op1, $op2, $extra_spec)) {
@@ -1079,17 +1089,19 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
             }
             return;
         case ZEND_VM_KIND_CALL:
-            if ($opcode["hot"] && ZEND_VM_KIND == ZEND_VM_KIND_HYBRID && is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
+        case ZEND_VM_KIND_TAILCALL:
+            $cconv = $kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV';
+            if ($opcode["hot"] && ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID && is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
                 if (isset($opcode["use"])) {
-                    out($f,"static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+                    out($f,"static zend_always_inline ZEND_OPCODE_HANDLER_RET {$cconv} {$spec_name}_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
                     $additional_func = true;
                 } else {
-                    out($f,"static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+                    out($f,"static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET {$cconv} {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
                 }
             } else if ($opcode["hot"] && is_cold_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
-                out($f,"static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+                out($f,"static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET {$cconv} {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
             } else {
-                out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+                out($f,"static ZEND_OPCODE_HANDLER_RET {$cconv} {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
             }
             break;
         case ZEND_VM_KIND_SWITCH:
@@ -1116,7 +1128,8 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
     gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec);
 
     if ($additional_func) {
-        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+        $cconv = $kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV';
+        out($f,"static ZEND_OPCODE_HANDLER_RET {$cconv} {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
         out($f,"{\n");
         out($f,"\tZEND_VM_TAIL_CALL({$spec_name}_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
         out($f,"}\n");
@@ -1125,7 +1138,7 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
 }
 
 // Generates helper
-function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $cold = false, $hot = false, $extra_spec = null) {
+function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $cold = false, $hot = false, $extra_spec = null, $signature_only = false) {
     global $definition_file, $prefix;
 
     if ($kind == ZEND_VM_KIND_HYBRID && !$hot) {
@@ -1140,7 +1153,8 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno,
         out($f, "#line $lineno \"$definition_file\"\n");
     }
 
-    $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
+    $variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
+    $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"").$variant;
 
     // Generate helper's entry point according to selected threading model
     switch ($kind) {
@@ -1148,8 +1162,11 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno,
             out($f, $spec_name . "_LABEL:\n");
             break;
         case ZEND_VM_KIND_CALL:
+        case ZEND_VM_KIND_TAILCALL:
             if ($inline) {
                 $zend_attributes = " zend_always_inline";
+                $zend_cconv = "";
+                $zend_cconv_ex = "";
                 $zend_fastcall = "";
             } else {
                 if ($cold) {
@@ -1157,14 +1174,22 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno,
                 } else {
                     $zend_attributes = " zend_never_inline";
                 }
-                $zend_fastcall = " ZEND_FASTCALL";
+                if ($kind !== ZEND_VM_KIND_TAILCALL) {
+                    $zend_cconv = " ZEND_OPCODE_HANDLER_FUNC_CCONV ";
+                    $zend_cconv_ex = " ZEND_OPCODE_HANDLER_FUNC_CCONV_EX ";
+                } else {
+                    $zend_cconv = " ZEND_OPCODE_HANDLER_CCONV ";
+                    $zend_cconv_ex = " ZEND_OPCODE_HANDLER_CCONV_EX ";
+                }
+                $zend_fastcall = " ZEND_FASTCALL ";
             }
+            $semi = $signature_only ? ';' : '';
             if ($param == null) {
               // Helper without parameters
-                out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name(ZEND_OPCODE_HANDLER_ARGS)\n");
+                out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_cconv $spec_name(ZEND_OPCODE_HANDLER_ARGS)$semi\n");
             } else {
               // Helper with parameter
-                out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name(ZEND_OPCODE_HANDLER_ARGS_EX $param)\n");
+                out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_cconv_ex $spec_name(ZEND_OPCODE_HANDLER_ARGS_EX $param)$semi\n");
             }
             break;
         case ZEND_VM_KIND_SWITCH:
@@ -1175,18 +1200,22 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno,
             break;
     }
 
-    // Generate helper's code
-    gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec);
+    if (!$signature_only) {
+        // Generate helper's code
+        gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec);
+    }
 }
 
-
 function gen_null_label($f, $kind, $prolog) {
     switch ($kind) {
         case ZEND_VM_KIND_CALL:
             out($f,$prolog."ZEND_NULL_HANDLER,\n");
             break;
+        case ZEND_VM_KIND_TAILCALL:
+            out($f,$prolog."ZEND_NULL_TAILCALL_HANDLER,\n");
+            break;
         case ZEND_VM_KIND_SWITCH:
-            out($f,$prolog."(void*)(uintptr_t)-1,\n");
+            out($f,$prolog."-1,\n");
             break;
         case ZEND_VM_KIND_GOTO:
             out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
@@ -1387,8 +1416,11 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
                         case ZEND_VM_KIND_CALL:
                             out($f,"$prolog{$spec_name}_HANDLER,\n");
                             break;
+                        case ZEND_VM_KIND_TAILCALL:
+                            out($f,"$prolog{$spec_name}_TAILCALL_HANDLER,\n");
+                            break;
                         case ZEND_VM_KIND_SWITCH:
-                            out($f,$prolog."(void*)(uintptr_t)$switch_labels[$spec_name],\n");
+                            out($f,$prolog."$switch_labels[$spec_name],\n");
                             break;
                         case ZEND_VM_KIND_GOTO:
                             out($f,$prolog."(void*)&&{$spec_name}_LABEL,\n");
@@ -1433,10 +1465,11 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
               // to handler of undefined opcode
                 switch ($kind) {
                     case ZEND_VM_KIND_CALL:
-                        out($f,$prolog."ZEND_NULL_HANDLER,\n");
+                    case ZEND_VM_KIND_TAILCALL:
+                        out($f,$prolog."ZEND_NULL{$variant}_HANDLER,\n");
                         break;
                     case ZEND_VM_KIND_SWITCH:
-                        out($f,$prolog."(void*)(uintptr_t)-1,\n");
+                        out($f,$prolog."-1,\n");
                         break;
                     case ZEND_VM_KIND_GOTO:
                         out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
@@ -1453,6 +1486,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
                 // Emit pointer to unspecialized handler
                 switch ($kind) {
                 case ZEND_VM_KIND_CALL:
+                case ZEND_VM_KIND_TAILCALL:
                     out($f,$prolog.$dsc['alias']."_HANDLER,\n");
                     break;
                 case ZEND_VM_KIND_GOTO:
@@ -1464,10 +1498,11 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
                 // Emit pointer to unspecialized handler
                 switch ($kind) {
                 case ZEND_VM_KIND_CALL:
+                case ZEND_VM_KIND_TAILCALL:
                     out($f,$prolog.$dsc["op"]."_HANDLER,\n");
                     break;
                 case ZEND_VM_KIND_SWITCH:
-                    out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n");
+                    out($f,$prolog.((string)$num).",\n");
                     break;
                 case ZEND_VM_KIND_GOTO:
                     out($f,$prolog."(void*)&&".$dsc["op"]."_LABEL,\n");
@@ -1477,10 +1512,11 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
             } else {
                 switch ($kind) {
                     case ZEND_VM_KIND_CALL:
-                        out($f,$prolog."ZEND_NULL_HANDLER,\n");
+                    case ZEND_VM_KIND_TAILCALL:
+                        out($f,$prolog."ZEND_NULL{$variant}_HANDLER,\n");
                         break;
                     case ZEND_VM_KIND_SWITCH:
-                        out($f,$prolog."(void*)(uintptr_t)-1,\n");
+                        out($f,$prolog."-1,\n");
                         break;
                     case ZEND_VM_KIND_GOTO:
                         out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
@@ -1496,8 +1532,11 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
         case ZEND_VM_KIND_CALL:
             out($f,$prolog."ZEND_NULL_HANDLER\n");
             break;
+        case ZEND_VM_KIND_TAILCALL:
+            out($f,$prolog."ZEND_NULL_TAILCALL_HANDLER\n");
+            break;
         case ZEND_VM_KIND_SWITCH:
-            out($f,$prolog."(void*)(uintptr_t)-1\n");
+            out($f,$prolog."-1\n");
             break;
         case ZEND_VM_KIND_GOTO:
             out($f,$prolog."(void*)&&ZEND_NULL_LABEL\n");
@@ -1533,22 +1572,36 @@ function gen_specs($f, $prolog, $specs) {
 }
 
 // Generates handler for undefined opcodes (CALL threading model)
-function gen_null_handler($f) {
-    static $done = 0;
-
-    // New and all executors with CALL threading model can use the same handler
-    // for undefined opcodes, do we emit code for it only once
-    if (!$done) {
-        $done = 1;
-        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
-        out($f,"{\n");
-        out($f,"\tUSE_OPLINE\n");
-        out($f,"\n");
-        out($f,"\tSAVE_OPLINE();\n");
-        out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
-        out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
-        out($f,"}\n\n");
+function gen_null_handler($f, $kind) {
+    $cconv = $kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV';
+    $variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
+    out($f,"static ZEND_OPCODE_HANDLER_RET {$cconv} ZEND_NULL{$variant}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+    out($f,"{\n");
+    out($f,"\tUSE_OPLINE\n");
+    out($f,"\n");
+    out($f,"\tSAVE_OPLINE();\n");
+    out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+    out($f,"}\n\n");
+}
+
+function gen_halt_handler($f, $kind) {
+    out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+    out($f,"{\n");
+    out($f,"\treturn (zend_op*) ZEND_VM_ENTER_BIT;\n");
+    out($f,"}\n\n");
+}
+
+function gen_interrupt_func($f, $kind, $spec) {
+    $cconv = $kind === ZEND_VM_KIND_TAILCALL ? 'ZEND_OPCODE_HANDLER_CCONV' : 'ZEND_OPCODE_HANDLER_FUNC_CCONV';
+    $variant = $kind === ZEND_VM_KIND_TAILCALL ? '_TAILCALL' : '';
+    out($f, "static ZEND_COLD zend_never_inline ZEND_OPCODE_HANDLER_RET {$cconv} zend_interrupt{$variant}(ZEND_OPCODE_HANDLER_ARGS) {\n");
+    out($f,"\tSAVE_OPLINE();\n");
+    if ($kind === ZEND_VM_KIND_TAILCALL) {
+        out($f,"\tZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+    } else {
+        out($f, "\treturn &call_interrupt_op;\n");
     }
+    out($f, "}\n");
 }
 
 function extra_spec_name($extra_spec) {
@@ -1671,6 +1724,8 @@ function read_order_file($fn) {
 function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array()) {
     global $list, $opcodes, $helpers, $op_types_ex, $gen_order;
 
+    $delayed_helpers = fopen("php://memory", "w+");
+
     if ($spec) {
         // Produce specialized executor
         $op1t = $op_types_ex;
@@ -1698,7 +1753,13 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
                             if (isset($helpers[$num]["op1"][$op1]) &&
                                 isset($helpers[$num]["op2"][$op2])) {
                               // Generate helper code
-                                gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"], $extra_spec);
+                                if ($kind === ZEND_VM_KIND_TAILCALL && $helpers[$num]["param"] !== null) {
+                                    $out = $delayed_helpers;
+                                    gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"], $extra_spec, signature_only: true);
+                                } else {
+                                    $out = $f;
+                                }
+                                gen_helper($out, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"], $extra_spec);
                             }
                         }
                     } else {
@@ -1722,7 +1783,13 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
             } else if (isset($dsc["helper"])) {
                 $num = $dsc["helper"];
                 // Generate helper code
-                gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"]);
+                if ($kind === ZEND_VM_KIND_TAILCALL && $helpers[$num]["param"] !== null) {
+                    $out = $delayed_helpers;
+                    gen_helper($out, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"], signature_only: true);
+                } else {
+                    $out = $f;
+                }
+                gen_helper($out, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"]);
             } else {
                 var_dump($dsc);
                 die("??? $kind:$num\n");
@@ -1746,17 +1813,23 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
     // Generate handler for undefined opcodes
     switch ($kind) {
         case ZEND_VM_KIND_CALL:
-            gen_null_handler($f);
+            gen_null_handler($f, $kind);
+            out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+            gen_interrupt_func($f, $kind, $spec);
+            out($f, "#endif\n");
+            break;
+        case ZEND_VM_KIND_TAILCALL:
+            gen_null_handler($f, $kind);
+            gen_halt_handler($f, $kind);
+            gen_interrupt_func($f, $kind, $spec);
             break;
         case ZEND_VM_KIND_SWITCH:
             out($f,"default: ZEND_NULL_LABEL:\n");
             out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
-            out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
             break;
         case ZEND_VM_KIND_GOTO:
             out($f,"ZEND_NULL_LABEL:\n");
             out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
-            out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
             break;
         case ZEND_VM_KIND_HYBRID:
             out($f,"\t\t\tHYBRID_CASE(HYBRID_HALT):\n");
@@ -1774,6 +1847,21 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
             out($f,"\t\t\t\tHYBRID_BREAK(); /* Never reached */\n");
             break;
     }
+
+    rewind($delayed_helpers);
+    $delayed_helpers = stream_get_contents($delayed_helpers);
+    if ($delayed_helpers !== '') {
+        out($f, "/* The following helpers can not tailcall due to signature mismatch. Redefine some macros so they do not enforce tailcall. */\n");
+        out($f, "#pragma push_macro(\"ZEND_VM_CONTINUE\")\n");
+        out($f, "#undef  ZEND_VM_CONTINUE\n");
+        out($f, "#pragma push_macro(\"ZEND_VM_INTERRUPT\")\n");
+        out($f, "#undef  ZEND_VM_INTERRUPT\n");
+        out($f, "#define ZEND_VM_CONTINUE(handler) return opline\n");
+        out($f, "#define ZEND_VM_INTERRUPT()       return zend_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)\n");
+        out($f, $delayed_helpers);
+        out($f, "#pragma pop_macro(\"ZEND_VM_INTERRUPT\")\n");
+        out($f, "#pragma pop_macro(\"ZEND_VM_CONTINUE\")\n");
+    }
 }
 
 function skip_blanks($f, $prolog, $epilog) {
@@ -1813,20 +1901,28 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                     out($f,"#define SPEC_RULE_OBSERVER     0x02000000\n");
                     out($f,"\n");
                     out($f,"static const uint32_t *zend_spec_handlers;\n");
-                    out($f,"static const void * const *zend_opcode_handlers;\n");
+                    out($f,"static zend_vm_opcode_handler_t const *zend_opcode_handlers;\n");
                     out($f,"static int zend_handlers_count;\n");
                     if ($kind == ZEND_VM_KIND_HYBRID) {
                         out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
-                        out($f,"static const void * const * zend_opcode_handler_funcs;\n");
+                        out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n");
                         out($f,"static zend_op hybrid_halt_op;\n");
                         out($f,"#endif\n");
                     }
-                    out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
-                    out($f,"static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
+                    if ($kind == ZEND_VM_KIND_HYBRID || $kind == ZEND_VM_KIND_CALL) {
+                        out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n\n");
+                        out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n");
+                        out($f,"#endif\n\n");
+                        out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+                        out($f,"static const zend_op call_interrupt_op;\n");
+                        out($f,"#endif\n\n");
+                    }
+                    out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC\n");
+                    out($f,"static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
                     out($f,"#endif\n\n");
                     if ($kind == ZEND_VM_KIND_HYBRID) {
-                        out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
-                        out($f,"static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op);\n");
+                        out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+                        out($f,"static zend_vm_opcode_handler_func_t zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op);\n");
                         out($f,"#else\n");
                         out($f,"# define zend_vm_get_opcode_handler_func zend_vm_get_opcode_handler\n");
                         out($f,"#endif\n\n");
@@ -1882,11 +1978,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                             out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
                             out($f,"# define ZEND_OPCODE_HANDLER_RET void\n");
                             out($f,"# define ZEND_VM_TAIL_CALL(call) call; return\n");
-                            out($f,"# ifdef ZEND_VM_TAIL_CALL_DISPATCH\n");
-                            out($f,"#  define ZEND_VM_CONTINUE()     ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); return\n");
-                            out($f,"# else\n");
-                            out($f,"#  define ZEND_VM_CONTINUE()     return\n");
-                            out($f,"# endif\n");
+                            out($f,"# define ZEND_VM_CONTINUE()      return\n");
                             if ($kind == ZEND_VM_KIND_HYBRID) {
                                 out($f,"# if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
                                 out($f,"#  define ZEND_VM_RETURN()        opline = &hybrid_halt_op; return\n");
@@ -1911,8 +2003,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                             }
                             out($f,"# define ZEND_VM_COLD            ZEND_COLD ZEND_OPT_SIZE\n");
                             out($f,"#endif\n");
-                            out($f,"\n");
-                            out($f,"typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);\n");
+                            out($f,"#define ZEND_VM_DISPATCH_TO_HELPER(call) ZEND_VM_TAIL_CALL(call)\n");
                             out($f,"\n");
                             out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
                             out($f,"# define DCL_OPLINE\n");
@@ -1950,15 +2041,19 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                             out($f,"# define ZEND_VM_LEAVE()           return (zend_op*)((uintptr_t)opline | ZEND_VM_ENTER_BIT)\n");
                             out($f,"#endif\n");
                             out($f,"#define ZEND_VM_INTERRUPT()      ZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+                            out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
                             out($f,"#define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+                            out($f,"#else\n");
+                            out($f,"#define ZEND_VM_LOOP_INTERRUPT() opline = (zend_op*)((uintptr_t)zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU) & ~ZEND_VM_ENTER_BIT);\n");
+                            out($f,"#endif\n");
                             if ($kind == ZEND_VM_KIND_HYBRID) {
-                                out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler_func(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+                                out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler_func(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
                             } else {
-                                out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+                                out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
                             }
                             out($f,"\n");
-                            out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS);\n");
-                            out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
+                            out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS);\n");
+                            out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
                             out($f,"\n");
                             break;
                         case ZEND_VM_KIND_SWITCH:
@@ -2034,13 +2129,66 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
 //						out($f,"# define ZEND_VM_INTERRUPT()     goto zend_interrupt_helper_SPEC_LABEL\n");
                         out($f,"#endif\n\n");
                     }
+
+                    if ($kind == ZEND_VM_KIND_HYBRID || $kind == ZEND_VM_KIND_CALL) {
+
+                        /* Generate both CALL and TAILCALL handlers.
+                         * TAILCALL handlers are used as zend_vm_opcode_handler_t
+                         * when supported.
+                         * CALL handlers are used as zend_vm_opcode_handler_func_t.
+                         */
+                        out($f,"#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+                        out($f,"\n");
+                        out($f,"# undef ZEND_VM_TAIL_CALL\n");
+                        out($f,"# undef ZEND_VM_CONTINUE\n");
+                        out($f,"# undef ZEND_VM_RETURN\n");
+                        out($f,"# undef ZEND_VM_DISPATCH_TO_HELPER\n");
+                        out($f,"# undef ZEND_VM_INTERRUPT\n");
+                        out($f,"# undef ZEND_VM_ENTER_EX\n");
+                        out($f,"# undef ZEND_VM_LEAVE\n");
+                        out($f,"\n");
+                        out($f,"# define ZEND_VM_TAIL_CALL(call)               ZEND_MUSTTAIL return call\n");
+                        out($f,"# define ZEND_VM_CONTINUE()                    ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))\n");
+                        out($f,"# define ZEND_VM_RETURN()                      opline = &call_halt_op; ZEND_VM_CONTINUE()\n");
+                        out($f,"# define ZEND_VM_DISPATCH_TO_HELPER(call) \\\n");
+                        out($f,"    do { \\\n");
+                        out($f,"        opline = call; \\\n");
+                        out($f,"        ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \\\n");
+                        out($f,"    } while (0)\n");
+                        out($f,"# define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE()\n");
+                        out($f,"# define ZEND_VM_INTERRUPT()        ZEND_VM_TAIL_CALL(zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))\n");
+                        out($f,"# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+                        out($f,"# define ZEND_VM_LEAVE()    ZEND_VM_CONTINUE()\n");
+                        out($f,"\n");
+                        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper".($spec?"_SPEC":"")."_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);\n");
+                        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt(ZEND_OPCODE_HANDLER_ARGS);\n");
+                        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_TAILCALL(ZEND_OPCODE_HANDLER_ARGS);\n");
+                        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
+                        out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
+                        out($f,"static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline);\n");
+                        out($f,"\n");
+                        out($f,"static const zend_op call_halt_op = {\n");
+                        out($f,"    .handler = ZEND_HALT_TAILCALL_HANDLER,\n");
+                        out($f,"};\n");
+                        out($f,"static const zend_op call_leave_op = {\n");
+                        out($f,"    .handler = zend_leave_helper_SPEC_TAILCALL,\n");
+                        out($f,"};\n");
+                        out($f,"static const zend_op call_interrupt_op = {\n");
+                        out($f,"    .handler = zend_interrupt_helper_SPEC_TAILCALL,\n");
+                        out($f,"};\n");
+                        out($f,"\n");
+
+                        gen_executor_code($f, $spec, ZEND_VM_KIND_TAILCALL, $m[1]);
+
+                        out($f,"#endif /* ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL */\n");
+                    }
                     break;
                 case "EXECUTOR_NAME":
                     out($f, $m[1].$executor_name.$m[3]."\n");
                     break;
                 case "HELPER_VARS":
                     if ($kind == ZEND_VM_KIND_SWITCH) {
-                        out($f,$m[1]."const void *dispatch_handler;\n");
+                        out($f,$m[1]."zend_vm_opcode_handler_t dispatch_handler;\n");
                     }
                     if ($kind != ZEND_VM_KIND_CALL && count($params)) {
                         if ($kind == ZEND_VM_KIND_HYBRID) {
@@ -2094,11 +2242,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                         }
                         $prolog = $m[1];
                         out($f,$prolog."if (UNEXPECTED(execute_data == NULL)) {\n");
-                        out($f,$prolog."\tstatic const void * const labels[] = {\n");
+                        out($f,$prolog."\tstatic zend_vm_opcode_handler_t const labels[] = {\n");
                         gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
                         out($f,$prolog."\t};\n");
-                        out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
-                        out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
+                        out($f,$prolog."\tzend_opcode_handlers = (zend_vm_opcode_handler_t*) labels;\n");
+                        out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(labels[0]);\n");
                         if ($kind == ZEND_VM_KIND_HYBRID) {
                             out($f,$prolog."\tmemset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));\n");
                             out($f,$prolog."\thybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;\n");
@@ -2143,10 +2291,10 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                             out($f,"#else /* ZEND_VM_KIND != ZEND_VM_KIND_HYBRID */\n");
                         case ZEND_VM_KIND_CALL:
                             out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
-                            out($f, $m[1]."((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+                            out($f, $m[1]."(OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
                             out($f, $m[1]."if (UNEXPECTED(!OPLINE))".$m[3]."\n");
                             out($f,"#else\n");
-                            out($f, $m[1]."opline = ((opcode_handler_t)opline->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+                            out($f, $m[1]."opline = (opline->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
                             out($f, $m[1]."if (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT)))".$m[3]."\n");
                             out($f,"#endif\n");
                             if ($kind == ZEND_VM_KIND_HYBRID) {
@@ -2194,7 +2342,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                     break;
                 case "EXTERNAL_EXECUTOR":
                     if ($kind == ZEND_VM_KIND_CALL) {
-                        gen_executor_code($f, $spec, $kind, $m[1]);
+                        gen_executor_code($f, $spec, ZEND_VM_KIND_CALL, $m[1]);
                     }
                     break;
                 case "INITIALIZER_NAME":
@@ -2212,25 +2360,38 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
                         out($f,$prolog."zend_spec_handlers = specs;\n");
                         out($f,$prolog.$executor_name."_ex(NULL);\n");
                     } else {
-                        out($f,$prolog."static const void * const labels[] = {\n");
-                        gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
+                        out($f,$prolog."static zend_vm_opcode_handler_func_t const funcs[] = {\n");
+                        gen_labels($f, $spec, ZEND_VM_KIND_CALL, $prolog."\t", $specs);
                         out($f,$prolog."};\n");
+                        out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL || ZEND_VM_KIND == ZEND_VM_KIND_SWITCH\n");
+                        out($f,$prolog."static zend_vm_opcode_handler_t const handlers[] = {\n");
+                        gen_labels($f, $spec, $kind === ZEND_VM_KIND_HYBRID || $kind === ZEND_VM_KIND_CALL ? ZEND_VM_KIND_TAILCALL : $kind, $prolog."\t", $specs, $switch_labels);
+                        out($f,$prolog."};\n");
+                        out($f,$prolog."zend_handlers_count = sizeof(handlers) / sizeof(handlers[0]);\n");
+                        out($f, "#elif ZEND_VM_KIND != ZEND_VM_KIND_HYBRID\n");
+                        out($f,$prolog."static zend_vm_opcode_handler_t const *handlers = funcs;\n");
+                        out($f,$prolog."zend_handlers_count = sizeof(funcs) / sizeof(funcs[0]);\n");
+                        out($f, "#endif\n");
                         out($f,$prolog."static const uint32_t specs[] = {\n");
                         gen_specs($f, $prolog."\t", $specs);
                         out($f,$prolog."};\n");
+                        out($f,"#if 0\n");
                         if ($kind == ZEND_VM_KIND_HYBRID) {
-                            out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
-                            out($f,$prolog."zend_opcode_handler_funcs = labels;\n");
+                            out($f,"#elif (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+                            out($f,$prolog."zend_opcode_handler_funcs = funcs;\n");
                             out($f,$prolog."zend_spec_handlers = specs;\n");
                             out($f,$prolog.$executor_name."_ex(NULL);\n");
-                            out($f,"#else\n");
                         }
-                        out($f,$prolog."zend_opcode_handlers = labels;\n");
-                        out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n");
-                        out($f,$prolog."zend_spec_handlers = specs;\n");
-                        if ($kind == ZEND_VM_KIND_HYBRID) {
-                            out($f,"#endif\n");
+                        if ($kind == ZEND_VM_KIND_HYBRID || $kind == ZEND_VM_KIND_CALL) {
+                            out($f,"#elif ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+                            out($f,$prolog."zend_opcode_handler_funcs = funcs;\n");
+                            out($f,$prolog."zend_opcode_handlers = handlers;\n");
+                            out($f,$prolog."zend_spec_handlers = specs;\n");
                         }
+                        out($f,"#else\n");
+                        out($f,$prolog."zend_opcode_handlers = handlers;\n");
+                        out($f,$prolog."zend_spec_handlers = specs;\n");
+                        out($f,"#endif\n");
                     }
                     break;
                 default:
@@ -2342,16 +2503,34 @@ function gen_vm_opcodes_header(
     $str .= "#define ZEND_VM_KIND_SWITCH\t" . ZEND_VM_KIND_SWITCH . "\n";
     $str .= "#define ZEND_VM_KIND_GOTO\t" . ZEND_VM_KIND_GOTO . "\n";
     $str .= "#define ZEND_VM_KIND_HYBRID\t" . ZEND_VM_KIND_HYBRID . "\n";
-    if ($GLOBALS["vm_kind_name"][ZEND_VM_KIND] === "ZEND_VM_KIND_HYBRID") {
+    $str .= "#define ZEND_VM_KIND_TAILCALL\t" . ZEND_VM_KIND_TAILCALL . "\n";
+    $str .= << $val) {
         $str .= sprintf("#define %-24s 0x%08x\n", $name, $val);
     }
@@ -2579,9 +2782,9 @@ function gen_vm($def, $skel) {
             }
 
             // Store parameters
-            if ((ZEND_VM_KIND == ZEND_VM_KIND_GOTO
-             || ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
-             || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID && $hot))
+            if ((ZEND_VM_GEN_KIND == ZEND_VM_KIND_GOTO
+             || ZEND_VM_GEN_KIND == ZEND_VM_KIND_SWITCH
+             || (ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID && $hot))
              && $param) {
                 foreach (explode(",", $param ) as $p) {
                     $p = trim($p);
@@ -2643,7 +2846,7 @@ function gen_vm($def, $skel) {
                 die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
             }
             $opcodes[$opnames[$dsc['op']]]['alias'] = $op;
-            if (!ZEND_VM_SPEC && ZEND_VM_KIND == ZEND_VM_KIND_SWITCH) {
+            if (!ZEND_VM_SPEC && ZEND_VM_GEN_KIND == ZEND_VM_KIND_SWITCH) {
                 $code = $opnames[$op];
                 $opcodes[$code]['use'] = 1;
             }
@@ -2669,46 +2872,46 @@ function gen_vm($def, $skel) {
 
     // Insert header
     out($f, HEADER_TEXT);
-    fputs($f,"#include \n");
-    fputs($f,"#include \n");
-    fputs($f,"#include \n\n");
+    out($f,"#include \n");
+    out($f,"#include \n");
+    out($f,"#include \n\n");
 
-    fputs($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n");
+    out($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n");
     for ($i = 0; $i <= $max_opcode; $i++) {
-        fputs($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n");
+        out($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n");
     }
-    fputs($f, "};\n\n");
+    out($f, "};\n\n");
 
-    fputs($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n");
+    out($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n");
     for ($i = 0; $i <= $max_opcode; $i++) {
-        fprintf($f, "\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0);
-    }
-    fputs($f, "};\n\n");
-
-    fputs($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) {\n");
-    fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
-    fputs($f, "\t\treturn NULL;\n");
-    fputs($f, "\t}\n");
-    fputs($f, "\treturn zend_vm_opcodes_names[opcode];\n");
-    fputs($f, "}\n");
-
-    fputs($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(uint8_t opcode) {\n");
-    fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
-    fputs($f, "\t\topcode = ZEND_NOP;\n");
-    fputs($f, "\t}\n");
-    fputs($f, "\treturn zend_vm_opcodes_flags[opcode];\n");
-    fputs($f, "}\n");
-
-    fputs($f, "ZEND_API uint8_t zend_get_opcode_id(const char *name, size_t length) {\n");
-    fputs($f, "\tuint8_t opcode;\n");
-    fputs($f, "\tfor (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) {\n");
-    fputs($f, "\t\tconst char *opcode_name = zend_vm_opcodes_names[opcode];\n");
-    fputs($f, "\t\tif (opcode_name && strncmp(opcode_name, name, length) == 0) {\n");
-    fputs($f, "\t\t\treturn opcode;\n");
-    fputs($f, "\t\t}\n");
-    fputs($f, "\t}\n");
-    fputs($f, "\treturn ZEND_VM_LAST_OPCODE + 1;\n");
-    fputs($f, "}\n");
+        out($f, sprintf("\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0));
+    }
+    out($f, "};\n\n");
+
+    out($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) {\n");
+    out($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
+    out($f, "\t\treturn NULL;\n");
+    out($f, "\t}\n");
+    out($f, "\treturn zend_vm_opcodes_names[opcode];\n");
+    out($f, "}\n");
+
+    out($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(uint8_t opcode) {\n");
+    out($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
+    out($f, "\t\topcode = ZEND_NOP;\n");
+    out($f, "\t}\n");
+    out($f, "\treturn zend_vm_opcodes_flags[opcode];\n");
+    out($f, "}\n");
+
+    out($f, "ZEND_API uint8_t zend_get_opcode_id(const char *name, size_t length) {\n");
+    out($f, "\tuint8_t opcode;\n");
+    out($f, "\tfor (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) {\n");
+    out($f, "\t\tconst char *opcode_name = zend_vm_opcodes_names[opcode];\n");
+    out($f, "\t\tif (opcode_name && strncmp(opcode_name, name, length) == 0) {\n");
+    out($f, "\t\t\treturn opcode;\n");
+    out($f, "\t\t}\n");
+    out($f, "\t}\n");
+    out($f, "\treturn ZEND_VM_LAST_OPCODE + 1;\n");
+    out($f, "}\n");
 
     fclose($f);
     echo "zend_vm_opcodes.c generated successfully.\n";
@@ -2756,7 +2959,7 @@ function gen_vm($def, $skel) {
     out($f, "255\n};\n\n");
 
     // Generate specialized executor
-    gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_vm_init");
+    gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_GEN_KIND, "execute", "zend_vm_init");
     out($f, "\n");
 
     // Generate zend_vm_get_opcode_handler() function
@@ -2839,8 +3042,8 @@ function gen_vm($def, $skel) {
         out($f, "\treturn (spec & SPEC_START_MASK) + offset;\n");
     }
     out($f, "}\n\n");
-    out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
-    out($f, "static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n");
+    out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) || !ZEND_VM_SPEC\n");
+    out($f, "static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n");
     out($f, "{\n");
     if (!ZEND_VM_SPEC) {
         out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
@@ -2850,10 +3053,10 @@ function gen_vm($def, $skel) {
     out($f, "}\n");
     out($f, "#endif\n\n");
 
-    if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+    if (ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_GEN_KIND == ZEND_VM_KIND_CALL) {
         // Generate zend_vm_get_opcode_handler_func() function
-        out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n");
-        out($f,"static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op)\n");
+        out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+        out($f,"static zend_vm_opcode_handler_func_t zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op)\n");
         out($f, "{\n");
         out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
         if (!ZEND_VM_SPEC) {
@@ -2961,12 +3164,12 @@ function gen_vm($def, $skel) {
     out($f, "}\n\n");
 
     // Generate zend_vm_call_opcode_handler() function
-    if (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+    if (ZEND_VM_GEN_KIND == ZEND_VM_KIND_CALL || ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID) {
         out($f, "ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
         out($f, "{\n");
-        if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
-            out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
-            out($f, "\topcode_handler_t handler;\n");
+        if (ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID) {
+            out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL)\n");
+            out($f, "\tzend_vm_opcode_handler_func_t handler;\n");
             out($f,"#endif\n");
         }
         out($f, "\tDCL_OPLINE;\n");
@@ -2983,15 +3186,15 @@ function gen_vm($def, $skel) {
         out($f, "\n");
         out($f, "\tLOAD_OPLINE();\n");
         out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
-        if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+        if (ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID) {
             out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
-            out($f, "\thandler = (opcode_handler_t)zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);\n");
+            out($f, "\thandler = zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);\n");
             out($f, "\thandler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
             out($f, "\tif (EXPECTED(opline != &hybrid_halt_op)) {\n");
             out($f,"#else\n");
         }
-        out($f, "\t((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
-        if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+        out($f, "\t(OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+        if (ZEND_VM_GEN_KIND == ZEND_VM_KIND_HYBRID) {
             out($f, "\tif (EXPECTED(opline)) {\n");
             out($f,"#endif\n");
         } else {
@@ -3003,9 +3206,14 @@ function gen_vm($def, $skel) {
         out($f, "\t\tret = -1;\n");
         out($f, "\t}\n");
         out($f, "#else\n");
-        out($f, "\topline = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
-
-        out($f, "if (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT))) {\n");
+        out($f, "# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL\n");
+        out($f, "\thandler = zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);\n");
+        out($f, "\topline = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+        out($f, "# else\n");
+        out($f, "\topline = (OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+        out($f, "# endif\n");
+
+        out($f, "\tif (UNEXPECTED(((uintptr_t)opline & ZEND_VM_ENTER_BIT))) {\n");
         out($f, "\t\topline = (const zend_op*)((uintptr_t)opline & ~ZEND_VM_ENTER_BIT);\n");
         out($f, "\t\tif (EXPECTED(opline)) {\n");
         out($f, "\t\t\t/* ZEND_VM_ENTER() or ZEND_VM_LEAVE() */\n");
@@ -3069,16 +3277,16 @@ function usage() {
         $kind = substr($argv[$i], strlen("--with-vm-kind="));
         switch ($kind) {
             case "CALL":
-                define("ZEND_VM_KIND", ZEND_VM_KIND_CALL);
+                define("ZEND_VM_GEN_KIND", ZEND_VM_KIND_CALL);
                 break;
             case "SWITCH":
-                define("ZEND_VM_KIND", ZEND_VM_KIND_SWITCH);
+                define("ZEND_VM_GEN_KIND", ZEND_VM_KIND_SWITCH);
                 break;
             case "GOTO":
-                define("ZEND_VM_KIND", ZEND_VM_KIND_GOTO);
+                define("ZEND_VM_GEN_KIND", ZEND_VM_KIND_GOTO);
                 break;
             case "HYBRID":
-                define("ZEND_VM_KIND", ZEND_VM_KIND_HYBRID);
+                define("ZEND_VM_GEN_KIND", ZEND_VM_KIND_HYBRID);
                 break;
             default:
                 echo("ERROR: Invalid vm kind '$kind'\n");
@@ -3102,9 +3310,9 @@ function usage() {
 }
 
 // Using defaults
-if (!defined("ZEND_VM_KIND")) {
+if (!defined("ZEND_VM_GEN_KIND")) {
     // Using CALL threading by default
-    define("ZEND_VM_KIND", ZEND_VM_KIND_HYBRID);
+    define("ZEND_VM_GEN_KIND", ZEND_VM_KIND_HYBRID);
 }
 if (!defined("ZEND_VM_SPEC")) {
     // Using specialized executor by default
diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h
index 33d951141550..b1ff354531a5 100644
--- a/Zend/zend_vm_handlers.h
+++ b/Zend/zend_vm_handlers.h
@@ -46,20 +46,13 @@
 	_(73, ZEND_MUL_SPEC_TMPVARCV_TMPVARCV) \
 	_(75, ZEND_MUL_SPEC_TMPVARCV_TMPVARCV) \
 	_(76, ZEND_DIV_SPEC_CONST_CONST) \
-	_(77, ZEND_DIV_SPEC_CONST_TMPVAR) \
-	_(78, ZEND_DIV_SPEC_CONST_TMPVAR) \
+	_(77, ZEND_DIV_SPEC_CONST_TMP) \
 	_(80, ZEND_DIV_SPEC_CONST_CV) \
-	_(81, ZEND_DIV_SPEC_TMPVAR_CONST) \
-	_(82, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \
-	_(83, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \
-	_(85, ZEND_DIV_SPEC_TMPVAR_CV) \
-	_(86, ZEND_DIV_SPEC_TMPVAR_CONST) \
-	_(87, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \
-	_(88, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \
-	_(90, ZEND_DIV_SPEC_TMPVAR_CV) \
+	_(81, ZEND_DIV_SPEC_TMP_CONST) \
+	_(82, ZEND_DIV_SPEC_TMP_TMP) \
+	_(85, ZEND_DIV_SPEC_TMP_CV) \
 	_(96, ZEND_DIV_SPEC_CV_CONST) \
-	_(97, ZEND_DIV_SPEC_CV_TMPVAR) \
-	_(98, ZEND_DIV_SPEC_CV_TMPVAR) \
+	_(97, ZEND_DIV_SPEC_CV_TMP) \
 	_(100, ZEND_DIV_SPEC_CV_CV) \
 	_(101, ZEND_MOD_SPEC_CONST_CONST) \
 	_(102, ZEND_MOD_SPEC_CONST_TMPVARCV) \
@@ -109,20 +102,13 @@
 	_(172, ZEND_SR_SPEC_TMPVARCV_TMPVARCV) \
 	_(173, ZEND_SR_SPEC_TMPVARCV_TMPVARCV) \
 	_(175, ZEND_SR_SPEC_TMPVARCV_TMPVARCV) \
-	_(177, ZEND_CONCAT_SPEC_CONST_TMPVAR) \
-	_(178, ZEND_CONCAT_SPEC_CONST_TMPVAR) \
+	_(177, ZEND_CONCAT_SPEC_CONST_TMP) \
 	_(180, ZEND_CONCAT_SPEC_CONST_CV) \
-	_(181, ZEND_CONCAT_SPEC_TMPVAR_CONST) \
-	_(182, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(183, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(185, ZEND_CONCAT_SPEC_TMPVAR_CV) \
-	_(186, ZEND_CONCAT_SPEC_TMPVAR_CONST) \
-	_(187, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(188, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(190, ZEND_CONCAT_SPEC_TMPVAR_CV) \
+	_(181, ZEND_CONCAT_SPEC_TMP_CONST) \
+	_(182, ZEND_CONCAT_SPEC_TMP_TMP) \
+	_(185, ZEND_CONCAT_SPEC_TMP_CV) \
 	_(196, ZEND_CONCAT_SPEC_CV_CONST) \
-	_(197, ZEND_CONCAT_SPEC_CV_TMPVAR) \
-	_(198, ZEND_CONCAT_SPEC_CV_TMPVAR) \
+	_(197, ZEND_CONCAT_SPEC_CV_TMP) \
 	_(200, ZEND_CONCAT_SPEC_CV_CV) \
 	_(201, ZEND_BW_OR_SPEC_CONST_CONST) \
 	_(206, ZEND_BW_OR_SPEC_TMPVARCV_CONST) \
@@ -164,123 +150,72 @@
 	_(273, ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV) \
 	_(275, ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV) \
 	_(276, ZEND_POW_SPEC_CONST_CONST) \
-	_(277, ZEND_POW_SPEC_CONST_TMPVAR) \
-	_(278, ZEND_POW_SPEC_CONST_TMPVAR) \
+	_(277, ZEND_POW_SPEC_CONST_TMP) \
 	_(280, ZEND_POW_SPEC_CONST_CV) \
-	_(281, ZEND_POW_SPEC_TMPVAR_CONST) \
-	_(282, ZEND_POW_SPEC_TMPVAR_TMPVAR) \
-	_(283, ZEND_POW_SPEC_TMPVAR_TMPVAR) \
-	_(285, ZEND_POW_SPEC_TMPVAR_CV) \
-	_(286, ZEND_POW_SPEC_TMPVAR_CONST) \
-	_(287, ZEND_POW_SPEC_TMPVAR_TMPVAR) \
-	_(288, ZEND_POW_SPEC_TMPVAR_TMPVAR) \
-	_(290, ZEND_POW_SPEC_TMPVAR_CV) \
+	_(281, ZEND_POW_SPEC_TMP_CONST) \
+	_(282, ZEND_POW_SPEC_TMP_TMP) \
+	_(285, ZEND_POW_SPEC_TMP_CV) \
 	_(296, ZEND_POW_SPEC_CV_CONST) \
-	_(297, ZEND_POW_SPEC_CV_TMPVAR) \
-	_(298, ZEND_POW_SPEC_CV_TMPVAR) \
+	_(297, ZEND_POW_SPEC_CV_TMP) \
 	_(300, ZEND_POW_SPEC_CV_CV) \
 	_(301, ZEND_BW_NOT_SPEC_CONST) \
 	_(302, ZEND_BW_NOT_SPEC_TMPVARCV) \
 	_(303, ZEND_BW_NOT_SPEC_TMPVARCV) \
 	_(305, ZEND_BW_NOT_SPEC_TMPVARCV) \
 	_(306, ZEND_BOOL_NOT_SPEC_CONST) \
-	_(307, ZEND_BOOL_NOT_SPEC_TMPVAR) \
-	_(308, ZEND_BOOL_NOT_SPEC_TMPVAR) \
+	_(307, ZEND_BOOL_NOT_SPEC_TMP) \
 	_(310, ZEND_BOOL_NOT_SPEC_CV) \
 	_(311, ZEND_BOOL_XOR_SPEC_CONST_CONST) \
-	_(316, ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) \
-	_(317, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \
-	_(318, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \
-	_(321, ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) \
-	_(322, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \
-	_(323, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \
+	_(316, ZEND_BOOL_XOR_SPEC_TMP_CONST) \
+	_(317, ZEND_BOOL_XOR_SPEC_TMP_TMP) \
 	_(331, ZEND_BOOL_XOR_SPEC_CV_CONST) \
-	_(332, ZEND_BOOL_XOR_SPEC_CV_TMPVAR) \
-	_(333, ZEND_BOOL_XOR_SPEC_CV_TMPVAR) \
+	_(332, ZEND_BOOL_XOR_SPEC_CV_TMP) \
 	_(335, ZEND_BOOL_XOR_SPEC_CV_CV) \
 	_(336, ZEND_IS_IDENTICAL_SPEC_CONST_CONST) \
 	_(341, ZEND_IS_IDENTICAL_SPEC_TMP_CONST) \
 	_(342, ZEND_IS_IDENTICAL_SPEC_TMP_TMP) \
-	_(346, ZEND_IS_IDENTICAL_SPEC_VAR_CONST) \
-	_(347, ZEND_IS_IDENTICAL_SPEC_VAR_TMP) \
-	_(348, ZEND_IS_IDENTICAL_SPEC_VAR_VAR) \
 	_(356, ZEND_IS_IDENTICAL_SPEC_CV_CONST) \
 	_(357, ZEND_IS_IDENTICAL_SPEC_CV_TMP) \
-	_(358, ZEND_IS_IDENTICAL_SPEC_CV_VAR) \
 	_(360, ZEND_IS_IDENTICAL_SPEC_CV_CV) \
 	_(361, ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST) \
 	_(366, ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST) \
 	_(367, ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP) \
-	_(371, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST) \
-	_(372, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP) \
-	_(373, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR) \
 	_(381, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST) \
 	_(382, ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP) \
-	_(383, ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR) \
 	_(385, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV) \
 	_(386, ZEND_IS_EQUAL_SPEC_CONST_CONST) \
 	_(387, ZEND_IS_EQUAL_SPEC_CONST_CONST) \
 	_(388, ZEND_IS_EQUAL_SPEC_CONST_CONST) \
-	_(401, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST) \
-	_(402, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \
-	_(403, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \
-	_(404, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(405, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(406, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
-	_(407, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(408, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(409, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
-	_(416, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST) \
-	_(417, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \
-	_(418, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \
-	_(419, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(420, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(421, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
-	_(422, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(423, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(424, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
+	_(401, ZEND_IS_EQUAL_SPEC_TMP_CONST) \
+	_(402, ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ) \
+	_(403, ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ) \
+	_(404, ZEND_IS_EQUAL_SPEC_TMP_TMP) \
+	_(405, ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ) \
+	_(406, ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ) \
 	_(446, ZEND_IS_EQUAL_SPEC_CV_CONST) \
 	_(447, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ) \
 	_(448, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ) \
-	_(449, ZEND_IS_EQUAL_SPEC_CV_TMPVAR) \
-	_(450, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ) \
-	_(451, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \
-	_(452, ZEND_IS_EQUAL_SPEC_CV_TMPVAR) \
-	_(453, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ) \
-	_(454, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \
+	_(449, ZEND_IS_EQUAL_SPEC_CV_TMP) \
+	_(450, ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ) \
+	_(451, ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ) \
 	_(458, ZEND_IS_EQUAL_SPEC_CV_CV) \
 	_(459, ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ) \
 	_(460, ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ) \
 	_(461, ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST) \
 	_(462, ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST) \
 	_(463, ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST) \
-	_(476, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST) \
-	_(477, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \
-	_(478, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \
-	_(479, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(480, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(481, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
-	_(482, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(483, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(484, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
-	_(491, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST) \
-	_(492, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \
-	_(493, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \
-	_(494, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(495, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(496, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
-	_(497, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \
-	_(498, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \
-	_(499, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \
+	_(476, ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST) \
+	_(477, ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ) \
+	_(478, ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ) \
+	_(479, ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP) \
+	_(480, ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ) \
+	_(481, ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ) \
 	_(521, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST) \
 	_(522, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ) \
 	_(523, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ) \
-	_(524, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR) \
-	_(525, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ) \
-	_(526, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \
-	_(527, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR) \
-	_(528, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ) \
-	_(529, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \
+	_(524, ZEND_IS_NOT_EQUAL_SPEC_CV_TMP) \
+	_(525, ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ) \
+	_(526, ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ) \
 	_(533, ZEND_IS_NOT_EQUAL_SPEC_CV_CV) \
 	_(534, ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ) \
 	_(535, ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ) \
@@ -384,139 +319,90 @@
 	_(707, ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED) \
 	_(708, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED) \
 	_(709, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED) \
-	_(710, ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED) \
-	_(711, ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED) \
 	_(714, ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED) \
 	_(715, ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED) \
 	_(726, ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED) \
 	_(727, ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED) \
 	_(728, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED) \
 	_(729, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED) \
-	_(730, ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED) \
-	_(731, ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED) \
 	_(734, ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED) \
 	_(735, ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED) \
 	_(786, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST) \
 	_(787, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP) \
-	_(788, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR) \
 	_(790, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV) \
-	_(791, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST) \
-	_(792, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP) \
-	_(793, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR) \
-	_(795, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV) \
-	_(796, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST) \
-	_(797, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP) \
-	_(798, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR) \
-	_(800, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV) \
+	_(791, ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST) \
+	_(792, ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP) \
+	_(795, ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV) \
 	_(801, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST) \
 	_(802, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP) \
-	_(803, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR) \
 	_(805, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV) \
 	_(806, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST) \
 	_(807, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP) \
-	_(808, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR) \
 	_(810, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV) \
 	_(836, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST) \
 	_(837, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP) \
-	_(838, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR) \
 	_(840, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV) \
-	_(841, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST) \
-	_(842, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP) \
-	_(843, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR) \
-	_(845, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV) \
-	_(846, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST) \
-	_(847, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP) \
-	_(848, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR) \
-	_(850, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV) \
+	_(841, ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST) \
+	_(842, ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP) \
+	_(845, ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV) \
 	_(851, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST) \
 	_(852, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP) \
-	_(853, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR) \
 	_(855, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV) \
 	_(856, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST) \
 	_(857, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP) \
-	_(858, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR) \
 	_(860, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV) \
 	_(911, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST) \
 	_(912, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP) \
-	_(913, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR) \
 	_(915, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV) \
-	_(916, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST) \
-	_(917, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP) \
-	_(918, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR) \
-	_(920, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV) \
-	_(921, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST) \
-	_(922, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP) \
-	_(923, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR) \
-	_(925, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV) \
+	_(916, ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST) \
+	_(917, ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP) \
+	_(920, ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV) \
 	_(931, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST) \
 	_(932, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP) \
-	_(933, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR) \
 	_(935, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV) \
 	_(936, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST) \
 	_(937, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP) \
-	_(938, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR) \
 	_(940, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV) \
-	_(941, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST) \
-	_(942, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP) \
-	_(943, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \
-	_(945, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \
-	_(946, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST) \
-	_(947, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP) \
-	_(948, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \
-	_(950, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \
+	_(941, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST) \
+	_(942, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP) \
+	_(945, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV) \
 	_(956, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST) \
 	_(957, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP) \
-	_(958, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR) \
 	_(960, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV) \
 	_(961, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST) \
 	_(962, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP) \
-	_(963, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR) \
 	_(965, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV) \
-	_(966, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST) \
-	_(967, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP) \
-	_(968, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR) \
-	_(970, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV) \
-	_(971, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST) \
-	_(972, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP) \
-	_(973, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR) \
-	_(975, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV) \
+	_(966, ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST) \
+	_(967, ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP) \
+	_(970, ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV) \
 	_(981, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST) \
 	_(982, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP) \
-	_(983, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR) \
 	_(985, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV) \
 	_(986, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST) \
 	_(987, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP) \
-	_(988, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR) \
 	_(990, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV) \
 	_(1001, ZEND_ASSIGN_OP_SPEC_VAR_CONST) \
-	_(1002, ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR) \
-	_(1003, ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR) \
+	_(1002, ZEND_ASSIGN_OP_SPEC_VAR_TMP) \
 	_(1005, ZEND_ASSIGN_OP_SPEC_VAR_CV) \
 	_(1011, ZEND_ASSIGN_OP_SPEC_CV_CONST) \
-	_(1012, ZEND_ASSIGN_OP_SPEC_CV_TMPVAR) \
-	_(1013, ZEND_ASSIGN_OP_SPEC_CV_TMPVAR) \
+	_(1012, ZEND_ASSIGN_OP_SPEC_CV_TMP) \
 	_(1015, ZEND_ASSIGN_OP_SPEC_CV_CV) \
 	_(1026, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST) \
-	_(1027, ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR) \
-	_(1028, ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR) \
+	_(1027, ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP) \
 	_(1029, ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED) \
 	_(1030, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV) \
 	_(1036, ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST) \
-	_(1037, ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR) \
-	_(1038, ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR) \
+	_(1037, ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP) \
 	_(1039, ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED) \
 	_(1040, ZEND_ASSIGN_DIM_OP_SPEC_CV_CV) \
 	_(1051, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST) \
-	_(1052, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR) \
-	_(1053, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR) \
+	_(1052, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP) \
 	_(1055, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV) \
 	_(1056, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST) \
-	_(1057, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR) \
-	_(1058, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR) \
+	_(1057, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP) \
 	_(1060, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV) \
 	_(1061, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST) \
-	_(1062, ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR) \
-	_(1063, ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR) \
+	_(1062, ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP) \
 	_(1065, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV) \
 	_(1066, ZEND_ASSIGN_STATIC_PROP_OP_SPEC) \
 	_(1079, ZEND_ASSIGN_REF_SPEC_VAR_VAR) \
@@ -529,26 +415,20 @@
 	_(1096, ZEND_QM_ASSIGN_SPEC_CV) \
 	_(1149, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR) \
 	_(1151, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV) \
-	_(1154, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR) \
-	_(1156, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV) \
-	_(1159, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR) \
-	_(1161, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV) \
+	_(1154, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR) \
+	_(1156, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV) \
 	_(1169, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR) \
 	_(1171, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV) \
 	_(1174, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR) \
 	_(1176, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV) \
-	_(1179, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \
-	_(1181, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \
-	_(1184, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \
-	_(1186, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \
+	_(1179, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR) \
+	_(1181, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV) \
 	_(1194, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR) \
 	_(1196, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV) \
 	_(1199, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR) \
 	_(1201, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV) \
-	_(1204, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR) \
-	_(1206, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV) \
-	_(1209, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR) \
-	_(1211, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV) \
+	_(1204, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR) \
+	_(1206, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV) \
 	_(1219, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR) \
 	_(1221, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV) \
 	_(1222, ZEND_ASSIGN_STATIC_PROP_REF_SPEC) \
@@ -568,25 +448,20 @@
 	_(1254, ZEND_POST_INC_STATIC_PROP_SPEC) \
 	_(1255, ZEND_JMP_SPEC) \
 	_(1256, ZEND_JMPZ_SPEC_CONST) \
-	_(1257, ZEND_JMPZ_SPEC_TMPVAR) \
-	_(1258, ZEND_JMPZ_SPEC_TMPVAR) \
+	_(1257, ZEND_JMPZ_SPEC_TMP) \
 	_(1260, ZEND_JMPZ_SPEC_CV) \
 	_(1261, ZEND_JMPNZ_SPEC_CONST) \
-	_(1262, ZEND_JMPNZ_SPEC_TMPVAR) \
-	_(1263, ZEND_JMPNZ_SPEC_TMPVAR) \
+	_(1262, ZEND_JMPNZ_SPEC_TMP) \
 	_(1265, ZEND_JMPNZ_SPEC_CV) \
 	_(1266, ZEND_JMPZ_EX_SPEC_CONST) \
-	_(1267, ZEND_JMPZ_EX_SPEC_TMPVAR) \
-	_(1268, ZEND_JMPZ_EX_SPEC_TMPVAR) \
+	_(1267, ZEND_JMPZ_EX_SPEC_TMP) \
 	_(1270, ZEND_JMPZ_EX_SPEC_CV) \
 	_(1271, ZEND_JMPNZ_EX_SPEC_CONST) \
-	_(1272, ZEND_JMPNZ_EX_SPEC_TMPVAR) \
-	_(1273, ZEND_JMPNZ_EX_SPEC_TMPVAR) \
+	_(1272, ZEND_JMPNZ_EX_SPEC_TMP) \
 	_(1275, ZEND_JMPNZ_EX_SPEC_CV) \
-	_(1276, ZEND_CASE_SPEC_TMPVAR_CONST) \
-	_(1277, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \
-	_(1278, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \
-	_(1280, ZEND_CASE_SPEC_TMPVAR_CV) \
+	_(1276, ZEND_CASE_SPEC_TMP_CONST) \
+	_(1277, ZEND_CASE_SPEC_TMP_TMP) \
+	_(1280, ZEND_CASE_SPEC_TMP_CV) \
 	_(1281, ZEND_CHECK_VAR_SPEC_CV_UNUSED) \
 	_(1282, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \
 	_(1283, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \
@@ -594,39 +469,27 @@
 	_(1289, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK) \
 	_(1292, ZEND_CAST_SPEC_CONST) \
 	_(1293, ZEND_CAST_SPEC_TMP) \
-	_(1294, ZEND_CAST_SPEC_VAR) \
 	_(1296, ZEND_CAST_SPEC_CV) \
 	_(1297, ZEND_BOOL_SPEC_CONST) \
-	_(1298, ZEND_BOOL_SPEC_TMPVAR) \
-	_(1299, ZEND_BOOL_SPEC_TMPVAR) \
+	_(1298, ZEND_BOOL_SPEC_TMP) \
 	_(1301, ZEND_BOOL_SPEC_CV) \
 	_(1302, ZEND_FAST_CONCAT_SPEC_CONST_CONST) \
-	_(1303, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \
-	_(1304, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \
+	_(1303, ZEND_FAST_CONCAT_SPEC_CONST_TMP) \
 	_(1306, ZEND_FAST_CONCAT_SPEC_CONST_CV) \
-	_(1307, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \
-	_(1308, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(1309, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(1311, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \
-	_(1312, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \
-	_(1313, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(1314, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \
-	_(1316, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \
+	_(1307, ZEND_FAST_CONCAT_SPEC_TMP_CONST) \
+	_(1308, ZEND_FAST_CONCAT_SPEC_TMP_TMP) \
+	_(1311, ZEND_FAST_CONCAT_SPEC_TMP_CV) \
 	_(1322, ZEND_FAST_CONCAT_SPEC_CV_CONST) \
-	_(1323, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \
-	_(1324, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \
+	_(1323, ZEND_FAST_CONCAT_SPEC_CV_TMP) \
 	_(1326, ZEND_FAST_CONCAT_SPEC_CV_CV) \
 	_(1327, ZEND_ROPE_INIT_SPEC_UNUSED_CONST) \
-	_(1328, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \
-	_(1329, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \
+	_(1328, ZEND_ROPE_INIT_SPEC_UNUSED_TMP) \
 	_(1331, ZEND_ROPE_INIT_SPEC_UNUSED_CV) \
 	_(1332, ZEND_ROPE_ADD_SPEC_TMP_CONST) \
-	_(1333, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \
-	_(1334, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \
+	_(1333, ZEND_ROPE_ADD_SPEC_TMP_TMP) \
 	_(1336, ZEND_ROPE_ADD_SPEC_TMP_CV) \
 	_(1337, ZEND_ROPE_END_SPEC_TMP_CONST) \
-	_(1338, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \
-	_(1339, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \
+	_(1338, ZEND_ROPE_END_SPEC_TMP_TMP) \
 	_(1341, ZEND_ROPE_END_SPEC_TMP_CV) \
 	_(1342, ZEND_BEGIN_SILENCE_SPEC) \
 	_(1343, ZEND_END_SILENCE_SPEC_TMP) \
@@ -640,8 +503,6 @@
 	_(1351, ZEND_RETURN_SPEC_OBSERVER) \
 	_(1352, ZEND_RETURN_SPEC_TMP) \
 	_(1353, ZEND_RETURN_SPEC_OBSERVER) \
-	_(1354, ZEND_RETURN_SPEC_VAR) \
-	_(1355, ZEND_RETURN_SPEC_OBSERVER) \
 	_(1358, ZEND_RETURN_SPEC_CV) \
 	_(1359, ZEND_RETURN_SPEC_OBSERVER) \
 	_(1360, ZEND_RECV_SPEC_UNUSED) \
@@ -670,56 +531,45 @@
 	_(1467, ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST) \
 	_(1468, ZEND_FREE_SPEC_TMPVAR) \
 	_(1469, ZEND_INIT_ARRAY_SPEC_CONST_CONST) \
-	_(1470, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \
-	_(1471, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \
+	_(1470, ZEND_INIT_ARRAY_SPEC_CONST_TMP) \
 	_(1472, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED) \
 	_(1473, ZEND_INIT_ARRAY_SPEC_CONST_CV) \
 	_(1474, ZEND_INIT_ARRAY_SPEC_TMP_CONST) \
-	_(1475, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \
-	_(1476, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \
+	_(1475, ZEND_INIT_ARRAY_SPEC_TMP_TMP) \
 	_(1477, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED) \
 	_(1478, ZEND_INIT_ARRAY_SPEC_TMP_CV) \
 	_(1479, ZEND_INIT_ARRAY_SPEC_VAR_CONST) \
-	_(1480, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \
-	_(1481, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \
+	_(1480, ZEND_INIT_ARRAY_SPEC_VAR_TMP) \
 	_(1482, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED) \
 	_(1483, ZEND_INIT_ARRAY_SPEC_VAR_CV) \
 	_(1484, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) \
-	_(1485, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \
-	_(1486, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \
+	_(1485, ZEND_INIT_ARRAY_SPEC_UNUSED_TMP) \
 	_(1487, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) \
 	_(1488, ZEND_INIT_ARRAY_SPEC_UNUSED_CV) \
 	_(1489, ZEND_INIT_ARRAY_SPEC_CV_CONST) \
-	_(1490, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \
-	_(1491, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \
+	_(1490, ZEND_INIT_ARRAY_SPEC_CV_TMP) \
 	_(1492, ZEND_INIT_ARRAY_SPEC_CV_UNUSED) \
 	_(1493, ZEND_INIT_ARRAY_SPEC_CV_CV) \
 	_(1494, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST) \
-	_(1495, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \
-	_(1496, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \
+	_(1495, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP) \
 	_(1497, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED) \
 	_(1498, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV) \
 	_(1499, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST) \
-	_(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \
-	_(1501, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \
+	_(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP) \
 	_(1502, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED) \
 	_(1503, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV) \
 	_(1504, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST) \
-	_(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \
-	_(1506, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \
+	_(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP) \
 	_(1507, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED) \
 	_(1508, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV) \
 	_(1514, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST) \
-	_(1515, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \
-	_(1516, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \
+	_(1515, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP) \
 	_(1517, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED) \
 	_(1518, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV) \
 	_(1519, ZEND_INCLUDE_OR_EVAL_SPEC_CONST) \
 	_(1520, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \
-	_(1521, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \
+	_(1521, ZEND_INCLUDE_OR_EVAL_SPEC_TMP) \
 	_(1522, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \
-	_(1523, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \
-	_(1524, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \
 	_(1527, ZEND_INCLUDE_OR_EVAL_SPEC_CV) \
 	_(1528, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \
 	_(1529, ZEND_UNSET_VAR_SPEC_CONST_UNUSED) \
@@ -727,245 +577,187 @@
 	_(1531, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \
 	_(1533, ZEND_UNSET_VAR_SPEC_CV_UNUSED) \
 	_(1544, ZEND_UNSET_DIM_SPEC_VAR_CONST) \
-	_(1545, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \
-	_(1546, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \
+	_(1545, ZEND_UNSET_DIM_SPEC_VAR_TMP) \
 	_(1548, ZEND_UNSET_DIM_SPEC_VAR_CV) \
 	_(1554, ZEND_UNSET_DIM_SPEC_CV_CONST) \
-	_(1555, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \
-	_(1556, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \
+	_(1555, ZEND_UNSET_DIM_SPEC_CV_TMP) \
 	_(1558, ZEND_UNSET_DIM_SPEC_CV_CV) \
 	_(1569, ZEND_UNSET_OBJ_SPEC_VAR_CONST) \
-	_(1570, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \
-	_(1571, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \
+	_(1570, ZEND_UNSET_OBJ_SPEC_VAR_TMP) \
 	_(1573, ZEND_UNSET_OBJ_SPEC_VAR_CV) \
 	_(1574, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST) \
-	_(1575, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \
-	_(1576, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \
+	_(1575, ZEND_UNSET_OBJ_SPEC_UNUSED_TMP) \
 	_(1578, ZEND_UNSET_OBJ_SPEC_UNUSED_CV) \
 	_(1579, ZEND_UNSET_OBJ_SPEC_CV_CONST) \
-	_(1580, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \
-	_(1581, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \
+	_(1580, ZEND_UNSET_OBJ_SPEC_CV_TMP) \
 	_(1583, ZEND_UNSET_OBJ_SPEC_CV_CV) \
 	_(1584, ZEND_FE_RESET_R_SPEC_CONST) \
 	_(1585, ZEND_FE_RESET_R_SPEC_TMP) \
-	_(1586, ZEND_FE_RESET_R_SPEC_VAR) \
 	_(1588, ZEND_FE_RESET_R_SPEC_CV) \
-	_(1589, ZEND_FE_FETCH_R_SPEC_VAR) \
+	_(1589, ZEND_FE_FETCH_R_SPEC_TMP) \
 	_(1590, ZEND_FETCH_R_SPEC_CONST_UNUSED) \
-	_(1591, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \
-	_(1592, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \
+	_(1591, ZEND_FETCH_R_SPEC_TMP_UNUSED) \
 	_(1594, ZEND_FETCH_R_SPEC_CV_UNUSED) \
 	_(1595, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \
-	_(1596, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \
-	_(1597, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \
+	_(1596, ZEND_FETCH_DIM_R_SPEC_CONST_TMP) \
 	_(1599, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \
 	_(1600, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \
-	_(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \
-	_(1602, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \
+	_(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP) \
 	_(1604, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \
 	_(1605, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \
-	_(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \
-	_(1607, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \
+	_(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP) \
 	_(1609, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \
 	_(1615, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \
-	_(1616, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \
-	_(1617, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \
+	_(1616, ZEND_FETCH_DIM_R_SPEC_CV_TMP) \
 	_(1619, ZEND_FETCH_DIM_R_SPEC_CV_CV) \
 	_(1620, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \
-	_(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \
-	_(1622, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \
+	_(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_TMP) \
 	_(1624, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \
 	_(1625, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \
-	_(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \
-	_(1627, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \
+	_(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP) \
 	_(1629, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \
 	_(1630, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \
-	_(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \
-	_(1632, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \
+	_(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP) \
 	_(1634, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \
 	_(1635, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \
-	_(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \
-	_(1637, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \
+	_(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP) \
 	_(1639, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \
 	_(1640, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \
-	_(1641, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \
-	_(1642, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \
+	_(1641, ZEND_FETCH_OBJ_R_SPEC_CV_TMP) \
 	_(1644, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \
 	_(1645, ZEND_FETCH_W_SPEC_CONST_UNUSED) \
-	_(1646, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \
-	_(1647, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \
+	_(1646, ZEND_FETCH_W_SPEC_TMP_UNUSED) \
 	_(1649, ZEND_FETCH_W_SPEC_CV_UNUSED) \
 	_(1660, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \
-	_(1661, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \
-	_(1662, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \
+	_(1661, ZEND_FETCH_DIM_W_SPEC_VAR_TMP) \
 	_(1663, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \
 	_(1664, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \
 	_(1670, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \
-	_(1671, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \
-	_(1672, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \
+	_(1671, ZEND_FETCH_DIM_W_SPEC_CV_TMP) \
 	_(1673, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \
 	_(1674, ZEND_FETCH_DIM_W_SPEC_CV_CV) \
 	_(1685, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \
-	_(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \
-	_(1687, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \
+	_(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_TMP) \
 	_(1689, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \
 	_(1690, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \
-	_(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \
-	_(1692, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \
+	_(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP) \
 	_(1694, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \
 	_(1695, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \
-	_(1696, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \
-	_(1697, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \
+	_(1696, ZEND_FETCH_OBJ_W_SPEC_CV_TMP) \
 	_(1699, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \
 	_(1700, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \
-	_(1701, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \
-	_(1702, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \
+	_(1701, ZEND_FETCH_RW_SPEC_TMP_UNUSED) \
 	_(1704, ZEND_FETCH_RW_SPEC_CV_UNUSED) \
 	_(1715, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \
-	_(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \
-	_(1717, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \
+	_(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_TMP) \
 	_(1718, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \
 	_(1719, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \
 	_(1725, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \
-	_(1726, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \
-	_(1727, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \
+	_(1726, ZEND_FETCH_DIM_RW_SPEC_CV_TMP) \
 	_(1728, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \
 	_(1729, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \
 	_(1740, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \
-	_(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \
-	_(1742, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \
+	_(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP) \
 	_(1744, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \
 	_(1745, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \
-	_(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \
-	_(1747, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \
+	_(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP) \
 	_(1749, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \
 	_(1750, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \
-	_(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \
-	_(1752, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \
+	_(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_TMP) \
 	_(1754, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \
 	_(1755, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \
-	_(1756, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \
-	_(1757, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \
+	_(1756, ZEND_FETCH_IS_SPEC_TMP_UNUSED) \
 	_(1759, ZEND_FETCH_IS_SPEC_CV_UNUSED) \
 	_(1760, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \
-	_(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \
-	_(1762, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \
+	_(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_TMP) \
 	_(1764, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \
 	_(1765, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \
-	_(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \
-	_(1767, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \
+	_(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP) \
 	_(1769, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \
 	_(1770, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \
-	_(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \
-	_(1772, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \
+	_(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP) \
 	_(1774, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \
 	_(1780, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \
-	_(1781, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \
-	_(1782, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \
+	_(1781, ZEND_FETCH_DIM_IS_SPEC_CV_TMP) \
 	_(1784, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \
 	_(1785, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \
-	_(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \
-	_(1787, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \
+	_(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP) \
 	_(1789, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \
 	_(1790, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \
-	_(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \
-	_(1792, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \
+	_(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP) \
 	_(1794, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \
 	_(1795, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \
-	_(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \
-	_(1797, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \
+	_(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP) \
 	_(1799, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \
 	_(1800, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \
-	_(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \
-	_(1802, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \
+	_(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP) \
 	_(1804, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \
 	_(1805, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \
-	_(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \
-	_(1807, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \
+	_(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_TMP) \
 	_(1809, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \
 	_(1810, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \
-	_(1811, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \
-	_(1812, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \
+	_(1811, ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED) \
 	_(1814, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \
 	_(1815, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \
-	_(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \
-	_(1817, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \
+	_(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP) \
 	_(1818, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \
 	_(1819, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \
 	_(1820, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \
-	_(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \
-	_(1822, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \
+	_(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP) \
 	_(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \
 	_(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \
 	_(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \
-	_(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \
-	_(1827, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \
+	_(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP) \
 	_(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \
 	_(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \
 	_(1835, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \
-	_(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \
-	_(1837, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \
+	_(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP) \
 	_(1838, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \
 	_(1839, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \
 	_(1840, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \
-	_(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \
-	_(1842, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \
+	_(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP) \
 	_(1844, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \
 	_(1845, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \
-	_(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \
-	_(1847, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \
+	_(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP) \
 	_(1849, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \
 	_(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \
-	_(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \
-	_(1852, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \
+	_(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP) \
 	_(1854, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \
 	_(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \
-	_(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \
-	_(1857, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \
+	_(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP) \
 	_(1859, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \
 	_(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \
-	_(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \
-	_(1862, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \
+	_(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP) \
 	_(1864, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \
 	_(1865, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \
-	_(1866, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \
-	_(1867, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \
+	_(1866, ZEND_FETCH_UNSET_SPEC_TMP_UNUSED) \
 	_(1869, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \
 	_(1880, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \
-	_(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \
-	_(1882, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \
+	_(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP) \
 	_(1884, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \
 	_(1890, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \
-	_(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \
-	_(1892, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \
+	_(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP) \
 	_(1894, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \
 	_(1905, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \
-	_(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \
-	_(1907, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \
+	_(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP) \
 	_(1909, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \
 	_(1910, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \
-	_(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \
-	_(1912, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \
+	_(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP) \
 	_(1914, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \
 	_(1915, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \
-	_(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \
-	_(1917, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \
+	_(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP) \
 	_(1919, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \
 	_(1920, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \
-	_(1921, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \
-	_(1922, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \
+	_(1921, ZEND_FETCH_LIST_R_SPEC_CONST_TMP) \
 	_(1924, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \
 	_(1925, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \
-	_(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \
-	_(1927, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \
+	_(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) \
 	_(1929, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \
 	_(1930, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \
-	_(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \
-	_(1932, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \
+	_(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) \
 	_(1934, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \
 	_(1940, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \
-	_(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \
-	_(1942, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \
+	_(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) \
 	_(1944, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \
 	_(1945, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \
 	_(1946, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \
@@ -980,901 +772,827 @@
 	_(1961, ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST) \
 	_(1964, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \
 	_(1966, ZEND_CATCH_SPEC_CONST) \
-	_(1967, ZEND_THROW_SPEC_CONST) \
-	_(1968, ZEND_THROW_SPEC_TMPVAR) \
-	_(1969, ZEND_THROW_SPEC_TMPVAR) \
-	_(1971, ZEND_THROW_SPEC_CV) \
-	_(1972, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \
-	_(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \
-	_(1974, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \
-	_(1975, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \
-	_(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \
-	_(1977, ZEND_CLONE_SPEC_CONST) \
-	_(1978, ZEND_CLONE_SPEC_TMPVAR) \
-	_(1979, ZEND_CLONE_SPEC_TMPVAR) \
-	_(1980, ZEND_CLONE_SPEC_UNUSED) \
-	_(1981, ZEND_CLONE_SPEC_CV) \
-	_(1982, ZEND_RETURN_BY_REF_SPEC_CONST) \
-	_(1983, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \
-	_(1984, ZEND_RETURN_BY_REF_SPEC_TMP) \
-	_(1985, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \
-	_(1986, ZEND_RETURN_BY_REF_SPEC_VAR) \
+	_(1969, ZEND_CATCH_SPEC_UNUSED) \
+	_(1971, ZEND_THROW_SPEC_CONST) \
+	_(1972, ZEND_THROW_SPEC_TMP) \
+	_(1975, ZEND_THROW_SPEC_CV) \
+	_(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \
+	_(1977, ZEND_FETCH_CLASS_SPEC_UNUSED_TMP) \
+	_(1979, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \
+	_(1980, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \
+	_(1981, ZEND_CLONE_SPEC_CONST) \
+	_(1982, ZEND_CLONE_SPEC_TMP) \
+	_(1984, ZEND_CLONE_SPEC_UNUSED) \
+	_(1985, ZEND_CLONE_SPEC_CV) \
+	_(1986, ZEND_RETURN_BY_REF_SPEC_CONST) \
 	_(1987, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \
-	_(1990, ZEND_RETURN_BY_REF_SPEC_CV) \
+	_(1988, ZEND_RETURN_BY_REF_SPEC_TMP) \
+	_(1989, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \
+	_(1990, ZEND_RETURN_BY_REF_SPEC_VAR) \
 	_(1991, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \
-	_(1992, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \
-	_(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \
-	_(1994, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \
-	_(1996, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \
-	_(1997, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \
-	_(1998, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \
-	_(1999, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \
-	_(2001, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \
-	_(2002, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \
-	_(2003, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \
-	_(2004, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \
-	_(2006, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \
-	_(2007, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \
-	_(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \
-	_(2009, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \
-	_(2011, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \
-	_(2012, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \
-	_(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \
-	_(2014, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \
-	_(2016, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \
-	_(2017, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \
-	_(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \
-	_(2019, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \
-	_(2020, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \
-	_(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \
-	_(2027, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \
-	_(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \
-	_(2029, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \
-	_(2030, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \
-	_(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \
-	_(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \
-	_(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \
-	_(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \
-	_(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \
-	_(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \
-	_(2042, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \
-	_(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \
-	_(2044, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \
-	_(2046, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \
-	_(2047, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \
-	_(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \
-	_(2049, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \
-	_(2051, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \
-	_(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \
-	_(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2054, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2056, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \
-	_(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \
-	_(2058, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2059, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2061, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \
-	_(2067, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \
-	_(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \
-	_(2069, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \
-	_(2071, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \
-	_(2072, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \
-	_(2073, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \
-	_(2078, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \
-	_(2079, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \
-	_(2082, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \
-	_(2083, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \
-	_(2088, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \
-	_(2089, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \
-	_(2132, ZEND_SEND_VAR_SPEC_VAR_CONST) \
-	_(2135, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \
-	_(2142, ZEND_SEND_VAR_SPEC_CV_CONST) \
-	_(2145, ZEND_SEND_VAR_SPEC_CV_UNUSED) \
-	_(2147, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \
-	_(2148, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \
-	_(2149, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \
-	_(2151, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \
-	_(2152, ZEND_SEND_ARRAY_SPEC) \
-	_(2153, ZEND_SEND_USER_SPEC_CONST) \
-	_(2154, ZEND_SEND_USER_SPEC_TMP) \
-	_(2155, ZEND_SEND_USER_SPEC_VAR) \
-	_(2157, ZEND_SEND_USER_SPEC_CV) \
-	_(2158, ZEND_STRLEN_SPEC_CONST) \
-	_(2159, ZEND_STRLEN_SPEC_TMPVAR) \
-	_(2160, ZEND_STRLEN_SPEC_TMPVAR) \
-	_(2162, ZEND_STRLEN_SPEC_CV) \
-	_(2163, ZEND_DEFINED_SPEC_CONST) \
-	_(2164, ZEND_TYPE_CHECK_SPEC_CONST) \
-	_(2165, ZEND_TYPE_CHECK_SPEC_TMPVAR) \
-	_(2166, ZEND_TYPE_CHECK_SPEC_TMPVAR) \
-	_(2168, ZEND_TYPE_CHECK_SPEC_CV) \
-	_(2169, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \
-	_(2170, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \
-	_(2171, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \
-	_(2172, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \
-	_(2173, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \
-	_(2174, ZEND_FE_RESET_RW_SPEC_CONST) \
-	_(2175, ZEND_FE_RESET_RW_SPEC_TMP) \
-	_(2176, ZEND_FE_RESET_RW_SPEC_VAR) \
-	_(2178, ZEND_FE_RESET_RW_SPEC_CV) \
-	_(2179, ZEND_FE_FETCH_RW_SPEC_VAR) \
-	_(2180, ZEND_FE_FREE_SPEC_TMPVAR) \
-	_(2181, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \
-	_(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \
-	_(2183, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \
-	_(2185, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \
-	_(2186, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \
-	_(2187, ZEND_DO_ICALL_SPEC_RETVAL_USED) \
-	_(2188, ZEND_DO_ICALL_SPEC_OBSERVER) \
-	_(2189, ZEND_DO_ICALL_SPEC_OBSERVER) \
-	_(2190, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \
-	_(2191, ZEND_DO_UCALL_SPEC_RETVAL_USED) \
-	_(2192, ZEND_DO_UCALL_SPEC_OBSERVER) \
-	_(2193, ZEND_DO_UCALL_SPEC_OBSERVER) \
-	_(2194, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \
-	_(2195, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \
-	_(2196, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \
-	_(2197, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \
-	_(2208, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \
-	_(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \
-	_(2210, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \
-	_(2212, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \
-	_(2213, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \
-	_(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \
-	_(2215, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \
-	_(2217, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \
-	_(2218, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \
-	_(2219, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \
-	_(2220, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \
-	_(2222, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \
-	_(2233, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \
-	_(2234, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \
-	_(2235, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \
-	_(2237, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \
-	_(2238, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \
-	_(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \
-	_(2240, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \
-	_(2242, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \
-	_(2243, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \
-	_(2244, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \
-	_(2245, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \
-	_(2247, ZEND_POST_INC_OBJ_SPEC_CV_CV) \
-	_(2248, ZEND_ECHO_SPEC_CONST) \
-	_(2249, ZEND_ECHO_SPEC_TMPVAR) \
-	_(2250, ZEND_ECHO_SPEC_TMPVAR) \
-	_(2252, ZEND_ECHO_SPEC_CV) \
-	_(2259, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \
-	_(2261, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \
-	_(2262, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \
-	_(2264, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \
-	_(2266, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \
-	_(2267, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \
-	_(2274, ZEND_INSTANCEOF_SPEC_CV_CONST) \
-	_(2276, ZEND_INSTANCEOF_SPEC_CV_VAR) \
-	_(2277, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \
-	_(2279, ZEND_GENERATOR_CREATE_SPEC) \
-	_(2282, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \
-	_(2284, ZEND_MAKE_REF_SPEC_CV_UNUSED) \
-	_(2285, ZEND_DECLARE_FUNCTION_SPEC) \
-	_(2286, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \
-	_(2287, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \
-	_(2288, ZEND_DECLARE_CLASS_SPEC_CONST) \
-	_(2289, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \
-	_(2290, ZEND_DECLARE_ANON_CLASS_SPEC) \
-	_(2291, ZEND_ADD_ARRAY_UNPACK_SPEC) \
-	_(2292, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \
-	_(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \
-	_(2294, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \
-	_(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \
-	_(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \
-	_(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2299, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \
-	_(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \
-	_(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2304, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \
-	_(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \
-	_(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \
-	_(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \
-	_(2309, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \
-	_(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \
-	_(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \
-	_(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \
-	_(2314, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \
-	_(2316, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \
-	_(2317, ZEND_HANDLE_EXCEPTION_SPEC) \
-	_(2318, ZEND_USER_OPCODE_SPEC) \
-	_(2319, ZEND_ASSERT_CHECK_SPEC) \
-	_(2320, ZEND_JMP_SET_SPEC_CONST) \
-	_(2321, ZEND_JMP_SET_SPEC_TMP) \
-	_(2322, ZEND_JMP_SET_SPEC_VAR) \
-	_(2324, ZEND_JMP_SET_SPEC_CV) \
-	_(2325, ZEND_UNSET_CV_SPEC_CV_UNUSED) \
-	_(2326, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \
-	_(2327, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \
-	_(2328, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \
-	_(2329, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \
-	_(2330, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \
-	_(2332, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \
-	_(2333, ZEND_SEPARATE_SPEC_VAR_UNUSED) \
-	_(2335, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \
-	_(2336, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \
-	_(2337, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \
-	_(2338, ZEND_FETCH_CLASS_NAME_SPEC_CV) \
-	_(2339, ZEND_CALL_TRAMPOLINE_SPEC) \
-	_(2340, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \
-	_(2341, ZEND_DISCARD_EXCEPTION_SPEC) \
-	_(2342, ZEND_YIELD_SPEC_CONST_CONST) \
-	_(2343, ZEND_YIELD_SPEC_CONST_TMPVAR) \
-	_(2344, ZEND_YIELD_SPEC_CONST_TMPVAR) \
-	_(2345, ZEND_YIELD_SPEC_CONST_UNUSED) \
-	_(2346, ZEND_YIELD_SPEC_CONST_CV) \
-	_(2347, ZEND_YIELD_SPEC_TMP_CONST) \
-	_(2348, ZEND_YIELD_SPEC_TMP_TMPVAR) \
-	_(2349, ZEND_YIELD_SPEC_TMP_TMPVAR) \
-	_(2350, ZEND_YIELD_SPEC_TMP_UNUSED) \
-	_(2351, ZEND_YIELD_SPEC_TMP_CV) \
-	_(2352, ZEND_YIELD_SPEC_VAR_CONST) \
-	_(2353, ZEND_YIELD_SPEC_VAR_TMPVAR) \
-	_(2354, ZEND_YIELD_SPEC_VAR_TMPVAR) \
-	_(2355, ZEND_YIELD_SPEC_VAR_UNUSED) \
-	_(2356, ZEND_YIELD_SPEC_VAR_CV) \
-	_(2357, ZEND_YIELD_SPEC_UNUSED_CONST) \
-	_(2358, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \
-	_(2359, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \
-	_(2360, ZEND_YIELD_SPEC_UNUSED_UNUSED) \
-	_(2361, ZEND_YIELD_SPEC_UNUSED_CV) \
-	_(2362, ZEND_YIELD_SPEC_CV_CONST) \
-	_(2363, ZEND_YIELD_SPEC_CV_TMPVAR) \
-	_(2364, ZEND_YIELD_SPEC_CV_TMPVAR) \
-	_(2365, ZEND_YIELD_SPEC_CV_UNUSED) \
-	_(2366, ZEND_YIELD_SPEC_CV_CV) \
-	_(2367, ZEND_GENERATOR_RETURN_SPEC_CONST) \
-	_(2368, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \
-	_(2369, ZEND_GENERATOR_RETURN_SPEC_TMP) \
-	_(2370, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \
-	_(2371, ZEND_GENERATOR_RETURN_SPEC_VAR) \
+	_(1994, ZEND_RETURN_BY_REF_SPEC_CV) \
+	_(1995, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \
+	_(1996, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \
+	_(1997, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP) \
+	_(2000, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \
+	_(2001, ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST) \
+	_(2002, ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP) \
+	_(2005, ZEND_INIT_METHOD_CALL_SPEC_TMP_CV) \
+	_(2011, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \
+	_(2012, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP) \
+	_(2015, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \
+	_(2016, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \
+	_(2017, ZEND_INIT_METHOD_CALL_SPEC_CV_TMP) \
+	_(2020, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \
+	_(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \
+	_(2022, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP) \
+	_(2024, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \
+	_(2025, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \
+	_(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \
+	_(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP) \
+	_(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \
+	_(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \
+	_(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \
+	_(2037, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP) \
+	_(2039, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \
+	_(2040, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \
+	_(2046, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \
+	_(2047, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED) \
+	_(2050, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \
+	_(2051, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \
+	_(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP) \
+	_(2055, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \
+	_(2056, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST) \
+	_(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP) \
+	_(2060, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV) \
+	_(2071, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \
+	_(2072, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP) \
+	_(2075, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \
+	_(2076, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \
+	_(2077, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \
+	_(2082, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED) \
+	_(2083, ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK) \
+	_(2086, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \
+	_(2087, ZEND_SEND_VAL_EX_SPEC_TMP_CONST) \
+	_(2092, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED) \
+	_(2093, ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK) \
+	_(2136, ZEND_SEND_VAR_SPEC_VAR_CONST) \
+	_(2139, ZEND_SEND_VAR_SPEC_VAR_UNUSED) \
+	_(2146, ZEND_SEND_VAR_SPEC_CV_CONST) \
+	_(2149, ZEND_SEND_VAR_SPEC_CV_UNUSED) \
+	_(2151, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \
+	_(2152, ZEND_INIT_USER_CALL_SPEC_CONST_TMP) \
+	_(2155, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \
+	_(2156, ZEND_SEND_ARRAY_SPEC) \
+	_(2157, ZEND_SEND_USER_SPEC_CONST) \
+	_(2158, ZEND_SEND_USER_SPEC_TMP) \
+	_(2161, ZEND_SEND_USER_SPEC_CV) \
+	_(2162, ZEND_STRLEN_SPEC_CONST) \
+	_(2163, ZEND_STRLEN_SPEC_TMP) \
+	_(2166, ZEND_STRLEN_SPEC_CV) \
+	_(2167, ZEND_DEFINED_SPEC_CONST) \
+	_(2168, ZEND_TYPE_CHECK_SPEC_CONST) \
+	_(2169, ZEND_TYPE_CHECK_SPEC_TMP) \
+	_(2172, ZEND_TYPE_CHECK_SPEC_CV) \
+	_(2173, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \
+	_(2174, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \
+	_(2175, ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED) \
+	_(2176, ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED) \
+	_(2177, ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED) \
+	_(2178, ZEND_FE_RESET_RW_SPEC_CONST) \
+	_(2179, ZEND_FE_RESET_RW_SPEC_TMP) \
+	_(2180, ZEND_FE_RESET_RW_SPEC_VAR) \
+	_(2182, ZEND_FE_RESET_RW_SPEC_CV) \
+	_(2183, ZEND_FE_FETCH_RW_SPEC_VAR) \
+	_(2184, ZEND_FE_FREE_SPEC_TMPVAR) \
+	_(2185, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \
+	_(2186, ZEND_INIT_DYNAMIC_CALL_SPEC_TMP) \
+	_(2189, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \
+	_(2190, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \
+	_(2191, ZEND_DO_ICALL_SPEC_RETVAL_USED) \
+	_(2192, ZEND_DO_ICALL_SPEC_OBSERVER) \
+	_(2193, ZEND_DO_ICALL_SPEC_OBSERVER) \
+	_(2194, ZEND_DO_UCALL_SPEC_RETVAL_UNUSED) \
+	_(2195, ZEND_DO_UCALL_SPEC_RETVAL_USED) \
+	_(2196, ZEND_DO_UCALL_SPEC_OBSERVER) \
+	_(2197, ZEND_DO_UCALL_SPEC_OBSERVER) \
+	_(2198, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED) \
+	_(2199, ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED) \
+	_(2200, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \
+	_(2201, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \
+	_(2212, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \
+	_(2213, ZEND_PRE_INC_OBJ_SPEC_VAR_TMP) \
+	_(2216, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \
+	_(2217, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \
+	_(2218, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP) \
+	_(2221, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \
+	_(2222, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \
+	_(2223, ZEND_PRE_INC_OBJ_SPEC_CV_TMP) \
+	_(2226, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \
+	_(2237, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \
+	_(2238, ZEND_POST_INC_OBJ_SPEC_VAR_TMP) \
+	_(2241, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \
+	_(2242, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \
+	_(2243, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP) \
+	_(2246, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \
+	_(2247, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \
+	_(2248, ZEND_POST_INC_OBJ_SPEC_CV_TMP) \
+	_(2251, ZEND_POST_INC_OBJ_SPEC_CV_CV) \
+	_(2252, ZEND_ECHO_SPEC_CONST) \
+	_(2253, ZEND_ECHO_SPEC_TMP) \
+	_(2256, ZEND_ECHO_SPEC_CV) \
+	_(2263, ZEND_INSTANCEOF_SPEC_TMP_CONST) \
+	_(2265, ZEND_INSTANCEOF_SPEC_TMP_VAR) \
+	_(2266, ZEND_INSTANCEOF_SPEC_TMP_UNUSED) \
+	_(2278, ZEND_INSTANCEOF_SPEC_CV_CONST) \
+	_(2280, ZEND_INSTANCEOF_SPEC_CV_VAR) \
+	_(2281, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \
+	_(2283, ZEND_GENERATOR_CREATE_SPEC) \
+	_(2286, ZEND_MAKE_REF_SPEC_VAR_UNUSED) \
+	_(2288, ZEND_MAKE_REF_SPEC_CV_UNUSED) \
+	_(2289, ZEND_DECLARE_FUNCTION_SPEC) \
+	_(2290, ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) \
+	_(2291, ZEND_DECLARE_CONST_SPEC_CONST_CONST) \
+	_(2292, ZEND_DECLARE_CLASS_SPEC_CONST) \
+	_(2293, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST) \
+	_(2294, ZEND_DECLARE_ANON_CLASS_SPEC) \
+	_(2295, ZEND_ADD_ARRAY_UNPACK_SPEC) \
+	_(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \
+	_(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP) \
+	_(2300, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \
+	_(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST) \
+	_(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP) \
+	_(2305, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV) \
+	_(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \
+	_(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP) \
+	_(2315, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \
+	_(2316, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \
+	_(2317, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP) \
+	_(2320, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \
+	_(2321, ZEND_HANDLE_EXCEPTION_SPEC) \
+	_(2322, ZEND_USER_OPCODE_SPEC) \
+	_(2323, ZEND_ASSERT_CHECK_SPEC) \
+	_(2324, ZEND_JMP_SET_SPEC_CONST) \
+	_(2325, ZEND_JMP_SET_SPEC_TMP) \
+	_(2328, ZEND_JMP_SET_SPEC_CV) \
+	_(2329, ZEND_UNSET_CV_SPEC_CV_UNUSED) \
+	_(2330, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \
+	_(2331, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \
+	_(2332, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \
+	_(2333, ZEND_FETCH_LIST_W_SPEC_VAR_TMP) \
+	_(2336, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \
+	_(2337, ZEND_SEPARATE_SPEC_VAR_UNUSED) \
+	_(2339, ZEND_FETCH_CLASS_NAME_SPEC_TMP) \
+	_(2341, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \
+	_(2342, ZEND_FETCH_CLASS_NAME_SPEC_CV) \
+	_(2343, ZEND_CALL_TRAMPOLINE_SPEC) \
+	_(2344, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \
+	_(2345, ZEND_DISCARD_EXCEPTION_SPEC) \
+	_(2346, ZEND_YIELD_SPEC_CONST_CONST) \
+	_(2347, ZEND_YIELD_SPEC_CONST_TMP) \
+	_(2349, ZEND_YIELD_SPEC_CONST_UNUSED) \
+	_(2350, ZEND_YIELD_SPEC_CONST_CV) \
+	_(2351, ZEND_YIELD_SPEC_TMP_CONST) \
+	_(2352, ZEND_YIELD_SPEC_TMP_TMP) \
+	_(2354, ZEND_YIELD_SPEC_TMP_UNUSED) \
+	_(2355, ZEND_YIELD_SPEC_TMP_CV) \
+	_(2356, ZEND_YIELD_SPEC_VAR_CONST) \
+	_(2357, ZEND_YIELD_SPEC_VAR_TMP) \
+	_(2359, ZEND_YIELD_SPEC_VAR_UNUSED) \
+	_(2360, ZEND_YIELD_SPEC_VAR_CV) \
+	_(2361, ZEND_YIELD_SPEC_UNUSED_CONST) \
+	_(2362, ZEND_YIELD_SPEC_UNUSED_TMP) \
+	_(2364, ZEND_YIELD_SPEC_UNUSED_UNUSED) \
+	_(2365, ZEND_YIELD_SPEC_UNUSED_CV) \
+	_(2366, ZEND_YIELD_SPEC_CV_CONST) \
+	_(2367, ZEND_YIELD_SPEC_CV_TMP) \
+	_(2369, ZEND_YIELD_SPEC_CV_UNUSED) \
+	_(2370, ZEND_YIELD_SPEC_CV_CV) \
+	_(2371, ZEND_GENERATOR_RETURN_SPEC_CONST) \
 	_(2372, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \
-	_(2375, ZEND_GENERATOR_RETURN_SPEC_CV) \
+	_(2373, ZEND_GENERATOR_RETURN_SPEC_TMP) \
+	_(2374, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \
+	_(2375, ZEND_GENERATOR_RETURN_SPEC_VAR) \
 	_(2376, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \
-	_(2377, ZEND_FAST_CALL_SPEC) \
-	_(2378, ZEND_FAST_RET_SPEC) \
-	_(2379, ZEND_RECV_VARIADIC_SPEC_UNUSED) \
-	_(2380, ZEND_SEND_UNPACK_SPEC) \
-	_(2381, ZEND_YIELD_FROM_SPEC_CONST) \
-	_(2382, ZEND_YIELD_FROM_SPEC_TMPVAR) \
-	_(2383, ZEND_YIELD_FROM_SPEC_TMPVAR) \
-	_(2385, ZEND_YIELD_FROM_SPEC_CV) \
-	_(2386, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \
-	_(2387, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \
-	_(2388, ZEND_COALESCE_SPEC_CONST) \
-	_(2389, ZEND_COALESCE_SPEC_TMP) \
-	_(2390, ZEND_COALESCE_SPEC_VAR) \
-	_(2392, ZEND_COALESCE_SPEC_CV) \
-	_(2393, ZEND_SPACESHIP_SPEC_CONST_CONST) \
-	_(2394, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \
-	_(2395, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \
-	_(2397, ZEND_SPACESHIP_SPEC_CONST_CV) \
-	_(2398, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \
-	_(2399, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \
-	_(2400, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \
-	_(2402, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \
-	_(2403, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \
-	_(2404, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \
-	_(2405, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \
-	_(2407, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \
-	_(2413, ZEND_SPACESHIP_SPEC_CV_CONST) \
-	_(2414, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \
-	_(2415, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \
-	_(2417, ZEND_SPACESHIP_SPEC_CV_CV) \
-	_(2418, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \
-	_(2419, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \
-	_(2422, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \
-	_(2424, ZEND_FETCH_STATIC_PROP_R_SPEC) \
-	_(2425, ZEND_FETCH_STATIC_PROP_W_SPEC) \
-	_(2426, ZEND_FETCH_STATIC_PROP_RW_SPEC) \
-	_(2427, ZEND_FETCH_STATIC_PROP_IS_SPEC) \
-	_(2428, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \
-	_(2429, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \
-	_(2430, ZEND_UNSET_STATIC_PROP_SPEC) \
-	_(2431, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \
-	_(2432, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \
-	_(2433, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \
-	_(2434, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \
-	_(2436, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \
-	_(2442, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \
-	_(2443, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \
-	_(2444, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \
-	_(2446, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \
-	_(2447, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \
-	_(2448, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \
-	_(2449, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \
-	_(2451, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \
-	_(2457, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \
-	_(2458, ZEND_BIND_STATIC_SPEC_CV) \
-	_(2459, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \
-	_(2460, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \
-	_(2463, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \
-	_(2465, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \
-	_(2466, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \
-	_(2467, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \
-	_(2468, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \
-	_(2470, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \
-	_(2471, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \
-	_(2472, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \
-	_(2473, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \
-	_(2475, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \
-	_(2476, ZEND_IN_ARRAY_SPEC_CONST_CONST) \
-	_(2477, ZEND_IN_ARRAY_SPEC_TMP_CONST) \
-	_(2478, ZEND_IN_ARRAY_SPEC_VAR_CONST) \
-	_(2480, ZEND_IN_ARRAY_SPEC_CV_CONST) \
-	_(2481, ZEND_COUNT_SPEC_CONST_UNUSED) \
-	_(2482, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \
-	_(2483, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \
-	_(2485, ZEND_COUNT_SPEC_CV_UNUSED) \
-	_(2486, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \
-	_(2487, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \
-	_(2488, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \
-	_(2489, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \
-	_(2490, ZEND_GET_CLASS_SPEC_CV_UNUSED) \
-	_(2491, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \
-	_(2492, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \
-	_(2493, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \
-	_(2494, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \
-	_(2496, ZEND_GET_TYPE_SPEC_CV_UNUSED) \
-	_(2497, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \
-	_(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \
-	_(2499, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \
-	_(2501, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \
-	_(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \
-	_(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \
-	_(2504, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \
-	_(2506, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \
-	_(2507, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \
-	_(2508, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \
-	_(2509, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \
-	_(2511, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \
-	_(2517, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \
-	_(2518, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \
-	_(2519, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \
-	_(2521, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \
-	_(2522, ZEND_MATCH_SPEC_CONST_CONST) \
-	_(2523, ZEND_MATCH_SPEC_TMPVARCV_CONST) \
-	_(2524, ZEND_MATCH_SPEC_TMPVARCV_CONST) \
-	_(2526, ZEND_MATCH_SPEC_TMPVARCV_CONST) \
-	_(2532, ZEND_CASE_STRICT_SPEC_TMP_CONST) \
-	_(2533, ZEND_CASE_STRICT_SPEC_TMP_TMP) \
-	_(2534, ZEND_CASE_STRICT_SPEC_TMP_VAR) \
-	_(2536, ZEND_CASE_STRICT_SPEC_TMP_CV) \
-	_(2537, ZEND_CASE_STRICT_SPEC_VAR_CONST) \
-	_(2538, ZEND_CASE_STRICT_SPEC_VAR_TMP) \
-	_(2539, ZEND_CASE_STRICT_SPEC_VAR_VAR) \
-	_(2541, ZEND_CASE_STRICT_SPEC_VAR_CV) \
-	_(2552, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \
-	_(2553, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \
-	_(2554, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \
-	_(2556, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \
-	_(2557, ZEND_JMP_NULL_SPEC_CONST) \
-	_(2558, ZEND_JMP_NULL_SPEC_TMP) \
-	_(2559, ZEND_JMP_NULL_SPEC_VAR) \
-	_(2561, ZEND_JMP_NULL_SPEC_CV) \
-	_(2562, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \
-	_(2563, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \
-	_(2564, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \
-	_(2565, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \
-	_(2566, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \
-	_(2567, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \
-	_(2568, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \
-	_(2569, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \
-	_(2570, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \
-	_(2571, ZEND_FRAMELESS_ICALL_2_SPEC) \
-	_(2572, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \
-	_(2573, ZEND_FRAMELESS_ICALL_3_SPEC) \
-	_(2574, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \
-	_(2575, ZEND_JMP_FRAMELESS_SPEC_CONST) \
-	_(2576, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \
-	_(2577, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST) \
-	_(2578, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \
-	_(2579, ZEND_RECV_NOTYPE_SPEC) \
-	_(2581, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \
-	_(2582, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \
-	_(2584, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \
-	_(2585, ZEND_JMP_FORWARD_SPEC) \
+	_(2379, ZEND_GENERATOR_RETURN_SPEC_CV) \
+	_(2380, ZEND_GENERATOR_RETURN_SPEC_OBSERVER) \
+	_(2381, ZEND_FAST_CALL_SPEC) \
+	_(2382, ZEND_FAST_RET_SPEC) \
+	_(2383, ZEND_RECV_VARIADIC_SPEC_UNUSED) \
+	_(2384, ZEND_SEND_UNPACK_SPEC) \
+	_(2385, ZEND_YIELD_FROM_SPEC_CONST) \
+	_(2386, ZEND_YIELD_FROM_SPEC_TMP) \
+	_(2389, ZEND_YIELD_FROM_SPEC_CV) \
+	_(2390, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \
+	_(2391, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \
+	_(2392, ZEND_COALESCE_SPEC_CONST) \
+	_(2393, ZEND_COALESCE_SPEC_TMP) \
+	_(2396, ZEND_COALESCE_SPEC_CV) \
+	_(2397, ZEND_SPACESHIP_SPEC_CONST_CONST) \
+	_(2398, ZEND_SPACESHIP_SPEC_CONST_TMP) \
+	_(2401, ZEND_SPACESHIP_SPEC_CONST_CV) \
+	_(2402, ZEND_SPACESHIP_SPEC_TMP_CONST) \
+	_(2403, ZEND_SPACESHIP_SPEC_TMP_TMP) \
+	_(2406, ZEND_SPACESHIP_SPEC_TMP_CV) \
+	_(2417, ZEND_SPACESHIP_SPEC_CV_CONST) \
+	_(2418, ZEND_SPACESHIP_SPEC_CV_TMP) \
+	_(2421, ZEND_SPACESHIP_SPEC_CV_CV) \
+	_(2422, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \
+	_(2423, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \
+	_(2426, ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED) \
+	_(2428, ZEND_FETCH_STATIC_PROP_R_SPEC) \
+	_(2429, ZEND_FETCH_STATIC_PROP_W_SPEC) \
+	_(2430, ZEND_FETCH_STATIC_PROP_RW_SPEC) \
+	_(2431, ZEND_FETCH_STATIC_PROP_IS_SPEC) \
+	_(2432, ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC) \
+	_(2433, ZEND_FETCH_STATIC_PROP_UNSET_SPEC) \
+	_(2434, ZEND_UNSET_STATIC_PROP_SPEC) \
+	_(2435, ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC) \
+	_(2436, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST) \
+	_(2437, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \
+	_(2438, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \
+	_(2440, ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV) \
+	_(2446, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST) \
+	_(2447, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \
+	_(2448, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \
+	_(2450, ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) \
+	_(2451, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST) \
+	_(2452, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \
+	_(2453, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \
+	_(2455, ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) \
+	_(2461, ZEND_BIND_LEXICAL_SPEC_TMP_CV) \
+	_(2462, ZEND_BIND_STATIC_SPEC_CV) \
+	_(2463, ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) \
+	_(2464, ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST) \
+	_(2467, ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED) \
+	_(2469, ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) \
+	_(2470, ZEND_SWITCH_LONG_SPEC_CONST_CONST) \
+	_(2471, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \
+	_(2472, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \
+	_(2474, ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST) \
+	_(2475, ZEND_SWITCH_STRING_SPEC_CONST_CONST) \
+	_(2476, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \
+	_(2477, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \
+	_(2479, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \
+	_(2480, ZEND_IN_ARRAY_SPEC_CONST_CONST) \
+	_(2481, ZEND_IN_ARRAY_SPEC_TMP_CONST) \
+	_(2484, ZEND_IN_ARRAY_SPEC_CV_CONST) \
+	_(2485, ZEND_COUNT_SPEC_CONST_UNUSED) \
+	_(2486, ZEND_COUNT_SPEC_TMP_UNUSED) \
+	_(2489, ZEND_COUNT_SPEC_CV_UNUSED) \
+	_(2490, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \
+	_(2491, ZEND_GET_CLASS_SPEC_TMP_UNUSED) \
+	_(2493, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \
+	_(2494, ZEND_GET_CLASS_SPEC_CV_UNUSED) \
+	_(2495, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \
+	_(2496, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \
+	_(2497, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \
+	_(2500, ZEND_GET_TYPE_SPEC_CV_UNUSED) \
+	_(2501, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \
+	_(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP) \
+	_(2505, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \
+	_(2506, ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST) \
+	_(2507, ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP) \
+	_(2510, ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV) \
+	_(2521, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \
+	_(2522, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP) \
+	_(2525, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \
+	_(2526, ZEND_MATCH_SPEC_CONST_CONST) \
+	_(2527, ZEND_MATCH_SPEC_TMPVARCV_CONST) \
+	_(2528, ZEND_MATCH_SPEC_TMPVARCV_CONST) \
+	_(2530, ZEND_MATCH_SPEC_TMPVARCV_CONST) \
+	_(2531, ZEND_CASE_STRICT_SPEC_TMP_CONST) \
+	_(2532, ZEND_CASE_STRICT_SPEC_TMP_TMP) \
+	_(2535, ZEND_CASE_STRICT_SPEC_TMP_CV) \
+	_(2536, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \
+	_(2537, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \
+	_(2538, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \
+	_(2540, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \
+	_(2541, ZEND_JMP_NULL_SPEC_CONST) \
+	_(2542, ZEND_JMP_NULL_SPEC_TMP) \
+	_(2545, ZEND_JMP_NULL_SPEC_CV) \
+	_(2546, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \
+	_(2547, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \
+	_(2548, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \
+	_(2549, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \
+	_(2550, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \
+	_(2551, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \
+	_(2552, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \
+	_(2553, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \
+	_(2554, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \
+	_(2555, ZEND_FRAMELESS_ICALL_2_SPEC) \
+	_(2556, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \
+	_(2557, ZEND_FRAMELESS_ICALL_3_SPEC) \
+	_(2558, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \
+	_(2559, ZEND_JMP_FRAMELESS_SPEC_CONST) \
+	_(2560, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \
+	_(2561, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST) \
+	_(2562, ZEND_TYPE_ASSERT_SPEC_CONST) \
+	_(2564, ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_TMP_UNUSED) \
+	_(2566, ZEND_VERIFY_GENERIC_ARGUMENTS_SPEC_UNUSED_UNUSED) \
+	_(2569, ZEND_INSTALL_GENERIC_ARGS_SPEC_TMP_UNUSED) \
+	_(2571, ZEND_INSTALL_GENERIC_ARGS_SPEC_UNUSED_UNUSED) \
+	_(2573, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \
+	_(2574, ZEND_RECV_NOTYPE_SPEC) \
+	_(2576, ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) \
+	_(2579, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \
+	_(2580, ZEND_JMP_FORWARD_SPEC) \
+	_(2586, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2587, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2588, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2590, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
 	_(2592, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2593, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2597, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2598, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2600, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2607, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2608, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2610, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2601, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2602, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2603, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2605, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2611, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
+	_(2612, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2613, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2615, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
 	_(2617, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2618, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
-	_(2622, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2623, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2625, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
-	_(2632, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2633, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2635, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2626, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \
+	_(2627, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2628, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2630, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2636, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2637, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2638, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2640, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
 	_(2642, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2643, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2647, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2648, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2650, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2657, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2658, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2660, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
-	_(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
-	_(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
+	_(2651, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2652, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2653, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2655, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2657, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
+	_(2658, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
+	_(2660, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \
+	_(2661, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
 	_(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2668, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2672, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2673, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2675, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2682, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2683, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2685, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2687, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
-	_(2688, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
-	_(2690, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
+	_(2676, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2677, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2678, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2680, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2682, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
+	_(2683, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
+	_(2685, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \
+	_(2686, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
+	_(2687, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2688, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2690, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
 	_(2692, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2693, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
-	_(2697, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2698, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2700, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
-	_(2707, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2708, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2710, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2712, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(2713, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(2715, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(2701, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \
+	_(2702, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2703, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2705, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2707, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(2708, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(2710, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(2711, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2712, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2713, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2715, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
 	_(2717, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2718, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2722, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2723, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2725, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2732, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2733, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2735, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2726, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2727, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2728, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2730, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2736, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2737, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2738, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2740, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
 	_(2742, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2743, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
 	_(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2747, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2748, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2750, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
-	_(2757, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2758, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
-	_(2760, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2751, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \
+	_(2752, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2753, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2755, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \
+	_(2761, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2762, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2763, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2765, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
 	_(2767, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2768, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
 	_(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2772, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2773, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2775, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2782, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2783, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2785, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2776, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2777, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2778, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2780, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2786, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2787, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2788, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2790, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
 	_(2792, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2793, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
 	_(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2797, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2798, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2800, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2807, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2808, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2810, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2879, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2885, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2954, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2960, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3029, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3035, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3104, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3110, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3111, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
-	_(3112, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3113, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3114, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
-	_(3115, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3116, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3117, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
-	_(3121, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \
-	_(3122, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
-	_(3126, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \
-	_(3130, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
-	_(3131, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
-	_(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3135, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3139, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
-	_(3140, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3141, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
-	_(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
-	_(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3165, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3170, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3171, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
-	_(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3189, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3190, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3191, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3195, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3199, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3200, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3201, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3240, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3245, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3246, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3264, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3265, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3266, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3270, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3274, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3275, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3276, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
-	_(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
-	_(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
-	_(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3315, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3320, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3321, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
-	_(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3339, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3340, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3341, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3345, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3349, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
-	_(3350, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3351, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
-	_(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
-	_(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
-	_(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3390, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3395, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3396, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
-	_(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
-	_(3414, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
-	_(3415, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3416, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3420, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3424, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
-	_(3425, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
-	_(3426, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
-	_(3427, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
-	_(3428, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
-	_(3429, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \
-	_(3430, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \
-	_(3431, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
-	_(3432, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
-	_(3433, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \
-	_(3434, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \
-	_(3435, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \
-	_(3436, ZEND_POST_INC_LONG_SPEC_CV) \
-	_(3437, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \
-	_(3438, ZEND_POST_DEC_LONG_SPEC_CV) \
-	_(3439, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \
-	_(3440, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
-	_(3441, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
-	_(3443, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
-	_(3444, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \
-	_(3445, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
-	_(3446, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
-	_(3448, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
-	_(3449, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \
-	_(3450, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
-	_(3451, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
-	_(3453, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
-	_(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
-	_(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
-	_(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
+	_(2801, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2802, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2803, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2805, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2822, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2823, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2824, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2837, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2850, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2866, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2867, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2868, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2869, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2870, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2879, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2880, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2897, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2898, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2899, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2912, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2925, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2941, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(2942, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2943, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2944, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2945, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(2954, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2955, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2972, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2973, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2974, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(2987, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3000, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3016, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3017, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3018, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3019, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3020, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3029, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3030, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3047, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3048, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3049, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3062, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3075, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3091, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3092, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3093, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3094, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3095, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3104, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3105, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3106, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
+	_(3107, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3108, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3109, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \
+	_(3110, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3111, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3112, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
+	_(3116, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \
+	_(3117, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \
+	_(3121, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \
+	_(3125, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
+	_(3126, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3127, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3128, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
+	_(3129, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3130, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \
+	_(3135, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3136, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
+	_(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
+	_(3153, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3165, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3166, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \
+	_(3183, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3184, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3185, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3186, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3189, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3190, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3195, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3196, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3228, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3240, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3241, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3258, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3259, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3260, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3261, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3264, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3265, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3270, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3271, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
+	_(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
+	_(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \
+	_(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3303, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3315, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3316, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \
+	_(3333, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3334, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3335, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3336, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3339, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3340, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \
+	_(3345, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3346, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \
+	_(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \
+	_(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \
+	_(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3378, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3390, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3391, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \
+	_(3408, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \
+	_(3409, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \
+	_(3410, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3411, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3414, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3415, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \
+	_(3420, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \
+	_(3421, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \
+	_(3422, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
+	_(3423, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
+	_(3424, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \
+	_(3425, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \
+	_(3426, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \
+	_(3427, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \
+	_(3428, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \
+	_(3429, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \
+	_(3430, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \
+	_(3431, ZEND_POST_INC_LONG_SPEC_CV) \
+	_(3432, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \
+	_(3433, ZEND_POST_DEC_LONG_SPEC_CV) \
+	_(3434, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \
+	_(3435, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
+	_(3436, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
+	_(3438, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \
+	_(3439, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \
+	_(3440, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
+	_(3441, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
+	_(3443, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \
+	_(3444, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \
+	_(3445, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
+	_(3446, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
+	_(3448, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \
+	_(3450, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
+	_(3451, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
+	_(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \
+	_(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \
+	_(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
+	_(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
 	_(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \
 	_(3460, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
 	_(3461, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
 	_(3463, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3464, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \
-	_(3465, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3466, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \
-	_(3474, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \
-	_(3475, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
-	_(3476, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
-	_(3478, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
-	_(3481, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \
-	_(3483, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \
-	_(3486, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \
-	_(3488, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \
-	_(3489, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \
-	_(3490, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \
-	_(3491, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \
-	_(3492, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \
-	_(3492+1, ZEND_NULL)
+	_(3469, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \
+	_(3470, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
+	_(3471, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
+	_(3473, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
+	_(3476, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \
+	_(3478, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \
+	_(3481, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \
+	_(3483, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \
+	_(3484, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \
+	_(3485, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \
+	_(3486, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \
+	_(3487, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \
+	_(3487+1, ZEND_NULL)
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 00ad38baaafe..84e541d4de06 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -22,7 +21,7 @@
 #include 
 #include 
 
-static const char *zend_vm_opcodes_names[211] = {
+static const char *zend_vm_opcodes_names[214] = {
 	"ZEND_NOP",
 	"ZEND_ADD",
 	"ZEND_SUB",
@@ -234,42 +233,45 @@ static const char *zend_vm_opcodes_names[211] = {
 	"ZEND_JMP_FRAMELESS",
 	"ZEND_INIT_PARENT_PROPERTY_HOOK_CALL",
 	"ZEND_DECLARE_ATTRIBUTED_CONST",
+	"ZEND_TYPE_ASSERT",
+	"ZEND_VERIFY_GENERIC_ARGUMENTS",
+	"ZEND_INSTALL_GENERIC_ARGS",
 };
 
-static uint32_t zend_vm_opcodes_flags[211] = {
+static uint32_t zend_vm_opcodes_flags[214] = {
 	0x00000000,
 	0x00000b0b,
 	0x00000b0b,
 	0x80000b0b,
-	0x00000707,
+	0x00000303,
 	0x00000b0b,
 	0x00000b0b,
 	0x00000b0b,
-	0x40000707,
+	0x40000303,
 	0x80000b0b,
 	0x80000b0b,
 	0x80000b0b,
-	0x00000707,
+	0x00000303,
 	0x0000000b,
-	0x00000007,
-	0x80000707,
+	0x00000003,
+	0x80000303,
+	0x80000303,
+	0x80000303,
 	0x80000303,
 	0x80000303,
-	0x80000707,
-	0x80000707,
 	0x00000b0b,
 	0x00000b0b,
 	0x00000301,
-	0x00006701,
-	0x00040751,
+	0x00006301,
+	0x00040351,
 	0x00040000,
-	0x04000701,
-	0x04006701,
-	0x04000751,
+	0x04000301,
+	0x04006301,
+	0x04000351,
 	0x04000000,
 	0x0b000101,
 	0x00000003,
-	0x0b040751,
+	0x0b040351,
 	0x0b040000,
 	0x00000001,
 	0x00000001,
@@ -280,20 +282,20 @@ static uint32_t zend_vm_opcodes_flags[211] = {
 	0x00040000,
 	0x00040000,
 	0x00000020,
-	0x00002007,
-	0x00002007,
+	0x00002003,
+	0x00002003,
 	0x00000000,
-	0x00002007,
-	0x00002007,
-	0x00000705,
+	0x00002003,
+	0x00002003,
+	0x00000301,
 	0x00000101,
 	0x00001301,
 	0x07000003,
-	0x00000007,
-	0x00000707,
-	0x01000701,
-	0x01000701,
-	0x01000701,
+	0x00000003,
+	0x00000303,
+	0x01000301,
+	0x01000301,
+	0x01000301,
 	0x00000000,
 	0x00000001,
 	0x01040300,
@@ -307,35 +309,35 @@ static uint32_t zend_vm_opcodes_flags[211] = {
 	0x00001301,
 	0x0100a173,
 	0x01040300,
-	0x00000005,
-	0x00186703,
-	0x00106703,
-	0x08000007,
+	0x00004005,
+	0x00186303,
+	0x00106303,
+	0x08000003,
 	0x00010107,
-	0x00000701,
-	0x00040751,
+	0x00000301,
+	0x00040351,
 	0x00002003,
 	0x03000001,
 	0x00000000,
-	0x00010107,
-	0x00000707,
-	0x00040757,
-	0x00010107,
-	0x00006701,
-	0x00640751,
-	0x00010107,
-	0x00006701,
-	0x00040751,
-	0x00010107,
-	0x00000707,
-	0x00040757,
-	0x00010107,
-	0x00006703,
-	0x00240753,
-	0x00010107,
-	0x00000701,
-	0x00040751,
-	0x0000070b,
+	0x00010103,
+	0x00000307,
+	0x00040357,
+	0x00010103,
+	0x00006301,
+	0x00640351,
+	0x00010103,
+	0x00006301,
+	0x00040351,
+	0x00010103,
+	0x00000307,
+	0x00040357,
+	0x00010103,
+	0x00006303,
+	0x00240353,
+	0x00010103,
+	0x00000301,
+	0x00040351,
+	0x0000030b,
 	0x00040391,
 	0x00001301,
 	0x00000000,
@@ -345,37 +347,37 @@ static uint32_t zend_vm_opcodes_flags[211] = {
 	0x01000000,
 	0x00001301,
 	0x02042003,
-	0x00000007,
-	0x00040771,
-	0x00000057,
+	0x00000003,
+	0x00040371,
+	0x00000053,
 	0x0b000003,
-	0x01040757,
-	0x01048773,
-	0x00030107,
-	0x00020707,
+	0x01040353,
+	0x01048373,
+	0x00030103,
+	0x00020303,
 	0x00001303,
 	0x00001301,
-	0x01000703,
+	0x01000303,
 	0x01000000,
 	0x00001003,
-	0x00000007,
+	0x00000003,
 	0x00040003,
-	0x09000007,
+	0x09000003,
 	0x00000103,
 	0x00002003,
 	0x03000001,
-	0x00000005,
-	0x01000700,
+	0x00004005,
+	0x01000300,
 	0x00000000,
 	0x00000000,
 	0x00000000,
-	0x00040751,
-	0x00040751,
-	0x00040751,
-	0x00040751,
-	0x00000007,
+	0x00040351,
+	0x00040351,
+	0x00040351,
+	0x00040351,
+	0x00000003,
 	0x00000000,
-	0x00047305,
+	0x00047301,
 	0x00000000,
 	0x00000101,
 	0x00001000,
@@ -385,29 +387,29 @@ static uint32_t zend_vm_opcodes_flags[211] = {
 	0x00000303,
 	0x00040000,
 	0x00000000,
-	0x00060757,
+	0x00060353,
 	0x00000000,
 	0x00000000,
 	0x00002000,
 	0x00002003,
 	0x00000101,
 	0x00020101,
-	0x00000701,
+	0x00000301,
 	0x00000101,
-	0x00000075,
+	0x00000071,
 	0x00000000,
 	0x00000000,
-	0x0b000703,
+	0x0b000303,
 	0x00000003,
 	0x00000020,
 	0x00003000,
 	0x00000110,
 	0x00000000,
-	0x00000007,
+	0x00000003,
 	0x00000105,
 	0x00040301,
 	0x00002003,
-	0x00000707,
+	0x00000303,
 	0x00000101,
 	0x00000103,
 	0x00047000,
@@ -427,11 +429,11 @@ static uint32_t zend_vm_opcodes_flags[211] = {
 	0x0300030b,
 	0x0300030b,
 	0x01000303,
-	0x00000107,
-	0x00000107,
+	0x00000103,
+	0x00000103,
 	0x00000101,
 	0x00000103,
-	0x00000707,
+	0x00000303,
 	0x0300030b,
 	0x00000301,
 	0x0000010b,
@@ -439,7 +441,7 @@ static uint32_t zend_vm_opcodes_flags[211] = {
 	0x00000101,
 	0x00000101,
 	0x00000101,
-	0x00000101,
+	0x01040101,
 	0x00002001,
 	0x00000101,
 	0x00000100,
@@ -448,6 +450,9 @@ static uint32_t zend_vm_opcodes_flags[211] = {
 	0x01042003,
 	0x01001103,
 	0x00000303,
+	0x01000003,
+	0x00000101,
+	0x00000101,
 };
 
 ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) {
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 29469bb5f7dc..1c4b487196d2 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Andi Gutmans                                  |
    |          Zeev Suraski                                  |
@@ -29,9 +28,21 @@
 #define ZEND_VM_KIND_SWITCH	2
 #define ZEND_VM_KIND_GOTO	3
 #define ZEND_VM_KIND_HYBRID	4
+#define ZEND_VM_KIND_TAILCALL	5
+static const char *const zend_vm_kind_name[] = {
+    NULL,
+    "ZEND_VM_KIND_CALL",
+    "ZEND_VM_KIND_SWITCH",
+    "ZEND_VM_KIND_GOTO",
+    "ZEND_VM_KIND_HYBRID",
+    "ZEND_VM_KIND_TAILCALL",
+};
+#if 0
 /* HYBRID requires support for computed GOTO and global register variables*/
-#if (defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS))
+#elif (defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS))
 # define ZEND_VM_KIND		ZEND_VM_KIND_HYBRID
+#elif defined(HAVE_MUSTTAIL) && defined(HAVE_PRESERVE_NONE) && (defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__))
+# define ZEND_VM_KIND		ZEND_VM_KIND_TAILCALL
 #else
 # define ZEND_VM_KIND		ZEND_VM_KIND_CALL
 #endif
@@ -42,6 +53,30 @@
 # endif
 #endif
 
+#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+# define ZEND_OPCODE_HANDLER_CCONV    ZEND_PRESERVE_NONE
+# define ZEND_OPCODE_HANDLER_CCONV_EX ZEND_FASTCALL
+#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL
+# define ZEND_OPCODE_HANDLER_CCONV    ZEND_FASTCALL
+# define ZEND_OPCODE_HANDLER_CCONV_EX ZEND_FASTCALL
+#endif
+#define ZEND_OPCODE_HANDLER_FUNC_CCONV    ZEND_FASTCALL
+#define ZEND_OPCODE_HANDLER_FUNC_CCONV_EX ZEND_FASTCALL
+
+#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
+typedef const void* zend_vm_opcode_handler_t;
+typedef void (ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(void);
+#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL
+typedef const struct _zend_op *(ZEND_OPCODE_HANDLER_CCONV *zend_vm_opcode_handler_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);
+typedef const struct _zend_op *(ZEND_OPCODE_HANDLER_FUNC_CCONV *zend_vm_opcode_handler_func_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);
+#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
+typedef int zend_vm_opcode_handler_t;
+#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO
+typedef const void* zend_vm_opcode_handler_t;
+#else
+# error
+#endif
+
 #define ZEND_VM_OP_SPEC          0x00000001
 #define ZEND_VM_OP_CONST         0x00000002
 #define ZEND_VM_OP_TMPVAR        0x00000004
@@ -50,6 +85,7 @@
 #define ZEND_VM_OP_NUM           0x00000010
 #define ZEND_VM_OP_JMP_ADDR      0x00000020
 #define ZEND_VM_OP_TRY_CATCH     0x00000030
+#define ZEND_VM_OP_LOOP_END      0x00000040
 #define ZEND_VM_OP_THIS          0x00000050
 #define ZEND_VM_OP_NEXT          0x00000060
 #define ZEND_VM_OP_CLASS_FETCH   0x00000070
@@ -294,7 +330,10 @@ END_EXTERN_C()
 #define ZEND_JMP_FRAMELESS                  208
 #define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL 209
 #define ZEND_DECLARE_ATTRIBUTED_CONST       210
+#define ZEND_TYPE_ASSERT                    211
+#define ZEND_VERIFY_GENERIC_ARGUMENTS       212
+#define ZEND_INSTALL_GENERIC_ARGS           213
 
-#define ZEND_VM_LAST_OPCODE                 210
+#define ZEND_VM_LAST_OPCODE                 213
 
 #endif
diff --git a/Zend/zend_vm_trace_handlers.h b/Zend/zend_vm_trace_handlers.h
index eaf97e012cac..e7510f406711 100644
--- a/Zend/zend_vm_trace_handlers.h
+++ b/Zend/zend_vm_trace_handlers.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_vm_trace_lines.h b/Zend/zend_vm_trace_lines.h
index 740e18776395..8c194edbcde1 100644
--- a/Zend/zend_vm_trace_lines.h
+++ b/Zend/zend_vm_trace_lines.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_vm_trace_map.h b/Zend/zend_vm_trace_map.h
index d84aa0442d26..18c705b454d5 100644
--- a/Zend/zend_vm_trace_map.h
+++ b/Zend/zend_vm_trace_map.h
@@ -2,15 +2,14 @@
    +----------------------------------------------------------------------+
    | Zend Engine                                                          |
    +----------------------------------------------------------------------+
-   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   | Copyright © Zend Technologies Ltd., a subsidiary company of          |
+   |     Perforce Software, Inc., and Contributors.                       |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: Dmitry Stogov                               |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c
index cf363cd12595..ad0308f44e20 100644
--- a/Zend/zend_weakrefs.c
+++ b/Zend/zend_weakrefs.c
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: krakjoe@php.net                                             |
    +----------------------------------------------------------------------+
@@ -36,19 +34,21 @@ typedef struct _zend_weakmap_iterator {
 	uint32_t ht_iter;
 } zend_weakmap_iterator;
 
-/* EG(weakrefs) is a map from a key corresponding to a zend_object pointer to all the WeakReference and/or WeakMap entries relating to that pointer.
+/* EG(weakrefs) is a map from a key corresponding to a zend_object pointer to all the WeakReference, WeakMap, and/or bare HashTable entries relating to that pointer.
  *
  * 1. For a single WeakReference,
  *    the HashTable's corresponding value's tag is a ZEND_WEAKREF_TAG_REF and the pointer is a singleton WeakReference instance (zend_weakref *) for that zend_object pointer (from WeakReference::create()).
  * 2. For a single WeakMap, the HashTable's corresponding value's tag is a ZEND_WEAKREF_TAG_MAP and the pointer is a WeakMap instance (zend_weakmap *).
- * 3. For multiple values associated with the same zend_object pointer, the HashTable entry's tag is a ZEND_WEAKREF_TAG_HT with a HashTable mapping
- *    tagged pointers of at most 1 WeakReference and 1 or more WeakMaps to the same tagged pointer.
+ * 3. For a single bare HashTable, the HashTable's corresponding value's tag is a ZEND_WEAKREF_TAG_BARE_HT and the pointer is a HashTable*.
+ * 4. For multiple values associated with the same zend_object pointer, the HashTable entry's tag is a ZEND_WEAKREF_TAG_HT with a HashTable mapping
+ *    tagged pointers of at most 1 WeakReference and 1 or more WeakMap or bare HashTable to the same tagged pointer.
  *
  * ZEND_MM_ALIGNED_OFFSET_LOG2 is at least 2 on supported architectures (pointers to the objects in question are aligned to 4 bytes (1<<2) even on 32-bit systems),
  * i.e. the least two significant bits of the pointer can be used as a tag (ZEND_WEAKREF_TAG_*). */
-#define ZEND_WEAKREF_TAG_REF 0
-#define ZEND_WEAKREF_TAG_MAP 1
-#define ZEND_WEAKREF_TAG_HT  2
+#define ZEND_WEAKREF_TAG_REF     0
+#define ZEND_WEAKREF_TAG_MAP     1
+#define ZEND_WEAKREF_TAG_HT      2
+#define ZEND_WEAKREF_TAG_BARE_HT 3
 #define ZEND_WEAKREF_GET_TAG(p) (((uintptr_t) (p)) & 3)
 #define ZEND_WEAKREF_GET_PTR(p) ((void *) (((uintptr_t) (p)) & ~3))
 #define ZEND_WEAKREF_ENCODE(p, t) ((void *) (((uintptr_t) (p)) | (t)))
@@ -58,10 +58,10 @@ static zend_class_entry *zend_ce_weakmap;
 static zend_object_handlers zend_weakref_handlers;
 static zend_object_handlers zend_weakmap_handlers;
 
-#define zend_weakref_from(o) ((zend_weakref*)(((char*) o) - XtOffsetOf(zend_weakref, std)))
+#define zend_weakref_from(o) (ZEND_CONTAINER_OF(o, zend_weakref, std))
 #define zend_weakref_fetch(z) zend_weakref_from(Z_OBJ_P(z))
 
-#define zend_weakmap_from(o) ((zend_weakmap*)(((char*) o) - XtOffsetOf(zend_weakmap, std)))
+#define zend_weakmap_from(o) (ZEND_CONTAINER_OF(o, zend_weakmap, std))
 #define zend_weakmap_fetch(z) zend_weakmap_from(Z_OBJ_P(z))
 
 static inline void zend_weakref_unref_single(
@@ -72,8 +72,8 @@ static inline void zend_weakref_unref_single(
 		zend_weakref *wr = ptr;
 		wr->referent = NULL;
 	} else {
-		/* unreferencing WeakMap entry (at ptr) with a key of object. */
-		ZEND_ASSERT(tag == ZEND_WEAKREF_TAG_MAP);
+		/* unreferencing WeakMap or bare HashTable entry (at ptr) with a key of object. */
+		ZEND_ASSERT(tag == ZEND_WEAKREF_TAG_MAP || tag == ZEND_WEAKREF_TAG_BARE_HT);
 		zend_hash_index_del((HashTable *) ptr, zend_object_to_weakref_key(object));
 	}
 }
@@ -107,15 +107,15 @@ static void zend_weakref_register(zend_object *object, void *payload) {
 	void *tagged_ptr = Z_PTR_P(zv);
 	if (ZEND_WEAKREF_GET_TAG(tagged_ptr) == ZEND_WEAKREF_TAG_HT) {
 		HashTable *ht = ZEND_WEAKREF_GET_PTR(tagged_ptr);
-		zend_hash_index_add_new_ptr(ht, (zend_ulong) payload, payload);
+		zend_hash_index_add_new_ptr(ht, (zend_ulong)(uintptr_t) payload, payload);
 		return;
 	}
 
 	/* Convert simple pointer to hashtable. */
 	HashTable *ht = emalloc(sizeof(HashTable));
 	zend_hash_init(ht, 0, NULL, NULL, 0);
-	zend_hash_index_add_new_ptr(ht, (zend_ulong) tagged_ptr, tagged_ptr);
-	zend_hash_index_add_new_ptr(ht, (zend_ulong) payload, payload);
+	zend_hash_index_add_new_ptr(ht, (zend_ulong)(uintptr_t) tagged_ptr, tagged_ptr);
+	zend_hash_index_add_new_ptr(ht, (zend_ulong)(uintptr_t) payload, payload);
 	/* Replace the single WeakMap or WeakReference entry in EG(weakrefs) with a HashTable with 2 entries in place. */
 	ZVAL_PTR(zv, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_HT));
 }
@@ -136,19 +136,19 @@ static void zend_weakref_unregister(zend_object *object, void *payload, bool wea
 		if (weakref_free) {
 			zend_weakref_unref_single(ptr, tag, object);
 		} else {
-			/* The optimization of skipping unref is only used in the destructor of WeakMap */
-			ZEND_ASSERT(ZEND_WEAKREF_GET_TAG(payload) == ZEND_WEAKREF_TAG_MAP);
+			/* The optimization of skipping unref is used for zend_weakrefs_hash_clean_ex() */
+			ZEND_ASSERT(ZEND_WEAKREF_GET_TAG(payload) == ZEND_WEAKREF_TAG_MAP || ZEND_WEAKREF_GET_TAG(payload) == ZEND_WEAKREF_TAG_BARE_HT);
 		}
 		return;
 	}
 
 	HashTable *ht = ptr;
 #if ZEND_DEBUG
-	void *old_payload = zend_hash_index_find_ptr(ht, (zend_ulong) payload);
+	void *old_payload = zend_hash_index_find_ptr(ht, (zend_ulong)(uintptr_t) payload);
 	ZEND_ASSERT(old_payload && "Weakref not registered?");
 	ZEND_ASSERT(old_payload == payload);
 #endif
-	zend_hash_index_del(ht, (zend_ulong) payload);
+	zend_hash_index_del(ht, (zend_ulong)(uintptr_t) payload);
 	if (zend_hash_num_elements(ht) == 0) {
 		GC_DEL_FLAGS(object, IS_OBJ_WEAKLY_REFERENCED);
 		zend_hash_destroy(ht);
@@ -161,15 +161,17 @@ static void zend_weakref_unregister(zend_object *object, void *payload, bool wea
 		zend_weakref_unref_single(
 			ZEND_WEAKREF_GET_PTR(payload), ZEND_WEAKREF_GET_TAG(payload), object);
 	} else {
-		/* The optimization of skipping unref is only used in the destructor of WeakMap */
-		ZEND_ASSERT(ZEND_WEAKREF_GET_TAG(payload) == ZEND_WEAKREF_TAG_MAP);
+		/* The optimization of skipping unref is used for zend_weakrefs_hash_clean_ex() */
+		ZEND_ASSERT(ZEND_WEAKREF_GET_TAG(payload) == ZEND_WEAKREF_TAG_MAP || ZEND_WEAKREF_GET_TAG(payload) == ZEND_WEAKREF_TAG_BARE_HT);
 	}
 }
 
+/* Insert 'pData' into bare HashTable 'ht', with the given 'key'. 'key' is
+ * weakly referenced. 'ht' is considered to be a bare HashTable, not a WeakMap. */
 ZEND_API zval *zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pData) {
 	zval *zv = zend_hash_index_add(ht, zend_object_to_weakref_key(key), pData);
 	if (zv) {
-		zend_weakref_register(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_MAP));
+		zend_weakref_register(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_BARE_HT));
 	}
 	return zv;
 }
@@ -177,17 +179,26 @@ ZEND_API zval *zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pDa
 ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key) {
 	zval *zv = zend_hash_index_find(ht, zend_object_to_weakref_key(key));
 	if (zv) {
-		zend_weakref_unregister(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_MAP), 1);
+		zend_weakref_unregister(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_BARE_HT), true);
 		return SUCCESS;
 	}
 	return FAILURE;
 }
 
-ZEND_API void zend_weakrefs_hash_clean(HashTable *ht) {
+static void zend_weakrefs_hash_clean_ex(HashTable *ht, int type) {
 	zend_ulong obj_key;
-	ZEND_HASH_FOREACH_NUM_KEY(ht, obj_key) {
-		zend_weakrefs_hash_del(ht, zend_weakref_key_to_object(obj_key));
+	ZEND_HASH_MAP_FOREACH_NUM_KEY(ht, obj_key) {
+		/* Optimization: Don't call zend_weakref_unref_single to free individual entries from ht when unregistering (which would do a hash table lookup, call zend_hash_index_del, and skip over any bucket collisions).
+		 * Let freeing the corresponding values for WeakMap entries be done in zend_hash_clean, freeing objects sequentially.
+		 * The performance difference is notable for larger WeakMaps with worse cache locality. */
+		zend_weakref_unregister(
+			zend_weakref_key_to_object(obj_key), ZEND_WEAKREF_ENCODE(ht, type), false);
 	} ZEND_HASH_FOREACH_END();
+	zend_hash_clean(ht);
+}
+
+ZEND_API void zend_weakrefs_hash_clean(HashTable *ht) {
+	zend_weakrefs_hash_clean_ex(ht, ZEND_WEAKREF_TAG_BARE_HT);
 }
 
 void zend_weakrefs_init(void) {
@@ -224,7 +235,7 @@ static zend_object* zend_weakref_new(zend_class_entry *ce) {
 static zend_always_inline bool zend_weakref_find(zend_object *referent, zval *return_value) {
 	void *tagged_ptr = zend_hash_index_find_ptr(&EG(weakrefs), zend_object_to_weakref_key(referent));
 	if (!tagged_ptr) {
-		return 0;
+		return false;
 	}
 
 	void *ptr = ZEND_WEAKREF_GET_PTR(tagged_ptr);
@@ -234,7 +245,7 @@ static zend_always_inline bool zend_weakref_find(zend_object *referent, zval *re
 found_weakref:
 		wr = ptr;
 		RETVAL_OBJ_COPY(&wr->std);
-		return 1;
+		return true;
 	}
 
 	if (tag == ZEND_WEAKREF_TAG_HT) {
@@ -246,7 +257,7 @@ static zend_always_inline bool zend_weakref_find(zend_object *referent, zval *re
 		} ZEND_HASH_FOREACH_END();
 	}
 
-	return 0;
+	return false;
 }
 
 static zend_always_inline void zend_weakref_create(zend_object *referent, zval *return_value) {
@@ -272,7 +283,7 @@ static void zend_weakref_free(zend_object *zo) {
 	zend_weakref *wr = zend_weakref_from(zo);
 
 	if (wr->referent) {
-		zend_weakref_unregister(wr->referent, ZEND_WEAKREF_ENCODE(wr, ZEND_WEAKREF_TAG_REF), 1);
+		zend_weakref_unregister(wr->referent, ZEND_WEAKREF_ENCODE(wr, ZEND_WEAKREF_TAG_REF), true);
 	}
 
 	zend_object_std_dtor(&wr->std);
@@ -336,14 +347,7 @@ static zend_object *zend_weakmap_create_object(zend_class_entry *ce)
 static void zend_weakmap_free_obj(zend_object *object)
 {
 	zend_weakmap *wm = zend_weakmap_from(object);
-	zend_ulong obj_key;
-	ZEND_HASH_MAP_FOREACH_NUM_KEY(&wm->ht, obj_key) {
-		/* Optimization: Don't call zend_weakref_unref_single to free individual entries from wm->ht when unregistering (which would do a hash table lookup, call zend_hash_index_del, and skip over any bucket collisions).
-		 * Let freeing the corresponding values for WeakMap entries be done in zend_hash_destroy, freeing objects sequentially.
-		 * The performance difference is notable for larger WeakMaps with worse cache locality. */
-		zend_weakref_unregister(
-			zend_weakref_key_to_object(obj_key), ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP), 0);
-	} ZEND_HASH_FOREACH_END();
+	zend_weakrefs_hash_clean_ex(&wm->ht, ZEND_WEAKREF_TAG_MAP);
 	zend_hash_destroy(&wm->ht);
 	zend_object_std_dtor(&wm->std);
 }
@@ -364,18 +368,25 @@ static zval *zend_weakmap_read_dimension(zend_object *object, zval *offset, int
 	zend_weakmap *wm = zend_weakmap_from(object);
 	zend_object *obj_addr = Z_OBJ_P(offset);
 	zval *zv = zend_hash_index_find(&wm->ht, zend_object_to_weakref_key(obj_addr));
-	if (zv == NULL) {
-		if (type != BP_VAR_IS) {
-			zend_throw_error(NULL,
-				"Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle);
+	if (type == BP_VAR_W || type == BP_VAR_RW) {
+		if (zv == NULL) {
+			zval value;
+			zend_weakref_register(obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
+			ZVAL_NULL(&value);
+			zv = zend_hash_index_add_new(&wm->ht, zend_object_to_weakref_key(obj_addr), &value);
+		}
+		ZVAL_MAKE_REF(zv);
+	} else {
+		if (zv == NULL) {
+			if (type != BP_VAR_IS) {
+				zend_throw_error(NULL,
+					"Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle);
+				return NULL;
+			}
 			return NULL;
 		}
-		return NULL;
 	}
 
-	if (type == BP_VAR_W || type == BP_VAR_RW) {
-		ZVAL_MAKE_REF(zv);
-	}
 	return zv;
 }
 
@@ -449,7 +460,7 @@ static void zend_weakmap_unset_dimension(zend_object *object, zval *offset)
 		return;
 	}
 
-	zend_weakref_unregister(obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP), 1);
+	zend_weakref_unregister(obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP), true);
 }
 
 static zend_result zend_weakmap_count_elements(zend_object *object, zend_long *count)
@@ -547,6 +558,10 @@ HashTable *zend_weakmap_get_object_key_entry_gc(zend_object *object, zval **tabl
 				ZEND_ASSERT(zv);
 				zend_get_gc_buffer_add_ptr(gc_buffer, zv);
 				zend_get_gc_buffer_add_obj(gc_buffer, &wm->std);
+			} else if (ZEND_WEAKREF_GET_TAG(tagged_ptr) == ZEND_WEAKREF_TAG_BARE_HT) {
+				/* Bare HashTables are intentionally ignored, since they are
+				 * intended for internal usage by extensions and might not be
+				 * collectable. */
 			}
 		} ZEND_HASH_FOREACH_END();
 	} else if (tag == ZEND_WEAKREF_TAG_MAP) {
@@ -555,6 +570,8 @@ HashTable *zend_weakmap_get_object_key_entry_gc(zend_object *object, zval **tabl
 		ZEND_ASSERT(zv);
 		zend_get_gc_buffer_add_ptr(gc_buffer, zv);
 		zend_get_gc_buffer_add_obj(gc_buffer, &wm->std);
+	} else if (tag == ZEND_WEAKREF_TAG_BARE_HT) {
+		/* Bare HashTables are intentionally ignored (see above) */
 	}
 
 	zend_get_gc_buffer_use(gc_buffer, table, n);
@@ -581,6 +598,9 @@ HashTable *zend_weakmap_get_object_entry_gc(zend_object *object, zval **table, i
 				zval *zv = zend_hash_index_find(&wm->ht, obj_key);
 				ZEND_ASSERT(zv);
 				zend_get_gc_buffer_add_ptr(gc_buffer, zv);
+			} else if (ZEND_WEAKREF_GET_TAG(tagged_ptr) == ZEND_WEAKREF_TAG_BARE_HT) {
+				/* Bare HashTables are intentionally ignored
+				 * (see zend_weakmap_get_object_key_entry_gc) */
 			}
 		} ZEND_HASH_FOREACH_END();
 	} else if (tag == ZEND_WEAKREF_TAG_MAP) {
@@ -588,6 +608,9 @@ HashTable *zend_weakmap_get_object_entry_gc(zend_object *object, zval **table, i
 		zval *zv = zend_hash_index_find(&wm->ht, obj_key);
 		ZEND_ASSERT(zv);
 		zend_get_gc_buffer_add_ptr(gc_buffer, zv);
+	} else if (tag == ZEND_WEAKREF_TAG_BARE_HT) {
+		/* Bare HashTables are intentionally ignored
+		 * (see zend_weakmap_get_object_key_entry_gc) */
 	}
 
 	zend_get_gc_buffer_use(gc_buffer, table, n);
@@ -648,7 +671,7 @@ static void zend_weakmap_iterator_get_current_key(zend_object_iterator *obj_iter
 
 	zend_string *string_key;
 	zend_ulong num_key;
-	int key_type = zend_hash_get_current_key_ex(&wm->ht, &string_key, &num_key, pos);
+	zend_hash_key_type key_type = zend_hash_get_current_key_ex(&wm->ht, &string_key, &num_key, pos);
 	if (key_type == HASH_KEY_NON_EXISTENT) {
 		ZVAL_NULL(key);
 		return;
@@ -713,7 +736,7 @@ ZEND_METHOD(WeakMap, offsetGet)
 		RETURN_THROWS();
 	}
 
-	ZVAL_COPY(return_value, zv);
+	RETURN_COPY_DEREF(zv);
 }
 
 ZEND_METHOD(WeakMap, offsetSet)
@@ -751,9 +774,7 @@ ZEND_METHOD(WeakMap, offsetUnset)
 
 ZEND_METHOD(WeakMap, count)
 {
-	if (zend_parse_parameters_none() == FAILURE) {
-		RETURN_THROWS();
-	}
+	ZEND_PARSE_PARAMETERS_NONE();
 
 	zend_long count;
 	zend_weakmap_count_elements(Z_OBJ_P(ZEND_THIS), &count);
@@ -762,9 +783,7 @@ ZEND_METHOD(WeakMap, count)
 
 ZEND_METHOD(WeakMap, getIterator)
 {
-	if (zend_parse_parameters_none() == FAILURE) {
-		RETURN_THROWS();
-	}
+	ZEND_PARSE_PARAMETERS_NONE();
 
 	zend_create_internal_iterator_zval(return_value, ZEND_THIS);
 }
@@ -777,7 +796,7 @@ void zend_register_weakref_ce(void) /* {{{ */
 	zend_ce_weakref->default_object_handlers = &zend_weakref_handlers;
 
 	memcpy(&zend_weakref_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
-	zend_weakref_handlers.offset = XtOffsetOf(zend_weakref, std);
+	zend_weakref_handlers.offset = offsetof(zend_weakref, std);
 
 	zend_weakref_handlers.free_obj = zend_weakref_free;
 	zend_weakref_handlers.get_debug_info = zend_weakref_get_debug_info;
@@ -790,7 +809,7 @@ void zend_register_weakref_ce(void) /* {{{ */
 	zend_ce_weakmap->default_object_handlers = &zend_weakmap_handlers;
 
 	memcpy(&zend_weakmap_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
-	zend_weakmap_handlers.offset = XtOffsetOf(zend_weakmap, std);
+	zend_weakmap_handlers.offset = offsetof(zend_weakmap, std);
 	zend_weakmap_handlers.free_obj = zend_weakmap_free_obj;
 	zend_weakmap_handlers.read_dimension = zend_weakmap_read_dimension;
 	zend_weakmap_handlers.write_dimension = zend_weakmap_write_dimension;
diff --git a/Zend/zend_weakrefs.h b/Zend/zend_weakrefs.h
index 00d4fbcc6bc4..41662c33a300 100644
--- a/Zend/zend_weakrefs.h
+++ b/Zend/zend_weakrefs.h
@@ -1,14 +1,12 @@
 /*
    +----------------------------------------------------------------------+
-   | Copyright (c) The PHP Group                                          |
+   | Copyright © The PHP Group and Contributors.                          |
    +----------------------------------------------------------------------+
-   | This source file is subject to version 2.00 of the Zend license,     |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.zend.com/license/2_00.txt.                                |
-   | If you did not receive a copy of the Zend license and are unable to  |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@zend.com so we can mail you a copy immediately.              |
+   | This source file is subject to the Modified BSD License that is      |
+   | bundled with this package in the file LICENSE, and is available      |
+   | through the World Wide Web at .        |
+   |                                                                      |
+   | SPDX-License-Identifier: BSD-3-Clause                                |
    +----------------------------------------------------------------------+
    | Authors: krakjoe@php.net                                             |
    +----------------------------------------------------------------------+
diff --git a/Zend/zend_weakrefs_arginfo.h b/Zend/zend_weakrefs_arginfo.h
index eba02f03fb13..90c4d42cf4d3 100644
--- a/Zend/zend_weakrefs_arginfo.h
+++ b/Zend/zend_weakrefs_arginfo.h
@@ -1,4 +1,4 @@
-/* This is a generated file, edit the .stub.php file instead.
+/* This is a generated file, edit zend_weakrefs.stub.php instead.
  * Stub hash: d91889851d9732d41e43fffddb6235d033c67534 */
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_WeakReference___construct, 0, 0, 0)
diff --git a/bench/bench_reification.php b/bench/bench_reification.php
new file mode 100644
index 000000000000..7bbb3ac5ff03
--- /dev/null
+++ b/bench/bench_reification.php
@@ -0,0 +1,828 @@
+ 0 ? $a_ns / $b_ns : 0;
+    printf("  %-55s %+9.1f ns/op delta  (%.2fx %s vs %s)\n",
+        $label, $delta, $ratio, $a_name, $b_name);
+}
+
+// --------------------------------------------------------------------------
+// Scenario 1: non-generic baseline — instantiation and method dispatch
+// --------------------------------------------------------------------------
+class PlainFoo { public int $x = 0; }
+class PlainBox {
+    public function __construct(public mixed $value = null) {}
+    public function tick(int $x): int { return $x + 1; }
+}
+
+function plain_new(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        new PlainFoo();
+    }
+}
+function plain_method(int $n): void {
+    $b = new PlainBox();
+    $acc = 0;
+    for ($i = 0; $i < $n; $i++) {
+        $acc = $b->tick($acc);
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 2: generic-class instantiation
+// --------------------------------------------------------------------------
+class GenBox {
+    public function __construct(public mixed $value = null) {}
+    public function tick(int $x): int { return $x + 1; }
+}
+class IntBox extends GenBox {}
+
+function gen_new_turbofish(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        new GenBox::();
+    }
+}
+function gen_new_default(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        new GenBox();
+    }
+}
+function gen_new_extends(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        new IntBox();
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 3: method dispatch on generic-class instance
+// --------------------------------------------------------------------------
+function gen_method_on_mono(int $n): void {
+    $b = new GenBox::();
+    $acc = 0;
+    for ($i = 0; $i < $n; $i++) {
+        $acc = $b->tick($acc);
+    }
+}
+function gen_method_on_default(int $n): void {
+    $b = new GenBox();
+    $acc = 0;
+    for ($i = 0; $i < $n; $i++) {
+        $acc = $b->tick($acc);
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 4: T-keyed expressions inside the body
+// --------------------------------------------------------------------------
+class Marker {}
+class TBox {
+    public function makeT(): object   { return new T(); }
+    public function classT(): string  { return T::class; }
+    public function isT(object $x): bool { return $x instanceof T; }
+}
+function tbox_makeT(int $n): void {
+    $b = new TBox::();
+    for ($i = 0; $i < $n; $i++) {
+        $b->makeT();
+    }
+}
+function tbox_classT(int $n): void {
+    $b = new TBox::();
+    for ($i = 0; $i < $n; $i++) {
+        $b->classT();
+    }
+}
+function tbox_isT(int $n): void {
+    $b = new TBox::();
+    $m = new Marker();
+    for ($i = 0; $i < $n; $i++) {
+        $b->isT($m);
+    }
+}
+function plain_makeT(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        new Marker();
+    }
+}
+function plain_classT(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        $_ = Marker::class;
+    }
+}
+function plain_isT(int $n): void {
+    $m = new Marker();
+    for ($i = 0; $i < $n; $i++) {
+        $_ = $m instanceof Marker;
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 5: inference vs turbofish vs non-generic
+// --------------------------------------------------------------------------
+class Foo { public int $tag = 0; }
+function makeGen(T $x): T { return $x; }
+function makeNonGen(Foo $x): Foo { return $x; }
+
+function infer_call(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        makeGen($f);
+    }
+}
+function turbofish_call(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        makeGen::($f);
+    }
+}
+function plain_call(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        makeNonGen($f);
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 6: multi-parameter inference
+// --------------------------------------------------------------------------
+class Bar { public int $tag = 0; }
+function makeTwoGen(T $x, U $y): T { return $x; }
+function makeTwoNonGen(Foo $x, Bar $y): Foo { return $x; }
+
+function infer_two(int $n): void {
+    $f = new Foo();
+    $b = new Bar();
+    for ($i = 0; $i < $n; $i++) {
+        makeTwoGen($f, $b);
+    }
+}
+function turbofish_two(int $n): void {
+    $f = new Foo();
+    $b = new Bar();
+    for ($i = 0; $i < $n; $i++) {
+        makeTwoGen::($f, $b);
+    }
+}
+function plain_two(int $n): void {
+    $f = new Foo();
+    $b = new Bar();
+    for ($i = 0; $i < $n; $i++) {
+        makeTwoNonGen($f, $b);
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 7: inference + bound conformance check
+// --------------------------------------------------------------------------
+function makeBounded(T $x): T { return $x; }
+
+function infer_bounded(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        makeBounded($f);
+    }
+}
+function turbofish_bounded(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        makeBounded::($f);
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 8: reified arg-type coercion (callee has T $x and turbofish)
+// --------------------------------------------------------------------------
+function takesT(T $x): T { return $x; }
+function takesTBounded(T $x): T { return $x; }
+function takesPlain(Foo $x): Foo { return $x; }
+
+function reified_arg_check(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        takesTBounded::($f);
+    }
+}
+function plain_arg_check(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        takesPlain($f);
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 9: forwarded T-refs — `id::($x)` inside a generic wrapper.
+// Exercises (a) per-call zend_type_arg_table build via the borrowed-pointer
+// chain, (b) zend_check_user_type_slow on the substituted type, and (c) the
+// VERIFY path that INSTALL can't elide (T-refs in turbofish).
+// --------------------------------------------------------------------------
+function idGen(T $x): T { return $x; }
+function nestedGen(U $x): U { return idGen::($x); }
+interface Fooable {}
+interface Barable {}
+class FooBar implements Fooable, Barable {}
+
+function forwarded_scalar(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        nestedGen::($i);
+    }
+}
+function direct_scalar(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        idGen::($i);
+    }
+}
+function forwarded_class(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        nestedGen::($f);
+    }
+}
+function direct_class(int $n): void {
+    $f = new Foo();
+    for ($i = 0; $i < $n; $i++) {
+        idGen::($f);
+    }
+}
+function forwarded_union(int $n): void {
+    for ($i = 0; $i < $n; $i++) {
+        nestedGen::($i);
+    }
+}
+function forwarded_intersection(int $n): void {
+    $fb = new FooBar();
+    for ($i = 0; $i < $n; $i++) {
+        nestedGen::($fb);
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 10: generic instanceof/catch in a hot inner loop — exercises the
+// polymorphic inline cache on the IS_UNUSED FETCH_CLASS path. The first
+// iteration misses; subsequent iterations within the same frame hit on a
+// pointer compare against (type_args generation, called_scope).
+// --------------------------------------------------------------------------
+class Container {}
+
+function instanceof_t_hot_loop(array $items): int {
+    $count = 0;
+    foreach ($items as $item) {
+        if ($item instanceof Container) {
+            $count++;
+        }
+    }
+    return $count;
+}
+function instanceof_concrete_hot_loop(array $items): int {
+    $count = 0;
+    foreach ($items as $item) {
+        if ($item instanceof Container) {
+            $count++;
+        }
+    }
+    return $count;
+}
+
+function bench_instanceof_t(int $n): void {
+    $items = [new Container::(), new Container::(), new Foo()];
+    /* outer N drives the inner-loop count via a fixed batch — keeps the
+     * PIC slot warm across iterations of the body. */
+    instanceof_t_hot_loop::(array_fill(0, $n, $items[0]));
+}
+function bench_instanceof_concrete(int $n): void {
+    $items = [new Container::(), new Container::(), new Foo()];
+    instanceof_concrete_hot_loop(array_fill(0, $n, $items[0]));
+}
+
+// --------------------------------------------------------------------------
+// Driver
+// --------------------------------------------------------------------------
+echo "PHP ", PHP_VERSION, " (", PHP_BINARY, ")\n";
+echo "Reified bound-erased generics benchmark\n";
+
+section("1. Non-generic baseline");
+$plain_new_ns    = bench("plain new Foo()",              'plain_new');
+$plain_method_ns = bench("plain \$box->tick()",           'plain_method');
+
+section("2. Generic-class instantiation");
+$gen_tf_ns       = bench("new GenBox::()",          'gen_new_turbofish');
+$gen_def_ns      = bench("new GenBox() (default T=int)", 'gen_new_default');
+$gen_ext_ns      = bench("new IntBox() (extends GenBox)", 'gen_new_extends');
+compare("delta: GenBox          vs PlainFoo", $gen_tf_ns,  "gen",   $plain_new_ns, "plain");
+compare("delta: GenBox (default)     vs PlainFoo", $gen_def_ns, "gen",   $plain_new_ns, "plain");
+compare("delta: IntBox extends       vs PlainFoo", $gen_ext_ns, "gen",   $plain_new_ns, "plain");
+
+section("3. Method dispatch on generic-class receiver");
+$gen_mono_method_ns    = bench("GenBox->tick()",          'gen_method_on_mono');
+$gen_default_method_ns = bench("GenBox(default)->tick()",      'gen_method_on_default');
+compare("delta: GenBox->tick    vs PlainBox->tick", $gen_mono_method_ns, "gen", $plain_method_ns, "plain");
+
+section("4. T-keyed body expressions");
+$tbox_makeT_ns  = bench("TBox->makeT()",   'tbox_makeT');
+$plain_makeT_ns = bench("new Marker() direct",     'plain_makeT');
+compare("delta: new T()              vs new Marker()", $tbox_makeT_ns, "T", $plain_makeT_ns, "direct");
+$tbox_classT_ns  = bench("TBox->classT()",  'tbox_classT');
+$plain_classT_ns = bench("Marker::class direct",    'plain_classT');
+compare("delta: T::class             vs Marker::class", $tbox_classT_ns, "T", $plain_classT_ns, "direct");
+$tbox_isT_ns  = bench("TBox->isT()",     'tbox_isT');
+$plain_isT_ns = bench("\$x instanceof Marker direct", 'plain_isT');
+compare("delta: instanceof T         vs instanceof Marker", $tbox_isT_ns, "T", $plain_isT_ns, "direct");
+
+section("5. Inference vs turbofish vs non-generic call");
+$infer_ns    = bench("makeGen(\$x)  — inference",       'infer_call');
+$turbo_ns    = bench("makeGen::(\$x) — turbofish", 'turbofish_call');
+$plain_fn_ns = bench("makeNonGen(\$x) — no generics",   'plain_call');
+compare("delta: inference            vs plain", $infer_ns, "infer", $plain_fn_ns, "plain");
+compare("delta: turbofish            vs plain", $turbo_ns, "turbo", $plain_fn_ns, "plain");
+compare("delta: inference            vs turbofish", $infer_ns, "infer", $turbo_ns, "turbo");
+
+section("6. Multi-parameter inference");
+$infer2_ns = bench("makeTwoGen(\$f,\$b)  — infer T,U",   'infer_two');
+$turbo2_ns = bench("makeTwoGen::  — turbofish", 'turbofish_two');
+$plain2_ns = bench("makeTwoNonGen(\$f,\$b)",             'plain_two');
+compare("delta: infer T,U            vs plain", $infer2_ns, "infer2", $plain2_ns, "plain");
+compare("delta: turbofish T,U        vs plain", $turbo2_ns, "turbo2", $plain2_ns, "plain");
+
+section("7. Inference + bound check");
+$infer_bd_ns = bench("makeBounded(\$x) — infer + bound",   'infer_bounded');
+$turbo_bd_ns = bench("makeBounded::(\$x) — turbo+bd", 'turbofish_bounded');
+compare("delta: infer+bound          vs infer (no bound)", $infer_bd_ns, "ibnd", $infer_ns,  "infer");
+compare("delta: turbo+bound          vs turbo (no bound)", $turbo_bd_ns, "tbnd", $turbo_ns, "turbo");
+
+section("8. Reified arg-type coercion");
+$reified_arg_ns = bench("takesTBounded::(\$f)", 'reified_arg_check');
+$plain_arg_ns   = bench("takesPlain(\$f)",            'plain_arg_check');
+compare("delta: reified arg check    vs plain typed arg", $reified_arg_ns, "reif", $plain_arg_ns, "plain");
+
+section("9. Forwarded T-refs (nested generic calls)");
+$fwd_scalar_ns  = bench("nestedGen::(\$i) — forwarded scalar",     'forwarded_scalar');
+$dir_scalar_ns  = bench("idGen::(\$i)     — direct scalar",         'direct_scalar');
+compare("delta: forwarded scalar     vs direct scalar", $fwd_scalar_ns, "fwd", $dir_scalar_ns, "dir");
+$fwd_class_ns   = bench("nestedGen::(\$f) — forwarded class",       'forwarded_class');
+$dir_class_ns   = bench("idGen::(\$f)     — direct class",          'direct_class');
+compare("delta: forwarded class      vs direct class", $fwd_class_ns, "fwd", $dir_class_ns, "dir");
+$fwd_union_ns   = bench("nestedGen::     — forwarded union", 'forwarded_union', ITERS_LIGHT);
+$fwd_inter_ns   = bench("nestedGen:: — forwarded ix",   'forwarded_intersection', ITERS_LIGHT);
+compare("delta: forwarded union      vs forwarded scalar", $fwd_union_ns, "uni", $fwd_scalar_ns, "scl");
+
+section("10. Generic instanceof in hot inner loop (PIC)");
+$inst_t_ns        = bench("instanceof Container (PIC warm)", 'bench_instanceof_t');
+$inst_concrete_ns = bench("instanceof Container    (cache slot)", 'bench_instanceof_concrete');
+compare("delta: instanceof T         vs instanceof bare", $inst_t_ns, "T", $inst_concrete_ns, "bare");
+
+// --------------------------------------------------------------------------
+// Scenario 11: depth scaling for nested monomorph instantiation.
+// All monomorphs are synthesized + cached on first use; the hot loop is
+// supposed to hit the class-table lookup at pointer-compare speed regardless
+// of nesting depth. If the cost grows with depth in the hot path, something
+// is being recomputed per call (canonical-name string build, arg-table
+// rebuild, etc.).
+// --------------------------------------------------------------------------
+class L1 {}
+class L2 {}
+class L3 {}
+class L4 {}
+
+function deep_new_d1(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new L1::(); }
+}
+function deep_new_d2(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new L1::>(); }
+}
+function deep_new_d3(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new L1::>>(); }
+}
+function deep_new_d4(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new L1::>>>(); }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 12: composite type arguments (union, intersection, DNF).
+// Canonicalization sorts the alternatives, so equivalent shapes converge on
+// the same monomorph name.
+// --------------------------------------------------------------------------
+interface Ifc1 {}
+interface Ifc2 {}
+class Holder1 {}
+
+function comp_concrete(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new Holder1::(); }
+}
+function comp_union(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new Holder1::(); }
+}
+function comp_intersection(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new Holder1::(); }
+}
+function comp_dnf(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new Holder1::<(Ifc1&Ifc2)|int>(); }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 13: bounded inner parameter — the `A>` pattern where
+// the inner C declares its own bound, so synthesizing the outer monomorph
+// triggers a bound-conformance check on the inner application.
+// --------------------------------------------------------------------------
+class FBound {}
+class FSub extends FBound {}
+class WithBound {}
+class WithoutBound {}
+
+function nested_bounded_only(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new WithBound::(); }
+}
+function nested_outer_around_bounded(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new WithoutBound::>(); }
+}
+function nested_intersection_with_bounded(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new WithoutBound::>(); }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 14: instanceof on deeply-nested monomorphs. The polymorphic
+// inline cache should make depth irrelevant after warmup — the slot just
+// caches the resolved ce.
+// --------------------------------------------------------------------------
+function deep_instanceof_d1(int $n): void {
+    $box = new L1::();
+    for ($i = 0; $i < $n; $i++) { $_ = $box instanceof L1; }
+}
+function deep_instanceof_d3(int $n): void {
+    $box = new L1::>>();
+    for ($i = 0; $i < $n; $i++) { $_ = $box instanceof L1>>; }
+}
+function deep_instanceof_d3_mismatch(int $n): void {
+    $box = new L1::>>();
+    for ($i = 0; $i < $n; $i++) { $_ = $box instanceof L1>>; }
+}
+function deep_instanceof_d3_bare(int $n): void {
+    $box = new L1::>>();
+    for ($i = 0; $i < $n; $i++) { $_ = $box instanceof L1; }
+}
+
+section("11. Depth scaling — nested monomorph `new`");
+$d1_ns = bench("new L1            (depth 1)", 'deep_new_d1');
+$d2_ns = bench("new L1>        (depth 2)", 'deep_new_d2');
+$d3_ns = bench("new L1>>    (depth 3)", 'deep_new_d3');
+$d4_ns = bench("new L1>>> (depth 4)", 'deep_new_d4');
+compare("delta: depth 2              vs depth 1", $d2_ns, "d2", $d1_ns, "d1");
+compare("delta: depth 3              vs depth 1", $d3_ns, "d3", $d1_ns, "d1");
+compare("delta: depth 4              vs depth 1", $d4_ns, "d4", $d1_ns, "d1");
+
+section("12. Composite type-argument shapes");
+$cc_ns = bench("new Holder1",                 'comp_concrete');
+$cu_ns = bench("new Holder1",          'comp_union');
+$ci_ns = bench("new Holder1",           'comp_intersection');
+$cd_ns = bench("new Holder1<(Ifc1&Ifc2)|int>",     'comp_dnf');
+compare("delta: union                vs concrete",       $cu_ns, "uni", $cc_ns, "cnc");
+compare("delta: intersection         vs concrete",       $ci_ns, "ix",  $cc_ns, "cnc");
+compare("delta: DNF                  vs concrete",       $cd_ns, "dnf", $cc_ns, "cnc");
+
+section("13. Bounded inner parameter (`A>` pattern)");
+$nb_ns  = bench("new WithBound           (just the inner)",       'nested_bounded_only');
+$nob_ns = bench("new WithoutBound>",                    'nested_outer_around_bounded');
+$nix_ns = bench("new WithoutBound>",             'nested_intersection_with_bounded');
+compare("delta: outer wraps bounded  vs inner alone",   $nob_ns, "out", $nb_ns,  "inner");
+compare("delta: intersection w/bound vs outer alone",   $nix_ns, "ix",  $nob_ns, "out");
+
+section("14. Deep `instanceof` (PIC vs depth)");
+$di1_ns = bench("instanceof L1             (depth 1)",              'deep_instanceof_d1');
+$di3_ns = bench("instanceof L1>>     (depth 3, match)",       'deep_instanceof_d3');
+$dim_ns = bench("instanceof L1>>  (depth 3, mismatch)",    'deep_instanceof_d3_mismatch');
+$dib_ns = bench("instanceof L1                  (bare, hits ancestor)",  'deep_instanceof_d3_bare');
+compare("delta: depth 3 match        vs depth 1 match", $di3_ns, "d3", $di1_ns, "d1");
+compare("delta: depth 3 mismatch     vs depth 3 match", $dim_ns, "mis", $di3_ns, "mat");
+compare("delta: bare ancestor        vs depth 3 match", $dib_ns, "bare", $di3_ns, "d3");
+
+// --------------------------------------------------------------------------
+// Scenario 15: deep parameter type check at RECV. The arg_info type is now
+// the canonical monomorph (`Box>>`), so RECV's instanceof_function
+// resolves and enforces the full identity — passing the wrong monomorph
+// rejects, not silently accepts. After warmup the class-lookup cache makes
+// the check the same speed as a non-generic typed param.
+// --------------------------------------------------------------------------
+class DPlain {}
+class DBox {}
+
+function takes_plain(DPlain $x): void {}
+function takes_d1(DBox $x): void {}
+function takes_d2(DBox> $x): void {}
+function takes_d3(DBox>> $x): void {}
+function takes_d4(DBox>>> $x): void {}
+
+function bench_param_plain(int $n): void {
+    $v = new DPlain();
+    for ($i = 0; $i < $n; $i++) { takes_plain($v); }
+}
+function bench_param_d1(int $n): void {
+    $v = new DBox::();
+    for ($i = 0; $i < $n; $i++) { takes_d1($v); }
+}
+function bench_param_d2(int $n): void {
+    $v = new DBox::>();
+    for ($i = 0; $i < $n; $i++) { takes_d2($v); }
+}
+function bench_param_d3(int $n): void {
+    $v = new DBox::>>();
+    for ($i = 0; $i < $n; $i++) { takes_d3($v); }
+}
+function bench_param_d4(int $n): void {
+    $v = new DBox::>>>();
+    for ($i = 0; $i < $n; $i++) { takes_d4($v); }
+}
+
+section("15. Deep parameter type check (RECV reifies the full monomorph)");
+$p_pl_ns = bench("f(DPlain \$x)                  (non-generic baseline)", 'bench_param_plain');
+$p_d1_ns = bench("f(DBox \$x)               (depth 1)",              'bench_param_d1');
+$p_d2_ns = bench("f(DBox> \$x)           (depth 2)",              'bench_param_d2');
+$p_d3_ns = bench("f(DBox>> \$x)       (depth 3)",              'bench_param_d3');
+$p_d4_ns = bench("f(DBox>>> \$x)   (depth 4)",              'bench_param_d4');
+compare("delta: deep d1              vs plain", $p_d1_ns, "d1", $p_pl_ns, "plain");
+compare("delta: deep d4              vs plain", $p_d4_ns, "d4", $p_pl_ns, "plain");
+compare("delta: deep d4              vs deep d1", $p_d4_ns, "d4", $p_d1_ns, "d1");
+
+// --------------------------------------------------------------------------
+// Scenario 16: inference from a deep-typed value. The compiler can't
+// destructure `Box` into a T-binding at the call site (only bare T
+// params are inferable), but `id(T $x)` does pick up the value's full
+// runtime monomorph as T. Compare to explicit turbofish with the same deep
+// type, and to the equivalent non-generic call.
+// --------------------------------------------------------------------------
+function id_gen(T $x): T { return $x; }
+
+function bench_infer_d1(int $n): void {
+    $v = new DBox::();
+    for ($i = 0; $i < $n; $i++) { id_gen($v); }
+}
+function bench_infer_d3(int $n): void {
+    $v = new DBox::>>();
+    for ($i = 0; $i < $n; $i++) { id_gen($v); }
+}
+function bench_turbofish_d3(int $n): void {
+    $v = new DBox::>>();
+    for ($i = 0; $i < $n; $i++) { id_gen::>>>($v); }
+}
+function bench_plain_pass(int $n): void {
+    $v = new DPlain();
+    for ($i = 0; $i < $n; $i++) { takes_plain($v); }
+}
+
+section("16. Inference / turbofish with deep value");
+$inf1_ns = bench("id(DBox)                  — inferred",             'bench_infer_d1');
+$inf3_ns = bench("id(DBox>>)          — inferred",             'bench_infer_d3');
+$tf3_ns  = bench("id::>>>(\$v)    — turbofish",           'bench_turbofish_d3');
+$plp_ns  = bench("takes_plain(\$plain)            — non-generic ref",     'bench_plain_pass');
+compare("delta: inferred d1          vs plain", $inf1_ns, "infD1", $plp_ns, "plain");
+compare("delta: inferred d3          vs plain", $inf3_ns, "infD3", $plp_ns, "plain");
+compare("delta: turbofish d3         vs inferred d3", $tf3_ns,  "tf",   $inf3_ns, "inf");
+
+// --------------------------------------------------------------------------
+// Scenario 17: method dispatch on a deep generic receiver. The receiver's
+// class is the monomorph (e.g., DReceiver>>); the method lookup
+// goes through the monomorph's function table. Hot loops with the same
+// receiver class should pay zero depth penalty after warmup.
+// --------------------------------------------------------------------------
+class DReceiver {
+    public function tick(int $x): int { return $x + 1; }
+}
+class DReceiverPlain {
+    public function tick(int $x): int { return $x + 1; }
+}
+
+function bench_recv_plain(int $n): void {
+    $r = new DReceiverPlain();
+    $acc = 0;
+    for ($i = 0; $i < $n; $i++) { $acc = $r->tick($acc); }
+}
+function bench_recv_d1(int $n): void {
+    $r = new DReceiver::();
+    $acc = 0;
+    for ($i = 0; $i < $n; $i++) { $acc = $r->tick($acc); }
+}
+function bench_recv_d3(int $n): void {
+    $r = new DReceiver::>>();
+    $acc = 0;
+    for ($i = 0; $i < $n; $i++) { $acc = $r->tick($acc); }
+}
+
+section("17. Method dispatch on a deep generic receiver");
+$mr_pl_ns = bench("DReceiverPlain->tick()           (non-generic)",        'bench_recv_plain');
+$mr_d1_ns = bench("DReceiver->tick()           (depth 1)",            'bench_recv_d1');
+$mr_d3_ns = bench("DReceiver>>->tick()   (depth 3)",            'bench_recv_d3');
+compare("delta: receiver d1          vs plain", $mr_d1_ns, "d1", $mr_pl_ns, "plain");
+compare("delta: receiver d3          vs d1",    $mr_d3_ns, "d3", $mr_d1_ns, "d1");
+
+// --------------------------------------------------------------------------
+// Scenario 18: pass-through with deep param + deep return. Two RECV checks
+// per call (param + return), each resolving a deep monomorph class.
+// --------------------------------------------------------------------------
+function passthrough_plain(DPlain $x): DPlain { return $x; }
+function passthrough_d3(DBox>> $x): DBox>> { return $x; }
+
+function bench_passthrough_plain(int $n): void {
+    $v = new DPlain();
+    for ($i = 0; $i < $n; $i++) { passthrough_plain($v); }
+}
+function bench_passthrough_d3(int $n): void {
+    $v = new DBox::>>();
+    for ($i = 0; $i < $n; $i++) { passthrough_d3($v); }
+}
+
+section("18. Pass-through (param + return both deep)");
+$pt_pl_ns = bench("DPlain f(DPlain \$x): DPlain",                          'bench_passthrough_plain');
+$pt_d3_ns = bench("DBox>> f(DBox>> \$x): same",      'bench_passthrough_d3');
+compare("delta: deep passthrough     vs plain passthrough", $pt_d3_ns, "d3", $pt_pl_ns, "plain");
+
+// ============================================================================
+// PATHOLOGICAL — looking for super-linear blowup.
+// Each scenario varies one structural dimension while holding the others
+// constant. If the cost grows worse than linearly in that dimension, the
+// implementation has a problem worth flagging.
+// ============================================================================
+
+// --------------------------------------------------------------------------
+// Scenario 19: canonical-name traversal depth. Building "Box>>"
+// touches every layer of the tree. Linear depth → linear cost is the goal.
+// --------------------------------------------------------------------------
+class CB {}
+function cn_d1(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CB::(); }
+}
+function cn_d3(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CB::>>(); }
+}
+function cn_d5(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CB::>>>>(); }
+}
+function cn_d8(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CB::>>>>>>>(); }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 20: wide DNF — many alternatives in a union of intersections.
+// Pre-erasure value check loops over alternatives; worst case is O(width).
+// --------------------------------------------------------------------------
+interface DA {} interface DB {} interface DC {} interface DD {}
+interface DE {} interface DF {} interface DG {} interface DH {}
+class Hits implements DA, DB, DC, DD, DE, DF, DG, DH {}
+function dnf_w2(T $x): T { return $x; }
+function dnf_w4(T $x): T { return $x; }
+function dnf_w2_call(int $n): void {
+    $v = new Hits();
+    for ($i = 0; $i < $n; $i++) { dnf_w2($v); }
+}
+function dnf_w4_call(int $n): void {
+    $v = new Hits();
+    for ($i = 0; $i < $n; $i++) { dnf_w4($v); }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 21: diamond inheritance binding chain. D extends C>>
+// resolution. Bench the act of constructing instances through the chain.
+// --------------------------------------------------------------------------
+class CL1 {}
+class CL2 extends CL1 {}
+class CL3 extends CL2 {}
+class CL4 extends CL3 {}
+class CL5 extends CL4 {}
+function chain_d2(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CL2::(); }
+}
+function chain_d3(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CL3::(); }
+}
+function chain_d4(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CL4::(); }
+}
+function chain_d5(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new CL5::(); }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 22: polymorphic inline cache thrashing. The PIC at instanceof/
+// catch keys on (type_args generation, called_scope). A hot loop that
+// switches the binding per iteration should miss the cache every time,
+// turning O(1) into an O(class-table-lookup) cost per iteration.
+// --------------------------------------------------------------------------
+class PicBox {}
+function pic_stable(array $items): int {
+    $count = 0;
+    foreach ($items as $item) {
+        if ($item instanceof PicBox) { $count++; }
+    }
+    return $count;
+}
+/* Outer loop alternates the T binding per call — every entry into the inner
+ * loop sees a different type_args generation, so the PIC slot mismatches
+ * and re-resolves on the first item. The inner loop then runs warm. */
+function bench_pic_stable_int(int $n): void {
+    $items = array_fill(0, 16, new PicBox::());
+    for ($i = 0; $i < $n; $i++) {
+        pic_stable::($items);
+    }
+}
+function bench_pic_alternating(int $n): void {
+    $items = array_fill(0, 16, new PicBox::());
+    /* call alternates T between int and string — each call's args_box has
+     * a different cache key, so the per-call type_arg_table differs and
+     * the inner-loop PIC must re-resolve at least once per call. */
+    for ($i = 0; $i < $n; $i++) {
+        if ($i & 1) {
+            pic_stable::($items);
+        } else {
+            pic_stable::($items);
+        }
+    }
+}
+
+// --------------------------------------------------------------------------
+// Scenario 23: bound-conformance check on deeply-nested args. Each level of
+// nesting may trigger an additional recursive call into the variance/bound
+// machinery.
+// --------------------------------------------------------------------------
+class BX {}
+function bnd_d1(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new BX::(); }
+}
+function bnd_d3(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new BX::>>(); }
+}
+function bnd_d5(int $n): void {
+    for ($i = 0; $i < $n; $i++) { new BX::>>>>(); }
+}
+
+section("19. Canonical-name traversal depth");
+$cn1_ns = bench("new CB                          (depth 1)",   'cn_d1');
+$cn3_ns = bench("new CB>>                  (depth 3)",   'cn_d3');
+$cn5_ns = bench("new CB>>>>          (depth 5)",   'cn_d5');
+$cn8_ns = bench("new CB<...x8 levels...>         (depth 8)",   'cn_d8');
+compare("delta: d3 vs d1               (3x deeper)", $cn3_ns, "d3", $cn1_ns, "d1");
+compare("delta: d5 vs d1               (5x deeper)", $cn5_ns, "d5", $cn1_ns, "d1");
+compare("delta: d8 vs d1               (8x deeper)", $cn8_ns, "d8", $cn1_ns, "d1");
+
+section("20. Wide DNF bound — value check across union of intersections");
+$dnf2_ns = bench("dnf<(DA&DB)|(DC&DD)>(Hits) — 2 alts",      'dnf_w2_call');
+$dnf4_ns = bench("dnf<(DA&DB)|(DC&DD)|(DE&DF)|(DG&DH)> — 4", 'dnf_w4_call');
+compare("delta: 4 alts vs 2 alts        (2x wider)", $dnf4_ns, "w4", $dnf2_ns, "w2");
+
+section("21. Inheritance binding chain depth");
+$ch2_ns = bench("new CL2             (chain depth 2)",  'chain_d2');
+$ch3_ns = bench("new CL3             (chain depth 3)",  'chain_d3');
+$ch4_ns = bench("new CL4             (chain depth 4)",  'chain_d4');
+$ch5_ns = bench("new CL5             (chain depth 5)",  'chain_d5');
+compare("delta: chain 3 vs chain 2",     $ch3_ns, "c3", $ch2_ns, "c2");
+compare("delta: chain 5 vs chain 2",     $ch5_ns, "c5", $ch2_ns, "c2");
+
+section("22. PIC thrashing (alternating T)");
+$pic_st_ns = bench("instanceof PicBox — stable T (PIC warm)",  'bench_pic_stable_int',  ITERS_LIGHT);
+$pic_alt_ns = bench("instanceof PicBox — alternating T",       'bench_pic_alternating', ITERS_LIGHT);
+compare("delta: alternating vs stable", $pic_alt_ns, "alt", $pic_st_ns, "stable");
+
+section("23. Bound-conformance depth");
+$bd1_ns = bench("new BX           (depth 1, bound: object)",       'bnd_d1');
+$bd3_ns = bench("new BX>>   (depth 3)",                      'bnd_d3');
+$bd5_ns = bench("new BX<...x5 nested...>  (depth 5)",                      'bnd_d5');
+compare("delta: d3 vs d1               (3x deeper)", $bd3_ns, "d3", $bd1_ns, "d1");
+compare("delta: d5 vs d1               (5x deeper)", $bd5_ns, "d5", $bd1_ns, "d1");
+
+$opcache_loaded = extension_loaded('Zend OPcache');
+$opcache_on = $opcache_loaded
+    && function_exists('opcache_get_status')
+    && (bool) (opcache_get_status(false)['opcache_enabled'] ?? false);
+$jit_on = false;
+if ($opcache_on) {
+    $status = opcache_get_status(false);
+    /* 'enabled' = JIT is built into this opcache; 'on' = JIT is active at runtime */
+    $jit_on = (bool) ($status['jit']['on'] ?? false);
+}
+$opcache_label = $opcache_on
+    ? ('enabled' . ($jit_on ? ' + JIT' : ', JIT off'))
+    : ($opcache_loaded ? 'loaded but disabled (opcache.enable_cli=0)' : 'not loaded');
+echo "\nNote: opcache is $opcache_label. Same build, same interpreter\n";
+echo "      path across all scenarios — deltas between rows are the signal.\n";
diff --git a/benchmark/generate_diff.php b/benchmark/generate_diff.php
index 94c020df4b99..466a6ae0e1ed 100644
--- a/benchmark/generate_diff.php
+++ b/benchmark/generate_diff.php
@@ -62,7 +62,7 @@ function formatDiff(?int $baseInstructions, int $headInstructions): string {
 }
 
 function find_benchmarked_commit_hash(string $repo, string $commitHash): ?string {
-    $repeat = 10;
+    $repeat = 100;
 
     while (true) {
         if ($repeat-- <= 0) {
diff --git a/build/Makefile.gcov b/build/Makefile.gcov
index de85893398cd..5097bfaaa277 100644
--- a/build/Makefile.gcov
+++ b/build/Makefile.gcov
@@ -16,15 +16,6 @@ LCOV_EXCLUDES = \
 	'$(top_srcdir)/parse_date.re' \
 	'$(top_srcdir)/parse_iso_intervals.re'
 
-GCOVR_EXCLUDES = \
-	'ext/bcmath/libbcmath/.*' \
-	'ext/date/lib/.*' \
-	'ext/fileinfo/libmagic/.*' \
-	'ext/gd/libgd/.*' \
-	'ext/hash/sha3/.*' \
-	'ext/mbstring/libmbfl/.*' \
-	'ext/pcre/pcre2lib/.*'
-
 lcov: lcov-html
 
 php_lcov.info:
@@ -48,15 +39,11 @@ gcovr-html:
 	@echo "Generating gcovr HTML"
 	@rm -rf gcovr_html/
 	@mkdir gcovr_html
-	gcovr -sr . -o gcovr_html/index.html --html --html-details \
-		--exclude-directories 'ext/date/lib$$' \
-		$(foreach lib, $(GCOVR_EXCLUDES), -e $(lib))
+	gcovr -r . -o gcovr_html/index.html --html --html-details
 
 gcovr-xml:
 	@echo "Generating gcovr XML"
 	@rm -f gcovr.xml
-	gcovr -sr . -o gcovr.xml --xml \
-		--exclude-directories 'ext/date/lib$$' \
-		$(foreach lib, $(GCOVR_EXCLUDES), -e $(lib))
+	gcovr -r . -o gcovr.xml --xml
 
 .PHONY: gcovr-html lcov-html php_lcov.info
diff --git a/build/Makefile.global b/build/Makefile.global
index 32605a203e18..16d57b54c831 100644
--- a/build/Makefile.global
+++ b/build/Makefile.global
@@ -89,7 +89,7 @@ PHP_TEST_SHARED_EXTENSIONS =  ` \
 			. $$i; $(top_srcdir)/build/shtool echo -n -- " -d zend_extension=$(top_builddir)/modules/$$dlname"; \
 		done; \
 	fi`
-PHP_DEPRECATED_DIRECTIVES_REGEX = '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?|session\.sid_(length|bits_per_character))[\t\ ]*='
+PHP_DEPRECATED_DIRECTIVES_REGEX = '^[\t\ ]*(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?|session\.sid_(length|bits_per_character))[\t\ ]*='
 
 test: all
 	@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
diff --git a/build/ax_check_compile_flag.m4 b/build/ax_check_compile_flag.m4
index 68fd43d5ddb0..54191c55353e 100644
--- a/build/ax_check_compile_flag.m4
+++ b/build/ax_check_compile_flag.m4
@@ -34,14 +34,24 @@
 #   and this notice are preserved.  This file is offered as-is, without any
 #   warranty.
 
-#serial 7
+#serial 11
 
 AC_DEFUN([AX_CHECK_COMPILE_FLAG],
 [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
 AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
 AC_CACHE_CHECK([whether the _AC_LANG compiler accepts $1], CACHEVAR, [
   ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
-  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  if test x"m4_case(_AC_LANG,
+                     [C], [$GCC],
+                     [C++], [$GXX],
+                     [Fortran], [$GFC],
+                     [Fortran 77], [$G77],
+                     [Objective C], [$GOBJC],
+                     [Objective C++], [$GOBJCXX],
+                     [no])" = xyes ; then
+    add_gnu_werror="-Werror"
+  fi
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1 $add_gnu_werror"
   AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
     [AS_VAR_SET(CACHEVAR,[yes])],
     [AS_VAR_SET(CACHEVAR,[no])])
diff --git a/build/config.guess b/build/config.guess
index 48a684601bd2..a9d01fde4617 100755
--- a/build/config.guess
+++ b/build/config.guess
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2024 Free Software Foundation, Inc.
+#   Copyright 1992-2025 Free Software Foundation, Inc.
 
 # shellcheck disable=SC2006,SC2268 # see below for rationale
 
-timestamp='2024-07-27'
+timestamp='2025-07-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -60,7 +60,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2024 Free Software Foundation, Inc.
+Copyright 1992-2025 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -1597,8 +1597,11 @@ EOF
     *:Unleashed:*:*)
 	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
 	;;
-    *:Ironclad:*:*)
-	GUESS=$UNAME_MACHINE-unknown-ironclad
+    x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*)
+	GUESS=$UNAME_MACHINE-pc-ironclad-mlibc
+	;;
+    *:[Ii]ronclad:*:*)
+	GUESS=$UNAME_MACHINE-unknown-ironclad-mlibc
 	;;
 esac
 
@@ -1808,8 +1811,8 @@ fi
 exit 1
 
 # Local variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
 # time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-format: "%Y-%02m-%02d"
 # time-stamp-end: "'"
 # End:
diff --git a/build/config.sub b/build/config.sub
index 4aaae46f6f74..3d35cde174de 100755
--- a/build/config.sub
+++ b/build/config.sub
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2024 Free Software Foundation, Inc.
+#   Copyright 1992-2025 Free Software Foundation, Inc.
 
 # shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale
 
-timestamp='2024-05-27'
+timestamp='2025-07-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -76,7 +76,7 @@ Report bugs and patches to ."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2024 Free Software Foundation, Inc.
+Copyright 1992-2025 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -145,6 +145,7 @@ case $1 in
 			| kfreebsd*-gnu* \
 			| knetbsd*-gnu* \
 			| kopensolaris*-gnu* \
+			| ironclad-* \
 			| linux-* \
 			| managarm-* \
 			| netbsd*-eabi* \
@@ -242,7 +243,6 @@ case $1 in
 					| rombug \
 					| semi \
 					| sequent* \
-					| siemens \
 					| sgi* \
 					| siemens \
 					| sim \
@@ -261,7 +261,7 @@ case $1 in
 						basic_machine=$field1-$field2
 						basic_os=
 						;;
-					zephyr*)
+					tock* | zephyr*)
 						basic_machine=$field1-unknown
 						basic_os=$field2
 						;;
@@ -1194,7 +1194,7 @@ case $cpu-$vendor in
 	xscale-* | xscalee[bl]-*)
 		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
 		;;
-	arm64-* | aarch64le-*)
+	arm64-* | aarch64le-* | arm64_32-*)
 		cpu=aarch64
 		;;
 
@@ -1321,6 +1321,7 @@ case $cpu-$vendor in
 			| i960 \
 			| ia16 \
 			| ia64 \
+			| intelgt \
 			| ip2k \
 			| iq2000 \
 			| javascript \
@@ -1522,6 +1523,10 @@ EOF
 		kernel=nto
 		os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
 		;;
+	ironclad*)
+		kernel=ironclad
+		os=`echo "$basic_os" | sed -e 's|ironclad|mlibc|'`
+		;;
 	linux*)
 		kernel=linux
 		os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
@@ -1976,6 +1981,7 @@ case $os in
 	| atheos* \
 	| auroraux* \
 	| aux* \
+	| banan_os* \
 	| beos* \
 	| bitrig* \
 	| bme* \
@@ -2022,7 +2028,6 @@ case $os in
 	| ios* \
 	| iris* \
 	| irix* \
-	| ironclad* \
 	| isc* \
 	| its* \
 	| l4re* \
@@ -2118,6 +2123,7 @@ case $os in
 	| sysv* \
 	| tenex* \
 	| tirtos* \
+	| tock* \
 	| toppers* \
 	| tops10* \
 	| tops20* \
@@ -2214,6 +2220,8 @@ case $kernel-$os-$obj in
 		;;
 	uclinux-uclibc*- | uclinux-gnu*- )
 		;;
+	ironclad-mlibc*-)
+		;;
 	managarm-mlibc*- | managarm-kernel*- )
 		;;
 	windows*-msvc*-)
@@ -2249,6 +2257,8 @@ case $kernel-$os-$obj in
 		;;
 	*-eabi*- | *-gnueabi*-)
 		;;
+	ios*-simulator- | tvos*-simulator- | watchos*-simulator- )
+		;;
 	none--*)
 		# None (no kernel, i.e. freestanding / bare metal),
 		# can be paired with an machine code file format
@@ -2347,8 +2357,8 @@ echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
 exit
 
 # Local variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp nil t)
 # time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-format: "%Y-%02m-%02d"
 # time-stamp-end: "'"
 # End:
diff --git a/build/gen_stub.php b/build/gen_stub.php
index fcef8213d0b5..619c4c905b60 100755
--- a/build/gen_stub.php
+++ b/build/gen_stub.php
@@ -26,6 +26,7 @@
 const PHP_83_VERSION_ID = 80300;
 const PHP_84_VERSION_ID = 80400;
 const PHP_85_VERSION_ID = 80500;
+const PHP_86_VERSION_ID = 80600;
 const ALL_PHP_VERSION_IDS = [
     PHP_70_VERSION_ID,
     PHP_80_VERSION_ID,
@@ -34,6 +35,7 @@
     PHP_83_VERSION_ID,
     PHP_84_VERSION_ID,
     PHP_85_VERSION_ID,
+    PHP_86_VERSION_ID,
 ];
 
 // file_put_contents() but with a success message printed after saving
@@ -43,6 +45,35 @@ function reportFilePutContents(string $filename, string $content): void {
     }
 }
 
+if (!function_exists('array_any')) {
+    function array_any(array $array, callable $callback): bool {
+        foreach ($array as $key => $value) {
+            if ($callback($value, $key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
+if (function_exists('clone')) {
+    // Replace (\clone)(...) with \clone(...) once the minimally
+    // supported PHP version is 8.5.
+    define('clone', \clone(...));
+} else {
+    define(
+        'clone',
+        /**
+         * @template T
+         * @param T $o
+         * @return T
+         */
+        function (object $o): object {
+            return clone $o;
+        }
+    );
+}
+
 /**
  * @return FileInfo[]
  */
@@ -54,7 +85,7 @@ function processDirectory(string $dir, Context $context): array {
     );
     foreach ($it as $file) {
         $pathName = $file->getPathName();
-        if (preg_match('/\.stub\.php$/', $pathName)) {
+        if (str_ends_with($pathName, '.stub.php')) {
             $pathNames[] = $pathName;
         }
     }
@@ -82,11 +113,22 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
             $stubFilenameWithoutExtension = str_replace(".stub.php", "", $stubFile);
             $arginfoFile = "{$stubFilenameWithoutExtension}_arginfo.h";
             $legacyFile = "{$stubFilenameWithoutExtension}_legacy_arginfo.h";
-
+            $declFile = "{$stubFilenameWithoutExtension}_decl.h";
+
+            /* Check if the stub file changed, by checking that the hash stored
+             * in the generated arginfo.h matches.
+             * Also check that the decl.h file has the same hash. At this point
+             * we don't know if a decl.h file is supposed to exist, so extract
+             * this information (whether a decl file should exist) from the
+             * arginfo.h file. */
             $stubCode = file_get_contents($stubFile);
-            $stubHash = computeStubHash($stubCode);
+            $stubHash = sha1(str_replace("\r\n", "\n", $stubCode));
             $oldStubHash = extractStubHash($arginfoFile);
-            if ($stubHash === $oldStubHash && !$context->forceParse) {
+            $hasDeclHeader = extractHasDeclHeader($arginfoFile);
+            $oldStubHashDecl = extractStubHash($declFile);
+            $generatedFilesUpToDate = $stubHash === $oldStubHash
+                    && ($hasDeclHeader ? $stubHash === $oldStubHashDecl : $oldStubHashDecl === null);
+            if ($generatedFilesUpToDate && !$context->forceParse) {
                 /* Stub file did not change, do not regenerate. */
                 return null;
             }
@@ -122,26 +164,29 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
             return $fileInfo;
         }
 
-        $arginfoCode = generateArgInfoCode(
+        [$arginfoCode, $declCode] = $fileInfo->generateArgInfoCode(
             basename($stubFilenameWithoutExtension),
-            $fileInfo,
             $context->allConstInfos,
             $stubHash
         );
-        if ($context->forceRegeneration || $stubHash !== $oldStubHash) {
+        if ($context->forceRegeneration || !$generatedFilesUpToDate) {
             reportFilePutContents($arginfoFile, $arginfoCode);
+            if ($declCode !== '') {
+                reportFilePutContents($declFile, $declCode);
+            } else if (file_exists($declFile)) {
+                unlink($declFile);
+            }
         }
 
         if ($fileInfo->shouldGenerateLegacyArginfo()) {
             $legacyFileInfo = $fileInfo->getLegacyVersion();
 
-            $arginfoCode = generateArgInfoCode(
+            [$arginfoCode] = $legacyFileInfo->generateArgInfoCode(
                 basename($stubFilenameWithoutExtension),
-                $legacyFileInfo,
                 $context->allConstInfos,
                 $stubHash
             );
-            if ($context->forceRegeneration || $stubHash !== $oldStubHash) {
+            if ($context->forceRegeneration || !$generatedFilesUpToDate) {
                 reportFilePutContents($legacyFile, $arginfoCode);
             }
         }
@@ -153,23 +198,28 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
     }
 }
 
-function computeStubHash(string $stubCode): string {
-    return sha1(str_replace("\r\n", "\n", $stubCode));
-}
-
 function extractStubHash(string $arginfoFile): ?string {
     if (!file_exists($arginfoFile)) {
         return null;
     }
 
     $arginfoCode = file_get_contents($arginfoFile);
-    if (!preg_match('/\* Stub hash: ([0-9a-f]+) \*/', $arginfoCode, $matches)) {
+    if (!preg_match('/\* Stub hash: ([0-9a-f]+)/', $arginfoCode, $matches)) {
         return null;
     }
 
     return $matches[1];
 }
 
+function extractHasDeclHeader(string $arginfoFile): bool {
+    if (!file_exists($arginfoFile)) {
+        return false;
+    }
+
+    $arginfoCode = file_get_contents($arginfoFile);
+    return str_contains($arginfoCode, '* Has decl header: yes *');
+}
+
 class Context {
     public bool $forceParse = false;
     public bool $forceRegeneration = false;
@@ -180,20 +230,17 @@ class Context {
 }
 
 class ArrayType extends SimpleType {
-    private /* readonly */ Type $keyType;
-    private /* readonly */ Type $valueType;
 
-    public static function createGenericArray(): self
-    {
-        return new ArrayType(Type::fromString("int|string"), Type::fromString("mixed|ref"));
+    public function __construct(
+        private readonly Type $keyType,
+        private readonly Type $valueType,
+    ) {
+        parent::__construct("array", true);
     }
 
-    public function __construct(Type $keyType, Type $valueType)
+    public static function createGenericArray(): self
     {
-        parent::__construct("array", true);
-
-        $this->keyType = $keyType;
-        $this->valueType = $valueType;
+        return new ArrayType(Type::fromString("int|string"), Type::fromString("mixed|ref"));
     }
 
     public function toOptimizerTypeMask(): string {
@@ -219,8 +266,11 @@ public function equals(SimpleType $other): bool {
 }
 
 class SimpleType {
-    public /* readonly */ string $name;
-    public /* readonly */ bool $isBuiltin;
+
+    protected function __construct(
+        public readonly string $name,
+        public readonly bool $isBuiltin,
+    ) {}
 
     public static function fromNode(Node $node): SimpleType {
         if ($node instanceof Node\Name) {
@@ -299,24 +349,16 @@ public static function fromString(string $typeString): SimpleType
      */
     public static function fromValue($value): SimpleType
     {
-        switch (gettype($value)) {
-            case "NULL":
-                return SimpleType::null();
-            case "boolean":
-                return new SimpleType("bool", true);
-            case "integer":
-                return new SimpleType("int", true);
-            case "double":
-                return new SimpleType("float", true);
-            case "string":
-                return new SimpleType("string", true);
-            case "array":
-                return new SimpleType("array", true);
-            case "object":
-                return new SimpleType("object", true);
-            default:
-                throw new Exception("Type \"" . gettype($value) . "\" cannot be inferred based on value");
-        }
+        return match (gettype($value)) {
+            "NULL" => SimpleType::null(),
+            "boolean" => new SimpleType("bool", true),
+            "integer" => new SimpleType("int", true),
+            "double" => new SimpleType("float", true),
+            "string" => new SimpleType("string", true),
+            "array" => new SimpleType("array", true),
+            "object" => new SimpleType("object", true),
+            default => throw new Exception("Type \"" . gettype($value) . "\" cannot be inferred based on value"),
+        };
     }
 
     public static function null(): SimpleType
@@ -324,11 +366,6 @@ public static function null(): SimpleType
         return new SimpleType("null", true);
     }
 
-    protected function __construct(string $name, bool $isBuiltin) {
-        $this->name = $name;
-        $this->isBuiltin = $isBuiltin;
-    }
-
     public function isScalar(): bool {
         return $this->isBuiltin && in_array($this->name, ["null", "false", "true", "bool", "int", "float"], true);
     }
@@ -361,90 +398,44 @@ public function isMixed(): bool {
         return $this->isBuiltin && $this->name === 'mixed';
     }
 
-    public function toTypeCode(): string {
+    private function toTypeInfo(): array {
         assert($this->isBuiltin);
-        switch ($this->name) {
-            case "bool":
-                return "_IS_BOOL";
-            case "int":
-                return "IS_LONG";
-            case "float":
-                return "IS_DOUBLE";
-            case "string":
-                return "IS_STRING";
-            case "array":
-                return "IS_ARRAY";
-            case "object":
-                return "IS_OBJECT";
-            case "void":
-                return "IS_VOID";
-            case "callable":
-                return "IS_CALLABLE";
-            case "mixed":
-                return "IS_MIXED";
-            case "static":
-                return "IS_STATIC";
-            case "never":
-                return "IS_NEVER";
-            case "null":
-                return "IS_NULL";
-            case "false":
-                return "IS_FALSE";
-            case "true":
-                return "IS_TRUE";
-            default:
-                throw new Exception("Not implemented: $this->name");
-        }
+
+        return match ($this->name) {
+            "null" => ["IS_NULL", "MAY_BE_NULL"],
+            "false" => ["IS_FALSE", "MAY_BE_FALSE"],
+            "true" => ["IS_TRUE", "MAY_BE_TRUE"],
+            "bool" => ["_IS_BOOL", "MAY_BE_BOOL"],
+            "int" => ["IS_LONG", "MAY_BE_LONG"],
+            "float" => ["IS_DOUBLE", "MAY_BE_DOUBLE"],
+            "string" => ["IS_STRING", "MAY_BE_STRING"],
+            "array" => ["IS_ARRAY", "MAY_BE_ARRAY"],
+            "object" => ["IS_OBJECT", "MAY_BE_OBJECT"],
+            "callable" => ["IS_CALLABLE", "MAY_BE_CALLABLE"],
+            "mixed" => ["IS_MIXED", "MAY_BE_ANY"],
+            "void" => ["IS_VOID", "MAY_BE_VOID"],
+            "static" => ["IS_STATIC", "MAY_BE_STATIC"],
+            "never" => ["IS_NEVER", "MAY_BE_NEVER"],
+            default => throw new Exception("Not implemented: $this->name"),
+        };
     }
 
-    public function toTypeMask(): string {
-        assert($this->isBuiltin);
+    public function toTypeCode(): string {
+        return $this->toTypeInfo()[0];
+    }
 
-        switch ($this->name) {
-            case "null":
-                return "MAY_BE_NULL";
-            case "false":
-                return "MAY_BE_FALSE";
-            case "true":
-                return "MAY_BE_TRUE";
-            case "bool":
-                return "MAY_BE_BOOL";
-            case "int":
-                return "MAY_BE_LONG";
-            case "float":
-                return "MAY_BE_DOUBLE";
-            case "string":
-                return "MAY_BE_STRING";
-            case "array":
-                return "MAY_BE_ARRAY";
-            case "object":
-                return "MAY_BE_OBJECT";
-            case "callable":
-                return "MAY_BE_CALLABLE";
-            case "mixed":
-                return "MAY_BE_ANY";
-            case "void":
-                return "MAY_BE_VOID";
-            case "static":
-                return "MAY_BE_STATIC";
-            case "never":
-                return "MAY_BE_NEVER";
-            default:
-                throw new Exception("Not implemented: $this->name");
-        }
+    public function toTypeMask(): string {
+        return $this->toTypeInfo()[1];
     }
 
     public function toOptimizerTypeMaskForArrayKey(): string {
         assert($this->isBuiltin);
 
-        switch ($this->name) {
-            case "int":
-                return "MAY_BE_ARRAY_KEY_LONG";
-            case "string":
-                return "MAY_BE_ARRAY_KEY_STRING";
-            default:
-                throw new Exception("Type $this->name cannot be an array key");
-        }
+        return match ($this->name) {
+            "int" => "MAY_BE_ARRAY_KEY_LONG",
+            "string" => "MAY_BE_ARRAY_KEY_STRING",
+            default => throw new Exception("Type $this->name cannot be an array key"),
+        };
     }
 
     public function toOptimizerTypeMaskForArrayValue(): string {
@@ -452,34 +443,21 @@ public function toOptimizerTypeMaskForArrayValue(): string {
             return "MAY_BE_ARRAY_OF_OBJECT";
         }
 
-        switch ($this->name) {
-            case "null":
-                return "MAY_BE_ARRAY_OF_NULL";
-            case "false":
-                return "MAY_BE_ARRAY_OF_FALSE";
-            case "true":
-                return "MAY_BE_ARRAY_OF_TRUE";
-            case "bool":
-                return "MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE";
-            case "int":
-                return "MAY_BE_ARRAY_OF_LONG";
-            case "float":
-                return "MAY_BE_ARRAY_OF_DOUBLE";
-            case "string":
-                return "MAY_BE_ARRAY_OF_STRING";
-            case "array":
-                return "MAY_BE_ARRAY_OF_ARRAY";
-            case "object":
-                return "MAY_BE_ARRAY_OF_OBJECT";
-            case "resource":
-                return "MAY_BE_ARRAY_OF_RESOURCE";
-            case "mixed":
-                return "MAY_BE_ARRAY_OF_ANY";
-            case "ref":
-                return "MAY_BE_ARRAY_OF_REF";
-            default:
-                throw new Exception("Type $this->name cannot be an array value");
-        }
+        return match ($this->name) {
+            "null" => "MAY_BE_ARRAY_OF_NULL",
+            "false" => "MAY_BE_ARRAY_OF_FALSE",
+            "true" => "MAY_BE_ARRAY_OF_TRUE",
+            "bool" => "MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE",
+            "int" => "MAY_BE_ARRAY_OF_LONG",
+            "float" => "MAY_BE_ARRAY_OF_DOUBLE",
+            "string" => "MAY_BE_ARRAY_OF_STRING",
+            "array" => "MAY_BE_ARRAY_OF_ARRAY",
+            "object" => "MAY_BE_ARRAY_OF_OBJECT",
+            "resource" => "MAY_BE_ARRAY_OF_RESOURCE",
+            "mixed" => "MAY_BE_ARRAY_OF_ANY",
+            "ref" => "MAY_BE_ARRAY_OF_REF",
+            default => throw new Exception("Type $this->name cannot be an array value"),
+        };
     }
 
     public function toOptimizerTypeMask(): string {
@@ -487,18 +465,13 @@ public function toOptimizerTypeMask(): string {
             return "MAY_BE_OBJECT";
         }
 
-        switch ($this->name) {
-            case "resource":
-                return "MAY_BE_RESOURCE";
-            case "callable":
-                return "MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_OBJECT";
-            case "iterable":
-                return "MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_OBJECT";
-            case "mixed":
-                return "MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY";
-        }
-
-        return $this->toTypeMask();
+        return match ($this->name) {
+            "resource" => "MAY_BE_RESOURCE",
+            "callable" => "MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_OBJECT",
+            "iterable" => "MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_OBJECT",
+            "mixed" => "MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY",
+            default => $this->toTypeMask(),
+        };
     }
 
     public function toEscapedName(): string {
@@ -522,13 +495,18 @@ public function equals(SimpleType $other): bool {
 // Instances of Type are immutable and do not need to be cloned
 // when held by an object that is cloned
 class Type {
-    /** @var SimpleType[] */
-    public /* readonly */ array $types;
-    public /* readonly */ bool $isIntersection;
+
+    /**
+     * @param SimpleType[] $types
+     */
+    private function __construct(
+        public readonly array $types,
+        public readonly bool $isIntersection
+    ) {}
 
     public static function fromNode(Node $node): Type {
         if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) {
-            $nestedTypeObjects = array_map(['Type', 'fromNode'], $node->types);
+            $nestedTypeObjects = array_map(Type::fromNode(...), $node->types);
             $types = [];
             foreach ($nestedTypeObjects as $typeObject) {
                 array_push($types, ...$typeObject->types);
@@ -597,32 +575,12 @@ public static function fromString(string $typeString): self {
         return new Type($simpleTypes, $isIntersection);
     }
 
-    /**
-     * @param SimpleType[] $types
-     */
-    private function __construct(array $types, bool $isIntersection) {
-        $this->types = $types;
-        $this->isIntersection = $isIntersection;
-    }
-
     public function isScalar(): bool {
-        foreach ($this->types as $type) {
-            if (!$type->isScalar()) {
-                return false;
-            }
-        }
-
-        return true;
+        return !array_any($this->types, static fn (SimpleType $type): bool => !$type->isScalar());
     }
 
     public function isNullable(): bool {
-        foreach ($this->types as $type) {
-            if ($type->isNull()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any($this->types, static fn (SimpleType $type): bool => $type->isNull());
     }
 
     public function tryToSimpleType(): ?SimpleType {
@@ -732,19 +690,15 @@ function ($type) { return $type->name; },
 }
 
 class ArginfoType {
-    /** @var SimpleType[] $classTypes */
-    public /* readonly */ array $classTypes;
-    /** @var SimpleType[] $builtinTypes */
-    private /* readonly */ array $builtinTypes;
 
     /**
      * @param SimpleType[] $classTypes
      * @param SimpleType[] $builtinTypes
      */
-    public function __construct(array $classTypes, array $builtinTypes) {
-        $this->classTypes = $classTypes;
-        $this->builtinTypes = $builtinTypes;
-    }
+    public function __construct(
+        public readonly array $classTypes,
+        private readonly array $builtinTypes,
+    ) {}
 
     public function hasClassType(): bool {
         return !empty($this->classTypes);
@@ -771,35 +725,18 @@ class ArgInfo {
     public const SEND_BY_REF = "1";
     public const SEND_PREFER_REF = "ZEND_SEND_PREFER_REF";
 
-    public /* readonly */ string $name;
-    public /* readonly */ string $sendBy;
-    public /* readonly */ bool $isVariadic;
-    public ?Type $type;
-    private /* readonly */ ?Type $phpDocType;
-    public ?string $defaultValue;
-    /** @var AttributeInfo[] */
-    public array $attributes;
-
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        string $name,
-        string $sendBy,
-        bool $isVariadic,
-        ?Type $type,
-        ?Type $phpDocType,
-        ?string $defaultValue,
-        array $attributes
-    ) {
-        $this->name = $name;
-        $this->sendBy = $sendBy;
-        $this->isVariadic = $isVariadic;
-        $this->type = $type;
-        $this->phpDocType = $phpDocType;
-        $this->defaultValue = $defaultValue;
-        $this->attributes = $attributes;
-    }
+        public readonly string $name,
+        public readonly string $sendBy,
+        public readonly bool $isVariadic,
+        public ?Type $type,
+        private readonly ?Type $phpDocType,
+        public ?string $defaultValue,
+        public array $attributes,
+    ) {}
 
     public function equals(ArgInfo $other): bool {
         return $this->name === $other->name
@@ -834,16 +771,11 @@ private function getDefaultValueAsArginfoString(): string {
     }
 
     public function getDefaultValueAsMethodSynopsisString(): ?string {
-        switch ($this->defaultValue) {
-            case 'UNKNOWN':
-                return null;
-            case 'false':
-            case 'true':
-            case 'null':
-                return "&{$this->defaultValue};";
-        }
-
-        return $this->defaultValue;
+        return match ($this->defaultValue) {
+            'UNKNOWN' => null,
+            'false' | 'true' | 'null' => "&{$this->defaultValue};",
+            default => $this->defaultValue,
+        };
     }
 
     public function toZendInfo(): string {
@@ -898,13 +830,6 @@ public function getDeclarationName(): string;
 
 abstract class AbstractConstName implements VariableLikeName
 {
-    public function equals(AbstractConstName $const): bool
-    {
-        return $this->__toString() === $const->__toString();
-    }
-
-    abstract public function isClassConst(): bool;
-
     public function isUnknown(): bool
     {
         return strtolower($this->__toString()) === "unknown";
@@ -912,7 +837,7 @@ public function isUnknown(): bool
 }
 
 class ConstName extends AbstractConstName {
-    private /* readonly */ string $const;
+    private readonly string $const;
 
     public function __construct(?Name $namespace, string $const)
     {
@@ -922,11 +847,6 @@ public function __construct(?Name $namespace, string $const)
         $this->const = $const;
     }
 
-    public function isClassConst(): bool
-    {
-        return false;
-    }
-
     public function isUnknown(): bool
     {
         $name = $this->__toString();
@@ -948,19 +868,11 @@ public function getDeclarationName(): string
 }
 
 class ClassConstName extends AbstractConstName {
-    public /* readonly */ Name $class;
-    private /* readonly */ string $const;
-
-    public function __construct(Name $class, string $const)
-    {
-        $this->class = $class;
-        $this->const = $const;
-    }
 
-    public function isClassConst(): bool
-    {
-        return true;
-    }
+    public function __construct(
+        public readonly Name $class,
+        private readonly string $const,
+    ) {}
 
     public function __toString(): string
     {
@@ -974,14 +886,11 @@ public function getDeclarationName(): string
 }
 
 class PropertyName implements VariableLikeName {
-    public /* readonly */ Name $class;
-    private /* readonly */ string $property;
 
-    public function __construct(Name $class, string $property)
-    {
-        $this->class = $class;
-        $this->property = $property;
-    }
+    public function __construct(
+        public readonly Name $class,
+        private readonly string $property
+    ) {}
 
     public function __toString(): string
     {
@@ -994,23 +903,34 @@ public function getDeclarationName(): string
     }
 }
 
+class EnumCaseName {
+    public function __construct(
+        public readonly Name $enum,
+        public readonly string $case
+    ) {
+    }
+
+    public function __toString(): string
+    {
+        return "$this->enum::$this->case";
+    }
+}
+
 interface FunctionOrMethodName {
     public function getDeclaration(): string;
     public function getArgInfoName(): string;
     public function getMethodSynopsisFilename(): string;
     public function getNameForAttributes(): string;
     public function __toString(): string;
-    public function isMethod(): bool;
     public function isConstructor(): bool;
     public function isDestructor(): bool;
 }
 
 class FunctionName implements FunctionOrMethodName {
-    private /* readonly */ Name $name;
 
-    public function __construct(Name $name) {
-        $this->name = $name;
-    }
+    public function __construct(
+        private readonly Name $name,
+    ) {}
 
     public function getNamespace(): ?string {
         if ($this->name->isQualified()) {
@@ -1060,10 +980,6 @@ public function __toString(): string {
         return $this->name->toString();
     }
 
-    public function isMethod(): bool {
-        return false;
-    }
-
     public function isConstructor(): bool {
         return false;
     }
@@ -1074,13 +990,11 @@ public function isDestructor(): bool {
 }
 
 class MethodName implements FunctionOrMethodName {
-    public /* readonly */ Name $className;
-    public /* readonly */ string $methodName;
 
-    public function __construct(Name $className, string $methodName) {
-        $this->className = $className;
-        $this->methodName = $methodName;
-    }
+    public function __construct(
+        public readonly Name $className,
+        public readonly string $methodName,
+    ) {}
 
     public function getDeclarationClassName(): string {
         return implode('_', $this->className->getParts());
@@ -1109,10 +1023,6 @@ public function __toString(): string {
         return "$this->className::$this->methodName";
     }
 
-    public function isMethod(): bool {
-        return true;
-    }
-
     public function isConstructor(): bool {
         return $this->methodName === "__construct";
     }
@@ -1132,18 +1042,16 @@ class ReturnInfo {
         self::REFCOUNT_N,
     ];
 
-    private /* readonly */ bool $byRef;
-    // NOT readonly - gets removed when discarding info for older PHP versions
-    public ?Type $type;
-    public /* readonly */ ?Type $phpDocType;
-    public /* readonly */ bool $tentativeReturnType;
-    public /* readonly */ string $refcount;
-
-    public function __construct(bool $byRef, ?Type $type, ?Type $phpDocType, bool $tentativeReturnType, ?string $refcount) {
-        $this->byRef = $byRef;
-        $this->type = $type;
-        $this->phpDocType = $phpDocType;
-        $this->tentativeReturnType = $tentativeReturnType;
+    public readonly string $refcount;
+
+    public function __construct(
+        private readonly bool $byRef,
+        // NOT readonly - gets removed when discarding info for older PHP versions
+        public ?Type $type,
+        public readonly ?Type $phpDocType,
+        public readonly bool $tentativeReturnType,
+        ?string $refcount
+    ) {
         $this->setRefcount($refcount);
     }
 
@@ -1244,27 +1152,144 @@ private function beginArgInfoCompatible(string $funcInfoName, int $minArgs): str
     }
 }
 
+class VersionFlags {
+
+    /**
+     * Keys are the PHP versions, values are arrays of flags
+     */
+    private array $flagsByVersion;
+
+    public function __construct(array $baseFlags) {
+        $this->flagsByVersion = [];
+        foreach (ALL_PHP_VERSION_IDS as $version) {
+            $this->flagsByVersion[$version] = $baseFlags;
+        }
+    }
+
+    public function addForVersionsAbove(string $flag, int $minimumVersionId): void {
+        $write = false;
+
+        foreach (ALL_PHP_VERSION_IDS as $version) {
+            if ($version === $minimumVersionId || $write === true) {
+                $this->flagsByVersion[$version][] = $flag;
+                $write = true;
+            }
+        }
+    }
+
+    public function isEmpty(): bool {
+        return !array_any(
+            ALL_PHP_VERSION_IDS,
+            fn (int $version): bool => $this->flagsByVersion[$version] !== []
+        );
+    }
+
+    /**
+     * If we have ZEND_ACC2_ flags, represent as 'ZEND_FENTRY_FLAGS(flags1, flags2)'.
+     * Otherwise, represent as just 'flags1' (backwards compatible).
+     */
+    private function formatFlags(array $flags): string {
+        $flags1 = [];
+        $flags2 = [];
+        foreach ($flags as $flag) {
+            if (str_starts_with($flag, 'ZEND_ACC2_')) {
+                $flags2[] = $flag;
+            } else {
+                $flags1[] = $flag;
+            }
+        }
+
+        if ($flags2 !== []) {
+            return sprintf(
+                'ZEND_FENTRY_FLAGS(%s, %s)',
+                $flags1 === [] ? 0 : implode("|", $flags1),
+                implode("|", $flags2),
+            );
+        }
+
+        return implode("|", $flags1);
+    }
+
+    public function generateVersionDependentFlagCode(
+        string $codeTemplate,
+        ?int $phpVersionIdMinimumCompatibility,
+        ?int $phpVersionIdMaxCompatibility = null
+    ): string {
+        $flagsByPhpVersions = $this->flagsByVersion;
+        $phpVersions = ALL_PHP_VERSION_IDS;
+        sort($phpVersions);
+        $currentPhpVersion = end($phpVersions);
+
+        // No version compatibility is needed
+        if ($phpVersionIdMinimumCompatibility === null) {
+            if (empty($flagsByPhpVersions[$currentPhpVersion])) {
+                return '';
+            }
+            return sprintf($codeTemplate, $this->formatFlags($flagsByPhpVersions[$currentPhpVersion]));
+        }
+
+        ksort($flagsByPhpVersions);
+        // Remove flags which depend on a PHP version below the minimally supported one
+        $index = array_search($phpVersionIdMinimumCompatibility, array_keys($flagsByPhpVersions));
+        if ($index === false) {
+            throw new Exception("Missing version dependent flags for PHP version ID \"$phpVersionIdMinimumCompatibility\"");
+        }
+        $flagsByPhpVersions = array_slice($flagsByPhpVersions, $index, null, true);
+        if ($phpVersionIdMaxCompatibility !== null) {
+            // Remove flags which depend on a PHP version above the maximally supported one
+            $index = array_search($phpVersionIdMaxCompatibility, array_keys($flagsByPhpVersions));
+            if ($index === false) {
+                throw new Exception("Missing version dependent flags for PHP version ID \"$phpVersionIdMaxCompatibility\"");
+            }
+            $flagsByPhpVersions = array_slice($flagsByPhpVersions, 0, $index, true);
+        }
+
+        // Remove version-specific flags which don't differ from the previous one
+        // Also populate '0' values
+        $previousVersionId = null;
+        foreach ($flagsByPhpVersions as $versionId => $versionFlags) {
+            if ($versionFlags === []) {
+                $versionFlags = ['0'];
+                $flagsByPhpVersions[$versionId] = ['0'];
+            }
+            if ($previousVersionId !== null && $flagsByPhpVersions[$previousVersionId] === $versionFlags) {
+                unset($flagsByPhpVersions[$versionId]);
+            } else {
+                $previousVersionId = $versionId;
+            }
+        }
+
+        $flagCount = count($flagsByPhpVersions);
+
+        // Do not add a condition unnecessarily when the only version is the same as the minimally supported one
+        if ($flagCount === 1) {
+            reset($flagsByPhpVersions);
+            $firstVersion = key($flagsByPhpVersions);
+            if ($firstVersion === $phpVersionIdMinimumCompatibility) {
+                return sprintf($codeTemplate, $this->formatFlags(reset($flagsByPhpVersions)));
+            }
+        }
+
+        // Add the necessary conditions around the code using the version-specific flags
+        $code = '';
+        $i = 0;
+        foreach (array_reverse($flagsByPhpVersions, true) as $version => $versionFlags) {
+            $if = $i === 0 ? "#if" : "#elif";
+            $endif = $i === $flagCount - 1 ? "#endif\n" : "";
+
+            $code .= "$if (PHP_VERSION_ID >= $version)\n";
+
+            $code .= sprintf($codeTemplate, $this->formatFlags($versionFlags));
+            $code .= $endif;
+
+            $i++;
+        }
+
+        return $code;
+    }
+}
+
 class FuncInfo {
-    public /* readonly */ FunctionOrMethodName $name;
-    private /* readonly */ int $classFlags;
-    public int $flags;
-    public /* readonly */ ?string $aliasType;
-    public ?FunctionOrMethodName $alias;
-    private /* readonly */ bool $isDeprecated;
-    private bool $supportsCompileTimeEval;
-    public /* readonly */ bool $verify;
-    /** @var ArgInfo[] */
-    public /* readonly */ array $args;
-    public /* readonly */ ReturnInfo $return;
-    private /* readonly */ int $numRequiredArgs;
-    public /* readonly */ ?string $cond;
-    public bool $isUndocumentable;
-    private ?int $minimumPhpVersionIdCompatibility;
-    /** @var AttributeInfo[] */
-    public array $attributes;
-    /** @var FramelessFunctionInfo[] */
-    private array $framelessFunctionInfos;
-    private ?ExposedDocComment $exposedDocComment;
 
     /**
      * @param ArgInfo[] $args
@@ -1272,41 +1297,25 @@ class FuncInfo {
      * @param FramelessFunctionInfo[] $framelessFunctionInfos
      */
     public function __construct(
-        FunctionOrMethodName $name,
-        int $classFlags,
-        int $flags,
-        ?string $aliasType,
-        ?FunctionOrMethodName $alias,
-        bool $isDeprecated,
-        bool $supportsCompileTimeEval,
-        bool $verify,
-        array $args,
-        ReturnInfo $return,
-        int $numRequiredArgs,
-        ?string $cond,
-        bool $isUndocumentable,
-        ?int $minimumPhpVersionIdCompatibility,
-        array $attributes,
-        array $framelessFunctionInfos,
-        ?ExposedDocComment $exposedDocComment
+        public readonly FunctionOrMethodName $name,
+        private readonly int $classFlags,
+        public int $flags,
+        public readonly ?string $aliasType,
+        public ?FunctionOrMethodName $alias,
+        private readonly bool $isDeprecated,
+        private bool $supportsCompileTimeEval,
+        private bool $forbidDynamicCalls,
+        public readonly bool $verify,
+        public /* readonly */ array $args,
+        public /* readonly */ ReturnInfo $return,
+        private readonly int $numRequiredArgs,
+        public readonly ?string $cond,
+        public bool $isUndocumentable,
+        private ?int $minimumPhpVersionIdCompatibility,
+        public array $attributes,
+        private array $framelessFunctionInfos,
+        private ?ExposedDocComment $exposedDocComment,
     ) {
-        $this->name = $name;
-        $this->classFlags = $classFlags;
-        $this->flags = $flags;
-        $this->aliasType = $aliasType;
-        $this->alias = $alias;
-        $this->isDeprecated = $isDeprecated;
-        $this->supportsCompileTimeEval = $supportsCompileTimeEval;
-        $this->verify = $verify;
-        $this->args = $args;
-        $this->return = $return;
-        $this->numRequiredArgs = $numRequiredArgs;
-        $this->cond = $cond;
-        $this->isUndocumentable = $isUndocumentable;
-        $this->minimumPhpVersionIdCompatibility = $minimumPhpVersionIdCompatibility;
-        $this->attributes = $attributes;
-        $this->framelessFunctionInfos = $framelessFunctionInfos;
-        $this->exposedDocComment = $exposedDocComment;
         if ($return->tentativeReturnType && $this->isFinalMethod()) {
             throw new Exception("Tentative return inapplicable for final method");
         }
@@ -1314,10 +1323,10 @@ public function __construct(
 
     public function isMethod(): bool
     {
-        return $this->name->isMethod();
+        return $this->name instanceof MethodName;
     }
 
-    public function isFinalMethod(): bool
+    private function isFinalMethod(): bool
     {
         return ($this->flags & Modifiers::FINAL) || ($this->classFlags & Modifiers::FINAL);
     }
@@ -1328,7 +1337,7 @@ public function isInstanceMethod(): bool
     }
 
     /** @return string[] */
-    public function getModifierNames(): array
+    private function getModifierNames(): array
     {
         if (!$this->isMethod()) {
             return [];
@@ -1359,16 +1368,13 @@ public function getModifierNames(): array
 
     private function hasParamWithUnknownDefaultValue(): bool
     {
-        foreach ($this->args as $arg) {
-            if ($arg->defaultValue && !$arg->hasProperDefaultValue()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->args,
+            static fn (ArgInfo $arg): bool => $arg->defaultValue && !$arg->hasProperDefaultValue()
+        );
     }
 
-    public function equalsApartFromNameAndRefcount(FuncInfo $other): bool {
+    private function equalsApartFromNameAndRefcount(FuncInfo $other): bool {
         if (count($this->args) !== count($other->args)) {
             return false;
         }
@@ -1411,27 +1417,21 @@ public function getFramelessDeclaration(): ?string {
             return null;
         }
 
-        $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID;
-
         $code = '';
-
-        if (!$php84MinimumCompatibility) {
-            $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n";
-        }
-
+        $infos = '';
         foreach ($this->framelessFunctionInfos as $framelessFunctionInfo) {
             $code .= "ZEND_FRAMELESS_FUNCTION({$this->name->getFunctionName()}, {$framelessFunctionInfo->arity});\n";
+            $infos .= "\t{ ZEND_FRAMELESS_FUNCTION_NAME({$this->name->getFunctionName()}, {$framelessFunctionInfo->arity}), {$framelessFunctionInfo->arity} },\n";
         }
 
         $code .= 'static const zend_frameless_function_info ' . $this->getFramelessFunctionInfosName() . "[] = {\n";
-        foreach ($this->framelessFunctionInfos as $framelessFunctionInfo) {
-            $code .= "\t{ ZEND_FRAMELESS_FUNCTION_NAME({$this->name->getFunctionName()}, {$framelessFunctionInfo->arity}), {$framelessFunctionInfo->arity} },\n";
-        }
+        $code .= $infos;
         $code .= "\t{ 0 },\n";
         $code .= "};\n";
 
+        $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID;
         if (!$php84MinimumCompatibility) {
-            $code .= "#endif\n";
+            return "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n$code#endif\n";
         }
 
         return $code;
@@ -1442,14 +1442,6 @@ private function getFramelessFunctionInfosName(): string {
     }
 
     public function getFunctionEntry(): string {
-        $code = "";
-
-        $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID;
-        $isVanillaEntry = $this->alias === null && !$this->supportsCompileTimeEval && $this->exposedDocComment === null && empty($this->framelessFunctionInfos);
-        $argInfoName = $this->getArgInfoName();
-        $flagsByPhpVersions = $this->getArginfoFlagsByPhpVersions();
-        $functionEntryCode = null;
-
         if (!empty($this->framelessFunctionInfos)) {
             if ($this->isMethod()) {
                 throw new Exception('Frameless methods are not supported yet');
@@ -1462,9 +1454,13 @@ public function getFunctionEntry(): string {
             }
         }
 
-        if ($this->isMethod()) {
-            $zendName = '"' . $this->name->methodName . '"';
-            if ($this->alias) {
+        $isVanillaEntry = $this->alias === null && !$this->supportsCompileTimeEval && $this->exposedDocComment === null && empty($this->framelessFunctionInfos);
+        $argInfoName = $this->getArgInfoName();
+        $flagsByPhpVersions = $this->getArginfoFlagsByPhpVersions();
+
+        if ($this->isMethod()) {
+            $zendName = '"' . $this->name->methodName . '"';
+            if ($this->alias) {
                 if ($this->alias instanceof MethodName) {
                     $name = "zim_" . $this->alias->getDeclarationClassName() . "_" . $this->alias->methodName;
                 } else if ($this->alias instanceof FunctionName) {
@@ -1472,80 +1468,60 @@ public function getFunctionEntry(): string {
                 } else {
                     throw new Error("Cannot happen");
                 }
+            } elseif ($this->flags & Modifiers::ABSTRACT) {
+                $name = "NULL";
             } else {
-                if ($this->flags & Modifiers::ABSTRACT) {
-                    $name = "NULL";
-                } else {
-                    $name = "zim_" . $this->name->getDeclarationClassName() . "_" . $this->name->methodName;
-
-                    if ($isVanillaEntry) {
-                        $template = "\tZEND_ME(" . $this->name->getDeclarationClassName() . ", " . $this->name->methodName . ", $argInfoName, %s)\n";
-                        $flagsCode = generateVersionDependentFlagCode(
-                            $template,
-                            $flagsByPhpVersions,
-                            $this->minimumPhpVersionIdCompatibility
-                        );
-                        $functionEntryCode = rtrim($flagsCode);
-                    }
+                $name = "zim_" . $this->name->getDeclarationClassName() . "_" . $this->name->methodName;
+
+                if ($isVanillaEntry) {
+                    $template = "\tZEND_ME(" . $this->name->getDeclarationClassName() . ", " . $this->name->methodName . ", $argInfoName, %s)\n";
+                    $flagsCode = $flagsByPhpVersions->generateVersionDependentFlagCode(
+                        $template,
+                        $this->minimumPhpVersionIdCompatibility
+                    );
+                    return rtrim($flagsCode) . "\n";
                 }
             }
         } else if ($this->name instanceof FunctionName) {
             $functionName = $this->name->getFunctionName();
             $declarationName = $this->alias ? $this->alias->getNonNamespacedName() : $this->name->getDeclarationName();
+            $name = "zif_$declarationName";
 
             if ($this->name->getNamespace()) {
                 $namespace = addslashes($this->name->getNamespace());
                 $zendName = "ZEND_NS_NAME(\"$namespace\", \"$functionName\")";
-                $name = "zif_$declarationName";
             } else {
-                $zendName = '"' . $functionName . '"';
-                $name = "zif_$declarationName";
-
                 // Can only use ZEND_FE() if we have no flags for *all* versions
-                $hasFlags = false;
-                foreach ($flagsByPhpVersions as $flags) {
-                    if ($flags !== ['0']) {
-                        $hasFlags = true;
-                        break;
-                    }
-                }
-                if ($isVanillaEntry && !$hasFlags) {
-                    $functionEntryCode = "\tZEND_FE($declarationName, $argInfoName)";
+                if ($isVanillaEntry && $flagsByPhpVersions->isEmpty()) {
+                    return "\tZEND_FE($declarationName, $argInfoName)\n";
                 }
+                $zendName = '"' . $functionName . '"';
             }
         } else {
             throw new Error("Cannot happen");
         }
 
-        if ($functionEntryCode !== null) {
-            $code .= "$functionEntryCode\n";
-        } else {
-            if (!$php84MinimumCompatibility) {
-                $code .= "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n";
-            }
-
-            $php84AndAboveFlags = array_slice($flagsByPhpVersions, 5, null, true);
-            $docComment = $this->exposedDocComment ? '"' . $this->exposedDocComment->escape() . '"' : "NULL";
-            $framelessFuncInfosName = !empty($this->framelessFunctionInfos) ? $this->getFramelessFunctionInfosName() : "NULL";
+        $docComment = $this->exposedDocComment ? '"' . $this->exposedDocComment->escape() . '"' : "NULL";
+        $framelessFuncInfosName = !empty($this->framelessFunctionInfos) ? $this->getFramelessFunctionInfosName() : "NULL";
 
-            $code .= generateVersionDependentFlagCode(
-                "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s, $framelessFuncInfosName, $docComment)\n",
-                $php84AndAboveFlags,
-                PHP_84_VERSION_ID
-            );
+        // Assume 8.4+ here, if older versions are supported this is conditional
+        $code = $flagsByPhpVersions->generateVersionDependentFlagCode(
+            "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s, $framelessFuncInfosName, $docComment)\n",
+            PHP_84_VERSION_ID
+        );
 
-            if (!$php84MinimumCompatibility) {
-                $code .= "#else\n";
+        $php84MinimumCompatibility = $this->minimumPhpVersionIdCompatibility === null || $this->minimumPhpVersionIdCompatibility >= PHP_84_VERSION_ID;
+        if (!$php84MinimumCompatibility) {
+            $code = "#if (PHP_VERSION_ID >= " . PHP_84_VERSION_ID . ")\n$code";
+            $code .= "#else\n";
 
-                $flags = array_slice($flagsByPhpVersions, 0, 4, true);
-                $code .= generateVersionDependentFlagCode(
-                    "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s)\n",
-                    $flags,
-                    $this->minimumPhpVersionIdCompatibility
-                );
+            $code .= $flagsByPhpVersions->generateVersionDependentFlagCode(
+                "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s)\n",
+                $this->minimumPhpVersionIdCompatibility,
+                PHP_83_VERSION_ID
+            );
 
-                $code .= "#endif\n";
-            }
+            $code .= "#endif\n";
         }
 
         return $code;
@@ -1586,8 +1562,7 @@ public function discardInfoForOldPhpVersions(?int $minimumPhpVersionIdCompatibil
         $this->minimumPhpVersionIdCompatibility = $minimumPhpVersionIdCompatibility;
     }
 
-    /** @return array */
-    private function getArginfoFlagsByPhpVersions(): array
+    private function getArginfoFlagsByPhpVersions(): VersionFlags
     {
         $flags = [];
 
@@ -1617,47 +1592,31 @@ private function getArginfoFlagsByPhpVersions(): array
             $flags[] = "ZEND_ACC_DEPRECATED";
         }
 
-        foreach ($this->attributes as $attr) {
-            switch ($attr->class) {
-                case "Deprecated":
-                    $flags[] = "ZEND_ACC_DEPRECATED";
-                    break;
-            }
+        if (array_any(
+            $this->attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "Deprecated"
+        )) {
+            $flags[] = "ZEND_ACC_DEPRECATED";
         }
 
-        $php82AndAboveFlags = $flags;
+        $flags = new VersionFlags($flags);
+
         if ($this->isMethod() === false && $this->supportsCompileTimeEval) {
-            $php82AndAboveFlags[] = "ZEND_ACC_COMPILE_TIME_EVAL";
+            $flags->addForVersionsAbove("ZEND_ACC_COMPILE_TIME_EVAL", PHP_82_VERSION_ID);
         }
 
-        $php85AndAboveFlags = $php82AndAboveFlags;
-        foreach ($this->attributes as $attr) {
-            switch ($attr->class) {
-                case "NoDiscard":
-                    $php85AndAboveFlags[] = "ZEND_ACC_NODISCARD";
-                    break;
-            }
+        if (array_any(
+            $this->attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "NoDiscard"
+        )) {
+            $flags->addForVersionsAbove("ZEND_ACC_NODISCARD", PHP_85_VERSION_ID);
         }
 
-        if (empty($flags)) {
-            $flags[] = "0";
-        }
-        if (empty($php82AndAboveFlags)) {
-            $php82AndAboveFlags[] = "0";
-        }
-        if (empty($php85AndAboveFlags)) {
-            $php85AndAboveFlags[] = "0";
+        if ($this->forbidDynamicCalls) {
+            $flags->addForVersionsAbove("ZEND_ACC2_FORBID_DYN_CALLS", PHP_86_VERSION_ID);
         }
 
-        return [
-            PHP_70_VERSION_ID => $flags,
-            PHP_80_VERSION_ID => $flags,
-            PHP_81_VERSION_ID => $flags,
-            PHP_82_VERSION_ID => $php82AndAboveFlags,
-            PHP_83_VERSION_ID => $php82AndAboveFlags,
-            PHP_84_VERSION_ID => $php82AndAboveFlags,
-            PHP_85_VERSION_ID => $php85AndAboveFlags,
-        ];
+        return $flags;
     }
 
     private function generateRefSect1(DOMDocument $doc, string $role): DOMElement {
@@ -1672,7 +1631,7 @@ private function generateRefSect1(DOMDocument $doc, string $role): DOMElement {
     }
 
     public function getMethodSynopsisDocument(): ?string {
-        $REFSEC1_SEPERATOR = "\n\n ";
+        $REFSEC1_SEPARATOR = "\n\n ";
 
         $doc = new DOMDocument("1.0", "utf-8");
         $doc->formatOutput = true;
@@ -1682,7 +1641,7 @@ public function getMethodSynopsisDocument(): ?string {
 
         if ($this->isMethod()) {
             assert($this->name instanceof MethodName);
-            /* Namespaces are seperated by '-', '_' must be converted to '-' too.
+            /* Namespaces are separated by '-', '_' must be converted to '-' too.
              * Trim away the __ for magic methods */
             $id = strtolower(
                 str_replace('\\', '-', $this->name->className->__toString())
@@ -1711,7 +1670,7 @@ public function getMethodSynopsisDocument(): ?string {
         $refnamediv->appendChild($refpurpose);
 
         $refnamediv->appendChild(new DOMText("\n "));
-        $refentry->append($refnamediv, $REFSEC1_SEPERATOR);
+        $refentry->append($refnamediv, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $descriptionRefSec = $this->generateRefSect1($doc, 'description');
@@ -1730,16 +1689,16 @@ public function getMethodSynopsisDocument(): ?string {
         $descriptionRefSec->appendChild($returnDescriptionPara);
 
         $descriptionRefSec->appendChild(new DOMText("\n "));
-        $refentry->append($descriptionRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($descriptionRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $parametersRefSec = $this->getParameterSection($doc);
-        $refentry->append($parametersRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($parametersRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         if (!$this->name->isConstructor() && !$this->name->isDestructor()) {
             $returnRefSec = $this->getReturnValueSection($doc);
-            $refentry->append($returnRefSec, $REFSEC1_SEPERATOR);
+            $refentry->append($returnRefSec, $REFSEC1_SEPARATOR);
         }
 
         /* Creation of  */
@@ -1759,14 +1718,14 @@ public function getMethodSynopsisDocument(): ?string {
         $errorsRefSec->appendChild($errorsDescriptionPara);
         $errorsRefSec->appendChild(new DOMText("\n "));
 
-        $refentry->append($errorsRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($errorsRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $changelogRefSec = $this->getChangelogSection($doc);
-        $refentry->append($changelogRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($changelogRefSec, $REFSEC1_SEPARATOR);
 
         $exampleRefSec = $this->getExampleSection($doc, $id);
-        $refentry->append($exampleRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($exampleRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $notesRefSec = $this->generateRefSect1($doc, 'notes');
@@ -1779,7 +1738,7 @@ public function getMethodSynopsisDocument(): ?string {
         $noteTag->append("\n   ", $noteTagSimara, "\n  ");
         $notesRefSec->append($noteTag, "\n ");
 
-        $refentry->append($notesRefSec, $REFSEC1_SEPERATOR);
+        $refentry->append($notesRefSec, $REFSEC1_SEPARATOR);
 
         /* Creation of  */
         $seeAlsoRefSec = $this->generateRefSect1($doc, 'seealso');
@@ -1851,56 +1810,56 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
             $noParamEntity = $doc->createEntityReference('no.function.parameters');
             $parametersRefSec->appendChild($noParamEntity);
             return $parametersRefSec;
-        } else {
-            $parametersContainer = $doc->createDocumentFragment();
-
-            $parametersContainer->appendChild(new DOMText("\n  "));
-            $parametersList = $doc->createElement('variablelist');
-            $parametersContainer->appendChild($parametersList);
-
-            /*
-            
-             name
-             
-              
-               Description.
-              
-             
-            
-            */
-            foreach ($this->args as $arg) {
-                $parameter = $doc->createElement('parameter', $arg->name);
-                $parameterTerm = $doc->createElement('term');
-                $parameterTerm->appendChild($parameter);
-
-                $listItemPara = $doc->createElement('simpara');
-                $listItemPara->append(
-                    "\n      ",
-                    "Description.",
-                    "\n     ",
-                );
+        }
+        $parametersContainer = $doc->createDocumentFragment();
+
+        $parametersContainer->appendChild(new DOMText("\n  "));
+        $parametersList = $doc->createElement('variablelist');
+        $parametersContainer->appendChild($parametersList);
+
+        /*
+        
+            name
+            
+            
+            Description.
+            
+            
+        
+        */
+        foreach ($this->args as $arg) {
+            $parameter = $doc->createElement('parameter', $arg->name);
+            $parameterTerm = $doc->createElement('term');
+            $parameterTerm->appendChild($parameter);
+
+            $listItemPara = $doc->createElement('simpara');
+            $listItemPara->append(
+                "\n      ",
+                "Description.",
+                "\n     ",
+            );
 
-                $parameterEntryListItem = $doc->createElement('listitem');
-                $parameterEntryListItem->append(
-                    "\n     ",
-                    $listItemPara,
-                    "\n    ",
-                );
+            $parameterEntryListItem = $doc->createElement('listitem');
+            $parameterEntryListItem->append(
+                "\n     ",
+                $listItemPara,
+                "\n    ",
+            );
 
-                $parameterEntry = $doc->createElement('varlistentry');
-                $parameterEntry->append(
-                    "\n    ",
-                    $parameterTerm,
-                    "\n    ",
-                    $parameterEntryListItem,
-                    "\n   ",
-                );
+            $parameterEntry = $doc->createElement('varlistentry');
+            $parameterEntry->append(
+                "\n    ",
+                $parameterTerm,
+                "\n    ",
+                $parameterEntryListItem,
+                "\n   ",
+            );
 
-                $parametersList->appendChild(new DOMText("\n   "));
-                $parametersList->appendChild($parameterEntry);
-            }
-            $parametersList->appendChild(new DOMText("\n  "));
+            $parametersList->appendChild(new DOMText("\n   "));
+            $parametersList->appendChild($parameterEntry);
         }
+        $parametersList->appendChild(new DOMText("\n  "));
+
         $parametersContainer->appendChild(new DOMText("\n "));
         $parametersRefSec->appendChild($parametersContainer);
         $parametersRefSec->appendChild(new DOMText("\n "));
@@ -1919,20 +1878,12 @@ private function getReturnValueSection(DOMDocument $doc): DOMElement {
         } else if (count($returnType->types) === 1) {
             $type = $returnType->types[0];
 
-            switch ($type->name) {
-                case 'void':
-                    $descriptionNode = $doc->createEntityReference('return.void');
-                    break;
-                case 'true':
-                    $descriptionNode = $doc->createEntityReference('return.true.always');
-                    break;
-                case 'bool':
-                    $descriptionNode = $doc->createEntityReference('return.success');
-                    break;
-                default:
-                    $descriptionNode = new DOMText("Description.");
-                    break;
-            }
+            $descriptionNode = match ($type->name) {
+                'void' => $doc->createEntityReference('return.void'),
+                'true' => $doc->createEntityReference('return.true.always'),
+                'bool' => $doc->createEntityReference('return.success'),
+                default => new DOMText("Description."),
+            };
             $returnDescriptionPara->appendChild($descriptionNode);
         } else {
             $returnDescriptionPara->appendChild(new DOMText("Description."));
@@ -2178,7 +2129,7 @@ public function getMethodSynopsisElement(DOMDocument $doc): ?DOMElement {
                 $defaultValue = $arg->getDefaultValueAsMethodSynopsisString();
                 if ($defaultValue !== null) {
                     $initializer = $doc->createElement('initializer');
-                    if (preg_match('/^[a-zA-Z_][a-zA-Z_0-9]*$/', $defaultValue)) {
+                    if (preg_match('/^[a-zA-Z_][a-zA-Z_0-9\:\\\\]*$/', $defaultValue)) {
                         $constant = $doc->createElement('constant', $defaultValue);
                         $initializer->appendChild($constant);
                     } else {
@@ -2203,38 +2154,41 @@ public function findEquivalent(array $generatedFuncInfos): ?FuncInfo {
         return null;
     }
 
-    public function toArgInfoCode(?int $minPHPCompatability): string {
+    public function toArgInfoCode(?int $minPHPCompatibility): string {
         $code = $this->return->beginArgInfo(
             $this->getArgInfoName(),
             $this->numRequiredArgs,
-            $minPHPCompatability === null || $minPHPCompatability >= PHP_81_VERSION_ID
+            $minPHPCompatibility === null || $minPHPCompatibility >= PHP_81_VERSION_ID
         );
-    
+
         foreach ($this->args as $argInfo) {
             $code .= $argInfo->toZendInfo();
         }
-    
+
         $code .= "ZEND_END_ARG_INFO()";
         return $code . "\n";
     }
 
     public function __clone()
     {
-        foreach ($this->args as $key => $argInfo) {
-            $this->args[$key] = clone $argInfo;
-        }
+        $this->args = array_map((\clone)(...), $this->args);
         $this->return = clone $this->return;
     }
 }
 
 class EvaluatedValue
 {
-    public /* readonly */ mixed $value;
-    public SimpleType $type;
-    public Expr $expr;
-    public bool $isUnknownConstValue;
-    /** @var ConstInfo[] */
-    public array $originatingConsts;
+
+    /**
+     * @param ConstInfo[] $originatingConsts
+     */
+    private function __construct(
+        public readonly mixed $value,
+        public SimpleType $type,
+        public Expr $expr,
+        public array $originatingConsts,
+        public bool $isUnknownConstValue,
+    ) {}
 
     /**
      * @param array $allConstInfos
@@ -2246,14 +2200,11 @@ public static function createFromExpression(Expr $expr, ?SimpleType $constType,
         {
             /** @var iterable */
             public array $visitedConstants = [];
-            /** @var array */
-            public array $allConstInfos;
 
             /** @param array $allConstInfos */
-            public function __construct(array $allConstInfos)
-            {
-                $this->allConstInfos = $allConstInfos;
-            }
+            public function __construct(
+                public array $allConstInfos,
+            ) {}
 
             /** @return Node|null */
             public function enterNode(Node $expr)
@@ -2342,24 +2293,14 @@ public static function null(): EvaluatedValue
         return new self(null, SimpleType::null(), new Expr\ConstFetch(new Node\Name('null')), [], false);
     }
 
-    /**
-     * @param mixed $value
-     * @param ConstInfo[] $originatingConsts
-     */
-    private function __construct($value, SimpleType $type, Expr $expr, array $originatingConsts, bool $isUnknownConstValue)
-    {
-        $this->value = $value;
-        $this->type = $type;
-        $this->expr = $expr;
-        $this->originatingConsts = $originatingConsts;
-        $this->isUnknownConstValue = $isUnknownConstValue;
-    }
-
-    public function initializeZval(string $zvalName): string
+    public function initializeZval(string $zvalName, bool $alreadyExists = false, string $forStringDef = ''): string
     {
         $cExpr = $this->getCExpr();
 
-        $code = "\tzval $zvalName;\n";
+        $code = '';
+        if (!$alreadyExists) {
+            $code = "\tzval $zvalName;\n";
+        }
 
         if ($this->type->isNull()) {
             $code .= "\tZVAL_NULL(&$zvalName);\n";
@@ -2379,8 +2320,11 @@ public function initializeZval(string $zvalName): string
             if ($cExpr === '""') {
                 $code .= "\tZVAL_EMPTY_STRING(&$zvalName);\n";
             } else {
-                $code .= "\tzend_string *{$zvalName}_str = zend_string_init($cExpr, strlen($cExpr), 1);\n";
-                $code .= "\tZVAL_STR(&$zvalName, {$zvalName}_str);\n";
+                if ($forStringDef === '') {
+                    $forStringDef = "{$zvalName}_str";
+                }
+                $code .= "\tzend_string *$forStringDef = zend_string_init($cExpr, strlen($cExpr), 1);\n";
+                $code .= "\tZVAL_STR(&$zvalName, $forStringDef);\n";
             }
         } elseif ($this->type->isArray()) {
             if ($cExpr == '[]') {
@@ -2410,35 +2354,18 @@ public function getCExpr(): ?string
 
 abstract class VariableLike
 {
-    protected int $flags;
-    public ?Type $type;
-    public /* readonly */ ?Type $phpDocType;
-    private /* readonly */ ?string $link;
-    protected ?int $phpVersionIdMinimumCompatibility;
-    /** @var AttributeInfo[] */
-    public array $attributes;
-    protected /* readonly */ ?ExposedDocComment $exposedDocComment;
-
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        int $flags,
-        ?Type $type,
-        ?Type $phpDocType,
-        ?string $link,
-        ?int $phpVersionIdMinimumCompatibility,
-        array $attributes,
-        ?ExposedDocComment $exposedDocComment
-    ) {
-        $this->flags = $flags;
-        $this->type = $type;
-        $this->phpDocType = $phpDocType;
-        $this->link = $link;
-        $this->phpVersionIdMinimumCompatibility = $phpVersionIdMinimumCompatibility;
-        $this->attributes = $attributes;
-        $this->exposedDocComment = $exposedDocComment;
-    }
+        protected int $flags,
+        public ?Type $type,
+        public readonly ?Type $phpDocType,
+        private readonly ?string $link,
+        protected ?int $phpVersionIdMinimumCompatibility,
+        public array $attributes,
+        protected readonly ?ExposedDocComment $exposedDocComment,
+    ) {}
 
     abstract protected function getVariableTypeName(): string;
 
@@ -2451,10 +2378,7 @@ abstract protected function getFieldSynopsisValueString(array $allConstInfos): ?
 
     abstract public function discardInfoForOldPhpVersions(?int $minimumPhpVersionIdCompatibility): void;
 
-    /**
-     * @return array
-     */
-    protected function getFlagsByPhpVersion(): array
+    protected function getFlagsByPhpVersion(): VersionFlags
     {
         $flags = "ZEND_ACC_PUBLIC";
         if ($this->flags & Modifiers::PROTECTED) {
@@ -2463,22 +2387,22 @@ protected function getFlagsByPhpVersion(): array
             $flags = "ZEND_ACC_PRIVATE";
         }
 
-        return [
-            PHP_70_VERSION_ID => [$flags],
-            PHP_80_VERSION_ID => [$flags],
-            PHP_81_VERSION_ID => [$flags],
-            PHP_82_VERSION_ID => [$flags],
-            PHP_83_VERSION_ID => [$flags],
-            PHP_84_VERSION_ID => [$flags],
-            PHP_85_VERSION_ID => [$flags],
-        ];
+        $versionFlags = new VersionFlags([$flags]);
+
+        if ($this->flags & Modifiers::PUBLIC_SET) {
+            $versionFlags->addForVersionsAbove("ZEND_ACC_PUBLIC_SET", PHP_84_VERSION_ID);
+        } elseif ($this->flags & Modifiers::PROTECTED_SET) {
+            $versionFlags->addForVersionsAbove("ZEND_ACC_PROTECTED_SET", PHP_84_VERSION_ID);
+        } elseif ($this->flags & Modifiers::PRIVATE_SET) {
+            $versionFlags->addForVersionsAbove("ZEND_ACC_PRIVATE_SET", PHP_84_VERSION_ID);
+        }
+
+        return $versionFlags;
     }
 
     protected function getTypeCode(string $variableLikeName, string &$code): string
     {
         $variableLikeType = $this->getVariableTypeName();
-
-        $typeCode = "";
         if ($this->type) {
             $arginfoType = $this->type->toArginfoType();
             if ($arginfoType->hasClassType()) {
@@ -2494,8 +2418,8 @@ protected function getTypeCode(string $variableLikeName, string &$code): string
                     $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->num_types = $classTypeCount;\n";
 
                     foreach ($arginfoType->classTypes as $k => $classType) {
-                        $escapedClassName = $classType->toEscapedName();
-                        $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$escapedClassName}, 0, 0);\n";
+                        $varEscapedClassName = $classType->toVarEscapedName();
+                        $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, 0);\n";
                     }
 
                     $typeMaskCode = $this->type->toArginfoType()->toTypeMask();
@@ -2505,34 +2429,31 @@ protected function getTypeCode(string $variableLikeName, string &$code): string
                     } else {
                         $code .= "\tzend_type {$variableLikeType}_{$variableLikeName}_type = ZEND_TYPE_INIT_UNION({$variableLikeType}_{$variableLikeName}_type_list, $typeMaskCode);\n";
                     }
-                    $typeCode = "{$variableLikeType}_{$variableLikeName}_type";
-                } else {
-                    $escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
-                    $varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName();
-                    $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n";
-
-                    $typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
+                    return "{$variableLikeType}_{$variableLikeName}_type";
                 }
-            } else {
-                $typeCode = "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";
+                $escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
+                $varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName();
+                $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n";
+
+                return "(zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
             }
-        } else {
-            $typeCode = "(zend_type) ZEND_TYPE_INIT_NONE(0)";
+            return "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";
         }
-
-        return $typeCode;
+        return "(zend_type) ZEND_TYPE_INIT_NONE(0)";
     }
 
     /** @param array $allConstInfos */
-    public function getFieldSynopsisElement(DOMDocument $doc, array $allConstInfos): DOMElement
+    public function getFieldSynopsisElement(DOMDocument $doc, array $allConstInfos, int $indentationLevel): DOMElement
     {
+        $indentation = str_repeat(" ", $indentationLevel);
+
         $fieldsynopsisElement = $doc->createElement("fieldsynopsis");
 
-        $this->addModifiersToFieldSynopsis($doc, $fieldsynopsisElement);
+        $this->addModifiersToFieldSynopsis($doc, $fieldsynopsisElement, $indentationLevel + 1);
 
         $type = $this->phpDocType ?? $this->type;
         if ($type) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation "));
             $fieldsynopsisElement->appendChild($type->getTypeForDoc($doc));
         }
 
@@ -2543,100 +2464,80 @@ public function getFieldSynopsisElement(DOMDocument $doc, array $allConstInfos):
             $varnameElement->setAttribute("linkend", $this->getFieldSynopsisDefaultLinkend());
         }
 
-        $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+        $fieldsynopsisElement->appendChild(new DOMText("\n$indentation "));
         $fieldsynopsisElement->appendChild($varnameElement);
 
         $valueString = $this->getFieldSynopsisValueString($allConstInfos);
         if ($valueString) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation "));
             $initializerElement = $doc->createElement("initializer",  $valueString);
             $fieldsynopsisElement->appendChild($initializerElement);
         }
 
-        $fieldsynopsisElement->appendChild(new DOMText("\n    "));
+        $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
 
         return $fieldsynopsisElement;
     }
 
-    protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement): void
+    protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement, int $indentationLevel): void
     {
+        $indentation = str_repeat(" ", $indentationLevel);
+
         if ($this->flags & Modifiers::PUBLIC) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "public"));
         } elseif ($this->flags & Modifiers::PROTECTED) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "protected"));
         } elseif ($this->flags & Modifiers::PRIVATE) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "private"));
         }
-    }
-
-    /**
-     * @param array $flags
-     * @return array
-     */
-    protected function addFlagForVersionsAbove(array $flags, string $flag, int $minimumVersionId): array
-    {
-        $write = false;
 
-        foreach ($flags as $version => $versionFlags) {
-            if ($version === $minimumVersionId || $write === true) {
-                $flags[$version][] = $flag;
-                $write = true;
-            }
+        if ($this->flags & Modifiers::PUBLIC_SET) {
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
+            $fieldsynopsisElement->appendChild($doc->createElement("modifier", "public(set)"));
+        } elseif ($this->flags & Modifiers::PROTECTED_SET) {
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
+            $fieldsynopsisElement->appendChild($doc->createElement("modifier", "protected(set)"));
+        } elseif ($this->flags & Modifiers::PRIVATE_SET) {
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
+            $fieldsynopsisElement->appendChild($doc->createElement("modifier", "private(set)"));
         }
-
-        return $flags;
     }
+
 }
 
 class ConstInfo extends VariableLike
 {
-    public /* readonly */ AbstractConstName $name;
-    public /* readonly */ Expr $value;
-    private bool $isDeprecated;
-    private /* readonly */ ?string $valueString;
-    public /* readonly */ ?string $cond;
-    public /* readonly */ ?string $cValue;
-    public /* readonly */ bool $isUndocumentable;
-    private /* readonly */ bool $isFileCacheAllowed;
 
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        AbstractConstName $name,
+        public readonly AbstractConstName $name,
         int $flags,
-        Expr $value,
-        ?string $valueString,
+        public readonly Expr $value,
+        private readonly ?string $valueString,
         ?Type $type,
         ?Type $phpDocType,
-        bool $isDeprecated,
-        ?string $cond,
-        ?string $cValue,
-        bool $isUndocumentable,
+        private bool $isDeprecated,
+        public readonly ?string $cond,
+        public readonly ?string $cValue,
+        public readonly bool $isUndocumentable,
         ?string $link,
         ?int $phpVersionIdMinimumCompatibility,
         array $attributes,
         ?ExposedDocComment $exposedDocComment,
-        bool $isFileCacheAllowed
+        private readonly bool $isFileCacheAllowed,
     ) {
-        foreach ($attributes as $attr) {
-            if ($attr->class === "Deprecated") {
-                $isDeprecated = true;
-                break;
-            }
+        if (array_any(
+            $attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "Deprecated"
+        )) {
+            $this->isDeprecated = true;
         }
 
-        $this->name = $name;
-        $this->value = $value;
-        $this->valueString = $valueString;
-        $this->isDeprecated = $isDeprecated;
-        $this->cond = $cond;
-        $this->cValue = $cValue;
-        $this->isUndocumentable = $isUndocumentable;
-        $this->isFileCacheAllowed = $isFileCacheAllowed;
         parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility, $attributes, $exposedDocComment);
     }
 
@@ -2685,41 +2586,35 @@ protected function getFieldSynopsisValueString(array $allConstInfos): ?string
         return $this->valueString;
     }
 
-    public function getPredefinedConstantTerm(DOMDocument $doc, int $indentationLevel): DOMElement {
+    private function getPredefinedConstantElement(
+        DOMDocument $doc,
+        int $indentationLevel,
+        string $name
+    ): DOMElement {
         $indentation = str_repeat(" ", $indentationLevel);
 
-        $termElement = $doc->createElement("term");
+        $element = $doc->createElement($name);
 
         $constantElement = $doc->createElement("constant");
         $constantElement->textContent = $this->name->__toString();
 
         $typeElement = ($this->phpDocType ?? $this->type)->getTypeForDoc($doc);
 
-        $termElement->appendChild(new DOMText("\n$indentation "));
-        $termElement->appendChild($constantElement);
-        $termElement->appendChild(new DOMText("\n$indentation ("));
-        $termElement->appendChild($typeElement);
-        $termElement->appendChild(new DOMText(")\n$indentation"));
+        $element->appendChild(new DOMText("\n$indentation "));
+        $element->appendChild($constantElement);
+        $element->appendChild(new DOMText("\n$indentation ("));
+        $element->appendChild($typeElement);
+        $element->appendChild(new DOMText(")\n$indentation"));
 
-        return $termElement;
+        return $element;
     }
 
-    public function getPredefinedConstantEntry(DOMDocument $doc, int $indentationLevel): DOMElement {
-        $indentation = str_repeat(" ", $indentationLevel);
-
-        $entryElement = $doc->createElement("entry");
-
-        $constantElement = $doc->createElement("constant");
-        $constantElement->textContent = $this->name->__toString();
-        $typeElement = ($this->phpDocType ?? $this->type)->getTypeForDoc($doc);
-
-        $entryElement->appendChild(new DOMText("\n$indentation "));
-        $entryElement->appendChild($constantElement);
-        $entryElement->appendChild(new DOMText("\n$indentation ("));
-        $entryElement->appendChild($typeElement);
-        $entryElement->appendChild(new DOMText(")\n$indentation"));
+    public function getPredefinedConstantTerm(DOMDocument $doc, int $indentationLevel): DOMElement {
+        return $this->getPredefinedConstantElement($doc, $indentationLevel, "term");
+    }
 
-        return $entryElement;
+    public function getPredefinedConstantEntry(DOMDocument $doc, int $indentationLevel): DOMElement {
+        return $this->getPredefinedConstantElement($doc, $indentationLevel, "entry");
     }
 
     public function discardInfoForOldPhpVersions(?int $phpVersionIdMinimumCompatibility): void {
@@ -2751,8 +2646,8 @@ public function getDeclaration(array $allConstInfos): string
 
         // Condition will be added by generateCodeWithConditions()
 
-        if ($this->name->isClassConst()) {
-            $code = $this->getClassConstDeclaration($value, $allConstInfos);
+        if ($this->name instanceof ClassConstName) {
+            $code = $this->getClassConstDeclaration($value);
         } else {
             $code = $this->getGlobalConstDeclaration($value);
         }
@@ -2778,39 +2673,50 @@ private function getGlobalConstDeclaration(EvaluatedValue $value): string
         if ($this->isDeprecated) {
             $flags .= " | CONST_DEPRECATED";
         }
+
+        $code = "\t";
+        if ($this->attributes !== []) {
+            if ($this->phpVersionIdMinimumCompatibility === null || $this->phpVersionIdMinimumCompatibility >= PHP_85_VERSION_ID) {
+                // Registration only returns the constant since PHP 8.5, it's
+                // not worth the bloat to add two different registration blocks
+                // with conditions for the PHP version
+                $constVarName = 'const_' . $constName;
+                $code .= "zend_constant *$constVarName = ";
+            }
+        }
+
         if ($value->type->isNull()) {
-            return "\tREGISTER_NULL_CONSTANT(\"$constName\", $flags);\n";
+            return $code . "REGISTER_NULL_CONSTANT(\"$constName\", $flags);\n";
         }
 
         if ($value->type->isBool()) {
-            return "\tREGISTER_BOOL_CONSTANT(\"$constName\", " . ($cExpr ?: ($constValue ? "true" : "false")) . ", $flags);\n";
+            return $code . "REGISTER_BOOL_CONSTANT(\"$constName\", " . ($cExpr ?: ($constValue ? "true" : "false")) . ", $flags);\n";
         }
 
         if ($value->type->isInt()) {
-            return "\tREGISTER_LONG_CONSTANT(\"$constName\", " . ($cExpr ?: (int) $constValue) . ", $flags);\n";
+            return $code . "REGISTER_LONG_CONSTANT(\"$constName\", " . ($cExpr ?: (int) $constValue) . ", $flags);\n";
         }
 
         if ($value->type->isFloat()) {
-            return "\tREGISTER_DOUBLE_CONSTANT(\"$constName\", " . ($cExpr ?: (float) $constValue) . ", $flags);\n";
+            return $code . "REGISTER_DOUBLE_CONSTANT(\"$constName\", " . ($cExpr ?: (float) $constValue) . ", $flags);\n";
         }
 
         if ($value->type->isString()) {
-            return "\tREGISTER_STRING_CONSTANT(\"$constName\", " . ($cExpr ?: '"' . addslashes($constValue) . '"') . ", $flags);\n";
+            return $code . "REGISTER_STRING_CONSTANT(\"$constName\", " . ($cExpr ?: '"' . addslashes($constValue) . '"') . ", $flags);\n";
         }
 
         throw new Exception("Unimplemented constant type");
     }
 
-    /** @param array $allConstInfos */
-    private function getClassConstDeclaration(EvaluatedValue $value, array $allConstInfos): string
+    private function getClassConstDeclaration(EvaluatedValue $value): string
     {
         $constName = $this->name->getDeclarationName();
 
-        $zvalCode = $value->initializeZval("const_{$constName}_value", $allConstInfos);
+        $zvalCode = $value->initializeZval("const_{$constName}_value");
 
         $code = "\n" . $zvalCode;
 
-        $code .= "\tzend_string *const_{$constName}_name = zend_string_init_interned(\"$constName\", sizeof(\"$constName\") - 1, 1);\n";
+        $code .= "\tzend_string *const_{$constName}_name = zend_string_init_interned(\"$constName\", sizeof(\"$constName\") - 1, true);\n";
         $nameCode = "const_{$constName}_name";
 
         if ($this->exposedDocComment) {
@@ -2837,9 +2743,8 @@ private function getClassConstDeclaration(EvaluatedValue $value, array $allConst
             }
             $template .= "zend_declare_typed_class_constant(class_entry, $nameCode, &const_{$constName}_value, %s, $commentCode, $typeCode);\n";
 
-            $code .= generateVersionDependentFlagCode(
+            $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode(
                 $template,
-                $this->getFlagsByPhpVersion(),
                 $this->phpVersionIdMinimumCompatibility
             );
         }
@@ -2855,9 +2760,8 @@ private function getClassConstDeclaration(EvaluatedValue $value, array $allConst
                 $template = "\t";
             }
             $template .= "zend_declare_class_constant_ex(class_entry, $nameCode, &const_{$constName}_value, %s, $commentCode);\n";
-            $code .= generateVersionDependentFlagCode(
+            $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode(
                 $template,
-                $this->getFlagsByPhpVersion(),
                 $this->phpVersionIdMinimumCompatibility
             );
         }
@@ -2866,7 +2770,7 @@ private function getClassConstDeclaration(EvaluatedValue $value, array $allConst
             $code .= "#endif\n";
         }
 
-        $code .= "\tzend_string_release(const_{$constName}_name);\n";
+        $code .= "\tzend_string_release_ex(const_{$constName}_name, true);\n";
 
         return $code;
     }
@@ -2907,47 +2811,39 @@ private function getValueAssertion(EvaluatedValue $value): string
         throw new Exception("Unimplemented constant type");
     }
 
-    /**
-     * @return array
-     */
-    protected function getFlagsByPhpVersion(): array
+    protected function getFlagsByPhpVersion(): VersionFlags
     {
         $flags = parent::getFlagsByPhpVersion();
 
         // $this->isDeprecated also accounts for any #[\Deprecated] attributes
         if ($this->isDeprecated) {
-            $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID);
+            $flags->addForVersionsAbove("ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID);
         }
 
         if ($this->flags & Modifiers::FINAL) {
-            $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_FINAL", PHP_81_VERSION_ID);
+            $flags->addForVersionsAbove("ZEND_ACC_FINAL", PHP_81_VERSION_ID);
         }
 
         return $flags;
     }
 
-    protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement): void
+    protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement, int $indentationLevel): void
     {
-        parent::addModifiersToFieldSynopsis($doc, $fieldsynopsisElement);
+        parent::addModifiersToFieldSynopsis($doc, $fieldsynopsisElement, $indentationLevel);
+
+        $indentation = str_repeat(" ", $indentationLevel);
 
         if ($this->flags & Modifiers::FINAL) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "final"));
         }
 
-        $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+        $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
         $fieldsynopsisElement->appendChild($doc->createElement("modifier", "const"));
     }
 }
 
-class PropertyInfo extends VariableLike
-{
-    private /* readonly */ int $classFlags;
-    public /* readonly */ PropertyName $name;
-    private /* readonly */ ?Expr $defaultValue;
-    private /* readonly */ ?string $defaultValueString;
-    private /* readonly */ bool $isDocReadonly;
-    private /* readonly */ bool $isVirtual;
+class StringBuilder {
 
     // Map possible variable names to the known string constant, see
     // ZEND_KNOWN_STRINGS
@@ -3049,32 +2945,112 @@ class PropertyInfo extends VariableLike
         "parent" => "ZEND_STR_PARENT",
         "username" => "ZEND_STR_USERNAME",
         "password" => "ZEND_STR_PASSWORD",
+        "clone" => "ZEND_STR_CLONE",
+        '8.0' => 'ZEND_STR_8_DOT_0',
+        '8.1' => 'ZEND_STR_8_DOT_1',
+        '8.2' => 'ZEND_STR_8_DOT_2',
+        '8.3' => 'ZEND_STR_8_DOT_3',
+        '8.4' => 'ZEND_STR_8_DOT_4',
+        '8.5' => 'ZEND_STR_8_DOT_5',
+    ];
+
+    // NEW in 8.6
+    private const PHP_86_KNOWN = [
+        "arguments" => "ZEND_STR_ARGUMENTS",
     ];
 
+    /**
+     * Get an array of three strings:
+     *   - declaration of zend_string, if needed, or empty otherwise
+     *   - usage of that zend_string, or usage with ZSTR_KNOWN()
+     *   - freeing the zend_string, if needed
+     *
+     * @param string $varName
+     * @param string $strContent
+     * @param ?int $minPHPCompatibility
+     * @param bool $interned
+     * @return string[]
+     */
+    public static function getString(
+        string $varName,
+        string $content,
+        ?int $minPHPCompatibility,
+        bool $interned = false
+    ): array {
+        // Generally strings will not be known
+        $initFn = $interned ? 'zend_string_init_interned' : 'zend_string_init';
+        $result = [
+            "\tzend_string *$varName = $initFn(\"$content\", sizeof(\"$content\") - 1, true);\n",
+            $varName,
+            "\tzend_string_release_ex($varName, true);\n"
+        ];
+        // For attribute values that are not freed
+        if ($varName === '') {
+            $result[0] = "$initFn(\"$content\", sizeof(\"$content\") - 1, true);\n";
+        }
+        // If not set, use the current latest version
+        $allVersions = ALL_PHP_VERSION_IDS;
+        $minPhp = $minPHPCompatibility ?? end($allVersions);
+        if ($minPhp < PHP_80_VERSION_ID) {
+            // No known strings in 7.0
+            return $result;
+        }
+        $include = self::PHP_80_KNOWN;
+        switch ($minPhp) {
+            case PHP_86_VERSION_ID:
+                $include = array_merge($include, self::PHP_86_KNOWN);
+                // Intentional fall through
+
+            case PHP_85_VERSION_ID:
+                $include = array_merge($include, self::PHP_85_KNOWN);
+                // Intentional fall through
+
+            case PHP_84_VERSION_ID:
+                $include = array_merge($include, self::PHP_84_KNOWN);
+                // Intentional fall through
+
+            case PHP_83_VERSION_ID:
+            case PHP_82_VERSION_ID:
+                $include = array_merge($include, self::PHP_82_KNOWN);
+                // Intentional fall through
+
+            case PHP_81_VERSION_ID:
+                $include = array_merge($include, self::PHP_81_KNOWN);
+                break;
+        }
+        if (array_key_exists($content, $include)) {
+            $knownStr = $include[$content];
+            return [
+                '',
+                "ZSTR_KNOWN($knownStr)",
+                '',
+            ];
+        }
+        return $result;
+    }
+}
+
+class PropertyInfo extends VariableLike
+{
+
     /**
      * @param AttributeInfo[] $attributes
      */
     public function __construct(
-        PropertyName $name,
-        int $classFlags,
+        public readonly PropertyName $name,
+        private readonly int $classFlags,
         int $flags,
         ?Type $type,
         ?Type $phpDocType,
-        ?Expr $defaultValue,
-        ?string $defaultValueString,
-        bool $isDocReadonly,
-        bool $isVirtual,
+        private readonly ?Expr $defaultValue,
+        private readonly ?string $defaultValueString,
+        private readonly bool $isDocReadonly,
+        private readonly bool $isVirtual,
         ?string $link,
         ?int $phpVersionIdMinimumCompatibility,
         array $attributes,
         ?ExposedDocComment $exposedDocComment
     ) {
-        $this->name = $name;
-        $this->classFlags = $classFlags;
-        $this->defaultValue = $defaultValue;
-        $this->defaultValueString = $defaultValueString;
-        $this->isDocReadonly = $isDocReadonly;
-        $this->isVirtual = $isVirtual;
         parent::__construct($flags, $type, $phpDocType, $link, $phpVersionIdMinimumCompatibility, $attributes, $exposedDocComment);
     }
 
@@ -3131,7 +3107,11 @@ public function getDeclaration(array $allConstInfos): string {
             $code .= $defaultValue->initializeZval($zvalName);
         }
 
-        [$stringInit, $nameCode, $stringRelease] = $this->getString($propertyName);
+        [$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
+            "property_{$propertyName}_name",
+            $propertyName,
+            $this->phpVersionIdMinimumCompatibility
+        );
         $code .= $stringInit;
 
         if ($this->exposedDocComment) {
@@ -3155,9 +3135,8 @@ public function getDeclaration(array $allConstInfos): string {
             $template .= "zend_declare_property_ex(class_entry, $nameCode, &$zvalName, %s, $commentCode);\n";
         }
 
-        $code .= generateVersionDependentFlagCode(
+        $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode(
             $template,
-            $this->getFlagsByPhpVersion(),
             $this->phpVersionIdMinimumCompatibility
         );
 
@@ -3166,184 +3145,196 @@ public function getDeclaration(array $allConstInfos): string {
         return $code;
     }
 
-    /**
-     * Get an array of three strings:
-     *   - declaration of zend_string, if needed, or empty otherwise
-     *   - usage of that zend_string, or usage with ZSTR_KNOWN()
-     *   - freeing the zend_string, if needed
-     *
-     * @param string $propName
-     * @return string[]
-     */
-    private function getString(string $propName): array {
-        // Generally strings will not be known
-        $nameCode = "property_{$propName}_name";
-        $result = [
-            "\tzend_string *$nameCode = zend_string_init(\"$propName\", sizeof(\"$propName\") - 1, 1);\n",
-            $nameCode,
-            "\tzend_string_release($nameCode);\n"
-        ];
-        // If not set, use the current latest version
-        $allVersions = ALL_PHP_VERSION_IDS;
-        $minPhp = $this->phpVersionIdMinimumCompatibility ?? end($allVersions);
-        if ($minPhp < PHP_80_VERSION_ID) {
-            // No known strings in 7.0
-            return $result;
-        }
-        $include = self::PHP_80_KNOWN;
-        switch ($minPhp) {
-            case PHP_85_VERSION_ID:
-                $include = array_merge($include, self::PHP_85_KNOWN);
-                // Intentional fall through
-
-            case PHP_84_VERSION_ID:
-                $include = array_merge($include, self::PHP_84_KNOWN);
-                // Intentional fall through
-
-            case PHP_83_VERSION_ID:
-            case PHP_82_VERSION_ID:
-                $include = array_merge($include, self::PHP_82_KNOWN);
-                // Intentional fall through
-
-            case PHP_81_VERSION_ID:
-                $include = array_merge($include, self::PHP_81_KNOWN);
-                break;
-        }
-        if (array_key_exists($propName, $include)) {
-            $knownStr = $include[$propName];
-            return [
-                '',
-                "ZSTR_KNOWN($knownStr)",
-                '',
-            ];
-        }
-        return $result;
-    }
-
-    /**
-     * @return array
-     */
-    protected function getFlagsByPhpVersion(): array
+    protected function getFlagsByPhpVersion(): VersionFlags
     {
         $flags = parent::getFlagsByPhpVersion();
 
         if ($this->flags & Modifiers::STATIC) {
-            $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_STATIC", PHP_70_VERSION_ID);
+            $flags->addForVersionsAbove("ZEND_ACC_STATIC", PHP_70_VERSION_ID);
         }
 
         if ($this->flags & Modifiers::FINAL) {
-            $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_FINAL", PHP_84_VERSION_ID);
+            $flags->addForVersionsAbove("ZEND_ACC_FINAL", PHP_84_VERSION_ID);
         }
 
         if ($this->flags & Modifiers::READONLY) {
-            $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_READONLY", PHP_81_VERSION_ID);
+            $flags->addForVersionsAbove("ZEND_ACC_READONLY", PHP_81_VERSION_ID);
         } elseif ($this->classFlags & Modifiers::READONLY) {
-            $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_READONLY", PHP_82_VERSION_ID);
+            $flags->addForVersionsAbove("ZEND_ACC_READONLY", PHP_82_VERSION_ID);
         }
 
         if ($this->isVirtual) {
-            $flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_VIRTUAL", PHP_84_VERSION_ID);
+            $flags->addForVersionsAbove("ZEND_ACC_VIRTUAL", PHP_84_VERSION_ID);
         }
 
         return $flags;
     }
 
-    protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement): void
+    protected function addModifiersToFieldSynopsis(DOMDocument $doc, DOMElement $fieldsynopsisElement, int $indentationLevel): void
     {
-        parent::addModifiersToFieldSynopsis($doc, $fieldsynopsisElement);
+        parent::addModifiersToFieldSynopsis($doc, $fieldsynopsisElement, $indentationLevel);
+
+        $indentation = str_repeat(" ", $indentationLevel);
 
         if ($this->flags & Modifiers::STATIC) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "static"));
         }
 
         if ($this->flags & Modifiers::FINAL) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "final"));
         }
 
         if ($this->flags & Modifiers::READONLY || $this->isDocReadonly) {
-            $fieldsynopsisElement->appendChild(new DOMText("\n     "));
+            $fieldsynopsisElement->appendChild(new DOMText("\n$indentation"));
             $fieldsynopsisElement->appendChild($doc->createElement("modifier", "readonly"));
         }
     }
 }
 
 class EnumCaseInfo {
-    private /* readonly */ string $name;
-    private /* readonly */ ?Expr $value;
+    public function __construct(
+        public readonly EnumCaseName $name,
+        private readonly ?Expr $value,
+        private readonly ?string $valueString
+    ) {}
+
+    /** @param array $allConstInfos */
+    public function getDeclaration(array $allConstInfos): string {
+        $escapedName = addslashes($this->name->case);
+        if ($this->value === null) {
+            return "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
+        }
+        $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
+
+        $zvalName = "enum_case_{$escapedName}_value";
+        $code = "\n" . $value->initializeZval($zvalName);
+        $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";
 
-    public function __construct(string $name, ?Expr $value) {
-        $this->name = $name;
-        $this->value = $value;
+        return $code;
     }
 
     /** @param array $allConstInfos */
-    public function getDeclaration(array $allConstInfos): string {
-        $escapedName = addslashes($this->name);
+    public function getEnumSynopsisItemElement(DOMDocument $doc, array $allConstInfos, int $indentationLevel): DOMElement
+    {
+        $indentation = str_repeat(" ", $indentationLevel);
+
+        $itemElement = $doc->createElement("enumitem");
+
+        $identifierElement = $doc->createElement("enumidentifier", $this->name->case);
+
+        $itemElement->appendChild(new DOMText("\n$indentation "));
+        $itemElement->appendChild($identifierElement);
+
+        $valueString = $this->getEnumSynopsisValueString($allConstInfos);
+        if ($valueString) {
+            $itemElement->appendChild(new DOMText("\n$indentation "));
+            $valueElement = $doc->createElement("enumvalue",  $valueString);
+            $itemElement->appendChild($valueElement);
+        }
+
+        $descriptionElement = $doc->createElement("enumitemdescription", "Description.");
+        $itemElement->appendChild(new DOMText("\n$indentation "));
+        $itemElement->appendChild($descriptionElement);
+
+        $itemElement->appendChild(new DOMText("\n$indentation"));
+
+        return $itemElement;
+    }
+
+    /** @param array $allConstInfos */
+    public function getEnumSynopsisValueString(array $allConstInfos): ?string
+    {
         if ($this->value === null) {
-            $code = "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
-        } else {
-            $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
+            return null;
+        }
 
-            $zvalName = "enum_case_{$escapedName}_value";
-            $code = "\n" . $value->initializeZval($zvalName);
-            $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";
+        $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
+        if ($value->isUnknownConstValue) {
+            return null;
         }
 
-        return $code;
+        if ($value->originatingConsts) {
+            return implode("\n", array_map(function (ConstInfo $const) use ($allConstInfos) {
+                return $const->getFieldSynopsisValueString($allConstInfos);
+            }, $value->originatingConsts));
+        }
+
+        return $this->valueString;
     }
 }
 
 // Instances of AttributeInfo are immutable and do not need to be cloned
 // when held by an object that is cloned
 class AttributeInfo {
-    public /* readonly */ string $class;
-    /** @var \PhpParser\Node\Arg[] */
-    private /* readonly */ array $args;
 
     /** @param \PhpParser\Node\Arg[] $args */
-    public function __construct(string $class, array $args) {
-        $this->class = $class;
-        $this->args = $args;
-    }
-
-    /** @param array $allConstInfos */
-    public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility): string {
-        $php82MinimumCompatibility = $phpVersionIdMinimumCompatibility === null || $phpVersionIdMinimumCompatibility >= PHP_82_VERSION_ID;
-        $php84MinimumCompatibility = $phpVersionIdMinimumCompatibility === null || $phpVersionIdMinimumCompatibility >= PHP_84_VERSION_ID;
-        /* see ZEND_KNOWN_STRINGS in Zend/strings.h */
-        $knowns = [
-            "message" => "ZEND_STR_MESSAGE",
-        ];
-        if ($php82MinimumCompatibility) {
-            $knowns["SensitiveParameter"] = "ZEND_STR_SENSITIVEPARAMETER";
-        }
-        if ($php84MinimumCompatibility) {
-            $knowns["Deprecated"] = "ZEND_STR_DEPRECATED_CAPITALIZED";
-            $knowns["since"] = "ZEND_STR_SINCE";
-        }
+    public function __construct(
+        public readonly string $class,
+        private readonly array $args,
+    ) {}
 
-        $code = "\n";
+    /**
+     * @param array $allConstInfos
+     * @param array &$declaredStrings Map of string content to
+     *   the name of a zend_string already created with that content
+     */
+    public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, array &$declaredStrings = []): string {
         $escapedAttributeName = strtr($this->class, '\\', '_');
-        if (isset($knowns[$escapedAttributeName])) {
-            $code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, ZSTR_KNOWN({$knowns[$escapedAttributeName]}), " . count($this->args) . ");\n";
-        } else {
-            $code .= "\tzend_string *attribute_name_{$escapedAttributeName}_$nameSuffix = zend_string_init_interned(\"" . addcslashes($this->class, "\\") . "\", sizeof(\"" . addcslashes($this->class, "\\") . "\") - 1, 1);\n";
-            $code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, attribute_name_{$escapedAttributeName}_$nameSuffix, " . count($this->args) . ");\n";
-            $code .= "\tzend_string_release(attribute_name_{$escapedAttributeName}_$nameSuffix);\n";
-        }
+        [$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
+            "attribute_name_{$escapedAttributeName}_$nameSuffix",
+            addcslashes($this->class, "\\"),
+            $phpVersionIdMinimumCompatibility,
+            true
+        );
+        $code = "\n";
+        $code .= $stringInit;
+        $code .= "\t" . ($this->args ? "zend_attribute *attribute_{$escapedAttributeName}_$nameSuffix = " : "") . "$invocation, $nameCode, " . count($this->args) . ");\n";
+        $code .= $stringRelease;
+
         foreach ($this->args as $i => $arg) {
-            $value = EvaluatedValue::createFromExpression($arg->value, null, null, $allConstInfos);
-            $zvalName = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg$i";
-            $code .= $value->initializeZval($zvalName);
-            $code .= "\tZVAL_COPY_VALUE(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, &$zvalName);\n";
+            $initValue = '';
+            if ($arg->value instanceof Node\Scalar\String_) {
+                $strVal = $arg->value->value;
+                [$strInit, $strUse, $strRelease] = StringBuilder::getString(
+                    'unused',
+                    $strVal,
+                    $phpVersionIdMinimumCompatibility
+                );
+                if ($strInit === '') {
+                    $initValue = "\tZVAL_STR(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, $strUse);\n";
+                } elseif (isset($declaredStrings[$strVal])) {
+                    $strUse = $declaredStrings[$strVal];
+                    $initValue = "\tZVAL_STR_COPY(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, $strUse);\n";
+                }
+            }
+            if ($initValue === '') {
+                $value = EvaluatedValue::createFromExpression($arg->value, null, null, $allConstInfos);
+                $code .= $value->initializeZval(
+                    "attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value",
+                    true,
+                    "attribute_{$escapedAttributeName}_{$nameSuffix}_arg{$i}_str"
+                );
+                if ($arg->value instanceof Node\Scalar\String_) {
+                    $declaredStrings[$arg->value->value] = "attribute_{$escapedAttributeName}_{$nameSuffix}_arg{$i}_str";
+                }
+            } else {
+                $code .= $initValue;
+            }
             if ($arg->name) {
-                if (isset($knowns[$arg->name->name])) {
-                    $code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = ZSTR_KNOWN({$knowns[$arg->name->name]});\n";
+                [$stringInit, $nameCode, $stringRelease] = StringBuilder::getString(
+                    "",
+                    $arg->name->name,
+                    $phpVersionIdMinimumCompatibility,
+                    true
+                );
+                if ($stringInit === '') {
+                    $nameCode .= ";\n";
                 } else {
-                    $code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = zend_string_init_interned(\"{$arg->name->name}\", sizeof(\"{$arg->name->name}\") - 1, 1);\n";
+                    $nameCode = $stringInit;
                 }
+                $code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = $nameCode";
             }
         }
         return $code;
@@ -3367,32 +3358,6 @@ public static function createFromGroups(array $attributeGroups): array {
 }
 
 class ClassInfo {
-    public /* readonly */ Name $name;
-    private int $flags;
-    public string $type;
-    public /* readonly */ ?string $alias;
-    private /* readonly */ ?SimpleType $enumBackingType;
-    private /* readonly */ bool $isDeprecated;
-    private bool $isStrictProperties;
-    /** @var AttributeInfo[] */
-    private array $attributes;
-    private ?ExposedDocComment $exposedDocComment;
-    private bool $isNotSerializable;
-    /** @var Name[] */
-    private /* readonly */ array $extends;
-    /** @var Name[] */
-    private /* readonly */ array $implements;
-    /** @var ConstInfo[] */
-    public /* readonly */ array $constInfos;
-    /** @var PropertyInfo[] */
-    private /* readonly */ array $propertyInfos;
-    /** @var FuncInfo[] */
-    public array $funcInfos;
-    /** @var EnumCaseInfo[] */
-    private /* readonly */ array $enumCaseInfos;
-    public /* readonly */ ?string $cond;
-    public ?int $phpVersionIdMinimumCompatibility;
-    public /* readonly */ bool $isUndocumentable;
 
     /**
      * @param AttributeInfo[] $attributes
@@ -3404,46 +3369,26 @@ class ClassInfo {
      * @param EnumCaseInfo[] $enumCaseInfos
      */
     public function __construct(
-        Name $name,
-        int $flags,
-        string $type,
-        ?string $alias,
-        ?SimpleType $enumBackingType,
-        bool $isDeprecated,
-        bool $isStrictProperties,
-        array $attributes,
-        ?ExposedDocComment $exposedDocComment,
-        bool $isNotSerializable,
-        array $extends,
-        array $implements,
-        array $constInfos,
-        array $propertyInfos,
-        array $funcInfos,
-        array $enumCaseInfos,
-        ?string $cond,
-        ?int $minimumPhpVersionIdCompatibility,
-        bool $isUndocumentable
-    ) {
-        $this->name = $name;
-        $this->flags = $flags;
-        $this->type = $type;
-        $this->alias = $alias;
-        $this->enumBackingType = $enumBackingType;
-        $this->isDeprecated = $isDeprecated;
-        $this->isStrictProperties = $isStrictProperties;
-        $this->attributes = $attributes;
-        $this->exposedDocComment = $exposedDocComment;
-        $this->isNotSerializable = $isNotSerializable;
-        $this->extends = $extends;
-        $this->implements = $implements;
-        $this->constInfos = $constInfos;
-        $this->propertyInfos = $propertyInfos;
-        $this->funcInfos = $funcInfos;
-        $this->enumCaseInfos = $enumCaseInfos;
-        $this->cond = $cond;
-        $this->phpVersionIdMinimumCompatibility = $minimumPhpVersionIdCompatibility;
-        $this->isUndocumentable = $isUndocumentable;
-    }
+        public readonly Name $name,
+        private int $flags,
+        public string $type,
+        public readonly ?string $alias,
+        private readonly ?SimpleType $enumBackingType,
+        private readonly bool $isDeprecated,
+        private bool $isStrictProperties,
+        private array $attributes,
+        private ?ExposedDocComment $exposedDocComment,
+        private bool $isNotSerializable,
+        private readonly array $extends,
+        private readonly array $implements,
+        public /* readonly */ array $constInfos,
+        private /* readonly */ array $propertyInfos,
+        public array $funcInfos,
+        private readonly array $enumCaseInfos,
+        public readonly ?string $cond,
+        public ?int $phpVersionIdMinimumCompatibility,
+        public readonly bool $isUndocumentable,
+    ) {}
 
     /** @param array $allConstInfos */
     public function getRegistration(array $allConstInfos): string
@@ -3476,13 +3421,17 @@ public function getRegistration(array $allConstInfos): string
 
         $code .= "{\n";
 
+        $flags = $this->getFlagsByPhpVersion();
+
         $classMethods = ($this->funcInfos === []) ? 'NULL' : "class_{$escapedName}_methods";
         if ($this->type === "enum") {
             $name = addslashes((string) $this->name);
             $backingType = $this->enumBackingType
                 ? $this->enumBackingType->toTypeCode() : "IS_UNDEF";
             $code .= "\tzend_class_entry *class_entry = zend_register_internal_enum(\"$name\", $backingType, $classMethods);\n";
-            $code .= generateVersionDependentFlagCode("\tclass_entry->ce_flags = %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility);
+            if (!$flags->isEmpty()) {
+                $code .= $this->getFlagsByPhpVersion()->generateVersionDependentFlagCode("\tclass_entry->ce_flags = %s;\n", $this->phpVersionIdMinimumCompatibility);
+            }
         } else {
             $code .= "\tzend_class_entry ce, *class_entry;\n\n";
             if (count($this->name->getParts()) > 1) {
@@ -3500,7 +3449,7 @@ public function getRegistration(array $allConstInfos): string
                 }
 
                 $template = "\tclass_entry = zend_register_internal_class_with_flags(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ", %s);\n";
-                $entries = generateVersionDependentFlagCode($template, $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility ? max($this->phpVersionIdMinimumCompatibility, PHP_84_VERSION_ID) : null);
+                $entries = $flags->generateVersionDependentFlagCode($template, $this->phpVersionIdMinimumCompatibility ? max($this->phpVersionIdMinimumCompatibility, PHP_84_VERSION_ID) : null);
                 if ($entries !== '') {
                     $code .= $entries;
                 } else {
@@ -3511,12 +3460,16 @@ public function getRegistration(array $allConstInfos): string
                     $code .= "#else\n";
 
                     $code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]->toString()) : "NULL") . ");\n";
-                    $code .= generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility);
+                    if (!$flags->isEmpty()) {
+                        $code .= $flags->generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->phpVersionIdMinimumCompatibility);
+                    }
                     $code .= "#endif\n";
                 }
             } else {
                 $code .= "\tclass_entry = zend_register_internal_interface(&ce);\n";
-                $code .= generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->getFlagsByPhpVersion(), $this->phpVersionIdMinimumCompatibility);
+                if (!$flags->isEmpty()) {
+                    $code .= $flags->generateVersionDependentFlagCode("\tclass_entry->ce_flags |= %s;\n", $this->phpVersionIdMinimumCompatibility);
+                }
 
             }
         }
@@ -3561,60 +3514,49 @@ function (Name $item) {
         foreach ($this->propertyInfos as $property) {
             $code .= $property->getDeclaration($allConstInfos);
         }
+        // Reusable strings for wrapping conditional PHP 8.0+ code
+        if ($php80MinimumCompatibility) {
+            $php80CondStart = '';
+            $php80CondEnd = '';
+        } else {
+            $php80CondStart = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")";
+            $php80CondEnd = "#endif\n";
+        }
+
+        $declaredStrings = [];
 
         if (!empty($this->attributes)) {
-            if (!$php80MinimumCompatibility) {
-                $code .= "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")";
-            }
+            $code .= $php80CondStart;
 
             foreach ($this->attributes as $key => $attribute) {
                 $code .= $attribute->generateCode(
                     "zend_add_class_attribute(class_entry",
                     "class_{$escapedName}_$key",
                     $allConstInfos,
-                    $this->phpVersionIdMinimumCompatibility
+                    $this->phpVersionIdMinimumCompatibility,
+                    $declaredStrings
                 );
             }
 
-            if (!$php80MinimumCompatibility) {
-                $code .= "#endif\n";
-            }
+            $code .= $php80CondEnd;
         }
 
-        if ($attributeInitializationCode = generateConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond)) {
-            if (!$php80MinimumCompatibility) {
-                $code .= "#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")";
-            }
-
+        if ($attributeInitializationCode = generateConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond, $declaredStrings)) {
+            $code .= $php80CondStart;
             $code .= "\n" . $attributeInitializationCode;
-
-            if (!$php80MinimumCompatibility) {
-                $code .= "#endif\n";
-            }
+            $code .= $php80CondEnd;
         }
 
-        if ($attributeInitializationCode = generatePropertyAttributeInitialization($this->propertyInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility)) {
-            if (!$php80MinimumCompatibility) {
-                $code .= "#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")";
-            }
-
+        if ($attributeInitializationCode = generatePropertyAttributeInitialization($this->propertyInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $declaredStrings)) {
+            $code .= $php80CondStart;
             $code .= "\n" . $attributeInitializationCode;
-
-            if (!$php80MinimumCompatibility) {
-                $code .= "#endif\n";
-            }
+            $code .= $php80CondEnd;
         }
 
-        if ($attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond)) {
-            if (!$php80MinimumCompatibility) {
-                $code .= "#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")\n";
-            }
-
+        if ($attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->phpVersionIdMinimumCompatibility, $this->cond, $declaredStrings)) {
+            $code .= $php80CondStart;
             $code .= "\n" . $attributeInitializationCode;
-
-            if (!$php80MinimumCompatibility) {
-                $code .= "#endif\n";
-            }
+            $code .= $php80CondEnd;
         }
 
         $code .= "\n\treturn class_entry;\n";
@@ -3632,10 +3574,39 @@ function (Name $item) {
         return $code;
     }
 
-    /**
-     * @return array
-     */
-    private function getFlagsByPhpVersion(): array
+    public function getCDeclarations(): string
+    {
+        if ($this->type !== "enum") {
+            return '';
+        }
+
+        $code = '';
+
+        if ($this->cond) {
+            $code .= "#if {$this->cond}\n";
+        }
+
+        $cEnumName = 'zend_enum_' . str_replace('\\', '_', $this->name->toString());
+
+        $code .= "typedef enum {$cEnumName} {\n";
+
+        $i = 1;
+        foreach ($this->enumCaseInfos as $case) {
+            $cName = 'ZEND_ENUM_' . str_replace('\\', '_', $this->name->toString()) . '_' . $case->name->case;
+            $code .= "\t{$cName} = {$i},\n";
+            $i++;
+        }
+
+        $code .= "} {$cEnumName};\n";
+
+        if ($this->cond) {
+            $code .= "#endif\n";
+        }
+
+        return $code;
+    }
+
+    private function getFlagsByPhpVersion(): VersionFlags
     {
         $php70Flags = [];
 
@@ -3655,44 +3626,28 @@ private function getFlagsByPhpVersion(): array
             $php70Flags[] = "ZEND_ACC_DEPRECATED";
         }
 
-        $php80Flags = $php70Flags;
+        $flags = new VersionFlags($php70Flags);
 
         if ($this->isStrictProperties) {
-            $php80Flags[] = "ZEND_ACC_NO_DYNAMIC_PROPERTIES";
+            $flags->addForVersionsAbove("ZEND_ACC_NO_DYNAMIC_PROPERTIES", PHP_80_VERSION_ID);
         }
 
-        $php81Flags = $php80Flags;
-
         if ($this->isNotSerializable) {
-            $php81Flags[] = "ZEND_ACC_NOT_SERIALIZABLE";
+            $flags->addForVersionsAbove("ZEND_ACC_NOT_SERIALIZABLE", PHP_81_VERSION_ID);
         }
 
-        $php82Flags = $php81Flags;
-
         if ($this->flags & Modifiers::READONLY) {
-            $php82Flags[] = "ZEND_ACC_READONLY_CLASS";
+            $flags->addForVersionsAbove("ZEND_ACC_READONLY_CLASS", PHP_82_VERSION_ID);
         }
 
-        foreach ($this->attributes as $attr) {
-            if ($attr->class === "AllowDynamicProperties") {
-                $php82Flags[] = "ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES";
-                break;
-            }
+        if (array_any(
+            $this->attributes,
+            static fn (AttributeInfo $attr): bool => $attr->class === "AllowDynamicProperties"
+        )) {
+            $flags->addForVersionsAbove("ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES", PHP_82_VERSION_ID);
         }
 
-        $php83Flags = $php82Flags;
-        $php84Flags = $php83Flags;
-        $php85Flags = $php84Flags;
-
-        return [
-            PHP_70_VERSION_ID => $php70Flags,
-            PHP_80_VERSION_ID => $php80Flags,
-            PHP_81_VERSION_ID => $php81Flags,
-            PHP_82_VERSION_ID => $php82Flags,
-            PHP_83_VERSION_ID => $php83Flags,
-            PHP_84_VERSION_ID => $php84Flags,
-            PHP_85_VERSION_ID => $php85Flags,
-        ];
+        return $flags;
     }
 
     public function discardInfoForOldPhpVersions(?int $phpVersionIdMinimumCompatibility): void {
@@ -3730,112 +3685,148 @@ public function getClassSynopsisDocument(array $classMap, array $allConstInfos):
      * @param array $allConstInfos
      */
     public function getClassSynopsisElement(DOMDocument $doc, array $classMap, array $allConstInfos): ?DOMElement {
-        $classSynopsis = $doc->createElement("classsynopsis");
-        $classSynopsis->setAttribute("class", $this->type === "interface" ? "interface" : "class");
-
-        $exceptionOverride = $this->type === "class" && $this->isException($classMap) ? "exception" : null;
-        $ooElement = self::createOoElement($doc, $this, $exceptionOverride, true, null, 4);
-        if (!$ooElement) {
-            return null;
+        if ($this->type === "enum") {
+            $classSynopsis = $doc->createElement("enumsynopsis");
+        } else {
+            $classSynopsis = $doc->createElement("classsynopsis");
+            $classSynopsis->setAttribute("class", $this->type === "interface" ? "interface" : "class");
+        }
+
+        $namespace = $this->getNamespace();
+        if ($namespace) {
+            $classSynopsisIndentationLevel = 4;
+            $classSynopsisIndentation = str_repeat(" ", $classSynopsisIndentationLevel);
+            $packageSynopsis = $doc->createElement("packagesynopsis");
+            $packageSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation"));
+            $package = $doc->createElement("package", $namespace);
+            $packageSynopsis->appendChild($package);
+            $packageSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation"));
+            $packageSynopsis->appendChild($classSynopsis);
+            $packageSynopsis->appendChild(new DOMText("\n   "));
+            $root = $packageSynopsis;
+        } else {
+            $root = $classSynopsis;
+            $classSynopsisIndentationLevel = 3;
+            $classSynopsisIndentation = str_repeat(" ", $classSynopsisIndentationLevel);
         }
-        $classSynopsis->appendChild(new DOMText("\n    "));
-        $classSynopsis->appendChild($ooElement);
 
-        foreach ($this->extends as $k => $parent) {
-            $parentInfo = $classMap[$parent->toString()] ?? null;
-            if ($parentInfo === null) {
-                throw new Exception("Missing parent class " . $parent->toString());
-            }
+        $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
 
-            $ooElement = self::createOoElement(
-                $doc,
-                $parentInfo,
-                null,
-                false,
-                $k === 0 ? "extends" : null,
-                4
-            );
+        if ($this->type === "enum") {
+            $enumName = $doc->createElement("enumname", $this->getClassName());
+            $classSynopsis->appendChild($enumName);
+
+            foreach ($this->enumCaseInfos as $enumCaseInfo) {
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $enumItemElement = $enumCaseInfo->getEnumSynopsisItemElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
+                $classSynopsis->appendChild($enumItemElement);
+            }
+        } else {
+            $exceptionOverride = $this->type === "class" && $this->isException($classMap) ? "exception" : null;
+            $ooElement = self::createOoElement($doc, $this, $exceptionOverride, true, null, $classSynopsisIndentationLevel + 1);
             if (!$ooElement) {
                 return null;
             }
-
-            $classSynopsis->appendChild(new DOMText("\n\n    "));
             $classSynopsis->appendChild($ooElement);
-        }
 
-        foreach ($this->implements as $k => $interface) {
-            $interfaceInfo = $classMap[$interface->toString()] ?? null;
-            if (!$interfaceInfo) {
-                throw new Exception("Missing implemented interface " . $interface->toString());
+            foreach ($this->extends as $k => $parent) {
+                $parentInfo = $classMap[$parent->toString()] ?? null;
+                if ($parentInfo === null) {
+                    throw new Exception("Missing parent class " . $parent->toString());
+                }
+
+                $ooElement = self::createOoElement(
+                    $doc,
+                    $parentInfo,
+                    null,
+                    false,
+                    $k === 0 ? "extends" : null,
+                    $classSynopsisIndentationLevel + 1
+                );
+                if (!$ooElement) {
+                    return null;
+                }
+
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsis->appendChild($ooElement);
             }
 
-            $ooElement = self::createOoElement($doc, $interfaceInfo, null, false, $k === 0 ? "implements" : null, 4);
-            if (!$ooElement) {
-                return null;
+            foreach ($this->implements as $k => $interface) {
+                $interfaceInfo = $classMap[$interface->toString()] ?? null;
+                if (!$interfaceInfo) {
+                    throw new Exception("Missing implemented interface " . $interface->toString());
+                }
+
+                $ooElement = self::createOoElement($doc, $interfaceInfo, null, false, $k === 0 ? "implements" : null, $classSynopsisIndentationLevel + 1);
+                if (!$ooElement) {
+                    return null;
+                }
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsis->appendChild($ooElement);
             }
-            $classSynopsis->appendChild(new DOMText("\n\n    "));
-            $classSynopsis->appendChild($ooElement);
-        }
 
-        /** @var array $parentsWithInheritedConstants */
-        $parentsWithInheritedConstants = [];
-        /** @var array $parentsWithInheritedProperties */
-        $parentsWithInheritedProperties = [];
-        /** @var array $parentsWithInheritedMethods */
-        $parentsWithInheritedMethods = [];
+            /** @var array $parentsWithInheritedConstants */
+            $parentsWithInheritedConstants = [];
+            /** @var array $parentsWithInheritedProperties */
+            $parentsWithInheritedProperties = [];
+            /** @var array $parentsWithInheritedMethods */
+            $parentsWithInheritedMethods = [];
 
-        $this->collectInheritedMembers(
-            $parentsWithInheritedConstants,
-            $parentsWithInheritedProperties,
-            $parentsWithInheritedMethods,
-            $this->hasConstructor(),
-            $classMap
-        );
+            $this->collectInheritedMembers(
+                $parentsWithInheritedConstants,
+                $parentsWithInheritedProperties,
+                $parentsWithInheritedMethods,
+                $this->hasConstructor(),
+                $classMap
+            );
 
-        $this->appendInheritedMemberSectionToClassSynopsis(
-            $doc,
-            $classSynopsis,
-            $parentsWithInheritedConstants,
-            "&Constants;",
-            "&InheritedConstants;"
-        );
+            $this->appendInheritedMemberSectionToClassSynopsis(
+                $doc,
+                $classSynopsis,
+                $parentsWithInheritedConstants,
+                "&Constants;",
+                "&InheritedConstants;",
+                $classSynopsisIndentationLevel + 1
+            );
 
-        if (!empty($this->constInfos)) {
-            $classSynopsis->appendChild(new DOMText("\n\n    "));
-            $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Constants;");
-            $classSynopsisInfo->setAttribute("role", "comment");
-            $classSynopsis->appendChild($classSynopsisInfo);
+            if (!empty($this->constInfos)) {
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Constants;");
+                $classSynopsisInfo->setAttribute("role", "comment");
+                $classSynopsis->appendChild($classSynopsisInfo);
 
-            foreach ($this->constInfos as $constInfo) {
-                $classSynopsis->appendChild(new DOMText("\n    "));
-                $fieldSynopsisElement = $constInfo->getFieldSynopsisElement($doc, $allConstInfos);
-                $classSynopsis->appendChild($fieldSynopsisElement);
+                foreach ($this->constInfos as $constInfo) {
+                    $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
+                    $fieldSynopsisElement = $constInfo->getFieldSynopsisElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
+                    $classSynopsis->appendChild($fieldSynopsisElement);
+                }
             }
-        }
 
-        if (!empty($this->propertyInfos)) {
-            $classSynopsis->appendChild(new DOMText("\n\n    "));
-            $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Properties;");
-            $classSynopsisInfo->setAttribute("role", "comment");
-            $classSynopsis->appendChild($classSynopsisInfo);
+            if (!empty($this->propertyInfos)) {
+                $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
+                $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Properties;");
+                $classSynopsisInfo->setAttribute("role", "comment");
+                $classSynopsis->appendChild($classSynopsisInfo);
 
-            foreach ($this->propertyInfos as $propertyInfo) {
-                $classSynopsis->appendChild(new DOMText("\n    "));
-                $fieldSynopsisElement = $propertyInfo->getFieldSynopsisElement($doc, $allConstInfos);
-                $classSynopsis->appendChild($fieldSynopsisElement);
+                foreach ($this->propertyInfos as $propertyInfo) {
+                    $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
+                    $fieldSynopsisElement = $propertyInfo->getFieldSynopsisElement($doc, $allConstInfos, $classSynopsisIndentationLevel + 1);
+                    $classSynopsis->appendChild($fieldSynopsisElement);
+                }
             }
-        }
 
-        $this->appendInheritedMemberSectionToClassSynopsis(
-            $doc,
-            $classSynopsis,
-            $parentsWithInheritedProperties,
-            "&Properties;",
-            "&InheritedProperties;"
-        );
+            $this->appendInheritedMemberSectionToClassSynopsis(
+                $doc,
+                $classSynopsis,
+                $parentsWithInheritedProperties,
+                "&Properties;",
+                "&InheritedProperties;",
+                $classSynopsisIndentationLevel + 1
+            );
+        }
 
         if (!empty($this->funcInfos)) {
-            $classSynopsis->appendChild(new DOMText("\n\n    "));
+            $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
             $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&Methods;");
             $classSynopsisInfo->setAttribute("role", "comment");
             $classSynopsis->appendChild($classSynopsisInfo);
@@ -3844,35 +3835,38 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap, array
             $escapedName = addslashes($this->name->__toString());
 
             if ($this->hasConstructor()) {
-                $classSynopsis->appendChild(new DOMText("\n    "));
+                $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
                 $includeElement = $this->createIncludeElement(
                     $doc,
-                    "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[@role='$escapedName'])"
+                    "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[@role='$escapedName'])",
+                    $classSynopsisIndentationLevel + 1
                 );
                 $classSynopsis->appendChild($includeElement);
             }
 
             if ($this->hasMethods()) {
-                $classSynopsis->appendChild(new DOMText("\n    "));
+                $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
                 $includeElement = $this->createIncludeElement(
                     $doc,
-                    "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[@role='$escapedName'])"
+                    "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:methodsynopsis[@role='$escapedName'])",
+                    $classSynopsisIndentationLevel + 1
                 );
                 $classSynopsis->appendChild($includeElement);
             }
 
             if ($this->hasDestructor()) {
-                $classSynopsis->appendChild(new DOMText("\n    "));
+                $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
                 $includeElement = $this->createIncludeElement(
                     $doc,
-                    "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:destructorsynopsis[@role='$escapedName'])"
+                    "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$classReference')/db:refentry/db:refsect1[@role='description']/descendant::db:destructorsynopsis[@role='$escapedName'])",
+                    $classSynopsisIndentationLevel + 1
                 );
                 $classSynopsis->appendChild($includeElement);
             }
         }
 
         if (!empty($parentsWithInheritedMethods)) {
-            $classSynopsis->appendChild(new DOMText("\n\n    "));
+            $classSynopsis->appendChild(new DOMText("\n\n$classSynopsisIndentation "));
             $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "&InheritedMethods;");
             $classSynopsisInfo->setAttribute("role", "comment");
             $classSynopsis->appendChild($classSynopsisInfo);
@@ -3885,10 +3879,11 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap, array
                 $escapedParentName = addslashes($parentName->__toString());
 
                 foreach ($parentMethodsynopsisTypes as $parentMethodsynopsisType) {
-                    $classSynopsis->appendChild(new DOMText("\n    "));
+                    $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation "));
                     $includeElement = $this->createIncludeElement(
                         $doc,
-                        "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$parentReference')/db:refentry/db:refsect1[@role='description']/descendant::db:{$parentMethodsynopsisType}[@role='$escapedParentName'])"
+                        "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$parentReference')/db:refentry/db:refsect1[@role='description']/descendant::db:{$parentMethodsynopsisType}[@role='$escapedParentName'])",
+                        $classSynopsisIndentationLevel + 1
                     );
 
                     $classSynopsis->appendChild($includeElement);
@@ -3896,23 +3891,23 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap, array
             }
         }
 
-        $classSynopsis->appendChild(new DOMText("\n   "));
+        $classSynopsis->appendChild(new DOMText("\n$classSynopsisIndentation"));
 
-        return $classSynopsis;
+        return $root;
     }
 
     private static function createOoElement(
         DOMDocument $doc,
         ClassInfo $classInfo,
         ?string $typeOverride,
-        bool $withModifiers,
+        bool $isMainClass,
         ?string $modifierOverride,
         int $indentationLevel
     ): ?DOMElement {
         $indentation = str_repeat(" ", $indentationLevel);
 
         if ($classInfo->type !== "class" && $classInfo->type !== "interface") {
-            echo "Class synopsis generation is not implemented for " . $classInfo->type . "\n";
+            echo "Warning: Class synopsis generation is not implemented for " . $classInfo->type . " of type " . $classInfo->name . "\n";
             return null;
         }
 
@@ -3923,7 +3918,7 @@ private static function createOoElement(
         if ($modifierOverride !== null) {
             $ooElement->appendChild($doc->createElement('modifier', $modifierOverride));
             $ooElement->appendChild(new DOMText("\n$indentation "));
-        } elseif ($withModifiers) {
+        } elseif ($isMainClass) {
             foreach ($classInfo->attributes as $attribute) {
                 $modifier = $doc->createElement("modifier", "#[\\" . $attribute->class . "]");
                 $modifier->setAttribute("role", "attribute");
@@ -3945,7 +3940,7 @@ private static function createOoElement(
             }
         }
 
-        $nameElement = $doc->createElement("{$type}name", $classInfo->name->toString());
+        $nameElement = $doc->createElement("{$type}name", $isMainClass ? $classInfo->getClassName() : $classInfo->name->toString());
         $ooElement->appendChild($nameElement);
         $ooElement->appendChild(new DOMText("\n$indentation"));
 
@@ -4072,98 +4067,95 @@ private function isException(array $classMap): bool
 
     private function hasConstructor(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if ($funcInfo->name->isConstructor()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isConstructor()
+        );
     }
 
     private function hasNonPrivateConstructor(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if ($funcInfo->name->isConstructor() && !($funcInfo->flags & Modifiers::PRIVATE)) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isConstructor() && !($funcInfo->flags & Modifiers::PRIVATE)
+        );
     }
 
     private function hasDestructor(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if ($funcInfo->name->isDestructor()) {
-                return true;
-            }
-        }
-
-        return false;
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isDestructor()
+        );
     }
 
     private function hasMethods(): bool
     {
-        foreach ($this->funcInfos as $funcInfo) {
-            if (!$funcInfo->name->isConstructor() && !$funcInfo->name->isDestructor()) {
-                return true;
-            }
+        return array_any(
+            $this->funcInfos,
+            static fn (FuncInfo $funcInfo): bool => !$funcInfo->name->isConstructor() && !$funcInfo->name->isDestructor()
+        );
+    }
+
+    public function getNamespace(): ?string {
+        if ($this->name->isQualified()) {
+            return $this->name->slice(0, -1)->toString();
         }
 
-        return false;
+        return null;
     }
 
-    private function createIncludeElement(DOMDocument $doc, string $query): DOMElement
+    public function getClassName(): string {
+        return $this->name->getLast();
+    }
+
+    private function createIncludeElement(DOMDocument $doc, string $query, int $indentationLevel): DOMElement
     {
+        $indentation = str_repeat(" ", $indentationLevel);
+
         $includeElement = $doc->createElement("xi:include");
         $attr = $doc->createAttribute("xpointer");
         $attr->value = $query;
         $includeElement->appendChild($attr);
         $fallbackElement = $doc->createElement("xi:fallback");
-        $includeElement->appendChild(new DOMText("\n     "));
+        $includeElement->appendChild(new DOMText("\n$indentation "));
         $includeElement->appendChild($fallbackElement);
-        $includeElement->appendChild(new DOMText("\n    "));
+        $includeElement->appendChild(new DOMText("\n$indentation"));
 
         return $includeElement;
     }
 
     public function __clone()
     {
-        foreach ($this->constInfos as $key => $constInfo) {
-            $this->constInfos[$key] = clone $constInfo;
-        }
-
-        foreach ($this->propertyInfos as $key => $propertyInfo) {
-            $this->propertyInfos[$key] = clone $propertyInfo;
-        }
-
-        foreach ($this->funcInfos as $key => $funcInfo) {
-            $this->funcInfos[$key] = clone $funcInfo;
-        }
+        $this->constInfos = array_map((\clone)(...), $this->constInfos);
+        $this->propertyInfos = array_map((\clone)(...), $this->propertyInfos);
+        $this->funcInfos = array_map((\clone)(...), $this->funcInfos);
     }
 
     /**
      * @param Name[] $parents
      */
-    private function appendInheritedMemberSectionToClassSynopsis(DOMDocument $doc, DOMElement $classSynopsis, array $parents, string $label, string $inheritedLabel): void
+    private function appendInheritedMemberSectionToClassSynopsis(DOMDocument $doc, DOMElement $classSynopsis, array $parents, string $label, string $inheritedLabel, int $indentationLevel): void
     {
         if (empty($parents)) {
             return;
         }
 
-        $classSynopsis->appendChild(new DOMText("\n\n    "));
+        $indentation = str_repeat(" ", $indentationLevel);
+
+        $classSynopsis->appendChild(new DOMText("\n\n$indentation"));
         $classSynopsisInfo = $doc->createElement("classsynopsisinfo", "$inheritedLabel");
         $classSynopsisInfo->setAttribute("role", "comment");
         $classSynopsis->appendChild($classSynopsisInfo);
 
         foreach ($parents as $parent) {
-            $classSynopsis->appendChild(new DOMText("\n    "));
+            $classSynopsis->appendChild(new DOMText("\n$indentation"));
             $parentReference = self::getClassSynopsisReference($parent);
 
             $includeElement = $this->createIncludeElement(
                 $doc,
-                "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$parentReference')/db:partintro/db:section/db:classsynopsis/db:fieldsynopsis[preceding-sibling::db:classsynopsisinfo[1][@role='comment' and text()='$label']]))"
+                "xmlns(db=http://docbook.org/ns/docbook) xpointer(id('$parentReference')/db:partintro/db:section/db:classsynopsis/db:fieldsynopsis[preceding-sibling::db:classsynopsisinfo[1][@role='comment' and text()='$label']]))",
+                $indentationLevel
             );
             $classSynopsis->appendChild($includeElement);
         }
@@ -4176,12 +4168,13 @@ class FileInfo {
     /** @var ConstInfo[] */
     public array $constInfos = [];
     /** @var FuncInfo[] */
-    public array $funcInfos = [];
+    private array $funcInfos = [];
     /** @var ClassInfo[] */
     public array $classInfos = [];
-    public bool $generateFunctionEntries = false;
-    public string $declarationPrefix = "";
-    public bool $generateClassEntries = false;
+    private bool $generateFunctionEntries = false;
+    private string $declarationPrefix = "";
+    private bool $generateClassEntries = false;
+    private bool $generateCEnums = false;
     private bool $isUndocumentable = false;
     private bool $legacyArginfoGeneration = false;
     private ?int $minimumPhpVersionIdCompatibility = null;
@@ -4197,7 +4190,8 @@ public function __construct(array $fileTags) {
                     throw new Exception(
                         "Legacy PHP version must be one of: \"" . PHP_70_VERSION_ID . "\" (PHP 7.0), \"" . PHP_80_VERSION_ID . "\" (PHP 8.0), " .
                         "\"" . PHP_81_VERSION_ID . "\" (PHP 8.1), \"" . PHP_82_VERSION_ID . "\" (PHP 8.2), \"" . PHP_83_VERSION_ID . "\" (PHP 8.3), " .
-                        "\"" . PHP_84_VERSION_ID . "\" (PHP 8.4), \"" . PHP_85_VERSION_ID . "\" (PHP 8.5), \"" . $tag->value . "\" provided"
+                        "\"" . PHP_84_VERSION_ID . "\" (PHP 8.4), \"" . PHP_85_VERSION_ID . "\" (PHP 8.5), \"" . PHP_86_VERSION_ID . "\" (PHP 8.6), " .
+                        $tag->value . "\" provided"
                     );
                 }
 
@@ -4207,6 +4201,8 @@ public function __construct(array $fileTags) {
                 $this->declarationPrefix = $tag->value ? $tag->value . " " : "";
             } else if ($tag->name === 'undocumentable') {
                 $this->isUndocumentable = true;
+            } else if ($tag->name === 'generate-c-enums') {
+                $this->generateCEnums = true;
             }
         }
 
@@ -4243,22 +4239,14 @@ public function getAllConstInfos(): array {
         return $result;
     }
 
-    public function __clone()
-    {
-        foreach ($this->constInfos as $key => $constInfo) {
-            $this->constInfos[$key] = clone $constInfo;
-        }
-
-        foreach ($this->funcInfos as $key => $funcInfo) {
-            $this->funcInfos[$key] = clone $funcInfo;
-        }
-
-        foreach ($this->classInfos as $key => $classInfo) {
-            $this->classInfos[$key] = clone $classInfo;
-        }
+    public function __clone()
+    {
+        $this->constInfos = array_map((\clone)(...), $this->constInfos);
+        $this->funcInfos = array_map((\clone)(...), $this->funcInfos);
+        $this->classInfos = array_map((\clone)(...), $this->classInfos);
     }
 
-    public function getMinimumPhpVersionIdCompatibility(): ?int {
+    private function getMinimumPhpVersionIdCompatibility(): ?int {
         // Non-legacy arginfo files are always PHP 8.0+ compatible
         if (!$this->legacyArginfoGeneration &&
             $this->minimumPhpVersionIdCompatibility !== null &&
@@ -4300,31 +4288,48 @@ protected function pName_FullyQualified(Name\FullyQualified $node): string {
                 return implode('\\', $node->getParts());
             }
         };
-    
+
         $stmts = $parser->parse($code);
         $nodeTraverser->traverse($stmts);
-    
-        $fileTags = DocCommentTag::parseDocComments(getFileDocComments($stmts));
+
+        $fileTags = DocCommentTag::parseDocComments(self::getFileDocComments($stmts));
         $fileInfo = new FileInfo($fileTags);
-    
+
         $fileInfo->handleStatements($stmts, $prettyPrinter);
         return $fileInfo;
     }
 
+    /** @return DocComment[] */
+    private static function getFileDocComments(array $stmts): array {
+        if (empty($stmts)) {
+            return [];
+        }
+
+        return array_filter(
+            $stmts[0]->getComments(),
+            static fn ($comment): bool => $comment instanceof DocComment
+        );
+    }
+
     private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPrinter): void {
         $conds = [];
         foreach ($stmts as $stmt) {
             $cond = self::handlePreprocessorConditions($conds, $stmt);
-    
+
             if ($stmt instanceof Stmt\Nop) {
                 continue;
             }
-    
+
             if ($stmt instanceof Stmt\Namespace_) {
                 $this->handleStatements($stmt->stmts, $prettyPrinter);
                 continue;
             }
-    
+
+            if ($stmt instanceof Stmt\Use_ || $stmt instanceof Stmt\GroupUse) {
+                // use statements are resolved by NameResolver before this point
+                continue;
+            }
+
             if ($stmt instanceof Stmt\Const_) {
                 foreach ($stmt->consts as $const) {
                     $this->constInfos[] = parseConstLike(
@@ -4342,7 +4347,7 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                 }
                 continue;
             }
-    
+
             if ($stmt instanceof Stmt\Function_) {
                 $this->funcInfos[] = parseFunctionLike(
                     $prettyPrinter,
@@ -4356,7 +4361,7 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                 );
                 continue;
             }
-    
+
             if ($stmt instanceof Stmt\ClassLike) {
                 $className = $stmt->namespacedName;
                 $constInfos = [];
@@ -4368,10 +4373,10 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                     if ($classStmt instanceof Stmt\Nop) {
                         continue;
                     }
-    
+
                     $classFlags = $stmt instanceof Class_ ? $stmt->flags : 0;
                     $abstractFlag = $stmt instanceof Stmt\Interface_ ? Modifiers::ABSTRACT : 0;
-    
+
                     if ($classStmt instanceof Stmt\ClassConst) {
                         foreach ($classStmt->consts as $const) {
                             $constInfos[] = parseConstLike(
@@ -4420,12 +4425,15 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                         );
                     } else if ($classStmt instanceof Stmt\EnumCase) {
                         $enumCaseInfos[] = new EnumCaseInfo(
-                            $classStmt->name->toString(), $classStmt->expr);
+                            new EnumCaseName($className, $classStmt->name->toString()),
+                            $classStmt->expr,
+                            $classStmt->expr ? $prettyPrinter->prettyPrintExpr($classStmt->expr) : null,
+                        );
                     } else {
                         throw new Exception("Not implemented {$classStmt->getType()}");
                     }
                 }
-    
+
                 $this->classInfos[] = parseClass(
                     $className,
                     $stmt,
@@ -4439,7 +4447,7 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                 );
                 continue;
             }
-    
+
             if ($stmt instanceof Stmt\Expression) {
                 $expr = $stmt->expr;
                 if ($expr instanceof Expr\Include_) {
@@ -4447,7 +4455,7 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
                     continue;
                 }
             }
-    
+
             throw new Exception("Unexpected node {$stmt->getType()}");
         }
         if (!empty($conds)) {
@@ -4479,19 +4487,169 @@ private static function handlePreprocessorConditions(array &$conds, Stmt $stmt):
                 throw new Exception("Unrecognized preprocessor directive \"$text\"");
             }
         }
-    
+
         return empty($conds) ? null : implode(' && ', $conds);
     }
+
+    /** @param array $allConstInfos */
+    public function generateClassEntryCode(array $allConstInfos): string {
+        $code = "";
+
+        foreach ($this->classInfos as $class) {
+            $code .= "\n" . $class->getRegistration($allConstInfos);
+        }
+
+        return $code;
+    }
+
+    public function generateCDeclarations(): string {
+        $code = "";
+
+        if (!$this->generateCEnums) {
+            return $code;
+        }
+
+        foreach ($this->classInfos as $class) {
+            $cdecl = $class->getCDeclarations();
+            if ($cdecl !== '') {
+                $code .= "\n" . $cdecl;
+            }
+        }
+
+        return $code;
+    }
+
+
+    /**
+     * @param array $allConstInfos
+     * @return array{string, string}
+     */
+    public function generateArgInfoCode(
+        string $stubFilenameWithoutExtension,
+        array $allConstInfos,
+        string $stubHash
+    ): array {
+        $code = "";
+
+        $generatedFuncInfos = [];
+
+        $argInfoCode = generateCodeWithConditions(
+            $this->getAllFuncInfos(), "\n",
+            function (FuncInfo $funcInfo) use (&$generatedFuncInfos) {
+                /* If there already is an equivalent arginfo structure, only emit a #define */
+                if ($generatedFuncInfo = $funcInfo->findEquivalent($generatedFuncInfos)) {
+                    $code = sprintf(
+                        "#define %s %s\n",
+                        $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName()
+                    );
+                } else {
+                    $code = $funcInfo->toArgInfoCode($this->getMinimumPhpVersionIdCompatibility());
+                }
+
+                $generatedFuncInfos[] = $funcInfo;
+                return $code;
+            }
+        );
+
+        if ($argInfoCode !== "") {
+            $code .= "$argInfoCode\n";
+        }
+
+        if ($this->generateFunctionEntries) {
+            $framelessFunctionCode = generateCodeWithConditions(
+                $this->getAllFuncInfos(), "\n",
+                static function (FuncInfo $funcInfo) {
+                    return $funcInfo->getFramelessDeclaration();
+                }
+            );
+
+            if ($framelessFunctionCode !== "") {
+                $code .= "$framelessFunctionCode\n";
+            }
+
+            $generatedFunctionDeclarations = [];
+            $code .= generateCodeWithConditions(
+                $this->getAllFuncInfos(), "",
+                function (FuncInfo $funcInfo) use (&$generatedFunctionDeclarations) {
+                    $key = $funcInfo->getDeclarationKey();
+                    if (isset($generatedFunctionDeclarations[$key])) {
+                        return null;
+                    }
+
+                    $generatedFunctionDeclarations[$key] = true;
+                    return $this->declarationPrefix . $funcInfo->getDeclaration();
+                }
+            );
+
+            $code .= generateFunctionEntries(null, $this->funcInfos);
+
+            foreach ($this->classInfos as $classInfo) {
+                $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond);
+            }
+        }
+
+        $php80MinimumCompatibility = $this->getMinimumPhpVersionIdCompatibility() === null || $this->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
+
+        if ($this->generateClassEntries) {
+            $declaredStrings = [];
+            $attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
+            $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
+            if ($attributeInitializationCode) {
+                if (!$php80MinimumCompatibility) {
+                    $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
+                }
+            }
+
+            if ($attributeInitializationCode !== "" || !empty($this->constInfos)) {
+                $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n";
+                $code .= "{\n";
+
+                $code .= generateCodeWithConditions(
+                    $this->constInfos,
+                    '',
+                    static fn (ConstInfo $constInfo): string => $constInfo->getDeclaration($allConstInfos)
+                );
+
+                if ($attributeInitializationCode !== "" && $this->constInfos) {
+                    $code .= "\n";
+                }
+
+                $code .= $attributeInitializationCode;
+                $code .= "}\n";
+            }
+
+            $code .= $this->generateClassEntryCode($allConstInfos);
+        }
+
+        $hasDeclFile = false;
+        $declCode = $this->generateCDeclarations();
+        if ($declCode !== '') {
+            $hasDeclFile = true;
+            $headerName = "ZEND_" . strtoupper($stubFilenameWithoutExtension) . "_DECL_{$stubHash}_H";
+            $declCode = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+                . " * Stub hash: $stubHash */\n"
+                . "\n"
+                . "#ifndef {$headerName}\n"
+                . "#define {$headerName}\n"
+                . $declCode . "\n"
+                . "#endif /* {$headerName} */\n";
+        }
+
+        $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+            . " * Stub hash: $stubHash"
+            . ($hasDeclFile ? "\n * Has decl header: yes */\n" : " */\n")
+            . $code;
+
+        return [$code, $declCode];
+    }
 }
 
 class DocCommentTag {
-    public /* readonly */ string $name;
-    public /* readonly */ ?string $value;
 
-    public function __construct(string $name, ?string $value) {
-        $this->name = $name;
-        $this->value = $value;
-    }
+    public function __construct(
+        public readonly string $name,
+        public readonly ?string $value,
+    ) {}
 
     public function getValue(): string {
         if ($this->value === null) {
@@ -4507,7 +4665,7 @@ public function getType(): string {
         $matches = [];
 
         if ($this->name === "param") {
-            preg_match('/^\s*([\w\|\\\\\[\]<>, ]+)\s*(?:[{(]|\$\w+).*$/', $value, $matches);
+            preg_match('/^\s*([\w\|\\\\\[\]<>, ]+)\s*(?:[{(]|(\.\.\.)?\$\w+).*$/', $value, $matches);
         } elseif ($this->name === "return" || $this->name === "var") {
             preg_match('/^\s*([\w\|\\\\\[\]<>, ]+)/', $value, $matches);
         }
@@ -4529,7 +4687,7 @@ public function getVariableName(): string {
 
         if ($this->name === "param") {
             // Allow for parsing extended types like callable(string):mixed in docblocks
-            preg_match('/^\s*(?[\w\|\\\\]+(?\((?(?:(?&parens)|[^(){}[\]]*+))++\)|\{(?&inparens)\}|\[(?&inparens)\])*+(?::(?&type))?)\s*\$(?\w+).*$/', $value, $matches);
+            preg_match('/^\s*(?[\w\|\\\\]+(?\((?(?:(?&parens)|[^(){}[\]<>]*+))++\)|\{(?&inparens)\}|\[(?&inparens)\]|<(?&inparens)>)*+(?::(?&type))?)\s*(\.\.\.)?\$(?\w+).*$/', $value, $matches);
         } elseif ($this->name === "prefer-ref") {
             preg_match('/^\s*\$(?\w+).*$/', $value, $matches);
         }
@@ -4577,11 +4735,10 @@ public static function makeTagMap(array $tags): array {
 // Instances of ExposedDocComment are immutable and do not need to be cloned
 // when held by an object that is cloned
 class ExposedDocComment {
-    private /* readonly */ string $docComment;
 
-    public function __construct(string $docComment) {
-        $this->docComment = $docComment;
-    }
+    public function __construct(
+        private readonly string $docComment,
+    ) {}
 
     public function escape(): string {
         return str_replace("\n", '\n', addslashes($this->docComment));
@@ -4618,7 +4775,7 @@ public static function extractExposedComment(array $comments): ?ExposedDocCommen
 // Instances of FramelessFunctionInfo are immutable and do not need to be cloned
 // when held by an object that is cloned
 class FramelessFunctionInfo {
-    public /* readonly */ int $arity;
+    public readonly int $arity;
 
     public function __construct(string $json) {
         // FIXME: Should have some validation
@@ -4645,6 +4802,7 @@ function parseFunctionLike(
         $alias = null;
         $isDeprecated = false;
         $supportsCompileTimeEval = false;
+        $forbidDynamicCalls = false;
         $verify = true;
         $docReturnType = null;
         $tentativeReturnType = false;
@@ -4660,6 +4818,7 @@ function parseFunctionLike(
             $verify = !array_key_exists('no-verify', $tagMap);
             $tentativeReturnType = array_key_exists('tentative-return-type', $tagMap);
             $supportsCompileTimeEval = array_key_exists('compile-time-eval', $tagMap);
+            $forbidDynamicCalls = array_key_exists('forbid-dynamic-calls', $tagMap);
             $isUndocumentable = $isUndocumentable || array_key_exists('undocumentable', $tagMap);
 
             foreach ($tags as $tag) {
@@ -4792,6 +4951,7 @@ function parseFunctionLike(
             $alias,
             $isDeprecated,
             $supportsCompileTimeEval,
+            $forbidDynamicCalls,
             $verify,
             $args,
             $return,
@@ -4841,7 +5001,32 @@ function parseConstLike(
     }
 
     if ($type === null && $phpDocType === null) {
-        throw new Exception("Missing type for constant " . $name->__toString());
+        if ($const->value instanceof Node\Scalar\Float_) {
+            $phpDocType = 'float';
+        } elseif ($const->value instanceof Node\Scalar\Int_
+            || ($const->value instanceof Expr\UnaryMinus
+                && $const->value->expr instanceof Node\Scalar\Int_
+            )
+        ) {
+            $phpDocType = 'int';
+        } elseif ($const->value instanceof Node\Scalar\String_) {
+            $phpDocType = 'string';
+        } elseif ($const->value instanceof Expr\ConstFetch
+            && $const->value->name instanceof Node\Name\FullyQualified
+            && (
+                $const->value->name->name === 'false'
+                || $const->value->name->name === 'true'
+            )
+        ) {
+            $phpDocType = 'bool';
+        } elseif ($const->value instanceof Expr\ConstFetch
+            && $const->value->name instanceof Node\Name\FullyQualified
+            && $const->value->name->name === 'null'
+        ) {
+            $phpDocType = 'null';
+        } else {
+            throw new Exception("Missing type for constant " . $name->__toString());
+        }
     }
 
     $constType = $type ? Type::fromNode($type) : null;
@@ -4956,7 +5141,6 @@ function parseClass(
 ): ClassInfo {
     $comments = $class->getComments();
     $alias = null;
-    $allowsDynamicProperties = false;
 
     $tags = DocCommentTag::parseDocComments($comments);
     $tagMap = DocCommentTag::makeTagMap($tags);
@@ -4972,13 +5156,10 @@ function parseClass(
     }
 
     $attributes = AttributeInfo::createFromGroups($class->attrGroups);
-    foreach ($attributes as $attribute) {
-        switch ($attribute->class) {
-            case 'AllowDynamicProperties':
-                $allowsDynamicProperties = true;
-                break 2;
-        }
-    }
+    $allowsDynamicProperties = array_any(
+        $attributes,
+        static fn (AttributeInfo $attribute): bool => $attribute->class === 'AllowDynamicProperties'
+    );
 
     if ($isStrictProperties && $allowsDynamicProperties) {
         throw new Exception("A class may not have '@strict-properties' and '#[\\AllowDynamicProperties]' at the same time.");
@@ -5035,18 +5216,6 @@ function parseClass(
     );
 }
 
-/** @return DocComment[] */
-function getFileDocComments(array $stmts): array {
-    if (empty($stmts)) {
-        return [];
-    }
-
-    return array_filter(
-        $stmts[0]->getComments(),
-        static fn ( $comment ): bool => $comment instanceof DocComment
-    );
-}
-
 /**
  * @template T
  * @param iterable $infos
@@ -5102,121 +5271,6 @@ function generateCodeWithConditions(
     return $code;
 }
 
-/**
- * @param array $allConstInfos
- */
-function generateArgInfoCode(
-    string $stubFilenameWithoutExtension,
-    FileInfo $fileInfo,
-    array $allConstInfos,
-    string $stubHash
-): string {
-    $code = "/* This is a generated file, edit the .stub.php file instead.\n"
-          . " * Stub hash: $stubHash */\n";
-
-    $generatedFuncInfos = [];
-
-    $argInfoCode = generateCodeWithConditions(
-        $fileInfo->getAllFuncInfos(), "\n",
-        static function (FuncInfo $funcInfo) use (&$generatedFuncInfos, $fileInfo) {
-            /* If there already is an equivalent arginfo structure, only emit a #define */
-            if ($generatedFuncInfo = $funcInfo->findEquivalent($generatedFuncInfos)) {
-                $code = sprintf(
-                    "#define %s %s\n",
-                    $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName()
-                );
-            } else {
-                $code = $funcInfo->toArgInfoCode($fileInfo->getMinimumPhpVersionIdCompatibility());
-            }
-
-            $generatedFuncInfos[] = $funcInfo;
-            return $code;
-        }
-    );
-
-    if ($argInfoCode !== "") {
-        $code .= "$argInfoCode\n";
-    }
-
-    if ($fileInfo->generateFunctionEntries) {
-        $framelessFunctionCode = generateCodeWithConditions(
-            $fileInfo->getAllFuncInfos(), "\n",
-            static function (FuncInfo $funcInfo) {
-                return $funcInfo->getFramelessDeclaration();
-            }
-        );
-
-        if ($framelessFunctionCode !== "") {
-            $code .= "$framelessFunctionCode\n";
-        }
-
-        $generatedFunctionDeclarations = [];
-        $code .= generateCodeWithConditions(
-            $fileInfo->getAllFuncInfos(), "",
-            static function (FuncInfo $funcInfo) use ($fileInfo, &$generatedFunctionDeclarations) {
-                $key = $funcInfo->getDeclarationKey();
-                if (isset($generatedFunctionDeclarations[$key])) {
-                    return null;
-                }
-
-                $generatedFunctionDeclarations[$key] = true;
-                return $fileInfo->declarationPrefix . $funcInfo->getDeclaration();
-            }
-        );
-
-        $code .= generateFunctionEntries(null, $fileInfo->funcInfos);
-
-        foreach ($fileInfo->classInfos as $classInfo) {
-            $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond);
-        }
-    }
-
-    $php80MinimumCompatibility = $fileInfo->getMinimumPhpVersionIdCompatibility() === null || $fileInfo->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
-
-    if ($fileInfo->generateClassEntries) {
-        $attributeInitializationCode = generateFunctionAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null);
-        $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($fileInfo->constInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null);
-        if ($attributeInitializationCode) {
-            if (!$php80MinimumCompatibility) {
-                $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
-            }
-        }
-
-        if ($attributeInitializationCode !== "" || !empty($fileInfo->constInfos)) {
-            $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n";
-            $code .= "{\n";
-
-            $code .= generateCodeWithConditions(
-                $fileInfo->constInfos,
-                '',
-                static fn (ConstInfo $constInfo): string => $constInfo->getDeclaration($allConstInfos)
-            );
-
-            if ($attributeInitializationCode !== "" && $fileInfo->constInfos) {
-                $code .= "\n";
-            }
-
-            $code .= $attributeInitializationCode;
-            $code .= "}\n";
-        }
-
-        $code .= generateClassEntryCode($fileInfo, $allConstInfos);
-    }
-
-    return $code;
-}
-
-/** @param array $allConstInfos */
-function generateClassEntryCode(FileInfo $fileInfo, array $allConstInfos): string {
-    $code = "";
-
-    foreach ($fileInfo->classInfos as $class) {
-        $code .= "\n" . $class->getRegistration($allConstInfos);
-    }
-
-    return $code;
-}
-
 /** @param FuncInfo[] $funcInfos */
 function generateFunctionEntries(?Name $className, array $funcInfos, ?string $cond = null): string {
     // No need to add anything if there are no function entries
@@ -5224,19 +5278,13 @@ function generateFunctionEntries(?Name $className, array $funcInfos, ?string $co
         return '';
     }
 
-    $code = "\n";
-
-    if ($cond) {
-        $code .= "#if {$cond}\n";
-    }
-
     $functionEntryName = "ext_functions";
     if ($className) {
         $underscoreName = implode("_", $className->getParts());
         $functionEntryName = "class_{$underscoreName}_methods";
     }
 
-    $code .= "static const zend_function_entry {$functionEntryName}[] = {\n";
+    $code = "\nstatic const zend_function_entry {$functionEntryName}[] = {\n";
     $code .= generateCodeWithConditions($funcInfos, "", static function (FuncInfo $funcInfo) {
         return $funcInfo->getFunctionEntry();
     }, $cond);
@@ -5244,18 +5292,22 @@ function generateFunctionEntries(?Name $className, array $funcInfos, ?string $co
     $code .= "};\n";
 
     if ($cond) {
-        $code .= "#endif\n";
+        $code = "\n#if {$cond}{$code}#endif\n";
     }
 
     return $code;
 }
 
-/** @param iterable $funcInfos */
-function generateFunctionAttributeInitialization(iterable $funcInfos, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, ?string $parentCond = null): string {
+/**
+ * @param iterable $funcInfos
+ * @param array &$declaredStrings Map of string content to
+ *   the name of a zend_string already created with that content
+ */
+function generateFunctionAttributeInitialization(iterable $funcInfos, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility, ?string $parentCond = null, array &$declaredStrings = []): string {
     return generateCodeWithConditions(
         $funcInfos,
         "",
-        static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility) {
+        static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility, &$declaredStrings) {
             $code = null;
 
             if ($funcInfo->name instanceof MethodName) {
@@ -5264,12 +5316,22 @@ static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCo
                 $functionTable = "CG(function_table)";
             }
 
+            // Make sure we don't try and use strings that might only be
+            // conditionally available; string reuse is only among declarations
+            // that are always there
+            if ($funcInfo->cond) {
+                $useDeclared = [];
+            } else {
+                $useDeclared = &$declaredStrings;
+            }
+
             foreach ($funcInfo->attributes as $key => $attribute) {
                 $code .= $attribute->generateCode(
                     "zend_add_function_attribute(zend_hash_str_find_ptr($functionTable, \"" . $funcInfo->name->getNameForAttributes() . "\", sizeof(\"" . $funcInfo->name->getNameForAttributes() . "\") - 1)",
                     "func_" . $funcInfo->name->getNameForAttributes() . "_$key",
                     $allConstInfos,
-                    $phpVersionIdMinimumCompatibility
+                    $phpVersionIdMinimumCompatibility,
+                    $useDeclared
                 );
             }
 
@@ -5279,7 +5341,8 @@ static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCo
                         "zend_add_parameter_attribute(zend_hash_str_find_ptr($functionTable, \"" . $funcInfo->name->getNameForAttributes() . "\", sizeof(\"" . $funcInfo->name->getNameForAttributes() . "\") - 1), $index",
                         "func_{$funcInfo->name->getNameForAttributes()}_arg{$index}_$key",
                         $allConstInfos,
-                        $phpVersionIdMinimumCompatibility
+                        $phpVersionIdMinimumCompatibility,
+                        $useDeclared
                     );
                 }
             }
@@ -5293,37 +5356,53 @@ static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCo
 /**
  * @param iterable $constInfos
  * @param array $allConstInfos
+ * @param array &$declaredStrings Map of string content to
+ *   the name of a zend_string already created with that content
  */
 function generateGlobalConstantAttributeInitialization(
     iterable $constInfos,
     array $allConstInfos,
     ?int $phpVersionIdMinimumCompatibility,
-    ?string $parentCond = null
+    ?string $parentCond = null,
+    array &$declaredStrings = []
 ): string {
     $isConditional = false;
     if ($phpVersionIdMinimumCompatibility !== null && $phpVersionIdMinimumCompatibility < PHP_85_VERSION_ID) {
         $isConditional = true;
-        $phpVersionIdMinimumCompatibility = PHP_85_VERSION_ID;
     }
     $code = generateCodeWithConditions(
         $constInfos,
         "",
-        static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility) {
+        static function (ConstInfo $constInfo) use ($allConstInfos, $isConditional, &$declaredStrings) {
             $code = "";
 
             if ($constInfo->attributes === []) {
                 return null;
             }
+            // Make sure we don't try and use strings that might only be
+            // conditionally available; string reuse is only among declarations
+            // that are always there
+            if ($constInfo->cond) {
+                $useDeclared = [];
+            } else {
+                $useDeclared = &$declaredStrings;
+            }
             $constName = str_replace('\\', '\\\\', $constInfo->name->__toString());
             $constVarName = 'const_' . $constName;
 
-            $code .= "\tzend_constant *$constVarName = zend_hash_str_find_ptr(EG(zend_constants), \"" . $constName . "\", sizeof(\"" . $constName . "\") - 1);\n";
+            // The entire attribute block will be conditional if PHP < 8.5 is
+            // supported, but also if PHP < 8.5 is supported we need to search
+            // for the constant; see GH-19029
+            if ($isConditional) {
+                $code .= "\tzend_constant *$constVarName = zend_hash_str_find_ptr(EG(zend_constants), \"" . $constName . "\", sizeof(\"" . $constName . "\") - 1);\n";
+            }
             foreach ($constInfo->attributes as $key => $attribute) {
                 $code .= $attribute->generateCode(
                     "zend_add_global_constant_attribute($constVarName",
                     $constVarName . "_$key",
                     $allConstInfos,
-                    $phpVersionIdMinimumCompatibility
+                    PHP_85_VERSION_ID,
+                    $useDeclared
                 );
             }
 
@@ -5340,25 +5419,37 @@ static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimum
 /**
  * @param iterable $constInfos
  * @param array $allConstInfos
+ * @param array &$declaredStrings Map of string content to
+ *    the name of a zend_string already created with that content
  */
 function generateConstantAttributeInitialization(
     iterable $constInfos,
     array $allConstInfos,
     ?int $phpVersionIdMinimumCompatibility,
-    ?string $parentCond = null
+    ?string $parentCond = null,
+    array &$declaredStrings = []
 ): string {
     return generateCodeWithConditions(
         $constInfos,
         "",
-        static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility) {
+        static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility, &$declaredStrings) {
             $code = null;
 
+            // Make sure we don't try and use strings that might only be
+            // conditionally available; string reuse is only among declarations
+            // that are always there
+            if ($constInfo->cond) {
+                $useDeclared = [];
+            } else {
+                $useDeclared = &$declaredStrings;
+            }
             foreach ($constInfo->attributes as $key => $attribute) {
                 $code .= $attribute->generateCode(
                     "zend_add_class_constant_attribute(class_entry, const_" . $constInfo->name->getDeclarationName(),
                     "const_" . $constInfo->name->getDeclarationName() . "_$key",
                     $allConstInfos,
-                    $phpVersionIdMinimumCompatibility
+                    $phpVersionIdMinimumCompatibility,
+                    $useDeclared
                 );
             }
 
@@ -5371,11 +5462,14 @@ static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimum
 /**
  * @param iterable $propertyInfos
  * @param array $allConstInfos
+ * @param array &$declaredStrings Map of string content to
+ *    the name of a zend_string already created with that content
  */
 function generatePropertyAttributeInitialization(
     iterable $propertyInfos,
     array $allConstInfos,
-    ?int $phpVersionIdMinimumCompatibility
+    ?int $phpVersionIdMinimumCompatibility,
+    array &$declaredStrings
 ): string {
     $code = "";
     foreach ($propertyInfos as $propertyInfo) {
@@ -5384,7 +5478,8 @@ function generatePropertyAttributeInitialization(
                 "zend_add_property_attribute(class_entry, property_" . $propertyInfo->name->getDeclarationName(),
                 "property_" . $propertyInfo->name->getDeclarationName() . "_" . $key,
                 $allConstInfos,
-                $phpVersionIdMinimumCompatibility
+                $phpVersionIdMinimumCompatibility,
+                $declaredStrings
             );
         }
     }
@@ -5407,80 +5502,6 @@ function generateOptimizerInfo(array $funcMap): string {
     return $code;
 }
 
-/**
- * @param array $flagsByPhpVersions
- * @return string
- */
-function generateVersionDependentFlagCode(string $codeTemplate, array $flagsByPhpVersions, ?int $phpVersionIdMinimumCompatibility): string
-{
-    $phpVersions = ALL_PHP_VERSION_IDS;
-    sort($phpVersions);
-    $currentPhpVersion = end($phpVersions);
-
-    // No version compatibility is needed
-    if ($phpVersionIdMinimumCompatibility === null) {
-        if (empty($flagsByPhpVersions[$currentPhpVersion])) {
-            return '';
-        }
-
-        return sprintf($codeTemplate, implode("|", $flagsByPhpVersions[$currentPhpVersion]));
-    }
-
-    // Remove flags which depend on a PHP version below the minimally supported one
-    ksort($flagsByPhpVersions);
-    $index = array_search($phpVersionIdMinimumCompatibility, array_keys($flagsByPhpVersions));
-    if ($index === false) {
-        throw new Exception("Missing version dependent flags for PHP version ID \"$phpVersionIdMinimumCompatibility\"");
-    }
-    $flagsByPhpVersions = array_slice($flagsByPhpVersions, $index, null, true);
-
-    // Remove empty version-specific flags
-    $flagsByPhpVersions = array_filter($flagsByPhpVersions);
-
-    // There are no version-specific flags
-    if (empty($flagsByPhpVersions)) {
-        return '';
-    }
-
-    // Remove version-specific flags which don't differ from the previous one
-    $previousVersionId = null;
-    foreach ($flagsByPhpVersions as $versionId => $versionFlags) {
-        if ($previousVersionId !== null && $flagsByPhpVersions[$previousVersionId] === $versionFlags) {
-            unset($flagsByPhpVersions[$versionId]);
-        } else {
-            $previousVersionId = $versionId;
-        }
-    }
-
-    $flagCount = count($flagsByPhpVersions);
-
-    // Do not add a condition unnecessarily when the only version is the same as the minimally supported one
-    if ($flagCount === 1) {
-        reset($flagsByPhpVersions);
-        $firstVersion = key($flagsByPhpVersions);
-        if ($firstVersion === $phpVersionIdMinimumCompatibility) {
-            return sprintf($codeTemplate, implode("|", reset($flagsByPhpVersions)));
-        }
-    }
-
-    // Add the necessary conditions around the code using the version-specific flags
-    $code = '';
-    $i = 0;
-    foreach (array_reverse($flagsByPhpVersions, true) as $version => $versionFlags) {
-        $if = $i === 0 ? "#if" : "#elif";
-        $endif = $i === $flagCount - 1 ? "#endif\n" : "";
-
-        $code .= "$if (PHP_VERSION_ID >= $version)\n";
-
-        $code .= sprintf($codeTemplate, implode("|", $versionFlags));
-        $code .= $endif;
-
-        $i++;
-    }
-
-    return $code;
-}
-
 /**
  * @param array $constMap
  * @param array $undocumentedConstMap
@@ -5689,7 +5710,7 @@ function replaceClassSynopses(
             continue;
         }
 
-        if (stripos($xml, "getElementsByTagName("classsynopsis") as $element) {
-            $classSynopsisElements[] = $element;
+            $synopsisElements[] = $element;
         }
 
-        foreach ($classSynopsisElements as $classSynopsis) {
-            if (!$classSynopsis instanceof DOMElement) {
-                continue;
-            }
+        foreach ($doc->getElementsByTagName("enumsynopsis") as $element) {
+            $synopsisElements[] = $element;
+        }
 
-            $child = $classSynopsis->firstElementChild;
-            if ($child === null) {
+        foreach ($synopsisElements as $synopsis) {
+            if (!$synopsis instanceof DOMElement) {
                 continue;
             }
-            $child = $child->lastElementChild;
-            if ($child === null) {
-                continue;
+
+            if ($synopsis->nodeName === "classsynopsis") {
+                $child = $synopsis->firstElementChild;
+                if ($child === null) {
+                    continue;
+                }
+                $child = $child->lastElementChild;
+                if ($child === null) {
+                    continue;
+                }
+            } elseif ($synopsis->nodeName === "enumsynopsis") {
+                $child = $synopsis->firstElementChild;
+                if ($child === null) {
+                    continue;
+                }
             }
+
             $className = $child->textContent;
+
+            if ($synopsis->parentElement->nodeName === "packagesynopsis" &&
+                $synopsis->parentElement->firstElementChild->nodeName === "package"
+            ) {
+                $package = $synopsis->parentElement->firstElementChild;
+                $namespace = $package->textContent;
+
+                $className = $namespace . "\\" . $className;
+                $elementToReplace = $synopsis->parentElement;
+            } else {
+                $elementToReplace = $synopsis;
+            }
+
             if (!isset($classMap[$className])) {
                 continue;
             }
@@ -5732,17 +5778,32 @@ function replaceClassSynopses(
 
             $classInfo = $classMap[$className];
 
-            $newClassSynopsis = $classInfo->getClassSynopsisElement($doc, $classMap, $allConstInfos);
-            if ($newClassSynopsis === null) {
+            $newSynopsis = $classInfo->getClassSynopsisElement($doc, $classMap, $allConstInfos);
+            if ($newSynopsis === null) {
                 continue;
             }
 
             // Check if there is any change - short circuit if there is not any.
 
-            if (replaceAndCompareXmls($doc, $classSynopsis, $newClassSynopsis)) {
+            if (replaceAndCompareXmls($doc, $elementToReplace, $newSynopsis)) {
                 continue;
             }
 
+            if ($synopsis->nodeName === "enumsynopsis") {
+                $oldEnumCaseDescriptionElements = collectEnumSynopsisItemDescriptions($className, $elementToReplace);
+                $newEnumCaseDescriptionElements = collectEnumSynopsisItemDescriptions($className, $newSynopsis);
+
+                foreach ($newEnumCaseDescriptionElements as $key => $newEnumCaseDescriptionElement) {
+                    if (isset($oldEnumCaseDescriptionElements[$key]) === false) {
+                        continue;
+                    }
+
+                    $oldEnumCaseDescriptionElement = $oldEnumCaseDescriptionElements[$key];
+
+                    $newEnumCaseDescriptionElement->parentElement->replaceChild($oldEnumCaseDescriptionElement, $newEnumCaseDescriptionElement);
+                }
+            }
+
             // Return the updated XML
 
             $replacedXml = $doc->saveXML();
@@ -5778,6 +5839,28 @@ function replaceClassSynopses(
     return $classSynopses;
 }
 
+/**
+ * @return array
+ */
+function collectEnumSynopsisItemDescriptions(string $className, DOMElement $synopsis): array
+{
+    $enumCaseDescriptionElements = [];
+
+    $enumCaseDescriptions = $synopsis->getElementsByTagName("enumitemdescription");
+    foreach ($enumCaseDescriptions as $enumItemDescription) {
+        $enumCaseNames = $enumItemDescription->parentElement->getElementsByTagName("enumidentifier");
+        if (empty($enumCaseNames)) {
+            continue;
+        }
+
+        $enumCaseName = $enumCaseNames[0]->textContent;
+
+        $enumCaseDescriptionElements["$className::$enumCaseName"] = $enumItemDescription;
+    }
+
+    return $enumCaseDescriptionElements;
+}
+
 function getReplacedSynopsisXml(string $xml): string
 {
     return preg_replace(
@@ -6045,9 +6128,10 @@ function installPhpParser(string $version, string $phpParserDir) {
         chdir(__DIR__);
 
         $tarName = "v$version.tar.gz";
-        passthru("wget https://github.com/nikic/PHP-Parser/archive/$tarName", $exit);
+        $downloadUrl = "https://github.com/nikic/PHP-Parser/archive/$tarName";
+        passthru("wget -O $tarName $downloadUrl", $exit);
         if ($exit !== 0) {
-            passthru("curl -LO https://github.com/nikic/PHP-Parser/archive/$tarName", $exit);
+            passthru("curl -LO $downloadUrl", $exit);
         }
         if ($exit !== 0) {
             throw new Exception("Failed to download PHP-Parser tarball");
@@ -6057,6 +6141,7 @@ function installPhpParser(string $version, string $phpParserDir) {
         }
         passthru("tar xvzf $tarName -C PHP-Parser-$version --strip-components 1", $exit);
         if ($exit !== 0) {
+            rmdir($phpParserDir);
             throw new Exception("Failed to extract PHP-Parser tarball");
         }
         unlink(__DIR__ . "/$tarName");
@@ -6078,14 +6163,14 @@ function initPhpParser() {
     }
 
     $isInitialized = true;
-    $version = "5.5.0";
+    $version = "5.6.1";
     $phpParserDir = __DIR__ . "/PHP-Parser-$version";
     if (!is_dir($phpParserDir)) {
         installPhpParser($version, $phpParserDir);
     }
 
     spl_autoload_register(static function(string $class) use ($phpParserDir) {
-        if (strpos($class, "PhpParser\\") === 0) {
+        if (str_starts_with($class, "PhpParser\\")) {
             $fileName = $phpParserDir . "/lib/" . str_replace("\\", "/", $class) . ".php";
             require $fileName;
         }
@@ -6372,7 +6457,7 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
 
 if ($verifyManual) {
     foreach ($undocumentedConstMap as $constName => $info) {
-        if ($info->name->isClassConst() || $info->isUndocumentable) {
+        if ($info->name instanceof ClassConstName || $info->isUndocumentable) {
             continue;
         }
 
diff --git a/build/libtool.m4 b/build/libtool.m4
index 0b9528d7dc7b..8d323b3ee4a6 100644
--- a/build/libtool.m4
+++ b/build/libtool.m4
@@ -1,1356 +1,2394 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
-## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
-## 2008  Free Software Foundation, Inc.
-## Originally by Gordon Matzigkeit , 1996
-##
-## This file is free software; the Free Software Foundation gives
-## unlimited permission to copy and/or distribute it, with or without
-## modifications, as long as this notice is preserved.
-
-# serial 52 AC_PROG_LIBTOOL
-
-ifdef([AC_ACVERSION],[
-# autoconf 2.13 compatibility
-# Set PATH_SEPARATOR variable
-# ---------------------------------
-# Find the correct PATH separator.  Usually this is :', but
-# DJGPP uses ;' like DOS.
-if test "X${PATH_SEPARATOR+set}" != Xset; then
-  UNAME=${UNAME-`uname 2>/dev/null`}
-  case X$UNAME in
-    *-DOS) lt_cv_sys_path_separator=';' ;;
-    *)     lt_cv_sys_path_separator=':' ;;
-  esac
-  PATH_SEPARATOR=$lt_cv_sys_path_separator
-fi
+#
+#   Copyright (C) 1996-2001, 2003-2019, 2021-2024 Free Software
+#   Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2024 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the  same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
 ])
 
-# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
-# -----------------------------------------------------------
-# If this macro is not defined by Autoconf, define it here.
-ifdef([AC_PROVIDE_IFELSE],
-         [],
-         [define([AC_PROVIDE_IFELSE],
-	         [ifdef([AC_PROVIDE_$1],
-		           [$2], [$3])])])
+# serial 63 LT_INIT
 
-# AC_PROG_LIBTOOL
-# ---------------
-AC_DEFUN([AC_PROG_LIBTOOL],
-[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
-dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
-dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
-  AC_PROVIDE_IFELSE([AC_PROG_CXX],
-    [AC_LIBTOOL_CXX],
-    [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
-  ])])
-])# AC_PROG_LIBTOOL
-
-
-# _AC_PROG_LIBTOOL
-# ----------------
-AC_DEFUN([_AC_PROG_LIBTOOL],
-[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
-AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.64])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+LIBTOOL_DEPS=$ltmain
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
 AC_SUBST(LIBTOOL)dnl
 
-# Prevent multiple expansion
-define([AC_PROG_LIBTOOL], [])
-])# _AC_PROG_LIBTOOL
+_LT_SETUP
 
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
 
-# AC_LIBTOOL_SETUP
-# ----------------
-AC_DEFUN([AC_LIBTOOL_SETUP],
-[AC_PREREQ(2.13)dnl
-AC_REQUIRE([AC_ENABLE_SHARED])dnl
-AC_REQUIRE([AC_ENABLE_STATIC])dnl
-AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+    for cc_temp in @S|@*""; do
+      case $cc_temp in
+        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+        \-*) ;;
+        *) break;;
+      esac
+    done
+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
 AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_PROG_LD])dnl
-AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
-AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
 
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
 AC_REQUIRE([AC_PROG_LN_S])dnl
-AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
-# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
-AC_REQUIRE([AC_OBJEXT])dnl
-AC_REQUIRE([AC_EXEEXT])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
 dnl
-AC_LIBTOOL_SYS_MAX_CMD_LEN
-AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-AC_LIBTOOL_OBJDIR
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_DECL_FILECMD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+   setopt NO_GLOB_SUBST
+fi
 
-AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
-_LT_AC_PROG_ECHO_BACKSLASH
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
 
 case $host_os in
 aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test "X${COLLECT_NAMES+set}" != Xset; then
+  if test set != "${COLLECT_NAMES+set}"; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
   ;;
 esac
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e 1s/^X//'
-[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
-
-# Same as above, but do not quote variable references.
-[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
-# Constants:
-rm="rm -f"
-
 # Global variables:
-default_ofile=libtool
+ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC and
+# ICC, which need '.lib').
 libext=a
-ltmain="$ac_aux_dir/ltmain.sh"
-ofile="$default_ofile"
-with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-AC_CHECK_TOOL(AR, ar, false)
-AC_CHECK_TOOL(RANLIB, ranlib, :)
-AC_CHECK_TOOL(STRIP, strip, :)
+with_gnu_ld=$lt_cv_prog_gnu_ld
 
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
+old_CC=$CC
+old_CFLAGS=$CFLAGS
 
 # Set sane defaults for various variables
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-test -z "$AS" && AS=as
 test -z "$CC" && CC=cc
 test -z "$LTCC" && LTCC=$CC
 test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
-test -z "$DLLTOOL" && DLLTOOL=dlltool
 test -z "$LD" && LD=ld
-test -z "$LN_S" && LN_S="ln -s"
-test -z "$MAGIC_CMD" && MAGIC_CMD=file
-test -z "$NM" && NM=nm
-test -z "$SED" && SED=sed
-test -z "$OBJDUMP" && OBJDUMP=objdump
-test -z "$RANLIB" && RANLIB=:
-test -z "$STRIP" && STRIP=:
 test -z "$ac_objext" && ac_objext=o
 
-# Determine commands to create old-style static archives.
-old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
-old_postinstall_cmds='chmod 644 $oldlib'
-old_postuninstall_cmds=
-
-if test -n "$RANLIB"; then
-  case $host_os in
-  openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
-    ;;
-  *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
-    ;;
-  esac
-  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
-fi
-
 _LT_CC_BASENAME([$compiler])
 
 # Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
 case $deplibs_check_method in
 file_magic*)
   if test "$file_magic_cmd" = '$MAGIC_CMD'; then
-    AC_PATH_MAGIC
+    _LT_PATH_MAGIC
   fi
   ;;
 esac
 
-_LT_REQUIRED_DARWIN_CHECKS
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
 
-AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
-AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
-enable_win32_dll=yes, enable_win32_dll=no)
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
 
-AC_ARG_ENABLE([libtool-lock],
-[  --disable-libtool-lock  Avoid locking (might break parallel builds)])
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
 
-AC_ARG_WITH([pic],
-[  --with-pic              Try to use only PIC/non-PIC objects [default=use both]],
-    [pic_mode="$withval"],
-    [pic_mode=default])
-test -z "$pic_mode" && pic_mode=default
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
 
-# Use C for the default configuration in the libtool script
-tagname=
-AC_LIBTOOL_LANG_C_CONFIG
-_LT_AC_TAGCONFIG
-])# AC_LIBTOOL_SETUP
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
 
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
 
-# _LT_AC_SYS_COMPILER
-# -------------------
-AC_DEFUN([_LT_AC_SYS_COMPILER],
-[AC_REQUIRE([AC_PROG_CC])dnl
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
 
-# If no C compiler was specified, use CC.
-LTCC=${LTCC-"$CC"}
 
-# If no C compiler flags were specified, use CFLAGS.
-LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
 
-# Allow CC to be a program name with arguments.
-compiler=$CC
-])# _LT_AC_SYS_COMPILER
 
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
 
-# _LT_CC_BASENAME(CC)
-# -------------------
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-AC_DEFUN([_LT_CC_BASENAME],
-[for cc_temp in $1""; do
-  case $cc_temp in
-    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
-    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
-    \-*) ;;
-    *) break;;
-  esac
-done
-cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
 ])
 
 
-# _LT_COMPILER_BOILERPLATE
-# ------------------------
-# Check for compiler boilerplate output or warnings with
-# the simple compiler test code.
-AC_DEFUN([_LT_COMPILER_BOILERPLATE],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_compile_test_code" >conftest.$ac_ext
-eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_compiler_boilerplate=`cat conftest.err`
-$rm conftest*
-])# _LT_COMPILER_BOILERPLATE
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
 
 
-# _LT_LINKER_BOILERPLATE
-# ----------------------
-# Check for linker boilerplate output or warnings with
-# the simple link test code.
-AC_DEFUN([_LT_LINKER_BOILERPLATE],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-ac_outfile=conftest.$ac_objext
-echo "$lt_simple_link_test_code" >conftest.$ac_ext
-eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
-_lt_linker_boilerplate=`cat conftest.err`
-$rm -r conftest*
-])# _LT_LINKER_BOILERPLATE
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
 
 
-dnl autoconf 2.13 compatibility
-dnl _LT_AC_TRY_LINK()
-AC_DEFUN([_LT_AC_TRY_LINK], [
-cat > conftest.$ac_ext <&5
-  cat conftest.$ac_ext >&6
-ifelse([$2], , , [$2
-  rm -rf conftest*
-])dnl
-fi
-rm -f conftest*])
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
 
-# _LT_REQUIRED_DARWIN_CHECKS
-# --------------------------
-# Check for some things on darwin
-AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS],[
-  case $host_os in
-    rhapsody* | darwin*)
-    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
-    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
 
-    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
-      [lt_cv_apple_cc_single_mod=no
-      if test -z "${LT_MULTI_MODULE}"; then
-   # By default we will add the -single_module flag. You can override
-   # by either setting the environment variable LT_MULTI_MODULE
-   # non-empty at configure time, or by adding -multi_module to the
-   # link flags.
-   echo "int foo(void){return 1;}" > conftest.c
-   $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
-     -dynamiclib ${wl}-single_module conftest.c
-   if test -f libconftest.dylib; then
-     lt_cv_apple_cc_single_mod=yes
-     rm -rf libconftest.dylib*
-   fi
-   rm conftest.c
-      fi])
-    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
-      [lt_cv_ld_exported_symbols_list],
-      [lt_cv_ld_exported_symbols_list=no
-      save_LDFLAGS=$LDFLAGS
-      echo "_main" > conftest.sym
-      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
-      _LT_AC_TRY_LINK([lt_cv_ld_exported_symbols_list=yes],[lt_cv_ld_exported_symbols_list=no])
-   LDFLAGS="$save_LDFLAGS"
-    ])
-    case $host_os in
-    rhapsody* | darwin1.[[0123]])
-      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
-    darwin1.*)
-     _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
-    darwin*)
-      # if running on 10.5 or later, the deployment target defaults
-      # to the OS version, if on x86, and 10.4, the deployment
-      # target defaults to 10.4. Don't you love it?
-      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
-   10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
-     _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
-   10.[[012]]*)
-     _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
-   *)
-     _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
-      esac
-    ;;
-  esac
-    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
-      _lt_dar_single_mod='$single_module'
-    fi
-    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
-      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
-    else
-      _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}"
-    fi
-    if test "$DSYMUTIL" != ":"; then
-      _lt_dsymutil="~$DSYMUTIL \$lib || :"
-    else
-      _lt_dsymutil=
-    fi
-    ;;
-  esac
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
 ])
 
-# _LT_AC_SYS_LIBPATH_AIX
-# ----------------------
-# Links a minimal program and checks the executable
-# for the system default hardcoded library path. In most cases,
-# this is /usr/lib:/lib, but when the MPI compilers are used
-# the location of the communication and MPI libs are included too.
-# If we don't find anything, use the default library path according
-# to the aix ld manual.
-AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-_LT_AC_TRY_LINK([
-lt_aix_libpath_sed='
-    /Import File Strings/,/^$/ {
-	/^0/ {
-	    s/^0  *\(.*\)$/\1/
-	    p
-	}
-    }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi],[])
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
-])# _LT_AC_SYS_LIBPATH_AIX
 
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    ='`$ECHO "$" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
 
-# _LT_AC_SHELL_INIT(ARG)
-# ----------------------
-AC_DEFUN([_LT_AC_SHELL_INIT],
-[ifdef([AC_DIVERSION_NOTICE],
-	     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
-	 [AC_DIVERT_PUSH(NOTICE)])
-$1
-AC_DIVERT_POP
-])# _LT_AC_SHELL_INIT
 
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
 
-# _LT_AC_PROG_ECHO_BACKSLASH
-# --------------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
-AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
-[_LT_AC_SHELL_INIT([
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$ECHO in
-X*--fallback-echo)
-  # Remove one level of quotation (which was required for Make).
-  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
-  ;;
-esac
 
-echo=${ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X[$]1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
-  # Yippee, $echo works!
-  :
-else
-  # Restart under the correct shell.
-  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
 
-if test "X[$]1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat </dev/null 2>&1 && unset CDPATH
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
 
-if test -z "$ECHO"; then
-if test "X${echo_test_string+set}" != Xset; then
-# find a string as large as possible, as long as the shell can cope with it
-  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
-    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
-    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
-       echo_test_string=`eval $cmd` &&
-       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
-    then
-      break
-    fi
-  done
-fi
 
-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
-   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
-   test "X$echo_testing_string" = "X$echo_test_string"; then
-  :
-else
-  # The Solaris, AIX, and Digital Unix default echo programs unquote
-  # backslashes.  This makes it impossible to quote backslashes using
-  #   echo "$something" | sed 's/\\/\\\\/g'
-  #
-  # So, first we look for a working echo in the user's PATH.
-
-  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-  for dir in $PATH /usr/ucb; do
-    IFS="$lt_save_ifs"
-    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
-       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
-       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
-       test "X$echo_testing_string" = "X$echo_test_string"; then
-      echo="$dir/echo"
-      break
-    fi
-  done
-  IFS="$lt_save_ifs"
-
-  if test "X$echo" = Xecho; then
-    # We didn't find a better echo, so look for alternatives.
-    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
-       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
-       test "X$echo_testing_string" = "X$echo_test_string"; then
-      # This shell has a builtin print -r that does the trick.
-      echo='print -r'
-    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
-	 test "X$CONFIG_SHELL" != X/bin/ksh; then
-      # If we have ksh, try running configure again with it.
-      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
-      export ORIGINAL_CONFIG_SHELL
-      CONFIG_SHELL=/bin/ksh
-      export CONFIG_SHELL
-      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
-    else
-      # Try using printf.
-      echo='printf %s\n'
-      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
-	 echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
-	 test "X$echo_testing_string" = "X$echo_test_string"; then
-	# Cool, printf works
-	:
-      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
-	   test "X$echo_testing_string" = 'X\t' &&
-	   echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
-	   test "X$echo_testing_string" = "X$echo_test_string"; then
-	CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
-	export CONFIG_SHELL
-	SHELL="$CONFIG_SHELL"
-	export SHELL
-	echo="$CONFIG_SHELL [$]0 --fallback-echo"
-      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
-	   test "X$echo_testing_string" = 'X\t' &&
-	   echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
-	   test "X$echo_testing_string" = "X$echo_test_string"; then
-	echo="$CONFIG_SHELL [$]0 --fallback-echo"
-      else
-	# maybe with a smaller string...
-	prev=:
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
 
-	for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
-	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
-	  then
-	    break
-	  fi
-	  prev="$cmd"
-	done
 
-	if test "$prev" != 'sed 50q "[$]0"'; then
-	  echo_test_string=`eval $prev`
-	  export echo_test_string
-	  exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
-	else
-	  # Oops.  We lost completely, so just stick with echo.
-	  echo=echo
-	fi
-      fi
-    fi
-  fi
-fi
-fi
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
 
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-ECHO=$echo
-if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
-   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
 
-AC_SUBST(ECHO)
-])])# _LT_AC_PROG_ECHO_BACKSLASH
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
 
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
-# _LT_AC_LOCK
-# -----------
-AC_DEFUN([_LT_AC_LOCK],
-[dnl
-#AC_ARG_ENABLE([libtool-lock],
-#[  --disable-libtool-lock  avoid locking (might break parallel builds)])
-#test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
 
-# Some flags need to be propagated to the compiler or linker for good
-# libtool support.
-case $host in
-ia64-*-hpux*)
-  # Find out which ABI we are using.
-  echo 'int i;' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-    case `/usr/bin/file conftest.$ac_objext` in
-    *ELF-32*)
-      HPUX_IA64_MODE="32"
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
       ;;
-    *ELF-64*)
-      HPUX_IA64_MODE="64"
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
       ;;
     esac
-  fi
-  rm -rf conftest*
-  ;;
-*-*-irix6*)
-  # Find out which ABI we are using.
-  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-   if test "$lt_cv_prog_gnu_ld" = yes; then
-    case `/usr/bin/file conftest.$ac_objext` in
-    *32-bit*)
-      LD="${LD-ld} -melf32bsmip"
-      ;;
-    *N32*)
-      LD="${LD-ld} -melf32bmipn32"
-      ;;
-    *64-bit*)
-      LD="${LD-ld} -melf64bmip"
-      ;;
-    esac
-   else
-    case `/usr/bin/file conftest.$ac_objext` in
-    *32-bit*)
-      LD="${LD-ld} -32"
-      ;;
-    *N32*)
-      LD="${LD-ld} -n32"
-      ;;
-    *64-bit*)
-      LD="${LD-ld} -64"
-      ;;
-    esac
-   fi
-  fi
-  rm -rf conftest*
-  ;;
+done
 
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
-s390*-*linux*|sparc*-*linux*)
-  # Find out which ABI we are using.
-  echo 'int i;' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-    case `/usr/bin/file conftest.o` in
-    *32-bit*)
-      case $host in
-        x86_64-*kfreebsd*-gnu)
-          LD="${LD-ld} -m elf_i386_fbsd"
-          ;;
-        x86_64-*linux*)
-          LD="${LD-ld} -m elf_i386"
-          ;;
-        powerpc64le-*linux*)
-          LD="${LD-ld} -m elf32lppclinux"
-          ;;
-        powerpc64-*linux*)
-          LD="${LD-ld} -m elf32ppclinux"
-          ;;
-        s390x-*linux*)
-          LD="${LD-ld} -m elf_s390"
-          ;;
-        sparc64-*linux*)
-          LD="${LD-ld} -m elf32_sparc"
-          ;;
-      esac
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
       ;;
-    *64-bit*)
-      case $host in
-        x86_64-*kfreebsd*-gnu)
-          LD="${LD-ld} -m elf_x86_64_fbsd"
-          ;;
-        x86_64-*linux*)
-          LD="${LD-ld} -m elf_x86_64"
-          ;;
-        powerpcle-*linux*)
-          LD="${LD-ld} -m elf64lppc"
-          ;;
-        powerpc-*linux*)
-          LD="${LD-ld} -m elf64ppc"
-          ;;
-        s390*-*linux*)
-          LD="${LD-ld} -m elf64_s390"
-          ;;
-        sparc*-*linux*)
-          LD="${LD-ld} -m elf64_sparc"
-          ;;
-      esac
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
       ;;
     esac
-  fi
-  rm -rf conftest*
-  ;;
+done
 
-*-*-sco3.2v5*)
-  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS="$CFLAGS"
-  CFLAGS="$CFLAGS -belf"
-  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
-    [AC_LANG_PUSH([C])
-     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
-    AC_LANG_POP([C])])
-  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
-    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS="$SAVE_CFLAGS"
-  fi
-  ;;
-sparc*-*solaris*)
-  # Find out which ABI we are using.
-  echo 'int i;' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-    case `/usr/bin/file conftest.o` in
-    *64-bit*)
-      case $lt_cv_prog_gnu_ld in
-      yes*) LD="${LD-ld} -m elf64_sparc" ;;
-      *)
-        if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
-	  LD="${LD-ld} -64"
-	fi
-	;;
-      esac
-      ;;
-    esac
-  fi
-  rm -rf conftest*
-  ;;
+_LT_OUTPUT_LIBTOOL_INIT
+])
 
-AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
-[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
-  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
-  AC_CHECK_TOOL(AS, as, false)
-  AC_CHECK_TOOL(OBJDUMP, objdump, false)
-  ;;
-  ])
-esac
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), in case it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
 
-need_locks="$enable_libtool_lock"
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
 
-])# _LT_AC_LOCK
+Usage: $[0] [[OPTIONS]]
 
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
 
-# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
-# ----------------------------------------------------------------
-# Check whether the given compiler option works
-AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
-[AC_REQUIRE([LT_AC_PROG_SED])
-AC_CACHE_CHECK([$1], [$2],
-  [$2=no
-  ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
-   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$3"
-   # Insert the option either (1) after the last *FLAGS variable, or
-   # (2) before a word containing "conftest.", or (3) at the end.
-   # Note that $ac_compile itself does not contain backslashes and begins
-   # with a dollar sign (not a hyphen), so the echo should work correctly.
-   # The option is referenced via a variable to avoid confusing sed.
-   lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-   -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"configure:__oline__: $lt_compile\"" >&5)
-   (eval "$lt_compile" 2>conftest.err)
-   ac_status=$?
-   cat conftest.err >&5
-   echo "configure:__oline__: \$? = $ac_status" >&5
-   if (exit $ac_status) && test -s "$ac_outfile"; then
-     # The compiler can only warn and ignore the option if not recognized
-     # So say no if there are warnings other than the usual output.
-     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
-     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
-     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
-       $2=yes
-     fi
-   fi
-   $rm conftest*
-])
+Report bugs to ."
 
-if test x"[$]$2" = xyes; then
-    ifelse([$5], , :, [$5])
-else
-    ifelse([$6], , :, [$6])
-fi
-])# AC_LIBTOOL_COMPILER_OPTION
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
 
+Copyright (C) 2024 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
 
-# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
-#                          [ACTION-SUCCESS], [ACTION-FAILURE])
-# ------------------------------------------------------------
-# Check whether the given compiler option works
-AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_CACHE_CHECK([$1], [$2],
-  [$2=no
-   save_LDFLAGS="$LDFLAGS"
-   LDFLAGS="$LDFLAGS $3"
-   echo "$lt_simple_link_test_code" > conftest.$ac_ext
-   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
-     # The linker can only warn and ignore the option if not recognized
-     # So say no if there are warnings
-     if test -s conftest.err; then
-       # Append any errors to the config.log.
-       cat conftest.err 1>&5
-       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
-       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
-       if diff conftest.exp conftest.er2 >/dev/null; then
-         $2=yes
-       fi
-     else
-       $2=yes
-     fi
-   fi
-   $rm -r conftest*
-   LDFLAGS="$save_LDFLAGS"
-])
+while test 0 != $[#]
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
 
-if test x"[$]$2" = xyes; then
-    ifelse([$4], , :, [$4])
-else
-    ifelse([$5], , :, [$5])
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
 fi
-])# AC_LIBTOOL_LINKER_OPTION
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options that allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}"; then
+      setopt NO_GLOB_SUBST
+    fi
 
+    cfgfile=${ofile}T
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
 
-# AC_LIBTOOL_SYS_MAX_CMD_LEN
-# --------------------------
-AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
-[# find the maximum length of command line arguments
-AC_MSG_CHECKING([the maximum length of command line arguments])
-AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
-  i=0
-  teststring="ABCD"
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
 
-  case $build_os in
-  msdosdjgpp*)
-    # On DJGPP, this test can blow up pretty badly due to problems in libc
-    # (any single argument exceeding 2000 bytes causes a buffer overrun
-    # during glob expansion).  Even if it were fixed, the result of this
-    # check would be larger than it should be.
-    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
-    ;;
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
 
-  gnu*)
-    # Under GNU Hurd, this test is not required because there is
-    # no limit to the length of command line arguments.
-    # Libtool will interpret -1 as no limit whatsoever
-    lt_cv_sys_max_cmd_len=-1;
-    ;;
+_LT_COPYING
+_LT_LIBTOOL_TAGS
 
-  cygwin* | mingw*)
-    # On Win9x/ME, this test blows up -- it succeeds, but takes
-    # about 5 minutes as the teststring grows exponentially.
-    # Worse, since 9x/ME are not pre-emptively multitasking,
-    # you end up with a "frozen" computer, even though with patience
-    # the test eventually succeeds (with a max line length of 256k).
-    # Instead, let's just punt: use the minimum linelength reported by
-    # all of the supported platforms: 8192 (on NT/2K/XP).
-    lt_cv_sys_max_cmd_len=8192;
-    ;;
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
 
-  amigaos*)
-    # On AmigaOS with pdksh, this test takes hours, literally.
-    # So we just punt and use a minimum line length of 8192.
-    lt_cv_sys_max_cmd_len=8192;
-    ;;
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
 
-  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
-    # This has been around since 386BSD, at least.  Likely further.
-    if test -x /sbin/sysctl; then
-      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
-    elif test -x /usr/sbin/sysctl; then
-      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
-    else
-      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
-    fi
-    # And add a safety zone
-    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
-    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
-    ;;
+_LT_EOF
 
-  interix*)
-    # We know the value 262144 and hardcode it with a safety zone (like BSD)
-    lt_cv_sys_max_cmd_len=196608
-    ;;
+    cat <<'_LT_EOF' >> "$cfgfile"
 
-  osf*)
-    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
-    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
-    # nice to cause kernel panics so lets avoid the loop below.
-    # First set a reasonable default.
-    lt_cv_sys_max_cmd_len=16384
-    #
-    if test -x /sbin/sysconfig; then
-      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
-        *1*) lt_cv_sys_max_cmd_len=-1 ;;
-      esac
-    fi
-    ;;
-  sco3.2v5*)
-    lt_cv_sys_max_cmd_len=102400
-    ;;
-  sysv5* | sco5v6* | sysv4.2uw2*)
-    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
-    if test -n "$kargmax"; then
-      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ 	]]//'`
-    else
-      lt_cv_sys_max_cmd_len=32768
-    fi
-    ;;
-  *)
-    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
-    if test -n "$lt_cv_sys_max_cmd_len"; then
-      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
-      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
-    else
-      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
-      while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
-	       = "XX$teststring") >/dev/null 2>&1 &&
-	      new_result=`expr "X$teststring" : ".*" 2>&1` &&
-	      lt_cv_sys_max_cmd_len=$new_result &&
-	      test $i != 17 # 1/2 MB should be enough
-      do
-        i=`expr $i + 1`
-        teststring=$teststring$teststring
-      done
-      teststring=
-      # Add a significant safety factor because C++ compilers can tack on massive
-      # amounts of additional arguments before passing them to the linker.
-      # It appears as though 1/2 is a usable value.
-      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
-    fi
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
     ;;
   esac
-])
-if test -n $lt_cv_sys_max_cmd_len ; then
-  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
-else
-  AC_MSG_RESULT(none)
-fi
-])# AC_LIBTOOL_SYS_MAX_CMD_LEN
 
+  _LT_PROG_LTMAIN
 
-# _LT_AC_CHECK_DLFCN
-# ------------------
-AC_DEFUN([_LT_AC_CHECK_DLFCN],
-[AC_CHECK_HEADERS(dlfcn.h)dnl
-])# _LT_AC_CHECK_DLFCN
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  $SED '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
 
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
 
-# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
-#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
-# ---------------------------------------------------------------------
-AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
-[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
-if test "$cross_compiling" = yes; then :
-  [$4]
-else
-  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
-  lt_status=$lt_dlunknown
-  cat > conftest.$ac_ext <
-#endif
 
-#include 
-#include 
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
 
-#ifdef RTLD_GLOBAL
-#  define LT_DLGLOBAL		RTLD_GLOBAL
-#else
-#  ifdef DL_GLOBAL
-#    define LT_DLGLOBAL		DL_GLOBAL
-#  else
-#    define LT_DLGLOBAL		0
-#  endif
-#endif
 
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
-   find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-#  ifdef RTLD_LAZY
-#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
-#  else
-#    ifdef DL_LAZY
-#      define LT_DLLAZY_OR_NOW		DL_LAZY
-#    else
-#      ifdef RTLD_NOW
-#        define LT_DLLAZY_OR_NOW	RTLD_NOW
-#      else
-#        ifdef DL_NOW
-#          define LT_DLLAZY_OR_NOW	DL_NOW
-#        else
-#          define LT_DLLAZY_OR_NOW	0
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
 
-void fnord(void) { int i=42;}
-int main (void)
-{
-  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
-  int status = $lt_dlunknown;
 
-  if (self)
-    {
-      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
-      /* dlclose (self); */
-    }
-  else
-    puts (dlerror ());
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Go],			[_LT_LANG(GO)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
 
-    return (status);
-}]
-EOF
-  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
-    (./conftest; exit; ) >&5 2>/dev/null
-    lt_status=$?
-    case x$lt_status in
-      x$lt_dlno_uscore) $1 ;;
-      x$lt_dlneed_uscore) $2 ;;
-      x$lt_dlunknown|x*) $3 ;;
-    esac
-  else :
-    # compilation failed
-    $3
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
   fi
 fi
-rm -fr conftest*
-])# _LT_AC_TRY_DLOPEN_SELF
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
 
 
-# AC_LIBTOOL_DLOPEN_SELF
-# ----------------------
-AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
-[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
-if test "x$enable_dlopen" != xyes; then
-  enable_dlopen=unknown
-  enable_dlopen_self=unknown
-  enable_dlopen_self_static=unknown
-else
-  lt_cv_dlopen=no
-  lt_cv_dlopen_libs=
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
 
-  case $host_os in
-  beos* | haiku*)
-    lt_cv_dlopen="load_add_on"
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=yes
-    ;;
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
 
-  mingw* | pw32*)
-    lt_cv_dlopen="LoadLibrary"
-    lt_cv_dlopen_libs=
-   ;;
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
 
-  cygwin*)
-    lt_cv_dlopen="dlopen"
-    lt_cv_dlopen_libs=
-   ;;
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
 
-  darwin*)
-  # if libdl is installed we need to link against it
-    AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
-    lt_cv_dlopen="dyld"
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=yes
-    ])
-   ;;
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
 
-  *)
-    AC_CHECK_FUNC([shl_load],
-	  [lt_cv_dlopen="shl_load"],
-      [AC_CHECK_LIB([dld], [shl_load],
-	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
-	[AC_CHECK_FUNC([dlopen],
-	      [lt_cv_dlopen="dlopen"],
-	  [AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
-	    [AC_CHECK_LIB([svld], [dlopen],
-		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
-	      [AC_CHECK_LIB([dld], [dld_link],
-		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
-	      ])
-	    ])
-	  ])
-	])
-      ])
-    ;;
-  esac
 
-  if test "x$lt_cv_dlopen" != xno; then
-    enable_dlopen=yes
-  else
-    enable_dlopen=no
-  fi
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
 
-  case $lt_cv_dlopen in
-  dlopen)
-    save_CPPFLAGS="$CPPFLAGS"
-    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS="$LDFLAGS"
-    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
 
-    save_LIBS="$LIBS"
-    LIBS="$lt_cv_dlopen_libs $LIBS"
 
-    AC_CACHE_CHECK([whether a program can dlopen itself],
-	  lt_cv_dlopen_self, [dnl
-	  _LT_AC_TRY_DLOPEN_SELF(
-	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
-	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "$LT_MULTI_MODULE"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+
+    # Feature test to disable chained fixups since it is not
+    # compatible with '-undefined dynamic_lookup'
+    AC_CACHE_CHECK([for -no_fixup_chains linker flag],
+      [lt_cv_support_no_fixup_chains],
+      [ save_LDFLAGS=$LDFLAGS
+        LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains"
+        AC_LINK_IFELSE(
+          [AC_LANG_PROGRAM([],[])],
+          lt_cv_support_no_fixup_chains=yes,
+          lt_cv_support_no_fixup_chains=no
+        )
+        LDFLAGS=$save_LDFLAGS
+      ]
+    )
+
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS=$save_LDFLAGS
     ])
 
-    if test "x$lt_cv_dlopen_self" = xyes; then
-      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
-      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
-    	  lt_cv_dlopen_self_static, [dnl
-	  _LT_AC_TRY_DLOPEN_SELF(
-	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
-	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
-      ])
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main(void) { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+    darwin*)
+      case $MACOSX_DEPLOYMENT_TARGET,$host in
+        10.[[012]],*|,*powerpc*-darwin[[5-8]]*)
+          _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+        *)
+          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup'
+          if test yes = "$lt_cv_support_no_fixup_chains"; then
+            AS_VAR_APPEND([_lt_dar_allow_undefined], [' $wl-no_fixup_chains'])
+          fi
+        ;;
+      esac
+    ;;
+  esac
+    if test yes = "$lt_cv_apple_cc_single_mod"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    _lt_dar_needs_single_mod=no
+    case $host_os in
+    rhapsody* | darwin1.*)
+      _lt_dar_needs_single_mod=yes ;;
+    darwin*)
+      # When targeting Mac OS X 10.4 (darwin 8) or later,
+      # -single_module is the default and -multi_module is unsupported.
+      # The toolchain on macOS 10.14 (darwin 18) and later cannot
+      # target any OS version that needs -single_module.
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+      10.0,*-darwin[[567]].*|10.[[0-3]],*-darwin[[5-9]].*|10.[[0-3]],*-darwin1[[0-7]].*)
+        _lt_dar_needs_single_mod=yes ;;
+      esac
+    ;;
+    esac
+    if test yes = "$lt_cv_ld_exported_symbols_list"; then
+      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+    fi
+    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
     fi
-
-    CPPFLAGS="$save_CPPFLAGS"
-    LDFLAGS="$save_LDFLAGS"
-    LIBS="$save_LIBS"
     ;;
   esac
+])
 
-  case $lt_cv_dlopen_self in
-  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
-  *) enable_dlopen_self=unknown ;;
-  esac
 
-  case $lt_cv_dlopen_self_static in
-  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
-  *) enable_dlopen_self_static=unknown ;;
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  if test yes = "$lt_cv_ld_force_load"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+  case $cc_basename in
+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
   esac
-fi
-])# AC_LIBTOOL_DLOPEN_SELF
+  if test yes = "$_lt_dar_can_shared"; then
+    output_verbose_link_cmd=func_echo_all
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+    _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    m4_if([$1], [CXX],
+[   if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
 
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
 
-# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
-# ---------------------------------
-# Check to see if options -c and -o are simultaneously supported by compiler
-AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
-AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
-  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
-  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
-   $rm -r conftest 2>/dev/null
-   mkdir conftest
-   cd conftest
-   mkdir out
-   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
-   lt_compiler_flag="-o out/conftest2.$ac_objext"
-   # Insert the option either (1) after the last *FLAGS variable, or
-   # (2) before a word containing "conftest.", or (3) at the end.
-   # Note that $ac_compile itself does not contain backslashes and begins
-   # with a dollar sign (not a hyphen), so the echo should work correctly.
-   lt_compile=`echo "$ac_compile" | $SED \
-   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-   -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"configure:__oline__: $lt_compile\"" >&5)
-   (eval "$lt_compile" 2>out/conftest.err)
-   ac_status=$?
-   cat out/conftest.err >&5
-   echo "configure:__oline__: \$? = $ac_status" >&5
-   if (exit $ac_status) && test -s out/conftest2.$ac_objext
-   then
-     # The compiler can only warn and ignore the option if not recognized
-     # So say no if there are warnings
-     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
-     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
-     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
-       _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
-     fi
-   fi
-   chmod u+w . 2>&5
-   $rm conftest*
-   # SGI C++ compiler will create directory out/ii_files/ for
-   # template instantiation
-   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
-   $rm out/* && rmdir out
-   cd ..
-   rmdir conftest
-   $rm conftest*
-])
-])# AC_LIBTOOL_PROG_CC_C_O
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
 
 
-# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
-# -----------------------------------------
-# Check to see if we can do hard links to lock some files if needed
-AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
-[AC_REQUIRE([_LT_AC_LOCK])dnl
 
-hard_links="nottested"
-if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
-  # do not overwrite the value of need_locks provided by the user
-  AC_MSG_CHECKING([if we can lock with hard links])
-  hard_links=yes
-  $rm conftest*
-  ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  touch conftest.a
-  ln conftest.a conftest.b 2>&5 || hard_links=no
-  ln conftest.a conftest.b 2>/dev/null && hard_links=no
-  AC_MSG_RESULT([$hard_links])
-  if test "$hard_links" = no; then
-    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
-    need_locks=warn
-  fi
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
 else
-  need_locks=no
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
 fi
-])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
 
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
 
-# AC_LIBTOOL_OBJDIR
-# -----------------
-AC_DEFUN([AC_LIBTOOL_OBJDIR],
-[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
-[rm -f .libs 2>/dev/null
-mkdir .libs 2>/dev/null
-if test -d .libs; then
-  lt_cv_objdir=.libs
-else
-  # MS-DOS does not allow filenames that begin with a dot.
+case $ECHO in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+  [Search for dependent libraries within DIR (or the compiler's sysroot
+   if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+   if test yes = "$GCC"; then
+     # Trim trailing / since we'll always append absolute paths and we want
+     # to avoid //, if only for less confusing output for the user.
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([$with_sysroot])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out what ABI is being produced by ac_compile, and set mode
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `$FILECMD conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE=32
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE=64
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test yes = "$lt_cv_prog_gnu_ld"; then
+      case `$FILECMD conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `$FILECMD conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+mips64*-*linux*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    emul=elf
+    case `$FILECMD conftest.$ac_objext` in
+      *32-bit*)
+	emul="${emul}32"
+	;;
+      *64-bit*)
+	emul="${emul}64"
+	;;
+    esac
+    case `$FILECMD conftest.$ac_objext` in
+      *MSB*)
+	emul="${emul}btsmip"
+	;;
+      *LSB*)
+	emul="${emul}ltsmip"
+	;;
+    esac
+    case `$FILECMD conftest.$ac_objext` in
+      *N32*)
+	emul="${emul}n32"
+	;;
+    esac
+    LD="${LD-ld} -m $emul"
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.  Note that the listed cases only cover the
+  # situations where additional linker options are needed (such as when
+  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+  # vice versa); the common cases where no linker options are needed do
+  # not appear in the list.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `$FILECMD conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*|x86_64-gnu*)
+	    case `$FILECMD conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*linux*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*|x86_64-gnu*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*linux*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test yes != "$lt_cv_cc_needs_belf"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS=$SAVE_CFLAGS
+  fi
+  ;;
+*-*solaris*)
+  # Find out what ABI is being produced by ac_compile, and set linker
+  # options accordingly.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `$FILECMD conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*|x86_64-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD=${LD-ld}_sol2
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+_LT_DECL([], [AR], [1], [The archiver])
+
+# Use ARFLAGS variable as AR's operation code to sync the variable naming with
+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
+# higher priority because that's what people were doing historically (setting
+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
+# variable obsoleted/removed.
+
+test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
+lt_ar_flags=$AR_FLAGS
+_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
+
+# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
+_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
+         [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test 0 -eq "$ac_status"; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test 0 -ne "$ac_status"; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test no = "$lt_cv_ar_at_file"; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_REQUIRE([AC_PROG_RANLIB])
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+  old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS=$LDFLAGS
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring=ABCD
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu* | ironclad*)
+    # Under GNU Hurd and Ironclad, this test is not required because there
+    # is no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | windows* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+       test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test 17 != "$i" # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include 
+#endif
+
+#include 
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord (void) __attribute__((visibility("default")));
+#endif
+
+int fnord (void) { return 42; }
+int main (void)
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | windows* | pw32* | cegcc*)
+    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+    # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+    lt_cv_dlopen=dyld
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  tpf*)
+    # Don't try to run any link tests for TPF.  We know it's impossible
+    # because TPF is a cross-compiler, and we know how we open DSOs.
+    lt_cv_dlopen=dlopen
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=no
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen=shl_load],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen=dlopen],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test no = "$lt_cv_dlopen"; then
+    enable_dlopen=no
+  else
+    enable_dlopen=yes
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS=$CPPFLAGS
+    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS=$LDFLAGS
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS=$LIBS
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test yes = "$lt_cv_dlopen_self"; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS=$save_CPPFLAGS
+    LDFLAGS=$save_LDFLAGS
+    LIBS=$save_LIBS
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test no = "$hard_links"; then
+    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
   lt_cv_objdir=_libs
 fi
 rmdir .libs 2>/dev/null])
 objdir=$lt_cv_objdir
-])# AC_LIBTOOL_OBJDIR
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+  [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
 
 
-# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
-# ----------------------------------------------
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
 # Check hardcoding attributes.
-AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
 [AC_MSG_CHECKING([how to hardcode library paths into programs])
-_LT_AC_TAGVAR(hardcode_action, $1)=
-if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
-   test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \
-   test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
 
   # We can hardcode non-existent directories.
-  if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
-     test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
     # Linking always hardcodes the temporary library directory.
-    _LT_AC_TAGVAR(hardcode_action, $1)=relink
+    _LT_TAGVAR(hardcode_action, $1)=relink
   else
     # We can link without hardcoding, and we can hardcode nonexisting dirs.
-    _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+    _LT_TAGVAR(hardcode_action, $1)=immediate
   fi
 else
   # We cannot hardcode anything, or else we can only hardcode existing
   # directories.
-  _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
 fi
-AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
 
-if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
-     test "$enable_shared" = no; then
+elif test yes = "$shlibpath_overrides_runpath" ||
+     test no = "$enable_shared"; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
-])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
 
 
-# AC_LIBTOOL_SYS_LIB_STRIP
-# ------------------------
-AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
-[striplib=
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
 old_striplib=
 AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
-  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
-  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
-  AC_MSG_RESULT([yes])
-else
-# FIXME - insert some real tests, host_os isn't really good enough
-  case $host_os in
-   darwin*)
-       if test -n "$STRIP" ; then
-         striplib="$STRIP -x"
-         old_striplib="$STRIP -S"
-         AC_MSG_RESULT([yes])
-       else
+if test -z "$STRIP"; then
   AC_MSG_RESULT([no])
+else
+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+    old_striplib="$STRIP --strip-debug"
+    striplib="$STRIP --strip-unneeded"
+    AC_MSG_RESULT([yes])
+  else
+    case $host_os in
+    darwin*)
+      # FIXME - insert some real tests, host_os isn't really good enough
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+      ;;
+    freebsd*)
+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
+        old_striplib="$STRIP --strip-debug"
+        striplib="$STRIP --strip-unneeded"
+        AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+      fi
+      ;;
+    *)
+      AC_MSG_RESULT([no])
+      ;;
+    esac
+  fi
 fi
-       ;;
-   *)
-  AC_MSG_RESULT([no])
-    ;;
-  esac
-fi
-])# AC_LIBTOOL_SYS_LIB_STRIP
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
 
 
-# AC_LIBTOOL_SYS_DYNAMIC_LINKER
-# -----------------------------
-# PORTME Fill in your ld.so characteristics
-AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_MSG_CHECKING([dynamic linker characteristics])
-library_names_spec=
-libname_spec='lib$name'
-soname_spec=
-shrext_cmds=".so"
-postinstall_cmds=
-postuninstall_cmds=
-finish_cmds=
-finish_eval=
-shlibpath_var=
-shlibpath_overrides_runpath=unknown
-version_type=none
-dynamic_linker="$host_os ld.so"
-sys_lib_dlsearch_path_spec="/lib /usr/lib"
-ifelse($1,[],[
-if test "$GCC" = yes; then
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+#       string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+#       string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+#       "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+#       VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+    case x@S|@2 in
+    x)
+        ;;
+    *:)
+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+        ;;
+    x:*)
+        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+        ;;
+    *::*)
+        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+        ;;
+    *)
+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+        ;;
+    esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test yes = "$GCC"; then
+  case $host_os in
+    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+    *) lt_awk_arg='/^libraries:/' ;;
+  esac
   case $host_os in
-    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
-    *) lt_awk_arg="/^libraries:/" ;;
+    mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+    *) lt_sed_strip_eq='s|=/|/|g' ;;
   esac
-  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
     # if the path contains ";" then we assume it to be the separator
     # otherwise default to the standard path separator (i.e. ":") - it is
     # assumed that no part of a normal pathname contains ";" but that should
     # okay in the real world where ";" in dirpaths is itself problematic.
-    lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'`
-  else
-    lt_search_path_spec=`echo "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-  fi
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary.
+  # and add multilib dir if necessary...
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  # ...but if some path component already ends with the multilib dir we assume
+  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+  case "$lt_multi_os_dir; $lt_search_path_spec " in
+  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+    lt_multi_os_dir=
+    ;;
+  esac
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
-    else
+    if test -d "$lt_sys_path$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+    elif test -n "$lt_multi_os_dir"; then
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
-  lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk '
-BEGIN {RS=" "; FS="/|\n";} {
-  lt_foo="";
-  lt_count=0;
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+  lt_foo = "";
+  lt_count = 0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo="/" $lt_i lt_foo;
+          lt_foo = "/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -1360,10 +2398,29 @@ BEGIN {RS=" "; FS="/|\n";} {
   if (lt_foo != "") { lt_freq[[lt_foo]]++; }
   if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
 }'`
-  sys_lib_search_path_spec=`echo $lt_search_path_spec`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
   sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
 fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
 need_lib_prefix=unknown
 hardcode_into_libs=no
 
@@ -1371,88 +2428,139 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
 case $host_os in
 aix3*)
-  version_type=linux
-  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='${libname}${release}${shared_ext}$major'
+  soname_spec='$libname$release$shared_ext$major'
   ;;
 
 aix[[4-9]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test "$host_cpu" = ia64; then
+  if test ia64 = "$host_cpu"; then
     # AIX 5 supports IA64
-    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line `#! .'.  This would cause the generated library to
-    # depend on `.', always an invalid library.  This was fixed in
+    # the line '#! .'.  This would cause the generated library to
+    # depend on '.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[[01]] | aix4.[[01]].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # Using Import Files as archive members, it is possible to support
+    # filename-based versioning of shared library archives on AIX. While
+    # this would work for both with and without runtime linking, it will
+    # prevent static linking of such archives. So we do filename-based
+    # shared library versioning with .so extension only, which is used
+    # when both runtime linking and shared linking is enabled.
+    # Unfortunately, runtime linking may impact performance, so we do
+    # not want this to be the default eventually. Also, we use the
+    # versioned .so libs for executables only if there is the -brtl
+    # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only.
+    # To allow for filename-based versioning support, we need to create
+    # libNAME.so.V as an archive file, containing:
+    # *) an Import File, referring to the versioned filename of the
+    #    archive as well as the shared archive member, telling the
+    #    bitwidth (32 or 64) of that shared object, and providing the
+    #    list of exported symbols of that shared object, eventually
+    #    decorated with the 'weak' keyword
+    # *) the shared object with the F_LOADONLY flag set, to really avoid
+    #    it being seen by the linker.
+    # At run time we better use the real file rather than another symlink,
+    # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+    case $with_aix_soname,$aix_use_runtimelinking in
+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    if test "$aix_use_runtimelinking" = yes; then
+    aix,yes) # traditional libtool
+      dynamic_linker='AIX unversionable lib.so'
       # If using run time linking (on AIX 4.2 or later) use lib.so
       # instead of lib.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-    else
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      ;;
+    aix,no) # traditional AIX only
+      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='${libname}${release}.a $libname.a'
-      soname_spec='${libname}${release}${shared_ext}$major'
-    fi
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      ;;
+    svr4,*) # full svr4 only
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,yes) # both, prefer svr4
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+      # unpreferred sharedlib libNAME.a needs extra handling
+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *,no) # both, prefer aix
+      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+      ;;
+    esac
     shlibpath_var=LIBPATH
   fi
   ;;
 
 amigaos*)
-  library_names_spec='$libname.ixlibrary $libname.a'
-  # Create ${libname}_ixlibrary.a entries in /sys/libs.
-  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
   ;;
 
 beos*)
-  library_names_spec='${libname}${shared_ext}'
+  library_names_spec='$libname$shared_ext'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
 
-haiku*)
-  # Since haiku provides gcc, use GNU style here
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LIBRARY_PATH
-  hardcode_into_libs=yes
-  ;;
-
 bsdi[[45]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -1462,61 +2570,126 @@ bsdi[[45]]*)
   # libtool to hard-code these into programs
   ;;
 
-cygwin* | mingw* | pw32*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=".dll"
+  shrext_cmds=.dll
   need_version=no
   need_lib_prefix=no
 
-  case $GCC,$host_os in
-  yes,cygwin* | yes,mingw* | yes,pw32*)
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \${file}`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
-      dldir=$destdir/`dirname \$dlpath`~
-      test -d \$dldir || mkdir -p \$dldir~
-      $install_prog $dir/$dlname \$dldir/$dlname~
-      chmod a+x \$dldir/$dlname'
+    # If user builds GCC with multilib enabled,
+    # it should just install on $(libdir)
+    # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones.
+    if test xyes = x"$multilib"; then
+      postinstall_cmds='base_file=`basename \$file`~
+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+        dldir=$destdir/`dirname \$dlpath`~
+        $install_prog $dir/$dlname $destdir/$dlname~
+        chmod a+x $destdir/$dlname~
+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+          eval '\''$striplib $destdir/$dlname'\'' || exit \$?;
+        fi'
+    else
+      postinstall_cmds='base_file=`basename \$file`~
+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+        dldir=$destdir/`dirname \$dlpath`~
+        test -d \$dldir || mkdir -p \$dldir~
+        $install_prog $dir/$dlname \$dldir/$dlname~
+        chmod a+x \$dldir/$dlname~
+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+          eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+        fi'
+    fi
     postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
       dlpath=$dir/\$dldll~
-       $rm \$dlpath'
+       $RM \$dlpath'
     shlibpath_overrides_runpath=yes
 
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
-      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
-    mingw*)
+    mingw* | windows* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
-      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-      if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
-        # It is most probably a Windows format PATH printed by
-        # mingw gcc, but we are running on Cygwin. Gcc prints its search
-        # path with ; separators, and with drive letters. We can handle the
-        # drive letters (cygwin fileutils understands them), so leave them,
-        # especially as we might pass files found there to a mingw objdump,
-        # which wouldn't understand a cygwinified path. Ahh.
-        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
-      else
-        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-      fi
+      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
       ;;
     esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl* | *,icl*)
+    # Native MSVC or ICC
+    libname_spec='$name'
+    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+    library_names_spec='$libname.dll.lib'
+
+    case $build_os in
+    mingw* | windows*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec=$LIB
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \$file`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
     ;;
 
   *)
-    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    # Assume MSVC and ICC wrapper
+    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+    dynamic_linker='Win32 ld.exe'
     ;;
   esac
-  dynamic_linker='Win32 ld.exe'
   # FIXME: first we should search . and the directory the executable is in
   shlibpath_var=PATH
   ;;
@@ -1526,51 +2699,66 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
-  soname_spec='${libname}${release}${major}$shared_ext'
+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$major$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
-  ifelse([$1], [],[
+m4_if([$1], [],[
   sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
   sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
   ;;
 
 dgux*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
-  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
-freebsd* | dragonfly*)
+freebsd* | dragonfly* | midnightbsd*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
   if test -x /usr/bin/objformat; then
     objformat=`/usr/bin/objformat`
   else
     case $host_os in
-    freebsd[[123]].*) objformat=aout ;;
+    freebsd[[23]].*) objformat=aout ;;
     *) objformat=elf ;;
     esac
   fi
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+      soname_spec='$libname$release$shared_ext$major'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
       need_version=yes
       ;;
   esac
-  shlibpath_var=LD_LIBRARY_PATH
+  case $host_cpu in
+    powerpc64)
+      # On FreeBSD bi-arch platforms, a different variable is used for 32-bit
+      # binaries.  See .
+      AC_COMPILE_IFELSE(
+        [AC_LANG_SOURCE(
+           [[int test_pointer_size[sizeof (void *) - 5];
+           ]])],
+        [shlibpath_var=LD_LIBRARY_PATH],
+        [shlibpath_var=LD_32_LIBRARY_PATH])
+      ;;
+    *)
+      shlibpath_var=LD_LIBRARY_PATH
+      ;;
+  esac
   case $host_os in
-  freebsd2*)
+  freebsd2.*)
     shlibpath_overrides_runpath=yes
     ;;
   freebsd3.[[01]]* | freebsdelf3.[[01]]*)
@@ -1589,14 +2777,18 @@ freebsd* | dragonfly*)
   esac
   ;;
 
-gnu*)
-  version_type=linux
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  hardcode_into_libs=yes
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib'
+  sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib'
+  hardcode_into_libs=no
   ;;
 
 hpux9* | hpux10* | hpux11*)
@@ -1612,45 +2804,48 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-    soname_spec='${libname}${release}${shared_ext}$major'
-    if test "X$HPUX_IA64_MODE" = X32; then
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    if test 32 = "$HPUX_IA64_MODE"; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
-   hppa*64*)
-     shrext_cmds='.sl'
-     hardcode_into_libs=yes
-     dynamic_linker="$host_os dld.sl"
-     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
-     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-     soname_spec='${libname}${release}${shared_ext}$major'
-     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
-     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-     ;;
-   *)
+  *)
     shrext_cmds='.sl'
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-    soname_spec='${libname}${release}${shared_ext}$major'
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
     ;;
   esac
-  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
   postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
   ;;
 
 interix[[3-9]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -1661,16 +2856,16 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test "$lt_cv_prog_gnu_ld" = yes; then
-		version_type=linux
+	if test yes = "$lt_cv_prog_gnu_ld"; then
+		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
 	fi ;;
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='${libname}${release}${shared_ext}$major'
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -1689,8 +2884,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
-  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
   hardcode_into_libs=yes
   ;;
 
@@ -1699,24 +2894,66 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
-  version_type=linux
+linux*android*)
+  version_type=none # Android doesn't support versioned libraries.
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  dynamic_linker='Android linker'
+  # -rpath works at least for libraries that are not overridden by
+  # libraries installed in system locations.
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
   # This implies no fast_install, which is unacceptable.
   # Some rework will be needed to allow for fast_install
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Append ld.so.conf contents to the search path
+  # Ideally, we could use ldconfig to report *all* directories which are
+  # searched for libraries, however this is still not possible.  Aside from not
+  # being certain /sbin/ldconfig is available, command
+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+  # even though it is searched at run-time.  Try to do the best guess by
+  # appending ld.so.conf contents (and includes) to the search path.
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ 	]*hwcap[ 	]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -1729,17 +2966,29 @@ linux* | k*bsd*-gnu)
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
   need_version=no
-  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
-    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-    soname_spec='${libname}${release}${shared_ext}$major'
+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    soname_spec='$libname$release$shared_ext$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -1747,79 +2996,114 @@ netbsd*)
   hardcode_into_libs=yes
   ;;
 
+*-mlibc)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  dynamic_linker='mlibc ld.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
 newsos6)
-  version_type=linux
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
 
-nto-qnx*)
-  version_type=linux
+*nto* | *qnx*)
+  version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
   ;;
 
 openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec="/usr/lib"
+  sys_lib_dlsearch_path_spec=/usr/lib
   need_lib_prefix=no
-  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
-  case $host_os in
-    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
-    *)                         need_version=no  ;;
-  esac
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
-  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
-  shlibpath_var=LD_LIBRARY_PATH
-  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-    case $host_os in
-      openbsd2.[[89]] | openbsd2.[[89]].*)
-	shlibpath_overrides_runpath=no
-	;;
-      *)
-	shlibpath_overrides_runpath=yes
-	;;
-      esac
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+    need_version=no
   else
-    shlibpath_overrides_runpath=yes
+    need_version=yes
   fi
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
   ;;
 
 os2*)
   libname_spec='$name'
-  shrext_cmds=".dll"
+  version_type=windows
+  shrext_cmds=.dll
+  need_version=no
   need_lib_prefix=no
-  library_names_spec='$libname${shared_ext} $libname.a'
+  # OS/2 can only load a DLL with a base name of 8 characters or less.
+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+    v=$($ECHO $release$versuffix | tr -d .-);
+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+    $ECHO $n$v`$shared_ext'
+  library_names_spec='${libname}_dll.$libext'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=LIBPATH
+  shlibpath_var=BEGINLIBPATH
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  postinstall_cmds='base_file=`basename \$file`~
+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+    dldir=$destdir/`dirname \$dlpath`~
+    test -d \$dldir || mkdir -p \$dldir~
+    $install_prog $dir/$dlname \$dldir/$dlname~
+    chmod a+x \$dldir/$dlname~
+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+    fi'
+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+    dlpath=$dir/\$dldll~
+    $RM \$dlpath'
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='${libname}${release}${shared_ext}$major'
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
   ;;
 
 rdos*)
   dynamic_linker=no
   ;;
 
+serenity*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  dynamic_linker='SerenityOS LibELF'
+  ;;
+
 solaris*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -1829,26 +3113,25 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test "$with_gnu_ld" = yes; then
+  if test yes = "$with_gnu_ld"; then
     need_lib_prefix=no
   fi
   need_version=yes
   ;;
 
 sysv4 | sysv4.3*)
-  version_type=linux
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
       shlibpath_overrides_runpath=no
       need_lib_prefix=no
-      export_dynamic_flag_spec='${wl}-Blargedynsym'
       runpath_var=LD_RUN_PATH
       ;;
     siemens)
@@ -1864,343 +3147,170 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec ;then
-    version_type=linux
-    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
-    soname_spec='$libname${shared_ext}.$major'
+  if test -d /usr/nec; then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+    soname_spec='$libname$shared_ext.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
-  ;;
-
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=freebsd-elf
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  hardcode_into_libs=yes
-  if test "$with_gnu_ld" = yes; then
-    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
-    shlibpath_overrides_runpath=no
-  else
-    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
-    shlibpath_overrides_runpath=yes
-    case $host_os in
-      sco3.2v5*)
-        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
-	;;
-    esac
-  fi
-  sys_lib_dlsearch_path_spec='/usr/lib'
-  ;;
-
-uts4*)
-  version_type=linux
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  ;;
-
-*)
-  dynamic_linker=no
-  ;;
-esac
-AC_MSG_RESULT([$dynamic_linker])
-test "$dynamic_linker" = no && can_build_shared=no
-
-AC_CACHE_VAL([lt_cv_sys_lib_search_path_spec],
-[lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"])
-sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
-AC_CACHE_VAL([lt_cv_sys_lib_dlsearch_path_spec],
-[lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"])
-sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
-
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
-  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
-
-
-# _LT_AC_TAGCONFIG
-# ----------------
-AC_DEFUN([_LT_AC_TAGCONFIG],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_ARG_WITH([tags],
-[  --with-tags[=TAGS]        Include additional configurations [automatic]
-],
-[tagnames="$withval"])
-
-if test -f "$ltmain" && test -n "$tagnames"; then
-  if test ! -f "${ofile}"; then
-    AC_MSG_WARN([output file '$ofile' does not exist])
-  fi
-
-  if test -z "$LTCC"; then
-    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
-    if test -z "$LTCC"; then
-      AC_MSG_WARN([output file '$ofile' does not look like a libtool script])
-    else
-      AC_MSG_WARN([using 'LTCC=$LTCC', extracted from '$ofile'])
-    fi
-  fi
-  if test -z "$LTCFLAGS"; then
-    eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
-  fi
-
-  # Extract list of available tagged configurations in $ofile.
-  # Note that this assumes the entire list is on one line.
-  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
-
-  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
-  for tagname in $tagnames; do
-    IFS="$lt_save_ifs"
-    # Check whether tagname contains only valid characters
-    case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
-    "") ;;
-    *)  AC_MSG_ERROR([invalid tag name: $tagname])
-	;;
-    esac
-
-    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
-    then
-      AC_MSG_ERROR([tag name "$tagname" already exists])
-    fi
-
-    # Update the list of available tags.
-    if test -n "$tagname"; then
-      echo appending configuration tag \"$tagname\" to $ofile
-
-      case $tagname in
-      CXX)
-	if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
-	    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
-	    (test "X$CXX" != "Xg++"))) ; then
-	  AC_LIBTOOL_LANG_CXX_CONFIG
-	else
-	  tagname=""
-	fi
-	;;
-
-      *)
-	AC_MSG_ERROR([Unsupported tag name: $tagname])
-	;;
-      esac
-
-      # Append the new tag name to the list of available tags.
-      if test -n "$tagname" ; then
-      available_tags="$available_tags $tagname"
-    fi
-    fi
-  done
-  IFS="$lt_save_ifs"
-
-  # Now substitute the updated list of available tags.
-  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
-    mv "${ofile}T" "$ofile"
-    chmod +x "$ofile"
-  else
-    rm -f "${ofile}T"
-    AC_MSG_ERROR([unable to update list of available tagged configurations.])
-  fi
-fi
-])# _LT_AC_TAGCONFIG
-
-
-# AC_LIBTOOL_DLOPEN
-# -----------------
-# enable checks for dlopen support
-AC_DEFUN([AC_LIBTOOL_DLOPEN],
- [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
-])# AC_LIBTOOL_DLOPEN
-
-
-# AC_LIBTOOL_WIN32_DLL
-# --------------------
-# declare package support for building win32 DLLs
-AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
-[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
-])# AC_LIBTOOL_WIN32_DLL
-
-
-# AC_ENABLE_SHARED([DEFAULT])
-# ---------------------------
-# implement the --enable-shared flag
-# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
-AC_DEFUN([AC_ENABLE_SHARED],
-[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE([shared],
-changequote(<<, >>)dnl
-<<  --enable-shared[=PKGS]    Build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
-changequote([, ])dnl
-    [p=${PACKAGE-default}
-    case $enableval in
-    yes) enable_shared=yes ;;
-    no) enable_shared=no ;;
-    *)
-      enable_shared=no
-      # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
-      for pkg in $enableval; do
-	IFS="$lt_save_ifs"
-	if test "X$pkg" = "X$p"; then
-	  enable_shared=yes
-	fi
-      done
-      IFS="$lt_save_ifs"
-      ;;
-    esac],
-    [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
-])# AC_ENABLE_SHARED
-
-
-# AC_DISABLE_SHARED
-# -----------------
-# set the default shared flag to --disable-shared
-AC_DEFUN([AC_DISABLE_SHARED],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-AC_ENABLE_SHARED(no)
-])# AC_DISABLE_SHARED
-
-
-# AC_ENABLE_STATIC([DEFAULT])
-# ---------------------------
-# implement the --enable-static flag
-# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
-AC_DEFUN([AC_ENABLE_STATIC],
-[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE([static],
-changequote(<<, >>)dnl
-<<  --enable-static[=PKGS]    Build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
-changequote([, ])dnl
-    [p=${PACKAGE-default}
-    case $enableval in
-    yes) enable_static=yes ;;
-    no) enable_static=no ;;
-    *)
-     enable_static=no
-      # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
-      for pkg in $enableval; do
-	IFS="$lt_save_ifs"
-	if test "X$pkg" = "X$p"; then
-	  enable_static=yes
-	fi
-      done
-      IFS="$lt_save_ifs"
-      ;;
-    esac],
-    [enable_static=]AC_ENABLE_STATIC_DEFAULT)
-])# AC_ENABLE_STATIC
-
+  ;;
 
-# AC_DISABLE_STATIC
-# -----------------
-# set the default static flag to --disable-static
-AC_DEFUN([AC_DISABLE_STATIC],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-AC_ENABLE_STATIC(no)
-])# AC_DISABLE_STATIC
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=sco
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test yes = "$with_gnu_ld"; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
 
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
 
-# AC_ENABLE_FAST_INSTALL([DEFAULT])
-# ---------------------------------
-# implement the --enable-fast-install flag
-# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
-AC_DEFUN([AC_ENABLE_FAST_INSTALL],
-[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
-AC_ARG_ENABLE([fast-install],
-changequote(<<, >>)dnl
-<<  --enable-fast-install[=PKGS]
-                          Optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
-changequote([, ])dnl
-    [p=${PACKAGE-default}
-    case $enableval in
-    yes) enable_fast_install=yes ;;
-    no) enable_fast_install=no ;;
-    *)
-      enable_fast_install=no
-      # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
-      for pkg in $enableval; do
-	IFS="$lt_save_ifs"
-	if test "X$pkg" = "X$p"; then
-	  enable_fast_install=yes
-	fi
-      done
-      IFS="$lt_save_ifs"
-      ;;
-    esac],
-    [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
-])# AC_ENABLE_FAST_INSTALL
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='$libname$release$shared_ext$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
 
+emscripten*)
+  version_type=none
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  dynamic_linker="Emscripten linker"
+  _LT_COMPILER_PIC($1)='-fPIC'
+  _LT_TAGVAR(archive_cmds, $1)='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib'
+  _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym'
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(no_undefined_flag, $1)=
+  ;;
 
-# AC_DISABLE_FAST_INSTALL
-# -----------------------
-# set the default to --disable-fast-install
-AC_DEFUN([AC_DISABLE_FAST_INSTALL],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-AC_ENABLE_FAST_INSTALL(no)
-])# AC_DISABLE_FAST_INSTALL
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
 
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
 
-# AC_LIBTOOL_PICMODE([MODE])
-# --------------------------
-# implement the --with-pic flag
-# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
-AC_DEFUN([AC_LIBTOOL_PICMODE],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-pic_mode=ifelse($#,1,$1,default)
-])# AC_LIBTOOL_PICMODE
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
 
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
 
-# AC_PROG_EGREP
-# -------------
-ifdef([AC_PROG_EGREP], [], [AC_DEFUN([AC_PROG_EGREP],
-[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
-   [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
-    then ac_cv_prog_egrep='grep -E'
-    else ac_cv_prog_egrep='egrep'
-    fi])
- EGREP=$ac_cv_prog_egrep
- AC_SUBST([EGREP])
-])])
-
-
-# AC_PATH_TOOL_PREFIX
-# -------------------
-# find a file program which can recognize shared library
-AC_DEFUN([AC_PATH_TOOL_PREFIX],
-[AC_REQUIRE([AC_PROG_EGREP])dnl
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+    [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
 AC_MSG_CHECKING([for $1])
 AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
 [case $MAGIC_CMD in
 [[\\/*] |  ?:[\\/]*])
-  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD="$MAGIC_CMD"
-  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD=$MAGIC_CMD
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
 dnl $ac_dummy forces splitting on constant user-supplied paths.
 dnl POSIX.2 word splitting is done only on the output of word expansions,
 dnl not every word.  This closes a longstanding sh security hole.
-  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
   for ac_dir in $ac_dummy; do
-    IFS="$lt_save_ifs"
+    IFS=$lt_save_ifs
     test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$1; then
-      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+    if test -f "$ac_dir/$1"; then
+      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
 	  else
-	    cat <&2
+	    cat <<_LT_EOF 1>&2
 
 *** Warning: the command libtool uses to detect shared libraries,
 *** $file_magic_cmd, produces output that libtool cannot recognize.
@@ -2211,60 +3321,72 @@ dnl not every word.  This closes a longstanding sh security hole.
 *** may want to report the problem to your system manager and/or to
 *** bug-libtool@gnu.org
 
-EOF
+_LT_EOF
 	  fi ;;
 	esac
       fi
       break
     fi
   done
-  IFS="$lt_save_ifs"
-  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  IFS=$lt_save_ifs
+  MAGIC_CMD=$lt_save_MAGIC_CMD
   ;;
 esac])
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
 if test -n "$MAGIC_CMD"; then
   AC_MSG_RESULT($MAGIC_CMD)
 else
   AC_MSG_RESULT(no)
 fi
-])# AC_PATH_TOOL_PREFIX
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
 
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
 
-# AC_PATH_MAGIC
-# -------------
-# find a file program which can recognize a shared library
-AC_DEFUN([AC_PATH_MAGIC],
-[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
 if test -z "$lt_cv_path_MAGIC_CMD"; then
   if test -n "$ac_tool_prefix"; then
-    AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
   else
     MAGIC_CMD=:
   fi
 fi
-])# AC_PATH_MAGIC
+])# _LT_PATH_MAGIC
 
 
-# AC_PROG_LD
+# LT_PATH_LD
 # ----------
 # find the pathname to the GNU or non-GNU linker
-AC_DEFUN([AC_PROG_LD],
-[AC_ARG_WITH([gnu-ld],
-[  --with-gnu-ld           Assume the C compiler uses GNU ld [default=no]],
-    [test "$withval" = no || with_gnu_ld=yes],
-    [with_gnu_ld=no])
-AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_REQUIRE([AC_PROG_CC])dnl
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
 AC_REQUIRE([AC_CANONICAL_HOST])dnl
 AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test no = "$withval" || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
 ac_prog=ld
-if test "$GCC" = yes; then
+if test yes = "$GCC"; then
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by $CC])
   case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
+  *-*-mingw* | *-*-windows*)
+    # gcc leaves a trailing carriage return, which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -2274,11 +3396,11 @@ if test "$GCC" = yes; then
     [[\\/]]* | ?:[[\\/]]*)
       re_direlt='/[[^/]][[^/]]*/\.\./'
       # Canonicalize the pathname of ld
-      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
-      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
-	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD="$ac_prog"
+      test -z "$LD" && LD=$ac_prog
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -2289,52 +3411,61 @@ if test "$GCC" = yes; then
     with_gnu_ld=unknown
     ;;
   esac
-elif test "$with_gnu_ld" = yes; then
+elif test yes = "$with_gnu_ld"; then
   AC_MSG_CHECKING([for GNU ld])
 else
   AC_MSG_CHECKING([for non-GNU ld])
 fi
 AC_CACHE_VAL(lt_cv_path_LD,
 [if test -z "$LD"; then
-  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS="$lt_save_ifs"
+    IFS=$lt_save_ifs
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD="$ac_dir/$ac_prog"
+      lt_cv_path_LD=$ac_dir/$ac_prog
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 &1 &1 conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+  [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
 # how to check for library dependencies
 #  -- PORTME fill in with the dynamic library characteristics
-AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
-[AC_CACHE_CHECK([how to recognize dependent libraries],
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
 lt_cv_deplibs_check_method,
 [lt_cv_file_magic_cmd='$MAGIC_CMD'
 lt_cv_file_magic_test_file=
@@ -2387,26 +3564,25 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
+# 'unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[[4-9]]*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-beos* | haiku*)
+beos*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
 bsdi[[45]]*)
   lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
-  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_cmd='$FILECMD -L'
   lt_cv_file_magic_test_file=/shlib/libc.so
   ;;
 
@@ -2416,7 +3592,7 @@ cygwin*)
   lt_cv_file_magic_cmd='func_win32_libid'
   ;;
 
-mingw* | pw32*)
+mingw* | windows* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
@@ -2424,23 +3600,30 @@ mingw* | pw32*)
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)'
     lt_cv_file_magic_cmd='$OBJDUMP -f'
   fi
   ;;
 
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
 darwin* | rhapsody*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-freebsd* | dragonfly*)
-  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+freebsd* | dragonfly* | midnightbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     case $host_cpu in
     i*86 )
       # Not sure whether the presence of OpenBSD here was a mistake.
       # Let's accept both of them until this is cleared up.
       lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
-      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_cmd=$FILECMD
       lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
       ;;
     esac
@@ -2449,23 +3632,23 @@ freebsd* | dragonfly*)
   fi
   ;;
 
-gnu*)
+haiku*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
 hpux10.20* | hpux11*)
-  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_cmd=$FILECMD
   case $host_cpu in
   ia64*)
     lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
     lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
     ;;
   hppa*64*)
-    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
     lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
     ;;
   *)
-    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
     lt_cv_file_magic_test_file=/usr/lib/libc.sl
     ;;
   esac
@@ -2486,13 +3669,17 @@ irix5* | irix6* | nonstopux*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd*)
-  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+*-mlibc)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
@@ -2501,16 +3688,16 @@ netbsd*)
 
 newos6*)
   lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
-  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_cmd=$FILECMD
   lt_cv_file_magic_test_file=/usr/lib/libnls.so
   ;;
 
-nto-qnx*)
-  lt_cv_deplibs_check_method=unknown
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
   ;;
 
 openbsd*)
-  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
@@ -2525,10 +3712,18 @@ rdos*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
+serenity*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
 solaris*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
 sysv4 | sysv4.3*)
   case $host_vendor in
   motorola)
@@ -2556,51 +3751,84 @@ sysv4 | sysv4.3*)
   esac
   ;;
 
-sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+os2*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 esac
 ])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | windows* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
 file_magic_cmd=$lt_cv_file_magic_cmd
 deplibs_check_method=$lt_cv_deplibs_check_method
 test -z "$deplibs_check_method" && deplibs_check_method=unknown
-])# AC_DEPLIBS_CHECK_METHOD
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
 
 
-# AC_PROG_NM
+# LT_PATH_NM
 # ----------
-# find the pathname to a BSD-compatible name lister
-AC_DEFUN([AC_PROG_NM],
-[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
 [if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM="$NM"
+  lt_cv_path_NM=$NM
 else
-  lt_nm_to_check="${ac_tool_prefix}nm"
+  lt_nm_to_check=${ac_tool_prefix}nm
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS="$lt_save_ifs"
+      IFS=$lt_save_ifs
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm="$ac_dir/$lt_tmp_nm"
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+      tmp_nm=$ac_dir/$lt_tmp_nm
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
-	*/dev/null* | *'Invalid file or object type'*)
+	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+	case $build_os in
+	mingw* | windows*) lt_bad_file=conftest.nm/nofile ;;
+	*) lt_bad_file=/dev/null ;;
+	esac
+	case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in
+	*$lt_bad_file* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break
+	  break 2
 	  ;;
 	*)
-	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break
+	    break 2
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -2611,3760 +3839,4650 @@ else
 	esac
       fi
     done
-    IFS="$lt_save_ifs"
+    IFS=$lt_save_ifs
   done
-  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+  : ${lt_cv_path_NM=no}
 fi])
-NM="$lt_cv_path_NM"
-])# AC_PROG_NM
+if test no != "$lt_cv_path_NM"; then
+  NM=$lt_cv_path_NM
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols -headers"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  AC_SUBST([DUMPBIN])
+  if test : != "$DUMPBIN"; then
+    NM=$DUMPBIN
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | windows* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh;
+  # decide which one to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
 
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
 
-# AC_CHECK_LIBM
-# -------------
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_manifest_tool],
+  [lt_cv_path_manifest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_manifest_tool=yes
+  fi
+  rm -f conftest*])
+if test yes != "$lt_cv_path_manifest_tool"; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+  test DEF = "`$SED -n dnl
+    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace
+    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments
+    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl
+    -e q dnl                          Only consider the first "real" line
+    $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
 # check for math library
-AC_DEFUN([AC_CHECK_LIBM],
+AC_DEFUN([LT_LIB_M],
 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
 LIBM=
 case $host in
-*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin* | *-*-haiku*)
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*)
   # These system don't have libm, or don't need it
   ;;
 *-ncr-sysv4.3*)
-  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
   AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
   ;;
 *)
-  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  AC_CHECK_LIB(m, cos, LIBM=-lm)
   ;;
 esac
-])# AC_CHECK_LIBM
-
-
-# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
-# -----------------------------------
-# sets LIBLTDL to the link flags for the libltdl convenience library and
-# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-convenience to the configure arguments.  Note that
-# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
-# it is assumed to be `libltdl'.  LIBLTDL will be prefixed with
-# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
-# (note the single quotes!).  If your package is not flat and you're not
-# using automake, define top_builddir and top_srcdir appropriately in
-# the Makefiles.
-AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-  case $enable_ltdl_convenience in
-  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
-  "") enable_ltdl_convenience=yes
-      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
-  esac
-  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
-  LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
-  # For backwards non-gettext consistent compatibility...
-  INCLTDL="$LTDLINCL"
-])# AC_LIBLTDL_CONVENIENCE
+AC_SUBST([LIBM])
+])# LT_LIB_M
 
-
-# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
-# -----------------------------------
-# sets LIBLTDL to the link flags for the libltdl installable library and
-# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-install to the configure arguments.  Note that
-# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
-# and an installed libltdl is not found, it is assumed to be `libltdl'.
-# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
-# '${top_srcdir}/' (note the single quotes!).  If your package is not
-# flat and you're not using automake, define top_builddir and top_srcdir
-# appropriately in the Makefiles.
-# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
-AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
-[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
-  AC_CHECK_LIB(ltdl, lt_dlinit,
-  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
-  [if test x"$enable_ltdl_install" = xno; then
-     AC_MSG_WARN([libltdl not installed, but installation disabled])
-   else
-     enable_ltdl_install=yes
-   fi
-  ])
-  if test x"$enable_ltdl_install" = x"yes"; then
-    ac_configure_args="$ac_configure_args --enable-ltdl-install"
-    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
-    LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
-  else
-    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
-    LIBLTDL="-lltdl"
-    LTDLINCL=
-  fi
-  # For backwards non-gettext consistent compatibility...
-  INCLTDL="$LTDLINCL"
-])# AC_LIBLTDL_INSTALLABLE
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
 
 
-# AC_LIBTOOL_CXX
-# --------------
-# enable support for C++ libraries
-AC_DEFUN([AC_LIBTOOL_CXX],
-[AC_REQUIRE([_LT_AC_LANG_CXX])
-])# AC_LIBTOOL_CXX
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
 
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
 
-# _LT_AC_LANG_CXX
-# ---------------
-AC_DEFUN([_LT_AC_LANG_CXX],
-[AC_REQUIRE([AC_PROG_CXX])
-AC_REQUIRE([_LT_AC_PROG_CXXCPP])
-_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
-])# _LT_AC_LANG_CXX
+if test yes = "$GCC"; then
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
 
-# _LT_AC_PROG_CXXCPP
-# ------------------
-AC_DEFUN([_LT_AC_PROG_CXXCPP],
-[
-AC_REQUIRE([AC_PROG_CXX])
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
-    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
-    (test "X$CXX" != "Xg++"))) ; then
-  AC_PROG_CXXCPP
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
 fi
-])# _LT_AC_PROG_CXXCPP
-
-# AC_LIBTOOL_LANG_C_CONFIG
-# ------------------------
-# Ensure that the configuration vars for the C compiler are
-# suitably defined.  Those variables are subsequently used by
-# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
-AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
-AC_DEFUN([_LT_AC_LANG_C_CONFIG],
-[lt_save_CC="$CC"
-AC_LANG_PUSH([C])
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
 
-# Source file extension for C test sources.
-ac_ext=c
-
-# Object file extension for compiled C test sources.
-objext=o
-_LT_AC_TAGVAR(objext, $1)=$objext
 
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
 
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(void){return(0);}'
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
 
-_LT_AC_SYS_COMPILER
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
 
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
 
-## CAVEAT EMPTOR:
-## There is no encapsulation within the following macros, do not change
-## the running order or otherwise move them around unless you know exactly
-## what you are doing...
-AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
-AC_LIBTOOL_PROG_COMPILER_PIC($1)
-AC_LIBTOOL_PROG_CC_C_O($1)
-AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
-AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
-AC_LIBTOOL_DLOPEN_SELF
-
-# Report which library types will actually be built
-AC_MSG_CHECKING([if libtool supports shared libraries])
-AC_MSG_RESULT([$can_build_shared])
-
-AC_MSG_CHECKING([whether to build shared libraries])
-test "$can_build_shared" = "no" && enable_shared=no
-
-# On AIX, shared libraries and static libraries use the same namespace, and
-# are all built from PIC.
+# Define system-specific variables.
 case $host_os in
-aix3*)
-  test "$enable_shared" = yes && enable_static=no
-  if test -n "$RANLIB"; then
-    archive_cmds="$archive_cmds~\$RANLIB \$lib"
-    postinstall_cmds='$RANLIB $lib'
-  fi
+aix*)
+  symcode='[[BCDT]]'
   ;;
-
-aix[[4-9]]*)
-  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
-    test "$enable_shared" = yes && enable_static=no
+cygwin* | mingw* | windows* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test ia64 = "$host_cpu"; then
+    symcode='[[ABCDEGRST]]'
   fi
-    ;;
-esac
-AC_MSG_RESULT([$enable_shared])
-
-AC_MSG_CHECKING([whether to build static libraries])
-# Make sure either enable_shared or enable_static is yes.
-test "$enable_shared" = yes || enable_static=yes
-AC_MSG_RESULT([$enable_static])
-
-AC_LIBTOOL_CONFIG($1)
-
-AC_LANG_POP([C])
-CC="$lt_save_CC"
-])# AC_LIBTOOL_LANG_C_CONFIG
-
-
-# AC_LIBTOOL_LANG_CXX_CONFIG
-# --------------------------
-# Ensure that the configuration vars for the C compiler are
-# suitably defined.  Those variables are subsequently used by
-# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
-AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
-AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
-[AC_LANG_PUSH([C++])
-AC_REQUIRE([AC_PROG_CXX])
-AC_REQUIRE([_LT_AC_PROG_CXXCPP])
-
-_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-_LT_AC_TAGVAR(allow_undefined_flag, $1)=
-_LT_AC_TAGVAR(always_export_symbols, $1)=no
-_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
-_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
-_LT_AC_TAGVAR(hardcode_direct, $1)=no
-_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
-_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
-_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-_LT_AC_TAGVAR(hardcode_automatic, $1)=no
-_LT_AC_TAGVAR(module_cmds, $1)=
-_LT_AC_TAGVAR(module_expsym_cmds, $1)=
-_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
-_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
-_LT_AC_TAGVAR(no_undefined_flag, $1)=
-_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
-_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-
-# Dependencies to place before and after the object being linked:
-_LT_AC_TAGVAR(predep_objects, $1)=
-_LT_AC_TAGVAR(postdep_objects, $1)=
-_LT_AC_TAGVAR(predeps, $1)=
-_LT_AC_TAGVAR(postdeps, $1)=
-_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
-_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)=
-
-# Source file extension for C++ test sources.
-ac_ext=cpp
-
-# Object file extension for compiled C++ test sources.
-objext=o
-_LT_AC_TAGVAR(objext, $1)=$objext
-
-# Code to be used in simple compile tests
-lt_simple_compile_test_code="int some_variable = 0;"
-
-# Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
-
-# ltmain only uses $CC for tagged configurations so make sure $CC is set.
-_LT_AC_SYS_COMPILER
-
-# save warnings/boilerplate of simple test code
-_LT_COMPILER_BOILERPLATE
-_LT_LINKER_BOILERPLATE
-
-# Allow CC to be a program name with arguments.
-lt_save_CC=$CC
-lt_save_LD=$LD
-lt_save_GCC=$GCC
-GCC=$GXX
-lt_save_with_gnu_ld=$with_gnu_ld
-lt_save_path_LD=$lt_cv_path_LD
-if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
-  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
-else
-  unset lt_cv_prog_gnu_ld
-fi
-if test -n "${lt_cv_path_LDCXX+set}"; then
-  lt_cv_path_LD=$lt_cv_path_LDCXX
-else
-  unset lt_cv_path_LD
-fi
-test -z "${LDCXX+set}" || LD=$LDCXX
-CC=${CXX-"c++"}
-compiler=$CC
-_LT_AC_TAGVAR(compiler, $1)=$CC
-_LT_CC_BASENAME([$compiler])
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BCDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
 
-# We don't want -fno-exception wen compiling C++ code, so set the
-# no_builtin_flag separately
-if test "$GXX" = yes; then
-  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  # Gets list of data symbols to import.
+  lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'"
+  # Adjust the below global symbol transforms to fixup imported variables.
+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
+  lt_c_name_lib_hook="\
+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
 else
-  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+  # Disable hooks by default.
+  lt_cv_sys_global_symbol_to_import=
+  lt_cdecl_hook=
+  lt_c_name_hook=
+  lt_c_name_lib_hook=
 fi
 
-if test "$GXX" = yes; then
-  # Set up default GNU C++ configuration
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="$SED -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
 
-  AC_PROG_LD
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
 
-  # Check if GNU C++ uses GNU ld as the underlying linker, since the
-  # archiving commands below assume that GNU ld is being used.
-  if test "$with_gnu_ld" = yes; then
-    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
-    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw* | windows*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
 
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
-    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
 
-    # If archive_cmds runs LD, not CC, wlarc should be empty
-    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
-    #     investigate it a little bit more. (MM)
-    wlarc='${wl}'
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
 
-    # ancient GNU ld didn't support --whole-archive et. al.
-    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
-	grep 'no-whole-archive' > /dev/null; then
-      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
-    else
-      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
-    fi
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function,
+    # D for any global variable and I for any imported variable.
+    # Also find C++ and __fastcall symbols from MSVC++ or ICC,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
   else
-    with_gnu_ld=no
-    wlarc=
-
-    # A generic and very simple default shared library creation
-    # command for GNU C++ for the case where it uses the native
-    # linker, instead of GNU ld.  If possible, this setting should
-    # overridden to take advantage of the native linker features on
-    # the platform it is being used on.
-    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+    lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
   fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'"
 
-  # Commands to make compiler produce verbose output that lists
-  # what "hidden" libraries, object files and flags are used when
-  # linking a shared library.
-  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
-else
-  GXX=no
-  with_gnu_ld=no
-  wlarc=
-fi
-
-# PORTME: fill in a description of your system's C++ link characteristics
-AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
-_LT_AC_TAGVAR(ld_shlibs, $1)=yes
-case $host_os in
-  aix3*)
-    # FIXME: insert proper C++ library support
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-  aix[[4-9]]*)
-    if test "$host_cpu" = ia64; then
-      # On IA64, the linker does run time linking by default, so we don't
-      # have to do anything special.
-      aix_use_runtimelinking=no
-      exp_sym_flag='-Bexport'
-      no_entry_flag=""
-    else
-      aix_use_runtimelinking=no
-
-      # Test if we are trying to use run time linking or normal
-      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-      # need to do runtime linking.
-      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
-	for ld_flag in $LDFLAGS; do
-	  case $ld_flag in
-	  *-brtl*)
-	    aix_use_runtimelinking=yes
-	    break
-	    ;;
-	  esac
-	done
-	;;
-      esac
-
-      exp_sym_flag='-bexport'
-      no_entry_flag='-bnoentry'
-    fi
+  # Check to see that the pipe works correctly.
+  pipe_works=no
 
-    # When large executables or shared objects are built, AIX ld can
-    # have problems creating the table of contents.  If linking a library
-    # or program results in "error TOC overflow" add -mminimal-toc to
-    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
-    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
-
-    _LT_AC_TAGVAR(archive_cmds, $1)=''
-    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
-    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-
-    if test "$GXX" = yes; then
-      case $host_os in aix4.[[012]]|aix4.[[012]].*)
-      # We only want to do this on AIX 4.2 and lower, the check
-      # below for broken collect2 doesn't work under 4.3+
-	collect2name=`${CC} -print-prog-name=collect2`
-	if test -f "$collect2name" && \
-	   strings "$collect2name" | grep resolve_lib_name >/dev/null
-	then
-	  # We have reworked collect2
-	  :
-	else
-	  # We have old collect2
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
-	  # It fails to find uninstalled libraries when the uninstalled
-	  # path is not listed in the libpath.  Setting hardcode_minus_L
-	  # to unsupported forces relinking
-	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
-	fi
-	;;
-      esac
-      shared_flag='-shared'
-      if test "$aix_use_runtimelinking" = yes; then
-	shared_flag="$shared_flag "'${wl}-G'
-      fi
-    else
-      # not using gcc
-      if test "$host_cpu" = ia64; then
-	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
-	# chokes on -Wl,-G. The following line is correct:
-	shared_flag='-G'
-      else
-	if test "$aix_use_runtimelinking" = yes; then
-	  shared_flag='${wl}-G'
-	else
-	  shared_flag='${wl}-bM:SRE'
-	fi
-      fi
-    fi
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(void){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
 
-    # It seems that -bexpall does not export symbols beginning with
-    # underscore (_), so it is better to generate a list of symbols to export.
-    _LT_AC_TAGVAR(always_export_symbols, $1)=yes
-    if test "$aix_use_runtimelinking" = yes; then
-      # Warning - without using the other runtime loading flags (-brtl),
-      # -berok will link without error, but may produce a broken library.
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
-      # Determine the default libpath from the value encoded in an empty executable.
-      _LT_AC_SYS_LIBPATH_AIX
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
-     else
-      if test "$host_cpu" = ia64; then
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
       else
-	# Determine the default libpath from the value encoded in an empty executable.
-	_LT_AC_SYS_LIBPATH_AIX
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-	# Warning - without using the other run time loading flags,
-	# -berok will link without error, but may produce a broken library.
-	_LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
-	# Exported symbols can be pulled into shared objects from archives
-	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
-	_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-	# This is similar to how AIX traditionally builds its shared libraries.
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	rm -f "$nlist"T
       fi
-    fi
-    ;;
 
-  beos*)
-    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
-      # Joseph Beckenbach  says some releases of gcc
-      # support --undefined.  This deserves some investigation.  FIXME
-      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-    else
-      _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    fi
-    ;;
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
 
-  chorus*)
-    case $cc_basename in
-      *)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-    esac
-    ;;
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-  cygwin* | mingw* | pw32*)
-    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
-    # as there is no search path for DLLs.
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-    _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
-    _LT_AC_TAGVAR(always_export_symbols, $1)=no
-    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-
-    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-      # If the export-symbols file already is a .def file (1st line
-      # is EXPORTS), use it as is; otherwise, prepend...
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
-	cp $export_symbols $output_objdir/$soname.def;
-      else
-	echo EXPORTS > $output_objdir/$soname.def;
-	cat $export_symbols >> $output_objdir/$soname.def;
-      fi~
-      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-    else
-      _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    fi
-  ;;
-      darwin* | rhapsody*)
-      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-      _LT_AC_TAGVAR(hardcode_direct, $1)=no
-      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
-      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
-      if test "$GXX" = yes ; then
-      output_verbose_link_cmd='echo'
-      _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-      _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-      _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
-      if test "$lt_cv_apple_cc_single_mod" != "yes"; then
-        _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
-        _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
-      fi
-      else
-      case $cc_basename in
-        xlc*)
-         output_verbose_link_cmd='echo'
-          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
-          _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
-          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
-          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
-          ;;
-       *)
-         _LT_AC_TAGVAR(ld_shlibs, $1)=no
-          ;;
-      esac
-      fi
-        ;;
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
 
-  dgux*)
-    case $cc_basename in
-      ec++*)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-      ghcx*)
-	# Green Hills C++ Compiler
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-      *)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-    esac
-    ;;
-  freebsd[[12]].*)
-    # C++ shared libraries reported to be fairly broken before switch to ELF
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-  freebsd-elf*)
-    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-    ;;
-  freebsd* | dragonfly*)
-    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
-    # conventions
-    _LT_AC_TAGVAR(ld_shlibs, $1)=yes
-    ;;
-  gnu*)
-    ;;
-  hpux9*)
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-    _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
-				# but as the default
-				# location of the library.
+	  cat <<_LT_EOF >> conftest.$ac_ext
 
-    case $cc_basename in
-    CC*)
-      # FIXME: insert proper C++ library support
-      _LT_AC_TAGVAR(ld_shlibs, $1)=no
-      ;;
-    aCC*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
-      # Commands to make compiler produce verbose output that lists
-      # what "hidden" libraries, object files and flags are used when
-      # linking a shared library.
-      #
-      # There doesn't appear to be a way to prevent this compiler from
-      # explicitly linking system object files so we need to strip them
-      # from the output so that they don't get included in the library
-      # dependencies.
-      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-      ;;
-    *)
-      if test "$GXX" = yes; then
-        _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
-      else
-        # FIXME: insert proper C++ library support
-        _LT_AC_TAGVAR(ld_shlibs, $1)=no
-      fi
-      ;;
-    esac
-    ;;
-  hpux10*|hpux11*)
-    if test $with_gnu_ld = no; then
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+/* The mapping between symbol names and symbols.  */
+LT@&t@_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
 
-      case $host_cpu in
-      hppa*64*|ia64*) ;;
-      *)
-	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-        ;;
-      esac
-    fi
-    case $host_cpu in
-    hppa*64*|ia64*)
-      _LT_AC_TAGVAR(hardcode_direct, $1)=no
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
-    *)
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
-					      # but as the default
-					      # location of the library.
-      ;;
-    esac
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
 
-    case $cc_basename in
-      CC*)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-      aCC*)
-	case $host_cpu in
-	hppa*64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	  ;;
-	ia64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	  ;;
-	*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	  ;;
-	esac
-	# Commands to make compiler produce verbose output that lists
-	# what "hidden" libraries, object files and flags are used when
-	# linking a shared library.
-	#
-	# There doesn't appear to be a way to prevent this compiler from
-	# explicitly linking system object files so we need to strip them
-	# from the output so that they don't get included in the library
-	# dependencies.
-	output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-	;;
-      *)
-	if test "$GXX" = yes; then
-	  if test $with_gnu_ld = no; then
-	    case $host_cpu in
-	    hppa*64*)
-	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      ;;
-	    ia64*)
-	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      ;;
-	    *)
-	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      ;;
-	    esac
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS=conftstm.$ac_objext
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+	    pipe_works=yes
 	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
 	else
-	  # FIXME: insert proper C++ library support
-	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
-	fi
-	;;
-    esac
-    ;;
-  interix[[3-9]]*)
-    _LT_AC_TAGVAR(hardcode_direct, $1)=no
-    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-    # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
-    # Instead, shared libraries are loaded at an image base (0x10000000 by
-    # default) and relocated if they conflict, which is a slow very memory
-    # consuming and fragmenting process.  To avoid this, we pick a random,
-    # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
-    # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-    ;;
-  irix5* | irix6*)
-    case $cc_basename in
-      CC*)
-	# SGI C++
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
-	# Archives containing C++ object files must be created using
-	# "CC -ar", where "CC" is the IRIX C++ compiler.  This is
-	# necessary to make sure instantiated templates are included
-	# in the archive.
-	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
-	;;
-      *)
-	if test "$GXX" = yes; then
-	  if test "$with_gnu_ld" = no; then
-	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-	  else
-	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
-	  fi
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
 	fi
-	_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-	;;
-    esac
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-    ;;
-  linux* | k*bsd*-gnu)
-    case $cc_basename in
-      KCC*)
-	# Kuck and Associates, Inc. (KAI) C++ Compiler
-
-	# KCC will only create a shared library if the output file
-	# ends with ".so" (or ".sl" for HP-UX), so rename the library
-	# to its proper name (with version) after linking.
-	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
-	# Commands to make compiler produce verbose output that lists
-	# what "hidden" libraries, object files and flags are used when
-	# linking a shared library.
-	#
-	# There doesn't appear to be a way to prevent this compiler from
-	# explicitly linking system object files so we need to strip them
-	# from the output so that they don't get included in the library
-	# dependencies.
-	output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
-	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-
-	# Archives containing C++ object files must be created using
-	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
-	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
-	;;
-      icpc*)
-	# Intel C++
-	with_gnu_ld=yes
-	# version 8.0 and above of icpc choke on multiply defined symbols
-	# if we add $predep_objects and $postdep_objects, however 7.1 and
-	# earlier do not add the objects themselves.
-	case `$CC -V 2>&1` in
-	*"Version 7."*)
-  	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
-  	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-	  ;;
-	*)  # Version 8.0 or newer
-	  tmp_idyn=
-	  case $host_cpu in
-	    ia64*) tmp_idyn=' -i_dynamic';;
-	  esac
-  	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-	  ;;
-	esac
-	_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
-	;;
-      pgCC* | pgcpp*)
-        # Portland Group C++ compiler
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
-  	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
-
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
-	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
-        ;;
-      cxx*)
-	# Compaq C++
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
-
-	runpath_var=LD_RUN_PATH
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
-	# Commands to make compiler produce verbose output that lists
-	# what "hidden" libraries, object files and flags are used when
-	# linking a shared library.
-	#
-	# There doesn't appear to be a way to prevent this compiler from
-	# explicitly linking system object files so we need to strip them
-	# from the output so that they don't get included in the library
-	# dependencies.
-	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-	;;
-      *)
-	case `$CC -V 2>&1 | sed 5q` in
-	*Sun\ C*)
-	  # Sun C++ 5.9
-	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
-
-	  # Not sure whether something based on
-	  # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
-	  # would be better.
-	  output_verbose_link_cmd='echo'
-
-	  # Archives containing C++ object files must be created using
-	  # "CC -xar", where "CC" is the Sun C++ compiler.  This is
-	  # necessary to make sure instantiated templates are included
-	  # in the archive.
-	  _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
-	  ;;
-	esac
-	;;
-    esac
-    ;;
-  lynxos*)
-    # FIXME: insert proper C++ library support
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-  m88k*)
-    # FIXME: insert proper C++ library support
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-  mvs*)
-    case $cc_basename in
-      cxx*)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-      *)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-    esac
-    ;;
-  netbsd*)
-    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
-      wlarc=
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-    fi
-    # Workaround some broken pre-1.5 toolchains
-    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
-    ;;
-  openbsd2*)
-    # C++ shared libraries are fairly broken
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-  openbsd*)
-    if test -f /usr/libexec/ld.so; then
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
-	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
       fi
-      output_verbose_link_cmd='echo'
     else
-      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
     fi
-    ;;
-  osf3*)
-    case $cc_basename in
-      KCC*)
-	# Kuck and Associates, Inc. (KAI) C++ Compiler
-
-	# KCC will only create a shared library if the output file
-	# ends with ".so" (or ".sl" for HP-UX), so rename the library
-	# to its proper name (with version) after linking.
-	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
-	# Archives containing C++ object files must be created using
-	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
-	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
 
-	;;
-      RCC*)
-	# Rational C++ 2.4.1
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	;;
-      cxx*)
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
-	# Commands to make compiler produce verbose output that lists
-	# what "hidden" libraries, object files and flags are used when
-	# linking a shared library.
-	#
-	# There doesn't appear to be a way to prevent this compiler from
-	# explicitly linking system object files so we need to strip them
-	# from the output so that they don't get included in the library
-	# dependencies.
-	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
-	;;
-      *)
-	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
-	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+  # Do not use the global_symbol_pipe unless it works.
+  if test yes = "$pipe_works"; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
 
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
 
-	  # Commands to make compiler produce verbose output that lists
-	  # what "hidden" libraries, object files and flags are used when
-	  # linking a shared library.
-	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+    [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+    [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
 
-	else
-	  # FIXME: insert proper C++ library support
-	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
-	fi
-	;;
-    esac
-    ;;
-  osf4* | osf5*)
-    case $cc_basename in
-      KCC*)
-	# Kuck and Associates, Inc. (KAI) C++ Compiler
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test yes = "$GXX"; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
-	# KCC will only create a shared library if the output file
-	# ends with ".so" (or ".sl" for HP-UX), so rename the library
-	# to its proper name (with version) after linking.
-	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
 
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the '-m68020' flag to GCC prevents building anything better,
+            # like '-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
 
-	# Archives containing C++ object files must be created using
-	# the KAI C++ compiler.
-	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
-	;;
-      RCC*)
-	# Rational C++ 2.4.1
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
 	;;
-      cxx*)
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-	  echo "-hidden">> $lib.exp~
-	  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version	$verstring` -update_registry ${output_objdir}/so_locations -o $lib~
-	  $rm $lib.exp'
-
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
-	# Commands to make compiler produce verbose output that lists
-	# what "hidden" libraries, object files and flags are used when
-	# linking a shared library.
-	#
-	# There doesn't appear to be a way to prevent this compiler from
-	# explicitly linking system object files so we need to strip them
-	# from the output so that they don't get included in the library
-	# dependencies.
-	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      esac
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
 	;;
       *)
-	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
-	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-	 _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-
-	  # Commands to make compiler produce verbose output that lists
-	  # what "hidden" libraries, object files and flags are used when
-	  # linking a shared library.
-	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
-
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test ia64 = "$host_cpu"; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	else
-	  # FIXME: insert proper C++ library support
-	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
 	fi
 	;;
-    esac
-    ;;
-  psos*)
-    # FIXME: insert proper C++ library support
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-  sunos4*)
-    case $cc_basename in
-      CC*)
-	# Sun C++ 4.x
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
 	;;
-      lcc*)
-	# Lucid
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
 	;;
-      *)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
 	;;
-    esac
-    ;;
-  solaris*)
-    case $cc_basename in
-      CC*)
-	# Sun C++ 4.2, 5.x and Centerline C++
-        _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
-	_LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-	$CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-	case $host_os in
-	  solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      freebsd* | dragonfly* | midnightbsd*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    if test ia64 != "$host_cpu"; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
 	  *)
-	    # The compiler driver will combine and reorder linker options,
-	    # but understands `-z linker_flag'.
-	    # Supported since Solaris 2.6 (maybe 2.5.1?)
-	    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	    ;;
 	esac
-	_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-
-	output_verbose_link_cmd='echo'
-
-	# Archives containing C++ object files must be created using
-	# "CC -xar", where "CC" is the Sun C++ compiler.  This is
-	# necessary to make sure instantiated templates are included
-	# in the archive.
-	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
 	;;
-      gcx*)
-	# Green Hills C++ Compiler
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-
-	# The C++ compiler must be used to create the archive.
-	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
 	;;
-      *)
-	# GNU C++ compiler with Solaris linker
-	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
-	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
-	  if $CC --version | grep -v '^2\.7' > /dev/null; then
-	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-		$CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
-	    # Commands to make compiler produce verbose output that lists
-	    # what "hidden" libraries, object files and flags are used when
-	    # linking a shared library.
-	    output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
-	  else
-	    # g++ 2.7 appears to require `-G' NOT `-shared' on this
-	    # platform.
-	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
-	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-		$CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
-
-	    # Commands to make compiler produce verbose output that lists
-	    # what "hidden" libraries, object files and flags are used when
-	    # linking a shared library.
-	    output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
-	  fi
-
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
-	  case $host_os in
-	  solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
 	  *)
-	    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	    ;;
-	  esac
-	fi
+	esac
 	;;
-    esac
-    ;;
-  sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
-    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-    runpath_var='LD_RUN_PATH'
-
-    case $cc_basename in
-      CC*)
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | $SED 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
 	;;
-      *)
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      lynxos*)
 	;;
-    esac
-    ;;
-  sysv5* | sco3.2v5* | sco5v6*)
-    # Note: We can NOT use -z defs as we might desire, because we do not
-    # link with -lc, and that would cause any symbols used from libc to
-    # always be unresolved, which means just about no library would
-    # ever link correctly.  If we're not using GNU ld we use -z text
-    # though, which does catch some bad symbols but isn't as heavy-handed
-    # as -z defs.
-    # For security reasons, it is highly recommended that you always
-    # use absolute paths for naming shared libraries, and exclude the
-    # DT_RUNPATH tag from executables and libraries.  But doing so
-    # requires that you compile everything twice, which is a pain.
-    # So that behaviour is only enabled if SCOABSPATH is set to a
-    # non-empty value in the environment.  Most likely only useful for
-    # creating official distributions of packages.
-    # This is a hack until libtool officially supports absolute path
-    # names for shared libraries.
-    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
-    _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
-    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
-    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
-    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
-    runpath_var='LD_RUN_PATH'
-
-    case $cc_basename in
-      CC*)
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      m88k*)
 	;;
-      *)
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
 	;;
-    esac
-    ;;
-  tandem*)
-    case $cc_basename in
-      NCC*)
-	# NonStop-UX NCC 3.20
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      netbsd* | netbsdelf*-gnu)
 	;;
-      *)
-	# FIXME: insert proper C++ library support
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      *-mlibc)
 	;;
-    esac
-    ;;
-  vxworks*)
-    # FIXME: insert proper C++ library support
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-  *)
-    # FIXME: insert proper C++ library support
-    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-    ;;
-esac
-AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
-test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
-_LT_AC_TAGVAR(GCC, $1)="$GXX"
-_LT_AC_TAGVAR(LD, $1)="$LD"
-
-## CAVEAT EMPTOR:
-## There is no encapsulation within the following macros, do not change
-## the running order or otherwise move them around unless you know exactly
-## what you are doing...
-AC_LIBTOOL_POSTDEP_PREDEP($1)
-AC_LIBTOOL_PROG_COMPILER_PIC($1)
-AC_LIBTOOL_PROG_CC_C_O($1)
-AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
-AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-
-AC_LIBTOOL_CONFIG($1)
-
-AC_LANG_POP([C++])
-CC=$lt_save_CC
-LDCXX=$LD
-LD=$lt_save_LD
-GCC=$lt_save_GCC
-with_gnu_ldcxx=$with_gnu_ld
-with_gnu_ld=$lt_save_with_gnu_ld
-lt_cv_path_LDCXX=$lt_cv_path_LD
-lt_cv_path_LD=$lt_save_path_LD
-lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
-lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-])# AC_LIBTOOL_LANG_CXX_CONFIG
-
-# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
-# ------------------------------------
-# Figure out "hidden" library dependencies from verbose
-# compiler output when linking a shared library.
-# Parse the compiler output and extract the necessary
-# objects, libraries and library flags.
-AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-dnl we can't use the lt_simple_compile_test_code here,
-dnl because it contains code intended for an executable,
-dnl not a library.  It's possible we should let each
-dnl tag define a new lt_????_link_test_code variable,
-dnl but it's only used here...
-ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <&1 | sed 5q` in
-  *Sun\ C*)
-    # Sun C++ 5.9
-    #
-    # The more standards-conforming stlport4 library is
-    # incompatible with the Cstd library. Avoid specifying
-    # it if it's in CXXFLAGS. Ignore libCrun as
-    # -library=stlport4 depends on it.
-    case " $CXX $CXXFLAGS " in
-    *" -library=stlport4 "*)
-      solaris_use_stlport4=yes
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
     esac
-    if test "$solaris_use_stlport4" != yes; then
-      _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
-    fi
-    ;;
-  esac
-  ;;
 
-solaris*)
-  case $cc_basename in
-  CC*)
-    # The more standards-conforming stlport4 library is
-    # incompatible with the Cstd library. Avoid specifying
-    # it if it's in CXXFLAGS. Ignore libCrun as
-    # -library=stlport4 depends on it.
-    case " $CXX $CXXFLAGS " in
-    *" -library=stlport4 "*)
-      solaris_use_stlport4=yes
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
       ;;
     esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test ia64 = "$host_cpu"; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
 
-    # Adding this requires a known-good setup of shared libraries for
-    # Sun compiler versions before 5.6, else PIC objects from an old
-    # archive will be linked into the output, leading to subtle bugs.
-    if test "$solaris_use_stlport4" != yes; then
-      _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
-    fi
-    ;;
-  esac
-  ;;
-esac
-])
-case " $_LT_AC_TAGVAR(postdeps, $1) " in
-*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
-esac
-])# AC_LIBTOOL_POSTDEP_PREDEP
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      case $cc_basename in
+      nagfor*)
+        # NAG Fortran compiler
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      esac
+      ;;
 
-# AC_LIBTOOL_CONFIG([TAGNAME])
-# ----------------------------
-# If TAGNAME is not passed, then create an initial libtool script
-# with a default configuration from the untagged config vars.  Otherwise
-# add code to config.status for appending the configuration named by
-# TAGNAME from the matching tagged config vars.
-AC_DEFUN([AC_LIBTOOL_CONFIG],
-[# The else clause should only fire when bootstrapping the
-# libtool distribution, otherwise you forgot to ship ltmain.sh
-# with your package, and you will get complaints that there are
-# no rules to generate ltmain.sh.
-if test -f "$ltmain"; then
-  # See if we are running on zsh, and set the options which allow our commands through
-  # without removal of \ escapes.
-  if test -n "${ZSH_VERSION+set}" ; then
-    setopt NO_GLOB_SUBST
-  fi
-  # Now quote all the things that may contain metacharacters while being
-  # careful not to overquote the AC_SUBSTed values.  We take copies of the
-  # variables and quote the copies for generation of the libtool script.
-  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
-    SED SHELL STRIP \
-    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
-    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
-    deplibs_check_method reload_flag reload_cmds need_locks \
-    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
-    lt_cv_sys_global_symbol_to_c_name_address \
-    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
-    old_postinstall_cmds old_postuninstall_cmds \
-    _LT_AC_TAGVAR(compiler, $1) \
-    _LT_AC_TAGVAR(CC, $1) \
-    _LT_AC_TAGVAR(LD, $1) \
-    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
-    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
-    _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
-    _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
-    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
-    _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
-    _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
-    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
-    _LT_AC_TAGVAR(old_archive_cmds, $1) \
-    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
-    _LT_AC_TAGVAR(predep_objects, $1) \
-    _LT_AC_TAGVAR(postdep_objects, $1) \
-    _LT_AC_TAGVAR(predeps, $1) \
-    _LT_AC_TAGVAR(postdeps, $1) \
-    _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
-    _LT_AC_TAGVAR(compiler_lib_search_dirs, $1) \
-    _LT_AC_TAGVAR(archive_cmds, $1) \
-    _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
-    _LT_AC_TAGVAR(postinstall_cmds, $1) \
-    _LT_AC_TAGVAR(postuninstall_cmds, $1) \
-    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
-    _LT_AC_TAGVAR(allow_undefined_flag, $1) \
-    _LT_AC_TAGVAR(no_undefined_flag, $1) \
-    _LT_AC_TAGVAR(export_symbols_cmds, $1) \
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
-    _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
-    _LT_AC_TAGVAR(hardcode_automatic, $1) \
-    _LT_AC_TAGVAR(module_cmds, $1) \
-    _LT_AC_TAGVAR(module_expsym_cmds, $1) \
-    _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
-    _LT_AC_TAGVAR(fix_srcfile_path, $1) \
-    _LT_AC_TAGVAR(exclude_expsyms, $1) \
-    _LT_AC_TAGVAR(include_expsyms, $1); do
-
-    case $var in
-    _LT_AC_TAGVAR(old_archive_cmds, $1) | \
-    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
-    _LT_AC_TAGVAR(archive_cmds, $1) | \
-    _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
-    _LT_AC_TAGVAR(module_cmds, $1) | \
-    _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
-    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
-    _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
-    extract_expsyms_cmds | reload_cmds | finish_cmds | \
-    postinstall_cmds | postuninstall_cmds | \
-    old_postinstall_cmds | old_postuninstall_cmds | \
-    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
-      # Double-quote double-evaled strings.
-      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      case $host_os in
+      os2*)
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+	;;
+      esac
       ;;
-    *)
-      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
       ;;
-    esac
-  done
 
-  case $lt_echo in
-  *'\[$]0 --fallback-echo"')
-    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
-    ;;
-  esac
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64, which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      *flang* | ftn | f18* | f95*)
+        # Flang compiler.
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | $SED 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+        *Intel*\ [[CF]]*Compiler*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	  ;;
+	*Portland\ Group*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
 
-ifelse([$1], [],
-  [cfgfile="${ofile}T"
-  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
-  $rm -f "$cfgfile"
-  AC_MSG_RESULT([
-creating $ofile])],
-  [cfgfile="$ofile"])
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
 
-  cat <<__EOF__ >> "$cfgfile"
-ifelse([$1], [],
-[#! $SHELL
+    *-mlibc)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+      ;;
 
-# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
-# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
-#
-# This file is part of GNU Libtool:
-# Originally by Gordon Matzigkeit , 1996
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
 
-# A sed program that does not truncate output.
-SED=$lt_SED
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
 
-# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="$SED -e 1s/^X//"
+    serenity*)
+      ;;
 
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
 
-# The names of the tagged configurations supported by this script.
-available_tags=
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
 
-# ### BEGIN LIBTOOL CONFIG],
-[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
 
-# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
 
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
 
-# Whether or not to build shared libraries.
-build_libtool_libs=$enable_shared
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
 
-# Whether or not to build static libraries.
-build_old_libs=$enable_static
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
 
-# Whether or not to add -lc for building shared libraries.
-build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms that do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
 
-# Whether or not to disallow shared libs when runtime libs are static
-allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
 
-# Whether or not to optimize for fast installation.
-fast_install=$enable_fast_install
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
 
-# The host system.
-host_alias=$host_alias
-host=$host
-host_os=$host_os
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
 
-# The build system.
-build_alias=$build_alias
-build=$build
-build_os=$build_os
 
-# An echo program that does not interpret backslashes.
-echo=$lt_echo
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+    # Without the "-l" option, or with the "-B" option, AIX nm treats
+    # weak defined symbols like other global defined symbols, whereas
+    # GNU nm marks them as "W".
+    # While the 'weak' keyword is ignored in the Export File, we need
+    # it in the Import File for the 'aix-soname' feature, so we have
+    # to replace the "-B" option with "-P" for AIX nm.
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+    ;;
+  cygwin* | mingw* | windows* | cegcc*)
+    case $cc_basename in
+    cl* | icl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ' (' and ')$', so one must not match beginning or
+  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+  # as well as any symbol that contains 'd'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
 
-# The archiver.
-AR=$lt_AR
-AR_FLAGS=$lt_AR_FLAGS
+  case $host_os in
+  cygwin* | mingw* | windows* | pw32* | cegcc*)
+    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++ or Intel C++ Compiler.
+    if test yes != "$GCC"; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
+    with_gnu_ld=yes
+    ;;
+  esac
 
-# A C compiler.
-LTCC=$lt_LTCC
+  _LT_TAGVAR(ld_shlibs, $1)=yes
 
-# LTCC compiler flags.
-LTCFLAGS=$lt_LTCFLAGS
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test yes = "$with_gnu_ld"; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
 
-# A language-specific compiler.
-CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+  if test yes = "$lt_use_gnu_ld_interface"; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='$wl'
 
-# Is the compiler the GNU C compiler?
-with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
 
-# An ERE matcher.
-EGREP=$lt_EGREP
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test ia64 != "$host_cpu"; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
 
-# The linker used to build libraries.
-LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
 
-# Whether we need hard or soft links.
-LN_S=$lt_LN_S
+_LT_EOF
+      fi
+      ;;
 
-# A BSD-compatible nm program.
-NM=$lt_NM
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
 
-# A symbol stripping program
-STRIP=$lt_STRIP
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach  says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
 
-# Used to examine libraries when file_magic_cmd begins "file"
-MAGIC_CMD=$MAGIC_CMD
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      _LT_TAGVAR(file_list_spec, $1)='@'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file, use it as
+	# is; otherwise, prepend EXPORTS...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+          cp $export_symbols $output_objdir/$soname.def;
+        else
+          echo EXPORTS > $output_objdir/$soname.def;
+          cat $export_symbols >> $output_objdir/$soname.def;
+        fi~
+        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
 
-# Used on cygwin: DLL creation program.
-DLLTOOL="$DLLTOOL"
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=no
+      ;;
 
-# Used on cygwin: object dumper.
-OBJDUMP="$OBJDUMP"
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      shrext_cmds=.dll
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='@'
+      ;;
 
-# Used on cygwin: assembler.
-AS="$AS"
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
 
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test linux-dietlibc = "$host_os"; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test no = "$tmp_diet"
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+        nagfor*)                        # NAGFOR 5.3
+          tmp_sharedflag='-Wl,-shared' ;;
+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | $SED 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
 
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
+        if test yes = "$supports_anon_versioning"; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+            cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+            echo "local: *; };" >> $output_objdir/$libname.ver~
+            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+        fi
 
-# How to pass a linker flag through the compiler.
-wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+	case $cc_basename in
+	tcc*)
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+	  ;;
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test yes = "$supports_anon_versioning"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+              cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+              echo "local: *; };" >> $output_objdir/$libname.ver~
+              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
 
-# Object file suffix (normally "o").
-objext="$ac_objext"
+    *-mlibc)
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      ;;
 
-# Old archive suffix (normally "a").
-libext="$libext"
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
 
-# Shared library suffix (normally ".so").
-shrext_cmds='$shrext_cmds'
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
 
-# Executable file suffix (normally "").
-exeext="$exeext"
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
 
-# Additional compiler flags for building library objects.
-pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
-pic_mode=$pic_mode
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
 
-# What is the maximum length of a command?
-max_cmd_len=$lt_cv_sys_max_cmd_len
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
 
-# Does compiler simultaneously support -c and -o options?
-compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
 
-# Must we lock files when doing compilation?
-need_locks=$lt_need_locks
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
 
-# Do we need the lib prefix for modules?
-need_lib_prefix=$need_lib_prefix
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Do we need a version for libraries?
-need_version=$need_version
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
 
-# Whether dlopen is supported.
-dlopen_support=$enable_dlopen
+    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
 
-# Whether dlopen of programs is supported.
-dlopen_self=$enable_dlopen_self
+    aix[[4-9]]*)
+      if test ia64 = "$host_cpu"; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
+	# Without the "-l" option, or with the "-B" option, AIX nm treats
+	# weak defined symbols like other global defined symbols, whereas
+	# GNU nm marks them as "W".
+	# While the 'weak' keyword is ignored in the Export File, we need
+	# it in the Import File for the 'aix-soname' feature, so we have
+	# to replace the "-B" option with "-P" for AIX nm.
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
 
-# Whether dlopen of statically linked programs is supported.
-dlopen_self_static=$enable_dlopen_self_static
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# have runtime linking enabled, and use it for executables.
+	# For shared libraries, we enable/disable runtime linking
+	# depending on the kind of the shared library created -
+	# when "with_aix_soname,aix_use_runtimelinking" is:
+	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "aix,yes"  lib.so          shared, rtl:yes, for executables
+	#            lib.a           static archive
+	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
+	#            lib.a(lib.so.V) shared, rtl:no,  for executables
+	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a(lib.so.V) shared, rtl:no
+	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+	#            lib.a           static archive
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	    # so we don't have lib.a shared libs to link our executables.
+	    # We have to force runtime linking in this case.
+	    aix_use_runtimelinking=yes
+	    LDFLAGS="$LDFLAGS -Wl,-brtl"
+	  fi
+	  ;;
+	esac
 
-# Compiler flag to prevent dynamic linking.
-link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
 
-# Compiler flag to turn off builtin functions.
-no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
 
-# Compiler flag to allow reflexive dlopens.
-export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+      case $with_aix_soname,$aix_use_runtimelinking in
+      aix,*) ;; # traditional, no import file
+      svr4,* | *,yes) # use import file
+	# The Import File defines what to hardcode.
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+	;;
+      esac
 
-# Compiler flag to generate shared objects directly from archives.
-whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+      if test yes = "$GCC"; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test yes = "$aix_use_runtimelinking"; then
+	  shared_flag="$shared_flag "'$wl-G'
+	fi
+	# Need to ensure runtime linking is disabled for the traditional
+	# shared library, or the linker may eventually find shared libraries
+	# /with/ Import File - we do not want to mix them.
+	shared_flag_aix='-shared'
+	shared_flag_svr4='-shared $wl-G'
+      else
+	# not using gcc
+	if test ia64 = "$host_cpu"; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag='$wl-G'
+	  else
+	    shared_flag='$wl-bM:SRE'
+	  fi
+	  shared_flag_aix='$wl-bM:SRE'
+	  shared_flag_svr4='$wl-G'
+	fi
+      fi
 
-# Compiler flag to generate thread-safe objects.
-thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX([$1])
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+      else
+	if test ia64 = "$host_cpu"; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX([$1])
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+	  if test yes = "$with_gnu_ld"; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	  # -brtl affects multiple linker settings, -berok does not and is overridden later
+	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+	  if test svr4 != "$with_aix_soname"; then
+	    # This is similar to how AIX traditionally builds its shared libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	  fi
+	  if test aix != "$with_aix_soname"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	  else
+	    # used by -dlpreopen to get the symbols
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	  fi
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	fi
+      fi
+      ;;
 
-# Library versioning type.
-version_type=$version_type
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
 
-# Format of library name prefix.
-libname_spec=$lt_libname_spec
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
 
-# List of archive names.  First name is the real one, the rest are links.
-# The last name is the one that the linker finds with -lNAME.
-library_names_spec=$lt_library_names_spec
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++ or Intel C++ Compiler.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl* | icl*)
+	# Native MSVC or ICC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+            cp "$export_symbols" "$output_objdir/$soname.def";
+            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+          else
+            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+          fi~
+          $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+          lt_tool_outputfile="@TOOL_OUTPUT@"~
+          case $lt_outputfile in
+            *.exe|*.EXE) ;;
+            *)
+              lt_outputfile=$lt_outputfile.exe
+              lt_tool_outputfile=$lt_tool_outputfile.exe
+              ;;
+          esac~
+          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+            $RM "$lt_outputfile.manifest";
+          fi'
+	;;
+      *)
+	# Assume MSVC and ICC wrapper
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=.dll
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	# FIXME: Should let the user specify the lib program.
+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
 
-# The coded name of the library, if different from the real name.
-soname_spec=$lt_soname_spec
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
 
-# Commands used to build and install an old-style archive.
-RANLIB=$lt_RANLIB
-old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
-old_postinstall_cmds=$lt_old_postinstall_cmds
-old_postuninstall_cmds=$lt_old_postuninstall_cmds
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Create an old-style archive from a shared archive.
-old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Create a temporary old-style archive to link instead of a shared archive.
-old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Commands used to build and install a shared archive.
-archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
-archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
-postinstall_cmds=$lt_postinstall_cmds
-postuninstall_cmds=$lt_postuninstall_cmds
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly* | midnightbsd*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Commands used to build a loadable module (assumed same as above if empty)
-module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
-module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+    hpux9*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
 
-# Commands to strip libraries.
-old_striplib=$lt_old_striplib
-striplib=$lt_striplib
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      ;;
 
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+    hpux10*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test no = "$with_gnu_ld"; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
 
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+    hpux11*)
+      if test yes,no = "$GCC,$with_gnu_ld"; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  ;;
+	esac
+      fi
+      if test no = "$with_gnu_ld"; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
-# Dependencies to place before the objects being linked to create a
-# shared library.
-predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
 
-# Dependencies to place after the objects being linked to create a
-# shared library.
-postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
 
-# The directories searched by this compiler when creating a shared
-# library
-compiler_lib_search_dirs=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)
+    irix5* | irix6* | nonstopux*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS=$LDFLAGS
+	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS=$save_LDFLAGS])
+	if test yes = "$lt_cv_irix_exported_symbol"; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+	fi
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
 
-# The library search path used internally by the compiler when linking
-# a shared library.
-compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+    linux*)
+      case $cc_basename in
+      tcc*)
+	# Fabrice Bellard et al's Tiny C Compiler
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	;;
+      esac
+      ;;
 
-# Method to check whether dependent libraries are shared objects.
-deplibs_check_method=$lt_deplibs_check_method
+    *-mlibc)
+      ;;
 
-# Command to use when deplibs_check_method == file_magic.
-file_magic_cmd=$lt_file_magic_cmd
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Flag that allows shared libraries with undefined symbols to be built.
-allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Flag that forces no undefined symbols.
-no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+    *nto* | *qnx*)
+      ;;
 
-# Commands used to finish a libtool library installation in a directory.
-finish_cmds=$lt_finish_cmds
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	else
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
 
-# Same as above, but a single script fragment to be evaled but not shown.
-finish_eval=$lt_finish_eval
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      shrext_cmds=.dll
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	$ECHO EXPORTS >> $output_objdir/$libname.def~
+	prefix_cmds="$SED"~
+	if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	  prefix_cmds="$prefix_cmds -e 1d";
+	fi~
+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	emximp -o $lib $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='@'
+      ;;
 
-# Take the output of nm and produce a listing of raw symbols and C names.
-global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+    osf3*)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
 
-# Transform the output of nm in a proper C declaration
-global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
 
-# Transform the output of nm in a C name address pair
-global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
 
-# This is the shared library runtime path variable.
-runpath_var=$runpath_var
+    serenity*)
+      ;;
 
-# This is the shared library path variable.
-shlibpath_var=$shlibpath_var
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test yes = "$GCC"; then
+	wlarc='$wl'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='$wl'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test yes = "$GCC"; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
 
-# Is shlibpath searched before the hard-coded library search path?
-shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+    sunos4*)
+      if test sequent = "$host_vendor"; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# How to hardcode a shared library path into an executable.
-hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Whether we should hardcode library paths into libraries.
-hardcode_into_libs=$hardcode_into_libs
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
 
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
 
-# If ld is used when linking, flag to hardcode \$libdir into
-# a binary during linking. This must work even if \$libdir does
-# not exist.
-hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
 
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
 
-# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+      runpath_var='LD_RUN_PATH'
 
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+      if test yes = "$GCC"; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
 
-# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
-# the resulting binary.
-hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
 
-# Set to yes if building a shared library automatically hardcodes DIR into the library
-# and all subsequent libraries and executables linked against it.
-hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
 
-# Variables whose values should be saved in libtool wrapper scripts and
-# restored at relink time.
-variables_saved_for_relink="$variables_saved_for_relink"
+    if test sni = "$host_vendor"; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
 
-# Whether libtool must link a program against all its dependency libraries.
-link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
 
-# Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
 
-# Run-time system search path for libraries
-sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
 
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
+  if test yes,yes = "$GCC,$enable_shared"; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+	  _LT_TAGVAR(allow_undefined_flag, $1)=
+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+	  then
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  fi
+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+      ;;
+    esac
+  fi
+  ;;
+esac
 
-# Set to yes if exported symbols are required.
-always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e. impossible to change by setting $shlibpath_var if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
 
-# The commands to list exported symbols.
-export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+# Source file extension for C test sources.
+ac_ext=c
 
-# The commands to extract the exported symbol list from a shared archive.
-extract_expsyms_cmds=$lt_extract_expsyms_cmds
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
 
-# Symbols that should not be listed in the preloaded symbols.
-exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
 
-# Symbols that must always be exported.
-include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(void){return(0);}'
 
-ifelse([$1],[],
-[# ### END LIBTOOL CONFIG],
-[# ### END LIBTOOL TAG CONFIG: $tagname])
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
 
-__EOF__
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
 
-ifelse([$1],[], [
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report what library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test no = "$can_build_shared" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
   case $host_os in
   aix3*)
-    cat <<\EOF >> "$cfgfile"
+    test yes = "$enable_shared" && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
 
-# AIX sometimes has problems with the GCC collect2 program.  For some
-# reason, if we set the COLLECT_NAMES environment variable, the problems
-# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
-  COLLECT_NAMES=
-  export COLLECT_NAMES
-fi
-EOF
+  aix[[4-9]]*)
+    if test ia64 != "$host_cpu"; then
+      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+      yes,aix,yes) ;;			# shared object as lib.so file only
+      yes,svr4,*) ;;			# shared object as lib.so archive member only
+      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+      esac
+    fi
     ;;
   esac
+  AC_MSG_RESULT([$enable_shared])
 
-  # We use sed instead of cat because bash on DJGPP gets confused if
-  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
-  # text mode, it properly converts lines to CR/LF.  This bash problem
-  # is reportedly fixed, but why not run on old versions too?
-  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test yes = "$enable_shared" || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
 
-  mv -f "$cfgfile" "$ofile" || \
-    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
-  chmod +x "$ofile"
-])
-else
-  # If there is no Makefile yet, we rely on a make rule to execute
-  # `config.status --recheck' to rerun these tests and create the
-  # libtool script then.
-  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
-  if test -f "$ltmain_in"; then
-    test -f Makefile && make "$ltmain"
-  fi
+  _LT_CONFIG($1)
 fi
-])# AC_LIBTOOL_CONFIG
-
-
-# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
-# -------------------------------------------
-AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
-[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
-
-_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
 
-if test "$GCC" = yes; then
-  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
 
-  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
-    lt_cv_prog_compiler_rtti_exceptions,
-    [-fno-rtti -fno-exceptions], [],
-    [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+    (test g++ != "$CXX"))); then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
 fi
-])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
-
 
-# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-# ---------------------------------
-AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
-[AC_REQUIRE([AC_CANONICAL_HOST])
-AC_REQUIRE([LT_AC_PROG_SED])
-AC_REQUIRE([AC_PROG_NM])
-AC_REQUIRE([AC_OBJEXT])
-# Check for command to grab the raw symbol name followed by C symbol from nm.
-AC_MSG_CHECKING([command to parse $NM output from $compiler object])
-AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
-[
-# These are sane defaults that work on at least a few old systems.
-# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
-
-# Character class describing NM global symbol codes.
-symcode='[[BCDEGRST]]'
-
-# Regexp to match symbols that can be accessed directly from C.
-sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
-
-# Transform an extracted symbol line into a proper C declaration
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
 
-# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+# Source file extension for C++ test sources.
+ac_ext=cpp
 
-# Define system-specific variables.
-case $host_os in
-aix*)
-  symcode='[[BCDT]]'
-  ;;
-cygwin* | mingw* | pw32*)
-  symcode='[[ABCDGISTW]]'
-  ;;
-hpux*) # Its linker distinguishes data from code symbols
-  if test "$host_cpu" = ia64; then
-    symcode='[[ABCDEGRST]]'
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
   fi
-  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
-  ;;
-linux* | k*bsd*-gnu)
-  if test "$host_cpu" = ia64; then
-    symcode='[[ABCDGIRSTW]]'
-    lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
-    lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
   fi
-  ;;
-irix* | nonstopux*)
-  symcode='[[BCDEGRST]]'
-  ;;
-osf*)
-  symcode='[[BCDEGQRST]]'
-  ;;
-solaris*)
-  symcode='[[BDRT]]'
-  ;;
-sco3.2v5*)
-  symcode='[[DT]]'
-  ;;
-sysv4.2uw2*)
-  symcode='[[DT]]'
-  ;;
-sysv5* | sco5v6* | unixware* | OpenUNIX*)
-  symcode='[[ABDT]]'
-  ;;
-sysv4)
-  symcode='[[DFNSTU]]'
-  ;;
-esac
-
-# Handle CRLF in mingw tool chain
-opt_cr=
-case $build_os in
-mingw*)
-  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
-  ;;
-esac
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
 
-# If we're using GNU nm, then use its standard symbol codes.
-case `$NM -V 2>&1` in
-*GNU* | *'with BFD'*)
-  symcode='[[ABCDGIRSTW]]' ;;
-esac
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test yes = "$GXX"; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
 
-# Try without a prefix undercore, then with it.
-for ac_symprfx in "" "_"; do
+    if test yes = "$GXX"; then
+      # Set up default GNU C++ configuration
 
-  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
-  symxfrm="\\1 $ac_symprfx\\2 \\2"
+      LT_PATH_LD
 
-  # Write the raw and C identifiers.
-  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ 	]]\($symcode$symcode*\)[[ 	]][[ 	]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test yes = "$with_gnu_ld"; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
 
-  # Check to see that the pipe works correctly.
-  pipe_works=no
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
 
-  rm -f conftest*
-  cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then
-      # Try sorting and uniquifying the output.
-      if sort "$nlist" | uniq > "$nlist"T; then
-	mv -f "$nlist"T "$nlist"
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
       else
-	rm -f "$nlist"T
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
       fi
 
-      # Make sure that we snagged all the symbols we need.
-      if grep ' nm_test_var$' "$nlist" >/dev/null; then
-	if grep ' nm_test_func$' "$nlist" >/dev/null; then
-	  cat < conftest.$ac_ext
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-EOF
-	  # Now generate the symbol file.
-	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
-
-	  cat <> conftest.$ac_ext
-#if defined (__STDC__) && __STDC__
-# define lt_ptr_t void *
-#else
-# define lt_ptr_t char *
-# define const
-#endif
-
-/* The mapping between symbol names and symbols. */
-const struct {
-  const char *name;
-  lt_ptr_t address;
-}
-lt_preloaded_symbols[[]] =
-{
-EOF
-	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
-	  cat <<\EOF >> conftest.$ac_ext
-  {0, (lt_ptr_t) 0}
-};
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
 
-#ifdef __cplusplus
-}
-#endif
-EOF
-	  # Now try linking the two files.
-	  mv conftest.$ac_objext conftstm.$ac_objext
-	  lt_save_LIBS="$LIBS"
-	  lt_save_CFLAGS="$CFLAGS"
-	  LIBS="conftstm.$ac_objext"
-	  CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
-	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
-	    pipe_works=yes
-	  fi
-	  LIBS="$lt_save_LIBS"
-	  CFLAGS="$lt_save_CFLAGS"
-	else
-	  echo "cannot find nm_test_func in $nlist" >&5
-	fi
-      else
-	echo "cannot find nm_test_var in $nlist" >&5
-      fi
     else
-      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
     fi
-  else
-    echo "$progname: failed program was:" >&5
-    cat conftest.$ac_ext >&5
-  fi
-  rm -rf conftest* conftst*
-
-  # Do not use the global_symbol_pipe unless it works.
-  if test "$pipe_works" = yes; then
-    break
-  else
-    lt_cv_sys_global_symbol_pipe=
-  fi
-done
-])
-if test -z "$lt_cv_sys_global_symbol_pipe"; then
-  lt_cv_sys_global_symbol_to_cdecl=
-fi
-if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
-  AC_MSG_RESULT(failed)
-else
-  AC_MSG_RESULT(ok)
-fi
-]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
-
-
-# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
-# ---------------------------------------
-AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
-[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
-_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
-_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
-
-AC_MSG_CHECKING([for $compiler option to produce PIC])
- ifelse([$1],[CXX],[
-  # C++ specific cases for pic, static, wl, etc.
-  if test "$GXX" = yes; then
-    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
     case $host_os in
-    aix*)
-      # All AIX code is PIC.
-      if test "$host_cpu" = ia64; then
-	# AIX 5 now supports IA64 processor
-	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      fi
-      ;;
-    amigaos*)
-      # FIXME: we need at least 68020 code to build shared libraries, but
-      # adding the `-m68020' flag to GCC prevents building anything better,
-      # like `-m68040'.
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
-      ;;
-    beos* | haiku* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
-      # PIC is the default for these OSes.
-      ;;
-    mingw* | cygwin* | os2* | pw32*)
-      # This hack is so that the source file can tell whether it is being
-      # built for inclusion in a dll (and should export symbols for example).
-      # Although the cygwin gcc ignores -fPIC, still need this for old-style
-      # (--disable-auto-import) libraries
-	  _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
-      ;;
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
-      ;;
-    *djgpp*)
-      # DJGPP does not support shared libraries at all
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
-      ;;
-    interix[[3-9]]*)
-      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
-      # Instead, we relocate shared libraries at runtime.
-      ;;
-    sysv4*MP*)
-      if test -d /usr/nec; then
-	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
-      fi
-      ;;
-    hpux*)
-      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
-      # not for PA HP-UX.
-      case $host_cpu in
-      hppa*64*|ia64*)
-	;;
-      *)
-	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	;;
-      esac
-      ;;
-    *)
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-      ;;
-    esac
-  else
-    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
       aix[[4-9]]*)
-	# All AIX code is PIC.
-	if test "$host_cpu" = ia64; then
-	  # AIX 5 now supports IA64 processor
-	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        if test ia64 = "$host_cpu"; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # have runtime linking enabled, and use it for executables.
+          # For shared libraries, we enable/disable runtime linking
+          # depending on the kind of the shared library created -
+          # when "with_aix_soname,aix_use_runtimelinking" is:
+          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "aix,yes"  lib.so          shared, rtl:yes, for executables
+          #            lib.a           static archive
+          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
+          #            lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a(lib.so.V) shared, rtl:no
+          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a           static archive
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
+	      # so we don't have lib.a shared libs to link our executables.
+	      # We have to force runtime linking in this case.
+	      aix_use_runtimelinking=yes
+	      LDFLAGS="$LDFLAGS -Wl,-brtl"
+	    fi
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+        case $with_aix_soname,$aix_use_runtimelinking in
+        aix,*) ;;	# no import file
+        svr4,* | *,yes) # use import file
+          # The Import File defines what to hardcode.
+          _LT_TAGVAR(hardcode_direct, $1)=no
+          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+          ;;
+        esac
+
+        if test yes = "$GXX"; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`$CC -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test yes = "$aix_use_runtimelinking"; then
+	    shared_flag=$shared_flag' $wl-G'
+	  fi
+	  # Need to ensure runtime linking is disabled for the traditional
+	  # shared library, or the linker may eventually find shared libraries
+	  # /with/ Import File - we do not want to mix them.
+	  shared_flag_aix='-shared'
+	  shared_flag_svr4='-shared $wl-G'
+        else
+          # not using gcc
+          if test ia64 = "$host_cpu"; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test yes = "$aix_use_runtimelinking"; then
+	      shared_flag='$wl-G'
+	    else
+	      shared_flag='$wl-bM:SRE'
+	    fi
+	    shared_flag_aix='$wl-bM:SRE'
+	    shared_flag_svr4='$wl-G'
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          # The "-G" linker flag allows undefined symbols.
+          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX([$1])
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        else
+          if test ia64 = "$host_cpu"; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX([$1])
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+	    if test yes = "$with_gnu_ld"; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+	    # -brtl affects multiple linker settings, -berok does not and is overridden later
+	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+	    if test svr4 != "$with_aix_soname"; then
+	      # This is similar to how AIX traditionally builds its shared
+	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+	    fi
+	    if test aix != "$with_aix_soname"; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+	    else
+	      # used by -dlpreopen to get the symbols
+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
+	    fi
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach  says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
 	else
-	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	  _LT_TAGVAR(ld_shlibs, $1)=no
 	fi
 	;;
+
       chorus*)
-	case $cc_basename in
-	cxch68*)
-	  # Green Hills C++ Compiler
-	  # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | windows* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl* | ,icl* | no,icl*)
+	  # Native MSVC or ICC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=.dll
+	  # FIXME: Setting linknames here is a bad hack.
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+              cp "$export_symbols" "$output_objdir/$soname.def";
+              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+            else
+              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+            fi~
+            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+            linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+            lt_tool_outputfile="@TOOL_OUTPUT@"~
+            case $lt_outputfile in
+              *.exe|*.EXE) ;;
+              *)
+                lt_outputfile=$lt_outputfile.exe
+                lt_tool_outputfile=$lt_tool_outputfile.exe
+                ;;
+            esac~
+            func_to_tool_file "$lt_outputfile"~
+            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+              $RM "$lt_outputfile.manifest";
+            fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=no
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file, use it as
+	    # is; otherwise, prepend EXPORTS...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+              cp $export_symbols $output_objdir/$soname.def;
+            else
+              echo EXPORTS > $output_objdir/$soname.def;
+              cat $export_symbols >> $output_objdir/$soname.def;
+            fi~
+            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
 	  ;;
 	esac
 	;;
-       darwin*)
-         # PIC is the default on this platform
-         # Common symbols not allowed in MH_DYLIB files
-         case $cc_basename in
-           xlc*)
-           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
-           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-           ;;
-         esac
-       ;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      os2*)
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	shrext_cmds=.dll
+	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	  $ECHO EXPORTS >> $output_objdir/$libname.def~
+	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	  emximp -o $lib $output_objdir/$libname.def'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+	  $ECHO EXPORTS >> $output_objdir/$libname.def~
+	  prefix_cmds="$SED"~
+	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
+	    prefix_cmds="$prefix_cmds -e 1d";
+	  fi~
+	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+	  emximp -o $lib $output_objdir/$libname.def'
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	;;
+
       dgux*)
-	case $cc_basename in
-	  ec++*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	  ghcx*)
+          ghcx*)
 	    # Green Hills C++ Compiler
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	  *)
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	esac
-	;;
-      freebsd* | dragonfly*)
-	# FreeBSD uses GNU C++
-	;;
-      hpux9* | hpux10* | hpux11*)
-	case $cc_basename in
-	  CC*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
-	    if test "$host_cpu" != ia64; then
-	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
-	    fi
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly* | midnightbsd*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=no
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test yes = "$GXX"; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test no = "$with_gnu_ld"; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	  aCC*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+          aCC*)
 	    case $host_cpu in
-	    hppa*64*|ia64*)
-	      # +Z the default
-	      ;;
-	    *)
-	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
-	      ;;
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
 	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
-	  *)
+          *)
+	    if test yes = "$GXX"; then
+	      if test no = "$with_gnu_ld"; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
 	    ;;
-	esac
-	;;
-      interix*)
-	# This is c89, which is MS Visual C++ (no shared libs)
-	# Anyone wants to do a port?
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
-      irix5* | irix6* | nonstopux*)
-	case $cc_basename in
-	  CC*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
-	    # CC pic flag -KPIC is the default.
-	    ;;
-	  *)
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
-	esac
-	;;
-      linux* | k*bsd*-gnu)
-	case $cc_basename in
-	  KCC*)
-	    # KAI C++ Compiler
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+          *)
+	    if test yes = "$GXX"; then
+	      if test no = "$with_gnu_ld"; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
 	    ;;
-      ecpc*)
-        # old Intel C++ for x86_64 which still supported -KPIC.
-        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-        _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
-        ;;
-      icpc*)
-        # Intel C++, used to be incompatible with GCC.
-        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-        _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
         ;;
-	  pgCC* | pgcpp*)
-	    # Portland Group C++ compiler.
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
 	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+               rm -rf $tpldir~
+               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+                $RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+                rm -rf $tpldir~
+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+            ;;
 	  cxx*)
 	    # Compaq C++
-	    # Make sure the PIC flag is empty.  It appears that all Alpha
-	    # Linux and Compaq Tru64 Unix objects are PIC.
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	    if test yes = "$supports_anon_versioning"; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+                cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+                echo "local: *; };" >> $output_objdir/$libname.ver~
+                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    fi
 	    ;;
 	  *)
-	    case `$CC -V 2>&1 | sed 5q` in
+	    case `$CC -V 2>&1 | $SED 5q` in
 	    *Sun\ C*)
 	      # Sun C++ 5.9
-	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-	      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-	      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
 	      ;;
 	    esac
 	    ;;
 	esac
 	;;
+
       lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
 	;;
+
       m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
 	;;
+
       mvs*)
-	case $cc_basename in
-	  cxx*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
 	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
 	esac
 	;;
+
+      *-mlibc)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
       netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
 	;;
+
       osf3* | osf4* | osf5*)
-	case $cc_basename in
-	  KCC*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
 	    ;;
-	  RCC*)
+          RCC*)
 	    # Rational C++ 2.4.1
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	  cxx*)
-	    # Digital/Compaq C++
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    # Make sure the PIC flag is empty.  It appears that all Alpha
-	    # Linux and Compaq Tru64 Unix objects are PIC.
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+                  echo "-hidden">> $lib.exp~
+                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+                  $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
+	    if test yes,no = "$GXX,$with_gnu_ld"; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
 	    ;;
-	esac
-	;;
+        esac
+        ;;
+
       psos*)
-	;;
-      solaris*)
-	case $cc_basename in
-	  CC*)
-	    # Sun C++ 4.2, 5.x and Centerline C++
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
-	    ;;
-	  gcx*)
-	    # Green Hills C++ Compiler
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
-	    ;;
-	  *)
-	    ;;
-	esac
-	;;
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      serenity*)
+        ;;
+
       sunos4*)
-	case $cc_basename in
-	  CC*)
+        case $cc_basename in
+          CC*)
 	    # Sun C++ 4.x
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	  lcc*)
+          lcc*)
 	    # Lucid
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
-	    ;;
-	  *)
-	    ;;
-	esac
-	;;
-      tandem*)
-	case $cc_basename in
-	  NCC*)
-	    # NonStop-UX NCC 3.20
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-	    ;;
-	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	esac
-	;;
-      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
-	case $cc_basename in
-	  CC*)
-	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
 	    ;;
-	esac
-	;;
-      vxworks*)
-	;;
-      *)
-	_LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
-	;;
-    esac
-  fi
-],
-[
-  if test "$GCC" = yes; then
-    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
-
-    case $host_os in
-      aix*)
-      # All AIX code is PIC.
-      if test "$host_cpu" = ia64; then
-	# AIX 5 now supports IA64 processor
-	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      fi
-      ;;
-
-    amigaos*)
-      # FIXME: we need at least 68020 code to build shared libraries, but
-      # adding the `-m68020' flag to GCC prevents building anything better,
-      # like `-m68040'.
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
-      ;;
-
-    beos* | haiku* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
-      # PIC is the default for these OSes.
-      ;;
-
-    mingw* | cygwin* | pw32* | os2*)
-      # This hack is so that the source file can tell whether it is being
-      # built for inclusion in a dll (and should export symbols for example).
-      # Although the cygwin gcc ignores -fPIC, still need this for old-style
-      # (--disable-auto-import) libraries
-	  _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
-      ;;
-
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
-      ;;
-
-    interix[[3-9]]*)
-      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
-      # Instead, we relocate shared libraries at runtime.
-      ;;
-
-    msdosdjgpp*)
-      # Just because we use GCC doesn't mean we suddenly get shared libraries
-      # on systems that don't support them.
-      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
-      enable_shared=no
-      ;;
-
-    sysv4*MP*)
-      if test -d /usr/nec; then
-	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
-      fi
-      ;;
-
-    hpux*)
-      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
-      # not for PA HP-UX.
-      case $host_cpu in
-      hppa*64*|ia64*)
-	# +Z the default
-	;;
-      *)
-	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	;;
-      esac
-      ;;
-
-    *)
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-      ;;
-    esac
-  else
-    # PORTME Check for flag to pass linker flags through the system compiler.
-    case $host_os in
-    aix*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      if test "$host_cpu" = ia64; then
-	# AIX 5 now supports IA64 processor
-	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      else
-	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
-      fi
-      ;;
-      darwin*)
-        # PIC is the default on this platform
-        # Common symbols not allowed in MH_DYLIB files
-       case $cc_basename in
-         xlc*)
-         _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
-         _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-         ;;
-       esac
-       ;;
+        esac
+        ;;
 
-    mingw* | cygwin* | pw32* | os2*)
-      # This hack is so that the source file can tell whether it is being
-      # built for inclusion in a dll (and should export symbols for example).
-	  _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
-      ;;
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands '-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
 
-    hpux9* | hpux10* | hpux11*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
-      # not for PA HP-UX.
-      case $host_cpu in
-      hppa*64*|ia64*)
-	# +Z the default
-	;;
-      *)
-	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
-	;;
-      esac
-      # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
-      ;;
+	    output_verbose_link_cmd='func_echo_all'
 
-    irix5* | irix6* | nonstopux*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      # PIC (with -KPIC) is the default.
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
-      ;;
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
 
-    newsos6)
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      ;;
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test yes,no = "$GXX,$with_gnu_ld"; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
+	      else
+	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
 
-    linux* | k*bsd*-gnu)
       case $cc_basename in
-      # old Intel for x86_64 which still supported -KPIC.
-      ecc*)
-        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-        _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
-        ;;
-      # icc used to be incompatible with GCC.
-      # ICC 10 doesn't accept -KPIC any more.
-      icc*)
-        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-        _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
-        ;;
-      pgcc* | pgf77* | pgf90* | pgf95*)
-        # Portland Group compilers (*not* the Pentium gcc compiler,
-	# which looks to be a dead project)
-	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
-	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-        ;;
-      ccc*)
-        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-        # All Alpha code is PIC.
-        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
-        ;;
-      *)
-        case `$CC -V 2>&1 | sed 5q` in
-	*Sun\ C*)
-	  # Sun C 5.9
-	  _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-	  _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
-	*Sun\ F*)
-	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
-	  _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-	  _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=''
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
-	esac
-	;;
       esac
       ;;
 
-    osf3* | osf4* | osf5*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      # All OSF/1 code is PIC.
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
-      ;;
-
-    rdos*)
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
-      ;;
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+	runpath_var='LD_RUN_PATH'
 
-    solaris*)
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      case $cc_basename in
-      f77* | f90* | f95*)
-	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
-      *)
-	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
-      esac
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+              '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+              '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
       ;;
 
-    sunos4*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      ;;
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
 
-    sysv4 | sysv4.2uw2* | sysv4.3*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      ;;
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
 
-    sysv4*MP*)
-      if test -d /usr/nec ;then
-	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
-	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      fi
-      ;;
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
 
-    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      ;;
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)=$GXX
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case @S|@2 in
+  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
 
-    unicos*)
-      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
-      ;;
 
-    uts4*)
-      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
-      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-      ;;
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
 
-    *)
-      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
-      ;;
-    esac
-  fi
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
 ])
-AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
 
-#
-# Check to make sure the PIC flag actually works.
-#
-if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
-  AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
-    _LT_AC_TAGVAR(lt_cv_prog_compiler_pic_works, $1),
-    [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
-    [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
-     "" | " "*) ;;
-     *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
-     esac],
-    [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
-     _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
-fi
-case $host_os in
-  # For platforms which do not support PIC, -DPIC is meaningless:
-  *djgpp*)
-    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
-    ;;
-  *)
-    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
-    ;;
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
 esac
 
-#
-# Check to make sure the static flag actually works.
-#
-wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\"
-AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
-  _LT_AC_TAGVAR(lt_cv_prog_compiler_static_works, $1),
-  $lt_tmp_static_flag,
-  [],
-  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
-])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
 
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
 
-# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
-# ------------------------------------
-# See if the linker supports building shared libraries.
-AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
-[AC_REQUIRE([LT_AC_PROG_SED])dnl
-AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
-ifelse([$1],[CXX],[
-  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
-  case $host_os in
-  aix[[4-9]]*)
-    # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to AIX nm, but means don't demangle with GNU nm
-    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
-      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
-    else
-      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
-    fi
-    ;;
-  pw32*)
-    _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
-  ;;
-  cygwin* | mingw*)
-    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
-  ;;
-  *)
-    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
-  ;;
-  esac
-  _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
-],[
-  runpath_var=
-  _LT_AC_TAGVAR(allow_undefined_flag, $1)=
-  _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
-  _LT_AC_TAGVAR(archive_cmds, $1)=
-  _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
-  _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
-  _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
-  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
-  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
-  _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
-  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
-  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
-  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
-  _LT_AC_TAGVAR(hardcode_direct, $1)=no
-  _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
-  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-  _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
-  _LT_AC_TAGVAR(hardcode_automatic, $1)=no
-  _LT_AC_TAGVAR(module_cmds, $1)=
-  _LT_AC_TAGVAR(module_expsym_cmds, $1)=
-  _LT_AC_TAGVAR(always_export_symbols, $1)=no
-  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
-  # include_expsyms should be a list of space-separated symbols to be *always*
-  # included in the symbol list
-  _LT_AC_TAGVAR(include_expsyms, $1)=
-  # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ` (' and `)$', so one must not match beginning or
-  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
-  # as well as any symbol that contains `d'.
-  _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
-  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
-  # platforms (ab)use it in PIC code, but their linkers get confused if
-  # the symbol is explicitly referenced.  Since portable code cannot
-  # rely on this symbol name, it's probably fine to never include it in
-  # preloaded symbol tables.
-  # Exclude shared library initialization/finalization symbols.
-dnl Note also adjust exclude_expsyms for C++ above.
-  extract_expsyms_cmds=
-  # Just being paranoid about ensuring that cc_basename is set.
-  _LT_CC_BASENAME([$compiler])
-  case $host_os in
-  cygwin* | mingw* | pw32*)
-    # FIXME: the MSVC++ port hasn't been tested in a loooong time
-    # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++.
-    if test "$GCC" != yes; then
-      with_gnu_ld=no
-    fi
-    ;;
-  interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++)
-    with_gnu_ld=yes
-    ;;
-  openbsd*)
-    with_gnu_ld=no
-    ;;
-  esac
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $prev$p in
 
-  _LT_AC_TAGVAR(ld_shlibs, $1)=yes
-  if test "$with_gnu_ld" = yes; then
-    # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='${wl}'
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R,l}" and the path.
+       # Remove the space.
+       if test x-L = x"$p" ||
+          test x-R = x"$p" ||
+          test x-l = x"$p"; then
+	 prev=$p
+	 continue
+       fi
 
-    # Set some defaults for GNU ld with shared library support. These
-    # are reset later if shared libraries are not supported. Putting them
-    # here allows them to be overridden if necessary.
-    runpath_var=LD_RUN_PATH
-    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
-    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-    # ancient GNU ld didn't support --whole-archive et. al.
-    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
-	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
-      else
-  	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
-    fi
-    supports_anon_versioning=no
-    case `$LD -v 2>/dev/null` in
-      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
-      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
-      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
-      *\ 2.11.*) ;; # other 2.11 versions
-      *) supports_anon_versioning=yes ;;
-    esac
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test no = "$pre_test_object_deps_done"; then
+	 case $prev in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)=$prev$p
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test no = "$pre_test_object_deps_done"; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)=$p
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)=$p
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
 
-    # See if GNU ld supports shared libraries.
-    case $host_os in
-    aix[[3-9]]*)
-      # On AIX/PPC, the GNU linker is very broken
-      if test "$host_cpu" != ia64; then
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	cat <&2
+    *) ;; # Ignore the rest.
 
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
-*** to be unable to reliably create shared libraries on AIX.
-*** Therefore, libtool is disabling shared libraries support.  If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
+    esac
+  done
 
-EOF
-      fi
-      ;;
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
 
-    amigaos*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
 
-      # Samuel A. Falvo II  reports
-      # that the semantics of dynamic libraries on AmigaOS, at least up
-      # to version 4, is to share data among multiple programs linked
-      # with the same dynamic library.  Since this doesn't match the
-      # behavior of shared libraries on other platforms, we can't use
-      # them.
-      _LT_AC_TAGVAR(ld_shlibs, $1)=no
-      ;;
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+esac
+])
 
-    beos*)
-      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
-	# Joseph Beckenbach  says some releases of gcc
-	# support --undefined.  This deserves some investigation.  FIXME
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-      else
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-      fi
-      ;;
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+  _lt_disable_F77=yes
+fi
 
-    cygwin* | mingw* | pw32*)
-      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
-      # as there is no search path for DLLs.
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
-      _LT_AC_TAGVAR(always_export_symbols, $1)=no
-      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
-
-      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file (1st line
-	# is EXPORTS), use it as is; otherwise, prepend...
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
-	  cp $export_symbols $output_objdir/$soname.def;
-	else
-	  echo EXPORTS > $output_objdir/$soname.def;
-	  cat $export_symbols >> $output_objdir/$soname.def;
-	fi~
-	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-      else
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-      fi
-      ;;
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
 
-    interix[[3-9]]*)
-      _LT_AC_TAGVAR(hardcode_direct, $1)=no
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
-      # Instead, shared libraries are loaded at an image base (0x10000000 by
-      # default) and relocated if they conflict, which is a slow very memory
-      # consuming and fragmenting process.  To avoid this, we pick a random,
-      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
-      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      ;;
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
 
-    gnu* | linux* | k*bsd*-gnu)
-      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-	tmp_addflag=
-	case $cc_basename,$host_cpu in
-	pgcc*)				# Portland Group C compiler
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
-	  tmp_addflag=' $pic_flag'
-	  ;;
-	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
-	  tmp_addflag=' $pic_flag -Mnomain' ;;
-	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
-	  tmp_addflag=' -i_dynamic' ;;
-	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
-	  tmp_addflag=' -i_dynamic -nofor_main' ;;
-	ifc* | ifort*)			# Intel Fortran compiler
-	  tmp_addflag=' -nofor_main' ;;
-	esac
-	case `$CC -V 2>&1 | sed 5q` in
-	*Sun\ C*)			# Sun C 5.9
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
-	  tmp_sharedflag='-G' ;;
-	*Sun\ F*)			# Sun Fortran 8.3
-	  tmp_sharedflag='-G' ;;
-	*)
-	  tmp_sharedflag='-shared' ;;
-	esac
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test no = "$can_build_shared" && enable_shared=no
 
-	if test $supports_anon_versioning = yes; then
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
-  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-  $echo "local: *; };" >> $output_objdir/$libname.ver~
-	  $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test yes = "$enable_shared" && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test ia64 != "$host_cpu"; then
+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+	  yes,aix,yes) ;;		# shared object as lib.so file only
+	  yes,svr4,*) ;;		# shared object as lib.so archive member only
+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+	  esac
 	fi
-      else
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-      fi
-      ;;
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test yes = "$enable_shared" || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)=$G77
+    _LT_TAGVAR(LD, $1)=$LD
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+  _lt_disable_FC=yes
+fi
 
-    netbsd*)
-      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
-	wlarc=
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-      fi
-      ;;
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
 
-    solaris*)
-      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	cat <&2
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
 
-*** Warning: The releases 2.8.* of the GNU linker cannot reliably
-*** create shared libraries on Solaris systems.  Therefore, libtool
-*** is disabling shared libraries support.  We urge you to upgrade GNU
-*** binutils to release 2.9.1 or newer.  Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
 
-EOF
-      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-      else
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-      fi
-      ;;
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
 
-    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
-      case `$LD -v 2>&1` in
-        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-	cat <<_LT_EOF 1>&2
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
-*** reliably create shared libraries on SCO systems.  Therefore, libtool
-*** is disabling shared libraries support.  We urge you to upgrade GNU
-*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
-*** your PATH or compiler configuration so that the native linker is
-*** used, and then restart.
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
 
-_LT_EOF
-	;;
-	*)
-	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-	    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
-	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
-	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
-	  else
-	    _LT_AC_TAGVAR(ld_shlibs, $1)=no
-	  fi
-	;;
-      esac
-      ;;
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
 
-    sunos4*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-      wlarc=
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test no = "$can_build_shared" && enable_shared=no
 
-    *)
-      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
-      else
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-      fi
-      ;;
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test yes = "$enable_shared" && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test ia64 != "$host_cpu"; then
+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+	  yes,aix,yes) ;;		# shared object as lib.so file only
+	  yes,svr4,*) ;;		# shared object as lib.so archive member only
+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
+	  esac
+	fi
+        ;;
     esac
+    AC_MSG_RESULT([$enable_shared])
 
-    if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then
-      runpath_var=
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
-      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
-    fi
-  else
-    # PORTME fill in a description of your system's linker (not GNU ld)
-    case $host_os in
-    aix3*)
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
-      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
-      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
-      # Note: this linker hardcodes the directories in LIBPATH if there
-      # are no directories specified by -L.
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
-	# Neither direct hardcoding nor static linking is supported with a
-	# broken collect2.
-	_LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
-      fi
-      ;;
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test yes = "$enable_shared" || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
 
-    aix[[4-9]]*)
-      if test "$host_cpu" = ia64; then
-	# On IA64, the linker does run time linking by default, so we don't
-	# have to do anything special.
-	aix_use_runtimelinking=no
-	exp_sym_flag='-Bexport'
-	no_entry_flag=""
-      else
-	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to AIX nm, but means don't demangle with GNU nm
-	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
-	  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
-	else
-	  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
-	fi
-	aix_use_runtimelinking=no
+    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+    _LT_TAGVAR(LD, $1)=$LD
 
-	# Test if we are trying to use run time linking or normal
-	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# need to do runtime linking.
-	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
-	  for ld_flag in $LDFLAGS; do
-  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
-  	    aix_use_runtimelinking=yes
-  	    break
-  	  fi
-	  done
-	  ;;
-	esac
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
 
-	exp_sym_flag='-bexport'
-	no_entry_flag='-bnoentry'
-      fi
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
 
-      # When large executables or shared objects are built, AIX ld can
-      # have problems creating the table of contents.  If linking a library
-      # or program results in "error TOC overflow" add -mminimal-toc to
-      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
-      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
 
-      _LT_AC_TAGVAR(archive_cmds, $1)=''
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
-      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
 
-      if test "$GCC" = yes; then
-	case $host_os in aix4.[[012]]|aix4.[[012]].*)
-	# We only want to do this on AIX 4.2 and lower, the check
-	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`${CC} -print-prog-name=collect2`
-	  if test -f "$collect2name" && \
-  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
-	  then
-  	  # We have reworked collect2
-  	  :
-	  else
-  	  # We have old collect2
-  	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
-  	  # It fails to find uninstalled libraries when the uninstalled
-  	  # path is not listed in the libpath.  Setting hardcode_minus_L
-  	  # to unsupported forces relinking
-  	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-  	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-  	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
-	  fi
-	  ;;
-	esac
-	shared_flag='-shared'
-	if test "$aix_use_runtimelinking" = yes; then
-	  shared_flag="$shared_flag "'${wl}-G'
-	fi
-      else
-	# not using gcc
-	if test "$host_cpu" = ia64; then
-  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
-  	# chokes on -Wl,-G. The following line is correct:
-	  shared_flag='-G'
-	else
-	  if test "$aix_use_runtimelinking" = yes; then
-	    shared_flag='${wl}-G'
-	  else
-	    shared_flag='${wl}-bM:SRE'
-	  fi
-	fi
-      fi
 
-      # It seems that -bexpall does not export symbols beginning with
-      # underscore (_), so it is better to generate a list of symbols to export.
-      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
-      if test "$aix_use_runtimelinking" = yes; then
-	# Warning - without using the other runtime loading flags (-brtl),
-	# -berok will link without error, but may produce a broken library.
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
-       # Determine the default libpath from the value encoded in an empty executable.
-       _LT_AC_SYS_LIBPATH_AIX
-       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
-       else
-	if test "$host_cpu" = ia64; then
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
-	  _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
-	else
-	 # Determine the default libpath from the value encoded in an empty executable.
-	 _LT_AC_SYS_LIBPATH_AIX
-	 _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-	  # Warning - without using the other run time loading flags,
-	  # -berok will link without error, but may produce a broken library.
-	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
-	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
-	  # Exported symbols can be pulled into shared objects from archives
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
-	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-	  # This is similar to how AIX traditionally builds its shared libraries.
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
-	fi
-      fi
-      ;;
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
 
-    amigaos*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      # see comment about different semantics on the GNU ld section
-      _LT_AC_TAGVAR(ld_shlibs, $1)=no
-      ;;
+# Source file extension for Java test sources.
+ac_ext=java
 
-    bsdi[[45]]*)
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
-      ;;
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
 
-    cygwin* | mingw* | pw32*)
-      # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++.
-      # hardcode_libdir_flag_spec is actually meaningless, as there is
-      # no search path for DLLs.
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
-      # Tell ltmain to make .lib files, not .a files.
-      libext=lib
-      # Tell ltmain to make .dll files, not .so files.
-      shrext_cmds=".dll"
-      # FIXME: Setting linknames here is a bad hack.
-      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
-      # The linker will automatically build a .lib file if we build a DLL.
-      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
-      # FIXME: Should let the user specify the lib program.
-      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
-      _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
-      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      ;;
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
 
-    darwin* | rhapsody*)
-      case $host_os in
-        rhapsody* | darwin1.[[012]])
-         _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
-         ;;
-       *) # Darwin 1.3 on
-         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
-           _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
-         else
-           case ${MACOSX_DEPLOYMENT_TARGET} in
-             10.[[012]])
-               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
-               ;;
-             *)
-               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
-               ;;
-           esac
-         fi
-         ;;
-      esac
-      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-      _LT_AC_TAGVAR(hardcode_direct, $1)=no
-      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
-      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-    if test "$GCC" = yes ; then
-    	output_verbose_link_cmd='echo'
-        _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
-        _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
-        _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
-        _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
-    else
-      case $cc_basename in
-        xlc*)
-         output_verbose_link_cmd='echo'
-         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring'
-         _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
-          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
-         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
-          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
-          ;;
-       *)
-         _LT_AC_TAGVAR(ld_shlibs, $1)=no
-          ;;
-      esac
-    fi
-      ;;
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
 
-    dgux*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
 
-    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
-    # support.  Future versions do this automatically, but an explicit c++rt0.o
-    # does not break anything, and helps significantly (at the cost of a little
-    # extra space).
-    freebsd2.2*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
 
-    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
-    freebsd2*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
 
-    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
-    freebsd* | dragonfly*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
 
-    hpux9*)
-      if test "$GCC" = yes; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
-      fi
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
 
-      # hardcode_minus_L: Not really in the search PATH,
-      # but as the default location of the library.
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-      ;;
 
-    hpux10*)
-      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
-      fi
-      if test "$with_gnu_ld" = no; then
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
 
-	_LT_AC_TAGVAR(hardcode_direct, $1)=yes
-	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+# Source file extension for Go test sources.
+ac_ext=go
 
-	# hardcode_minus_L: Not really in the search PATH,
-	# but as the default location of the library.
-	_LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      fi
-      ;;
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
 
-    hpux11*)
-      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-	case $host_cpu in
-	hppa*64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  ;;
-	ia64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
-	  ;;
-	*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
-	  ;;
-	esac
-      else
-	case $host_cpu in
-	hppa*64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  ;;
-	ia64*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
-	  ;;
-	*)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
-	  ;;
-	esac
-      fi
-      if test "$with_gnu_ld" = no; then
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
 
-	case $host_cpu in
-	hppa*64*|ia64*)
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
-	  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-	  ;;
-	*)
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-	  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
 
-	  # hardcode_minus_L: Not really in the search PATH,
-	  # but as the default location of the library.
-	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-	  ;;
-	esac
-      fi
-      ;;
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
 
-    irix5* | irix6* | nonstopux*)
-      if test "$GCC" = yes; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
-      fi
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-      ;;
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
 
-    netbsd*)
-      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
-      fi
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
 
-    newsos6)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
 
-    openbsd*)
-      if test -f /usr/libexec/ld.so; then
-	_LT_AC_TAGVAR(hardcode_direct, $1)=yes
-	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-	if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
-	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-	  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
-	else
-	  case $host_os in
-	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
-	     _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
-	     _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	     ;;
-	   *)
-	     _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	     _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
-	     ;;
-	  esac
-        fi
-      else
-	_LT_AC_TAGVAR(ld_shlibs, $1)=no
-      fi
-      ;;
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
 
-    os2*)
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
-      _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
-      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
-      ;;
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
 
-    osf3*)
-      if test "$GCC" = yes; then
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-      else
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-      fi
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-      ;;
+AC_LANG_RESTORE
 
-    osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test "$GCC" = yes; then
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
-      else
-	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
-	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
 
-	# Both c and cxx compiler support -rpath directly
-	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
-      fi
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
-      ;;
 
-    solaris*)
-      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
-      if test "$GCC" = yes; then
-	wlarc='${wl}'
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
-      else
-	wlarc=''
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
-  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
-      fi
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      case $host_os in
-      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
-      *)
-	# The compiler driver will combine and reorder linker options,
-	# but understands `-z linker_flag'.  GCC discards it without `$wl',
-	# but is careful enough not to reorder.
- 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test "$GCC" = yes; then
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
-	else
-	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
-	fi
-	;;
-      esac
-      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-      ;;
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
 
-    sunos4*)
-      if test "x$host_vendor" = xsequent; then
-	# Use $CC to link under sequent, because it throws in some extra .o
-	# files that make .init and .fini sections work.
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
-      fi
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
-      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# Source file extension for RC test sources.
+ac_ext=rc
 
-    sysv4)
-      case $host_vendor in
-	sni)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
-	;;
-	siemens)
-	  ## LD is ld it makes a PLAMLIB
-	  ## CC just makes a GrossModule.
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
-	  _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
-        ;;
-	motorola)
-	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-	  _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
-	;;
-      esac
-      runpath_var='LD_RUN_PATH'
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
 
-    sysv4.3*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
-      ;;
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
 
-    sysv4*MP*)
-      if test -d /usr/nec; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-	runpath_var=LD_RUN_PATH
-	hardcode_runpath_var=yes
-	_LT_AC_TAGVAR(ld_shlibs, $1)=yes
-      fi
-      ;;
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
 
-    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
-      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      runpath_var='LD_RUN_PATH'
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
 
-      if test "$GCC" = yes; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-      fi
-      ;;
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
 
-    sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We can NOT use -z defs as we might desire, because we do not
-      # link with -lc, and that would cause any symbols used from libc to
-      # always be unresolved, which means just about no library would
-      # ever link correctly.  If we're not using GNU ld we use -z text
-      # though, which does catch some bad symbols but isn't as heavy-handed
-      # as -z defs.
-      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
-      _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
-      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
-      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
-      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
-      runpath_var='LD_RUN_PATH'
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
 
-      if test "$GCC" = yes; then
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
-      else
-	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
-      fi
-      ;;
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
 
-    uts4*)
-      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
-      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-      ;;
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
 
-    *)
-      _LT_AC_TAGVAR(ld_shlibs, $1)=no
-      ;;
-    esac
-  fi
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
 ])
-AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
-test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
-#
-# Do we need to explicitly link libc?
-#
-case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
-x|xyes)
-  # Assume -lc should be added
-  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
 
-  if test "$enable_shared" = yes && test "$GCC" = yes; then
-    case $_LT_AC_TAGVAR(archive_cmds, $1) in
-    *'~'*)
-      # FIXME: we may have to deal with multi-command sequences.
-      ;;
-    '$CC '*)
-      # Test whether the compiler implicitly links with -lc since on some
-      # systems, -lgcc has to come before -lc. If gcc already passes -lc
-      # to ld, don't add -lc before -lgcc.
-      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
-      $rm conftest*
-      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
-      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
-        soname=conftest
-        lib=conftest
-        libobjs=conftest.$ac_objext
-        deplibs=
-        wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
-	pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
-        compiler_flags=-v
-        linker_flags=-v
-        verstring=
-        output_objdir=.
-        libname=conftest
-        lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
-        _LT_AC_TAGVAR(allow_undefined_flag, $1)=
-        if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
-        then
-	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
-        else
-	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
-        fi
-        _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
-      else
-        cat conftest.err 1>&5
-      fi
-      $rm conftest*
-      AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
-      ;;
-    esac
-  fi
-  ;;
-esac
-])# AC_LIBTOOL_PROG_LD_SHLIBS
 
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
 
-# _LT_AC_FILE_LTDLL_C
-# -------------------
-# Be careful that the start marker always follows a newline.
-AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
-# /* ltdll.c starts here */
-# #define WIN32_LEAN_AND_MEAN
-# #include 
-# #undef WIN32_LEAN_AND_MEAN
-# #include 
-#
-# #ifndef __CYGWIN__
-# #  ifdef __CYGWIN32__
-# #    define __CYGWIN__ __CYGWIN32__
-# #  endif
-# #endif
-#
-# #ifdef __cplusplus
-# extern "C" {
-# #endif
-# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
-# #ifdef __cplusplus
-# }
-# #endif
-#
-# #ifdef __CYGWIN__
-# #include 
-# DECLARE_CYGWIN_DLL( DllMain );
-# #endif
-# HINSTANCE __hDllInstance_base;
-#
-# BOOL APIENTRY
-# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
-# {
-#   __hDllInstance_base = hInst;
-#   return TRUE;
-# }
-# /* ltdll.c ends here */
-])# _LT_AC_FILE_LTDLL_C
 
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
 
-# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
-# ---------------------------------
-AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
 
 
-# old names
-AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
-AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
-AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
-AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
-AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
-AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
-AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
 
-# This is just to silence aclocal about the macro not being used
-ifelse([AC_DISABLE_FAST_INSTALL])
 
-############################################################
-# NOTE: This macro has been submitted for inclusion into   #
-#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
-#  a released version of Autoconf we should remove this    #
-#  macro and use it instead.                               #
-############################################################
-# LT_AC_PROG_SED
+# _LT_DECL_OBJDUMP
 # --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_FILECMD
+# ----------------
+# Check for a file(cmd) program that can be used to detect file type and magic
+m4_defun([_LT_DECL_FILECMD],
+[AC_CHECK_PROG([FILECMD], [file], [file], [:])
+_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types])
+])# _LD_DECL_FILECMD
+
+# _LT_DECL_SED
+# ------------
 # Check for a fully-functional sed program, that truncates
 # as few characters as possible.  Prefer GNU sed if found.
-AC_DEFUN([LT_AC_PROG_SED],
-[AC_MSG_CHECKING([for a sed that does not truncate output])
-AC_CACHE_VAL(lt_cv_path_SED,
-[# Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for lt_ac_prog in sed gsed; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      if test -f "$as_dir/$lt_ac_prog$ac_exec_ext"; then
-        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
-      fi
-    done
-  done
-done
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
-  test ! -f $lt_ac_sed && continue
-  cat /dev/null > conftest.in
-  lt_ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
-  # Check for GNU sed and select it if it is found.
-  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
-    lt_cv_path_SED=$lt_ac_sed
-    break
-  fi
-  while true; do
-    cat conftest.in conftest.in >conftest.tmp
-    mv conftest.tmp conftest.in
-    cp conftest.in conftest.nl
-    echo >>conftest.nl
-    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
-    cmp -s conftest.out conftest.nl || break
-    # 10000 chars as input seems more than enough
-    test $lt_ac_count -gt 10 && break
-    lt_ac_count=`expr $lt_ac_count + 1`
-    if test $lt_ac_count -gt $lt_ac_max; then
-      lt_ac_max=$lt_ac_count
-      lt_cv_path_SED=$lt_ac_sed
-    fi
-  done
-done
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* | *-*-windows* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* | *-*-windows* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
 ])
-SED=$lt_cv_path_SED
-AC_MSG_RESULT([$SED])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* | *-*-windows* )
+    case $build in
+      *-*-mingw* | *-*-windows* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
 ])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/build/ltmain.sh b/build/ltmain.sh
index 3c00e7915707..3e6a3db3a5a1 100755
--- a/build/ltmain.sh
+++ b/build/ltmain.sh
@@ -1,6658 +1,11405 @@
-# ltmain.sh - Provide generalized library-building support services.
-# NOTE: Changing this file will not affect anything until you rerun configure.
-#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
-# 2007, 2008  Free Software Foundation, Inc.
-# Originally by Gordon Matzigkeit , 1996
-#
-# This program is free software; you can redistribute it and/or modify
+#! /usr/bin/env sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+##               by inline-source v2019-02-19.15
+
+# libtool (GNU libtool) 2.5.4
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit , 1996
+
+# Copyright (C) 1996-2019, 2021-2024 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful, but
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# along with this program.  If not, see .
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.5.4
+package_revision=2.5.4
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2019-02-19.15; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+# Copyright (C) 2004-2019, 2021, 2023-2024 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# , and GPL version 2 or later
+# .  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-basename="s,^.*/,,g"
+# Please report bugs or propose patches to:
+# 
 
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath="$0"
 
-# The name of this program:
-progname=`echo "$progpath" | $SED $basename`
-modename="$progname"
+## ------ ##
+## Usage. ##
+## ------ ##
 
-# Global variables:
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
 
-PROGRAM=ltmain.sh
-PACKAGE=libtool
-VERSION=1.5.26
-TIMESTAMP=" (1.1220.2.492 2008/01/30 06:40:56)"
 
-# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
   NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# Check that we have a working $echo.
-if test "X$1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X$1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
-  # Yippee, $echo works!
-  :
-else
-  # Restart under the correct shell, and then maybe $echo will work.
-  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat </dev/null` in *posix*) set -o posix ;; esac
 fi
 
-default_mode=
-help="Try \`$progname --help' for more information."
-magic="%%%MAGIC variable%%%"
-mkdir="mkdir"
-mv="mv -f"
-rm="rm -f"
-
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed="${SED}"' -e 1s/^X//'
-sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
-# test EBCDIC or ASCII
-case `echo X|tr X '\101'` in
- A) # ASCII based system
-    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
-  SP2NL='tr \040 \012'
-  NL2SP='tr \015\012 \040\040'
-  ;;
- *) # EBCDIC based system
-  SP2NL='tr \100 \n'
-  NL2SP='tr \r\n \100\100'
-  ;;
-esac
-
-# NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-# We save the old values to restore during execute mode.
-lt_env=
-for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
 do
-  eval "if test \"\${$lt_var+set}\" = set; then
-	  save_$lt_var=\$$lt_var
-	  lt_env=\"$lt_var=\$$lt_var \$lt_env\"
-	  $lt_var=C
-	  export $lt_var
+  eval "if test set = \"\${$_G_var+set}\"; then
+          save_$_G_var=\$$_G_var
+          $_G_var=C
+	  export $_G_var
+	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
 	fi"
 done
-
-if test -n "$lt_env"; then
-  lt_env="env $lt_env"
-fi
+# These NLS vars are set unconditionally (bootstrap issue #24).  Unset those
+# in case the environment reset is needed later and the $save_* variant is not
+# defined (see the code above).
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
 
 # Make sure IFS has a sensible default
-lt_nl='
+sp=' '
+nl='
 '
-IFS=" 	$lt_nl"
-
-if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
-  $echo "$modename: not configured to build any kind of library" 1>&2
-  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-  exit $EXIT_FAILURE
+IFS="$sp	$nl"
+
+# There are apparently some systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
 fi
 
-# Global variables.
-mode=$default_mode
-nonopt=
-prev=
-prevopt=
-run=
-show="$echo"
-show_help=
-execute_dlfiles=
-duplicate_deps=no
-preserve_args=
-lo2o="s/\\.lo\$/.${objext}/"
-o2lo="s/\\.${objext}\$/.lo/"
-extracted_archives=
-extracted_serial=0
-
-#####################################
-# Shell function definitions:
-# This seems to be the best place for them
 
-# func_mktempdir [string]
-# Make a temporary directory that won't clash with other running
-# libtool processes, and avoids race conditions if possible.  If
-# given, STRING is the basename for that directory.
-func_mktempdir ()
+# func_unset VAR
+# --------------
+# Portably unset VAR.
+# In some shells, an 'unset VAR' statement leaves a non-zero return
+# status if VAR is already unset, which might be problematic if the
+# statement is used at the end of a function (thus poisoning its return
+# value) or when 'set -e' is active (causing even a spurious abort of
+# the script in this case).
+func_unset ()
 {
-    my_template="${TMPDIR-/tmp}/${1-$progname}"
-
-    if test "$run" = ":"; then
-      # Return a directory name, but don't create it in dry-run mode
-      my_tmpdir="${my_template}-$$"
-    else
+    { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }
+}
 
-      # If mktemp works, use that first and foremost
-      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
 
-      if test ! -d "$my_tmpdir"; then
-	# Failing that, at least try and use $RANDOM to avoid a race
-	my_tmpdir="${my_template}-${RANDOM-0}$$"
+# Make sure CDPATH doesn't cause `cd` commands to output the target dir.
+func_unset CDPATH
 
-	save_mktempdir_umask=`umask`
-	umask 0077
-	$mkdir "$my_tmpdir"
-	umask $save_mktempdir_umask
-      fi
+# Make sure ${,E,F}GREP behave sanely.
+func_unset GREP_OPTIONS
 
-      # If we're not in dry-run mode, bomb out on failure
-      test -d "$my_tmpdir" || {
-        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
-	exit $EXIT_FAILURE
-      }
-    fi
 
-    $echo "X$my_tmpdir" | $Xsed
-}
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
 
 
-# func_win32_libid arg
-# return the library type of file 'arg'
-#
-# Need a lot of goo to handle *both* DLLs and import libs
-# Has to be a shell function in order to 'eat' the argument
-# that is supplied when $file_magic_command is called.
-func_win32_libid ()
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
 {
-  win32_libid_type="unknown"
-  win32_fileres=`file -L $1 2>/dev/null`
-  case $win32_fileres in
-  *ar\ archive\ import\ library*) # definitely import
-    win32_libid_type="x86 archive import"
-    ;;
-  *ar\ archive*) # could be an import, or static
-    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
-      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
-      win32_nmres=`eval $NM -f posix -A $1 | \
-	$SED -n -e '1,100{
-		/ I /{
-			s,.*,import,
-			p
-			q
-			}
-		}'`
-      case $win32_nmres in
-      import*)  win32_libid_type="x86 archive import";;
-      *)        win32_libid_type="x86 archive static";;
-      esac
-    fi
-    ;;
-  *DLL*)
-    win32_libid_type="x86 DLL"
-    ;;
-  *executable*) # but shell scripts are "executable" too...
-    case $win32_fileres in
-    *MS\ Windows\ PE\ Intel*)
-      win32_libid_type="x86 DLL"
-      ;;
-    esac
-    ;;
-  esac
-  $echo $win32_libid_type
+    test -f "$1" && test -x "$1"
 }
 
 
-# func_infer_tag arg
-# Infer tagged configuration to use if any are available and
-# if one wasn't chosen via the "--tag" command line option.
-# Only attempt this if the compiler in the base compile
-# command doesn't match the default compiler.
-# arg is usually of the form 'gcc ...'
-func_infer_tag ()
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
 {
-    if test -n "$available_tags" && test -z "$tagname"; then
-      CC_quoted=
-      for arg in $CC; do
-	case $arg in
-	  *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	CC_quoted="$CC_quoted $arg"
+    _G_progs_list=$1
+    _G_check_func=$2
+    _G_PATH=${3-"$PATH"}
+
+    _G_path_prog_max=0
+    _G_path_prog_found=false
+    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+    for _G_dir in $_G_PATH; do
+      IFS=$_G_save_IFS
+      test -z "$_G_dir" && _G_dir=.
+      for _G_prog_name in $_G_progs_list; do
+        for _exeext in '' .EXE; do
+          _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+          func_executable_p "$_G_path_prog" || continue
+          case `"$_G_path_prog" --version 2>&1` in
+            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+            *)     $_G_check_func $_G_path_prog
+		   func_path_progs_result=$func_check_prog_result
+		   ;;
+          esac
+          $_G_path_prog_found && break 3
+        done
       done
-      case $@ in
-      # Blanks in the command may have been stripped by the calling shell,
-      # but not from the CC environment variable when configure was run.
-      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
-      # Blanks at the start of $base_compile will cause this to fail
-      # if we don't check for them as well.
-      *)
-	for z in $available_tags; do
-	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
-	    # Evaluate the configuration.
-	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
-	    CC_quoted=
-	    for arg in $CC; do
-	    # Double-quote args containing other shell metacharacters.
-	    case $arg in
-	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	      arg="\"$arg\""
-	      ;;
-	    esac
-	    CC_quoted="$CC_quoted $arg"
-	  done
-	    case "$@ " in
-	      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
-	      # The compiler in the base compile command matches
-	      # the one in the tagged configuration.
-	      # Assume this is the tagged configuration we want.
-	      tagname=$z
-	      break
-	      ;;
-	    esac
-	  fi
-	done
-	# If $tagname still isn't set, then no tagged configuration
-	# was found and let the user know that the "--tag" command
-	# line option must be used.
-	if test -z "$tagname"; then
-	  $echo "$modename: unable to infer tagged configuration"
-	  $echo "$modename: specify a tag with \`--tag'" 1>&2
-	  exit $EXIT_FAILURE
-#        else
-#          $echo "$modename: using $tagname tagged configuration"
-	fi
-	;;
-      esac
-    fi
+    done
+    IFS=$_G_save_IFS
+    test -z "$func_path_progs_result" && {
+      echo "no acceptable sed could be found in \$PATH" >&2
+      exit 1
+    }
 }
 
 
-# func_extract_an_archive dir oldlib
-func_extract_an_archive ()
-{
-    f_ex_an_ar_dir="$1"; shift
-    f_ex_an_ar_oldlib="$1"
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
 
-    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
-    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
-    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
-     :
-    else
-      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
-      exit $EXIT_FAILURE
-    fi
-}
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+  for _G_i in 1 2 3 4 5 6 7; do
+    _G_sed_script=$_G_sed_script$nl$_G_sed_script
+  done
+  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+  _G_sed_script=
 
-# func_extract_archives gentop oldlib ...
-func_extract_archives ()
-{
-    my_gentop="$1"; shift
-    my_oldlibs=${1+"$@"}
-    my_oldobjs=""
-    my_xlib=""
-    my_xabs=""
-    my_xdir=""
-    my_status=""
-
-    $show "${rm}r $my_gentop"
-    $run ${rm}r "$my_gentop"
-    $show "$mkdir $my_gentop"
-    $run $mkdir "$my_gentop"
-    my_status=$?
-    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
-      exit $my_status
-    fi
+  func_check_prog_sed ()
+  {
+    _G_path_prog=$1
 
-    for my_xlib in $my_oldlibs; do
-      # Extract the objects.
-      case $my_xlib in
-	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
-	*) my_xabs=`pwd`"/$my_xlib" ;;
-      esac
-      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
-      my_xlib_u=$my_xlib
-      while :; do
-        case " $extracted_archives " in
-	*" $my_xlib_u "*)
-	  extracted_serial=`expr $extracted_serial + 1`
-	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
-	*) break ;;
-	esac
-      done
-      extracted_archives="$extracted_archives $my_xlib_u"
-      my_xdir="$my_gentop/$my_xlib_u"
-
-      $show "${rm}r $my_xdir"
-      $run ${rm}r "$my_xdir"
-      $show "$mkdir $my_xdir"
-      $run $mkdir "$my_xdir"
-      exit_status=$?
-      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
-	exit $exit_status
+    _G_count=0
+    printf 0123456789 >conftest.in
+    while :
+    do
+      cat conftest.in conftest.in >conftest.tmp
+      mv conftest.tmp conftest.in
+      cp conftest.in conftest.nl
+      echo '' >> conftest.nl
+      "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break
+      diff conftest.out conftest.nl >/dev/null 2>&1 || break
+      _G_count=`expr $_G_count + 1`
+      if test "$_G_count" -gt "$_G_path_prog_max"; then
+        # Best one so far, save it but keep looking for a better one
+        func_check_prog_result=$_G_path_prog
+        _G_path_prog_max=$_G_count
       fi
-      case $host in
-      *-darwin*)
-	$show "Extracting $my_xabs"
-	# Do not bother doing anything if just a dry run
-	if test -z "$run"; then
-	  darwin_orig_dir=`pwd`
-	  cd $my_xdir || exit $?
-	  darwin_archive=$my_xabs
-	  darwin_curdir=`pwd`
-	  darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
-	  darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
-	  if test -n "$darwin_arches"; then 
-	    darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
-	    darwin_arch=
-	    $show "$darwin_base_archive has multiple architectures $darwin_arches"
-	    for darwin_arch in  $darwin_arches ; do
-	      mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
-	      lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
-	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
-	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
-	      cd "$darwin_curdir"
-	      $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
-	    done # $darwin_arches
-      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
-	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
-	    darwin_file=
-	    darwin_files=
-	    for darwin_file in $darwin_filelist; do
-	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
-	      lipo -create -output "$darwin_file" $darwin_files
-	    done # $darwin_filelist
-	    ${rm}r unfat-$$
-	    cd "$darwin_orig_dir"
-	  else
-	    cd "$darwin_orig_dir"
- 	    func_extract_an_archive "$my_xdir" "$my_xabs"
-	  fi # $darwin_arches
-	fi # $run
-	;;
-      *)
-        func_extract_an_archive "$my_xdir" "$my_xabs"
-        ;;
-      esac
-      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+      # 10*(2^10) chars as input seems more than enough
+      test 10 -lt "$_G_count" && break
     done
-    func_extract_archives_result="$my_oldobjs"
+    rm -f conftest.in conftest.tmp conftest.nl conftest.out
+  }
+
+  func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"
+  rm -f conftest.sed
+  SED=$func_path_progs_result
 }
-# End of Shell function definitions
-#####################################
 
-# Darwin sucks
-eval std_shrext=\"$shrext_cmds\"
 
-disable_libs=no
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+  func_check_prog_grep ()
+  {
+    _G_path_prog=$1
 
-# Parse our command line options once, thoroughly.
-while test "$#" -gt 0
-do
-  arg="$1"
-  shift
+    _G_count=0
+    _G_path_prog_max=0
+    printf 0123456789 >conftest.in
+    while :
+    do
+      cat conftest.in conftest.in >conftest.tmp
+      mv conftest.tmp conftest.in
+      cp conftest.in conftest.nl
+      echo 'GREP' >> conftest.nl
+      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break
+      diff conftest.out conftest.nl >/dev/null 2>&1 || break
+      _G_count=`expr $_G_count + 1`
+      if test "$_G_count" -gt "$_G_path_prog_max"; then
+        # Best one so far, save it but keep looking for a better one
+        func_check_prog_result=$_G_path_prog
+        _G_path_prog_max=$_G_count
+      fi
+      # 10*(2^10) chars as input seems more than enough
+      test 10 -lt "$_G_count" && break
+    done
+    rm -f conftest.in conftest.tmp conftest.nl conftest.out
+  }
 
-  case $arg in
-  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
-  *) optarg= ;;
-  esac
+  func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"
+  GREP=$func_path_progs_result
+}
 
-  # If the previous option needs an argument, assign it.
-  if test -n "$prev"; then
-    case $prev in
-    execute_dlfiles)
-      execute_dlfiles="$execute_dlfiles $arg"
-      ;;
-    tag)
-      tagname="$arg"
-      preserve_args="${preserve_args}=$arg"
 
-      # Check whether tagname contains only valid characters
-      case $tagname in
-      *[!-_A-Za-z0-9,/]*)
-	$echo "$progname: invalid tag name: $tagname" 1>&2
-	exit $EXIT_FAILURE
-	;;
-      esac
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
 
-      case $tagname in
-      CC)
-	# Don't test for the "default" C tag, as we know, it's there, but
-	# not specially marked.
-	;;
-      *)
-	if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
-	  taglist="$taglist $tagname"
-	  # Evaluate the configuration.
-	  eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
-	else
-	  $echo "$progname: ignoring unknown tag $tagname" 1>&2
-	fi
-	;;
-      esac
-      ;;
-    *)
-      eval "$prev=\$arg"
-      ;;
-    esac
+# All uppercase variable names are used for environment variables.  These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
 
-    prev=
-    prevopt=
-    continue
-  fi
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
 
-  # Have we seen a non-optional argument yet?
-  case $arg in
-  --help)
-    show_help=yes
-    ;;
 
-  --version)
-    echo "\
-$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
 
-Copyright (C) 2008  Free Software Foundation, Inc.
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-    exit $?
-    ;;
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
 
-  --config)
-    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
-    # Now print the configurations for the tags.
-    for tagname in $taglist; do
-      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
-    done
-    exit $?
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same.  If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion.  Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+  s/$_G_bs4/&\\
+/g
+  s/^$_G_bs2$_G_dollar/$_G_bs&/
+  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+  s/\n//g"
+
+# require_check_ifs_backslash
+# ---------------------------
+# Check if we can use backslash as IFS='\' separator, and set
+# $check_ifs_backshlash_broken to ':' or 'false'.
+require_check_ifs_backslash=func_require_check_ifs_backslash
+func_require_check_ifs_backslash ()
+{
+  _G_save_IFS=$IFS
+  IFS='\'
+  _G_check_ifs_backshlash='a\\b'
+  for _G_i in $_G_check_ifs_backshlash
+  do
+  case $_G_i in
+  a)
+    check_ifs_backshlash_broken=false
     ;;
-
-  --debug)
-    $echo "$progname: enabling shell trace mode"
-    set -x
-    preserve_args="$preserve_args $arg"
+  '')
+    break
     ;;
-
-  --dry-run | -n)
-    run=:
+  *)
+    check_ifs_backshlash_broken=:
+    break
     ;;
+  esac
+  done
+  IFS=$_G_save_IFS
+  require_check_ifs_backslash=:
+}
 
-  --features)
-    $echo "host: $host"
-    if test "$build_libtool_libs" = yes; then
-      $echo "enable shared libraries"
-    else
-      $echo "disable shared libraries"
-    fi
-    if test "$build_old_libs" = yes; then
-      $echo "enable static libraries"
-    else
-      $echo "disable static libraries"
-    fi
-    exit $?
-    ;;
 
-  --finish) mode="finish" ;;
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
 
-  --mode) prevopt="--mode" prev=mode ;;
-  --mode=*) mode="$optarg" ;;
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
 
-  --preserve-dup-deps) duplicate_deps="yes" ;;
-
-  --quiet | --silent)
-    show=:
-    preserve_args="$preserve_args $arg"
-    ;;
-
-  --tag)
-    prevopt="--tag"
-    prev=tag
-    preserve_args="$preserve_args --tag"
-    ;;
-  --tag=*)
-    set tag "$optarg" ${1+"$@"}
-    shift
-    prev=tag
-    preserve_args="$preserve_args --tag"
-    ;;
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
 
-  -dlopen)
-    prevopt="-dlopen"
-    prev=execute_dlfiles
-    ;;
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
 
-  -*)
-    $echo "$modename: unrecognized option \`$arg'" 1>&2
-    $echo "$help" 1>&2
-    exit $EXIT_FAILURE
-    ;;
+# By convention, finish your script with:
+#
+#    exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
 
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+     progdir=`cd "$progdir" && pwd`
+     progpath=$progdir/$progname
+     ;;
   *)
-    nonopt="$arg"
-    break
-    ;;
-  esac
-done
-
-if test -n "$prevopt"; then
-  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
-  $echo "$help" 1>&2
-  exit $EXIT_FAILURE
-fi
-
-case $disable_libs in
-no) 
-  ;;
-shared)
-  build_libtool_libs=no
-  build_old_libs=yes
-  ;;
-static)
-  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
-  ;;
+     _G_IFS=$IFS
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS=$_G_IFS
+       test -x "$progdir/$progname" && break
+     done
+     IFS=$_G_IFS
+     test -n "$progdir" || progdir=`pwd`
+     progpath=$progdir/$progname
+     ;;
 esac
 
-# If this variable is set in any of the actions, the command in it
-# will be execed at the end.  This prevents here-documents from being
-# left over by shells.
-exec_cmd=
 
-if test -z "$show_help"; then
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
 
-  # Infer the operation mode.
-  if test -z "$mode"; then
-    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
-    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
-    case $nonopt in
-    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
-      mode=link
-      for arg
-      do
-	case $arg in
-	-c)
-	   mode=compile
-	   break
-	   ;;
-	esac
-      done
-      ;;
-    *db | *dbx | *strace | *truss)
-      mode=execute
-      ;;
-    *install*|cp|mv)
-      mode=install
-      ;;
-    *rm)
-      mode=uninstall
-      ;;
-    *)
-      # If we have no mode, but dlfiles were specified, then do execute mode.
-      test -n "$execute_dlfiles" && mode=execute
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
 
-      # Just use the default operation mode.
-      if test -z "$mode"; then
-	if test -n "$nonopt"; then
-	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
-	else
-	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
-	fi
-      fi
-      ;;
-    esac
-  fi
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
 
-  # Only execute mode is allowed to have -dlopen flags.
-  if test -n "$execute_dlfiles" && test "$mode" != execute; then
-    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
-    $echo "$help" 1>&2
-    exit $EXIT_FAILURE
-  fi
+# Categories 'all' and 'none' are always available.  Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
 
-  # Change the help message to a mode-specific one.
-  generic_help="$help"
-  help="Try \`$modename --help --mode=$mode' for more information."
+# By default, display warnings according to 'opt_warning_types'.  Set
+# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
 
-  # These modes are in order of execution frequency so that they run quickly.
-  case $mode in
-  # libtool compile mode
-  compile)
-    modename="$modename: compile"
-    # Get the compilation command and the source file.
-    base_compile=
-    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
-    suppress_opt=yes
-    suppress_output=
-    arg_mode=normal
-    libobj=
-    later=
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
 
-    for arg
-    do
-      case $arg_mode in
-      arg  )
-	# do not "continue".  Instead, add this to base_compile
-	lastarg="$arg"
-	arg_mode=normal
-	;;
 
-      target )
-	libobj="$arg"
-	arg_mode=normal
-	continue
-	;;
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
 
-      normal )
-	# Accept any command-line options.
-	case $arg in
-	-o)
-	  if test -n "$libobj" ; then
-	    $echo "$modename: you cannot specify \`-o' more than once" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  arg_mode=target
-	  continue
-	  ;;
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
 
-	-static | -prefer-pic | -prefer-non-pic)
-	  later="$later $arg"
-	  continue
-	  ;;
 
-	-no-suppress)
-	  suppress_opt=no
-	  continue
-	  ;;
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+    $debug_cmd
+
+    test -t 1 && {
+      # COLORTERM and USE_ANSI_COLORS environment variables take
+      # precedence, because most terminfo databases neglect to describe
+      # whether color sequences are supported.
+      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+      if test 1 = "$USE_ANSI_COLORS"; then
+        # Standard ANSI escape sequences
+        tc_reset=''
+        tc_bold='';   tc_standout=''
+        tc_red='';   tc_green=''
+        tc_blue='';  tc_cyan=''
+      else
+        # Otherwise trust the terminfo database after all.
+        test -n "`tput sgr0 2>/dev/null`" && {
+          tc_reset=`tput sgr0`
+          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+          tc_standout=$tc_bold
+          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+        }
+      fi
+    }
 
-	-Xcompiler)
-	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
-	  continue      #  The current "srcfile" will either be retained or
-	  ;;            #  replaced later.  I would guess that would be a bug.
+    require_term_colors=:
+}
 
-	-Wc,*)
-	  args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
-	  lastarg=
-	  save_ifs="$IFS"; IFS=','
- 	  for arg in $args; do
-	    IFS="$save_ifs"
-
-	    # Double-quote args containing other shell metacharacters.
-	    # Many Bourne shells cannot handle close brackets correctly
-	    # in scan sets, so we specify it separately.
-	    case $arg in
-	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	      arg="\"$arg\""
-	      ;;
-	    esac
-	    lastarg="$lastarg $arg"
-	  done
-	  IFS="$save_ifs"
-	  lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
 
-	  # Add the arguments to base_compile.
-	  base_compile="$base_compile $lastarg"
-	  continue
-	  ;;
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
 
-	* )
-	  # Accept the current argument as the source file.
-	  # The previous "srcfile" becomes the current argument.
-	  #
-	  lastarg="$srcfile"
-	  srcfile="$arg"
-	  ;;
-	esac  #  case $arg
-	;;
-      esac    #  case $arg_mode
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
 
-      # Aesthetically quote the previous argument.
-      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
-
-      case $lastarg in
-      # Double-quote args containing other shell metacharacters.
-      # Many Bourne shells cannot handle close brackets correctly
-      # in scan sets, and some SunOS ksh mistreat backslash-escaping
-      # in scan sets (worked around with variable expansion),
-      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
-      # at all, so we specify them separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	lastarg="\"$lastarg\""
-	;;
-      esac
 
-      base_compile="$base_compile $lastarg"
-    done # for arg
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
 
-    case $arg_mode in
-    arg)
-      $echo "$modename: you must specify an argument for -Xcompile"
-      exit $EXIT_FAILURE
-      ;;
-    target)
-      $echo "$modename: you must specify a target with \`-o'" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    *)
-      # Get the name of the library object.
-      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
-      ;;
+  # We should try to minimise forks, especially on Windows where they are
+  # unreasonably slow, so skip the feature probes when bash or zsh are
+  # being used:
+  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+    : ${_G_HAVE_ARITH_OP="yes"}
+    : ${_G_HAVE_XSI_OPS="yes"}
+    # The += operator was introduced in bash 3.1
+    case $BASH_VERSION in
+      [12].* | 3.0 | 3.0*) ;;
+      *)
+        : ${_G_HAVE_PLUSEQ_OP="yes"}
+        ;;
     esac
+  fi
 
-    # Recognize several different file suffixes.
-    # If the user specifies -o file.o, it is replaced with file.lo
-    xform='[cCFSifmso]'
-    case $libobj in
-    *.ada) xform=ada ;;
-    *.adb) xform=adb ;;
-    *.ads) xform=ads ;;
-    *.asm) xform=asm ;;
-    *.c++) xform=c++ ;;
-    *.cc) xform=cc ;;
-    *.ii) xform=ii ;;
-    *.class) xform=class ;;
-    *.cpp) xform=cpp ;;
-    *.cxx) xform=cxx ;;
-    *.[fF][09]?) xform=[fF][09]. ;;
-    *.for) xform=for ;;
-    *.java) xform=java ;;
-    *.obj) xform=obj ;;
-    *.sx) xform=sx ;;
-    esac
+  # _G_HAVE_PLUSEQ_OP
+  # Can be empty, in which case the shell is probed, "yes" if += is
+  # usable or anything else if it does not work.
+  test -z "$_G_HAVE_PLUSEQ_OP" \
+    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+    && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_append ()
+  {
+    $debug_cmd
 
-    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+    eval "$1+=\$2"
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_append ()
+  {
+    $debug_cmd
 
-    case $libobj in
-    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
-    *)
-      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    esac
+    eval "$1=\$$1\$2"
+  }
+fi
 
-    func_infer_tag $base_compile
 
-    for arg in $later; do
-      case $arg in
-      -shared)
-	test yes = "$build_libtool_libs" \
-	  || func_fatal_configuration "cannot build a shared library"
-	build_old_libs=no
-	continue
-	;;
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+  eval 'func_append_quoted ()
+  {
+    $debug_cmd
 
-      -static)
-	build_old_libs=yes
-	continue
-	;;
+    func_quote_arg pretty "$2"
+    eval "$1+=\\ \$func_quote_arg_result"
+  }'
+else
+  func_append_quoted ()
+  {
+    $debug_cmd
 
-      -prefer-pic)
-	pic_mode=yes
-	continue
-	;;
+    func_quote_arg pretty "$2"
+    eval "$1=\$$1\\ \$func_quote_arg_result"
+  }
+fi
 
-      -prefer-non-pic)
-	pic_mode=no
-	continue
-	;;
-      esac
-    done
 
-    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
-    case $qlibobj in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	qlibobj="\"$qlibobj\"" ;;
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE.  For example:
+#
+#   func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+    $debug_cmd
+
+    eval _G_current_value='`$ECHO $'$1'`'
+    _G_delim=`expr "$2" : '\(.\)'`
+
+    case $_G_delim$_G_current_value$_G_delim in
+      *"$2$_G_delim"*) ;;
+      *) func_append "$@" ;;
     esac
-    test "X$libobj" != "X$qlibobj" \
-	&& $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' 	&()|`$[]' \
-	&& $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
-    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
-    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
-    if test "X$xdir" = "X$obj"; then
-      xdir=
-    else
-      xdir=$xdir/
-    fi
-    lobj=${xdir}$objdir/$objname
+}
 
-    if test -z "$base_compile"; then
-      $echo "$modename: you must specify a compilation command" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
 
-    # Delete any leftover library objects.
-    if test "$build_old_libs" = yes; then
-      removelist="$obj $lobj $libobj ${libobj}T"
-    else
-      removelist="$lobj $libobj ${libobj}T"
-    fi
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+  test -z "$_G_HAVE_ARITH_OP" \
+    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+    && _G_HAVE_ARITH_OP=yes
 
-    $run $rm $removelist
-    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+if test yes = "$_G_HAVE_ARITH_OP"; then
+  eval 'func_arith ()
+  {
+    $debug_cmd
 
-    # On Cygwin there's no "real" PIC flag so we must build both object types
-    case $host_os in
-    cygwin* | mingw* | pw32* | os2*)
-      pic_mode=default
-      ;;
-    esac
-    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
-      # non-PIC code in shared libraries is not supported
-      pic_mode=default
-    fi
+    func_arith_result=$(( $* ))
+  }'
+else
+  func_arith ()
+  {
+    $debug_cmd
 
-    # Calculate the filename of the output object if compiler does
-    # not support -o with -c
-    if test "$compiler_c_o" = no; then
-      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
-      lockfile="$output_obj.lock"
-      removelist="$removelist $output_obj $lockfile"
-      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
-    else
-      output_obj=
-      need_locks=no
-      lockfile=
-    fi
+    func_arith_result=`expr "$@"`
+  }
+fi
 
-    # Lock this critical section if it is needed
-    # We use this script file to make the link, it avoids creating a new file
-    if test "$need_locks" = yes; then
-      until $run ln "$progpath" "$lockfile" 2>/dev/null; do
-	$show "Waiting for $lockfile to be removed"
-	sleep 2
-      done
-    elif test "$need_locks" = warn; then
-      if test -f "$lockfile"; then
-	$echo "\
-*** ERROR, $lockfile exists and contains:
-`cat $lockfile 2>/dev/null`
 
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  # If this shell supports suffix pattern removal, then use it to avoid
+  # forking. Hide the definitions single quotes in case the shell chokes
+  # on unsupported syntax...
+  _b='func_basename_result=${1##*/}'
+  _d='case $1 in
+        */*) func_dirname_result=${1%/*}$2 ;;
+        *  ) func_dirname_result=$3        ;;
+      esac'
 
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
-      $echo "$srcfile" > "$lockfile"
-    fi
+else
+  # ...otherwise fall back to using sed.
+  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`
+      if test "X$func_dirname_result" = "X$1"; then
+        func_dirname_result=$3
+      else
+        func_append func_dirname_result "$2"
+      fi'
+fi
 
-    if test -n "$fix_srcfile_path"; then
-      eval srcfile=\"$fix_srcfile_path\"
-    fi
-    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
-    case $qsrcfile in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-      qsrcfile="\"$qsrcfile\"" ;;
-    esac
+eval 'func_basename ()
+{
+    $debug_cmd
 
-    $run $rm "$libobj" "${libobj}T"
+    '"$_b"'
+}'
 
-    # Create a libtool object file (analogous to a ".la" file),
-    # but don't create it if we're doing a dry run.
-    test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then
-	$echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
 
-but it should contain:
-$srcfile
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
 
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
 
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+    $debug_cmd
 
-      # Just move the object if needed, then go on to compile the next one
-      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
-	$show "$mv $output_obj $lobj"
-	if $run $mv $output_obj $lobj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
+    $require_term_colors
 
-      # Append the name of the PIC object to the libtool object file.
-      test -z "$run" && cat >> ${libobj}T <&2
+      _G_prefix=$_G_indent
+    done
+    IFS=$func_echo_infix_1_IFS
+}
 
-      # Allow error messages only from the first compilation.
-      if test "$suppress_opt" = yes; then
-        suppress_output=' >/dev/null 2>&1'
-      fi
-    else
-      # No PIC object so indicate it doesn't exist in the libtool
-      # object file.
-      test -z "$run" && cat >> ${libobj}T <&2
+}
 
-      if test "$need_locks" = warn &&
-	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
-	$echo "\
-*** ERROR, $lockfile contains:
-`cat $lockfile 2>/dev/null`
 
-but it should contain:
-$srcfile
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    $debug_cmd
 
-This indicates that another process is trying to use the same
-temporary object file, and libtool could not work around it because
-your compiler does not support \`-c' and \`-o' together.  If you
-repeat this compilation, it may succeed, by chance, but you had better
-avoid parallel builds (make -j) in this platform, or get a better
-compiler."
+    func_error "$*"
+    exit $EXIT_FAILURE
+}
 
-	$run $rm $removelist
-	exit $EXIT_FAILURE
-      fi
 
-      # Just move the object if needed
-      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
-	$show "$mv $output_obj $obj"
-	if $run $mv $output_obj $obj; then :
-	else
-	  error=$?
-	  $run $rm $removelist
-	  exit $error
-	fi
-      fi
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $debug_cmd
 
-      # Append the name of the non-PIC object the libtool object file.
-      # Only append if the libtool object file exists.
-      test -z "$run" && cat >> ${libobj}T </dev/null 2>&1
+}
 
-EOF
-    else
-      # Append the name of the non-PIC object the libtool object file.
-      # Only append if the libtool object file exists.
-      test -z "$run" && cat >> ${libobj}T </dev/null \
+    && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_len ()
+  {
+    $debug_cmd
+
+    func_len_result=${#1}
+  }'
+else
+  func_len ()
+  {
+    $debug_cmd
+
+    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+  }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    $debug_cmd
+
+    _G_directory_path=$1
+    _G_dir_list=
+
+    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+      # Protect directory names starting with '-'
+      case $_G_directory_path in
+        -*) _G_directory_path=./$_G_directory_path ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$_G_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list in case some portion of path contains whitespace.
+        _G_dir_list=$_G_directory_path:$_G_dir_list
+
+        # If the last portion added has no slash in it, the list is done
+        case $_G_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+      done
+      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+      func_mkdir_p_IFS=$IFS; IFS=:
+      for _G_dir in $_G_dir_list; do
+	IFS=$func_mkdir_p_IFS
+        # mkdir can fail with a 'File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$_G_dir" 2>/dev/null || :
+      done
+      IFS=$func_mkdir_p_IFS
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$_G_directory_path" || \
+        func_fatal_error "Failed to create '$1'"
     fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+    $debug_cmd
+
+    _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+    if test : = "$opt_dry_run"; then
+      # Return a directory name, but don't create it in dry-run mode
+      _G_tmpdir=$_G_template-$$
+    else
+
+      # If mktemp works, use that first and foremost
+      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
 
-    $run $mv "${libobj}T" "${libobj}"
+      if test ! -d "$_G_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        _G_tmpdir=$_G_template-${RANDOM-0}$$
 
-    # Unlock the critical section if it was locked
-    if test "$need_locks" != no; then
-      $run $rm "$lockfile"
+        func_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$_G_tmpdir"
+        umask $func_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$_G_tmpdir" || \
+        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
     fi
 
-    exit $EXIT_SUCCESS
-    ;;
+    $ECHO "$_G_tmpdir"
+}
 
-  # libtool link mode
-  link | relink)
-    modename="$modename: link"
-    case $host in
-    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-      # It is impossible to link a dll without this setting, and
-      # we shouldn't force the makefile maintainer to figure out
-      # which system we are compiling for in order to pass an extra
-      # flag for every libtool invocation.
-      # allow_undefined=no
 
-      # FIXME: Unfortunately, there are problems with the above when trying
-      # to make a dll which has undefined symbols, in which case not
-      # even a static library is built.  For now, we need to specify
-      # -no-undefined on the libtool link line when we can be certain
-      # that all symbols are satisfied, otherwise we get a static library.
-      allow_undefined=yes
-      ;;
-    *)
-      allow_undefined=yes
-      ;;
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+    $debug_cmd
+
+    # These SED scripts presuppose an absolute path with a trailing slash.
+    _G_pathcar='s|^/\([^/]*\).*$|\1|'
+    _G_pathcdr='s|^/[^/]*||'
+    _G_removedotparts=':dotsl
+		s|/\./|/|g
+		t dotsl
+		s|/\.$|/|'
+    _G_collapseslashes='s|/\{1,\}|/|g'
+    _G_finalslash='s|/*$|/|'
+
+    # Start from root dir and reassemble the path.
+    func_normal_abspath_result=
+    func_normal_abspath_tpath=$1
+    func_normal_abspath_altnamespace=
+    case $func_normal_abspath_tpath in
+      "")
+        # Empty path, that just means $cwd.
+        func_stripname '' '/' "`pwd`"
+        func_normal_abspath_result=$func_stripname_result
+        return
+        ;;
+      # The next three entries are used to spot a run of precisely
+      # two leading slashes without using negated character classes;
+      # we take advantage of case's first-match behaviour.
+      ///*)
+        # Unusual form of absolute path, do nothing.
+        ;;
+      //*)
+        # Not necessarily an ordinary path; POSIX reserves leading '//'
+        # and for example Cygwin uses it to access remote file shares
+        # over CIFS/SMB, so we conserve a leading double slash if found.
+        func_normal_abspath_altnamespace=/
+        ;;
+      /*)
+        # Absolute path, do nothing.
+        ;;
+      *)
+        # Relative path, prepend $cwd.
+        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+        ;;
     esac
-    libtool_args="$nonopt"
-    base_compile="$nonopt $@"
-    compile_command="$nonopt"
-    finalize_command="$nonopt"
 
-    compile_rpath=
-    finalize_rpath=
-    compile_shlibpath=
-    finalize_shlibpath=
-    convenience=
-    old_convenience=
-    deplibs=
-    old_deplibs=
-    compiler_flags=
-    linker_flags=
-    dllsearchpath=
-    lib_search_path=`pwd`
-    inst_prefix_dir=
+    # Cancel out all the simple stuff to save iterations.  We also want
+    # the path to end with a slash for ease of parsing, so make sure
+    # there is one (and only one) here.
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+    while :; do
+      # Processed it all yet?
+      if test / = "$func_normal_abspath_tpath"; then
+        # If we ascended to the root using ".." the result may be empty now.
+        if test -z "$func_normal_abspath_result"; then
+          func_normal_abspath_result=/
+        fi
+        break
+      fi
+      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_pathcar"`
+      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+          -e "$_G_pathcdr"`
+      # Figure out what to do with it
+      case $func_normal_abspath_tcomponent in
+        "")
+          # Trailing empty path component, ignore it.
+          ;;
+        ..)
+          # Parent dir; strip last assembled component from result.
+          func_dirname "$func_normal_abspath_result"
+          func_normal_abspath_result=$func_dirname_result
+          ;;
+        *)
+          # Actual path component, append it.
+          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+          ;;
+      esac
+    done
+    # Restore leading double-slash if one was found on entry.
+    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
 
-    avoid_version=no
-    dlfiles=
-    dlprefiles=
-    dlself=no
-    export_dynamic=no
-    export_symbols=
-    export_symbols_regex=
-    generated=
-    libobjs=
-    ltlibs=
-    module=no
-    no_install=no
-    objs=
-    non_pic_objects=
-    notinst_path= # paths that contain not-installed libtool libraries
-    precious_files_regex=
-    prefer_static_libs=no
-    preload=no
-    prev=
-    prevarg=
-    release=
-    rpath=
-    xrpath=
-    perm_rpath=
-    temp_rpath=
-    thread_safe=no
-    vinfo=
-    vinfo_number=no
-    single_module="${wl}-single_module"
 
-    func_infer_tag $base_compile
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+    $debug_cmd
 
-    # We need to know -static, to get the right output filenames.
-    for arg
-    do
-      case $arg in
-      -shared)
-	test yes != "$build_libtool_libs" \
-	  && func_fatal_configuration "cannot build a shared library"
-	build_old_libs=no
-	break
-	;;
-      -all-static | -static | -static-libtool-libs)
-	case $arg in
-	-all-static)
-	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
-	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
-	  fi
-	  if test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=yes
-	  ;;
-	-static)
-	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=built
-	  ;;
-	-static-libtool-libs)
-	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
-	    dlopen_self=$dlopen_self_static
-	  fi
-	  prefer_static_libs=yes
-	  ;;
-	esac
-	build_libtool_libs=no
-	build_old_libs=yes
-	break
-	;;
+    $opt_quiet || func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+    $debug_cmd
+
+    func_relative_path_result=
+    func_normal_abspath "$1"
+    func_relative_path_tlibdir=$func_normal_abspath_result
+    func_normal_abspath "$2"
+    func_relative_path_tbindir=$func_normal_abspath_result
+
+    # Ascend the tree starting from libdir
+    while :; do
+      # check if we have found a prefix of bindir
+      case $func_relative_path_tbindir in
+        $func_relative_path_tlibdir)
+          # found an exact match
+          func_relative_path_tcancelled=
+          break
+          ;;
+        $func_relative_path_tlibdir*)
+          # found a matching prefix
+          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+          func_relative_path_tcancelled=$func_stripname_result
+          if test -z "$func_relative_path_result"; then
+            func_relative_path_result=.
+          fi
+          break
+          ;;
+        *)
+          func_dirname $func_relative_path_tlibdir
+          func_relative_path_tlibdir=$func_dirname_result
+          if test -z "$func_relative_path_tlibdir"; then
+            # Have to descend all the way to the root!
+            func_relative_path_result=../$func_relative_path_result
+            func_relative_path_tcancelled=$func_relative_path_tbindir
+            break
+          fi
+          func_relative_path_result=../$func_relative_path_result
+          ;;
       esac
     done
 
-    # See if our shared archives depend on static archives.
-    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+    # Now calculate path; take care to avoid doubling-up slashes.
+    func_stripname '' '/' "$func_relative_path_result"
+    func_relative_path_result=$func_stripname_result
+    func_stripname '/' '/' "$func_relative_path_tcancelled"
+    if test -n "$func_stripname_result"; then
+      func_append func_relative_path_result "/$func_stripname_result"
+    fi
 
-    # Go through the arguments, transforming them on the way.
-    while test "$#" -gt 0; do
-      arg="$1"
-      shift
-      case $arg in
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
-	;;
-      *) qarg=$arg ;;
-      esac
-      libtool_args="$libtool_args $qarg"
+    # Normalisation. If bindir is libdir, return '.' else relative path.
+    if test -n "$func_relative_path_result"; then
+      func_stripname './' '' "$func_relative_path_result"
+      func_relative_path_result=$func_stripname_result
+    fi
 
-      # If the previous option needs an argument, assign it.
-      if test -n "$prev"; then
-	case $prev in
-	output)
-	  compile_command="$compile_command @OUTPUT@"
-	  finalize_command="$finalize_command @OUTPUT@"
-	  ;;
-	esac
+    test -n "$func_relative_path_result" || func_relative_path_result=.
 
-	case $prev in
-	dlfiles|dlprefiles)
-	  if test "$preload" = no; then
-	    # Add the symbol object into the linking commands.
-	    compile_command="$compile_command @SYMFILE@"
-	    finalize_command="$finalize_command @SYMFILE@"
-	    preload=yes
-	  fi
-	  case $arg in
-	  *.la | *.lo) ;;  # We handle these cases below.
-	  force)
-	    if test "$dlself" = no; then
-	      dlself=needless
-	      export_dynamic=yes
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  self)
-	    if test "$prev" = dlprefiles; then
-	      dlself=yes
-	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
-	      dlself=yes
-	    else
-	      dlself=needless
-	      export_dynamic=yes
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  *)
-	    if test "$prev" = dlfiles; then
-	      dlfiles="$dlfiles $arg"
-	    else
-	      dlprefiles="$dlprefiles $arg"
-	    fi
-	    prev=
-	    continue
-	    ;;
-	  esac
-	  ;;
-	expsyms)
-	  export_symbols="$arg"
-	  if test ! -f "$arg"; then
-	    $echo "$modename: symbol file \`$arg' does not exist"
-	    exit $EXIT_FAILURE
-	  fi
-	  prev=
-	  continue
-	  ;;
-	expsyms_regex)
-	  export_symbols_regex="$arg"
-	  prev=
-	  continue
-	  ;;
-	inst_prefix)
-	  inst_prefix_dir="$arg"
-	  prev=
-	  continue
-	  ;;
-	precious_regex)
-	  precious_files_regex="$arg"
-	  prev=
-	  continue
-	  ;;
-	release)
-	  release="-$arg"
-	  prev=
-	  continue
-	  ;;
-	objectlist)
-	  if test -f "$arg"; then
-	    save_arg=$arg
-	    moreargs=
-	    for fil in `cat $save_arg`
-	    do
-#	      moreargs="$moreargs $fil"
-	      arg=$fil
-	      # A libtool-controlled object.
+    :
+}
 
-	      # Check to see that this really is a libtool object.
-	      if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-		pic_object=
-		non_pic_object=
 
-		# Read the .lo file
-		# If there is no directory component, then add one.
-		case $arg in
-		*/* | *\\*) . $arg ;;
-		*) . ./$arg ;;
-		esac
+# func_quote_portable EVAL ARG
+# ----------------------------
+# Internal function to portably implement func_quote_arg.  Note that we still
+# keep attention to performance here so we as much as possible try to avoid
+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
+func_quote_portable ()
+{
+    $debug_cmd
 
-		if test -z "$pic_object" || \
-		   test -z "$non_pic_object" ||
-		   test "$pic_object" = none && \
-		   test "$non_pic_object" = none; then
-		  $echo "$modename: cannot find name of object for \`$arg'" 1>&2
-		  exit $EXIT_FAILURE
-		fi
+    $require_check_ifs_backslash
 
-		# Extract subdirectory from the argument.
-		xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-		if test "X$xdir" = "X$arg"; then
-		  xdir=
-		else
-		  xdir="$xdir/"
-		fi
+    func_quote_portable_result=$2
 
-		if test "$pic_object" != none; then
-		  # Prepend the subdirectory the object is found in.
-		  pic_object="$xdir$pic_object"
+    # one-time-loop (easy break)
+    while true
+    do
+      if $1; then
+        func_quote_portable_result=`$ECHO "$2" | $SED \
+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
+        break
+      fi
 
-		  if test "$prev" = dlfiles; then
-		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-		      dlfiles="$dlfiles $pic_object"
-		      prev=
-		      continue
-		    else
-		      # If libtool objects are unsupported, then we need to preload.
-		      prev=dlprefiles
-		    fi
-		  fi
+      # Quote for eval.
+      case $func_quote_portable_result in
+        *[\\\`\"\$]*)
+          # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string
+          # contains the shell wildcard characters.
+          case $check_ifs_backshlash_broken$func_quote_portable_result in
+            :*|*[\[\*\?]*)
+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
+                  | $SED "$sed_quote_subst"`
+              break
+              ;;
+          esac
 
-		  # CHECK ME:  I think I busted this.  -Ossama
-		  if test "$prev" = dlprefiles; then
-		    # Preload the old-style object.
-		    dlprefiles="$dlprefiles $pic_object"
-		    prev=
-		  fi
+          func_quote_portable_old_IFS=$IFS
+          for _G_char in '\' '`' '"' '$'
+          do
+            # STATE($1) PREV($2) SEPARATOR($3)
+            set start "" ""
+            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
+            IFS=$_G_char
+            for _G_part in $func_quote_portable_result
+            do
+              case $1 in
+              quote)
+                func_append func_quote_portable_result "$3$2"
+                set quote "$_G_part" "\\$_G_char"
+                ;;
+              start)
+                set first "" ""
+                func_quote_portable_result=
+                ;;
+              first)
+                set quote "$_G_part" ""
+                ;;
+              esac
+            done
+          done
+          IFS=$func_quote_portable_old_IFS
+          ;;
+        *) ;;
+      esac
+      break
+    done
 
-		  # A PIC object.
-		  libobjs="$libobjs $pic_object"
-		  arg="$pic_object"
-		fi
+    func_quote_portable_unquoted_result=$func_quote_portable_result
+    case $func_quote_portable_result in
+      # double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and variable expansion
+      # for a subsequent eval.
+      # many bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_portable_result=\"$func_quote_portable_result\"
+        ;;
+    esac
+}
 
-		# Non-PIC object.
-		if test "$non_pic_object" != none; then
-		  # Prepend the subdirectory the object is found in.
-		  non_pic_object="$xdir$non_pic_object"
 
-		  # A standard non-PIC object
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		  if test -z "$pic_object" || test "$pic_object" = none ; then
-		    arg="$non_pic_object"
-		  fi
-		else
-		  # If the PIC object exists, use it instead.
-		  # $xdir was prepended to $pic_object above.
-		  non_pic_object="$pic_object"
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		fi
-	      else
-		# Only an error if not doing a dry-run.
-		if test -z "$run"; then
-		  $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
-		  exit $EXIT_FAILURE
-		else
-		  # Dry-run case.
+# func_quotefast_eval ARG
+# -----------------------
+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
+# but optimized for speed.  Result is stored in $func_quotefast_eval.
+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
+  printf -v _GL_test_printf_tilde %q '~'
+  if test '\~' = "$_GL_test_printf_tilde"; then
+    func_quotefast_eval ()
+    {
+      printf -v func_quotefast_eval_result %q "$1"
+    }
+  else
+    # Broken older Bash implementations.  Make those faster too if possible.
+    func_quotefast_eval ()
+    {
+      case $1 in
+        '~'*)
+          func_quote_portable false "$1"
+          func_quotefast_eval_result=$func_quote_portable_result
+          ;;
+        *)
+          printf -v func_quotefast_eval_result %q "$1"
+          ;;
+      esac
+    }
+  fi
+else
+  func_quotefast_eval ()
+  {
+    func_quote_portable false "$1"
+    func_quotefast_eval_result=$func_quote_portable_result
+  }
+fi
 
-		  # Extract subdirectory from the argument.
-		  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-		  if test "X$xdir" = "X$arg"; then
-		    xdir=
-		  else
-		    xdir="$xdir/"
-		  fi
 
-		  pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
-		  non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
-		  libobjs="$libobjs $pic_object"
-		  non_pic_objects="$non_pic_objects $non_pic_object"
-		fi
-	      fi
-	    done
-	  else
-	    $echo "$modename: link input file \`$save_arg' does not exist"
-	    exit $EXIT_FAILURE
-	  fi
-	  arg=$save_arg
-	  prev=
-	  continue
-	  ;;
-	rpath | xrpath)
-	  # We need an absolute path.
-	  case $arg in
-	  [\\/]* | [A-Za-z]:[\\/]*) ;;
-	  *)
-	    $echo "$modename: only absolute run-paths are allowed" 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	  if test "$prev" = rpath; then
-	    case "$rpath " in
-	    *" $arg "*) ;;
-	    *) rpath="$rpath $arg" ;;
-	    esac
-	  else
-	    case "$xrpath " in
-	    *" $arg "*) ;;
-	    *) xrpath="$xrpath $arg" ;;
-	    esac
-	  fi
-	  prev=
-	  continue
-	  ;;
-	xcompiler)
-	  compiler_flags="$compiler_flags $qarg"
-	  prev=
-	  compile_command="$compile_command $qarg"
-	  finalize_command="$finalize_command $qarg"
-	  continue
-	  ;;
-	xlinker)
-	  linker_flags="$linker_flags $qarg"
-	  compiler_flags="$compiler_flags $wl$qarg"
-	  prev=
-	  compile_command="$compile_command $wl$qarg"
-	  finalize_command="$finalize_command $wl$qarg"
-	  continue
-	  ;;
-	xcclinker)
-	  linker_flags="$linker_flags $qarg"
-	  compiler_flags="$compiler_flags $qarg"
-	  prev=
-	  compile_command="$compile_command $qarg"
-	  finalize_command="$finalize_command $qarg"
-	  continue
-	  ;;
-	shrext)
-  	  shrext_cmds="$arg"
-	  prev=
-	  continue
-	  ;;
-	darwin_framework|darwin_framework_skip)
-	  test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
-	  compile_command="$compile_command $arg"
-	  finalize_command="$finalize_command $arg"
-	  prev=
-	  continue
-	  ;;
-	*)
-	  eval "$prev=\"\$arg\""
-	  prev=
-	  continue
-	  ;;
-	esac
-      fi # test -n "$prev"
+# func_quote_arg MODEs ARG
+# ------------------------
+# Quote one ARG to be evaled later.  MODEs argument may contain zero or more
+# specifiers listed below separated by ',' character.  This function returns two
+# values:
+#   i) func_quote_arg_result
+#      double-quoted (when needed), suitable for a subsequent eval
+#  ii) func_quote_arg_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.  Available only if 'unquoted' is specified.
+#
+# Available modes:
+# ----------------
+# 'eval' (default)
+#       - escape shell special characters
+# 'expand'
+#       - the same as 'eval';  but do not quote variable references
+# 'pretty'
+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
+#         be used later in func_quote to get output like: 'echo "a b"' instead
+#         of 'echo a\ b'.  This is slower than default on some shells.
+# 'unquoted'
+#       - produce also $func_quote_arg_unquoted_result which does not contain
+#         wrapping double-quotes.
+#
+# Examples for 'func_quote_arg pretty,unquoted string':
+#
+#   string      | *_result              | *_unquoted_result
+#   ------------+-----------------------+-------------------
+#   "           | \"                    | \"
+#   a b         | "a b"                 | a b
+#   "a b"       | "\"a b\""             | \"a b\"
+#   *           | "*"                   | *
+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
+#
+# Examples for 'func_quote_arg pretty,unquoted,expand string':
+#
+#   string        |   *_result          |  *_unquoted_result
+#   --------------+---------------------+--------------------
+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
+func_quote_arg ()
+{
+    _G_quote_expand=false
+    case ,$1, in
+      *,expand,*)
+        _G_quote_expand=:
+        ;;
+    esac
 
-      prevarg="$arg"
+    case ,$1, in
+      *,pretty,*|*,expand,*|*,unquoted,*)
+        func_quote_portable $_G_quote_expand "$2"
+        func_quote_arg_result=$func_quote_portable_result
+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
+        ;;
+      *)
+        # Faster quote-for-eval for some shells.
+        func_quotefast_eval "$2"
+        func_quote_arg_result=$func_quotefast_eval_result
+        ;;
+    esac
+}
 
-      case $arg in
-      -all-static)
-	if test -n "$link_static_flag"; then
-	  compile_command="$compile_command $link_static_flag"
-	  finalize_command="$finalize_command $link_static_flag"
-	fi
-	continue
-	;;
 
-      -allow-undefined)
-	# FIXME: remove this flag sometime in the future.
-	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
-	continue
-	;;
+# func_quote MODEs ARGs...
+# ------------------------
+# Quote all ARGs to be evaled later and join them into single command.  See
+# func_quote_arg's description for more info.
+func_quote ()
+{
+    $debug_cmd
+    _G_func_quote_mode=$1 ; shift
+    func_quote_result=
+    while test 0 -lt $#; do
+      func_quote_arg "$_G_func_quote_mode" "$1"
+      if test -n "$func_quote_result"; then
+        func_append func_quote_result " $func_quote_arg_result"
+      else
+        func_append func_quote_result "$func_quote_arg_result"
+      fi
+      shift
+    done
+}
 
-      -avoid-version)
-	avoid_version=yes
-	continue
-	;;
 
-      -dlopen)
-	prev=dlfiles
-	continue
-	;;
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_stripname ()
+  {
+    $debug_cmd
+
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary variable first.
+    func_stripname_result=$3
+    func_stripname_result=${func_stripname_result#"$1"}
+    func_stripname_result=${func_stripname_result%"$2"}
+  }'
+else
+  func_stripname ()
+  {
+    $debug_cmd
 
-      -dlpreopen)
-	prev=dlprefiles
-	continue
-	;;
+    case $2 in
+      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+    esac
+  }
+fi
 
-      -export-dynamic)
-	export_dynamic=yes
-	continue
-	;;
 
-      -export-symbols | -export-symbols-regex)
-	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	  $echo "$modename: more than one -exported-symbols argument is not allowed"
-	  exit $EXIT_FAILURE
-	fi
-	if test "X$arg" = "X-export-symbols"; then
-	  prev=expsyms
-	else
-	  prev=expsyms_regex
-	fi
-	continue
-	;;
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    $debug_cmd
 
-      -framework|-arch|-isysroot)
-	case " $CC " in
-	  *" ${arg} ${1} "* | *" ${arg}	${1} "*) 
-		prev=darwin_framework_skip ;;
-	  *) compiler_flags="$compiler_flags $arg"
-	     prev=darwin_framework ;;
-	esac
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-	continue
-	;;
+    _G_cmd=$1
+    _G_fail_exp=${2-':'}
 
-      -inst-prefix-dir)
-	prev=inst_prefix
-	continue
-	;;
+    func_quote_arg pretty,expand "$_G_cmd"
+    eval "func_notquiet $func_quote_arg_result"
 
-      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
-      # so, if we see these flags be careful not to treat them like -L
-      -L[A-Z][A-Z]*:*)
-	case $with_gcc/$host in
-	no/*-*-irix* | /*-*-irix*)
-	  compile_command="$compile_command $arg"
-	  finalize_command="$finalize_command $arg"
-	  ;;
-	esac
-	continue
-	;;
+    $opt_dry_run || {
+      eval "$_G_cmd"
+      _G_status=$?
+      if test 0 -ne "$_G_status"; then
+	eval "(exit $_G_status); $_G_fail_exp"
+      fi
+    }
+}
 
-      -L*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
-	# We need an absolute path.
-	case $dir in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  absdir=`cd "$dir" && pwd`
-	  if test -z "$absdir"; then
-	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
-	    absdir="$dir"
-	    notinst_path="$notinst_path $dir"
-	  fi
-	  dir="$absdir"
-	  ;;
-	esac
-	case "$deplibs " in
-	*" -L$dir "*) ;;
-	*)
-	  deplibs="$deplibs -L$dir"
-	  lib_search_path="$lib_search_path $dir"
-	  ;;
-	esac
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-	  testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
-	  case :$dllsearchpath: in
-	  *":$dir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$dir";;
-	  esac
-	  case :$dllsearchpath: in
-	  *":$testbindir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
-	  esac
-	  ;;
-	esac
-	continue
-	;;
 
-      -l*)
-	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
-	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
-	    # These systems don't actually have a C or math library (as such)
-	    continue
-	    ;;
-	  *-*-os2*)
-	    # These systems don't actually have a C library (as such)
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	    # Do not include libc due to us having libc/libc_r.
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-rhapsody* | *-*-darwin1.[012])
-	    # Rhapsody C and math libraries are in the System framework
-	    deplibs="$deplibs -framework System"
-	    continue
-	    ;;
-	  *-*-sco3.2v5* | *-*-sco5v6*)
-	    # Causes problems with __ctype
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
-	    # Compiler inserts libc in the correct place for threads to work
-	    test "X$arg" = "X-lc" && continue
-	    ;;
-	  esac
-	elif test "X$arg" = "X-lc_r"; then
-	 case $host in
-	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	   # Do not include libc_r directly, use -pthread flag.
-	   continue
-	   ;;
-	 esac
-	fi
-	deplibs="$deplibs $arg"
-	continue
-	;;
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    $debug_cmd
 
-      # Tru64 UNIX uses -model [arg] to determine the layout of C++
-      # classes, name mangling, and exception handling.
-      -model)
-	compile_command="$compile_command $arg"
-	compiler_flags="$compiler_flags $arg"
-	finalize_command="$finalize_command $arg"
-	prev=xcompiler
-	continue
-	;;
+    _G_cmd=$1
+    _G_fail_exp=${2-':'}
 
-     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
-	compiler_flags="$compiler_flags $arg"
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-	continue
-	;;
+    $opt_quiet || {
+      func_quote_arg expand,pretty "$_G_cmd"
+      eval "func_echo $func_quote_arg_result"
+    }
 
-      -multi_module)
-	single_module="${wl}-multi_module"
-	continue
-	;;
+    $opt_dry_run || {
+      eval "$_G_user_locale
+	    $_G_cmd"
+      _G_status=$?
+      eval "$_G_safe_locale"
+      if test 0 -ne "$_G_status"; then
+	eval "(exit $_G_status); $_G_fail_exp"
+      fi
+    }
+}
 
-      -module)
-	module=yes
-	continue
-	;;
 
-      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
-      # -r[0-9][0-9]* specifies the processor on the SGI compiler
-      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
-      # +DA*, +DD* enable 64-bit mode on the HP compiler
-      # -q* pass through compiler args for the IBM compiler
-      # -m* pass through architecture-specific compiler args for GCC
-      # -m*, -t[45]*, -txscale* pass through architecture-specific
-      # compiler args for GCC
-      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
-      # -F/path gives path to uninstalled frameworks, gcc on darwin
-      # @file GCC response files
-      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
-      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+    $debug_cmd
 
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-        compile_command="$compile_command $arg"
-        finalize_command="$finalize_command $arg"
-        compiler_flags="$compiler_flags $arg"
-        continue
-        ;;
+    case $1 in
+    [0-9]* | *[!a-zA-Z0-9_]*)
+      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+      ;;
+    * )
+      func_tr_sh_result=$1
+      ;;
+    esac
+}
 
-      -shrext)
-	prev=shrext
-	continue
-	;;
 
-      -no-fast-install)
-	fast_install=no
-	continue
-	;;
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $debug_cmd
 
-      -no-install)
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
-	  # The PATH hackery in wrapper scripts is required on Windows
-	  # and Darwin in order for the loader to find any dlls it needs.
-	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
-	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
-	  fast_install=no
-	  ;;
-	*) no_install=yes ;;
-	esac
-	continue
-	;;
+    $opt_verbose && func_echo "$*"
 
-      -no-undefined)
-	allow_undefined=no
-	continue
-	;;
+    :
+}
 
-      -objectlist)
-	prev=objectlist
-	continue
-	;;
 
-      -o) prev=output ;;
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+    $debug_cmd
 
-      -precious-files-regex)
-	prev=precious_regex
-	continue
-	;;
+    $require_term_colors
 
-      -release)
-	prev=release
-	continue
-	;;
+    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
 
-      -rpath)
-	prev=rpath
-	continue
-	;;
 
-      -R)
-	prev=xrpath
-	continue
-	;;
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+    $debug_cmd
 
-      -R*)
-	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
-	# We need an absolute path.
-	case $dir in
-	[\\/]* | [A-Za-z]:[\\/]*) ;;
-	*)
-	  $echo "$modename: only absolute run-paths are allowed" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
-	case "$xrpath " in
-	*" $dir "*) ;;
-	*) xrpath="$xrpath $dir" ;;
-	esac
-	continue
-	;;
+    # CATEGORY must be in the warning_categories list!
+    case " $warning_categories " in
+      *" $1 "*) ;;
+      *) func_internal_error "invalid warning category '$1'" ;;
+    esac
 
-      -static | -static-libtool-libs)
-	# The effects of -static are defined in a previous loop.
-	# We used to do the same as -all-static on platforms that
-	# didn't have a PIC flag, but the assumption that the effects
-	# would be equivalent was wrong.  It would break on at least
-	# Digital Unix and AIX.
-	continue
-	;;
+    _G_category=$1
+    shift
 
-      -thread-safe)
-	thread_safe=yes
-	continue
-	;;
+    case " $opt_warning_types " in
+      *" $_G_category "*) $warning_func ${1+"$@"} ;;
+    esac
+}
 
-      -version-info)
-	prev=vinfo
-	continue
-	;;
-      -version-number)
-	prev=vinfo
-	vinfo_number=yes
-	continue
-	;;
 
-      -Wc,*)
-	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
-	arg=
-	save_ifs="$IFS"; IFS=','
-	for flag in $args; do
-	  IFS="$save_ifs"
-	  case $flag in
-	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	    flag="\"$flag\""
-	    ;;
-	  esac
-	  arg="$arg $wl$flag"
-	  compiler_flags="$compiler_flags $flag"
-	done
-	IFS="$save_ifs"
-	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-	;;
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+    $debug_cmd
 
-      -Wl,*)
-	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
-	arg=
-	save_ifs="$IFS"; IFS=','
-	for flag in $args; do
-	  IFS="$save_ifs"
-	  case $flag in
-	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	    flag="\"$flag\""
-	    ;;
-	  esac
-	  arg="$arg $wl$flag"
-	  compiler_flags="$compiler_flags $wl$flag"
-	  linker_flags="$linker_flags $flag"
-	done
-	IFS="$save_ifs"
-	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
-	;;
+    printf '%s\n%s\n' "$1" "$2" \
+      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
 
-      -Xcompiler)
-	prev=xcompiler
-	continue
-	;;
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false.  Use it like this:
+#
+#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+    $debug_cmd
 
-      -Xlinker)
-	prev=xlinker
-	continue
-	;;
+    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
 
-      -XCClinker)
-	prev=xcclinker
-	continue
-	;;
 
-      # Some other compiler flag.
-      -* | +*)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
 
-      *.$objext)
-	# A standard object.
-	objs="$objs $arg"
-	;;
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
 
-      *.lo)
-	# A libtool-controlled object.
+# This is free software.  There is NO warranty; not even for
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Copyright (C) 2010-2019, 2021, 2023-2024 Bootstrap Authors
+#
+# This file is dual licensed under the terms of the MIT license
+# , and GPL version 2 or later
+# .  You must apply one of
+# these licenses when using or redistributing this software or any of
+# the files within it.  See the URLs above, or the file `LICENSE`
+# included in the Bootstrap distribution for the full license texts.
 
-	# Check to see that this really is a libtool object.
-	if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-	  pic_object=
-	  non_pic_object=
+# Please report bugs or propose patches to:
+# 
 
-	  # Read the .lo file
-	  # If there is no directory component, then add one.
-	  case $arg in
-	  */* | *\\*) . $arg ;;
-	  *) . ./$arg ;;
-	  esac
+# Set a version string for this script.
+scriptversion=2019-02-19.15; # UTC
 
-	  if test -z "$pic_object" || \
-	     test -z "$non_pic_object" ||
-	     test "$pic_object" = none && \
-	     test "$non_pic_object" = none; then
-	    $echo "$modename: cannot find name of object for \`$arg'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
 
-	  # Extract subdirectory from the argument.
-	  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-	  if test "X$xdir" = "X$arg"; then
-	    xdir=
- 	  else
-	    xdir="$xdir/"
-	  fi
+## ------ ##
+## Usage. ##
+## ------ ##
 
-	  if test "$pic_object" != none; then
-	    # Prepend the subdirectory the object is found in.
-	    pic_object="$xdir$pic_object"
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+#   #!/bin/sh
+#   . relative/path/to/funclib.sh
+#   . relative/path/to/options-parser
+#   scriptversion=1.0
+#   func_options ${1+"$@"}
+#   eval set dummy "$func_options_result"; shift
+#   ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# Copyright'.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug in processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'.  Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+       --debug        enable verbose shell tracing
+   -W, --warnings=CATEGORY
+                      report the warnings falling in CATEGORY [all]
+   -v, --verbose      verbosely report processing
+       --version      print version information and exit
+   -h, --help         print short or long help message and exit
+"
 
-	    if test "$prev" = dlfiles; then
-	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-		dlfiles="$dlfiles $pic_object"
-		prev=
-		continue
-	      else
-		# If libtool objects are unsupported, then we need to preload.
-		prev=dlprefiles
-	      fi
-	    fi
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+       'all'          show all warnings
+       'none'         turn off all the warnings
+       'error'        warnings are treated as fatal errors"
 
-	    # CHECK ME:  I think I busted this.  -Ossama
-	    if test "$prev" = dlprefiles; then
-	      # Preload the old-style object.
-	      dlprefiles="$dlprefiles $pic_object"
-	      prev=
-	    fi
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
 
-	    # A PIC object.
-	    libobjs="$libobjs $pic_object"
-	    arg="$pic_object"
-	  fi
 
-	  # Non-PIC object.
-	  if test "$non_pic_object" != none; then
-	    # Prepend the subdirectory the object is found in.
-	    non_pic_object="$xdir$non_pic_object"
 
-	    # A standard non-PIC object
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	    if test -z "$pic_object" || test "$pic_object" = none ; then
-	      arg="$non_pic_object"
-	    fi
-	  else
-	    # If the PIC object exists, use it instead.
-	    # $xdir was prepended to $pic_object above.
-	    non_pic_object="$pic_object"
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	  fi
-	else
-	  # Only an error if not doing a dry-run.
-	  if test -z "$run"; then
-	    $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
-	    exit $EXIT_FAILURE
-	  else
-	    # Dry-run case.
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
 
-	    # Extract subdirectory from the argument.
-	    xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
-	    if test "X$xdir" = "X$arg"; then
-	      xdir=
-	    else
-	      xdir="$xdir/"
-	    fi
+# This section contains functions for adding, removing, and running hooks
+# in the main code.  A hook is just a list of function names that can be
+# run in order later on.
 
-	    pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
-	    non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
-	    libobjs="$libobjs $pic_object"
-	    non_pic_objects="$non_pic_objects $non_pic_object"
-	  fi
-	fi
-	;;
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+    $debug_cmd
 
-      *.$libext)
-	# An archive.
-	deplibs="$deplibs $arg"
-	old_deplibs="$old_deplibs $arg"
-	continue
-	;;
+    func_append hookable_fns " $1"
+}
 
-      *.la)
-	# A libtool-controlled library.
 
-	if test "$prev" = dlfiles; then
-	  # This library was specified with -dlopen.
-	  dlfiles="$dlfiles $arg"
-	  prev=
-	elif test "$prev" = dlprefiles; then
-	  # The library was specified with -dlpreopen.
-	  dlprefiles="$dlprefiles $arg"
-	  prev=
-	else
-	  deplibs="$deplibs $arg"
-	fi
-	continue
-	;;
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+    $debug_cmd
 
-      # Some other compiler argument.
-      *)
-	# Unknown arguments in both finalize_command and compile_command need
-	# to be aesthetically quoted because they are evaled later.
-	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
-	case $arg in
-	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
-	  arg="\"$arg\""
-	  ;;
-	esac
-	;;
-      esac # arg
+    case " $hookable_fns " in
+      *" $1 "*) ;;
+      *) func_fatal_error "'$1' does not accept hook functions." ;;
+    esac
 
-      # Now actually substitute the argument into the commands.
-      if test -n "$arg"; then
-	compile_command="$compile_command $arg"
-	finalize_command="$finalize_command $arg"
-      fi
-    done # argument parsing loop
+    eval func_append ${1}_hooks '" $2"'
+}
 
-    if test -n "$prev"; then
-      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-    fi
 
-    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
-      eval arg=\"$export_dynamic_flag_spec\"
-      compile_command="$compile_command $arg"
-      finalize_command="$finalize_command $arg"
-    fi
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of hook functions to be called by
+# FUNC_NAME.
+func_remove_hook ()
+{
+    $debug_cmd
 
-    oldlibs=
-    # calculate the name of the file, without its directory
-    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
-    libobjs_save="$libobjs"
+    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
 
-    if test -n "$shlibpath_var"; then
-      # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
-    else
-      shlib_search_path=
-    fi
-    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
-    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
 
-    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
-    if test "X$output_objdir" = "X$output"; then
-      output_objdir="$objdir"
+# func_propagate_result FUNC_NAME_A FUNC_NAME_B
+# ---------------------------------------------
+# If the *_result variable of FUNC_NAME_A _is set_, assign its value to
+# *_result variable of FUNC_NAME_B.
+func_propagate_result ()
+{
+    $debug_cmd
+
+    func_propagate_result_result=:
+    if eval "test \"\${${1}_result+set}\" = set"
+    then
+      eval "${2}_result=\$${1}_result"
     else
-      output_objdir="$output_objdir/$objdir"
-    fi
-    # Create the object directory.
-    if test ! -d "$output_objdir"; then
-      $show "$mkdir $output_objdir"
-      $run $mkdir $output_objdir
-      exit_status=$?
-      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
-	exit $exit_status
-      fi
+      func_propagate_result_result=false
     fi
+}
 
-    # Determine the type of output
-    case $output in
-    "")
-      $echo "$modename: you must specify an output file" 1>&2
-      $echo "$help" 1>&2
-      exit $EXIT_FAILURE
-      ;;
-    *.$libext) linkmode=oldlib ;;
-    *.lo | *.$objext) linkmode=obj ;;
-    *.la) linkmode=lib ;;
-    *) linkmode=prog ;; # Anything else should be a program.
-    esac
 
-    case $host in
-    *cygwin* | *mingw* | *pw32*)
-      # don't eliminate duplications in $postdeps and $predeps
-      duplicate_compiler_generated_deps=yes
-      ;;
-    *)
-      duplicate_compiler_generated_deps=$duplicate_deps
-      ;;
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It's assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+    $debug_cmd
+
+    case " $hookable_fns " in
+      *" $1 "*) ;;
+      *) func_fatal_error "'$1' does not support hook functions." ;;
     esac
-    specialdeplibs=
 
-    libs=
-    # Find all interdependent deplibs by searching for libraries
-    # that are linked more than once (e.g. -la -lb -la)
-    for deplib in $deplibs; do
-      if test "X$duplicate_deps" = "Xyes" ; then
-	case "$libs " in
-	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	esac
+    eval _G_hook_fns=\$$1_hooks; shift
+
+    for _G_hook in $_G_hook_fns; do
+      func_unset "${_G_hook}_result"
+      eval $_G_hook '${1+"$@"}'
+      func_propagate_result $_G_hook func_run_hooks
+      if $func_propagate_result_result; then
+        eval set dummy "$func_run_hooks_result"; shift
       fi
-      libs="$libs $deplib"
     done
+}
 
-    if test "$linkmode" = lib; then
-      libs="$predeps $libs $compiler_lib_search_path $postdeps"
 
-      # Compute libraries that are listed more than once in $predeps
-      # $postdeps and mark them as special (i.e., whose duplicates are
-      # not to be eliminated).
-      pre_post_deps=
-      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
-	for pre_post_dep in $predeps $postdeps; do
-	  case "$pre_post_deps " in
-	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
-	  esac
-	  pre_post_deps="$pre_post_deps $pre_post_dep"
-	done
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list from your hook function.  You may remove
+# or edit any options that you action, and then pass back the remaining
+# unprocessed options in '_result', escaped
+# suitably for 'eval'.
+#
+# The '_result' variable is automatically unset
+# before your hook gets called; for best performance, only set the
+# *_result variable when necessary (i.e. don't call the 'func_quote'
+# function unnecessarily because it can be an expensive operation on some
+# machines).
+#
+# Like this:
+#
+#    my_options_prep ()
+#    {
+#        $debug_cmd
+#
+#        # Extend the existing usage message.
+#        usage_message=$usage_message'
+#      -s, --silent       don'\''t print informational messages
+#    '
+#        # No change in '$@' (ignored completely by this hook).  Leave
+#        # my_options_prep_result variable intact.
+#    }
+#    func_add_hook func_options_prep my_options_prep
+#
+#
+#    my_silent_option ()
+#    {
+#        $debug_cmd
+#
+#        args_changed=false
+#
+#        # Note that, for efficiency, we parse as many options as we can
+#        # recognise in a loop before passing the remainder back to the
+#        # caller on the first unrecognised argument we encounter.
+#        while test $# -gt 0; do
+#          opt=$1; shift
+#          case $opt in
+#            --silent|-s) opt_silent=:
+#                         args_changed=:
+#                         ;;
+#            # Separate non-argument short options:
+#            -s*)         func_split_short_opt "$_G_opt"
+#                         set dummy "$func_split_short_opt_name" \
+#                             "-$func_split_short_opt_arg" ${1+"$@"}
+#                         shift
+#                         args_changed=:
+#                         ;;
+#            *)           # Make sure the first unrecognised option "$_G_opt"
+#                         # is added back to "$@" in case we need it later,
+#                         # if $args_changed was set to 'true'.
+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+#          esac
+#        done
+#
+#        # Only call 'func_quote' here if we processed at least one argument.
+#        if $args_changed; then
+#          func_quote eval ${1+"$@"}
+#          my_silent_option_result=$func_quote_result
+#        fi
+#    }
+#    func_add_hook func_parse_options my_silent_option
+#
+#
+#    my_option_validation ()
+#    {
+#        $debug_cmd
+#
+#        $opt_silent && $opt_verbose && func_fatal_help "\
+#    '--silent' and '--verbose' options are mutually exclusive."
+#    }
+#    func_add_hook func_validate_options my_option_validation
+#
+# You'll also need to manually amend $usage_message to reflect the extra
+# options you parse.  It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options_finish [ARG]...
+# ----------------------------
+# Finishing the option parse loop (call 'func_options' hooks ATM).
+func_options_finish ()
+{
+    $debug_cmd
+
+    func_run_hooks func_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_options_finish
+}
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+    $debug_cmd
+
+    _G_options_quoted=false
+
+    for my_func in options_prep parse_options validate_options options_finish
+    do
+      func_unset func_${my_func}_result
+      func_unset func_run_hooks_result
+      eval func_$my_func '${1+"$@"}'
+      func_propagate_result func_$my_func func_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_options_result"; shift
+        _G_options_quoted=:
       fi
-      pre_post_deps=
-    fi
+    done
 
-    deplibs=
-    newdependency_libs=
-    newlib_search_path=
-    need_relink=no # whether we're linking any uninstalled libtool libraries
-    notinst_deplibs= # not-installed libtool libraries
-    case $linkmode in
-    lib)
-	passes="conv link"
-	for file in $dlfiles $dlprefiles; do
-	  case $file in
-	  *.la) ;;
-	  *)
-	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
-	    exit $EXIT_FAILURE
-	    ;;
-	  esac
-	done
-	;;
-    prog)
-	compile_deplibs=
-	finalize_deplibs=
-	alldeplibs=no
-	newdlfiles=
-	newdlprefiles=
-	passes="conv scan dlopen dlpreopen link"
-	;;
-    *)  passes="conv"
-	;;
-    esac
-    for pass in $passes; do
-      if test "$linkmode,$pass" = "lib,link" ||
-	 test "$linkmode,$pass" = "prog,scan"; then
-	libs="$deplibs"
-	deplibs=
+    $_G_options_quoted || {
+      # As we (func_options) are top-level options-parser function and
+      # nobody quoted "$@" for us yet, we need to do it explicitly for
+      # caller.
+      func_quote eval ${1+"$@"}
+      func_options_result=$func_quote_result
+    }
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters.  If a hook function modifies that list, and
+# needs to propagate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+    $debug_cmd
+
+    # Option defaults:
+    opt_verbose=false
+    opt_warning_types=
+
+    func_run_hooks func_options_prep ${1+"$@"}
+    func_propagate_result func_run_hooks func_options_prep
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+    $debug_cmd
+
+    _G_parse_options_requote=false
+    # this just eases exit handling
+    while test $# -gt 0; do
+      # Defer to hook functions for initial option parsing, so they
+      # get priority in the event of reusing an option name.
+      func_run_hooks func_parse_options ${1+"$@"}
+      func_propagate_result func_run_hooks func_parse_options
+      if $func_propagate_result_result; then
+        eval set dummy "$func_parse_options_result"; shift
+        # Even though we may have changed "$@", we passed the "$@" array
+        # down into the hook and it quoted it for us (because we are in
+        # this if-branch).  No need to quote it again.
+        _G_parse_options_requote=false
       fi
-      if test "$linkmode" = prog; then
-	case $pass in
-	dlopen) libs="$dlfiles" ;;
-	dlpreopen) libs="$dlprefiles" ;;
-	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
-	esac
+
+      # Break out of the loop if we already parsed every option.
+      test $# -gt 0 || break
+
+      # We expect that one of the options parsed in this function matches
+      # and thus we remove _G_opt from "$@" and need to re-quote.
+      _G_match_parse_options=:
+      _G_opt=$1
+      shift
+      case $_G_opt in
+        --debug|-x)   debug_cmd='set -x'
+                      func_echo "enabling shell trace mode" >&2
+                      $debug_cmd
+                      ;;
+
+        --no-warnings|--no-warning|--no-warn)
+                      set dummy --warnings none ${1+"$@"}
+                      shift
+		      ;;
+
+        --warnings|--warning|-W)
+                      if test $# = 0 && func_missing_arg $_G_opt; then
+                        _G_parse_options_requote=:
+                        break
+                      fi
+                      case " $warning_categories $1" in
+                        *" $1 "*)
+                          # trailing space prevents matching last $1 above
+                          func_append_uniq opt_warning_types " $1"
+                          ;;
+                        *all)
+                          opt_warning_types=$warning_categories
+                          ;;
+                        *none)
+                          opt_warning_types=none
+                          warning_func=:
+                          ;;
+                        *error)
+                          opt_warning_types=$warning_categories
+                          warning_func=func_fatal_error
+                          ;;
+                        *)
+                          func_fatal_error \
+                             "unsupported warning category: '$1'"
+                          ;;
+                      esac
+                      shift
+                      ;;
+
+        --verbose|-v) opt_verbose=: ;;
+        --version)    func_version ;;
+        -\?|-h)       func_usage ;;
+        --help)       func_help ;;
+
+	# Separate optargs to long options (plugins may need this):
+	--*=*)        func_split_equals "$_G_opt"
+	              set dummy "$func_split_equals_lhs" \
+                          "$func_split_equals_rhs" ${1+"$@"}
+                      shift
+                      ;;
+
+       # Separate optargs to short options:
+        -W*)
+                      func_split_short_opt "$_G_opt"
+                      set dummy "$func_split_short_opt_name" \
+                          "$func_split_short_opt_arg" ${1+"$@"}
+                      shift
+                      ;;
+
+        # Separate non-argument short options:
+        -\?*|-h*|-v*|-x*)
+                      func_split_short_opt "$_G_opt"
+                      set dummy "$func_split_short_opt_name" \
+                          "-$func_split_short_opt_arg" ${1+"$@"}
+                      shift
+                      ;;
+
+        --)           _G_parse_options_requote=: ; break ;;
+        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift
+                      _G_match_parse_options=false
+                      break
+                      ;;
+      esac
+
+      if $_G_match_parse_options; then
+        _G_parse_options_requote=:
       fi
-      if test "$pass" = dlopen; then
-	# Collect dlpreopened libraries
-	save_deplibs="$deplibs"
-	deplibs=
+    done
+
+    if $_G_parse_options_requote; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      func_parse_options_result=$func_quote_result
+    fi
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+    $debug_cmd
+
+    # Display all warnings if -W was not given.
+    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+    func_run_hooks func_validate_options ${1+"$@"}
+    func_propagate_result func_run_hooks func_validate_options
+
+    # Bail if the options were screwed!
+    $exit_cmd $EXIT_FAILURE
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    $debug_cmd
+
+    eval \$ECHO \""Usage: $usage"\"
+    eval \$ECHO \""$fatal_help"\"
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+    $debug_cmd
+
+    func_usage_message
+    $ECHO "$long_help_message"
+    exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $debug_cmd
+
+    func_error "Missing argument for '$1'."
+    exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables
+# after splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+    && (eval 'x=a/b/c;
+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+    && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_split_equals ()
+  {
+      $debug_cmd
+
+      func_split_equals_lhs=${1%%=*}
+      func_split_equals_rhs=${1#*=}
+      if test "x$func_split_equals_lhs" = "x$1"; then
+        func_split_equals_rhs=
       fi
-      for deplib in $libs; do
-	lib=
-	found=no
-	case $deplib in
-	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
-	  if test "$linkmode,$pass" = "prog,link"; then
-	    compile_deplibs="$deplib $compile_deplibs"
-	    finalize_deplibs="$deplib $finalize_deplibs"
-	  else
-	    compiler_flags="$compiler_flags $deplib"
-	  fi
-	  continue
-	  ;;
-	-l*)
-	  if test "$linkmode" != lib && test "$linkmode" != prog; then
-	    $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
-	    continue
-	  fi
-	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
-	  if test "$linkmode" = lib; then
-	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
-	  else
-	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
-	  fi
-	  for searchdir in $searchdirs; do
-	    for search_ext in .la $std_shrext .so .a; do
-	      # Search the libtool library
-	      lib="$searchdir/lib${name}${search_ext}"
-	      if test -f "$lib"; then
-		if test "$search_ext" = ".la"; then
-		  found=yes
-		else
-		  found=no
-		fi
-		break 2
-	      fi
-	    done
-	  done
-	  if test "$found" != yes; then
-	    # deplib doesn't seem to be a libtool library
-	    if test "$linkmode,$pass" = "prog,link"; then
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      deplibs="$deplib $deplibs"
-	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    continue
-	  else # deplib is a libtool library
-	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
-	    # We need to do some special things here, and not later.
-	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-	      case " $predeps $postdeps " in
-	      *" $deplib "*)
-		if (${SED} -e '2q' $lib |
-                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
-		  library_names=
-		  old_library=
-		  case $lib in
-		  */* | *\\*) . $lib ;;
-		  *) . ./$lib ;;
-		  esac
-		  for l in $old_library $library_names; do
-		    ll="$l"
-		  done
-		  if test "X$ll" = "X$old_library" ; then # only static version available
-		    found=no
-		    ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
-		    test "X$ladir" = "X$lib" && ladir="."
-		    lib=$ladir/$old_library
-		    if test "$linkmode,$pass" = "prog,link"; then
-		      compile_deplibs="$deplib $compile_deplibs"
-		      finalize_deplibs="$deplib $finalize_deplibs"
-		    else
-		      deplibs="$deplib $deplibs"
-		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
-		    fi
-		    continue
-		  fi
-		fi
-	        ;;
-	      *) ;;
-	      esac
-	    fi
-	  fi
-	  ;; # -l
-	-L*)
-	  case $linkmode in
-	  lib)
-	    deplibs="$deplib $deplibs"
-	    test "$pass" = conv && continue
-	    newdependency_libs="$deplib $newdependency_libs"
-	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-	    ;;
-	  prog)
-	    if test "$pass" = conv; then
-	      deplibs="$deplib $deplibs"
-	      continue
-	    fi
-	    if test "$pass" = scan; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    fi
-	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
-	    ;;
-	  *)
-	    $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
-	    ;;
-	  esac # linkmode
-	  continue
-	  ;; # -L
-	-R*)
-	  if test "$pass" = link; then
-	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
-	    # Make sure the xrpath contains only unique directories.
-	    case "$xrpath " in
-	    *" $dir "*) ;;
-	    *) xrpath="$xrpath $dir" ;;
-	    esac
-	  fi
-	  deplibs="$deplib $deplibs"
-	  continue
-	  ;;
-	*.la) lib="$deplib" ;;
-	*.$libext)
-	  if test "$pass" = conv; then
-	    deplibs="$deplib $deplibs"
-	    continue
-	  fi
-	  case $linkmode in
-	  lib)
-	    valid_a_lib=no
-	    case $deplibs_check_method in
-	      match_pattern*)
-		set dummy $deplibs_check_method
-	        match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-		if eval $echo \"$deplib\" 2>/dev/null \
-		    | $SED 10q \
-		    | $EGREP "$match_pattern_regex" > /dev/null; then
-		  valid_a_lib=yes
-		fi
-		;;
-	      pass_all)
-		valid_a_lib=yes
-		;;
-            esac
-	    if test "$valid_a_lib" != yes; then
-	      $echo
-	      $echo "*** Warning: Trying to link with static lib archive $deplib."
-	      $echo "*** I have the capability to make that library automatically link in when"
-	      $echo "*** you link to this library.  But I can only do this if you have a"
-	      $echo "*** shared version of the library, which you do not appear to have"
-	      $echo "*** because the file extensions .$libext of this argument makes me believe"
-	      $echo "*** that it is just a static archive that I should not used here."
-	    else
-	      $echo
-	      $echo "*** Warning: Linking the shared library $output against the"
-	      $echo "*** static library $deplib is not portable!"
-	      deplibs="$deplib $deplibs"
-	    fi
-	    continue
-	    ;;
-	  prog)
-	    if test "$pass" != link; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    fi
-	    continue
-	    ;;
-	  esac # linkmode
-	  ;; # *.$libext
-	*.lo | *.$objext)
-	  if test "$pass" = conv; then
-	    deplibs="$deplib $deplibs"
-	  elif test "$linkmode" = prog; then
-	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
-	      # If there is no dlopen support or we're linking statically,
-	      # we need to preload.
-	      newdlprefiles="$newdlprefiles $deplib"
-	      compile_deplibs="$deplib $compile_deplibs"
-	      finalize_deplibs="$deplib $finalize_deplibs"
-	    else
-	      newdlfiles="$newdlfiles $deplib"
-	    fi
-	  fi
-	  continue
-	  ;;
-	%DEPLIBS%)
-	  alldeplibs=yes
-	  continue
-	  ;;
-	esac # case $deplib
-	if test "$found" = yes || test -f "$lib"; then :
-	else
-	  $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
-	  exit $EXIT_FAILURE
-	fi
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_split_equals ()
+  {
+      $debug_cmd
 
-	# Check to see that this really is a libtool archive.
-	if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
-	else
-	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
-	  exit $EXIT_FAILURE
-	fi
+      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+      func_split_equals_rhs=
+      test "x$func_split_equals_lhs=" = "x$1" \
+        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+  }
+fi #func_split_equals
 
-	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
-	test "X$ladir" = "X$lib" && ladir="."
 
-	dlname=
-	dlopen=
-	dlpreopen=
-	libdir=
-	library_names=
-	old_library=
-	# If the library was installed with an old release of libtool,
-	# it will not redefine variables installed, or shouldnotlink
-	installed=yes
-	shouldnotlink=no
-	avoidtemprpath=
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+  # This is an XSI compatible shell, allowing a faster implementation...
+  eval 'func_split_short_opt ()
+  {
+      $debug_cmd
 
+      func_split_short_opt_arg=${1#??}
+      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+  }'
+else
+  # ...otherwise fall back to using expr, which is often a shell builtin.
+  func_split_short_opt ()
+  {
+      $debug_cmd
 
-	# Read the .la file
-	case $lib in
-	*/* | *\\*) . $lib ;;
-	*) . ./$lib ;;
-	esac
+      func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'`
+      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+  }
+fi #func_split_short_opt
 
-	if test "$linkmode,$pass" = "lib,link" ||
-	   test "$linkmode,$pass" = "prog,scan" ||
-	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
-	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
-	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
-	fi
 
-	if test "$pass" = conv; then
-	  # Only check for convenience libraries
-	  deplibs="$lib $deplibs"
-	  if test -z "$libdir"; then
-	    if test -z "$old_library"; then
-	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-	      exit $EXIT_FAILURE
-	    fi
-	    # It is a libtool convenience library, so add in its objects.
-	    convenience="$convenience $ladir/$objdir/$old_library"
-	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
-	    tmp_libs=
-	    for deplib in $dependency_libs; do
-	      deplibs="$deplib $deplibs"
-              if test "X$duplicate_deps" = "Xyes" ; then
-	        case "$tmp_libs " in
-	        *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	        esac
-              fi
-	      tmp_libs="$tmp_libs $deplib"
-	    done
-	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
-	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  continue
-	fi # $pass = conv
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $debug_cmd
 
+    func_usage_message
+    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+    exit 0
+}
 
-	# Get the name of the library we link against.
-	linklib=
-	for l in $old_library $library_names; do
-	  linklib="$l"
-	done
-	if test -z "$linklib"; then
-	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
-	  exit $EXIT_FAILURE
-	fi
 
-	# This library was specified with -dlopen.
-	if test "$pass" = dlopen; then
-	  if test -z "$libdir"; then
-	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  if test -z "$dlname" ||
-	     test "$dlopen_support" != yes ||
-	     test "$build_libtool_libs" = no; then
-	    # If there is no dlname, no dlopen support or we're linking
-	    # statically, we need to preload.  We also need to preload any
-	    # dependent libraries so libltdl's deplib preloader doesn't
-	    # bomb out in the load deplibs phase.
-	    dlprefiles="$dlprefiles $lib $dependency_libs"
-	  else
-	    newdlfiles="$newdlfiles $lib"
-	  fi
-	  continue
-	fi # $pass = dlopen
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+    $debug_cmd
 
-	# We need an absolute path.
-	case $ladir in
-	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
-	*)
-	  abs_ladir=`cd "$ladir" && pwd`
-	  if test -z "$abs_ladir"; then
-	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
-	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
-	    abs_ladir="$ladir"
-	  fi
-	  ;;
-	esac
-	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+    eval \$ECHO \""Usage: $usage"\"
+    echo
+    $SED -n 's|^# ||
+        /^Written by/{
+          x;p;x
+        }
+	h
+	/^Written by/q' < "$progpath"
+    echo
+    eval \$ECHO \""$usage_message"\"
+}
 
-	# Find the relevant object directory and library name.
-	if test "X$installed" = Xyes; then
-	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
-	    dir="$ladir"
-	    absdir="$abs_ladir"
-	    libdir="$abs_ladir"
-	  else
-	    dir="$libdir"
-	    absdir="$libdir"
-	  fi
-	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
-	else
-	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
-	    dir="$ladir"
-	    absdir="$abs_ladir"
-	    # Remove this search path later
-	    notinst_path="$notinst_path $abs_ladir"
-	  else
-	    dir="$ladir/$objdir"
-	    absdir="$abs_ladir/$objdir"
-	    # Remove this search path later
-	    notinst_path="$notinst_path $abs_ladir"
-	  fi
-	fi # $installed = yes
-	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
 
-	# This library was specified with -dlpreopen.
-	if test "$pass" = dlpreopen; then
-	  if test -z "$libdir"; then
-	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
-	    exit $EXIT_FAILURE
-	  fi
-	  # Prefer using a static library (so that no silly _DYNAMIC symbols
-	  # are required to link).
-	  if test -n "$old_library"; then
-	    newdlprefiles="$newdlprefiles $dir/$old_library"
-	  # Otherwise, use the dlname, so that lt_dlopen finds it.
-	  elif test -n "$dlname"; then
-	    newdlprefiles="$newdlprefiles $dir/$dlname"
-	  else
-	    newdlprefiles="$newdlprefiles $dir/$linklib"
-	  fi
-	fi # $pass = dlpreopen
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+# The version message is extracted from the calling file's header
+# comments, with leading '# ' stripped:
+#   1. First display the progname and version
+#   2. Followed by the header comment line matching  /^# Written by /
+#   3. Then a blank line followed by the first following line matching
+#      /^# Copyright /
+#   4. Immediately followed by any lines between the previous matches,
+#      except lines preceding the intervening completely blank line.
+# For example, see the header comments of this file.
+func_version ()
+{
+    $debug_cmd
 
-	if test -z "$libdir"; then
-	  # Link the convenience library
-	  if test "$linkmode" = lib; then
-	    deplibs="$dir/$old_library $deplibs"
-	  elif test "$linkmode,$pass" = "prog,link"; then
-	    compile_deplibs="$dir/$old_library $compile_deplibs"
-	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
-	  else
-	    deplibs="$lib $deplibs" # used for prog,scan pass
-	  fi
-	  continue
-	fi
+    printf '%s\n' "$progname $scriptversion"
+    $SED -n '
+        /^# Written by /!b
+        s|^# ||; p; n
 
+        :fwd2blnk
+        /./ {
+          n
+          b fwd2blnk
+        }
+        p; n
+
+        :holdwrnt
+        s|^# ||
+        s|^# *$||
+        /^Copyright /!{
+          /./H
+          n
+          b holdwrnt
+        }
 
-	if test "$linkmode" = prog && test "$pass" != link; then
-	  newlib_search_path="$newlib_search_path $ladir"
-	  deplibs="$lib $deplibs"
+        s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+        G
+        s|\(\n\)\n*|\1|g
+        p; q' < "$progpath"
 
-	  linkalldeplibs=no
-	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
-	     test "$build_libtool_libs" = no; then
-	    linkalldeplibs=yes
-	  fi
+    exit $?
+}
 
-	  tmp_libs=
-	  for deplib in $dependency_libs; do
-	    case $deplib in
-	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
-	    esac
-	    # Need to link against all dependency_libs?
-	    if test "$linkalldeplibs" = yes; then
-	      deplibs="$deplib $deplibs"
-	    else
-	      # Need to hardcode shared library paths
-	      # or/and link against static libraries
-	      newdependency_libs="$deplib $newdependency_libs"
-	    fi
-	    if test "X$duplicate_deps" = "Xyes" ; then
-	      case "$tmp_libs " in
-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	      esac
-	    fi
-	    tmp_libs="$tmp_libs $deplib"
-	  done # for deplib
-	  continue
-	fi # $linkmode = prog...
 
-	if test "$linkmode,$pass" = "prog,link"; then
-	  if test -n "$library_names" &&
-	     { { test "$prefer_static_libs" = no ||
-		 test "$prefer_static_libs,$installed" = "built,yes"; } ||
-	       test -z "$old_library"; }; then
-	    # We need to hardcode the library path
-	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
-	      # Make sure the rpath contains only unique directories.
-	      case "$temp_rpath " in
-	      *" $dir "*) ;;
-	      *" $absdir "*) ;;
-	      *) temp_rpath="$temp_rpath $absdir" ;;
-	      esac
-	    fi
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
 
-	    # Hardcode the library path.
-	    # Skip directories that are in the system default run-time
-	    # search path.
-	    case " $sys_lib_dlsearch_path " in
-	    *" $absdir "*) ;;
-	    *)
-	      case "$compile_rpath " in
-	      *" $absdir "*) ;;
-	      *) compile_rpath="$compile_rpath $absdir"
-	      esac
-	      ;;
-	    esac
-	    case " $sys_lib_dlsearch_path " in
-	    *" $libdir "*) ;;
-	    *)
-	      case "$finalize_rpath " in
-	      *" $libdir "*) ;;
-	      *) finalize_rpath="$finalize_rpath $libdir"
-	      esac
-	      ;;
-	    esac
-	  fi # $linkmode,$pass = prog,link...
+# Set a version string.
+scriptversion='(GNU libtool) 2.5.4'
 
-	  if test "$alldeplibs" = yes &&
-	     { test "$deplibs_check_method" = pass_all ||
-	       { test "$build_libtool_libs" = yes &&
-		 test -n "$library_names"; }; }; then
-	    # We only need to search for static libraries
-	    continue
-	  fi
-	fi
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $debug_cmd
 
-	link_static=no # Whether the deplib will be linked statically
-	use_static_libs=$prefer_static_libs
-	if test "$use_static_libs" = built && test "$installed" = yes ; then
-	  use_static_libs=no
-	fi
-	if test -n "$library_names" &&
-	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
-	  if test "$installed" = no; then
-	    notinst_deplibs="$notinst_deplibs $lib"
-	    need_relink=yes
-	  fi
-	  # This is a shared library
+	year=`date +%Y`
 
-	  # Warn about portability, can't link against -module's on
-	  # some systems (darwin)
-	  if test "$shouldnotlink" = yes && test "$pass" = link ; then
-	    $echo
-	    if test "$linkmode" = prog; then
-	      $echo "*** Warning: Linking the executable $output against the loadable module"
-	    else
-	      $echo "*** Warning: Linking the shared library $output against the loadable module"
-	    fi
-	    $echo "*** $linklib is not portable!"
-	  fi
-	  if test "$linkmode" = lib &&
-	     test "$hardcode_into_libs" = yes; then
-	    # Hardcode the library path.
-	    # Skip directories that are in the system default run-time
-	    # search path.
-	    case " $sys_lib_dlsearch_path " in
-	    *" $absdir "*) ;;
-	    *)
-	      case "$compile_rpath " in
-	      *" $absdir "*) ;;
-	      *) compile_rpath="$compile_rpath $absdir"
-	      esac
-	      ;;
-	    esac
-	    case " $sys_lib_dlsearch_path " in
-	    *" $libdir "*) ;;
-	    *)
-	      case "$finalize_rpath " in
-	      *" $libdir "*) ;;
-	      *) finalize_rpath="$finalize_rpath $libdir"
-	      esac
-	      ;;
-	    esac
-	  fi
+	cat <
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
 
-	  if test -n "$old_archive_from_expsyms_cmds"; then
-	    # figure out the soname
-	    set dummy $library_names
-	    realname="$2"
-	    shift; shift
-	    libname=`eval \\$echo \"$libname_spec\"`
-	    # use dlname if we got it. it's perfectly good, no?
-	    if test -n "$dlname"; then
-	      soname="$dlname"
-	    elif test -n "$soname_spec"; then
-	      # bleh windows
-	      case $host in
-	      *cygwin* | mingw*)
-		major=`expr $current - $age`
-		versuffix="-$major"
-		;;
-	      esac
-	      eval soname=\"$soname_spec\"
-	    else
-	      soname="$realname"
-	    fi
+Originally written by Gordon Matzigkeit, 1996
+(See AUTHORS for complete contributor listing)
+EOF
 
-	    # Make a new name for the extract_expsyms_cmds to use
-	    soroot="$soname"
-	    soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
-	    newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+    exit $?
+}
 
-	    # If the library has no export list, then create one now
-	    if test -f "$output_objdir/$soname-def"; then :
-	    else
-	      $show "extracting exported symbol list from \`$soname'"
-	      save_ifs="$IFS"; IFS='~'
-	      cmds=$extract_expsyms_cmds
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd" || exit $?
-	      done
-	      IFS="$save_ifs"
-	    fi
 
-	    # Create $newlib
-	    if test -f "$output_objdir/$newlib"; then :; else
-	      $show "generating import library for \`$soname'"
-	      save_ifs="$IFS"; IFS='~'
-	      cmds=$old_archive_from_expsyms_cmds
-	      for cmd in $cmds; do
-		IFS="$save_ifs"
-		eval cmd=\"$cmd\"
-		$show "$cmd"
-		$run eval "$cmd" || exit $?
-	      done
-	      IFS="$save_ifs"
-	    fi
-	    # make sure the library variables are pointing to the new library
-	    dir=$output_objdir
-	    linklib=$newlib
-	  fi # test -n "$old_archive_from_expsyms_cmds"
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+    $debug_cmd
 
-	  if test "$linkmode" = prog || test "$mode" != relink; then
-	    add_shlibpath=
-	    add_dir=
-	    add=
-	    lib_linked=yes
-	    case $hardcode_action in
-	    immediate | unsupported)
-	      if test "$hardcode_direct" = no; then
-		add="$dir/$linklib"
-		case $host in
-		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
-		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
-		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
-		    *-*-unixware7*) add_dir="-L$dir" ;;
-		  *-*-darwin* )
-		    # if the lib is a module then we can not link against
-		    # it, someone is ignoring the new warnings I added
-		    if /usr/bin/file -L $add 2> /dev/null |
-                      $EGREP ": [^:]* bundle" >/dev/null ; then
-		      $echo "** Warning, lib $linklib is a module, not a shared library"
-		      if test -z "$old_library" ; then
-		        $echo
-		        $echo "** And there doesn't seem to be a static archive available"
-		        $echo "** The link will probably fail, sorry"
-		      else
-		        add="$dir/$old_library"
-		      fi
-		    fi
-		esac
-	      elif test "$hardcode_minus_L" = no; then
-		case $host in
-		*-*-sunos*) add_shlibpath="$dir" ;;
-		esac
-		add_dir="-L$dir"
-		add="-l$name"
-	      elif test "$hardcode_shlibpath_var" = no; then
-		add_shlibpath="$dir"
-		add="-l$name"
-	      else
-		lib_linked=no
-	      fi
-	      ;;
-	    relink)
-	      if test "$hardcode_direct" = yes; then
-		add="$dir/$linklib"
-	      elif test "$hardcode_minus_L" = yes; then
-		add_dir="-L$dir"
-		# Try looking first in the location we're being installed to.
-		if test -n "$inst_prefix_dir"; then
-		  case $libdir in
-		    [\\/]*)
-		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
-		      ;;
-		  esac
-		fi
-		add="-l$name"
-	      elif test "$hardcode_shlibpath_var" = yes; then
-		add_shlibpath="$dir"
-		add="-l$name"
-	      else
-		lib_linked=no
-	      fi
-	      ;;
-	    *) lib_linked=no ;;
-	    esac
+    _G_message=$*
 
-	    if test "$lib_linked" != yes; then
-	      $echo "$modename: configuration error: unsupported hardcode properties"
-	      exit $EXIT_FAILURE
-	    fi
+    func_echo_IFS=$IFS
+    IFS=$nl
+    for _G_line in $_G_message; do
+      IFS=$func_echo_IFS
+      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+    done
+    IFS=$func_echo_IFS
+}
 
-	    if test -n "$add_shlibpath"; then
-	      case :$compile_shlibpath: in
-	      *":$add_shlibpath:"*) ;;
-	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
-	      esac
-	    fi
-	    if test "$linkmode" = prog; then
-	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
-	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
-	    else
-	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
-	      test -n "$add" && deplibs="$add $deplibs"
-	      if test "$hardcode_direct" != yes && \
-		 test "$hardcode_minus_L" != yes && \
-		 test "$hardcode_shlibpath_var" = yes; then
-		case :$finalize_shlibpath: in
-		*":$libdir:"*) ;;
-		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-		esac
-	      fi
-	    fi
-	  fi
 
-	  if test "$linkmode" = prog || test "$mode" = relink; then
-	    add_shlibpath=
-	    add_dir=
-	    add=
-	    # Finalize command for both is simple: just hardcode it.
-	    if test "$hardcode_direct" = yes; then
-	      add="$libdir/$linklib"
-	    elif test "$hardcode_minus_L" = yes; then
-	      add_dir="-L$libdir"
-	      add="-l$name"
-	    elif test "$hardcode_shlibpath_var" = yes; then
-	      case :$finalize_shlibpath: in
-	      *":$libdir:"*) ;;
-	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
-	      esac
-	      add="-l$name"
-	    elif test "$hardcode_automatic" = yes; then
-	      if test -n "$inst_prefix_dir" &&
-		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
-	        add="$inst_prefix_dir$libdir/$linklib"
-	      else
-	        add="$libdir/$linklib"
-	      fi
-	    else
-	      # We cannot seem to hardcode it, guess we'll fake it.
-	      add_dir="-L$libdir"
-	      # Try looking first in the location we're being installed to.
-	      if test -n "$inst_prefix_dir"; then
-		case $libdir in
-		  [\\/]*)
-		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
-		    ;;
-		esac
-	      fi
-	      add="-l$name"
-	    fi
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+       --config                 show all configuration variables
+       --debug                  enable verbose shell tracing
+   -n, --dry-run                display commands without modifying any files
+       --features               display basic configuration information
+       --finish                 use operation '--mode=finish'
+       --mode=MODE              use operation mode MODE
+       --no-finish              don't update shared library cache
+       --no-quiet, --no-silent  print default informational messages
+       --no-warnings            equivalent to '-Wnone'
+       --preserve-dup-deps      don't remove duplicate dependency libraries
+       --quiet, --silent        don't print informational messages
+       --reorder-cache=DIRS     reorder shared library cache for preferred DIRS
+       --tag=TAG                use configuration variables from tag TAG
+   -v, --verbose                print more informational messages than default
+       --version                print version information
+   -W, --warnings=CATEGORY      report the warnings falling in CATEGORY [all]
+   -h, --help, --help-all       print short, long, or detailed help message
+"
 
-	    if test "$linkmode" = prog; then
-	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
-	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
-	    else
-	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
-	      test -n "$add" && deplibs="$add $deplibs"
-	    fi
-	  fi
-	elif test "$linkmode" = prog; then
-	  # Here we assume that one of hardcode_direct or hardcode_minus_L
-	  # is not unsupported.  This is valid on all known static and
-	  # shared platforms.
-	  if test "$hardcode_direct" != unsupported; then
-	    test -n "$old_library" && linklib="$old_library"
-	    compile_deplibs="$dir/$linklib $compile_deplibs"
-	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
-	  else
-	    compile_deplibs="-l$name -L$dir $compile_deplibs"
-	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
-	  fi
-	elif test "$build_libtool_libs" = yes; then
-	  # Not a shared library
-	  if test "$deplibs_check_method" != pass_all; then
-	    # We're trying link a shared library against a static one
-	    # but the system doesn't support it.
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+    $debug_cmd
 
-	    # Just print a warning and add the library to dependency_libs so
-	    # that the program can be linked against the static library.
-	    $echo
-	    $echo "*** Warning: This system can not link to static lib archive $lib."
-	    $echo "*** I have the capability to make that library automatically link in when"
-	    $echo "*** you link to this library.  But I can only do this if you have a"
-	    $echo "*** shared version of the library, which you do not appear to have."
-	    if test "$module" = yes; then
-	      $echo "*** But as you try to build a module library, libtool will still create "
-	      $echo "*** a static module, that should work as long as the dlopening application"
-	      $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
-	      if test -z "$global_symbol_pipe"; then
-		$echo
-		$echo "*** However, this would only work if libtool was able to extract symbol"
-		$echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-		$echo "*** not find such a program.  So, this module is probably useless."
-		$echo "*** \`nm' from GNU binutils and a full rebuild may help."
-	      fi
-	      if test "$build_old_libs" = no; then
-		build_libtool_libs=module
-		build_old_libs=yes
-	      else
-		build_libtool_libs=no
-	      fi
-	    fi
-	  else
-	    deplibs="$dir/$old_library $deplibs"
-	    link_static=yes
-	  fi
-	fi # link shared/static library?
+    func_usage_message
+    $ECHO "$long_help_message
 
-	if test "$linkmode" = lib; then
-	  if test -n "$dependency_libs" &&
-	     { test "$hardcode_into_libs" != yes ||
-	       test "$build_old_libs" = yes ||
-	       test "$link_static" = yes; }; then
-	    # Extract -R from dependency_libs
-	    temp_deplibs=
-	    for libdir in $dependency_libs; do
-	      case $libdir in
-	      -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
-		   case " $xrpath " in
-		   *" $temp_xrpath "*) ;;
-		   *) xrpath="$xrpath $temp_xrpath";;
-		   esac;;
-	      *) temp_deplibs="$temp_deplibs $libdir";;
-	      esac
-	    done
-	    dependency_libs="$temp_deplibs"
-	  fi
+MODE must be one of the following:
 
-	  newlib_search_path="$newlib_search_path $absdir"
-	  # Link against this library
-	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
-	  # ... and its dependency_libs
-	  tmp_libs=
-	  for deplib in $dependency_libs; do
-	    newdependency_libs="$deplib $newdependency_libs"
-	    if test "X$duplicate_deps" = "Xyes" ; then
-	      case "$tmp_libs " in
-	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
-	      esac
-	    fi
-	    tmp_libs="$tmp_libs $deplib"
-	  done
+       clean           remove files from the build directory
+       compile         compile a source file into a libtool object
+       execute         automatically set library path, then run a program
+       finish          complete the installation of libtool libraries
+       install         install libraries or executables
+       link            create a library or an executable
+       uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+       host-triplet:   $host
+       shell:          $SHELL
+       compiler:       $LTCC
+       compiler flags: $LTCFLAGS
+       linker:         $LD (gnu? $with_gnu_ld)
+       version:        $progname $scriptversion
+       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to .
+GNU libtool home page: .
+General help using GNU software: ."
+    exit 0
+}
 
-	  if test "$link_all_deplibs" != no; then
-	    # Add the search paths of all dependency libraries
-	    for deplib in $dependency_libs; do
-	      case $deplib in
-	      -L*) path="$deplib" ;;
-	      *.la)
-		dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
-		test "X$dir" = "X$deplib" && dir="."
-		# We need an absolute path.
-		case $dir in
-		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
-		*)
-		  absdir=`cd "$dir" && pwd`
-		  if test -z "$absdir"; then
-		    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
-		    absdir="$dir"
-		  fi
-		  ;;
-		esac
-		if grep "^installed=no" $deplib > /dev/null; then
-		  path="$absdir/$objdir"
-		else
-		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-		  if test -z "$libdir"; then
-		    $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
-		    exit $EXIT_FAILURE
-		  fi
-		  if test "$absdir" != "$libdir"; then
-		    $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
-		  fi
-		  path="$absdir"
-		fi
-		depdepl=
-		case $host in
-		*-*-darwin*)
-		  # we do not want to link against static libs,
-		  # but need to link against shared
-		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
-		  eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
-		  if test -n "$deplibrary_names" ; then
-		    for tmp in $deplibrary_names ; do
-		      depdepl=$tmp
-		    done
-		    if test -f "$deplibdir/$depdepl" ; then
-		      depdepl="$deplibdir/$depdepl"
-	      	    elif test -f "$path/$depdepl" ; then
-		      depdepl="$path/$depdepl"
-		    else
-		      # Can't find it, oh well...
-		      depdepl=
-		    fi
-		    # do not add paths which are already there
-		    case " $newlib_search_path " in
-		    *" $path "*) ;;
-		    *) newlib_search_path="$newlib_search_path $path";;
-		    esac
-		  fi
-		  path=""
-		  ;;
-		*)
-		  path="-L$path"
-		  ;;
-		esac
-		;;
-	      -l*)
-		case $host in
-		*-*-darwin*)
-		  # Again, we only want to link against shared libraries
-		  eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
-		  for tmp in $newlib_search_path ; do
-		    if test -f "$tmp/lib$tmp_libs.dylib" ; then
-		      eval depdepl="$tmp/lib$tmp_libs.dylib"
-		      break
-		    fi
-		  done
-		  path=""
-		  ;;
-		*) continue ;;
-		esac
-		;;
-	      *) continue ;;
-	      esac
-	      case " $deplibs " in
-	      *" $path "*) ;;
-	      *) deplibs="$path $deplibs" ;;
-	      esac
-	      case " $deplibs " in
-	      *" $depdepl "*) ;;
-	      *) deplibs="$depdepl $deplibs" ;;
-	      esac
-	    done
-	  fi # link_all_deplibs != no
-	fi # linkmode = lib
-      done # for deplib in $libs
-      dependency_libs="$newdependency_libs"
-      if test "$pass" = dlpreopen; then
-	# Link the dlpreopened libraries before other libraries
-	for deplib in $save_deplibs; do
-	  deplibs="$deplib $deplibs"
-	done
-      fi
-      if test "$pass" != dlopen; then
-	if test "$pass" != conv; then
-	  # Make sure lib_search_path contains only unique directories.
-	  lib_search_path=
-	  for dir in $newlib_search_path; do
-	    case "$lib_search_path " in
-	    *" $dir "*) ;;
-	    *) lib_search_path="$lib_search_path $dir" ;;
-	    esac
-	  done
-	  newlib_search_path=
-	fi
 
-	if test "$linkmode,$pass" != "prog,link"; then
-	  vars="deplibs"
-	else
-	  vars="compile_deplibs finalize_deplibs"
-	fi
-	for var in $vars dependency_libs; do
-	  # Add libraries to $var in reverse order
-	  eval tmp_libs=\"\$$var\"
-	  new_libs=
-	  for deplib in $tmp_libs; do
-	    # FIXME: Pedantically, this is the right thing to do, so
-	    #        that some nasty dependency loop isn't accidentally
-	    #        broken:
-	    #new_libs="$deplib $new_libs"
-	    # Pragmatically, this seems to cause very few problems in
-	    # practice:
-	    case $deplib in
-	    -L*) new_libs="$deplib $new_libs" ;;
-	    -R*) ;;
-	    *)
-	      # And here is the reason: when a library appears more
-	      # than once as an explicit dependence of a library, or
-	      # is implicitly linked in more than once by the
-	      # compiler, it is considered special, and multiple
-	      # occurrences thereof are not removed.  Compare this
-	      # with having the same library being listed as a
-	      # dependency of multiple other libraries: in this case,
-	      # we know (pedantically, we assume) the library does not
-	      # need to be listed more than once, so we keep only the
-	      # last copy.  This is not always right, but it is rare
-	      # enough that we require users that really mean to play
-	      # such unportable linking tricks to link the library
-	      # using -Wl,-lname, so that libtool does not consider it
-	      # for duplicate removal.
-	      case " $specialdeplibs " in
-	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
-	      *)
-		case " $new_libs " in
-		*" $deplib "*) ;;
-		*) new_libs="$deplib $new_libs" ;;
-		esac
-		;;
-	      esac
-	      ;;
-	    esac
-	  done
-	  tmp_libs=
-	  for deplib in $new_libs; do
-	    case $deplib in
-	    -L*)
-	      case " $tmp_libs " in
-	      *" $deplib "*) ;;
-	      *) tmp_libs="$tmp_libs $deplib" ;;
-	      esac
-	      ;;
-	    *) tmp_libs="$tmp_libs $deplib" ;;
-	    esac
-	  done
-	  eval $var=\"$tmp_libs\"
-	done # for var
-      fi
-      # Last step: remove runtime libs from dependency_libs
-      # (they stay in deplibs)
-      tmp_libs=
-      for i in $dependency_libs ; do
-	case " $predeps $postdeps $compiler_lib_search_path " in
-	*" $i "*)
-	  i=""
-	  ;;
-	esac
-	if test -n "$i" ; then
-	  tmp_libs="$tmp_libs $i"
-	fi
-      done
-      dependency_libs=$tmp_libs
-    done # for pass
-    if test "$linkmode" = prog; then
-      dlfiles="$newdlfiles"
-      dlprefiles="$newdlprefiles"
-    fi
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
 
-    case $linkmode in
-    oldlib)
-      case " $deplibs" in
-      *\ -l* | *\ -L*)
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;;
-      esac
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
 
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
-      fi
+if test yes = "$_G_HAVE_XSI_OPS"; then
+  eval 'func_lo2o ()
+  {
+    case $1 in
+      *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+      *   ) func_lo2o_result=$1               ;;
+    esac
+  }'
 
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
-      fi
+  # func_xform LIBOBJ-OR-SOURCE
+  # ---------------------------
+  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+  # suffix to a '.lo' libtool-object suffix.
+  eval 'func_xform ()
+  {
+    func_xform_result=${1%.*}.lo
+  }'
+else
+  # ...otherwise fall back to using sed.
+  func_lo2o ()
+  {
+    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+  }
 
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
-      fi
+  func_xform ()
+  {
+    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+  }
+fi
 
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
-      fi
 
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
-      fi
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_fatal_error ${1+"$@"} \
+      "See the $PACKAGE documentation for more information." \
+      "Fatal configuration error."
+}
 
-      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
-	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
-      fi
 
-      # Now set the variables for building old libraries.
-      build_libtool_libs=no
-      oldlibs="$output"
-      objs="$objs$old_deplibs"
-      ;;
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
 
-    lib)
-      # Make sure we only generate libraries of the form `libNAME.la'.
-      case $outputname in
-      lib*)
-	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
-	eval shared_ext=\"$shrext_cmds\"
-	eval libname=\"$libname_spec\"
-	;;
-      *)
-	if test "$module" = no; then
-	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-	if test "$need_lib_prefix" != no; then
-	  # Add the "lib" prefix for modules if required
-	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-	  eval shared_ext=\"$shrext_cmds\"
-	  eval libname=\"$libname_spec\"
-	else
-	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
-	fi
-	;;
-      esac
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
 
-      if test -n "$objs"; then
-	if test "$deplibs_check_method" != pass_all; then
-	  $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
-	  exit $EXIT_FAILURE
-	else
-	  $echo
-	  $echo "*** Warning: Linking the shared library $output against the non-libtool"
-	  $echo "*** objects $objs is not portable!"
-	  libobjs="$libobjs $objs"
-	fi
-      fi
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
 
-      if test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
-      fi
+    exit $?
+}
 
-      set dummy $rpath
-      if test "$#" -gt 2; then
-	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
-      fi
-      install_libdir="$2"
 
-      oldlibs=
-      if test -z "$rpath"; then
-	if test "$build_libtool_libs" = yes; then
-	  # Building a libtool convenience library.
-	  # Some compilers have problems with a `.al' extension so
-	  # convenience libraries should have the same extension an
-	  # archive normally would.
-	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
-	  build_libtool_libs=convenience
-	  build_old_libs=yes
-	fi
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test yes = "$build_libtool_libs"; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test yes = "$build_old_libs"; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
 
-	if test -n "$vinfo"; then
-	  $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
-	fi
+    exit $?
+}
 
-	if test -n "$release"; then
-	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
-	fi
-      else
 
-	# Parse the version information argument.
-	save_ifs="$IFS"; IFS=':'
-	set dummy $vinfo 0 0 0
-	IFS="$save_ifs"
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+    # Global variable:
+    tagname=$1
 
-	if test -n "$8"; then
-	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
-	  $echo "$help" 1>&2
-	  exit $EXIT_FAILURE
-	fi
+    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+    sed_extractcf=/$re_begincf/,/$re_endcf/p
 
-	# convert absolute version numbers to libtool ages
-	# this retains compatibility with .la files and attempts
-	# to make the code below a bit more comprehensible
+    # Validate tagname.
+    case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+        func_fatal_error "invalid tag name: $tagname"
+        ;;
+    esac
 
-	case $vinfo_number in
-	yes)
-	  number_major="$2"
-	  number_minor="$3"
-	  number_revision="$4"
-	  #
-	  # There are really only two kinds -- those that
-	  # use the current revision as the major version
-	  # and those that subtract age and use age as
-	  # a minor version.  But, then there is irix
-	  # which has an extra 1 added just for fun
-	  #
-	  case $version_type in
-	  darwin|linux|osf|windows|none)
-	    current=`expr $number_major + $number_minor`
-	    age="$number_minor"
-	    revision="$number_revision"
-	    ;;
-	  freebsd-aout|freebsd-elf|sunos)
-	    current="$number_major"
-	    revision="$number_minor"
-	    age="0"
-	    ;;
-	  irix|nonstopux)
-	    current=`expr $number_major + $number_minor`
-	    age="$number_minor"
-	    revision="$number_minor"
-	    lt_irix_increment=no
-	    ;;
-	  esac
-	  ;;
-	no)
-	  current="$2"
-	  revision="$3"
-	  age="$4"
-	  ;;
-	esac
+    # Don't test for the "default" C tag, as we know it's
+    # there but not specially marked.
+    case $tagname in
+        CC) ;;
+    *)
+        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	  taglist="$taglist $tagname"
 
-	# Check that each of the things are valid numbers.
-	case $current in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
+	  # Evaluate the configuration.  Be careful to quote the path
+	  # and the sed script, to avoid splitting on whitespace, but
+	  # also don't use non-portable quotes within backquotes within
+	  # quotes we have to do it in 2 steps:
+	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	  eval "$extractedcf"
+        else
+	  func_error "ignoring unknown tag $tagname"
+        fi
+        ;;
+    esac
+}
 
-	case $revision in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
 
-	case $age in
-	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
-	*)
-	  $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+    if test "$package_revision" != "$macro_revision"; then
+      if test "$VERSION" != "$macro_version"; then
+        if test -z "$macro_version"; then
+          cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+        else
+          cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+        fi
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+      fi
 
-	if test "$age" -gt "$current"; then
-	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
-	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
-	  exit $EXIT_FAILURE
-	fi
+      exit $EXIT_MISMATCH
+    fi
+}
 
-	# Calculate the version variables.
-	major=
-	versuffix=
-	verstring=
-	case $version_type in
-	none) ;;
 
-	darwin)
-	  # Like Linux, but with the current version available in
-	  # verstring for coding it into the library header
-	  major=.`expr $current - $age`
-	  versuffix="$major.$age.$revision"
-	  # Darwin ld doesn't like 0 for these options...
-	  minor_current=`expr $current + 1`
-	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
-	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
-	  ;;
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+    $debug_mode
+
+    # Option defaults:
+    opt_config=false
+    opt_dlopen=
+    opt_dry_run=false
+    opt_help=false
+    opt_mode=
+    opt_reorder_cache=false
+    opt_preserve_dup_deps=false
+    opt_quiet=false
+    opt_finishing=true
+    opt_warning=
+
+    nonopt=
+    preserve_args=
+
+    _G_rc_lt_options_prep=:
+
+    # Shorthand for --mode=foo, only valid as the first argument
+    case $1 in
+    clean|clea|cle|cl)
+      shift; set dummy --mode clean ${1+"$@"}; shift
+      ;;
+    compile|compil|compi|comp|com|co|c)
+      shift; set dummy --mode compile ${1+"$@"}; shift
+      ;;
+    execute|execut|execu|exec|exe|ex|e)
+      shift; set dummy --mode execute ${1+"$@"}; shift
+      ;;
+    finish|finis|fini|fin|fi|f)
+      shift; set dummy --mode finish ${1+"$@"}; shift
+      ;;
+    install|instal|insta|inst|ins|in|i)
+      shift; set dummy --mode install ${1+"$@"}; shift
+      ;;
+    link|lin|li|l)
+      shift; set dummy --mode link ${1+"$@"}; shift
+      ;;
+    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+      shift; set dummy --mode uninstall ${1+"$@"}; shift
+      ;;
+    *)
+      _G_rc_lt_options_prep=false
+      ;;
+    esac
 
-	freebsd-aout)
-	  major=".$current"
-	  versuffix=".$current.$revision";
-	  ;;
+    if $_G_rc_lt_options_prep; then
+      # Pass back the list of options.
+      func_quote eval ${1+"$@"}
+      libtool_options_prep_result=$func_quote_result
+    fi
+}
+func_add_hook func_options_prep libtool_options_prep
 
-	freebsd-elf)
-	  major=".$current"
-	  versuffix=".$current";
-	  ;;
 
-	irix | nonstopux)
-	  if test "X$lt_irix_increment" = "Xno"; then
-	    major=`expr $current - $age`
-	  else
-	    major=`expr $current - $age + 1`
-	  fi
-	  case $version_type in
-	    nonstopux) verstring_prefix=nonstopux ;;
-	    *)         verstring_prefix=sgi ;;
-	  esac
-	  verstring="$verstring_prefix$major.$revision"
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+    $debug_cmd
 
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$revision
-	  while test "$loop" -ne 0; do
-	    iface=`expr $revision - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="$verstring_prefix$major.$iface:$verstring"
-	  done
+    _G_rc_lt_parse_options=false
 
-	  # Before this point, $major must not contain `.'.
-	  major=.$major
-	  versuffix="$major.$revision"
-	  ;;
+    # Perform our own loop to consume as many options as possible in
+    # each iteration.
+    while test $# -gt 0; do
+      _G_match_lt_parse_options=:
+      _G_opt=$1
+      shift
+      case $_G_opt in
+        --dry-run|--dryrun|-n)
+                        opt_dry_run=:
+                        ;;
+
+        --config)       func_config ;;
+
+        --dlopen|-dlopen)
+                        opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+                        shift
+                        ;;
+
+        --preserve-dup-deps)
+                        opt_preserve_dup_deps=: ;;
+
+        --features)     func_features ;;
+
+        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;
+
+        --help)         opt_help=: ;;
+
+        --help-all)     opt_help=': help-all' ;;
+
+        --mode)         test $# = 0 && func_missing_arg $_G_opt && break
+                        opt_mode=$1
+                        case $1 in
+                          # Valid mode arguments:
+                          clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+                          # Catch anything else as an error
+                          *) func_error "invalid argument '$1' for $_G_opt"
+                             exit_cmd=exit
+                             ;;
+                        esac
+                        shift
+                        ;;
+
+        --no-finish)
+                        opt_finishing=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --no-silent|--no-quiet)
+                        opt_quiet=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --no-warnings|--no-warning|--no-warn)
+                        opt_warning=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --no-verbose)
+                        opt_verbose=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --reorder-cache)
+                        opt_reorder_cache=true
+                        shared_lib_dirs=$1
+                        if test -n "$shared_lib_dirs"; then
+                          case $1 in
+                            # Must begin with /:
+                            /*) ;;
+
+                            # Catch anything else as an error (relative paths)
+                            *) func_error "invalid argument '$1' for $_G_opt"
+                               func_error "absolute paths are required for $_G_opt"
+                               exit_cmd=exit
+                               ;;
+                          esac
+                        fi
+                        shift
+                        ;;
+
+        --silent|--quiet)
+                        opt_quiet=:
+                        opt_verbose=false
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        --tag)          test $# = 0 && func_missing_arg $_G_opt && break
+                        opt_tag=$1
+                        func_append preserve_args " $_G_opt $1"
+                        func_enable_tag "$1"
+                        shift
+                        ;;
+
+        --verbose|-v)   opt_quiet=false
+                        opt_verbose=:
+                        func_append preserve_args " $_G_opt"
+                        ;;
+
+        # An option not handled by this hook function:
+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
+                        _G_match_lt_parse_options=false
+                        break
+                        ;;
+      esac
+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
+    done
 
-	linux)
-	  major=.`expr $current - $age`
-	  versuffix="$major.$age.$revision"
-	  ;;
+    if $_G_rc_lt_parse_options; then
+      # save modified positional parameters for caller
+      func_quote eval ${1+"$@"}
+      libtool_parse_options_result=$func_quote_result
+    fi
+}
+func_add_hook func_parse_options libtool_parse_options
 
-	osf)
-	  major=.`expr $current - $age`
-	  versuffix=".$current.$age.$revision"
-	  verstring="$current.$age.$revision"
 
-	  # Add in all the interfaces that we are compatible with.
-	  loop=$age
-	  while test "$loop" -ne 0; do
-	    iface=`expr $current - $loop`
-	    loop=`expr $loop - 1`
-	    verstring="$verstring:${iface}.0"
-	  done
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+    if $opt_warning; then
+        $debug_cmd
+        $warning_func ${1+"$@"}
+    fi
+}
 
-	  # Make executables depend on our current version.
-	  verstring="$verstring:${current}.0"
-	  ;;
 
-	sunos)
-	  major=".$current"
-	  versuffix=".$current.$revision"
-	  ;;
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+    # save first non-option argument
+    if test 0 -lt $#; then
+      nonopt=$1
+      shift
+    fi
 
-	windows)
-	  # Use '-' rather than '.', since we only want one
-	  # extension on DOS 8.3 filesystems.
-	  major=`expr $current - $age`
-	  versuffix="-$major"
-	  ;;
+    # preserve --debug
+    test : = "$debug_cmd" || func_append preserve_args " --debug"
 
-	*)
-	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
-	  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
-	  exit $EXIT_FAILURE
-	  ;;
-	esac
+    case $host_os in
+      # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+      # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+      cygwin* | mingw* | windows* | pw32* | cegcc* | solaris2* | os2*)
+        # don't eliminate duplications in $postdeps and $predeps
+        opt_duplicate_compiler_generated_deps=:
+        ;;
+      *)
+        opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+        ;;
+    esac
 
-	# Clear the version info if we defaulted, and they specified a release.
-	if test -z "$vinfo" && test -n "$release"; then
-	  major=
-	  case $version_type in
-	  darwin)
-	    # we can't check for "0.0" in archive_cmds due to quoting
-	    # problems, so we reset it completely
-	    verstring=
-	    ;;
-	  *)
-	    verstring="0.0"
-	    ;;
-	  esac
-	  if test "$need_version" = no; then
-	    versuffix=
-	  else
-	    versuffix=".0.0"
-	  fi
-	fi
+    $opt_help || {
+      # Sanity checks first:
+      func_check_version_match
 
-	# Remove version info from name if versioning should be avoided
-	if test "$avoid_version" = yes && test "$need_version" = no; then
-	  major=
-	  versuffix=
-	  verstring=""
-	fi
+      test yes != "$build_libtool_libs" \
+        && test yes != "$build_old_libs" \
+        && func_fatal_configuration "not configured to build any kind of library"
 
-	# Check to see if the archive will have undefined symbols.
-	if test "$allow_undefined" = yes; then
-	  if test "$allow_undefined_flag" = unsupported; then
-	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
-	    build_libtool_libs=no
-	    build_old_libs=yes
-	  fi
-	else
-	  # Don't allow undefined symbols.
-	  allow_undefined_flag="$no_undefined_flag"
-	fi
+      # Darwin sucks
+      eval std_shrext=\"$shrext_cmds\"
+
+      # Only execute mode is allowed to have -dlopen flags.
+      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+        func_error "unrecognized option '-dlopen'"
+        $ECHO "$help" 1>&2
+        exit $EXIT_FAILURE
       fi
 
-      if test "$mode" != relink; then
-	# Remove our outputs, but don't remove object files since they
-	# may have been created when compiling PIC objects.
-	removelist=
-	tempremovelist=`$echo "$output_objdir/*"`
-	for p in $tempremovelist; do
-	  case $p in
-	    *.$objext | *.gcno)
-	       ;;
-	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
-	       if test "X$precious_files_regex" != "X"; then
-	         if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
-	         then
-		   continue
-		 fi
-	       fi
-	       removelist="$removelist $p"
-	       ;;
-	    *) ;;
-	  esac
-	done
-	if test -n "$removelist"; then
-	  $show "${rm}r $removelist"
-	  $run ${rm}r $removelist
-	fi
-      fi
+      # Change the help message to a mode-specific one.
+      generic_help=$help
+      help="Try '$progname --help --mode=$opt_mode' for more information."
+    }
 
-      # Now set the variables for building old libraries.
-      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
-	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+    # Pass back the unparsed argument list
+    func_quote eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_result
+}
+func_add_hook func_validate_options libtool_validate_options
 
-	# Transform .lo files to .o files.
-	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
-      fi
 
-      # Eliminate all temporary directories.
-      #for path in $notinst_path; do
-      #	lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
-      #	deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
-      #	dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
-      #done
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
 
-      if test -n "$xrpath"; then
-	# If the user specified any rpath flags, then add them.
-	temp_xrpath=
-	for libdir in $xrpath; do
-	  temp_xrpath="$temp_xrpath -R$libdir"
-	  case "$finalize_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
-	  esac
-	done
-	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
-	  dependency_libs="$temp_xrpath $dependency_libs"
-	fi
-      fi
 
-      # Make sure dlfiles contains only unique files that won't be dlpreopened
-      old_dlfiles="$dlfiles"
-      dlfiles=
-      for lib in $old_dlfiles; do
-	case " $dlprefiles $dlfiles " in
-	*" $lib "*) ;;
-	*) dlfiles="$dlfiles $lib" ;;
-	esac
-      done
 
-      # Make sure dlprefiles contains only unique files
-      old_dlprefiles="$dlprefiles"
-      dlprefiles=
-      for lib in $old_dlprefiles; do
-	case "$dlprefiles " in
-	*" $lib "*) ;;
-	*) dlprefiles="$dlprefiles $lib" ;;
-	esac
-      done
+## ----------- ##
+##    Main.    ##
+## ----------- ##
 
-      if test "$build_libtool_libs" = yes; then
-	if test -n "$rpath"; then
-	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
-	    # these systems don't actually have a c library (as such)!
-	    ;;
-	  *-*-rhapsody* | *-*-darwin1.[012])
-	    # Rhapsody C library is in the System framework
-	    deplibs="$deplibs -framework System"
-	    ;;
-	  *-*-netbsd*)
-	    # Don't link with libc until the a.out ld.so is fixed.
-	    ;;
-	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
-	    # Do not include libc due to us having libc/libc_r.
-	    ;;
-	  *-*-sco3.2v5* | *-*-sco5v6*)
-	    # Causes problems with __ctype
-	    ;;
-	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
-	    # Compiler inserts libc in the correct place for threads to work
-	    ;;
- 	  *)
-	    # Add libc to deplibs on all other systems if necessary.
-	    if test "$build_libtool_need_lc" = "yes"; then
-	      deplibs="$deplibs -lc"
-	    fi
-	    ;;
-	  esac
-	fi
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
 
-	# Transform deplibs into only deplibs that can be linked in shared.
-	name_save=$name
-	libname_save=$libname
-	release_save=$release
-	versuffix_save=$versuffix
-	major_save=$major
-	# I'm not sure if I'm treating the release correctly.  I think
-	# release should show up in the -l (ie -lgmp5) so we don't want to
-	# add it in twice.  Is that correct?
-	release=""
-	versuffix=""
-	major=""
-	newdeplibs=
-	droppeddeps=no
-	case $deplibs_check_method in
-	pass_all)
-	  # Don't check for shared/static.  Everything works.
-	  # This might be a little naive.  We might want to check
-	  # whether the library exists or not.  But this is on
-	  # osf3 & osf4 and I'm not really sure... Just
-	  # implementing what was already the behavior.
-	  newdeplibs=$deplibs
-	  ;;
-	test_compile)
-	  # This code stresses the "libraries are programs" paradigm to its
-	  # limits. Maybe even breaks it.  We compile a program, linking it
-	  # against the deplibs as a proxy for the library.  Then we can check
-	  # whether they linked in statically or dynamically with ldd.
-	  $rm conftest.c
-	  cat > conftest.c </dev/null`
-		  for potent_lib in $potential_libs; do
-		      # Follow soft links.
-		      if ls -lLd "$potent_lib" 2>/dev/null \
-			 | grep " -> " >/dev/null; then
-			continue
-		      fi
-		      # The statement above tries to avoid entering an
-		      # endless loop below, in case of cyclic links.
-		      # We might still enter an endless loop, since a link
-		      # loop can be closed while we follow links,
-		      # but so what?
-		      potlib="$potent_lib"
-		      while test -h "$potlib" 2>/dev/null; do
-			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
-			case $potliblink in
-			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
-			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
-			esac
-		      done
-		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
-			 | ${SED} 10q \
-			 | $EGREP "$file_magic_regex" > /dev/null; then
-			newdeplibs="$newdeplibs $a_deplib"
-			a_deplib=""
-			break 2
-		      fi
-		  done
-		done
-	      fi
-	      if test -n "$a_deplib" ; then
-		droppeddeps=yes
-		$echo
-		$echo "*** Warning: linker path does not have real file for library $a_deplib."
-		$echo "*** I have the capability to make that library automatically link in when"
-		$echo "*** you link to this library.  But I can only do this if you have a"
-		$echo "*** shared version of the library, which you do not appear to have"
-		$echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib" ; then
-		  $echo "*** with $libname but no candidates were found. (...for file magic test)"
-		else
-		  $echo "*** with $libname and none of the candidates passed a file format test"
-		  $echo "*** using a file magic. Last file checked: $potlib"
-		fi
-	      fi
-	    else
-	      # Add a -L argument.
-	      newdeplibs="$newdeplibs $a_deplib"
-	    fi
-	  done # Gone through all deplibs.
-	  ;;
-	match_pattern*)
-	  set dummy $deplibs_check_method
-	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
-	  for a_deplib in $deplibs; do
-	    name=`expr $a_deplib : '-l\(.*\)'`
-	    # If $name is empty we are operating on a -L argument.
-	    if test -n "$name" && test "$name" != "0"; then
-	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-		case " $predeps $postdeps " in
-		*" $a_deplib "*)
-		  newdeplibs="$newdeplibs $a_deplib"
-		  a_deplib=""
-		  ;;
-		esac
-	      fi
-	      if test -n "$a_deplib" ; then
-		libname=`eval \\$echo \"$libname_spec\"`
-		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
-		  for potent_lib in $potential_libs; do
-		    potlib="$potent_lib" # see symlink-check above in file_magic test
-		    if eval $echo \"$potent_lib\" 2>/dev/null \
-		        | ${SED} 10q \
-		        | $EGREP "$match_pattern_regex" > /dev/null; then
-		      newdeplibs="$newdeplibs $a_deplib"
-		      a_deplib=""
-		      break 2
-		    fi
-		  done
-		done
-	      fi
-	      if test -n "$a_deplib" ; then
-		droppeddeps=yes
-		$echo
-		$echo "*** Warning: linker path does not have real file for library $a_deplib."
-		$echo "*** I have the capability to make that library automatically link in when"
-		$echo "*** you link to this library.  But I can only do this if you have a"
-		$echo "*** shared version of the library, which you do not appear to have"
-		$echo "*** because I did check the linker path looking for a file starting"
-		if test -z "$potlib" ; then
-		  $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
-		else
-		  $echo "*** with $libname and none of the candidates passed a file format test"
-		  $echo "*** using a regex pattern. Last file checked: $potlib"
-		fi
-	      fi
-	    else
-	      # Add a -L argument.
-	      newdeplibs="$newdeplibs $a_deplib"
-	    fi
-	  done # Gone through all deplibs.
-	  ;;
-	none | unknown | *)
-	  newdeplibs=""
-	  tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
-	    -e 's/ -[LR][^ ]*//g'`
-	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
-	    for i in $predeps $postdeps ; do
-	      # can't use Xsed below, because $i might contain '/'
-	      tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
-	    done
-	  fi
-	  if $echo "X $tmp_deplibs" | $Xsed -e 's/[ 	]//g' \
-	    | grep . >/dev/null; then
-	    $echo
-	    if test "X$deplibs_check_method" = "Xnone"; then
-	      $echo "*** Warning: inter-library dependencies are not supported in this platform."
-	    else
-	      $echo "*** Warning: inter-library dependencies are not known to be supported."
-	    fi
-	    $echo "*** All declared inter-library dependencies are being dropped."
-	    droppeddeps=yes
-	  fi
-	  ;;
-	esac
-	versuffix=$versuffix_save
-	major=$major_save
-	release=$release_save
-	libname=$libname_save
-	name=$name_save
+# Global variables.
+extracted_archives=
+extracted_serial=0
 
-	case $host in
-	*-*-rhapsody* | *-*-darwin1.[012])
-	  # On Rhapsody replace the C library is the System framework
-	  newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	  ;;
-	esac
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
 
-	if test "$droppeddeps" = yes; then
-	  if test "$module" = yes; then
-	    $echo
-	    $echo "*** Warning: libtool could not satisfy all declared inter-library"
-	    $echo "*** dependencies of module $libname.  Therefore, libtool will create"
-	    $echo "*** a static module, that should work as long as the dlopening"
-	    $echo "*** application is linked with the -dlopen flag."
-	    if test -z "$global_symbol_pipe"; then
-	      $echo
-	      $echo "*** However, this would only work if libtool was able to extract symbol"
-	      $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
-	      $echo "*** not find such a program.  So, this module is probably useless."
-	      $echo "*** \`nm' from GNU binutils and a full rebuild may help."
-	    fi
-	    if test "$build_old_libs" = no; then
-	      oldlibs="$output_objdir/$libname.$libext"
-	      build_libtool_libs=module
-	      build_old_libs=yes
-	    else
-	      build_libtool_libs=no
-	    fi
-	  else
-	    $echo "*** The inter-library dependencies that have been dropped here will be"
-	    $echo "*** automatically added whenever a program is linked with this library"
-	    $echo "*** or is declared to -dlopen it."
-
-	    if test "$allow_undefined" = no; then
-	      $echo
-	      $echo "*** Since this library must not contain undefined symbols,"
-	      $echo "*** because either the platform does not support them or"
-	      $echo "*** it was explicitly requested with -no-undefined,"
-	      $echo "*** libtool will only create a static version of it."
-	      if test "$build_old_libs" = no; then
-		oldlibs="$output_objdir/$libname.$libext"
-		build_libtool_libs=module
-		build_old_libs=yes
-	      else
-		build_libtool_libs=no
-	      fi
-	    fi
-	  fi
-	fi
-	# Done checking deplibs!
-	deplibs=$newdeplibs
-      fi
 
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
 
-      # move library search paths that coincide with paths to not yet
-      # installed libraries to the beginning of the library search list
-      new_libs=
-      for path in $notinst_path; do
-	case " $new_libs " in
-	*" -L$path/$objdir "*) ;;
-	*)
-	  case " $deplibs " in
-	  *" -L$path/$objdir "*)
-	    new_libs="$new_libs -L$path/$objdir" ;;
-	  esac
-	  ;;
-	esac
-      done
-      for deplib in $deplibs; do
-	case $deplib in
-	-L*)
-	  case " $new_libs " in
-	  *" $deplib "*) ;;
-	  *) new_libs="$new_libs $deplib" ;;
-	  esac
-	  ;;
-	*) new_libs="$new_libs $deplib" ;;
-	esac
-      done
-      deplibs="$new_libs"
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
 
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
 
-      # All the library-specific variables (install_libdir is set above).
-      library_names=
-      old_library=
-      dlname=
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case $lalib_p_line in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test yes = "$lalib_p"
+}
 
-      # Test again, we may have decided not to build it any more
-      if test "$build_libtool_libs" = yes; then
-	if test "$hardcode_into_libs" = yes; then
-	  # Hardcode the library paths
-	  hardcode_libdirs=
-	  dep_rpath=
-	  rpath="$finalize_rpath"
-	  test "$mode" != relink && rpath="$compile_rpath$rpath"
-	  for libdir in $rpath; do
-	    if test -n "$hardcode_libdir_flag_spec"; then
-	      if test -n "$hardcode_libdir_separator"; then
-		if test -z "$hardcode_libdirs"; then
-		  hardcode_libdirs="$libdir"
-		else
-		  # Just accumulate the unique libdirs.
-		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		    ;;
-		  *)
-		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		    ;;
-		  esac
-		fi
-	      else
-		eval flag=\"$hardcode_libdir_flag_spec\"
-		dep_rpath="$dep_rpath $flag"
-	      fi
-	    elif test -n "$runpath_var"; then
-	      case "$perm_rpath " in
-	      *" $libdir "*) ;;
-	      *) perm_rpath="$perm_rpath $libdir" ;;
-	      esac
-	    fi
-	  done
-	  # Substitute the hardcoded libdirs into the rpath.
-	  if test -n "$hardcode_libdir_separator" &&
-	     test -n "$hardcode_libdirs"; then
-	    libdir="$hardcode_libdirs"
-	    if test -n "$hardcode_libdir_flag_spec_ld"; then
-	      case $archive_cmds in
-	      *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;;
-	      *)      eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;;
-	      esac
-	    else
-	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
-	    fi
-	  fi
-	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
-	    # We should set the runpath_var.
-	    rpath=
-	    for dir in $perm_rpath; do
-	      rpath="$rpath$dir:"
-	    done
-	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
-	  fi
-	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
-	fi
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    test -f "$1" &&
+      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
 
-	shlibpath="$finalize_shlibpath"
-	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
-	if test -n "$shlibpath"; then
-	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
-	fi
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
 
-	# Get the real and link names of the library.
-	eval shared_ext=\"$shrext_cmds\"
-	eval library_names=\"$library_names_spec\"
-	set dummy $library_names
-	realname="$2"
-	shift; shift
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
 
-	if test -n "$soname_spec"; then
-	  eval soname=\"$soname_spec\"
-	else
-	  soname="$realname"
-	fi
-	if test -z "$dlname"; then
-	  dlname=$soname
-	fi
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
 
-	lib="$output_objdir/$realname"
-	linknames=
-	for link
-	do
-	  linknames="$linknames $link"
-	done
 
-	# Use standard objects if they are pic
-	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $debug_cmd
+
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$sp$nl
+      eval cmd=\"$cmd\"
+      IFS=$save_ifs
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
 
-	# Prepare the list of exported symbols
-	if test -z "$export_symbols"; then
-	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
-	    $show "generating symbol list for \`$libname.la'"
-	    export_symbols="$output_objdir/$libname.exp"
-	    $run $rm $export_symbols
-	    cmds=$export_symbols_cmds
-	    save_ifs="$IFS"; IFS='~'
-	    for cmd in $cmds; do
-	      IFS="$save_ifs"
-	      eval cmd=\"$cmd\"
-	      if len=`expr "X$cmd" : ".*"` &&
-	       test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	        $show "$cmd"
-	        $run eval "$cmd" || exit $?
-	        skipped_export=false
-	      else
-	        # The command line is too long to execute in one step.
-	        $show "using reloadable object file for export list..."
-	        skipped_export=:
-		# Break out early, otherwise skipped_export may be
-		# set to false by a later but shorter cmd.
-		break
-	      fi
-	    done
-	    IFS="$save_ifs"
-	    if test -n "$export_symbols_regex"; then
-	      $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
-	      $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
-	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
-	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
-	    fi
-	  fi
-	fi
 
-	if test -n "$export_symbols" && test -n "$include_expsyms"; then
-	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
-	fi
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $debug_cmd
 
-	tmp_deplibs=
-	for test_deplib in $deplibs; do
-		case " $convenience " in
-		*" $test_deplib "*) ;;
-		*)
-			tmp_deplibs="$tmp_deplibs $test_deplib"
-			;;
-		esac
-	done
-	deplibs="$tmp_deplibs"
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
 
-	if test -n "$convenience"; then
-	  if test -n "$whole_archive_flag_spec"; then
-	    save_libobjs=$libobjs
-	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
-	  else
-	    gentop="$output_objdir/${outputname}x"
-	    generated="$generated $gentop"
 
-	    func_extract_archives $gentop $convenience
-	    libobjs="$libobjs $func_extract_archives_result"
-	  fi
-	fi
-	
-	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
-	  eval flag=\"$thread_safe_flag_spec\"
-	  linker_flags="$linker_flags $flag"
-	fi
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
 
-	# Make a backup of the uninstalled library when relinking
-	if test "$mode" = relink; then
-	  $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
-	fi
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case $lt_sysroot:$1 in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result='='$func_stripname_result
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
 
-	# Do each of the archive commands.
-	if test "$module" = yes && test -n "$module_cmds" ; then
-	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
-	    eval test_cmds=\"$module_expsym_cmds\"
-	    cmds=$module_expsym_cmds
-	  else
-	    eval test_cmds=\"$module_cmds\"
-	    cmds=$module_cmds
-	  fi
-	else
-	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
-	  eval test_cmds=\"$archive_expsym_cmds\"
-	  cmds=$archive_expsym_cmds
-	else
-	  eval test_cmds=\"$archive_cmds\"
-	  cmds=$archive_cmds
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $debug_cmd
+
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
 	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with '--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
 	fi
+	;;
+      esac
+    fi
+}
 
-	if test "X$skipped_export" != "X:" &&
-	   len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-	   test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
-	  :
-	else
-	  # The command line is too long to link in one step, link piecewise.
-	  $echo "creating reloadable object files..."
-
-	  # Save the value of $output and $libobjs because we want to
-	  # use them later.  If we have whole_archive_flag_spec, we
-	  # want to use save_libobjs as it was before
-	  # whole_archive_flag_spec was expanded, because we can't
-	  # assume the linker understands whole_archive_flag_spec.
-	  # This may have to be revisited, in case too many
-	  # convenience libraries get linked in and end up exceeding
-	  # the spec.
-	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
-	    save_libobjs=$libobjs
-	  fi
-	  save_output=$output
-	  output_la=`$echo "X$output" | $Xsed -e "$basename"`
 
-	  # Clear the reloadable object creation command queue and
-	  # initialize k to one.
-	  test_cmds=
-	  concat_cmds=
-	  objlist=
-	  delfiles=
-	  last_robj=
-	  k=1
-	  output=$output_objdir/$output_la-${k}.$objext
-	  # Loop over the list of objects to be linked.
-	  for obj in $save_libobjs
-	  do
-	    eval test_cmds=\"$reload_cmds $objlist $last_robj\"
-	    if test "X$objlist" = X ||
-	       { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
-		 test "$len" -le "$max_cmd_len"; }; then
-	      objlist="$objlist $obj"
-	    else
-	      # The command $test_cmds is almost too long, add a
-	      # command to the queue.
-	      if test "$k" -eq 1 ; then
-		# The first file doesn't have a previous command to add.
-		eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
-	      else
-		# All subsequent reloadable object files will link in
-		# the last one created.
-		eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
-	      fi
-	      last_robj=$output_objdir/$output_la-${k}.$objext
-	      k=`expr $k + 1`
-	      output=$output_objdir/$output_la-${k}.$objext
-	      objlist=$obj
-	      len=1
-	    fi
-	  done
-	  # Handle the remaining objects by creating one last
-	  # reloadable object file.  All subsequent reloadable object
-	  # files will link in the last one created.
-	  test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-	  eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
-
-	  if ${skipped_export-false}; then
-	    $show "generating symbol list for \`$libname.la'"
-	    export_symbols="$output_objdir/$libname.exp"
-	    $run $rm $export_symbols
-	    libobjs=$output
-	    # Append the command to create the export file.
-	    eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
-          fi
 
-	  # Set up a command to remove the reloadable object files
-	  # after they are used.
-	  i=0
-	  while test "$i" -lt "$k"
-	  do
-	    i=`expr $i + 1`
-	    delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
-	  done
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=$1
+    if test yes = "$build_libtool_libs"; then
+      write_lobj=\'$2\'
+    else
+      write_lobj=none
+    fi
 
-	  $echo "creating a temporary reloadable object file: $output"
+    if test yes = "$build_old_libs"; then
+      write_oldobj=\'$3\'
+    else
+      write_oldobj=none
+    fi
 
-	  # Loop through the commands generated above and execute them.
-	  save_ifs="$IFS"; IFS='~'
-	  for cmd in $concat_cmds; do
-	    IFS="$save_ifs"
-	    $show "$cmd"
-	    $run eval "$cmd" || exit $?
-	  done
-	  IFS="$save_ifs"
+    $opt_dry_run || {
+      cat >${write_libobj}T </dev/null`
+    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
 
-	# Restore the uninstalled library and exit
-	if test "$mode" = relink; then
-	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
 
-	  if test -n "$convenience"; then
-	    if test -z "$whole_archive_flag_spec"; then
-	      $show "${rm}r $gentop"
-	      $run ${rm}r "$gentop"
-	    fi
-	  fi
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH. Assumes ARG has no leading or trailing path separator
+# characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $debug_cmd
+
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result"; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $debug_cmd
 
-	  exit $EXIT_SUCCESS
-	fi
-
-	# Create links to the real library.
-	for linkname in $linknames; do
-	  if test "$realname" != "$linkname"; then
-	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
-	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
-	  fi
-	done
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
 
-	# If -module or -export-dynamic was specified, set the dlname.
-	if test "$module" = yes || test "$export_dynamic" = yes; then
-	  # On all known operating systems, these are identical.
-	  dlname="$soname"
-	fi
-      fi
-      ;;
 
-    obj)
-      case " $deplibs" in
-      *\ -l* | *\ -L*)
-	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;;
-      esac
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $debug_cmd
 
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
-      fi
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
 
-      if test -n "$rpath"; then
-	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
-      fi
 
-      if test -n "$xrpath"; then
-	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
-      fi
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $debug_cmd
+
+  if test -z "$2" && test -n "$1"; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  '$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result=$1
+  fi
+}
+# end func_convert_file_check
 
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
-      fi
 
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
-      fi
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $debug_cmd
+
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  '$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result=$3
+    fi
+  fi
+}
+# end func_convert_path_check
 
-      case $output in
-      *.lo)
-	if test -n "$objs$old_deplibs"; then
-	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
-	  exit $EXIT_FAILURE
-	fi
-	libobj="$output"
-	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
-	;;
-      *)
-	libobj=
-	obj="$output"
-	;;
-      esac
 
-      # Delete the old objects.
-      $run $rm $obj $libobj
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $debug_cmd
 
-      # Objects from convenience libraries.  This assumes
-      # single-version convenience libraries.  Whenever we create
-      # different ones for PIC/non-PIC, this we'll have to duplicate
-      # the extraction.
-      reload_conv_objs=
-      gentop=
-      # reload_cmds runs $LD directly, so let us get rid of
-      # -Wl from whole_archive_flag_spec and hope we can get by with
-      # turning comma into space..
-      wl=
+  case $4 in
+  $1 ) func_to_host_path_result=$3$func_to_host_path_result
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
 
-      if test -n "$convenience"; then
-	if test -n "$whole_archive_flag_spec"; then
-	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
-	  reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
-	else
-	  gentop="$output_objdir/${obj}x"
-	  generated="$generated $gentop"
 
-	  func_extract_archives $gentop $convenience
-	  reload_conv_objs="$reload_objs $func_extract_archives_result"
-	fi
-      fi
+# func_convert_delimited_path PATH ORIG_DELIMITER NEW_DELIMITER
+# Replaces a delimiter for a given path.
+func_convert_delimited_path ()
+{
+	converted_path=`$ECHO "$1" | $SED "s#$2#$3#g"`
+}
+# end func_convert_delimited_path
 
-      # Create the old-style object.
-      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
-
-      output="$obj"
-      cmds=$reload_cmds
-      save_ifs="$IFS"; IFS='~'
-      for cmd in $cmds; do
-	IFS="$save_ifs"
-	eval cmd=\"$cmd\"
-	$show "$cmd"
-	$run eval "$cmd" || exit $?
-      done
-      IFS="$save_ifs"
 
-      # Exit if we aren't doing a library object file.
-      if test -z "$libobj"; then
-	if test -n "$gentop"; then
-	  $show "${rm}r $gentop"
-	  $run ${rm}r $gentop
-	fi
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
 
-	exit $EXIT_SUCCESS
-      fi
 
-      if test "$build_libtool_libs" != yes; then
-	if test -n "$gentop"; then
-	  $show "${rm}r $gentop"
-	  $run ${rm}r $gentop
-	fi
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $debug_cmd
 
-	# Create an invalid libtool object if no PIC, so that we don't
-	# accidentally link it into a program.
-	# $show "echo timestamp > $libobj"
-	# $run eval "echo timestamp > $libobj" || exit $?
-	exit $EXIT_SUCCESS
-      fi
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
 
-      if test -n "$pic_flag" || test "$pic_mode" != default; then
-	# Only do commands if we really have different PIC objects.
-	reload_objs="$libobjs $reload_conv_objs"
-	output="$libobj"
-	cmds=$reload_cmds
-	save_ifs="$IFS"; IFS='~'
-	for cmd in $cmds; do
-	  IFS="$save_ifs"
-	  eval cmd=\"$cmd\"
-	  $show "$cmd"
-	  $run eval "$cmd" || exit $?
-	done
-	IFS="$save_ifs"
-      fi
 
-      if test -n "$gentop"; then
-	$show "${rm}r $gentop"
-	$run ${rm}r $gentop
-      fi
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $debug_cmd
 
-      exit $EXIT_SUCCESS
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
       ;;
+  esac
+}
+# end func_to_tool_file
 
-    prog)
-      case $host in
-	*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
-      esac
-      if test -n "$vinfo"; then
-	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
-      fi
 
-      if test -n "$release"; then
-	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
-      fi
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result=$1
+}
+# end func_convert_file_noop
 
-      if test "$preload" = yes; then
-	if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
-	   test "$dlopen_self_static" = unknown; then
-	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
-	fi
-      fi
 
-      case $host in
-      *-*-rhapsody* | *-*-darwin1.[012])
-	# On Rhapsody replace the C library is the System framework
-	compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
-	;;
-      esac
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $debug_cmd
 
-      case $host in
-      *darwin*)
-        # Don't allow lazy linking, it breaks C++ global constructors
-        if test "$tagname" = CXX ; then
-        compile_command="$compile_command ${wl}-bind_at_load"
-        finalize_command="$finalize_command ${wl}-bind_at_load"
-        fi
-        ;;
-      esac
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result=$func_convert_core_msys_to_w32_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
 
 
-      # move library search paths that coincide with paths to not yet
-      # installed libraries to the beginning of the library search list
-      new_libs=
-      for path in $notinst_path; do
-	case " $new_libs " in
-	*" -L$path/$objdir "*) ;;
-	*)
-	  case " $compile_deplibs " in
-	  *" -L$path/$objdir "*)
-	    new_libs="$new_libs -L$path/$objdir" ;;
-	  esac
-	  ;;
-	esac
-      done
-      for deplib in $compile_deplibs; do
-	case $deplib in
-	-L*)
-	  case " $new_libs " in
-	  *" $deplib "*) ;;
-	  *) new_libs="$new_libs $deplib" ;;
-	  esac
-	  ;;
-	*) new_libs="$new_libs $deplib" ;;
-	esac
-      done
-      compile_deplibs="$new_libs"
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $debug_cmd
 
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
 
-      compile_command="$compile_command $compile_deplibs"
-      finalize_command="$finalize_command $finalize_deplibs"
 
-      if test -n "$rpath$xrpath"; then
-	# If the user specified any rpath flags, then add them.
-	for libdir in $rpath $xrpath; do
-	  # This is the magic to use -rpath.
-	  case "$finalize_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_rpath="$finalize_rpath $libdir" ;;
-	  esac
-	done
-      fi
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $debug_cmd
 
-      # Now hardcode the library paths
-      rpath=
-      hardcode_libdirs=
-      for libdir in $compile_rpath $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		;;
-	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) perm_rpath="$perm_rpath $libdir" ;;
-	  esac
-	fi
-	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
-	  testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
-	  case :$dllsearchpath: in
-	  *":$libdir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$libdir";;
-	  esac
-	  case :$dllsearchpath: in
-	  *":$testbindir:"*) ;;
-	  *) dllsearchpath="$dllsearchpath:$testbindir";;
-	  esac
-	  ;;
-	esac
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      compile_rpath="$rpath"
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
 
-      rpath=
-      hardcode_libdirs=
-      for libdir in $finalize_rpath; do
-	if test -n "$hardcode_libdir_flag_spec"; then
-	  if test -n "$hardcode_libdir_separator"; then
-	    if test -z "$hardcode_libdirs"; then
-	      hardcode_libdirs="$libdir"
-	    else
-	      # Just accumulate the unique libdirs.
-	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
-	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
-		;;
-	      *)
-		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
-		;;
-	      esac
-	    fi
-	  else
-	    eval flag=\"$hardcode_libdir_flag_spec\"
-	    rpath="$rpath $flag"
-	  fi
-	elif test -n "$runpath_var"; then
-	  case "$finalize_perm_rpath " in
-	  *" $libdir "*) ;;
-	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
-	  esac
-	fi
-      done
-      # Substitute the hardcoded libdirs into the rpath.
-      if test -n "$hardcode_libdir_separator" &&
-	 test -n "$hardcode_libdirs"; then
-	libdir="$hardcode_libdirs"
-	eval rpath=\" $hardcode_libdir_flag_spec\"
-      fi
-      finalize_rpath="$rpath"
 
-      if test -n "$libobjs" && test "$build_old_libs" = yes; then
-	# Transform all the library objects into standard objects.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-      fi
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $debug_cmd
 
-      dlsyms=
-      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
-	if test -n "$NM" && test -n "$global_symbol_pipe"; then
-	  dlsyms="${outputname}S.c"
-	else
-	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
-	fi
-      fi
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result=$func_cygpath_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
 
-      if test -n "$dlsyms"; then
-	case $dlsyms in
-	"") ;;
-	*.c)
-	  # Discover the nlist of each of the dlfiles.
-	  nlist="$output_objdir/${outputname}.nm"
 
-	  $show "$rm $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_file_result=$1
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result=$func_cygpath_result
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
 
-	  # Parse the name list into a source file.
-	  $show "creating $output_objdir/$dlsyms"
 
-	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
-/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
-/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $debug_cmd
 
-#ifdef __cplusplus
-extern \"C\" {
-#endif
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd=func_convert_path_$func_stripname_result
+  fi
+}
 
-/* Prevent the only kind of declaration conflicts we can make. */
-#define lt_preloaded_symbols some_other_symbol
 
-/* External symbol declarations for the compiler. */\
-"
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $debug_cmd
 
-	  if test "$dlself" = yes; then
-	    $show "generating symbol list for \`$output'"
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
 
-	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
 
-	    # Add our own program objects to the symbol list.
-	    progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-	    for arg in $progfiles; do
-	      $show "extracting global C symbols from \`$arg'"
-	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	    done
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result=$1
+}
+# end func_convert_path_noop
 
-	    if test -n "$exclude_expsyms"; then
-	      $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
 
-	    if test -n "$export_symbols_regex"; then
-	      $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
-	      $run eval '$mv "$nlist"T "$nlist"'
-	    fi
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result=$func_convert_core_msys_to_w32_result
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
 
-	    # Prepare the list of exported symbols
-	    if test -z "$export_symbols"; then
-	      export_symbols="$output_objdir/$outputname.exp"
-	      $run $rm $export_symbols
-	      $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
-              case $host in
-              *cygwin* | *mingw* )
-	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
-		$run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
-                ;;
-              esac
-	    else
-	      $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
-	      $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
-	      $run eval 'mv "$nlist"T "$nlist"'
-              case $host in
-              *cygwin* | *mingw* )
-	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
-		$run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
-                ;;
-              esac
-	    fi
-	  fi
-
-	  for arg in $dlprefiles; do
-	    $show "extracting global C symbols from \`$arg'"
-	    name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
-	    $run eval '$echo ": $name " >> "$nlist"'
-	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
-	  done
-
-	  if test -z "$run"; then
-	    # Make sure we have at least an empty file.
-	    test -f "$nlist" || : > "$nlist"
-
-	    if test -n "$exclude_expsyms"; then
-	      $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
-	      $mv "$nlist"T "$nlist"
-	    fi
-
-	    # Try sorting and uniquifying the output.
-	    if grep -v "^: " < "$nlist" |
-		if sort -k 3 /dev/null 2>&1; then
-		  sort -k 3
-		else
-		  sort +2
-		fi |
-		uniq > "$nlist"S; then
-	      :
-	    else
-	      grep -v "^: " < "$nlist" > "$nlist"S
-	    fi
-
-	    if test -f "$nlist"S; then
-	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
-	    else
-	      $echo '/* NONE */' >> "$output_objdir/$dlsyms"
-	    fi
 
-	    $echo >> "$output_objdir/$dlsyms" "\
-
-#undef lt_preloaded_symbols
-
-#if defined (__STDC__) && __STDC__
-# define lt_ptr void *
-#else
-# define lt_ptr char *
-# define const
-#endif
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
 
-/* The mapping between symbol names and symbols. */
-"
 
-	    case $host in
-	    *cygwin* | *mingw* )
-	  $echo >> "$output_objdir/$dlsyms" "\
-/* DATA imports from DLLs on WIN32 can't be const, because
-   runtime relocations are performed -- see ld's documentation
-   on pseudo-relocs */
-struct {
-"
-	      ;;
-	    * )
-	  $echo >> "$output_objdir/$dlsyms" "\
-const struct {
-"
-	      ;;
-	    esac
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
 
 
-	  $echo >> "$output_objdir/$dlsyms" "\
-  const char *name;
-  lt_ptr address;
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result=$func_cygpath_result
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
 }
-lt_preloaded_symbols[] =
-{\
-"
+# end func_convert_path_msys_to_cygwin
 
-	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
-
-	    $echo >> "$output_objdir/$dlsyms" "\
-  {0, (lt_ptr) 0}
-};
 
-/* This works around a problem in FreeBSD linker */
-#ifdef FREEBSD_WORKAROUND
-static const void *lt_preloaded_setup() {
-  return lt_preloaded_symbols;
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $debug_cmd
+
+  func_to_host_path_result=$1
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result=$func_cygpath_result
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
 }
-#endif
+# end func_convert_path_nix_to_cygwin
 
-#ifdef __cplusplus
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+  $debug_cmd
+
+  func_dll_def_p_tmp=`$SED -n \
+    -e 's/^[	 ]*//' \
+    -e '/^\(;.*\)*$/d' \
+    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \
+    -e q \
+    "$1"`
+  test DEF = "$func_dll_def_p_tmp"
 }
-#endif\
-"
-	  fi
 
-	  pic_flag_for_symtable=
-	  case $host in
-	  # compiling the symbol table file with pic_flag works around
-	  # a FreeBSD bug that causes programs to crash when -lm is
-	  # linked before any other PIC object.  But we must not use
-	  # pic_flag when linking with -static.  The problem exists in
-	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
-	    case "$compile_command " in
-	    *" -static "*) ;;
-	    *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
-	    esac;;
-	  *-*-hpux*)
-	    case "$compile_command " in
-	    *" -static "*) ;;
-	    *) pic_flag_for_symtable=" $pic_flag";;
-	    esac
-	  esac
 
-	  # Now compile the dynamic symbol file.
-	  $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
-	  $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+# func_reorder_shared_lib_cache DIRS
+# Reorder the shared library cache by unconfiguring previous shared library cache
+# and configuring preferred search directories before previous search directories.
+# Previous shared library cache: /usr/lib /usr/local/lib
+# Preferred search directories: /tmp/testing
+# Reordered shared library cache: /tmp/testing /usr/lib /usr/local/lib
+func_reorder_shared_lib_cache ()
+{
+	$debug_cmd
+
+	case $host_os in
+	  openbsd*)
+	    get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"`
+	    func_convert_delimited_path "$get_search_directories" ':' '\ '
+	    save_search_directories=$converted_path
+	    func_convert_delimited_path "$1" ':' '\ '
+
+	    # Ensure directories exist
+	    for dir in $converted_path; do
+	      # Ensure each directory is an absolute path
+	      case $dir in
+	        /*) ;;
+	        *) func_error "Directory '$dir' is not an absolute path"
+	           exit $EXIT_FAILURE ;;
+	      esac
+	      # Ensure no trailing slashes
+	      func_stripname '' '/' "$dir"
+	      dir=$func_stripname_result
+	      if test -d "$dir"; then
+	        if test -n "$preferred_search_directories"; then
+	          preferred_search_directories="$preferred_search_directories $dir"
+	        else
+	          preferred_search_directories=$dir
+	        fi
+	      else
+	        func_error "Directory '$dir' does not exist"
+	        exit $EXIT_FAILURE
+	      fi
+	    done
 
-	  # Clean up the generated files.
-	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
-	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+	    PATH="$PATH:/sbin" ldconfig -U $save_search_directories
+	    PATH="$PATH:/sbin" ldconfig -m $preferred_search_directories $save_search_directories
+	    get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"`
+	    func_convert_delimited_path "$get_search_directories" ':' '\ '
+	    reordered_search_directories=$converted_path
 
-	  # Transform the symbol file into the correct name.
-          case $host in
-          *cygwin* | *mingw* )
-            if test -f "$output_objdir/${outputname}.def" ; then
-              compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
-              finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
-            else
-              compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-              finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-             fi
-            ;;
-          * )
-            compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-            finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
-            ;;
-          esac
+	    $ECHO "Original: $save_search_directories"
+	    $ECHO "Reordered: $reordered_search_directories"
+	    exit $EXIT_SUCCESS
 	  ;;
-	*)
-	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
-	  exit $EXIT_FAILURE
+	  *)
+	    func_error "--reorder-cache is not supported for host_os=$host_os."
+	    exit $EXIT_FAILURE
 	  ;;
 	esac
-      else
-	# We keep going just in case the user didn't refer to
-	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
-	# really was required.
-
-	# Nullify the symbol file.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
-	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
-      fi
+}
+# end func_reorder_shared_lib_cache
 
-      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
-	# Replace the output file specification.
-	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP`
-	link_command="$compile_command$compile_rpath"
 
-	# We have no uninstalled library dependencies, so finalize right now.
-	$show "$link_command"
-	$run eval "$link_command"
-	exit_status=$?
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $debug_cmd
 
-	# Delete the generated files.
-	if test -n "$dlsyms"; then
-	  $show "$rm $output_objdir/${outputname}S.${objext}"
-	  $run $rm "$output_objdir/${outputname}S.${objext}"
-	fi
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
 
-	exit $exit_status
-      fi
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg=$arg
+	arg_mode=normal
+	;;
 
-      if test -n "$shlibpath_var"; then
-	# We should set the shlibpath_var
-	rpath=
-	for dir in $temp_rpath; do
-	  case $dir in
-	  [\\/]* | [A-Za-z]:[\\/]*)
-	    # Absolute path.
-	    rpath="$rpath$dir:"
-	    ;;
-	  *)
-	    # Relative path: add a thisdir entry.
-	    rpath="$rpath\$thisdir/$dir:"
-	    ;;
-	  esac
-	done
-	temp_rpath="$rpath"
-      fi
+      target )
+	libobj=$arg
+	arg_mode=normal
+	continue
+	;;
 
-      if test -n "$compile_shlibpath$finalize_shlibpath"; then
-	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
-      fi
-      if test -n "$finalize_shlibpath"; then
-	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
-      fi
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify '-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
 
-      compile_var=
-      finalize_var=
-      if test -n "$runpath_var"; then
-	if test -n "$perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-	if test -n "$finalize_perm_rpath"; then
-	  # We should set the runpath_var.
-	  rpath=
-	  for dir in $finalize_perm_rpath; do
-	    rpath="$rpath$dir:"
-	  done
-	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
-	fi
-      fi
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
 
-      if test "$no_install" = yes; then
-	# We don't need to create a wrapper script.
-	link_command="$compile_var$compile_command$compile_rpath"
-	# Replace the output file specification.
-	link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
-	# Delete the old output file.
-	$run $rm $output
-	# Link the executable and exit
-	$show "$link_command"
-	$run eval "$link_command" || exit $?
-	exit $EXIT_SUCCESS
-      fi
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
+	  continue
+	  ;;
 
-      if test "$hardcode_action" = relink; then
-	# Fast installation is not supported
-	link_command="$compile_var$compile_command$compile_rpath"
-	relink_command="$finalize_var$finalize_command$finalize_rpath"
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
 
-	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
-	$echo "$modename: \`$output' will be relinked during installation" 1>&2
-      else
-	if test "$fast_install" != no; then
-	  link_command="$finalize_var$compile_command$finalize_rpath"
-	  if test "$fast_install" = yes; then
-	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP`
-	  else
-	    # fast_install is set to needless
-	    relink_command=
-	  fi
-	else
-	  link_command="$compile_var$compile_command$compile_rpath"
-	  relink_command="$finalize_var$finalize_command$finalize_rpath"
-	fi
-      fi
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
 
-      # Replace the output file specification.
-      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs=$IFS; IFS=,
+	  for arg in $args; do
+	    IFS=$save_ifs
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS=$save_ifs
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
 
-      # Delete the old output files.
-      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
 
-      $show "$link_command"
-      $run eval "$link_command" || exit $?
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg=$srcfile
+	  srcfile=$arg
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
 
-      # Now create the wrapper script.
-      $show "creating $output"
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
 
-      # Quote the relink command for shipping.
-      if test -n "$relink_command"; then
-	# Preserve any variables that may affect compiler behavior
-	for var in $variables_saved_for_relink; do
-	  if eval test -z \"\${$var+set}\"; then
-	    relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
-	  elif eval var_value=\$$var; test -z "$var_value"; then
-	    relink_command="$var=; export $var; $relink_command"
-	  else
-	    var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
-	    relink_command="$var=\"$var_value\"; export $var; $relink_command"
-	  fi
-	done
-	relink_command="(cd `pwd`; $relink_command)"
-	relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
-      fi
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with '-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj=$func_basename_result
+      }
+      ;;
+    esac
 
-      # Quote $echo for shipping.
-      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
-	case $progpath in
-	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
-	*) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
-	esac
-	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
-      else
-	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
-      fi
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
 
-      # Only actually do things if our run command is non-null.
-      if test -z "$run"; then
-	# win32 will think the script is a binary if it has
-	# a .exe suffix, so we strip it off here.
-	case $output in
-	  *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
-	esac
-	# test for cygwin because mv fails w/o .exe extensions
-	case $host in
-	  *cygwin*)
-	    exeext=.exe
-	    outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
-	  *) exeext= ;;
-	esac
-	case $host in
-	  *cygwin* | *mingw* )
-            output_name=`basename $output`
-            output_path=`dirname $output`
-            cwrappersource="$output_path/$objdir/lt-$output_name.c"
-            cwrapper="$output_path/$output_name.exe"
-            $rm $cwrappersource $cwrapper
-            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from '$libobj'"
+      ;;
+    esac
 
-	    cat > $cwrappersource <> $cwrappersource<<"EOF"
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
 
-#if defined(PATH_MAX)
-# define LT_PATHMAX PATH_MAX
-#elif defined(MAXPATHLEN)
-# define LT_PATHMAX MAXPATHLEN
-#else
-# define LT_PATHMAX 1024
-#endif
+    func_quote_arg pretty "$libobj"
+    test "X$libobj" != "X$func_quote_arg_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name '$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname=$func_basename_result
+    xdir=$func_dirname_result
+    lobj=$xdir$objdir/$objname
 
-#ifndef DIR_SEPARATOR
-# define DIR_SEPARATOR '/'
-# define PATH_SEPARATOR ':'
-#endif
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
 
-#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
-  defined (__OS2__)
-# define HAVE_DOS_BASED_FILE_SYSTEM
-# ifndef DIR_SEPARATOR_2
-#  define DIR_SEPARATOR_2 '\\'
-# endif
-# ifndef PATH_SEPARATOR_2
-#  define PATH_SEPARATOR_2 ';'
-# endif
-#endif
+    # Delete any leftover library objects.
+    if test yes = "$build_old_libs"; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
 
-#ifndef DIR_SEPARATOR_2
-# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
-#else /* DIR_SEPARATOR_2 */
-# define IS_DIR_SEPARATOR(ch) \
-        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
-#endif /* DIR_SEPARATOR_2 */
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | windows* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
 
-#ifndef PATH_SEPARATOR_2
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
-#else /* PATH_SEPARATOR_2 */
-# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
-#endif /* PATH_SEPARATOR_2 */
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test no = "$compiler_c_o"; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+      lockfile=$output_obj.lock
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
 
-#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
-#define XFREE(stale) do { \
-  if (stale) { free ((void *) stale); stale = 0; } \
-} while (0)
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test yes = "$need_locks"; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test warn = "$need_locks"; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
 
-/* -DDEBUG is fairly common in CFLAGS.  */
-#undef DEBUG
-#if defined DEBUGWRAPPER
-# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
-#else
-# define DEBUG(format, ...)
-#endif
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
 
-const char *program_name = NULL;
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
 
-void * xmalloc (size_t num);
-char * xstrdup (const char *string);
-const char * base_name (const char *name);
-char * find_executable(const char *wrapper);
-int    check_executable(const char *path);
-char * strendzap(char *str, const char *pat);
-void lt_fatal (const char *message, ...);
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
 
-int
-main (int argc, char *argv[])
-{
-  char **newargz;
-  int i;
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_arg pretty "$srcfile"
+    qsrcfile=$func_quote_arg_result
 
-  program_name = (char *) xstrdup (base_name (argv[0]));
-  DEBUG("(main) argv[0]      : %s\n",argv[0]);
-  DEBUG("(main) program_name : %s\n",program_name);
-  newargz = XMALLOC(char *, argc+2);
-EOF
+    # Only build a PIC object if we are building libtool libraries.
+    if test yes = "$build_libtool_libs"; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
 
-            cat >> $cwrappersource <> $cwrappersource <<"EOF"
-  newargz[1] = find_executable(argv[0]);
-  if (newargz[1] == NULL)
-    lt_fatal("Couldn't find %s", argv[0]);
-  DEBUG("(main) found exe at : %s\n",newargz[1]);
-  /* we know the script has the same name, without the .exe */
-  /* so make sure newargz[1] doesn't end in .exe */
-  strendzap(newargz[1],".exe");
-  for (i = 1; i < argc; i++)
-    newargz[i+1] = xstrdup(argv[i]);
-  newargz[argc+1] = NULL;
+      func_mkdir_p "$xdir$objdir"
 
-  for (i=0; i> $cwrappersource <> $cwrappersource </dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
 
-            cat >> $cwrappersource <<"EOF"
-  return 127;
-}
+but it should contain:
+$srcfile
 
-void *
-xmalloc (size_t num)
-{
-  void * p = (void *) malloc (num);
-  if (!p)
-    lt_fatal ("Memory exhausted");
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
 
-  return p;
-}
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
 
-char *
-xstrdup (const char *string)
-{
-  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
-;
-}
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
 
-const char *
-base_name (const char *name)
-{
-  const char *base;
+      # Allow error messages only from the first compilation.
+      if test yes = "$suppress_opt"; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
 
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  /* Skip over the disk name in MSDOS pathnames. */
-  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
-    name += 2;
-#endif
+    # Only build a position-dependent object if we build old libraries.
+    if test yes = "$build_old_libs"; then
+      if test yes != "$pic_mode"; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test yes = "$compiler_c_o"; then
+	func_append command " -o $obj"
+      fi
 
-  for (base = name; *name; name++)
-    if (IS_DIR_SEPARATOR (*name))
-      base = name + 1;
-  return base;
-}
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
 
-int
-check_executable(const char * path)
-{
-  struct stat st;
+      if test warn = "$need_locks" &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
 
-  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
-  if ((!path) || (!*path))
-    return 0;
+but it should contain:
+$srcfile
 
-  if ((stat (path, &st) >= 0) &&
-      (
-        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
-#if defined (S_IXOTH)
-       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
-#endif
-#if defined (S_IXGRP)
-       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
-#endif
-       ((st.st_mode & S_IXUSR) == S_IXUSR))
-      )
-    return 1;
-  else
-    return 0;
-}
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
 
-/* Searches for the full path of the wrapper.  Returns
-   newly allocated full path name if found, NULL otherwise */
-char *
-find_executable (const char* wrapper)
-{
-  int has_slash = 0;
-  const char* p;
-  const char* p_next;
-  /* static buffer for getcwd */
-  char tmp[LT_PATHMAX + 1];
-  int tmp_len;
-  char* concat_name;
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
 
-  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
 
-  if ((wrapper == NULL) || (*wrapper == '\0'))
-    return NULL;
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
 
-  /* Absolute path? */
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
-  {
-    concat_name = xstrdup (wrapper);
-    if (check_executable(concat_name))
-      return concat_name;
-    XFREE(concat_name);
-  }
-  else
-  {
-#endif
-    if (IS_DIR_SEPARATOR (wrapper[0]))
-    {
-      concat_name = xstrdup (wrapper);
-      if (check_executable(concat_name))
-        return concat_name;
-      XFREE(concat_name);
+      # Unlock the critical section if it was locked
+      if test no != "$need_locks"; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
     }
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  }
-#endif
 
-  for (p = wrapper; *p; p++)
-    if (*p == '/')
-    {
-      has_slash = 1;
-      break;
-    }
-  if (!has_slash)
-  {
-    /* no slashes; search PATH */
-    const char* path = getenv ("PATH");
-    if (path != NULL)
-    {
-      for (p = path; *p; p = p_next)
-      {
-        const char* q;
-        size_t p_len;
-        for (q = p; *q; q++)
-          if (IS_PATH_SEPARATOR(*q))
-            break;
-        p_len = q - p;
-        p_next = (*q == '\0' ? q : q + 1);
-        if (p_len == 0)
-        {
-          /* empty path: current directory */
-          if (getcwd (tmp, LT_PATHMAX) == NULL)
-            lt_fatal ("getcwd failed");
-          tmp_len = strlen(tmp);
-          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
-          memcpy (concat_name, tmp, tmp_len);
-          concat_name[tmp_len] = '/';
-          strcpy (concat_name + tmp_len + 1, wrapper);
-        }
-        else
-        {
-          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
-          memcpy (concat_name, p, p_len);
-          concat_name[p_len] = '/';
-          strcpy (concat_name + p_len + 1, wrapper);
-        }
-        if (check_executable(concat_name))
-          return concat_name;
-        XFREE(concat_name);
-      }
-    }
-    /* not found in PATH; assume curdir */
-  }
-  /* Relative path | not found in path: prepend cwd */
-  if (getcwd (tmp, LT_PATHMAX) == NULL)
-    lt_fatal ("getcwd failed");
-  tmp_len = strlen(tmp);
-  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
-  memcpy (concat_name, tmp, tmp_len);
-  concat_name[tmp_len] = '/';
-  strcpy (concat_name + tmp_len + 1, wrapper);
+    exit $EXIT_SUCCESS
+}
 
-  if (check_executable(concat_name))
-    return concat_name;
-  XFREE(concat_name);
-  return NULL;
+$opt_help || {
+  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
 }
 
-char *
-strendzap(char *str, const char *pat)
+func_mode_help ()
 {
-  size_t len, patlen;
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
 
-  assert(str != NULL);
-  assert(pat != NULL);
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
 
-  len = strlen(str);
-  patlen = strlen(pat);
+Remove files from the build directory.
 
-  if (patlen <= len)
-  {
-    str += len - patlen;
-    if (strcmp(str, pat) == 0)
-      *str = '\0';
-  }
-  return str;
-}
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+to RM.
 
-static void
-lt_error_core (int exit_status, const char * mode,
-          const char * message, va_list ap)
-{
-  fprintf (stderr, "%s: %s: ", program_name, mode);
-  vfprintf (stderr, message, ap);
-  fprintf (stderr, ".\n");
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
 
-  if (exit_status >= 0)
-    exit (exit_status);
-}
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
 
-void
-lt_fatal (const char *message, ...)
-{
-  va_list ap;
-  va_start (ap, message);
-  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
-  va_end (ap);
-}
-EOF
-          # we should really use a build-platform specific compiler
-          # here, but OTOH, the wrappers (shell script and this C one)
-          # are only useful if you want to execute the "real" binary.
-          # Since the "real" binary is built for $host, then this
-          # wrapper might as well be built for $host, too.
-          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
-          ;;
-        esac
-        $rm $output
-        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+Compile a source file into a libtool library object.
 
-	$echo > $output "\
-#! $SHELL
+This mode accepts the following additional options:
 
-# $output - temporary wrapper script for $objdir/$outputname
-# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
-#
-# The $output program cannot be directly executed until all the libtool
-# libraries that it depends on are installed.
-#
-# This wrapper script should never be moved out of the build directory.
-# If it is, it will not operate correctly.
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a '.o' file suitable for static linking
+  -static           only build a '.o' file suitable for static linking
+  -Wc,FLAG
+  -Xcompiler FLAG   pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-Xsed='${SED} -e 1s/^X//'
-sed_quote_subst='$sed_quote_subst'
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+        ;;
 
-# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
-if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '\${1+\"\$@\"}'='\"\$@\"'
-  setopt NO_GLOB_SUBST
-else
-  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the '--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  use a list of object files found in FILE to specify objects
+  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wa,FLAG
+  -Xassembler FLAG  pass linker-specific FLAG directly to the assembler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode '$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test : = "$opt_help"; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    $SED '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
 fi
-BIN_SH=xpg4; export BIN_SH # for Tru64
-DUALCASE=1; export DUALCASE # for MKS sh
 
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
-relink_command=\"$relink_command\"
+# If option '--reorder-cache', reorder the shared library cache and exit.
+if $opt_reorder_cache; then
+    func_reorder_shared_lib_cache $shared_lib_dirs
+fi
 
-# This environment variable determines our operation mode.
-if test \"\$libtool_install_magic\" = \"$magic\"; then
-  # install mode needs the following variable:
-  notinst_deplibs='$notinst_deplibs'
-else
-  # When we are sourced in execute mode, \$file and \$echo are already set.
-  if test \"\$libtool_execute_magic\" != \"$magic\"; then
-    echo=\"$qecho\"
-    file=\"\$0\"
-    # Make sure echo works.
-    if test \"X\$1\" = X--no-reexec; then
-      # Discard the --no-reexec flag, and continue.
-      shift
-    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
-      # Yippee, \$echo works!
-      :
-    else
-      # Restart under the correct shell, and then maybe \$echo will work.
-      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
-    fi
-  fi\
-"
-	$echo >> $output "\
 
-  # Find the directory that this script lives in.
-  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
-  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $debug_cmd
 
-  # Follow symbolic links until we get to the real thisdir.
-  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
-  while test -n \"\$file\"; do
-    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+    # The first argument is the command name.
+    cmd=$nonopt
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
 
-    # If there was a directory component, then change thisdir.
-    if test \"x\$destdir\" != \"x\$file\"; then
-      case \"\$destdir\" in
-      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
-      *) thisdir=\"\$thisdir/\$destdir\" ;;
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "'$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "'$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "'$file' was not linked with '-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir=$func_dirname_result
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir=$func_dirname_result
+	;;
+
+      *)
+	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir=$absdir
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic=$magic
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file=$progdir/$program
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file=$progdir/$program
+	fi
+	;;
       esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if $opt_dry_run; then
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    else
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd=\$cmd$args
     fi
+}
 
-    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
-    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
-  done
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
 
-  # Try to get the absolute directory name.
-  absdir=\`cd \"\$thisdir\" && pwd\`
-  test -n \"\$absdir\" && thisdir=\"\$absdir\"
-"
 
-	if test "$fast_install" = yes; then
-	  $echo >> $output "\
-  program=lt-'$outputname'$exeext
-  progdir=\"\$thisdir/$objdir\"
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $debug_cmd
 
-  if test ! -f \"\$progdir/\$program\" || \\
-     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
-       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+    libs=
+    libdirs=
+    admincmds=
 
-    file=\"\$\$-\$program\"
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
 
-    if test ! -d \"\$progdir\"; then
-      $mkdir \"\$progdir\"
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "'$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument '$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs" && $opt_finishing; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_quiet && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      if test "false" = "$opt_finishing"; then
+        echo
+        echo "NOTE: finish_cmds were not executed during testing, so you must"
+        echo "manually run ldconfig to add a given test directory, LIBDIR, to"
+        echo "the search path for generated executables."
+      fi
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the '$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
+
+	$ECHO "   - use the '$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $debug_cmd
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac
+    then
+      # Aesthetically quote it.
+      func_quote_arg pretty "$nonopt"
+      install_prog="$func_quote_arg_result "
+      arg=$1
+      shift
     else
-      $rm \"\$progdir/\$file\"
-    fi"
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_arg pretty "$arg"
+    func_append install_prog "$func_quote_arg_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=false
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=: ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test X-m = "X$prev" && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_arg pretty "$arg"
+      func_append install_prog " $func_quote_arg_result"
+      if test -n "$arg2"; then
+	func_quote_arg pretty "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_arg_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the '$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_arg pretty "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_arg_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=:
+    if $isdir; then
+      destdir=$dest
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir=$func_dirname_result
+      destname=$func_basename_result
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "'$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "'$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic=$magic
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "'$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir=$func_dirname_result
+	func_append dir "$objdir"
+
+	if test -n "$relink_command"; then
+	  # Strip any trailing slash from the destination.
+	  func_stripname '' '/' "$libdir"
+	  destlibdir=$func_stripname_result
+
+	  func_stripname '' '/' "$destdir"
+	  s_destdir=$func_stripname_result
+
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking '$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname=$1
+	  shift
+
+	  srcname=$realname
+	  test -n "$relink_command" && srcname=${realname}T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme=$stripme
+	  case $host_os in
+	  cygwin* | mingw* | windows* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=
+	      ;;
+	    esac
+	    ;;
+	  os2*)
+	    case $realname in
+	    *_dll.a)
+	      tstripme=
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try 'ln -sf' first, because the 'ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib=$destdir/$realname
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name=$func_basename_result
+	instname=$dir/${name}i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile=$destdir/$destname
+	else
+	  func_basename "$file"
+	  destfile=$func_basename_result
+	  destfile=$destdir/$destfile
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest=$destfile
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to '$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test yes = "$build_old_libs"; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile=$destdir/$destname
+	else
+	  func_basename "$file"
+	  destfile=$func_basename_result
+	  destfile=$destdir/$destfile
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=.exe
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw* | *windows*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+	  finalize=:
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "'$lib' has not been installed in '$libdir'"
+	      finalize=false
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test no = "$fast_install" && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if $finalize; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file=$func_basename_result
+	        outputname=$tmpdir/$file
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_quiet || {
+	          func_quote_arg expand,pretty "$relink_command"
+		  eval "func_echo $func_quote_arg_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink '$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file=$outputname
+	      else
+	        func_warning "cannot relink '$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name=$func_basename_result
+
+      # Set up the ranlib parameters.
+      oldlib=$destdir/$name
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run '$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $debug_cmd
+
+    my_outputname=$1
+    my_originator=$2
+    my_pic_p=${3-false}
+    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms=${my_outputname}S.c
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist=$output_objdir/$my_outputname.nm
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test yes = "$dlself"; then
+	  func_verbose "generating symbol list for '$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols=$output_objdir/$outputname.exp
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *windows* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *windows* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from '$dlprefile'"
+	  func_basename "$dlprefile"
+	  name=$func_basename_result
+          case $host in
+	    *cygwin* | *mingw* | *windows* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname"; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename=$func_basename_result
+	          else
+	            # no lafile. user explicitly requested -dlpreopen .
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename"; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          case $host in
+	            i[3456]86-*-mingw32*)
+	              eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	                $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	            ;;
+	            *)
+	              eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	                $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/__nm_//' >> '$nlist'"
+	            ;;
+	          esac
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 /dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  func_show_eval '$RM "${nlist}I"'
+	  if test -n "$global_symbol_to_import"; then
+	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+	  if test -s "$nlist"I; then
+	    echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+  for (; symbol->name; ++symbol)
+    {"
+	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+	    echo >> "$output_objdir/$my_dlsyms" "\
+    }
+}"
+	  fi
+	  echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+	  if test -s "$nlist"I; then
+	    echo >> "$output_objdir/$my_dlsyms" "\
+  {\"@INIT@\", (void *) <_syminit},"
+	  fi
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj=$output_objdir/${my_outputname}S.$objext
+	case $host in
+	*cygwin* | *mingw* | *windows* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for '$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $debug_cmd
+
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $debug_cmd
+
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $debug_cmd
+
+  win32_libid_type=unknown
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' >/dev/null; then
+      case $nm_interface in
+      "MS dumpbin")
+	if func_cygming_ms_implib_p "$1" ||
+	   func_cygming_gnu_implib_p "$1"
+	then
+	  win32_nmres=import
+	else
+	  win32_nmres=
+	fi
+	;;
+      *)
+	func_to_tool_file "$1" func_convert_file_msys_to_w32
+	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	  $SED -n -e '
+	    1,100{
+		/ I /{
+		    s|.*|import|
+		    p
+		    q
+		}
+	    }'`
+	;;
+      esac
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $debug_cmd
+
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $debug_cmd
+
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive that possess that section. Heuristic: eliminate
+    # all those that have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $debug_cmd
+
+  if func_cygming_gnu_implib_p "$1"; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1"; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $debug_cmd
+
+    f_ex_an_ar_dir=$1; shift
+    f_ex_an_ar_oldlib=$1
+    if test yes = "$lock_old_archive_extraction"; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test yes = "$lock_old_archive_extraction"; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $debug_cmd
+
+    my_gentop=$1; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=
+    my_xlib=
+    my_xabs=
+    my_xdir=
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib=$func_basename_result
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir=$my_gentop/$my_xlib_u
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  func_basename "$darwin_archive"
+	  darwin_base_archive=$func_basename_result
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches; do
+	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+	      func_extract_an_archive "`pwd`" "$darwin_base_archive"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw/windows
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory.  This is a cygwin/mingw/windows-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    func_quote_arg pretty "$ECHO"
+    qECHO=$func_quote_arg_result
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=$qECHO
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw/windows when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test yes = "$fast_install"; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	\$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <
+#include 
+#if defined _WIN32 && !defined __GNUC__
+# include 
+# include 
+# include 
+#else
+# include 
+# include 
+# ifdef __CYGWIN__
+#  include 
+# endif
+#endif
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+_CRTIMP int __cdecl _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+  defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  size_t tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = (size_t) (q - p);
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (STREQ (str, pat))
+	*str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    size_t len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      size_t orig_value_len = strlen (orig_value);
+      size_t add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      size_t len = strlen (new_value);
+      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[--len] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw* | windows*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+	      $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $debug_cmd
+
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+    $debug_cmd
+
+    case " $compile_command " in
+    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+      suncc_use_cstd_abi=no
+      ;;
+    *)
+      suncc_use_cstd_abi=yes
+      ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $debug_cmd
+
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # what system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll that has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    compile_rpath_tail=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    os2dllname=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=false
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    temp_rpath_tail=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    rpath_arg=
+    single_module=$wl-single_module
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test yes != "$build_libtool_libs" \
+	  && func_fatal_configuration "cannot build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg=$1
+      shift
+      func_quote_arg pretty,unquoted "$arg"
+      qarg=$func_quote_arg_unquoted_result
+      func_append libtool_args " $func_quote_arg_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir=$arg
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  $preload || {
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=:
+	  }
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test no = "$dlself"; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test dlprefiles = "$prev"; then
+	      dlself=yes
+	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test dlfiles = "$prev"; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols=$arg
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file '$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex=$arg
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir=$arg
+	  prev=
+	  continue
+	  ;;
+	mllvm)
+	  # Clang does not use LLVM to link, so we can simply discard any
+	  # '-mllvm $arg' options when doing the link step.
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test none = "$pic_object" &&
+		   test none = "$non_pic_object"; then
+		  func_fatal_error "cannot find name of object for '$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir=$func_dirname_result
+
+		if test none != "$pic_object"; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object=$xdir$pic_object
+
+		  if test dlfiles = "$prev"; then
+		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test dlprefiles = "$prev"; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg=$pic_object
+		fi
+
+		# Non-PIC object.
+		if test none != "$non_pic_object"; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object=$xdir$non_pic_object
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test none = "$pic_object"; then
+		    arg=$non_pic_object
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object=$pic_object
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir=$func_dirname_result
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "'$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file '$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	os2dllname)
+	  os2dllname=$arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex=$arg
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release=-$arg
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "argument to -rpath is not absolute: $arg"
+	    ;;
+	  esac
+	  if test rpath = "$prev"; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds=$arg
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xassembler)
+	  func_append compiler_flags " -Xassembler $qarg"
+	  prev=
+	  func_append compile_command " -Xassembler $qarg"
+	  func_append finalize_command " -Xassembler $qarg"
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg=$arg
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "'-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test X-export-symbols = "X$arg"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between '-L' and '$1'"
+	  else
+	    func_fatal_error "need path for '-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of '$dir'"
+	  dir=$absdir
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test X-lc = "X$arg" && continue
+	    ;;
+	  esac
+	elif test X-lc_r = "X$arg"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -mllvm)
+	prev=mllvm
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      # -q ');
+try {
+    clone $dom->documentElement->attributes;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    clone $dom->documentElement->childNodes;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+
+$dom = Dom\XMLDocument::createFromString(']>');
+try {
+    clone $dom->documentElement->attributes;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    clone $dom->documentElement->childNodes;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    clone $dom->documentElement->children;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    clone $dom->doctype->entities;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+Trying to clone an uncloneable object of class DOMNamedNodeMap
+Trying to clone an uncloneable object of class DOMNodeList
+Trying to clone an uncloneable object of class Dom\NamedNodeMap
+Trying to clone an uncloneable object of class Dom\NodeList
+Trying to clone an uncloneable object of class Dom\HTMLCollection
+Trying to clone an uncloneable object of class Dom\DtdNamedNodeMap
diff --git a/ext/dom/tests/gh15192.phpt b/ext/dom/tests/gh15192.phpt
index c7bf0a543bb9..f6031c2a40b0 100644
--- a/ext/dom/tests/gh15192.phpt
+++ b/ext/dom/tests/gh15192.phpt
@@ -11,7 +11,7 @@ $dom = new DomDocument();
 var_dump($element);
 ?>
 --EXPECT--
-object(Dom\HTMLElement)#3 (30) {
+object(Dom\HTMLElement)#3 (31) {
   ["namespaceURI"]=>
   string(28) "http://www.w3.org/1999/xhtml"
   ["prefix"]=>
@@ -28,6 +28,8 @@ object(Dom\HTMLElement)#3 (30) {
   string(22) "(object value omitted)"
   ["attributes"]=>
   string(22) "(object value omitted)"
+  ["children"]=>
+  string(22) "(object value omitted)"
   ["firstElementChild"]=>
   string(22) "(object value omitted)"
   ["lastElementChild"]=>
diff --git a/ext/dom/tests/gh16317.phpt b/ext/dom/tests/gh16317.phpt
new file mode 100644
index 000000000000..870c337716f0
--- /dev/null
+++ b/ext/dom/tests/gh16317.phpt
@@ -0,0 +1,20 @@
+--TEST--
+GH-16317 (DOM classes do not allow __debugInfo() overrides to work)
+--FILE--
+ 'y'];
+    }
+}
+
+var_dump(new Demo());
+
+?>
+--EXPECT--
+object(Demo)#1 (1) {
+  ["x"]=>
+  string(1) "y"
+}
diff --git a/ext/dom/tests/gh16356.phpt b/ext/dom/tests/gh16356.phpt
index ad09c2681806..53d90d8490e2 100644
--- a/ext/dom/tests/gh16356.phpt
+++ b/ext/dom/tests/gh16356.phpt
@@ -13,7 +13,7 @@ var_dump($e1, $e2);
 
 ?>
 --EXPECT--
-object(Dom\Element)#3 (30) {
+object(Dom\Element)#3 (31) {
   ["namespaceURI"]=>
   string(12) "urn:example1"
   ["prefix"]=>
@@ -30,6 +30,8 @@ object(Dom\Element)#3 (30) {
   string(22) "(object value omitted)"
   ["attributes"]=>
   string(22) "(object value omitted)"
+  ["children"]=>
+  string(22) "(object value omitted)"
   ["firstElementChild"]=>
   NULL
   ["lastElementChild"]=>
@@ -75,7 +77,7 @@ object(Dom\Element)#3 (30) {
   ["textContent"]=>
   string(0) ""
 }
-object(Dom\Element)#4 (30) {
+object(Dom\Element)#4 (31) {
   ["namespaceURI"]=>
   string(12) "urn:example2"
   ["prefix"]=>
@@ -92,6 +94,8 @@ object(Dom\Element)#4 (30) {
   string(22) "(object value omitted)"
   ["attributes"]=>
   string(22) "(object value omitted)"
+  ["children"]=>
+  string(22) "(object value omitted)"
   ["firstElementChild"]=>
   NULL
   ["lastElementChild"]=>
diff --git a/ext/dom/tests/gh19612.phpt b/ext/dom/tests/gh19612.phpt
new file mode 100644
index 000000000000..38554f3c8360
--- /dev/null
+++ b/ext/dom/tests/gh19612.phpt
@@ -0,0 +1,30 @@
+--TEST--
+GH-19612 (Mitigate libxml2 tree dictionary bug)
+--EXTENSIONS--
+dom
+--FILE--
+loadXML(<<
+]>
+
+XML);
+$html = new DOMDocument;
+$html->loadHTML('

foo

', LIBXML_NOERROR); +$p = $html->documentElement->firstChild->firstChild; +$p->appendChild($html->adoptNode($xml->documentElement->firstElementChild->cloneNode(true))); + +echo $html->saveXML(); +echo $xml->saveXML(); +?> +--EXPECT-- + + +

foo

+ + +]> + diff --git a/ext/dom/tests/gh20722.phpt b/ext/dom/tests/gh20722.phpt new file mode 100644 index 000000000000..38d3314618f3 --- /dev/null +++ b/ext/dom/tests/gh20722.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-20722 (Null pointer dereference in DOM namespace node cloning via clone on malformed objects) +--EXTENSIONS-- +dom +--FILE-- + +--EXPECT-- +Done diff --git a/ext/dom/tests/gh22077.phpt b/ext/dom/tests/gh22077.phpt new file mode 100644 index 000000000000..fd4e42cc8aaf --- /dev/null +++ b/ext/dom/tests/gh22077.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-22077 (UAF in custom XPath function) +--FILE-- +registerNamespace("my", "my.ns"); +$xpath->registerPHPFunctionNS('my.ns', 'include', function(): DOMElement { + $includedDocument = new DOMDocument; + $includedDocument->loadXML(''); + return $includedDocument->documentElement; +}); +$nodeset = $xpath->query('my:include()/uaf'); +$node = $nodeset->item(0); +var_dump($nodeset->length); +var_dump($node->ownerDocument->saveXML($node)); +?> +--EXPECT-- +int(2) +string(6) "" diff --git a/ext/dom/tests/modern/common/Element_getElementsByClassName_empty.phpt b/ext/dom/tests/modern/common/Element_getElementsByClassName_empty.phpt new file mode 100644 index 000000000000..d2e3b0ea22b9 --- /dev/null +++ b/ext/dom/tests/modern/common/Element_getElementsByClassName_empty.phpt @@ -0,0 +1,32 @@ +--TEST-- +Dom\Element::getElementsByClassName() empty class names +--EXTENSIONS-- +dom +--FILE-- + +

+ +HTML, LIBXML_NOERROR); + +$collection = $dom->documentElement->getElementsByClassName(""); +var_dump($collection->count()); + +foreach ($collection as $node) { + throw new Error("unreachable"); +} + +var_dump($dom->getElementsByClassName(" ")->count()); +var_dump($dom->getElementsByClassName("\t")->count()); +var_dump($dom->getElementsByClassName("\t\n\f\v")->count()); +var_dump($dom->getElementsByClassName("\t\n\f\v")->namedItem("child")); + +?> +--EXPECT-- +int(0) +int(0) +int(0) +int(0) +NULL diff --git a/ext/dom/tests/modern/common/Element_getElementsByClassName_non_quirks.phpt b/ext/dom/tests/modern/common/Element_getElementsByClassName_non_quirks.phpt new file mode 100644 index 000000000000..e658e3399ca0 --- /dev/null +++ b/ext/dom/tests/modern/common/Element_getElementsByClassName_non_quirks.phpt @@ -0,0 +1,55 @@ +--TEST-- +Dom\Element::getElementsByClassName() non quirks mode +--EXTENSIONS-- +dom +--FILE-- + +
+

1

+

2

+

3

+

4

+

5

+

6

+
+
+

7

+

8

+

9

+

10

+

11

+
+HTML); + +$collection = $dom->getElementsByClassName("foo \n bar"); + +echo "There are {$collection->length} items in the document in total that have both \"foo\" and \"bar\"\n"; + +$collection = $dom->getElementById('container')->getElementsByClassName("foo \n bar"); + +echo "There are {$collection->length} items in #container in total that have both \"foo\" and \"bar\"\n"; + +foreach ($collection as $key => $node) { + echo "--- Key $key ---\n"; + var_dump($node->tagName, $node->textContent); + var_dump($node === $collection->item($key)); +} + +var_dump($collection->namedItem("here")->textContent); + +?> +--EXPECT-- +There are 3 items in the document in total that have both "foo" and "bar" +There are 2 items in #container in total that have both "foo" and "bar" +--- Key 0 --- +string(1) "P" +string(1) "5" +bool(true) +--- Key 1 --- +string(1) "P" +string(1) "6" +bool(true) +string(1) "6" diff --git a/ext/dom/tests/modern/common/Element_getElementsByClassName_quirks.phpt b/ext/dom/tests/modern/common/Element_getElementsByClassName_quirks.phpt new file mode 100644 index 000000000000..52e964ea4317 --- /dev/null +++ b/ext/dom/tests/modern/common/Element_getElementsByClassName_quirks.phpt @@ -0,0 +1,69 @@ +--TEST-- +Dom\Element::getElementsByClassName() quirks mode +--EXTENSIONS-- +dom +--FILE-- + +
+

1

+

2

+

3

+

4

+
+ + +HTML, LIBXML_NOERROR); +$collection = $dom->documentElement->getElementsByClassName("Bar"); + +echo "There are {$dom->getElementsByClassName("foo \n bar")->count()} items in the document in total that have both \"foo\" and \"bar\"\n"; + +echo "There are {$collection->count()} \"Bar\" items\n"; + +foreach ($collection as $key => $node) { + echo "--- Key $key ---\n"; + var_dump($node->tagName, $node->textContent); + var_dump($node === $collection->item($key)); +} + +echo "--- named item \"here\" ---\n"; + +var_dump($collection->namedItem("here")->textContent); + +?> +--EXPECT-- +There are 1 items in the document in total that have both "foo" and "bar" +There are 4 "Bar" items +--- Key 0 --- +string(3) "DIV" +string(56) " + + 1 + 2 + 3 + 4 + + +" +bool(true) +--- Key 1 --- +string(4) "MAIN" +string(45) " + 1 + 2 + 3 + 4 + " +bool(true) +--- Key 2 --- +string(1) "P" +string(1) "2" +bool(true) +--- Key 3 --- +string(1) "P" +string(1) "4" +bool(true) +--- named item "here" --- +string(1) "2" diff --git a/ext/dom/tests/modern/common/ParentNode_children.phpt b/ext/dom/tests/modern/common/ParentNode_children.phpt new file mode 100644 index 000000000000..54db132f1b16 --- /dev/null +++ b/ext/dom/tests/modern/common/ParentNode_children.phpt @@ -0,0 +1,48 @@ +--TEST-- +ParentNode::$children +--EXTENSIONS-- +dom +--FILE-- + +
+ + + + + +XML); +$children = $dom->documentElement->children; +var_dump($children === $dom->documentElement->children); // Tests caching behaviour +var_dump($children !== (clone $dom->documentElement)->children); // Tests caching behaviour does not persist across clones +var_dump(count($children)); +var_dump($children->length); + +foreach ($children as $key => $child) { + var_dump($key, $child->nodeName); +} + +foreach ($children->namedItem('foo')->children as $key => $child) { + var_dump($key, $child->nodeName); +} + +?> +--EXPECT-- +bool(true) +bool(true) +int(4) +int(4) +int(0) +string(1) "a" +int(1) +string(1) "b" +int(2) +string(1) "c" +int(3) +string(1) "e" +int(0) +string(2) "c1" +int(1) +string(2) "c2" diff --git a/ext/dom/tests/modern/common/gh21077.phpt b/ext/dom/tests/modern/common/gh21077.phpt new file mode 100644 index 000000000000..d9f9478925ee --- /dev/null +++ b/ext/dom/tests/modern/common/gh21077.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-21077 (Accessing Dom\Node::baseURI can throw TypeError) +--EXTENSIONS-- +dom +--CREDITS-- +mbeccati +--FILE-- +createDocumentType('html', 'publicId', 'systemId'); + +var_dump($node->baseURI); + +$dom = Dom\XMLDocument::createEmpty(); +$dom->append($node = $dom->importNode($node)); + +var_dump($dom->saveXML()); + +var_dump($node->baseURI); + +?> +--EXPECT-- +string(11) "about:blank" +string(84) " + +" +string(11) "about:blank" diff --git a/ext/dom/tests/modern/common/gh21097.phpt b/ext/dom/tests/modern/common/gh21097.phpt new file mode 100644 index 000000000000..db6abd12fcf7 --- /dev/null +++ b/ext/dom/tests/modern/common/gh21097.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-21097 (Accessing Dom\Node properties can can throw TypeError(s)) +--EXTENSIONS-- +dom +--CREDITS-- +mbeccati +--FILE-- +createDocumentType('html', 'publicId', 'systemId'); + +$r = new \ReflectionClass($node); +foreach ($r->getProperties(\ReflectionProperty::IS_PUBLIC) as $p) { + echo $p->getName(), ": "; + var_dump($node->{$p->getName()}); +} + +?> +--EXPECT-- +nodeType: int(10) +nodeName: string(4) "html" +baseURI: string(11) "about:blank" +isConnected: bool(false) +ownerDocument: NULL +parentNode: NULL +parentElement: NULL +childNodes: object(Dom\NodeList)#24 (1) { + ["length"]=> + int(0) +} +firstChild: NULL +lastChild: NULL +previousSibling: NULL +nextSibling: NULL +nodeValue: NULL +textContent: string(0) "" +name: string(4) "html" +entities: object(Dom\DtdNamedNodeMap)#24 (1) { + ["length"]=> + int(0) +} +notations: object(Dom\DtdNamedNodeMap)#24 (1) { + ["length"]=> + int(0) +} +publicId: string(8) "publicId" +systemId: string(8) "systemId" +internalSubset: NULL diff --git a/ext/dom/tests/modern/css_selectors/gh18877.phpt b/ext/dom/tests/modern/css_selectors/gh18877.phpt new file mode 100644 index 000000000000..8cab491a0dde --- /dev/null +++ b/ext/dom/tests/modern/css_selectors/gh18877.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-18877 (\Dom\HTMLDocument querySelectorAll selecting only the first when using ~ and :has) +--EXTENSIONS-- +dom +--FILE-- + + + + +
+ 1 + 2 + 3 + + +TEXT; + +$dom = \Dom\HTMLDocument::createFromString($text, options: LIBXML_NOERROR); +foreach ($dom->querySelectorAll('div:has(div) ~ *') as $node) { + var_dump($node->textContent); +} + +?> +--EXPECT-- +string(1) "1" +string(1) "2" +string(1) "3" diff --git a/ext/dom/tests/modern/css_selectors/gh20395.phpt b/ext/dom/tests/modern/css_selectors/gh20395.phpt new file mode 100644 index 000000000000..af04cb1c27a4 --- /dev/null +++ b/ext/dom/tests/modern/css_selectors/gh20395.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-20395 (\Dom\ParentNode::querySelector and \Dom\ParentNode::querySelectorAll requires elements in $selectors to be lowercase) +--EXTENSIONS-- +dom +--CREDITS-- +DeveloperRob +--FILE-- +'; +$dom = Dom\HtmlDocument::createFromString($html); +var_dump(is_null($dom->querySelector('html'))); +var_dump(is_null($dom->querySelector('Html'))); +var_dump(is_null($dom->querySelector('HTML'))); + +$dom->body->appendChild($dom->createElement('div')); +$dom->body->appendChild($dom->createElementNS('http://www.w3.org/1999/xhtml', 'Div')); + +foreach ($dom->querySelectorAll('div') as $div) { + var_dump($div->localName); +} + +foreach ($dom->querySelectorAll('Div') as $div) { + var_dump($div->localName); +} + +?> +--EXPECT-- +bool(false) +bool(false) +bool(false) +string(3) "div" +string(3) "div" diff --git a/ext/dom/tests/modern/css_selectors/pseudo_classes_links.phpt b/ext/dom/tests/modern/css_selectors/pseudo_classes_links.phpt index 8a688286b680..7afcb6e3cfbd 100644 --- a/ext/dom/tests/modern/css_selectors/pseudo_classes_links.phpt +++ b/ext/dom/tests/modern/css_selectors/pseudo_classes_links.phpt @@ -11,6 +11,7 @@ $dom = DOM\XMLDocument::createFromString(<<
Link Link + Not actually a link Link XML); @@ -18,6 +19,7 @@ XML); test_helper($dom, ':any-link'); test_helper($dom, ':link'); test_helper($dom, 'a:not(:any-link)'); +test_helper($dom, ':not(:any-link)'); ?> --EXPECT-- @@ -29,3 +31,12 @@ test_helper($dom, 'a:not(:any-link)'); Link --- Selector: a:not(:any-link) --- Link +--- Selector: :not(:any-link) --- + + Link + Link + Not actually a link + Link + +Link +Not actually a link diff --git a/ext/dom/tests/modern/html/gh21688.phpt b/ext/dom/tests/modern/html/gh21688.phpt new file mode 100644 index 000000000000..ddfb4d326c63 --- /dev/null +++ b/ext/dom/tests/modern/html/gh21688.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-21688 (SEGV in C14N on empty HTMLDocument) +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +dom +--FILE-- +C14N()); +?> +--EXPECT-- +string(0) "" diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt index 5051c3f9aabf..c6347ae48589 100644 --- a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt +++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_01.phpt @@ -23,7 +23,7 @@ var_dump(get_class($dom->getElementsByTagName("p")->item(0))); ?> --EXPECT-- -object(Dom\HTMLDocument)#1 (28) { +object(Dom\HTMLDocument)#1 (29) { ["implementation"]=> string(22) "(object value omitted)" ["URL"]=> @@ -40,6 +40,8 @@ object(Dom\HTMLDocument)#1 (28) { NULL ["documentElement"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt index b160c72f0a54..d7dea308b5d2 100644 --- a/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt +++ b/ext/dom/tests/modern/html/interactions/HTMLDocument_should_retain_properties_and_owner_02.phpt @@ -23,7 +23,7 @@ var_dump(get_class($dom->getElementsByTagName("p")->item(0))); ?> --EXPECT-- -object(Dom\HTMLDocument)#1 (28) { +object(Dom\HTMLDocument)#1 (29) { ["implementation"]=> string(22) "(object value omitted)" ["URL"]=> @@ -40,6 +40,8 @@ object(Dom\HTMLDocument)#1 (28) { NULL ["documentElement"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/html/interactions/gh20281.phpt b/ext/dom/tests/modern/html/interactions/gh20281.phpt new file mode 100644 index 000000000000..324c5a275633 --- /dev/null +++ b/ext/dom/tests/modern/html/interactions/gh20281.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-20281 (\Dom\Document::getElementById() is inconsistent after nodes are removed) +--EXTENSIONS-- +dom +--CREDITS-- +cscott +--FILE-- +b

c

', LIBXML_NOERROR); +$p = $d->getElementById('a'); +$p->remove(); +echo $d->getElementById('a')->textContent, "\n"; +?> +--EXPECT-- +c diff --git a/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt b/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt index 058d4432b49d..89574b7a631f 100644 --- a/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt +++ b/ext/dom/tests/modern/html/parser/Element_innerHTML.phpt @@ -60,6 +60,6 @@ echo $dom->saveXML(), "\n"; - + diff --git a/ext/dom/tests/modern/html/parser/gh21486.phpt b/ext/dom/tests/modern/html/parser/gh21486.phpt new file mode 100644 index 000000000000..62df1e5ca6bd --- /dev/null +++ b/ext/dom/tests/modern/html/parser/gh21486.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-21486 (Dom\HTMLDocument parser mangles xml:space and xml:lang attributes) +--EXTENSIONS-- +dom +--CREDITS-- +JKingweb +--FILE-- +"); +$e = $d->getElementsByTagName("div")[0]; +$e->innerHTML = ''; +$svg = $d->querySelector("svg"); +echo $e->innerHTML."\n"; +echo $svg->attributes[0]->localName." ".var_export($svg->attributes[0]->namespaceURI, true)."\n"; +?> +--EXPECT-- + +space 'http://www.w3.org/XML/1998/namespace' diff --git a/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt b/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt index ae49a6a494c9..4cf1b3888fee 100644 --- a/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt +++ b/ext/dom/tests/modern/spec/Document_implementation_createDocument.phpt @@ -37,7 +37,7 @@ echo $dom->implementation->createDocument(null, "", $dtd)->saveXml(), "\n"; ?> --EXPECT-- --- (null, "") --- -object(Dom\XMLDocument)#3 (32) { +object(Dom\XMLDocument)#3 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -62,6 +62,8 @@ object(Dom\XMLDocument)#3 (32) { NULL ["documentElement"]=> NULL + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt b/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt index bfb150b5cca8..74deed8bdc34 100644 --- a/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt +++ b/ext/dom/tests/modern/spec/Document_implementation_createDocumentType.phpt @@ -43,7 +43,7 @@ object(Dom\DocumentType)#3 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> @@ -86,7 +86,7 @@ object(Dom\DocumentType)#2 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> @@ -129,7 +129,7 @@ object(Dom\DocumentType)#1 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> @@ -172,7 +172,7 @@ object(Dom\DocumentType)#4 (19) { ["nodeName"]=> string(5) "qname" ["baseURI"]=> - NULL + string(11) "about:blank" ["isConnected"]=> bool(false) ["parentNode"]=> diff --git a/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt b/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt index 78625fcb6f7d..cb623f702983 100644 --- a/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt +++ b/ext/dom/tests/modern/spec/Element_prefix_readonly.phpt @@ -14,5 +14,5 @@ try { echo $dom->saveXml(); ?> --EXPECT-- -Cannot modify readonly property Dom\HTMLElement::$prefix +Cannot modify private(set) property Dom\Element::$prefix from global scope diff --git a/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt b/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt index 67a964a7ec51..a88b4fc808b0 100644 --- a/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt +++ b/ext/dom/tests/modern/spec/ParentNode_append_exception_consistency.phpt @@ -18,7 +18,9 @@ var_dump($element->parentNode); ?> --EXPECT-- Exception: Cannot have more than one element child in a document -object(Dom\DocumentFragment)#2 (17) { +object(Dom\DocumentFragment)#2 (18) { + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt b/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt index fb0853939f88..4ac15a029e37 100644 --- a/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt +++ b/ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt @@ -21,7 +21,6 @@ var_dump($doctype); var_dump($doctype->entities["test"]); var_dump($doctype->entities["myimage"]); -// TODO: isConnected returning false is a bug var_dump($doctype->notations["GIF"]); ?> @@ -142,17 +141,19 @@ object(Dom\Entity)#3 (17) { ["textContent"]=> NULL } -object(Dom\Notation)#4 (13) { +object(Dom\Notation)#4 (14) { ["nodeType"]=> int(12) ["nodeName"]=> string(3) "GIF" ["baseURI"]=> - NULL + string(%d) "%s" ["isConnected"]=> - bool(false) + bool(true) + ["ownerDocument"]=> + string(22) "(object value omitted)" ["parentNode"]=> - NULL + string(22) "(object value omitted)" ["parentElement"]=> NULL ["childNodes"]=> @@ -168,5 +169,5 @@ object(Dom\Notation)#4 (13) { ["nodeValue"]=> NULL ["textContent"]=> - string(0) "" + NULL } diff --git a/ext/dom/tests/modern/xml/XMLDocument_debug.phpt b/ext/dom/tests/modern/xml/XMLDocument_debug.phpt index e2d6ebffe89c..7067e5607bdb 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_debug.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_debug.phpt @@ -10,7 +10,7 @@ var_dump($dom); ?> --EXPECT-- -object(Dom\XMLDocument)#1 (32) { +object(Dom\XMLDocument)#1 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -35,6 +35,8 @@ object(Dom\XMLDocument)#1 (32) { NULL ["documentElement"]=> NULL + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt b/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt index 62d64a05f9b2..6276d1e9a98c 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_fromEmptyDocument_02.phpt @@ -10,7 +10,7 @@ var_dump($dom); ?> --EXPECT-- -object(Dom\XMLDocument)#1 (32) { +object(Dom\XMLDocument)#1 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -35,6 +35,8 @@ object(Dom\XMLDocument)#1 (32) { NULL ["documentElement"]=> NULL + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> NULL ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt b/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt index 13359f4b2858..16db09547bff 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_fromString_03.phpt @@ -6,7 +6,7 @@ dom '', + 'JPEG' => '', + 'HTML' => '', +]; + +foreach ($cases as $name => $declaration) { + $xml = << + +XML; + + $dom = Dom\XMLDocument::createFromString($xml); + $doctype = $dom->doctype; + $notations = $doctype->notations; + + echo "=== $name ===\n"; + + $namedNotation = $notations->getNamedItem($name); + foreach ($notations as $iteratedNotation) { + // getNamedItem + var_dump($namedNotation->nodeName); + var_dump($namedNotation->textContent); + var_dump($namedNotation->nodeValue); + var_dump($namedNotation->isConnected); + var_dump($namedNotation->ownerDocument === $dom); + var_dump($namedNotation->parentNode === $doctype); + var_dump($namedNotation->parentElement); + + // iteration + var_dump($iteratedNotation->nodeName); + var_dump($iteratedNotation->textContent); + var_dump($iteratedNotation->nodeValue); + var_dump($iteratedNotation->isConnected); + var_dump($iteratedNotation->ownerDocument === $dom); + var_dump($iteratedNotation->parentNode === $doctype); + var_dump($iteratedNotation->parentElement); + + // wiring + // getNamedItem and iteration each allocate a fresh Notation instance + var_dump($namedNotation !== $iteratedNotation); + } +} +?> +--EXPECT-- +=== GIF === +string(3) "GIF" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +string(3) "GIF" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +bool(true) +=== JPEG === +string(4) "JPEG" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +string(4) "JPEG" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +bool(true) +=== HTML === +string(4) "HTML" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +string(4) "HTML" +NULL +NULL +bool(true) +bool(true) +bool(true) +NULL +bool(true) diff --git a/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt b/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt index e18c43f05ae8..89cfe83de710 100644 --- a/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt +++ b/ext/dom/tests/modern/xml/XMLDocument_node_ownerDocument_for_XML.phpt @@ -13,7 +13,7 @@ var_dump($element->ownerDocument); ?> --EXPECTF-- -object(Dom\XMLDocument)#1 (32) { +object(Dom\XMLDocument)#1 (33) { ["xmlEncoding"]=> string(5) "UTF-8" ["xmlStandalone"]=> @@ -38,6 +38,8 @@ object(Dom\XMLDocument)#1 (32) { NULL ["documentElement"]=> string(22) "(object value omitted)" + ["children"]=> + string(22) "(object value omitted)" ["firstElementChild"]=> string(22) "(object value omitted)" ["lastElementChild"]=> diff --git a/ext/dom/tests/modern/xml/attribute_getNamedItemNS_incorrect_ns_check.phpt b/ext/dom/tests/modern/xml/attribute_getNamedItemNS_incorrect_ns_check.phpt new file mode 100644 index 000000000000..dc8c1f87c14c --- /dev/null +++ b/ext/dom/tests/modern/xml/attribute_getNamedItemNS_incorrect_ns_check.phpt @@ -0,0 +1,26 @@ +--TEST-- +getNamedItemNS() incorrect namespace check +--EXTENSIONS-- +dom +--CREDITS-- +veewee +--FILE-- + + + +EOXML +); +$documentElement = $xml->documentElement; +$attributes = $documentElement->attributes; +$schemaLocation = $attributes->getNamedItemNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation'); +var_dump($schemaLocation->textContent); + +?> +--EXPECT-- +string(116) "http://www.happy-helpers1.com note-namespace1.xsd http://www.happy-helpers2.com http://localhost/note-namespace2.xsd" diff --git a/ext/dom/tests/modern/xml/canonicalize_unattached.phpt b/ext/dom/tests/modern/xml/canonicalize_unattached.phpt new file mode 100644 index 000000000000..cec5f1085757 --- /dev/null +++ b/ext/dom/tests/modern/xml/canonicalize_unattached.phpt @@ -0,0 +1,20 @@ +--TEST-- +Canonicalize unattached node should fail +--EXTENSIONS-- +dom +--FILE-- +'); +$child = $d->documentElement->firstChild; +$child->remove(); + +try { + $child->C14N(); +} catch (Dom\DOMException $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Canonicalization can only happen on nodes attached to a document. diff --git a/ext/dom/tests/modern/xml/gh18979.phpt b/ext/dom/tests/modern/xml/gh18979.phpt new file mode 100644 index 000000000000..3a90bd583773 --- /dev/null +++ b/ext/dom/tests/modern/xml/gh18979.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-18979 (DOM\XMLDocument::createComment() triggers undefined behavior with null byte) +--EXTENSIONS-- +dom +--FILE-- +createElement("container"); +$container->append($dom->createComment("\0")); +var_dump($container->innerHTML); +?> +--EXPECT-- +string(7) "" diff --git a/ext/dom/tests/modern/xml/gh20444.phpt b/ext/dom/tests/modern/xml/gh20444.phpt new file mode 100644 index 000000000000..b3a77e3f13ed --- /dev/null +++ b/ext/dom/tests/modern/xml/gh20444.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-20444 (Dom\XMLDocument::C14N() seems broken compared to DOMDocument::C14N()) +--EXTENSIONS-- +dom +--FILE-- + + + + abc + +EOF; + +$d = \Dom\XMLDocument::createFromString($xml); +var_dump($d->C14N(true)); + +$xml = << + + + + 123 + + +EOF; + +$d = \Dom\XMLDocument::createFromString($xml); +var_dump($d->C14N()); + +?> +--EXPECT-- +string(128) " + + abc +" +string(134) " + + + 123 + +" diff --git a/ext/dom/tests/modern/xml/gh21544.phpt b/ext/dom/tests/modern/xml/gh21544.phpt new file mode 100644 index 000000000000..b76742ae84a5 --- /dev/null +++ b/ext/dom/tests/modern/xml/gh21544.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-21544 (Dom\XMLDocument::C14N() drops namespace declarations on DOM-built documents) +--CREDITS-- +Toon Verwerft (veewee) +--EXTENSIONS-- +dom +--FILE-- +createElementNS("urn:envelope", "env:Root"); +$doc->appendChild($root); +$child = $doc->createElementNS("urn:child", "x:Child"); +$root->appendChild($child); + +$parsed = Dom\XMLDocument::createFromString( + '' +); + +echo "DOM-built C14N: " . $doc->C14N() . PHP_EOL; +echo "Parsed C14N: " . $parsed->C14N() . PHP_EOL; +var_dump($doc->C14N() === $parsed->C14N()); + +?> +--EXPECT-- +DOM-built C14N: +Parsed C14N: +bool(true) diff --git a/ext/dom/tests/modern/xml/gh21548.phpt b/ext/dom/tests/modern/xml/gh21548.phpt new file mode 100644 index 000000000000..55299c8d6e67 --- /dev/null +++ b/ext/dom/tests/modern/xml/gh21548.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-21548 (Dom\XMLDocument::C14N() emits duplicate xmlns declarations after setAttributeNS()) +--CREDITS-- +Toon Verwerft (veewee) +--EXTENSIONS-- +dom +--FILE-- +'); +$doc->documentElement->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:ns1", "urn:a"); + +echo $doc->C14N() . PHP_EOL; + +?> +--EXPECT-- + diff --git a/ext/dom/tests/parentnode_childnode_too_long_text.phpt b/ext/dom/tests/parentnode_childnode_too_long_text.phpt index 62edaebfe4a8..dee10566e265 100644 --- a/ext/dom/tests/parentnode_childnode_too_long_text.phpt +++ b/ext/dom/tests/parentnode_childnode_too_long_text.phpt @@ -6,6 +6,7 @@ dom memory_limit=-1 --SKIPIF-- --EXPECT-- Cannot assign array to property DOMNode::$nodeValue of type ?string -Cannot modify readonly property DOMDocument::$nodeType -Cannot modify readonly property DOMDocument::$xmlEncoding -Cannot modify readonly property DOMEntity::$actualEncoding -Cannot modify readonly property DOMEntity::$encoding -Cannot modify readonly property DOMEntity::$version +Cannot modify private(set) property DOMNode::$nodeType from global scope +Cannot modify private(set) property DOMDocument::$xmlEncoding from global scope +Cannot modify private(set) property DOMEntity::$actualEncoding from global scope +Cannot modify private(set) property DOMEntity::$encoding from global scope +Cannot modify private(set) property DOMEntity::$version from global scope diff --git a/ext/dom/tests/registerPhpFunctionNS.phpt b/ext/dom/tests/registerPhpFunctionNS.phpt index 4c4fb157000b..2ee98168251f 100644 --- a/ext/dom/tests/registerPhpFunctionNS.phpt +++ b/ext/dom/tests/registerPhpFunctionNS.phpt @@ -62,14 +62,14 @@ $xpath->registerPhpFunctionNS('urn:bar', 'test', 'strtolower'); var_dump($xpath->query('//a[bar:test(string(@href)) = "https://php.net"]')); ?> ---EXPECT-- +--EXPECTF-- --- Legit cases: global function callable --- object(DOMNodeList)#5 (1) { ["length"]=> int(1) } --- Legit cases: string callable --- -object(DOMNodeList)#5 (1) { +object(DOMNodeList)#%d (1) { ["length"]=> int(1) } @@ -79,12 +79,12 @@ array(1) { [0]=> string(15) "https://PHP.net" } -object(DOMNodeList)#3 (1) { +object(DOMNodeList)#%d (1) { ["length"]=> int(0) } --- Legit cases: instance class method callable --- -object(DOMNodeList)#6 (1) { +object(DOMNodeList)#%d (1) { ["length"]=> int(1) } @@ -100,7 +100,7 @@ array(1) { --- Legit cases: global function callable that returns nothing --- string(15) "https://PHP.net" --- Legit cases: multiple namespaces --- -object(DOMNodeList)#5 (1) { +object(DOMNodeList)#%d (1) { ["length"]=> int(1) } diff --git a/ext/dom/text.c b/ext/dom/text.c index ca8fcf63d3ac..357ff1969490 100644 --- a/ext/dom/text.c +++ b/ext/dom/text.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | @@ -96,7 +94,6 @@ Modern spec URL: https://dom.spec.whatwg.org/#dom-text-splittext */ PHP_METHOD(DOMText, splitText) { - zval *id; xmlChar *first; xmlChar *second; xmlNodePtr node; @@ -105,11 +102,10 @@ PHP_METHOD(DOMText, splitText) int length; dom_object *intern; - id = ZEND_THIS; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &offset) == FAILURE) { RETURN_THROWS(); } - DOM_GET_OBJ(node, id, xmlNodePtr, intern); + DOM_GET_OBJ(node, ZEND_THIS, xmlNodePtr, intern); if (offset < 0) { zend_argument_value_error(1, "must be greater than or equal to 0"); @@ -129,17 +125,18 @@ PHP_METHOD(DOMText, splitText) first = xmlUTF8Strndup(cur, (int)offset); second = xmlUTF8Strsub(cur, (int)offset, (int)(length - offset)); - xmlNodeSetContent(node, first); - nnode = xmlNewDocText(node->doc, second); - - xmlFree(first); - xmlFree(second); + xmlNodeSetContent(node, NULL); + node->content = first; + nnode = xmlNewDocText(node->doc, NULL); if (nnode == NULL) { + xmlFree(second); php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true); RETURN_THROWS(); } + nnode->content = second; + if (node->parent != NULL) { nnode->type = XML_ELEMENT_NODE; xmlAddNextSibling(node, nnode); @@ -155,21 +152,11 @@ Since: DOM Level 3 */ PHP_METHOD(DOMText, isWhitespaceInElementContent) { - zval *id; xmlNodePtr node; dom_object *intern; - - id = ZEND_THIS; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } - DOM_GET_OBJ(node, id, xmlNodePtr, intern); - - if (xmlIsBlankNode(node)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_NONE(); + DOM_GET_OBJ(node, ZEND_THIS, xmlNodePtr, intern); + RETURN_BOOL(xmlIsBlankNode(node)); } /* }}} end dom_text_is_whitespace_in_element_content */ diff --git a/ext/dom/token_list.c b/ext/dom/token_list.c index fe768e17b2e9..de449465b768 100644 --- a/ext/dom/token_list.c +++ b/ext/dom/token_list.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | +----------------------------------------------------------------------+ @@ -51,7 +49,7 @@ static zend_always_inline void dom_add_token(HashTable *ht, zend_string *token) /* https://dom.spec.whatwg.org/#concept-ordered-set-parser * and https://infra.spec.whatwg.org/#split-on-ascii-whitespace */ -static void dom_ordered_set_parser(HashTable *token_set, const char *position) +void dom_ordered_set_parser(HashTable *token_set, const char *position, bool to_lowercase) { /* Adapted steps from "split on ASCII whitespace" such that that loop directly appends to the token set. */ @@ -72,6 +70,9 @@ static void dom_ordered_set_parser(HashTable *token_set, const char *position) /* 4.2. Append token to tokens. */ zend_string *token = zend_string_init(start, length, false); + if (to_lowercase) { + zend_str_tolower(ZSTR_VAL(token), length); + } dom_add_token(token_set, token); zend_string_release_ex(token, false); @@ -83,6 +84,53 @@ static void dom_ordered_set_parser(HashTable *token_set, const char *position) * => That's the token set. */ } +/* This returns true if all tokens in "token_set" are found in "value". */ +bool dom_ordered_set_all_contained(HashTable *token_set, const char *value, bool to_lowercase) +{ + /* This code is conceptually close to dom_ordered_set_parser(), + * but without building a hash table. + * Since the storage of the token set maps a value on itself, + * we can reuse that storage as a "seen" flag by setting it to NULL. */ + zval *zv; + + uint32_t still_needed = zend_hash_num_elements(token_set); + + value += strspn(value, ascii_whitespace); + + while (*value != '\0' && still_needed > 0) { + const char *start = value; + value += strcspn(value, ascii_whitespace); + size_t length = value - start; + + if (to_lowercase) { + ALLOCA_FLAG(use_heap) + char *lc_str = zend_str_tolower_copy(do_alloca(length + 1, use_heap), start, length); + zv = zend_hash_str_find(token_set, lc_str, length); + free_alloca(lc_str, use_heap); + } else { + zv = zend_hash_str_find(token_set, start, length); + } + if (zv) { + if (Z_STR_P(zv)) { + still_needed--; + Z_STR_P(zv) = NULL; + } + } + + value += strspn(value, ascii_whitespace); + } + + /* Restore "seen" flag. */ + zend_string *k; + ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(token_set, k, zv) { + if (!Z_STR_P(zv)) { + Z_STR_P(zv) = k; + } + } ZEND_HASH_FOREACH_END(); + + return still_needed == 0; +} + /* https://dom.spec.whatwg.org/#concept-ordered-set-serializer */ static char *dom_ordered_set_serializer(HashTable *token_set) { @@ -166,7 +214,7 @@ static void dom_token_list_update_set(dom_token_list_object *intern, HashTable * xmlChar *value = dom_token_list_get_class_value(attr, &should_free); if (value != NULL) { /* 2. Otherwise, parse the token set. */ - dom_ordered_set_parser(token_set, (const char *) value); + dom_ordered_set_parser(token_set, (const char *) value, false); intern->cached_string = estrdup((const char *) value); } else { intern->cached_string = NULL; @@ -527,7 +575,7 @@ PHP_METHOD(Dom_TokenList, toggle) HashTable *token_set = TOKEN_LIST_GET_SET(intern); zval *found_token = zend_hash_find(token_set, token); if (found_token != NULL) { - ZEND_ASSERT(XtOffsetOf(Bucket, val) == 0 && "the cast only works if this is true"); + ZEND_ASSERT(offsetof(Bucket, val) == 0 && "the cast only works if this is true"); Bucket *bucket = (Bucket *) found_token; /* 3.1. If force is either not given or is false, then remove token from this’s token set, @@ -577,7 +625,7 @@ PHP_METHOD(Dom_TokenList, replace) } /* 4. Replace token in this’s token set with newToken. */ - ZEND_ASSERT(XtOffsetOf(Bucket, val) == 0 && "the cast only works if this is true"); + ZEND_ASSERT(offsetof(Bucket, val) == 0 && "the cast only works if this is true"); Bucket *bucket = (Bucket *) found_token; if (zend_hash_set_bucket_key(token_set, bucket, new_token) == NULL) { /* It already exists, remove token instead. */ diff --git a/ext/dom/token_list.h b/ext/dom/token_list.h index 4711852c4d87..7bddd6c9b462 100644 --- a/ext/dom/token_list.h +++ b/ext/dom/token_list.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | +----------------------------------------------------------------------+ @@ -27,14 +25,16 @@ typedef struct dom_token_list_object { static inline dom_token_list_object *php_dom_token_list_from_obj(zend_object *obj) { - return (dom_token_list_object *)((char *) obj - XtOffsetOf(dom_token_list_object, dom.std)); + return (dom_token_list_object *)((char *) obj - offsetof(dom_token_list_object, dom.std)); } static inline dom_token_list_object *php_dom_token_list_from_dom_obj(dom_object *obj) { - return (dom_token_list_object *)((char *) obj - XtOffsetOf(dom_token_list_object, dom)); + return ZEND_CONTAINER_OF(obj, dom_token_list_object, dom); } +void dom_ordered_set_parser(HashTable *token_set, const char *position, bool to_lowercase); +bool dom_ordered_set_all_contained(HashTable *token_set, const char *value, bool to_lowercase); void dom_token_list_ctor(dom_token_list_object *intern, dom_object *element_obj); void dom_token_list_free_obj(zend_object *object); zval *dom_token_list_read_dimension(zend_object *object, zval *offset, int type, zval *rv); diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h index a63e43e92a77..42937cc37848 100644 --- a/ext/dom/xml_common.h +++ b/ext/dom/xml_common.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | @@ -30,7 +28,7 @@ typedef struct _dom_object { } dom_object; static inline dom_object *php_dom_obj_from_obj(zend_object *obj) { - return (dom_object*)((char*)(obj) - XtOffsetOf(dom_object, std)); + return ZEND_CONTAINER_OF(obj, dom_object, std); } #define Z_DOMOBJ_P(zv) php_dom_obj_from_obj(Z_OBJ_P((zv))) diff --git a/ext/dom/xml_document.c b/ext/dom/xml_document.c index 4d941de0f068..e4f7542f1696 100644 --- a/ext/dom/xml_document.c +++ b/ext/dom/xml_document.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | +----------------------------------------------------------------------+ @@ -39,7 +37,6 @@ static bool check_options_validity(uint32_t arg_num, zend_long options) | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS - | XML_PARSE_XINCLUDE | XML_PARSE_NSCLEAN | XML_PARSE_NOCDATA | XML_PARSE_NONET @@ -60,7 +57,6 @@ static bool check_options_validity(uint32_t arg_num, zend_long options) "LIBXML_NOERROR, " "LIBXML_NOWARNING, " "LIBXML_NOBLANKS, " - "LIBXML_XINCLUDE, " "LIBXML_NSCLEAN, " "LIBXML_NOCDATA, " "LIBXML_NONET, " diff --git a/ext/dom/xml_serializer.c b/ext/dom/xml_serializer.c index debbb41fdade..da43f24aab01 100644 --- a/ext/dom/xml_serializer.c +++ b/ext/dom/xml_serializer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | +----------------------------------------------------------------------+ @@ -640,7 +638,11 @@ static int dom_xml_serialize_comment_node(xmlOutputBufferPtr out, xmlNodePtr com const xmlChar *ptr = comment->content; if (ptr != NULL) { TRY(dom_xml_check_char_production(ptr)); - if (strstr((const char *) ptr, "--") != NULL || ptr[strlen((const char *) ptr) - 1] == '-') { + if (strstr((const char *) ptr, "--") != NULL) { + return -1; + } + size_t len = strlen((const char *) ptr); + if (len > 0 && ptr[len - 1] == '-') { return -1; } } @@ -1093,7 +1095,10 @@ static int dom_xml_serialize_element_node( /* 14. If ns is the HTML namespace, and the node's list of children is empty, and the node's localName matches * any one of the following void elements: ... */ if (element->children == NULL) { - if (xmlSaveNoEmptyTags) { + ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations") + int saveNoEmptyTags = xmlSaveNoEmptyTags; + ZEND_DIAGNOSTIC_IGNORED_END + if (saveNoEmptyTags) { /* Do nothing, use the closing style. */ } else if (php_dom_ns_is_fast(element, php_dom_ns_is_html_magic_token)) { size_t name_length = strlen((const char *) element->name); diff --git a/ext/dom/xml_serializer.h b/ext/dom/xml_serializer.h index 2d5c3bd84277..e686083a27aa 100644 --- a/ext/dom/xml_serializer.h +++ b/ext/dom/xml_serializer.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | +----------------------------------------------------------------------+ diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index 21baa59ffed0..bd9947b4ad10 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | @@ -35,6 +33,24 @@ #ifdef LIBXML_XPATH_ENABLED +static dom_object *dom_xpath_intern_for_doc(dom_xpath_object *xpath_obj, xmlDocPtr doc) +{ + if (xpath_obj->dom.document && xpath_obj->dom.document->ptr == doc) { + return &xpath_obj->dom; + } + HashTable *node_list = xpath_obj->xpath_callbacks.node_list; + if (node_list) { + zval *entry; + ZEND_HASH_PACKED_FOREACH_VAL(node_list, entry) { + dom_object *obj = Z_DOMOBJ_P(entry); + if (obj->document && obj->document->ptr == doc) { + return obj; + } + } ZEND_HASH_FOREACH_END(); + } + return &xpath_obj->dom; +} + void dom_xpath_objects_free_storage(zend_object *object) { dom_xpath_object *intern = php_xpath_obj_from_obj(object); @@ -191,7 +207,7 @@ zend_result dom_xpath_document_read(dom_object *obj, zval *retval) /* {{{ registerNodeNamespaces bool*/ static inline dom_xpath_object *php_xpath_obj_from_dom_obj(dom_object *obj) { - return (dom_xpath_object*)((char*)(obj) - XtOffsetOf(dom_xpath_object, dom)); + return ZEND_CONTAINER_OF(obj, dom_xpath_object, dom); } zend_result dom_xpath_register_node_ns_read(dom_object *obj, zval *retval) @@ -227,10 +243,7 @@ PHP_METHOD(DOMXPath, registerNamespace) RETURN_THROWS(); } - if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) { - RETURN_FALSE; - } - RETURN_TRUE; + RETURN_BOOL(xmlXPathRegisterNs(ctxp, prefix, ns_uri) == 0); } /* }}} */ @@ -357,7 +370,8 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern) node = php_dom_create_fake_namespace_decl(nsparent, original, &child, parent_intern); } else { - php_dom_create_object(node, &child, &intern->dom); + dom_object *parent = dom_xpath_intern_for_doc(intern, node->doc); + php_dom_create_object(node, &child, parent); } add_next_index_zval(&retval, &child); } diff --git a/ext/dom/xpath_callbacks.c b/ext/dom/xpath_callbacks.c index c4715fa67e80..90395dc15f2e 100644 --- a/ext/dom/xpath_callbacks.c +++ b/ext/dom/xpath_callbacks.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | @@ -215,6 +213,7 @@ static zend_result php_dom_xpath_callback_ns_update_method_handler( } zend_tmp_string_release(tmp_str); } else { + zend_tmp_string_release(tmp_str); zend_fcc_dtor(fcc); efree(fcc); return FAILURE; @@ -407,6 +406,7 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat fci.param_count = param_count; fci.params = params; fci.named_params = NULL; + fci.consumed_args = 0; ZVAL_STRINGL(&fci.function_name, function_name, function_name_length); zend_call_function(&fci, NULL); @@ -429,15 +429,12 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat if (Z_TYPE(callback_retval) != IS_UNDEF) { if (Z_TYPE(callback_retval) == IS_OBJECT && (instanceof_function(Z_OBJCE(callback_retval), dom_get_node_ce(php_dom_follow_spec_node((const xmlNode *) ctxt->context->doc))))) { - xmlNode *nodep; - dom_object *obj; if (xpath_callbacks->node_list == NULL) { xpath_callbacks->node_list = zend_new_array(0); } - Z_ADDREF_P(&callback_retval); zend_hash_next_index_insert_new(xpath_callbacks->node_list, &callback_retval); - obj = Z_DOMOBJ_P(&callback_retval); - nodep = dom_object_get_node(obj); + dom_object *obj = Z_DOMOBJ_P(&callback_retval); + xmlNodePtr nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(callback_retval) == IS_FALSE || Z_TYPE(callback_retval) == IS_TRUE) { valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(callback_retval) == IS_TRUE)); @@ -446,12 +443,10 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat zval_ptr_dtor(&callback_retval); return FAILURE; } else { - zend_string *tmp_str; - zend_string *str = zval_get_tmp_string(&callback_retval, &tmp_str); - valuePush(ctxt, xmlXPathNewString(BAD_CAST ZSTR_VAL(str))); - zend_tmp_string_release(tmp_str); + convert_to_string(&callback_retval); + valuePush(ctxt, xmlXPathNewString(BAD_CAST Z_STRVAL(callback_retval))); + zval_ptr_dtor_str(&callback_retval); } - zval_ptr_dtor(&callback_retval); } return SUCCESS; diff --git a/ext/dom/xpath_callbacks.h b/ext/dom/xpath_callbacks.h index 3a4d8731f474..072f52196331 100644 --- a/ext/dom/xpath_callbacks.h +++ b/ext/dom/xpath_callbacks.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | +----------------------------------------------------------------------+ diff --git a/ext/enchant/config.w32 b/ext/enchant/config.w32 index c50f48ffb6c8..45a194cdb7ff 100644 --- a/ext/enchant/config.w32 +++ b/ext/enchant/config.w32 @@ -3,8 +3,8 @@ ARG_WITH("enchant", "Enchant Support", "no"); if (PHP_ENCHANT == "yes") { - if (CHECK_HEADER_ADD_INCLUDE("enchant.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\enchant") && - CHECK_HEADER_ADD_INCLUDE("glib.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\glib-2.0")) { + if (CHECK_HEADER("enchant.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\enchant") && + CHECK_HEADER("glib.h", "CFLAGS_ENCHANT", PHP_ENCHANT+ ";" + PHP_PHP_BUILD + "\\include\\glib-2.0")) { if (CHECK_LIB("libenchant2.lib", "enchant", PHP_ENCHANT)) { have_enchant = true; } else if (CHECK_LIB("libenchant.lib", "enchant", PHP_ENCHANT)) { diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index eedb49b69e8f..4a37908612b2 100644 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre-Alain Joye | | Ilia Alshanetsky | @@ -51,7 +49,7 @@ zend_class_entry *enchant_broker_ce; static zend_object_handlers enchant_broker_handlers; static inline enchant_broker *enchant_broker_from_obj(zend_object *obj) { - return (enchant_broker *)((char *)(obj) - XtOffsetOf(enchant_broker, std)); + return ZEND_CONTAINER_OF(obj, enchant_broker, std); } #define Z_ENCHANT_BROKER_P(zv) enchant_broker_from_obj(Z_OBJ_P(zv)) @@ -69,7 +67,7 @@ zend_class_entry *enchant_dict_ce; static zend_object_handlers enchant_dict_handlers; static inline enchant_dict *enchant_dict_from_obj(zend_object *obj) { - return (enchant_dict *)((char *)(obj) - XtOffsetOf(enchant_dict, std)); + return ZEND_CONTAINER_OF(obj, enchant_dict, std); } #define Z_ENCHANT_DICT_P(zv) enchant_dict_from_obj(Z_OBJ_P(zv)) @@ -192,7 +190,7 @@ PHP_MINIT_FUNCTION(enchant) enchant_broker_ce->default_object_handlers = &enchant_broker_handlers; memcpy(&enchant_broker_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - enchant_broker_handlers.offset = XtOffsetOf(enchant_broker, std); + enchant_broker_handlers.offset = offsetof(enchant_broker, std); enchant_broker_handlers.free_obj = php_enchant_broker_free; enchant_broker_handlers.clone_obj = NULL; enchant_broker_handlers.compare = zend_objects_not_comparable; @@ -202,7 +200,7 @@ PHP_MINIT_FUNCTION(enchant) enchant_dict_ce->default_object_handlers = &enchant_dict_handlers; memcpy(&enchant_dict_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - enchant_dict_handlers.offset = XtOffsetOf(enchant_dict, std); + enchant_dict_handlers.offset = offsetof(enchant_dict, std); enchant_dict_handlers.free_obj = php_enchant_dict_free; enchant_dict_handlers.clone_obj = NULL; enchant_dict_handlers.compare = zend_objects_not_comparable; @@ -264,9 +262,7 @@ PHP_FUNCTION(enchant_broker_init) enchant_broker *broker; EnchantBroker *pbroker; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); pbroker = enchant_broker_init(); if (pbroker) { @@ -348,12 +344,10 @@ PHP_FUNCTION(enchant_broker_set_dict_path) case PHP_ENCHANT_MYSPELL: enchant_broker_set_param(pbroker->pbroker, "enchant.myspell.dictionary.path", value); RETURN_TRUE; - break; case PHP_ENCHANT_ISPELL: enchant_broker_set_param(pbroker->pbroker, "enchant.ispell.dictionary.path", value); RETURN_TRUE; - break; default: RETURN_FALSE; @@ -671,17 +665,18 @@ PHP_FUNCTION(enchant_dict_suggest) } PHP_ENCHANT_GET_DICT; - array_init(return_value); suggs = enchant_dict_suggest(pdict->pdict, word, wordlen, &n_sugg); if (suggs && n_sugg) { - size_t i; + array_init_size(return_value, n_sugg); - for (i = 0; i < n_sugg; i++) { + for (size_t i = 0; i < n_sugg; i++) { add_next_index_string(return_value, suggs[i]); } enchant_dict_free_string_list(pdict->pdict, suggs); + } else { + RETURN_EMPTY_ARRAY(); } } /* }}} */ diff --git a/ext/enchant/enchant.stub.php b/ext/enchant/enchant.stub.php index eafce22eac7d..6ddbee768f14 100644 --- a/ext/enchant/enchant.stub.php +++ b/ext/enchant/enchant.stub.php @@ -5,14 +5,14 @@ /** * @var int * @cvalue PHP_ENCHANT_MYSPELL - * @deprecated */ +#[\Deprecated(since: '8.0', message: 'as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated')] const ENCHANT_MYSPELL = UNKNOWN; /** * @var int * @cvalue PHP_ENCHANT_ISPELL - * @deprecated */ +#[\Deprecated(since: '8.0', message: 'as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated')] const ENCHANT_ISPELL = UNKNOWN; #ifdef HAVE_ENCHANT_GET_VERSION /** diff --git a/ext/enchant/enchant_arginfo.h b/ext/enchant/enchant_arginfo.h index a06f713f9ced..39e7e577bf9a 100644 --- a/ext/enchant/enchant_arginfo.h +++ b/ext/enchant/enchant_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9dd3fce23840ced1c265f8ec1dd3929298fdfe37 */ +/* This is a generated file, edit enchant.stub.php instead. + * Stub hash: 31974eb901477da53ede7476953d461d32f772ba */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_enchant_broker_init, 0, 0, EnchantBroker, MAY_BE_FALSE) ZEND_END_ARG_INFO() @@ -156,74 +156,61 @@ static const zend_function_entry ext_functions[] = { static void register_enchant_symbols(int module_number) { - REGISTER_LONG_CONSTANT("ENCHANT_MYSPELL", PHP_ENCHANT_MYSPELL, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("ENCHANT_ISPELL", PHP_ENCHANT_ISPELL, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_ENCHANT_MYSPELL = REGISTER_LONG_CONSTANT("ENCHANT_MYSPELL", PHP_ENCHANT_MYSPELL, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_ENCHANT_ISPELL = REGISTER_LONG_CONSTANT("ENCHANT_ISPELL", PHP_ENCHANT_ISPELL, CONST_PERSISTENT | CONST_DEPRECATED); #if defined(HAVE_ENCHANT_GET_VERSION) REGISTER_STRING_CONSTANT("LIBENCHANT_VERSION", PHP_ENCHANT_GET_VERSION, CONST_PERSISTENT); #endif zend_attribute *attribute_Deprecated_func_enchant_broker_free_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_broker_free", sizeof("enchant_broker_free") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_enchant_broker_free_0_arg0; - zend_string *attribute_Deprecated_func_enchant_broker_free_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_0_arg0, attribute_Deprecated_func_enchant_broker_free_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_free_0->args[0].value, &attribute_Deprecated_func_enchant_broker_free_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_broker_free_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_broker_free_0_arg1; zend_string *attribute_Deprecated_func_enchant_broker_free_0_arg1_str = zend_string_init("as EnchantBroker objects are freed automatically", strlen("as EnchantBroker objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_0_arg1, attribute_Deprecated_func_enchant_broker_free_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_free_0->args[1].value, &attribute_Deprecated_func_enchant_broker_free_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_0->args[1].value, attribute_Deprecated_func_enchant_broker_free_0_arg1_str); attribute_Deprecated_func_enchant_broker_free_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_enchant_broker_set_dict_path_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_broker_set_dict_path", sizeof("enchant_broker_set_dict_path") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_enchant_broker_set_dict_path_0_arg0; - zend_string *attribute_Deprecated_func_enchant_broker_set_dict_path_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_set_dict_path_0_arg0, attribute_Deprecated_func_enchant_broker_set_dict_path_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_set_dict_path_0->args[0].value, &attribute_Deprecated_func_enchant_broker_set_dict_path_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_set_dict_path_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_broker_set_dict_path_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_enchant_broker_get_dict_path_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_broker_get_dict_path", sizeof("enchant_broker_get_dict_path") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_enchant_broker_get_dict_path_0_arg0; - zend_string *attribute_Deprecated_func_enchant_broker_get_dict_path_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_get_dict_path_0_arg0, attribute_Deprecated_func_enchant_broker_get_dict_path_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_get_dict_path_0->args[0].value, &attribute_Deprecated_func_enchant_broker_get_dict_path_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_get_dict_path_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_broker_get_dict_path_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_enchant_broker_free_dict_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_broker_free_dict", sizeof("enchant_broker_free_dict") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_enchant_broker_free_dict_0_arg0; - zend_string *attribute_Deprecated_func_enchant_broker_free_dict_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_dict_0_arg0, attribute_Deprecated_func_enchant_broker_free_dict_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_free_dict_0->args[0].value, &attribute_Deprecated_func_enchant_broker_free_dict_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_dict_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_broker_free_dict_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_broker_free_dict_0_arg1; zend_string *attribute_Deprecated_func_enchant_broker_free_dict_0_arg1_str = zend_string_init("as EnchantDictionary objects are freed automatically", strlen("as EnchantDictionary objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_dict_0_arg1, attribute_Deprecated_func_enchant_broker_free_dict_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_broker_free_dict_0->args[1].value, &attribute_Deprecated_func_enchant_broker_free_dict_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_broker_free_dict_0->args[1].value, attribute_Deprecated_func_enchant_broker_free_dict_0_arg1_str); attribute_Deprecated_func_enchant_broker_free_dict_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_enchant_dict_add_to_personal_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_dict_add_to_personal", sizeof("enchant_dict_add_to_personal") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg0; - zend_string *attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg0, attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[0].value, &attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1; zend_string *attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1_str = zend_string_init("use enchant_dict_add() instead", strlen("use enchant_dict_add() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1, attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[1].value, &attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[1].value, attribute_Deprecated_func_enchant_dict_add_to_personal_0_arg1_str); attribute_Deprecated_func_enchant_dict_add_to_personal_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_enchant_dict_is_in_session_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "enchant_dict_is_in_session", sizeof("enchant_dict_is_in_session") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_enchant_dict_is_in_session_0_arg0; - zend_string *attribute_Deprecated_func_enchant_dict_is_in_session_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_dict_is_in_session_0_arg0, attribute_Deprecated_func_enchant_dict_is_in_session_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_dict_is_in_session_0->args[0].value, &attribute_Deprecated_func_enchant_dict_is_in_session_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_enchant_dict_is_in_session_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_enchant_dict_is_in_session_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1; zend_string *attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1_str = zend_string_init("use enchant_dict_is_added() instead", strlen("use enchant_dict_is_added() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1, attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_enchant_dict_is_in_session_0->args[1].value, &attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_enchant_dict_is_in_session_0->args[1].value, attribute_Deprecated_func_enchant_dict_is_in_session_0_arg1_str); attribute_Deprecated_func_enchant_dict_is_in_session_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_ENCHANT_MYSPELL_0 = zend_add_global_constant_attribute(const_ENCHANT_MYSPELL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); + attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1_str = zend_string_init("as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated", strlen("as enchant_broker_get_dict_path() and enchant_broker_set_dict_path() are deprecated"), 1); + ZVAL_STR(&attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[1].value, attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1_str); + attribute_Deprecated_const_ENCHANT_MYSPELL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_ENCHANT_ISPELL_0 = zend_add_global_constant_attribute(const_ENCHANT_ISPELL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_ENCHANT_ISPELL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); + attribute_Deprecated_const_ENCHANT_ISPELL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_ENCHANT_ISPELL_0->args[1].value, attribute_Deprecated_const_ENCHANT_MYSPELL_0_arg1_str); + attribute_Deprecated_const_ENCHANT_ISPELL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_EnchantBroker(void) diff --git a/ext/enchant/php_enchant.h b/ext/enchant/php_enchant.h index 81150648d119..d87b2b6550ad 100644 --- a/ext/enchant/php_enchant.h +++ b/ext/enchant/php_enchant.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre-Alain Joye | +----------------------------------------------------------------------+ diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 916986172886..91be074a0be3 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | @@ -1290,6 +1288,18 @@ typedef struct { mn_offset_mode_t offset_mode; } maker_note_type; +#define FOURCC(id) (((uint32_t)(id[0])<<24) | (id[1]<<16) | (id[2]<<8) | (id[3])) + +typedef struct { + uint64_t size; + uint32_t type; +} isobmff_box_type; + +typedef struct { + uint32_t offset; + uint32_t size; +} isobmff_item_pos_type; + /* Some maker notes (e.g. DJI info tag) require custom parsing */ #define REQUIRES_CUSTOM_PARSING NULL @@ -2092,7 +2102,7 @@ static inline char *exif_offset_info_try_get( static inline bool exif_offset_info_contains( const exif_offset_info *info, const char *start, size_t length) { if (ptr_offset_overflows(start, length)) { - return 0; + return false; } /* start and valid_start are both inclusive, end and valid_end are both exclusive, @@ -3249,6 +3259,7 @@ static bool exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * val #define REQUIRE_NON_EMPTY() do { \ if (byte_count == 0) { \ + EFREE_IF(outside); \ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Cannot be empty", tag, exif_get_tagname_debug(tag, tag_table)); \ return false; \ } \ @@ -4013,7 +4024,6 @@ static bool exif_scan_thumbnail(image_info_type *ImageInfo) case M_EOI: exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Could not compute size of thumbnail"); return false; - break; default: /* just skip */ @@ -4279,11 +4289,167 @@ static bool exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offs return result; } +/* Returns the size of the header, which must be smaller than the size of the box. */ +static int exif_isobmff_parse_box(unsigned char *buf, isobmff_box_type *box) +{ + box->size = php_ifd_get32u(buf, 1); + buf += 4; + box->type = php_ifd_get32u(buf, 1); + if (box->size != 1) { + return 8; + } + buf += 4; + box->size = php_ifd_get64u(buf, 1); + return 16; +} + +static void exif_isobmff_parse_meta(unsigned char *data, unsigned char *end, isobmff_item_pos_type *pos) +{ + isobmff_box_type box, item; + unsigned char *p; + int header_size, exif_id = -1, version, item_count, i; + + size_t remain; +#define CHECK(n) do { \ + if (remain < (n)) { \ + return; \ + } \ +} while (0) +#define ADVANCE(n) do { \ + CHECK(n); \ + remain -= (n); \ + p += (n); \ +} while (0) + + unsigned char *box_offset = data + 4; + while (box_offset < end - 16) { + header_size = exif_isobmff_parse_box(box_offset, &box); + if (box.size < header_size) { + return; + } + p = box_offset; + remain = end - p; + + if (box.type == FOURCC("iinf")) { + ADVANCE(header_size + 4); + version = p[-4]; + if (version < 2) { + ADVANCE(2); + item_count = php_ifd_get16u(p - 2, 1); + } else { + ADVANCE(4); + item_count = php_ifd_get32u(p - 4, 1); + } + for (i = 0; i < item_count && p < end - 20; i++) { + header_size = exif_isobmff_parse_box(p, &item); + if (item.size < header_size) { + return; + } + CHECK(header_size + 12); + if (!memcmp(p + header_size + 8, "Exif", 4)) { + exif_id = php_ifd_get16u(p + header_size + 4, 1); + break; + } + ADVANCE(item.size); + } + if (exif_id < 0) { + break; + } + } + else if (box.type == FOURCC("iloc")) { + ADVANCE(header_size + 6); + version = p[-6]; + if (version < 2) { + ADVANCE(2); + item_count = php_ifd_get16u(p - 2, 1); + } else { + ADVANCE(4); + item_count = php_ifd_get32u(p - 4, 1); + } + for (i = 0; i < item_count && p < end - 16; i++, p += 16) { + if (php_ifd_get16u(p, 1) == exif_id) { + pos->offset = php_ifd_get32u(p + 8, 1); + pos->size = php_ifd_get32u(p + 12, 1); + break; + } + } + break; + } + + if (end - 16 - box_offset <= box.size) { + break; + } + box_offset += box.size; + } + +#undef ADVANCE +#undef CHECK +} + +static bool exif_scan_HEIF_header(image_info_type *ImageInfo, unsigned char *buf) +{ + isobmff_box_type box; + isobmff_item_pos_type pos; + unsigned char *data; + uint64_t limit; + int box_header_size, remain; + bool ret = false; + + for (size_t offset = php_ifd_get32u(buf, 1); ImageInfo->FileSize - 16 > offset; offset += box.size) { + if ((php_stream_seek(ImageInfo->infile, offset, SEEK_SET) < 0) || + (exif_read_from_stream_file_looped(ImageInfo->infile, (char*)buf, 16) != 16)) { + break; + } + box_header_size = exif_isobmff_parse_box(buf, &box); + if (box.size < box_header_size) { + break; + } + if (box.type == FOURCC("meta")) { + limit = box.size - box_header_size; + if (limit < 36) { + break; + } + data = (unsigned char *)emalloc(limit); + remain = 16 - box_header_size; + if (remain) { + memcpy(data, buf + box_header_size, remain); + } + memset(&pos, 0, sizeof(pos)); + if (exif_read_from_stream_file_looped(ImageInfo->infile, (char*)(data + remain), limit - remain) == limit - remain) { + exif_isobmff_parse_meta(data, data + limit, &pos); + } + if ((pos.size >= 2) && + (pos.size < ImageInfo->FileSize) && + (ImageInfo->FileSize - pos.size >= pos.offset) && + (php_stream_seek(ImageInfo->infile, pos.offset + 2, SEEK_SET) >= 0)) { + if (limit >= pos.size - 2) { + limit = pos.size - 2; + } else { + limit = pos.size - 2; + efree(data); + data = (unsigned char *)emalloc(limit); + } + if (exif_read_from_stream_file_looped(ImageInfo->infile, (char*)data, limit) == limit) { + exif_process_APP1(ImageInfo, (char*)data, limit, pos.offset + 2); + ret = true; + } + } + efree(data); + break; + } + if (offset + box.size < offset) { + break; + } + } + + return ret; +} + /* {{{ exif_scan_FILE_header * Parse the marker stream until SOS or EOI is seen; */ static bool exif_scan_FILE_header(image_info_type *ImageInfo) { - unsigned char file_header[8]; + unsigned char file_header[16]; ImageInfo->FileType = IMAGE_FILETYPE_UNKNOWN; @@ -4344,6 +4510,17 @@ static bool exif_scan_FILE_header(image_info_type *ImageInfo) exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid TIFF file"); return false; } + } else if ((ImageInfo->FileSize > 16) && + (!memcmp(file_header + 4, "ftyp", 4)) && + (exif_read_from_stream_file_looped(ImageInfo->infile, (char*)(file_header + 8), 4) == 4) && + ((!memcmp(file_header + 8, "heic", 4)) || (!memcmp(file_header + 8, "heix", 4)) || (!memcmp(file_header + 8, "mif1", 4)))) { + if (exif_scan_HEIF_header(ImageInfo, file_header)) { + ImageInfo->FileType = IMAGE_FILETYPE_HEIF; + return true; + } else { + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid HEIF file"); + return false; + } } else { exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "File not supported"); return false; diff --git a/ext/exif/exif_arginfo.h b/ext/exif/exif_arginfo.h index c9e42b9a4770..4821fd7fbafd 100644 --- a/ext/exif/exif_arginfo.h +++ b/ext/exif/exif_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit exif.stub.php instead. * Stub hash: 633b2db018fa1453845a854a6361f11f107f4653 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_exif_tagname, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) diff --git a/ext/exif/php_exif.h b/ext/exif/php_exif.h index 4ae5894f9036..5a4d2ec4d2a5 100644 --- a/ext/exif/php_exif.h +++ b/ext/exif/php_exif.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | diff --git a/ext/exif/tests/exif029.phpt b/ext/exif/tests/exif029.phpt new file mode 100644 index 000000000000..f2eadbfe5d2a --- /dev/null +++ b/ext/exif/tests/exif029.phpt @@ -0,0 +1,145 @@ +--TEST-- +Check for exif_read_data, HEIF with IFD0 and EXIF data in Motorola byte-order. +--EXTENSIONS-- +exif +--INI-- +output_handler= +zlib.output_compression=0 +--FILE-- + +--EXPECTF-- +array(53) { + ["FileName"]=> + string(13) "image029.heic" + ["FileDateTime"]=> + int(%d) + ["FileSize"]=> + int(42199) + ["FileType"]=> + int(20) + ["MimeType"]=> + string(10) "image/heif" + ["SectionsFound"]=> + string(19) "ANY_TAG, IFD0, EXIF" + ["COMPUTED"]=> + array(3) { + ["IsColor"]=> + int(0) + ["ByteOrderMotorola"]=> + int(1) + ["ApertureFNumber"]=> + string(5) "f/1.8" + } + ["Make"]=> + string(5) "Apple" + ["Model"]=> + string(26) "iPhone SE (3rd generation)" + ["Orientation"]=> + int(1) + ["XResolution"]=> + string(4) "72/1" + ["YResolution"]=> + string(4) "72/1" + ["ResolutionUnit"]=> + int(2) + ["Software"]=> + string(6) "17.2.1" + ["DateTime"]=> + string(19) "2024:02:21 16:03:50" + ["HostComputer"]=> + string(26) "iPhone SE (3rd generation)" + ["TileWidth"]=> + int(512) + ["TileLength"]=> + int(512) + ["Exif_IFD_Pointer"]=> + int(264) + ["ExposureTime"]=> + string(4) "1/60" + ["FNumber"]=> + string(3) "9/5" + ["ExposureProgram"]=> + int(2) + ["ISOSpeedRatings"]=> + int(200) + ["ExifVersion"]=> + string(4) "0232" + ["DateTimeOriginal"]=> + string(19) "2024:02:21 16:03:50" + ["DateTimeDigitized"]=> + string(19) "2024:02:21 16:03:50" + ["OffsetTime"]=> + string(6) "+08:00" + ["OffsetTimeOriginal"]=> + string(6) "+08:00" + ["OffsetTimeDigitized"]=> + string(6) "+08:00" + ["ShutterSpeedValue"]=> + string(12) "159921/27040" + ["ApertureValue"]=> + string(11) "54823/32325" + ["BrightnessValue"]=> + string(11) "29968/13467" + ["ExposureBiasValue"]=> + string(3) "0/1" + ["MeteringMode"]=> + int(5) + ["Flash"]=> + int(16) + ["FocalLength"]=> + string(7) "399/100" + ["SubjectLocation"]=> + array(4) { + [0]=> + int(1995) + [1]=> + int(1507) + [2]=> + int(2217) + [3]=> + int(1332) + } + ["MakerNote"]=> + string(9) "Apple iOS" + ["SubSecTimeOriginal"]=> + string(3) "598" + ["SubSecTimeDigitized"]=> + string(3) "598" + ["ColorSpace"]=> + int(65535) + ["ExifImageWidth"]=> + int(4032) + ["ExifImageLength"]=> + int(3024) + ["SensingMethod"]=> + int(2) + ["SceneType"]=> + string(1) "" + ["ExposureMode"]=> + int(0) + ["WhiteBalance"]=> + int(0) + ["DigitalZoomRatio"]=> + string(7) "756/151" + ["FocalLengthIn35mmFilm"]=> + int(140) + ["UndefinedTag:0xA432"]=> + array(4) { + [0]=> + string(15) "4183519/1048501" + [1]=> + string(15) "4183519/1048501" + [2]=> + string(3) "9/5" + [3]=> + string(3) "9/5" + } + ["UndefinedTag:0xA433"]=> + string(5) "Apple" + ["UndefinedTag:0xA434"]=> + string(51) "iPhone SE (3rd generation) back camera 3.99mm f/1.8" + ["UndefinedTag:0xA460"]=> + int(2) +} diff --git a/ext/exif/tests/heic_box_overflow.phpt b/ext/exif/tests/heic_box_overflow.phpt new file mode 100644 index 000000000000..b3a5e42df91f --- /dev/null +++ b/ext/exif/tests/heic_box_overflow.phpt @@ -0,0 +1,27 @@ +--TEST-- +HEIC box overflow +--EXTENSIONS-- +exif +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Warning: exif_read_data(heic_box_overflow): Invalid HEIF file in %s on line %d +bool(false) diff --git a/ext/exif/tests/heic_iloc_underflow.phpt b/ext/exif/tests/heic_iloc_underflow.phpt new file mode 100644 index 000000000000..9dd1878b60dd --- /dev/null +++ b/ext/exif/tests/heic_iloc_underflow.phpt @@ -0,0 +1,19 @@ +--TEST-- +HEIC iloc extent_length underflow +--EXTENSIONS-- +exif +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Warning: exif_read_data(heic_iloc_underflow.heic): Invalid HEIF file in %s on line %d +bool(false) diff --git a/ext/exif/tests/image029.heic b/ext/exif/tests/image029.heic new file mode 100644 index 000000000000..99f8186d0723 Binary files /dev/null and b/ext/exif/tests/image029.heic differ diff --git a/ext/exif/tests/oss_fuzz_442954659/input b/ext/exif/tests/oss_fuzz_442954659/input new file mode 100644 index 000000000000..5049d7e79d10 Binary files /dev/null and b/ext/exif/tests/oss_fuzz_442954659/input differ diff --git a/ext/exif/tests/oss_fuzz_442954659/oss_fuzz_442954659.phpt b/ext/exif/tests/oss_fuzz_442954659/oss_fuzz_442954659.phpt new file mode 100644 index 000000000000..131b2c5be980 --- /dev/null +++ b/ext/exif/tests/oss_fuzz_442954659/oss_fuzz_442954659.phpt @@ -0,0 +1,10 @@ +--TEST-- +OSS-Fuzz #442954659 (zero-size box in HEIF file causes infinite loop) +--EXTENSIONS-- +exif +--FILE-- + +--EXPECTF-- +Warning: exif_read_data(%s): Invalid HEIF file in %s on line %d diff --git a/ext/exif/tests/oss_fuzz_444479893/input b/ext/exif/tests/oss_fuzz_444479893/input new file mode 100644 index 000000000000..91e083c9c627 Binary files /dev/null and b/ext/exif/tests/oss_fuzz_444479893/input differ diff --git a/ext/exif/tests/oss_fuzz_444479893/oss_fuzz_444479893.phpt b/ext/exif/tests/oss_fuzz_444479893/oss_fuzz_444479893.phpt new file mode 100644 index 000000000000..b03635400f0a --- /dev/null +++ b/ext/exif/tests/oss_fuzz_444479893/oss_fuzz_444479893.phpt @@ -0,0 +1,10 @@ +--TEST-- +OSS-Fuzz #442954659 (Crash in exif_scan_HEIF_header) +--EXTENSIONS-- +exif +--FILE-- + +--EXPECTF-- +Warning: exif_read_data(%s): Invalid HEIF file in %s on line %d diff --git a/ext/ext_skel.php b/ext/ext_skel.php index cd82abb34697..3237ca625c99 100755 --- a/ext/ext_skel.php +++ b/ext/ext_skel.php @@ -2,15 +2,13 @@ . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kalle Sommer Nielsen | +----------------------------------------------------------------------+ @@ -42,7 +40,7 @@ function print_help() { Very simple. First, change to the ext/ directory of the PHP sources. Then run the following - php ext_skel.php --ext extension_name + php ext_skel.php --ext extension_name --vendor vendor_name and everything you need will be placed in directory ext/extension_name. @@ -90,11 +88,12 @@ functions strictly needed by others. Exposed internal function must be named OPTIONS - php ext_skel.php --ext [--experimental] [--author ] - [--dir ] [--std] [--onlyunix] - [--onlywindows] [--help] + php ext_skel.php --ext --vendor [--experimental] + [--author ] [--dir ] [--std] + [--onlyunix] [--onlywindows] [--help] --ext The name of the extension defined as + --vendor The vendor of the extension for Packagist --experimental Passed if this extension is experimental, this creates the EXPERIMENTAL file in the root of the extension --author Your name, this is used if --std is passed and for the @@ -147,6 +146,7 @@ function process_args($argv, $argc) { 'unix' => true, 'windows' => true, 'ext' => '', + 'vendor' => '', 'dir' => __DIR__ . DIRECTORY_SEPARATOR, 'skel' => __DIR__ . DIRECTORY_SEPARATOR . 'skeleton' . DIRECTORY_SEPARATOR, 'author' => false, @@ -185,6 +185,7 @@ function process_args($argv, $argc) { } break; case 'ext': + case 'vendor': case 'dir': case 'author': { if (!isset($argv[$i + 1]) || ($argv[$i + 1][0] == '-' && $argv[$i + 1][1] == '-')) { @@ -204,6 +205,8 @@ function process_args($argv, $argc) { if (empty($options['ext'])) { error('No extension name passed, use "--ext "'); + } else if (empty($options['vendor'])) { + error('No vendor name passed, use "--vendor "'); } else if (!$options['unix'] && !$options['windows']) { error('Cannot pass both --onlyunix and --onlywindows'); } else if (!is_dir($options['skel'])) { @@ -217,6 +220,12 @@ function process_args($argv, $argc) { .' Using only lower case letters is preferred.'); } + // Validate vendor + if (!preg_match('/^[a-z][a-z0-9_-]+$/i', $options['vendor'])) { + error('Invalid vendor name. Valid names start with a letter,' + .' followed by any number of letters, numbers, hypens, or underscores.'); + } + $options['ext'] = str_replace(['\\', '/'], '', strtolower($options['ext'])); return $options; @@ -231,6 +240,7 @@ function process_source_tags($file, $short_name) { error('Unable to open file for reading: ' . $short_name); } + $source = str_replace('%VENDORNAME%', $options['vendor'], $source); $source = str_replace('%EXTNAME%', $options['ext'], $source); $source = str_replace('%EXTNAMECAPS%', strtoupper($options['ext']), $source); @@ -245,15 +255,13 @@ function process_source_tags($file, $short_name) { $header = <<<"HEADER" /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: $credits | +----------------------------------------------------------------------+ @@ -290,6 +298,7 @@ function copy_config_scripts() { } $files[] = '.gitignore'; + $files[] = 'composer.json'; foreach($files as $config_script) { $new_config_script = $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $config_script; diff --git a/ext/ffi/config.w32 b/ext/ffi/config.w32 index cfe54706a871..c3d3e7289189 100644 --- a/ext/ffi/config.w32 +++ b/ext/ffi/config.w32 @@ -1,7 +1,7 @@ ARG_WITH('ffi', 'ffi support', 'no'); if (PHP_FFI != 'no') { - if (CHECK_HEADER_ADD_INCLUDE("ffi.h", "CFLAGS_FFI", PHP_FFI+ ";" + PHP_PHP_BUILD + "\\include") && + if (CHECK_HEADER("ffi.h", "CFLAGS_FFI", PHP_FFI+ ";" + PHP_PHP_BUILD + "\\include") && CHECK_LIB("libffi.lib", "ffi", PHP_FFI)) { AC_DEFINE('HAVE_FFI', 1, "Define to 1 if the PHP extension 'ffi' is available."); diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 10fc11f52e70..779b41fcad3d 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -950,6 +948,7 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v fci.object = NULL; fci.param_count = callback_data->arg_count; fci.named_params = NULL; + fci.consumed_args = 0; if (callback_data->type->func.args) { int n = 0; @@ -957,7 +956,8 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v ZEND_HASH_PACKED_FOREACH_PTR(callback_data->type->func.args, arg_type) { arg_type = ZEND_FFI_TYPE(arg_type); - zend_ffi_cdata_to_zval(NULL, args[n], arg_type, BP_VAR_R, &fci.params[n], (zend_ffi_flags)(arg_type->attr & ZEND_FFI_ATTR_CONST), 0, 0); + zend_ffi_cdata_to_zval(NULL, args[n], arg_type, BP_VAR_R, &fci.params[n], (zend_ffi_flags)(arg_type->attr & ZEND_FFI_ATTR_CONST), + false, false); n++; } ZEND_HASH_FOREACH_END(); } @@ -1133,7 +1133,7 @@ static zval *zend_ffi_cdata_get(zend_object *obj, zend_string *member, int read_ return &EG(uninitialized_zval); } - zend_ffi_cdata_to_zval(cdata, cdata->ptr, type, BP_VAR_R, rv, 0, 0, 0); + zend_ffi_cdata_to_zval(cdata, cdata->ptr, type, BP_VAR_R, rv, 0, false, false); return rv; } /* }}} */ @@ -1252,10 +1252,8 @@ static zval *zend_ffi_cdata_read_field(zend_object *obj, zend_string *field_name type = ZEND_FFI_TYPE(type->pointer.type); } if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - zend_throw_error(zend_ffi_exception_ce, "Attempt to read field '%s' of non C struct/union", ZSTR_VAL(field_name)); - return &EG(uninitialized_zval); - } + zend_throw_error(zend_ffi_exception_ce, "Attempt to read field '%s' of non C struct/union", ZSTR_VAL(field_name)); + return &EG(uninitialized_zval); } field = zend_hash_find_ptr(&type->record.fields, field_name); @@ -1302,7 +1300,8 @@ static zval *zend_ffi_cdata_read_field(zend_object *obj, zend_string *field_name } } ptr = (void*)(((char*)ptr) + field->offset); - zend_ffi_cdata_to_zval(NULL, ptr, field_type, read_type, rv, (cdata->flags & ZEND_FFI_FLAG_CONST) | (zend_ffi_flags)field->is_const, 0, 0); + zend_ffi_cdata_to_zval(NULL, ptr, field_type, read_type, rv, (cdata->flags & ZEND_FFI_FLAG_CONST) | (zend_ffi_flags)field->is_const, + false, false); } else { zend_ffi_bit_field_to_zval(ptr, field, rv); } @@ -1329,10 +1328,8 @@ static zval *zend_ffi_cdata_write_field(zend_object *obj, zend_string *field_nam type = ZEND_FFI_TYPE(type->pointer.type); } if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - if (UNEXPECTED(type->kind != ZEND_FFI_TYPE_STRUCT)) { - zend_throw_error(zend_ffi_exception_ce, "Attempt to assign field '%s' of non C struct/union", ZSTR_VAL(field_name)); - return value; - } + zend_throw_error(zend_ffi_exception_ce, "Attempt to assign field '%s' of non C struct/union", ZSTR_VAL(field_name)); + return value; } field = zend_hash_find_ptr(&type->record.fields, field_name); @@ -1438,7 +1435,7 @@ static zval *zend_ffi_cdata_read_dim(zend_object *obj, zval *offset, int read_ty return &EG(uninitialized_zval); } - zend_ffi_cdata_to_zval(NULL, ptr, dim_type, read_type, rv, is_const, 0, 0); + zend_ffi_cdata_to_zval(NULL, ptr, dim_type, read_type, rv, is_const, false, false); return rv; } /* }}} */ @@ -1527,7 +1524,7 @@ static bool zend_ffi_ctype_name_append(zend_ffi_ctype_name_buf *buf, const char static bool zend_ffi_ctype_name(zend_ffi_ctype_name_buf *buf, const zend_ffi_type *type) /* {{{ */ { const char *name = NULL; - bool is_ptr = 0; + bool is_ptr = false; while (1) { switch (type->kind) { @@ -1587,12 +1584,12 @@ static bool zend_ffi_ctype_name(zend_ffi_ctype_name_buf *buf, const zend_ffi_typ if (!zend_ffi_ctype_name_prepend(buf, "*", 1)) { return 0; } - is_ptr = 1; + is_ptr = true; type = ZEND_FFI_TYPE(type->pointer.type); break; case ZEND_FFI_TYPE_FUNC: if (is_ptr) { - is_ptr = 0; + is_ptr = false; if (!zend_ffi_ctype_name_prepend(buf, "(", 1) || !zend_ffi_ctype_name_append(buf, ")", 1)) { return 0; @@ -1606,7 +1603,7 @@ static bool zend_ffi_ctype_name(zend_ffi_ctype_name_buf *buf, const zend_ffi_typ break; case ZEND_FFI_TYPE_ARRAY: if (is_ptr) { - is_ptr = 0; + is_ptr = false; if (!zend_ffi_ctype_name_prepend(buf, "(", 1) || !zend_ffi_ctype_name_append(buf, ")", 1)) { return 0; @@ -1984,7 +1981,8 @@ static zval *zend_ffi_cdata_it_get_current_data(zend_object_iterator *it) /* {{{ ptr = (void*)((char*)cdata->ptr + dim_type->size * iter->it.index); zval_ptr_dtor(&iter->value); - zend_ffi_cdata_to_zval(NULL, ptr, dim_type, iter->by_ref ? BP_VAR_RW : BP_VAR_R, &iter->value, (cdata->flags & ZEND_FFI_FLAG_CONST) | (zend_ffi_flags)(type->attr & ZEND_FFI_ATTR_CONST), 0, 0); + zend_ffi_cdata_to_zval(NULL, ptr, dim_type, iter->by_ref ? BP_VAR_RW : BP_VAR_R, &iter->value, (cdata->flags & ZEND_FFI_FLAG_CONST) | (zend_ffi_flags)(type->attr & ZEND_FFI_ATTR_CONST), + false, false); return &iter->value; } /* }}} */ @@ -2082,12 +2080,11 @@ static HashTable *zend_ffi_cdata_get_debug_info(zend_object *obj, int *is_temp) case ZEND_FFI_TYPE_SINT32: case ZEND_FFI_TYPE_UINT64: case ZEND_FFI_TYPE_SINT64: - zend_ffi_cdata_to_zval(cdata, ptr, type, BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, 0, 0); + zend_ffi_cdata_to_zval(cdata, ptr, type, BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, false, false); ht = zend_new_array(1); zend_hash_str_add(ht, "cdata", sizeof("cdata")-1, &tmp); *is_temp = 1; return ht; - break; case ZEND_FFI_TYPE_POINTER: if (*(void**)ptr == NULL) { ZVAL_NULL(&tmp); @@ -2102,7 +2099,8 @@ static HashTable *zend_ffi_cdata_get_debug_info(zend_object *obj, int *is_temp) *is_temp = 1; return ht; } else { - zend_ffi_cdata_to_zval(NULL, *(void**)ptr, ZEND_FFI_TYPE(type->pointer.type), BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, 0, 0); + zend_ffi_cdata_to_zval(NULL, *(void**)ptr, ZEND_FFI_TYPE(type->pointer.type), BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, + false, false); ht = zend_new_array(1); zend_hash_index_add_new(ht, 0, &tmp); *is_temp = 1; @@ -2115,7 +2113,8 @@ static HashTable *zend_ffi_cdata_get_debug_info(zend_object *obj, int *is_temp) if (key) { if (!f->bits) { void *f_ptr = (void*)(((char*)ptr) + f->offset); - zend_ffi_cdata_to_zval(NULL, f_ptr, ZEND_FFI_TYPE(f->type), BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, 0, type->attr & ZEND_FFI_ATTR_UNION); + zend_ffi_cdata_to_zval(NULL, f_ptr, ZEND_FFI_TYPE(f->type), BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, + false, type->attr & ZEND_FFI_ATTR_UNION); zend_hash_add(ht, key, &tmp); } else { zend_ffi_bit_field_to_zval(ptr, f, &tmp); @@ -2128,7 +2127,8 @@ static HashTable *zend_ffi_cdata_get_debug_info(zend_object *obj, int *is_temp) case ZEND_FFI_TYPE_ARRAY: ht = zend_new_array(type->array.length); for (n = 0; n < type->array.length; n++) { - zend_ffi_cdata_to_zval(NULL, ptr, ZEND_FFI_TYPE(type->array.type), BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, 0, 0); + zend_ffi_cdata_to_zval(NULL, ptr, ZEND_FFI_TYPE(type->array.type), BP_VAR_R, &tmp, ZEND_FFI_FLAG_CONST, + false, false); zend_hash_index_add(ht, n, &tmp); ptr = (void*)(((char*)ptr) + ZEND_FFI_TYPE(type->array.type)->size); } @@ -2139,7 +2139,6 @@ static HashTable *zend_ffi_cdata_get_debug_info(zend_object *obj, int *is_temp) // TODO: function name ??? *is_temp = 1; return ht; - break; default: ZEND_UNREACHABLE(); break; @@ -2184,6 +2183,7 @@ static zend_result zend_ffi_cdata_get_closure(zend_object *obj, zend_class_entry func->common.arg_flags[1] = 0; func->common.arg_flags[2] = 0; func->common.fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE; + func->common.fn_flags2 = 0; func->common.function_name = ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE); /* set to 0 to avoid arg_info[] allocation, because all values are passed by value anyway */ func->common.num_args = 0; @@ -2307,7 +2307,7 @@ static zend_object *zend_ffi_new(zend_class_entry *class_type) /* {{{ */ ffi->lib = NULL; ffi->symbols = NULL; ffi->tags = NULL; - ffi->persistent = 0; + ffi->persistent = false; return &ffi->std; } @@ -2509,7 +2509,8 @@ static zval *zend_ffi_read_var(zend_object *obj, zend_string *var_name, int read } if (sym->kind == ZEND_FFI_SYM_VAR) { - zend_ffi_cdata_to_zval(NULL, sym->addr, ZEND_FFI_TYPE(sym->type), read_type, rv, (zend_ffi_flags)sym->is_const, 0, 0); + zend_ffi_cdata_to_zval(NULL, sym->addr, ZEND_FFI_TYPE(sym->type), read_type, rv, (zend_ffi_flags)sym->is_const, + false, false); } else if (sym->kind == ZEND_FFI_SYM_FUNC) { zend_ffi_cdata *cdata; zend_ffi_type *new_type = emalloc(sizeof(zend_ffi_type)); @@ -2962,6 +2963,7 @@ static zend_function *zend_ffi_get_func(zend_object **obj, zend_string *name, co func->common.arg_flags[1] = 0; func->common.arg_flags[2] = 0; func->common.fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE; + func->common.fn_flags2 = 0; func->common.function_name = zend_string_copy(name); /* set to 0 to avoid arg_info[] allocation, because all values are passed by value anyway */ func->common.num_args = 0; @@ -3098,17 +3100,7 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ FFI_G(default_type_attr) = ZEND_FFI_ATTR_STORED; if (zend_ffi_parse_decl(ZSTR_VAL(code), ZSTR_LEN(code)) == FAILURE) { - if (FFI_G(symbols)) { - zend_hash_destroy(FFI_G(symbols)); - efree(FFI_G(symbols)); - FFI_G(symbols) = NULL; - } - if (FFI_G(tags)) { - zend_hash_destroy(FFI_G(tags)); - efree(FFI_G(tags)); - FFI_G(tags) = NULL; - } - RETURN_THROWS(); + goto cleanup; } if (FFI_G(symbols)) { @@ -3121,7 +3113,7 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ addr = DL_FETCH_SYMBOL(handle, ZSTR_VAL(name)); if (!addr) { zend_throw_error(zend_ffi_exception_ce, "Failed resolving C variable '%s'", ZSTR_VAL(name)); - RETURN_THROWS(); + goto cleanup; } sym->addr = addr; } else if (sym->kind == ZEND_FFI_SYM_FUNC) { @@ -3131,7 +3123,7 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ zend_string_release(mangled_name); if (!addr) { zend_throw_error(zend_ffi_exception_ce, "Failed resolving C function '%s'", ZSTR_VAL(name)); - RETURN_THROWS(); + goto cleanup; } sym->addr = addr; } @@ -3148,6 +3140,22 @@ ZEND_METHOD(FFI, cdef) /* {{{ */ FFI_G(tags) = NULL; RETURN_OBJ(&ffi->std); + +cleanup: + if (lib && handle) { + DL_UNLOAD(handle); + } + if (FFI_G(symbols)) { + zend_hash_destroy(FFI_G(symbols)); + efree(FFI_G(symbols)); + FFI_G(symbols) = NULL; + } + if (FFI_G(tags)) { + zend_hash_destroy(FFI_G(tags)); + efree(FFI_G(tags)); + FFI_G(tags) = NULL; + } + RETURN_THROWS(); } /* }}} */ @@ -3581,7 +3589,7 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */ } ffi->symbols = scope->symbols; ffi->tags = scope->tags; - ffi->persistent = 1; + ffi->persistent = true; } else { ffi = (zend_ffi*)zend_ffi_new(zend_ffi_ce); ffi->lib = handle; @@ -3764,14 +3772,14 @@ static zend_result zend_ffi_validate_var_type(const zend_ffi_type *type, bool al zend_ffi_throw_parser_error("function type is not allowed at line %d", FFI_G(line)); return FAILURE; } - return zend_ffi_validate_type(type, 0, allow_incomplete_array); + return zend_ffi_validate_type(type, false, allow_incomplete_array); } /* }}} */ void zend_ffi_validate_type_name(zend_ffi_dcl *dcl) /* {{{ */ { zend_ffi_finalize_type(dcl); - if (zend_ffi_validate_var_type(ZEND_FFI_TYPE(dcl->type), 0) == FAILURE) { + if (zend_ffi_validate_var_type(ZEND_FFI_TYPE(dcl->type), false) == FAILURE) { zend_ffi_cleanup_dcl(dcl); LONGJMP(FFI_G(bailout), FAILURE); } @@ -4708,9 +4716,8 @@ ZEND_METHOD(FFI, isNull) /* {{{ */ ZEND_METHOD(FFI_CType, getName) /* {{{ */ { zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + + ZEND_PARSE_PARAMETERS_NONE(); zend_ffi_ctype_name_buf buf; @@ -4730,9 +4737,7 @@ ZEND_METHOD(FFI_CType, getKind) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); RETURN_LONG(type->kind); @@ -4744,9 +4749,7 @@ ZEND_METHOD(FFI_CType, getSize) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); RETURN_LONG(type->size); @@ -4758,9 +4761,7 @@ ZEND_METHOD(FFI_CType, getAlignment) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); RETURN_LONG(type->align); @@ -4772,9 +4773,7 @@ ZEND_METHOD(FFI_CType, getAttributes) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); RETURN_LONG(type->attr); @@ -4786,9 +4785,7 @@ ZEND_METHOD(FFI_CType, getEnumKind) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_ENUM) { @@ -4805,9 +4802,7 @@ ZEND_METHOD(FFI_CType, getArrayElementType) /* {{{ */ zend_ffi_type *type; zend_ffi_ctype *ret; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_ARRAY) { @@ -4826,9 +4821,7 @@ ZEND_METHOD(FFI_CType, getArrayLength) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_ARRAY) { @@ -4845,9 +4838,7 @@ ZEND_METHOD(FFI_CType, getPointerType) /* {{{ */ zend_ffi_ctype *ret; zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_POINTER) { @@ -4869,9 +4860,7 @@ ZEND_METHOD(FFI_CType, getStructFieldNames) /* {{{ */ zend_string* name; zval zv; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_STRUCT) { @@ -4949,9 +4938,7 @@ ZEND_METHOD(FFI_CType, getFuncABI) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_FUNC) { @@ -4968,9 +4955,7 @@ ZEND_METHOD(FFI_CType, getFuncReturnType) /* {{{ */ zend_ffi_ctype *ret; zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_FUNC) { @@ -4989,9 +4974,7 @@ ZEND_METHOD(FFI_CType, getFuncParameterCount) /* {{{ */ const zend_ffi_ctype *ctype = (zend_ffi_ctype*)(Z_OBJ_P(ZEND_THIS)); const zend_ffi_type *type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); type = ZEND_FFI_TYPE(ctype->type); if (type->kind != ZEND_FFI_TYPE_FUNC) { @@ -5369,7 +5352,7 @@ static zend_result zend_ffi_preload_glob(const char *filename) /* {{{ */ /* pass */ } else { for(i=0 ; itype); - bool overflow = 0; + bool overflow = false; bool is_signed = (enum_type->enumeration.kind == ZEND_FFI_TYPE_SINT8 || enum_type->enumeration.kind == ZEND_FFI_TYPE_SINT16 || @@ -6009,36 +5992,36 @@ void zend_ffi_add_enum_val(zend_ffi_dcl *enum_dcl, const char *name, size_t name if (val->kind == ZEND_FFI_VAL_EMPTY) { if (is_signed) { if (*last == 0x7FFFFFFFFFFFFFFFLL) { - overflow = 1; + overflow = true; } } else { if ((*min != 0 || *max != 0) && (uint64_t)*last == 0xFFFFFFFFFFFFFFFFULL) { - overflow = 1; + overflow = true; } } value = *last + 1; } else if (val->kind == ZEND_FFI_VAL_CHAR) { if (!is_signed && val->ch < 0) { if ((uint64_t)*max > 0x7FFFFFFFFFFFFFFFULL) { - overflow = 1; + overflow = true; } else { - is_signed = 1; + is_signed = true; } } value = val->ch; } else if (val->kind == ZEND_FFI_VAL_INT32 || val->kind == ZEND_FFI_VAL_INT64) { if (!is_signed && val->i64 < 0) { if ((uint64_t)*max > 0x7FFFFFFFFFFFFFFFULL) { - overflow = 1; + overflow = true; } else { - is_signed = 1; + is_signed = true; } } value = val->i64; } else if (val->kind == ZEND_FFI_VAL_UINT32 || val->kind == ZEND_FFI_VAL_UINT64) { if (is_signed && val->u64 > 0x7FFFFFFFFFFFFFFFULL) { - overflow = 1; + overflow = true; } value = val->u64; } else { @@ -6142,7 +6125,7 @@ static zend_result zend_ffi_validate_field_type(const zend_ffi_type *type, zend_ if (type == struct_type) { zend_ffi_throw_parser_error("Struct/union can't contain an instance of itself at line %d", FFI_G(line)); return FAILURE; - } else if (zend_ffi_validate_var_type(type, 1) == FAILURE) { + } else if (zend_ffi_validate_var_type(type, true) == FAILURE) { return FAILURE; } else if (struct_type->attr & ZEND_FFI_ATTR_UNION) { if (type->attr & ZEND_FFI_ATTR_INCOMPLETE_ARRAY) { @@ -6185,7 +6168,7 @@ void zend_ffi_add_field(zend_ffi_dcl *struct_dcl, const char *name, size_t name_ } field->type = field_dcl->type; field->is_const = (bool)(field_dcl->attr & ZEND_FFI_ATTR_CONST); - field->is_nested = 0; + field->is_nested = false; field->first_bit = 0; field->bits = 0; field_dcl->type = field_type; /* reset "owned" flag */ @@ -6238,7 +6221,7 @@ void zend_ffi_add_anonymous_field(zend_ffi_dcl *struct_dcl, zend_ffi_dcl *field_ } new_field->type = field->type; new_field->is_const = field->is_const; - new_field->is_nested = 1; + new_field->is_nested = true; new_field->first_bit = field->first_bit; new_field->bits = field->bits; field->type = ZEND_FFI_TYPE(field->type); /* reset "owned" flag */ @@ -6353,7 +6336,7 @@ void zend_ffi_add_bit_field(zend_ffi_dcl *struct_dcl, const char *name, size_t n } field->type = field_dcl->type; field->is_const = (bool)(field_dcl->attr & ZEND_FFI_ATTR_CONST); - field->is_nested = 0; + field->is_nested = false; field_dcl->type = field_type; /* reset "owned" flag */ if (name) { @@ -6412,7 +6395,7 @@ static zend_result zend_ffi_validate_array_element_type(const zend_ffi_type *typ zend_ffi_throw_parser_error("Only the leftmost array can be undimensioned at line %d", FFI_G(line)); return FAILURE; } - return zend_ffi_validate_type(type, 0, 1); + return zend_ffi_validate_type(type, false, true); } /* }}} */ @@ -6472,7 +6455,7 @@ static zend_result zend_ffi_validate_func_ret_type(const zend_ffi_type *type) /* zend_ffi_throw_parser_error("Function returning array is not allowed at line %d", FFI_G(line)); return FAILURE; } - return zend_ffi_validate_incomplete_type(type, 1, 0); + return zend_ffi_validate_incomplete_type(type, true, false); } /* }}} */ @@ -6646,7 +6629,7 @@ void zend_ffi_add_arg(HashTable **args, const char *name, size_t name_len, zend_ new_type->pointer.type = arg_dcl->type; arg_dcl->type = ZEND_FFI_TYPE_MAKE_OWNED(new_type); } - if (zend_ffi_validate_incomplete_type(type, 1, 1) == FAILURE) { + if (zend_ffi_validate_incomplete_type(type, true, true) == FAILURE) { zend_ffi_cleanup_dcl(arg_dcl); zend_hash_destroy(*args); pefree(*args, FFI_G(persistent)); @@ -6725,7 +6708,7 @@ void zend_ffi_declare(const char *name, size_t name_len, zend_ffi_dcl *dcl) /* { zend_ffi_type *type; type = ZEND_FFI_TYPE(dcl->type); - if (zend_ffi_validate_type(type, (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) == ZEND_FFI_DCL_EXTERN, 1) == FAILURE) { + if (zend_ffi_validate_type(type, (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) == ZEND_FFI_DCL_EXTERN, true) == FAILURE) { zend_ffi_cleanup_dcl(dcl); LONGJMP(FFI_G(bailout), FAILURE); } @@ -7100,7 +7083,6 @@ static zend_result zend_ffi_nested_type(zend_ffi_type *type, zend_ffi_type *nest nested_type->size = nested_type->array.length * ZEND_FFI_TYPE(nested_type->array.type)->size; nested_type->align = ZEND_FFI_TYPE(nested_type->array.type)->align; return SUCCESS; - break; case ZEND_FFI_TYPE_FUNC: /* "char" is used as a terminator of nested declaration */ if (nested_type->func.ret_type == &zend_ffi_type_char) { diff --git a/ext/ffi/ffi.g b/ext/ffi/ffi.g index 364837242890..9ab8ee404edf 100644 --- a/ext/ffi/ffi.g +++ b/ext/ffi/ffi.g @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -30,15 +28,13 @@ php llk.php ffi.g %{ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/ext/ffi/ffi_arginfo.h b/ext/ffi/ffi_arginfo.h index 563c9f8b8e8b..a263e0bfb32e 100644 --- a/ext/ffi/ffi_arginfo.h +++ b/ext/ffi/ffi_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit ffi.stub.php instead. * Stub hash: d3626f5d39317876fc7d4f240b0758f17f3472c8 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_FFI_cdef, 0, 0, FFI, 0) @@ -205,9 +205,9 @@ static zend_class_entry *register_class_FFI(void) zval const___BIGGEST_ALIGNMENT___value; ZVAL_LONG(&const___BIGGEST_ALIGNMENT___value, __BIGGEST_ALIGNMENT__); - zend_string *const___BIGGEST_ALIGNMENT___name = zend_string_init_interned("__BIGGEST_ALIGNMENT__", sizeof("__BIGGEST_ALIGNMENT__") - 1, 1); + zend_string *const___BIGGEST_ALIGNMENT___name = zend_string_init_interned("__BIGGEST_ALIGNMENT__", sizeof("__BIGGEST_ALIGNMENT__") - 1, true); zend_declare_typed_class_constant(class_entry, const___BIGGEST_ALIGNMENT___name, &const___BIGGEST_ALIGNMENT___value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const___BIGGEST_ALIGNMENT___name); + zend_string_release_ex(const___BIGGEST_ALIGNMENT___name, true); return class_entry; } @@ -231,233 +231,233 @@ static zend_class_entry *register_class_FFI_CType(void) zval const_TYPE_VOID_value; ZVAL_LONG(&const_TYPE_VOID_value, ZEND_FFI_TYPE_VOID); - zend_string *const_TYPE_VOID_name = zend_string_init_interned("TYPE_VOID", sizeof("TYPE_VOID") - 1, 1); + zend_string *const_TYPE_VOID_name = zend_string_init_interned("TYPE_VOID", sizeof("TYPE_VOID") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_VOID_name, &const_TYPE_VOID_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_VOID_name); + zend_string_release_ex(const_TYPE_VOID_name, true); zval const_TYPE_FLOAT_value; ZVAL_LONG(&const_TYPE_FLOAT_value, ZEND_FFI_TYPE_FLOAT); - zend_string *const_TYPE_FLOAT_name = zend_string_init_interned("TYPE_FLOAT", sizeof("TYPE_FLOAT") - 1, 1); + zend_string *const_TYPE_FLOAT_name = zend_string_init_interned("TYPE_FLOAT", sizeof("TYPE_FLOAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_FLOAT_name, &const_TYPE_FLOAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_FLOAT_name); + zend_string_release_ex(const_TYPE_FLOAT_name, true); zval const_TYPE_DOUBLE_value; ZVAL_LONG(&const_TYPE_DOUBLE_value, ZEND_FFI_TYPE_DOUBLE); - zend_string *const_TYPE_DOUBLE_name = zend_string_init_interned("TYPE_DOUBLE", sizeof("TYPE_DOUBLE") - 1, 1); + zend_string *const_TYPE_DOUBLE_name = zend_string_init_interned("TYPE_DOUBLE", sizeof("TYPE_DOUBLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_DOUBLE_name, &const_TYPE_DOUBLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_DOUBLE_name); + zend_string_release_ex(const_TYPE_DOUBLE_name, true); #if defined(HAVE_LONG_DOUBLE) zval const_TYPE_LONGDOUBLE_value; ZVAL_LONG(&const_TYPE_LONGDOUBLE_value, ZEND_FFI_TYPE_LONGDOUBLE); - zend_string *const_TYPE_LONGDOUBLE_name = zend_string_init_interned("TYPE_LONGDOUBLE", sizeof("TYPE_LONGDOUBLE") - 1, 1); + zend_string *const_TYPE_LONGDOUBLE_name = zend_string_init_interned("TYPE_LONGDOUBLE", sizeof("TYPE_LONGDOUBLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_LONGDOUBLE_name, &const_TYPE_LONGDOUBLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_LONGDOUBLE_name); + zend_string_release_ex(const_TYPE_LONGDOUBLE_name, true); #endif zval const_TYPE_UINT8_value; ZVAL_LONG(&const_TYPE_UINT8_value, ZEND_FFI_TYPE_UINT8); - zend_string *const_TYPE_UINT8_name = zend_string_init_interned("TYPE_UINT8", sizeof("TYPE_UINT8") - 1, 1); + zend_string *const_TYPE_UINT8_name = zend_string_init_interned("TYPE_UINT8", sizeof("TYPE_UINT8") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_UINT8_name, &const_TYPE_UINT8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_UINT8_name); + zend_string_release_ex(const_TYPE_UINT8_name, true); zval const_TYPE_SINT8_value; ZVAL_LONG(&const_TYPE_SINT8_value, ZEND_FFI_TYPE_SINT8); - zend_string *const_TYPE_SINT8_name = zend_string_init_interned("TYPE_SINT8", sizeof("TYPE_SINT8") - 1, 1); + zend_string *const_TYPE_SINT8_name = zend_string_init_interned("TYPE_SINT8", sizeof("TYPE_SINT8") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_SINT8_name, &const_TYPE_SINT8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_SINT8_name); + zend_string_release_ex(const_TYPE_SINT8_name, true); zval const_TYPE_UINT16_value; ZVAL_LONG(&const_TYPE_UINT16_value, ZEND_FFI_TYPE_UINT16); - zend_string *const_TYPE_UINT16_name = zend_string_init_interned("TYPE_UINT16", sizeof("TYPE_UINT16") - 1, 1); + zend_string *const_TYPE_UINT16_name = zend_string_init_interned("TYPE_UINT16", sizeof("TYPE_UINT16") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_UINT16_name, &const_TYPE_UINT16_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_UINT16_name); + zend_string_release_ex(const_TYPE_UINT16_name, true); zval const_TYPE_SINT16_value; ZVAL_LONG(&const_TYPE_SINT16_value, ZEND_FFI_TYPE_SINT16); - zend_string *const_TYPE_SINT16_name = zend_string_init_interned("TYPE_SINT16", sizeof("TYPE_SINT16") - 1, 1); + zend_string *const_TYPE_SINT16_name = zend_string_init_interned("TYPE_SINT16", sizeof("TYPE_SINT16") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_SINT16_name, &const_TYPE_SINT16_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_SINT16_name); + zend_string_release_ex(const_TYPE_SINT16_name, true); zval const_TYPE_UINT32_value; ZVAL_LONG(&const_TYPE_UINT32_value, ZEND_FFI_TYPE_UINT32); - zend_string *const_TYPE_UINT32_name = zend_string_init_interned("TYPE_UINT32", sizeof("TYPE_UINT32") - 1, 1); + zend_string *const_TYPE_UINT32_name = zend_string_init_interned("TYPE_UINT32", sizeof("TYPE_UINT32") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_UINT32_name, &const_TYPE_UINT32_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_UINT32_name); + zend_string_release_ex(const_TYPE_UINT32_name, true); zval const_TYPE_SINT32_value; ZVAL_LONG(&const_TYPE_SINT32_value, ZEND_FFI_TYPE_SINT32); - zend_string *const_TYPE_SINT32_name = zend_string_init_interned("TYPE_SINT32", sizeof("TYPE_SINT32") - 1, 1); + zend_string *const_TYPE_SINT32_name = zend_string_init_interned("TYPE_SINT32", sizeof("TYPE_SINT32") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_SINT32_name, &const_TYPE_SINT32_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_SINT32_name); + zend_string_release_ex(const_TYPE_SINT32_name, true); zval const_TYPE_UINT64_value; ZVAL_LONG(&const_TYPE_UINT64_value, ZEND_FFI_TYPE_UINT64); - zend_string *const_TYPE_UINT64_name = zend_string_init_interned("TYPE_UINT64", sizeof("TYPE_UINT64") - 1, 1); + zend_string *const_TYPE_UINT64_name = zend_string_init_interned("TYPE_UINT64", sizeof("TYPE_UINT64") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_UINT64_name, &const_TYPE_UINT64_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_UINT64_name); + zend_string_release_ex(const_TYPE_UINT64_name, true); zval const_TYPE_SINT64_value; ZVAL_LONG(&const_TYPE_SINT64_value, ZEND_FFI_TYPE_SINT64); - zend_string *const_TYPE_SINT64_name = zend_string_init_interned("TYPE_SINT64", sizeof("TYPE_SINT64") - 1, 1); + zend_string *const_TYPE_SINT64_name = zend_string_init_interned("TYPE_SINT64", sizeof("TYPE_SINT64") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_SINT64_name, &const_TYPE_SINT64_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_SINT64_name); + zend_string_release_ex(const_TYPE_SINT64_name, true); zval const_TYPE_ENUM_value; ZVAL_LONG(&const_TYPE_ENUM_value, ZEND_FFI_TYPE_ENUM); - zend_string *const_TYPE_ENUM_name = zend_string_init_interned("TYPE_ENUM", sizeof("TYPE_ENUM") - 1, 1); + zend_string *const_TYPE_ENUM_name = zend_string_init_interned("TYPE_ENUM", sizeof("TYPE_ENUM") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_ENUM_name, &const_TYPE_ENUM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_ENUM_name); + zend_string_release_ex(const_TYPE_ENUM_name, true); zval const_TYPE_BOOL_value; ZVAL_LONG(&const_TYPE_BOOL_value, ZEND_FFI_TYPE_BOOL); - zend_string *const_TYPE_BOOL_name = zend_string_init_interned("TYPE_BOOL", sizeof("TYPE_BOOL") - 1, 1); + zend_string *const_TYPE_BOOL_name = zend_string_init_interned("TYPE_BOOL", sizeof("TYPE_BOOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_BOOL_name, &const_TYPE_BOOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_BOOL_name); + zend_string_release_ex(const_TYPE_BOOL_name, true); zval const_TYPE_CHAR_value; ZVAL_LONG(&const_TYPE_CHAR_value, ZEND_FFI_TYPE_CHAR); - zend_string *const_TYPE_CHAR_name = zend_string_init_interned("TYPE_CHAR", sizeof("TYPE_CHAR") - 1, 1); + zend_string *const_TYPE_CHAR_name = zend_string_init_interned("TYPE_CHAR", sizeof("TYPE_CHAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_CHAR_name, &const_TYPE_CHAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_CHAR_name); + zend_string_release_ex(const_TYPE_CHAR_name, true); zval const_TYPE_POINTER_value; ZVAL_LONG(&const_TYPE_POINTER_value, ZEND_FFI_TYPE_POINTER); - zend_string *const_TYPE_POINTER_name = zend_string_init_interned("TYPE_POINTER", sizeof("TYPE_POINTER") - 1, 1); + zend_string *const_TYPE_POINTER_name = zend_string_init_interned("TYPE_POINTER", sizeof("TYPE_POINTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_POINTER_name, &const_TYPE_POINTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_POINTER_name); + zend_string_release_ex(const_TYPE_POINTER_name, true); zval const_TYPE_FUNC_value; ZVAL_LONG(&const_TYPE_FUNC_value, ZEND_FFI_TYPE_FUNC); - zend_string *const_TYPE_FUNC_name = zend_string_init_interned("TYPE_FUNC", sizeof("TYPE_FUNC") - 1, 1); + zend_string *const_TYPE_FUNC_name = zend_string_init_interned("TYPE_FUNC", sizeof("TYPE_FUNC") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_FUNC_name, &const_TYPE_FUNC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_FUNC_name); + zend_string_release_ex(const_TYPE_FUNC_name, true); zval const_TYPE_ARRAY_value; ZVAL_LONG(&const_TYPE_ARRAY_value, ZEND_FFI_TYPE_ARRAY); - zend_string *const_TYPE_ARRAY_name = zend_string_init_interned("TYPE_ARRAY", sizeof("TYPE_ARRAY") - 1, 1); + zend_string *const_TYPE_ARRAY_name = zend_string_init_interned("TYPE_ARRAY", sizeof("TYPE_ARRAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_ARRAY_name, &const_TYPE_ARRAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_ARRAY_name); + zend_string_release_ex(const_TYPE_ARRAY_name, true); zval const_TYPE_STRUCT_value; ZVAL_LONG(&const_TYPE_STRUCT_value, ZEND_FFI_TYPE_STRUCT); - zend_string *const_TYPE_STRUCT_name = zend_string_init_interned("TYPE_STRUCT", sizeof("TYPE_STRUCT") - 1, 1); + zend_string *const_TYPE_STRUCT_name = zend_string_init_interned("TYPE_STRUCT", sizeof("TYPE_STRUCT") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_STRUCT_name, &const_TYPE_STRUCT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_STRUCT_name); + zend_string_release_ex(const_TYPE_STRUCT_name, true); zval const_ATTR_CONST_value; ZVAL_LONG(&const_ATTR_CONST_value, ZEND_FFI_ATTR_CONST); - zend_string *const_ATTR_CONST_name = zend_string_init_interned("ATTR_CONST", sizeof("ATTR_CONST") - 1, 1); + zend_string *const_ATTR_CONST_name = zend_string_init_interned("ATTR_CONST", sizeof("ATTR_CONST") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_CONST_name, &const_ATTR_CONST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_CONST_name); + zend_string_release_ex(const_ATTR_CONST_name, true); zval const_ATTR_INCOMPLETE_TAG_value; ZVAL_LONG(&const_ATTR_INCOMPLETE_TAG_value, ZEND_FFI_ATTR_INCOMPLETE_TAG); - zend_string *const_ATTR_INCOMPLETE_TAG_name = zend_string_init_interned("ATTR_INCOMPLETE_TAG", sizeof("ATTR_INCOMPLETE_TAG") - 1, 1); + zend_string *const_ATTR_INCOMPLETE_TAG_name = zend_string_init_interned("ATTR_INCOMPLETE_TAG", sizeof("ATTR_INCOMPLETE_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_INCOMPLETE_TAG_name, &const_ATTR_INCOMPLETE_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_INCOMPLETE_TAG_name); + zend_string_release_ex(const_ATTR_INCOMPLETE_TAG_name, true); zval const_ATTR_VARIADIC_value; ZVAL_LONG(&const_ATTR_VARIADIC_value, ZEND_FFI_ATTR_VARIADIC); - zend_string *const_ATTR_VARIADIC_name = zend_string_init_interned("ATTR_VARIADIC", sizeof("ATTR_VARIADIC") - 1, 1); + zend_string *const_ATTR_VARIADIC_name = zend_string_init_interned("ATTR_VARIADIC", sizeof("ATTR_VARIADIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_VARIADIC_name, &const_ATTR_VARIADIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_VARIADIC_name); + zend_string_release_ex(const_ATTR_VARIADIC_name, true); zval const_ATTR_INCOMPLETE_ARRAY_value; ZVAL_LONG(&const_ATTR_INCOMPLETE_ARRAY_value, ZEND_FFI_ATTR_INCOMPLETE_ARRAY); - zend_string *const_ATTR_INCOMPLETE_ARRAY_name = zend_string_init_interned("ATTR_INCOMPLETE_ARRAY", sizeof("ATTR_INCOMPLETE_ARRAY") - 1, 1); + zend_string *const_ATTR_INCOMPLETE_ARRAY_name = zend_string_init_interned("ATTR_INCOMPLETE_ARRAY", sizeof("ATTR_INCOMPLETE_ARRAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_INCOMPLETE_ARRAY_name, &const_ATTR_INCOMPLETE_ARRAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_INCOMPLETE_ARRAY_name); + zend_string_release_ex(const_ATTR_INCOMPLETE_ARRAY_name, true); zval const_ATTR_VLA_value; ZVAL_LONG(&const_ATTR_VLA_value, ZEND_FFI_ATTR_VLA); - zend_string *const_ATTR_VLA_name = zend_string_init_interned("ATTR_VLA", sizeof("ATTR_VLA") - 1, 1); + zend_string *const_ATTR_VLA_name = zend_string_init_interned("ATTR_VLA", sizeof("ATTR_VLA") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_VLA_name, &const_ATTR_VLA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_VLA_name); + zend_string_release_ex(const_ATTR_VLA_name, true); zval const_ATTR_UNION_value; ZVAL_LONG(&const_ATTR_UNION_value, ZEND_FFI_ATTR_UNION); - zend_string *const_ATTR_UNION_name = zend_string_init_interned("ATTR_UNION", sizeof("ATTR_UNION") - 1, 1); + zend_string *const_ATTR_UNION_name = zend_string_init_interned("ATTR_UNION", sizeof("ATTR_UNION") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_UNION_name, &const_ATTR_UNION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_UNION_name); + zend_string_release_ex(const_ATTR_UNION_name, true); zval const_ATTR_PACKED_value; ZVAL_LONG(&const_ATTR_PACKED_value, ZEND_FFI_ATTR_PACKED); - zend_string *const_ATTR_PACKED_name = zend_string_init_interned("ATTR_PACKED", sizeof("ATTR_PACKED") - 1, 1); + zend_string *const_ATTR_PACKED_name = zend_string_init_interned("ATTR_PACKED", sizeof("ATTR_PACKED") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_PACKED_name, &const_ATTR_PACKED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_PACKED_name); + zend_string_release_ex(const_ATTR_PACKED_name, true); zval const_ATTR_MS_STRUCT_value; ZVAL_LONG(&const_ATTR_MS_STRUCT_value, ZEND_FFI_ATTR_MS_STRUCT); - zend_string *const_ATTR_MS_STRUCT_name = zend_string_init_interned("ATTR_MS_STRUCT", sizeof("ATTR_MS_STRUCT") - 1, 1); + zend_string *const_ATTR_MS_STRUCT_name = zend_string_init_interned("ATTR_MS_STRUCT", sizeof("ATTR_MS_STRUCT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_MS_STRUCT_name, &const_ATTR_MS_STRUCT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_MS_STRUCT_name); + zend_string_release_ex(const_ATTR_MS_STRUCT_name, true); zval const_ATTR_GCC_STRUCT_value; ZVAL_LONG(&const_ATTR_GCC_STRUCT_value, ZEND_FFI_ATTR_GCC_STRUCT); - zend_string *const_ATTR_GCC_STRUCT_name = zend_string_init_interned("ATTR_GCC_STRUCT", sizeof("ATTR_GCC_STRUCT") - 1, 1); + zend_string *const_ATTR_GCC_STRUCT_name = zend_string_init_interned("ATTR_GCC_STRUCT", sizeof("ATTR_GCC_STRUCT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_GCC_STRUCT_name, &const_ATTR_GCC_STRUCT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_GCC_STRUCT_name); + zend_string_release_ex(const_ATTR_GCC_STRUCT_name, true); zval const_ABI_DEFAULT_value; ZVAL_LONG(&const_ABI_DEFAULT_value, ZEND_FFI_ABI_DEFAULT); - zend_string *const_ABI_DEFAULT_name = zend_string_init_interned("ABI_DEFAULT", sizeof("ABI_DEFAULT") - 1, 1); + zend_string *const_ABI_DEFAULT_name = zend_string_init_interned("ABI_DEFAULT", sizeof("ABI_DEFAULT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_DEFAULT_name, &const_ABI_DEFAULT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_DEFAULT_name); + zend_string_release_ex(const_ABI_DEFAULT_name, true); zval const_ABI_CDECL_value; ZVAL_LONG(&const_ABI_CDECL_value, ZEND_FFI_ABI_CDECL); - zend_string *const_ABI_CDECL_name = zend_string_init_interned("ABI_CDECL", sizeof("ABI_CDECL") - 1, 1); + zend_string *const_ABI_CDECL_name = zend_string_init_interned("ABI_CDECL", sizeof("ABI_CDECL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_CDECL_name, &const_ABI_CDECL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_CDECL_name); + zend_string_release_ex(const_ABI_CDECL_name, true); zval const_ABI_FASTCALL_value; ZVAL_LONG(&const_ABI_FASTCALL_value, ZEND_FFI_ABI_FASTCALL); - zend_string *const_ABI_FASTCALL_name = zend_string_init_interned("ABI_FASTCALL", sizeof("ABI_FASTCALL") - 1, 1); + zend_string *const_ABI_FASTCALL_name = zend_string_init_interned("ABI_FASTCALL", sizeof("ABI_FASTCALL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_FASTCALL_name, &const_ABI_FASTCALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_FASTCALL_name); + zend_string_release_ex(const_ABI_FASTCALL_name, true); zval const_ABI_THISCALL_value; ZVAL_LONG(&const_ABI_THISCALL_value, ZEND_FFI_ABI_THISCALL); - zend_string *const_ABI_THISCALL_name = zend_string_init_interned("ABI_THISCALL", sizeof("ABI_THISCALL") - 1, 1); + zend_string *const_ABI_THISCALL_name = zend_string_init_interned("ABI_THISCALL", sizeof("ABI_THISCALL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_THISCALL_name, &const_ABI_THISCALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_THISCALL_name); + zend_string_release_ex(const_ABI_THISCALL_name, true); zval const_ABI_STDCALL_value; ZVAL_LONG(&const_ABI_STDCALL_value, ZEND_FFI_ABI_STDCALL); - zend_string *const_ABI_STDCALL_name = zend_string_init_interned("ABI_STDCALL", sizeof("ABI_STDCALL") - 1, 1); + zend_string *const_ABI_STDCALL_name = zend_string_init_interned("ABI_STDCALL", sizeof("ABI_STDCALL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_STDCALL_name, &const_ABI_STDCALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_STDCALL_name); + zend_string_release_ex(const_ABI_STDCALL_name, true); zval const_ABI_PASCAL_value; ZVAL_LONG(&const_ABI_PASCAL_value, ZEND_FFI_ABI_PASCAL); - zend_string *const_ABI_PASCAL_name = zend_string_init_interned("ABI_PASCAL", sizeof("ABI_PASCAL") - 1, 1); + zend_string *const_ABI_PASCAL_name = zend_string_init_interned("ABI_PASCAL", sizeof("ABI_PASCAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_PASCAL_name, &const_ABI_PASCAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_PASCAL_name); + zend_string_release_ex(const_ABI_PASCAL_name, true); zval const_ABI_REGISTER_value; ZVAL_LONG(&const_ABI_REGISTER_value, ZEND_FFI_ABI_REGISTER); - zend_string *const_ABI_REGISTER_name = zend_string_init_interned("ABI_REGISTER", sizeof("ABI_REGISTER") - 1, 1); + zend_string *const_ABI_REGISTER_name = zend_string_init_interned("ABI_REGISTER", sizeof("ABI_REGISTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_REGISTER_name, &const_ABI_REGISTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_REGISTER_name); + zend_string_release_ex(const_ABI_REGISTER_name, true); zval const_ABI_MS_value; ZVAL_LONG(&const_ABI_MS_value, ZEND_FFI_ABI_MS); - zend_string *const_ABI_MS_name = zend_string_init_interned("ABI_MS", sizeof("ABI_MS") - 1, 1); + zend_string *const_ABI_MS_name = zend_string_init_interned("ABI_MS", sizeof("ABI_MS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_MS_name, &const_ABI_MS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_MS_name); + zend_string_release_ex(const_ABI_MS_name, true); zval const_ABI_SYSV_value; ZVAL_LONG(&const_ABI_SYSV_value, ZEND_FFI_ABI_SYSV); - zend_string *const_ABI_SYSV_name = zend_string_init_interned("ABI_SYSV", sizeof("ABI_SYSV") - 1, 1); + zend_string *const_ABI_SYSV_name = zend_string_init_interned("ABI_SYSV", sizeof("ABI_SYSV") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_SYSV_name, &const_ABI_SYSV_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_SYSV_name); + zend_string_release_ex(const_ABI_SYSV_name, true); zval const_ABI_VECTORCALL_value; ZVAL_LONG(&const_ABI_VECTORCALL_value, ZEND_FFI_ABI_VECTORCALL); - zend_string *const_ABI_VECTORCALL_name = zend_string_init_interned("ABI_VECTORCALL", sizeof("ABI_VECTORCALL") - 1, 1); + zend_string *const_ABI_VECTORCALL_name = zend_string_init_interned("ABI_VECTORCALL", sizeof("ABI_VECTORCALL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ABI_VECTORCALL_name, &const_ABI_VECTORCALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ABI_VECTORCALL_name); + zend_string_release_ex(const_ABI_VECTORCALL_name, true); return class_entry; } diff --git a/ext/ffi/ffi_parser.c b/ext/ffi/ffi_parser.c index 26d623a40290..27f1469133fe 100644 --- a/ext/ffi/ffi_parser.c +++ b/ext/ffi/ffi_parser.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -2634,7 +2632,7 @@ static int parse_enumerator(int sym, zend_ffi_dcl *enum_dcl, int64_t *min, int64 static int parse_declarator(int sym, zend_ffi_dcl *dcl, const char **name, size_t *name_len) { zend_ffi_dcl nested_dcl = {ZEND_FFI_DCL_CHAR, 0, 0, 0, NULL}; - bool nested = 0; + bool nested = false; if (sym == YY__STAR) { sym = parse_pointer(sym, dcl); } @@ -2650,7 +2648,7 @@ static int parse_declarator(int sym, zend_ffi_dcl *dcl, const char **name, size_ yy_error_sym("')' expected, got", sym); } sym = get_sym(); - nested = 1; + nested = true; } else { yy_error_sym("unexpected", sym); } @@ -2663,7 +2661,7 @@ static int parse_declarator(int sym, zend_ffi_dcl *dcl, const char **name, size_ static int parse_abstract_declarator(int sym, zend_ffi_dcl *dcl) { zend_ffi_dcl nested_dcl = {ZEND_FFI_DCL_CHAR, 0, 0, 0, NULL}; - bool nested = 0; + bool nested = false; if (sym == YY__STAR) { sym = parse_pointer(sym, dcl); } @@ -2677,7 +2675,7 @@ static int parse_abstract_declarator(int sym, zend_ffi_dcl *dcl) { yy_error_sym("')' expected, got", sym); } sym = get_sym(); - nested = 1; + nested = true; } if (sym == YY__LBRACK || sym == YY__LPAREN) { sym = parse_array_or_function_declarators(sym, dcl, &nested_dcl); @@ -2688,7 +2686,7 @@ static int parse_abstract_declarator(int sym, zend_ffi_dcl *dcl) { static int parse_parameter_declarator(int sym, zend_ffi_dcl *dcl, const char **name, size_t *name_len) { zend_ffi_dcl nested_dcl = {ZEND_FFI_DCL_CHAR, 0, 0, 0, NULL}; - bool nested = 0; + bool nested = false; if (sym == YY__STAR) { sym = parse_pointer(sym, dcl); } @@ -2702,7 +2700,7 @@ static int parse_parameter_declarator(int sym, zend_ffi_dcl *dcl, const char **n yy_error_sym("')' expected, got", sym); } sym = get_sym(); - nested = 1; + nested = true; } else if (sym == YY_ID) { sym = parse_ID(sym, name, name_len); } else if (sym == YY__LBRACK || sym == YY__LPAREN || sym == YY__RPAREN || sym == YY__COMMA) { diff --git a/ext/ffi/php_ffi.h b/ext/ffi/php_ffi.h index ba92947e62bf..02fdb221c3df 100644 --- a/ext/ffi/php_ffi.h +++ b/ext/ffi/php_ffi.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Dmitry Stogov | +----------------------------------------------------------------------+ diff --git a/ext/ffi/tests/001.phpt b/ext/ffi/tests/001.phpt deleted file mode 100644 index 3196498aba0d..000000000000 --- a/ext/ffi/tests/001.phpt +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -FFI 001: Check if FFI is loaded ---EXTENSIONS-- -ffi ---INI-- -ffi.enable=1 ---FILE-- - ---EXPECT-- -The extension "FFI" is available diff --git a/ext/ffi/tests/025.phpt b/ext/ffi/tests/025.phpt index b1cdab9463e6..817d12806dea 100644 --- a/ext/ffi/tests/025.phpt +++ b/ext/ffi/tests/025.phpt @@ -39,6 +39,8 @@ object(FFI\CData:char)#%d (1) { ["cdata"]=> string(1) "a" } + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d object(FFI\CData:char)#%d (1) { ["cdata"]=> string(1) "b" diff --git a/ext/ffi/tests/gh14286_2.phpt b/ext/ffi/tests/gh14286_2.phpt index c3fc0b242a47..4dc48ccc27a1 100644 --- a/ext/ffi/tests/gh14286_2.phpt +++ b/ext/ffi/tests/gh14286_2.phpt @@ -2,10 +2,6 @@ GH-14286 (ffi enum type (when enum has no name) make memory leak) --EXTENSIONS-- ffi ---SKIPIF-- - --INI-- ffi.enable=1 --FILE-- diff --git a/ext/ffi/tests/gh18629_cdef_resolve_func.phpt b/ext/ffi/tests/gh18629_cdef_resolve_func.phpt new file mode 100644 index 000000000000..ae81412efa63 --- /dev/null +++ b/ext/ffi/tests/gh18629_cdef_resolve_func.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-18629 (FFI::cdef() leaks on function resolution failure) +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Failed resolving C function 'nonexistent_ffi_test_func' diff --git a/ext/ffi/tests/gh18629_read_field_non_struct.phpt b/ext/ffi/tests/gh18629_read_field_non_struct.phpt new file mode 100644 index 000000000000..307fde1a53b8 --- /dev/null +++ b/ext/ffi/tests/gh18629_read_field_non_struct.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-18629 (Read field of non C struct/union) +--EXTENSIONS-- +ffi +--INI-- +ffi.enable=1 +--FILE-- +new("int*"); +try { + $y = $x->foo; +} catch (\FFI\Exception $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Attempt to read field 'foo' of non C struct/union diff --git a/ext/fileinfo/config.m4 b/ext/fileinfo/config.m4 index 346061411e08..2d6139f06dff 100644 --- a/ext/fileinfo/config.m4 +++ b/ext/fileinfo/config.m4 @@ -29,11 +29,6 @@ if test "$PHP_FILEINFO" != "no"; then AC_CHECK_HEADERS([sys/sysmacros.h]) - AC_CHECK_FUNCS([strcasestr],,[ - AC_MSG_NOTICE([using libmagic strcasestr implementation]) - libmagic_sources="$libmagic_sources libmagic/strcasestr.c" - ]) - AX_GCC_FUNC_ATTRIBUTE([visibility]) PHP_NEW_EXTENSION([fileinfo], diff --git a/ext/fileinfo/config.w32 b/ext/fileinfo/config.w32 index 2a42dc45a1d1..34670e7451e4 100644 --- a/ext/fileinfo/config.w32 +++ b/ext/fileinfo/config.w32 @@ -8,7 +8,7 @@ if (PHP_FILEINFO != 'no') { encoding.c fsmagic.c funcs.c \ is_json.c is_tar.c is_simh.c magic.c print.c \ readcdf.c softmagic.c der.c \ - strcasestr.c buffer.c is_csv.c"; + buffer.c is_csv.c"; EXTENSION('fileinfo', 'fileinfo.c php_libmagic.c', true, "/I" + configure_module_dirname + "/libmagic /I" + configure_module_dirname); ADD_EXTENSION_DEP('fileinfo', 'pcre'); diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 143b8ba080fc..88126e9f6121 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ @@ -31,10 +29,11 @@ #include "php_ini.h" #include "ext/standard/info.h" #include "ext/standard/file.h" /* needed for context stuff */ +#include "Zend/zend_attributes.h" +#include "Zend/zend_exceptions.h" #include "php_fileinfo.h" #include "fileinfo_arginfo.h" #include "fopen_wrappers.h" /* needed for is_url */ -#include "Zend/zend_exceptions.h" static zend_object_handlers finfo_object_handlers; zend_class_entry *finfo_class_entry; @@ -45,7 +44,7 @@ typedef struct _finfo_object { } finfo_object; static inline finfo_object *php_finfo_fetch_object(zend_object *obj) { - return (finfo_object *)((char*)(obj) - XtOffsetOf(finfo_object, zo)); + return ZEND_CONTAINER_OF(obj, finfo_object, zo); } #define Z_FINFO_P(zv) php_finfo_fetch_object(Z_OBJ_P((zv))) @@ -83,7 +82,7 @@ PHP_MINIT_FUNCTION(finfo) /* copy the standard object handlers to you handler table */ memcpy(&finfo_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - finfo_object_handlers.offset = XtOffsetOf(finfo_object, zo); + finfo_object_handlers.offset = offsetof(finfo_object, zo); finfo_object_handlers.free_obj = finfo_objects_free; finfo_object_handlers.clone_obj = NULL; @@ -153,22 +152,10 @@ PHP_FUNCTION(finfo_open) } else if (file && *file) { /* user specified file, perform open_basedir checks */ if (php_check_open_basedir(file)) { - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } if (!expand_filepath_with_mode(file, resolved_path, NULL, 0, CWD_EXPAND)) { - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } file = resolved_path; } @@ -177,37 +164,35 @@ PHP_FUNCTION(finfo_open) if (magic == NULL) { php_error_docref(NULL, E_WARNING, "Invalid mode '" ZEND_LONG_FMT "'.", options); - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } if (magic_load(magic, file) == -1) { php_error_docref(NULL, E_WARNING, "Failed to load magic database at \"%s\"", file); magic_close(magic); - if (object) { - zend_restore_error_handling(&zeh); - if (!EG(exception)) { - zend_throw_exception(NULL, "Constructor failed", 0); - } - } - RETURN_FALSE; + goto err; } if (object) { zend_restore_error_handling(&zeh); finfo_object *obj = Z_FINFO_P(object); obj->magic = magic; + return; } else { zend_object *zobj = finfo_objects_new(finfo_class_entry); finfo_object *obj = php_finfo_fetch_object(zobj); obj->magic = magic; RETURN_OBJ(zobj); } + +err: + if (object) { + zend_restore_error_handling(&zeh); + if (!EG(exception)) { + zend_throw_exception(NULL, "Constructor failed", 0); + } + } + RETURN_FALSE; } /* }}} */ @@ -281,11 +266,12 @@ static const char* php_fileinfo_from_path(struct magic_set *magic, const zend_st if (php_stream_stat(stream, &ssb) == SUCCESS) { if (ssb.sb.st_mode & S_IFDIR) { ret_val = "directory"; - } else { - ret_val = magic_stream(magic, stream); - if (UNEXPECTED(ret_val == NULL)) { - php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic)); - } + } + } + if (!ret_val) { + ret_val = magic_stream(magic, stream); + if (UNEXPECTED(ret_val == NULL)) { + php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic)); } } @@ -356,6 +342,13 @@ PHP_FUNCTION(finfo_buffer) RETURN_THROWS(); } + if (ZEND_NUM_ARGS() == 4 || (hasThis() && ZEND_NUM_ARGS() == 3)) { + php_error_docref(NULL, E_DEPRECATED, "The $context parameter has no effect for finfo_buffer()"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + if (!Z_FINFO_P(self)->magic) { zend_throw_error(NULL, "Invalid finfo object"); RETURN_THROWS(); diff --git a/ext/fileinfo/fileinfo.stub.php b/ext/fileinfo/fileinfo.stub.php index 2dba0fe2659e..238ad7c14809 100644 --- a/ext/fileinfo/fileinfo.stub.php +++ b/ext/fileinfo/fileinfo.stub.php @@ -92,6 +92,7 @@ public function set_flags(int $flags): true {} /** @refcount 1 */ function finfo_open(int $flags = FILEINFO_NONE, ?string $magic_database = null): finfo|false {} +#[\Deprecated(since: '8.5', message: 'as finfo objects are freed automatically')] function finfo_close(finfo $finfo): true {} function finfo_set_flags(finfo $finfo, int $flags): true {} diff --git a/ext/fileinfo/fileinfo_arginfo.h b/ext/fileinfo/fileinfo_arginfo.h index 024e7d4b6bd5..4dd001ca05b6 100644 --- a/ext/fileinfo/fileinfo_arginfo.h +++ b/ext/fileinfo/fileinfo_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: d5bc322159e4af87077c07ddaca0a77803b4743a */ +/* This is a generated file, edit fileinfo.stub.php instead. + * Stub hash: 311d1049e32af017b44e260a00f13830714b1e96 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_finfo_open, 0, 0, finfo, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "FILEINFO_NONE") @@ -63,7 +63,7 @@ ZEND_FUNCTION(mime_content_type); static const zend_function_entry ext_functions[] = { ZEND_FE(finfo_open, arginfo_finfo_open) - ZEND_FE(finfo_close, arginfo_finfo_close) + ZEND_RAW_FENTRY("finfo_close", zif_finfo_close, arginfo_finfo_close, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(finfo_set_flags, arginfo_finfo_set_flags) ZEND_FE(finfo_file, arginfo_finfo_file) ZEND_FE(finfo_buffer, arginfo_finfo_buffer) @@ -96,6 +96,14 @@ static void register_fileinfo_symbols(int module_number) #endif REGISTER_LONG_CONSTANT("FILEINFO_APPLE", MAGIC_APPLE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILEINFO_EXTENSION", MAGIC_EXTENSION, CONST_PERSISTENT); + + + zend_attribute *attribute_Deprecated_func_finfo_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "finfo_close", sizeof("finfo_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_finfo_close_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_finfo_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_finfo_close_0_arg1_str = zend_string_init("as finfo objects are freed automatically", strlen("as finfo objects are freed automatically"), 1); + ZVAL_STR(&attribute_Deprecated_func_finfo_close_0->args[1].value, attribute_Deprecated_func_finfo_close_0_arg1_str); + attribute_Deprecated_func_finfo_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_finfo(void) diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch index 4eb7ccd336f8..0f69e732fdd5 100644 --- a/ext/fileinfo/libmagic.patch +++ b/ext/fileinfo/libmagic.patch @@ -1,6 +1,6 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c ---- libmagic.orig/apprentice.c 2024-11-27 16:37:00.000000000 +0100 -+++ libmagic/apprentice.c 2025-02-09 02:25:02.364884555 +0100 +--- libmagic.orig/apprentice.c 2024-11-27 10:37:00.000000000 -0500 ++++ libmagic/apprentice.c 2026-03-20 12:10:19.777614667 -0400 @@ -32,7 +32,7 @@ #include "file.h" @@ -325,14 +325,14 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c // Don't warn for DER if (mpa.type == FILE_DER) return 0; -@@ -1151,6 +1075,7 @@ +@@ -1150,6 +1074,7 @@ + ma->mp->desc); file_mdump(ma->mp); file_mdump(mb->mp); +#endif return 0; } return x > 0 ? -1 : 1; - } @@ -1303,7 +1228,7 @@ size_t incr = mset[i].max + ALLOC_INCR; @@ -954,8 +954,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c if (ma[j].cont_level == 0) break; diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c ---- libmagic.orig/ascmagic.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/ascmagic.c 2025-02-09 01:20:19.757840211 +0100 +--- libmagic.orig/ascmagic.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/ascmagic.c 2026-03-19 16:25:42.998672674 -0400 @@ -96,7 +96,7 @@ rv = file_ascmagic_with_encoding(ms, &bb, ubuf, ulen, code, type, text); @@ -996,8 +996,8 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c return rv; } diff -u libmagic.orig/buffer.c libmagic/buffer.c ---- libmagic.orig/buffer.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/buffer.c 2025-02-09 01:20:19.757910844 +0100 +--- libmagic.orig/buffer.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/buffer.c 2026-03-19 16:25:42.998672674 -0400 @@ -31,19 +31,21 @@ #endif /* lint */ @@ -1055,8 +1055,8 @@ diff -u libmagic.orig/buffer.c libmagic/buffer.c goto out; } diff -u libmagic.orig/cdf.c libmagic/cdf.c ---- libmagic.orig/cdf.c 2024-11-25 22:24:59.000000000 +0100 -+++ libmagic/cdf.c 2025-02-09 01:25:00.187641434 +0100 +--- libmagic.orig/cdf.c 2024-11-25 16:24:59.000000000 -0500 ++++ libmagic/cdf.c 2026-03-19 16:25:42.998672674 -0400 @@ -43,7 +43,9 @@ #include #endif @@ -1286,8 +1286,8 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c #endif diff -u libmagic.orig/cdf.h libmagic/cdf.h ---- libmagic.orig/cdf.h 2024-11-25 22:18:55.000000000 +0100 -+++ libmagic/cdf.h 2025-02-09 01:23:35.871635744 +0100 +--- libmagic.orig/cdf.h 2024-11-25 16:18:55.000000000 -0500 ++++ libmagic/cdf.h 2026-03-19 16:25:42.990672671 -0400 @@ -37,8 +37,6 @@ #ifdef WIN32 @@ -1439,8 +1439,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h diff -u libmagic.orig/compress.c libmagic/compress.c ---- libmagic.orig/compress.c 2024-11-10 17:52:27.000000000 +0100 -+++ libmagic/compress.c 2025-02-09 01:59:42.978538071 +0100 +--- libmagic.orig/compress.c 2024-11-10 11:52:27.000000000 -0500 ++++ libmagic/compress.c 2026-03-20 12:10:19.777614667 -0400 @@ -64,13 +64,14 @@ #if defined(HAVE_SYS_TIME_H) #include @@ -1666,8 +1666,8 @@ diff -u libmagic.orig/compress.c libmagic/compress.c #endif +#endif diff -u libmagic.orig/der.c libmagic/der.c ---- libmagic.orig/der.c 2024-11-25 23:31:53.000000000 +0100 -+++ libmagic/der.c 2025-02-09 01:20:19.770853011 +0100 +--- libmagic.orig/der.c 2024-11-25 17:31:53.000000000 -0500 ++++ libmagic/der.c 2026-03-19 16:25:43.002672676 -0400 @@ -54,7 +54,9 @@ #include "magic.h" #include "der.h" @@ -1679,8 +1679,8 @@ diff -u libmagic.orig/der.c libmagic/der.c #include #endif diff -u libmagic.orig/der.h libmagic/der.h ---- libmagic.orig/der.h 2024-11-25 22:26:18.000000000 +0100 -+++ libmagic/der.h 2023-04-09 22:21:58.195018580 +0200 +--- libmagic.orig/der.h 2024-11-25 16:26:18.000000000 -0500 ++++ libmagic/der.h 2026-03-19 16:25:43.006672678 -0400 @@ -24,5 +24,5 @@ * POSSIBILITY OF SUCH DAMAGE. */ @@ -1690,8 +1690,8 @@ diff -u libmagic.orig/der.h libmagic/der.h +extern int der_offs(struct magic_set *, struct magic *, size_t); +extern int der_cmp(struct magic_set *, struct magic *); diff -u libmagic.orig/encoding.c libmagic/encoding.c ---- libmagic.orig/encoding.c 2024-10-29 21:56:48.000000000 +0100 -+++ libmagic/encoding.c 2025-02-09 01:20:19.770879123 +0100 +--- libmagic.orig/encoding.c 2024-10-29 16:56:48.000000000 -0400 ++++ libmagic/encoding.c 2026-03-19 16:25:43.010672679 -0400 @@ -97,7 +97,7 @@ nbytes = ms->encoding_max; @@ -1726,8 +1726,8 @@ diff -u libmagic.orig/encoding.c libmagic/encoding.c return rv; } diff -u libmagic.orig/file.h libmagic/file.h ---- libmagic.orig/file.h 2024-11-27 16:37:00.000000000 +0100 -+++ libmagic/file.h 2025-02-09 01:47:36.242811911 +0100 +--- libmagic.orig/file.h 2024-11-27 10:37:00.000000000 -0500 ++++ libmagic/file.h 2026-03-25 16:14:40.128668705 -0400 @@ -27,15 +27,13 @@ */ /* @@ -1767,6 +1767,21 @@ diff -u libmagic.orig/file.h libmagic/file.h #define ENABLE_CONDITIONALS +@@ -109,12 +102,12 @@ + + #if HAVE_VISIBILITY + # if defined(WIN32) +-# define file_public __declspec(dllexport) ++# define file_public + # ifndef file_protected + # define file_protected + # endif + # else +-# define file_public __attribute__((__visibility__("default"))) ++# define file_public __attribute__((__visibility__("hidden"))) + # ifndef file_protected + # define file_protected __attribute__((__visibility__("hidden"))) + # endif @@ -179,7 +172,7 @@ #define MAXstring 128 /* max len of "string" types */ @@ -1883,7 +1898,7 @@ diff -u libmagic.orig/file.h libmagic/file.h typedef struct { char *buf; size_t blen; -@@ -649,19 +629,6 @@ +@@ -649,28 +629,12 @@ extern file_protected const size_t file_nnames; #endif @@ -1903,7 +1918,16 @@ diff -u libmagic.orig/file.h libmagic/file.h #ifndef HAVE_STRLCPY size_t strlcpy(char *, const char *, size_t); #endif -@@ -681,31 +648,6 @@ + #ifndef HAVE_STRLCAT + size_t strlcat(char *, const char *, size_t); + #endif +-#ifndef HAVE_STRCASESTR +-char *strcasestr(const char *, const char *); +-#endif + #ifndef HAVE_GETLINE + ssize_t getline(char **, size_t *, FILE *); + ssize_t getdelim(char **, size_t *, int, FILE *); +@@ -681,31 +645,6 @@ #ifndef HAVE_ASCTIME_R char *asctime_r(const struct tm *, char *); #endif @@ -1936,8 +1960,8 @@ diff -u libmagic.orig/file.h libmagic/file.h #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK) #define QUICK diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c ---- libmagic.orig/fsmagic.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/fsmagic.c 2025-02-09 01:20:19.770987982 +0100 +--- libmagic.orig/fsmagic.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/fsmagic.c 2026-03-19 16:25:43.006672678 -0400 @@ -66,26 +66,10 @@ # define minor(dev) ((dev) & 0xff) #endif @@ -2229,8 +2253,8 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c #ifndef __COHERENT__ case S_IFSOCK: diff -u libmagic.orig/funcs.c libmagic/funcs.c ---- libmagic.orig/funcs.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/funcs.c 2025-02-09 01:29:25.403659334 +0100 +--- libmagic.orig/funcs.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/funcs.c 2026-03-19 16:25:42.990672671 -0400 @@ -66,7 +66,7 @@ file_private void file_clearbuf(struct magic_set *ms) @@ -2592,8 +2616,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c file_protected int file_clear_closexec(int fd) { diff -u libmagic.orig/magic.c libmagic/magic.c ---- libmagic.orig/magic.c 2024-06-19 18:18:53.000000000 +0200 -+++ libmagic/magic.c 2025-02-09 01:20:19.771155033 +0100 +--- libmagic.orig/magic.c 2024-06-19 12:18:53.000000000 -0400 ++++ libmagic/magic.c 2026-03-20 12:10:19.777614667 -0400 @@ -25,11 +25,6 @@ * SUCH DAMAGE. */ @@ -3066,8 +3090,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c } return file_getbuffer(ms); diff -u libmagic.orig/magic.h libmagic/magic.h ---- libmagic.orig/magic.h 2025-02-09 12:43:22.903059789 +0100 -+++ libmagic/magic.h 2025-02-09 01:39:57.110146603 +0100 +--- libmagic.orig/magic.h 2026-03-25 16:14:49.284673536 -0400 ++++ libmagic/magic.h 2026-03-20 12:10:19.777614667 -0400 @@ -47,8 +47,6 @@ * extensions */ #define MAGIC_COMPRESS_TRANSP 0x2000000 /* Check inside compressed files @@ -3109,8 +3133,8 @@ diff -u libmagic.orig/magic.h libmagic/magic.h const char *magic_buffer(magic_t, const void *, size_t); diff -u libmagic.orig/print.c libmagic/print.c ---- libmagic.orig/print.c 2024-10-06 19:04:42.000000000 +0200 -+++ libmagic/print.c 2025-02-09 01:36:41.713156291 +0100 +--- libmagic.orig/print.c 2024-10-06 13:04:42.000000000 -0400 ++++ libmagic/print.c 2026-03-19 16:25:42.982672668 -0400 @@ -74,7 +74,7 @@ if (m->mask_op & FILE_OPINVERSE) (void) fputc('~', stderr); @@ -3187,8 +3211,8 @@ diff -u libmagic.orig/print.c libmagic/print.c if (pp == NULL) goto out; diff -u libmagic.orig/readcdf.c libmagic/readcdf.c ---- libmagic.orig/readcdf.c 2024-11-25 22:07:46.000000000 +0100 -+++ libmagic/readcdf.c 2025-02-09 01:20:19.771337672 +0100 +--- libmagic.orig/readcdf.c 2024-11-25 16:07:46.000000000 -0500 ++++ libmagic/readcdf.c 2026-03-19 16:25:43.002672676 -0400 @@ -31,7 +31,9 @@ #include @@ -3307,8 +3331,8 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c /* If we handled it already, return */ if (i != -1) diff -u libmagic.orig/softmagic.c libmagic/softmagic.c ---- libmagic.orig/softmagic.c 2024-11-27 16:37:00.000000000 +0100 -+++ libmagic/softmagic.c 2025-02-09 01:21:46.845689318 +0100 +--- libmagic.orig/softmagic.c 2024-11-27 10:37:00.000000000 -0500 ++++ libmagic/softmagic.c 2026-03-19 16:25:42.986672670 -0400 @@ -32,7 +32,7 @@ #include "file.h" diff --git a/ext/fileinfo/libmagic/config.h b/ext/fileinfo/libmagic/config.h index 4af6e06c4127..34a10d59faa1 100644 --- a/ext/fileinfo/libmagic/config.h +++ b/ext/fileinfo/libmagic/config.h @@ -2,11 +2,7 @@ #include "php_libmagic.h" #ifndef HAVE_STDINT_H -#define HAVE_STDINT_H 1 -#endif - -#ifndef HAVE_STDINT_H -#define HAVE_STDINT_H 1 +# define HAVE_STDINT_H 1 #endif #ifndef HAVE_VISIBILITY diff --git a/ext/fileinfo/libmagic/file.h b/ext/fileinfo/libmagic/file.h index f8fe58895002..5357578c6a77 100644 --- a/ext/fileinfo/libmagic/file.h +++ b/ext/fileinfo/libmagic/file.h @@ -102,12 +102,12 @@ #if HAVE_VISIBILITY # if defined(WIN32) -# define file_public __declspec(dllexport) +# define file_public # ifndef file_protected # define file_protected # endif # else -# define file_public __attribute__((__visibility__("default"))) +# define file_public __attribute__((__visibility__("hidden"))) # ifndef file_protected # define file_protected __attribute__((__visibility__("hidden"))) # endif @@ -635,9 +635,6 @@ size_t strlcpy(char *, const char *, size_t); #ifndef HAVE_STRLCAT size_t strlcat(char *, const char *, size_t); #endif -#ifndef HAVE_STRCASESTR -char *strcasestr(const char *, const char *); -#endif #ifndef HAVE_GETLINE ssize_t getline(char **, size_t *, FILE *); ssize_t getdelim(char **, size_t *, int, FILE *); diff --git a/ext/fileinfo/php_fileinfo.h b/ext/fileinfo/php_fileinfo.h index a0536294429b..50de6f79a537 100644 --- a/ext/fileinfo/php_fileinfo.h +++ b/ext/fileinfo/php_fileinfo.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ diff --git a/ext/fileinfo/php_libmagic.c b/ext/fileinfo/php_libmagic.c index 05123fa8133a..efb78653c211 100644 --- a/ext/fileinfo/php_libmagic.c +++ b/ext/fileinfo/php_libmagic.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/fileinfo/php_libmagic.h b/ext/fileinfo/php_libmagic.h index 23d0c3e8eaa1..59e8e091a487 100644 --- a/ext/fileinfo/php_libmagic.h +++ b/ext/fileinfo/php_libmagic.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/fileinfo/tests/finfo_buffer_deprecated_context_param.phpt b/ext/fileinfo/tests/finfo_buffer_deprecated_context_param.phpt new file mode 100644 index 000000000000..ef4c736999d8 --- /dev/null +++ b/ext/fileinfo/tests/finfo_buffer_deprecated_context_param.phpt @@ -0,0 +1,20 @@ +--TEST-- +finfo_buffer() deprecated $context param +--EXTENSIONS-- +fileinfo +--FILE-- +buffer($buffer, FILEINFO_NONE, null)); + +?> +--EXPECTF-- +Deprecated: finfo_buffer(): The $context parameter has no effect for finfo_buffer() in %s on line %d +string(36) "ASCII text, with no line terminators" + +Deprecated: finfo::buffer(): The $context parameter has no effect for finfo_buffer() in %s on line %d +string(36) "ASCII text, with no line terminators" diff --git a/ext/fileinfo/tests/finfo_close_basic.phpt b/ext/fileinfo/tests/finfo_close_basic.phpt index cdaf4b23b000..1abd7216390d 100644 --- a/ext/fileinfo/tests/finfo_close_basic.phpt +++ b/ext/fileinfo/tests/finfo_close_basic.phpt @@ -23,6 +23,8 @@ unset( $finfo ); *** Testing finfo_close() : basic functionality *** object(finfo)#%d (0) { } + +Deprecated: Function finfo_close() is deprecated since 8.5, as finfo objects are freed automatically in %s on line %d bool(true) object(finfo)#%d (%d) { } diff --git a/ext/fileinfo/tests/finfo_close_error.phpt b/ext/fileinfo/tests/finfo_close_error.phpt index c43597f26a4e..c7873b462724 100644 --- a/ext/fileinfo/tests/finfo_close_error.phpt +++ b/ext/fileinfo/tests/finfo_close_error.phpt @@ -15,8 +15,10 @@ try { } ?> ---EXPECT-- +--EXPECTF-- *** Testing finfo_close() : error conditions *** -- Testing finfo_close() function with wrong resource type -- + +Deprecated: Function finfo_close() is deprecated since 8.5, as finfo objects are freed automatically in %s on line %d finfo_close(): Argument #1 ($finfo) must be of type finfo, resource given diff --git a/ext/fileinfo/tests/finfo_upstream.phpt b/ext/fileinfo/tests/finfo_upstream.phpt index 2a28bd7f776c..ff1c1b161404 100644 --- a/ext/fileinfo/tests/finfo_upstream.phpt +++ b/ext/fileinfo/tests/finfo_upstream.phpt @@ -2,6 +2,12 @@ Fileinfo run upstream tests --EXTENSIONS-- fileinfo +--SKIPIF-- + --ENV-- TZ=UTC --FILE-- diff --git a/ext/fileinfo/tests/magic b/ext/fileinfo/tests/magic index e8ad0f0ce784..c8783aea05c7 100644 --- a/ext/fileinfo/tests/magic +++ b/ext/fileinfo/tests/magic @@ -39944,7 +39944,7 @@ # look for archive member RunTime.xml like in Microsoft.Windows.Cosa.Desktop.Client.ppkg >>>156 search/68233/s RunTime.xml \bWindows provisioning package) !:ext ppkg -# if is is not a Windows provisioning package, then it is a WIM +# if it is not a Windows provisioning package, then it is a WIM >>>156 default x \bWIM) image # second disk image part created by Microsoft's RecoveryDrive.exe has name Reconstruct.WIM2 !:ext wim/wim2 diff --git "a/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" "b/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" index e8ad0f0ce784..c8783aea05c7 100644 --- "a/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" +++ "b/ext/fileinfo/tests/magic\347\247\201\343\201\257\343\202\254\343\203\251\343\202\271\343\202\222\351\243\237\343\201\271\343\202\211\343\202\214\343\201\276\343\201\231" @@ -39944,7 +39944,7 @@ # look for archive member RunTime.xml like in Microsoft.Windows.Cosa.Desktop.Client.ppkg >>>156 search/68233/s RunTime.xml \bWindows provisioning package) !:ext ppkg -# if is is not a Windows provisioning package, then it is a WIM +# if it is not a Windows provisioning package, then it is a WIM >>>156 default x \bWIM) image # second disk image part created by Microsoft's RecoveryDrive.exe has name Reconstruct.WIM2 !:ext wim/wim2 diff --git a/ext/fileinfo/tests/remote_resource.phpt b/ext/fileinfo/tests/remote_resource.phpt new file mode 100644 index 000000000000..b443393f826b --- /dev/null +++ b/ext/fileinfo/tests/remote_resource.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-20679 (finfo_file() doesn't work on remote resources) +--EXTENSIONS-- +fileinfo +--INI-- +allow_url_fopen=1 +--SKIPIF-- + +--FILE-- + $pid, 'uri' => $uri] = http_server([ + "data://text/plain,HTTP/1.0 200 Ok\r\n\r\nfoo", +], $output); + +$f = finfo_open(); +var_dump(finfo_file($f, $uri)); + +http_server_kill($pid); +?> +--EXPECT-- +string(51) "HTML document, ASCII text, with no line terminators" diff --git a/ext/filter/callback_filter.c b/ext/filter/callback_filter.c index b6d57739b2b9..688cbf072175 100644 --- a/ext/filter/callback_filter.c +++ b/ext/filter/callback_filter.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | +----------------------------------------------------------------------+ @@ -16,25 +14,25 @@ #include "php_filter.h" -void php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL) { zval retval; - int status; + zend_fcall_info_cache fcc; - if (!option_array || !zend_is_callable(option_array, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL)) { + if (!option_array || !zend_is_callable_ex(option_array, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL)) { zend_type_error("%s(): Option must be a valid callback", get_active_function_name()); zval_ptr_dtor(value); ZVAL_NULL(value); - return; + return SUCCESS; } - status = call_user_function(NULL, NULL, option_array, &retval, 1, value); + zend_call_known_fcc(&fcc, &retval, 1, value, NULL); + zval_ptr_dtor(value); - if (status == SUCCESS && !Z_ISUNDEF(retval)) { - zval_ptr_dtor(value); + if (!Z_ISUNDEF(retval)) { ZVAL_COPY_VALUE(value, &retval); } else { - zval_ptr_dtor(value); ZVAL_NULL(value); } + return SUCCESS; } diff --git a/ext/filter/filter.c b/ext/filter/filter.c index 50eefb440d67..9dbd6dceda53 100644 --- a/ext/filter/filter.c +++ b/ext/filter/filter.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Derick Rethans | @@ -27,13 +25,15 @@ ZEND_DECLARE_MODULE_GLOBALS(filter) +#include "zend_attributes.h" #include "filter_private.h" #include "filter_arginfo.h" +#include "zend_exceptions.h" typedef struct filter_list_entry { const char *name; int id; - void (*function)(PHP_INPUT_FILTER_PARAM_DECL); + zend_result (*function)(PHP_INPUT_FILTER_PARAM_DECL); } filter_list_entry; /* {{{ filter_list */ @@ -76,6 +76,9 @@ static const filter_list_entry filter_list[] = { static unsigned int php_sapi_filter(int arg, const char *var, char **val, size_t val_len, size_t *new_val_len); static unsigned int php_sapi_filter_init(void); +zend_class_entry *php_filter_exception_ce; +zend_class_entry *php_filter_failed_exception_ce; + /* {{{ filter_module_entry */ zend_module_entry filter_module_entry = { STANDARD_MODULE_HEADER, @@ -159,6 +162,9 @@ PHP_MINIT_FUNCTION(filter) sapi_register_input_filter(php_sapi_filter, php_sapi_filter_init); + php_filter_exception_ce = register_class_Filter_FilterException(zend_ce_exception); + php_filter_failed_exception_ce = register_class_Filter_FilterFailedException(php_filter_exception_ce); + return SUCCESS; } /* }}} */ @@ -250,6 +256,16 @@ static void php_zval_filter(zval *value, zend_long filter, zend_long flags, zval ce = Z_OBJCE_P(value); if (!ce->__tostring) { zval_ptr_dtor(value); + if (flags & FILTER_THROW_ON_FAILURE) { + zend_throw_exception_ex( + php_filter_failed_exception_ce, + 0, + "filter validation failed: object of type %s has no __toString() method", + ZSTR_VAL(ce->name) + ); + ZVAL_NULL(value); + return; + } /* #67167: doesn't return null on failure for objects */ if (flags & FILTER_NULL_ON_FAILURE) { ZVAL_NULL(value); @@ -263,7 +279,29 @@ static void php_zval_filter(zval *value, zend_long filter, zend_long flags, zval /* Here be strings */ convert_to_string(value); - filter_func.function(value, flags, options, charset); + zend_string *copy_for_throwing = NULL; + if (flags & FILTER_THROW_ON_FAILURE) { + copy_for_throwing = zend_string_copy(Z_STR_P(value)); + } + + zend_result result = filter_func.function(value, flags, options, charset); + + if (flags & FILTER_THROW_ON_FAILURE) { + ZEND_ASSERT(copy_for_throwing != NULL); + if (result == FAILURE) { + zend_throw_exception_ex( + php_filter_failed_exception_ce, + 0, + "filter validation failed: filter %s not satisfied by '%s'", + filter_func.name, + ZSTR_VAL(copy_for_throwing) + ); + zend_string_delref(copy_for_throwing); + return; + } + zend_string_delref(copy_for_throwing); + copy_for_throwing = NULL; + } handle_default: if (options && Z_TYPE_P(options) == IS_ARRAY && @@ -439,17 +477,14 @@ PHP_FUNCTION(filter_has_var) RETURN_THROWS(); } - if (array_ptr && zend_hash_exists(Z_ARRVAL_P(array_ptr), var)) { - RETURN_TRUE; - } - - RETURN_FALSE; + RETURN_BOOL(array_ptr && zend_hash_exists(Z_ARRVAL_P(array_ptr), var)); } /* }}} */ static void php_filter_call( zval *filtered, zend_long filter, HashTable *filter_args_ht, zend_long filter_args_long, - zend_long filter_flags + zend_long filter_flags, + uint32_t options_arg_num ) /* {{{ */ { zval *options = NULL; char *charset = NULL; @@ -491,10 +526,28 @@ static void php_filter_call( } } + /* Cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE */ + if ((filter_flags & FILTER_NULL_ON_FAILURE) && (filter_flags & FILTER_THROW_ON_FAILURE)) { + zval_ptr_dtor(filtered); + ZVAL_NULL(filtered); + zend_argument_value_error( + options_arg_num, + "cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE" + ); + return; + } + if (Z_TYPE_P(filtered) == IS_ARRAY) { if (filter_flags & FILTER_REQUIRE_SCALAR) { zval_ptr_dtor(filtered); - if (filter_flags & FILTER_NULL_ON_FAILURE) { + if (filter_flags & FILTER_THROW_ON_FAILURE) { + ZVAL_NULL(filtered); + zend_throw_exception( + php_filter_failed_exception_ce, + "filter validation failed: not a scalar value (got an array)", + 0 + ); + } else if (filter_flags & FILTER_NULL_ON_FAILURE) { ZVAL_NULL(filtered); } else { ZVAL_FALSE(filtered); @@ -505,6 +558,17 @@ static void php_filter_call( return; } if (filter_flags & FILTER_REQUIRE_ARRAY) { + if (filter_flags & FILTER_THROW_ON_FAILURE) { + zend_throw_exception_ex( + php_filter_failed_exception_ce, + 0, + "filter validation failed: not an array (got %s)", + zend_zval_value_name(filtered) + ); + zval_ptr_dtor(filtered); + ZVAL_NULL(filtered); + return; + } zval_ptr_dtor(filtered); if (filter_flags & FILTER_NULL_ON_FAILURE) { ZVAL_NULL(filtered); @@ -515,6 +579,10 @@ static void php_filter_call( } php_zval_filter(filtered, filter, filter_flags, options, charset); + /* Don't wrap in an array if we are throwing an exception */ + if (EG(exception)) { + return; + } if (filter_flags & FILTER_FORCE_ARRAY) { zval tmp; ZVAL_COPY_VALUE(&tmp, filtered); @@ -529,7 +597,7 @@ static void php_filter_array_handler(zval *input, HashTable *op_ht, zend_long op ) /* {{{ */ { if (!op_ht) { ZVAL_DUP(return_value, input); - php_filter_call(return_value, -1, NULL, op_long, FILTER_REQUIRE_ARRAY); + php_filter_call(return_value, -1, NULL, op_long, FILTER_REQUIRE_ARRAY, 2); } else { array_init(return_value); zend_string *arg_key; @@ -553,11 +621,23 @@ static void php_filter_array_handler(zval *input, HashTable *op_ht, zend_long op zval nval; ZVAL_DEREF(tmp); ZVAL_DUP(&nval, tmp); + + if (Z_TYPE_P(arg_elm) != IS_ARRAY) { + zend_long filter_id = zval_get_long(arg_elm); + if (!PHP_FILTER_ID_EXISTS(filter_id)) { + php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, filter_id); + } + } + php_filter_call(&nval, -1, Z_TYPE_P(arg_elm) == IS_ARRAY ? Z_ARRVAL_P(arg_elm) : NULL, Z_TYPE_P(arg_elm) == IS_ARRAY ? 0 : zval_get_long(arg_elm), - FILTER_REQUIRE_SCALAR + FILTER_REQUIRE_SCALAR, + 2 ); + if (EG(exception)) { + RETURN_THROWS(); + } zend_hash_update(Z_ARRVAL_P(return_value), arg_key, &nval); } } ZEND_HASH_FOREACH_END(); @@ -597,11 +677,35 @@ PHP_FUNCTION(filter_input) if (!filter_args_ht) { filter_flags = filter_args_long; } else { - zval *option, *opt, *def; + zval *option; if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) { filter_flags = zval_get_long(option); } + } + + /* Cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE */ + if ((filter_flags & FILTER_NULL_ON_FAILURE) && (filter_flags & FILTER_THROW_ON_FAILURE)) { + zend_argument_value_error( + 4, + "cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE" + ); + RETURN_THROWS(); + } + if (filter_flags & FILTER_THROW_ON_FAILURE) { + zend_throw_exception_ex( + php_filter_failed_exception_ce, + 0, + "input value '%s' not found", + ZSTR_VAL(var) + ); + RETURN_THROWS(); + } + + /* FILTER_THROW_ON_FAILURE overrides defaults, needs to be checked + * before the default is used. */ + if (filter_args_ht) { + zval *opt, *def; if ((opt = zend_hash_str_find_deref(filter_args_ht, "options", sizeof("options") - 1)) != NULL && Z_TYPE_P(opt) == IS_ARRAY && (def = zend_hash_str_find_deref(Z_ARRVAL_P(opt), "default", sizeof("default") - 1)) != NULL @@ -625,7 +729,7 @@ PHP_FUNCTION(filter_input) ZVAL_DUP(return_value, tmp); - php_filter_call(return_value, filter, filter_args_ht, filter_args_long, FILTER_REQUIRE_SCALAR); + php_filter_call(return_value, filter, filter_args_ht, filter_args_long, FILTER_REQUIRE_SCALAR, 4); } /* }}} */ @@ -651,7 +755,7 @@ PHP_FUNCTION(filter_var) ZVAL_DUP(return_value, data); - php_filter_call(return_value, filter, filter_args_ht, filter_args_long, FILTER_REQUIRE_SCALAR); + php_filter_call(return_value, filter, filter_args_ht, filter_args_long, FILTER_REQUIRE_SCALAR, 3); } /* }}} */ @@ -719,9 +823,7 @@ PHP_FUNCTION(filter_list) { int size = sizeof(filter_list) / sizeof(filter_list_entry); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); for (int i = 0; i < size; ++i) { diff --git a/ext/filter/filter.stub.php b/ext/filter/filter.stub.php index 030de50f5189..4332f9261e98 100644 --- a/ext/filter/filter.stub.php +++ b/ext/filter/filter.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +namespace { /** * @var int * @cvalue PARSE_POST @@ -54,6 +55,11 @@ * @cvalue FILTER_NULL_ON_FAILURE */ const FILTER_NULL_ON_FAILURE = UNKNOWN; +/** + * @var int + * @cvalue FILTER_THROW_ON_FAILURE + */ +const FILTER_THROW_ON_FAILURE = UNKNOWN; /** * @var int @@ -121,14 +127,14 @@ /** * @var int * @cvalue FILTER_SANITIZE_STRING - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'use htmlspecialchars() instead')] const FILTER_SANITIZE_STRING = UNKNOWN; /** * @var int * @cvalue FILTER_SANITIZE_STRING - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'use htmlspecialchars() instead')] const FILTER_SANITIZE_STRIPPED = UNKNOWN; /** * @var int @@ -313,3 +319,13 @@ function filter_var_array(array $array, array|int $options = FILTER_DEFAULT, boo function filter_list(): array {} function filter_id(string $name): int|false {} + +} + +namespace Filter { + + class FilterException extends \Exception {} + + class FilterFailedException extends FilterException {} + +} diff --git a/ext/filter/filter_arginfo.h b/ext/filter/filter_arginfo.h index a05806c5e120..4e24ede41a63 100644 --- a/ext/filter/filter_arginfo.h +++ b/ext/filter/filter_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: c3f3240137eaa89316276920acf35f975b2dd8f9 */ +/* This is a generated file, edit filter.stub.php instead. + * Stub hash: c3eb55dfec619af1e46be206f51a2b0893ed399f */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_has_var, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, input_type, IS_LONG, 0) @@ -69,6 +69,7 @@ static void register_filter_symbols(int module_number) REGISTER_LONG_CONSTANT("FILTER_REQUIRE_ARRAY", FILTER_REQUIRE_ARRAY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FORCE_ARRAY", FILTER_FORCE_ARRAY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_NULL_ON_FAILURE", FILTER_NULL_ON_FAILURE, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_THROW_ON_FAILURE", FILTER_THROW_ON_FAILURE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_VALIDATE_INT", FILTER_VALIDATE_INT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_VALIDATE_BOOLEAN", FILTER_VALIDATE_BOOL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_VALIDATE_BOOL", FILTER_VALIDATE_BOOL, CONST_PERSISTENT); @@ -81,8 +82,8 @@ static void register_filter_symbols(int module_number) REGISTER_LONG_CONSTANT("FILTER_VALIDATE_MAC", FILTER_VALIDATE_MAC, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_DEFAULT", FILTER_DEFAULT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_UNSAFE_RAW", FILTER_UNSAFE_RAW, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRING", FILTER_SANITIZE_STRING, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRIPPED", FILTER_SANITIZE_STRING, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_FILTER_SANITIZE_STRING = REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRING", FILTER_SANITIZE_STRING, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_FILTER_SANITIZE_STRIPPED = REGISTER_LONG_CONSTANT("FILTER_SANITIZE_STRIPPED", FILTER_SANITIZE_STRING, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("FILTER_SANITIZE_ENCODED", FILTER_SANITIZE_ENCODED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_SANITIZE_SPECIAL_CHARS", FILTER_SANITIZE_SPECIAL_CHARS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_SANITIZE_FULL_SPECIAL_CHARS", FILTER_SANITIZE_FULL_SPECIAL_CHARS, CONST_PERSISTENT); @@ -114,4 +115,38 @@ static void register_filter_symbols(int module_number) REGISTER_LONG_CONSTANT("FILTER_FLAG_GLOBAL_RANGE", FILTER_FLAG_GLOBAL_RANGE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_HOSTNAME", FILTER_FLAG_HOSTNAME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_EMAIL_UNICODE", FILTER_FLAG_EMAIL_UNICODE, CONST_PERSISTENT); + + + zend_attribute *attribute_Deprecated_const_FILTER_SANITIZE_STRING_0 = zend_add_global_constant_attribute(const_FILTER_SANITIZE_STRING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1_str = zend_string_init("use htmlspecialchars() instead", strlen("use htmlspecialchars() instead"), 1); + ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[1].value, attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1_str); + attribute_Deprecated_const_FILTER_SANITIZE_STRING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0 = zend_add_global_constant_attribute(const_FILTER_SANITIZE_STRIPPED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[1].value, attribute_Deprecated_const_FILTER_SANITIZE_STRING_0_arg1_str); + attribute_Deprecated_const_FILTER_SANITIZE_STRIPPED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +} + +static zend_class_entry *register_class_Filter_FilterException(zend_class_entry *class_entry_Exception) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Filter", "FilterException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Exception, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Filter_FilterFailedException(zend_class_entry *class_entry_Filter_FilterException) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Filter", "FilterFailedException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Filter_FilterException, 0); + + return class_entry; } diff --git a/ext/filter/filter_private.h b/ext/filter/filter_private.h index a1bbb500f8db..14975e7911a4 100644 --- a/ext/filter/filter_private.h +++ b/ext/filter/filter_private.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | +----------------------------------------------------------------------+ @@ -24,6 +22,7 @@ #define FILTER_FORCE_ARRAY 0x4000000 #define FILTER_NULL_ON_FAILURE 0x8000000 +#define FILTER_THROW_ON_FAILURE 0x10000000 #define FILTER_FLAG_ALLOW_OCTAL 0x0001 #define FILTER_FLAG_ALLOW_HEX 0x0002 @@ -50,7 +49,7 @@ #define FILTER_FLAG_IPV6 0x00200000 #define FILTER_FLAG_NO_RES_RANGE 0x00400000 #define FILTER_FLAG_NO_PRIV_RANGE 0x00800000 -#define FILTER_FLAG_GLOBAL_RANGE 0x10000000 +#define FILTER_FLAG_GLOBAL_RANGE 0x20000000 #define FILTER_FLAG_HOSTNAME 0x100000 @@ -93,9 +92,18 @@ || (id >= FILTER_VALIDATE_ALL && id <= FILTER_VALIDATE_LAST) \ || id == FILTER_CALLBACK) + +/* When using FILTER_THROW_ON_FAILURE, we can't actually throw the error here + * because we don't have access to the name of the filter. Returning FAILURE + * from the filter handler indicates that validation failed *and* an exception + * should thus be thrown. */ #define RETURN_VALIDATION_FAILED \ if (EG(exception)) { \ - return; \ + return SUCCESS; \ + } else if (flags & FILTER_THROW_ON_FAILURE) { \ + zval_ptr_dtor(value); \ + ZVAL_NULL(value); \ + return FAILURE; \ } else if (flags & FILTER_NULL_ON_FAILURE) { \ zval_ptr_dtor(value); \ ZVAL_NULL(value); \ @@ -103,7 +111,7 @@ zval_ptr_dtor(value); \ ZVAL_FALSE(value); \ } \ - return; \ + return SUCCESS; \ #define PHP_FILTER_TRIM_DEFAULT(p, len) PHP_FILTER_TRIM_DEFAULT_EX(p, len, 1); diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 0dd307122345..45acf6d47541 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | | Pierre-A. Joye | @@ -16,10 +14,11 @@ +----------------------------------------------------------------------+ */ +#include "zend_exceptions.h" #include "php_filter.h" #include "filter_private.h" -#include "ext/standard/url.h" #include "ext/pcre/php_pcre.h" +#include "ext/uri/php_uri.h" #include "zend_multiply.h" @@ -89,6 +88,8 @@ #define FORMAT_IPV4 4 #define FORMAT_IPV6 6 +#define URL_OPTION_URI_PARSER_CLASS "uri_parser_class" + static bool _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]); static bool php_filter_parse_int(const char *str, size_t str_len, zend_long *ret) { /* {{{ */ @@ -195,7 +196,7 @@ static bool php_filter_parse_hex(const char *str, size_t str_len, zend_long *ret } /* }}} */ -void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_int(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { zval *option_val; zend_long min_range, max_range, option_flags; @@ -266,12 +267,12 @@ void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } else { zval_ptr_dtor(value); ZVAL_LONG(value, ctx_value); - return; } + return SUCCESS; } /* }}} */ -void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { const char *str = Z_STRVAL_P(value); size_t len = Z_STRLEN_P(value); @@ -337,10 +338,11 @@ void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ zval_ptr_dtor(value); ZVAL_BOOL(value, ret); } + return SUCCESS; } /* }}} */ -void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { size_t len; const char *str, *end; @@ -467,10 +469,11 @@ void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ RETURN_VALIDATION_FAILED } efree(num); + return SUCCESS; } /* }}} */ -void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { zval *option_val; zend_string *regexp; @@ -503,6 +506,7 @@ void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ if (rc < 0) { RETURN_VALIDATION_FAILED } + return SUCCESS; } static bool php_filter_validate_domain_ex(const zend_string *domain, zend_long flags) /* {{{ */ @@ -529,21 +533,21 @@ static bool php_filter_validate_domain_ex(const zend_string *domain, zend_long f } /* First char must be alphanumeric */ - if(*s == '.' || (hostname && !isalnum((int)*(unsigned char *)s))) { + if(*s == '.' || (hostname && !isalnum((unsigned char)*s))) { return false; } while (s < e) { if (*s == '.') { /* The first and the last character of a label must be alphanumeric */ - if (*(s + 1) == '.' || (hostname && (!isalnum((int)*(unsigned char *)(s - 1)) || !isalnum((int)*(unsigned char *)(s + 1))))) { + if (*(s + 1) == '.' || (hostname && (!isalnum((unsigned char)s[-1]) || !isalnum((unsigned char)s[1])))) { return false; } /* Reset label length counter */ i = 1; } else { - if (i > 63 || (hostname && (*s != '-' || *(s + 1) == '\0') && !isalnum((int)*(unsigned char *)s))) { + if (i > 63 || (hostname && (*s != '-' || *(s + 1) == '\0') && !isalnum((unsigned char)*s))) { return false; } @@ -557,11 +561,12 @@ static bool php_filter_validate_domain_ex(const zend_string *domain, zend_long f } /* }}} */ -void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { if (!php_filter_validate_domain_ex(Z_STR_P(value), flags)) { RETURN_VALIDATION_FAILED } + return SUCCESS; } /* }}} */ @@ -570,9 +575,9 @@ static bool is_userinfo_valid(const zend_string *str) const char *p = ZSTR_VAL(str); while (p - ZSTR_VAL(str) < ZSTR_LEN(str)) { static const char *valid = "-._~!$&'()*+,;=:"; - if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) { + if (isalpha((unsigned char)*p) || isdigit((unsigned char)*p) || strchr(valid, *p)) { p++; - } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) { + } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 3 && isdigit((unsigned char)p[1]) && isxdigit((unsigned char)p[2])) { p += 3; } else { return false; @@ -589,9 +594,8 @@ static bool php_filter_is_valid_ipv6_hostname(const zend_string *s) return *ZSTR_VAL(s) == '[' && *t == ']' && _php_filter_validate_ipv6(ZSTR_VAL(s) + 1, ZSTR_LEN(s) - 2, NULL); } -void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { - php_url *url; size_t old_len = Z_STRLEN_P(value); php_filter_url(value, flags, option_array, charset); @@ -600,56 +604,71 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ RETURN_VALIDATION_FAILED } - /* Use parse_url - if it returns false, we return NULL */ - url = php_url_parse_ex(Z_STRVAL_P(value), Z_STRLEN_P(value)); + /* Parse options */ + zval *option_val; + zend_string *parser_name; + int parser_name_set; + FETCH_STR_OPTION(parser_name, URL_OPTION_URI_PARSER_CLASS); + + const php_uri_parser *uri_parser = php_uri_get_parser(parser_name_set ? parser_name : NULL); + if (uri_parser == NULL) { + zend_value_error("%s(): \"uri_parser_class\" option has invalid value", get_active_function_name()); + RETURN_VALIDATION_FAILED + } - if (url == NULL) { + /* Parse the URI - if it fails, we return NULL */ + php_uri *uri = php_uri_parse_to_struct(uri_parser, Z_STRVAL_P(value), Z_STRLEN_P(value), PHP_URI_COMPONENT_READ_MODE_RAW, true); + if (uri == NULL) { RETURN_VALIDATION_FAILED } - if (url->scheme != NULL && - (zend_string_equals_literal_ci(url->scheme, "http") || zend_string_equals_literal_ci(url->scheme, "https"))) { + if (uri->scheme != NULL && + (zend_string_equals_literal_ci(uri->scheme, "http") || zend_string_equals_literal_ci(uri->scheme, "https"))) { - if (url->host == NULL) { - goto bad_url; + if (uri->host == NULL) { + php_uri_struct_free(uri); + RETURN_VALIDATION_FAILED } if ( + /* Skipping these checks is possible because the new URI implementations perform comprehensive validations. */ + strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0 && /* An IPv6 enclosed by square brackets is a valid hostname.*/ - !php_filter_is_valid_ipv6_hostname(url->host) && + !php_filter_is_valid_ipv6_hostname(uri->host) && /* Validate domain. * This includes a loose check for an IPv4 address. */ - !php_filter_validate_domain_ex(url->host, FILTER_FLAG_HOSTNAME) + !php_filter_validate_domain_ex(uri->host, FILTER_FLAG_HOSTNAME) ) { - php_url_free(url); + php_uri_struct_free(uri); RETURN_VALIDATION_FAILED } } - if ( - url->scheme == NULL || - /* some schemas allow the host to be empty */ - (url->host == NULL && (!zend_string_equals_literal(url->scheme, "mailto") && !zend_string_equals_literal(url->scheme, "news") && !zend_string_equals_literal(url->scheme, "file"))) || - ((flags & FILTER_FLAG_PATH_REQUIRED) && url->path == NULL) || ((flags & FILTER_FLAG_QUERY_REQUIRED) && url->query == NULL) + if (uri->scheme == NULL || + /* some schemes allow the host to be empty */ + (uri->host == NULL && (!zend_string_equals_literal(uri->scheme, "mailto") && !zend_string_equals_literal(uri->scheme, "news") && !zend_string_equals_literal(uri->scheme, "file"))) || + ((flags & FILTER_FLAG_PATH_REQUIRED) && uri->path == NULL) || ((flags & FILTER_FLAG_QUERY_REQUIRED) && uri->query == NULL) ) { -bad_url: - php_url_free(url); + php_uri_struct_free(uri); RETURN_VALIDATION_FAILED } - if ((url->user != NULL && !is_userinfo_valid(url->user)) - || (url->pass != NULL && !is_userinfo_valid(url->pass)) + if (strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0 && + ( + (uri->user != NULL && !is_userinfo_valid(uri->user)) || + (uri->password != NULL && !is_userinfo_valid(uri->password)) + ) ) { - php_url_free(url); + php_uri_struct_free(uri); RETURN_VALIDATION_FAILED - } - php_url_free(url); + php_uri_struct_free(uri); + return SUCCESS; } /* }}} */ -void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { /* * The regex below is based on a regex by Michael Rushton. @@ -715,6 +734,7 @@ void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ if (rc < 0) { RETURN_VALIDATION_FAILED } + return SUCCESS; } /* }}} */ @@ -766,7 +786,7 @@ static bool _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8] const char *s = str; if (!memchr(str, ':', str_len)) { - return 0; + return false; } /* check for bundled IPv4 */ @@ -777,12 +797,12 @@ static bool _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8] } if (!_php_filter_validate_ipv4(ipv4, (str_len - (ipv4 - str)), ip4elm)) { - return 0; + return false; } str_len = ipv4 - str; /* length excluding ipv4 */ if (str_len < 2) { - return 0; + return false; } if (ipv4[-2] != ':') { @@ -975,7 +995,7 @@ static bool ipv6_get_status_flags(const int ip[8], bool *global, bool *reserved, * to throw out reserved ranges; multicast ranges... etc. If both allow_ipv4 * and allow_ipv6 flags flag are used, then the first dot or colon determine * the format */ -void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { int ip[8]; int mode; @@ -1003,7 +1023,7 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } if (!ipv4_get_status_flags(ip, &flag_global, &flag_reserved, &flag_private)) { - return; /* no special block */ + return SUCCESS; /* no special block */ } } else if (mode == FORMAT_IPV6) { @@ -1012,7 +1032,7 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } if (!ipv6_get_status_flags(ip, &flag_global, &flag_reserved, &flag_private)) { - return; /* no special block */ + return SUCCESS; /* no special block */ } } @@ -1027,10 +1047,11 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ if ((flags & FILTER_FLAG_NO_RES_RANGE) && flag_reserved == true) { RETURN_VALIDATION_FAILED } + return SUCCESS; } /* }}} */ -void php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +zend_result php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { const char *input = Z_STRVAL_P(value); size_t input_len = Z_STRLEN_P(value); @@ -1089,5 +1110,6 @@ void php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ RETURN_VALIDATION_FAILED } } + return SUCCESS; } /* }}} */ diff --git a/ext/filter/php_filter.h b/ext/filter/php_filter.h index f782907898fc..ccf8b6b4883f 100644 --- a/ext/filter/php_filter.h +++ b/ext/filter/php_filter.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Derick Rethans | @@ -53,27 +51,27 @@ ZEND_TSRMLS_CACHE_EXTERN() #define IF_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(filter, v) #define PHP_INPUT_FILTER_PARAM_DECL zval *value, zend_long flags, zval *option_array, char *charset -void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_int(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_float(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_add_slashes(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_string(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_email(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_url(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_add_slashes(PHP_INPUT_FILTER_PARAM_DECL); -void php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL); +zend_result php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL); #endif /* FILTER_H */ diff --git a/ext/filter/sanitizing_filters.c b/ext/filter/sanitizing_filters.c index ebc20e47711d..456b138ca934 100644 --- a/ext/filter/sanitizing_filters.c +++ b/ext/filter/sanitizing_filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Derick Rethans | +----------------------------------------------------------------------+ @@ -168,7 +166,7 @@ static void filter_map_apply(zval *value, const filter_map *map) /* }}} */ /* {{{ php_filter_string */ -void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_string(PHP_INPUT_FILTER_PARAM_DECL) { size_t new_len; unsigned char enc[256] = {0}; @@ -206,23 +204,24 @@ void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL) } else { ZVAL_EMPTY_STRING(value); } - return; } + return SUCCESS; } /* }}} */ /* {{{ php_filter_encoded */ -void php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL) { /* apply strip_high and strip_low filters */ php_filter_strip(value, flags); /* urlencode */ php_filter_encode_url(value, (unsigned char *)DEFAULT_URL_ENCODE, sizeof(DEFAULT_URL_ENCODE)-1); + return SUCCESS; } /* }}} */ /* {{{ php_filter_special_chars */ -void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL) { unsigned char enc[256] = {0}; @@ -239,11 +238,12 @@ void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL) } php_filter_encode_html(value, enc); + return SUCCESS; } /* }}} */ /* {{{ php_filter_full_special_chars */ -void php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL) { zend_string *buf; int quotes; @@ -258,11 +258,12 @@ void php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL) /* charset_hint */ NULL, /* double_encode */ 0, /* quiet */ 0); zval_ptr_dtor(value); ZVAL_STR(value, buf); + return SUCCESS; } /* }}} */ /* {{{ php_filter_unsafe_raw */ -void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL) { /* Only if no flags are set (optimization) */ if (flags != 0 && Z_STRLEN_P(value) > 0) { @@ -285,6 +286,7 @@ void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL) zval_ptr_dtor(value); ZVAL_NULL(value); } + return SUCCESS; } /* }}} */ @@ -295,7 +297,7 @@ void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL) #define PUNCTUATION "<>#%\"" #define RESERVED ";/?:@&=" -void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_email(PHP_INPUT_FILTER_PARAM_DECL) { /* Check section 6 of rfc 822 http://www.faqs.org/rfcs/rfc822.html */ const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT "!#$%&'*+-=?^_`{|}~@.[]"; @@ -304,11 +306,12 @@ void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL) filter_map_init(&map); filter_map_update(&map, 1, allowed_list); filter_map_apply(value, &map); + return SUCCESS; } /* }}} */ /* {{{ php_filter_url */ -void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_url(PHP_INPUT_FILTER_PARAM_DECL) { /* Strip all chars not part of section 5 of * http://www.faqs.org/rfcs/rfc1738.html */ @@ -318,11 +321,12 @@ void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL) filter_map_init(&map); filter_map_update(&map, 1, allowed_list); filter_map_apply(value, &map); + return SUCCESS; } /* }}} */ /* {{{ php_filter_number_int */ -void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL) { /* strip everything [^0-9+-] */ const unsigned char allowed_list[] = "+-" DIGIT; @@ -331,11 +335,12 @@ void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL) filter_map_init(&map); filter_map_update(&map, 1, allowed_list); filter_map_apply(value, &map); + return SUCCESS; } /* }}} */ /* {{{ php_filter_number_float */ -void php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL) { /* strip everything [^0-9+-] */ const unsigned char allowed_list[] = "+-" DIGIT; @@ -355,15 +360,17 @@ void php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL) filter_map_update(&map, 4, (const unsigned char *) "eE"); } filter_map_apply(value, &map); + return SUCCESS; } /* }}} */ /* {{{ php_filter_add_slashes */ -void php_filter_add_slashes(PHP_INPUT_FILTER_PARAM_DECL) +zend_result php_filter_add_slashes(PHP_INPUT_FILTER_PARAM_DECL) { zend_string *buf = php_addslashes(Z_STR_P(value)); zval_ptr_dtor(value); ZVAL_STR(value, buf); + return SUCCESS; } /* }}} */ diff --git a/ext/filter/tests/025.phpt b/ext/filter/tests/025.phpt index d8e06e3ac20c..05459fcb1cb2 100644 --- a/ext/filter/tests/025.phpt +++ b/ext/filter/tests/025.phpt @@ -16,24 +16,24 @@ var_dump(filter_var(".", FILTER_SANITIZE_STRING)); echo "Done\n"; ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(12) "!@#$%^&*()'"" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(24) "!@#$%^&*()'"" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "`1234567890" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(5) "`123`" -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(1) "." Done diff --git a/ext/filter/tests/026.phpt b/ext/filter/tests/026.phpt index db43df7949a0..856f5325cb3b 100644 --- a/ext/filter/tests/026.phpt +++ b/ext/filter/tests/026.phpt @@ -20,30 +20,30 @@ var_dump(filter_var("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH)); echo "Done\n"; ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(40) "Let me see you Stripped down to the bone" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "!@#$%^&*()>" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(40) "Let me see you Stripped down to the bone" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "!@#$%^&*()>" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(40) "Let me see you Stripped down to the bone" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(11) "!@#$%^&*()>" -Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRIPPED is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" Done diff --git a/ext/filter/tests/039.phpt b/ext/filter/tests/039.phpt index 571d3a3265fc..229feecd4475 100644 --- a/ext/filter/tests/039.phpt +++ b/ext/filter/tests/039.phpt @@ -125,12 +125,18 @@ array(1) { ["var_name"]=> NULL } + +Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d array(1) { ["var_name"]=> string(0) "" } -- (5) + +Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d filter_var_array(): Argument #2 ($options) cannot contain empty keys + +Warning: filter_var_array(): Unknown filter with ID 0 in %s on line %d filter_var_array(): Argument #2 ($options) cannot contain empty keys Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d diff --git a/ext/filter/tests/042.phpt b/ext/filter/tests/042.phpt index 0795392f7aca..28f346afeefc 100644 --- a/ext/filter/tests/042.phpt +++ b/ext/filter/tests/042.phpt @@ -15,8 +15,8 @@ $a = filter_var($var, FILTER_SANITIZE_STRING, array("flags" => FILTER_FLAG_STRIP echo $a . "\n"; ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d XYZalert(/ext/filter+bypass/);ABC -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d XYZalert(/ext/filter+bypass/);ABC diff --git a/ext/filter/tests/062.phpt b/ext/filter/tests/062.phpt new file mode 100644 index 000000000000..2623443314ad --- /dev/null +++ b/ext/filter/tests/062.phpt @@ -0,0 +1,184 @@ +--TEST-- +filter_var() and FILTER_VALIDATE_URL with different URI parsers +--EXTENSIONS-- +filter +--FILE-- + $parserName])); + } + + var_dump(filter_var("qwe", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName])); + var_dump(filter_var("http://qwe", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName])); + var_dump(filter_var("http://", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName])); + var_dump(filter_var("/tmp/test", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName])); + var_dump(filter_var("http://www.example.com", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName])); + var_dump(filter_var("http://www.example.com", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName, "flags" => FILTER_FLAG_PATH_REQUIRED])); + var_dump(filter_var("http://www.example.com/path/at/the/server/", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName, "flags" => FILTER_FLAG_PATH_REQUIRED])); + var_dump(filter_var("http://www.example.com/index.html", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName, "flags" => FILTER_FLAG_QUERY_REQUIRED])); + var_dump(filter_var("http://www.example.com/index.php?a=b&c=d", FILTER_VALIDATE_URL, ["uri_parser_class" => $parserName, "flags" => FILTER_FLAG_QUERY_REQUIRED])); +} + +echo "RFC3986:\n"; +validateUrls(Uri\Rfc3986Uri::class); + +echo "\nWHATWG:\n"; +validateUrls(Uri\WhatWgUri::class); + +echo "Done\n"; +?> +--EXPECT-- +RFC3986: +string(29) "http://example.com/index.html" +string(32) "http://www.example.com/index.php" +string(31) "http://www.example/img/test.png" +string(27) "http://www.example/img/dir/" +string(26) "http://www.example/img/dir" +string(79) "http://www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com/" +bool(false) +bool(false) +string(261) "http://kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com." +bool(false) +string(48) "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]" +string(50) "http://[2001:db8:0:85a3:0:0:ac1f:8001]:123/me.html" +string(36) "http://[2001:db8:0:85a3::ac1f:8001]/" +string(12) "http://[::1]" +string(31) "http://cont-ains.h-yph-en-s.com" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(18) "file:///tmp/test.c" +string(26) "ftp://ftp.example.com/tmp/" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(18) "mailto:foo@bar.com" +string(17) "news:news.php.net" +string(14) "file://foo/bar" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(10) "http://qwe" +bool(false) +bool(false) +string(22) "http://www.example.com" +bool(false) +string(42) "http://www.example.com/path/at/the/server/" +bool(false) +string(40) "http://www.example.com/index.php?a=b&c=d" + +WHATWG: +string(29) "http://example.com/index.html" +string(32) "http://www.example.com/index.php" +string(31) "http://www.example/img/test.png" +string(27) "http://www.example/img/dir/" +string(26) "http://www.example/img/dir" +string(79) "http://www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com/" +bool(false) +bool(false) +string(261) "http://kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com." +bool(false) +string(48) "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]" +string(50) "http://[2001:db8:0:85a3:0:0:ac1f:8001]:123/me.html" +string(36) "http://[2001:db8:0:85a3::ac1f:8001]/" +string(12) "http://[::1]" +string(31) "http://cont-ains.h-yph-en-s.com" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(18) "file:///tmp/test.c" +string(26) "ftp://ftp.example.com/tmp/" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(18) "mailto:foo@bar.com" +string(17) "news:news.php.net" +string(14) "file://foo/bar" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(10) "http://qwe" +bool(false) +bool(false) +string(22) "http://www.example.com" +bool(false) +string(42) "http://www.example.com/path/at/the/server/" +bool(false) +string(40) "http://www.example.com/index.php?a=b&c=d" +Done diff --git a/ext/filter/tests/bug69203.phpt b/ext/filter/tests/bug69203.phpt index 3453c7c0adc6..85356ba2a134 100644 --- a/ext/filter/tests/bug69203.phpt +++ b/ext/filter/tests/bug69203.phpt @@ -10,7 +10,7 @@ var_dump(filter_var("\x7f", FILTER_SANITIZE_ENCODED, FILTER_FLAG_STRIP_HIGH)); var_dump(filter_var("\x7f", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_HIGH)); ?> --EXPECTF-- -Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in %s on line %d +Deprecated: Constant FILTER_SANITIZE_STRING is deprecated since 8.1, use htmlspecialchars() instead in %s on line %d string(0) "" string(0) "" string(0) "" diff --git a/ext/filter/tests/gh16993.phpt b/ext/filter/tests/gh16993.phpt new file mode 100644 index 000000000000..c264296fc15e --- /dev/null +++ b/ext/filter/tests/gh16993.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-16993: filter_var_array should emit warning for unknown filters +--EXTENSIONS-- +filter +--FILE-- + '42']; + +$result = filter_var_array($data, ['test' => FILTER_VALIDATE_INT|FILTER_NULL_ON_FAILURE]); +var_dump($result); + +$result = filter_var_array($data, ['test' => ['filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_NULL_ON_FAILURE]]); +var_dump($result); +?> +--EXPECTF-- +Warning: filter_var_array(): Unknown filter with ID 134217985 in %s on line %d +array(1) { + ["test"]=> + string(2) "42" +} +array(1) { + ["test"]=> + int(42) +} diff --git a/ext/filter/tests/throw-on-failure/filter_input_array_failure.phpt b/ext/filter/tests/throw-on-failure/filter_input_array_failure.phpt new file mode 100644 index 000000000000..868829dbbac0 --- /dev/null +++ b/ext/filter/tests/throw-on-failure/filter_input_array_failure.phpt @@ -0,0 +1,29 @@ +--TEST-- +FILTER_THROW_ON_FAILURE: filter_input_array() failure +--EXTENSIONS-- +filter +--GET-- +a=1 +--FILE-- + ['flags' => FILTER_REQUIRE_ARRAY | FILTER_THROW_ON_FAILURE]]); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +echo "\nvalidation fails (filter value)\n"; +try { + filter_input_array(INPUT_GET, ['a' => ['filter' => FILTER_VALIDATE_EMAIL, 'flags' => FILTER_THROW_ON_FAILURE]]); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +validation fails (array type check) +Filter\FilterFailedException: filter validation failed: not an array (got string) + +validation fails (filter value) +Filter\FilterFailedException: filter validation failed: filter validate_email not satisfied by '1' diff --git a/ext/filter/tests/throw-on-failure/filter_input_failure.phpt b/ext/filter/tests/throw-on-failure/filter_input_failure.phpt new file mode 100644 index 000000000000..8ec2d572e7f1 --- /dev/null +++ b/ext/filter/tests/throw-on-failure/filter_input_failure.phpt @@ -0,0 +1,39 @@ +--TEST-- +FILTER_THROW_ON_FAILURE: filter_input() failure +--EXTENSIONS-- +filter +--GET-- +a=1 +--FILE-- +getMessage() . "\n"; +} + +echo "\nvalidation fails (array type check)\n"; +try { + filter_input(INPUT_GET, 'a', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY | FILTER_THROW_ON_FAILURE); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +echo "\nvalidation fails (filter value)\n"; +try { + filter_input(INPUT_GET, 'a', FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +missing value +Filter\FilterFailedException: input value 'b' not found + +validation fails (array type check) +Filter\FilterFailedException: filter validation failed: not an array (got string) + +validation fails (filter value) +Filter\FilterFailedException: filter validation failed: filter validate_email not satisfied by '1' diff --git a/ext/filter/tests/throw-on-failure/filter_success.phpt b/ext/filter/tests/throw-on-failure/filter_success.phpt new file mode 100644 index 000000000000..c5b0e2fc9fdd --- /dev/null +++ b/ext/filter/tests/throw-on-failure/filter_success.phpt @@ -0,0 +1,68 @@ +--TEST-- +FILTER_THROW_ON_FAILURE: successful filters do not throw +--EXTENSIONS-- +filter +--GET-- +a=daniel.e.scherzer@gmail.com +--FILE-- +wrapped; } +} + +echo "filter_input:\n"; +var_dump(filter_input(INPUT_GET, 'a', FILTER_DEFAULT, FILTER_THROW_ON_FAILURE)); +var_dump(filter_input(INPUT_GET, 'a', FILTER_DEFAULT, FILTER_REQUIRE_SCALAR | FILTER_THROW_ON_FAILURE)); +var_dump(filter_input(INPUT_GET, 'a', FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE)); + +echo "\nfilter_input_array:\n"; +var_dump(filter_input_array(INPUT_GET, ['a' => ['flags' => FILTER_REQUIRE_SCALAR | FILTER_THROW_ON_FAILURE]])); +var_dump(filter_input_array(INPUT_GET, ['a' => ['filter' => FILTER_VALIDATE_EMAIL, 'flags' => FILTER_THROW_ON_FAILURE]])); + +echo "\nfilter_var:\n"; +var_dump(filter_var('a', FILTER_DEFAULT, FILTER_REQUIRE_SCALAR | FILTER_THROW_ON_FAILURE)); +var_dump(filter_var(new MyString('daniel.e.scherzer@gmail.com'), FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE)); +var_dump(filter_var('daniel.e.scherzer@gmail.com', FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE)); + +echo "\nfilter_var_array:\n"; +var_dump(filter_var_array(['a' => 'a'], ['a' => ['flags' => FILTER_REQUIRE_SCALAR | FILTER_THROW_ON_FAILURE]])); +var_dump(filter_var_array(['a' => new MyString('bar')], ['a' => ['flags' => FILTER_THROW_ON_FAILURE]])); +var_dump(filter_var_array(['a' => 'daniel.e.scherzer@gmail.com'], ['a' => ['filter' => FILTER_VALIDATE_EMAIL, 'flags' => FILTER_THROW_ON_FAILURE]])); + +?> +--EXPECT-- +filter_input: +string(27) "daniel.e.scherzer@gmail.com" +string(27) "daniel.e.scherzer@gmail.com" +string(27) "daniel.e.scherzer@gmail.com" + +filter_input_array: +array(1) { + ["a"]=> + string(27) "daniel.e.scherzer@gmail.com" +} +array(1) { + ["a"]=> + string(27) "daniel.e.scherzer@gmail.com" +} + +filter_var: +string(1) "a" +string(27) "daniel.e.scherzer@gmail.com" +string(27) "daniel.e.scherzer@gmail.com" + +filter_var_array: +array(1) { + ["a"]=> + string(1) "a" +} +array(1) { + ["a"]=> + string(3) "bar" +} +array(1) { + ["a"]=> + string(27) "daniel.e.scherzer@gmail.com" +} diff --git a/ext/filter/tests/throw-on-failure/filter_var_array_failure.phpt b/ext/filter/tests/throw-on-failure/filter_var_array_failure.phpt new file mode 100644 index 000000000000..f40dec1537dd --- /dev/null +++ b/ext/filter/tests/throw-on-failure/filter_var_array_failure.phpt @@ -0,0 +1,37 @@ +--TEST-- +FILTER_THROW_ON_FAILURE: filter_var_array() failure +--EXTENSIONS-- +filter +--FILE-- + 'a'], ['a' => ['flags' => FILTER_REQUIRE_ARRAY | FILTER_THROW_ON_FAILURE]]); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +echo "\nvalidation fails (object without __toString)\n"; +try { + filter_var_array(['a' => new stdClass()], ['a' => ['flags' => FILTER_THROW_ON_FAILURE]]); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +echo "\nvalidation fails (filter value)\n"; +try { + filter_var_array(['a' => true], ['a' => ['filter' => FILTER_VALIDATE_EMAIL, 'flags' => FILTER_THROW_ON_FAILURE]]); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +validation fails (array type check) +Filter\FilterFailedException: filter validation failed: not an array (got string) + +validation fails (object without __toString) +Filter\FilterFailedException: filter validation failed: object of type stdClass has no __toString() method + +validation fails (filter value) +Filter\FilterFailedException: filter validation failed: filter validate_email not satisfied by '1' diff --git a/ext/filter/tests/throw-on-failure/filter_var_failure.phpt b/ext/filter/tests/throw-on-failure/filter_var_failure.phpt new file mode 100644 index 000000000000..fccc61da4d0f --- /dev/null +++ b/ext/filter/tests/throw-on-failure/filter_var_failure.phpt @@ -0,0 +1,37 @@ +--TEST-- +FILTER_THROW_ON_FAILURE: filter_input() failure +--EXTENSIONS-- +filter +--FILE-- +getMessage() . "\n"; +} + +echo "\nvalidation fails (object without __toString)\n"; +try { + filter_var(new stdClass(), FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +echo "\nvalidation fails (filter value)\n"; +try { + filter_var('a', FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE); +} catch (Filter\FilterFailedException $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +validation fails (array type check) +Filter\FilterFailedException: filter validation failed: not an array (got string) + +validation fails (object without __toString) +Filter\FilterFailedException: filter validation failed: object of type stdClass has no __toString() method + +validation fails (filter value) +Filter\FilterFailedException: filter validation failed: filter validate_email not satisfied by 'a' diff --git a/ext/filter/tests/throw-on-failure/throw-and-null-error.phpt b/ext/filter/tests/throw-on-failure/throw-and-null-error.phpt new file mode 100644 index 000000000000..48c37618ed91 --- /dev/null +++ b/ext/filter/tests/throw-on-failure/throw-and-null-error.phpt @@ -0,0 +1,86 @@ +--TEST-- +Cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE +--EXTENSIONS-- +filter +--GET-- +a=1 +--FILE-- +getMessage() . "\n"; +} +try { + filter_input(INPUT_GET, 'b', FILTER_DEFAULT, ['flags' => $flags]); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +echo "\nfilter_input(), with a missing value and a default\n"; +try { + filter_input(INPUT_GET, 'b', FILTER_DEFAULT, ['flags' => $flags, 'options' => ['default' => 'a']]); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +echo "\nfilter_input(), with a present value\n"; +try { + filter_input(INPUT_GET, 'a', FILTER_DEFAULT, $flags); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +try { + filter_input(INPUT_GET, 'a', FILTER_DEFAULT, ['flags' => $flags]); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +echo "\nfilter_var()\n"; +try { + filter_var(true, FILTER_DEFAULT, $flags); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +try { + filter_var(true, FILTER_DEFAULT, ['flags' => $flags]); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +echo "\nfilter_input_array()\n"; +try { + filter_input_array(INPUT_GET, ['a' => ['flags' => $flags]]); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} + +echo "\nfilter_var_array()\n"; +try { + filter_var_array(['a' => true], ['a' => ['flags' => $flags]]); +} catch (ValueError $e) { + echo get_class($e) . ": " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +filter_input(), with a missing value +ValueError: filter_input(): Argument #4 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE +ValueError: filter_input(): Argument #4 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE + +filter_input(), with a missing value and a default +ValueError: filter_input(): Argument #4 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE + +filter_input(), with a present value +ValueError: filter_input(): Argument #4 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE +ValueError: filter_input(): Argument #4 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE + +filter_var() +ValueError: filter_var(): Argument #3 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE +ValueError: filter_var(): Argument #3 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE + +filter_input_array() +ValueError: filter_input_array(): Argument #2 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE + +filter_var_array() +ValueError: filter_var_array(): Argument #2 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index f37ee6861761..66a05a95f4ed 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | @@ -130,7 +128,7 @@ ftpbuf_t* ftp_open(const char *host, short port, zend_long timeout_sec) /* Default Settings */ ftp->timeout_sec = timeout_sec; - ftp->nb = 0; + ftp->nb = false; size = sizeof(ftp->localaddr); memset(&ftp->localaddr, 0, size); @@ -263,8 +261,8 @@ bool ftp_login(ftpbuf_t *ftp, const char *user, const size_t user_len, const cha if (ftp->resp != 334) { return false; } else { - ftp->old_ssl = 1; - ftp->use_ssl_for_data = 1; + ftp->old_ssl = true; + ftp->use_ssl_for_data = true; } } @@ -385,7 +383,7 @@ bool ftp_reinit(ftpbuf_t *ftp) ftp_gc(ftp); - ftp->nb = 0; + ftp->nb = false; if (!ftp_putcmd(ftp, "REIN", sizeof("REIN")-1, NULL, (size_t) 0)) { return false; @@ -485,7 +483,7 @@ void ftp_raw(ftpbuf_t *ftp, const char *cmd, const size_t cmd_len, zval *return_ array_init(return_value); while (ftp_readline(ftp)) { add_next_index_string(return_value, ftp->inbuf); - if (isdigit(ftp->inbuf[0]) && isdigit(ftp->inbuf[1]) && isdigit(ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { + if (isdigit((unsigned char)ftp->inbuf[0]) && isdigit((unsigned char)ftp->inbuf[1]) && isdigit((unsigned char)ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { return; } } @@ -791,7 +789,7 @@ bool ftp_pasv(ftpbuf_t *ftp, int pasv) return false; } /* parse out the IP and port */ - for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); + for (ptr = ftp->inbuf; *ptr && !isdigit((unsigned char)*ptr); ptr++); n = sscanf(ptr, "%lu,%lu,%lu,%lu,%lu,%lu", &b[0], &b[1], &b[2], &b[3], &b[4], &b[5]); if (n != 6) { return false; @@ -1102,7 +1100,7 @@ time_t ftp_mdtm(ftpbuf_t *ftp, const char *path, const size_t path_len) return -1; } /* parse out the timestamp */ - for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); + for (ptr = ftp->inbuf; *ptr && !isdigit((unsigned char)*ptr); ptr++); n = sscanf(ptr, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); if (n != 6) { return -1; @@ -1193,7 +1191,7 @@ static bool ftp_putcmd(ftpbuf_t *ftp, const char *cmd, const size_t cmd_len, con return false; } if (strpbrk(args, "\r\n")) { - return 0; + return false; } size = slprintf(data, sizeof(data), "%s %s\r\n", cmd, args); } else { @@ -1278,13 +1276,13 @@ static bool ftp_getresp(ftpbuf_t *ftp) } /* Break out when the end-tag is found */ - if (isdigit(ftp->inbuf[0]) && isdigit(ftp->inbuf[1]) && isdigit(ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { + if (isdigit((unsigned char)ftp->inbuf[0]) && isdigit((unsigned char)ftp->inbuf[1]) && isdigit((unsigned char)ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { break; } } /* translate the tag */ - if (!isdigit(ftp->inbuf[0]) || !isdigit(ftp->inbuf[1]) || !isdigit(ftp->inbuf[2])) { + if (!isdigit((unsigned char)ftp->inbuf[0]) || !isdigit((unsigned char)ftp->inbuf[1]) || !isdigit((unsigned char)ftp->inbuf[2])) { return false; } @@ -1317,7 +1315,7 @@ static ssize_t my_recv_wrapper_with_restart(php_socket_t fd, void *buf, size_t s static int single_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t size) { #ifdef HAVE_FTP_SSL int err; - bool retry = 0; + bool retry = false; SSL *handle = NULL; php_socket_t fd; size_t sent; @@ -1338,11 +1336,11 @@ static int single_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t size) { switch (err) { case SSL_ERROR_NONE: - retry = 0; + retry = false; break; case SSL_ERROR_ZERO_RETURN: - retry = 0; + retry = false; SSL_shutdown(handle); break; @@ -1382,7 +1380,8 @@ static int my_poll(php_socket_t fd, int events, int timeout) { if (n == -1 && php_socket_errno() == EINTR) { zend_hrtime_t delta_ns = zend_hrtime() - start_ns; - if (delta_ns > timeout_hr) { + /* delta_ns == 0 is only possible with a platform that does not support a high-res timer. */ + if (delta_ns > timeout_hr || UNEXPECTED(delta_ns == 0)) { #ifndef PHP_WIN32 errno = ETIMEDOUT; #endif @@ -1436,7 +1435,7 @@ static int my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) int n, nr_bytes; #ifdef HAVE_FTP_SSL int err; - bool retry = 0; + bool retry = false; SSL *handle = NULL; php_socket_t fd; #endif @@ -1470,11 +1469,11 @@ static int my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) switch (err) { case SSL_ERROR_NONE: - retry = 0; + retry = false; break; case SSL_ERROR_ZERO_RETURN: - retry = 0; + retry = false; SSL_shutdown(handle); break; @@ -1507,7 +1506,7 @@ static int my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len) return (nr_bytes); } -static bool data_available(ftpbuf_t *ftp, php_socket_t s) +static bool data_available(ftpbuf_t *ftp, php_socket_t s, bool silent) { int n; @@ -1515,6 +1514,9 @@ static bool data_available(ftpbuf_t *ftp, php_socket_t s) if (n < 1) { char buf[256]; if (n == 0) { + if (silent) { + return false; + } #ifdef PHP_WIN32 _set_errno(ETIMEDOUT); #else @@ -1771,11 +1773,11 @@ static databuf_t* data_accept(databuf_t *data, ftpbuf_t *ftp) switch (err) { case SSL_ERROR_NONE: - retry = 0; + retry = false; break; case SSL_ERROR_ZERO_RETURN: - retry = 0; + retry = false; SSL_shutdown(data->ssl_handle); break; @@ -1830,7 +1832,9 @@ static void ftp_ssl_shutdown(ftpbuf_t *ftp, php_socket_t fd, SSL *ssl_handle) { done = 0; } - while (!done && data_available(ftp, fd)) { + /* Don't report timeouts on the control channel if we're negotiating a shutdown already. + * Some servers don't put a final response. */ + while (!done && data_available(ftp, fd, true)) { ERR_clear_error(); nread = SSL_read(ssl_handle, buf, sizeof(buf)); if (nread <= 0) { @@ -2057,7 +2061,7 @@ int ftp_nb_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, const siz ftp->data = data; ftp->stream = outstream; ftp->lastch = 0; - ftp->nb = 1; + ftp->nb = true; return (ftp_nb_continue_read(ftp)); @@ -2077,7 +2081,7 @@ int ftp_nb_continue_read(ftpbuf_t *ftp) data = ftp->data; /* check if there is already more data */ - if (!data_available(ftp, data->fd)) { + if (!data_available(ftp, data->fd, false)) { return PHP_FTP_MOREDATA; } @@ -2117,10 +2121,10 @@ int ftp_nb_continue_read(ftpbuf_t *ftp) goto bail; } - ftp->nb = 0; + ftp->nb = false; return PHP_FTP_FINISHED; bail: - ftp->nb = 0; + ftp->nb = false; data_close(ftp); return PHP_FTP_FAILED; } @@ -2165,7 +2169,7 @@ int ftp_nb_put(ftpbuf_t *ftp, const char *path, const size_t path_len, php_strea ftp->data = data; ftp->stream = instream; ftp->lastch = 0; - ftp->nb = 1; + ftp->nb = true; return (ftp_nb_continue_write(ftp)); @@ -2194,10 +2198,10 @@ int ftp_nb_continue_write(ftpbuf_t *ftp) if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) { goto bail; } - ftp->nb = 0; + ftp->nb = false; return PHP_FTP_FINISHED; bail: data_close(ftp); - ftp->nb = 0; + ftp->nb = false; return PHP_FTP_FAILED; } diff --git a/ext/ftp/ftp.h b/ext/ftp/ftp.h index 241f92f57ec3..b336754c3f88 100644 --- a/ext/ftp/ftp.h +++ b/ext/ftp/ftp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | diff --git a/ext/ftp/ftp_arginfo.h b/ext/ftp/ftp_arginfo.h index 77bc47df03f6..edb0b4b8a91b 100644 --- a/ext/ftp/ftp_arginfo.h +++ b/ext/ftp/ftp_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit ftp.stub.php instead. * Stub hash: 29606d7114a0698b8ae231173a624b17c196ffec */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_ftp_connect, 0, 1, FTP\\Connection, MAY_BE_FALSE) diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index fb771a66d73e..501ce9bc68d7 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | @@ -40,9 +38,7 @@ static zend_class_entry *php_ftp_ce = NULL; static zend_object_handlers ftp_object_handlers; zend_module_entry php_ftp_module_entry = { - STANDARD_MODULE_HEADER_EX, - NULL, - NULL, + STANDARD_MODULE_HEADER, "ftp", ext_functions, PHP_MINIT(ftp), @@ -103,7 +99,7 @@ PHP_MINIT_FUNCTION(ftp) php_ftp_ce->create_object = ftp_object_create; memcpy(&ftp_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ftp_object_handlers.offset = XtOffsetOf(php_ftp_object, std); + ftp_object_handlers.offset = offsetof(php_ftp_object, std); ftp_object_handlers.get_constructor = ftp_object_get_constructor; ftp_object_handlers.free_obj = ftp_object_destroy; ftp_object_handlers.clone_obj = NULL; @@ -147,11 +143,18 @@ PHP_FUNCTION(ftp_connect) RETURN_THROWS(); } + const uint64_t timeoutmax = (uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0); + if (timeout_sec <= 0) { zend_argument_value_error(3, "must be greater than 0"); RETURN_THROWS(); } + if (timeout_sec >= timeoutmax) { + zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, timeoutmax); + RETURN_THROWS(); + } + /* connect */ if (!(ftp = ftp_open(host, (short)port, timeout_sec))) { RETURN_FALSE; @@ -483,7 +486,7 @@ PHP_FUNCTION(ftp_rawlist) ftpbuf_t *ftp; char **llist, **ptr, *dir; size_t dir_len; - bool recursive = 0; + bool recursive = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|b", &z_ftp, php_ftp_ce, &dir, &dir_len, &recursive) == FAILURE) { RETURN_THROWS(); @@ -673,11 +676,8 @@ PHP_FUNCTION(ftp_pasv) } GET_FTPBUF(ftp, z_ftp); - if (!ftp_pasv(ftp, pasv ? 1 : 0)) { - RETURN_FALSE; - } + RETURN_BOOL(ftp_pasv(ftp, pasv ? 1 : 0)); - RETURN_TRUE; } /* }}} */ @@ -815,7 +815,7 @@ PHP_FUNCTION(ftp_nb_get) } /* }}} */ -/* {{{ Continues retrieving/sending a file nbronously */ +/* {{{ Continues to retrieve or send a file in non-blocking mode */ PHP_FUNCTION(ftp_nb_continue) { zval *z_ftp; @@ -828,7 +828,7 @@ PHP_FUNCTION(ftp_nb_continue) GET_FTPBUF(ftp, z_ftp); if (!ftp->nb) { - php_error_docref(NULL, E_WARNING, "No nbronous transfer to continue"); + php_error_docref(NULL, E_WARNING, "No non-blocking transfer to continue"); RETURN_LONG(PHP_FTP_FAILED); } @@ -1262,7 +1262,6 @@ PHP_FUNCTION(ftp_set_option) } ftp->timeout_sec = Z_LVAL_P(z_value); RETURN_TRUE; - break; case PHP_FTP_OPT_AUTOSEEK: if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) { zend_argument_type_error(3, "must be of type bool for the FTP_AUTOSEEK option, %s given", zend_zval_value_name(z_value)); @@ -1270,7 +1269,6 @@ PHP_FUNCTION(ftp_set_option) } ftp->autoseek = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0; RETURN_TRUE; - break; case PHP_FTP_OPT_USEPASVADDRESS: if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) { zend_argument_type_error(3, "must be of type bool for the FTP_USEPASVADDRESS option, %s given", zend_zval_value_name(z_value)); @@ -1278,11 +1276,9 @@ PHP_FUNCTION(ftp_set_option) } ftp->usepasvaddress = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0; RETURN_TRUE; - break; default: zend_argument_value_error(2, "must be one of FTP_TIMEOUT_SEC, FTP_AUTOSEEK, or FTP_USEPASVADDRESS"); RETURN_THROWS(); - break; } } /* }}} */ @@ -1302,13 +1298,10 @@ PHP_FUNCTION(ftp_get_option) switch (option) { case PHP_FTP_OPT_TIMEOUT_SEC: RETURN_LONG(ftp->timeout_sec); - break; case PHP_FTP_OPT_AUTOSEEK: RETURN_BOOL(ftp->autoseek); - break; case PHP_FTP_OPT_USEPASVADDRESS: RETURN_BOOL(ftp->usepasvaddress); - break; default: zend_argument_value_error(2, "must be one of FTP_TIMEOUT_SEC, FTP_AUTOSEEK, or FTP_USEPASVADDRESS"); RETURN_THROWS(); diff --git a/ext/ftp/php_ftp.h b/ext/ftp/php_ftp.h index b701f1331d0b..ee9cb50c4382 100644 --- a/ext/ftp/php_ftp.h +++ b/ext/ftp/php_ftp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrew Skalski | | Stefan Esser (resume functions) | diff --git a/ext/ftp/tests/005.phpt b/ext/ftp/tests/005.phpt index 409b60e18471..f08cadd2b428 100644 --- a/ext/ftp/tests/005.phpt +++ b/ext/ftp/tests/005.phpt @@ -85,7 +85,7 @@ int(-1) Warning: ftp_mkdir(): Command not implemented (7). in %s005.php on line %d bool(false) -Warning: ftp_nb_continue(): No nbronous transfer to continue in %s005.php on line %d +Warning: ftp_nb_continue(): No non-blocking transfer to continue in %s on line %d int(0) ftp_nb_fget(): Argument #4 ($mode) must be either FTP_ASCII or FTP_BINARY ftp_nb_fput(): Argument #4 ($mode) must be either FTP_ASCII or FTP_BINARY diff --git a/ext/ftp/tests/gh20601.phpt b/ext/ftp/tests/gh20601.phpt new file mode 100644 index 000000000000..3ece7736c3aa --- /dev/null +++ b/ext/ftp/tests/gh20601.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-20601 (ftp_connect timeout overflow) +--EXTENSIONS-- +ftp +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +ftp_connect(): Argument #3 ($timeout) must be less than %d diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index a95ea3fba70e..a997238b7f75 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -65,6 +65,7 @@ AC_DEFUN([PHP_GD_PNG],[ PHP_EVAL_LIBLINE([$PNG_LIBS], [GD_SHARED_LIBADD]) PHP_EVAL_INCLINE([$PNG_CFLAGS]) AC_DEFINE([HAVE_LIBPNG], [1], [Define to 1 if you have the libpng library.]) + AC_DEFINE([HAVE_GD_PNG], [1], [Define to 1 if gd extension has PNG support.]) ]) AC_DEFUN([PHP_GD_AVIF], [ @@ -162,17 +163,22 @@ AC_CACHE_CHECK([for working gdImageCreateFrom$1 in libgd], [php_var], /* A custom gdErrorMethod */ void exit1(int priority, const char *format, va_list args) { + (void)priority; + (void)format; + (void)args; _exit(1); } /* Override the default gd_error_method with one that actually causes the program to return an error. */ -int main(int argc, char** argv) { +int main(void) +{ m4_if([$1],[Xpm], [char* f = "test.xpm"], [FILE* f = NULL]); gdSetErrorMethod(exit1); gdImagePtr p = gdImageCreateFrom$1(f); + (void)p; return 0; }])], [AS_VAR_SET([php_var], [yes])], @@ -191,8 +197,6 @@ AC_DEFUN([PHP_GD_CHECK_VERSION],[ PHP_GD_CHECK_FORMAT([Webp], [AC_DEFINE([HAVE_GD_WEBP], [1])]) PHP_GD_CHECK_FORMAT([Jpeg], [AC_DEFINE([HAVE_GD_JPG], [1])]) PHP_GD_CHECK_FORMAT([Xpm], [AC_DEFINE([HAVE_GD_XPM], [1])]) - PHP_GD_CHECK_FORMAT([Bmp], [AC_DEFINE([HAVE_GD_BMP], [1])]) - PHP_GD_CHECK_FORMAT([Tga], [AC_DEFINE([HAVE_GD_TGA], [1])]) PHP_CHECK_LIBRARY([gd], [gdFontCacheShutdown], [AC_DEFINE([HAVE_GD_FREETYPE], [1])], [], @@ -258,15 +262,12 @@ if test "$PHP_GD" != "no"; then libgd/wbmp.c "]) -dnl These are always available with bundled library AC_DEFINE([HAVE_GD_BUNDLED], [1], [Define to 1 if gd extension uses GD library bundled in PHP.]) - AC_DEFINE([HAVE_GD_PNG], [1], - [Define to 1 if gd extension has PNG support.]) - AC_DEFINE([HAVE_GD_BMP], [1], - [Define to 1 if gd extension has BMP support.]) - AC_DEFINE([HAVE_GD_TGA], [1], - [Define to 1 if gd extension has TGA support.]) + + AC_DEFINE([HAVE_GD_GET_INTERPOLATION], [1], + [Define to 1 if GD library has the 'gdImageGetInterpolationMethod' + function.]) dnl Various checks for GD features PHP_SETUP_ZLIB([GD_SHARED_LIBADD]) diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index b410db7f1cb3..506bb05cf2e0 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -8,28 +8,29 @@ if (PHP_GD != "no") { if ( CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) && CHECK_LIB("freetype_a.lib;freetype.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("ft2build.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\freetype2;" + PHP_PHP_BUILD + "\\include\\freetype") && + CHECK_HEADER("ft2build.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\freetype2;" + PHP_PHP_BUILD + "\\include\\freetype") && CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd") && - (CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng16") || - CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng15") || - CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng12")) && + CHECK_HEADER("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd") && + (CHECK_HEADER("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng16") || + CHECK_HEADER("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng15") || + CHECK_HEADER("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng12")) && (CHECK_LIB("libiconv_a.lib;libiconv.lib", "gd", PHP_GD) || CHECK_LIB("iconv_a.lib;iconv.lib", "gd", PHP_GD)) && - CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_GD", PHP_GD) && + CHECK_HEADER("iconv.h", "CFLAGS_GD", PHP_GD) && SETUP_ZLIB_LIB("gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) + CHECK_HEADER("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) ) { + AC_DEFINE('HAVE_ICONV_H', 1, 'Define to 1 if you have the header'); if (CHECK_LIB("libXpm_a.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11") + CHECK_HEADER("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11") ) { AC_DEFINE('HAVE_XPM', 1, "Define to 1 if you have the xpm library."); AC_DEFINE('HAVE_GD_XPM', 1, "Define to 1 if gd extension has XPM support."); } if (PHP_LIBWEBP != "no") { if ((CHECK_LIB("libwebp_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebp.lib", "gd", PHP_GD)) && - CHECK_HEADER_ADD_INCLUDE("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") && - CHECK_HEADER_ADD_INCLUDE("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) { + CHECK_HEADER("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") && + CHECK_HEADER("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) { AC_DEFINE("HAVE_LIBWEBP", 1, "Define to 1 if you have the libwebp library."); AC_DEFINE("HAVE_GD_WEBP", 1, "Define to 1 if gd extension has WebP support."); } else { @@ -39,10 +40,10 @@ if (PHP_GD != "no") { if (PHP_LIBAVIF != "no") { if (CHECK_LIB("avif_a.lib", "gd", PHP_GD) && CHECK_LIB("aom_a.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { + CHECK_HEADER("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF"); } else if (CHECK_LIB("avif.lib", "gd", PHP_GD) && - CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { + CHECK_HEADER("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) { ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF"); } else { WARNING("libavif not enabled; libraries and headers not found"); @@ -61,8 +62,6 @@ if (PHP_GD != "no") { gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c gd_tga.c", "gd"); AC_DEFINE('HAVE_GD_BUNDLED', 1, "Define to 1 if gd extension uses GD library bundled in PHP."); AC_DEFINE('HAVE_GD_PNG', 1, "Define to 1 if gd extension has PNG support."); - AC_DEFINE('HAVE_GD_BMP', 1, "Define to 1 if gd extension has BMP support."); - AC_DEFINE('HAVE_GD_TGA', 1, "Define to 1 if gd extension has TGA support."); AC_DEFINE('HAVE_LIBPNG', 1, "Define to 1 if you have the libpng library."); AC_DEFINE('HAVE_LIBJPEG', 1, "Define to 1 if you have the libjpeg library."); AC_DEFINE('HAVE_GD_JPG', 1, "Define to 1 if gd extension has JPEG support."); diff --git a/ext/gd/gd.c b/ext/gd/gd.c index e993fb65f47d..92ab74fda575 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | @@ -34,6 +32,7 @@ #include "ext/standard/info.h" #include "php_open_temporary_file.h" #include "php_memory_streams.h" +#include "zend_attributes.h" #include "zend_object_handlers.h" #ifdef HAVE_SYS_WAIT_H @@ -119,7 +118,7 @@ static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS); /* End Section filters declarations */ static gdImagePtr _php_image_create_from_string(zend_string *Data, const char *tn, gdImagePtr (*ioctx_func_p)(gdIOCtxPtr)); static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, const char *tn, gdImagePtr (*func_p)(FILE *), gdImagePtr (*ioctx_func_p)(gdIOCtxPtr)); -static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, const char *tn); +static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type); static gdIOCtx *create_stream_context(php_stream *stream, int close_stream); static gdIOCtx *create_output_context(zval *to_zval, uint32_t arg_num); static int _php_image_type(zend_string *data); @@ -151,7 +150,7 @@ static zend_function *php_gd_image_object_get_constructor(zend_object *object) static zend_always_inline php_gd_image_object* php_gd_exgdimage_from_zobj_p(zend_object* obj) { - return (php_gd_image_object *) ((char *) (obj) - XtOffsetOf(php_gd_image_object, std)); + return ZEND_CONTAINER_OF(obj, php_gd_image_object, std); } /** @@ -207,7 +206,7 @@ static void php_gd_object_minit_helper(void) php_gd_image_object_handlers.free_obj = php_gd_image_object_free; php_gd_image_object_handlers.get_constructor = php_gd_image_object_get_constructor; php_gd_image_object_handlers.compare = zend_objects_not_comparable; - php_gd_image_object_handlers.offset = XtOffsetOf(php_gd_image_object, std); + php_gd_image_object_handlers.offset = offsetof(php_gd_image_object, std); } static zend_class_entry *gd_font_ce = NULL; @@ -272,7 +271,7 @@ static void php_gd_font_minit_helper(void) php_gd_font_object_handlers.clone_obj = NULL; php_gd_font_object_handlers.free_obj = php_gd_font_object_free; php_gd_font_object_handlers.get_constructor = php_gd_font_object_get_constructor; - php_gd_font_object_handlers.offset = XtOffsetOf(php_gd_font_object, std); + php_gd_font_object_handlers.offset = offsetof(php_gd_font_object, std); } /********************************************************* @@ -443,15 +442,11 @@ PHP_MINFO_FUNCTION(gd) #ifdef HAVE_GD_WEBP php_info_print_table_row(2, "WebP Support", "enabled"); #endif -#ifdef HAVE_GD_BMP php_info_print_table_row(2, "BMP Support", "enabled"); -#endif #ifdef HAVE_GD_AVIF php_info_print_table_row(2, "AVIF Support", "enabled"); #endif -#ifdef HAVE_GD_TGA php_info_print_table_row(2, "TGA Read Support", "enabled"); -#endif php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } @@ -496,21 +491,13 @@ PHP_FUNCTION(gd_info) #else add_assoc_bool(return_value, "WebP Support", 0); #endif -#ifdef HAVE_GD_BMP add_assoc_bool(return_value, "BMP Support", 1); -#else - add_assoc_bool(return_value, "BMP Support", 0); -#endif #ifdef HAVE_GD_AVIF add_assoc_bool(return_value, "AVIF Support", 1); #else add_assoc_bool(return_value, "AVIF Support", 0); #endif -#ifdef HAVE_GD_TGA add_assoc_bool(return_value, "TGA Read Support", 1); -#else - add_assoc_bool(return_value, "TGA Read Support", 0); -#endif #ifdef USE_GD_JISX0208 add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 1); #else @@ -651,7 +638,20 @@ PHP_FUNCTION(imagesetstyle) stylearr = safe_emalloc(num_styles, sizeof(int), 0); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(styles), item) { - stylearr[index++] = zval_get_long(item); + bool failed = false; + ZVAL_DEREF(item); + zend_long tmp = zval_try_get_long(item, &failed); + if (failed) { + efree(stylearr); + zend_argument_type_error(2, "must only have elements of type int, %s given", zend_zval_type_name(item)); + RETURN_THROWS(); + } + if (ZEND_LONG_EXCEEDS_INT(tmp)) { + efree(stylearr); + zend_argument_value_error(2, "elements must be between %d and %d", INT_MIN, INT_MAX); + RETURN_THROWS(); + } + stylearr[index++] = (int) tmp; } ZEND_HASH_FOREACH_END(); gdImageSetStyle(im, stylearr, index); @@ -775,19 +775,15 @@ PHP_FUNCTION(imagecolormatch) case -1: zend_argument_value_error(1, "must be TrueColor"); RETURN_THROWS(); - break; case -2: zend_argument_value_error(2, "must be Palette"); RETURN_THROWS(); - break; case -3: zend_argument_value_error(2, "must be the same size as argument #1 ($im1)"); RETURN_THROWS(); - break; case -4: zend_argument_value_error(2, "must have at least one color"); RETURN_THROWS(); - break; } RETURN_TRUE; @@ -830,6 +826,11 @@ PHP_FUNCTION(imagefilledellipse) Z_PARAM_LONG(color) ZEND_PARSE_PARAMETERS_END(); + if (w < 0 || ZEND_LONG_INT_OVFL(w)) { + zend_argument_value_error(4, "must be between 0 and %d", INT_MAX); + RETURN_THROWS(); + } + im = php_gd_libgdimageptr_from_zval_p(IM); gdImageFilledEllipse(im, cx, cy, w, h, color); @@ -1335,12 +1336,8 @@ PHP_FUNCTION(imagetypes) #ifdef HAVE_GD_WEBP ret |= PHP_IMG_WEBP; #endif -#ifdef HAVE_GD_BMP ret |= PHP_IMG_BMP; -#endif -#ifdef HAVE_GD_TGA ret |= PHP_IMG_TGA; -#endif #ifdef HAVE_GD_AVIF ret |= PHP_IMG_AVIF; #endif @@ -1589,7 +1586,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, pefree(pstr, 1); zend_string_release_ex(buff, 0); } - else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO)) { + else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO) == SUCCESS) { /* try and force the stream to be FILE* */ if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_TRY_HARD, (void **) &fp, REPORT_ERRORS)) { goto out_err; @@ -1609,7 +1606,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, #ifdef HAVE_GD_JPG case PHP_GDIMG_TYPE_JPG: - ignore_warning = INI_INT("gd.jpeg_ignore_warning"); + ignore_warning = zend_ini_bool_literal("gd.jpeg_ignore_warning"); im = gdImageCreateFromJpegEx(fp, ignore_warning); break; #endif @@ -1724,26 +1721,22 @@ PHP_FUNCTION(imagecreatefromgd2part) } /* }}} */ -#ifdef HAVE_GD_BMP /* {{{ Create a new image from BMP file or URL */ PHP_FUNCTION(imagecreatefrombmp) { _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_BMP, "BMP", gdImageCreateFromBmp, gdImageCreateFromBmpCtx); } /* }}} */ -#endif -#ifdef HAVE_GD_TGA /* {{{ Create a new image from TGA file or URL */ PHP_FUNCTION(imagecreatefromtga) { _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_TGA, "TGA", gdImageCreateFromTga, gdImageCreateFromTgaCtx); } /* }}} */ -#endif /* {{{ _php_image_output */ -static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, const char *tn) +static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type) { zval *imgind; char *file = NULL; @@ -1764,7 +1757,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, cons RETURN_THROWS(); } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } /* quality must fit in an int */ @@ -1794,7 +1787,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, cons } gdImageGd2(im, fp, quality, type); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } fflush(fp); fclose(fp); @@ -1820,7 +1813,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, cons } gdImageGd2(im, tmp, quality, type); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } fseek(tmp, 0, SEEK_SET); @@ -2116,18 +2109,17 @@ PHP_FUNCTION(imagewbmp) /* {{{ Output GD image to browser or file */ PHP_FUNCTION(imagegd) { - _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD, "GD"); + _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD); } /* }}} */ /* {{{ Output GD2 image to browser or file */ PHP_FUNCTION(imagegd2) { - _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2"); + _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2); } /* }}} */ -#ifdef HAVE_GD_BMP /* {{{ Output BMP image to browser or file */ PHP_FUNCTION(imagebmp) { @@ -2158,7 +2150,6 @@ PHP_FUNCTION(imagebmp) RETURN_TRUE; } /* }}} */ -#endif /* {{{ Destroy an image - No effect as of PHP 8.0 */ PHP_FUNCTION(imagedestroy) @@ -2469,11 +2460,21 @@ PHP_FUNCTION(imagegammacorrect) RETURN_THROWS(); } + if (!zend_finite(input)) { + zend_argument_value_error(2, "must be finite"); + RETURN_THROWS(); + } + if (output <= 0.0) { zend_argument_value_error(3, "must be greater than 0"); RETURN_THROWS(); } + if (!zend_finite(output)) { + zend_argument_value_error(3, "must be finite"); + RETURN_THROWS(); + } + gamma = input / output; im = php_gd_libgdimageptr_from_zval_p(IM); @@ -2982,7 +2983,8 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode) zend_long X, Y, COL; zend_string *C; gdImagePtr im; - int ch = 0, col, x, y, i; + int ch = 0, col, i; + unsigned int x, y; size_t l = 0; unsigned char *str = NULL; zend_object *font_obj = NULL; @@ -3015,21 +3017,21 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode) switch (mode) { case 0: - gdImageChar(im, font, x, y, ch, col); + gdImageChar(im, font, (int)x, (int)y, ch, col); break; case 1: php_gdimagecharup(im, font, x, y, ch, col); break; case 2: for (i = 0; (i < l); i++) { - gdImageChar(im, font, x, y, (int) ((unsigned char) str[i]), col); + gdImageChar(im, font, (int)x, (int)y, (int) ((unsigned char) str[i]), col); x += font->w; } break; case 3: { for (i = 0; (i < l); i++) { /* php_gdimagecharup(im, font, x, y, (int) str[i], col); */ - gdImageCharUp(im, font, x, y, (int) str[i], col); + gdImageCharUp(im, font, (int)x, (int)y, (int) str[i], col); y -= font->w; } break; @@ -3604,7 +3606,20 @@ static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS) colors = safe_emalloc(num_colors, sizeof(int), 0); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(hash_colors), color) { - *(colors + i++) = (int) zval_get_long(color); + bool failed = false; + ZVAL_DEREF(color); + zend_long tmp = zval_try_get_long(color, &failed); + if (failed) { + efree(colors); + zend_argument_type_error(5, "must be of type int, %s given", zend_zval_type_name(color)); + RETURN_THROWS(); + } + if (tmp < 0 || ZEND_LONG_INT_OVFL(tmp)) { + efree(colors); + zend_argument_value_error(5, "value must be between 0 and %d", INT_MAX); + RETURN_THROWS(); + } + colors[i++] = (int) tmp; } ZEND_HASH_FOREACH_END(); RETVAL_BOOL(gdImageScatterColor(im, (int)scatter_sub, (int)scatter_plus, colors, num_colors)); @@ -3621,7 +3636,7 @@ PHP_FUNCTION(imagefilter) zval *tmp; typedef void (*image_filter)(INTERNAL_FUNCTION_PARAMETERS); - zend_long filtertype; + zend_long filtertype = 0; image_filter filters[] = { php_image_filter_negate , @@ -3639,15 +3654,17 @@ PHP_FUNCTION(imagefilter) php_image_filter_scatter }; - if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > IMAGE_FILTER_MAX_ARGS) { - WRONG_PARAM_COUNT; - } else if (zend_parse_parameters(2, "Ol", &tmp, gd_image_ce, &filtertype) == FAILURE) { + /* We need to do some initial ZPP parsing to be able to extract the filter value */ + if (zend_parse_parameters(MIN(2, ZEND_NUM_ARGS()), "Ol*", &tmp, gd_image_ce, &filtertype) == FAILURE) { + RETURN_THROWS(); } - if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) { - filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (UNEXPECTED(filtertype < 0 || filtertype > IMAGE_FILTER_MAX)) { + zend_argument_value_error(2, "must be one of the IMG_FILTER_* filter constants"); + RETURN_THROWS(); } + filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ @@ -3770,6 +3787,23 @@ PHP_FUNCTION(imageantialias) } /* }}} */ +static bool php_gd_zval_try_get_c_int(zval *tmp, const char *field, int *res) { + zend_long r; + bool failed = false; + ZVAL_DEREF(tmp); + r = zval_try_get_long(tmp, &failed); + if (failed) { + zend_argument_type_error(2, "\"%s\" key must be of type int, %s given", field, zend_zval_type_name(tmp)); + return false; + } + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(r))) { + zend_argument_value_error(2, "\"%s\" key must be between %d and %d", field, INT_MIN, INT_MAX); + return false; + } + *res = (int)r; + return true; +} + /* {{{ Crop an image using the given coordinates and size, x, y, width and height. */ PHP_FUNCTION(imagecrop) { @@ -3788,28 +3822,36 @@ PHP_FUNCTION(imagecrop) im = php_gd_libgdimageptr_from_zval_p(IM); if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "x", sizeof("x") -1)) != NULL) { - rect.x = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "x", &rect.x)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have an \"x\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "y", sizeof("y") - 1)) != NULL) { - rect.y = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "y", &rect.y)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have a \"y\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "width", sizeof("width") - 1)) != NULL) { - rect.width = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "width", &rect.width)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have a \"width\" key"); RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "height", sizeof("height") - 1)) != NULL) { - rect.height = zval_get_long(tmp); + if (!php_gd_zval_try_get_c_int(tmp, "height", &rect.height)) { + RETURN_THROWS(); + } } else { zend_argument_value_error(2, "must have a \"height\" key"); RETURN_THROWS(); @@ -3935,9 +3977,17 @@ PHP_FUNCTION(imagescale) src_y = gdImageSY(im); if (src_x && tmp_h < 0) { + if (tmp_w > (ZEND_LONG_MAX / src_y)) { + zend_argument_value_error(2, "must be less than or equal to " ZEND_LONG_FMT, (zend_long)(ZEND_LONG_MAX / src_y)); + RETURN_THROWS(); + } tmp_h = tmp_w * src_y / src_x; } if (src_y && tmp_w < 0) { + if (tmp_h > (ZEND_LONG_MAX / src_x)) { + zend_argument_value_error(3, "must be less than or equal to " ZEND_LONG_FMT, (zend_long)(ZEND_LONG_MAX / src_x)); + RETURN_THROWS(); + } tmp_w = tmp_h * src_x / src_y; } } @@ -4304,7 +4354,7 @@ PHP_FUNCTION(imageresolution) * * Stream Handling * Formerly contained within ext/gd/gd_ctx.c and included - * at the the top of this file + * at the top of this file * ********************************************************/ @@ -4392,7 +4442,7 @@ static gdIOCtx *create_output_context(zval *to_zval, uint32_t arg_num) { } close_stream = 0; } else if (Z_TYPE_P(to_zval) == IS_STRING) { - if (CHECK_ZVAL_NULL_PATH(to_zval)) { + if (zend_str_has_nul_byte(Z_STR_P(to_zval))) { zend_argument_type_error(arg_num, "must not contain null bytes"); return NULL; } diff --git a/ext/gd/gd.stub.php b/ext/gd/gd.stub.php index b3b82766ee98..0632724b44f3 100644 --- a/ext/gd/gd.stub.php +++ b/ext/gd/gd.stub.php @@ -449,17 +449,11 @@ * /usr/include/pngconf.h:310:2: error: #error png.h already includes setjmp.h with some additional fixup. * as error, use the values for now... */ -/** @var int */ const PNG_NO_FILTER = 0x00; -/** @var int */ const PNG_FILTER_NONE = 0x08; -/** @var int */ const PNG_FILTER_SUB = 0x10; -/** @var int */ const PNG_FILTER_UP = 0x20; -/** @var int */ const PNG_FILTER_AVG = 0x40; -/** @var int */ const PNG_FILTER_PAETH = 0x80; /** @var int */ const PNG_ALL_FILTERS = 0x08 | 0x10 | 0x20 | 0x40 | 0x80; @@ -589,14 +583,10 @@ function imagecreatefromgd2(string $filename): GdImage|false {} /** @refcount 1 */ function imagecreatefromgd2part(string $filename, int $x, int $y, int $width, int $height): GdImage|false {} -#ifdef HAVE_GD_BMP /** @refcount 1 */ function imagecreatefrombmp(string $filename): GdImage|false {} -#endif -#ifdef HAVE_GD_TGA function imagecreatefromtga(string $filename): GdImage|false {} -#endif function imagexbm(GdImage $image, ?string $filename, ?int $foreground_color = null): bool {} @@ -630,11 +620,10 @@ function imagegd(GdImage $image, ?string $file = null): bool {} function imagegd2(GdImage $image, ?string $file = null, int $chunk_size = 128, int $mode = IMG_GD2_RAW): bool {} -#ifdef HAVE_GD_BMP /** @param resource|string|null $file */ function imagebmp(GdImage $image, $file = null, bool $compressed = true): bool {} -#endif +#[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.0")] function imagedestroy(GdImage $image): true {} function imagecolorallocate(GdImage $image, int $red, int $green, int $blue): int|false {} diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index c80aaac46334..6b6327fd682f 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 94822f6472750c646fc138f383278ca692b39d27 */ +/* This is a generated file, edit gd.stub.php instead. + * Stub hash: 2cdc0b485d9b62bb9021973d3c8cce0169b21ac0 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gd_info, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -191,17 +191,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefromgd2part, 0, 5 ZEND_ARG_TYPE_INFO(0, height, IS_LONG, 0) ZEND_END_ARG_INFO() -#if defined(HAVE_GD_BMP) -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefrombmp, 0, 1, GdImage, MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) -ZEND_END_ARG_INFO() -#endif +#define arginfo_imagecreatefrombmp arginfo_imagecreatefromgif -#if defined(HAVE_GD_TGA) -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefromtga, 0, 1, GdImage, MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) -ZEND_END_ARG_INFO() -#endif +#define arginfo_imagecreatefromtga arginfo_imagecreatefromgif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagexbm, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) @@ -266,13 +258,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagegd2, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "IMG_GD2_RAW") ZEND_END_ARG_INFO() -#if defined(HAVE_GD_BMP) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagebmp, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, file, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, compressed, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagedestroy, 0, 1, IS_TRUE, 0) ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) @@ -619,12 +609,8 @@ ZEND_FUNCTION(imagecreatefromwbmp); ZEND_FUNCTION(imagecreatefromgd); ZEND_FUNCTION(imagecreatefromgd2); ZEND_FUNCTION(imagecreatefromgd2part); -#if defined(HAVE_GD_BMP) ZEND_FUNCTION(imagecreatefrombmp); -#endif -#if defined(HAVE_GD_TGA) ZEND_FUNCTION(imagecreatefromtga); -#endif ZEND_FUNCTION(imagexbm); #if defined(HAVE_GD_AVIF) ZEND_FUNCTION(imageavif); @@ -642,9 +628,7 @@ ZEND_FUNCTION(imagejpeg); ZEND_FUNCTION(imagewbmp); ZEND_FUNCTION(imagegd); ZEND_FUNCTION(imagegd2); -#if defined(HAVE_GD_BMP) ZEND_FUNCTION(imagebmp); -#endif ZEND_FUNCTION(imagedestroy); ZEND_FUNCTION(imagecolorallocate); ZEND_FUNCTION(imagepalettecopy); @@ -755,12 +739,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(imagecreatefromgd, arginfo_imagecreatefromgd) ZEND_FE(imagecreatefromgd2, arginfo_imagecreatefromgd2) ZEND_FE(imagecreatefromgd2part, arginfo_imagecreatefromgd2part) -#if defined(HAVE_GD_BMP) ZEND_FE(imagecreatefrombmp, arginfo_imagecreatefrombmp) -#endif -#if defined(HAVE_GD_TGA) ZEND_FE(imagecreatefromtga, arginfo_imagecreatefromtga) -#endif ZEND_FE(imagexbm, arginfo_imagexbm) #if defined(HAVE_GD_AVIF) ZEND_FE(imageavif, arginfo_imageavif) @@ -778,10 +758,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(imagewbmp, arginfo_imagewbmp) ZEND_FE(imagegd, arginfo_imagegd) ZEND_FE(imagegd2, arginfo_imagegd2) -#if defined(HAVE_GD_BMP) ZEND_FE(imagebmp, arginfo_imagebmp) -#endif - ZEND_FE(imagedestroy, arginfo_imagedestroy) + ZEND_RAW_FENTRY("imagedestroy", zif_imagedestroy, arginfo_imagedestroy, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(imagecolorallocate, arginfo_imagecolorallocate) ZEND_FE(imagepalettecopy, arginfo_imagepalettecopy) ZEND_FE(imagecolorat, arginfo_imagecolorat) @@ -945,6 +923,14 @@ static void register_gd_symbols(int module_number) REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH", 0x80, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS", 0x8 | 0x10 | 0x20 | 0x40 | 0x80, CONST_PERSISTENT); #endif + + + zend_attribute *attribute_Deprecated_func_imagedestroy_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "imagedestroy", sizeof("imagedestroy") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_imagedestroy_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_imagedestroy_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_imagedestroy_0_arg1_str = zend_string_init("as it has no effect since PHP 8.0", strlen("as it has no effect since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_imagedestroy_0->args[1].value, attribute_Deprecated_func_imagedestroy_0_arg1_str); + attribute_Deprecated_func_imagedestroy_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_GdImage(void) diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 71a0e9ea63f2..47c4dbc0d770 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1783,6 +1783,9 @@ void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) a=w>>1; b=h>>1; + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } gdImageSetPixel(im,mx+a, my, c); gdImageSetPixel(im,mx-a, my, c); mx1 = mx-a;my1 = my; @@ -1824,7 +1827,9 @@ void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c) a=w>>1; b=h>>1; - + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } for (x = mx-a; x <= mx+a; x++) { gdImageSetPixel(im, x, my, c); } @@ -2879,12 +2884,12 @@ void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c) void gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels) { - if (im->style) { - gdFree(im->style); - } if (overflow2(sizeof (int), noOfPixels)) { return; } + if (im->style) { + gdFree(im->style); + } im->style = (int *) gdMalloc(sizeof(int) * noOfPixels); memcpy(im->style, style, sizeof(int) * noOfPixels); im->styleLength = noOfPixels; diff --git a/ext/gd/libgd/gd_filter.c b/ext/gd/libgd/gd_filter.c index d567898548d2..97dea5c552cd 100644 --- a/ext/gd/libgd/gd_filter.c +++ b/ext/gd/libgd/gd_filter.c @@ -7,6 +7,7 @@ #else # include #endif +#include #include #include @@ -20,6 +21,20 @@ /* Begin filters function */ #define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel) +static int gdClampFloatToByte(float value) +{ + if (!isfinite(value)) { + return value > 0.0f ? 255 : 0; + } + if (value > 255.0f) { + return 255; + } + if (value < 0.0f) { + return 0; + } + return (int)value; +} + #ifdef _WIN32 # define GD_SCATTER_SEED() (unsigned int)(time(0) * GetCurrentProcessId()) #else @@ -417,6 +432,7 @@ int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, flo for ( y=0; ysy; y++) { for(x=0; xsx; x++) { + int new_ri, new_gi, new_bi; new_r = new_g = new_b = 0; pxl = f(srcback, x, y); new_a = gdImageAlpha(srcback, pxl); @@ -435,13 +451,13 @@ int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, flo new_g = (new_g/filter_div)+offset; new_b = (new_b/filter_div)+offset; - new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r); - new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g); - new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b); + new_ri = gdClampFloatToByte(new_r); + new_gi = gdClampFloatToByte(new_g); + new_bi = gdClampFloatToByte(new_b); - new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + new_pxl = gdImageColorAllocateAlpha(src, new_ri, new_gi, new_bi, new_a); if (new_pxl == -1) { - new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a); + new_pxl = gdImageColorClosestAlpha(src, new_ri, new_gi, new_bi, new_a); } gdImageSetPixel (src, x, y, new_pxl); } diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c index f0974c2a99d4..c15a97c7b592 100644 --- a/ext/gd/libgd/gd_jpeg.c +++ b/ext/gd/libgd/gd_jpeg.c @@ -125,6 +125,10 @@ const char * gdJpegGetVersionString() return "9 compatible"; break; + case 100: + return "10 compatible"; + break; + default: return "unknown"; } diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c index 438a564ff17c..cbc4872d2fce 100644 --- a/ext/gd/libgd/gd_security.c +++ b/ext/gd/libgd/gd_security.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "gd.h" #include "gd_errors.h" @@ -30,3 +31,20 @@ int overflow2(int a, int b) } return 0; } + +int overflowMul3(int a, int b, int c) +{ + if (a < 0 || b < 0 || c < 0) { + return 1; + } + if (a == 0 || b == 0 || c == 0) { + return 0; + } + if (a > INT_MAX / b) { + return 1; + } + if ((int64_t)a * b > INT64_MAX / c) { + return 1; + } + return 0; +} diff --git a/ext/gd/libgd/gd_xbm.c b/ext/gd/libgd/gd_xbm.c index 3c655a2998c1..bd81b8685b20 100644 --- a/ext/gd/libgd/gd_xbm.c +++ b/ext/gd/libgd/gd_xbm.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ @@ -191,7 +189,7 @@ void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out) } else { for (i=0; i. | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | @@ -23,7 +21,6 @@ #if defined(HAVE_LIBGD) || defined(HAVE_GD_BUNDLED) -/* open_basedir and safe_mode checks */ #define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \ if (!filename || php_check_open_basedir(filename)) { \ php_error_docref(NULL, E_WARNING, errormsg); \ diff --git a/ext/gd/tests/bug19366.phpt b/ext/gd/tests/bug19366.phpt index 7fae0be5d7e0..93288dc96ade 100644 --- a/ext/gd/tests/bug19366.phpt +++ b/ext/gd/tests/bug19366.phpt @@ -36,8 +36,6 @@ echo "Alive: Send to browser\n"; //Header("Content-type: image/PNG"); //ImagePNG($ImHandle); -echo "Alive: Free resources\n"; -imagedestroy($ImHandle); echo "Alive: Done\n"; ?> --EXPECT-- @@ -46,5 +44,4 @@ Alive: Define colors Alive: Draw Alive: ImageString Alive: Send to browser -Alive: Free resources Alive: Done diff --git a/ext/gd/tests/bug28147.phpt b/ext/gd/tests/bug28147.phpt index 90314b153225..0578f659bd93 100644 --- a/ext/gd/tests/bug28147.phpt +++ b/ext/gd/tests/bug28147.phpt @@ -16,8 +16,6 @@ imagefilledrectangle($im,0,0,299,299,$w); imageantialias($im,true); imageline($im, 299, 299, 0, 299, $red); -imagedestroy($im); - echo "Alive\n"; ?> --EXPECT-- diff --git a/ext/gd/tests/bug36697-mb.phpt b/ext/gd/tests/bug36697-mb.phpt index 0a661012bcb0..f061076da72d 100644 --- a/ext/gd/tests/bug36697-mb.phpt +++ b/ext/gd/tests/bug36697-mb.phpt @@ -13,7 +13,7 @@ imagecolortransparent($im, $trans_color); imagefilledrectangle($im, 0,0, 192,36, $trans_color); $c = imagecolorat($im, 191,35); imagegif($im, $dest); -imagedestroy($im); +$im = null; $im = imagecreatefromgif($dest); $c = imagecolorat($im, 191, 35); $colors = imagecolorsforindex($im, $c); diff --git a/ext/gd/tests/bug36697.phpt b/ext/gd/tests/bug36697.phpt index ae6cc5bc64d1..838750ccf251 100644 --- a/ext/gd/tests/bug36697.phpt +++ b/ext/gd/tests/bug36697.phpt @@ -13,7 +13,7 @@ imagecolortransparent($im, $trans_color); imagefilledrectangle($im, 0,0, 192,36, $trans_color); $c = imagecolorat($im, 191,35); imagegif($im, $dest); -imagedestroy($im); +$im = null; $im = imagecreatefromgif($dest); $c = imagecolorat($im, 191, 35); $colors = imagecolorsforindex($im, $c); diff --git a/ext/gd/tests/bug38179.phpt b/ext/gd/tests/bug38179.phpt index 17e9ed28406e..1dee6687677d 100644 --- a/ext/gd/tests/bug38179.phpt +++ b/ext/gd/tests/bug38179.phpt @@ -18,8 +18,6 @@ imagecopy($dst_tc, $src, 0,0, 0,0, imagesx($src), imagesy($src)); $p1 = imagecolorat($dst_tc, 3,3); printf("%X\n", $p1); - -imagedestroy($src); imagedestroy($dst_tc); ?> --EXPECT-- 46FF0000 diff --git a/ext/gd/tests/bug42434.phpt b/ext/gd/tests/bug42434.phpt index d7cca5ab6b34..ddc6c8000d62 100644 --- a/ext/gd/tests/bug42434.phpt +++ b/ext/gd/tests/bug42434.phpt @@ -15,8 +15,6 @@ if (imagecolorat($im, 9, 0) == 0x000000) { } else { echo 'Bugged'; } - -imagedestroy($im); ?> --EXPECT-- DONE diff --git a/ext/gd/tests/bug43121.phpt b/ext/gd/tests/bug43121.phpt index 21550a03c88d..81eb564a5e69 100644 --- a/ext/gd/tests/bug43121.phpt +++ b/ext/gd/tests/bug43121.phpt @@ -17,8 +17,6 @@ $im_tile = ImageCreateFromGif(__DIR__ . "/bug43121.gif" ); ImageSetTile( $im, $im_tile ); ImageFill( $im, 0, 0, IMG_COLOR_TILED ); -ImageDestroy( $im ); - print "OK"; ?> --EXPECT-- diff --git a/ext/gd/tests/bug43828.phpt b/ext/gd/tests/bug43828.phpt index 8bc3f9bbcaf8..fd6620666f8d 100644 --- a/ext/gd/tests/bug43828.phpt +++ b/ext/gd/tests/bug43828.phpt @@ -23,8 +23,6 @@ imagefilledarc($im, 49, 49, 99,99, 0 , 360, $color, IMG_ARC_PIE); include_once __DIR__ . '/func.inc'; test_image_equals_file(__DIR__ . '/bug43828.png', $im); - -imagedestroy($im); ?> --EXPECT-- The images are equal. diff --git a/ext/gd/tests/bug45799.phpt b/ext/gd/tests/bug45799.phpt index f7124ce5b971..dc20efdbb942 100644 --- a/ext/gd/tests/bug45799.phpt +++ b/ext/gd/tests/bug45799.phpt @@ -12,7 +12,6 @@ if (!(imagetypes() & IMG_PNG)) { --EXPECTF-- Warning: imagepng(): gd-png error: no colors in palette%win %s on line %d diff --git a/ext/gd/tests/bug50194.phpt b/ext/gd/tests/bug50194.phpt index 33d2400c46e8..860ac3d50532 100644 --- a/ext/gd/tests/bug50194.phpt +++ b/ext/gd/tests/bug50194.phpt @@ -32,8 +32,6 @@ if (isset($matches[1]) && $matches[1] > 2000) { } else { echo "The images are similar.\n"; } - -imagedestroy($im); ?> --EXPECT-- The images are similar. diff --git a/ext/gd/tests/bug61221.phpt b/ext/gd/tests/bug61221.phpt index 97a90db045b3..fa2d89cff34d 100644 --- a/ext/gd/tests/bug61221.phpt +++ b/ext/gd/tests/bug61221.phpt @@ -15,7 +15,6 @@ imageline($img, 0, $imageh / 2, $imagew - 1, $imageh / 2, $redsolid); imagegammacorrect($img, 1, 1); $color = imagecolorat($img, 0, 0); var_dump($color === $blacktransparent); -imagedestroy($img); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/bug65148.phpt b/ext/gd/tests/bug65148.phpt index 4dfa13ccaa92..0d71655aad10 100644 --- a/ext/gd/tests/bug65148.phpt +++ b/ext/gd/tests/bug65148.phpt @@ -37,10 +37,8 @@ foreach ($interpolations as $name => $interpolation) { $t = imagecolorallocatealpha($img, 0, 0, 0, 127); $imgr = imagerotate($img, -5, $t); $results[$name] = array('x' => imagesx($imgr), 'y' => imagesy($imgr)); - imagedestroy($imgr); } -imagedestroy($img); print_r($results); ?> --EXPECT-- diff --git a/ext/gd/tests/bug66356.phpt b/ext/gd/tests/bug66356.phpt index b65fb54f5718..616a270115c1 100644 --- a/ext/gd/tests/bug66356.phpt +++ b/ext/gd/tests/bug66356.phpt @@ -7,10 +7,14 @@ gd $img = imagecreatetruecolor(10, 10); // POC #1 -var_dump(imagecrop($img, array("x" => "a", "y" => 0, "width" => 10, "height" => 10))); +var_dump(imagecrop($img, array("x" => 0, "y" => 0, "width" => 10, "height" => 10))); -$arr = array("x" => "a", "y" => "12b", "width" => 10, "height" => 10); -var_dump(imagecrop($img, $arr)); +$arr = array("x" => 2147483647, "y" => 2147483647, "width" => 10, "height" => 10); +try { + imagecrop($img, $arr); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} print_r($arr); // POC #2 @@ -28,12 +32,11 @@ var_dump(imagecrop($img, array("x" => 0, "y" => 0, "width" => 65535, "height" => --EXPECTF-- object(GdImage)#2 (0) { } -object(GdImage)#2 (0) { -} +imagecrop(): Argument #2 ($rectangle) overflow with "x" and "width" keys Array ( - [x] => a - [y] => 12b + [x] => 2147483647 + [y] => 2147483647 [width] => 10 [height] => 10 ) @@ -41,9 +44,9 @@ Array Warning: imagecrop(): %cne parameter to a memory allocation multiplication is negative or zero, failing operation gracefully in %s on line %d bool(false) -object(GdImage)#2 (0) { +object(GdImage)#3 (0) { } -object(GdImage)#2 (0) { +object(GdImage)#3 (0) { } Warning: imagecrop(): %croduct of memory allocation multiplication would exceed INT_MAX, failing operation gracefully diff --git a/ext/gd/tests/bug67325.phpt b/ext/gd/tests/bug67325.phpt index b1e84242a4a3..fe5602567f8a 100644 --- a/ext/gd/tests/bug67325.phpt +++ b/ext/gd/tests/bug67325.phpt @@ -24,8 +24,6 @@ for ($i = 0; $i < 256; $i++) { } } var_dump($white); - -imagedestroy($im); ?> --EXPECT-- int(0) diff --git a/ext/gd/tests/bug67447.phpt b/ext/gd/tests/bug67447.phpt index e78e272ff2e7..f8e4d20c794d 100644 --- a/ext/gd/tests/bug67447.phpt +++ b/ext/gd/tests/bug67447.phpt @@ -10,8 +10,6 @@ $red = imagecolorallocate($image, 255, 0, 0); imagefill($image, 0, 0, $red); $cropped = imagecrop($image, ['x' => 0, 'y' => 0, 'width' => 250, 'height' => 250]); var_dump(imagecolorat($cropped, 249, 249) === $red); -imagedestroy($image); -imagedestroy($cropped); // palette $image = imagecreate(500, 500); @@ -20,8 +18,6 @@ $red = imagecolorallocate($image, 255, 0, 0); imagefill($image, 0, 0, $red); $cropped = imagecrop($image, ['x' => 0, 'y' => 0, 'width' => 250, 'height' => 250]); var_dump(imagecolorsforindex($cropped, imagecolorat($cropped, 249, 249))); -imagedestroy($image); -imagedestroy($cropped); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/bug69024.phpt b/ext/gd/tests/bug69024.phpt index da80a5b609a8..d6eaa40a31f8 100644 --- a/ext/gd/tests/bug69024.phpt +++ b/ext/gd/tests/bug69024.phpt @@ -6,7 +6,6 @@ gd --EXPECT-- diff --git a/ext/gd/tests/bug70102.phpt b/ext/gd/tests/bug70102.phpt index bfdcbd377a3a..63a81f7cc46a 100644 --- a/ext/gd/tests/bug70102.phpt +++ b/ext/gd/tests/bug70102.phpt @@ -19,7 +19,6 @@ $white = imagecolorallocate($im, 255, 255, 255); var_dump($white & 0xffffff); imagefilledrectangle($im, 0, 0, 7, 7, $white); imagewebp($im, $filename); -imagedestroy($im); $im = imagecreatefromwebp($filename); $color = imagecolorat($im, 4, 4); diff --git a/ext/gd/tests/bug72339.phpt b/ext/gd/tests/bug72339.phpt index 561a1b347b51..c6c30c502076 100644 --- a/ext/gd/tests/bug72339.phpt +++ b/ext/gd/tests/bug72339.phpt @@ -33,9 +33,6 @@ fclose($fh); $im = imagecreatefromgd2($fname); -if ($im) { - imagedestroy($im); -} unlink($fname); ?> diff --git a/ext/gd/tests/bug72709.phpt b/ext/gd/tests/bug72709.phpt index b0b4aa77bdf9..bc20d1bf58b8 100644 --- a/ext/gd/tests/bug72709.phpt +++ b/ext/gd/tests/bug72709.phpt @@ -14,7 +14,6 @@ catch (\Error $ex) { } imagesetpixel($im, 0, 0, IMG_COLOR_STYLED); -imagedestroy($im); ?> ====DONE==== --EXPECT-- diff --git a/ext/gd/tests/bug77198_auto.phpt b/ext/gd/tests/bug77198_auto.phpt index 9df67d7f2ff6..5153ec4870a9 100644 --- a/ext/gd/tests/bug77198_auto.phpt +++ b/ext/gd/tests/bug77198_auto.phpt @@ -39,9 +39,7 @@ for ($y = 0; $y < 8; $y++) { if ($color !== 0x000000) { printf("Pixel at %d, %d: unexpected color (%d)\n", $x, $y, $color); } - imagedestroy($cropped); } - imagedestroy($orig); } } diff --git a/ext/gd/tests/bug77198_threshold.phpt b/ext/gd/tests/bug77198_threshold.phpt index e164286afca5..662ebbe75c04 100644 --- a/ext/gd/tests/bug77198_threshold.phpt +++ b/ext/gd/tests/bug77198_threshold.phpt @@ -36,9 +36,7 @@ for ($y = 0; $y < 8; $y++) { if ($color !== 0x000000) { printf("Pixel at %d, %d: unexpected color (%d)\n", $x, $y, $color); } - imagedestroy($cropped); } - imagedestroy($orig); } } diff --git a/ext/gd/tests/bug77270.phpt b/ext/gd/tests/bug77270.phpt index 33246880c53d..77608757f8f4 100644 --- a/ext/gd/tests/bug77270.phpt +++ b/ext/gd/tests/bug77270.phpt @@ -1,7 +1,5 @@ --TEST-- Bug #77270 (imagecolormatch Out Of Bounds Write on Heap) ---INI-- -memory_limit=-1 --EXTENSIONS-- gd --SKIPIF-- diff --git a/ext/gd/tests/bug77272.phpt b/ext/gd/tests/bug77272.phpt index f2483f915c17..11fd3b3ce569 100644 --- a/ext/gd/tests/bug77272.phpt +++ b/ext/gd/tests/bug77272.phpt @@ -6,6 +6,7 @@ memory_limit=-1 gd --SKIPIF-- --FILE-- --INI-- diff --git a/ext/gd/tests/bug79945.phpt b/ext/gd/tests/bug79945.phpt index 5db958e36d35..46dac358d8e2 100644 --- a/ext/gd/tests/bug79945.phpt +++ b/ext/gd/tests/bug79945.phpt @@ -9,17 +9,17 @@ if (!(imagetypes() & IMG_PNG)) { } set_error_handler(function($errno, $errstr) { if (str_contains($errstr, 'Cannot cast a filtered stream on this system')) { - die('skip: fopencookie not support on this system'); + die('skip: fopencookie not supported on this system'); } }); -imagecreatefrompng('php://filter/read=convert.base64-encode/resource=' . __DIR__ . '/test.png'); +imagecreatefrompng('php://filter/read=string.rot13/resource=' . __DIR__ . '/test.png'); restore_error_handler(); ?> --FILE-- --CLEAN-- --EXPECTF-- -Warning: imagecreatefrompng(): "php://filter/read=convert.base64-encode/resource=%s" is not a valid PNG file in %s on line %d +Warning: imagecreatefrompng(): "php://filter/read=string.rot13/resource=%s" is not a valid PNG file in %s on line %d diff --git a/ext/gd/tests/colorat.phpt b/ext/gd/tests/colorat.phpt index d0e62aca9102..82d6d56b5c7b 100644 --- a/ext/gd/tests/colorat.phpt +++ b/ext/gd/tests/colorat.phpt @@ -15,7 +15,6 @@ echo 'test colorat truecolor: '; $c = imagecolorat($im, 3,3); echo $c == 0x0 ? 'ok' : 'failed'; echo "\n"; -imagedestroy($im); $im = imagecreate(6,6); $c1 = imagecolorallocate($im, 255,255,255); diff --git a/ext/gd/tests/colorclosest.phpt b/ext/gd/tests/colorclosest.phpt index 2633b24017d1..8cfcbdcdea4e 100644 --- a/ext/gd/tests/colorclosest.phpt +++ b/ext/gd/tests/colorclosest.phpt @@ -8,7 +8,7 @@ gd $im = imagecreatetruecolor(5,5); $c = imagecolorclosest($im, 255,0,255); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorclosest($im, 255,0,255); @@ -17,13 +17,13 @@ try { } catch (ValueError $exception) { echo $exception->getMessage() . "\n"; } -imagedestroy($im); +$im = null; $im = imagecreate(5,5); imagecolorallocate($im, 255, 0, 255); $c = imagecolorclosest($im, 255,0,255); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolve($im, $i,0,0); @@ -46,7 +46,7 @@ print_r(imagecolorsforindex($im, $c)); $im = imagecreatetruecolor(5,5); $c = imagecolorclosestalpha($im, 255,0,255,100); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorclosestalpha($im, 255,0,255,100); @@ -55,13 +55,13 @@ try { } catch (ValueError $exception) { echo $exception->getMessage() . "\n"; } -imagedestroy($im); +$im = null; $im = imagecreate(5,5); imagecolorallocatealpha($im, 255, 0, 255, 1); $c = imagecolorclosestalpha($im, 255,0,255,1); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolvealpha($im, $i,0,0,1); diff --git a/ext/gd/tests/colorexact.phpt b/ext/gd/tests/colorexact.phpt index 361701c77d36..c28ad54d5016 100644 --- a/ext/gd/tests/colorexact.phpt +++ b/ext/gd/tests/colorexact.phpt @@ -12,7 +12,7 @@ $c2 = imagecolorexactalpha($im, 255,0,255, 100); printf("%X\n", $c); printf("%X\n", $c2); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorallocate($im, 255,0,255); @@ -26,8 +26,6 @@ echo imagecolorexactalpha($im, 255,200,0,100) . "\n"; // unallocated index echo imagecolorexact($im, 12,12,12) . "\n"; - -imagedestroy($im); ?> --EXPECT-- FF00FF diff --git a/ext/gd/tests/colormatch.phpt b/ext/gd/tests/colormatch.phpt index 65b690ecd015..fe22784c9942 100644 --- a/ext/gd/tests/colormatch.phpt +++ b/ext/gd/tests/colormatch.phpt @@ -15,8 +15,6 @@ try { } echo "ok\n"; - -imagedestroy($im); ?> --EXPECT-- imagecolormatch(): Argument #2 ($image2) must have at least one color diff --git a/ext/gd/tests/colorresolve.phpt b/ext/gd/tests/colorresolve.phpt index 08daa4bb5f04..595018e73dcd 100644 --- a/ext/gd/tests/colorresolve.phpt +++ b/ext/gd/tests/colorresolve.phpt @@ -8,12 +8,12 @@ gd $im = imagecreatetruecolor(5,5); $c = imagecolorresolve($im, 255,0,255); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorresolve($im, 255,0,255); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolve($im, $i,0,0); @@ -38,12 +38,12 @@ print_r(imagecolorsforindex($im, $c)); $im = imagecreatetruecolor(5,5); $c = imagecolorresolvealpha($im, 255,0,255, 100); printf("%X\n", $c); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); $c = imagecolorresolvealpha($im, 255,0,255,100); print_r(imagecolorsforindex($im, $c)); -imagedestroy($im); +$im = null; $im = imagecreate(5,5); for ($i=0; $i<255; $i++) imagecolorresolvealpha($im, $i,0,0,1); diff --git a/ext/gd/tests/copy.phpt b/ext/gd/tests/copy.phpt index 5f099090e661..dc0b5ca1293b 100644 --- a/ext/gd/tests/copy.phpt +++ b/ext/gd/tests/copy.phpt @@ -22,7 +22,8 @@ if ($p1 && $p2 && $p3) { echo "TC/TC: ok\n"; } -imagedestroy($src_tc); imagedestroy($dst_tc); +$src_tc = null; +$dst_tc = null; $src_tc = imagecreatetruecolor(5,5); @@ -46,7 +47,8 @@ $p3 = $c3['red'] == 0x00 && $c3['blue']==0x00 && $c3['green']==0xff; if ($p1 && $p2 && $p3) { echo "TC/P: ok\n"; } -imagedestroy($src_tc); imagedestroy($dst_tc); +$src_tc = null; +$dst_tc = null; diff --git a/ext/gd/tests/dashedlines.phpt b/ext/gd/tests/dashedlines.phpt index 11b2e83fad46..552b2bfc2976 100644 --- a/ext/gd/tests/dashedlines.phpt +++ b/ext/gd/tests/dashedlines.phpt @@ -26,7 +26,7 @@ $p5 = imagecolorat($im, 5,5) == $b; if ($p1 && $p2 && $p3 && $p4 && $p5) { echo "Horizontal: ok\n"; } -imagedestroy($im); +$im = null; $im = imagecreatetruecolor(6,6); imagefill($im, 0,0, 0xffffff); @@ -46,7 +46,7 @@ $p6 = imagecolorat($im, 2,5) == $b; if ($p1 && $p2 && $p3 && $p4 && $p5 && $p6) { echo "Vertical: ok\n"; } -imagedestroy($im); +$im = null; $im = imagecreatetruecolor(6,6); @@ -66,9 +66,6 @@ $p6 = imagecolorat($im, 5,5) == $b; if ($p1 && $p2 && $p3 && $p4 && $p5 && $p6) { echo "Diagonal: ok\n"; } -imagedestroy($im); - - ?> --EXPECT-- Horizontal: ok diff --git a/ext/gd/tests/gh16232.phpt b/ext/gd/tests/gh16232.phpt index 7f839d737bb5..469ae633c5da 100644 --- a/ext/gd/tests/gh16232.phpt +++ b/ext/gd/tests/gh16232.phpt @@ -9,10 +9,10 @@ $bad_webp = __DIR__ . "/gh16232.webp"; copy($good_webp, $bad_webp); var_dump(imagecreatefromwbmp($bad_webp)); $data = file_get_contents($bad_webp); -$data[3] = chr(-1); +$data[3] = chr(255); file_put_contents($bad_webp, $data); var_dump(imagecreatefromwbmp($bad_webp)); -$data[3] = chr(1000); +$data[3] = chr(232); file_put_contents($bad_webp, $data); var_dump(imagecreatefromwbmp($bad_webp)); unlink($bad_webp); diff --git a/ext/gd/tests/gh16322.phpt b/ext/gd/tests/gh16322.phpt index 1edc27285d2d..1e5ab2f3a6b1 100644 --- a/ext/gd/tests/gh16322.phpt +++ b/ext/gd/tests/gh16322.phpt @@ -2,8 +2,6 @@ GH-16322 (imageaffine overflow/underflow on affine matrix) --EXTENSIONS-- gd ---INI-- -memory_limit=-1 --FILE-- --FILE-- --FILE-- +--FILE-- +getMessage() . PHP_EOL; +} +try { + imagesetstyle($img, [0, PHP_INT_MIN]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagefilter($img, IMG_FILTER_SCATTER, 0, 0, [new A()]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagefilter($img, IMG_FILTER_SCATTER, 0, 0, [-1]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => PHP_INT_MIN, "y" => 0, "width" => 0, "height" => 0]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => PHP_INT_MIN, "width" => 0, "height" => 0]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => PHP_INT_MAX, "height" => 0]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => 0, "height" => PHP_INT_MAX]); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + imagecrop($img, ["x" => new A(), "y" => 0, "width" => 0, "height" => 0]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => new A(), "width" => 0, "height" => 0]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => new A(), "height" => 0]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} +try { + imagecrop($img, ["x" => 0, "y" => 0, "width" => 0, "height" => new A()]); +} catch (\TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} + +$one = 1; +var_dump(imagecrop($img, ["x" => &$one, "y" => &$one, "width" => &$one, "height" => &$one])); +?> +--EXPECTF-- +imagesetstyle(): Argument #2 ($style) must only have elements of type int, A given +imagesetstyle(): Argument #2 ($style) elements must be between %i and %d +imagefilter(): Argument #5 must be of type int, A given +imagefilter(): Argument #5 value must be between 0 and 2147483647 +imagecrop(): Argument #2 ($rectangle) "x" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "y" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "width" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "height" key must be between %i and %d +imagecrop(): Argument #2 ($rectangle) "x" key must be of type int, A given +imagecrop(): Argument #2 ($rectangle) "y" key must be of type int, A given +imagecrop(): Argument #2 ($rectangle) "width" key must be of type int, A given +imagecrop(): Argument #2 ($rectangle) "height" key must be of type int, A given +object(GdImage)#2 (0) { +} diff --git a/ext/gd/tests/gh19578.phpt b/ext/gd/tests/gh19578.phpt new file mode 100644 index 000000000000..15d10f752d0d --- /dev/null +++ b/ext/gd/tests/gh19578.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-19578: imagefilledellipse underflow on width argument +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + imagefilledellipse($src, 0, 0, -16, 254, 0); +} catch (\ValueError $e) { + echo $e->getMessage(); +} +?> +--EXPECTF-- +imagefilledellipse(): Argument #4 ($width) must be between 0 and %d +imagefilledellipse(): Argument #4 ($width) must be between 0 and %d diff --git a/ext/gd/tests/gh19578_32bits.phpt b/ext/gd/tests/gh19578_32bits.phpt new file mode 100644 index 000000000000..2cb73a60987e --- /dev/null +++ b/ext/gd/tests/gh19578_32bits.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-19578: imagefilledellipse underflow on width argument +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +imagefilledellipse(): Argument #4 ($width) must be between 0 and %d diff --git a/ext/gd/tests/gh19666.phpt b/ext/gd/tests/gh19666.phpt new file mode 100644 index 000000000000..ba9bf54f5661 --- /dev/null +++ b/ext/gd/tests/gh19666.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-19666 (Unexpected nan value in imageconvolution) +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +bool(true) +array(4) { + ["red"]=> + int(0) + ["green"]=> + int(0) + ["blue"]=> + int(0) + ["alpha"]=> + int(0) +} diff --git a/ext/gd/tests/gh19739.phpt b/ext/gd/tests/gh19739.phpt new file mode 100644 index 000000000000..7dce387b780e --- /dev/null +++ b/ext/gd/tests/gh19739.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-19739 (integer overflow in imageellipse / imagefilledellipse) +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +done diff --git a/ext/gd/tests/gh19955.phpt b/ext/gd/tests/gh19955.phpt new file mode 100644 index 000000000000..30787bfc11c3 --- /dev/null +++ b/ext/gd/tests/gh19955.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-19955: (imagefttext() memory leak) +--EXTENSIONS-- +gd +--CREDITS-- +YuanchengJiang +--SKIPIF-- + +--FILE-- + +--EXPECT-- +OK diff --git a/ext/gd/tests/gh20551.phpt b/ext/gd/tests/gh20551.phpt new file mode 100644 index 000000000000..32ca50ca5f62 --- /dev/null +++ b/ext/gd/tests/gh20551.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-20551: (imagegammacorrect out of range input/output value) +--EXTENSIONS-- +gd +--FILE-- +getMessage(), PHP_EOL; + } +} +?> +--EXPECT-- +imagegammacorrect(): Argument #2 ($input_gamma) must be finite +imagegammacorrect(): Argument #2 ($input_gamma) must be finite +imagegammacorrect(): Argument #2 ($input_gamma) must be finite +imagegammacorrect(): Argument #2 ($input_gamma) must be greater than 0 +imagegammacorrect(): Argument #3 ($output_gamma) must be finite +imagegammacorrect(): Argument #3 ($output_gamma) must be finite +imagegammacorrect(): Argument #3 ($output_gamma) must be finite +imagegammacorrect(): Argument #3 ($output_gamma) must be greater than 0 diff --git a/ext/gd/tests/gh20602.phpt b/ext/gd/tests/gh20602.phpt new file mode 100644 index 000000000000..29c781e76a2d --- /dev/null +++ b/ext/gd/tests/gh20602.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-20551: (imagegammacorrect out of range input/output value) +--EXTENSIONS-- +gd +--FILE-- +getMessage(), PHP_EOL; +} +try { + imagescale($im, -1, PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +imagescale(): Argument #2 ($width) must be less than or equal to %d +imagescale(): Argument #3 ($height) must be less than or equal to %d diff --git a/ext/gd/tests/gh20622.phpt b/ext/gd/tests/gh20622.phpt new file mode 100644 index 000000000000..42109ddc13e4 --- /dev/null +++ b/ext/gd/tests/gh20622.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-20622 (imagestring/imagestringup overflow/underflow) +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +OK diff --git a/ext/gd/tests/imagebmp_basic.phpt b/ext/gd/tests/imagebmp_basic.phpt index 31a62e674a84..82b14f06b3cd 100644 --- a/ext/gd/tests/imagebmp_basic.phpt +++ b/ext/gd/tests/imagebmp_basic.phpt @@ -4,7 +4,9 @@ imagebmp() - basic functionality gd --SKIPIF-- --FILE-- --EXPECT-- int(0) diff --git a/ext/gd/tests/imagecolorset_basic.phpt b/ext/gd/tests/imagecolorset_basic.phpt index 7677b85948aa..006202007fa2 100644 --- a/ext/gd/tests/imagecolorset_basic.phpt +++ b/ext/gd/tests/imagecolorset_basic.phpt @@ -28,7 +28,6 @@ imagecolorset($im, $bg, 0, 0, 255); imagepalettetotruecolor($im); include_once __DIR__ . '/func.inc'; test_image_equals_file(__DIR__ . '/imagecolorset_basic.png', $im); -imagedestroy($im); ?> --EXPECT-- The images are equal. diff --git a/ext/gd/tests/imagecolorstotal_basic.phpt b/ext/gd/tests/imagecolorstotal_basic.phpt index 8f90b05e235f..b95275cd3249 100644 --- a/ext/gd/tests/imagecolorstotal_basic.phpt +++ b/ext/gd/tests/imagecolorstotal_basic.phpt @@ -17,9 +17,6 @@ $gif = __DIR__."/php.gif"; $im = imagecreatefromgif($gif); echo 'Total colors in image: ' . imagecolorstotal($im); - -// Free image -imagedestroy($im); ?> --EXPECT-- *** Testing imagecolorstotal() : basic functionality *** diff --git a/ext/gd/tests/imagecolourstotal_basic.phpt b/ext/gd/tests/imagecolourstotal_basic.phpt index 0c9fd763247b..f66a68424850 100644 --- a/ext/gd/tests/imagecolourstotal_basic.phpt +++ b/ext/gd/tests/imagecolourstotal_basic.phpt @@ -22,15 +22,13 @@ var_dump( imagecolorstotal( $img )); $bg = imagecolorallocate( $img, 255, 0, 0 ); $bg = imagecolorallocate( $img, 0, 0, 255 ); var_dump( imagecolorstotal( $img )); -imagedestroy( $img ); +$img = null; // Truecolor image $img = imagecreatetruecolor( 50, 50 ); var_dump( imagecolorstotal( $img ) ); $bg = imagecolorallocate( $img, 255, 255, 255 ); var_dump( imagecolorstotal( $img ) ); -imagedestroy( $img ); - ?> --EXPECT-- *** Testing imagecolorstotal() : basic functionality *** diff --git a/ext/gd/tests/imagecopyresampled_basic.phpt b/ext/gd/tests/imagecopyresampled_basic.phpt index 9fb1178e540a..3f2f73527239 100644 --- a/ext/gd/tests/imagecopyresampled_basic.phpt +++ b/ext/gd/tests/imagecopyresampled_basic.phpt @@ -47,11 +47,6 @@ imagepng($image_sml, $dest_sml); list($width, $height) = getimagesize($dest_sml); echo "Size of copy: width=". $width . " height=" . $height . "\n"; - -imagedestroy($image_lge); -imagedestroy($image_sml); - - echo "Done\n"; ?> --CLEAN-- diff --git a/ext/gd/tests/imagecopyresampled_variation1.phpt b/ext/gd/tests/imagecopyresampled_variation1.phpt index 207344765565..6c3fd021a1ac 100644 --- a/ext/gd/tests/imagecopyresampled_variation1.phpt +++ b/ext/gd/tests/imagecopyresampled_variation1.phpt @@ -59,9 +59,6 @@ if (!($alpha >= EXP_ALPHA - 1 && $alpha <= EXP_ALPHA + 1)) { printf("alpha: expected roughly %d, got %d\n", EXP_ALPHA, $alpha); } -imagedestroy($copy); -imagedestroy($im); - echo 'DONE'; ?> --EXPECT-- diff --git a/ext/gd/tests/imagecreatefrombmp_basic.phpt b/ext/gd/tests/imagecreatefrombmp_basic.phpt index 4989e617b471..da6fe1b97dae 100644 --- a/ext/gd/tests/imagecreatefrombmp_basic.phpt +++ b/ext/gd/tests/imagecreatefrombmp_basic.phpt @@ -4,7 +4,6 @@ imagecreatefrombmp() - basic functionality gd --SKIPIF-- --CLEAN-- diff --git a/ext/gd/tests/imagedestroy_deprecated.phpt b/ext/gd/tests/imagedestroy_deprecated.phpt new file mode 100644 index 000000000000..37c39fbfe271 --- /dev/null +++ b/ext/gd/tests/imagedestroy_deprecated.phpt @@ -0,0 +1,11 @@ +--TEST-- +imagedestroy() deprecation message +--EXTENSIONS-- +gd +--FILE-- + +--EXPECTF-- +Deprecated: Function imagedestroy() is deprecated since 8.5, as it has no effect since PHP 8.0 in %s on line %d diff --git a/ext/gd/tests/imagefill_1.phpt b/ext/gd/tests/imagefill_1.phpt index d8631f73cc42..113c1c984387 100644 --- a/ext/gd/tests/imagefill_1.phpt +++ b/ext/gd/tests/imagefill_1.phpt @@ -18,7 +18,6 @@ $green = imagecolorallocate($im, 0,255,0); print_r(imagecolorat($im, 0,0)); imagefill($im, 0,0,$white + 3); print_r(imagecolorat($im, 0,0)); -imagedestroy($im); ?> --EXPECT-- 00 diff --git a/ext/gd/tests/imagefilledpolygon_basic.phpt b/ext/gd/tests/imagefilledpolygon_basic.phpt index bbb8f9c2eb04..3681d96c6e73 100644 --- a/ext/gd/tests/imagefilledpolygon_basic.phpt +++ b/ext/gd/tests/imagefilledpolygon_basic.phpt @@ -55,9 +55,6 @@ $color2 = imagecolorsforindex($image_in, $col2); $color3 = imagecolorsforindex($image_in, $col3); var_dump($color1, $color2, $color3); -imagedestroy($image); -imagedestroy($image_in); - echo "Done\n"; ?> --CLEAN-- diff --git a/ext/gd/tests/imagefilter_error1.phpt b/ext/gd/tests/imagefilter_error1.phpt index 6e2ccabb874a..cc9904e320da 100644 --- a/ext/gd/tests/imagefilter_error1.phpt +++ b/ext/gd/tests/imagefilter_error1.phpt @@ -14,6 +14,12 @@ try { } catch (TypeError $e) { echo $e->getMessage(), "\n"; } +try { + var_dump(imagefilter(20, 1)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECT-- -Wrong parameter count for imagefilter() +imagefilter() expects at least 2 arguments, 1 given +imagefilter(): Argument #1 ($image) must be of type GdImage, int given diff --git a/ext/gd/tests/imagefilter_invalid_filter_error.phpt b/ext/gd/tests/imagefilter_invalid_filter_error.phpt new file mode 100644 index 000000000000..f543e4a69f5d --- /dev/null +++ b/ext/gd/tests/imagefilter_invalid_filter_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-20070: Testing wrong parameter passing in imagefilter() of GD library +--EXTENSIONS-- +gd +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +ValueError: imagefilter(): Argument #2 ($filter) must be one of the IMG_FILTER_* filter constants diff --git a/ext/gd/tests/imagefttext.phpt b/ext/gd/tests/imagefttext.phpt index a60c4d8afbae..83243a78e520 100644 --- a/ext/gd/tests/imagefttext.phpt +++ b/ext/gd/tests/imagefttext.phpt @@ -40,11 +40,10 @@ gd $im = imagecreate(256, 256); var_dump(testrun($im, $fontfile_8859)); - imagedestroy($im); + $im = null; $im = imagecreatetruecolor(256, 256); var_dump(testrun($im, $fontfile_8859)); - imagedestroy($im); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/imagepalettetotruecolor_basic.phpt b/ext/gd/tests/imagepalettetotruecolor_basic.phpt index e4e4ee89ca1d..d886227a15ef 100644 --- a/ext/gd/tests/imagepalettetotruecolor_basic.phpt +++ b/ext/gd/tests/imagepalettetotruecolor_basic.phpt @@ -11,7 +11,6 @@ var_dump($im instanceof GdImage); var_dump(imageistruecolor($im)); var_dump(imagepalettetotruecolor($im)); var_dump(imageistruecolor($im)); -imagedestroy($im); ?> --EXPECT-- bool(true) diff --git a/ext/gd/tests/imagepolygon_basic.phpt b/ext/gd/tests/imagepolygon_basic.phpt index c41b0710ef43..741f34c48ab8 100644 --- a/ext/gd/tests/imagepolygon_basic.phpt +++ b/ext/gd/tests/imagepolygon_basic.phpt @@ -42,8 +42,6 @@ $color1 = imagecolorsforindex($image, $col1); $color2 = imagecolorsforindex($image, $col2); var_dump($color1, $color2); -imagedestroy($image); - echo "Done\n"; ?> --CLEAN-- diff --git a/ext/gd/tests/imagerotate_overflow.phpt b/ext/gd/tests/imagerotate_overflow.phpt index a7be335ca92a..590f4d7152c9 100644 --- a/ext/gd/tests/imagerotate_overflow.phpt +++ b/ext/gd/tests/imagerotate_overflow.phpt @@ -11,14 +11,6 @@ $tmp = imagerotate ($im, 5, -9999999); var_dump($tmp); -if ($tmp) { - imagedestroy($tmp); -} - -if ($im) { - imagedestroy($im); -} - ?> --EXPECT-- bool(false) diff --git a/ext/gd/tests/imagettftext_charmap_order.phpt b/ext/gd/tests/imagettftext_charmap_order.phpt index 32d5c9d0d7e4..6fe5353e9fc2 100644 --- a/ext/gd/tests/imagettftext_charmap_order.phpt +++ b/ext/gd/tests/imagettftext_charmap_order.phpt @@ -61,7 +61,6 @@ if ($black_pixels >= 10) { } else { printf("FAIL %d black pixels\n", $black_pixels); } -imagedestroy($im); ?> --EXPECTF-- SUCCESS %d black pixels diff --git a/ext/gd/tests/libgd00100.phpt b/ext/gd/tests/libgd00100.phpt index 80e24d0ba203..8f9955640b3c 100644 --- a/ext/gd/tests/libgd00100.phpt +++ b/ext/gd/tests/libgd00100.phpt @@ -109,8 +109,6 @@ imagefilledpolygon($im, $points, $black); include_once __DIR__ . '/func.inc'; test_image_equals_file(__DIR__ . '/libgd00100.png', $im); - -imagedestroy($im); ?> --EXPECT-- The images are equal. diff --git a/ext/gd/tests/libgd00186.phpt b/ext/gd/tests/libgd00186.phpt index fb9e2985ced4..142f1637b2b3 100644 --- a/ext/gd/tests/libgd00186.phpt +++ b/ext/gd/tests/libgd00186.phpt @@ -26,8 +26,6 @@ if ($arr['blue'] == 2) { } else { $r = "Failed"; } -imagedestroy($tile); -imagedestroy($im); echo $r; ?> --EXPECT-- diff --git a/ext/gettext/config.w32 b/ext/gettext/config.w32 index 3e644655426b..e4a4168d949b 100644 --- a/ext/gettext/config.w32 +++ b/ext/gettext/config.w32 @@ -3,7 +3,7 @@ ARG_WITH("gettext", "gettext support", "no"); if (PHP_GETTEXT != "no") { - if (CHECK_LIB("libintl_a.lib;libintl.lib", "gettext", PHP_GETTEXT) && CHECK_HEADER_ADD_INCLUDE("libintl.h", "CFLAGS_GETTEXT")) { + if (CHECK_LIB("libintl_a.lib;libintl.lib", "gettext", PHP_GETTEXT) && CHECK_HEADER("libintl.h", "CFLAGS_GETTEXT")) { EXTENSION("gettext", "gettext.c", PHP_GETTEXT_SHARED, "-DHAVE_BIND_TEXTDOMAIN_CODESET=1 -DHAVE_DNGETTEXT=1 -DHAVE_NGETTEXT=1 -DHAVE_LIBINTL=1 -DHAVE_DCNGETTEXT=1"); } else { WARNING("gettext not enabled; libraries and headers not found"); diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 27f0dfa26da7..172ae76d3876 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alex Plotnick | +----------------------------------------------------------------------+ @@ -194,7 +192,7 @@ PHP_FUNCTION(bindtextdomain) btd_result = bindtextdomain(ZSTR_VAL(domain), NULL); if (btd_result == NULL) { /* POSIX-compliant implementations can return - * NULL if an error occured. On musl you will + * NULL if an error occurred. On musl you will * also get NULL if the domain is not yet * bound, because musl has no default directory * to return in that case. */ diff --git a/ext/gettext/gettext_arginfo.h b/ext/gettext/gettext_arginfo.h index 265f6cd900ed..8b622a322add 100644 --- a/ext/gettext/gettext_arginfo.h +++ b/ext/gettext/gettext_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit gettext.stub.php instead. * Stub hash: c675dc9492943bbac106c5906b75c31436964423 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_textdomain, 0, 0, IS_STRING, 0) diff --git a/ext/gettext/php_gettext.h b/ext/gettext/php_gettext.h index f98e459f127c..5799ecf1d89b 100644 --- a/ext/gettext/php_gettext.h +++ b/ext/gettext/php_gettext.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alex Plotnick | +----------------------------------------------------------------------+ diff --git a/ext/gmp/config.w32 b/ext/gmp/config.w32 index 2bb4aa63ad0f..dc0c1e978d31 100644 --- a/ext/gmp/config.w32 +++ b/ext/gmp/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("gmp", "Include GNU MP support.", "no"); if (PHP_GMP != "no") { if (CHECK_LIB("mpir_a.lib", "gmp", PHP_GMP) && - CHECK_HEADER_ADD_INCLUDE("gmp.h", "CFLAGS_GMP", PHP_GMP + ";" + PHP_PHP_BUILD + "\\include\\mpir")) { + CHECK_HEADER("gmp.h", "CFLAGS_GMP", PHP_GMP + ";" + PHP_PHP_BUILD + "\\include\\mpir")) { EXTENSION("gmp", "gmp.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); PHP_INSTALL_HEADERS("ext/gmp", "php_gmp_int.h"); AC_DEFINE('HAVE_GMP', 1, "Define to 1 if the PHP extension 'gmp' is available."); diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 8cf20c90fc7a..ef06d0fda30c 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -285,7 +283,7 @@ static HashTable *gmp_get_debug_info(zend_object *obj, int *is_temp) /* {{{ */ static zend_object *gmp_clone_obj(zend_object *obj) /* {{{ */ { - gmp_object *old_object = GET_GMP_OBJECT_FROM_OBJ(obj); + const gmp_object *old_object = GET_GMP_OBJECT_FROM_OBJ(obj); gmp_object *new_object = GET_GMP_OBJECT_FROM_OBJ(gmp_create_object(obj->ce)); zend_objects_clone_members( &new_object->std, &old_object->std); @@ -334,11 +332,11 @@ static zend_result shift_operator_helper(gmp_binary_ui_op_t op, zval *return_val if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) { if (UNEXPECTED(!IS_GMP(op2))) { - // For PHP 8.3 and up use zend_try_get_long() + bool failed; switch (Z_TYPE_P(op2)) { case IS_DOUBLE: - shift = zval_get_long(op2); - if (UNEXPECTED(EG(exception))) { + shift = zval_try_get_long(op2, &failed); + if (UNEXPECTED(failed)) { return FAILURE; } break; @@ -358,10 +356,10 @@ static zend_result shift_operator_helper(gmp_binary_ui_op_t op, zval *return_val shift = Z_LVAL_P(op2); } - if (shift < 0) { + if (shift < 0 || shift > ULONG_MAX) { zend_throw_error( - zend_ce_value_error, "%s must be greater than or equal to 0", - opcode == ZEND_POW ? "Exponent" : "Shift" + zend_ce_value_error, "%s must be between 0 and %lu", + opcode == ZEND_POW ? "Exponent" : "Shift", ULONG_MAX ); ZVAL_UNDEF(return_value); return FAILURE; @@ -393,7 +391,7 @@ typeof_op_failure: ; case ZEND_SR: op_sigil = ">>"; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } zend_type_error("Unsupported operand types: %s %s %s", zend_zval_type_name(op1), op_sigil, zend_zval_type_name(op2)); return FAILURE; @@ -588,7 +586,7 @@ ZEND_MINIT_FUNCTION(gmp) gmp_ce->unserialize = gmp_unserialize; memcpy(&gmp_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - gmp_object_handlers.offset = XtOffsetOf(gmp_object, std); + gmp_object_handlers.offset = offsetof(gmp_object, std); gmp_object_handlers.free_obj = gmp_free_object_storage; gmp_object_handlers.cast_object = gmp_cast_object; gmp_object_handlers.get_debug_info = gmp_get_debug_info; @@ -634,7 +632,7 @@ static zend_result convert_zstr_to_gmp(mpz_t gmp_number, const zend_string *val, bool skip_lead = false; size_t num_len = ZSTR_LEN(val); - while (isspace(*num_str)) { + while (isspace((unsigned char)*num_str)) { ++num_str; --num_len; } @@ -929,7 +927,7 @@ ZEND_FUNCTION(gmp_div_qr) case GMP_ROUND_MINUSINF: mpz_fdiv_qr(gmpnum_result1, gmpnum_result2, gmpnum_a, gmpnum_b); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -1089,14 +1087,11 @@ ZEND_FUNCTION(gmp_fact) GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum) ZEND_PARSE_PARAMETERS_END(); - if (mpz_sgn(gmpnum) < 0) { - zend_argument_value_error(1, "must be greater than or equal to 0"); + if (!mpz_fits_ulong_p(gmpnum)) { + zend_argument_value_error(1, "must be between 0 and %lu", ULONG_MAX); RETURN_THROWS(); } - // TODO: Check that we don't an int that is larger than an unsigned long? - // Could use mpz_fits_slong_p() if we revert to using mpz_get_si() - INIT_GMP_RETVAL(gmpnum_result); mpz_fac_ui(gmpnum_result, mpz_get_ui(gmpnum)); } @@ -1114,8 +1109,8 @@ ZEND_FUNCTION(gmp_binomial) Z_PARAM_LONG(k) ZEND_PARSE_PARAMETERS_END(); - if (k < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (k < 0 || k > ULONG_MAX) { + zend_argument_value_error(2, "must be between 0 and %lu", ULONG_MAX); RETURN_THROWS(); } @@ -1136,8 +1131,8 @@ ZEND_FUNCTION(gmp_pow) Z_PARAM_LONG(exp) ZEND_PARSE_PARAMETERS_END(); - if (exp < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (exp < 0 || exp > ULONG_MAX) { + zend_argument_value_error(2, "must be between 0 and %lu", ULONG_MAX); RETURN_THROWS(); } @@ -1163,7 +1158,7 @@ ZEND_FUNCTION(gmp_powm) } if (!mpz_cmp_ui(gmpnum_mod, 0)) { - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); + zend_argument_error(zend_ce_division_by_zero_error, 3, "Modulo by zero"); RETURN_THROWS(); } @@ -1226,8 +1221,8 @@ ZEND_FUNCTION(gmp_root) Z_PARAM_LONG(nth) ZEND_PARSE_PARAMETERS_END(); - if (nth <= 0) { - zend_argument_value_error(2, "must be greater than 0"); + if (nth <= 0 || nth > ULONG_MAX) { + zend_argument_value_error(2, "must be between 1 and %lu", ULONG_MAX); RETURN_THROWS(); } @@ -1253,8 +1248,8 @@ ZEND_FUNCTION(gmp_rootrem) Z_PARAM_LONG(nth) ZEND_PARSE_PARAMETERS_END(); - if (nth <= 0) { - zend_argument_value_error(2, "must be greater than or equal to 1"); + if (nth <= 0 || nth > ULONG_MAX) { + zend_argument_value_error(2, "must be between 1 and %lu", ULONG_MAX); RETURN_THROWS(); } @@ -1535,7 +1530,7 @@ ZEND_FUNCTION(gmp_setbit) { zval *a_arg; zend_long index; - bool set = 1; + bool set = true; mpz_ptr gmpnum_a; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol|b", &a_arg, gmp_ce, &index, &set) == FAILURE) { diff --git a/ext/gmp/gmp_arginfo.h b/ext/gmp/gmp_arginfo.h index 31927d3e482b..436e3a22ea72 100644 --- a/ext/gmp/gmp_arginfo.h +++ b/ext/gmp/gmp_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit gmp.stub.php instead. * Stub hash: 3aabd5a5d2db0df15b249a425465ae718c13ab6b */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_init, 0, 1, GMP, 0) diff --git a/ext/gmp/php_gmp.h b/ext/gmp/php_gmp.h index 597c7a9146c2..220a36d64285 100644 --- a/ext/gmp/php_gmp.h +++ b/ext/gmp/php_gmp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/gmp/php_gmp_int.h b/ext/gmp/php_gmp_int.h index 32f1d32f592a..01cf26eb3ed5 100644 --- a/ext/gmp/php_gmp_int.h +++ b/ext/gmp/php_gmp_int.h @@ -1,3 +1,15 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + */ + /* interface header; needs to be installed; FIXME rename? */ #ifndef incl_PHP_GMP_INT_H @@ -24,7 +36,7 @@ typedef struct _gmp_object { } gmp_object; static inline gmp_object *php_gmp_object_from_zend_object(zend_object *zobj) { - return (gmp_object *)( ((char *)zobj) - XtOffsetOf(gmp_object, std) ); + return ZEND_CONTAINER_OF(zobj, gmp_object, std); } PHP_GMP_API zend_class_entry *php_gmp_class_entry(void); diff --git a/ext/gmp/tests/gmp_binomial.phpt b/ext/gmp/tests/gmp_binomial.phpt index 4598a4c47ee8..1bf371e68a14 100644 --- a/ext/gmp/tests/gmp_binomial.phpt +++ b/ext/gmp/tests/gmp_binomial.phpt @@ -26,7 +26,7 @@ try { echo $e->getMessage() . \PHP_EOL; } ?> ---EXPECT-- +--EXPECTF-- object(GMP)#1 (1) { ["num"]=> string(3) "252" @@ -67,4 +67,4 @@ object(GMP)#2 (1) { ["num"]=> string(1) "7" } -gmp_binomial(): Argument #2 ($k) must be greater than or equal to 0 +gmp_binomial(): Argument #2 ($k) must be between 0 and %d diff --git a/ext/gmp/tests/gmp_fact.phpt b/ext/gmp/tests/gmp_fact.phpt index e03931454940..b28f572c6975 100644 --- a/ext/gmp/tests/gmp_fact.phpt +++ b/ext/gmp/tests/gmp_fact.phpt @@ -45,17 +45,17 @@ try { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- string(1) "1" gmp_fact(): Argument #1 ($num) is not an integer string string(1) "1" -gmp_fact(): Argument #1 ($num) must be greater than or equal to 0 -gmp_fact(): Argument #1 ($num) must be greater than or equal to 0 +gmp_fact(): Argument #1 ($num) must be between 0 and %d +gmp_fact(): Argument #1 ($num) must be between 0 and %d string(19) "2432902008176640000" string(65) "30414093201713378043612608166064768844377641568960512000000000000" string(7) "3628800" string(1) "1" string(9) "479001600" -gmp_fact(): Argument #1 ($num) must be greater than or equal to 0 +gmp_fact(): Argument #1 ($num) must be between 0 and %d gmp_fact(): Argument #1 ($num) must be of type GMP|string|int, array given Done diff --git a/ext/gmp/tests/gmp_fact_overflow.phpt b/ext/gmp/tests/gmp_fact_overflow.phpt new file mode 100644 index 000000000000..2d22005818c5 --- /dev/null +++ b/ext/gmp/tests/gmp_fact_overflow.phpt @@ -0,0 +1,25 @@ +--TEST-- +gmp_fact() rejects values larger than unsigned long +--EXTENSIONS-- +gmp +--FILE-- +getMessage() . \PHP_EOL; +} + +try { + var_dump(gmp_fact(gmp_init("18446744073709551616"))); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECTF-- +gmp_fact(): Argument #1 ($num) must be between 0 and %d +gmp_fact(): Argument #1 ($num) must be between 0 and %d +Done diff --git a/ext/gmp/tests/gmp_overflow_llp64.phpt b/ext/gmp/tests/gmp_overflow_llp64.phpt new file mode 100644 index 000000000000..ea242bc52155 --- /dev/null +++ b/ext/gmp/tests/gmp_overflow_llp64.phpt @@ -0,0 +1,58 @@ +--TEST-- +GMP functions reject values larger than unsigned long on LLP64 +--EXTENSIONS-- +gmp +--SKIPIF-- + +--FILE-- +getMessage() . PHP_EOL; +} + +try { + gmp_binomial(10, PHP_INT_MAX); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + gmp_root(10, PHP_INT_MAX); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + gmp_rootrem(10, PHP_INT_MAX); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +$n = gmp_init(2); +try { + $n << PHP_INT_MAX; +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + $n ** PHP_INT_MAX; +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECTF-- +gmp_pow(): Argument #2 ($exponent) must be between 0 and %d +gmp_binomial(): Argument #2 ($k) must be between 0 and %d +gmp_root(): Argument #2 ($nth) must be between 1 and %d +gmp_rootrem(): Argument #2 ($nth) must be between 1 and %d +Shift must be between 0 and %d +Exponent must be between 0 and %d +Done diff --git a/ext/gmp/tests/gmp_pow.phpt b/ext/gmp/tests/gmp_pow.phpt index f42e44e31abe..36d0d16d8ccc 100644 --- a/ext/gmp/tests/gmp_pow.phpt +++ b/ext/gmp/tests/gmp_pow.phpt @@ -43,17 +43,17 @@ try { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- string(4) "1024" string(4) "1024" string(5) "-2048" string(4) "1024" string(1) "1" -gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 +gmp_pow(): Argument #2 ($exponent) must be between 0 and %d string(4) "1024" string(14) "10240000000000" string(17) "97656250000000000" -gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 +gmp_pow(): Argument #2 ($exponent) must be between 0 and %d string(14) "10240000000000" string(14) "10240000000000" gmp_pow(): Argument #2 ($exponent) must be of type int, array given diff --git a/ext/gmp/tests/gmp_pow2.phpt b/ext/gmp/tests/gmp_pow2.phpt index 43bf9bb5aaa5..96f33e8c25ca 100644 --- a/ext/gmp/tests/gmp_pow2.phpt +++ b/ext/gmp/tests/gmp_pow2.phpt @@ -31,5 +31,5 @@ object(GMP)#%d (1) { ["num"]=> string(4) "1024" } -Exponent must be greater than or equal to 0 -Exponent must be greater than or equal to 0 +Exponent must be between 0 and %d +Exponent must be between 0 and %d diff --git a/ext/gmp/tests/gmp_pown.phpt b/ext/gmp/tests/gmp_pown.phpt index 0e7b3bd1fa5d..79709f272715 100644 --- a/ext/gmp/tests/gmp_pown.phpt +++ b/ext/gmp/tests/gmp_pown.phpt @@ -63,7 +63,7 @@ var_dump(gmp_powm(10, $n, 10)); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- string(1) "0" string(1) "5" string(1) "5" @@ -73,8 +73,8 @@ string(3) "533" string(3) "331" string(3) "171" string(3) "371" -Modulo by zero -Modulo by zero +gmp_powm(): Argument #3 ($modulus) Modulo by zero +gmp_powm(): Argument #3 ($modulus) Modulo by zero gmp_powm(): Argument #1 ($num) must be of type GMP|string|int, array given gmp_powm(): Argument #2 ($exponent) must be of type GMP|string|int, array given gmp_powm(): Argument #2 ($exponent) must be of type GMP|string|int, TypeError given diff --git a/ext/gmp/tests/gmp_remroot.phpt b/ext/gmp/tests/gmp_remroot.phpt index 8e53858c6047..de54d0e91c3e 100644 --- a/ext/gmp/tests/gmp_remroot.phpt +++ b/ext/gmp/tests/gmp_remroot.phpt @@ -105,5 +105,5 @@ array(2) { string(1) "0" } } -gmp_rootrem(): Argument #2 ($nth) must be greater than or equal to 1 -gmp_rootrem(): Argument #2 ($nth) must be greater than or equal to 1 +gmp_rootrem(): Argument #2 ($nth) must be between 1 and %d +gmp_rootrem(): Argument #2 ($nth) must be between 1 and %d diff --git a/ext/gmp/tests/gmp_root.phpt b/ext/gmp/tests/gmp_root.phpt index 2313b207cc8d..36793e249721 100644 --- a/ext/gmp/tests/gmp_root.phpt +++ b/ext/gmp/tests/gmp_root.phpt @@ -58,5 +58,5 @@ object(GMP)#%d (1) { ["num"]=> string(1) "0" } -gmp_root(): Argument #2 ($nth) must be greater than 0 -gmp_root(): Argument #2 ($nth) must be greater than 0 +gmp_root(): Argument #2 ($nth) must be between 1 and %d +gmp_root(): Argument #2 ($nth) must be between 1 and %d diff --git a/ext/gmp/tests/overloading.phpt b/ext/gmp/tests/overloading.phpt index 14c35ea8470c..f55a83f0bd5f 100644 --- a/ext/gmp/tests/overloading.phpt +++ b/ext/gmp/tests/overloading.phpt @@ -123,7 +123,7 @@ $a .= '17'; var_dump($a); ?> ---EXPECT-- +--EXPECTF-- object(GMP)#3 (1) { ["num"]=> string(2) "59" @@ -254,8 +254,8 @@ object(GMP)#5 (1) { ["num"]=> string(3) "-11" } -Shift must be greater than or equal to 0 -Shift must be greater than or equal to 0 +Shift must be between 0 and %d +Shift must be between 0 and %d object(GMP)#5 (1) { ["num"]=> string(3) "-43" diff --git a/ext/gmp/tests/overloading_with_float_fractional.phpt b/ext/gmp/tests/overloading_with_float_fractional.phpt index fc078eeec3e9..a86356a9dd54 100644 --- a/ext/gmp/tests/overloading_with_float_fractional.phpt +++ b/ext/gmp/tests/overloading_with_float_fractional.phpt @@ -100,6 +100,8 @@ object(GMP)#2 (1) { ["num"]=> string(1) "0" } + +Deprecated: Implicit conversion from float 42.5 to int loses precision in %s on line %d object(GMP)#2 (1) { ["num"]=> string(69) "150130937545296572356771972164254457814047970568738777235893533016064" @@ -122,10 +124,14 @@ object(GMP)#2 (1) { ["num"]=> string(1) "0" } + +Deprecated: Implicit conversion from float 42.5 to int loses precision in %s on line %d object(GMP)#2 (1) { ["num"]=> string(15) "184717953466368" } + +Deprecated: Implicit conversion from float 42.5 to int loses precision in %s on line %d object(GMP)#2 (1) { ["num"]=> string(1) "0" diff --git a/ext/hash/config.m4 b/ext/hash/config.m4 index 5248786efb08..2da44c503a62 100644 --- a/ext/hash/config.m4 +++ b/ext/hash/config.m4 @@ -23,8 +23,7 @@ AS_VAR_IF([ac_cv_c_bigendian_php], [yes], [ SHA3_OPT_SRC="$SHA3_DIR/KeccakP-1600-inplace32BI.c" dnl Add -Wno-implicit-fallthrough flag as it happens on 32 bit builds AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough], - [PHP_HASH_CFLAGS="$PHP_HASH_CFLAGS -Wno-implicit-fallthrough"],, - [-Werror]) + [PHP_HASH_CFLAGS="$PHP_HASH_CFLAGS -Wno-implicit-fallthrough"]) ],[ AC_MSG_RESULT([yes]) SHA3_DIR="sha3/generic64lc" diff --git a/ext/hash/config.w32 b/ext/hash/config.w32 index dd4c050bcd25..e63efcfd84cb 100644 --- a/ext/hash/config.w32 +++ b/ext/hash/config.w32 @@ -22,7 +22,7 @@ if(X64) { ADD_SOURCES(hash_sha3_dir, 'KeccakHash.c KeccakSponge.c KeccakP-1600-inplace32BI.c', 'hash'); } -if (!CHECK_HEADER_ADD_INCLUDE('KeccakHash.h', 'CFLAGS_HASH', hash_sha3_dir)) { +if (!CHECK_HEADER('KeccakHash.h', 'CFLAGS_HASH', hash_sha3_dir)) { // Should NEVER happen ERROR('Unable to locate SHA3 headers'); } diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 13c345de4dd1..96adc561c228 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | | Scott MacVicar | @@ -229,20 +227,20 @@ static void one_to_buffer(size_t sz, unsigned char *buf, uint64_t val) { significant bits first. This allows 32-bit and 64-bit architectures to interchange serialized HashContexts. */ -PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ +PHP_HASH_API hash_spec_result php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */ { size_t pos = 0, max_alignment = 1; unsigned char *buf = (unsigned char *) hash->context; zval tmp; if (buf == NULL) { - return FAILURE; + return HASH_SPEC_FAILURE; } array_init(zv); while (*spec != '\0' && *spec != '.') { char spec_ch = *spec; size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment); if (pos + count * sz > hash->ops->context_size) { - return FAILURE; + return HASH_SPEC_FAILURE; } if (isupper((unsigned char) spec_ch)) { pos += count * sz; @@ -265,38 +263,33 @@ PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *h } } if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) { - return FAILURE; + return HASH_SPEC_FAILURE; } - return SUCCESS; + return HASH_SPEC_SUCCESS; } /* }}} */ -/* Unserialize a hash context serialized by `php_hash_serialize_spec` with `spec`. - Returns SUCCESS on success and a negative error code on failure. - Codes: FAILURE (-1) == generic failure - -999 == spec wrong size for context - -1000 - POS == problem at byte offset POS */ - -PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec) /* {{{ */ +/* Unserialize a hash context serialized by `php_hash_serialize_spec` with `spec`. */ +PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec) /* {{{ */ { size_t pos = 0, max_alignment = 1, j = 0; unsigned char *buf = (unsigned char *) hash->context; zval *elt; if (Z_TYPE_P(zv) != IS_ARRAY) { - return FAILURE; + return HASH_SPEC_FAILURE; } while (*spec != '\0' && *spec != '.') { char spec_ch = *spec; size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment); if (pos + count * sz > hash->ops->context_size) { - return -999; + return WRONG_CONTEXT_SIZE; } if (isupper((unsigned char) spec_ch)) { pos += count * sz; } else if (sz == 1 && count > 1) { elt = zend_hash_index_find(Z_ARRVAL_P(zv), j); if (!elt || Z_TYPE_P(elt) != IS_STRING || Z_STRLEN_P(elt) != count) { - return -1000 - pos; + return BYTE_OFFSET_POS_ERROR - pos; } ++j; memcpy(buf + pos, Z_STRVAL_P(elt), count); @@ -306,14 +299,14 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z uint64_t val; elt = zend_hash_index_find(Z_ARRVAL_P(zv), j); if (!elt || Z_TYPE_P(elt) != IS_LONG) { - return -1000 - pos; + return BYTE_OFFSET_POS_ERROR - pos; } ++j; val = (uint32_t) Z_LVAL_P(elt); if (sz == 8) { elt = zend_hash_index_find(Z_ARRVAL_P(zv), j); if (!elt || Z_TYPE_P(elt) != IS_LONG) { - return -1000 - pos; + return BYTE_OFFSET_POS_ERROR - pos; } ++j; val += ((uint64_t) Z_LVAL_P(elt)) << 32; @@ -325,31 +318,32 @@ PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const z } } if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) { - return -999; + return WRONG_CONTEXT_SIZE; } - return SUCCESS; + + return HASH_SPEC_SUCCESS; } /* }}} */ -PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ +PHP_HASH_API hash_spec_result php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */ { - if (hash->ops->serialize_spec) { - *magic = PHP_HASH_SERIALIZE_MAGIC_SPEC; - return php_hash_serialize_spec(hash, zv, hash->ops->serialize_spec); - } else { - return FAILURE; - } + if (!hash->ops->serialize_spec) { + return HASH_SPEC_FAILURE; + } + + *magic = PHP_HASH_SERIALIZE_MAGIC_SPEC; + return php_hash_serialize_spec(hash, zv, hash->ops->serialize_spec); } /* }}} */ -PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) /* {{{ */ +PHP_HASH_API hash_spec_result php_hash_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) /* {{{ */ { if (hash->ops->serialize_spec && magic == PHP_HASH_SERIALIZE_MAGIC_SPEC) { return php_hash_unserialize_spec(hash, zv, hash->ops->serialize_spec); - } else { - return FAILURE; } + + return HASH_SPEC_FAILURE; } /* }}} */ @@ -369,7 +363,7 @@ static void php_hash_do_hash( RETURN_THROWS(); } if (isfilename) { - if (CHECK_NULL_PATH(data, data_len)) { + if (zend_char_has_nul_byte(data, data_len)) { zend_argument_value_error(1, "must not contain any null bytes"); RETURN_THROWS(); } @@ -411,7 +405,7 @@ static void php_hash_do_hash( php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0; - zend_string_release_ex(digest, 0); + zend_string_efree(digest); RETURN_NEW_STR(hex_digest); } } @@ -512,7 +506,7 @@ static void php_hash_do_hash_hmac( } if (isfilename) { - if (CHECK_NULL_PATH(data, data_len)) { + if (zend_char_has_nul_byte(data, data_len)) { zend_argument_value_error(2, "must not contain any null bytes"); RETURN_THROWS(); } @@ -542,7 +536,7 @@ static void php_hash_do_hash_hmac( if (n < 0) { efree(context); efree(K); - zend_string_release(digest); + zend_string_efree(digest); RETURN_FALSE; } @@ -568,7 +562,7 @@ static void php_hash_do_hash_hmac( php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), ops->digest_size); ZSTR_VAL(hex_digest)[2 * ops->digest_size] = 0; - zend_string_release_ex(digest, 0); + zend_string_efree(digest); RETURN_NEW_STR(hex_digest); } } @@ -581,13 +575,13 @@ PHP_FUNCTION(hash_hmac) zend_string *algo; char *data, *key; size_t data_len, key_len; - bool raw_output = 0; + bool raw_output = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sss|b", &algo, &data, &data_len, &key, &key_len, &raw_output) == FAILURE) { RETURN_THROWS(); } - php_hash_do_hash_hmac(return_value, algo, data, data_len, key, key_len, raw_output, 0); + php_hash_do_hash_hmac(return_value, algo, data, data_len, key, key_len, raw_output, false); } /* }}} */ @@ -598,13 +592,13 @@ PHP_FUNCTION(hash_hmac_file) zend_string *algo; char *data, *key; size_t data_len, key_len; - bool raw_output = 0; + bool raw_output = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sss|b", &algo, &data, &data_len, &key, &key_len, &raw_output) == FAILURE) { RETURN_THROWS(); } - php_hash_do_hash_hmac(return_value, algo, data, data_len, key, key_len, raw_output, 1); + php_hash_do_hash_hmac(return_value, algo, data, data_len, key, key_len, raw_output, true); } /* }}} */ @@ -782,7 +776,7 @@ PHP_FUNCTION(hash_final) { zval *zhash; php_hashcontext_object *hash; - bool raw_output = 0; + bool raw_output = false; zend_string *digest; size_t digest_len; @@ -829,7 +823,7 @@ PHP_FUNCTION(hash_final) php_hash_bin2hex(ZSTR_VAL(hex_digest), (unsigned char *) ZSTR_VAL(digest), digest_len); ZSTR_VAL(hex_digest)[2 * digest_len] = 0; - zend_string_release_ex(digest, 0); + zend_string_efree(digest); RETURN_NEW_STR(hex_digest); } } @@ -851,8 +845,6 @@ PHP_FUNCTION(hash_copy) RETVAL_OBJ(Z_OBJ_HANDLER_P(zhash, clone_obj)(Z_OBJ_P(zhash))); if (php_hashcontext_from_object(Z_OBJ_P(return_value))->context == NULL) { - zval_ptr_dtor(return_value); - zend_throw_error(NULL, "Cannot copy hash"); RETURN_THROWS(); } @@ -864,9 +856,7 @@ PHP_FUNCTION(hash_algos) { zend_string *str; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); ZEND_HASH_MAP_FOREACH_STR_KEY(&php_hash_hashtable, str) { @@ -881,9 +871,7 @@ PHP_FUNCTION(hash_hmac_algos) zend_string *str; const php_hash_ops *ops; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&php_hash_hashtable, str, ops) { @@ -995,7 +983,7 @@ PHP_FUNCTION(hash_pbkdf2) unsigned char *computed_salt, *digest, *temp, *result, *K1, *K2 = NULL; zend_long loops, i, j, iterations, digest_length = 0, length = 0; size_t pass_len, salt_len = 0; - bool raw_output = 0; + bool raw_output = false; const php_hash_ops *ops; void *context; HashTable *args = NULL; @@ -1184,6 +1172,7 @@ static void mhash_init(INIT_FUNC_ARGS) int len; int algo_number = 0; + zend_string *deprecation_reason = zend_string_init("as the mhash*() functions were deprecated", strlen("as the mhash*() functions were deprecated"), 1); for (algo_number = 0; algo_number < MHASH_NUM_ALGOS; algo_number++) { struct mhash_bc_entry algorithm = mhash_to_hash[algo_number]; if (algorithm.mhash_name == NULL) { @@ -1191,8 +1180,18 @@ static void mhash_init(INIT_FUNC_ARGS) } len = slprintf(buf, 127, "MHASH_%s", algorithm.mhash_name); - zend_register_long_constant(buf, len, algorithm.value, CONST_PERSISTENT|CONST_DEPRECATED, module_number); + zend_constant *mhash_const = zend_register_long_constant(buf, len, algorithm.value, CONST_PERSISTENT|CONST_DEPRECATED, module_number); + + zend_attribute *deprecation_attrib = zend_add_global_constant_attribute(mhash_const, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&deprecation_attrib->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + deprecation_attrib->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&deprecation_attrib->args[1].value, deprecation_reason); + deprecation_attrib->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } + /* Each of the attributes uses ZVAL_STR_COPY instead of trying to special + * case one of them to use ZVAL_STR, but that means there is one more + * reference that needs to be decremented. */ + zend_string_release(deprecation_reason); /* TODO: this cause #69823 zend_register_internal_module(&mhash_module_entry); */ } @@ -1222,9 +1221,9 @@ PHP_FUNCTION(mhash) } if (key) { - php_hash_do_hash_hmac(return_value, algo, data, data_len, key, key_len, 1, 0); + php_hash_do_hash_hmac(return_value, algo, data, data_len, key, key_len, true, false); } else { - php_hash_do_hash(return_value, algo, data, data_len, 1, 0, NULL); + php_hash_do_hash(return_value, algo, data, data_len, true, false, NULL); } if (algo) { @@ -1255,9 +1254,7 @@ PHP_FUNCTION(mhash_get_hash_name) /* {{{ Gets the number of available hashes */ PHP_FUNCTION(mhash_count) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(MHASH_NUM_ALGOS - 1); } /* }}} */ @@ -1400,7 +1397,7 @@ static void php_hashcontext_free(zend_object *obj) { /* {{{ php_hashcontext_clone */ static zend_object *php_hashcontext_clone(zend_object *zobj) { - php_hashcontext_object *oldobj = php_hashcontext_from_object(zobj); + const php_hashcontext_object *oldobj = php_hashcontext_from_object(zobj); zend_object *znew = php_hashcontext_create(zobj->ce); php_hashcontext_object *newobj = php_hashcontext_from_object(znew); @@ -1458,9 +1455,7 @@ PHP_METHOD(HashContext, __serialize) zend_long magic = 0; zval tmp; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -1477,7 +1472,7 @@ PHP_METHOD(HashContext, __serialize) ZVAL_LONG(&tmp, hash->options); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); - if (hash->ops->hash_serialize(hash, &magic, &tmp) != SUCCESS) { + if (hash->ops->hash_serialize(hash, &magic, &tmp) != HASH_SPEC_SUCCESS) { goto serialize_failure; } zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); @@ -1506,7 +1501,7 @@ PHP_METHOD(HashContext, __unserialize) HashTable *data; zval *algo_zv, *magic_zv, *options_zv, *hash_zv, *members_zv; zend_long magic, options; - int unserialize_result; + hash_spec_result unserialize_result; const php_hash_ops *ops; if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &data) == FAILURE) { @@ -1555,7 +1550,7 @@ PHP_METHOD(HashContext, __unserialize) ops->hash_init(hash->context, NULL); unserialize_result = ops->hash_unserialize(hash, magic, hash_zv); - if (unserialize_result != SUCCESS) { + if (unserialize_result != HASH_SPEC_SUCCESS) { zend_throw_exception_ex(NULL, 0, "Incomplete or ill-formed serialization data (\"%s\" code %d)", ops->algo, unserialize_result); /* free context */ php_hashcontext_dtor(Z_OBJ_P(object)); @@ -1657,7 +1652,7 @@ PHP_MINIT_FUNCTION(hash) memcpy(&php_hashcontext_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_hashcontext_handlers.offset = XtOffsetOf(php_hashcontext_object, std); + php_hashcontext_handlers.offset = offsetof(php_hashcontext_object, std); php_hashcontext_handlers.free_obj = php_hashcontext_free; php_hashcontext_handlers.clone_obj = php_hashcontext_clone; diff --git a/ext/hash/hash_adler32.c b/ext/hash/hash_adler32.c index 3898ea60e877..2a40b3318cd5 100644 --- a/ext/hash/hash_adler32.c +++ b/ext/hash/hash_adler32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | diff --git a/ext/hash/hash_arginfo.h b/ext/hash/hash_arginfo.h index 24a17fd9750b..798bf66dc33c 100644 --- a/ext/hash/hash_arginfo.h +++ b/ext/hash/hash_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit hash.stub.php instead. * Stub hash: b0fe91da9b0469b44a9647b774b9b00498592e30 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hash, 0, 2, IS_STRING, 0) @@ -209,38 +209,23 @@ static void register_hash_symbols(int module_number) #if defined(PHP_MHASH_BC) zend_attribute *attribute_Deprecated_func_mhash_get_block_size_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mhash_get_block_size", sizeof("mhash_get_block_size") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_mhash_get_block_size_0_arg0; - zend_string *attribute_Deprecated_func_mhash_get_block_size_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_mhash_get_block_size_0_arg0, attribute_Deprecated_func_mhash_get_block_size_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mhash_get_block_size_0->args[0].value, &attribute_Deprecated_func_mhash_get_block_size_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mhash_get_block_size_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_mhash_get_block_size_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_mhash_get_hash_name_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mhash_get_hash_name", sizeof("mhash_get_hash_name") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_mhash_get_hash_name_0_arg0; - zend_string *attribute_Deprecated_func_mhash_get_hash_name_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_mhash_get_hash_name_0_arg0, attribute_Deprecated_func_mhash_get_hash_name_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mhash_get_hash_name_0->args[0].value, &attribute_Deprecated_func_mhash_get_hash_name_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mhash_get_hash_name_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_mhash_get_hash_name_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_mhash_keygen_s2k_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mhash_keygen_s2k", sizeof("mhash_keygen_s2k") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_mhash_keygen_s2k_0_arg0; - zend_string *attribute_Deprecated_func_mhash_keygen_s2k_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_mhash_keygen_s2k_0_arg0, attribute_Deprecated_func_mhash_keygen_s2k_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mhash_keygen_s2k_0->args[0].value, &attribute_Deprecated_func_mhash_keygen_s2k_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mhash_keygen_s2k_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_mhash_keygen_s2k_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_mhash_count_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mhash_count", sizeof("mhash_count") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_mhash_count_0_arg0; - zend_string *attribute_Deprecated_func_mhash_count_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_mhash_count_0_arg0, attribute_Deprecated_func_mhash_count_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mhash_count_0->args[0].value, &attribute_Deprecated_func_mhash_count_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mhash_count_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_mhash_count_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_mhash_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mhash", sizeof("mhash") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_mhash_0_arg0; - zend_string *attribute_Deprecated_func_mhash_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_mhash_0_arg0, attribute_Deprecated_func_mhash_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mhash_0->args[0].value, &attribute_Deprecated_func_mhash_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mhash_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_mhash_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); #endif } diff --git a/ext/hash/hash_crc32.c b/ext/hash/hash_crc32.c index a770d0b55416..795cfcdf05b2 100644 --- a/ext/hash/hash_crc32.c +++ b/ext/hash/hash_crc32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | diff --git a/ext/hash/hash_fnv.c b/ext/hash/hash_fnv.c index 92d4922bd810..58101c4f2e6c 100644 --- a/ext/hash/hash_fnv.c +++ b/ext/hash/hash_fnv.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Maclean | +----------------------------------------------------------------------+ diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index 2ad6948a9a67..ad87754970b9 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -304,17 +302,17 @@ PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context) ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_gost_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_gost_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_GOST_CTX *ctx = (PHP_GOST_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_GOST_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_GOST_SPEC)) == HASH_SPEC_SUCCESS && ctx->length < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_gost_ops = { diff --git a/ext/hash/hash_haval.c b/ext/hash/hash_haval.c index 67bc2b2e4780..2adafdb189e2 100644 --- a/ext/hash/hash_haval.c +++ b/ext/hash/hash_haval.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/hash_joaat.c b/ext/hash/hash_joaat.c index 328f9292c4ca..0d7b64092f47 100644 --- a/ext/hash/hash_joaat.c +++ b/ext/hash/hash_joaat.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Martin Jansen | +----------------------------------------------------------------------+ diff --git a/ext/hash/hash_md.c b/ext/hash/hash_md.c index 96da7fce82a2..0bd48a9c823c 100644 --- a/ext/hash/hash_md.c +++ b/ext/hash/hash_md.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Taken from: ext/standard/md5.c | +----------------------------------------------------------------------+ @@ -47,7 +45,7 @@ const php_hash_ops php_hash_md4_ops = { 1 }; -static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv); +static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv); const php_hash_ops php_hash_md2_ops = { "md2", @@ -356,15 +354,15 @@ PHP_HASH_API void PHP_MD2Final(unsigned char output[16], PHP_MD2_CTX *context) memcpy(output, context->state, 16); } -static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_MD2_CTX *ctx = (PHP_MD2_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_MD2_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_MD2_SPEC)) == HASH_SPEC_SUCCESS && (unsigned char) ctx->in_buffer < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } diff --git a/ext/hash/hash_murmur.c b/ext/hash/hash_murmur.c index 0117b2e57d36..cd5d5f4be520 100644 --- a/ext/hash/hash_murmur.c +++ b/ext/hash/hash_murmur.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/hash/hash_ripemd.c b/ext/hash/hash_ripemd.c index 4802fdf9a1fc..1b76f58ff098 100644 --- a/ext/hash/hash_ripemd.c +++ b/ext/hash/hash_ripemd.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/hash_sha.c b/ext/hash/hash_sha.c index 3129446fcde4..fd4d8ce5a36a 100644 --- a/ext/hash/hash_sha.c +++ b/ext/hash/hash_sha.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Steffan Esser | | Sara Golemon | diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c index 07da2cfd2d01..d82840e81de6 100644 --- a/ext/hash/hash_sha3.c +++ b/ext/hash/hash_sha3.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ @@ -200,20 +198,20 @@ static void PHP_SHA3_Final(unsigned char* digest, ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX)); } -static int php_sha3_unserialize(php_hashcontext_object *hash, +static hash_spec_result php_sha3_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv, size_t block_size) { PHP_SHA3_CTX *ctx = (PHP_SHA3_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_SHA3_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_SHA3_SPEC)) == HASH_SPEC_SUCCESS && ctx->pos < block_size) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } // ========================================================================== @@ -292,23 +290,23 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \ #endif #define PHP_KECCAK_SPEC "b200IiIIB" -static zend_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) +static hash_spec_result php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) { *magic = PHP_HASH_SERIALIZE_MAGIC_KECCAK; return php_hash_serialize_spec(hash, zv, PHP_KECCAK_SPEC); } -static int php_keccak_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_keccak_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { Keccak_HashInstance *ctx = (Keccak_HashInstance *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_KECCAK - && (r = php_hash_unserialize_spec(hash, zv, PHP_KECCAK_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_KECCAK_SPEC)) == HASH_SPEC_SUCCESS && ctx->sponge.byteIOIndex < ctx->sponge.rate / 8) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } // ========================================================================== diff --git a/ext/hash/hash_snefru.c b/ext/hash/hash_snefru.c index c1dbc3ae57a6..5f08eb088229 100644 --- a/ext/hash/hash_snefru.c +++ b/ext/hash/hash_snefru.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -189,17 +187,17 @@ PHP_HASH_API void PHP_SNEFRUFinal(unsigned char digest[32], PHP_SNEFRU_CTX *cont ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_snefru_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_snefru_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_SNEFRU_CTX *ctx = (PHP_SNEFRU_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_SNEFRU_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_SNEFRU_SPEC)) == HASH_SPEC_SUCCESS && ctx->length < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_snefru_ops = { diff --git a/ext/hash/hash_tiger.c b/ext/hash/hash_tiger.c index 841693a67dd1..1153711d85d4 100644 --- a/ext/hash/hash_tiger.c +++ b/ext/hash/hash_tiger.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -239,17 +237,17 @@ PHP_HASH_API void PHP_TIGER192Final(unsigned char digest[24], PHP_TIGER_CTX *con ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_tiger_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_tiger_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_TIGER_CTX *ctx = (PHP_TIGER_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_TIGER_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_TIGER_SPEC)) == HASH_SPEC_SUCCESS && ctx->length < sizeof(ctx->buffer)) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } #define PHP_HASH_TIGER_OPS(p, b) \ diff --git a/ext/hash/hash_whirlpool.c b/ext/hash/hash_whirlpool.c index db5a0da1236a..2a5b220d3a18 100644 --- a/ext/hash/hash_whirlpool.c +++ b/ext/hash/hash_whirlpool.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | @@ -429,20 +427,20 @@ PHP_HASH_API void PHP_WHIRLPOOLFinal(unsigned char digest[64], PHP_WHIRLPOOL_CTX ZEND_SECURE_ZERO(context, sizeof(*context)); } -static int php_whirlpool_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) +static hash_spec_result php_whirlpool_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_WHIRLPOOL_CTX *ctx = (PHP_WHIRLPOOL_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_WHIRLPOOL_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_WHIRLPOOL_SPEC)) == HASH_SPEC_SUCCESS && ctx->buffer.pos >= 0 && ctx->buffer.pos < (int) sizeof(ctx->buffer.data) && ctx->buffer.bits >= ctx->buffer.pos * 8 && ctx->buffer.bits < ctx->buffer.pos * 8 + 8) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_whirlpool_ops = { diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c index 1c1315afd4b2..b6177905e691 100644 --- a/ext/hash/hash_xxhash.c +++ b/ext/hash/hash_xxhash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ @@ -17,9 +15,9 @@ #include "php_hash.h" #include "php_hash_xxhash.h" -static int php_hash_xxh32_unserialize( +static hash_spec_result php_hash_xxh32_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv); -static int php_hash_xxh64_unserialize( +static hash_spec_result php_hash_xxh64_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv); const php_hash_ops php_hash_xxh32_ops = { @@ -75,18 +73,18 @@ PHP_HASH_API zend_result PHP_XXH32Copy(const php_hash_ops *ops, const PHP_XXH32_ return SUCCESS; } -static int php_hash_xxh32_unserialize( +static hash_spec_result php_hash_xxh32_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_XXH32_CTX *ctx = (PHP_XXH32_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH32_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH32_SPEC)) == HASH_SPEC_SUCCESS && ctx->s.memsize < 16) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_xxh64_ops = { @@ -231,18 +229,18 @@ PHP_HASH_API zend_result PHP_XXH3_64_Copy(const php_hash_ops *ops, const PHP_XXH return SUCCESS; } -static int php_hash_xxh64_unserialize( +static hash_spec_result php_hash_xxh64_unserialize( php_hashcontext_object *hash, zend_long magic, const zval *zv) { PHP_XXH64_CTX *ctx = (PHP_XXH64_CTX *) hash->context; - int r = FAILURE; + hash_spec_result r = HASH_SPEC_FAILURE; if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC - && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH64_SPEC)) == SUCCESS + && (r = php_hash_unserialize_spec(hash, zv, PHP_XXH64_SPEC)) == HASH_SPEC_SUCCESS && ctx->s.memsize < 32) { - return SUCCESS; - } else { - return r != SUCCESS ? r : -2000; + return HASH_SPEC_SUCCESS; } + + return r != HASH_SPEC_SUCCESS ? r : CONTEXT_VALIDATION_FAILURE; } const php_hash_ops php_hash_xxh3_128_ops = { diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 3b058ef48bdb..9eac5da78c8d 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ @@ -29,14 +27,22 @@ #define L64 INT64_C +typedef enum { + HASH_SPEC_SUCCESS = 0, + HASH_SPEC_FAILURE = -1, + WRONG_CONTEXT_SIZE = -999, + BYTE_OFFSET_POS_ERROR = -1000, + CONTEXT_VALIDATION_FAILURE = -2000, +} hash_spec_result; + typedef struct _php_hashcontext_object php_hashcontext_object; typedef void (*php_hash_init_func_t)(void *context, HashTable *args); typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, size_t count); typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context); typedef zend_result (*php_hash_copy_func_t)(const void *ops, const void *orig_context, void *dest_context); -typedef zend_result (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); -typedef int (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv); +typedef hash_spec_result (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv); +typedef hash_spec_result (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv); typedef struct _php_hash_ops { const char *algo; @@ -148,10 +154,10 @@ extern PHP_HASH_API zend_class_entry *php_hashcontext_ce; PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo); PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops); PHP_HASH_API zend_result php_hash_copy(const void *ops, const void *orig_context, void *dest_context); -PHP_HASH_API zend_result php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); -PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv); -PHP_HASH_API zend_result php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); -PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec); +PHP_HASH_API hash_spec_result php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv); +PHP_HASH_API hash_spec_result php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv); +PHP_HASH_API hash_spec_result php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec); +PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec); static inline void *php_hash_alloc_context(const php_hash_ops *ops) { /* Zero out context memory so serialization doesn't expose internals */ diff --git a/ext/hash/php_hash_adler32.h b/ext/hash/php_hash_adler32.h index bacb47ff1c91..c076893cb76f 100644 --- a/ext/hash/php_hash_adler32.h +++ b/ext/hash/php_hash_adler32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_crc32.h b/ext/hash/php_hash_crc32.h index b6accea17bb6..f50bff1c69ea 100644 --- a/ext/hash/php_hash_crc32.h +++ b/ext/hash/php_hash_crc32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_crc32_tables.h b/ext/hash/php_hash_crc32_tables.h index d126f177bdbe..28b70e4226b3 100644 --- a/ext/hash/php_hash_crc32_tables.h +++ b/ext/hash/php_hash_crc32_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_fnv.h b/ext/hash/php_hash_fnv.h index e9d1ce8d0b44..5e82bc4dab66 100644 --- a/ext/hash/php_hash_fnv.h +++ b/ext/hash/php_hash_fnv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Maclean | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index 66992b09b976..f1116c3852d6 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_haval.h b/ext/hash/php_hash_haval.h index e3a3a31b3685..c857d84b0abd 100644 --- a/ext/hash/php_hash_haval.h +++ b/ext/hash/php_hash_haval.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_joaat.h b/ext/hash/php_hash_joaat.h index fcc4cc3911bb..26e5adc03532 100644 --- a/ext/hash/php_hash_joaat.h +++ b/ext/hash/php_hash_joaat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Martin Jansen | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_md.h b/ext/hash/php_hash_md.h index f648fbf7c3c2..f9abbd5583b5 100644 --- a/ext/hash/php_hash_md.h +++ b/ext/hash/php_hash_md.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Original Author: Rasmus Lerdorf | | Modified for pHASH by: Sara Golemon diff --git a/ext/hash/php_hash_murmur.h b/ext/hash/php_hash_murmur.h index 6180a9b8f341..1539011156b3 100644 --- a/ext/hash/php_hash_murmur.h +++ b/ext/hash/php_hash_murmur.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_ripemd.h b/ext/hash/php_hash_ripemd.h index 0065450d21bb..1d30330d9e7f 100644 --- a/ext/hash/php_hash_ripemd.h +++ b/ext/hash/php_hash_ripemd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_sha.h b/ext/hash/php_hash_sha.h index 50eef82e858a..e2c6eac30b4c 100644 --- a/ext/hash/php_hash_sha.h +++ b/ext/hash/php_hash_sha.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | SHA1 Author: Stefan Esser | | SHA256 Author: Sara Golemon | diff --git a/ext/hash/php_hash_sha3.h b/ext/hash/php_hash_sha3.h index 8381a8943b4d..2692fd5de766 100644 --- a/ext/hash/php_hash_sha3.h +++ b/ext/hash/php_hash_sha3.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_snefru.h b/ext/hash/php_hash_snefru.h index df90e8e46968..2fbeb7c42ebe 100644 --- a/ext/hash/php_hash_snefru.h +++ b/ext/hash/php_hash_snefru.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_snefru_tables.h b/ext/hash/php_hash_snefru_tables.h index 0fc186b14cbe..075b2fe3e620 100644 --- a/ext/hash/php_hash_snefru_tables.h +++ b/ext/hash/php_hash_snefru_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_tiger.h b/ext/hash/php_hash_tiger.h index 92515c4dbf75..aa0f6cafbe8d 100644 --- a/ext/hash/php_hash_tiger.h +++ b/ext/hash/php_hash_tiger.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_tiger_tables.h b/ext/hash/php_hash_tiger_tables.h index 594bf836fd04..f2d1bb69f1ec 100644 --- a/ext/hash/php_hash_tiger_tables.h +++ b/ext/hash/php_hash_tiger_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Michael Wallner | | Sara Golemon | diff --git a/ext/hash/php_hash_whirlpool.h b/ext/hash/php_hash_whirlpool.h index f28ab234861b..b12e6c50a9f6 100644 --- a/ext/hash/php_hash_whirlpool.h +++ b/ext/hash/php_hash_whirlpool.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_whirlpool_tables.h b/ext/hash/php_hash_whirlpool_tables.h index ef121efe9449..cd58d6c53a3e 100644 --- a/ext/hash/php_hash_whirlpool_tables.h +++ b/ext/hash/php_hash_whirlpool_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Michael Wallner | +----------------------------------------------------------------------+ diff --git a/ext/hash/php_hash_xxhash.h b/ext/hash/php_hash_xxhash.h index f099039f3711..e2003ba4c584 100644 --- a/ext/hash/php_hash_xxhash.h +++ b/ext/hash/php_hash_xxhash.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Anatol Belski | +----------------------------------------------------------------------+ diff --git a/ext/hash/tests/mhash_001.phpt b/ext/hash/tests/mhash_001.phpt index 29f0f473380b..87da672550f6 100644 --- a/ext/hash/tests/mhash_001.phpt +++ b/ext/hash/tests/mhash_001.phpt @@ -35,77 +35,77 @@ foreach ($supported_hash_al as $hash=>$wanted) { } ?> --EXPECTF-- -Deprecated: Constant MHASH_MD5 is deprecated in %s on line %d +Deprecated: Constant MHASH_MD5 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_MD5 ok -Deprecated: Constant MHASH_SHA1 is deprecated in %s on line %d +Deprecated: Constant MHASH_SHA1 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_SHA1 ok -Deprecated: Constant MHASH_HAVAL256 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL256 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_HAVAL256 ok -Deprecated: Constant MHASH_HAVAL192 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL192 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_HAVAL192 ok -Deprecated: Constant MHASH_HAVAL224 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL224 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_HAVAL224 ok -Deprecated: Constant MHASH_HAVAL160 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL160 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_HAVAL160 ok -Deprecated: Constant MHASH_RIPEMD160 is deprecated in %s on line %d +Deprecated: Constant MHASH_RIPEMD160 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_RIPEMD160 ok -Deprecated: Constant MHASH_GOST is deprecated in %s on line %d +Deprecated: Constant MHASH_GOST is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_GOST ok -Deprecated: Constant MHASH_TIGER is deprecated in %s on line %d +Deprecated: Constant MHASH_TIGER is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_TIGER ok -Deprecated: Constant MHASH_CRC32 is deprecated in %s on line %d +Deprecated: Constant MHASH_CRC32 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_CRC32 ok -Deprecated: Constant MHASH_CRC32B is deprecated in %s on line %d +Deprecated: Constant MHASH_CRC32B is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d MHASH_CRC32B diff --git a/ext/hash/tests/mhash_003.phpt b/ext/hash/tests/mhash_003.phpt index f39e1ff387cb..1a0983ee54f4 100644 --- a/ext/hash/tests/mhash_003.phpt +++ b/ext/hash/tests/mhash_003.phpt @@ -35,77 +35,77 @@ foreach ($supported_hash_al as $hash=>$wanted) { } ?> --EXPECTF-- -Deprecated: Constant MHASH_MD5 is deprecated in %s on line %d +Deprecated: Constant MHASH_MD5 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_MD5 ok -Deprecated: Constant MHASH_SHA1 is deprecated in %s on line %d +Deprecated: Constant MHASH_SHA1 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_SHA1 ok -Deprecated: Constant MHASH_HAVAL256 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL256 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_HAVAL256 ok -Deprecated: Constant MHASH_HAVAL224 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL224 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_HAVAL224 ok -Deprecated: Constant MHASH_HAVAL192 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL192 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_HAVAL192 ok -Deprecated: Constant MHASH_HAVAL160 is deprecated in %s on line %d +Deprecated: Constant MHASH_HAVAL160 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_HAVAL160 ok -Deprecated: Constant MHASH_RIPEMD160 is deprecated in %s on line %d +Deprecated: Constant MHASH_RIPEMD160 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_RIPEMD160 ok -Deprecated: Constant MHASH_GOST is deprecated in %s on line %d +Deprecated: Constant MHASH_GOST is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_GOST ok -Deprecated: Constant MHASH_TIGER is deprecated in %s on line %d +Deprecated: Constant MHASH_TIGER is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_TIGER ok -Deprecated: Constant MHASH_CRC32 is deprecated in %s on line %d +Deprecated: Constant MHASH_CRC32 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_CRC32 ok -Deprecated: Constant MHASH_CRC32B is deprecated in %s on line %d +Deprecated: Constant MHASH_CRC32B is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d Deprecated: Function mhash_keygen_s2k() is deprecated since 8.1 in %s on line %d MHASH_CRC32B diff --git a/ext/hash/tests/mhash_004.phpt b/ext/hash/tests/mhash_004.phpt index e47d48eb1a5d..e7aa3c5e2df6 100644 --- a/ext/hash/tests/mhash_004.phpt +++ b/ext/hash/tests/mhash_004.phpt @@ -12,7 +12,7 @@ var_dump($algo); ?> --EXPECTF-- -Deprecated: Constant MHASH_MD5 is deprecated in %s on line %d +Deprecated: Constant MHASH_MD5 is deprecated since 8.5, as the mhash*() functions were deprecated in %s on line %d int(1) Deprecated: Function mhash() is deprecated since 8.1 in %s on line %d diff --git a/ext/hash/xxhash/xxhash.h b/ext/hash/xxhash/xxhash.h index 259371a3addd..a18e8c762daa 100644 --- a/ext/hash/xxhash/xxhash.h +++ b/ext/hash/xxhash/xxhash.h @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-2020 Yann Collet + * Copyright (C) 2012-2021 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -32,49 +32,142 @@ * - xxHash homepage: https://www.xxhash.com * - xxHash source repository: https://github.com/Cyan4973/xxHash */ + /*! * @mainpage xxHash * + * xxHash is an extremely fast non-cryptographic hash algorithm, working at RAM speed + * limits. + * + * It is proposed in four flavors, in three families: + * 1. @ref XXH32_family + * - Classic 32-bit hash function. Simple, compact, and runs on almost all + * 32-bit and 64-bit systems. + * 2. @ref XXH64_family + * - Classic 64-bit adaptation of XXH32. Just as simple, and runs well on most + * 64-bit systems (but _not_ 32-bit systems). + * 3. @ref XXH3_family + * - Modern 64-bit and 128-bit hash function family which features improved + * strength and performance across the board, especially on smaller data. + * It benefits greatly from SIMD and 64-bit without requiring it. + * + * Benchmarks + * --- + * The reference system uses an Intel i7-9700K CPU, and runs Ubuntu x64 20.04. + * The open source benchmark program is compiled with clang v10.0 using -O3 flag. + * + * | Hash Name | ISA ext | Width | Large Data Speed | Small Data Velocity | + * | -------------------- | ------- | ----: | ---------------: | ------------------: | + * | XXH3_64bits() | @b AVX2 | 64 | 59.4 GB/s | 133.1 | + * | MeowHash | AES-NI | 128 | 58.2 GB/s | 52.5 | + * | XXH3_128bits() | @b AVX2 | 128 | 57.9 GB/s | 118.1 | + * | CLHash | PCLMUL | 64 | 37.1 GB/s | 58.1 | + * | XXH3_64bits() | @b SSE2 | 64 | 31.5 GB/s | 133.1 | + * | XXH3_128bits() | @b SSE2 | 128 | 29.6 GB/s | 118.1 | + * | RAM sequential read | | N/A | 28.0 GB/s | N/A | + * | ahash | AES-NI | 64 | 22.5 GB/s | 107.2 | + * | City64 | | 64 | 22.0 GB/s | 76.6 | + * | T1ha2 | | 64 | 22.0 GB/s | 99.0 | + * | City128 | | 128 | 21.7 GB/s | 57.7 | + * | FarmHash | AES-NI | 64 | 21.3 GB/s | 71.9 | + * | XXH64() | | 64 | 19.4 GB/s | 71.0 | + * | SpookyHash | | 64 | 19.3 GB/s | 53.2 | + * | Mum | | 64 | 18.0 GB/s | 67.0 | + * | CRC32C | SSE4.2 | 32 | 13.0 GB/s | 57.9 | + * | XXH32() | | 32 | 9.7 GB/s | 71.9 | + * | City32 | | 32 | 9.1 GB/s | 66.0 | + * | Blake3* | @b AVX2 | 256 | 4.4 GB/s | 8.1 | + * | Murmur3 | | 32 | 3.9 GB/s | 56.1 | + * | SipHash* | | 64 | 3.0 GB/s | 43.2 | + * | Blake3* | @b SSE2 | 256 | 2.4 GB/s | 8.1 | + * | HighwayHash | | 64 | 1.4 GB/s | 6.0 | + * | FNV64 | | 64 | 1.2 GB/s | 62.7 | + * | Blake2* | | 256 | 1.1 GB/s | 5.1 | + * | SHA1* | | 160 | 0.8 GB/s | 5.6 | + * | MD5* | | 128 | 0.6 GB/s | 7.8 | + * @note + * - Hashes which require a specific ISA extension are noted. SSE2 is also noted, + * even though it is mandatory on x64. + * - Hashes with an asterisk are cryptographic. Note that MD5 is non-cryptographic + * by modern standards. + * - Small data velocity is a rough average of algorithm's efficiency for small + * data. For more accurate information, see the wiki. + * - More benchmarks and strength tests are found on the wiki: + * https://github.com/Cyan4973/xxHash/wiki + * + * Usage + * ------ + * All xxHash variants use a similar API. Changing the algorithm is a trivial + * substitution. + * + * @pre + * For functions which take an input and length parameter, the following + * requirements are assumed: + * - The range from [`input`, `input + length`) is valid, readable memory. + * - The only exception is if the `length` is `0`, `input` may be `NULL`. + * - For C++, the objects must have the *TriviallyCopyable* property, as the + * functions access bytes directly as if it was an array of `unsigned char`. + * + * @anchor single_shot_example + * **Single Shot** + * + * These functions are stateless functions which hash a contiguous block of memory, + * immediately returning the result. They are the easiest and usually the fastest + * option. + * + * XXH32(), XXH64(), XXH3_64bits(), XXH3_128bits() + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which hashes a null terminated string with XXH32(). + * XXH32_hash_t hash_string(const char* string, XXH32_hash_t seed) + * { + * // NULL pointers are only valid if the length is zero + * size_t length = (string == NULL) ? 0 : strlen(string); + * return XXH32(string, length, seed); + * } + * @endcode + * + * @anchor streaming_example + * **Streaming** + * + * These groups of functions allow incremental hashing of unknown size, even + * more than what would fit in a size_t. + * + * XXH32_reset(), XXH64_reset(), XXH3_64bits_reset(), XXH3_128bits_reset() + * + * @code{.c} + * #include + * #include + * #include "xxhash.h" + * // Example for a function which hashes a FILE incrementally with XXH3_64bits(). + * XXH64_hash_t hashFile(FILE* f) + * { + * // Allocate a state struct. Do not just use malloc() or new. + * XXH3_state_t* state = XXH3_createState(); + * assert(state != NULL && "Out of memory!"); + * // Reset the state to start a new hashing session. + * XXH3_64bits_reset(state); + * char buffer[4096]; + * size_t count; + * // Read the file in chunks + * while ((count = fread(buffer, 1, sizeof(buffer), f)) != 0) { + * // Run update() as many times as necessary to process the data + * XXH3_64bits_update(state, buffer, count); + * } + * // Retrieve the finalized hash. This will not change the state. + * XXH64_hash_t result = XXH3_64bits_digest(state); + * // Free the state. Do not use free(). + * XXH3_freeState(state); + * return result; + * } + * @endcode + * * @file xxhash.h * xxHash prototypes and implementation */ -/* TODO: update */ -/* Notice extracted from xxHash homepage: - -xxHash is an extremely fast hash algorithm, running at RAM speed limits. -It also successfully passes all tests from the SMHasher suite. - -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) - -Name Speed Q.Score Author -xxHash 5.4 GB/s 10 -CrapWow 3.2 GB/s 2 Andrew -MurmurHash 3a 2.7 GB/s 10 Austin Appleby -SpookyHash 2.0 GB/s 10 Bob Jenkins -SBox 1.4 GB/s 9 Bret Mulvey -Lookup3 1.2 GB/s 9 Bob Jenkins -SuperFastHash 1.2 GB/s 1 Paul Hsieh -CityHash64 1.05 GB/s 10 Pike & Alakuijala -FNV 0.55 GB/s 5 Fowler, Noll, Vo -CRC32 0.43 GB/s 9 -MD5-32 0.33 GB/s 10 Ronald L. Rivest -SHA1-32 0.28 GB/s 10 - -Q.Score is a measure of quality of the hash function. -It depends on successfully passing SMHasher test set. -10 is a perfect score. - -Note: SMHasher's CRC32 implementation is not the fastest one. -Other speed-oriented implementations can be faster, -especially in combination with PCLMUL instruction: -https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735 - -A 64-bit version, named XXH64, is available since r35. -It offers much better speed, but for 64-bit applications only. -Name Speed on 64 bits Speed on 32 bits -XXH64 13.8 GB/s 1.9 GB/s -XXH32 6.8 GB/s 6.0 GB/s -*/ #if defined (__cplusplus) extern "C" { @@ -84,21 +177,80 @@ extern "C" { * INLINE mode ******************************/ /*! - * XXH_INLINE_ALL (and XXH_PRIVATE_API) + * @defgroup public Public API + * Contains details on the public xxHash functions. + * @{ + */ +#ifdef XXH_DOXYGEN +/*! + * @brief Gives access to internal state declaration, required for static allocation. + * + * Incompatible with dynamic linking, due to risks of ABI changes. + * + * Usage: + * @code{.c} + * #define XXH_STATIC_LINKING_ONLY + * #include "xxhash.h" + * @endcode + */ +# define XXH_STATIC_LINKING_ONLY +/* Do not undef XXH_STATIC_LINKING_ONLY for Doxygen */ + +/*! + * @brief Gives access to internal definitions. + * + * Usage: + * @code{.c} + * #define XXH_STATIC_LINKING_ONLY + * #define XXH_IMPLEMENTATION + * #include "xxhash.h" + * @endcode + */ +# define XXH_IMPLEMENTATION +/* Do not undef XXH_IMPLEMENTATION for Doxygen */ + +/*! + * @brief Exposes the implementation and marks all functions as `inline`. + * * Use these build macros to inline xxhash into the target unit. * Inlining improves performance on small inputs, especially when the length is * expressed as a compile-time constant: * - * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html + * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html * * It also keeps xxHash symbols private to the unit, so they are not exported. * * Usage: + * @code{.c} * #define XXH_INLINE_ALL * #include "xxhash.h" - * + * @endcode * Do not compile and link xxhash.o as a separate object, as it is not useful. */ +# define XXH_INLINE_ALL +# undef XXH_INLINE_ALL +/*! + * @brief Exposes the implementation without marking functions as inline. + */ +# define XXH_PRIVATE_API +# undef XXH_PRIVATE_API +/*! + * @brief Emulate a namespace by transparently prefixing all symbols. + * + * If you want to include _and expose_ xxHash functions from within your own + * library, but also want to avoid symbol collisions with other libraries which + * may also include xxHash, you can use @ref XXH_NAMESPACE to automatically prefix + * any public symbol from xxhash library with the value of @ref XXH_NAMESPACE + * (therefore, avoid empty or numeric values). + * + * Note that no change is required within the calling program as long as it + * includes `xxhash.h`: Regular symbol names will be automatically translated + * by this header. + */ +# define XXH_NAMESPACE /* YOUR NAME HERE */ +# undef XXH_NAMESPACE +#endif + #if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \ && !defined(XXH_INLINE_ALL_31684351384) /* this section should be traversed only once */ @@ -213,23 +365,15 @@ extern "C" { # undef XXHASH_H_STATIC_13879238742 #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ - - /* **************************************************************** * Stable API *****************************************************************/ #ifndef XXHASH_H_5627135585666179 #define XXHASH_H_5627135585666179 1 - -/*! - * @defgroup public Public API - * Contains details on the public xxHash functions. - * @{ - */ -/* specific declaration modes for Windows */ +/*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -240,24 +384,6 @@ extern "C" { # endif #endif -#ifdef XXH_DOXYGEN -/*! - * @brief Emulate a namespace by transparently prefixing all symbols. - * - * If you want to include _and expose_ xxHash functions from within your own - * library, but also want to avoid symbol collisions with other libraries which - * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix - * any public symbol from xxhash library with the value of XXH_NAMESPACE - * (therefore, avoid empty or numeric values). - * - * Note that no change is required within the calling program as long as it - * includes `xxhash.h`: Regular symbol names will be automatically translated - * by this header. - */ -# define XXH_NAMESPACE /* YOUR NAME HERE */ -# undef XXH_NAMESPACE -#endif - #ifdef XXH_NAMESPACE # define XXH_CAT(A,B) A##B # define XXH_NAME2(A,B) XXH_CAT(A,B) @@ -317,12 +443,40 @@ extern "C" { #endif +/* ************************************* +* Compiler specifics +***************************************/ + +/* specific declaration modes for Windows */ +#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) +# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# ifdef XXH_EXPORT +# define XXH_PUBLIC_API __declspec(dllexport) +# elif XXH_IMPORT +# define XXH_PUBLIC_API __declspec(dllimport) +# endif +# else +# define XXH_PUBLIC_API /* do nothing */ +# endif +#endif + +#if defined (__GNUC__) +# define XXH_CONSTF __attribute__((const)) +# define XXH_PUREF __attribute__((pure)) +# define XXH_MALLOCF __attribute__((malloc)) +#else +# define XXH_CONSTF /* disable */ +# define XXH_PUREF +# define XXH_MALLOCF +#endif + /* ************************************* * Version ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 8 -#define XXH_VERSION_RELEASE 1 +#define XXH_VERSION_RELEASE 2 +/*! @brief Version number, encoded as two digits each */ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) /*! @@ -331,16 +485,22 @@ extern "C" { * This is mostly useful when xxHash is compiled as a shared library, * since the returned value comes from the library, as opposed to header file. * - * @return `XXH_VERSION_NUMBER` of the invoked library. + * @return @ref XXH_VERSION_NUMBER of the invoked library. */ -XXH_PUBLIC_API unsigned XXH_versionNumber (void); +XXH_PUBLIC_API XXH_CONSTF unsigned XXH_versionNumber (void); /* **************************** * Common basic types ******************************/ #include /* size_t */ -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; +/*! + * @brief Exit code for the streaming API. + */ +typedef enum { + XXH_OK = 0, /*!< OK */ + XXH_ERROR /*!< Error */ +} XXH_errorcode; /*-********************************************************************** @@ -364,29 +524,27 @@ typedef uint32_t XXH32_hash_t; # include # if UINT_MAX == 0xFFFFFFFFUL typedef unsigned int XXH32_hash_t; +# elif ULONG_MAX == 0xFFFFFFFFUL + typedef unsigned long XXH32_hash_t; # else -# if ULONG_MAX == 0xFFFFFFFFUL - typedef unsigned long XXH32_hash_t; -# else -# error "unsupported platform: need a 32-bit type" -# endif +# error "unsupported platform: need a 32-bit type" # endif #endif /*! * @} * - * @defgroup xxh32_family XXH32 family + * @defgroup XXH32_family XXH32 family * @ingroup public * Contains functions used in the classic 32-bit xxHash algorithm. * * @note * XXH32 is useful for older platforms, with no or poor 64-bit performance. - * Note that @ref xxh3_family provides competitive speed - * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results. + * Note that the @ref XXH3_family provides competitive speed for both 32-bit + * and 64-bit systems, and offers true 64/128 bit hash results. * - * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families - * @see @ref xxh32_impl for implementation details + * @see @ref XXH64_family, @ref XXH3_family : Other xxHash families + * @see @ref XXH32_impl for implementation details * @{ */ @@ -395,6 +553,8 @@ typedef uint32_t XXH32_hash_t; * * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s * + * See @ref single_shot_example "Single Shot Example" for an example. + * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 32-bit seed to alter the hash's output predictably. @@ -412,8 +572,9 @@ typedef uint32_t XXH32_hash_t; * @see * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. */ -XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); +#ifndef XXH_NO_STREAM /*! * Streaming functions generate the xxHash value from an incremental input. * This method is slower than single-call functions, due to state management. @@ -436,32 +597,7 @@ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_ * * When done, release the state using `XXH*_freeState()`. * - * Example code for incrementally hashing a file: - * @code{.c} - * #include - * #include - * #define BUFFER_SIZE 256 - * - * // Note: XXH64 and XXH3 use the same interface. - * XXH32_hash_t - * hashFile(FILE* stream) - * { - * XXH32_state_t* state; - * unsigned char buf[BUFFER_SIZE]; - * size_t amt; - * XXH32_hash_t hash; - * - * state = XXH32_createState(); // Create a state - * assert(state != NULL); // Error check here - * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed - * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) { - * XXH32_update(state, buf, amt); // Hash the file in chunks - * } - * hash = XXH32_digest(state); // Finalize the hash - * XXH32_freeState(state); // Clean up - * return hash; - * } - * @endcode + * @see streaming_example at the top of @ref xxhash.h for an example. */ /*! @@ -478,7 +614,7 @@ typedef struct XXH32_state_s XXH32_state_t; * Must be freed with XXH32_freeState(). * @return An allocated XXH32_state_t on success, `NULL` on failure. */ -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); +XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); /*! * @brief Frees an @ref XXH32_state_t. * @@ -546,7 +682,8 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* * * @return The calculated xxHash32 value from that state. */ -XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ @@ -597,43 +734,72 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t * * @return The converted hash. */ -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); +XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); +/*! @cond Doxygen ignores this part */ #ifdef __has_attribute # define XXH_HAS_ATTRIBUTE(x) __has_attribute(x) #else # define XXH_HAS_ATTRIBUTE(x) 0 #endif +/*! @endcond */ +/*! @cond Doxygen ignores this part */ +/* + * C23 __STDC_VERSION__ number hasn't been specified yet. For now + * leave as `201711L` (C17 + 1). + * TODO: Update to correct value when its been specified. + */ +#define XXH_C23_VN 201711L +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ /* C-language Attributes are added in C23. */ -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute) +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= XXH_C23_VN) && defined(__has_c_attribute) # define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) #else # define XXH_HAS_C_ATTRIBUTE(x) 0 #endif +/*! @endcond */ +/*! @cond Doxygen ignores this part */ #if defined(__cplusplus) && defined(__has_cpp_attribute) # define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) #else # define XXH_HAS_CPP_ATTRIBUTE(x) 0 #endif +/*! @endcond */ +/*! @cond Doxygen ignores this part */ /* -Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute -introduced in CPP17 and C23. -CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough -C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough -*/ -#if XXH_HAS_C_ATTRIBUTE(x) -# define XXH_FALLTHROUGH [[fallthrough]] -#elif XXH_HAS_CPP_ATTRIBUTE(x) + * Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute + * introduced in CPP17 and C23. + * CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough + * C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough + */ +#if XXH_HAS_C_ATTRIBUTE(fallthrough) || XXH_HAS_CPP_ATTRIBUTE(fallthrough) # define XXH_FALLTHROUGH [[fallthrough]] #elif XXH_HAS_ATTRIBUTE(__fallthrough__) -# define XXH_FALLTHROUGH __attribute__ ((fallthrough)) +# define XXH_FALLTHROUGH __attribute__ ((__fallthrough__)) #else -# define XXH_FALLTHROUGH +# define XXH_FALLTHROUGH /* fallthrough */ #endif +/*! @endcond */ + +/*! @cond Doxygen ignores this part */ +/* + * Define XXH_NOESCAPE for annotated pointers in public API. + * https://clang.llvm.org/docs/AttributeReference.html#noescape + * As of writing this, only supported by clang. + */ +#if XXH_HAS_ATTRIBUTE(noescape) +# define XXH_NOESCAPE __attribute__((noescape)) +#else +# define XXH_NOESCAPE +#endif +/*! @endcond */ + /*! * @} @@ -671,7 +837,7 @@ typedef uint64_t XXH64_hash_t; /*! * @} * - * @defgroup xxh64_family XXH64 family + * @defgroup XXH64_family XXH64 family * @ingroup public * @{ * Contains functions used in the classic 64-bit xxHash algorithm. @@ -682,7 +848,6 @@ typedef uint64_t XXH64_hash_t; * It provides better speed for systems with vector processing capabilities. */ - /*! * @brief Calculates the 64-bit hash of @p input using xxHash64. * @@ -706,32 +871,131 @@ typedef uint64_t XXH64_hash_t; * @see * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. */ -XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); /******* Streaming *******/ +#ifndef XXH_NO_STREAM /*! * @brief The opaque state struct for the XXH64 streaming API. * * @see XXH64_state_s for details. */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); + +/*! + * @brief Allocates an @ref XXH64_state_t. + * + * Must be freed with XXH64_freeState(). + * @return An allocated XXH64_state_t on success, `NULL` on failure. + */ +XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); + +/*! + * @brief Frees an @ref XXH64_state_t. + * + * Must be allocated with XXH64_createState(). + * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). + * @return XXH_OK. + */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); -XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed); -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); +/*! + * @brief Copies one @ref XXH64_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. + */ +XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const XXH64_state_t* src_state); +/*! + * @brief Resets an @ref XXH64_state_t to begin a new hash. + * + * This function resets and seeds a state. Call it before @ref XXH64_update(). + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + */ +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); + +/*! + * @brief Consumes a block of @p input to an @ref XXH64_state_t. + * + * Call this to incrementally consume blocks of data. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + */ +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated hash value from an @ref XXH64_state_t. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated xxHash64 value from that state. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ + +/*! + * @brief Canonical (big endian) representation of @ref XXH64_hash_t. + */ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t; -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); + +/*! + * @brief Converts an @ref XXH64_hash_t to a big endian @ref XXH64_canonical_t. + * + * @param dst The @ref XXH64_canonical_t pointer to be stored to. + * @param hash The @ref XXH64_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + */ +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); + +/*! + * @brief Converts an @ref XXH64_canonical_t to a native @ref XXH64_hash_t. + * + * @param src The @ref XXH64_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); + +#ifndef XXH_NO_XXH3 /*! * @} * ************************************************************************ - * @defgroup xxh3_family XXH3 family + * @defgroup XXH3_family XXH3 family * @ingroup public * @{ * @@ -751,16 +1015,26 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src * * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic, * but does not require it. - * Any 32-bit and 64-bit targets that can run XXH32 smoothly - * can run XXH3 at competitive speeds, even without vector support. - * Further details are explained in the implementation. - * - * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8, - * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro. + * Most 32-bit and 64-bit targets that can run XXH32 smoothly can run XXH3 + * at competitive speeds, even without vector support. Further details are + * explained in the implementation. + * + * XXH3 has a fast scalar implementation, but it also includes accelerated SIMD + * implementations for many common platforms: + * - AVX512 + * - AVX2 + * - SSE2 + * - ARM NEON + * - WebAssembly SIMD128 + * - POWER8 VSX + * - s390x ZVector + * This can be controlled via the @ref XXH_VECTOR macro, but it automatically + * selects the best version according to predefined macros. For the x86 family, an + * automatic runtime dispatcher is included separately in @ref xxh_x86dispatch.c. * * XXH3 implementation is portable: * it has a generic C90 formulation that can be compiled on any platform, - * all implementations generage exactly the same hash value on all platforms. + * all implementations generate exactly the same hash value on all platforms. * Starting from v0.8.0, it's also labelled "stable", meaning that * any future version will also generate the same hash value. * @@ -772,24 +1046,42 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src * * The API supports one-shot hashing, streaming mode, and custom secrets. */ - /*-********************************************************************** * XXH3 64-bit variant ************************************************************************/ -/* XXH3_64bits(): - * default 64-bit variant, using default secret and default seed of 0. - * It's the fastest variant. */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len); +/*! + * @brief 64-bit unseeded variant of XXH3. + * + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however + * it may have slightly better performance due to constant propagation of the + * defaults. + * + * @see + * XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms + * @see + * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants + * @see + * XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); -/* - * XXH3_64bits_withSeed(): - * This variant generates a custom secret on the fly - * based on default secret altered using the `seed` value. +/*! + * @brief 64-bit seeded variant of XXH3 + * + * This variant generates a custom secret on the fly based on default secret + * altered using the `seed` value. + * * While this operation is decently fast, note that it's not completely free. - * Note: seed==0 produces the same results as XXH3_64bits(). + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * @param input The data to hash + * @param length The length + * @param seed The 64-bit seed to alter the state. */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); /*! * The bare minimum size for a custom secret. @@ -800,8 +1092,9 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X */ #define XXH3_SECRET_SIZE_MIN 136 -/* - * XXH3_64bits_withSecret(): +/*! + * @brief 64-bit variant of XXH3 with a custom "secret". + * * It's possible to provide any blob of bytes as a "secret" to generate the hash. * This makes it more difficult for an external actor to prepare an intentional collision. * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). @@ -817,10 +1110,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, X * This is not necessarily the case when using the blob of bytes directly * because, when hashing _small_ inputs, only a portion of the secret is employed. */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ +#ifndef XXH_NO_STREAM /* * Streaming requires state maintenance. * This operation costs memory and CPU. @@ -834,23 +1128,53 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, * @see XXH3_state_s for details. */ typedef struct XXH3_state_s XXH3_state_t; -XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void); +XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr); -XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state); -/* - * XXH3_64bits_reset(): - * Initialize with default parameters. - * digest will be equivalent to `XXH3_64bits()`. +/*! + * @brief Copies one @ref XXH3_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr); -/* - * XXH3_64bits_reset_withSeed(): - * Generate a custom secret from `seed`, and store it into `statePtr`. - * digest will be equivalent to `XXH3_64bits_withSeed()`. +XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOESCAPE const XXH3_state_t* src_state); + +/*! + * @brief Resets an @ref XXH3_state_t to begin a new hash. + * + * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_64bits_update(). + * Digest will be equivalent to `XXH3_64bits()`. + * + * @param statePtr The state struct to reset. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); -/* +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); + +/*! + * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. + * + * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_64bits_update(). + * Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the state. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); + +/*! * XXH3_64bits_reset_withSecret(): * `secret` is referenced, it _must outlive_ the hash streaming session. * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, @@ -859,10 +1183,44 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, * When in doubt about the randomness of a candidate `secret`, * consider employing `XXH3_generateSecret()` instead (see below). */ -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); -XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr); +/*! + * @brief Consumes a block of @p input to an @ref XXH3_state_t. + * + * Call this to incrementally consume blocks of data. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); + +/*! + * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated XXH3 64-bit hash value from that state. + */ +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /* note : canonical representation of XXH3 is the same as XXH64 * since they both produce XXH64_hash_t values */ @@ -883,11 +1241,31 @@ typedef struct { XXH64_hash_t high64; /*!< `value >> 64` */ } XXH128_hash_t; -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); +/*! + * @brief Unseeded 128-bit variant of XXH3 + * + * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead + * for shorter inputs. + * + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however + * it may have slightly better performance due to constant propagation of the + * defaults. + * + * @see + * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms + * @see + * XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see + * XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); +/*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); +/*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ +#ifndef XXH_NO_STREAM /* * Streaming requires state maintenance. * This operation costs memory and CPU. @@ -900,12 +1278,77 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t le * All reset and streaming functions have same meaning as their 64-bit counterpart. */ -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr); -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); +/*! + * @brief Resets an @ref XXH3_state_t to begin a new hash. + * + * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_128bits_update(). + * Digest will be equivalent to `XXH3_128bits()`. + * + * @param statePtr The state struct to reset. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); + +/*! + * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. + * + * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_128bits_update(). + * Digest will be equivalent to `XXH3_128bits_withSeed()`. + * + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the state. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! @brief Custom secret 128-bit variant of XXH3. @see XXH_64bits_reset_withSecret(). */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); + +/*! + * @brief Consumes a block of @p input to an @ref XXH3_state_t. + * + * Call this to incrementally consume blocks of data. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length); -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr); +/*! + * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated XXH3 128-bit hash value from that state. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); +#endif /* !XXH_NO_STREAM */ /* Following helper functions make it possible to compare XXH128_hast_t values. * Since XXH128_hash_t is a structure, this capability is not offered by the language. @@ -915,26 +1358,48 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr); * XXH128_isEqual(): * Return: 1 if `h1` and `h2` are equal, 0 if they are not. */ -XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); +XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); /*! - * XXH128_cmp(): - * + * @brief Compares two @ref XXH128_hash_t * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * - * return: >0 if *h128_1 > *h128_2 - * =0 if *h128_1 == *h128_2 - * <0 if *h128_1 < *h128_2 + * @return: >0 if *h128_1 > *h128_2 + * =0 if *h128_1 == *h128_2 + * <0 if *h128_1 < *h128_2 */ -XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2); +XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); /******* Canonical representation *******/ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t; -static zend_always_inline void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash); -XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src); +/*! + * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. + * + * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param hash The @ref XXH128_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + */ +XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); + +/*! + * @brief Converts an @ref XXH128_canonical_t to a native @ref XXH128_hash_t. + * + * @param src The @ref XXH128_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); + + +#endif /* !XXH_NO_XXH3 */ #endif /* XXH_NO_LONG_LONG */ /*! @@ -978,7 +1443,7 @@ struct XXH32_state_s { XXH32_hash_t v[4]; /*!< Accumulator lanes */ XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ - XXH32_hash_t reserved; /*!< Reserved field. Do not read or write to it, it may be removed. */ + XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ }; /* typedef'd to XXH32_state_t */ @@ -1002,9 +1467,11 @@ struct XXH64_state_s { XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ - XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it, it may be removed. */ + XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ +#ifndef XXH_NO_XXH3 + #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ # include # define XXH_ALIGN(n) alignas(n) @@ -1038,6 +1505,7 @@ struct XXH64_state_s { #define XXH3_INTERNALBUFFER_SIZE 256 /*! + * @internal * @brief Default size of the secret buffer (and @ref XXH3_kSecret). * * This is the size used in @ref XXH3_kSecret and the seeded functions. @@ -1070,7 +1538,7 @@ struct XXH64_state_s { */ struct XXH3_state_s { XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]); - /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */ + /*!< The 8 accumulators. See @ref XXH32_state_s::v and @ref XXH64_state_s::v */ XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]); /*!< Used to store a custom secret generated from a seed. */ XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]); @@ -1110,69 +1578,119 @@ struct XXH3_state_s { * Note that this doesn't prepare the state for a streaming operation, * it's still necessary to use XXH3_NNbits_reset*() afterwards. */ -#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; } +#define XXH3_INITSTATE(XXH3_state_ptr) \ + do { \ + XXH3_state_t* tmp_xxh3_state_ptr = (XXH3_state_ptr); \ + tmp_xxh3_state_ptr->seed = 0; \ + tmp_xxh3_state_ptr->extSecret = NULL; \ + } while(0) -/* XXH128() : +/*! * simple alias to pre-selected XXH3_128bits variant */ -XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); /* === Experimental API === */ /* Symbols defined below must be considered tied to a specific library version. */ -/* +/*! * XXH3_generateSecret(): * * Derive a high-entropy secret from any user-defined content, named customSeed. * The generated secret can be used in combination with `*_withSecret()` functions. - * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed, - * as it becomes much more difficult for an external actor to guess how to impact the calculation logic. + * The `_withSecret()` variants are useful to provide a higher level of protection + * than 64-bit seed, as it becomes much more difficult for an external actor to + * guess how to impact the calculation logic. * * The function accepts as input a custom seed of any length and any content, - * and derives from it a high-entropy secret of length @secretSize - * into an already allocated buffer @secretBuffer. - * @secretSize must be >= XXH3_SECRET_SIZE_MIN + * and derives from it a high-entropy secret of length @p secretSize into an + * already allocated buffer @p secretBuffer. * * The generated secret can then be used with any `*_withSecret()` variant. - * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`, - * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()` + * The functions @ref XXH3_128bits_withSecret(), @ref XXH3_64bits_withSecret(), + * @ref XXH3_128bits_reset_withSecret() and @ref XXH3_64bits_reset_withSecret() * are part of this list. They all accept a `secret` parameter - * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN) + * which must be large enough for implementation reasons (>= @ref XXH3_SECRET_SIZE_MIN) * _and_ feature very high entropy (consist of random-looking bytes). - * These conditions can be a high bar to meet, so - * XXH3_generateSecret() can be employed to ensure proper quality. + * These conditions can be a high bar to meet, so @ref XXH3_generateSecret() can + * be employed to ensure proper quality. * - * customSeed can be anything. It can have any size, even small ones, - * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes. - * The resulting `secret` will nonetheless provide all required qualities. + * @p customSeed can be anything. It can have any size, even small ones, + * and its content can be anything, even "poor entropy" sources such as a bunch + * of zeroes. The resulting `secret` will nonetheless provide all required qualities. + * + * @pre + * - @p secretSize must be >= @ref XXH3_SECRET_SIZE_MIN + * - When @p customSeedSize > 0, supplying NULL as customSeed is undefined behavior. * - * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior. + * Example code: + * @code{.c} + * #include + * #include + * #include + * #define XXH_STATIC_LINKING_ONLY // expose unstable API + * #include "xxhash.h" + * // Hashes argv[2] using the entropy from argv[1]. + * int main(int argc, char* argv[]) + * { + * char secret[XXH3_SECRET_SIZE_MIN]; + * if (argv != 3) { return 1; } + * XXH3_generateSecret(secret, sizeof(secret), argv[1], strlen(argv[1])); + * XXH64_hash_t h = XXH3_64bits_withSecret( + * argv[2], strlen(argv[2]), + * secret, sizeof(secret) + * ); + * printf("%016llx\n", (unsigned long long) h); + * } + * @endcode */ -XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize); - +XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer, size_t secretSize, XXH_NOESCAPE const void* customSeed, size_t customSeedSize); -/* - * XXH3_generateSecret_fromSeed(): - * - * Generate the same secret as the _withSeed() variants. - * - * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily). - * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes. +/*! + * @brief Generate the same secret as the _withSeed() variants. * * The generated secret can be used in combination with *`*_withSecret()` and `_withSecretandSeed()` variants. - * This generator is notably useful in combination with `_withSecretandSeed()`, - * as a way to emulate a faster `_withSeed()` variant. + * + * Example C++ `std::string` hash class: + * @code{.cpp} + * #include + * #define XXH_STATIC_LINKING_ONLY // expose unstable API + * #include "xxhash.h" + * // Slow, seeds each time + * class HashSlow { + * XXH64_hash_t seed; + * public: + * HashSlow(XXH64_hash_t s) : seed{s} {} + * size_t operator()(const std::string& x) const { + * return size_t{XXH3_64bits_withSeed(x.c_str(), x.length(), seed)}; + * } + * }; + * // Fast, caches the seeded secret for future uses. + * class HashFast { + * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * public: + * HashFast(XXH64_hash_t s) { + * XXH3_generateSecret_fromSeed(secret, seed); + * } + * size_t operator()(const std::string& x) const { + * return size_t{ + * XXH3_64bits_withSecret(x.c_str(), x.length(), secret, sizeof(secret)) + * }; + * } + * }; + * @endcode + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes + * @param seed The seed to seed the state. */ -XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed); +XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); -/* - * *_withSecretandSeed() : +/*! * These variants generate hash values using either - * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) - * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) + * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX). * * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. * `_withSeed()` has to generate the secret on the fly for "large" keys. @@ -1181,7 +1699,7 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_ * which requires more instructions than _withSeed() variants. * Therefore, _withSecretandSeed variant combines the best of both worlds. * - * When @secret has been generated by XXH3_generateSecret_fromSeed(), + * When @p secret has been generated by XXH3_generateSecret_fromSeed(), * this variant produces *exactly* the same results as `_withSeed()` variant, * hence offering only a pure speed benefit on "large" input, * by skipping the need to regenerate the secret for every large input. @@ -1190,32 +1708,34 @@ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_ * for example with XXH3_64bits(), which then becomes the seed, * and then employ both the seed and the secret in _withSecretandSeed(). * On top of speed, an added benefit is that each bit in the secret - * has a 50% chance to swap each bit in the output, - * via its impact to the seed. + * has a 50% chance to swap each bit in the output, via its impact to the seed. + * * This is not guaranteed when using the secret directly in "small data" scenarios, * because only portions of the secret are employed for small data. */ -XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecretandSeed(const void* data, size_t len, - const void* secret, size_t secretSize, +XXH_PUBLIC_API XXH_PUREF XXH64_hash_t +XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed); - -XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSecretandSeed(const void* data, size_t len, - const void* secret, size_t secretSize, +/*! @copydoc XXH3_64bits_withSecretandSeed() */ +XXH_PUBLIC_API XXH_PUREF XXH128_hash_t +XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); - +#ifndef XXH_NO_STREAM +/*! @copydoc XXH3_64bits_withSecretandSeed() */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, - const void* secret, size_t secretSize, +XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); - +/*! @copydoc XXH3_64bits_withSecretandSeed() */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, - const void* secret, size_t secretSize, +XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, + XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); +#endif /* !XXH_NO_STREAM */ - +#endif /* !XXH_NO_XXH3 */ #endif /* XXH_NO_LONG_LONG */ #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # define XXH_IMPLEMENTATION @@ -1269,7 +1789,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, /*! * @brief Define this to disable 64-bit code. * - * Useful if only using the @ref xxh32_family and you have a strict C90 compiler. + * Useful if only using the @ref XXH32_family and you have a strict C90 compiler. */ # define XXH_NO_LONG_LONG # undef XXH_NO_LONG_LONG /* don't actually */ @@ -1292,7 +1812,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * Use `memcpy()`. Safe and portable. Note that most modern compilers will * eliminate the function call and treat it as an unaligned access. * - * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((packed))` + * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((aligned(1)))` * @par * Depends on compiler extensions and is therefore not portable. * This method is safe _if_ your compiler supports it, @@ -1312,19 +1832,47 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * inline small `memcpy()` calls, and it might also be faster on big-endian * systems which lack a native byteswap instruction. However, some compilers * will emit literal byteshifts even if the target supports unaligned access. - * . + * * * @warning * Methods 1 and 2 rely on implementation-defined behavior. Use these with * care, as what works on one compiler/platform/optimization level may cause * another to read garbage data or even crash. * - * See http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details. + * See https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details. * * Prefer these methods in priority order (0 > 3 > 1 > 2) */ # define XXH_FORCE_MEMORY_ACCESS 0 +/*! + * @def XXH_SIZE_OPT + * @brief Controls how much xxHash optimizes for size. + * + * xxHash, when compiled, tends to result in a rather large binary size. This + * is mostly due to heavy usage to forced inlining and constant folding of the + * @ref XXH3_family to increase performance. + * + * However, some developers prefer size over speed. This option can + * significantly reduce the size of the generated code. When using the `-Os` + * or `-Oz` options on GCC or Clang, this is defined to 1 by default, + * otherwise it is defined to 0. + * + * Most of these size optimizations can be controlled manually. + * + * This is a number from 0-2. + * - `XXH_SIZE_OPT` == 0: Default. xxHash makes no size optimizations. Speed + * comes first. + * - `XXH_SIZE_OPT` == 1: Default for `-Os` and `-Oz`. xxHash is more + * conservative and disables hacks that increase code size. It implies the + * options @ref XXH_NO_INLINE_HINTS == 1, @ref XXH_FORCE_ALIGN_CHECK == 0, + * and @ref XXH3_NEON_LANES == 8 if they are not already defined. + * - `XXH_SIZE_OPT` == 2: xxHash tries to make itself as small as possible. + * Performance may cry. For example, the single shot functions just use the + * streaming API. + */ +# define XXH_SIZE_OPT 0 + /*! * @def XXH_FORCE_ALIGN_CHECK * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32() @@ -1346,9 +1894,11 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * * In these cases, the alignment check can be removed by setting this macro to 0. * Then the code will always use unaligned memory access. - * Align check is automatically disabled on x86, x64 & arm64, + * Align check is automatically disabled on x86, x64, ARM64, and some ARM chips * which are platforms known to offer good unaligned memory accesses performance. * + * It is also disabled by default when @ref XXH_SIZE_OPT >= 1. + * * This option does not affect XXH3 (only XXH32 and XXH64). */ # define XXH_FORCE_ALIGN_CHECK 0 @@ -1370,8 +1920,8 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the * compiler full control on whether to inline or not. * - * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using - * -fno-inline with GCC or Clang, this will automatically be defined. + * When not optimizing (-O0), using `-fno-inline` with GCC or Clang, or if + * @ref XXH_SIZE_OPT >= 1, this will automatically be defined. */ # define XXH_NO_INLINE_HINTS 0 @@ -1413,34 +1963,45 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, */ # define XXH_OLD_NAMES # undef XXH_OLD_NAMES /* don't actually use, it is ugly. */ + +/*! + * @def XXH_NO_STREAM + * @brief Disables the streaming API. + * + * When xxHash is not inlined and the streaming functions are not used, disabling + * the streaming functions can improve code size significantly, especially with + * the @ref XXH3_family which tends to make constant folded copies of itself. + */ +# define XXH_NO_STREAM +# undef XXH_NO_STREAM /* don't actually */ #endif /* XXH_DOXYGEN */ /*! * @} */ #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ - /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */ -# if !defined(__clang__) && \ -( \ - (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ - ( \ - defined(__GNUC__) && ( \ - (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \ - ( \ - defined(__mips__) && \ - (__mips <= 5 || __mips_isa_rev < 6) && \ - (!defined(__mips16) || defined(__mips_mips16e2)) \ - ) \ - ) \ - ) \ -) + /* prefer __packed__ structures (method 1) for GCC + * < ARMv7 with unaligned access (e.g. Raspbian armhf) still uses byte shifting, so we use memcpy + * which for some reason does unaligned loads. */ +# if defined(__GNUC__) && !(defined(__ARM_ARCH) && __ARM_ARCH < 7 && defined(__ARM_FEATURE_UNALIGNED)) # define XXH_FORCE_MEMORY_ACCESS 1 # endif #endif +#ifndef XXH_SIZE_OPT + /* default to 1 for -Os or -Oz */ +# if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE_SIZE__) +# define XXH_SIZE_OPT 1 +# else +# define XXH_SIZE_OPT 0 +# endif +#endif + #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \ - || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */ + /* don't check on sizeopt, x86, aarch64, or arm when unaligned access is available */ +# if XXH_SIZE_OPT >= 1 || \ + defined(__i386) || defined(__x86_64__) || defined(__aarch64__) || defined(__ARM_FEATURE_UNALIGNED) \ + || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) || defined(_M_ARM) /* visual */ # define XXH_FORCE_ALIGN_CHECK 0 # else # define XXH_FORCE_ALIGN_CHECK 1 @@ -1448,8 +2009,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, #endif #ifndef XXH_NO_INLINE_HINTS -# if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \ - || defined(__NO_INLINE__) /* -O0, -fno-inline */ +# if XXH_SIZE_OPT >= 1 || defined(__NO_INLINE__) /* -O0, -fno-inline */ # define XXH_NO_INLINE_HINTS 1 # else # define XXH_NO_INLINE_HINTS 0 @@ -1479,6 +2039,24 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, /* ************************************* * Includes & Memory related functions ***************************************/ +#if defined(XXH_NO_STREAM) +/* nothing */ +#elif defined(XXH_NO_STDLIB) + +/* When requesting to disable any mention of stdlib, + * the library loses the ability to invoked malloc / free. + * In practice, it means that functions like `XXH*_createState()` + * will always fail, and return NULL. + * This flag is useful in situations where + * xxhash.h is integrated into some kernel, embedded or limited environment + * without access to dynamic allocation. + */ + +static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; } +static void XXH_free(void* p) { (void)p; } + +#else + /* * Modify the local functions below should you wish to use * different memory routines for malloc() and free() @@ -1489,7 +2067,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, * @internal * @brief Modify this function to use a different routine than malloc(). */ -static void* XXH_malloc(size_t s) { return malloc(s); } +static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); } /*! * @internal @@ -1497,6 +2075,8 @@ static void* XXH_malloc(size_t s) { return malloc(s); } */ static void XXH_free(void* p) { free(p); } +#endif /* XXH_NO_STDLIB */ + #include /*! @@ -1571,7 +2151,11 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) # include /* note: can still be disabled with NDEBUG */ # define XXH_ASSERT(c) assert(c) #else -# define XXH_ASSERT(c) ((void)0) +# if defined(__INTEL_COMPILER) +# define XXH_ASSERT(c) XXH_ASSUME((unsigned char) (c)) +# else +# define XXH_ASSERT(c) XXH_ASSUME(c) +# endif #endif /* note: use after variable declarations */ @@ -1603,11 +2187,19 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) * XXH3_initCustomSecret_scalar(). */ #if defined(__GNUC__) || defined(__clang__) -# define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var)) +# define XXH_COMPILER_GUARD(var) __asm__("" : "+r" (var)) #else # define XXH_COMPILER_GUARD(var) ((void)0) #endif +/* Specifically for NEON vectors which use the "w" constraint, on + * Clang. */ +#if defined(__clang__) && defined(__ARM_ARCH) && !defined(__wasm__) +# define XXH_COMPILER_GUARD_CLANG_NEON(var) __asm__("" : "+w" (var)) +#else +# define XXH_COMPILER_GUARD_CLANG_NEON(var) ((void)0) +#endif + /* ************************************* * Basic Types ***************************************/ @@ -1622,6 +2214,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) typedef XXH32_hash_t xxh_u32; #ifdef XXH_OLD_NAMES +# warning "XXH_OLD_NAMES is planned to be removed starting v0.9. If the program depends on it, consider moving away from it by employing newer type names directly" # define BYTE xxh_u8 # define U8 xxh_u8 # define U32 xxh_u32 @@ -1695,25 +2288,26 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* - * __pack instructions are safer but compiler specific, hence potentially - * problematic for some compilers. - * - * Currently only defined for GCC and ICC. + * __attribute__((aligned(1))) is supported by gcc and clang. Originally the + * documentation claimed that it only increased the alignment, but actually it + * can decrease it on gcc, clang, and icc: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69502, + * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; #endif static xxh_u32 XXH_read32(const void* ptr) { - typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign; - return ((const xxh_unalign*)ptr)->u32; + typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + return *((const xxh_unalign32*)ptr); } #else /* * Portable and safe solution. Generally efficient. - * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html + * see: https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html */ static xxh_u32 XXH_read32(const void* memPtr) { @@ -1789,6 +2383,51 @@ static int XXH_isLittleEndian(void) # define XXH_HAS_BUILTIN(x) 0 #endif + + +/* + * C23 and future versions have standard "unreachable()". + * Once it has been implemented reliably we can add it as an + * additional case: + * + * ``` + * #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= XXH_C23_VN) + * # include + * # ifdef unreachable + * # define XXH_UNREACHABLE() unreachable() + * # endif + * #endif + * ``` + * + * Note C++23 also has std::unreachable() which can be detected + * as follows: + * ``` + * #if defined(__cpp_lib_unreachable) && (__cpp_lib_unreachable >= 202202L) + * # include + * # define XXH_UNREACHABLE() std::unreachable() + * #endif + * ``` + * NB: `__cpp_lib_unreachable` is defined in the `` header. + * We don't use that as including `` in `extern "C"` blocks + * doesn't work on GCC12 + */ + +#if XXH_HAS_BUILTIN(__builtin_unreachable) +# define XXH_UNREACHABLE() __builtin_unreachable() + +#elif defined(_MSC_VER) +# define XXH_UNREACHABLE() __assume(0) + +#else +# define XXH_UNREACHABLE() +#endif + +#if XXH_HAS_BUILTIN(__builtin_assume) +# define XXH_ASSUME(c) __builtin_assume(c) +#else +# define XXH_ASSUME(c) if (!(c)) { XXH_UNREACHABLE(); } +#endif + /*! * @internal * @def XXH_rotl32(x,r) @@ -1911,8 +2550,10 @@ XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } *********************************************************************/ /*! * @} - * @defgroup xxh32_impl XXH32 implementation + * @defgroup XXH32_impl XXH32 implementation * @ingroup impl + * + * Details on the XXH32 implementation. * @{ */ /* #define instead of static const, to be used as initializers */ @@ -1946,7 +2587,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) acc += input * XXH_PRIME32_2; acc = XXH_rotl32(acc, 13); acc *= XXH_PRIME32_1; -#if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) +#if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: * A compiler fence is the only thing that prevents GCC and Clang from @@ -1976,9 +2617,12 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) * can load data, while v3 can multiply. SSE forces them to operate * together. * - * This is also enabled on AArch64, as Clang autovectorizes it incorrectly - * and it is pointless writing a NEON implementation that is basically the - * same speed as scalar for XXH32. + * This is also enabled on AArch64, as Clang is *very aggressive* in vectorizing + * the loop. NEON is only faster on the A53, and with the newer cores, it is less + * than half the speed. + * + * Additionally, this is used on WASM SIMD128 because it JITs to the same + * SIMD instructions and has the same issue. */ XXH_COMPILER_GUARD(acc); #endif @@ -1992,17 +2636,17 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) * The final mix ensures that all input bits have a chance to impact any bit in * the output digest, resulting in an unbiased distribution. * - * @param h32 The hash to avalanche. + * @param hash The hash to avalanche. * @return The avalanched hash. */ -static xxh_u32 XXH32_avalanche(xxh_u32 h32) +static xxh_u32 XXH32_avalanche(xxh_u32 hash) { - h32 ^= h32 >> 15; - h32 *= XXH_PRIME32_2; - h32 ^= h32 >> 13; - h32 *= XXH_PRIME32_3; - h32 ^= h32 >> 16; - return(h32); + hash ^= hash >> 15; + hash *= XXH_PRIME32_2; + hash ^= hash >> 13; + hash *= XXH_PRIME32_3; + hash ^= hash >> 16; + return hash; } #define XXH_get32bits(p) XXH_readLE32_align(p, align) @@ -2015,24 +2659,25 @@ static xxh_u32 XXH32_avalanche(xxh_u32 h32) * This final stage will digest them to ensure that all input bytes are present * in the final mix. * - * @param h32 The hash to finalize. + * @param hash The hash to finalize. * @param ptr The pointer to the remaining input. * @param len The remaining length, modulo 16. * @param align Whether @p ptr is aligned. * @return The finalized hash. + * @see XXH64_finalize(). */ -static xxh_u32 -XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) +static XXH_PUREF xxh_u32 +XXH32_finalize(xxh_u32 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { -#define XXH_PROCESS1 do { \ - h32 += (*ptr++) * XXH_PRIME32_5; \ - h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \ +#define XXH_PROCESS1 do { \ + hash += (*ptr++) * XXH_PRIME32_5; \ + hash = XXH_rotl32(hash, 11) * XXH_PRIME32_1; \ } while (0) -#define XXH_PROCESS4 do { \ - h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \ - ptr += 4; \ - h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \ +#define XXH_PROCESS4 do { \ + hash += XXH_get32bits(ptr) * XXH_PRIME32_3; \ + ptr += 4; \ + hash = XXH_rotl32(hash, 17) * XXH_PRIME32_4; \ } while (0) if (ptr==NULL) XXH_ASSERT(len == 0); @@ -2048,49 +2693,49 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) XXH_PROCESS1; --len; } - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); } else { switch(len&15) /* or switch(bEnd - p) */ { case 12: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 8: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 4: XXH_PROCESS4; - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); case 13: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 9: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 5: XXH_PROCESS4; XXH_PROCESS1; - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); case 14: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 10: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 6: XXH_PROCESS4; XXH_PROCESS1; XXH_PROCESS1; - return XXH32_avalanche(h32); + return XXH32_avalanche(hash); case 15: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 11: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 7: XXH_PROCESS4; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 3: XXH_PROCESS1; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 2: XXH_PROCESS1; - XXH_FALLTHROUGH; + XXH_FALLTHROUGH; /* fallthrough */ case 1: XXH_PROCESS1; - XXH_FALLTHROUGH; - case 0: return XXH32_avalanche(h32); + XXH_FALLTHROUGH; /* fallthrough */ + case 0: return XXH32_avalanche(hash); } XXH_ASSERT(0); - return h32; /* reaching this point is deemed impossible */ + return hash; /* reaching this point is deemed impossible */ } } @@ -2110,7 +2755,7 @@ XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) * @param align Whether @p input is aligned. * @return The calculated hash. */ -XXH_FORCE_INLINE xxh_u32 +XXH_FORCE_INLINE XXH_PUREF xxh_u32 XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align) { xxh_u32 h32; @@ -2143,10 +2788,10 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment return XXH32_finalize(h32, input, len&15, align); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed) { -#if 0 +#if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ XXH32_state_t state; XXH32_reset(&state, seed); @@ -2165,42 +2810,39 @@ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t s /******* Hash streaming *******/ -/*! - * @ingroup xxh32_family - */ +#ifndef XXH_NO_STREAM +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) { return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) { XXH_free(statePtr); return XXH_OK; } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) { XXH_memcpy(dstState, srcState, sizeof(*dstState)); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed) { - XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)); - state.v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - state.v[1] = seed + XXH_PRIME32_2; - state.v[2] = seed + 0; - state.v[3] = seed - XXH_PRIME32_1; - /* do not write into reserved, planned to be removed in a future version */ - XXH_memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); + XXH_ASSERT(statePtr != NULL); + memset(statePtr, 0, sizeof(*statePtr)); + statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + statePtr->v[1] = seed + XXH_PRIME32_2; + statePtr->v[2] = seed + 0; + statePtr->v[3] = seed - XXH_PRIME32_1; return XXH_OK; } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t* state, const void* input, size_t len) { @@ -2255,7 +2897,7 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len) } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) { xxh_u32 h32; @@ -2273,12 +2915,12 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); } - +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ /*! - * @ingroup xxh32_family + * @ingroup XXH32_family * The default return values from XXH functions are unsigned 32 and 64 bit * integers. * @@ -2297,7 +2939,7 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); XXH_memcpy(dst, &hash, sizeof(*dst)); } -/*! @ingroup xxh32_family */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) { return XXH_readBE32(src); @@ -2338,25 +2980,26 @@ static xxh_u64 XXH_read64(const void* memPtr) #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* - * __pack instructions are safer, but compiler specific, hence potentially - * problematic for some compilers. - * - * Currently only defined for GCC and ICC. + * __attribute__((aligned(1))) is supported by gcc and clang. Originally the + * documentation claimed that it only increased the alignment, but actually it + * can decrease it on gcc, clang, and icc: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69502, + * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; #endif static xxh_u64 XXH_read64(const void* ptr) { - typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64; - return ((const xxh_unalign64*)ptr)->u64; + typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + return *((const xxh_unalign64*)ptr); } #else /* * Portable and safe solution. Generally efficient. - * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html + * see: https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html */ static xxh_u64 XXH_read64(const void* memPtr) { @@ -2440,8 +3083,10 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align) /******* xxh64 *******/ /*! * @} - * @defgroup xxh64_impl XXH64 implementation + * @defgroup XXH64_impl XXH64 implementation * @ingroup impl + * + * Details on the XXH64 implementation. * @{ */ /* #define rather that static const, to be used as initializers */ @@ -2459,6 +3104,7 @@ XXH_readLE64_align(const void* ptr, XXH_alignment align) # define PRIME64_5 XXH_PRIME64_5 #endif +/*! @copydoc XXH32_round */ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) { acc += input * XXH_PRIME64_2; @@ -2475,43 +3121,59 @@ static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val) return acc; } -static xxh_u64 XXH64_avalanche(xxh_u64 h64) +/*! @copydoc XXH32_avalanche */ +static xxh_u64 XXH64_avalanche(xxh_u64 hash) { - h64 ^= h64 >> 33; - h64 *= XXH_PRIME64_2; - h64 ^= h64 >> 29; - h64 *= XXH_PRIME64_3; - h64 ^= h64 >> 32; - return h64; + hash ^= hash >> 33; + hash *= XXH_PRIME64_2; + hash ^= hash >> 29; + hash *= XXH_PRIME64_3; + hash ^= hash >> 32; + return hash; } #define XXH_get64bits(p) XXH_readLE64_align(p, align) -static xxh_u64 -XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) +/*! + * @internal + * @brief Processes the last 0-31 bytes of @p ptr. + * + * There may be up to 31 bytes remaining to consume from the input. + * This final stage will digest them to ensure that all input bytes are present + * in the final mix. + * + * @param hash The hash to finalize. + * @param ptr The pointer to the remaining input. + * @param len The remaining length, modulo 32. + * @param align Whether @p ptr is aligned. + * @return The finalized hash + * @see XXH32_finalize(). + */ +static XXH_PUREF xxh_u64 +XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { if (ptr==NULL) XXH_ASSERT(len == 0); len &= 31; while (len >= 8) { xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); ptr += 8; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4; + hash ^= k1; + hash = XXH_rotl64(hash,27) * XXH_PRIME64_1 + XXH_PRIME64_4; len -= 8; } if (len >= 4) { - h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; + hash ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; ptr += 4; - h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; + hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; len -= 4; } while (len > 0) { - h64 ^= (*ptr++) * XXH_PRIME64_5; - h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1; + hash ^= (*ptr++) * XXH_PRIME64_5; + hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1; --len; } - return XXH64_avalanche(h64); + return XXH64_avalanche(hash); } #ifdef XXH_OLD_NAMES @@ -2524,7 +3186,15 @@ XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) # undef XXH_PROCESS8_64 #endif -XXH_FORCE_INLINE xxh_u64 +/*! + * @internal + * @brief The implementation for @ref XXH64(). + * + * @param input , len , seed Directly passed from @ref XXH64(). + * @param align Whether @p input is aligned. + * @return The calculated hash. + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align) { xxh_u64 h64; @@ -2561,10 +3231,10 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64 (XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) { -#if 0 +#if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ XXH64_state_t state; XXH64_reset(&state, seed); @@ -2582,42 +3252,40 @@ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t s } /******* Hash Streaming *******/ - -/*! @ingroup xxh64_family*/ +#ifndef XXH_NO_STREAM +/*! @ingroup XXH64_family*/ XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) { return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); } -/*! @ingroup xxh64_family */ +/*! @ingroup XXH64_family */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) { XXH_free(statePtr); return XXH_OK; } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dstState, const XXH64_state_t* srcState) { XXH_memcpy(dstState, srcState, sizeof(*dstState)); } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed) { - XXH64_state_t state; /* use a local state to memcpy() in order to avoid strict-aliasing warnings */ - memset(&state, 0, sizeof(state)); - state.v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - state.v[1] = seed + XXH_PRIME64_2; - state.v[2] = seed + 0; - state.v[3] = seed - XXH_PRIME64_1; - /* do not write into reserved64, might be removed in a future version */ - XXH_memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64)); + XXH_ASSERT(statePtr != NULL); + memset(statePtr, 0, sizeof(*statePtr)); + statePtr->v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + statePtr->v[1] = seed + XXH_PRIME64_2; + statePtr->v[2] = seed + 0; + statePtr->v[3] = seed - XXH_PRIME64_1; return XXH_OK; } -/*! @ingroup xxh64_family */ +/*! @ingroup XXH64_family */ XXH_PUBLIC_API XXH_errorcode -XXH64_update (XXH64_state_t* state, const void* input, size_t len) +XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, size_t len) { if (input==NULL) { XXH_ASSERT(len == 0); @@ -2667,8 +3335,8 @@ XXH64_update (XXH64_state_t* state, const void* input, size_t len) } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state) { xxh_u64 h64; @@ -2686,20 +3354,20 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state) return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); } - +#endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); XXH_memcpy(dst, &hash, sizeof(*dst)); } -/*! @ingroup xxh64_family */ -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) +/*! @ingroup XXH64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src) { return XXH_readBE64(src); } @@ -2712,7 +3380,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src ************************************************************************ */ /*! * @} - * @defgroup xxh3_impl XXH3 implementation + * @defgroup XXH3_impl XXH3 implementation * @ingroup impl * @{ */ @@ -2720,11 +3388,19 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src /* === Compiler specifics === */ #if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ -# define XXH_RESTRICT /* disable */ +# define XXH_RESTRICT /* disable */ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ # define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict #else -/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */ # define XXH_RESTRICT /* disable */ #endif @@ -2738,17 +3414,33 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src # define XXH_unlikely(x) (x) #endif -#if defined(__GNUC__) -# if defined(__AVX2__) -# include -# elif defined(__SSE2__) -# include -# elif defined(__ARM_NEON__) || defined(__ARM_NEON) +#ifndef XXH_HAS_INCLUDE +# ifdef __has_include +# define XXH_HAS_INCLUDE(x) __has_include(x) +# else +# define XXH_HAS_INCLUDE(x) 0 +# endif +#endif + +#if defined(__GNUC__) || defined(__clang__) +# if defined(__ARM_FEATURE_SVE) +# include +# endif +# if defined(__ARM_NEON__) || defined(__ARM_NEON) \ + || (defined(_M_ARM) && _M_ARM >= 7) \ + || defined(_M_ARM64) || defined(_M_ARM64EC) \ + || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE()) /* WASM SIMD128 via SIMDe */ # define inline __inline__ /* circumvent a clang bug */ # include # undef inline +# elif defined(__AVX2__) +# include +# elif defined(__SSE2__) +# include # endif -#elif defined(_MSC_VER) +#endif + +#if defined(_MSC_VER) # include #endif @@ -2848,7 +3540,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src * Note that these are actually implemented as macros. * * If this is not defined, it is detected automatically. - * @ref XXH_X86DISPATCH overrides this. + * internal macro XXH_X86DISPATCH overrides this. */ enum XXH_VECTOR_TYPE /* fake enum */ { XXH_SCALAR = 0, /*!< Portable scalar version */ @@ -2860,14 +3552,19 @@ enum XXH_VECTOR_TYPE /* fake enum */ { */ XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ - XXH_NEON = 4, /*!< NEON for most ARMv7-A and all AArch64 */ + XXH_NEON = 4, /*!< + * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 + * via the SIMDeverywhere polyfill provided with the + * Emscripten SDK. + */ XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ + XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ }; /*! * @ingroup tuning * @brief Selects the minimum alignment for XXH3's accumulators. * - * When using SIMD, this should match the alignment reqired for said vector + * When using SIMD, this should match the alignment required for said vector * type, so, for example, 32 for AVX2. * * Default: Auto detected. @@ -2883,23 +3580,27 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_AVX512 3 # define XXH_NEON 4 # define XXH_VSX 5 +# define XXH_SVE 6 #endif #ifndef XXH_VECTOR /* can be defined on command line */ -# if defined(__AVX512F__) -# define XXH_VECTOR XXH_AVX512 -# elif defined(__AVX2__) -# define XXH_VECTOR XXH_AVX2 -# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) -# define XXH_VECTOR XXH_SSE2 +# if defined(__ARM_FEATURE_SVE) +# define XXH_VECTOR XXH_SVE # elif ( \ defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \ - || defined(_M_ARM64) || defined(_M_ARM_ARMV7VE) /* msvc */ \ + || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \ + || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE()) /* wasm simd128 via SIMDe */ \ ) && ( \ defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ ) # define XXH_VECTOR XXH_NEON +# elif defined(__AVX512F__) +# define XXH_VECTOR XXH_AVX512 +# elif defined(__AVX2__) +# define XXH_VECTOR XXH_AVX2 +# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) +# define XXH_VECTOR XXH_SSE2 # elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \ || (defined(__s390x__) && defined(__VEC__)) \ && defined(__GNUC__) /* TODO: IBM XL */ @@ -2909,6 +3610,17 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # endif #endif +/* __ARM_FEATURE_SVE is only supported by GCC & Clang. */ +#if (XXH_VECTOR == XXH_SVE) && !defined(__ARM_FEATURE_SVE) +# ifdef _MSC_VER +# pragma warning(once : 4606) +# else +# warning "__ARM_FEATURE_SVE isn't supported. Use SCALAR instead." +# endif +# undef XXH_VECTOR +# define XXH_VECTOR XXH_SCALAR +#endif + /* * Controls the alignment of the accumulator, * for compatibility with aligned vector loads, which are usually faster. @@ -2928,16 +3640,26 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_ACC_ALIGN 16 # elif XXH_VECTOR == XXH_AVX512 /* avx512 */ # define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_SVE /* sve */ +# define XXH_ACC_ALIGN 64 # endif #endif #if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \ || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512 # define XXH_SEC_ALIGN XXH_ACC_ALIGN +#elif XXH_VECTOR == XXH_SVE +# define XXH_SEC_ALIGN XXH_ACC_ALIGN #else # define XXH_SEC_ALIGN 8 #endif +#if defined(__GNUC__) || defined(__clang__) +# define XXH_ALIASING __attribute__((may_alias)) +#else +# define XXH_ALIASING /* nothing */ +#endif + /* * UGLY HACK: * GCC usually generates the best code with -O3 for xxHash. @@ -2961,111 +3683,130 @@ enum XXH_VECTOR_TYPE /* fake enum */ { */ #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ - && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ + && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */ # pragma GCC push_options # pragma GCC optimize("-O2") #endif - #if XXH_VECTOR == XXH_NEON + /* - * NEON's setup for vmlal_u32 is a little more complicated than it is on - * SSE2, AVX2, and VSX. - * - * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast. - * - * To do the same operation, the 128-bit 'Q' register needs to be split into - * two 64-bit 'D' registers, performing this operation:: + * UGLY HACK: While AArch64 GCC on Linux does not seem to care, on macOS, GCC -O3 + * optimizes out the entire hashLong loop because of the aliasing violation. * - * [ a | b ] - * | '---------. .--------' | - * | x | - * | .---------' '--------. | - * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ] - * - * Due to significant changes in aarch64, the fastest method for aarch64 is - * completely different than the fastest method for ARMv7-A. - * - * ARMv7-A treats D registers as unions overlaying Q registers, so modifying - * D11 will modify the high half of Q5. This is similar to how modifying AH - * will only affect bits 8-15 of AX on x86. - * - * VZIP takes two registers, and puts even lanes in one register and odd lanes - * in the other. + * However, GCC is also inefficient at load-store optimization with vld1q/vst1q, + * so the only option is to mark it as aliasing. + */ +typedef uint64x2_t xxh_aliasing_uint64x2_t XXH_ALIASING; + +/*! + * @internal + * @brief `vld1q_u64` but faster and alignment-safe. * - * On ARMv7-A, this strangely modifies both parameters in place instead of - * taking the usual 3-operand form. + * On AArch64, unaligned access is always safe, but on ARMv7-a, it is only + * *conditionally* safe (`vld1` has an alignment bit like `movdq[ua]` in x86). * - * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the - * lower and upper halves of the Q register to end up with the high and low - * halves where we want - all in one instruction. + * GCC for AArch64 sees `vld1q_u8` as an intrinsic instead of a load, so it + * prohibits load-store optimizations. Therefore, a direct dereference is used. * - * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] } + * Otherwise, `vld1q_u8` is used with `vreinterpretq_u8_u64` to do a safe + * unaligned load. + */ +#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__) +XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr) /* silence -Wcast-align */ +{ + return *(xxh_aliasing_uint64x2_t const *)ptr; +} +#else +XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr) +{ + return vreinterpretq_u64_u8(vld1q_u8((uint8_t const*)ptr)); +} +#endif + +/*! + * @internal + * @brief `vmlal_u32` on low and high halves of a vector. * - * Unfortunately we need inline assembly for this: Instructions modifying two - * registers at once is not possible in GCC or Clang's IR, and they have to - * create a copy. + * This is a workaround for AArch64 GCC < 11 which implemented arm_neon.h with + * inline assembly and were therefore incapable of merging the `vget_{low, high}_u32` + * with `vmlal_u32`. + */ +#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 11 +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + /* Inline assembly is the only way */ + __asm__("umlal %0.2d, %1.2s, %2.2s" : "+w" (acc) : "w" (lhs), "w" (rhs)); + return acc; +} +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + /* This intrinsic works as expected */ + return vmlal_high_u32(acc, lhs, rhs); +} +#else +/* Portable intrinsic versions */ +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + return vmlal_u32(acc, vget_low_u32(lhs), vget_low_u32(rhs)); +} +/*! @copydoc XXH_vmlal_low_u32 + * Assume the compiler converts this to vmlal_high_u32 on aarch64 */ +XXH_FORCE_INLINE uint64x2_t +XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs) +{ + return vmlal_u32(acc, vget_high_u32(lhs), vget_high_u32(rhs)); +} +#endif + +/*! + * @ingroup tuning + * @brief Controls the NEON to scalar ratio for XXH3 * - * aarch64 requires a different approach. + * This can be set to 2, 4, 6, or 8. * - * In order to make it easier to write a decent compiler for aarch64, many - * quirks were removed, such as conditional execution. + * ARM Cortex CPUs are _very_ sensitive to how their pipelines are used. * - * NEON was also affected by this. + * For example, the Cortex-A73 can dispatch 3 micro-ops per cycle, but only 2 of those + * can be NEON. If you are only using NEON instructions, you are only using 2/3 of the CPU + * bandwidth. * - * aarch64 cannot access the high bits of a Q-form register, and writes to a - * D-form register zero the high bits, similar to how writes to W-form scalar - * registers (or DWORD registers on x86_64) work. + * This is even more noticeable on the more advanced cores like the Cortex-A76 which + * can dispatch 8 micro-ops per cycle, but still only 2 NEON micro-ops at once. * - * The formerly free vget_high intrinsics now require a vext (with a few - * exceptions) + * Therefore, to make the most out of the pipeline, it is beneficial to run 6 NEON lanes + * and 2 scalar lanes, which is chosen by default. * - * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent - * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one - * operand. + * This does not apply to Apple processors or 32-bit processors, which run better with + * full NEON. These will default to 8. Additionally, size-optimized builds run 8 lanes. * - * The equivalent of the VZIP.32 on the lower and upper halves would be this - * mess: + * This change benefits CPUs with large micro-op buffers without negatively affecting + * most other CPUs: * - * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] } - * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] } - * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] } + * | Chipset | Dispatch type | NEON only | 6:2 hybrid | Diff. | + * |:----------------------|:--------------------|----------:|-----------:|------:| + * | Snapdragon 730 (A76) | 2 NEON/8 micro-ops | 8.8 GB/s | 10.1 GB/s | ~16% | + * | Snapdragon 835 (A73) | 2 NEON/3 micro-ops | 5.1 GB/s | 5.3 GB/s | ~5% | + * | Marvell PXA1928 (A53) | In-order dual-issue | 1.9 GB/s | 1.9 GB/s | 0% | + * | Apple M1 | 4 NEON/8 micro-ops | 37.3 GB/s | 36.1 GB/s | ~-3% | * - * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN): + * It also seems to fix some bad codegen on GCC, making it almost as fast as clang. * - * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32); - * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF); + * When using WASM SIMD128, if this is 2 or 6, SIMDe will scalarize 2 of the lanes meaning + * it effectively becomes worse 4. * - * This is available on ARMv7-A, but is less efficient than a single VZIP.32. + * @see XXH3_accumulate_512_neon() */ - -/*! - * Function-like macro: - * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi) - * { - * outLo = (uint32x2_t)(in & 0xFFFFFFFF); - * outHi = (uint32x2_t)(in >> 32); - * in = UNDEFINED; - * } - */ -# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \ - && defined(__GNUC__) \ - && !defined(__aarch64__) && !defined(__arm64__) && !defined(_M_ARM64) -# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ - do { \ - /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \ - /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \ - /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \ - __asm__("vzip.32 %e0, %f0" : "+w" (in)); \ - (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \ - (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \ - } while (0) -# else -# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ - do { \ - (outLo) = vmovn_u64 (in); \ - (outHi) = vshrn_n_u64 ((in), 32); \ - } while (0) +# ifndef XXH3_NEON_LANES +# if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \ + && !defined(__APPLE__) && XXH_SIZE_OPT <= 0 +# define XXH3_NEON_LANES 6 +# else +# define XXH3_NEON_LANES XXH_ACC_NB +# endif # endif #endif /* XXH_VECTOR == XXH_NEON */ @@ -3078,27 +3819,42 @@ enum XXH_VECTOR_TYPE /* fake enum */ { * inconsistent intrinsics, spotty coverage, and multiple endiannesses. */ #if XXH_VECTOR == XXH_VSX +/* Annoyingly, these headers _may_ define three macros: `bool`, `vector`, + * and `pixel`. This is a problem for obvious reasons. + * + * These keywords are unnecessary; the spec literally says they are + * equivalent to `__bool`, `__vector`, and `__pixel` and may be undef'd + * after including the header. + * + * We use pragma push_macro/pop_macro to keep the namespace clean. */ +# pragma push_macro("bool") +# pragma push_macro("vector") +# pragma push_macro("pixel") +/* silence potential macro redefined warnings */ +# undef bool +# undef vector +# undef pixel + # if defined(__s390x__) # include # else -/* gcc's altivec.h can have the unwanted consequence to unconditionally - * #define bool, vector, and pixel keywords, - * with bad consequences for programs already using these keywords for other purposes. - * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined. - * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler, - * but it seems that, in some cases, it isn't. - * Force the build macro to be defined, so that keywords are not altered. - */ -# if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__) -# define __APPLE_ALTIVEC__ -# endif # include # endif +/* Restore the original macro values, if applicable. */ +# pragma pop_macro("pixel") +# pragma pop_macro("vector") +# pragma pop_macro("bool") + typedef __vector unsigned long long xxh_u64x2; typedef __vector unsigned char xxh_u8x16; typedef __vector unsigned xxh_u32x4; +/* + * UGLY HACK: Similar to aarch64 macOS GCC, s390x GCC has the same aliasing issue. + */ +typedef xxh_u64x2 xxh_aliasing_u64x2 XXH_ALIASING; + # ifndef XXH_VSX_BE # if defined(__BIG_ENDIAN__) \ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) @@ -3150,8 +3906,9 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr) /* s390x is always big endian, no issue on this platform */ # define XXH_vec_mulo vec_mulo # define XXH_vec_mule vec_mule -# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) +# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) && !defined(__ibmxl__) /* Clang has a better way to control this, we can just use the builtin which doesn't swap. */ + /* The IBM XL Compiler (which defined __clang__) only implements the vec_* operations */ # define XXH_vec_mulo __builtin_altivec_vmulouw # define XXH_vec_mule __builtin_altivec_vmuleuw # else @@ -3172,13 +3929,28 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) # endif /* XXH_vec_mulo, XXH_vec_mule */ #endif /* XXH_VECTOR == XXH_VSX */ +#if XXH_VECTOR == XXH_SVE +#define ACCRND(acc, offset) \ +do { \ + svuint64_t input_vec = svld1_u64(mask, xinput + offset); \ + svuint64_t secret_vec = svld1_u64(mask, xsecret + offset); \ + svuint64_t mixed = sveor_u64_x(mask, secret_vec, input_vec); \ + svuint64_t swapped = svtbl_u64(input_vec, kSwap); \ + svuint64_t mixed_lo = svextw_u64_x(mask, mixed); \ + svuint64_t mixed_hi = svlsr_n_u64_x(mask, mixed, 32); \ + svuint64_t mul = svmad_u64_x(mask, mixed_lo, mixed_hi, swapped); \ + acc = svadd_u64_x(mask, acc, mul); \ +} while (0) +#endif /* XXH_VECTOR == XXH_SVE */ /* prefetch * can be disabled, by declaring XXH_NO_PREFETCH build macro */ #if defined(XXH_NO_PREFETCH) # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ #else -# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */ +# if XXH_SIZE_OPT >= 1 +# define XXH_PREFETCH(ptr) (void)(ptr) +# elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */ # include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ # define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) @@ -3215,6 +3987,8 @@ XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = { 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, }; +static const xxh_u64 PRIME_MX1 = 0x165667919E3779F9ULL; /*!< 0b0001011001010110011001111001000110011110001101110111100111111001 */ +static const xxh_u64 PRIME_MX2 = 0x9FB21C651E98DF25ULL; /*!< 0b1001111110110010000111000110010100011110100110001101111100100101 */ #ifdef XXH_OLD_NAMES # define kSecret XXH3_kSecret @@ -3243,7 +4017,6 @@ XXH_mult32to64(xxh_u64 x, xxh_u64 y) return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF); } #elif defined(_MSC_VER) && defined(_M_IX86) -# include # define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y)) #else /* @@ -3283,7 +4056,7 @@ XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) * In that case it is best to use the portable one. * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677 */ -#if defined(__GNUC__) && !defined(__wasm__) \ +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__wasm__) \ && defined(__SIZEOF_INT128__) \ || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) @@ -3300,7 +4073,7 @@ XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) * * This compiles to single operand MUL on x64. */ -#elif defined(_M_X64) || defined(_M_IA64) +#elif (defined(_M_X64) || defined(_M_IA64)) && !defined(_M_ARM64EC) #ifndef _MSC_VER # pragma intrinsic(_umul128) @@ -3317,7 +4090,7 @@ XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) * * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method. */ -#elif defined(_M_ARM64) +#elif defined(_M_ARM64) || defined(_M_ARM64EC) #ifndef _MSC_VER # pragma intrinsic(__umulh) @@ -3407,7 +4180,7 @@ XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs) } /*! Seems to produce slightly better code on GCC for some reason. */ -XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) +XXH_FORCE_INLINE XXH_CONSTF xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) { XXH_ASSERT(0 <= shift && shift < 64); return v64 ^ (v64 >> shift); @@ -3420,7 +4193,7 @@ XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) static XXH64_hash_t XXH3_avalanche(xxh_u64 h64) { h64 = XXH_xorshift64(h64, 37); - h64 *= 0x165667919E3779F9ULL; + h64 *= PRIME_MX1; h64 = XXH_xorshift64(h64, 32); return h64; } @@ -3434,9 +4207,9 @@ static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) { /* this mix is inspired by Pelle Evensen's rrmxmx */ h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24); - h64 *= 0x9FB21C651E98DF25ULL; + h64 *= PRIME_MX2; h64 ^= (h64 >> 35) + len ; - h64 *= 0x9FB21C651E98DF25ULL; + h64 *= PRIME_MX2; return XXH_xorshift64(h64, 28); } @@ -3474,7 +4247,7 @@ static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) * * This adds an extra layer of strength for custom secrets. */ -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -3496,7 +4269,7 @@ XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h } } -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -3512,7 +4285,7 @@ XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_h } } -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -3529,7 +4302,7 @@ XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_ } } -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(len <= 16); @@ -3599,7 +4372,7 @@ XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input, } /* For mid range keys, XXH3 uses a Mum-hash variant. */ -XXH_FORCE_INLINE XXH64_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH64_hash_t XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -3608,6 +4381,14 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, XXH_ASSERT(16 < len && len <= 128); { xxh_u64 acc = len * XXH_PRIME64_1; +#if XXH_SIZE_OPT >= 1 + /* Smaller and cleaner, but slightly slower. */ + unsigned int i = (unsigned int)(len - 1) / 32; + do { + acc += XXH3_mix16B(input+16 * i, secret+32*i, seed); + acc += XXH3_mix16B(input+len-16*(i+1), secret+32*i+16, seed); + } while (i-- != 0); +#else if (len > 32) { if (len > 64) { if (len > 96) { @@ -3622,14 +4403,14 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, } acc += XXH3_mix16B(input+0, secret+0, seed); acc += XXH3_mix16B(input+len-16, secret+16, seed); - +#endif return XXH3_avalanche(acc); } } #define XXH3_MIDSIZE_MAX 240 -XXH_NO_INLINE XXH64_hash_t +XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -3641,13 +4422,17 @@ XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, #define XXH3_MIDSIZE_LASTOFFSET 17 { xxh_u64 acc = len * XXH_PRIME64_1; - int const nbRounds = (int)len / 16; - int i; + xxh_u64 acc_end; + unsigned int const nbRounds = (unsigned int)len / 16; + unsigned int i; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); for (i=0; i<8; i++) { acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed); } - acc = XXH3_avalanche(acc); + /* last bytes */ + acc_end = XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); XXH_ASSERT(nbRounds >= 8); + acc = XXH3_avalanche(acc); #if defined(__clang__) /* Clang */ \ && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ @@ -3674,11 +4459,13 @@ XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, #pragma clang loop vectorize(disable) #endif for (i=8 ; i < nbRounds; i++) { - acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); + /* + * Prevents clang for unrolling the acc loop and interleaving with this one. + */ + XXH_COMPILER_GUARD(acc); + acc_end += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); } - /* last bytes */ - acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); - return XXH3_avalanche(acc); + return XXH3_avalanche(acc + acc_end); } } @@ -3694,6 +4481,47 @@ XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, # define ACC_NB XXH_ACC_NB #endif +#ifndef XXH_PREFETCH_DIST +# ifdef __clang__ +# define XXH_PREFETCH_DIST 320 +# else +# if (XXH_VECTOR == XXH_AVX512) +# define XXH_PREFETCH_DIST 512 +# else +# define XXH_PREFETCH_DIST 384 +# endif +# endif /* __clang__ */ +#endif /* XXH_PREFETCH_DIST */ + +/* + * These macros are to generate an XXH3_accumulate() function. + * The two arguments select the name suffix and target attribute. + * + * The name of this symbol is XXH3_accumulate_() and it calls + * XXH3_accumulate_512_(). + * + * It may be useful to hand implement this function if the compiler fails to + * optimize the inline function. + */ +#define XXH3_ACCUMULATE_TEMPLATE(name) \ +void \ +XXH3_accumulate_##name(xxh_u64* XXH_RESTRICT acc, \ + const xxh_u8* XXH_RESTRICT input, \ + const xxh_u8* XXH_RESTRICT secret, \ + size_t nbStripes) \ +{ \ + size_t n; \ + for (n = 0; n < nbStripes; n++ ) { \ + const xxh_u8* const in = input + n*XXH_STRIPE_LEN; \ + XXH_PREFETCH(in + XXH_PREFETCH_DIST); \ + XXH3_accumulate_512_##name( \ + acc, \ + in, \ + secret + n*XXH_SECRET_CONSUME_RATE); \ + } \ +} + + XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) { if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); @@ -3714,6 +4542,7 @@ XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) typedef long long xxh_i64; #endif + /* * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized. * @@ -3761,7 +4590,7 @@ XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, /* data_key = data_vec ^ key_vec; */ __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); /* data_key_lo = data_key >> 32; */ - __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + __m512i const data_key_lo = _mm512_srli_epi64 (data_key, 32); /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo); /* xacc[0] += swap(data_vec); */ @@ -3771,6 +4600,7 @@ XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, *xacc = _mm512_add_epi64(product, sum); } } +XXH_FORCE_INLINE XXH_TARGET_AVX512 XXH3_ACCUMULATE_TEMPLATE(avx512) /* * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing. @@ -3804,13 +4634,12 @@ XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) /* xacc[0] ^= (xacc[0] >> 47) */ __m512i const acc_vec = *xacc; __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47); - __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted); /* xacc[0] ^= secret; */ __m512i const key_vec = _mm512_loadu_si512 (secret); - __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + __m512i const data_key = _mm512_ternarylogic_epi32(key_vec, acc_vec, shifted, 0x96 /* key_vec ^ acc_vec ^ shifted */); /* xacc[0] *= XXH_PRIME32_1; */ - __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + __m512i const data_key_hi = _mm512_srli_epi64 (data_key, 32); __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32); __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32); *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32)); @@ -3825,7 +4654,8 @@ XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) XXH_ASSERT(((size_t)customSecret & 63) == 0); (void)(&XXH_writeLE64); { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i); - __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64)); + __m512i const seed_pos = _mm512_set1_epi64((xxh_i64)seed64); + __m512i const seed = _mm512_mask_sub_epi64(seed_pos, 0xAA, _mm512_set1_epi8(0), seed_pos); const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret); __m512i* const dest = ( __m512i*) customSecret; @@ -3833,14 +4663,7 @@ XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */ XXH_ASSERT(((size_t)dest & 63) == 0); for (i=0; i < nbRounds; ++i) { - /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*', - * this will warn "discards 'const' qualifier". */ - union { - const __m512i* cp; - void* p; - } remote_const_void; - remote_const_void.cp = src + i; - dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed); + dest[i] = _mm512_add_epi64(_mm512_load_si512(src + i), seed); } } } @@ -3876,7 +4699,7 @@ XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, /* data_key = data_vec ^ key_vec; */ __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); /* data_key_lo = data_key >> 32; */ - __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m256i const data_key_lo = _mm256_srli_epi64 (data_key, 32); /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo); /* xacc[i] += swap(data_vec); */ @@ -3886,6 +4709,7 @@ XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, xacc[i] = _mm256_add_epi64(product, sum); } } } +XXH_FORCE_INLINE XXH_TARGET_AVX2 XXH3_ACCUMULATE_TEMPLATE(avx2) XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) @@ -3908,7 +4732,7 @@ XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); /* xacc[i] *= XXH_PRIME32_1; */ - __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m256i const data_key_hi = _mm256_srli_epi64 (data_key, 32); __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32); __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32); xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32)); @@ -3940,12 +4764,12 @@ XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTR XXH_ASSERT(((size_t)dest & 31) == 0); /* GCC -O2 need unroll loop manually */ - dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed); - dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed); - dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed); - dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed); - dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed); - dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed); + dest[0] = _mm256_add_epi64(_mm256_load_si256(src+0), seed); + dest[1] = _mm256_add_epi64(_mm256_load_si256(src+1), seed); + dest[2] = _mm256_add_epi64(_mm256_load_si256(src+2), seed); + dest[3] = _mm256_add_epi64(_mm256_load_si256(src+3), seed); + dest[4] = _mm256_add_epi64(_mm256_load_si256(src+4), seed); + dest[5] = _mm256_add_epi64(_mm256_load_si256(src+5), seed); } } @@ -3992,6 +4816,7 @@ XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc, xacc[i] = _mm_add_epi64(product, sum); } } } +XXH_FORCE_INLINE XXH_TARGET_SSE2 XXH3_ACCUMULATE_TEMPLATE(sse2) XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) @@ -4059,96 +4884,222 @@ XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTR #if (XXH_VECTOR == XXH_NEON) +/* forward declarations for the scalar routines */ +XXH_FORCE_INLINE void +XXH3_scalarRound(void* XXH_RESTRICT acc, void const* XXH_RESTRICT input, + void const* XXH_RESTRICT secret, size_t lane); + +XXH_FORCE_INLINE void +XXH3_scalarScrambleRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT secret, size_t lane); + +/*! + * @internal + * @brief The bulk processing loop for NEON and WASM SIMD128. + * + * The NEON code path is actually partially scalar when running on AArch64. This + * is to optimize the pipelining and can have up to 15% speedup depending on the + * CPU, and it also mitigates some GCC codegen issues. + * + * @see XXH3_NEON_LANES for configuring this and details about this optimization. + * + * NEON's 32-bit to 64-bit long multiply takes a half vector of 32-bit + * integers instead of the other platforms which mask full 64-bit vectors, + * so the setup is more complicated than just shifting right. + * + * Additionally, there is an optimization for 4 lanes at once noted below. + * + * Since, as stated, the most optimal amount of lanes for Cortexes is 6, + * there needs to be *three* versions of the accumulate operation used + * for the remaining 2 lanes. + * + * WASM's SIMD128 uses SIMDe's arm_neon.h polyfill because the intrinsics overlap + * nearly perfectly. + */ + XXH_FORCE_INLINE void XXH3_accumulate_512_neon( void* XXH_RESTRICT acc, const void* XXH_RESTRICT input, const void* XXH_RESTRICT secret) { XXH_ASSERT((((size_t)acc) & 15) == 0); - { - uint64x2_t* const xacc = (uint64x2_t *) acc; + XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0); + { /* GCC for darwin arm64 does not like aliasing here */ + xxh_aliasing_uint64x2_t* const xacc = (xxh_aliasing_uint64x2_t*) acc; /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ - uint8_t const* const xinput = (const uint8_t *) input; - uint8_t const* const xsecret = (const uint8_t *) secret; + uint8_t const* xinput = (const uint8_t *) input; + uint8_t const* xsecret = (const uint8_t *) secret; size_t i; - for (i=0; i < XXH_STRIPE_LEN / sizeof(uint64x2_t); i++) { +#ifdef __wasm_simd128__ + /* + * On WASM SIMD128, Clang emits direct address loads when XXH3_kSecret + * is constant propagated, which results in it converting it to this + * inside the loop: + * + * a = v128.load(XXH3_kSecret + 0 + $secret_offset, offset = 0) + * b = v128.load(XXH3_kSecret + 16 + $secret_offset, offset = 0) + * ... + * + * This requires a full 32-bit address immediate (and therefore a 6 byte + * instruction) as well as an add for each offset. + * + * Putting an asm guard prevents it from folding (at the cost of losing + * the alignment hint), and uses the free offset in `v128.load` instead + * of adding secret_offset each time which overall reduces code size by + * about a kilobyte and improves performance. + */ + XXH_COMPILER_GUARD(xsecret); +#endif + /* Scalar lanes use the normal scalarRound routine */ + for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { + XXH3_scalarRound(acc, input, secret, i); + } + i = 0; + /* 4 NEON lanes at a time. */ + for (; i+1 < XXH3_NEON_LANES / 2; i+=2) { /* data_vec = xinput[i]; */ - uint8x16_t data_vec = vld1q_u8(xinput + (i * 16)); + uint64x2_t data_vec_1 = XXH_vld1q_u64(xinput + (i * 16)); + uint64x2_t data_vec_2 = XXH_vld1q_u64(xinput + ((i+1) * 16)); /* key_vec = xsecret[i]; */ - uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); - uint64x2_t data_key; - uint32x2_t data_key_lo, data_key_hi; - /* xacc[i] += swap(data_vec); */ - uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec); - uint64x2_t const swapped = vextq_u64(data64, data64, 1); - xacc[i] = vaddq_u64 (xacc[i], swapped); + uint64x2_t key_vec_1 = XXH_vld1q_u64(xsecret + (i * 16)); + uint64x2_t key_vec_2 = XXH_vld1q_u64(xsecret + ((i+1) * 16)); + /* data_swap = swap(data_vec) */ + uint64x2_t data_swap_1 = vextq_u64(data_vec_1, data_vec_1, 1); + uint64x2_t data_swap_2 = vextq_u64(data_vec_2, data_vec_2, 1); /* data_key = data_vec ^ key_vec; */ - data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec)); - /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF); - * data_key_hi = (uint32x2_t) (data_key >> 32); - * data_key = UNDEFINED; */ - XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); - /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */ - xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi); + uint64x2_t data_key_1 = veorq_u64(data_vec_1, key_vec_1); + uint64x2_t data_key_2 = veorq_u64(data_vec_2, key_vec_2); + /* + * If we reinterpret the 64x2 vectors as 32x4 vectors, we can use a + * de-interleave operation for 4 lanes in 1 step with `vuzpq_u32` to + * get one vector with the low 32 bits of each lane, and one vector + * with the high 32 bits of each lane. + * + * The intrinsic returns a double vector because the original ARMv7-a + * instruction modified both arguments in place. AArch64 and SIMD128 emit + * two instructions from this intrinsic. + * + * [ dk11L | dk11H | dk12L | dk12H ] -> [ dk11L | dk12L | dk21L | dk22L ] + * [ dk21L | dk21H | dk22L | dk22H ] -> [ dk11H | dk12H | dk21H | dk22H ] + */ + uint32x4x2_t unzipped = vuzpq_u32( + vreinterpretq_u32_u64(data_key_1), + vreinterpretq_u32_u64(data_key_2) + ); + /* data_key_lo = data_key & 0xFFFFFFFF */ + uint32x4_t data_key_lo = unzipped.val[0]; + /* data_key_hi = data_key >> 32 */ + uint32x4_t data_key_hi = unzipped.val[1]; + /* + * Then, we can split the vectors horizontally and multiply which, as for most + * widening intrinsics, have a variant that works on both high half vectors + * for free on AArch64. A similar instruction is available on SIMD128. + * + * sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi + */ + uint64x2_t sum_1 = XXH_vmlal_low_u32(data_swap_1, data_key_lo, data_key_hi); + uint64x2_t sum_2 = XXH_vmlal_high_u32(data_swap_2, data_key_lo, data_key_hi); + /* + * Clang reorders + * a += b * c; // umlal swap.2d, dkl.2s, dkh.2s + * c += a; // add acc.2d, acc.2d, swap.2d + * to + * c += a; // add acc.2d, acc.2d, swap.2d + * c += b * c; // umlal acc.2d, dkl.2s, dkh.2s + * + * While it would make sense in theory since the addition is faster, + * for reasons likely related to umlal being limited to certain NEON + * pipelines, this is worse. A compiler guard fixes this. + */ + XXH_COMPILER_GUARD_CLANG_NEON(sum_1); + XXH_COMPILER_GUARD_CLANG_NEON(sum_2); + /* xacc[i] = acc_vec + sum; */ + xacc[i] = vaddq_u64(xacc[i], sum_1); + xacc[i+1] = vaddq_u64(xacc[i+1], sum_2); + } + /* Operate on the remaining NEON lanes 2 at a time. */ + for (; i < XXH3_NEON_LANES / 2; i++) { + /* data_vec = xinput[i]; */ + uint64x2_t data_vec = XXH_vld1q_u64(xinput + (i * 16)); + /* key_vec = xsecret[i]; */ + uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16)); + /* acc_vec_2 = swap(data_vec) */ + uint64x2_t data_swap = vextq_u64(data_vec, data_vec, 1); + /* data_key = data_vec ^ key_vec; */ + uint64x2_t data_key = veorq_u64(data_vec, key_vec); + /* For two lanes, just use VMOVN and VSHRN. */ + /* data_key_lo = data_key & 0xFFFFFFFF; */ + uint32x2_t data_key_lo = vmovn_u64(data_key); + /* data_key_hi = data_key >> 32; */ + uint32x2_t data_key_hi = vshrn_n_u64(data_key, 32); + /* sum = data_swap + (u64x2) data_key_lo * (u64x2) data_key_hi; */ + uint64x2_t sum = vmlal_u32(data_swap, data_key_lo, data_key_hi); + /* Same Clang workaround as before */ + XXH_COMPILER_GUARD_CLANG_NEON(sum); + /* xacc[i] = acc_vec + sum; */ + xacc[i] = vaddq_u64 (xacc[i], sum); } } } +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(neon) XXH_FORCE_INLINE void XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) { XXH_ASSERT((((size_t)acc) & 15) == 0); - { uint64x2_t* xacc = (uint64x2_t*) acc; + { xxh_aliasing_uint64x2_t* xacc = (xxh_aliasing_uint64x2_t*) acc; uint8_t const* xsecret = (uint8_t const*) secret; - uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1); size_t i; - for (i=0; i < XXH_STRIPE_LEN/sizeof(uint64x2_t); i++) { + /* WASM uses operator overloads and doesn't need these. */ +#ifndef __wasm_simd128__ + /* { prime32_1, prime32_1 } */ + uint32x2_t const kPrimeLo = vdup_n_u32(XXH_PRIME32_1); + /* { 0, prime32_1, 0, prime32_1 } */ + uint32x4_t const kPrimeHi = vreinterpretq_u32_u64(vdupq_n_u64((xxh_u64)XXH_PRIME32_1 << 32)); +#endif + + /* AArch64 uses both scalar and neon at the same time */ + for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { + XXH3_scalarScrambleRound(acc, secret, i); + } + for (i=0; i < XXH3_NEON_LANES / 2; i++) { /* xacc[i] ^= (xacc[i] >> 47); */ uint64x2_t acc_vec = xacc[i]; - uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47); - uint64x2_t data_vec = veorq_u64 (acc_vec, shifted); + uint64x2_t shifted = vshrq_n_u64(acc_vec, 47); + uint64x2_t data_vec = veorq_u64(acc_vec, shifted); /* xacc[i] ^= xsecret[i]; */ - uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16)); - uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec)); - + uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16)); + uint64x2_t data_key = veorq_u64(data_vec, key_vec); /* xacc[i] *= XXH_PRIME32_1 */ - uint32x2_t data_key_lo, data_key_hi; - /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF); - * data_key_hi = (uint32x2_t) (xacc[i] >> 32); - * xacc[i] = UNDEFINED; */ - XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); - { /* - * prod_hi = (data_key >> 32) * XXH_PRIME32_1; - * - * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will - * incorrectly "optimize" this: - * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b)); - * shifted = vshll_n_u32(tmp, 32); - * to this: - * tmp = "vmulq_u64"(a, b); // no such thing! - * shifted = vshlq_n_u64(tmp, 32); - * - * However, unlike SSE, Clang lacks a 64-bit multiply routine - * for NEON, and it scalarizes two 64-bit multiplies instead. - * - * vmull_u32 has the same timing as vmul_u32, and it avoids - * this bug completely. - * See https://bugs.llvm.org/show_bug.cgi?id=39967 - */ - uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime); - /* xacc[i] = prod_hi << 32; */ - xacc[i] = vshlq_n_u64(prod_hi, 32); - /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */ - xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime); - } - } } +#ifdef __wasm_simd128__ + /* SIMD128 has multiply by u64x2, use it instead of expanding and scalarizing */ + xacc[i] = data_key * XXH_PRIME32_1; +#else + /* + * Expanded version with portable NEON intrinsics + * + * lo(x) * lo(y) + (hi(x) * lo(y) << 32) + * + * prod_hi = hi(data_key) * lo(prime) << 32 + * + * Since we only need 32 bits of this multiply a trick can be used, reinterpreting the vector + * as a uint32x4_t and multiplying by { 0, prime, 0, prime } to cancel out the unwanted bits + * and avoid the shift. + */ + uint32x4_t prod_hi = vmulq_u32 (vreinterpretq_u32_u64(data_key), kPrimeHi); + /* Extract low bits for vmlal_u32 */ + uint32x2_t data_key_lo = vmovn_u64(data_key); + /* xacc[i] = prod_hi + lo(data_key) * XXH_PRIME32_1; */ + xacc[i] = vmlal_u32(vreinterpretq_u64_u32(prod_hi), data_key_lo, kPrimeLo); +#endif + } + } } - #endif #if (XXH_VECTOR == XXH_VSX) @@ -4159,23 +5110,23 @@ XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) { /* presumed aligned */ - unsigned int* const xacc = (unsigned int*) acc; - xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */ - xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */ + xxh_aliasing_u64x2* const xacc = (xxh_aliasing_u64x2*) acc; + xxh_u8 const* const xinput = (xxh_u8 const*) input; /* no alignment restriction */ + xxh_u8 const* const xsecret = (xxh_u8 const*) secret; /* no alignment restriction */ xxh_u64x2 const v32 = { 32, 32 }; size_t i; for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { /* data_vec = xinput[i]; */ - xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i); + xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + 16*i); /* key_vec = xsecret[i]; */ - xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + 16*i); xxh_u64x2 const data_key = data_vec ^ key_vec; /* shuffled = (data_key << 32) | (data_key >> 32); */ xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32); /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */ xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled); /* acc_vec = xacc[i]; */ - xxh_u64x2 acc_vec = (xxh_u64x2)vec_xl(0, xacc + 4 * i); + xxh_u64x2 acc_vec = xacc[i]; acc_vec += product; /* swap high and low halves */ @@ -4184,18 +5135,18 @@ XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, #else acc_vec += vec_xxpermdi(data_vec, data_vec, 2); #endif - /* xacc[i] = acc_vec; */ - vec_xst((xxh_u32x4)acc_vec, 0, xacc + 4 * i); + xacc[i] = acc_vec; } } +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(vsx) XXH_FORCE_INLINE void XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) { XXH_ASSERT((((size_t)acc) & 15) == 0); - { xxh_u64x2* const xacc = (xxh_u64x2*) acc; - const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret; + { xxh_aliasing_u64x2* const xacc = (xxh_aliasing_u64x2*) acc; + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* constants */ xxh_u64x2 const v32 = { 32, 32 }; xxh_u64x2 const v47 = { 47, 47 }; @@ -4207,7 +5158,7 @@ XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47); /* xacc[i] ^= xsecret[i]; */ - xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + 16*i); xxh_u64x2 const data_key = data_vec ^ key_vec; /* xacc[i] *= XXH_PRIME32_1 */ @@ -4221,40 +5172,233 @@ XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) #endif +#if (XXH_VECTOR == XXH_SVE) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_sve( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + uint64_t *xacc = (uint64_t *)acc; + const uint64_t *xinput = (const uint64_t *)(const void *)input; + const uint64_t *xsecret = (const uint64_t *)(const void *)secret; + svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1); + uint64_t element_count = svcntd(); + if (element_count >= 8) { + svbool_t mask = svptrue_pat_b64(SV_VL8); + svuint64_t vacc = svld1_u64(mask, xacc); + ACCRND(vacc, 0); + svst1_u64(mask, xacc, vacc); + } else if (element_count == 2) { /* sve128 */ + svbool_t mask = svptrue_pat_b64(SV_VL2); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 2); + svuint64_t acc2 = svld1_u64(mask, xacc + 4); + svuint64_t acc3 = svld1_u64(mask, xacc + 6); + ACCRND(acc0, 0); + ACCRND(acc1, 2); + ACCRND(acc2, 4); + ACCRND(acc3, 6); + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 2, acc1); + svst1_u64(mask, xacc + 4, acc2); + svst1_u64(mask, xacc + 6, acc3); + } else { + svbool_t mask = svptrue_pat_b64(SV_VL4); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 4); + ACCRND(acc0, 0); + ACCRND(acc1, 4); + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 4, acc1); + } +} + +XXH_FORCE_INLINE void +XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, + size_t nbStripes) +{ + if (nbStripes != 0) { + uint64_t *xacc = (uint64_t *)acc; + const uint64_t *xinput = (const uint64_t *)(const void *)input; + const uint64_t *xsecret = (const uint64_t *)(const void *)secret; + svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1); + uint64_t element_count = svcntd(); + if (element_count >= 8) { + svbool_t mask = svptrue_pat_b64(SV_VL8); + svuint64_t vacc = svld1_u64(mask, xacc + 0); + do { + /* svprfd(svbool_t, void *, enum svfprop); */ + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(vacc, 0); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, vacc); + } else if (element_count == 2) { /* sve128 */ + svbool_t mask = svptrue_pat_b64(SV_VL2); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 2); + svuint64_t acc2 = svld1_u64(mask, xacc + 4); + svuint64_t acc3 = svld1_u64(mask, xacc + 6); + do { + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(acc0, 0); + ACCRND(acc1, 2); + ACCRND(acc2, 4); + ACCRND(acc3, 6); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 2, acc1); + svst1_u64(mask, xacc + 4, acc2); + svst1_u64(mask, xacc + 6, acc3); + } else { + svbool_t mask = svptrue_pat_b64(SV_VL4); + svuint64_t acc0 = svld1_u64(mask, xacc + 0); + svuint64_t acc1 = svld1_u64(mask, xacc + 4); + do { + svprfd(mask, xinput + 128, SV_PLDL1STRM); + ACCRND(acc0, 0); + ACCRND(acc1, 4); + xinput += 8; + xsecret += 1; + nbStripes--; + } while (nbStripes != 0); + + svst1_u64(mask, xacc + 0, acc0); + svst1_u64(mask, xacc + 4, acc1); + } + } +} + +#endif + /* scalar variants - universal */ +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +/* + * In XXH3_scalarRound(), GCC and Clang have a similar codegen issue, where they + * emit an excess mask and a full 64-bit multiply-add (MADD X-form). + * + * While this might not seem like much, as AArch64 is a 64-bit architecture, only + * big Cortex designs have a full 64-bit multiplier. + * + * On the little cores, the smaller 32-bit multiplier is used, and full 64-bit + * multiplies expand to 2-3 multiplies in microcode. This has a major penalty + * of up to 4 latency cycles and 2 stall cycles in the multiply pipeline. + * + * Thankfully, AArch64 still provides the 32-bit long multiply-add (UMADDL) which does + * not have this penalty and does the mask automatically. + */ +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc) +{ + xxh_u64 ret; + /* note: %x = 64-bit register, %w = 32-bit register */ + __asm__("umaddl %x0, %w1, %w2, %x3" : "=r" (ret) : "r" (lhs), "r" (rhs), "r" (acc)); + return ret; +} +#else +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc) +{ + return XXH_mult32to64((xxh_u32)lhs, (xxh_u32)rhs) + acc; +} +#endif + +/*! + * @internal + * @brief Scalar round for @ref XXH3_accumulate_512_scalar(). + * + * This is extracted to its own function because the NEON path uses a combination + * of NEON and scalar. + */ +XXH_FORCE_INLINE void +XXH3_scalarRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT input, + void const* XXH_RESTRICT secret, + size_t lane) +{ + xxh_u64* xacc = (xxh_u64*) acc; + xxh_u8 const* xinput = (xxh_u8 const*) input; + xxh_u8 const* xsecret = (xxh_u8 const*) secret; + XXH_ASSERT(lane < XXH_ACC_NB); + XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0); + { + xxh_u64 const data_val = XXH_readLE64(xinput + lane * 8); + xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8); + xacc[lane ^ 1] += data_val; /* swap adjacent lanes */ + xacc[lane] = XXH_mult32to64_add64(data_key /* & 0xFFFFFFFF */, data_key >> 32, xacc[lane]); + } +} + +/*! + * @internal + * @brief Processes a 64 byte block of data using the scalar path. + */ XXH_FORCE_INLINE void XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT input, const void* XXH_RESTRICT secret) { - xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ - const xxh_u8* const xinput = (const xxh_u8*) input; /* no alignment restriction */ - const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ size_t i; - XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0); + /* ARM GCC refuses to unroll this loop, resulting in a 24% slowdown on ARMv6. */ +#if defined(__GNUC__) && !defined(__clang__) \ + && (defined(__arm__) || defined(__thumb2__)) \ + && defined(__ARM_FEATURE_UNALIGNED) /* no unaligned access just wastes bytes */ \ + && XXH_SIZE_OPT <= 0 +# pragma GCC unroll 8 +#endif for (i=0; i < XXH_ACC_NB; i++) { - xxh_u64 const data_val = XXH_readLE64(xinput + 8*i); - xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + i*8); - xacc[i ^ 1] += data_val; /* swap adjacent lanes */ - xacc[i] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32); + XXH3_scalarRound(acc, input, secret, i); } } +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(scalar) +/*! + * @internal + * @brief Scalar scramble step for @ref XXH3_scrambleAcc_scalar(). + * + * This is extracted to its own function because the NEON path uses a combination + * of NEON and scalar. + */ XXH_FORCE_INLINE void -XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +XXH3_scalarScrambleRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT secret, + size_t lane) { xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ - size_t i; XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0); - for (i=0; i < XXH_ACC_NB; i++) { - xxh_u64 const key64 = XXH_readLE64(xsecret + 8*i); - xxh_u64 acc64 = xacc[i]; + XXH_ASSERT(lane < XXH_ACC_NB); + { + xxh_u64 const key64 = XXH_readLE64(xsecret + lane * 8); + xxh_u64 acc64 = xacc[lane]; acc64 = XXH_xorshift64(acc64, 47); acc64 ^= key64; acc64 *= XXH_PRIME32_1; - xacc[i] = acc64; + xacc[lane] = acc64; + } +} + +/*! + * @internal + * @brief Scrambles the accumulators after a large chunk has been read + */ +XXH_FORCE_INLINE void +XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + size_t i; + for (i=0; i < XXH_ACC_NB; i++) { + XXH3_scalarScrambleRound(acc, secret, i); } } @@ -4269,15 +5413,16 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) const xxh_u8* kSecretPtr = XXH3_kSecret; XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); -#if defined(__clang__) && defined(__aarch64__) +#if defined(__GNUC__) && defined(__aarch64__) /* * UGLY HACK: - * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are + * GCC and Clang generate a bunch of MOV/MOVK pairs for aarch64, and they are * placed sequentially, in order, at the top of the unrolled loop. * * While MOVK is great for generating constants (2 cycles for a 64-bit - * constant compared to 4 cycles for LDR), long MOVK chains stall the - * integer pipelines: + * constant compared to 4 cycles for LDR), it fights for bandwidth with + * the arithmetic instructions. + * * I L S * MOVK * MOVK @@ -4286,7 +5431,7 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) * ADD * SUB STR * STR - * By forcing loads from memory (as the asm line causes Clang to assume + * By forcing loads from memory (as the asm line causes the compiler to assume * that XXH3_kSecretPtr has been changed), the pipelines are used more * efficiently: * I L S @@ -4294,23 +5439,20 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) * ADD LDR * SUB STR * STR + * + * See XXH3_NEON_LANES for details on the pipsline. + * * XXH3_64bits_withSeed, len == 256, Snapdragon 835 * without hack: 2654.4 MB/s * with hack: 3202.9 MB/s */ XXH_COMPILER_GUARD(kSecretPtr); #endif - /* - * Note: in debug mode, this overrides the asm optimization - * and Clang will emit MOVK chains again. - */ - XXH_ASSERT(kSecretPtr == XXH3_kSecret); - { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; int i; for (i=0; i < nbRounds; i++) { /* - * The asm hack causes Clang to assume that kSecretPtr aliases with + * The asm hack causes the compiler to assume that kSecretPtr aliases with * customSecret, and on aarch64, this prevented LDP from merging two * loads together for free. Putting the loads together before the stores * properly generates LDP. @@ -4323,7 +5465,7 @@ XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) } -typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*); +typedef void (*XXH3_f_accumulate)(xxh_u64* XXH_RESTRICT, const xxh_u8* XXH_RESTRICT, const xxh_u8* XXH_RESTRICT, size_t); typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*); typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); @@ -4331,82 +5473,63 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); #if (XXH_VECTOR == XXH_AVX512) #define XXH3_accumulate_512 XXH3_accumulate_512_avx512 +#define XXH3_accumulate XXH3_accumulate_avx512 #define XXH3_scrambleAcc XXH3_scrambleAcc_avx512 #define XXH3_initCustomSecret XXH3_initCustomSecret_avx512 #elif (XXH_VECTOR == XXH_AVX2) #define XXH3_accumulate_512 XXH3_accumulate_512_avx2 +#define XXH3_accumulate XXH3_accumulate_avx2 #define XXH3_scrambleAcc XXH3_scrambleAcc_avx2 #define XXH3_initCustomSecret XXH3_initCustomSecret_avx2 #elif (XXH_VECTOR == XXH_SSE2) #define XXH3_accumulate_512 XXH3_accumulate_512_sse2 +#define XXH3_accumulate XXH3_accumulate_sse2 #define XXH3_scrambleAcc XXH3_scrambleAcc_sse2 #define XXH3_initCustomSecret XXH3_initCustomSecret_sse2 #elif (XXH_VECTOR == XXH_NEON) #define XXH3_accumulate_512 XXH3_accumulate_512_neon +#define XXH3_accumulate XXH3_accumulate_neon #define XXH3_scrambleAcc XXH3_scrambleAcc_neon #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar #elif (XXH_VECTOR == XXH_VSX) #define XXH3_accumulate_512 XXH3_accumulate_512_vsx +#define XXH3_accumulate XXH3_accumulate_vsx #define XXH3_scrambleAcc XXH3_scrambleAcc_vsx #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#elif (XXH_VECTOR == XXH_SVE) +#define XXH3_accumulate_512 XXH3_accumulate_512_sve +#define XXH3_accumulate XXH3_accumulate_sve +#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + #else /* scalar */ #define XXH3_accumulate_512 XXH3_accumulate_512_scalar +#define XXH3_accumulate XXH3_accumulate_scalar #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar #endif - - -#ifndef XXH_PREFETCH_DIST -# ifdef __clang__ -# define XXH_PREFETCH_DIST 320 -# else -# if (XXH_VECTOR == XXH_AVX512) -# define XXH_PREFETCH_DIST 512 -# else -# define XXH_PREFETCH_DIST 384 -# endif -# endif /* __clang__ */ -#endif /* XXH_PREFETCH_DIST */ - -/* - * XXH3_accumulate() - * Loops over XXH3_accumulate_512(). - * Assumption: nbStripes will not overflow the secret size - */ -XXH_FORCE_INLINE void -XXH3_accumulate( xxh_u64* XXH_RESTRICT acc, - const xxh_u8* XXH_RESTRICT input, - const xxh_u8* XXH_RESTRICT secret, - size_t nbStripes, - XXH3_f_accumulate_512 f_acc512) -{ - size_t n; - for (n = 0; n < nbStripes; n++ ) { - const xxh_u8* const in = input + n*XXH_STRIPE_LEN; - XXH_PREFETCH(in + XXH_PREFETCH_DIST); - f_acc512(acc, - in, - secret + n*XXH_SECRET_CONSUME_RATE); - } -} +#if XXH_SIZE_OPT >= 1 /* don't do SIMD for initialization */ +# undef XXH3_initCustomSecret +# define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#endif XXH_FORCE_INLINE void XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; @@ -4418,7 +5541,7 @@ XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); for (n = 0; n < nb_blocks; n++) { - XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512); + f_acc(acc, input + n*block_len, secret, nbStripesPerBlock); f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN); } @@ -4426,12 +5549,12 @@ XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, XXH_ASSERT(len > XXH_STRIPE_LEN); { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN; XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); - XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512); + f_acc(acc, input + nb_blocks*block_len, secret, nbStripes); /* last stripe */ { const xxh_u8* const p = input + len - XXH_STRIPE_LEN; #define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */ - f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); + XXH3_accumulate_512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); } } } @@ -4476,12 +5599,12 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre XXH_FORCE_INLINE XXH64_hash_t XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, const void* XXH_RESTRICT secret, size_t secretSize, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; - XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble); + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc, f_scramble); /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); @@ -4495,13 +5618,15 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, * It's important for performance to transmit secret's size (when it's static) * so that the compiler can properly optimize the vectorized loop. * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set. + * When the secret size is unknown, or on GCC 12 where the mix of NO_INLINE and FORCE_INLINE + * breaks -Og, this is XXH_NO_INLINE. */ XXH3_WITH_SECRET_INLINE XXH64_hash_t XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) { (void)seed64; - return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc); + return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate, XXH3_scrambleAcc); } /* @@ -4510,12 +5635,12 @@ XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, * Note that inside this no_inline function, we do inline the internal loop, * and provide a statically defined secret size to allow optimization of vector loop. */ -XXH_NO_INLINE XXH64_hash_t +XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) { (void)seed64; (void)secret; (void)secretLen; - return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc); + return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate, XXH3_scrambleAcc); } /* @@ -4532,18 +5657,20 @@ XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, XXH_FORCE_INLINE XXH64_hash_t XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, XXH64_hash_t seed, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble, XXH3_f_initCustomSecret f_initSec) { +#if XXH_SIZE_OPT <= 0 if (seed == 0) return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), - f_acc512, f_scramble); + f_acc, f_scramble); +#endif { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; f_initSec(secret, seed); return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret), - f_acc512, f_scramble); + f_acc, f_scramble); } } @@ -4551,12 +5678,12 @@ XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, * It's important for performance that XXH3_hashLong is not inlined. */ XXH_NO_INLINE XXH64_hash_t -XXH3_hashLong_64b_withSeed(const void* input, size_t len, - XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen) +XXH3_hashLong_64b_withSeed(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) { (void)secret; (void)secretLen; return XXH3_hashLong_64b_withSeed_internal(input, len, seed, - XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); + XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret); } @@ -4588,37 +5715,37 @@ XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len, /* === Public entry point === */ -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length) { - return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); + return XXH3_64bits_internal(input, length, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +XXH3_64bits_withSecret(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize) { - return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); + return XXH3_64bits_internal(input, length, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed) { - return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); + return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); } XXH_PUBLIC_API XXH64_hash_t -XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed) +XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) { - if (len <= XXH3_MIDSIZE_MAX) - return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); - return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize); + if (length <= XXH3_MIDSIZE_MAX) + return XXH3_64bits_internal(input, length, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); + return XXH3_hashLong_64b_withSecret(input, length, seed, (const xxh_u8*)secret, secretSize); } /* === XXH3 streaming === */ - +#ifndef XXH_NO_STREAM /* * Malloc's a pointer that is always aligned to align. * @@ -4642,7 +5769,7 @@ XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, * * Align must be a power of 2 and 8 <= align <= 128. */ -static void* XXH_alignedMalloc(size_t s, size_t align) +static XXH_MALLOCF void* XXH_alignedMalloc(size_t s, size_t align) { XXH_ASSERT(align <= 128 && align >= 8); /* range check */ XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */ @@ -4684,7 +5811,13 @@ static void XXH_alignedFree(void* p) XXH_free(base); } } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ +/*! + * @brief Allocate an @ref XXH3_state_t. + * + * Must be freed with XXH3_freeState(). + * @return An allocated XXH3_state_t on success, `NULL` on failure. + */ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) { XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64); @@ -4693,16 +5826,23 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) return state; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ +/*! + * @brief Frees an @ref XXH3_state_t. + * + * Must be allocated with XXH3_createState(). + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @return XXH_OK. + */ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) { XXH_alignedFree(statePtr); return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API void -XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state) +XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOESCAPE const XXH3_state_t* src_state) { XXH_memcpy(dst_state, src_state, sizeof(*dst_state)); } @@ -4734,18 +5874,18 @@ XXH3_reset_internal(XXH3_state_t* statePtr, statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset(XXH3_state_t* statePtr) +XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr) { if (statePtr == NULL) return XXH_ERROR; XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize) { if (statePtr == NULL) return XXH_ERROR; XXH3_reset_internal(statePtr, 0, secret, secretSize); @@ -4754,9 +5894,9 @@ XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed) { if (statePtr == NULL) return XXH_ERROR; if (seed==0) return XXH3_64bits_reset(statePtr); @@ -4766,9 +5906,9 @@ XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64) +XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64) { if (statePtr == NULL) return XXH_ERROR; if (secret == NULL) return XXH_ERROR; @@ -4778,35 +5918,61 @@ XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, return XXH_OK; } -/* Note : when XXH3_consumeStripes() is invoked, - * there must be a guarantee that at least one more byte must be consumed from input - * so that the function can blindly consume all stripes using the "normal" secret segment */ -XXH_FORCE_INLINE void +/*! + * @internal + * @brief Processes a large input for XXH3_update() and XXH3_digest_long(). + * + * Unlike XXH3_hashLong_internal_loop(), this can process data that overlaps a block. + * + * @param acc Pointer to the 8 accumulator lanes + * @param nbStripesSoFarPtr In/out pointer to the number of leftover stripes in the block* + * @param nbStripesPerBlock Number of stripes in a block + * @param input Input pointer + * @param nbStripes Number of stripes to process + * @param secret Secret pointer + * @param secretLimit Offset of the last block in @p secret + * @param f_acc Pointer to an XXH3_accumulate implementation + * @param f_scramble Pointer to an XXH3_scrambleAcc implementation + * @return Pointer past the end of @p input after processing + */ +XXH_FORCE_INLINE const xxh_u8 * XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock, const xxh_u8* XXH_RESTRICT input, size_t nbStripes, const xxh_u8* XXH_RESTRICT secret, size_t secretLimit, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { - XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */ - XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock); - if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) { - /* need a scrambling operation */ - size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr; - size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock; - XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512); - f_scramble(acc, secret + secretLimit); - XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512); - *nbStripesSoFarPtr = nbStripesAfterBlock; - } else { - XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512); + const xxh_u8* initialSecret = secret + *nbStripesSoFarPtr * XXH_SECRET_CONSUME_RATE; + /* Process full blocks */ + if (nbStripes >= (nbStripesPerBlock - *nbStripesSoFarPtr)) { + /* Process the initial partial block... */ + size_t nbStripesThisIter = nbStripesPerBlock - *nbStripesSoFarPtr; + + do { + /* Accumulate and scramble */ + f_acc(acc, input, initialSecret, nbStripesThisIter); + f_scramble(acc, secret + secretLimit); + input += nbStripesThisIter * XXH_STRIPE_LEN; + nbStripes -= nbStripesThisIter; + /* Then continue the loop with the full block size */ + nbStripesThisIter = nbStripesPerBlock; + initialSecret = secret; + } while (nbStripes >= nbStripesPerBlock); + *nbStripesSoFarPtr = 0; + } + /* Process a partial block */ + if (nbStripes > 0) { + f_acc(acc, input, initialSecret, nbStripes); + input += nbStripes * XXH_STRIPE_LEN; *nbStripesSoFarPtr += nbStripes; } + /* Return end pointer */ + return input; } #ifndef XXH3_STREAM_USE_STACK -# ifndef __clang__ /* clang doesn't need additional stack space */ +# if XXH_SIZE_OPT <= 0 && !defined(__clang__) /* clang doesn't need additional stack space */ # define XXH3_STREAM_USE_STACK 1 # endif #endif @@ -4816,7 +5982,7 @@ XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, XXH_FORCE_INLINE XXH_errorcode XXH3_update(XXH3_state_t* XXH_RESTRICT const state, const xxh_u8* XXH_RESTRICT input, size_t len, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { if (input==NULL) { @@ -4832,7 +5998,8 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, * when operating accumulators directly into state. * Operating into stack space seems to enable proper optimization. * clang, on the other hand, doesn't seem to need this trick */ - XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc)); + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; + XXH_memcpy(acc, state->acc, sizeof(acc)); #else xxh_u64* XXH_RESTRICT const acc = state->acc; #endif @@ -4840,7 +6007,7 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE); /* small input : just fill in tmp buffer */ - if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { + if (len <= XXH3_INTERNALBUFFER_SIZE - state->bufferedSize) { XXH_memcpy(state->buffer + state->bufferedSize, input, len); state->bufferedSize += (XXH32_hash_t)len; return XXH_OK; @@ -4862,57 +6029,20 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, &state->nbStripesSoFar, state->nbStripesPerBlock, state->buffer, XXH3_INTERNALBUFFER_STRIPES, secret, state->secretLimit, - f_acc512, f_scramble); + f_acc, f_scramble); state->bufferedSize = 0; } XXH_ASSERT(input < bEnd); - - /* large input to consume : ingest per full block */ - if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) { + if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) { size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN; - XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar); - /* join to current block's end */ - { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar; - XXH_ASSERT(nbStripes <= nbStripes); - XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512); - f_scramble(acc, secret + state->secretLimit); - state->nbStripesSoFar = 0; - input += nbStripesToEnd * XXH_STRIPE_LEN; - nbStripes -= nbStripesToEnd; - } - /* consume per entire blocks */ - while(nbStripes >= state->nbStripesPerBlock) { - XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512); - f_scramble(acc, secret + state->secretLimit); - input += state->nbStripesPerBlock * XXH_STRIPE_LEN; - nbStripes -= state->nbStripesPerBlock; - } - /* consume last partial block */ - XXH3_accumulate(acc, input, secret, nbStripes, f_acc512); - input += nbStripes * XXH_STRIPE_LEN; - XXH_ASSERT(input < bEnd); /* at least some bytes left */ - state->nbStripesSoFar = nbStripes; - /* buffer predecessor of last partial stripe */ - XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); - XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN); - } else { - /* content to consume <= block size */ - /* Consume input by a multiple of internal buffer size */ - if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) { - const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE; - do { - XXH3_consumeStripes(acc, + input = XXH3_consumeStripes(acc, &state->nbStripesSoFar, state->nbStripesPerBlock, - input, XXH3_INTERNALBUFFER_STRIPES, - secret, state->secretLimit, - f_acc512, f_scramble); - input += XXH3_INTERNALBUFFER_SIZE; - } while (inputbuffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); - } - } + input, nbStripes, + secret, state->secretLimit, + f_acc, f_scramble); + XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); + } /* Some remaining input (always) : buffer it */ XXH_ASSERT(input < bEnd); XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE); @@ -4921,19 +6051,19 @@ XXH3_update(XXH3_state_t* XXH_RESTRICT const state, state->bufferedSize = (XXH32_hash_t)(bEnd-input); #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1 /* save stack accumulators into state */ - memcpy(state->acc, acc, sizeof(acc)); + XXH_memcpy(state->acc, acc, sizeof(acc)); #endif } return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len) +XXH3_64bits_update(XXH_NOESCAPE XXH3_state_t* state, XXH_NOESCAPE const void* input, size_t len) { return XXH3_update(state, (const xxh_u8*)input, len, - XXH3_accumulate_512, XXH3_scrambleAcc); + XXH3_accumulate, XXH3_scrambleAcc); } @@ -4942,37 +6072,40 @@ XXH3_digest_long (XXH64_hash_t* acc, const XXH3_state_t* state, const unsigned char* secret) { + xxh_u8 lastStripe[XXH_STRIPE_LEN]; + const xxh_u8* lastStripePtr; + /* * Digest on a local copy. This way, the state remains unaltered, and it can * continue ingesting more input afterwards. */ XXH_memcpy(acc, state->acc, sizeof(state->acc)); if (state->bufferedSize >= XXH_STRIPE_LEN) { + /* Consume remaining stripes then point to remaining data in buffer */ size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN; size_t nbStripesSoFar = state->nbStripesSoFar; XXH3_consumeStripes(acc, &nbStripesSoFar, state->nbStripesPerBlock, state->buffer, nbStripes, secret, state->secretLimit, - XXH3_accumulate_512, XXH3_scrambleAcc); - /* last stripe */ - XXH3_accumulate_512(acc, - state->buffer + state->bufferedSize - XXH_STRIPE_LEN, - secret + state->secretLimit - XXH_SECRET_LASTACC_START); + XXH3_accumulate, XXH3_scrambleAcc); + lastStripePtr = state->buffer + state->bufferedSize - XXH_STRIPE_LEN; } else { /* bufferedSize < XXH_STRIPE_LEN */ - xxh_u8 lastStripe[XXH_STRIPE_LEN]; + /* Copy to temp buffer */ size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize; XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */ XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); - XXH3_accumulate_512(acc, - lastStripe, - secret + state->secretLimit - XXH_SECRET_LASTACC_START); + lastStripePtr = lastStripe; } + /* Last stripe */ + XXH3_accumulate_512(acc, + lastStripePtr, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); } -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* state) { const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; if (state->totalLen > XXH3_MIDSIZE_MAX) { @@ -4988,7 +6121,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); } - +#endif /* !XXH_NO_STREAM */ /* ========================================== @@ -5008,7 +6141,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64). */ -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { /* A doubled version of 1to3_64b with different constants. */ @@ -5037,7 +6170,7 @@ XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_ } } -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -5057,14 +6190,14 @@ XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_ m128.low64 ^= (m128.high64 >> 3); m128.low64 = XXH_xorshift64(m128.low64, 35); - m128.low64 *= 0x9FB21C651E98DF25ULL; + m128.low64 *= PRIME_MX2; m128.low64 = XXH_xorshift64(m128.low64, 28); m128.high64 = XXH3_avalanche(m128.high64); return m128; } } -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(input != NULL); @@ -5139,7 +6272,7 @@ XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64 /* * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN */ -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) { XXH_ASSERT(len <= 16); @@ -5170,7 +6303,7 @@ XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2, } -XXH_FORCE_INLINE XXH128_hash_t +XXH_FORCE_INLINE XXH_PUREF XXH128_hash_t XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -5181,6 +6314,16 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, { XXH128_hash_t acc; acc.low64 = len * XXH_PRIME64_1; acc.high64 = 0; + +#if XXH_SIZE_OPT >= 1 + { + /* Smaller, but slightly slower. */ + unsigned int i = (unsigned int)(len - 1) / 32; + do { + acc = XXH128_mix32B(acc, input+16*i, input+len-16*(i+1), secret+32*i, seed); + } while (i-- != 0); + } +#else if (len > 32) { if (len > 64) { if (len > 96) { @@ -5191,6 +6334,7 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed); } acc = XXH128_mix32B(acc, input, input+len-16, secret, seed); +#endif { XXH128_hash_t h128; h128.low64 = acc.low64 + acc.high64; h128.high64 = (acc.low64 * XXH_PRIME64_1) @@ -5203,7 +6347,7 @@ XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, } } -XXH_NO_INLINE XXH128_hash_t +XXH_NO_INLINE XXH_PUREF XXH128_hash_t XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, XXH64_hash_t seed) @@ -5212,25 +6356,34 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); { XXH128_hash_t acc; - int const nbRounds = (int)len / 32; - int i; + unsigned i; acc.low64 = len * XXH_PRIME64_1; acc.high64 = 0; - for (i=0; i<4; i++) { + /* + * We set as `i` as offset + 32. We do this so that unchanged + * `len` can be used as upper bound. This reaches a sweet spot + * where both x86 and aarch64 get simple agen and good codegen + * for the loop. + */ + for (i = 32; i < 160; i += 32) { acc = XXH128_mix32B(acc, - input + (32 * i), - input + (32 * i) + 16, - secret + (32 * i), + input + i - 32, + input + i - 16, + secret + i - 32, seed); } acc.low64 = XXH3_avalanche(acc.low64); acc.high64 = XXH3_avalanche(acc.high64); - XXH_ASSERT(nbRounds >= 4); - for (i=4 ; i < nbRounds; i++) { + /* + * NB: `i <= len` will duplicate the last 32-bytes if + * len % 32 was zero. This is an unfortunate necessity to keep + * the hash result stable. + */ + for (i=160; i <= len; i += 32) { acc = XXH128_mix32B(acc, - input + (32 * i), - input + (32 * i) + 16, - secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)), + input + i - 32, + input + i - 16, + secret + XXH3_MIDSIZE_STARTOFFSET + i - 160, seed); } /* last bytes */ @@ -5238,7 +6391,7 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, input + len - 16, input + len - 32, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16, - 0ULL - seed); + (XXH64_hash_t)0 - seed); { XXH128_hash_t h128; h128.low64 = acc.low64 + acc.high64; @@ -5255,12 +6408,12 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble) { XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; - XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble); + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc, f_scramble); /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); @@ -5278,21 +6431,24 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, } /* - * It's important for performance that XXH3_hashLong is not inlined. + * It's important for performance that XXH3_hashLong() is not inlined. */ -XXH_NO_INLINE XXH128_hash_t +XXH_NO_INLINE XXH_PUREF XXH128_hash_t XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen) { (void)seed64; (void)secret; (void)secretLen; return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), - XXH3_accumulate_512, XXH3_scrambleAcc); + XXH3_accumulate, XXH3_scrambleAcc); } /* - * It's important for performance to pass @secretLen (when it's static) + * It's important for performance to pass @p secretLen (when it's static) * to the compiler, so that it can properly optimize the vectorized loop. + * + * When the secret size is unknown, or on GCC 12 where the mix of NO_INLINE and FORCE_INLINE + * breaks -Og, this is XXH_NO_INLINE. */ XXH3_WITH_SECRET_INLINE XXH128_hash_t XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len, @@ -5301,24 +6457,24 @@ XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len, { (void)seed64; return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen, - XXH3_accumulate_512, XXH3_scrambleAcc); + XXH3_accumulate, XXH3_scrambleAcc); } XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len, XXH64_hash_t seed64, - XXH3_f_accumulate_512 f_acc512, + XXH3_f_accumulate f_acc, XXH3_f_scrambleAcc f_scramble, XXH3_f_initCustomSecret f_initSec) { if (seed64 == 0) return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), - f_acc512, f_scramble); + f_acc, f_scramble); { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; f_initSec(secret, seed64); return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret), - f_acc512, f_scramble); + f_acc, f_scramble); } } @@ -5331,7 +6487,7 @@ XXH3_hashLong_128b_withSeed(const void* input, size_t len, { (void)secret; (void)secretLen; return XXH3_hashLong_128b_withSeed_internal(input, len, seed64, - XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); + XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret); } typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t, @@ -5361,94 +6517,93 @@ XXH3_128bits_internal(const void* input, size_t len, /* === Public XXH128 API === */ -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* input, size_t len) { return XXH3_128bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_128b_default); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +XXH3_128bits_withSecret(XXH_NOESCAPE const void* input, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize) { return XXH3_128bits_internal(input, len, 0, (const xxh_u8*)secret, secretSize, XXH3_hashLong_128b_withSecret); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +XXH3_128bits_withSeed(XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) { return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_128b_withSeed); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed) +XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) { if (len <= XXH3_MIDSIZE_MAX) return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH128(const void* input, size_t len, XXH64_hash_t seed) +XXH128(XXH_NOESCAPE const void* input, size_t len, XXH64_hash_t seed) { return XXH3_128bits_withSeed(input, len, seed); } /* === XXH3 128-bit streaming === */ - +#ifndef XXH_NO_STREAM /* * All initialization and update functions are identical to 64-bit streaming variant. * The only difference is the finalization routine. */ -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset(XXH3_state_t* statePtr) +XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr) { return XXH3_64bits_reset(statePtr); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize) { return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed) { return XXH3_64bits_reset_withSeed(statePtr, seed); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed) +XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed) { return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len) +XXH3_128bits_update(XXH_NOESCAPE XXH3_state_t* state, XXH_NOESCAPE const void* input, size_t len) { - return XXH3_update(state, (const xxh_u8*)input, len, - XXH3_accumulate_512, XXH3_scrambleAcc); + return XXH3_64bits_update(state, input, len); } -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* state) { const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; if (state->totalLen > XXH3_MIDSIZE_MAX) { @@ -5472,13 +6627,13 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); } - +#endif /* !XXH_NO_STREAM */ /* 128-bit utility functions */ #include /* memcmp, memcpy */ /* return : 1 is equal, 0 if different */ -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) { /* note : XXH128_hash_t is compact, it has no padding byte */ @@ -5486,11 +6641,11 @@ XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) } /* This prototype is compatible with stdlib's qsort(). - * return : >0 if *h128_1 > *h128_2 - * <0 if *h128_1 < *h128_2 - * =0 if *h128_1 == *h128_2 */ -/*! @ingroup xxh3_family */ -XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) + * @return : >0 if *h128_1 > *h128_2 + * <0 if *h128_1 < *h128_2 + * =0 if *h128_1 == *h128_2 */ +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2) { XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1; XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2; @@ -5502,9 +6657,9 @@ XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) /*====== Canonical representation ======*/ -/*! @ingroup xxh3_family */ -static zend_always_inline void -XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) +/*! @ingroup XXH3_family */ +XXH_PUBLIC_API void +XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) { @@ -5515,9 +6670,9 @@ XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64)); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH128_hash_t -XXH128_hashFromCanonical(const XXH128_canonical_t* src) +XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src) { XXH128_hash_t h; h.high64 = XXH_readBE64(src); @@ -5533,26 +6688,34 @@ XXH128_hashFromCanonical(const XXH128_canonical_t* src) */ #define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x)) -static void XXH3_combine16(void* dst, XXH128_hash_t h128) +XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128) { XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 ); XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 ); } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API XXH_errorcode -XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize) +XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer, size_t secretSize, XXH_NOESCAPE const void* customSeed, size_t customSeedSize) { +#if (XXH_DEBUGLEVEL >= 1) XXH_ASSERT(secretBuffer != NULL); - if (secretBuffer == NULL) return XXH_ERROR; XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); +#else + /* production mode, assert() are disabled */ + if (secretBuffer == NULL) return XXH_ERROR; if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; +#endif + if (customSeedSize == 0) { customSeed = XXH3_kSecret; customSeedSize = XXH_SECRET_DEFAULT_SIZE; } +#if (XXH_DEBUGLEVEL >= 1) XXH_ASSERT(customSeed != NULL); +#else if (customSeed == NULL) return XXH_ERROR; +#endif /* Fill secretBuffer with a copy of customSeed - repeat as needed */ { size_t pos = 0; @@ -5576,9 +6739,9 @@ XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSee return XXH_OK; } -/*! @ingroup xxh3_family */ +/*! @ingroup XXH3_family */ XXH_PUBLIC_API void -XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed) +XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed) { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; XXH3_initCustomSecret(secret, seed); @@ -5591,7 +6754,7 @@ XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed) /* Pop our optimization override from above */ #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ - && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ + && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0 /* respect -O0 and -Os */ # pragma GCC pop_options #endif @@ -5606,5 +6769,5 @@ XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed) #if defined (__cplusplus) -} +} /* extern "C" */ #endif diff --git a/ext/iconv/config.m4 b/ext/iconv/config.m4 index 4d0dc3648983..e86f3535a97c 100644 --- a/ext/iconv/config.m4 +++ b/ext/iconv/config.m4 @@ -83,6 +83,20 @@ int main(void) { AS_VAR_IF([php_cv_iconv_errno], [yes],, [AC_MSG_FAILURE([The iconv check failed, 'errno' is missing.])]) + dnl iconv on some platforms (NetBSD pre-10, Solaris) may have a non-standard + dnl const input parameter; libiconv may imitate this on those platforms. + AC_CACHE_CHECK([if iconv input parameter is const (non-standard)], [php_cv_iconv_const], + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +#include + +size_t iconv(iconv_t cd, const char **src, size_t *srcleft, char **dst, size_t *dstleft); + ])], + [php_cv_iconv_const=const], + [php_cv_iconv_const=non-const])]) + dnl non-const is just used for display, set it back + AS_VAR_IF([php_cv_iconv_const], [non-const], + [php_cv_iconv_const=]) + AC_CACHE_CHECK([if iconv supports //IGNORE], [php_cv_iconv_ignore], [AC_RUN_IFELSE([AC_LANG_SOURCE([ #include @@ -120,7 +134,7 @@ int main(void) { PHP_NEW_EXTENSION([iconv], [iconv.c], [$ext_shared],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) + [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DICONV_CONST=$php_cv_iconv_const]) PHP_SUBST([ICONV_SHARED_LIBADD]) PHP_INSTALL_HEADERS([ext/iconv], [php_iconv.h]) fi diff --git a/ext/iconv/config.w32 b/ext/iconv/config.w32 index d99c53fb9363..b8fe6804d526 100644 --- a/ext/iconv/config.w32 +++ b/ext/iconv/config.w32 @@ -5,7 +5,7 @@ ARG_WITH("iconv", "iconv support", "yes"); if (PHP_ICONV != "no") { if ((CHECK_LIB("libiconv_a.lib", "iconv", PHP_ICONV) || CHECK_LIB("libiconv.lib", "iconv", PHP_ICONV) || CHECK_LIB("iconv_a.lib", "iconv", PHP_ICONV) || CHECK_LIB("iconv.lib", "iconv", PHP_ICONV)) && - CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_ICONV", PHP_ICONV)) { + CHECK_HEADER("iconv.h", "CFLAGS_ICONV", PHP_ICONV)) { EXTENSION("iconv", "iconv.c", PHP_ICONV_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 157ee41a11a0..d9b54388a8f8 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rui Hirokawa | | Stig Bakken | @@ -43,11 +41,11 @@ #undef iconv #endif -#if defined(__NetBSD__) -// unfortunately, netbsd has still the old non posix conformant signature -// libiconv tends to match the eventual system's iconv too. -#define ICONV_CONST const -#else +/* iconv can have different constiness for src on some platforms; + * this is explained in config.m4. On Windows, it's always non-const, + * but it can be awkward to set that on the command line. Do it here. + */ +#ifndef ICONV_CONST #define ICONV_CONST #endif @@ -460,59 +458,65 @@ PHP_ICONV_API php_iconv_err_t php_iconv_string(const char *in_p, size_t in_len, out_left = in_len + 32; /* Avoid realloc() most cases */ out_size = 0; bsz = out_left; - out_buf = zend_string_alloc(bsz, 0); - out_p = ZSTR_VAL(out_buf); - - while (in_left > 0) { - result = iconv(cd, (ICONV_CONST char **) &in_p, &in_left, (char **) &out_p, &out_left); - out_size = bsz - out_left; - if (result == (size_t)(-1)) { - if (ignore_ilseq && errno == EILSEQ) { - if (in_left <= 1) { - result = 0; - } else { - errno = 0; - in_p++; - in_left--; - continue; + + zend_try { + out_buf = zend_string_alloc(bsz, 0); + out_p = ZSTR_VAL(out_buf); + + while (in_left > 0) { + result = iconv(cd, (ICONV_CONST char **) &in_p, &in_left, (char **) &out_p, &out_left); + out_size = bsz - out_left; + if (result == (size_t)(-1)) { + if (ignore_ilseq && errno == EILSEQ) { + if (in_left <= 1) { + result = 0; + } else { + errno = 0; + in_p++; + in_left--; + continue; + } } - } - if (errno == E2BIG && in_left > 0) { - /* converted string is longer than out buffer */ - bsz += in_len; + if (errno == E2BIG && in_left > 0) { + /* converted string is longer than out buffer */ + bsz += in_len; - out_buf = zend_string_extend(out_buf, bsz, 0); - out_p = ZSTR_VAL(out_buf); - out_p += out_size; - out_left = bsz - out_size; - continue; + out_buf = zend_string_extend(out_buf, bsz, 0); + out_p = ZSTR_VAL(out_buf); + out_p += out_size; + out_left = bsz - out_size; + continue; + } } + break; } - break; - } - if (result != (size_t)(-1)) { - /* flush the shift-out sequences */ - for (;;) { - result = iconv(cd, NULL, NULL, (char **) &out_p, &out_left); - out_size = bsz - out_left; + if (result != (size_t)(-1)) { + /* flush the shift-out sequences */ + for (;;) { + result = iconv(cd, NULL, NULL, (char **) &out_p, &out_left); + out_size = bsz - out_left; - if (result != (size_t)(-1)) { - break; - } + if (result != (size_t)(-1)) { + break; + } - if (errno == E2BIG) { - bsz += 16; - out_buf = zend_string_extend(out_buf, bsz, 0); - out_p = ZSTR_VAL(out_buf); - out_p += out_size; - out_left = bsz - out_size; - } else { - break; + if (errno == E2BIG) { + bsz += 16; + out_buf = zend_string_extend(out_buf, bsz, 0); + out_p = ZSTR_VAL(out_buf); + out_p += out_size; + out_left = bsz - out_size; + } else { + break; + } } } - } + } zend_catch { + iconv_close(cd); + zend_bailout(); + } zend_end_try(); iconv_close(cd); @@ -685,58 +689,63 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval, errno = 0; more = nbytes > 0 && len > 0; - for (in_p = str, in_left = nbytes, cnt = 0; more; ++cnt) { - out_p = buf; - out_left = sizeof(buf); + bool bailout = false; + zend_try { + for (in_p = str, in_left = nbytes, cnt = 0; more; ++cnt) { + out_p = buf; + out_left = sizeof(buf); - more = in_left > 0 && len > 0; + more = in_left > 0 && len > 0; - iconv(cd1, more ? (ICONV_CONST char **)&in_p : NULL, more ? &in_left : NULL, (char **) &out_p, &out_left); - if (out_left == sizeof(buf)) { - break; - } + iconv(cd1, more ? (ICONV_CONST char **)&in_p : NULL, more ? &in_left : NULL, (char **) &out_p, &out_left); + if (out_left == sizeof(buf)) { + break; + } - if ((zend_long)cnt >= offset) { - if (cd2 == (iconv_t)NULL) { - cd2 = iconv_open(enc, GENERIC_SUPERSET_NAME); + if ((zend_long)cnt >= offset) { + if (cd2 == (iconv_t)NULL) { + cd2 = iconv_open(enc, GENERIC_SUPERSET_NAME); - if (cd2 == (iconv_t)(-1)) { - cd2 = (iconv_t)NULL; - if (errno == EINVAL) { - err = PHP_ICONV_ERR_WRONG_CHARSET; - } else { - err = PHP_ICONV_ERR_CONVERTER; + if (cd2 == (iconv_t)(-1)) { + cd2 = (iconv_t)NULL; + if (errno == EINVAL) { + err = PHP_ICONV_ERR_WRONG_CHARSET; + } else { + err = PHP_ICONV_ERR_CONVERTER; + } + break; } + } + + if (_php_iconv_appendl(pretval, buf, sizeof(buf), cd2) != PHP_ICONV_ERR_SUCCESS) { break; } + --len; } - if (_php_iconv_appendl(pretval, buf, sizeof(buf), cd2) != PHP_ICONV_ERR_SUCCESS) { - break; - } - --len; } - } - - switch (errno) { - case EINVAL: - err = PHP_ICONV_ERR_ILLEGAL_CHAR; - break; + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + break; - case EILSEQ: - err = PHP_ICONV_ERR_ILLEGAL_SEQ; - break; + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + break; - case E2BIG: - break; - } - if (err == PHP_ICONV_ERR_SUCCESS) { - if (cd2 != (iconv_t)NULL) { - _php_iconv_appendl(pretval, NULL, 0, cd2); + case E2BIG: + break; } - smart_str_0(pretval); - } + if (err == PHP_ICONV_ERR_SUCCESS) { + if (cd2 != (iconv_t)NULL) { + _php_iconv_appendl(pretval, NULL, 0, cd2); + } + smart_str_0(pretval); + } + } zend_catch { + bailout = true; + } zend_end_try(); if (cd1 != (iconv_t)NULL) { iconv_close(cd1); @@ -745,6 +754,9 @@ static php_iconv_err_t _php_iconv_substr(smart_str *pretval, if (cd2 != (iconv_t)NULL) { iconv_close(cd2); } + if (bailout) { + zend_bailout(); + } return err; } @@ -904,6 +916,7 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn { php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; iconv_t cd = (iconv_t)(-1), cd_pl = (iconv_t)(-1); + bool bailout = false; size_t char_cnt = 0; size_t out_charset_len; size_t lfchars_len; @@ -962,215 +975,221 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn goto out; } - buf = safe_emalloc(1, max_line_len, 5); + zend_try { + buf = safe_emalloc(1, max_line_len, 5); - char_cnt = max_line_len; + char_cnt = max_line_len; - _php_iconv_appendl(pretval, fname, fname_nbytes, cd_pl); - char_cnt -= fname_nbytes; - smart_str_appendl(pretval, ": ", sizeof(": ") - 1); - char_cnt -= 2; + _php_iconv_appendl(pretval, fname, fname_nbytes, cd_pl); + char_cnt -= fname_nbytes; + smart_str_appendl(pretval, ": ", sizeof(": ") - 1); + char_cnt -= 2; - in_p = fval; - in_left = fval_nbytes; + in_p = fval; + in_left = fval_nbytes; - do { - size_t prev_in_left; - size_t out_size; - size_t encoded_word_min_len = sizeof("=\?\?X\?\?=")-1 + out_charset_len + (enc_scheme == PHP_ICONV_ENC_SCHEME_BASE64 ? 4 : 3); + do { + size_t prev_in_left; + size_t out_size; + size_t encoded_word_min_len = sizeof("=\?\?X\?\?=")-1 + out_charset_len + (enc_scheme == PHP_ICONV_ENC_SCHEME_BASE64 ? 4 : 3); - if (char_cnt < encoded_word_min_len + lfchars_len + 1) { - /* lfchars must be encoded in ASCII here*/ - smart_str_appendl(pretval, lfchars, lfchars_len); - smart_str_appendc(pretval, ' '); - char_cnt = max_line_len - 1; - } + if (char_cnt < encoded_word_min_len + lfchars_len + 1) { + /* lfchars must be encoded in ASCII here*/ + smart_str_appendl(pretval, lfchars, lfchars_len); + smart_str_appendc(pretval, ' '); + char_cnt = max_line_len - 1; + } - smart_str_appendl(pretval, "=?", sizeof("=?") - 1); - char_cnt -= 2; - smart_str_appendl(pretval, out_charset, out_charset_len); - char_cnt -= out_charset_len; - smart_str_appendc(pretval, '?'); - char_cnt --; + smart_str_appendl(pretval, "=?", sizeof("=?") - 1); + char_cnt -= 2; + smart_str_appendl(pretval, out_charset, out_charset_len); + char_cnt -= out_charset_len; + smart_str_appendc(pretval, '?'); + char_cnt --; - switch (enc_scheme) { - case PHP_ICONV_ENC_SCHEME_BASE64: { - size_t ini_in_left; - const char *ini_in_p; - size_t out_reserved = 4; + switch (enc_scheme) { + case PHP_ICONV_ENC_SCHEME_BASE64: { + size_t ini_in_left; + const char *ini_in_p; + size_t out_reserved = 4; - smart_str_appendc(pretval, 'B'); - char_cnt--; - smart_str_appendc(pretval, '?'); - char_cnt--; + smart_str_appendc(pretval, 'B'); + char_cnt--; + smart_str_appendc(pretval, '?'); + char_cnt--; - prev_in_left = ini_in_left = in_left; - ini_in_p = in_p; + prev_in_left = ini_in_left = in_left; + ini_in_p = in_p; - out_size = (char_cnt - 2) / 4 * 3; + out_size = (char_cnt - 2) / 4 * 3; - for (;;) { - out_p = buf; + for (;;) { + out_p = buf; - if (out_size <= out_reserved) { - err = PHP_ICONV_ERR_TOO_BIG; - goto out; - } + if (out_size <= out_reserved) { + err = PHP_ICONV_ERR_TOO_BIG; + goto out_try; + } - out_left = out_size - out_reserved; + out_left = out_size - out_reserved; - if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { - switch (errno) { - case EINVAL: - err = PHP_ICONV_ERR_ILLEGAL_CHAR; - goto out; + if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + goto out_try; - case EILSEQ: - err = PHP_ICONV_ERR_ILLEGAL_SEQ; - goto out; + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + goto out_try; - case E2BIG: - if (prev_in_left == in_left) { - err = PHP_ICONV_ERR_TOO_BIG; - goto out; - } - break; + case E2BIG: + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_TOO_BIG; + goto out_try; + } + break; - default: - err = PHP_ICONV_ERR_UNKNOWN; - goto out; + default: + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } } - } - out_left += out_reserved; + out_left += out_reserved; - if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { - if (errno != E2BIG) { + if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { + if (errno != E2BIG) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } + } else { + break; + } + + if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { err = PHP_ICONV_ERR_UNKNOWN; - goto out; + goto out_try; } - } else { - break; - } - if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; + out_reserved += 4; + in_left = ini_in_left; + in_p = ini_in_p; } - out_reserved += 4; - in_left = ini_in_left; - in_p = ini_in_p; - } + prev_in_left = in_left; - prev_in_left = in_left; + encoded = php_base64_encode((unsigned char *) buf, (out_size - out_left)); - encoded = php_base64_encode((unsigned char *) buf, (out_size - out_left)); + if (char_cnt < ZSTR_LEN(encoded)) { + /* something went wrong! */ + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } - if (char_cnt < ZSTR_LEN(encoded)) { - /* something went wrong! */ - err = PHP_ICONV_ERR_UNKNOWN; - goto out; - } + smart_str_append(pretval, encoded); + char_cnt -= ZSTR_LEN(encoded); + smart_str_appendl(pretval, "?=", sizeof("?=") - 1); + char_cnt -= 2; - smart_str_appendl(pretval, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); - char_cnt -= ZSTR_LEN(encoded); - smart_str_appendl(pretval, "?=", sizeof("?=") - 1); - char_cnt -= 2; + zend_string_release_ex(encoded, 0); + encoded = NULL; + } break; /* case PHP_ICONV_ENC_SCHEME_BASE64: */ - zend_string_release_ex(encoded, 0); - encoded = NULL; - } break; /* case PHP_ICONV_ENC_SCHEME_BASE64: */ + case PHP_ICONV_ENC_SCHEME_QPRINT: { + size_t ini_in_left; + const char *ini_in_p; + const unsigned char *p; + size_t nbytes_required; - case PHP_ICONV_ENC_SCHEME_QPRINT: { - size_t ini_in_left; - const char *ini_in_p; - const unsigned char *p; - size_t nbytes_required; + smart_str_appendc(pretval, 'Q'); + char_cnt--; + smart_str_appendc(pretval, '?'); + char_cnt--; - smart_str_appendc(pretval, 'Q'); - char_cnt--; - smart_str_appendc(pretval, '?'); - char_cnt--; + prev_in_left = ini_in_left = in_left; + ini_in_p = in_p; - prev_in_left = ini_in_left = in_left; - ini_in_p = in_p; + for (out_size = (char_cnt - 2); out_size > 0;) { - for (out_size = (char_cnt - 2); out_size > 0;) { + nbytes_required = 0; - nbytes_required = 0; + out_p = buf; + out_left = out_size; - out_p = buf; - out_left = out_size; + if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { + switch (errno) { + case EINVAL: + err = PHP_ICONV_ERR_ILLEGAL_CHAR; + goto out_try; - if (iconv(cd, (ICONV_CONST char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) { - switch (errno) { - case EINVAL: - err = PHP_ICONV_ERR_ILLEGAL_CHAR; - goto out; + case EILSEQ: + err = PHP_ICONV_ERR_ILLEGAL_SEQ; + goto out_try; - case EILSEQ: - err = PHP_ICONV_ERR_ILLEGAL_SEQ; - goto out; + case E2BIG: + if (prev_in_left == in_left) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; + } + break; - case E2BIG: - if (prev_in_left == in_left) { + default: err = PHP_ICONV_ERR_UNKNOWN; - goto out; - } - break; - - default: + goto out_try; + } + } + if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { + if (errno != E2BIG) { err = PHP_ICONV_ERR_UNKNOWN; - goto out; + goto out_try; + } } - } - if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)-1) { - if (errno != E2BIG) { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; + + for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { + nbytes_required += qp_table[*p]; } - } - for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { - nbytes_required += qp_table[*p]; + if (nbytes_required <= char_cnt - 2) { + break; + } + + out_size -= ((nbytes_required - (char_cnt - 2)) + 2) / 3; + in_left = ini_in_left; + in_p = ini_in_p; } - if (nbytes_required <= char_cnt - 2) { - break; + for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { + if (qp_table[*p] == 1) { + smart_str_appendc(pretval, *(char *)p); + char_cnt--; + } else { + static const char qp_digits[] = "0123456789ABCDEF"; + smart_str_appendc(pretval, '='); + smart_str_appendc(pretval, qp_digits[(*p >> 4) & 0x0f]); + smart_str_appendc(pretval, qp_digits[(*p & 0x0f)]); + char_cnt -= 3; + } } - out_size -= ((nbytes_required - (char_cnt - 2)) + 2) / 3; - in_left = ini_in_left; - in_p = ini_in_p; - } + smart_str_appendl(pretval, "?=", sizeof("?=") - 1); + char_cnt -= 2; - for (p = (unsigned char *)buf; p < (unsigned char *)out_p; p++) { - if (qp_table[*p] == 1) { - smart_str_appendc(pretval, *(char *)p); - char_cnt--; - } else { - static const char qp_digits[] = "0123456789ABCDEF"; - smart_str_appendc(pretval, '='); - smart_str_appendc(pretval, qp_digits[(*p >> 4) & 0x0f]); - smart_str_appendc(pretval, qp_digits[(*p & 0x0f)]); - char_cnt -= 3; + if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; } - } - - smart_str_appendl(pretval, "?=", sizeof("?=") - 1); - char_cnt -= 2; - if (iconv(cd, NULL, NULL, NULL, NULL) == (size_t)-1) { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; - } + } break; /* case PHP_ICONV_ENC_SCHEME_QPRINT: */ + } + } while (in_left > 0); - } break; /* case PHP_ICONV_ENC_SCHEME_QPRINT: */ - } - } while (in_left > 0); + smart_str_0(pretval); - smart_str_0(pretval); +out_try: ; + } zend_catch { + bailout = true; + } zend_end_try(); out: if (cd != (iconv_t)(-1)) { @@ -1185,6 +1204,9 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn if (buf != NULL) { efree(buf); } + if (bailout) { + zend_bailout(); + } return err; } /* }}} */ @@ -1193,6 +1215,7 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *str, size_t str_nbytes, const char *enc, const char **next_pos, int mode) { php_iconv_err_t err = PHP_ICONV_ERR_SUCCESS; + bool bailout = false; iconv_t cd = (iconv_t)(-1), cd_pl = (iconv_t)(-1); @@ -1224,206 +1247,229 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st } p1 = str; - for (str_left = str_nbytes; str_left > 0; str_left--, p1++) { - int eos = 0; - - switch (scan_stat) { - case 0: /* expecting any character */ - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + zend_try { + for (str_left = str_nbytes; str_left > 0; str_left--, p1++) { + int eos = 0; + + switch (scan_stat) { + case 0: /* expecting any character */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case '\n': - scan_stat = 8; - break; + case '\n': + scan_stat = 8; + break; - case '=': /* first letter of an encoded chunk */ - encoded_word = p1; - scan_stat = 1; - break; + case '=': /* first letter of an encoded chunk */ + encoded_word = p1; + scan_stat = 1; + break; - case ' ': case '\t': /* a chunk of whitespaces */ - spaces = p1; - scan_stat = 11; - break; + case ' ': case '\t': /* a chunk of whitespaces */ + spaces = p1; + scan_stat = 11; + break; - default: /* first letter of a non-encoded word */ - err = _php_iconv_appendc(pretval, *p1, cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - if (mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR) { - err = PHP_ICONV_ERR_SUCCESS; - } else { - goto out; + default: /* first letter of a non-encoded word */ + err = _php_iconv_appendc(pretval, *p1, cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + if (mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR) { + err = PHP_ICONV_ERR_SUCCESS; + } else { + goto out_try; + } } - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } - break; - } - break; - - case 1: /* expecting a delimiter */ - if (*p1 != '?') { - if (*p1 == '\r' || *p1 == '\n') { - --p1; - } - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } + break; } break; - } - csname = p1 + 1; - scan_stat = 2; - break; - - case 2: /* expecting a charset name */ - switch (*p1) { - case '?': /* normal delimiter: encoding scheme follows */ - scan_stat = 3; - break; - case '*': /* new style delimiter: locale id follows */ - scan_stat = 10; - break; - - case '\r': case '\n': /* not an encoded-word */ - --p1; - _php_iconv_appendc(pretval, '=', cd_pl); - _php_iconv_appendc(pretval, '?', cd_pl); - err = _php_iconv_appendl(pretval, csname, (size_t)((p1 + 1) - csname), cd_pl); + case 1: /* expecting a delimiter */ + if (*p1 != '?') { + if (*p1 == '\r' || *p1 == '\n') { + --p1; + } + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; + goto out_try; } - csname = NULL; + encoded_word = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { scan_stat = 12; - } - else { + } else { scan_stat = 0; } - continue; - } - if (scan_stat != 2) { - char tmpbuf[80]; - - if (csname == NULL) { - err = PHP_ICONV_ERR_MALFORMED; - goto out; + break; } + csname = p1 + 1; + scan_stat = 2; + break; - csname_len = (size_t)(p1 - csname); + case 2: /* expecting a charset name */ + switch (*p1) { + case '?': /* normal delimiter: encoding scheme follows */ + scan_stat = 3; + break; - if (csname_len > sizeof(tmpbuf) - 1) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + case '*': /* new style delimiter: locale id follows */ + scan_stat = 10; + break; + + case '\r': case '\n': /* not an encoded-word */ + --p1; + _php_iconv_appendc(pretval, '=', cd_pl); + _php_iconv_appendc(pretval, '?', cd_pl); + err = _php_iconv_appendl(pretval, csname, (size_t)((p1 + 1) - csname), cd_pl); if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; + goto out_try; } - encoded_word = NULL; + csname = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { scan_stat = 12; - } else { + } + else { scan_stat = 0; } - break; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; - } + continue; } + if (scan_stat != 2) { + char tmpbuf[80]; - memcpy(tmpbuf, csname, csname_len); - tmpbuf[csname_len] = '\0'; - - if (cd != (iconv_t)(-1)) { - iconv_close(cd); - } + if (csname == NULL) { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; + } - cd = iconv_open(enc, tmpbuf); + csname_len = (size_t)(p1 - csname); - if (cd == (iconv_t)(-1)) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* Bad character set, but the user wants us to - * press on. In this case, we'll just insert the - * undecoded encoded word, since there isn't really - * a more sensible behaviour available; the only - * other options are to swallow the encoded word - * entirely or decode it with an arbitrarily chosen - * single byte encoding, both of which seem to have - * a higher WTF factor than leaving it undecoded. - * - * Given this approach, we need to skip ahead to - * the end of the encoded word. */ - int qmarks = 2; - while (qmarks > 0 && str_left > 1) { - if (*(++p1) == '?') { - --qmarks; + if (csname_len > sizeof(tmpbuf) - 1) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; } - --str_left; + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; } + } + + memcpy(tmpbuf, csname, csname_len); + tmpbuf[csname_len] = '\0'; - /* Look ahead to check for the terminating = that - * should be there as well; if it's there, we'll - * also include that. If it's not, there isn't much - * we can do at this point. */ - if (*(p1 + 1) == '=') { - ++p1; - if (str_left > 1) { + if (cd != (iconv_t)(-1)) { + iconv_close(cd); + } + + cd = iconv_open(enc, tmpbuf); + + if (cd == (iconv_t)(-1)) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* Bad character set, but the user wants us to + * press on. In this case, we'll just insert the + * undecoded encoded word, since there isn't really + * a more sensible behaviour available; the only + * other options are to swallow the encoded word + * entirely or decode it with an arbitrarily chosen + * single byte encoding, both of which seem to have + * a higher WTF factor than leaving it undecoded. + * + * Given this approach, we need to skip ahead to + * the end of the encoded word. */ + int qmarks = 2; + while (qmarks > 0 && str_left > 1) { + if (*(++p1) == '?') { + --qmarks; + } --str_left; } - } - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } + /* Look ahead to check for the terminating = that + * should be there as well; if it's there, we'll + * also include that. If it's not, there isn't much + * we can do at this point. */ + if (*(p1 + 1) == '=') { + ++p1; + if (str_left > 1) { + --str_left; + } + } - /* Let's go back and see if there are further - * encoded words or bare content, and hope they - * might actually have a valid character set. */ - scan_stat = 12; - break; - } else { - if (errno == EINVAL) { - err = PHP_ICONV_ERR_WRONG_CHARSET; + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + + /* Let's go back and see if there are further + * encoded words or bare content, and hope they + * might actually have a valid character set. */ + scan_stat = 12; + break; } else { - err = PHP_ICONV_ERR_CONVERTER; + if (errno == EINVAL) { + err = PHP_ICONV_ERR_WRONG_CHARSET; + } else { + err = PHP_ICONV_ERR_CONVERTER; + } + goto out_try; } - goto out; } } - } - break; + break; - case 3: /* expecting a encoding scheme specifier */ - switch (*p1) { - case 'b': - case 'B': - enc_scheme = PHP_ICONV_ENC_SCHEME_BASE64; - scan_stat = 4; - break; + case 3: /* expecting a encoding scheme specifier */ + switch (*p1) { + case 'b': + case 'B': + enc_scheme = PHP_ICONV_ENC_SCHEME_BASE64; + scan_stat = 4; + break; - case 'q': - case 'Q': - enc_scheme = PHP_ICONV_ENC_SCHEME_QPRINT; - scan_stat = 4; - break; + case 'q': + case 'Q': + enc_scheme = PHP_ICONV_ENC_SCHEME_QPRINT; + scan_stat = 4; + break; - default: + default: + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; + } + } + break; + + case 4: /* expecting a delimiter */ + if (*p1 != '?') { if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; + goto out_try; } encoded_word = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { @@ -1434,301 +1480,285 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st break; } else { err = PHP_ICONV_ERR_MALFORMED; - goto out; + goto out_try; } - } - break; - - case 4: /* expecting a delimiter */ - if (*p1 != '?') { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; - } - break; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; } - } - encoded_text = p1 + 1; - scan_stat = 5; - break; - - case 5: /* expecting an encoded portion */ - if (*p1 == '?') { - encoded_text_len = (size_t)(p1 - encoded_text); - scan_stat = 6; - } - break; + encoded_text = p1 + 1; + scan_stat = 5; + break; - case 7: /* expecting a "\n" character */ - if (*p1 == '\n') { - scan_stat = 8; - } else { - /* bare CR */ - _php_iconv_appendc(pretval, '\r', cd_pl); - _php_iconv_appendc(pretval, *p1, cd_pl); - scan_stat = 0; - } - break; + case 5: /* expecting an encoded portion */ + if (*p1 == '?') { + encoded_text_len = (size_t)(p1 - encoded_text); + scan_stat = 6; + } + break; - case 8: /* checking whether the following line is part of a - folded header */ - if (*p1 != ' ' && *p1 != '\t') { - --p1; - str_left = 1; /* quit_loop */ + case 7: /* expecting a "\n" character */ + if (*p1 == '\n') { + scan_stat = 8; + } else { + /* bare CR */ + _php_iconv_appendc(pretval, '\r', cd_pl); + _php_iconv_appendc(pretval, *p1, cd_pl); + scan_stat = 0; + } break; - } - if (encoded_word == NULL) { - _php_iconv_appendc(pretval, ' ', cd_pl); - } - spaces = NULL; - scan_stat = 11; - break; - case 6: /* expecting a End-Of-Chunk character "=" */ - if (*p1 != '=') { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; - } + case 8: /* checking whether the following line is part of a + folded header */ + if (*p1 != ' ' && *p1 != '\t') { + --p1; + str_left = 1; /* quit_loop */ break; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; } - } - scan_stat = 9; - if (str_left == 1) { - eos = 1; - } else { + if (encoded_word == NULL) { + _php_iconv_appendc(pretval, ' ', cd_pl); + } + spaces = NULL; + scan_stat = 11; break; - } - /* TODO might want to rearrange logic so this is more obvious */ - ZEND_FALLTHROUGH; - case 9: /* choice point, seeing what to do next.*/ - switch (*p1) { - default: - /* Handle non-RFC-compliant formats - * - * RFC2047 requires the character that comes right - * after an encoded word (chunk) to be a whitespace, - * while there are lots of broken implementations that - * generate such malformed headers that don't fulfill - * that requirement. - */ - if (!eos) { + case 6: /* expecting a End-Of-Chunk character "=" */ + if (*p1 != '=') { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + encoded_word = NULL; if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } scan_stat = 12; - break; + } else { + scan_stat = 0; } + break; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; } - ZEND_FALLTHROUGH; - - case '\r': case '\n': case ' ': case '\t': { - zend_string *decoded_text; - - switch (enc_scheme) { - case PHP_ICONV_ENC_SCHEME_BASE64: - decoded_text = php_base64_decode((unsigned char*)encoded_text, encoded_text_len); - break; - - case PHP_ICONV_ENC_SCHEME_QPRINT: - decoded_text = php_quot_print_decode((unsigned char*)encoded_text, encoded_text_len, 1); - break; - default: - decoded_text = NULL; - break; - } + } + scan_stat = 9; + if (str_left == 1) { + eos = 1; + } else { + break; + } + /* TODO might want to rearrange logic so this is more obvious */ + ZEND_FALLTHROUGH; - if (decoded_text == NULL) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); - if (err != PHP_ICONV_ERR_SUCCESS) { - goto out; - } - encoded_word = NULL; + case 9: /* choice point, seeing what to do next.*/ + switch (*p1) { + default: + /* Handle non-RFC-compliant formats + * + * RFC2047 requires the character that comes right + * after an encoded word (chunk) to be a whitespace, + * while there are lots of broken implementations that + * generate such malformed headers that don't fulfill + * that requirement. + */ + if (!eos) { if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } scan_stat = 12; - } else { - scan_stat = 0; + break; } - break; - } else { - err = PHP_ICONV_ERR_UNKNOWN; - goto out; } - } + ZEND_FALLTHROUGH; - err = _php_iconv_appendl(pretval, ZSTR_VAL(decoded_text), ZSTR_LEN(decoded_text), cd); - if (err == PHP_ICONV_ERR_SUCCESS) { - err = _php_iconv_appendl(pretval, NULL, 0, cd); - } - zend_string_release_ex(decoded_text, 0); + case '\r': case '\n': case ' ': case '\t': { + zend_string *decoded_text; - if (err != PHP_ICONV_ERR_SUCCESS) { - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - /* pass the entire chunk through the converter */ - err = _php_iconv_appendl(pretval, encoded_word, (size_t)(p1 - encoded_word), cd_pl); - encoded_word = NULL; - if (err != PHP_ICONV_ERR_SUCCESS) { + switch (enc_scheme) { + case PHP_ICONV_ENC_SCHEME_BASE64: + decoded_text = php_base64_decode((unsigned char*)encoded_text, encoded_text_len); break; + + case PHP_ICONV_ENC_SCHEME_QPRINT: + decoded_text = php_quot_print_decode((unsigned char*)encoded_text, encoded_text_len, 1); + break; + default: + decoded_text = NULL; + break; + } + + if (decoded_text == NULL) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl); + if (err != PHP_ICONV_ERR_SUCCESS) { + goto out_try; + } + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } else { + err = PHP_ICONV_ERR_UNKNOWN; + goto out_try; } - } else { - goto out; } - } - if (eos) { /* reached end-of-string. done. */ - scan_stat = 0; - break; - } + err = _php_iconv_appendl(pretval, ZSTR_VAL(decoded_text), ZSTR_LEN(decoded_text), cd); + if (err == PHP_ICONV_ERR_SUCCESS) { + err = _php_iconv_appendl(pretval, NULL, 0, cd); + } + zend_string_release_ex(decoded_text, 0); - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + if (err != PHP_ICONV_ERR_SUCCESS) { + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + /* pass the entire chunk through the converter */ + err = _php_iconv_appendl(pretval, encoded_word, (size_t)(p1 - encoded_word), cd_pl); + encoded_word = NULL; + if (err != PHP_ICONV_ERR_SUCCESS) { + break; + } + } else { + goto out_try; + } + } - case '\n': - scan_stat = 8; + if (eos) { /* reached end-of-string. done. */ + scan_stat = 0; break; + } - case '=': /* first letter of an encoded chunk */ - scan_stat = 1; - break; + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case ' ': case '\t': /* medial whitespaces */ - spaces = p1; - scan_stat = 11; - break; + case '\n': + scan_stat = 8; + break; - default: /* first letter of a non-encoded word */ - _php_iconv_appendc(pretval, *p1, cd_pl); - scan_stat = 12; - break; - } - } break; - } - break; + case '=': /* first letter of an encoded chunk */ + scan_stat = 1; + break; - case 10: /* expects a language specifier. dismiss it for now */ - if (*p1 == '?') { - scan_stat = 3; - } - break; + case ' ': case '\t': /* medial whitespaces */ + spaces = p1; + scan_stat = 11; + break; - case 11: /* expecting a chunk of whitespaces */ - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + default: /* first letter of a non-encoded word */ + _php_iconv_appendc(pretval, *p1, cd_pl); + scan_stat = 12; + break; + } + } break; + } + break; - case '\n': - scan_stat = 8; - break; + case 10: /* expects a language specifier. dismiss it for now */ + if (*p1 == '?') { + scan_stat = 3; + } + break; - case '=': /* first letter of an encoded chunk */ - if (spaces != NULL && encoded_word == NULL) { - _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); - spaces = NULL; - } - encoded_word = p1; - scan_stat = 1; - break; + case 11: /* expecting a chunk of whitespaces */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case ' ': case '\t': - break; + case '\n': + scan_stat = 8; + break; - default: /* first letter of a non-encoded word */ - if (spaces != NULL) { - _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); - spaces = NULL; - } - _php_iconv_appendc(pretval, *p1, cd_pl); - encoded_word = NULL; - if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { - scan_stat = 12; - } else { - scan_stat = 0; - } - break; - } - break; + case '=': /* first letter of an encoded chunk */ + if (spaces != NULL && encoded_word == NULL) { + _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); + spaces = NULL; + } + encoded_word = p1; + scan_stat = 1; + break; - case 12: /* expecting a non-encoded word */ - switch (*p1) { - case '\r': /* part of an EOL sequence? */ - scan_stat = 7; - break; + case ' ': case '\t': + break; - case '\n': - scan_stat = 8; - break; + default: /* first letter of a non-encoded word */ + if (spaces != NULL) { + _php_iconv_appendl(pretval, spaces, (size_t)(p1 - spaces), cd_pl); + spaces = NULL; + } + _php_iconv_appendc(pretval, *p1, cd_pl); + encoded_word = NULL; + if ((mode & PHP_ICONV_MIME_DECODE_STRICT)) { + scan_stat = 12; + } else { + scan_stat = 0; + } + break; + } + break; - case ' ': case '\t': - spaces = p1; - scan_stat = 11; - break; + case 12: /* expecting a non-encoded word */ + switch (*p1) { + case '\r': /* part of an EOL sequence? */ + scan_stat = 7; + break; - case '=': /* first letter of an encoded chunk */ - if (!(mode & PHP_ICONV_MIME_DECODE_STRICT)) { - encoded_word = p1; - scan_stat = 1; + case '\n': + scan_stat = 8; break; - } - ZEND_FALLTHROUGH; - default: - _php_iconv_appendc(pretval, *p1, cd_pl); - break; - } - break; + case ' ': case '\t': + spaces = p1; + scan_stat = 11; + break; + + case '=': /* first letter of an encoded chunk */ + if (!(mode & PHP_ICONV_MIME_DECODE_STRICT)) { + encoded_word = p1; + scan_stat = 1; + break; + } + ZEND_FALLTHROUGH; + + default: + _php_iconv_appendc(pretval, *p1, cd_pl); + break; + } + break; + } } - } - switch (scan_stat) { - case 0: case 8: case 11: case 12: - break; - default: - if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { - if (scan_stat == 1) { - _php_iconv_appendc(pretval, '=', cd_pl); + switch (scan_stat) { + case 0: case 8: case 11: case 12: + break; + default: + if ((mode & PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) { + if (scan_stat == 1) { + _php_iconv_appendc(pretval, '=', cd_pl); + } + err = PHP_ICONV_ERR_SUCCESS; + } else { + err = PHP_ICONV_ERR_MALFORMED; + goto out_try; } - err = PHP_ICONV_ERR_SUCCESS; - } else { - err = PHP_ICONV_ERR_MALFORMED; - goto out; - } - } + } - if (next_pos != NULL) { - *next_pos = p1; - } + if (next_pos != NULL) { + *next_pos = p1; + } + + smart_str_0(pretval); + +out_try: ; + } zend_catch { + bailout = true; + } zend_end_try(); - smart_str_0(pretval); out: if (cd != (iconv_t)(-1)) { iconv_close(cd); @@ -1736,6 +1766,9 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st if (cd_pl != (iconv_t)(-1)) { iconv_close(cd_pl); } + if (bailout) { + zend_bailout(); + } return err; } /* }}} */ @@ -1825,7 +1858,7 @@ PHP_FUNCTION(iconv_substr) size_t charset_len; zend_string *str; zend_long offset, length = 0; - bool len_is_null = 1; + bool len_is_null = true; php_iconv_err_t err; @@ -2554,6 +2587,33 @@ static php_stream_filter_status_t php_iconv_stream_filter_do_filter( } /* }}} */ +/* {{{ php_iconv_stream_filter_seek */ +static zend_result php_iconv_stream_filter_seek( + php_stream *stream, + php_stream_filter *filter, + zend_off_t offset, + int whence) +{ + php_iconv_stream_filter *self = (php_iconv_stream_filter *)Z_PTR(filter->abstract); + + /* Reset stub buffer */ + self->stub_len = 0; + + /* Reset iconv conversion state by closing and reopening the converter */ + iconv_close(self->cd); + + self->cd = iconv_open(self->to_charset, self->from_charset); + if ((iconv_t)-1 == self->cd) { + php_error_docref(NULL, E_WARNING, + "iconv stream filter (\"%s\"=>\"%s\"): failed to reset conversion state", + self->from_charset, self->to_charset); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + /* {{{ php_iconv_stream_filter_cleanup */ static void php_iconv_stream_filter_cleanup(php_stream_filter *filter) { @@ -2564,18 +2624,23 @@ static void php_iconv_stream_filter_cleanup(php_stream_filter *filter) static const php_stream_filter_ops php_iconv_stream_filter_ops = { php_iconv_stream_filter_do_filter, + php_iconv_stream_filter_seek, php_iconv_stream_filter_cleanup, "convert.iconv.*" }; /* {{{ php_iconv_stream_filter_create */ -static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, uint8_t persistent) +static php_stream_filter *php_iconv_stream_filter_factory_create(const char *name, zval *params, bool persistent) { - php_stream_filter *retval = NULL; php_iconv_stream_filter *inst; + php_stream_filter_seekable_t write_seekable; const char *from_charset = NULL, *to_charset = NULL; size_t from_charset_len, to_charset_len; + if (php_stream_filter_parse_write_seek_mode(params, &write_seekable) == FAILURE) { + return NULL; + } + if ((from_charset = strchr(name, '.')) == NULL) { return NULL; } @@ -2602,12 +2667,8 @@ static php_stream_filter *php_iconv_stream_filter_factory_create(const char *nam return NULL; } - if (NULL == (retval = php_stream_filter_alloc(&php_iconv_stream_filter_ops, inst, persistent))) { - php_iconv_stream_filter_dtor(inst); - pefree(inst, persistent); - } - - return retval; + return php_stream_filter_alloc(&php_iconv_stream_filter_ops, inst, persistent, + PSFS_SEEKABLE_START, write_seekable); } /* }}} */ diff --git a/ext/iconv/iconv_arginfo.h b/ext/iconv/iconv_arginfo.h index df2ecad3898e..fd23b7113cef 100644 --- a/ext/iconv/iconv_arginfo.h +++ b/ext/iconv/iconv_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit iconv.stub.php instead. * Stub hash: 4367fa431d3e4814e42d9aa514c10cae1d842d8f */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_iconv_strlen, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) diff --git a/ext/iconv/php_iconv.h b/ext/iconv/php_iconv.h index fcabdfaf6449..84a934e1e98b 100644 --- a/ext/iconv/php_iconv.h +++ b/ext/iconv/php_iconv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rui Hirokawa | | Stig Bakken | diff --git a/ext/iconv/tests/bug37773.phpt b/ext/iconv/tests/bug37773.phpt index 4dcdd56b3cb5..1d1b8f569ed1 100644 --- a/ext/iconv/tests/bug37773.phpt +++ b/ext/iconv/tests/bug37773.phpt @@ -10,6 +10,9 @@ if ($test === false) { die("skip UTF-8 is not supported?"); } +if (PHP_OS_FAMILY === 'Solaris') { + die("skip Solaris iconv behaves differently"); +} ?> --FILE-- --FILE-- --FILE-- --INI-- error_reporting=2039 --FILE-- diff --git a/ext/iconv/tests/gh17399.phpt b/ext/iconv/tests/gh17399.phpt new file mode 100644 index 000000000000..b93fc638e84c --- /dev/null +++ b/ext/iconv/tests/gh17399.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-17399 (iconv memory leak with large line-length in iconv_mime_encode) +--EXTENSIONS-- +iconv +--FILE-- + PHP_INT_MAX, +]; +iconv_mime_encode('Subject', 'test', $options); +?> +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh17399_iconv.phpt b/ext/iconv/tests/gh17399_iconv.phpt new file mode 100644 index 000000000000..2cdd0e176b20 --- /dev/null +++ b/ext/iconv/tests/gh17399_iconv.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-17399 (iconv() leak on bailout) +--EXTENSIONS-- +iconv +--INI-- +memory_limit=2M +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh17399_mime_decode.phpt b/ext/iconv/tests/gh17399_mime_decode.phpt new file mode 100644 index 000000000000..95a37d364f33 --- /dev/null +++ b/ext/iconv/tests/gh17399_mime_decode.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-17399 (iconv_mime_decode() leak on bailout) +--EXTENSIONS-- +iconv +--INI-- +memory_limit=2M +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh17399_substr.phpt b/ext/iconv/tests/gh17399_substr.phpt new file mode 100644 index 000000000000..12d4cff28eac --- /dev/null +++ b/ext/iconv/tests/gh17399_substr.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-17399 (iconv_substr() leak on bailout) +--EXTENSIONS-- +iconv +--INI-- +memory_limit=2M +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Allowed memory size of %d bytes exhausted %s in %s on line %d diff --git a/ext/iconv/tests/gh21664.phpt b/ext/iconv/tests/gh21664.phpt new file mode 100644 index 000000000000..92c66049c8dd --- /dev/null +++ b/ext/iconv/tests/gh21664.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21664 (iconv_mime_decode/iconv_mime_encode bailout corruption) +--EXTENSIONS-- +iconv +--FILE-- + "UTF-8", "output-charset" => "UTF-8"]); +var_dump($r); + +echo "Done\n"; +?> +--EXPECTF-- +Notice: iconv_mime_decode(): Detected an illegal character in input string in %s on line %d +bool(false) + +Notice: iconv_mime_encode(): Detected an illegal character in input string in %s on line %d +bool(false) +Done diff --git a/ext/iconv/tests/iconv003.phpt b/ext/iconv/tests/iconv003.phpt index 86e2e207b2a1..f3c2da39ed78 100644 --- a/ext/iconv/tests/iconv003.phpt +++ b/ext/iconv/tests/iconv003.phpt @@ -2,6 +2,12 @@ iconv() test 3 --EXTENSIONS-- iconv +--SKIPIF-- + --FILE-- --FILE-- --FILE-- +--CLEAN-- + +--EXPECTF-- +First read (20 bytes): Hello, this is a tes +Seek to start: SUCCESS +Content after seek matches: YES + +Warning: fseek(): Stream filter convert.iconv.* is seekable only to start position in %s on line %d +Seek to middle: FAILURE diff --git a/ext/iconv/tests/iconv_strrpos.phpt b/ext/iconv/tests/iconv_strrpos.phpt index 66d4e81d1d20..111d59dcd424 100644 --- a/ext/iconv/tests/iconv_strrpos.phpt +++ b/ext/iconv/tests/iconv_strrpos.phpt @@ -2,6 +2,12 @@ iconv_strrpos() --EXTENSIONS-- iconv +--SKIPIF-- + --INI-- iconv.internal_charset=ISO-8859-1 --FILE-- diff --git a/ext/iconv/tests/iconv_substr_out_of_bounds.phpt b/ext/iconv/tests/iconv_substr_out_of_bounds.phpt index fa335ccc22e6..7f4c28ae11fc 100644 --- a/ext/iconv/tests/iconv_substr_out_of_bounds.phpt +++ b/ext/iconv/tests/iconv_substr_out_of_bounds.phpt @@ -2,6 +2,12 @@ iconv_substr() with out of bounds offset --EXTENSIONS-- iconv +--SKIPIF-- + --FILE-- . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -96,7 +96,7 @@ static int BreakIterator_compare_objects(zval *object1, /* {{{ clone handler for BreakIterator */ static zend_object *BreakIterator_clone_obj(zend_object *object) { - BreakIterator_object *bio_orig = php_intl_breakiterator_fetch_object(object); + const BreakIterator_object *bio_orig = php_intl_breakiterator_fetch_object(object); zend_object *ret_val = BreakIterator_ce_ptr->create_object(object->ce); BreakIterator_object *bio_new = php_intl_breakiterator_fetch_object(ret_val); @@ -212,7 +212,7 @@ U_CFUNC void breakiterator_register_BreakIterator_class(void) memcpy(&BreakIterator_handlers, &std_object_handlers, sizeof BreakIterator_handlers); - BreakIterator_handlers.offset = XtOffsetOf(BreakIterator_object, zo); + BreakIterator_handlers.offset = offsetof(BreakIterator_object, zo); BreakIterator_handlers.compare = BreakIterator_compare_objects; BreakIterator_handlers.clone_obj = BreakIterator_clone_obj; BreakIterator_handlers.get_debug_info = BreakIterator_get_debug_info; diff --git a/ext/intl/breakiterator/breakiterator_class.h b/ext/intl/breakiterator/breakiterator_class.h index 0852d86e2a82..c18f9c674866 100644 --- a/ext/intl/breakiterator/breakiterator_class.h +++ b/ext/intl/breakiterator/breakiterator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -42,7 +42,7 @@ typedef struct { } BreakIterator_object; static inline BreakIterator_object *php_intl_breakiterator_fetch_object(zend_object *obj) { - return (BreakIterator_object *)((char*)(obj) - XtOffsetOf(BreakIterator_object, zo)); + return ZEND_CONTAINER_OF(obj, BreakIterator_object, zo); } #define Z_INTL_BREAKITERATOR_P(zv) php_intl_breakiterator_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp index 6817f52ffb02..805057489013 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.cpp +++ b/ext/intl/breakiterator/breakiterator_iterators.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -43,7 +43,7 @@ inline BreakIterator *_breakiter_prolog(zend_object_iterator *iter) if (bio->biter == NULL) { intl_errors_set(BREAKITER_ERROR_P(bio), U_INVALID_STATE_ERROR, "The BreakIterator object backing the PHP iterator is not " - "properly constructed", 0); + "properly constructed"); } return bio->biter; } diff --git a/ext/intl/breakiterator/breakiterator_iterators.h b/ext/intl/breakiterator/breakiterator_iterators.h index e52d066ac9ed..3ac07cd271c8 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.h +++ b/ext/intl/breakiterator/breakiterator_iterators.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h index f83c0accf6bf..423c60709d9c 100644 --- a/ext/intl/breakiterator/breakiterator_iterators_arginfo.h +++ b/ext/intl/breakiterator/breakiterator_iterators_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit breakiterator_iterators.stub.php instead. * Stub hash: 5dc9ab2cc5862b2082fb9cd5cec909298921b115 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlPartsIterator_getBreakIterator, 0, 0, IntlBreakIterator, 0) @@ -25,21 +25,21 @@ static zend_class_entry *register_class_IntlPartsIterator(zend_class_entry *clas zval const_KEY_SEQUENTIAL_value; ZVAL_LONG(&const_KEY_SEQUENTIAL_value, PARTS_ITERATOR_KEY_SEQUENTIAL); - zend_string *const_KEY_SEQUENTIAL_name = zend_string_init_interned("KEY_SEQUENTIAL", sizeof("KEY_SEQUENTIAL") - 1, 1); + zend_string *const_KEY_SEQUENTIAL_name = zend_string_init_interned("KEY_SEQUENTIAL", sizeof("KEY_SEQUENTIAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_KEY_SEQUENTIAL_name, &const_KEY_SEQUENTIAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_KEY_SEQUENTIAL_name); + zend_string_release_ex(const_KEY_SEQUENTIAL_name, true); zval const_KEY_LEFT_value; ZVAL_LONG(&const_KEY_LEFT_value, PARTS_ITERATOR_KEY_LEFT); - zend_string *const_KEY_LEFT_name = zend_string_init_interned("KEY_LEFT", sizeof("KEY_LEFT") - 1, 1); + zend_string *const_KEY_LEFT_name = zend_string_init_interned("KEY_LEFT", sizeof("KEY_LEFT") - 1, true); zend_declare_typed_class_constant(class_entry, const_KEY_LEFT_name, &const_KEY_LEFT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_KEY_LEFT_name); + zend_string_release_ex(const_KEY_LEFT_name, true); zval const_KEY_RIGHT_value; ZVAL_LONG(&const_KEY_RIGHT_value, PARTS_ITERATOR_KEY_RIGHT); - zend_string *const_KEY_RIGHT_name = zend_string_init_interned("KEY_RIGHT", sizeof("KEY_RIGHT") - 1, 1); + zend_string *const_KEY_RIGHT_name = zend_string_init_interned("KEY_RIGHT", sizeof("KEY_RIGHT") - 1, true); zend_declare_typed_class_constant(class_entry, const_KEY_RIGHT_name, &const_KEY_RIGHT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_KEY_RIGHT_name); + zend_string_release_ex(const_KEY_RIGHT_name, true); return class_entry; } diff --git a/ext/intl/breakiterator/breakiterator_methods.cpp b/ext/intl/breakiterator/breakiterator_methods.cpp index 56a3a35c97f8..66a35e65ac6a 100644 --- a/ext/intl/breakiterator/breakiterator_methods.cpp +++ b/ext/intl/breakiterator/breakiterator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -41,14 +41,13 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, __construct) 0 ); } -static void _breakiter_factory(const char *func_name, - BreakIterator *(*func)(const Locale&, UErrorCode&), - INTERNAL_FUNCTION_PARAMETERS) +static void _breakiter_factory( + BreakIterator *(*func)(const Locale&, UErrorCode&), + INTERNAL_FUNCTION_PARAMETERS) { BreakIterator *biter; char *locale_str = NULL; size_t dummy; - char *msg; UErrorCode status = UErrorCode(); intl_error_reset(NULL); @@ -64,10 +63,7 @@ static void _breakiter_factory(const char *func_name, biter = func(Locale::createFromName(locale_str), status); intl_error_set_code(NULL, status); if (U_FAILURE(status)) { - spprintf(&msg, 0, "%s: error creating BreakIterator", - func_name); - intl_error_set_custom_msg(NULL, msg, 1); - efree(msg); + intl_error_set_custom_msg(NULL, "error creating BreakIterator"); RETURN_NULL(); } @@ -76,35 +72,35 @@ static void _breakiter_factory(const char *func_name, U_CFUNC PHP_METHOD(IntlBreakIterator, createWordInstance) { - _breakiter_factory("breakiter_create_word_instance", + _breakiter_factory( &BreakIterator::createWordInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createLineInstance) { - _breakiter_factory("breakiter_create_line_instance", + _breakiter_factory( &BreakIterator::createLineInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createCharacterInstance) { - _breakiter_factory("breakiter_create_character_instance", + _breakiter_factory( &BreakIterator::createCharacterInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createSentenceInstance) { - _breakiter_factory("breakiter_create_sentence_instance", + _breakiter_factory( &BreakIterator::createSentenceInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } U_CFUNC PHP_METHOD(IntlBreakIterator, createTitleInstance) { - _breakiter_factory("breakiter_create_title_instance", + _breakiter_factory( &BreakIterator::createTitleInstance, INTERNAL_FUNCTION_PARAM_PASSTHRU); } @@ -149,12 +145,11 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, setText) BREAKITER_METHOD_FETCH_OBJECT; ut = utext_openUTF8(ut, ZSTR_VAL(text), ZSTR_LEN(text), BREAKITER_ERROR_CODE_P(bio)); - INTL_METHOD_CHECK_STATUS(bio, "breakiter_set_text: error opening UText"); + INTL_METHOD_CHECK_STATUS(bio, "error opening UText"); bio->biter->setText(ut, BREAKITER_ERROR_CODE(bio)); utext_close(ut); /* ICU shallow clones the UText */ - INTL_METHOD_CHECK_STATUS(bio, "breakiter_set_text: error calling " - "BreakIterator::setText()"); + INTL_METHOD_CHECK_STATUS(bio, "error calling BreakIterator::setText()"); /* When ICU clones the UText, it does not copy the buffer, so we have to * keep the string buffer around by holding a reference to its zval. This @@ -302,19 +297,16 @@ U_CFUNC PHP_METHOD(IntlBreakIterator, getLocale) Z_PARAM_LONG(locale_type) ZEND_PARSE_PARAMETERS_END(); - /* Change to ValueError? */ if (locale_type != ULOC_ACTUAL_LOCALE && locale_type != ULOC_VALID_LOCALE) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "breakiter_get_locale: invalid locale type", 0); - RETURN_FALSE; + zend_argument_value_error(1, "must be either Locale::ACTUAL_LOCALE or Locale::VALID_LOCALE"); + RETURN_THROWS(); } BREAKITER_METHOD_FETCH_OBJECT; Locale locale = bio->biter->getLocale((ULocDataLocaleType)locale_type, BREAKITER_ERROR_CODE(bio)); - INTL_METHOD_CHECK_STATUS(bio, - "breakiter_get_locale: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(bio, "Call to ICU method has failed"); RETURN_STRING(locale.getName()); } diff --git a/ext/intl/breakiterator/codepointiterator_internal.cpp b/ext/intl/breakiterator/codepointiterator_internal.cpp index 3982a599af38..47d5df00c1be 100644 --- a/ext/intl/breakiterator/codepointiterator_internal.cpp +++ b/ext/intl/breakiterator/codepointiterator_internal.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/breakiterator/codepointiterator_internal.h b/ext/intl/breakiterator/codepointiterator_internal.h index 8090bfbbd3cc..a64d49e24d5e 100644 --- a/ext/intl/breakiterator/codepointiterator_internal.h +++ b/ext/intl/breakiterator/codepointiterator_internal.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/breakiterator/codepointiterator_methods.cpp b/ext/intl/breakiterator/codepointiterator_methods.cpp index 49beb41be4e9..3b5044cb45a1 100644 --- a/ext/intl/breakiterator/codepointiterator_methods.cpp +++ b/ext/intl/breakiterator/codepointiterator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp index c84972fe5b98..1e1c2f0f6e5c 100644 --- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp +++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -32,17 +32,16 @@ static inline RuleBasedBreakIterator *fetch_rbbi(BreakIterator_object *bio) { return (RuleBasedBreakIterator*)bio->biter; } -static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) +U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) { - char *rules; - size_t rules_len; - bool compiled = false; - UErrorCode status = U_ZERO_ERROR; + zend_string *rules; + bool compiled = false; + UErrorCode status = U_ZERO_ERROR; BREAKITER_METHOD_INIT_VARS; object = ZEND_THIS; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(rules, rules_len) + Z_PARAM_STR(rules) Z_PARAM_OPTIONAL Z_PARAM_BOOL(compiled) ZEND_PARSE_PARAMETERS_END(); @@ -53,20 +52,14 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_er RETURN_THROWS(); } - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - - // instantiation of ICU object RuleBasedBreakIterator *rbbi; if (!compiled) { UnicodeString rulesStr; UParseError parseError = UParseError(); - if (intl_stringFromChar(rulesStr, rules, rules_len, &status) - == FAILURE) { + if (intl_stringFromChar(rulesStr, ZSTR_VAL(rules), ZSTR_LEN(rules), &status) == FAILURE) { zend_throw_exception(IntlException_ce_ptr, - "IntlRuleBasedBreakIterator::__construct(): " - "rules were not a valid UTF-8 string", 0); + "IntlRuleBasedBreakIterator::__construct(): rules were not a valid UTF-8 string", 0); RETURN_THROWS(); } @@ -84,29 +77,16 @@ static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS, zend_er RETURN_THROWS(); } } else { // compiled - rbbi = new RuleBasedBreakIterator((uint8_t*)rules, rules_len, status); + rbbi = new RuleBasedBreakIterator(reinterpret_cast(ZSTR_VAL(rules)), ZSTR_LEN(rules), status); if (U_FAILURE(status)) { zend_throw_exception(IntlException_ce_ptr, - "IntlRuleBasedBreakIterator::__construct(): " - "unable to create instance from compiled rules", 0); + "IntlRuleBasedBreakIterator::__construct(): unable to create instance from compiled rules", 0); delete rbbi; RETURN_THROWS(); } } - breakiterator_object_create(return_value, rbbi, 0); -} - -U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct) -{ - zend_error_handling error_handling; - bool error_handling_replaced = 0; - - return_value = ZEND_THIS; - _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced); - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); - } + breakiterator_object_create(object, rbbi, false); } U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRules) @@ -125,8 +105,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRules) if (!u8str) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), - "rbbi_hash_code: Error converting result to UTF-8 string", - 0); + "Error converting result to UTF-8 string"); RETURN_FALSE; } RETVAL_STR(u8str); @@ -164,8 +143,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getRuleStatusVec) BREAKITER_ERROR_CODE(bio)); if (U_FAILURE(BREAKITER_ERROR_CODE(bio))) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), - "rbbi_get_rule_status_vec: failed obtaining the status values", - 0); + "failed obtaining the status values"); RETURN_FALSE; } @@ -189,8 +167,7 @@ U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, getBinaryRules) if (rules_len > INT_MAX - 1) { intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio), - "rbbi_get_binary_rules: the rules are too large", - 0); + "the rules are too large"); RETURN_FALSE; } diff --git a/ext/intl/calendar/calendar.stub.php b/ext/intl/calendar/calendar.stub.php index 078ecb0c2daa..56602da0ec22 100644 --- a/ext/intl/calendar/calendar.stub.php +++ b/ext/intl/calendar/calendar.stub.php @@ -90,11 +90,10 @@ class IntlCalendar private function __construct() {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type * @alias intlcal_create_instance */ - public static function createInstance($timezone = null, ?string $locale = null): ?IntlCalendar {} + public static function createInstance(IntlTimeZone|DateTimeZone|string|null $timezone = null, ?string $locale = null): ?IntlCalendar {} /** * @tentative-return-type @@ -355,11 +354,9 @@ public function setSkippedWallTimeOption(int $option): true {} public function setTime(float $timestamp): bool {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type - * @alias intlcal_set_time_zone */ - public function setTimeZone($timezone): bool {} + public function setTimeZone(IntlTimeZone|DateTimeZone|string|null $timezone): bool {} /** * @tentative-return-type diff --git a/ext/intl/calendar/calendar_arginfo.h b/ext/intl/calendar/calendar_arginfo.h index 9e050539b2e8..291283309acc 100644 --- a/ext/intl/calendar/calendar_arginfo.h +++ b/ext/intl/calendar/calendar_arginfo.h @@ -1,11 +1,11 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: c014b88c9b6aa145ea20cc1f3fd719fe9f3d6966 */ +/* This is a generated file, edit calendar.stub.php instead. + * Stub hash: 2fc12d1fde65efbec4305f4934a3f4b25282a552 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlCalendar___construct, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlCalendar_createInstance, 0, 0, IntlCalendar, 1) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -165,7 +165,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlCalendar_set ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlCalendar_setTimeZone, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_IntlCalendar_toDateTime, 0, 0, DateTime, MAY_BE_FALSE) @@ -249,7 +249,7 @@ ZEND_FUNCTION(intlcal_set_lenient); ZEND_FUNCTION(intlcal_set_repeated_wall_time_option); ZEND_FUNCTION(intlcal_set_skipped_wall_time_option); ZEND_FUNCTION(intlcal_set_time); -ZEND_FUNCTION(intlcal_set_time_zone); +ZEND_METHOD(IntlCalendar, setTimeZone); ZEND_FUNCTION(intlcal_to_date_time); ZEND_METHOD(IntlGregorianCalendar, createFromDate); ZEND_METHOD(IntlGregorianCalendar, createFromDateTime); @@ -305,7 +305,7 @@ static const zend_function_entry class_IntlCalendar_methods[] = { ZEND_RAW_FENTRY("setRepeatedWallTimeOption", zif_intlcal_set_repeated_wall_time_option, arginfo_class_IntlCalendar_setRepeatedWallTimeOption, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("setSkippedWallTimeOption", zif_intlcal_set_skipped_wall_time_option, arginfo_class_IntlCalendar_setSkippedWallTimeOption, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("setTime", zif_intlcal_set_time, arginfo_class_IntlCalendar_setTime, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("setTimeZone", zif_intlcal_set_time_zone, arginfo_class_IntlCalendar_setTimeZone, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_ME(IntlCalendar, setTimeZone, arginfo_class_IntlCalendar_setTimeZone, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("toDateTime", zif_intlcal_to_date_time, arginfo_class_IntlCalendar_toDateTime, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_FE_END }; @@ -329,237 +329,237 @@ static zend_class_entry *register_class_IntlCalendar(void) zval const_FIELD_ERA_value; ZVAL_LONG(&const_FIELD_ERA_value, UCAL_ERA); - zend_string *const_FIELD_ERA_name = zend_string_init_interned("FIELD_ERA", sizeof("FIELD_ERA") - 1, 1); + zend_string *const_FIELD_ERA_name = zend_string_init_interned("FIELD_ERA", sizeof("FIELD_ERA") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_ERA_name, &const_FIELD_ERA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_ERA_name); + zend_string_release_ex(const_FIELD_ERA_name, true); zval const_FIELD_YEAR_value; ZVAL_LONG(&const_FIELD_YEAR_value, UCAL_YEAR); - zend_string *const_FIELD_YEAR_name = zend_string_init_interned("FIELD_YEAR", sizeof("FIELD_YEAR") - 1, 1); + zend_string *const_FIELD_YEAR_name = zend_string_init_interned("FIELD_YEAR", sizeof("FIELD_YEAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_YEAR_name, &const_FIELD_YEAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_YEAR_name); + zend_string_release_ex(const_FIELD_YEAR_name, true); zval const_FIELD_MONTH_value; ZVAL_LONG(&const_FIELD_MONTH_value, UCAL_MONTH); - zend_string *const_FIELD_MONTH_name = zend_string_init_interned("FIELD_MONTH", sizeof("FIELD_MONTH") - 1, 1); + zend_string *const_FIELD_MONTH_name = zend_string_init_interned("FIELD_MONTH", sizeof("FIELD_MONTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_MONTH_name, &const_FIELD_MONTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_MONTH_name); + zend_string_release_ex(const_FIELD_MONTH_name, true); zval const_FIELD_WEEK_OF_YEAR_value; ZVAL_LONG(&const_FIELD_WEEK_OF_YEAR_value, UCAL_WEEK_OF_YEAR); - zend_string *const_FIELD_WEEK_OF_YEAR_name = zend_string_init_interned("FIELD_WEEK_OF_YEAR", sizeof("FIELD_WEEK_OF_YEAR") - 1, 1); + zend_string *const_FIELD_WEEK_OF_YEAR_name = zend_string_init_interned("FIELD_WEEK_OF_YEAR", sizeof("FIELD_WEEK_OF_YEAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_WEEK_OF_YEAR_name, &const_FIELD_WEEK_OF_YEAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_WEEK_OF_YEAR_name); + zend_string_release_ex(const_FIELD_WEEK_OF_YEAR_name, true); zval const_FIELD_WEEK_OF_MONTH_value; ZVAL_LONG(&const_FIELD_WEEK_OF_MONTH_value, UCAL_WEEK_OF_MONTH); - zend_string *const_FIELD_WEEK_OF_MONTH_name = zend_string_init_interned("FIELD_WEEK_OF_MONTH", sizeof("FIELD_WEEK_OF_MONTH") - 1, 1); + zend_string *const_FIELD_WEEK_OF_MONTH_name = zend_string_init_interned("FIELD_WEEK_OF_MONTH", sizeof("FIELD_WEEK_OF_MONTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_WEEK_OF_MONTH_name, &const_FIELD_WEEK_OF_MONTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_WEEK_OF_MONTH_name); + zend_string_release_ex(const_FIELD_WEEK_OF_MONTH_name, true); zval const_FIELD_DATE_value; ZVAL_LONG(&const_FIELD_DATE_value, UCAL_DATE); - zend_string *const_FIELD_DATE_name = zend_string_init_interned("FIELD_DATE", sizeof("FIELD_DATE") - 1, 1); + zend_string *const_FIELD_DATE_name = zend_string_init_interned("FIELD_DATE", sizeof("FIELD_DATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_DATE_name, &const_FIELD_DATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_DATE_name); + zend_string_release_ex(const_FIELD_DATE_name, true); zval const_FIELD_DAY_OF_YEAR_value; ZVAL_LONG(&const_FIELD_DAY_OF_YEAR_value, UCAL_DAY_OF_YEAR); - zend_string *const_FIELD_DAY_OF_YEAR_name = zend_string_init_interned("FIELD_DAY_OF_YEAR", sizeof("FIELD_DAY_OF_YEAR") - 1, 1); + zend_string *const_FIELD_DAY_OF_YEAR_name = zend_string_init_interned("FIELD_DAY_OF_YEAR", sizeof("FIELD_DAY_OF_YEAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_DAY_OF_YEAR_name, &const_FIELD_DAY_OF_YEAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_DAY_OF_YEAR_name); + zend_string_release_ex(const_FIELD_DAY_OF_YEAR_name, true); zval const_FIELD_DAY_OF_WEEK_value; ZVAL_LONG(&const_FIELD_DAY_OF_WEEK_value, UCAL_DAY_OF_WEEK); - zend_string *const_FIELD_DAY_OF_WEEK_name = zend_string_init_interned("FIELD_DAY_OF_WEEK", sizeof("FIELD_DAY_OF_WEEK") - 1, 1); + zend_string *const_FIELD_DAY_OF_WEEK_name = zend_string_init_interned("FIELD_DAY_OF_WEEK", sizeof("FIELD_DAY_OF_WEEK") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_DAY_OF_WEEK_name, &const_FIELD_DAY_OF_WEEK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_DAY_OF_WEEK_name); + zend_string_release_ex(const_FIELD_DAY_OF_WEEK_name, true); zval const_FIELD_DAY_OF_WEEK_IN_MONTH_value; ZVAL_LONG(&const_FIELD_DAY_OF_WEEK_IN_MONTH_value, UCAL_DAY_OF_WEEK_IN_MONTH); - zend_string *const_FIELD_DAY_OF_WEEK_IN_MONTH_name = zend_string_init_interned("FIELD_DAY_OF_WEEK_IN_MONTH", sizeof("FIELD_DAY_OF_WEEK_IN_MONTH") - 1, 1); + zend_string *const_FIELD_DAY_OF_WEEK_IN_MONTH_name = zend_string_init_interned("FIELD_DAY_OF_WEEK_IN_MONTH", sizeof("FIELD_DAY_OF_WEEK_IN_MONTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_DAY_OF_WEEK_IN_MONTH_name, &const_FIELD_DAY_OF_WEEK_IN_MONTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_DAY_OF_WEEK_IN_MONTH_name); + zend_string_release_ex(const_FIELD_DAY_OF_WEEK_IN_MONTH_name, true); zval const_FIELD_AM_PM_value; ZVAL_LONG(&const_FIELD_AM_PM_value, UCAL_AM_PM); - zend_string *const_FIELD_AM_PM_name = zend_string_init_interned("FIELD_AM_PM", sizeof("FIELD_AM_PM") - 1, 1); + zend_string *const_FIELD_AM_PM_name = zend_string_init_interned("FIELD_AM_PM", sizeof("FIELD_AM_PM") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_AM_PM_name, &const_FIELD_AM_PM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_AM_PM_name); + zend_string_release_ex(const_FIELD_AM_PM_name, true); zval const_FIELD_HOUR_value; ZVAL_LONG(&const_FIELD_HOUR_value, UCAL_HOUR); - zend_string *const_FIELD_HOUR_name = zend_string_init_interned("FIELD_HOUR", sizeof("FIELD_HOUR") - 1, 1); + zend_string *const_FIELD_HOUR_name = zend_string_init_interned("FIELD_HOUR", sizeof("FIELD_HOUR") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_HOUR_name, &const_FIELD_HOUR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_HOUR_name); + zend_string_release_ex(const_FIELD_HOUR_name, true); zval const_FIELD_HOUR_OF_DAY_value; ZVAL_LONG(&const_FIELD_HOUR_OF_DAY_value, UCAL_HOUR_OF_DAY); - zend_string *const_FIELD_HOUR_OF_DAY_name = zend_string_init_interned("FIELD_HOUR_OF_DAY", sizeof("FIELD_HOUR_OF_DAY") - 1, 1); + zend_string *const_FIELD_HOUR_OF_DAY_name = zend_string_init_interned("FIELD_HOUR_OF_DAY", sizeof("FIELD_HOUR_OF_DAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_HOUR_OF_DAY_name, &const_FIELD_HOUR_OF_DAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_HOUR_OF_DAY_name); + zend_string_release_ex(const_FIELD_HOUR_OF_DAY_name, true); zval const_FIELD_MINUTE_value; ZVAL_LONG(&const_FIELD_MINUTE_value, UCAL_MINUTE); - zend_string *const_FIELD_MINUTE_name = zend_string_init_interned("FIELD_MINUTE", sizeof("FIELD_MINUTE") - 1, 1); + zend_string *const_FIELD_MINUTE_name = zend_string_init_interned("FIELD_MINUTE", sizeof("FIELD_MINUTE") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_MINUTE_name, &const_FIELD_MINUTE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_MINUTE_name); + zend_string_release_ex(const_FIELD_MINUTE_name, true); zval const_FIELD_SECOND_value; ZVAL_LONG(&const_FIELD_SECOND_value, UCAL_SECOND); - zend_string *const_FIELD_SECOND_name = zend_string_init_interned("FIELD_SECOND", sizeof("FIELD_SECOND") - 1, 1); + zend_string *const_FIELD_SECOND_name = zend_string_init_interned("FIELD_SECOND", sizeof("FIELD_SECOND") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_SECOND_name, &const_FIELD_SECOND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_SECOND_name); + zend_string_release_ex(const_FIELD_SECOND_name, true); zval const_FIELD_MILLISECOND_value; ZVAL_LONG(&const_FIELD_MILLISECOND_value, UCAL_MILLISECOND); - zend_string *const_FIELD_MILLISECOND_name = zend_string_init_interned("FIELD_MILLISECOND", sizeof("FIELD_MILLISECOND") - 1, 1); + zend_string *const_FIELD_MILLISECOND_name = zend_string_init_interned("FIELD_MILLISECOND", sizeof("FIELD_MILLISECOND") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_MILLISECOND_name, &const_FIELD_MILLISECOND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_MILLISECOND_name); + zend_string_release_ex(const_FIELD_MILLISECOND_name, true); zval const_FIELD_ZONE_OFFSET_value; ZVAL_LONG(&const_FIELD_ZONE_OFFSET_value, UCAL_ZONE_OFFSET); - zend_string *const_FIELD_ZONE_OFFSET_name = zend_string_init_interned("FIELD_ZONE_OFFSET", sizeof("FIELD_ZONE_OFFSET") - 1, 1); + zend_string *const_FIELD_ZONE_OFFSET_name = zend_string_init_interned("FIELD_ZONE_OFFSET", sizeof("FIELD_ZONE_OFFSET") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_ZONE_OFFSET_name, &const_FIELD_ZONE_OFFSET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_ZONE_OFFSET_name); + zend_string_release_ex(const_FIELD_ZONE_OFFSET_name, true); zval const_FIELD_DST_OFFSET_value; ZVAL_LONG(&const_FIELD_DST_OFFSET_value, UCAL_DST_OFFSET); - zend_string *const_FIELD_DST_OFFSET_name = zend_string_init_interned("FIELD_DST_OFFSET", sizeof("FIELD_DST_OFFSET") - 1, 1); + zend_string *const_FIELD_DST_OFFSET_name = zend_string_init_interned("FIELD_DST_OFFSET", sizeof("FIELD_DST_OFFSET") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_DST_OFFSET_name, &const_FIELD_DST_OFFSET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_DST_OFFSET_name); + zend_string_release_ex(const_FIELD_DST_OFFSET_name, true); zval const_FIELD_YEAR_WOY_value; ZVAL_LONG(&const_FIELD_YEAR_WOY_value, UCAL_YEAR_WOY); - zend_string *const_FIELD_YEAR_WOY_name = zend_string_init_interned("FIELD_YEAR_WOY", sizeof("FIELD_YEAR_WOY") - 1, 1); + zend_string *const_FIELD_YEAR_WOY_name = zend_string_init_interned("FIELD_YEAR_WOY", sizeof("FIELD_YEAR_WOY") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_YEAR_WOY_name, &const_FIELD_YEAR_WOY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_YEAR_WOY_name); + zend_string_release_ex(const_FIELD_YEAR_WOY_name, true); zval const_FIELD_DOW_LOCAL_value; ZVAL_LONG(&const_FIELD_DOW_LOCAL_value, UCAL_DOW_LOCAL); - zend_string *const_FIELD_DOW_LOCAL_name = zend_string_init_interned("FIELD_DOW_LOCAL", sizeof("FIELD_DOW_LOCAL") - 1, 1); + zend_string *const_FIELD_DOW_LOCAL_name = zend_string_init_interned("FIELD_DOW_LOCAL", sizeof("FIELD_DOW_LOCAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_DOW_LOCAL_name, &const_FIELD_DOW_LOCAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_DOW_LOCAL_name); + zend_string_release_ex(const_FIELD_DOW_LOCAL_name, true); zval const_FIELD_EXTENDED_YEAR_value; ZVAL_LONG(&const_FIELD_EXTENDED_YEAR_value, UCAL_EXTENDED_YEAR); - zend_string *const_FIELD_EXTENDED_YEAR_name = zend_string_init_interned("FIELD_EXTENDED_YEAR", sizeof("FIELD_EXTENDED_YEAR") - 1, 1); + zend_string *const_FIELD_EXTENDED_YEAR_name = zend_string_init_interned("FIELD_EXTENDED_YEAR", sizeof("FIELD_EXTENDED_YEAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_EXTENDED_YEAR_name, &const_FIELD_EXTENDED_YEAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_EXTENDED_YEAR_name); + zend_string_release_ex(const_FIELD_EXTENDED_YEAR_name, true); zval const_FIELD_JULIAN_DAY_value; ZVAL_LONG(&const_FIELD_JULIAN_DAY_value, UCAL_JULIAN_DAY); - zend_string *const_FIELD_JULIAN_DAY_name = zend_string_init_interned("FIELD_JULIAN_DAY", sizeof("FIELD_JULIAN_DAY") - 1, 1); + zend_string *const_FIELD_JULIAN_DAY_name = zend_string_init_interned("FIELD_JULIAN_DAY", sizeof("FIELD_JULIAN_DAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_JULIAN_DAY_name, &const_FIELD_JULIAN_DAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_JULIAN_DAY_name); + zend_string_release_ex(const_FIELD_JULIAN_DAY_name, true); zval const_FIELD_MILLISECONDS_IN_DAY_value; ZVAL_LONG(&const_FIELD_MILLISECONDS_IN_DAY_value, UCAL_MILLISECONDS_IN_DAY); - zend_string *const_FIELD_MILLISECONDS_IN_DAY_name = zend_string_init_interned("FIELD_MILLISECONDS_IN_DAY", sizeof("FIELD_MILLISECONDS_IN_DAY") - 1, 1); + zend_string *const_FIELD_MILLISECONDS_IN_DAY_name = zend_string_init_interned("FIELD_MILLISECONDS_IN_DAY", sizeof("FIELD_MILLISECONDS_IN_DAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_MILLISECONDS_IN_DAY_name, &const_FIELD_MILLISECONDS_IN_DAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_MILLISECONDS_IN_DAY_name); + zend_string_release_ex(const_FIELD_MILLISECONDS_IN_DAY_name, true); zval const_FIELD_IS_LEAP_MONTH_value; ZVAL_LONG(&const_FIELD_IS_LEAP_MONTH_value, UCAL_IS_LEAP_MONTH); - zend_string *const_FIELD_IS_LEAP_MONTH_name = zend_string_init_interned("FIELD_IS_LEAP_MONTH", sizeof("FIELD_IS_LEAP_MONTH") - 1, 1); + zend_string *const_FIELD_IS_LEAP_MONTH_name = zend_string_init_interned("FIELD_IS_LEAP_MONTH", sizeof("FIELD_IS_LEAP_MONTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_IS_LEAP_MONTH_name, &const_FIELD_IS_LEAP_MONTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_IS_LEAP_MONTH_name); + zend_string_release_ex(const_FIELD_IS_LEAP_MONTH_name, true); zval const_FIELD_FIELD_COUNT_value; ZVAL_LONG(&const_FIELD_FIELD_COUNT_value, UCAL_FIELD_COUNT); - zend_string *const_FIELD_FIELD_COUNT_name = zend_string_init_interned("FIELD_FIELD_COUNT", sizeof("FIELD_FIELD_COUNT") - 1, 1); + zend_string *const_FIELD_FIELD_COUNT_name = zend_string_init_interned("FIELD_FIELD_COUNT", sizeof("FIELD_FIELD_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_FIELD_COUNT_name, &const_FIELD_FIELD_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_FIELD_COUNT_name); + zend_string_release_ex(const_FIELD_FIELD_COUNT_name, true); zval const_FIELD_DAY_OF_MONTH_value; ZVAL_LONG(&const_FIELD_DAY_OF_MONTH_value, UCAL_DAY_OF_MONTH); - zend_string *const_FIELD_DAY_OF_MONTH_name = zend_string_init_interned("FIELD_DAY_OF_MONTH", sizeof("FIELD_DAY_OF_MONTH") - 1, 1); + zend_string *const_FIELD_DAY_OF_MONTH_name = zend_string_init_interned("FIELD_DAY_OF_MONTH", sizeof("FIELD_DAY_OF_MONTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_FIELD_DAY_OF_MONTH_name, &const_FIELD_DAY_OF_MONTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FIELD_DAY_OF_MONTH_name); + zend_string_release_ex(const_FIELD_DAY_OF_MONTH_name, true); zval const_DOW_SUNDAY_value; ZVAL_LONG(&const_DOW_SUNDAY_value, UCAL_SUNDAY); - zend_string *const_DOW_SUNDAY_name = zend_string_init_interned("DOW_SUNDAY", sizeof("DOW_SUNDAY") - 1, 1); + zend_string *const_DOW_SUNDAY_name = zend_string_init_interned("DOW_SUNDAY", sizeof("DOW_SUNDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_SUNDAY_name, &const_DOW_SUNDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_SUNDAY_name); + zend_string_release_ex(const_DOW_SUNDAY_name, true); zval const_DOW_MONDAY_value; ZVAL_LONG(&const_DOW_MONDAY_value, UCAL_MONDAY); - zend_string *const_DOW_MONDAY_name = zend_string_init_interned("DOW_MONDAY", sizeof("DOW_MONDAY") - 1, 1); + zend_string *const_DOW_MONDAY_name = zend_string_init_interned("DOW_MONDAY", sizeof("DOW_MONDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_MONDAY_name, &const_DOW_MONDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_MONDAY_name); + zend_string_release_ex(const_DOW_MONDAY_name, true); zval const_DOW_TUESDAY_value; ZVAL_LONG(&const_DOW_TUESDAY_value, UCAL_TUESDAY); - zend_string *const_DOW_TUESDAY_name = zend_string_init_interned("DOW_TUESDAY", sizeof("DOW_TUESDAY") - 1, 1); + zend_string *const_DOW_TUESDAY_name = zend_string_init_interned("DOW_TUESDAY", sizeof("DOW_TUESDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_TUESDAY_name, &const_DOW_TUESDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_TUESDAY_name); + zend_string_release_ex(const_DOW_TUESDAY_name, true); zval const_DOW_WEDNESDAY_value; ZVAL_LONG(&const_DOW_WEDNESDAY_value, UCAL_WEDNESDAY); - zend_string *const_DOW_WEDNESDAY_name = zend_string_init_interned("DOW_WEDNESDAY", sizeof("DOW_WEDNESDAY") - 1, 1); + zend_string *const_DOW_WEDNESDAY_name = zend_string_init_interned("DOW_WEDNESDAY", sizeof("DOW_WEDNESDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_WEDNESDAY_name, &const_DOW_WEDNESDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_WEDNESDAY_name); + zend_string_release_ex(const_DOW_WEDNESDAY_name, true); zval const_DOW_THURSDAY_value; ZVAL_LONG(&const_DOW_THURSDAY_value, UCAL_THURSDAY); - zend_string *const_DOW_THURSDAY_name = zend_string_init_interned("DOW_THURSDAY", sizeof("DOW_THURSDAY") - 1, 1); + zend_string *const_DOW_THURSDAY_name = zend_string_init_interned("DOW_THURSDAY", sizeof("DOW_THURSDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_THURSDAY_name, &const_DOW_THURSDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_THURSDAY_name); + zend_string_release_ex(const_DOW_THURSDAY_name, true); zval const_DOW_FRIDAY_value; ZVAL_LONG(&const_DOW_FRIDAY_value, UCAL_FRIDAY); - zend_string *const_DOW_FRIDAY_name = zend_string_init_interned("DOW_FRIDAY", sizeof("DOW_FRIDAY") - 1, 1); + zend_string *const_DOW_FRIDAY_name = zend_string_init_interned("DOW_FRIDAY", sizeof("DOW_FRIDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_FRIDAY_name, &const_DOW_FRIDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_FRIDAY_name); + zend_string_release_ex(const_DOW_FRIDAY_name, true); zval const_DOW_SATURDAY_value; ZVAL_LONG(&const_DOW_SATURDAY_value, UCAL_SATURDAY); - zend_string *const_DOW_SATURDAY_name = zend_string_init_interned("DOW_SATURDAY", sizeof("DOW_SATURDAY") - 1, 1); + zend_string *const_DOW_SATURDAY_name = zend_string_init_interned("DOW_SATURDAY", sizeof("DOW_SATURDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_SATURDAY_name, &const_DOW_SATURDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_SATURDAY_name); + zend_string_release_ex(const_DOW_SATURDAY_name, true); zval const_DOW_TYPE_WEEKDAY_value; ZVAL_LONG(&const_DOW_TYPE_WEEKDAY_value, UCAL_WEEKDAY); - zend_string *const_DOW_TYPE_WEEKDAY_name = zend_string_init_interned("DOW_TYPE_WEEKDAY", sizeof("DOW_TYPE_WEEKDAY") - 1, 1); + zend_string *const_DOW_TYPE_WEEKDAY_name = zend_string_init_interned("DOW_TYPE_WEEKDAY", sizeof("DOW_TYPE_WEEKDAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_TYPE_WEEKDAY_name, &const_DOW_TYPE_WEEKDAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_TYPE_WEEKDAY_name); + zend_string_release_ex(const_DOW_TYPE_WEEKDAY_name, true); zval const_DOW_TYPE_WEEKEND_value; ZVAL_LONG(&const_DOW_TYPE_WEEKEND_value, UCAL_WEEKEND); - zend_string *const_DOW_TYPE_WEEKEND_name = zend_string_init_interned("DOW_TYPE_WEEKEND", sizeof("DOW_TYPE_WEEKEND") - 1, 1); + zend_string *const_DOW_TYPE_WEEKEND_name = zend_string_init_interned("DOW_TYPE_WEEKEND", sizeof("DOW_TYPE_WEEKEND") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_TYPE_WEEKEND_name, &const_DOW_TYPE_WEEKEND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_TYPE_WEEKEND_name); + zend_string_release_ex(const_DOW_TYPE_WEEKEND_name, true); zval const_DOW_TYPE_WEEKEND_OFFSET_value; ZVAL_LONG(&const_DOW_TYPE_WEEKEND_OFFSET_value, UCAL_WEEKEND_ONSET); - zend_string *const_DOW_TYPE_WEEKEND_OFFSET_name = zend_string_init_interned("DOW_TYPE_WEEKEND_OFFSET", sizeof("DOW_TYPE_WEEKEND_OFFSET") - 1, 1); + zend_string *const_DOW_TYPE_WEEKEND_OFFSET_name = zend_string_init_interned("DOW_TYPE_WEEKEND_OFFSET", sizeof("DOW_TYPE_WEEKEND_OFFSET") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_TYPE_WEEKEND_OFFSET_name, &const_DOW_TYPE_WEEKEND_OFFSET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_TYPE_WEEKEND_OFFSET_name); + zend_string_release_ex(const_DOW_TYPE_WEEKEND_OFFSET_name, true); zval const_DOW_TYPE_WEEKEND_CEASE_value; ZVAL_LONG(&const_DOW_TYPE_WEEKEND_CEASE_value, UCAL_WEEKEND_CEASE); - zend_string *const_DOW_TYPE_WEEKEND_CEASE_name = zend_string_init_interned("DOW_TYPE_WEEKEND_CEASE", sizeof("DOW_TYPE_WEEKEND_CEASE") - 1, 1); + zend_string *const_DOW_TYPE_WEEKEND_CEASE_name = zend_string_init_interned("DOW_TYPE_WEEKEND_CEASE", sizeof("DOW_TYPE_WEEKEND_CEASE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DOW_TYPE_WEEKEND_CEASE_name, &const_DOW_TYPE_WEEKEND_CEASE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DOW_TYPE_WEEKEND_CEASE_name); + zend_string_release_ex(const_DOW_TYPE_WEEKEND_CEASE_name, true); zval const_WALLTIME_FIRST_value; ZVAL_LONG(&const_WALLTIME_FIRST_value, UCAL_WALLTIME_FIRST); - zend_string *const_WALLTIME_FIRST_name = zend_string_init_interned("WALLTIME_FIRST", sizeof("WALLTIME_FIRST") - 1, 1); + zend_string *const_WALLTIME_FIRST_name = zend_string_init_interned("WALLTIME_FIRST", sizeof("WALLTIME_FIRST") - 1, true); zend_declare_typed_class_constant(class_entry, const_WALLTIME_FIRST_name, &const_WALLTIME_FIRST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WALLTIME_FIRST_name); + zend_string_release_ex(const_WALLTIME_FIRST_name, true); zval const_WALLTIME_LAST_value; ZVAL_LONG(&const_WALLTIME_LAST_value, UCAL_WALLTIME_LAST); - zend_string *const_WALLTIME_LAST_name = zend_string_init_interned("WALLTIME_LAST", sizeof("WALLTIME_LAST") - 1, 1); + zend_string *const_WALLTIME_LAST_name = zend_string_init_interned("WALLTIME_LAST", sizeof("WALLTIME_LAST") - 1, true); zend_declare_typed_class_constant(class_entry, const_WALLTIME_LAST_name, &const_WALLTIME_LAST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WALLTIME_LAST_name); + zend_string_release_ex(const_WALLTIME_LAST_name, true); zval const_WALLTIME_NEXT_VALID_value; ZVAL_LONG(&const_WALLTIME_NEXT_VALID_value, UCAL_WALLTIME_NEXT_VALID); - zend_string *const_WALLTIME_NEXT_VALID_name = zend_string_init_interned("WALLTIME_NEXT_VALID", sizeof("WALLTIME_NEXT_VALID") - 1, 1); + zend_string *const_WALLTIME_NEXT_VALID_name = zend_string_init_interned("WALLTIME_NEXT_VALID", sizeof("WALLTIME_NEXT_VALID") - 1, true); zend_declare_typed_class_constant(class_entry, const_WALLTIME_NEXT_VALID_name, &const_WALLTIME_NEXT_VALID_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WALLTIME_NEXT_VALID_name); + zend_string_release_ex(const_WALLTIME_NEXT_VALID_name, true); return class_entry; } diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp index f0582c64d2b2..63b203d08d44 100644 --- a/ext/intl/calendar/calendar_class.cpp +++ b/ext/intl/calendar/calendar_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -71,13 +71,13 @@ U_CFUNC void calendar_object_construct(zval *object, CALENDAR_METHOD_FETCH_OBJECT_NO_CHECK; //populate to from object assert(co->ucal == NULL); - co->ucal = (Calendar*)calendar; + co->ucal = calendar; } /* {{{ clone handler for Calendar */ static zend_object *Calendar_clone_obj(zend_object *object) { - Calendar_object *co_orig = php_intl_calendar_fetch_object(object); + const Calendar_object *co_orig = php_intl_calendar_fetch_object(object); zend_object *ret_val = Calendar_ce_ptr->create_object(object->ce); Calendar_object *co_new = php_intl_calendar_fetch_object(ret_val); @@ -256,7 +256,7 @@ void calendar_register_IntlCalendar_class(void) memcpy( &Calendar_handlers, &std_object_handlers, sizeof Calendar_handlers); - Calendar_handlers.offset = XtOffsetOf(Calendar_object, zo); + Calendar_handlers.offset = offsetof(Calendar_object, zo); Calendar_handlers.clone_obj = Calendar_clone_obj; Calendar_handlers.get_debug_info = Calendar_get_debug_info; Calendar_handlers.free_obj = Calendar_objects_free; diff --git a/ext/intl/calendar/calendar_class.h b/ext/intl/calendar/calendar_class.h index 167bded8f31b..9f8040c81893 100644 --- a/ext/intl/calendar/calendar_class.h +++ b/ext/intl/calendar/calendar_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -39,7 +39,7 @@ typedef struct { } Calendar_object; static inline Calendar_object *php_intl_calendar_fetch_object(zend_object *obj) { - return (Calendar_object *)((char*)(obj) - XtOffsetOf(Calendar_object, zo)); + return ZEND_CONTAINER_OF(obj, Calendar_object, zo); } #define Z_INTL_CALENDAR_P(zv) php_intl_calendar_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index 9b7a37c0df52..fe4749d6d62d 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -72,22 +72,21 @@ U_CFUNC PHP_METHOD(IntlCalendar, __construct) U_CFUNC PHP_FUNCTION(intlcal_create_instance) { - zval *zv_timezone = NULL; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; char *locale_str = NULL; size_t locale_len = 0; - TimeZone *timeZone; UErrorCode status = U_ZERO_ERROR; intl_error_reset(NULL); ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(zv_timezone) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) Z_PARAM_STRING_OR_NULL(locale_str, locale_len) ZEND_PARSE_PARAMETERS_END(); - timeZone = timezone_process_timezone_argument(zv_timezone, NULL, - "intlcal_create_instance"); - if (timeZone == NULL) { + TimeZone *timeZone = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr, 1); + if (timeZone == nullptr) { RETURN_NULL(); } @@ -99,7 +98,7 @@ U_CFUNC PHP_FUNCTION(intlcal_create_instance) Locale::createFromName(locale_str), status); if (UNEXPECTED(cal == NULL)) { delete timeZone; - intl_error_set(NULL, status, "Error creating ICU Calendar object", 0); + intl_error_set(NULL, status, "Error creating ICU Calendar object"); RETURN_NULL(); } @@ -179,8 +178,8 @@ U_CFUNC PHP_FUNCTION(intlcal_get_keyword_values_for_locale) Locale::createFromName(locale), (UBool)commonly_used, status); if (se == NULL) { - intl_error_set(NULL, status, "intlcal_get_keyword_values_for_locale: " - "error calling underlying method", 0); + intl_error_set(NULL, status, + "error calling underlying method"); RETURN_FALSE; } @@ -204,7 +203,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_available_locales) int32_t count; const Locale *availLocales = Calendar::getAvailableLocales(count); - array_init(return_value); + array_init_size(return_value, count); for (int i = 0; i < count; i++) { Locale locale = availLocales[i]; add_next_index_string(return_value, locale.getName()); @@ -252,8 +251,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_time) CALENDAR_METHOD_FETCH_OBJECT; UDate result = co->ucal->getTime(CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_time: error calling ICU Calendar::getTime"); + INTL_METHOD_CHECK_STATUS(co, "error calling ICU Calendar::getTime"); RETURN_DOUBLE((double)result); } @@ -293,31 +291,33 @@ U_CFUNC PHP_FUNCTION(intlcal_add) CALENDAR_METHOD_FETCH_OBJECT; co->ucal->add((UCalendarDateFields)field, (int32_t)amount, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_add: Call to underlying method failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to underlying method failed"); RETURN_TRUE; } +/* {{{ Set formatter's timezone. */ U_CFUNC PHP_FUNCTION(intlcal_set_time_zone) { - zval *zv_timezone; - TimeZone *timeZone; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; + CALENDAR_METHOD_INIT_VARS; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), - "Oz!", &object, Calendar_ce_ptr, &zv_timezone) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(object, Calendar_ce_ptr) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); CALENDAR_METHOD_FETCH_OBJECT; - if (zv_timezone == NULL) { + if (timezone_object == nullptr && timezone_string == nullptr) { RETURN_TRUE; /* the method does nothing if passed null */ } - timeZone = timezone_process_timezone_argument(zv_timezone, - CALENDAR_ERROR_P(co), "intlcal_set_time_zone"); - if (timeZone == NULL) { + TimeZone *timeZone = timezone_process_timezone_argument( + timezone_object, timezone_string, CALENDAR_ERROR_P(co), 2); + if (timeZone == nullptr) { RETURN_FALSE; } @@ -326,6 +326,34 @@ U_CFUNC PHP_FUNCTION(intlcal_set_time_zone) RETURN_TRUE; } +U_CFUNC PHP_METHOD(IntlCalendar, setTimeZone) +{ + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; + + CALENDAR_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); + + object = ZEND_THIS; + CALENDAR_METHOD_FETCH_OBJECT; + + if (timezone_object == nullptr && timezone_string == nullptr) { + RETURN_TRUE; /* the method does nothing if passed null */ + } + + TimeZone *timeZone = timezone_process_timezone_argument( + timezone_object, timezone_string, CALENDAR_ERROR_P(co), 1); + if (timeZone == nullptr) { + RETURN_FALSE; + } + + co->ucal->adoptTimeZone(timeZone); + + RETURN_TRUE; +} static void _php_intlcal_before_after( UBool (Calendar::*func)(const Calendar&, UErrorCode&) const, @@ -345,12 +373,12 @@ static void _php_intlcal_before_after( when_co = Z_INTL_CALENDAR_P(when_object); if (when_co->ucal == NULL) { - zend_argument_error(NULL, 2, "is uninitialized"); + zend_argument_error(NULL, hasThis() ? 1 : 2, "is uninitialized"); RETURN_THROWS(); } UBool res = (co->ucal->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_before/after: Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)res); } @@ -391,8 +419,8 @@ U_CFUNC PHP_FUNCTION(intlcal_set) } for (int i = 0; i < arg_num; i++) { - /* Arguments start at 1 */ - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 1); + /* Count from intlcal_set($calendar, ...), so date/time arguments start at #2. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 2); } CALENDAR_METHOD_FETCH_OBJECT; @@ -427,9 +455,10 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDate) RETURN_THROWS(); } - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); + /* These method-only APIs parse the object first, so the API argument positions are offset by +1. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4); CALENDAR_METHOD_FETCH_OBJECT; @@ -450,18 +479,19 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDateTime) RETURN_THROWS(); } - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 4); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 5); + /* These method-only APIs parse the object first, so the API argument positions are offset by +1. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 5); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 6); CALENDAR_METHOD_FETCH_OBJECT; if (second_is_null) { co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute); } else { - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 6); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 7); co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second); } } @@ -490,7 +520,7 @@ U_CFUNC PHP_FUNCTION(intlcal_roll) co->ucal->roll((UCalendarDateFields)field, (int32_t)value, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_roll: Error calling ICU Calendar::roll"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU Calendar::roll"); RETURN_TRUE; } @@ -536,8 +566,7 @@ U_CFUNC PHP_FUNCTION(intlcal_field_difference) int32_t result = co->ucal->fieldDifference((UDate)when, (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_field_difference: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -570,8 +599,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_day_of_week_type) int32_t result = co->ucal->getDayOfWeekType( (UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_day_of_week_type: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -588,8 +616,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_first_day_of_week) CALENDAR_METHOD_FETCH_OBJECT; int32_t result = co->ucal->getFirstDayOfWeek(CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_first_day_of_week: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -647,8 +674,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_locale) Locale locale = co->ucal->getLocale((ULocDataLocaleType)locale_type, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_locale: Call to ICU method has failed"); + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_STRING(locale.getName()); } @@ -671,8 +697,8 @@ U_CFUNC PHP_FUNCTION(intlcal_get_minimal_days_in_first_week) CALENDAR_METHOD_FETCH_OBJECT; uint8_t result = co->ucal->getMinimalDaysInFirstWeek(); - INTL_METHOD_CHECK_STATUS(co, - "intlcal_get_first_day_of_week: Call to ICU method has failed"); /* TODO Is it really a failure? */ + /* TODO Is it really a failure? */ + INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); } @@ -697,7 +723,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_time_zone) TimeZone *tz = co->ucal->getTimeZone().clone(); if (UNEXPECTED(tz == NULL)) { intl_errors_set(CALENDAR_ERROR_P(co), U_MEMORY_ALLOCATION_ERROR, - "intlcal_get_time_zone: could not clone TimeZone", 0); + "could not clone TimeZone"); RETURN_FALSE; } @@ -734,8 +760,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_weekend_transition) int32_t res = co->ucal->getWeekendTransition((UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_get_weekend_transition: " - "Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_LONG((zend_long)res); } @@ -752,8 +777,7 @@ U_CFUNC PHP_FUNCTION(intlcal_in_daylight_time) CALENDAR_METHOD_FETCH_OBJECT; UBool ret = co->ucal->inDaylightTime(CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_in_daylight_time: " - "Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)ret); } @@ -772,7 +796,7 @@ U_CFUNC PHP_FUNCTION(intlcal_is_equivalent_to) other_co = Z_INTL_CALENDAR_P(other_object); if (other_co->ucal == NULL) { - zend_argument_error(NULL, 2, "is uninitialized"); + zend_argument_error(NULL, hasThis() ? 1 : 2, "is uninitialized"); RETURN_THROWS(); } @@ -829,8 +853,7 @@ U_CFUNC PHP_FUNCTION(intlcal_is_weekend) RETURN_BOOL((int)co->ucal->isWeekend()); } else { UBool ret = co->ucal->isWeekend((UDate)date, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_is_weekend: " - "Error calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "Error calling ICU method"); RETURN_BOOL((int)ret); } } @@ -910,12 +933,12 @@ U_CFUNC PHP_FUNCTION(intlcal_equals) CALENDAR_METHOD_FETCH_OBJECT; other_co = Z_INTL_CALENDAR_P(other_object); if (other_co->ucal == NULL) { - zend_argument_error(NULL, 2, "is uninitialized"); + zend_argument_error(NULL, hasThis() ? 1 : 2, "is uninitialized"); RETURN_THROWS(); } UBool result = co->ucal->equals(*other_co->ucal, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlcal_equals: error calling ICU Calendar::equals"); + INTL_METHOD_CHECK_STATUS(co, "error calling ICU Calendar::equals"); RETURN_BOOL((int)result); } @@ -1028,16 +1051,14 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time) datetime = php_date_obj_from_obj(date_obj); if (!datetime->time) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_from_date_time: DateTime object is unconstructed", - 0); + "DateTime object is unconstructed"); goto error; } zend_call_method_with_0_params(date_obj, php_date_get_date_ce(), NULL, "gettimestamp", &zv_timestamp); if (Z_TYPE(zv_timestamp) != IS_LONG) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_from_date_time: bad DateTime; call to " - "DateTime::getTimestamp() failed", 0); + "bad DateTime; call to DateTime::getTimestamp() failed"); zval_ptr_dtor(&zv_timestamp); goto error; } @@ -1046,7 +1067,7 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time) timeZone = TimeZone::getGMT()->clone(); } else { timeZone = timezone_convert_datetimezone(datetime->time->zone_type, - datetime, 1, NULL, "intlcal_from_date_time"); + datetime, 1, NULL); if (timeZone == NULL) { goto error; } @@ -1060,16 +1081,16 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time) Locale::createFromName(locale_str), status); if (UNEXPECTED(cal == NULL)) { delete timeZone; - intl_error_set(NULL, status, "intlcal_from_date_time: " - "error creating ICU Calendar object", 0); + intl_error_set(NULL, status, + "error creating ICU Calendar object"); goto error; } cal->setTime(((UDate)Z_LVAL(zv_timestamp)) * 1000., status); if (U_FAILURE(status)) { /* time zone was adopted by cal; should not be deleted here */ delete cal; - intl_error_set(NULL, status, "intlcal_from_date_time: " - "error creating ICU Calendar::setTime()", 0); + intl_error_set(NULL, status, + "error creating ICU Calendar::setTime()"); goto error; } @@ -1105,8 +1126,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time) if (UNEXPECTED(date > (double)U_INT64_MAX || date < (double)U_INT64_MIN)) { intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_to_date_time: The calendar date is out of the " - "range for a 64-bit integer", 0); + "The calendar date is out of the range for a 64-bit integer"); RETURN_FALSE; } @@ -1119,7 +1139,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time) /* Now get the time zone */ const TimeZone& tz = co->ucal->getTimeZone(); zval *timezone_zval = timezone_convert_to_datetimezone( - &tz, CALENDAR_ERROR_P(co), "intlcal_to_date_time", &tmp); + &tz, CALENDAR_ERROR_P(co), &tmp); if (timezone_zval == NULL) { zval_ptr_dtor(&ts_zval); RETURN_FALSE; @@ -1146,8 +1166,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time) &retval, timezone_zval); if (Z_ISUNDEF(retval) || Z_TYPE(retval) == IS_FALSE) { intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR, - "intlcal_to_date_time: call to DateTime::setTimeZone has failed", - 1); + "call to DateTime::setTimeZone has failed"); zval_ptr_dtor(return_value); RETVAL_FALSE; goto error; diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index d6b8f0602dd0..aeb728e29de1 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -17,6 +17,7 @@ #endif #include "../intl_cppshims.h" +#include #include #include @@ -46,16 +47,14 @@ using icu::StringPiece; } static inline GregorianCalendar *fetch_greg(Calendar_object *co) { - return (GregorianCalendar*)co->ucal; + return static_cast(co->ucal); } static bool set_gregorian_calendar_time_zone(GregorianCalendar *gcal, UErrorCode status) { if (U_FAILURE(status)) { intl_error_set(NULL, status, - "IntlGregorianCalendar: Error creating ICU GregorianCalendar from date", - 0 - ); + "Error creating ICU GregorianCalendar from date"); return false; } @@ -64,10 +63,8 @@ static bool set_gregorian_calendar_time_zone(GregorianCalendar *gcal, UErrorCode UnicodeString tzstr = UnicodeString::fromUTF8(StringPiece(tzinfo->name)); if (tzstr.isBogus()) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "IntlGregorianCalendar: Could not create UTF-8 string " - "from PHP's default timezone name (see date_default_timezone_get())", - 0 - ); + "Could not create UTF-8 string from PHP's default timezone " + "name (see date_default_timezone_get())"); return false; } @@ -78,10 +75,10 @@ static bool set_gregorian_calendar_time_zone(GregorianCalendar *gcal, UErrorCode return true; } -static void _php_intlgregcal_constructor_body( - INTERNAL_FUNCTION_PARAMETERS, bool is_constructor, zend_error_handling *error_handling, bool *error_handling_replaced) +static void _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) { - zval *tz_object = NULL; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; zval args_a[6], *args = &args_a[0]; char *locale = NULL; @@ -116,25 +113,28 @@ static void _php_intlgregcal_constructor_body( // argument parsing if (variant <= 2) { - if (zend_parse_parameters(MIN(ZEND_NUM_ARGS(), 2), - "|z!s!", &tz_object, &locale, &locale_len) == FAILURE) { - RETURN_THROWS(); - } - } - if (variant > 2 && zend_parse_parameters(ZEND_NUM_ARGS(), - "lll|lll", &largs[0], &largs[1], &largs[2], &largs[3], &largs[4], - &largs[5]) == FAILURE) { - RETURN_THROWS(); + /* These dummy variables are needed because the 2 param constructor allows trailing nulls... */ + zval *dummy1, *dummy2, *dummy3, *dummy4; + ZEND_PARSE_PARAMETERS_START(0, 6) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + Z_PARAM_STRING_OR_NULL(locale, locale_len) + Z_PARAM_ZVAL(dummy1) + Z_PARAM_ZVAL(dummy2) + Z_PARAM_ZVAL(dummy3) + Z_PARAM_ZVAL(dummy4) + ZEND_PARSE_PARAMETERS_END(); } - - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; + if (variant > 2 + && zend_parse_parameters(ZEND_NUM_ARGS(), "lll|lll", + &largs[0], &largs[1], &largs[2], &largs[3], &largs[4], &largs[5]) == FAILURE + ) { + RETURN_THROWS(); } // instantion of ICU object Calendar_object *co = Z_INTL_CALENDAR_P(return_value); - GregorianCalendar *gcal = NULL; + std::unique_ptr gcal; if (co->ucal) { zend_throw_error(NULL, "IntlGregorianCalendar object is already constructed"); @@ -143,9 +143,9 @@ static void _php_intlgregcal_constructor_body( if (variant <= 2) { // From timezone and locale (0 to 2 arguments) - TimeZone *tz = timezone_process_timezone_argument(tz_object, NULL, - "intlgregcal_create_instance"); - if (tz == NULL) { + TimeZone *tz = timezone_process_timezone_argument(timezone_object, timezone_string, nullptr, 1); + if (tz == nullptr) { + // TODO: Exception should always occur already? if (!EG(exception)) { zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); } @@ -159,15 +159,12 @@ static void _php_intlgregcal_constructor_body( locale = const_cast(intl_locale_get_default()); } - gcal = new GregorianCalendar(tz, Locale::createFromName(locale), - status); + gcal = std::unique_ptr(new GregorianCalendar(tz, Locale::createFromName(locale), + status)); // Should this throw? if (U_FAILURE(status)) { - intl_error_set(NULL, status, "intlgregcal_create_instance: error " - "creating ICU GregorianCalendar from time zone and locale", 0); - if (gcal) { - delete gcal; - } + intl_error_set(NULL, status, "error creating ICU " + "GregorianCalendar from time zone and locale"); delete tz; if (!is_constructor) { zval_ptr_dtor(return_value); @@ -177,26 +174,28 @@ static void _php_intlgregcal_constructor_body( } } else { // From date/time (3, 5 or 6 arguments) + GregorianCalendar *tmp; for (int i = 0; i < variant; i++) { - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], hasThis() ? (i-1) : i); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], i + 1); } if (variant == 3) { - gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], + tmp = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], status); } else if (variant == 5) { - gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], + tmp = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], status); } else if (variant == 6) { - gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], + tmp = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1], (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], (int32_t)largs[5], status); } else { ZEND_UNREACHABLE(); } - if (!set_gregorian_calendar_time_zone(gcal, status)) { - delete gcal; + gcal = std::unique_ptr(tmp); + + if (!set_gregorian_calendar_time_zone(gcal.get(), status)) { if (!is_constructor) { zval_ptr_dtor(return_value); RETVAL_NULL(); @@ -205,36 +204,34 @@ static void _php_intlgregcal_constructor_body( } } - co->ucal = gcal; + co->ucal = gcal.release(); } U_CFUNC PHP_FUNCTION(intlgregcal_create_instance) { - intl_error_reset(NULL); - object_init_ex(return_value, GregorianCalendar_ce_ptr); - _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ 0, NULL, NULL); + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ false); } U_CFUNC PHP_METHOD(IntlGregorianCalendar, __construct) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; return_value = ZEND_THIS; - _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ 1, &error_handling, &error_handling_replaced); - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); - } + _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* is_constructor */ true); + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDate) { zend_long year, month, day; UErrorCode status = U_ZERO_ERROR; - zend_error_handling error_handling; Calendar_object *co; - GregorianCalendar *gcal; + std::unique_ptr gcal; intl_error_reset(NULL); @@ -248,20 +245,22 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDate) ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); - gcal = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, status); - if (!set_gregorian_calendar_time_zone(gcal, status)) { - delete gcal; + gcal = std::unique_ptr(new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, status)); + if (!set_gregorian_calendar_time_zone(gcal.get(), status)) { + ZEND_ASSERT(EG(exception)); goto cleanup; } object_init_ex(return_value, GregorianCalendar_ce_ptr); co = Z_INTL_CALENDAR_P(return_value); - co->ucal = gcal; + co->ucal = gcal.release(); cleanup: - zend_restore_error_handling(&error_handling); + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDateTime) @@ -269,9 +268,8 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDateTime) zend_long year, month, day, hour, minute, second; bool second_is_null = 1; UErrorCode status = U_ZERO_ERROR; - zend_error_handling error_handling; Calendar_object *co; - GregorianCalendar *gcal; + GregorianCalendar *tmp; intl_error_reset(NULL); @@ -291,25 +289,28 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDateTime) ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 4); ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 5); - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); - if (second_is_null) { - gcal = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, status); + tmp = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, status); } else { ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 6); - gcal = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second, status); + tmp = new GregorianCalendar((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second, status); } - if (!set_gregorian_calendar_time_zone(gcal, status)) { - delete gcal; + auto gcal = std::unique_ptr(tmp); + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + if (!set_gregorian_calendar_time_zone(gcal.get(), status)) { + ZEND_ASSERT(EG(exception)); goto cleanup; } object_init_ex(return_value, GregorianCalendar_ce_ptr); co = Z_INTL_CALENDAR_P(return_value); - co->ucal = gcal; + // TODO: trying to get passed the ownership change step + co->ucal = gcal.release(); cleanup: - zend_restore_error_handling(&error_handling); + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } U_CFUNC PHP_FUNCTION(intlgregcal_set_gregorian_change) @@ -326,8 +327,7 @@ U_CFUNC PHP_FUNCTION(intlgregcal_set_gregorian_change) CALENDAR_METHOD_FETCH_OBJECT; fetch_greg(co)->setGregorianChange(date, CALENDAR_ERROR_CODE(co)); - INTL_METHOD_CHECK_STATUS(co, "intlgregcal_set_gregorian_change: error " - "calling ICU method"); + INTL_METHOD_CHECK_STATUS(co, "error calling ICU method"); RETURN_TRUE; } diff --git a/ext/intl/collator/collator.h b/ext/intl/collator/collator.h index e92429f51179..959da9063e09 100644 --- a/ext/intl/collator/collator.h +++ b/ext/intl/collator/collator.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_arginfo.h b/ext/intl/collator/collator_arginfo.h index 3f469b02facd..4367d12be4f7 100644 --- a/ext/intl/collator/collator_arginfo.h +++ b/ext/intl/collator/collator_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit collator.stub.php instead. * Stub hash: cbe3c5f4c35d93f90c3e7164bdfc4e2fefc88c83 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Collator___construct, 0, 0, 1) @@ -103,147 +103,147 @@ static zend_class_entry *register_class_Collator(void) zval const_DEFAULT_VALUE_value; ZVAL_LONG(&const_DEFAULT_VALUE_value, UCOL_DEFAULT); - zend_string *const_DEFAULT_VALUE_name = zend_string_init_interned("DEFAULT_VALUE", sizeof("DEFAULT_VALUE") - 1, 1); + zend_string *const_DEFAULT_VALUE_name = zend_string_init_interned("DEFAULT_VALUE", sizeof("DEFAULT_VALUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DEFAULT_VALUE_name, &const_DEFAULT_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DEFAULT_VALUE_name); + zend_string_release_ex(const_DEFAULT_VALUE_name, true); zval const_PRIMARY_value; ZVAL_LONG(&const_PRIMARY_value, UCOL_PRIMARY); - zend_string *const_PRIMARY_name = zend_string_init_interned("PRIMARY", sizeof("PRIMARY") - 1, 1); + zend_string *const_PRIMARY_name = zend_string_init_interned("PRIMARY", sizeof("PRIMARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_PRIMARY_name, &const_PRIMARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PRIMARY_name); + zend_string_release_ex(const_PRIMARY_name, true); zval const_SECONDARY_value; ZVAL_LONG(&const_SECONDARY_value, UCOL_SECONDARY); - zend_string *const_SECONDARY_name = zend_string_init_interned("SECONDARY", sizeof("SECONDARY") - 1, 1); + zend_string *const_SECONDARY_name = zend_string_init_interned("SECONDARY", sizeof("SECONDARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_SECONDARY_name, &const_SECONDARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SECONDARY_name); + zend_string_release_ex(const_SECONDARY_name, true); zval const_TERTIARY_value; ZVAL_LONG(&const_TERTIARY_value, UCOL_TERTIARY); - zend_string *const_TERTIARY_name = zend_string_init_interned("TERTIARY", sizeof("TERTIARY") - 1, 1); + zend_string *const_TERTIARY_name = zend_string_init_interned("TERTIARY", sizeof("TERTIARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_TERTIARY_name, &const_TERTIARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TERTIARY_name); + zend_string_release_ex(const_TERTIARY_name, true); zval const_DEFAULT_STRENGTH_value; ZVAL_LONG(&const_DEFAULT_STRENGTH_value, UCOL_DEFAULT_STRENGTH); - zend_string *const_DEFAULT_STRENGTH_name = zend_string_init_interned("DEFAULT_STRENGTH", sizeof("DEFAULT_STRENGTH") - 1, 1); + zend_string *const_DEFAULT_STRENGTH_name = zend_string_init_interned("DEFAULT_STRENGTH", sizeof("DEFAULT_STRENGTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_DEFAULT_STRENGTH_name, &const_DEFAULT_STRENGTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DEFAULT_STRENGTH_name); + zend_string_release_ex(const_DEFAULT_STRENGTH_name, true); zval const_QUATERNARY_value; ZVAL_LONG(&const_QUATERNARY_value, UCOL_QUATERNARY); - zend_string *const_QUATERNARY_name = zend_string_init_interned("QUATERNARY", sizeof("QUATERNARY") - 1, 1); + zend_string *const_QUATERNARY_name = zend_string_init_interned("QUATERNARY", sizeof("QUATERNARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_QUATERNARY_name, &const_QUATERNARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_QUATERNARY_name); + zend_string_release_ex(const_QUATERNARY_name, true); zval const_IDENTICAL_value; ZVAL_LONG(&const_IDENTICAL_value, UCOL_IDENTICAL); - zend_string *const_IDENTICAL_name = zend_string_init_interned("IDENTICAL", sizeof("IDENTICAL") - 1, 1); + zend_string *const_IDENTICAL_name = zend_string_init_interned("IDENTICAL", sizeof("IDENTICAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_IDENTICAL_name, &const_IDENTICAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IDENTICAL_name); + zend_string_release_ex(const_IDENTICAL_name, true); zval const_OFF_value; ZVAL_LONG(&const_OFF_value, UCOL_OFF); - zend_string *const_OFF_name = zend_string_init_interned("OFF", sizeof("OFF") - 1, 1); + zend_string *const_OFF_name = zend_string_init_interned("OFF", sizeof("OFF") - 1, true); zend_declare_typed_class_constant(class_entry, const_OFF_name, &const_OFF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OFF_name); + zend_string_release_ex(const_OFF_name, true); zval const_ON_value; ZVAL_LONG(&const_ON_value, UCOL_ON); - zend_string *const_ON_name = zend_string_init_interned("ON", sizeof("ON") - 1, 1); + zend_string *const_ON_name = zend_string_init_interned("ON", sizeof("ON") - 1, true); zend_declare_typed_class_constant(class_entry, const_ON_name, &const_ON_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ON_name); + zend_string_release_ex(const_ON_name, true); zval const_SHIFTED_value; ZVAL_LONG(&const_SHIFTED_value, UCOL_SHIFTED); - zend_string *const_SHIFTED_name = zend_string_init_interned("SHIFTED", sizeof("SHIFTED") - 1, 1); + zend_string *const_SHIFTED_name = zend_string_init_interned("SHIFTED", sizeof("SHIFTED") - 1, true); zend_declare_typed_class_constant(class_entry, const_SHIFTED_name, &const_SHIFTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SHIFTED_name); + zend_string_release_ex(const_SHIFTED_name, true); zval const_NON_IGNORABLE_value; ZVAL_LONG(&const_NON_IGNORABLE_value, UCOL_NON_IGNORABLE); - zend_string *const_NON_IGNORABLE_name = zend_string_init_interned("NON_IGNORABLE", sizeof("NON_IGNORABLE") - 1, 1); + zend_string *const_NON_IGNORABLE_name = zend_string_init_interned("NON_IGNORABLE", sizeof("NON_IGNORABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_NON_IGNORABLE_name, &const_NON_IGNORABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NON_IGNORABLE_name); + zend_string_release_ex(const_NON_IGNORABLE_name, true); zval const_LOWER_FIRST_value; ZVAL_LONG(&const_LOWER_FIRST_value, UCOL_LOWER_FIRST); - zend_string *const_LOWER_FIRST_name = zend_string_init_interned("LOWER_FIRST", sizeof("LOWER_FIRST") - 1, 1); + zend_string *const_LOWER_FIRST_name = zend_string_init_interned("LOWER_FIRST", sizeof("LOWER_FIRST") - 1, true); zend_declare_typed_class_constant(class_entry, const_LOWER_FIRST_name, &const_LOWER_FIRST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LOWER_FIRST_name); + zend_string_release_ex(const_LOWER_FIRST_name, true); zval const_UPPER_FIRST_value; ZVAL_LONG(&const_UPPER_FIRST_value, UCOL_UPPER_FIRST); - zend_string *const_UPPER_FIRST_name = zend_string_init_interned("UPPER_FIRST", sizeof("UPPER_FIRST") - 1, 1); + zend_string *const_UPPER_FIRST_name = zend_string_init_interned("UPPER_FIRST", sizeof("UPPER_FIRST") - 1, true); zend_declare_typed_class_constant(class_entry, const_UPPER_FIRST_name, &const_UPPER_FIRST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UPPER_FIRST_name); + zend_string_release_ex(const_UPPER_FIRST_name, true); zval const_FRENCH_COLLATION_value; ZVAL_LONG(&const_FRENCH_COLLATION_value, UCOL_FRENCH_COLLATION); - zend_string *const_FRENCH_COLLATION_name = zend_string_init_interned("FRENCH_COLLATION", sizeof("FRENCH_COLLATION") - 1, 1); + zend_string *const_FRENCH_COLLATION_name = zend_string_init_interned("FRENCH_COLLATION", sizeof("FRENCH_COLLATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_FRENCH_COLLATION_name, &const_FRENCH_COLLATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FRENCH_COLLATION_name); + zend_string_release_ex(const_FRENCH_COLLATION_name, true); zval const_ALTERNATE_HANDLING_value; ZVAL_LONG(&const_ALTERNATE_HANDLING_value, UCOL_ALTERNATE_HANDLING); - zend_string *const_ALTERNATE_HANDLING_name = zend_string_init_interned("ALTERNATE_HANDLING", sizeof("ALTERNATE_HANDLING") - 1, 1); + zend_string *const_ALTERNATE_HANDLING_name = zend_string_init_interned("ALTERNATE_HANDLING", sizeof("ALTERNATE_HANDLING") - 1, true); zend_declare_typed_class_constant(class_entry, const_ALTERNATE_HANDLING_name, &const_ALTERNATE_HANDLING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ALTERNATE_HANDLING_name); + zend_string_release_ex(const_ALTERNATE_HANDLING_name, true); zval const_CASE_FIRST_value; ZVAL_LONG(&const_CASE_FIRST_value, UCOL_CASE_FIRST); - zend_string *const_CASE_FIRST_name = zend_string_init_interned("CASE_FIRST", sizeof("CASE_FIRST") - 1, 1); + zend_string *const_CASE_FIRST_name = zend_string_init_interned("CASE_FIRST", sizeof("CASE_FIRST") - 1, true); zend_declare_typed_class_constant(class_entry, const_CASE_FIRST_name, &const_CASE_FIRST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CASE_FIRST_name); + zend_string_release_ex(const_CASE_FIRST_name, true); zval const_CASE_LEVEL_value; ZVAL_LONG(&const_CASE_LEVEL_value, UCOL_CASE_LEVEL); - zend_string *const_CASE_LEVEL_name = zend_string_init_interned("CASE_LEVEL", sizeof("CASE_LEVEL") - 1, 1); + zend_string *const_CASE_LEVEL_name = zend_string_init_interned("CASE_LEVEL", sizeof("CASE_LEVEL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CASE_LEVEL_name, &const_CASE_LEVEL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CASE_LEVEL_name); + zend_string_release_ex(const_CASE_LEVEL_name, true); zval const_NORMALIZATION_MODE_value; ZVAL_LONG(&const_NORMALIZATION_MODE_value, UCOL_NORMALIZATION_MODE); - zend_string *const_NORMALIZATION_MODE_name = zend_string_init_interned("NORMALIZATION_MODE", sizeof("NORMALIZATION_MODE") - 1, 1); + zend_string *const_NORMALIZATION_MODE_name = zend_string_init_interned("NORMALIZATION_MODE", sizeof("NORMALIZATION_MODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_NORMALIZATION_MODE_name, &const_NORMALIZATION_MODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NORMALIZATION_MODE_name); + zend_string_release_ex(const_NORMALIZATION_MODE_name, true); zval const_STRENGTH_value; ZVAL_LONG(&const_STRENGTH_value, UCOL_STRENGTH); - zend_string *const_STRENGTH_name = zend_string_init_interned("STRENGTH", sizeof("STRENGTH") - 1, 1); + zend_string *const_STRENGTH_name = zend_string_init_interned("STRENGTH", sizeof("STRENGTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_STRENGTH_name, &const_STRENGTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_STRENGTH_name); + zend_string_release_ex(const_STRENGTH_name, true); zval const_HIRAGANA_QUATERNARY_MODE_value; ZVAL_LONG(&const_HIRAGANA_QUATERNARY_MODE_value, UCOL_HIRAGANA_QUATERNARY_MODE); - zend_string *const_HIRAGANA_QUATERNARY_MODE_name = zend_string_init_interned("HIRAGANA_QUATERNARY_MODE", sizeof("HIRAGANA_QUATERNARY_MODE") - 1, 1); + zend_string *const_HIRAGANA_QUATERNARY_MODE_name = zend_string_init_interned("HIRAGANA_QUATERNARY_MODE", sizeof("HIRAGANA_QUATERNARY_MODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_HIRAGANA_QUATERNARY_MODE_name, &const_HIRAGANA_QUATERNARY_MODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HIRAGANA_QUATERNARY_MODE_name); + zend_string_release_ex(const_HIRAGANA_QUATERNARY_MODE_name, true); zval const_NUMERIC_COLLATION_value; ZVAL_LONG(&const_NUMERIC_COLLATION_value, UCOL_NUMERIC_COLLATION); - zend_string *const_NUMERIC_COLLATION_name = zend_string_init_interned("NUMERIC_COLLATION", sizeof("NUMERIC_COLLATION") - 1, 1); + zend_string *const_NUMERIC_COLLATION_name = zend_string_init_interned("NUMERIC_COLLATION", sizeof("NUMERIC_COLLATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_NUMERIC_COLLATION_name, &const_NUMERIC_COLLATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NUMERIC_COLLATION_name); + zend_string_release_ex(const_NUMERIC_COLLATION_name, true); zval const_SORT_REGULAR_value; ZVAL_LONG(&const_SORT_REGULAR_value, COLLATOR_SORT_REGULAR); - zend_string *const_SORT_REGULAR_name = zend_string_init_interned("SORT_REGULAR", sizeof("SORT_REGULAR") - 1, 1); + zend_string *const_SORT_REGULAR_name = zend_string_init_interned("SORT_REGULAR", sizeof("SORT_REGULAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_SORT_REGULAR_name, &const_SORT_REGULAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SORT_REGULAR_name); + zend_string_release_ex(const_SORT_REGULAR_name, true); zval const_SORT_STRING_value; ZVAL_LONG(&const_SORT_STRING_value, COLLATOR_SORT_STRING); - zend_string *const_SORT_STRING_name = zend_string_init_interned("SORT_STRING", sizeof("SORT_STRING") - 1, 1); + zend_string *const_SORT_STRING_name = zend_string_init_interned("SORT_STRING", sizeof("SORT_STRING") - 1, true); zend_declare_typed_class_constant(class_entry, const_SORT_STRING_name, &const_SORT_STRING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SORT_STRING_name); + zend_string_release_ex(const_SORT_STRING_name, true); zval const_SORT_NUMERIC_value; ZVAL_LONG(&const_SORT_NUMERIC_value, COLLATOR_SORT_NUMERIC); - zend_string *const_SORT_NUMERIC_name = zend_string_init_interned("SORT_NUMERIC", sizeof("SORT_NUMERIC") - 1, 1); + zend_string *const_SORT_NUMERIC_name = zend_string_init_interned("SORT_NUMERIC", sizeof("SORT_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_SORT_NUMERIC_name, &const_SORT_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SORT_NUMERIC_name); + zend_string_release_ex(const_SORT_NUMERIC_name, true); return class_entry; } diff --git a/ext/intl/collator/collator_attr.c b/ext/intl/collator/collator_attr.c deleted file mode 100644 index f16ae0cc5285..000000000000 --- a/ext/intl/collator/collator_attr.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "collator_class.h" -#include "collator_convert.h" - -#include - -/* {{{ Get collation attribute value. */ -PHP_FUNCTION( collator_get_attribute ) -{ - zend_long attribute, value; - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", - &object, Collator_ce_ptr, &attribute ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - value = ucol_getAttribute( co->ucoll, attribute, COLLATOR_ERROR_CODE_P( co ) ); - COLLATOR_CHECK_STATUS( co, "Error getting attribute value" ); - - RETURN_LONG( value ); -} -/* }}} */ - -/* {{{ Set collation attribute. */ -PHP_FUNCTION( collator_set_attribute ) -{ - zend_long attribute, value; - COLLATOR_METHOD_INIT_VARS - - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oll", - &object, Collator_ce_ptr, &attribute, &value ) == FAILURE) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - /* Set new value for the given attribute. */ - ucol_setAttribute( co->ucoll, attribute, value, COLLATOR_ERROR_CODE_P( co ) ); - COLLATOR_CHECK_STATUS( co, "Error setting attribute value" ); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Returns the current collation strength. */ -PHP_FUNCTION( collator_get_strength ) -{ - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, Collator_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - /* Get current strength and return it. */ - RETURN_LONG( ucol_getStrength( co->ucoll ) ); -} -/* }}} */ - -/* {{{ Set the collation strength. */ -PHP_FUNCTION( collator_set_strength ) -{ - zend_long strength; - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", - &object, Collator_ce_ptr, &strength ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - /* Set given strength. */ - ucol_setStrength( co->ucoll, strength ); - - RETURN_TRUE; -} -/* }}} */ diff --git a/ext/intl/collator/collator_attr.cpp b/ext/intl/collator/collator_attr.cpp new file mode 100644 index 000000000000..14b8abf497b4 --- /dev/null +++ b/ext/intl/collator/collator_attr.cpp @@ -0,0 +1,124 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +} +#include "collator_class.h" +#include "collator_convert.h" + +#include + +/* {{{ Get collation attribute value. */ +U_CFUNC PHP_FUNCTION( collator_get_attribute ) +{ + zend_long attribute, value; + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", + &object, Collator_ce_ptr, &attribute ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + value = ucol_getAttribute( co->ucoll, static_cast(attribute), COLLATOR_ERROR_CODE_P( co ) ); + COLLATOR_CHECK_STATUS( co, "Error getting attribute value" ); + + RETURN_LONG( value ); +} +/* }}} */ + +/* {{{ Set collation attribute. */ +U_CFUNC PHP_FUNCTION( collator_set_attribute ) +{ + zend_long attribute, value; + COLLATOR_METHOD_INIT_VARS + + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oll", + &object, Collator_ce_ptr, &attribute, &value ) == FAILURE) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + /* Set new value for the given attribute. */ + ucol_setAttribute( co->ucoll, static_cast(attribute), static_cast(value), COLLATOR_ERROR_CODE_P( co ) ); + COLLATOR_CHECK_STATUS( co, "Error setting attribute value" ); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Returns the current collation strength. */ +U_CFUNC PHP_FUNCTION( collator_get_strength ) +{ + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, Collator_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + /* Get current strength and return it. */ + RETURN_LONG( ucol_getStrength( co->ucoll ) ); +} +/* }}} */ + +/* {{{ Set the collation strength. */ +U_CFUNC PHP_FUNCTION( collator_set_strength ) +{ + zend_long strength; + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", + &object, Collator_ce_ptr, &strength ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + /* Set given strength. */ + ucol_setStrength( co->ucoll, static_cast(strength) ); + + RETURN_TRUE; +} +/* }}} */ diff --git a/ext/intl/collator/collator_class.c b/ext/intl/collator/collator_class.c deleted file mode 100644 index 3a883c9e2e64..000000000000 --- a/ext/intl/collator/collator_class.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#include "collator.h" -#include "collator_class.h" -#include "php_intl.h" -#include "collator_sort.h" -#include "collator_convert.h" -#include "intl_error.h" - -#include - -#include "collator_arginfo.h" - -zend_class_entry *Collator_ce_ptr = NULL; -static zend_object_handlers Collator_handlers; - -/* - * Auxiliary functions needed by objects of 'Collator' class - */ - -/* {{{ Collator_objects_free */ -void Collator_objects_free(zend_object *object ) -{ - Collator_object* co = php_intl_collator_fetch_object(object); - - zend_object_std_dtor(&co->zo ); - - collator_object_destroy(co ); -} -/* }}} */ - -/* {{{ Collator_object_create */ -zend_object *Collator_object_create(zend_class_entry *ce ) -{ - Collator_object *intern = zend_object_alloc(sizeof(Collator_object), ce); - intl_error_init(COLLATOR_ERROR_P(intern)); - zend_object_std_init(&intern->zo, ce ); - object_properties_init(&intern->zo, ce); - - return &intern->zo; -} -/* }}} */ - -/* - * 'Collator' class registration structures & functions - */ - -/* {{{ collator_register_Collator_symbols - * Initialize 'Collator' class - */ -void collator_register_Collator_symbols(int module_number) -{ - register_collator_symbols(module_number); - - /* Create and register 'Collator' class. */ - Collator_ce_ptr = register_class_Collator(); - Collator_ce_ptr->create_object = Collator_object_create; - Collator_ce_ptr->default_object_handlers = &Collator_handlers; - - memcpy(&Collator_handlers, &std_object_handlers, - sizeof Collator_handlers); - /* Collator has no usable clone semantics - ucol_cloneBinary/ucol_openBinary require binary buffer - for which we don't have the place to keep */ - Collator_handlers.offset = XtOffsetOf(Collator_object, zo); - Collator_handlers.clone_obj = NULL; - Collator_handlers.free_obj = Collator_objects_free; -} -/* }}} */ - -/* {{{ void collator_object_init( Collator_object* co ) - * Initialize internals of Collator_object. - * Must be called before any other call to 'collator_object_...' functions. - */ -void collator_object_init( Collator_object* co ) -{ - if( !co ) - return; - - intl_error_init( COLLATOR_ERROR_P( co ) ); -} -/* }}} */ - -/* {{{ void collator_object_destroy( Collator_object* co ) - * Clean up mem allocted by internals of Collator_object - */ -void collator_object_destroy( Collator_object* co ) -{ - if( !co ) - return; - - if( co->ucoll ) - { - ucol_close( co->ucoll ); - co->ucoll = NULL; - } - - intl_error_reset( COLLATOR_ERROR_P( co ) ); -} -/* }}} */ diff --git a/ext/intl/collator/collator_class.cpp b/ext/intl/collator/collator_class.cpp new file mode 100644 index 000000000000..4fd991bd156c --- /dev/null +++ b/ext/intl/collator/collator_class.cpp @@ -0,0 +1,114 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#include "collator.h" +#include "collator_class.h" +extern "C" { +#include "php_intl.h" +#include "intl_error.h" +#include "collator_arginfo.h" +} +#include "collator_sort.h" +#include "collator_convert.h" + +#include + + +zend_class_entry *Collator_ce_ptr = nullptr; +static zend_object_handlers Collator_handlers; + +/* + * Auxiliary functions needed by objects of 'Collator' class + */ + +/* {{{ Collator_objects_free */ +void Collator_objects_free(zend_object *object ) +{ + Collator_object* co = php_intl_collator_fetch_object(object); + + zend_object_std_dtor(&co->zo ); + + collator_object_destroy(co ); +} +/* }}} */ + +/* {{{ Collator_object_create */ +U_CFUNC zend_object *Collator_object_create(zend_class_entry *ce ) +{ + Collator_object *intern = reinterpret_cast(zend_object_alloc(sizeof(Collator_object), ce)); + intl_error_init(COLLATOR_ERROR_P(intern)); + zend_object_std_init(&intern->zo, ce ); + object_properties_init(&intern->zo, ce); + + return &intern->zo; +} +/* }}} */ + +/* + * 'Collator' class registration structures & functions + */ + +/* {{{ collator_register_Collator_symbols + * Initialize 'Collator' class + */ +U_CFUNC void collator_register_Collator_symbols(int module_number) +{ + register_collator_symbols(module_number); + + /* Create and register 'Collator' class. */ + Collator_ce_ptr = register_class_Collator(); + Collator_ce_ptr->create_object = Collator_object_create; + Collator_ce_ptr->default_object_handlers = &Collator_handlers; + + memcpy(&Collator_handlers, &std_object_handlers, + sizeof Collator_handlers); + /* Collator has no usable clone semantics - ucol_cloneBinary/ucol_openBinary require binary buffer + for which we don't have the place to keep */ + Collator_handlers.offset = offsetof(Collator_object, zo); + Collator_handlers.clone_obj = nullptr; + Collator_handlers.free_obj = Collator_objects_free; +} +/* }}} */ + +/* {{{ void collator_object_init( Collator_object* co ) + * Initialize internals of Collator_object. + * Must be called before any other call to 'collator_object_...' functions. + */ +U_CFUNC void collator_object_init( Collator_object* co ) +{ + if( !co ) + return; + + intl_error_init( COLLATOR_ERROR_P( co ) ); +} +/* }}} */ + +/* {{{ void collator_object_destroy( Collator_object* co ) + * Clean up mem allocted by internals of Collator_object + */ +U_CFUNC void collator_object_destroy( Collator_object* co ) +{ + if( !co ) + return; + + if( co->ucoll ) + { + ucol_close( co->ucoll ); + co->ucoll = nullptr; + } + + intl_error_reset( COLLATOR_ERROR_P( co ) ); +} +/* }}} */ diff --git a/ext/intl/collator/collator_class.h b/ext/intl/collator/collator_class.h index 5c69c2e5affb..643291ab181c 100644 --- a/ext/intl/collator/collator_class.h +++ b/ext/intl/collator/collator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -18,9 +18,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif #include "../intl_common.h" #include "../intl_error.h" #include "../intl_data.h" +#ifdef __cplusplus +} +#endif #include @@ -42,13 +48,19 @@ typedef struct { #define COLLATOR_ERROR_CODE_P(co) &(INTL_ERROR_CODE(COLLATOR_ERROR(co))) static inline Collator_object *php_intl_collator_fetch_object(zend_object *obj) { - return (Collator_object *)((char*)(obj) - XtOffsetOf(Collator_object, zo)); + return ZEND_CONTAINER_OF(obj, Collator_object, zo); } #define Z_INTL_COLLATOR_P(zv) php_intl_collator_fetch_object(Z_OBJ_P(zv)) +#ifdef __cplusplus +extern "C" { +#endif void collator_register_Collator_symbols(int module_number); void collator_object_init( Collator_object* co ); void collator_object_destroy( Collator_object* co ); +#ifdef __cplusplus +} +#endif extern zend_class_entry *Collator_ce_ptr; @@ -66,7 +78,7 @@ extern zend_class_entry *Collator_ce_ptr; intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); \ if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) \ { \ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), msg, 0 ); \ + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), msg); \ RETURN_FALSE; \ } \ diff --git a/ext/intl/collator/collator_compare.c b/ext/intl/collator/collator_compare.c deleted file mode 100644 index f71d57f74f86..000000000000 --- a/ext/intl/collator/collator_compare.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "collator_class.h" -#include "intl_convert.h" - -/* {{{ Compare two strings. */ -PHP_FUNCTION( collator_compare ) -{ - char* str1 = NULL; - char* str2 = NULL; - size_t str1_len = 0; - size_t str2_len = 0; - - UChar* ustr1 = NULL; - UChar* ustr2 = NULL; - int ustr1_len = 0; - int ustr2_len = 0; - - UCollationResult result; - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oss", - &object, Collator_ce_ptr, &str1, &str1_len, &str2, &str2_len ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - if (!co || !co->ucoll) { - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); - zend_throw_error(NULL, "Object not initialized"); - - RETURN_THROWS(); - } - - /* - * Compare given strings (converting them to UTF-16 first). - */ - - /* First convert the strings to UTF-16. */ - intl_convert_utf8_to_utf16( - &ustr1, &ustr1_len, str1, str1_len, COLLATOR_ERROR_CODE_P( co ) ); - if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) - { - /* Set global error code. */ - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - - /* Set error messages. */ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Error converting first argument to UTF-16", 0 ); - if (ustr1) { - efree( ustr1 ); - } - RETURN_FALSE; - } - - intl_convert_utf8_to_utf16( - &ustr2, &ustr2_len, str2, str2_len, COLLATOR_ERROR_CODE_P( co ) ); - if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) - { - /* Set global error code. */ - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - - /* Set error messages. */ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Error converting second argument to UTF-16", 0 ); - if (ustr1) { - efree( ustr1 ); - } - if (ustr2) { - efree( ustr2 ); - } - RETURN_FALSE; - } - - /* Then compare them. */ - result = ucol_strcoll( - co->ucoll, - ustr1, ustr1_len, - ustr2, ustr2_len ); - - if( ustr1 ) - efree( ustr1 ); - if( ustr2 ) - efree( ustr2 ); - - /* Return result of the comparison. */ - RETURN_LONG( result ); -} -/* }}} */ diff --git a/ext/intl/collator/collator_compare.cpp b/ext/intl/collator/collator_compare.cpp new file mode 100644 index 000000000000..bac0bbf50b21 --- /dev/null +++ b/ext/intl/collator/collator_compare.cpp @@ -0,0 +1,118 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "intl_convert.h" +} +#include "collator_class.h" + +/* {{{ Compare two strings. */ +U_CFUNC PHP_FUNCTION( collator_compare ) +{ + char* str1 = NULL; + char* str2 = NULL; + size_t str1_len = 0; + size_t str2_len = 0; + + UChar* ustr1 = NULL; + UChar* ustr2 = NULL; + int ustr1_len = 0; + int ustr2_len = 0; + + UCollationResult result; + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oss", + &object, Collator_ce_ptr, &str1, &str1_len, &str2, &str2_len ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + if (!co || !co->ucoll) { + intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg(COLLATOR_ERROR_P( co ), "Object not initialized"); + zend_throw_error(NULL, "Object not initialized"); + + RETURN_THROWS(); + } + + /* + * Compare given strings (converting them to UTF-16 first). + */ + + /* First convert the strings to UTF-16. */ + intl_convert_utf8_to_utf16( + &ustr1, &ustr1_len, str1, str1_len, COLLATOR_ERROR_CODE_P( co ) ); + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) + { + /* Set global error code. */ + intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); + + /* Set error messages. */ + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Error converting first argument to UTF-16"); + if (ustr1) { + efree( ustr1 ); + } + RETURN_FALSE; + } + + intl_convert_utf8_to_utf16( + &ustr2, &ustr2_len, str2, str2_len, COLLATOR_ERROR_CODE_P( co ) ); + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) + { + /* Set global error code. */ + intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); + + /* Set error messages. */ + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Error converting second argument to UTF-16"); + if (ustr1) { + efree( ustr1 ); + } + if (ustr2) { + efree( ustr2 ); + } + RETURN_FALSE; + } + + /* Then compare them. */ + result = ucol_strcoll( + co->ucoll, + ustr1, ustr1_len, + ustr2, ustr2_len ); + + if( ustr1 ) + efree( ustr1 ); + if( ustr2 ) + efree( ustr2 ); + + /* Return result of the comparison. */ + RETURN_LONG( result ); +} +/* }}} */ diff --git a/ext/intl/collator/collator_convert.c b/ext/intl/collator/collator_convert.c deleted file mode 100644 index 68f177e36b0f..000000000000 --- a/ext/intl/collator/collator_convert.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "collator_class.h" -#include "collator_is_numeric.h" -#include "collator_convert.h" -#include "intl_convert.h" - -#include -#include - -#define COLLATOR_CONVERT_RETURN_FAILED(retval) { \ - Z_TRY_ADDREF_P(retval); \ - return retval; \ - } - -/* {{{ collator_convert_hash_item_from_utf8_to_utf16 */ -static void collator_convert_hash_item_from_utf8_to_utf16( - HashTable* hash, zval *hashData, zend_string *hashKey, zend_ulong hashIndex, - UErrorCode* status ) -{ - const char* old_val; - size_t old_val_len; - zval znew_val; - - /* Process string values only. */ - if( Z_TYPE_P( hashData ) != IS_STRING ) - return; - - old_val = Z_STRVAL_P( hashData ); - old_val_len = Z_STRLEN_P( hashData ); - - /* Convert it from UTF-8 to UTF-16LE. */ - zend_string *zstr = intl_convert_utf8_to_utf16_zstr( old_val, old_val_len, status ); - if( U_FAILURE( *status ) ) - return; - - /* Update current hash item with the converted value. */ - ZVAL_NEW_STR( &znew_val, zstr ); - - if( hashKey) - { - zend_hash_update( hash, hashKey, &znew_val); - } - else /* hashKeyType == HASH_KEY_IS_LONG */ - { - zend_hash_index_update( hash, hashIndex, &znew_val); - } -} -/* }}} */ - -/* {{{ collator_convert_hash_item_from_utf16_to_utf8 */ -static void collator_convert_hash_item_from_utf16_to_utf8( - HashTable* hash, zval * hashData, zend_string* hashKey, zend_ulong hashIndex, - UErrorCode* status ) -{ - const char* old_val; - size_t old_val_len; - zend_string* u8str; - zval znew_val; - - /* Process string values only. */ - if( Z_TYPE_P( hashData ) != IS_STRING ) - return; - - old_val = Z_STRVAL_P( hashData ); - old_val_len = Z_STRLEN_P( hashData ); - - /* Convert it from UTF-16LE to UTF-8 and save the result to new_val[_len]. */ - u8str = intl_convert_utf16_to_utf8( - (UChar*)old_val, UCHARS(old_val_len), status ); - if( !u8str ) - return; - - /* Update current hash item with the converted value. */ - ZVAL_NEW_STR( &znew_val, u8str); - - if( hashKey ) - { - zend_hash_update( hash, hashKey, &znew_val); - } - else /* hashKeyType == HASH_KEY_IS_LONG */ - { - zend_hash_index_update( hash, hashIndex, &znew_val); - } -} -/* }}} */ - -/* {{{ collator_convert_hash_from_utf8_to_utf16 - * Convert values of the given hash from UTF-8 encoding to UTF-16LE. - */ -void collator_convert_hash_from_utf8_to_utf16( HashTable* hash, UErrorCode* status ) -{ - zend_ulong hashIndex; - zval *hashData; - zend_string *hashKey; - - ZEND_HASH_FOREACH_KEY_VAL(hash, hashIndex, hashKey, hashData) { - /* Convert current hash item from UTF-8 to UTF-16LE. */ - collator_convert_hash_item_from_utf8_to_utf16( - hash, hashData, hashKey, hashIndex, status ); - if( U_FAILURE( *status ) ) - return; - } ZEND_HASH_FOREACH_END(); -} -/* }}} */ - -/* {{{ collator_convert_hash_from_utf16_to_utf8 - * Convert values of the given hash from UTF-16LE encoding to UTF-8. - */ -void collator_convert_hash_from_utf16_to_utf8( HashTable* hash, UErrorCode* status ) -{ - zend_ulong hashIndex; - zend_string *hashKey; - zval *hashData; - - ZEND_HASH_FOREACH_KEY_VAL(hash, hashIndex, hashKey, hashData) { - /* Convert current hash item from UTF-16LE to UTF-8. */ - collator_convert_hash_item_from_utf16_to_utf8( - hash, hashData, hashKey, hashIndex, status ); - if( U_FAILURE( *status ) ) { - return; - } - } ZEND_HASH_FOREACH_END(); -} -/* }}} */ - -/* {{{ collator_convert_zstr_utf16_to_utf8 - * - * Convert string from utf16 to utf8. - * - * @param zval* utf16_zval String to convert. - * - * @return zval* Converted string. - */ -zval* collator_convert_zstr_utf16_to_utf8( zval* utf16_zval, zval *rv ) -{ - zend_string* u8str; - UErrorCode status = U_ZERO_ERROR; - - /* Convert to utf8 then. */ - u8str = intl_convert_utf16_to_utf8( - (UChar*) Z_STRVAL_P(utf16_zval), UCHARS( Z_STRLEN_P(utf16_zval) ), &status ); - if( !u8str ) { - php_error( E_WARNING, "Error converting utf16 to utf8 in collator_convert_zval_utf16_to_utf8()" ); - ZVAL_EMPTY_STRING( rv ); - } else { - ZVAL_NEW_STR( rv, u8str ); - } - return rv; -} -/* }}} */ - -zend_string *collator_convert_zstr_utf8_to_utf16(zend_string *utf8_str) -{ - UErrorCode status = U_ZERO_ERROR; - - /* Convert the string to UTF-16. */ - zend_string *zstr = intl_convert_utf8_to_utf16_zstr( - ZSTR_VAL(utf8_str), ZSTR_LEN(utf8_str), - &status); - // FIXME Or throw error or use intl internal error handler - if (U_FAILURE(status)) { - php_error(E_WARNING, - "Error casting object to string in collator_convert_zstr_utf8_to_utf16()"); - zstr = ZSTR_EMPTY_ALLOC(); - } - - return zstr; -} - -/* {{{ collator_convert_object_to_string - * Convert object to UTF16-encoded string. - */ -zval* collator_convert_object_to_string( zval* obj, zval *rv ) -{ - zval* zstr = NULL; - UErrorCode status = U_ZERO_ERROR; - - /* Bail out if it's not an object. */ - if( Z_TYPE_P( obj ) != IS_OBJECT ) - { - COLLATOR_CONVERT_RETURN_FAILED( obj ); - } - - /* Try object's handlers. */ - zstr = rv; - - if( Z_OBJ_HT_P(obj)->cast_object( Z_OBJ_P(obj), zstr, IS_STRING ) == FAILURE ) - { - /* cast_object failed => bail out. */ - zval_ptr_dtor( zstr ); - COLLATOR_CONVERT_RETURN_FAILED( obj ); - } - - /* Object wasn't successfully converted => bail out. */ - if( zstr == NULL ) - { - COLLATOR_CONVERT_RETURN_FAILED( obj ); - } - - /* Convert the string to UTF-16. */ - zend_string *converted_str = intl_convert_utf8_to_utf16_zstr( - Z_STRVAL_P( zstr ), Z_STRLEN_P( zstr ), - &status ); - // FIXME Or throw error or use intl internal error handler - if( U_FAILURE( status ) ) { - php_error( E_WARNING, "Error casting object to string in collator_convert_object_to_string()" ); - converted_str = ZSTR_EMPTY_ALLOC(); - } - - /* Cleanup zstr to hold utf16 string. */ - zval_ptr_dtor_str( zstr ); - - /* Set string. */ - ZVAL_STR( zstr, converted_str ); - - return zstr; -} -/* }}} */ - -/* {{{ collator_convert_string_to_number - * - * Convert string to number. - * - * @param zval* str String to convert. - * - * @return zval* Number. If str is not numeric string return number zero. - */ -zval* collator_convert_string_to_number( zval* str, zval *rv ) -{ - zval* num = collator_convert_string_to_number_if_possible( str, rv ); - if( num == str ) - { - /* String wasn't converted => return zero. */ - zval_ptr_dtor( num ); - - num = rv; - ZVAL_LONG( num, 0 ); - } - - return num; -} -/* }}} */ - -/* {{{ collator_convert_string_to_double - * - * Convert string to double. - * - * @param zval* str String to convert. - * - * @return zval* Number. If str is not numeric string return number zero. - */ -zval* collator_convert_string_to_double( zval* str, zval *rv ) -{ - zval* num = collator_convert_string_to_number( str, rv ); - if( Z_TYPE_P(num) == IS_LONG ) - { - ZVAL_DOUBLE( num, Z_LVAL_P( num ) ); - } - - return num; -} -/* }}} */ - -/* {{{ collator_convert_string_to_number_if_possible - * - * Convert string to numer. - * - * @param zval* str String to convert. - * - * @return zval* Number if str is numeric string. Otherwise - * original str param. - */ -zval* collator_convert_string_to_number_if_possible( zval* str, zval *rv ) -{ - uint8_t is_numeric = 0; - zend_long lval = 0; - double dval = 0; - - if( Z_TYPE_P( str ) != IS_STRING ) - { - COLLATOR_CONVERT_RETURN_FAILED( str ); - } - - if ( ( is_numeric = collator_is_numeric( (UChar*) Z_STRVAL_P(str), UCHARS( Z_STRLEN_P(str) ), &lval, &dval, /* allow_errors */ false ) ) ) - { - if( is_numeric == IS_LONG ) { - ZVAL_LONG(rv, lval); - } - if( is_numeric == IS_DOUBLE ) - ZVAL_DOUBLE(rv, dval); - } - else - { - COLLATOR_CONVERT_RETURN_FAILED( str ); - } - - return rv; -} -/* }}} */ - -/* Returns string from input zval. - * - * @param zval* arg zval to get string from - * - * @return zend_string* UTF16 string. - */ -zend_string *collator_zval_to_string(zval *arg) -{ - // TODO: This is extremely weird in that it leaves pre-existing strings alone and does not - // perform a UTF-8 to UTF-16 conversion for them. The assumption is that values that are - // already strings have already been converted beforehand. It would be good to clean this up. - if (Z_TYPE_P(arg) == IS_STRING) { - return zend_string_copy(Z_STR_P(arg)); - } - - zend_string *utf8_str = zval_get_string(arg); - zend_string *utf16_str = collator_convert_zstr_utf8_to_utf16(utf8_str); - zend_string_release(utf8_str); - return utf16_str; -} - -/* {{{ collator_normalize_sort_argument - * - * Normalize argument to use in sort's compare function. - * - * @param zval* arg Sort's argument to normalize. - * - * @return zval* Normalized copy of arg or unmodified arg - * if normalization is not needed. - */ -zval* collator_normalize_sort_argument( zval* arg, zval *rv ) -{ - zval* n_arg = NULL; - - if( Z_TYPE_P( arg ) != IS_STRING ) - { - /* If it's not a string then nothing to do. - * Return original arg. - */ - COLLATOR_CONVERT_RETURN_FAILED( arg ); - } - - /* Try convert to number. */ - n_arg = collator_convert_string_to_number_if_possible( arg, rv ); - - if( n_arg == arg ) - { - /* Conversion to number failed. */ - zval_ptr_dtor( n_arg ); - - /* Convert string to utf8. */ - n_arg = collator_convert_zstr_utf16_to_utf8( arg, rv ); - } - - return n_arg; -} -/* }}} */ diff --git a/ext/intl/collator/collator_convert.cpp b/ext/intl/collator/collator_convert.cpp new file mode 100644 index 000000000000..dd3360a69092 --- /dev/null +++ b/ext/intl/collator/collator_convert.cpp @@ -0,0 +1,383 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "intl_convert.h" +} +#include "collator_class.h" +#include "collator_is_numeric.h" +#include "collator_convert.h" + +#include +#include + +#define COLLATOR_CONVERT_RETURN_FAILED(retval) { \ + Z_TRY_ADDREF_P(retval); \ + return retval; \ + } + +/* {{{ collator_convert_hash_item_from_utf8_to_utf16 */ +static void collator_convert_hash_item_from_utf8_to_utf16( + HashTable* hash, zval *hashData, zend_string *hashKey, zend_ulong hashIndex, + UErrorCode* status ) +{ + const char* old_val; + size_t old_val_len; + zval znew_val; + + /* Process string values only. */ + if( Z_TYPE_P( hashData ) != IS_STRING ) + return; + + old_val = Z_STRVAL_P( hashData ); + old_val_len = Z_STRLEN_P( hashData ); + + /* Convert it from UTF-8 to UTF-16LE. */ + zend_string *zstr = intl_convert_utf8_to_utf16_zstr( old_val, old_val_len, status ); + if( U_FAILURE( *status ) ) + return; + + /* Update current hash item with the converted value. */ + ZVAL_NEW_STR( &znew_val, zstr ); + + if( hashKey) + { + zend_hash_update( hash, hashKey, &znew_val); + } + else /* hashKeyType == HASH_KEY_IS_LONG */ + { + zend_hash_index_update( hash, hashIndex, &znew_val); + } +} +/* }}} */ + +/* {{{ collator_convert_hash_item_from_utf16_to_utf8 */ +static void collator_convert_hash_item_from_utf16_to_utf8( + HashTable* hash, zval * hashData, zend_string* hashKey, zend_ulong hashIndex, + UErrorCode* status ) +{ + const char* old_val; + size_t old_val_len; + zend_string* u8str; + zval znew_val; + + /* Process string values only. */ + if( Z_TYPE_P( hashData ) != IS_STRING ) + return; + + old_val = Z_STRVAL_P( hashData ); + old_val_len = Z_STRLEN_P( hashData ); + + /* Convert it from UTF-16LE to UTF-8 and save the result to new_val[_len]. */ + u8str = intl_convert_utf16_to_utf8( + (UChar*)old_val, UCHARS(old_val_len), status ); + if( !u8str ) + return; + + /* Update current hash item with the converted value. */ + ZVAL_NEW_STR( &znew_val, u8str); + + if( hashKey ) + { + zend_hash_update( hash, hashKey, &znew_val); + } + else /* hashKeyType == HASH_KEY_IS_LONG */ + { + zend_hash_index_update( hash, hashIndex, &znew_val); + } +} +/* }}} */ + +/* {{{ collator_convert_hash_from_utf8_to_utf16 + * Convert values of the given hash from UTF-8 encoding to UTF-16LE. + */ +U_CFUNC void collator_convert_hash_from_utf8_to_utf16( HashTable* hash, UErrorCode* status ) +{ + zend_ulong hashIndex; + zval *hashData; + zend_string *hashKey; + + ZEND_HASH_FOREACH_KEY_VAL(hash, hashIndex, hashKey, hashData) { + /* Convert current hash item from UTF-8 to UTF-16LE. */ + collator_convert_hash_item_from_utf8_to_utf16( + hash, hashData, hashKey, hashIndex, status ); + if( U_FAILURE( *status ) ) + return; + } ZEND_HASH_FOREACH_END(); +} +/* }}} */ + +/* {{{ collator_convert_hash_from_utf16_to_utf8 + * Convert values of the given hash from UTF-16LE encoding to UTF-8. + */ +U_CFUNC void collator_convert_hash_from_utf16_to_utf8( HashTable* hash, UErrorCode* status ) +{ + zend_ulong hashIndex; + zend_string *hashKey; + zval *hashData; + + ZEND_HASH_FOREACH_KEY_VAL(hash, hashIndex, hashKey, hashData) { + /* Convert current hash item from UTF-16LE to UTF-8. */ + collator_convert_hash_item_from_utf16_to_utf8( + hash, hashData, hashKey, hashIndex, status ); + if( U_FAILURE( *status ) ) { + return; + } + } ZEND_HASH_FOREACH_END(); +} +/* }}} */ + +/* {{{ collator_convert_zstr_utf16_to_utf8 + * + * Convert string from utf16 to utf8. + * + * @param zval* utf16_zval String to convert. + * + * @return zval* Converted string. + */ +U_CFUNC zval* collator_convert_zstr_utf16_to_utf8( zval* utf16_zval, zval *rv ) +{ + zend_string* u8str; + UErrorCode status = U_ZERO_ERROR; + + /* Convert to utf8 then. */ + u8str = intl_convert_utf16_to_utf8( + (UChar*) Z_STRVAL_P(utf16_zval), UCHARS( Z_STRLEN_P(utf16_zval) ), &status ); + if( !u8str ) { + php_error( E_WARNING, "Error converting utf16 to utf8 in collator_convert_zval_utf16_to_utf8()" ); + ZVAL_EMPTY_STRING( rv ); + } else { + ZVAL_NEW_STR( rv, u8str ); + } + return rv; +} +/* }}} */ + +U_CFUNC zend_string *collator_convert_zstr_utf8_to_utf16(zend_string *utf8_str) +{ + UErrorCode status = U_ZERO_ERROR; + + /* Convert the string to UTF-16. */ + zend_string *zstr = intl_convert_utf8_to_utf16_zstr( + ZSTR_VAL(utf8_str), ZSTR_LEN(utf8_str), + &status); + // FIXME Or throw error or use intl internal error handler + if (U_FAILURE(status)) { + php_error(E_WARNING, + "Error casting object to string in collator_convert_zstr_utf8_to_utf16()"); + zstr = ZSTR_EMPTY_ALLOC(); + } + + return zstr; +} + +/* {{{ collator_convert_object_to_string + * Convert object to UTF16-encoded string. + */ +U_CFUNC zval* collator_convert_object_to_string( zval* obj, zval *rv ) +{ + zval* zstr = nullptr; + UErrorCode status = U_ZERO_ERROR; + + /* Bail out if it's not an object. */ + if( Z_TYPE_P( obj ) != IS_OBJECT ) + { + COLLATOR_CONVERT_RETURN_FAILED( obj ); + } + + /* Try object's handlers. */ + zstr = rv; + + if( Z_OBJ_HT_P(obj)->cast_object( Z_OBJ_P(obj), zstr, IS_STRING ) == FAILURE ) + { + /* cast_object failed => bail out. */ + zval_ptr_dtor( zstr ); + COLLATOR_CONVERT_RETURN_FAILED( obj ); + } + + /* Object wasn't successfully converted => bail out. */ + if( zstr == nullptr ) + { + COLLATOR_CONVERT_RETURN_FAILED( obj ); + } + + /* Convert the string to UTF-16. */ + zend_string *converted_str = intl_convert_utf8_to_utf16_zstr( + Z_STRVAL_P( zstr ), Z_STRLEN_P( zstr ), + &status ); + // FIXME Or throw error or use intl internal error handler + if( U_FAILURE( status ) ) { + php_error( E_WARNING, "Error casting object to string in collator_convert_object_to_string()" ); + converted_str = ZSTR_EMPTY_ALLOC(); + } + + /* Cleanup zstr to hold utf16 string. */ + zval_ptr_dtor_str( zstr ); + + /* Set string. */ + ZVAL_STR( zstr, converted_str ); + + return zstr; +} +/* }}} */ + +/* {{{ collator_convert_string_to_number + * + * Convert string to number. + * + * @param zval* str String to convert. + * + * @return zval* Number. If str is not numeric string return number zero. + */ +U_CFUNC zval* collator_convert_string_to_number( zval* str, zval *rv ) +{ + zval* num = collator_convert_string_to_number_if_possible( str, rv ); + if( num == str ) + { + /* String wasn't converted => return zero. */ + zval_ptr_dtor( num ); + + num = rv; + ZVAL_LONG( num, 0 ); + } + + return num; +} +/* }}} */ + +/* {{{ collator_convert_string_to_double + * + * Convert string to double. + * + * @param zval* str String to convert. + * + * @return zval* Number. If str is not numeric string return number zero. + */ +U_CFUNC zval* collator_convert_string_to_double( zval* str, zval *rv ) +{ + zval* num = collator_convert_string_to_number( str, rv ); + if( Z_TYPE_P(num) == IS_LONG ) + { + ZVAL_DOUBLE( num, Z_LVAL_P( num ) ); + } + + return num; +} +/* }}} */ + +/* {{{ collator_convert_string_to_number_if_possible + * + * Convert string to number. + * + * @param zval* str String to convert. + * + * @return zval* Number if str is numeric string. Otherwise + * original str param. + */ +U_CFUNC zval* collator_convert_string_to_number_if_possible( zval* str, zval *rv ) +{ + uint8_t is_numeric = 0; + zend_long lval = 0; + double dval = 0; + + if( Z_TYPE_P( str ) != IS_STRING ) + { + COLLATOR_CONVERT_RETURN_FAILED( str ); + } + + if ( ( is_numeric = collator_is_numeric( (UChar*) Z_STRVAL_P(str), UCHARS( Z_STRLEN_P(str) ), &lval, &dval, /* allow_errors */ false ) ) ) + { + if( is_numeric == IS_LONG ) { + ZVAL_LONG(rv, lval); + } + if( is_numeric == IS_DOUBLE ) + ZVAL_DOUBLE(rv, dval); + } + else + { + COLLATOR_CONVERT_RETURN_FAILED( str ); + } + + return rv; +} +/* }}} */ + +/* Returns string from input zval. + * + * @param zval* arg zval to get string from + * + * @return zend_string* UTF16 string. + */ +U_CFUNC zend_string *collator_zval_to_string(zval *arg) +{ + // TODO: This is extremely weird in that it leaves pre-existing strings alone and does not + // perform a UTF-8 to UTF-16 conversion for them. The assumption is that values that are + // already strings have already been converted beforehand. It would be good to clean this up. + if (Z_TYPE_P(arg) == IS_STRING) { + return zend_string_copy(Z_STR_P(arg)); + } + + zend_string *utf8_str = zval_get_string(arg); + zend_string *utf16_str = collator_convert_zstr_utf8_to_utf16(utf8_str); + zend_string_release(utf8_str); + return utf16_str; +} + +/* {{{ collator_normalize_sort_argument + * + * Normalize argument to use in sort's compare function. + * + * @param zval* arg Sort's argument to normalize. + * + * @return zval* Normalized copy of arg or unmodified arg + * if normalization is not needed. + */ +U_CFUNC zval* collator_normalize_sort_argument( zval* arg, zval *rv ) +{ + zval* n_arg = nullptr; + + if( Z_TYPE_P( arg ) != IS_STRING ) + { + /* If it's not a string then nothing to do. + * Return original arg. + */ + COLLATOR_CONVERT_RETURN_FAILED( arg ); + } + + /* Try convert to number. */ + n_arg = collator_convert_string_to_number_if_possible( arg, rv ); + + if( n_arg == arg ) + { + /* Conversion to number failed. */ + zval_ptr_dtor( n_arg ); + + /* Convert string to utf8. */ + n_arg = collator_convert_zstr_utf16_to_utf8( arg, rv ); + } + + return n_arg; +} +/* }}} */ diff --git a/ext/intl/collator/collator_convert.h b/ext/intl/collator/collator_convert.h index 1d5856096439..1d65d9d2d76b 100644 --- a/ext/intl/collator/collator_convert.h +++ b/ext/intl/collator/collator_convert.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -19,6 +19,9 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif void collator_convert_hash_from_utf8_to_utf16( HashTable* hash, UErrorCode* status ); void collator_convert_hash_from_utf16_to_utf8( HashTable* hash, UErrorCode* status ); @@ -32,5 +35,8 @@ zval* collator_convert_string_to_number_if_possible( zval* str, zval *rv ); zval* collator_convert_string_to_double( zval* str, zval *rv ); zend_string *collator_zval_to_string(zval *arg); +#ifdef __cplusplus +} +#endif #endif // COLLATOR_CONVERT_H diff --git a/ext/intl/collator/collator_create.c b/ext/intl/collator/collator_create.c deleted file mode 100644 index 88dacc1c1db4..000000000000 --- a/ext/intl/collator/collator_create.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "collator_class.h" -#include "intl_data.h" - -/* {{{ */ -static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) -{ - char* locale; - size_t locale_len = 0; - zval* object; - Collator_object* co; - - intl_error_reset( NULL ); - object = return_value; - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(locale, locale_len) - ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - } - - INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); - COLLATOR_METHOD_FETCH_OBJECT; - - if(locale_len == 0) { - locale = (char *)intl_locale_get_default(); - } - - /* Open ICU collator. */ - co->ucoll = ucol_open( locale, COLLATOR_ERROR_CODE_P( co ) ); - INTL_CTOR_CHECK_STATUS(co, "collator_create: unable to open ICU collator"); - return SUCCESS; -} -/* }}} */ - -/* {{{ Create collator. */ -PHP_FUNCTION( collator_create ) -{ - object_init_ex( return_value, Collator_ce_ptr ); - if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { - zval_ptr_dtor(return_value); - RETURN_NULL(); - } -} -/* }}} */ - -/* {{{ Collator object constructor. */ -PHP_METHOD( Collator, __construct ) -{ - zend_error_handling error_handling; - bool error_handling_replaced = 0; - - return_value = ZEND_THIS; - if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { - if (!EG(exception)) { - zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); - } -} -/* }}} */ diff --git a/ext/intl/collator/collator_create.cpp b/ext/intl/collator/collator_create.cpp new file mode 100644 index 000000000000..7aa715f8e091 --- /dev/null +++ b/ext/intl/collator/collator_create.cpp @@ -0,0 +1,85 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +} +#include "collator_class.h" +#include "intl_data.h" + +/* {{{ */ +static int collator_ctor(INTERNAL_FUNCTION_PARAMETERS) +{ + char* locale; + size_t locale_len = 0; + zval* object; + Collator_object* co; + + intl_error_reset( nullptr ); + object = return_value; + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(locale, locale_len) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); + COLLATOR_METHOD_FETCH_OBJECT; + + if(locale_len == 0) { + locale = (char *)intl_locale_get_default(); + } + + /* Open ICU collator. */ + co->ucoll = ucol_open( locale, COLLATOR_ERROR_CODE_P( co ) ); + INTL_CTOR_CHECK_STATUS(co, "unable to open ICU collator"); + return SUCCESS; +} +/* }}} */ + +/* {{{ Create collator. */ +U_CFUNC PHP_FUNCTION( collator_create ) +{ + object_init_ex( return_value, Collator_ce_ptr ); + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + zval_ptr_dtor(return_value); + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ Collator object constructor. */ +U_CFUNC PHP_METHOD( Collator, __construct ) +{ + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + + return_value = ZEND_THIS; + if (collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); + } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; +} +/* }}} */ diff --git a/ext/intl/collator/collator_error.c b/ext/intl/collator/collator_error.c deleted file mode 100644 index 2189b312d7c2..000000000000 --- a/ext/intl/collator/collator_error.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "collator_class.h" - -/* {{{ Get collator's last error code. */ -PHP_FUNCTION( collator_get_error_code ) -{ - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, Collator_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object (without resetting its last error code). */ - co = Z_INTL_COLLATOR_P(object); - if( co == NULL ) - RETURN_FALSE; - - /* Return collator's last error code. */ - RETURN_LONG( COLLATOR_ERROR_CODE( co ) ); -} -/* }}} */ - -/* {{{ Get text description for collator's last error code. */ -PHP_FUNCTION( collator_get_error_message ) -{ - zend_string* message = NULL; - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, Collator_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object (without resetting its last error code). */ - co = Z_INTL_COLLATOR_P( object ); - if( co == NULL ) - RETURN_FALSE; - - /* Return last error message. */ - message = intl_error_get_message( COLLATOR_ERROR_P( co ) ); - RETURN_STR(message); -} -/* }}} */ diff --git a/ext/intl/collator/collator_error.cpp b/ext/intl/collator/collator_error.cpp new file mode 100644 index 000000000000..2a1eda8f9f36 --- /dev/null +++ b/ext/intl/collator/collator_error.cpp @@ -0,0 +1,75 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +} +#include "collator_class.h" + +/* {{{ Get collator's last error code. */ +U_CFUNC PHP_FUNCTION( collator_get_error_code ) +{ + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, Collator_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object (without resetting its last error code). */ + co = Z_INTL_COLLATOR_P(object); + if( co == nullptr ) + RETURN_FALSE; + + /* Return collator's last error code. */ + RETURN_LONG( COLLATOR_ERROR_CODE( co ) ); +} +/* }}} */ + +/* {{{ Get text description for collator's last error code. */ +U_CFUNC PHP_FUNCTION( collator_get_error_message ) +{ + zend_string* message = nullptr; + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, Collator_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object (without resetting its last error code). */ + co = Z_INTL_COLLATOR_P( object ); + if( co == nullptr ) + RETURN_FALSE; + + /* Return last error message. */ + message = intl_error_get_message( COLLATOR_ERROR_P( co ) ); + RETURN_STR(message); +} +/* }}} */ diff --git a/ext/intl/collator/collator_is_numeric.c b/ext/intl/collator/collator_is_numeric.c deleted file mode 100644 index 4c473d947711..000000000000 --- a/ext/intl/collator/collator_is_numeric.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#include "collator_is_numeric.h" - -/* {{{ Taken from PHP6:zend_u_strtod() */ -static double collator_u_strtod(const UChar *nptr, UChar **endptr) /* {{{ */ -{ - const UChar *u = nptr, *nstart; - UChar c = *u; - int any = 0; - - while (u_isspace(c)) { - c = *++u; - } - nstart = u; - - if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) { - c = *++u; - } - - while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { - any = 1; - c = *++u; - } - - if (c == 0x2E /*'.'*/) { - c = *++u; - while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { - any = 1; - c = *++u; - } - } - - if ((c == 0x65 /*'e'*/ || c == 0x45 /*'E'*/) && any) { - const UChar *e = u; - int any_exp = 0; - - c = *++u; - if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) { - c = *++u; - } - - while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { - any_exp = 1; - c = *++u; - } - - if (!any_exp) { - u = e; - } - } - - if (any) { - char buf[64], *numbuf, *bufpos; - size_t length = u - nstart; - double value; - ALLOCA_FLAG(use_heap = 0); - - if (length < sizeof(buf)) { - numbuf = buf; - } else { - numbuf = (char *) do_alloca(length + 1, use_heap); - } - - bufpos = numbuf; - - while (nstart < u) { - *bufpos++ = (char) *nstart++; - } - - *bufpos = '\0'; - value = zend_strtod(numbuf, NULL); - - if (numbuf != buf) { - free_alloca(numbuf, use_heap); - } - - if (endptr != NULL) { - *endptr = (UChar *)u; - } - - return value; - } - - if (endptr != NULL) { - *endptr = (UChar *)nptr; - } - - return 0; -} -/* }}} */ - -/* {{{ collator_u_strtol - * Taken from PHP6:zend_u_strtol() - * - * Convert a Unicode string to a long integer. - * - * Ignores `locale' stuff. - */ -static zend_long collator_u_strtol(const UChar *nptr, UChar **endptr, int base) -{ - const UChar *s = nptr; - zend_ulong acc; - UChar c; - zend_ulong cutoff; - int neg = 0, any, cutlim; - - if (s == NULL) { - errno = ERANGE; - if (endptr != NULL) { - *endptr = NULL; - } - return 0; - } - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - do { - c = *s++; - } while (u_isspace(c)); - if (c == 0x2D /*'-'*/) { - neg = 1; - c = *s++; - } else if (c == 0x2B /*'+'*/) - c = *s++; - if ((base == 0 || base == 16) && - (c == 0x30 /*'0'*/) - && (*s == 0x78 /*'x'*/ || *s == 0x58 /*'X'*/)) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = (c == 0x30 /*'0'*/) ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for longs is - * [-2147483648..2147483647] and the input base is 10, - * cutoff will be set to 214748364 and cutlim to either - * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated - * a value > 214748364, or equal but the next digit is > 7 (or 8), - * the number is too big, and we will return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? -(zend_ulong)ZEND_LONG_MIN : ZEND_LONG_MAX; - cutlim = cutoff % (zend_ulong)base; - cutoff /= (zend_ulong)base; - for (acc = 0, any = 0;; c = *s++) { - if (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) - c -= 0x30 /*'0'*/; - else if (c >= 0x41 /*'A'*/ && c <= 0x5A /*'Z'*/) - c -= 0x41 /*'A'*/ - 10; - else if (c >= 0x61 /*'a'*/ && c <= 0x7A /*'z'*/) - c -= 0x61 /*'a'*/ - 10; - else - break; - if (c >= base) - break; - - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = neg ? ZEND_LONG_MIN : ZEND_LONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (UChar *)(any ? s - 1 : nptr); - return (acc); -} -/* }}} */ - -/* Consume (trailing) whitespace just like collator_u_strtol() consumes leading whitespace */ -static zend_always_inline UChar *collator_skip_ws(UChar *end_ptr) -{ - while (u_isspace(*end_ptr)) { - end_ptr++; - } - return end_ptr; -} - -/* {{{ collator_is_numeric] - * Taken from PHP6:is_numeric_unicode() - */ -uint8_t collator_is_numeric( UChar *str, int32_t length, zend_long *lval, double *dval, bool allow_errors ) -{ - zend_long local_lval; - double local_dval; - UChar *end_ptr_long, *end_ptr_double; - - if (!length) { - return 0; - } - - errno=0; - local_lval = collator_u_strtol(str, &end_ptr_long, 10); - if (errno != ERANGE) { - end_ptr_long = collator_skip_ws(end_ptr_long); - if (end_ptr_long == str+length) { /* integer string */ - if (lval) { - *lval = local_lval; - } - return IS_LONG; - } else if (end_ptr_long == str && *end_ptr_long != '\0' && *str != '.' && *str != '-') { /* ignore partial string matches */ - return 0; - } - } else { - end_ptr_long = NULL; - } - - local_dval = collator_u_strtod(str, &end_ptr_double); - if (local_dval == 0 && end_ptr_double == str) { - end_ptr_double = NULL; - } else { - end_ptr_double = collator_skip_ws(end_ptr_double); - if (end_ptr_double == str+length) { /* floating point string */ - if (!zend_finite(local_dval)) { - /* "inf","nan" and maybe other weird ones */ - return 0; - } - - if (dval) { - *dval = local_dval; - } - return IS_DOUBLE; - } - } - - if (!allow_errors) { - return 0; - } - - if (allow_errors) { - if (end_ptr_double > end_ptr_long && dval) { - *dval = local_dval; - return IS_DOUBLE; - } else if (end_ptr_long && lval) { - *lval = local_lval; - return IS_LONG; - } - } - return 0; -} -/* }}} */ diff --git a/ext/intl/collator/collator_is_numeric.cpp b/ext/intl/collator/collator_is_numeric.cpp new file mode 100644 index 000000000000..85a6eb695c0b --- /dev/null +++ b/ext/intl/collator/collator_is_numeric.cpp @@ -0,0 +1,274 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#include "collator_is_numeric.h" + +/* {{{ Taken from PHP6:zend_u_strtod() */ +static double collator_u_strtod(const UChar *nptr, UChar **endptr) /* {{{ */ +{ + const UChar *u = nptr, *nstart; + UChar c = *u; + int any = 0; + + while (u_isspace(c)) { + c = *++u; + } + nstart = u; + + if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) { + c = *++u; + } + + while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { + any = 1; + c = *++u; + } + + if (c == 0x2E /*'.'*/) { + c = *++u; + while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { + any = 1; + c = *++u; + } + } + + if ((c == 0x65 /*'e'*/ || c == 0x45 /*'E'*/) && any) { + const UChar *e = u; + int any_exp = 0; + + c = *++u; + if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) { + c = *++u; + } + + while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { + any_exp = 1; + c = *++u; + } + + if (!any_exp) { + u = e; + } + } + + if (any) { + char buf[64], *numbuf, *bufpos; + size_t length = u - nstart; + double value; + ALLOCA_FLAG(use_heap = 0); + + if (length < sizeof(buf)) { + numbuf = buf; + } else { + numbuf = (char *) do_alloca(length + 1, use_heap); + } + + bufpos = numbuf; + + while (nstart < u) { + *bufpos++ = (char) *nstart++; + } + + *bufpos = '\0'; + value = zend_strtod(numbuf, nullptr); + + if (numbuf != buf) { + free_alloca(numbuf, use_heap); + } + + if (endptr != nullptr) { + *endptr = (UChar *)u; + } + + return value; + } + + if (endptr != nullptr) { + *endptr = (UChar *)nptr; + } + + return 0; +} +/* }}} */ + +/* {{{ collator_u_strtol + * Taken from PHP6:zend_u_strtol() + * + * Convert a Unicode string to a long integer. + * + * Ignores `locale' stuff. + */ +static zend_long collator_u_strtol(const UChar *nptr, UChar **endptr, int base) +{ + const UChar *s = nptr; + zend_ulong acc; + UChar c; + zend_ulong cutoff; + int neg = 0, any, cutlim; + + if (s == nullptr) { + errno = ERANGE; + if (endptr != nullptr) { + *endptr = nullptr; + } + return 0; + } + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do { + c = *s++; + } while (u_isspace(c)); + if (c == 0x2D /*'-'*/) { + neg = 1; + c = *s++; + } else if (c == 0x2B /*'+'*/) + c = *s++; + if ((base == 0 || base == 16) && + (c == 0x30 /*'0'*/) + && (*s == 0x78 /*'x'*/ || *s == 0x58 /*'X'*/)) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = (c == 0x30 /*'0'*/) ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(zend_ulong)ZEND_LONG_MIN : ZEND_LONG_MAX; + cutlim = cutoff % (zend_ulong)base; + cutoff /= (zend_ulong)base; + for (acc = 0, any = 0;; c = *s++) { + if (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) + c -= 0x30 /*'0'*/; + else if (c >= 0x41 /*'A'*/ && c <= 0x5A /*'Z'*/) + c -= 0x41 /*'A'*/ - 10; + else if (c >= 0x61 /*'a'*/ && c <= 0x7A /*'z'*/) + c -= 0x61 /*'a'*/ - 10; + else + break; + if (c >= base) + break; + + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? ZEND_LONG_MIN : ZEND_LONG_MAX; + errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != nullptr) + *endptr = (UChar *)(any ? s - 1 : nptr); + return (acc); +} +/* }}} */ + +/* Consume (trailing) whitespace just like collator_u_strtol() consumes leading whitespace */ +static zend_always_inline UChar *collator_skip_ws(UChar *end_ptr) +{ + while (u_isspace(*end_ptr)) { + end_ptr++; + } + return end_ptr; +} + +/* {{{ collator_is_numeric] + * Taken from PHP6:is_numeric_unicode() + */ +uint8_t collator_is_numeric( UChar *str, int32_t length, zend_long *lval, double *dval, bool allow_errors ) +{ + zend_long local_lval; + double local_dval; + UChar *end_ptr_long, *end_ptr_double; + + if (!length) { + return 0; + } + + errno=0; + local_lval = collator_u_strtol(str, &end_ptr_long, 10); + if (errno != ERANGE) { + end_ptr_long = collator_skip_ws(end_ptr_long); + if (end_ptr_long == str+length) { /* integer string */ + if (lval) { + *lval = local_lval; + } + return IS_LONG; + } else if (end_ptr_long == str && *end_ptr_long != '\0' && *str != '.' && *str != '-') { /* ignore partial string matches */ + return 0; + } + } else { + end_ptr_long = nullptr; + } + + local_dval = collator_u_strtod(str, &end_ptr_double); + if (local_dval == 0 && end_ptr_double == str) { + end_ptr_double = nullptr; + } else { + end_ptr_double = collator_skip_ws(end_ptr_double); + if (end_ptr_double == str+length) { /* floating point string */ + if (!zend_finite(local_dval)) { + /* "inf","nan" and maybe other weird ones */ + return 0; + } + + if (dval) { + *dval = local_dval; + } + return IS_DOUBLE; + } + } + + if (!allow_errors) { + return 0; + } + + if (allow_errors) { + if (end_ptr_double > end_ptr_long && dval) { + *dval = local_dval; + return IS_DOUBLE; + } else if (end_ptr_long && lval) { + *lval = local_lval; + return IS_LONG; + } + } + return 0; +} +/* }}} */ diff --git a/ext/intl/collator/collator_is_numeric.h b/ext/intl/collator/collator_is_numeric.h index d30acd0b5843..e2f6ed83a178 100644 --- a/ext/intl/collator/collator_is_numeric.h +++ b/ext/intl/collator/collator_is_numeric.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/collator/collator_locale.c b/ext/intl/collator/collator_locale.c deleted file mode 100644 index e1cdcdf2a609..000000000000 --- a/ext/intl/collator/collator_locale.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "collator_class.h" -#include "intl_convert.h" - -#include - -/* {{{ Gets the locale name of the collator. */ -PHP_FUNCTION( collator_get_locale ) -{ - zend_long type = 0; - char* locale_name = NULL; - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", - &object, Collator_ce_ptr, &type ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - if (!co || !co->ucoll) { - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); - zend_throw_error(NULL, "Object not initialized"); - - RETURN_THROWS(); - } - - /* Get locale by specified type. */ - locale_name = (char*) ucol_getLocaleByType( - co->ucoll, type, COLLATOR_ERROR_CODE_P( co ) ); - COLLATOR_CHECK_STATUS( co, "Error getting locale by type" ); - - /* Return it. */ - RETVAL_STRINGL( locale_name, strlen(locale_name) ); -} -/* }}} */ diff --git a/ext/intl/collator/collator_locale.cpp b/ext/intl/collator/collator_locale.cpp new file mode 100644 index 000000000000..ea1393779846 --- /dev/null +++ b/ext/intl/collator/collator_locale.cpp @@ -0,0 +1,67 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +} +#include "collator_class.h" +#include "intl_convert.h" + +#include + +/* {{{ Gets the locale name of the collator. */ +U_CFUNC PHP_FUNCTION( collator_get_locale ) +{ + zend_long type = 0; + char* locale_name = nullptr; + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", + &object, Collator_ce_ptr, &type ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + if (!co || !co->ucoll) { + intl_error_set_code( nullptr, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Object not initialized"); + zend_throw_error(nullptr, "Object not initialized"); + + RETURN_THROWS(); + } + + /* Get locale by specified type. */ + locale_name = (char*) ucol_getLocaleByType( + co->ucoll, static_cast(type), COLLATOR_ERROR_CODE_P( co ) ); + COLLATOR_CHECK_STATUS( co, "Error getting locale by type" ); + + /* Return it. */ + RETVAL_STRINGL( locale_name, strlen(locale_name) ); +} +/* }}} */ diff --git a/ext/intl/collator/collator_sort.c b/ext/intl/collator/collator_sort.c deleted file mode 100644 index 75466aacb07a..000000000000 --- a/ext/intl/collator/collator_sort.c +++ /dev/null @@ -1,565 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "collator.h" -#include "collator_class.h" -#include "collator_sort.h" -#include "collator_convert.h" -#include "intl_convert.h" - -#if !defined(HAVE_PTRDIFF_T) && !defined(_PTRDIFF_T_DEFINED) -typedef zend_long ptrdiff_t; -#endif - -/** - * Declare 'index' which will point to sort key in sort key - * buffer. - */ -typedef struct _collator_sort_key_index { - char* key; /* pointer to sort key */ - zval* zstr; /* pointer to original string(hash-item) */ -} collator_sort_key_index_t; - -ZEND_EXTERN_MODULE_GLOBALS( intl ) - -static const size_t DEF_SORT_KEYS_BUF_SIZE = 1048576; -static const size_t DEF_SORT_KEYS_BUF_INCREMENT = 1048576; - -static const size_t DEF_SORT_KEYS_INDX_BUF_SIZE = 1048576; -static const size_t DEF_SORT_KEYS_INDX_BUF_INCREMENT = 1048576; - -static const size_t DEF_UTF16_BUF_SIZE = 1024; - -/* {{{ collator_regular_compare_function */ -static int collator_regular_compare_function(zval *result, zval *op1, zval *op2) -{ - int rc = SUCCESS; - zval str1, str2; - zval num1, num2; - zval norm1, norm2; - zval *num1_p = NULL, *num2_p = NULL; - zval *norm1_p = NULL, *norm2_p = NULL; - zval *str1_p, *str2_p; - - ZVAL_NULL(&str1); - str1_p = collator_convert_object_to_string( op1, &str1 ); - ZVAL_NULL(&str2); - str2_p = collator_convert_object_to_string( op2, &str2 ); - - /* If both args are strings AND either of args is not numeric string - * then use ICU-compare. Otherwise PHP-compare. */ - if( Z_TYPE_P(str1_p) == IS_STRING && Z_TYPE_P(str2_p) == IS_STRING && - ( str1_p == ( num1_p = collator_convert_string_to_number_if_possible( str1_p, &num1 ) ) || - str2_p == ( num2_p = collator_convert_string_to_number_if_possible( str2_p, &num2 ) ) ) ) - { - /* Compare the strings using ICU. */ - ZEND_ASSERT(INTL_G(current_collator) != NULL); - ZVAL_LONG(result, ucol_strcoll( - INTL_G(current_collator), - INTL_ZSTR_VAL(Z_STR_P(str1_p)), INTL_ZSTR_LEN(Z_STR_P(str1_p)), - INTL_ZSTR_VAL(Z_STR_P(str2_p)), INTL_ZSTR_LEN(Z_STR_P(str2_p)) )); - } - else - { - /* num1 is set if str1 and str2 are strings. */ - if( num1_p ) - { - if( num1_p == str1_p ) - { - /* str1 is string but not numeric string - * just convert it to utf8. - */ - norm1_p = collator_convert_zstr_utf16_to_utf8( str1_p, &norm1 ); - - /* num2 is not set but str2 is string => do normalization. */ - norm2_p = collator_normalize_sort_argument( str2_p, &norm2 ); - } - else - { - /* str1 is numeric strings => passthru to PHP-compare. */ - Z_TRY_ADDREF_P(num1_p); - norm1_p = num1_p; - - /* str2 is numeric strings => passthru to PHP-compare. */ - Z_TRY_ADDREF_P(num2_p); - norm2_p = num2_p; - } - } - else - { - /* num1 is not set if str1 or str2 is not a string => do normalization. */ - norm1_p = collator_normalize_sort_argument( str1_p, &norm1 ); - - /* if num1 is not set then num2 is not set as well => do normalization. */ - norm2_p = collator_normalize_sort_argument( str2_p, &norm2 ); - } - - rc = compare_function( result, norm1_p, norm2_p ); - - zval_ptr_dtor( norm1_p ); - zval_ptr_dtor( norm2_p ); - } - - if( num1_p ) - zval_ptr_dtor( num1_p ); - - if( num2_p ) - zval_ptr_dtor( num2_p ); - - zval_ptr_dtor( str1_p ); - zval_ptr_dtor( str2_p ); - - return rc; -} -/* }}} */ - -/* {{{ collator_numeric_compare_function - * Convert input args to double and compare it. - */ -static int collator_numeric_compare_function(zval *result, zval *op1, zval *op2) -{ - zval num1, num2; - zval *num1_p = NULL; - zval *num2_p = NULL; - - if( Z_TYPE_P(op1) == IS_STRING ) - { - num1_p = collator_convert_string_to_double( op1, &num1 ); - op1 = num1_p; - } - - if( Z_TYPE_P(op2) == IS_STRING ) - { - num2_p = collator_convert_string_to_double( op2, &num2 ); - op2 = num2_p; - } - - ZVAL_LONG(result, numeric_compare_function(op1, op2)); - - if( num1_p ) - zval_ptr_dtor( num1_p ); - if( num2_p ) - zval_ptr_dtor( num2_p ); - - return SUCCESS; -} -/* }}} */ - -/* {{{ collator_icu_compare_function - * Direct use of ucol_strcoll. -*/ -static int collator_icu_compare_function(zval *result, zval *op1, zval *op2) -{ - int rc = SUCCESS; - zend_string *str1 = collator_zval_to_string(op1); - zend_string *str2 = collator_zval_to_string(op2); - - /* Compare the strings using ICU. */ - ZEND_ASSERT(INTL_G(current_collator) != NULL); - ZVAL_LONG(result, ucol_strcoll( - INTL_G(current_collator), - INTL_ZSTR_VAL(str1), INTL_ZSTR_LEN(str1), - INTL_ZSTR_VAL(str2), INTL_ZSTR_LEN(str2) )); - - zend_string_release(str1); - zend_string_release(str2); - - return rc; -} -/* }}} */ - -/* {{{ collator_compare_func - * Taken from PHP7 source (array_data_compare). - */ -static int collator_compare_func(Bucket *f, Bucket *s) -{ - zval result; - zval *first = &f->val; - zval *second = &s->val; - - if( INTL_G(compare_func)( &result, first, second) == FAILURE ) - return 0; - - if( Z_TYPE(result) == IS_DOUBLE ) - { - if( Z_DVAL(result) < 0 ) - return -1; - else if( Z_DVAL(result) > 0 ) - return 1; - else - return 0; - } - - convert_to_long(&result); - - if( Z_LVAL(result) < 0 ) - return -1; - else if( Z_LVAL(result) > 0 ) - return 1; - - return 0; -} -/* }}} */ - -/* {{{ Compare sort keys */ -static int collator_cmp_sort_keys( const void *p1, const void *p2 ) -{ - char* key1 = ((collator_sort_key_index_t*)p1)->key; - char* key2 = ((collator_sort_key_index_t*)p2)->key; - - return strcmp( key1, key2 ); -} -/* }}} */ - -/* {{{ Choose compare function according to sort flags. */ -static collator_compare_func_t collator_get_compare_function( const zend_long sort_flags ) -{ - collator_compare_func_t func; - - switch( sort_flags ) - { - case COLLATOR_SORT_NUMERIC: - func = collator_numeric_compare_function; - break; - - case COLLATOR_SORT_STRING: - func = collator_icu_compare_function; - break; - - case COLLATOR_SORT_REGULAR: - default: - func = collator_regular_compare_function; - break; - } - - return func; -} -/* }}} */ - -/* {{{ Common code shared by collator_sort() and collator_asort() API functions. */ -static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) -{ - UCollator* saved_collator; - zval* array = NULL; - HashTable* hash = NULL; - zend_long sort_flags = COLLATOR_SORT_REGULAR; - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa/|l", - &object, Collator_ce_ptr, &array, &sort_flags ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - if (!co->ucoll) { - zend_throw_error(NULL, "Object not initialized"); - RETURN_THROWS(); - } - - /* Set 'compare function' according to sort flags. */ - INTL_G(compare_func) = collator_get_compare_function( sort_flags ); - - hash = Z_ARRVAL_P( array ); - - /* Convert strings in the specified array from UTF-8 to UTF-16. */ - collator_convert_hash_from_utf8_to_utf16( hash, COLLATOR_ERROR_CODE_P( co ) ); - COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-8 to UTF-16" ); - - /* Save specified collator in the request-global (?) variable. */ - saved_collator = INTL_G( current_collator ); - INTL_G( current_collator ) = co->ucoll; - - /* Sort specified array. */ - zend_hash_sort(hash, collator_compare_func, renumber); - - /* Restore saved collator. */ - INTL_G( current_collator ) = saved_collator; - - /* Convert strings in the specified array back to UTF-8. */ - collator_convert_hash_from_utf16_to_utf8( hash, COLLATOR_ERROR_CODE_P( co ) ); - COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-16 to UTF-8" ); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Sort array using specified collator. */ -PHP_FUNCTION( collator_sort ) -{ - collator_sort_internal( true, INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -static void collator_sortkey_swap(collator_sort_key_index_t *p, collator_sort_key_index_t *q) /* {{{ */ -{ - collator_sort_key_index_t t; - t = *p; - *p = *q; - *q = t; -} -/* }}} */ - -/* {{{ Equivalent to standard PHP sort using Collator. - * Uses ICU ucol_getSortKey for performance. - */ -PHP_FUNCTION( collator_sort_with_sort_keys ) -{ - zval* array = NULL; - zval garbage; - HashTable* hash = NULL; - zval* hashData = NULL; /* currently processed item of input hash */ - - char* sortKeyBuf = NULL; /* buffer to store sort keys */ - uint32_t sortKeyBufSize = DEF_SORT_KEYS_BUF_SIZE; /* buffer size */ - ptrdiff_t sortKeyBufOffset = 0; /* pos in buffer to store sort key */ - uint32_t sortKeyLen = 0; /* the length of currently processing key */ - uint32_t bufLeft = 0; - uint32_t bufIncrement = 0; - - collator_sort_key_index_t* sortKeyIndxBuf = NULL; /* buffer to store 'indexes' which will be passed to 'qsort' */ - uint32_t sortKeyIndxBufSize = DEF_SORT_KEYS_INDX_BUF_SIZE; - uint32_t sortKeyIndxSize = sizeof( collator_sort_key_index_t ); - - uint32_t sortKeyCount = 0; - uint32_t j = 0; - - UChar* utf16_buf = NULL; /* tmp buffer to hold current processing string in utf-16 */ - int utf16_buf_size = DEF_UTF16_BUF_SIZE; /* the length of utf16_buf */ - int utf16_len = 0; /* length of converted string */ - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa", - &object, Collator_ce_ptr, &array ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - if (!co || !co->ucoll) { - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); - zend_throw_error(NULL, "Object not initialized"); - - RETURN_THROWS(); - } - - /* - * Sort specified array. - */ - hash = Z_ARRVAL_P( array ); - - if( !hash || zend_hash_num_elements( hash ) == 0 ) - RETURN_TRUE; - - /* Create bufers */ - sortKeyBuf = ecalloc( sortKeyBufSize, sizeof( char ) ); - sortKeyIndxBuf = ecalloc( sortKeyIndxBufSize, sizeof( uint8_t ) ); - utf16_buf = eumalloc( utf16_buf_size ); - - /* Iterate through input hash and create a sort key for each value. */ - ZEND_HASH_FOREACH_VAL(hash, hashData) { - /* Convert current hash item from UTF-8 to UTF-16LE and save the result to utf16_buf. */ - - utf16_len = utf16_buf_size; - - /* Process string values only. */ - if( Z_TYPE_P( hashData ) == IS_STRING ) - { - intl_convert_utf8_to_utf16( &utf16_buf, &utf16_len, Z_STRVAL_P( hashData ), Z_STRLEN_P( hashData ), COLLATOR_ERROR_CODE_P( co ) ); - - if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) - { - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Sort with sort keys failed", 0 ); - - if( utf16_buf ) - efree( utf16_buf ); - - efree( sortKeyIndxBuf ); - efree( sortKeyBuf ); - - RETURN_FALSE; - } - } - else - { - /* Set empty string */ - utf16_len = 0; - utf16_buf[utf16_len] = 0; - } - - if( (utf16_len + 1) > utf16_buf_size ) - utf16_buf_size = utf16_len + 1; - - /* Get sort key, reallocating the buffer if needed. */ - bufLeft = sortKeyBufSize - sortKeyBufOffset; - - sortKeyLen = ucol_getSortKey( co->ucoll, - utf16_buf, - utf16_len, - (uint8_t*)sortKeyBuf + sortKeyBufOffset, - bufLeft ); - - /* check for sortKeyBuf overflow, increasing its size of the buffer if needed */ - if( sortKeyLen > bufLeft ) - { - bufIncrement = ( sortKeyLen > DEF_SORT_KEYS_BUF_INCREMENT ) ? sortKeyLen : DEF_SORT_KEYS_BUF_INCREMENT; - - sortKeyBufSize += bufIncrement; - bufLeft += bufIncrement; - - sortKeyBuf = erealloc( sortKeyBuf, sortKeyBufSize ); - - sortKeyLen = ucol_getSortKey( co->ucoll, utf16_buf, utf16_len, (uint8_t*)sortKeyBuf + sortKeyBufOffset, bufLeft ); - } - - /* check sortKeyIndxBuf overflow, increasing its size of the buffer if needed */ - if( ( sortKeyCount + 1 ) * sortKeyIndxSize > sortKeyIndxBufSize ) - { - bufIncrement = ( sortKeyIndxSize > DEF_SORT_KEYS_INDX_BUF_INCREMENT ) ? sortKeyIndxSize : DEF_SORT_KEYS_INDX_BUF_INCREMENT; - - sortKeyIndxBufSize += bufIncrement; - - sortKeyIndxBuf = erealloc( sortKeyIndxBuf, sortKeyIndxBufSize ); - } - - sortKeyIndxBuf[sortKeyCount].key = (char*)sortKeyBufOffset; /* remember just offset, cause address */ - /* of 'sortKeyBuf' may be changed due to realloc. */ - sortKeyIndxBuf[sortKeyCount].zstr = hashData; - - sortKeyBufOffset += sortKeyLen; - ++sortKeyCount; - - } ZEND_HASH_FOREACH_END(); - - /* update ptrs to point to valid keys. */ - for( j = 0; j < sortKeyCount; j++ ) - sortKeyIndxBuf[j].key = sortKeyBuf + (ptrdiff_t)sortKeyIndxBuf[j].key; - - /* sort it */ - zend_sort( sortKeyIndxBuf, sortKeyCount, - sortKeyIndxSize, collator_cmp_sort_keys, (swap_func_t)collator_sortkey_swap); - - ZVAL_COPY_VALUE(&garbage, array); - /* for resulting hash we'll assign new hash keys rather then reordering */ - array_init_size(array, sortKeyCount); - zend_hash_real_init_packed(Z_ARRVAL_P(array)); - - for( j = 0; j < sortKeyCount; j++ ) - { - Z_TRY_ADDREF_P( sortKeyIndxBuf[j].zstr ); - zend_hash_next_index_insert( Z_ARRVAL_P(array), sortKeyIndxBuf[j].zstr); - } - - if( utf16_buf ) - efree( utf16_buf ); - - zval_ptr_dtor(&garbage); - efree( sortKeyIndxBuf ); - efree( sortKeyBuf ); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Sort array using specified collator, maintaining index association. */ -PHP_FUNCTION( collator_asort ) -{ - collator_sort_internal( false, INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ Get a sort key for a string from a Collator. */ -PHP_FUNCTION( collator_get_sort_key ) -{ - char* str = NULL; - size_t str_len = 0; - UChar* ustr = NULL; - int32_t ustr_len = 0; - int key_len = 0; - zend_string* key_str; - - COLLATOR_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", - &object, Collator_ce_ptr, &str, &str_len ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - COLLATOR_METHOD_FETCH_OBJECT; - - if (!co || !co->ucoll) { - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Object not initialized", 0 ); - zend_throw_error(NULL, "Object not initialized"); - - RETURN_THROWS(); - } - - /* - * Compare given strings (converting them to UTF-16 first). - */ - - /* First convert the strings to UTF-16. */ - intl_convert_utf8_to_utf16( - &ustr, &ustr_len, str, str_len, COLLATOR_ERROR_CODE_P( co ) ); - if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) - { - /* Set global error code. */ - intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); - - /* Set error messages. */ - intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), - "Error converting first argument to UTF-16", 0 ); - efree( ustr ); - RETURN_FALSE; - } - - /* ucol_getSortKey is exception in that the key length includes the - * NUL terminator*/ - key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, NULL, 0); - if(!key_len) { - efree( ustr ); - RETURN_FALSE; - } - key_str = zend_string_alloc(key_len, 0); - key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, (uint8_t*)ZSTR_VAL(key_str), key_len); - efree( ustr ); - if(!key_len) { - RETURN_FALSE; - } - ZSTR_LEN(key_str) = key_len - 1; - RETVAL_NEW_STR(key_str); -} -/* }}} */ diff --git a/ext/intl/collator/collator_sort.cpp b/ext/intl/collator/collator_sort.cpp new file mode 100644 index 000000000000..2b1122cb747a --- /dev/null +++ b/ext/intl/collator/collator_sort.cpp @@ -0,0 +1,566 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "intl_convert.h" +} +#include "collator.h" +#include "collator_class.h" +#include "collator_sort.h" +#include "collator_convert.h" + +/** + * Declare 'index' which will point to sort key in sort key + * buffer. + */ +typedef struct _collator_sort_key_index { + char* key; /* pointer to sort key */ + zval* zstr; /* pointer to original string(hash-item) */ +} collator_sort_key_index_t; + +ZEND_EXTERN_MODULE_GLOBALS( intl ) + +static const size_t DEF_SORT_KEYS_BUF_SIZE = 1048576; +static const size_t DEF_SORT_KEYS_BUF_INCREMENT = 1048576; + +static const size_t DEF_SORT_KEYS_INDX_BUF_SIZE = 1048576; +static const size_t DEF_SORT_KEYS_INDX_BUF_INCREMENT = 1048576; + +static const size_t DEF_UTF16_BUF_SIZE = 1024; + +/* {{{ collator_regular_compare_function */ +static int collator_regular_compare_function(zval *result, zval *op1, zval *op2) +{ + int rc = SUCCESS; + zval str1, str2; + zval num1, num2; + zval norm1, norm2; + zval *num1_p = nullptr, *num2_p = nullptr; + zval *norm1_p = nullptr, *norm2_p = nullptr; + zval *str1_p, *str2_p; + + ZVAL_NULL(&str1); + str1_p = collator_convert_object_to_string( op1, &str1 ); + ZVAL_NULL(&str2); + str2_p = collator_convert_object_to_string( op2, &str2 ); + + /* If both args are strings AND either of args is not numeric string + * then use ICU-compare. Otherwise PHP-compare. */ + if( Z_TYPE_P(str1_p) == IS_STRING && Z_TYPE_P(str2_p) == IS_STRING && + ( str1_p == ( num1_p = collator_convert_string_to_number_if_possible( str1_p, &num1 ) ) || + str2_p == ( num2_p = collator_convert_string_to_number_if_possible( str2_p, &num2 ) ) ) ) + { + /* Compare the strings using ICU. */ + ZEND_ASSERT(INTL_G(current_collator) != nullptr); + ZVAL_LONG(result, ucol_strcoll( + INTL_G(current_collator), + INTL_ZSTR_VAL(Z_STR_P(str1_p)), INTL_ZSTR_LEN(Z_STR_P(str1_p)), + INTL_ZSTR_VAL(Z_STR_P(str2_p)), INTL_ZSTR_LEN(Z_STR_P(str2_p)) )); + } + else + { + /* num1 is set if str1 and str2 are strings. */ + if( num1_p ) + { + if( num1_p == str1_p ) + { + /* str1 is string but not numeric string + * just convert it to utf8. + */ + norm1_p = collator_convert_zstr_utf16_to_utf8( str1_p, &norm1 ); + + /* num2 is not set but str2 is string => do normalization. */ + norm2_p = collator_normalize_sort_argument( str2_p, &norm2 ); + } + else + { + /* str1 is numeric strings => passthru to PHP-compare. */ + Z_TRY_ADDREF_P(num1_p); + norm1_p = num1_p; + + /* str2 is numeric strings => passthru to PHP-compare. */ + Z_TRY_ADDREF_P(num2_p); + norm2_p = num2_p; + } + } + else + { + /* num1 is not set if str1 or str2 is not a string => do normalization. */ + norm1_p = collator_normalize_sort_argument( str1_p, &norm1 ); + + /* if num1 is not set then num2 is not set as well => do normalization. */ + norm2_p = collator_normalize_sort_argument( str2_p, &norm2 ); + } + + rc = compare_function( result, norm1_p, norm2_p ); + + zval_ptr_dtor( norm1_p ); + zval_ptr_dtor( norm2_p ); + } + + if( num1_p ) + zval_ptr_dtor( num1_p ); + + if( num2_p ) + zval_ptr_dtor( num2_p ); + + zval_ptr_dtor( str1_p ); + zval_ptr_dtor( str2_p ); + + return rc; +} +/* }}} */ + +/* {{{ collator_numeric_compare_function + * Convert input args to double and compare it. + */ +static int collator_numeric_compare_function(zval *result, zval *op1, zval *op2) +{ + zval num1, num2; + zval *num1_p = nullptr; + zval *num2_p = nullptr; + + if( Z_TYPE_P(op1) == IS_STRING ) + { + num1_p = collator_convert_string_to_double( op1, &num1 ); + op1 = num1_p; + } + + if( Z_TYPE_P(op2) == IS_STRING ) + { + num2_p = collator_convert_string_to_double( op2, &num2 ); + op2 = num2_p; + } + + ZVAL_LONG(result, numeric_compare_function(op1, op2)); + + if( num1_p ) + zval_ptr_dtor( num1_p ); + if( num2_p ) + zval_ptr_dtor( num2_p ); + + return SUCCESS; +} +/* }}} */ + +/* {{{ collator_icu_compare_function + * Direct use of ucol_strcoll. +*/ +static int collator_icu_compare_function(zval *result, zval *op1, zval *op2) +{ + int rc = SUCCESS; + zend_string *str1 = collator_zval_to_string(op1); + zend_string *str2 = collator_zval_to_string(op2); + + /* Compare the strings using ICU. */ + ZEND_ASSERT(INTL_G(current_collator) != nullptr); + ZVAL_LONG(result, ucol_strcoll( + INTL_G(current_collator), + INTL_ZSTR_VAL(str1), INTL_ZSTR_LEN(str1), + INTL_ZSTR_VAL(str2), INTL_ZSTR_LEN(str2) )); + + zend_string_release(str1); + zend_string_release(str2); + + return rc; +} +/* }}} */ + +/* {{{ collator_compare_func + * Taken from PHP7 source (array_data_compare). + */ +static int collator_compare_func(Bucket *f, Bucket *s) +{ + zval result; + zval *first = &f->val; + zval *second = &s->val; + + if( INTL_G(compare_func)( &result, first, second) == FAILURE ) + return 0; + + if( Z_TYPE(result) == IS_DOUBLE ) + { + if( Z_DVAL(result) < 0 ) + return -1; + else if( Z_DVAL(result) > 0 ) + return 1; + else + return 0; + } + + convert_to_long(&result); + + if( Z_LVAL(result) < 0 ) + return -1; + else if( Z_LVAL(result) > 0 ) + return 1; + + return 0; +} +/* }}} */ + +/* {{{ Compare sort keys */ +static int collator_cmp_sort_keys( const void *p1, const void *p2 ) +{ + char* key1 = ((collator_sort_key_index_t*)p1)->key; + char* key2 = ((collator_sort_key_index_t*)p2)->key; + + return strcmp( key1, key2 ); +} +/* }}} */ + +/* {{{ Choose compare function according to sort flags. */ +static collator_compare_func_t collator_get_compare_function( const zend_long sort_flags ) +{ + collator_compare_func_t func; + + switch( sort_flags ) + { + case COLLATOR_SORT_NUMERIC: + func = collator_numeric_compare_function; + break; + + case COLLATOR_SORT_STRING: + func = collator_icu_compare_function; + break; + + case COLLATOR_SORT_REGULAR: + default: + func = collator_regular_compare_function; + break; + } + + return func; +} +/* }}} */ + +/* {{{ Common code shared by collator_sort() and collator_asort() API functions. */ +static void collator_sort_internal( int renumber, INTERNAL_FUNCTION_PARAMETERS ) +{ + UCollator* saved_collator; + zval* array = nullptr; + HashTable* hash = nullptr; + zend_long sort_flags = COLLATOR_SORT_REGULAR; + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa/|l", + &object, Collator_ce_ptr, &array, &sort_flags ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + if (!co->ucoll) { + zend_throw_error(NULL, "Object not initialized"); + RETURN_THROWS(); + } + + /* Set 'compare function' according to sort flags. */ + INTL_G(compare_func) = collator_get_compare_function( sort_flags ); + + hash = Z_ARRVAL_P( array ); + + /* Convert strings in the specified array from UTF-8 to UTF-16. */ + collator_convert_hash_from_utf8_to_utf16( hash, COLLATOR_ERROR_CODE_P( co ) ); + COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-8 to UTF-16" ); + + /* Save specified collator in the request-global (?) variable. */ + saved_collator = INTL_G( current_collator ); + INTL_G( current_collator ) = co->ucoll; + + /* Sort specified array. */ + zend_hash_sort(hash, collator_compare_func, renumber); + + /* Restore saved collator. */ + INTL_G( current_collator ) = saved_collator; + + /* Convert strings in the specified array back to UTF-8. */ + collator_convert_hash_from_utf16_to_utf8( hash, COLLATOR_ERROR_CODE_P( co ) ); + COLLATOR_CHECK_STATUS( co, "Error converting hash from UTF-16 to UTF-8" ); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Sort array using specified collator. */ +U_CFUNC PHP_FUNCTION( collator_sort ) +{ + collator_sort_internal( true, INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +static void collator_sortkey_swap(collator_sort_key_index_t *p, collator_sort_key_index_t *q) /* {{{ */ +{ + collator_sort_key_index_t t; + t = *p; + *p = *q; + *q = t; +} +/* }}} */ + +/* {{{ Equivalent to standard PHP sort using Collator. + * Uses ICU ucol_getSortKey for performance. + */ +U_CFUNC PHP_FUNCTION( collator_sort_with_sort_keys ) +{ + zval* array = nullptr; + zval garbage; + HashTable* hash = nullptr; + zval* hashData = nullptr; /* currently processed item of input hash */ + + char* sortKeyBuf = nullptr; /* buffer to store sort keys */ + uint32_t sortKeyBufSize = DEF_SORT_KEYS_BUF_SIZE; /* buffer size */ + ptrdiff_t sortKeyBufOffset = 0; /* pos in buffer to store sort key */ + uint32_t sortKeyLen = 0; /* the length of currently processing key */ + uint32_t bufLeft = 0; + uint32_t bufIncrement = 0; + + collator_sort_key_index_t* sortKeyIndxBuf = nullptr; /* buffer to store 'indexes' which will be passed to 'qsort' */ + uint32_t sortKeyIndxBufSize = DEF_SORT_KEYS_INDX_BUF_SIZE; + uint32_t sortKeyIndxSize = sizeof( collator_sort_key_index_t ); + + uint32_t sortKeyCount = 0; + uint32_t j = 0; + + UChar* utf16_buf = nullptr; /* tmp buffer to hold current processing string in utf-16 */ + int utf16_buf_size = DEF_UTF16_BUF_SIZE; /* the length of utf16_buf */ + int utf16_len = 0; /* length of converted string */ + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa", + &object, Collator_ce_ptr, &array ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + if (!co || !co->ucoll) { + intl_error_set_code( nullptr, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Object not initialized"); + zend_throw_error(NULL, "Object not initialized"); + + RETURN_THROWS(); + } + + /* + * Sort specified array. + */ + hash = Z_ARRVAL_P( array ); + + if( !hash || zend_hash_num_elements( hash ) == 0 ) + RETURN_TRUE; + + /* Create buffers */ + sortKeyBuf = reinterpret_cast(ecalloc( sortKeyBufSize, sizeof( char ) )); + sortKeyIndxBuf = reinterpret_cast(ecalloc( sortKeyIndxBufSize, sizeof( uint8_t ) )); + utf16_buf = eumalloc( utf16_buf_size ); + + /* Iterate through input hash and create a sort key for each value. */ + ZEND_HASH_FOREACH_VAL(hash, hashData) { + /* Convert current hash item from UTF-8 to UTF-16LE and save the result to utf16_buf. */ + + utf16_len = utf16_buf_size; + + /* Process string values only. */ + if( Z_TYPE_P( hashData ) == IS_STRING ) + { + intl_convert_utf8_to_utf16( &utf16_buf, &utf16_len, Z_STRVAL_P( hashData ), Z_STRLEN_P( hashData ), COLLATOR_ERROR_CODE_P( co ) ); + + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) + { + intl_error_set_code( nullptr, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Sort with sort keys failed"); + + if( utf16_buf ) + efree( utf16_buf ); + + efree( sortKeyIndxBuf ); + efree( sortKeyBuf ); + + RETURN_FALSE; + } + } + else + { + /* Set empty string */ + utf16_len = 0; + utf16_buf[utf16_len] = 0; + } + + if( (utf16_len + 1) > utf16_buf_size ) + utf16_buf_size = utf16_len + 1; + + /* Get sort key, reallocating the buffer if needed. */ + bufLeft = sortKeyBufSize - sortKeyBufOffset; + + sortKeyLen = ucol_getSortKey( co->ucoll, + utf16_buf, + utf16_len, + (uint8_t*)sortKeyBuf + sortKeyBufOffset, + bufLeft ); + + /* check for sortKeyBuf overflow, increasing its size of the buffer if needed */ + if( sortKeyLen > bufLeft ) + { + bufIncrement = ( sortKeyLen > DEF_SORT_KEYS_BUF_INCREMENT ) ? sortKeyLen : DEF_SORT_KEYS_BUF_INCREMENT; + + sortKeyBufSize += bufIncrement; + bufLeft += bufIncrement; + + sortKeyBuf = reinterpret_cast(erealloc( sortKeyBuf, sortKeyBufSize )); + + sortKeyLen = ucol_getSortKey( co->ucoll, utf16_buf, utf16_len, (uint8_t*)sortKeyBuf + sortKeyBufOffset, bufLeft ); + } + + /* check sortKeyIndxBuf overflow, increasing its size of the buffer if needed */ + if( ( sortKeyCount + 1 ) * sortKeyIndxSize > sortKeyIndxBufSize ) + { + bufIncrement = ( sortKeyIndxSize > DEF_SORT_KEYS_INDX_BUF_INCREMENT ) ? sortKeyIndxSize : DEF_SORT_KEYS_INDX_BUF_INCREMENT; + + sortKeyIndxBufSize += bufIncrement; + + sortKeyIndxBuf = reinterpret_cast(erealloc( sortKeyIndxBuf, sortKeyIndxBufSize )); + } + + sortKeyIndxBuf[sortKeyCount].key = (char*)sortKeyBufOffset; /* remember just offset, cause address */ + /* of 'sortKeyBuf' may be changed due to realloc. */ + sortKeyIndxBuf[sortKeyCount].zstr = hashData; + + sortKeyBufOffset += sortKeyLen; + ++sortKeyCount; + + } ZEND_HASH_FOREACH_END(); + + /* update ptrs to point to valid keys. */ + for( j = 0; j < sortKeyCount; j++ ) + sortKeyIndxBuf[j].key = sortKeyBuf + (ptrdiff_t)sortKeyIndxBuf[j].key; + + /* sort it */ + zend_sort( sortKeyIndxBuf, sortKeyCount, + sortKeyIndxSize, collator_cmp_sort_keys, (swap_func_t)collator_sortkey_swap); + + ZVAL_COPY_VALUE(&garbage, array); + /* for resulting hash we'll assign new hash keys rather then reordering */ + array_init_size(array, sortKeyCount); + zend_hash_real_init_packed(Z_ARRVAL_P(array)); + + for( j = 0; j < sortKeyCount; j++ ) + { + Z_TRY_ADDREF_P( sortKeyIndxBuf[j].zstr ); + zend_hash_next_index_insert( Z_ARRVAL_P(array), sortKeyIndxBuf[j].zstr); + } + + if( utf16_buf ) + efree( utf16_buf ); + + zval_ptr_dtor(&garbage); + efree( sortKeyIndxBuf ); + efree( sortKeyBuf ); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Sort array using specified collator, maintaining index association. */ +U_CFUNC PHP_FUNCTION( collator_asort ) +{ + collator_sort_internal( false, INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ Get a sort key for a string from a Collator. */ +U_CFUNC PHP_FUNCTION( collator_get_sort_key ) +{ + char* str = nullptr; + size_t str_len = 0; + UChar* ustr = nullptr; + int32_t ustr_len = 0; + int key_len = 0; + zend_string* key_str; + + COLLATOR_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", + &object, Collator_ce_ptr, &str, &str_len ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + COLLATOR_METHOD_FETCH_OBJECT; + + if (!co || !co->ucoll) { + intl_error_set_code( nullptr, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Object not initialized"); + zend_throw_error(NULL, "Object not initialized"); + + RETURN_THROWS(); + } + + /* + * Compare given strings (converting them to UTF-16 first). + */ + + /* First convert the strings to UTF-16. */ + intl_convert_utf8_to_utf16( + &ustr, &ustr_len, str, str_len, COLLATOR_ERROR_CODE_P( co ) ); + if( U_FAILURE( COLLATOR_ERROR_CODE( co ) ) ) + { + /* Set global error code. */ + intl_error_set_code( nullptr, COLLATOR_ERROR_CODE( co ) ); + + /* Set error messages. */ + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), "Error converting first argument to UTF-16"); + efree( ustr ); + RETURN_FALSE; + } + + /* ucol_getSortKey is exception in that the key length includes the + * NUL terminator*/ + key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, nullptr, 0); + if(!key_len) { + efree( ustr ); + RETURN_FALSE; + } + key_str = zend_string_alloc(key_len, 0); + key_len = ucol_getSortKey(co->ucoll, ustr, ustr_len, (uint8_t*)ZSTR_VAL(key_str), key_len); + efree( ustr ); + if(!key_len) { + zend_string_efree(key_str); + RETURN_FALSE; + } + ZSTR_LEN(key_str) = key_len - 1; + RETVAL_NEW_STR(key_str); +} +/* }}} */ diff --git a/ext/intl/collator/collator_sort.h b/ext/intl/collator/collator_sort.h index 53abc1028a0e..6b4c5766da6b 100644 --- a/ext/intl/collator/collator_sort.h +++ b/ext/intl/collator/collator_sort.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/common/common.stub.php b/ext/intl/common/common.stub.php index c76ac9f756d4..bbb8ad217939 100644 --- a/ext/intl/common/common.stub.php +++ b/ext/intl/common/common.stub.php @@ -423,11 +423,10 @@ */ const U_MULTIPLE_DECIMAL_SEPARATORS = UNKNOWN; /** - * Typo: kept for backward compatibility. Use U_MULTIPLE_DECIMAL_SEPARATORS * @var int - * @deprecated * @cvalue U_MULTIPLE_DECIMAL_SEPERATORS */ +#[\Deprecated(since: '8.3', message: 'use U_MULTIPLE_DECIMAL_SEPARATORS instead')] const U_MULTIPLE_DECIMAL_SEPERATORS = UNKNOWN; /** * @var int diff --git a/ext/intl/common/common_arginfo.h b/ext/intl/common/common_arginfo.h index c5e023ecb888..2a15cccab892 100644 --- a/ext/intl/common/common_arginfo.h +++ b/ext/intl/common/common_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 83971f2cec8c413d6207382e6ebc4ebf500e805f */ +/* This is a generated file, edit common.stub.php instead. + * Stub hash: 9ed8bfc955a557c02171ec12b4634c60c6fb513e */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlIterator_current, 0, 0, IS_MIXED, 0) ZEND_END_ARG_INFO() @@ -113,7 +113,7 @@ static void register_common_symbols(int module_number) REGISTER_LONG_CONSTANT("U_UNEXPECTED_TOKEN", U_UNEXPECTED_TOKEN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("U_FMT_PARSE_ERROR_START", U_FMT_PARSE_ERROR_START, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("U_MULTIPLE_DECIMAL_SEPARATORS", U_MULTIPLE_DECIMAL_SEPARATORS, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("U_MULTIPLE_DECIMAL_SEPERATORS", U_MULTIPLE_DECIMAL_SEPERATORS, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_U_MULTIPLE_DECIMAL_SEPERATORS = REGISTER_LONG_CONSTANT("U_MULTIPLE_DECIMAL_SEPERATORS", U_MULTIPLE_DECIMAL_SEPERATORS, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("U_MULTIPLE_EXPONENTIAL_SYMBOLS", U_MULTIPLE_EXPONENTIAL_SYMBOLS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("U_MALFORMED_EXPONENTIAL_PATTERN", U_MALFORMED_EXPONENTIAL_PATTERN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("U_MULTIPLE_PERCENT_SYMBOLS", U_MULTIPLE_PERCENT_SYMBOLS, CONST_PERSISTENT); @@ -172,6 +172,14 @@ static void register_common_symbols(int module_number) REGISTER_LONG_CONSTANT("U_STRINGPREP_UNASSIGNED_ERROR", U_STRINGPREP_UNASSIGNED_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("U_STRINGPREP_CHECK_BIDI_ERROR", U_STRINGPREP_CHECK_BIDI_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("U_ERROR_LIMIT", U_ERROR_LIMIT, CONST_PERSISTENT); + + + zend_attribute *attribute_Deprecated_const_U_MULTIPLE_DECIMAL_SEPERATORS_0 = zend_add_global_constant_attribute(const_U_MULTIPLE_DECIMAL_SEPERATORS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_U_MULTIPLE_DECIMAL_SEPERATORS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); + attribute_Deprecated_const_U_MULTIPLE_DECIMAL_SEPERATORS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_U_MULTIPLE_DECIMAL_SEPERATORS_0_arg1_str = zend_string_init("use U_MULTIPLE_DECIMAL_SEPARATORS instead", strlen("use U_MULTIPLE_DECIMAL_SEPARATORS instead"), 1); + ZVAL_STR(&attribute_Deprecated_const_U_MULTIPLE_DECIMAL_SEPERATORS_0->args[1].value, attribute_Deprecated_const_U_MULTIPLE_DECIMAL_SEPERATORS_0_arg1_str); + attribute_Deprecated_const_U_MULTIPLE_DECIMAL_SEPERATORS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_IntlIterator(zend_class_entry *class_entry_Iterator) diff --git a/ext/intl/common/common_date.cpp b/ext/intl/common/common_date.cpp index e27a67ec55ad..fb5ca6edaebe 100644 --- a/ext/intl/common/common_date.cpp +++ b/ext/intl/common/common_date.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -30,11 +30,9 @@ using icu::UnicodeString; /* {{{ timezone_convert_datetimezone * The timezone in DateTime and DateTimeZone is not unified. */ -U_CFUNC TimeZone *timezone_convert_datetimezone(int type, - void *object, - int is_datetime, - intl_error *outside_error, - const char *func) +U_CFUNC TimeZone *timezone_convert_datetimezone( + int type, void *object, bool is_datetime, + intl_error *outside_error) { char *id = NULL, offset_id[] = "GMT+00:00"; @@ -58,11 +56,8 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, minutes *= minutes > 0 ? 1 : -1; if (offset_mins <= -24 * 60 || offset_mins >= 24 * 60) { - spprintf(&message, 0, "%s: object has an time zone offset " - "that's too large", func); intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "object has an time zone offset that's too large"); return NULL; } @@ -82,10 +77,9 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, UnicodeString s = UnicodeString(id, id_len, US_INV); timeZone = TimeZone::createTimeZone(s); if (*timeZone == TimeZone::getUnknown()) { - spprintf(&message, 0, "%s: time zone id '%s' " - "extracted from ext/date DateTimeZone not recognized", func, id); - intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); + spprintf(&message, 0, "time zone id '%s' " + "extracted from ext/date DateTimeZone not recognized", id); + intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message); efree(message); delete timeZone; return NULL; @@ -95,7 +89,7 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, /* }}} */ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz, - intl_error *err, const char *func) + intl_error *err) { char *message; php_date_obj *datetime = php_date_obj_from_obj(obj); @@ -125,8 +119,8 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti // TODO: Remove this when DateTimeInterface::getTimestamp() no longer has a tentative return type if (Z_TYPE(retval) != IS_LONG) { zval_ptr_dtor(&retval); - spprintf(&message, 0, "%s: %s::getTimestamp() did not return an int", func, ZSTR_VAL(obj->ce->name)); - intl_errors_set(err, U_INTERNAL_PROGRAM_ERROR, message, 1); + spprintf(&message, 0, "%s::getTimestamp() did not return an int", ZSTR_VAL(obj->ce->name)); + intl_errors_set(err, U_INTERNAL_PROGRAM_ERROR, message); efree(message); return FAILURE; } @@ -136,10 +130,9 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti if (tz) { if (!datetime->time) { - spprintf(&message, 0, "%s: the %s object is not properly " - "initialized", func, ZSTR_VAL(obj->ce->name)); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); + spprintf(&message, 0, "the %s object is not properly " + "initialized", ZSTR_VAL(obj->ce->name)); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message); efree(message); return FAILURE; } @@ -147,13 +140,10 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti *tz = TimeZone::getGMT()->clone(); } else { *tz = timezone_convert_datetimezone(datetime->time->zone_type, - datetime, 1, NULL, func); + datetime, 1, NULL); if (*tz == NULL) { - spprintf(&message, 0, "%s: could not convert DateTime's " - "time zone", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "could not convert DateTime's time zone"); return FAILURE; } } @@ -162,12 +152,11 @@ U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, Ti return SUCCESS; } -U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func) +U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err) { double rv = ZEND_NAN; zend_long lv; int type; - char *message; if (err && U_FAILURE(err->code)) { return ZEND_NAN; @@ -182,11 +171,12 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func) } else if (type == IS_LONG) { rv = U_MILLIS_PER_SECOND * (double)lv; } else { - spprintf(&message, 0, "%s: string '%s' is not numeric, " - "which would be required for it to be a valid date", func, + char *message; + spprintf(&message, 0, "string '%s' is not numeric, " + "which would be required for it to be a valid date", Z_STRVAL_P(z)); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); + message); efree(message); } break; @@ -198,42 +188,31 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func) break; case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(z), php_date_get_interface_ce())) { - intl_datetime_decompose(Z_OBJ_P(z), &rv, nullptr, err, func); + intl_datetime_decompose(Z_OBJ_P(z), &rv, nullptr, err); } else if (instanceof_function(Z_OBJCE_P(z), Calendar_ce_ptr)) { Calendar_object *co = Z_INTL_CALENDAR_P(z); if (co->ucal == NULL) { - spprintf(&message, 0, "%s: IntlCalendar object is not properly " - "constructed", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "IntlCalendar object is not properly constructed"); } else { UErrorCode status = UErrorCode(); rv = (double)co->ucal->getTime(status); if (U_FAILURE(status)) { - spprintf(&message, 0, "%s: call to internal " - "Calendar::getTime() has failed", func); - intl_errors_set(err, status, message, 1); - efree(message); + intl_errors_set(err, status, "call to internal Calendar::getTime() has failed"); } } } else { - /* TODO: try with cast(), get() to obtain a number */ - spprintf(&message, 0, "%s: invalid object type for date/time " - "(only IntlCalendar and DateTimeInterface permitted)", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "invalid object type for date/time " + "(only IntlCalendar and DateTimeInterface permitted)"); } break; case IS_REFERENCE: z = Z_REFVAL_P(z); goto try_again; default: - spprintf(&message, 0, "%s: invalid PHP type for date", func); intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - efree(message); + "invalid PHP type for date"); break; } diff --git a/ext/intl/common/common_date.h b/ext/intl/common/common_date.h index e9fac3a02bd5..a3a58eb3b037 100644 --- a/ext/intl/common/common_date.h +++ b/ext/intl/common/common_date.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -24,15 +24,18 @@ U_CDECL_END #ifdef __cplusplus +// TODO once C++ migration done we can drop this workaround +#undef U_SHOW_CPLUSPLUS_API +#define U_SHOW_CPLUSPLUS_API 1 #include using icu::TimeZone; -U_CFUNC TimeZone *timezone_convert_datetimezone(int type, void *object, int is_datetime, intl_error *outside_error, const char *func); -U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz, intl_error *err, const char *func); +U_CFUNC TimeZone *timezone_convert_datetimezone(int type, void *object, bool is_datetime, intl_error *outside_error); +U_CFUNC zend_result intl_datetime_decompose(zend_object *obj, double *millis, TimeZone **tz, intl_error *err); #endif -U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func); +U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err); #endif /* COMMON_DATE_H */ diff --git a/ext/intl/common/common_enum.cpp b/ext/intl/common/common_enum.cpp index 4585a60f077a..379561866941 100644 --- a/ext/intl/common/common_enum.cpp +++ b/ext/intl/common/common_enum.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -21,6 +21,10 @@ // Fix build on Windows/old versions of ICU #include +extern "C" { +#include +} + #include "common_enum.h" #include "common_arginfo.h" @@ -74,8 +78,7 @@ static void string_enum_current_move_forward(zend_object_iterator *iter) intl_error_set_code(NULL, INTLITERATOR_ERROR_CODE(ii)); if (U_FAILURE(INTLITERATOR_ERROR_CODE(ii))) { - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), - "Error fetching next iteration element", 0); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), "Error fetching next iteration element"); } else if (result) { ZVAL_STRINGL(&zoi_iter->current, result, result_length); } //else we've reached the end of the enum, nothing more is required @@ -105,8 +108,7 @@ static void string_enum_rewind(zend_object_iterator *iter) intl_error_set_code(NULL, INTLITERATOR_ERROR_CODE(ii)); if (U_FAILURE(INTLITERATOR_ERROR_CODE(ii))) { - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), - "Error resetting enumeration", 0); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii), "Error resetting enumeration"); } else { iter->funcs->move_forward(iter); } @@ -268,7 +270,7 @@ PHP_METHOD(IntlIterator, rewind) ii->iterator->funcs->rewind(ii->iterator); } else { intl_errors_set(INTLITERATOR_ERROR_P(ii), U_UNSUPPORTED_ERROR, - "IntlIterator::rewind: rewind not supported", 0); + "rewind not supported"); } } @@ -292,7 +294,7 @@ U_CFUNC void intl_register_common_symbols(int module_number) memcpy(&IntlIterator_handlers, &std_object_handlers, sizeof IntlIterator_handlers); - IntlIterator_handlers.offset = XtOffsetOf(IntlIterator_object, zo); + IntlIterator_handlers.offset = offsetof(IntlIterator_object, zo); IntlIterator_handlers.clone_obj = NULL; IntlIterator_handlers.dtor_obj = IntlIterator_objects_dtor; IntlIterator_handlers.free_obj = IntlIterator_objects_free; diff --git a/ext/intl/common/common_enum.h b/ext/intl/common/common_enum.h index 6f0828528901..69633064ee90 100644 --- a/ext/intl/common/common_enum.h +++ b/ext/intl/common/common_enum.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -53,7 +53,7 @@ typedef struct { static inline IntlIterator_object *php_intl_iterator_fetch_object(zend_object *obj) { - return (IntlIterator_object *)((char*)(obj) - XtOffsetOf(IntlIterator_object, zo)); + return ZEND_CONTAINER_OF(obj, IntlIterator_object, zo); } #define Z_INTL_ITERATOR_P(zv) php_intl_iterator_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/common/common_error.c b/ext/intl/common/common_error.c deleted file mode 100644 index 733a1913ad08..000000000000 --- a/ext/intl/common/common_error.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Vadim Savchuk | - | Dmitry Lakhtyuk | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "intl_error.h" - -/* {{{ Get code of the last occurred error. */ -PHP_FUNCTION( intl_get_error_code ) -{ - ZEND_PARSE_PARAMETERS_NONE(); - - RETURN_LONG( intl_error_get_code( NULL ) ); -} -/* }}} */ - -/* {{{ Get text description of the last occurred error. */ -PHP_FUNCTION( intl_get_error_message ) -{ - ZEND_PARSE_PARAMETERS_NONE(); - - RETURN_STR(intl_error_get_message( NULL )); -} -/* }}} */ - -/* {{{ Check whether the given error code indicates a failure. - * Returns true if it does, and false if the code - * indicates success or a warning. - */ -PHP_FUNCTION( intl_is_failure ) -{ - zend_long err_code; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(err_code) - ZEND_PARSE_PARAMETERS_END(); - - RETURN_BOOL( U_FAILURE( err_code ) ); -} -/* }}} */ - -/* {{{ Return a string for a given error code. - * The string will be the same as the name of the error code constant. - */ -PHP_FUNCTION( intl_error_name ) -{ - zend_long err_code; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(err_code) - ZEND_PARSE_PARAMETERS_END(); - - RETURN_STRING( (char*)u_errorName( err_code ) ); -} -/* }}} */ diff --git a/ext/intl/common/common_error.cpp b/ext/intl/common/common_error.cpp new file mode 100644 index 000000000000..8d0cca52bb77 --- /dev/null +++ b/ext/intl/common/common_error.cpp @@ -0,0 +1,72 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Vadim Savchuk | + | Dmitry Lakhtyuk | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "intl_error.h" +} + +/* {{{ Get code of the last occurred error. */ +U_CFUNC PHP_FUNCTION( intl_get_error_code ) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_LONG( intl_error_get_code( NULL ) ); +} +/* }}} */ + +/* {{{ Get text description of the last occurred error. */ +U_CFUNC PHP_FUNCTION( intl_get_error_message ) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_STR(intl_error_get_message( NULL )); +} +/* }}} */ + +/* {{{ Check whether the given error code indicates a failure. + * Returns true if it does, and false if the code + * indicates success or a warning. + */ +U_CFUNC PHP_FUNCTION( intl_is_failure ) +{ + zend_long err_code; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(err_code) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_BOOL( U_FAILURE( static_cast(err_code) ) ); +} +/* }}} */ + +/* {{{ Return a string for a given error code. + * The string will be the same as the name of the error code constant. + */ +U_CFUNC PHP_FUNCTION( intl_error_name ) +{ + zend_long err_code; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(err_code) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_STRING( (char*)u_errorName( static_cast(err_code) ) ); +} +/* }}} */ diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index 20adc3a4ce3a..7251f2283534 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -8,82 +8,83 @@ if test "$PHP_INTL" != "no"; then PHP_SUBST([INTL_SHARED_LIBADD]) INTL_COMMON_FLAGS="$ICU_CFLAGS -Wno-write-strings -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1" PHP_NEW_EXTENSION([intl], m4_normalize([ - collator/collator_attr.c - collator/collator_class.c - collator/collator_compare.c - collator/collator_convert.c - collator/collator_create.c - collator/collator_error.c - collator/collator_is_numeric.c - collator/collator_locale.c - collator/collator_sort.c - common/common_error.c - converter/converter.c - dateformat/dateformat_attr.c - dateformat/dateformat_class.c - dateformat/dateformat_data.c - dateformat/dateformat_format.c - dateformat/dateformat_parse.c - dateformat/dateformat.c - formatter/formatter_attr.c - formatter/formatter_class.c - formatter/formatter_data.c - formatter/formatter_format.c - formatter/formatter_main.c - formatter/formatter_parse.c - grapheme/grapheme_string.c - grapheme/grapheme_util.c - idn/idn.c intl_convert.c intl_error.c - locale/locale_class.c - locale/locale_methods.c - locale/locale.c - listformatter/listformatter_class.c - msgformat/msgformat_attr.c - msgformat/msgformat_class.c - msgformat/msgformat_data.c - msgformat/msgformat_format.c - msgformat/msgformat_parse.c - msgformat/msgformat.c - normalizer/normalizer_class.c - normalizer/normalizer_normalize.c php_intl.c - resourcebundle/resourcebundle_class.c - resourcebundle/resourcebundle_iterator.c - resourcebundle/resourcebundle.c - spoofchecker/spoofchecker_class.c - spoofchecker/spoofchecker_create.c - spoofchecker/spoofchecker_main.c - transliterator/transliterator_class.c - transliterator/transliterator_methods.c - uchar/uchar.c ]), [$ext_shared],, [$INTL_COMMON_FLAGS], [cxx]) PHP_INTL_CXX_SOURCES="intl_convertcpp.cpp \ + collator/collator_attr.cpp \ + collator/collator_class.cpp \ + collator/collator_compare.cpp \ + collator/collator_convert.cpp \ + collator/collator_create.cpp \ + collator/collator_error.cpp \ + collator/collator_is_numeric.cpp \ + collator/collator_locale.cpp \ + collator/collator_sort.cpp \ common/common_enum.cpp \ common/common_date.cpp \ - dateformat/dateformat_format_object.cpp \ - dateformat/dateformat_create.cpp \ + common/common_error.cpp \ + dateformat/dateformat_class.cpp \ + converter/converter.cpp \ + dateformat/dateformat.cpp \ + dateformat/dateformat_attr.cpp \ dateformat/dateformat_attrcpp.cpp \ + dateformat/dateformat_create.cpp \ + dateformat/dateformat_data.cpp \ + dateformat/dateformat_format.cpp \ + dateformat/dateformat_format_object.cpp \ dateformat/dateformat_helpers.cpp \ + dateformat/dateformat_parse.cpp \ dateformat/datepatterngenerator_class.cpp \ dateformat/datepatterngenerator_methods.cpp \ + formatter/formatter_class.cpp \ + grapheme/grapheme_string.cpp \ + grapheme/grapheme_util.cpp \ msgformat/msgformat_helpers.cpp \ + rangeformatter/rangeformatter_class.cpp \ timezone/timezone_class.cpp \ timezone/timezone_methods.cpp \ calendar/calendar_class.cpp \ calendar/calendar_methods.cpp \ calendar/gregoriancalendar_methods.cpp \ + formatter/formatter_attr.cpp \ + formatter/formatter_data.cpp \ + formatter/formatter_format.cpp \ + formatter/formatter_main.cpp \ + formatter/formatter_parse.cpp \ + msgformat/msgformat_attr.cpp \ + msgformat/msgformat_class.cpp \ + msgformat/msgformat_data.cpp \ + msgformat/msgformat_format.cpp \ + msgformat/msgformat_parse.cpp \ + msgformat/msgformat.cpp \ + normalizer/normalizer_class.cpp \ + normalizer/normalizer_normalize.cpp \ breakiterator/breakiterator_class.cpp \ breakiterator/breakiterator_iterators.cpp \ breakiterator/breakiterator_methods.cpp \ breakiterator/rulebasedbreakiterator_methods.cpp \ breakiterator/codepointiterator_internal.cpp \ - breakiterator/codepointiterator_methods.cpp" + breakiterator/codepointiterator_methods.cpp \ + listformatter/listformatter_class.cpp \ + transliterator/transliterator_class.cpp \ + transliterator/transliterator_methods.cpp \ + idn/idn.cpp \ + locale/locale_class.cpp \ + locale/locale_methods.cpp \ + locale/locale.cpp \ + resourcebundle/resourcebundle_class.cpp \ + resourcebundle/resourcebundle_iterator.cpp \ + resourcebundle/resourcebundle.cpp \ + spoofchecker/spoofchecker_class.cpp \ + spoofchecker/spoofchecker_create.cpp \ + spoofchecker/spoofchecker_main.cpp \ + uchar/uchar.cpp" PHP_REQUIRE_CXX() @@ -123,6 +124,7 @@ if test "$PHP_INTL" != "no"; then $ext_builddir/listformatter $ext_builddir/msgformat $ext_builddir/normalizer + $ext_builddir/rangeformatter $ext_builddir/resourcebundle $ext_builddir/spoofchecker $ext_builddir/timezone diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index b8161865d254..9e2f695532d3 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -7,70 +7,73 @@ if (PHP_INTL != "no") { CHECK_LIB("icuin.lib", "intl", PHP_INTL) && CHECK_LIB("icuio.lib", "intl", PHP_INTL) && CHECK_LIB("icuuc.lib", "intl", PHP_INTL) && - CHECK_HEADER_ADD_INCLUDE("unicode/utf.h", "CFLAGS_INTL")) { + CHECK_HEADER("unicode/utf.h", "CFLAGS_INTL")) { // always build as shared - zend_strtod.c/ICU type conflict EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", true, "/I \"" + configure_module_dirname + "\" /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); ADD_EXTENSION_DEP('intl', 'date'); ADD_SOURCES(configure_module_dirname + "/collator", "\ - collator_attr.c \ - collator_class.c \ - collator_compare.c \ - collator_convert.c \ - collator_create.c \ - collator_error.c \ - collator_is_numeric.c \ - collator_locale.c \ - collator_sort.c \ + collator_attr.cpp \ + collator_class.cpp \ + collator_compare.cpp \ + collator_convert.cpp \ + collator_create.cpp \ + collator_error.cpp \ + collator_is_numeric.cpp \ + collator_locale.cpp \ + collator_sort.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/common", "\ - common_error.c \ + common_error.cpp \ common_enum.cpp \ common_date.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/converter", "\ - converter.c \ + converter.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/formatter", "\ - formatter_attr.c \ - formatter_class.c \ - formatter_data.c \ - formatter_format.c \ - formatter_main.c \ - formatter_parse.c \ + formatter_attr.cpp \ + formatter_class.cpp \ + formatter_data.cpp \ + formatter_format.cpp \ + formatter_main.cpp \ + formatter_parse.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/listformatter", "\ - listformatter_class.c \ + listformatter_class.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/locale", "\ - locale.c \ - locale_class.c \ - locale_methods.c \ + locale.cpp \ + locale_class.cpp \ + locale_methods.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/msgformat", "\ - msgformat.c \ - msgformat_attr.c \ - msgformat_class.c \ - msgformat_data.c \ - msgformat_format.c \ + msgformat.cpp \ + msgformat_attr.cpp \ + msgformat_class.cpp \ + msgformat_data.cpp \ + msgformat_format.cpp \ msgformat_helpers.cpp \ - msgformat_parse.c \ + msgformat_parse.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/grapheme", "\ - grapheme_string.c grapheme_util.c \ + grapheme_string.cpp grapheme_util.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/normalizer", "\ - normalizer_class.c \ - normalizer_normalize.c \ + normalizer_class.cpp \ + normalizer_normalize.cpp \ + ", "intl"); + ADD_SOURCES(configure_module_dirname + "/rangeformatter", "\ + rangeformatter_class.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/dateformat", "\ - dateformat.c \ - dateformat_class.c \ - dateformat_attr.c \ - dateformat_format.c \ + dateformat.cpp \ + dateformat_class.cpp \ + dateformat_attr.cpp \ + dateformat_format.cpp \ dateformat_format_object.cpp \ - dateformat_parse.c \ - dateformat_data.c \ + dateformat_parse.cpp \ + dateformat_data.cpp \ dateformat_attrcpp.cpp \ dateformat_helpers.cpp \ dateformat_create.cpp \ @@ -78,28 +81,26 @@ if (PHP_INTL != "no") { datepatterngenerator_methods.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/uchar", "\ - uchar.c", + uchar.cpp", "intl"); ADD_SOURCES(configure_module_dirname + "/idn", "\ - idn.c", + idn.cpp", "intl"); ADD_SOURCES(configure_module_dirname + "/resourcebundle", "\ - resourcebundle.c \ - resourcebundle_class.c \ - resourcebundle_iterator.c", + resourcebundle.cpp \ + resourcebundle_class.cpp \ + resourcebundle_iterator.cpp", "intl"); - if (CHECK_HEADER_ADD_INCLUDE("unicode/uspoof.h", "CFLAGS_INTL")) { - ADD_SOURCES(configure_module_dirname + "/spoofchecker", "\ - spoofchecker_class.c \ - spoofchecker_create.c \ - spoofchecker_main.c", - "intl"); - } + ADD_SOURCES(configure_module_dirname + "/spoofchecker", "\ + spoofchecker_class.cpp \ + spoofchecker_create.cpp \ + spoofchecker_main.cpp", + "intl"); ADD_SOURCES(configure_module_dirname + "/transliterator", "\ - transliterator_class.c \ - transliterator_methods.c", + transliterator_class.cpp \ + transliterator_methods.cpp", "intl"); ADD_SOURCES(configure_module_dirname + "/timezone", "\ diff --git a/ext/intl/converter/converter.c b/ext/intl/converter/converter.c deleted file mode 100644 index 3aa7a53aa485..000000000000 --- a/ext/intl/converter/converter.c +++ /dev/null @@ -1,965 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Sara Golemon | - +----------------------------------------------------------------------+ - */ - -#include "converter.h" -#include "zend_exceptions.h" - -#include -#include -#include -#include -#include - -#include "../intl_error.h" -#include "../intl_common.h" -#include "converter_arginfo.h" - -typedef struct _php_converter_object { - UConverter *src, *dest; - zend_fcall_info_cache to_cache, from_cache; - intl_error error; - zend_object obj; -} php_converter_object; - - -static inline php_converter_object *php_converter_fetch_object(zend_object *obj) { - return (php_converter_object *)((char*)(obj) - XtOffsetOf(php_converter_object, obj)); -} -#define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv)) - -static zend_class_entry *php_converter_ce; -static zend_object_handlers php_converter_object_handlers; - -#define CONV_GET(pzv) (Z_INTL_CONVERTER_P((pzv))) -#define THROW_UFAILURE(obj, fname, error) php_converter_throw_failure(obj, error, \ - fname "() returned error " ZEND_LONG_FMT ": %s", (zend_long)error, u_errorName(error)) - -/* {{{ php_converter_throw_failure */ -static inline void php_converter_throw_failure(php_converter_object *objval, UErrorCode error, const char *format, ...) { - intl_error *err = objval ? &(objval->error) : NULL; - char message[1024]; - va_list vargs; - - va_start(vargs, format); - vsnprintf(message, sizeof(message), format, vargs); - va_end(vargs); - - intl_errors_set(err, error, message, 1); -} -/* }}} */ - -/* {{{ php_converter_default_callback */ -static void php_converter_default_callback(zval *return_value, zval *zobj, zend_long reason, zval *error) { - /* Basic functionality so children can call parent::toUCallback() */ - switch (reason) { - case UCNV_UNASSIGNED: - case UCNV_ILLEGAL: - case UCNV_IRREGULAR: - { - php_converter_object *objval = (php_converter_object*)CONV_GET(zobj); - char chars[127]; - int8_t chars_len = sizeof(chars); - UErrorCode uerror = U_ZERO_ERROR; - if(!objval->src) { - php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Source Converter has not been initialized yet"); - chars[0] = 0x1A; - chars[1] = 0; - chars_len = 1; - ZEND_TRY_ASSIGN_REF_LONG(error, U_INVALID_STATE_ERROR); - RETVAL_STRINGL(chars, chars_len); - return; - } - - /* Yes, this is fairly wasteful at first glance, - * but considering that the alternative is to store - * what's sent into setSubstChars() and the fact - * that this is an extremely unlikely codepath - * I'd rather take the CPU hit here, than waste time - * storing a value I'm unlikely to use. - */ - ucnv_getSubstChars(objval->src, chars, &chars_len, &uerror); - if (U_FAILURE(uerror)) { - THROW_UFAILURE(objval, "ucnv_getSubstChars", uerror); - chars[0] = 0x1A; - chars[1] = 0; - chars_len = 1; - } - ZEND_TRY_ASSIGN_REF_LONG(error, uerror); - RETVAL_STRINGL(chars, chars_len); - } - } -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, toUCallback) { - zend_long reason; - zend_string *source, *codeUnits; - zval *error; - - ZEND_PARSE_PARAMETERS_START(4, 4) - Z_PARAM_LONG(reason) - Z_PARAM_STR(source) - Z_PARAM_STR(codeUnits) - Z_PARAM_ZVAL(error) - ZEND_PARSE_PARAMETERS_END(); - - php_converter_default_callback(return_value, ZEND_THIS, reason, error); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, fromUCallback) { - zend_long reason; - zval *source, *error; - zend_long codePoint; - - ZEND_PARSE_PARAMETERS_START(4, 4) - Z_PARAM_LONG(reason) - Z_PARAM_ARRAY(source) - Z_PARAM_LONG(codePoint) - Z_PARAM_ZVAL(error) - ZEND_PARSE_PARAMETERS_END(); - - php_converter_default_callback(return_value, ZEND_THIS, reason, error); -} -/* }}} */ - -/* {{{ php_converter_check_limits */ -static inline bool php_converter_check_limits(php_converter_object *objval, zend_long available, zend_long needed) { - if (available < needed) { - php_converter_throw_failure(objval, U_BUFFER_OVERFLOW_ERROR, "Buffer overrun " ZEND_LONG_FMT " bytes needed, " ZEND_LONG_FMT " available", needed, available); - return 0; - } - return 1; -} -/* }}} */ - -#define TARGET_CHECK(cnvargs, needed) php_converter_check_limits(objval, cnvargs->targetLimit - cnvargs->target, needed) - -/* {{{ php_converter_append_toUnicode_target */ -static void php_converter_append_toUnicode_target(zval *val, UConverterToUnicodeArgs *args, php_converter_object *objval) { - switch (Z_TYPE_P(val)) { - case IS_NULL: - /* Code unit is being skipped */ - return; - case IS_LONG: - { - zend_long lval = Z_LVAL_P(val); - if ((lval < 0) || (lval > 0x10FFFF)) { - php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR, "Invalid codepoint U+%04lx", lval); - return; - } - if (lval > 0xFFFF) { - /* Supplemental planes U+010000 - U+10FFFF */ - if (TARGET_CHECK(args, 2)) { - /* TODO: Find the ICU call which does this properly */ - *(args->target++) = (UChar)(((lval - 0x10000) >> 10) | 0xD800); - *(args->target++) = (UChar)(((lval - 0x10000) & 0x3FF) | 0xDC00); - } - return; - } - /* Non-suggogate BMP codepoint */ - if (TARGET_CHECK(args, 1)) { - *(args->target++) = (UChar)lval; - } - return; - } - case IS_STRING: - { - const char *strval = Z_STRVAL_P(val); - int i = 0, strlen = Z_STRLEN_P(val); - - while((i != strlen) && TARGET_CHECK(args, 1)) { - UChar c; - U8_NEXT(strval, i, strlen, c); - *(args->target++) = c; - } - return; - } - case IS_ARRAY: - { - HashTable *ht = Z_ARRVAL_P(val); - zval *tmpzval; - - ZEND_HASH_FOREACH_VAL(ht, tmpzval) { - php_converter_append_toUnicode_target(tmpzval, args, objval); - } ZEND_HASH_FOREACH_END(); - return; - } - default: - php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR, - "toUCallback() specified illegal type for substitution character"); - } -} -/* }}} */ - -/* {{{ php_converter_to_u_callback */ -static void php_converter_to_u_callback(const void *context, - UConverterToUnicodeArgs *args, - const char *codeUnits, int32_t length, - UConverterCallbackReason reason, - UErrorCode *pErrorCode) { - php_converter_object *objval = (php_converter_object*)context; - zval retval; - zval zargs[4]; - - ZVAL_LONG(&zargs[0], reason); - if (args->source) { - ZVAL_STRINGL(&zargs[1], args->source, args->sourceLimit - args->source); - } else { - ZVAL_EMPTY_STRING(&zargs[1]); - } - if (codeUnits) { - ZVAL_STRINGL(&zargs[2], codeUnits, length); - } else { - ZVAL_EMPTY_STRING(&zargs[2]); - } - ZVAL_LONG(&zargs[3], *pErrorCode); - ZVAL_MAKE_REF(&zargs[3]); - - zend_call_known_fcc(&objval->to_cache, &retval, 4, zargs, NULL); - /* When no exception is thrown */ - if (EXPECTED(!Z_ISUNDEF(retval))) { - php_converter_append_toUnicode_target(&retval, args, objval); - zval_ptr_dtor(&retval); - } - - if (Z_TYPE(zargs[3]) == IS_LONG) { - *pErrorCode = Z_LVAL(zargs[3]); - } else if (Z_ISREF(zargs[3]) && Z_TYPE_P(Z_REFVAL(zargs[3])) == IS_LONG) { - *pErrorCode = Z_LVAL_P(Z_REFVAL(zargs[3])); - } - - zval_ptr_dtor(&zargs[0]); - zval_ptr_dtor(&zargs[1]); - zval_ptr_dtor(&zargs[2]); - zval_ptr_dtor(&zargs[3]); -} -/* }}} */ - -/* {{{ php_converter_append_fromUnicode_target */ -static void php_converter_append_fromUnicode_target(zval *val, UConverterFromUnicodeArgs *args, php_converter_object *objval) { - switch (Z_TYPE_P(val)) { - case IS_NULL: - /* Ignore */ - return; - case IS_LONG: - if (TARGET_CHECK(args, 1)) { - *(args->target++) = Z_LVAL_P(val); - } - return; - case IS_STRING: - { - size_t vallen = Z_STRLEN_P(val); - if (TARGET_CHECK(args, vallen)) { - args->target = zend_mempcpy(args->target, Z_STRVAL_P(val), vallen); - } - return; - } - case IS_ARRAY: - { - HashTable *ht = Z_ARRVAL_P(val); - zval *tmpzval; - ZEND_HASH_FOREACH_VAL(ht, tmpzval) { - php_converter_append_fromUnicode_target(tmpzval, args, objval); - } ZEND_HASH_FOREACH_END(); - return; - } - default: - php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR, "fromUCallback() specified illegal type for substitution character"); - } -} -/* }}} */ - -/* {{{ php_converter_from_u_callback */ -static void php_converter_from_u_callback(const void *context, - UConverterFromUnicodeArgs *args, - const UChar *codeUnits, int32_t length, UChar32 codePoint, - UConverterCallbackReason reason, - UErrorCode *pErrorCode) { - php_converter_object *objval = (php_converter_object*)context; - zval retval; - zval zargs[4]; - - ZVAL_LONG(&zargs[0], reason); - array_init_size(&zargs[1], length); - zend_hash_real_init_packed(Z_ARRVAL(zargs[1])); - int i = 0; - while (i < length) { - UChar32 c; - U16_NEXT(codeUnits, i, length, c); - add_next_index_long(&zargs[1], c); - } - ZVAL_LONG(&zargs[2], codePoint); - ZVAL_LONG(&zargs[3], *pErrorCode); - ZVAL_MAKE_REF(&zargs[3]); - - zend_call_known_fcc(&objval->from_cache, &retval, 4, zargs, NULL); - /* When no exception is thrown */ - if (EXPECTED(!Z_ISUNDEF(retval))) { - php_converter_append_fromUnicode_target(&retval, args, objval); - zval_ptr_dtor(&retval); - } - - if (Z_TYPE(zargs[3]) == IS_LONG) { - *pErrorCode = Z_LVAL(zargs[3]); - } else if (Z_ISREF(zargs[3]) && Z_TYPE_P(Z_REFVAL(zargs[3])) == IS_LONG) { - *pErrorCode = Z_LVAL_P(Z_REFVAL(zargs[3])); - } - - zval_ptr_dtor(&zargs[0]); - zval_ptr_dtor(&zargs[1]); - zval_ptr_dtor(&zargs[2]); - zval_ptr_dtor(&zargs[3]); -} -/* }}} */ - -/* {{{ php_converter_set_callbacks */ -static inline bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv) { - bool ret = true; - UErrorCode error = U_ZERO_ERROR; - - if (objval->obj.ce == php_converter_ce) { - /* Short-circuit having to go through method calls and data marshalling - * when we're using default behavior - */ - return 1; - } - - ucnv_setToUCallBack(cnv, (UConverterToUCallback)php_converter_to_u_callback, (const void*)objval, - NULL, NULL, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setToUCallBack", error); - ret = 0; - } - - error = U_ZERO_ERROR; - ucnv_setFromUCallBack(cnv, (UConverterFromUCallback)php_converter_from_u_callback, (const void*)objval, - NULL, NULL, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setFromUCallBack", error); - ret = 0; - } - return ret; -} -/* }}} */ - -/* {{{ php_converter_set_encoding */ -static bool php_converter_set_encoding(php_converter_object *objval, - UConverter **pcnv, - const char *enc, size_t enc_len) { - UErrorCode error = U_ZERO_ERROR; - UConverter *cnv = ucnv_open(enc, &error); - - if (error == U_AMBIGUOUS_ALIAS_WARNING) { - UErrorCode getname_error = U_ZERO_ERROR; - const char *actual_encoding = ucnv_getName(cnv, &getname_error); - if (U_FAILURE(getname_error)) { - /* Should never happen */ - actual_encoding = "(unknown)"; - } - php_error_docref(NULL, E_WARNING, "Ambiguous encoding specified, using %s", actual_encoding); - } else if (U_FAILURE(error)) { - if (objval) { - THROW_UFAILURE(objval, "ucnv_open", error); - } else { - char *msg; - spprintf(&msg, 0, "Error setting encoding: %d - %s", (int)error, u_errorName(error)); - intl_error_set(NULL, error, msg, 1); - efree(msg); - } - return false; - } - - if (objval && !php_converter_set_callbacks(objval, cnv)) { - return false; - } - - if (*pcnv) { - ucnv_close(*pcnv); - } - *pcnv = cnv; - return true; -} -/* }}} */ - -/* {{{ php_converter_do_set_encoding */ -static void php_converter_do_set_encoding(UConverter **pcnv, INTERNAL_FUNCTION_PARAMETERS) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - char *enc; - size_t enc_len; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(enc, enc_len) - ZEND_PARSE_PARAMETERS_END(); - - intl_errors_reset(&objval->error); - - RETURN_BOOL(php_converter_set_encoding(objval, pcnv, enc, enc_len)); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, setSourceEncoding) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - php_converter_do_set_encoding(&(objval->src), INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, setDestinationEncoding) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - php_converter_do_set_encoding(&(objval->dest), INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ php_converter_do_get_encoding */ -static void php_converter_do_get_encoding(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { - const char *name; - - ZEND_PARSE_PARAMETERS_NONE(); - - intl_errors_reset(&objval->error); - - if (!cnv) { - RETURN_NULL(); - } - - name = ucnv_getName(cnv, &objval->error.code); - if (U_FAILURE(objval->error.code)) { - THROW_UFAILURE(objval, "ucnv_getName()", objval->error.code); - RETURN_FALSE; - } - - RETURN_STRING(name); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getSourceEncoding) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - php_converter_do_get_encoding(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getDestinationEncoding) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - php_converter_do_get_encoding(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ php_converter_do_get_type */ -static void php_converter_do_get_type(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { - UConverterType t; - - ZEND_PARSE_PARAMETERS_NONE(); - intl_errors_reset(&objval->error); - - if (!cnv) { - RETURN_NULL(); - } - - t = ucnv_getType(cnv); - if (U_FAILURE(objval->error.code)) { - THROW_UFAILURE(objval, "ucnv_getType", objval->error.code); - RETURN_FALSE; - } - - RETURN_LONG(t); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getSourceType) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - php_converter_do_get_type(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getDestinationType) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - php_converter_do_get_type(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ php_converter_resolve_callback */ -static void php_converter_resolve_callback( - zend_fcall_info_cache *fcc, - zend_object *obj, - const char *callback_name, - size_t callback_name_len -) { - zend_function *fn = zend_hash_str_find_ptr_lc(&obj->ce->function_table, callback_name, callback_name_len); - ZEND_ASSERT(fn != NULL); - - fcc->function_handler = fn; - fcc->object = obj; - fcc->called_scope = obj->ce; - fcc->calling_scope = NULL; - fcc->closure = NULL; -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, __construct) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - char *src = "utf-8"; - size_t src_len = sizeof("utf-8") - 1; - char *dest = src; - size_t dest_len = src_len; - - intl_error_reset(NULL); - - ZEND_PARSE_PARAMETERS_START(0, 2) - Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(dest, dest_len) - Z_PARAM_STRING_OR_NULL(src, src_len) - ZEND_PARSE_PARAMETERS_END(); - - php_converter_set_encoding(objval, &(objval->src), src, src_len ); - php_converter_set_encoding(objval, &(objval->dest), dest, dest_len); - php_converter_resolve_callback(&objval->to_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("toUCallback")); - php_converter_resolve_callback(&objval->from_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("fromUCallback")); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, setSubstChars) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - char *chars; - size_t chars_len; - int ret = 1; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(chars, chars_len) - ZEND_PARSE_PARAMETERS_END(); - - intl_errors_reset(&objval->error); - - if (objval->src) { - UErrorCode error = U_ZERO_ERROR; - ucnv_setSubstChars(objval->src, chars, chars_len, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setSubstChars", error); - ret = 0; - } - } else { - php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Source Converter has not been initialized yet"); - ret = 0; - } - - if (objval->dest) { - UErrorCode error = U_ZERO_ERROR; - ucnv_setSubstChars(objval->dest, chars, chars_len, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_setSubstChars", error); - ret = 0; - } - } else { - php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Destination Converter has not been initialized yet"); - ret = 0; - } - - RETURN_BOOL(ret); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getSubstChars) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - char chars[127]; - int8_t chars_len = sizeof(chars); - UErrorCode error = U_ZERO_ERROR; - - ZEND_PARSE_PARAMETERS_NONE(); - intl_errors_reset(&objval->error); - - if (!objval->src) { - RETURN_NULL(); - } - - /* src and dest get the same subst chars set, - * so it doesn't really matter which one we read from - */ - ucnv_getSubstChars(objval->src, chars, &chars_len, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_getSubstChars", error); - RETURN_FALSE; - } - - RETURN_STRINGL(chars, chars_len); -} -/* }}} */ - -/* {{{ php_converter_do_convert */ -static zend_string* php_converter_do_convert(UConverter *dest_cnv, - UConverter *src_cnv, const char *src, int32_t src_len, - php_converter_object *objval - ) { - UErrorCode error = U_ZERO_ERROR; - int32_t temp_len, ret_len; - zend_string *ret; - UChar *temp; - - if (!src_cnv || !dest_cnv) { - php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, - "Internal converters not initialized"); - return NULL; - } - - /* Get necessary buffer size first */ - temp_len = 1 + ucnv_toUChars(src_cnv, NULL, 0, src, src_len, &error); - if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { - THROW_UFAILURE(objval, "ucnv_toUChars", error); - return NULL; - } - temp = safe_emalloc(sizeof(UChar), temp_len, sizeof(UChar)); - - /* Convert to intermediate UChar* array */ - error = U_ZERO_ERROR; - temp_len = ucnv_toUChars(src_cnv, temp, temp_len, src, src_len, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_toUChars", error); - efree(temp); - return NULL; - } - temp[temp_len] = 0; - - /* Get necessary output buffer size */ - ret_len = ucnv_fromUChars(dest_cnv, NULL, 0, temp, temp_len, &error); - if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { - THROW_UFAILURE(objval, "ucnv_fromUChars", error); - efree(temp); - return NULL; - } - - ret = zend_string_alloc(ret_len, 0); - - /* Convert to final encoding */ - error = U_ZERO_ERROR; - ZSTR_LEN(ret) = ucnv_fromUChars(dest_cnv, ZSTR_VAL(ret), ret_len+1, temp, temp_len, &error); - efree(temp); - if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "ucnv_fromUChars", error); - zend_string_efree(ret); - return NULL; - } - - return ret; -} -/* }}} */ - -/* {{{ */ -#define UCNV_REASON_CASE(v) case (UCNV_ ## v) : RETURN_STRINGL( "REASON_" #v , sizeof( "REASON_" #v ) - 1); -PHP_METHOD(UConverter, reasonText) { - zend_long reason; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(reason) - ZEND_PARSE_PARAMETERS_END(); - intl_error_reset(NULL); - - switch (reason) { - UCNV_REASON_CASE(UNASSIGNED) - UCNV_REASON_CASE(ILLEGAL) - UCNV_REASON_CASE(IRREGULAR) - UCNV_REASON_CASE(RESET) - UCNV_REASON_CASE(CLOSE) - UCNV_REASON_CASE(CLONE) - default: - zend_argument_value_error(1, "must be a UConverter::REASON_* constant"); - RETURN_THROWS(); - } -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, convert) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - char *str; - size_t str_len; - zend_string *ret; - bool reverse = false; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(str, str_len) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(reverse) - ZEND_PARSE_PARAMETERS_END(); - intl_errors_reset(&objval->error); - - ret = php_converter_do_convert(reverse ? objval->src : objval->dest, - reverse ? objval->dest : objval->src, - str, str_len, - objval); - if (ret) { - RETURN_NEW_STR(ret); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, transcode) { - char *str, *src, *dest; - size_t str_len, src_len, dest_len; - zval *options = NULL; - UConverter *src_cnv = NULL, *dest_cnv = NULL; - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_STRING(str, str_len) - Z_PARAM_STRING(dest, dest_len) - Z_PARAM_STRING(src, src_len) - Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - ZEND_PARSE_PARAMETERS_END(); - intl_error_reset(NULL); - - if (php_converter_set_encoding(NULL, &src_cnv, src, src_len) && - php_converter_set_encoding(NULL, &dest_cnv, dest, dest_len)) { - zend_string *ret; - UErrorCode error = U_ZERO_ERROR; - - if (options && zend_hash_num_elements(Z_ARRVAL_P(options))) { - zval *tmpzval; - - if (U_SUCCESS(error) && - (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst") - 1)) != NULL && - Z_TYPE_P(tmpzval) == IS_STRING) { - error = U_ZERO_ERROR; - ucnv_setSubstChars(src_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); - } - if (U_SUCCESS(error) && - (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst") - 1)) != NULL && - Z_TYPE_P(tmpzval) == IS_STRING) { - error = U_ZERO_ERROR; - ucnv_setSubstChars(dest_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); - } - } - - if (U_SUCCESS(error) && - (ret = php_converter_do_convert(dest_cnv, src_cnv, str, str_len, NULL)) != NULL) { - RETVAL_NEW_STR(ret); - } - - if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "transcode", error); - RETVAL_FALSE; - } - } else { - RETVAL_FALSE; - } - - if (src_cnv) { - ucnv_close(src_cnv); - } - if (dest_cnv) { - ucnv_close(dest_cnv); - } -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getErrorCode) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - - ZEND_PARSE_PARAMETERS_NONE(); - - RETURN_LONG(intl_error_get_code(&(objval->error))); -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getErrorMessage) { - php_converter_object *objval = CONV_GET(ZEND_THIS); - - ZEND_PARSE_PARAMETERS_NONE(); - - zend_string *message = intl_error_get_message(&(objval->error)); - if (message) { - RETURN_STR(message); - } else { - RETURN_NULL(); - } -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getAvailable) { - int32_t i, - count = ucnv_countAvailable(); - - ZEND_PARSE_PARAMETERS_NONE(); - - intl_error_reset(NULL); - - array_init_size(return_value, count); - zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); - for(i = 0; i < count; i++) { - const char *name = ucnv_getAvailableName(i); - add_next_index_string(return_value, name); - } -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getAliases) { - char *name; - size_t name_len; - UErrorCode error = U_ZERO_ERROR; - uint16_t i, count; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(name, name_len) - ZEND_PARSE_PARAMETERS_END(); - intl_error_reset(NULL); - - count = ucnv_countAliases(name, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "ucnv_countAliases", error); - RETURN_FALSE; - } - - array_init_size(return_value, count); - zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); - for(i = 0; i < count; i++) { - const char *alias; - - error = U_ZERO_ERROR; - alias = ucnv_getAlias(name, i, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "ucnv_getAlias", error); - zend_array_destroy(Z_ARR_P(return_value)); - RETURN_NULL(); - } - add_next_index_string(return_value, alias); - } -} -/* }}} */ - -/* {{{ */ -PHP_METHOD(UConverter, getStandards) { - uint16_t i, count; - - ZEND_PARSE_PARAMETERS_NONE(); - intl_error_reset(NULL); - - count = ucnv_countStandards(); - array_init_size(return_value, count); - zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); - for(i = 0; i < count; i++) { - UErrorCode error = U_ZERO_ERROR; - const char *name = ucnv_getStandard(i, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "ucnv_getStandard", error); - zend_array_destroy(Z_ARR_P(return_value)); - RETURN_NULL(); - } - add_next_index_string(return_value, name); - } -} -/* }}} */ - -/* {{{ Converter create/clone/destroy */ -static void php_converter_free_object(zend_object *obj) { - php_converter_object *objval = php_converter_fetch_object(obj); - - if (objval->src) { - ucnv_close(objval->src); - } - - if (objval->dest) { - ucnv_close(objval->dest); - } - - intl_error_reset(&objval->error); - zend_object_std_dtor(obj); -} - -static zend_object *php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval) { - php_converter_object *objval; - - objval = zend_object_alloc(sizeof(php_converter_object), ce); - - zend_object_std_init(&objval->obj, ce); - object_properties_init(&objval->obj, ce); - intl_error_init(&(objval->error)); - - *pobjval = objval; - - return &objval->obj; -} - -static zend_object *php_converter_create_object(zend_class_entry *ce) { - php_converter_object *objval = NULL; - zend_object *retval = php_converter_object_ctor(ce, &objval); - - object_properties_init(&(objval->obj), ce); - - return retval; -} - -static zend_object *php_converter_clone_object(zend_object *object) { - php_converter_object *objval, *oldobj = php_converter_fetch_object(object); - zend_object *retval = php_converter_object_ctor(object->ce, &objval); - UErrorCode error = U_ZERO_ERROR; - -#if U_ICU_VERSION_MAJOR_NUM > 70 - objval->src = ucnv_clone(oldobj->src, &error); -#else - objval->src = ucnv_safeClone(oldobj->src, NULL, NULL, &error); -#endif - if (U_SUCCESS(error)) { - error = U_ZERO_ERROR; -#if U_ICU_VERSION_MAJOR_NUM > 70 - objval->dest = ucnv_clone(oldobj->dest, &error); -#else - objval->dest = ucnv_safeClone(oldobj->dest, NULL, NULL, &error); -#endif - } - - if (U_FAILURE(error)) { - zend_throw_error(NULL, "Failed to clone UConverter"); - return retval; - } - - /* Update contexts for converter error handlers */ - php_converter_set_callbacks(objval, objval->src ); - php_converter_set_callbacks(objval, objval->dest); - - zend_objects_clone_members(&(objval->obj), &(oldobj->obj)); - - /* Newly cloned object deliberately does not inherit error state from original object */ - - return retval; -} -/* }}} */ - -/* {{{ php_converter_minit */ -int php_converter_minit(INIT_FUNC_ARGS) { - php_converter_ce = register_class_UConverter(); - php_converter_ce->create_object = php_converter_create_object; - php_converter_ce->default_object_handlers = &php_converter_object_handlers; - memcpy(&php_converter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_converter_object_handlers.offset = XtOffsetOf(php_converter_object, obj); - php_converter_object_handlers.clone_obj = php_converter_clone_object; - php_converter_object_handlers.free_obj = php_converter_free_object; - - return SUCCESS; -} -/* }}} */ diff --git a/ext/intl/converter/converter.cpp b/ext/intl/converter/converter.cpp new file mode 100644 index 000000000000..597746b8faca --- /dev/null +++ b/ext/intl/converter/converter.cpp @@ -0,0 +1,985 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ + */ + +#include "zend_exceptions.h" + +#include +#include +#include +#include +#include + +extern "C" { +#include "converter.h" +#include "php_intl.h" +#include "../intl_error.h" +#include "../intl_common.h" +} +#include "converter_arginfo.h" + +typedef struct _php_converter_object { + UConverter *src, *dest; + zend_fcall_info_cache to_cache, from_cache; + intl_error error; + zend_object obj; +} php_converter_object; + + +static inline php_converter_object *php_converter_fetch_object(zend_object *obj) { + return (php_converter_object *)((char*)(obj) - offsetof(php_converter_object, obj)); +} +#define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv)) + +static zend_class_entry *php_converter_ce; +static zend_object_handlers php_converter_object_handlers; + +#define CONV_GET(pzv) (Z_INTL_CONVERTER_P((pzv))) +#define THROW_UFAILURE(obj, error) php_converter_throw_failure(obj, error, \ + "returned error " ZEND_LONG_FMT ": %s", (zend_long)error, u_errorName(error)) + +/* {{{ php_converter_throw_failure */ +static inline void php_converter_throw_failure(php_converter_object *objval, UErrorCode error, const char *format, ...) { + intl_error *err = objval ? &(objval->error) : NULL; + char message[1024]; + va_list vargs; + + va_start(vargs, format); + vsnprintf(message, sizeof(message), format, vargs); + va_end(vargs); + + intl_errors_set(err, error, message); +} +/* }}} */ + +/* {{{ php_converter_default_callback */ +static void php_converter_default_callback(zval *return_value, zval *zobj, zend_long reason, zval *error) { + /* Basic functionality so children can call parent::toUCallback() */ + switch (reason) { + case UCNV_UNASSIGNED: + case UCNV_ILLEGAL: + case UCNV_IRREGULAR: + { + php_converter_object *objval = (php_converter_object*)CONV_GET(zobj); + char chars[127]; + int8_t chars_len = sizeof(chars); + UErrorCode uerror = U_ZERO_ERROR; + if(!objval->src) { + php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Source Converter has not been initialized yet"); + chars[0] = 0x1A; + chars[1] = 0; + chars_len = 1; + ZEND_TRY_ASSIGN_REF_LONG(error, U_INVALID_STATE_ERROR); + RETVAL_STRINGL(chars, chars_len); + return; + } + + /* Yes, this is fairly wasteful at first glance, + * but considering that the alternative is to store + * what's sent into setSubstChars() and the fact + * that this is an extremely unlikely codepath + * I'd rather take the CPU hit here, than waste time + * storing a value I'm unlikely to use. + */ + ucnv_getSubstChars(objval->src, chars, &chars_len, &uerror); + if (U_FAILURE(uerror)) { + THROW_UFAILURE(objval, uerror); + chars[0] = 0x1A; + chars[1] = 0; + chars_len = 1; + } + ZEND_TRY_ASSIGN_REF_LONG(error, uerror); + RETVAL_STRINGL(chars, chars_len); + } + } +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, toUCallback) { + zend_long reason; + zend_string *source, *codeUnits; + zval *error; + + ZEND_PARSE_PARAMETERS_START(4, 4) + Z_PARAM_LONG(reason) + Z_PARAM_STR(source) + Z_PARAM_STR(codeUnits) + Z_PARAM_ZVAL(error) + ZEND_PARSE_PARAMETERS_END(); + + php_converter_default_callback(return_value, ZEND_THIS, reason, error); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, fromUCallback) { + zend_long reason; + zval *source, *error; + zend_long codePoint; + + ZEND_PARSE_PARAMETERS_START(4, 4) + Z_PARAM_LONG(reason) + Z_PARAM_ARRAY(source) + Z_PARAM_LONG(codePoint) + Z_PARAM_ZVAL(error) + ZEND_PARSE_PARAMETERS_END(); + + php_converter_default_callback(return_value, ZEND_THIS, reason, error); +} +/* }}} */ + +/* {{{ php_converter_check_limits */ +static inline bool php_converter_check_limits(php_converter_object *objval, zend_long available, zend_long needed) { + if (available < needed) { + php_converter_throw_failure(objval, U_BUFFER_OVERFLOW_ERROR, "Buffer overrun " ZEND_LONG_FMT " bytes needed, " ZEND_LONG_FMT " available", needed, available); + return false; + } + return true; +} +/* }}} */ + +#define TARGET_CHECK(cnvargs, needed) php_converter_check_limits(objval, cnvargs->targetLimit - cnvargs->target, needed) + +/* {{{ php_converter_append_toUnicode_target */ +static void php_converter_append_toUnicode_target(zval *val, UConverterToUnicodeArgs *args, php_converter_object *objval) { + switch (Z_TYPE_P(val)) { + case IS_NULL: + /* Code unit is being skipped */ + return; + case IS_LONG: + { + zend_long lval = Z_LVAL_P(val); + if ((lval < 0) || (lval > 0x10FFFF)) { + php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR, "Invalid codepoint U+%04lx", lval); + return; + } + if (lval > 0xFFFF) { + /* Supplemental planes U+010000 - U+10FFFF */ + if (TARGET_CHECK(args, 2)) { + int32_t offset = 0; + U16_APPEND_UNSAFE(args->target, offset, lval); + args->target += offset; + } + return; + } + /* Non-suggogate BMP codepoint */ + if (TARGET_CHECK(args, 1)) { + *(args->target++) = (UChar)lval; + } + return; + } + case IS_STRING: + { + const char *strval = Z_STRVAL_P(val); + int i = 0, strlen = Z_STRLEN_P(val); + + while((i != strlen) && TARGET_CHECK(args, 1)) { + UChar c; + U8_NEXT(strval, i, strlen, c); + *(args->target++) = c; + } + return; + } + case IS_ARRAY: + { + HashTable *ht = Z_ARRVAL_P(val); + zval *tmpzval; + + ZEND_HASH_FOREACH_VAL(ht, tmpzval) { + php_converter_append_toUnicode_target(tmpzval, args, objval); + } ZEND_HASH_FOREACH_END(); + return; + } + default: + php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR, + "toUCallback() specified illegal type for substitution character"); + } +} +/* }}} */ + +/* {{{ php_converter_to_u_callback */ +static void php_converter_to_u_callback(const void *context, + UConverterToUnicodeArgs *args, + const char *codeUnits, int32_t length, + UConverterCallbackReason reason, + UErrorCode *pErrorCode) { + php_converter_object *objval = (php_converter_object*)context; + zval retval; + zval zargs[4]; + + ZVAL_LONG(&zargs[0], reason); + if (args->source) { + ZVAL_STRINGL(&zargs[1], args->source, args->sourceLimit - args->source); + } else { + ZVAL_EMPTY_STRING(&zargs[1]); + } + if (codeUnits) { + ZVAL_STRINGL(&zargs[2], codeUnits, length); + } else { + ZVAL_EMPTY_STRING(&zargs[2]); + } + ZVAL_LONG(&zargs[3], *pErrorCode); + ZVAL_MAKE_REF(&zargs[3]); + + zend_call_known_fcc(&objval->to_cache, &retval, 4, zargs, NULL); + /* When no exception is thrown */ + if (EXPECTED(!Z_ISUNDEF(retval))) { + php_converter_append_toUnicode_target(&retval, args, objval); + zval_ptr_dtor(&retval); + } + + if (Z_TYPE(zargs[3]) == IS_LONG) { + *pErrorCode = static_cast(Z_LVAL(zargs[3])); + } else if (Z_ISREF(zargs[3]) && Z_TYPE_P(Z_REFVAL(zargs[3])) == IS_LONG) { + *pErrorCode = static_cast(Z_LVAL_P(Z_REFVAL(zargs[3]))); + } + + zval_ptr_dtor(&zargs[0]); + zval_ptr_dtor(&zargs[1]); + zval_ptr_dtor(&zargs[2]); + zval_ptr_dtor(&zargs[3]); +} +/* }}} */ + +/* {{{ php_converter_append_fromUnicode_target */ +static void php_converter_append_fromUnicode_target(zval *val, UConverterFromUnicodeArgs *args, php_converter_object *objval) { + switch (Z_TYPE_P(val)) { + case IS_NULL: + /* Ignore */ + return; + case IS_LONG: + if (TARGET_CHECK(args, 1)) { + *(args->target++) = Z_LVAL_P(val); + } + return; + case IS_STRING: + { + size_t vallen = Z_STRLEN_P(val); + if (TARGET_CHECK(args, vallen)) { + args->target = reinterpret_cast(zend_mempcpy(args->target, Z_STRVAL_P(val), vallen)); + } + return; + } + case IS_ARRAY: + { + HashTable *ht = Z_ARRVAL_P(val); + zval *tmpzval; + ZEND_HASH_FOREACH_VAL(ht, tmpzval) { + php_converter_append_fromUnicode_target(tmpzval, args, objval); + } ZEND_HASH_FOREACH_END(); + return; + } + default: + php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR, "fromUCallback() specified illegal type for substitution character"); + } +} +/* }}} */ + +/* {{{ php_converter_from_u_callback */ +static void php_converter_from_u_callback(const void *context, + UConverterFromUnicodeArgs *args, + const UChar *codeUnits, int32_t length, UChar32 codePoint, + UConverterCallbackReason reason, + UErrorCode *pErrorCode) { + php_converter_object *objval = (php_converter_object*)context; + zval retval; + zval zargs[4]; + + ZVAL_LONG(&zargs[0], reason); + array_init_size(&zargs[1], length); + zend_hash_real_init_packed(Z_ARRVAL(zargs[1])); + int i = 0; + while (i < length) { + UChar32 c; + U16_NEXT(codeUnits, i, length, c); + add_next_index_long(&zargs[1], c); + } + ZVAL_LONG(&zargs[2], codePoint); + ZVAL_LONG(&zargs[3], *pErrorCode); + ZVAL_MAKE_REF(&zargs[3]); + + zend_call_known_fcc(&objval->from_cache, &retval, 4, zargs, NULL); + /* When no exception is thrown */ + if (EXPECTED(!Z_ISUNDEF(retval))) { + php_converter_append_fromUnicode_target(&retval, args, objval); + zval_ptr_dtor(&retval); + } + + if (Z_TYPE(zargs[3]) == IS_LONG) { + *pErrorCode = static_cast(Z_LVAL(zargs[3])); + } else if (Z_ISREF(zargs[3]) && Z_TYPE_P(Z_REFVAL(zargs[3])) == IS_LONG) { + *pErrorCode = static_cast(Z_LVAL_P(Z_REFVAL(zargs[3]))); + } + + zval_ptr_dtor(&zargs[0]); + zval_ptr_dtor(&zargs[1]); + zval_ptr_dtor(&zargs[2]); + zval_ptr_dtor(&zargs[3]); +} +/* }}} */ + +/* {{{ php_converter_set_callbacks */ +static inline bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv) { + bool ret = true; + UErrorCode error = U_ZERO_ERROR; + + if (objval->obj.ce == php_converter_ce) { + /* Short-circuit having to go through method calls and data marshalling + * when we're using default behavior + */ + return true; + } + + ucnv_setToUCallBack(cnv, (UConverterToUCallback)php_converter_to_u_callback, (const void*)objval, + nullptr, nullptr, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, error); + ret = false; + } + + error = U_ZERO_ERROR; + ucnv_setFromUCallBack(cnv, (UConverterFromUCallback)php_converter_from_u_callback, (const void*)objval, + nullptr, nullptr, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, error); + ret = false; + } + return ret; +} +/* }}} */ + +/* {{{ php_converter_set_encoding */ +static bool php_converter_set_encoding(php_converter_object *objval, + UConverter **pcnv, + const char *enc, size_t enc_len) { + UErrorCode error = U_ZERO_ERROR; + UConverter *cnv = ucnv_open(enc, &error); + + if (error == U_AMBIGUOUS_ALIAS_WARNING) { + UErrorCode getname_error = U_ZERO_ERROR; + const char *actual_encoding = ucnv_getName(cnv, &getname_error); + if (U_FAILURE(getname_error)) { + /* Should never happen */ + actual_encoding = "(unknown)"; + } + char *msg; + spprintf(&msg, 0, "Ambiguous encoding specified, using %s", actual_encoding); + intl_error_set(NULL, error, msg); + efree(msg); + } else if (U_FAILURE(error)) { + if (objval) { + THROW_UFAILURE(objval, error); + } else { + char *msg; + spprintf(&msg, 0, "Error setting encoding: %d - %s", (int)error, u_errorName(error)); + intl_error_set(NULL, error, msg); + efree(msg); + } + return false; + } + + if (objval && !php_converter_set_callbacks(objval, cnv)) { + return false; + } + + if (*pcnv) { + ucnv_close(*pcnv); + } + *pcnv = cnv; + return true; +} +/* }}} */ + +/* {{{ php_converter_do_set_encoding */ +static void php_converter_do_set_encoding(UConverter **pcnv, INTERNAL_FUNCTION_PARAMETERS) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + char *enc; + size_t enc_len; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(enc, enc_len) + ZEND_PARSE_PARAMETERS_END(); + + intl_errors_reset(&objval->error); + + RETURN_BOOL(php_converter_set_encoding(objval, pcnv, enc, enc_len)); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, setSourceEncoding) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + php_converter_do_set_encoding(&(objval->src), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, setDestinationEncoding) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + php_converter_do_set_encoding(&(objval->dest), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ php_converter_do_get_encoding */ +static void php_converter_do_get_encoding(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { + const char *name; + + ZEND_PARSE_PARAMETERS_NONE(); + + intl_errors_reset(&objval->error); + + if (!cnv) { + RETURN_NULL(); + } + + name = ucnv_getName(cnv, &objval->error.code); + if (U_FAILURE(objval->error.code)) { + THROW_UFAILURE(objval, objval->error.code); + RETURN_FALSE; + } + + RETURN_STRING(name); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getSourceEncoding) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + php_converter_do_get_encoding(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getDestinationEncoding) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + php_converter_do_get_encoding(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ php_converter_do_get_type */ +static void php_converter_do_get_type(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) { + UConverterType t; + + ZEND_PARSE_PARAMETERS_NONE(); + intl_errors_reset(&objval->error); + + if (!cnv) { + RETURN_NULL(); + } + + t = ucnv_getType(cnv); + if (U_FAILURE(objval->error.code)) { + THROW_UFAILURE(objval, objval->error.code); + RETURN_FALSE; + } + + RETURN_LONG(t); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getSourceType) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + php_converter_do_get_type(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getDestinationType) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + php_converter_do_get_type(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ php_converter_resolve_callback */ +static void php_converter_resolve_callback( + zend_fcall_info_cache *fcc, + zend_object *obj, + const char *callback_name, + size_t callback_name_len +) { + zend_function *fn = reinterpret_cast(zend_hash_str_find_ptr_lc(&obj->ce->function_table, callback_name, callback_name_len)); + ZEND_ASSERT(fn != nullptr); + + fcc->function_handler = fn; + fcc->object = obj; + fcc->called_scope = obj->ce; + fcc->calling_scope = nullptr; + fcc->closure = nullptr; +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, __construct) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + char *src = "utf-8"; + size_t src_len = sizeof("utf-8") - 1; + char *dest = src; + size_t dest_len = src_len; + + intl_error_reset(NULL); + + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_STRING_OR_NULL(dest, dest_len) + Z_PARAM_STRING_OR_NULL(src, src_len) + ZEND_PARSE_PARAMETERS_END(); + + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + if (UNEXPECTED(!php_converter_set_encoding(objval, &(objval->src), src, src_len))) { + ZEND_ASSERT(EG(exception)); + goto cleanup; + } + if (UNEXPECTED(!php_converter_set_encoding(objval, &(objval->dest), dest, dest_len))) { + ZEND_ASSERT(EG(exception)); + goto cleanup; + } + php_converter_resolve_callback(&objval->to_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("toUCallback")); + php_converter_resolve_callback(&objval->from_cache, Z_OBJ_P(ZEND_THIS), ZEND_STRL("fromUCallback")); +cleanup: + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, setSubstChars) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + char *chars; + size_t chars_len; + int ret = 1; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(chars, chars_len) + ZEND_PARSE_PARAMETERS_END(); + + intl_errors_reset(&objval->error); + + if (objval->src) { + UErrorCode error = U_ZERO_ERROR; + ucnv_setSubstChars(objval->src, chars, chars_len, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, error); + ret = 0; + } + } else { + php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Source Converter has not been initialized yet"); + ret = 0; + } + + if (objval->dest) { + UErrorCode error = U_ZERO_ERROR; + ucnv_setSubstChars(objval->dest, chars, chars_len, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, error); + ret = 0; + } + } else { + php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, "Destination Converter has not been initialized yet"); + ret = 0; + } + + RETURN_BOOL(ret); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getSubstChars) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + char chars[127]; + int8_t chars_len = sizeof(chars); + UErrorCode error = U_ZERO_ERROR; + + ZEND_PARSE_PARAMETERS_NONE(); + intl_errors_reset(&objval->error); + + if (!objval->src) { + RETURN_NULL(); + } + + /* src and dest get the same subst chars set, + * so it doesn't really matter which one we read from + */ + ucnv_getSubstChars(objval->src, chars, &chars_len, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, error); + RETURN_FALSE; + } + + RETURN_STRINGL(chars, chars_len); +} +/* }}} */ + +/* {{{ php_converter_do_convert */ +static zend_string* php_converter_do_convert(UConverter *dest_cnv, + UConverter *src_cnv, const char *src, int32_t src_len, + php_converter_object *objval + ) { + UErrorCode error = U_ZERO_ERROR; + int32_t temp_len, ret_len; + zend_string *ret; + UChar *temp; + + if (!src_cnv || !dest_cnv) { + php_converter_throw_failure(objval, U_INVALID_STATE_ERROR, + "Internal converters not initialized"); + return nullptr; + } + + /* Get necessary buffer size first */ + temp_len = 1 + ucnv_toUChars(src_cnv, NULL, 0, src, src_len, &error); + if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { + THROW_UFAILURE(objval, error); + return nullptr; + } + temp = reinterpret_cast(safe_emalloc(sizeof(UChar), temp_len, sizeof(UChar))); + + /* Convert to intermediate UChar* array */ + error = U_ZERO_ERROR; + temp_len = ucnv_toUChars(src_cnv, temp, temp_len, src, src_len, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, error); + efree(temp); + return nullptr; + } + temp[temp_len] = 0; + + /* Get necessary output buffer size */ + ret_len = ucnv_fromUChars(dest_cnv, NULL, 0, temp, temp_len, &error); + if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) { + THROW_UFAILURE(objval, error); + efree(temp); + return nullptr; + } + + ret = zend_string_alloc(ret_len, 0); + + /* Convert to final encoding */ + error = U_ZERO_ERROR; + ZSTR_LEN(ret) = ucnv_fromUChars(dest_cnv, ZSTR_VAL(ret), ret_len+1, temp, temp_len, &error); + efree(temp); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, error); + zend_string_efree(ret); + return nullptr; + } + + return ret; +} +/* }}} */ + +/* {{{ */ +#define UCNV_REASON_CASE(v) case (UCNV_ ## v) : RETURN_STRINGL( "REASON_" #v , sizeof( "REASON_" #v ) - 1); +PHP_METHOD(UConverter, reasonText) { + zend_long reason; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(reason) + ZEND_PARSE_PARAMETERS_END(); + intl_error_reset(NULL); + + switch (reason) { + UCNV_REASON_CASE(UNASSIGNED) + UCNV_REASON_CASE(ILLEGAL) + UCNV_REASON_CASE(IRREGULAR) + UCNV_REASON_CASE(RESET) + UCNV_REASON_CASE(CLOSE) + UCNV_REASON_CASE(CLONE) + default: + zend_argument_value_error(1, "must be a UConverter::REASON_* constant"); + RETURN_THROWS(); + } +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, convert) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + char *str; + size_t str_len; + zend_string *ret; + bool reverse = false; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(str, str_len) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(reverse) + ZEND_PARSE_PARAMETERS_END(); + intl_errors_reset(&objval->error); + + ret = php_converter_do_convert(reverse ? objval->src : objval->dest, + reverse ? objval->dest : objval->src, + str, str_len, + objval); + if (ret) { + RETURN_NEW_STR(ret); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, transcode) { + char *str, *src, *dest; + size_t str_len, src_len, dest_len; + zval *options = nullptr; + UConverter *src_cnv = nullptr, *dest_cnv = nullptr; + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_STRING(str, str_len) + Z_PARAM_STRING(dest, dest_len) + Z_PARAM_STRING(src, src_len) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_OR_NULL(options) + ZEND_PARSE_PARAMETERS_END(); + intl_error_reset(NULL); + + if (php_converter_set_encoding(NULL, &src_cnv, src, src_len) && + php_converter_set_encoding(NULL, &dest_cnv, dest, dest_len)) { + zend_string *ret; + UErrorCode error = U_ZERO_ERROR; + + if (options && zend_hash_num_elements(Z_ARRVAL_P(options))) { + zval *tmpzval; + + if (U_SUCCESS(error) && + (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst") - 1)) != NULL && + Z_TYPE_P(tmpzval) == IS_STRING) { + error = U_ZERO_ERROR; + ucnv_setSubstChars(src_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); + } + if (U_SUCCESS(error) && + (tmpzval = zend_hash_str_find_deref(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst") - 1)) != NULL && + Z_TYPE_P(tmpzval) == IS_STRING) { + error = U_ZERO_ERROR; + ucnv_setSubstChars(dest_cnv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval) & 0x7F, &error); + } + } + + if (U_SUCCESS(error) && + (ret = php_converter_do_convert(dest_cnv, src_cnv, str, str_len, NULL)) != NULL) { + RETVAL_NEW_STR(ret); + } + + if (U_FAILURE(error)) { + THROW_UFAILURE(NULL, error); + RETVAL_FALSE; + } + } else { + RETVAL_FALSE; + } + + if (src_cnv) { + ucnv_close(src_cnv); + } + if (dest_cnv) { + ucnv_close(dest_cnv); + } +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getErrorCode) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_LONG(intl_error_get_code(&(objval->error))); +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getErrorMessage) { + php_converter_object *objval = CONV_GET(ZEND_THIS); + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_string *message = intl_error_get_message(&(objval->error)); + if (message) { + RETURN_STR(message); + } else { + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getAvailable) { + int32_t i, + count = ucnv_countAvailable(); + + ZEND_PARSE_PARAMETERS_NONE(); + + intl_error_reset(NULL); + + array_init_size(return_value, count); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); + for(i = 0; i < count; i++) { + const char *name = ucnv_getAvailableName(i); + add_next_index_string(return_value, name); + } +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getAliases) { + char *name; + size_t name_len; + UErrorCode error = U_ZERO_ERROR; + uint16_t i, count; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(name, name_len) + ZEND_PARSE_PARAMETERS_END(); + intl_error_reset(NULL); + + count = ucnv_countAliases(name, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(NULL, error); + RETURN_FALSE; + } + + array_init_size(return_value, count); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); + for(i = 0; i < count; i++) { + const char *alias; + + error = U_ZERO_ERROR; + alias = ucnv_getAlias(name, i, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(NULL, error); + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_NULL(); + } + add_next_index_string(return_value, alias); + } +} +/* }}} */ + +/* {{{ */ +PHP_METHOD(UConverter, getStandards) { + uint16_t i, count; + + ZEND_PARSE_PARAMETERS_NONE(); + intl_error_reset(NULL); + + count = ucnv_countStandards(); + array_init_size(return_value, count); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); + for(i = 0; i < count; i++) { + UErrorCode error = U_ZERO_ERROR; + const char *name = ucnv_getStandard(i, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(NULL, error); + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_NULL(); + } + add_next_index_string(return_value, name); + } +} +/* }}} */ + +/* {{{ Converter create/clone/destroy */ +static void php_converter_free_object(zend_object *obj) { + php_converter_object *objval = php_converter_fetch_object(obj); + + if (objval->src) { + ucnv_close(objval->src); + } + + if (objval->dest) { + ucnv_close(objval->dest); + } + + intl_error_reset(&objval->error); + zend_object_std_dtor(obj); +} + +static zend_object *php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval) { + php_converter_object *objval; + + objval = reinterpret_cast(zend_object_alloc(sizeof(php_converter_object), ce)); + + zend_object_std_init(&objval->obj, ce); + object_properties_init(&objval->obj, ce); + intl_error_init(&(objval->error)); + + *pobjval = objval; + + return &objval->obj; +} + +static zend_object *php_converter_create_object(zend_class_entry *ce) { + php_converter_object *objval = nullptr; + zend_object *retval = php_converter_object_ctor(ce, &objval); + + object_properties_init(&(objval->obj), ce); + + return retval; +} + +static zend_object *php_converter_clone_object(zend_object *object) { + const php_converter_object *oldobj = php_converter_fetch_object(object); + php_converter_object *objval; + zend_object *retval = php_converter_object_ctor(object->ce, &objval); + UErrorCode error = U_ZERO_ERROR; + +#if U_ICU_VERSION_MAJOR_NUM > 70 + objval->src = ucnv_clone(oldobj->src, &error); +#else + objval->src = ucnv_safeClone(oldobj->src, NULL, NULL, &error); +#endif + if (U_SUCCESS(error)) { + error = U_ZERO_ERROR; +#if U_ICU_VERSION_MAJOR_NUM > 70 + objval->dest = ucnv_clone(oldobj->dest, &error); +#else + objval->dest = ucnv_safeClone(oldobj->dest, NULL, NULL, &error); +#endif + } + + if (U_FAILURE(error)) { + zend_throw_error(NULL, "Failed to clone UConverter"); + return retval; + } + + /* Update contexts for converter error handlers */ + php_converter_set_callbacks(objval, objval->src ); + php_converter_set_callbacks(objval, objval->dest); + + zend_objects_clone_members(&(objval->obj), &(oldobj->obj)); + + /* Newly cloned object deliberately does not inherit error state from original object */ + + return retval; +} +/* }}} */ + +/* {{{ php_converter_minit */ +U_CFUNC int php_converter_minit(INIT_FUNC_ARGS) { + php_converter_ce = register_class_UConverter(); + php_converter_ce->create_object = php_converter_create_object; + php_converter_ce->default_object_handlers = &php_converter_object_handlers; + memcpy(&php_converter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_converter_object_handlers.offset = offsetof(php_converter_object, obj); + php_converter_object_handlers.clone_obj = php_converter_clone_object; + php_converter_object_handlers.free_obj = php_converter_free_object; + + return SUCCESS; +} +/* }}} */ diff --git a/ext/intl/converter/converter.h b/ext/intl/converter/converter.h index f9fb27b82a7d..60967d196723 100644 --- a/ext/intl/converter/converter.h +++ b/ext/intl/converter/converter.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ @@ -21,6 +21,12 @@ #include "php.h" +#ifdef __cplusplus +extern "C" { +#endif int php_converter_minit(INIT_FUNC_ARGS); +#ifdef __cplusplus +} +#endif #endif /* PHP_INTL_CONVERTER_H */ diff --git a/ext/intl/converter/converter_arginfo.h b/ext/intl/converter/converter_arginfo.h index 4e02daf9478a..d43981abf6ae 100644 --- a/ext/intl/converter/converter_arginfo.h +++ b/ext/intl/converter/converter_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit converter.stub.php instead. * Stub hash: f351fbf3afd9753fb16c87903c3dbd5e4621c024 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_UConverter___construct, 0, 0, 0) @@ -126,249 +126,249 @@ static zend_class_entry *register_class_UConverter(void) zval const_REASON_UNASSIGNED_value; ZVAL_LONG(&const_REASON_UNASSIGNED_value, UCNV_UNASSIGNED); - zend_string *const_REASON_UNASSIGNED_name = zend_string_init_interned("REASON_UNASSIGNED", sizeof("REASON_UNASSIGNED") - 1, 1); + zend_string *const_REASON_UNASSIGNED_name = zend_string_init_interned("REASON_UNASSIGNED", sizeof("REASON_UNASSIGNED") - 1, true); zend_declare_typed_class_constant(class_entry, const_REASON_UNASSIGNED_name, &const_REASON_UNASSIGNED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REASON_UNASSIGNED_name); + zend_string_release_ex(const_REASON_UNASSIGNED_name, true); zval const_REASON_ILLEGAL_value; ZVAL_LONG(&const_REASON_ILLEGAL_value, UCNV_ILLEGAL); - zend_string *const_REASON_ILLEGAL_name = zend_string_init_interned("REASON_ILLEGAL", sizeof("REASON_ILLEGAL") - 1, 1); + zend_string *const_REASON_ILLEGAL_name = zend_string_init_interned("REASON_ILLEGAL", sizeof("REASON_ILLEGAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_REASON_ILLEGAL_name, &const_REASON_ILLEGAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REASON_ILLEGAL_name); + zend_string_release_ex(const_REASON_ILLEGAL_name, true); zval const_REASON_IRREGULAR_value; ZVAL_LONG(&const_REASON_IRREGULAR_value, UCNV_IRREGULAR); - zend_string *const_REASON_IRREGULAR_name = zend_string_init_interned("REASON_IRREGULAR", sizeof("REASON_IRREGULAR") - 1, 1); + zend_string *const_REASON_IRREGULAR_name = zend_string_init_interned("REASON_IRREGULAR", sizeof("REASON_IRREGULAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_REASON_IRREGULAR_name, &const_REASON_IRREGULAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REASON_IRREGULAR_name); + zend_string_release_ex(const_REASON_IRREGULAR_name, true); zval const_REASON_RESET_value; ZVAL_LONG(&const_REASON_RESET_value, UCNV_RESET); - zend_string *const_REASON_RESET_name = zend_string_init_interned("REASON_RESET", sizeof("REASON_RESET") - 1, 1); + zend_string *const_REASON_RESET_name = zend_string_init_interned("REASON_RESET", sizeof("REASON_RESET") - 1, true); zend_declare_typed_class_constant(class_entry, const_REASON_RESET_name, &const_REASON_RESET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REASON_RESET_name); + zend_string_release_ex(const_REASON_RESET_name, true); zval const_REASON_CLOSE_value; ZVAL_LONG(&const_REASON_CLOSE_value, UCNV_CLOSE); - zend_string *const_REASON_CLOSE_name = zend_string_init_interned("REASON_CLOSE", sizeof("REASON_CLOSE") - 1, 1); + zend_string *const_REASON_CLOSE_name = zend_string_init_interned("REASON_CLOSE", sizeof("REASON_CLOSE") - 1, true); zend_declare_typed_class_constant(class_entry, const_REASON_CLOSE_name, &const_REASON_CLOSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REASON_CLOSE_name); + zend_string_release_ex(const_REASON_CLOSE_name, true); zval const_REASON_CLONE_value; ZVAL_LONG(&const_REASON_CLONE_value, UCNV_CLONE); - zend_string *const_REASON_CLONE_name = zend_string_init_interned("REASON_CLONE", sizeof("REASON_CLONE") - 1, 1); + zend_string *const_REASON_CLONE_name = zend_string_init_interned("REASON_CLONE", sizeof("REASON_CLONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_REASON_CLONE_name, &const_REASON_CLONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REASON_CLONE_name); + zend_string_release_ex(const_REASON_CLONE_name, true); zval const_UNSUPPORTED_CONVERTER_value; ZVAL_LONG(&const_UNSUPPORTED_CONVERTER_value, UCNV_UNSUPPORTED_CONVERTER); - zend_string *const_UNSUPPORTED_CONVERTER_name = zend_string_init_interned("UNSUPPORTED_CONVERTER", sizeof("UNSUPPORTED_CONVERTER") - 1, 1); + zend_string *const_UNSUPPORTED_CONVERTER_name = zend_string_init_interned("UNSUPPORTED_CONVERTER", sizeof("UNSUPPORTED_CONVERTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_UNSUPPORTED_CONVERTER_name, &const_UNSUPPORTED_CONVERTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UNSUPPORTED_CONVERTER_name); + zend_string_release_ex(const_UNSUPPORTED_CONVERTER_name, true); zval const_SBCS_value; ZVAL_LONG(&const_SBCS_value, UCNV_SBCS); - zend_string *const_SBCS_name = zend_string_init_interned("SBCS", sizeof("SBCS") - 1, 1); + zend_string *const_SBCS_name = zend_string_init_interned("SBCS", sizeof("SBCS") - 1, true); zend_declare_typed_class_constant(class_entry, const_SBCS_name, &const_SBCS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SBCS_name); + zend_string_release_ex(const_SBCS_name, true); zval const_DBCS_value; ZVAL_LONG(&const_DBCS_value, UCNV_DBCS); - zend_string *const_DBCS_name = zend_string_init_interned("DBCS", sizeof("DBCS") - 1, 1); + zend_string *const_DBCS_name = zend_string_init_interned("DBCS", sizeof("DBCS") - 1, true); zend_declare_typed_class_constant(class_entry, const_DBCS_name, &const_DBCS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DBCS_name); + zend_string_release_ex(const_DBCS_name, true); zval const_MBCS_value; ZVAL_LONG(&const_MBCS_value, UCNV_MBCS); - zend_string *const_MBCS_name = zend_string_init_interned("MBCS", sizeof("MBCS") - 1, 1); + zend_string *const_MBCS_name = zend_string_init_interned("MBCS", sizeof("MBCS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MBCS_name, &const_MBCS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MBCS_name); + zend_string_release_ex(const_MBCS_name, true); zval const_LATIN_1_value; ZVAL_LONG(&const_LATIN_1_value, UCNV_LATIN_1); - zend_string *const_LATIN_1_name = zend_string_init_interned("LATIN_1", sizeof("LATIN_1") - 1, 1); + zend_string *const_LATIN_1_name = zend_string_init_interned("LATIN_1", sizeof("LATIN_1") - 1, true); zend_declare_typed_class_constant(class_entry, const_LATIN_1_name, &const_LATIN_1_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LATIN_1_name); + zend_string_release_ex(const_LATIN_1_name, true); zval const_UTF8_value; ZVAL_LONG(&const_UTF8_value, UCNV_UTF8); - zend_string *const_UTF8_name = zend_string_init_interned("UTF8", sizeof("UTF8") - 1, 1); + zend_string *const_UTF8_name = zend_string_init_interned("UTF8", sizeof("UTF8") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF8_name, &const_UTF8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF8_name); + zend_string_release_ex(const_UTF8_name, true); zval const_UTF16_BigEndian_value; ZVAL_LONG(&const_UTF16_BigEndian_value, UCNV_UTF16_BigEndian); - zend_string *const_UTF16_BigEndian_name = zend_string_init_interned("UTF16_BigEndian", sizeof("UTF16_BigEndian") - 1, 1); + zend_string *const_UTF16_BigEndian_name = zend_string_init_interned("UTF16_BigEndian", sizeof("UTF16_BigEndian") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF16_BigEndian_name, &const_UTF16_BigEndian_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF16_BigEndian_name); + zend_string_release_ex(const_UTF16_BigEndian_name, true); zval const_UTF16_LittleEndian_value; ZVAL_LONG(&const_UTF16_LittleEndian_value, UCNV_UTF16_LittleEndian); - zend_string *const_UTF16_LittleEndian_name = zend_string_init_interned("UTF16_LittleEndian", sizeof("UTF16_LittleEndian") - 1, 1); + zend_string *const_UTF16_LittleEndian_name = zend_string_init_interned("UTF16_LittleEndian", sizeof("UTF16_LittleEndian") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF16_LittleEndian_name, &const_UTF16_LittleEndian_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF16_LittleEndian_name); + zend_string_release_ex(const_UTF16_LittleEndian_name, true); zval const_UTF32_BigEndian_value; ZVAL_LONG(&const_UTF32_BigEndian_value, UCNV_UTF32_BigEndian); - zend_string *const_UTF32_BigEndian_name = zend_string_init_interned("UTF32_BigEndian", sizeof("UTF32_BigEndian") - 1, 1); + zend_string *const_UTF32_BigEndian_name = zend_string_init_interned("UTF32_BigEndian", sizeof("UTF32_BigEndian") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF32_BigEndian_name, &const_UTF32_BigEndian_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF32_BigEndian_name); + zend_string_release_ex(const_UTF32_BigEndian_name, true); zval const_UTF32_LittleEndian_value; ZVAL_LONG(&const_UTF32_LittleEndian_value, UCNV_UTF32_LittleEndian); - zend_string *const_UTF32_LittleEndian_name = zend_string_init_interned("UTF32_LittleEndian", sizeof("UTF32_LittleEndian") - 1, 1); + zend_string *const_UTF32_LittleEndian_name = zend_string_init_interned("UTF32_LittleEndian", sizeof("UTF32_LittleEndian") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF32_LittleEndian_name, &const_UTF32_LittleEndian_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF32_LittleEndian_name); + zend_string_release_ex(const_UTF32_LittleEndian_name, true); zval const_EBCDIC_STATEFUL_value; ZVAL_LONG(&const_EBCDIC_STATEFUL_value, UCNV_EBCDIC_STATEFUL); - zend_string *const_EBCDIC_STATEFUL_name = zend_string_init_interned("EBCDIC_STATEFUL", sizeof("EBCDIC_STATEFUL") - 1, 1); + zend_string *const_EBCDIC_STATEFUL_name = zend_string_init_interned("EBCDIC_STATEFUL", sizeof("EBCDIC_STATEFUL") - 1, true); zend_declare_typed_class_constant(class_entry, const_EBCDIC_STATEFUL_name, &const_EBCDIC_STATEFUL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EBCDIC_STATEFUL_name); + zend_string_release_ex(const_EBCDIC_STATEFUL_name, true); zval const_ISO_2022_value; ZVAL_LONG(&const_ISO_2022_value, UCNV_ISO_2022); - zend_string *const_ISO_2022_name = zend_string_init_interned("ISO_2022", sizeof("ISO_2022") - 1, 1); + zend_string *const_ISO_2022_name = zend_string_init_interned("ISO_2022", sizeof("ISO_2022") - 1, true); zend_declare_typed_class_constant(class_entry, const_ISO_2022_name, &const_ISO_2022_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ISO_2022_name); + zend_string_release_ex(const_ISO_2022_name, true); zval const_LMBCS_1_value; ZVAL_LONG(&const_LMBCS_1_value, UCNV_LMBCS_1); - zend_string *const_LMBCS_1_name = zend_string_init_interned("LMBCS_1", sizeof("LMBCS_1") - 1, 1); + zend_string *const_LMBCS_1_name = zend_string_init_interned("LMBCS_1", sizeof("LMBCS_1") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_1_name, &const_LMBCS_1_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_1_name); + zend_string_release_ex(const_LMBCS_1_name, true); zval const_LMBCS_2_value; ZVAL_LONG(&const_LMBCS_2_value, UCNV_LMBCS_2); - zend_string *const_LMBCS_2_name = zend_string_init_interned("LMBCS_2", sizeof("LMBCS_2") - 1, 1); + zend_string *const_LMBCS_2_name = zend_string_init_interned("LMBCS_2", sizeof("LMBCS_2") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_2_name, &const_LMBCS_2_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_2_name); + zend_string_release_ex(const_LMBCS_2_name, true); zval const_LMBCS_3_value; ZVAL_LONG(&const_LMBCS_3_value, UCNV_LMBCS_3); - zend_string *const_LMBCS_3_name = zend_string_init_interned("LMBCS_3", sizeof("LMBCS_3") - 1, 1); + zend_string *const_LMBCS_3_name = zend_string_init_interned("LMBCS_3", sizeof("LMBCS_3") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_3_name, &const_LMBCS_3_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_3_name); + zend_string_release_ex(const_LMBCS_3_name, true); zval const_LMBCS_4_value; ZVAL_LONG(&const_LMBCS_4_value, UCNV_LMBCS_4); - zend_string *const_LMBCS_4_name = zend_string_init_interned("LMBCS_4", sizeof("LMBCS_4") - 1, 1); + zend_string *const_LMBCS_4_name = zend_string_init_interned("LMBCS_4", sizeof("LMBCS_4") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_4_name, &const_LMBCS_4_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_4_name); + zend_string_release_ex(const_LMBCS_4_name, true); zval const_LMBCS_5_value; ZVAL_LONG(&const_LMBCS_5_value, UCNV_LMBCS_5); - zend_string *const_LMBCS_5_name = zend_string_init_interned("LMBCS_5", sizeof("LMBCS_5") - 1, 1); + zend_string *const_LMBCS_5_name = zend_string_init_interned("LMBCS_5", sizeof("LMBCS_5") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_5_name, &const_LMBCS_5_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_5_name); + zend_string_release_ex(const_LMBCS_5_name, true); zval const_LMBCS_6_value; ZVAL_LONG(&const_LMBCS_6_value, UCNV_LMBCS_6); - zend_string *const_LMBCS_6_name = zend_string_init_interned("LMBCS_6", sizeof("LMBCS_6") - 1, 1); + zend_string *const_LMBCS_6_name = zend_string_init_interned("LMBCS_6", sizeof("LMBCS_6") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_6_name, &const_LMBCS_6_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_6_name); + zend_string_release_ex(const_LMBCS_6_name, true); zval const_LMBCS_8_value; ZVAL_LONG(&const_LMBCS_8_value, UCNV_LMBCS_8); - zend_string *const_LMBCS_8_name = zend_string_init_interned("LMBCS_8", sizeof("LMBCS_8") - 1, 1); + zend_string *const_LMBCS_8_name = zend_string_init_interned("LMBCS_8", sizeof("LMBCS_8") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_8_name, &const_LMBCS_8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_8_name); + zend_string_release_ex(const_LMBCS_8_name, true); zval const_LMBCS_11_value; ZVAL_LONG(&const_LMBCS_11_value, UCNV_LMBCS_11); - zend_string *const_LMBCS_11_name = zend_string_init_interned("LMBCS_11", sizeof("LMBCS_11") - 1, 1); + zend_string *const_LMBCS_11_name = zend_string_init_interned("LMBCS_11", sizeof("LMBCS_11") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_11_name, &const_LMBCS_11_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_11_name); + zend_string_release_ex(const_LMBCS_11_name, true); zval const_LMBCS_16_value; ZVAL_LONG(&const_LMBCS_16_value, UCNV_LMBCS_16); - zend_string *const_LMBCS_16_name = zend_string_init_interned("LMBCS_16", sizeof("LMBCS_16") - 1, 1); + zend_string *const_LMBCS_16_name = zend_string_init_interned("LMBCS_16", sizeof("LMBCS_16") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_16_name, &const_LMBCS_16_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_16_name); + zend_string_release_ex(const_LMBCS_16_name, true); zval const_LMBCS_17_value; ZVAL_LONG(&const_LMBCS_17_value, UCNV_LMBCS_17); - zend_string *const_LMBCS_17_name = zend_string_init_interned("LMBCS_17", sizeof("LMBCS_17") - 1, 1); + zend_string *const_LMBCS_17_name = zend_string_init_interned("LMBCS_17", sizeof("LMBCS_17") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_17_name, &const_LMBCS_17_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_17_name); + zend_string_release_ex(const_LMBCS_17_name, true); zval const_LMBCS_18_value; ZVAL_LONG(&const_LMBCS_18_value, UCNV_LMBCS_18); - zend_string *const_LMBCS_18_name = zend_string_init_interned("LMBCS_18", sizeof("LMBCS_18") - 1, 1); + zend_string *const_LMBCS_18_name = zend_string_init_interned("LMBCS_18", sizeof("LMBCS_18") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_18_name, &const_LMBCS_18_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_18_name); + zend_string_release_ex(const_LMBCS_18_name, true); zval const_LMBCS_19_value; ZVAL_LONG(&const_LMBCS_19_value, UCNV_LMBCS_19); - zend_string *const_LMBCS_19_name = zend_string_init_interned("LMBCS_19", sizeof("LMBCS_19") - 1, 1); + zend_string *const_LMBCS_19_name = zend_string_init_interned("LMBCS_19", sizeof("LMBCS_19") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_19_name, &const_LMBCS_19_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_19_name); + zend_string_release_ex(const_LMBCS_19_name, true); zval const_LMBCS_LAST_value; ZVAL_LONG(&const_LMBCS_LAST_value, UCNV_LMBCS_LAST); - zend_string *const_LMBCS_LAST_name = zend_string_init_interned("LMBCS_LAST", sizeof("LMBCS_LAST") - 1, 1); + zend_string *const_LMBCS_LAST_name = zend_string_init_interned("LMBCS_LAST", sizeof("LMBCS_LAST") - 1, true); zend_declare_typed_class_constant(class_entry, const_LMBCS_LAST_name, &const_LMBCS_LAST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LMBCS_LAST_name); + zend_string_release_ex(const_LMBCS_LAST_name, true); zval const_HZ_value; ZVAL_LONG(&const_HZ_value, UCNV_HZ); - zend_string *const_HZ_name = zend_string_init_interned("HZ", sizeof("HZ") - 1, 1); + zend_string *const_HZ_name = zend_string_init_interned("HZ", sizeof("HZ") - 1, true); zend_declare_typed_class_constant(class_entry, const_HZ_name, &const_HZ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HZ_name); + zend_string_release_ex(const_HZ_name, true); zval const_SCSU_value; ZVAL_LONG(&const_SCSU_value, UCNV_SCSU); - zend_string *const_SCSU_name = zend_string_init_interned("SCSU", sizeof("SCSU") - 1, 1); + zend_string *const_SCSU_name = zend_string_init_interned("SCSU", sizeof("SCSU") - 1, true); zend_declare_typed_class_constant(class_entry, const_SCSU_name, &const_SCSU_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SCSU_name); + zend_string_release_ex(const_SCSU_name, true); zval const_ISCII_value; ZVAL_LONG(&const_ISCII_value, UCNV_ISCII); - zend_string *const_ISCII_name = zend_string_init_interned("ISCII", sizeof("ISCII") - 1, 1); + zend_string *const_ISCII_name = zend_string_init_interned("ISCII", sizeof("ISCII") - 1, true); zend_declare_typed_class_constant(class_entry, const_ISCII_name, &const_ISCII_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ISCII_name); + zend_string_release_ex(const_ISCII_name, true); zval const_US_ASCII_value; ZVAL_LONG(&const_US_ASCII_value, UCNV_US_ASCII); - zend_string *const_US_ASCII_name = zend_string_init_interned("US_ASCII", sizeof("US_ASCII") - 1, 1); + zend_string *const_US_ASCII_name = zend_string_init_interned("US_ASCII", sizeof("US_ASCII") - 1, true); zend_declare_typed_class_constant(class_entry, const_US_ASCII_name, &const_US_ASCII_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_US_ASCII_name); + zend_string_release_ex(const_US_ASCII_name, true); zval const_UTF7_value; ZVAL_LONG(&const_UTF7_value, UCNV_UTF7); - zend_string *const_UTF7_name = zend_string_init_interned("UTF7", sizeof("UTF7") - 1, 1); + zend_string *const_UTF7_name = zend_string_init_interned("UTF7", sizeof("UTF7") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF7_name, &const_UTF7_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF7_name); + zend_string_release_ex(const_UTF7_name, true); zval const_BOCU1_value; ZVAL_LONG(&const_BOCU1_value, UCNV_BOCU1); - zend_string *const_BOCU1_name = zend_string_init_interned("BOCU1", sizeof("BOCU1") - 1, 1); + zend_string *const_BOCU1_name = zend_string_init_interned("BOCU1", sizeof("BOCU1") - 1, true); zend_declare_typed_class_constant(class_entry, const_BOCU1_name, &const_BOCU1_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BOCU1_name); + zend_string_release_ex(const_BOCU1_name, true); zval const_UTF16_value; ZVAL_LONG(&const_UTF16_value, UCNV_UTF16); - zend_string *const_UTF16_name = zend_string_init_interned("UTF16", sizeof("UTF16") - 1, 1); + zend_string *const_UTF16_name = zend_string_init_interned("UTF16", sizeof("UTF16") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF16_name, &const_UTF16_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF16_name); + zend_string_release_ex(const_UTF16_name, true); zval const_UTF32_value; ZVAL_LONG(&const_UTF32_value, UCNV_UTF32); - zend_string *const_UTF32_name = zend_string_init_interned("UTF32", sizeof("UTF32") - 1, 1); + zend_string *const_UTF32_name = zend_string_init_interned("UTF32", sizeof("UTF32") - 1, true); zend_declare_typed_class_constant(class_entry, const_UTF32_name, &const_UTF32_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UTF32_name); + zend_string_release_ex(const_UTF32_name, true); zval const_CESU8_value; ZVAL_LONG(&const_CESU8_value, UCNV_CESU8); - zend_string *const_CESU8_name = zend_string_init_interned("CESU8", sizeof("CESU8") - 1, 1); + zend_string *const_CESU8_name = zend_string_init_interned("CESU8", sizeof("CESU8") - 1, true); zend_declare_typed_class_constant(class_entry, const_CESU8_name, &const_CESU8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CESU8_name); + zend_string_release_ex(const_CESU8_name, true); zval const_IMAP_MAILBOX_value; ZVAL_LONG(&const_IMAP_MAILBOX_value, UCNV_IMAP_MAILBOX); - zend_string *const_IMAP_MAILBOX_name = zend_string_init_interned("IMAP_MAILBOX", sizeof("IMAP_MAILBOX") - 1, 1); + zend_string *const_IMAP_MAILBOX_name = zend_string_init_interned("IMAP_MAILBOX", sizeof("IMAP_MAILBOX") - 1, true); zend_declare_typed_class_constant(class_entry, const_IMAP_MAILBOX_name, &const_IMAP_MAILBOX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IMAP_MAILBOX_name); + zend_string_release_ex(const_IMAP_MAILBOX_name, true); return class_entry; } diff --git a/ext/intl/dateformat/dateformat.c b/ext/intl/dateformat/dateformat.c deleted file mode 100644 index e6ebd5b78964..000000000000 --- a/ext/intl/dateformat/dateformat.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "php_intl.h" -#include "dateformat_class.h" -#include "dateformat.h" - -/* {{{ Get formatter's last error code. */ -PHP_FUNCTION( datefmt_get_error_code ) -{ - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - dfo = Z_INTL_DATEFORMATTER_P( object ); - - /* Return formatter's last error code. */ - RETURN_LONG( INTL_DATA_ERROR_CODE(dfo) ); -} -/* }}} */ - -/* {{{ Get text description for formatter's last error code. */ -PHP_FUNCTION( datefmt_get_error_message ) -{ - zend_string *message = NULL; - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - dfo = Z_INTL_DATEFORMATTER_P( object ); - - /* Return last error message. */ - message = intl_error_get_message( INTL_DATA_ERROR_P(dfo) ); - RETURN_STR( message); -} -/* }}} */ diff --git a/ext/intl/dateformat/dateformat.cpp b/ext/intl/dateformat/dateformat.cpp new file mode 100644 index 000000000000..64454a8afde9 --- /dev/null +++ b/ext/intl/dateformat/dateformat.cpp @@ -0,0 +1,64 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +extern "C" { +#include "php_intl.h" +} +#include "dateformat_class.h" +#include "dateformat.h" + +/* {{{ Get formatter's last error code. */ +U_CFUNC PHP_FUNCTION( datefmt_get_error_code ) +{ + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, IntlDateFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + dfo = Z_INTL_DATEFORMATTER_P( object ); + + /* Return formatter's last error code. */ + RETURN_LONG( INTL_DATA_ERROR_CODE(dfo) ); +} +/* }}} */ + +/* {{{ Get text description for formatter's last error code. */ +U_CFUNC PHP_FUNCTION( datefmt_get_error_message ) +{ + zend_string *message = NULL; + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, IntlDateFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + dfo = Z_INTL_DATEFORMATTER_P( object ); + + /* Return last error message. */ + message = intl_error_get_message( INTL_DATA_ERROR_P(dfo) ); + RETURN_STR( message); +} +/* }}} */ diff --git a/ext/intl/dateformat/dateformat.h b/ext/intl/dateformat/dateformat.h index 3e0b14cf6c0d..bff8d4e1ed72 100644 --- a/ext/intl/dateformat/dateformat.h +++ b/ext/intl/dateformat/dateformat.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat.stub.php b/ext/intl/dateformat/dateformat.stub.php index 7582af2717fb..89ebc5f61c0e 100644 --- a/ext/intl/dateformat/dateformat.stub.php +++ b/ext/intl/dateformat/dateformat.stub.php @@ -32,20 +32,18 @@ class IntlDateFormatter public const int TRADITIONAL = UNKNOWN; /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @param IntlCalendar|int|null $calendar */ public function __construct( ?string $locale, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, - $timezone = null, + IntlTimeZone|DateTimeZone|string|null $timezone = null, $calendar = null, ?string $pattern = null ) {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type * @alias datefmt_create */ @@ -53,7 +51,7 @@ public static function create( ?string $locale, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, - $timezone = null, + IntlTimeZone|DateTimeZone|string|null $timezone = null, IntlCalendar|int|null $calendar = null, ?string $pattern = null ): ?IntlDateFormatter {} @@ -101,11 +99,9 @@ public function getCalendarObject(): IntlCalendar|false|null {} public function getTimeZone(): IntlTimeZone|false {} /** - * @param IntlTimeZone|DateTimeZone|string|null $timezone * @tentative-return-type - * @alias datefmt_set_timezone */ - public function setTimeZone($timezone): bool {} + public function setTimeZone(IntlTimeZone|DateTimeZone|string|null $timezone): bool {} /** * @tentative-return-type diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h index b57cb79468f2..2d297b26a042 100644 --- a/ext/intl/dateformat/dateformat_arginfo.h +++ b/ext/intl/dateformat/dateformat_arginfo.h @@ -1,11 +1,11 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 56b66b1b51220ddbff698ec4c9a6ae60f3e0bfb0 */ +/* This is a generated file, edit dateformat.stub.php instead. + * Stub hash: 160d05ec65c45b66b13eaecbef20b3c59bfb33d1 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dateType, IS_LONG, 0, "IntlDateFormatter::FULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeType, IS_LONG, 0, "IntlDateFormatter::FULL") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, calendar, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -14,7 +14,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlDateFormatter ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dateType, IS_LONG, 0, "IntlDateFormatter::FULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeType, IS_LONG, 0, "IntlDateFormatter::FULL") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -40,7 +40,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_IntlDateForm ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlDateFormatter_setTimeZone, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlDateFormatter_setPattern, 0, 1, _IS_BOOL, 0) @@ -100,7 +100,7 @@ ZEND_FUNCTION(datefmt_set_calendar); ZEND_FUNCTION(datefmt_get_timezone_id); ZEND_FUNCTION(datefmt_get_calendar_object); ZEND_FUNCTION(datefmt_get_timezone); -ZEND_FUNCTION(datefmt_set_timezone); +ZEND_METHOD(IntlDateFormatter, setTimeZone); ZEND_FUNCTION(datefmt_set_pattern); ZEND_FUNCTION(datefmt_get_pattern); ZEND_FUNCTION(datefmt_get_locale); @@ -124,7 +124,7 @@ static const zend_function_entry class_IntlDateFormatter_methods[] = { ZEND_RAW_FENTRY("getTimeZoneId", zif_datefmt_get_timezone_id, arginfo_class_IntlDateFormatter_getTimeZoneId, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getCalendarObject", zif_datefmt_get_calendar_object, arginfo_class_IntlDateFormatter_getCalendarObject, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getTimeZone", zif_datefmt_get_timezone, arginfo_class_IntlDateFormatter_getTimeZone, ZEND_ACC_PUBLIC, NULL, NULL) - ZEND_RAW_FENTRY("setTimeZone", zif_datefmt_set_timezone, arginfo_class_IntlDateFormatter_setTimeZone, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_ME(IntlDateFormatter, setTimeZone, arginfo_class_IntlDateFormatter_setTimeZone, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("setPattern", zif_datefmt_set_pattern, arginfo_class_IntlDateFormatter_setPattern, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getPattern", zif_datefmt_get_pattern, arginfo_class_IntlDateFormatter_getPattern, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getLocale", zif_datefmt_get_locale, arginfo_class_IntlDateFormatter_getLocale, ZEND_ACC_PUBLIC, NULL, NULL) @@ -149,75 +149,75 @@ static zend_class_entry *register_class_IntlDateFormatter(void) zval const_FULL_value; ZVAL_LONG(&const_FULL_value, UDAT_FULL); - zend_string *const_FULL_name = zend_string_init_interned("FULL", sizeof("FULL") - 1, 1); + zend_string *const_FULL_name = zend_string_init_interned("FULL", sizeof("FULL") - 1, true); zend_declare_typed_class_constant(class_entry, const_FULL_name, &const_FULL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FULL_name); + zend_string_release_ex(const_FULL_name, true); zval const_LONG_value; ZVAL_LONG(&const_LONG_value, UDAT_LONG); - zend_string *const_LONG_name = zend_string_init_interned("LONG", sizeof("LONG") - 1, 1); + zend_string *const_LONG_name = zend_string_init_interned("LONG", sizeof("LONG") - 1, true); zend_declare_typed_class_constant(class_entry, const_LONG_name, &const_LONG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LONG_name); + zend_string_release_ex(const_LONG_name, true); zval const_MEDIUM_value; ZVAL_LONG(&const_MEDIUM_value, UDAT_MEDIUM); - zend_string *const_MEDIUM_name = zend_string_init_interned("MEDIUM", sizeof("MEDIUM") - 1, 1); + zend_string *const_MEDIUM_name = zend_string_init_interned("MEDIUM", sizeof("MEDIUM") - 1, true); zend_declare_typed_class_constant(class_entry, const_MEDIUM_name, &const_MEDIUM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MEDIUM_name); + zend_string_release_ex(const_MEDIUM_name, true); zval const_SHORT_value; ZVAL_LONG(&const_SHORT_value, UDAT_SHORT); - zend_string *const_SHORT_name = zend_string_init_interned("SHORT", sizeof("SHORT") - 1, 1); + zend_string *const_SHORT_name = zend_string_init_interned("SHORT", sizeof("SHORT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SHORT_name, &const_SHORT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SHORT_name); + zend_string_release_ex(const_SHORT_name, true); zval const_NONE_value; ZVAL_LONG(&const_NONE_value, UDAT_NONE); - zend_string *const_NONE_name = zend_string_init_interned("NONE", sizeof("NONE") - 1, 1); + zend_string *const_NONE_name = zend_string_init_interned("NONE", sizeof("NONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_NONE_name, &const_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NONE_name); + zend_string_release_ex(const_NONE_name, true); zval const_RELATIVE_FULL_value; ZVAL_LONG(&const_RELATIVE_FULL_value, UDAT_FULL_RELATIVE); - zend_string *const_RELATIVE_FULL_name = zend_string_init_interned("RELATIVE_FULL", sizeof("RELATIVE_FULL") - 1, 1); + zend_string *const_RELATIVE_FULL_name = zend_string_init_interned("RELATIVE_FULL", sizeof("RELATIVE_FULL") - 1, true); zend_declare_typed_class_constant(class_entry, const_RELATIVE_FULL_name, &const_RELATIVE_FULL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_RELATIVE_FULL_name); + zend_string_release_ex(const_RELATIVE_FULL_name, true); zval const_RELATIVE_LONG_value; ZVAL_LONG(&const_RELATIVE_LONG_value, UDAT_LONG_RELATIVE); - zend_string *const_RELATIVE_LONG_name = zend_string_init_interned("RELATIVE_LONG", sizeof("RELATIVE_LONG") - 1, 1); + zend_string *const_RELATIVE_LONG_name = zend_string_init_interned("RELATIVE_LONG", sizeof("RELATIVE_LONG") - 1, true); zend_declare_typed_class_constant(class_entry, const_RELATIVE_LONG_name, &const_RELATIVE_LONG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_RELATIVE_LONG_name); + zend_string_release_ex(const_RELATIVE_LONG_name, true); zval const_RELATIVE_MEDIUM_value; ZVAL_LONG(&const_RELATIVE_MEDIUM_value, UDAT_MEDIUM_RELATIVE); - zend_string *const_RELATIVE_MEDIUM_name = zend_string_init_interned("RELATIVE_MEDIUM", sizeof("RELATIVE_MEDIUM") - 1, 1); + zend_string *const_RELATIVE_MEDIUM_name = zend_string_init_interned("RELATIVE_MEDIUM", sizeof("RELATIVE_MEDIUM") - 1, true); zend_declare_typed_class_constant(class_entry, const_RELATIVE_MEDIUM_name, &const_RELATIVE_MEDIUM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_RELATIVE_MEDIUM_name); + zend_string_release_ex(const_RELATIVE_MEDIUM_name, true); zval const_RELATIVE_SHORT_value; ZVAL_LONG(&const_RELATIVE_SHORT_value, UDAT_SHORT_RELATIVE); - zend_string *const_RELATIVE_SHORT_name = zend_string_init_interned("RELATIVE_SHORT", sizeof("RELATIVE_SHORT") - 1, 1); + zend_string *const_RELATIVE_SHORT_name = zend_string_init_interned("RELATIVE_SHORT", sizeof("RELATIVE_SHORT") - 1, true); zend_declare_typed_class_constant(class_entry, const_RELATIVE_SHORT_name, &const_RELATIVE_SHORT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_RELATIVE_SHORT_name); + zend_string_release_ex(const_RELATIVE_SHORT_name, true); zval const_PATTERN_value; ZVAL_LONG(&const_PATTERN_value, UDAT_PATTERN); - zend_string *const_PATTERN_name = zend_string_init_interned("PATTERN", sizeof("PATTERN") - 1, 1); + zend_string *const_PATTERN_name = zend_string_init_interned("PATTERN", sizeof("PATTERN") - 1, true); zend_declare_typed_class_constant(class_entry, const_PATTERN_name, &const_PATTERN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PATTERN_name); + zend_string_release_ex(const_PATTERN_name, true); zval const_GREGORIAN_value; ZVAL_LONG(&const_GREGORIAN_value, UCAL_GREGORIAN); - zend_string *const_GREGORIAN_name = zend_string_init_interned("GREGORIAN", sizeof("GREGORIAN") - 1, 1); + zend_string *const_GREGORIAN_name = zend_string_init_interned("GREGORIAN", sizeof("GREGORIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_GREGORIAN_name, &const_GREGORIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GREGORIAN_name); + zend_string_release_ex(const_GREGORIAN_name, true); zval const_TRADITIONAL_value; ZVAL_LONG(&const_TRADITIONAL_value, UCAL_TRADITIONAL); - zend_string *const_TRADITIONAL_name = zend_string_init_interned("TRADITIONAL", sizeof("TRADITIONAL") - 1, 1); + zend_string *const_TRADITIONAL_name = zend_string_init_interned("TRADITIONAL", sizeof("TRADITIONAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_TRADITIONAL_name, &const_TRADITIONAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRADITIONAL_name); + zend_string_release_ex(const_TRADITIONAL_name, true); return class_entry; } diff --git a/ext/intl/dateformat/dateformat_attr.c b/ext/intl/dateformat/dateformat_attr.c deleted file mode 100644 index 8032d758a939..000000000000 --- a/ext/intl/dateformat/dateformat_attr.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "../php_intl.h" -#include "dateformat_class.h" -#include "../intl_convert.h" -#include "dateformat_class.h" - -#include -#include - -/* {{{ Get formatter datetype. */ -PHP_FUNCTION( datefmt_get_datetype ) -{ - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter datetype." ); - - RETURN_LONG(dfo->date_type ); -} -/* }}} */ - -/* {{{ Get formatter timetype. */ -PHP_FUNCTION( datefmt_get_timetype ) -{ - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter timetype." ); - - RETURN_LONG(dfo->time_type ); -} -/* }}} */ - -/* {{{ Get formatter pattern. */ -PHP_FUNCTION( datefmt_get_pattern ) -{ - UChar value_buf[64]; - uint32_t length = USIZE( value_buf ); - UChar* value = value_buf; - bool is_pattern_localized = false; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - length = udat_toPattern(DATE_FORMAT_OBJECT(dfo), is_pattern_localized, value, length, &INTL_DATA_ERROR_CODE(dfo)); - if(INTL_DATA_ERROR_CODE(dfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { - ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ - INTL_DATA_ERROR_CODE(dfo) = U_ZERO_ERROR; - value = eumalloc(length); - length = udat_toPattern(DATE_FORMAT_OBJECT(dfo), is_pattern_localized, value, length, &INTL_DATA_ERROR_CODE(dfo) ); - if(U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - efree(value); - value = value_buf; - } - } - INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter pattern" ); - - INTL_METHOD_RETVAL_UTF8( dfo, value, length, ( value != value_buf ) ); -} -/* }}} */ - -/* {{{ Set formatter pattern. */ -PHP_FUNCTION( datefmt_set_pattern ) -{ - char* value = NULL; - size_t value_len = 0; - int32_t slength = 0; - UChar* svalue = NULL; - bool is_pattern_localized = false; - - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", - &object, IntlDateFormatter_ce_ptr, &value, &value_len ) == FAILURE ) - { - RETURN_THROWS(); - } - - DATE_FORMAT_METHOD_FETCH_OBJECT; - - /* Convert given pattern to UTF-16. */ - intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(dfo)); - INTL_METHOD_CHECK_STATUS(dfo, "Error converting pattern to UTF-16" ); - - udat_applyPattern(DATE_FORMAT_OBJECT(dfo), (UBool)is_pattern_localized, svalue, slength); - - if (svalue) { - efree(svalue); - } - INTL_METHOD_CHECK_STATUS(dfo, "Error setting symbol value"); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Get formatter locale. */ -PHP_FUNCTION( datefmt_get_locale ) -{ - char *loc; - zend_long loc_type =ULOC_ACTUAL_LOCALE; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O|l", - &object, IntlDateFormatter_ce_ptr,&loc_type) == FAILURE ) - { - - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - loc = (char *)udat_getLocaleByType(DATE_FORMAT_OBJECT(dfo), loc_type,&INTL_DATA_ERROR_CODE(dfo)); - INTL_METHOD_CHECK_STATUS(dfo, "Error getting locale"); - RETURN_STRING(loc); -} -/* }}} */ - -/* {{{ Get formatter isLenient. */ -PHP_FUNCTION( datefmt_is_lenient ) -{ - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - RETVAL_BOOL(udat_isLenient(DATE_FORMAT_OBJECT(dfo))); -} -/* }}} */ - -/* {{{ Set formatter lenient. */ -PHP_FUNCTION( datefmt_set_lenient ) -{ - bool isLenient = false; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ob", - &object, IntlDateFormatter_ce_ptr,&isLenient ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - udat_setLenient(DATE_FORMAT_OBJECT(dfo), (UBool)isLenient ); -} -/* }}} */ diff --git a/ext/intl/dateformat/dateformat_attr.cpp b/ext/intl/dateformat/dateformat_attr.cpp new file mode 100644 index 000000000000..170a85889d53 --- /dev/null +++ b/ext/intl/dateformat/dateformat_attr.cpp @@ -0,0 +1,205 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + +extern "C" { +#include "../php_intl.h" +#include "../intl_convert.h" +} +#include "dateformat_class.h" +#include "dateformat_class.h" + +#include +#include + +/* {{{ Get formatter datetype. */ +U_CFUNC PHP_FUNCTION( datefmt_get_datetype ) +{ + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter datetype." ); + + RETURN_LONG(dfo->date_type ); +} +/* }}} */ + +/* {{{ Get formatter timetype. */ +U_CFUNC PHP_FUNCTION( datefmt_get_timetype ) +{ + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter timetype." ); + + RETURN_LONG(dfo->time_type ); +} +/* }}} */ + +/* {{{ Get formatter pattern. */ +U_CFUNC PHP_FUNCTION( datefmt_get_pattern ) +{ + UChar value_buf[64]; + uint32_t length = USIZE( value_buf ); + UChar* value = value_buf; + bool is_pattern_localized = false; + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + length = udat_toPattern(DATE_FORMAT_OBJECT(dfo), is_pattern_localized, value, length, &INTL_DATA_ERROR_CODE(dfo)); + if(INTL_DATA_ERROR_CODE(dfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { + ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ + INTL_DATA_ERROR_CODE(dfo) = U_ZERO_ERROR; + value = eumalloc(length); + length = udat_toPattern(DATE_FORMAT_OBJECT(dfo), is_pattern_localized, value, length, &INTL_DATA_ERROR_CODE(dfo) ); + if(U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { + efree(value); + value = value_buf; + } + } + INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter pattern" ); + + INTL_METHOD_RETVAL_UTF8( dfo, value, length, ( value != value_buf ) ); +} +/* }}} */ + +/* {{{ Set formatter pattern. */ +U_CFUNC PHP_FUNCTION( datefmt_set_pattern ) +{ + char* value = nullptr; + size_t value_len = 0; + int32_t slength = 0; + UChar* svalue = nullptr; + bool is_pattern_localized = false; + + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", + &object, IntlDateFormatter_ce_ptr, &value, &value_len ) == FAILURE ) + { + RETURN_THROWS(); + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + /* Convert given pattern to UTF-16. */ + intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(dfo)); + INTL_METHOD_CHECK_STATUS(dfo, "Error converting pattern to UTF-16" ); + + udat_applyPattern(DATE_FORMAT_OBJECT(dfo), (UBool)is_pattern_localized, svalue, slength); + + if (svalue) { + efree(svalue); + } + INTL_METHOD_CHECK_STATUS(dfo, "Error setting symbol value"); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get formatter locale. */ +U_CFUNC PHP_FUNCTION( datefmt_get_locale ) +{ + const char *loc; + zend_long loc_type =ULOC_ACTUAL_LOCALE; + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O|l", + &object, IntlDateFormatter_ce_ptr,&loc_type) == FAILURE ) + { + + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + loc = udat_getLocaleByType(DATE_FORMAT_OBJECT(dfo), static_cast(loc_type),&INTL_DATA_ERROR_CODE(dfo)); + INTL_METHOD_CHECK_STATUS(dfo, "Error getting locale"); + RETURN_STRING(loc); +} +/* }}} */ + +/* {{{ Get formatter isLenient. */ +U_CFUNC PHP_FUNCTION( datefmt_is_lenient ) +{ + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, IntlDateFormatter_ce_ptr ) == FAILURE ) + { + + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + RETVAL_BOOL(udat_isLenient(DATE_FORMAT_OBJECT(dfo))); +} +/* }}} */ + +/* {{{ Set formatter lenient. */ +U_CFUNC PHP_FUNCTION( datefmt_set_lenient ) +{ + bool isLenient = false; + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ob", + &object, IntlDateFormatter_ce_ptr,&isLenient ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + udat_setLenient(DATE_FORMAT_OBJECT(dfo), (UBool)isLenient ); +} +/* }}} */ diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp index 1fb5b514bc6a..1c8fb88a3d51 100644 --- a/ext/intl/dateformat/dateformat_attrcpp.cpp +++ b/ext/intl/dateformat/dateformat_attrcpp.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -71,8 +71,7 @@ U_CFUNC PHP_FUNCTION(datefmt_get_timezone) TimeZone *tz_clone = tz.clone(); if (UNEXPECTED(tz_clone == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_get_timezone: Out of memory when cloning time zone", - 0); + "Out of memory when cloning time zone"); RETURN_FALSE; } @@ -82,21 +81,46 @@ U_CFUNC PHP_FUNCTION(datefmt_get_timezone) /* {{{ Set formatter's timezone. */ U_CFUNC PHP_FUNCTION(datefmt_set_timezone) { - zval *timezone_zv; - TimeZone *timezone; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; DATE_FORMAT_METHOD_INIT_VARS; - if ( zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), - "Oz", &object, IntlDateFormatter_ce_ptr, &timezone_zv) == FAILURE) { - RETURN_THROWS(); + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(object, IntlDateFormatter_ce_ptr) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + TimeZone *timezone = timezone_process_timezone_argument( + timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo), 2); + if (timezone == nullptr) { + RETURN_FALSE; } + fetch_datefmt(dfo)->adoptTimeZone(timezone); + + RETURN_TRUE; +} + +U_CFUNC PHP_METHOD(IntlDateFormatter, setTimeZone) +{ + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; + + DATE_FORMAT_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) + ZEND_PARSE_PARAMETERS_END(); + + object = ZEND_THIS; DATE_FORMAT_METHOD_FETCH_OBJECT; - timezone = timezone_process_timezone_argument(timezone_zv, - INTL_DATA_ERROR_P(dfo), "datefmt_set_timezone"); - if (timezone == NULL) { + TimeZone *timezone = timezone_process_timezone_argument( + timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo), 1); + if (timezone == nullptr) { RETURN_FALSE; } @@ -146,8 +170,7 @@ U_CFUNC PHP_FUNCTION(datefmt_get_calendar_object) Calendar *cal_clone = cal->clone(); if (UNEXPECTED(cal_clone == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_get_calendar_object: Out of memory when cloning " - "calendar", 0); + "Out of memory when cloning calendar"); RETURN_FALSE; } @@ -187,7 +210,7 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) // must store the requested locale on object creation if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, - "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type, cal_owned) == FAILURE + INTL_DATA_ERROR_P(dfo), cal, cal_type, cal_owned) == FAILURE ) { RETURN_FALSE; } @@ -197,8 +220,7 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) TimeZone *old_timezone = fetch_datefmt(dfo)->getTimeZone().clone(); if (UNEXPECTED(old_timezone == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_set_calendar: Out of memory when cloning calendar", - 0); + "Out of memory when cloning calendar"); delete cal; RETURN_FALSE; } @@ -207,8 +229,7 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) cal = cal->clone(); if (UNEXPECTED(cal == NULL)) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, - "datefmt_set_calendar: Out of memory when cloning calendar", - 0); + "Out of memory when cloning calendar"); RETURN_FALSE; } } diff --git a/ext/intl/dateformat/dateformat_class.c b/ext/intl/dateformat/dateformat_class.c deleted file mode 100644 index 15bf5bf23ce5..000000000000 --- a/ext/intl/dateformat/dateformat_class.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ -#include - -#include "dateformat_class.h" -#include "php_intl.h" -#include "dateformat_data.h" -#include "dateformat.h" -#include "dateformat_arginfo.h" - -#include - -zend_class_entry *IntlDateFormatter_ce_ptr = NULL; -static zend_object_handlers IntlDateFormatter_handlers; - -/* - * Auxiliary functions needed by objects of 'IntlDateFormatter' class - */ - -/* {{{ IntlDateFormatter_objects_free */ -void IntlDateFormatter_object_free( zend_object *object ) -{ - IntlDateFormatter_object* dfo = php_intl_dateformatter_fetch_object(object); - - zend_object_std_dtor( &dfo->zo ); - - if (dfo->requested_locale) { - efree( dfo->requested_locale ); - } - - dateformat_data_free( &dfo->datef_data ); -} -/* }}} */ - -/* {{{ IntlDateFormatter_object_create */ -zend_object *IntlDateFormatter_object_create(zend_class_entry *ce) -{ - IntlDateFormatter_object* intern; - - intern = zend_object_alloc(sizeof(IntlDateFormatter_object), ce); - dateformat_data_init( &intern->datef_data ); - zend_object_std_init( &intern->zo, ce ); - object_properties_init(&intern->zo, ce); - intern->date_type = 0; - intern->time_type = 0; - intern->calendar = -1; - intern->requested_locale = NULL; - - return &intern->zo; -} -/* }}} */ - -/* {{{ IntlDateFormatter_object_clone */ -zend_object *IntlDateFormatter_object_clone(zend_object *object) -{ - IntlDateFormatter_object *dfo = php_intl_dateformatter_fetch_object(object); - zend_object *new_obj = IntlDateFormatter_ce_ptr->create_object(object->ce); - IntlDateFormatter_object *new_dfo = php_intl_dateformatter_fetch_object(new_obj); - - /* clone standard parts */ - zend_objects_clone_members(&new_dfo->zo, &dfo->zo); - - /* clone formatter object */ - if (DATE_FORMAT_OBJECT(dfo) != NULL) { - UErrorCode error = U_ZERO_ERROR; - DATE_FORMAT_OBJECT(new_dfo) = udat_clone(DATE_FORMAT_OBJECT(dfo), &error); - - if (U_FAILURE(error)) { - zend_throw_error(NULL, "Failed to clone IntlDateFormatter"); - } - } else { - zend_throw_error(NULL, "Cannot clone uninitialized IntlDateFormatter"); - } - return new_obj; -} -/* }}} */ - -/* - * 'IntlDateFormatter' class registration structures & functions - */ - -/* {{{ dateformat_register_class - * Initialize 'IntlDateFormatter' class - */ -void dateformat_register_IntlDateFormatter_class( void ) -{ - /* Create and register 'IntlDateFormatter' class. */ - IntlDateFormatter_ce_ptr = register_class_IntlDateFormatter(); - IntlDateFormatter_ce_ptr->create_object = IntlDateFormatter_object_create; - IntlDateFormatter_ce_ptr->default_object_handlers = &IntlDateFormatter_handlers; - - memcpy(&IntlDateFormatter_handlers, &std_object_handlers, - sizeof IntlDateFormatter_handlers); - IntlDateFormatter_handlers.offset = XtOffsetOf(IntlDateFormatter_object, zo); - IntlDateFormatter_handlers.clone_obj = IntlDateFormatter_object_clone; - IntlDateFormatter_handlers.free_obj = IntlDateFormatter_object_free; -} -/* }}} */ diff --git a/ext/intl/dateformat/dateformat_class.cpp b/ext/intl/dateformat/dateformat_class.cpp new file mode 100644 index 000000000000..e9869612b873 --- /dev/null +++ b/ext/intl/dateformat/dateformat_class.cpp @@ -0,0 +1,111 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ +#include + +extern "C" { +#include "dateformat_class.h" +#include "php_intl.h" +#include "dateformat_data.h" +#include "dateformat.h" +#include "dateformat_arginfo.h" +} + +#include + +zend_class_entry *IntlDateFormatter_ce_ptr = NULL; +static zend_object_handlers IntlDateFormatter_handlers; + +/* + * Auxiliary functions needed by objects of 'IntlDateFormatter' class + */ + +/* {{{ IntlDateFormatter_objects_free */ +void IntlDateFormatter_object_free( zend_object *object ) +{ + IntlDateFormatter_object* dfo = php_intl_dateformatter_fetch_object(object); + + zend_object_std_dtor( &dfo->zo ); + + if (dfo->requested_locale) { + efree( dfo->requested_locale ); + } + + dateformat_data_free( &dfo->datef_data ); +} +/* }}} */ + +/* {{{ IntlDateFormatter_object_create */ +zend_object *IntlDateFormatter_object_create(zend_class_entry *ce) +{ + IntlDateFormatter_object* intern; + + intern = reinterpret_cast(zend_object_alloc(sizeof(IntlDateFormatter_object), ce)); + dateformat_data_init( &intern->datef_data ); + zend_object_std_init( &intern->zo, ce ); + object_properties_init(&intern->zo, ce); + intern->date_type = 0; + intern->time_type = 0; + intern->calendar = -1; + intern->requested_locale = NULL; + + return &intern->zo; +} +/* }}} */ + +/* {{{ IntlDateFormatter_object_clone */ +zend_object *IntlDateFormatter_object_clone(zend_object *object) +{ + const IntlDateFormatter_object *dfo = php_intl_dateformatter_fetch_object(object); + zend_object *new_obj = IntlDateFormatter_ce_ptr->create_object(object->ce); + IntlDateFormatter_object *new_dfo = php_intl_dateformatter_fetch_object(new_obj); + + /* clone standard parts */ + zend_objects_clone_members(&new_dfo->zo, &dfo->zo); + + /* clone formatter object */ + if (DATE_FORMAT_OBJECT(dfo) != NULL) { + UErrorCode error = U_ZERO_ERROR; + DATE_FORMAT_OBJECT(new_dfo) = udat_clone(DATE_FORMAT_OBJECT(dfo), &error); + + if (U_FAILURE(error)) { + zend_throw_error(NULL, "Failed to clone IntlDateFormatter"); + } + } else { + zend_throw_error(NULL, "Cannot clone uninitialized IntlDateFormatter"); + } + return new_obj; +} +/* }}} */ + +/* + * 'IntlDateFormatter' class registration structures & functions + */ + +/* {{{ dateformat_register_class + * Initialize 'IntlDateFormatter' class + */ +void dateformat_register_IntlDateFormatter_class( void ) +{ + /* Create and register 'IntlDateFormatter' class. */ + IntlDateFormatter_ce_ptr = register_class_IntlDateFormatter(); + IntlDateFormatter_ce_ptr->create_object = IntlDateFormatter_object_create; + IntlDateFormatter_ce_ptr->default_object_handlers = &IntlDateFormatter_handlers; + + memcpy(&IntlDateFormatter_handlers, &std_object_handlers, + sizeof IntlDateFormatter_handlers); + IntlDateFormatter_handlers.offset = offsetof(IntlDateFormatter_object, zo); + IntlDateFormatter_handlers.clone_obj = IntlDateFormatter_object_clone; + IntlDateFormatter_handlers.free_obj = IntlDateFormatter_object_free; +} +/* }}} */ diff --git a/ext/intl/dateformat/dateformat_class.h b/ext/intl/dateformat/dateformat_class.h index 18afb55023b4..dc94907e9960 100644 --- a/ext/intl/dateformat/dateformat_class.h +++ b/ext/intl/dateformat/dateformat_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -16,9 +16,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif #include "intl_common.h" #include "intl_error.h" #include "intl_data.h" +#ifdef __cplusplus +} +#endif #include "dateformat_data.h" typedef struct { @@ -31,12 +37,18 @@ typedef struct { } IntlDateFormatter_object; static inline IntlDateFormatter_object *php_intl_dateformatter_fetch_object(zend_object *obj) { - return (IntlDateFormatter_object *)((char*)(obj) - XtOffsetOf(IntlDateFormatter_object, zo)); + return ZEND_CONTAINER_OF(obj, IntlDateFormatter_object, zo); } #define Z_INTL_DATEFORMATTER_P(zv) php_intl_dateformatter_fetch_object(Z_OBJ_P(zv)) +#ifdef __cplusplus +extern "C" { +#endif void dateformat_register_IntlDateFormatter_class( void ); extern zend_class_entry *IntlDateFormatter_ce_ptr; +#ifdef __cplusplus +} +#endif /* Auxiliary macros */ diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp index d071c7d9d2ed..df98c7178fc6 100644 --- a/ext/intl/dateformat/dateformat_create.cpp +++ b/ext/intl/dateformat/dateformat_create.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | | Gustavo Lopes | @@ -22,6 +22,7 @@ extern "C" { #include #include +#include #include "php_intl.h" #include "dateformat_create.h" @@ -45,7 +46,7 @@ extern "C" { UDAT_PATTERN == (i)) /* {{{ */ -static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) +static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { zval *object; char *locale_str; @@ -59,7 +60,8 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin Calendar *cal = NULL; zend_long calendar_type; bool calendar_owned; - zval *timezone_zv = NULL; + zend_object *timezone_object = nullptr; + zend_string *timezone_string = nullptr; TimeZone *timezone = NULL; bool explicit_tz; char* pattern_str = NULL; @@ -76,33 +78,28 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin Z_PARAM_OPTIONAL Z_PARAM_LONG(date_type) Z_PARAM_LONG(time_type) - Z_PARAM_ZVAL(timezone_zv) + Z_PARAM_OBJ_OR_STR_OR_NULL(timezone_object, timezone_string) Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null) Z_PARAM_STRING_OR_NULL(pattern_str, pattern_str_len) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - } - DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; if (DATE_FORMAT_OBJECT(dfo) != NULL) { - intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: cannot call constructor twice", 0); + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "cannot call constructor twice"); return FAILURE; } if (!INTL_UDATE_FMT_OK(date_type)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: invalid date format style", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid date format style"); return FAILURE; } if (!INTL_UDATE_FMT_OK(time_type)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: invalid time format style", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid time format style"); return FAILURE; } if (date_type == UDAT_PATTERN && time_type != UDAT_PATTERN) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: time format must be UDAT_PATTERN if date format is UDAT_PATTERN", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: time format must be IntlDateFormatter::PATTERN if date format is IntlDateFormatter::PATTERN"); return FAILURE; } @@ -110,28 +107,32 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin if (locale_len == 0) { locale_str = (char *) intl_locale_get_default(); } - locale = Locale::createFromName(locale_str); + + char* canonicalized_locale = canonicalize_locale_string(locale_str); + const char* final_locale = canonicalized_locale ? canonicalized_locale : locale_str; + const char* stored_locale = canonicalized_locale ? canonicalized_locale : locale_str; + + locale = Locale::createFromName(final_locale); /* get*Name accessors being set does not preclude being bogus */ if (locale.isBogus() || ((locale_len == 1 && locale_str[0] != 'C') || (locale_len > 1 && strlen(locale.getISO3Language()) == 0))) { - zend_argument_value_error(1, "\"%s\" is invalid", locale_str); - return FAILURE; + zend_argument_value_error(1, "\"%s\" is invalid", locale_str); + goto error; } /* process calendar */ - if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, "datefmt_create", + if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, INTL_DATA_ERROR_P(dfo), cal, calendar_type, calendar_owned) == FAILURE ) { goto error; } /* process timezone */ - explicit_tz = timezone_zv != NULL && Z_TYPE_P(timezone_zv) != IS_NULL; + explicit_tz = timezone_object != nullptr || timezone_string != nullptr; if (explicit_tz || calendar_owned ) { //we have an explicit time zone or a non-object calendar - timezone = timezone_process_timezone_argument(timezone_zv, - INTL_DATA_ERROR_P(dfo), "datefmt_create"); - if (timezone == NULL) { + timezone = timezone_process_timezone_argument(timezone_object, timezone_string, INTL_DATA_ERROR_P(dfo), 4); + if (timezone == nullptr) { goto error; } } @@ -142,20 +143,20 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo)); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { /* object construction -> only set global error */ - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " - "error converting pattern to UTF-16", 0); + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), + "error converting pattern to UTF-16"); goto error; } } DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type, - (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue, + (UDateFormatStyle)date_type, final_locale, NULL, 0, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); if (pattern_str && pattern_str_len > 0) { udat_applyPattern(DATE_FORMAT_OBJECT(dfo), true, svalue, slength); if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: error applying pattern", 0); + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "error applying pattern"); goto error; } } @@ -173,8 +174,7 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin df->adoptTimeZone(timezone); } } else { - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date " - "formatter creation failed", 0); + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "date formatter creation failed"); goto error; } @@ -182,9 +182,13 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin dfo->date_type = date_type; dfo->time_type = time_type; dfo->calendar = calendar_type; - dfo->requested_locale = estrdup(locale_str); + /* Store the canonicalized locale, or fallback to original if canonicalization failed */ + dfo->requested_locale = estrdup(stored_locale); error: + if (canonicalized_locale) { + efree(canonicalized_locale); + } if (svalue) { efree(svalue); } @@ -203,7 +207,7 @@ static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handlin U_CFUNC PHP_FUNCTION( datefmt_create ) { object_init_ex( return_value, IntlDateFormatter_ce_ptr ); - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -213,21 +217,18 @@ U_CFUNC PHP_FUNCTION( datefmt_create ) /* {{{ IntlDateFormatter object constructor. */ U_CFUNC PHP_METHOD( IntlDateFormatter, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { - if (!EG(exception)) { - zend_string *err = intl_error_get_message(NULL); - zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); - zend_string_release_ex(err, 0); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } /* }}} */ diff --git a/ext/intl/dateformat/dateformat_create.h b/ext/intl/dateformat/dateformat_create.h index a15828e7794c..440f91d261d9 100644 --- a/ext/intl/dateformat/dateformat_create.h +++ b/ext/intl/dateformat/dateformat_create.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/dateformat/dateformat_data.c b/ext/intl/dateformat/dateformat_data.c deleted file mode 100644 index 9c12af6fb605..000000000000 --- a/ext/intl/dateformat/dateformat_data.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "dateformat_data.h" - -/* {{{ void dateformat_data_init( dateformat_data* datef_data ) - * Initialize internals of dateformat_data. - */ -void dateformat_data_init( dateformat_data* datef_data ) -{ - if( !datef_data ) - return; - - datef_data->udatf = NULL; - intl_error_reset( &datef_data->error ); -} -/* }}} */ - -/* {{{ void dateformat_data_free( dateformat_data* datef_data ) - * Clean up memory allocated for dateformat_data - */ -void dateformat_data_free( dateformat_data* datef_data ) -{ - if( !datef_data ) - return; - - if( datef_data->udatf ) - udat_close( datef_data->udatf ); - - datef_data->udatf = NULL; - intl_error_reset( &datef_data->error ); -} -/* }}} */ - -/* {{{ dateformat_data* dateformat_data_create() - * Allocate memory for dateformat_data and initialize it with default values. - */ -dateformat_data* dateformat_data_create( void ) -{ - dateformat_data* datef_data = ecalloc( 1, sizeof(dateformat_data) ); - - dateformat_data_init( datef_data ); - - return datef_data; -} -/* }}} */ diff --git a/ext/intl/dateformat/dateformat_data.cpp b/ext/intl/dateformat/dateformat_data.cpp new file mode 100644 index 000000000000..6246257732c1 --- /dev/null +++ b/ext/intl/dateformat/dateformat_data.cpp @@ -0,0 +1,60 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "dateformat_data.h" + +/* {{{ void dateformat_data_init( dateformat_data* datef_data ) + * Initialize internals of dateformat_data. + */ +void dateformat_data_init( dateformat_data* datef_data ) +{ + if( !datef_data ) + return; + + datef_data->udatf = nullptr; + intl_error_reset( &datef_data->error ); +} +/* }}} */ + +/* {{{ void dateformat_data_free( dateformat_data* datef_data ) + * Clean up memory allocated for dateformat_data + */ +void dateformat_data_free( dateformat_data* datef_data ) +{ + if( !datef_data ) + return; + + if( datef_data->udatf ) + udat_close( datef_data->udatf ); + + datef_data->udatf = nullptr; + intl_error_reset( &datef_data->error ); +} +/* }}} */ + +/* {{{ dateformat_data* dateformat_data_create() + * Allocate memory for dateformat_data and initialize it with default values. + */ +dateformat_data* dateformat_data_create( void ) +{ + dateformat_data* datef_data = reinterpret_cast(ecalloc( 1, sizeof(dateformat_data) )); + + dateformat_data_init( datef_data ); + + return datef_data; +} +/* }}} */ diff --git a/ext/intl/dateformat/dateformat_data.h b/ext/intl/dateformat/dateformat_data.h index 4007d1344fbb..a8dcef4c500b 100644 --- a/ext/intl/dateformat/dateformat_data.h +++ b/ext/intl/dateformat/dateformat_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -18,7 +18,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif #include "intl_error.h" +#ifdef __cplusplus +} +#endif typedef struct { // error handling @@ -28,8 +34,14 @@ typedef struct { UDateFormat * udatf; } dateformat_data; +#ifdef __cplusplus +extern "C" { +#endif dateformat_data* dateformat_data_create( void ); void dateformat_data_init( dateformat_data* datef_data ); void dateformat_data_free( dateformat_data* datef_data ); +#ifdef __cplusplus +} +#endif #endif // DATE_FORMAT_DATA_H diff --git a/ext/intl/dateformat/dateformat_format.c b/ext/intl/dateformat/dateformat_format.c deleted file mode 100644 index f4ef8a40d645..000000000000 --- a/ext/intl/dateformat/dateformat_format.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "../php_intl.h" - -#include -#include - -#include "../intl_convert.h" -#include "../common/common_date.h" -#include "dateformat.h" -#include "dateformat_class.h" -#include "dateformat_data.h" - -/* {{{ Internal function which calls the udat_format */ -static void internal_format(IntlDateFormatter_object *dfo, UDate timestamp, zval *return_value) -{ - UChar* formatted = NULL; - int32_t resultlengthneeded =0 ; - - resultlengthneeded=udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, NULL, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo)); - if(INTL_DATA_ERROR_CODE(dfo)==U_BUFFER_OVERFLOW_ERROR) - { - INTL_DATA_ERROR_CODE(dfo)=U_ZERO_ERROR; - formatted=(UChar*)emalloc(sizeof(UChar) * resultlengthneeded); - udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, formatted, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo)); - } - - if (formatted && U_FAILURE( INTL_DATA_ERROR_CODE(dfo) ) ) { - efree(formatted); - } - - INTL_METHOD_CHECK_STATUS( dfo, "Date formatting failed" ); - INTL_METHOD_RETVAL_UTF8( dfo, formatted, resultlengthneeded, 1 ); - -} -/* }}} */ - - -/* {{{ Internal function which fetches an element from the passed array for the key_name passed */ -static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo, - HashTable* hash_arr, char* key_name, intl_error *err) -{ - zval *ele_value = NULL; - int32_t result = 0; - char *message; - - if (U_FAILURE(err->code)) { - return result; - } - - if ((ele_value = zend_hash_str_find_deref(hash_arr, key_name, strlen(key_name))) != NULL) { - if(Z_TYPE_P(ele_value) != IS_LONG) { - spprintf(&message, 0, "datefmt_format: parameter array contains " - "a non-integer element for key '%s'", key_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1); - efree(message); - } else { - if (Z_LVAL_P(ele_value) > INT32_MAX || - Z_LVAL_P(ele_value) < INT32_MIN) { - spprintf(&message, 0, "datefmt_format: value " ZEND_LONG_FMT " is out of " - "bounds for a 32-bit integer in key '%s'", - Z_LVAL_P(ele_value), key_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1); - efree(message); - } else { - result = Z_LVAL_P(ele_value); - } - } - } - - return result; -} -/* }}} */ - -/* {{{ Internal function which sets UCalendar from the passed array and retrieves timestamp */ -static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, - HashTable *hash_arr) -{ - int32_t year, - month, - hour, - minute, - second, - mday; - UCalendar *pcal; - UDate result; - intl_error *err = &dfo->datef_data.error; - -#define INTL_GET_ELEM(elem) \ - internal_get_arr_ele(dfo, hash_arr, (elem), err) - - /* Fetch values from the incoming array */ - year = INTL_GET_ELEM(CALENDAR_YEAR) + 1900; /* tm_year is years since 1900 */ - /* Month in ICU and PHP starts from January =0 */ - month = INTL_GET_ELEM(CALENDAR_MON); - hour = INTL_GET_ELEM(CALENDAR_HOUR); - minute = INTL_GET_ELEM(CALENDAR_MIN); - second = INTL_GET_ELEM(CALENDAR_SEC); - /* For the ucal_setDateTime() function, this is the 'date' value */ - mday = INTL_GET_ELEM(CALENDAR_MDAY); - -#undef INTL_GET_ELEM - - pcal = ucal_clone(udat_getCalendar(DATE_FORMAT_OBJECT(dfo)), - &INTL_DATA_ERROR_CODE(dfo)); - - if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) { - intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "datefmt_format: " - "error cloning calendar", 0); - return 0; - } - - /* set the incoming values for the calendar */ - ucal_setDateTime(pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo)); - /* actually, ucal_setDateTime cannot fail */ - - /* Fetch the timestamp from the UCalendar */ - result = ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo)); - ucal_close(pcal); - return result; -} - - -/* {{{ Format the time value as a string. */ -PHP_FUNCTION(datefmt_format) -{ - UDate timestamp = 0; - HashTable *hash_arr = NULL; - zval *zarg = NULL; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", - &object, IntlDateFormatter_ce_ptr, &zarg) == FAILURE) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable " - "to parse input params", 0 ); - RETURN_THROWS(); - } - - DATE_FORMAT_METHOD_FETCH_OBJECT; - - if (Z_TYPE_P(zarg) == IS_ARRAY) { - hash_arr = Z_ARRVAL_P(zarg); - if (!hash_arr || zend_hash_num_elements(hash_arr) == 0) { - RETURN_FALSE; - } - - timestamp = internal_get_timestamp(dfo, hash_arr); - INTL_METHOD_CHECK_STATUS(dfo, "datefmt_format: date formatting failed") - } else { - timestamp = intl_zval_to_millis(zarg, INTL_DATA_ERROR_P(dfo), - "datefmt_format"); - if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - RETURN_FALSE; - } - } - - internal_format( dfo, timestamp, return_value); -} - -/* }}} */ diff --git a/ext/intl/dateformat/dateformat_format.cpp b/ext/intl/dateformat/dateformat_format.cpp new file mode 100644 index 000000000000..8b2a28d5c4d2 --- /dev/null +++ b/ext/intl/dateformat/dateformat_format.cpp @@ -0,0 +1,176 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +extern "C" { +#include "../php_intl.h" +#include "../intl_convert.h" +} + +#include "../common/common_date.h" +#include "dateformat.h" +#include "dateformat_class.h" +#include "dateformat_data.h" + +/* {{{ Internal function which calls the udat_format */ +static void internal_format(IntlDateFormatter_object *dfo, UDate timestamp, zval *return_value) +{ + UChar* formatted = NULL; + int32_t resultlengthneeded =0 ; + + resultlengthneeded=udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, NULL, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo)); + if(INTL_DATA_ERROR_CODE(dfo)==U_BUFFER_OVERFLOW_ERROR) + { + INTL_DATA_ERROR_CODE(dfo)=U_ZERO_ERROR; + formatted=(UChar*)emalloc(sizeof(UChar) * resultlengthneeded); + udat_format( DATE_FORMAT_OBJECT(dfo), timestamp, formatted, resultlengthneeded, NULL, &INTL_DATA_ERROR_CODE(dfo)); + } + + if (formatted && U_FAILURE( INTL_DATA_ERROR_CODE(dfo) ) ) { + efree(formatted); + } + + INTL_METHOD_CHECK_STATUS( dfo, "Date formatting failed" ); + INTL_METHOD_RETVAL_UTF8( dfo, formatted, resultlengthneeded, 1 ); + +} +/* }}} */ + + +/* {{{ Internal function which fetches an element from the passed array for the key_name passed */ +static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo, + HashTable* hash_arr, char* key_name, intl_error *err) +{ + zval *ele_value = NULL; + int32_t result = 0; + char *message; + + if (U_FAILURE(err->code)) { + return result; + } + + if ((ele_value = zend_hash_str_find_deref(hash_arr, key_name, strlen(key_name))) != NULL) { + if(Z_TYPE_P(ele_value) != IS_LONG) { + spprintf(&message, 0, "parameter array contains " + "a non-integer element for key '%s'", key_name); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message); + efree(message); + } else { + if (Z_LVAL_P(ele_value) > INT32_MAX || + Z_LVAL_P(ele_value) < INT32_MIN) { + spprintf(&message, 0, "value " ZEND_LONG_FMT " is out of " + "bounds for a 32-bit integer in key '%s'", + Z_LVAL_P(ele_value), key_name); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message); + efree(message); + } else { + result = Z_LVAL_P(ele_value); + } + } + } + + return result; +} +/* }}} */ + +/* {{{ Internal function which sets UCalendar from the passed array and retrieves timestamp */ +static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, + HashTable *hash_arr) +{ + int32_t year, + month, + hour, + minute, + second, + mday; + UCalendar *pcal; + UDate result; + intl_error *err = &dfo->datef_data.error; + +#define INTL_GET_ELEM(elem) \ + internal_get_arr_ele(dfo, hash_arr, (elem), err) + + /* Fetch values from the incoming array */ + year = INTL_GET_ELEM(CALENDAR_YEAR) + 1900; /* tm_year is years since 1900 */ + /* Month in ICU and PHP starts from January =0 */ + month = INTL_GET_ELEM(CALENDAR_MON); + hour = INTL_GET_ELEM(CALENDAR_HOUR); + minute = INTL_GET_ELEM(CALENDAR_MIN); + second = INTL_GET_ELEM(CALENDAR_SEC); + /* For the ucal_setDateTime() function, this is the 'date' value */ + mday = INTL_GET_ELEM(CALENDAR_MDAY); + +#undef INTL_GET_ELEM + + pcal = ucal_clone(udat_getCalendar(DATE_FORMAT_OBJECT(dfo)), + &INTL_DATA_ERROR_CODE(dfo)); + + if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) { + intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "error cloning calendar"); + return 0; + } + + /* set the incoming values for the calendar */ + ucal_setDateTime(pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo)); + /* actually, ucal_setDateTime cannot fail */ + + /* Fetch the timestamp from the UCalendar */ + result = ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo)); + ucal_close(pcal); + return result; +} + + +/* {{{ Format the time value as a string. */ +U_CFUNC PHP_FUNCTION(datefmt_format) +{ + UDate timestamp = 0; + HashTable *hash_arr = NULL; + zval *zarg = NULL; + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", + &object, IntlDateFormatter_ce_ptr, &zarg) == FAILURE) { + RETURN_THROWS(); + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + if (Z_TYPE_P(zarg) == IS_ARRAY) { + hash_arr = Z_ARRVAL_P(zarg); + if (!hash_arr || zend_hash_num_elements(hash_arr) == 0) { + RETURN_FALSE; + } + + timestamp = internal_get_timestamp(dfo, hash_arr); + INTL_METHOD_CHECK_STATUS(dfo, "date formatting failed") + } else { + timestamp = intl_zval_to_millis(zarg, INTL_DATA_ERROR_P(dfo)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { + RETURN_FALSE; + } + } + + internal_format( dfo, timestamp, return_value); +} + +/* }}} */ diff --git a/ext/intl/dateformat/dateformat_format_object.cpp b/ext/intl/dateformat/dateformat_format_object.cpp index 81490c62fd5e..5b0950094d51 100644 --- a/ext/intl/dateformat/dateformat_format_object.cpp +++ b/ext/intl/dateformat/dateformat_format_object.cpp @@ -1,18 +1,19 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ */ #include "../intl_cppshims.h" +#include #include #include @@ -70,10 +71,10 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) size_t locale_len; bool pattern = false; UDate date; - TimeZone *timeZone = NULL; + std::unique_ptr timeZone; UErrorCode status = U_ZERO_ERROR; - DateFormat *df = NULL; - Calendar *cal = NULL; + std::unique_ptr df; + std::unique_ptr cal; DateFormat::EStyle dateStyle = DateFormat::kDefault, timeStyle = DateFormat::kDefault; @@ -94,8 +95,8 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) HashTable *ht = Z_ARRVAL_P(format); if (zend_hash_num_elements(ht) != 2) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad format; if array, it must have " - "two elements", 0); + "bad format; if array, it must have " + "two elements"); RETURN_FALSE; } @@ -105,13 +106,13 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) if (!valid_format(z)) { if (idx == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad format; the date format (first " - "element of the array) is not valid", 0); + "bad format; the date format (first " + "element of the array) is not valid"); } else { ZEND_ASSERT(idx == 1 && "We checked that there are two elements above"); intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad format; the time format (second " - "element of the array) is not valid", 0); + "bad format; the time format (second " + "element of the array) is not valid"); } RETURN_FALSE; } @@ -127,8 +128,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) } else if (Z_TYPE_P(format) == IS_LONG) { if (!valid_format(format)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: the date/time format type is invalid", - 0); + "the date/time format type is invalid"); RETURN_FALSE; } dateStyle = timeStyle = (DateFormat::EStyle)Z_LVAL_P(format); @@ -138,7 +138,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) } if (Z_STRLEN_P(format) == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: the format is empty", 0); + "the format is empty"); RETURN_FALSE; } pattern = true; @@ -154,72 +154,58 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) Calendar *obj_cal = calendar_fetch_native_calendar(object); if (obj_cal == NULL) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_format_object: bad IntlCalendar instance: " - "not initialized properly", 0); + "bad IntlCalendar instance: not initialized properly"); RETURN_FALSE; } - timeZone = obj_cal->getTimeZone().clone(); + timeZone = std::unique_ptr(obj_cal->getTimeZone().clone()); date = obj_cal->getTime(status); if (U_FAILURE(status)) { intl_error_set(NULL, status, - "datefmt_format_object: error obtaining instant from " - "IntlCalendar", 0); - RETVAL_FALSE; - goto cleanup; + "error obtaining instant from IntlCalendar"); + RETURN_FALSE; } - cal = obj_cal->clone(); + cal = std::unique_ptr(obj_cal->clone()); } else if (instanceof_function(instance_ce, php_date_get_interface_ce())) { - if (intl_datetime_decompose(object, &date, &timeZone, NULL, - "datefmt_format_object") == FAILURE) { + TimeZone *tz; + if (intl_datetime_decompose(object, &date, &tz, NULL) == FAILURE) { RETURN_FALSE; } - cal = new GregorianCalendar(Locale::createFromName(locale_str), status); + timeZone = std::unique_ptr(tz); + cal = std::unique_ptr(new GregorianCalendar(Locale::createFromName(locale_str), status)); if (U_FAILURE(status)) { - intl_error_set(NULL, status, - "datefmt_format_object: could not create GregorianCalendar", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "could not create GregorianCalendar"); + RETURN_FALSE; } } else { - intl_error_set(NULL, status, "datefmt_format_object: the passed object " - "must be an instance of either IntlCalendar or DateTimeInterface", - 0); + intl_error_set(NULL, status, "the passed object must be an instance " + "of either IntlCalendar or DateTimeInterface"); RETURN_FALSE; } if (pattern) { StringPiece sp(Z_STRVAL_P(format)); - df = new SimpleDateFormat( + df = std::unique_ptr(new SimpleDateFormat( UnicodeString::fromUTF8(sp), Locale::createFromName(locale_str), - status); + status)); if (U_FAILURE(status)) { - intl_error_set(NULL, status, - "datefmt_format_object: could not create SimpleDateFormat", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "could not create SimpleDateFormat"); + RETURN_FALSE; } } else { - df = DateFormat::createDateTimeInstance(dateStyle, timeStyle, - Locale::createFromName(locale_str)); + df = std::unique_ptr(DateFormat::createDateTimeInstance(dateStyle, timeStyle, + Locale::createFromName(locale_str))); if (df == NULL) { /* according to ICU sources, this should never happen */ - intl_error_set(NULL, status, - "datefmt_format_object: could not create DateFormat", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "could not create DateFormat"); + RETURN_FALSE; } } //must be in this order (or have the cal adopt the tz) - df->adoptCalendar(cal); - cal = NULL; - df->adoptTimeZone(timeZone); - timeZone = NULL; + df->adoptCalendar(cal.release()); + df->adoptTimeZone(timeZone.release()); { zend_string *u8str; @@ -228,18 +214,9 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) u8str = intl_charFromString(result, &status); if (!u8str) { - intl_error_set(NULL, status, - "datefmt_format_object: error converting result to UTF-8", - 0); - RETVAL_FALSE; - goto cleanup; + intl_error_set(NULL, status, "error converting result to UTF-8"); + RETURN_FALSE; } RETVAL_STR(u8str); } - - -cleanup: - delete df; - delete timeZone; - delete cal; } diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp index 2842c520a309..747105bb4f90 100644 --- a/ext/intl/dateformat/dateformat_helpers.cpp +++ b/ext/intl/dateformat/dateformat_helpers.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -28,11 +28,10 @@ extern "C" { using icu::GregorianCalendar; -int datefmt_process_calendar_arg( +zend_result datefmt_process_calendar_arg( zend_object *calendar_obj, zend_long calendar_long, bool calendar_is_null, Locale const& locale, - const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned + intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned ) { - char *msg; UErrorCode status = UErrorCode(); if (calendar_is_null) { @@ -45,13 +44,11 @@ int datefmt_process_calendar_arg( } else if (!calendar_obj) { zend_long v = calendar_long; if (v != (zend_long)UCAL_TRADITIONAL && v != (zend_long)UCAL_GREGORIAN) { - spprintf(&msg, 0, "%s: Invalid value for calendar type; it must be " - "one of IntlDateFormatter::TRADITIONAL (locale's default " - "calendar) or IntlDateFormatter::GREGORIAN. " - "Alternatively, it can be an IntlCalendar object", - func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, + "Invalid value for calendar type; it must be one of " + "IntlDateFormatter::TRADITIONAL (locale's default calendar) or" + " IntlDateFormatter::GREGORIAN. Alternatively, it can be an " + "IntlCalendar object"); return FAILURE; } else if (v == (zend_long)UCAL_TRADITIONAL) { cal = Calendar::createInstance(locale, status); @@ -65,10 +62,7 @@ int datefmt_process_calendar_arg( } else if (calendar_obj) { cal = calendar_fetch_native_calendar(calendar_obj); if (cal == NULL) { - spprintf(&msg, 0, "%s: Found unconstructed IntlCalendar object", - func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, "Found unconstructed IntlCalendar object"); return FAILURE; } calendar_owned = false; @@ -76,10 +70,8 @@ int datefmt_process_calendar_arg( cal_int_type = -1; } else { - spprintf(&msg, 0, "%s: Invalid calendar argument; should be an integer " - "or an IntlCalendar instance", func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, + "Invalid calendar argument; should be an integer or an IntlCalendar instance"); return FAILURE; } @@ -87,9 +79,7 @@ int datefmt_process_calendar_arg( status = U_MEMORY_ALLOCATION_ERROR; } if (U_FAILURE(status)) { - spprintf(&msg, 0, "%s: Failure instantiating calendar", func_name); - intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1); - efree(msg); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, "Failure instantiating calendar"); return FAILURE; } diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h index 4140eb730a2c..f71e7f368706 100644 --- a/ext/intl/dateformat/dateformat_helpers.h +++ b/ext/intl/dateformat/dateformat_helpers.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -30,9 +30,9 @@ using icu::Locale; using icu::Calendar; using icu::DateFormat; -int datefmt_process_calendar_arg( +zend_result datefmt_process_calendar_arg( zend_object *calendar_obj, zend_long calendar_long, bool calendar_is_null, Locale const& locale, - const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned + intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned ); #endif /* DATEFORMAT_HELPERS_H */ diff --git a/ext/intl/dateformat/dateformat_parse.c b/ext/intl/dateformat/dateformat_parse.c deleted file mode 100644 index 2bdde08bcace..000000000000 --- a/ext/intl/dateformat/dateformat_parse.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "php_intl.h" -#include "intl_convert.h" -#include "dateformat.h" -#include "dateformat_class.h" -#include "dateformat_data.h" - -/* {{{ - * Internal function which calls the udat_parse - * param int store_error acts like a boolean - * if set to 1 - store any error encountered in the parameter parse_error - * if set to 0 - no need to store any error encountered in the parameter parse_error -*/ -static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, bool update_calendar, zval *return_value) -{ - double result = 0; - UDate timestamp =0; - UChar* text_utf16 = NULL; - int32_t text_utf16_len = 0; - - /* Convert timezone to UTF-16. */ - intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo)); - INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); - - if (UNEXPECTED(update_calendar)) { - UCalendar *parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo)); - udat_parseCalendar(DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); - if (text_utf16) { - efree(text_utf16); - } - INTL_METHOD_CHECK_STATUS( dfo, "Calendar parsing failed" ); - timestamp = ucal_getMillis( parsed_calendar, &INTL_DATA_ERROR_CODE(dfo)); - } else { - timestamp = udat_parse(DATE_FORMAT_OBJECT(dfo), text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); - if (text_utf16) { - efree(text_utf16); - } - } - - INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" ); - /* Since return is in sec. */ - result = (double)timestamp / U_MILLIS_PER_SECOND; - if (result > (double)LONG_MAX || result < (double)LONG_MIN) { - ZVAL_DOUBLE(return_value, result<0?ceil(result):floor(result)); - } else { - ZVAL_LONG(return_value, (zend_long)result); - } -} -/* }}} */ - -static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, const UCalendar *parsed_calendar, zend_long calendar_field, char* key_name) -{ - zend_long calendar_field_val = ucal_get( parsed_calendar, calendar_field, &INTL_DATA_ERROR_CODE(dfo)); - INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : could not get a field from calendar" ); - - if( strcmp(key_name, CALENDAR_YEAR )==0 ){ - /* since tm_year is years from 1900 */ - add_assoc_long( return_value, key_name,( calendar_field_val-1900) ); - }else if( strcmp(key_name, CALENDAR_WDAY )==0 ){ - /* since tm_wday starts from 0 whereas ICU WDAY start from 1 */ - add_assoc_long( return_value, key_name,( calendar_field_val-1) ); - }else{ - add_assoc_long( return_value, key_name, calendar_field_val ); - } -} - -/* {{{ Internal function which calls the udat_parseCalendar */ -static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, zval *return_value) -{ - UCalendar *parsed_calendar = NULL; - UChar* text_utf16 = NULL; - int32_t text_utf16_len = 0; - zend_long isInDST = 0; - - /* Convert timezone to UTF-16. */ - intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo)); - INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); - - parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo)); - udat_parseCalendar( DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); - - if (text_utf16) { - efree(text_utf16); - } - - INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" ); - - - array_init( return_value ); - /* Add entries from various fields of the obtained parsed_calendar */ - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_SECOND, CALENDAR_SEC); - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MINUTE, CALENDAR_MIN); - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_HOUR_OF_DAY, CALENDAR_HOUR); - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_YEAR, CALENDAR_YEAR); - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_MONTH, CALENDAR_MDAY); - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_WEEK, CALENDAR_WDAY); - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_YEAR, CALENDAR_YDAY); - add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MONTH, CALENDAR_MON); - - /* Is in DST? */ - isInDST = ucal_inDaylightTime(parsed_calendar , &INTL_DATA_ERROR_CODE(dfo)); - INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : while checking if currently in DST." ); - add_assoc_long( return_value, CALENDAR_ISDST,isInDST==1); -} -/* }}} */ - - -/* {{{ Parse the string $value starting at parse_pos to a Unix timestamp -int */ -PHP_FUNCTION(datefmt_parse) -{ - char* text_to_parse = NULL; - size_t text_len =0; - zval* z_parse_pos = NULL; - int32_t parse_pos = -1; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|z!", - &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){ - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - if (z_parse_pos) { - zval *z_parse_pos_tmp = z_parse_pos; - ZVAL_DEREF(z_parse_pos_tmp); - zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); - if (ZEND_LONG_INT_OVFL(long_parse_pos)) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0); - RETURN_FALSE; - } - parse_pos = (int32_t)long_parse_pos; - if ((size_t)parse_pos > text_len) { - RETURN_FALSE; - } - } - internal_parse_to_timestamp( dfo, text_to_parse, text_len, z_parse_pos ? &parse_pos : NULL, false, return_value); - if (z_parse_pos) { - ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos); - } -} -/* }}} */ - -PHP_METHOD(IntlDateFormatter, parseToCalendar) -{ - zend_string *text_to_parse = NULL; - zval* z_parse_pos = NULL; - int32_t parse_pos = -1; - - DATE_FORMAT_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR(text_to_parse) - Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(z_parse_pos) - ZEND_PARSE_PARAMETERS_END(); - - object = ZEND_THIS; - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - if (z_parse_pos) { - bool failed; - zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); - if (failed) { - zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); - RETURN_THROWS(); - } - if (ZEND_LONG_INT_OVFL(long_parse_pos)) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0); - RETURN_FALSE; - } - parse_pos = (int32_t)long_parse_pos; - if (parse_pos != -1 && (size_t)parse_pos > ZSTR_LEN(text_to_parse)) { - RETURN_FALSE; - } - } - internal_parse_to_timestamp( dfo, ZSTR_VAL(text_to_parse), ZSTR_LEN(text_to_parse), z_parse_pos ? &parse_pos : NULL, true, return_value); - if (z_parse_pos) { - ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos); - } -} - -/* {{{ Parse the string $value to a localtime array */ -PHP_FUNCTION(datefmt_localtime) -{ - char* text_to_parse = NULL; - size_t text_len =0; - zval* z_parse_pos = NULL; - int32_t parse_pos = -1; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|z!", - &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){ - RETURN_THROWS(); - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - if (z_parse_pos) { - zval *z_parse_pos_tmp = z_parse_pos; - ZVAL_DEREF(z_parse_pos_tmp); - zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); - if (ZEND_LONG_INT_OVFL(long_parse_pos)) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0); - RETURN_FALSE; - } - parse_pos = (int32_t)long_parse_pos; - if((size_t)parse_pos > text_len) { - RETURN_FALSE; - } - } - internal_parse_to_localtime( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value); - if (z_parse_pos) { - ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos); - } -} -/* }}} */ diff --git a/ext/intl/dateformat/dateformat_parse.cpp b/ext/intl/dateformat/dateformat_parse.cpp new file mode 100644 index 000000000000..13cf56ad7d82 --- /dev/null +++ b/ext/intl/dateformat/dateformat_parse.cpp @@ -0,0 +1,250 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +extern "C" { +#include "php_intl.h" +#include "intl_convert.h" +} +#include "dateformat.h" +#include "dateformat_class.h" +#include "dateformat_data.h" + +/* {{{ + * Internal function which calls the udat_parse + * param int store_error acts like a boolean + * if set to 1 - store any error encountered in the parameter parse_error + * if set to 0 - no need to store any error encountered in the parameter parse_error +*/ +static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, bool update_calendar, zval *return_value) +{ + double result = 0; + UDate timestamp =0; + UChar* text_utf16 = NULL; + int32_t text_utf16_len = 0; + + /* Convert timezone to UTF-16. */ + intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo)); + INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); + + if (UNEXPECTED(update_calendar)) { + UCalendar *parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo)); + udat_parseCalendar(DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); + if (text_utf16) { + efree(text_utf16); + } + INTL_METHOD_CHECK_STATUS( dfo, "Calendar parsing failed" ); + timestamp = ucal_getMillis( parsed_calendar, &INTL_DATA_ERROR_CODE(dfo)); + } else { + timestamp = udat_parse(DATE_FORMAT_OBJECT(dfo), text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); + if (text_utf16) { + efree(text_utf16); + } + } + + INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" ); + /* Since return is in sec. */ + result = (double)timestamp / U_MILLIS_PER_SECOND; + if (result > (double)LONG_MAX || result < (double)LONG_MIN) { + ZVAL_DOUBLE(return_value, result<0?ceil(result):floor(result)); + } else { + ZVAL_LONG(return_value, (zend_long)result); + } +} +/* }}} */ + +static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, const UCalendar *parsed_calendar, zend_long calendar_field, char* key_name) +{ + zend_long calendar_field_val = ucal_get( parsed_calendar, static_cast(calendar_field), &INTL_DATA_ERROR_CODE(dfo)); + INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : could not get a field from calendar" ); + + if( strcmp(key_name, CALENDAR_YEAR )==0 ){ + /* since tm_year is years from 1900 */ + add_assoc_long( return_value, key_name,( calendar_field_val-1900) ); + }else if( strcmp(key_name, CALENDAR_WDAY )==0 ){ + /* since tm_wday starts from 0 whereas ICU WDAY start from 1 */ + add_assoc_long( return_value, key_name,( calendar_field_val-1) ); + }else{ + add_assoc_long( return_value, key_name, calendar_field_val ); + } +} + +/* {{{ Internal function which calls the udat_parseCalendar */ +static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, size_t text_len, int32_t *parse_pos, zval *return_value) +{ + UCalendar *parsed_calendar = NULL; + UChar* text_utf16 = NULL; + int32_t text_utf16_len = 0; + zend_long isInDST = 0; + + /* Convert timezone to UTF-16. */ + intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo)); + INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); + + parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo)); + udat_parseCalendar( DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); + + if (text_utf16) { + efree(text_utf16); + } + + INTL_METHOD_CHECK_STATUS( dfo, "Date parsing failed" ); + + + array_init_size( return_value, 9 ); + /* Add entries from various fields of the obtained parsed_calendar */ + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_SECOND, CALENDAR_SEC); + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MINUTE, CALENDAR_MIN); + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_HOUR_OF_DAY, CALENDAR_HOUR); + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_YEAR, CALENDAR_YEAR); + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_MONTH, CALENDAR_MDAY); + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_WEEK, CALENDAR_WDAY); + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_DAY_OF_YEAR, CALENDAR_YDAY); + add_to_localtime_arr( dfo, return_value, parsed_calendar, UCAL_MONTH, CALENDAR_MON); + + /* Is in DST? */ + isInDST = ucal_inDaylightTime(parsed_calendar , &INTL_DATA_ERROR_CODE(dfo)); + INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : while checking if currently in DST." ); + add_assoc_long( return_value, CALENDAR_ISDST,isInDST==1); +} +/* }}} */ + + +/* {{{ Parse the string $value starting at parse_pos to a Unix timestamp -int */ +U_CFUNC PHP_FUNCTION(datefmt_parse) +{ + char* text_to_parse = NULL; + size_t text_len =0; + zval* z_parse_pos = NULL; + int32_t parse_pos = -1; + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|z!", + &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){ + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + if (z_parse_pos) { + zval *z_parse_pos_tmp = z_parse_pos; + ZVAL_DEREF(z_parse_pos_tmp); + zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); + if (ZEND_LONG_INT_OVFL(long_parse_pos)) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "String index is out of valid range."); + RETURN_FALSE; + } + parse_pos = (int32_t)long_parse_pos; + if ((size_t)parse_pos > text_len) { + RETURN_FALSE; + } + } + internal_parse_to_timestamp( dfo, text_to_parse, text_len, z_parse_pos ? &parse_pos : NULL, false, return_value); + if (z_parse_pos) { + ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos); + } +} +/* }}} */ + +U_CFUNC PHP_METHOD(IntlDateFormatter, parseToCalendar) +{ + zend_string *text_to_parse = NULL; + zval* z_parse_pos = NULL; + int32_t parse_pos = -1; + + DATE_FORMAT_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(text_to_parse) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(z_parse_pos) + ZEND_PARSE_PARAMETERS_END(); + + object = ZEND_THIS; + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + if (z_parse_pos) { + bool failed; + zend_long long_parse_pos = zval_try_get_long(z_parse_pos, &failed); + if (failed) { + zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos)); + RETURN_THROWS(); + } + if (ZEND_LONG_INT_OVFL(long_parse_pos)) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "String index is out of valid range."); + RETURN_FALSE; + } + parse_pos = (int32_t)long_parse_pos; + if (parse_pos != -1 && (size_t)parse_pos > ZSTR_LEN(text_to_parse)) { + RETURN_FALSE; + } + } + internal_parse_to_timestamp( dfo, ZSTR_VAL(text_to_parse), ZSTR_LEN(text_to_parse), z_parse_pos ? &parse_pos : NULL, true, return_value); + if (z_parse_pos) { + ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos); + } +} + +/* {{{ Parse the string $value to a localtime array */ +U_CFUNC PHP_FUNCTION(datefmt_localtime) +{ + char* text_to_parse = NULL; + size_t text_len =0; + zval* z_parse_pos = NULL; + int32_t parse_pos = -1; + + DATE_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|z!", + &object, IntlDateFormatter_ce_ptr, &text_to_parse, &text_len, &z_parse_pos ) == FAILURE ){ + RETURN_THROWS(); + } + + /* Fetch the object. */ + DATE_FORMAT_METHOD_FETCH_OBJECT; + + if (z_parse_pos) { + zval *z_parse_pos_tmp = z_parse_pos; + ZVAL_DEREF(z_parse_pos_tmp); + zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp); + if (ZEND_LONG_INT_OVFL(long_parse_pos)) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "String index is out of valid range."); + RETURN_FALSE; + } + parse_pos = (int32_t)long_parse_pos; + if((size_t)parse_pos > text_len) { + RETURN_FALSE; + } + } + internal_parse_to_localtime( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value); + if (z_parse_pos) { + ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos); + } +} +/* }}} */ diff --git a/ext/intl/dateformat/datepatterngenerator_arginfo.h b/ext/intl/dateformat/datepatterngenerator_arginfo.h index 14327b0d69f8..01debdbe5fa6 100644 --- a/ext/intl/dateformat/datepatterngenerator_arginfo.h +++ b/ext/intl/dateformat/datepatterngenerator_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit datepatterngenerator.stub.php instead. * Stub hash: 4456b13f7ed59847bbf129cd45b0d1f63ce70108 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDatePatternGenerator___construct, 0, 0, 0) diff --git a/ext/intl/dateformat/datepatterngenerator_class.cpp b/ext/intl/dateformat/datepatterngenerator_class.cpp index 38faff751fb7..4a137d916f12 100644 --- a/ext/intl/dateformat/datepatterngenerator_class.cpp +++ b/ext/intl/dateformat/datepatterngenerator_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Mel Dafert (mel@dafert.at) | +----------------------------------------------------------------------+ @@ -36,7 +36,7 @@ zend_object_handlers IntlDatePatternGenerator_handlers; static zend_object *IntlDatePatternGenerator_object_clone(zend_object *object) { - IntlDatePatternGenerator_object *dtpgo_orig = php_intl_datepatterngenerator_fetch_object(object); + const IntlDatePatternGenerator_object *dtpgo_orig = php_intl_datepatterngenerator_fetch_object(object); zend_object *ret_val = IntlDatePatternGenerator_ce_ptr->create_object(object->ce); IntlDatePatternGenerator_object *dtpgo_new = php_intl_datepatterngenerator_fetch_object(ret_val); @@ -106,7 +106,7 @@ void dateformat_register_IntlDatePatternGenerator_class( void ) memcpy(&IntlDatePatternGenerator_handlers, &std_object_handlers, sizeof IntlDatePatternGenerator_handlers); - IntlDatePatternGenerator_handlers.offset = XtOffsetOf(IntlDatePatternGenerator_object, zo); + IntlDatePatternGenerator_handlers.offset = offsetof(IntlDatePatternGenerator_object, zo); IntlDatePatternGenerator_handlers.clone_obj = IntlDatePatternGenerator_object_clone; IntlDatePatternGenerator_handlers.free_obj = IntlDatePatternGenerator_object_free; } diff --git a/ext/intl/dateformat/datepatterngenerator_class.h b/ext/intl/dateformat/datepatterngenerator_class.h index eb8f7c433d0e..92739d396627 100644 --- a/ext/intl/dateformat/datepatterngenerator_class.h +++ b/ext/intl/dateformat/datepatterngenerator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Mel Dafert (mel@dafert.at) | +----------------------------------------------------------------------+ @@ -37,7 +37,7 @@ typedef struct { } IntlDatePatternGenerator_object; static inline IntlDatePatternGenerator_object *php_intl_datepatterngenerator_fetch_object(zend_object *obj) { - return (IntlDatePatternGenerator_object *)((char*)(obj) - XtOffsetOf(IntlDatePatternGenerator_object, zo)); + return ZEND_CONTAINER_OF(obj, IntlDatePatternGenerator_object, zo); } #define Z_INTL_DATEPATTERNGENERATOR_P(zv) php_intl_datepatterngenerator_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/dateformat/datepatterngenerator_methods.cpp b/ext/intl/dateformat/datepatterngenerator_methods.cpp index 1b659c7aa20c..f22be1c21fc1 100644 --- a/ext/intl/dateformat/datepatterngenerator_methods.cpp +++ b/ext/intl/dateformat/datepatterngenerator_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Mel Dafert (mel@dafert.at) | +----------------------------------------------------------------------+ @@ -30,7 +30,7 @@ using icu::DateTimePatternGenerator; using icu::Locale; using icu::StringPiece; -static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) +static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS) { char *locale_str; size_t locale_len = 0; @@ -44,15 +44,10 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling * Z_PARAM_STRING_OR_NULL(locale_str, locale_len) ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - } - DTPATTERNGEN_METHOD_FETCH_OBJECT_NO_CHECK; if (dtpgo->dtpg != NULL) { - intl_errors_set(DTPATTERNGEN_ERROR_P(dtpgo), U_ILLEGAL_ARGUMENT_ERROR, "Cannot call constructor twice", 0); + intl_errors_set(DTPATTERNGEN_ERROR_P(dtpgo), U_ILLEGAL_ARGUMENT_ERROR, "Cannot call constructor twice"); return FAILURE; } @@ -68,8 +63,7 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling * if (U_FAILURE(DTPATTERNGEN_ERROR_CODE(dtpgo))) { intl_error_set(NULL, DTPATTERNGEN_ERROR_CODE(dtpgo), - "Error creating DateTimePatternGenerator", - 0); + "Error creating DateTimePatternGenerator"); return FAILURE; } @@ -79,7 +73,7 @@ static zend_result dtpg_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling * U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) { object_init_ex( return_value, IntlDatePatternGenerator_ce_ptr ); - if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } @@ -87,22 +81,19 @@ U_CFUNC PHP_METHOD( IntlDatePatternGenerator, create ) U_CFUNC PHP_METHOD( IntlDatePatternGenerator, __construct ) { - zend_error_handling error_handling; - bool error_handling_replaced = 0; + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; /* return_value param is being changed, therefore we will always return * NULL here */ return_value = ZEND_THIS; - if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { - if (!EG(exception)) { - zend_string *err = intl_error_get_message(NULL); - zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); - zend_string_release_ex(err, 0); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); + if (dtpg_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; } diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index b872b0dc20f4..d3d29f70168d 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit formatter.stub.php instead. * Stub hash: d886941aa76837aed1da08845dbaff9442107203 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter___construct, 0, 0, 2) @@ -127,510 +127,507 @@ static zend_class_entry *register_class_NumberFormatter(void) zval const_PATTERN_DECIMAL_value; ZVAL_LONG(&const_PATTERN_DECIMAL_value, UNUM_PATTERN_DECIMAL); - zend_string *const_PATTERN_DECIMAL_name = zend_string_init_interned("PATTERN_DECIMAL", sizeof("PATTERN_DECIMAL") - 1, 1); + zend_string *const_PATTERN_DECIMAL_name = zend_string_init_interned("PATTERN_DECIMAL", sizeof("PATTERN_DECIMAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PATTERN_DECIMAL_name, &const_PATTERN_DECIMAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PATTERN_DECIMAL_name); + zend_string_release_ex(const_PATTERN_DECIMAL_name, true); zval const_DECIMAL_value; ZVAL_LONG(&const_DECIMAL_value, UNUM_DECIMAL); - zend_string *const_DECIMAL_name = zend_string_init_interned("DECIMAL", sizeof("DECIMAL") - 1, 1); + zend_string *const_DECIMAL_name = zend_string_init_interned("DECIMAL", sizeof("DECIMAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DECIMAL_name, &const_DECIMAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DECIMAL_name); + zend_string_release_ex(const_DECIMAL_name, true); zval const_DECIMAL_COMPACT_SHORT_value; ZVAL_LONG(&const_DECIMAL_COMPACT_SHORT_value, UNUM_DECIMAL_COMPACT_SHORT); - zend_string *const_DECIMAL_COMPACT_SHORT_name = zend_string_init_interned("DECIMAL_COMPACT_SHORT", sizeof("DECIMAL_COMPACT_SHORT") - 1, 1); + zend_string *const_DECIMAL_COMPACT_SHORT_name = zend_string_init_interned("DECIMAL_COMPACT_SHORT", sizeof("DECIMAL_COMPACT_SHORT") - 1, true); zend_declare_typed_class_constant(class_entry, const_DECIMAL_COMPACT_SHORT_name, &const_DECIMAL_COMPACT_SHORT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DECIMAL_COMPACT_SHORT_name); + zend_string_release_ex(const_DECIMAL_COMPACT_SHORT_name, true); zval const_DECIMAL_COMPACT_LONG_value; ZVAL_LONG(&const_DECIMAL_COMPACT_LONG_value, UNUM_DECIMAL_COMPACT_LONG); - zend_string *const_DECIMAL_COMPACT_LONG_name = zend_string_init_interned("DECIMAL_COMPACT_LONG", sizeof("DECIMAL_COMPACT_LONG") - 1, 1); + zend_string *const_DECIMAL_COMPACT_LONG_name = zend_string_init_interned("DECIMAL_COMPACT_LONG", sizeof("DECIMAL_COMPACT_LONG") - 1, true); zend_declare_typed_class_constant(class_entry, const_DECIMAL_COMPACT_LONG_name, &const_DECIMAL_COMPACT_LONG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DECIMAL_COMPACT_LONG_name); + zend_string_release_ex(const_DECIMAL_COMPACT_LONG_name, true); zval const_CURRENCY_value; ZVAL_LONG(&const_CURRENCY_value, UNUM_CURRENCY); - zend_string *const_CURRENCY_name = zend_string_init_interned("CURRENCY", sizeof("CURRENCY") - 1, 1); + zend_string *const_CURRENCY_name = zend_string_init_interned("CURRENCY", sizeof("CURRENCY") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENCY_name, &const_CURRENCY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENCY_name); + zend_string_release_ex(const_CURRENCY_name, true); zval const_PERCENT_value; ZVAL_LONG(&const_PERCENT_value, UNUM_PERCENT); - zend_string *const_PERCENT_name = zend_string_init_interned("PERCENT", sizeof("PERCENT") - 1, 1); + zend_string *const_PERCENT_name = zend_string_init_interned("PERCENT", sizeof("PERCENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PERCENT_name, &const_PERCENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PERCENT_name); + zend_string_release_ex(const_PERCENT_name, true); zval const_SCIENTIFIC_value; ZVAL_LONG(&const_SCIENTIFIC_value, UNUM_SCIENTIFIC); - zend_string *const_SCIENTIFIC_name = zend_string_init_interned("SCIENTIFIC", sizeof("SCIENTIFIC") - 1, 1); + zend_string *const_SCIENTIFIC_name = zend_string_init_interned("SCIENTIFIC", sizeof("SCIENTIFIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_SCIENTIFIC_name, &const_SCIENTIFIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SCIENTIFIC_name); + zend_string_release_ex(const_SCIENTIFIC_name, true); zval const_SPELLOUT_value; ZVAL_LONG(&const_SPELLOUT_value, UNUM_SPELLOUT); - zend_string *const_SPELLOUT_name = zend_string_init_interned("SPELLOUT", sizeof("SPELLOUT") - 1, 1); + zend_string *const_SPELLOUT_name = zend_string_init_interned("SPELLOUT", sizeof("SPELLOUT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SPELLOUT_name, &const_SPELLOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SPELLOUT_name); + zend_string_release_ex(const_SPELLOUT_name, true); zval const_ORDINAL_value; ZVAL_LONG(&const_ORDINAL_value, UNUM_ORDINAL); - zend_string *const_ORDINAL_name = zend_string_init_interned("ORDINAL", sizeof("ORDINAL") - 1, 1); + zend_string *const_ORDINAL_name = zend_string_init_interned("ORDINAL", sizeof("ORDINAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ORDINAL_name, &const_ORDINAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ORDINAL_name); + zend_string_release_ex(const_ORDINAL_name, true); zval const_DURATION_value; ZVAL_LONG(&const_DURATION_value, UNUM_DURATION); - zend_string *const_DURATION_name = zend_string_init_interned("DURATION", sizeof("DURATION") - 1, 1); + zend_string *const_DURATION_name = zend_string_init_interned("DURATION", sizeof("DURATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_DURATION_name, &const_DURATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DURATION_name); + zend_string_release_ex(const_DURATION_name, true); zval const_PATTERN_RULEBASED_value; ZVAL_LONG(&const_PATTERN_RULEBASED_value, UNUM_PATTERN_RULEBASED); - zend_string *const_PATTERN_RULEBASED_name = zend_string_init_interned("PATTERN_RULEBASED", sizeof("PATTERN_RULEBASED") - 1, 1); + zend_string *const_PATTERN_RULEBASED_name = zend_string_init_interned("PATTERN_RULEBASED", sizeof("PATTERN_RULEBASED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PATTERN_RULEBASED_name, &const_PATTERN_RULEBASED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PATTERN_RULEBASED_name); + zend_string_release_ex(const_PATTERN_RULEBASED_name, true); zval const_IGNORE_value; ZVAL_LONG(&const_IGNORE_value, UNUM_IGNORE); - zend_string *const_IGNORE_name = zend_string_init_interned("IGNORE", sizeof("IGNORE") - 1, 1); + zend_string *const_IGNORE_name = zend_string_init_interned("IGNORE", sizeof("IGNORE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IGNORE_name, &const_IGNORE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IGNORE_name); + zend_string_release_ex(const_IGNORE_name, true); zval const_CURRENCY_ISO_value; ZVAL_LONG(&const_CURRENCY_ISO_value, UNUM_CURRENCY_ISO); - zend_string *const_CURRENCY_ISO_name = zend_string_init_interned("CURRENCY_ISO", sizeof("CURRENCY_ISO") - 1, 1); + zend_string *const_CURRENCY_ISO_name = zend_string_init_interned("CURRENCY_ISO", sizeof("CURRENCY_ISO") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENCY_ISO_name, &const_CURRENCY_ISO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENCY_ISO_name); + zend_string_release_ex(const_CURRENCY_ISO_name, true); zval const_CURRENCY_PLURAL_value; ZVAL_LONG(&const_CURRENCY_PLURAL_value, UNUM_CURRENCY_PLURAL); - zend_string *const_CURRENCY_PLURAL_name = zend_string_init_interned("CURRENCY_PLURAL", sizeof("CURRENCY_PLURAL") - 1, 1); + zend_string *const_CURRENCY_PLURAL_name = zend_string_init_interned("CURRENCY_PLURAL", sizeof("CURRENCY_PLURAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENCY_PLURAL_name, &const_CURRENCY_PLURAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENCY_PLURAL_name); + zend_string_release_ex(const_CURRENCY_PLURAL_name, true); zval const_CURRENCY_ACCOUNTING_value; ZVAL_LONG(&const_CURRENCY_ACCOUNTING_value, UNUM_CURRENCY_ACCOUNTING); - zend_string *const_CURRENCY_ACCOUNTING_name = zend_string_init_interned("CURRENCY_ACCOUNTING", sizeof("CURRENCY_ACCOUNTING") - 1, 1); + zend_string *const_CURRENCY_ACCOUNTING_name = zend_string_init_interned("CURRENCY_ACCOUNTING", sizeof("CURRENCY_ACCOUNTING") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENCY_ACCOUNTING_name, &const_CURRENCY_ACCOUNTING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENCY_ACCOUNTING_name); + zend_string_release_ex(const_CURRENCY_ACCOUNTING_name, true); zval const_CASH_CURRENCY_value; ZVAL_LONG(&const_CASH_CURRENCY_value, UNUM_CASH_CURRENCY); - zend_string *const_CASH_CURRENCY_name = zend_string_init_interned("CASH_CURRENCY", sizeof("CASH_CURRENCY") - 1, 1); + zend_string *const_CASH_CURRENCY_name = zend_string_init_interned("CASH_CURRENCY", sizeof("CASH_CURRENCY") - 1, true); zend_declare_typed_class_constant(class_entry, const_CASH_CURRENCY_name, &const_CASH_CURRENCY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CASH_CURRENCY_name); + zend_string_release_ex(const_CASH_CURRENCY_name, true); zval const_CURRENCY_STANDARD_value; ZVAL_LONG(&const_CURRENCY_STANDARD_value, UNUM_CURRENCY_STANDARD); - zend_string *const_CURRENCY_STANDARD_name = zend_string_init_interned("CURRENCY_STANDARD", sizeof("CURRENCY_STANDARD") - 1, 1); + zend_string *const_CURRENCY_STANDARD_name = zend_string_init_interned("CURRENCY_STANDARD", sizeof("CURRENCY_STANDARD") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENCY_STANDARD_name, &const_CURRENCY_STANDARD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENCY_STANDARD_name); + zend_string_release_ex(const_CURRENCY_STANDARD_name, true); zval const_DEFAULT_STYLE_value; ZVAL_LONG(&const_DEFAULT_STYLE_value, UNUM_DEFAULT); - zend_string *const_DEFAULT_STYLE_name = zend_string_init_interned("DEFAULT_STYLE", sizeof("DEFAULT_STYLE") - 1, 1); + zend_string *const_DEFAULT_STYLE_name = zend_string_init_interned("DEFAULT_STYLE", sizeof("DEFAULT_STYLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DEFAULT_STYLE_name, &const_DEFAULT_STYLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DEFAULT_STYLE_name); + zend_string_release_ex(const_DEFAULT_STYLE_name, true); zval const_ROUND_CEILING_value; ZVAL_LONG(&const_ROUND_CEILING_value, UNUM_ROUND_CEILING); - zend_string *const_ROUND_CEILING_name = zend_string_init_interned("ROUND_CEILING", sizeof("ROUND_CEILING") - 1, 1); + zend_string *const_ROUND_CEILING_name = zend_string_init_interned("ROUND_CEILING", sizeof("ROUND_CEILING") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_CEILING_name, &const_ROUND_CEILING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_CEILING_name); + zend_string_release_ex(const_ROUND_CEILING_name, true); zval const_ROUND_FLOOR_value; ZVAL_LONG(&const_ROUND_FLOOR_value, UNUM_ROUND_FLOOR); - zend_string *const_ROUND_FLOOR_name = zend_string_init_interned("ROUND_FLOOR", sizeof("ROUND_FLOOR") - 1, 1); + zend_string *const_ROUND_FLOOR_name = zend_string_init_interned("ROUND_FLOOR", sizeof("ROUND_FLOOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_FLOOR_name, &const_ROUND_FLOOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_FLOOR_name); + zend_string_release_ex(const_ROUND_FLOOR_name, true); zval const_ROUND_DOWN_value; ZVAL_LONG(&const_ROUND_DOWN_value, UNUM_ROUND_DOWN); - zend_string *const_ROUND_DOWN_name = zend_string_init_interned("ROUND_DOWN", sizeof("ROUND_DOWN") - 1, 1); + zend_string *const_ROUND_DOWN_name = zend_string_init_interned("ROUND_DOWN", sizeof("ROUND_DOWN") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_DOWN_name, &const_ROUND_DOWN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_DOWN_name); + zend_string_release_ex(const_ROUND_DOWN_name, true); zval const_ROUND_UP_value; ZVAL_LONG(&const_ROUND_UP_value, UNUM_ROUND_UP); - zend_string *const_ROUND_UP_name = zend_string_init_interned("ROUND_UP", sizeof("ROUND_UP") - 1, 1); + zend_string *const_ROUND_UP_name = zend_string_init_interned("ROUND_UP", sizeof("ROUND_UP") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_UP_name, &const_ROUND_UP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_UP_name); + zend_string_release_ex(const_ROUND_UP_name, true); zval const_ROUND_TOWARD_ZERO_value; ZVAL_LONG(&const_ROUND_TOWARD_ZERO_value, UNUM_ROUND_DOWN); - zend_string *const_ROUND_TOWARD_ZERO_name = zend_string_init_interned("ROUND_TOWARD_ZERO", sizeof("ROUND_TOWARD_ZERO") - 1, 1); + zend_string *const_ROUND_TOWARD_ZERO_name = zend_string_init_interned("ROUND_TOWARD_ZERO", sizeof("ROUND_TOWARD_ZERO") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_TOWARD_ZERO_name, &const_ROUND_TOWARD_ZERO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_TOWARD_ZERO_name); + zend_string_release_ex(const_ROUND_TOWARD_ZERO_name, true); zval const_ROUND_AWAY_FROM_ZERO_value; ZVAL_LONG(&const_ROUND_AWAY_FROM_ZERO_value, UNUM_ROUND_UP); - zend_string *const_ROUND_AWAY_FROM_ZERO_name = zend_string_init_interned("ROUND_AWAY_FROM_ZERO", sizeof("ROUND_AWAY_FROM_ZERO") - 1, 1); + zend_string *const_ROUND_AWAY_FROM_ZERO_name = zend_string_init_interned("ROUND_AWAY_FROM_ZERO", sizeof("ROUND_AWAY_FROM_ZERO") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_AWAY_FROM_ZERO_name, &const_ROUND_AWAY_FROM_ZERO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_AWAY_FROM_ZERO_name); + zend_string_release_ex(const_ROUND_AWAY_FROM_ZERO_name, true); zval const_ROUND_HALFEVEN_value; ZVAL_LONG(&const_ROUND_HALFEVEN_value, UNUM_ROUND_HALFEVEN); - zend_string *const_ROUND_HALFEVEN_name = zend_string_init_interned("ROUND_HALFEVEN", sizeof("ROUND_HALFEVEN") - 1, 1); + zend_string *const_ROUND_HALFEVEN_name = zend_string_init_interned("ROUND_HALFEVEN", sizeof("ROUND_HALFEVEN") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_HALFEVEN_name, &const_ROUND_HALFEVEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_HALFEVEN_name); + zend_string_release_ex(const_ROUND_HALFEVEN_name, true); #if U_ICU_VERSION_MAJOR_NUM >= 69 zval const_ROUND_HALFODD_value; ZVAL_LONG(&const_ROUND_HALFODD_value, UNUM_ROUND_HALF_ODD); - zend_string *const_ROUND_HALFODD_name = zend_string_init_interned("ROUND_HALFODD", sizeof("ROUND_HALFODD") - 1, 1); + zend_string *const_ROUND_HALFODD_name = zend_string_init_interned("ROUND_HALFODD", sizeof("ROUND_HALFODD") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_HALFODD_name, &const_ROUND_HALFODD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_HALFODD_name); + zend_string_release_ex(const_ROUND_HALFODD_name, true); #endif zval const_ROUND_HALFDOWN_value; ZVAL_LONG(&const_ROUND_HALFDOWN_value, UNUM_ROUND_HALFDOWN); - zend_string *const_ROUND_HALFDOWN_name = zend_string_init_interned("ROUND_HALFDOWN", sizeof("ROUND_HALFDOWN") - 1, 1); + zend_string *const_ROUND_HALFDOWN_name = zend_string_init_interned("ROUND_HALFDOWN", sizeof("ROUND_HALFDOWN") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_HALFDOWN_name, &const_ROUND_HALFDOWN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_HALFDOWN_name); + zend_string_release_ex(const_ROUND_HALFDOWN_name, true); zval const_ROUND_HALFUP_value; ZVAL_LONG(&const_ROUND_HALFUP_value, UNUM_ROUND_HALFUP); - zend_string *const_ROUND_HALFUP_name = zend_string_init_interned("ROUND_HALFUP", sizeof("ROUND_HALFUP") - 1, 1); + zend_string *const_ROUND_HALFUP_name = zend_string_init_interned("ROUND_HALFUP", sizeof("ROUND_HALFUP") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUND_HALFUP_name, &const_ROUND_HALFUP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUND_HALFUP_name); + zend_string_release_ex(const_ROUND_HALFUP_name, true); zval const_PAD_BEFORE_PREFIX_value; ZVAL_LONG(&const_PAD_BEFORE_PREFIX_value, UNUM_PAD_BEFORE_PREFIX); - zend_string *const_PAD_BEFORE_PREFIX_name = zend_string_init_interned("PAD_BEFORE_PREFIX", sizeof("PAD_BEFORE_PREFIX") - 1, 1); + zend_string *const_PAD_BEFORE_PREFIX_name = zend_string_init_interned("PAD_BEFORE_PREFIX", sizeof("PAD_BEFORE_PREFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_PAD_BEFORE_PREFIX_name, &const_PAD_BEFORE_PREFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PAD_BEFORE_PREFIX_name); + zend_string_release_ex(const_PAD_BEFORE_PREFIX_name, true); zval const_PAD_AFTER_PREFIX_value; ZVAL_LONG(&const_PAD_AFTER_PREFIX_value, UNUM_PAD_AFTER_PREFIX); - zend_string *const_PAD_AFTER_PREFIX_name = zend_string_init_interned("PAD_AFTER_PREFIX", sizeof("PAD_AFTER_PREFIX") - 1, 1); + zend_string *const_PAD_AFTER_PREFIX_name = zend_string_init_interned("PAD_AFTER_PREFIX", sizeof("PAD_AFTER_PREFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_PAD_AFTER_PREFIX_name, &const_PAD_AFTER_PREFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PAD_AFTER_PREFIX_name); + zend_string_release_ex(const_PAD_AFTER_PREFIX_name, true); zval const_PAD_BEFORE_SUFFIX_value; ZVAL_LONG(&const_PAD_BEFORE_SUFFIX_value, UNUM_PAD_BEFORE_SUFFIX); - zend_string *const_PAD_BEFORE_SUFFIX_name = zend_string_init_interned("PAD_BEFORE_SUFFIX", sizeof("PAD_BEFORE_SUFFIX") - 1, 1); + zend_string *const_PAD_BEFORE_SUFFIX_name = zend_string_init_interned("PAD_BEFORE_SUFFIX", sizeof("PAD_BEFORE_SUFFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_PAD_BEFORE_SUFFIX_name, &const_PAD_BEFORE_SUFFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PAD_BEFORE_SUFFIX_name); + zend_string_release_ex(const_PAD_BEFORE_SUFFIX_name, true); zval const_PAD_AFTER_SUFFIX_value; ZVAL_LONG(&const_PAD_AFTER_SUFFIX_value, UNUM_PAD_AFTER_SUFFIX); - zend_string *const_PAD_AFTER_SUFFIX_name = zend_string_init_interned("PAD_AFTER_SUFFIX", sizeof("PAD_AFTER_SUFFIX") - 1, 1); + zend_string *const_PAD_AFTER_SUFFIX_name = zend_string_init_interned("PAD_AFTER_SUFFIX", sizeof("PAD_AFTER_SUFFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_PAD_AFTER_SUFFIX_name, &const_PAD_AFTER_SUFFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PAD_AFTER_SUFFIX_name); + zend_string_release_ex(const_PAD_AFTER_SUFFIX_name, true); zval const_PARSE_INT_ONLY_value; ZVAL_LONG(&const_PARSE_INT_ONLY_value, UNUM_PARSE_INT_ONLY); - zend_string *const_PARSE_INT_ONLY_name = zend_string_init_interned("PARSE_INT_ONLY", sizeof("PARSE_INT_ONLY") - 1, 1); + zend_string *const_PARSE_INT_ONLY_name = zend_string_init_interned("PARSE_INT_ONLY", sizeof("PARSE_INT_ONLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARSE_INT_ONLY_name, &const_PARSE_INT_ONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARSE_INT_ONLY_name); + zend_string_release_ex(const_PARSE_INT_ONLY_name, true); zval const_GROUPING_USED_value; ZVAL_LONG(&const_GROUPING_USED_value, UNUM_GROUPING_USED); - zend_string *const_GROUPING_USED_name = zend_string_init_interned("GROUPING_USED", sizeof("GROUPING_USED") - 1, 1); + zend_string *const_GROUPING_USED_name = zend_string_init_interned("GROUPING_USED", sizeof("GROUPING_USED") - 1, true); zend_declare_typed_class_constant(class_entry, const_GROUPING_USED_name, &const_GROUPING_USED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GROUPING_USED_name); + zend_string_release_ex(const_GROUPING_USED_name, true); zval const_DECIMAL_ALWAYS_SHOWN_value; ZVAL_LONG(&const_DECIMAL_ALWAYS_SHOWN_value, UNUM_DECIMAL_ALWAYS_SHOWN); - zend_string *const_DECIMAL_ALWAYS_SHOWN_name = zend_string_init_interned("DECIMAL_ALWAYS_SHOWN", sizeof("DECIMAL_ALWAYS_SHOWN") - 1, 1); + zend_string *const_DECIMAL_ALWAYS_SHOWN_name = zend_string_init_interned("DECIMAL_ALWAYS_SHOWN", sizeof("DECIMAL_ALWAYS_SHOWN") - 1, true); zend_declare_typed_class_constant(class_entry, const_DECIMAL_ALWAYS_SHOWN_name, &const_DECIMAL_ALWAYS_SHOWN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DECIMAL_ALWAYS_SHOWN_name); + zend_string_release_ex(const_DECIMAL_ALWAYS_SHOWN_name, true); zval const_MAX_INTEGER_DIGITS_value; ZVAL_LONG(&const_MAX_INTEGER_DIGITS_value, UNUM_MAX_INTEGER_DIGITS); - zend_string *const_MAX_INTEGER_DIGITS_name = zend_string_init_interned("MAX_INTEGER_DIGITS", sizeof("MAX_INTEGER_DIGITS") - 1, 1); + zend_string *const_MAX_INTEGER_DIGITS_name = zend_string_init_interned("MAX_INTEGER_DIGITS", sizeof("MAX_INTEGER_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MAX_INTEGER_DIGITS_name, &const_MAX_INTEGER_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MAX_INTEGER_DIGITS_name); + zend_string_release_ex(const_MAX_INTEGER_DIGITS_name, true); zval const_MIN_INTEGER_DIGITS_value; ZVAL_LONG(&const_MIN_INTEGER_DIGITS_value, UNUM_MIN_INTEGER_DIGITS); - zend_string *const_MIN_INTEGER_DIGITS_name = zend_string_init_interned("MIN_INTEGER_DIGITS", sizeof("MIN_INTEGER_DIGITS") - 1, 1); + zend_string *const_MIN_INTEGER_DIGITS_name = zend_string_init_interned("MIN_INTEGER_DIGITS", sizeof("MIN_INTEGER_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIN_INTEGER_DIGITS_name, &const_MIN_INTEGER_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIN_INTEGER_DIGITS_name); + zend_string_release_ex(const_MIN_INTEGER_DIGITS_name, true); zval const_INTEGER_DIGITS_value; ZVAL_LONG(&const_INTEGER_DIGITS_value, UNUM_INTEGER_DIGITS); - zend_string *const_INTEGER_DIGITS_name = zend_string_init_interned("INTEGER_DIGITS", sizeof("INTEGER_DIGITS") - 1, 1); + zend_string *const_INTEGER_DIGITS_name = zend_string_init_interned("INTEGER_DIGITS", sizeof("INTEGER_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_INTEGER_DIGITS_name, &const_INTEGER_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_INTEGER_DIGITS_name); + zend_string_release_ex(const_INTEGER_DIGITS_name, true); zval const_MAX_FRACTION_DIGITS_value; ZVAL_LONG(&const_MAX_FRACTION_DIGITS_value, UNUM_MAX_FRACTION_DIGITS); - zend_string *const_MAX_FRACTION_DIGITS_name = zend_string_init_interned("MAX_FRACTION_DIGITS", sizeof("MAX_FRACTION_DIGITS") - 1, 1); + zend_string *const_MAX_FRACTION_DIGITS_name = zend_string_init_interned("MAX_FRACTION_DIGITS", sizeof("MAX_FRACTION_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MAX_FRACTION_DIGITS_name, &const_MAX_FRACTION_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MAX_FRACTION_DIGITS_name); + zend_string_release_ex(const_MAX_FRACTION_DIGITS_name, true); zval const_MIN_FRACTION_DIGITS_value; ZVAL_LONG(&const_MIN_FRACTION_DIGITS_value, UNUM_MIN_FRACTION_DIGITS); - zend_string *const_MIN_FRACTION_DIGITS_name = zend_string_init_interned("MIN_FRACTION_DIGITS", sizeof("MIN_FRACTION_DIGITS") - 1, 1); + zend_string *const_MIN_FRACTION_DIGITS_name = zend_string_init_interned("MIN_FRACTION_DIGITS", sizeof("MIN_FRACTION_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIN_FRACTION_DIGITS_name, &const_MIN_FRACTION_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIN_FRACTION_DIGITS_name); + zend_string_release_ex(const_MIN_FRACTION_DIGITS_name, true); zval const_FRACTION_DIGITS_value; ZVAL_LONG(&const_FRACTION_DIGITS_value, UNUM_FRACTION_DIGITS); - zend_string *const_FRACTION_DIGITS_name = zend_string_init_interned("FRACTION_DIGITS", sizeof("FRACTION_DIGITS") - 1, 1); + zend_string *const_FRACTION_DIGITS_name = zend_string_init_interned("FRACTION_DIGITS", sizeof("FRACTION_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_FRACTION_DIGITS_name, &const_FRACTION_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FRACTION_DIGITS_name); + zend_string_release_ex(const_FRACTION_DIGITS_name, true); zval const_MULTIPLIER_value; ZVAL_LONG(&const_MULTIPLIER_value, UNUM_MULTIPLIER); - zend_string *const_MULTIPLIER_name = zend_string_init_interned("MULTIPLIER", sizeof("MULTIPLIER") - 1, 1); + zend_string *const_MULTIPLIER_name = zend_string_init_interned("MULTIPLIER", sizeof("MULTIPLIER") - 1, true); zend_declare_typed_class_constant(class_entry, const_MULTIPLIER_name, &const_MULTIPLIER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MULTIPLIER_name); + zend_string_release_ex(const_MULTIPLIER_name, true); zval const_GROUPING_SIZE_value; ZVAL_LONG(&const_GROUPING_SIZE_value, UNUM_GROUPING_SIZE); - zend_string *const_GROUPING_SIZE_name = zend_string_init_interned("GROUPING_SIZE", sizeof("GROUPING_SIZE") - 1, 1); + zend_string *const_GROUPING_SIZE_name = zend_string_init_interned("GROUPING_SIZE", sizeof("GROUPING_SIZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_GROUPING_SIZE_name, &const_GROUPING_SIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GROUPING_SIZE_name); + zend_string_release_ex(const_GROUPING_SIZE_name, true); zval const_ROUNDING_MODE_value; ZVAL_LONG(&const_ROUNDING_MODE_value, UNUM_ROUNDING_MODE); - zend_string *const_ROUNDING_MODE_name = zend_string_init_interned("ROUNDING_MODE", sizeof("ROUNDING_MODE") - 1, 1); + zend_string *const_ROUNDING_MODE_name = zend_string_init_interned("ROUNDING_MODE", sizeof("ROUNDING_MODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUNDING_MODE_name, &const_ROUNDING_MODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUNDING_MODE_name); + zend_string_release_ex(const_ROUNDING_MODE_name, true); zval const_ROUNDING_INCREMENT_value; ZVAL_LONG(&const_ROUNDING_INCREMENT_value, UNUM_ROUNDING_INCREMENT); - zend_string *const_ROUNDING_INCREMENT_name = zend_string_init_interned("ROUNDING_INCREMENT", sizeof("ROUNDING_INCREMENT") - 1, 1); + zend_string *const_ROUNDING_INCREMENT_name = zend_string_init_interned("ROUNDING_INCREMENT", sizeof("ROUNDING_INCREMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ROUNDING_INCREMENT_name, &const_ROUNDING_INCREMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ROUNDING_INCREMENT_name); + zend_string_release_ex(const_ROUNDING_INCREMENT_name, true); zval const_FORMAT_WIDTH_value; ZVAL_LONG(&const_FORMAT_WIDTH_value, UNUM_FORMAT_WIDTH); - zend_string *const_FORMAT_WIDTH_name = zend_string_init_interned("FORMAT_WIDTH", sizeof("FORMAT_WIDTH") - 1, 1); + zend_string *const_FORMAT_WIDTH_name = zend_string_init_interned("FORMAT_WIDTH", sizeof("FORMAT_WIDTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_FORMAT_WIDTH_name, &const_FORMAT_WIDTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FORMAT_WIDTH_name); + zend_string_release_ex(const_FORMAT_WIDTH_name, true); zval const_PADDING_POSITION_value; ZVAL_LONG(&const_PADDING_POSITION_value, UNUM_PADDING_POSITION); - zend_string *const_PADDING_POSITION_name = zend_string_init_interned("PADDING_POSITION", sizeof("PADDING_POSITION") - 1, 1); + zend_string *const_PADDING_POSITION_name = zend_string_init_interned("PADDING_POSITION", sizeof("PADDING_POSITION") - 1, true); zend_declare_typed_class_constant(class_entry, const_PADDING_POSITION_name, &const_PADDING_POSITION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PADDING_POSITION_name); + zend_string_release_ex(const_PADDING_POSITION_name, true); zval const_SECONDARY_GROUPING_SIZE_value; ZVAL_LONG(&const_SECONDARY_GROUPING_SIZE_value, UNUM_SECONDARY_GROUPING_SIZE); - zend_string *const_SECONDARY_GROUPING_SIZE_name = zend_string_init_interned("SECONDARY_GROUPING_SIZE", sizeof("SECONDARY_GROUPING_SIZE") - 1, 1); + zend_string *const_SECONDARY_GROUPING_SIZE_name = zend_string_init_interned("SECONDARY_GROUPING_SIZE", sizeof("SECONDARY_GROUPING_SIZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SECONDARY_GROUPING_SIZE_name, &const_SECONDARY_GROUPING_SIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SECONDARY_GROUPING_SIZE_name); + zend_string_release_ex(const_SECONDARY_GROUPING_SIZE_name, true); zval const_SIGNIFICANT_DIGITS_USED_value; ZVAL_LONG(&const_SIGNIFICANT_DIGITS_USED_value, UNUM_SIGNIFICANT_DIGITS_USED); - zend_string *const_SIGNIFICANT_DIGITS_USED_name = zend_string_init_interned("SIGNIFICANT_DIGITS_USED", sizeof("SIGNIFICANT_DIGITS_USED") - 1, 1); + zend_string *const_SIGNIFICANT_DIGITS_USED_name = zend_string_init_interned("SIGNIFICANT_DIGITS_USED", sizeof("SIGNIFICANT_DIGITS_USED") - 1, true); zend_declare_typed_class_constant(class_entry, const_SIGNIFICANT_DIGITS_USED_name, &const_SIGNIFICANT_DIGITS_USED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SIGNIFICANT_DIGITS_USED_name); + zend_string_release_ex(const_SIGNIFICANT_DIGITS_USED_name, true); zval const_MIN_SIGNIFICANT_DIGITS_value; ZVAL_LONG(&const_MIN_SIGNIFICANT_DIGITS_value, UNUM_MIN_SIGNIFICANT_DIGITS); - zend_string *const_MIN_SIGNIFICANT_DIGITS_name = zend_string_init_interned("MIN_SIGNIFICANT_DIGITS", sizeof("MIN_SIGNIFICANT_DIGITS") - 1, 1); + zend_string *const_MIN_SIGNIFICANT_DIGITS_name = zend_string_init_interned("MIN_SIGNIFICANT_DIGITS", sizeof("MIN_SIGNIFICANT_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIN_SIGNIFICANT_DIGITS_name, &const_MIN_SIGNIFICANT_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIN_SIGNIFICANT_DIGITS_name); + zend_string_release_ex(const_MIN_SIGNIFICANT_DIGITS_name, true); zval const_MAX_SIGNIFICANT_DIGITS_value; ZVAL_LONG(&const_MAX_SIGNIFICANT_DIGITS_value, UNUM_MAX_SIGNIFICANT_DIGITS); - zend_string *const_MAX_SIGNIFICANT_DIGITS_name = zend_string_init_interned("MAX_SIGNIFICANT_DIGITS", sizeof("MAX_SIGNIFICANT_DIGITS") - 1, 1); + zend_string *const_MAX_SIGNIFICANT_DIGITS_name = zend_string_init_interned("MAX_SIGNIFICANT_DIGITS", sizeof("MAX_SIGNIFICANT_DIGITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MAX_SIGNIFICANT_DIGITS_name, &const_MAX_SIGNIFICANT_DIGITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MAX_SIGNIFICANT_DIGITS_name); + zend_string_release_ex(const_MAX_SIGNIFICANT_DIGITS_name, true); zval const_LENIENT_PARSE_value; ZVAL_LONG(&const_LENIENT_PARSE_value, UNUM_LENIENT_PARSE); - zend_string *const_LENIENT_PARSE_name = zend_string_init_interned("LENIENT_PARSE", sizeof("LENIENT_PARSE") - 1, 1); + zend_string *const_LENIENT_PARSE_name = zend_string_init_interned("LENIENT_PARSE", sizeof("LENIENT_PARSE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LENIENT_PARSE_name, &const_LENIENT_PARSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LENIENT_PARSE_name); + zend_string_release_ex(const_LENIENT_PARSE_name, true); zval const_POSITIVE_PREFIX_value; ZVAL_LONG(&const_POSITIVE_PREFIX_value, UNUM_POSITIVE_PREFIX); - zend_string *const_POSITIVE_PREFIX_name = zend_string_init_interned("POSITIVE_PREFIX", sizeof("POSITIVE_PREFIX") - 1, 1); + zend_string *const_POSITIVE_PREFIX_name = zend_string_init_interned("POSITIVE_PREFIX", sizeof("POSITIVE_PREFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_POSITIVE_PREFIX_name, &const_POSITIVE_PREFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_POSITIVE_PREFIX_name); + zend_string_release_ex(const_POSITIVE_PREFIX_name, true); zval const_POSITIVE_SUFFIX_value; ZVAL_LONG(&const_POSITIVE_SUFFIX_value, UNUM_POSITIVE_SUFFIX); - zend_string *const_POSITIVE_SUFFIX_name = zend_string_init_interned("POSITIVE_SUFFIX", sizeof("POSITIVE_SUFFIX") - 1, 1); + zend_string *const_POSITIVE_SUFFIX_name = zend_string_init_interned("POSITIVE_SUFFIX", sizeof("POSITIVE_SUFFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_POSITIVE_SUFFIX_name, &const_POSITIVE_SUFFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_POSITIVE_SUFFIX_name); + zend_string_release_ex(const_POSITIVE_SUFFIX_name, true); zval const_NEGATIVE_PREFIX_value; ZVAL_LONG(&const_NEGATIVE_PREFIX_value, UNUM_NEGATIVE_PREFIX); - zend_string *const_NEGATIVE_PREFIX_name = zend_string_init_interned("NEGATIVE_PREFIX", sizeof("NEGATIVE_PREFIX") - 1, 1); + zend_string *const_NEGATIVE_PREFIX_name = zend_string_init_interned("NEGATIVE_PREFIX", sizeof("NEGATIVE_PREFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_NEGATIVE_PREFIX_name, &const_NEGATIVE_PREFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NEGATIVE_PREFIX_name); + zend_string_release_ex(const_NEGATIVE_PREFIX_name, true); zval const_NEGATIVE_SUFFIX_value; ZVAL_LONG(&const_NEGATIVE_SUFFIX_value, UNUM_NEGATIVE_SUFFIX); - zend_string *const_NEGATIVE_SUFFIX_name = zend_string_init_interned("NEGATIVE_SUFFIX", sizeof("NEGATIVE_SUFFIX") - 1, 1); + zend_string *const_NEGATIVE_SUFFIX_name = zend_string_init_interned("NEGATIVE_SUFFIX", sizeof("NEGATIVE_SUFFIX") - 1, true); zend_declare_typed_class_constant(class_entry, const_NEGATIVE_SUFFIX_name, &const_NEGATIVE_SUFFIX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NEGATIVE_SUFFIX_name); + zend_string_release_ex(const_NEGATIVE_SUFFIX_name, true); zval const_PADDING_CHARACTER_value; ZVAL_LONG(&const_PADDING_CHARACTER_value, UNUM_PADDING_CHARACTER); - zend_string *const_PADDING_CHARACTER_name = zend_string_init_interned("PADDING_CHARACTER", sizeof("PADDING_CHARACTER") - 1, 1); + zend_string *const_PADDING_CHARACTER_name = zend_string_init_interned("PADDING_CHARACTER", sizeof("PADDING_CHARACTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_PADDING_CHARACTER_name, &const_PADDING_CHARACTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PADDING_CHARACTER_name); + zend_string_release_ex(const_PADDING_CHARACTER_name, true); zval const_CURRENCY_CODE_value; ZVAL_LONG(&const_CURRENCY_CODE_value, UNUM_CURRENCY_CODE); - zend_string *const_CURRENCY_CODE_name = zend_string_init_interned("CURRENCY_CODE", sizeof("CURRENCY_CODE") - 1, 1); + zend_string *const_CURRENCY_CODE_name = zend_string_init_interned("CURRENCY_CODE", sizeof("CURRENCY_CODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENCY_CODE_name, &const_CURRENCY_CODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENCY_CODE_name); + zend_string_release_ex(const_CURRENCY_CODE_name, true); zval const_DEFAULT_RULESET_value; ZVAL_LONG(&const_DEFAULT_RULESET_value, UNUM_DEFAULT_RULESET); - zend_string *const_DEFAULT_RULESET_name = zend_string_init_interned("DEFAULT_RULESET", sizeof("DEFAULT_RULESET") - 1, 1); + zend_string *const_DEFAULT_RULESET_name = zend_string_init_interned("DEFAULT_RULESET", sizeof("DEFAULT_RULESET") - 1, true); zend_declare_typed_class_constant(class_entry, const_DEFAULT_RULESET_name, &const_DEFAULT_RULESET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DEFAULT_RULESET_name); + zend_string_release_ex(const_DEFAULT_RULESET_name, true); zval const_PUBLIC_RULESETS_value; ZVAL_LONG(&const_PUBLIC_RULESETS_value, UNUM_PUBLIC_RULESETS); - zend_string *const_PUBLIC_RULESETS_name = zend_string_init_interned("PUBLIC_RULESETS", sizeof("PUBLIC_RULESETS") - 1, 1); + zend_string *const_PUBLIC_RULESETS_name = zend_string_init_interned("PUBLIC_RULESETS", sizeof("PUBLIC_RULESETS") - 1, true); zend_declare_typed_class_constant(class_entry, const_PUBLIC_RULESETS_name, &const_PUBLIC_RULESETS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PUBLIC_RULESETS_name); + zend_string_release_ex(const_PUBLIC_RULESETS_name, true); zval const_DECIMAL_SEPARATOR_SYMBOL_value; ZVAL_LONG(&const_DECIMAL_SEPARATOR_SYMBOL_value, UNUM_DECIMAL_SEPARATOR_SYMBOL); - zend_string *const_DECIMAL_SEPARATOR_SYMBOL_name = zend_string_init_interned("DECIMAL_SEPARATOR_SYMBOL", sizeof("DECIMAL_SEPARATOR_SYMBOL") - 1, 1); + zend_string *const_DECIMAL_SEPARATOR_SYMBOL_name = zend_string_init_interned("DECIMAL_SEPARATOR_SYMBOL", sizeof("DECIMAL_SEPARATOR_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DECIMAL_SEPARATOR_SYMBOL_name, &const_DECIMAL_SEPARATOR_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DECIMAL_SEPARATOR_SYMBOL_name); + zend_string_release_ex(const_DECIMAL_SEPARATOR_SYMBOL_name, true); zval const_GROUPING_SEPARATOR_SYMBOL_value; ZVAL_LONG(&const_GROUPING_SEPARATOR_SYMBOL_value, UNUM_GROUPING_SEPARATOR_SYMBOL); - zend_string *const_GROUPING_SEPARATOR_SYMBOL_name = zend_string_init_interned("GROUPING_SEPARATOR_SYMBOL", sizeof("GROUPING_SEPARATOR_SYMBOL") - 1, 1); + zend_string *const_GROUPING_SEPARATOR_SYMBOL_name = zend_string_init_interned("GROUPING_SEPARATOR_SYMBOL", sizeof("GROUPING_SEPARATOR_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_GROUPING_SEPARATOR_SYMBOL_name, &const_GROUPING_SEPARATOR_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GROUPING_SEPARATOR_SYMBOL_name); + zend_string_release_ex(const_GROUPING_SEPARATOR_SYMBOL_name, true); zval const_PATTERN_SEPARATOR_SYMBOL_value; ZVAL_LONG(&const_PATTERN_SEPARATOR_SYMBOL_value, UNUM_PATTERN_SEPARATOR_SYMBOL); - zend_string *const_PATTERN_SEPARATOR_SYMBOL_name = zend_string_init_interned("PATTERN_SEPARATOR_SYMBOL", sizeof("PATTERN_SEPARATOR_SYMBOL") - 1, 1); + zend_string *const_PATTERN_SEPARATOR_SYMBOL_name = zend_string_init_interned("PATTERN_SEPARATOR_SYMBOL", sizeof("PATTERN_SEPARATOR_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PATTERN_SEPARATOR_SYMBOL_name, &const_PATTERN_SEPARATOR_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PATTERN_SEPARATOR_SYMBOL_name); + zend_string_release_ex(const_PATTERN_SEPARATOR_SYMBOL_name, true); zval const_PERCENT_SYMBOL_value; ZVAL_LONG(&const_PERCENT_SYMBOL_value, UNUM_PERCENT_SYMBOL); - zend_string *const_PERCENT_SYMBOL_name = zend_string_init_interned("PERCENT_SYMBOL", sizeof("PERCENT_SYMBOL") - 1, 1); + zend_string *const_PERCENT_SYMBOL_name = zend_string_init_interned("PERCENT_SYMBOL", sizeof("PERCENT_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PERCENT_SYMBOL_name, &const_PERCENT_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PERCENT_SYMBOL_name); + zend_string_release_ex(const_PERCENT_SYMBOL_name, true); zval const_ZERO_DIGIT_SYMBOL_value; ZVAL_LONG(&const_ZERO_DIGIT_SYMBOL_value, UNUM_ZERO_DIGIT_SYMBOL); - zend_string *const_ZERO_DIGIT_SYMBOL_name = zend_string_init_interned("ZERO_DIGIT_SYMBOL", sizeof("ZERO_DIGIT_SYMBOL") - 1, 1); + zend_string *const_ZERO_DIGIT_SYMBOL_name = zend_string_init_interned("ZERO_DIGIT_SYMBOL", sizeof("ZERO_DIGIT_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_ZERO_DIGIT_SYMBOL_name, &const_ZERO_DIGIT_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ZERO_DIGIT_SYMBOL_name); + zend_string_release_ex(const_ZERO_DIGIT_SYMBOL_name, true); zval const_DIGIT_SYMBOL_value; ZVAL_LONG(&const_DIGIT_SYMBOL_value, UNUM_DIGIT_SYMBOL); - zend_string *const_DIGIT_SYMBOL_name = zend_string_init_interned("DIGIT_SYMBOL", sizeof("DIGIT_SYMBOL") - 1, 1); + zend_string *const_DIGIT_SYMBOL_name = zend_string_init_interned("DIGIT_SYMBOL", sizeof("DIGIT_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DIGIT_SYMBOL_name, &const_DIGIT_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DIGIT_SYMBOL_name); + zend_string_release_ex(const_DIGIT_SYMBOL_name, true); zval const_MINUS_SIGN_SYMBOL_value; ZVAL_LONG(&const_MINUS_SIGN_SYMBOL_value, UNUM_MINUS_SIGN_SYMBOL); - zend_string *const_MINUS_SIGN_SYMBOL_name = zend_string_init_interned("MINUS_SIGN_SYMBOL", sizeof("MINUS_SIGN_SYMBOL") - 1, 1); + zend_string *const_MINUS_SIGN_SYMBOL_name = zend_string_init_interned("MINUS_SIGN_SYMBOL", sizeof("MINUS_SIGN_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_MINUS_SIGN_SYMBOL_name, &const_MINUS_SIGN_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MINUS_SIGN_SYMBOL_name); + zend_string_release_ex(const_MINUS_SIGN_SYMBOL_name, true); zval const_PLUS_SIGN_SYMBOL_value; ZVAL_LONG(&const_PLUS_SIGN_SYMBOL_value, UNUM_PLUS_SIGN_SYMBOL); - zend_string *const_PLUS_SIGN_SYMBOL_name = zend_string_init_interned("PLUS_SIGN_SYMBOL", sizeof("PLUS_SIGN_SYMBOL") - 1, 1); + zend_string *const_PLUS_SIGN_SYMBOL_name = zend_string_init_interned("PLUS_SIGN_SYMBOL", sizeof("PLUS_SIGN_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PLUS_SIGN_SYMBOL_name, &const_PLUS_SIGN_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PLUS_SIGN_SYMBOL_name); + zend_string_release_ex(const_PLUS_SIGN_SYMBOL_name, true); zval const_CURRENCY_SYMBOL_value; ZVAL_LONG(&const_CURRENCY_SYMBOL_value, UNUM_CURRENCY_SYMBOL); - zend_string *const_CURRENCY_SYMBOL_name = zend_string_init_interned("CURRENCY_SYMBOL", sizeof("CURRENCY_SYMBOL") - 1, 1); + zend_string *const_CURRENCY_SYMBOL_name = zend_string_init_interned("CURRENCY_SYMBOL", sizeof("CURRENCY_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENCY_SYMBOL_name, &const_CURRENCY_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENCY_SYMBOL_name); + zend_string_release_ex(const_CURRENCY_SYMBOL_name, true); zval const_INTL_CURRENCY_SYMBOL_value; ZVAL_LONG(&const_INTL_CURRENCY_SYMBOL_value, UNUM_INTL_CURRENCY_SYMBOL); - zend_string *const_INTL_CURRENCY_SYMBOL_name = zend_string_init_interned("INTL_CURRENCY_SYMBOL", sizeof("INTL_CURRENCY_SYMBOL") - 1, 1); + zend_string *const_INTL_CURRENCY_SYMBOL_name = zend_string_init_interned("INTL_CURRENCY_SYMBOL", sizeof("INTL_CURRENCY_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_INTL_CURRENCY_SYMBOL_name, &const_INTL_CURRENCY_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_INTL_CURRENCY_SYMBOL_name); + zend_string_release_ex(const_INTL_CURRENCY_SYMBOL_name, true); zval const_MONETARY_SEPARATOR_SYMBOL_value; ZVAL_LONG(&const_MONETARY_SEPARATOR_SYMBOL_value, UNUM_MONETARY_SEPARATOR_SYMBOL); - zend_string *const_MONETARY_SEPARATOR_SYMBOL_name = zend_string_init_interned("MONETARY_SEPARATOR_SYMBOL", sizeof("MONETARY_SEPARATOR_SYMBOL") - 1, 1); + zend_string *const_MONETARY_SEPARATOR_SYMBOL_name = zend_string_init_interned("MONETARY_SEPARATOR_SYMBOL", sizeof("MONETARY_SEPARATOR_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_MONETARY_SEPARATOR_SYMBOL_name, &const_MONETARY_SEPARATOR_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MONETARY_SEPARATOR_SYMBOL_name); + zend_string_release_ex(const_MONETARY_SEPARATOR_SYMBOL_name, true); zval const_EXPONENTIAL_SYMBOL_value; ZVAL_LONG(&const_EXPONENTIAL_SYMBOL_value, UNUM_EXPONENTIAL_SYMBOL); - zend_string *const_EXPONENTIAL_SYMBOL_name = zend_string_init_interned("EXPONENTIAL_SYMBOL", sizeof("EXPONENTIAL_SYMBOL") - 1, 1); + zend_string *const_EXPONENTIAL_SYMBOL_name = zend_string_init_interned("EXPONENTIAL_SYMBOL", sizeof("EXPONENTIAL_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXPONENTIAL_SYMBOL_name, &const_EXPONENTIAL_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXPONENTIAL_SYMBOL_name); + zend_string_release_ex(const_EXPONENTIAL_SYMBOL_name, true); zval const_PERMILL_SYMBOL_value; ZVAL_LONG(&const_PERMILL_SYMBOL_value, UNUM_PERMILL_SYMBOL); - zend_string *const_PERMILL_SYMBOL_name = zend_string_init_interned("PERMILL_SYMBOL", sizeof("PERMILL_SYMBOL") - 1, 1); + zend_string *const_PERMILL_SYMBOL_name = zend_string_init_interned("PERMILL_SYMBOL", sizeof("PERMILL_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PERMILL_SYMBOL_name, &const_PERMILL_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PERMILL_SYMBOL_name); + zend_string_release_ex(const_PERMILL_SYMBOL_name, true); zval const_PAD_ESCAPE_SYMBOL_value; ZVAL_LONG(&const_PAD_ESCAPE_SYMBOL_value, UNUM_PAD_ESCAPE_SYMBOL); - zend_string *const_PAD_ESCAPE_SYMBOL_name = zend_string_init_interned("PAD_ESCAPE_SYMBOL", sizeof("PAD_ESCAPE_SYMBOL") - 1, 1); + zend_string *const_PAD_ESCAPE_SYMBOL_name = zend_string_init_interned("PAD_ESCAPE_SYMBOL", sizeof("PAD_ESCAPE_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PAD_ESCAPE_SYMBOL_name, &const_PAD_ESCAPE_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PAD_ESCAPE_SYMBOL_name); + zend_string_release_ex(const_PAD_ESCAPE_SYMBOL_name, true); zval const_INFINITY_SYMBOL_value; ZVAL_LONG(&const_INFINITY_SYMBOL_value, UNUM_INFINITY_SYMBOL); - zend_string *const_INFINITY_SYMBOL_name = zend_string_init_interned("INFINITY_SYMBOL", sizeof("INFINITY_SYMBOL") - 1, 1); + zend_string *const_INFINITY_SYMBOL_name = zend_string_init_interned("INFINITY_SYMBOL", sizeof("INFINITY_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_INFINITY_SYMBOL_name, &const_INFINITY_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_INFINITY_SYMBOL_name); + zend_string_release_ex(const_INFINITY_SYMBOL_name, true); zval const_NAN_SYMBOL_value; ZVAL_LONG(&const_NAN_SYMBOL_value, UNUM_NAN_SYMBOL); - zend_string *const_NAN_SYMBOL_name = zend_string_init_interned("NAN_SYMBOL", sizeof("NAN_SYMBOL") - 1, 1); + zend_string *const_NAN_SYMBOL_name = zend_string_init_interned("NAN_SYMBOL", sizeof("NAN_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_NAN_SYMBOL_name, &const_NAN_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NAN_SYMBOL_name); + zend_string_release_ex(const_NAN_SYMBOL_name, true); zval const_SIGNIFICANT_DIGIT_SYMBOL_value; ZVAL_LONG(&const_SIGNIFICANT_DIGIT_SYMBOL_value, UNUM_SIGNIFICANT_DIGIT_SYMBOL); - zend_string *const_SIGNIFICANT_DIGIT_SYMBOL_name = zend_string_init_interned("SIGNIFICANT_DIGIT_SYMBOL", sizeof("SIGNIFICANT_DIGIT_SYMBOL") - 1, 1); + zend_string *const_SIGNIFICANT_DIGIT_SYMBOL_name = zend_string_init_interned("SIGNIFICANT_DIGIT_SYMBOL", sizeof("SIGNIFICANT_DIGIT_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_SIGNIFICANT_DIGIT_SYMBOL_name, &const_SIGNIFICANT_DIGIT_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SIGNIFICANT_DIGIT_SYMBOL_name); + zend_string_release_ex(const_SIGNIFICANT_DIGIT_SYMBOL_name, true); zval const_MONETARY_GROUPING_SEPARATOR_SYMBOL_value; ZVAL_LONG(&const_MONETARY_GROUPING_SEPARATOR_SYMBOL_value, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL); - zend_string *const_MONETARY_GROUPING_SEPARATOR_SYMBOL_name = zend_string_init_interned("MONETARY_GROUPING_SEPARATOR_SYMBOL", sizeof("MONETARY_GROUPING_SEPARATOR_SYMBOL") - 1, 1); + zend_string *const_MONETARY_GROUPING_SEPARATOR_SYMBOL_name = zend_string_init_interned("MONETARY_GROUPING_SEPARATOR_SYMBOL", sizeof("MONETARY_GROUPING_SEPARATOR_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_MONETARY_GROUPING_SEPARATOR_SYMBOL_name, &const_MONETARY_GROUPING_SEPARATOR_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MONETARY_GROUPING_SEPARATOR_SYMBOL_name); + zend_string_release_ex(const_MONETARY_GROUPING_SEPARATOR_SYMBOL_name, true); zval const_TYPE_DEFAULT_value; ZVAL_LONG(&const_TYPE_DEFAULT_value, FORMAT_TYPE_DEFAULT); - zend_string *const_TYPE_DEFAULT_name = zend_string_init_interned("TYPE_DEFAULT", sizeof("TYPE_DEFAULT") - 1, 1); + zend_string *const_TYPE_DEFAULT_name = zend_string_init_interned("TYPE_DEFAULT", sizeof("TYPE_DEFAULT") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_DEFAULT_name, &const_TYPE_DEFAULT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_DEFAULT_name); + zend_string_release_ex(const_TYPE_DEFAULT_name, true); zval const_TYPE_INT32_value; ZVAL_LONG(&const_TYPE_INT32_value, FORMAT_TYPE_INT32); - zend_string *const_TYPE_INT32_name = zend_string_init_interned("TYPE_INT32", sizeof("TYPE_INT32") - 1, 1); + zend_string *const_TYPE_INT32_name = zend_string_init_interned("TYPE_INT32", sizeof("TYPE_INT32") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_INT32_name, &const_TYPE_INT32_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_INT32_name); + zend_string_release_ex(const_TYPE_INT32_name, true); zval const_TYPE_INT64_value; ZVAL_LONG(&const_TYPE_INT64_value, FORMAT_TYPE_INT64); - zend_string *const_TYPE_INT64_name = zend_string_init_interned("TYPE_INT64", sizeof("TYPE_INT64") - 1, 1); + zend_string *const_TYPE_INT64_name = zend_string_init_interned("TYPE_INT64", sizeof("TYPE_INT64") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_INT64_name, &const_TYPE_INT64_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_INT64_name); + zend_string_release_ex(const_TYPE_INT64_name, true); zval const_TYPE_DOUBLE_value; ZVAL_LONG(&const_TYPE_DOUBLE_value, FORMAT_TYPE_DOUBLE); - zend_string *const_TYPE_DOUBLE_name = zend_string_init_interned("TYPE_DOUBLE", sizeof("TYPE_DOUBLE") - 1, 1); + zend_string *const_TYPE_DOUBLE_name = zend_string_init_interned("TYPE_DOUBLE", sizeof("TYPE_DOUBLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_DOUBLE_name, &const_TYPE_DOUBLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_DOUBLE_name); + zend_string_release_ex(const_TYPE_DOUBLE_name, true); zval const_TYPE_CURRENCY_value; ZVAL_LONG(&const_TYPE_CURRENCY_value, FORMAT_TYPE_CURRENCY); - zend_string *const_TYPE_CURRENCY_name = zend_string_init_interned("TYPE_CURRENCY", sizeof("TYPE_CURRENCY") - 1, 1); + zend_string *const_TYPE_CURRENCY_name = zend_string_init_interned("TYPE_CURRENCY", sizeof("TYPE_CURRENCY") - 1, true); zend_class_constant *const_TYPE_CURRENCY = zend_declare_typed_class_constant(class_entry, const_TYPE_CURRENCY_name, &const_TYPE_CURRENCY_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_CURRENCY_name); + zend_string_release_ex(const_TYPE_CURRENCY_name, true); zend_attribute *attribute_Deprecated_const_TYPE_CURRENCY_0 = zend_add_class_constant_attribute(class_entry, const_TYPE_CURRENCY, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_const_TYPE_CURRENCY_0_arg0; - zend_string *attribute_Deprecated_const_TYPE_CURRENCY_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); - ZVAL_STR(&attribute_Deprecated_const_TYPE_CURRENCY_0_arg0, attribute_Deprecated_const_TYPE_CURRENCY_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_const_TYPE_CURRENCY_0->args[0].value, &attribute_Deprecated_const_TYPE_CURRENCY_0_arg0); + ZVAL_STR(&attribute_Deprecated_const_TYPE_CURRENCY_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_const_TYPE_CURRENCY_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); return class_entry; diff --git a/ext/intl/formatter/formatter_attr.c b/ext/intl/formatter/formatter_attr.c deleted file mode 100644 index 874984f5405f..000000000000 --- a/ext/intl/formatter/formatter_attr.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "formatter_class.h" -#include "intl_convert.h" - -#include - -/* {{{ Get formatter attribute value. */ -PHP_FUNCTION( numfmt_get_attribute ) -{ - zend_long attribute, value; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", - &object, NumberFormatter_ce_ptr, &attribute ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - switch(attribute) { - case UNUM_PARSE_INT_ONLY: - case UNUM_GROUPING_USED: - case UNUM_DECIMAL_ALWAYS_SHOWN: - case UNUM_MAX_INTEGER_DIGITS: - case UNUM_MIN_INTEGER_DIGITS: - case UNUM_INTEGER_DIGITS: - case UNUM_MAX_FRACTION_DIGITS: - case UNUM_MIN_FRACTION_DIGITS: - case UNUM_FRACTION_DIGITS: - case UNUM_MULTIPLIER: - case UNUM_GROUPING_SIZE: - case UNUM_ROUNDING_MODE: - case UNUM_FORMAT_WIDTH: - case UNUM_PADDING_POSITION: - case UNUM_SECONDARY_GROUPING_SIZE: - case UNUM_SIGNIFICANT_DIGITS_USED: - case UNUM_MIN_SIGNIFICANT_DIGITS: - case UNUM_MAX_SIGNIFICANT_DIGITS: - case UNUM_LENIENT_PARSE: - value = unum_getAttribute(FORMATTER_OBJECT(nfo), attribute); - if(value == -1) { - INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; - } else { - RETVAL_LONG(value); - } - break; - case UNUM_ROUNDING_INCREMENT: - { - double value_double = unum_getDoubleAttribute(FORMATTER_OBJECT(nfo), attribute); - if(value_double == -1) { - INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; - } else { - RETVAL_DOUBLE(value_double); - } - } - break; - default: - INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; - break; - } - - INTL_METHOD_CHECK_STATUS( nfo, "Error getting attribute value" ); -} -/* }}} */ - -/* {{{ Get formatter attribute value. */ -PHP_FUNCTION( numfmt_get_text_attribute ) -{ - zend_long attribute; - UChar value_buf[64]; - int32_t value_buf_size = USIZE( value_buf ); - UChar* value = value_buf; - int32_t length = 0; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", - &object, NumberFormatter_ce_ptr, &attribute ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, value_buf_size, &INTL_DATA_ERROR_CODE(nfo) ); - if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= value_buf_size) { - ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ - INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; - value = eumalloc(length); - length = unum_getTextAttribute( FORMATTER_OBJECT(nfo), attribute, value, length, &INTL_DATA_ERROR_CODE(nfo) ); - if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { - efree(value); - value = value_buf; - } - } - INTL_METHOD_CHECK_STATUS( nfo, "Error getting attribute value" ); - - INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value != value_buf ) ); -} -/* }}} */ - -/* {{{ Get formatter attribute value. */ -PHP_FUNCTION( numfmt_set_attribute ) -{ - zend_long attribute; - zval *value; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oln", - &object, NumberFormatter_ce_ptr, &attribute, &value ) == FAILURE) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - switch(attribute) { - case UNUM_PARSE_INT_ONLY: - case UNUM_GROUPING_USED: - case UNUM_DECIMAL_ALWAYS_SHOWN: - case UNUM_MAX_INTEGER_DIGITS: - case UNUM_MIN_INTEGER_DIGITS: - case UNUM_INTEGER_DIGITS: - case UNUM_MAX_FRACTION_DIGITS: - case UNUM_MIN_FRACTION_DIGITS: - case UNUM_FRACTION_DIGITS: - case UNUM_MULTIPLIER: - case UNUM_GROUPING_SIZE: - case UNUM_ROUNDING_MODE: - case UNUM_FORMAT_WIDTH: - case UNUM_PADDING_POSITION: - case UNUM_SECONDARY_GROUPING_SIZE: - case UNUM_SIGNIFICANT_DIGITS_USED: - case UNUM_MIN_SIGNIFICANT_DIGITS: - case UNUM_MAX_SIGNIFICANT_DIGITS: - case UNUM_LENIENT_PARSE: - unum_setAttribute(FORMATTER_OBJECT(nfo), attribute, zval_get_long(value)); - break; - case UNUM_ROUNDING_INCREMENT: - unum_setDoubleAttribute(FORMATTER_OBJECT(nfo), attribute, zval_get_double(value)); - break; - default: - INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; - break; - } - - INTL_METHOD_CHECK_STATUS( nfo, "Error setting attribute value" ); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Get formatter attribute value. */ -PHP_FUNCTION( numfmt_set_text_attribute ) -{ - int32_t slength = 0; - UChar *svalue = NULL; - zend_long attribute; - char *value; - size_t len; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ols", - &object, NumberFormatter_ce_ptr, &attribute, &value, &len ) == FAILURE) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - /* Convert given attribute value to UTF-16. */ - intl_convert_utf8_to_utf16(&svalue, &slength, value, len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "Error converting attribute value to UTF-16" ); - - /* Actually set new attribute value. */ - unum_setTextAttribute(FORMATTER_OBJECT(nfo), attribute, svalue, slength, &INTL_DATA_ERROR_CODE(nfo)); - if (svalue) { - efree(svalue); - } - INTL_METHOD_CHECK_STATUS( nfo, "Error setting text attribute" ); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Get formatter symbol value. */ -PHP_FUNCTION( numfmt_get_symbol ) -{ - zend_long symbol; - UChar value_buf[4]; - UChar *value = value_buf; - uint32_t length = USIZE(value_buf); - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", - &object, NumberFormatter_ce_ptr, &symbol ) == FAILURE ) - { - RETURN_THROWS(); - } - - if(symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "numfmt_get_symbol: invalid symbol value", 0 ); - RETURN_FALSE; - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value_buf, length, &INTL_DATA_ERROR_CODE(nfo)); - if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { - ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ - INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; - value = eumalloc(length); - length = unum_getSymbol(FORMATTER_OBJECT(nfo), symbol, value, length, &INTL_DATA_ERROR_CODE(nfo)); - if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { - efree(value); - value = value_buf; - } - } - INTL_METHOD_CHECK_STATUS( nfo, "Error getting symbol value" ); - - INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value_buf != value ) ); -} -/* }}} */ - -/* {{{ Set formatter symbol value. */ -PHP_FUNCTION( numfmt_set_symbol ) -{ - zend_long symbol; - char* value = NULL; - size_t value_len = 0; - UChar* svalue = 0; - int32_t slength = 0; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ols", - &object, NumberFormatter_ce_ptr, &symbol, &value, &value_len ) == FAILURE ) - { - RETURN_THROWS(); - } - - if (symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "numfmt_set_symbol: invalid symbol value", 0 ); - RETURN_FALSE; - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - /* Convert given symbol to UTF-16. */ - intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "Error converting symbol value to UTF-16" ); - - /* Actually set the symbol. */ - unum_setSymbol(FORMATTER_OBJECT(nfo), symbol, svalue, slength, &INTL_DATA_ERROR_CODE(nfo)); - if (svalue) { - efree(svalue); - } - INTL_METHOD_CHECK_STATUS( nfo, "Error setting symbol value" ); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Get formatter pattern. */ -PHP_FUNCTION( numfmt_get_pattern ) -{ - UChar value_buf[64]; - uint32_t length = USIZE( value_buf ); - UChar* value = value_buf; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, NumberFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - length = unum_toPattern(FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo)); - if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { - ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ - INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; - value = eumalloc(length); - length = unum_toPattern( FORMATTER_OBJECT(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo) ); - if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { - efree(value); - value = value_buf; - } - } - INTL_METHOD_CHECK_STATUS( nfo, "Error getting formatter pattern" ); - - INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value != value_buf ) ); -} -/* }}} */ - -/* {{{ Set formatter pattern. */ -PHP_FUNCTION( numfmt_set_pattern ) -{ - char* value = NULL; - size_t value_len = 0; - int32_t slength = 0; - UChar* svalue = NULL; - UParseError spattern_error = {0}; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", - &object, NumberFormatter_ce_ptr, &value, &value_len ) == FAILURE ) - { - RETURN_THROWS(); - } - - FORMATTER_METHOD_FETCH_OBJECT; - - /* Convert given pattern to UTF-16. */ - intl_convert_utf8_to_utf16(&svalue, &slength, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "Error converting pattern to UTF-16" ); - - unum_applyPattern(FORMATTER_OBJECT(nfo), 0, svalue, slength, &spattern_error, &INTL_DATA_ERROR_CODE(nfo)); - if (svalue) { - efree(svalue); - } - if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { - char *msg; - spprintf(&msg, 0, "Error setting pattern value at line %d, offset %d", spattern_error.line, spattern_error.offset); - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), msg, 1); - efree(msg); - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Get formatter locale. */ -PHP_FUNCTION( numfmt_get_locale ) -{ - zend_long type = ULOC_ACTUAL_LOCALE; - char* loc; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O|l", - &object, NumberFormatter_ce_ptr, &type ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - loc = (char *)unum_getLocaleByType(FORMATTER_OBJECT(nfo), type, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "Error getting locale" ); - RETURN_STRING(loc); -} -/* }}} */ diff --git a/ext/intl/formatter/formatter_attr.cpp b/ext/intl/formatter/formatter_attr.cpp new file mode 100644 index 000000000000..d21873ecdabc --- /dev/null +++ b/ext/intl/formatter/formatter_attr.cpp @@ -0,0 +1,391 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" + +extern "C" { +#include "php_intl.h" +#include "intl_convert.h" +} + +#define FORMATTER_UNUM(nfo) reinterpret_cast(FORMATTER_OBJECT(nfo)) + +/* {{{ Get formatter attribute value. */ +U_CFUNC PHP_FUNCTION( numfmt_get_attribute ) +{ + zend_long lattribute, value; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", + &object, NumberFormatter_ce_ptr, &lattribute ) == FAILURE ) + { + RETURN_THROWS(); + } + + UNumberFormatAttribute attribute = static_cast(lattribute); + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + switch(attribute) { + case UNUM_PARSE_INT_ONLY: + case UNUM_GROUPING_USED: + case UNUM_DECIMAL_ALWAYS_SHOWN: + case UNUM_MAX_INTEGER_DIGITS: + case UNUM_MIN_INTEGER_DIGITS: + case UNUM_INTEGER_DIGITS: + case UNUM_MAX_FRACTION_DIGITS: + case UNUM_MIN_FRACTION_DIGITS: + case UNUM_FRACTION_DIGITS: + case UNUM_MULTIPLIER: + case UNUM_GROUPING_SIZE: + case UNUM_ROUNDING_MODE: + case UNUM_FORMAT_WIDTH: + case UNUM_PADDING_POSITION: + case UNUM_SECONDARY_GROUPING_SIZE: + case UNUM_SIGNIFICANT_DIGITS_USED: + case UNUM_MIN_SIGNIFICANT_DIGITS: + case UNUM_MAX_SIGNIFICANT_DIGITS: + case UNUM_LENIENT_PARSE: + value = unum_getAttribute(FORMATTER_UNUM(nfo), attribute); + if(value == -1) { + INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; + } else { + RETVAL_LONG(value); + } + break; + case UNUM_ROUNDING_INCREMENT: + { + double value_double = unum_getDoubleAttribute(FORMATTER_UNUM(nfo), attribute); + if(value_double == -1) { + INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; + } else { + RETVAL_DOUBLE(value_double); + } + } + break; + default: + INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; + break; + } + + INTL_METHOD_CHECK_STATUS( nfo, "Error getting attribute value" ); +} +/* }}} */ + +/* {{{ Get formatter attribute value. */ +U_CFUNC PHP_FUNCTION( numfmt_get_text_attribute ) +{ + zend_long lattribute; + UChar value_buf[64]; + int32_t value_buf_size = USIZE( value_buf ); + UChar* value = value_buf; + int32_t length = 0; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", + &object, NumberFormatter_ce_ptr, &lattribute ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + UNumberFormatTextAttribute attribute = static_cast(lattribute); + + length = unum_getTextAttribute( FORMATTER_UNUM(nfo), attribute, value, value_buf_size, &INTL_DATA_ERROR_CODE(nfo) ); + if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= value_buf_size) { + ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ + INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; + value = eumalloc(length); + length = unum_getTextAttribute( FORMATTER_UNUM(nfo), attribute, value, length, &INTL_DATA_ERROR_CODE(nfo) ); + if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + efree(value); + value = value_buf; + } + } + INTL_METHOD_CHECK_STATUS( nfo, "Error getting attribute value" ); + + INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value != value_buf ) ); +} +/* }}} */ + +/* {{{ Get formatter attribute value. */ +U_CFUNC PHP_FUNCTION( numfmt_set_attribute ) +{ + zend_long lattribute; + zval *value; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oln", + &object, NumberFormatter_ce_ptr, &lattribute, &value ) == FAILURE) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + UNumberFormatAttribute attribute = static_cast(lattribute); + + switch(attribute) { + case UNUM_PARSE_INT_ONLY: + case UNUM_GROUPING_USED: + case UNUM_DECIMAL_ALWAYS_SHOWN: + case UNUM_MAX_INTEGER_DIGITS: + case UNUM_MIN_INTEGER_DIGITS: + case UNUM_INTEGER_DIGITS: + case UNUM_MAX_FRACTION_DIGITS: + case UNUM_MIN_FRACTION_DIGITS: + case UNUM_FRACTION_DIGITS: + case UNUM_MULTIPLIER: + case UNUM_GROUPING_SIZE: + case UNUM_ROUNDING_MODE: + case UNUM_FORMAT_WIDTH: + case UNUM_PADDING_POSITION: + case UNUM_SECONDARY_GROUPING_SIZE: + case UNUM_SIGNIFICANT_DIGITS_USED: + case UNUM_MIN_SIGNIFICANT_DIGITS: + case UNUM_MAX_SIGNIFICANT_DIGITS: + case UNUM_LENIENT_PARSE: + unum_setAttribute(FORMATTER_UNUM(nfo), attribute, zval_get_long(value)); + break; + case UNUM_ROUNDING_INCREMENT: + unum_setDoubleAttribute(FORMATTER_UNUM(nfo), attribute, zval_get_double(value)); + break; + default: + INTL_DATA_ERROR_CODE(nfo) = U_UNSUPPORTED_ERROR; + break; + } + + INTL_METHOD_CHECK_STATUS( nfo, "Error setting attribute value" ); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get formatter attribute value. */ +U_CFUNC PHP_FUNCTION( numfmt_set_text_attribute ) +{ + zend_long attribute; + char *value; + size_t len; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ols", + &object, NumberFormatter_ce_ptr, &attribute, &value, &len ) == FAILURE) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + /* Convert given attribute value to UTF-16. */ + UnicodeString svalue; + intl_stringFromChar(svalue, value, len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Error converting attribute value to UTF-16" ); + + /* Actually set new attribute value. */ + unum_setTextAttribute(FORMATTER_UNUM(nfo), static_cast(attribute), svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Error setting text attribute" ); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get formatter symbol value. */ +U_CFUNC PHP_FUNCTION( numfmt_get_symbol ) +{ + zend_long lsymbol; + UChar value_buf[4]; + UChar *value = value_buf; + uint32_t length = USIZE(value_buf); + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ol", + &object, NumberFormatter_ce_ptr, &lsymbol ) == FAILURE ) + { + RETURN_THROWS(); + } + + UNumberFormatSymbol symbol = static_cast(lsymbol); + + if(symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid symbol value"); + RETURN_FALSE; + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + length = unum_getSymbol(FORMATTER_UNUM(nfo), symbol, value_buf, length, &INTL_DATA_ERROR_CODE(nfo)); + if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { + ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ + INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; + value = eumalloc(length); + length = unum_getSymbol(FORMATTER_UNUM(nfo), symbol, value, length, &INTL_DATA_ERROR_CODE(nfo)); + if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + efree(value); + value = value_buf; + } + } + INTL_METHOD_CHECK_STATUS( nfo, "Error getting symbol value" ); + + INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value_buf != value ) ); +} +/* }}} */ + +/* {{{ Set formatter symbol value. */ +U_CFUNC PHP_FUNCTION( numfmt_set_symbol ) +{ + zend_long lsymbol; + char* value = NULL; + size_t value_len = 0; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ols", + &object, NumberFormatter_ce_ptr, &lsymbol, &value, &value_len ) == FAILURE ) + { + RETURN_THROWS(); + } + + UNumberFormatSymbol symbol = static_cast(lsymbol); + + if (symbol >= UNUM_FORMAT_SYMBOL_COUNT || symbol < 0) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "invalid symbol value"); + RETURN_FALSE; + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + /* Convert given symbol to UTF-16. */ + UnicodeString svalue; + intl_stringFromChar(svalue, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Error converting symbol value to UTF-16" ); + + /* Actually set the symbol. */ + unum_setSymbol(FORMATTER_UNUM(nfo), symbol, svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Error setting symbol value" ); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get formatter pattern. */ +U_CFUNC PHP_FUNCTION( numfmt_get_pattern ) +{ + UChar value_buf[64]; + uint32_t length = USIZE( value_buf ); + UChar* value = value_buf; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, NumberFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + length = unum_toPattern(FORMATTER_UNUM(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo)); + if(INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR && length >= USIZE( value_buf )) { + ++length; /* to avoid U_STRING_NOT_TERMINATED_WARNING */ + INTL_DATA_ERROR_CODE(nfo) = U_ZERO_ERROR; + value = eumalloc(length); + length = unum_toPattern( FORMATTER_UNUM(nfo), 0, value, length, &INTL_DATA_ERROR_CODE(nfo) ); + if(U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + efree(value); + value = value_buf; + } + } + INTL_METHOD_CHECK_STATUS( nfo, "Error getting formatter pattern" ); + + INTL_METHOD_RETVAL_UTF8( nfo, value, length, ( value != value_buf ) ); +} +/* }}} */ + +/* {{{ Set formatter pattern. */ +U_CFUNC PHP_FUNCTION( numfmt_set_pattern ) +{ + char* value = NULL; + size_t value_len = 0; + UParseError spattern_error = {0}; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", + &object, NumberFormatter_ce_ptr, &value, &value_len ) == FAILURE ) + { + RETURN_THROWS(); + } + + FORMATTER_METHOD_FETCH_OBJECT; + + /* Convert given pattern to UTF-16. */ + UnicodeString svalue; + intl_stringFromChar(svalue, value, value_len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Error converting pattern to UTF-16" ); + + unum_applyPattern(FORMATTER_UNUM(nfo), 0, svalue.getBuffer(), svalue.length(), &spattern_error, &INTL_DATA_ERROR_CODE(nfo)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + char *msg; + spprintf(&msg, 0, "Error setting pattern value at line %d, offset %d", spattern_error.line, spattern_error.offset); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), msg); + efree(msg); + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get formatter locale. */ +U_CFUNC PHP_FUNCTION( numfmt_get_locale ) +{ + zend_long type = ULOC_ACTUAL_LOCALE; + const char* loc; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O|l", + &object, NumberFormatter_ce_ptr, &type ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + loc = unum_getLocaleByType(FORMATTER_UNUM(nfo), static_cast(type), &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Error getting locale" ); + RETURN_STRING(loc); +} +/* }}} */ diff --git a/ext/intl/formatter/formatter_class.c b/ext/intl/formatter/formatter_class.c deleted file mode 100644 index 7832824c94e1..000000000000 --- a/ext/intl/formatter/formatter_class.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#include - -#include "formatter_class.h" -#include "php_intl.h" -#include "formatter_data.h" -#include "formatter_format.h" - -#include -#include "Zend/zend_attributes.h" -#include "Zend/zend_interfaces.h" - -#include "formatter_arginfo.h" - -zend_class_entry *NumberFormatter_ce_ptr = NULL; -static zend_object_handlers NumberFormatter_handlers; - -/* - * Auxiliary functions needed by objects of 'NumberFormatter' class - */ - -/* {{{ NumberFormatter_objects_free */ -void NumberFormatter_object_free( zend_object *object ) -{ - NumberFormatter_object* nfo = php_intl_number_format_fetch_object(object); - - zend_object_std_dtor( &nfo->zo ); - - formatter_data_free( &nfo->nf_data ); -} -/* }}} */ - -/* {{{ NumberFormatter_object_create */ -zend_object *NumberFormatter_object_create(zend_class_entry *ce) -{ - NumberFormatter_object* intern; - - intern = zend_object_alloc(sizeof(NumberFormatter_object), ce); - formatter_data_init( &intern->nf_data ); - zend_object_std_init( &intern->zo, ce ); - object_properties_init(&intern->zo, ce); - - return &intern->zo; -} -/* }}} */ - -/* {{{ NumberFormatter_object_clone */ -zend_object *NumberFormatter_object_clone(zend_object *object) -{ - NumberFormatter_object *nfo = php_intl_number_format_fetch_object(object); - zend_object *new_obj = NumberFormatter_ce_ptr->create_object(object->ce); - NumberFormatter_object *new_nfo = php_intl_number_format_fetch_object(new_obj); - - /* clone standard parts */ - zend_objects_clone_members(&new_nfo->zo, &nfo->zo); - - /* clone formatter object. It may fail, the destruction code must handle this case */ - if (FORMATTER_OBJECT(nfo) != NULL) { - UErrorCode error = U_ZERO_ERROR; - FORMATTER_OBJECT(new_nfo) = unum_clone(FORMATTER_OBJECT(nfo), &error); - if (U_FAILURE(error)) { - zend_throw_error(NULL, "Failed to clone NumberFormatter"); - } - } else { - zend_throw_error(NULL, "Cannot clone uninitialized NumberFormatter"); - } - return new_obj; -} -/* }}} */ - -/* - * 'NumberFormatter' class registration structures & functions - */ - -/* {{{ formatter_register_class - * Initialize 'NumberFormatter' class - */ -void formatter_register_class( void ) -{ - /* Create and register 'NumberFormatter' class. */ - NumberFormatter_ce_ptr = register_class_NumberFormatter(); - NumberFormatter_ce_ptr->create_object = NumberFormatter_object_create; - NumberFormatter_ce_ptr->default_object_handlers = &NumberFormatter_handlers; - - memcpy(&NumberFormatter_handlers, &std_object_handlers, - sizeof(NumberFormatter_handlers)); - NumberFormatter_handlers.offset = XtOffsetOf(NumberFormatter_object, zo); - NumberFormatter_handlers.clone_obj = NumberFormatter_object_clone; - NumberFormatter_handlers.free_obj = NumberFormatter_object_free; -} -/* }}} */ diff --git a/ext/intl/formatter/formatter_class.cpp b/ext/intl/formatter/formatter_class.cpp new file mode 100644 index 000000000000..5b82b53c6d62 --- /dev/null +++ b/ext/intl/formatter/formatter_class.cpp @@ -0,0 +1,105 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#include "formatter_class.h" +extern "C" { +#include "php_intl.h" +#include "formatter_data.h" +#include "formatter_format.h" +} + +#include +#include "Zend/zend_attributes.h" +#include "Zend/zend_interfaces.h" + +extern "C" { +#include "formatter_arginfo.h" +} + +zend_class_entry *NumberFormatter_ce_ptr = NULL; +static zend_object_handlers NumberFormatter_handlers; + +/* + * Auxiliary functions needed by objects of 'NumberFormatter' class + */ + +/* {{{ NumberFormatter_objects_free */ +U_CFUNC void NumberFormatter_object_free( zend_object *object ) +{ + NumberFormatter_object* nfo = php_intl_number_format_fetch_object(object); + + zend_object_std_dtor( &nfo->zo ); + + formatter_data_free( &nfo->nf_data ); +} +/* }}} */ + +/* {{{ NumberFormatter_object_create */ +U_CFUNC zend_object *NumberFormatter_object_create(zend_class_entry *ce) +{ + NumberFormatter_object* intern; + + intern = reinterpret_cast(zend_object_alloc(sizeof(NumberFormatter_object), ce)); + formatter_data_init( &intern->nf_data ); + zend_object_std_init( &intern->zo, ce ); + object_properties_init(&intern->zo, ce); + + return &intern->zo; +} +/* }}} */ + +/* {{{ NumberFormatter_object_clone */ +U_CFUNC zend_object *NumberFormatter_object_clone(zend_object *object) +{ + const NumberFormatter_object *nfo = php_intl_number_format_fetch_object(object); + zend_object *new_obj = NumberFormatter_ce_ptr->create_object(object->ce); + NumberFormatter_object *new_nfo = php_intl_number_format_fetch_object(new_obj); + + /* clone standard parts */ + zend_objects_clone_members(&new_nfo->zo, &nfo->zo); + + /* clone formatter object. It may fail, the destruction code must handle this case */ + if (FORMATTER_OBJECT(nfo) != nullptr) { + FORMATTER_OBJECT(new_nfo) = FORMATTER_OBJECT(nfo)->clone(); + if (FORMATTER_OBJECT(new_nfo) == nullptr) { + zend_throw_error(NULL, "Failed to clone NumberFormatter"); + } + } else { + zend_throw_error(NULL, "Cannot clone uninitialized NumberFormatter"); + } + return new_obj; +} +/* }}} */ + +/* + * 'NumberFormatter' class registration structures & functions + */ + +/* {{{ formatter_register_class + * Initialize 'NumberFormatter' class + */ +U_CFUNC void formatter_register_class( void ) +{ + /* Create and register 'NumberFormatter' class. */ + NumberFormatter_ce_ptr = register_class_NumberFormatter(); + NumberFormatter_ce_ptr->create_object = NumberFormatter_object_create; + NumberFormatter_ce_ptr->default_object_handlers = &NumberFormatter_handlers; + + memcpy(&NumberFormatter_handlers, &std_object_handlers, + sizeof(NumberFormatter_handlers)); + NumberFormatter_handlers.offset = offsetof(NumberFormatter_object, zo); + NumberFormatter_handlers.clone_obj = NumberFormatter_object_clone; + NumberFormatter_handlers.free_obj = NumberFormatter_object_free; +} +/* }}} */ diff --git a/ext/intl/formatter/formatter_class.h b/ext/intl/formatter/formatter_class.h index f7da2b220191..e7f4780bb3bd 100644 --- a/ext/intl/formatter/formatter_class.h +++ b/ext/intl/formatter/formatter_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -15,12 +15,17 @@ #ifndef FORMATTER_CLASS_H #define FORMATTER_CLASS_H -#include +#include "formatter_data.h" +#ifdef __cplusplus +extern "C" { +#endif #include "intl_common.h" #include "intl_error.h" #include "intl_data.h" -#include "formatter_data.h" +#ifdef __cplusplus +} +#endif typedef struct { formatter_data nf_data; @@ -28,12 +33,18 @@ typedef struct { } NumberFormatter_object; static inline NumberFormatter_object *php_intl_number_format_fetch_object(zend_object *obj) { - return (NumberFormatter_object *)((char*)(obj) - XtOffsetOf(NumberFormatter_object, zo)); + return ZEND_CONTAINER_OF(obj, NumberFormatter_object, zo); } #define Z_INTL_NUMBERFORMATTER_P(zv) php_intl_number_format_fetch_object(Z_OBJ_P(zv)) +#ifdef __cplusplus +extern "C" { +#endif void formatter_register_class( void ); extern zend_class_entry *NumberFormatter_ce_ptr; +#ifdef __cplusplus +} +#endif /* Auxiliary macros */ diff --git a/ext/intl/formatter/formatter_data.c b/ext/intl/formatter/formatter_data.c deleted file mode 100644 index 57dbc8bde6b5..000000000000 --- a/ext/intl/formatter/formatter_data.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "formatter_data.h" - -/* {{{ void formatter_data_init( formatter_data* nf_data ) - * Initialize internals of formatter_data. - */ -void formatter_data_init( formatter_data* nf_data ) -{ - if( !nf_data ) - return; - - nf_data->unum = NULL; - intl_error_reset( &nf_data->error ); -} -/* }}} */ - -/* {{{ void formatter_data_free( formatter_data* nf_data ) - * Clean up mem allocted by internals of formatter_data - */ -void formatter_data_free( formatter_data* nf_data ) -{ - if( !nf_data ) - return; - - if( nf_data->unum ) - unum_close( nf_data->unum ); - - nf_data->unum = NULL; - intl_error_reset( &nf_data->error ); -} -/* }}} */ - -/* {{{ formatter_data* formatter_data_create() - * Alloc mem for formatter_data and initialize it with default values. - */ -formatter_data* formatter_data_create( void ) -{ - formatter_data* nf_data = ecalloc( 1, sizeof(formatter_data) ); - - formatter_data_init( nf_data ); - - return nf_data; -} -/* }}} */ diff --git a/ext/intl/formatter/formatter_data.cpp b/ext/intl/formatter/formatter_data.cpp new file mode 100644 index 000000000000..506972e72088 --- /dev/null +++ b/ext/intl/formatter/formatter_data.cpp @@ -0,0 +1,59 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "formatter_data.h" + +/* {{{ void formatter_data_init( formatter_data* nf_data ) + * Initialize internals of formatter_data. + */ +void formatter_data_init( formatter_data* nf_data ) +{ + if( !nf_data ) + return; + + nf_data->unum = nullptr; + intl_error_reset( &nf_data->error ); +} +/* }}} */ + +/* {{{ void formatter_data_free( formatter_data* nf_data ) + * Clean up mem allocated by internals of formatter_data + */ +void formatter_data_free( formatter_data* nf_data ) +{ + if( !nf_data ) + return; + + delete nf_data->unum; + nf_data->unum = nullptr; + intl_error_reset( &nf_data->error ); +} +/* }}} */ + +/* {{{ formatter_data* formatter_data_create() + * Alloc mem for formatter_data and initialize it with default values. + */ +formatter_data* formatter_data_create( void ) +{ + formatter_data* nf_data = reinterpret_cast(ecalloc( 1, sizeof(formatter_data) )); + + formatter_data_init( nf_data ); + + return nf_data; +} +/* }}} */ diff --git a/ext/intl/formatter/formatter_data.h b/ext/intl/formatter/formatter_data.h index 817ad0d6055f..1208970471bf 100644 --- a/ext/intl/formatter/formatter_data.h +++ b/ext/intl/formatter/formatter_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -15,22 +15,46 @@ #ifndef FORMATTER_DATA_H #define FORMATTER_DATA_H +#ifdef __cplusplus +extern "C" { +#endif #include +#ifdef __cplusplus +} +#endif + +#include -#include +#ifdef __cplusplus +using icu::NumberFormat; +#else +typedef void NumberFormat; +#endif +#ifdef __cplusplus +extern "C" { +#endif #include "intl_error.h" +#ifdef __cplusplus +} +#endif typedef struct { // error hangling intl_error error; // formatter handling - UNumberFormat* unum; + NumberFormat* unum; } formatter_data; +#ifdef __cplusplus +extern "C" { +#endif formatter_data* formatter_data_create( void ); void formatter_data_init( formatter_data* nf_data ); void formatter_data_free( formatter_data* nf_data ); +#ifdef __cplusplus +} +#endif #endif // FORMATTER_DATA_H diff --git a/ext/intl/formatter/formatter_format.c b/ext/intl/formatter/formatter_format.c deleted file mode 100644 index 0323757ed862..000000000000 --- a/ext/intl/formatter/formatter_format.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" - -#include - -#include "formatter_class.h" -#include "formatter_format.h" -#include "intl_convert.h" - -/* {{{ Format a number. */ -PHP_FUNCTION( numfmt_format ) -{ - zval *number; - zend_long type = FORMAT_TYPE_DEFAULT; - UChar format_buf[32]; - UChar* formatted = format_buf; - int32_t formatted_len = USIZE(format_buf); - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "On|l", - &object, NumberFormatter_ce_ptr, &number, &type ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - if(type == FORMAT_TYPE_DEFAULT) { - switch(Z_TYPE_P(number)) { - case IS_LONG: - /* take INT32 on 32-bit, int64 on 64-bit */ - type = (sizeof(zend_long) == 8)?FORMAT_TYPE_INT64:FORMAT_TYPE_INT32; - break; - case IS_DOUBLE: - type = FORMAT_TYPE_DOUBLE; - break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - } - - switch(type) { - case FORMAT_TYPE_INT32: - convert_to_long(number); - formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), - formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - formatted_len = unum_format(FORMATTER_OBJECT(nfo), (int32_t)Z_LVAL_P(number), - formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { - efree(formatted); - } - } - INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); - break; - - case FORMAT_TYPE_INT64: - { - int64_t value = (Z_TYPE_P(number) == IS_DOUBLE)?(int64_t)Z_DVAL_P(number):Z_LVAL_P(number); - formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - formatted_len = unum_formatInt64(FORMATTER_OBJECT(nfo), value, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { - efree(formatted); - } - } - INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); - } - break; - - case FORMAT_TYPE_DOUBLE: - convert_to_double(number); - formatted_len = unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - unum_formatDouble(FORMATTER_OBJECT(nfo), Z_DVAL_P(number), formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - if (U_FAILURE( INTL_DATA_ERROR_CODE(nfo) ) ) { - efree(formatted); - } - } - INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); - break; - case FORMAT_TYPE_CURRENCY: - if (getThis()) { - const char *space; - const char *class_name = get_active_class_name(&space); - zend_argument_value_error(2, "cannot be NumberFormatter::TYPE_CURRENCY constant, " - "use %s%sformatCurrency() method instead", class_name, space); - } else { - zend_argument_value_error(3, "cannot be NumberFormatter::TYPE_CURRENCY constant, use numfmt_format_currency() function instead"); - } - RETURN_THROWS(); - default: - zend_argument_value_error(hasThis() ? 2 : 3, "must be a NumberFormatter::TYPE_* constant"); - RETURN_THROWS(); - } - - INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) ); -} -/* }}} */ - -/* {{{ Format a number as currency. */ -PHP_FUNCTION( numfmt_format_currency ) -{ - double number; - UChar format_buf[32]; - UChar* formatted = format_buf; - int32_t formatted_len = USIZE(format_buf); - char* currency = NULL; - size_t currency_len = 0; - UChar* scurrency = NULL; - int32_t scurrency_len = 0; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ods", - &object, NumberFormatter_ce_ptr, &number, ¤cy, ¤cy_len ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - /* Convert currency to UTF-16. */ - intl_convert_utf8_to_utf16(&scurrency, &scurrency_len, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" ); - - /* Format the number using a fixed-length buffer. */ - formatted_len = unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - - /* If the buffer turned out to be too small - * then allocate another buffer dynamically - * and use it to format the number. - */ - if (INTL_DATA_ERROR_CODE(nfo) == U_BUFFER_OVERFLOW_ERROR) { - intl_error_reset(INTL_DATA_ERROR_P(nfo)); - formatted = eumalloc(formatted_len); - unum_formatDoubleCurrency(FORMATTER_OBJECT(nfo), number, scurrency, formatted, formatted_len, NULL, &INTL_DATA_ERROR_CODE(nfo)); - } - - if( U_FAILURE( INTL_DATA_ERROR_CODE((nfo)) ) ) { - intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((nfo)) ); - intl_errors_set_custom_msg( INTL_DATA_ERROR_P(nfo), "Number formatting failed", 0 ); - RETVAL_FALSE; - if (formatted != format_buf) { - efree(formatted); - } - } else { - INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) ); - } - - if(scurrency) { - efree(scurrency); - } -} - -/* }}} */ diff --git a/ext/intl/formatter/formatter_format.cpp b/ext/intl/formatter/formatter_format.cpp new file mode 100644 index 000000000000..48edabc8ccde --- /dev/null +++ b/ext/intl/formatter/formatter_format.cpp @@ -0,0 +1,149 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" +#include "formatter_format.h" + +extern "C" { +#include "php_intl.h" +} + +/* {{{ Format a number. */ +U_CFUNC PHP_FUNCTION( numfmt_format ) +{ + zval *number; + zend_long type = FORMAT_TYPE_DEFAULT; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "On|l", + &object, NumberFormatter_ce_ptr, &number, &type ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + if(type == FORMAT_TYPE_DEFAULT) { + switch(Z_TYPE_P(number)) { + case IS_LONG: + /* take INT32 on 32-bit, int64 on 64-bit */ + type = (sizeof(zend_long) == 8)?FORMAT_TYPE_INT64:FORMAT_TYPE_INT32; + break; + case IS_DOUBLE: + type = FORMAT_TYPE_DOUBLE; + break; + default: ZEND_UNREACHABLE(); + } + } + + icu::UnicodeString result; + icu::FieldPosition pos; + + switch(type) { + case FORMAT_TYPE_INT32: + convert_to_long(number); + FORMATTER_OBJECT(nfo)->format((int32_t)Z_LVAL_P(number), result, pos, INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + break; + + case FORMAT_TYPE_INT64: + { + int64_t value = (Z_TYPE_P(number) == IS_DOUBLE)?(int64_t)Z_DVAL_P(number):Z_LVAL_P(number); + FORMATTER_OBJECT(nfo)->format(value, result, pos, INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + } + break; + + case FORMAT_TYPE_DOUBLE: + convert_to_double(number); + FORMATTER_OBJECT(nfo)->format(Z_DVAL_P(number), result, pos, INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Number formatting failed" ); + break; + case FORMAT_TYPE_CURRENCY: + if (hasThis()) { + const char *space; + const char *class_name = get_active_class_name(&space); + zend_argument_value_error(2, "cannot be NumberFormatter::TYPE_CURRENCY constant, " + "use %s%sformatCurrency() method instead", class_name, space); + } else { + zend_argument_value_error(3, "cannot be NumberFormatter::TYPE_CURRENCY constant, use numfmt_format_currency() function instead"); + } + RETURN_THROWS(); + default: + zend_argument_value_error(hasThis() ? 2 : 3, "must be a NumberFormatter::TYPE_* constant"); + RETURN_THROWS(); + } + + zend_string *u8str = intl_charFromString(result, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS(nfo, "Error converting result to UTF-8"); + RETVAL_STR(u8str); +} +/* }}} */ + +/* {{{ Format a number as currency. */ +U_CFUNC PHP_FUNCTION( numfmt_format_currency ) +{ + double number; + char* currency = NULL; + size_t currency_len = 0; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Ods", + &object, NumberFormatter_ce_ptr, &number, ¤cy, ¤cy_len ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + /* Convert currency to UTF-16. */ + icu::UnicodeString ucurrency; + intl_stringFromChar(ucurrency, currency, currency_len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-16 failed" ); + + /* Format using CurrencyAmount. */ + icu::CurrencyAmount *currAmt = new icu::CurrencyAmount(number, ucurrency.getTerminatedBuffer(), INTL_DATA_ERROR_CODE(nfo)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + delete currAmt; + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), "Number formatting failed"); + RETURN_FALSE; + } + icu::Formattable fmt; + fmt.adoptObject(currAmt); + icu::UnicodeString result; + icu::FieldPosition pos; + FORMATTER_OBJECT(nfo)->format(fmt, result, pos, INTL_DATA_ERROR_CODE(nfo)); + + if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(nfo), "Number formatting failed"); + RETURN_FALSE; + } + + zend_string *u8str = intl_charFromString(result, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS(nfo, "Error converting result to UTF-8"); + RETVAL_STR(u8str); +} + +/* }}} */ diff --git a/ext/intl/formatter/formatter_format.h b/ext/intl/formatter/formatter_format.h index 0238d5d4b8b0..14aa91193ba2 100644 --- a/ext/intl/formatter/formatter_format.h +++ b/ext/intl/formatter/formatter_format.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/formatter/formatter_main.c b/ext/intl/formatter/formatter_main.c deleted file mode 100644 index 6f8fb98d2143..000000000000 --- a/ext/intl/formatter/formatter_main.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "php_intl.h" -#include "formatter_class.h" -#include "intl_convert.h" - -/* {{{ */ -static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) -{ - char* locale; - char* pattern = NULL; - size_t locale_len = 0, pattern_len = 0; - zend_long style; - UChar* spattern = NULL; - int32_t spattern_len = 0; - FORMATTER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(locale, locale_len) - Z_PARAM_LONG(style) - Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(pattern, pattern_len) - ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - } - - INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); - object = return_value; - FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; - if (FORMATTER_OBJECT(nfo)) { - zend_throw_error(NULL, "NumberFormatter object is already constructed"); - return FAILURE; - } - - /* Convert pattern (if specified) to UTF-16. */ - if(pattern && pattern_len) { - intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: error converting pattern to UTF-16"); - } - - if(locale_len == 0) { - locale = (char *)intl_locale_get_default(); - } - - if (strlen(uloc_getISO3Language(locale)) == 0) { - zend_argument_value_error(1, "\"%s\" is invalid", locale); - return FAILURE; - } - - /* Create an ICU number formatter. */ - FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo)); - - if(spattern) { - efree(spattern); - } - - INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed"); - return SUCCESS; -} -/* }}} */ - -/* {{{ Create number formatter. */ -PHP_FUNCTION( numfmt_create ) -{ - object_init_ex( return_value, NumberFormatter_ce_ptr ); - if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { - zval_ptr_dtor(return_value); - RETURN_NULL(); - } -} -/* }}} */ - -/* {{{ NumberFormatter object constructor. */ -PHP_METHOD( NumberFormatter, __construct ) -{ - zend_error_handling error_handling; - bool error_handling_replaced = 0; - - return_value = ZEND_THIS; - if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { - if (!EG(exception)) { - zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); - } -} -/* }}} */ - -/* {{{ Get formatter's last error code. */ -PHP_FUNCTION( numfmt_get_error_code ) -{ - FORMATTER_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, NumberFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - nfo = Z_INTL_NUMBERFORMATTER_P(object); - - /* Return formatter's last error code. */ - RETURN_LONG( INTL_DATA_ERROR_CODE(nfo) ); -} -/* }}} */ - -/* {{{ Get text description for formatter's last error code. */ -PHP_FUNCTION( numfmt_get_error_message ) -{ - zend_string *message = NULL; - FORMATTER_METHOD_INIT_VARS - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, NumberFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - nfo = Z_INTL_NUMBERFORMATTER_P(object); - - /* Return last error message. */ - message = intl_error_get_message( INTL_DATA_ERROR_P(nfo) ); - RETURN_STR(message); -} -/* }}} */ diff --git a/ext/intl/formatter/formatter_main.cpp b/ext/intl/formatter/formatter_main.cpp new file mode 100644 index 000000000000..79750714a5f0 --- /dev/null +++ b/ext/intl/formatter/formatter_main.cpp @@ -0,0 +1,199 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" + +extern "C" { +#include "php_intl.h" +} + +/* {{{ */ +static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +{ + char* locale; + char* pattern = NULL; + size_t locale_len = 0, pattern_len = 0; + zend_long style; + UnicodeString upattern; + FORMATTER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STRING(locale, locale_len) + Z_PARAM_LONG(style) + Z_PARAM_OPTIONAL + Z_PARAM_STRING_OR_NULL(pattern, pattern_len) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); + object = return_value; + FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK; + if (FORMATTER_OBJECT(nfo)) { + zend_throw_error(NULL, "NumberFormatter object is already constructed"); + return FAILURE; + } + + /* Convert pattern (if specified) to UTF-16. */ + if(pattern && pattern_len) { + intl_stringFromChar(upattern, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_CTOR_CHECK_STATUS(nfo, "error converting pattern to UTF-16"); + } + + if(locale_len == 0) { + locale = (char *)intl_locale_get_default(); + } + + if (icu::Locale(locale).getISO3Language()[0] == '\0') { + zend_argument_value_error(1, "\"%s\" is invalid", locale); + return FAILURE; + } + + char* canonicalized_locale = canonicalize_locale_string(locale); + const char* final_locale = canonicalized_locale ? canonicalized_locale : locale; + + /* Create an ICU number formatter. */ + icu::Locale loc(final_locale); + switch (style) { + case UNUM_PATTERN_DECIMAL: { + icu::DecimalFormatSymbols *syms = new icu::DecimalFormatSymbols(loc, INTL_DATA_ERROR_CODE(nfo)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(nfo))) { + delete syms; + break; + } + FORMATTER_OBJECT(nfo) = new icu::DecimalFormat(upattern, syms, INTL_DATA_ERROR_CODE(nfo)); + if (FORMATTER_OBJECT(nfo) == nullptr) { + delete syms; + } + break; + } + case UNUM_PATTERN_RULEBASED: { + UParseError parseError; + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(upattern, loc, parseError, INTL_DATA_ERROR_CODE(nfo)); + break; + } + case UNUM_SPELLOUT: + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_SPELLOUT, loc, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_ORDINAL: + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_ORDINAL, loc, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_DURATION: + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_DURATION, loc, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_NUMBERING_SYSTEM: { + UErrorCode localErr = U_ZERO_ERROR; + int32_t keywordLength = loc.getKeywordValue("numbers", nullptr, 0, localErr); + if (keywordLength > 0) { + FORMATTER_OBJECT(nfo) = NumberFormat::createInstance(loc, UNUM_DEFAULT, INTL_DATA_ERROR_CODE(nfo)); + } else { + FORMATTER_OBJECT(nfo) = new icu::RuleBasedNumberFormat(icu::URBNF_NUMBERING_SYSTEM, loc, INTL_DATA_ERROR_CODE(nfo)); + } + break; + } + case UNUM_DECIMAL_COMPACT_SHORT: + FORMATTER_OBJECT(nfo) = icu::CompactDecimalFormat::createInstance(loc, UNUM_SHORT, INTL_DATA_ERROR_CODE(nfo)); + break; + case UNUM_DECIMAL_COMPACT_LONG: + FORMATTER_OBJECT(nfo) = icu::CompactDecimalFormat::createInstance(loc, UNUM_LONG, INTL_DATA_ERROR_CODE(nfo)); + break; + default: + FORMATTER_OBJECT(nfo) = NumberFormat::createInstance(loc, static_cast(style), INTL_DATA_ERROR_CODE(nfo)); + break; + } + + if (canonicalized_locale) { + efree(canonicalized_locale); + } + + INTL_CTOR_CHECK_STATUS(nfo, "number formatter creation failed"); + return SUCCESS; +} +/* }}} */ + +/* {{{ Create number formatter. */ +U_CFUNC PHP_FUNCTION( numfmt_create ) +{ + object_init_ex( return_value, NumberFormatter_ce_ptr ); + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + zval_ptr_dtor(return_value); + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ NumberFormatter object constructor. */ +U_CFUNC PHP_METHOD( NumberFormatter, __construct ) +{ + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + + return_value = ZEND_THIS; + if (numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); + } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; +} +/* }}} */ + +/* {{{ Get formatter's last error code. */ +U_CFUNC PHP_FUNCTION( numfmt_get_error_code ) +{ + FORMATTER_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, NumberFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + nfo = Z_INTL_NUMBERFORMATTER_P(object); + + /* Return formatter's last error code. */ + RETURN_LONG( INTL_DATA_ERROR_CODE(nfo) ); +} +/* }}} */ + +/* {{{ Get text description for formatter's last error code. */ +U_CFUNC PHP_FUNCTION( numfmt_get_error_message ) +{ + zend_string *message = NULL; + FORMATTER_METHOD_INIT_VARS + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, NumberFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + nfo = Z_INTL_NUMBERFORMATTER_P(object); + + /* Return last error message. */ + message = intl_error_get_message( INTL_DATA_ERROR_P(nfo) ); + RETURN_STR(message); +} +/* }}} */ diff --git a/ext/intl/formatter/formatter_parse.c b/ext/intl/formatter/formatter_parse.c deleted file mode 100644 index 993990065040..000000000000 --- a/ext/intl/formatter/formatter_parse.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" - -#include -#include - -#include "formatter_class.h" -#include "formatter_format.h" -#include "intl_convert.h" - -#define ICU_LOCALE_BUG 1 - -/* {{{ Parse a number. */ -PHP_FUNCTION( numfmt_parse ) -{ - zend_long type = FORMAT_TYPE_DOUBLE; - UChar* sstr = NULL; - int32_t sstr_len = 0; - char* str = NULL; - size_t str_len; - int32_t val32, position = 0; - int64_t val64; - double val_double; - int32_t* position_p = NULL; - zval *zposition = NULL; - char *oldlocale; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if (zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|lz!", - &object, NumberFormatter_ce_ptr, &str, &str_len, &type, &zposition ) == FAILURE ) - { - RETURN_THROWS(); - } - - if (zposition) { - position = (int32_t) zval_get_long(zposition); - position_p = &position; - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - /* Convert given string to UTF-16. */ - intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" ); - -#if ICU_LOCALE_BUG && defined(LC_NUMERIC) - /* need to copy here since setlocale may change it later */ - oldlocale = estrdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, "C"); -#endif - - switch(type) { - case FORMAT_TYPE_INT32: - val32 = unum_parse(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo)); - RETVAL_LONG(val32); - break; - case FORMAT_TYPE_INT64: - val64 = unum_parseInt64(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo)); - if(val64 > ZEND_LONG_MAX || val64 < ZEND_LONG_MIN) { - RETVAL_DOUBLE(val64); - } else { - RETVAL_LONG((zend_long)val64); - } - break; - case FORMAT_TYPE_DOUBLE: - val_double = unum_parseDouble(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, &INTL_DATA_ERROR_CODE(nfo)); - RETVAL_DOUBLE(val_double); - break; - case FORMAT_TYPE_CURRENCY: - if (getThis()) { - const char *space; - const char *class_name = get_active_class_name(&space); - zend_argument_value_error(2, "cannot be NumberFormatter::TYPE_CURRENCY constant, " - "use %s%sparseCurrency() method instead", class_name, space); - } else { - zend_argument_value_error(3, "cannot be NumberFormatter::TYPE_CURRENCY constant, use numfmt_parse_currency() function instead"); - } - goto cleanup; - default: - zend_argument_value_error(hasThis() ? 2 : 3, "must be a NumberFormatter::TYPE_* constant"); - goto cleanup; - } - - if (zposition) { - ZEND_TRY_ASSIGN_REF_LONG(zposition, position); - } - -cleanup: - -#if ICU_LOCALE_BUG && defined(LC_NUMERIC) - setlocale(LC_NUMERIC, oldlocale); - efree(oldlocale); -#endif - - if (sstr) { - efree(sstr); - } - - INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); -} -/* }}} */ - -/* {{{ Parse a number as currency. */ -PHP_FUNCTION( numfmt_parse_currency ) -{ - double number; - UChar currency[5] = {0}; - UChar* sstr = NULL; - int32_t sstr_len = 0; - zend_string *u8str; - char *str; - size_t str_len; - int32_t* position_p = NULL; - int32_t position = 0; - zval *zcurrency, *zposition = NULL; - FORMATTER_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Osz|z!", - &object, NumberFormatter_ce_ptr, &str, &str_len, &zcurrency, &zposition ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - FORMATTER_METHOD_FETCH_OBJECT; - - /* Convert given string to UTF-16. */ - intl_convert_utf8_to_utf16(&sstr, &sstr_len, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" ); - - if(zposition) { - position = (int32_t) zval_get_long(zposition); - position_p = &position; - } - - number = unum_parseDoubleCurrency(FORMATTER_OBJECT(nfo), sstr, sstr_len, position_p, currency, &INTL_DATA_ERROR_CODE(nfo)); - if(zposition) { - ZEND_TRY_ASSIGN_REF_LONG(zposition, position); - } - if (sstr) { - efree(sstr); - } - INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); - - /* Convert parsed currency to UTF-8 and pass it back to caller. */ - u8str = intl_convert_utf16_to_utf8(currency, u_strlen(currency), &INTL_DATA_ERROR_CODE(nfo)); - INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-8 failed" ); - ZEND_TRY_ASSIGN_REF_NEW_STR(zcurrency, u8str); - - RETVAL_DOUBLE( number ); -} -/* }}} */ diff --git a/ext/intl/formatter/formatter_parse.cpp b/ext/intl/formatter/formatter_parse.cpp new file mode 100644 index 000000000000..7bbc461516bc --- /dev/null +++ b/ext/intl/formatter/formatter_parse.cpp @@ -0,0 +1,185 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "../intl_convertcpp.h" +#include "formatter_class.h" +#include "formatter_format.h" + +extern "C" { +#include "php_intl.h" +} + +#include +#include + +#define ICU_LOCALE_BUG 1 + +/* {{{ Parse a number. */ +U_CFUNC PHP_FUNCTION( numfmt_parse ) +{ + zend_long type = FORMAT_TYPE_DOUBLE; + char* str = NULL; + size_t str_len; + int32_t position = 0; + zval *zposition = NULL; + char *oldlocale; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if (zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|lz!", + &object, NumberFormatter_ce_ptr, &str, &str_len, &type, &zposition ) == FAILURE ) + { + RETURN_THROWS(); + } + + if (zposition) { + position = (int32_t) zval_get_long(zposition); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + /* Convert given string to UTF-16. */ + icu::UnicodeString ustr; + intl_stringFromChar(ustr, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" ); + +#if ICU_LOCALE_BUG && defined(LC_NUMERIC) + /* need to copy here since setlocale may change it later */ + oldlocale = estrdup(setlocale(LC_NUMERIC, NULL)); + setlocale(LC_NUMERIC, "C"); +#endif + + switch(type) { + case FORMAT_TYPE_INT32: + case FORMAT_TYPE_INT64: + case FORMAT_TYPE_DOUBLE: + { + icu::Formattable result; + icu::ParsePosition pp(position); + FORMATTER_OBJECT(nfo)->parse(ustr, result, pp); + + if (pp.getErrorIndex() >= 0) { + INTL_DATA_ERROR_CODE(nfo) = U_PARSE_ERROR; + } else { + position = pp.getIndex(); + switch(type) { + case FORMAT_TYPE_INT32: + RETVAL_LONG(result.getLong(INTL_DATA_ERROR_CODE(nfo))); + break; + case FORMAT_TYPE_INT64: + { + int64_t val64 = result.getInt64(INTL_DATA_ERROR_CODE(nfo)); + if(val64 > ZEND_LONG_MAX || val64 < ZEND_LONG_MIN) { + RETVAL_DOUBLE(val64); + } else { + RETVAL_LONG((zend_long)val64); + } + break; + } + case FORMAT_TYPE_DOUBLE: + RETVAL_DOUBLE(result.getDouble(INTL_DATA_ERROR_CODE(nfo))); + break; + } + } + break; + } + case FORMAT_TYPE_CURRENCY: + if (hasThis()) { + const char *space; + const char *class_name = get_active_class_name(&space); + zend_argument_value_error(2, "cannot be NumberFormatter::TYPE_CURRENCY constant, " + "use %s%sparseCurrency() method instead", class_name, space); + } else { + zend_argument_value_error(3, "cannot be NumberFormatter::TYPE_CURRENCY constant, use numfmt_parse_currency() function instead"); + } + goto cleanup; + default: + zend_argument_value_error(hasThis() ? 2 : 3, "must be a NumberFormatter::TYPE_* constant"); + goto cleanup; + } + + if (zposition) { + ZEND_TRY_ASSIGN_REF_LONG(zposition, position); + } + +cleanup: + +#if ICU_LOCALE_BUG && defined(LC_NUMERIC) + setlocale(LC_NUMERIC, oldlocale); + efree(oldlocale); +#endif + + INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); +} +/* }}} */ + +/* {{{ Parse a number as currency. */ +U_CFUNC PHP_FUNCTION( numfmt_parse_currency ) +{ + char *str; + size_t str_len; + int32_t position = 0; + zval *zcurrency, *zposition = NULL; + FORMATTER_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Osz|z!", + &object, NumberFormatter_ce_ptr, &str, &str_len, &zcurrency, &zposition ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + FORMATTER_METHOD_FETCH_OBJECT; + + /* Convert given string to UTF-16. */ + icu::UnicodeString ustr; + intl_stringFromChar(ustr, str, str_len, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "String conversion to UTF-16 failed" ); + + if(zposition) { + position = (int32_t) zval_get_long(zposition); + } + + icu::ParsePosition pp(position); + std::unique_ptr currAmt(FORMATTER_OBJECT(nfo)->parseCurrency(ustr, pp)); + + if (currAmt == nullptr || pp.getErrorIndex() >= 0) { + INTL_DATA_ERROR_CODE(nfo) = U_PARSE_ERROR; + INTL_METHOD_CHECK_STATUS( nfo, "Number parsing failed" ); + } + + if(zposition) { + ZEND_TRY_ASSIGN_REF_LONG(zposition, pp.getIndex()); + } + + double number = currAmt->getNumber().getDouble(INTL_DATA_ERROR_CODE(nfo)); + + /* Convert parsed currency to UTF-8 and pass it back to caller. */ + icu::UnicodeString ucurrency(currAmt->getISOCurrency()); + + zend_string *u8str = intl_charFromString(ucurrency, &INTL_DATA_ERROR_CODE(nfo)); + INTL_METHOD_CHECK_STATUS( nfo, "Currency conversion to UTF-8 failed" ); + ZEND_TRY_ASSIGN_REF_STR(zcurrency, u8str); + + RETVAL_DOUBLE( number ); +} +/* }}} */ diff --git a/ext/intl/grapheme/grapheme.h b/ext/intl/grapheme/grapheme.h index 003e0d49317a..b52f48f9d142 100644 --- a/ext/intl/grapheme/grapheme.h +++ b/ext/intl/grapheme/grapheme.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ @@ -18,7 +18,13 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif void grapheme_close_global_iterator( void ); +#ifdef __cplusplus +} +#endif #define GRAPHEME_EXTRACT_TYPE_COUNT 0 #define GRAPHEME_EXTRACT_TYPE_MAXBYTES 1 diff --git a/ext/intl/grapheme/grapheme_string.c b/ext/intl/grapheme/grapheme_string.c deleted file mode 100644 index 34dd2ed369cf..000000000000 --- a/ext/intl/grapheme/grapheme_string.c +++ /dev/null @@ -1,1120 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Ed Batutis | - +----------------------------------------------------------------------+ - */ - -/* {{{ includes */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "grapheme.h" -#include "grapheme_util.h" - -#include -#include -#include -#include -#include - -/* }}} */ - -/* {{{ Get number of graphemes in a string */ -PHP_FUNCTION(grapheme_strlen) -{ - char* string; - size_t string_len; - UChar* ustring = NULL; - int ustring_len = 0; - zend_long ret_len; - UErrorCode status; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(string, string_len) - ZEND_PARSE_PARAMETERS_END(); - - ret_len = grapheme_ascii_check((unsigned char *)string, string_len); - - if ( ret_len >= 0 ) - RETURN_LONG(string_len); - - /* convert the string to UTF-16. */ - status = U_ZERO_ERROR; - intl_convert_utf8_to_utf16(&ustring, &ustring_len, string, string_len, &status ); - - if ( U_FAILURE( status ) ) { - /* Set global error code. */ - intl_error_set_code( NULL, status ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); - if (ustring) { - efree( ustring ); - } - RETURN_NULL(); - } - - ret_len = grapheme_split_string(ustring, ustring_len, NULL, 0 ); - - if (ustring) { - efree( ustring ); - } - - if (ret_len >= 0) { - RETVAL_LONG(ret_len); - } else { - RETVAL_FALSE; - } -} -/* }}} */ - -/* {{{ Find position of first occurrence of a string within another */ -PHP_FUNCTION(grapheme_strpos) -{ - char *haystack, *needle; - size_t haystack_len, needle_len; - const char *found; - zend_long loffset = 0; - int32_t offset = 0; - size_t noffset = 0; - zend_long ret_pos; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(haystack, haystack_len) - Z_PARAM_STRING(needle, needle_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(loffset) - ZEND_PARSE_PARAMETERS_END(); - - if ( OUTSIDE_STRING(loffset, haystack_len) ) { - zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); - RETURN_THROWS(); - } - - /* we checked that it will fit: */ - offset = (int32_t) loffset; - noffset = offset >= 0 ? offset : (int32_t)haystack_len + offset; - - /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ - - if (offset >= 0 && grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0) { - /* quick check to see if the string might be there - * I realize that 'offset' is 'grapheme count offset' but will work in spite of that - */ - found = php_memnstr(haystack + noffset, needle, needle_len, haystack + haystack_len); - - /* if it isn't there the we are done */ - if (found) { - RETURN_LONG(found - haystack); - } - RETURN_FALSE; - } - - /* do utf16 part of the strpos */ - ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 0 /* fIgnoreCase */, 0 /* last */ ); - - if ( ret_pos >= 0 ) { - RETURN_LONG(ret_pos); - } else { - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ Find position of first occurrence of a string within another, ignoring case differences */ -PHP_FUNCTION(grapheme_stripos) -{ - char *haystack, *needle; - size_t haystack_len, needle_len; - const char *found; - zend_long loffset = 0; - int32_t offset = 0; - zend_long ret_pos; - int is_ascii; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(haystack, haystack_len) - Z_PARAM_STRING(needle, needle_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(loffset) - ZEND_PARSE_PARAMETERS_END(); - - if ( OUTSIDE_STRING(loffset, haystack_len) ) { - zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); - RETURN_THROWS(); - } - - /* we checked that it will fit: */ - offset = (int32_t) loffset; - - /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ - - is_ascii = ( grapheme_ascii_check((unsigned char*)haystack, haystack_len) >= 0 ); - - if ( is_ascii ) { - char *haystack_dup, *needle_dup; - int32_t noffset = offset >= 0 ? offset : (int32_t)haystack_len + offset; - needle_dup = estrndup(needle, needle_len); - zend_str_tolower(needle_dup, needle_len); - haystack_dup = estrndup(haystack, haystack_len); - zend_str_tolower(haystack_dup, haystack_len); - - found = php_memnstr(haystack_dup + noffset, needle_dup, needle_len, haystack_dup + haystack_len); - - efree(haystack_dup); - efree(needle_dup); - - if (found) { - RETURN_LONG(found - haystack_dup); - } - - /* if needle was ascii too, we are all done, otherwise we need to try using Unicode to see what we get */ - if ( grapheme_ascii_check((unsigned char *)needle, needle_len) >= 0 ) { - RETURN_FALSE; - } - } - - /* do utf16 part of the strpos */ - ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 1 /* fIgnoreCase */, 0 /*last */ ); - - if ( ret_pos >= 0 ) { - RETURN_LONG(ret_pos); - } else { - RETURN_FALSE; - } - -} -/* }}} */ - -/* {{{ Find position of last occurrence of a string within another */ -PHP_FUNCTION(grapheme_strrpos) -{ - char *haystack, *needle; - size_t haystack_len, needle_len; - zend_long loffset = 0; - int32_t offset = 0; - zend_long ret_pos; - int is_ascii; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(haystack, haystack_len) - Z_PARAM_STRING(needle, needle_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(loffset) - ZEND_PARSE_PARAMETERS_END(); - - if ( OUTSIDE_STRING(loffset, haystack_len) ) { - zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); - RETURN_THROWS(); - } - - /* we checked that it will fit: */ - offset = (int32_t) loffset; - - /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ - - is_ascii = grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0; - - if ( is_ascii ) { - - ret_pos = grapheme_strrpos_ascii(haystack, haystack_len, needle, needle_len, offset); - - if ( ret_pos >= 0 ) { - RETURN_LONG(ret_pos); - } - - /* if the needle was ascii too, we are done */ - - if ( grapheme_ascii_check((unsigned char *)needle, needle_len) >= 0 ) { - RETURN_FALSE; - } - - /* else we need to continue via utf16 */ - } - - ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 0 /* f_ignore_case */, 1/* last */); - - if ( ret_pos >= 0 ) { - RETURN_LONG(ret_pos); - } else { - RETURN_FALSE; - } - - -} -/* }}} */ - -/* {{{ Find position of last occurrence of a string within another, ignoring case */ -PHP_FUNCTION(grapheme_strripos) -{ - char *haystack, *needle; - size_t haystack_len, needle_len; - zend_long loffset = 0; - int32_t offset = 0; - zend_long ret_pos; - int is_ascii; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(haystack, haystack_len) - Z_PARAM_STRING(needle, needle_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(loffset) - ZEND_PARSE_PARAMETERS_END(); - - if ( OUTSIDE_STRING(loffset, haystack_len) ) { - zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); - RETURN_THROWS(); - } - - /* we checked that it will fit: */ - offset = (int32_t) loffset; - - /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ - - is_ascii = grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0; - - if ( is_ascii ) { - char *needle_dup, *haystack_dup; - - needle_dup = estrndup(needle, needle_len); - zend_str_tolower(needle_dup, needle_len); - haystack_dup = estrndup(haystack, haystack_len); - zend_str_tolower(haystack_dup, haystack_len); - - ret_pos = grapheme_strrpos_ascii(haystack_dup, haystack_len, needle_dup, needle_len, offset); - - efree(haystack_dup); - efree(needle_dup); - - if ( ret_pos >= 0 ) { - RETURN_LONG(ret_pos); - } - - /* if the needle was ascii too, we are done */ - - if ( grapheme_ascii_check((unsigned char *)needle, needle_len) >= 0 ) { - RETURN_FALSE; - } - - /* else we need to continue via utf16 */ - } - - ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, NULL, 1 /* f_ignore_case */, 1 /*last */); - - if ( ret_pos >= 0 ) { - RETURN_LONG(ret_pos); - } else { - RETURN_FALSE; - } - - -} -/* }}} */ - -/* {{{ Returns part of a string */ -PHP_FUNCTION(grapheme_substr) -{ - char *str; - zend_string *u8_sub_str; - UChar *ustr; - size_t str_len; - int32_t ustr_len; - zend_long lstart = 0, length = 0; - int32_t start = 0; - int iter_val; - UErrorCode status; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; - UBreakIterator* bi = NULL; - int sub_str_start_pos, sub_str_end_pos; - int32_t (*iter_func)(UBreakIterator *); - bool no_length = true; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(str, str_len) - Z_PARAM_LONG(lstart) - Z_PARAM_OPTIONAL - Z_PARAM_LONG_OR_NULL(length, no_length) - ZEND_PARSE_PARAMETERS_END(); - - if (lstart < INT32_MIN || lstart > INT32_MAX) { - zend_argument_value_error(2, "is too large"); - RETURN_THROWS(); - } - - start = (int32_t) lstart; - - if (no_length) { - length = str_len; - } - - if (length < INT32_MIN || length > INT32_MAX) { - zend_argument_value_error(3, "is too large"); - RETURN_THROWS(); - } - - /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ - - if ( grapheme_ascii_check((unsigned char *)str, str_len) >= 0 ) { - int32_t asub_str_len; - char *sub_str; - grapheme_substr_ascii(str, str_len, start, (int32_t)length, &sub_str, &asub_str_len); - - if ( NULL == sub_str ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_substr: invalid parameters", 1 ); - RETURN_FALSE; - } - - RETURN_STRINGL(sub_str, asub_str_len); - } - - ustr = NULL; - ustr_len = 0; - status = U_ZERO_ERROR; - intl_convert_utf8_to_utf16(&ustr, &ustr_len, str, str_len, &status); - - if ( U_FAILURE( status ) ) { - /* Set global error code. */ - intl_error_set_code( NULL, status ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); - if (ustr) { - efree( ustr ); - } - RETURN_FALSE; - } - - bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &status ); - - if( U_FAILURE(status) ) { - RETURN_FALSE; - } - - ubrk_setText(bi, ustr, ustr_len, &status); - - if ( start < 0 ) { - iter_func = ubrk_previous; - ubrk_last(bi); - iter_val = 1; - } - else { - iter_func = ubrk_next; - iter_val = -1; - } - - sub_str_start_pos = 0; - - while ( start ) { - sub_str_start_pos = iter_func(bi); - - if ( UBRK_DONE == sub_str_start_pos ) { - break; - } - - start += iter_val; - } - - if (0 != start) { - if (start > 0) { - if (ustr) { - efree(ustr); - } - ubrk_close(bi); - RETURN_EMPTY_STRING(); - } - - sub_str_start_pos = 0; - ubrk_first(bi); - } - - /* OK to convert here since if str_len were big, convert above would fail */ - if (length >= (int32_t)str_len) { - - /* no length supplied or length is too big, return the rest of the string */ - - status = U_ZERO_ERROR; - u8_sub_str = intl_convert_utf16_to_utf8(ustr + sub_str_start_pos, ustr_len - sub_str_start_pos, &status); - - if (ustr) { - efree( ustr ); - } - ubrk_close( bi ); - - if ( !u8_sub_str ) { - /* Set global error code. */ - intl_error_set_code( NULL, status ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); - - RETURN_FALSE; - } - - /* return the allocated string, not a duplicate */ - RETVAL_NEW_STR(u8_sub_str); - return; - } - - if(length == 0) { - /* empty length - we've validated start, we can return "" now */ - if (ustr) { - efree(ustr); - } - ubrk_close(bi); - RETURN_EMPTY_STRING(); - } - - /* find the end point of the string to return */ - - if ( length < 0 ) { - iter_func = ubrk_previous; - ubrk_last(bi); - iter_val = 1; - } - else { - iter_func = ubrk_next; - iter_val = -1; - } - - sub_str_end_pos = 0; - - while ( length ) { - sub_str_end_pos = iter_func(bi); - - if ( UBRK_DONE == sub_str_end_pos ) { - break; - } - - length += iter_val; - } - - ubrk_close(bi); - - if ( UBRK_DONE == sub_str_end_pos) { - if (length < 0) { - efree(ustr); - RETURN_EMPTY_STRING(); - } else { - sub_str_end_pos = ustr_len; - } - } - - if (sub_str_start_pos > sub_str_end_pos) { - efree(ustr); - RETURN_EMPTY_STRING(); - } - - status = U_ZERO_ERROR; - u8_sub_str = intl_convert_utf16_to_utf8(ustr + sub_str_start_pos, ( sub_str_end_pos - sub_str_start_pos ), &status); - - efree( ustr ); - - if ( !u8_sub_str ) { - /* Set global error code. */ - intl_error_set_code( NULL, status ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting output string to UTF-8", 0 ); - - RETURN_FALSE; - } - - /* return the allocated string, not a duplicate */ - RETVAL_NEW_STR(u8_sub_str); -} -/* }}} */ - -/* {{{ strstr_common_handler */ -static void strstr_common_handler(INTERNAL_FUNCTION_PARAMETERS, int f_ignore_case) -{ - char *haystack, *needle; - const char *found; - size_t haystack_len, needle_len; - int32_t ret_pos, uchar_pos; - bool part = false; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(haystack, haystack_len) - Z_PARAM_STRING(needle, needle_len) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(part) - ZEND_PARSE_PARAMETERS_END(); - - if ( !f_ignore_case ) { - - /* ASCII optimization: quick check to see if the string might be there */ - found = php_memnstr(haystack, needle, needle_len, haystack + haystack_len); - - /* if it isn't there the we are done */ - if ( !found ) { - RETURN_FALSE; - } - - /* if it is there, and if the haystack is ascii, we are all done */ - if ( grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0 ) { - size_t found_offset = found - haystack; - - if (part) { - RETURN_STRINGL(haystack, found_offset); - } else { - RETURN_STRINGL(found, haystack_len - found_offset); - } - } - - } - - /* need to work in utf16 */ - ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, 0, &uchar_pos, f_ignore_case, 0 /*last */ ); - - if ( ret_pos < 0 ) { - RETURN_FALSE; - } - - /* uchar_pos is the 'nth' Unicode character position of the needle */ - - ret_pos = 0; - U8_FWD_N(haystack, ret_pos, haystack_len, uchar_pos); - - if (part) { - RETURN_STRINGL(haystack, ret_pos); - } else { - RETURN_STRINGL(haystack + ret_pos, haystack_len - ret_pos); - } - -} -/* }}} */ - -/* {{{ Finds first occurrence of a string within another */ -PHP_FUNCTION(grapheme_strstr) -{ - strstr_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0 /* f_ignore_case */); -} -/* }}} */ - -/* {{{ Finds first occurrence of a string within another */ -PHP_FUNCTION(grapheme_stristr) -{ - strstr_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1 /* f_ignore_case */); -} -/* }}} */ - -/* {{{ grapheme_extract_charcount_iter - grapheme iterator for grapheme_extract MAXCHARS */ -static inline int32_t -grapheme_extract_charcount_iter(UBreakIterator *bi, int32_t csize, unsigned char *pstr, int32_t str_len) -{ - int pos = 0; - int ret_pos = 0; - int break_pos, prev_break_pos; - int count = 0; - - while ( 1 ) { - pos = ubrk_next(bi); - - if ( UBRK_DONE == pos ) { - break; - } - - for ( break_pos = ret_pos; break_pos < pos; ) { - count++; - prev_break_pos = break_pos; - U8_FWD_1(pstr, break_pos, str_len); - - if ( prev_break_pos == break_pos ) { - /* something wrong - malformed utf8? */ - csize = 0; - break; - } - } - - /* if we are beyond our limit, then the loop is done */ - if ( count > csize ) { - break; - } - - ret_pos = break_pos; - } - - return ret_pos; -} -/* }}} */ - -/* {{{ grapheme_extract_bytecount_iter - grapheme iterator for grapheme_extract MAXBYTES */ -static inline int32_t -grapheme_extract_bytecount_iter(UBreakIterator *bi, int32_t bsize, unsigned char *pstr, int32_t str_len) -{ - int pos = 0; - int ret_pos = 0; - - while ( 1 ) { - pos = ubrk_next(bi); - - if ( UBRK_DONE == pos ) { - break; - } - - if ( pos > bsize ) { - break; - } - - ret_pos = pos; - } - - return ret_pos; -} -/* }}} */ - -/* {{{ grapheme_extract_count_iter - grapheme iterator for grapheme_extract COUNT */ -static inline int32_t -grapheme_extract_count_iter(UBreakIterator *bi, int32_t size, unsigned char *pstr, int32_t str_len) -{ - int next_pos = 0; - int ret_pos = 0; - - while ( size ) { - next_pos = ubrk_next(bi); - - if ( UBRK_DONE == next_pos ) { - break; - } - ret_pos = next_pos; - size--; - } - - return ret_pos; -} -/* }}} */ - -/* {{{ grapheme extract iter function pointer array */ -typedef int32_t (*grapheme_extract_iter)(UBreakIterator * /*bi*/, int32_t /*size*/, unsigned char * /*pstr*/, int32_t /*str_len*/); - -static const grapheme_extract_iter grapheme_extract_iters[] = { - &grapheme_extract_count_iter, - &grapheme_extract_bytecount_iter, - &grapheme_extract_charcount_iter, -}; -/* }}} */ - -/* {{{ Function to extract a sequence of default grapheme clusters */ -PHP_FUNCTION(grapheme_extract) -{ - char *str, *pstr; - UText ut = UTEXT_INITIALIZER; - size_t str_len; - zend_long size; /* maximum number of grapheme clusters, bytes, or characters (based on extract_type) to return */ - zend_long lstart = 0; /* starting position in str in bytes */ - int32_t start = 0; - zend_long extract_type = GRAPHEME_EXTRACT_TYPE_COUNT; - UErrorCode status; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; - UBreakIterator* bi = NULL; - int ret_pos; - zval *next = NULL; /* return offset of next part of the string */ - - ZEND_PARSE_PARAMETERS_START(2, 5) - Z_PARAM_STRING(str, str_len) - Z_PARAM_LONG(size) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(extract_type) - Z_PARAM_LONG(lstart) - Z_PARAM_ZVAL(next) - ZEND_PARSE_PARAMETERS_END(); - - if (lstart < 0) { - lstart += str_len; - } - - if ( NULL != next ) { - ZEND_ASSERT(Z_ISREF_P(next)); - ZEND_TRY_ASSIGN_REF_LONG(next, lstart); - if (UNEXPECTED(EG(exception))) { - RETURN_THROWS(); - } - } - - if ( extract_type < GRAPHEME_EXTRACT_TYPE_MIN || extract_type > GRAPHEME_EXTRACT_TYPE_MAX ) { - zend_argument_value_error(3, "must be one of GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS"); - RETURN_THROWS(); - } - - if ( lstart > INT32_MAX || lstart < 0 || (size_t)lstart >= str_len ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_extract: start not contained in string", 0 ); - RETURN_FALSE; - } - - if (size < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); - RETURN_THROWS(); - } - - if (size > INT32_MAX) { - zend_argument_value_error(2, "is too large"); - RETURN_THROWS(); - } - - if (size == 0) { - RETURN_EMPTY_STRING(); - } - - /* we checked that it will fit: */ - start = (int32_t) lstart; - - pstr = str + start; - - /* just in case pstr points in the middle of a character, move forward to the start of the next char */ - if ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) { - char *str_end = str + str_len; - - while ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) { - pstr++; - start++; - if ( pstr >= str_end ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "grapheme_extract: invalid input string", 0 ); - - RETURN_FALSE; - } - } - } - - str_len -= (pstr - str); - - /* if the string is all ASCII up to size+1 - or str_len whichever is first - then we are done. - (size + 1 because the size-th character might be the beginning of a grapheme cluster) - */ - - if ( -1 != grapheme_ascii_check((unsigned char *)pstr, MIN(size + 1, str_len)) ) { - size_t nsize = MIN(size, str_len); - if ( NULL != next ) { - ZEND_TRY_ASSIGN_REF_LONG(next, start + nsize); - } - RETURN_STRINGL(pstr, nsize); - } - - status = U_ZERO_ERROR; - utext_openUTF8(&ut, pstr, str_len, &status); - - if ( U_FAILURE( status ) ) { - /* Set global error code. */ - intl_error_set_code( NULL, status ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error opening UTF-8 text", 0 ); - - RETURN_FALSE; - } - - bi = NULL; - status = U_ZERO_ERROR; - bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); - - ubrk_setUText(bi, &ut, &status); - /* if the caller put us in the middle of a grapheme, we can't detect it in all cases since we - can't back up. So, we will not do anything. */ - - /* now we need to find the end of the chunk the user wants us to return */ - /* it's ok to convert str_len to in32_t since if it were too big intl_convert_utf8_to_utf16 above would fail */ - ret_pos = (*grapheme_extract_iters[extract_type])(bi, size, (unsigned char *)pstr, (int32_t)str_len); - - utext_close(&ut); - ubrk_close(bi); - - if ( NULL != next ) { - ZEND_TRY_ASSIGN_REF_LONG(next, start + ret_pos); - } - - RETURN_STRINGL(((char *)pstr), ret_pos); -} - -PHP_FUNCTION(grapheme_str_split) -{ - char *pstr, *end; - zend_string *str; - zend_long split_len = 1; - - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; - UErrorCode ustatus = U_ZERO_ERROR; - int32_t pos, current, i, end_len = 0; - UBreakIterator* bi; - UText *ut = NULL; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR(str) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(split_len) - ZEND_PARSE_PARAMETERS_END(); - - if (split_len <= 0 || split_len > UINT_MAX / 4) { - zend_argument_value_error(2, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); - RETURN_THROWS(); - } - - if (ZSTR_LEN(str) == 0) { - RETURN_EMPTY_ARRAY(); - } - - pstr = ZSTR_VAL(str); - ut = utext_openUTF8(ut, pstr, ZSTR_LEN(str), &ustatus); - - if ( U_FAILURE( ustatus ) ) { - /* Set global error code. */ - intl_error_set_code( NULL, ustatus ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error opening UTF-8 text", 0 ); - - RETURN_FALSE; - } - - bi = NULL; - ustatus = U_ZERO_ERROR; - bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &ustatus ); - - if( U_FAILURE(ustatus) ) { - RETURN_FALSE; - } - - ubrk_setUText(bi, ut, &ustatus); - - pos = 0; - array_init(return_value); - - for (end = pstr, i = 0, current = 0; pos != UBRK_DONE;) { - end_len = pos - current; - pos = ubrk_next(bi); - - if (i == split_len - 1) { - if ( pos != UBRK_DONE ) { - add_next_index_stringl(return_value, pstr, pos - current); - end = pstr + pos - current; - i = 0; - } - pstr += pos - current; - current = pos; - } else { - i += 1; - } - } - - if (i != 0 && end_len != 0) { - add_next_index_stringl(return_value, end, end_len); - } - - utext_close(ut); - ubrk_close(bi); -} - -PHP_FUNCTION(grapheme_levenshtein) -{ - zend_string *string1, *string2; - zend_long cost_ins = 1; - zend_long cost_rep = 1; - zend_long cost_del = 1; - - ZEND_PARSE_PARAMETERS_START(2, 5) - Z_PARAM_STR(string1) - Z_PARAM_STR(string2) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(cost_ins) - Z_PARAM_LONG(cost_rep) - Z_PARAM_LONG(cost_del) - ZEND_PARSE_PARAMETERS_END(); - - if (cost_ins <= 0 || cost_ins > UINT_MAX / 4) { - zend_argument_value_error(3, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); - RETURN_THROWS(); - } - - if (cost_rep <= 0 || cost_rep > UINT_MAX / 4) { - zend_argument_value_error(4, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); - RETURN_THROWS(); - } - - if (cost_del <= 0 || cost_del > UINT_MAX / 4) { - zend_argument_value_error(5, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); - RETURN_THROWS(); - } - - zend_long c0, c1, c2; - zend_long retval; - size_t i2; - char *pstr1, *pstr2; - - UChar *ustring1 = NULL; - UChar *ustring2 = NULL; - - int32_t ustring1_len = 0; - int32_t ustring2_len = 0; - - UErrorCode ustatus = U_ZERO_ERROR; - - /* When all costs are equal, levenshtein fulfills the requirements of a metric, which means - * that the distance is symmetric. If string1 is shorter than string2 we can save memory (and CPU time) - * by having shorter rows (p1 & p2). */ - if (ZSTR_LEN(string1) < ZSTR_LEN(string2) && cost_ins == cost_rep && cost_rep == cost_del) { - zend_string *tmp = string1; - string1 = string2; - string2 = tmp; - } - - pstr1 = ZSTR_VAL(string1); - pstr2 = ZSTR_VAL(string2); - - intl_convert_utf8_to_utf16(&ustring1, &ustring1_len, pstr1, ZSTR_LEN(string1), &ustatus); - - if (U_FAILURE(ustatus)) { - intl_error_set_code(NULL, ustatus); - - intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16", 0); - RETVAL_FALSE; - goto out_ustring1; - } - - intl_convert_utf8_to_utf16(&ustring2, &ustring2_len, pstr2, ZSTR_LEN(string2), &ustatus); - - if (U_FAILURE(ustatus)) { - intl_error_set_code(NULL, ustatus); - - intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16", 0); - RETVAL_FALSE; - goto out_ustring2; - } - - UBreakIterator *bi1, *bi2; - - int32_t strlen_1, strlen_2; - strlen_1 = grapheme_split_string(ustring1, ustring1_len, NULL, 0); - strlen_2 = grapheme_split_string(ustring2, ustring2_len, NULL, 0); - if (UNEXPECTED(strlen_1 < 0 || strlen_2 < 0)) { - RETVAL_FALSE; - goto out_ustring2; - } - - if (strlen_1 == 0) { - RETVAL_LONG(strlen_2 * cost_ins); - goto out_ustring2; - } - if (strlen_2 == 0) { - RETVAL_LONG(strlen_1 * cost_del); - goto out_ustring2; - } - - unsigned char u_break_iterator_buffer1[U_BRK_SAFECLONE_BUFFERSIZE]; - unsigned char u_break_iterator_buffer2[U_BRK_SAFECLONE_BUFFERSIZE]; - bi1 = grapheme_get_break_iterator(u_break_iterator_buffer1, &ustatus); - if (U_FAILURE(ustatus)) { - intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #1 ($string1)", 0); - RETVAL_FALSE; - goto out_bi1; - } - - bi2 = grapheme_get_break_iterator(u_break_iterator_buffer2, &ustatus); - if (U_FAILURE(ustatus)) { - intl_error_set_code(NULL, ustatus); - intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #2 ($string2)", 0); - RETVAL_FALSE; - goto out_bi2; - } - - ubrk_setText(bi1, ustring1, ustring1_len, &ustatus); - if (U_FAILURE(ustatus)) { - intl_error_set_code(NULL, ustatus); - - intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #1 ($string1)", 0); - RETVAL_FALSE; - goto out_bi2; - } - - ubrk_setText(bi2, ustring2, ustring2_len, &ustatus); - if (U_FAILURE(ustatus)) { - intl_error_set_code(NULL, ustatus); - - intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #2 ($string2)", 0); - RETVAL_FALSE; - goto out_bi2; - } - UCollator *collator = ucol_open("", &ustatus); - if (U_FAILURE(ustatus)) { - intl_error_set_code(NULL, ustatus); - - intl_error_set_custom_msg(NULL, "Error on ucol_open", 0); - RETVAL_FALSE; - goto out_collator; - } - - zend_long *p1, *p2, *tmp; - p1 = safe_emalloc((size_t) strlen_2 + 1, sizeof(zend_long), 0); - p2 = safe_emalloc((size_t) strlen_2 + 1, sizeof(zend_long), 0); - - for (i2 = 0; i2 <= strlen_2; i2++) { - p1[i2] = i2 * cost_ins; - } - - int32_t current1 = 0; - int32_t current2 = 0; - int32_t pos1 = 0; - int32_t pos2 = 0; - - while (true) { - current1 = ubrk_current(bi1); - pos1 = ubrk_next(bi1); - if (pos1 == UBRK_DONE) { - break; - } - p2[0] = p1[0] + cost_del; - for (i2 = 0, pos2 = 0; pos2 != UBRK_DONE; i2++) { - current2 = ubrk_current(bi2); - pos2 = ubrk_next(bi2); - if (pos2 == UBRK_DONE) { - break; - } - if (ucol_strcoll(collator, ustring1 + current1, pos1 - current1, ustring2 + current2, pos2 - current2) == UCOL_EQUAL) { - c0 = p1[i2]; - } else { - c0 = p1[i2] + cost_rep; - } - c1 = p1[i2 + 1] + cost_del; - if (c1 < c0) { - c0 = c1; - } - c2 = p2[i2] + cost_ins; - if (c2 < c0) { - c0 = c2; - } - p2[i2 + 1] = c0; - } - ubrk_first(bi2); - tmp = p1; - p1 = p2; - p2 = tmp; - } - - retval = p1[strlen_2]; - RETVAL_LONG(retval); - - efree(p2); - efree(p1); - -out_collator: - ucol_close(collator); -out_bi2: - ubrk_close(bi2); -out_bi1: - ubrk_close(bi1); -out_ustring2: - efree(ustring2); -out_ustring1: - efree(ustring1); -} - -/* }}} */ diff --git a/ext/intl/grapheme/grapheme_string.cpp b/ext/intl/grapheme/grapheme_string.cpp new file mode 100644 index 000000000000..9b463fcd94cf --- /dev/null +++ b/ext/intl/grapheme/grapheme_string.cpp @@ -0,0 +1,1197 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Author: Ed Batutis | + +----------------------------------------------------------------------+ + */ + +/* {{{ includes */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include +#include "grapheme.h" +#include "grapheme_util.h" +} + +#include +#include +#include +#include +#include + +/* }}} */ + +/* {{{ Get number of graphemes in a string */ +U_CFUNC PHP_FUNCTION(grapheme_strlen) +{ + char* string; + size_t string_len; + UChar* ustring = nullptr; + int ustring_len = 0; + zend_long ret_len; + UErrorCode status; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(string, string_len) + ZEND_PARSE_PARAMETERS_END(); + + ret_len = grapheme_ascii_check((unsigned char *)string, string_len); + + if ( ret_len >= 0 ) + RETURN_LONG(string_len); + + /* convert the string to UTF-16. */ + status = U_ZERO_ERROR; + intl_convert_utf8_to_utf16(&ustring, &ustring_len, string, string_len, &status ); + + if ( U_FAILURE( status ) ) { + /* Set global error code. */ + intl_error_set_code( nullptr, status ); + + /* Set error messages. */ + intl_error_set_custom_msg( nullptr, "Error converting input string to UTF-16"); + if (ustring) { + efree( ustring ); + } + RETURN_NULL(); + } + + ret_len = grapheme_split_string(ustring, ustring_len, nullptr, 0 ); + + if (ustring) { + efree( ustring ); + } + + if (ret_len >= 0) { + RETVAL_LONG(ret_len); + } else { + RETVAL_FALSE; + } +} +/* }}} */ + +/* {{{ Find position of first occurrence of a string within another */ +U_CFUNC PHP_FUNCTION(grapheme_strpos) +{ + char *haystack, *needle, *locale = ""; + size_t haystack_len, needle_len, locale_len = 0; + const char *found; + zend_long loffset = 0; + int32_t offset = 0; + size_t noffset = 0; + zend_long ret_pos; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STRING(haystack, haystack_len) + Z_PARAM_STRING(needle, needle_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(loffset) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if ( OUTSIDE_STRING(loffset, haystack_len) ) { + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); + } + + /* we checked that it will fit: */ + offset = (int32_t) loffset; + noffset = offset >= 0 ? offset : (int32_t)haystack_len + offset; + + /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ + + if (offset >= 0 && grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0) { + /* quick check to see if the string might be there + * I realize that 'offset' is 'grapheme count offset' but will work in spite of that + */ + found = php_memnstr(haystack + noffset, needle, needle_len, haystack + haystack_len); + + /* if it isn't there the we are done */ + if (found) { + RETURN_LONG(found - haystack); + } + RETURN_FALSE; + } + + /* do utf16 part of the strpos */ + ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, nullptr, /* fIgnoreCase */ 0, /* last */ 0, locale); + + if ( ret_pos >= 0 ) { + RETURN_LONG(ret_pos); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ Find position of first occurrence of a string within another, ignoring case differences */ +U_CFUNC PHP_FUNCTION(grapheme_stripos) +{ + char *haystack, *needle, *locale = ""; + size_t haystack_len, needle_len, locale_len = 0; + const char *found; + zend_long loffset = 0; + int32_t offset = 0; + zend_long ret_pos; + int is_ascii; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STRING(haystack, haystack_len) + Z_PARAM_STRING(needle, needle_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(loffset) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if ( OUTSIDE_STRING(loffset, haystack_len) ) { + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); + } + + /* we checked that it will fit: */ + offset = (int32_t) loffset; + + /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ + + is_ascii = ( grapheme_ascii_check((unsigned char*)haystack, haystack_len) >= 0 ); + + if ( is_ascii ) { + char *haystack_dup, *needle_dup; + int32_t noffset = offset >= 0 ? offset : (int32_t)haystack_len + offset; + needle_dup = estrndup(needle, needle_len); + zend_str_tolower(needle_dup, needle_len); + haystack_dup = estrndup(haystack, haystack_len); + zend_str_tolower(haystack_dup, haystack_len); + + found = php_memnstr(haystack_dup + noffset, needle_dup, needle_len, haystack_dup + haystack_len); + + efree(haystack_dup); + efree(needle_dup); + + if (found) { + RETURN_LONG(found - haystack_dup); + } + + /* if needle was ascii too, we are all done, otherwise we need to try using Unicode to see what we get */ + if ( grapheme_ascii_check((unsigned char *)needle, needle_len) >= 0 ) { + RETURN_FALSE; + } + } + + /* do utf16 part of the strpos */ + ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, nullptr, /* fIgnoreCase */ 1, /*last */ 0, locale); + + if ( ret_pos >= 0 ) { + RETURN_LONG(ret_pos); + } else { + RETURN_FALSE; + } + +} +/* }}} */ + +/* {{{ Find position of last occurrence of a string within another */ +U_CFUNC PHP_FUNCTION(grapheme_strrpos) +{ + char *haystack, *needle; + char *locale = ""; + size_t haystack_len, needle_len, locale_len = 0; + zend_long loffset = 0; + int32_t offset = 0; + zend_long ret_pos; + int is_ascii; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STRING(haystack, haystack_len) + Z_PARAM_STRING(needle, needle_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(loffset) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if ( OUTSIDE_STRING(loffset, haystack_len) ) { + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); + } + + /* we checked that it will fit: */ + offset = (int32_t) loffset; + + /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ + + is_ascii = grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0; + + if ( is_ascii ) { + + ret_pos = grapheme_strrpos_ascii(haystack, haystack_len, needle, needle_len, offset); + + if ( ret_pos >= 0 ) { + RETURN_LONG(ret_pos); + } + + /* if the needle was ascii too, we are done */ + + if ( grapheme_ascii_check((unsigned char *)needle, needle_len) >= 0 ) { + RETURN_FALSE; + } + + /* else we need to continue via utf16 */ + } + + ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, nullptr, /* f_ignore_case */ 0, /* last */ 1, locale); + + if ( ret_pos >= 0 ) { + RETURN_LONG(ret_pos); + } else { + RETURN_FALSE; + } + + +} +/* }}} */ + +/* {{{ Find position of last occurrence of a string within another, ignoring case */ +U_CFUNC PHP_FUNCTION(grapheme_strripos) +{ + char *haystack, *needle, *locale = ""; + size_t haystack_len, needle_len, locale_len = 0; + zend_long loffset = 0; + int32_t offset = 0; + zend_long ret_pos; + int is_ascii; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STRING(haystack, haystack_len) + Z_PARAM_STRING(needle, needle_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(loffset) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if ( OUTSIDE_STRING(loffset, haystack_len) ) { + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); + } + + /* we checked that it will fit: */ + offset = (int32_t) loffset; + + /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ + + is_ascii = grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0; + + if ( is_ascii ) { + char *needle_dup, *haystack_dup; + + needle_dup = estrndup(needle, needle_len); + zend_str_tolower(needle_dup, needle_len); + haystack_dup = estrndup(haystack, haystack_len); + zend_str_tolower(haystack_dup, haystack_len); + + ret_pos = grapheme_strrpos_ascii(haystack_dup, haystack_len, needle_dup, needle_len, offset); + + efree(haystack_dup); + efree(needle_dup); + + if ( ret_pos >= 0 ) { + RETURN_LONG(ret_pos); + } + + /* if the needle was ascii too, we are done */ + + if ( grapheme_ascii_check((unsigned char *)needle, needle_len) >= 0 ) { + RETURN_FALSE; + } + + /* else we need to continue via utf16 */ + } + + ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, offset, nullptr, /* f_ignore_case */ 1, /*last */ 1, locale); + + if ( ret_pos >= 0 ) { + RETURN_LONG(ret_pos); + } else { + RETURN_FALSE; + } + + +} +/* }}} */ + +/* {{{ Returns part of a string */ +U_CFUNC PHP_FUNCTION(grapheme_substr) +{ + char *str, *locale = ""; + zend_string *u8_sub_str; + UChar *ustr; + size_t str_len, locale_len = 0; + int32_t ustr_len; + zend_long lstart = 0, length = 0; + int32_t start = 0; + int iter_val; + UErrorCode status; + unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; + UBreakIterator* bi = nullptr; + int sub_str_start_pos, sub_str_end_pos; + int32_t (*iter_func)(UBreakIterator *); + bool no_length = true; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STRING(str, str_len) + Z_PARAM_LONG(lstart) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(length, no_length) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if (lstart < INT32_MIN || lstart > INT32_MAX) { + zend_argument_value_error(2, "is too large"); + RETURN_THROWS(); + } + + start = (int32_t) lstart; + + if (no_length) { + length = str_len; + } + + if (length < INT32_MIN || length > INT32_MAX) { + zend_argument_value_error(3, "is too large"); + RETURN_THROWS(); + } + + /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ + + if ( grapheme_ascii_check((unsigned char *)str, str_len) >= 0 ) { + int32_t asub_str_len; + char *sub_str; + grapheme_substr_ascii(str, str_len, start, (int32_t)length, &sub_str, &asub_str_len); + + if ( nullptr == sub_str ) { + intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR, "invalid parameters"); + RETURN_FALSE; + } + + RETURN_STRINGL(sub_str, asub_str_len); + } + + ustr = nullptr; + ustr_len = 0; + status = U_ZERO_ERROR; + intl_convert_utf8_to_utf16(&ustr, &ustr_len, str, str_len, &status); + + if ( U_FAILURE( status ) ) { + /* Set global error code. */ + intl_error_set_code( nullptr, status ); + + /* Set error messages. */ + intl_error_set_custom_msg( nullptr, "Error converting input string to UTF-16"); + if (ustr) { + efree( ustr ); + } + RETURN_FALSE; + } + + bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &status ); + + if( U_FAILURE(status) ) { + RETURN_FALSE; + } + + ubrk_setText(bi, ustr, ustr_len, &status); + + if ( start < 0 ) { + iter_func = ubrk_previous; + ubrk_last(bi); + iter_val = 1; + } + else { + iter_func = ubrk_next; + iter_val = -1; + } + + sub_str_start_pos = 0; + + while ( start ) { + sub_str_start_pos = iter_func(bi); + + if ( UBRK_DONE == sub_str_start_pos ) { + break; + } + + start += iter_val; + } + + if (0 != start) { + if (start > 0) { + if (ustr) { + efree(ustr); + } + ubrk_close(bi); + RETURN_EMPTY_STRING(); + } + + sub_str_start_pos = 0; + ubrk_first(bi); + } + + /* OK to convert here since if str_len were big, convert above would fail */ + if (length >= (int32_t)str_len) { + + /* no length supplied or length is too big, return the rest of the string */ + + status = U_ZERO_ERROR; + u8_sub_str = intl_convert_utf16_to_utf8(ustr + sub_str_start_pos, ustr_len - sub_str_start_pos, &status); + + if (ustr) { + efree( ustr ); + } + ubrk_close( bi ); + + if ( !u8_sub_str ) { + /* Set global error code. */ + intl_error_set_code( nullptr, status ); + + /* Set error messages. */ + intl_error_set_custom_msg( nullptr, "Error converting output string to UTF-8"); + + RETURN_FALSE; + } + + /* return the allocated string, not a duplicate */ + RETVAL_NEW_STR(u8_sub_str); + return; + } + + if(length == 0) { + /* empty length - we've validated start, we can return "" now */ + if (ustr) { + efree(ustr); + } + ubrk_close(bi); + RETURN_EMPTY_STRING(); + } + + /* find the end point of the string to return */ + + if ( length < 0 ) { + iter_func = ubrk_previous; + ubrk_last(bi); + iter_val = 1; + } + else { + iter_func = ubrk_next; + iter_val = -1; + } + + sub_str_end_pos = 0; + + while ( length ) { + sub_str_end_pos = iter_func(bi); + + if ( UBRK_DONE == sub_str_end_pos ) { + break; + } + + length += iter_val; + } + + ubrk_close(bi); + + if ( UBRK_DONE == sub_str_end_pos) { + if (length < 0) { + efree(ustr); + RETURN_EMPTY_STRING(); + } else { + sub_str_end_pos = ustr_len; + } + } + + if (sub_str_start_pos > sub_str_end_pos) { + efree(ustr); + RETURN_EMPTY_STRING(); + } + + status = U_ZERO_ERROR; + u8_sub_str = intl_convert_utf16_to_utf8(ustr + sub_str_start_pos, ( sub_str_end_pos - sub_str_start_pos ), &status); + + efree( ustr ); + + if ( !u8_sub_str ) { + /* Set global error code. */ + intl_error_set_code( nullptr, status ); + + /* Set error messages. */ + intl_error_set_custom_msg( nullptr, "Error converting output string to UTF-8"); + + RETURN_FALSE; + } + + /* return the allocated string, not a duplicate */ + RETVAL_NEW_STR(u8_sub_str); +} +/* }}} */ + +/* {{{ strstr_common_handler */ +static void strstr_common_handler(INTERNAL_FUNCTION_PARAMETERS, int f_ignore_case) +{ + char *haystack, *needle, *locale = ""; + const char *found; + size_t haystack_len, needle_len, locale_len = 0; + int32_t ret_pos, uchar_pos; + bool part = false; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STRING(haystack, haystack_len) + Z_PARAM_STRING(needle, needle_len) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(part) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if ( !f_ignore_case ) { + + /* ASCII optimization: quick check to see if the string might be there */ + found = php_memnstr(haystack, needle, needle_len, haystack + haystack_len); + + /* if it isn't there the we are done */ + if ( !found ) { + RETURN_FALSE; + } + + /* if it is there, and if the haystack is ascii, we are all done */ + if ( grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0 ) { + size_t found_offset = found - haystack; + + if (part) { + RETURN_STRINGL(haystack, found_offset); + } else { + RETURN_STRINGL(found, haystack_len - found_offset); + } + } + + } + + /* need to work in utf16 */ + ret_pos = grapheme_strpos_utf16(haystack, haystack_len, needle, needle_len, 0, &uchar_pos, f_ignore_case, /* last */ 0, locale); + + if ( ret_pos < 0 ) { + RETURN_FALSE; + } + + /* uchar_pos is the 'nth' Unicode character position of the needle */ + + ret_pos = 0; + U8_FWD_N(haystack, ret_pos, haystack_len, uchar_pos); + + if (part) { + RETURN_STRINGL(haystack, ret_pos); + } else { + RETURN_STRINGL(haystack + ret_pos, haystack_len - ret_pos); + } + +} +/* }}} */ + +/* {{{ Finds first occurrence of a string within another */ +U_CFUNC PHP_FUNCTION(grapheme_strstr) +{ + strstr_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0 /* f_ignore_case */); +} +/* }}} */ + +/* {{{ Finds first occurrence of a string within another */ +U_CFUNC PHP_FUNCTION(grapheme_stristr) +{ + strstr_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1 /* f_ignore_case */); +} +/* }}} */ + +/* {{{ grapheme_extract_charcount_iter - grapheme iterator for grapheme_extract MAXCHARS */ +static inline int32_t +grapheme_extract_charcount_iter(UBreakIterator *bi, int32_t csize, unsigned char *pstr, int32_t str_len) +{ + int pos = 0; + int ret_pos = 0; + int break_pos, prev_break_pos; + int count = 0; + + while ( 1 ) { + pos = ubrk_next(bi); + + if ( UBRK_DONE == pos ) { + break; + } + + for ( break_pos = ret_pos; break_pos < pos; ) { + count++; + prev_break_pos = break_pos; + U8_FWD_1(pstr, break_pos, str_len); + + if ( prev_break_pos == break_pos ) { + /* something wrong - malformed utf8? */ + csize = 0; + break; + } + } + + /* if we are beyond our limit, then the loop is done */ + if ( count > csize ) { + break; + } + + ret_pos = break_pos; + } + + return ret_pos; +} +/* }}} */ + +/* {{{ grapheme_extract_bytecount_iter - grapheme iterator for grapheme_extract MAXBYTES */ +static inline int32_t +grapheme_extract_bytecount_iter(UBreakIterator *bi, int32_t bsize, unsigned char *pstr, int32_t str_len) +{ + int pos = 0; + int ret_pos = 0; + + while ( 1 ) { + pos = ubrk_next(bi); + + if ( UBRK_DONE == pos ) { + break; + } + + if ( pos > bsize ) { + break; + } + + ret_pos = pos; + } + + return ret_pos; +} +/* }}} */ + +/* {{{ grapheme_extract_count_iter - grapheme iterator for grapheme_extract COUNT */ +static inline int32_t +grapheme_extract_count_iter(UBreakIterator *bi, int32_t size, unsigned char *pstr, int32_t str_len) +{ + int next_pos = 0; + int ret_pos = 0; + + while ( size ) { + next_pos = ubrk_next(bi); + + if ( UBRK_DONE == next_pos ) { + break; + } + ret_pos = next_pos; + size--; + } + + return ret_pos; +} +/* }}} */ + +/* {{{ grapheme extract iter function pointer array */ +typedef int32_t (*grapheme_extract_iter)(UBreakIterator * /*bi*/, int32_t /*size*/, unsigned char * /*pstr*/, int32_t /*str_len*/); + +static const grapheme_extract_iter grapheme_extract_iters[] = { + &grapheme_extract_count_iter, + &grapheme_extract_bytecount_iter, + &grapheme_extract_charcount_iter, +}; +/* }}} */ + +/* {{{ Function to extract a sequence of default grapheme clusters */ +U_CFUNC PHP_FUNCTION(grapheme_extract) +{ + char *str, *pstr; + UText ut = UTEXT_INITIALIZER; + size_t str_len; + zend_long size; /* maximum number of grapheme clusters, bytes, or characters (based on extract_type) to return */ + zend_long lstart = 0; /* starting position in str in bytes */ + int32_t start = 0; + zend_long extract_type = GRAPHEME_EXTRACT_TYPE_COUNT; + UErrorCode status; + unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; + UBreakIterator* bi = nullptr; + int ret_pos; + zval *next = nullptr; /* return offset of next part of the string */ + + ZEND_PARSE_PARAMETERS_START(2, 5) + Z_PARAM_STRING(str, str_len) + Z_PARAM_LONG(size) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(extract_type) + Z_PARAM_LONG(lstart) + Z_PARAM_ZVAL(next) + ZEND_PARSE_PARAMETERS_END(); + + if (lstart < 0) { + lstart += str_len; + } + + if ( nullptr != next ) { + ZEND_ASSERT(Z_ISREF_P(next)); + ZEND_TRY_ASSIGN_REF_LONG(next, lstart); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + + if ( extract_type < GRAPHEME_EXTRACT_TYPE_MIN || extract_type > GRAPHEME_EXTRACT_TYPE_MAX ) { + zend_argument_value_error(3, "must be one of GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS"); + RETURN_THROWS(); + } + + if ( lstart > INT32_MAX || lstart < 0 || (size_t)lstart >= str_len ) { + intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR, "start not contained in string"); + RETURN_FALSE; + } + + if (size < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + + if (size > INT32_MAX) { + zend_argument_value_error(2, "is too large"); + RETURN_THROWS(); + } + + if (size == 0) { + RETURN_EMPTY_STRING(); + } + + /* we checked that it will fit: */ + start = (int32_t) lstart; + + pstr = str + start; + + /* just in case pstr points in the middle of a character, move forward to the start of the next char */ + if ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) { + char *str_end = str + str_len; + + while ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) { + pstr++; + start++; + if ( pstr >= str_end ) { + intl_error_set( nullptr, U_ILLEGAL_ARGUMENT_ERROR, + "grapheme_extract: invalid input string"); + + RETURN_FALSE; + } + } + } + + str_len -= (pstr - str); + + /* if the string is all ASCII up to size+1 - or str_len whichever is first - then we are done. + (size + 1 because the size-th character might be the beginning of a grapheme cluster) + */ + + if ( -1 != grapheme_ascii_check((unsigned char *)pstr, MIN(size + 1, str_len)) ) { + size_t nsize = MIN(size, str_len); + if ( nullptr != next ) { + ZEND_TRY_ASSIGN_REF_LONG(next, start + nsize); + } + RETURN_STRINGL(pstr, nsize); + } + + status = U_ZERO_ERROR; + utext_openUTF8(&ut, pstr, str_len, &status); + + if ( U_FAILURE( status ) ) { + /* Set global error code. */ + intl_error_set_code( nullptr, status ); + + /* Set error messages. */ + intl_error_set_custom_msg( nullptr, "Error opening UTF-8 text"); + + RETURN_FALSE; + } + + bi = nullptr; + status = U_ZERO_ERROR; + bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); + + ubrk_setUText(bi, &ut, &status); + /* if the caller put us in the middle of a grapheme, we can't detect it in all cases since we + can't back up. So, we will not do anything. */ + + /* now we need to find the end of the chunk the user wants us to return */ + /* it's ok to convert str_len to in32_t since if it were too big intl_convert_utf8_to_utf16 above would fail */ + ret_pos = (*grapheme_extract_iters[extract_type])(bi, size, (unsigned char *)pstr, (int32_t)str_len); + + utext_close(&ut); + ubrk_close(bi); + + if ( nullptr != next ) { + ZEND_TRY_ASSIGN_REF_LONG(next, start + ret_pos); + } + + RETURN_STRINGL(((char *)pstr), ret_pos); +} + +U_CFUNC PHP_FUNCTION(grapheme_str_split) +{ + char *pstr, *end; + zend_string *str; + zend_long split_len = 1; + + unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; + UErrorCode ustatus = U_ZERO_ERROR; + int32_t pos, current, i, end_len = 0; + UBreakIterator* bi; + UText *ut = nullptr; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(str) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(split_len) + ZEND_PARSE_PARAMETERS_END(); + + if (split_len <= 0 || split_len > UINT_MAX / 4) { + zend_argument_value_error(2, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); + RETURN_THROWS(); + } + + if (ZSTR_LEN(str) == 0) { + RETURN_EMPTY_ARRAY(); + } + + pstr = ZSTR_VAL(str); + ut = utext_openUTF8(ut, pstr, ZSTR_LEN(str), &ustatus); + + if ( U_FAILURE( ustatus ) ) { + /* Set global error code. */ + intl_error_set_code( nullptr, ustatus ); + + /* Set error messages. */ + intl_error_set_custom_msg( nullptr, "Error opening UTF-8 text"); + + RETURN_FALSE; + } + + bi = nullptr; + ustatus = U_ZERO_ERROR; + bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &ustatus ); + + if( U_FAILURE(ustatus) ) { + RETURN_FALSE; + } + + ubrk_setUText(bi, ut, &ustatus); + + pos = 0; + array_init(return_value); + + for (end = pstr, i = 0, current = 0; pos != UBRK_DONE;) { + end_len = pos - current; + pos = ubrk_next(bi); + + if (i == split_len - 1) { + if ( pos != UBRK_DONE ) { + add_next_index_stringl(return_value, pstr, pos - current); + end = pstr + pos - current; + i = 0; + } + pstr += pos - current; + current = pos; + } else { + i += 1; + } + } + + if (i != 0 && end_len != 0) { + add_next_index_stringl(return_value, end, end_len); + } + + utext_close(ut); + ubrk_close(bi); +} + +U_CFUNC PHP_FUNCTION(grapheme_levenshtein) +{ + zend_string *string1, *string2; + zend_long cost_ins = 1; + zend_long cost_rep = 1; + zend_long cost_del = 1; + char *locale = ""; + size_t locale_len = 0; + + ZEND_PARSE_PARAMETERS_START(2, 6) + Z_PARAM_STR(string1) + Z_PARAM_STR(string2) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(cost_ins) + Z_PARAM_LONG(cost_rep) + Z_PARAM_LONG(cost_del) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if (cost_ins <= 0 || cost_ins > UINT_MAX / 4) { + zend_argument_value_error(3, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); + RETURN_THROWS(); + } + + if (cost_rep <= 0 || cost_rep > UINT_MAX / 4) { + zend_argument_value_error(4, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); + RETURN_THROWS(); + } + + if (cost_del <= 0 || cost_del > UINT_MAX / 4) { + zend_argument_value_error(5, "must be greater than 0 and less than or equal to %d", UINT_MAX / 4); + RETURN_THROWS(); + } + + zend_long c0, c1, c2; + zend_long retval; + size_t i2; + char *pstr1, *pstr2; + + UChar *ustring1 = nullptr; + UChar *ustring2 = nullptr; + + int32_t ustring1_len = 0; + int32_t ustring2_len = 0; + int32_t current1 = 0; + int32_t current2 = 0; + int32_t pos1 = 0; + int32_t pos2 = 0; + + UCollator *collator = nullptr; + + UErrorCode ustatus = U_ZERO_ERROR; + + /* When all costs are equal, levenshtein fulfills the requirements of a metric, which means + * that the distance is symmetric. If string1 is shorter than string2 we can save memory (and CPU time) + * by having shorter rows (p1 & p2). */ + if (ZSTR_LEN(string1) < ZSTR_LEN(string2) && cost_ins == cost_rep && cost_rep == cost_del) { + zend_string *tmp = string1; + string1 = string2; + string2 = tmp; + } + + pstr1 = ZSTR_VAL(string1); + pstr2 = ZSTR_VAL(string2); + + intl_convert_utf8_to_utf16(&ustring1, &ustring1_len, pstr1, ZSTR_LEN(string1), &ustatus); + + if (U_FAILURE(ustatus)) { + intl_error_set_code(NULL, ustatus); + + intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16"); + RETVAL_FALSE; + goto out_ustring1; + } + + intl_convert_utf8_to_utf16(&ustring2, &ustring2_len, pstr2, ZSTR_LEN(string2), &ustatus); + + if (U_FAILURE(ustatus)) { + intl_error_set_code(NULL, ustatus); + + intl_error_set_custom_msg(NULL, "Error converting input string to UTF-16"); + RETVAL_FALSE; + goto out_ustring2; + } + + UBreakIterator *bi1, *bi2; + + int32_t strlen_1, strlen_2; + strlen_1 = grapheme_split_string(ustring1, ustring1_len, nullptr, 0); + strlen_2 = grapheme_split_string(ustring2, ustring2_len, nullptr, 0); + if (UNEXPECTED(strlen_1 < 0 || strlen_2 < 0)) { + RETVAL_FALSE; + goto out_ustring2; + } + + if (strlen_1 == 0) { + RETVAL_LONG(strlen_2 * cost_ins); + goto out_ustring2; + } + if (strlen_2 == 0) { + RETVAL_LONG(strlen_1 * cost_del); + goto out_ustring2; + } + + unsigned char u_break_iterator_buffer1[U_BRK_SAFECLONE_BUFFERSIZE]; + unsigned char u_break_iterator_buffer2[U_BRK_SAFECLONE_BUFFERSIZE]; + bi1 = grapheme_get_break_iterator(u_break_iterator_buffer1, &ustatus); + if (U_FAILURE(ustatus)) { + intl_error_set_code(NULL, ustatus); + intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #1 ($string1)"); + RETVAL_FALSE; + goto out_bi1; + } + + bi2 = grapheme_get_break_iterator(u_break_iterator_buffer2, &ustatus); + if (U_FAILURE(ustatus)) { + intl_error_set_code(NULL, ustatus); + intl_error_set_custom_msg(NULL, "Error on grapheme_get_break_iterator for argument #2 ($string2)"); + RETVAL_FALSE; + goto out_bi2; + } + + ubrk_setText(bi1, ustring1, ustring1_len, &ustatus); + if (U_FAILURE(ustatus)) { + intl_error_set_code(NULL, ustatus); + + intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #1 ($string1)"); + RETVAL_FALSE; + goto out_bi2; + } + + ubrk_setText(bi2, ustring2, ustring2_len, &ustatus); + if (U_FAILURE(ustatus)) { + intl_error_set_code(NULL, ustatus); + + intl_error_set_custom_msg(NULL, "Error on ubrk_setText for argument #2 ($string2)"); + RETVAL_FALSE; + goto out_bi2; + } + collator = ucol_open(locale, &ustatus); + if (U_FAILURE(ustatus)) { + intl_error_set_code(NULL, ustatus); + + intl_error_set_custom_msg(NULL, "Error on ucol_open"); + RETVAL_FALSE; + goto out_collator; + } + + zend_long *p1, *p2, *tmp; + p1 = reinterpret_cast(safe_emalloc((size_t) strlen_2 + 1, sizeof(zend_long), 0)); + p2 = reinterpret_cast(safe_emalloc((size_t) strlen_2 + 1, sizeof(zend_long), 0)); + + for (i2 = 0; i2 <= strlen_2; i2++) { + p1[i2] = i2 * cost_ins; + } + + while (true) { + current1 = ubrk_current(bi1); + pos1 = ubrk_next(bi1); + if (pos1 == UBRK_DONE) { + break; + } + p2[0] = p1[0] + cost_del; + for (i2 = 0, pos2 = 0; pos2 != UBRK_DONE; i2++) { + current2 = ubrk_current(bi2); + pos2 = ubrk_next(bi2); + if (pos2 == UBRK_DONE) { + break; + } + if (ucol_strcoll(collator, ustring1 + current1, pos1 - current1, ustring2 + current2, pos2 - current2) == UCOL_EQUAL) { + c0 = p1[i2]; + } else { + c0 = p1[i2] + cost_rep; + } + c1 = p1[i2 + 1] + cost_del; + if (c1 < c0) { + c0 = c1; + } + c2 = p2[i2] + cost_ins; + if (c2 < c0) { + c0 = c2; + } + p2[i2 + 1] = c0; + } + ubrk_first(bi2); + tmp = p1; + p1 = p2; + p2 = tmp; + } + + retval = p1[strlen_2]; + RETVAL_LONG(retval); + + efree(p2); + efree(p1); + +out_collator: + ucol_close(collator); +out_bi2: + ubrk_close(bi2); +out_bi1: + ubrk_close(bi1); +out_ustring2: + efree(ustring2); +out_ustring1: + efree(ustring1); +} + +U_CFUNC PHP_FUNCTION(grapheme_strrev) +{ + zend_string *string; + UText *ut = nullptr; + UErrorCode ustatus = U_ZERO_ERROR; + UBreakIterator *bi; + char *pstr, *end, *p; + zend_string *ret; + int32_t pos = 0, current = 0, end_len = 0; + unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(string) + ZEND_PARSE_PARAMETERS_END(); + + if (ZSTR_LEN(string) == 0) { + RETURN_EMPTY_STRING(); + } + + pstr = ZSTR_VAL(string); + ut = utext_openUTF8(ut, pstr, ZSTR_LEN(string), &ustatus); + + if (U_FAILURE(ustatus)) { + intl_error_set_code(nullptr, ustatus); + intl_error_set_custom_msg(nullptr, "Error opening UTF-8 text"); + + RETVAL_FALSE; + goto close; + } + + bi = nullptr; + ustatus = U_ZERO_ERROR; + + bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &ustatus ); + ret = zend_string_alloc(ZSTR_LEN(string), 0); + p = ZSTR_VAL(ret); + + ubrk_setUText(bi, ut, &ustatus); + pos = ubrk_last(bi); + if (pos == UBRK_DONE) { + goto ubrk_end; + } + + current = ZSTR_LEN(string); + for (end = pstr; pos != UBRK_DONE; ) { + pos = ubrk_previous(bi); + end_len = current - pos; + for (int32_t j = 0; j < end_len; j++) { + *p++ = *(pstr + pos + j); + } + current = pos; + } +ubrk_end: + RETVAL_NEW_STR(ret); + ubrk_close(bi); +close: + utext_close(ut); +} + +/* }}} */ diff --git a/ext/intl/grapheme/grapheme_util.c b/ext/intl/grapheme/grapheme_util.c deleted file mode 100644 index 501b9dfb221d..000000000000 --- a/ext/intl/grapheme/grapheme_util.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Ed Batutis | - +----------------------------------------------------------------------+ - */ - -/* {{{ includes */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "grapheme.h" -#include "grapheme_util.h" -#include "intl_common.h" - -#include -#include -#include -#include -#include - -ZEND_EXTERN_MODULE_GLOBALS( intl ) - -/* }}} */ - -/* {{{ grapheme_close_global_iterator - clean up */ -void -grapheme_close_global_iterator( void ) -{ - UBreakIterator *global_break_iterator = INTL_G( grapheme_iterator ); - - if ( NULL != global_break_iterator ) { - ubrk_close(global_break_iterator); - } -} -/* }}} */ - -/* {{{ grapheme_substr_ascii f='from' - starting point, l='length' */ -void grapheme_substr_ascii(char *str, size_t str_len, int32_t f, int32_t l, char **sub_str, int32_t *sub_str_len) -{ - int32_t str_len2 = (int32_t)str_len; /* in order to avoid signed/unsigned problems */ - *sub_str = NULL; - - if(str_len > INT32_MAX) { - /* We cannot return long strings from ICU functions, so we won't here too */ - return; - } - - /* if "from" position is negative, count start position from the end - * of the string - */ - if (f < 0) { - f = str_len2 + f; - if (f < 0) { - f = 0; - } - } else if (f > str_len2) { - f = str_len2; - } - - /* if "length" position is negative, set it to the length - * needed to stop that many chars from the end of the string - */ - if (l < 0) { - l = (str_len2 - f) + l; - if (l < 0) { - l = 0; - } - } else if (l > str_len2 - f) { - l = str_len2 - f; - } - - *sub_str = str + f; - *sub_str_len = l; -} -/* }}} */ - -#define STRPOS_CHECK_STATUS(status, error) \ - if ( U_FAILURE( (status) ) ) { \ - intl_error_set_code( NULL, (status) ); \ - intl_error_set_custom_msg( NULL, (error), 0 ); \ - ret_pos = -1; \ - goto finish; \ - } - - -/* {{{ grapheme_strpos_utf16 - strrpos using utf16*/ -int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case, int last) -{ - UChar *uhaystack = NULL, *uneedle = NULL; - int32_t uhaystack_len = 0, uneedle_len = 0, char_pos, ret_pos, offset_pos = 0; - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; - UBreakIterator* bi = NULL; - UErrorCode status; - UStringSearch* src = NULL; - - if(puchar_pos) { - *puchar_pos = -1; - } - /* convert the strings to UTF-16. */ - - status = U_ZERO_ERROR; - intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, haystack, haystack_len, &status ); - STRPOS_CHECK_STATUS(status, "Error converting input string to UTF-16"); - - status = U_ZERO_ERROR; - intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, needle, needle_len, &status ); - STRPOS_CHECK_STATUS(status, "Error converting needle string to UTF-16"); - - /* get a pointer to the haystack taking into account the offset */ - status = U_ZERO_ERROR; - bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); - STRPOS_CHECK_STATUS(status, "Failed to get iterator"); - status = U_ZERO_ERROR; - ubrk_setText(bi, uhaystack, uhaystack_len, &status); - STRPOS_CHECK_STATUS(status, "Failed to set up iterator"); - - if (uneedle_len == 0) { - offset_pos = grapheme_get_haystack_offset(bi, offset); - if (offset_pos == -1) { - zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); - ret_pos = -1; - goto finish; - } - ret_pos = last && offset >= 0 ? uhaystack_len : offset_pos; - goto finish; - } - - status = U_ZERO_ERROR; - src = usearch_open(uneedle, uneedle_len, uhaystack, uhaystack_len, "", bi, &status); - STRPOS_CHECK_STATUS(status, "Error creating search object"); - - if(f_ignore_case) { - UCollator *coll = usearch_getCollator(src); - status = U_ZERO_ERROR; - ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &status); - STRPOS_CHECK_STATUS(status, "Error setting collation strength"); - usearch_reset(src); - } - - if(offset != 0) { - offset_pos = grapheme_get_haystack_offset(bi, offset); - if (offset_pos == -1) { - zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); - ret_pos = -1; - goto finish; - } - status = U_ZERO_ERROR; - usearch_setOffset(src, last ? 0 : offset_pos, &status); - STRPOS_CHECK_STATUS(status, "Invalid search offset"); - } - - - if(last) { - if (offset >= 0) { - char_pos = usearch_last(src, &status); - if(char_pos < offset_pos) { - /* last one is beyond our start offset */ - char_pos = USEARCH_DONE; - } - } else { - /* searching backwards is broken, so we search forwards, albeit it's less efficient */ - int32_t prev_pos = USEARCH_DONE; - do { - char_pos = usearch_next(src, &status); - if (char_pos == USEARCH_DONE || char_pos > offset_pos) { - char_pos = prev_pos; - break; - } - prev_pos = char_pos; - } while(1); - } - } else { - char_pos = usearch_next(src, &status); - } - STRPOS_CHECK_STATUS(status, "Error looking up string"); - if(char_pos != USEARCH_DONE && ubrk_isBoundary(bi, char_pos)) { - ret_pos = grapheme_count_graphemes(bi, uhaystack,char_pos); - if(puchar_pos) { - *puchar_pos = char_pos; - } - } else { - ret_pos = -1; - } - -finish: - if (uhaystack) { - efree( uhaystack ); - } - if (uneedle) { - efree( uneedle ); - } - if (bi) { - ubrk_close (bi); - } - if (src) { - usearch_close (src); - } - - return ret_pos; -} - -/* }}} */ - -/* {{{ grapheme_ascii_check: ASCII check */ -zend_long grapheme_ascii_check(const unsigned char *day, size_t len) -{ - int ret_len = len; - while ( len-- ) { - if ( *day++ > 0x7f || (*day == '\n' && *(day - 1) == '\r') ) - return -1; - } - - return ret_len; -} - -/* }}} */ - -/* {{{ grapheme_split_string: find and optionally return grapheme boundaries */ -int32_t grapheme_split_string(const UChar *text, int32_t text_length, int boundary_array[], int boundary_array_len ) -{ - unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; - UErrorCode status = U_ZERO_ERROR; - int ret_len, pos; - UBreakIterator* bi; - - bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &status ); - - if( U_FAILURE(status) ) { - return -1; - } - - ubrk_setText(bi, text, text_length, &status); - - pos = 0; - - for ( ret_len = 0; pos != UBRK_DONE; ) { - - pos = ubrk_next(bi); - - if ( pos != UBRK_DONE ) { - - if ( NULL != boundary_array && ret_len < boundary_array_len ) { - boundary_array[ret_len] = pos; - } - - ret_len++; - } - } - - ubrk_close(bi); - - return ret_len; -} -/* }}} */ - -/* {{{ grapheme_count_graphemes */ -int32_t grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len) -{ - int ret_len = 0; - int pos = 0; - UErrorCode status = U_ZERO_ERROR; - - ubrk_setText(bi, string, string_len, &status); - - do { - - pos = ubrk_next(bi); - - if ( UBRK_DONE != pos ) { - ret_len++; - } - - } while ( UBRK_DONE != pos ); - - return ret_len; -} -/* }}} */ - - -/* {{{ grapheme_get_haystack_offset - bump the haystack pointer based on the grapheme count offset */ -int32_t grapheme_get_haystack_offset(UBreakIterator* bi, int32_t offset) -{ - int32_t pos; - int32_t (*iter_op)(UBreakIterator* bi); - int iter_incr; - - if ( 0 == offset ) { - return 0; - } - - if ( offset < 0 ) { - iter_op = ubrk_previous; - ubrk_last(bi); /* one past the end */ - iter_incr = 1; - } - else { - iter_op = ubrk_next; - iter_incr = -1; - } - - pos = 0; - - while ( pos != UBRK_DONE && offset != 0 ) { - - pos = iter_op(bi); - - if ( UBRK_DONE != pos ) { - offset += iter_incr; - } - } - - if ( offset != 0 ) { - return -1; - } - - return pos; -} -/* }}} */ - -/* {{{ grapheme_strrpos_ascii: borrowed from the php ext/standard/string.c */ -zend_long grapheme_strrpos_ascii(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset) -{ - char *p, *e; - - if (offset >= 0) { - p = haystack + offset; - e = haystack + haystack_len - needle_len; - } else { - p = haystack; - if (needle_len > (size_t)-offset) { - e = haystack + haystack_len - needle_len; - } else { - e = haystack + haystack_len + offset; - } - } - - if (needle_len == 1) { - /* Single character search can shortcut memcmps */ - while (e >= p) { - if (*e == *needle) { - return (e - p + (offset > 0 ? offset : 0)); - } - e--; - } - return -1; - } - - while (e >= p) { - if (memcmp(e, needle, needle_len) == 0) { - return (e - p + (offset > 0 ? offset : 0)); - } - e--; - } - - return -1; -} - -/* }}} */ - -/* {{{ grapheme_get_break_iterator: get a clone of the global character break iterator */ -UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status ) -{ - UBreakIterator *global_break_iterator = INTL_G( grapheme_iterator ); - - if ( NULL == global_break_iterator ) { - - global_break_iterator = ubrk_open(UBRK_CHARACTER, - NULL, /* icu default locale - locale has no effect on this iterator */ - NULL, /* text not set in global iterator */ - 0, /* text length = 0 */ - status); - - INTL_G(grapheme_iterator) = global_break_iterator; - } - -#if U_ICU_VERSION_MAJOR_NUM >= 69 - return ubrk_clone(global_break_iterator, status); -#else - int32_t buffer_size = U_BRK_SAFECLONE_BUFFERSIZE; - - return ubrk_safeClone(global_break_iterator, stack_buffer, &buffer_size, status); -#endif -} -/* }}} */ diff --git a/ext/intl/grapheme/grapheme_util.cpp b/ext/intl/grapheme/grapheme_util.cpp new file mode 100644 index 000000000000..d5bbef6009cd --- /dev/null +++ b/ext/intl/grapheme/grapheme_util.cpp @@ -0,0 +1,401 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Author: Ed Batutis | + +----------------------------------------------------------------------+ + */ + +/* {{{ includes */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include +#include "grapheme.h" +#include "grapheme_util.h" +#include "intl_common.h" +} + +#include +#include +#include +#include +#include + +ZEND_EXTERN_MODULE_GLOBALS( intl ) + +/* }}} */ + +/* {{{ grapheme_close_global_iterator - clean up */ +U_CFUNC void +grapheme_close_global_iterator( void ) +{ + UBreakIterator *global_break_iterator = INTL_G( grapheme_iterator ); + + if ( NULL != global_break_iterator ) { + ubrk_close(global_break_iterator); + } +} +/* }}} */ + +/* {{{ grapheme_substr_ascii f='from' - starting point, l='length' */ +U_CFUNC void grapheme_substr_ascii(char *str, size_t str_len, int32_t f, int32_t l, char **sub_str, int32_t *sub_str_len) +{ + int32_t str_len2 = (int32_t)str_len; /* in order to avoid signed/unsigned problems */ + *sub_str = NULL; + + if(str_len > INT32_MAX) { + /* We cannot return long strings from ICU functions, so we won't here too */ + return; + } + + /* if "from" position is negative, count start position from the end + * of the string + */ + if (f < 0) { + f = str_len2 + f; + if (f < 0) { + f = 0; + } + } else if (f > str_len2) { + f = str_len2; + } + + /* if "length" position is negative, set it to the length + * needed to stop that many chars from the end of the string + */ + if (l < 0) { + l = (str_len2 - f) + l; + if (l < 0) { + l = 0; + } + } else if (l > str_len2 - f) { + l = str_len2 - f; + } + + *sub_str = str + f; + *sub_str_len = l; +} +/* }}} */ + +#define STRPOS_CHECK_STATUS(status, error) \ + if ( U_FAILURE( (status) ) ) { \ + intl_error_set_code( NULL, (status) ); \ + intl_error_set_custom_msg( NULL, (error)); \ + ret_pos = -1; \ + goto finish; \ + } + + +/* {{{ grapheme_strpos_utf16 - strrpos using utf16*/ +U_CFUNC int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int32_t *puchar_pos, int f_ignore_case, int last, const char* locale) +{ + UChar *uhaystack = NULL, *uneedle = NULL; + int32_t uhaystack_len = 0, uneedle_len = 0, char_pos, ret_pos, offset_pos = 0; + unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; + UBreakIterator* bi = NULL; + UErrorCode status; + UStringSearch* src = NULL; + + if(puchar_pos) { + *puchar_pos = -1; + } + /* convert the strings to UTF-16. */ + + status = U_ZERO_ERROR; + intl_convert_utf8_to_utf16(&uhaystack, &uhaystack_len, haystack, haystack_len, &status ); + STRPOS_CHECK_STATUS(status, "Error converting input string to UTF-16"); + + status = U_ZERO_ERROR; + intl_convert_utf8_to_utf16(&uneedle, &uneedle_len, needle, needle_len, &status ); + STRPOS_CHECK_STATUS(status, "Error converting needle string to UTF-16"); + + /* get a pointer to the haystack taking into account the offset */ + status = U_ZERO_ERROR; + bi = grapheme_get_break_iterator(u_break_iterator_buffer, &status ); + STRPOS_CHECK_STATUS(status, "Failed to get iterator"); + status = U_ZERO_ERROR; + ubrk_setText(bi, uhaystack, uhaystack_len, &status); + STRPOS_CHECK_STATUS(status, "Failed to set up iterator"); + + if (uneedle_len == 0) { + offset_pos = grapheme_get_haystack_offset(bi, offset); + if (offset_pos == -1) { + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + ret_pos = -1; + goto finish; + } + ret_pos = last && offset >= 0 ? uhaystack_len : offset_pos; + goto finish; + } + + status = U_ZERO_ERROR; + src = usearch_open(uneedle, uneedle_len, uhaystack, uhaystack_len, locale, bi, &status); + STRPOS_CHECK_STATUS(status, "Error creating search object"); + + if(f_ignore_case) { + UCollator *coll = usearch_getCollator(src); + status = U_ZERO_ERROR; + ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_SECONDARY, &status); + STRPOS_CHECK_STATUS(status, "Error setting collation strength"); + usearch_reset(src); + } + + if(offset != 0) { + offset_pos = grapheme_get_haystack_offset(bi, offset); + if (offset_pos == -1) { + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + ret_pos = -1; + goto finish; + } + status = U_ZERO_ERROR; + usearch_setOffset(src, last ? 0 : offset_pos, &status); + STRPOS_CHECK_STATUS(status, "Invalid search offset"); + } + + + if(last) { + if (offset >= 0) { + char_pos = usearch_last(src, &status); + if(char_pos < offset_pos) { + /* last one is beyond our start offset */ + char_pos = USEARCH_DONE; + } + } else { + /* searching backwards is broken, so we search forwards, albeit it's less efficient */ + int32_t prev_pos = USEARCH_DONE; + do { + char_pos = usearch_next(src, &status); + if (char_pos == USEARCH_DONE || char_pos > offset_pos) { + char_pos = prev_pos; + break; + } + prev_pos = char_pos; + } while(1); + } + } else { + char_pos = usearch_next(src, &status); + } + STRPOS_CHECK_STATUS(status, "Error looking up string"); + if(char_pos != USEARCH_DONE && ubrk_isBoundary(bi, char_pos)) { + ret_pos = grapheme_count_graphemes(bi, uhaystack,char_pos); + if(puchar_pos) { + *puchar_pos = char_pos; + } + } else { + ret_pos = -1; + } + +finish: + if (uhaystack) { + efree( uhaystack ); + } + if (uneedle) { + efree( uneedle ); + } + if (bi) { + ubrk_close (bi); + } + if (src) { + usearch_close (src); + } + + return ret_pos; +} + +/* }}} */ + +/* {{{ grapheme_ascii_check: ASCII check */ +U_CFUNC zend_long grapheme_ascii_check(const unsigned char *day, size_t len) +{ + int ret_len = len; + while ( len-- ) { + if ( *day++ > 0x7f || (*day == '\n' && *(day - 1) == '\r') ) + return -1; + } + + return ret_len; +} + +/* }}} */ + +/* {{{ grapheme_split_string: find and optionally return grapheme boundaries */ +U_CFUNC int32_t grapheme_split_string(const UChar *text, int32_t text_length, int boundary_array[], int boundary_array_len ) +{ + unsigned char u_break_iterator_buffer[U_BRK_SAFECLONE_BUFFERSIZE]; + UErrorCode status = U_ZERO_ERROR; + int ret_len, pos; + UBreakIterator* bi; + + bi = grapheme_get_break_iterator((void*)u_break_iterator_buffer, &status ); + + if( U_FAILURE(status) ) { + return -1; + } + + ubrk_setText(bi, text, text_length, &status); + + pos = 0; + + for ( ret_len = 0; pos != UBRK_DONE; ) { + + pos = ubrk_next(bi); + + if ( pos != UBRK_DONE ) { + + if ( NULL != boundary_array && ret_len < boundary_array_len ) { + boundary_array[ret_len] = pos; + } + + ret_len++; + } + } + + ubrk_close(bi); + + return ret_len; +} +/* }}} */ + +/* {{{ grapheme_count_graphemes */ +U_CFUNC int32_t grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t string_len) +{ + int ret_len = 0; + int pos = 0; + UErrorCode status = U_ZERO_ERROR; + + ubrk_setText(bi, string, string_len, &status); + + do { + + pos = ubrk_next(bi); + + if ( UBRK_DONE != pos ) { + ret_len++; + } + + } while ( UBRK_DONE != pos ); + + return ret_len; +} +/* }}} */ + + +/* {{{ grapheme_get_haystack_offset - bump the haystack pointer based on the grapheme count offset */ +U_CFUNC int32_t grapheme_get_haystack_offset(UBreakIterator* bi, int32_t offset) +{ + int32_t pos; + int32_t (*iter_op)(UBreakIterator* bi); + int iter_incr; + + if ( 0 == offset ) { + return 0; + } + + if ( offset < 0 ) { + iter_op = ubrk_previous; + ubrk_last(bi); /* one past the end */ + iter_incr = 1; + } + else { + iter_op = ubrk_next; + iter_incr = -1; + } + + pos = 0; + + while ( pos != UBRK_DONE && offset != 0 ) { + + pos = iter_op(bi); + + if ( UBRK_DONE != pos ) { + offset += iter_incr; + } + } + + if ( offset != 0 ) { + return -1; + } + + return pos; +} +/* }}} */ + +/* {{{ grapheme_strrpos_ascii: borrowed from the php ext/standard/string.c */ +U_CFUNC zend_long grapheme_strrpos_ascii(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset) +{ + char *p, *e; + + if (offset >= 0) { + p = haystack + offset; + e = haystack + haystack_len - needle_len; + } else { + p = haystack; + if (needle_len > (size_t)-offset) { + e = haystack + haystack_len - needle_len; + } else { + e = haystack + haystack_len + offset; + } + } + + if (needle_len == 1) { + /* Single character search can shortcut memcmps */ + while (e >= p) { + if (*e == *needle) { + return (e - p + (offset > 0 ? offset : 0)); + } + e--; + } + return -1; + } + + while (e >= p) { + if (memcmp(e, needle, needle_len) == 0) { + return (e - p + (offset > 0 ? offset : 0)); + } + e--; + } + + return -1; +} + +/* }}} */ + +/* {{{ grapheme_get_break_iterator: get a clone of the global character break iterator */ +U_CFUNC UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status ) +{ + UBreakIterator *global_break_iterator = INTL_G( grapheme_iterator ); + + if ( NULL == global_break_iterator ) { + + global_break_iterator = ubrk_open(UBRK_CHARACTER, + NULL, /* icu default locale - locale has no effect on this iterator */ + NULL, /* text not set in global iterator */ + 0, /* text length = 0 */ + status); + + INTL_G(grapheme_iterator) = global_break_iterator; + } + +#if U_ICU_VERSION_MAJOR_NUM >= 69 + return ubrk_clone(global_break_iterator, status); +#else + int32_t buffer_size = U_BRK_SAFECLONE_BUFFERSIZE; + + return ubrk_safeClone(global_break_iterator, stack_buffer, &buffer_size, status); +#endif +} +/* }}} */ diff --git a/ext/intl/grapheme/grapheme_util.h b/ext/intl/grapheme/grapheme_util.h index d03194621acf..a1d67981d270 100644 --- a/ext/intl/grapheme/grapheme_util.h +++ b/ext/intl/grapheme/grapheme_util.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ @@ -15,6 +15,9 @@ #ifndef GRAPHEME_GRAPHEME_UTIL_H #define GRAPHEME_GRAPHEME_UTIL_H +#ifdef __cplusplus +extern "C" { +#endif #include "php_intl.h" #include "intl_convert.h" @@ -25,8 +28,8 @@ zend_long grapheme_ascii_check(const unsigned char *day, size_t len); void grapheme_substr_ascii(char *str, size_t str_len, int32_t f, int32_t l, char **sub_str, int32_t *sub_str_len); zend_long grapheme_strrpos_ascii(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset); -int32_t grapheme_strrpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int f_ignore_case); -int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int *puchar_pos, int f_ignore_case, int last); +int32_t grapheme_strrpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int f_ignore_case, const char *locale); +int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char *needle, size_t needle_len, int32_t offset, int *puchar_pos, int f_ignore_case, int last, const char *locale); int32_t grapheme_split_string(const UChar *text, int32_t text_length, int boundary_array[], int boundary_array_len ); @@ -35,6 +38,9 @@ int32_t grapheme_count_graphemes(UBreakIterator *bi, UChar *string, int32_t stri int32_t grapheme_get_haystack_offset(UBreakIterator* bi, int32_t offset); UBreakIterator* grapheme_get_break_iterator(void *stack_buffer, UErrorCode *status ); +#ifdef __cplusplus +} +#endif /* OUTSIDE_STRING: check if (possibly negative) long offset is outside the string with int32_t length */ #define OUTSIDE_STRING(offset, max_len) ( offset <= INT32_MIN || offset > INT32_MAX || (offset < 0 ? -offset > (zend_long) max_len : offset > (zend_long) max_len) ) diff --git a/ext/intl/idn/idn.c b/ext/intl/idn/idn.c deleted file mode 100644 index cd4546ad7f8b..000000000000 --- a/ext/intl/idn/idn.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Pierre A. Joye | - | Gustavo Lopes | - +----------------------------------------------------------------------+ - */ - -/* {{{ includes */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include - -#include "idn.h" -#include "intl_error.h" -/* }}} */ - -enum { - INTL_IDN_TO_ASCII = 0, - INTL_IDN_TO_UTF8 -}; - -/* like INTL_CHECK_STATUS, but as a function and varying the name of the func */ -static zend_result php_intl_idn_check_status(UErrorCode err, const char *msg) -{ - intl_error_set_code(NULL, err); - if (U_FAILURE(err)) { - char *buff; - spprintf(&buff, 0, "%s: %s", - get_active_function_name(), - msg); - intl_error_set_custom_msg(NULL, buff, 1); - efree(buff); - return FAILURE; - } - - return SUCCESS; -} - -static void php_intl_idn_to_46(INTERNAL_FUNCTION_PARAMETERS, - const zend_string *domain, uint32_t option, int mode, zval *idna_info) -{ - UErrorCode status = U_ZERO_ERROR; - UIDNA *uts46; - int32_t len; - int32_t buffer_capac; - zend_string *buffer; - UIDNAInfo info = UIDNA_INFO_INITIALIZER; - - uts46 = uidna_openUTS46(option, &status); - if (php_intl_idn_check_status(status, "failed to open UIDNA instance") == FAILURE) { - RETURN_FALSE; - } - - if (mode == INTL_IDN_TO_ASCII) { - buffer_capac = 255; - buffer = zend_string_alloc(buffer_capac, 0); - len = uidna_nameToASCII_UTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain), - ZSTR_VAL(buffer), buffer_capac, &info, &status); - } else { - buffer_capac = 252*4; - buffer = zend_string_alloc(buffer_capac, 0); - len = uidna_nameToUnicodeUTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain), - ZSTR_VAL(buffer), buffer_capac, &info, &status); - } - if (len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE) { - uidna_close(uts46); - zend_string_efree(buffer); - RETURN_FALSE; - } - - ZSTR_VAL(buffer)[len] = '\0'; - ZSTR_LEN(buffer) = len; - - if (idna_info) { - add_assoc_str_ex(idna_info, "result", sizeof("result")-1, zend_string_copy(buffer)); - add_assoc_bool_ex(idna_info, "isTransitionalDifferent", - sizeof("isTransitionalDifferent")-1, info.isTransitionalDifferent); - add_assoc_long_ex(idna_info, "errors", sizeof("errors")-1, (zend_long)info.errors); - } - - if (info.errors == 0) { - RETVAL_STR(buffer); - } else { - zend_string_release_ex(buffer, false); - RETVAL_FALSE; - } - - uidna_close(uts46); -} - -static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) -{ - zend_string *domain; - zend_long option = UIDNA_DEFAULT, - variant = INTL_IDN_VARIANT_UTS46; - zval *idna_info = NULL; - - intl_error_reset(NULL); - - ZEND_PARSE_PARAMETERS_START(1, 4) - Z_PARAM_STR(domain) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(option) - Z_PARAM_LONG(variant) - Z_PARAM_ZVAL(idna_info) - ZEND_PARSE_PARAMETERS_END(); - - if (ZSTR_LEN(domain) == 0) { - zend_argument_must_not_be_empty_error(1); - RETURN_THROWS(); - } - if (ZSTR_LEN(domain) > INT32_MAX - 1) { - zend_argument_value_error(1, "must be less than " PRId32 " bytes", INT32_MAX); - RETURN_THROWS(); - } - if (variant != INTL_IDN_VARIANT_UTS46) { - zend_argument_value_error(2, "must be INTL_IDNA_VARIANT_UTS46"); - RETURN_THROWS(); - } - /* don't check options; it wasn't checked before */ - - if (idna_info != NULL) { - idna_info = zend_try_array_init(idna_info); - if (!idna_info) { - RETURN_THROWS(); - } - } - - php_intl_idn_to_46(INTERNAL_FUNCTION_PARAM_PASSTHRU, domain, (uint32_t)option, mode, idna_info); -} - -/* {{{ Converts an Unicode domain to ASCII representation, as defined in the IDNA RFC */ -PHP_FUNCTION(idn_to_ascii) -{ - php_intl_idn_handoff(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_ASCII); -} -/* }}} */ - - -/* {{{ Converts an ASCII representation of the domain to Unicode (UTF-8), as defined in the IDNA RFC */ -PHP_FUNCTION(idn_to_utf8) -{ - php_intl_idn_handoff(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_UTF8); -} -/* }}} */ diff --git a/ext/intl/idn/idn.cpp b/ext/intl/idn/idn.cpp new file mode 100644 index 000000000000..28708eb93508 --- /dev/null +++ b/ext/intl/idn/idn.cpp @@ -0,0 +1,157 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Author: Pierre A. Joye | + | Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + +/* {{{ includes */ +#ifdef HAVE_CONFIG_H +#include +#endif + +extern "C" { +#include "../php_intl.h" +} +#include +#include + +#include "idn.h" + +extern "C" { +#include "intl_error.h" +} +/* }}} */ + +enum { + INTL_IDN_TO_ASCII = 0, + INTL_IDN_TO_UTF8 +}; + +/* like INTL_CHECK_STATUS, but as a function and varying the name of the func */ +static zend_result php_intl_idn_check_status(UErrorCode err, const char *msg) +{ + intl_error_set_code(NULL, err); + if (U_FAILURE(err)) { + intl_error_set_custom_msg(NULL, msg); + return FAILURE; + } + + return SUCCESS; +} + +static void php_intl_idn_to_46(INTERNAL_FUNCTION_PARAMETERS, + const zend_string *domain, uint32_t option, int mode, zval *idna_info) +{ + UErrorCode status = U_ZERO_ERROR; + UIDNA *uts46; + int32_t len; + int32_t buffer_capac; + zend_string *buffer; + UIDNAInfo info = UIDNA_INFO_INITIALIZER; + + uts46 = uidna_openUTS46(option, &status); + if (php_intl_idn_check_status(status, "failed to open UIDNA instance") == FAILURE) { + RETURN_FALSE; + } + + if (mode == INTL_IDN_TO_ASCII) { + buffer_capac = 255; + buffer = zend_string_alloc(buffer_capac, 0); + len = uidna_nameToASCII_UTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain), + ZSTR_VAL(buffer), buffer_capac, &info, &status); + } else { + buffer_capac = 252*4; + buffer = zend_string_alloc(buffer_capac, 0); + len = uidna_nameToUnicodeUTF8(uts46, ZSTR_VAL(domain), ZSTR_LEN(domain), + ZSTR_VAL(buffer), buffer_capac, &info, &status); + } + if (len >= buffer_capac || php_intl_idn_check_status(status, "failed to convert name") == FAILURE) { + uidna_close(uts46); + zend_string_efree(buffer); + RETURN_FALSE; + } + + ZSTR_VAL(buffer)[len] = '\0'; + ZSTR_LEN(buffer) = len; + + if (idna_info) { + add_assoc_str_ex(idna_info, "result", sizeof("result")-1, zend_string_copy(buffer)); + add_assoc_bool_ex(idna_info, "isTransitionalDifferent", + sizeof("isTransitionalDifferent")-1, info.isTransitionalDifferent); + add_assoc_long_ex(idna_info, "errors", sizeof("errors")-1, (zend_long)info.errors); + } + + if (info.errors == 0) { + RETVAL_STR(buffer); + } else { + zend_string_release_ex(buffer, false); + RETVAL_FALSE; + } + + uidna_close(uts46); +} + +static void php_intl_idn_handoff(INTERNAL_FUNCTION_PARAMETERS, int mode) +{ + zend_string *domain; + zend_long option = UIDNA_DEFAULT, + variant = INTL_IDN_VARIANT_UTS46; + zval *idna_info = NULL; + + intl_error_reset(NULL); + + ZEND_PARSE_PARAMETERS_START(1, 4) + Z_PARAM_STR(domain) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(option) + Z_PARAM_LONG(variant) + Z_PARAM_ZVAL(idna_info) + ZEND_PARSE_PARAMETERS_END(); + + if (ZSTR_LEN(domain) == 0) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + if (ZSTR_LEN(domain) > INT32_MAX - 1) { + zend_argument_value_error(1, "must be less than " PRId32 " bytes", INT32_MAX); + RETURN_THROWS(); + } + if (variant != INTL_IDN_VARIANT_UTS46) { + zend_argument_value_error(2, "must be INTL_IDNA_VARIANT_UTS46"); + RETURN_THROWS(); + } + /* don't check options; it wasn't checked before */ + + if (idna_info != NULL) { + idna_info = zend_try_array_init(idna_info); + if (!idna_info) { + RETURN_THROWS(); + } + } + + php_intl_idn_to_46(INTERNAL_FUNCTION_PARAM_PASSTHRU, domain, (uint32_t)option, mode, idna_info); +} + +/* {{{ Converts an Unicode domain to ASCII representation, as defined in the IDNA RFC */ +U_CFUNC PHP_FUNCTION(idn_to_ascii) +{ + php_intl_idn_handoff(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_ASCII); +} +/* }}} */ + + +/* {{{ Converts an ASCII representation of the domain to Unicode (UTF-8), as defined in the IDNA RFC */ +U_CFUNC PHP_FUNCTION(idn_to_utf8) +{ + php_intl_idn_handoff(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_UTF8); +} +/* }}} */ diff --git a/ext/intl/idn/idn.h b/ext/intl/idn/idn.h index 596e63f207e0..cf3af63a26ae 100644 --- a/ext/intl/idn/idn.h +++ b/ext/intl/idn/idn.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Pierre A. Joye | +----------------------------------------------------------------------+ diff --git a/ext/intl/intl_common.h b/ext/intl/intl_common.h index cef96325e9af..1fdb1c16efed 100644 --- a/ext/intl/intl_common.h +++ b/ext/intl/intl_common.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/intl_convert.c b/ext/intl/intl_convert.c index 39f70821e117..abbcc6c1fa73 100644 --- a/ext/intl/intl_convert.c +++ b/ext/intl/intl_convert.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/intl_convert.h b/ext/intl/intl_convert.h index 5cc3a671333d..443d373d55c2 100644 --- a/ext/intl/intl_convert.h +++ b/ext/intl/intl_convert.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | diff --git a/ext/intl/intl_convertcpp.cpp b/ext/intl/intl_convertcpp.cpp index b919c3fb4087..70d28e5c23ca 100644 --- a/ext/intl/intl_convertcpp.cpp +++ b/ext/intl/intl_convertcpp.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -72,7 +72,7 @@ zend_string* intl_charFromString(const UnicodeString &from, UErrorCode *status) const UChar *utf16buf = from.getBuffer(); int32_t actual_len; - u_strToUTF8WithSub(ZSTR_VAL(u8res), capacity, &actual_len, utf16buf, from.length(), + u_strToUTF8WithSub(ZSTR_VAL(u8res), capacity + 1, &actual_len, utf16buf, from.length(), U_SENTINEL, NULL, status); if (U_FAILURE(*status)) { diff --git a/ext/intl/intl_convertcpp.h b/ext/intl/intl_convertcpp.h index 28948c2e01ca..ef4310bac4ff 100644 --- a/ext/intl/intl_convertcpp.h +++ b/ext/intl/intl_convertcpp.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/intl_cppshims.h b/ext/intl/intl_cppshims.h index 169448a2edf3..d2bc5f9a240d 100644 --- a/ext/intl/intl_cppshims.h +++ b/ext/intl/intl_cppshims.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/intl_data.h b/ext/intl/intl_data.h index 23320a9ff113..c36f0adf5665 100644 --- a/ext/intl/intl_data.h +++ b/ext/intl/intl_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -48,7 +48,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, (err) ); \ if( U_FAILURE((err)) ) \ { \ - intl_error_set_custom_msg( NULL, msg, 0 ); \ + intl_error_set_custom_msg( NULL, msg); \ RETURN_FALSE; \ } @@ -57,7 +57,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, (err) ); \ if( U_FAILURE((err)) ) \ { \ - intl_error_set_custom_msg( NULL, msg, 0 ); \ + intl_error_set_custom_msg( NULL, msg); \ RETURN_NULL(); \ } @@ -67,7 +67,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ RETURN_FALSE; \ } @@ -76,7 +76,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ RETVAL_FALSE; \ goto label; \ } @@ -86,7 +86,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ zval_ptr_dtor(return_value); \ RETURN_NULL(); \ } @@ -96,7 +96,7 @@ typedef struct _intl_data { intl_error_set_code( NULL, INTL_DATA_ERROR_CODE((obj)) ); \ if( U_FAILURE( INTL_DATA_ERROR_CODE((obj)) ) ) \ { \ - intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg, 0 ); \ + intl_errors_set_custom_msg( INTL_DATA_ERROR_P((obj)), msg); \ return FAILURE; \ } @@ -117,7 +117,7 @@ typedef struct _intl_data { if((locale_len) > INTL_MAX_LOCALE_LEN) { \ char *_msg; \ spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg, 1); \ + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg); \ efree(_msg); \ RETURN_NULL(); \ } @@ -126,7 +126,7 @@ typedef struct _intl_data { if((locale_len) > INTL_MAX_LOCALE_LEN) { \ char *_msg; \ spprintf(&_msg, 0, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); \ - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg, 1); \ + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, _msg); \ efree(_msg); \ return FAILURE; \ } diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c index a1c3a9efb2d4..f19a5ec617dc 100644 --- a/ext/intl/intl_error.c +++ b/ext/intl/intl_error.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -42,12 +42,10 @@ static void intl_free_custom_error_msg( intl_error* err ) if( !err && !( err = intl_g_error_get( ) ) ) return; - if(err->free_custom_error_message ) { - efree( err->custom_error_message ); + if (err->custom_error_message) { + zend_string_release_ex(err->custom_error_message, false); + err->custom_error_message = NULL; } - - err->custom_error_message = NULL; - err->free_custom_error_message = 0; } /* }}} */ @@ -70,7 +68,6 @@ void intl_error_init( intl_error* err ) err->code = U_ZERO_ERROR; err->custom_error_message = NULL; - err->free_custom_error_message = 0; } /* }}} */ @@ -87,28 +84,41 @@ void intl_error_reset( intl_error* err ) /* }}} */ /* {{{ Set last error message to msg copying it if needed. */ -void intl_error_set_custom_msg( intl_error* err, const char* msg, int copyMsg ) +void intl_error_set_custom_msg( intl_error* err, const char* msg) { - if( !msg ) + /* See ext/intl/tests/bug70451.phpt and uchar.c:zif_IntlChar_charFromName */ + if (UNEXPECTED(msg == NULL)) { return; + } + + zend_string *method_or_func = get_active_function_or_method_name(); + zend_string *prefixed_message = zend_string_concat3( + ZSTR_VAL(method_or_func), ZSTR_LEN(method_or_func), + ZEND_STRL("(): "), + msg, strlen(msg) + ); + zend_string_release_ex(method_or_func, false); if( !err ) { - if( INTL_G( error_level ) ) + if (INTL_G(error_level)) { + /* Docref will prefix the function/method for us, so use original message */ php_error_docref( NULL, INTL_G( error_level ), "%s", msg ); - if( INTL_G( use_exceptions ) ) - zend_throw_exception_ex( IntlException_ce_ptr, 0, "%s", msg ); + } + if (INTL_G(use_exceptions)) { + /* Use this variant as we have a zend_string already */ + zend_throw_error_exception(IntlException_ce_ptr, prefixed_message, 0, 0); + } } - if( !err && !( err = intl_g_error_get( ) ) ) + if (!err && !(err = intl_g_error_get() )) { + zend_string_release_ex(prefixed_message, false); return; + } /* Free previous message if any */ intl_free_custom_error_msg( err ); - /* Mark message copied if any */ - err->free_custom_error_message = copyMsg; - /* Set user's error text message */ - err->custom_error_message = copyMsg ? estrdup( msg ) : (char *) msg; + err->custom_error_message = prefixed_message; } /* }}} */ @@ -116,21 +126,22 @@ void intl_error_set_custom_msg( intl_error* err, const char* msg, int copyMsg ) zend_string * intl_error_get_message( intl_error* err ) { const char *uErrorName = NULL; - zend_string *errMessage = 0; + zend_string *errMessage = NULL; if( !err && !( err = intl_g_error_get( ) ) ) return ZSTR_EMPTY_ALLOC(); uErrorName = u_errorName( err->code ); + size_t uErrorLen = strlen(uErrorName); /* Format output string */ - if( err->custom_error_message ) - { - errMessage = strpprintf(0, "%s: %s", err->custom_error_message, uErrorName ); - } - else - { - errMessage = strpprintf(0, "%s", uErrorName ); + if (err->custom_error_message) { + errMessage = zend_string_concat3( + ZSTR_VAL(err->custom_error_message), ZSTR_LEN(err->custom_error_message), + ZEND_STRL(": "), + uErrorName, uErrorLen); + } else { + errMessage = zend_string_init(uErrorName, strlen(uErrorName), false); } return errMessage; @@ -158,18 +169,18 @@ UErrorCode intl_error_get_code( intl_error* err ) /* }}} */ /* {{{ Set error code and message. */ -void intl_error_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ) +void intl_error_set( intl_error* err, UErrorCode code, const char* msg) { intl_error_set_code( err, code ); - intl_error_set_custom_msg( err, msg, copyMsg ); + intl_error_set_custom_msg( err, msg); } /* }}} */ /* {{{ Set error code and message. */ -void intl_errors_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ) +void intl_errors_set( intl_error* err, UErrorCode code, const char* msg) { intl_errors_set_code( err, code ); - intl_errors_set_custom_msg( err, msg, copyMsg ); + intl_errors_set_custom_msg( err, msg); } /* }}} */ @@ -184,12 +195,12 @@ void intl_errors_reset( intl_error* err ) /* }}} */ /* {{{ */ -void intl_errors_set_custom_msg( intl_error* err, const char* msg, int copyMsg ) +void intl_errors_set_custom_msg(intl_error* err, const char* msg) { if(err) { - intl_error_set_custom_msg( err, msg, copyMsg ); + intl_error_set_custom_msg( err, msg); } - intl_error_set_custom_msg( NULL, msg, copyMsg ); + intl_error_set_custom_msg( NULL, msg); } /* }}} */ diff --git a/ext/intl/intl_error.h b/ext/intl/intl_error.h index 74bf0d8a43ee..dd13cf84ebd2 100644 --- a/ext/intl/intl_error.h +++ b/ext/intl/intl_error.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -23,26 +23,25 @@ #define INTL_ERROR_CODE(e) (e).code -typedef struct _intl_error { - UErrorCode code; - int free_custom_error_message; - char* custom_error_message; +typedef struct { + zend_string *custom_error_message; + UErrorCode code; } intl_error; intl_error* intl_error_create( void ); void intl_error_init( intl_error* err ); void intl_error_reset( intl_error* err ); void intl_error_set_code( intl_error* err, UErrorCode err_code ); -void intl_error_set_custom_msg( intl_error* err, const char* msg, int copyMsg ); -void intl_error_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ); +void intl_error_set_custom_msg( intl_error* err, const char* msg); +void intl_error_set( intl_error* err, UErrorCode code, const char* msg); UErrorCode intl_error_get_code( intl_error* err ); zend_string* intl_error_get_message( intl_error* err ); -// Wrappers to synchonize object's and global error structures. +// Wrappers to synchronize object's and global error structures. void intl_errors_reset( intl_error* err ); -void intl_errors_set_custom_msg( intl_error* err, const char* msg, int copyMsg ); +void intl_errors_set_custom_msg( intl_error* err, const char* msg); void intl_errors_set_code( intl_error* err, UErrorCode err_code ); -void intl_errors_set( intl_error* err, UErrorCode code, const char* msg, int copyMsg ); +void intl_errors_set( intl_error* err, UErrorCode code, const char* msg); // Other error helpers smart_str intl_parse_error_to_string( UParseError* pe ); diff --git a/ext/intl/listformatter/listformatter_arginfo.h b/ext/intl/listformatter/listformatter_arginfo.h index 3a2afa2d1c2d..8be31588d6ba 100644 --- a/ext/intl/listformatter/listformatter_arginfo.h +++ b/ext/intl/listformatter/listformatter_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit listformatter.stub.php instead. * Stub hash: cdbbdb55d1e53f422c5854460c3c6cc3d01360d7 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlListFormatter___construct, 0, 0, 1) @@ -40,59 +40,59 @@ static zend_class_entry *register_class_IntlListFormatter(void) zval const_TYPE_AND_value; ZVAL_LONG(&const_TYPE_AND_value, ULISTFMT_TYPE_AND); - zend_string *const_TYPE_AND_name = zend_string_init_interned("TYPE_AND", sizeof("TYPE_AND") - 1, 1); + zend_string *const_TYPE_AND_name = zend_string_init_interned("TYPE_AND", sizeof("TYPE_AND") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_AND_name, &const_TYPE_AND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_AND_name); + zend_string_release_ex(const_TYPE_AND_name, true); #endif #if !(U_ICU_VERSION_MAJOR_NUM >= 67) zval const_TYPE_AND_value; ZVAL_LONG(&const_TYPE_AND_value, INTL_LISTFORMATTER_FALLBACK_TYPE_AND); - zend_string *const_TYPE_AND_name = zend_string_init_interned("TYPE_AND", sizeof("TYPE_AND") - 1, 1); + zend_string *const_TYPE_AND_name = zend_string_init_interned("TYPE_AND", sizeof("TYPE_AND") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_AND_name, &const_TYPE_AND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_AND_name); + zend_string_release_ex(const_TYPE_AND_name, true); #endif #if U_ICU_VERSION_MAJOR_NUM >= 67 zval const_TYPE_OR_value; ZVAL_LONG(&const_TYPE_OR_value, ULISTFMT_TYPE_OR); - zend_string *const_TYPE_OR_name = zend_string_init_interned("TYPE_OR", sizeof("TYPE_OR") - 1, 1); + zend_string *const_TYPE_OR_name = zend_string_init_interned("TYPE_OR", sizeof("TYPE_OR") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_OR_name, &const_TYPE_OR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_OR_name); + zend_string_release_ex(const_TYPE_OR_name, true); zval const_TYPE_UNITS_value; ZVAL_LONG(&const_TYPE_UNITS_value, ULISTFMT_TYPE_UNITS); - zend_string *const_TYPE_UNITS_name = zend_string_init_interned("TYPE_UNITS", sizeof("TYPE_UNITS") - 1, 1); + zend_string *const_TYPE_UNITS_name = zend_string_init_interned("TYPE_UNITS", sizeof("TYPE_UNITS") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_UNITS_name, &const_TYPE_UNITS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_UNITS_name); + zend_string_release_ex(const_TYPE_UNITS_name, true); zval const_WIDTH_WIDE_value; ZVAL_LONG(&const_WIDTH_WIDE_value, ULISTFMT_WIDTH_WIDE); - zend_string *const_WIDTH_WIDE_name = zend_string_init_interned("WIDTH_WIDE", sizeof("WIDTH_WIDE") - 1, 1); + zend_string *const_WIDTH_WIDE_name = zend_string_init_interned("WIDTH_WIDE", sizeof("WIDTH_WIDE") - 1, true); zend_declare_typed_class_constant(class_entry, const_WIDTH_WIDE_name, &const_WIDTH_WIDE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WIDTH_WIDE_name); + zend_string_release_ex(const_WIDTH_WIDE_name, true); #endif #if !(U_ICU_VERSION_MAJOR_NUM >= 67) zval const_WIDTH_WIDE_value; ZVAL_LONG(&const_WIDTH_WIDE_value, INTL_LISTFORMATTER_FALLBACK_WIDTH_WIDE); - zend_string *const_WIDTH_WIDE_name = zend_string_init_interned("WIDTH_WIDE", sizeof("WIDTH_WIDE") - 1, 1); + zend_string *const_WIDTH_WIDE_name = zend_string_init_interned("WIDTH_WIDE", sizeof("WIDTH_WIDE") - 1, true); zend_declare_typed_class_constant(class_entry, const_WIDTH_WIDE_name, &const_WIDTH_WIDE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WIDTH_WIDE_name); + zend_string_release_ex(const_WIDTH_WIDE_name, true); #endif #if U_ICU_VERSION_MAJOR_NUM >= 67 zval const_WIDTH_SHORT_value; ZVAL_LONG(&const_WIDTH_SHORT_value, ULISTFMT_WIDTH_SHORT); - zend_string *const_WIDTH_SHORT_name = zend_string_init_interned("WIDTH_SHORT", sizeof("WIDTH_SHORT") - 1, 1); + zend_string *const_WIDTH_SHORT_name = zend_string_init_interned("WIDTH_SHORT", sizeof("WIDTH_SHORT") - 1, true); zend_declare_typed_class_constant(class_entry, const_WIDTH_SHORT_name, &const_WIDTH_SHORT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WIDTH_SHORT_name); + zend_string_release_ex(const_WIDTH_SHORT_name, true); zval const_WIDTH_NARROW_value; ZVAL_LONG(&const_WIDTH_NARROW_value, ULISTFMT_WIDTH_NARROW); - zend_string *const_WIDTH_NARROW_name = zend_string_init_interned("WIDTH_NARROW", sizeof("WIDTH_NARROW") - 1, 1); + zend_string *const_WIDTH_NARROW_name = zend_string_init_interned("WIDTH_NARROW", sizeof("WIDTH_NARROW") - 1, true); zend_declare_typed_class_constant(class_entry, const_WIDTH_NARROW_name, &const_WIDTH_NARROW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WIDTH_NARROW_name); + zend_string_release_ex(const_WIDTH_NARROW_name, true); #endif return class_entry; diff --git a/ext/intl/listformatter/listformatter_class.c b/ext/intl/listformatter/listformatter_class.c deleted file mode 100644 index 1fe8da554a1c..000000000000 --- a/ext/intl/listformatter/listformatter_class.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Bogdan Ungureanu | - +----------------------------------------------------------------------+ -*/ - -#include "php.h" -#include "php_intl.h" -#include -#include "listformatter_class.h" -#include "listformatter_arginfo.h" -#include "intl_convert.h" - -static zend_object_handlers listformatter_handlers; - -static void listformatter_free_obj(zend_object *object) -{ - ListFormatter_object *obj = php_intl_listformatter_fetch_object(object); - - if( obj->lf_data.ulistfmt ) - ulistfmt_close( obj->lf_data.ulistfmt ); - - obj->lf_data.ulistfmt = NULL; - intl_error_reset( &obj->lf_data.error ); - - zend_object_std_dtor(&obj->zo); -} - -static zend_object *listformatter_create_object(zend_class_entry *class_type) -{ - ListFormatter_object *obj; - obj = zend_object_alloc(sizeof(ListFormatter_object), class_type); - - obj->lf_data.ulistfmt = NULL; - intl_error_reset( &obj->lf_data.error ); - - zend_object_std_init(&obj->zo, class_type); - object_properties_init(&obj->zo, class_type); - obj->zo.handlers = &listformatter_handlers; - return &obj->zo; -} - -PHP_METHOD(IntlListFormatter, __construct) -{ - ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); - char* locale; - size_t locale_len = 0; - #if U_ICU_VERSION_MAJOR_NUM >= 67 - zend_long type = ULISTFMT_TYPE_AND; - zend_long width = ULISTFMT_WIDTH_WIDE; - #else - zend_long type = INTL_LISTFORMATTER_FALLBACK_TYPE_AND; - zend_long width = INTL_LISTFORMATTER_FALLBACK_WIDTH_WIDE; - #endif - ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_STRING(locale, locale_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(type) - Z_PARAM_LONG(width) - ZEND_PARSE_PARAMETERS_END(); - - if(locale_len == 0) { - locale = (char *)intl_locale_get_default(); - } - - if (locale_len > INTL_MAX_LOCALE_LEN) { - zend_argument_value_error(1, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); - RETURN_THROWS(); - } - - if (strlen(uloc_getISO3Language(locale)) == 0) { - zend_argument_value_error(1, "\"%s\" is invalid", locale); - RETURN_THROWS(); - } - - UErrorCode status = U_ZERO_ERROR; - #if U_ICU_VERSION_MAJOR_NUM >= 67 - if (type != ULISTFMT_TYPE_AND && type != ULISTFMT_TYPE_OR && type != ULISTFMT_TYPE_UNITS) { - zend_argument_value_error(2, "must be one of IntlListFormatter::TYPE_AND, IntlListFormatter::TYPE_OR, or IntlListFormatter::TYPE_UNITS"); - RETURN_THROWS(); - } - - if (width != ULISTFMT_WIDTH_WIDE && width != ULISTFMT_WIDTH_SHORT && width != ULISTFMT_WIDTH_NARROW) { - zend_argument_value_error(3, "must be one of IntlListFormatter::WIDTH_WIDE, IntlListFormatter::WIDTH_SHORT, or IntlListFormatter::WIDTH_NARROW"); - RETURN_THROWS(); - } - - LISTFORMATTER_OBJECT(obj) = ulistfmt_openForType(locale, type, width, &status); - #else - if (type != INTL_LISTFORMATTER_FALLBACK_TYPE_AND) { - zend_argument_value_error(2, "contains an unsupported type. ICU 66 and below only support IntlListFormatter::TYPE_AND"); - RETURN_THROWS(); - } - - if (width != INTL_LISTFORMATTER_FALLBACK_WIDTH_WIDE) { - zend_argument_value_error(3, "contains an unsupported width. ICU 66 and below only support IntlListFormatter::WIDTH_WIDE"); - RETURN_THROWS(); - } - - LISTFORMATTER_OBJECT(obj) = ulistfmt_open(locale, &status); - #endif - - if (U_FAILURE(status)) { - intl_error_set(NULL, status, "Constructor failed", 0); - zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); - RETURN_THROWS(); - } -} - -PHP_METHOD(IntlListFormatter, format) -{ - ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); - HashTable *ht; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY_HT(ht) - ZEND_PARSE_PARAMETERS_END(); - - uint32_t count = zend_hash_num_elements(ht); - if (count == 0) { - RETURN_EMPTY_STRING(); - } - - const UChar **items = (const UChar **)safe_emalloc(count, sizeof(const UChar *), 0); - int32_t *itemLengths = (int32_t *)safe_emalloc(count, sizeof(int32_t), 0); - uint32_t i = 0; - zval *val; - - ZEND_HASH_FOREACH_VAL(ht, val) { - zend_string *str_val; - - str_val = zval_get_string(val); - - // Convert PHP string to UTF-16 - UChar *ustr = NULL; - int32_t ustr_len = 0; - UErrorCode status = U_ZERO_ERROR; - - intl_convert_utf8_to_utf16(&ustr, &ustr_len, ZSTR_VAL(str_val), ZSTR_LEN(str_val), &status); - zend_string_release(str_val); - - if (U_FAILURE(status)) { - // We can't use goto cleanup because items and itemLengths are incompletely allocated - for (uint32_t j = 0; j < i; j++) { - efree((void *)items[j]); - } - efree(items); - efree(itemLengths); - intl_error_set(NULL, status, "Failed to convert string to UTF-16", 0); - RETURN_FALSE; - } - - items[i] = ustr; - itemLengths[i] = ustr_len; - i++; - } ZEND_HASH_FOREACH_END(); - - UErrorCode status = U_ZERO_ERROR; - int32_t resultLength; - UChar *result = NULL; - - resultLength = ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, NULL, 0, &status); - - if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) { - intl_error_set(NULL, status, "Failed to format list", 0); - RETVAL_FALSE; - goto cleanup; - } - - // Allocate buffer and try again - status = U_ZERO_ERROR; - result = (UChar *)safe_emalloc(resultLength + 1, sizeof(UChar), 0); - ulistfmt_format(LISTFORMATTER_OBJECT(obj), items, itemLengths, count, result, resultLength, &status); - - if (U_FAILURE(status)) { - if (result) { - efree(result); - } - intl_error_set(NULL, status, "Failed to format list", 0); - RETVAL_FALSE; - goto cleanup; - } - - // Convert result back to UTF-8 - zend_string *ret = intl_convert_utf16_to_utf8(result, resultLength, &status); - efree(result); - - if (!ret) { - intl_error_set(NULL, status, "Failed to convert result to UTF-8", 0); - RETVAL_FALSE; - } else { - RETVAL_NEW_STR(ret); - } - -cleanup: - for (i = 0; i < count; i++) { - efree((void *)items[i]); - } - efree(items); - efree(itemLengths); -} - -PHP_METHOD(IntlListFormatter, getErrorCode) -{ - ZEND_PARSE_PARAMETERS_NONE(); - - ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); - - UErrorCode status = intl_error_get_code(LISTFORMATTER_ERROR_P(obj)); - - RETURN_LONG(status); -} - -PHP_METHOD(IntlListFormatter, getErrorMessage) -{ - ZEND_PARSE_PARAMETERS_NONE(); - - ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); - - zend_string *message = intl_error_get_message(LISTFORMATTER_ERROR_P(obj)); - RETURN_STR(message); -} - -void listformatter_register_class(void) -{ - zend_class_entry *class_entry = register_class_IntlListFormatter(); - class_entry->create_object = listformatter_create_object; - - memcpy(&listformatter_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - listformatter_handlers.offset = XtOffsetOf(ListFormatter_object, zo); - listformatter_handlers.free_obj = listformatter_free_obj; - listformatter_handlers.clone_obj = NULL; -} diff --git a/ext/intl/listformatter/listformatter_class.cpp b/ext/intl/listformatter/listformatter_class.cpp new file mode 100644 index 000000000000..950eb81b7e15 --- /dev/null +++ b/ext/intl/listformatter/listformatter_class.cpp @@ -0,0 +1,214 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Bogdan Ungureanu | + +----------------------------------------------------------------------+ +*/ + +extern "C" { +#include "php.h" +} + +#include +#include +#include "../intl_convertcpp.h" + +extern "C" { +#include "php_intl.h" +} +#include "listformatter_class.h" +#include "listformatter_arginfo.h" + +#include + +static zend_object_handlers listformatter_handlers; + +static void listformatter_free_obj(zend_object *object) +{ + ListFormatter_object *obj = php_intl_listformatter_fetch_object(object); + + delete obj->lf_data.ulistfmt; + obj->lf_data.ulistfmt = nullptr; + intl_error_reset( &obj->lf_data.error ); + + zend_object_std_dtor(&obj->zo); +} + +static zend_object *listformatter_create_object(zend_class_entry *class_type) +{ + ListFormatter_object *obj; + obj = reinterpret_cast(zend_object_alloc(sizeof(ListFormatter_object), class_type)); + + obj->lf_data.ulistfmt = nullptr; + intl_error_reset( &obj->lf_data.error ); + + zend_object_std_init(&obj->zo, class_type); + object_properties_init(&obj->zo, class_type); + obj->zo.handlers = &listformatter_handlers; + return &obj->zo; +} + +PHP_METHOD(IntlListFormatter, __construct) +{ + ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); + char* locale; + size_t locale_len = 0; + #if U_ICU_VERSION_MAJOR_NUM >= 67 + zend_long type = ULISTFMT_TYPE_AND; + zend_long width = ULISTFMT_WIDTH_WIDE; + #else + zend_long type = INTL_LISTFORMATTER_FALLBACK_TYPE_AND; + zend_long width = INTL_LISTFORMATTER_FALLBACK_WIDTH_WIDE; + #endif + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_STRING(locale, locale_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(type) + Z_PARAM_LONG(width) + ZEND_PARSE_PARAMETERS_END(); + + if(locale_len == 0) { + locale = (char *)intl_locale_get_default(); + } + + if (locale_len > INTL_MAX_LOCALE_LEN) { + zend_argument_value_error(1, "must be less than or equal to %d characters", INTL_MAX_LOCALE_LEN); + RETURN_THROWS(); + } + + if (icu::Locale(locale).getISO3Language()[0] == '\0') { + zend_argument_value_error(1, "\"%s\" is invalid", locale); + RETURN_THROWS(); + } + + UErrorCode status = U_ZERO_ERROR; + #if U_ICU_VERSION_MAJOR_NUM >= 67 + if (type != ULISTFMT_TYPE_AND && type != ULISTFMT_TYPE_OR && type != ULISTFMT_TYPE_UNITS) { + zend_argument_value_error(2, "must be one of IntlListFormatter::TYPE_AND, IntlListFormatter::TYPE_OR, or IntlListFormatter::TYPE_UNITS"); + RETURN_THROWS(); + } + + if (width != ULISTFMT_WIDTH_WIDE && width != ULISTFMT_WIDTH_SHORT && width != ULISTFMT_WIDTH_NARROW) { + zend_argument_value_error(3, "must be one of IntlListFormatter::WIDTH_WIDE, IntlListFormatter::WIDTH_SHORT, or IntlListFormatter::WIDTH_NARROW"); + RETURN_THROWS(); + } + + LISTFORMATTER_OBJECT(obj) = ListFormatter::createInstance(icu::Locale(locale), static_cast(type), static_cast(width), status); + #else + if (type != INTL_LISTFORMATTER_FALLBACK_TYPE_AND) { + zend_argument_value_error(2, "contains an unsupported type. ICU 66 and below only support IntlListFormatter::TYPE_AND"); + RETURN_THROWS(); + } + + if (width != INTL_LISTFORMATTER_FALLBACK_WIDTH_WIDE) { + zend_argument_value_error(3, "contains an unsupported width. ICU 66 and below only support IntlListFormatter::WIDTH_WIDE"); + RETURN_THROWS(); + } + + LISTFORMATTER_OBJECT(obj) = ListFormatter::createInstance(icu::Locale(locale), status); + #endif + + if (U_FAILURE(status)) { + intl_error_set(nullptr, status, "Constructor failed"); + zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); + RETURN_THROWS(); + } +} + +PHP_METHOD(IntlListFormatter, format) +{ + ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); + HashTable *ht; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(ht) + ZEND_PARSE_PARAMETERS_END(); + + intl_errors_reset(LISTFORMATTER_ERROR_P(obj)); + + uint32_t count = zend_hash_num_elements(ht); + if (count == 0) { + RETURN_EMPTY_STRING(); + } + + std::unique_ptr items(new UnicodeString[count]); + uint32_t i = 0; + zval *val; + + ZEND_HASH_FOREACH_VAL(ht, val) { + zend_string *str_val, *tmp_str; + UErrorCode conv_status = U_ZERO_ERROR; + + str_val = zval_try_get_tmp_string(val, &tmp_str); + if (UNEXPECTED(!str_val)) { + RETURN_THROWS(); + } + intl_stringFromChar(items[i], ZSTR_VAL(str_val), ZSTR_LEN(str_val), &conv_status); + zend_tmp_string_release(tmp_str); + + if (U_FAILURE(conv_status)) { + intl_errors_set(LISTFORMATTER_ERROR_P(obj), conv_status, "Failed to convert string to UTF-16"); + RETURN_FALSE; + } + + i++; + } ZEND_HASH_FOREACH_END(); + + UErrorCode status = U_ZERO_ERROR; + UnicodeString result; + + LISTFORMATTER_OBJECT(obj)->format(items.get(), count, result, status); + + if (U_FAILURE(status)) { + intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to format list"); + RETURN_FALSE; + } + + zend_string *ret = intl_charFromString(result, &status); + + if (!ret) { + intl_errors_set(LISTFORMATTER_ERROR_P(obj), status, "Failed to convert result to UTF-8"); + RETURN_FALSE; + } + + RETVAL_STR(ret); +} + +PHP_METHOD(IntlListFormatter, getErrorCode) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); + + UErrorCode status = intl_error_get_code(LISTFORMATTER_ERROR_P(obj)); + + RETURN_LONG(status); +} + +PHP_METHOD(IntlListFormatter, getErrorMessage) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + ListFormatter_object *obj = Z_INTL_LISTFORMATTER_P(ZEND_THIS); + + zend_string *message = intl_error_get_message(LISTFORMATTER_ERROR_P(obj)); + RETURN_STR(message); +} + +void listformatter_register_class(void) +{ + zend_class_entry *class_entry = register_class_IntlListFormatter(); + class_entry->create_object = listformatter_create_object; + + memcpy(&listformatter_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + listformatter_handlers.offset = offsetof(ListFormatter_object, zo); + listformatter_handlers.free_obj = listformatter_free_obj; + listformatter_handlers.clone_obj = nullptr; +} diff --git a/ext/intl/listformatter/listformatter_class.h b/ext/intl/listformatter/listformatter_class.h index 8fe8137796bf..80b35f55b388 100644 --- a/ext/intl/listformatter/listformatter_class.h +++ b/ext/intl/listformatter/listformatter_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Bogdan Ungureanu | +----------------------------------------------------------------------+ @@ -21,14 +21,20 @@ #include "intl_error.h" #include "intl_data.h" -#include +#include + +#ifdef __cplusplus +using icu::ListFormatter; +#else +typedef void ListFormatter; +#endif typedef struct { // error handling intl_error error; // formatter handling - UListFormatter* ulistfmt; + ListFormatter* ulistfmt; } listformatter_data; typedef struct { @@ -37,7 +43,7 @@ typedef struct { } ListFormatter_object; static inline ListFormatter_object *php_intl_listformatter_fetch_object(zend_object *obj) { - return (ListFormatter_object *)((char*)(obj) - XtOffsetOf(ListFormatter_object, zo)); + return ZEND_CONTAINER_OF(obj, ListFormatter_object, zo); } #define Z_INTL_LISTFORMATTER_P(zv) php_intl_listformatter_fetch_object(Z_OBJ_P(zv)) @@ -46,8 +52,14 @@ static inline ListFormatter_object *php_intl_listformatter_fetch_object(zend_obj #define LISTFORMATTER_OBJECT(lfo) (lfo)->lf_data.ulistfmt +#ifdef __cplusplus +extern "C" { +#endif void listformatter_register_class( void ); extern zend_class_entry *ListFormatter_ce_ptr; +#ifdef __cplusplus +} +#endif #define INTL_LISTFORMATTER_FALLBACK_TYPE_AND 0 #define INTL_LISTFORMATTER_FALLBACK_WIDTH_WIDE 0 diff --git a/ext/intl/locale/locale.c b/ext/intl/locale/locale.c deleted file mode 100644 index 76b269ca85e3..000000000000 --- a/ext/intl/locale/locale.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "locale_class.h" -#include "locale.h" - -#include -#include -#include diff --git a/ext/intl/locale/locale.cpp b/ext/intl/locale/locale.cpp new file mode 100644 index 000000000000..bad1c775c1b0 --- /dev/null +++ b/ext/intl/locale/locale.cpp @@ -0,0 +1,24 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Author: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "locale_class.h" +#include "locale.h" + +#include +#include +#include diff --git a/ext/intl/locale/locale.h b/ext/intl/locale/locale.h index 31aef035050d..1c40871d2065 100644 --- a/ext/intl/locale/locale.h +++ b/ext/intl/locale/locale.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ diff --git a/ext/intl/locale/locale_arginfo.h b/ext/intl/locale/locale_arginfo.h index 79a16452e297..1d6e6683e21a 100644 --- a/ext/intl/locale/locale_arginfo.h +++ b/ext/intl/locale/locale_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit locale.stub.php instead. * Stub hash: ff1f75bd34a52f57210734e2f5e29efb87566137 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Locale_getDefault, 0, 0, IS_STRING, 0) @@ -128,70 +128,70 @@ static zend_class_entry *register_class_Locale(void) zval const_ACTUAL_LOCALE_value; ZVAL_LONG(&const_ACTUAL_LOCALE_value, ULOC_ACTUAL_LOCALE); - zend_string *const_ACTUAL_LOCALE_name = zend_string_init_interned("ACTUAL_LOCALE", sizeof("ACTUAL_LOCALE") - 1, 1); + zend_string *const_ACTUAL_LOCALE_name = zend_string_init_interned("ACTUAL_LOCALE", sizeof("ACTUAL_LOCALE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ACTUAL_LOCALE_name, &const_ACTUAL_LOCALE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ACTUAL_LOCALE_name); + zend_string_release_ex(const_ACTUAL_LOCALE_name, true); zval const_VALID_LOCALE_value; ZVAL_LONG(&const_VALID_LOCALE_value, ULOC_VALID_LOCALE); - zend_string *const_VALID_LOCALE_name = zend_string_init_interned("VALID_LOCALE", sizeof("VALID_LOCALE") - 1, 1); + zend_string *const_VALID_LOCALE_name = zend_string_init_interned("VALID_LOCALE", sizeof("VALID_LOCALE") - 1, true); zend_declare_typed_class_constant(class_entry, const_VALID_LOCALE_name, &const_VALID_LOCALE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_VALID_LOCALE_name); + zend_string_release_ex(const_VALID_LOCALE_name, true); zval const_DEFAULT_LOCALE_value; ZVAL_NULL(&const_DEFAULT_LOCALE_value); - zend_string *const_DEFAULT_LOCALE_name = zend_string_init_interned("DEFAULT_LOCALE", sizeof("DEFAULT_LOCALE") - 1, 1); + zend_string *const_DEFAULT_LOCALE_name = zend_string_init_interned("DEFAULT_LOCALE", sizeof("DEFAULT_LOCALE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DEFAULT_LOCALE_name, &const_DEFAULT_LOCALE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_NULL)); - zend_string_release(const_DEFAULT_LOCALE_name); + zend_string_release_ex(const_DEFAULT_LOCALE_name, true); zval const_LANG_TAG_value; zend_string *const_LANG_TAG_value_str = zend_string_init(LOC_LANG_TAG, strlen(LOC_LANG_TAG), 1); ZVAL_STR(&const_LANG_TAG_value, const_LANG_TAG_value_str); - zend_string *const_LANG_TAG_name = zend_string_init_interned("LANG_TAG", sizeof("LANG_TAG") - 1, 1); + zend_string *const_LANG_TAG_name = zend_string_init_interned("LANG_TAG", sizeof("LANG_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_LANG_TAG_name, &const_LANG_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_LANG_TAG_name); + zend_string_release_ex(const_LANG_TAG_name, true); zval const_EXTLANG_TAG_value; zend_string *const_EXTLANG_TAG_value_str = zend_string_init(LOC_EXTLANG_TAG, strlen(LOC_EXTLANG_TAG), 1); ZVAL_STR(&const_EXTLANG_TAG_value, const_EXTLANG_TAG_value_str); - zend_string *const_EXTLANG_TAG_name = zend_string_init_interned("EXTLANG_TAG", sizeof("EXTLANG_TAG") - 1, 1); + zend_string *const_EXTLANG_TAG_name = zend_string_init_interned("EXTLANG_TAG", sizeof("EXTLANG_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXTLANG_TAG_name, &const_EXTLANG_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_EXTLANG_TAG_name); + zend_string_release_ex(const_EXTLANG_TAG_name, true); zval const_SCRIPT_TAG_value; zend_string *const_SCRIPT_TAG_value_str = zend_string_init(LOC_SCRIPT_TAG, strlen(LOC_SCRIPT_TAG), 1); ZVAL_STR(&const_SCRIPT_TAG_value, const_SCRIPT_TAG_value_str); - zend_string *const_SCRIPT_TAG_name = zend_string_init_interned("SCRIPT_TAG", sizeof("SCRIPT_TAG") - 1, 1); + zend_string *const_SCRIPT_TAG_name = zend_string_init_interned("SCRIPT_TAG", sizeof("SCRIPT_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_SCRIPT_TAG_name, &const_SCRIPT_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_SCRIPT_TAG_name); + zend_string_release_ex(const_SCRIPT_TAG_name, true); zval const_REGION_TAG_value; zend_string *const_REGION_TAG_value_str = zend_string_init(LOC_REGION_TAG, strlen(LOC_REGION_TAG), 1); ZVAL_STR(&const_REGION_TAG_value, const_REGION_TAG_value_str); - zend_string *const_REGION_TAG_name = zend_string_init_interned("REGION_TAG", sizeof("REGION_TAG") - 1, 1); + zend_string *const_REGION_TAG_name = zend_string_init_interned("REGION_TAG", sizeof("REGION_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_REGION_TAG_name, &const_REGION_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_REGION_TAG_name); + zend_string_release_ex(const_REGION_TAG_name, true); zval const_VARIANT_TAG_value; zend_string *const_VARIANT_TAG_value_str = zend_string_init(LOC_VARIANT_TAG, strlen(LOC_VARIANT_TAG), 1); ZVAL_STR(&const_VARIANT_TAG_value, const_VARIANT_TAG_value_str); - zend_string *const_VARIANT_TAG_name = zend_string_init_interned("VARIANT_TAG", sizeof("VARIANT_TAG") - 1, 1); + zend_string *const_VARIANT_TAG_name = zend_string_init_interned("VARIANT_TAG", sizeof("VARIANT_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_VARIANT_TAG_name, &const_VARIANT_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_VARIANT_TAG_name); + zend_string_release_ex(const_VARIANT_TAG_name, true); zval const_GRANDFATHERED_LANG_TAG_value; zend_string *const_GRANDFATHERED_LANG_TAG_value_str = zend_string_init(LOC_GRANDFATHERED_LANG_TAG, strlen(LOC_GRANDFATHERED_LANG_TAG), 1); ZVAL_STR(&const_GRANDFATHERED_LANG_TAG_value, const_GRANDFATHERED_LANG_TAG_value_str); - zend_string *const_GRANDFATHERED_LANG_TAG_name = zend_string_init_interned("GRANDFATHERED_LANG_TAG", sizeof("GRANDFATHERED_LANG_TAG") - 1, 1); + zend_string *const_GRANDFATHERED_LANG_TAG_name = zend_string_init_interned("GRANDFATHERED_LANG_TAG", sizeof("GRANDFATHERED_LANG_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_GRANDFATHERED_LANG_TAG_name, &const_GRANDFATHERED_LANG_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_GRANDFATHERED_LANG_TAG_name); + zend_string_release_ex(const_GRANDFATHERED_LANG_TAG_name, true); zval const_PRIVATE_TAG_value; zend_string *const_PRIVATE_TAG_value_str = zend_string_init(LOC_PRIVATE_TAG, strlen(LOC_PRIVATE_TAG), 1); ZVAL_STR(&const_PRIVATE_TAG_value, const_PRIVATE_TAG_value_str); - zend_string *const_PRIVATE_TAG_name = zend_string_init_interned("PRIVATE_TAG", sizeof("PRIVATE_TAG") - 1, 1); + zend_string *const_PRIVATE_TAG_name = zend_string_init_interned("PRIVATE_TAG", sizeof("PRIVATE_TAG") - 1, true); zend_declare_typed_class_constant(class_entry, const_PRIVATE_TAG_name, &const_PRIVATE_TAG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_PRIVATE_TAG_name); + zend_string_release_ex(const_PRIVATE_TAG_name, true); return class_entry; } diff --git a/ext/intl/locale/locale_class.c b/ext/intl/locale/locale_class.c deleted file mode 100644 index cbde2a5fb070..000000000000 --- a/ext/intl/locale/locale_class.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ - -#include -#include "php_intl.h" -#include "intl_error.h" -#include "locale_class.h" -#include "locale.h" -#include "locale_arginfo.h" - -zend_class_entry *Locale_ce_ptr = NULL; - -/* - * 'Locale' class registration structures & functions - */ - -/* {{{ locale_register_Locale_class - * Initialize 'Locale' class - */ -void locale_register_Locale_class( void ) -{ - /* Create and register 'Locale' class. */ - Locale_ce_ptr = register_class_Locale(); - Locale_ce_ptr->create_object = NULL; -} -/* }}} */ diff --git a/ext/intl/locale/locale_class.cpp b/ext/intl/locale/locale_class.cpp new file mode 100644 index 000000000000..a8d34f2e9f24 --- /dev/null +++ b/ext/intl/locale/locale_class.cpp @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ + +#include +extern "C" { +#include "php_intl.h" +#include "intl_error.h" +#include "locale_class.h" +#include "locale.h" +#include "locale_arginfo.h" +} + +zend_class_entry *Locale_ce_ptr = NULL; + +/* + * 'Locale' class registration structures & functions + */ + +/* {{{ locale_register_Locale_class + * Initialize 'Locale' class + */ +U_CFUNC void locale_register_Locale_class( void ) +{ + /* Create and register 'Locale' class. */ + Locale_ce_ptr = register_class_Locale(); + Locale_ce_ptr->create_object = NULL; +} +/* }}} */ diff --git a/ext/intl/locale/locale_class.h b/ext/intl/locale/locale_class.h index aa339d75db9b..86cbc6ed9421 100644 --- a/ext/intl/locale/locale_class.h +++ b/ext/intl/locale/locale_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Kirti Velankar | +----------------------------------------------------------------------+ @@ -31,7 +31,7 @@ typedef struct { } Locale_object; -void locale_register_Locale_class( void ); +U_CFUNC void locale_register_Locale_class( void ); extern zend_class_entry *Locale_ce_ptr; diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c deleted file mode 100644 index 8b63007c5d82..000000000000 --- a/ext/intl/locale/locale_methods.c +++ /dev/null @@ -1,1688 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Kirti Velankar | - +----------------------------------------------------------------------+ -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "php_intl.h" -#include "locale.h" -#include "locale_class.h" -#include "intl_convert.h" -#include "intl_data.h" - -#include -#include -#include -#include "main/php_ini.h" -#include "zend_smart_str.h" - -ZEND_EXTERN_MODULE_GLOBALS( intl ) - -/* Sizes required for the strings "variant15" , "extlang11", "private12" etc. */ -#define SEPARATOR "_" -#define SEPARATOR1 "-" -#define DELIMITER "-_" -#define EXTLANG_PREFIX "a" -#define PRIVATE_PREFIX "x" -#define DISP_NAME "name" - -#define MAX_NO_VARIANT 15 -#define MAX_NO_EXTLANG 3 -#define MAX_NO_PRIVATE 15 -#define MAX_NO_LOOKUP_LANG_TAG 100 - -#define LOC_NOT_FOUND 1 - -/* Sizes required for the strings "variant15" , "extlang3", "private12" etc. */ -#define VARIANT_KEYNAME_LEN 11 -#define EXTLANG_KEYNAME_LEN 10 -#define PRIVATE_KEYNAME_LEN 11 - -/* Based on the IANA language subtag registry (File-Date: 2021-08-06) - * https://www.iana.org/assignments/language-subtag-registry - * - * This list includes all grandfathered tags, as well as redundant - * tags that have a Preferred-Value. - */ -static const char * const LOC_GRANDFATHERED[] = { - "art-lojban", - "cel-gaulish", - "en-GB-oed", - "i-ami", - "i-bnn", - "i-default", - "i-enochian", - "i-hak", - "i-klingon", - "i-lux", - "i-mingo", - "i-navajo", - "i-pwn", - "i-tao", - "i-tay", - "i-tsu", - "no-bok", - "no-nyn", - "sgn-BE-FR", - "sgn-BE-NL", - "sgn-BR", - "sgn-CH-DE", - "sgn-CO", - "sgn-DE", - "sgn-DK", - "sgn-ES", - "sgn-FR", - "sgn-GB", - "sgn-GR", - "sgn-IE", - "sgn-IT", - "sgn-JP", - "sgn-MX", - "sgn-NI", - "sgn-NL", - "sgn-NO", - "sgn-PT", - "sgn-SE", - "sgn-US", - "sgn-ZA", - "zh-cmn", - "zh-cmn-Hans", - "zh-cmn-Hant", - "zh-gan", - "zh-guoyu", - "zh-hakka", - "zh-min", - "zh-min-nan", - "zh-wuu", - "zh-xiang", - NULL -}; - -/* Based on the IANA language subtag registry (File-Date: 2021-08-06) - * - * This array lists the preferred values for the grandfathered and redundant - * tags listed in LOC_GRANDFATHERED. This is in sync with the array - * LOC_GRANDFATHERED, i.e., the offsets of the grandfathered tags match the - * offsets of the preferred value. If a value in LOC_PREFERRED_GRANDFATHERED is - * NULL, then the matching offset in LOC_GRANDFATHERED has no preferred value. - */ -static const char * const LOC_PREFERRED_GRANDFATHERED[] = { - "jbo", - NULL, - "en-GB-oxendict", - "ami", - "bnn", - NULL, - NULL, - "hak", - "tlh", - "lb", - NULL, - "nv", - "pwn", - "tao", - "tay", - "tsu", - "nb", - "nn", - "sfb", - "vgt", - "bzs", - "sgg", - "csn", - "gsg", - "dsl", - "ssp", - "fsl", - "bfi", - "gss", - "isg", - "ise", - "jsl", - "mfs", - "ncs", - "dse", - "nsl", - "psr", - "swl", - "ase", - "sfs", - "cmn", - "cmn-Hans", - "cmn-Hant", - "gan", - "cmn", - "hak", - NULL, - "nan", - "wuu", - "hsn", - NULL -}; - -/* returns true if a is an ID separator, false otherwise */ -#define isIDSeparator(a) (a == '_' || a == '-') -#define isKeywordSeparator(a) (a == '@' ) -#define isEndOfTag(a) (a == '\0' ) - -#define isPrefixLetter(a) ((a=='x')||(a=='X')||(a=='i')||(a=='I')) - -/*returns true if one of the special prefixes is here (s=string) - 'x-' or 'i-' */ -#define isIDPrefix(s) (isPrefixLetter(s[0])&&isIDSeparator(s[1])) -#define isKeywordPrefix(s) ( isKeywordSeparator(s[0]) ) - -/* Dot terminates it because of POSIX form where dot precedes the codepage - * except for variant */ -#define isTerminator(a) ((a==0)||(a=='.')||(a=='@')) - -/* {{{ return the offset of 'key' in the array 'list'. - * returns -1 if not present */ -static int16_t findOffset(const char* const* list, const char* key) -{ - const char* const* anchor = list; - while (*list != NULL) { - if (strcasecmp(key, *list) == 0) { - return (int16_t)(list - anchor); - } - list++; - } - - return -1; - -} -/*}}}*/ - -static char* getPreferredTag(const char* gf_tag) -{ - char* result = NULL; - zend_off_t grOffset = 0; - - grOffset = findOffset( LOC_GRANDFATHERED ,gf_tag); - if(grOffset < 0) { - return NULL; - } - if( LOC_PREFERRED_GRANDFATHERED[grOffset] != NULL ){ - /* return preferred tag */ - result = estrdup( LOC_PREFERRED_GRANDFATHERED[grOffset] ); - } else { - /* Return correct grandfathered language tag */ - result = estrdup( LOC_GRANDFATHERED[grOffset] ); - } - return result; -} - -/* {{{ -* returns the position of next token for lookup -* or -1 if no token -* strtokr equivalent search for token in reverse direction -*/ -static zend_off_t getStrrtokenPos(char* str, zend_off_t savedPos) -{ - zend_off_t result =-1; - zend_off_t i; - - for(i=savedPos-1; i>=0; i--) { - if(isIDSeparator(*(str+i)) || isKeywordSeparator(*(str+i))){ - /* delimiter found; check for singleton */ - if(i>=2 && isIDSeparator(*(str+i-2)) ){ - /* a singleton; so send the position of token before the singleton */ - result = i-2; - } else { - result = i; - } - break; - } - } - if(result < 1){ - /* Just in case inavlid locale e.g. '-x-xyz' or '-sl_Latn' */ - result =-1; - } - return result; -} -/* }}} */ - -/* {{{ -* returns the position of a singleton if present -* returns -1 if no singleton -* strtok equivalent search for singleton -*/ -static zend_off_t getSingletonPos(const char* str) -{ - zend_off_t result =-1; - size_t len = 0; - - if( str && ((len=strlen(str))>0) ){ - zend_off_t i = 0; - for( i=0; (size_t)i < len ; i++){ - if( isIDSeparator(*(str+i)) ){ - if( i==1){ - /* string is of the form x-avy or a-prv1 */ - result =0; - break; - } else { - /* delimiter found; check for singleton */ - if( isIDSeparator(*(str+i+2)) ){ - /* a singleton; so send the position of separator before singleton */ - result = i+1; - break; - } - } - } - }/* end of for */ - - } - return result; -} -/* }}} */ - -/* {{{ Get default locale */ -/* }}} */ -/* {{{ Get default locale */ -PHP_NAMED_FUNCTION(zif_locale_get_default) -{ - ZEND_PARSE_PARAMETERS_NONE(); - - RETURN_STRING( intl_locale_get_default( ) ); -} - -/* }}} */ - -/* {{{ Set default locale */ -/* }}} */ -/* {{{ Set default locale */ -PHP_NAMED_FUNCTION(zif_locale_set_default) -{ - zend_string* locale_name; - zend_string *ini_name; - char *default_locale = NULL; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH_STR(locale_name) - ZEND_PARSE_PARAMETERS_END(); - - if (ZSTR_LEN(locale_name) == 0) { - default_locale = (char *)uloc_getDefault(); - locale_name = zend_string_init(default_locale, strlen(default_locale), 0); - } - - ini_name = zend_string_init(LOCALE_INI_NAME, sizeof(LOCALE_INI_NAME) - 1, 0); - zend_alter_ini_entry(ini_name, locale_name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); - if (default_locale != NULL) { - zend_string_release_ex(locale_name, 0); - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ -* Gets the value from ICU -* common code shared by get_primary_language,get_script or get_region or get_variant -* result = 0 if error, 1 if successful , -1 if no value -*/ -static zend_string* get_icu_value_internal( const char* loc_name , char* tag_name, int* result , int fromParseLocale) -{ - zend_string* tag_value = NULL; - int32_t tag_value_len = 512; - - char* mod_loc_name = NULL; - - int32_t buflen = 512; - UErrorCode status = U_ZERO_ERROR; - - if (strlen(loc_name) > INTL_MAX_LOCALE_LEN) { - return NULL; - } - - if( strcmp(tag_name, LOC_CANONICALIZE_TAG) != 0 ){ - /* Handle grandfathered languages */ - zend_off_t grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); - if( grOffset >= 0 ){ - if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ - return zend_string_init(loc_name, strlen(loc_name), 0); - } else { - /* Since Grandfathered , no value , do nothing , retutn NULL */ - return NULL; - } - } - - if( fromParseLocale==1 ){ - zend_off_t singletonPos = 0; - - /* Handle singletons */ - if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ - if( strlen(loc_name)>1 && (isIDPrefix(loc_name) == 1) ){ - return zend_string_init(loc_name, strlen(loc_name), 0); - } - } - - singletonPos = getSingletonPos( loc_name ); - if( singletonPos == 0){ - /* singleton at start of script, region , variant etc. - * or invalid singleton at start of language */ - return NULL; - } else if( singletonPos > 0 ){ - /* singleton at some position except at start - * strip off the singleton and rest of the loc_name */ - mod_loc_name = estrndup ( loc_name , singletonPos-1); - } - } /* end of if fromParse */ - - } /* end of if != LOC_CANONICAL_TAG */ - - if( mod_loc_name == NULL){ - mod_loc_name = estrdup(loc_name ); - } - - /* Proceed to ICU */ - do{ - if (tag_value) { - tag_value = zend_string_realloc( tag_value , buflen, 0); - } else { - tag_value = zend_string_alloc( buflen, 0); - } - tag_value_len = buflen; - - if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){ - buflen = uloc_getScript ( mod_loc_name , tag_value->val , tag_value_len , &status); - } - if( strcmp(tag_name , LOC_LANG_TAG )==0 ){ - buflen = uloc_getLanguage ( mod_loc_name , tag_value->val , tag_value_len , &status); - } - if( strcmp(tag_name , LOC_REGION_TAG)==0 ){ - buflen = uloc_getCountry ( mod_loc_name , tag_value->val , tag_value_len , &status); - } - if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){ - buflen = uloc_getVariant ( mod_loc_name , tag_value->val , tag_value_len , &status); - } - if( strcmp(tag_name , LOC_CANONICALIZE_TAG)==0 ){ - buflen = uloc_canonicalize ( mod_loc_name , tag_value->val , tag_value_len , &status); - } - - if( U_FAILURE( status ) ) { - if( status == U_BUFFER_OVERFLOW_ERROR ) { - status = U_ZERO_ERROR; - buflen++; /* add space for \0 */ - continue; - } - - /* Error in retrieving data */ - *result = 0; - if( tag_value ){ - zend_string_release_ex( tag_value, 0 ); - } - if( mod_loc_name ){ - efree( mod_loc_name); - } - return NULL; - } - } while( buflen > tag_value_len ); - - if( buflen ==0 ){ - /* No value found */ - *result = -1; - if( tag_value ){ - zend_string_release_ex( tag_value, 0 ); - } - if( mod_loc_name ){ - efree( mod_loc_name); - } - return NULL; - } else { - *result = 1; - } - - if( mod_loc_name ){ - efree( mod_loc_name); - } - - tag_value->len = strlen(tag_value->val); - return tag_value; -} -/* }}} */ - -/* {{{ -* Gets the value from ICU , called when PHP userspace function is called -* common code shared by get_primary_language,get_script or get_region or get_variant -*/ -static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) -{ - - char* loc_name = NULL; - size_t loc_name_len = 0; - - zend_string* tag_value = NULL; - char* empty_result = ""; - - int result = 0; - char* msg = NULL; - - UErrorCode status = U_ZERO_ERROR; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH(loc_name, loc_name_len) - ZEND_PARSE_PARAMETERS_END(); - - if(loc_name_len == 0) { - loc_name = (char *)intl_locale_get_default(); - loc_name_len = strlen(loc_name); - } - - INTL_CHECK_LOCALE_LEN(loc_name_len); - - /* Call ICU get */ - tag_value = get_icu_value_internal( loc_name , tag_name , &result ,0); - - /* No value found */ - if( result == -1 ) { - if( tag_value){ - zend_string_release_ex( tag_value, 0 ); - } - RETURN_STRING( empty_result); - } - - /* value found */ - if( tag_value){ - RETVAL_STR( tag_value ); - return; - } - - /* Error encountered while fetching the value */ - if( result ==0) { - spprintf(&msg , 0, "locale_get_%s : unable to get locale %s", tag_name , tag_name ); - intl_error_set( NULL, status, msg , 1 ); - efree(msg); - RETURN_NULL(); - } - -} -/* }}} */ - -/* {{{ gets the script for the $locale */ -PHP_FUNCTION( locale_get_script ) -{ - get_icu_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ gets the region for the $locale */ -PHP_FUNCTION( locale_get_region ) -{ - get_icu_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ gets the primary language for the $locale */ -PHP_FUNCTION(locale_get_primary_language ) -{ - get_icu_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - - -/* {{{ - * common code shared by display_xyz functions to get the value from ICU - }}} */ -static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) -{ - char* loc_name = NULL; - size_t loc_name_len = 0; - - char* disp_loc_name = NULL; - size_t disp_loc_name_len = 0; - int free_loc_name = 0; - - UChar* disp_name = NULL; - int32_t disp_name_len = 0; - - char* mod_loc_name = NULL; - - int32_t buflen = 512; - UErrorCode status = U_ZERO_ERROR; - - zend_string* u8str; - - char* msg = NULL; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_PATH(loc_name, loc_name_len) - Z_PARAM_OPTIONAL - Z_PARAM_PATH_OR_NULL(disp_loc_name, disp_loc_name_len) - ZEND_PARSE_PARAMETERS_END(); - - if(loc_name_len > ULOC_FULLNAME_CAPACITY) { - /* See bug 67397: overlong locale names cause trouble in uloc_getDisplayName */ - spprintf(&msg , 0, "locale_get_display_%s : name too long", tag_name ); - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, msg , 1 ); - efree(msg); - RETURN_FALSE; - } - - if(loc_name_len == 0) { - loc_name = (char *)intl_locale_get_default(); - } - - if( strcmp(tag_name, DISP_NAME) != 0 ){ - /* Handle grandfathered languages */ - int grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); - if( grOffset >= 0 ){ - if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ - mod_loc_name = getPreferredTag( loc_name ); - } else { - /* Since Grandfathered, no value, do nothing, return NULL */ - RETURN_FALSE; - } - } - } /* end of if != LOC_CANONICAL_TAG */ - - if( mod_loc_name==NULL ){ - mod_loc_name = estrdup( loc_name ); - } - - /* Check if disp_loc_name passed , if not use default locale */ - if( !disp_loc_name){ - disp_loc_name = estrdup(intl_locale_get_default()); - free_loc_name = 1; - } - - /* Get the disp_value for the given locale */ - do{ - disp_name = erealloc( disp_name , buflen * sizeof(UChar) ); - disp_name_len = buflen; - - if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ - buflen = uloc_getDisplayLanguage ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); - } else if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){ - buflen = uloc_getDisplayScript ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); - } else if( strcmp(tag_name , LOC_REGION_TAG)==0 ){ - buflen = uloc_getDisplayCountry ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); - } else if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){ - buflen = uloc_getDisplayVariant ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); - } else if( strcmp(tag_name , DISP_NAME)==0 ){ - buflen = uloc_getDisplayName ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); - } - - /* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */ - if( U_FAILURE( status ) ) - { - if( status == U_BUFFER_OVERFLOW_ERROR ) - { - status = U_ZERO_ERROR; - continue; - } - - spprintf(&msg, 0, "locale_get_display_%s : unable to get locale %s", tag_name , tag_name ); - intl_error_set( NULL, status, msg , 1 ); - efree(msg); - if( disp_name){ - efree( disp_name ); - } - if( mod_loc_name){ - efree( mod_loc_name ); - } - if (free_loc_name) { - efree((void *)disp_loc_name); - disp_loc_name = NULL; - } - RETURN_FALSE; - } - } while( buflen > disp_name_len ); - - if( mod_loc_name){ - efree( mod_loc_name ); - } - if (free_loc_name) { - efree((void *)disp_loc_name); - disp_loc_name = NULL; - } - /* Convert display locale name from UTF-16 to UTF-8. */ - u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status ); - efree( disp_name ); - if( !u8str ) - { - spprintf(&msg, 0, "locale_get_display_%s :error converting display name for %s to UTF-8", tag_name , tag_name ); - intl_error_set( NULL, status, msg , 1 ); - efree(msg); - RETURN_FALSE; - } - - RETVAL_NEW_STR( u8str ); -} -/* }}} */ - -/* {{{ gets the name for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_name) -{ - get_icu_disp_value_src_php( DISP_NAME , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ gets the language for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_language) -{ - get_icu_disp_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ gets the script for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_script) -{ - get_icu_disp_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ gets the region for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_region) -{ - get_icu_disp_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ -* proto static string Locale::getDisplayVariant($locale, $in_locale = null) -* gets the variant for the $locale in $in_locale or default_locale - }}} */ -/* {{{ -* proto static string get_display_variant($locale, $in_locale = null) -* gets the variant for the $locale in $in_locale or default_locale -*/ -PHP_FUNCTION(locale_get_display_variant) -{ - get_icu_disp_value_src_php( LOC_VARIANT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - - /* {{{ return an associative array containing keyword-value - * pairs for this locale. The keys are keys to the array (doh!) - * }}}*/ - /* {{{ return an associative array containing keyword-value - * pairs for this locale. The keys are keys to the array (doh!) - */ -PHP_FUNCTION( locale_get_keywords ) -{ - UEnumeration* e = NULL; - UErrorCode status = U_ZERO_ERROR; - - const char* kw_key = NULL; - int32_t kw_key_len = 0; - - char* loc_name = NULL; - size_t loc_name_len = 0; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH(loc_name, loc_name_len) - ZEND_PARSE_PARAMETERS_END(); - - INTL_CHECK_LOCALE_LEN(strlen(loc_name)); - - if(loc_name_len == 0) { - loc_name = (char *)intl_locale_get_default(); - } - - /* Get the keywords */ - e = uloc_openKeywords( loc_name, &status ); - if( e != NULL ) { - /* - ICU expects the buffer to be allocated before calling the function - and so the buffer size has been explicitly specified - ICU uloc.h #define ULOC_KEYWORD_AND_VALUES_CAPACITY 100 - hence the kw_value buffer size is 100 - */ - - /* Traverse it, filling the return array. */ - array_init( return_value ); - - while( ( kw_key = uenum_next( e, &kw_key_len, &status ) ) != NULL ){ - int32_t kw_value_len = 100; - zend_string *kw_value_str = zend_string_alloc(kw_value_len, 0); - - /* Get the keyword value for each keyword */ - kw_value_len=uloc_getKeywordValue( loc_name, kw_key, ZSTR_VAL(kw_value_str), kw_value_len, &status ); - if (status == U_BUFFER_OVERFLOW_ERROR) { - status = U_ZERO_ERROR; - kw_value_str = zend_string_extend(kw_value_str, kw_value_len, 0); - kw_value_len=uloc_getKeywordValue( loc_name,kw_key, ZSTR_VAL(kw_value_str), kw_value_len+1, &status ); - } else if(!U_FAILURE(status)) { - kw_value_str = zend_string_truncate(kw_value_str, kw_value_len, 0); - } - if (U_FAILURE(status)) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 ); - if( kw_value_str){ - zend_string_efree( kw_value_str ); - } - zend_array_destroy(Z_ARR_P(return_value)); - RETURN_FALSE; - } - - add_assoc_str( return_value, (char *)kw_key, kw_value_str); - } /* end of while */ - - } /* end of if e!=NULL */ - - uenum_close( e ); -} -/* }}} */ - - /* {{{ @return string the canonicalized locale - * }}} */ - /* {{{ @param string $locale The locale string to canonicalize */ -PHP_FUNCTION(locale_canonicalize) -{ - get_icu_value_src_php( LOC_CANONICALIZE_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); -} -/* }}} */ - -/* {{{ append_key_value -* Internal function which is called from locale_compose -* gets the value for the key_name and appends to the loc_name -* returns 1 if successful , -1 if not found , -* 0 if array element is not a string , -2 if buffer-overflow -*/ -static int append_key_value(smart_str* loc_name, HashTable* hash_arr, char* key_name) -{ - zval *ele_value; - - if ((ele_value = zend_hash_str_find_deref(hash_arr , key_name, strlen(key_name))) != NULL ) { - if(Z_TYPE_P(ele_value)!= IS_STRING ){ - /* element value is not a string */ - return FAILURE; - } - if(strcmp(key_name, LOC_LANG_TAG) != 0 && - strcmp(key_name, LOC_GRANDFATHERED_LANG_TAG)!=0 ) { - /* not lang or grandfathered tag */ - smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - } - smart_str_appendl(loc_name, Z_STRVAL_P(ele_value) , Z_STRLEN_P(ele_value)); - return SUCCESS; - } - - return LOC_NOT_FOUND; -} -/* }}} */ - -/* {{{ append_prefix , appends the prefix needed -* e.g. private adds 'x' -*/ -static void add_prefix(smart_str* loc_name, char* key_name) -{ - if( strncmp(key_name , LOC_PRIVATE_TAG , 7) == 0 ){ - smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - smart_str_appendl(loc_name, PRIVATE_PREFIX , sizeof(PRIVATE_PREFIX)-1); - } -} -/* }}} */ - -/* {{{ append_multiple_key_values -* Internal function which is called from locale_compose -* gets the multiple values for the key_name and appends to the loc_name -* used for 'variant','extlang','private' -* returns 1 if successful , -1 if not found , -* 0 if array element is not a string , -2 if buffer-overflow -*/ -static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, char* key_name) -{ - zval *ele_value; - int isFirstSubtag = 0; - - /* Variant/ Extlang/Private etc. */ - if ((ele_value = zend_hash_str_find_deref( hash_arr , key_name , strlen(key_name))) != NULL) { - if( Z_TYPE_P(ele_value) == IS_STRING ){ - add_prefix( loc_name , key_name); - - smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - smart_str_appendl(loc_name, Z_STRVAL_P(ele_value) , Z_STRLEN_P(ele_value)); - return SUCCESS; - } else if(Z_TYPE_P(ele_value) == IS_ARRAY ) { - HashTable *arr = Z_ARRVAL_P(ele_value); - zval *data; - - ZEND_HASH_FOREACH_VAL(arr, data) { - ZVAL_DEREF(data); - if(Z_TYPE_P(data) != IS_STRING) { - return FAILURE; - } - if (isFirstSubtag++ == 0){ - add_prefix(loc_name , key_name); - } - smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - smart_str_appendl(loc_name, Z_STRVAL_P(data) , Z_STRLEN_P(data)); - } ZEND_HASH_FOREACH_END(); - return SUCCESS; - } else { - return FAILURE; - } - } else { - char cur_key_name[31]; - int max_value = 0, i; - /* Decide the max_value: the max. no. of elements allowed */ - if( strcmp(key_name , LOC_VARIANT_TAG) ==0 ){ - max_value = MAX_NO_VARIANT; - } - if( strcmp(key_name , LOC_EXTLANG_TAG) ==0 ){ - max_value = MAX_NO_EXTLANG; - } - if( strcmp(key_name , LOC_PRIVATE_TAG) ==0 ){ - max_value = MAX_NO_PRIVATE; - } - - /* Multiple variant values as variant0, variant1 ,variant2 */ - isFirstSubtag = 0; - for( i=0 ; i< max_value; i++ ){ - snprintf( cur_key_name , 30, "%s%d", key_name , i); - if ((ele_value = zend_hash_str_find_deref( hash_arr , cur_key_name , strlen(cur_key_name))) != NULL) { - if( Z_TYPE_P(ele_value)!= IS_STRING ){ - /* variant is not a string */ - return FAILURE; - } - /* Add the contents */ - if (isFirstSubtag++ == 0){ - add_prefix(loc_name , cur_key_name); - } - smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); - smart_str_appendl(loc_name, Z_STRVAL_P(ele_value) , Z_STRLEN_P(ele_value)); - } - } /* end of for */ - } /* end of else */ - - return SUCCESS; -} -/* }}} */ - -/*{{{ -* If applicable sets error message and aborts locale_compose gracefully -* returns 0 if locale_compose needs to be aborted -* otherwise returns 1 -*/ -static int handleAppendResult( int result, smart_str* loc_name) -{ - intl_error_reset( NULL ); - if( result == FAILURE) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "locale_compose: parameter array element is not a string", 0 ); - smart_str_free(loc_name); - return 0; - } - return 1; -} -/* }}} */ - -#define RETURN_SMART_STR(str) smart_str_0((str)); RETURN_NEW_STR((str)->s) -/* {{{ Creates a locale by combining the parts of locale-ID passed -* }}} */ -/* {{{ Creates a locale by combining the parts of locale-ID passed -* }}} */ -PHP_FUNCTION(locale_compose) -{ - smart_str loc_name_s = {0}; - smart_str *loc_name = &loc_name_s; - zval* arr = NULL; - HashTable* hash_arr = NULL; - int result = 0; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY(arr) - ZEND_PARSE_PARAMETERS_END(); - - hash_arr = Z_ARRVAL_P( arr ); - - if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) - RETURN_FALSE; - - /* Check for grandfathered first */ - result = append_key_value(loc_name, hash_arr, LOC_GRANDFATHERED_LANG_TAG); - if( result == SUCCESS){ - RETURN_SMART_STR(loc_name); - } - if( !handleAppendResult( result, loc_name)){ - RETURN_FALSE; - } - - /* Not grandfathered */ - result = append_key_value(loc_name, hash_arr , LOC_LANG_TAG); - if( result == LOC_NOT_FOUND ){ - zend_argument_value_error(1, "must contain a \"%s\" key", LOC_LANG_TAG); - smart_str_free(loc_name); - RETURN_THROWS(); - } - if( !handleAppendResult( result, loc_name)){ - RETURN_FALSE; - } - - /* Extlang */ - result = append_multiple_key_values(loc_name, hash_arr , LOC_EXTLANG_TAG); - if( !handleAppendResult( result, loc_name)){ - RETURN_FALSE; - } - - /* Script */ - result = append_key_value(loc_name, hash_arr , LOC_SCRIPT_TAG); - if( !handleAppendResult( result, loc_name)){ - RETURN_FALSE; - } - - /* Region */ - result = append_key_value( loc_name, hash_arr , LOC_REGION_TAG); - if( !handleAppendResult( result, loc_name)){ - RETURN_FALSE; - } - - /* Variant */ - result = append_multiple_key_values( loc_name, hash_arr , LOC_VARIANT_TAG); - if( !handleAppendResult( result, loc_name)){ - RETURN_FALSE; - } - - /* Private */ - result = append_multiple_key_values( loc_name, hash_arr , LOC_PRIVATE_TAG); - if( !handleAppendResult( result, loc_name)){ - RETURN_FALSE; - } - - RETURN_SMART_STR(loc_name); -} -/* }}} */ - - -/*{{{ -* Parses the locale and returns private subtags if existing -* else returns NULL -* e.g. for locale='en_US-x-prv1-prv2-prv3' -* returns a pointer to the string 'prv1-prv2-prv3' -*/ -static zend_string* get_private_subtags(const char* loc_name) -{ - zend_string* result = NULL; - size_t len = 0; - const char* mod_loc_name =NULL; - - if( loc_name && (len = strlen(loc_name)) > 0 ){ - zend_off_t singletonPos = 0; - mod_loc_name = loc_name ; - while( (singletonPos = getSingletonPos(mod_loc_name)) > -1){ - if( (*(mod_loc_name+singletonPos)=='x') || (*(mod_loc_name+singletonPos)=='X') ){ - /* private subtag start found */ - if( singletonPos + 2 == len){ - /* loc_name ends with '-x-' ; return NULL */ - } - else{ - /* result = mod_loc_name + singletonPos +2; */ - result = zend_string_init(mod_loc_name + singletonPos+2 , (len -( singletonPos +2) ), 0); - } - break; - } - else{ - if((size_t)(singletonPos + 1) >= len){ - /* String end */ - break; - } else { - /* singleton found but not a private subtag , hence check further in the string for the private subtag */ - mod_loc_name = mod_loc_name + singletonPos +1; - len = strlen(mod_loc_name); - } - } - } /* end of while */ - } - - return result; -} -/* }}} */ - -/* {{{ code used by locale_parse */ -static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name) -{ - zend_string* key_value = NULL; - char* cur_key_name = NULL; - char* token = NULL; - char* last_ptr = NULL; - - int result = 0; - int cur_result = 0; - - - if( strcmp(key_name , LOC_PRIVATE_TAG)==0 ){ - key_value = get_private_subtags( loc_name ); - result = 1; - } else { - key_value = get_icu_value_internal( loc_name , key_name , &result,1 ); - } - if( (strcmp(key_name , LOC_PRIVATE_TAG)==0) || - ( strcmp(key_name , LOC_VARIANT_TAG)==0) ){ - if( result > 0 && key_value){ - int cnt = 0; - /* Tokenize on the "_" or "-" */ - token = php_strtok_r( key_value->val , DELIMITER ,&last_ptr); - if( cur_key_name ){ - efree( cur_key_name); - } - /* Over-allocates a few bytes for the integer so we don't have to reallocate. */ - size_t cur_key_name_size = (sizeof("-2147483648") - 1) + strlen(key_name) + 1; - cur_key_name = emalloc(cur_key_name_size); - snprintf( cur_key_name, cur_key_name_size , "%s%d", key_name , cnt++); - add_assoc_string( hash_arr, cur_key_name , token); - /* tokenize on the "_" or "-" and stop at singleton if any */ - while( (token = php_strtok_r(NULL , DELIMITER , &last_ptr)) && (strlen(token)>1) ){ - snprintf( cur_key_name , cur_key_name_size, "%s%d", key_name , cnt++); - add_assoc_string( hash_arr, cur_key_name , token); - } -/* - if( strcmp(key_name, LOC_PRIVATE_TAG) == 0 ){ - } -*/ - } - if (key_value) { - zend_string_release_ex(key_value, 0); - } - } else { - if( result == 1 ){ - add_assoc_str( hash_arr, key_name , key_value); - cur_result = 1; - } else if (key_value) { - zend_string_release_ex(key_value, 0); - } - } - - if( cur_key_name ){ - efree( cur_key_name); - } - /*if( key_name != LOC_PRIVATE_TAG && key_value){*/ - return cur_result; -} -/* }}} */ - -/* {{{ parses a locale-id into an array the different parts of it */ -PHP_FUNCTION(locale_parse) -{ - char* loc_name = NULL; - size_t loc_name_len = 0; - int grOffset = 0; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH(loc_name, loc_name_len) - ZEND_PARSE_PARAMETERS_END(); - - INTL_CHECK_LOCALE_LEN(strlen(loc_name)); - - if(loc_name_len == 0) { - loc_name = (char *)intl_locale_get_default(); - } - - array_init( return_value ); - - grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); - if( grOffset >= 0 ){ - add_assoc_string( return_value , LOC_GRANDFATHERED_LANG_TAG, (char *)loc_name); - } - else{ - /* Not grandfathered */ - add_array_entry( loc_name , return_value , LOC_LANG_TAG); - add_array_entry( loc_name , return_value , LOC_SCRIPT_TAG); - add_array_entry( loc_name , return_value , LOC_REGION_TAG); - add_array_entry( loc_name , return_value , LOC_VARIANT_TAG); - add_array_entry( loc_name , return_value , LOC_PRIVATE_TAG); - } -} -/* }}} */ - -/* {{{ gets an array containing the list of variants, or null */ -PHP_FUNCTION(locale_get_all_variants) -{ - char* loc_name = NULL; - size_t loc_name_len = 0; - - int result = 0; - char* token = NULL; - zend_string* variant = NULL; - char* saved_ptr = NULL; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH(loc_name, loc_name_len) - ZEND_PARSE_PARAMETERS_END(); - - if(loc_name_len == 0) { - loc_name = (char *)intl_locale_get_default(); - loc_name_len = strlen(loc_name); - } - - INTL_CHECK_LOCALE_LEN(loc_name_len); - - array_init( return_value ); - - /* If the locale is grandfathered, stop, no variants */ - if( findOffset( LOC_GRANDFATHERED , loc_name ) >= 0 ){ - /* ("Grandfathered Tag. No variants."); */ - } - else { - /* Call ICU variant */ - variant = get_icu_value_internal( loc_name , LOC_VARIANT_TAG , &result ,0); - if( result > 0 && variant){ - /* Tokenize on the "_" or "-" */ - token = php_strtok_r( variant->val , DELIMITER , &saved_ptr); - add_next_index_stringl( return_value, token , strlen(token)); - /* tokenize on the "_" or "-" and stop at singleton if any */ - while( (token = php_strtok_r(NULL , DELIMITER, &saved_ptr)) && (strlen(token)>1) ){ - add_next_index_stringl( return_value, token , strlen(token)); - } - } - if( variant ){ - zend_string_release_ex( variant, 0 ); - } - } - - -} -/* }}} */ - -/* {{{ Converts to lower case and also replaces all hyphens with the underscore */ -static int strToMatch(const char* str ,char *retstr) -{ - char* anchor = NULL; - const char* anchor1 = NULL; - int result = 0; - - if( (!str) || str[0] == '\0'){ - return result; - } else { - anchor = retstr; - anchor1 = str; - while( (*str)!='\0' ){ - if( *str == '-' ){ - *retstr = '_'; - } else { - *retstr = tolower(*str); - } - str++; - retstr++; - } - *retstr = '\0'; - retstr= anchor; - str= anchor1; - result = 1; - } - - return(result); -} -/* }}} */ - -/* {{{ Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ -/* }}} */ -/* {{{ Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ -PHP_FUNCTION(locale_filter_matches) -{ - char* lang_tag = NULL; - size_t lang_tag_len = 0; - char* loc_range = NULL; - size_t loc_range_len = 0; - - int result = 0; - char* token = 0; - char* chrcheck = NULL; - - zend_string* can_lang_tag = NULL; - zend_string* can_loc_range = NULL; - - char* cur_lang_tag = NULL; - char* cur_loc_range = NULL; - - bool boolCanonical = 0; - UErrorCode status = U_ZERO_ERROR; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_PATH(lang_tag, lang_tag_len) - Z_PARAM_PATH(loc_range, loc_range_len) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(boolCanonical) - ZEND_PARSE_PARAMETERS_END(); - - if(loc_range_len == 0) { - loc_range = (char *)intl_locale_get_default(); - loc_range_len = strlen(loc_range); - } - - if( strcmp(loc_range,"*")==0){ - RETURN_TRUE; - } - - INTL_CHECK_LOCALE_LEN(loc_range_len); - INTL_CHECK_LOCALE_LEN(lang_tag_len); - - if( boolCanonical ){ - /* canonicalize loc_range */ - can_loc_range=get_icu_value_internal( loc_range , LOC_CANONICALIZE_TAG , &result , 0); - if( result <=0) { - intl_error_set( NULL, status, - "locale_filter_matches : unable to canonicalize loc_range" , 0 ); - RETURN_FALSE; - } - - /* canonicalize lang_tag */ - can_lang_tag = get_icu_value_internal( lang_tag , LOC_CANONICALIZE_TAG , &result , 0); - if( result <=0) { - intl_error_set( NULL, status, - "locale_filter_matches : unable to canonicalize lang_tag" , 0 ); - RETURN_FALSE; - } - - /* Convert to lower case for case-insensitive comparison */ - cur_lang_tag = ecalloc( 1, can_lang_tag->len + 1); - - /* Convert to lower case for case-insensitive comparison */ - result = strToMatch( can_lang_tag->val , cur_lang_tag); - if( result == 0) { - efree( cur_lang_tag ); - zend_string_release_ex( can_lang_tag, 0 ); - RETURN_FALSE; - } - - cur_loc_range = ecalloc( 1, can_loc_range->len + 1); - result = strToMatch( can_loc_range->val , cur_loc_range ); - if( result == 0) { - efree( cur_lang_tag ); - zend_string_release_ex( can_lang_tag, 0 ); - efree( cur_loc_range ); - zend_string_release_ex( can_loc_range, 0 ); - RETURN_FALSE; - } - - /* check if prefix */ - token = strstr( cur_lang_tag , cur_loc_range ); - - if( token && (token==cur_lang_tag) ){ - /* check if the char. after match is SEPARATOR */ - chrcheck = token + (strlen(cur_loc_range)); - if( isIDSeparator(*chrcheck) || isKeywordSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ - efree( cur_lang_tag ); - efree( cur_loc_range ); - if( can_lang_tag){ - zend_string_release_ex( can_lang_tag, 0 ); - } - if( can_loc_range){ - zend_string_release_ex( can_loc_range, 0 ); - } - RETURN_TRUE; - } - } - - /* No prefix as loc_range */ - if( cur_lang_tag){ - efree( cur_lang_tag ); - } - if( cur_loc_range){ - efree( cur_loc_range ); - } - if( can_lang_tag){ - zend_string_release_ex( can_lang_tag, 0 ); - } - if( can_loc_range){ - zend_string_release_ex( can_loc_range, 0 ); - } - RETURN_FALSE; - - } /* end of if isCanonical */ - else{ - /* Convert to lower case for case-insensitive comparison */ - cur_lang_tag = ecalloc( 1, strlen(lang_tag ) + 1); - - result = strToMatch( lang_tag , cur_lang_tag); - if( result == 0) { - efree( cur_lang_tag ); - RETURN_FALSE; - } - cur_loc_range = ecalloc( 1, strlen(loc_range ) + 1); - result = strToMatch( loc_range , cur_loc_range ); - if( result == 0) { - efree( cur_lang_tag ); - efree( cur_loc_range ); - RETURN_FALSE; - } - - /* check if prefix */ - token = strstr( cur_lang_tag , cur_loc_range ); - - if( token && (token==cur_lang_tag) ){ - /* check if the char. after match is SEPARATOR */ - chrcheck = token + (strlen(cur_loc_range)); - if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ - efree( cur_lang_tag ); - efree( cur_loc_range ); - RETURN_TRUE; - } - } - - /* No prefix as loc_range */ - if( cur_lang_tag){ - efree( cur_lang_tag ); - } - if( cur_loc_range){ - efree( cur_loc_range ); - } - RETURN_FALSE; - - } -} -/* }}} */ - -static void array_cleanup( char* arr[] , int arr_size) -{ - int i=0; - for( i=0; i< arr_size; i++ ){ - if( arr[i*2] ){ - efree( arr[i*2]); - } - } - efree(arr); -} - -#define LOOKUP_CLEAN_RETURN(value) array_cleanup(cur_arr, cur_arr_len); return (value) -/* {{{ -* returns the lookup result to lookup_loc_range_src_php -* internal function -*/ -static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int canonicalize ) -{ - int i = 0; - int cur_arr_len = 0; - int result = 0; - - zend_string* lang_tag = NULL; - zval* ele_value = NULL; - - char* cur_loc_range = NULL; - zend_string* can_loc_range = NULL; - zend_off_t saved_pos = 0; - - zend_string* return_value = NULL; - - char **cur_arr = ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *)); - ZEND_HASH_FOREACH_VAL(hash_arr, ele_value) { - ZVAL_DEREF(ele_value); - /* convert the array to lowercase , also replace hyphens with the underscore and store it in cur_arr */ - if(Z_TYPE_P(ele_value)!= IS_STRING) { - /* element value is not a string */ - zend_argument_type_error(2, "must only contain string values"); - LOOKUP_CLEAN_RETURN(NULL); - } - if (zend_str_has_nul_byte(Z_STR_P(ele_value))) { - zend_argument_value_error(2, "must not contain any null bytes"); - LOOKUP_CLEAN_RETURN(NULL); - } - cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); - result = strToMatch(Z_STRVAL_P(ele_value), cur_arr[cur_arr_len*2]); - if(result == 0) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag", 0); - LOOKUP_CLEAN_RETURN(NULL); - } - cur_arr[cur_arr_len*2+1] = Z_STRVAL_P(ele_value); - cur_arr_len++ ; - } ZEND_HASH_FOREACH_END(); /* end of for */ - - /* Canonicalize array elements */ - if(canonicalize) { - for(i=0; ival[0]) { - if(lang_tag) { - zend_string_release_ex(lang_tag, 0); - } - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0); - LOOKUP_CLEAN_RETURN(NULL); - } - cur_arr[i*2] = erealloc(cur_arr[i*2], lang_tag->len+1); - result = strToMatch(lang_tag->val, cur_arr[i*2]); - zend_string_release_ex(lang_tag, 0); - if(result == 0) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0); - LOOKUP_CLEAN_RETURN(NULL); - } - } - - } - - if(canonicalize) { - /* Canonicalize the loc_range */ - can_loc_range = get_icu_value_internal(loc_range, LOC_CANONICALIZE_TAG, &result , 0); - if( result != 1 || can_loc_range == NULL || !can_loc_range->val[0]) { - /* Error */ - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize loc_range" , 0 ); - if(can_loc_range) { - zend_string_release_ex(can_loc_range, 0); - } - LOOKUP_CLEAN_RETURN(NULL); - } else { - loc_range = can_loc_range->val; - } - } - - cur_loc_range = ecalloc(1, strlen(loc_range)+1); - /* convert to lower and replace hyphens */ - result = strToMatch(loc_range, cur_loc_range); - if(can_loc_range) { - zend_string_release_ex(can_loc_range, 0); - } - if(result == 0) { - efree(cur_loc_range); - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0); - LOOKUP_CLEAN_RETURN(NULL); - } - - /* Lookup for the lang_tag match */ - saved_pos = strlen(cur_loc_range); - while(saved_pos > 0) { - for(i=0; i< cur_arr_len; i++){ - if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) { - /* Match found */ - char *str = canonicalize ? cur_arr[i*2] : cur_arr[i*2+1]; - return_value = zend_string_init(str, strlen(str), 0); - efree(cur_loc_range); - LOOKUP_CLEAN_RETURN(return_value); - } - } - saved_pos = getStrrtokenPos(cur_loc_range, saved_pos); - } - - /* Match not found */ - efree(cur_loc_range); - LOOKUP_CLEAN_RETURN(NULL); -} -/* }}} */ - -/* {{{ Searches the items in $langtag for the best match to the language -* range -*/ -/* }}} */ -/* {{{ Searches the items in $langtag for the best match to the language -* range -*/ -PHP_FUNCTION(locale_lookup) -{ - zend_string* fallback_loc_str = NULL; - char* loc_range = NULL; - size_t loc_range_len = 0; - - zval* arr = NULL; - HashTable* hash_arr = NULL; - bool boolCanonical = 0; - zend_string* result_str = NULL; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_ARRAY(arr) - Z_PARAM_PATH(loc_range, loc_range_len) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(boolCanonical) - Z_PARAM_PATH_STR_OR_NULL(fallback_loc_str) - ZEND_PARSE_PARAMETERS_END(); - - if(loc_range_len == 0) { - if(fallback_loc_str) { - loc_range = ZSTR_VAL(fallback_loc_str); - loc_range_len = ZSTR_LEN(fallback_loc_str); - } else { - loc_range = (char *)intl_locale_get_default(); - loc_range_len = strlen(loc_range); - } - } - - hash_arr = Z_ARRVAL_P(arr); - - INTL_CHECK_LOCALE_LEN(loc_range_len); - - if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) { - RETURN_EMPTY_STRING(); - } - - result_str = lookup_loc_range(loc_range, hash_arr, boolCanonical); - if(result_str == NULL || ZSTR_VAL(result_str)[0] == '\0') { - if( fallback_loc_str ) { - result_str = zend_string_copy(fallback_loc_str); - } else { - RETURN_EMPTY_STRING(); - } - } - - RETURN_STR(result_str); -} -/* }}} */ - -/* {{{ Tries to find out best available locale based on HTTP "Accept-Language" header */ -/* }}} */ -/* {{{ Tries to find out best available locale based on HTTP "Accept-Language" header */ -PHP_FUNCTION(locale_accept_from_http) -{ - UEnumeration *available; - char *http_accept = NULL; - size_t http_accept_len; - UErrorCode status = 0; - int len; - char resultLocale[INTL_MAX_LOCALE_LEN+1]; - UAcceptResult outResult; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(http_accept, http_accept_len) - ZEND_PARSE_PARAMETERS_END(); - if(http_accept_len > ULOC_FULLNAME_CAPACITY) { - /* check each fragment, if any bigger than capacity, can't do it due to bug #72533 */ - char *start = http_accept; - char *end; - size_t len; - do { - end = strchr(start, ','); - len = end ? end-start : http_accept_len-(start-http_accept); - if(len > ULOC_FULLNAME_CAPACITY) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "locale_accept_from_http: locale string too long", 0 ); - RETURN_FALSE; - } - if(end) { - start = end+1; - } - } while(end != NULL); - } - - available = ures_openAvailableLocales(NULL, &status); - INTL_CHECK_STATUS(status, "locale_accept_from_http: failed to retrieve locale list"); - len = uloc_acceptLanguageFromHTTP(resultLocale, INTL_MAX_LOCALE_LEN, - &outResult, http_accept, available, &status); - uenum_close(available); - INTL_CHECK_STATUS(status, "locale_accept_from_http: failed to find acceptable locale"); - if (len < 0 || outResult == ULOC_ACCEPT_FAILED) { - RETURN_FALSE; - } - RETURN_STRINGL(resultLocale, len); -} -/* }}} */ - -PHP_FUNCTION(locale_is_right_to_left) -{ - char *locale; - size_t locale_len; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH(locale, locale_len) - ZEND_PARSE_PARAMETERS_END(); - - if (!locale_len) { - locale = (char *)intl_locale_get_default(); - } - - RETURN_BOOL(uloc_isRightToLeft(locale)); -} - -PHP_FUNCTION(locale_add_likely_subtags) -{ - char *locale, maximized_locale[ULOC_FULLNAME_CAPACITY]; - UErrorCode status = 0; - size_t locale_len; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH(locale, locale_len) - ZEND_PARSE_PARAMETERS_END(); - - if (!locale_len) { - locale = (char *)intl_locale_get_default(); - } - - int32_t maximized_locale_len = uloc_addLikelySubtags(locale, maximized_locale, sizeof(maximized_locale), &status); - INTL_CHECK_STATUS(status, "locale_add_likely_subtags: invalid locale"); - if (maximized_locale_len < 0) { - RETURN_FALSE; - } - - RETURN_STRINGL(maximized_locale, maximized_locale_len); -} - -PHP_FUNCTION(locale_minimize_subtags) -{ - char *locale, minimized_locale[ULOC_FULLNAME_CAPACITY]; - UErrorCode status = 0; - size_t locale_len; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH(locale, locale_len) - ZEND_PARSE_PARAMETERS_END(); - - if (!locale_len) { - locale = (char *)intl_locale_get_default(); - } - - int32_t minimized_locale_len = uloc_minimizeSubtags(locale, minimized_locale, sizeof(minimized_locale), &status); - INTL_CHECK_STATUS(status, "locale_minimize_subtags: invalid locale"); - if (minimized_locale_len < 0) { - RETURN_FALSE; - } - - RETURN_STRINGL(minimized_locale, minimized_locale_len); -} diff --git a/ext/intl/locale/locale_methods.cpp b/ext/intl/locale/locale_methods.cpp new file mode 100644 index 000000000000..1ee32a2f094e --- /dev/null +++ b/ext/intl/locale/locale_methods.cpp @@ -0,0 +1,1683 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar | + +----------------------------------------------------------------------+ +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +extern "C" { +#include "php_intl.h" +#include "locale.h" +#include "locale_class.h" +#include "intl_convert.h" +#include "intl_data.h" + +#include +#include +#include +#include "main/php_ini.h" +#include "zend_smart_str.h" +} + +ZEND_EXTERN_MODULE_GLOBALS( intl ) + +/* Sizes required for the strings "variant15" , "extlang11", "private12" etc. */ +#define SEPARATOR "_" +#define SEPARATOR1 "-" +#define DELIMITER "-_" +#define EXTLANG_PREFIX "a" +#define PRIVATE_PREFIX "x" +#define DISP_NAME "name" + +#define MAX_NO_VARIANT 15 +#define MAX_NO_EXTLANG 3 +#define MAX_NO_PRIVATE 15 +#define MAX_NO_LOOKUP_LANG_TAG 100 + +#define LOC_NOT_FOUND 1 + +/* Sizes required for the strings "variant15" , "extlang3", "private12" etc. */ +#define VARIANT_KEYNAME_LEN 11 +#define EXTLANG_KEYNAME_LEN 10 +#define PRIVATE_KEYNAME_LEN 11 + +/* Based on the IANA language subtag registry (File-Date: 2021-08-06) + * https://www.iana.org/assignments/language-subtag-registry + * + * This list includes all grandfathered tags, as well as redundant + * tags that have a Preferred-Value. + */ +static const char * const LOC_GRANDFATHERED[] = { + "art-lojban", + "cel-gaulish", + "en-GB-oed", + "i-ami", + "i-bnn", + "i-default", + "i-enochian", + "i-hak", + "i-klingon", + "i-lux", + "i-mingo", + "i-navajo", + "i-pwn", + "i-tao", + "i-tay", + "i-tsu", + "no-bok", + "no-nyn", + "sgn-BE-FR", + "sgn-BE-NL", + "sgn-BR", + "sgn-CH-DE", + "sgn-CO", + "sgn-DE", + "sgn-DK", + "sgn-ES", + "sgn-FR", + "sgn-GB", + "sgn-GR", + "sgn-IE", + "sgn-IT", + "sgn-JP", + "sgn-MX", + "sgn-NI", + "sgn-NL", + "sgn-NO", + "sgn-PT", + "sgn-SE", + "sgn-US", + "sgn-ZA", + "zh-cmn", + "zh-cmn-Hans", + "zh-cmn-Hant", + "zh-gan", + "zh-guoyu", + "zh-hakka", + "zh-min", + "zh-min-nan", + "zh-wuu", + "zh-xiang", + NULL +}; + +/* Based on the IANA language subtag registry (File-Date: 2021-08-06) + * + * This array lists the preferred values for the grandfathered and redundant + * tags listed in LOC_GRANDFATHERED. This is in sync with the array + * LOC_GRANDFATHERED, i.e., the offsets of the grandfathered tags match the + * offsets of the preferred value. If a value in LOC_PREFERRED_GRANDFATHERED is + * NULL, then the matching offset in LOC_GRANDFATHERED has no preferred value. + */ +static const char * const LOC_PREFERRED_GRANDFATHERED[] = { + "jbo", + NULL, + "en-GB-oxendict", + "ami", + "bnn", + NULL, + NULL, + "hak", + "tlh", + "lb", + NULL, + "nv", + "pwn", + "tao", + "tay", + "tsu", + "nb", + "nn", + "sfb", + "vgt", + "bzs", + "sgg", + "csn", + "gsg", + "dsl", + "ssp", + "fsl", + "bfi", + "gss", + "isg", + "ise", + "jsl", + "mfs", + "ncs", + "dse", + "nsl", + "psr", + "swl", + "ase", + "sfs", + "cmn", + "cmn-Hans", + "cmn-Hant", + "gan", + "cmn", + "hak", + NULL, + "nan", + "wuu", + "hsn", + NULL +}; + +/* returns true if a is an ID separator, false otherwise */ +#define isIDSeparator(a) (a == '_' || a == '-') +#define isKeywordSeparator(a) (a == '@' ) +#define isEndOfTag(a) (a == '\0' ) + +#define isPrefixLetter(a) ((a=='x')||(a=='X')||(a=='i')||(a=='I')) + +/*returns true if one of the special prefixes is here (s=string) + 'x-' or 'i-' */ +#define isIDPrefix(s) (isPrefixLetter(s[0])&&isIDSeparator(s[1])) +#define isKeywordPrefix(s) ( isKeywordSeparator(s[0]) ) + +/* Dot terminates it because of POSIX form where dot precedes the codepage + * except for variant */ +#define isTerminator(a) ((a==0)||(a=='.')||(a=='@')) + +/* {{{ return the offset of 'key' in the array 'list'. + * returns -1 if not present */ +static int16_t findOffset(const char* const* list, const char* key) +{ + const char* const* anchor = list; + while (*list != NULL) { + if (strcasecmp(key, *list) == 0) { + return (int16_t)(list - anchor); + } + list++; + } + + return -1; + +} +/*}}}*/ + +static char* getPreferredTag(const char* gf_tag) +{ + char* result = NULL; + zend_off_t grOffset = 0; + + grOffset = findOffset( LOC_GRANDFATHERED ,gf_tag); + if(grOffset < 0) { + return NULL; + } + if( LOC_PREFERRED_GRANDFATHERED[grOffset] != NULL ){ + /* return preferred tag */ + result = estrdup( LOC_PREFERRED_GRANDFATHERED[grOffset] ); + } else { + /* Return correct grandfathered language tag */ + result = estrdup( LOC_GRANDFATHERED[grOffset] ); + } + return result; +} + +/* {{{ +* returns the position of next token for lookup +* or -1 if no token +* strtokr equivalent search for token in reverse direction +*/ +static zend_off_t getStrrtokenPos(char* str, zend_off_t savedPos) +{ + zend_off_t result =-1; + zend_off_t i; + + for(i=savedPos-1; i>=0; i--) { + if(isIDSeparator(*(str+i)) || isKeywordSeparator(*(str+i))){ + /* delimiter found; check for singleton */ + if(i>=2 && isIDSeparator(*(str+i-2)) ){ + /* a singleton; so send the position of token before the singleton */ + result = i-2; + } else { + result = i; + } + break; + } + } + if(result < 1){ + /* Just in case invalid locale e.g. '-x-xyz' or '-sl_Latn' */ + result =-1; + } + return result; +} +/* }}} */ + +/* {{{ +* returns the position of a singleton if present +* returns -1 if no singleton +* strtok equivalent search for singleton +*/ +static zend_off_t getSingletonPos(const char* str) +{ + zend_off_t result =-1; + size_t len = 0; + + if( str && ((len=strlen(str))>0) ){ + zend_off_t i = 0; + for( i=0; (size_t)i < len ; i++){ + if( isIDSeparator(*(str+i)) ){ + if( i==1){ + /* string is of the form x-avy or a-prv1 */ + result =0; + break; + } else { + /* delimiter found; check for singleton */ + if( isIDSeparator(*(str+i+2)) ){ + /* a singleton; so send the position of separator before singleton */ + result = i+1; + break; + } + } + } + }/* end of for */ + + } + return result; +} +/* }}} */ + +/* {{{ Get default locale */ +/* }}} */ +/* {{{ Get default locale */ +U_CFUNC PHP_NAMED_FUNCTION(zif_locale_get_default) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + RETURN_STRING( intl_locale_get_default( ) ); +} + +/* }}} */ + +/* {{{ Set default locale */ +/* }}} */ +/* {{{ Set default locale */ +U_CFUNC PHP_NAMED_FUNCTION(zif_locale_set_default) +{ + zend_string* locale_name; + zend_string *ini_name; + char *default_locale = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH_STR(locale_name) + ZEND_PARSE_PARAMETERS_END(); + + if (ZSTR_LEN(locale_name) == 0) { + default_locale = (char *)uloc_getDefault(); + locale_name = zend_string_init(default_locale, strlen(default_locale), 0); + } + + ini_name = zend_string_init(LOCALE_INI_NAME, sizeof(LOCALE_INI_NAME) - 1, 0); + zend_alter_ini_entry(ini_name, locale_name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_string_release_ex(ini_name, 0); + if (default_locale != NULL) { + zend_string_release_ex(locale_name, 0); + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ +* Gets the value from ICU +* common code shared by get_primary_language,get_script or get_region or get_variant +* result = 0 if error, 1 if successful , -1 if no value +*/ +static zend_string* get_icu_value_internal( const char* loc_name , const char* tag_name, int* result , int fromParseLocale) +{ + zend_string* tag_value = NULL; + int32_t tag_value_len = 512; + + char* mod_loc_name = NULL; + + int32_t buflen = 512; + UErrorCode status = U_ZERO_ERROR; + + if (strlen(loc_name) > INTL_MAX_LOCALE_LEN) { + return NULL; + } + + if( strcmp(tag_name, LOC_CANONICALIZE_TAG) != 0 ){ + /* Handle grandfathered languages */ + zend_off_t grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); + if( grOffset >= 0 ){ + if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ + return zend_string_init(loc_name, strlen(loc_name), 0); + } else { + /* Since Grandfathered , no value , do nothing , return NULL */ + return NULL; + } + } + + if( fromParseLocale==1 ){ + zend_off_t singletonPos = 0; + + /* Handle singletons */ + if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ + if( strlen(loc_name)>1 && (isIDPrefix(loc_name) == 1) ){ + return zend_string_init(loc_name, strlen(loc_name), 0); + } + } + + singletonPos = getSingletonPos( loc_name ); + if( singletonPos == 0){ + /* singleton at start of script, region , variant etc. + * or invalid singleton at start of language */ + return NULL; + } else if( singletonPos > 0 ){ + /* singleton at some position except at start + * strip off the singleton and rest of the loc_name */ + mod_loc_name = estrndup ( loc_name , singletonPos-1); + } + } /* end of if fromParse */ + + } /* end of if != LOC_CANONICAL_TAG */ + + if( mod_loc_name == NULL){ + mod_loc_name = estrdup(loc_name ); + } + + /* Proceed to ICU */ + do{ + if (tag_value) { + tag_value = zend_string_realloc( tag_value , buflen, 0); + } else { + tag_value = zend_string_alloc( buflen, 0); + } + tag_value_len = buflen; + + if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){ + buflen = uloc_getScript ( mod_loc_name , tag_value->val , tag_value_len , &status); + } + if( strcmp(tag_name , LOC_LANG_TAG )==0 ){ + buflen = uloc_getLanguage ( mod_loc_name , tag_value->val , tag_value_len , &status); + } + if( strcmp(tag_name , LOC_REGION_TAG)==0 ){ + buflen = uloc_getCountry ( mod_loc_name , tag_value->val , tag_value_len , &status); + } + if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){ + buflen = uloc_getVariant ( mod_loc_name , tag_value->val , tag_value_len , &status); + } + if( strcmp(tag_name , LOC_CANONICALIZE_TAG)==0 ){ + buflen = uloc_canonicalize ( mod_loc_name , tag_value->val , tag_value_len , &status); + } + + if( U_FAILURE( status ) ) { + if( status == U_BUFFER_OVERFLOW_ERROR ) { + status = U_ZERO_ERROR; + buflen++; /* add space for \0 */ + continue; + } + + /* Error in retrieving data */ + *result = 0; + if( tag_value ){ + zend_string_release_ex( tag_value, 0 ); + } + if( mod_loc_name ){ + efree( mod_loc_name); + } + return NULL; + } + } while( buflen > tag_value_len ); + + if( buflen ==0 ){ + /* No value found */ + *result = -1; + if( tag_value ){ + zend_string_release_ex( tag_value, 0 ); + } + if( mod_loc_name ){ + efree( mod_loc_name); + } + return NULL; + } else { + *result = 1; + } + + if( mod_loc_name ){ + efree( mod_loc_name); + } + + tag_value->len = buflen; + return tag_value; +} +/* }}} */ + +/* {{{ +* Gets the value from ICU , called when PHP userspace function is called +* common code shared by get_primary_language,get_script or get_region or get_variant +*/ +static void get_icu_value_src_php( const char* tag_name, INTERNAL_FUNCTION_PARAMETERS) +{ + + char* loc_name = NULL; + size_t loc_name_len = 0; + + zend_string* tag_value = NULL; + + int result = 0; + char* msg = NULL; + + UErrorCode status = U_ZERO_ERROR; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(loc_name, loc_name_len) + ZEND_PARSE_PARAMETERS_END(); + + if(loc_name_len == 0) { + loc_name = (char *)intl_locale_get_default(); + loc_name_len = strlen(loc_name); + } + + INTL_CHECK_LOCALE_LEN(loc_name_len); + + /* Call ICU get */ + tag_value = get_icu_value_internal( loc_name , tag_name , &result ,0); + + /* No value found */ + if( result == -1 ) { + if( tag_value){ + zend_string_release_ex( tag_value, 0 ); + } + RETURN_EMPTY_STRING(); + } + + /* value found */ + if( tag_value){ + RETURN_STR( tag_value ); + } + + /* Error encountered while fetching the value */ + if( result ==0) { + spprintf(&msg , 0, "unable to get locale %s", tag_name ); + intl_error_set( NULL, status, msg); + efree(msg); + RETURN_NULL(); + } + +} +/* }}} */ + +/* {{{ gets the script for the $locale */ +U_CFUNC PHP_FUNCTION( locale_get_script ) +{ + get_icu_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ gets the region for the $locale */ +U_CFUNC PHP_FUNCTION( locale_get_region ) +{ + get_icu_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ gets the primary language for the $locale */ +U_CFUNC PHP_FUNCTION(locale_get_primary_language ) +{ + get_icu_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + + +/* {{{ + * common code shared by display_xyz functions to get the value from ICU + }}} */ +static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_PARAMETERS) +{ + char* loc_name = NULL; + size_t loc_name_len = 0; + + char* disp_loc_name = NULL; + size_t disp_loc_name_len = 0; + int free_loc_name = 0; + + UChar* disp_name = NULL; + int32_t disp_name_len = 0; + + char* mod_loc_name = NULL; + + int32_t buflen = 512; + UErrorCode status = U_ZERO_ERROR; + + zend_string* u8str; + + char* msg = NULL; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_PATH(loc_name, loc_name_len) + Z_PARAM_OPTIONAL + Z_PARAM_PATH_OR_NULL(disp_loc_name, disp_loc_name_len) + ZEND_PARSE_PARAMETERS_END(); + + if(loc_name_len > ULOC_FULLNAME_CAPACITY) { + /* See bug 67397: overlong locale names cause trouble in uloc_getDisplayName */ + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "name too long"); + RETURN_FALSE; + } + + if(loc_name_len == 0) { + loc_name = (char *)intl_locale_get_default(); + } + + if( strcmp(tag_name, DISP_NAME) != 0 ){ + /* Handle grandfathered languages */ + int grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); + if( grOffset >= 0 ){ + if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ + mod_loc_name = getPreferredTag( loc_name ); + } else { + /* Since Grandfathered, no value, do nothing, return NULL */ + RETURN_FALSE; + } + } + } /* end of if != LOC_CANONICAL_TAG */ + + if( mod_loc_name==NULL ){ + mod_loc_name = estrdup( loc_name ); + } + + /* Check if disp_loc_name passed , if not use default locale */ + if( !disp_loc_name){ + disp_loc_name = estrdup(intl_locale_get_default()); + free_loc_name = 1; + } + + /* Get the disp_value for the given locale */ + do{ + disp_name = reinterpret_cast(erealloc( disp_name , buflen * sizeof(UChar) )); + disp_name_len = buflen; + + if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ + buflen = uloc_getDisplayLanguage ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); + } else if( strcmp(tag_name , LOC_SCRIPT_TAG)==0 ){ + buflen = uloc_getDisplayScript ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); + } else if( strcmp(tag_name , LOC_REGION_TAG)==0 ){ + buflen = uloc_getDisplayCountry ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); + } else if( strcmp(tag_name , LOC_VARIANT_TAG)==0 ){ + buflen = uloc_getDisplayVariant ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); + } else if( strcmp(tag_name , DISP_NAME)==0 ){ + buflen = uloc_getDisplayName ( mod_loc_name , disp_loc_name , disp_name , disp_name_len , &status); + } + + /* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */ + if( U_FAILURE( status ) ) + { + if( status == U_BUFFER_OVERFLOW_ERROR ) + { + status = U_ZERO_ERROR; + continue; + } + + spprintf(&msg, 0, "unable to get locale %s", tag_name ); + intl_error_set( NULL, status, msg); + efree(msg); + if( disp_name){ + efree( disp_name ); + } + if( mod_loc_name){ + efree( mod_loc_name ); + } + if (free_loc_name) { + efree((void *)disp_loc_name); + disp_loc_name = NULL; + } + RETURN_FALSE; + } + } while( buflen > disp_name_len ); + + if( mod_loc_name){ + efree( mod_loc_name ); + } + if (free_loc_name) { + efree((void *)disp_loc_name); + disp_loc_name = NULL; + } + /* Convert display locale name from UTF-16 to UTF-8. */ + u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status ); + efree( disp_name ); + if( !u8str ) + { + spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name ); + intl_error_set( NULL, status, msg); + efree(msg); + RETURN_FALSE; + } + + RETVAL_NEW_STR( u8str ); +} +/* }}} */ + +/* {{{ gets the name for the $locale in $in_locale or default_locale */ +U_CFUNC PHP_FUNCTION(locale_get_display_name) +{ + get_icu_disp_value_src_php( DISP_NAME , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ gets the language for the $locale in $in_locale or default_locale */ +U_CFUNC PHP_FUNCTION(locale_get_display_language) +{ + get_icu_disp_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ gets the script for the $locale in $in_locale or default_locale */ +U_CFUNC PHP_FUNCTION(locale_get_display_script) +{ + get_icu_disp_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ gets the region for the $locale in $in_locale or default_locale */ +U_CFUNC PHP_FUNCTION(locale_get_display_region) +{ + get_icu_disp_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ +* proto static string Locale::getDisplayVariant($locale, $in_locale = null) +* gets the variant for the $locale in $in_locale or default_locale + }}} */ +/* {{{ +* proto static string get_display_variant($locale, $in_locale = null) +* gets the variant for the $locale in $in_locale or default_locale +*/ +U_CFUNC PHP_FUNCTION(locale_get_display_variant) +{ + get_icu_disp_value_src_php( LOC_VARIANT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + + /* {{{ return an associative array containing keyword-value + * pairs for this locale. The keys are keys to the array (doh!) + * }}}*/ + /* {{{ return an associative array containing keyword-value + * pairs for this locale. The keys are keys to the array (doh!) + */ +U_CFUNC PHP_FUNCTION( locale_get_keywords ) +{ + UEnumeration* e = NULL; + UErrorCode status = U_ZERO_ERROR; + + const char* kw_key = NULL; + int32_t kw_key_len = 0; + + char* loc_name = NULL; + size_t loc_name_len = 0; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(loc_name, loc_name_len) + ZEND_PARSE_PARAMETERS_END(); + + INTL_CHECK_LOCALE_LEN(loc_name_len); + + if(loc_name_len == 0) { + loc_name = (char *)intl_locale_get_default(); + } + + /* Get the keywords */ + e = uloc_openKeywords( loc_name, &status ); + if( e != NULL ) { + /* + ICU expects the buffer to be allocated before calling the function + and so the buffer size has been explicitly specified + ICU uloc.h #define ULOC_KEYWORD_AND_VALUES_CAPACITY 100 + hence the kw_value buffer size is 100 + */ + + /* Traverse it, filling the return array. */ + array_init( return_value ); + + while( ( kw_key = uenum_next( e, &kw_key_len, &status ) ) != NULL ){ + int32_t kw_value_len = 100; + zend_string *kw_value_str = zend_string_alloc(kw_value_len, 0); + + /* Get the keyword value for each keyword */ + kw_value_len=uloc_getKeywordValue( loc_name, kw_key, ZSTR_VAL(kw_value_str), kw_value_len, &status ); + if (status == U_BUFFER_OVERFLOW_ERROR) { + status = U_ZERO_ERROR; + kw_value_str = zend_string_extend(kw_value_str, kw_value_len, 0); + kw_value_len=uloc_getKeywordValue( loc_name,kw_key, ZSTR_VAL(kw_value_str), kw_value_len+1, &status ); + } else if(!U_FAILURE(status)) { + kw_value_str = zend_string_truncate(kw_value_str, kw_value_len, 0); + } + if (U_FAILURE(status)) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "Error encountered while getting the keyword value for the keyword"); + if( kw_value_str){ + zend_string_efree( kw_value_str ); + } + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_FALSE; + } + + add_assoc_str( return_value, (char *)kw_key, kw_value_str); + } /* end of while */ + + } /* end of if e!=NULL */ + + uenum_close( e ); +} +/* }}} */ + + /* {{{ @return string the canonicalized locale + * }}} */ + /* {{{ @param string $locale The locale string to canonicalize */ +U_CFUNC PHP_FUNCTION(locale_canonicalize) +{ + get_icu_value_src_php( LOC_CANONICALIZE_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); +} +/* }}} */ + +/* {{{ append_key_value +* Internal function which is called from locale_compose +* gets the value for the key_name and appends to the loc_name +* returns 1 if successful , -1 if not found , +* 0 if array element is not a string , -2 if buffer-overflow +*/ +static int append_key_value(smart_str* loc_name, HashTable* hash_arr, const char* key_name) +{ + zval *ele_value; + + if ((ele_value = zend_hash_str_find_deref(hash_arr , key_name, strlen(key_name))) != NULL ) { + if(Z_TYPE_P(ele_value)!= IS_STRING ){ + /* element value is not a string */ + return FAILURE; + } + if(strcmp(key_name, LOC_LANG_TAG) != 0 && + strcmp(key_name, LOC_GRANDFATHERED_LANG_TAG)!=0 ) { + /* not lang or grandfathered tag */ + smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); + } + smart_str_append(loc_name, Z_STR_P(ele_value)); + return SUCCESS; + } + + return LOC_NOT_FOUND; +} +/* }}} */ + +/* {{{ append_prefix , appends the prefix needed +* e.g. private adds 'x' +*/ +static void add_prefix(smart_str* loc_name, const char* key_name) +{ + if( strncmp(key_name , LOC_PRIVATE_TAG , 7) == 0 ){ + smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); + smart_str_appendl(loc_name, PRIVATE_PREFIX , sizeof(PRIVATE_PREFIX)-1); + } +} +/* }}} */ + +/* {{{ append_multiple_key_values +* Internal function which is called from locale_compose +* gets the multiple values for the key_name and appends to the loc_name +* used for 'variant','extlang','private' +* returns 1 if successful , -1 if not found , +* 0 if array element is not a string , -2 if buffer-overflow +*/ +static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, const char* key_name) +{ + zval *ele_value; + int isFirstSubtag = 0; + + /* Variant/ Extlang/Private etc. */ + if ((ele_value = zend_hash_str_find_deref( hash_arr , key_name , strlen(key_name))) != NULL) { + if( Z_TYPE_P(ele_value) == IS_STRING ){ + add_prefix( loc_name , key_name); + + smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); + smart_str_append(loc_name, Z_STR_P(ele_value)); + return SUCCESS; + } else if(Z_TYPE_P(ele_value) == IS_ARRAY ) { + HashTable *arr = Z_ARRVAL_P(ele_value); + zval *data; + + ZEND_HASH_FOREACH_VAL(arr, data) { + ZVAL_DEREF(data); + if(Z_TYPE_P(data) != IS_STRING) { + return FAILURE; + } + if (isFirstSubtag++ == 0){ + add_prefix(loc_name , key_name); + } + smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); + smart_str_append(loc_name, Z_STR_P(data)); + } ZEND_HASH_FOREACH_END(); + return SUCCESS; + } else { + return FAILURE; + } + } else { + char cur_key_name[31]; + int max_value = 0, i; + /* Decide the max_value: the max. no. of elements allowed */ + if( strcmp(key_name , LOC_VARIANT_TAG) ==0 ){ + max_value = MAX_NO_VARIANT; + } + if( strcmp(key_name , LOC_EXTLANG_TAG) ==0 ){ + max_value = MAX_NO_EXTLANG; + } + if( strcmp(key_name , LOC_PRIVATE_TAG) ==0 ){ + max_value = MAX_NO_PRIVATE; + } + + /* Multiple variant values as variant0, variant1 ,variant2 */ + isFirstSubtag = 0; + for( i=0 ; i< max_value; i++ ){ + snprintf( cur_key_name , 30, "%s%d", key_name , i); + if ((ele_value = zend_hash_str_find_deref( hash_arr , cur_key_name , strlen(cur_key_name))) != NULL) { + if( Z_TYPE_P(ele_value)!= IS_STRING ){ + /* variant is not a string */ + return FAILURE; + } + /* Add the contents */ + if (isFirstSubtag++ == 0){ + add_prefix(loc_name , cur_key_name); + } + smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); + smart_str_append(loc_name, Z_STR_P(ele_value)); + } + } /* end of for */ + } /* end of else */ + + return SUCCESS; +} +/* }}} */ + +/*{{{ +* If applicable sets error message and aborts locale_compose gracefully +* returns 0 if locale_compose needs to be aborted +* otherwise returns 1 +*/ +static int handleAppendResult( int result, smart_str* loc_name) +{ + intl_error_reset( NULL ); + if( result == FAILURE) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, + "parameter array element is not a string"); + smart_str_free(loc_name); + return 0; + } + return 1; +} +/* }}} */ + +#define RETURN_SMART_STR(str) smart_str_0((str)); RETURN_NEW_STR((str)->s) +/* {{{ Creates a locale by combining the parts of locale-ID passed +* }}} */ +/* {{{ Creates a locale by combining the parts of locale-ID passed +* }}} */ +U_CFUNC PHP_FUNCTION(locale_compose) +{ + smart_str loc_name_s = {NULL, 0}; + smart_str *loc_name = &loc_name_s; + zval* arr = NULL; + HashTable* hash_arr = NULL; + int result = 0; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY(arr) + ZEND_PARSE_PARAMETERS_END(); + + hash_arr = Z_ARRVAL_P( arr ); + + if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) + RETURN_FALSE; + + /* Check for grandfathered first */ + result = append_key_value(loc_name, hash_arr, LOC_GRANDFATHERED_LANG_TAG); + if( result == SUCCESS){ + RETURN_SMART_STR(loc_name); + } + if( !handleAppendResult( result, loc_name)){ + RETURN_FALSE; + } + + /* Not grandfathered */ + result = append_key_value(loc_name, hash_arr , LOC_LANG_TAG); + if( result == LOC_NOT_FOUND ){ + zend_argument_value_error(1, "must contain a \"%s\" key", LOC_LANG_TAG); + smart_str_free(loc_name); + RETURN_THROWS(); + } + if( !handleAppendResult( result, loc_name)){ + RETURN_FALSE; + } + + /* Extlang */ + result = append_multiple_key_values(loc_name, hash_arr , LOC_EXTLANG_TAG); + if( !handleAppendResult( result, loc_name)){ + RETURN_FALSE; + } + + /* Script */ + result = append_key_value(loc_name, hash_arr , LOC_SCRIPT_TAG); + if( !handleAppendResult( result, loc_name)){ + RETURN_FALSE; + } + + /* Region */ + result = append_key_value( loc_name, hash_arr , LOC_REGION_TAG); + if( !handleAppendResult( result, loc_name)){ + RETURN_FALSE; + } + + /* Variant */ + result = append_multiple_key_values( loc_name, hash_arr , LOC_VARIANT_TAG); + if( !handleAppendResult( result, loc_name)){ + RETURN_FALSE; + } + + /* Private */ + result = append_multiple_key_values( loc_name, hash_arr , LOC_PRIVATE_TAG); + if( !handleAppendResult( result, loc_name)){ + RETURN_FALSE; + } + + RETURN_SMART_STR(loc_name); +} +/* }}} */ + + +/*{{{ +* Parses the locale and returns private subtags if existing +* else returns NULL +* e.g. for locale='en_US-x-prv1-prv2-prv3' +* returns a pointer to the string 'prv1-prv2-prv3' +*/ +static zend_string* get_private_subtags(const char* loc_name) +{ + zend_string* result = NULL; + size_t len = 0; + const char* mod_loc_name =NULL; + + if( loc_name && (len = strlen(loc_name)) > 0 ){ + zend_off_t singletonPos = 0; + mod_loc_name = loc_name ; + while( (singletonPos = getSingletonPos(mod_loc_name)) > -1){ + if( (*(mod_loc_name+singletonPos)=='x') || (*(mod_loc_name+singletonPos)=='X') ){ + /* private subtag start found */ + if( singletonPos + 2 == len){ + /* loc_name ends with '-x-' ; return NULL */ + } + else{ + /* result = mod_loc_name + singletonPos +2; */ + result = zend_string_init(mod_loc_name + singletonPos+2 , (len -( singletonPos +2) ), 0); + } + break; + } + else{ + if((size_t)(singletonPos + 1) >= len){ + /* String end */ + break; + } else { + /* singleton found but not a private subtag , hence check further in the string for the private subtag */ + mod_loc_name = mod_loc_name + singletonPos +1; + len = strlen(mod_loc_name); + } + } + } /* end of while */ + } + + return result; +} +/* }}} */ + +/* {{{ code used by locale_parse */ +static int add_array_entry(const char* loc_name, zval* hash_arr, const char* key_name) +{ + zend_string* key_value = NULL; + char* cur_key_name = NULL; + char* token = NULL; + char* last_ptr = NULL; + + int result = 0; + int cur_result = 0; + + + if( strcmp(key_name , LOC_PRIVATE_TAG)==0 ){ + key_value = get_private_subtags( loc_name ); + result = 1; + } else { + key_value = get_icu_value_internal( loc_name , key_name , &result,1 ); + } + if( (strcmp(key_name , LOC_PRIVATE_TAG)==0) || + ( strcmp(key_name , LOC_VARIANT_TAG)==0) ){ + if( result > 0 && key_value){ + int cnt = 0; + /* Tokenize on the "_" or "-" */ + token = php_strtok_r( key_value->val , DELIMITER ,&last_ptr); + if( cur_key_name ){ + efree( cur_key_name); + } + /* Over-allocates a few bytes for the integer so we don't have to reallocate. */ + size_t cur_key_name_size = (sizeof("-2147483648") - 1) + strlen(key_name) + 1; + cur_key_name = reinterpret_cast(emalloc(cur_key_name_size)); + snprintf( cur_key_name, cur_key_name_size , "%s%d", key_name , cnt++); + add_assoc_string( hash_arr, cur_key_name , token); + /* tokenize on the "_" or "-" and stop at singleton if any */ + while( (token = php_strtok_r(NULL , DELIMITER , &last_ptr)) && (strlen(token)>1) ){ + snprintf( cur_key_name , cur_key_name_size, "%s%d", key_name , cnt++); + add_assoc_string( hash_arr, cur_key_name , token); + } +/* + if( strcmp(key_name, LOC_PRIVATE_TAG) == 0 ){ + } +*/ + } + if (key_value) { + zend_string_release_ex(key_value, 0); + } + } else { + if( result == 1 ){ + add_assoc_str( hash_arr, key_name , key_value); + cur_result = 1; + } else if (key_value) { + zend_string_release_ex(key_value, 0); + } + } + + if( cur_key_name ){ + efree( cur_key_name); + } + /*if( key_name != LOC_PRIVATE_TAG && key_value){*/ + return cur_result; +} +/* }}} */ + +/* {{{ parses a locale-id into an array the different parts of it */ +U_CFUNC PHP_FUNCTION(locale_parse) +{ + char* loc_name = NULL; + size_t loc_name_len = 0; + int grOffset = 0; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(loc_name, loc_name_len) + ZEND_PARSE_PARAMETERS_END(); + + INTL_CHECK_LOCALE_LEN(loc_name_len); + + if(loc_name_len == 0) { + loc_name = (char *)intl_locale_get_default(); + } + + array_init( return_value ); + + grOffset = findOffset( LOC_GRANDFATHERED , loc_name ); + if( grOffset >= 0 ){ + add_assoc_string( return_value , LOC_GRANDFATHERED_LANG_TAG, (char *)loc_name); + } + else{ + /* Not grandfathered */ + add_array_entry( loc_name , return_value , LOC_LANG_TAG); + add_array_entry( loc_name , return_value , LOC_SCRIPT_TAG); + add_array_entry( loc_name , return_value , LOC_REGION_TAG); + add_array_entry( loc_name , return_value , LOC_VARIANT_TAG); + add_array_entry( loc_name , return_value , LOC_PRIVATE_TAG); + } +} +/* }}} */ + +/* {{{ gets an array containing the list of variants, or null */ +U_CFUNC PHP_FUNCTION(locale_get_all_variants) +{ + char* loc_name = NULL; + size_t loc_name_len = 0; + + int result = 0; + char* token = NULL; + zend_string* variant = NULL; + char* saved_ptr = NULL; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(loc_name, loc_name_len) + ZEND_PARSE_PARAMETERS_END(); + + if(loc_name_len == 0) { + loc_name = (char *)intl_locale_get_default(); + loc_name_len = strlen(loc_name); + } + + INTL_CHECK_LOCALE_LEN(loc_name_len); + + array_init( return_value ); + + /* If the locale is grandfathered, stop, no variants */ + if( findOffset( LOC_GRANDFATHERED , loc_name ) >= 0 ){ + /* ("Grandfathered Tag. No variants."); */ + } + else { + /* Call ICU variant */ + variant = get_icu_value_internal( loc_name , LOC_VARIANT_TAG , &result ,0); + if( result > 0 && variant){ + /* Tokenize on the "_" or "-" */ + token = php_strtok_r( variant->val , DELIMITER , &saved_ptr); + add_next_index_stringl( return_value, token , strlen(token)); + /* tokenize on the "_" or "-" and stop at singleton if any */ + while( (token = php_strtok_r(NULL , DELIMITER, &saved_ptr)) && (strlen(token)>1) ){ + add_next_index_stringl( return_value, token , strlen(token)); + } + } + if( variant ){ + zend_string_release_ex( variant, 0 ); + } + } + + +} +/* }}} */ + +/* {{{ Converts to lower case and also replaces all hyphens with the underscore */ +static int strToMatch(const char* str ,char *retstr) +{ + char* anchor = NULL; + const char* anchor1 = NULL; + int result = 0; + + if( (!str) || str[0] == '\0'){ + return result; + } else { + anchor = retstr; + anchor1 = str; + while( (*str)!='\0' ){ + if( *str == '-' ){ + *retstr = '_'; + } else { + *retstr = tolower((unsigned char)*str); + } + str++; + retstr++; + } + *retstr = '\0'; + retstr= anchor; + str= anchor1; + result = 1; + } + + return(result); +} +/* }}} */ + +/* {{{ Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ +/* }}} */ +/* {{{ Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ +U_CFUNC PHP_FUNCTION(locale_filter_matches) +{ + char* lang_tag = NULL; + size_t lang_tag_len = 0; + char* loc_range = NULL; + size_t loc_range_len = 0; + + int result = 0; + char* token = 0; + char* chrcheck = NULL; + + zend_string* can_lang_tag = NULL; + zend_string* can_loc_range = NULL; + + char* cur_lang_tag = NULL; + char* cur_loc_range = NULL; + + bool boolCanonical = 0; + UErrorCode status = U_ZERO_ERROR; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_PATH(lang_tag, lang_tag_len) + Z_PARAM_PATH(loc_range, loc_range_len) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(boolCanonical) + ZEND_PARSE_PARAMETERS_END(); + + if(loc_range_len == 0) { + loc_range = (char *)intl_locale_get_default(); + loc_range_len = strlen(loc_range); + } + + if( strcmp(loc_range,"*")==0){ + RETURN_TRUE; + } + + INTL_CHECK_LOCALE_LEN(loc_range_len); + INTL_CHECK_LOCALE_LEN(lang_tag_len); + + if( boolCanonical ){ + /* canonicalize loc_range */ + can_loc_range=get_icu_value_internal( loc_range , LOC_CANONICALIZE_TAG , &result , 0); + if( result <=0) { + intl_error_set(NULL, status, "unable to canonicalize loc_range"); + RETURN_FALSE; + } + + /* canonicalize lang_tag */ + can_lang_tag = get_icu_value_internal( lang_tag , LOC_CANONICALIZE_TAG , &result , 0); + if( result <=0) { + zend_string_release_ex( can_loc_range, false ); + intl_error_set(NULL, status, "unable to canonicalize lang_tag"); + RETURN_FALSE; + } + + /* Convert to lower case for case-insensitive comparison */ + cur_lang_tag = reinterpret_cast(ecalloc( 1, can_lang_tag->len + 1)); + + /* Convert to lower case for case-insensitive comparison */ + result = strToMatch( can_lang_tag->val , cur_lang_tag); + if( result == 0) { + efree( cur_lang_tag ); + zend_string_release_ex( can_lang_tag, 0 ); + RETURN_FALSE; + } + + cur_loc_range = reinterpret_cast(ecalloc( 1, can_loc_range->len + 1)); + result = strToMatch( can_loc_range->val , cur_loc_range ); + if( result == 0) { + efree( cur_lang_tag ); + zend_string_release_ex( can_lang_tag, 0 ); + efree( cur_loc_range ); + zend_string_release_ex( can_loc_range, 0 ); + RETURN_FALSE; + } + + /* check if prefix */ + token = strstr( cur_lang_tag , cur_loc_range ); + + if( token && (token==cur_lang_tag) ){ + /* check if the char. after match is SEPARATOR */ + chrcheck = token + can_loc_range->len; + if( isIDSeparator(*chrcheck) || isKeywordSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ + efree( cur_lang_tag ); + efree( cur_loc_range ); + if( can_lang_tag){ + zend_string_release_ex( can_lang_tag, 0 ); + } + if( can_loc_range){ + zend_string_release_ex( can_loc_range, 0 ); + } + RETURN_TRUE; + } + } + + /* No prefix as loc_range */ + if( cur_lang_tag){ + efree( cur_lang_tag ); + } + if( cur_loc_range){ + efree( cur_loc_range ); + } + if( can_lang_tag){ + zend_string_release_ex( can_lang_tag, 0 ); + } + if( can_loc_range){ + zend_string_release_ex( can_loc_range, 0 ); + } + RETURN_FALSE; + + } /* end of if isCanonical */ + else{ + /* Convert to lower case for case-insensitive comparison */ + cur_lang_tag = reinterpret_cast(ecalloc(1, lang_tag_len + 1)); + + result = strToMatch( lang_tag , cur_lang_tag); + if( result == 0) { + efree( cur_lang_tag ); + RETURN_FALSE; + } + cur_loc_range = reinterpret_cast(ecalloc(1, loc_range_len + 1)); + result = strToMatch( loc_range , cur_loc_range ); + if( result == 0) { + efree( cur_lang_tag ); + efree( cur_loc_range ); + RETURN_FALSE; + } + + /* check if prefix */ + token = strstr( cur_lang_tag , cur_loc_range ); + + if( token && (token==cur_lang_tag) ){ + /* check if the char. after match is SEPARATOR */ + chrcheck = token + loc_range_len; + if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ + efree( cur_lang_tag ); + efree( cur_loc_range ); + RETURN_TRUE; + } + } + + /* No prefix as loc_range */ + if( cur_lang_tag){ + efree( cur_lang_tag ); + } + if( cur_loc_range){ + efree( cur_loc_range ); + } + RETURN_FALSE; + + } +} +/* }}} */ + +static void array_cleanup( char* arr[] , int arr_size) +{ + int i=0; + for( i=0; i< arr_size; i++ ){ + if( arr[i*2] ){ + efree( arr[i*2]); + } + } + efree(arr); +} + +#define LOOKUP_CLEAN_RETURN(value) array_cleanup(cur_arr, cur_arr_len); return (value) +/* {{{ +* returns the lookup result to lookup_loc_range_src_php +* internal function +*/ +static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int canonicalize ) +{ + int i = 0; + int cur_arr_len = 0; + int result = 0; + + zend_string* lang_tag = NULL; + zval* ele_value = NULL; + + char* cur_loc_range = NULL; + zend_string* can_loc_range = NULL; + zend_off_t saved_pos = 0; + + zend_string* return_value = NULL; + + char **cur_arr = reinterpret_cast(ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *))); + ZEND_HASH_FOREACH_VAL(hash_arr, ele_value) { + ZVAL_DEREF(ele_value); + /* convert the array to lowercase , also replace hyphens with the underscore and store it in cur_arr */ + if(Z_TYPE_P(ele_value)!= IS_STRING) { + /* element value is not a string */ + zend_argument_type_error(2, "must only contain string values"); + LOOKUP_CLEAN_RETURN(NULL); + } + if (zend_str_has_nul_byte(Z_STR_P(ele_value))) { + zend_argument_value_error(2, "must not contain any null bytes"); + LOOKUP_CLEAN_RETURN(NULL); + } + cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); + result = strToMatch(Z_STRVAL_P(ele_value), cur_arr[cur_arr_len*2]); + if(result == 0) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); + LOOKUP_CLEAN_RETURN(NULL); + } + cur_arr[cur_arr_len*2+1] = Z_STRVAL_P(ele_value); + cur_arr_len++ ; + } ZEND_HASH_FOREACH_END(); /* end of for */ + + /* Canonicalize array elements */ + if(canonicalize) { + for(i=0; ival[0]) { + if(lang_tag) { + zend_string_release_ex(lang_tag, 0); + } + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); + LOOKUP_CLEAN_RETURN(NULL); + } + cur_arr[i*2] = reinterpret_cast(erealloc(cur_arr[i*2], lang_tag->len+1)); + result = strToMatch(lang_tag->val, cur_arr[i*2]); + zend_string_release_ex(lang_tag, 0); + if(result == 0) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); + LOOKUP_CLEAN_RETURN(NULL); + } + } + + } + + if(canonicalize) { + /* Canonicalize the loc_range */ + can_loc_range = get_icu_value_internal(loc_range, LOC_CANONICALIZE_TAG, &result , 0); + if( result != 1 || can_loc_range == NULL || !can_loc_range->val[0]) { + /* Error */ + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize loc_range"); + if(can_loc_range) { + zend_string_release_ex(can_loc_range, 0); + } + LOOKUP_CLEAN_RETURN(NULL); + } else { + loc_range = can_loc_range->val; + } + } + + cur_loc_range = reinterpret_cast(ecalloc(1, strlen(loc_range)+1)); + /* convert to lower and replace hyphens */ + result = strToMatch(loc_range, cur_loc_range); + if(can_loc_range) { + zend_string_release_ex(can_loc_range, 0); + } + if(result == 0) { + efree(cur_loc_range); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "unable to canonicalize lang_tag"); + LOOKUP_CLEAN_RETURN(NULL); + } + + /* Lookup for the lang_tag match */ + saved_pos = strlen(cur_loc_range); + while(saved_pos > 0) { + for(i=0; i< cur_arr_len; i++){ + if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) { + /* Match found */ + char *str = canonicalize ? cur_arr[i*2] : cur_arr[i*2+1]; + return_value = zend_string_init(str, strlen(str), 0); + efree(cur_loc_range); + LOOKUP_CLEAN_RETURN(return_value); + } + } + saved_pos = getStrrtokenPos(cur_loc_range, saved_pos); + } + + /* Match not found */ + efree(cur_loc_range); + LOOKUP_CLEAN_RETURN(NULL); +} +/* }}} */ + +/* {{{ Searches the items in $langtag for the best match to the language +* range +*/ +/* }}} */ +/* {{{ Searches the items in $langtag for the best match to the language +* range +*/ +U_CFUNC PHP_FUNCTION(locale_lookup) +{ + zend_string* fallback_loc_str = NULL; + char* loc_range = NULL; + size_t loc_range_len = 0; + + zval* arr = NULL; + HashTable* hash_arr = NULL; + bool boolCanonical = 0; + zend_string* result_str = NULL; + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_ARRAY(arr) + Z_PARAM_PATH(loc_range, loc_range_len) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(boolCanonical) + Z_PARAM_PATH_STR_OR_NULL(fallback_loc_str) + ZEND_PARSE_PARAMETERS_END(); + + if(loc_range_len == 0) { + if(fallback_loc_str) { + loc_range = ZSTR_VAL(fallback_loc_str); + loc_range_len = ZSTR_LEN(fallback_loc_str); + } else { + loc_range = (char *)intl_locale_get_default(); + loc_range_len = strlen(loc_range); + } + } + + hash_arr = Z_ARRVAL_P(arr); + + INTL_CHECK_LOCALE_LEN(loc_range_len); + + if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) { + RETURN_EMPTY_STRING(); + } + + result_str = lookup_loc_range(loc_range, hash_arr, boolCanonical); + if(result_str == NULL || ZSTR_VAL(result_str)[0] == '\0') { + if( fallback_loc_str ) { + result_str = zend_string_copy(fallback_loc_str); + } else { + RETURN_EMPTY_STRING(); + } + } + + RETURN_STR(result_str); +} +/* }}} */ + +/* {{{ Tries to find out best available locale based on HTTP "Accept-Language" header */ +U_CFUNC PHP_FUNCTION(locale_accept_from_http) +{ + UEnumeration *available; + char *http_accept = NULL; + size_t http_accept_len; + UErrorCode status = U_ZERO_ERROR; + int len; + char resultLocale[INTL_MAX_LOCALE_LEN+1]; + UAcceptResult outResult; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(http_accept, http_accept_len) + ZEND_PARSE_PARAMETERS_END(); + if(http_accept_len > ULOC_FULLNAME_CAPACITY) { + /* check each fragment, if any bigger than capacity, can't do it due to bug #72533 */ + char *start = http_accept; + char *end; + size_t len; + do { + end = strchr(start, ','); + len = end ? end-start : http_accept_len-(start-http_accept); + if(len > ULOC_FULLNAME_CAPACITY) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, + "locale string too long"); + RETURN_FALSE; + } + if(end) { + start = end+1; + } + } while(end != NULL); + } + + available = ures_openAvailableLocales(NULL, &status); + INTL_CHECK_STATUS(status, "failed to retrieve locale list"); + len = uloc_acceptLanguageFromHTTP(resultLocale, INTL_MAX_LOCALE_LEN, + &outResult, http_accept, available, &status); + uenum_close(available); + INTL_CHECK_STATUS(status, "failed to find acceptable locale"); + if (len < 0 || outResult == ULOC_ACCEPT_FAILED) { + RETURN_FALSE; + } + RETURN_STRINGL(resultLocale, len); +} +/* }}} */ + +U_CFUNC PHP_FUNCTION(locale_is_right_to_left) +{ + char *locale; + size_t locale_len; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if (!locale_len) { + locale = (char *)intl_locale_get_default(); + } + + RETURN_BOOL(uloc_isRightToLeft(locale)); +} + +U_CFUNC PHP_FUNCTION(locale_add_likely_subtags) +{ + char *locale, maximized_locale[ULOC_FULLNAME_CAPACITY]; + UErrorCode status = U_ZERO_ERROR; + size_t locale_len; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if (!locale_len) { + locale = (char *)intl_locale_get_default(); + } + + int32_t maximized_locale_len = uloc_addLikelySubtags(locale, maximized_locale, sizeof(maximized_locale), &status); + INTL_CHECK_STATUS(status, "invalid locale"); + if (maximized_locale_len < 0) { + RETURN_FALSE; + } + + RETURN_STRINGL(maximized_locale, maximized_locale_len); +} + +U_CFUNC PHP_FUNCTION(locale_minimize_subtags) +{ + char *locale, minimized_locale[ULOC_FULLNAME_CAPACITY]; + UErrorCode status = U_ZERO_ERROR; + size_t locale_len; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(locale, locale_len) + ZEND_PARSE_PARAMETERS_END(); + + if (!locale_len) { + locale = (char *)intl_locale_get_default(); + } + + int32_t minimized_locale_len = uloc_minimizeSubtags(locale, minimized_locale, sizeof(minimized_locale), &status); + INTL_CHECK_STATUS(status, "invalid locale"); + if (minimized_locale_len < 0) { + RETURN_FALSE; + } + + RETURN_STRINGL(minimized_locale, minimized_locale_len); +} diff --git a/ext/intl/msgformat/msgformat.c b/ext/intl/msgformat/msgformat.c deleted file mode 100644 index 51643d86d458..000000000000 --- a/ext/intl/msgformat/msgformat.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "php_intl.h" -#include "msgformat_class.h" -#include "msgformat_data.h" -#include "intl_convert.h" - -/* {{{ */ -static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) -{ - char* locale; - char* pattern; - size_t locale_len = 0, pattern_len = 0; - UChar* spattern = NULL; - int spattern_len = 0; - zval* object; - MessageFormatter_object* mfo; - UParseError parse_error; - intl_error_reset( NULL ); - - object = return_value; - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STRING(locale, locale_len) - Z_PARAM_STRING(pattern, pattern_len) - ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - } - - INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); - MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; - - /* Convert pattern (if specified) to UTF-16. */ - if(pattern && pattern_len) { - intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); - INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: error converting pattern to UTF-16"); - } else { - spattern_len = 0; - spattern = NULL; - } - - if(locale_len == 0) { - locale = (char *)intl_locale_get_default(); - } - -#ifdef MSG_FORMAT_QUOTE_APOS - if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { - INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: error converting pattern to quote-friendly format"); - } -#endif - - if ((mfo)->mf_data.orig_format) { - msgformat_data_free(&mfo->mf_data); - } - - (mfo)->mf_data.orig_format = estrndup(pattern, pattern_len); - (mfo)->mf_data.orig_format_len = pattern_len; - - /* Create an ICU message formatter. */ - MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, locale, &parse_error, &INTL_DATA_ERROR_CODE(mfo)); - - if(spattern) { - efree(spattern); - } - - if (INTL_DATA_ERROR_CODE( mfo ) == U_PATTERN_SYNTAX_ERROR) { - char *msg = NULL; - smart_str parse_error_str; - parse_error_str = intl_parse_error_to_string( &parse_error ); - spprintf( &msg, 0, "pattern syntax error (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "unknown parser error" ); - smart_str_free( &parse_error_str ); - - intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) ); - intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg, 1 ); - - efree( msg ); - return FAILURE; - } - - INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: message formatter creation failed"); - return SUCCESS; -} -/* }}} */ - -/* {{{ Create formatter. */ -PHP_FUNCTION( msgfmt_create ) -{ - object_init_ex( return_value, MessageFormatter_ce_ptr ); - if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { - zval_ptr_dtor(return_value); - RETURN_NULL(); - } -} -/* }}} */ - -/* {{{ MessageFormatter object constructor. */ -PHP_METHOD( MessageFormatter, __construct ) -{ - zend_error_handling error_handling; - bool error_handling_replaced = 0; - - return_value = ZEND_THIS; - if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { - if (!EG(exception)) { - zend_string *err = intl_error_get_message(NULL); - zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL)); - zend_string_release_ex(err, 0); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); - } -} -/* }}} */ - -/* {{{ Get formatter's last error code. */ -PHP_FUNCTION( msgfmt_get_error_code ) -{ - zval* object = NULL; - MessageFormatter_object* mfo = NULL; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, MessageFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - mfo = Z_INTL_MESSAGEFORMATTER_P( object ); - - /* Return formatter's last error code. */ - RETURN_LONG( INTL_DATA_ERROR_CODE(mfo) ); -} -/* }}} */ - -/* {{{ Get text description for formatter's last error code. */ -PHP_FUNCTION( msgfmt_get_error_message ) -{ - zend_string* message = NULL; - zval* object = NULL; - MessageFormatter_object* mfo = NULL; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, MessageFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - mfo = Z_INTL_MESSAGEFORMATTER_P( object ); - - /* Return last error message. */ - message = intl_error_get_message( &mfo->mf_data.error ); - RETURN_STR(message); -} -/* }}} */ diff --git a/ext/intl/msgformat/msgformat.cpp b/ext/intl/msgformat/msgformat.cpp new file mode 100644 index 000000000000..3857e97b4a4a --- /dev/null +++ b/ext/intl/msgformat/msgformat.cpp @@ -0,0 +1,171 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +extern "C" { +#include "php_intl.h" +#include "msgformat_class.h" +#include "msgformat_data.h" +#include "intl_convert.h" +} + +/* {{{ */ +static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +{ + char* locale; + char* pattern; + size_t locale_len = 0, pattern_len = 0; + UChar* spattern = NULL; + int spattern_len = 0; + zval* object; + MessageFormatter_object* mfo; + UParseError parse_error; + intl_error_reset( NULL ); + + object = return_value; + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STRING(locale, locale_len) + Z_PARAM_STRING(pattern, pattern_len) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); + MSG_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; + + /* Convert pattern (if specified) to UTF-16. */ + if(pattern && pattern_len) { + intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); + INTL_CTOR_CHECK_STATUS(mfo, "error converting pattern to UTF-16"); + } else { + spattern_len = 0; + spattern = NULL; + } + + if(locale_len == 0) { + locale = (char *)intl_locale_get_default(); + } + +#ifdef MSG_FORMAT_QUOTE_APOS + if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { + INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: error converting pattern to quote-friendly format"); + } +#endif + + if ((mfo)->mf_data.orig_format) { + msgformat_data_free(&mfo->mf_data); + } + + (mfo)->mf_data.orig_format = estrndup(pattern, pattern_len); + (mfo)->mf_data.orig_format_len = pattern_len; + + /* Create an ICU message formatter. */ + MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, locale, &parse_error, &INTL_DATA_ERROR_CODE(mfo)); + + if(spattern) { + efree(spattern); + } + + if (INTL_DATA_ERROR_CODE( mfo ) == U_PATTERN_SYNTAX_ERROR) { + char *msg = NULL; + smart_str parse_error_str; + parse_error_str = intl_parse_error_to_string( &parse_error ); + spprintf( &msg, 0, "pattern syntax error (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "unknown parser error" ); + smart_str_free( &parse_error_str ); + + intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) ); + intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg); + + efree( msg ); + return FAILURE; + } + + INTL_CTOR_CHECK_STATUS(mfo, "message formatter creation failed"); + return SUCCESS; +} +/* }}} */ + +/* {{{ Create formatter. */ +U_CFUNC PHP_FUNCTION( msgfmt_create ) +{ + object_init_ex( return_value, MessageFormatter_ce_ptr ); + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + zval_ptr_dtor(return_value); + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ MessageFormatter object constructor. */ +U_CFUNC PHP_METHOD( MessageFormatter, __construct ) +{ + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + + return_value = ZEND_THIS; + if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); + } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; +} +/* }}} */ + +/* {{{ Get formatter's last error code. */ +U_CFUNC PHP_FUNCTION( msgfmt_get_error_code ) +{ + zval* object = NULL; + MessageFormatter_object* mfo = NULL; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, MessageFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + mfo = Z_INTL_MESSAGEFORMATTER_P( object ); + + /* Return formatter's last error code. */ + RETURN_LONG( INTL_DATA_ERROR_CODE(mfo) ); +} +/* }}} */ + +/* {{{ Get text description for formatter's last error code. */ +U_CFUNC PHP_FUNCTION( msgfmt_get_error_message ) +{ + zend_string* message = NULL; + zval* object = NULL; + MessageFormatter_object* mfo = NULL; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, MessageFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + mfo = Z_INTL_MESSAGEFORMATTER_P( object ); + + /* Return last error message. */ + message = intl_error_get_message( &mfo->mf_data.error ); + RETURN_STR(message); +} +/* }}} */ diff --git a/ext/intl/msgformat/msgformat_arginfo.h b/ext/intl/msgformat/msgformat_arginfo.h index 74353fbf93ae..6f59b06059d7 100644 --- a/ext/intl/msgformat/msgformat_arginfo.h +++ b/ext/intl/msgformat/msgformat_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit msgformat.stub.php instead. * Stub hash: d595f5c582996ebb96ab39df8cb56c4cf6c8dfcf */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_MessageFormatter___construct, 0, 0, 2) diff --git a/ext/intl/msgformat/msgformat_attr.c b/ext/intl/msgformat/msgformat_attr.c deleted file mode 100644 index b56bf360d114..000000000000 --- a/ext/intl/msgformat/msgformat_attr.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "msgformat_class.h" -#include "msgformat_data.h" -#include "intl_convert.h" - -#include - -/* {{{ Get formatter pattern. */ -PHP_FUNCTION( msgfmt_get_pattern ) -{ - MSG_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, MessageFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - MSG_FORMAT_METHOD_FETCH_OBJECT; - - if(mfo->mf_data.orig_format) { - RETURN_STRINGL(mfo->mf_data.orig_format, mfo->mf_data.orig_format_len); - } - - RETURN_FALSE; -} -/* }}} */ - -/* {{{ Set formatter pattern. */ -PHP_FUNCTION( msgfmt_set_pattern ) -{ - char* value = NULL; - size_t value_len = 0; - int32_t spattern_len = 0; - UChar* spattern = NULL; - UParseError spattern_error = {0}; - MSG_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", - &object, MessageFormatter_ce_ptr, &value, &value_len ) == FAILURE ) - { - RETURN_THROWS(); - } - - MSG_FORMAT_METHOD_FETCH_OBJECT; - - /* Convert given pattern to UTF-16. */ - intl_convert_utf8_to_utf16(&spattern, &spattern_len, value, value_len, &INTL_DATA_ERROR_CODE(mfo)); - INTL_METHOD_CHECK_STATUS(mfo, "Error converting pattern to UTF-16" ); - -#ifdef MSG_FORMAT_QUOTE_APOS - if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { - intl_error_set( NULL, U_INVALID_FORMAT_ERROR, - "msgfmt_set_pattern: error converting pattern to quote-friendly format", 0 ); - RETURN_FALSE; - } -#endif - - umsg_applyPattern(MSG_FORMAT_OBJECT(mfo), spattern, spattern_len, &spattern_error, &INTL_DATA_ERROR_CODE(mfo)); - if (spattern) { - efree(spattern); - } - if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { - char *msg; - spprintf(&msg, 0, "Error setting symbol value at line %d, offset %d", spattern_error.line, spattern_error.offset); - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(mfo), msg, 1); - efree(msg); - RETURN_FALSE; - } - - if(mfo->mf_data.orig_format) { - efree(mfo->mf_data.orig_format); - } - mfo->mf_data.orig_format = estrndup(value, value_len); - mfo->mf_data.orig_format_len = value_len; - /* invalidate cached format types */ - if (mfo->mf_data.arg_types) { - zend_hash_destroy(mfo->mf_data.arg_types); - efree(mfo->mf_data.arg_types); - mfo->mf_data.arg_types = NULL; - } - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Get formatter locale. */ -PHP_FUNCTION( msgfmt_get_locale ) -{ - char *loc; - MSG_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, MessageFormatter_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - MSG_FORMAT_METHOD_FETCH_OBJECT; - - loc = (char *)umsg_getLocale(MSG_FORMAT_OBJECT(mfo)); - RETURN_STRING(loc); -} -/* }}} */ diff --git a/ext/intl/msgformat/msgformat_attr.cpp b/ext/intl/msgformat/msgformat_attr.cpp new file mode 100644 index 000000000000..15c3525b858f --- /dev/null +++ b/ext/intl/msgformat/msgformat_attr.cpp @@ -0,0 +1,128 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "msgformat_class.h" +#include "msgformat_data.h" +#include "intl_convert.h" +} + +#include + +/* {{{ Get formatter pattern. */ +U_CFUNC PHP_FUNCTION( msgfmt_get_pattern ) +{ + MSG_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, MessageFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + MSG_FORMAT_METHOD_FETCH_OBJECT; + + if(mfo->mf_data.orig_format) { + RETURN_STRINGL(mfo->mf_data.orig_format, mfo->mf_data.orig_format_len); + } + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ Set formatter pattern. */ +U_CFUNC PHP_FUNCTION( msgfmt_set_pattern ) +{ + char* value = NULL; + size_t value_len = 0; + int32_t spattern_len = 0; + UChar* spattern = NULL; + UParseError spattern_error = {0}; + MSG_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os", + &object, MessageFormatter_ce_ptr, &value, &value_len ) == FAILURE ) + { + RETURN_THROWS(); + } + + MSG_FORMAT_METHOD_FETCH_OBJECT; + + /* Convert given pattern to UTF-16. */ + intl_convert_utf8_to_utf16(&spattern, &spattern_len, value, value_len, &INTL_DATA_ERROR_CODE(mfo)); + INTL_METHOD_CHECK_STATUS(mfo, "Error converting pattern to UTF-16" ); + +#ifdef MSG_FORMAT_QUOTE_APOS + if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { + intl_error_set( NULL, U_INVALID_FORMAT_ERROR, + "msgfmt_set_pattern: error converting pattern to quote-friendly format", 0 ); + RETURN_FALSE; + } +#endif + + umsg_applyPattern(MSG_FORMAT_OBJECT(mfo), spattern, spattern_len, &spattern_error, &INTL_DATA_ERROR_CODE(mfo)); + if (spattern) { + efree(spattern); + } + if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { + char *msg; + spprintf(&msg, 0, "Error setting symbol value at line %d, offset %d", spattern_error.line, spattern_error.offset); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(mfo), msg); + efree(msg); + RETURN_FALSE; + } + + if(mfo->mf_data.orig_format) { + efree(mfo->mf_data.orig_format); + } + mfo->mf_data.orig_format = estrndup(value, value_len); + mfo->mf_data.orig_format_len = value_len; + /* invalidate cached format types */ + if (mfo->mf_data.arg_types) { + zend_hash_destroy(mfo->mf_data.arg_types); + efree(mfo->mf_data.arg_types); + mfo->mf_data.arg_types = NULL; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ Get formatter locale. */ +U_CFUNC PHP_FUNCTION( msgfmt_get_locale ) +{ + char *loc; + MSG_FORMAT_METHOD_INIT_VARS; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, MessageFormatter_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + MSG_FORMAT_METHOD_FETCH_OBJECT; + + loc = (char *)umsg_getLocale(MSG_FORMAT_OBJECT(mfo)); + RETURN_STRING(loc); +} +/* }}} */ diff --git a/ext/intl/msgformat/msgformat_class.c b/ext/intl/msgformat/msgformat_class.c deleted file mode 100644 index 4e0766a911b9..000000000000 --- a/ext/intl/msgformat/msgformat_class.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#include - -#include "msgformat_class.h" -#include "php_intl.h" -#include "msgformat_data.h" -#include "msgformat_arginfo.h" - -#include - -zend_class_entry *MessageFormatter_ce_ptr = NULL; -static zend_object_handlers MessageFormatter_handlers; - -/* - * Auxiliary functions needed by objects of 'MessageFormatter' class - */ - -/* {{{ MessageFormatter_objects_free */ -void MessageFormatter_object_free( zend_object *object ) -{ - MessageFormatter_object* mfo = php_intl_messageformatter_fetch_object(object); - - zend_object_std_dtor( &mfo->zo ); - - msgformat_data_free( &mfo->mf_data ); -} -/* }}} */ - -/* {{{ MessageFormatter_object_create */ -zend_object *MessageFormatter_object_create(zend_class_entry *ce) -{ - MessageFormatter_object* intern; - - intern = zend_object_alloc(sizeof(MessageFormatter_object), ce); - msgformat_data_init( &intern->mf_data ); - zend_object_std_init( &intern->zo, ce ); - object_properties_init(&intern->zo, ce); - - return &intern->zo; -} -/* }}} */ - -/* {{{ MessageFormatter_object_clone */ -zend_object *MessageFormatter_object_clone(zend_object *object) -{ - MessageFormatter_object *mfo = php_intl_messageformatter_fetch_object(object); - zend_object *new_obj = MessageFormatter_ce_ptr->create_object(object->ce); - MessageFormatter_object *new_mfo = php_intl_messageformatter_fetch_object(new_obj); - - /* clone standard parts */ - zend_objects_clone_members(&new_mfo->zo, &mfo->zo); - - /* clone formatter object */ - if (MSG_FORMAT_OBJECT(mfo) != NULL) { - UErrorCode error = U_ZERO_ERROR; - MSG_FORMAT_OBJECT(new_mfo) = umsg_clone(MSG_FORMAT_OBJECT(mfo), &error); - - if (U_FAILURE(error)) { - zend_throw_error(NULL, "Failed to clone MessageFormatter"); - } - } else { - zend_throw_error(NULL, "Cannot clone uninitialized MessageFormatter"); - } - return new_obj; -} -/* }}} */ - -/* - * 'MessageFormatter' class registration structures & functions - */ - -/* {{{ msgformat_register_class - * Initialize 'MessageFormatter' class - */ -void msgformat_register_class( void ) -{ - /* Create and register 'MessageFormatter' class. */ - MessageFormatter_ce_ptr = register_class_MessageFormatter(); - MessageFormatter_ce_ptr->create_object = MessageFormatter_object_create; - MessageFormatter_ce_ptr->default_object_handlers = &MessageFormatter_handlers; - - memcpy(&MessageFormatter_handlers, &std_object_handlers, - sizeof MessageFormatter_handlers); - MessageFormatter_handlers.offset = XtOffsetOf(MessageFormatter_object, zo); - MessageFormatter_handlers.clone_obj = MessageFormatter_object_clone; - MessageFormatter_handlers.free_obj = MessageFormatter_object_free; -} -/* }}} */ diff --git a/ext/intl/msgformat/msgformat_class.cpp b/ext/intl/msgformat/msgformat_class.cpp new file mode 100644 index 000000000000..c4d74924b04a --- /dev/null +++ b/ext/intl/msgformat/msgformat_class.cpp @@ -0,0 +1,103 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#include + +extern "C" { +#include "msgformat_class.h" +#include "php_intl.h" +#include "msgformat_data.h" +#include "msgformat_arginfo.h" +} + +#include + +zend_class_entry *MessageFormatter_ce_ptr = NULL; +static zend_object_handlers MessageFormatter_handlers; + +/* + * Auxiliary functions needed by objects of 'MessageFormatter' class + */ + +/* {{{ MessageFormatter_objects_free */ +U_CFUNC void MessageFormatter_object_free( zend_object *object ) +{ + MessageFormatter_object* mfo = php_intl_messageformatter_fetch_object(object); + + zend_object_std_dtor( &mfo->zo ); + + msgformat_data_free( &mfo->mf_data ); +} +/* }}} */ + +/* {{{ MessageFormatter_object_create */ +U_CFUNC zend_object *MessageFormatter_object_create(zend_class_entry *ce) +{ + MessageFormatter_object* intern; + + intern = reinterpret_cast(zend_object_alloc(sizeof(MessageFormatter_object), ce)); + msgformat_data_init( &intern->mf_data ); + zend_object_std_init( &intern->zo, ce ); + object_properties_init(&intern->zo, ce); + + return &intern->zo; +} +/* }}} */ + +/* {{{ MessageFormatter_object_clone */ +U_CFUNC zend_object *MessageFormatter_object_clone(zend_object *object) +{ + const MessageFormatter_object *mfo = php_intl_messageformatter_fetch_object(object); + zend_object *new_obj = MessageFormatter_ce_ptr->create_object(object->ce); + MessageFormatter_object *new_mfo = php_intl_messageformatter_fetch_object(new_obj); + + /* clone standard parts */ + zend_objects_clone_members(&new_mfo->zo, &mfo->zo); + + /* clone formatter object */ + if (MSG_FORMAT_OBJECT(mfo) != NULL) { + UErrorCode error = U_ZERO_ERROR; + MSG_FORMAT_OBJECT(new_mfo) = reinterpret_cast(umsg_clone(MSG_FORMAT_OBJECT(mfo), &error)); + + if (U_FAILURE(error)) { + zend_throw_error(NULL, "Failed to clone MessageFormatter"); + } + } else { + zend_throw_error(NULL, "Cannot clone uninitialized MessageFormatter"); + } + return new_obj; +} +/* }}} */ + +/* + * 'MessageFormatter' class registration structures & functions + */ + +/* {{{ msgformat_register_class + * Initialize 'MessageFormatter' class + */ +void msgformat_register_class( void ) +{ + /* Create and register 'MessageFormatter' class. */ + MessageFormatter_ce_ptr = register_class_MessageFormatter(); + MessageFormatter_ce_ptr->create_object = MessageFormatter_object_create; + MessageFormatter_ce_ptr->default_object_handlers = &MessageFormatter_handlers; + + memcpy(&MessageFormatter_handlers, &std_object_handlers, + sizeof MessageFormatter_handlers); + MessageFormatter_handlers.offset = offsetof(MessageFormatter_object, zo); + MessageFormatter_handlers.clone_obj = MessageFormatter_object_clone; + MessageFormatter_handlers.free_obj = MessageFormatter_object_free; +} +/* }}} */ diff --git a/ext/intl/msgformat/msgformat_class.h b/ext/intl/msgformat/msgformat_class.h index 809fdec65418..a066b38e1d13 100644 --- a/ext/intl/msgformat/msgformat_class.h +++ b/ext/intl/msgformat/msgformat_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -32,7 +32,7 @@ typedef struct { static inline MessageFormatter_object *php_intl_messageformatter_fetch_object(zend_object *obj) { - return (MessageFormatter_object *)((char*)(obj) - XtOffsetOf(MessageFormatter_object, zo)); + return ZEND_CONTAINER_OF(obj, MessageFormatter_object, zo); } #define Z_INTL_MESSAGEFORMATTER_P(zv) php_intl_messageformatter_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/msgformat/msgformat_data.c b/ext/intl/msgformat/msgformat_data.c deleted file mode 100644 index 5d170d25945f..000000000000 --- a/ext/intl/msgformat/msgformat_data.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include "msgformat_data.h" - -#include "msgformat_class.h" - -/* {{{ void msgformat_data_init( msgformat_data* mf_data ) - * Initialize internals of msgformat_data. - */ -void msgformat_data_init( msgformat_data* mf_data ) -{ - if( !mf_data ) - return; - - mf_data->umsgf = NULL; - mf_data->orig_format = NULL; - mf_data->arg_types = NULL; - mf_data->tz_set = 0; - intl_error_reset( &mf_data->error ); -} -/* }}} */ - -/* {{{ void msgformat_data_free( msgformat_data* mf_data ) - * Clean up memory allocated for msgformat_data - */ -void msgformat_data_free(msgformat_data* mf_data) -{ - if (!mf_data) - return; - - if (mf_data->umsgf) - umsg_close(mf_data->umsgf); - - if (mf_data->orig_format) { - efree(mf_data->orig_format); - mf_data->orig_format = NULL; - } - - if (mf_data->arg_types) { - zend_hash_destroy(mf_data->arg_types); - efree(mf_data->arg_types); - mf_data->arg_types = NULL; - } - - mf_data->umsgf = NULL; - intl_error_reset(&mf_data->error); -} -/* }}} */ - -/* {{{ msgformat_data* msgformat_data_create() - * Allocate memory for msgformat_data and initialize it with default values. - */ -msgformat_data* msgformat_data_create( void ) -{ - msgformat_data* mf_data = ecalloc( 1, sizeof(msgformat_data) ); - - msgformat_data_init( mf_data ); - - return mf_data; -} -/* }}} */ - -#ifdef MSG_FORMAT_QUOTE_APOS -int msgformat_fix_quotes(UChar **spattern, uint32_t *spattern_len, UErrorCode *ec) -{ - if(*spattern && *spattern_len && u_strchr(*spattern, (UChar)'\'')) { - UChar *npattern = safe_emalloc(sizeof(UChar)*2, *spattern_len, sizeof(UChar)); - uint32_t npattern_len; - npattern_len = umsg_autoQuoteApostrophe(*spattern, *spattern_len, npattern, 2*(*spattern_len)+1, ec); - efree(*spattern); - if( U_FAILURE(*ec) ) - { - return FAILURE; - } - npattern = erealloc(npattern, sizeof(UChar)*(npattern_len+1)); - *spattern = npattern; - *spattern_len = npattern_len; - } - return SUCCESS; -} -#endif diff --git a/ext/intl/msgformat/msgformat_data.cpp b/ext/intl/msgformat/msgformat_data.cpp new file mode 100644 index 000000000000..c629e8a3d818 --- /dev/null +++ b/ext/intl/msgformat/msgformat_data.cpp @@ -0,0 +1,98 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "msgformat_data.h" + +#include "msgformat_class.h" + +/* {{{ void msgformat_data_init( msgformat_data* mf_data ) + * Initialize internals of msgformat_data. + */ +U_CFUNC void msgformat_data_init( msgformat_data* mf_data ) +{ + if( !mf_data ) + return; + + mf_data->umsgf = NULL; + mf_data->orig_format = NULL; + mf_data->arg_types = NULL; + mf_data->tz_set = 0; + intl_error_reset( &mf_data->error ); +} +/* }}} */ + +/* {{{ void msgformat_data_free( msgformat_data* mf_data ) + * Clean up memory allocated for msgformat_data + */ +U_CFUNC void msgformat_data_free(msgformat_data* mf_data) +{ + if (!mf_data) + return; + + if (mf_data->umsgf) + umsg_close(mf_data->umsgf); + + if (mf_data->orig_format) { + efree(mf_data->orig_format); + mf_data->orig_format = NULL; + } + + if (mf_data->arg_types) { + zend_hash_destroy(mf_data->arg_types); + efree(mf_data->arg_types); + mf_data->arg_types = NULL; + } + + mf_data->umsgf = NULL; + intl_error_reset(&mf_data->error); +} +/* }}} */ + +/* {{{ msgformat_data* msgformat_data_create() + * Allocate memory for msgformat_data and initialize it with default values. + */ +msgformat_data* msgformat_data_create( void ) +{ + msgformat_data* mf_data = reinterpret_cast(ecalloc( 1, sizeof(msgformat_data) )); + + msgformat_data_init( mf_data ); + + return mf_data; +} +/* }}} */ + +#ifdef MSG_FORMAT_QUOTE_APOS +int msgformat_fix_quotes(UChar **spattern, uint32_t *spattern_len, UErrorCode *ec) +{ + if(*spattern && *spattern_len && u_strchr(*spattern, (UChar)'\'')) { + UChar *npattern = safe_emalloc(sizeof(UChar)*2, *spattern_len, sizeof(UChar)); + uint32_t npattern_len; + npattern_len = umsg_autoQuoteApostrophe(*spattern, *spattern_len, npattern, 2*(*spattern_len)+1, ec); + efree(*spattern); + if( U_FAILURE(*ec) ) + { + return FAILURE; + } + npattern = erealloc(npattern, sizeof(UChar)*(npattern_len+1)); + *spattern = npattern; + *spattern_len = npattern_len; + } + return SUCCESS; +} +#endif diff --git a/ext/intl/msgformat/msgformat_data.h b/ext/intl/msgformat/msgformat_data.h index 539c7d6d9255..121c8360efea 100644 --- a/ext/intl/msgformat/msgformat_data.h +++ b/ext/intl/msgformat/msgformat_data.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -17,7 +17,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif #include "../intl_error.h" +#ifdef __cplusplus +} +#endif #include @@ -26,16 +32,22 @@ typedef struct { intl_error error; // formatter handling - UMessageFormat* umsgf; + UMessageFormat *umsgf; char* orig_format; zend_ulong orig_format_len; HashTable* arg_types; int tz_set; /* if we've already the time zone in sub-formats */ } msgformat_data; +#ifdef __cplusplus +extern "C" { +#endif msgformat_data* msgformat_data_create( void ); void msgformat_data_init( msgformat_data* mf_data ); void msgformat_data_free( msgformat_data* mf_data ); +#ifdef __cplusplus +} +#endif #ifdef MSG_FORMAT_QUOTE_APOS int msgformat_fix_quotes(UChar **spattern, uint32_t *spattern_len, UErrorCode *ec); diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c deleted file mode 100644 index 46a364c5d3a2..000000000000 --- a/ext/intl/msgformat/msgformat_format.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "php_intl.h" -#include "msgformat_class.h" -#include "msgformat_data.h" -#include "msgformat_helpers.h" -#include "intl_convert.h" - -#ifndef Z_ADDREF_P -#define Z_ADDREF_P(z) ((z)->refcount++) -#endif - -/* {{{ */ -static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *return_value) -{ - UChar* formatted = NULL; - int32_t formatted_len = 0; - - umsg_format_helper(mfo, Z_ARRVAL_P(args), &formatted, &formatted_len); - - if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { - if (formatted) { - efree(formatted); - } - RETURN_FALSE; - } else { - INTL_METHOD_RETVAL_UTF8(mfo, formatted, formatted_len, 1); - } -} -/* }}} */ - -/* {{{ Format a message. */ -PHP_FUNCTION( msgfmt_format ) -{ - zval *args; - MSG_FORMAT_METHOD_INIT_VARS; - - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa", - &object, MessageFormatter_ce_ptr, &args ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object. */ - MSG_FORMAT_METHOD_FETCH_OBJECT; - - msgfmt_do_format(mfo, args, return_value); -} -/* }}} */ - -/* {{{ Format a message. */ -PHP_FUNCTION( msgfmt_format_message ) -{ - zval *args; - UChar *spattern = NULL; - int spattern_len = 0; - char *pattern = NULL; - size_t pattern_len = 0; - const char *slocale = NULL; - size_t slocale_len = 0; - MessageFormatter_object mf; - MessageFormatter_object *mfo = &mf; - UParseError parse_error; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "ssa", - &slocale, &slocale_len, &pattern, &pattern_len, &args ) == FAILURE ) - { - RETURN_THROWS(); - } - - INTL_CHECK_LOCALE_LEN(slocale_len); - - memset(mfo, 0, sizeof(*mfo)); - msgformat_data_init(&mfo->mf_data); - - if(pattern && pattern_len) { - intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); - if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) ) - { - intl_error_set(/* intl_error* */ NULL, U_ILLEGAL_ARGUMENT_ERROR, - "msgfmt_format_message: error converting pattern to UTF-16", 0 ); - RETURN_FALSE; - } - } else { - spattern_len = 0; - spattern = NULL; - } - - if(slocale_len == 0) { - slocale = intl_locale_get_default(); - } - -#ifdef MSG_FORMAT_QUOTE_APOS - if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { - intl_error_set(/* intl_error* */ NULL, U_INVALID_FORMAT_ERROR, - "msgfmt_format_message: error converting pattern to quote-friendly format", 0 ); - RETURN_FALSE; - } -#endif - - /* Create an ICU message formatter. */ - MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, &parse_error, &INTL_DATA_ERROR_CODE(mfo)); - if(spattern && spattern_len) { - efree(spattern); - } - - /* Cannot use INTL_METHOD_CHECK_STATUS() as we need to free the message object formatter */ - if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { - if (INTL_DATA_ERROR_CODE( mfo ) == U_PATTERN_SYNTAX_ERROR) { - char *msg = NULL; - smart_str parse_error_str; - parse_error_str = intl_parse_error_to_string( &parse_error ); - spprintf( &msg, 0, "pattern syntax error (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "unknown parser error" ); - smart_str_free( &parse_error_str ); - - /* Pass NULL to intl_error* parameter to store message in global Intl error msg stack */ - intl_error_set_code(/* intl_error* */ NULL, INTL_DATA_ERROR_CODE( mfo ) ); - intl_errors_set_custom_msg(/* intl_error* */ NULL, msg, 1 ); - - efree( msg ); - } else { - intl_errors_set_custom_msg(/* intl_error* */ NULL, "Creating message formatter failed", 0 ); - } - umsg_close(MSG_FORMAT_OBJECT(mfo)); - RETURN_FALSE; - } - - msgfmt_do_format(mfo, args, return_value); - - /* drop the temporary formatter */ - msgformat_data_free(&mfo->mf_data); -} -/* }}} */ diff --git a/ext/intl/msgformat/msgformat_format.cpp b/ext/intl/msgformat/msgformat_format.cpp new file mode 100644 index 000000000000..c0a02ad8db17 --- /dev/null +++ b/ext/intl/msgformat/msgformat_format.cpp @@ -0,0 +1,156 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +extern "C" { +#include "php_intl.h" +#include "msgformat_class.h" +#include "msgformat_data.h" +#include "msgformat_helpers.h" +#include "intl_convert.h" +} + +#ifndef Z_ADDREF_P +#define Z_ADDREF_P(z) ((z)->refcount++) +#endif + +/* {{{ */ +static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *return_value) +{ + UChar* formatted = NULL; + int32_t formatted_len = 0; + + umsg_format_helper(mfo, Z_ARRVAL_P(args), &formatted, &formatted_len); + + if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { + if (formatted) { + efree(formatted); + } + RETURN_FALSE; + } else { + INTL_METHOD_RETVAL_UTF8(mfo, formatted, formatted_len, 1); + } +} +/* }}} */ + +/* {{{ Format a message. */ +U_CFUNC PHP_FUNCTION( msgfmt_format ) +{ + zval *args; + MSG_FORMAT_METHOD_INIT_VARS; + + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oa", + &object, MessageFormatter_ce_ptr, &args ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object. */ + MSG_FORMAT_METHOD_FETCH_OBJECT; + + msgfmt_do_format(mfo, args, return_value); +} +/* }}} */ + +/* {{{ Format a message. */ +U_CFUNC PHP_FUNCTION( msgfmt_format_message ) +{ + zval *args; + UChar *spattern = NULL; + int spattern_len = 0; + char *pattern = NULL; + size_t pattern_len = 0; + const char *slocale = NULL; + size_t slocale_len = 0; + MessageFormatter_object mf; + MessageFormatter_object *mfo = &mf; + UParseError parse_error; + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "ssa", + &slocale, &slocale_len, &pattern, &pattern_len, &args ) == FAILURE ) + { + RETURN_THROWS(); + } + + INTL_CHECK_LOCALE_LEN(slocale_len); + + memset(mfo, 0, sizeof(*mfo)); + msgformat_data_init(&mfo->mf_data); + + if(pattern && pattern_len) { + intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); + if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) ) + { + intl_error_set(/* intl_error* */ NULL, U_ILLEGAL_ARGUMENT_ERROR, + "error converting pattern to UTF-16"); + RETURN_FALSE; + } + } else { + spattern_len = 0; + spattern = NULL; + } + + if(slocale_len == 0) { + slocale = intl_locale_get_default(); + } + +#ifdef MSG_FORMAT_QUOTE_APOS + if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { + intl_error_set(/* intl_error* */ NULL, U_INVALID_FORMAT_ERROR, + "msgfmt_format_message: error converting pattern to quote-friendly format"); + RETURN_FALSE; + } +#endif + + /* Create an ICU message formatter. */ + MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, &parse_error, &INTL_DATA_ERROR_CODE(mfo)); + if(spattern && spattern_len) { + efree(spattern); + } + + /* Cannot use INTL_METHOD_CHECK_STATUS() as we need to free the message object formatter */ + if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) { + if (INTL_DATA_ERROR_CODE( mfo ) == U_PATTERN_SYNTAX_ERROR) { + char *msg = NULL; + smart_str parse_error_str; + parse_error_str = intl_parse_error_to_string( &parse_error ); + spprintf( &msg, 0, "pattern syntax error (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "unknown parser error" ); + smart_str_free( &parse_error_str ); + + /* Pass NULL to intl_error* parameter to store message in global Intl error msg stack */ + intl_error_set_code(/* intl_error* */ NULL, INTL_DATA_ERROR_CODE( mfo ) ); + intl_errors_set_custom_msg(/* intl_error* */ NULL, msg); + + efree( msg ); + } else { + intl_errors_set_custom_msg(/* intl_error* */ NULL, "Creating message formatter failed"); + } + umsg_close(MSG_FORMAT_OBJECT(mfo)); + RETURN_FALSE; + } + + msgfmt_do_format(mfo, args, return_value); + + /* drop the temporary formatter */ + msgformat_data_free(&mfo->mf_data); +} +/* }}} */ diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index fbd85b857f3b..12e05af57219 100644 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ @@ -187,7 +187,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, int32_t argNumber = name_part.getValue(); if (argNumber < 0) { intl_errors_set(&err, U_INVALID_FORMAT_ERROR, - "Found part with negative number", 0); + "Found part with negative number"); continue; } if ((storedType = (Formattable::Type*)zend_hash_index_find_ptr(ret, (zend_ulong)argNumber)) == NULL) { @@ -196,7 +196,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, storedType = (Formattable::Type*)zend_hash_index_update_mem(ret, (zend_ulong)argNumber, (void*)&bogusType, sizeof(bogusType)); } } else { - intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Invalid part type encountered", 0); + intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Invalid part type encountered"); continue; } @@ -243,7 +243,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, * is broken. */ intl_errors_set(&err, U_PARSE_ERROR, "Expected UMSGPAT_PART_TYPE_ARG_TYPE part following " - "UMSGPAT_ARG_TYPE_SIMPLE part", 0); + "UMSGPAT_ARG_TYPE_SIMPLE part"); continue; } } else if (argType == UMSGPAT_ARG_TYPE_PLURAL) { @@ -262,7 +262,7 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, /* We found a different type for the same arg! */ if (*storedType != Formattable::kObject && *storedType != type) { intl_errors_set(&err, U_ARGUMENT_TYPE_MISMATCH, - "Inconsistent types declared for an argument", 0); + "Inconsistent types declared for an argument"); continue; } @@ -330,7 +330,7 @@ static void umsg_set_timezone(MessageFormatter_object *mfo, if (UNEXPECTED(formats == NULL)) { intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR, - "Out of memory retrieving subformats", 0); + "Out of memory retrieving subformats"); } for (int i = 0; U_SUCCESS(err.code) && i < count; i++) { @@ -341,9 +341,7 @@ static void umsg_set_timezone(MessageFormatter_object *mfo, } if (used_tz == NULL) { - zval nullzv; - ZVAL_NULL(&nullzv); - used_tz = timezone_process_timezone_argument(&nullzv, &err, "msgfmt_format"); + used_tz = timezone_process_timezone_argument(nullptr, nullptr, &err, 1); if (used_tz == NULL) { continue; } @@ -405,7 +403,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, /* includes case where index < 0 because it's exposed as unsigned */ if (UNEXPECTED(num_index > (zend_ulong)INT32_MAX)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, - "Found negative or too large array key", 0); + "Found negative or too large array key"); continue; } @@ -413,7 +411,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, int32_t len = u_sprintf(temp, "%u", (uint32_t)num_index); key.append(temp, len); - storedArgType = (Formattable::Type*)zend_hash_index_find_ptr(types, (zend_ulong)num_index); + storedArgType = (Formattable::Type*)zend_hash_index_find_ptr(types, num_index); } else { //string; assumed to be in UTF-8 intl_stringFromChar(key, ZSTR_VAL(str_index), ZSTR_LEN(str_index), &err.code); @@ -421,7 +419,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, char *message; spprintf(&message, 0, "Invalid UTF-8 data in argument key: '%s'", ZSTR_VAL(str_index)); - intl_errors_set(&err, err.code, message, 1); + intl_errors_set(&err, err.code, message); efree(message); continue; } @@ -457,7 +455,8 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, char *message; spprintf(&message, 0, "Invalid UTF-8 data in string argument: " "'%s'", ZSTR_VAL(str)); - intl_errors_set(&err, err.code, message, 1); + zend_tmp_string_release(tmp_str); + intl_errors_set(&err, err.code, message); efree(message); delete text; continue; @@ -481,7 +480,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, Z_DVAL_P(elem) < (double)INT32_MIN)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " - "32 bit integer argument", 0); + "32 bit integer argument"); } else { tInt32 = (int32_t)Z_DVAL_P(elem); } @@ -490,7 +489,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, Z_LVAL_P(elem) < INT32_MIN)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP integer with absolute value too large " - "for 32 bit integer argument", 0); + "for 32 bit integer argument"); } else { tInt32 = (int32_t)Z_LVAL_P(elem); } @@ -509,7 +508,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, Z_DVAL_P(elem) < (double)U_INT64_MIN)) { intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, "Found PHP float with absolute value too large for " - "64 bit integer argument", 0); + "64 bit integer argument"); } else { tInt64 = (int64_t)Z_DVAL_P(elem); } @@ -524,7 +523,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } case Formattable::kDate: { - double dd = intl_zval_to_millis(elem, &err, "msgfmt_format"); + double dd = intl_zval_to_millis(elem, &err); if (U_FAILURE(err.code)) { char *message; zend_string *u8key; @@ -533,7 +532,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, if (u8key) { spprintf(&message, 0, "The argument for key '%s' " "cannot be used as a date or time", ZSTR_VAL(u8key)); - intl_errors_set(&err, err.code, message, 1); + intl_errors_set(&err, err.code, message); zend_string_release_ex(u8key, 0); efree(message); } @@ -544,7 +543,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, } default: intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, - "Found unsupported argument type", 0); + "Found unsupported argument type"); break; } } else { @@ -578,8 +577,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, spprintf(&message, 0, "No strategy to convert the " "value given for the argument with key '%s' " "is available", ZSTR_VAL(u8key)); - intl_errors_set(&err, - U_ILLEGAL_ARGUMENT_ERROR, message, 1); + intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR, message); zend_string_release_ex(u8key, 0); efree(message); } @@ -602,7 +600,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, if (U_FAILURE(err.code)) { intl_errors_set(&err, err.code, - "Call to ICU MessageFormat::format() has failed", 0); + "Call to ICU MessageFormat::format() has failed"); return; } @@ -610,8 +608,7 @@ U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo, *formatted = eumalloc(*formatted_len+1); resultStr.extract(*formatted, *formatted_len+1, err.code); if (U_FAILURE(err.code)) { - intl_errors_set(&err, err.code, - "Error copying format() result", 0); + intl_errors_set(&err, err.code, "Error copying format() result"); return; } } @@ -652,7 +649,7 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval **args, UCh case Formattable::kInt64: aInt64 = fargs[i].getInt64(); - if(aInt64 > ZEND_LONG_MAX || aInt64 < -ZEND_LONG_MAX) { + if(aInt64 > ZEND_LONG_MAX || aInt64 < ZEND_LONG_MIN) { ZVAL_DOUBLE(&(*args)[i], (double)aInt64); } else { ZVAL_LONG(&(*args)[i], (zend_long)aInt64); diff --git a/ext/intl/msgformat/msgformat_helpers.h b/ext/intl/msgformat/msgformat_helpers.h index 20282526cbfb..c1a153783511 100644 --- a/ext/intl/msgformat/msgformat_helpers.h +++ b/ext/intl/msgformat/msgformat_helpers.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stanislav Malyshev | +----------------------------------------------------------------------+ diff --git a/ext/intl/msgformat/msgformat_parse.c b/ext/intl/msgformat/msgformat_parse.c deleted file mode 100644 index 80ede995c42e..000000000000 --- a/ext/intl/msgformat/msgformat_parse.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Stanislav Malyshev | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "php_intl.h" -#include "msgformat_class.h" -#include "msgformat_data.h" -#include "msgformat_helpers.h" -#include "intl_convert.h" - -/* {{{ */ -static void msgfmt_do_parse(MessageFormatter_object *mfo, char *source, size_t src_len, zval *return_value) -{ - zval *fargs; - int count = 0; - int i; - UChar *usource = NULL; - int usrc_len = 0; - - intl_convert_utf8_to_utf16(&usource, &usrc_len, source, src_len, &INTL_DATA_ERROR_CODE(mfo)); - INTL_METHOD_CHECK_STATUS(mfo, "Converting parse string failed"); - - umsg_parse_helper(MSG_FORMAT_OBJECT(mfo), &count, &fargs, usource, usrc_len, &INTL_DATA_ERROR_CODE(mfo)); - if (usource) { - efree(usource); - } - INTL_METHOD_CHECK_STATUS(mfo, "Parsing failed"); - - array_init_size(return_value, count); - zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); - for(i=0;imf_data); - - if(pattern && pattern_len) { - intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); - if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) ) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "msgfmt_parse_message: error converting pattern to UTF-16", 0 ); - RETURN_FALSE; - } - } else { - spattern_len = 0; - spattern = NULL; - } - - if(slocale_len == 0) { - slocale = (char *)intl_locale_get_default(); - } - -#ifdef MSG_FORMAT_QUOTE_APOS - if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { - intl_error_set( NULL, U_INVALID_FORMAT_ERROR, - "msgfmt_parse_message: error converting pattern to quote-friendly format", 0 ); - RETURN_FALSE; - } -#endif - - /* Create an ICU message formatter. */ - MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, NULL, &INTL_DATA_ERROR_CODE(mfo)); - if(spattern && spattern_len) { - efree(spattern); - } - INTL_METHOD_CHECK_STATUS(mfo, "Creating message formatter failed"); - - msgfmt_do_parse(mfo, source, src_len, return_value); - - /* drop the temporary formatter */ - msgformat_data_free(&mfo->mf_data); -} -/* }}} */ diff --git a/ext/intl/msgformat/msgformat_parse.cpp b/ext/intl/msgformat/msgformat_parse.cpp new file mode 100644 index 000000000000..b50dc1efed41 --- /dev/null +++ b/ext/intl/msgformat/msgformat_parse.cpp @@ -0,0 +1,140 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Stanislav Malyshev | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +extern "C" { +#include "php_intl.h" +#include "msgformat_class.h" +#include "msgformat_data.h" +#include "msgformat_helpers.h" +#include "intl_convert.h" +} + +/* {{{ */ +static void msgfmt_do_parse(MessageFormatter_object *mfo, char *source, size_t src_len, zval *return_value) +{ + zval *fargs; + int count = 0; + int i; + UChar *usource = NULL; + int usrc_len = 0; + + intl_convert_utf8_to_utf16(&usource, &usrc_len, source, src_len, &INTL_DATA_ERROR_CODE(mfo)); + INTL_METHOD_CHECK_STATUS(mfo, "Converting parse string failed"); + + umsg_parse_helper(MSG_FORMAT_OBJECT(mfo), &count, &fargs, usource, usrc_len, &INTL_DATA_ERROR_CODE(mfo)); + if (usource) { + efree(usource); + } + INTL_METHOD_CHECK_STATUS(mfo, "Parsing failed"); + + array_init_size(return_value, count); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); + for(i=0;imf_data); + + if(pattern && pattern_len) { + intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(mfo)); + if( U_FAILURE(INTL_DATA_ERROR_CODE((mfo))) ) + { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, + "error converting pattern to UTF-16"); + RETURN_FALSE; + } + } else { + spattern_len = 0; + spattern = NULL; + } + + if(slocale_len == 0) { + slocale = (char *)intl_locale_get_default(); + } + +#ifdef MSG_FORMAT_QUOTE_APOS + if(msgformat_fix_quotes(&spattern, &spattern_len, &INTL_DATA_ERROR_CODE(mfo)) != SUCCESS) { + intl_error_set( NULL, U_INVALID_FORMAT_ERROR, + "msgfmt_parse_message: error converting pattern to quote-friendly format", 0 ); + RETURN_FALSE; + } +#endif + + /* Create an ICU message formatter. */ + MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, slocale, NULL, &INTL_DATA_ERROR_CODE(mfo)); + if(spattern && spattern_len) { + efree(spattern); + } + INTL_METHOD_CHECK_STATUS_OR_GOTO(mfo, "Creating message formatter failed", clean); + + msgfmt_do_parse(mfo, source, src_len, return_value); + +clean: + /* drop the temporary formatter */ + msgformat_data_free(&mfo->mf_data); +} +/* }}} */ diff --git a/ext/intl/normalizer/normalizer.h b/ext/intl/normalizer/normalizer.h index 3c6aa0e6eafc..c6feaa106eb1 100644 --- a/ext/intl/normalizer/normalizer.h +++ b/ext/intl/normalizer/normalizer.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ diff --git a/ext/intl/normalizer/normalizer_arginfo.h b/ext/intl/normalizer/normalizer_arginfo.h index e5ef152c0423..761cf92b8c0a 100644 --- a/ext/intl/normalizer/normalizer_arginfo.h +++ b/ext/intl/normalizer/normalizer_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit normalizer.stub.php instead. * Stub hash: 908a9587edd132a41100be09c9908e088f3fa055 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_Normalizer_normalize, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) @@ -36,63 +36,63 @@ static zend_class_entry *register_class_Normalizer(void) zval const_FORM_D_value; ZVAL_LONG(&const_FORM_D_value, NORMALIZER_FORM_D); - zend_string *const_FORM_D_name = zend_string_init_interned("FORM_D", sizeof("FORM_D") - 1, 1); + zend_string *const_FORM_D_name = zend_string_init_interned("FORM_D", sizeof("FORM_D") - 1, true); zend_declare_typed_class_constant(class_entry, const_FORM_D_name, &const_FORM_D_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FORM_D_name); + zend_string_release_ex(const_FORM_D_name, true); zval const_NFD_value; ZVAL_LONG(&const_NFD_value, NORMALIZER_NFD); - zend_string *const_NFD_name = zend_string_init_interned("NFD", sizeof("NFD") - 1, 1); + zend_string *const_NFD_name = zend_string_init_interned("NFD", sizeof("NFD") - 1, true); zend_declare_typed_class_constant(class_entry, const_NFD_name, &const_NFD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NFD_name); + zend_string_release_ex(const_NFD_name, true); zval const_FORM_KD_value; ZVAL_LONG(&const_FORM_KD_value, NORMALIZER_FORM_KD); - zend_string *const_FORM_KD_name = zend_string_init_interned("FORM_KD", sizeof("FORM_KD") - 1, 1); + zend_string *const_FORM_KD_name = zend_string_init_interned("FORM_KD", sizeof("FORM_KD") - 1, true); zend_declare_typed_class_constant(class_entry, const_FORM_KD_name, &const_FORM_KD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FORM_KD_name); + zend_string_release_ex(const_FORM_KD_name, true); zval const_NFKD_value; ZVAL_LONG(&const_NFKD_value, NORMALIZER_NFKD); - zend_string *const_NFKD_name = zend_string_init_interned("NFKD", sizeof("NFKD") - 1, 1); + zend_string *const_NFKD_name = zend_string_init_interned("NFKD", sizeof("NFKD") - 1, true); zend_declare_typed_class_constant(class_entry, const_NFKD_name, &const_NFKD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NFKD_name); + zend_string_release_ex(const_NFKD_name, true); zval const_FORM_C_value; ZVAL_LONG(&const_FORM_C_value, NORMALIZER_FORM_C); - zend_string *const_FORM_C_name = zend_string_init_interned("FORM_C", sizeof("FORM_C") - 1, 1); + zend_string *const_FORM_C_name = zend_string_init_interned("FORM_C", sizeof("FORM_C") - 1, true); zend_declare_typed_class_constant(class_entry, const_FORM_C_name, &const_FORM_C_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FORM_C_name); + zend_string_release_ex(const_FORM_C_name, true); zval const_NFC_value; ZVAL_LONG(&const_NFC_value, NORMALIZER_NFC); - zend_string *const_NFC_name = zend_string_init_interned("NFC", sizeof("NFC") - 1, 1); + zend_string *const_NFC_name = zend_string_init_interned("NFC", sizeof("NFC") - 1, true); zend_declare_typed_class_constant(class_entry, const_NFC_name, &const_NFC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NFC_name); + zend_string_release_ex(const_NFC_name, true); zval const_FORM_KC_value; ZVAL_LONG(&const_FORM_KC_value, NORMALIZER_FORM_KC); - zend_string *const_FORM_KC_name = zend_string_init_interned("FORM_KC", sizeof("FORM_KC") - 1, 1); + zend_string *const_FORM_KC_name = zend_string_init_interned("FORM_KC", sizeof("FORM_KC") - 1, true); zend_declare_typed_class_constant(class_entry, const_FORM_KC_name, &const_FORM_KC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FORM_KC_name); + zend_string_release_ex(const_FORM_KC_name, true); zval const_NFKC_value; ZVAL_LONG(&const_NFKC_value, NORMALIZER_NFKC); - zend_string *const_NFKC_name = zend_string_init_interned("NFKC", sizeof("NFKC") - 1, 1); + zend_string *const_NFKC_name = zend_string_init_interned("NFKC", sizeof("NFKC") - 1, true); zend_declare_typed_class_constant(class_entry, const_NFKC_name, &const_NFKC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NFKC_name); + zend_string_release_ex(const_NFKC_name, true); zval const_FORM_KC_CF_value; ZVAL_LONG(&const_FORM_KC_CF_value, NORMALIZER_FORM_KC_CF); - zend_string *const_FORM_KC_CF_name = zend_string_init_interned("FORM_KC_CF", sizeof("FORM_KC_CF") - 1, 1); + zend_string *const_FORM_KC_CF_name = zend_string_init_interned("FORM_KC_CF", sizeof("FORM_KC_CF") - 1, true); zend_declare_typed_class_constant(class_entry, const_FORM_KC_CF_name, &const_FORM_KC_CF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FORM_KC_CF_name); + zend_string_release_ex(const_FORM_KC_CF_name, true); zval const_NFKC_CF_value; ZVAL_LONG(&const_NFKC_CF_value, NORMALIZER_NFKC_CF); - zend_string *const_NFKC_CF_name = zend_string_init_interned("NFKC_CF", sizeof("NFKC_CF") - 1, 1); + zend_string *const_NFKC_CF_name = zend_string_init_interned("NFKC_CF", sizeof("NFKC_CF") - 1, true); zend_declare_typed_class_constant(class_entry, const_NFKC_CF_name, &const_NFKC_CF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NFKC_CF_name); + zend_string_release_ex(const_NFKC_CF_name, true); return class_entry; } diff --git a/ext/intl/normalizer/normalizer_class.c b/ext/intl/normalizer/normalizer_class.c deleted file mode 100644 index d9e413d5e514..000000000000 --- a/ext/intl/normalizer/normalizer_class.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Ed Batutis | - +----------------------------------------------------------------------+ - */ - -#include "normalizer.h" -#include "normalizer_class.h" -#include "php_intl.h" -#include "normalizer_arginfo.h" -#include "intl_error.h" - -#include - -zend_class_entry *Normalizer_ce_ptr = NULL; - -/* - * 'Normalizer' class registration structures & functions - */ - -/* {{{ normalizer_register_Normalizer_class - * Initialize 'Normalizer' class - */ -void normalizer_register_Normalizer_class( void ) -{ - /* Create and register 'Normalizer' class. */ - Normalizer_ce_ptr = register_class_Normalizer(); - Normalizer_ce_ptr->create_object = NULL; -} -/* }}} */ diff --git a/ext/intl/normalizer/normalizer_class.cpp b/ext/intl/normalizer/normalizer_class.cpp new file mode 100644 index 000000000000..1898df04e2e1 --- /dev/null +++ b/ext/intl/normalizer/normalizer_class.cpp @@ -0,0 +1,49 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Ed Batutis | + +----------------------------------------------------------------------+ + */ + +#if __cplusplus >= 201703L +#include +#endif +#include + +#include "normalizer.h" +#include "normalizer_class.h" +#include "php_intl.h" +#ifdef __cplusplus +extern "C" { +#endif +#include "normalizer_arginfo.h" +#include "intl_error.h" +#ifdef __cplusplus +} +#endif + +#include + +zend_class_entry *Normalizer_ce_ptr = NULL; + +/* + * 'Normalizer' class registration structures & functions + */ + +/* {{{ normalizer_register_Normalizer_class + * Initialize 'Normalizer' class + */ +U_CFUNC void normalizer_register_Normalizer_class( void ) +{ + /* Create and register 'Normalizer' class. */ + Normalizer_ce_ptr = register_class_Normalizer(); + Normalizer_ce_ptr->create_object = NULL; +} +/* }}} */ diff --git a/ext/intl/normalizer/normalizer_class.h b/ext/intl/normalizer/normalizer_class.h index 6e57cae40ba0..e30c29237041 100644 --- a/ext/intl/normalizer/normalizer_class.h +++ b/ext/intl/normalizer/normalizer_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Ed Batutis | +----------------------------------------------------------------------+ @@ -36,6 +36,12 @@ typedef struct { #define NORMALIZER_ERROR_CODE(co) INTL_ERROR_CODE(NORMALIZER_ERROR(co)) #define NORMALIZER_ERROR_CODE_P(co) &(INTL_ERROR_CODE(NORMALIZER_ERROR(co))) +#ifdef __cplusplus +extern "C" { +#endif void normalizer_register_Normalizer_class( void ); +#ifdef __cplusplus +} +#endif extern zend_class_entry *Normalizer_ce_ptr; #endif // #ifndef NORMALIZER_CLASS_H diff --git a/ext/intl/normalizer/normalizer_normalize.c b/ext/intl/normalizer/normalizer_normalize.c deleted file mode 100644 index 38f12134146a..000000000000 --- a/ext/intl/normalizer/normalizer_normalize.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Ed Batutis | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include -#include "normalizer.h" -#include "normalizer_class.h" -#include "intl_convert.h" -#include - - -static const UNormalizer2 *intl_get_normalizer(zend_long form, UErrorCode *err) -{/*{{{*/ - switch (form) - { - case NORMALIZER_FORM_C: - return unorm2_getNFCInstance(err); - break; - case NORMALIZER_FORM_D: - return unorm2_getNFDInstance(err); - break; - case NORMALIZER_FORM_KC: - return unorm2_getNFKCInstance(err); - break; - case NORMALIZER_FORM_KD: - return unorm2_getNFKDInstance(err); - break; - case NORMALIZER_FORM_KC_CF: - return unorm2_getNFKCCasefoldInstance(err); - break; - } - - *err = U_ILLEGAL_ARGUMENT_ERROR; - return NULL; -}/*}}}*/ - -static int32_t intl_normalize(zend_long form, const UChar *src, int32_t src_len, UChar *dst, int32_t dst_len, UErrorCode *err) -{/*{{{*/ - const UNormalizer2 *norm = intl_get_normalizer(form, err); - if (U_FAILURE(*err)) { - return -1; - } - - return unorm2_normalize(norm, src, src_len, dst, dst_len, err); -}/*}}}*/ - -static UBool intl_is_normalized(zend_long form, const UChar *uinput, int32_t uinput_len, UErrorCode *err) -{/*{{{*/ - const UNormalizer2 *norm = intl_get_normalizer(form, err); - - if(U_FAILURE(*err)) { - return false; - } - - return unorm2_isNormalized(norm, uinput, uinput_len, err); -}/*}}}*/ - -/* {{{ Normalize a string. */ -PHP_FUNCTION( normalizer_normalize ) -{ - char* input = NULL; - /* form is optional, defaults to FORM_C */ - zend_long form = NORMALIZER_DEFAULT; - size_t input_len = 0; - - UChar* uinput = NULL; - int32_t uinput_len = 0; - int expansion_factor = 1; - UErrorCode status = U_ZERO_ERROR; - - UChar* uret_buf = NULL; - int32_t uret_len = 0; - - zend_string* u8str; - - int32_t size_needed; - - intl_error_reset( NULL ); - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "s|l", - &input, &input_len, &form ) == FAILURE ) - { - RETURN_THROWS(); - } - - expansion_factor = 1; - - switch(form) { - case NORMALIZER_FORM_D: - expansion_factor = 3; - break; - case NORMALIZER_FORM_KD: - expansion_factor = 3; - break; - case NORMALIZER_FORM_C: - case NORMALIZER_FORM_KC: - case NORMALIZER_FORM_KC_CF: - break; - default: - zend_argument_value_error(2, "must be a a valid normalization form"); - RETURN_THROWS(); - } - - /* - * Normalize string (converting it to UTF-16 first). - */ - - /* First convert the string to UTF-16. */ - intl_convert_utf8_to_utf16(&uinput, &uinput_len, input, input_len, &status ); - - if( U_FAILURE( status ) ) - { - /* Set global error code. */ - intl_error_set_code( NULL, status ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16", 0 ); - if (uinput) { - efree( uinput ); - } - RETURN_FALSE; - } - - - /* Allocate memory for the destination buffer for normalization */ - uret_len = uinput_len * expansion_factor; - uret_buf = eumalloc( uret_len + 1 ); - - /* normalize */ - size_needed = intl_normalize(form, uinput, uinput_len, uret_buf, uret_len, &status); - - /* Bail out if an unexpected error occurred. - * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough). - * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty). - */ - if( U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR && status != U_STRING_NOT_TERMINATED_WARNING ) { - intl_error_set_custom_msg( NULL, "Error normalizing string", 0 ); - efree( uret_buf ); - efree( uinput ); - RETURN_FALSE; - } - - if ( size_needed > uret_len ) { - /* realloc does not seem to work properly - memory is corrupted - * uret_buf = eurealloc(uret_buf, size_needed + 1); - */ - efree( uret_buf ); - uret_buf = eumalloc( size_needed + 1 ); - uret_len = size_needed; - - status = U_ZERO_ERROR; - - /* try normalize again */ - size_needed = intl_normalize(form, uinput, uinput_len, uret_buf, uret_len, &status); - - /* Bail out if an unexpected error occurred. */ - if( U_FAILURE(status) ) { - /* Set error messages. */ - intl_error_set_custom_msg( NULL,"Error normalizing string", 0 ); - efree( uret_buf ); - efree( uinput ); - RETURN_FALSE; - } - } - - efree( uinput ); - - /* the buffer we actually used */ - uret_len = size_needed; - - /* Convert normalized string from UTF-16 to UTF-8. */ - u8str = intl_convert_utf16_to_utf8(uret_buf, uret_len, &status ); - efree( uret_buf ); - if( !u8str ) - { - intl_error_set( NULL, status, - "normalizer_normalize: error converting normalized text UTF-8", 0 ); - RETURN_FALSE; - } - - /* Return it. */ - RETVAL_NEW_STR( u8str ); -} -/* }}} */ - -/* {{{ Test if a string is in a given normalization form. */ -PHP_FUNCTION( normalizer_is_normalized ) -{ - char* input = NULL; - /* form is optional, defaults to FORM_C */ - zend_long form = NORMALIZER_DEFAULT; - size_t input_len = 0; - - UChar* uinput = NULL; - int uinput_len = 0; - UErrorCode status = U_ZERO_ERROR; - - UBool uret = false; - - intl_error_reset( NULL ); - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "s|l", - &input, &input_len, &form) == FAILURE ) - { - RETURN_THROWS(); - } - - switch(form) { - case NORMALIZER_FORM_D: - case NORMALIZER_FORM_KD: - case NORMALIZER_FORM_C: - case NORMALIZER_FORM_KC: - case NORMALIZER_FORM_KC_CF: - break; - default: - zend_argument_value_error(2, "must be a a valid normalization form"); - RETURN_THROWS(); - } - - - /* - * Test normalization of string (converting it to UTF-16 first). - */ - - /* First convert the string to UTF-16. */ - intl_convert_utf8_to_utf16(&uinput, &uinput_len, input, input_len, &status ); - - if( U_FAILURE( status ) ) - { - /* Set global error code. */ - intl_error_set_code( NULL, status ); - - /* Set error messages. */ - intl_error_set_custom_msg( NULL, "Error converting string to UTF-16.", 0 ); - if (uinput) { - efree( uinput ); - } - RETURN_FALSE; - } - - - /* test string */ - uret = intl_is_normalized(form, uinput, uinput_len, &status); - - efree( uinput ); - - /* Bail out if an unexpected error occurred. */ - if( U_FAILURE(status) ) { - /* Set error messages. */ - intl_error_set_custom_msg( NULL,"Error testing if string is the given normalization form.", 0 ); - RETURN_FALSE; - } - - if ( uret ) - RETURN_TRUE; - - RETURN_FALSE; -} -/* }}} */ - -/* {{{ Returns the Decomposition_Mapping property for the given UTF-8 encoded code point. */ -PHP_FUNCTION( normalizer_get_raw_decomposition ) -{ - char* input = NULL; - size_t input_length = 0; - - UChar32 codepoint = -1; - int32_t offset = 0; - - UErrorCode status = U_ZERO_ERROR; - const UNormalizer2 *norm; - UChar decomposition[32]; - int32_t decomposition_length; - - zend_long form = NORMALIZER_DEFAULT; - - intl_error_reset(NULL); - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(input, input_length) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(form) - ZEND_PARSE_PARAMETERS_END(); - - norm = intl_get_normalizer(form, &status); - - U8_NEXT(input, offset, input_length, codepoint); - if ((size_t)offset != input_length) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Input string must be exactly one UTF-8 encoded code point long.", 0); - return; - } - - if ((codepoint < UCHAR_MIN_VALUE) || (codepoint > UCHAR_MAX_VALUE)) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Code point out of range", 0); - return; - } - - decomposition_length = unorm2_getRawDecomposition(norm, codepoint, decomposition, 32, &status); - if (decomposition_length == -1) { - RETURN_NULL(); - } - - RETVAL_NEW_STR(intl_convert_utf16_to_utf8(decomposition, decomposition_length, &status)); -} -/* }}} */ diff --git a/ext/intl/normalizer/normalizer_normalize.cpp b/ext/intl/normalizer/normalizer_normalize.cpp new file mode 100644 index 000000000000..846eda64b4c8 --- /dev/null +++ b/ext/intl/normalizer/normalizer_normalize.cpp @@ -0,0 +1,326 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Ed Batutis | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +#include +#include "normalizer.h" +#include "normalizer_class.h" +#include "intl_convert.h" +} +#include + + +static const UNormalizer2 *intl_get_normalizer(zend_long form, UErrorCode *err) +{/*{{{*/ + switch (form) + { + case NORMALIZER_FORM_C: + return unorm2_getNFCInstance(err); + case NORMALIZER_FORM_D: + return unorm2_getNFDInstance(err); + case NORMALIZER_FORM_KC: + return unorm2_getNFKCInstance(err); + case NORMALIZER_FORM_KD: + return unorm2_getNFKDInstance(err); + case NORMALIZER_FORM_KC_CF: + return unorm2_getNFKCCasefoldInstance(err); + } + + *err = U_ILLEGAL_ARGUMENT_ERROR; + return NULL; +}/*}}}*/ + +static int32_t intl_normalize(zend_long form, const UChar *src, int32_t src_len, UChar *dst, int32_t dst_len, UErrorCode *err) +{/*{{{*/ + const UNormalizer2 *norm = intl_get_normalizer(form, err); + if (U_FAILURE(*err)) { + return -1; + } + + return unorm2_normalize(norm, src, src_len, dst, dst_len, err); +}/*}}}*/ + +static UBool intl_is_normalized(zend_long form, const UChar *uinput, int32_t uinput_len, UErrorCode *err) +{/*{{{*/ + const UNormalizer2 *norm = intl_get_normalizer(form, err); + + if(U_FAILURE(*err)) { + return false; + } + + return unorm2_isNormalized(norm, uinput, uinput_len, err); +}/*}}}*/ + +/* {{{ Normalize a string. */ +U_CFUNC PHP_FUNCTION( normalizer_normalize ) +{ + char* input = NULL; + /* form is optional, defaults to FORM_C */ + zend_long form = NORMALIZER_DEFAULT; + size_t input_len = 0; + + UChar* uinput = NULL; + int32_t uinput_len = 0; + int expansion_factor = 1; + UErrorCode status = U_ZERO_ERROR; + + UChar* uret_buf = NULL; + int32_t uret_len = 0; + + zend_string* u8str; + + int32_t size_needed; + + intl_error_reset( NULL ); + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "s|l", + &input, &input_len, &form ) == FAILURE ) + { + RETURN_THROWS(); + } + + expansion_factor = 1; + + switch(form) { + case NORMALIZER_FORM_D: + expansion_factor = 3; + break; + case NORMALIZER_FORM_KD: + expansion_factor = 3; + break; + case NORMALIZER_FORM_C: + case NORMALIZER_FORM_KC: + case NORMALIZER_FORM_KC_CF: + break; + default: + zend_argument_value_error(2, "must be a a valid normalization form"); + RETURN_THROWS(); + } + + /* + * Normalize string (converting it to UTF-16 first). + */ + + /* First convert the string to UTF-16. */ + intl_convert_utf8_to_utf16(&uinput, &uinput_len, input, input_len, &status ); + + if( U_FAILURE( status ) ) + { + /* Set global error code. */ + intl_error_set_code( NULL, status ); + + /* Set error messages. */ + intl_error_set_custom_msg( NULL, "Error converting input string to UTF-16"); + if (uinput) { + efree( uinput ); + } + RETURN_FALSE; + } + + + /* Allocate memory for the destination buffer for normalization */ + uret_len = uinput_len * expansion_factor; + uret_buf = eumalloc( uret_len + 1 ); + + /* normalize */ + size_needed = intl_normalize(form, uinput, uinput_len, uret_buf, uret_len, &status); + + /* Bail out if an unexpected error occurred. + * (U_BUFFER_OVERFLOW_ERROR means that *target buffer is not large enough). + * (U_STRING_NOT_TERMINATED_WARNING usually means that the input string is empty). + */ + if( U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR && status != U_STRING_NOT_TERMINATED_WARNING ) { + intl_error_set_custom_msg( NULL, "Error normalizing string"); + efree( uret_buf ); + efree( uinput ); + RETURN_FALSE; + } + + if ( size_needed > uret_len ) { + /* realloc does not seem to work properly - memory is corrupted + * uret_buf = eurealloc(uret_buf, size_needed + 1); + */ + efree( uret_buf ); + uret_buf = eumalloc( size_needed + 1 ); + uret_len = size_needed; + + status = U_ZERO_ERROR; + + /* try normalize again */ + size_needed = intl_normalize(form, uinput, uinput_len, uret_buf, uret_len, &status); + + /* Bail out if an unexpected error occurred. */ + if( U_FAILURE(status) ) { + /* Set error messages. */ + intl_error_set_custom_msg( NULL,"Error normalizing string"); + efree( uret_buf ); + efree( uinput ); + RETURN_FALSE; + } + } + + efree( uinput ); + + /* the buffer we actually used */ + uret_len = size_needed; + + /* Convert normalized string from UTF-16 to UTF-8. */ + u8str = intl_convert_utf16_to_utf8(uret_buf, uret_len, &status ); + efree( uret_buf ); + if( !u8str ) + { + intl_error_set( NULL, status, + "error converting normalized text UTF-8"); + RETURN_FALSE; + } + + /* Return it. */ + RETVAL_NEW_STR( u8str ); +} +/* }}} */ + +/* {{{ Test if a string is in a given normalization form. */ +U_CFUNC PHP_FUNCTION( normalizer_is_normalized ) +{ + char* input = NULL; + /* form is optional, defaults to FORM_C */ + zend_long form = NORMALIZER_DEFAULT; + size_t input_len = 0; + + UChar* uinput = NULL; + int uinput_len = 0; + UErrorCode status = U_ZERO_ERROR; + + UBool uret = false; + + intl_error_reset( NULL ); + + /* Parse parameters. */ + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "s|l", + &input, &input_len, &form) == FAILURE ) + { + RETURN_THROWS(); + } + + switch(form) { + case NORMALIZER_FORM_D: + case NORMALIZER_FORM_KD: + case NORMALIZER_FORM_C: + case NORMALIZER_FORM_KC: + case NORMALIZER_FORM_KC_CF: + break; + default: + zend_argument_value_error(2, "must be a a valid normalization form"); + RETURN_THROWS(); + } + + + /* + * Test normalization of string (converting it to UTF-16 first). + */ + + /* First convert the string to UTF-16. */ + intl_convert_utf8_to_utf16(&uinput, &uinput_len, input, input_len, &status ); + + if( U_FAILURE( status ) ) + { + /* Set global error code. */ + intl_error_set_code( NULL, status ); + + /* Set error messages. */ + intl_error_set_custom_msg( NULL, "Error converting string to UTF-16."); + if (uinput) { + efree( uinput ); + } + RETURN_FALSE; + } + + + /* test string */ + uret = intl_is_normalized(form, uinput, uinput_len, &status); + + efree( uinput ); + + /* Bail out if an unexpected error occurred. */ + if( U_FAILURE(status) ) { + /* Set error messages. */ + intl_error_set_custom_msg( NULL,"Error testing if string is the given normalization form."); + RETURN_FALSE; + } + + if ( uret ) + RETURN_TRUE; + + RETURN_FALSE; +} +/* }}} */ + +/* {{{ Returns the Decomposition_Mapping property for the given UTF-8 encoded code point. */ +U_CFUNC PHP_FUNCTION( normalizer_get_raw_decomposition ) +{ + char* input = NULL; + size_t input_length = 0; + + UChar32 codepoint = -1; + int32_t offset = 0; + + UErrorCode status = U_ZERO_ERROR; + const UNormalizer2 *norm; + UChar decomposition[32]; + int32_t decomposition_length; + + zend_long form = NORMALIZER_DEFAULT; + + intl_error_reset(NULL); + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(input, input_length) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(form) + ZEND_PARSE_PARAMETERS_END(); + + norm = intl_get_normalizer(form, &status); + + U8_NEXT(input, offset, input_length, codepoint); + if ((size_t)offset != input_length) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Input string must be exactly one UTF-8 encoded code point long."); + return; + } + + if ((codepoint < UCHAR_MIN_VALUE) || (codepoint > UCHAR_MAX_VALUE)) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Code point out of range"); + return; + } + + decomposition_length = unorm2_getRawDecomposition(norm, codepoint, decomposition, 32, &status); + if (decomposition_length == -1) { + RETURN_NULL(); + } + + RETVAL_NEW_STR(intl_convert_utf16_to_utf8(decomposition, decomposition_length, &status)); +} +/* }}} */ diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c index 68fd2dedfba8..9882309c6f46 100644 --- a/ext/intl/php_intl.c +++ b/ext/intl/php_intl.c @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -42,6 +42,7 @@ #include "locale/locale_class.h" #include "listformatter/listformatter_class.h" +#include "rangeformatter/rangeformatter_class.h" #include "dateformat/dateformat.h" #include "dateformat/dateformat_class.h" @@ -98,10 +99,38 @@ const char *intl_locale_get_default( void ) return INTL_G(default_locale); } +char* canonicalize_locale_string(const char* locale) { + char canonicalized[ULOC_FULLNAME_CAPACITY]; + UErrorCode status = U_ZERO_ERROR; + int32_t canonicalized_len; + + canonicalized_len = uloc_canonicalize(locale, canonicalized, sizeof(canonicalized), &status); + + if (U_FAILURE(status) || canonicalized_len <= 0) { + return NULL; + } + + return estrdup(canonicalized); +} + +static PHP_INI_MH(OnUpdateErrorLevel) +{ + zend_long *p = ZEND_INI_GET_ADDR(); + *p = zend_ini_parse_quantity_warn(new_value, entry->name); + if (*p) { + php_error_docref("session.configuration", E_DEPRECATED, + "Using a value different than 0 for intl.error_level is deprecated," + " as the intl.error_level INI setting is deprecated." + " Instead the intl.use_exceptions INI setting should be enabled to throw exceptions on errors" + " or intl_get_error_code()/intl_get_error_message() should be used to manually deal with errors"); + } + return SUCCESS; +} + /* {{{ INI Settings */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY(LOCALE_INI_NAME, NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_locale, zend_intl_globals, intl_globals) - STD_PHP_INI_ENTRY("intl.error_level", "0", PHP_INI_ALL, OnUpdateLong, error_level, zend_intl_globals, intl_globals) + STD_PHP_INI_ENTRY("intl.error_level", "0", PHP_INI_ALL, OnUpdateErrorLevel, error_level, zend_intl_globals, intl_globals) STD_PHP_INI_BOOLEAN("intl.use_exceptions", "0", PHP_INI_ALL, OnUpdateBool, use_exceptions, zend_intl_globals, intl_globals) PHP_INI_END() /* }}} */ @@ -161,6 +190,10 @@ PHP_MINIT_FUNCTION( intl ) /* Register 'ListFormatter' PHP class */ listformatter_register_class( ); +#if U_ICU_VERSION_MAJOR_NUM >= 63 + /* Register 'NumberRangeFormatter' PHP class */ + rangeformatter_register_class( ); +#endif /* Register 'Normalizer' PHP class */ normalizer_register_Normalizer_class( ); diff --git a/ext/intl/php_intl.h b/ext/intl/php_intl.h index 69772f4a8548..1a9b4f769e86 100644 --- a/ext/intl/php_intl.h +++ b/ext/intl/php_intl.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Vadim Savchuk | | Dmitry Lakhtyuk | @@ -68,6 +68,7 @@ PHP_RSHUTDOWN_FUNCTION(intl); PHP_MINFO_FUNCTION(intl); const char *intl_locale_get_default( void ); +char *canonicalize_locale_string(const char* locale); #define PHP_INTL_VERSION PHP_VERSION diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php index dfb05a2b50ac..4bcb8587f786 100644 --- a/ext/intl/php_intl.stub.php +++ b/ext/intl/php_intl.stub.php @@ -173,8 +173,7 @@ class IntlException extends Exception /* calendar */ -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ -function intlcal_create_instance($timezone = null, ?string $locale = null): ?IntlCalendar {} +function intlcal_create_instance(IntlTimeZone|DateTimeZone|string|null $timezone = null, ?string $locale = null): ?IntlCalendar {} function intlcal_get_keyword_values_for_locale(string $keyword, string $locale, bool $onlyCommon): IntlIterator|false {} @@ -194,8 +193,7 @@ function intlcal_set_time(IntlCalendar $calendar, float $timestamp): bool {} function intlcal_add(IntlCalendar $calendar, int $field, int $value): bool {} -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ -function intlcal_set_time_zone(IntlCalendar $calendar, $timezone): bool {} +function intlcal_set_time_zone(IntlCalendar $calendar, IntlTimeZone|DateTimeZone|string|null $timezone): bool {} function intlcal_after(IntlCalendar $calendar, IntlCalendar $other): bool {} @@ -328,12 +326,11 @@ function intl_error_name(int $errorCode): string {} /* dateformat */ -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ function datefmt_create( ?string $locale, int $dateType = IntlDateFormatter::FULL, int $timeType = IntlDateFormatter::FULL, - $timezone = null, + IntlTimeZone|DateTimeZone|string|null $timezone = null, IntlCalendar|int|null $calendar = null, ?string $pattern = null ): ?IntlDateFormatter {} @@ -352,8 +349,7 @@ function datefmt_get_calendar_object(IntlDateFormatter $formatter): IntlCalendar function datefmt_get_timezone(IntlDateFormatter $formatter): IntlTimeZone|false {} -/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ -function datefmt_set_timezone(IntlDateFormatter $formatter, $timezone): bool {} +function datefmt_set_timezone(IntlDateFormatter $formatter, IntlTimeZone|DateTimeZone|string|null $timezone): bool {} function datefmt_set_pattern(IntlDateFormatter $formatter, string $pattern): bool {} @@ -431,23 +427,25 @@ function numfmt_get_error_message(NumberFormatter $formatter): string {} function grapheme_strlen(string $string): int|false|null {} -function grapheme_strpos(string $haystack, string $needle, int $offset = 0): int|false {} +function grapheme_strpos(string $haystack, string $needle, int $offset = 0, string $locale = ""): int|false {} -function grapheme_stripos(string $haystack, string $needle, int $offset = 0): int|false {} +function grapheme_stripos(string $haystack, string $needle, int $offset = 0, string $locale = ""): int|false {} -function grapheme_strrpos(string $haystack, string $needle, int $offset = 0): int|false {} +function grapheme_strrpos(string $haystack, string $needle, int $offset = 0, string $locale = ""): int|false {} -function grapheme_strripos(string $haystack, string $needle, int $offset = 0): int|false {} +function grapheme_strripos(string $haystack, string $needle, int $offset = 0, string $locale = ""): int|false {} -function grapheme_substr(string $string, int $offset, ?int $length = null): string|false {} +function grapheme_substr(string $string, int $offset, ?int $length = null, string $locale = ""): string|false {} -function grapheme_strstr(string $haystack, string $needle, bool $beforeNeedle = false): string|false {} +function grapheme_strstr(string $haystack, string $needle, bool $beforeNeedle = false, string $locale = ""): string|false {} -function grapheme_stristr(string $haystack, string $needle, bool $beforeNeedle = false): string|false {} +function grapheme_stristr(string $haystack, string $needle, bool $beforeNeedle = false, string $locale = ""): string|false {} function grapheme_str_split(string $string, int $length = 1): array|false {} -function grapheme_levenshtein(string $string1, string $string2, int $insertion_cost = 1, int $replacement_cost = 1, int $deletion_cost = 1): int|false {} +function grapheme_levenshtein(string $string1, string $string2, int $insertion_cost = 1, int $replacement_cost = 1, int $deletion_cost = 1, string $locale = ""): int|false {} + +function grapheme_strrev(string $string): string|false {} /** @param int $next */ function grapheme_extract(string $haystack, int $size, int $type = GRAPHEME_EXTR_COUNT, int $offset = 0, &$next = null): string|false {} @@ -571,8 +569,7 @@ function intltz_count_equivalent_ids(string $timezoneId): int|false {} function intltz_create_default(): IntlTimeZone {} -/** @param IntlTimeZone|string|int|float|null $countryOrRawOffset */ -function intltz_create_enumeration($countryOrRawOffset = null): IntlIterator|false {} +function intltz_create_enumeration(string|int|null $countryOrRawOffset = null): IntlIterator|false {} function intltz_create_time_zone(string $timezoneId): ?IntlTimeZone {} diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index b71008491073..81160349980c 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1,8 +1,8 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0d5b028a1ab8f35e8ee1b51ce3141b6ef782af28 */ +/* This is a generated file, edit php_intl.stub.php instead. + * Stub hash: c52fd0def2530be628beedbbcdcfecdcb07449a8 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -40,7 +40,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_intlcal_set_time_zone, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, calendar, IntlCalendar, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_intlcal_after, 0, 2, _IS_BOOL, 0) @@ -280,7 +280,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_datefmt_create, 0, 1, IntlDateFor ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dateType, IS_LONG, 0, "IntlDateFormatter::FULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeType, IS_LONG, 0, "IntlDateFormatter::FULL") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 1, "null") ZEND_END_ARG_INFO() @@ -312,7 +312,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_datefmt_set_timezone, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, formatter, IntlDateFormatter, 0) - ZEND_ARG_INFO(0, timezone) + ZEND_ARG_OBJ_TYPE_MASK(0, timezone, IntlTimeZone|DateTimeZone, MAY_BE_STRING|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_datefmt_set_pattern, 0, 2, _IS_BOOL, 0) @@ -462,6 +462,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_strpos, 0, 2, MAY_BE_LO ZEND_ARG_TYPE_INFO(0, haystack, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, needle, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() #define arginfo_grapheme_stripos arginfo_grapheme_strpos @@ -474,12 +475,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_substr, 0, 2, MAY_BE_ST ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_strstr, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, haystack, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, needle, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, beforeNeedle, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() #define arginfo_grapheme_stristr arginfo_grapheme_strstr @@ -495,6 +498,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_levenshtein, 0, 2, MAY_ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, insertion_cost, IS_LONG, 0, "1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, replacement_cost, IS_LONG, 0, "1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, deletion_cost, IS_LONG, 0, "1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, locale, IS_STRING, 0, "\"\"") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_strrev, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_grapheme_extract, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) @@ -679,7 +687,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intltz_create_default, 0, 0, Intl ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_intltz_create_enumeration, 0, 0, IntlIterator, MAY_BE_FALSE) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, countryOrRawOffset, "null") + ZEND_ARG_TYPE_MASK(0, countryOrRawOffset, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intltz_create_time_zone, 0, 1, IntlTimeZone, 1) @@ -918,6 +926,7 @@ ZEND_FUNCTION(grapheme_strstr); ZEND_FUNCTION(grapheme_stristr); ZEND_FUNCTION(grapheme_str_split); ZEND_FUNCTION(grapheme_levenshtein); +ZEND_FUNCTION(grapheme_strrev); ZEND_FUNCTION(grapheme_extract); ZEND_FUNCTION(idn_to_ascii); ZEND_FUNCTION(idn_to_utf8); @@ -1109,6 +1118,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(grapheme_stristr, arginfo_grapheme_stristr) ZEND_FE(grapheme_str_split, arginfo_grapheme_str_split) ZEND_FE(grapheme_levenshtein, arginfo_grapheme_levenshtein) + ZEND_FE(grapheme_strrev, arginfo_grapheme_strrev) ZEND_FE(grapheme_extract, arginfo_grapheme_extract) ZEND_FE(idn_to_ascii, arginfo_idn_to_ascii) ZEND_FE(idn_to_utf8, arginfo_idn_to_utf8) @@ -1223,27 +1233,17 @@ static void register_php_intl_symbols(int module_number) zend_attribute *attribute_Deprecated_func_intlcal_set_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "intlcal_set", sizeof("intlcal_set") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_intlcal_set_0_arg0; - zend_string *attribute_Deprecated_func_intlcal_set_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_intlcal_set_0_arg0, attribute_Deprecated_func_intlcal_set_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_intlcal_set_0->args[0].value, &attribute_Deprecated_func_intlcal_set_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_intlcal_set_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_intlcal_set_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_intlcal_set_0_arg1; zend_string *attribute_Deprecated_func_intlcal_set_0_arg1_str = zend_string_init("use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead", strlen("use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_intlcal_set_0_arg1, attribute_Deprecated_func_intlcal_set_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_intlcal_set_0->args[1].value, &attribute_Deprecated_func_intlcal_set_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_intlcal_set_0->args[1].value, attribute_Deprecated_func_intlcal_set_0_arg1_str); attribute_Deprecated_func_intlcal_set_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_intlgregcal_create_instance_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "intlgregcal_create_instance", sizeof("intlgregcal_create_instance") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_intlgregcal_create_instance_0_arg0; - zend_string *attribute_Deprecated_func_intlgregcal_create_instance_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_intlgregcal_create_instance_0_arg0, attribute_Deprecated_func_intlgregcal_create_instance_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_intlgregcal_create_instance_0->args[0].value, &attribute_Deprecated_func_intlgregcal_create_instance_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_intlgregcal_create_instance_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_intlgregcal_create_instance_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_intlgregcal_create_instance_0_arg1; zend_string *attribute_Deprecated_func_intlgregcal_create_instance_0_arg1_str = zend_string_init("use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead", strlen("use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_intlgregcal_create_instance_0_arg1, attribute_Deprecated_func_intlgregcal_create_instance_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_intlgregcal_create_instance_0->args[1].value, &attribute_Deprecated_func_intlgregcal_create_instance_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_intlgregcal_create_instance_0->args[1].value, attribute_Deprecated_func_intlgregcal_create_instance_0_arg1_str); attribute_Deprecated_func_intlgregcal_create_instance_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/intl/rangeformatter/rangeformatter.stub.php b/ext/intl/rangeformatter/rangeformatter.stub.php new file mode 100644 index 000000000000..eae40b5a56c2 --- /dev/null +++ b/ext/intl/rangeformatter/rangeformatter.stub.php @@ -0,0 +1,61 @@ += 63 + /** @cvalue UNUM_RANGE_COLLAPSE_AUTO */ + public const int COLLAPSE_AUTO = UNKNOWN; + + /** @cvalue UNUM_RANGE_COLLAPSE_NONE */ + public const int COLLAPSE_NONE = UNKNOWN; + + /** @cvalue UNUM_RANGE_COLLAPSE_UNIT */ + public const int COLLAPSE_UNIT = UNKNOWN; + + /** @cvalue UNUM_RANGE_COLLAPSE_ALL */ + public const int COLLAPSE_ALL = UNKNOWN; + + /** @cvalue UNUM_IDENTITY_FALLBACK_SINGLE_VALUE */ + public const int IDENTITY_FALLBACK_SINGLE_VALUE = UNKNOWN; + + /** @cvalue UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE */ + public const int IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE = UNKNOWN; + + /** @cvalue UNUM_IDENTITY_FALLBACK_APPROXIMATELY */ + public const int IDENTITY_FALLBACK_APPROXIMATELY = UNKNOWN; + + /** @cvalue UNUM_IDENTITY_FALLBACK_RANGE */ + public const int IDENTITY_FALLBACK_RANGE = UNKNOWN; +#else + public const int COLLAPSE_AUTO = 0; + + public const int COLLAPSE_NONE = 1; + + public const int COLLAPSE_UNIT = 2; + + public const int COLLAPSE_ALL = 3; + + public const int IDENTITY_FALLBACK_SINGLE_VALUE = 0; + + public const int IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE = 1; + + public const int IDENTITY_FALLBACK_APPROXIMATELY = 2; + + public const int IDENTITY_FALLBACK_RANGE = 3; +#endif + + private function __construct() {} + + public static function createFromSkeleton(string $skeleton, string $locale, int $collapse, int $identityFallback): IntlNumberRangeFormatter {} + + public function format(float|int $start, float|int $end): string {} + + public function getErrorCode(): int {} + + public function getErrorMessage(): string {} +} diff --git a/ext/intl/rangeformatter/rangeformatter_arginfo.h b/ext/intl/rangeformatter/rangeformatter_arginfo.h new file mode 100644 index 000000000000..a08ffc314c56 --- /dev/null +++ b/ext/intl/rangeformatter/rangeformatter_arginfo.h @@ -0,0 +1,148 @@ +/* This is a generated file, edit rangeformatter.stub.php instead. + * Stub hash: 7029642524e32984e893e1e050a5e0bbf275c416 */ + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlNumberRangeFormatter___construct, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_IntlNumberRangeFormatter_createFromSkeleton, 0, 4, IntlNumberRangeFormatter, 0) + ZEND_ARG_TYPE_INFO(0, skeleton, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, collapse, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, identityFallback, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_IntlNumberRangeFormatter_format, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_MASK(0, start, MAY_BE_DOUBLE|MAY_BE_LONG, NULL) + ZEND_ARG_TYPE_MASK(0, end, MAY_BE_DOUBLE|MAY_BE_LONG, NULL) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_IntlNumberRangeFormatter_getErrorCode, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_IntlNumberRangeFormatter_getErrorMessage, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_METHOD(IntlNumberRangeFormatter, __construct); +ZEND_METHOD(IntlNumberRangeFormatter, createFromSkeleton); +ZEND_METHOD(IntlNumberRangeFormatter, format); +ZEND_METHOD(IntlNumberRangeFormatter, getErrorCode); +ZEND_METHOD(IntlNumberRangeFormatter, getErrorMessage); + +static const zend_function_entry class_IntlNumberRangeFormatter_methods[] = { + ZEND_ME(IntlNumberRangeFormatter, __construct, arginfo_class_IntlNumberRangeFormatter___construct, ZEND_ACC_PRIVATE) + ZEND_ME(IntlNumberRangeFormatter, createFromSkeleton, arginfo_class_IntlNumberRangeFormatter_createFromSkeleton, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(IntlNumberRangeFormatter, format, arginfo_class_IntlNumberRangeFormatter_format, ZEND_ACC_PUBLIC) + ZEND_ME(IntlNumberRangeFormatter, getErrorCode, arginfo_class_IntlNumberRangeFormatter_getErrorCode, ZEND_ACC_PUBLIC) + ZEND_ME(IntlNumberRangeFormatter, getErrorMessage, arginfo_class_IntlNumberRangeFormatter_getErrorMessage, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static zend_class_entry *register_class_IntlNumberRangeFormatter(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "IntlNumberRangeFormatter", class_IntlNumberRangeFormatter_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); +#if U_ICU_VERSION_MAJOR_NUM >= 63 + + zval const_COLLAPSE_AUTO_value; + ZVAL_LONG(&const_COLLAPSE_AUTO_value, UNUM_RANGE_COLLAPSE_AUTO); + zend_string *const_COLLAPSE_AUTO_name = zend_string_init_interned("COLLAPSE_AUTO", sizeof("COLLAPSE_AUTO") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_AUTO_name, &const_COLLAPSE_AUTO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_AUTO_name, true); + + zval const_COLLAPSE_NONE_value; + ZVAL_LONG(&const_COLLAPSE_NONE_value, UNUM_RANGE_COLLAPSE_NONE); + zend_string *const_COLLAPSE_NONE_name = zend_string_init_interned("COLLAPSE_NONE", sizeof("COLLAPSE_NONE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_NONE_name, &const_COLLAPSE_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_NONE_name, true); + + zval const_COLLAPSE_UNIT_value; + ZVAL_LONG(&const_COLLAPSE_UNIT_value, UNUM_RANGE_COLLAPSE_UNIT); + zend_string *const_COLLAPSE_UNIT_name = zend_string_init_interned("COLLAPSE_UNIT", sizeof("COLLAPSE_UNIT") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_UNIT_name, &const_COLLAPSE_UNIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_UNIT_name, true); + + zval const_COLLAPSE_ALL_value; + ZVAL_LONG(&const_COLLAPSE_ALL_value, UNUM_RANGE_COLLAPSE_ALL); + zend_string *const_COLLAPSE_ALL_name = zend_string_init_interned("COLLAPSE_ALL", sizeof("COLLAPSE_ALL") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_ALL_name, &const_COLLAPSE_ALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_ALL_name, true); + + zval const_IDENTITY_FALLBACK_SINGLE_VALUE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_SINGLE_VALUE_value, UNUM_IDENTITY_FALLBACK_SINGLE_VALUE); + zend_string *const_IDENTITY_FALLBACK_SINGLE_VALUE_name = zend_string_init_interned("IDENTITY_FALLBACK_SINGLE_VALUE", sizeof("IDENTITY_FALLBACK_SINGLE_VALUE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_SINGLE_VALUE_name, &const_IDENTITY_FALLBACK_SINGLE_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_SINGLE_VALUE_name, true); + + zval const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value, UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE); + zend_string *const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name = zend_string_init_interned("IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE", sizeof("IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name, &const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name, true); + + zval const_IDENTITY_FALLBACK_APPROXIMATELY_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_APPROXIMATELY_value, UNUM_IDENTITY_FALLBACK_APPROXIMATELY); + zend_string *const_IDENTITY_FALLBACK_APPROXIMATELY_name = zend_string_init_interned("IDENTITY_FALLBACK_APPROXIMATELY", sizeof("IDENTITY_FALLBACK_APPROXIMATELY") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_APPROXIMATELY_name, &const_IDENTITY_FALLBACK_APPROXIMATELY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_APPROXIMATELY_name, true); + + zval const_IDENTITY_FALLBACK_RANGE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_RANGE_value, UNUM_IDENTITY_FALLBACK_RANGE); + zend_string *const_IDENTITY_FALLBACK_RANGE_name = zend_string_init_interned("IDENTITY_FALLBACK_RANGE", sizeof("IDENTITY_FALLBACK_RANGE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_RANGE_name, &const_IDENTITY_FALLBACK_RANGE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_RANGE_name, true); +#endif +#if !(U_ICU_VERSION_MAJOR_NUM >= 63) + + zval const_COLLAPSE_AUTO_value; + ZVAL_LONG(&const_COLLAPSE_AUTO_value, 0); + zend_string *const_COLLAPSE_AUTO_name = zend_string_init_interned("COLLAPSE_AUTO", sizeof("COLLAPSE_AUTO") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_AUTO_name, &const_COLLAPSE_AUTO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_AUTO_name, true); + + zval const_COLLAPSE_NONE_value; + ZVAL_LONG(&const_COLLAPSE_NONE_value, 1); + zend_string *const_COLLAPSE_NONE_name = zend_string_init_interned("COLLAPSE_NONE", sizeof("COLLAPSE_NONE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_NONE_name, &const_COLLAPSE_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_NONE_name, true); + + zval const_COLLAPSE_UNIT_value; + ZVAL_LONG(&const_COLLAPSE_UNIT_value, 2); + zend_string *const_COLLAPSE_UNIT_name = zend_string_init_interned("COLLAPSE_UNIT", sizeof("COLLAPSE_UNIT") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_UNIT_name, &const_COLLAPSE_UNIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_UNIT_name, true); + + zval const_COLLAPSE_ALL_value; + ZVAL_LONG(&const_COLLAPSE_ALL_value, 3); + zend_string *const_COLLAPSE_ALL_name = zend_string_init_interned("COLLAPSE_ALL", sizeof("COLLAPSE_ALL") - 1, true); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_ALL_name, &const_COLLAPSE_ALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_COLLAPSE_ALL_name, true); + + zval const_IDENTITY_FALLBACK_SINGLE_VALUE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_SINGLE_VALUE_value, 0); + zend_string *const_IDENTITY_FALLBACK_SINGLE_VALUE_name = zend_string_init_interned("IDENTITY_FALLBACK_SINGLE_VALUE", sizeof("IDENTITY_FALLBACK_SINGLE_VALUE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_SINGLE_VALUE_name, &const_IDENTITY_FALLBACK_SINGLE_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_SINGLE_VALUE_name, true); + + zval const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value, 1); + zend_string *const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name = zend_string_init_interned("IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE", sizeof("IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name, &const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name, true); + + zval const_IDENTITY_FALLBACK_APPROXIMATELY_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_APPROXIMATELY_value, 2); + zend_string *const_IDENTITY_FALLBACK_APPROXIMATELY_name = zend_string_init_interned("IDENTITY_FALLBACK_APPROXIMATELY", sizeof("IDENTITY_FALLBACK_APPROXIMATELY") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_APPROXIMATELY_name, &const_IDENTITY_FALLBACK_APPROXIMATELY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_APPROXIMATELY_name, true); + + zval const_IDENTITY_FALLBACK_RANGE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_RANGE_value, 3); + zend_string *const_IDENTITY_FALLBACK_RANGE_name = zend_string_init_interned("IDENTITY_FALLBACK_RANGE", sizeof("IDENTITY_FALLBACK_RANGE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_RANGE_name, &const_IDENTITY_FALLBACK_RANGE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_IDENTITY_FALLBACK_RANGE_name, true); +#endif + + return class_entry; +} diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp new file mode 100644 index 000000000000..6921791e588f --- /dev/null +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -0,0 +1,226 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Bogdan Ungureanu | + +----------------------------------------------------------------------+ +*/ + +extern "C" { + #include "php.h" + #include "zend_API.h" + #include "../intl_common.h" +} + +#if U_ICU_VERSION_MAJOR_NUM >= 63 +#include +#include +#include +#include +#include "../intl_convertcpp.h" + +extern "C" { + #include "../intl_error.h" + #include "../php_intl.h" + #include "../intl_data.h" + #include "rangeformatter_arginfo.h" + #include "rangeformatter_class.h" +} + +using icu::number::NumberRangeFormatter; +using icu::number::NumberFormatter; +using icu::number::UnlocalizedNumberFormatter; +using icu::number::LocalizedNumberRangeFormatter; +using icu::UnicodeString; +using icu::MeasureUnit; + +static zend_object_handlers rangeformatter_handlers; +zend_class_entry *class_entry_IntlNumberRangeFormatter; + +zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce) +{ + IntlNumberRangeFormatter_object* intern; + + intern = reinterpret_cast(zend_object_alloc(sizeof(IntlNumberRangeFormatter_object), ce)); + zend_object_std_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); + + // Initialize rangeformatter_data structure + intl_error_init(&intern->nrf_data.error); + intern->nrf_data.unumrf = nullptr; + + intern->zo.handlers = &rangeformatter_handlers; + + return &intern->zo; +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, __construct) +{ + ZEND_PARSE_PARAMETERS_NONE(); + zend_throw_error(NULL, "Cannot directly construct %s, use createFromSkeleton method instead", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)); +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) +{ + char* skeleton; + char* locale; + size_t locale_len; + size_t skeleton_len; + zend_long collapse; + zend_long identityFallback; + + ZEND_PARSE_PARAMETERS_START(4,4) + Z_PARAM_STRING(skeleton, skeleton_len) + Z_PARAM_STRING(locale, locale_len) + Z_PARAM_LONG(collapse) + Z_PARAM_LONG(identityFallback) + ZEND_PARSE_PARAMETERS_END(); + + if (locale_len == 0) { + locale = (char *)intl_locale_get_default(); + } + + if (locale_len > INTL_MAX_LOCALE_LEN) { + zend_argument_value_error(2, "must be no longer than %d characters", INTL_MAX_LOCALE_LEN); + RETURN_THROWS(); + } + + if (icu::Locale(locale).getISO3Language()[0] == '\0') { + zend_argument_value_error(2, "\"%s\" is invalid", locale); + RETURN_THROWS(); + } + + if (collapse != UNUM_RANGE_COLLAPSE_AUTO && collapse != UNUM_RANGE_COLLAPSE_NONE && collapse != UNUM_RANGE_COLLAPSE_UNIT && collapse != UNUM_RANGE_COLLAPSE_ALL) { + zend_argument_value_error(3, "must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL"); + RETURN_THROWS(); + } + + if (identityFallback != UNUM_IDENTITY_FALLBACK_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY && identityFallback != UNUM_IDENTITY_FALLBACK_RANGE) { + zend_argument_value_error(4, "must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE"); + RETURN_THROWS(); + } + + UErrorCode status = U_ZERO_ERROR; + + UnicodeString skeleton_ustr(skeleton, skeleton_len); + + UnlocalizedNumberFormatter nf = NumberFormatter::forSkeleton(skeleton_ustr, status); + + if (U_FAILURE(status)) { + // override error level and use exceptions + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + + intl_error_set(NULL, status, "Failed to create the number skeleton"); + + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; + } + + LocalizedNumberRangeFormatter* nrf = new LocalizedNumberRangeFormatter( + NumberRangeFormatter::with() + .locale(locale) + .numberFormatterBoth(nf) + .collapse(static_cast(collapse)) + .identityFallback(static_cast(identityFallback)) + ); + + zend_object* obj = IntlNumberRangeFormatter_object_create(class_entry_IntlNumberRangeFormatter); + + RANGEFORMATTER_OBJECT(php_intl_numberrangeformatter_fetch_object(obj)) = nrf; + + RETURN_OBJ(obj); +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) +{ + zval *start; + zval *end; + + IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_NUMBER(start) + Z_PARAM_NUMBER(end) + ZEND_PARSE_PARAMETERS_END(); + + UErrorCode error = U_ZERO_ERROR; + + icu::Formattable start_formattable(Z_TYPE_P(start) == IS_DOUBLE ? Z_DVAL_P(start) : Z_LVAL_P(start)); + icu::Formattable end_formattable(Z_TYPE_P(end) == IS_DOUBLE ? Z_DVAL_P(end) : Z_LVAL_P(end)); + + UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start_formattable, end_formattable, error).toString(error); + + // override error level and use exceptions + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + + if (U_FAILURE(error)) { + intl_error_set(NULL, error, "Failed to format number range"); + } + + zend_string *ret = intl_charFromString(result, &error); + + if (U_FAILURE(error)) { + intl_error_set(NULL, error, "Failed to convert result to UTF-8"); + } + + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; + + RETVAL_NEW_STR(ret); +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorCode) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); + + RETURN_LONG(intl_error_get_code(&obj->nrf_data.error)); +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorMessage) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); + + RETURN_STR(intl_error_get_message(&obj->nrf_data.error)); +} + +void IntlNumberRangeFormatter_object_free(zend_object *object) +{ + IntlNumberRangeFormatter_object* nfo = php_intl_numberrangeformatter_fetch_object(object); + + if (nfo->nrf_data.unumrf) { + delete nfo->nrf_data.unumrf; + nfo->nrf_data.unumrf = nullptr; + } + + intl_error_reset(&nfo->nrf_data.error); + + zend_object_std_dtor(&nfo->zo); +} + +void rangeformatter_register_class(void) +{ + class_entry_IntlNumberRangeFormatter = register_class_IntlNumberRangeFormatter(); + class_entry_IntlNumberRangeFormatter->create_object = IntlNumberRangeFormatter_object_create; + + memcpy(&rangeformatter_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + rangeformatter_handlers.offset = offsetof(IntlNumberRangeFormatter_object, zo); + rangeformatter_handlers.free_obj = IntlNumberRangeFormatter_object_free; + rangeformatter_handlers.clone_obj = NULL; +} +#endif diff --git a/ext/intl/rangeformatter/rangeformatter_class.h b/ext/intl/rangeformatter/rangeformatter_class.h new file mode 100644 index 000000000000..31b31d784282 --- /dev/null +++ b/ext/intl/rangeformatter/rangeformatter_class.h @@ -0,0 +1,53 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Bogdan Ungureanu | + +----------------------------------------------------------------------+ +*/ + +#ifndef RANGEFORMATTER_CLASS_H +#define RANGEFORMATTER_CLASS_H + +#include + +#ifdef __cplusplus +using icu::number::LocalizedNumberRangeFormatter; +#else +typedef void LocalizedNumberRangeFormatter; +#endif + +typedef struct { + // error handling + intl_error error; + + // formatter handling + LocalizedNumberRangeFormatter* unumrf; +} rangeformatter_data; + +typedef struct { + rangeformatter_data nrf_data; + zend_object zo; +} IntlNumberRangeFormatter_object; + +static inline IntlNumberRangeFormatter_object *php_intl_numberrangeformatter_fetch_object(zend_object *obj) { + return ZEND_CONTAINER_OF(obj, IntlNumberRangeFormatter_object, zo); +} + +#define Z_INTL_RANGEFORMATTER_P(zv) php_intl_numberrangeformatter_fetch_object(Z_OBJ_P(zv)) + +#define RANGEFORMATTER_ERROR(nfo) (nfo)->nrf_data.error +#define RANGEFORMATTER_ERROR_P(nfo) &(RANGEFORMATTER_ERROR(nfo)) + +#define RANGEFORMATTER_OBJECT(nfo) (nfo)->nrf_data.unumrf + + +void rangeformatter_register_class(void); + +#endif diff --git a/ext/intl/resourcebundle/resourcebundle.c b/ext/intl/resourcebundle/resourcebundle.c deleted file mode 100644 index e29596f01872..000000000000 --- a/ext/intl/resourcebundle/resourcebundle.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Hans-Peter Oeri (University of St.Gallen) | - +----------------------------------------------------------------------+ - */ - -#include - -#include -#include - -#include "intl_convert.h" -#include "intl_data.h" -#include "resourcebundle/resourcebundle_class.h" - -/* {{{ ResourceBundle_extract_value */ -void resourcebundle_extract_value( zval *return_value, ResourceBundle_object *source ) -{ - UResType restype; - const UChar* ufield; - const uint8_t* bfield; - const int32_t* vfield; - int32_t ilen; - int i; - zend_long lfield; - ResourceBundle_object* newrb; - - restype = ures_getType( source->child ); - switch (restype) - { - case URES_STRING: - ufield = ures_getString( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); - INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve string value"); - INTL_METHOD_RETVAL_UTF8(source, (UChar *)ufield, ilen, 0); - break; - - case URES_BINARY: - bfield = ures_getBinary( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); - INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve binary value"); - ZVAL_STRINGL( return_value, (char *) bfield, ilen ); - break; - - case URES_INT: - lfield = ures_getInt( source->child, &INTL_DATA_ERROR_CODE(source) ); - INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve integer value"); - ZVAL_LONG( return_value, lfield ); - break; - - case URES_INT_VECTOR: - vfield = ures_getIntVector( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); - INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve vector value"); - array_init_size( return_value, ilen ); - zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); - for (i=0; ime = source->child; - source->child = NULL; - intl_errors_reset(INTL_DATA_ERROR_P(source)); - break; - EMPTY_SWITCH_DEFAULT_CASE(); - } -} -/* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle.cpp b/ext/intl/resourcebundle/resourcebundle.cpp new file mode 100644 index 000000000000..d3a41b7c8d92 --- /dev/null +++ b/ext/intl/resourcebundle/resourcebundle.cpp @@ -0,0 +1,80 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Hans-Peter Oeri (University of St.Gallen) | + +----------------------------------------------------------------------+ + */ + +#include + +#include +#include + +extern "C" { +#include "intl_convert.h" +#include "intl_data.h" +#include "resourcebundle/resourcebundle_class.h" +} + +/* {{{ ResourceBundle_extract_value */ +U_CFUNC void resourcebundle_extract_value( zval *return_value, ResourceBundle_object *source ) +{ + UResType restype; + const UChar* ufield; + const uint8_t* bfield; + const int32_t* vfield; + int32_t ilen; + int i; + zend_long lfield; + ResourceBundle_object* newrb; + + restype = ures_getType( source->child ); + switch (restype) + { + case URES_STRING: + ufield = ures_getString( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); + INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve string value"); + INTL_METHOD_RETVAL_UTF8(source, (UChar *)ufield, ilen, 0); + break; + + case URES_BINARY: + bfield = ures_getBinary( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); + INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve binary value"); + ZVAL_STRINGL( return_value, (char *) bfield, ilen ); + break; + + case URES_INT: + lfield = ures_getInt( source->child, &INTL_DATA_ERROR_CODE(source) ); + INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve integer value"); + ZVAL_LONG( return_value, lfield ); + break; + + case URES_INT_VECTOR: + vfield = ures_getIntVector( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); + INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve vector value"); + array_init_size( return_value, ilen ); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); + for (i=0; ime = source->child; + source->child = NULL; + intl_errors_reset(INTL_DATA_ERROR_P(source)); + break; + default: ZEND_UNREACHABLE(); + } +} +/* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle.h b/ext/intl/resourcebundle/resourcebundle.h index ddcf75b8c50a..e7c79c480d35 100644 --- a/ext/intl/resourcebundle/resourcebundle.h +++ b/ext/intl/resourcebundle/resourcebundle.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ @@ -21,6 +21,12 @@ #include "resourcebundle/resourcebundle_class.h" +#ifdef __cplusplus +extern "C" { +#endif void resourcebundle_extract_value( zval *target, ResourceBundle_object *source); +#ifdef __cplusplus +} +#endif #endif // #ifndef RESOURCEBUNDLE_CLASS_H diff --git a/ext/intl/resourcebundle/resourcebundle_arginfo.h b/ext/intl/resourcebundle/resourcebundle_arginfo.h index f52de6314aa5..3f82668277ae 100644 --- a/ext/intl/resourcebundle/resourcebundle_arginfo.h +++ b/ext/intl/resourcebundle/resourcebundle_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit resourcebundle.stub.php instead. * Stub hash: e302e5ca1abcb9b52e3c14abbd38b9e8f1461390 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ResourceBundle___construct, 0, 0, 2) diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c deleted file mode 100644 index c64bf1d45184..000000000000 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Hans-Peter Oeri (University of St.Gallen) | - +----------------------------------------------------------------------+ - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "php_intl.h" -#include "intl_data.h" -#include "intl_common.h" - -#include "resourcebundle/resourcebundle.h" -#include "resourcebundle/resourcebundle_iterator.h" -#include "resourcebundle/resourcebundle_class.h" -#include "resourcebundle/resourcebundle_arginfo.h" - -zend_class_entry *ResourceBundle_ce_ptr = NULL; - -static zend_object_handlers ResourceBundle_object_handlers; - -/* {{{ ResourceBundle_object_free */ -static void ResourceBundle_object_free( zend_object *object ) -{ - ResourceBundle_object *rb = php_intl_resourcebundle_fetch_object(object); - - // only free local errors - intl_error_reset( INTL_DATA_ERROR_P(rb) ); - - if (rb->me) { - ures_close( rb->me ); - } - if (rb->child) { - ures_close( rb->child ); - } - - zend_object_std_dtor( &rb->zend ); -} -/* }}} */ - -/* {{{ ResourceBundle_object_create */ -static zend_object *ResourceBundle_object_create( zend_class_entry *ce ) -{ - ResourceBundle_object *rb; - - rb = zend_object_alloc(sizeof(ResourceBundle_object), ce); - - zend_object_std_init( &rb->zend, ce ); - object_properties_init( &rb->zend, ce); - - intl_error_init( INTL_DATA_ERROR_P(rb) ); - rb->me = NULL; - rb->child = NULL; - - return &rb->zend; -} -/* }}} */ - -/* {{{ ResourceBundle_ctor */ -static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_error_handling *error_handling, bool *error_handling_replaced) -{ - char *bundlename; - size_t bundlename_len = 0; - char *locale; - size_t locale_len = 0; - bool fallback = true; - - zval *object = return_value; - ResourceBundle_object *rb = Z_INTL_RESOURCEBUNDLE_P( object ); - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING_OR_NULL(locale, locale_len) - Z_PARAM_STRING_OR_NULL(bundlename, bundlename_len) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(fallback) - ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - - if (error_handling != NULL) { - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, error_handling); - *error_handling_replaced = 1; - } - - if (rb->me) { - zend_throw_error(NULL, "ResourceBundle object is already constructed"); - return FAILURE; - } - - INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); - - if (locale == NULL) { - locale = (char *)intl_locale_get_default(); - } - - if (bundlename_len >= MAXPATHLEN) { - zend_argument_value_error(2, "is too long"); - return FAILURE; - } - - if (fallback) { - rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); - } else { - rb->me = ures_openDirect(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); - } - - INTL_CTOR_CHECK_STATUS(rb, "resourcebundle_ctor: Cannot load libICU resource bundle"); - - if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || - INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) { - char *pbuf; - intl_errors_set_code(NULL, INTL_DATA_ERROR_CODE(rb)); - spprintf(&pbuf, 0, "resourcebundle_ctor: Cannot load libICU resource " - "'%s' without fallback from %s to %s", - bundlename ? bundlename : "(default data)", locale, - ures_getLocaleByType( - rb->me, ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(rb))); - intl_errors_set_custom_msg(INTL_DATA_ERROR_P(rb), pbuf, 1); - efree(pbuf); - return FAILURE; - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ ResourceBundle object constructor */ -PHP_METHOD( ResourceBundle, __construct ) -{ - zend_error_handling error_handling; - bool error_handling_replaced = 0; - - return_value = ZEND_THIS; - if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, &error_handling, &error_handling_replaced) == FAILURE) { - if (!EG(exception)) { - zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0); - } - } - if (error_handling_replaced) { - zend_restore_error_handling(&error_handling); - } -} -/* }}} */ - -/* {{{ */ -PHP_FUNCTION( resourcebundle_create ) -{ - object_init_ex( return_value, ResourceBundle_ce_ptr ); - if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, NULL, NULL) == FAILURE) { - zval_ptr_dtor(return_value); - RETURN_NULL(); - } -} -/* }}} */ - -/* {{{ resourcebundle_array_fetch */ -static zval *resource_bundle_array_fetch( - zend_object *object, zend_string *offset_str, zend_long offset_int, - zval *return_value, bool fallback, uint32_t offset_arg_num) -{ - int32_t index = 0; - char *key = NULL; - bool is_numeric = offset_str == NULL; - char *pbuf; - ResourceBundle_object *rb; - - rb = php_intl_resourcebundle_fetch_object(object); - intl_error_reset(NULL); - intl_error_reset(INTL_DATA_ERROR_P(rb)); - - if (offset_str) { - if (UNEXPECTED(ZSTR_LEN(offset_str) == 0)) { - if (offset_arg_num) { - zend_argument_must_not_be_empty_error(offset_arg_num); - } else { - zend_value_error("Offset must not be empty"); - } - return NULL; - } - key = ZSTR_VAL(offset_str); - rb->child = ures_getByKey(rb->me, key, rb->child, &INTL_DATA_ERROR_CODE(rb) ); - } else { - if (UNEXPECTED(offset_int < (zend_long)INT32_MIN || offset_int > (zend_long)INT32_MAX)) { - if (offset_arg_num) { - zend_argument_value_error(offset_arg_num, "index must be between %d and %d", INT32_MIN, INT32_MAX); - } else { - zend_value_error("Index must be between %d and %d", INT32_MIN, INT32_MAX); - } - return NULL; - } - index = (int32_t)offset_int; - rb->child = ures_getByIndex(rb->me, index, rb->child, &INTL_DATA_ERROR_CODE(rb)); - } - - intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) ); - if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) { - if (is_numeric) { - spprintf( &pbuf, 0, "Cannot load resource element %d", index ); - } else { - spprintf( &pbuf, 0, "Cannot load resource element '%s'", key ); - } - intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1 ); - efree(pbuf); - RETVAL_NULL(); - return return_value; - } - - if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) { - UErrorCode icuerror; - const char * locale = ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &icuerror ); - if (is_numeric) { - spprintf(&pbuf, 0, "Cannot load element %d without fallback from to %s", index, locale); - } else { - spprintf(&pbuf, 0, "Cannot load element '%s' without fallback from to %s", key, locale); - } - intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf, 1); - efree(pbuf); - RETVAL_NULL(); - return return_value; - } - - resourcebundle_extract_value( return_value, rb ); - return return_value; -} -/* }}} */ - -/* {{{ resourcebundle_array_get */ -zval *resourcebundle_array_get(zend_object *object, zval *offset, int type, zval *rv) -{ - if (offset == NULL) { - zend_throw_error(NULL, "Cannot apply [] to ResourceBundle object"); - return NULL; - } - - ZVAL_DEREF(offset); - if (Z_TYPE_P(offset) == IS_LONG) { - return resource_bundle_array_fetch(object, /* offset_str */ NULL, Z_LVAL_P(offset), rv, /* fallback */ true, /* arg_num */ 0); - } else if (Z_TYPE_P(offset) == IS_STRING) { - return resource_bundle_array_fetch(object, Z_STR_P(offset), /* offset_int */ 0, rv, /* fallback */ true, /* arg_num */ 0); - } else { - zend_illegal_container_offset(object->ce->name, offset, type); - return NULL; - } -} -/* }}} */ - -/* {{{ Get resource identified by numerical index or key name. */ -PHP_FUNCTION( resourcebundle_get ) -{ - bool fallback = true; - zend_object *resource_bundle = NULL; - zend_string *offset_str = NULL; - zend_long offset_long = 0; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_OBJ_OF_CLASS(resource_bundle, ResourceBundle_ce_ptr) - Z_PARAM_STR_OR_LONG(offset_str, offset_long) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(fallback) - ZEND_PARSE_PARAMETERS_END(); - - zval *retval = resource_bundle_array_fetch(resource_bundle, offset_str, offset_long, return_value, fallback, /* arg_num */ 2); - if (!retval) { - RETURN_THROWS(); - } -} -/* }}} */ - -PHP_METHOD(ResourceBundle , get) -{ - bool fallback = true; - zend_string *offset_str = NULL; - zend_long offset_long = 0; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR_OR_LONG(offset_str, offset_long) - Z_PARAM_OPTIONAL - Z_PARAM_BOOL(fallback) - ZEND_PARSE_PARAMETERS_END(); - - zval *retval = resource_bundle_array_fetch(Z_OBJ_P(ZEND_THIS), offset_str, offset_long, return_value, fallback, /* arg_num */ 1); - if (!retval) { - RETURN_THROWS(); - } -} -/* }}} */ - -/* {{{ resourcebundle_array_count */ -static zend_result resourcebundle_array_count(zend_object *object, zend_long *count) -{ - ResourceBundle_object *rb = php_intl_resourcebundle_fetch_object(object); - - if (rb->me == NULL) { - intl_errors_set(&rb->error, U_ILLEGAL_ARGUMENT_ERROR, - "Found unconstructed ResourceBundle", 0); - return 0; - } - - *count = ures_getSize( rb->me ); - - return SUCCESS; -} -/* }}} */ - -/* {{{ Get resources count */ -PHP_FUNCTION( resourcebundle_count ) -{ - int32_t len; - RESOURCEBUNDLE_METHOD_INIT_VARS; - - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, ResourceBundle_ce_ptr ) == FAILURE ) { - RETURN_THROWS(); - } - - RESOURCEBUNDLE_METHOD_FETCH_OBJECT; - - len = ures_getSize( rb->me ); - RETURN_LONG( len ); -} - -/* {{{ Get available locales from ResourceBundle name */ -PHP_FUNCTION( resourcebundle_locales ) -{ - char * bundlename; - size_t bundlename_len = 0; - const char * entry; - int entry_len; - UEnumeration *icuenum; - UErrorCode icuerror = U_ZERO_ERROR; - - intl_errors_reset( NULL ); - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(bundlename, bundlename_len) - ZEND_PARSE_PARAMETERS_END(); - - if (bundlename_len >= MAXPATHLEN) { - zend_argument_value_error(1, "is too long"); - RETURN_THROWS(); - } - - if(bundlename_len == 0) { - // fetch default locales list - bundlename = NULL; - } - - icuenum = ures_openAvailableLocales( bundlename, &icuerror ); - INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list"); - - uenum_reset( icuenum, &icuerror ); - INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list"); - - array_init( return_value ); - while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) { - add_next_index_stringl( return_value, (char *) entry, entry_len); - } - uenum_close( icuenum ); -} -/* }}} */ - -/* {{{ Get text description for ResourceBundle's last error code. */ -PHP_FUNCTION( resourcebundle_get_error_code ) -{ - RESOURCEBUNDLE_METHOD_INIT_VARS; - - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, ResourceBundle_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - rb = Z_INTL_RESOURCEBUNDLE_P( object ); - - RETURN_LONG(INTL_DATA_ERROR_CODE(rb)); -} -/* }}} */ - -/* {{{ Get text description for ResourceBundle's last error. */ -PHP_FUNCTION( resourcebundle_get_error_message ) -{ - zend_string* message = NULL; - RESOURCEBUNDLE_METHOD_INIT_VARS; - - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, ResourceBundle_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - rb = Z_INTL_RESOURCEBUNDLE_P( object ); - message = intl_error_get_message(INTL_DATA_ERROR_P(rb)); - RETURN_STR(message); -} -/* }}} */ - -PHP_METHOD(ResourceBundle, getIterator) { - ZEND_PARSE_PARAMETERS_NONE(); - - zend_create_internal_iterator_zval(return_value, ZEND_THIS); -} - -/* {{{ resourcebundle_register_class - * Initialize 'ResourceBundle' class - */ -void resourcebundle_register_class( void ) -{ - ResourceBundle_ce_ptr = register_class_ResourceBundle(zend_ce_aggregate, zend_ce_countable); - ResourceBundle_ce_ptr->create_object = ResourceBundle_object_create; - ResourceBundle_ce_ptr->default_object_handlers = &ResourceBundle_object_handlers; - ResourceBundle_ce_ptr->get_iterator = resourcebundle_get_iterator; - - ResourceBundle_object_handlers = std_object_handlers; - ResourceBundle_object_handlers.offset = XtOffsetOf(ResourceBundle_object, zend); - ResourceBundle_object_handlers.clone_obj = NULL; /* ICU ResourceBundle has no clone implementation */ - ResourceBundle_object_handlers.free_obj = ResourceBundle_object_free; - ResourceBundle_object_handlers.read_dimension = resourcebundle_array_get; - ResourceBundle_object_handlers.count_elements = resourcebundle_array_count; -} -/* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle_class.cpp b/ext/intl/resourcebundle/resourcebundle_class.cpp new file mode 100644 index 000000000000..43823137e605 --- /dev/null +++ b/ext/intl/resourcebundle/resourcebundle_class.cpp @@ -0,0 +1,433 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Hans-Peter Oeri (University of St.Gallen) | + +----------------------------------------------------------------------+ + */ + +#include +#include +#include + + +extern "C" { +#include +#include +} + +#include +#include + +extern "C" { +#include "php_intl.h" +#include "intl_data.h" +#include "intl_common.h" +#include "resourcebundle/resourcebundle.h" +#include "resourcebundle/resourcebundle_iterator.h" +#include "resourcebundle/resourcebundle_class.h" +#include "resourcebundle/resourcebundle_arginfo.h" +} + +zend_class_entry *ResourceBundle_ce_ptr = NULL; + +static zend_object_handlers ResourceBundle_object_handlers; + +/* {{{ ResourceBundle_object_free */ +static void ResourceBundle_object_free( zend_object *object ) +{ + ResourceBundle_object *rb = php_intl_resourcebundle_fetch_object(object); + + // only free local errors + intl_error_reset( INTL_DATA_ERROR_P(rb) ); + + if (rb->me) { + ures_close( rb->me ); + } + if (rb->child) { + ures_close( rb->child ); + } + + zend_object_std_dtor( &rb->zend ); +} +/* }}} */ + +/* {{{ ResourceBundle_object_create */ +static zend_object *ResourceBundle_object_create( zend_class_entry *ce ) +{ + ResourceBundle_object *rb; + + rb = reinterpret_cast(zend_object_alloc(sizeof(ResourceBundle_object), ce)); + + zend_object_std_init( &rb->zend, ce ); + object_properties_init( &rb->zend, ce); + + intl_error_init( INTL_DATA_ERROR_P(rb) ); + rb->me = NULL; + rb->child = NULL; + + return &rb->zend; +} +/* }}} */ + +/* {{{ ResourceBundle_ctor */ +static zend_result resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) +{ + char *bundlename; + size_t bundlename_len = 0; + char *locale; + size_t locale_len = 0; + bool fallback = true; + + zval *object = return_value; + ResourceBundle_object *rb = Z_INTL_RESOURCEBUNDLE_P( object ); + + intl_error_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STRING_OR_NULL(locale, locale_len) + Z_PARAM_STRING_OR_NULL(bundlename, bundlename_len) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(fallback) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + + if (rb->me) { + zend_throw_error(NULL, "ResourceBundle object is already constructed"); + return FAILURE; + } + + INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); + + if (locale == NULL) { + locale = (char *)intl_locale_get_default(); + } + + if (bundlename_len >= MAXPATHLEN) { + zend_argument_value_error(2, "is too long"); + return FAILURE; + } + + if (fallback) { + rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); + } else { + rb->me = ures_openDirect(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); + } + + INTL_CTOR_CHECK_STATUS(rb, "Cannot load libICU resource bundle"); + + if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || + INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) { + char *pbuf; + intl_errors_set_code(NULL, INTL_DATA_ERROR_CODE(rb)); + spprintf(&pbuf, 0, "Cannot load libICU resource " + "'%s' without fallback from %s to %s", + bundlename ? bundlename : "(default data)", locale, + ures_getLocaleByType( + rb->me, ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(rb))); + intl_errors_set_custom_msg(INTL_DATA_ERROR_P(rb), pbuf); + efree(pbuf); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ ResourceBundle object constructor */ +PHP_METHOD( ResourceBundle, __construct ) +{ + const bool old_use_exception = INTL_G(use_exceptions); + const zend_long old_error_level = INTL_G(error_level); + INTL_G(use_exceptions) = true; + INTL_G(error_level) = 0; + + return_value = ZEND_THIS; + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + ZEND_ASSERT(EG(exception)); + } + INTL_G(use_exceptions) = old_use_exception; + INTL_G(error_level) = old_error_level; +} +/* }}} */ + +/* {{{ */ +U_CFUNC PHP_FUNCTION( resourcebundle_create ) +{ + object_init_ex( return_value, ResourceBundle_ce_ptr ); + if (resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + zval_ptr_dtor(return_value); + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ resourcebundle_array_fetch */ +static zval *resource_bundle_array_fetch( + zend_object *object, zend_string *offset_str, zend_long offset_int, + zval *return_value, bool fallback, uint32_t offset_arg_num) +{ + int32_t index = 0; + char *key = NULL; + bool is_numeric = offset_str == NULL; + char *pbuf; + ResourceBundle_object *rb; + + rb = php_intl_resourcebundle_fetch_object(object); + intl_error_reset(NULL); + intl_error_reset(INTL_DATA_ERROR_P(rb)); + + if (offset_str) { + if (UNEXPECTED(ZSTR_LEN(offset_str) == 0)) { + if (offset_arg_num) { + zend_argument_must_not_be_empty_error(offset_arg_num); + } else { + zend_value_error("Offset must not be empty"); + } + return NULL; + } + key = ZSTR_VAL(offset_str); + rb->child = ures_getByKey(rb->me, key, rb->child, &INTL_DATA_ERROR_CODE(rb) ); + } else { + if (UNEXPECTED(offset_int < (zend_long)INT32_MIN || offset_int > (zend_long)INT32_MAX)) { + if (offset_arg_num) { + zend_argument_value_error(offset_arg_num, "index must be between %d and %d", INT32_MIN, INT32_MAX); + } else { + zend_value_error("Index must be between %d and %d", INT32_MIN, INT32_MAX); + } + return NULL; + } + index = (int32_t)offset_int; + rb->child = ures_getByIndex(rb->me, index, rb->child, &INTL_DATA_ERROR_CODE(rb)); + } + + intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) ); + if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) { + if (is_numeric) { + spprintf( &pbuf, 0, "Cannot load resource element %d", index ); + } else { + spprintf( &pbuf, 0, "Cannot load resource element '%s'", key ); + } + intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf); + efree(pbuf); + RETVAL_NULL(); + return return_value; + } + + if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING || INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) { + UErrorCode icuerror; + const char * locale = ures_getLocaleByType( rb->me, ULOC_ACTUAL_LOCALE, &icuerror ); + if (is_numeric) { + spprintf(&pbuf, 0, "Cannot load element %d without fallback from to %s", index, locale); + } else { + spprintf(&pbuf, 0, "Cannot load element '%s' without fallback from to %s", key, locale); + } + intl_errors_set_custom_msg( INTL_DATA_ERROR_P(rb), pbuf); + efree(pbuf); + RETVAL_NULL(); + return return_value; + } + + resourcebundle_extract_value( return_value, rb ); + return return_value; +} +/* }}} */ + +/* {{{ resourcebundle_array_get */ +U_CFUNC zval *resourcebundle_array_get(zend_object *object, zval *offset, int type, zval *rv) +{ + if (offset == NULL) { + zend_throw_error(NULL, "Cannot apply [] to ResourceBundle object"); + return NULL; + } + + ZVAL_DEREF(offset); + if (Z_TYPE_P(offset) == IS_LONG) { + return resource_bundle_array_fetch(object, /* offset_str */ NULL, Z_LVAL_P(offset), rv, /* fallback */ true, /* arg_num */ 0); + } else if (Z_TYPE_P(offset) == IS_STRING) { + return resource_bundle_array_fetch(object, Z_STR_P(offset), /* offset_int */ 0, rv, /* fallback */ true, /* arg_num */ 0); + } else { + zend_illegal_container_offset(object->ce->name, offset, type); + return NULL; + } +} +/* }}} */ + +/* {{{ Get resource identified by numerical index or key name. */ +U_CFUNC PHP_FUNCTION( resourcebundle_get ) +{ + bool fallback = true; + zend_object *resource_bundle = NULL; + zend_string *offset_str = NULL; + zend_long offset_long = 0; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_OBJ_OF_CLASS(resource_bundle, ResourceBundle_ce_ptr) + Z_PARAM_STR_OR_LONG(offset_str, offset_long) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(fallback) + ZEND_PARSE_PARAMETERS_END(); + + zval *retval = resource_bundle_array_fetch(resource_bundle, offset_str, offset_long, return_value, fallback, /* arg_num */ 2); + if (!retval) { + RETURN_THROWS(); + } +} +/* }}} */ + +PHP_METHOD(ResourceBundle , get) +{ + bool fallback = true; + zend_string *offset_str = NULL; + zend_long offset_long = 0; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_LONG(offset_str, offset_long) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(fallback) + ZEND_PARSE_PARAMETERS_END(); + + zval *retval = resource_bundle_array_fetch(Z_OBJ_P(ZEND_THIS), offset_str, offset_long, return_value, fallback, /* arg_num */ 1); + if (!retval) { + RETURN_THROWS(); + } +} +/* }}} */ + +/* {{{ resourcebundle_array_count */ +static zend_result resourcebundle_array_count(zend_object *object, zend_long *count) +{ + ResourceBundle_object *rb = php_intl_resourcebundle_fetch_object(object); + + if (rb->me == NULL) { + intl_errors_set(&rb->error, U_ILLEGAL_ARGUMENT_ERROR, + "Found unconstructed ResourceBundle"); + return FAILURE; + } + + *count = ures_getSize( rb->me ); + + return SUCCESS; +} +/* }}} */ + +/* {{{ Get resources count */ +U_CFUNC PHP_FUNCTION( resourcebundle_count ) +{ + int32_t len; + RESOURCEBUNDLE_METHOD_INIT_VARS; + + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", &object, ResourceBundle_ce_ptr ) == FAILURE ) { + RETURN_THROWS(); + } + + RESOURCEBUNDLE_METHOD_FETCH_OBJECT; + + len = ures_getSize( rb->me ); + RETURN_LONG( len ); +} + +/* {{{ Get available locales from ResourceBundle name */ +U_CFUNC PHP_FUNCTION( resourcebundle_locales ) +{ + char * bundlename; + size_t bundlename_len = 0; + const char * entry; + int entry_len; + UEnumeration *icuenum; + UErrorCode icuerror = U_ZERO_ERROR; + + intl_errors_reset( NULL ); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(bundlename, bundlename_len) + ZEND_PARSE_PARAMETERS_END(); + + if (bundlename_len >= MAXPATHLEN) { + zend_argument_value_error(1, "is too long"); + RETURN_THROWS(); + } + + if(bundlename_len == 0) { + // fetch default locales list + bundlename = NULL; + } + + icuenum = ures_openAvailableLocales( bundlename, &icuerror ); + INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list"); + + uenum_reset( icuenum, &icuerror ); + INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list"); + + array_init( return_value ); + while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) { + add_next_index_stringl( return_value, (char *) entry, entry_len); + } + uenum_close( icuenum ); +} +/* }}} */ + +/* {{{ Get text description for ResourceBundle's last error code. */ +U_CFUNC PHP_FUNCTION( resourcebundle_get_error_code ) +{ + RESOURCEBUNDLE_METHOD_INIT_VARS; + + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, ResourceBundle_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + rb = Z_INTL_RESOURCEBUNDLE_P( object ); + + RETURN_LONG(INTL_DATA_ERROR_CODE(rb)); +} +/* }}} */ + +/* {{{ Get text description for ResourceBundle's last error. */ +U_CFUNC PHP_FUNCTION( resourcebundle_get_error_message ) +{ + zend_string* message = NULL; + RESOURCEBUNDLE_METHOD_INIT_VARS; + + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, ResourceBundle_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + rb = Z_INTL_RESOURCEBUNDLE_P( object ); + message = intl_error_get_message(INTL_DATA_ERROR_P(rb)); + RETURN_STR(message); +} +/* }}} */ + +PHP_METHOD(ResourceBundle, getIterator) { + ZEND_PARSE_PARAMETERS_NONE(); + + zend_create_internal_iterator_zval(return_value, ZEND_THIS); +} + +/* {{{ resourcebundle_register_class + * Initialize 'ResourceBundle' class + */ +U_CFUNC void resourcebundle_register_class( void ) +{ + ResourceBundle_ce_ptr = register_class_ResourceBundle(zend_ce_aggregate, zend_ce_countable); + ResourceBundle_ce_ptr->create_object = ResourceBundle_object_create; + ResourceBundle_ce_ptr->default_object_handlers = &ResourceBundle_object_handlers; + ResourceBundle_ce_ptr->get_iterator = resourcebundle_get_iterator; + + ResourceBundle_object_handlers = std_object_handlers; + ResourceBundle_object_handlers.offset = offsetof(ResourceBundle_object, zend); + ResourceBundle_object_handlers.clone_obj = NULL; /* ICU ResourceBundle has no clone implementation */ + ResourceBundle_object_handlers.free_obj = ResourceBundle_object_free; + ResourceBundle_object_handlers.read_dimension = resourcebundle_array_get; + ResourceBundle_object_handlers.count_elements = resourcebundle_array_count; +} +/* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle_class.h b/ext/intl/resourcebundle/resourcebundle_class.h index be397c8d4760..1ec2ac592222 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.h +++ b/ext/intl/resourcebundle/resourcebundle_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ @@ -18,9 +18,14 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif #include "php.h" - #include "intl_error.h" +#ifdef __cplusplus +} +#endif typedef struct { intl_error error; @@ -31,7 +36,7 @@ typedef struct { } ResourceBundle_object; static inline ResourceBundle_object *php_intl_resourcebundle_fetch_object(zend_object *obj) { - return (ResourceBundle_object *)((char*)(obj) - XtOffsetOf(ResourceBundle_object, zend)); + return ZEND_CONTAINER_OF(obj, ResourceBundle_object, zend); } #define Z_INTL_RESOURCEBUNDLE_P(zv) php_intl_resourcebundle_fetch_object(Z_OBJ_P(zv)) @@ -46,7 +51,13 @@ static inline ResourceBundle_object *php_intl_resourcebundle_fetch_object(zend_o #define RESOURCEBUNDLE_OBJECT(rb) (rb)->me +#ifdef __cplusplus +extern "C" { +#endif void resourcebundle_register_class( void ); extern zend_class_entry *ResourceBundle_ce_ptr; +#ifdef __cplusplus +} +#endif #endif // #ifndef RESOURCEBUNDLE_CLASS_H diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.c b/ext/intl/resourcebundle/resourcebundle_iterator.c deleted file mode 100644 index c79269e47507..000000000000 --- a/ext/intl/resourcebundle/resourcebundle_iterator.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Hans-Peter Oeri (University of St.Gallen) | - +----------------------------------------------------------------------+ - */ - -#include -#include -#include - -#include "resourcebundle/resourcebundle.h" -#include "resourcebundle/resourcebundle_class.h" -#include "resourcebundle/resourcebundle_iterator.h" - -/* - * Although libicu offers iterator functions, they are not used here: libicu does iterate - * irrespective of array indices. Those cannot be recreated afterwards. Arrays as well as tables - * can however be accessed by numerical index, with table keys readable ex post. - */ - -/* {{{ resourcebundle_iterator_read */ -static void resourcebundle_iterator_read( ResourceBundle_iterator *iterator ) -{ - UErrorCode icuerror = U_ZERO_ERROR; - ResourceBundle_object *rb = iterator->subject; - - rb->child = ures_getByIndex( rb->me, iterator->i, rb->child, &icuerror ); - - if (U_SUCCESS(icuerror)) { - /* ATTN: key extraction must be the first thing to do... rb->child might be reset in read! */ - if (iterator->is_table) { - iterator->currentkey = estrdup( ures_getKey( rb->child ) ); - } - resourcebundle_extract_value( &iterator->current, rb ); - } - else { - ZVAL_UNDEF(&iterator->current); - } -} -/* }}} */ - -/* {{{ resourcebundle_iterator_invalidate */ -static void resourcebundle_iterator_invalidate( zend_object_iterator *iter ) -{ - ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; - - if (!Z_ISUNDEF(iterator->current)) { - zval_ptr_dtor( &iterator->current ); - ZVAL_UNDEF(&iterator->current); - } - if (iterator->currentkey) { - efree( iterator->currentkey ); - iterator->currentkey = NULL; - } -} -/* }}} */ - -/* {{{ resourcebundle_iterator_dtor */ -static void resourcebundle_iterator_dtor( zend_object_iterator *iter ) -{ - ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; - zval *object = &iterator->intern.data; - - resourcebundle_iterator_invalidate( iter ); - - zval_ptr_dtor(object); -} -/* }}} */ - -/* {{{ resourcebundle_iterator_has_more */ -static zend_result resourcebundle_iterator_has_more( zend_object_iterator *iter ) -{ - ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; - return (iterator->i < iterator->length) ? SUCCESS : FAILURE; -} -/* }}} */ - -/* {{{ resourcebundle_iterator_current */ -static zval *resourcebundle_iterator_current( zend_object_iterator *iter ) -{ - ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; - if (Z_ISUNDEF(iterator->current)) { - resourcebundle_iterator_read( iterator); - } - return &iterator->current; -} -/* }}} */ - -/* {{{ resourcebundle_iterator_key */ -static void resourcebundle_iterator_key( zend_object_iterator *iter, zval *key ) -{ - ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; - - if (Z_ISUNDEF(iterator->current)) { - resourcebundle_iterator_read( iterator); - } - - if (iterator->is_table) { - ZVAL_STRING(key, iterator->currentkey); - } else { - ZVAL_LONG(key, iterator->i); - } -} -/* }}} */ - -/* {{{ resourcebundle_iterator_step */ -static void resourcebundle_iterator_step( zend_object_iterator *iter ) -{ - ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; - - iterator->i++; - resourcebundle_iterator_invalidate( iter ); -} -/* }}} */ - -/* {{{ resourcebundle_iterator_has_reset */ -static void resourcebundle_iterator_reset( zend_object_iterator *iter ) -{ - ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; - - iterator->i = 0; - resourcebundle_iterator_invalidate( iter ); -} -/* }}} */ - -/* {{{ resourcebundle_iterator_funcs */ -static const zend_object_iterator_funcs resourcebundle_iterator_funcs = { - resourcebundle_iterator_dtor, - resourcebundle_iterator_has_more, - resourcebundle_iterator_current, - resourcebundle_iterator_key, - resourcebundle_iterator_step, - resourcebundle_iterator_reset, - resourcebundle_iterator_invalidate, - NULL, /* get_gc */ -}; -/* }}} */ - -/* {{{ resourcebundle_get_iterator */ -zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref ) -{ - if (byref) { - zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); - return NULL; - } - - ResourceBundle_object *rb = Z_INTL_RESOURCEBUNDLE_P(object ); - ResourceBundle_iterator *iterator = emalloc( sizeof( ResourceBundle_iterator ) ); - - zend_iterator_init(&iterator->intern); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(object)); - iterator->intern.funcs = &resourcebundle_iterator_funcs; - - iterator->subject = rb; - - /* The iterated rb can only be either URES_TABLE or URES_ARRAY - * All other types are returned as php primitives! - */ - iterator->is_table = (ures_getType( rb->me ) == URES_TABLE); - iterator->length = ures_getSize( rb->me ); - - ZVAL_UNDEF(&iterator->current); - iterator->currentkey = NULL; - iterator->i = 0; - - return (zend_object_iterator *) iterator; -} -/* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.cpp b/ext/intl/resourcebundle/resourcebundle_iterator.cpp new file mode 100644 index 000000000000..29288418437a --- /dev/null +++ b/ext/intl/resourcebundle/resourcebundle_iterator.cpp @@ -0,0 +1,179 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Hans-Peter Oeri (University of St.Gallen) | + +----------------------------------------------------------------------+ + */ + +extern "C" { +#include +#include +#include +} + +#include "resourcebundle/resourcebundle.h" +#include "resourcebundle/resourcebundle_class.h" +#include "resourcebundle/resourcebundle_iterator.h" + +/* + * Although libicu offers iterator functions, they are not used here: libicu does iterate + * irrespective of array indices. Those cannot be recreated afterwards. Arrays as well as tables + * can however be accessed by numerical index, with table keys readable ex post. + */ + +/* {{{ resourcebundle_iterator_read */ +static void resourcebundle_iterator_read( ResourceBundle_iterator *iterator ) +{ + UErrorCode icuerror = U_ZERO_ERROR; + ResourceBundle_object *rb = iterator->subject; + + rb->child = ures_getByIndex( rb->me, iterator->i, rb->child, &icuerror ); + + if (U_SUCCESS(icuerror)) { + /* ATTN: key extraction must be the first thing to do... rb->child might be reset in read! */ + if (iterator->is_table) { + iterator->currentkey = estrdup( ures_getKey( rb->child ) ); + } + resourcebundle_extract_value( &iterator->current, rb ); + } + else { + ZVAL_UNDEF(&iterator->current); + } +} +/* }}} */ + +/* {{{ resourcebundle_iterator_invalidate */ +static void resourcebundle_iterator_invalidate( zend_object_iterator *iter ) +{ + ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; + + if (!Z_ISUNDEF(iterator->current)) { + zval_ptr_dtor( &iterator->current ); + ZVAL_UNDEF(&iterator->current); + } + if (iterator->currentkey) { + efree( iterator->currentkey ); + iterator->currentkey = NULL; + } +} +/* }}} */ + +/* {{{ resourcebundle_iterator_dtor */ +static void resourcebundle_iterator_dtor( zend_object_iterator *iter ) +{ + ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; + zval *object = &iterator->intern.data; + + resourcebundle_iterator_invalidate( iter ); + + zval_ptr_dtor(object); +} +/* }}} */ + +/* {{{ resourcebundle_iterator_has_more */ +static zend_result resourcebundle_iterator_has_more( zend_object_iterator *iter ) +{ + ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; + return (iterator->i < iterator->length) ? SUCCESS : FAILURE; +} +/* }}} */ + +/* {{{ resourcebundle_iterator_current */ +static zval *resourcebundle_iterator_current( zend_object_iterator *iter ) +{ + ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; + if (Z_ISUNDEF(iterator->current)) { + resourcebundle_iterator_read( iterator); + } + return &iterator->current; +} +/* }}} */ + +/* {{{ resourcebundle_iterator_key */ +static void resourcebundle_iterator_key( zend_object_iterator *iter, zval *key ) +{ + ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; + + if (Z_ISUNDEF(iterator->current)) { + resourcebundle_iterator_read( iterator); + } + + if (iterator->is_table) { + ZVAL_STRING(key, iterator->currentkey); + } else { + ZVAL_LONG(key, iterator->i); + } +} +/* }}} */ + +/* {{{ resourcebundle_iterator_step */ +static void resourcebundle_iterator_step( zend_object_iterator *iter ) +{ + ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; + + iterator->i++; + resourcebundle_iterator_invalidate( iter ); +} +/* }}} */ + +/* {{{ resourcebundle_iterator_has_reset */ +static void resourcebundle_iterator_reset( zend_object_iterator *iter ) +{ + ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter; + + iterator->i = 0; + resourcebundle_iterator_invalidate( iter ); +} +/* }}} */ + +/* {{{ resourcebundle_iterator_funcs */ +static const zend_object_iterator_funcs resourcebundle_iterator_funcs = { + resourcebundle_iterator_dtor, + resourcebundle_iterator_has_more, + resourcebundle_iterator_current, + resourcebundle_iterator_key, + resourcebundle_iterator_step, + resourcebundle_iterator_reset, + resourcebundle_iterator_invalidate, + NULL, /* get_gc */ +}; +/* }}} */ + +/* {{{ resourcebundle_get_iterator */ +U_CFUNC zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref ) +{ + if (byref) { + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); + return NULL; + } + + ResourceBundle_object *rb = Z_INTL_RESOURCEBUNDLE_P(object ); + ResourceBundle_iterator *iterator = reinterpret_cast(emalloc( sizeof( ResourceBundle_iterator )) ); + + zend_iterator_init(&iterator->intern); + Z_ADDREF_P(object); + ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(object)); + iterator->intern.funcs = &resourcebundle_iterator_funcs; + + iterator->subject = rb; + + /* The iterated rb can only be either URES_TABLE or URES_ARRAY + * All other types are returned as php primitives! + */ + iterator->is_table = (ures_getType( rb->me ) == URES_TABLE); + iterator->length = ures_getSize( rb->me ); + + ZVAL_UNDEF(&iterator->current); + iterator->currentkey = NULL; + iterator->i = 0; + + return (zend_object_iterator *) iterator; +} +/* }}} */ diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.h b/ext/intl/resourcebundle/resourcebundle_iterator.h index 1ad948723160..762c12f363b5 100644 --- a/ext/intl/resourcebundle/resourcebundle_iterator.h +++ b/ext/intl/resourcebundle/resourcebundle_iterator.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Hans-Peter Oeri (University of St.Gallen) | +----------------------------------------------------------------------+ @@ -29,6 +29,12 @@ typedef struct { zend_long i; } ResourceBundle_iterator; +#ifdef __cplusplus +extern "C" { +#endif zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref ); +#ifdef __cplusplus +} +#endif #endif // #ifndef RESOURCEBUNDLE_ITERATOR_H diff --git a/ext/intl/spoofchecker/spoofchecker.stub.php b/ext/intl/spoofchecker/spoofchecker.stub.php index 0141252d478d..51a9c7d39074 100644 --- a/ext/intl/spoofchecker/spoofchecker.stub.php +++ b/ext/intl/spoofchecker/spoofchecker.stub.php @@ -19,7 +19,6 @@ class Spoofchecker public const int INVISIBLE = UNKNOWN; /** @cvalue USPOOF_CHAR_LIMIT */ public const int CHAR_LIMIT = UNKNOWN; -#if U_ICU_VERSION_MAJOR_NUM >= 58 /** @cvalue USPOOF_ASCII */ public const int ASCII = UNKNOWN; /** @cvalue USPOOF_HIGHLY_RESTRICTIVE */ @@ -34,7 +33,6 @@ class Spoofchecker public const int SINGLE_SCRIPT_RESTRICTIVE = UNKNOWN; /** @cvalue USPOOF_MIXED_NUMBERS */ public const int MIXED_NUMBERS = UNKNOWN; -#endif #if U_ICU_VERSION_MAJOR_NUM >= 62 /** @cvalue USPOOF_HIDDEN_OVERLAY */ public const int HIDDEN_OVERLAY = UNKNOWN; @@ -71,9 +69,7 @@ public function setAllowedLocales(string $locales): void {} /** @tentative-return-type */ public function setChecks(int $checks): void {} -#if U_ICU_VERSION_MAJOR_NUM >= 58 /** @tentative-return-type */ public function setRestrictionLevel(int $level): void {} -#endif public function setAllowedChars(string $pattern, int $patternOptions = 0): void {} } diff --git a/ext/intl/spoofchecker/spoofchecker_arginfo.h b/ext/intl/spoofchecker/spoofchecker_arginfo.h index 6a3c0e55aa27..8704065e479b 100644 --- a/ext/intl/spoofchecker/spoofchecker_arginfo.h +++ b/ext/intl/spoofchecker/spoofchecker_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 4834be57a3f0cb74dbc4422e609846139f09f6cb */ +/* This is a generated file, edit spoofchecker.stub.php instead. + * Stub hash: 4634f8ef9157fb3670a2ddc5e3246340660fc68c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Spoofchecker___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -23,11 +23,9 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Spoofchecker_set ZEND_ARG_TYPE_INFO(0, checks, IS_LONG, 0) ZEND_END_ARG_INFO() -#if U_ICU_VERSION_MAJOR_NUM >= 58 ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Spoofchecker_setRestrictionLevel, 0, 1, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, level, IS_LONG, 0) ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Spoofchecker_setAllowedChars, 0, 1, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0) @@ -39,9 +37,7 @@ ZEND_METHOD(Spoofchecker, isSuspicious); ZEND_METHOD(Spoofchecker, areConfusable); ZEND_METHOD(Spoofchecker, setAllowedLocales); ZEND_METHOD(Spoofchecker, setChecks); -#if U_ICU_VERSION_MAJOR_NUM >= 58 ZEND_METHOD(Spoofchecker, setRestrictionLevel); -#endif ZEND_METHOD(Spoofchecker, setAllowedChars); static const zend_function_entry class_Spoofchecker_methods[] = { @@ -50,9 +46,7 @@ static const zend_function_entry class_Spoofchecker_methods[] = { ZEND_ME(Spoofchecker, areConfusable, arginfo_class_Spoofchecker_areConfusable, ZEND_ACC_PUBLIC) ZEND_ME(Spoofchecker, setAllowedLocales, arginfo_class_Spoofchecker_setAllowedLocales, ZEND_ACC_PUBLIC) ZEND_ME(Spoofchecker, setChecks, arginfo_class_Spoofchecker_setChecks, ZEND_ACC_PUBLIC) -#if U_ICU_VERSION_MAJOR_NUM >= 58 ZEND_ME(Spoofchecker, setRestrictionLevel, arginfo_class_Spoofchecker_setRestrictionLevel, ZEND_ACC_PUBLIC) -#endif ZEND_ME(Spoofchecker, setAllowedChars, arginfo_class_Spoofchecker_setAllowedChars, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -66,122 +60,120 @@ static zend_class_entry *register_class_Spoofchecker(void) zval const_SINGLE_SCRIPT_CONFUSABLE_value; ZVAL_LONG(&const_SINGLE_SCRIPT_CONFUSABLE_value, USPOOF_SINGLE_SCRIPT_CONFUSABLE); - zend_string *const_SINGLE_SCRIPT_CONFUSABLE_name = zend_string_init_interned("SINGLE_SCRIPT_CONFUSABLE", sizeof("SINGLE_SCRIPT_CONFUSABLE") - 1, 1); + zend_string *const_SINGLE_SCRIPT_CONFUSABLE_name = zend_string_init_interned("SINGLE_SCRIPT_CONFUSABLE", sizeof("SINGLE_SCRIPT_CONFUSABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SINGLE_SCRIPT_CONFUSABLE_name, &const_SINGLE_SCRIPT_CONFUSABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SINGLE_SCRIPT_CONFUSABLE_name); + zend_string_release_ex(const_SINGLE_SCRIPT_CONFUSABLE_name, true); zval const_MIXED_SCRIPT_CONFUSABLE_value; ZVAL_LONG(&const_MIXED_SCRIPT_CONFUSABLE_value, USPOOF_MIXED_SCRIPT_CONFUSABLE); - zend_string *const_MIXED_SCRIPT_CONFUSABLE_name = zend_string_init_interned("MIXED_SCRIPT_CONFUSABLE", sizeof("MIXED_SCRIPT_CONFUSABLE") - 1, 1); + zend_string *const_MIXED_SCRIPT_CONFUSABLE_name = zend_string_init_interned("MIXED_SCRIPT_CONFUSABLE", sizeof("MIXED_SCRIPT_CONFUSABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIXED_SCRIPT_CONFUSABLE_name, &const_MIXED_SCRIPT_CONFUSABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIXED_SCRIPT_CONFUSABLE_name); + zend_string_release_ex(const_MIXED_SCRIPT_CONFUSABLE_name, true); zval const_WHOLE_SCRIPT_CONFUSABLE_value; ZVAL_LONG(&const_WHOLE_SCRIPT_CONFUSABLE_value, USPOOF_WHOLE_SCRIPT_CONFUSABLE); - zend_string *const_WHOLE_SCRIPT_CONFUSABLE_name = zend_string_init_interned("WHOLE_SCRIPT_CONFUSABLE", sizeof("WHOLE_SCRIPT_CONFUSABLE") - 1, 1); + zend_string *const_WHOLE_SCRIPT_CONFUSABLE_name = zend_string_init_interned("WHOLE_SCRIPT_CONFUSABLE", sizeof("WHOLE_SCRIPT_CONFUSABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_WHOLE_SCRIPT_CONFUSABLE_name, &const_WHOLE_SCRIPT_CONFUSABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WHOLE_SCRIPT_CONFUSABLE_name); + zend_string_release_ex(const_WHOLE_SCRIPT_CONFUSABLE_name, true); zval const_ANY_CASE_value; ZVAL_LONG(&const_ANY_CASE_value, USPOOF_ANY_CASE); - zend_string *const_ANY_CASE_name = zend_string_init_interned("ANY_CASE", sizeof("ANY_CASE") - 1, 1); + zend_string *const_ANY_CASE_name = zend_string_init_interned("ANY_CASE", sizeof("ANY_CASE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ANY_CASE_name, &const_ANY_CASE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ANY_CASE_name); + zend_string_release_ex(const_ANY_CASE_name, true); zval const_SINGLE_SCRIPT_value; ZVAL_LONG(&const_SINGLE_SCRIPT_value, USPOOF_SINGLE_SCRIPT); - zend_string *const_SINGLE_SCRIPT_name = zend_string_init_interned("SINGLE_SCRIPT", sizeof("SINGLE_SCRIPT") - 1, 1); + zend_string *const_SINGLE_SCRIPT_name = zend_string_init_interned("SINGLE_SCRIPT", sizeof("SINGLE_SCRIPT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SINGLE_SCRIPT_name, &const_SINGLE_SCRIPT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SINGLE_SCRIPT_name); + zend_string_release_ex(const_SINGLE_SCRIPT_name, true); zval const_INVISIBLE_value; ZVAL_LONG(&const_INVISIBLE_value, USPOOF_INVISIBLE); - zend_string *const_INVISIBLE_name = zend_string_init_interned("INVISIBLE", sizeof("INVISIBLE") - 1, 1); + zend_string *const_INVISIBLE_name = zend_string_init_interned("INVISIBLE", sizeof("INVISIBLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_INVISIBLE_name, &const_INVISIBLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_INVISIBLE_name); + zend_string_release_ex(const_INVISIBLE_name, true); zval const_CHAR_LIMIT_value; ZVAL_LONG(&const_CHAR_LIMIT_value, USPOOF_CHAR_LIMIT); - zend_string *const_CHAR_LIMIT_name = zend_string_init_interned("CHAR_LIMIT", sizeof("CHAR_LIMIT") - 1, 1); + zend_string *const_CHAR_LIMIT_name = zend_string_init_interned("CHAR_LIMIT", sizeof("CHAR_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_LIMIT_name, &const_CHAR_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_LIMIT_name); -#if U_ICU_VERSION_MAJOR_NUM >= 58 + zend_string_release_ex(const_CHAR_LIMIT_name, true); zval const_ASCII_value; ZVAL_LONG(&const_ASCII_value, USPOOF_ASCII); - zend_string *const_ASCII_name = zend_string_init_interned("ASCII", sizeof("ASCII") - 1, 1); + zend_string *const_ASCII_name = zend_string_init_interned("ASCII", sizeof("ASCII") - 1, true); zend_declare_typed_class_constant(class_entry, const_ASCII_name, &const_ASCII_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ASCII_name); + zend_string_release_ex(const_ASCII_name, true); zval const_HIGHLY_RESTRICTIVE_value; ZVAL_LONG(&const_HIGHLY_RESTRICTIVE_value, USPOOF_HIGHLY_RESTRICTIVE); - zend_string *const_HIGHLY_RESTRICTIVE_name = zend_string_init_interned("HIGHLY_RESTRICTIVE", sizeof("HIGHLY_RESTRICTIVE") - 1, 1); + zend_string *const_HIGHLY_RESTRICTIVE_name = zend_string_init_interned("HIGHLY_RESTRICTIVE", sizeof("HIGHLY_RESTRICTIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_HIGHLY_RESTRICTIVE_name, &const_HIGHLY_RESTRICTIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HIGHLY_RESTRICTIVE_name); + zend_string_release_ex(const_HIGHLY_RESTRICTIVE_name, true); zval const_MODERATELY_RESTRICTIVE_value; ZVAL_LONG(&const_MODERATELY_RESTRICTIVE_value, USPOOF_MODERATELY_RESTRICTIVE); - zend_string *const_MODERATELY_RESTRICTIVE_name = zend_string_init_interned("MODERATELY_RESTRICTIVE", sizeof("MODERATELY_RESTRICTIVE") - 1, 1); + zend_string *const_MODERATELY_RESTRICTIVE_name = zend_string_init_interned("MODERATELY_RESTRICTIVE", sizeof("MODERATELY_RESTRICTIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_MODERATELY_RESTRICTIVE_name, &const_MODERATELY_RESTRICTIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MODERATELY_RESTRICTIVE_name); + zend_string_release_ex(const_MODERATELY_RESTRICTIVE_name, true); zval const_MINIMALLY_RESTRICTIVE_value; ZVAL_LONG(&const_MINIMALLY_RESTRICTIVE_value, USPOOF_MINIMALLY_RESTRICTIVE); - zend_string *const_MINIMALLY_RESTRICTIVE_name = zend_string_init_interned("MINIMALLY_RESTRICTIVE", sizeof("MINIMALLY_RESTRICTIVE") - 1, 1); + zend_string *const_MINIMALLY_RESTRICTIVE_name = zend_string_init_interned("MINIMALLY_RESTRICTIVE", sizeof("MINIMALLY_RESTRICTIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_MINIMALLY_RESTRICTIVE_name, &const_MINIMALLY_RESTRICTIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MINIMALLY_RESTRICTIVE_name); + zend_string_release_ex(const_MINIMALLY_RESTRICTIVE_name, true); zval const_UNRESTRICTIVE_value; ZVAL_LONG(&const_UNRESTRICTIVE_value, USPOOF_UNRESTRICTIVE); - zend_string *const_UNRESTRICTIVE_name = zend_string_init_interned("UNRESTRICTIVE", sizeof("UNRESTRICTIVE") - 1, 1); + zend_string *const_UNRESTRICTIVE_name = zend_string_init_interned("UNRESTRICTIVE", sizeof("UNRESTRICTIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_UNRESTRICTIVE_name, &const_UNRESTRICTIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UNRESTRICTIVE_name); + zend_string_release_ex(const_UNRESTRICTIVE_name, true); zval const_SINGLE_SCRIPT_RESTRICTIVE_value; ZVAL_LONG(&const_SINGLE_SCRIPT_RESTRICTIVE_value, USPOOF_SINGLE_SCRIPT_RESTRICTIVE); - zend_string *const_SINGLE_SCRIPT_RESTRICTIVE_name = zend_string_init_interned("SINGLE_SCRIPT_RESTRICTIVE", sizeof("SINGLE_SCRIPT_RESTRICTIVE") - 1, 1); + zend_string *const_SINGLE_SCRIPT_RESTRICTIVE_name = zend_string_init_interned("SINGLE_SCRIPT_RESTRICTIVE", sizeof("SINGLE_SCRIPT_RESTRICTIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SINGLE_SCRIPT_RESTRICTIVE_name, &const_SINGLE_SCRIPT_RESTRICTIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SINGLE_SCRIPT_RESTRICTIVE_name); + zend_string_release_ex(const_SINGLE_SCRIPT_RESTRICTIVE_name, true); zval const_MIXED_NUMBERS_value; ZVAL_LONG(&const_MIXED_NUMBERS_value, USPOOF_MIXED_NUMBERS); - zend_string *const_MIXED_NUMBERS_name = zend_string_init_interned("MIXED_NUMBERS", sizeof("MIXED_NUMBERS") - 1, 1); + zend_string *const_MIXED_NUMBERS_name = zend_string_init_interned("MIXED_NUMBERS", sizeof("MIXED_NUMBERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIXED_NUMBERS_name, &const_MIXED_NUMBERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIXED_NUMBERS_name); -#endif + zend_string_release_ex(const_MIXED_NUMBERS_name, true); #if U_ICU_VERSION_MAJOR_NUM >= 62 zval const_HIDDEN_OVERLAY_value; ZVAL_LONG(&const_HIDDEN_OVERLAY_value, USPOOF_HIDDEN_OVERLAY); - zend_string *const_HIDDEN_OVERLAY_name = zend_string_init_interned("HIDDEN_OVERLAY", sizeof("HIDDEN_OVERLAY") - 1, 1); + zend_string *const_HIDDEN_OVERLAY_name = zend_string_init_interned("HIDDEN_OVERLAY", sizeof("HIDDEN_OVERLAY") - 1, true); zend_declare_typed_class_constant(class_entry, const_HIDDEN_OVERLAY_name, &const_HIDDEN_OVERLAY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HIDDEN_OVERLAY_name); + zend_string_release_ex(const_HIDDEN_OVERLAY_name, true); #endif zval const_IGNORE_SPACE_value; ZVAL_LONG(&const_IGNORE_SPACE_value, USET_IGNORE_SPACE); - zend_string *const_IGNORE_SPACE_name = zend_string_init_interned("IGNORE_SPACE", sizeof("IGNORE_SPACE") - 1, 1); + zend_string *const_IGNORE_SPACE_name = zend_string_init_interned("IGNORE_SPACE", sizeof("IGNORE_SPACE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IGNORE_SPACE_name, &const_IGNORE_SPACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IGNORE_SPACE_name); + zend_string_release_ex(const_IGNORE_SPACE_name, true); zval const_CASE_INSENSITIVE_value; ZVAL_LONG(&const_CASE_INSENSITIVE_value, USET_CASE_INSENSITIVE); - zend_string *const_CASE_INSENSITIVE_name = zend_string_init_interned("CASE_INSENSITIVE", sizeof("CASE_INSENSITIVE") - 1, 1); + zend_string *const_CASE_INSENSITIVE_name = zend_string_init_interned("CASE_INSENSITIVE", sizeof("CASE_INSENSITIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CASE_INSENSITIVE_name, &const_CASE_INSENSITIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CASE_INSENSITIVE_name); + zend_string_release_ex(const_CASE_INSENSITIVE_name, true); zval const_ADD_CASE_MAPPINGS_value; ZVAL_LONG(&const_ADD_CASE_MAPPINGS_value, USET_ADD_CASE_MAPPINGS); - zend_string *const_ADD_CASE_MAPPINGS_name = zend_string_init_interned("ADD_CASE_MAPPINGS", sizeof("ADD_CASE_MAPPINGS") - 1, 1); + zend_string *const_ADD_CASE_MAPPINGS_name = zend_string_init_interned("ADD_CASE_MAPPINGS", sizeof("ADD_CASE_MAPPINGS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ADD_CASE_MAPPINGS_name, &const_ADD_CASE_MAPPINGS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ADD_CASE_MAPPINGS_name); + zend_string_release_ex(const_ADD_CASE_MAPPINGS_name, true); #if U_ICU_VERSION_MAJOR_NUM >= 73 zval const_SIMPLE_CASE_INSENSITIVE_value; ZVAL_LONG(&const_SIMPLE_CASE_INSENSITIVE_value, USET_SIMPLE_CASE_INSENSITIVE); - zend_string *const_SIMPLE_CASE_INSENSITIVE_name = zend_string_init_interned("SIMPLE_CASE_INSENSITIVE", sizeof("SIMPLE_CASE_INSENSITIVE") - 1, 1); + zend_string *const_SIMPLE_CASE_INSENSITIVE_name = zend_string_init_interned("SIMPLE_CASE_INSENSITIVE", sizeof("SIMPLE_CASE_INSENSITIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SIMPLE_CASE_INSENSITIVE_name, &const_SIMPLE_CASE_INSENSITIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SIMPLE_CASE_INSENSITIVE_name); + zend_string_release_ex(const_SIMPLE_CASE_INSENSITIVE_name, true); #endif return class_entry; diff --git a/ext/intl/spoofchecker/spoofchecker_class.c b/ext/intl/spoofchecker/spoofchecker_class.c deleted file mode 100644 index 6fa59edd47b0..000000000000 --- a/ext/intl/spoofchecker/spoofchecker_class.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Scott MacVicar | - +----------------------------------------------------------------------+ - */ - -#include "spoofchecker_class.h" -#include "spoofchecker_arginfo.h" -#include "php_intl.h" -#include "intl_error.h" - -#include - -zend_class_entry *Spoofchecker_ce_ptr = NULL; -static zend_object_handlers Spoofchecker_handlers; - -/* - * Auxiliary functions needed by objects of 'Spoofchecker' class - */ - -/* {{{ Spoofchecker_objects_free */ -void Spoofchecker_objects_free(zend_object *object) -{ - Spoofchecker_object* co = php_intl_spoofchecker_fetch_object(object); - - zend_object_std_dtor(&co->zo); - - spoofchecker_object_destroy(co); -} -/* }}} */ - -/* {{{ Spoofchecker_object_create */ -zend_object *Spoofchecker_object_create(zend_class_entry *ce) -{ - Spoofchecker_object* intern; - - intern = zend_object_alloc(sizeof(Spoofchecker_object), ce); - intl_error_init(SPOOFCHECKER_ERROR_P(intern)); - zend_object_std_init(&intern->zo, ce); - object_properties_init(&intern->zo, ce); - - return &intern->zo; -} -/* }}} */ - -/* - * 'Spoofchecker' class registration structures & functions - */ - -/* {{{ Spoofchecker_class_functions - * Every 'Spoofchecker' class method has an entry in this table - */ - -static zend_object *spoofchecker_clone_obj(zend_object *object) /* {{{ */ -{ - Spoofchecker_object *spoofchecker_orig = php_intl_spoofchecker_fetch_object(object); - zend_object *new_obj_val = Spoofchecker_ce_ptr->create_object(object->ce); - Spoofchecker_object *spoofchecker_new = php_intl_spoofchecker_fetch_object(new_obj_val); - - zend_objects_clone_members(&spoofchecker_new->zo, &spoofchecker_orig->zo); - - if (spoofchecker_orig->uspoof != NULL) { - /* guaranteed to return NULL if it fails */ - UErrorCode error = U_ZERO_ERROR; - spoofchecker_new->uspoof = uspoof_clone(spoofchecker_orig->uspoof, &error); - if (U_FAILURE(error)) { - /* free new object */ - Spoofchecker_objects_free(&spoofchecker_new->zo); - zend_throw_error(NULL, "Failed to clone SpoofChecker"); - } - } else { - zend_throw_error(NULL, "Cannot clone uninitialized SpoofChecker"); - } - - return new_obj_val; -} -/* }}} */ - -/* {{{ spoofchecker_register_Spoofchecker_class - * Initialize 'Spoofchecker' class - */ -void spoofchecker_register_Spoofchecker_class(void) -{ - /* Create and register 'Spoofchecker' class. */ - Spoofchecker_ce_ptr = register_class_Spoofchecker(); - Spoofchecker_ce_ptr->create_object = Spoofchecker_object_create; - Spoofchecker_ce_ptr->default_object_handlers = &Spoofchecker_handlers; - - memcpy(&Spoofchecker_handlers, &std_object_handlers, - sizeof Spoofchecker_handlers); - Spoofchecker_handlers.offset = XtOffsetOf(Spoofchecker_object, zo); - Spoofchecker_handlers.clone_obj = spoofchecker_clone_obj; - Spoofchecker_handlers.free_obj = Spoofchecker_objects_free; -} -/* }}} */ - -/* {{{ void spoofchecker_object_init( Spoofchecker_object* co ) - * Initialize internals of Spoofchecker_object. - * Must be called before any other call to 'spoofchecker_object_...' functions. - */ -void spoofchecker_object_init(Spoofchecker_object* co) -{ - if (!co) { - return; - } - - intl_error_init(SPOOFCHECKER_ERROR_P(co)); -} -/* }}} */ - -/* {{{ void spoofchecker_object_destroy( Spoofchecker_object* co ) - * Clean up mem allocted by internals of Spoofchecker_object - */ -void spoofchecker_object_destroy(Spoofchecker_object* co) -{ - if (!co) { - return; - } - - if (co->uspoof) { - uspoof_close(co->uspoof); - co->uspoof = NULL; - } - -#if U_ICU_VERSION_MAJOR_NUM >= 58 - if (co->uspoofres) { - uspoof_closeCheckResult(co->uspoofres); - co->uspoofres = NULL; - } -#endif - - intl_error_reset(SPOOFCHECKER_ERROR_P(co)); -} -/* }}} */ diff --git a/ext/intl/spoofchecker/spoofchecker_class.cpp b/ext/intl/spoofchecker/spoofchecker_class.cpp new file mode 100644 index 000000000000..6f072081fa78 --- /dev/null +++ b/ext/intl/spoofchecker/spoofchecker_class.cpp @@ -0,0 +1,144 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Scott MacVicar | + +----------------------------------------------------------------------+ + */ + +#include "spoofchecker_class.h" +extern "C" { +#include "spoofchecker_arginfo.h" +#include "php_intl.h" +#include "intl_error.h" +} + +#include + +zend_class_entry *Spoofchecker_ce_ptr = NULL; +static zend_object_handlers Spoofchecker_handlers; + +/* + * Auxiliary functions needed by objects of 'Spoofchecker' class + */ + +/* {{{ Spoofchecker_objects_free */ +U_CFUNC void Spoofchecker_objects_free(zend_object *object) +{ + Spoofchecker_object* co = php_intl_spoofchecker_fetch_object(object); + + zend_object_std_dtor(&co->zo); + + spoofchecker_object_destroy(co); +} +/* }}} */ + +/* {{{ Spoofchecker_object_create */ +U_CFUNC zend_object *Spoofchecker_object_create(zend_class_entry *ce) +{ + Spoofchecker_object* intern; + + intern = reinterpret_cast(zend_object_alloc(sizeof(Spoofchecker_object), ce)); + intl_error_init(SPOOFCHECKER_ERROR_P(intern)); + zend_object_std_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); + + return &intern->zo; +} +/* }}} */ + +/* + * 'Spoofchecker' class registration structures & functions + */ + +/* {{{ Spoofchecker_class_functions + * Every 'Spoofchecker' class method has an entry in this table + */ + +static zend_object *spoofchecker_clone_obj(zend_object *object) /* {{{ */ +{ + const Spoofchecker_object *spoofchecker_orig = php_intl_spoofchecker_fetch_object(object); + zend_object *new_obj_val = Spoofchecker_ce_ptr->create_object(object->ce); + Spoofchecker_object *spoofchecker_new = php_intl_spoofchecker_fetch_object(new_obj_val); + + zend_objects_clone_members(&spoofchecker_new->zo, &spoofchecker_orig->zo); + + if (spoofchecker_orig->uspoof != NULL) { + /* guaranteed to return NULL if it fails */ + UErrorCode error = U_ZERO_ERROR; + spoofchecker_new->uspoof = uspoof_clone(spoofchecker_orig->uspoof, &error); + if (U_FAILURE(error)) { + /* free new object */ + Spoofchecker_objects_free(&spoofchecker_new->zo); + zend_throw_error(NULL, "Failed to clone SpoofChecker"); + } + } else { + zend_throw_error(NULL, "Cannot clone uninitialized SpoofChecker"); + } + + return new_obj_val; +} +/* }}} */ + +/* {{{ spoofchecker_register_Spoofchecker_class + * Initialize 'Spoofchecker' class + */ +U_CFUNC void spoofchecker_register_Spoofchecker_class(void) +{ + /* Create and register 'Spoofchecker' class. */ + Spoofchecker_ce_ptr = register_class_Spoofchecker(); + Spoofchecker_ce_ptr->create_object = Spoofchecker_object_create; + Spoofchecker_ce_ptr->default_object_handlers = &Spoofchecker_handlers; + + memcpy(&Spoofchecker_handlers, &std_object_handlers, + sizeof Spoofchecker_handlers); + Spoofchecker_handlers.offset = offsetof(Spoofchecker_object, zo); + Spoofchecker_handlers.clone_obj = spoofchecker_clone_obj; + Spoofchecker_handlers.free_obj = Spoofchecker_objects_free; +} +/* }}} */ + +/* {{{ void spoofchecker_object_init( Spoofchecker_object* co ) + * Initialize internals of Spoofchecker_object. + * Must be called before any other call to 'spoofchecker_object_...' functions. + */ +U_CFUNC void spoofchecker_object_init(Spoofchecker_object* co) +{ + if (!co) { + return; + } + + intl_error_init(SPOOFCHECKER_ERROR_P(co)); +} +/* }}} */ + +/* {{{ void spoofchecker_object_destroy( Spoofchecker_object* co ) + * Clean up mem allocted by internals of Spoofchecker_object + */ +U_CFUNC void spoofchecker_object_destroy(Spoofchecker_object* co) +{ + if (!co) { + return; + } + + if (co->uspoof) { + uspoof_close(co->uspoof); + co->uspoof = NULL; + } + +#if U_ICU_VERSION_MAJOR_NUM >= 58 + if (co->uspoofres) { + uspoof_closeCheckResult(co->uspoofres); + co->uspoofres = NULL; + } +#endif + + intl_error_reset(SPOOFCHECKER_ERROR_P(co)); +} +/* }}} */ diff --git a/ext/intl/spoofchecker/spoofchecker_class.h b/ext/intl/spoofchecker/spoofchecker_class.h index 480eeeb476ff..c3da53583b3a 100644 --- a/ext/intl/spoofchecker/spoofchecker_class.h +++ b/ext/intl/spoofchecker/spoofchecker_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -17,9 +17,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif #include "intl_common.h" #include "intl_error.h" #include "intl_data.h" +#ifdef __cplusplus +} +#endif #include @@ -37,7 +43,7 @@ typedef struct { } Spoofchecker_object; static inline Spoofchecker_object *php_intl_spoofchecker_fetch_object(zend_object *obj) { - return (Spoofchecker_object *)((char*)(obj) - XtOffsetOf(Spoofchecker_object, zo)); + return ZEND_CONTAINER_OF(obj, Spoofchecker_object, zo); } #define Z_INTL_SPOOFCHECKER_P(zv) php_intl_spoofchecker_fetch_object((Z_OBJ_P(zv))) @@ -47,10 +53,16 @@ static inline Spoofchecker_object *php_intl_spoofchecker_fetch_object(zend_objec #define SPOOFCHECKER_ERROR_CODE(co) INTL_ERROR_CODE(SPOOFCHECKER_ERROR(co)) #define SPOOFCHECKER_ERROR_CODE_P(co) &(INTL_ERROR_CODE(SPOOFCHECKER_ERROR(co))) +#ifdef __cplusplus +extern "C" { +#endif void spoofchecker_register_Spoofchecker_class(void); void spoofchecker_object_init(Spoofchecker_object* co); void spoofchecker_object_destroy(Spoofchecker_object* co); +#ifdef __cplusplus +} +#endif extern zend_class_entry *Spoofchecker_ce_ptr; @@ -73,7 +85,7 @@ extern zend_class_entry *Spoofchecker_ce_ptr; #define SPOOFCHECKER_CHECK_STATUS(co, msg) \ intl_error_set_code(NULL, SPOOFCHECKER_ERROR_CODE(co)); \ if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { \ - intl_errors_set_custom_msg(SPOOFCHECKER_ERROR_P(co), msg, 0); \ + intl_errors_set_custom_msg(SPOOFCHECKER_ERROR_P(co), msg); \ RETURN_FALSE; \ } \ diff --git a/ext/intl/spoofchecker/spoofchecker_create.c b/ext/intl/spoofchecker/spoofchecker_create.c deleted file mode 100644 index c1cecac8412a..000000000000 --- a/ext/intl/spoofchecker/spoofchecker_create.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Scott MacVicar | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "spoofchecker_class.h" -#include "intl_data.h" - -/* {{{ Spoofchecker object constructor. */ -PHP_METHOD(Spoofchecker, __construct) -{ -#if U_ICU_VERSION_MAJOR_NUM < 58 - int checks; -#endif - zend_error_handling error_handling; - SPOOFCHECKER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_NONE(); - - zend_replace_error_handling(EH_THROW, IntlException_ce_ptr, &error_handling); - - SPOOFCHECKER_METHOD_FETCH_OBJECT_NO_CHECK; - - co->uspoof = uspoof_open(SPOOFCHECKER_ERROR_CODE_P(co)); - INTL_METHOD_CHECK_STATUS(co, "spoofchecker: unable to open ICU Spoof Checker"); - -#if U_ICU_VERSION_MAJOR_NUM >= 58 - /* TODO save it into the object for further suspiction check comparison. */ - /* ICU 58 removes WSC and MSC handling. However there are restriction - levels as defined in - http://www.unicode.org/reports/tr39/tr39-15.html#Restriction_Level_Detection - and the default is high restrictive. In further, we might want to utilize - uspoof_check2 APIs when it became stable, to use extended check result APIs. - Subsequent changes in the unicode security algos are to be watched.*/ - uspoof_setRestrictionLevel(co->uspoof, SPOOFCHECKER_DEFAULT_RESTRICTION_LEVEL); - co->uspoofres = uspoof_openCheckResult(SPOOFCHECKER_ERROR_CODE_P(co)); -#else - /* Single-script enforcement is on by default. This fails for languages - like Japanese that legally use multiple scripts within a single word, - so we turn it off. - */ - checks = uspoof_getChecks(co->uspoof, SPOOFCHECKER_ERROR_CODE_P(co)); - uspoof_setChecks(co->uspoof, checks & ~USPOOF_SINGLE_SCRIPT, SPOOFCHECKER_ERROR_CODE_P(co)); -#endif - zend_restore_error_handling(&error_handling); -} -/* }}} */ diff --git a/ext/intl/spoofchecker/spoofchecker_create.cpp b/ext/intl/spoofchecker/spoofchecker_create.cpp new file mode 100644 index 000000000000..f4b51492cac6 --- /dev/null +++ b/ext/intl/spoofchecker/spoofchecker_create.cpp @@ -0,0 +1,67 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Scott MacVicar | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "intl_data.h" +} +#include "spoofchecker_class.h" + +/* {{{ Spoofchecker object constructor. */ +U_CFUNC PHP_METHOD(Spoofchecker, __construct) +{ +#if U_ICU_VERSION_MAJOR_NUM < 58 + int checks; +#endif + SPOOFCHECKER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_NONE(); + + SPOOFCHECKER_METHOD_FETCH_OBJECT_NO_CHECK; + + co->uspoof = uspoof_open(SPOOFCHECKER_ERROR_CODE_P(co)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(co))) { + zend_throw_exception(IntlException_ce_ptr, + "Spoofchecker::__construct(): unable to open ICU Spoof Checker", 0); + } + +#if U_ICU_VERSION_MAJOR_NUM >= 58 + /* TODO save it into the object for further suspiction check comparison. */ + /* ICU 58 removes WSC and MSC handling. However there are restriction + levels as defined in + http://www.unicode.org/reports/tr39/tr39-15.html#Restriction_Level_Detection + and the default is high restrictive. In further, we might want to utilize + uspoof_check2 APIs when it became stable, to use extended check result APIs. + Subsequent changes in the unicode security algos are to be watched.*/ + uspoof_setRestrictionLevel(co->uspoof, SPOOFCHECKER_DEFAULT_RESTRICTION_LEVEL); + co->uspoofres = uspoof_openCheckResult(SPOOFCHECKER_ERROR_CODE_P(co)); +#else + /* Single-script enforcement is on by default. This fails for languages + like Japanese that legally use multiple scripts within a single word, + so we turn it off. + */ + checks = uspoof_getChecks(co->uspoof, SPOOFCHECKER_ERROR_CODE_P(co)); + uspoof_setChecks(co->uspoof, checks & ~USPOOF_SINGLE_SCRIPT, SPOOFCHECKER_ERROR_CODE_P(co)); +#endif +} +/* }}} */ diff --git a/ext/intl/spoofchecker/spoofchecker_main.c b/ext/intl/spoofchecker/spoofchecker_main.c deleted file mode 100644 index afea503bc0e4..000000000000 --- a/ext/intl/spoofchecker/spoofchecker_main.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Scott MacVicar | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "intl_convert.h" -#include "spoofchecker_class.h" - -/* {{{ Checks if a given text contains any suspicious characters */ -PHP_METHOD(Spoofchecker, isSuspicious) -{ - int32_t ret, errmask; - zend_string *text; - zval *error_code = NULL; - SPOOFCHECKER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR(text) - Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(error_code) - ZEND_PARSE_PARAMETERS_END(); - - SPOOFCHECKER_METHOD_FETCH_OBJECT; - -#if U_ICU_VERSION_MAJOR_NUM >= 58 - ret = uspoof_check2UTF8(co->uspoof, ZSTR_VAL(text), ZSTR_LEN(text), co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); -#else - ret = uspoof_checkUTF8(co->uspoof, ZSTR_VAL(text), ZSTR_LEN(text), NULL, SPOOFCHECKER_ERROR_CODE_P(co)); -#endif - - if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { - php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); -#if U_ICU_VERSION_MAJOR_NUM >= 58 - errmask = uspoof_getCheckResultChecks(co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); - - if (errmask != ret) { - php_error_docref(NULL, E_WARNING, "unexpected error (%d), does not relate to the flags passed to setChecks (%d)", ret, errmask); - } -#endif - RETURN_TRUE; - } - - if (error_code) { - ZEND_TRY_ASSIGN_REF_LONG(error_code, ret); - } - RETVAL_BOOL(ret != 0); -} -/* }}} */ - -/* {{{ Checks if a given text contains any confusable characters */ -PHP_METHOD(Spoofchecker, areConfusable) -{ - int ret; - zend_string *s1, *s2; - zval *error_code = NULL; - SPOOFCHECKER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STR(s1) - Z_PARAM_STR(s2) - Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(error_code) - ZEND_PARSE_PARAMETERS_END(); - - SPOOFCHECKER_METHOD_FETCH_OBJECT; - if(ZSTR_LEN(s1) > INT32_MAX || ZSTR_LEN(s2) > INT32_MAX) { - SPOOFCHECKER_ERROR_CODE(co) = U_BUFFER_OVERFLOW_ERROR; - } else { - ret = uspoof_areConfusableUTF8(co->uspoof, ZSTR_VAL(s1), (int32_t)ZSTR_LEN(s1), ZSTR_VAL(s2), (int32_t)ZSTR_LEN(s2), SPOOFCHECKER_ERROR_CODE_P(co)); - } - if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { - php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); - RETURN_TRUE; - } - - if (error_code) { - ZEND_TRY_ASSIGN_REF_LONG(error_code, ret); - } - RETVAL_BOOL(ret != 0); -} -/* }}} */ - -/* {{{ Locales to use when running checks */ -PHP_METHOD(Spoofchecker, setAllowedLocales) -{ - zend_string *locales; - SPOOFCHECKER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(locales) - ZEND_PARSE_PARAMETERS_END(); - - SPOOFCHECKER_METHOD_FETCH_OBJECT; - - uspoof_setAllowedLocales(co->uspoof, ZSTR_VAL(locales), SPOOFCHECKER_ERROR_CODE_P(co)); - - if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { - php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); - return; - } -} -/* }}} */ - -/* {{{ Set the checks to run */ -PHP_METHOD(Spoofchecker, setChecks) -{ - zend_long checks; - SPOOFCHECKER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(checks) - ZEND_PARSE_PARAMETERS_END(); - - SPOOFCHECKER_METHOD_FETCH_OBJECT; - - uspoof_setChecks(co->uspoof, checks, SPOOFCHECKER_ERROR_CODE_P(co)); - - if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { - php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); - } -} -/* }}} */ - -#if U_ICU_VERSION_MAJOR_NUM >= 58 -/* TODO Document this method on PHP.net */ -/* {{{ Set the loosest restriction level allowed for strings. */ -PHP_METHOD(Spoofchecker, setRestrictionLevel) -{ - zend_long level; - SPOOFCHECKER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(level) - ZEND_PARSE_PARAMETERS_END(); - - SPOOFCHECKER_METHOD_FETCH_OBJECT; - - if (USPOOF_ASCII != level && - USPOOF_SINGLE_SCRIPT_RESTRICTIVE != level && - USPOOF_HIGHLY_RESTRICTIVE != level && - USPOOF_MODERATELY_RESTRICTIVE != level && - USPOOF_MINIMALLY_RESTRICTIVE != level && - USPOOF_UNRESTRICTIVE != level) { - zend_argument_value_error(1, "must be one of Spoofchecker::ASCII, Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE, " - "Spoofchecker::SINGLE_HIGHLY_RESTRICTIVE, Spoofchecker::SINGLE_MODERATELY_RESTRICTIVE, " - "Spoofchecker::SINGLE_MINIMALLY_RESTRICTIVE, or Spoofchecker::UNRESTRICTIVE"); - RETURN_THROWS(); - } - - uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level); -} -/* }}} */ -#endif - -PHP_METHOD(Spoofchecker, setAllowedChars) -{ - zend_string *pattern; - UChar *upattern = NULL; - int32_t upattern_len = 0; - zend_long pattern_option = 0; - SPOOFCHECKER_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR(pattern) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(pattern_option) - ZEND_PARSE_PARAMETERS_END(); - SPOOFCHECKER_METHOD_FETCH_OBJECT; - - if (ZSTR_LEN(pattern) > INT32_MAX) { - zend_argument_value_error(1, "must be less than or equal to " ZEND_LONG_FMT " bytes long", INT32_MAX); - RETURN_THROWS(); - } - - /* uset_applyPattern requires to start with a regex range char */ - if (ZSTR_VAL(pattern)[0] != '[' || ZSTR_VAL(pattern)[ZSTR_LEN(pattern) -1] != ']') { - zend_argument_value_error(1, "must be a valid regular expression character set pattern"); - RETURN_THROWS(); - } - - intl_convert_utf8_to_utf16(&upattern, &upattern_len, ZSTR_VAL(pattern), ZSTR_LEN(pattern), SPOOFCHECKER_ERROR_CODE_P(co)); - if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { - zend_argument_value_error(1, "string conversion to unicode encoding failed (%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); - RETURN_THROWS(); - } - - USet *set = uset_openEmpty(); - - /* pattern is either USE_IGNORE_SPACE alone or in conjunction with the following flags (but mutually exclusive) */ - if (pattern_option && - pattern_option != USET_IGNORE_SPACE && -#if U_ICU_VERSION_MAJOR_NUM >= 73 - pattern_option != (USET_IGNORE_SPACE|USET_SIMPLE_CASE_INSENSITIVE) && -#endif - pattern_option != (USET_IGNORE_SPACE|USET_CASE_INSENSITIVE) && - pattern_option != (USET_IGNORE_SPACE|USET_ADD_CASE_MAPPINGS)) { - zend_argument_value_error(2, "must be a valid pattern option, 0 or (SpoofChecker::IGNORE_SPACE|( or SpoofChecker::USET_CASE_INSENSITIVE or SpoofChecker::USET_ADD_CASE_MAPPINGS" -#if U_ICU_VERSION_MAJOR_NUM >= 73 - " or SpoofChecker::USET_SIMPLE_CASE_INSENSITIVE" -#endif - "))" - ); - uset_close(set); - efree(upattern); - RETURN_THROWS(); - } - - uset_applyPattern(set, upattern, upattern_len, (uint32_t)pattern_option, SPOOFCHECKER_ERROR_CODE_P(co)); - if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { - zend_argument_value_error(1, "must be a valid regular expression character set pattern (%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); - uset_close(set); - efree(upattern); - RETURN_THROWS(); - } - - uset_compact(set); - uspoof_setAllowedChars(co->uspoof, set, SPOOFCHECKER_ERROR_CODE_P(co)); - uset_close(set); - efree(upattern); - - if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { - php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); - } -} diff --git a/ext/intl/spoofchecker/spoofchecker_main.cpp b/ext/intl/spoofchecker/spoofchecker_main.cpp new file mode 100644 index 000000000000..73e14cabeaf1 --- /dev/null +++ b/ext/intl/spoofchecker/spoofchecker_main.cpp @@ -0,0 +1,243 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Scott MacVicar | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "intl_convert.h" +} +#include "spoofchecker_class.h" + +/* {{{ Checks if a given text contains any suspicious characters */ +U_CFUNC PHP_METHOD(Spoofchecker, isSuspicious) +{ + int32_t ret, errmask; + zend_string *text; + zval *error_code = NULL; + SPOOFCHECKER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(text) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(error_code) + ZEND_PARSE_PARAMETERS_END(); + + SPOOFCHECKER_METHOD_FETCH_OBJECT; + +#if U_ICU_VERSION_MAJOR_NUM >= 58 + ret = uspoof_check2UTF8(co->uspoof, ZSTR_VAL(text), ZSTR_LEN(text), co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); +#else + ret = uspoof_checkUTF8(co->uspoof, ZSTR_VAL(text), ZSTR_LEN(text), NULL, SPOOFCHECKER_ERROR_CODE_P(co)); +#endif + + if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { + php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); +#if U_ICU_VERSION_MAJOR_NUM >= 58 + errmask = uspoof_getCheckResultChecks(co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co)); + + if (errmask != ret) { + php_error_docref(NULL, E_WARNING, "unexpected error (%d), does not relate to the flags passed to setChecks (%d)", ret, errmask); + } +#endif + RETURN_TRUE; + } + + if (error_code) { + ZEND_TRY_ASSIGN_REF_LONG(error_code, ret); + } + RETVAL_BOOL(ret != 0); +} +/* }}} */ + +/* {{{ Checks if a given text contains any confusable characters */ +U_CFUNC PHP_METHOD(Spoofchecker, areConfusable) +{ + int ret; + zend_string *s1, *s2; + zval *error_code = NULL; + SPOOFCHECKER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(s1) + Z_PARAM_STR(s2) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(error_code) + ZEND_PARSE_PARAMETERS_END(); + + SPOOFCHECKER_METHOD_FETCH_OBJECT; + if(ZSTR_LEN(s1) > INT32_MAX || ZSTR_LEN(s2) > INT32_MAX) { + SPOOFCHECKER_ERROR_CODE(co) = U_BUFFER_OVERFLOW_ERROR; + } else { + ret = uspoof_areConfusableUTF8(co->uspoof, ZSTR_VAL(s1), (int32_t)ZSTR_LEN(s1), ZSTR_VAL(s2), (int32_t)ZSTR_LEN(s2), SPOOFCHECKER_ERROR_CODE_P(co)); + } + if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { + php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); + RETURN_TRUE; + } + + if (error_code) { + ZEND_TRY_ASSIGN_REF_LONG(error_code, ret); + } + RETVAL_BOOL(ret != 0); +} +/* }}} */ + +/* {{{ Locales to use when running checks */ +U_CFUNC PHP_METHOD(Spoofchecker, setAllowedLocales) +{ + zend_string *locales; + SPOOFCHECKER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(locales) + ZEND_PARSE_PARAMETERS_END(); + + SPOOFCHECKER_METHOD_FETCH_OBJECT; + + uspoof_setAllowedLocales(co->uspoof, ZSTR_VAL(locales), SPOOFCHECKER_ERROR_CODE_P(co)); + + if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { + php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); + return; + } +} +/* }}} */ + +/* {{{ Set the checks to run */ +U_CFUNC PHP_METHOD(Spoofchecker, setChecks) +{ + zend_long checks; + SPOOFCHECKER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(checks) + ZEND_PARSE_PARAMETERS_END(); + + SPOOFCHECKER_METHOD_FETCH_OBJECT; + + uspoof_setChecks(co->uspoof, checks, SPOOFCHECKER_ERROR_CODE_P(co)); + + if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { + php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); + } +} +/* }}} */ + +/* TODO Document this method on PHP.net */ +/* {{{ Set the loosest restriction level allowed for strings. */ +U_CFUNC PHP_METHOD(Spoofchecker, setRestrictionLevel) +{ + zend_long level; + SPOOFCHECKER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(level) + ZEND_PARSE_PARAMETERS_END(); + + SPOOFCHECKER_METHOD_FETCH_OBJECT; + + if (USPOOF_ASCII != level && + USPOOF_SINGLE_SCRIPT_RESTRICTIVE != level && + USPOOF_HIGHLY_RESTRICTIVE != level && + USPOOF_MODERATELY_RESTRICTIVE != level && + USPOOF_MINIMALLY_RESTRICTIVE != level && + USPOOF_UNRESTRICTIVE != level) { + zend_argument_value_error(1, "must be one of Spoofchecker::ASCII, Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE, " + "Spoofchecker::HIGHLY_RESTRICTIVE, Spoofchecker::MODERATELY_RESTRICTIVE, " + "Spoofchecker::MINIMALLY_RESTRICTIVE, or Spoofchecker::UNRESTRICTIVE"); + RETURN_THROWS(); + } + + uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level); +} +/* }}} */ + +U_CFUNC PHP_METHOD(Spoofchecker, setAllowedChars) +{ + zend_string *pattern; + UChar *upattern = NULL; + int32_t upattern_len = 0; + zend_long pattern_option = 0; + SPOOFCHECKER_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(pattern) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(pattern_option) + ZEND_PARSE_PARAMETERS_END(); + SPOOFCHECKER_METHOD_FETCH_OBJECT; + + if (ZSTR_LEN(pattern) > INT32_MAX) { + zend_argument_value_error(1, "must be less than or equal to " ZEND_LONG_FMT " bytes long", INT32_MAX); + RETURN_THROWS(); + } + + /* uset_applyPattern requires to start with a regex range char */ + if (ZSTR_VAL(pattern)[0] != '[' || ZSTR_VAL(pattern)[ZSTR_LEN(pattern) -1] != ']') { + zend_argument_value_error(1, "must be a valid regular expression character set pattern"); + RETURN_THROWS(); + } + + intl_convert_utf8_to_utf16(&upattern, &upattern_len, ZSTR_VAL(pattern), ZSTR_LEN(pattern), SPOOFCHECKER_ERROR_CODE_P(co)); + if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { + zend_argument_value_error(1, "string conversion to unicode encoding failed (%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); + RETURN_THROWS(); + } + + USet *set = uset_openEmpty(); + + /* pattern is either USE_IGNORE_SPACE alone or in conjunction with the following flags (but mutually exclusive) */ + if (pattern_option && + pattern_option != USET_IGNORE_SPACE && +#if U_ICU_VERSION_MAJOR_NUM >= 73 + pattern_option != (USET_IGNORE_SPACE|USET_SIMPLE_CASE_INSENSITIVE) && +#endif + pattern_option != (USET_IGNORE_SPACE|USET_CASE_INSENSITIVE) && + pattern_option != (USET_IGNORE_SPACE|USET_ADD_CASE_MAPPINGS)) { + zend_argument_value_error(2, "must be a valid pattern option, 0 or (SpoofChecker::IGNORE_SPACE|( or SpoofChecker::CASE_INSENSITIVE or SpoofChecker::ADD_CASE_MAPPINGS" +#if U_ICU_VERSION_MAJOR_NUM >= 73 + " or SpoofChecker::SIMPLE_CASE_INSENSITIVE" +#endif + "))" + ); + uset_close(set); + efree(upattern); + RETURN_THROWS(); + } + + uset_applyPattern(set, upattern, upattern_len, (uint32_t)pattern_option, SPOOFCHECKER_ERROR_CODE_P(co)); + if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { + zend_argument_value_error(1, "must be a valid regular expression character set pattern (%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); + uset_close(set); + efree(upattern); + RETURN_THROWS(); + } + + uset_compact(set); + uspoof_setAllowedChars(co->uspoof, set, SPOOFCHECKER_ERROR_CODE_P(co)); + uset_close(set); + efree(upattern); + + if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) { + php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co))); + } +} diff --git a/ext/intl/tests/breakiter___construct.phpt b/ext/intl/tests/breakiter___construct.phpt index 74d1b1beaa75..d23f43405796 100644 --- a/ext/intl/tests/breakiter___construct.phpt +++ b/ext/intl/tests/breakiter___construct.phpt @@ -4,12 +4,12 @@ IntlBreakIterator::__construct() should not be callable intl --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Call to private IntlBreakIterator::__construct() from global scope in %s:%d -Stack trace: -#0 {main} - thrown in %s on line %d +--EXPECT-- +Error: Call to private IntlBreakIterator::__construct() from global scope diff --git a/ext/intl/tests/breakiter___construct_error.phpt b/ext/intl/tests/breakiter___construct_error.phpt index 53a92009d3e0..e0e35f5f4f69 100644 --- a/ext/intl/tests/breakiter___construct_error.phpt +++ b/ext/intl/tests/breakiter___construct_error.phpt @@ -5,53 +5,44 @@ intl --FILE-- getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . "\n"; -} - //missing ; at the end: try { var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+')); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator()); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator(1,2,3)); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;', array())); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;', true)); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } $rbbi = new IntlRuleBasedBreakIterator(".;"); try { $rbbi->__construct(".;"); -} catch (Error $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> ---EXPECTF-- -Exception: IntlRuleBasedBreakIterator::__construct(): unable to create RuleBasedBreakIterator from rules (parse error on line 1, offset 31) in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct() expects at least 1 argument, 0 given in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct() expects at most 2 arguments, 3 given in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct(): Argument #2 ($compiled) must be of type bool, array given in %s on line %d - -Exception: IntlRuleBasedBreakIterator::__construct(): unable to create instance from compiled rules in %s on line %d - -Exception: IntlRuleBasedBreakIterator object is already constructed in %s on line %d +--EXPECT-- +IntlException: IntlRuleBasedBreakIterator::__construct(): unable to create RuleBasedBreakIterator from rules (parse error on line 1, offset 31) +ArgumentCountError: IntlRuleBasedBreakIterator::__construct() expects at least 1 argument, 0 given +ArgumentCountError: IntlRuleBasedBreakIterator::__construct() expects at most 2 arguments, 3 given +TypeError: IntlRuleBasedBreakIterator::__construct(): Argument #2 ($compiled) must be of type bool, array given +IntlException: IntlRuleBasedBreakIterator::__construct(): unable to create instance from compiled rules +Error: IntlRuleBasedBreakIterator object is already constructed diff --git a/ext/intl/tests/breakiter_clone_basic.phpt b/ext/intl/tests/breakiter_clone_basic.phpt index ac9197c10510..7fb7837cb8c8 100644 --- a/ext/intl/tests/breakiter_clone_basic.phpt +++ b/ext/intl/tests/breakiter_clone_basic.phpt @@ -4,7 +4,6 @@ IntlBreakIterator: clone handler intl --FILE-- current()); diff --git a/ext/intl/tests/breakiter_factories_basic.phpt b/ext/intl/tests/breakiter_factories_basic.phpt index 440a0e0f4220..00d49e5760d9 100644 --- a/ext/intl/tests/breakiter_factories_basic.phpt +++ b/ext/intl/tests/breakiter_factories_basic.phpt @@ -2,10 +2,10 @@ IntlBreakIterator factories: basic tests --EXTENSIONS-- intl +--INI-- +intl.default_locale=ja --FILE-- setText('foo bar trans'); diff --git a/ext/intl/tests/breakiter_following_basic.phpt b/ext/intl/tests/breakiter_following_basic.phpt index 0e18502c400e..872e73aba3c4 100644 --- a/ext/intl/tests/breakiter_following_basic.phpt +++ b/ext/intl/tests/breakiter_following_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::following(): basic test intl --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_getLocale_basic2.phpt b/ext/intl/tests/breakiter_getLocale_basic2.phpt index ee92043187ae..2ee223ac5218 100644 --- a/ext/intl/tests/breakiter_getLocale_basic2.phpt +++ b/ext/intl/tests/breakiter_getLocale_basic2.phpt @@ -6,8 +6,6 @@ intl = 0) die('skip for ICU < 64.0'); ?> --FILE-- = 64.0'); ?> --FILE-- getLocale(2); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +try { + $bi->getLocale(-1); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: IntlBreakIterator::getLocale(): Argument #1 ($type) must be either Locale::ACTUAL_LOCALE or Locale::VALID_LOCALE +ValueError: IntlBreakIterator::getLocale(): Argument #1 ($type) must be either Locale::ACTUAL_LOCALE or Locale::VALID_LOCALE diff --git a/ext/intl/tests/breakiter_getPartsIterator_basic.phpt b/ext/intl/tests/breakiter_getPartsIterator_basic.phpt index a8b6fffd59f2..4471fe7a497d 100644 --- a/ext/intl/tests/breakiter_getPartsIterator_basic.phpt +++ b/ext/intl/tests/breakiter_getPartsIterator_basic.phpt @@ -8,8 +8,6 @@ if (version_compare(INTL_ICU_VERSION, '57.1') > 0) die('skip for ICU <= 57.1'); ?> --FILE-- getPartsIterator(); diff --git a/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt b/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt index 96833990dd66..4f516c9abf71 100644 --- a/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt +++ b/ext/intl/tests/breakiter_getPartsIterator_basic2.phpt @@ -8,8 +8,6 @@ if (version_compare(INTL_ICU_VERSION, '57.1') <= 0) die('skip for ICU > 57.1'); ?> --FILE-- getPartsIterator(); diff --git a/ext/intl/tests/breakiter_getPartsIterator_error.phpt b/ext/intl/tests/breakiter_getPartsIterator_error.phpt index 0b2ce3c078f0..f1a5c18c825a 100644 --- a/ext/intl/tests/breakiter_getPartsIterator_error.phpt +++ b/ext/intl/tests/breakiter_getPartsIterator_error.phpt @@ -4,7 +4,6 @@ IntlBreakIterator::getPartsIterator(): bad args intl --FILE-- getText()); diff --git a/ext/intl/tests/breakiter_isBoundary_basic.phpt b/ext/intl/tests/breakiter_isBoundary_basic.phpt index 238337b737d5..27a1d2596e29 100644 --- a/ext/intl/tests/breakiter_isBoundary_basic.phpt +++ b/ext/intl/tests/breakiter_isBoundary_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::isBoundary(): basic test intl --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_last_basic.phpt b/ext/intl/tests/breakiter_last_basic.phpt index d3edd504a6e0..6cf579a41e97 100644 --- a/ext/intl/tests/breakiter_last_basic.phpt +++ b/ext/intl/tests/breakiter_last_basic.phpt @@ -4,7 +4,6 @@ IntlBreakIterator::last(): basic test intl --FILE-- setText('foo bar trans'); diff --git a/ext/intl/tests/breakiter_next_basic.phpt b/ext/intl/tests/breakiter_next_basic.phpt index 30d255102aa0..22726bf400e9 100644 --- a/ext/intl/tests/breakiter_next_basic.phpt +++ b/ext/intl/tests/breakiter_next_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::next(): basic test intl --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_preceding_basic.phpt b/ext/intl/tests/breakiter_preceding_basic.phpt index ed238eaef20e..7864f4b3c896 100644 --- a/ext/intl/tests/breakiter_preceding_basic.phpt +++ b/ext/intl/tests/breakiter_preceding_basic.phpt @@ -8,8 +8,6 @@ if (version_compare(INTL_ICU_VERSION, '57.1') > 0) die('skip for ICU <= 57.1'); ?> --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_preceding_basic2.phpt b/ext/intl/tests/breakiter_preceding_basic2.phpt index 4d7ae1eb2e37..04d2e0d65460 100644 --- a/ext/intl/tests/breakiter_preceding_basic2.phpt +++ b/ext/intl/tests/breakiter_preceding_basic2.phpt @@ -8,8 +8,6 @@ if (version_compare(INTL_ICU_VERSION, '57.1') <= 0) die('skip for ICU > 57.1'); ?> --FILE-- setText('foo bar trans zoo bee'); diff --git a/ext/intl/tests/breakiter_previous_basic.phpt b/ext/intl/tests/breakiter_previous_basic.phpt index fcafe672ad92..3f2976261103 100644 --- a/ext/intl/tests/breakiter_previous_basic.phpt +++ b/ext/intl/tests/breakiter_previous_basic.phpt @@ -4,8 +4,6 @@ IntlBreakIterator::previous(): basic test intl --FILE-- setText('foo bar trans'); diff --git a/ext/intl/tests/breakiter_setText_basic.phpt b/ext/intl/tests/breakiter_setText_basic.phpt index 8f15f31008da..1262e4a1e488 100644 --- a/ext/intl/tests/breakiter_setText_basic.phpt +++ b/ext/intl/tests/breakiter_setText_basic.phpt @@ -4,7 +4,6 @@ IntlBreakIterator::setText(): basic test intl --FILE-- --EXPECT-- bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "numfmt_set_symbol: invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "numfmt_set_symbol(): invalid symbol value: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt index 6bfbbd8a2f0a..c06ba8dd277f 100644 --- a/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt +++ b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt @@ -2,6 +2,8 @@ Bug #58756: w.r.t MessageFormatter --EXTENSIONS-- intl +--INI-- +date.timezone=America/New_York --SKIPIF-- --FILE-- compare('h', 'H'); +try { + $a = $c->compare('h', 'H'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->compare('h', 'H') -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-getlocale.phpt b/ext/intl/tests/bug60192-getlocale.phpt index fed0d634cc8d..4d648b3ec718 100644 --- a/ext/intl/tests/bug60192-getlocale.phpt +++ b/ext/intl/tests/bug60192-getlocale.phpt @@ -12,11 +12,11 @@ class Collator2 extends Collator{ } $c = new Collator2(); -$c->getLocale(Locale::ACTUAL_LOCALE); +try { + $c->getLocale(Locale::ACTUAL_LOCALE); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->getLocale(0) -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-getsortkey.phpt b/ext/intl/tests/bug60192-getsortkey.phpt index aeadf8db75a5..39a1c766e7ff 100644 --- a/ext/intl/tests/bug60192-getsortkey.phpt +++ b/ext/intl/tests/bug60192-getsortkey.phpt @@ -12,11 +12,11 @@ class Collator2 extends Collator{ } $c = new Collator2(); -$c->getSortKey('h'); +try { + $c->getSortKey('h'); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->getSortKey('h') -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-sort.phpt b/ext/intl/tests/bug60192-sort.phpt index 1166df816187..e95fd6237cf1 100644 --- a/ext/intl/tests/bug60192-sort.phpt +++ b/ext/intl/tests/bug60192-sort.phpt @@ -13,11 +13,11 @@ class Collator2 extends Collator{ $c = new Collator2(); $a = array('a', 'b'); -$c->sort($a); +try { + $c->sort($a); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->sort(Array) -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug60192-sortwithsortkeys.phpt b/ext/intl/tests/bug60192-sortwithsortkeys.phpt index 46aacb052ba8..532d153fb5b7 100644 --- a/ext/intl/tests/bug60192-sortwithsortkeys.phpt +++ b/ext/intl/tests/bug60192-sortwithsortkeys.phpt @@ -13,11 +13,11 @@ class Collator2 extends Collator{ $c = new Collator2(); $a = array('a', 'b'); -$c->sortWithSortKeys($a); +try { + $c->sortWithSortKeys($a); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught Error: Object not initialized in %s:%d -Stack trace: -#0 %s(%d): Collator->sortWithSortKeys(Array) -#1 {main} - thrown in %s on line %d +--EXPECT-- +Error: Object not initialized diff --git a/ext/intl/tests/bug62017.phpt b/ext/intl/tests/bug62017.phpt index 53b0deb4fa7d..c149b120246d 100644 --- a/ext/intl/tests/bug62017.phpt +++ b/ext/intl/tests/bug62017.phpt @@ -4,23 +4,20 @@ Bug #62017: datefmt_create with incorrectly encoded timezone leaks pattern intl --FILE-- getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { - new IntlDateFormatter('', IntlDateFormatter::NONE, IntlDateFormatter::NONE, "Europe/Lisbon", + new IntlDateFormatter('', IntlDateFormatter::NONE, IntlDateFormatter::NONE, "Europe/Lisbon", IntlDateFormatter::GREGORIAN, "\x80"); -} catch (IntlException $e) { - echo PHP_EOL."Exception: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> ---EXPECTF-- - -Exception: datefmt_create: Time zone identifier given is not a valid UTF-8 string in %s on line %d - -Exception: IntlDateFormatter::__construct(): datefmt_create: error converting pattern to UTF-16 in %s on line %d +--EXPECT-- +IntlException: datefmt_create(): Time zone identifier given is not a valid UTF-8 string +IntlException: IntlDateFormatter::__construct(): error converting pattern to UTF-16 diff --git a/ext/intl/tests/bug62081.phpt b/ext/intl/tests/bug62081.phpt index d1c066994b6e..5b6f1d50c9bf 100644 --- a/ext/intl/tests/bug62081.phpt +++ b/ext/intl/tests/bug62081.phpt @@ -6,13 +6,12 @@ date.timezone=Atlantic/Azores intl --FILE-- __construct('en', 1, 1)); +try { + var_dump($x->__construct('en', 1, 1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught IntlException: IntlDateFormatter::__construct(): datefmt_create: cannot call constructor twice in %sbug62081.php:4 -Stack trace: -#0 %sbug62081.php(4): IntlDateFormatter->__construct('en', 1, 1) -#1 {main} - thrown in %sbug62081.php on line 4 +--EXPECT-- +IntlException: IntlDateFormatter::__construct(): cannot call constructor twice diff --git a/ext/intl/tests/bug67397.phpt b/ext/intl/tests/bug67397.phpt index 7786c81dd4d0..023f47725ab5 100644 --- a/ext/intl/tests/bug67397.phpt +++ b/ext/intl/tests/bug67397.phpt @@ -5,17 +5,17 @@ intl --FILE-- --EXPECT-- -false -'locale_get_display_name : name too long: U_ILLEGAL_ARGUMENT_ERROR' +bool(false) +string(65) "Locale::getDisplayName(): name too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(66) "locale_get_display_name(): name too long: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/bug72533.phpt b/ext/intl/tests/bug72533.phpt index c7cc90f9c3b9..e294f98213e9 100644 --- a/ext/intl/tests/bug72533.phpt +++ b/ext/intl/tests/bug72533.phpt @@ -5,26 +5,30 @@ intl --FILE-- --EXPECT-- -false -'locale_accept_from_http: locale string too long: U_ILLEGAL_ARGUMENT_ERROR' -'en' +bool(false) +string(74) "Locale::acceptFromHttp(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(75) "locale_accept_from_http(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(74) "Locale::acceptFromHttp(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(75) "locale_accept_from_http(): locale string too long: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/bug75317.phpt b/ext/intl/tests/bug75317.phpt index 1dd96950bb0e..4df45f37bf80 100644 --- a/ext/intl/tests/bug75317.phpt +++ b/ext/intl/tests/bug75317.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #75317 (UConverter::setDestinationEncoding changes source instead of destinatination) +Bug #75317 (UConverter::setDestinationEncoding changes source instead of destination) --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/calendar_add_basic.phpt b/ext/intl/tests/calendar_add_basic.phpt index f732f02f358d..9a7a16f844fd 100644 --- a/ext/intl/tests/calendar_add_basic.phpt +++ b/ext/intl/tests/calendar_add_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::add() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- --EXPECT-- float(1330578367000) -float(1330578367000) \ No newline at end of file +float(1330578367000) diff --git a/ext/intl/tests/calendar_add_error.phpt b/ext/intl/tests/calendar_add_error.phpt deleted file mode 100644 index a56576df4593..000000000000 --- a/ext/intl/tests/calendar_add_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::add(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_add(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_add(1, 2, 3) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_before_after_error.phpt b/ext/intl/tests/calendar_before_after_error.phpt deleted file mode 100644 index 8688059124cc..000000000000 --- a/ext/intl/tests/calendar_before_after_error.phpt +++ /dev/null @@ -1,77 +0,0 @@ ---TEST-- -IntlCalendar::before()/after(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- -after()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->before()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try { - var_dump($c->after(1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->before(1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try{ - var_dump($c->after($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->before($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try { - var_dump(intlcal_after($c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_before($c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::after() expects exactly 1 argument, 0 given - -error: 0, IntlCalendar::before() expects exactly 1 argument, 0 given - -error: 0, IntlCalendar::after(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, IntlCalendar::before(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, IntlCalendar::after() expects exactly 1 argument, 2 given - -error: 0, IntlCalendar::before() expects exactly 1 argument, 2 given - -error: 0, intlcal_after() expects exactly 2 arguments, 1 given - -error: 0, intlcal_before() expects exactly 2 arguments, 1 given diff --git a/ext/intl/tests/calendar_clear_basic.phpt b/ext/intl/tests/calendar_clear_basic.phpt index df3ecc975896..f9edbac9c03d 100644 --- a/ext/intl/tests/calendar_clear_basic.phpt +++ b/ext/intl/tests/calendar_clear_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::clear() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- clear()); @@ -33,4 +33,4 @@ int(0) int(0) int(0) int(0) -float(-3600000) \ No newline at end of file +float(-3600000) diff --git a/ext/intl/tests/calendar_clear_error.phpt b/ext/intl/tests/calendar_clear_error.phpt index 7880275a7c10..8f1695564e94 100644 --- a/ext/intl/tests/calendar_clear_error.phpt +++ b/ext/intl/tests/calendar_clear_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::clear(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -20,13 +18,7 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_clear(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::clear(): Argument #1 ($field) must be a valid field intlcal_clear(): Argument #2 ($field) must be a valid field -intlcal_clear(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_clear_variation1.phpt b/ext/intl/tests/calendar_clear_variation1.phpt index 75f026d0521c..a485747f4d23 100644 --- a/ext/intl/tests/calendar_clear_variation1.phpt +++ b/ext/intl/tests/calendar_clear_variation1.phpt @@ -1,7 +1,7 @@ --TEST-- IntlCalendar::clear() 1 arg variation --INI-- -date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --SKIPIF-- @@ -12,16 +12,14 @@ if (version_compare(INTL_ICU_VERSION, '73.1') >= 0 && version_compare(INTL_ICU_V ?> --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); -//print_R($intlcal); + var_dump($intlcal->isSet(IntlCalendar::FIELD_MONTH)); var_dump($intlcal->clear(IntlCalendar::FIELD_MONTH)); var_dump($intlcal->isSet(IntlCalendar::FIELD_MONTH)); -//print_R($intlcal); + var_dump( $intlcal->getTime(), strtotime('2012-01-29 05:06:07 +0000') * 1000. diff --git a/ext/intl/tests/calendar_createInstance_basic.phpt b/ext/intl/tests/calendar_createInstance_basic.phpt index c2ddd976094e..f19f7c053588 100644 --- a/ext/intl/tests/calendar_createInstance_basic.phpt +++ b/ext/intl/tests/calendar_createInstance_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::createInstance() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl +date.timezone=Europe/Amsterdam --FILE-- getTimeZone()); diff --git a/ext/intl/tests/calendar_createInstance_error.phpt b/ext/intl/tests/calendar_createInstance_error.phpt index a48b6b12c2d1..28ade19b8fc8 100644 --- a/ext/intl/tests/calendar_createInstance_error.phpt +++ b/ext/intl/tests/calendar_createInstance_error.phpt @@ -4,7 +4,6 @@ IntlCalendar::createInstance: bad arguments intl --FILE-- --EXPECT-- -intlcal_create_instance: passed IntlTimeZone is not properly constructed +intlcal_create_instance(): passed IntlTimeZone is not properly constructed diff --git a/ext/intl/tests/calendar_createInstance_variation1.phpt b/ext/intl/tests/calendar_createInstance_variation1.phpt index a963e9ef7590..4c0848d80f1c 100644 --- a/ext/intl/tests/calendar_createInstance_variation1.phpt +++ b/ext/intl/tests/calendar_createInstance_variation1.phpt @@ -2,12 +2,11 @@ IntlCalendar::createInstance() argument variations --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam +intl.default_locale=nl --FILE-- getTimeZone()); diff --git a/ext/intl/tests/calendar_equals_before_after_basic.phpt b/ext/intl/tests/calendar_equals_before_after_basic.phpt index 36999bcb4ebf..4a7db1a708f9 100644 --- a/ext/intl/tests/calendar_equals_before_after_basic.phpt +++ b/ext/intl/tests/calendar_equals_before_after_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::equals(), ::before() and ::after() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- equals()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->equals(new stdclass)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->equals(1, 2)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - - -try { - var_dump(intlcal_equals($c, array())); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_equals(1, $c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::equals() expects exactly 1 argument, 0 given - -error: 0, IntlCalendar::equals(): Argument #1 ($other) must be of type IntlCalendar, stdClass given - -error: 0, IntlCalendar::equals() expects exactly 1 argument, 2 given - -error: 0, intlcal_equals(): Argument #2 ($other) must be of type IntlCalendar, array given - -error: 0, intlcal_equals(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_fieldDifference_basic.phpt b/ext/intl/tests/calendar_fieldDifference_basic.phpt index 4c910092a729..cb13fba7072d 100644 --- a/ext/intl/tests/calendar_fieldDifference_basic.phpt +++ b/ext/intl/tests/calendar_fieldDifference_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::fieldDifference() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); @@ -28,4 +27,4 @@ var_dump( --EXPECT-- int(3601) int(6) -int(61) \ No newline at end of file +int(61) diff --git a/ext/intl/tests/calendar_fieldDifference_error.phpt b/ext/intl/tests/calendar_fieldDifference_error.phpt index f538a0db6625..31070a395290 100644 --- a/ext/intl/tests/calendar_fieldDifference_error.phpt +++ b/ext/intl/tests/calendar_fieldDifference_error.phpt @@ -1,38 +1,16 @@ --TEST-- IntlCalendar::fieldDifference(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- fieldDifference($c, 2, 3)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} var_dump($c->fieldDifference(INF, 2)); +var_dump($c->getErrorMessage()); -try { - var_dump(intlcal_field_difference($c, 0, 1, 2)); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -var_dump(intlcal_field_difference(1, 0, 1)); ?> ---EXPECTF-- -IntlCalendar::fieldDifference() expects exactly 2 arguments, 3 given - -Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: Call to ICU method has failed in %s on line %d +--EXPECT-- bool(false) -intlcal_field_difference() expects exactly 3 arguments, 4 given - -Fatal error: Uncaught TypeError: intlcal_field_difference(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_field_difference(1, 0, 1) -#1 {main} - thrown in %s on line %d +string(88) "IntlCalendar::fieldDifference(): Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/calendar_fromDateTime_basic.phpt b/ext/intl/tests/calendar_fromDateTime_basic.phpt index ba68b267563c..d91a0e80bc67 100644 --- a/ext/intl/tests/calendar_fromDateTime_basic.phpt +++ b/ext/intl/tests/calendar_fromDateTime_basic.phpt @@ -2,11 +2,11 @@ IntlCalendar::fromDateTime(): basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl_NL +date.timezone=Europe/Lisbon --FILE-- getMessage(), PHP_EOL; } + class A extends DateTime { -function __construct() {} + function __construct() {} } var_dump(IntlCalendar::fromDateTime(new A)); +var_dump(intl_get_error_message()); $date = new DateTime('2012-01-01 00:00:00 +24:00'); var_dump(IntlCalendar::fromDateTime($date)); +var_dump(intl_get_error_message()); $date = new DateTime('2012-01-01 00:00:00 WEST'); var_dump(IntlCalendar::fromDateTime($date)); +var_dump(intl_get_error_message()); + ?> ---EXPECTF-- -threw exception, OK -Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: DateTime object is unconstructed in %s on line %d +--EXPECT-- +DateMalformedStringException: Failed to parse time string (foobar) at position 0 (f): The timezone could not be found in the database NULL - -Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: object has an time zone offset that's too large in %s on line %d +string(88) "IntlCalendar::fromDateTime(): DateTime object is unconstructed: U_ILLEGAL_ARGUMENT_ERROR" NULL - -Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d +string(103) "IntlCalendar::fromDateTime(): object has an time zone offset that's too large: U_ILLEGAL_ARGUMENT_ERROR" NULL +string(127) "IntlCalendar::fromDateTime(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/calendar_getAvailableLocales_basic.phpt b/ext/intl/tests/calendar_getAvailableLocales_basic.phpt index 38824b0924a2..85e5ed9acf91 100644 --- a/ext/intl/tests/calendar_getAvailableLocales_basic.phpt +++ b/ext/intl/tests/calendar_getAvailableLocales_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getAvailableLocales() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- 100); @@ -16,4 +16,4 @@ var_dump(in_array('pt', $locales)); ?> --EXPECT-- bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt b/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt index 1694d87c59b4..7097b495da67 100644 --- a/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt +++ b/ext/intl/tests/calendar_getDayOfWeekType_basic2.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getDayOfWeekType() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 00:00:00 +0000') * 1000); diff --git a/ext/intl/tests/calendar_getDayOfWeekType_error.phpt b/ext/intl/tests/calendar_getDayOfWeekType_error.phpt index e239f830f17e..fdea44c17fa8 100644 --- a/ext/intl/tests/calendar_getDayOfWeekType_error.phpt +++ b/ext/intl/tests/calendar_getDayOfWeekType_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::getDayOfWeekOfType(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -14,12 +12,6 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get_day_of_week_type(1, 1)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::getDayOfWeekType(): Argument #1 ($dayOfWeek) must be a valid day of the week -intlcal_get_day_of_week_type(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_getErrorCode_error.phpt b/ext/intl/tests/calendar_getErrorCode_error.phpt deleted file mode 100644 index cd4c644f1faa..000000000000 --- a/ext/intl/tests/calendar_getErrorCode_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getErrorCode(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_error_code(): Argument #1 ($calendar) must be of type IntlCalendar, null given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_error_code(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt b/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt index 689ec4b16a29..e1431f5815db 100644 --- a/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt +++ b/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt @@ -2,38 +2,35 @@ IntlCalendar::getErrorCode(), ::getErrorMessage() basic test --INI-- date.timezone=Atlantic/Azores +intl.default_locale=nl --EXTENSIONS-- intl --FILE-- getErrorCode(), - intlcal_get_error_code($intlcal), - $intlcal->getErrorMessage(), - intlcal_get_error_message($intlcal) + $intlcal->getErrorCode(), + intlcal_get_error_code($intlcal), + $intlcal->getErrorMessage(), + intlcal_get_error_message($intlcal) ); $intlcal->add(IntlCalendar::FIELD_SECOND, 2147483647); $intlcal->fieldDifference(-PHP_INT_MAX, IntlCalendar::FIELD_SECOND); var_dump( - $intlcal->getErrorCode(), - intlcal_get_error_code($intlcal), - $intlcal->getErrorMessage(), - intlcal_get_error_message($intlcal) + $intlcal->getErrorCode(), + intlcal_get_error_code($intlcal), + $intlcal->getErrorMessage(), + intlcal_get_error_message($intlcal) ); ?> ---EXPECTF-- +--EXPECT-- int(0) int(0) string(12) "U_ZERO_ERROR" string(12) "U_ZERO_ERROR" - -Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: Call to ICU method has failed in %s on line %d int(1) int(1) -string(81) "intlcal_field_difference: Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" -string(81) "intlcal_field_difference: Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" +string(88) "IntlCalendar::fieldDifference(): Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" +string(88) "IntlCalendar::fieldDifference(): Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/calendar_getErrorMessage_error.phpt b/ext/intl/tests/calendar_getErrorMessage_error.phpt deleted file mode 100644 index c6713290bea3..000000000000 --- a/ext/intl/tests/calendar_getErrorMessage_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getErrorMessage(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_error_message(): Argument #1 ($calendar) must be of type IntlCalendar, null given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_error_message(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt b/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt index 0cf0b8852787..ae91595afbab 100644 --- a/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt +++ b/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getFirstDayOfWeek() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- getFirstDayOfWeek()); @@ -13,4 +13,4 @@ var_dump(intlcal_get_first_day_of_week($intlcal)); ?> --EXPECT-- int(2) -int(2) \ No newline at end of file +int(2) diff --git a/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt b/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt deleted file mode 100644 index fb129437a7ce..000000000000 --- a/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getFirstDayOfWeek(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_first_day_of_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_first_day_of_week(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt b/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt index e6c05aa4273d..eea0a325b96c 100644 --- a/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt +++ b/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt @@ -4,27 +4,20 @@ IntlCalendar::getKeywordValuesForLocale() basic test intl --FILE-- 8); var_dump(in_array('japanese', $var)); ?> --EXPECT-- -Array -( - [0] => gregorian -) +array(1) { + [0]=> + string(9) "gregorian" +} bool(true) bool(true) diff --git a/ext/intl/tests/calendar_getLocale_basic.phpt b/ext/intl/tests/calendar_getLocale_basic.phpt index 92311ad41911..9c3eece1c5fa 100644 --- a/ext/intl/tests/calendar_getLocale_basic.phpt +++ b/ext/intl/tests/calendar_getLocale_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getLocale() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- getLocale(Locale::ACTUAL_LOCALE)); diff --git a/ext/intl/tests/calendar_getLocale_error.phpt b/ext/intl/tests/calendar_getLocale_error.phpt deleted file mode 100644 index 7b51734fe271..000000000000 --- a/ext/intl/tests/calendar_getLocale_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getLocale(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught ArgumentCountError: intlcal_get_locale() expects exactly 2 arguments, 1 given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_locale(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt index 42f7a56b440e..fe34cd04899b 100644 --- a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt +++ b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt @@ -2,10 +2,10 @@ IntlCalendar::getMinimalDaysInFirstWeek() basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl --FILE-- getMinimalDaysInFirstWeek()); diff --git a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt deleted file mode 100644 index 53ff687ee8c4..000000000000 --- a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getMinimalDaysInFirstWeek(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_minimal_days_in_first_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_minimal_days_in_first_week(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getNow_basic.phpt b/ext/intl/tests/calendar_getNow_basic.phpt index ddc21208b0c6..2b5eb8963426 100644 --- a/ext/intl/tests/calendar_getNow_basic.phpt +++ b/ext/intl/tests/calendar_getNow_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::getNow() basic test intl --FILE-- ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_skipped_wall_time_option(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_skipped_wall_time_option(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getTimeZone_basic.phpt b/ext/intl/tests/calendar_getTimeZone_basic.phpt index 7d19f19be7cf..4b98c1d648dd 100644 --- a/ext/intl/tests/calendar_getTimeZone_basic.phpt +++ b/ext/intl/tests/calendar_getTimeZone_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::getTimeZone() basic test intl --FILE-- getTimeZone()); diff --git a/ext/intl/tests/calendar_getTimeZone_error.phpt b/ext/intl/tests/calendar_getTimeZone_error.phpt deleted file mode 100644 index fad3a5e7e745..000000000000 --- a/ext/intl/tests/calendar_getTimeZone_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getTimeZone(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_time_zone(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_time_zone(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getTime_basic.phpt b/ext/intl/tests/calendar_getTime_basic.phpt index 97e31011e767..754dfde01474 100644 --- a/ext/intl/tests/calendar_getTime_basic.phpt +++ b/ext/intl/tests/calendar_getTime_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getTime() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- clear(); @@ -22,4 +18,4 @@ var_dump((float)$time*1000, $intlcal->getTime()); ?> --EXPECT-- float(1330473600000) -float(1330473600000) \ No newline at end of file +float(1330473600000) diff --git a/ext/intl/tests/calendar_getTime_error.phpt b/ext/intl/tests/calendar_getTime_error.phpt deleted file mode 100644 index 0f6a470637b1..000000000000 --- a/ext/intl/tests/calendar_getTime_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getTime(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_time(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_time(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getType_basic.phpt b/ext/intl/tests/calendar_getType_basic.phpt index c1ae1d242cde..bca65507eadd 100644 --- a/ext/intl/tests/calendar_getType_basic.phpt +++ b/ext/intl/tests/calendar_getType_basic.phpt @@ -1,19 +1,15 @@ --TEST-- IntlCalendar::getType() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getType()); +var_dump($intlcal->getType()); $intlcal = IntlCalendar::createInstance(null, "nl_NL@calendar=hebrew"); -VAR_DUMP(intlcal_get_type($intlcal)); +var_dump(intlcal_get_type($intlcal)); ?> --EXPECT-- string(9) "gregorian" -string(6) "hebrew" \ No newline at end of file +string(6) "hebrew" diff --git a/ext/intl/tests/calendar_getType_error.phpt b/ext/intl/tests/calendar_getType_error.phpt deleted file mode 100644 index 78d0a57f1549..000000000000 --- a/ext/intl/tests/calendar_getType_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::getType(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_get_type(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_get_type(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_getWeekendTransition_basic.phpt b/ext/intl/tests/calendar_getWeekendTransition_basic.phpt index 2045dc6e3416..4e5cfd41f4cd 100644 --- a/ext/intl/tests/calendar_getWeekendTransition_basic.phpt +++ b/ext/intl/tests/calendar_getWeekendTransition_basic.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- getWeekendTransition(IntlCalendar::DOW_SUNDAY)); diff --git a/ext/intl/tests/calendar_getWeekendTransition_error.phpt b/ext/intl/tests/calendar_getWeekendTransition_error.phpt index 9bd269c9a083..a5e020a6803a 100644 --- a/ext/intl/tests/calendar_getWeekendTransition_error.phpt +++ b/ext/intl/tests/calendar_getWeekendTransition_error.phpt @@ -1,12 +1,9 @@ --TEST-- IntlCalendar::getWeekendTransition(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get_weekend_transition(1, 1)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} - ?> --EXPECT-- IntlCalendar::getWeekendTransition(): Argument #1 ($dayOfWeek) must be a valid day of the week -intlcal_get_weekend_transition(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_getXMaximum_basic.phpt b/ext/intl/tests/calendar_getXMaximum_basic.phpt index 5e5ae778b2d2..35b8a202d397 100644 --- a/ext/intl/tests/calendar_getXMaximum_basic.phpt +++ b/ext/intl/tests/calendar_getXMaximum_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getMaximum(), ::getActualMaximum(), ::getLeastMaximum() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); @@ -27,4 +23,4 @@ int(28) int(29) int(29) int(31) -int(31) \ No newline at end of file +int(31) diff --git a/ext/intl/tests/calendar_getXMinimum_basic.phpt b/ext/intl/tests/calendar_getXMinimum_basic.phpt index c8b6c2e97878..671acc6806af 100644 --- a/ext/intl/tests/calendar_getXMinimum_basic.phpt +++ b/ext/intl/tests/calendar_getXMinimum_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::getMinimum(), ::getActualMinimum(), ::getGreatestMinimum() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000); @@ -27,4 +23,4 @@ int(1) int(1) int(1) int(1) -int(1) \ No newline at end of file +int(1) diff --git a/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt b/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt index 1cab590955d9..30365162820c 100644 --- a/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt +++ b/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::get/Least/Greatest/Minimum/Maximum(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -51,26 +49,6 @@ try { echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get_least_maximum(1, 1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_maximum(1, 1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_greatest_minimum(1, -1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_minimum(1, -1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- ValueError: 0, IntlCalendar::getLeastMaximum(): Argument #1 ($field) must be a valid field @@ -81,7 +59,3 @@ ValueError: 0, intlcal_get_least_maximum(): Argument #2 ($field) must be a valid ValueError: 0, intlcal_get_maximum(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_greatest_minimum(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_minimum(): Argument #2 ($field) must be a valid field -TypeError: 0, intlcal_get_least_maximum(): Argument #1 ($calendar) must be of type IntlCalendar, int given -TypeError: 0, intlcal_get_maximum(): Argument #1 ($calendar) must be of type IntlCalendar, int given -TypeError: 0, intlcal_get_greatest_minimum(): Argument #1 ($calendar) must be of type IntlCalendar, int given -TypeError: 0, intlcal_get_minimum(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_get_basic.phpt b/ext/intl/tests/calendar_get_basic.phpt index b22092010b33..37a61b83d0b4 100644 --- a/ext/intl/tests/calendar_get_basic.phpt +++ b/ext/intl/tests/calendar_get_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::get() basic test intl --FILE-- set(IntlCalendar::FIELD_DAY_OF_MONTH, 4); @@ -16,4 +14,4 @@ var_dump(intlcal_get($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH)); ?> --EXPECT-- int(4) -int(4) \ No newline at end of file +int(4) diff --git a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt index 9d40f9ec104e..475c06402225 100644 --- a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt +++ b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::get/getActualMaximum/getActualMinimum(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt index 0cfb77a8947e..10eb7f8029b8 100644 --- a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt +++ b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::get/getActualMaximum/getActualMinimum(): bad arguments (procedural) ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -9,22 +7,6 @@ intl $c = new IntlGregorianCalendar(NULL, 'pt_PT'); -try { - var_dump(intlcal_get($c)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_maximum($c)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_minimum($c)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} - try { var_dump(intlcal_get($c, -1)); } catch (Error $e) { @@ -41,48 +23,8 @@ try { echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_get($c, "s")); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_maximum($c, "s")); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_minimum($c, "s")); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} - -try { - var_dump(intlcal_get(1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_maximum(1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} -try { - var_dump(intlcal_get_actual_minimum(1)); -} catch (Error $e) { - echo get_class($e) . ': ' . $e->getCode() . ', ' . $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- -ArgumentCountError: 0, intlcal_get() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_maximum() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_minimum() expects exactly 2 arguments, 1 given ValueError: 0, intlcal_get(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_actual_maximum(): Argument #2 ($field) must be a valid field ValueError: 0, intlcal_get_actual_minimum(): Argument #2 ($field) must be a valid field -TypeError: 0, intlcal_get(): Argument #2 ($field) must be of type int, string given -TypeError: 0, intlcal_get_actual_maximum(): Argument #2 ($field) must be of type int, string given -TypeError: 0, intlcal_get_actual_minimum(): Argument #2 ($field) must be of type int, string given -ArgumentCountError: 0, intlcal_get() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_maximum() expects exactly 2 arguments, 1 given -ArgumentCountError: 0, intlcal_get_actual_minimum() expects exactly 2 arguments, 1 given diff --git a/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt b/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt index 146885b37700..249f39b7f19d 100644 --- a/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt +++ b/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt @@ -2,12 +2,11 @@ IntlCalendar::get/setRepeatedWallTimeOption(): basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=nl +date.timezone=Europe/Amsterdam --FILE-- setTime(strtotime('2012-01-01') * 1000); @@ -17,4 +13,4 @@ var_dump(intlcal_in_daylight_time($intlcal)); ?> --EXPECT-- bool(false) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_inDaylightTime_error.phpt b/ext/intl/tests/calendar_inDaylightTime_error.phpt deleted file mode 100644 index 7dd6d9c8803e..000000000000 --- a/ext/intl/tests/calendar_inDaylightTime_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::inDaylightTime(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_in_daylight_time(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_in_daylight_time(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_isEquivalentTo_basic.phpt b/ext/intl/tests/calendar_isEquivalentTo_basic.phpt index e9c0a6ec575d..bb01fcfa1f9e 100644 --- a/ext/intl/tests/calendar_isEquivalentTo_basic.phpt +++ b/ext/intl/tests/calendar_isEquivalentTo_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::isEquivalentTo() basic test intl --FILE-- isEquivalentTo(0)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->isEquivalentTo($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->isEquivalentTo(1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try { - var_dump(intlcal_is_equivalent_to($c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_is_equivalent_to($c, 1)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump(intlcal_is_equivalent_to(1, $c)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::isEquivalentTo(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, IntlCalendar::isEquivalentTo() expects exactly 1 argument, 2 given - -error: 0, IntlCalendar::isEquivalentTo(): Argument #1 ($other) must be of type IntlCalendar, int given - -error: 0, intlcal_is_equivalent_to() expects exactly 2 arguments, 1 given - -error: 0, intlcal_is_equivalent_to(): Argument #2 ($other) must be of type IntlCalendar, int given - -error: 0, intlcal_is_equivalent_to(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_isLenient_error.phpt b/ext/intl/tests/calendar_isLenient_error.phpt deleted file mode 100644 index 4011c11cdd89..000000000000 --- a/ext/intl/tests/calendar_isLenient_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::isLenient(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_is_lenient(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_is_lenient(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_isSet_basic.phpt b/ext/intl/tests/calendar_isSet_basic.phpt index 69895d9e93d8..2f6a8b22a391 100644 --- a/ext/intl/tests/calendar_isSet_basic.phpt +++ b/ext/intl/tests/calendar_isSet_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::isSet() basic test intl --FILE-- isSet(IntlCalendar::FIELD_MINUTE)); @@ -17,4 +15,4 @@ var_dump(intlcal_is_set($intlcal, IntlCalendar::FIELD_MINUTE)); --EXPECT-- bool(true) bool(false) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_isSet_error.phpt b/ext/intl/tests/calendar_isSet_error.phpt index 9f1361b8dce1..7f289f073ae0 100644 --- a/ext/intl/tests/calendar_isSet_error.phpt +++ b/ext/intl/tests/calendar_isSet_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::isSet(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -15,12 +13,6 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_is_set(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::isSet(): Argument #1 ($field) must be a valid field -intlcal_is_set(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_isWeekend_basic.phpt b/ext/intl/tests/calendar_isWeekend_basic.phpt index 83408b6283b8..9479bdc0298f 100644 --- a/ext/intl/tests/calendar_isWeekend_basic.phpt +++ b/ext/intl/tests/calendar_isWeekend_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::isWeekend basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- isWeekend(strtotime('2012-02-29 12:00:00 +0000') * 1000)); diff --git a/ext/intl/tests/calendar_isWeekend_error.phpt b/ext/intl/tests/calendar_isWeekend_error.phpt deleted file mode 100644 index d1d49149bf13..000000000000 --- a/ext/intl/tests/calendar_isWeekend_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::isWeekend(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_is_weekend(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_is_weekend(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_is_set_lenient_basic.phpt b/ext/intl/tests/calendar_is_set_lenient_basic.phpt index 4ec0d8cd01ea..e516050f27f7 100644 --- a/ext/intl/tests/calendar_is_set_lenient_basic.phpt +++ b/ext/intl/tests/calendar_is_set_lenient_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::isLenient(), ::setLenient() basic test intl --FILE-- isLenient()); @@ -21,4 +19,4 @@ bool(true) bool(true) bool(false) bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/calendar_roll_basic.phpt b/ext/intl/tests/calendar_roll_basic.phpt index 3a77bafec3ec..a8b088ec384f 100644 --- a/ext/intl/tests/calendar_roll_basic.phpt +++ b/ext/intl/tests/calendar_roll_basic.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- roll(IntlCalendar::FIELD_DAY_OF_MONTH, 2)); diff --git a/ext/intl/tests/calendar_roll_error.phpt b/ext/intl/tests/calendar_roll_error.phpt index 721297f0458b..4c05c17a5f81 100644 --- a/ext/intl/tests/calendar_roll_error.phpt +++ b/ext/intl/tests/calendar_roll_error.phpt @@ -1,7 +1,5 @@ --TEST-- IntlCalendar::roll(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- @@ -15,12 +13,6 @@ try { echo $e->getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_roll(1, 2, 3)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::roll(): Argument #1 ($field) must be a valid field -intlcal_roll(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_roll_variation1.phpt b/ext/intl/tests/calendar_roll_variation1.phpt index a496d6f2e547..d79d5dbb5985 100644 --- a/ext/intl/tests/calendar_roll_variation1.phpt +++ b/ext/intl/tests/calendar_roll_variation1.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- roll(IntlCalendar::FIELD_DAY_OF_MONTH, true)); diff --git a/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt b/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt index 88b2d53ca6cf..a77b00ce640e 100644 --- a/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt +++ b/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::setFirstDayOfWeek() basic test intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set_first_day_of_week(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::setFirstDayOfWeek(): Argument #1 ($dayOfWeek) must be a valid day of the week intlcal_set_first_day_of_week(): Argument #2 ($dayOfWeek) must be a valid day of the week -intlcal_set_first_day_of_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setLenient_error.phpt b/ext/intl/tests/calendar_setLenient_error.phpt deleted file mode 100644 index 13ecebc5fd5b..000000000000 --- a/ext/intl/tests/calendar_setLenient_error.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -IntlCalendar::setLenient(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlcal_set_lenient(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlcal_set_lenient(1, false) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt index 7d47f315ae01..5ac2eb589994 100644 --- a/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt +++ b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::setMinimalDaysInFirstWeek() basic test intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set_minimal_days_in_first_week(1, 2)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::setMinimalDaysInFirstWeek(): Argument #1 ($days) must be between 1 and 7 intlcal_set_minimal_days_in_first_week(): Argument #2 ($days) must be between 1 and 7 -intlcal_set_minimal_days_in_first_week(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt b/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt index 0e3c10d7f55a..8019c81870da 100644 --- a/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt +++ b/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt @@ -1,12 +1,9 @@ --TEST-- IntlCalendar::setSkipped/RepeatedWallTimeOption(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set_repeated_wall_time_option(1, 1)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECT-- IntlCalendar::setSkippedWallTimeOption(): Argument #1 ($option) must be one of IntlCalendar::WALLTIME_FIRST, IntlCalendar::WALLTIME_LAST, or IntlCalendar::WALLTIME_NEXT_VALID IntlCalendar::setRepeatedWallTimeOption(): Argument #1 ($option) must be either IntlCalendar::WALLTIME_FIRST or IntlCalendar::WALLTIME_LAST -intlcal_set_repeated_wall_time_option(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setTimeZone_basic.phpt b/ext/intl/tests/calendar_setTimeZone_basic.phpt index aacc384087dc..bd0be9e87818 100644 --- a/ext/intl/tests/calendar_setTimeZone_basic.phpt +++ b/ext/intl/tests/calendar_setTimeZone_basic.phpt @@ -4,8 +4,6 @@ IntlCalendar::setTimeZone() basic test intl --FILE-- getTimeZone()->getID()); diff --git a/ext/intl/tests/calendar_setTimeZone_error.phpt b/ext/intl/tests/calendar_setTimeZone_error.phpt deleted file mode 100644 index 0cf7939e2de6..000000000000 --- a/ext/intl/tests/calendar_setTimeZone_error.phpt +++ /dev/null @@ -1,49 +0,0 @@ ---TEST-- -IntlCalendar::setTimeZone(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- -setTimeZone($gmt, 2)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try { - var_dump($c->setTimeZone()); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} - -try{ - var_dump(intlcal_set_time_zone($c, 1, 2)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -try{ - var_dump(intlcal_set_time_zone(1, $gmt)); -} catch (Error $ex) { - echo "error: " . $ex->getCode() . ", " . $ex->getMessage() . "\n\n"; -} -?> ---EXPECT-- -error: 0, IntlCalendar::setTimeZone() expects exactly 1 argument, 2 given - -error: 0, IntlCalendar::setTimeZone() expects exactly 1 argument, 0 given - -error: 0, intlcal_set_time_zone() expects exactly 2 arguments, 3 given - -error: 0, intlcal_set_time_zone(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_setTimeZone_error2.phpt b/ext/intl/tests/calendar_setTimeZone_error2.phpt index c76867b695e4..6b65aa1a0e7c 100644 --- a/ext/intl/tests/calendar_setTimeZone_error2.phpt +++ b/ext/intl/tests/calendar_setTimeZone_error2.phpt @@ -2,25 +2,28 @@ IntlCalendar::setTimeZone(): valid time zones for DateTime but not ICU --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam +intl.default_locale=nl --FILE-- setTimeZone($pstdate->getTimeZone()); +var_dump($intlcal->setTimeZone($pstdate->getTimeZone())); +var_dump($intlcal->getErrorMessage()); var_dump($intlcal->getTimeZone()->getID()); $pstdate = new DateTime('2012-01-01 00:00:00 +24:00'); -$intlcal->setTimeZone($pstdate->getTimeZone()); +var_dump($intlcal->setTimeZone($pstdate->getTimeZone())); +var_dump($intlcal->getErrorMessage()); var_dump($intlcal->getTimeZone()->getID()); ?> ---EXPECTF-- -Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d +--EXPECT-- +bool(false) +string(126) "IntlCalendar::setTimeZone(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" string(16) "Europe/Amsterdam" - -Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: object has an time zone offset that's too large in %s on line %d +bool(false) +string(102) "IntlCalendar::setTimeZone(): object has an time zone offset that's too large: U_ILLEGAL_ARGUMENT_ERROR" string(16) "Europe/Amsterdam" diff --git a/ext/intl/tests/calendar_setTimeZone_variation1.phpt b/ext/intl/tests/calendar_setTimeZone_variation1.phpt index 820fd2fd21c0..01d933b9b9af 100644 --- a/ext/intl/tests/calendar_setTimeZone_variation1.phpt +++ b/ext/intl/tests/calendar_setTimeZone_variation1.phpt @@ -4,8 +4,6 @@ IntlCalendar::setTimeZone() variation with NULL arg intl --FILE-- getTimeZone()->getID()); @@ -23,4 +21,4 @@ var_dump($intlcal->get(IntlCalendar::FIELD_ZONE_OFFSET)); Europe/Amsterdam int(3600000) Europe/Amsterdam -int(3600000) \ No newline at end of file +int(3600000) diff --git a/ext/intl/tests/calendar_setTimeZone_variation2.phpt b/ext/intl/tests/calendar_setTimeZone_variation2.phpt index 25ec03c1f576..e9866e88c688 100644 --- a/ext/intl/tests/calendar_setTimeZone_variation2.phpt +++ b/ext/intl/tests/calendar_setTimeZone_variation2.phpt @@ -4,9 +4,6 @@ IntlCalendar::setTimeZone(): different ways to specify time zone intl --FILE-- setTimeZone('Europe/Paris'); diff --git a/ext/intl/tests/calendar_setTime_basic.phpt b/ext/intl/tests/calendar_setTime_basic.phpt index 41f3e0a964ed..045d312e8604 100644 --- a/ext/intl/tests/calendar_setTime_basic.phpt +++ b/ext/intl/tests/calendar_setTime_basic.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::setTime() basic test ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- ---EXPECTF-- -Fatal error: Uncaught ArgumentCountError: intlcal_set_time() expects exactly 2 arguments, 1 given in %s:%d -Stack trace: -#0 %s(%d): intlcal_set_time(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/calendar_set_basic.phpt b/ext/intl/tests/calendar_set_basic.phpt index 8c410bc3b75b..1cd946fdd3c9 100644 --- a/ext/intl/tests/calendar_set_basic.phpt +++ b/ext/intl/tests/calendar_set_basic.phpt @@ -6,8 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- set(IntlCalendar::FIELD_DAY_OF_MONTH, 2)); diff --git a/ext/intl/tests/calendar_set_date_out_of_bounds.phpt b/ext/intl/tests/calendar_set_date_out_of_bounds.phpt new file mode 100644 index 000000000000..db9d18275ae8 --- /dev/null +++ b/ext/intl/tests/calendar_set_date_out_of_bounds.phpt @@ -0,0 +1,32 @@ +--TEST-- +IntlCalendar::setDate(): out-of-bounds arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +setDate(99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDate(1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDate(1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +IntlCalendar::setDate(): Argument #1 ($year) must be between -2147483648 and 2147483647 +IntlCalendar::setDate(): Argument #2 ($month) must be between -2147483648 and 2147483647 +IntlCalendar::setDate(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt b/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt new file mode 100644 index 000000000000..798ab1ebb01f --- /dev/null +++ b/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt @@ -0,0 +1,53 @@ +--TEST-- +IntlCalendar::setDateTime(): out-of-bounds arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +setDateTime(99999999999, 1, 1, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 99999999999, 1, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 99999999999, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +IntlCalendar::setDateTime(): Argument #1 ($year) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #2 ($month) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #4 ($hour) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #5 ($minute) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #6 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_set_error.phpt b/ext/intl/tests/calendar_set_error.phpt index 4494c67c9540..d29442f51950 100644 --- a/ext/intl/tests/calendar_set_error.phpt +++ b/ext/intl/tests/calendar_set_error.phpt @@ -1,12 +1,9 @@ --TEST-- IntlCalendar::set(): bad arguments ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- getMessage() . \PHP_EOL; } -try { - var_dump(intlcal_set(1, 2, 3)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> --EXPECTF-- Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d @@ -50,6 +42,3 @@ IntlCalendar::set(): Argument #1 ($year) must be a valid field Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d intlcal_set(): Argument #2 ($year) must be a valid field - -Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d -intlcal_set(): Argument #1 ($calendar) must be of type IntlCalendar, int given diff --git a/ext/intl/tests/calendar_set_out_of_bounds.phpt b/ext/intl/tests/calendar_set_out_of_bounds.phpt new file mode 100644 index 000000000000..1ca407d3f713 --- /dev/null +++ b/ext/intl/tests/calendar_set_out_of_bounds.phpt @@ -0,0 +1,55 @@ +--TEST-- +IntlCalendar::set(): out-of-bounds date/time arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +set(99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlcal_set($cal, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->set(1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->set(1, 1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlcal_set($cal, 1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #1 ($year) must be between -2147483648 and 2147483647 + +Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d +intlcal_set(): Argument #3 ($month) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #4 ($hour) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #5 ($minute) must be between -2147483648 and 2147483647 + +Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d +intlcal_set(): Argument #7 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_set_variation1.phpt b/ext/intl/tests/calendar_set_variation1.phpt index 520c90948735..1d23a8d03c5d 100644 --- a/ext/intl/tests/calendar_set_variation1.phpt +++ b/ext/intl/tests/calendar_set_variation1.phpt @@ -1,13 +1,9 @@ --TEST-- IntlCalendar::set() argument variations ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --FILE-- clear(); diff --git a/ext/intl/tests/calendar_toDateTime_basic.phpt b/ext/intl/tests/calendar_toDateTime_basic.phpt index 391d13005c69..09942cbe3d8f 100644 --- a/ext/intl/tests/calendar_toDateTime_basic.phpt +++ b/ext/intl/tests/calendar_toDateTime_basic.phpt @@ -2,11 +2,10 @@ IntlCalendar::toDateTime(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon --FILE-- toDateTime()); -} catch (Exception $e) { -var_dump("exception: {$e->getMessage()}"); + var_dump($cal->toDateTime()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } try { var_dump(intlcal_to_date_time($cal)); -} catch (\Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } $cal = IntlCalendar::createInstance("Etc/Unknown"); try { var_dump($cal->toDateTime()); -} catch (\Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } try { var_dump(intlcal_to_date_time($cal)); -} catch (\Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } -try { - var_dump(intlcal_to_date_time(3)); -} catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; -} ?> ---EXPECTF-- -Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(77) "exception: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Warning: intlcal_to_date_time(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Warning: intlcal_to_date_time(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" -intlcal_to_date_time(): Argument #1 ($calendar) must be of type IntlCalendar, int given +--EXPECT-- +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) diff --git a/ext/intl/tests/calendar_uninitialized_argument_position.phpt b/ext/intl/tests/calendar_uninitialized_argument_position.phpt new file mode 100644 index 000000000000..f92367180549 --- /dev/null +++ b/ext/intl/tests/calendar_uninitialized_argument_position.phpt @@ -0,0 +1,36 @@ +--TEST-- +IntlCalendar methods report the correct argument position for uninitialized calendar arguments +--EXTENSIONS-- +intl +--FILE-- +newInstanceWithoutConstructor(); + +foreach (['equals', 'before', 'after', 'isEquivalentTo'] as $method) { + try { + $calendar->$method($uninitialized); + } catch (Error $e) { + echo $method, ': ', $e->getMessage(), PHP_EOL; + } +} + +foreach (['intlcal_equals', 'intlcal_before', 'intlcal_after', 'intlcal_is_equivalent_to'] as $function) { + try { + $function($calendar, $uninitialized); + } catch (Error $e) { + echo $function, ': ', $e->getMessage(), PHP_EOL; + } +} + +?> +--EXPECT-- +equals: IntlCalendar::equals(): Argument #1 ($other) is uninitialized +before: IntlCalendar::before(): Argument #1 ($other) is uninitialized +after: IntlCalendar::after(): Argument #1 ($other) is uninitialized +isEquivalentTo: IntlCalendar::isEquivalentTo(): Argument #1 ($other) is uninitialized +intlcal_equals: intlcal_equals(): Argument #2 ($other) is uninitialized +intlcal_before: intlcal_before(): Argument #2 ($other) is uninitialized +intlcal_after: intlcal_after(): Argument #2 ($other) is uninitialized +intlcal_is_equivalent_to: intlcal_is_equivalent_to(): Argument #2 ($other) is uninitialized diff --git a/ext/intl/tests/collation_customization.phpt b/ext/intl/tests/collation_customization.phpt deleted file mode 100644 index aeb14386fd21..000000000000 --- a/ext/intl/tests/collation_customization.phpt +++ /dev/null @@ -1,70 +0,0 @@ ---TEST-- -Collation customization ---EXTENSIONS-- -intl ---FILE-- - 0 ? ">" : "=" ); - $res .= " $eq $i"; - } - - $prev = $i; - } - $res .= "\n"; - - return $res; -} - -function check_alternate_handling( &$coll ) -{ - $res = ''; - - ut_coll_set_strength( $coll, Collator::TERTIARY ); - ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::NON_IGNORABLE ); - - $res .= cmp_array( $coll, array( 'di Silva', 'Di Silva', 'diSilva', 'U.S.A.', 'USA' ) ); - - ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::SHIFTED ); - - $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) ); - - ut_coll_set_strength( $coll, Collator::QUATERNARY ); - - $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) ); - $res .= "\n"; - - return $res; -} - -function ut_main() -{ - $coll = ut_coll_create( 'en_US' ); - - return - check_alternate_handling( $coll ); -} - -include_once( 'ut_common.inc' ); -ut_run(); -?> ---EXPECT-- -di Silva < Di Silva < diSilva < U.S.A. < USA -di Silva = diSilva < Di Silva < U.S.A. = USA -di Silva < diSilva < Di Silva < U.S.A. < USA diff --git a/ext/intl/tests/collator_create.phpt b/ext/intl/tests/collator_create.phpt new file mode 100644 index 000000000000..2554571ba355 --- /dev/null +++ b/ext/intl/tests/collator_create.phpt @@ -0,0 +1,74 @@ +--TEST-- +Collator creation tests +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +Locale: 'EN-US-ODESSA' + ULOC_REQUESTED_LOCALE = 'EN-US-ODESSA' + ULOC_VALID_LOCALE = 'en_US' + ULOC_ACTUAL_LOCALE = 'root' +Locale: 'UK_UA_ODESSA' + ULOC_REQUESTED_LOCALE = 'UK_UA_ODESSA' + ULOC_VALID_LOCALE = 'uk' + ULOC_ACTUAL_LOCALE = 'uk' +Locale: '' + ULOC_REQUESTED_LOCALE = '' + ULOC_VALID_LOCALE = '%s' + ULOC_ACTUAL_LOCALE = '%s' +Locale: 'root' + ULOC_REQUESTED_LOCALE = 'root' + ULOC_VALID_LOCALE = 'root' + ULOC_ACTUAL_LOCALE = 'root' +Locale: 'uk@currency=EURO' + ULOC_REQUESTED_LOCALE = 'uk@currency=EURO' + ULOC_VALID_LOCALE = 'uk' + ULOC_ACTUAL_LOCALE = 'uk' diff --git a/ext/intl/tests/collator_create4.phpt b/ext/intl/tests/collator_create4.phpt deleted file mode 100644 index 5747d366dcfa..000000000000 --- a/ext/intl/tests/collator_create4.phpt +++ /dev/null @@ -1,78 +0,0 @@ ---TEST-- -create() icu >= 53.1 ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Locale: 'EN-US-ODESSA' - ULOC_REQUESTED_LOCALE = 'EN-US-ODESSA' - ULOC_VALID_LOCALE = 'en_US' - ULOC_ACTUAL_LOCALE = 'root' -Locale: 'UK_UA_ODESSA' - ULOC_REQUESTED_LOCALE = 'UK_UA_ODESSA' - ULOC_VALID_LOCALE = 'uk' - ULOC_ACTUAL_LOCALE = 'uk' -Error creating collator with 'uk-ua_CALIFORNIA@currency=;currency=GRN' locale: collator_create: unable to open ICU collator: U_ILLEGAL_ARGUMENT_ERROR -Locale: '' - ULOC_REQUESTED_LOCALE = '' - ULOC_VALID_LOCALE = '%s' - ULOC_ACTUAL_LOCALE = '%s' -Locale: 'root' - ULOC_REQUESTED_LOCALE = 'root' - ULOC_VALID_LOCALE = 'root' - ULOC_ACTUAL_LOCALE = 'root' -Locale: 'uk@currency=EURO' - ULOC_REQUESTED_LOCALE = 'uk@currency=EURO' - ULOC_VALID_LOCALE = 'uk' - ULOC_ACTUAL_LOCALE = 'uk' -Error creating collator with '12345678911131517192123252729313335373941434547495153575961636567697173757779818385878991939597991234567891113151719212325272931333537394143454749515357596163656769717375777981838587899193959799' locale: Locale string too long, should be no longer than %d characters: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/collator_create_errors.phpt b/ext/intl/tests/collator_create_errors.phpt new file mode 100644 index 000000000000..41fc794f67c1 --- /dev/null +++ b/ext/intl/tests/collator_create_errors.phpt @@ -0,0 +1,40 @@ +--TEST-- +Collator creation errors +--EXTENSIONS-- +intl +--FILE-- +getMessage(), PHP_EOL; + } + + $c = Collator::create($locale); + var_dump($c); + var_dump(intl_get_error_message()); + + $c = collator_create($locale); + var_dump($c); + var_dump(intl_get_error_message()); +} + +?> +--EXPECT-- +IntlException: Collator::__construct(): unable to open ICU collator +NULL +string(73) "Collator::create(): unable to open ICU collator: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(72) "collator_create(): unable to open ICU collator: U_ILLEGAL_ARGUMENT_ERROR" +IntlException: Collator::__construct(): Locale string too long, should be no longer than 156 characters +NULL +string(109) "Collator::create(): Locale string too long, should be no longer than 156 characters: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(108) "collator_create(): Locale string too long, should be no longer than 156 characters: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/collator_customization.phpt b/ext/intl/tests/collator_customization.phpt new file mode 100644 index 000000000000..befb2c129e2c --- /dev/null +++ b/ext/intl/tests/collator_customization.phpt @@ -0,0 +1,69 @@ +--TEST-- +Collation customization +--EXTENSIONS-- +intl +--FILE-- + 0 ? ">" : "=" ); + $res .= " $eq $i"; + } + + $prev = $i; + } + $res .= "\n"; + + return $res; +} + +function check_alternate_handling(Collator $coll) +{ + $res = ''; + + ut_coll_set_strength( $coll, Collator::TERTIARY ); + ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::NON_IGNORABLE ); + + $res .= cmp_array( $coll, array( 'di Silva', 'Di Silva', 'diSilva', 'U.S.A.', 'USA' ) ); + + ut_coll_set_attribute( $coll, Collator::ALTERNATE_HANDLING, Collator::SHIFTED ); + + $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) ); + + ut_coll_set_strength( $coll, Collator::QUATERNARY ); + + $res .= cmp_array( $coll, array( 'di Silva', 'diSilva', 'Di Silva', 'U.S.A.', 'USA' ) ); + $res .= "\n"; + + return $res; +} + +function ut_main() +{ + $coll = ut_coll_create( 'en_US' ); + + return + check_alternate_handling( $coll ); +} + +include_once( 'ut_common.inc' ); +ut_run(); +?> +--EXPECT-- +di Silva < Di Silva < diSilva < U.S.A. < USA +di Silva = diSilva < Di Silva < U.S.A. = USA +di Silva < diSilva < Di Silva < U.S.A. < USA diff --git a/ext/intl/tests/collator_get_error_message.phpt b/ext/intl/tests/collator_get_error_message.phpt deleted file mode 100644 index ad67bc89c5a2..000000000000 --- a/ext/intl/tests/collator_get_error_message.phpt +++ /dev/null @@ -1,36 +0,0 @@ ---TEST-- -get_error_message() ---EXTENSIONS-- -intl ---FILE-- - ---EXPECT-- -U_ZERO_ERROR -Error getting attribute value: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/collator_get_invalid_attribute.phpt b/ext/intl/tests/collator_get_invalid_attribute.phpt new file mode 100644 index 000000000000..11a1e0ef9b64 --- /dev/null +++ b/ext/intl/tests/collator_get_invalid_attribute.phpt @@ -0,0 +1,23 @@ +--TEST-- +Collator get invalid attribute +--EXTENSIONS-- +intl +--FILE-- +getAttribute($attr)); +var_dump($coll->getErrorMessage()); + +var_dump(collator_get_attribute($coll, $attr)); +var_dump(collator_get_error_message($coll)); + +?> +--EXPECT-- +bool(false) +string(81) "Collator::getAttribute(): Error getting attribute value: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(81) "collator_get_attribute(): Error getting attribute value: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/cpbi_clone_equality.phpt b/ext/intl/tests/cpbi_clone_equality.phpt index 37f1998e257a..caea9f8ba08b 100644 --- a/ext/intl/tests/cpbi_clone_equality.phpt +++ b/ext/intl/tests/cpbi_clone_equality.phpt @@ -2,10 +2,10 @@ IntlCodePointBreakIterator: clone and equality --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --FILE-- getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . "\n"; -} try { var_dump(new IntlDateFormatter(NULL, 0, 0, 'bad timezone')); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, 3)); -} catch (IntlException $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } try { var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, new stdclass)); -} catch (TypeError $e) { - print_exception($e); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> ---EXPECTF-- - -Exception: datefmt_create: No such time zone: 'bad timezone' in %s on line %d - -Exception: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s on line %d +--EXPECT-- +IntlException: IntlDateFormatter::__construct(): No such time zone: "bad timezone" +IntlException: IntlDateFormatter::__construct(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object +TypeError: IntlDateFormatter::__construct(): Argument #5 ($calendar) must be of type IntlCalendar|int|null, stdClass given -Exception: IntlDateFormatter::__construct(): Argument #5 ($calendar) must be of type IntlCalendar|int|null, stdClass given in %s on line %d diff --git a/ext/intl/tests/dateformat_bug68893.phpt b/ext/intl/tests/dateformat_bug68893.phpt index 341acd49a6db..b0510097fc50 100644 --- a/ext/intl/tests/dateformat_bug68893.phpt +++ b/ext/intl/tests/dateformat_bug68893.phpt @@ -14,6 +14,6 @@ var_dump($f, intl_get_error_message()); ?> --EXPECT-- NULL -string(67) "datefmt_create: invalid date format style: U_ILLEGAL_ARGUMENT_ERROR" +string(69) "datefmt_create(): invalid date format style: U_ILLEGAL_ARGUMENT_ERROR" NULL -string(67) "datefmt_create: invalid time format style: U_ILLEGAL_ARGUMENT_ERROR" +string(69) "datefmt_create(): invalid time format style: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_calendars_variant.phpt b/ext/intl/tests/dateformat_calendars_variant.phpt new file mode 100644 index 000000000000..48c44c58834a --- /dev/null +++ b/ext/intl/tests/dateformat_calendars_variant.phpt @@ -0,0 +1,35 @@ +--TEST-- +IntlDateFormatter, calendars and time zone +--INI-- +date.timezone=Atlantic/Azores +--EXTENSIONS-- +intl +--SKIPIF-- += 0) die('skip for ICU < 72.1'); ?> +--FILE-- +format(strtotime('2012-01-01 00:00:00 +0000'))); +var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000'))); +var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000'))); + +?> +--EXPECT-- +string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" +string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" +string(44) "Sunday, 6 Tevet 5772 at 5:12:00 AM GMT+05:12" diff --git a/ext/intl/tests/dateformat_calendars_variant3.phpt b/ext/intl/tests/dateformat_calendars_variant3.phpt deleted file mode 100644 index 037d8066a081..000000000000 --- a/ext/intl/tests/dateformat_calendars_variant3.phpt +++ /dev/null @@ -1,48 +0,0 @@ ---TEST-- -IntlDateFormatter, calendars and time zone ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---SKIPIF-- -= 0) die('skip for ICU < 72.1'); ?> ---FILE-- -format(strtotime('2012-01-01 00:00:00 +0000'))); -var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000'))); -var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000'))); - -new IntlDateFormatter('en_US@calendar=hebrew', - IntlDateFormatter::FULL, - IntlDateFormatter::FULL, - 'GMT+05:12', - -1); -?> -==DONE== ---EXPECTF-- -string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" -string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" -string(44) "Sunday, 6 Tevet 5772 at 5:12:00 AM GMT+05:12" - -Fatal error: Uncaught IntlException: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %sdateformat_calendars_variant3.php:%d -Stack trace: -#0 %sdateformat_calendars_variant3.php(%d): IntlDateFormatter->__construct('en_US@calendar=...', 0, 0, 'GMT+05:12', -1) -#1 {main} - thrown %sdateformat_calendars_variant3.php on line %d diff --git a/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt b/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt index c63b302d8e5e..d5d0f437d9b6 100644 --- a/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt +++ b/ext/intl/tests/dateformat_calendars_variant_icu72-1.phpt @@ -8,7 +8,6 @@ intl = 72.1'); ?> --FILE-- format(strtotime('2012-01-01 00:00:00 +0000'))); var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000'))); var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000'))); -new IntlDateFormatter('en_US@calendar=hebrew', - IntlDateFormatter::FULL, - IntlDateFormatter::FULL, - 'GMT+05:12', - -1); ?> -==DONE== ---EXPECTF-- +--EXPECT-- string(49) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" string(49) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" string(46) "Sunday, 6 Tevet 5772 at 5:12:00 AM GMT+05:12" - -Fatal error: Uncaught IntlException: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s:%d -Stack trace: -#0 %s(%d): IntlDateFormatter->__construct('en_US@calendar=...', 0, 0, 'GMT+05:12', -1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt b/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt index 1571e08740ed..ad09a60327d7 100644 --- a/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt +++ b/ext/intl/tests/dateformat_create_cal_arg_variant4.phpt @@ -2,13 +2,13 @@ IntlDateFormatter: several forms of the calendar arg --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 0) die('skip for ICU < 58.1'); ?> --FILE-- = 58.1'); ?> --FILE-- getMessage(), PHP_EOL; +} + +$df = IntlDateFormatter::create($locale, $type, $type, $timezone, $invalidCalendar); +var_dump($df); +var_dump(intl_get_error_message()); + +$df = datefmt_create($locale, $type, $type, $timezone, $invalidCalendar); +var_dump($df); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +IntlException: IntlDateFormatter::__construct(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object +NULL +string(245) "IntlDateFormatter::create(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(234) "datefmt_create(): Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt b/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt index 096d04bbb514..d9a506a1dc41 100644 --- a/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt +++ b/ext/intl/tests/dateformat_formatObject_calendar_variant5.phpt @@ -2,13 +2,13 @@ IntlDateFormatter::formatObject(): IntlCalendar tests --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Europe/Lisbon --SKIPIF-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- getMessage(), "\n"; + var_dump(intl_get_error_message()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; } -$cal = IntlCalendar::createInstance(); +var_dump(IntlDateFormatter::formatObject(new stdclass)); +var_dump(intl_get_error_message()); +var_dump(IntlDateFormatter::formatObject(new A)); +var_dump(intl_get_error_message()); + var_dump(IntlDateFormatter::formatObject($cal, -2)); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array())); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array(1,2,3))); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array(array(), 1))); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, array(1, -2))); +var_dump(intl_get_error_message()); var_dump(IntlDateFormatter::formatObject($cal, "")); +var_dump(intl_get_error_message()); ?> ---EXPECTF-- -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the passed object must be an instance of either IntlCalendar or DateTimeInterface in %s on line %d +--EXPECT-- +DateObjectError: Object of type B (inheriting DateTime) has not been correctly initialized by calling parent::__construct() in its constructor bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad IntlCalendar instance: not initialized properly in %s on line %d +string(130) "IntlDateFormatter::formatObject(): the passed object must be an instance of either IntlCalendar or DateTimeInterface: U_ZERO_ERROR" bool(false) -Object of type B (inheriting DateTime) has not been correctly initialized by calling parent::__construct() in its constructor - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the date/time format type is invalid in %s on line %d +string(112) "IntlDateFormatter::formatObject(): bad IntlCalendar instance: not initialized properly: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; if array, it must have two elements in %s on line %d +string(97) "IntlDateFormatter::formatObject(): the date/time format type is invalid: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; if array, it must have two elements in %s on line %d +string(108) "IntlDateFormatter::formatObject(): bad format; if array, it must have two elements: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; the date format (first element of the array) is not valid in %s on line %d +string(108) "IntlDateFormatter::formatObject(): bad format; if array, it must have two elements: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; the time format (second element of the array) is not valid in %s on line %d +string(130) "IntlDateFormatter::formatObject(): bad format; the date format (first element of the array) is not valid: U_ILLEGAL_ARGUMENT_ERROR" bool(false) - -Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the format is empty in %s on line %d +string(131) "IntlDateFormatter::formatObject(): bad format; the time format (second element of the array) is not valid: U_ILLEGAL_ARGUMENT_ERROR" bool(false) +string(80) "IntlDateFormatter::formatObject(): the format is empty: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_format_code_datetime_objects.phpt b/ext/intl/tests/dateformat_format_code_datetime_objects.phpt new file mode 100644 index 000000000000..eb0511c8a4a1 --- /dev/null +++ b/ext/intl/tests/dateformat_format_code_datetime_objects.phpt @@ -0,0 +1,134 @@ +--TEST-- +datefmt_format_code DateTime input +--EXTENSIONS-- +intl +--FILE-- +setTimezone(new DateTimeZone("America/Los_Angeles")); + + $dates = [$d1, $d2]; + $res_str = ''; + + foreach ($dates as $date_entry) { + foreach ($datetype_arr as $datetype_entry) { + $res_str .= "\n------------"; + $res_str .= "\nDate is: ".var_export($date_entry, true); + $res_str .= "\n------------"; + + $fmt = ut_datefmt_create($locale_entry, $datetype_entry, $datetype_entry, $timezone, IntlDateFormatter::GREGORIAN); + $formatted = ut_datefmt_format($fmt, $date_entry); + + // Replace narrow no-break space (U+202F) with regular space for consistent output. + // INTL doesn't seem to be very consistent about it either + $formatted = str_replace("\u{202F}", ' ', $formatted); + + if (intl_get_error_code() == U_ZERO_ERROR) { + $res_str .= "\nFormatted DateTime is : $formatted"; + } else { + $res_str .= "\nError while formatting as: '" . intl_get_error_message() . "'"; + } + } + } + + return $res_str; +} + +include_once 'ut_common.inc'; +ut_run(); +?> +--EXPECT-- +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03.000000', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : Thursday, December 31, 2009 at 3:02:03 PM GMT-10:00 +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03.000000', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : December 31, 2009 at 3:02:03 PM GMT-10 +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03.000000', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : Dec 31, 2009, 3:02:03 PM +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03.000000', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : 12/31/09, 3:02 PM +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03.000000', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : 20091231 03:02 PM +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05.000000', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : Saturday, December 30, 2000 at 5:04:05 PM GMT-10:00 +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05.000000', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : December 30, 2000 at 5:04:05 PM GMT-10 +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05.000000', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : Dec 30, 2000, 5:04:05 PM +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05.000000', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : 12/30/00, 5:04 PM +------------ +Date is: \DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05.000000', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : 20001230 05:04 PM diff --git a/ext/intl/tests/dateformat_format_code_localtime_array.phpt b/ext/intl/tests/dateformat_format_code_localtime_array.phpt new file mode 100644 index 000000000000..e2432a003bf9 --- /dev/null +++ b/ext/intl/tests/dateformat_format_code_localtime_array.phpt @@ -0,0 +1,130 @@ +--TEST-- +datefmt_format_code localtime array +--EXTENSIONS-- +intl +--FILE-- + 24, + 'tm_min' => 3, + 'tm_hour' => 19, + 'tm_mday' => 3, + 'tm_mon' => 3, + 'tm_year' => 105, + ], + [ + 'tm_sec' => 21, + 'tm_min' => 5, + 'tm_hour' => 7, + 'tm_mday' => 13, + 'tm_mon' => 4, + 'tm_year' => 205, + ], + [ + 'tm_sec' => 11, + 'tm_min' => 13, + 'tm_hour' => 0, + 'tm_mday' => 17, + 'tm_mon' => 11, + 'tm_year' => -5, + ], + ]; + + $res_str = ''; + + foreach ($localtime_arr as $localtime_entry) { + $res_str .= "\n------------\n"; + $res_str .= "\nInput localtime is : "; + $res_str .= implode(' , ', array_map( + function ($k, $v) { + return "$k : '$v'"; + }, + array_keys($localtime_entry), + $localtime_entry + )); + + $res_str .= "\n------------\n"; + + foreach ($datetype_arr as $datetype_entry) { + $res_str .= "\nIntlDateFormatter locale = $locale_entry, datetype = $datetype_entry, timetype = $datetype_entry"; + $fmt = ut_datefmt_create($locale_entry, $datetype_entry, $datetype_entry, $timezone, IntlDateFormatter::GREGORIAN); + $formatted = ut_datefmt_format($fmt, $localtime_entry); + + // Replace narrow no-break space (U+202F) with regular space for consistent output. + // INTL doesn't seem to be very consistent about it either + $formatted = str_replace("\u{202F}", ' ', $formatted); + + if (intl_get_error_code() == U_ZERO_ERROR) { + $res_str .= "\nFormatted localtime_array is : $formatted"; + } else { + $res_str .= "\nError while formatting as: '" . intl_get_error_message() . "'"; + } + } + } + + return $res_str; +} + +include_once 'ut_common.inc'; +ut_run(); +?> +--EXPECT-- +------------ + +Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' +------------ + +IntlDateFormatter locale = en_US, datetype = 0, timetype = 0 +Formatted localtime_array is : Sunday, April 3, 2005 at 7:03:24 PM GMT-10:00 +IntlDateFormatter locale = en_US, datetype = 1, timetype = 1 +Formatted localtime_array is : April 3, 2005 at 7:03:24 PM GMT-10 +IntlDateFormatter locale = en_US, datetype = 2, timetype = 2 +Formatted localtime_array is : Apr 3, 2005, 7:03:24 PM +IntlDateFormatter locale = en_US, datetype = 3, timetype = 3 +Formatted localtime_array is : 4/3/05, 7:03 PM +IntlDateFormatter locale = en_US, datetype = -1, timetype = -1 +Formatted localtime_array is : 20050403 07:03 PM +------------ + +Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '4' , tm_year : '205' +------------ + +IntlDateFormatter locale = en_US, datetype = 0, timetype = 0 +Formatted localtime_array is : Wednesday, May 13, 2105 at 7:05:21 AM GMT-10:00 +IntlDateFormatter locale = en_US, datetype = 1, timetype = 1 +Formatted localtime_array is : May 13, 2105 at 7:05:21 AM GMT-10 +IntlDateFormatter locale = en_US, datetype = 2, timetype = 2 +Formatted localtime_array is : May 13, 2105, 7:05:21 AM +IntlDateFormatter locale = en_US, datetype = 3, timetype = 3 +Formatted localtime_array is : 5/13/05, 7:05 AM +IntlDateFormatter locale = en_US, datetype = -1, timetype = -1 +Formatted localtime_array is : 21050513 07:05 AM +------------ + +Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' +------------ + +IntlDateFormatter locale = en_US, datetype = 0, timetype = 0 +Formatted localtime_array is : Tuesday, December 17, 1895 at 12:13:11 AM GMT-10:00 +IntlDateFormatter locale = en_US, datetype = 1, timetype = 1 +Formatted localtime_array is : December 17, 1895 at 12:13:11 AM GMT-10 +IntlDateFormatter locale = en_US, datetype = 2, timetype = 2 +Formatted localtime_array is : Dec 17, 1895, 12:13:11 AM +IntlDateFormatter locale = en_US, datetype = 3, timetype = 3 +Formatted localtime_array is : 12/17/95, 12:13 AM +IntlDateFormatter locale = en_US, datetype = -1, timetype = -1 +Formatted localtime_array is : 18951217 12:13 AM diff --git a/ext/intl/tests/dateformat_format_code_timestamps.phpt b/ext/intl/tests/dateformat_format_code_timestamps.phpt new file mode 100644 index 000000000000..ac07eb7c479f --- /dev/null +++ b/ext/intl/tests/dateformat_format_code_timestamps.phpt @@ -0,0 +1,175 @@ +--TEST-- +datefmt_format_code with timestamps +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +------------ + +Input timestamp is : 0 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 31, 1969 at 2:00:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 31, 1969 at 2:00:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 31, 1969, 2:00:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/31/69, 2:00 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691231 02:00 PM +------------ + +Input timestamp is : -1200000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 17, 1969 at 4:40:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 17, 1969 at 4:40:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 17, 1969, 4:40:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/17/69, 4:40 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691217 04:40 PM +------------ + +Input timestamp is : 1200000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, January 14, 1970 at 11:20:00 AM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : January 14, 1970 at 11:20:00 AM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Jan 14, 1970, 11:20:00 AM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 1/14/70, 11:20 AM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19700114 11:20 AM +------------ + +Input timestamp is : 2200000000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Sunday, September 18, 2039 at 1:06:40 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : September 18, 2039 at 1:06:40 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Sep 18, 2039, 1:06:40 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 9/18/39, 1:06 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 20390918 01:06 PM +------------ + +Input timestamp is : -2200000000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Saturday, April 14, 1900 at 2:53:20 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : April 14, 1900 at 2:53:20 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Apr 14, 1900, 2:53:20 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 4/14/00, 2:53 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19000414 02:53 PM +------------ + +Input timestamp is : 90099999 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, November 8, 1972 at 9:46:39 AM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : November 8, 1972 at 9:46:39 AM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Nov 8, 1972, 9:46:39 AM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 11/8/72, 9:46 AM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19721108 09:46 AM +------------ + +Input timestamp is : 3600 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 31, 1969 at 3:00:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 31, 1969 at 3:00:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 31, 1969, 3:00:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/31/69, 3:00 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691231 03:00 PM +------------ + +Input timestamp is : -3600 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 31, 1969 at 1:00:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 31, 1969 at 1:00:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 31, 1969, 1:00:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/31/69, 1:00 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691231 01:00 PM diff --git a/ext/intl/tests/dateformat_format_error.phpt b/ext/intl/tests/dateformat_format_error.phpt new file mode 100644 index 000000000000..4358271efd08 --- /dev/null +++ b/ext/intl/tests/dateformat_format_error.phpt @@ -0,0 +1,26 @@ +--TEST-- +IntlDateFormatter->format() errors +--EXTENSIONS-- +intl +--FILE-- +format($object); +var_dump($v); +var_dump(intl_get_error_message()); + +$v = datefmt_format($f, $object); +var_dump($v); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +bool(false) +string(140) "IntlDateFormatter::format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(129) "datefmt_format(): invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/dateformat_format_relative.phpt b/ext/intl/tests/dateformat_format_relative.phpt index c93c1fd4a332..6455264142a6 100644 --- a/ext/intl/tests/dateformat_format_relative.phpt +++ b/ext/intl/tests/dateformat_format_relative.phpt @@ -2,11 +2,11 @@ datefmt_format_code() with relative formats --EXTENSIONS-- intl +--INI +date.timezone=America/Los_Angeles --FILE-- 24 , - 'tm_min' => 3, - 'tm_hour' => 19, - 'tm_mday' => 3, - 'tm_mon' => 3, - 'tm_year' => 105, - ); - $localtime_arr2 = array ( - 'tm_sec' => 21, - 'tm_min' => 5, - 'tm_hour' => 7, - 'tm_mday' => 13, - 'tm_mon' => 4, - 'tm_year' => 205, - ); - $localtime_arr3 = array ( - 'tm_sec' => 11, - 'tm_min' => 13, - 'tm_hour' => 0, - 'tm_mday' => 17, - 'tm_mon' => 11, - 'tm_year' => -5 - ); - - $localtime_arr = array ( - $localtime_arr1, - $localtime_arr2, - $localtime_arr3 - ); - - $d1 = new DateTime("2010-01-01 01:02:03", new DateTimeZone("UTC")); - $d2 = new DateTime("2000-12-31 03:04:05", new DateTimeZone("UTC")); - $d2->setTimezone(new DateTimeZone("PDT")); - $dates = array( - $d1, - $d2, - new StdClass(), - ); - - //Test format with input as a timestamp : integer - foreach( $time_arr as $timestamp_entry){ - $res_str .= "\n------------\n"; - $res_str .= "\nInput timestamp is : $timestamp_entry"; - $res_str .= "\n------------\n"; - foreach( $locale_arr as $locale_entry ){ - foreach( $datetype_arr as $datetype_entry ) - { - $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; - $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN); - $formatted = ut_datefmt_format( $fmt , $timestamp_entry); - $res_str .= "\nFormatted timestamp is : $formatted"; - } - } - } - - //Test format with input as a localtime :array - foreach( $localtime_arr as $localtime_entry){ - $res_str .= "\n------------\n"; - $res_str .= "\nInput localtime is : "; - foreach( $localtime_entry as $key => $value){ - $res_str .= "$key : '$value' , "; - } - - $res_str .= "\n------------\n"; - foreach( $locale_arr as $locale_entry ){ - foreach( $datetype_arr as $datetype_entry ) - { - $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; - $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN ); - $formatted1 = ut_datefmt_format( $fmt , $localtime_entry); - if( intl_get_error_code() == U_ZERO_ERROR){ - $res_str .= "\nFormatted localtime_array is : $formatted1"; - }else{ - $res_str .= "\nError while formatting as: '".intl_get_error_message()."'"; - } - } - } - } - - foreach($dates as $date_entry) { - foreach( $locale_arr as $locale_entry ){ - foreach( $datetype_arr as $datetype_entry ) { - $res_str .= "\n------------"; - $res_str .= "\nDate is: ".var_export($date_entry, true); - $res_str .= "\n------------"; - - $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN ); - $formatted1 = ut_datefmt_format( $fmt , $date_entry); - if( intl_get_error_code() == U_ZERO_ERROR){ - $res_str .= "\nFormatted DateTime is : $formatted1"; - }else{ - $res_str .= "\nError while formatting as: '".intl_get_error_message()."'"; - } - } - } - } - - return $res_str; - -} - -include_once( 'ut_common.inc' ); - -// Run the test -ut_run(); -?> ---EXPECT-- ------------- - -Input timestamp is : 0 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Wednesday, December 31, 1969 at 2:00:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : December 31, 1969 at 2:00:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Dec 31, 1969, 2:00:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 12/31/69, 2:00 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 19691231 02:00 PM ------------- - -Input timestamp is : -1200000 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Wednesday, December 17, 1969 at 4:40:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : December 17, 1969 at 4:40:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Dec 17, 1969, 4:40:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 12/17/69, 4:40 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 19691217 04:40 PM ------------- - -Input timestamp is : 1200000 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Wednesday, January 14, 1970 at 11:20:00 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : January 14, 1970 at 11:20:00 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Jan 14, 1970, 11:20:00 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 1/14/70, 11:20 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 19700114 11:20 AM ------------- - -Input timestamp is : 2200000000 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Sunday, September 18, 2039 at 1:06:40 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : September 18, 2039 at 1:06:40 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Sep 18, 2039, 1:06:40 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 9/18/39, 1:06 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 20390918 01:06 PM ------------- - -Input timestamp is : -2200000000 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Saturday, April 14, 1900 at 2:53:20 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : April 14, 1900 at 2:53:20 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Apr 14, 1900, 2:53:20 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 4/14/00, 2:53 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 19000414 02:53 PM ------------- - -Input timestamp is : 90099999 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Wednesday, November 8, 1972 at 9:46:39 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : November 8, 1972 at 9:46:39 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Nov 8, 1972, 9:46:39 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 11/8/72, 9:46 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 19721108 09:46 AM ------------- - -Input timestamp is : 3600 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Wednesday, December 31, 1969 at 3:00:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : December 31, 1969 at 3:00:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Dec 31, 1969, 3:00:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 12/31/69, 3:00 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 19691231 03:00 PM ------------- - -Input timestamp is : -3600 ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted timestamp is : Wednesday, December 31, 1969 at 1:00:00 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted timestamp is : December 31, 1969 at 1:00:00 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted timestamp is : Dec 31, 1969, 1:00:00 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted timestamp is : 12/31/69, 1:00 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted timestamp is : 19691231 01:00 PM ------------- - -Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' , ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted localtime_array is : Sunday, April 3, 2005 at 7:03:24 PM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted localtime_array is : April 3, 2005 at 7:03:24 PM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted localtime_array is : Apr 3, 2005, 7:03:24 PM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted localtime_array is : 4/3/05, 7:03 PM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted localtime_array is : 20050403 07:03 PM ------------- - -Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '4' , tm_year : '205' , ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted localtime_array is : Wednesday, May 13, 2105 at 7:05:21 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted localtime_array is : May 13, 2105 at 7:05:21 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted localtime_array is : May 13, 2105, 7:05:21 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted localtime_array is : 5/13/05, 7:05 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted localtime_array is : 21050513 07:05 AM ------------- - -Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' , ------------- - -IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 -Formatted localtime_array is : Tuesday, December 17, 1895 at 12:13:11 AM GMT-10:00 -IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 -Formatted localtime_array is : December 17, 1895 at 12:13:11 AM GMT-10 -IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 -Formatted localtime_array is : Dec 17, 1895, 12:13:11 AM -IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 -Formatted localtime_array is : 12/17/95, 12:13 AM -IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 -Formatted localtime_array is : 18951217 12:13 AM ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03.000000', - 'timezone_type' => 3, - 'timezone' => 'UTC', -)) ------------- -Formatted DateTime is : Thursday, December 31, 2009 at 3:02:03 PM GMT-10:00 ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03.000000', - 'timezone_type' => 3, - 'timezone' => 'UTC', -)) ------------- -Formatted DateTime is : December 31, 2009 at 3:02:03 PM GMT-10 ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03.000000', - 'timezone_type' => 3, - 'timezone' => 'UTC', -)) ------------- -Formatted DateTime is : Dec 31, 2009, 3:02:03 PM ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03.000000', - 'timezone_type' => 3, - 'timezone' => 'UTC', -)) ------------- -Formatted DateTime is : 12/31/09, 3:02 PM ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2010-01-01 01:02:03.000000', - 'timezone_type' => 3, - 'timezone' => 'UTC', -)) ------------- -Formatted DateTime is : 20091231 03:02 PM ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05.000000', - 'timezone_type' => 2, - 'timezone' => 'PDT', -)) ------------- -Formatted DateTime is : Saturday, December 30, 2000 at 5:04:05 PM GMT-10:00 ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05.000000', - 'timezone_type' => 2, - 'timezone' => 'PDT', -)) ------------- -Formatted DateTime is : December 30, 2000 at 5:04:05 PM GMT-10 ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05.000000', - 'timezone_type' => 2, - 'timezone' => 'PDT', -)) ------------- -Formatted DateTime is : Dec 30, 2000, 5:04:05 PM ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05.000000', - 'timezone_type' => 2, - 'timezone' => 'PDT', -)) ------------- -Formatted DateTime is : 12/30/00, 5:04 PM ------------- -Date is: \DateTime::__set_state(array( - 'date' => '2000-12-30 19:04:05.000000', - 'timezone_type' => 2, - 'timezone' => 'PDT', -)) ------------- -Formatted DateTime is : 20001230 05:04 PM ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' ------------- -Date is: (object) array( -) ------------- -Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted): U_ILLEGAL_ARGUMENT_ERROR' diff --git a/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt b/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt index 6842cdf1c408..4484bd4647a1 100644 --- a/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt +++ b/ext/intl/tests/dateformat_get_set_calendar_variant4.phpt @@ -2,13 +2,13 @@ IntlDateFormatter: setCalendar()/getCalendar()/getCalendarObject() --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 0) die('skip for ICU < 58.1'); ?> --FILE-- = 58.1 and < 70.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 0) die('skip for ICU >= 58.1 and < 70.1'); ?> --FILE-- = 70.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --SKIPIF-- = 70.1'); ?> --FILE-- getMessage(); -} -?> ---EXPECTF-- -Warning: PHP Startup: Invalid date.timezone value 'Mars/Utopia_Planitia', using 'UTC' instead in %s on line %d -Wat? diff --git a/ext/intl/tests/dateformat_setTimeZone_error.phpt b/ext/intl/tests/dateformat_setTimeZone_error.phpt index b911c4b41ec0..08ed8876d2f7 100644 --- a/ext/intl/tests/dateformat_setTimeZone_error.phpt +++ b/ext/intl/tests/dateformat_setTimeZone_error.phpt @@ -2,27 +2,26 @@ IntlDateFormatter::setTimeZone() bad args --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT +date.timezone=Atlantic/Azores --FILE-- setTimeZone(array()); -} catch (IntlException $e) { - echo $e->getMessage() . PHP_EOL; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } try { $df->setTimeZone('non existing timezone'); -} catch (IntlException $e) { - echo $e->getMessage(); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> ---EXPECTF-- -Warning: Array to string conversion in %s on line %d -datefmt_set_timezone: No such time zone: 'Array' -datefmt_set_timezone: No such time zone: 'non existing timezone' +--EXPECT-- +TypeError: IntlDateFormatter::setTimeZone(): Argument #1 ($timezone) must be of type object|string|null, array given +IntlException: IntlDateFormatter::setTimeZone(): No such time zone: "non existing timezone" diff --git a/ext/intl/tests/dateformat_set_timezone_id3.phpt b/ext/intl/tests/dateformat_set_timezone_id3.phpt index 16c0bb05b9be..89e834aacdb0 100644 --- a/ext/intl/tests/dateformat_set_timezone_id3.phpt +++ b/ext/intl/tests/dateformat_set_timezone_id3.phpt @@ -9,8 +9,6 @@ intl --FILE-- true, 'America/Los_Angeles' => true, 'America/Chicago' => true, - 'CN' => false ); $timestamp_entry = 0; @@ -61,10 +58,7 @@ include_once( 'ut_common.inc' ); // Run the test ut_run(); ?> ---EXPECTF-- -datefmt_set_timezone: No such time zone: 'CN' -datefmt_set_timezone: No such time zone: 'CN' - +--EXPECT-- After creation of the dateformatter : timezone_id= US/Pacific ----------- Trying to set timezone_id= America/New_York @@ -81,8 +75,3 @@ Trying to set timezone_id= America/Chicago After call to set_timezone_id : timezone_id= America/Chicago Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time ------------ -Trying to set timezone_id= CN -After call to set_timezone_id : timezone_id= America/Chicago -Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time -Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time diff --git a/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt b/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt index eebc6f0973a0..6424ba1e6b40 100644 --- a/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt +++ b/ext/intl/tests/dateformat_set_timezone_id_icu72-1.phpt @@ -1,5 +1,5 @@ --TEST-- -datefmt_set_timezone_id_code() icu >= 4.8 +datefmt_set_timezone_id_code() icu >= 72.1 --INI-- date.timezone=Atlantic/Azores --EXTENSIONS-- @@ -9,8 +9,6 @@ intl --FILE-- true, 'America/Los_Angeles' => true, 'America/Chicago' => true, - 'CN' => false ); $timestamp_entry = 0; @@ -61,10 +58,7 @@ include_once( 'ut_common.inc' ); // Run the test ut_run(); ?> ---EXPECTF-- -datefmt_set_timezone: No such time zone: 'CN' -datefmt_set_timezone: No such time zone: 'CN' - +--EXPECT-- After creation of the dateformatter : timezone_id= US/Pacific ----------- Trying to set timezone_id= America/New_York @@ -81,8 +75,3 @@ Trying to set timezone_id= America/Chicago After call to set_timezone_id : timezone_id= America/Chicago Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time ------------ -Trying to set timezone_id= CN -After call to set_timezone_id : timezone_id= America/Chicago -Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time -Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time diff --git a/ext/intl/tests/dateformat_timezone_arg_variations4.phpt b/ext/intl/tests/dateformat_timezone_arg_variations4.phpt index 0c2ea02a56d4..2abdc34a2ac8 100644 --- a/ext/intl/tests/dateformat_timezone_arg_variations4.phpt +++ b/ext/intl/tests/dateformat_timezone_arg_variations4.phpt @@ -2,10 +2,10 @@ IntlDateFormatter: several forms of the timezone arg --EXTENSIONS-- intl +--INI-- +date.timezone=Atlantic/Azores --FILE-- getBestPattern("YYYYMMMddjjmm"), "\n"; diff --git a/ext/intl/tests/datepatterngenerator_error.phpt b/ext/intl/tests/datepatterngenerator_error.phpt index 93419899482f..6ff0e19263f0 100644 --- a/ext/intl/tests/datepatterngenerator_error.phpt +++ b/ext/intl/tests/datepatterngenerator_error.phpt @@ -4,12 +4,12 @@ IntlDatePatternGenerator::getBestPattern(): errors intl --FILE-- getBestPattern("jjmm\x80")); +var_dump(intl_get_error_message()); ?> ---EXPECTF-- -Warning: IntlDatePatternGenerator::getBestPattern(): Skeleton is not a valid UTF-8 string in %s on line %d +--EXPECT-- bool(false) +string(102) "IntlDatePatternGenerator::getBestPattern(): Skeleton is not a valid UTF-8 string: U_INVALID_CHAR_FOUND" diff --git a/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt b/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt index 279554123b79..e67c1be2f1b4 100644 --- a/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt +++ b/ext/intl/tests/datepatterngenerator_get_best_pattern.phpt @@ -2,14 +2,13 @@ IntlDatePatternGenerator::getBestPattern() --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --SKIPIF-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- getBestPattern("YYYYMMMdd"), "\n"; echo $dtpg->getBestPattern(""), "\n"; -try { - $dtpg->getBestPattern(); -} catch(\ArgumentCountError $e) { - echo $e->getMessage(), "\n"; -} - ?> --EXPECT-- h:mm a HH:mm MMM dd, YYYY dd. MMM YYYY - -IntlDatePatternGenerator::getBestPattern() expects exactly 1 argument, 0 given diff --git a/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt b/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt index 2f4f744757ca..c35b2ff8d484 100644 --- a/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt +++ b/ext/intl/tests/datepatterngenerator_get_best_pattern_icu72-1.phpt @@ -2,14 +2,13 @@ IntlDatePatternGenerator::getBestPattern() --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --SKIPIF-- = 72.1'); ?> --FILE-- getBestPattern("YYYYMMMdd"), "\n"; echo $dtpg->getBestPattern(""), "\n"; -try { - $dtpg->getBestPattern(); -} catch(\ArgumentCountError $e) { - echo $e->getMessage(), "\n"; -} - ?> --EXPECT-- h:mm a HH:mm MMM dd, YYYY dd. MMM YYYY - -IntlDatePatternGenerator::getBestPattern() expects exactly 1 argument, 0 given diff --git a/ext/intl/tests/deprecated_U_MULTIPLE_DECIMAL_SEPERATORS.phpt b/ext/intl/tests/deprecated_U_MULTIPLE_DECIMAL_SEPERATORS.phpt new file mode 100644 index 000000000000..33cdbda7d229 --- /dev/null +++ b/ext/intl/tests/deprecated_U_MULTIPLE_DECIMAL_SEPERATORS.phpt @@ -0,0 +1,15 @@ +--TEST-- +U_MULTIPLE_DECIMAL_SEPERATORS is deprecated +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +Deprecated: Constant U_MULTIPLE_DECIMAL_SEPERATORS is deprecated since 8.3, use U_MULTIPLE_DECIMAL_SEPARATORS instead in %s on line %d +int(65793) + +Deprecated: Constant U_MULTIPLE_DECIMAL_SEPERATORS is deprecated since 8.3, use U_MULTIPLE_DECIMAL_SEPARATORS instead in %s on line %d +int(65793) diff --git a/ext/intl/tests/formatter/currencies.phpt b/ext/intl/tests/formatter/currencies.phpt index 01c64a0480d3..1293283e7fc2 100644 --- a/ext/intl/tests/formatter/currencies.phpt +++ b/ext/intl/tests/formatter/currencies.phpt @@ -1,6 +1,6 @@ --TEST-- NumberFormatter: currency formatting -----DESCRIPTION-- +--DESCRIPTION-- Tests NumberFormatter with various currenct-related formatters. --EXTENSIONS-- intl diff --git a/ext/intl/tests/formatter/rounding_modes.phpt b/ext/intl/tests/formatter/rounding_modes.phpt index 3261e3740795..bcb32983959a 100644 --- a/ext/intl/tests/formatter/rounding_modes.phpt +++ b/ext/intl/tests/formatter/rounding_modes.phpt @@ -6,7 +6,6 @@ intl = 69.0'); ?> --FILE-- getMessage() - . " in " . $e->getFile() . " on line " . $e->getLine() . "\n"; + echo "\n", $e::class, ": ", $e->getMessage(), "\n"; } function crt($t, $l, $s) { @@ -62,14 +61,14 @@ try { err($fmt); try { $fmt = numfmt_create(); -} catch (TypeError $e) { +} catch (Throwable $e) { print_exception($e); $fmt = null; } err($fmt); try { $fmt = NumberFormatter::create(); -} catch (TypeError $e) { +} catch (Throwable $e) { print_exception($e); $fmt = null; } @@ -78,7 +77,7 @@ err($fmt); $fmt = new NumberFormatter('en_US', NumberFormatter::DECIMAL); try { $fmt->__construct('en_US', NumberFormatter::DECIMAL); -} catch (Error $e) { +} catch (Throwable $e) { print_exception($e); $fmt = null; } @@ -95,16 +94,16 @@ foreach($args as $arg) { ?> --EXPECTF-- -ArgumentCountError: NumberFormatter::__construct() expects at least 2 arguments, 0 given in %s on line %d +ArgumentCountError: NumberFormatter::__construct() expects at least 2 arguments, 0 given 'U_ZERO_ERROR' -ArgumentCountError: numfmt_create() expects at least 2 arguments, 0 given in %s on line %d +ArgumentCountError: numfmt_create() expects at least 2 arguments, 0 given 'U_ZERO_ERROR' -ArgumentCountError: NumberFormatter::create() expects at least 2 arguments, 0 given in %s on line %d +ArgumentCountError: NumberFormatter::create() expects at least 2 arguments, 0 given 'U_ZERO_ERROR' -Error: NumberFormatter object is already constructed in %s on line %d +Error: NumberFormatter object is already constructed 'U_ZERO_ERROR' Deprecated: NumberFormatter::__construct(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d @@ -119,30 +118,30 @@ Deprecated: numfmt_create(): Passing null to parameter #1 ($locale) of type stri Deprecated: numfmt_create(): Passing null to parameter #2 ($style) of type int is deprecated in %s on line %d -ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "%s" is invalid in %s on line %d +ValueError: NumberFormatter::__construct(): Argument #1 ($locale) "whatever" is invalid 'U_ZERO_ERROR' -ValueError: NumberFormatter::create(): Argument #1 ($locale) "%s" is invalid in %s on line %d +ValueError: NumberFormatter::create(): Argument #1 ($locale) "whatever" is invalid 'U_ZERO_ERROR' -ValueError: numfmt_create(): Argument #1 ($locale) "%s" is invalid in %s on line %d +ValueError: numfmt_create(): Argument #1 ($locale) "whatever" is invalid 'U_ZERO_ERROR' -TypeError: NumberFormatter::__construct(): Argument #1 ($locale) must be of type string, array given in %s on line %d +TypeError: NumberFormatter::__construct(): Argument #1 ($locale) must be of type string, array given 'U_ZERO_ERROR' -TypeError: NumberFormatter::create(): Argument #1 ($locale) must be of type string, array given in %s on line %d +TypeError: NumberFormatter::create(): Argument #1 ($locale) must be of type string, array given 'U_ZERO_ERROR' -TypeError: numfmt_create(): Argument #1 ($locale) must be of type string, array given in %s on line %d +TypeError: numfmt_create(): Argument #1 ($locale) must be of type string, array given 'U_ZERO_ERROR' -IntlException: Constructor failed in %s on line %d -'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR' -'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR' -'numfmt_create: number formatter creation failed: U_UNSUPPORTED_ERROR' +IntlException: NumberFormatter::__construct(): number formatter creation failed +'NumberFormatter::__construct(): number formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'NumberFormatter::create(): number formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'numfmt_create(): number formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' -IntlException: Constructor failed in %s on line %d -'numfmt_create: number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' -'numfmt_create: number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' -'numfmt_create: number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' +IntlException: NumberFormatter::__construct(): number formatter creation failed +'NumberFormatter::__construct(): number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' +'NumberFormatter::create(): number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' +'numfmt_create(): number formatter creation failed: U_MEMORY_ALLOCATION_ERROR' diff --git a/ext/intl/tests/formatter_get_error.phpt b/ext/intl/tests/formatter_get_error.phpt index b8f1269fc65f..16a1c1db4766 100644 --- a/ext/intl/tests/formatter_get_error.phpt +++ b/ext/intl/tests/formatter_get_error.phpt @@ -5,27 +5,43 @@ intl --FILE-- parseCurrency('123.45', $currency); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); +$pos = 0; +$nf->parseCurrency('123.45', $currency, $pos); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); -function ut_main() -{ - $fmt = ut_nfmt_create( "en_US", NumberFormatter::CURRENCY ); - $currency = ''; - $pos = 0; - $num = ut_nfmt_parse_currency( $fmt, '123.45', $currency, $pos ); - if( $num === false ) - return $fmt->getErrorMessage() . " (" . $fmt->getErrorCode() . ")\n"; - else - return "Ooops, an error should have occurred."; -} +$nf = numfmt_create("en_US", NumberFormatter::CURRENCY); +var_dump(numfmt_parse_currency($nf, '123.45', $currency)); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); -include_once( 'ut_common.inc' ); +$pos = 0; +var_dump(numfmt_parse_currency($nf, '123.45', $currency, $pos)); +var_dump($currency); +var_dump($nf->getErrorMessage()); +var_dump($nf->getErrorCode()); -// Run the test -ut_run(); ?> --EXPECT-- -Number parsing failed: U_PARSE_ERROR (9) +NULL +string(70) "NumberFormatter::parseCurrency(): Number parsing failed: U_PARSE_ERROR" +int(9) +NULL +string(70) "NumberFormatter::parseCurrency(): Number parsing failed: U_PARSE_ERROR" +int(9) +bool(false) +NULL +string(61) "numfmt_parse_currency(): Number parsing failed: U_PARSE_ERROR" +int(9) +bool(false) +NULL +string(61) "numfmt_parse_currency(): Number parsing failed: U_PARSE_ERROR" +int(9) diff --git a/ext/intl/tests/formatter_get_set_pattern2.phpt b/ext/intl/tests/formatter_get_set_pattern2.phpt index 0d3e3e87d72d..7b454ae965ea 100644 --- a/ext/intl/tests/formatter_get_set_pattern2.phpt +++ b/ext/intl/tests/formatter_get_set_pattern2.phpt @@ -37,10 +37,6 @@ function ut_main() ut_nfmt_set_pattern($fmt, str_repeat('@', 200)); $res_str .= "New pattern: '" . ut_nfmt_get_pattern( $fmt ) . "'\n"; $res_str .= "Formatted number: " . ut_nfmt_format( $fmt, $test_value ) . "\n"; - $res = ut_nfmt_set_pattern( $fmt, "0.0 .#.#.#"); - if ($res !== false) - die("ut_nfmt_set_pattern should have failed"); - $res_str .= ut_nfmt_get_error_message( $fmt ) . " (" . ut_nfmt_get_error_code( $fmt ) . ")\n"; return $res_str; } @@ -56,4 +52,3 @@ New pattern: '0.0' Formatted number: 12345.1 New pattern: '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' Formatted number: 12345.123456000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -Error setting pattern value at line 0, offset 0: U_UNQUOTED_SPECIAL (65555) diff --git a/ext/intl/tests/formatter_set_invalid_pattern.phpt b/ext/intl/tests/formatter_set_invalid_pattern.phpt new file mode 100644 index 000000000000..2e94719e7568 --- /dev/null +++ b/ext/intl/tests/formatter_set_invalid_pattern.phpt @@ -0,0 +1,21 @@ +--TEST-- +numfmt_set_pattern() with invalid pattern +--EXTENSIONS-- +intl +--FILE-- +setPattern($pattern)); +var_dump($fmt->getErrorMessage()); +var_dump(numfmt_set_pattern($fmt, $pattern)); +var_dump(numfmt_get_error_message($fmt)); + +?> +--EXPECT-- +bool(false) +string(98) "NumberFormatter::setPattern(): Error setting pattern value at line 0, offset 0: U_UNQUOTED_SPECIAL" +bool(false) +string(89) "numfmt_set_pattern(): Error setting pattern value at line 0, offset 0: U_UNQUOTED_SPECIAL" diff --git a/ext/intl/tests/gh11658.phpt b/ext/intl/tests/gh11658.phpt index f0cfab9280ef..da3cc8b9a1c8 100644 --- a/ext/intl/tests/gh11658.phpt +++ b/ext/intl/tests/gh11658.phpt @@ -5,17 +5,17 @@ intl --FILE-- ---EXPECTF-- -Warning: MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}") in %s on line %d +--EXPECT-- bool(false) - -Warning: msgfmt_format_message(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}") in %s on line %d +MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR bool(false) +msgfmt_format_message(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR diff --git a/ext/intl/tests/gh11942_datefmt_locale_canonicalization.phpt b/ext/intl/tests/gh11942_datefmt_locale_canonicalization.phpt new file mode 100644 index 000000000000..26b0234fd3bd --- /dev/null +++ b/ext/intl/tests/gh11942_datefmt_locale_canonicalization.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-11942 (IntlDateFormatter should canonicalize locale strings) +--EXTENSIONS-- +intl +--FILE-- +getLocale(); + + $status = ($actual === $expected) ? 'PASS' : 'FAIL'; + echo "Input: $input -> Expected: $expected -> Actual: $actual -> $status\n"; +} + +$dateFormatter = new IntlDateFormatter('pt_PT.utf8', IntlDateFormatter::SHORT, IntlDateFormatter::NONE, 'UTC'); +$dateResult = $dateFormatter->format(1691585260); +echo "\nDateFormatter with pt_PT.utf8: " . $dateResult . "\n"; +?> +--EXPECT-- +Testing IntlDateFormatter locale canonicalization: +Input: pt -> Expected: pt -> Actual: pt -> PASS +Input: pt-PT -> Expected: pt_PT -> Actual: pt_PT -> PASS +Input: pt_PT.utf8 -> Expected: pt_PT -> Actual: pt_PT -> PASS +Input: fr_CA@euro -> Expected: fr_CA -> Actual: fr_CA -> PASS + +DateFormatter with pt_PT.utf8: 09/08/23 diff --git a/ext/intl/tests/gh11942_numfmt_locale_canonicalization.phpt b/ext/intl/tests/gh11942_numfmt_locale_canonicalization.phpt new file mode 100644 index 000000000000..bdb753d6127b --- /dev/null +++ b/ext/intl/tests/gh11942_numfmt_locale_canonicalization.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-11942 (NumberFormatter should canonicalize locale strings) +--EXTENSIONS-- +intl +--FILE-- +getLocale(); + + $status = ($actual === $expected) ? 'PASS' : 'FAIL'; + echo "Input: $input -> Expected: $expected -> Actual: $actual -> $status\n"; +} + +$numFormatter = new NumberFormatter('pt_PT.utf8', NumberFormatter::DECIMAL); +$numResult = $numFormatter->format(1234.56); +echo "\nNumberFormatter with pt_PT.utf8: " . $numResult . "\n"; +?> +--EXPECT-- +Testing NumberFormatter locale canonicalization: +Input: pt -> Expected: pt -> Actual: pt -> PASS +Input: pt-PT -> Expected: pt_PT -> Actual: pt_PT -> PASS +Input: pt_PT.utf8 -> Expected: pt_PT -> Actual: pt_PT -> PASS +Input: fr_CA@euro -> Expected: fr_CA -> Actual: fr_CA -> PASS + +NumberFormatter with pt_PT.utf8: 1 234,56 diff --git a/ext/intl/tests/gh12020.phpt b/ext/intl/tests/gh12020.phpt index e4102606ca54..c9fe55fa3cdd 100644 --- a/ext/intl/tests/gh12020.phpt +++ b/ext/intl/tests/gh12020.phpt @@ -13,10 +13,10 @@ var_dump(msgfmt_format_message('en', 'some {wrong.format}', []), intl_get_error_ ?> --EXPECT-- bool(false) -string(128) "pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" +string(163) "MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" bool(false) -string(116) "pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" +string(151) "MessageFormatter::formatMessage(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" bool(false) -string(128) "pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" +string(153) "msgfmt_format_message(): pattern syntax error (parse error at offset 19, after " message with {", before or at "invalid format}"): U_PATTERN_SYNTAX_ERROR" bool(false) -string(116) "pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" +string(141) "msgfmt_format_message(): pattern syntax error (parse error at offset 6, after "some {", before or at "wrong.format}"): U_PATTERN_SYNTAX_ERROR" diff --git a/ext/intl/tests/gh12243.phpt b/ext/intl/tests/gh12243.phpt index cb2b17760390..324ed9a65661 100644 --- a/ext/intl/tests/gh12243.phpt +++ b/ext/intl/tests/gh12243.phpt @@ -1,5 +1,5 @@ --TEST-- -GitHub #12043 segfault with IntlDateFormatter::dateType where it equals to UDAT_PATTERN (icu 50) but +GitHub #12043 segfault with IntlDateFormatter::dateType where it equals to IntlDateFormatter::PATTERN (icu 50) but IntldateFormatter::timeType needs to be set as such. --EXTENSIONS-- intl @@ -21,4 +21,4 @@ try { ?> --EXPECT-- -datefmt_create: time format must be UDAT_PATTERN if date format is UDAT_PATTERN: U_ILLEGAL_ARGUMENT_ERROR +IntlDateFormatter::__construct(): datefmt_create: time format must be IntlDateFormatter::PATTERN if date format is IntlDateFormatter::PATTERN diff --git a/ext/intl/tests/gh13766.phpt b/ext/intl/tests/gh13766.phpt index 70567fa86053..9ed8d985de47 100644 --- a/ext/intl/tests/gh13766.phpt +++ b/ext/intl/tests/gh13766.phpt @@ -32,4 +32,4 @@ int(%d) string(19) "America/Los_Angeles" IntlDateFormatter::parseToCalendar(): Argument #2 ($offset) must be of type int, string given -Deprecated: Implicit conversion from float %r(1\.4757395258967641E\+20|34359738352)%r to int loses precision in %s on line %d +Warning: The float %r(1\.4757395258967641E\+20|34359738352)%r is not representable as an int, cast occurred in %s on line %d diff --git a/ext/intl/tests/gh17469.phpt b/ext/intl/tests/gh17469.phpt index a0c5d719817d..5a2263684422 100644 --- a/ext/intl/tests/gh17469.phpt +++ b/ext/intl/tests/gh17469.phpt @@ -1,5 +1,7 @@ --TEST-- GH-17469: UConverter::transcode() raises always E_WARNING regardless of INI settings +--EXTENSIONS-- +intl --SKIPIF-- --EXPECTF-- +Deprecated: ini_set(): Using a value different than 0 for intl.error_level is deprecated, as the intl.error_level INI setting is deprecated. Instead the intl.use_exceptions INI setting should be enabled to throw exceptions on errors or intl_get_error_code()/intl_get_error_message() should be used to manually deal with errors in %s on line %d Warning: UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR in %s on line %d -Warning: UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR in %s on line 5 -Error setting encoding: 4 - U_FILE_ACCESS_ERROR -Error setting encoding: 4 - U_FILE_ACCESS_ERROR +Warning: UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR in %s on line %d +UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR +UConverter::transcode(): Error setting encoding: 4 - U_FILE_ACCESS_ERROR diff --git a/ext/intl/tests/gh21998.phpt b/ext/intl/tests/gh21998.phpt new file mode 100644 index 000000000000..392336dab522 --- /dev/null +++ b/ext/intl/tests/gh21998.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-21998 (NumberFormatter::format(INF) leaves a non-NUL-terminated zend_string) +--EXTENSIONS-- +intl +--FILE-- +format(INF)); +var_dump($fmt->format(-INF)); +var_dump($fmt->format(NAN)); +?> +--EXPECT-- +string(3) "∞" +string(4) "-∞" +string(3) "NaN" diff --git a/ext/intl/tests/grapheme_empty.phpt b/ext/intl/tests/grapheme_empty.phpt index 815663342fcb..cf2f1185abf7 100644 --- a/ext/intl/tests/grapheme_empty.phpt +++ b/ext/intl/tests/grapheme_empty.phpt @@ -5,8 +5,6 @@ intl --FILE-- getMessage() . PHP_EOL; } + +echo "--- Invalid locales ---\n"; +var_dump(grapheme_levenshtein("abc", "abc", locale: "defaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); +var_dump(intl_get_error_code()); +var_dump(intl_get_error_message()); + ?> --EXPECTF-- --- Equal --- @@ -121,8 +135,13 @@ int(2) --- Variable selector --- int(1) int(0) +int(1) int(0) --- Corner case --- grapheme_levenshtein(): Argument #3 ($insertion_cost) must be greater than 0 and less than or equal to %d grapheme_levenshtein(): Argument #4 ($replacement_cost) must be greater than 0 and less than or equal to %d grapheme_levenshtein(): Argument #5 ($deletion_cost) must be greater than 0 and less than or equal to %d +--- Invalid locales --- +bool(false) +int(%d) +string(68) "grapheme_levenshtein(): Error on ucol_open: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/grapheme_stripos_locale_dependency.phpt b/ext/intl/tests/grapheme_stripos_locale_dependency.phpt new file mode 100644 index 000000000000..e1a8d05e2541 --- /dev/null +++ b/ext/intl/tests/grapheme_stripos_locale_dependency.phpt @@ -0,0 +1,23 @@ +--TEST-- +grapheme_stripos() function locale dependency test +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +int(0) +int(0) +bool(false) +=== Invalid locales === +bool(false) +int(%d) +string(74) "grapheme_stripos(): Error creating search object: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/grapheme_stristr_locale_dependency.phpt b/ext/intl/tests/grapheme_stristr_locale_dependency.phpt new file mode 100644 index 000000000000..91d0e7273be0 --- /dev/null +++ b/ext/intl/tests/grapheme_stristr_locale_dependency.phpt @@ -0,0 +1,23 @@ +--TEST-- +grapheme_stristr() function locale dependency test +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +string(3) "abc" +string(1) "i" +bool(false) +=== Invalid locales === +bool(false) +int(%d) +string(74) "grapheme_stristr(): Error creating search object: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/grapheme_strpos_locale_dependency.phpt b/ext/intl/tests/grapheme_strpos_locale_dependency.phpt new file mode 100644 index 000000000000..f43b54123ab5 --- /dev/null +++ b/ext/intl/tests/grapheme_strpos_locale_dependency.phpt @@ -0,0 +1,12 @@ +--TEST-- +grapheme_strpos() function locale dependency test +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +bool(false) +int(0) diff --git a/ext/intl/tests/grapheme_strrev.phpt b/ext/intl/tests/grapheme_strrev.phpt new file mode 100644 index 000000000000..dff84fbba8e9 Binary files /dev/null and b/ext/intl/tests/grapheme_strrev.phpt differ diff --git a/ext/intl/tests/grapheme_strripos_locale_dependency.phpt b/ext/intl/tests/grapheme_strripos_locale_dependency.phpt new file mode 100644 index 000000000000..87e87c483b7a --- /dev/null +++ b/ext/intl/tests/grapheme_strripos_locale_dependency.phpt @@ -0,0 +1,23 @@ +--TEST-- +grapheme_strripos() function locale dependency test +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +int(0) +int(0) +bool(false) +=== Invalid locales === +bool(false) +int(%d) +string(75) "grapheme_strripos(): Error creating search object: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/gregoriancalendar___construct_basic.phpt b/ext/intl/tests/gregoriancalendar___construct_basic.phpt index 315c43f2904a..8ebe683f8d16 100644 --- a/ext/intl/tests/gregoriancalendar___construct_basic.phpt +++ b/ext/intl/tests/gregoriancalendar___construct_basic.phpt @@ -2,12 +2,11 @@ IntlGregorianCalendar::__construct(): basic --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam +intl.default_locale=nl --FILE-- getTimeZone()->getId()); diff --git a/ext/intl/tests/gregoriancalendar___construct_error.phpt b/ext/intl/tests/gregoriancalendar___construct_error.phpt index 2261da3955be..6922b7cadd8c 100644 --- a/ext/intl/tests/gregoriancalendar___construct_error.phpt +++ b/ext/intl/tests/gregoriancalendar___construct_error.phpt @@ -4,7 +4,6 @@ IntlGregorianCalendar::__construct(): bad arguments intl --FILE-- +--FILE-- +getMessage(), "\n"; +} + +try { + intlgregcal_create_instance(1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + new IntlGregorianCalendar(1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + new IntlGregorianCalendar(1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlgregcal_create_instance(1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #1 ($timezoneOrYear) must be between -2147483648 and 2147483647 + +Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +intlgregcal_create_instance(): Argument #2 ($localeOrMonth) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #4 ($hour) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #5 ($minute) must be between -2147483648 and 2147483647 + +Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +intlgregcal_create_instance(): Argument #6 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/gregoriancalendar___construct_variant1.phpt b/ext/intl/tests/gregoriancalendar___construct_variant1.phpt index 38a65ce7b9ea..6cf057f0a098 100644 --- a/ext/intl/tests/gregoriancalendar___construct_variant1.phpt +++ b/ext/intl/tests/gregoriancalendar___construct_variant1.phpt @@ -2,11 +2,10 @@ IntlGregorianCalendar::__construct(): argument variants --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam --FILE-- getTimeZone()->getId()); diff --git a/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt b/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt deleted file mode 100644 index 5665b793f388..000000000000 --- a/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -IntlGregorianCalendar::getGregorianChange(): bad arguments ---INI-- -date.timezone=Atlantic/Azores ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intlgregcal_get_gregorian_change(): Argument #1 ($calendar) must be of type IntlGregorianCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlgregcal_get_gregorian_change(1) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt b/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt index 8ae2410dc8c7..e0cd6b13b2ea 100644 --- a/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt +++ b/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt @@ -2,12 +2,11 @@ IntlGregorianCalendar::get/setGregorianChange(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Amsterdam +intl.default_locale=nl --FILE-- ---EXPECTF-- -Fatal error: Uncaught TypeError: intlgregcal_is_leap_year(): Argument #1 ($calendar) must be of type IntlGregorianCalendar, int given in %s:%d -Stack trace: -#0 %s(%d): intlgregcal_is_leap_year(1, 2) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/idn_uts46_errors.phpt b/ext/intl/tests/idn_uts46_errors.phpt index 1cbf336defa6..c1058c3a2439 100644 --- a/ext/intl/tests/idn_uts46_errors.phpt +++ b/ext/intl/tests/idn_uts46_errors.phpt @@ -9,7 +9,6 @@ intl ?> --FILE-- PHP level errors", "\n"; echo "bad variant:", "\n"; diff --git a/ext/intl/tests/ini_use_exceptions_basic.phpt b/ext/intl/tests/ini_use_exceptions_basic.phpt index c2aabfbe63f4..e03c991ae05f 100644 --- a/ext/intl/tests/ini_use_exceptions_basic.phpt +++ b/ext/intl/tests/ini_use_exceptions_basic.phpt @@ -16,7 +16,9 @@ ini_set("intl.error_level", E_NOTICE); var_dump($t->transliterate('a', 3)); ?> --EXPECTF-- -string(130) "transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1)" +string(133) "Transliterator::transliterate(): Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1)" -Notice: Transliterator::transliterate(): transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1) in %s on line %d +Deprecated: ini_set(): Using a value different than 0 for intl.error_level is deprecated, as the intl.error_level INI setting is deprecated. Instead the intl.use_exceptions INI setting should be enabled to throw exceptions on errors or intl_get_error_code()/intl_get_error_message() should be used to manually deal with errors in %s on line %d + +Notice: Transliterator::transliterate(): Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1) in %s on line %d bool(false) diff --git a/ext/intl/tests/intl_get_error_message.phpt b/ext/intl/tests/intl_get_error_message.phpt index 93d2e5c653af..83130e549dca 100644 --- a/ext/intl/tests/intl_get_error_message.phpt +++ b/ext/intl/tests/intl_get_error_message.phpt @@ -15,4 +15,4 @@ else ?> --EXPECT-- -Error getting locale by type: U_ILLEGAL_ARGUMENT_ERROR +collator_get_locale(): Error getting locale by type: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/listformatter/listformatter_error.phpt b/ext/intl/tests/listformatter/listformatter_error.phpt index d420b92a9f8d..4ca22136943e 100644 --- a/ext/intl/tests/listformatter/listformatter_error.phpt +++ b/ext/intl/tests/listformatter/listformatter_error.phpt @@ -33,6 +33,6 @@ try { ?> --EXPECT-- IntlListFormatter::__construct(): Argument #1 ($locale) "f" is invalid -IntlListFormatter::__construct(): Argument #1 ($locale) Locale string too long, should be no longer than 156 characters +IntlListFormatter::__construct(): Argument #1 ($locale) must be less than or equal to 156 characters Object of class stdClass could not be converted to string Object of class stdClass could not be converted to string diff --git a/ext/intl/tests/listformatter/listformatter_get_error.phpt b/ext/intl/tests/listformatter/listformatter_get_error.phpt new file mode 100644 index 000000000000..a2a23b3473d2 --- /dev/null +++ b/ext/intl/tests/listformatter/listformatter_get_error.phpt @@ -0,0 +1,25 @@ +--TEST-- +IntlListFormatter getErrorCode()/getErrorMessage() reflect format() failures +--EXTENSIONS-- +intl +--FILE-- +format(["\x80"])); +var_dump($formatter->getErrorCode() === U_INVALID_CHAR_FOUND); +var_dump($formatter->getErrorMessage()); + +var_dump($formatter->format(['a', 'b'])); +var_dump($formatter->getErrorCode() === U_ZERO_ERROR); +var_dump($formatter->getErrorMessage()); + +?> +--EXPECT-- +bool(false) +bool(true) +string(85) "IntlListFormatter::format(): Failed to convert string to UTF-16: U_INVALID_CHAR_FOUND" +string(7) "a and b" +bool(true) +string(12) "U_ZERO_ERROR" diff --git a/ext/intl/tests/locale_compose_locale.phpt b/ext/intl/tests/locale_compose_locale.phpt index 0a2a501b9baf..beaf4beaa8ae 100644 --- a/ext/intl/tests/locale_compose_locale.phpt +++ b/ext/intl/tests/locale_compose_locale.phpt @@ -13,115 +13,89 @@ intl function ut_main() { $loc_parts_arr1 = array( - Locale::LANG_TAG =>'sl' , - Locale::SCRIPT_TAG =>'Latn' , - Locale::REGION_TAG =>'IT' + Locale::LANG_TAG => 'sl', + Locale::SCRIPT_TAG => 'Latn', + Locale::REGION_TAG => 'IT' ); $loc_parts_arr2 = array( - Locale::LANG_TAG =>'de' , - Locale::REGION_TAG =>'DE' + Locale::LANG_TAG => 'de', + Locale::REGION_TAG => 'DE' ); $loc_parts_arr3 = array( - Locale::LANG_TAG =>'hi' + Locale::LANG_TAG => 'hi' ); $loc_parts_arr4 = array( - Locale::LANG_TAG =>'zh' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN' + Locale::LANG_TAG => 'zh', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN' ); $loc_parts_arr5 = array( - Locale::LANG_TAG =>'es' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN' + Locale::LANG_TAG => 'es', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN' ); $loc_parts_arr6 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - Locale::VARIANT_TAG.'14' =>'rozaj' , - 'variant1'=>'nedis' + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + Locale::VARIANT_TAG.'14' => 'rozaj', + 'variant1' => 'nedis' ); $loc_parts_arr7 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - 'variant14'=>'rozaj' , - 'variant1'=>'nedis' , - 'extlang0'=>'lng' , - 'extlang1'=>'ing' + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + 'variant14' => 'rozaj', + 'variant1' => 'nedis', + 'extlang0' => 'lng', + 'extlang1' => 'ing' ); $loc_parts_arr8 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - 'variant14'=>'rozaj' , - 'variant1'=>'nedis' , - 'extlang0'=>'lng' , - 'extlang1'=>'ing', - 'private7'=>'prv1' , - 'private9'=>'prv2' + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + 'variant14' => 'rozaj', + 'variant1' => 'nedis', + 'extlang0' => 'lng', + 'extlang1' => 'ing', + 'private7' => 'prv1', + 'private9' => 'prv2' ); $loc_parts_arr9 = array( - Locale::REGION_TAG =>'DE' - ); - $loc_parts_arr10 = array( - Locale::LANG_TAG => 45, - Locale::REGION_TAG => false, - Locale::SCRIPT_TAG => 15 - ); - $loc_parts_arr11 = array( - Locale::LANG_TAG =>'de' , - Locale::REGION_TAG =>'DE', - 'private0' => 13, - 'variant1' => array(), - 'extlang2' => false - ); - $loc_parts_arr12 = array( - Locale::LANG_TAG =>'en' , - Locale::SCRIPT_TAG =>'Hans' , - Locale::REGION_TAG =>'CN', - Locale::VARIANT_TAG => array('nedis', 'rozaj'), + Locale::LANG_TAG => 'en', + Locale::SCRIPT_TAG => 'Hans', + Locale::REGION_TAG => 'CN', + Locale::VARIANT_TAG => array('nedis', 'rozaj'), Locale::PRIVATE_TAG => array('prv1', 'prv2'), Locale::EXTLANG_TAG => array('lng', 'ing') - ); + ); $loc_parts_arr = array( - 'loc1' => $loc_parts_arr1 , - 'loc2' => $loc_parts_arr2 , - 'loc3' => $loc_parts_arr3 , - 'loc4' => $loc_parts_arr4 , - 'loc5' => $loc_parts_arr5 , - 'loc6' => $loc_parts_arr6 , - 'loc7' => $loc_parts_arr7 , - 'loc8' => $loc_parts_arr8 , - 'loc9' => $loc_parts_arr9 , - 'loc10' => $loc_parts_arr10 , - 'loc11' => $loc_parts_arr11 , - 'loc12' => $loc_parts_arr12 + 'loc1' => $loc_parts_arr1, + 'loc2' => $loc_parts_arr2, + 'loc3' => $loc_parts_arr3, + 'loc4' => $loc_parts_arr4, + 'loc5' => $loc_parts_arr5, + 'loc6' => $loc_parts_arr6, + 'loc7' => $loc_parts_arr7, + 'loc8' => $loc_parts_arr8, + 'loc9' => $loc_parts_arr9, ); $cnt = 0; $res_str = ''; - foreach($loc_parts_arr as $key => $value ){ + foreach ($loc_parts_arr as $key => $value) { $res_str .= "\n------------"; $res_str .= "\nInput Array name is : loc".(++$cnt) ; -/* - foreach($value as $valKey => $valValue ){ - $res_str .= $valKey ."->".$valValue." " ; - } -*/ - try { - $locale = ut_loc_locale_compose( $value); - $res_str .= "\n\nComposed Locale: "; - if( $locale){ - $res_str .= "$locale"; - }else{ - $res_str .= "No values found from Locale compose due to the following error:\n"; - $res_str .= intl_get_error_message() ; - } - } catch (ValueError $exception) { - echo $exception->getMessage() . "\n"; + + $locale = ut_loc_locale_compose( $value); + $res_str .= "\n\nComposed Locale: "; + if ($locale) { + $res_str .= "$locale"; + } else { + $res_str .= "No values found from Locale compose due to the following error:\n"; + $res_str .= intl_get_error_message() ; } } @@ -136,9 +110,6 @@ ut_run(); ?> --EXPECT-- -Locale::composeLocale(): Argument #1 ($subtags) must contain a "language" key -locale_compose(): Argument #1 ($subtags) must contain a "language" key - ------------ Input Array name is : loc1 @@ -173,18 +144,6 @@ Input Array name is : loc8 Composed Locale: en_lng_ing_Hans_CN_nedis_rozaj_x_prv1_prv2 ------------ Input Array name is : loc9 ------------- -Input Array name is : loc10 - -Composed Locale: No values found from Locale compose due to the following error: -locale_compose: parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR ------------- -Input Array name is : loc11 - -Composed Locale: No values found from Locale compose due to the following error: -locale_compose: parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR ------------- -Input Array name is : loc12 Composed Locale: en_lng_ing_Hans_CN_nedis_rozaj_x_prv1_prv2 ------------ diff --git a/ext/intl/tests/locale_compose_locale_errors.phpt b/ext/intl/tests/locale_compose_locale_errors.phpt new file mode 100644 index 000000000000..b0d68aae73ce --- /dev/null +++ b/ext/intl/tests/locale_compose_locale_errors.phpt @@ -0,0 +1,58 @@ +--TEST-- +locale_compose_locale() errors +--EXTENSIONS-- +intl +--FILE-- + 45, + Locale::REGION_TAG => false, + Locale::SCRIPT_TAG => 15, +]; + +var_dump(Locale::composeLocale($parts1)); +var_dump(intl_get_error_message()); +var_dump(locale_compose($parts1)); +var_dump(intl_get_error_message()); + +$parts2 = [ + Locale::LANG_TAG => 'de', + Locale::REGION_TAG => 'DE', + 'private0' => 13, + 'variant1' => array(), + 'extlang2' => false +]; + +var_dump(Locale::composeLocale($parts2)); +var_dump(intl_get_error_message()); +var_dump(locale_compose($parts2)); +var_dump(intl_get_error_message()); + +$parts3 = [ + Locale::REGION_TAG => 'DE', +]; + +try { + var_dump(Locale::composeLocale($parts3)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + var_dump(locale_compose($parts3)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +bool(false) +string(90) "Locale::composeLocale(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(83) "locale_compose(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(90) "Locale::composeLocale(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(83) "locale_compose(): parameter array element is not a string: U_ILLEGAL_ARGUMENT_ERROR" +ValueError: Locale::composeLocale(): Argument #1 ($subtags) must contain a "language" key +ValueError: locale_compose(): Argument #1 ($subtags) must contain a "language" key diff --git a/ext/intl/tests/locale_subtags.phpt b/ext/intl/tests/locale_subtags.phpt index 0c454706225b..f6cb7d1e957d 100644 --- a/ext/intl/tests/locale_subtags.phpt +++ b/ext/intl/tests/locale_subtags.phpt @@ -26,10 +26,10 @@ bool(true) bool(true) bool(true) bool(false) -string(67) "locale_add_likely_subtags: invalid locale: U_ILLEGAL_ARGUMENT_ERROR" +string(68) "Locale::addLikelySubtags(): invalid locale: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(65) "locale_minimize_subtags: invalid locale: U_ILLEGAL_ARGUMENT_ERROR" +string(67) "Locale::minimizeSubtags(): invalid locale: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(%d) "locale_add_likely_subtags: invalid locale: %s" +string(68) "Locale::addLikelySubtags(): invalid locale: U_ILLEGAL_ARGUMENT_ERROR" bool(false) -string(%d) "locale_minimize_subtags: invalid locale: %s" +string(%d) "Locale::minimizeSubtags(): invalid locale: %s" diff --git a/ext/intl/tests/msgfmt_errors.phpt b/ext/intl/tests/msgfmt_errors.phpt new file mode 100644 index 000000000000..78264c22b3ad --- /dev/null +++ b/ext/intl/tests/msgfmt_errors.phpt @@ -0,0 +1,30 @@ +--TEST-- +MessageFormatter with invalid locale +--EXTENSIONS-- +intl +--FILE-- +getMessage(), PHP_EOL; +} + +$mf = MessageFormatter::create('root', $fmt); +var_dump($mf); +var_dump(intl_get_error_message()); + +$mf = msgfmt_create('root', $fmt); +var_dump($mf); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +IntlException: MessageFormatter::__construct(): message formatter creation failed +NULL +string(87) "MessageFormatter::create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR" +NULL +string(76) "msgfmt_create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/msgfmt_fail2.phpt b/ext/intl/tests/msgfmt_fail2.phpt index a5256e724a02..de592e7b798c 100644 --- a/ext/intl/tests/msgfmt_fail2.phpt +++ b/ext/intl/tests/msgfmt_fail2.phpt @@ -130,23 +130,23 @@ Deprecated: MessageFormatter::__construct(): Passing null to parameter #1 ($loca Deprecated: MessageFormatter::__construct(): Passing null to parameter #2 ($pattern) of type string is deprecated in %s on line %d -IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +IntlException: MessageFormatter::__construct(): message formatter creation failed in %s on line %d +'MessageFormatter::__construct(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' Deprecated: MessageFormatter::create(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d Deprecated: MessageFormatter::create(): Passing null to parameter #2 ($pattern) of type string is deprecated in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'MessageFormatter::create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' Deprecated: msgfmt_create(): Passing null to parameter #1 ($locale) of type string is deprecated in %s on line %d Deprecated: msgfmt_create(): Passing null to parameter #2 ($pattern) of type string is deprecated in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'msgfmt_create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' -IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +IntlException: MessageFormatter::__construct(): message formatter creation failed in %s on line %d +'MessageFormatter::__construct(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'MessageFormatter::create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' +'msgfmt_create(): message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' TypeError: MessageFormatter::__construct(): Argument #1 ($locale) must be of type string, array given in %s on line %d 'U_ZERO_ERROR' @@ -157,17 +157,17 @@ TypeError: MessageFormatter::create(): Argument #1 ($locale) must be of type str TypeError: msgfmt_create(): Argument #1 ($locale) must be of type string, array given in %s on line %d 'U_ZERO_ERROR' -IntlException: pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR in %s on line %d -'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' -'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' -'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' +IntlException: MessageFormatter::__construct(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}") in %s on line %d +'MessageFormatter::__construct(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' +'MessageFormatter::create(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' +'msgfmt_create(): pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR' -IntlException: msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES in %s on line %d -'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES' -'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES' -'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES' +IntlException: MessageFormatter::__construct(): message formatter creation failed in %s on line %d +'MessageFormatter::__construct(): message formatter creation failed: U_UNMATCHED_BRACES' +'MessageFormatter::create(): message formatter creation failed: U_UNMATCHED_BRACES' +'msgfmt_create(): message formatter creation failed: U_UNMATCHED_BRACES' -IntlException: msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND in %s on line %d -'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' -'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' -'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' +IntlException: MessageFormatter::__construct(): error converting pattern to UTF-16 in %s on line %d +'MessageFormatter::__construct(): error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' +'MessageFormatter::create(): error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' +'msgfmt_create(): error converting pattern to UTF-16: U_INVALID_CHAR_FOUND' diff --git a/ext/intl/tests/msgfmt_format.phpt b/ext/intl/tests/msgfmt_format.phpt index 39efaf36c4e3..99440a882e34 100644 --- a/ext/intl/tests/msgfmt_format.phpt +++ b/ext/intl/tests/msgfmt_format.phpt @@ -17,13 +17,13 @@ function ut_main() 'ru_UA' => "{0,number,integer} мавп на {1,number,integer} деревах це {2,number} мавпи на кожному деревi", 'de' => "{0,number,integer} Affen über {1,number,integer} Bäume um {2,number} Affen pro Baum", 'en_UK' => "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree", - 'root' => '{0,whatever} would not work!', - 'fr' => "C'est la vie!", + 'fr' => "C'est la vie!", ); $str_res = ''; $m = 4560; $t = 123; + $v = [$m, $t, $m/$t]; foreach( $locales as $locale => $pattern ) { @@ -33,8 +33,8 @@ function ut_main() $str_res .= dump(intl_get_error_message())."\n"; continue; } - $str_res .= dump( ut_msgfmt_format( $fmt, array($m, $t, $m/$t) ) ) . "\n"; - $str_res .= dump( ut_msgfmt_format_message($locale, $pattern, array($m, $t, $m/$t))) . "\n"; + $str_res .= dump( ut_msgfmt_format( $fmt, $v) ) . "\n"; + $str_res .= dump( ut_msgfmt_format_message($locale, $pattern, $v)) . "\n"; } return $str_res; } @@ -62,9 +62,6 @@ Locale is: en_UK '4,560 monkeys on 123 trees make 37.073 monkeys per tree' '4,560 monkeys on 123 trees make 37.073 monkeys per tree' -Locale is: root -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' - Locale is: fr 'C\'est la vie!' 'C\'est la vie!' diff --git a/ext/intl/tests/msgfmt_format_datetime.phpt b/ext/intl/tests/msgfmt_format_datetime.phpt index e6a7451906f7..7ee35e643e22 100644 --- a/ext/intl/tests/msgfmt_format_datetime.phpt +++ b/ext/intl/tests/msgfmt_format_datetime.phpt @@ -1,15 +1,11 @@ --TEST-- MessageFormatter::format(): DateTime accepted to format dates and times ---INI-- -date.timezone=Atlantic/Azores --EXTENSIONS-- intl --SKIPIF-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- format(array(7))); +try { + var_dump($mf->format(array(7))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): Inconsistent types declared for an argument in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): Inconsistent types declared for an argument diff --git a/ext/intl/tests/msgfmt_format_error3.phpt b/ext/intl/tests/msgfmt_format_error3.phpt index f9c44789dc23..a03b0a21ecc4 100644 --- a/ext/intl/tests/msgfmt_format_error3.phpt +++ b/ext/intl/tests/msgfmt_format_error3.phpt @@ -2,17 +2,21 @@ MessageFormatter::format() given negative arg key --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=On --FILE-- format(array("foo" => 7, -1 => "bar"))); +try { + var_dump($mf->format(array("foo" => 7, -1 => "bar"))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): Found negative or too large array key in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): Found negative or too large array key diff --git a/ext/intl/tests/msgfmt_format_error4.phpt b/ext/intl/tests/msgfmt_format_error4.phpt index a6f591272308..78dc27b4092e 100644 --- a/ext/intl/tests/msgfmt_format_error4.phpt +++ b/ext/intl/tests/msgfmt_format_error4.phpt @@ -2,22 +2,45 @@ MessageFormatter::format() invalid UTF-8 for arg key or value --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=On --FILE-- format(array("foo" => 7, "\x80" => "bar"))); +try { + var_dump($mf->format(array("foo" => 7, "\x80" => "bar"))); +} catch (Throwable $e) { + var_dump($e::class === 'IntlException'); + var_dump("MessageFormatter::format(): Invalid UTF-8 data in argument key: '\x80'" === $e->getMessage()); +} -var_dump($mf->format(array("foo" => "\x80"))); -?> ---EXPECTF-- -Warning: MessageFormatter::format(): Invalid UTF-8 data in argument key: '' in %s on line %d -bool(false) +try { + var_dump($mf->format(array("foo" => "\x80"))); +} catch (Throwable $e) { + var_dump($e::class === 'IntlException'); + var_dump("MessageFormatter::format(): Invalid UTF-8 data in string argument: '\x80'" === $e->getMessage()); +} -Warning: MessageFormatter::format(): Invalid UTF-8 data in string argument: '' in %s on line %d -bool(false) +try { + var_dump($mf->format(array("foo" => new class { + function __toString(): string { + return str_repeat("\x80", random_int(1, 1)); + } + }))); +} catch (Throwable $e) { + var_dump($e::class === 'IntlException'); + var_dump("MessageFormatter::format(): Invalid UTF-8 data in string argument: '\x80'" === $e->getMessage()); +} +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/intl/tests/msgfmt_format_error5.phpt b/ext/intl/tests/msgfmt_format_error5.phpt index f3f87835b921..d5d7e6a4dc8e 100644 --- a/ext/intl/tests/msgfmt_format_error5.phpt +++ b/ext/intl/tests/msgfmt_format_error5.phpt @@ -2,21 +2,22 @@ MessageFormatter::format() invalid date/time argument --INI-- date.timezone=Atlantic/Azores +intl.use_exceptions=On --EXTENSIONS-- intl --FILE-- format(array("foo" => new stdclass()))); +try { + var_dump($mf->format(array("foo" => new stdclass()))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): msgfmt_format: invalid object type for date/time (only IntlCalendar and DateTimeInterface permitted) in %s on line %d - -Warning: MessageFormatter::format(): The argument for key 'foo' cannot be used as a date or time in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): The argument for key 'foo' cannot be used as a date or time diff --git a/ext/intl/tests/msgfmt_format_error6.phpt b/ext/intl/tests/msgfmt_format_error6.phpt index 23db39728226..9320194be6f3 100644 --- a/ext/intl/tests/msgfmt_format_error6.phpt +++ b/ext/intl/tests/msgfmt_format_error6.phpt @@ -2,17 +2,21 @@ MessageFormatter::format() invalid type for key not in pattern --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=On --FILE-- format(array("foo" => 'bar', 7 => fopen('php://memory', 'r+')))); +try { + var_dump($mf->format(array("foo" => 'bar', 7 => fopen('php://memory', 'r+')))); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: MessageFormatter::format(): No strategy to convert the value given for the argument with key '7' is available in %s on line %d -bool(false) +--EXPECT-- +IntlException: MessageFormatter::format(): No strategy to convert the value given for the argument with key '7' is available diff --git a/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt b/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt index 0b8e607ad2db..9436a9e95438 100644 --- a/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt +++ b/ext/intl/tests/msgfmt_format_intlcalendar_variant4.phpt @@ -2,6 +2,8 @@ MessageFormat accepts IntlCalendar args --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon --SKIPIF-- --FILE-- format(array($time, 'date')), " ", ?> --EXPECTF-- Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d -quinta-feira, 17 de maio de 2012 5:35:36 da tarde ptlis +quinta-feira, 17 de maio de 2012 5:35:36 %r(da tarde|p.m.)%r ptlis diff --git a/ext/intl/tests/msgfmt_format_message_errors.phpt b/ext/intl/tests/msgfmt_format_message_errors.phpt new file mode 100644 index 000000000000..8a5ee8ea2ea3 --- /dev/null +++ b/ext/intl/tests/msgfmt_format_message_errors.phpt @@ -0,0 +1,27 @@ +--TEST-- +MessageFormatter::parseMessage() with invalid locale +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +bool(false) +string(82) "MessageFormatter::formatMessage(): Creating message formatter failed: U_ZERO_ERROR" +bool(false) +string(72) "msgfmt_format_message(): Creating message formatter failed: U_ZERO_ERROR" diff --git a/ext/intl/tests/msgfmt_format_mixed_params.phpt b/ext/intl/tests/msgfmt_format_mixed_params.phpt index 016dbe96be4a..3cfb21009993 100644 --- a/ext/intl/tests/msgfmt_format_mixed_params.phpt +++ b/ext/intl/tests/msgfmt_format_mixed_params.phpt @@ -4,8 +4,6 @@ MessageFormatter::format(): mixed named and numeric parameters intl --FILE-- = 0) die('skip for ICU < 72.1'); ?> --FILE-- = 72.1'); ?> --FILE-- "{0,number,integer} мавп на {1,number,integer} деревах це {2,number} мавпи на кожному деревi", 'de' => "{0,number,integer} Affen über {1,number,integer} Bäume um {2,number} Affen pro Baum", 'en_UK' => "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree", - 'root' => '{0,whatever} would not work!', - 'fr' => 'C\'est {0,number,integer}', + 'fr' => 'C\'est {0,number,integer}', ); $results = array( @@ -26,7 +25,6 @@ function ut_main() 'ru_UA' => "4 560 мавп на 123 деревах це 37,073 мавпи на кожному деревi", 'de' => "4.560 Affen über 123 Bäume um 37,073 Affen pro Baum", 'en_UK' => "4,560 monkeys on 123 trees make 37.073 monkeys per tree", - 'root' => "4,560 monkeys on 123 trees make 37.073 monkeys per tree", 'fr' => "C'est 42", ); @@ -102,9 +100,6 @@ array ( 2 => 37.073, ) -Locale is: root -'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR' - Locale is: fr array ( 0 => 42, diff --git a/ext/intl/tests/msgfmt_parse_int64_min_64.phpt b/ext/intl/tests/msgfmt_parse_int64_min_64.phpt new file mode 100644 index 000000000000..2d003667813c --- /dev/null +++ b/ext/intl/tests/msgfmt_parse_int64_min_64.phpt @@ -0,0 +1,26 @@ +--TEST-- +MessageFormatter::parse() with PHP_INT_MIN on 64-bit platform +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +parse('-9,223,372,036,854,775,808'); +var_dump($parsed); + +$parsed = MessageFormatter::parseMessage('en_US', '{0,number,integer}', '-9,223,372,036,854,775,808'); +var_dump($parsed); + +?> +--EXPECT-- +array(1) { + [0]=> + int(-9223372036854775808) +} +array(1) { + [0]=> + int(-9223372036854775808) +} diff --git a/ext/intl/tests/msgfmt_parse_message_errors.phpt b/ext/intl/tests/msgfmt_parse_message_errors.phpt new file mode 100644 index 000000000000..7bd0780fa642 --- /dev/null +++ b/ext/intl/tests/msgfmt_parse_message_errors.phpt @@ -0,0 +1,27 @@ +--TEST-- +MessageFormatter::parseMessage() with invalid locale +--EXTENSIONS-- +intl +--CREDITS-- +girgias@php.net +--FILE-- + +--EXPECT-- +bool(false) +string(93) "MessageFormatter::parseMessage(): Creating message formatter failed: U_ILLEGAL_ARGUMENT_ERROR" +bool(false) +string(83) "msgfmt_parse_message(): Creating message formatter failed: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/msgfmt_setPattern_cache.phpt b/ext/intl/tests/msgfmt_setPattern_cache.phpt index 7aff410f082e..9b5af2542031 100644 --- a/ext/intl/tests/msgfmt_setPattern_cache.phpt +++ b/ext/intl/tests/msgfmt_setPattern_cache.phpt @@ -4,8 +4,6 @@ MessageFormatter::setPattern() invalidates arg types cache intl --FILE-- setPattern($broken); +var_dump($mf->getErrorMessage()); + +msgfmt_set_pattern($mf, $broken); +var_dump($mf->getErrorMessage()); + +?> +--EXPECT-- +string(103) "MessageFormatter::setPattern(): Error setting symbol value at line 0, offset 26: U_PATTERN_SYNTAX_ERROR" +string(93) "msgfmt_set_pattern(): Error setting symbol value at line 0, offset 26: U_PATTERN_SYNTAX_ERROR" diff --git a/ext/intl/tests/normalizer_get_raw_decomposition.phpt b/ext/intl/tests/normalizer_get_raw_decomposition.phpt index efb4424c80c9..678a85491fdc 100644 --- a/ext/intl/tests/normalizer_get_raw_decomposition.phpt +++ b/ext/intl/tests/normalizer_get_raw_decomposition.phpt @@ -2,67 +2,52 @@ normalizer_get_raw_decomposition() --EXTENSIONS-- intl ---SKIPIF-- - --FILE-- --EXPECT-- ---------------------- -'61' has no decomposition mapping -error info: 'U_ZERO_ERROR' (0) ---------------------- -'efbf9a' has the decomposition mapping 'e385a1' -error info: 'U_ZERO_ERROR' (0) ---------------------- -'efb7ba' has the decomposition mapping 'd8b5d984d98920d8a7d984d984d98720d8b9d984d98ad98720d988d8b3d984d985' -error info: 'U_ZERO_ERROR' (0) ---------------------- -'' has no decomposition mapping -error info: 'Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR' (1) ---------------------- -'6161' has no decomposition mapping -error info: 'Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR' (1) ---------------------- -'f5' has no decomposition mapping -error info: 'Code point out of range: U_ILLEGAL_ARGUMENT_ERROR' (1) +'a' has no decomposition mapping +'a' has no decomposition mapping +string(3) "ㅡ" +string(3) "ㅡ" +string(33) "صلى الله عليه وسلم" +string(33) "صلى الله عليه وسلم" +string(124) "Normalizer::getRawDecomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(125) "normalizer_get_raw_decomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(124) "Normalizer::getRawDecomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(125) "normalizer_get_raw_decomposition(): Input string must be exactly one UTF-8 encoded code point long.: U_ILLEGAL_ARGUMENT_ERROR" +string(84) "Normalizer::getRawDecomposition(): Code point out of range: U_ILLEGAL_ARGUMENT_ERROR" +string(85) "normalizer_get_raw_decomposition(): Code point out of range: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/rangeformatter/basic.phpt b/ext/intl/tests/rangeformatter/basic.phpt new file mode 100644 index 000000000000..0e76466bc09b --- /dev/null +++ b/ext/intl/tests/rangeformatter/basic.phpt @@ -0,0 +1,484 @@ +--TEST-- +Basic test for IntlNumberRangeFormatter +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, + 'IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE' => IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, + 'IDENTITY_FALLBACK_APPROXIMATELY' => IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, + 'IDENTITY_FALLBACK_RANGE' => IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE +]; + +$collapses = [ + 'COLLAPSE_AUTO' => IntlNumberRangeFormatter::COLLAPSE_AUTO, + 'COLLAPSE_NONE' => IntlNumberRangeFormatter::COLLAPSE_NONE, + 'COLLAPSE_UNIT' => IntlNumberRangeFormatter::COLLAPSE_UNIT, + 'COLLAPSE_ALL' => IntlNumberRangeFormatter::COLLAPSE_ALL +]; + +foreach ($languages as $language) { + foreach ($identityFallbacks as $iName => $identityFallback) { + foreach ($collapses as $cName => $collapse) { + echo PHP_EOL . $language . ' - ' . $cName . ' - ' . $iName . PHP_EOL; + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'measure-unit/length-meter', + $language, + $collapse, + $identityFallback + ); + + var_dump($nrf->format(1.1, 2.2)); + var_dump($nrf->format(100, 200)); + var_dump($nrf->format(-5, 5)); + var_dump($nrf->format(5, 5)); + var_dump($nrf->format(5.0001, 5.0001)); + var_dump($nrf->format(5, 5.1)); + var_dump($nrf->format(5.1, 6)); + } + } +} + +?> +--EXPECT-- +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(7) "5–5 m" +string(17) "5.0001–5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(11) "5 m – 5 m" +string(21) "5.0001 m – 5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(7) "5–5 m" +string(17) "5.0001–5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(7) "5–5 m" +string(17) "5.0001–5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(7) "5 - 5 m" +string(17) "5,0001 - 5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(9) "5 m - 5 m" +string(19) "5,0001 m - 5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(7) "5 - 5 m" +string(17) "5,0001 - 5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(7) "5 - 5 m" +string(17) "5,0001 - 5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(7) "5~5 m" +string(17) "5.0001~5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(11) "5 m ~ 5 m" +string(21) "5.0001 m ~ 5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(7) "5~5 m" +string(17) "5.0001~5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(7) "5~5 m" +string(17) "5.0001~5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" diff --git a/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt b/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt new file mode 100644 index 000000000000..31674ba6eea2 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test IntlNumberRangeFormatter cannot be cloned +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Trying to clone an uncloneable object of class IntlNumberRangeFormatter diff --git a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt new file mode 100644 index 000000000000..83c993d7fc98 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt @@ -0,0 +1,87 @@ +--TEST-- +errors for IntlNumberRangeFormatter +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage() . PHP_EOL; +} + +echo intl_get_error_code() . PHP_EOL; +echo intl_get_error_message() . PHP_EOL; + +try { + new IntlNumberRangeFormatter(); +} catch(Error $error) { + echo $error->getMessage() . PHP_EOL; +} + +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'ro', + 34, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'ro', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + 343 + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'invalid-language', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'ro_thisiswaytooooooooooooooooooooooooooooooooooooooooooooolongtobevaliditneedstobeatleast157characterstofailthevalidationinthelistformattercodeimplementation', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + +?> +--EXPECT-- +IntlNumberRangeFormatter::createFromSkeleton(): Failed to create the number skeleton +65811 +IntlNumberRangeFormatter::createFromSkeleton(): Failed to create the number skeleton: U_NUMBER_SKELETON_SYNTAX_ERROR +Call to private IntlNumberRangeFormatter::__construct() from global scope +IntlNumberRangeFormatter::createFromSkeleton(): Argument #3 ($collapse) must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL +IntlNumberRangeFormatter::createFromSkeleton(): Argument #4 ($identityFallback) must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE +IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) "invalid-language" is invalid +IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) must be no longer than 156 characters diff --git a/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt b/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt new file mode 100644 index 000000000000..f054aea94b5f --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test precision skeleton with IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +format(5.1, 5.2)); + var_dump($nrf->format(5.01, 5.02)); + var_dump($nrf->format(5.001, 5.002)); +} + +?> +--EXPECT-- +Approximate with .## +string(9) "5.1–5.2" +string(11) "5.01–5.02" +string(2) "~5" +Approximate with .# +string(9) "5.1–5.2" +string(2) "~5" +string(2) "~5" diff --git a/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt b/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt new file mode 100644 index 000000000000..9b3867161d60 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test IntlNumberRangeFormatter::createFromSkeleton throws error for ICU < 63 +--EXTENSIONS-- +intl +--SKIPIF-- += 0) { + die('skip for ICU > 63.0'); +} +?> +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Class "IntlNumberRangeFormatter" not found \ No newline at end of file diff --git a/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt b/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt new file mode 100644 index 000000000000..43afc85f2b5f --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test an empty skeleton with IntlNumberRangeFormatter +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +format(5.1, 5.2)); + +?> +--EXPECT-- +string(9) "5.1–5.2" diff --git a/ext/intl/tests/rbbiter___construct_basic.phpt b/ext/intl/tests/rbbiter___construct_basic.phpt index 6d2361f667b3..e749442daa9f 100644 --- a/ext/intl/tests/rbbiter___construct_basic.phpt +++ b/ext/intl/tests/rbbiter___construct_basic.phpt @@ -2,9 +2,10 @@ IntlRuleBasedBreakIterator::__construct: basic test --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --FILE-- = 0) die('skip for ICU < 61.1'); ?> --FILE-- = 61.1 && icu < 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 61.1'; ?> = 0) die('skip for ICU < 68.1'); ?> --FILE-- = 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 68.1'); ?> --FILE-- = 0) die('skip for ICU < 61.1'); ?> --FILE-- = 61.1 && icu < 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 61.1'); ?> = 0) die('skip for ICU < 68.1'); ?> --FILE-- = 68.1 --EXTENSIONS-- intl +--INI-- +intl.default_locale=pt_PT --SKIPIF-- = 68.1'); ?> --FILE-- getMessage(), PHP_EOL; +} + +$rb = resourcebundle_create('en_US', 'non-existing'); +var_dump($rb); +var_dump(intl_get_error_message()); + +require_once "resourcebundle.inc"; + +try { + $rb = new ResourceBundle('en_US', BUNDLE, false); + var_dump($rb); + var_dump(intl_get_error_message()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +$rb = resourcebundle_create('en_US', BUNDLE, false); +var_dump($rb); +var_dump(intl_get_error_message()); + +?> +--EXPECT-- +IntlException: ResourceBundle::__construct(): Cannot load libICU resource bundle +NULL +string(85) "resourcebundle_create(): Cannot load libICU resource bundle: U_MISSING_RESOURCE_ERROR" +IntlException: ResourceBundle::__construct(): Cannot load libICU resource bundle +NULL +string(85) "resourcebundle_create(): Cannot load libICU resource bundle: U_MISSING_RESOURCE_ERROR" diff --git a/ext/intl/tests/resourcebundle_get_errors.phpt b/ext/intl/tests/resourcebundle_get_errors.phpt new file mode 100644 index 000000000000..28952b816107 --- /dev/null +++ b/ext/intl/tests/resourcebundle_get_errors.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test ResourceBundle::get() missing keys +--EXTENSIONS-- +intl +--FILE-- +get('nonexisting')); +var_dump(intl_get_error_message()); + +var_dump(resourcebundle_get($bundle, 'nonexisting')); +var_dump(intl_get_error_message()); + +// Make sure accessing existing after non-existing works. +var_dump($bundle->get('teststring')); + +?> +--EXPECT-- +NULL +string(91) "ResourceBundle::get(): Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR" +NULL +string(90) "resourcebundle_get(): Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR" +string(12) "Hello World!" diff --git a/ext/intl/tests/resourcebundle_individual.phpt b/ext/intl/tests/resourcebundle_individual.phpt index d9be94b464b1..089c485dc8ab 100644 --- a/ext/intl/tests/resourcebundle_individual.phpt +++ b/ext/intl/tests/resourcebundle_individual.phpt @@ -1,5 +1,5 @@ --TEST-- -Test ResourceBundle::get() and length() - existing/missing keys +Test ResourceBundle::get() and length() - existing keys --EXTENSIONS-- intl --FILE-- @@ -25,13 +25,6 @@ function ut_main() { $r2 = ut_resourcebundle_get($r,'testarray' ); $str_res .= sprintf( "testarray: %s\n", ut_resourcebundle_get($r2, 2 ) ); - $t = ut_resourcebundle_get( $r, 'nonexisting' ); - $str_res .= debug( $t ); - - // Make sure accessing existing after non-existing works. - $t = ut_resourcebundle_get( $r, 'teststring' ); - $str_res .= debug( $t ); - return $str_res; } include_once( 'ut_common.inc' ); @@ -57,7 +50,3 @@ Array testbin: a1b2c3d4e5f67890 testtable: 3 testarray: string 3 -NULL - 2: Cannot load resource element 'nonexisting': U_MISSING_RESOURCE_ERROR -Hello World! - 0: U_ZERO_ERROR diff --git a/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt b/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt index 9d13be94aed5..b49e30317b3d 100644 --- a/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt +++ b/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt @@ -8,7 +8,6 @@ intl = 0) die('skip for ICU < 72.1'); ?> --FILE-- get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0); diff --git a/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt b/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt index d3e2615e0f49..98fa0c47305c 100644 --- a/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt +++ b/ext/intl/tests/resourcebundle_null_mandatory_args_variant_icu72-1.phpt @@ -8,7 +8,6 @@ intl = 72.1'); ?> --FILE-- get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0); diff --git a/ext/intl/tests/spoofchecker_007.phpt b/ext/intl/tests/spoofchecker_007.phpt index b5fc5814ddf8..5f3dbb47f192 100644 --- a/ext/intl/tests/spoofchecker_007.phpt +++ b/ext/intl/tests/spoofchecker_007.phpt @@ -4,12 +4,6 @@ spoofchecker with restriction level intl --SKIPIF-- -getConstant("SINGLE_SCRIPT_RESTRICTIVE")) { - die("skip Incompatible ICU version"); - } -?> --FILE-- or SpoofChecker::USET_CASE_INSENSITIVE%s)) +Spoofchecker::setAllowedChars(): Argument #2 ($patternOptions) must be a valid pattern option, 0 or (SpoofChecker::IGNORE_SPACE|( or SpoofChecker::CASE_INSENSITIVE%s)) Spoofchecker::setAllowedChars(): Argument #1 ($pattern) must be a valid regular expression character set pattern Spoofchecker::setAllowedChars(): Argument #1 ($pattern) must be a valid regular expression character set pattern diff --git a/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt new file mode 100644 index 000000000000..56cc194991ee --- /dev/null +++ b/ext/intl/tests/spoofchecker_supported_icu57_apis.phpt @@ -0,0 +1,36 @@ +--TEST-- +Spoofchecker exposes restriction-level APIs on all supported ICU versions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getConstant("ASCII"); +$singleScriptRestrictive = $r->getConstant("SINGLE_SCRIPT_RESTRICTIVE"); +$mixedNumbers = $r->getConstant("MIXED_NUMBERS"); + +var_dump($ascii !== false); +var_dump($singleScriptRestrictive !== false); +var_dump($mixedNumbers !== false); +var_dump(is_int($ascii)); +var_dump(is_int($singleScriptRestrictive)); +var_dump(is_int($mixedNumbers)); +var_dump($ascii !== $singleScriptRestrictive); +var_dump($ascii !== $mixedNumbers); +var_dump($singleScriptRestrictive !== $mixedNumbers); +var_dump($r->hasMethod("setRestrictionLevel")); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt index e8ed48d60a3e..187be350f594 100644 --- a/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt +++ b/ext/intl/tests/spoofchecker_unknown_restriction_level.phpt @@ -5,8 +5,6 @@ intl --SKIPIF-- --FILE-- --EXPECT-- -Spoofchecker::setRestrictionLevel(): Argument #1 ($level) must be one of Spoofchecker::ASCII, Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE, Spoofchecker::SINGLE_HIGHLY_RESTRICTIVE, Spoofchecker::SINGLE_MODERATELY_RESTRICTIVE, Spoofchecker::SINGLE_MINIMALLY_RESTRICTIVE, or Spoofchecker::UNRESTRICTIVE +Spoofchecker::setRestrictionLevel(): Argument #1 ($level) must be one of Spoofchecker::ASCII, Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE, Spoofchecker::HIGHLY_RESTRICTIVE, Spoofchecker::MODERATELY_RESTRICTIVE, Spoofchecker::MINIMALLY_RESTRICTIVE, or Spoofchecker::UNRESTRICTIVE diff --git a/ext/intl/tests/timezone_IDforWindowsID_basic.phpt b/ext/intl/tests/timezone_IDforWindowsID_basic.phpt index 8626223cb8bb..8e1fcbb4a8fc 100644 --- a/ext/intl/tests/timezone_IDforWindowsID_basic.phpt +++ b/ext/intl/tests/timezone_IDforWindowsID_basic.phpt @@ -8,7 +8,6 @@ intl array(NULL), 'India Standard Time' => array(NULL), 'Pacific Standard Time' => array('001', 'CA', 'MX', 'US', 'ZZ'), 'Romance Standard Time' => array('001', 'BE', 'DK', 'ES', 'FR'), @@ -25,9 +24,6 @@ foreach ($tzs as $tz => $regions) { } ?> --EXPECT-- -** Gnomeregan -bool(false) -Error: intltz_get_windows_id: Unknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR ** India Standard Time string(13) "Asia/Calcutta" ** Pacific Standard Time diff --git a/ext/intl/tests/timezone_IDforWindowsID_basic2.phpt b/ext/intl/tests/timezone_IDforWindowsID_basic2.phpt deleted file mode 100644 index 600e21fa70c8..000000000000 --- a/ext/intl/tests/timezone_IDforWindowsID_basic2.phpt +++ /dev/null @@ -1,45 +0,0 @@ ---TEST-- -IntlTimeZone::getIDForWindowsID basic test ---EXTENSIONS-- -intl ---SKIPIF-- -= 58.1'); ?> -= 0) die('skip for ICU <= 76.1'); ?> ---FILE-- - array(NULL), - 'India Standard Time' => array(NULL), - 'Pacific Standard Time' => array('001', 'CA', 'MX', 'US', 'ZZ'), - 'Romance Standard Time' => array('001', 'BE', 'DK', 'ES', 'FR'), -); - -foreach ($tzs as $tz => $regions) { - echo "** $tz\n"; - foreach ($regions as $region) { - var_dump(IntlTimeZone::getIDForWindowsID($tz, $region)); - if (intl_get_error_code() != U_ZERO_ERROR) { - echo "Error: ", intl_get_error_message(), "\n"; - } - } -} -?> ---EXPECTF-- -** Gnomeregan -bool(false) -Error: unknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR -** India Standard Time -string(13) "Asia/Calcutta" -** Pacific Standard Time -string(19) "America/Los_Angeles" -string(17) "America/Vancouver" -string(19) "America/Los_Angeles" -string(19) "America/Los_Angeles" -string(%d) "%r(PST8PDT|America\/Los_Angeles)%r" -** Romance Standard Time -string(12) "Europe/Paris" -string(15) "Europe/Brussels" -string(17) "Europe/Copenhagen" -string(13) "Europe/Madrid" -string(12) "Europe/Paris" diff --git a/ext/intl/tests/timezone_IDforWindowsID_basic_icu58_1.phpt b/ext/intl/tests/timezone_IDforWindowsID_basic_icu58_1.phpt new file mode 100644 index 000000000000..b92ebb89ec20 --- /dev/null +++ b/ext/intl/tests/timezone_IDforWindowsID_basic_icu58_1.phpt @@ -0,0 +1,41 @@ +--TEST-- +IntlTimeZone::getIDForWindowsID basic test +--EXTENSIONS-- +intl +--SKIPIF-- += 58.1'); ?> += 0) die('skip for ICU <= 76.1'); ?> +--FILE-- + array(NULL), + 'Pacific Standard Time' => array('001', 'CA', 'MX', 'US', 'ZZ'), + 'Romance Standard Time' => array('001', 'BE', 'DK', 'ES', 'FR'), +); + +foreach ($tzs as $tz => $regions) { + echo "** $tz\n"; + foreach ($regions as $region) { + var_dump(IntlTimeZone::getIDForWindowsID($tz, $region)); + if (intl_get_error_code() != U_ZERO_ERROR) { + echo "Error: ", intl_get_error_message(), "\n"; + } + } +} +?> +--EXPECTF-- +** India Standard Time +string(13) "Asia/Calcutta" +** Pacific Standard Time +string(19) "America/Los_Angeles" +string(17) "America/Vancouver" +string(19) "America/Los_Angeles" +string(19) "America/Los_Angeles" +string(%d) "%r(PST8PDT|America\/Los_Angeles)%r" +** Romance Standard Time +string(12) "Europe/Paris" +string(15) "Europe/Brussels" +string(17) "Europe/Copenhagen" +string(13) "Europe/Madrid" +string(12) "Europe/Paris" diff --git a/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt b/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt index 96de341974b1..d07c14797c65 100644 --- a/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt +++ b/ext/intl/tests/timezone_IDforWindowsID_basic_icu76_1.phpt @@ -8,7 +8,6 @@ intl array(NULL), 'India Standard Time' => array(NULL), 'Pacific Standard Time' => array('001', 'CA', 'MX', 'US', 'ZZ'), 'Romance Standard Time' => array('001', 'BE', 'DK', 'ES', 'FR'), @@ -24,10 +23,7 @@ foreach ($tzs as $tz => $regions) { } } ?> ---EXPECTF-- -** Gnomeregan -bool(false) -Error: %snknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR +--EXPECT-- ** India Standard Time string(13) "Asia/Calcutta" ** Pacific Standard Time diff --git a/ext/intl/tests/timezone_IDforWindowsID_error.phpt b/ext/intl/tests/timezone_IDforWindowsID_error.phpt new file mode 100644 index 000000000000..1160ce9f91a0 --- /dev/null +++ b/ext/intl/tests/timezone_IDforWindowsID_error.phpt @@ -0,0 +1,14 @@ +--TEST-- +IntlTimeZone::getIDForWindowsID() errors +--EXTENSIONS-- +intl +--FILE-- + +--EXPECT-- +bool(false) +string(85) "IntlTimeZone::getIDForWindowsID(): unknown windows timezone: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/timezone_argument_type_errors.phpt b/ext/intl/tests/timezone_argument_type_errors.phpt new file mode 100644 index 000000000000..02e1c58492c9 --- /dev/null +++ b/ext/intl/tests/timezone_argument_type_errors.phpt @@ -0,0 +1,42 @@ +--TEST-- +Intl timezone argument APIs reject non-stringable objects with TypeError +--EXTENSIONS-- +intl +--FILE-- +getMessage(), PHP_EOL; + } +} + +$std = new stdClass(); +$calendar = IntlCalendar::createInstance(); +$formatter = new IntlDateFormatter(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE); + +dump_exception(fn() => intlcal_create_instance($std)); +dump_exception(fn() => IntlCalendar::createInstance($std)); +dump_exception(fn() => intlcal_set_time_zone($calendar, $std)); +dump_exception(fn() => $calendar->setTimeZone($std)); +dump_exception(fn() => new IntlGregorianCalendar($std)); +dump_exception(fn() => datefmt_create(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $std)); +dump_exception(fn() => IntlDateFormatter::create(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $std)); +dump_exception(fn() => new IntlDateFormatter(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $std)); +dump_exception(fn() => datefmt_set_timezone($formatter, $std)); +dump_exception(fn() => $formatter->setTimeZone($std)); + +?> +--EXPECT-- +TypeError: intlcal_create_instance(): Argument #1 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlCalendar::createInstance(): Argument #1 ($timezone) Object of class stdClass could not be converted to string +TypeError: intlcal_set_time_zone(): Argument #2 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlCalendar::setTimeZone(): Argument #1 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlGregorianCalendar::__construct(): Argument #1 ($timezoneOrYear) Object of class stdClass could not be converted to string +TypeError: datefmt_create(): Argument #4 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlDateFormatter::create(): Argument #4 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlDateFormatter::__construct(): Argument #4 ($timezone) Object of class stdClass could not be converted to string +TypeError: datefmt_set_timezone(): Argument #2 ($timezone) Object of class stdClass could not be converted to string +TypeError: IntlDateFormatter::setTimeZone(): Argument #1 ($timezone) Object of class stdClass could not be converted to string diff --git a/ext/intl/tests/timezone_clone_basic.phpt b/ext/intl/tests/timezone_clone_basic.phpt index c09ffe462033..db13884d272d 100644 --- a/ext/intl/tests/timezone_clone_basic.phpt +++ b/ext/intl/tests/timezone_clone_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone clone handler: basic test intl --FILE-- GMT [rawOffset] => 0 [currentOffset] => 0 -) \ No newline at end of file +) diff --git a/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt b/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt index 2fa3a7d249fd..25fa0f8839bd 100644 --- a/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt +++ b/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::countEquivalentIDs(): basic test intl --FILE-- = 2); @@ -13,4 +12,4 @@ var_dump($count2 == $count); ?> --EXPECT-- bool(true) -bool(true) \ No newline at end of file +bool(true) diff --git a/ext/intl/tests/timezone_countEquivalentIDs_error.phpt b/ext/intl/tests/timezone_countEquivalentIDs_error.phpt index 23f95e129f1d..5eab5f881da8 100644 --- a/ext/intl/tests/timezone_countEquivalentIDs_error.phpt +++ b/ext/intl/tests/timezone_countEquivalentIDs_error.phpt @@ -4,10 +4,11 @@ IntlTimeZone::countEquivalentIDs(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::countEquivalentIDs(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) +IntlTimeZone::countEquivalentIDs(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_createDefault_basic.phpt b/ext/intl/tests/timezone_createDefault_basic.phpt index 82ba9c94564c..2281e9e35bf5 100644 --- a/ext/intl/tests/timezone_createDefault_basic.phpt +++ b/ext/intl/tests/timezone_createDefault_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createDefault(): basic test intl --FILE-- getMessage(), PHP_EOL; +} + +try { + var_dump(IntlTimeZone::createEnumeration(new stdClass())); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- -Warning: IntlTimeZone::createEnumeration(): invalid argument type in %s on line %d -bool(false) +--EXPECT-- +TypeError: IntlTimeZone::createEnumeration(): Argument #1 ($countryOrRawOffset) must be of type string|int|null, array given +TypeError: IntlTimeZone::createEnumeration(): Argument #1 ($countryOrRawOffset) must be of type string|int|null, stdClass given diff --git a/ext/intl/tests/timezone_createEnumeration_variation1.phpt b/ext/intl/tests/timezone_createEnumeration_variation1.phpt index 5dfe9f893e0f..96a73779bfa2 100644 --- a/ext/intl/tests/timezone_createEnumeration_variation1.phpt +++ b/ext/intl/tests/timezone_createEnumeration_variation1.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createEnumeration(): variant with offset intl --FILE-- --EXPECT-- -Array -( - [0] => Atlantic/Azores -) -Array -( - [0] => Atlantic/Azores -) +array(1) { + [0]=> + string(15) "Atlantic/Azores" +} +array(1) { + [0]=> + string(15) "Atlantic/Azores" +} diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt index 2173c4a5cd12..0eb26b826a34 100644 --- a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt +++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt @@ -1,13 +1,16 @@ --TEST-- -IntlTimeZone::createTimeZoneIDEnumeration(): errors +IntlTimeZone::createTimeZoneIDEnumeration() invalid zone type --EXTENSIONS-- intl --FILE-- getMessage(), PHP_EOL; +} + ?> ---EXPECTF-- -Warning: IntlTimeZone::createTimeZoneIDEnumeration(): bad zone type in %s on line %d -bool(false) +--EXPECT-- +ValueError: IntlTimeZone::createTimeZoneIDEnumeration(): Argument #1 ($type) must be one of IntlTimeZone::TYPE_ANY, IntlTimeZone::TYPE_CANONICAL, or IntlTimeZone::TYPE_CANONICAL_LOCATION diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error_64bit.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error_64bit.phpt new file mode 100644 index 000000000000..1e6791a172ca --- /dev/null +++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error_64bit.phpt @@ -0,0 +1,17 @@ +--TEST-- +IntlTimeZone::createTimeZoneIDEnumeration() offset out of range +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +?> +--EXPECT-- +ValueError: IntlTimeZone::createTimeZoneIDEnumeration(): Argument #3 ($rawOffset) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt index ff940aa725df..34523d0037d8 100644 --- a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt +++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createTimeZoneIDEnumeration(): variant without offset intl --FILE-- Atlantic/Azores - [1] => Etc/GMT+1 -) +array(2) { + [0]=> + string(15) "Atlantic/Azores" + [1]=> + string(9) "Etc/GMT+1" +} diff --git a/ext/intl/tests/timezone_createTimeZone_basic.phpt b/ext/intl/tests/timezone_createTimeZone_basic.phpt index c3ffe289672f..1a3549cafdf7 100644 --- a/ext/intl/tests/timezone_createTimeZone_basic.phpt +++ b/ext/intl/tests/timezone_createTimeZone_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::createTimeZone(): basic test intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::createTimeZone(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- NULL +IntlTimeZone::createTimeZone(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_equals_basic.phpt b/ext/intl/tests/timezone_equals_basic.phpt index 04636a4f7c4c..224f9c9229a3 100644 --- a/ext/intl/tests/timezone_equals_basic.phpt +++ b/ext/intl/tests/timezone_equals_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone equals handler: basic test intl --FILE-- getMessage()); + var_dump($tz == $tz2); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> @@ -35,5 +34,4 @@ object(IntlTimeZone)#2 (4) { ["currentOffset"]=> int(0) } -string(9) "Exception" -string(63) "Comparison with at least one unconstructed IntlTimeZone operand" \ No newline at end of file +Exception: Comparison with at least one unconstructed IntlTimeZone operand diff --git a/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt b/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt index 45443c78a166..3e9597de0bb8 100644 --- a/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt +++ b/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt @@ -2,11 +2,11 @@ IntlTimeZone::fromDateTimeZone(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon +intl.default_locale=nl --FILE-- getID(), $tz->getRawOffset()); diff --git a/ext/intl/tests/timezone_fromDateTimeZone_error.phpt b/ext/intl/tests/timezone_fromDateTimeZone_error.phpt index fe2a04453033..acd608bc376c 100644 --- a/ext/intl/tests/timezone_fromDateTimeZone_error.phpt +++ b/ext/intl/tests/timezone_fromDateTimeZone_error.phpt @@ -6,11 +6,12 @@ date.timezone=Atlantic/Azores intl --FILE-- getTimeZone())); +var_dump(intl_get_error_message()); + ?> ---EXPECTF-- -Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d +--EXPECT-- NULL +string(131) "IntlTimeZone::fromDateTimeZone(): time zone id 'WEST' extracted from ext/date DateTimeZone not recognized: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/timezone_getCanonicalID_basic.phpt b/ext/intl/tests/timezone_getCanonicalID_basic.phpt index 7660b04e2647..0bc18e4c8b65 100644 --- a/ext/intl/tests/timezone_getCanonicalID_basic.phpt +++ b/ext/intl/tests/timezone_getCanonicalID_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getCanonicalID: basic test intl --FILE-- --EXPECT-- Europe/Lisbon -Europe/Lisbon \ No newline at end of file +Europe/Lisbon diff --git a/ext/intl/tests/timezone_getCanonicalID_error.phpt b/ext/intl/tests/timezone_getCanonicalID_error.phpt index d85805555a38..542d3ca3fa41 100644 --- a/ext/intl/tests/timezone_getCanonicalID_error.phpt +++ b/ext/intl/tests/timezone_getCanonicalID_error.phpt @@ -4,10 +4,11 @@ IntlTimeZone::getCanonicalID(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getCanonicalID(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) +IntlTimeZone::getCanonicalID(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt b/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt index 3fedf4377197..d883bb06ebdb 100644 --- a/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt +++ b/ext/intl/tests/timezone_getCanonicalID_variant1_2.phpt @@ -4,20 +4,21 @@ IntlTimeZone::getCanonicalID(): second argument intl --FILE-- ---EXPECTF-- +--EXPECT-- string(13) "Europe/Lisbon" +U_ZERO_ERROR bool(true) - -Warning: IntlTimeZone::getCanonicalID(): error obtaining canonical ID in %stimezone_getCanonicalID_variant1_2.php on line %d bool(false) +IntlTimeZone::getCanonicalID(): error obtaining canonical ID: U_ILLEGAL_ARGUMENT_ERROR bool(true) diff --git a/ext/intl/tests/timezone_getDSTSavings_basic.phpt b/ext/intl/tests/timezone_getDSTSavings_basic.phpt index 1a0b5554322f..469e4b5791c0 100644 --- a/ext/intl/tests/timezone_getDSTSavings_basic.phpt +++ b/ext/intl/tests/timezone_getDSTSavings_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getDSTSavings(): basic test intl --FILE-- getDSTSavings()); @@ -14,4 +13,4 @@ var_dump(intltz_get_dst_savings($lsb)); ?> --EXPECT-- int(3600000) -int(3600000) \ No newline at end of file +int(3600000) diff --git a/ext/intl/tests/timezone_getDSTSavings_error.phpt b/ext/intl/tests/timezone_getDSTSavings_error.phpt deleted file mode 100644 index c444aab64533..000000000000 --- a/ext/intl/tests/timezone_getDSTSavings_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getDSTSavings(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_dst_savings(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_dst_savings(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getDisplayName_basic.phpt b/ext/intl/tests/timezone_getDisplayName_basic.phpt index 6db1596b3808..a80eeb762d1b 100644 --- a/ext/intl/tests/timezone_getDisplayName_basic.phpt +++ b/ext/intl/tests/timezone_getDisplayName_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getDisplayName(): basic test intl --FILE-- getDisplayName()); ?> --EXPECTF-- string(%d) "Western European%sTime" -string(%d) "Hora%sda Europa Ocidental" \ No newline at end of file +string(%d) "Hora%sda Europa Ocidental" diff --git a/ext/intl/tests/timezone_getDisplayName_error.phpt b/ext/intl/tests/timezone_getDisplayName_error.phpt index ce3ab2f7e766..ca845b2830ed 100644 --- a/ext/intl/tests/timezone_getDisplayName_error.phpt +++ b/ext/intl/tests/timezone_getDisplayName_error.phpt @@ -4,19 +4,12 @@ IntlTimeZone::getDisplayName(): errors intl --FILE-- getDisplayName(false, -1)); +echo intl_get_error_message(), PHP_EOL; -var_dump(intltz_get_display_name(null, IntlTimeZone::DISPLAY_SHORT, false, 'pt_PT')); ?> ---EXPECTF-- -Warning: IntlTimeZone::getDisplayName(): wrong display type in %s on line %d +--EXPECT-- bool(false) - -Fatal error: Uncaught TypeError: intltz_get_display_name(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_display_name(NULL, 1, false, 'pt_PT') -#1 {main} - thrown in %s on line %d +IntlTimeZone::getDisplayName(): wrong display type: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/timezone_getDisplayName_variant1.phpt b/ext/intl/tests/timezone_getDisplayName_variant1.phpt index 60c11ee91273..684e564779c6 100644 --- a/ext/intl/tests/timezone_getDisplayName_variant1.phpt +++ b/ext/intl/tests/timezone_getDisplayName_variant1.phpt @@ -2,15 +2,13 @@ IntlTimeZone::getDisplayName(): daylight parameter effect --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --FILE-- getDisplayName()); var_dump($lsb->getDisplayName(false)); var_dump($lsb->getDisplayName(true)); @@ -19,4 +17,4 @@ var_dump($lsb->getDisplayName(true)); --EXPECTF-- string(%d) "Western European%sTime" string(%d) "Western European%sTime" -string(28) "Western European Summer Time" \ No newline at end of file +string(28) "Western European Summer Time" diff --git a/ext/intl/tests/timezone_getDisplayName_variant4.phpt b/ext/intl/tests/timezone_getDisplayName_variant4.phpt index eccf6c78d2ca..ccde7f8e0ea7 100644 --- a/ext/intl/tests/timezone_getDisplayName_variant4.phpt +++ b/ext/intl/tests/timezone_getDisplayName_variant4.phpt @@ -2,15 +2,13 @@ IntlTimeZone::getDisplayName(): type parameter (ICU >= 51.2) --EXTENSIONS-- intl +--INI-- +intl.default_locale=en_US --FILE-- getDisplayName(false, IntlTimeZone::DISPLAY_SHORT)); var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG)); var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GENERIC)); @@ -21,12 +19,12 @@ var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_COMMONLY_USED)) var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_GENERIC_LOCATION)); ?> ---EXPECT-- -string(3) "GMT" +--EXPECTF-- +string(%d) "%r(GMT|GMT\+0)%r" string(30) "Western European Standard Time" string(13) "Portugal Time" string(21) "Western European Time" string(5) "+0000" -string(3) "GMT" -string(3) "GMT" +string(%d) "%r(GMT|GMT\+00:00)%r" +string(%d) "%r(GMT|GMT\+0)%r" string(13) "Portugal Time" diff --git a/ext/intl/tests/timezone_getEquivalentID_basic.phpt b/ext/intl/tests/timezone_getEquivalentID_basic.phpt index 2e311bc8664e..7702b01506ed 100644 --- a/ext/intl/tests/timezone_getEquivalentID_basic.phpt +++ b/ext/intl/tests/timezone_getEquivalentID_basic.phpt @@ -4,12 +4,11 @@ IntlTimeZone::getEquivalentID(): basic test intl --FILE-- --EXPECT-- -Portugal -Portugal \ No newline at end of file +string(8) "Portugal" +string(8) "Portugal" diff --git a/ext/intl/tests/timezone_getEquivalentID_error.phpt b/ext/intl/tests/timezone_getEquivalentID_error.phpt index ebb85fb1334a..c6b1a963daf7 100644 --- a/ext/intl/tests/timezone_getEquivalentID_error.phpt +++ b/ext/intl/tests/timezone_getEquivalentID_error.phpt @@ -4,10 +4,11 @@ IntlTimeZone::getEquivalentID(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getEquivalentID(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) +IntlTimeZone::getEquivalentID(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt b/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt index 597e9b51a0fc..be991baf5f67 100644 --- a/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt +++ b/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt @@ -11,24 +11,23 @@ if ($arch != 'x86_64' && $arch != 'i386') ?> --FILE-- getErrorCode()); var_dump($lsb->getErrorMessage()); +echo "Call to getOffset():\n"; var_dump($lsb->getOffset(INF, 1, $a, $b)); var_dump($lsb->getErrorCode()); var_dump($lsb->getErrorMessage()); ?> ---EXPECTF-- +--EXPECT-- int(0) string(12) "U_ZERO_ERROR" - -Warning: IntlTimeZone::getOffset(): error obtaining offset in %s on line %d +Call to getOffset(): bool(false) int(1) -string(48) "error obtaining offset: U_ILLEGAL_ARGUMENT_ERROR" +string(75) "IntlTimeZone::getOffset(): error obtaining offset: U_ILLEGAL_ARGUMENT_ERROR" diff --git a/ext/intl/tests/timezone_getErrorCode_error.phpt b/ext/intl/tests/timezone_getErrorCode_error.phpt deleted file mode 100644 index 3b91977c69b0..000000000000 --- a/ext/intl/tests/timezone_getErrorCode_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getErrorCode(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_error_code(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_error_code(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getErrorMessage_error.phpt b/ext/intl/tests/timezone_getErrorMessage_error.phpt deleted file mode 100644 index 80c5ec02f5a9..000000000000 --- a/ext/intl/tests/timezone_getErrorMessage_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getErrorMessage(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_error_message(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_error_message(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getGMT_basic.phpt b/ext/intl/tests/timezone_getGMT_basic.phpt index becc52fd3e14..d58b555bbe24 100644 --- a/ext/intl/tests/timezone_getGMT_basic.phpt +++ b/ext/intl/tests/timezone_getGMT_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getGMT(): basic test intl --FILE-- GMT [rawOffset] => 0 [currentOffset] => 0 -) \ No newline at end of file +) diff --git a/ext/intl/tests/timezone_getID_error.phpt b/ext/intl/tests/timezone_getID_error.phpt deleted file mode 100644 index 44b305f464dd..000000000000 --- a/ext/intl/tests/timezone_getID_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getID(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_id(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_id(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getIanaID.phpt b/ext/intl/tests/timezone_getIanaID.phpt index 7f728e48ec5f..1db39c398d6f 100644 --- a/ext/intl/tests/timezone_getIanaID.phpt +++ b/ext/intl/tests/timezone_getIanaID.phpt @@ -6,20 +6,24 @@ intl = 74.0'); ?> --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getIanaID(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) - -Warning: IntlTimeZone::getIanaID(): error obtaining IANA ID in %s on line %d +IntlTimeZone::getIanaID(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND bool(false) +IntlTimeZone::getIanaID(): error obtaining IANA ID: U_ILLEGAL_ARGUMENT_ERROR string(13) "Europe/Dublin" +U_ZERO_ERROR string(12) "Asia/Kolkata" +U_ZERO_ERROR bool(true) diff --git a/ext/intl/tests/timezone_getOffset_basic.phpt b/ext/intl/tests/timezone_getOffset_basic.phpt index 2f86869479c2..55c2fa7caee1 100644 --- a/ext/intl/tests/timezone_getOffset_basic.phpt +++ b/ext/intl/tests/timezone_getOffset_basic.phpt @@ -6,7 +6,6 @@ date.timezone=Atlantic/Azores intl --FILE-- --FILE-- getOffset(INF, true, $a, $a)); +echo intl_get_error_message(), PHP_EOL; -intltz_get_offset(null, time()*1000, false, $a, $a); ?> ---EXPECTF-- -Warning: IntlTimeZone::getOffset(): error obtaining offset in %s on line %d +--EXPECT-- bool(false) - -Fatal error: Uncaught TypeError: intltz_get_offset(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_offset(NULL, %f, false, NULL, NULL) -#1 {main} - thrown in %s on line %d +IntlTimeZone::getOffset(): error obtaining offset: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/timezone_getRawOffset_basic.phpt b/ext/intl/tests/timezone_getRawOffset_basic.phpt index 734df41375c4..545f1f1f8d87 100644 --- a/ext/intl/tests/timezone_getRawOffset_basic.phpt +++ b/ext/intl/tests/timezone_getRawOffset_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getRawOffset(): basic test intl --FILE-- getRawOffset()); @@ -14,4 +13,4 @@ var_dump(intltz_get_raw_offset($lsb)); ?> --EXPECT-- int(3600000) -int(0) \ No newline at end of file +int(0) diff --git a/ext/intl/tests/timezone_getRawOffset_error.phpt b/ext/intl/tests/timezone_getRawOffset_error.phpt deleted file mode 100644 index cc508ddbbebc..000000000000 --- a/ext/intl/tests/timezone_getRawOffset_error.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -IntlTimeZone::getRawOffset(): errors ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_get_raw_offset(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_get_raw_offset(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_getRegion_basic.phpt b/ext/intl/tests/timezone_getRegion_basic.phpt index 4aecd30e87d2..b156cb674559 100644 --- a/ext/intl/tests/timezone_getRegion_basic.phpt +++ b/ext/intl/tests/timezone_getRegion_basic.phpt @@ -4,12 +4,11 @@ IntlTimeZone::getRegion(): basic test intl --FILE-- --EXPECT-- -NL -NL +string(2) "NL" +string(2) "NL" diff --git a/ext/intl/tests/timezone_getRegion_error.phpt b/ext/intl/tests/timezone_getRegion_error.phpt index 70acbaa6fbca..d5ef9f2ae92e 100644 --- a/ext/intl/tests/timezone_getRegion_error.phpt +++ b/ext/intl/tests/timezone_getRegion_error.phpt @@ -4,14 +4,15 @@ IntlTimeZone::getRegion(): errors intl --FILE-- ---EXPECTF-- -Warning: IntlTimeZone::getRegion(): could not convert time zone id to UTF-16 in %s on line %d +--EXPECT-- bool(false) - -Warning: IntlTimeZone::getRegion(): error obtaining region in %s on line %d +IntlTimeZone::getRegion(): could not convert time zone id to UTF-16: U_INVALID_CHAR_FOUND bool(false) +IntlTimeZone::getRegion(): error obtaining region: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/timezone_getTZData_basic.phpt b/ext/intl/tests/timezone_getTZData_basic.phpt index bf0b3dfb9348..99d21357b556 100644 --- a/ext/intl/tests/timezone_getTZData_basic.phpt +++ b/ext/intl/tests/timezone_getTZData_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::getTZDataVersion: basic test intl --FILE-- --EXPECTF-- 20%d%s -20%d%s \ No newline at end of file +20%d%s diff --git a/ext/intl/tests/timezone_getUnknown_basic.phpt b/ext/intl/tests/timezone_getUnknown_basic.phpt index a7c2ac58177e..71785fc656c5 100644 --- a/ext/intl/tests/timezone_getUnknown_basic.phpt +++ b/ext/intl/tests/timezone_getUnknown_basic.phpt @@ -4,7 +4,6 @@ IntlCalendar::getUnknown(): basic test intl --FILE-- hasSameRules('foo')); -} catch (Error $ex) { - var_dump($ex->getCode(), $ex->getMessage()); - echo "\n"; -} - -try { - var_dump(intltz_has_same_rules(null, $tz)); -} catch (Error $ex) { - var_dump($ex->getCode(), $ex->getMessage()); - echo "\n"; -} -?> ---EXPECT-- -int(0) -string(93) "IntlTimeZone::hasSameRules(): Argument #1 ($other) must be of type IntlTimeZone, string given" - -int(0) -string(89) "intltz_has_same_rules(): Argument #1 ($timezone) must be of type IntlTimeZone, null given" diff --git a/ext/intl/tests/timezone_toDateTimeZone_basic.phpt b/ext/intl/tests/timezone_toDateTimeZone_basic.phpt index d82f65d7c0f4..bd5f6809d7e2 100644 --- a/ext/intl/tests/timezone_toDateTimeZone_basic.phpt +++ b/ext/intl/tests/timezone_toDateTimeZone_basic.phpt @@ -2,11 +2,11 @@ IntlTimeZone::toDateTimeZone(): basic test --EXTENSIONS-- intl +--INI-- +date.timezone=Europe/Lisbon +intl.default_locale=nl --FILE-- getID(), $tz->getRawOffset()); diff --git a/ext/intl/tests/timezone_toDateTimeZone_error.phpt b/ext/intl/tests/timezone_toDateTimeZone_error.phpt index 7355185541bc..8ba5be884b42 100644 --- a/ext/intl/tests/timezone_toDateTimeZone_error.phpt +++ b/ext/intl/tests/timezone_toDateTimeZone_error.phpt @@ -4,24 +4,18 @@ IntlTimeZone::toDateTimeZone(): errors intl --FILE-- toDateTimeZone()); -} catch (Exception $e) { - var_dump($e->getMessage()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + $previous = $e->getPrevious(); + echo ' ', $previous::class, ': ', $previous->getMessage(), PHP_EOL; } -var_dump(intltz_to_date_time_zone(1)); ?> ---EXPECTF-- -Warning: IntlTimeZone::toDateTimeZone(): intltz_to_date_time_zone: DateTimeZone constructor threw exception in %s on line %d -string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)" - -Fatal error: Uncaught TypeError: intltz_to_date_time_zone(): Argument #1 ($timezone) must be of type IntlTimeZone, int given in %s:%d -Stack trace: -#0 %s(%d): intltz_to_date_time_zone(1) -#1 {main} - thrown in %s on line %d +--EXPECT-- +IntlException: DateTimeZone constructor threw exception + DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown) diff --git a/ext/intl/tests/timezone_useDaylightTime_basic.phpt b/ext/intl/tests/timezone_useDaylightTime_basic.phpt index 2f8d02c2d154..3451739bb70f 100644 --- a/ext/intl/tests/timezone_useDaylightTime_basic.phpt +++ b/ext/intl/tests/timezone_useDaylightTime_basic.phpt @@ -4,7 +4,6 @@ IntlTimeZone::useDaylightTime: basic test intl --FILE-- ---EXPECTF-- -Fatal error: Uncaught TypeError: intltz_use_daylight_time(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d -Stack trace: -#0 %s(%d): intltz_use_daylight_time(NULL) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/timezone_windowsID_basic2.phpt b/ext/intl/tests/timezone_windowsID_basic2.phpt index aa1ce7f886c4..0db032207fa9 100644 --- a/ext/intl/tests/timezone_windowsID_basic2.phpt +++ b/ext/intl/tests/timezone_windowsID_basic2.phpt @@ -33,7 +33,7 @@ string(18) "Cuba Standard Time" string(21) "Central Standard Time" string(21) "Pacific Standard Time" bool(false) -Error: unknown system timezone: U_ILLEGAL_ARGUMENT_ERROR +Error: IntlTimeZone::getWindowsID(): unknown system timezone: U_ILLEGAL_ARGUMENT_ERROR string(21) "Morocco Standard Time" string(23) "Singapore Standard Time" string(26) "W. Australia Standard Time" diff --git a/ext/intl/tests/transliterator_clone.phpt b/ext/intl/tests/transliterator_clone.phpt index 057e2a7aef44..ccbe56ea6af5 100644 --- a/ext/intl/tests/transliterator_clone.phpt +++ b/ext/intl/tests/transliterator_clone.phpt @@ -4,7 +4,6 @@ Transliterator clone handler intl --FILE-- id,"\n"; diff --git a/ext/intl/tests/transliterator_create_error.phpt b/ext/intl/tests/transliterator_create_error.phpt index b554fb0dce5c..fd7db47a42ef 100644 --- a/ext/intl/tests/transliterator_create_error.phpt +++ b/ext/intl/tests/transliterator_create_error.phpt @@ -5,18 +5,14 @@ intl --FILE-- ---EXPECTF-- -Warning: Transliterator::create(): transliterator_create: unable to open ICU transliterator with id "inexistent id" in %s on line %d -transliterator_create: unable to open ICU transliterator with id "inexistent id": U_INVALID_ID - -Warning: Transliterator::create(): String conversion of id to UTF-16 failed in %s on line %d -String conversion of id to UTF-16 failed: U_INVALID_CHAR_FOUND -Done. +--EXPECT-- +NULL +Transliterator::create(): unable to open ICU transliterator with id "inexistent id": U_INVALID_ID +NULL +Transliterator::create(): String conversion of id to UTF-16 failed: U_INVALID_CHAR_FOUND diff --git a/ext/intl/tests/transliterator_create_from_rule_basic.phpt b/ext/intl/tests/transliterator_create_from_rule_basic.phpt index 5c9aa182b522..02f0b0362b78 100644 --- a/ext/intl/tests/transliterator_create_from_rule_basic.phpt +++ b/ext/intl/tests/transliterator_create_from_rule_basic.phpt @@ -4,7 +4,6 @@ Transliterator::createFromRules (basic) intl --FILE-- y; diff --git a/ext/intl/tests/transliterator_create_from_rule_error.phpt b/ext/intl/tests/transliterator_create_from_rule_error.phpt index 9a3b86944c8e..e6f885bfbc8f 100644 --- a/ext/intl/tests/transliterator_create_from_rule_error.phpt +++ b/ext/intl/tests/transliterator_create_from_rule_error.phpt @@ -4,7 +4,6 @@ Transliterator::createFromRules (error) intl --FILE-- ---EXPECTF-- -Warning: Transliterator::createFromRules(): String conversion of rules to UTF-16 failed in %s on line %d -String conversion of rules to UTF-16 failed: U_INVALID_CHAR_FOUND - -Warning: Transliterator::createFromRules(): transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error after "{'``'}a > “;", before or at "{'``'}a > b;") in %s on line %d -transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error after "{'``'}a > “;", before or at "{'``'}a > b;"): U_RULE_MASK_ERROR - -Warning: Transliterator::createFromRules(): transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error at offset 0, before or at "ffff") in %s on line %d -transliterator_create_from_rules: unable to create ICU transliterator from rules (parse error at offset 0, before or at "ffff"): U_MISSING_OPERATOR +--EXPECT-- +Transliterator::createFromRules(): String conversion of rules to UTF-16 failed: U_INVALID_CHAR_FOUND +Transliterator::createFromRules(): unable to create ICU transliterator from rules (parse error after "{'``'}a > “;", before or at "{'``'}a > b;"): U_RULE_MASK_ERROR +Transliterator::createFromRules(): unable to create ICU transliterator from rules (parse error at offset 0, before or at "ffff"): U_MISSING_OPERATOR Done. diff --git a/ext/intl/tests/transliterator_create_inverse_basic.phpt b/ext/intl/tests/transliterator_create_inverse_basic.phpt index 7206d61ea070..ed9187b4c044 100644 --- a/ext/intl/tests/transliterator_create_inverse_basic.phpt +++ b/ext/intl/tests/transliterator_create_inverse_basic.phpt @@ -5,8 +5,6 @@ intl --FILE-- transliterate($orstr); diff --git a/ext/intl/tests/transliterator_create_inverse_error.phpt b/ext/intl/tests/transliterator_create_inverse_error.phpt deleted file mode 100644 index a229a2eb7905..000000000000 --- a/ext/intl/tests/transliterator_create_inverse_error.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Transliterator::createInverse (error) ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: transliterator_create_inverse(): Argument #1 ($transliterator) must be of type Transliterator, string given in %s:%d -Stack trace: -#0 %s(%d): transliterator_create_inverse('jj') -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/transliterator_get_error_code_basic.phpt b/ext/intl/tests/transliterator_get_error_code_basic.phpt deleted file mode 100644 index 8fb59aa8b87d..000000000000 --- a/ext/intl/tests/transliterator_get_error_code_basic.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -Transliterator::getErrorCode (basic) ---EXTENSIONS-- -intl ---FILE-- -transliterate("\x8F")); -echo transliterator_get_error_code($t), "\n"; - -echo $t->getErrorCode(), "\n"; - -var_dump($t->transliterate("")); -echo $t->getErrorCode(), "\n"; - -echo "Done.\n"; -?> ---EXPECTF-- -Warning: Transliterator::transliterate(): String conversion of string to UTF-16 failed in %s on line %d -bool(false) -10 -10 -string(0) "" -0 -Done. diff --git a/ext/intl/tests/transliterator_get_error_code_error.phpt b/ext/intl/tests/transliterator_get_error_code_error.phpt deleted file mode 100644 index bb90e4ab6a43..000000000000 --- a/ext/intl/tests/transliterator_get_error_code_error.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Transliterator::getErrorCode (error) ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: transliterator_get_error_code(): Argument #1 ($transliterator) must be of type Transliterator, array given in %s:%d -Stack trace: -#0 %s(%d): transliterator_get_error_code(Array) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/transliterator_get_error_message_basic.phpt b/ext/intl/tests/transliterator_get_error_message_basic.phpt index 3c4c9eca513f..6f5ae0e4d0ee 100644 --- a/ext/intl/tests/transliterator_get_error_message_basic.phpt +++ b/ext/intl/tests/transliterator_get_error_message_basic.phpt @@ -1,26 +1,23 @@ --TEST-- -Transliterator::getErrorMessage (basic) +Transliterator::getErrorMessage() and Transliterator::getErrorCode()(basic) --EXTENSIONS-- intl --FILE-- transliterate("\x8F")); -echo transliterator_get_error_message($t), "\n"; -echo $t->getErrorMessage(), "\n"; +echo transliterator_get_error_code($t), ': ', transliterator_get_error_message($t), "\n"; + +echo $t->getErrorCode(), ': ', $t->getErrorMessage(), "\n"; var_dump($t->transliterate("")); -echo $t->getErrorMessage(), "\n"; +echo $t->getErrorCode(), ': ', $t->getErrorMessage(), "\n"; -echo "Done.\n"; ?> ---EXPECTF-- -Warning: Transliterator::transliterate(): String conversion of string to UTF-16 failed in %s on line %d +--EXPECT-- bool(false) -String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND -String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND +10: Transliterator::transliterate(): String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND +10: Transliterator::transliterate(): String conversion of string to UTF-16 failed: U_INVALID_CHAR_FOUND string(0) "" -U_ZERO_ERROR -Done. +0: U_ZERO_ERROR diff --git a/ext/intl/tests/transliterator_get_error_message_error.phpt b/ext/intl/tests/transliterator_get_error_message_error.phpt deleted file mode 100644 index 8449c3671d45..000000000000 --- a/ext/intl/tests/transliterator_get_error_message_error.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Transliterator::getErrorMessage (error) ---EXTENSIONS-- -intl ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught TypeError: transliterator_get_error_message(): Argument #1 ($transliterator) must be of type Transliterator, array given in %s:%d -Stack trace: -#0 %s(%d): transliterator_get_error_message(Array) -#1 {main} - thrown in %s on line %d diff --git a/ext/intl/tests/transliterator_list_ids_basic.phpt b/ext/intl/tests/transliterator_list_ids_basic.phpt index f6ffb06e81dd..8a808cd69459 100644 --- a/ext/intl/tests/transliterator_list_ids_basic.phpt +++ b/ext/intl/tests/transliterator_list_ids_basic.phpt @@ -5,7 +5,6 @@ intl --FILE-- 100); var_dump(count(Transliterator::listIDs()) > 100); diff --git a/ext/intl/tests/transliterator_transliterate_error.phpt b/ext/intl/tests/transliterator_transliterate_error.phpt index 4a354465bf21..e11de9333d4c 100644 --- a/ext/intl/tests/transliterator_transliterate_error.phpt +++ b/ext/intl/tests/transliterator_transliterate_error.phpt @@ -2,31 +2,34 @@ Transliterator::transliterate (error) --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=true --FILE-- getMessage(), PHP_EOL; +} try { - transliterator_transliterate($tr,"str",7,6); -} catch (ValueError $exception) { - echo $exception->getMessage() . "\n"; + transliterator_transliterate($tr, "str", 7, 6); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } //bad UTF-8 -transliterator_transliterate($tr, "\x80\x03"); +try { + transliterator_transliterate($tr, "\x80\x03"); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} -echo "Done.\n"; ?> ---EXPECTF-- -Warning: transliterator_transliterate(): transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 3) in %s on line %d -bool(false) -transliterator_transliterate(): Argument #2 ($string) must be less than or equal to argument #3 ($end) - -Warning: transliterator_transliterate(): String conversion of string to UTF-16 failed in %s on line %d -Done. +--EXPECT-- +IntlException: transliterator_transliterate(): Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 3) +ValueError: transliterator_transliterate(): Argument #2 ($string) must be less than or equal to argument #3 ($end) +IntlException: transliterator_transliterate(): String conversion of string to UTF-16 failed diff --git a/ext/intl/tests/transliterator_transliterate_variant1.phpt b/ext/intl/tests/transliterator_transliterate_variant1.phpt index 0e288ee63d25..1cc76cd244ab 100644 --- a/ext/intl/tests/transliterator_transliterate_variant1.phpt +++ b/ext/intl/tests/transliterator_transliterate_variant1.phpt @@ -2,37 +2,32 @@ transliterator_transliterate (variant 1, non-transliterator 1st arg) --EXTENSIONS-- intl +--INI-- +intl.use_exceptions=true --FILE-- getMessage(), PHP_EOL; +} class A { -function __toString() { return "inexistent id"; } + function __toString() { return "inexistent id"; } } -echo transliterator_transliterate(new A(), $str), "\n"; -echo intl_get_error_message(), "\n"; - -echo "Done.\n"; +try { + echo transliterator_transliterate(new A(), $str), "\n"; +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> ---EXPECTF-- +--EXPECT-- \u0020o - -Warning: transliterator_transliterate(): String conversion of id to UTF-16 failed in %s on line %d - -Warning: transliterator_transliterate(): Could not create transliterator with ID %s - -String conversion of id to UTF-16 failed: U_INVALID_CHAR_FOUND - -Warning: transliterator_transliterate(): transliterator_create: unable to open ICU transliterator with id "inexistent id" in %s on line %d - -Warning: transliterator_transliterate(): Could not create transliterator with ID "inexistent id" (transliterator_create: unable to open ICU transliterator with id "inexistent id": U_INVALID_ID) in %s on line %d - -transliterator_create: unable to open ICU transliterator with id "inexistent id": U_INVALID_ID -Done. +IntlException: transliterator_transliterate(): String conversion of id to UTF-16 failed +IntlException: transliterator_transliterate(): unable to open ICU transliterator with id "inexistent id" diff --git a/ext/intl/tests/uconverter___construct_error.phpt b/ext/intl/tests/uconverter___construct_error.phpt index 92adc4a71862..7237f799f885 100644 --- a/ext/intl/tests/uconverter___construct_error.phpt +++ b/ext/intl/tests/uconverter___construct_error.phpt @@ -1,15 +1,22 @@ --TEST-- Basic UConverter::convert() usage ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- ---EXPECTF-- -Warning: UConverter::__construct(): ucnv_open() returned error 4: U_FILE_ACCESS_ERROR in %s on line %d -object(UConverter)#%d (0) { +try { + $c = new UConverter("\x80", 'utf-8'); + var_dump($c); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + $c = new UConverter('utf-8', "\x80"); + var_dump($c); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } +?> +--EXPECT-- +IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR +IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR diff --git a/ext/intl/tests/uconverter_bug66873.phpt b/ext/intl/tests/uconverter_bug66873.phpt index 9ea684fbd389..68a01eee93dc 100644 --- a/ext/intl/tests/uconverter_bug66873.phpt +++ b/ext/intl/tests/uconverter_bug66873.phpt @@ -4,9 +4,13 @@ Bug #66873 - crash in UConverter with invalid encoding intl --FILE-- toUCallback(1, 1, 1, $b); var_dump($o->getErrorCode()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} ?> --EXPECT-- -int(27) +IntlException: UConverter::__construct(): returned error 4: U_FILE_ACCESS_ERROR diff --git a/ext/intl/tests/uconverter_func_subst.phpt b/ext/intl/tests/uconverter_func_subst.phpt index f8a32e814bb4..8d6553fc9834 100644 --- a/ext/intl/tests/uconverter_func_subst.phpt +++ b/ext/intl/tests/uconverter_func_subst.phpt @@ -1,5 +1,5 @@ --TEST-- -Basic UConverter::convert() w/ Subsitution +Basic UConverter::convert() w/ Substitution --EXTENSIONS-- intl --INI-- @@ -25,7 +25,7 @@ foreach(array('?','','??') as $subst) { --EXPECT-- string(23) "This is an ascii string" string(12) "Snowman: (?)" -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR -Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR +Error: UConverter::transcode(): returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR diff --git a/ext/intl/tests/uconverter_getDestinationEncoding.phpt b/ext/intl/tests/uconverter_getDestinationEncoding.phpt index d354f2a5682f..ca1a9b4d5a40 100644 --- a/ext/intl/tests/uconverter_getDestinationEncoding.phpt +++ b/ext/intl/tests/uconverter_getDestinationEncoding.phpt @@ -2,8 +2,6 @@ UConverter::getDestinationEncoding() --CREDITS-- Andy McNeice - PHP Testfest 2017 ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/uconverter_getSourceEncoding.phpt b/ext/intl/tests/uconverter_getSourceEncoding.phpt index 1bd99f81de00..2065f83e9b5f 100644 --- a/ext/intl/tests/uconverter_getSourceEncoding.phpt +++ b/ext/intl/tests/uconverter_getSourceEncoding.phpt @@ -2,8 +2,6 @@ UConverter::getSourceEncoding() --CREDITS-- Andy McNeice - PHP Testfest 2017 ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/tests/uconverter_setSourceEncoding.phpt b/ext/intl/tests/uconverter_setSourceEncoding.phpt index 3ad539bf80b7..c29558d546aa 100644 --- a/ext/intl/tests/uconverter_setSourceEncoding.phpt +++ b/ext/intl/tests/uconverter_setSourceEncoding.phpt @@ -2,8 +2,6 @@ UConverter::setSourceEncoding() --CREDITS-- Andy McNeice - PHP Testfest 2017 ---INI-- -intl.error_level = E_WARNING --EXTENSIONS-- intl --FILE-- diff --git a/ext/intl/timezone/timezone.stub.php b/ext/intl/timezone/timezone.stub.php index c879bb9ce55e..8a8927f7cd8a 100644 --- a/ext/intl/timezone/timezone.stub.php +++ b/ext/intl/timezone/timezone.stub.php @@ -45,11 +45,10 @@ public static function countEquivalentIDs(string $timezoneId): int|false {} public static function createDefault(): IntlTimeZone {} /** - * @param IntlTimeZone|string|int|float|null $countryOrRawOffset * @tentative-return-type * @alias intltz_create_enumeration */ - public static function createEnumeration($countryOrRawOffset = null): IntlIterator|false {} + public static function createEnumeration(string|int|null $countryOrRawOffset = null): IntlIterator|false {} /** * @tentative-return-type diff --git a/ext/intl/timezone/timezone_arginfo.h b/ext/intl/timezone/timezone_arginfo.h index 6206e03efad3..3b1985e685ee 100644 --- a/ext/intl/timezone/timezone_arginfo.h +++ b/ext/intl/timezone/timezone_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 6ffeea8491aa48c49879fa77bdb644d10d5c71bd */ +/* This is a generated file, edit timezone.stub.php instead. + * Stub hash: 22e652c6a05ade0a6fd3119e4742cd260ba27146 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlTimeZone___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -12,7 +12,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlTimeZone_crea ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_IntlTimeZone_createEnumeration, 0, 0, IntlIterator, MAY_BE_FALSE) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, countryOrRawOffset, "null") + ZEND_ARG_TYPE_MASK(0, countryOrRawOffset, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IntlTimeZone_createTimeZone, 0, 1, IntlTimeZone, 1) @@ -168,69 +168,69 @@ static zend_class_entry *register_class_IntlTimeZone(void) zval const_DISPLAY_SHORT_value; ZVAL_LONG(&const_DISPLAY_SHORT_value, TimeZone::SHORT); - zend_string *const_DISPLAY_SHORT_name = zend_string_init_interned("DISPLAY_SHORT", sizeof("DISPLAY_SHORT") - 1, 1); + zend_string *const_DISPLAY_SHORT_name = zend_string_init_interned("DISPLAY_SHORT", sizeof("DISPLAY_SHORT") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_SHORT_name, &const_DISPLAY_SHORT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_SHORT_name); + zend_string_release_ex(const_DISPLAY_SHORT_name, true); zval const_DISPLAY_LONG_value; ZVAL_LONG(&const_DISPLAY_LONG_value, TimeZone::LONG); - zend_string *const_DISPLAY_LONG_name = zend_string_init_interned("DISPLAY_LONG", sizeof("DISPLAY_LONG") - 1, 1); + zend_string *const_DISPLAY_LONG_name = zend_string_init_interned("DISPLAY_LONG", sizeof("DISPLAY_LONG") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_LONG_name, &const_DISPLAY_LONG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_LONG_name); + zend_string_release_ex(const_DISPLAY_LONG_name, true); zval const_DISPLAY_SHORT_GENERIC_value; ZVAL_LONG(&const_DISPLAY_SHORT_GENERIC_value, TimeZone::SHORT_GENERIC); - zend_string *const_DISPLAY_SHORT_GENERIC_name = zend_string_init_interned("DISPLAY_SHORT_GENERIC", sizeof("DISPLAY_SHORT_GENERIC") - 1, 1); + zend_string *const_DISPLAY_SHORT_GENERIC_name = zend_string_init_interned("DISPLAY_SHORT_GENERIC", sizeof("DISPLAY_SHORT_GENERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_SHORT_GENERIC_name, &const_DISPLAY_SHORT_GENERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_SHORT_GENERIC_name); + zend_string_release_ex(const_DISPLAY_SHORT_GENERIC_name, true); zval const_DISPLAY_LONG_GENERIC_value; ZVAL_LONG(&const_DISPLAY_LONG_GENERIC_value, TimeZone::LONG_GENERIC); - zend_string *const_DISPLAY_LONG_GENERIC_name = zend_string_init_interned("DISPLAY_LONG_GENERIC", sizeof("DISPLAY_LONG_GENERIC") - 1, 1); + zend_string *const_DISPLAY_LONG_GENERIC_name = zend_string_init_interned("DISPLAY_LONG_GENERIC", sizeof("DISPLAY_LONG_GENERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_LONG_GENERIC_name, &const_DISPLAY_LONG_GENERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_LONG_GENERIC_name); + zend_string_release_ex(const_DISPLAY_LONG_GENERIC_name, true); zval const_DISPLAY_SHORT_GMT_value; ZVAL_LONG(&const_DISPLAY_SHORT_GMT_value, TimeZone::SHORT_GMT); - zend_string *const_DISPLAY_SHORT_GMT_name = zend_string_init_interned("DISPLAY_SHORT_GMT", sizeof("DISPLAY_SHORT_GMT") - 1, 1); + zend_string *const_DISPLAY_SHORT_GMT_name = zend_string_init_interned("DISPLAY_SHORT_GMT", sizeof("DISPLAY_SHORT_GMT") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_SHORT_GMT_name, &const_DISPLAY_SHORT_GMT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_SHORT_GMT_name); + zend_string_release_ex(const_DISPLAY_SHORT_GMT_name, true); zval const_DISPLAY_LONG_GMT_value; ZVAL_LONG(&const_DISPLAY_LONG_GMT_value, TimeZone::LONG_GMT); - zend_string *const_DISPLAY_LONG_GMT_name = zend_string_init_interned("DISPLAY_LONG_GMT", sizeof("DISPLAY_LONG_GMT") - 1, 1); + zend_string *const_DISPLAY_LONG_GMT_name = zend_string_init_interned("DISPLAY_LONG_GMT", sizeof("DISPLAY_LONG_GMT") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_LONG_GMT_name, &const_DISPLAY_LONG_GMT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_LONG_GMT_name); + zend_string_release_ex(const_DISPLAY_LONG_GMT_name, true); zval const_DISPLAY_SHORT_COMMONLY_USED_value; ZVAL_LONG(&const_DISPLAY_SHORT_COMMONLY_USED_value, TimeZone::SHORT_COMMONLY_USED); - zend_string *const_DISPLAY_SHORT_COMMONLY_USED_name = zend_string_init_interned("DISPLAY_SHORT_COMMONLY_USED", sizeof("DISPLAY_SHORT_COMMONLY_USED") - 1, 1); + zend_string *const_DISPLAY_SHORT_COMMONLY_USED_name = zend_string_init_interned("DISPLAY_SHORT_COMMONLY_USED", sizeof("DISPLAY_SHORT_COMMONLY_USED") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_SHORT_COMMONLY_USED_name, &const_DISPLAY_SHORT_COMMONLY_USED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_SHORT_COMMONLY_USED_name); + zend_string_release_ex(const_DISPLAY_SHORT_COMMONLY_USED_name, true); zval const_DISPLAY_GENERIC_LOCATION_value; ZVAL_LONG(&const_DISPLAY_GENERIC_LOCATION_value, TimeZone::GENERIC_LOCATION); - zend_string *const_DISPLAY_GENERIC_LOCATION_name = zend_string_init_interned("DISPLAY_GENERIC_LOCATION", sizeof("DISPLAY_GENERIC_LOCATION") - 1, 1); + zend_string *const_DISPLAY_GENERIC_LOCATION_name = zend_string_init_interned("DISPLAY_GENERIC_LOCATION", sizeof("DISPLAY_GENERIC_LOCATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_DISPLAY_GENERIC_LOCATION_name, &const_DISPLAY_GENERIC_LOCATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DISPLAY_GENERIC_LOCATION_name); + zend_string_release_ex(const_DISPLAY_GENERIC_LOCATION_name, true); zval const_TYPE_ANY_value; ZVAL_LONG(&const_TYPE_ANY_value, UCAL_ZONE_TYPE_ANY); - zend_string *const_TYPE_ANY_name = zend_string_init_interned("TYPE_ANY", sizeof("TYPE_ANY") - 1, 1); + zend_string *const_TYPE_ANY_name = zend_string_init_interned("TYPE_ANY", sizeof("TYPE_ANY") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_ANY_name, &const_TYPE_ANY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_ANY_name); + zend_string_release_ex(const_TYPE_ANY_name, true); zval const_TYPE_CANONICAL_value; ZVAL_LONG(&const_TYPE_CANONICAL_value, UCAL_ZONE_TYPE_CANONICAL); - zend_string *const_TYPE_CANONICAL_name = zend_string_init_interned("TYPE_CANONICAL", sizeof("TYPE_CANONICAL") - 1, 1); + zend_string *const_TYPE_CANONICAL_name = zend_string_init_interned("TYPE_CANONICAL", sizeof("TYPE_CANONICAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_CANONICAL_name, &const_TYPE_CANONICAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_CANONICAL_name); + zend_string_release_ex(const_TYPE_CANONICAL_name, true); zval const_TYPE_CANONICAL_LOCATION_value; ZVAL_LONG(&const_TYPE_CANONICAL_LOCATION_value, UCAL_ZONE_TYPE_CANONICAL_LOCATION); - zend_string *const_TYPE_CANONICAL_LOCATION_name = zend_string_init_interned("TYPE_CANONICAL_LOCATION", sizeof("TYPE_CANONICAL_LOCATION") - 1, 1); + zend_string *const_TYPE_CANONICAL_LOCATION_name = zend_string_init_interned("TYPE_CANONICAL_LOCATION", sizeof("TYPE_CANONICAL_LOCATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_TYPE_CANONICAL_LOCATION_name, &const_TYPE_CANONICAL_LOCATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TYPE_CANONICAL_LOCATION_name); + zend_string_release_ex(const_TYPE_CANONICAL_LOCATION_name, true); return class_entry; } diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp index 2617b59a11bc..319e81c9a77d 100644 --- a/ext/intl/timezone/timezone_class.cpp +++ b/ext/intl/timezone/timezone_class.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -18,6 +18,7 @@ #endif #include "../intl_cppshims.h" +#include #include #include @@ -61,151 +62,152 @@ U_CFUNC void timezone_object_construct(const TimeZone *zone, zval *object, int o * Convert from TimeZone to DateTimeZone object */ U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, - const char *func, zval *ret) + zval *ret) { - UnicodeString id; - char *message = NULL; - php_timezone_obj *tzobj; - zval arg; + UnicodeString id; timeZone->getID(id); if (id.isBogus()) { - spprintf(&message, 0, "%s: could not obtain TimeZone id", func); intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - goto error; + "could not obtain TimeZone id"); + return nullptr; } - object_init_ex(ret, php_date_get_timezone_ce()); - tzobj = Z_PHPTIMEZONE_P(ret); - if (id.compare(0, 3, UnicodeString("GMT", sizeof("GMT")-1, US_INV)) == 0) { /* The DateTimeZone constructor doesn't support offset time zones, - * so we must mess with DateTimeZone structure ourselves */ - tzobj->initialized = 1; + * so we must mess with DateTimeZone structure ourselves */ + object_init_ex(ret, php_date_get_timezone_ce()); + php_timezone_obj *tzobj = Z_PHPTIMEZONE_P(ret); + + tzobj->initialized = true; tzobj->type = TIMELIB_ZONETYPE_OFFSET; //convert offset from milliseconds to seconds tzobj->tzi.utc_offset = timeZone->getRawOffset() / 1000; } else { - zend_string *u8str; - /* Call the constructor! */ - u8str = intl_charFromString(id, &INTL_ERROR_CODE(*outside_error)); + zend_string *u8str = intl_charFromString(id, &INTL_ERROR_CODE(*outside_error)); if (!u8str) { - spprintf(&message, 0, "%s: could not convert id to UTF-8", func); intl_errors_set(outside_error, INTL_ERROR_CODE(*outside_error), - message, 1); - goto error; + "could not convert id to UTF-8"); + return nullptr; } + + zval arg; ZVAL_STR(&arg, u8str); - zend_call_known_instance_method_with_1_params( - Z_OBJCE_P(ret)->constructor, Z_OBJ_P(ret), NULL, &arg); - if (EG(exception)) { - spprintf(&message, 0, - "%s: DateTimeZone constructor threw exception", func); - intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, - message, 1); - zend_object_store_ctor_failed(Z_OBJ_P(ret)); - zval_ptr_dtor(&arg); - goto error; - } + /* Instantiate the object and call the constructor */ + zend_result status = object_init_with_constructor(ret, php_date_get_timezone_ce(), 1, &arg, nullptr); zval_ptr_dtor(&arg); - } - - if (0) { -error: - if (ret) { - zval_ptr_dtor(ret); + if (UNEXPECTED(status == FAILURE)) { + zend_throw_exception(IntlException_ce_ptr, "DateTimeZone constructor threw exception", 0); + return nullptr; } - ret = NULL; } - if (message) { - efree(message); - } return ret; } /* }}} */ +static void timezone_throw_exception_with_call_location(const char *msg, const char *add_info) +{ + zend_string *fn = get_active_function_or_method_name(); + zend_throw_error(IntlException_ce_ptr, "%s(): %s%s%s%s", + ZSTR_VAL(fn), msg, + add_info ? "\"" : "", + add_info ? add_info : "", + add_info ? "\"" : "" + ); + zend_string_release_ex(fn, false); +} + /* {{{ timezone_process_timezone_argument - * TimeZone argument processor. outside_error may be NULL (for static functions/constructors) */ -U_CFUNC TimeZone *timezone_process_timezone_argument(zval *zv_timezone, - intl_error *outside_error, - const char *func) + * TimeZone argument processor. outside_error may be nullptr (for static functions/constructors) */ +U_CFUNC TimeZone *timezone_process_timezone_argument( + zend_object *timezone_object, zend_string *timezone_string, intl_error *outside_error, uint32_t arg_num) { - zval local_zv_tz; - TimeZone *timeZone; + std::unique_ptr timeZone; + bool free_string = false; - if (zv_timezone == NULL || Z_TYPE_P(zv_timezone) == IS_NULL) { + if (timezone_object == nullptr && timezone_string == nullptr) { timelib_tzinfo *tzinfo = get_timezone_info(); - ZVAL_STRING(&local_zv_tz, tzinfo->name); - zv_timezone = &local_zv_tz; - } else { - ZVAL_NULL(&local_zv_tz); + timezone_string = zend_string_init(tzinfo->name, strlen(tzinfo->name), false); + free_string = true; } - if (Z_TYPE_P(zv_timezone) == IS_OBJECT && - instanceof_function(Z_OBJCE_P(zv_timezone), TimeZone_ce_ptr)) { - TimeZone_object *to = Z_INTL_TIMEZONE_P(zv_timezone); - - if (to->utimezone == NULL) { - zend_throw_error(IntlException_ce_ptr, "%s: passed IntlTimeZone is not " - "properly constructed", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; - } - timeZone = to->utimezone->clone(); - if (UNEXPECTED(timeZone == NULL)) { - zend_throw_error(IntlException_ce_ptr, "%s: could not clone TimeZone", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; + if (timezone_object != nullptr) { + if (instanceof_function(timezone_object->ce, TimeZone_ce_ptr)) { + const TimeZone_object *to = php_intl_timezone_fetch_object(timezone_object); + + if (UNEXPECTED(to->utimezone == nullptr)) { + timezone_throw_exception_with_call_location( + "passed IntlTimeZone is not properly constructed",nullptr); + return nullptr; + } + timeZone = std::unique_ptr(to->utimezone->clone()); + if (UNEXPECTED(timeZone == nullptr)) { + timezone_throw_exception_with_call_location("could not clone TimeZone", nullptr); + return nullptr; + } + // well, this is included by the centralized C intl part so the "smart" part can't go further + return timeZone.release(); + } else if (instanceof_function(timezone_object->ce, php_date_get_timezone_ce())) { + php_timezone_obj *tz_obj = php_timezone_obj_from_obj(timezone_object); + + return timezone_convert_datetimezone(tz_obj->type, tz_obj, false, outside_error); + } else { + zval tmp; + zend_result status = timezone_object->handlers->cast_object(timezone_object, &tmp, IS_STRING); + if (EXPECTED(status == SUCCESS)) { + timezone_string = Z_STR(tmp); + free_string = true; + } else { + if (!EG(exception)) { + zend_argument_type_error(arg_num, + "Object of class %s could not be converted to string", + ZSTR_VAL(timezone_object->ce->name)); + } + return nullptr; + } } - } else if (Z_TYPE_P(zv_timezone) == IS_OBJECT && - instanceof_function(Z_OBJCE_P(zv_timezone), php_date_get_timezone_ce())) { + } - php_timezone_obj *tzobj = Z_PHPTIMEZONE_P(zv_timezone); + ZEND_ASSERT(timezone_string != nullptr); + UnicodeString id; + UErrorCode status = U_ZERO_ERROR; /* outside_error may be nullptr */ - zval_ptr_dtor_str(&local_zv_tz); - return timezone_convert_datetimezone(tzobj->type, tzobj, 0, - outside_error, func); - } else { - UnicodeString id; - UErrorCode status = U_ZERO_ERROR; /* outside_error may be NULL */ - if (!try_convert_to_string(zv_timezone)) { - zval_ptr_dtor_str(&local_zv_tz); - return NULL; - } - if (intl_stringFromChar(id, Z_STRVAL_P(zv_timezone), Z_STRLEN_P(zv_timezone), - &status) == FAILURE) { - zend_throw_error(IntlException_ce_ptr, "%s: Time zone identifier given is not a " - "valid UTF-8 string", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; + if (UNEXPECTED(intl_stringFromChar(id, ZSTR_VAL(timezone_string), ZSTR_LEN(timezone_string), &status) == FAILURE)) { + timezone_throw_exception_with_call_location("Time zone identifier given is not a valid UTF-8 string", nullptr); + if (free_string) { + zend_string_release_ex(timezone_string, false); } - timeZone = TimeZone::createTimeZone(id); - if (UNEXPECTED(timeZone == NULL)) { - zend_throw_error(IntlException_ce_ptr, "%s: Could not create time zone", func); - zval_ptr_dtor_str(&local_zv_tz); - return NULL; + return nullptr; + } + + timeZone = std::unique_ptr(TimeZone::createTimeZone(id)); + if (UNEXPECTED(timeZone == nullptr)) { + timezone_throw_exception_with_call_location("Could not create time zone",nullptr); + if (free_string) { + zend_string_release_ex(timezone_string, false); } - if (*timeZone == TimeZone::getUnknown()) { - zend_throw_error(IntlException_ce_ptr, "%s: No such time zone: '%s'", - func, Z_STRVAL_P(zv_timezone)); - zval_ptr_dtor_str(&local_zv_tz); - delete timeZone; - return NULL; + return nullptr; + } + if (UNEXPECTED(*timeZone == TimeZone::getUnknown())) { + timezone_throw_exception_with_call_location("No such time zone: ", ZSTR_VAL(timezone_string)); + if (free_string) { + zend_string_release_ex(timezone_string, false); } + return nullptr; } - - zval_ptr_dtor_str(&local_zv_tz); - - return timeZone; + if (free_string) { + zend_string_release_ex(timezone_string, false); + } + // well, this is included by the centralized C intl part so the "smart" part can't go further + return timeZone.release(); } /* }}} */ /* {{{ clone handler for TimeZone */ static zend_object *TimeZone_clone_obj(zend_object *object) { - TimeZone_object *to_orig = php_intl_timezone_fetch_object(object); + const TimeZone_object *to_orig = php_intl_timezone_fetch_object(object); zend_object *ret_val = TimeZone_ce_ptr->create_object(object->ce); TimeZone_object *to_new = php_intl_timezone_fetch_object(ret_val); @@ -356,7 +358,7 @@ U_CFUNC void timezone_register_IntlTimeZone_class(void) memcpy(&TimeZone_handlers, &std_object_handlers, sizeof TimeZone_handlers); - TimeZone_handlers.offset = XtOffsetOf(TimeZone_object, zo); + TimeZone_handlers.offset = offsetof(TimeZone_object, zo); TimeZone_handlers.clone_obj = TimeZone_clone_obj; TimeZone_handlers.compare = TimeZone_compare_objects; TimeZone_handlers.get_debug_info = TimeZone_get_debug_info; diff --git a/ext/intl/timezone/timezone_class.h b/ext/intl/timezone/timezone_class.h index 16d56b9af12d..a8a05395b406 100644 --- a/ext/intl/timezone/timezone_class.h +++ b/ext/intl/timezone/timezone_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -36,6 +36,8 @@ typedef struct { intl_error err; // ICU TimeZone + // TODO?: a direct change isn't possible due to C inclusion (also it s a const) + // but see later it can be made possible through different ICU class usages const TimeZone *utimezone; //whether to delete the timezone on object free @@ -45,7 +47,7 @@ typedef struct { } TimeZone_object; static inline TimeZone_object *php_intl_timezone_fetch_object(zend_object *obj) { - return (TimeZone_object *)((char*)(obj) - XtOffsetOf(TimeZone_object, zo)); + return ZEND_CONTAINER_OF(obj, TimeZone_object, zo); } #define Z_INTL_TIMEZONE_P(zv) php_intl_timezone_fetch_object(Z_OBJ_P(zv)) @@ -64,8 +66,8 @@ static inline TimeZone_object *php_intl_timezone_fetch_object(zend_object *obj) RETURN_THROWS(); \ } -zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, const char *func, zval *ret); -TimeZone *timezone_process_timezone_argument(zval *zv_timezone, intl_error *error, const char *func); +zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, zval *ret); +TimeZone *timezone_process_timezone_argument(zend_object *timezone_object, zend_string *timezone_string, intl_error *error, uint32_t arg_num); void timezone_object_construct(const TimeZone *zone, zval *object, int owned); diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp index 6ff0cf513779..29180f9caa2d 100644 --- a/ext/intl/timezone/timezone_methods.cpp +++ b/ext/intl/timezone/timezone_methods.cpp @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -60,7 +60,7 @@ U_CFUNC PHP_FUNCTION(intltz_create_time_zone) UnicodeString id = UnicodeString(); if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_NULL(); } @@ -82,14 +82,11 @@ U_CFUNC PHP_FUNCTION(intltz_from_date_time_zone) tzobj = Z_PHPTIMEZONE_P(zv_timezone); if (!tzobj->initialized) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "DateTimeZone object is unconstructed", - 0); - RETURN_NULL(); + zend_throw_error(NULL, "DateTimeZone object is unconstructed"); + RETURN_THROWS(); } - tz = timezone_convert_datetimezone(tzobj->type, tzobj, false, NULL, - "intltz_from_date_time_zone"); + tz = timezone_convert_datetimezone(tzobj->type, tzobj, false, NULL); if (tz == NULL) { RETURN_NULL(); } @@ -127,62 +124,36 @@ U_CFUNC PHP_FUNCTION(intltz_get_unknown) U_CFUNC PHP_FUNCTION(intltz_create_enumeration) { - zval *arg = NULL; - StringEnumeration *se = NULL; - intl_error_reset(NULL); + zend_string *timezone = nullptr; + zend_long timezone_shift = 0; + bool is_null = true; + StringEnumeration *se = nullptr; + intl_error_reset(nullptr); /* double indirection to have the zend engine destroy the new zval that * results from separation */ ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(arg) + Z_PARAM_STR_OR_LONG_OR_NULL(timezone, timezone_shift, is_null) ZEND_PARSE_PARAMETERS_END(); - if (arg == NULL || Z_TYPE_P(arg) == IS_NULL) { + if (is_null) { se = TimeZone::createEnumeration(); - } else if (Z_TYPE_P(arg) == IS_LONG) { -int_offset: - if (UNEXPECTED(Z_LVAL_P(arg) < (zend_long)INT32_MIN || - Z_LVAL_P(arg) > (zend_long)INT32_MAX)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "value is out of range", 0); - RETURN_FALSE; - } else { - se = TimeZone::createEnumeration((int32_t) Z_LVAL_P(arg)); - } - } else if (Z_TYPE_P(arg) == IS_DOUBLE) { -double_offset: - convert_to_long(arg); - goto int_offset; - } else if (Z_TYPE_P(arg) == IS_OBJECT || Z_TYPE_P(arg) == IS_STRING) { - zend_long lval; - double dval; - if (!try_convert_to_string(arg)) { + } else if (timezone != nullptr) { + se = TimeZone::createEnumeration(ZSTR_VAL(timezone)); + } else { + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(timezone_shift))) { + zend_argument_value_error(1, "must be between %d and %d", INT32_MIN, INT32_MAX); RETURN_THROWS(); } - switch (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &lval, &dval, 0)) { - case IS_DOUBLE: - zval_ptr_dtor(arg); - ZVAL_DOUBLE(arg, dval); - goto double_offset; - case IS_LONG: - zval_ptr_dtor(arg); - ZVAL_LONG(arg, lval); - goto int_offset; - } - /* else call string version */ - se = TimeZone::createEnumeration(Z_STRVAL_P(arg)); - } else { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "invalid argument type", 0); - RETURN_FALSE; + se = TimeZone::createEnumeration(static_cast(timezone_shift)); } if (se) { IntlIterator_from_StringEnumeration(se, return_value); } else { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "error obtaining enumeration", 0); + intl_error_set(nullptr, U_ILLEGAL_ARGUMENT_ERROR, + "error obtaining enumeration"); RETVAL_FALSE; } } @@ -201,7 +172,7 @@ U_CFUNC PHP_FUNCTION(intltz_count_equivalent_ids) UnicodeString id = UnicodeString(); if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -230,18 +201,17 @@ U_CFUNC PHP_FUNCTION(intltz_create_time_zone_id_enumeration) if (zoneType != UCAL_ZONE_TYPE_ANY && zoneType != UCAL_ZONE_TYPE_CANONICAL && zoneType != UCAL_ZONE_TYPE_CANONICAL_LOCATION) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "bad zone type", 0); - RETURN_FALSE; + zend_argument_value_error(1, "must be one of IntlTimeZone::TYPE_ANY," + " IntlTimeZone::TYPE_CANONICAL, or IntlTimeZone::TYPE_CANONICAL_LOCATION"); + RETURN_THROWS(); } if (!arg3isnull) { - if (UNEXPECTED(offset_arg < (zend_long)INT32_MIN || offset_arg > (zend_long)INT32_MAX)) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "offset out of bounds", 0); - RETURN_FALSE; + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(offset_arg))) { + zend_argument_value_error(3, "must be between %d and %d", INT32_MIN, INT32_MAX); + RETURN_THROWS(); } - offset = (int32_t)offset_arg; + offset = static_cast(offset_arg); offsetp = &offset; } //else leave offsetp NULL @@ -271,7 +241,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_canonical_id) UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -305,7 +275,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_region) UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -340,15 +310,16 @@ U_CFUNC PHP_FUNCTION(intltz_get_equivalent_id) Z_PARAM_LONG(index) ZEND_PARSE_PARAMETERS_END(); - if (UNEXPECTED(index < (zend_long)INT32_MIN || index > (zend_long)INT32_MAX)) { - RETURN_FALSE; + if (UNEXPECTED(ZEND_LONG_EXCEEDS_INT(index))) { + zend_argument_value_error(2, "must be between %d and %d", INT32_MIN, INT32_MAX); + RETURN_THROWS(); } UErrorCode status = UErrorCode(); UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -375,7 +346,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_iana_id) UnicodeString id; if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) { intl_error_set(NULL, status, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -484,8 +455,7 @@ U_CFUNC PHP_FUNCTION(intltz_has_same_rules) TIMEZONE_METHOD_FETCH_OBJECT; other_to = Z_INTL_TIMEZONE_P(other_object); if (other_to->utimezone == NULL) { - intl_errors_set(&to->err, U_ILLEGAL_ARGUMENT_ERROR, - "The second IntlTimeZone is unconstructed", 0); + intl_errors_set(&to->err, U_ILLEGAL_ARGUMENT_ERROR, "The second IntlTimeZone is unconstructed"); RETURN_FALSE; } @@ -519,8 +489,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_display_name) found = true; } if (!found) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "wrong display type", 0); + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "wrong display type"); RETURN_FALSE; } @@ -567,7 +536,7 @@ U_CFUNC PHP_FUNCTION(intltz_to_date_time_zone) TIMEZONE_METHOD_FETCH_OBJECT; zval *ret = timezone_convert_to_datetimezone(to->utimezone, - &TIMEZONE_ERROR(to), "intltz_to_date_time_zone", &tmp); + &TIMEZONE_ERROR(to), &tmp); if (ret) { ZVAL_COPY_VALUE(return_value, ret); @@ -630,16 +599,16 @@ U_CFUNC PHP_FUNCTION(intltz_get_windows_id) error = U_ZERO_ERROR; if (intl_stringFromChar(uID, id->val, id->len, &error) == FAILURE) { intl_error_set(NULL, error, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } error = U_ZERO_ERROR; TimeZone::getWindowsID(uID, uWinID, error); - INTL_CHECK_STATUS(error, "intltz_get_windows_id: Unable to get timezone from windows ID"); + INTL_CHECK_STATUS(error, "Unable to get timezone from windows ID"); if (uWinID.length() == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "unknown system timezone", 0); + "unknown system timezone"); RETURN_FALSE; } @@ -668,7 +637,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_id_for_windows_id) error = U_ZERO_ERROR; if (intl_stringFromChar(uWinID, winID->val, winID->len, &error) == FAILURE) { intl_error_set(NULL, error, - "could not convert time zone id to UTF-16", 0); + "could not convert time zone id to UTF-16"); RETURN_FALSE; } @@ -677,7 +646,7 @@ U_CFUNC PHP_FUNCTION(intltz_get_id_for_windows_id) INTL_CHECK_STATUS(error, "unable to get windows ID for timezone"); if (uID.length() == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "unknown windows timezone", 0); + "unknown windows timezone"); RETURN_FALSE; } diff --git a/ext/intl/transliterator/transliterator.h b/ext/intl/transliterator/transliterator.h index f98ca0682965..2a86eb6781be 100644 --- a/ext/intl/transliterator/transliterator.h +++ b/ext/intl/transliterator/transliterator.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/intl/transliterator/transliterator_arginfo.h b/ext/intl/transliterator/transliterator_arginfo.h index 6f74b55521df..2d9e80708d19 100644 --- a/ext/intl/transliterator/transliterator_arginfo.h +++ b/ext/intl/transliterator/transliterator_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit transliterator.stub.php instead. * Stub hash: 300bcc64e5ddaf469bfe4a12e65a6677bf2aea88 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Transliterator___construct, 0, 0, 0) @@ -62,21 +62,21 @@ static zend_class_entry *register_class_Transliterator(void) zval const_FORWARD_value; ZVAL_LONG(&const_FORWARD_value, TRANSLITERATOR_FORWARD); - zend_string *const_FORWARD_name = zend_string_init_interned("FORWARD", sizeof("FORWARD") - 1, 1); + zend_string *const_FORWARD_name = zend_string_init_interned("FORWARD", sizeof("FORWARD") - 1, true); zend_declare_typed_class_constant(class_entry, const_FORWARD_name, &const_FORWARD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FORWARD_name); + zend_string_release_ex(const_FORWARD_name, true); zval const_REVERSE_value; ZVAL_LONG(&const_REVERSE_value, TRANSLITERATOR_REVERSE); - zend_string *const_REVERSE_name = zend_string_init_interned("REVERSE", sizeof("REVERSE") - 1, 1); + zend_string *const_REVERSE_name = zend_string_init_interned("REVERSE", sizeof("REVERSE") - 1, true); zend_declare_typed_class_constant(class_entry, const_REVERSE_name, &const_REVERSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REVERSE_name); + zend_string_release_ex(const_REVERSE_name, true); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); - zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_id_name); + zend_string_release_ex(property_id_name, true); return class_entry; } diff --git a/ext/intl/transliterator/transliterator_class.c b/ext/intl/transliterator/transliterator_class.c deleted file mode 100644 index 438b71c2c417..000000000000 --- a/ext/intl/transliterator/transliterator_class.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Gustavo Lopes | - +----------------------------------------------------------------------+ - */ - -#include "transliterator_class.h" -#include "php_intl.h" -#include "transliterator_arginfo.h" -#include "intl_error.h" -#include "intl_convert.h" -#include "intl_data.h" - -#include - -zend_class_entry *Transliterator_ce_ptr = NULL; - -zend_object_handlers Transliterator_handlers; - -/* {{{ int transliterator_object_construct( zval *object, UTransliterator *utrans, UErrorCode *status ) - * Initialize internals of Transliterator_object. - */ -int transliterator_object_construct( zval *object, - UTransliterator *utrans, - UErrorCode *status ) -{ - const UChar *ustr_id; - int32_t ustr_id_len; - zend_string *u8str; - zval tmp; - Transliterator_object *to; - - TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; - - assert( to->utrans == NULL ); - /* this assignment must happen before any return with failure because the - * caller relies on it always being made (so it can just destroy the object - * to close the transliterator) */ - to->utrans = utrans; - - ustr_id = utrans_getUnicodeID( utrans, &ustr_id_len ); - u8str = intl_convert_utf16_to_utf8(ustr_id, (int ) ustr_id_len, status ); - if( !u8str ) - { - return FAILURE; - } - - ZVAL_NEW_STR(&tmp, u8str); - zend_update_property(Transliterator_ce_ptr, Z_OBJ_P(object), - "id", sizeof( "id" ) - 1, &tmp ); - GC_DELREF(u8str); - return SUCCESS; -} -/* }}} */ - -/* - * Auxiliary functions needed by objects of 'Transliterator' class - */ - -/* {{{ void transliterator_object_init( Transliterator_object* to ) - * Initialize internals of Transliterator_object. - */ -static void transliterator_object_init( Transliterator_object* to ) -{ - if( !to ) - return; - - intl_error_init( TRANSLITERATOR_ERROR_P( to ) ); -} -/* }}} */ - -/* {{{ void transliterator_object_destroy( Transliterator_object* to ) - * Clean up mem allocted by internals of Transliterator_object - */ -static void transliterator_object_destroy( Transliterator_object* to ) -{ - if( !to ) - return; - - if( to->utrans ) - { - utrans_close( to->utrans ); - to->utrans = NULL; - } - - intl_error_reset( TRANSLITERATOR_ERROR_P( to ) ); -} -/* }}} */ - -/* {{{ Transliterator_objects_free */ -static void Transliterator_objects_free( zend_object *object ) -{ - Transliterator_object* to = php_intl_transliterator_fetch_object(object); - - zend_object_std_dtor( &to->zo ); - - transliterator_object_destroy( to ); -} -/* }}} */ - -/* {{{ Transliterator_object_create */ -static zend_object *Transliterator_object_create( zend_class_entry *ce ) -{ - Transliterator_object* intern; - - intern = zend_object_alloc(sizeof(Transliterator_object), ce); - - zend_object_std_init( &intern->zo, ce ); - object_properties_init( &intern->zo, ce ); - transliterator_object_init( intern ); - - return &intern->zo; -} -/* }}} */ - -/* - * Object handlers for Transliterator class (and subclasses) - */ - -/* {{{ clone handler for Transliterator */ -static zend_object *Transliterator_clone_obj( zend_object *object ) -{ - Transliterator_object *to_orig = php_intl_transliterator_fetch_object(object); - zend_object *ret_val = Transliterator_ce_ptr->create_object(object->ce); - Transliterator_object *to_new = php_intl_transliterator_fetch_object(ret_val); - - zend_objects_clone_members( &to_new->zo, &to_orig->zo ); - if (to_orig->utrans != NULL) { - /* guaranteed to return NULL if it fails */ - UErrorCode error = U_ZERO_ERROR; - UTransliterator *utrans = utrans_clone( to_orig->utrans, &error); - - if (U_FAILURE(error)) { - if (utrans != NULL) { - transliterator_object_destroy(to_new); - } - zend_throw_error(NULL, "Failed to clone Transliterator"); - } else { - to_new->utrans = utrans; - } - } else { - /* We shouldn't have unconstructed objects in the first place */ - zend_throw_error(NULL, "Cannot clone uninitialized Transliterator"); - } - - return ret_val; -} -/* }}} */ - -/* {{{ transliterator_register_Transliterator_class - * Initialize 'Transliterator' class - */ -void transliterator_register_Transliterator_class( void ) -{ - /* Create and register 'Transliterator' class. */ - Transliterator_ce_ptr = register_class_Transliterator(); - Transliterator_ce_ptr->create_object = Transliterator_object_create; - Transliterator_ce_ptr->default_object_handlers = &Transliterator_handlers; - memcpy( &Transliterator_handlers, &std_object_handlers, sizeof Transliterator_handlers ); - Transliterator_handlers.offset = XtOffsetOf(Transliterator_object, zo); - Transliterator_handlers.free_obj = Transliterator_objects_free; - Transliterator_handlers.clone_obj = Transliterator_clone_obj; -} -/* }}} */ diff --git a/ext/intl/transliterator/transliterator_class.cpp b/ext/intl/transliterator/transliterator_class.cpp new file mode 100644 index 000000000000..737c51fcf4dd --- /dev/null +++ b/ext/intl/transliterator/transliterator_class.cpp @@ -0,0 +1,174 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + +#include "transliterator_class.h" +extern "C" { +#include "php_intl.h" +#include "intl_error.h" +#include "intl_convert.h" +#include "intl_data.h" +#include "transliterator_arginfo.h" +} + +#include + +zend_class_entry *Transliterator_ce_ptr = nullptr; + +zend_object_handlers Transliterator_handlers; + +/* {{{ int transliterator_object_construct( zval *object, UTransliterator *utrans, UErrorCode *status ) + * Initialize internals of Transliterator_object. + */ +U_CFUNC int transliterator_object_construct( zval *object, + UTransliterator *utrans, + UErrorCode *status ) +{ + const UChar *ustr_id; + int32_t ustr_id_len; + zend_string *u8str; + zval tmp; + Transliterator_object *to; + + TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; + + assert( to->utrans == nullptr ); + /* this assignment must happen before any return with failure because the + * caller relies on it always being made (so it can just destroy the object + * to close the transliterator) */ + to->utrans = utrans; + + ustr_id = utrans_getUnicodeID( utrans, &ustr_id_len ); + u8str = intl_convert_utf16_to_utf8(ustr_id, (int ) ustr_id_len, status ); + if( !u8str ) + { + return FAILURE; + } + + ZVAL_NEW_STR(&tmp, u8str); + zend_update_property(Transliterator_ce_ptr, Z_OBJ_P(object), + "id", sizeof( "id" ) - 1, &tmp ); + GC_DELREF(u8str); + return SUCCESS; +} +/* }}} */ + +/* + * Auxiliary functions needed by objects of 'Transliterator' class + */ + +/* {{{ void transliterator_object_init( Transliterator_object* to ) + * Initialize internals of Transliterator_object. + */ +static void transliterator_object_init( Transliterator_object* to ) +{ + if( !to ) + return; + + intl_error_init( TRANSLITERATOR_ERROR_P( to ) ); +} +/* }}} */ + +/* {{{ void transliterator_object_destroy( Transliterator_object* to ) + * Clean up mem allocated by internals of Transliterator_object + */ +static void transliterator_object_destroy( Transliterator_object* to ) +{ + if( !to ) + return; + + if( to->utrans ) + { + utrans_close( to->utrans ); + to->utrans = nullptr; + } + + intl_error_reset( TRANSLITERATOR_ERROR_P( to ) ); +} +/* }}} */ + +/* {{{ Transliterator_objects_free */ +static void Transliterator_objects_free( zend_object *object ) +{ + Transliterator_object* to = php_intl_transliterator_fetch_object(object); + + zend_object_std_dtor( &to->zo ); + + transliterator_object_destroy( to ); +} +/* }}} */ + +/* {{{ Transliterator_object_create */ +static zend_object *Transliterator_object_create( zend_class_entry *ce ) +{ + Transliterator_object* intern; + + intern = reinterpret_cast(zend_object_alloc(sizeof(Transliterator_object), ce)); + + zend_object_std_init( &intern->zo, ce ); + object_properties_init( &intern->zo, ce ); + transliterator_object_init( intern ); + + return &intern->zo; +} +/* }}} */ + +/* + * Object handlers for Transliterator class (and subclasses) + */ + +/* {{{ clone handler for Transliterator */ +static zend_object *Transliterator_clone_obj( zend_object *object ) +{ + const Transliterator_object *to_orig = php_intl_transliterator_fetch_object(object); + zend_object *ret_val = Transliterator_ce_ptr->create_object(object->ce); + Transliterator_object *to_new = php_intl_transliterator_fetch_object(ret_val); + + zend_objects_clone_members( &to_new->zo, &to_orig->zo ); + if (to_orig->utrans != nullptr) { + /* guaranteed to return nullptr if it fails */ + UErrorCode error = U_ZERO_ERROR; + UTransliterator *utrans = utrans_clone( to_orig->utrans, &error); + + if (U_FAILURE(error)) { + if (utrans != nullptr) { + transliterator_object_destroy(to_new); + } + zend_throw_error(nullptr, "Failed to clone Transliterator"); + } else { + to_new->utrans = utrans; + } + } else { + /* We shouldn't have unconstructed objects in the first place */ + zend_throw_error(nullptr, "Cannot clone uninitialized Transliterator"); + } + + return ret_val; +} +/* }}} */ + +/* {{{ transliterator_register_Transliterator_class + * Initialize 'Transliterator' class + */ +U_CFUNC void transliterator_register_Transliterator_class( void ) +{ + /* Create and register 'Transliterator' class. */ + Transliterator_ce_ptr = register_class_Transliterator(); + Transliterator_ce_ptr->create_object = Transliterator_object_create; + Transliterator_ce_ptr->default_object_handlers = &Transliterator_handlers; + memcpy( &Transliterator_handlers, &std_object_handlers, sizeof Transliterator_handlers ); + Transliterator_handlers.offset = offsetof(Transliterator_object, zo); + Transliterator_handlers.free_obj = Transliterator_objects_free; + Transliterator_handlers.clone_obj = Transliterator_clone_obj; +} +/* }}} */ diff --git a/ext/intl/transliterator/transliterator_class.h b/ext/intl/transliterator/transliterator_class.h index 2ce85d6cfdb7..e94758996e55 100644 --- a/ext/intl/transliterator/transliterator_class.h +++ b/ext/intl/transliterator/transliterator_class.h @@ -1,12 +1,12 @@ /* +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -17,8 +17,14 @@ #include +#ifdef __cplusplus +extern "C" { +#endif #include "intl_common.h" #include "intl_error.h" +#ifdef __cplusplus +} +#endif #include @@ -33,7 +39,7 @@ typedef struct { } Transliterator_object; static inline Transliterator_object *php_intl_transliterator_fetch_object(zend_object *obj) { - return (Transliterator_object *)((char*)(obj) - XtOffsetOf(Transliterator_object, zo)); + return ZEND_CONTAINER_OF(obj, Transliterator_object, zo); } #define Z_INTL_TRANSLITERATOR_P(zv) php_intl_transliterator_fetch_object(Z_OBJ_P(zv)) @@ -56,6 +62,9 @@ static inline Transliterator_object *php_intl_transliterator_fetch_object(zend_o RETURN_THROWS(); \ } +#ifdef __cplusplus +extern "C" { +#endif int transliterator_object_construct( zval *object, UTransliterator *utrans, UErrorCode *status ); @@ -64,5 +73,8 @@ void transliterator_register_Transliterator_class( void ); extern zend_class_entry *Transliterator_ce_ptr; extern zend_object_handlers Transliterator_handlers; +#ifdef __cplusplus +} +#endif #endif /* #ifndef TRANSLITERATOR_CLASS_H */ diff --git a/ext/intl/transliterator/transliterator_methods.c b/ext/intl/transliterator/transliterator_methods.c deleted file mode 100644 index ff3ddf516137..000000000000 --- a/ext/intl/transliterator/transliterator_methods.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Gustavo Lopes | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "php_intl.h" -#include "transliterator.h" -#include "transliterator_class.h" -#include "intl_data.h" -#include "intl_convert.h" - -#include - -static int create_transliterator( char *str_id, size_t str_id_len, zend_long direction, zval *object ) -{ - Transliterator_object *to; - UChar *ustr_id = NULL; - int32_t ustr_id_len = 0; - UTransliterator *utrans; - UParseError parse_error; - - intl_error_reset( NULL ); - - if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) - { - zend_argument_value_error(2, "must be either Transliterator::FORWARD or Transliterator::REVERSE"); - return FAILURE; - } - - object_init_ex( object, Transliterator_ce_ptr ); - TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; /* fetch zend object from zval "object" into "to" */ - - /* Convert transliterator id to UTF-16 */ - intl_convert_utf8_to_utf16( &ustr_id, &ustr_id_len, str_id, str_id_len, TRANSLITERATOR_ERROR_CODE_P( to ) ); - if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) - { - intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - intl_error_set_custom_msg( NULL, "String conversion of id to UTF-16 failed", 0 ); - zval_ptr_dtor( object ); - return FAILURE; - } - - /* Open ICU Transliterator. */ - utrans = utrans_openU( ustr_id, ustr_id_len, (UTransDirection ) direction, - NULL, -1, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) ); - if (ustr_id) { - efree( ustr_id ); - } - - if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) - { - char *buf = NULL; - intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - spprintf( &buf, 0, "transliterator_create: unable to open ICU transliterator" - " with id \"%s\"", str_id ); - if( buf == NULL ) { - intl_error_set_custom_msg( NULL, - "transliterator_create: unable to open ICU transliterator", 0 ); - } - else - { - intl_error_set_custom_msg( NULL, buf, /* copy message */ 1 ); - efree( buf ); - } - zval_ptr_dtor( object ); - return FAILURE; - } - - transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); - /* no need to close the transliterator manually on construction error */ - if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) - { - intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - intl_error_set_custom_msg( NULL, - "transliterator_create: internal constructor call failed", 0 ); - zval_ptr_dtor( object ); - return FAILURE; - } - - return SUCCESS; -} - -/* {{{ Opens a transliterator by id. */ -PHP_FUNCTION( transliterator_create ) -{ - char *str_id; - size_t str_id_len; - zend_long direction = TRANSLITERATOR_FORWARD; - int res; - - TRANSLITERATOR_METHOD_INIT_VARS; - - (void) to; /* unused */ - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(str_id, str_id_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(direction) - ZEND_PARSE_PARAMETERS_END(); - - object = return_value; - res = create_transliterator( str_id, str_id_len, direction, object ); - if( res == FAILURE ) - RETURN_NULL(); - - /* success, leave return_value as it is (set by create_transliterator) */ -} -/* }}} */ - -/* {{{ Opens a transliterator by id. */ -PHP_FUNCTION( transliterator_create_from_rules ) -{ - char *str_rules; - size_t str_rules_len; - UChar *ustr_rules = NULL; - int32_t ustr_rules_len = 0; - zend_long direction = TRANSLITERATOR_FORWARD; - UParseError parse_error; - UTransliterator *utrans; - UChar id[] = {0x52, 0x75, 0x6C, 0x65, 0x73, 0x54, 0x72, - 0x61, 0x6E, 0x73, 0x50, 0x48, 0x50, 0}; /* RulesTransPHP */ - TRANSLITERATOR_METHOD_INIT_VARS; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(str_rules, str_rules_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(direction) - ZEND_PARSE_PARAMETERS_END(); - - if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) - { - zend_argument_value_error(2, "must be either Transliterator::FORWARD or Transliterator::REVERSE"); - RETURN_THROWS(); - } - - object = return_value; - object_init_ex( object, Transliterator_ce_ptr ); - TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; - - intl_convert_utf8_to_utf16( &ustr_rules, &ustr_rules_len, - str_rules, str_rules_len, TRANSLITERATOR_ERROR_CODE_P( to ) ); - /* (I'm not a big fan of non-obvious flow control macros ). - * This one checks the error value, destroys object and returns false */ - INTL_METHOD_CHECK_STATUS_OR_NULL( to, "String conversion of rules to UTF-16 failed" ); - - /* Open ICU Transliterator. */ - utrans = utrans_openU( id, ( sizeof( id ) - 1 ) / ( sizeof( *id ) ), (UTransDirection ) direction, - ustr_rules, ustr_rules_len, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) ); - if (ustr_rules) { - efree( ustr_rules ); - } - - intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( to ) ); - if( U_FAILURE( INTL_DATA_ERROR_CODE( to ) ) ) - { - char *msg = NULL; - smart_str parse_error_str; - parse_error_str = intl_parse_error_to_string( &parse_error ); - spprintf( &msg, 0, "transliterator_create_from_rules: unable to " - "create ICU transliterator from rules (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "" ); - smart_str_free( &parse_error_str ); - if( msg != NULL ) - { - intl_errors_set_custom_msg( INTL_DATA_ERROR_P( to ), msg, 1 ); - efree( msg ); - } - zval_ptr_dtor( return_value ); - RETURN_NULL(); - } - transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); - /* no need to close the transliterator manually on construction error */ - INTL_METHOD_CHECK_STATUS_OR_NULL( to, "transliterator_create_from_rules: internal constructor call failed" ); -} -/* }}} */ - -/* {{{ Opens the inverse transliterator transliterator. */ -PHP_FUNCTION( transliterator_create_inverse ) -{ - Transliterator_object *to_orig; - UTransliterator *utrans; - TRANSLITERATOR_METHOD_INIT_VARS; - - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, Transliterator_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - TRANSLITERATOR_METHOD_FETCH_OBJECT; - to_orig = to; - - object = return_value; - object_init_ex( object, Transliterator_ce_ptr ); - TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; /* change "to" into new object (from "object" ) */ - - utrans = utrans_openInverse( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); - INTL_METHOD_CHECK_STATUS_OR_NULL( to, "transliterator_create_inverse: could not create " - "inverse ICU transliterator" ); - transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); - /* no need to close the transliterator manually on construction error */ - INTL_METHOD_CHECK_STATUS_OR_NULL( to, "transliterator_create: internal constructor call failed" ); -} -/* }}} */ - -/* {{{ Return an array with the registered transliterator IDs. */ -PHP_FUNCTION( transliterator_list_ids ) -{ - UEnumeration *en; - const UChar *elem; - int32_t elem_len; - UErrorCode status = U_ZERO_ERROR; - - intl_error_reset( NULL ); - - ZEND_PARSE_PARAMETERS_NONE(); - - en = utrans_openIDs( &status ); - INTL_CHECK_STATUS( status, - "transliterator_list_ids: Failed to obtain registered transliterators" ); - - array_init( return_value ); - while( (elem = uenum_unext( en, &elem_len, &status )) ) - { - zend_string *el = intl_convert_utf16_to_utf8(elem, elem_len, &status ); - - if( !el ) - { - break; - } - else - { - add_next_index_str( return_value, el); - } - } - uenum_close( en ); - - intl_error_set_code( NULL, status ); - if( U_FAILURE( status ) ) - { - zend_array_destroy( Z_ARR_P(return_value) ); - RETVAL_FALSE; - intl_error_set_custom_msg( NULL, "transliterator_list_ids: " - "Failed to build array of registered transliterators", 0 ); - } -} -/* }}} */ - -/* {{{ Transliterate a string. */ -PHP_FUNCTION( transliterator_transliterate ) -{ - char *str; - UChar *ustr = NULL, - *uresult = NULL; - size_t str_len; - int32_t ustr_len = 0, - capacity, - uresult_len; - zend_long start = 0, - limit = -1; - int success = 0; - zval tmp_object; - TRANSLITERATOR_METHOD_INIT_VARS; - - object = getThis(); - - ZVAL_UNDEF(&tmp_object); - - if (object == NULL) { - /* in non-OOP version, accept both a transliterator and a string */ - zend_string *arg1_str; - zend_object *arg1_obj; - - ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_OBJ_OF_CLASS_OR_STR(arg1_obj, Transliterator_ce_ptr, arg1_str) - Z_PARAM_STRING(str, str_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(start) - Z_PARAM_LONG(limit) - ZEND_PARSE_PARAMETERS_END(); - - if (arg1_str) { /* not a transliterator object as first argument */ - int res; - object = &tmp_object; - res = create_transliterator(ZSTR_VAL(arg1_str), ZSTR_LEN(arg1_str), TRANSLITERATOR_FORWARD, object); - if( res == FAILURE ) - { - if (!EG(exception)) { - zend_string *message = intl_error_get_message( NULL ); - php_error_docref(NULL, E_WARNING, "Could not create transliterator with ID \"%s\" (%s)", ZSTR_VAL(arg1_str), ZSTR_VAL(message) ); - zend_string_free( message ); - } - ZVAL_UNDEF(&tmp_object); - /* don't set U_ILLEGAL_ARGUMENT_ERROR to allow fetching of inner error */ - goto cleanup; - } - } else { - ZVAL_OBJ_COPY(&tmp_object, arg1_obj); - object = &tmp_object; - } - } else if(zend_parse_parameters( ZEND_NUM_ARGS(), "s|ll", &str, &str_len, &start, &limit) == FAILURE) { - RETURN_THROWS(); - } - - if (limit < -1) { - zend_argument_value_error(object ? 3 : 4, "must be greater than or equal to -1"); - goto cleanup_object; - } - - if (start < 0) { - zend_argument_value_error(object ? 2 : 3, "must be greater than or equal to 0"); - goto cleanup_object; - } - - if (limit != -1 && start > limit) { - zend_argument_value_error(object ? 2 : 3, "must be less than or equal to argument #%d ($end)", object ? 3 : 4); - goto cleanup_object; - } - - /* end argument parsing/validation */ - - TRANSLITERATOR_METHOD_FETCH_OBJECT; - - intl_convert_utf8_to_utf16(&ustr, &ustr_len, str, str_len, TRANSLITERATOR_ERROR_CODE_P(to)); - INTL_METHOD_CHECK_STATUS_OR_GOTO(to, "String conversion of string to UTF-16 failed", cleanup_object); - - /* we've started allocating resources, goto from now on */ - - if( ( start > ustr_len ) || (( limit != -1 ) && (limit > ustr_len ) ) ) - { - char *msg; - spprintf( &msg, 0, - "transliterator_transliterate: Neither \"start\" nor the \"end\" " - "arguments can exceed the number of UTF-16 code units " - "(in this case, %d)", (int) ustr_len ); - if(msg != NULL ) - { - intl_errors_set( TRANSLITERATOR_ERROR_P( to ), U_ILLEGAL_ARGUMENT_ERROR, - msg, 1 ); - efree( msg ); - } - goto cleanup; - } - - uresult = safe_emalloc( ustr_len, sizeof( UChar ), 1 * sizeof( UChar ) ); - capacity = ustr_len + 1; - - while( 1 ) - { - int32_t temp_limit = ( limit == -1 ? ustr_len : (int32_t) limit ); - memcpy( uresult, ustr, ustr_len * sizeof( UChar ) ); - uresult_len = ustr_len; - - utrans_transUChars( to->utrans, uresult, &uresult_len, capacity, (int32_t) start, - &temp_limit, TRANSLITERATOR_ERROR_CODE_P( to ) ); - if( TRANSLITERATOR_ERROR_CODE( to ) == U_BUFFER_OVERFLOW_ERROR ) - { - efree( uresult ); - - uresult = safe_emalloc( uresult_len, sizeof( UChar ), 1 * sizeof( UChar ) ); - capacity = uresult_len + 1; - - intl_error_reset( TRANSLITERATOR_ERROR_P( to ) ); - } - else if(TRANSLITERATOR_ERROR_CODE( to ) == U_STRING_NOT_TERMINATED_WARNING ) - { - uresult = safe_erealloc( uresult, uresult_len, sizeof( UChar ), 1 * sizeof( UChar ) ); - - intl_error_reset( TRANSLITERATOR_ERROR_P( to ) ); - break; - } - else if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) - { - intl_error_set_code( NULL, TRANSLITERATOR_ERROR_CODE( to ) ); - intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to ), - "transliterator_transliterate: transliteration failed", 0 ); - goto cleanup; - } - else - break; - } - - uresult[uresult_len] = (UChar) 0; - - success = 1; - -cleanup: - if( ustr ) - efree( ustr ); - - if( success ) { - /* frees uresult even on error */ - INTL_METHOD_RETVAL_UTF8( to, uresult, uresult_len, 1 ); - } - else - { - if( uresult ) - efree( uresult ); - RETVAL_FALSE; - } - -cleanup_object: - zval_ptr_dtor( &tmp_object ); -} -/* }}} */ - -PHP_METHOD( Transliterator, __construct ) -{ - /* this constructor shouldn't be called as it's private */ - zend_throw_exception( NULL, - "An object of this type cannot be created with the new operator.", - 0 ); -} - -/* {{{ Get the last error code for this transliterator. */ -PHP_FUNCTION( transliterator_get_error_code ) -{ - TRANSLITERATOR_METHOD_INIT_VARS - - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, Transliterator_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - /* Fetch the object (without resetting its last error code ). */ - to = Z_INTL_TRANSLITERATOR_P( object ); - - RETURN_LONG( (zend_long) TRANSLITERATOR_ERROR_CODE( to ) ); -} -/* }}} */ - - -/* {{{ Get the last error message for this transliterator. */ -PHP_FUNCTION( transliterator_get_error_message ) -{ - zend_string* message = NULL; - TRANSLITERATOR_METHOD_INIT_VARS - - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", - &object, Transliterator_ce_ptr ) == FAILURE ) - { - RETURN_THROWS(); - } - - - /* Fetch the object (without resetting its last error code ). */ - to = Z_INTL_TRANSLITERATOR_P( object ); - - /* Return last error message. */ - message = intl_error_get_message( TRANSLITERATOR_ERROR_P( to ) ); - RETURN_STR( message ); -} -/* }}} */ diff --git a/ext/intl/transliterator/transliterator_methods.cpp b/ext/intl/transliterator/transliterator_methods.cpp new file mode 100644 index 000000000000..2dce4612e7a2 --- /dev/null +++ b/ext/intl/transliterator/transliterator_methods.cpp @@ -0,0 +1,469 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if __cplusplus >= 201703L +#include +#include +#endif + +extern "C" { +#include "php_intl.h" +#include "intl_data.h" +#include "intl_convert.h" +} +#include "transliterator.h" +#include "transliterator_class.h" + +#include + +static int create_transliterator( char *str_id, size_t str_id_len, zend_long direction, zval *object ) +{ + Transliterator_object *to; + UChar *ustr_id = nullptr; + int32_t ustr_id_len = 0; + UTransliterator *utrans; + UParseError parse_error; + + intl_error_reset( nullptr ); + + if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) + { + zend_argument_value_error(2, "must be either Transliterator::FORWARD or Transliterator::REVERSE"); + return FAILURE; + } + + object_init_ex( object, Transliterator_ce_ptr ); + TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; /* fetch zend object from zval "object" into "to" */ + + /* Convert transliterator id to UTF-16 */ + intl_convert_utf8_to_utf16( &ustr_id, &ustr_id_len, str_id, str_id_len, TRANSLITERATOR_ERROR_CODE_P( to ) ); + if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) + { + intl_error_set_code( nullptr, TRANSLITERATOR_ERROR_CODE( to ) ); + intl_error_set_custom_msg( nullptr, "String conversion of id to UTF-16 failed"); + zval_ptr_dtor( object ); + return FAILURE; + } + + /* Open ICU Transliterator. */ + utrans = utrans_openU( ustr_id, ustr_id_len, (UTransDirection ) direction, + nullptr, -1, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) ); + if (ustr_id) { + efree( ustr_id ); + } + + if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) + { + char *buf = nullptr; + intl_error_set_code( nullptr, TRANSLITERATOR_ERROR_CODE( to ) ); + spprintf( &buf, 0, "unable to open ICU transliterator" + " with id \"%s\"", str_id ); + if( buf == nullptr ) { + intl_error_set_custom_msg(nullptr, "unable to open ICU transliterator"); + } + else + { + intl_error_set_custom_msg(nullptr, buf); + efree( buf ); + } + zval_ptr_dtor( object ); + return FAILURE; + } + + transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); + /* no need to close the transliterator manually on construction error */ + if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) + { + intl_error_set_code( nullptr, TRANSLITERATOR_ERROR_CODE( to ) ); + intl_error_set_custom_msg(nullptr, "internal constructor call failed"); + zval_ptr_dtor( object ); + return FAILURE; + } + + return SUCCESS; +} + +/* {{{ Opens a transliterator by id. */ +U_CFUNC PHP_FUNCTION( transliterator_create ) +{ + char *str_id; + size_t str_id_len; + zend_long direction = TRANSLITERATOR_FORWARD; + int res; + + TRANSLITERATOR_METHOD_INIT_VARS; + + (void) to; /* unused */ + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(str_id, str_id_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(direction) + ZEND_PARSE_PARAMETERS_END(); + + object = return_value; + res = create_transliterator( str_id, str_id_len, direction, object ); + if( res == FAILURE ) + RETURN_NULL(); + + /* success, leave return_value as it is (set by create_transliterator) */ +} +/* }}} */ + +/* {{{ Opens a transliterator by id. */ +U_CFUNC PHP_FUNCTION( transliterator_create_from_rules ) +{ + char *str_rules; + size_t str_rules_len; + UChar *ustr_rules = nullptr; + int32_t ustr_rules_len = 0; + zend_long direction = TRANSLITERATOR_FORWARD; + UParseError parse_error; + UTransliterator *utrans; + UChar id[] = {0x52, 0x75, 0x6C, 0x65, 0x73, 0x54, 0x72, + 0x61, 0x6E, 0x73, 0x50, 0x48, 0x50, 0}; /* RulesTransPHP */ + TRANSLITERATOR_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(str_rules, str_rules_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(direction) + ZEND_PARSE_PARAMETERS_END(); + + if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) + { + zend_argument_value_error(2, "must be either Transliterator::FORWARD or Transliterator::REVERSE"); + RETURN_THROWS(); + } + + object = return_value; + object_init_ex( object, Transliterator_ce_ptr ); + TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; + + intl_convert_utf8_to_utf16( &ustr_rules, &ustr_rules_len, + str_rules, str_rules_len, TRANSLITERATOR_ERROR_CODE_P( to ) ); + /* (I'm not a big fan of non-obvious flow control macros ). + * This one checks the error value, destroys object and returns false */ + INTL_METHOD_CHECK_STATUS_OR_NULL( to, "String conversion of rules to UTF-16 failed" ); + + /* Open ICU Transliterator. */ + utrans = utrans_openU( id, ( sizeof( id ) - 1 ) / ( sizeof( *id ) ), (UTransDirection ) direction, + ustr_rules, ustr_rules_len, &parse_error, TRANSLITERATOR_ERROR_CODE_P( to ) ); + if (ustr_rules) { + efree( ustr_rules ); + } + + intl_error_set_code( nullptr, INTL_DATA_ERROR_CODE( to ) ); + if( U_FAILURE( INTL_DATA_ERROR_CODE( to ) ) ) + { + char *msg = nullptr; + smart_str parse_error_str; + parse_error_str = intl_parse_error_to_string( &parse_error ); + spprintf( &msg, 0, "unable to " + "create ICU transliterator from rules (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "" ); + smart_str_free( &parse_error_str ); + if( msg != nullptr ) + { + intl_errors_set_custom_msg( INTL_DATA_ERROR_P( to ), msg); + efree( msg ); + } + zval_ptr_dtor( return_value ); + RETURN_NULL(); + } + transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); + /* no need to close the transliterator manually on construction error */ + INTL_METHOD_CHECK_STATUS_OR_NULL( to, "internal constructor call failed" ); +} +/* }}} */ + +/* {{{ Opens the inverse transliterator transliterator. */ +U_CFUNC PHP_FUNCTION( transliterator_create_inverse ) +{ + Transliterator_object *to_orig; + UTransliterator *utrans; + TRANSLITERATOR_METHOD_INIT_VARS; + + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, Transliterator_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + TRANSLITERATOR_METHOD_FETCH_OBJECT; + to_orig = to; + + object = return_value; + object_init_ex( object, Transliterator_ce_ptr ); + TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; /* change "to" into new object (from "object" ) */ + + utrans = utrans_openInverse( to_orig->utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); + INTL_METHOD_CHECK_STATUS_OR_NULL( to, "could not create " + "inverse ICU transliterator" ); + transliterator_object_construct( object, utrans, TRANSLITERATOR_ERROR_CODE_P( to ) ); + /* no need to close the transliterator manually on construction error */ + INTL_METHOD_CHECK_STATUS_OR_NULL( to, "internal constructor call failed" ); +} +/* }}} */ + +/* {{{ Return an array with the registered transliterator IDs. */ +U_CFUNC PHP_FUNCTION( transliterator_list_ids ) +{ + UEnumeration *en; + const UChar *elem; + int32_t elem_len; + UErrorCode status = U_ZERO_ERROR; + + intl_error_reset( nullptr ); + + ZEND_PARSE_PARAMETERS_NONE(); + + en = utrans_openIDs( &status ); + INTL_CHECK_STATUS( status, + "Failed to obtain registered transliterators" ); + + array_init( return_value ); + while( (elem = uenum_unext( en, &elem_len, &status )) ) + { + zend_string *el = intl_convert_utf16_to_utf8(elem, elem_len, &status ); + + if( !el ) + { + break; + } + else + { + add_next_index_str( return_value, el); + } + } + uenum_close( en ); + + intl_error_set_code( nullptr, status ); + if( U_FAILURE( status ) ) + { + zend_array_destroy( Z_ARR_P(return_value) ); + RETVAL_FALSE; + intl_error_set_custom_msg( nullptr, + "Failed to build array of registered transliterators"); + } +} +/* }}} */ + +/* {{{ Transliterate a string. */ +U_CFUNC PHP_FUNCTION( transliterator_transliterate ) +{ + char *str; + UChar *ustr = nullptr, + *uresult = nullptr; + size_t str_len; + int32_t ustr_len = 0, + capacity, + uresult_len; + zend_long start = 0, + limit = -1; + int success = 0; + zval tmp_object; + TRANSLITERATOR_METHOD_INIT_VARS; + + object = getThis(); + + ZVAL_UNDEF(&tmp_object); + + if (object == nullptr) { + /* in non-OOP version, accept both a transliterator and a string */ + zend_string *arg1_str; + zend_object *arg1_obj; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_OBJ_OF_CLASS_OR_STR(arg1_obj, Transliterator_ce_ptr, arg1_str) + Z_PARAM_STRING(str, str_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(start) + Z_PARAM_LONG(limit) + ZEND_PARSE_PARAMETERS_END(); + + if (arg1_str) { /* not a transliterator object as first argument */ + int res; + object = &tmp_object; + res = create_transliterator(ZSTR_VAL(arg1_str), ZSTR_LEN(arg1_str), TRANSLITERATOR_FORWARD, object); + if( res == FAILURE ) + { + if (!EG(exception)) { + zend_string *message = intl_error_get_message( nullptr ); + php_error_docref(nullptr, E_WARNING, "Could not create transliterator with ID \"%s\" (%s)", ZSTR_VAL(arg1_str), ZSTR_VAL(message) ); + zend_string_free( message ); + } + ZVAL_UNDEF(&tmp_object); + /* don't set U_ILLEGAL_ARGUMENT_ERROR to allow fetching of inner error */ + goto cleanup; + } + } else { + ZVAL_OBJ_COPY(&tmp_object, arg1_obj); + object = &tmp_object; + } + } else if(zend_parse_parameters( ZEND_NUM_ARGS(), "s|ll", &str, &str_len, &start, &limit) == FAILURE) { + RETURN_THROWS(); + } + + if (limit < -1) { + zend_argument_value_error(object ? 3 : 4, "must be greater than or equal to -1"); + goto cleanup_object; + } + + if (start < 0) { + zend_argument_value_error(object ? 2 : 3, "must be greater than or equal to 0"); + goto cleanup_object; + } + + if (limit != -1 && start > limit) { + zend_argument_value_error(object ? 2 : 3, "must be less than or equal to argument #%d ($end)", object ? 3 : 4); + goto cleanup_object; + } + + /* end argument parsing/validation */ + + TRANSLITERATOR_METHOD_FETCH_OBJECT; + + intl_convert_utf8_to_utf16(&ustr, &ustr_len, str, str_len, TRANSLITERATOR_ERROR_CODE_P(to)); + INTL_METHOD_CHECK_STATUS_OR_GOTO(to, "String conversion of string to UTF-16 failed", cleanup_object); + + /* we've started allocating resources, goto from now on */ + + if( ( start > ustr_len ) || (( limit != -1 ) && (limit > ustr_len ) ) ) + { + char *msg; + spprintf( &msg, 0, + "Neither \"start\" nor the \"end\" " + "arguments can exceed the number of UTF-16 code units " + "(in this case, %d)", (int) ustr_len ); + if(msg != nullptr ) + { + intl_errors_set(TRANSLITERATOR_ERROR_P(to), U_ILLEGAL_ARGUMENT_ERROR, msg); + efree( msg ); + } + goto cleanup; + } + + uresult = reinterpret_cast(safe_emalloc( ustr_len, sizeof( UChar ), 1 * sizeof( UChar ) )); + capacity = ustr_len + 1; + + while( 1 ) + { + int32_t temp_limit = ( limit == -1 ? ustr_len : (int32_t) limit ); + memcpy( uresult, ustr, ustr_len * sizeof( UChar ) ); + uresult_len = ustr_len; + + utrans_transUChars( to->utrans, uresult, &uresult_len, capacity, (int32_t) start, + &temp_limit, TRANSLITERATOR_ERROR_CODE_P( to ) ); + if( TRANSLITERATOR_ERROR_CODE( to ) == U_BUFFER_OVERFLOW_ERROR ) + { + efree( uresult ); + + uresult = reinterpret_cast(safe_emalloc( uresult_len, sizeof( UChar ), 1 * sizeof( UChar ) )); + capacity = uresult_len + 1; + + intl_error_reset( TRANSLITERATOR_ERROR_P( to ) ); + } + else if(TRANSLITERATOR_ERROR_CODE( to ) == U_STRING_NOT_TERMINATED_WARNING ) + { + uresult = reinterpret_cast(safe_erealloc( uresult, uresult_len, sizeof( UChar ), 1 * sizeof( UChar ) )); + + intl_error_reset( TRANSLITERATOR_ERROR_P( to ) ); + break; + } + else if( U_FAILURE( TRANSLITERATOR_ERROR_CODE( to ) ) ) + { + intl_error_set_code( nullptr, TRANSLITERATOR_ERROR_CODE( to ) ); + intl_errors_set_custom_msg( TRANSLITERATOR_ERROR_P( to ), "transliteration failed"); + goto cleanup; + } + else + break; + } + + uresult[uresult_len] = (UChar) 0; + + success = 1; + +cleanup: + if( ustr ) + efree( ustr ); + + if( success ) { + /* frees uresult even on error */ + INTL_METHOD_RETVAL_UTF8( to, uresult, uresult_len, 1 ); + } + else + { + if( uresult ) + efree( uresult ); + RETVAL_FALSE; + } + +cleanup_object: + zval_ptr_dtor( &tmp_object ); +} +/* }}} */ + +U_CFUNC PHP_METHOD( Transliterator, __construct ) +{ + /* this constructor shouldn't be called as it's private */ + zend_throw_exception( nullptr, + "An object of this type cannot be created with the new operator.", + 0 ); +} + +/* {{{ Get the last error code for this transliterator. */ +U_CFUNC PHP_FUNCTION( transliterator_get_error_code ) +{ + TRANSLITERATOR_METHOD_INIT_VARS + + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, Transliterator_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + /* Fetch the object (without resetting its last error code ). */ + to = Z_INTL_TRANSLITERATOR_P( object ); + + RETURN_LONG( (zend_long) TRANSLITERATOR_ERROR_CODE( to ) ); +} +/* }}} */ + + +/* {{{ Get the last error message for this transliterator. */ +U_CFUNC PHP_FUNCTION( transliterator_get_error_message ) +{ + zend_string* message = nullptr; + TRANSLITERATOR_METHOD_INIT_VARS + + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "O", + &object, Transliterator_ce_ptr ) == FAILURE ) + { + RETURN_THROWS(); + } + + + /* Fetch the object (without resetting its last error code ). */ + to = Z_INTL_TRANSLITERATOR_P( object ); + + /* Return last error message. */ + message = intl_error_get_message( TRANSLITERATOR_ERROR_P( to ) ); + RETURN_STR( message ); +} +/* }}} */ diff --git a/ext/intl/uchar/uchar.c b/ext/intl/uchar/uchar.c deleted file mode 100644 index ecfcd8fbe624..000000000000 --- a/ext/intl/uchar/uchar.c +++ /dev/null @@ -1,627 +0,0 @@ -#include "uchar.h" -#include "intl_data.h" -#include "intl_convert.h" - -#include -#include - -#include "uchar_arginfo.h" - -#define IC_METHOD(mname) PHP_METHOD(IntlChar, mname) - -static inline int convert_cp(UChar32* pcp, zend_string *string_codepoint, zend_long int_codepoint) { - if (string_codepoint != NULL) { - int32_t i = 0; - size_t string_codepoint_length = ZSTR_LEN(string_codepoint); - - if (ZEND_SIZE_T_INT_OVFL(string_codepoint_length)) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Input string is too long.", 0); - return FAILURE; - } - - U8_NEXT(ZSTR_VAL(string_codepoint), i, string_codepoint_length, int_codepoint); - if ((size_t)i != string_codepoint_length) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Passing a UTF-8 character for codepoint requires a string which is exactly one UTF-8 codepoint long.", 0); - return FAILURE; - } - } - - if ((int_codepoint < UCHAR_MIN_VALUE) || (int_codepoint > UCHAR_MAX_VALUE)) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Codepoint out of range", 0); - return FAILURE; - } - *pcp = (UChar32)int_codepoint; - return SUCCESS; -} - -static zend_never_inline int parse_code_point_param(INTERNAL_FUNCTION_PARAMETERS, UChar32 *cp) { - zend_string *string_codepoint; - zend_long int_codepoint = 0; - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) - ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); - return convert_cp(cp, string_codepoint, int_codepoint); -} - -/* {{{ Converts a numeric codepoint to UTF-8 - * Acts as an identify function when given a valid UTF-8 encoded codepoint - */ -IC_METHOD(chr) { - UChar32 cp; - char buffer[5]; - int buffer_len = 0; - - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { - RETURN_NULL(); - } - - /* We can use unsafe because we know the codepoint is in valid range - * and that 4 bytes is enough for any unicode point - */ - U8_APPEND_UNSAFE(buffer, buffer_len, cp); - buffer[buffer_len] = 0; - RETURN_STRINGL(buffer, buffer_len); -} -/* }}} */ - -/* {{{ Converts a UTf-8 encoded codepoint to its integer U32 value - * Acts as an identity function when passed a valid integer codepoint - */ -IC_METHOD(ord) { - UChar32 cp; - - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { - RETURN_NULL(); - } - - RETURN_LONG(cp); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(hasBinaryProperty) { - UChar32 cp; - zend_long prop; - zend_string *string_codepoint; - zend_long int_codepoint = 0; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) - Z_PARAM_LONG(prop) - ZEND_PARSE_PARAMETERS_END(); - - if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { - RETURN_NULL(); - } - - RETURN_BOOL(u_hasBinaryProperty(cp, (UProperty)prop)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getIntPropertyValue) { - UChar32 cp; - zend_long prop; - zend_string *string_codepoint; - zend_long int_codepoint = 0; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) - Z_PARAM_LONG(prop) - ZEND_PARSE_PARAMETERS_END(); - - if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { - RETURN_NULL(); - } - - RETURN_LONG(u_getIntPropertyValue(cp, (UProperty)prop)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getIntPropertyMinValue) { - zend_long prop; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(prop) - ZEND_PARSE_PARAMETERS_END(); - - RETURN_LONG(u_getIntPropertyMinValue((UProperty)prop)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getIntPropertyMaxValue) { - zend_long prop; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_LONG(prop) - ZEND_PARSE_PARAMETERS_END(); - - RETURN_LONG(u_getIntPropertyMaxValue((UProperty)prop)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getNumericValue) { - UChar32 cp; - - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { - RETURN_NULL(); - } - - RETURN_DOUBLE(u_getNumericValue(cp)); -} -/* }}} */ - -/* {{{ */ -typedef struct _enumCharType_data { - zend_fcall_info fci; - zend_fcall_info_cache fci_cache; -} enumCharType_data; -static UBool enumCharType_callback(enumCharType_data *context, - UChar32 start, UChar32 limit, UCharCategory type) { - zval retval; - zval args[3]; - - ZVAL_NULL(&retval); - /* Note that $start is INclusive, while $limit is EXclusive - * Therefore (0, 32, 15) means CPs 0..31 are of type 15 - */ - ZVAL_LONG(&args[0], start); - ZVAL_LONG(&args[1], limit); - ZVAL_LONG(&args[2], type); - - context->fci.retval = &retval; - context->fci.param_count = 3; - context->fci.params = args; - - if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) { - intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR); - intl_errors_set_custom_msg(NULL, "enumCharTypes callback failed", 0); - zval_ptr_dtor(&retval); - return 0; - } - zval_ptr_dtor(&retval); - return 1; -} -IC_METHOD(enumCharTypes) { - enumCharType_data context; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_FUNC(context.fci, context.fci_cache) - ZEND_PARSE_PARAMETERS_END(); - u_enumCharTypes((UCharEnumTypeRange*)enumCharType_callback, &context); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getBlockCode) { - UChar32 cp; - - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { - RETURN_NULL(); - } - - RETURN_LONG(ublock_getCode(cp)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(charName) { - UChar32 cp; - zend_string *string_codepoint; - zend_long int_codepoint = 0; - UErrorCode error = U_ZERO_ERROR; - zend_long nameChoice = U_UNICODE_CHAR_NAME; - zend_string *buffer = NULL; - int32_t buffer_len; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(nameChoice) - ZEND_PARSE_PARAMETERS_END(); - - if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { - RETURN_NULL(); - } - - buffer_len = u_charName(cp, (UCharNameChoice)nameChoice, NULL, 0, &error); - buffer = zend_string_alloc(buffer_len, 0); - error = U_ZERO_ERROR; - buffer_len = u_charName(cp, (UCharNameChoice)nameChoice, ZSTR_VAL(buffer), ZSTR_LEN(buffer) + 1, &error); - if (U_FAILURE(error)) { - zend_string_efree(buffer); - INTL_CHECK_STATUS_OR_NULL(error, "Failure getting character name"); - } - RETURN_NEW_STR(buffer); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(charFromName) { - char *name; - size_t name_len; - zend_long nameChoice = U_UNICODE_CHAR_NAME; - UChar32 ret; - UErrorCode error = U_ZERO_ERROR; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(name, name_len) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(nameChoice) - ZEND_PARSE_PARAMETERS_END(); - - ret = u_charFromName((UCharNameChoice)nameChoice, name, &error); - INTL_CHECK_STATUS_OR_NULL(error, NULL); - RETURN_LONG(ret); -} -/* }}} */ - -/* {{{ void void IntlChar::enumCharNames(int|string $start, int|string $limit, callable $callback, int $nameChoice = IntlChar::UNICODE_CHAR_NAME) */ -typedef struct _enumCharNames_data { - zend_fcall_info fci; - zend_fcall_info_cache fci_cache; -} enumCharNames_data; -static UBool enumCharNames_callback(enumCharNames_data *context, - UChar32 code, UCharNameChoice nameChoice, - const char *name, int32_t length) { - zval retval; - zval args[3]; - - ZVAL_NULL(&retval); - ZVAL_LONG(&args[0], code); - ZVAL_LONG(&args[1], nameChoice); - ZVAL_STRINGL(&args[2], name, length); - - context->fci.retval = &retval; - context->fci.param_count = 3; - context->fci.params = args; - - if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) { - intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR); - intl_error_set_custom_msg(NULL, "enumCharNames callback failed", 0); - zval_ptr_dtor(&retval); - zval_ptr_dtor_str(&args[2]); - return 0; - } - zval_ptr_dtor(&retval); - zval_ptr_dtor_str(&args[2]); - return 1; -} -IC_METHOD(enumCharNames) { - UChar32 start, limit; - zend_string *string_start, *string_limit; - zend_long int_start = 0, int_limit = 0; - enumCharNames_data context; - zend_long nameChoice = U_UNICODE_CHAR_NAME; - UErrorCode error = U_ZERO_ERROR; - - - ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_STR_OR_LONG(string_start, int_start) - Z_PARAM_STR_OR_LONG(string_limit, int_limit) - Z_PARAM_FUNC(context.fci, context.fci_cache) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(nameChoice) - ZEND_PARSE_PARAMETERS_END(); - - if (convert_cp(&start, string_start, int_start) == FAILURE || convert_cp(&limit, string_limit, int_limit) == FAILURE) { - RETURN_FALSE; - } - - u_enumCharNames(start, limit, (UEnumCharNamesFn*)enumCharNames_callback, &context, nameChoice, &error); - INTL_CHECK_STATUS(error, NULL); - RETURN_TRUE; -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getPropertyName) { - zend_long property; - zend_long nameChoice = U_LONG_PROPERTY_NAME; - const char *ret; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_LONG(property) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(nameChoice) - ZEND_PARSE_PARAMETERS_END(); - - ret = u_getPropertyName((UProperty)property, (UPropertyNameChoice)nameChoice); - if (ret) { - RETURN_STRING(ret); - } else { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Failed to get property name", 0); - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getPropertyEnum) { - char *alias; - size_t alias_len; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(alias, alias_len) - ZEND_PARSE_PARAMETERS_END(); - - RETURN_LONG(u_getPropertyEnum(alias)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getPropertyValueName) { - zend_long property, value, nameChoice = U_LONG_PROPERTY_NAME; - const char *ret; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_LONG(property) - Z_PARAM_LONG(value) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(nameChoice) - ZEND_PARSE_PARAMETERS_END(); - - ret = u_getPropertyValueName((UProperty)property, value, (UPropertyNameChoice)nameChoice); - if (ret) { - RETURN_STRING(ret); - } else { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Failed to get property name", 0); - RETURN_FALSE; - } -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getPropertyValueEnum) { - zend_long property; - char *name; - size_t name_len; - - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_LONG(property) - Z_PARAM_STRING(name, name_len) - ZEND_PARSE_PARAMETERS_END(); - - RETURN_LONG(u_getPropertyValueEnum((UProperty)property, name)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(foldCase) { - UChar32 cp, ret; - zend_long options = U_FOLD_CASE_DEFAULT; - zend_string *string_codepoint; - zend_long int_codepoint = 0; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(options) - ZEND_PARSE_PARAMETERS_END(); - - if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { - RETURN_NULL(); - } - - ret = u_foldCase(cp, options); - if (string_codepoint != NULL) { - char buffer[5]; - int buffer_len = 0; - U8_APPEND_UNSAFE(buffer, buffer_len, ret); - buffer[buffer_len] = 0; - RETURN_STRINGL(buffer, buffer_len); - } else { - RETURN_LONG(ret); - } -} -/* }}} */ - -/* {{{ */ -IC_METHOD(digit) { - UChar32 cp; - zend_long radix = 10; - int ret; - zend_string *string_codepoint; - zend_long int_codepoint = 0; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(radix) - ZEND_PARSE_PARAMETERS_END(); - - if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { - RETURN_NULL(); - } - - ret = u_digit(cp, radix); - if (ret < 0) { - intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); - intl_error_set_custom_msg(NULL, "Invalid digit", 0); - RETURN_FALSE; - } - RETURN_LONG(ret); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(forDigit) { - zend_long digit, radix = 10; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_LONG(digit) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(radix) - ZEND_PARSE_PARAMETERS_END(); - - RETURN_LONG(u_forDigit(digit, radix)); -} -/* }}} */ - -/* {{{ */ -IC_METHOD(charAge) { - UChar32 cp; - UVersionInfo version; - int i; - - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { - RETURN_NULL(); - } - - u_charAge(cp, version); - array_init(return_value); - for(i = 0; i < U_MAX_VERSION_LENGTH; ++i) { - add_next_index_long(return_value, version[i]); - } -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getUnicodeVersion) { - UVersionInfo version; - int i; - - ZEND_PARSE_PARAMETERS_NONE(); - - u_getUnicodeVersion(version); - array_init(return_value); - for(i = 0; i < U_MAX_VERSION_LENGTH; ++i) { - add_next_index_long(return_value, version[i]); - } -} -/* }}} */ - -/* {{{ */ -IC_METHOD(getFC_NFKC_Closure) { - UChar32 cp; - UChar *closure; - zend_string *u8str; - int32_t closure_len; - UErrorCode error = U_ZERO_ERROR; - - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { - RETURN_NULL(); - } - - closure_len = u_getFC_NFKC_Closure(cp, NULL, 0, &error); - if (closure_len == 0) { - RETURN_EMPTY_STRING(); - } - closure = safe_emalloc(sizeof(UChar), closure_len + 1, 0); - error = U_ZERO_ERROR; - closure_len = u_getFC_NFKC_Closure(cp, closure, closure_len, &error); - if (U_FAILURE(error)) { - efree(closure); - INTL_CHECK_STATUS(error, "Failed getting closure"); - } - - error = U_ZERO_ERROR; - u8str = intl_convert_utf16_to_utf8(closure, closure_len, &error); - INTL_CHECK_STATUS(error, "Failed converting output to UTF8"); - efree(closure); - RETVAL_NEW_STR(u8str); -} -/* }}} */ - -/* {{{ */ -#define IC_BOOL_METHOD_CHAR(name) \ -IC_METHOD(name) { \ - UChar32 cp; \ - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { \ - RETURN_NULL(); \ - } \ - RETURN_BOOL(u_##name(cp)); \ -} -IC_BOOL_METHOD_CHAR(isUAlphabetic) -IC_BOOL_METHOD_CHAR(isULowercase) -IC_BOOL_METHOD_CHAR(isUUppercase) -IC_BOOL_METHOD_CHAR(isUWhiteSpace) -IC_BOOL_METHOD_CHAR(islower) -IC_BOOL_METHOD_CHAR(isupper) -IC_BOOL_METHOD_CHAR(istitle) -IC_BOOL_METHOD_CHAR(isdigit) -IC_BOOL_METHOD_CHAR(isalpha) -IC_BOOL_METHOD_CHAR(isalnum) -IC_BOOL_METHOD_CHAR(isxdigit) -IC_BOOL_METHOD_CHAR(ispunct) -IC_BOOL_METHOD_CHAR(isgraph) -IC_BOOL_METHOD_CHAR(isblank) -IC_BOOL_METHOD_CHAR(isdefined) -IC_BOOL_METHOD_CHAR(isspace) -IC_BOOL_METHOD_CHAR(isJavaSpaceChar) -IC_BOOL_METHOD_CHAR(isWhitespace) -IC_BOOL_METHOD_CHAR(iscntrl) -IC_BOOL_METHOD_CHAR(isISOControl) -IC_BOOL_METHOD_CHAR(isprint) -IC_BOOL_METHOD_CHAR(isbase) -IC_BOOL_METHOD_CHAR(isMirrored) -IC_BOOL_METHOD_CHAR(isIDStart) -IC_BOOL_METHOD_CHAR(isIDPart) -IC_BOOL_METHOD_CHAR(isIDIgnorable) -IC_BOOL_METHOD_CHAR(isJavaIDStart) -IC_BOOL_METHOD_CHAR(isJavaIDPart) -#undef IC_BOOL_METHOD_CHAR -/* }}} */ - -/* {{{ */ -#define IC_INT_METHOD_CHAR(name) \ -IC_METHOD(name) { \ - UChar32 cp; \ - if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { \ - RETURN_NULL(); \ - } \ - RETURN_LONG(u_##name(cp)); \ -} -IC_INT_METHOD_CHAR(charDirection) -IC_INT_METHOD_CHAR(charType) -IC_INT_METHOD_CHAR(getCombiningClass) -IC_INT_METHOD_CHAR(charDigitValue) -#undef IC_INT_METHOD_CHAR -/* }}} */ - -/* {{{ Returns a utf-8 character if codepoint was passed as a utf-8 sequence - * Returns an int otherwise - */ -#define IC_CHAR_METHOD_CHAR(name) \ -IC_METHOD(name) { \ - UChar32 cp, ret; \ - zend_string *string_codepoint; \ - zend_long int_codepoint = -1; \ - ZEND_PARSE_PARAMETERS_START(1, 1) \ - Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) \ - ZEND_PARSE_PARAMETERS_END(); \ - if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { \ - RETURN_NULL(); \ - } \ - ret = u_##name(cp); \ - if (string_codepoint != NULL) { \ - char buffer[5]; \ - int buffer_len = 0; \ - U8_APPEND_UNSAFE(buffer, buffer_len, ret); \ - buffer[buffer_len] = 0; \ - RETURN_STRINGL(buffer, buffer_len); \ - } else { \ - RETURN_LONG(ret); \ - } \ -} -IC_CHAR_METHOD_CHAR(charMirror) -IC_CHAR_METHOD_CHAR(tolower) -IC_CHAR_METHOD_CHAR(toupper) -IC_CHAR_METHOD_CHAR(totitle) -IC_CHAR_METHOD_CHAR(getBidiPairedBracket) -#undef IC_CHAR_METHOD_CHAR -/* }}} */ - -int php_uchar_minit(INIT_FUNC_ARGS) { - register_class_IntlChar(); - - return SUCCESS; -} diff --git a/ext/intl/uchar/uchar.cpp b/ext/intl/uchar/uchar.cpp new file mode 100644 index 000000000000..ccb642b9d416 --- /dev/null +++ b/ext/intl/uchar/uchar.cpp @@ -0,0 +1,643 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ + */ + +extern "C" { +#include "uchar.h" +#include "intl_data.h" +#include "intl_convert.h" + +#include +#include + +#include "uchar_arginfo.h" +} + +#define IC_METHOD(mname) PHP_METHOD(IntlChar, mname) + +static inline int convert_cp(UChar32* pcp, zend_string *string_codepoint, zend_long int_codepoint) { + if (string_codepoint != NULL) { + int32_t i = 0; + size_t string_codepoint_length = ZSTR_LEN(string_codepoint); + + if (ZEND_SIZE_T_INT_OVFL(string_codepoint_length)) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Input string is too long."); + return FAILURE; + } + + U8_NEXT(ZSTR_VAL(string_codepoint), i, string_codepoint_length, int_codepoint); + if ((size_t)i != string_codepoint_length) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Passing a UTF-8 character for codepoint requires a string which is exactly one UTF-8 codepoint long."); + return FAILURE; + } + } + + if ((int_codepoint < UCHAR_MIN_VALUE) || (int_codepoint > UCHAR_MAX_VALUE)) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Codepoint out of range"); + return FAILURE; + } + *pcp = (UChar32)int_codepoint; + return SUCCESS; +} + +static zend_never_inline int parse_code_point_param(INTERNAL_FUNCTION_PARAMETERS, UChar32 *cp) { + zend_string *string_codepoint; + zend_long int_codepoint = 0; + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); + return convert_cp(cp, string_codepoint, int_codepoint); +} + +/* {{{ Converts a numeric codepoint to UTF-8 + * Acts as an identify function when given a valid UTF-8 encoded codepoint + */ +IC_METHOD(chr) { + UChar32 cp; + char buffer[5]; + int buffer_len = 0; + + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { + RETURN_NULL(); + } + + /* We can use unsafe because we know the codepoint is in valid range + * and that 4 bytes is enough for any unicode point + */ + U8_APPEND_UNSAFE(buffer, buffer_len, cp); + buffer[buffer_len] = 0; + RETURN_STRINGL(buffer, buffer_len); +} +/* }}} */ + +/* {{{ Converts a UTf-8 encoded codepoint to its integer U32 value + * Acts as an identity function when passed a valid integer codepoint + */ +IC_METHOD(ord) { + UChar32 cp; + + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { + RETURN_NULL(); + } + + RETURN_LONG(cp); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(hasBinaryProperty) { + UChar32 cp; + zend_long prop; + zend_string *string_codepoint; + zend_long int_codepoint = 0; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) + Z_PARAM_LONG(prop) + ZEND_PARSE_PARAMETERS_END(); + + if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { + RETURN_NULL(); + } + + RETURN_BOOL(u_hasBinaryProperty(cp, (UProperty)prop)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getIntPropertyValue) { + UChar32 cp; + zend_long prop; + zend_string *string_codepoint; + zend_long int_codepoint = 0; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) + Z_PARAM_LONG(prop) + ZEND_PARSE_PARAMETERS_END(); + + if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { + RETURN_NULL(); + } + + RETURN_LONG(u_getIntPropertyValue(cp, (UProperty)prop)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getIntPropertyMinValue) { + zend_long prop; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(prop) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(u_getIntPropertyMinValue((UProperty)prop)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getIntPropertyMaxValue) { + zend_long prop; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(prop) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(u_getIntPropertyMaxValue((UProperty)prop)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getNumericValue) { + UChar32 cp; + + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { + RETURN_NULL(); + } + + RETURN_DOUBLE(u_getNumericValue(cp)); +} +/* }}} */ + +/* {{{ */ +typedef struct _enumCharType_data { + zend_fcall_info fci; + zend_fcall_info_cache fci_cache; +} enumCharType_data; +static UBool enumCharType_callback(enumCharType_data *context, + UChar32 start, UChar32 limit, UCharCategory type) { + zval retval; + zval args[3]; + + ZVAL_NULL(&retval); + /* Note that $start is INclusive, while $limit is EXclusive + * Therefore (0, 32, 15) means CPs 0..31 are of type 15 + */ + ZVAL_LONG(&args[0], start); + ZVAL_LONG(&args[1], limit); + ZVAL_LONG(&args[2], type); + + context->fci.retval = &retval; + context->fci.param_count = 3; + context->fci.params = args; + + if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) { + intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR); + intl_errors_set_custom_msg(NULL, "enumCharTypes callback failed"); + zval_ptr_dtor(&retval); + return 0; + } + zval_ptr_dtor(&retval); + return 1; +} +IC_METHOD(enumCharTypes) { + enumCharType_data context; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_FUNC(context.fci, context.fci_cache) + ZEND_PARSE_PARAMETERS_END(); + u_enumCharTypes((UCharEnumTypeRange*)enumCharType_callback, &context); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getBlockCode) { + UChar32 cp; + + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { + RETURN_NULL(); + } + + RETURN_LONG(ublock_getCode(cp)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(charName) { + UChar32 cp; + zend_string *string_codepoint; + zend_long int_codepoint = 0; + UErrorCode error = U_ZERO_ERROR; + zend_long nameChoice = U_UNICODE_CHAR_NAME; + zend_string *buffer = NULL; + int32_t buffer_len; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(nameChoice) + ZEND_PARSE_PARAMETERS_END(); + + if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { + RETURN_NULL(); + } + + buffer_len = u_charName(cp, (UCharNameChoice)nameChoice, NULL, 0, &error); + buffer = zend_string_alloc(buffer_len, 0); + error = U_ZERO_ERROR; + buffer_len = u_charName(cp, (UCharNameChoice)nameChoice, ZSTR_VAL(buffer), ZSTR_LEN(buffer) + 1, &error); + if (U_FAILURE(error)) { + zend_string_efree(buffer); + INTL_CHECK_STATUS_OR_NULL(error, "Failure getting character name"); + } + RETURN_NEW_STR(buffer); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(charFromName) { + char *name; + size_t name_len; + zend_long nameChoice = U_UNICODE_CHAR_NAME; + UChar32 ret; + UErrorCode error = U_ZERO_ERROR; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(name, name_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(nameChoice) + ZEND_PARSE_PARAMETERS_END(); + + ret = u_charFromName((UCharNameChoice)nameChoice, name, &error); + INTL_CHECK_STATUS_OR_NULL(error, NULL); + RETURN_LONG(ret); +} +/* }}} */ + +/* {{{ void void IntlChar::enumCharNames(int|string $start, int|string $limit, callable $callback, int $nameChoice = IntlChar::UNICODE_CHAR_NAME) */ +typedef struct _enumCharNames_data { + zend_fcall_info fci; + zend_fcall_info_cache fci_cache; +} enumCharNames_data; +static UBool enumCharNames_callback(enumCharNames_data *context, + UChar32 code, UCharNameChoice nameChoice, + const char *name, int32_t length) { + zval retval; + zval args[3]; + + ZVAL_NULL(&retval); + ZVAL_LONG(&args[0], code); + ZVAL_LONG(&args[1], nameChoice); + ZVAL_STRINGL(&args[2], name, length); + + context->fci.retval = &retval; + context->fci.param_count = 3; + context->fci.params = args; + + if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) { + intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR); + intl_error_set_custom_msg(NULL, "enumCharNames callback failed"); + zval_ptr_dtor(&retval); + zval_ptr_dtor_str(&args[2]); + return 0; + } + zval_ptr_dtor(&retval); + zval_ptr_dtor_str(&args[2]); + return 1; +} +IC_METHOD(enumCharNames) { + UChar32 start, limit; + zend_string *string_start, *string_limit; + zend_long int_start = 0, int_limit = 0; + enumCharNames_data context; + zend_long nameChoice = U_UNICODE_CHAR_NAME; + UErrorCode error = U_ZERO_ERROR; + + + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_STR_OR_LONG(string_start, int_start) + Z_PARAM_STR_OR_LONG(string_limit, int_limit) + Z_PARAM_FUNC(context.fci, context.fci_cache) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(nameChoice) + ZEND_PARSE_PARAMETERS_END(); + + if (convert_cp(&start, string_start, int_start) == FAILURE || convert_cp(&limit, string_limit, int_limit) == FAILURE) { + RETURN_FALSE; + } + + u_enumCharNames(start, limit, (UEnumCharNamesFn*)enumCharNames_callback, &context, static_cast(nameChoice), &error); + INTL_CHECK_STATUS(error, NULL); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getPropertyName) { + zend_long property; + zend_long nameChoice = U_LONG_PROPERTY_NAME; + const char *ret; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_LONG(property) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(nameChoice) + ZEND_PARSE_PARAMETERS_END(); + + ret = u_getPropertyName((UProperty)property, (UPropertyNameChoice)nameChoice); + if (ret) { + RETURN_STRING(ret); + } else { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Failed to get property name"); + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getPropertyEnum) { + char *alias; + size_t alias_len; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STRING(alias, alias_len) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(u_getPropertyEnum(alias)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getPropertyValueName) { + zend_long property, value, nameChoice = U_LONG_PROPERTY_NAME; + const char *ret; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_LONG(property) + Z_PARAM_LONG(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(nameChoice) + ZEND_PARSE_PARAMETERS_END(); + + ret = u_getPropertyValueName((UProperty)property, value, (UPropertyNameChoice)nameChoice); + if (ret) { + RETURN_STRING(ret); + } else { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Failed to get property name"); + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getPropertyValueEnum) { + zend_long property; + char *name; + size_t name_len; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(property) + Z_PARAM_STRING(name, name_len) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(u_getPropertyValueEnum((UProperty)property, name)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(foldCase) { + UChar32 cp, ret; + zend_long options = U_FOLD_CASE_DEFAULT; + zend_string *string_codepoint; + zend_long int_codepoint = 0; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(options) + ZEND_PARSE_PARAMETERS_END(); + + if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { + RETURN_NULL(); + } + + ret = u_foldCase(cp, options); + if (string_codepoint != NULL) { + char buffer[5]; + int buffer_len = 0; + U8_APPEND_UNSAFE(buffer, buffer_len, ret); + buffer[buffer_len] = 0; + RETURN_STRINGL(buffer, buffer_len); + } else { + RETURN_LONG(ret); + } +} +/* }}} */ + +/* {{{ */ +IC_METHOD(digit) { + UChar32 cp; + zend_long radix = 10; + int ret; + zend_string *string_codepoint; + zend_long int_codepoint = 0; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(radix) + ZEND_PARSE_PARAMETERS_END(); + + if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { + RETURN_NULL(); + } + + ret = u_digit(cp, radix); + if (ret < 0) { + intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR); + intl_error_set_custom_msg(NULL, "Invalid digit"); + RETURN_FALSE; + } + RETURN_LONG(ret); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(forDigit) { + zend_long digit, radix = 10; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_LONG(digit) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(radix) + ZEND_PARSE_PARAMETERS_END(); + + RETURN_LONG(u_forDigit(digit, radix)); +} +/* }}} */ + +/* {{{ */ +IC_METHOD(charAge) { + UChar32 cp; + UVersionInfo version; + int i; + + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { + RETURN_NULL(); + } + + u_charAge(cp, version); + array_init(return_value); + for(i = 0; i < U_MAX_VERSION_LENGTH; ++i) { + add_next_index_long(return_value, version[i]); + } +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getUnicodeVersion) { + UVersionInfo version; + int i; + + ZEND_PARSE_PARAMETERS_NONE(); + + u_getUnicodeVersion(version); + array_init(return_value); + for(i = 0; i < U_MAX_VERSION_LENGTH; ++i) { + add_next_index_long(return_value, version[i]); + } +} +/* }}} */ + +/* {{{ */ +IC_METHOD(getFC_NFKC_Closure) { + UChar32 cp; + UChar *closure; + zend_string *u8str; + int32_t closure_len; + UErrorCode error = U_ZERO_ERROR; + + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { + RETURN_NULL(); + } + + closure_len = u_getFC_NFKC_Closure(cp, NULL, 0, &error); + if (closure_len == 0) { + RETURN_EMPTY_STRING(); + } + closure = reinterpret_cast(safe_emalloc(sizeof(UChar), closure_len + 1, 0)); + error = U_ZERO_ERROR; + closure_len = u_getFC_NFKC_Closure(cp, closure, closure_len, &error); + if (U_FAILURE(error)) { + efree(closure); + INTL_CHECK_STATUS(error, "Failed getting closure"); + } + + error = U_ZERO_ERROR; + u8str = intl_convert_utf16_to_utf8(closure, closure_len, &error); + INTL_CHECK_STATUS(error, "Failed converting output to UTF8"); + efree(closure); + RETVAL_NEW_STR(u8str); +} +/* }}} */ + +/* {{{ */ +#define IC_BOOL_METHOD_CHAR(name) \ +IC_METHOD(name) { \ + UChar32 cp; \ + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { \ + RETURN_NULL(); \ + } \ + RETURN_BOOL(u_##name(cp)); \ +} +IC_BOOL_METHOD_CHAR(isUAlphabetic) +IC_BOOL_METHOD_CHAR(isULowercase) +IC_BOOL_METHOD_CHAR(isUUppercase) +IC_BOOL_METHOD_CHAR(isUWhiteSpace) +IC_BOOL_METHOD_CHAR(islower) +IC_BOOL_METHOD_CHAR(isupper) +IC_BOOL_METHOD_CHAR(istitle) +IC_BOOL_METHOD_CHAR(isdigit) +IC_BOOL_METHOD_CHAR(isalpha) +IC_BOOL_METHOD_CHAR(isalnum) +IC_BOOL_METHOD_CHAR(isxdigit) +IC_BOOL_METHOD_CHAR(ispunct) +IC_BOOL_METHOD_CHAR(isgraph) +IC_BOOL_METHOD_CHAR(isblank) +IC_BOOL_METHOD_CHAR(isdefined) +IC_BOOL_METHOD_CHAR(isspace) +IC_BOOL_METHOD_CHAR(isJavaSpaceChar) +IC_BOOL_METHOD_CHAR(isWhitespace) +IC_BOOL_METHOD_CHAR(iscntrl) +IC_BOOL_METHOD_CHAR(isISOControl) +IC_BOOL_METHOD_CHAR(isprint) +IC_BOOL_METHOD_CHAR(isbase) +IC_BOOL_METHOD_CHAR(isMirrored) +IC_BOOL_METHOD_CHAR(isIDStart) +IC_BOOL_METHOD_CHAR(isIDPart) +IC_BOOL_METHOD_CHAR(isIDIgnorable) +IC_BOOL_METHOD_CHAR(isJavaIDStart) +IC_BOOL_METHOD_CHAR(isJavaIDPart) +#undef IC_BOOL_METHOD_CHAR +/* }}} */ + +/* {{{ */ +#define IC_INT_METHOD_CHAR(name) \ +IC_METHOD(name) { \ + UChar32 cp; \ + if (parse_code_point_param(INTERNAL_FUNCTION_PARAM_PASSTHRU, &cp) == FAILURE) { \ + RETURN_NULL(); \ + } \ + RETURN_LONG(u_##name(cp)); \ +} +IC_INT_METHOD_CHAR(charDirection) +IC_INT_METHOD_CHAR(charType) +IC_INT_METHOD_CHAR(getCombiningClass) +IC_INT_METHOD_CHAR(charDigitValue) +#undef IC_INT_METHOD_CHAR +/* }}} */ + +/* {{{ Returns a utf-8 character if codepoint was passed as a utf-8 sequence + * Returns an int otherwise + */ +#define IC_CHAR_METHOD_CHAR(name) \ +IC_METHOD(name) { \ + UChar32 cp, ret; \ + zend_string *string_codepoint; \ + zend_long int_codepoint = -1; \ + ZEND_PARSE_PARAMETERS_START(1, 1) \ + Z_PARAM_STR_OR_LONG(string_codepoint, int_codepoint) \ + ZEND_PARSE_PARAMETERS_END(); \ + if (convert_cp(&cp, string_codepoint, int_codepoint) == FAILURE) { \ + RETURN_NULL(); \ + } \ + ret = u_##name(cp); \ + if (string_codepoint != NULL) { \ + char buffer[5]; \ + int buffer_len = 0; \ + U8_APPEND_UNSAFE(buffer, buffer_len, ret); \ + buffer[buffer_len] = 0; \ + RETURN_STRINGL(buffer, buffer_len); \ + } else { \ + RETURN_LONG(ret); \ + } \ +} +IC_CHAR_METHOD_CHAR(charMirror) +IC_CHAR_METHOD_CHAR(tolower) +IC_CHAR_METHOD_CHAR(toupper) +IC_CHAR_METHOD_CHAR(totitle) +IC_CHAR_METHOD_CHAR(getBidiPairedBracket) +#undef IC_CHAR_METHOD_CHAR +/* }}} */ + +int php_uchar_minit(INIT_FUNC_ARGS) { + register_class_IntlChar(); + + return SUCCESS; +} diff --git a/ext/intl/uchar/uchar.h b/ext/intl/uchar/uchar.h index 25bab1f2156f..7b472163ab0f 100644 --- a/ext/intl/uchar/uchar.h +++ b/ext/intl/uchar/uchar.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Sara Golemon | + +----------------------------------------------------------------------+ + */ + #ifndef incl_PHP_INTL_UCHAR_H #define incl_PHP_INTL_UCHAR_H diff --git a/ext/intl/uchar/uchar_arginfo.h b/ext/intl/uchar/uchar_arginfo.h index f290fb2b958e..7de78a0fd9d8 100644 --- a/ext/intl/uchar/uchar_arginfo.h +++ b/ext/intl/uchar/uchar_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit uchar.stub.php instead. * Stub hash: 58fb5f326ee08cca73977720d3b055b0118d78bb */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_IntlChar_hasBinaryProperty, 0, 2, _IS_BOOL, 1) @@ -311,4001 +311,4001 @@ static zend_class_entry *register_class_IntlChar(void) zval const_UNICODE_VERSION_value; zend_string *const_UNICODE_VERSION_value_str = zend_string_init(U_UNICODE_VERSION, strlen(U_UNICODE_VERSION), 1); ZVAL_STR(&const_UNICODE_VERSION_value, const_UNICODE_VERSION_value_str); - zend_string *const_UNICODE_VERSION_name = zend_string_init_interned("UNICODE_VERSION", sizeof("UNICODE_VERSION") - 1, 1); + zend_string *const_UNICODE_VERSION_name = zend_string_init_interned("UNICODE_VERSION", sizeof("UNICODE_VERSION") - 1, true); zend_declare_typed_class_constant(class_entry, const_UNICODE_VERSION_name, &const_UNICODE_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_UNICODE_VERSION_name); + zend_string_release_ex(const_UNICODE_VERSION_name, true); zval const_CODEPOINT_MIN_value; ZVAL_LONG(&const_CODEPOINT_MIN_value, UCHAR_MIN_VALUE); - zend_string *const_CODEPOINT_MIN_name = zend_string_init_interned("CODEPOINT_MIN", sizeof("CODEPOINT_MIN") - 1, 1); + zend_string *const_CODEPOINT_MIN_name = zend_string_init_interned("CODEPOINT_MIN", sizeof("CODEPOINT_MIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_CODEPOINT_MIN_name, &const_CODEPOINT_MIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CODEPOINT_MIN_name); + zend_string_release_ex(const_CODEPOINT_MIN_name, true); zval const_CODEPOINT_MAX_value; ZVAL_LONG(&const_CODEPOINT_MAX_value, UCHAR_MAX_VALUE); - zend_string *const_CODEPOINT_MAX_name = zend_string_init_interned("CODEPOINT_MAX", sizeof("CODEPOINT_MAX") - 1, 1); + zend_string *const_CODEPOINT_MAX_name = zend_string_init_interned("CODEPOINT_MAX", sizeof("CODEPOINT_MAX") - 1, true); zend_declare_typed_class_constant(class_entry, const_CODEPOINT_MAX_name, &const_CODEPOINT_MAX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CODEPOINT_MAX_name); + zend_string_release_ex(const_CODEPOINT_MAX_name, true); zval const_NO_NUMERIC_VALUE_value; ZVAL_DOUBLE(&const_NO_NUMERIC_VALUE_value, U_NO_NUMERIC_VALUE); - zend_string *const_NO_NUMERIC_VALUE_name = zend_string_init_interned("NO_NUMERIC_VALUE", sizeof("NO_NUMERIC_VALUE") - 1, 1); + zend_string *const_NO_NUMERIC_VALUE_name = zend_string_init_interned("NO_NUMERIC_VALUE", sizeof("NO_NUMERIC_VALUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_NO_NUMERIC_VALUE_name, &const_NO_NUMERIC_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_DOUBLE)); - zend_string_release(const_NO_NUMERIC_VALUE_name); + zend_string_release_ex(const_NO_NUMERIC_VALUE_name, true); zval const_PROPERTY_ALPHABETIC_value; ZVAL_LONG(&const_PROPERTY_ALPHABETIC_value, UCHAR_ALPHABETIC); - zend_string *const_PROPERTY_ALPHABETIC_name = zend_string_init_interned("PROPERTY_ALPHABETIC", sizeof("PROPERTY_ALPHABETIC") - 1, 1); + zend_string *const_PROPERTY_ALPHABETIC_name = zend_string_init_interned("PROPERTY_ALPHABETIC", sizeof("PROPERTY_ALPHABETIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_ALPHABETIC_name, &const_PROPERTY_ALPHABETIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_ALPHABETIC_name); + zend_string_release_ex(const_PROPERTY_ALPHABETIC_name, true); zval const_PROPERTY_BINARY_START_value; ZVAL_LONG(&const_PROPERTY_BINARY_START_value, UCHAR_BINARY_START); - zend_string *const_PROPERTY_BINARY_START_name = zend_string_init_interned("PROPERTY_BINARY_START", sizeof("PROPERTY_BINARY_START") - 1, 1); + zend_string *const_PROPERTY_BINARY_START_name = zend_string_init_interned("PROPERTY_BINARY_START", sizeof("PROPERTY_BINARY_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BINARY_START_name, &const_PROPERTY_BINARY_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BINARY_START_name); + zend_string_release_ex(const_PROPERTY_BINARY_START_name, true); zval const_PROPERTY_ASCII_HEX_DIGIT_value; ZVAL_LONG(&const_PROPERTY_ASCII_HEX_DIGIT_value, UCHAR_ASCII_HEX_DIGIT); - zend_string *const_PROPERTY_ASCII_HEX_DIGIT_name = zend_string_init_interned("PROPERTY_ASCII_HEX_DIGIT", sizeof("PROPERTY_ASCII_HEX_DIGIT") - 1, 1); + zend_string *const_PROPERTY_ASCII_HEX_DIGIT_name = zend_string_init_interned("PROPERTY_ASCII_HEX_DIGIT", sizeof("PROPERTY_ASCII_HEX_DIGIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_ASCII_HEX_DIGIT_name, &const_PROPERTY_ASCII_HEX_DIGIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_ASCII_HEX_DIGIT_name); + zend_string_release_ex(const_PROPERTY_ASCII_HEX_DIGIT_name, true); zval const_PROPERTY_BIDI_CONTROL_value; ZVAL_LONG(&const_PROPERTY_BIDI_CONTROL_value, UCHAR_BIDI_CONTROL); - zend_string *const_PROPERTY_BIDI_CONTROL_name = zend_string_init_interned("PROPERTY_BIDI_CONTROL", sizeof("PROPERTY_BIDI_CONTROL") - 1, 1); + zend_string *const_PROPERTY_BIDI_CONTROL_name = zend_string_init_interned("PROPERTY_BIDI_CONTROL", sizeof("PROPERTY_BIDI_CONTROL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BIDI_CONTROL_name, &const_PROPERTY_BIDI_CONTROL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BIDI_CONTROL_name); + zend_string_release_ex(const_PROPERTY_BIDI_CONTROL_name, true); zval const_PROPERTY_BIDI_MIRRORED_value; ZVAL_LONG(&const_PROPERTY_BIDI_MIRRORED_value, UCHAR_BIDI_MIRRORED); - zend_string *const_PROPERTY_BIDI_MIRRORED_name = zend_string_init_interned("PROPERTY_BIDI_MIRRORED", sizeof("PROPERTY_BIDI_MIRRORED") - 1, 1); + zend_string *const_PROPERTY_BIDI_MIRRORED_name = zend_string_init_interned("PROPERTY_BIDI_MIRRORED", sizeof("PROPERTY_BIDI_MIRRORED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BIDI_MIRRORED_name, &const_PROPERTY_BIDI_MIRRORED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BIDI_MIRRORED_name); + zend_string_release_ex(const_PROPERTY_BIDI_MIRRORED_name, true); zval const_PROPERTY_DASH_value; ZVAL_LONG(&const_PROPERTY_DASH_value, UCHAR_DASH); - zend_string *const_PROPERTY_DASH_name = zend_string_init_interned("PROPERTY_DASH", sizeof("PROPERTY_DASH") - 1, 1); + zend_string *const_PROPERTY_DASH_name = zend_string_init_interned("PROPERTY_DASH", sizeof("PROPERTY_DASH") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_DASH_name, &const_PROPERTY_DASH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_DASH_name); + zend_string_release_ex(const_PROPERTY_DASH_name, true); zval const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_value; ZVAL_LONG(&const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_value, UCHAR_DEFAULT_IGNORABLE_CODE_POINT); - zend_string *const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_name = zend_string_init_interned("PROPERTY_DEFAULT_IGNORABLE_CODE_POINT", sizeof("PROPERTY_DEFAULT_IGNORABLE_CODE_POINT") - 1, 1); + zend_string *const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_name = zend_string_init_interned("PROPERTY_DEFAULT_IGNORABLE_CODE_POINT", sizeof("PROPERTY_DEFAULT_IGNORABLE_CODE_POINT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_name, &const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_name); + zend_string_release_ex(const_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_name, true); zval const_PROPERTY_DEPRECATED_value; ZVAL_LONG(&const_PROPERTY_DEPRECATED_value, UCHAR_DEPRECATED); - zend_string *const_PROPERTY_DEPRECATED_name = zend_string_init_interned("PROPERTY_DEPRECATED", sizeof("PROPERTY_DEPRECATED") - 1, 1); + zend_string *const_PROPERTY_DEPRECATED_name = zend_string_init_interned("PROPERTY_DEPRECATED", sizeof("PROPERTY_DEPRECATED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_DEPRECATED_name, &const_PROPERTY_DEPRECATED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_DEPRECATED_name); + zend_string_release_ex(const_PROPERTY_DEPRECATED_name, true); zval const_PROPERTY_DIACRITIC_value; ZVAL_LONG(&const_PROPERTY_DIACRITIC_value, UCHAR_DIACRITIC); - zend_string *const_PROPERTY_DIACRITIC_name = zend_string_init_interned("PROPERTY_DIACRITIC", sizeof("PROPERTY_DIACRITIC") - 1, 1); + zend_string *const_PROPERTY_DIACRITIC_name = zend_string_init_interned("PROPERTY_DIACRITIC", sizeof("PROPERTY_DIACRITIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_DIACRITIC_name, &const_PROPERTY_DIACRITIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_DIACRITIC_name); + zend_string_release_ex(const_PROPERTY_DIACRITIC_name, true); zval const_PROPERTY_EXTENDER_value; ZVAL_LONG(&const_PROPERTY_EXTENDER_value, UCHAR_EXTENDER); - zend_string *const_PROPERTY_EXTENDER_name = zend_string_init_interned("PROPERTY_EXTENDER", sizeof("PROPERTY_EXTENDER") - 1, 1); + zend_string *const_PROPERTY_EXTENDER_name = zend_string_init_interned("PROPERTY_EXTENDER", sizeof("PROPERTY_EXTENDER") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_EXTENDER_name, &const_PROPERTY_EXTENDER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_EXTENDER_name); + zend_string_release_ex(const_PROPERTY_EXTENDER_name, true); zval const_PROPERTY_FULL_COMPOSITION_EXCLUSION_value; ZVAL_LONG(&const_PROPERTY_FULL_COMPOSITION_EXCLUSION_value, UCHAR_FULL_COMPOSITION_EXCLUSION); - zend_string *const_PROPERTY_FULL_COMPOSITION_EXCLUSION_name = zend_string_init_interned("PROPERTY_FULL_COMPOSITION_EXCLUSION", sizeof("PROPERTY_FULL_COMPOSITION_EXCLUSION") - 1, 1); + zend_string *const_PROPERTY_FULL_COMPOSITION_EXCLUSION_name = zend_string_init_interned("PROPERTY_FULL_COMPOSITION_EXCLUSION", sizeof("PROPERTY_FULL_COMPOSITION_EXCLUSION") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_FULL_COMPOSITION_EXCLUSION_name, &const_PROPERTY_FULL_COMPOSITION_EXCLUSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_FULL_COMPOSITION_EXCLUSION_name); + zend_string_release_ex(const_PROPERTY_FULL_COMPOSITION_EXCLUSION_name, true); zval const_PROPERTY_GRAPHEME_BASE_value; ZVAL_LONG(&const_PROPERTY_GRAPHEME_BASE_value, UCHAR_GRAPHEME_BASE); - zend_string *const_PROPERTY_GRAPHEME_BASE_name = zend_string_init_interned("PROPERTY_GRAPHEME_BASE", sizeof("PROPERTY_GRAPHEME_BASE") - 1, 1); + zend_string *const_PROPERTY_GRAPHEME_BASE_name = zend_string_init_interned("PROPERTY_GRAPHEME_BASE", sizeof("PROPERTY_GRAPHEME_BASE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_GRAPHEME_BASE_name, &const_PROPERTY_GRAPHEME_BASE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_GRAPHEME_BASE_name); + zend_string_release_ex(const_PROPERTY_GRAPHEME_BASE_name, true); zval const_PROPERTY_GRAPHEME_EXTEND_value; ZVAL_LONG(&const_PROPERTY_GRAPHEME_EXTEND_value, UCHAR_GRAPHEME_EXTEND); - zend_string *const_PROPERTY_GRAPHEME_EXTEND_name = zend_string_init_interned("PROPERTY_GRAPHEME_EXTEND", sizeof("PROPERTY_GRAPHEME_EXTEND") - 1, 1); + zend_string *const_PROPERTY_GRAPHEME_EXTEND_name = zend_string_init_interned("PROPERTY_GRAPHEME_EXTEND", sizeof("PROPERTY_GRAPHEME_EXTEND") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_GRAPHEME_EXTEND_name, &const_PROPERTY_GRAPHEME_EXTEND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_GRAPHEME_EXTEND_name); + zend_string_release_ex(const_PROPERTY_GRAPHEME_EXTEND_name, true); zval const_PROPERTY_GRAPHEME_LINK_value; ZVAL_LONG(&const_PROPERTY_GRAPHEME_LINK_value, UCHAR_GRAPHEME_LINK); - zend_string *const_PROPERTY_GRAPHEME_LINK_name = zend_string_init_interned("PROPERTY_GRAPHEME_LINK", sizeof("PROPERTY_GRAPHEME_LINK") - 1, 1); + zend_string *const_PROPERTY_GRAPHEME_LINK_name = zend_string_init_interned("PROPERTY_GRAPHEME_LINK", sizeof("PROPERTY_GRAPHEME_LINK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_GRAPHEME_LINK_name, &const_PROPERTY_GRAPHEME_LINK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_GRAPHEME_LINK_name); + zend_string_release_ex(const_PROPERTY_GRAPHEME_LINK_name, true); zval const_PROPERTY_HEX_DIGIT_value; ZVAL_LONG(&const_PROPERTY_HEX_DIGIT_value, UCHAR_HEX_DIGIT); - zend_string *const_PROPERTY_HEX_DIGIT_name = zend_string_init_interned("PROPERTY_HEX_DIGIT", sizeof("PROPERTY_HEX_DIGIT") - 1, 1); + zend_string *const_PROPERTY_HEX_DIGIT_name = zend_string_init_interned("PROPERTY_HEX_DIGIT", sizeof("PROPERTY_HEX_DIGIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_HEX_DIGIT_name, &const_PROPERTY_HEX_DIGIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_HEX_DIGIT_name); + zend_string_release_ex(const_PROPERTY_HEX_DIGIT_name, true); zval const_PROPERTY_HYPHEN_value; ZVAL_LONG(&const_PROPERTY_HYPHEN_value, UCHAR_HYPHEN); - zend_string *const_PROPERTY_HYPHEN_name = zend_string_init_interned("PROPERTY_HYPHEN", sizeof("PROPERTY_HYPHEN") - 1, 1); + zend_string *const_PROPERTY_HYPHEN_name = zend_string_init_interned("PROPERTY_HYPHEN", sizeof("PROPERTY_HYPHEN") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_HYPHEN_name, &const_PROPERTY_HYPHEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_HYPHEN_name); + zend_string_release_ex(const_PROPERTY_HYPHEN_name, true); zval const_PROPERTY_ID_CONTINUE_value; ZVAL_LONG(&const_PROPERTY_ID_CONTINUE_value, UCHAR_ID_CONTINUE); - zend_string *const_PROPERTY_ID_CONTINUE_name = zend_string_init_interned("PROPERTY_ID_CONTINUE", sizeof("PROPERTY_ID_CONTINUE") - 1, 1); + zend_string *const_PROPERTY_ID_CONTINUE_name = zend_string_init_interned("PROPERTY_ID_CONTINUE", sizeof("PROPERTY_ID_CONTINUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_ID_CONTINUE_name, &const_PROPERTY_ID_CONTINUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_ID_CONTINUE_name); + zend_string_release_ex(const_PROPERTY_ID_CONTINUE_name, true); zval const_PROPERTY_ID_START_value; ZVAL_LONG(&const_PROPERTY_ID_START_value, UCHAR_ID_START); - zend_string *const_PROPERTY_ID_START_name = zend_string_init_interned("PROPERTY_ID_START", sizeof("PROPERTY_ID_START") - 1, 1); + zend_string *const_PROPERTY_ID_START_name = zend_string_init_interned("PROPERTY_ID_START", sizeof("PROPERTY_ID_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_ID_START_name, &const_PROPERTY_ID_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_ID_START_name); + zend_string_release_ex(const_PROPERTY_ID_START_name, true); zval const_PROPERTY_IDEOGRAPHIC_value; ZVAL_LONG(&const_PROPERTY_IDEOGRAPHIC_value, UCHAR_IDEOGRAPHIC); - zend_string *const_PROPERTY_IDEOGRAPHIC_name = zend_string_init_interned("PROPERTY_IDEOGRAPHIC", sizeof("PROPERTY_IDEOGRAPHIC") - 1, 1); + zend_string *const_PROPERTY_IDEOGRAPHIC_name = zend_string_init_interned("PROPERTY_IDEOGRAPHIC", sizeof("PROPERTY_IDEOGRAPHIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_IDEOGRAPHIC_name, &const_PROPERTY_IDEOGRAPHIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_IDEOGRAPHIC_name); + zend_string_release_ex(const_PROPERTY_IDEOGRAPHIC_name, true); zval const_PROPERTY_IDS_BINARY_OPERATOR_value; ZVAL_LONG(&const_PROPERTY_IDS_BINARY_OPERATOR_value, UCHAR_IDS_BINARY_OPERATOR); - zend_string *const_PROPERTY_IDS_BINARY_OPERATOR_name = zend_string_init_interned("PROPERTY_IDS_BINARY_OPERATOR", sizeof("PROPERTY_IDS_BINARY_OPERATOR") - 1, 1); + zend_string *const_PROPERTY_IDS_BINARY_OPERATOR_name = zend_string_init_interned("PROPERTY_IDS_BINARY_OPERATOR", sizeof("PROPERTY_IDS_BINARY_OPERATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_IDS_BINARY_OPERATOR_name, &const_PROPERTY_IDS_BINARY_OPERATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_IDS_BINARY_OPERATOR_name); + zend_string_release_ex(const_PROPERTY_IDS_BINARY_OPERATOR_name, true); zval const_PROPERTY_IDS_TRINARY_OPERATOR_value; ZVAL_LONG(&const_PROPERTY_IDS_TRINARY_OPERATOR_value, UCHAR_IDS_TRINARY_OPERATOR); - zend_string *const_PROPERTY_IDS_TRINARY_OPERATOR_name = zend_string_init_interned("PROPERTY_IDS_TRINARY_OPERATOR", sizeof("PROPERTY_IDS_TRINARY_OPERATOR") - 1, 1); + zend_string *const_PROPERTY_IDS_TRINARY_OPERATOR_name = zend_string_init_interned("PROPERTY_IDS_TRINARY_OPERATOR", sizeof("PROPERTY_IDS_TRINARY_OPERATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_IDS_TRINARY_OPERATOR_name, &const_PROPERTY_IDS_TRINARY_OPERATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_IDS_TRINARY_OPERATOR_name); + zend_string_release_ex(const_PROPERTY_IDS_TRINARY_OPERATOR_name, true); #if U_ICU_VERSION_MAJOR_NUM >= 74 zval const_PROPERTY_IDS_UNARY_OPERATOR_value; ZVAL_LONG(&const_PROPERTY_IDS_UNARY_OPERATOR_value, UCHAR_IDS_UNARY_OPERATOR); - zend_string *const_PROPERTY_IDS_UNARY_OPERATOR_name = zend_string_init_interned("PROPERTY_IDS_UNARY_OPERATOR", sizeof("PROPERTY_IDS_UNARY_OPERATOR") - 1, 1); + zend_string *const_PROPERTY_IDS_UNARY_OPERATOR_name = zend_string_init_interned("PROPERTY_IDS_UNARY_OPERATOR", sizeof("PROPERTY_IDS_UNARY_OPERATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_IDS_UNARY_OPERATOR_name, &const_PROPERTY_IDS_UNARY_OPERATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_IDS_UNARY_OPERATOR_name); + zend_string_release_ex(const_PROPERTY_IDS_UNARY_OPERATOR_name, true); zval const_PROPERTY_ID_COMPAT_MATH_START_value; ZVAL_LONG(&const_PROPERTY_ID_COMPAT_MATH_START_value, UCHAR_ID_COMPAT_MATH_START); - zend_string *const_PROPERTY_ID_COMPAT_MATH_START_name = zend_string_init_interned("PROPERTY_ID_COMPAT_MATH_START", sizeof("PROPERTY_ID_COMPAT_MATH_START") - 1, 1); + zend_string *const_PROPERTY_ID_COMPAT_MATH_START_name = zend_string_init_interned("PROPERTY_ID_COMPAT_MATH_START", sizeof("PROPERTY_ID_COMPAT_MATH_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_ID_COMPAT_MATH_START_name, &const_PROPERTY_ID_COMPAT_MATH_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_ID_COMPAT_MATH_START_name); + zend_string_release_ex(const_PROPERTY_ID_COMPAT_MATH_START_name, true); zval const_PROPERTY_ID_COMPAT_MATH_CONTINUE_value; ZVAL_LONG(&const_PROPERTY_ID_COMPAT_MATH_CONTINUE_value, UCHAR_ID_COMPAT_MATH_CONTINUE); - zend_string *const_PROPERTY_ID_COMPAT_MATH_CONTINUE_name = zend_string_init_interned("PROPERTY_ID_COMPAT_MATH_CONTINUE", sizeof("PROPERTY_ID_COMPAT_MATH_CONTINUE") - 1, 1); + zend_string *const_PROPERTY_ID_COMPAT_MATH_CONTINUE_name = zend_string_init_interned("PROPERTY_ID_COMPAT_MATH_CONTINUE", sizeof("PROPERTY_ID_COMPAT_MATH_CONTINUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_ID_COMPAT_MATH_CONTINUE_name, &const_PROPERTY_ID_COMPAT_MATH_CONTINUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_ID_COMPAT_MATH_CONTINUE_name); + zend_string_release_ex(const_PROPERTY_ID_COMPAT_MATH_CONTINUE_name, true); #endif zval const_PROPERTY_JOIN_CONTROL_value; ZVAL_LONG(&const_PROPERTY_JOIN_CONTROL_value, UCHAR_JOIN_CONTROL); - zend_string *const_PROPERTY_JOIN_CONTROL_name = zend_string_init_interned("PROPERTY_JOIN_CONTROL", sizeof("PROPERTY_JOIN_CONTROL") - 1, 1); + zend_string *const_PROPERTY_JOIN_CONTROL_name = zend_string_init_interned("PROPERTY_JOIN_CONTROL", sizeof("PROPERTY_JOIN_CONTROL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_JOIN_CONTROL_name, &const_PROPERTY_JOIN_CONTROL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_JOIN_CONTROL_name); + zend_string_release_ex(const_PROPERTY_JOIN_CONTROL_name, true); zval const_PROPERTY_LOGICAL_ORDER_EXCEPTION_value; ZVAL_LONG(&const_PROPERTY_LOGICAL_ORDER_EXCEPTION_value, UCHAR_LOGICAL_ORDER_EXCEPTION); - zend_string *const_PROPERTY_LOGICAL_ORDER_EXCEPTION_name = zend_string_init_interned("PROPERTY_LOGICAL_ORDER_EXCEPTION", sizeof("PROPERTY_LOGICAL_ORDER_EXCEPTION") - 1, 1); + zend_string *const_PROPERTY_LOGICAL_ORDER_EXCEPTION_name = zend_string_init_interned("PROPERTY_LOGICAL_ORDER_EXCEPTION", sizeof("PROPERTY_LOGICAL_ORDER_EXCEPTION") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_LOGICAL_ORDER_EXCEPTION_name, &const_PROPERTY_LOGICAL_ORDER_EXCEPTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_LOGICAL_ORDER_EXCEPTION_name); + zend_string_release_ex(const_PROPERTY_LOGICAL_ORDER_EXCEPTION_name, true); zval const_PROPERTY_LOWERCASE_value; ZVAL_LONG(&const_PROPERTY_LOWERCASE_value, UCHAR_LOWERCASE); - zend_string *const_PROPERTY_LOWERCASE_name = zend_string_init_interned("PROPERTY_LOWERCASE", sizeof("PROPERTY_LOWERCASE") - 1, 1); + zend_string *const_PROPERTY_LOWERCASE_name = zend_string_init_interned("PROPERTY_LOWERCASE", sizeof("PROPERTY_LOWERCASE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_LOWERCASE_name, &const_PROPERTY_LOWERCASE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_LOWERCASE_name); + zend_string_release_ex(const_PROPERTY_LOWERCASE_name, true); zval const_PROPERTY_MATH_value; ZVAL_LONG(&const_PROPERTY_MATH_value, UCHAR_MATH); - zend_string *const_PROPERTY_MATH_name = zend_string_init_interned("PROPERTY_MATH", sizeof("PROPERTY_MATH") - 1, 1); + zend_string *const_PROPERTY_MATH_name = zend_string_init_interned("PROPERTY_MATH", sizeof("PROPERTY_MATH") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_MATH_name, &const_PROPERTY_MATH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_MATH_name); + zend_string_release_ex(const_PROPERTY_MATH_name, true); zval const_PROPERTY_NONCHARACTER_CODE_POINT_value; ZVAL_LONG(&const_PROPERTY_NONCHARACTER_CODE_POINT_value, UCHAR_NONCHARACTER_CODE_POINT); - zend_string *const_PROPERTY_NONCHARACTER_CODE_POINT_name = zend_string_init_interned("PROPERTY_NONCHARACTER_CODE_POINT", sizeof("PROPERTY_NONCHARACTER_CODE_POINT") - 1, 1); + zend_string *const_PROPERTY_NONCHARACTER_CODE_POINT_name = zend_string_init_interned("PROPERTY_NONCHARACTER_CODE_POINT", sizeof("PROPERTY_NONCHARACTER_CODE_POINT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NONCHARACTER_CODE_POINT_name, &const_PROPERTY_NONCHARACTER_CODE_POINT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NONCHARACTER_CODE_POINT_name); + zend_string_release_ex(const_PROPERTY_NONCHARACTER_CODE_POINT_name, true); zval const_PROPERTY_QUOTATION_MARK_value; ZVAL_LONG(&const_PROPERTY_QUOTATION_MARK_value, UCHAR_QUOTATION_MARK); - zend_string *const_PROPERTY_QUOTATION_MARK_name = zend_string_init_interned("PROPERTY_QUOTATION_MARK", sizeof("PROPERTY_QUOTATION_MARK") - 1, 1); + zend_string *const_PROPERTY_QUOTATION_MARK_name = zend_string_init_interned("PROPERTY_QUOTATION_MARK", sizeof("PROPERTY_QUOTATION_MARK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_QUOTATION_MARK_name, &const_PROPERTY_QUOTATION_MARK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_QUOTATION_MARK_name); + zend_string_release_ex(const_PROPERTY_QUOTATION_MARK_name, true); zval const_PROPERTY_RADICAL_value; ZVAL_LONG(&const_PROPERTY_RADICAL_value, UCHAR_RADICAL); - zend_string *const_PROPERTY_RADICAL_name = zend_string_init_interned("PROPERTY_RADICAL", sizeof("PROPERTY_RADICAL") - 1, 1); + zend_string *const_PROPERTY_RADICAL_name = zend_string_init_interned("PROPERTY_RADICAL", sizeof("PROPERTY_RADICAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_RADICAL_name, &const_PROPERTY_RADICAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_RADICAL_name); + zend_string_release_ex(const_PROPERTY_RADICAL_name, true); zval const_PROPERTY_SOFT_DOTTED_value; ZVAL_LONG(&const_PROPERTY_SOFT_DOTTED_value, UCHAR_SOFT_DOTTED); - zend_string *const_PROPERTY_SOFT_DOTTED_name = zend_string_init_interned("PROPERTY_SOFT_DOTTED", sizeof("PROPERTY_SOFT_DOTTED") - 1, 1); + zend_string *const_PROPERTY_SOFT_DOTTED_name = zend_string_init_interned("PROPERTY_SOFT_DOTTED", sizeof("PROPERTY_SOFT_DOTTED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SOFT_DOTTED_name, &const_PROPERTY_SOFT_DOTTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SOFT_DOTTED_name); + zend_string_release_ex(const_PROPERTY_SOFT_DOTTED_name, true); zval const_PROPERTY_TERMINAL_PUNCTUATION_value; ZVAL_LONG(&const_PROPERTY_TERMINAL_PUNCTUATION_value, UCHAR_TERMINAL_PUNCTUATION); - zend_string *const_PROPERTY_TERMINAL_PUNCTUATION_name = zend_string_init_interned("PROPERTY_TERMINAL_PUNCTUATION", sizeof("PROPERTY_TERMINAL_PUNCTUATION") - 1, 1); + zend_string *const_PROPERTY_TERMINAL_PUNCTUATION_name = zend_string_init_interned("PROPERTY_TERMINAL_PUNCTUATION", sizeof("PROPERTY_TERMINAL_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_TERMINAL_PUNCTUATION_name, &const_PROPERTY_TERMINAL_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_TERMINAL_PUNCTUATION_name); + zend_string_release_ex(const_PROPERTY_TERMINAL_PUNCTUATION_name, true); zval const_PROPERTY_UNIFIED_IDEOGRAPH_value; ZVAL_LONG(&const_PROPERTY_UNIFIED_IDEOGRAPH_value, UCHAR_UNIFIED_IDEOGRAPH); - zend_string *const_PROPERTY_UNIFIED_IDEOGRAPH_name = zend_string_init_interned("PROPERTY_UNIFIED_IDEOGRAPH", sizeof("PROPERTY_UNIFIED_IDEOGRAPH") - 1, 1); + zend_string *const_PROPERTY_UNIFIED_IDEOGRAPH_name = zend_string_init_interned("PROPERTY_UNIFIED_IDEOGRAPH", sizeof("PROPERTY_UNIFIED_IDEOGRAPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_UNIFIED_IDEOGRAPH_name, &const_PROPERTY_UNIFIED_IDEOGRAPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_UNIFIED_IDEOGRAPH_name); + zend_string_release_ex(const_PROPERTY_UNIFIED_IDEOGRAPH_name, true); zval const_PROPERTY_UPPERCASE_value; ZVAL_LONG(&const_PROPERTY_UPPERCASE_value, UCHAR_UPPERCASE); - zend_string *const_PROPERTY_UPPERCASE_name = zend_string_init_interned("PROPERTY_UPPERCASE", sizeof("PROPERTY_UPPERCASE") - 1, 1); + zend_string *const_PROPERTY_UPPERCASE_name = zend_string_init_interned("PROPERTY_UPPERCASE", sizeof("PROPERTY_UPPERCASE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_UPPERCASE_name, &const_PROPERTY_UPPERCASE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_UPPERCASE_name); + zend_string_release_ex(const_PROPERTY_UPPERCASE_name, true); zval const_PROPERTY_WHITE_SPACE_value; ZVAL_LONG(&const_PROPERTY_WHITE_SPACE_value, UCHAR_WHITE_SPACE); - zend_string *const_PROPERTY_WHITE_SPACE_name = zend_string_init_interned("PROPERTY_WHITE_SPACE", sizeof("PROPERTY_WHITE_SPACE") - 1, 1); + zend_string *const_PROPERTY_WHITE_SPACE_name = zend_string_init_interned("PROPERTY_WHITE_SPACE", sizeof("PROPERTY_WHITE_SPACE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_WHITE_SPACE_name, &const_PROPERTY_WHITE_SPACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_WHITE_SPACE_name); + zend_string_release_ex(const_PROPERTY_WHITE_SPACE_name, true); zval const_PROPERTY_XID_CONTINUE_value; ZVAL_LONG(&const_PROPERTY_XID_CONTINUE_value, UCHAR_XID_CONTINUE); - zend_string *const_PROPERTY_XID_CONTINUE_name = zend_string_init_interned("PROPERTY_XID_CONTINUE", sizeof("PROPERTY_XID_CONTINUE") - 1, 1); + zend_string *const_PROPERTY_XID_CONTINUE_name = zend_string_init_interned("PROPERTY_XID_CONTINUE", sizeof("PROPERTY_XID_CONTINUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_XID_CONTINUE_name, &const_PROPERTY_XID_CONTINUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_XID_CONTINUE_name); + zend_string_release_ex(const_PROPERTY_XID_CONTINUE_name, true); zval const_PROPERTY_XID_START_value; ZVAL_LONG(&const_PROPERTY_XID_START_value, UCHAR_XID_START); - zend_string *const_PROPERTY_XID_START_name = zend_string_init_interned("PROPERTY_XID_START", sizeof("PROPERTY_XID_START") - 1, 1); + zend_string *const_PROPERTY_XID_START_name = zend_string_init_interned("PROPERTY_XID_START", sizeof("PROPERTY_XID_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_XID_START_name, &const_PROPERTY_XID_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_XID_START_name); + zend_string_release_ex(const_PROPERTY_XID_START_name, true); zval const_PROPERTY_CASE_SENSITIVE_value; ZVAL_LONG(&const_PROPERTY_CASE_SENSITIVE_value, UCHAR_CASE_SENSITIVE); - zend_string *const_PROPERTY_CASE_SENSITIVE_name = zend_string_init_interned("PROPERTY_CASE_SENSITIVE", sizeof("PROPERTY_CASE_SENSITIVE") - 1, 1); + zend_string *const_PROPERTY_CASE_SENSITIVE_name = zend_string_init_interned("PROPERTY_CASE_SENSITIVE", sizeof("PROPERTY_CASE_SENSITIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CASE_SENSITIVE_name, &const_PROPERTY_CASE_SENSITIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CASE_SENSITIVE_name); + zend_string_release_ex(const_PROPERTY_CASE_SENSITIVE_name, true); zval const_PROPERTY_S_TERM_value; ZVAL_LONG(&const_PROPERTY_S_TERM_value, UCHAR_S_TERM); - zend_string *const_PROPERTY_S_TERM_name = zend_string_init_interned("PROPERTY_S_TERM", sizeof("PROPERTY_S_TERM") - 1, 1); + zend_string *const_PROPERTY_S_TERM_name = zend_string_init_interned("PROPERTY_S_TERM", sizeof("PROPERTY_S_TERM") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_S_TERM_name, &const_PROPERTY_S_TERM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_S_TERM_name); + zend_string_release_ex(const_PROPERTY_S_TERM_name, true); zval const_PROPERTY_VARIATION_SELECTOR_value; ZVAL_LONG(&const_PROPERTY_VARIATION_SELECTOR_value, UCHAR_VARIATION_SELECTOR); - zend_string *const_PROPERTY_VARIATION_SELECTOR_name = zend_string_init_interned("PROPERTY_VARIATION_SELECTOR", sizeof("PROPERTY_VARIATION_SELECTOR") - 1, 1); + zend_string *const_PROPERTY_VARIATION_SELECTOR_name = zend_string_init_interned("PROPERTY_VARIATION_SELECTOR", sizeof("PROPERTY_VARIATION_SELECTOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_VARIATION_SELECTOR_name, &const_PROPERTY_VARIATION_SELECTOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_VARIATION_SELECTOR_name); + zend_string_release_ex(const_PROPERTY_VARIATION_SELECTOR_name, true); zval const_PROPERTY_NFD_INERT_value; ZVAL_LONG(&const_PROPERTY_NFD_INERT_value, UCHAR_NFD_INERT); - zend_string *const_PROPERTY_NFD_INERT_name = zend_string_init_interned("PROPERTY_NFD_INERT", sizeof("PROPERTY_NFD_INERT") - 1, 1); + zend_string *const_PROPERTY_NFD_INERT_name = zend_string_init_interned("PROPERTY_NFD_INERT", sizeof("PROPERTY_NFD_INERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFD_INERT_name, &const_PROPERTY_NFD_INERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFD_INERT_name); + zend_string_release_ex(const_PROPERTY_NFD_INERT_name, true); zval const_PROPERTY_NFKD_INERT_value; ZVAL_LONG(&const_PROPERTY_NFKD_INERT_value, UCHAR_NFKD_INERT); - zend_string *const_PROPERTY_NFKD_INERT_name = zend_string_init_interned("PROPERTY_NFKD_INERT", sizeof("PROPERTY_NFKD_INERT") - 1, 1); + zend_string *const_PROPERTY_NFKD_INERT_name = zend_string_init_interned("PROPERTY_NFKD_INERT", sizeof("PROPERTY_NFKD_INERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFKD_INERT_name, &const_PROPERTY_NFKD_INERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFKD_INERT_name); + zend_string_release_ex(const_PROPERTY_NFKD_INERT_name, true); zval const_PROPERTY_NFC_INERT_value; ZVAL_LONG(&const_PROPERTY_NFC_INERT_value, UCHAR_NFC_INERT); - zend_string *const_PROPERTY_NFC_INERT_name = zend_string_init_interned("PROPERTY_NFC_INERT", sizeof("PROPERTY_NFC_INERT") - 1, 1); + zend_string *const_PROPERTY_NFC_INERT_name = zend_string_init_interned("PROPERTY_NFC_INERT", sizeof("PROPERTY_NFC_INERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFC_INERT_name, &const_PROPERTY_NFC_INERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFC_INERT_name); + zend_string_release_ex(const_PROPERTY_NFC_INERT_name, true); zval const_PROPERTY_NFKC_INERT_value; ZVAL_LONG(&const_PROPERTY_NFKC_INERT_value, UCHAR_NFKC_INERT); - zend_string *const_PROPERTY_NFKC_INERT_name = zend_string_init_interned("PROPERTY_NFKC_INERT", sizeof("PROPERTY_NFKC_INERT") - 1, 1); + zend_string *const_PROPERTY_NFKC_INERT_name = zend_string_init_interned("PROPERTY_NFKC_INERT", sizeof("PROPERTY_NFKC_INERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFKC_INERT_name, &const_PROPERTY_NFKC_INERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFKC_INERT_name); + zend_string_release_ex(const_PROPERTY_NFKC_INERT_name, true); zval const_PROPERTY_SEGMENT_STARTER_value; ZVAL_LONG(&const_PROPERTY_SEGMENT_STARTER_value, UCHAR_SEGMENT_STARTER); - zend_string *const_PROPERTY_SEGMENT_STARTER_name = zend_string_init_interned("PROPERTY_SEGMENT_STARTER", sizeof("PROPERTY_SEGMENT_STARTER") - 1, 1); + zend_string *const_PROPERTY_SEGMENT_STARTER_name = zend_string_init_interned("PROPERTY_SEGMENT_STARTER", sizeof("PROPERTY_SEGMENT_STARTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SEGMENT_STARTER_name, &const_PROPERTY_SEGMENT_STARTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SEGMENT_STARTER_name); + zend_string_release_ex(const_PROPERTY_SEGMENT_STARTER_name, true); zval const_PROPERTY_PATTERN_SYNTAX_value; ZVAL_LONG(&const_PROPERTY_PATTERN_SYNTAX_value, UCHAR_PATTERN_SYNTAX); - zend_string *const_PROPERTY_PATTERN_SYNTAX_name = zend_string_init_interned("PROPERTY_PATTERN_SYNTAX", sizeof("PROPERTY_PATTERN_SYNTAX") - 1, 1); + zend_string *const_PROPERTY_PATTERN_SYNTAX_name = zend_string_init_interned("PROPERTY_PATTERN_SYNTAX", sizeof("PROPERTY_PATTERN_SYNTAX") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_PATTERN_SYNTAX_name, &const_PROPERTY_PATTERN_SYNTAX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_PATTERN_SYNTAX_name); + zend_string_release_ex(const_PROPERTY_PATTERN_SYNTAX_name, true); zval const_PROPERTY_PATTERN_WHITE_SPACE_value; ZVAL_LONG(&const_PROPERTY_PATTERN_WHITE_SPACE_value, UCHAR_PATTERN_WHITE_SPACE); - zend_string *const_PROPERTY_PATTERN_WHITE_SPACE_name = zend_string_init_interned("PROPERTY_PATTERN_WHITE_SPACE", sizeof("PROPERTY_PATTERN_WHITE_SPACE") - 1, 1); + zend_string *const_PROPERTY_PATTERN_WHITE_SPACE_name = zend_string_init_interned("PROPERTY_PATTERN_WHITE_SPACE", sizeof("PROPERTY_PATTERN_WHITE_SPACE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_PATTERN_WHITE_SPACE_name, &const_PROPERTY_PATTERN_WHITE_SPACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_PATTERN_WHITE_SPACE_name); + zend_string_release_ex(const_PROPERTY_PATTERN_WHITE_SPACE_name, true); zval const_PROPERTY_POSIX_ALNUM_value; ZVAL_LONG(&const_PROPERTY_POSIX_ALNUM_value, UCHAR_POSIX_ALNUM); - zend_string *const_PROPERTY_POSIX_ALNUM_name = zend_string_init_interned("PROPERTY_POSIX_ALNUM", sizeof("PROPERTY_POSIX_ALNUM") - 1, 1); + zend_string *const_PROPERTY_POSIX_ALNUM_name = zend_string_init_interned("PROPERTY_POSIX_ALNUM", sizeof("PROPERTY_POSIX_ALNUM") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_POSIX_ALNUM_name, &const_PROPERTY_POSIX_ALNUM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_POSIX_ALNUM_name); + zend_string_release_ex(const_PROPERTY_POSIX_ALNUM_name, true); zval const_PROPERTY_POSIX_BLANK_value; ZVAL_LONG(&const_PROPERTY_POSIX_BLANK_value, UCHAR_POSIX_BLANK); - zend_string *const_PROPERTY_POSIX_BLANK_name = zend_string_init_interned("PROPERTY_POSIX_BLANK", sizeof("PROPERTY_POSIX_BLANK") - 1, 1); + zend_string *const_PROPERTY_POSIX_BLANK_name = zend_string_init_interned("PROPERTY_POSIX_BLANK", sizeof("PROPERTY_POSIX_BLANK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_POSIX_BLANK_name, &const_PROPERTY_POSIX_BLANK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_POSIX_BLANK_name); + zend_string_release_ex(const_PROPERTY_POSIX_BLANK_name, true); zval const_PROPERTY_POSIX_GRAPH_value; ZVAL_LONG(&const_PROPERTY_POSIX_GRAPH_value, UCHAR_POSIX_GRAPH); - zend_string *const_PROPERTY_POSIX_GRAPH_name = zend_string_init_interned("PROPERTY_POSIX_GRAPH", sizeof("PROPERTY_POSIX_GRAPH") - 1, 1); + zend_string *const_PROPERTY_POSIX_GRAPH_name = zend_string_init_interned("PROPERTY_POSIX_GRAPH", sizeof("PROPERTY_POSIX_GRAPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_POSIX_GRAPH_name, &const_PROPERTY_POSIX_GRAPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_POSIX_GRAPH_name); + zend_string_release_ex(const_PROPERTY_POSIX_GRAPH_name, true); zval const_PROPERTY_POSIX_PRINT_value; ZVAL_LONG(&const_PROPERTY_POSIX_PRINT_value, UCHAR_POSIX_PRINT); - zend_string *const_PROPERTY_POSIX_PRINT_name = zend_string_init_interned("PROPERTY_POSIX_PRINT", sizeof("PROPERTY_POSIX_PRINT") - 1, 1); + zend_string *const_PROPERTY_POSIX_PRINT_name = zend_string_init_interned("PROPERTY_POSIX_PRINT", sizeof("PROPERTY_POSIX_PRINT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_POSIX_PRINT_name, &const_PROPERTY_POSIX_PRINT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_POSIX_PRINT_name); + zend_string_release_ex(const_PROPERTY_POSIX_PRINT_name, true); zval const_PROPERTY_POSIX_XDIGIT_value; ZVAL_LONG(&const_PROPERTY_POSIX_XDIGIT_value, UCHAR_POSIX_XDIGIT); - zend_string *const_PROPERTY_POSIX_XDIGIT_name = zend_string_init_interned("PROPERTY_POSIX_XDIGIT", sizeof("PROPERTY_POSIX_XDIGIT") - 1, 1); + zend_string *const_PROPERTY_POSIX_XDIGIT_name = zend_string_init_interned("PROPERTY_POSIX_XDIGIT", sizeof("PROPERTY_POSIX_XDIGIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_POSIX_XDIGIT_name, &const_PROPERTY_POSIX_XDIGIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_POSIX_XDIGIT_name); + zend_string_release_ex(const_PROPERTY_POSIX_XDIGIT_name, true); zval const_PROPERTY_CASED_value; ZVAL_LONG(&const_PROPERTY_CASED_value, UCHAR_CASED); - zend_string *const_PROPERTY_CASED_name = zend_string_init_interned("PROPERTY_CASED", sizeof("PROPERTY_CASED") - 1, 1); + zend_string *const_PROPERTY_CASED_name = zend_string_init_interned("PROPERTY_CASED", sizeof("PROPERTY_CASED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CASED_name, &const_PROPERTY_CASED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CASED_name); + zend_string_release_ex(const_PROPERTY_CASED_name, true); zval const_PROPERTY_CASE_IGNORABLE_value; ZVAL_LONG(&const_PROPERTY_CASE_IGNORABLE_value, UCHAR_CASE_IGNORABLE); - zend_string *const_PROPERTY_CASE_IGNORABLE_name = zend_string_init_interned("PROPERTY_CASE_IGNORABLE", sizeof("PROPERTY_CASE_IGNORABLE") - 1, 1); + zend_string *const_PROPERTY_CASE_IGNORABLE_name = zend_string_init_interned("PROPERTY_CASE_IGNORABLE", sizeof("PROPERTY_CASE_IGNORABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CASE_IGNORABLE_name, &const_PROPERTY_CASE_IGNORABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CASE_IGNORABLE_name); + zend_string_release_ex(const_PROPERTY_CASE_IGNORABLE_name, true); zval const_PROPERTY_CHANGES_WHEN_LOWERCASED_value; ZVAL_LONG(&const_PROPERTY_CHANGES_WHEN_LOWERCASED_value, UCHAR_CHANGES_WHEN_LOWERCASED); - zend_string *const_PROPERTY_CHANGES_WHEN_LOWERCASED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_LOWERCASED", sizeof("PROPERTY_CHANGES_WHEN_LOWERCASED") - 1, 1); + zend_string *const_PROPERTY_CHANGES_WHEN_LOWERCASED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_LOWERCASED", sizeof("PROPERTY_CHANGES_WHEN_LOWERCASED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CHANGES_WHEN_LOWERCASED_name, &const_PROPERTY_CHANGES_WHEN_LOWERCASED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CHANGES_WHEN_LOWERCASED_name); + zend_string_release_ex(const_PROPERTY_CHANGES_WHEN_LOWERCASED_name, true); zval const_PROPERTY_CHANGES_WHEN_UPPERCASED_value; ZVAL_LONG(&const_PROPERTY_CHANGES_WHEN_UPPERCASED_value, UCHAR_CHANGES_WHEN_UPPERCASED); - zend_string *const_PROPERTY_CHANGES_WHEN_UPPERCASED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_UPPERCASED", sizeof("PROPERTY_CHANGES_WHEN_UPPERCASED") - 1, 1); + zend_string *const_PROPERTY_CHANGES_WHEN_UPPERCASED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_UPPERCASED", sizeof("PROPERTY_CHANGES_WHEN_UPPERCASED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CHANGES_WHEN_UPPERCASED_name, &const_PROPERTY_CHANGES_WHEN_UPPERCASED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CHANGES_WHEN_UPPERCASED_name); + zend_string_release_ex(const_PROPERTY_CHANGES_WHEN_UPPERCASED_name, true); zval const_PROPERTY_CHANGES_WHEN_TITLECASED_value; ZVAL_LONG(&const_PROPERTY_CHANGES_WHEN_TITLECASED_value, UCHAR_CHANGES_WHEN_TITLECASED); - zend_string *const_PROPERTY_CHANGES_WHEN_TITLECASED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_TITLECASED", sizeof("PROPERTY_CHANGES_WHEN_TITLECASED") - 1, 1); + zend_string *const_PROPERTY_CHANGES_WHEN_TITLECASED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_TITLECASED", sizeof("PROPERTY_CHANGES_WHEN_TITLECASED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CHANGES_WHEN_TITLECASED_name, &const_PROPERTY_CHANGES_WHEN_TITLECASED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CHANGES_WHEN_TITLECASED_name); + zend_string_release_ex(const_PROPERTY_CHANGES_WHEN_TITLECASED_name, true); zval const_PROPERTY_CHANGES_WHEN_CASEFOLDED_value; ZVAL_LONG(&const_PROPERTY_CHANGES_WHEN_CASEFOLDED_value, UCHAR_CHANGES_WHEN_CASEFOLDED); - zend_string *const_PROPERTY_CHANGES_WHEN_CASEFOLDED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_CASEFOLDED", sizeof("PROPERTY_CHANGES_WHEN_CASEFOLDED") - 1, 1); + zend_string *const_PROPERTY_CHANGES_WHEN_CASEFOLDED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_CASEFOLDED", sizeof("PROPERTY_CHANGES_WHEN_CASEFOLDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CHANGES_WHEN_CASEFOLDED_name, &const_PROPERTY_CHANGES_WHEN_CASEFOLDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CHANGES_WHEN_CASEFOLDED_name); + zend_string_release_ex(const_PROPERTY_CHANGES_WHEN_CASEFOLDED_name, true); zval const_PROPERTY_CHANGES_WHEN_CASEMAPPED_value; ZVAL_LONG(&const_PROPERTY_CHANGES_WHEN_CASEMAPPED_value, UCHAR_CHANGES_WHEN_CASEMAPPED); - zend_string *const_PROPERTY_CHANGES_WHEN_CASEMAPPED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_CASEMAPPED", sizeof("PROPERTY_CHANGES_WHEN_CASEMAPPED") - 1, 1); + zend_string *const_PROPERTY_CHANGES_WHEN_CASEMAPPED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_CASEMAPPED", sizeof("PROPERTY_CHANGES_WHEN_CASEMAPPED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CHANGES_WHEN_CASEMAPPED_name, &const_PROPERTY_CHANGES_WHEN_CASEMAPPED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CHANGES_WHEN_CASEMAPPED_name); + zend_string_release_ex(const_PROPERTY_CHANGES_WHEN_CASEMAPPED_name, true); zval const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_value; ZVAL_LONG(&const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_value, UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED); - zend_string *const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED", sizeof("PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED") - 1, 1); + zend_string *const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_name = zend_string_init_interned("PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED", sizeof("PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_name, &const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_name); + zend_string_release_ex(const_PROPERTY_CHANGES_WHEN_NFKC_CASEFOLDED_name, true); zval const_PROPERTY_BINARY_LIMIT_value; ZVAL_LONG(&const_PROPERTY_BINARY_LIMIT_value, UCHAR_BINARY_LIMIT); - zend_string *const_PROPERTY_BINARY_LIMIT_name = zend_string_init_interned("PROPERTY_BINARY_LIMIT", sizeof("PROPERTY_BINARY_LIMIT") - 1, 1); + zend_string *const_PROPERTY_BINARY_LIMIT_name = zend_string_init_interned("PROPERTY_BINARY_LIMIT", sizeof("PROPERTY_BINARY_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BINARY_LIMIT_name, &const_PROPERTY_BINARY_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BINARY_LIMIT_name); + zend_string_release_ex(const_PROPERTY_BINARY_LIMIT_name, true); zval const_PROPERTY_BIDI_CLASS_value; ZVAL_LONG(&const_PROPERTY_BIDI_CLASS_value, UCHAR_BIDI_CLASS); - zend_string *const_PROPERTY_BIDI_CLASS_name = zend_string_init_interned("PROPERTY_BIDI_CLASS", sizeof("PROPERTY_BIDI_CLASS") - 1, 1); + zend_string *const_PROPERTY_BIDI_CLASS_name = zend_string_init_interned("PROPERTY_BIDI_CLASS", sizeof("PROPERTY_BIDI_CLASS") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BIDI_CLASS_name, &const_PROPERTY_BIDI_CLASS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BIDI_CLASS_name); + zend_string_release_ex(const_PROPERTY_BIDI_CLASS_name, true); zval const_PROPERTY_INT_START_value; ZVAL_LONG(&const_PROPERTY_INT_START_value, UCHAR_INT_START); - zend_string *const_PROPERTY_INT_START_name = zend_string_init_interned("PROPERTY_INT_START", sizeof("PROPERTY_INT_START") - 1, 1); + zend_string *const_PROPERTY_INT_START_name = zend_string_init_interned("PROPERTY_INT_START", sizeof("PROPERTY_INT_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_INT_START_name, &const_PROPERTY_INT_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_INT_START_name); + zend_string_release_ex(const_PROPERTY_INT_START_name, true); zval const_PROPERTY_BLOCK_value; ZVAL_LONG(&const_PROPERTY_BLOCK_value, UCHAR_BLOCK); - zend_string *const_PROPERTY_BLOCK_name = zend_string_init_interned("PROPERTY_BLOCK", sizeof("PROPERTY_BLOCK") - 1, 1); + zend_string *const_PROPERTY_BLOCK_name = zend_string_init_interned("PROPERTY_BLOCK", sizeof("PROPERTY_BLOCK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BLOCK_name, &const_PROPERTY_BLOCK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BLOCK_name); + zend_string_release_ex(const_PROPERTY_BLOCK_name, true); zval const_PROPERTY_CANONICAL_COMBINING_CLASS_value; ZVAL_LONG(&const_PROPERTY_CANONICAL_COMBINING_CLASS_value, UCHAR_CANONICAL_COMBINING_CLASS); - zend_string *const_PROPERTY_CANONICAL_COMBINING_CLASS_name = zend_string_init_interned("PROPERTY_CANONICAL_COMBINING_CLASS", sizeof("PROPERTY_CANONICAL_COMBINING_CLASS") - 1, 1); + zend_string *const_PROPERTY_CANONICAL_COMBINING_CLASS_name = zend_string_init_interned("PROPERTY_CANONICAL_COMBINING_CLASS", sizeof("PROPERTY_CANONICAL_COMBINING_CLASS") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CANONICAL_COMBINING_CLASS_name, &const_PROPERTY_CANONICAL_COMBINING_CLASS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CANONICAL_COMBINING_CLASS_name); + zend_string_release_ex(const_PROPERTY_CANONICAL_COMBINING_CLASS_name, true); zval const_PROPERTY_DECOMPOSITION_TYPE_value; ZVAL_LONG(&const_PROPERTY_DECOMPOSITION_TYPE_value, UCHAR_DECOMPOSITION_TYPE); - zend_string *const_PROPERTY_DECOMPOSITION_TYPE_name = zend_string_init_interned("PROPERTY_DECOMPOSITION_TYPE", sizeof("PROPERTY_DECOMPOSITION_TYPE") - 1, 1); + zend_string *const_PROPERTY_DECOMPOSITION_TYPE_name = zend_string_init_interned("PROPERTY_DECOMPOSITION_TYPE", sizeof("PROPERTY_DECOMPOSITION_TYPE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_DECOMPOSITION_TYPE_name, &const_PROPERTY_DECOMPOSITION_TYPE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_DECOMPOSITION_TYPE_name); + zend_string_release_ex(const_PROPERTY_DECOMPOSITION_TYPE_name, true); zval const_PROPERTY_EAST_ASIAN_WIDTH_value; ZVAL_LONG(&const_PROPERTY_EAST_ASIAN_WIDTH_value, UCHAR_EAST_ASIAN_WIDTH); - zend_string *const_PROPERTY_EAST_ASIAN_WIDTH_name = zend_string_init_interned("PROPERTY_EAST_ASIAN_WIDTH", sizeof("PROPERTY_EAST_ASIAN_WIDTH") - 1, 1); + zend_string *const_PROPERTY_EAST_ASIAN_WIDTH_name = zend_string_init_interned("PROPERTY_EAST_ASIAN_WIDTH", sizeof("PROPERTY_EAST_ASIAN_WIDTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_EAST_ASIAN_WIDTH_name, &const_PROPERTY_EAST_ASIAN_WIDTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_EAST_ASIAN_WIDTH_name); + zend_string_release_ex(const_PROPERTY_EAST_ASIAN_WIDTH_name, true); zval const_PROPERTY_GENERAL_CATEGORY_value; ZVAL_LONG(&const_PROPERTY_GENERAL_CATEGORY_value, UCHAR_GENERAL_CATEGORY); - zend_string *const_PROPERTY_GENERAL_CATEGORY_name = zend_string_init_interned("PROPERTY_GENERAL_CATEGORY", sizeof("PROPERTY_GENERAL_CATEGORY") - 1, 1); + zend_string *const_PROPERTY_GENERAL_CATEGORY_name = zend_string_init_interned("PROPERTY_GENERAL_CATEGORY", sizeof("PROPERTY_GENERAL_CATEGORY") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_GENERAL_CATEGORY_name, &const_PROPERTY_GENERAL_CATEGORY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_GENERAL_CATEGORY_name); + zend_string_release_ex(const_PROPERTY_GENERAL_CATEGORY_name, true); zval const_PROPERTY_JOINING_GROUP_value; ZVAL_LONG(&const_PROPERTY_JOINING_GROUP_value, UCHAR_JOINING_GROUP); - zend_string *const_PROPERTY_JOINING_GROUP_name = zend_string_init_interned("PROPERTY_JOINING_GROUP", sizeof("PROPERTY_JOINING_GROUP") - 1, 1); + zend_string *const_PROPERTY_JOINING_GROUP_name = zend_string_init_interned("PROPERTY_JOINING_GROUP", sizeof("PROPERTY_JOINING_GROUP") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_JOINING_GROUP_name, &const_PROPERTY_JOINING_GROUP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_JOINING_GROUP_name); + zend_string_release_ex(const_PROPERTY_JOINING_GROUP_name, true); zval const_PROPERTY_JOINING_TYPE_value; ZVAL_LONG(&const_PROPERTY_JOINING_TYPE_value, UCHAR_JOINING_TYPE); - zend_string *const_PROPERTY_JOINING_TYPE_name = zend_string_init_interned("PROPERTY_JOINING_TYPE", sizeof("PROPERTY_JOINING_TYPE") - 1, 1); + zend_string *const_PROPERTY_JOINING_TYPE_name = zend_string_init_interned("PROPERTY_JOINING_TYPE", sizeof("PROPERTY_JOINING_TYPE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_JOINING_TYPE_name, &const_PROPERTY_JOINING_TYPE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_JOINING_TYPE_name); + zend_string_release_ex(const_PROPERTY_JOINING_TYPE_name, true); zval const_PROPERTY_LINE_BREAK_value; ZVAL_LONG(&const_PROPERTY_LINE_BREAK_value, UCHAR_LINE_BREAK); - zend_string *const_PROPERTY_LINE_BREAK_name = zend_string_init_interned("PROPERTY_LINE_BREAK", sizeof("PROPERTY_LINE_BREAK") - 1, 1); + zend_string *const_PROPERTY_LINE_BREAK_name = zend_string_init_interned("PROPERTY_LINE_BREAK", sizeof("PROPERTY_LINE_BREAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_LINE_BREAK_name, &const_PROPERTY_LINE_BREAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_LINE_BREAK_name); + zend_string_release_ex(const_PROPERTY_LINE_BREAK_name, true); zval const_PROPERTY_NUMERIC_TYPE_value; ZVAL_LONG(&const_PROPERTY_NUMERIC_TYPE_value, UCHAR_NUMERIC_TYPE); - zend_string *const_PROPERTY_NUMERIC_TYPE_name = zend_string_init_interned("PROPERTY_NUMERIC_TYPE", sizeof("PROPERTY_NUMERIC_TYPE") - 1, 1); + zend_string *const_PROPERTY_NUMERIC_TYPE_name = zend_string_init_interned("PROPERTY_NUMERIC_TYPE", sizeof("PROPERTY_NUMERIC_TYPE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NUMERIC_TYPE_name, &const_PROPERTY_NUMERIC_TYPE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NUMERIC_TYPE_name); + zend_string_release_ex(const_PROPERTY_NUMERIC_TYPE_name, true); zval const_PROPERTY_SCRIPT_value; ZVAL_LONG(&const_PROPERTY_SCRIPT_value, UCHAR_SCRIPT); - zend_string *const_PROPERTY_SCRIPT_name = zend_string_init_interned("PROPERTY_SCRIPT", sizeof("PROPERTY_SCRIPT") - 1, 1); + zend_string *const_PROPERTY_SCRIPT_name = zend_string_init_interned("PROPERTY_SCRIPT", sizeof("PROPERTY_SCRIPT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SCRIPT_name, &const_PROPERTY_SCRIPT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SCRIPT_name); + zend_string_release_ex(const_PROPERTY_SCRIPT_name, true); zval const_PROPERTY_HANGUL_SYLLABLE_TYPE_value; ZVAL_LONG(&const_PROPERTY_HANGUL_SYLLABLE_TYPE_value, UCHAR_HANGUL_SYLLABLE_TYPE); - zend_string *const_PROPERTY_HANGUL_SYLLABLE_TYPE_name = zend_string_init_interned("PROPERTY_HANGUL_SYLLABLE_TYPE", sizeof("PROPERTY_HANGUL_SYLLABLE_TYPE") - 1, 1); + zend_string *const_PROPERTY_HANGUL_SYLLABLE_TYPE_name = zend_string_init_interned("PROPERTY_HANGUL_SYLLABLE_TYPE", sizeof("PROPERTY_HANGUL_SYLLABLE_TYPE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_HANGUL_SYLLABLE_TYPE_name, &const_PROPERTY_HANGUL_SYLLABLE_TYPE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_HANGUL_SYLLABLE_TYPE_name); + zend_string_release_ex(const_PROPERTY_HANGUL_SYLLABLE_TYPE_name, true); zval const_PROPERTY_NFD_QUICK_CHECK_value; ZVAL_LONG(&const_PROPERTY_NFD_QUICK_CHECK_value, UCHAR_NFD_QUICK_CHECK); - zend_string *const_PROPERTY_NFD_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFD_QUICK_CHECK", sizeof("PROPERTY_NFD_QUICK_CHECK") - 1, 1); + zend_string *const_PROPERTY_NFD_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFD_QUICK_CHECK", sizeof("PROPERTY_NFD_QUICK_CHECK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFD_QUICK_CHECK_name, &const_PROPERTY_NFD_QUICK_CHECK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFD_QUICK_CHECK_name); + zend_string_release_ex(const_PROPERTY_NFD_QUICK_CHECK_name, true); zval const_PROPERTY_NFKD_QUICK_CHECK_value; ZVAL_LONG(&const_PROPERTY_NFKD_QUICK_CHECK_value, UCHAR_NFKD_QUICK_CHECK); - zend_string *const_PROPERTY_NFKD_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFKD_QUICK_CHECK", sizeof("PROPERTY_NFKD_QUICK_CHECK") - 1, 1); + zend_string *const_PROPERTY_NFKD_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFKD_QUICK_CHECK", sizeof("PROPERTY_NFKD_QUICK_CHECK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFKD_QUICK_CHECK_name, &const_PROPERTY_NFKD_QUICK_CHECK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFKD_QUICK_CHECK_name); + zend_string_release_ex(const_PROPERTY_NFKD_QUICK_CHECK_name, true); zval const_PROPERTY_NFC_QUICK_CHECK_value; ZVAL_LONG(&const_PROPERTY_NFC_QUICK_CHECK_value, UCHAR_NFC_QUICK_CHECK); - zend_string *const_PROPERTY_NFC_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFC_QUICK_CHECK", sizeof("PROPERTY_NFC_QUICK_CHECK") - 1, 1); + zend_string *const_PROPERTY_NFC_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFC_QUICK_CHECK", sizeof("PROPERTY_NFC_QUICK_CHECK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFC_QUICK_CHECK_name, &const_PROPERTY_NFC_QUICK_CHECK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFC_QUICK_CHECK_name); + zend_string_release_ex(const_PROPERTY_NFC_QUICK_CHECK_name, true); zval const_PROPERTY_NFKC_QUICK_CHECK_value; ZVAL_LONG(&const_PROPERTY_NFKC_QUICK_CHECK_value, UCHAR_NFKC_QUICK_CHECK); - zend_string *const_PROPERTY_NFKC_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFKC_QUICK_CHECK", sizeof("PROPERTY_NFKC_QUICK_CHECK") - 1, 1); + zend_string *const_PROPERTY_NFKC_QUICK_CHECK_name = zend_string_init_interned("PROPERTY_NFKC_QUICK_CHECK", sizeof("PROPERTY_NFKC_QUICK_CHECK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NFKC_QUICK_CHECK_name, &const_PROPERTY_NFKC_QUICK_CHECK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NFKC_QUICK_CHECK_name); + zend_string_release_ex(const_PROPERTY_NFKC_QUICK_CHECK_name, true); zval const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_value; ZVAL_LONG(&const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_value, UCHAR_LEAD_CANONICAL_COMBINING_CLASS); - zend_string *const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_name = zend_string_init_interned("PROPERTY_LEAD_CANONICAL_COMBINING_CLASS", sizeof("PROPERTY_LEAD_CANONICAL_COMBINING_CLASS") - 1, 1); + zend_string *const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_name = zend_string_init_interned("PROPERTY_LEAD_CANONICAL_COMBINING_CLASS", sizeof("PROPERTY_LEAD_CANONICAL_COMBINING_CLASS") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_name, &const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_name); + zend_string_release_ex(const_PROPERTY_LEAD_CANONICAL_COMBINING_CLASS_name, true); zval const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_value; ZVAL_LONG(&const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_value, UCHAR_TRAIL_CANONICAL_COMBINING_CLASS); - zend_string *const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_name = zend_string_init_interned("PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS", sizeof("PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS") - 1, 1); + zend_string *const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_name = zend_string_init_interned("PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS", sizeof("PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_name, &const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_name); + zend_string_release_ex(const_PROPERTY_TRAIL_CANONICAL_COMBINING_CLASS_name, true); zval const_PROPERTY_GRAPHEME_CLUSTER_BREAK_value; ZVAL_LONG(&const_PROPERTY_GRAPHEME_CLUSTER_BREAK_value, UCHAR_GRAPHEME_CLUSTER_BREAK); - zend_string *const_PROPERTY_GRAPHEME_CLUSTER_BREAK_name = zend_string_init_interned("PROPERTY_GRAPHEME_CLUSTER_BREAK", sizeof("PROPERTY_GRAPHEME_CLUSTER_BREAK") - 1, 1); + zend_string *const_PROPERTY_GRAPHEME_CLUSTER_BREAK_name = zend_string_init_interned("PROPERTY_GRAPHEME_CLUSTER_BREAK", sizeof("PROPERTY_GRAPHEME_CLUSTER_BREAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_GRAPHEME_CLUSTER_BREAK_name, &const_PROPERTY_GRAPHEME_CLUSTER_BREAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_GRAPHEME_CLUSTER_BREAK_name); + zend_string_release_ex(const_PROPERTY_GRAPHEME_CLUSTER_BREAK_name, true); zval const_PROPERTY_SENTENCE_BREAK_value; ZVAL_LONG(&const_PROPERTY_SENTENCE_BREAK_value, UCHAR_SENTENCE_BREAK); - zend_string *const_PROPERTY_SENTENCE_BREAK_name = zend_string_init_interned("PROPERTY_SENTENCE_BREAK", sizeof("PROPERTY_SENTENCE_BREAK") - 1, 1); + zend_string *const_PROPERTY_SENTENCE_BREAK_name = zend_string_init_interned("PROPERTY_SENTENCE_BREAK", sizeof("PROPERTY_SENTENCE_BREAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SENTENCE_BREAK_name, &const_PROPERTY_SENTENCE_BREAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SENTENCE_BREAK_name); + zend_string_release_ex(const_PROPERTY_SENTENCE_BREAK_name, true); zval const_PROPERTY_WORD_BREAK_value; ZVAL_LONG(&const_PROPERTY_WORD_BREAK_value, UCHAR_WORD_BREAK); - zend_string *const_PROPERTY_WORD_BREAK_name = zend_string_init_interned("PROPERTY_WORD_BREAK", sizeof("PROPERTY_WORD_BREAK") - 1, 1); + zend_string *const_PROPERTY_WORD_BREAK_name = zend_string_init_interned("PROPERTY_WORD_BREAK", sizeof("PROPERTY_WORD_BREAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_WORD_BREAK_name, &const_PROPERTY_WORD_BREAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_WORD_BREAK_name); + zend_string_release_ex(const_PROPERTY_WORD_BREAK_name, true); zval const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_value; ZVAL_LONG(&const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_value, UCHAR_BIDI_PAIRED_BRACKET_TYPE); - zend_string *const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_name = zend_string_init_interned("PROPERTY_BIDI_PAIRED_BRACKET_TYPE", sizeof("PROPERTY_BIDI_PAIRED_BRACKET_TYPE") - 1, 1); + zend_string *const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_name = zend_string_init_interned("PROPERTY_BIDI_PAIRED_BRACKET_TYPE", sizeof("PROPERTY_BIDI_PAIRED_BRACKET_TYPE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_name, &const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_name); + zend_string_release_ex(const_PROPERTY_BIDI_PAIRED_BRACKET_TYPE_name, true); zval const_PROPERTY_INT_LIMIT_value; ZVAL_LONG(&const_PROPERTY_INT_LIMIT_value, UCHAR_INT_LIMIT); - zend_string *const_PROPERTY_INT_LIMIT_name = zend_string_init_interned("PROPERTY_INT_LIMIT", sizeof("PROPERTY_INT_LIMIT") - 1, 1); + zend_string *const_PROPERTY_INT_LIMIT_name = zend_string_init_interned("PROPERTY_INT_LIMIT", sizeof("PROPERTY_INT_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_INT_LIMIT_name, &const_PROPERTY_INT_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_INT_LIMIT_name); + zend_string_release_ex(const_PROPERTY_INT_LIMIT_name, true); zval const_PROPERTY_GENERAL_CATEGORY_MASK_value; ZVAL_LONG(&const_PROPERTY_GENERAL_CATEGORY_MASK_value, UCHAR_GENERAL_CATEGORY_MASK); - zend_string *const_PROPERTY_GENERAL_CATEGORY_MASK_name = zend_string_init_interned("PROPERTY_GENERAL_CATEGORY_MASK", sizeof("PROPERTY_GENERAL_CATEGORY_MASK") - 1, 1); + zend_string *const_PROPERTY_GENERAL_CATEGORY_MASK_name = zend_string_init_interned("PROPERTY_GENERAL_CATEGORY_MASK", sizeof("PROPERTY_GENERAL_CATEGORY_MASK") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_GENERAL_CATEGORY_MASK_name, &const_PROPERTY_GENERAL_CATEGORY_MASK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_GENERAL_CATEGORY_MASK_name); + zend_string_release_ex(const_PROPERTY_GENERAL_CATEGORY_MASK_name, true); zval const_PROPERTY_MASK_START_value; ZVAL_LONG(&const_PROPERTY_MASK_START_value, UCHAR_MASK_START); - zend_string *const_PROPERTY_MASK_START_name = zend_string_init_interned("PROPERTY_MASK_START", sizeof("PROPERTY_MASK_START") - 1, 1); + zend_string *const_PROPERTY_MASK_START_name = zend_string_init_interned("PROPERTY_MASK_START", sizeof("PROPERTY_MASK_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_MASK_START_name, &const_PROPERTY_MASK_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_MASK_START_name); + zend_string_release_ex(const_PROPERTY_MASK_START_name, true); zval const_PROPERTY_MASK_LIMIT_value; ZVAL_LONG(&const_PROPERTY_MASK_LIMIT_value, UCHAR_MASK_LIMIT); - zend_string *const_PROPERTY_MASK_LIMIT_name = zend_string_init_interned("PROPERTY_MASK_LIMIT", sizeof("PROPERTY_MASK_LIMIT") - 1, 1); + zend_string *const_PROPERTY_MASK_LIMIT_name = zend_string_init_interned("PROPERTY_MASK_LIMIT", sizeof("PROPERTY_MASK_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_MASK_LIMIT_name, &const_PROPERTY_MASK_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_MASK_LIMIT_name); + zend_string_release_ex(const_PROPERTY_MASK_LIMIT_name, true); zval const_PROPERTY_NUMERIC_VALUE_value; ZVAL_LONG(&const_PROPERTY_NUMERIC_VALUE_value, UCHAR_NUMERIC_VALUE); - zend_string *const_PROPERTY_NUMERIC_VALUE_name = zend_string_init_interned("PROPERTY_NUMERIC_VALUE", sizeof("PROPERTY_NUMERIC_VALUE") - 1, 1); + zend_string *const_PROPERTY_NUMERIC_VALUE_name = zend_string_init_interned("PROPERTY_NUMERIC_VALUE", sizeof("PROPERTY_NUMERIC_VALUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NUMERIC_VALUE_name, &const_PROPERTY_NUMERIC_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NUMERIC_VALUE_name); + zend_string_release_ex(const_PROPERTY_NUMERIC_VALUE_name, true); zval const_PROPERTY_DOUBLE_START_value; ZVAL_LONG(&const_PROPERTY_DOUBLE_START_value, UCHAR_DOUBLE_START); - zend_string *const_PROPERTY_DOUBLE_START_name = zend_string_init_interned("PROPERTY_DOUBLE_START", sizeof("PROPERTY_DOUBLE_START") - 1, 1); + zend_string *const_PROPERTY_DOUBLE_START_name = zend_string_init_interned("PROPERTY_DOUBLE_START", sizeof("PROPERTY_DOUBLE_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_DOUBLE_START_name, &const_PROPERTY_DOUBLE_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_DOUBLE_START_name); + zend_string_release_ex(const_PROPERTY_DOUBLE_START_name, true); zval const_PROPERTY_DOUBLE_LIMIT_value; ZVAL_LONG(&const_PROPERTY_DOUBLE_LIMIT_value, UCHAR_DOUBLE_LIMIT); - zend_string *const_PROPERTY_DOUBLE_LIMIT_name = zend_string_init_interned("PROPERTY_DOUBLE_LIMIT", sizeof("PROPERTY_DOUBLE_LIMIT") - 1, 1); + zend_string *const_PROPERTY_DOUBLE_LIMIT_name = zend_string_init_interned("PROPERTY_DOUBLE_LIMIT", sizeof("PROPERTY_DOUBLE_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_DOUBLE_LIMIT_name, &const_PROPERTY_DOUBLE_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_DOUBLE_LIMIT_name); + zend_string_release_ex(const_PROPERTY_DOUBLE_LIMIT_name, true); zval const_PROPERTY_AGE_value; ZVAL_LONG(&const_PROPERTY_AGE_value, UCHAR_AGE); - zend_string *const_PROPERTY_AGE_name = zend_string_init_interned("PROPERTY_AGE", sizeof("PROPERTY_AGE") - 1, 1); + zend_string *const_PROPERTY_AGE_name = zend_string_init_interned("PROPERTY_AGE", sizeof("PROPERTY_AGE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_AGE_name, &const_PROPERTY_AGE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_AGE_name); + zend_string_release_ex(const_PROPERTY_AGE_name, true); zval const_PROPERTY_STRING_START_value; ZVAL_LONG(&const_PROPERTY_STRING_START_value, UCHAR_STRING_START); - zend_string *const_PROPERTY_STRING_START_name = zend_string_init_interned("PROPERTY_STRING_START", sizeof("PROPERTY_STRING_START") - 1, 1); + zend_string *const_PROPERTY_STRING_START_name = zend_string_init_interned("PROPERTY_STRING_START", sizeof("PROPERTY_STRING_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_STRING_START_name, &const_PROPERTY_STRING_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_STRING_START_name); + zend_string_release_ex(const_PROPERTY_STRING_START_name, true); zval const_PROPERTY_BIDI_MIRRORING_GLYPH_value; ZVAL_LONG(&const_PROPERTY_BIDI_MIRRORING_GLYPH_value, UCHAR_BIDI_MIRRORING_GLYPH); - zend_string *const_PROPERTY_BIDI_MIRRORING_GLYPH_name = zend_string_init_interned("PROPERTY_BIDI_MIRRORING_GLYPH", sizeof("PROPERTY_BIDI_MIRRORING_GLYPH") - 1, 1); + zend_string *const_PROPERTY_BIDI_MIRRORING_GLYPH_name = zend_string_init_interned("PROPERTY_BIDI_MIRRORING_GLYPH", sizeof("PROPERTY_BIDI_MIRRORING_GLYPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BIDI_MIRRORING_GLYPH_name, &const_PROPERTY_BIDI_MIRRORING_GLYPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BIDI_MIRRORING_GLYPH_name); + zend_string_release_ex(const_PROPERTY_BIDI_MIRRORING_GLYPH_name, true); zval const_PROPERTY_CASE_FOLDING_value; ZVAL_LONG(&const_PROPERTY_CASE_FOLDING_value, UCHAR_CASE_FOLDING); - zend_string *const_PROPERTY_CASE_FOLDING_name = zend_string_init_interned("PROPERTY_CASE_FOLDING", sizeof("PROPERTY_CASE_FOLDING") - 1, 1); + zend_string *const_PROPERTY_CASE_FOLDING_name = zend_string_init_interned("PROPERTY_CASE_FOLDING", sizeof("PROPERTY_CASE_FOLDING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_CASE_FOLDING_name, &const_PROPERTY_CASE_FOLDING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_CASE_FOLDING_name); + zend_string_release_ex(const_PROPERTY_CASE_FOLDING_name, true); zval const_PROPERTY_ISO_COMMENT_value; ZVAL_LONG(&const_PROPERTY_ISO_COMMENT_value, UCHAR_ISO_COMMENT); - zend_string *const_PROPERTY_ISO_COMMENT_name = zend_string_init_interned("PROPERTY_ISO_COMMENT", sizeof("PROPERTY_ISO_COMMENT") - 1, 1); + zend_string *const_PROPERTY_ISO_COMMENT_name = zend_string_init_interned("PROPERTY_ISO_COMMENT", sizeof("PROPERTY_ISO_COMMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_ISO_COMMENT_name, &const_PROPERTY_ISO_COMMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_ISO_COMMENT_name); + zend_string_release_ex(const_PROPERTY_ISO_COMMENT_name, true); zval const_PROPERTY_LOWERCASE_MAPPING_value; ZVAL_LONG(&const_PROPERTY_LOWERCASE_MAPPING_value, UCHAR_LOWERCASE_MAPPING); - zend_string *const_PROPERTY_LOWERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_LOWERCASE_MAPPING", sizeof("PROPERTY_LOWERCASE_MAPPING") - 1, 1); + zend_string *const_PROPERTY_LOWERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_LOWERCASE_MAPPING", sizeof("PROPERTY_LOWERCASE_MAPPING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_LOWERCASE_MAPPING_name, &const_PROPERTY_LOWERCASE_MAPPING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_LOWERCASE_MAPPING_name); + zend_string_release_ex(const_PROPERTY_LOWERCASE_MAPPING_name, true); zval const_PROPERTY_NAME_value; ZVAL_LONG(&const_PROPERTY_NAME_value, UCHAR_NAME); - zend_string *const_PROPERTY_NAME_name = zend_string_init_interned("PROPERTY_NAME", sizeof("PROPERTY_NAME") - 1, 1); + zend_string *const_PROPERTY_NAME_name = zend_string_init_interned("PROPERTY_NAME", sizeof("PROPERTY_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NAME_name, &const_PROPERTY_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NAME_name); + zend_string_release_ex(const_PROPERTY_NAME_name, true); zval const_PROPERTY_SIMPLE_CASE_FOLDING_value; ZVAL_LONG(&const_PROPERTY_SIMPLE_CASE_FOLDING_value, UCHAR_SIMPLE_CASE_FOLDING); - zend_string *const_PROPERTY_SIMPLE_CASE_FOLDING_name = zend_string_init_interned("PROPERTY_SIMPLE_CASE_FOLDING", sizeof("PROPERTY_SIMPLE_CASE_FOLDING") - 1, 1); + zend_string *const_PROPERTY_SIMPLE_CASE_FOLDING_name = zend_string_init_interned("PROPERTY_SIMPLE_CASE_FOLDING", sizeof("PROPERTY_SIMPLE_CASE_FOLDING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SIMPLE_CASE_FOLDING_name, &const_PROPERTY_SIMPLE_CASE_FOLDING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SIMPLE_CASE_FOLDING_name); + zend_string_release_ex(const_PROPERTY_SIMPLE_CASE_FOLDING_name, true); zval const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_value; ZVAL_LONG(&const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_value, UCHAR_SIMPLE_LOWERCASE_MAPPING); - zend_string *const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_SIMPLE_LOWERCASE_MAPPING", sizeof("PROPERTY_SIMPLE_LOWERCASE_MAPPING") - 1, 1); + zend_string *const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_SIMPLE_LOWERCASE_MAPPING", sizeof("PROPERTY_SIMPLE_LOWERCASE_MAPPING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_name, &const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_name); + zend_string_release_ex(const_PROPERTY_SIMPLE_LOWERCASE_MAPPING_name, true); zval const_PROPERTY_SIMPLE_TITLECASE_MAPPING_value; ZVAL_LONG(&const_PROPERTY_SIMPLE_TITLECASE_MAPPING_value, UCHAR_SIMPLE_TITLECASE_MAPPING); - zend_string *const_PROPERTY_SIMPLE_TITLECASE_MAPPING_name = zend_string_init_interned("PROPERTY_SIMPLE_TITLECASE_MAPPING", sizeof("PROPERTY_SIMPLE_TITLECASE_MAPPING") - 1, 1); + zend_string *const_PROPERTY_SIMPLE_TITLECASE_MAPPING_name = zend_string_init_interned("PROPERTY_SIMPLE_TITLECASE_MAPPING", sizeof("PROPERTY_SIMPLE_TITLECASE_MAPPING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SIMPLE_TITLECASE_MAPPING_name, &const_PROPERTY_SIMPLE_TITLECASE_MAPPING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SIMPLE_TITLECASE_MAPPING_name); + zend_string_release_ex(const_PROPERTY_SIMPLE_TITLECASE_MAPPING_name, true); zval const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_value; ZVAL_LONG(&const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_value, UCHAR_SIMPLE_UPPERCASE_MAPPING); - zend_string *const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_SIMPLE_UPPERCASE_MAPPING", sizeof("PROPERTY_SIMPLE_UPPERCASE_MAPPING") - 1, 1); + zend_string *const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_SIMPLE_UPPERCASE_MAPPING", sizeof("PROPERTY_SIMPLE_UPPERCASE_MAPPING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_name, &const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_name); + zend_string_release_ex(const_PROPERTY_SIMPLE_UPPERCASE_MAPPING_name, true); zval const_PROPERTY_TITLECASE_MAPPING_value; ZVAL_LONG(&const_PROPERTY_TITLECASE_MAPPING_value, UCHAR_TITLECASE_MAPPING); - zend_string *const_PROPERTY_TITLECASE_MAPPING_name = zend_string_init_interned("PROPERTY_TITLECASE_MAPPING", sizeof("PROPERTY_TITLECASE_MAPPING") - 1, 1); + zend_string *const_PROPERTY_TITLECASE_MAPPING_name = zend_string_init_interned("PROPERTY_TITLECASE_MAPPING", sizeof("PROPERTY_TITLECASE_MAPPING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_TITLECASE_MAPPING_name, &const_PROPERTY_TITLECASE_MAPPING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_TITLECASE_MAPPING_name); + zend_string_release_ex(const_PROPERTY_TITLECASE_MAPPING_name, true); zval const_PROPERTY_UNICODE_1_NAME_value; ZVAL_LONG(&const_PROPERTY_UNICODE_1_NAME_value, UCHAR_UNICODE_1_NAME); - zend_string *const_PROPERTY_UNICODE_1_NAME_name = zend_string_init_interned("PROPERTY_UNICODE_1_NAME", sizeof("PROPERTY_UNICODE_1_NAME") - 1, 1); + zend_string *const_PROPERTY_UNICODE_1_NAME_name = zend_string_init_interned("PROPERTY_UNICODE_1_NAME", sizeof("PROPERTY_UNICODE_1_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_UNICODE_1_NAME_name, &const_PROPERTY_UNICODE_1_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_UNICODE_1_NAME_name); + zend_string_release_ex(const_PROPERTY_UNICODE_1_NAME_name, true); zval const_PROPERTY_UPPERCASE_MAPPING_value; ZVAL_LONG(&const_PROPERTY_UPPERCASE_MAPPING_value, UCHAR_UPPERCASE_MAPPING); - zend_string *const_PROPERTY_UPPERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_UPPERCASE_MAPPING", sizeof("PROPERTY_UPPERCASE_MAPPING") - 1, 1); + zend_string *const_PROPERTY_UPPERCASE_MAPPING_name = zend_string_init_interned("PROPERTY_UPPERCASE_MAPPING", sizeof("PROPERTY_UPPERCASE_MAPPING") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_UPPERCASE_MAPPING_name, &const_PROPERTY_UPPERCASE_MAPPING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_UPPERCASE_MAPPING_name); + zend_string_release_ex(const_PROPERTY_UPPERCASE_MAPPING_name, true); zval const_PROPERTY_BIDI_PAIRED_BRACKET_value; ZVAL_LONG(&const_PROPERTY_BIDI_PAIRED_BRACKET_value, UCHAR_BIDI_PAIRED_BRACKET); - zend_string *const_PROPERTY_BIDI_PAIRED_BRACKET_name = zend_string_init_interned("PROPERTY_BIDI_PAIRED_BRACKET", sizeof("PROPERTY_BIDI_PAIRED_BRACKET") - 1, 1); + zend_string *const_PROPERTY_BIDI_PAIRED_BRACKET_name = zend_string_init_interned("PROPERTY_BIDI_PAIRED_BRACKET", sizeof("PROPERTY_BIDI_PAIRED_BRACKET") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_BIDI_PAIRED_BRACKET_name, &const_PROPERTY_BIDI_PAIRED_BRACKET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_BIDI_PAIRED_BRACKET_name); + zend_string_release_ex(const_PROPERTY_BIDI_PAIRED_BRACKET_name, true); zval const_PROPERTY_STRING_LIMIT_value; ZVAL_LONG(&const_PROPERTY_STRING_LIMIT_value, UCHAR_STRING_LIMIT); - zend_string *const_PROPERTY_STRING_LIMIT_name = zend_string_init_interned("PROPERTY_STRING_LIMIT", sizeof("PROPERTY_STRING_LIMIT") - 1, 1); + zend_string *const_PROPERTY_STRING_LIMIT_name = zend_string_init_interned("PROPERTY_STRING_LIMIT", sizeof("PROPERTY_STRING_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_STRING_LIMIT_name, &const_PROPERTY_STRING_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_STRING_LIMIT_name); + zend_string_release_ex(const_PROPERTY_STRING_LIMIT_name, true); zval const_PROPERTY_SCRIPT_EXTENSIONS_value; ZVAL_LONG(&const_PROPERTY_SCRIPT_EXTENSIONS_value, UCHAR_SCRIPT_EXTENSIONS); - zend_string *const_PROPERTY_SCRIPT_EXTENSIONS_name = zend_string_init_interned("PROPERTY_SCRIPT_EXTENSIONS", sizeof("PROPERTY_SCRIPT_EXTENSIONS") - 1, 1); + zend_string *const_PROPERTY_SCRIPT_EXTENSIONS_name = zend_string_init_interned("PROPERTY_SCRIPT_EXTENSIONS", sizeof("PROPERTY_SCRIPT_EXTENSIONS") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_SCRIPT_EXTENSIONS_name, &const_PROPERTY_SCRIPT_EXTENSIONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_SCRIPT_EXTENSIONS_name); + zend_string_release_ex(const_PROPERTY_SCRIPT_EXTENSIONS_name, true); zval const_PROPERTY_OTHER_PROPERTY_START_value; ZVAL_LONG(&const_PROPERTY_OTHER_PROPERTY_START_value, UCHAR_OTHER_PROPERTY_START); - zend_string *const_PROPERTY_OTHER_PROPERTY_START_name = zend_string_init_interned("PROPERTY_OTHER_PROPERTY_START", sizeof("PROPERTY_OTHER_PROPERTY_START") - 1, 1); + zend_string *const_PROPERTY_OTHER_PROPERTY_START_name = zend_string_init_interned("PROPERTY_OTHER_PROPERTY_START", sizeof("PROPERTY_OTHER_PROPERTY_START") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_OTHER_PROPERTY_START_name, &const_PROPERTY_OTHER_PROPERTY_START_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_OTHER_PROPERTY_START_name); + zend_string_release_ex(const_PROPERTY_OTHER_PROPERTY_START_name, true); zval const_PROPERTY_OTHER_PROPERTY_LIMIT_value; ZVAL_LONG(&const_PROPERTY_OTHER_PROPERTY_LIMIT_value, UCHAR_OTHER_PROPERTY_LIMIT); - zend_string *const_PROPERTY_OTHER_PROPERTY_LIMIT_name = zend_string_init_interned("PROPERTY_OTHER_PROPERTY_LIMIT", sizeof("PROPERTY_OTHER_PROPERTY_LIMIT") - 1, 1); + zend_string *const_PROPERTY_OTHER_PROPERTY_LIMIT_name = zend_string_init_interned("PROPERTY_OTHER_PROPERTY_LIMIT", sizeof("PROPERTY_OTHER_PROPERTY_LIMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_OTHER_PROPERTY_LIMIT_name, &const_PROPERTY_OTHER_PROPERTY_LIMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_OTHER_PROPERTY_LIMIT_name); + zend_string_release_ex(const_PROPERTY_OTHER_PROPERTY_LIMIT_name, true); zval const_PROPERTY_INVALID_CODE_value; ZVAL_LONG(&const_PROPERTY_INVALID_CODE_value, UCHAR_INVALID_CODE); - zend_string *const_PROPERTY_INVALID_CODE_name = zend_string_init_interned("PROPERTY_INVALID_CODE", sizeof("PROPERTY_INVALID_CODE") - 1, 1); + zend_string *const_PROPERTY_INVALID_CODE_name = zend_string_init_interned("PROPERTY_INVALID_CODE", sizeof("PROPERTY_INVALID_CODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_INVALID_CODE_name, &const_PROPERTY_INVALID_CODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_INVALID_CODE_name); + zend_string_release_ex(const_PROPERTY_INVALID_CODE_name, true); zval const_CHAR_CATEGORY_UNASSIGNED_value; ZVAL_LONG(&const_CHAR_CATEGORY_UNASSIGNED_value, U_UNASSIGNED); - zend_string *const_CHAR_CATEGORY_UNASSIGNED_name = zend_string_init_interned("CHAR_CATEGORY_UNASSIGNED", sizeof("CHAR_CATEGORY_UNASSIGNED") - 1, 1); + zend_string *const_CHAR_CATEGORY_UNASSIGNED_name = zend_string_init_interned("CHAR_CATEGORY_UNASSIGNED", sizeof("CHAR_CATEGORY_UNASSIGNED") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_UNASSIGNED_name, &const_CHAR_CATEGORY_UNASSIGNED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_UNASSIGNED_name); + zend_string_release_ex(const_CHAR_CATEGORY_UNASSIGNED_name, true); zval const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_value; ZVAL_LONG(&const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_value, U_GENERAL_OTHER_TYPES); - zend_string *const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_name = zend_string_init_interned("CHAR_CATEGORY_GENERAL_OTHER_TYPES", sizeof("CHAR_CATEGORY_GENERAL_OTHER_TYPES") - 1, 1); + zend_string *const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_name = zend_string_init_interned("CHAR_CATEGORY_GENERAL_OTHER_TYPES", sizeof("CHAR_CATEGORY_GENERAL_OTHER_TYPES") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_name, &const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_name); + zend_string_release_ex(const_CHAR_CATEGORY_GENERAL_OTHER_TYPES_name, true); zval const_CHAR_CATEGORY_UPPERCASE_LETTER_value; ZVAL_LONG(&const_CHAR_CATEGORY_UPPERCASE_LETTER_value, U_UPPERCASE_LETTER); - zend_string *const_CHAR_CATEGORY_UPPERCASE_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_UPPERCASE_LETTER", sizeof("CHAR_CATEGORY_UPPERCASE_LETTER") - 1, 1); + zend_string *const_CHAR_CATEGORY_UPPERCASE_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_UPPERCASE_LETTER", sizeof("CHAR_CATEGORY_UPPERCASE_LETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_UPPERCASE_LETTER_name, &const_CHAR_CATEGORY_UPPERCASE_LETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_UPPERCASE_LETTER_name); + zend_string_release_ex(const_CHAR_CATEGORY_UPPERCASE_LETTER_name, true); zval const_CHAR_CATEGORY_LOWERCASE_LETTER_value; ZVAL_LONG(&const_CHAR_CATEGORY_LOWERCASE_LETTER_value, U_LOWERCASE_LETTER); - zend_string *const_CHAR_CATEGORY_LOWERCASE_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_LOWERCASE_LETTER", sizeof("CHAR_CATEGORY_LOWERCASE_LETTER") - 1, 1); + zend_string *const_CHAR_CATEGORY_LOWERCASE_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_LOWERCASE_LETTER", sizeof("CHAR_CATEGORY_LOWERCASE_LETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_LOWERCASE_LETTER_name, &const_CHAR_CATEGORY_LOWERCASE_LETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_LOWERCASE_LETTER_name); + zend_string_release_ex(const_CHAR_CATEGORY_LOWERCASE_LETTER_name, true); zval const_CHAR_CATEGORY_TITLECASE_LETTER_value; ZVAL_LONG(&const_CHAR_CATEGORY_TITLECASE_LETTER_value, U_TITLECASE_LETTER); - zend_string *const_CHAR_CATEGORY_TITLECASE_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_TITLECASE_LETTER", sizeof("CHAR_CATEGORY_TITLECASE_LETTER") - 1, 1); + zend_string *const_CHAR_CATEGORY_TITLECASE_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_TITLECASE_LETTER", sizeof("CHAR_CATEGORY_TITLECASE_LETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_TITLECASE_LETTER_name, &const_CHAR_CATEGORY_TITLECASE_LETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_TITLECASE_LETTER_name); + zend_string_release_ex(const_CHAR_CATEGORY_TITLECASE_LETTER_name, true); zval const_CHAR_CATEGORY_MODIFIER_LETTER_value; ZVAL_LONG(&const_CHAR_CATEGORY_MODIFIER_LETTER_value, U_MODIFIER_LETTER); - zend_string *const_CHAR_CATEGORY_MODIFIER_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_MODIFIER_LETTER", sizeof("CHAR_CATEGORY_MODIFIER_LETTER") - 1, 1); + zend_string *const_CHAR_CATEGORY_MODIFIER_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_MODIFIER_LETTER", sizeof("CHAR_CATEGORY_MODIFIER_LETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_MODIFIER_LETTER_name, &const_CHAR_CATEGORY_MODIFIER_LETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_MODIFIER_LETTER_name); + zend_string_release_ex(const_CHAR_CATEGORY_MODIFIER_LETTER_name, true); zval const_CHAR_CATEGORY_OTHER_LETTER_value; ZVAL_LONG(&const_CHAR_CATEGORY_OTHER_LETTER_value, U_OTHER_LETTER); - zend_string *const_CHAR_CATEGORY_OTHER_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_LETTER", sizeof("CHAR_CATEGORY_OTHER_LETTER") - 1, 1); + zend_string *const_CHAR_CATEGORY_OTHER_LETTER_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_LETTER", sizeof("CHAR_CATEGORY_OTHER_LETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_OTHER_LETTER_name, &const_CHAR_CATEGORY_OTHER_LETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_OTHER_LETTER_name); + zend_string_release_ex(const_CHAR_CATEGORY_OTHER_LETTER_name, true); zval const_CHAR_CATEGORY_NON_SPACING_MARK_value; ZVAL_LONG(&const_CHAR_CATEGORY_NON_SPACING_MARK_value, U_NON_SPACING_MARK); - zend_string *const_CHAR_CATEGORY_NON_SPACING_MARK_name = zend_string_init_interned("CHAR_CATEGORY_NON_SPACING_MARK", sizeof("CHAR_CATEGORY_NON_SPACING_MARK") - 1, 1); + zend_string *const_CHAR_CATEGORY_NON_SPACING_MARK_name = zend_string_init_interned("CHAR_CATEGORY_NON_SPACING_MARK", sizeof("CHAR_CATEGORY_NON_SPACING_MARK") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_NON_SPACING_MARK_name, &const_CHAR_CATEGORY_NON_SPACING_MARK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_NON_SPACING_MARK_name); + zend_string_release_ex(const_CHAR_CATEGORY_NON_SPACING_MARK_name, true); zval const_CHAR_CATEGORY_ENCLOSING_MARK_value; ZVAL_LONG(&const_CHAR_CATEGORY_ENCLOSING_MARK_value, U_ENCLOSING_MARK); - zend_string *const_CHAR_CATEGORY_ENCLOSING_MARK_name = zend_string_init_interned("CHAR_CATEGORY_ENCLOSING_MARK", sizeof("CHAR_CATEGORY_ENCLOSING_MARK") - 1, 1); + zend_string *const_CHAR_CATEGORY_ENCLOSING_MARK_name = zend_string_init_interned("CHAR_CATEGORY_ENCLOSING_MARK", sizeof("CHAR_CATEGORY_ENCLOSING_MARK") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_ENCLOSING_MARK_name, &const_CHAR_CATEGORY_ENCLOSING_MARK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_ENCLOSING_MARK_name); + zend_string_release_ex(const_CHAR_CATEGORY_ENCLOSING_MARK_name, true); zval const_CHAR_CATEGORY_COMBINING_SPACING_MARK_value; ZVAL_LONG(&const_CHAR_CATEGORY_COMBINING_SPACING_MARK_value, U_COMBINING_SPACING_MARK); - zend_string *const_CHAR_CATEGORY_COMBINING_SPACING_MARK_name = zend_string_init_interned("CHAR_CATEGORY_COMBINING_SPACING_MARK", sizeof("CHAR_CATEGORY_COMBINING_SPACING_MARK") - 1, 1); + zend_string *const_CHAR_CATEGORY_COMBINING_SPACING_MARK_name = zend_string_init_interned("CHAR_CATEGORY_COMBINING_SPACING_MARK", sizeof("CHAR_CATEGORY_COMBINING_SPACING_MARK") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_COMBINING_SPACING_MARK_name, &const_CHAR_CATEGORY_COMBINING_SPACING_MARK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_COMBINING_SPACING_MARK_name); + zend_string_release_ex(const_CHAR_CATEGORY_COMBINING_SPACING_MARK_name, true); zval const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_value; ZVAL_LONG(&const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_value, U_DECIMAL_DIGIT_NUMBER); - zend_string *const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_name = zend_string_init_interned("CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER", sizeof("CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER") - 1, 1); + zend_string *const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_name = zend_string_init_interned("CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER", sizeof("CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_name, &const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_name); + zend_string_release_ex(const_CHAR_CATEGORY_DECIMAL_DIGIT_NUMBER_name, true); zval const_CHAR_CATEGORY_LETTER_NUMBER_value; ZVAL_LONG(&const_CHAR_CATEGORY_LETTER_NUMBER_value, U_LETTER_NUMBER); - zend_string *const_CHAR_CATEGORY_LETTER_NUMBER_name = zend_string_init_interned("CHAR_CATEGORY_LETTER_NUMBER", sizeof("CHAR_CATEGORY_LETTER_NUMBER") - 1, 1); + zend_string *const_CHAR_CATEGORY_LETTER_NUMBER_name = zend_string_init_interned("CHAR_CATEGORY_LETTER_NUMBER", sizeof("CHAR_CATEGORY_LETTER_NUMBER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_LETTER_NUMBER_name, &const_CHAR_CATEGORY_LETTER_NUMBER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_LETTER_NUMBER_name); + zend_string_release_ex(const_CHAR_CATEGORY_LETTER_NUMBER_name, true); zval const_CHAR_CATEGORY_OTHER_NUMBER_value; ZVAL_LONG(&const_CHAR_CATEGORY_OTHER_NUMBER_value, U_OTHER_NUMBER); - zend_string *const_CHAR_CATEGORY_OTHER_NUMBER_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_NUMBER", sizeof("CHAR_CATEGORY_OTHER_NUMBER") - 1, 1); + zend_string *const_CHAR_CATEGORY_OTHER_NUMBER_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_NUMBER", sizeof("CHAR_CATEGORY_OTHER_NUMBER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_OTHER_NUMBER_name, &const_CHAR_CATEGORY_OTHER_NUMBER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_OTHER_NUMBER_name); + zend_string_release_ex(const_CHAR_CATEGORY_OTHER_NUMBER_name, true); zval const_CHAR_CATEGORY_SPACE_SEPARATOR_value; ZVAL_LONG(&const_CHAR_CATEGORY_SPACE_SEPARATOR_value, U_SPACE_SEPARATOR); - zend_string *const_CHAR_CATEGORY_SPACE_SEPARATOR_name = zend_string_init_interned("CHAR_CATEGORY_SPACE_SEPARATOR", sizeof("CHAR_CATEGORY_SPACE_SEPARATOR") - 1, 1); + zend_string *const_CHAR_CATEGORY_SPACE_SEPARATOR_name = zend_string_init_interned("CHAR_CATEGORY_SPACE_SEPARATOR", sizeof("CHAR_CATEGORY_SPACE_SEPARATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_SPACE_SEPARATOR_name, &const_CHAR_CATEGORY_SPACE_SEPARATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_SPACE_SEPARATOR_name); + zend_string_release_ex(const_CHAR_CATEGORY_SPACE_SEPARATOR_name, true); zval const_CHAR_CATEGORY_LINE_SEPARATOR_value; ZVAL_LONG(&const_CHAR_CATEGORY_LINE_SEPARATOR_value, U_LINE_SEPARATOR); - zend_string *const_CHAR_CATEGORY_LINE_SEPARATOR_name = zend_string_init_interned("CHAR_CATEGORY_LINE_SEPARATOR", sizeof("CHAR_CATEGORY_LINE_SEPARATOR") - 1, 1); + zend_string *const_CHAR_CATEGORY_LINE_SEPARATOR_name = zend_string_init_interned("CHAR_CATEGORY_LINE_SEPARATOR", sizeof("CHAR_CATEGORY_LINE_SEPARATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_LINE_SEPARATOR_name, &const_CHAR_CATEGORY_LINE_SEPARATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_LINE_SEPARATOR_name); + zend_string_release_ex(const_CHAR_CATEGORY_LINE_SEPARATOR_name, true); zval const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_value; ZVAL_LONG(&const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_value, U_PARAGRAPH_SEPARATOR); - zend_string *const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_name = zend_string_init_interned("CHAR_CATEGORY_PARAGRAPH_SEPARATOR", sizeof("CHAR_CATEGORY_PARAGRAPH_SEPARATOR") - 1, 1); + zend_string *const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_name = zend_string_init_interned("CHAR_CATEGORY_PARAGRAPH_SEPARATOR", sizeof("CHAR_CATEGORY_PARAGRAPH_SEPARATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_name, &const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_name); + zend_string_release_ex(const_CHAR_CATEGORY_PARAGRAPH_SEPARATOR_name, true); zval const_CHAR_CATEGORY_CONTROL_CHAR_value; ZVAL_LONG(&const_CHAR_CATEGORY_CONTROL_CHAR_value, U_CONTROL_CHAR); - zend_string *const_CHAR_CATEGORY_CONTROL_CHAR_name = zend_string_init_interned("CHAR_CATEGORY_CONTROL_CHAR", sizeof("CHAR_CATEGORY_CONTROL_CHAR") - 1, 1); + zend_string *const_CHAR_CATEGORY_CONTROL_CHAR_name = zend_string_init_interned("CHAR_CATEGORY_CONTROL_CHAR", sizeof("CHAR_CATEGORY_CONTROL_CHAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_CONTROL_CHAR_name, &const_CHAR_CATEGORY_CONTROL_CHAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_CONTROL_CHAR_name); + zend_string_release_ex(const_CHAR_CATEGORY_CONTROL_CHAR_name, true); zval const_CHAR_CATEGORY_FORMAT_CHAR_value; ZVAL_LONG(&const_CHAR_CATEGORY_FORMAT_CHAR_value, U_FORMAT_CHAR); - zend_string *const_CHAR_CATEGORY_FORMAT_CHAR_name = zend_string_init_interned("CHAR_CATEGORY_FORMAT_CHAR", sizeof("CHAR_CATEGORY_FORMAT_CHAR") - 1, 1); + zend_string *const_CHAR_CATEGORY_FORMAT_CHAR_name = zend_string_init_interned("CHAR_CATEGORY_FORMAT_CHAR", sizeof("CHAR_CATEGORY_FORMAT_CHAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_FORMAT_CHAR_name, &const_CHAR_CATEGORY_FORMAT_CHAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_FORMAT_CHAR_name); + zend_string_release_ex(const_CHAR_CATEGORY_FORMAT_CHAR_name, true); zval const_CHAR_CATEGORY_PRIVATE_USE_CHAR_value; ZVAL_LONG(&const_CHAR_CATEGORY_PRIVATE_USE_CHAR_value, U_PRIVATE_USE_CHAR); - zend_string *const_CHAR_CATEGORY_PRIVATE_USE_CHAR_name = zend_string_init_interned("CHAR_CATEGORY_PRIVATE_USE_CHAR", sizeof("CHAR_CATEGORY_PRIVATE_USE_CHAR") - 1, 1); + zend_string *const_CHAR_CATEGORY_PRIVATE_USE_CHAR_name = zend_string_init_interned("CHAR_CATEGORY_PRIVATE_USE_CHAR", sizeof("CHAR_CATEGORY_PRIVATE_USE_CHAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_PRIVATE_USE_CHAR_name, &const_CHAR_CATEGORY_PRIVATE_USE_CHAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_PRIVATE_USE_CHAR_name); + zend_string_release_ex(const_CHAR_CATEGORY_PRIVATE_USE_CHAR_name, true); zval const_CHAR_CATEGORY_SURROGATE_value; ZVAL_LONG(&const_CHAR_CATEGORY_SURROGATE_value, U_SURROGATE); - zend_string *const_CHAR_CATEGORY_SURROGATE_name = zend_string_init_interned("CHAR_CATEGORY_SURROGATE", sizeof("CHAR_CATEGORY_SURROGATE") - 1, 1); + zend_string *const_CHAR_CATEGORY_SURROGATE_name = zend_string_init_interned("CHAR_CATEGORY_SURROGATE", sizeof("CHAR_CATEGORY_SURROGATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_SURROGATE_name, &const_CHAR_CATEGORY_SURROGATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_SURROGATE_name); + zend_string_release_ex(const_CHAR_CATEGORY_SURROGATE_name, true); zval const_CHAR_CATEGORY_DASH_PUNCTUATION_value; ZVAL_LONG(&const_CHAR_CATEGORY_DASH_PUNCTUATION_value, U_DASH_PUNCTUATION); - zend_string *const_CHAR_CATEGORY_DASH_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_DASH_PUNCTUATION", sizeof("CHAR_CATEGORY_DASH_PUNCTUATION") - 1, 1); + zend_string *const_CHAR_CATEGORY_DASH_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_DASH_PUNCTUATION", sizeof("CHAR_CATEGORY_DASH_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_DASH_PUNCTUATION_name, &const_CHAR_CATEGORY_DASH_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_DASH_PUNCTUATION_name); + zend_string_release_ex(const_CHAR_CATEGORY_DASH_PUNCTUATION_name, true); zval const_CHAR_CATEGORY_START_PUNCTUATION_value; ZVAL_LONG(&const_CHAR_CATEGORY_START_PUNCTUATION_value, U_START_PUNCTUATION); - zend_string *const_CHAR_CATEGORY_START_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_START_PUNCTUATION", sizeof("CHAR_CATEGORY_START_PUNCTUATION") - 1, 1); + zend_string *const_CHAR_CATEGORY_START_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_START_PUNCTUATION", sizeof("CHAR_CATEGORY_START_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_START_PUNCTUATION_name, &const_CHAR_CATEGORY_START_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_START_PUNCTUATION_name); + zend_string_release_ex(const_CHAR_CATEGORY_START_PUNCTUATION_name, true); zval const_CHAR_CATEGORY_END_PUNCTUATION_value; ZVAL_LONG(&const_CHAR_CATEGORY_END_PUNCTUATION_value, U_END_PUNCTUATION); - zend_string *const_CHAR_CATEGORY_END_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_END_PUNCTUATION", sizeof("CHAR_CATEGORY_END_PUNCTUATION") - 1, 1); + zend_string *const_CHAR_CATEGORY_END_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_END_PUNCTUATION", sizeof("CHAR_CATEGORY_END_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_END_PUNCTUATION_name, &const_CHAR_CATEGORY_END_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_END_PUNCTUATION_name); + zend_string_release_ex(const_CHAR_CATEGORY_END_PUNCTUATION_name, true); zval const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_value; ZVAL_LONG(&const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_value, U_CONNECTOR_PUNCTUATION); - zend_string *const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_CONNECTOR_PUNCTUATION", sizeof("CHAR_CATEGORY_CONNECTOR_PUNCTUATION") - 1, 1); + zend_string *const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_CONNECTOR_PUNCTUATION", sizeof("CHAR_CATEGORY_CONNECTOR_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_name, &const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_name); + zend_string_release_ex(const_CHAR_CATEGORY_CONNECTOR_PUNCTUATION_name, true); zval const_CHAR_CATEGORY_OTHER_PUNCTUATION_value; ZVAL_LONG(&const_CHAR_CATEGORY_OTHER_PUNCTUATION_value, U_OTHER_PUNCTUATION); - zend_string *const_CHAR_CATEGORY_OTHER_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_PUNCTUATION", sizeof("CHAR_CATEGORY_OTHER_PUNCTUATION") - 1, 1); + zend_string *const_CHAR_CATEGORY_OTHER_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_PUNCTUATION", sizeof("CHAR_CATEGORY_OTHER_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_OTHER_PUNCTUATION_name, &const_CHAR_CATEGORY_OTHER_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_OTHER_PUNCTUATION_name); + zend_string_release_ex(const_CHAR_CATEGORY_OTHER_PUNCTUATION_name, true); zval const_CHAR_CATEGORY_MATH_SYMBOL_value; ZVAL_LONG(&const_CHAR_CATEGORY_MATH_SYMBOL_value, U_MATH_SYMBOL); - zend_string *const_CHAR_CATEGORY_MATH_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_MATH_SYMBOL", sizeof("CHAR_CATEGORY_MATH_SYMBOL") - 1, 1); + zend_string *const_CHAR_CATEGORY_MATH_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_MATH_SYMBOL", sizeof("CHAR_CATEGORY_MATH_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_MATH_SYMBOL_name, &const_CHAR_CATEGORY_MATH_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_MATH_SYMBOL_name); + zend_string_release_ex(const_CHAR_CATEGORY_MATH_SYMBOL_name, true); zval const_CHAR_CATEGORY_CURRENCY_SYMBOL_value; ZVAL_LONG(&const_CHAR_CATEGORY_CURRENCY_SYMBOL_value, U_CURRENCY_SYMBOL); - zend_string *const_CHAR_CATEGORY_CURRENCY_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_CURRENCY_SYMBOL", sizeof("CHAR_CATEGORY_CURRENCY_SYMBOL") - 1, 1); + zend_string *const_CHAR_CATEGORY_CURRENCY_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_CURRENCY_SYMBOL", sizeof("CHAR_CATEGORY_CURRENCY_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_CURRENCY_SYMBOL_name, &const_CHAR_CATEGORY_CURRENCY_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_CURRENCY_SYMBOL_name); + zend_string_release_ex(const_CHAR_CATEGORY_CURRENCY_SYMBOL_name, true); zval const_CHAR_CATEGORY_MODIFIER_SYMBOL_value; ZVAL_LONG(&const_CHAR_CATEGORY_MODIFIER_SYMBOL_value, U_MODIFIER_SYMBOL); - zend_string *const_CHAR_CATEGORY_MODIFIER_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_MODIFIER_SYMBOL", sizeof("CHAR_CATEGORY_MODIFIER_SYMBOL") - 1, 1); + zend_string *const_CHAR_CATEGORY_MODIFIER_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_MODIFIER_SYMBOL", sizeof("CHAR_CATEGORY_MODIFIER_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_MODIFIER_SYMBOL_name, &const_CHAR_CATEGORY_MODIFIER_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_MODIFIER_SYMBOL_name); + zend_string_release_ex(const_CHAR_CATEGORY_MODIFIER_SYMBOL_name, true); zval const_CHAR_CATEGORY_OTHER_SYMBOL_value; ZVAL_LONG(&const_CHAR_CATEGORY_OTHER_SYMBOL_value, U_OTHER_SYMBOL); - zend_string *const_CHAR_CATEGORY_OTHER_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_SYMBOL", sizeof("CHAR_CATEGORY_OTHER_SYMBOL") - 1, 1); + zend_string *const_CHAR_CATEGORY_OTHER_SYMBOL_name = zend_string_init_interned("CHAR_CATEGORY_OTHER_SYMBOL", sizeof("CHAR_CATEGORY_OTHER_SYMBOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_OTHER_SYMBOL_name, &const_CHAR_CATEGORY_OTHER_SYMBOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_OTHER_SYMBOL_name); + zend_string_release_ex(const_CHAR_CATEGORY_OTHER_SYMBOL_name, true); zval const_CHAR_CATEGORY_INITIAL_PUNCTUATION_value; ZVAL_LONG(&const_CHAR_CATEGORY_INITIAL_PUNCTUATION_value, U_INITIAL_PUNCTUATION); - zend_string *const_CHAR_CATEGORY_INITIAL_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_INITIAL_PUNCTUATION", sizeof("CHAR_CATEGORY_INITIAL_PUNCTUATION") - 1, 1); + zend_string *const_CHAR_CATEGORY_INITIAL_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_INITIAL_PUNCTUATION", sizeof("CHAR_CATEGORY_INITIAL_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_INITIAL_PUNCTUATION_name, &const_CHAR_CATEGORY_INITIAL_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_INITIAL_PUNCTUATION_name); + zend_string_release_ex(const_CHAR_CATEGORY_INITIAL_PUNCTUATION_name, true); zval const_CHAR_CATEGORY_FINAL_PUNCTUATION_value; ZVAL_LONG(&const_CHAR_CATEGORY_FINAL_PUNCTUATION_value, U_FINAL_PUNCTUATION); - zend_string *const_CHAR_CATEGORY_FINAL_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_FINAL_PUNCTUATION", sizeof("CHAR_CATEGORY_FINAL_PUNCTUATION") - 1, 1); + zend_string *const_CHAR_CATEGORY_FINAL_PUNCTUATION_name = zend_string_init_interned("CHAR_CATEGORY_FINAL_PUNCTUATION", sizeof("CHAR_CATEGORY_FINAL_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_FINAL_PUNCTUATION_name, &const_CHAR_CATEGORY_FINAL_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_FINAL_PUNCTUATION_name); + zend_string_release_ex(const_CHAR_CATEGORY_FINAL_PUNCTUATION_name, true); zval const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_value; ZVAL_LONG(&const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_value, U_CHAR_CATEGORY_COUNT); - zend_string *const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_name = zend_string_init_interned("CHAR_CATEGORY_CHAR_CATEGORY_COUNT", sizeof("CHAR_CATEGORY_CHAR_CATEGORY_COUNT") - 1, 1); + zend_string *const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_name = zend_string_init_interned("CHAR_CATEGORY_CHAR_CATEGORY_COUNT", sizeof("CHAR_CATEGORY_CHAR_CATEGORY_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_name, &const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_name); + zend_string_release_ex(const_CHAR_CATEGORY_CHAR_CATEGORY_COUNT_name, true); zval const_CHAR_DIRECTION_LEFT_TO_RIGHT_value; ZVAL_LONG(&const_CHAR_DIRECTION_LEFT_TO_RIGHT_value, U_LEFT_TO_RIGHT); - zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT") - 1, 1); + zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_LEFT_TO_RIGHT_name, &const_CHAR_DIRECTION_LEFT_TO_RIGHT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_LEFT_TO_RIGHT_name); + zend_string_release_ex(const_CHAR_DIRECTION_LEFT_TO_RIGHT_name, true); zval const_CHAR_DIRECTION_RIGHT_TO_LEFT_value; ZVAL_LONG(&const_CHAR_DIRECTION_RIGHT_TO_LEFT_value, U_RIGHT_TO_LEFT); - zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT") - 1, 1); + zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_RIGHT_TO_LEFT_name, &const_CHAR_DIRECTION_RIGHT_TO_LEFT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_RIGHT_TO_LEFT_name); + zend_string_release_ex(const_CHAR_DIRECTION_RIGHT_TO_LEFT_name, true); zval const_CHAR_DIRECTION_EUROPEAN_NUMBER_value; ZVAL_LONG(&const_CHAR_DIRECTION_EUROPEAN_NUMBER_value, U_EUROPEAN_NUMBER); - zend_string *const_CHAR_DIRECTION_EUROPEAN_NUMBER_name = zend_string_init_interned("CHAR_DIRECTION_EUROPEAN_NUMBER", sizeof("CHAR_DIRECTION_EUROPEAN_NUMBER") - 1, 1); + zend_string *const_CHAR_DIRECTION_EUROPEAN_NUMBER_name = zend_string_init_interned("CHAR_DIRECTION_EUROPEAN_NUMBER", sizeof("CHAR_DIRECTION_EUROPEAN_NUMBER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_EUROPEAN_NUMBER_name, &const_CHAR_DIRECTION_EUROPEAN_NUMBER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_EUROPEAN_NUMBER_name); + zend_string_release_ex(const_CHAR_DIRECTION_EUROPEAN_NUMBER_name, true); zval const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_value; ZVAL_LONG(&const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_value, U_EUROPEAN_NUMBER_SEPARATOR); - zend_string *const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR", sizeof("CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR") - 1, 1); + zend_string *const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR", sizeof("CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_name, &const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_name); + zend_string_release_ex(const_CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR_name, true); zval const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_value; ZVAL_LONG(&const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_value, U_EUROPEAN_NUMBER_TERMINATOR); - zend_string *const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_name = zend_string_init_interned("CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR", sizeof("CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR") - 1, 1); + zend_string *const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_name = zend_string_init_interned("CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR", sizeof("CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_name, &const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_name); + zend_string_release_ex(const_CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR_name, true); zval const_CHAR_DIRECTION_ARABIC_NUMBER_value; ZVAL_LONG(&const_CHAR_DIRECTION_ARABIC_NUMBER_value, U_ARABIC_NUMBER); - zend_string *const_CHAR_DIRECTION_ARABIC_NUMBER_name = zend_string_init_interned("CHAR_DIRECTION_ARABIC_NUMBER", sizeof("CHAR_DIRECTION_ARABIC_NUMBER") - 1, 1); + zend_string *const_CHAR_DIRECTION_ARABIC_NUMBER_name = zend_string_init_interned("CHAR_DIRECTION_ARABIC_NUMBER", sizeof("CHAR_DIRECTION_ARABIC_NUMBER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_ARABIC_NUMBER_name, &const_CHAR_DIRECTION_ARABIC_NUMBER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_ARABIC_NUMBER_name); + zend_string_release_ex(const_CHAR_DIRECTION_ARABIC_NUMBER_name, true); zval const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_value; ZVAL_LONG(&const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_value, U_COMMON_NUMBER_SEPARATOR); - zend_string *const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR", sizeof("CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR") - 1, 1); + zend_string *const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR", sizeof("CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_name, &const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_name); + zend_string_release_ex(const_CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR_name, true); zval const_CHAR_DIRECTION_BLOCK_SEPARATOR_value; ZVAL_LONG(&const_CHAR_DIRECTION_BLOCK_SEPARATOR_value, U_BLOCK_SEPARATOR); - zend_string *const_CHAR_DIRECTION_BLOCK_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_BLOCK_SEPARATOR", sizeof("CHAR_DIRECTION_BLOCK_SEPARATOR") - 1, 1); + zend_string *const_CHAR_DIRECTION_BLOCK_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_BLOCK_SEPARATOR", sizeof("CHAR_DIRECTION_BLOCK_SEPARATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_BLOCK_SEPARATOR_name, &const_CHAR_DIRECTION_BLOCK_SEPARATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_BLOCK_SEPARATOR_name); + zend_string_release_ex(const_CHAR_DIRECTION_BLOCK_SEPARATOR_name, true); zval const_CHAR_DIRECTION_SEGMENT_SEPARATOR_value; ZVAL_LONG(&const_CHAR_DIRECTION_SEGMENT_SEPARATOR_value, U_SEGMENT_SEPARATOR); - zend_string *const_CHAR_DIRECTION_SEGMENT_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_SEGMENT_SEPARATOR", sizeof("CHAR_DIRECTION_SEGMENT_SEPARATOR") - 1, 1); + zend_string *const_CHAR_DIRECTION_SEGMENT_SEPARATOR_name = zend_string_init_interned("CHAR_DIRECTION_SEGMENT_SEPARATOR", sizeof("CHAR_DIRECTION_SEGMENT_SEPARATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_SEGMENT_SEPARATOR_name, &const_CHAR_DIRECTION_SEGMENT_SEPARATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_SEGMENT_SEPARATOR_name); + zend_string_release_ex(const_CHAR_DIRECTION_SEGMENT_SEPARATOR_name, true); zval const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_value; ZVAL_LONG(&const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_value, U_WHITE_SPACE_NEUTRAL); - zend_string *const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_name = zend_string_init_interned("CHAR_DIRECTION_WHITE_SPACE_NEUTRAL", sizeof("CHAR_DIRECTION_WHITE_SPACE_NEUTRAL") - 1, 1); + zend_string *const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_name = zend_string_init_interned("CHAR_DIRECTION_WHITE_SPACE_NEUTRAL", sizeof("CHAR_DIRECTION_WHITE_SPACE_NEUTRAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_name, &const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_name); + zend_string_release_ex(const_CHAR_DIRECTION_WHITE_SPACE_NEUTRAL_name, true); zval const_CHAR_DIRECTION_OTHER_NEUTRAL_value; ZVAL_LONG(&const_CHAR_DIRECTION_OTHER_NEUTRAL_value, U_OTHER_NEUTRAL); - zend_string *const_CHAR_DIRECTION_OTHER_NEUTRAL_name = zend_string_init_interned("CHAR_DIRECTION_OTHER_NEUTRAL", sizeof("CHAR_DIRECTION_OTHER_NEUTRAL") - 1, 1); + zend_string *const_CHAR_DIRECTION_OTHER_NEUTRAL_name = zend_string_init_interned("CHAR_DIRECTION_OTHER_NEUTRAL", sizeof("CHAR_DIRECTION_OTHER_NEUTRAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_OTHER_NEUTRAL_name, &const_CHAR_DIRECTION_OTHER_NEUTRAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_OTHER_NEUTRAL_name); + zend_string_release_ex(const_CHAR_DIRECTION_OTHER_NEUTRAL_name, true); zval const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_value; ZVAL_LONG(&const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_value, U_LEFT_TO_RIGHT_EMBEDDING); - zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING") - 1, 1); + zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_name, &const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_name); + zend_string_release_ex(const_CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING_name, true); zval const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_value; ZVAL_LONG(&const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_value, U_LEFT_TO_RIGHT_OVERRIDE); - zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE") - 1, 1); + zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_name, &const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_name); + zend_string_release_ex(const_CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE_name, true); zval const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_value; ZVAL_LONG(&const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_value, U_RIGHT_TO_LEFT_ARABIC); - zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC") - 1, 1); + zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_name, &const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_name); + zend_string_release_ex(const_CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC_name, true); zval const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_value; ZVAL_LONG(&const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_value, U_RIGHT_TO_LEFT_EMBEDDING); - zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING") - 1, 1); + zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_name, &const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_name); + zend_string_release_ex(const_CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING_name, true); zval const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_value; ZVAL_LONG(&const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_value, U_RIGHT_TO_LEFT_OVERRIDE); - zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE") - 1, 1); + zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_name, &const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_name); + zend_string_release_ex(const_CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE_name, true); zval const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_value; ZVAL_LONG(&const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_value, U_POP_DIRECTIONAL_FORMAT); - zend_string *const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_name = zend_string_init_interned("CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT", sizeof("CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT") - 1, 1); + zend_string *const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_name = zend_string_init_interned("CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT", sizeof("CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_name, &const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_name); + zend_string_release_ex(const_CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT_name, true); zval const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_value; ZVAL_LONG(&const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_value, U_DIR_NON_SPACING_MARK); - zend_string *const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_name = zend_string_init_interned("CHAR_DIRECTION_DIR_NON_SPACING_MARK", sizeof("CHAR_DIRECTION_DIR_NON_SPACING_MARK") - 1, 1); + zend_string *const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_name = zend_string_init_interned("CHAR_DIRECTION_DIR_NON_SPACING_MARK", sizeof("CHAR_DIRECTION_DIR_NON_SPACING_MARK") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_name, &const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_name); + zend_string_release_ex(const_CHAR_DIRECTION_DIR_NON_SPACING_MARK_name, true); zval const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_value; ZVAL_LONG(&const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_value, U_BOUNDARY_NEUTRAL); - zend_string *const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_name = zend_string_init_interned("CHAR_DIRECTION_BOUNDARY_NEUTRAL", sizeof("CHAR_DIRECTION_BOUNDARY_NEUTRAL") - 1, 1); + zend_string *const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_name = zend_string_init_interned("CHAR_DIRECTION_BOUNDARY_NEUTRAL", sizeof("CHAR_DIRECTION_BOUNDARY_NEUTRAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_name, &const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_name); + zend_string_release_ex(const_CHAR_DIRECTION_BOUNDARY_NEUTRAL_name, true); zval const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_value; ZVAL_LONG(&const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_value, U_FIRST_STRONG_ISOLATE); - zend_string *const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_FIRST_STRONG_ISOLATE", sizeof("CHAR_DIRECTION_FIRST_STRONG_ISOLATE") - 1, 1); + zend_string *const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_FIRST_STRONG_ISOLATE", sizeof("CHAR_DIRECTION_FIRST_STRONG_ISOLATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_name, &const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_name); + zend_string_release_ex(const_CHAR_DIRECTION_FIRST_STRONG_ISOLATE_name, true); zval const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_value; ZVAL_LONG(&const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_value, U_LEFT_TO_RIGHT_ISOLATE); - zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE") - 1, 1); + zend_string *const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE", sizeof("CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_name, &const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_name); + zend_string_release_ex(const_CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE_name, true); zval const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_value; ZVAL_LONG(&const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_value, U_RIGHT_TO_LEFT_ISOLATE); - zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE") - 1, 1); + zend_string *const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE", sizeof("CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_name, &const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_name); + zend_string_release_ex(const_CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE_name, true); zval const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_value; ZVAL_LONG(&const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_value, U_POP_DIRECTIONAL_ISOLATE); - zend_string *const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE", sizeof("CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE") - 1, 1); + zend_string *const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_name = zend_string_init_interned("CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE", sizeof("CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_name, &const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_name); + zend_string_release_ex(const_CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE_name, true); zval const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_value; ZVAL_LONG(&const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_value, U_CHAR_DIRECTION_COUNT); - zend_string *const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_name = zend_string_init_interned("CHAR_DIRECTION_CHAR_DIRECTION_COUNT", sizeof("CHAR_DIRECTION_CHAR_DIRECTION_COUNT") - 1, 1); + zend_string *const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_name = zend_string_init_interned("CHAR_DIRECTION_CHAR_DIRECTION_COUNT", sizeof("CHAR_DIRECTION_CHAR_DIRECTION_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_name, &const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_name); + zend_string_release_ex(const_CHAR_DIRECTION_CHAR_DIRECTION_COUNT_name, true); zval const_BLOCK_CODE_NO_BLOCK_value; ZVAL_LONG(&const_BLOCK_CODE_NO_BLOCK_value, UBLOCK_NO_BLOCK); - zend_string *const_BLOCK_CODE_NO_BLOCK_name = zend_string_init_interned("BLOCK_CODE_NO_BLOCK", sizeof("BLOCK_CODE_NO_BLOCK") - 1, 1); + zend_string *const_BLOCK_CODE_NO_BLOCK_name = zend_string_init_interned("BLOCK_CODE_NO_BLOCK", sizeof("BLOCK_CODE_NO_BLOCK") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_NO_BLOCK_name, &const_BLOCK_CODE_NO_BLOCK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_NO_BLOCK_name); + zend_string_release_ex(const_BLOCK_CODE_NO_BLOCK_name, true); zval const_BLOCK_CODE_BASIC_LATIN_value; ZVAL_LONG(&const_BLOCK_CODE_BASIC_LATIN_value, UBLOCK_BASIC_LATIN); - zend_string *const_BLOCK_CODE_BASIC_LATIN_name = zend_string_init_interned("BLOCK_CODE_BASIC_LATIN", sizeof("BLOCK_CODE_BASIC_LATIN") - 1, 1); + zend_string *const_BLOCK_CODE_BASIC_LATIN_name = zend_string_init_interned("BLOCK_CODE_BASIC_LATIN", sizeof("BLOCK_CODE_BASIC_LATIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BASIC_LATIN_name, &const_BLOCK_CODE_BASIC_LATIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BASIC_LATIN_name); + zend_string_release_ex(const_BLOCK_CODE_BASIC_LATIN_name, true); zval const_BLOCK_CODE_LATIN_1_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_LATIN_1_SUPPLEMENT_value, UBLOCK_LATIN_1_SUPPLEMENT); - zend_string *const_BLOCK_CODE_LATIN_1_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_LATIN_1_SUPPLEMENT", sizeof("BLOCK_CODE_LATIN_1_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_LATIN_1_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_LATIN_1_SUPPLEMENT", sizeof("BLOCK_CODE_LATIN_1_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LATIN_1_SUPPLEMENT_name, &const_BLOCK_CODE_LATIN_1_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LATIN_1_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_LATIN_1_SUPPLEMENT_name, true); zval const_BLOCK_CODE_LATIN_EXTENDED_A_value; ZVAL_LONG(&const_BLOCK_CODE_LATIN_EXTENDED_A_value, UBLOCK_LATIN_EXTENDED_A); - zend_string *const_BLOCK_CODE_LATIN_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_A", sizeof("BLOCK_CODE_LATIN_EXTENDED_A") - 1, 1); + zend_string *const_BLOCK_CODE_LATIN_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_A", sizeof("BLOCK_CODE_LATIN_EXTENDED_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LATIN_EXTENDED_A_name, &const_BLOCK_CODE_LATIN_EXTENDED_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LATIN_EXTENDED_A_name); + zend_string_release_ex(const_BLOCK_CODE_LATIN_EXTENDED_A_name, true); zval const_BLOCK_CODE_LATIN_EXTENDED_B_value; ZVAL_LONG(&const_BLOCK_CODE_LATIN_EXTENDED_B_value, UBLOCK_LATIN_EXTENDED_B); - zend_string *const_BLOCK_CODE_LATIN_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_B", sizeof("BLOCK_CODE_LATIN_EXTENDED_B") - 1, 1); + zend_string *const_BLOCK_CODE_LATIN_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_B", sizeof("BLOCK_CODE_LATIN_EXTENDED_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LATIN_EXTENDED_B_name, &const_BLOCK_CODE_LATIN_EXTENDED_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LATIN_EXTENDED_B_name); + zend_string_release_ex(const_BLOCK_CODE_LATIN_EXTENDED_B_name, true); zval const_BLOCK_CODE_IPA_EXTENSIONS_value; ZVAL_LONG(&const_BLOCK_CODE_IPA_EXTENSIONS_value, UBLOCK_IPA_EXTENSIONS); - zend_string *const_BLOCK_CODE_IPA_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_IPA_EXTENSIONS", sizeof("BLOCK_CODE_IPA_EXTENSIONS") - 1, 1); + zend_string *const_BLOCK_CODE_IPA_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_IPA_EXTENSIONS", sizeof("BLOCK_CODE_IPA_EXTENSIONS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_IPA_EXTENSIONS_name, &const_BLOCK_CODE_IPA_EXTENSIONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_IPA_EXTENSIONS_name); + zend_string_release_ex(const_BLOCK_CODE_IPA_EXTENSIONS_name, true); zval const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_value; ZVAL_LONG(&const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_value, UBLOCK_SPACING_MODIFIER_LETTERS); - zend_string *const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_name = zend_string_init_interned("BLOCK_CODE_SPACING_MODIFIER_LETTERS", sizeof("BLOCK_CODE_SPACING_MODIFIER_LETTERS") - 1, 1); + zend_string *const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_name = zend_string_init_interned("BLOCK_CODE_SPACING_MODIFIER_LETTERS", sizeof("BLOCK_CODE_SPACING_MODIFIER_LETTERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_name, &const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_name); + zend_string_release_ex(const_BLOCK_CODE_SPACING_MODIFIER_LETTERS_name, true); zval const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_value; ZVAL_LONG(&const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_value, UBLOCK_COMBINING_DIACRITICAL_MARKS); - zend_string *const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_name = zend_string_init_interned("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS", sizeof("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS") - 1, 1); + zend_string *const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_name = zend_string_init_interned("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS", sizeof("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_name, &const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_name); + zend_string_release_ex(const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_name, true); zval const_BLOCK_CODE_GREEK_value; ZVAL_LONG(&const_BLOCK_CODE_GREEK_value, UBLOCK_GREEK); - zend_string *const_BLOCK_CODE_GREEK_name = zend_string_init_interned("BLOCK_CODE_GREEK", sizeof("BLOCK_CODE_GREEK") - 1, 1); + zend_string *const_BLOCK_CODE_GREEK_name = zend_string_init_interned("BLOCK_CODE_GREEK", sizeof("BLOCK_CODE_GREEK") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GREEK_name, &const_BLOCK_CODE_GREEK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GREEK_name); + zend_string_release_ex(const_BLOCK_CODE_GREEK_name, true); zval const_BLOCK_CODE_CYRILLIC_value; ZVAL_LONG(&const_BLOCK_CODE_CYRILLIC_value, UBLOCK_CYRILLIC); - zend_string *const_BLOCK_CODE_CYRILLIC_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC", sizeof("BLOCK_CODE_CYRILLIC") - 1, 1); + zend_string *const_BLOCK_CODE_CYRILLIC_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC", sizeof("BLOCK_CODE_CYRILLIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CYRILLIC_name, &const_BLOCK_CODE_CYRILLIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CYRILLIC_name); + zend_string_release_ex(const_BLOCK_CODE_CYRILLIC_name, true); zval const_BLOCK_CODE_ARMENIAN_value; ZVAL_LONG(&const_BLOCK_CODE_ARMENIAN_value, UBLOCK_ARMENIAN); - zend_string *const_BLOCK_CODE_ARMENIAN_name = zend_string_init_interned("BLOCK_CODE_ARMENIAN", sizeof("BLOCK_CODE_ARMENIAN") - 1, 1); + zend_string *const_BLOCK_CODE_ARMENIAN_name = zend_string_init_interned("BLOCK_CODE_ARMENIAN", sizeof("BLOCK_CODE_ARMENIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARMENIAN_name, &const_BLOCK_CODE_ARMENIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARMENIAN_name); + zend_string_release_ex(const_BLOCK_CODE_ARMENIAN_name, true); zval const_BLOCK_CODE_HEBREW_value; ZVAL_LONG(&const_BLOCK_CODE_HEBREW_value, UBLOCK_HEBREW); - zend_string *const_BLOCK_CODE_HEBREW_name = zend_string_init_interned("BLOCK_CODE_HEBREW", sizeof("BLOCK_CODE_HEBREW") - 1, 1); + zend_string *const_BLOCK_CODE_HEBREW_name = zend_string_init_interned("BLOCK_CODE_HEBREW", sizeof("BLOCK_CODE_HEBREW") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HEBREW_name, &const_BLOCK_CODE_HEBREW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HEBREW_name); + zend_string_release_ex(const_BLOCK_CODE_HEBREW_name, true); zval const_BLOCK_CODE_ARABIC_value; ZVAL_LONG(&const_BLOCK_CODE_ARABIC_value, UBLOCK_ARABIC); - zend_string *const_BLOCK_CODE_ARABIC_name = zend_string_init_interned("BLOCK_CODE_ARABIC", sizeof("BLOCK_CODE_ARABIC") - 1, 1); + zend_string *const_BLOCK_CODE_ARABIC_name = zend_string_init_interned("BLOCK_CODE_ARABIC", sizeof("BLOCK_CODE_ARABIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARABIC_name, &const_BLOCK_CODE_ARABIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARABIC_name); + zend_string_release_ex(const_BLOCK_CODE_ARABIC_name, true); zval const_BLOCK_CODE_SYRIAC_value; ZVAL_LONG(&const_BLOCK_CODE_SYRIAC_value, UBLOCK_SYRIAC); - zend_string *const_BLOCK_CODE_SYRIAC_name = zend_string_init_interned("BLOCK_CODE_SYRIAC", sizeof("BLOCK_CODE_SYRIAC") - 1, 1); + zend_string *const_BLOCK_CODE_SYRIAC_name = zend_string_init_interned("BLOCK_CODE_SYRIAC", sizeof("BLOCK_CODE_SYRIAC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SYRIAC_name, &const_BLOCK_CODE_SYRIAC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SYRIAC_name); + zend_string_release_ex(const_BLOCK_CODE_SYRIAC_name, true); zval const_BLOCK_CODE_THAANA_value; ZVAL_LONG(&const_BLOCK_CODE_THAANA_value, UBLOCK_THAANA); - zend_string *const_BLOCK_CODE_THAANA_name = zend_string_init_interned("BLOCK_CODE_THAANA", sizeof("BLOCK_CODE_THAANA") - 1, 1); + zend_string *const_BLOCK_CODE_THAANA_name = zend_string_init_interned("BLOCK_CODE_THAANA", sizeof("BLOCK_CODE_THAANA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_THAANA_name, &const_BLOCK_CODE_THAANA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_THAANA_name); + zend_string_release_ex(const_BLOCK_CODE_THAANA_name, true); zval const_BLOCK_CODE_DEVANAGARI_value; ZVAL_LONG(&const_BLOCK_CODE_DEVANAGARI_value, UBLOCK_DEVANAGARI); - zend_string *const_BLOCK_CODE_DEVANAGARI_name = zend_string_init_interned("BLOCK_CODE_DEVANAGARI", sizeof("BLOCK_CODE_DEVANAGARI") - 1, 1); + zend_string *const_BLOCK_CODE_DEVANAGARI_name = zend_string_init_interned("BLOCK_CODE_DEVANAGARI", sizeof("BLOCK_CODE_DEVANAGARI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_DEVANAGARI_name, &const_BLOCK_CODE_DEVANAGARI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_DEVANAGARI_name); + zend_string_release_ex(const_BLOCK_CODE_DEVANAGARI_name, true); zval const_BLOCK_CODE_BENGALI_value; ZVAL_LONG(&const_BLOCK_CODE_BENGALI_value, UBLOCK_BENGALI); - zend_string *const_BLOCK_CODE_BENGALI_name = zend_string_init_interned("BLOCK_CODE_BENGALI", sizeof("BLOCK_CODE_BENGALI") - 1, 1); + zend_string *const_BLOCK_CODE_BENGALI_name = zend_string_init_interned("BLOCK_CODE_BENGALI", sizeof("BLOCK_CODE_BENGALI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BENGALI_name, &const_BLOCK_CODE_BENGALI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BENGALI_name); + zend_string_release_ex(const_BLOCK_CODE_BENGALI_name, true); zval const_BLOCK_CODE_GURMUKHI_value; ZVAL_LONG(&const_BLOCK_CODE_GURMUKHI_value, UBLOCK_GURMUKHI); - zend_string *const_BLOCK_CODE_GURMUKHI_name = zend_string_init_interned("BLOCK_CODE_GURMUKHI", sizeof("BLOCK_CODE_GURMUKHI") - 1, 1); + zend_string *const_BLOCK_CODE_GURMUKHI_name = zend_string_init_interned("BLOCK_CODE_GURMUKHI", sizeof("BLOCK_CODE_GURMUKHI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GURMUKHI_name, &const_BLOCK_CODE_GURMUKHI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GURMUKHI_name); + zend_string_release_ex(const_BLOCK_CODE_GURMUKHI_name, true); zval const_BLOCK_CODE_GUJARATI_value; ZVAL_LONG(&const_BLOCK_CODE_GUJARATI_value, UBLOCK_GUJARATI); - zend_string *const_BLOCK_CODE_GUJARATI_name = zend_string_init_interned("BLOCK_CODE_GUJARATI", sizeof("BLOCK_CODE_GUJARATI") - 1, 1); + zend_string *const_BLOCK_CODE_GUJARATI_name = zend_string_init_interned("BLOCK_CODE_GUJARATI", sizeof("BLOCK_CODE_GUJARATI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GUJARATI_name, &const_BLOCK_CODE_GUJARATI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GUJARATI_name); + zend_string_release_ex(const_BLOCK_CODE_GUJARATI_name, true); zval const_BLOCK_CODE_ORIYA_value; ZVAL_LONG(&const_BLOCK_CODE_ORIYA_value, UBLOCK_ORIYA); - zend_string *const_BLOCK_CODE_ORIYA_name = zend_string_init_interned("BLOCK_CODE_ORIYA", sizeof("BLOCK_CODE_ORIYA") - 1, 1); + zend_string *const_BLOCK_CODE_ORIYA_name = zend_string_init_interned("BLOCK_CODE_ORIYA", sizeof("BLOCK_CODE_ORIYA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ORIYA_name, &const_BLOCK_CODE_ORIYA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ORIYA_name); + zend_string_release_ex(const_BLOCK_CODE_ORIYA_name, true); zval const_BLOCK_CODE_TAMIL_value; ZVAL_LONG(&const_BLOCK_CODE_TAMIL_value, UBLOCK_TAMIL); - zend_string *const_BLOCK_CODE_TAMIL_name = zend_string_init_interned("BLOCK_CODE_TAMIL", sizeof("BLOCK_CODE_TAMIL") - 1, 1); + zend_string *const_BLOCK_CODE_TAMIL_name = zend_string_init_interned("BLOCK_CODE_TAMIL", sizeof("BLOCK_CODE_TAMIL") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAMIL_name, &const_BLOCK_CODE_TAMIL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAMIL_name); + zend_string_release_ex(const_BLOCK_CODE_TAMIL_name, true); zval const_BLOCK_CODE_TELUGU_value; ZVAL_LONG(&const_BLOCK_CODE_TELUGU_value, UBLOCK_TELUGU); - zend_string *const_BLOCK_CODE_TELUGU_name = zend_string_init_interned("BLOCK_CODE_TELUGU", sizeof("BLOCK_CODE_TELUGU") - 1, 1); + zend_string *const_BLOCK_CODE_TELUGU_name = zend_string_init_interned("BLOCK_CODE_TELUGU", sizeof("BLOCK_CODE_TELUGU") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TELUGU_name, &const_BLOCK_CODE_TELUGU_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TELUGU_name); + zend_string_release_ex(const_BLOCK_CODE_TELUGU_name, true); zval const_BLOCK_CODE_KANNADA_value; ZVAL_LONG(&const_BLOCK_CODE_KANNADA_value, UBLOCK_KANNADA); - zend_string *const_BLOCK_CODE_KANNADA_name = zend_string_init_interned("BLOCK_CODE_KANNADA", sizeof("BLOCK_CODE_KANNADA") - 1, 1); + zend_string *const_BLOCK_CODE_KANNADA_name = zend_string_init_interned("BLOCK_CODE_KANNADA", sizeof("BLOCK_CODE_KANNADA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KANNADA_name, &const_BLOCK_CODE_KANNADA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KANNADA_name); + zend_string_release_ex(const_BLOCK_CODE_KANNADA_name, true); zval const_BLOCK_CODE_MALAYALAM_value; ZVAL_LONG(&const_BLOCK_CODE_MALAYALAM_value, UBLOCK_MALAYALAM); - zend_string *const_BLOCK_CODE_MALAYALAM_name = zend_string_init_interned("BLOCK_CODE_MALAYALAM", sizeof("BLOCK_CODE_MALAYALAM") - 1, 1); + zend_string *const_BLOCK_CODE_MALAYALAM_name = zend_string_init_interned("BLOCK_CODE_MALAYALAM", sizeof("BLOCK_CODE_MALAYALAM") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MALAYALAM_name, &const_BLOCK_CODE_MALAYALAM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MALAYALAM_name); + zend_string_release_ex(const_BLOCK_CODE_MALAYALAM_name, true); zval const_BLOCK_CODE_SINHALA_value; ZVAL_LONG(&const_BLOCK_CODE_SINHALA_value, UBLOCK_SINHALA); - zend_string *const_BLOCK_CODE_SINHALA_name = zend_string_init_interned("BLOCK_CODE_SINHALA", sizeof("BLOCK_CODE_SINHALA") - 1, 1); + zend_string *const_BLOCK_CODE_SINHALA_name = zend_string_init_interned("BLOCK_CODE_SINHALA", sizeof("BLOCK_CODE_SINHALA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SINHALA_name, &const_BLOCK_CODE_SINHALA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SINHALA_name); + zend_string_release_ex(const_BLOCK_CODE_SINHALA_name, true); zval const_BLOCK_CODE_THAI_value; ZVAL_LONG(&const_BLOCK_CODE_THAI_value, UBLOCK_THAI); - zend_string *const_BLOCK_CODE_THAI_name = zend_string_init_interned("BLOCK_CODE_THAI", sizeof("BLOCK_CODE_THAI") - 1, 1); + zend_string *const_BLOCK_CODE_THAI_name = zend_string_init_interned("BLOCK_CODE_THAI", sizeof("BLOCK_CODE_THAI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_THAI_name, &const_BLOCK_CODE_THAI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_THAI_name); + zend_string_release_ex(const_BLOCK_CODE_THAI_name, true); zval const_BLOCK_CODE_LAO_value; ZVAL_LONG(&const_BLOCK_CODE_LAO_value, UBLOCK_LAO); - zend_string *const_BLOCK_CODE_LAO_name = zend_string_init_interned("BLOCK_CODE_LAO", sizeof("BLOCK_CODE_LAO") - 1, 1); + zend_string *const_BLOCK_CODE_LAO_name = zend_string_init_interned("BLOCK_CODE_LAO", sizeof("BLOCK_CODE_LAO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LAO_name, &const_BLOCK_CODE_LAO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LAO_name); + zend_string_release_ex(const_BLOCK_CODE_LAO_name, true); zval const_BLOCK_CODE_TIBETAN_value; ZVAL_LONG(&const_BLOCK_CODE_TIBETAN_value, UBLOCK_TIBETAN); - zend_string *const_BLOCK_CODE_TIBETAN_name = zend_string_init_interned("BLOCK_CODE_TIBETAN", sizeof("BLOCK_CODE_TIBETAN") - 1, 1); + zend_string *const_BLOCK_CODE_TIBETAN_name = zend_string_init_interned("BLOCK_CODE_TIBETAN", sizeof("BLOCK_CODE_TIBETAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TIBETAN_name, &const_BLOCK_CODE_TIBETAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TIBETAN_name); + zend_string_release_ex(const_BLOCK_CODE_TIBETAN_name, true); zval const_BLOCK_CODE_MYANMAR_value; ZVAL_LONG(&const_BLOCK_CODE_MYANMAR_value, UBLOCK_MYANMAR); - zend_string *const_BLOCK_CODE_MYANMAR_name = zend_string_init_interned("BLOCK_CODE_MYANMAR", sizeof("BLOCK_CODE_MYANMAR") - 1, 1); + zend_string *const_BLOCK_CODE_MYANMAR_name = zend_string_init_interned("BLOCK_CODE_MYANMAR", sizeof("BLOCK_CODE_MYANMAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MYANMAR_name, &const_BLOCK_CODE_MYANMAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MYANMAR_name); + zend_string_release_ex(const_BLOCK_CODE_MYANMAR_name, true); zval const_BLOCK_CODE_GEORGIAN_value; ZVAL_LONG(&const_BLOCK_CODE_GEORGIAN_value, UBLOCK_GEORGIAN); - zend_string *const_BLOCK_CODE_GEORGIAN_name = zend_string_init_interned("BLOCK_CODE_GEORGIAN", sizeof("BLOCK_CODE_GEORGIAN") - 1, 1); + zend_string *const_BLOCK_CODE_GEORGIAN_name = zend_string_init_interned("BLOCK_CODE_GEORGIAN", sizeof("BLOCK_CODE_GEORGIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GEORGIAN_name, &const_BLOCK_CODE_GEORGIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GEORGIAN_name); + zend_string_release_ex(const_BLOCK_CODE_GEORGIAN_name, true); zval const_BLOCK_CODE_HANGUL_JAMO_value; ZVAL_LONG(&const_BLOCK_CODE_HANGUL_JAMO_value, UBLOCK_HANGUL_JAMO); - zend_string *const_BLOCK_CODE_HANGUL_JAMO_name = zend_string_init_interned("BLOCK_CODE_HANGUL_JAMO", sizeof("BLOCK_CODE_HANGUL_JAMO") - 1, 1); + zend_string *const_BLOCK_CODE_HANGUL_JAMO_name = zend_string_init_interned("BLOCK_CODE_HANGUL_JAMO", sizeof("BLOCK_CODE_HANGUL_JAMO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HANGUL_JAMO_name, &const_BLOCK_CODE_HANGUL_JAMO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HANGUL_JAMO_name); + zend_string_release_ex(const_BLOCK_CODE_HANGUL_JAMO_name, true); zval const_BLOCK_CODE_ETHIOPIC_value; ZVAL_LONG(&const_BLOCK_CODE_ETHIOPIC_value, UBLOCK_ETHIOPIC); - zend_string *const_BLOCK_CODE_ETHIOPIC_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC", sizeof("BLOCK_CODE_ETHIOPIC") - 1, 1); + zend_string *const_BLOCK_CODE_ETHIOPIC_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC", sizeof("BLOCK_CODE_ETHIOPIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ETHIOPIC_name, &const_BLOCK_CODE_ETHIOPIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ETHIOPIC_name); + zend_string_release_ex(const_BLOCK_CODE_ETHIOPIC_name, true); zval const_BLOCK_CODE_CHEROKEE_value; ZVAL_LONG(&const_BLOCK_CODE_CHEROKEE_value, UBLOCK_CHEROKEE); - zend_string *const_BLOCK_CODE_CHEROKEE_name = zend_string_init_interned("BLOCK_CODE_CHEROKEE", sizeof("BLOCK_CODE_CHEROKEE") - 1, 1); + zend_string *const_BLOCK_CODE_CHEROKEE_name = zend_string_init_interned("BLOCK_CODE_CHEROKEE", sizeof("BLOCK_CODE_CHEROKEE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CHEROKEE_name, &const_BLOCK_CODE_CHEROKEE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CHEROKEE_name); + zend_string_release_ex(const_BLOCK_CODE_CHEROKEE_name, true); zval const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_value; ZVAL_LONG(&const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_value, UBLOCK_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS); - zend_string *const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_name = zend_string_init_interned("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS", sizeof("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS") - 1, 1); + zend_string *const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_name = zend_string_init_interned("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS", sizeof("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_name, &const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_name); + zend_string_release_ex(const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_name, true); zval const_BLOCK_CODE_OGHAM_value; ZVAL_LONG(&const_BLOCK_CODE_OGHAM_value, UBLOCK_OGHAM); - zend_string *const_BLOCK_CODE_OGHAM_name = zend_string_init_interned("BLOCK_CODE_OGHAM", sizeof("BLOCK_CODE_OGHAM") - 1, 1); + zend_string *const_BLOCK_CODE_OGHAM_name = zend_string_init_interned("BLOCK_CODE_OGHAM", sizeof("BLOCK_CODE_OGHAM") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OGHAM_name, &const_BLOCK_CODE_OGHAM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OGHAM_name); + zend_string_release_ex(const_BLOCK_CODE_OGHAM_name, true); zval const_BLOCK_CODE_RUNIC_value; ZVAL_LONG(&const_BLOCK_CODE_RUNIC_value, UBLOCK_RUNIC); - zend_string *const_BLOCK_CODE_RUNIC_name = zend_string_init_interned("BLOCK_CODE_RUNIC", sizeof("BLOCK_CODE_RUNIC") - 1, 1); + zend_string *const_BLOCK_CODE_RUNIC_name = zend_string_init_interned("BLOCK_CODE_RUNIC", sizeof("BLOCK_CODE_RUNIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_RUNIC_name, &const_BLOCK_CODE_RUNIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_RUNIC_name); + zend_string_release_ex(const_BLOCK_CODE_RUNIC_name, true); zval const_BLOCK_CODE_KHMER_value; ZVAL_LONG(&const_BLOCK_CODE_KHMER_value, UBLOCK_KHMER); - zend_string *const_BLOCK_CODE_KHMER_name = zend_string_init_interned("BLOCK_CODE_KHMER", sizeof("BLOCK_CODE_KHMER") - 1, 1); + zend_string *const_BLOCK_CODE_KHMER_name = zend_string_init_interned("BLOCK_CODE_KHMER", sizeof("BLOCK_CODE_KHMER") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KHMER_name, &const_BLOCK_CODE_KHMER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KHMER_name); + zend_string_release_ex(const_BLOCK_CODE_KHMER_name, true); zval const_BLOCK_CODE_MONGOLIAN_value; ZVAL_LONG(&const_BLOCK_CODE_MONGOLIAN_value, UBLOCK_MONGOLIAN); - zend_string *const_BLOCK_CODE_MONGOLIAN_name = zend_string_init_interned("BLOCK_CODE_MONGOLIAN", sizeof("BLOCK_CODE_MONGOLIAN") - 1, 1); + zend_string *const_BLOCK_CODE_MONGOLIAN_name = zend_string_init_interned("BLOCK_CODE_MONGOLIAN", sizeof("BLOCK_CODE_MONGOLIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MONGOLIAN_name, &const_BLOCK_CODE_MONGOLIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MONGOLIAN_name); + zend_string_release_ex(const_BLOCK_CODE_MONGOLIAN_name, true); zval const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_value; ZVAL_LONG(&const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_value, UBLOCK_LATIN_EXTENDED_ADDITIONAL); - zend_string *const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL", sizeof("BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL") - 1, 1); + zend_string *const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL", sizeof("BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_name, &const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_name); + zend_string_release_ex(const_BLOCK_CODE_LATIN_EXTENDED_ADDITIONAL_name, true); zval const_BLOCK_CODE_GREEK_EXTENDED_value; ZVAL_LONG(&const_BLOCK_CODE_GREEK_EXTENDED_value, UBLOCK_GREEK_EXTENDED); - zend_string *const_BLOCK_CODE_GREEK_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_GREEK_EXTENDED", sizeof("BLOCK_CODE_GREEK_EXTENDED") - 1, 1); + zend_string *const_BLOCK_CODE_GREEK_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_GREEK_EXTENDED", sizeof("BLOCK_CODE_GREEK_EXTENDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GREEK_EXTENDED_name, &const_BLOCK_CODE_GREEK_EXTENDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GREEK_EXTENDED_name); + zend_string_release_ex(const_BLOCK_CODE_GREEK_EXTENDED_name, true); zval const_BLOCK_CODE_GENERAL_PUNCTUATION_value; ZVAL_LONG(&const_BLOCK_CODE_GENERAL_PUNCTUATION_value, UBLOCK_GENERAL_PUNCTUATION); - zend_string *const_BLOCK_CODE_GENERAL_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_GENERAL_PUNCTUATION", sizeof("BLOCK_CODE_GENERAL_PUNCTUATION") - 1, 1); + zend_string *const_BLOCK_CODE_GENERAL_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_GENERAL_PUNCTUATION", sizeof("BLOCK_CODE_GENERAL_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GENERAL_PUNCTUATION_name, &const_BLOCK_CODE_GENERAL_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GENERAL_PUNCTUATION_name); + zend_string_release_ex(const_BLOCK_CODE_GENERAL_PUNCTUATION_name, true); zval const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_value; ZVAL_LONG(&const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_value, UBLOCK_SUPERSCRIPTS_AND_SUBSCRIPTS); - zend_string *const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_name = zend_string_init_interned("BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS", sizeof("BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS") - 1, 1); + zend_string *const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_name = zend_string_init_interned("BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS", sizeof("BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_name, &const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_name); + zend_string_release_ex(const_BLOCK_CODE_SUPERSCRIPTS_AND_SUBSCRIPTS_name, true); zval const_BLOCK_CODE_CURRENCY_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_CURRENCY_SYMBOLS_value, UBLOCK_CURRENCY_SYMBOLS); - zend_string *const_BLOCK_CODE_CURRENCY_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_CURRENCY_SYMBOLS", sizeof("BLOCK_CODE_CURRENCY_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_CURRENCY_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_CURRENCY_SYMBOLS", sizeof("BLOCK_CODE_CURRENCY_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CURRENCY_SYMBOLS_name, &const_BLOCK_CODE_CURRENCY_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CURRENCY_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_CURRENCY_SYMBOLS_name, true); zval const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_value, UBLOCK_COMBINING_MARKS_FOR_SYMBOLS); - zend_string *const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS", sizeof("BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS", sizeof("BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_name, &const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_COMBINING_MARKS_FOR_SYMBOLS_name, true); zval const_BLOCK_CODE_LETTERLIKE_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_LETTERLIKE_SYMBOLS_value, UBLOCK_LETTERLIKE_SYMBOLS); - zend_string *const_BLOCK_CODE_LETTERLIKE_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_LETTERLIKE_SYMBOLS", sizeof("BLOCK_CODE_LETTERLIKE_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_LETTERLIKE_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_LETTERLIKE_SYMBOLS", sizeof("BLOCK_CODE_LETTERLIKE_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LETTERLIKE_SYMBOLS_name, &const_BLOCK_CODE_LETTERLIKE_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LETTERLIKE_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_LETTERLIKE_SYMBOLS_name, true); zval const_BLOCK_CODE_NUMBER_FORMS_value; ZVAL_LONG(&const_BLOCK_CODE_NUMBER_FORMS_value, UBLOCK_NUMBER_FORMS); - zend_string *const_BLOCK_CODE_NUMBER_FORMS_name = zend_string_init_interned("BLOCK_CODE_NUMBER_FORMS", sizeof("BLOCK_CODE_NUMBER_FORMS") - 1, 1); + zend_string *const_BLOCK_CODE_NUMBER_FORMS_name = zend_string_init_interned("BLOCK_CODE_NUMBER_FORMS", sizeof("BLOCK_CODE_NUMBER_FORMS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_NUMBER_FORMS_name, &const_BLOCK_CODE_NUMBER_FORMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_NUMBER_FORMS_name); + zend_string_release_ex(const_BLOCK_CODE_NUMBER_FORMS_name, true); zval const_BLOCK_CODE_ARROWS_value; ZVAL_LONG(&const_BLOCK_CODE_ARROWS_value, UBLOCK_ARROWS); - zend_string *const_BLOCK_CODE_ARROWS_name = zend_string_init_interned("BLOCK_CODE_ARROWS", sizeof("BLOCK_CODE_ARROWS") - 1, 1); + zend_string *const_BLOCK_CODE_ARROWS_name = zend_string_init_interned("BLOCK_CODE_ARROWS", sizeof("BLOCK_CODE_ARROWS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARROWS_name, &const_BLOCK_CODE_ARROWS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARROWS_name); + zend_string_release_ex(const_BLOCK_CODE_ARROWS_name, true); zval const_BLOCK_CODE_MATHEMATICAL_OPERATORS_value; ZVAL_LONG(&const_BLOCK_CODE_MATHEMATICAL_OPERATORS_value, UBLOCK_MATHEMATICAL_OPERATORS); - zend_string *const_BLOCK_CODE_MATHEMATICAL_OPERATORS_name = zend_string_init_interned("BLOCK_CODE_MATHEMATICAL_OPERATORS", sizeof("BLOCK_CODE_MATHEMATICAL_OPERATORS") - 1, 1); + zend_string *const_BLOCK_CODE_MATHEMATICAL_OPERATORS_name = zend_string_init_interned("BLOCK_CODE_MATHEMATICAL_OPERATORS", sizeof("BLOCK_CODE_MATHEMATICAL_OPERATORS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MATHEMATICAL_OPERATORS_name, &const_BLOCK_CODE_MATHEMATICAL_OPERATORS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MATHEMATICAL_OPERATORS_name); + zend_string_release_ex(const_BLOCK_CODE_MATHEMATICAL_OPERATORS_name, true); zval const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_value; ZVAL_LONG(&const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_value, UBLOCK_MISCELLANEOUS_TECHNICAL); - zend_string *const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_TECHNICAL", sizeof("BLOCK_CODE_MISCELLANEOUS_TECHNICAL") - 1, 1); + zend_string *const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_TECHNICAL", sizeof("BLOCK_CODE_MISCELLANEOUS_TECHNICAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_name, &const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_name); + zend_string_release_ex(const_BLOCK_CODE_MISCELLANEOUS_TECHNICAL_name, true); zval const_BLOCK_CODE_CONTROL_PICTURES_value; ZVAL_LONG(&const_BLOCK_CODE_CONTROL_PICTURES_value, UBLOCK_CONTROL_PICTURES); - zend_string *const_BLOCK_CODE_CONTROL_PICTURES_name = zend_string_init_interned("BLOCK_CODE_CONTROL_PICTURES", sizeof("BLOCK_CODE_CONTROL_PICTURES") - 1, 1); + zend_string *const_BLOCK_CODE_CONTROL_PICTURES_name = zend_string_init_interned("BLOCK_CODE_CONTROL_PICTURES", sizeof("BLOCK_CODE_CONTROL_PICTURES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CONTROL_PICTURES_name, &const_BLOCK_CODE_CONTROL_PICTURES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CONTROL_PICTURES_name); + zend_string_release_ex(const_BLOCK_CODE_CONTROL_PICTURES_name, true); zval const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_value; ZVAL_LONG(&const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_value, UBLOCK_OPTICAL_CHARACTER_RECOGNITION); - zend_string *const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_name = zend_string_init_interned("BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION", sizeof("BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION") - 1, 1); + zend_string *const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_name = zend_string_init_interned("BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION", sizeof("BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_name, &const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_name); + zend_string_release_ex(const_BLOCK_CODE_OPTICAL_CHARACTER_RECOGNITION_name, true); zval const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_value; ZVAL_LONG(&const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_value, UBLOCK_ENCLOSED_ALPHANUMERICS); - zend_string *const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_ALPHANUMERICS", sizeof("BLOCK_CODE_ENCLOSED_ALPHANUMERICS") - 1, 1); + zend_string *const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_ALPHANUMERICS", sizeof("BLOCK_CODE_ENCLOSED_ALPHANUMERICS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_name, &const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_name); + zend_string_release_ex(const_BLOCK_CODE_ENCLOSED_ALPHANUMERICS_name, true); zval const_BLOCK_CODE_BOX_DRAWING_value; ZVAL_LONG(&const_BLOCK_CODE_BOX_DRAWING_value, UBLOCK_BOX_DRAWING); - zend_string *const_BLOCK_CODE_BOX_DRAWING_name = zend_string_init_interned("BLOCK_CODE_BOX_DRAWING", sizeof("BLOCK_CODE_BOX_DRAWING") - 1, 1); + zend_string *const_BLOCK_CODE_BOX_DRAWING_name = zend_string_init_interned("BLOCK_CODE_BOX_DRAWING", sizeof("BLOCK_CODE_BOX_DRAWING") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BOX_DRAWING_name, &const_BLOCK_CODE_BOX_DRAWING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BOX_DRAWING_name); + zend_string_release_ex(const_BLOCK_CODE_BOX_DRAWING_name, true); zval const_BLOCK_CODE_BLOCK_ELEMENTS_value; ZVAL_LONG(&const_BLOCK_CODE_BLOCK_ELEMENTS_value, UBLOCK_BLOCK_ELEMENTS); - zend_string *const_BLOCK_CODE_BLOCK_ELEMENTS_name = zend_string_init_interned("BLOCK_CODE_BLOCK_ELEMENTS", sizeof("BLOCK_CODE_BLOCK_ELEMENTS") - 1, 1); + zend_string *const_BLOCK_CODE_BLOCK_ELEMENTS_name = zend_string_init_interned("BLOCK_CODE_BLOCK_ELEMENTS", sizeof("BLOCK_CODE_BLOCK_ELEMENTS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BLOCK_ELEMENTS_name, &const_BLOCK_CODE_BLOCK_ELEMENTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BLOCK_ELEMENTS_name); + zend_string_release_ex(const_BLOCK_CODE_BLOCK_ELEMENTS_name, true); zval const_BLOCK_CODE_GEOMETRIC_SHAPES_value; ZVAL_LONG(&const_BLOCK_CODE_GEOMETRIC_SHAPES_value, UBLOCK_GEOMETRIC_SHAPES); - zend_string *const_BLOCK_CODE_GEOMETRIC_SHAPES_name = zend_string_init_interned("BLOCK_CODE_GEOMETRIC_SHAPES", sizeof("BLOCK_CODE_GEOMETRIC_SHAPES") - 1, 1); + zend_string *const_BLOCK_CODE_GEOMETRIC_SHAPES_name = zend_string_init_interned("BLOCK_CODE_GEOMETRIC_SHAPES", sizeof("BLOCK_CODE_GEOMETRIC_SHAPES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GEOMETRIC_SHAPES_name, &const_BLOCK_CODE_GEOMETRIC_SHAPES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GEOMETRIC_SHAPES_name); + zend_string_release_ex(const_BLOCK_CODE_GEOMETRIC_SHAPES_name, true); zval const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_value, UBLOCK_MISCELLANEOUS_SYMBOLS); - zend_string *const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_SYMBOLS", sizeof("BLOCK_CODE_MISCELLANEOUS_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_SYMBOLS", sizeof("BLOCK_CODE_MISCELLANEOUS_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_name, &const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_name, true); zval const_BLOCK_CODE_DINGBATS_value; ZVAL_LONG(&const_BLOCK_CODE_DINGBATS_value, UBLOCK_DINGBATS); - zend_string *const_BLOCK_CODE_DINGBATS_name = zend_string_init_interned("BLOCK_CODE_DINGBATS", sizeof("BLOCK_CODE_DINGBATS") - 1, 1); + zend_string *const_BLOCK_CODE_DINGBATS_name = zend_string_init_interned("BLOCK_CODE_DINGBATS", sizeof("BLOCK_CODE_DINGBATS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_DINGBATS_name, &const_BLOCK_CODE_DINGBATS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_DINGBATS_name); + zend_string_release_ex(const_BLOCK_CODE_DINGBATS_name, true); zval const_BLOCK_CODE_BRAILLE_PATTERNS_value; ZVAL_LONG(&const_BLOCK_CODE_BRAILLE_PATTERNS_value, UBLOCK_BRAILLE_PATTERNS); - zend_string *const_BLOCK_CODE_BRAILLE_PATTERNS_name = zend_string_init_interned("BLOCK_CODE_BRAILLE_PATTERNS", sizeof("BLOCK_CODE_BRAILLE_PATTERNS") - 1, 1); + zend_string *const_BLOCK_CODE_BRAILLE_PATTERNS_name = zend_string_init_interned("BLOCK_CODE_BRAILLE_PATTERNS", sizeof("BLOCK_CODE_BRAILLE_PATTERNS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BRAILLE_PATTERNS_name, &const_BLOCK_CODE_BRAILLE_PATTERNS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BRAILLE_PATTERNS_name); + zend_string_release_ex(const_BLOCK_CODE_BRAILLE_PATTERNS_name, true); zval const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_value, UBLOCK_CJK_RADICALS_SUPPLEMENT); - zend_string *const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_CJK_RADICALS_SUPPLEMENT", sizeof("BLOCK_CODE_CJK_RADICALS_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_CJK_RADICALS_SUPPLEMENT", sizeof("BLOCK_CODE_CJK_RADICALS_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_name, &const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_RADICALS_SUPPLEMENT_name, true); zval const_BLOCK_CODE_KANGXI_RADICALS_value; ZVAL_LONG(&const_BLOCK_CODE_KANGXI_RADICALS_value, UBLOCK_KANGXI_RADICALS); - zend_string *const_BLOCK_CODE_KANGXI_RADICALS_name = zend_string_init_interned("BLOCK_CODE_KANGXI_RADICALS", sizeof("BLOCK_CODE_KANGXI_RADICALS") - 1, 1); + zend_string *const_BLOCK_CODE_KANGXI_RADICALS_name = zend_string_init_interned("BLOCK_CODE_KANGXI_RADICALS", sizeof("BLOCK_CODE_KANGXI_RADICALS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KANGXI_RADICALS_name, &const_BLOCK_CODE_KANGXI_RADICALS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KANGXI_RADICALS_name); + zend_string_release_ex(const_BLOCK_CODE_KANGXI_RADICALS_name, true); zval const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_value; ZVAL_LONG(&const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_value, UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS); - zend_string *const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_name = zend_string_init_interned("BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS", sizeof("BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS") - 1, 1); + zend_string *const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_name = zend_string_init_interned("BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS", sizeof("BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_name, &const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_name); + zend_string_release_ex(const_BLOCK_CODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS_name, true); zval const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_value, UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION); - zend_string *const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION", sizeof("BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION", sizeof("BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_name, &const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_SYMBOLS_AND_PUNCTUATION_name, true); zval const_BLOCK_CODE_HIRAGANA_value; ZVAL_LONG(&const_BLOCK_CODE_HIRAGANA_value, UBLOCK_HIRAGANA); - zend_string *const_BLOCK_CODE_HIRAGANA_name = zend_string_init_interned("BLOCK_CODE_HIRAGANA", sizeof("BLOCK_CODE_HIRAGANA") - 1, 1); + zend_string *const_BLOCK_CODE_HIRAGANA_name = zend_string_init_interned("BLOCK_CODE_HIRAGANA", sizeof("BLOCK_CODE_HIRAGANA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HIRAGANA_name, &const_BLOCK_CODE_HIRAGANA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HIRAGANA_name); + zend_string_release_ex(const_BLOCK_CODE_HIRAGANA_name, true); zval const_BLOCK_CODE_KATAKANA_value; ZVAL_LONG(&const_BLOCK_CODE_KATAKANA_value, UBLOCK_KATAKANA); - zend_string *const_BLOCK_CODE_KATAKANA_name = zend_string_init_interned("BLOCK_CODE_KATAKANA", sizeof("BLOCK_CODE_KATAKANA") - 1, 1); + zend_string *const_BLOCK_CODE_KATAKANA_name = zend_string_init_interned("BLOCK_CODE_KATAKANA", sizeof("BLOCK_CODE_KATAKANA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KATAKANA_name, &const_BLOCK_CODE_KATAKANA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KATAKANA_name); + zend_string_release_ex(const_BLOCK_CODE_KATAKANA_name, true); zval const_BLOCK_CODE_BOPOMOFO_value; ZVAL_LONG(&const_BLOCK_CODE_BOPOMOFO_value, UBLOCK_BOPOMOFO); - zend_string *const_BLOCK_CODE_BOPOMOFO_name = zend_string_init_interned("BLOCK_CODE_BOPOMOFO", sizeof("BLOCK_CODE_BOPOMOFO") - 1, 1); + zend_string *const_BLOCK_CODE_BOPOMOFO_name = zend_string_init_interned("BLOCK_CODE_BOPOMOFO", sizeof("BLOCK_CODE_BOPOMOFO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BOPOMOFO_name, &const_BLOCK_CODE_BOPOMOFO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BOPOMOFO_name); + zend_string_release_ex(const_BLOCK_CODE_BOPOMOFO_name, true); zval const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_value; ZVAL_LONG(&const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_value, UBLOCK_HANGUL_COMPATIBILITY_JAMO); - zend_string *const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_name = zend_string_init_interned("BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO", sizeof("BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO") - 1, 1); + zend_string *const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_name = zend_string_init_interned("BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO", sizeof("BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_name, &const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_name); + zend_string_release_ex(const_BLOCK_CODE_HANGUL_COMPATIBILITY_JAMO_name, true); zval const_BLOCK_CODE_KANBUN_value; ZVAL_LONG(&const_BLOCK_CODE_KANBUN_value, UBLOCK_KANBUN); - zend_string *const_BLOCK_CODE_KANBUN_name = zend_string_init_interned("BLOCK_CODE_KANBUN", sizeof("BLOCK_CODE_KANBUN") - 1, 1); + zend_string *const_BLOCK_CODE_KANBUN_name = zend_string_init_interned("BLOCK_CODE_KANBUN", sizeof("BLOCK_CODE_KANBUN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KANBUN_name, &const_BLOCK_CODE_KANBUN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KANBUN_name); + zend_string_release_ex(const_BLOCK_CODE_KANBUN_name, true); zval const_BLOCK_CODE_BOPOMOFO_EXTENDED_value; ZVAL_LONG(&const_BLOCK_CODE_BOPOMOFO_EXTENDED_value, UBLOCK_BOPOMOFO_EXTENDED); - zend_string *const_BLOCK_CODE_BOPOMOFO_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_BOPOMOFO_EXTENDED", sizeof("BLOCK_CODE_BOPOMOFO_EXTENDED") - 1, 1); + zend_string *const_BLOCK_CODE_BOPOMOFO_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_BOPOMOFO_EXTENDED", sizeof("BLOCK_CODE_BOPOMOFO_EXTENDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BOPOMOFO_EXTENDED_name, &const_BLOCK_CODE_BOPOMOFO_EXTENDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BOPOMOFO_EXTENDED_name); + zend_string_release_ex(const_BLOCK_CODE_BOPOMOFO_EXTENDED_name, true); zval const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_value; ZVAL_LONG(&const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_value, UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS); - zend_string *const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS", sizeof("BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS") - 1, 1); + zend_string *const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS", sizeof("BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_name, &const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_name); + zend_string_release_ex(const_BLOCK_CODE_ENCLOSED_CJK_LETTERS_AND_MONTHS_name, true); zval const_BLOCK_CODE_CJK_COMPATIBILITY_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_COMPATIBILITY_value, UBLOCK_CJK_COMPATIBILITY); - zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY", sizeof("BLOCK_CODE_CJK_COMPATIBILITY") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY", sizeof("BLOCK_CODE_CJK_COMPATIBILITY") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_COMPATIBILITY_name, &const_BLOCK_CODE_CJK_COMPATIBILITY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_COMPATIBILITY_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_COMPATIBILITY_name, true); zval const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_value, UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A); - zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_name, &const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A_name, true); zval const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_value, UBLOCK_CJK_UNIFIED_IDEOGRAPHS); - zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_name, &const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_name, true); zval const_BLOCK_CODE_YI_SYLLABLES_value; ZVAL_LONG(&const_BLOCK_CODE_YI_SYLLABLES_value, UBLOCK_YI_SYLLABLES); - zend_string *const_BLOCK_CODE_YI_SYLLABLES_name = zend_string_init_interned("BLOCK_CODE_YI_SYLLABLES", sizeof("BLOCK_CODE_YI_SYLLABLES") - 1, 1); + zend_string *const_BLOCK_CODE_YI_SYLLABLES_name = zend_string_init_interned("BLOCK_CODE_YI_SYLLABLES", sizeof("BLOCK_CODE_YI_SYLLABLES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_YI_SYLLABLES_name, &const_BLOCK_CODE_YI_SYLLABLES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_YI_SYLLABLES_name); + zend_string_release_ex(const_BLOCK_CODE_YI_SYLLABLES_name, true); zval const_BLOCK_CODE_YI_RADICALS_value; ZVAL_LONG(&const_BLOCK_CODE_YI_RADICALS_value, UBLOCK_YI_RADICALS); - zend_string *const_BLOCK_CODE_YI_RADICALS_name = zend_string_init_interned("BLOCK_CODE_YI_RADICALS", sizeof("BLOCK_CODE_YI_RADICALS") - 1, 1); + zend_string *const_BLOCK_CODE_YI_RADICALS_name = zend_string_init_interned("BLOCK_CODE_YI_RADICALS", sizeof("BLOCK_CODE_YI_RADICALS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_YI_RADICALS_name, &const_BLOCK_CODE_YI_RADICALS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_YI_RADICALS_name); + zend_string_release_ex(const_BLOCK_CODE_YI_RADICALS_name, true); zval const_BLOCK_CODE_HANGUL_SYLLABLES_value; ZVAL_LONG(&const_BLOCK_CODE_HANGUL_SYLLABLES_value, UBLOCK_HANGUL_SYLLABLES); - zend_string *const_BLOCK_CODE_HANGUL_SYLLABLES_name = zend_string_init_interned("BLOCK_CODE_HANGUL_SYLLABLES", sizeof("BLOCK_CODE_HANGUL_SYLLABLES") - 1, 1); + zend_string *const_BLOCK_CODE_HANGUL_SYLLABLES_name = zend_string_init_interned("BLOCK_CODE_HANGUL_SYLLABLES", sizeof("BLOCK_CODE_HANGUL_SYLLABLES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HANGUL_SYLLABLES_name, &const_BLOCK_CODE_HANGUL_SYLLABLES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HANGUL_SYLLABLES_name); + zend_string_release_ex(const_BLOCK_CODE_HANGUL_SYLLABLES_name, true); zval const_BLOCK_CODE_HIGH_SURROGATES_value; ZVAL_LONG(&const_BLOCK_CODE_HIGH_SURROGATES_value, UBLOCK_HIGH_SURROGATES); - zend_string *const_BLOCK_CODE_HIGH_SURROGATES_name = zend_string_init_interned("BLOCK_CODE_HIGH_SURROGATES", sizeof("BLOCK_CODE_HIGH_SURROGATES") - 1, 1); + zend_string *const_BLOCK_CODE_HIGH_SURROGATES_name = zend_string_init_interned("BLOCK_CODE_HIGH_SURROGATES", sizeof("BLOCK_CODE_HIGH_SURROGATES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HIGH_SURROGATES_name, &const_BLOCK_CODE_HIGH_SURROGATES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HIGH_SURROGATES_name); + zend_string_release_ex(const_BLOCK_CODE_HIGH_SURROGATES_name, true); zval const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_value; ZVAL_LONG(&const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_value, UBLOCK_HIGH_PRIVATE_USE_SURROGATES); - zend_string *const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_name = zend_string_init_interned("BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES", sizeof("BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES") - 1, 1); + zend_string *const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_name = zend_string_init_interned("BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES", sizeof("BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_name, &const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_name); + zend_string_release_ex(const_BLOCK_CODE_HIGH_PRIVATE_USE_SURROGATES_name, true); zval const_BLOCK_CODE_LOW_SURROGATES_value; ZVAL_LONG(&const_BLOCK_CODE_LOW_SURROGATES_value, UBLOCK_LOW_SURROGATES); - zend_string *const_BLOCK_CODE_LOW_SURROGATES_name = zend_string_init_interned("BLOCK_CODE_LOW_SURROGATES", sizeof("BLOCK_CODE_LOW_SURROGATES") - 1, 1); + zend_string *const_BLOCK_CODE_LOW_SURROGATES_name = zend_string_init_interned("BLOCK_CODE_LOW_SURROGATES", sizeof("BLOCK_CODE_LOW_SURROGATES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LOW_SURROGATES_name, &const_BLOCK_CODE_LOW_SURROGATES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LOW_SURROGATES_name); + zend_string_release_ex(const_BLOCK_CODE_LOW_SURROGATES_name, true); zval const_BLOCK_CODE_PRIVATE_USE_AREA_value; ZVAL_LONG(&const_BLOCK_CODE_PRIVATE_USE_AREA_value, UBLOCK_PRIVATE_USE_AREA); - zend_string *const_BLOCK_CODE_PRIVATE_USE_AREA_name = zend_string_init_interned("BLOCK_CODE_PRIVATE_USE_AREA", sizeof("BLOCK_CODE_PRIVATE_USE_AREA") - 1, 1); + zend_string *const_BLOCK_CODE_PRIVATE_USE_AREA_name = zend_string_init_interned("BLOCK_CODE_PRIVATE_USE_AREA", sizeof("BLOCK_CODE_PRIVATE_USE_AREA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PRIVATE_USE_AREA_name, &const_BLOCK_CODE_PRIVATE_USE_AREA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PRIVATE_USE_AREA_name); + zend_string_release_ex(const_BLOCK_CODE_PRIVATE_USE_AREA_name, true); zval const_BLOCK_CODE_PRIVATE_USE_value; ZVAL_LONG(&const_BLOCK_CODE_PRIVATE_USE_value, UBLOCK_PRIVATE_USE); - zend_string *const_BLOCK_CODE_PRIVATE_USE_name = zend_string_init_interned("BLOCK_CODE_PRIVATE_USE", sizeof("BLOCK_CODE_PRIVATE_USE") - 1, 1); + zend_string *const_BLOCK_CODE_PRIVATE_USE_name = zend_string_init_interned("BLOCK_CODE_PRIVATE_USE", sizeof("BLOCK_CODE_PRIVATE_USE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PRIVATE_USE_name, &const_BLOCK_CODE_PRIVATE_USE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PRIVATE_USE_name); + zend_string_release_ex(const_BLOCK_CODE_PRIVATE_USE_name, true); zval const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_value, UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS); - zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS", sizeof("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS", sizeof("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_name, &const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_name, true); zval const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_value; ZVAL_LONG(&const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_value, UBLOCK_ALPHABETIC_PRESENTATION_FORMS); - zend_string *const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_name = zend_string_init_interned("BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS", sizeof("BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS") - 1, 1); + zend_string *const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_name = zend_string_init_interned("BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS", sizeof("BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_name, &const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_name); + zend_string_release_ex(const_BLOCK_CODE_ALPHABETIC_PRESENTATION_FORMS_name, true); zval const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_value; ZVAL_LONG(&const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_value, UBLOCK_ARABIC_PRESENTATION_FORMS_A); - zend_string *const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_name = zend_string_init_interned("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A", sizeof("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A") - 1, 1); + zend_string *const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_name = zend_string_init_interned("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A", sizeof("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_name, &const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_name); + zend_string_release_ex(const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_A_name, true); zval const_BLOCK_CODE_COMBINING_HALF_MARKS_value; ZVAL_LONG(&const_BLOCK_CODE_COMBINING_HALF_MARKS_value, UBLOCK_COMBINING_HALF_MARKS); - zend_string *const_BLOCK_CODE_COMBINING_HALF_MARKS_name = zend_string_init_interned("BLOCK_CODE_COMBINING_HALF_MARKS", sizeof("BLOCK_CODE_COMBINING_HALF_MARKS") - 1, 1); + zend_string *const_BLOCK_CODE_COMBINING_HALF_MARKS_name = zend_string_init_interned("BLOCK_CODE_COMBINING_HALF_MARKS", sizeof("BLOCK_CODE_COMBINING_HALF_MARKS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COMBINING_HALF_MARKS_name, &const_BLOCK_CODE_COMBINING_HALF_MARKS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COMBINING_HALF_MARKS_name); + zend_string_release_ex(const_BLOCK_CODE_COMBINING_HALF_MARKS_name, true); zval const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_value, UBLOCK_CJK_COMPATIBILITY_FORMS); - zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY_FORMS", sizeof("BLOCK_CODE_CJK_COMPATIBILITY_FORMS") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY_FORMS", sizeof("BLOCK_CODE_CJK_COMPATIBILITY_FORMS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_name, &const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_COMPATIBILITY_FORMS_name, true); zval const_BLOCK_CODE_SMALL_FORM_VARIANTS_value; ZVAL_LONG(&const_BLOCK_CODE_SMALL_FORM_VARIANTS_value, UBLOCK_SMALL_FORM_VARIANTS); - zend_string *const_BLOCK_CODE_SMALL_FORM_VARIANTS_name = zend_string_init_interned("BLOCK_CODE_SMALL_FORM_VARIANTS", sizeof("BLOCK_CODE_SMALL_FORM_VARIANTS") - 1, 1); + zend_string *const_BLOCK_CODE_SMALL_FORM_VARIANTS_name = zend_string_init_interned("BLOCK_CODE_SMALL_FORM_VARIANTS", sizeof("BLOCK_CODE_SMALL_FORM_VARIANTS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SMALL_FORM_VARIANTS_name, &const_BLOCK_CODE_SMALL_FORM_VARIANTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SMALL_FORM_VARIANTS_name); + zend_string_release_ex(const_BLOCK_CODE_SMALL_FORM_VARIANTS_name, true); zval const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_value; ZVAL_LONG(&const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_value, UBLOCK_ARABIC_PRESENTATION_FORMS_B); - zend_string *const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_name = zend_string_init_interned("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B", sizeof("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B") - 1, 1); + zend_string *const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_name = zend_string_init_interned("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B", sizeof("BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_name, &const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_name); + zend_string_release_ex(const_BLOCK_CODE_ARABIC_PRESENTATION_FORMS_B_name, true); zval const_BLOCK_CODE_SPECIALS_value; ZVAL_LONG(&const_BLOCK_CODE_SPECIALS_value, UBLOCK_SPECIALS); - zend_string *const_BLOCK_CODE_SPECIALS_name = zend_string_init_interned("BLOCK_CODE_SPECIALS", sizeof("BLOCK_CODE_SPECIALS") - 1, 1); + zend_string *const_BLOCK_CODE_SPECIALS_name = zend_string_init_interned("BLOCK_CODE_SPECIALS", sizeof("BLOCK_CODE_SPECIALS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SPECIALS_name, &const_BLOCK_CODE_SPECIALS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SPECIALS_name); + zend_string_release_ex(const_BLOCK_CODE_SPECIALS_name, true); zval const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_value; ZVAL_LONG(&const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_value, UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS); - zend_string *const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_name = zend_string_init_interned("BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS", sizeof("BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS") - 1, 1); + zend_string *const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_name = zend_string_init_interned("BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS", sizeof("BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_name, &const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_name); + zend_string_release_ex(const_BLOCK_CODE_HALFWIDTH_AND_FULLWIDTH_FORMS_name, true); zval const_BLOCK_CODE_OLD_ITALIC_value; ZVAL_LONG(&const_BLOCK_CODE_OLD_ITALIC_value, UBLOCK_OLD_ITALIC); - zend_string *const_BLOCK_CODE_OLD_ITALIC_name = zend_string_init_interned("BLOCK_CODE_OLD_ITALIC", sizeof("BLOCK_CODE_OLD_ITALIC") - 1, 1); + zend_string *const_BLOCK_CODE_OLD_ITALIC_name = zend_string_init_interned("BLOCK_CODE_OLD_ITALIC", sizeof("BLOCK_CODE_OLD_ITALIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OLD_ITALIC_name, &const_BLOCK_CODE_OLD_ITALIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OLD_ITALIC_name); + zend_string_release_ex(const_BLOCK_CODE_OLD_ITALIC_name, true); zval const_BLOCK_CODE_GOTHIC_value; ZVAL_LONG(&const_BLOCK_CODE_GOTHIC_value, UBLOCK_GOTHIC); - zend_string *const_BLOCK_CODE_GOTHIC_name = zend_string_init_interned("BLOCK_CODE_GOTHIC", sizeof("BLOCK_CODE_GOTHIC") - 1, 1); + zend_string *const_BLOCK_CODE_GOTHIC_name = zend_string_init_interned("BLOCK_CODE_GOTHIC", sizeof("BLOCK_CODE_GOTHIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GOTHIC_name, &const_BLOCK_CODE_GOTHIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GOTHIC_name); + zend_string_release_ex(const_BLOCK_CODE_GOTHIC_name, true); zval const_BLOCK_CODE_DESERET_value; ZVAL_LONG(&const_BLOCK_CODE_DESERET_value, UBLOCK_DESERET); - zend_string *const_BLOCK_CODE_DESERET_name = zend_string_init_interned("BLOCK_CODE_DESERET", sizeof("BLOCK_CODE_DESERET") - 1, 1); + zend_string *const_BLOCK_CODE_DESERET_name = zend_string_init_interned("BLOCK_CODE_DESERET", sizeof("BLOCK_CODE_DESERET") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_DESERET_name, &const_BLOCK_CODE_DESERET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_DESERET_name); + zend_string_release_ex(const_BLOCK_CODE_DESERET_name, true); zval const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_value, UBLOCK_BYZANTINE_MUSICAL_SYMBOLS); - zend_string *const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS", sizeof("BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS", sizeof("BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_name, &const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_BYZANTINE_MUSICAL_SYMBOLS_name, true); zval const_BLOCK_CODE_MUSICAL_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_MUSICAL_SYMBOLS_value, UBLOCK_MUSICAL_SYMBOLS); - zend_string *const_BLOCK_CODE_MUSICAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_MUSICAL_SYMBOLS", sizeof("BLOCK_CODE_MUSICAL_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_MUSICAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_MUSICAL_SYMBOLS", sizeof("BLOCK_CODE_MUSICAL_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MUSICAL_SYMBOLS_name, &const_BLOCK_CODE_MUSICAL_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MUSICAL_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_MUSICAL_SYMBOLS_name, true); zval const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_value, UBLOCK_MATHEMATICAL_ALPHANUMERIC_SYMBOLS); - zend_string *const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS", sizeof("BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS", sizeof("BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_name, &const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_MATHEMATICAL_ALPHANUMERIC_SYMBOLS_name, true); zval const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_value, UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B); - zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_name, &const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B_name, true); zval const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_value, UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT); - zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT", sizeof("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT", sizeof("BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_name, &const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT_name, true); zval const_BLOCK_CODE_TAGS_value; ZVAL_LONG(&const_BLOCK_CODE_TAGS_value, UBLOCK_TAGS); - zend_string *const_BLOCK_CODE_TAGS_name = zend_string_init_interned("BLOCK_CODE_TAGS", sizeof("BLOCK_CODE_TAGS") - 1, 1); + zend_string *const_BLOCK_CODE_TAGS_name = zend_string_init_interned("BLOCK_CODE_TAGS", sizeof("BLOCK_CODE_TAGS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAGS_name, &const_BLOCK_CODE_TAGS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAGS_name); + zend_string_release_ex(const_BLOCK_CODE_TAGS_name, true); zval const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_value, UBLOCK_CYRILLIC_SUPPLEMENT); - zend_string *const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_SUPPLEMENT", sizeof("BLOCK_CODE_CYRILLIC_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_SUPPLEMENT", sizeof("BLOCK_CODE_CYRILLIC_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_name, &const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_CYRILLIC_SUPPLEMENT_name, true); zval const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_value; ZVAL_LONG(&const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_value, UBLOCK_CYRILLIC_SUPPLEMENTARY); - zend_string *const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_SUPPLEMENTARY", sizeof("BLOCK_CODE_CYRILLIC_SUPPLEMENTARY") - 1, 1); + zend_string *const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_SUPPLEMENTARY", sizeof("BLOCK_CODE_CYRILLIC_SUPPLEMENTARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_name, &const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_name); + zend_string_release_ex(const_BLOCK_CODE_CYRILLIC_SUPPLEMENTARY_name, true); zval const_BLOCK_CODE_TAGALOG_value; ZVAL_LONG(&const_BLOCK_CODE_TAGALOG_value, UBLOCK_TAGALOG); - zend_string *const_BLOCK_CODE_TAGALOG_name = zend_string_init_interned("BLOCK_CODE_TAGALOG", sizeof("BLOCK_CODE_TAGALOG") - 1, 1); + zend_string *const_BLOCK_CODE_TAGALOG_name = zend_string_init_interned("BLOCK_CODE_TAGALOG", sizeof("BLOCK_CODE_TAGALOG") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAGALOG_name, &const_BLOCK_CODE_TAGALOG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAGALOG_name); + zend_string_release_ex(const_BLOCK_CODE_TAGALOG_name, true); zval const_BLOCK_CODE_HANUNOO_value; ZVAL_LONG(&const_BLOCK_CODE_HANUNOO_value, UBLOCK_HANUNOO); - zend_string *const_BLOCK_CODE_HANUNOO_name = zend_string_init_interned("BLOCK_CODE_HANUNOO", sizeof("BLOCK_CODE_HANUNOO") - 1, 1); + zend_string *const_BLOCK_CODE_HANUNOO_name = zend_string_init_interned("BLOCK_CODE_HANUNOO", sizeof("BLOCK_CODE_HANUNOO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HANUNOO_name, &const_BLOCK_CODE_HANUNOO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HANUNOO_name); + zend_string_release_ex(const_BLOCK_CODE_HANUNOO_name, true); zval const_BLOCK_CODE_BUHID_value; ZVAL_LONG(&const_BLOCK_CODE_BUHID_value, UBLOCK_BUHID); - zend_string *const_BLOCK_CODE_BUHID_name = zend_string_init_interned("BLOCK_CODE_BUHID", sizeof("BLOCK_CODE_BUHID") - 1, 1); + zend_string *const_BLOCK_CODE_BUHID_name = zend_string_init_interned("BLOCK_CODE_BUHID", sizeof("BLOCK_CODE_BUHID") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BUHID_name, &const_BLOCK_CODE_BUHID_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BUHID_name); + zend_string_release_ex(const_BLOCK_CODE_BUHID_name, true); zval const_BLOCK_CODE_TAGBANWA_value; ZVAL_LONG(&const_BLOCK_CODE_TAGBANWA_value, UBLOCK_TAGBANWA); - zend_string *const_BLOCK_CODE_TAGBANWA_name = zend_string_init_interned("BLOCK_CODE_TAGBANWA", sizeof("BLOCK_CODE_TAGBANWA") - 1, 1); + zend_string *const_BLOCK_CODE_TAGBANWA_name = zend_string_init_interned("BLOCK_CODE_TAGBANWA", sizeof("BLOCK_CODE_TAGBANWA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAGBANWA_name, &const_BLOCK_CODE_TAGBANWA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAGBANWA_name); + zend_string_release_ex(const_BLOCK_CODE_TAGBANWA_name, true); zval const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_value; ZVAL_LONG(&const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_value, UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A); - zend_string *const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A", sizeof("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A") - 1, 1); + zend_string *const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A", sizeof("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_name, &const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_name); + zend_string_release_ex(const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A_name, true); zval const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_value; ZVAL_LONG(&const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_value, UBLOCK_SUPPLEMENTAL_ARROWS_A); - zend_string *const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_ARROWS_A", sizeof("BLOCK_CODE_SUPPLEMENTAL_ARROWS_A") - 1, 1); + zend_string *const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_ARROWS_A", sizeof("BLOCK_CODE_SUPPLEMENTAL_ARROWS_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_name, &const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_name); + zend_string_release_ex(const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_A_name, true); zval const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_value; ZVAL_LONG(&const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_value, UBLOCK_SUPPLEMENTAL_ARROWS_B); - zend_string *const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_ARROWS_B", sizeof("BLOCK_CODE_SUPPLEMENTAL_ARROWS_B") - 1, 1); + zend_string *const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_ARROWS_B", sizeof("BLOCK_CODE_SUPPLEMENTAL_ARROWS_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_name, &const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_name); + zend_string_release_ex(const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_B_name, true); zval const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_value; ZVAL_LONG(&const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_value, UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B); - zend_string *const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B", sizeof("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B") - 1, 1); + zend_string *const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B", sizeof("BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_name, &const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_name); + zend_string_release_ex(const_BLOCK_CODE_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B_name, true); zval const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_value; ZVAL_LONG(&const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_value, UBLOCK_SUPPLEMENTAL_MATHEMATICAL_OPERATORS); - zend_string *const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS", sizeof("BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS") - 1, 1); + zend_string *const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS", sizeof("BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_name, &const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_name); + zend_string_release_ex(const_BLOCK_CODE_SUPPLEMENTAL_MATHEMATICAL_OPERATORS_name, true); zval const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_value; ZVAL_LONG(&const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_value, UBLOCK_KATAKANA_PHONETIC_EXTENSIONS); - zend_string *const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS", sizeof("BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS") - 1, 1); + zend_string *const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS", sizeof("BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_name, &const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_name); + zend_string_release_ex(const_BLOCK_CODE_KATAKANA_PHONETIC_EXTENSIONS_name, true); zval const_BLOCK_CODE_VARIATION_SELECTORS_value; ZVAL_LONG(&const_BLOCK_CODE_VARIATION_SELECTORS_value, UBLOCK_VARIATION_SELECTORS); - zend_string *const_BLOCK_CODE_VARIATION_SELECTORS_name = zend_string_init_interned("BLOCK_CODE_VARIATION_SELECTORS", sizeof("BLOCK_CODE_VARIATION_SELECTORS") - 1, 1); + zend_string *const_BLOCK_CODE_VARIATION_SELECTORS_name = zend_string_init_interned("BLOCK_CODE_VARIATION_SELECTORS", sizeof("BLOCK_CODE_VARIATION_SELECTORS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_VARIATION_SELECTORS_name, &const_BLOCK_CODE_VARIATION_SELECTORS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_VARIATION_SELECTORS_name); + zend_string_release_ex(const_BLOCK_CODE_VARIATION_SELECTORS_name, true); zval const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_value; ZVAL_LONG(&const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_value, UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_A); - zend_string *const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A", sizeof("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A") - 1, 1); + zend_string *const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A", sizeof("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_name, &const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_name); + zend_string_release_ex(const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_A_name, true); zval const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_value; ZVAL_LONG(&const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_value, UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_B); - zend_string *const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B", sizeof("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B") - 1, 1); + zend_string *const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B", sizeof("BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_name, &const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_name); + zend_string_release_ex(const_BLOCK_CODE_SUPPLEMENTARY_PRIVATE_USE_AREA_B_name, true); zval const_BLOCK_CODE_LIMBU_value; ZVAL_LONG(&const_BLOCK_CODE_LIMBU_value, UBLOCK_LIMBU); - zend_string *const_BLOCK_CODE_LIMBU_name = zend_string_init_interned("BLOCK_CODE_LIMBU", sizeof("BLOCK_CODE_LIMBU") - 1, 1); + zend_string *const_BLOCK_CODE_LIMBU_name = zend_string_init_interned("BLOCK_CODE_LIMBU", sizeof("BLOCK_CODE_LIMBU") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LIMBU_name, &const_BLOCK_CODE_LIMBU_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LIMBU_name); + zend_string_release_ex(const_BLOCK_CODE_LIMBU_name, true); zval const_BLOCK_CODE_TAI_LE_value; ZVAL_LONG(&const_BLOCK_CODE_TAI_LE_value, UBLOCK_TAI_LE); - zend_string *const_BLOCK_CODE_TAI_LE_name = zend_string_init_interned("BLOCK_CODE_TAI_LE", sizeof("BLOCK_CODE_TAI_LE") - 1, 1); + zend_string *const_BLOCK_CODE_TAI_LE_name = zend_string_init_interned("BLOCK_CODE_TAI_LE", sizeof("BLOCK_CODE_TAI_LE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAI_LE_name, &const_BLOCK_CODE_TAI_LE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAI_LE_name); + zend_string_release_ex(const_BLOCK_CODE_TAI_LE_name, true); zval const_BLOCK_CODE_KHMER_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_KHMER_SYMBOLS_value, UBLOCK_KHMER_SYMBOLS); - zend_string *const_BLOCK_CODE_KHMER_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_KHMER_SYMBOLS", sizeof("BLOCK_CODE_KHMER_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_KHMER_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_KHMER_SYMBOLS", sizeof("BLOCK_CODE_KHMER_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KHMER_SYMBOLS_name, &const_BLOCK_CODE_KHMER_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KHMER_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_KHMER_SYMBOLS_name, true); zval const_BLOCK_CODE_PHONETIC_EXTENSIONS_value; ZVAL_LONG(&const_BLOCK_CODE_PHONETIC_EXTENSIONS_value, UBLOCK_PHONETIC_EXTENSIONS); - zend_string *const_BLOCK_CODE_PHONETIC_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_PHONETIC_EXTENSIONS", sizeof("BLOCK_CODE_PHONETIC_EXTENSIONS") - 1, 1); + zend_string *const_BLOCK_CODE_PHONETIC_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_PHONETIC_EXTENSIONS", sizeof("BLOCK_CODE_PHONETIC_EXTENSIONS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PHONETIC_EXTENSIONS_name, &const_BLOCK_CODE_PHONETIC_EXTENSIONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PHONETIC_EXTENSIONS_name); + zend_string_release_ex(const_BLOCK_CODE_PHONETIC_EXTENSIONS_name, true); zval const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_value; ZVAL_LONG(&const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_value, UBLOCK_MISCELLANEOUS_SYMBOLS_AND_ARROWS); - zend_string *const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS", sizeof("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS") - 1, 1); + zend_string *const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS", sizeof("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_name, &const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_name); + zend_string_release_ex(const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_ARROWS_name, true); zval const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_value, UBLOCK_YIJING_HEXAGRAM_SYMBOLS); - zend_string *const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS", sizeof("BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS", sizeof("BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_name, &const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_YIJING_HEXAGRAM_SYMBOLS_name, true); zval const_BLOCK_CODE_LINEAR_B_SYLLABARY_value; ZVAL_LONG(&const_BLOCK_CODE_LINEAR_B_SYLLABARY_value, UBLOCK_LINEAR_B_SYLLABARY); - zend_string *const_BLOCK_CODE_LINEAR_B_SYLLABARY_name = zend_string_init_interned("BLOCK_CODE_LINEAR_B_SYLLABARY", sizeof("BLOCK_CODE_LINEAR_B_SYLLABARY") - 1, 1); + zend_string *const_BLOCK_CODE_LINEAR_B_SYLLABARY_name = zend_string_init_interned("BLOCK_CODE_LINEAR_B_SYLLABARY", sizeof("BLOCK_CODE_LINEAR_B_SYLLABARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LINEAR_B_SYLLABARY_name, &const_BLOCK_CODE_LINEAR_B_SYLLABARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LINEAR_B_SYLLABARY_name); + zend_string_release_ex(const_BLOCK_CODE_LINEAR_B_SYLLABARY_name, true); zval const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_value; ZVAL_LONG(&const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_value, UBLOCK_LINEAR_B_IDEOGRAMS); - zend_string *const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_name = zend_string_init_interned("BLOCK_CODE_LINEAR_B_IDEOGRAMS", sizeof("BLOCK_CODE_LINEAR_B_IDEOGRAMS") - 1, 1); + zend_string *const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_name = zend_string_init_interned("BLOCK_CODE_LINEAR_B_IDEOGRAMS", sizeof("BLOCK_CODE_LINEAR_B_IDEOGRAMS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_name, &const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_name); + zend_string_release_ex(const_BLOCK_CODE_LINEAR_B_IDEOGRAMS_name, true); zval const_BLOCK_CODE_AEGEAN_NUMBERS_value; ZVAL_LONG(&const_BLOCK_CODE_AEGEAN_NUMBERS_value, UBLOCK_AEGEAN_NUMBERS); - zend_string *const_BLOCK_CODE_AEGEAN_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_AEGEAN_NUMBERS", sizeof("BLOCK_CODE_AEGEAN_NUMBERS") - 1, 1); + zend_string *const_BLOCK_CODE_AEGEAN_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_AEGEAN_NUMBERS", sizeof("BLOCK_CODE_AEGEAN_NUMBERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_AEGEAN_NUMBERS_name, &const_BLOCK_CODE_AEGEAN_NUMBERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_AEGEAN_NUMBERS_name); + zend_string_release_ex(const_BLOCK_CODE_AEGEAN_NUMBERS_name, true); zval const_BLOCK_CODE_UGARITIC_value; ZVAL_LONG(&const_BLOCK_CODE_UGARITIC_value, UBLOCK_UGARITIC); - zend_string *const_BLOCK_CODE_UGARITIC_name = zend_string_init_interned("BLOCK_CODE_UGARITIC", sizeof("BLOCK_CODE_UGARITIC") - 1, 1); + zend_string *const_BLOCK_CODE_UGARITIC_name = zend_string_init_interned("BLOCK_CODE_UGARITIC", sizeof("BLOCK_CODE_UGARITIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_UGARITIC_name, &const_BLOCK_CODE_UGARITIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_UGARITIC_name); + zend_string_release_ex(const_BLOCK_CODE_UGARITIC_name, true); zval const_BLOCK_CODE_SHAVIAN_value; ZVAL_LONG(&const_BLOCK_CODE_SHAVIAN_value, UBLOCK_SHAVIAN); - zend_string *const_BLOCK_CODE_SHAVIAN_name = zend_string_init_interned("BLOCK_CODE_SHAVIAN", sizeof("BLOCK_CODE_SHAVIAN") - 1, 1); + zend_string *const_BLOCK_CODE_SHAVIAN_name = zend_string_init_interned("BLOCK_CODE_SHAVIAN", sizeof("BLOCK_CODE_SHAVIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SHAVIAN_name, &const_BLOCK_CODE_SHAVIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SHAVIAN_name); + zend_string_release_ex(const_BLOCK_CODE_SHAVIAN_name, true); zval const_BLOCK_CODE_OSMANYA_value; ZVAL_LONG(&const_BLOCK_CODE_OSMANYA_value, UBLOCK_OSMANYA); - zend_string *const_BLOCK_CODE_OSMANYA_name = zend_string_init_interned("BLOCK_CODE_OSMANYA", sizeof("BLOCK_CODE_OSMANYA") - 1, 1); + zend_string *const_BLOCK_CODE_OSMANYA_name = zend_string_init_interned("BLOCK_CODE_OSMANYA", sizeof("BLOCK_CODE_OSMANYA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OSMANYA_name, &const_BLOCK_CODE_OSMANYA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OSMANYA_name); + zend_string_release_ex(const_BLOCK_CODE_OSMANYA_name, true); zval const_BLOCK_CODE_CYPRIOT_SYLLABARY_value; ZVAL_LONG(&const_BLOCK_CODE_CYPRIOT_SYLLABARY_value, UBLOCK_CYPRIOT_SYLLABARY); - zend_string *const_BLOCK_CODE_CYPRIOT_SYLLABARY_name = zend_string_init_interned("BLOCK_CODE_CYPRIOT_SYLLABARY", sizeof("BLOCK_CODE_CYPRIOT_SYLLABARY") - 1, 1); + zend_string *const_BLOCK_CODE_CYPRIOT_SYLLABARY_name = zend_string_init_interned("BLOCK_CODE_CYPRIOT_SYLLABARY", sizeof("BLOCK_CODE_CYPRIOT_SYLLABARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CYPRIOT_SYLLABARY_name, &const_BLOCK_CODE_CYPRIOT_SYLLABARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CYPRIOT_SYLLABARY_name); + zend_string_release_ex(const_BLOCK_CODE_CYPRIOT_SYLLABARY_name, true); zval const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_value, UBLOCK_TAI_XUAN_JING_SYMBOLS); - zend_string *const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_TAI_XUAN_JING_SYMBOLS", sizeof("BLOCK_CODE_TAI_XUAN_JING_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_TAI_XUAN_JING_SYMBOLS", sizeof("BLOCK_CODE_TAI_XUAN_JING_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_name, &const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_TAI_XUAN_JING_SYMBOLS_name, true); zval const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_value, UBLOCK_VARIATION_SELECTORS_SUPPLEMENT); - zend_string *const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT", sizeof("BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT", sizeof("BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_name, &const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_VARIATION_SELECTORS_SUPPLEMENT_name, true); zval const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_value; ZVAL_LONG(&const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_value, UBLOCK_ANCIENT_GREEK_MUSICAL_NOTATION); - zend_string *const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_name = zend_string_init_interned("BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION", sizeof("BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION") - 1, 1); + zend_string *const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_name = zend_string_init_interned("BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION", sizeof("BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_name, &const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_name); + zend_string_release_ex(const_BLOCK_CODE_ANCIENT_GREEK_MUSICAL_NOTATION_name, true); zval const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_value; ZVAL_LONG(&const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_value, UBLOCK_ANCIENT_GREEK_NUMBERS); - zend_string *const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_ANCIENT_GREEK_NUMBERS", sizeof("BLOCK_CODE_ANCIENT_GREEK_NUMBERS") - 1, 1); + zend_string *const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_ANCIENT_GREEK_NUMBERS", sizeof("BLOCK_CODE_ANCIENT_GREEK_NUMBERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_name, &const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_name); + zend_string_release_ex(const_BLOCK_CODE_ANCIENT_GREEK_NUMBERS_name, true); zval const_BLOCK_CODE_ARABIC_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_ARABIC_SUPPLEMENT_value, UBLOCK_ARABIC_SUPPLEMENT); - zend_string *const_BLOCK_CODE_ARABIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ARABIC_SUPPLEMENT", sizeof("BLOCK_CODE_ARABIC_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_ARABIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ARABIC_SUPPLEMENT", sizeof("BLOCK_CODE_ARABIC_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARABIC_SUPPLEMENT_name, &const_BLOCK_CODE_ARABIC_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARABIC_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_ARABIC_SUPPLEMENT_name, true); zval const_BLOCK_CODE_BUGINESE_value; ZVAL_LONG(&const_BLOCK_CODE_BUGINESE_value, UBLOCK_BUGINESE); - zend_string *const_BLOCK_CODE_BUGINESE_name = zend_string_init_interned("BLOCK_CODE_BUGINESE", sizeof("BLOCK_CODE_BUGINESE") - 1, 1); + zend_string *const_BLOCK_CODE_BUGINESE_name = zend_string_init_interned("BLOCK_CODE_BUGINESE", sizeof("BLOCK_CODE_BUGINESE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BUGINESE_name, &const_BLOCK_CODE_BUGINESE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BUGINESE_name); + zend_string_release_ex(const_BLOCK_CODE_BUGINESE_name, true); zval const_BLOCK_CODE_CJK_STROKES_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_STROKES_value, UBLOCK_CJK_STROKES); - zend_string *const_BLOCK_CODE_CJK_STROKES_name = zend_string_init_interned("BLOCK_CODE_CJK_STROKES", sizeof("BLOCK_CODE_CJK_STROKES") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_STROKES_name = zend_string_init_interned("BLOCK_CODE_CJK_STROKES", sizeof("BLOCK_CODE_CJK_STROKES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_STROKES_name, &const_BLOCK_CODE_CJK_STROKES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_STROKES_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_STROKES_name, true); zval const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_value, UBLOCK_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT); - zend_string *const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT", sizeof("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT", sizeof("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_name, &const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT_name, true); zval const_BLOCK_CODE_COPTIC_value; ZVAL_LONG(&const_BLOCK_CODE_COPTIC_value, UBLOCK_COPTIC); - zend_string *const_BLOCK_CODE_COPTIC_name = zend_string_init_interned("BLOCK_CODE_COPTIC", sizeof("BLOCK_CODE_COPTIC") - 1, 1); + zend_string *const_BLOCK_CODE_COPTIC_name = zend_string_init_interned("BLOCK_CODE_COPTIC", sizeof("BLOCK_CODE_COPTIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COPTIC_name, &const_BLOCK_CODE_COPTIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COPTIC_name); + zend_string_release_ex(const_BLOCK_CODE_COPTIC_name, true); zval const_BLOCK_CODE_ETHIOPIC_EXTENDED_value; ZVAL_LONG(&const_BLOCK_CODE_ETHIOPIC_EXTENDED_value, UBLOCK_ETHIOPIC_EXTENDED); - zend_string *const_BLOCK_CODE_ETHIOPIC_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC_EXTENDED", sizeof("BLOCK_CODE_ETHIOPIC_EXTENDED") - 1, 1); + zend_string *const_BLOCK_CODE_ETHIOPIC_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC_EXTENDED", sizeof("BLOCK_CODE_ETHIOPIC_EXTENDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ETHIOPIC_EXTENDED_name, &const_BLOCK_CODE_ETHIOPIC_EXTENDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ETHIOPIC_EXTENDED_name); + zend_string_release_ex(const_BLOCK_CODE_ETHIOPIC_EXTENDED_name, true); zval const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_value, UBLOCK_ETHIOPIC_SUPPLEMENT); - zend_string *const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC_SUPPLEMENT", sizeof("BLOCK_CODE_ETHIOPIC_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC_SUPPLEMENT", sizeof("BLOCK_CODE_ETHIOPIC_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_name, &const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_ETHIOPIC_SUPPLEMENT_name, true); zval const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_value, UBLOCK_GEORGIAN_SUPPLEMENT); - zend_string *const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_GEORGIAN_SUPPLEMENT", sizeof("BLOCK_CODE_GEORGIAN_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_GEORGIAN_SUPPLEMENT", sizeof("BLOCK_CODE_GEORGIAN_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_name, &const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_GEORGIAN_SUPPLEMENT_name, true); zval const_BLOCK_CODE_GLAGOLITIC_value; ZVAL_LONG(&const_BLOCK_CODE_GLAGOLITIC_value, UBLOCK_GLAGOLITIC); - zend_string *const_BLOCK_CODE_GLAGOLITIC_name = zend_string_init_interned("BLOCK_CODE_GLAGOLITIC", sizeof("BLOCK_CODE_GLAGOLITIC") - 1, 1); + zend_string *const_BLOCK_CODE_GLAGOLITIC_name = zend_string_init_interned("BLOCK_CODE_GLAGOLITIC", sizeof("BLOCK_CODE_GLAGOLITIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GLAGOLITIC_name, &const_BLOCK_CODE_GLAGOLITIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GLAGOLITIC_name); + zend_string_release_ex(const_BLOCK_CODE_GLAGOLITIC_name, true); zval const_BLOCK_CODE_KHAROSHTHI_value; ZVAL_LONG(&const_BLOCK_CODE_KHAROSHTHI_value, UBLOCK_KHAROSHTHI); - zend_string *const_BLOCK_CODE_KHAROSHTHI_name = zend_string_init_interned("BLOCK_CODE_KHAROSHTHI", sizeof("BLOCK_CODE_KHAROSHTHI") - 1, 1); + zend_string *const_BLOCK_CODE_KHAROSHTHI_name = zend_string_init_interned("BLOCK_CODE_KHAROSHTHI", sizeof("BLOCK_CODE_KHAROSHTHI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KHAROSHTHI_name, &const_BLOCK_CODE_KHAROSHTHI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KHAROSHTHI_name); + zend_string_release_ex(const_BLOCK_CODE_KHAROSHTHI_name, true); zval const_BLOCK_CODE_MODIFIER_TONE_LETTERS_value; ZVAL_LONG(&const_BLOCK_CODE_MODIFIER_TONE_LETTERS_value, UBLOCK_MODIFIER_TONE_LETTERS); - zend_string *const_BLOCK_CODE_MODIFIER_TONE_LETTERS_name = zend_string_init_interned("BLOCK_CODE_MODIFIER_TONE_LETTERS", sizeof("BLOCK_CODE_MODIFIER_TONE_LETTERS") - 1, 1); + zend_string *const_BLOCK_CODE_MODIFIER_TONE_LETTERS_name = zend_string_init_interned("BLOCK_CODE_MODIFIER_TONE_LETTERS", sizeof("BLOCK_CODE_MODIFIER_TONE_LETTERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MODIFIER_TONE_LETTERS_name, &const_BLOCK_CODE_MODIFIER_TONE_LETTERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MODIFIER_TONE_LETTERS_name); + zend_string_release_ex(const_BLOCK_CODE_MODIFIER_TONE_LETTERS_name, true); zval const_BLOCK_CODE_NEW_TAI_LUE_value; ZVAL_LONG(&const_BLOCK_CODE_NEW_TAI_LUE_value, UBLOCK_NEW_TAI_LUE); - zend_string *const_BLOCK_CODE_NEW_TAI_LUE_name = zend_string_init_interned("BLOCK_CODE_NEW_TAI_LUE", sizeof("BLOCK_CODE_NEW_TAI_LUE") - 1, 1); + zend_string *const_BLOCK_CODE_NEW_TAI_LUE_name = zend_string_init_interned("BLOCK_CODE_NEW_TAI_LUE", sizeof("BLOCK_CODE_NEW_TAI_LUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_NEW_TAI_LUE_name, &const_BLOCK_CODE_NEW_TAI_LUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_NEW_TAI_LUE_name); + zend_string_release_ex(const_BLOCK_CODE_NEW_TAI_LUE_name, true); zval const_BLOCK_CODE_OLD_PERSIAN_value; ZVAL_LONG(&const_BLOCK_CODE_OLD_PERSIAN_value, UBLOCK_OLD_PERSIAN); - zend_string *const_BLOCK_CODE_OLD_PERSIAN_name = zend_string_init_interned("BLOCK_CODE_OLD_PERSIAN", sizeof("BLOCK_CODE_OLD_PERSIAN") - 1, 1); + zend_string *const_BLOCK_CODE_OLD_PERSIAN_name = zend_string_init_interned("BLOCK_CODE_OLD_PERSIAN", sizeof("BLOCK_CODE_OLD_PERSIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OLD_PERSIAN_name, &const_BLOCK_CODE_OLD_PERSIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OLD_PERSIAN_name); + zend_string_release_ex(const_BLOCK_CODE_OLD_PERSIAN_name, true); zval const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_value, UBLOCK_PHONETIC_EXTENSIONS_SUPPLEMENT); - zend_string *const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT", sizeof("BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT", sizeof("BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_name, &const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_PHONETIC_EXTENSIONS_SUPPLEMENT_name, true); zval const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_value; ZVAL_LONG(&const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_value, UBLOCK_SUPPLEMENTAL_PUNCTUATION); - zend_string *const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION", sizeof("BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION") - 1, 1); + zend_string *const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION", sizeof("BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_name, &const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_name); + zend_string_release_ex(const_BLOCK_CODE_SUPPLEMENTAL_PUNCTUATION_name, true); zval const_BLOCK_CODE_SYLOTI_NAGRI_value; ZVAL_LONG(&const_BLOCK_CODE_SYLOTI_NAGRI_value, UBLOCK_SYLOTI_NAGRI); - zend_string *const_BLOCK_CODE_SYLOTI_NAGRI_name = zend_string_init_interned("BLOCK_CODE_SYLOTI_NAGRI", sizeof("BLOCK_CODE_SYLOTI_NAGRI") - 1, 1); + zend_string *const_BLOCK_CODE_SYLOTI_NAGRI_name = zend_string_init_interned("BLOCK_CODE_SYLOTI_NAGRI", sizeof("BLOCK_CODE_SYLOTI_NAGRI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SYLOTI_NAGRI_name, &const_BLOCK_CODE_SYLOTI_NAGRI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SYLOTI_NAGRI_name); + zend_string_release_ex(const_BLOCK_CODE_SYLOTI_NAGRI_name, true); zval const_BLOCK_CODE_TIFINAGH_value; ZVAL_LONG(&const_BLOCK_CODE_TIFINAGH_value, UBLOCK_TIFINAGH); - zend_string *const_BLOCK_CODE_TIFINAGH_name = zend_string_init_interned("BLOCK_CODE_TIFINAGH", sizeof("BLOCK_CODE_TIFINAGH") - 1, 1); + zend_string *const_BLOCK_CODE_TIFINAGH_name = zend_string_init_interned("BLOCK_CODE_TIFINAGH", sizeof("BLOCK_CODE_TIFINAGH") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TIFINAGH_name, &const_BLOCK_CODE_TIFINAGH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TIFINAGH_name); + zend_string_release_ex(const_BLOCK_CODE_TIFINAGH_name, true); zval const_BLOCK_CODE_VERTICAL_FORMS_value; ZVAL_LONG(&const_BLOCK_CODE_VERTICAL_FORMS_value, UBLOCK_VERTICAL_FORMS); - zend_string *const_BLOCK_CODE_VERTICAL_FORMS_name = zend_string_init_interned("BLOCK_CODE_VERTICAL_FORMS", sizeof("BLOCK_CODE_VERTICAL_FORMS") - 1, 1); + zend_string *const_BLOCK_CODE_VERTICAL_FORMS_name = zend_string_init_interned("BLOCK_CODE_VERTICAL_FORMS", sizeof("BLOCK_CODE_VERTICAL_FORMS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_VERTICAL_FORMS_name, &const_BLOCK_CODE_VERTICAL_FORMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_VERTICAL_FORMS_name); + zend_string_release_ex(const_BLOCK_CODE_VERTICAL_FORMS_name, true); zval const_BLOCK_CODE_NKO_value; ZVAL_LONG(&const_BLOCK_CODE_NKO_value, UBLOCK_NKO); - zend_string *const_BLOCK_CODE_NKO_name = zend_string_init_interned("BLOCK_CODE_NKO", sizeof("BLOCK_CODE_NKO") - 1, 1); + zend_string *const_BLOCK_CODE_NKO_name = zend_string_init_interned("BLOCK_CODE_NKO", sizeof("BLOCK_CODE_NKO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_NKO_name, &const_BLOCK_CODE_NKO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_NKO_name); + zend_string_release_ex(const_BLOCK_CODE_NKO_name, true); zval const_BLOCK_CODE_BALINESE_value; ZVAL_LONG(&const_BLOCK_CODE_BALINESE_value, UBLOCK_BALINESE); - zend_string *const_BLOCK_CODE_BALINESE_name = zend_string_init_interned("BLOCK_CODE_BALINESE", sizeof("BLOCK_CODE_BALINESE") - 1, 1); + zend_string *const_BLOCK_CODE_BALINESE_name = zend_string_init_interned("BLOCK_CODE_BALINESE", sizeof("BLOCK_CODE_BALINESE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BALINESE_name, &const_BLOCK_CODE_BALINESE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BALINESE_name); + zend_string_release_ex(const_BLOCK_CODE_BALINESE_name, true); zval const_BLOCK_CODE_LATIN_EXTENDED_C_value; ZVAL_LONG(&const_BLOCK_CODE_LATIN_EXTENDED_C_value, UBLOCK_LATIN_EXTENDED_C); - zend_string *const_BLOCK_CODE_LATIN_EXTENDED_C_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_C", sizeof("BLOCK_CODE_LATIN_EXTENDED_C") - 1, 1); + zend_string *const_BLOCK_CODE_LATIN_EXTENDED_C_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_C", sizeof("BLOCK_CODE_LATIN_EXTENDED_C") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LATIN_EXTENDED_C_name, &const_BLOCK_CODE_LATIN_EXTENDED_C_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LATIN_EXTENDED_C_name); + zend_string_release_ex(const_BLOCK_CODE_LATIN_EXTENDED_C_name, true); zval const_BLOCK_CODE_LATIN_EXTENDED_D_value; ZVAL_LONG(&const_BLOCK_CODE_LATIN_EXTENDED_D_value, UBLOCK_LATIN_EXTENDED_D); - zend_string *const_BLOCK_CODE_LATIN_EXTENDED_D_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_D", sizeof("BLOCK_CODE_LATIN_EXTENDED_D") - 1, 1); + zend_string *const_BLOCK_CODE_LATIN_EXTENDED_D_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_D", sizeof("BLOCK_CODE_LATIN_EXTENDED_D") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LATIN_EXTENDED_D_name, &const_BLOCK_CODE_LATIN_EXTENDED_D_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LATIN_EXTENDED_D_name); + zend_string_release_ex(const_BLOCK_CODE_LATIN_EXTENDED_D_name, true); zval const_BLOCK_CODE_PHAGS_PA_value; ZVAL_LONG(&const_BLOCK_CODE_PHAGS_PA_value, UBLOCK_PHAGS_PA); - zend_string *const_BLOCK_CODE_PHAGS_PA_name = zend_string_init_interned("BLOCK_CODE_PHAGS_PA", sizeof("BLOCK_CODE_PHAGS_PA") - 1, 1); + zend_string *const_BLOCK_CODE_PHAGS_PA_name = zend_string_init_interned("BLOCK_CODE_PHAGS_PA", sizeof("BLOCK_CODE_PHAGS_PA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PHAGS_PA_name, &const_BLOCK_CODE_PHAGS_PA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PHAGS_PA_name); + zend_string_release_ex(const_BLOCK_CODE_PHAGS_PA_name, true); zval const_BLOCK_CODE_PHOENICIAN_value; ZVAL_LONG(&const_BLOCK_CODE_PHOENICIAN_value, UBLOCK_PHOENICIAN); - zend_string *const_BLOCK_CODE_PHOENICIAN_name = zend_string_init_interned("BLOCK_CODE_PHOENICIAN", sizeof("BLOCK_CODE_PHOENICIAN") - 1, 1); + zend_string *const_BLOCK_CODE_PHOENICIAN_name = zend_string_init_interned("BLOCK_CODE_PHOENICIAN", sizeof("BLOCK_CODE_PHOENICIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PHOENICIAN_name, &const_BLOCK_CODE_PHOENICIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PHOENICIAN_name); + zend_string_release_ex(const_BLOCK_CODE_PHOENICIAN_name, true); zval const_BLOCK_CODE_CUNEIFORM_value; ZVAL_LONG(&const_BLOCK_CODE_CUNEIFORM_value, UBLOCK_CUNEIFORM); - zend_string *const_BLOCK_CODE_CUNEIFORM_name = zend_string_init_interned("BLOCK_CODE_CUNEIFORM", sizeof("BLOCK_CODE_CUNEIFORM") - 1, 1); + zend_string *const_BLOCK_CODE_CUNEIFORM_name = zend_string_init_interned("BLOCK_CODE_CUNEIFORM", sizeof("BLOCK_CODE_CUNEIFORM") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CUNEIFORM_name, &const_BLOCK_CODE_CUNEIFORM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CUNEIFORM_name); + zend_string_release_ex(const_BLOCK_CODE_CUNEIFORM_name, true); zval const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_value; ZVAL_LONG(&const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_value, UBLOCK_CUNEIFORM_NUMBERS_AND_PUNCTUATION); - zend_string *const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION", sizeof("BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION") - 1, 1); + zend_string *const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_name = zend_string_init_interned("BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION", sizeof("BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_name, &const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_name); + zend_string_release_ex(const_BLOCK_CODE_CUNEIFORM_NUMBERS_AND_PUNCTUATION_name, true); zval const_BLOCK_CODE_COUNTING_ROD_NUMERALS_value; ZVAL_LONG(&const_BLOCK_CODE_COUNTING_ROD_NUMERALS_value, UBLOCK_COUNTING_ROD_NUMERALS); - zend_string *const_BLOCK_CODE_COUNTING_ROD_NUMERALS_name = zend_string_init_interned("BLOCK_CODE_COUNTING_ROD_NUMERALS", sizeof("BLOCK_CODE_COUNTING_ROD_NUMERALS") - 1, 1); + zend_string *const_BLOCK_CODE_COUNTING_ROD_NUMERALS_name = zend_string_init_interned("BLOCK_CODE_COUNTING_ROD_NUMERALS", sizeof("BLOCK_CODE_COUNTING_ROD_NUMERALS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COUNTING_ROD_NUMERALS_name, &const_BLOCK_CODE_COUNTING_ROD_NUMERALS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COUNTING_ROD_NUMERALS_name); + zend_string_release_ex(const_BLOCK_CODE_COUNTING_ROD_NUMERALS_name, true); zval const_BLOCK_CODE_SUNDANESE_value; ZVAL_LONG(&const_BLOCK_CODE_SUNDANESE_value, UBLOCK_SUNDANESE); - zend_string *const_BLOCK_CODE_SUNDANESE_name = zend_string_init_interned("BLOCK_CODE_SUNDANESE", sizeof("BLOCK_CODE_SUNDANESE") - 1, 1); + zend_string *const_BLOCK_CODE_SUNDANESE_name = zend_string_init_interned("BLOCK_CODE_SUNDANESE", sizeof("BLOCK_CODE_SUNDANESE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUNDANESE_name, &const_BLOCK_CODE_SUNDANESE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUNDANESE_name); + zend_string_release_ex(const_BLOCK_CODE_SUNDANESE_name, true); zval const_BLOCK_CODE_LEPCHA_value; ZVAL_LONG(&const_BLOCK_CODE_LEPCHA_value, UBLOCK_LEPCHA); - zend_string *const_BLOCK_CODE_LEPCHA_name = zend_string_init_interned("BLOCK_CODE_LEPCHA", sizeof("BLOCK_CODE_LEPCHA") - 1, 1); + zend_string *const_BLOCK_CODE_LEPCHA_name = zend_string_init_interned("BLOCK_CODE_LEPCHA", sizeof("BLOCK_CODE_LEPCHA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LEPCHA_name, &const_BLOCK_CODE_LEPCHA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LEPCHA_name); + zend_string_release_ex(const_BLOCK_CODE_LEPCHA_name, true); zval const_BLOCK_CODE_OL_CHIKI_value; ZVAL_LONG(&const_BLOCK_CODE_OL_CHIKI_value, UBLOCK_OL_CHIKI); - zend_string *const_BLOCK_CODE_OL_CHIKI_name = zend_string_init_interned("BLOCK_CODE_OL_CHIKI", sizeof("BLOCK_CODE_OL_CHIKI") - 1, 1); + zend_string *const_BLOCK_CODE_OL_CHIKI_name = zend_string_init_interned("BLOCK_CODE_OL_CHIKI", sizeof("BLOCK_CODE_OL_CHIKI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OL_CHIKI_name, &const_BLOCK_CODE_OL_CHIKI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OL_CHIKI_name); + zend_string_release_ex(const_BLOCK_CODE_OL_CHIKI_name, true); zval const_BLOCK_CODE_CYRILLIC_EXTENDED_A_value; ZVAL_LONG(&const_BLOCK_CODE_CYRILLIC_EXTENDED_A_value, UBLOCK_CYRILLIC_EXTENDED_A); - zend_string *const_BLOCK_CODE_CYRILLIC_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_EXTENDED_A", sizeof("BLOCK_CODE_CYRILLIC_EXTENDED_A") - 1, 1); + zend_string *const_BLOCK_CODE_CYRILLIC_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_EXTENDED_A", sizeof("BLOCK_CODE_CYRILLIC_EXTENDED_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CYRILLIC_EXTENDED_A_name, &const_BLOCK_CODE_CYRILLIC_EXTENDED_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CYRILLIC_EXTENDED_A_name); + zend_string_release_ex(const_BLOCK_CODE_CYRILLIC_EXTENDED_A_name, true); zval const_BLOCK_CODE_VAI_value; ZVAL_LONG(&const_BLOCK_CODE_VAI_value, UBLOCK_VAI); - zend_string *const_BLOCK_CODE_VAI_name = zend_string_init_interned("BLOCK_CODE_VAI", sizeof("BLOCK_CODE_VAI") - 1, 1); + zend_string *const_BLOCK_CODE_VAI_name = zend_string_init_interned("BLOCK_CODE_VAI", sizeof("BLOCK_CODE_VAI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_VAI_name, &const_BLOCK_CODE_VAI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_VAI_name); + zend_string_release_ex(const_BLOCK_CODE_VAI_name, true); zval const_BLOCK_CODE_CYRILLIC_EXTENDED_B_value; ZVAL_LONG(&const_BLOCK_CODE_CYRILLIC_EXTENDED_B_value, UBLOCK_CYRILLIC_EXTENDED_B); - zend_string *const_BLOCK_CODE_CYRILLIC_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_EXTENDED_B", sizeof("BLOCK_CODE_CYRILLIC_EXTENDED_B") - 1, 1); + zend_string *const_BLOCK_CODE_CYRILLIC_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_CYRILLIC_EXTENDED_B", sizeof("BLOCK_CODE_CYRILLIC_EXTENDED_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CYRILLIC_EXTENDED_B_name, &const_BLOCK_CODE_CYRILLIC_EXTENDED_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CYRILLIC_EXTENDED_B_name); + zend_string_release_ex(const_BLOCK_CODE_CYRILLIC_EXTENDED_B_name, true); zval const_BLOCK_CODE_SAURASHTRA_value; ZVAL_LONG(&const_BLOCK_CODE_SAURASHTRA_value, UBLOCK_SAURASHTRA); - zend_string *const_BLOCK_CODE_SAURASHTRA_name = zend_string_init_interned("BLOCK_CODE_SAURASHTRA", sizeof("BLOCK_CODE_SAURASHTRA") - 1, 1); + zend_string *const_BLOCK_CODE_SAURASHTRA_name = zend_string_init_interned("BLOCK_CODE_SAURASHTRA", sizeof("BLOCK_CODE_SAURASHTRA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SAURASHTRA_name, &const_BLOCK_CODE_SAURASHTRA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SAURASHTRA_name); + zend_string_release_ex(const_BLOCK_CODE_SAURASHTRA_name, true); zval const_BLOCK_CODE_KAYAH_LI_value; ZVAL_LONG(&const_BLOCK_CODE_KAYAH_LI_value, UBLOCK_KAYAH_LI); - zend_string *const_BLOCK_CODE_KAYAH_LI_name = zend_string_init_interned("BLOCK_CODE_KAYAH_LI", sizeof("BLOCK_CODE_KAYAH_LI") - 1, 1); + zend_string *const_BLOCK_CODE_KAYAH_LI_name = zend_string_init_interned("BLOCK_CODE_KAYAH_LI", sizeof("BLOCK_CODE_KAYAH_LI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KAYAH_LI_name, &const_BLOCK_CODE_KAYAH_LI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KAYAH_LI_name); + zend_string_release_ex(const_BLOCK_CODE_KAYAH_LI_name, true); zval const_BLOCK_CODE_REJANG_value; ZVAL_LONG(&const_BLOCK_CODE_REJANG_value, UBLOCK_REJANG); - zend_string *const_BLOCK_CODE_REJANG_name = zend_string_init_interned("BLOCK_CODE_REJANG", sizeof("BLOCK_CODE_REJANG") - 1, 1); + zend_string *const_BLOCK_CODE_REJANG_name = zend_string_init_interned("BLOCK_CODE_REJANG", sizeof("BLOCK_CODE_REJANG") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_REJANG_name, &const_BLOCK_CODE_REJANG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_REJANG_name); + zend_string_release_ex(const_BLOCK_CODE_REJANG_name, true); zval const_BLOCK_CODE_CHAM_value; ZVAL_LONG(&const_BLOCK_CODE_CHAM_value, UBLOCK_CHAM); - zend_string *const_BLOCK_CODE_CHAM_name = zend_string_init_interned("BLOCK_CODE_CHAM", sizeof("BLOCK_CODE_CHAM") - 1, 1); + zend_string *const_BLOCK_CODE_CHAM_name = zend_string_init_interned("BLOCK_CODE_CHAM", sizeof("BLOCK_CODE_CHAM") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CHAM_name, &const_BLOCK_CODE_CHAM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CHAM_name); + zend_string_release_ex(const_BLOCK_CODE_CHAM_name, true); zval const_BLOCK_CODE_ANCIENT_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_ANCIENT_SYMBOLS_value, UBLOCK_ANCIENT_SYMBOLS); - zend_string *const_BLOCK_CODE_ANCIENT_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_ANCIENT_SYMBOLS", sizeof("BLOCK_CODE_ANCIENT_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_ANCIENT_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_ANCIENT_SYMBOLS", sizeof("BLOCK_CODE_ANCIENT_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ANCIENT_SYMBOLS_name, &const_BLOCK_CODE_ANCIENT_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ANCIENT_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_ANCIENT_SYMBOLS_name, true); zval const_BLOCK_CODE_PHAISTOS_DISC_value; ZVAL_LONG(&const_BLOCK_CODE_PHAISTOS_DISC_value, UBLOCK_PHAISTOS_DISC); - zend_string *const_BLOCK_CODE_PHAISTOS_DISC_name = zend_string_init_interned("BLOCK_CODE_PHAISTOS_DISC", sizeof("BLOCK_CODE_PHAISTOS_DISC") - 1, 1); + zend_string *const_BLOCK_CODE_PHAISTOS_DISC_name = zend_string_init_interned("BLOCK_CODE_PHAISTOS_DISC", sizeof("BLOCK_CODE_PHAISTOS_DISC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PHAISTOS_DISC_name, &const_BLOCK_CODE_PHAISTOS_DISC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PHAISTOS_DISC_name); + zend_string_release_ex(const_BLOCK_CODE_PHAISTOS_DISC_name, true); zval const_BLOCK_CODE_LYCIAN_value; ZVAL_LONG(&const_BLOCK_CODE_LYCIAN_value, UBLOCK_LYCIAN); - zend_string *const_BLOCK_CODE_LYCIAN_name = zend_string_init_interned("BLOCK_CODE_LYCIAN", sizeof("BLOCK_CODE_LYCIAN") - 1, 1); + zend_string *const_BLOCK_CODE_LYCIAN_name = zend_string_init_interned("BLOCK_CODE_LYCIAN", sizeof("BLOCK_CODE_LYCIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LYCIAN_name, &const_BLOCK_CODE_LYCIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LYCIAN_name); + zend_string_release_ex(const_BLOCK_CODE_LYCIAN_name, true); zval const_BLOCK_CODE_CARIAN_value; ZVAL_LONG(&const_BLOCK_CODE_CARIAN_value, UBLOCK_CARIAN); - zend_string *const_BLOCK_CODE_CARIAN_name = zend_string_init_interned("BLOCK_CODE_CARIAN", sizeof("BLOCK_CODE_CARIAN") - 1, 1); + zend_string *const_BLOCK_CODE_CARIAN_name = zend_string_init_interned("BLOCK_CODE_CARIAN", sizeof("BLOCK_CODE_CARIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CARIAN_name, &const_BLOCK_CODE_CARIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CARIAN_name); + zend_string_release_ex(const_BLOCK_CODE_CARIAN_name, true); zval const_BLOCK_CODE_LYDIAN_value; ZVAL_LONG(&const_BLOCK_CODE_LYDIAN_value, UBLOCK_LYDIAN); - zend_string *const_BLOCK_CODE_LYDIAN_name = zend_string_init_interned("BLOCK_CODE_LYDIAN", sizeof("BLOCK_CODE_LYDIAN") - 1, 1); + zend_string *const_BLOCK_CODE_LYDIAN_name = zend_string_init_interned("BLOCK_CODE_LYDIAN", sizeof("BLOCK_CODE_LYDIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LYDIAN_name, &const_BLOCK_CODE_LYDIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LYDIAN_name); + zend_string_release_ex(const_BLOCK_CODE_LYDIAN_name, true); zval const_BLOCK_CODE_MAHJONG_TILES_value; ZVAL_LONG(&const_BLOCK_CODE_MAHJONG_TILES_value, UBLOCK_MAHJONG_TILES); - zend_string *const_BLOCK_CODE_MAHJONG_TILES_name = zend_string_init_interned("BLOCK_CODE_MAHJONG_TILES", sizeof("BLOCK_CODE_MAHJONG_TILES") - 1, 1); + zend_string *const_BLOCK_CODE_MAHJONG_TILES_name = zend_string_init_interned("BLOCK_CODE_MAHJONG_TILES", sizeof("BLOCK_CODE_MAHJONG_TILES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MAHJONG_TILES_name, &const_BLOCK_CODE_MAHJONG_TILES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MAHJONG_TILES_name); + zend_string_release_ex(const_BLOCK_CODE_MAHJONG_TILES_name, true); zval const_BLOCK_CODE_DOMINO_TILES_value; ZVAL_LONG(&const_BLOCK_CODE_DOMINO_TILES_value, UBLOCK_DOMINO_TILES); - zend_string *const_BLOCK_CODE_DOMINO_TILES_name = zend_string_init_interned("BLOCK_CODE_DOMINO_TILES", sizeof("BLOCK_CODE_DOMINO_TILES") - 1, 1); + zend_string *const_BLOCK_CODE_DOMINO_TILES_name = zend_string_init_interned("BLOCK_CODE_DOMINO_TILES", sizeof("BLOCK_CODE_DOMINO_TILES") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_DOMINO_TILES_name, &const_BLOCK_CODE_DOMINO_TILES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_DOMINO_TILES_name); + zend_string_release_ex(const_BLOCK_CODE_DOMINO_TILES_name, true); zval const_BLOCK_CODE_SAMARITAN_value; ZVAL_LONG(&const_BLOCK_CODE_SAMARITAN_value, UBLOCK_SAMARITAN); - zend_string *const_BLOCK_CODE_SAMARITAN_name = zend_string_init_interned("BLOCK_CODE_SAMARITAN", sizeof("BLOCK_CODE_SAMARITAN") - 1, 1); + zend_string *const_BLOCK_CODE_SAMARITAN_name = zend_string_init_interned("BLOCK_CODE_SAMARITAN", sizeof("BLOCK_CODE_SAMARITAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SAMARITAN_name, &const_BLOCK_CODE_SAMARITAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SAMARITAN_name); + zend_string_release_ex(const_BLOCK_CODE_SAMARITAN_name, true); zval const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_value; ZVAL_LONG(&const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_value, UBLOCK_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED); - zend_string *const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED", sizeof("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED") - 1, 1); + zend_string *const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED", sizeof("BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_name, &const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_name); + zend_string_release_ex(const_BLOCK_CODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_name, true); zval const_BLOCK_CODE_TAI_THAM_value; ZVAL_LONG(&const_BLOCK_CODE_TAI_THAM_value, UBLOCK_TAI_THAM); - zend_string *const_BLOCK_CODE_TAI_THAM_name = zend_string_init_interned("BLOCK_CODE_TAI_THAM", sizeof("BLOCK_CODE_TAI_THAM") - 1, 1); + zend_string *const_BLOCK_CODE_TAI_THAM_name = zend_string_init_interned("BLOCK_CODE_TAI_THAM", sizeof("BLOCK_CODE_TAI_THAM") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAI_THAM_name, &const_BLOCK_CODE_TAI_THAM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAI_THAM_name); + zend_string_release_ex(const_BLOCK_CODE_TAI_THAM_name, true); zval const_BLOCK_CODE_VEDIC_EXTENSIONS_value; ZVAL_LONG(&const_BLOCK_CODE_VEDIC_EXTENSIONS_value, UBLOCK_VEDIC_EXTENSIONS); - zend_string *const_BLOCK_CODE_VEDIC_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_VEDIC_EXTENSIONS", sizeof("BLOCK_CODE_VEDIC_EXTENSIONS") - 1, 1); + zend_string *const_BLOCK_CODE_VEDIC_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_VEDIC_EXTENSIONS", sizeof("BLOCK_CODE_VEDIC_EXTENSIONS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_VEDIC_EXTENSIONS_name, &const_BLOCK_CODE_VEDIC_EXTENSIONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_VEDIC_EXTENSIONS_name); + zend_string_release_ex(const_BLOCK_CODE_VEDIC_EXTENSIONS_name, true); zval const_BLOCK_CODE_LISU_value; ZVAL_LONG(&const_BLOCK_CODE_LISU_value, UBLOCK_LISU); - zend_string *const_BLOCK_CODE_LISU_name = zend_string_init_interned("BLOCK_CODE_LISU", sizeof("BLOCK_CODE_LISU") - 1, 1); + zend_string *const_BLOCK_CODE_LISU_name = zend_string_init_interned("BLOCK_CODE_LISU", sizeof("BLOCK_CODE_LISU") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LISU_name, &const_BLOCK_CODE_LISU_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LISU_name); + zend_string_release_ex(const_BLOCK_CODE_LISU_name, true); zval const_BLOCK_CODE_BAMUM_value; ZVAL_LONG(&const_BLOCK_CODE_BAMUM_value, UBLOCK_BAMUM); - zend_string *const_BLOCK_CODE_BAMUM_name = zend_string_init_interned("BLOCK_CODE_BAMUM", sizeof("BLOCK_CODE_BAMUM") - 1, 1); + zend_string *const_BLOCK_CODE_BAMUM_name = zend_string_init_interned("BLOCK_CODE_BAMUM", sizeof("BLOCK_CODE_BAMUM") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BAMUM_name, &const_BLOCK_CODE_BAMUM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BAMUM_name); + zend_string_release_ex(const_BLOCK_CODE_BAMUM_name, true); zval const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_value; ZVAL_LONG(&const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_value, UBLOCK_COMMON_INDIC_NUMBER_FORMS); - zend_string *const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_name = zend_string_init_interned("BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS", sizeof("BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS") - 1, 1); + zend_string *const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_name = zend_string_init_interned("BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS", sizeof("BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_name, &const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_name); + zend_string_release_ex(const_BLOCK_CODE_COMMON_INDIC_NUMBER_FORMS_name, true); zval const_BLOCK_CODE_DEVANAGARI_EXTENDED_value; ZVAL_LONG(&const_BLOCK_CODE_DEVANAGARI_EXTENDED_value, UBLOCK_DEVANAGARI_EXTENDED); - zend_string *const_BLOCK_CODE_DEVANAGARI_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_DEVANAGARI_EXTENDED", sizeof("BLOCK_CODE_DEVANAGARI_EXTENDED") - 1, 1); + zend_string *const_BLOCK_CODE_DEVANAGARI_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_DEVANAGARI_EXTENDED", sizeof("BLOCK_CODE_DEVANAGARI_EXTENDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_DEVANAGARI_EXTENDED_name, &const_BLOCK_CODE_DEVANAGARI_EXTENDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_DEVANAGARI_EXTENDED_name); + zend_string_release_ex(const_BLOCK_CODE_DEVANAGARI_EXTENDED_name, true); zval const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_value; ZVAL_LONG(&const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_value, UBLOCK_HANGUL_JAMO_EXTENDED_A); - zend_string *const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_HANGUL_JAMO_EXTENDED_A", sizeof("BLOCK_CODE_HANGUL_JAMO_EXTENDED_A") - 1, 1); + zend_string *const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_HANGUL_JAMO_EXTENDED_A", sizeof("BLOCK_CODE_HANGUL_JAMO_EXTENDED_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_name, &const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_name); + zend_string_release_ex(const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_A_name, true); zval const_BLOCK_CODE_JAVANESE_value; ZVAL_LONG(&const_BLOCK_CODE_JAVANESE_value, UBLOCK_JAVANESE); - zend_string *const_BLOCK_CODE_JAVANESE_name = zend_string_init_interned("BLOCK_CODE_JAVANESE", sizeof("BLOCK_CODE_JAVANESE") - 1, 1); + zend_string *const_BLOCK_CODE_JAVANESE_name = zend_string_init_interned("BLOCK_CODE_JAVANESE", sizeof("BLOCK_CODE_JAVANESE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_JAVANESE_name, &const_BLOCK_CODE_JAVANESE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_JAVANESE_name); + zend_string_release_ex(const_BLOCK_CODE_JAVANESE_name, true); zval const_BLOCK_CODE_MYANMAR_EXTENDED_A_value; ZVAL_LONG(&const_BLOCK_CODE_MYANMAR_EXTENDED_A_value, UBLOCK_MYANMAR_EXTENDED_A); - zend_string *const_BLOCK_CODE_MYANMAR_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_MYANMAR_EXTENDED_A", sizeof("BLOCK_CODE_MYANMAR_EXTENDED_A") - 1, 1); + zend_string *const_BLOCK_CODE_MYANMAR_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_MYANMAR_EXTENDED_A", sizeof("BLOCK_CODE_MYANMAR_EXTENDED_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MYANMAR_EXTENDED_A_name, &const_BLOCK_CODE_MYANMAR_EXTENDED_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MYANMAR_EXTENDED_A_name); + zend_string_release_ex(const_BLOCK_CODE_MYANMAR_EXTENDED_A_name, true); zval const_BLOCK_CODE_TAI_VIET_value; ZVAL_LONG(&const_BLOCK_CODE_TAI_VIET_value, UBLOCK_TAI_VIET); - zend_string *const_BLOCK_CODE_TAI_VIET_name = zend_string_init_interned("BLOCK_CODE_TAI_VIET", sizeof("BLOCK_CODE_TAI_VIET") - 1, 1); + zend_string *const_BLOCK_CODE_TAI_VIET_name = zend_string_init_interned("BLOCK_CODE_TAI_VIET", sizeof("BLOCK_CODE_TAI_VIET") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAI_VIET_name, &const_BLOCK_CODE_TAI_VIET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAI_VIET_name); + zend_string_release_ex(const_BLOCK_CODE_TAI_VIET_name, true); zval const_BLOCK_CODE_MEETEI_MAYEK_value; ZVAL_LONG(&const_BLOCK_CODE_MEETEI_MAYEK_value, UBLOCK_MEETEI_MAYEK); - zend_string *const_BLOCK_CODE_MEETEI_MAYEK_name = zend_string_init_interned("BLOCK_CODE_MEETEI_MAYEK", sizeof("BLOCK_CODE_MEETEI_MAYEK") - 1, 1); + zend_string *const_BLOCK_CODE_MEETEI_MAYEK_name = zend_string_init_interned("BLOCK_CODE_MEETEI_MAYEK", sizeof("BLOCK_CODE_MEETEI_MAYEK") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MEETEI_MAYEK_name, &const_BLOCK_CODE_MEETEI_MAYEK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MEETEI_MAYEK_name); + zend_string_release_ex(const_BLOCK_CODE_MEETEI_MAYEK_name, true); zval const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_value; ZVAL_LONG(&const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_value, UBLOCK_HANGUL_JAMO_EXTENDED_B); - zend_string *const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_HANGUL_JAMO_EXTENDED_B", sizeof("BLOCK_CODE_HANGUL_JAMO_EXTENDED_B") - 1, 1); + zend_string *const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_HANGUL_JAMO_EXTENDED_B", sizeof("BLOCK_CODE_HANGUL_JAMO_EXTENDED_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_name, &const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_name); + zend_string_release_ex(const_BLOCK_CODE_HANGUL_JAMO_EXTENDED_B_name, true); zval const_BLOCK_CODE_IMPERIAL_ARAMAIC_value; ZVAL_LONG(&const_BLOCK_CODE_IMPERIAL_ARAMAIC_value, UBLOCK_IMPERIAL_ARAMAIC); - zend_string *const_BLOCK_CODE_IMPERIAL_ARAMAIC_name = zend_string_init_interned("BLOCK_CODE_IMPERIAL_ARAMAIC", sizeof("BLOCK_CODE_IMPERIAL_ARAMAIC") - 1, 1); + zend_string *const_BLOCK_CODE_IMPERIAL_ARAMAIC_name = zend_string_init_interned("BLOCK_CODE_IMPERIAL_ARAMAIC", sizeof("BLOCK_CODE_IMPERIAL_ARAMAIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_IMPERIAL_ARAMAIC_name, &const_BLOCK_CODE_IMPERIAL_ARAMAIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_IMPERIAL_ARAMAIC_name); + zend_string_release_ex(const_BLOCK_CODE_IMPERIAL_ARAMAIC_name, true); zval const_BLOCK_CODE_OLD_SOUTH_ARABIAN_value; ZVAL_LONG(&const_BLOCK_CODE_OLD_SOUTH_ARABIAN_value, UBLOCK_OLD_SOUTH_ARABIAN); - zend_string *const_BLOCK_CODE_OLD_SOUTH_ARABIAN_name = zend_string_init_interned("BLOCK_CODE_OLD_SOUTH_ARABIAN", sizeof("BLOCK_CODE_OLD_SOUTH_ARABIAN") - 1, 1); + zend_string *const_BLOCK_CODE_OLD_SOUTH_ARABIAN_name = zend_string_init_interned("BLOCK_CODE_OLD_SOUTH_ARABIAN", sizeof("BLOCK_CODE_OLD_SOUTH_ARABIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OLD_SOUTH_ARABIAN_name, &const_BLOCK_CODE_OLD_SOUTH_ARABIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OLD_SOUTH_ARABIAN_name); + zend_string_release_ex(const_BLOCK_CODE_OLD_SOUTH_ARABIAN_name, true); zval const_BLOCK_CODE_AVESTAN_value; ZVAL_LONG(&const_BLOCK_CODE_AVESTAN_value, UBLOCK_AVESTAN); - zend_string *const_BLOCK_CODE_AVESTAN_name = zend_string_init_interned("BLOCK_CODE_AVESTAN", sizeof("BLOCK_CODE_AVESTAN") - 1, 1); + zend_string *const_BLOCK_CODE_AVESTAN_name = zend_string_init_interned("BLOCK_CODE_AVESTAN", sizeof("BLOCK_CODE_AVESTAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_AVESTAN_name, &const_BLOCK_CODE_AVESTAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_AVESTAN_name); + zend_string_release_ex(const_BLOCK_CODE_AVESTAN_name, true); zval const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_value; ZVAL_LONG(&const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_value, UBLOCK_INSCRIPTIONAL_PARTHIAN); - zend_string *const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_name = zend_string_init_interned("BLOCK_CODE_INSCRIPTIONAL_PARTHIAN", sizeof("BLOCK_CODE_INSCRIPTIONAL_PARTHIAN") - 1, 1); + zend_string *const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_name = zend_string_init_interned("BLOCK_CODE_INSCRIPTIONAL_PARTHIAN", sizeof("BLOCK_CODE_INSCRIPTIONAL_PARTHIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_name, &const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_name); + zend_string_release_ex(const_BLOCK_CODE_INSCRIPTIONAL_PARTHIAN_name, true); zval const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_value; ZVAL_LONG(&const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_value, UBLOCK_INSCRIPTIONAL_PAHLAVI); - zend_string *const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_name = zend_string_init_interned("BLOCK_CODE_INSCRIPTIONAL_PAHLAVI", sizeof("BLOCK_CODE_INSCRIPTIONAL_PAHLAVI") - 1, 1); + zend_string *const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_name = zend_string_init_interned("BLOCK_CODE_INSCRIPTIONAL_PAHLAVI", sizeof("BLOCK_CODE_INSCRIPTIONAL_PAHLAVI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_name, &const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_name); + zend_string_release_ex(const_BLOCK_CODE_INSCRIPTIONAL_PAHLAVI_name, true); zval const_BLOCK_CODE_OLD_TURKIC_value; ZVAL_LONG(&const_BLOCK_CODE_OLD_TURKIC_value, UBLOCK_OLD_TURKIC); - zend_string *const_BLOCK_CODE_OLD_TURKIC_name = zend_string_init_interned("BLOCK_CODE_OLD_TURKIC", sizeof("BLOCK_CODE_OLD_TURKIC") - 1, 1); + zend_string *const_BLOCK_CODE_OLD_TURKIC_name = zend_string_init_interned("BLOCK_CODE_OLD_TURKIC", sizeof("BLOCK_CODE_OLD_TURKIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OLD_TURKIC_name, &const_BLOCK_CODE_OLD_TURKIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OLD_TURKIC_name); + zend_string_release_ex(const_BLOCK_CODE_OLD_TURKIC_name, true); zval const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_value, UBLOCK_RUMI_NUMERAL_SYMBOLS); - zend_string *const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_RUMI_NUMERAL_SYMBOLS", sizeof("BLOCK_CODE_RUMI_NUMERAL_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_RUMI_NUMERAL_SYMBOLS", sizeof("BLOCK_CODE_RUMI_NUMERAL_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_name, &const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_RUMI_NUMERAL_SYMBOLS_name, true); zval const_BLOCK_CODE_KAITHI_value; ZVAL_LONG(&const_BLOCK_CODE_KAITHI_value, UBLOCK_KAITHI); - zend_string *const_BLOCK_CODE_KAITHI_name = zend_string_init_interned("BLOCK_CODE_KAITHI", sizeof("BLOCK_CODE_KAITHI") - 1, 1); + zend_string *const_BLOCK_CODE_KAITHI_name = zend_string_init_interned("BLOCK_CODE_KAITHI", sizeof("BLOCK_CODE_KAITHI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KAITHI_name, &const_BLOCK_CODE_KAITHI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KAITHI_name); + zend_string_release_ex(const_BLOCK_CODE_KAITHI_name, true); zval const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_value; ZVAL_LONG(&const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_value, UBLOCK_EGYPTIAN_HIEROGLYPHS); - zend_string *const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_name = zend_string_init_interned("BLOCK_CODE_EGYPTIAN_HIEROGLYPHS", sizeof("BLOCK_CODE_EGYPTIAN_HIEROGLYPHS") - 1, 1); + zend_string *const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_name = zend_string_init_interned("BLOCK_CODE_EGYPTIAN_HIEROGLYPHS", sizeof("BLOCK_CODE_EGYPTIAN_HIEROGLYPHS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_name, &const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_name); + zend_string_release_ex(const_BLOCK_CODE_EGYPTIAN_HIEROGLYPHS_name, true); zval const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_value, UBLOCK_ENCLOSED_ALPHANUMERIC_SUPPLEMENT); - zend_string *const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT", sizeof("BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT", sizeof("BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_name, &const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_ENCLOSED_ALPHANUMERIC_SUPPLEMENT_name, true); zval const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_value, UBLOCK_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT); - zend_string *const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT", sizeof("BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT", sizeof("BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_name, &const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_name, true); zval const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_value, UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C); - zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_name, &const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_name, true); zval const_BLOCK_CODE_MANDAIC_value; ZVAL_LONG(&const_BLOCK_CODE_MANDAIC_value, UBLOCK_MANDAIC); - zend_string *const_BLOCK_CODE_MANDAIC_name = zend_string_init_interned("BLOCK_CODE_MANDAIC", sizeof("BLOCK_CODE_MANDAIC") - 1, 1); + zend_string *const_BLOCK_CODE_MANDAIC_name = zend_string_init_interned("BLOCK_CODE_MANDAIC", sizeof("BLOCK_CODE_MANDAIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MANDAIC_name, &const_BLOCK_CODE_MANDAIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MANDAIC_name); + zend_string_release_ex(const_BLOCK_CODE_MANDAIC_name, true); zval const_BLOCK_CODE_BATAK_value; ZVAL_LONG(&const_BLOCK_CODE_BATAK_value, UBLOCK_BATAK); - zend_string *const_BLOCK_CODE_BATAK_name = zend_string_init_interned("BLOCK_CODE_BATAK", sizeof("BLOCK_CODE_BATAK") - 1, 1); + zend_string *const_BLOCK_CODE_BATAK_name = zend_string_init_interned("BLOCK_CODE_BATAK", sizeof("BLOCK_CODE_BATAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BATAK_name, &const_BLOCK_CODE_BATAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BATAK_name); + zend_string_release_ex(const_BLOCK_CODE_BATAK_name, true); zval const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_value; ZVAL_LONG(&const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_value, UBLOCK_ETHIOPIC_EXTENDED_A); - zend_string *const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC_EXTENDED_A", sizeof("BLOCK_CODE_ETHIOPIC_EXTENDED_A") - 1, 1); + zend_string *const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_ETHIOPIC_EXTENDED_A", sizeof("BLOCK_CODE_ETHIOPIC_EXTENDED_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_name, &const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_name); + zend_string_release_ex(const_BLOCK_CODE_ETHIOPIC_EXTENDED_A_name, true); zval const_BLOCK_CODE_BRAHMI_value; ZVAL_LONG(&const_BLOCK_CODE_BRAHMI_value, UBLOCK_BRAHMI); - zend_string *const_BLOCK_CODE_BRAHMI_name = zend_string_init_interned("BLOCK_CODE_BRAHMI", sizeof("BLOCK_CODE_BRAHMI") - 1, 1); + zend_string *const_BLOCK_CODE_BRAHMI_name = zend_string_init_interned("BLOCK_CODE_BRAHMI", sizeof("BLOCK_CODE_BRAHMI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BRAHMI_name, &const_BLOCK_CODE_BRAHMI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BRAHMI_name); + zend_string_release_ex(const_BLOCK_CODE_BRAHMI_name, true); zval const_BLOCK_CODE_BAMUM_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_BAMUM_SUPPLEMENT_value, UBLOCK_BAMUM_SUPPLEMENT); - zend_string *const_BLOCK_CODE_BAMUM_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_BAMUM_SUPPLEMENT", sizeof("BLOCK_CODE_BAMUM_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_BAMUM_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_BAMUM_SUPPLEMENT", sizeof("BLOCK_CODE_BAMUM_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BAMUM_SUPPLEMENT_name, &const_BLOCK_CODE_BAMUM_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BAMUM_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_BAMUM_SUPPLEMENT_name, true); zval const_BLOCK_CODE_KANA_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_KANA_SUPPLEMENT_value, UBLOCK_KANA_SUPPLEMENT); - zend_string *const_BLOCK_CODE_KANA_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_KANA_SUPPLEMENT", sizeof("BLOCK_CODE_KANA_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_KANA_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_KANA_SUPPLEMENT", sizeof("BLOCK_CODE_KANA_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KANA_SUPPLEMENT_name, &const_BLOCK_CODE_KANA_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KANA_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_KANA_SUPPLEMENT_name, true); zval const_BLOCK_CODE_PLAYING_CARDS_value; ZVAL_LONG(&const_BLOCK_CODE_PLAYING_CARDS_value, UBLOCK_PLAYING_CARDS); - zend_string *const_BLOCK_CODE_PLAYING_CARDS_name = zend_string_init_interned("BLOCK_CODE_PLAYING_CARDS", sizeof("BLOCK_CODE_PLAYING_CARDS") - 1, 1); + zend_string *const_BLOCK_CODE_PLAYING_CARDS_name = zend_string_init_interned("BLOCK_CODE_PLAYING_CARDS", sizeof("BLOCK_CODE_PLAYING_CARDS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PLAYING_CARDS_name, &const_BLOCK_CODE_PLAYING_CARDS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PLAYING_CARDS_name); + zend_string_release_ex(const_BLOCK_CODE_PLAYING_CARDS_name, true); zval const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_value; ZVAL_LONG(&const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_value, UBLOCK_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS); - zend_string *const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS", sizeof("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS") - 1, 1); + zend_string *const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_name = zend_string_init_interned("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS", sizeof("BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_name, &const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_name); + zend_string_release_ex(const_BLOCK_CODE_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS_name, true); zval const_BLOCK_CODE_EMOTICONS_value; ZVAL_LONG(&const_BLOCK_CODE_EMOTICONS_value, UBLOCK_EMOTICONS); - zend_string *const_BLOCK_CODE_EMOTICONS_name = zend_string_init_interned("BLOCK_CODE_EMOTICONS", sizeof("BLOCK_CODE_EMOTICONS") - 1, 1); + zend_string *const_BLOCK_CODE_EMOTICONS_name = zend_string_init_interned("BLOCK_CODE_EMOTICONS", sizeof("BLOCK_CODE_EMOTICONS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_EMOTICONS_name, &const_BLOCK_CODE_EMOTICONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_EMOTICONS_name); + zend_string_release_ex(const_BLOCK_CODE_EMOTICONS_name, true); zval const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_value, UBLOCK_TRANSPORT_AND_MAP_SYMBOLS); - zend_string *const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS", sizeof("BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS", sizeof("BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_name, &const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_TRANSPORT_AND_MAP_SYMBOLS_name, true); zval const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_value, UBLOCK_ALCHEMICAL_SYMBOLS); - zend_string *const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_ALCHEMICAL_SYMBOLS", sizeof("BLOCK_CODE_ALCHEMICAL_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_ALCHEMICAL_SYMBOLS", sizeof("BLOCK_CODE_ALCHEMICAL_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_name, &const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_ALCHEMICAL_SYMBOLS_name, true); zval const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_value; ZVAL_LONG(&const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_value, UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D); - zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D") - 1, 1); + zend_string *const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_name = zend_string_init_interned("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D", sizeof("BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_name, &const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_name); + zend_string_release_ex(const_BLOCK_CODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D_name, true); zval const_BLOCK_CODE_ARABIC_EXTENDED_A_value; ZVAL_LONG(&const_BLOCK_CODE_ARABIC_EXTENDED_A_value, UBLOCK_ARABIC_EXTENDED_A); - zend_string *const_BLOCK_CODE_ARABIC_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_ARABIC_EXTENDED_A", sizeof("BLOCK_CODE_ARABIC_EXTENDED_A") - 1, 1); + zend_string *const_BLOCK_CODE_ARABIC_EXTENDED_A_name = zend_string_init_interned("BLOCK_CODE_ARABIC_EXTENDED_A", sizeof("BLOCK_CODE_ARABIC_EXTENDED_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARABIC_EXTENDED_A_name, &const_BLOCK_CODE_ARABIC_EXTENDED_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARABIC_EXTENDED_A_name); + zend_string_release_ex(const_BLOCK_CODE_ARABIC_EXTENDED_A_name, true); zval const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_value; ZVAL_LONG(&const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_value, UBLOCK_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS); - zend_string *const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS", sizeof("BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS") - 1, 1); + zend_string *const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_name = zend_string_init_interned("BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS", sizeof("BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_name, &const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_name); + zend_string_release_ex(const_BLOCK_CODE_ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS_name, true); zval const_BLOCK_CODE_CHAKMA_value; ZVAL_LONG(&const_BLOCK_CODE_CHAKMA_value, UBLOCK_CHAKMA); - zend_string *const_BLOCK_CODE_CHAKMA_name = zend_string_init_interned("BLOCK_CODE_CHAKMA", sizeof("BLOCK_CODE_CHAKMA") - 1, 1); + zend_string *const_BLOCK_CODE_CHAKMA_name = zend_string_init_interned("BLOCK_CODE_CHAKMA", sizeof("BLOCK_CODE_CHAKMA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CHAKMA_name, &const_BLOCK_CODE_CHAKMA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CHAKMA_name); + zend_string_release_ex(const_BLOCK_CODE_CHAKMA_name, true); zval const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_value; ZVAL_LONG(&const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_value, UBLOCK_MEETEI_MAYEK_EXTENSIONS); - zend_string *const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS", sizeof("BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS") - 1, 1); + zend_string *const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_name = zend_string_init_interned("BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS", sizeof("BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_name, &const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_name); + zend_string_release_ex(const_BLOCK_CODE_MEETEI_MAYEK_EXTENSIONS_name, true); zval const_BLOCK_CODE_MEROITIC_CURSIVE_value; ZVAL_LONG(&const_BLOCK_CODE_MEROITIC_CURSIVE_value, UBLOCK_MEROITIC_CURSIVE); - zend_string *const_BLOCK_CODE_MEROITIC_CURSIVE_name = zend_string_init_interned("BLOCK_CODE_MEROITIC_CURSIVE", sizeof("BLOCK_CODE_MEROITIC_CURSIVE") - 1, 1); + zend_string *const_BLOCK_CODE_MEROITIC_CURSIVE_name = zend_string_init_interned("BLOCK_CODE_MEROITIC_CURSIVE", sizeof("BLOCK_CODE_MEROITIC_CURSIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MEROITIC_CURSIVE_name, &const_BLOCK_CODE_MEROITIC_CURSIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MEROITIC_CURSIVE_name); + zend_string_release_ex(const_BLOCK_CODE_MEROITIC_CURSIVE_name, true); zval const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_value; ZVAL_LONG(&const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_value, UBLOCK_MEROITIC_HIEROGLYPHS); - zend_string *const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_name = zend_string_init_interned("BLOCK_CODE_MEROITIC_HIEROGLYPHS", sizeof("BLOCK_CODE_MEROITIC_HIEROGLYPHS") - 1, 1); + zend_string *const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_name = zend_string_init_interned("BLOCK_CODE_MEROITIC_HIEROGLYPHS", sizeof("BLOCK_CODE_MEROITIC_HIEROGLYPHS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_name, &const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_name); + zend_string_release_ex(const_BLOCK_CODE_MEROITIC_HIEROGLYPHS_name, true); zval const_BLOCK_CODE_MIAO_value; ZVAL_LONG(&const_BLOCK_CODE_MIAO_value, UBLOCK_MIAO); - zend_string *const_BLOCK_CODE_MIAO_name = zend_string_init_interned("BLOCK_CODE_MIAO", sizeof("BLOCK_CODE_MIAO") - 1, 1); + zend_string *const_BLOCK_CODE_MIAO_name = zend_string_init_interned("BLOCK_CODE_MIAO", sizeof("BLOCK_CODE_MIAO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MIAO_name, &const_BLOCK_CODE_MIAO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MIAO_name); + zend_string_release_ex(const_BLOCK_CODE_MIAO_name, true); zval const_BLOCK_CODE_SHARADA_value; ZVAL_LONG(&const_BLOCK_CODE_SHARADA_value, UBLOCK_SHARADA); - zend_string *const_BLOCK_CODE_SHARADA_name = zend_string_init_interned("BLOCK_CODE_SHARADA", sizeof("BLOCK_CODE_SHARADA") - 1, 1); + zend_string *const_BLOCK_CODE_SHARADA_name = zend_string_init_interned("BLOCK_CODE_SHARADA", sizeof("BLOCK_CODE_SHARADA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SHARADA_name, &const_BLOCK_CODE_SHARADA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SHARADA_name); + zend_string_release_ex(const_BLOCK_CODE_SHARADA_name, true); zval const_BLOCK_CODE_SORA_SOMPENG_value; ZVAL_LONG(&const_BLOCK_CODE_SORA_SOMPENG_value, UBLOCK_SORA_SOMPENG); - zend_string *const_BLOCK_CODE_SORA_SOMPENG_name = zend_string_init_interned("BLOCK_CODE_SORA_SOMPENG", sizeof("BLOCK_CODE_SORA_SOMPENG") - 1, 1); + zend_string *const_BLOCK_CODE_SORA_SOMPENG_name = zend_string_init_interned("BLOCK_CODE_SORA_SOMPENG", sizeof("BLOCK_CODE_SORA_SOMPENG") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SORA_SOMPENG_name, &const_BLOCK_CODE_SORA_SOMPENG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SORA_SOMPENG_name); + zend_string_release_ex(const_BLOCK_CODE_SORA_SOMPENG_name, true); zval const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_value; ZVAL_LONG(&const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_value, UBLOCK_SUNDANESE_SUPPLEMENT); - zend_string *const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_SUNDANESE_SUPPLEMENT", sizeof("BLOCK_CODE_SUNDANESE_SUPPLEMENT") - 1, 1); + zend_string *const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_name = zend_string_init_interned("BLOCK_CODE_SUNDANESE_SUPPLEMENT", sizeof("BLOCK_CODE_SUNDANESE_SUPPLEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_name, &const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_name); + zend_string_release_ex(const_BLOCK_CODE_SUNDANESE_SUPPLEMENT_name, true); zval const_BLOCK_CODE_TAKRI_value; ZVAL_LONG(&const_BLOCK_CODE_TAKRI_value, UBLOCK_TAKRI); - zend_string *const_BLOCK_CODE_TAKRI_name = zend_string_init_interned("BLOCK_CODE_TAKRI", sizeof("BLOCK_CODE_TAKRI") - 1, 1); + zend_string *const_BLOCK_CODE_TAKRI_name = zend_string_init_interned("BLOCK_CODE_TAKRI", sizeof("BLOCK_CODE_TAKRI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TAKRI_name, &const_BLOCK_CODE_TAKRI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TAKRI_name); + zend_string_release_ex(const_BLOCK_CODE_TAKRI_name, true); zval const_BLOCK_CODE_BASSA_VAH_value; ZVAL_LONG(&const_BLOCK_CODE_BASSA_VAH_value, UBLOCK_BASSA_VAH); - zend_string *const_BLOCK_CODE_BASSA_VAH_name = zend_string_init_interned("BLOCK_CODE_BASSA_VAH", sizeof("BLOCK_CODE_BASSA_VAH") - 1, 1); + zend_string *const_BLOCK_CODE_BASSA_VAH_name = zend_string_init_interned("BLOCK_CODE_BASSA_VAH", sizeof("BLOCK_CODE_BASSA_VAH") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_BASSA_VAH_name, &const_BLOCK_CODE_BASSA_VAH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_BASSA_VAH_name); + zend_string_release_ex(const_BLOCK_CODE_BASSA_VAH_name, true); zval const_BLOCK_CODE_CAUCASIAN_ALBANIAN_value; ZVAL_LONG(&const_BLOCK_CODE_CAUCASIAN_ALBANIAN_value, UBLOCK_CAUCASIAN_ALBANIAN); - zend_string *const_BLOCK_CODE_CAUCASIAN_ALBANIAN_name = zend_string_init_interned("BLOCK_CODE_CAUCASIAN_ALBANIAN", sizeof("BLOCK_CODE_CAUCASIAN_ALBANIAN") - 1, 1); + zend_string *const_BLOCK_CODE_CAUCASIAN_ALBANIAN_name = zend_string_init_interned("BLOCK_CODE_CAUCASIAN_ALBANIAN", sizeof("BLOCK_CODE_CAUCASIAN_ALBANIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_CAUCASIAN_ALBANIAN_name, &const_BLOCK_CODE_CAUCASIAN_ALBANIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_CAUCASIAN_ALBANIAN_name); + zend_string_release_ex(const_BLOCK_CODE_CAUCASIAN_ALBANIAN_name, true); zval const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_value; ZVAL_LONG(&const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_value, UBLOCK_COPTIC_EPACT_NUMBERS); - zend_string *const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_COPTIC_EPACT_NUMBERS", sizeof("BLOCK_CODE_COPTIC_EPACT_NUMBERS") - 1, 1); + zend_string *const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_COPTIC_EPACT_NUMBERS", sizeof("BLOCK_CODE_COPTIC_EPACT_NUMBERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_name, &const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_name); + zend_string_release_ex(const_BLOCK_CODE_COPTIC_EPACT_NUMBERS_name, true); zval const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_value; ZVAL_LONG(&const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_value, UBLOCK_COMBINING_DIACRITICAL_MARKS_EXTENDED); - zend_string *const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED", sizeof("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED") - 1, 1); + zend_string *const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED", sizeof("BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_name, &const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_name); + zend_string_release_ex(const_BLOCK_CODE_COMBINING_DIACRITICAL_MARKS_EXTENDED_name, true); zval const_BLOCK_CODE_DUPLOYAN_value; ZVAL_LONG(&const_BLOCK_CODE_DUPLOYAN_value, UBLOCK_DUPLOYAN); - zend_string *const_BLOCK_CODE_DUPLOYAN_name = zend_string_init_interned("BLOCK_CODE_DUPLOYAN", sizeof("BLOCK_CODE_DUPLOYAN") - 1, 1); + zend_string *const_BLOCK_CODE_DUPLOYAN_name = zend_string_init_interned("BLOCK_CODE_DUPLOYAN", sizeof("BLOCK_CODE_DUPLOYAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_DUPLOYAN_name, &const_BLOCK_CODE_DUPLOYAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_DUPLOYAN_name); + zend_string_release_ex(const_BLOCK_CODE_DUPLOYAN_name, true); zval const_BLOCK_CODE_ELBASAN_value; ZVAL_LONG(&const_BLOCK_CODE_ELBASAN_value, UBLOCK_ELBASAN); - zend_string *const_BLOCK_CODE_ELBASAN_name = zend_string_init_interned("BLOCK_CODE_ELBASAN", sizeof("BLOCK_CODE_ELBASAN") - 1, 1); + zend_string *const_BLOCK_CODE_ELBASAN_name = zend_string_init_interned("BLOCK_CODE_ELBASAN", sizeof("BLOCK_CODE_ELBASAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ELBASAN_name, &const_BLOCK_CODE_ELBASAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ELBASAN_name); + zend_string_release_ex(const_BLOCK_CODE_ELBASAN_name, true); zval const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_value; ZVAL_LONG(&const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_value, UBLOCK_GEOMETRIC_SHAPES_EXTENDED); - zend_string *const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED", sizeof("BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED") - 1, 1); + zend_string *const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_name = zend_string_init_interned("BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED", sizeof("BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_name, &const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_name); + zend_string_release_ex(const_BLOCK_CODE_GEOMETRIC_SHAPES_EXTENDED_name, true); zval const_BLOCK_CODE_GRANTHA_value; ZVAL_LONG(&const_BLOCK_CODE_GRANTHA_value, UBLOCK_GRANTHA); - zend_string *const_BLOCK_CODE_GRANTHA_name = zend_string_init_interned("BLOCK_CODE_GRANTHA", sizeof("BLOCK_CODE_GRANTHA") - 1, 1); + zend_string *const_BLOCK_CODE_GRANTHA_name = zend_string_init_interned("BLOCK_CODE_GRANTHA", sizeof("BLOCK_CODE_GRANTHA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_GRANTHA_name, &const_BLOCK_CODE_GRANTHA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_GRANTHA_name); + zend_string_release_ex(const_BLOCK_CODE_GRANTHA_name, true); zval const_BLOCK_CODE_KHOJKI_value; ZVAL_LONG(&const_BLOCK_CODE_KHOJKI_value, UBLOCK_KHOJKI); - zend_string *const_BLOCK_CODE_KHOJKI_name = zend_string_init_interned("BLOCK_CODE_KHOJKI", sizeof("BLOCK_CODE_KHOJKI") - 1, 1); + zend_string *const_BLOCK_CODE_KHOJKI_name = zend_string_init_interned("BLOCK_CODE_KHOJKI", sizeof("BLOCK_CODE_KHOJKI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KHOJKI_name, &const_BLOCK_CODE_KHOJKI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KHOJKI_name); + zend_string_release_ex(const_BLOCK_CODE_KHOJKI_name, true); zval const_BLOCK_CODE_KHUDAWADI_value; ZVAL_LONG(&const_BLOCK_CODE_KHUDAWADI_value, UBLOCK_KHUDAWADI); - zend_string *const_BLOCK_CODE_KHUDAWADI_name = zend_string_init_interned("BLOCK_CODE_KHUDAWADI", sizeof("BLOCK_CODE_KHUDAWADI") - 1, 1); + zend_string *const_BLOCK_CODE_KHUDAWADI_name = zend_string_init_interned("BLOCK_CODE_KHUDAWADI", sizeof("BLOCK_CODE_KHUDAWADI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_KHUDAWADI_name, &const_BLOCK_CODE_KHUDAWADI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_KHUDAWADI_name); + zend_string_release_ex(const_BLOCK_CODE_KHUDAWADI_name, true); zval const_BLOCK_CODE_LATIN_EXTENDED_E_value; ZVAL_LONG(&const_BLOCK_CODE_LATIN_EXTENDED_E_value, UBLOCK_LATIN_EXTENDED_E); - zend_string *const_BLOCK_CODE_LATIN_EXTENDED_E_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_E", sizeof("BLOCK_CODE_LATIN_EXTENDED_E") - 1, 1); + zend_string *const_BLOCK_CODE_LATIN_EXTENDED_E_name = zend_string_init_interned("BLOCK_CODE_LATIN_EXTENDED_E", sizeof("BLOCK_CODE_LATIN_EXTENDED_E") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LATIN_EXTENDED_E_name, &const_BLOCK_CODE_LATIN_EXTENDED_E_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LATIN_EXTENDED_E_name); + zend_string_release_ex(const_BLOCK_CODE_LATIN_EXTENDED_E_name, true); zval const_BLOCK_CODE_LINEAR_A_value; ZVAL_LONG(&const_BLOCK_CODE_LINEAR_A_value, UBLOCK_LINEAR_A); - zend_string *const_BLOCK_CODE_LINEAR_A_name = zend_string_init_interned("BLOCK_CODE_LINEAR_A", sizeof("BLOCK_CODE_LINEAR_A") - 1, 1); + zend_string *const_BLOCK_CODE_LINEAR_A_name = zend_string_init_interned("BLOCK_CODE_LINEAR_A", sizeof("BLOCK_CODE_LINEAR_A") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_LINEAR_A_name, &const_BLOCK_CODE_LINEAR_A_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_LINEAR_A_name); + zend_string_release_ex(const_BLOCK_CODE_LINEAR_A_name, true); zval const_BLOCK_CODE_MAHAJANI_value; ZVAL_LONG(&const_BLOCK_CODE_MAHAJANI_value, UBLOCK_MAHAJANI); - zend_string *const_BLOCK_CODE_MAHAJANI_name = zend_string_init_interned("BLOCK_CODE_MAHAJANI", sizeof("BLOCK_CODE_MAHAJANI") - 1, 1); + zend_string *const_BLOCK_CODE_MAHAJANI_name = zend_string_init_interned("BLOCK_CODE_MAHAJANI", sizeof("BLOCK_CODE_MAHAJANI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MAHAJANI_name, &const_BLOCK_CODE_MAHAJANI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MAHAJANI_name); + zend_string_release_ex(const_BLOCK_CODE_MAHAJANI_name, true); zval const_BLOCK_CODE_MANICHAEAN_value; ZVAL_LONG(&const_BLOCK_CODE_MANICHAEAN_value, UBLOCK_MANICHAEAN); - zend_string *const_BLOCK_CODE_MANICHAEAN_name = zend_string_init_interned("BLOCK_CODE_MANICHAEAN", sizeof("BLOCK_CODE_MANICHAEAN") - 1, 1); + zend_string *const_BLOCK_CODE_MANICHAEAN_name = zend_string_init_interned("BLOCK_CODE_MANICHAEAN", sizeof("BLOCK_CODE_MANICHAEAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MANICHAEAN_name, &const_BLOCK_CODE_MANICHAEAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MANICHAEAN_name); + zend_string_release_ex(const_BLOCK_CODE_MANICHAEAN_name, true); zval const_BLOCK_CODE_MENDE_KIKAKUI_value; ZVAL_LONG(&const_BLOCK_CODE_MENDE_KIKAKUI_value, UBLOCK_MENDE_KIKAKUI); - zend_string *const_BLOCK_CODE_MENDE_KIKAKUI_name = zend_string_init_interned("BLOCK_CODE_MENDE_KIKAKUI", sizeof("BLOCK_CODE_MENDE_KIKAKUI") - 1, 1); + zend_string *const_BLOCK_CODE_MENDE_KIKAKUI_name = zend_string_init_interned("BLOCK_CODE_MENDE_KIKAKUI", sizeof("BLOCK_CODE_MENDE_KIKAKUI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MENDE_KIKAKUI_name, &const_BLOCK_CODE_MENDE_KIKAKUI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MENDE_KIKAKUI_name); + zend_string_release_ex(const_BLOCK_CODE_MENDE_KIKAKUI_name, true); zval const_BLOCK_CODE_MODI_value; ZVAL_LONG(&const_BLOCK_CODE_MODI_value, UBLOCK_MODI); - zend_string *const_BLOCK_CODE_MODI_name = zend_string_init_interned("BLOCK_CODE_MODI", sizeof("BLOCK_CODE_MODI") - 1, 1); + zend_string *const_BLOCK_CODE_MODI_name = zend_string_init_interned("BLOCK_CODE_MODI", sizeof("BLOCK_CODE_MODI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MODI_name, &const_BLOCK_CODE_MODI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MODI_name); + zend_string_release_ex(const_BLOCK_CODE_MODI_name, true); zval const_BLOCK_CODE_MRO_value; ZVAL_LONG(&const_BLOCK_CODE_MRO_value, UBLOCK_MRO); - zend_string *const_BLOCK_CODE_MRO_name = zend_string_init_interned("BLOCK_CODE_MRO", sizeof("BLOCK_CODE_MRO") - 1, 1); + zend_string *const_BLOCK_CODE_MRO_name = zend_string_init_interned("BLOCK_CODE_MRO", sizeof("BLOCK_CODE_MRO") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MRO_name, &const_BLOCK_CODE_MRO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MRO_name); + zend_string_release_ex(const_BLOCK_CODE_MRO_name, true); zval const_BLOCK_CODE_MYANMAR_EXTENDED_B_value; ZVAL_LONG(&const_BLOCK_CODE_MYANMAR_EXTENDED_B_value, UBLOCK_MYANMAR_EXTENDED_B); - zend_string *const_BLOCK_CODE_MYANMAR_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_MYANMAR_EXTENDED_B", sizeof("BLOCK_CODE_MYANMAR_EXTENDED_B") - 1, 1); + zend_string *const_BLOCK_CODE_MYANMAR_EXTENDED_B_name = zend_string_init_interned("BLOCK_CODE_MYANMAR_EXTENDED_B", sizeof("BLOCK_CODE_MYANMAR_EXTENDED_B") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_MYANMAR_EXTENDED_B_name, &const_BLOCK_CODE_MYANMAR_EXTENDED_B_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_MYANMAR_EXTENDED_B_name); + zend_string_release_ex(const_BLOCK_CODE_MYANMAR_EXTENDED_B_name, true); zval const_BLOCK_CODE_NABATAEAN_value; ZVAL_LONG(&const_BLOCK_CODE_NABATAEAN_value, UBLOCK_NABATAEAN); - zend_string *const_BLOCK_CODE_NABATAEAN_name = zend_string_init_interned("BLOCK_CODE_NABATAEAN", sizeof("BLOCK_CODE_NABATAEAN") - 1, 1); + zend_string *const_BLOCK_CODE_NABATAEAN_name = zend_string_init_interned("BLOCK_CODE_NABATAEAN", sizeof("BLOCK_CODE_NABATAEAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_NABATAEAN_name, &const_BLOCK_CODE_NABATAEAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_NABATAEAN_name); + zend_string_release_ex(const_BLOCK_CODE_NABATAEAN_name, true); zval const_BLOCK_CODE_OLD_NORTH_ARABIAN_value; ZVAL_LONG(&const_BLOCK_CODE_OLD_NORTH_ARABIAN_value, UBLOCK_OLD_NORTH_ARABIAN); - zend_string *const_BLOCK_CODE_OLD_NORTH_ARABIAN_name = zend_string_init_interned("BLOCK_CODE_OLD_NORTH_ARABIAN", sizeof("BLOCK_CODE_OLD_NORTH_ARABIAN") - 1, 1); + zend_string *const_BLOCK_CODE_OLD_NORTH_ARABIAN_name = zend_string_init_interned("BLOCK_CODE_OLD_NORTH_ARABIAN", sizeof("BLOCK_CODE_OLD_NORTH_ARABIAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OLD_NORTH_ARABIAN_name, &const_BLOCK_CODE_OLD_NORTH_ARABIAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OLD_NORTH_ARABIAN_name); + zend_string_release_ex(const_BLOCK_CODE_OLD_NORTH_ARABIAN_name, true); zval const_BLOCK_CODE_OLD_PERMIC_value; ZVAL_LONG(&const_BLOCK_CODE_OLD_PERMIC_value, UBLOCK_OLD_PERMIC); - zend_string *const_BLOCK_CODE_OLD_PERMIC_name = zend_string_init_interned("BLOCK_CODE_OLD_PERMIC", sizeof("BLOCK_CODE_OLD_PERMIC") - 1, 1); + zend_string *const_BLOCK_CODE_OLD_PERMIC_name = zend_string_init_interned("BLOCK_CODE_OLD_PERMIC", sizeof("BLOCK_CODE_OLD_PERMIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_OLD_PERMIC_name, &const_BLOCK_CODE_OLD_PERMIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_OLD_PERMIC_name); + zend_string_release_ex(const_BLOCK_CODE_OLD_PERMIC_name, true); zval const_BLOCK_CODE_ORNAMENTAL_DINGBATS_value; ZVAL_LONG(&const_BLOCK_CODE_ORNAMENTAL_DINGBATS_value, UBLOCK_ORNAMENTAL_DINGBATS); - zend_string *const_BLOCK_CODE_ORNAMENTAL_DINGBATS_name = zend_string_init_interned("BLOCK_CODE_ORNAMENTAL_DINGBATS", sizeof("BLOCK_CODE_ORNAMENTAL_DINGBATS") - 1, 1); + zend_string *const_BLOCK_CODE_ORNAMENTAL_DINGBATS_name = zend_string_init_interned("BLOCK_CODE_ORNAMENTAL_DINGBATS", sizeof("BLOCK_CODE_ORNAMENTAL_DINGBATS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_ORNAMENTAL_DINGBATS_name, &const_BLOCK_CODE_ORNAMENTAL_DINGBATS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_ORNAMENTAL_DINGBATS_name); + zend_string_release_ex(const_BLOCK_CODE_ORNAMENTAL_DINGBATS_name, true); zval const_BLOCK_CODE_PAHAWH_HMONG_value; ZVAL_LONG(&const_BLOCK_CODE_PAHAWH_HMONG_value, UBLOCK_PAHAWH_HMONG); - zend_string *const_BLOCK_CODE_PAHAWH_HMONG_name = zend_string_init_interned("BLOCK_CODE_PAHAWH_HMONG", sizeof("BLOCK_CODE_PAHAWH_HMONG") - 1, 1); + zend_string *const_BLOCK_CODE_PAHAWH_HMONG_name = zend_string_init_interned("BLOCK_CODE_PAHAWH_HMONG", sizeof("BLOCK_CODE_PAHAWH_HMONG") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PAHAWH_HMONG_name, &const_BLOCK_CODE_PAHAWH_HMONG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PAHAWH_HMONG_name); + zend_string_release_ex(const_BLOCK_CODE_PAHAWH_HMONG_name, true); zval const_BLOCK_CODE_PALMYRENE_value; ZVAL_LONG(&const_BLOCK_CODE_PALMYRENE_value, UBLOCK_PALMYRENE); - zend_string *const_BLOCK_CODE_PALMYRENE_name = zend_string_init_interned("BLOCK_CODE_PALMYRENE", sizeof("BLOCK_CODE_PALMYRENE") - 1, 1); + zend_string *const_BLOCK_CODE_PALMYRENE_name = zend_string_init_interned("BLOCK_CODE_PALMYRENE", sizeof("BLOCK_CODE_PALMYRENE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PALMYRENE_name, &const_BLOCK_CODE_PALMYRENE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PALMYRENE_name); + zend_string_release_ex(const_BLOCK_CODE_PALMYRENE_name, true); zval const_BLOCK_CODE_PAU_CIN_HAU_value; ZVAL_LONG(&const_BLOCK_CODE_PAU_CIN_HAU_value, UBLOCK_PAU_CIN_HAU); - zend_string *const_BLOCK_CODE_PAU_CIN_HAU_name = zend_string_init_interned("BLOCK_CODE_PAU_CIN_HAU", sizeof("BLOCK_CODE_PAU_CIN_HAU") - 1, 1); + zend_string *const_BLOCK_CODE_PAU_CIN_HAU_name = zend_string_init_interned("BLOCK_CODE_PAU_CIN_HAU", sizeof("BLOCK_CODE_PAU_CIN_HAU") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PAU_CIN_HAU_name, &const_BLOCK_CODE_PAU_CIN_HAU_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PAU_CIN_HAU_name); + zend_string_release_ex(const_BLOCK_CODE_PAU_CIN_HAU_name, true); zval const_BLOCK_CODE_PSALTER_PAHLAVI_value; ZVAL_LONG(&const_BLOCK_CODE_PSALTER_PAHLAVI_value, UBLOCK_PSALTER_PAHLAVI); - zend_string *const_BLOCK_CODE_PSALTER_PAHLAVI_name = zend_string_init_interned("BLOCK_CODE_PSALTER_PAHLAVI", sizeof("BLOCK_CODE_PSALTER_PAHLAVI") - 1, 1); + zend_string *const_BLOCK_CODE_PSALTER_PAHLAVI_name = zend_string_init_interned("BLOCK_CODE_PSALTER_PAHLAVI", sizeof("BLOCK_CODE_PSALTER_PAHLAVI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_PSALTER_PAHLAVI_name, &const_BLOCK_CODE_PSALTER_PAHLAVI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_PSALTER_PAHLAVI_name); + zend_string_release_ex(const_BLOCK_CODE_PSALTER_PAHLAVI_name, true); zval const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_value; ZVAL_LONG(&const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_value, UBLOCK_SHORTHAND_FORMAT_CONTROLS); - zend_string *const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_name = zend_string_init_interned("BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS", sizeof("BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS") - 1, 1); + zend_string *const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_name = zend_string_init_interned("BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS", sizeof("BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_name, &const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_name); + zend_string_release_ex(const_BLOCK_CODE_SHORTHAND_FORMAT_CONTROLS_name, true); zval const_BLOCK_CODE_SIDDHAM_value; ZVAL_LONG(&const_BLOCK_CODE_SIDDHAM_value, UBLOCK_SIDDHAM); - zend_string *const_BLOCK_CODE_SIDDHAM_name = zend_string_init_interned("BLOCK_CODE_SIDDHAM", sizeof("BLOCK_CODE_SIDDHAM") - 1, 1); + zend_string *const_BLOCK_CODE_SIDDHAM_name = zend_string_init_interned("BLOCK_CODE_SIDDHAM", sizeof("BLOCK_CODE_SIDDHAM") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SIDDHAM_name, &const_BLOCK_CODE_SIDDHAM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SIDDHAM_name); + zend_string_release_ex(const_BLOCK_CODE_SIDDHAM_name, true); zval const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_value; ZVAL_LONG(&const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_value, UBLOCK_SINHALA_ARCHAIC_NUMBERS); - zend_string *const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS", sizeof("BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS") - 1, 1); + zend_string *const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_name = zend_string_init_interned("BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS", sizeof("BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_name, &const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_name); + zend_string_release_ex(const_BLOCK_CODE_SINHALA_ARCHAIC_NUMBERS_name, true); zval const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_value; ZVAL_LONG(&const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_value, UBLOCK_SUPPLEMENTAL_ARROWS_C); - zend_string *const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_ARROWS_C", sizeof("BLOCK_CODE_SUPPLEMENTAL_ARROWS_C") - 1, 1); + zend_string *const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_name = zend_string_init_interned("BLOCK_CODE_SUPPLEMENTAL_ARROWS_C", sizeof("BLOCK_CODE_SUPPLEMENTAL_ARROWS_C") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_name, &const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_name); + zend_string_release_ex(const_BLOCK_CODE_SUPPLEMENTAL_ARROWS_C_name, true); zval const_BLOCK_CODE_TIRHUTA_value; ZVAL_LONG(&const_BLOCK_CODE_TIRHUTA_value, UBLOCK_TIRHUTA); - zend_string *const_BLOCK_CODE_TIRHUTA_name = zend_string_init_interned("BLOCK_CODE_TIRHUTA", sizeof("BLOCK_CODE_TIRHUTA") - 1, 1); + zend_string *const_BLOCK_CODE_TIRHUTA_name = zend_string_init_interned("BLOCK_CODE_TIRHUTA", sizeof("BLOCK_CODE_TIRHUTA") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_TIRHUTA_name, &const_BLOCK_CODE_TIRHUTA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_TIRHUTA_name); + zend_string_release_ex(const_BLOCK_CODE_TIRHUTA_name, true); zval const_BLOCK_CODE_WARANG_CITI_value; ZVAL_LONG(&const_BLOCK_CODE_WARANG_CITI_value, UBLOCK_WARANG_CITI); - zend_string *const_BLOCK_CODE_WARANG_CITI_name = zend_string_init_interned("BLOCK_CODE_WARANG_CITI", sizeof("BLOCK_CODE_WARANG_CITI") - 1, 1); + zend_string *const_BLOCK_CODE_WARANG_CITI_name = zend_string_init_interned("BLOCK_CODE_WARANG_CITI", sizeof("BLOCK_CODE_WARANG_CITI") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_WARANG_CITI_name, &const_BLOCK_CODE_WARANG_CITI_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_WARANG_CITI_name); + zend_string_release_ex(const_BLOCK_CODE_WARANG_CITI_name, true); zval const_BLOCK_CODE_COUNT_value; ZVAL_LONG(&const_BLOCK_CODE_COUNT_value, UBLOCK_COUNT); - zend_string *const_BLOCK_CODE_COUNT_name = zend_string_init_interned("BLOCK_CODE_COUNT", sizeof("BLOCK_CODE_COUNT") - 1, 1); + zend_string *const_BLOCK_CODE_COUNT_name = zend_string_init_interned("BLOCK_CODE_COUNT", sizeof("BLOCK_CODE_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_COUNT_name, &const_BLOCK_CODE_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_COUNT_name); + zend_string_release_ex(const_BLOCK_CODE_COUNT_name, true); zval const_BLOCK_CODE_INVALID_CODE_value; ZVAL_LONG(&const_BLOCK_CODE_INVALID_CODE_value, UBLOCK_INVALID_CODE); - zend_string *const_BLOCK_CODE_INVALID_CODE_name = zend_string_init_interned("BLOCK_CODE_INVALID_CODE", sizeof("BLOCK_CODE_INVALID_CODE") - 1, 1); + zend_string *const_BLOCK_CODE_INVALID_CODE_name = zend_string_init_interned("BLOCK_CODE_INVALID_CODE", sizeof("BLOCK_CODE_INVALID_CODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BLOCK_CODE_INVALID_CODE_name, &const_BLOCK_CODE_INVALID_CODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BLOCK_CODE_INVALID_CODE_name); + zend_string_release_ex(const_BLOCK_CODE_INVALID_CODE_name, true); zval const_BPT_NONE_value; ZVAL_LONG(&const_BPT_NONE_value, U_BPT_NONE); - zend_string *const_BPT_NONE_name = zend_string_init_interned("BPT_NONE", sizeof("BPT_NONE") - 1, 1); + zend_string *const_BPT_NONE_name = zend_string_init_interned("BPT_NONE", sizeof("BPT_NONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BPT_NONE_name, &const_BPT_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BPT_NONE_name); + zend_string_release_ex(const_BPT_NONE_name, true); zval const_BPT_OPEN_value; ZVAL_LONG(&const_BPT_OPEN_value, U_BPT_OPEN); - zend_string *const_BPT_OPEN_name = zend_string_init_interned("BPT_OPEN", sizeof("BPT_OPEN") - 1, 1); + zend_string *const_BPT_OPEN_name = zend_string_init_interned("BPT_OPEN", sizeof("BPT_OPEN") - 1, true); zend_declare_typed_class_constant(class_entry, const_BPT_OPEN_name, &const_BPT_OPEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BPT_OPEN_name); + zend_string_release_ex(const_BPT_OPEN_name, true); zval const_BPT_CLOSE_value; ZVAL_LONG(&const_BPT_CLOSE_value, U_BPT_CLOSE); - zend_string *const_BPT_CLOSE_name = zend_string_init_interned("BPT_CLOSE", sizeof("BPT_CLOSE") - 1, 1); + zend_string *const_BPT_CLOSE_name = zend_string_init_interned("BPT_CLOSE", sizeof("BPT_CLOSE") - 1, true); zend_declare_typed_class_constant(class_entry, const_BPT_CLOSE_name, &const_BPT_CLOSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BPT_CLOSE_name); + zend_string_release_ex(const_BPT_CLOSE_name, true); zval const_BPT_COUNT_value; ZVAL_LONG(&const_BPT_COUNT_value, U_BPT_COUNT); - zend_string *const_BPT_COUNT_name = zend_string_init_interned("BPT_COUNT", sizeof("BPT_COUNT") - 1, 1); + zend_string *const_BPT_COUNT_name = zend_string_init_interned("BPT_COUNT", sizeof("BPT_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BPT_COUNT_name, &const_BPT_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BPT_COUNT_name); + zend_string_release_ex(const_BPT_COUNT_name, true); zval const_EA_NEUTRAL_value; ZVAL_LONG(&const_EA_NEUTRAL_value, U_EA_NEUTRAL); - zend_string *const_EA_NEUTRAL_name = zend_string_init_interned("EA_NEUTRAL", sizeof("EA_NEUTRAL") - 1, 1); + zend_string *const_EA_NEUTRAL_name = zend_string_init_interned("EA_NEUTRAL", sizeof("EA_NEUTRAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_EA_NEUTRAL_name, &const_EA_NEUTRAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EA_NEUTRAL_name); + zend_string_release_ex(const_EA_NEUTRAL_name, true); zval const_EA_AMBIGUOUS_value; ZVAL_LONG(&const_EA_AMBIGUOUS_value, U_EA_AMBIGUOUS); - zend_string *const_EA_AMBIGUOUS_name = zend_string_init_interned("EA_AMBIGUOUS", sizeof("EA_AMBIGUOUS") - 1, 1); + zend_string *const_EA_AMBIGUOUS_name = zend_string_init_interned("EA_AMBIGUOUS", sizeof("EA_AMBIGUOUS") - 1, true); zend_declare_typed_class_constant(class_entry, const_EA_AMBIGUOUS_name, &const_EA_AMBIGUOUS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EA_AMBIGUOUS_name); + zend_string_release_ex(const_EA_AMBIGUOUS_name, true); zval const_EA_HALFWIDTH_value; ZVAL_LONG(&const_EA_HALFWIDTH_value, U_EA_HALFWIDTH); - zend_string *const_EA_HALFWIDTH_name = zend_string_init_interned("EA_HALFWIDTH", sizeof("EA_HALFWIDTH") - 1, 1); + zend_string *const_EA_HALFWIDTH_name = zend_string_init_interned("EA_HALFWIDTH", sizeof("EA_HALFWIDTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_EA_HALFWIDTH_name, &const_EA_HALFWIDTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EA_HALFWIDTH_name); + zend_string_release_ex(const_EA_HALFWIDTH_name, true); zval const_EA_FULLWIDTH_value; ZVAL_LONG(&const_EA_FULLWIDTH_value, U_EA_FULLWIDTH); - zend_string *const_EA_FULLWIDTH_name = zend_string_init_interned("EA_FULLWIDTH", sizeof("EA_FULLWIDTH") - 1, 1); + zend_string *const_EA_FULLWIDTH_name = zend_string_init_interned("EA_FULLWIDTH", sizeof("EA_FULLWIDTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_EA_FULLWIDTH_name, &const_EA_FULLWIDTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EA_FULLWIDTH_name); + zend_string_release_ex(const_EA_FULLWIDTH_name, true); zval const_EA_NARROW_value; ZVAL_LONG(&const_EA_NARROW_value, U_EA_NARROW); - zend_string *const_EA_NARROW_name = zend_string_init_interned("EA_NARROW", sizeof("EA_NARROW") - 1, 1); + zend_string *const_EA_NARROW_name = zend_string_init_interned("EA_NARROW", sizeof("EA_NARROW") - 1, true); zend_declare_typed_class_constant(class_entry, const_EA_NARROW_name, &const_EA_NARROW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EA_NARROW_name); + zend_string_release_ex(const_EA_NARROW_name, true); zval const_EA_WIDE_value; ZVAL_LONG(&const_EA_WIDE_value, U_EA_WIDE); - zend_string *const_EA_WIDE_name = zend_string_init_interned("EA_WIDE", sizeof("EA_WIDE") - 1, 1); + zend_string *const_EA_WIDE_name = zend_string_init_interned("EA_WIDE", sizeof("EA_WIDE") - 1, true); zend_declare_typed_class_constant(class_entry, const_EA_WIDE_name, &const_EA_WIDE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EA_WIDE_name); + zend_string_release_ex(const_EA_WIDE_name, true); zval const_EA_COUNT_value; ZVAL_LONG(&const_EA_COUNT_value, U_EA_COUNT); - zend_string *const_EA_COUNT_name = zend_string_init_interned("EA_COUNT", sizeof("EA_COUNT") - 1, 1); + zend_string *const_EA_COUNT_name = zend_string_init_interned("EA_COUNT", sizeof("EA_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_EA_COUNT_name, &const_EA_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EA_COUNT_name); + zend_string_release_ex(const_EA_COUNT_name, true); zval const_UNICODE_CHAR_NAME_value; ZVAL_LONG(&const_UNICODE_CHAR_NAME_value, U_UNICODE_CHAR_NAME); - zend_string *const_UNICODE_CHAR_NAME_name = zend_string_init_interned("UNICODE_CHAR_NAME", sizeof("UNICODE_CHAR_NAME") - 1, 1); + zend_string *const_UNICODE_CHAR_NAME_name = zend_string_init_interned("UNICODE_CHAR_NAME", sizeof("UNICODE_CHAR_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_UNICODE_CHAR_NAME_name, &const_UNICODE_CHAR_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UNICODE_CHAR_NAME_name); + zend_string_release_ex(const_UNICODE_CHAR_NAME_name, true); zval const_UNICODE_10_CHAR_NAME_value; ZVAL_LONG(&const_UNICODE_10_CHAR_NAME_value, U_UNICODE_10_CHAR_NAME); - zend_string *const_UNICODE_10_CHAR_NAME_name = zend_string_init_interned("UNICODE_10_CHAR_NAME", sizeof("UNICODE_10_CHAR_NAME") - 1, 1); + zend_string *const_UNICODE_10_CHAR_NAME_name = zend_string_init_interned("UNICODE_10_CHAR_NAME", sizeof("UNICODE_10_CHAR_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_UNICODE_10_CHAR_NAME_name, &const_UNICODE_10_CHAR_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UNICODE_10_CHAR_NAME_name); + zend_string_release_ex(const_UNICODE_10_CHAR_NAME_name, true); zval const_EXTENDED_CHAR_NAME_value; ZVAL_LONG(&const_EXTENDED_CHAR_NAME_value, U_EXTENDED_CHAR_NAME); - zend_string *const_EXTENDED_CHAR_NAME_name = zend_string_init_interned("EXTENDED_CHAR_NAME", sizeof("EXTENDED_CHAR_NAME") - 1, 1); + zend_string *const_EXTENDED_CHAR_NAME_name = zend_string_init_interned("EXTENDED_CHAR_NAME", sizeof("EXTENDED_CHAR_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXTENDED_CHAR_NAME_name, &const_EXTENDED_CHAR_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXTENDED_CHAR_NAME_name); + zend_string_release_ex(const_EXTENDED_CHAR_NAME_name, true); zval const_CHAR_NAME_ALIAS_value; ZVAL_LONG(&const_CHAR_NAME_ALIAS_value, U_CHAR_NAME_ALIAS); - zend_string *const_CHAR_NAME_ALIAS_name = zend_string_init_interned("CHAR_NAME_ALIAS", sizeof("CHAR_NAME_ALIAS") - 1, 1); + zend_string *const_CHAR_NAME_ALIAS_name = zend_string_init_interned("CHAR_NAME_ALIAS", sizeof("CHAR_NAME_ALIAS") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_NAME_ALIAS_name, &const_CHAR_NAME_ALIAS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_NAME_ALIAS_name); + zend_string_release_ex(const_CHAR_NAME_ALIAS_name, true); zval const_CHAR_NAME_CHOICE_COUNT_value; ZVAL_LONG(&const_CHAR_NAME_CHOICE_COUNT_value, U_CHAR_NAME_CHOICE_COUNT); - zend_string *const_CHAR_NAME_CHOICE_COUNT_name = zend_string_init_interned("CHAR_NAME_CHOICE_COUNT", sizeof("CHAR_NAME_CHOICE_COUNT") - 1, 1); + zend_string *const_CHAR_NAME_CHOICE_COUNT_name = zend_string_init_interned("CHAR_NAME_CHOICE_COUNT", sizeof("CHAR_NAME_CHOICE_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHAR_NAME_CHOICE_COUNT_name, &const_CHAR_NAME_CHOICE_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHAR_NAME_CHOICE_COUNT_name); + zend_string_release_ex(const_CHAR_NAME_CHOICE_COUNT_name, true); zval const_SHORT_PROPERTY_NAME_value; ZVAL_LONG(&const_SHORT_PROPERTY_NAME_value, U_SHORT_PROPERTY_NAME); - zend_string *const_SHORT_PROPERTY_NAME_name = zend_string_init_interned("SHORT_PROPERTY_NAME", sizeof("SHORT_PROPERTY_NAME") - 1, 1); + zend_string *const_SHORT_PROPERTY_NAME_name = zend_string_init_interned("SHORT_PROPERTY_NAME", sizeof("SHORT_PROPERTY_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_SHORT_PROPERTY_NAME_name, &const_SHORT_PROPERTY_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SHORT_PROPERTY_NAME_name); + zend_string_release_ex(const_SHORT_PROPERTY_NAME_name, true); zval const_LONG_PROPERTY_NAME_value; ZVAL_LONG(&const_LONG_PROPERTY_NAME_value, U_LONG_PROPERTY_NAME); - zend_string *const_LONG_PROPERTY_NAME_name = zend_string_init_interned("LONG_PROPERTY_NAME", sizeof("LONG_PROPERTY_NAME") - 1, 1); + zend_string *const_LONG_PROPERTY_NAME_name = zend_string_init_interned("LONG_PROPERTY_NAME", sizeof("LONG_PROPERTY_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_LONG_PROPERTY_NAME_name, &const_LONG_PROPERTY_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LONG_PROPERTY_NAME_name); + zend_string_release_ex(const_LONG_PROPERTY_NAME_name, true); zval const_PROPERTY_NAME_CHOICE_COUNT_value; ZVAL_LONG(&const_PROPERTY_NAME_CHOICE_COUNT_value, U_PROPERTY_NAME_CHOICE_COUNT); - zend_string *const_PROPERTY_NAME_CHOICE_COUNT_name = zend_string_init_interned("PROPERTY_NAME_CHOICE_COUNT", sizeof("PROPERTY_NAME_CHOICE_COUNT") - 1, 1); + zend_string *const_PROPERTY_NAME_CHOICE_COUNT_name = zend_string_init_interned("PROPERTY_NAME_CHOICE_COUNT", sizeof("PROPERTY_NAME_CHOICE_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PROPERTY_NAME_CHOICE_COUNT_name, &const_PROPERTY_NAME_CHOICE_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PROPERTY_NAME_CHOICE_COUNT_name); + zend_string_release_ex(const_PROPERTY_NAME_CHOICE_COUNT_name, true); zval const_DT_NONE_value; ZVAL_LONG(&const_DT_NONE_value, U_DT_NONE); - zend_string *const_DT_NONE_name = zend_string_init_interned("DT_NONE", sizeof("DT_NONE") - 1, 1); + zend_string *const_DT_NONE_name = zend_string_init_interned("DT_NONE", sizeof("DT_NONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_NONE_name, &const_DT_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_NONE_name); + zend_string_release_ex(const_DT_NONE_name, true); zval const_DT_CANONICAL_value; ZVAL_LONG(&const_DT_CANONICAL_value, U_DT_CANONICAL); - zend_string *const_DT_CANONICAL_name = zend_string_init_interned("DT_CANONICAL", sizeof("DT_CANONICAL") - 1, 1); + zend_string *const_DT_CANONICAL_name = zend_string_init_interned("DT_CANONICAL", sizeof("DT_CANONICAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_CANONICAL_name, &const_DT_CANONICAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_CANONICAL_name); + zend_string_release_ex(const_DT_CANONICAL_name, true); zval const_DT_COMPAT_value; ZVAL_LONG(&const_DT_COMPAT_value, U_DT_COMPAT); - zend_string *const_DT_COMPAT_name = zend_string_init_interned("DT_COMPAT", sizeof("DT_COMPAT") - 1, 1); + zend_string *const_DT_COMPAT_name = zend_string_init_interned("DT_COMPAT", sizeof("DT_COMPAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_COMPAT_name, &const_DT_COMPAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_COMPAT_name); + zend_string_release_ex(const_DT_COMPAT_name, true); zval const_DT_CIRCLE_value; ZVAL_LONG(&const_DT_CIRCLE_value, U_DT_CIRCLE); - zend_string *const_DT_CIRCLE_name = zend_string_init_interned("DT_CIRCLE", sizeof("DT_CIRCLE") - 1, 1); + zend_string *const_DT_CIRCLE_name = zend_string_init_interned("DT_CIRCLE", sizeof("DT_CIRCLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_CIRCLE_name, &const_DT_CIRCLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_CIRCLE_name); + zend_string_release_ex(const_DT_CIRCLE_name, true); zval const_DT_FINAL_value; ZVAL_LONG(&const_DT_FINAL_value, U_DT_FINAL); - zend_string *const_DT_FINAL_name = zend_string_init_interned("DT_FINAL", sizeof("DT_FINAL") - 1, 1); + zend_string *const_DT_FINAL_name = zend_string_init_interned("DT_FINAL", sizeof("DT_FINAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_FINAL_name, &const_DT_FINAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_FINAL_name); + zend_string_release_ex(const_DT_FINAL_name, true); zval const_DT_FONT_value; ZVAL_LONG(&const_DT_FONT_value, U_DT_FONT); - zend_string *const_DT_FONT_name = zend_string_init_interned("DT_FONT", sizeof("DT_FONT") - 1, 1); + zend_string *const_DT_FONT_name = zend_string_init_interned("DT_FONT", sizeof("DT_FONT") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_FONT_name, &const_DT_FONT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_FONT_name); + zend_string_release_ex(const_DT_FONT_name, true); zval const_DT_FRACTION_value; ZVAL_LONG(&const_DT_FRACTION_value, U_DT_FRACTION); - zend_string *const_DT_FRACTION_name = zend_string_init_interned("DT_FRACTION", sizeof("DT_FRACTION") - 1, 1); + zend_string *const_DT_FRACTION_name = zend_string_init_interned("DT_FRACTION", sizeof("DT_FRACTION") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_FRACTION_name, &const_DT_FRACTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_FRACTION_name); + zend_string_release_ex(const_DT_FRACTION_name, true); zval const_DT_INITIAL_value; ZVAL_LONG(&const_DT_INITIAL_value, U_DT_INITIAL); - zend_string *const_DT_INITIAL_name = zend_string_init_interned("DT_INITIAL", sizeof("DT_INITIAL") - 1, 1); + zend_string *const_DT_INITIAL_name = zend_string_init_interned("DT_INITIAL", sizeof("DT_INITIAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_INITIAL_name, &const_DT_INITIAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_INITIAL_name); + zend_string_release_ex(const_DT_INITIAL_name, true); zval const_DT_ISOLATED_value; ZVAL_LONG(&const_DT_ISOLATED_value, U_DT_ISOLATED); - zend_string *const_DT_ISOLATED_name = zend_string_init_interned("DT_ISOLATED", sizeof("DT_ISOLATED") - 1, 1); + zend_string *const_DT_ISOLATED_name = zend_string_init_interned("DT_ISOLATED", sizeof("DT_ISOLATED") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_ISOLATED_name, &const_DT_ISOLATED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_ISOLATED_name); + zend_string_release_ex(const_DT_ISOLATED_name, true); zval const_DT_MEDIAL_value; ZVAL_LONG(&const_DT_MEDIAL_value, U_DT_MEDIAL); - zend_string *const_DT_MEDIAL_name = zend_string_init_interned("DT_MEDIAL", sizeof("DT_MEDIAL") - 1, 1); + zend_string *const_DT_MEDIAL_name = zend_string_init_interned("DT_MEDIAL", sizeof("DT_MEDIAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_MEDIAL_name, &const_DT_MEDIAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_MEDIAL_name); + zend_string_release_ex(const_DT_MEDIAL_name, true); zval const_DT_NARROW_value; ZVAL_LONG(&const_DT_NARROW_value, U_DT_NARROW); - zend_string *const_DT_NARROW_name = zend_string_init_interned("DT_NARROW", sizeof("DT_NARROW") - 1, 1); + zend_string *const_DT_NARROW_name = zend_string_init_interned("DT_NARROW", sizeof("DT_NARROW") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_NARROW_name, &const_DT_NARROW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_NARROW_name); + zend_string_release_ex(const_DT_NARROW_name, true); zval const_DT_NOBREAK_value; ZVAL_LONG(&const_DT_NOBREAK_value, U_DT_NOBREAK); - zend_string *const_DT_NOBREAK_name = zend_string_init_interned("DT_NOBREAK", sizeof("DT_NOBREAK") - 1, 1); + zend_string *const_DT_NOBREAK_name = zend_string_init_interned("DT_NOBREAK", sizeof("DT_NOBREAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_NOBREAK_name, &const_DT_NOBREAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_NOBREAK_name); + zend_string_release_ex(const_DT_NOBREAK_name, true); zval const_DT_SMALL_value; ZVAL_LONG(&const_DT_SMALL_value, U_DT_SMALL); - zend_string *const_DT_SMALL_name = zend_string_init_interned("DT_SMALL", sizeof("DT_SMALL") - 1, 1); + zend_string *const_DT_SMALL_name = zend_string_init_interned("DT_SMALL", sizeof("DT_SMALL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_SMALL_name, &const_DT_SMALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_SMALL_name); + zend_string_release_ex(const_DT_SMALL_name, true); zval const_DT_SQUARE_value; ZVAL_LONG(&const_DT_SQUARE_value, U_DT_SQUARE); - zend_string *const_DT_SQUARE_name = zend_string_init_interned("DT_SQUARE", sizeof("DT_SQUARE") - 1, 1); + zend_string *const_DT_SQUARE_name = zend_string_init_interned("DT_SQUARE", sizeof("DT_SQUARE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_SQUARE_name, &const_DT_SQUARE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_SQUARE_name); + zend_string_release_ex(const_DT_SQUARE_name, true); zval const_DT_SUB_value; ZVAL_LONG(&const_DT_SUB_value, U_DT_SUB); - zend_string *const_DT_SUB_name = zend_string_init_interned("DT_SUB", sizeof("DT_SUB") - 1, 1); + zend_string *const_DT_SUB_name = zend_string_init_interned("DT_SUB", sizeof("DT_SUB") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_SUB_name, &const_DT_SUB_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_SUB_name); + zend_string_release_ex(const_DT_SUB_name, true); zval const_DT_SUPER_value; ZVAL_LONG(&const_DT_SUPER_value, U_DT_SUPER); - zend_string *const_DT_SUPER_name = zend_string_init_interned("DT_SUPER", sizeof("DT_SUPER") - 1, 1); + zend_string *const_DT_SUPER_name = zend_string_init_interned("DT_SUPER", sizeof("DT_SUPER") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_SUPER_name, &const_DT_SUPER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_SUPER_name); + zend_string_release_ex(const_DT_SUPER_name, true); zval const_DT_VERTICAL_value; ZVAL_LONG(&const_DT_VERTICAL_value, U_DT_VERTICAL); - zend_string *const_DT_VERTICAL_name = zend_string_init_interned("DT_VERTICAL", sizeof("DT_VERTICAL") - 1, 1); + zend_string *const_DT_VERTICAL_name = zend_string_init_interned("DT_VERTICAL", sizeof("DT_VERTICAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_VERTICAL_name, &const_DT_VERTICAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_VERTICAL_name); + zend_string_release_ex(const_DT_VERTICAL_name, true); zval const_DT_WIDE_value; ZVAL_LONG(&const_DT_WIDE_value, U_DT_WIDE); - zend_string *const_DT_WIDE_name = zend_string_init_interned("DT_WIDE", sizeof("DT_WIDE") - 1, 1); + zend_string *const_DT_WIDE_name = zend_string_init_interned("DT_WIDE", sizeof("DT_WIDE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_WIDE_name, &const_DT_WIDE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_WIDE_name); + zend_string_release_ex(const_DT_WIDE_name, true); zval const_DT_COUNT_value; ZVAL_LONG(&const_DT_COUNT_value, U_DT_COUNT); - zend_string *const_DT_COUNT_name = zend_string_init_interned("DT_COUNT", sizeof("DT_COUNT") - 1, 1); + zend_string *const_DT_COUNT_name = zend_string_init_interned("DT_COUNT", sizeof("DT_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_DT_COUNT_name, &const_DT_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DT_COUNT_name); + zend_string_release_ex(const_DT_COUNT_name, true); zval const_JT_NON_JOINING_value; ZVAL_LONG(&const_JT_NON_JOINING_value, U_JT_NON_JOINING); - zend_string *const_JT_NON_JOINING_name = zend_string_init_interned("JT_NON_JOINING", sizeof("JT_NON_JOINING") - 1, 1); + zend_string *const_JT_NON_JOINING_name = zend_string_init_interned("JT_NON_JOINING", sizeof("JT_NON_JOINING") - 1, true); zend_declare_typed_class_constant(class_entry, const_JT_NON_JOINING_name, &const_JT_NON_JOINING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JT_NON_JOINING_name); + zend_string_release_ex(const_JT_NON_JOINING_name, true); zval const_JT_JOIN_CAUSING_value; ZVAL_LONG(&const_JT_JOIN_CAUSING_value, U_JT_JOIN_CAUSING); - zend_string *const_JT_JOIN_CAUSING_name = zend_string_init_interned("JT_JOIN_CAUSING", sizeof("JT_JOIN_CAUSING") - 1, 1); + zend_string *const_JT_JOIN_CAUSING_name = zend_string_init_interned("JT_JOIN_CAUSING", sizeof("JT_JOIN_CAUSING") - 1, true); zend_declare_typed_class_constant(class_entry, const_JT_JOIN_CAUSING_name, &const_JT_JOIN_CAUSING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JT_JOIN_CAUSING_name); + zend_string_release_ex(const_JT_JOIN_CAUSING_name, true); zval const_JT_DUAL_JOINING_value; ZVAL_LONG(&const_JT_DUAL_JOINING_value, U_JT_DUAL_JOINING); - zend_string *const_JT_DUAL_JOINING_name = zend_string_init_interned("JT_DUAL_JOINING", sizeof("JT_DUAL_JOINING") - 1, 1); + zend_string *const_JT_DUAL_JOINING_name = zend_string_init_interned("JT_DUAL_JOINING", sizeof("JT_DUAL_JOINING") - 1, true); zend_declare_typed_class_constant(class_entry, const_JT_DUAL_JOINING_name, &const_JT_DUAL_JOINING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JT_DUAL_JOINING_name); + zend_string_release_ex(const_JT_DUAL_JOINING_name, true); zval const_JT_LEFT_JOINING_value; ZVAL_LONG(&const_JT_LEFT_JOINING_value, U_JT_LEFT_JOINING); - zend_string *const_JT_LEFT_JOINING_name = zend_string_init_interned("JT_LEFT_JOINING", sizeof("JT_LEFT_JOINING") - 1, 1); + zend_string *const_JT_LEFT_JOINING_name = zend_string_init_interned("JT_LEFT_JOINING", sizeof("JT_LEFT_JOINING") - 1, true); zend_declare_typed_class_constant(class_entry, const_JT_LEFT_JOINING_name, &const_JT_LEFT_JOINING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JT_LEFT_JOINING_name); + zend_string_release_ex(const_JT_LEFT_JOINING_name, true); zval const_JT_RIGHT_JOINING_value; ZVAL_LONG(&const_JT_RIGHT_JOINING_value, U_JT_RIGHT_JOINING); - zend_string *const_JT_RIGHT_JOINING_name = zend_string_init_interned("JT_RIGHT_JOINING", sizeof("JT_RIGHT_JOINING") - 1, 1); + zend_string *const_JT_RIGHT_JOINING_name = zend_string_init_interned("JT_RIGHT_JOINING", sizeof("JT_RIGHT_JOINING") - 1, true); zend_declare_typed_class_constant(class_entry, const_JT_RIGHT_JOINING_name, &const_JT_RIGHT_JOINING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JT_RIGHT_JOINING_name); + zend_string_release_ex(const_JT_RIGHT_JOINING_name, true); zval const_JT_TRANSPARENT_value; ZVAL_LONG(&const_JT_TRANSPARENT_value, U_JT_TRANSPARENT); - zend_string *const_JT_TRANSPARENT_name = zend_string_init_interned("JT_TRANSPARENT", sizeof("JT_TRANSPARENT") - 1, 1); + zend_string *const_JT_TRANSPARENT_name = zend_string_init_interned("JT_TRANSPARENT", sizeof("JT_TRANSPARENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_JT_TRANSPARENT_name, &const_JT_TRANSPARENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JT_TRANSPARENT_name); + zend_string_release_ex(const_JT_TRANSPARENT_name, true); zval const_JT_COUNT_value; ZVAL_LONG(&const_JT_COUNT_value, U_JT_COUNT); - zend_string *const_JT_COUNT_name = zend_string_init_interned("JT_COUNT", sizeof("JT_COUNT") - 1, 1); + zend_string *const_JT_COUNT_name = zend_string_init_interned("JT_COUNT", sizeof("JT_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_JT_COUNT_name, &const_JT_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JT_COUNT_name); + zend_string_release_ex(const_JT_COUNT_name, true); zval const_JG_NO_JOINING_GROUP_value; ZVAL_LONG(&const_JG_NO_JOINING_GROUP_value, U_JG_NO_JOINING_GROUP); - zend_string *const_JG_NO_JOINING_GROUP_name = zend_string_init_interned("JG_NO_JOINING_GROUP", sizeof("JG_NO_JOINING_GROUP") - 1, 1); + zend_string *const_JG_NO_JOINING_GROUP_name = zend_string_init_interned("JG_NO_JOINING_GROUP", sizeof("JG_NO_JOINING_GROUP") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_NO_JOINING_GROUP_name, &const_JG_NO_JOINING_GROUP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_NO_JOINING_GROUP_name); + zend_string_release_ex(const_JG_NO_JOINING_GROUP_name, true); zval const_JG_AIN_value; ZVAL_LONG(&const_JG_AIN_value, U_JG_AIN); - zend_string *const_JG_AIN_name = zend_string_init_interned("JG_AIN", sizeof("JG_AIN") - 1, 1); + zend_string *const_JG_AIN_name = zend_string_init_interned("JG_AIN", sizeof("JG_AIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_AIN_name, &const_JG_AIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_AIN_name); + zend_string_release_ex(const_JG_AIN_name, true); zval const_JG_ALAPH_value; ZVAL_LONG(&const_JG_ALAPH_value, U_JG_ALAPH); - zend_string *const_JG_ALAPH_name = zend_string_init_interned("JG_ALAPH", sizeof("JG_ALAPH") - 1, 1); + zend_string *const_JG_ALAPH_name = zend_string_init_interned("JG_ALAPH", sizeof("JG_ALAPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_ALAPH_name, &const_JG_ALAPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_ALAPH_name); + zend_string_release_ex(const_JG_ALAPH_name, true); zval const_JG_ALEF_value; ZVAL_LONG(&const_JG_ALEF_value, U_JG_ALEF); - zend_string *const_JG_ALEF_name = zend_string_init_interned("JG_ALEF", sizeof("JG_ALEF") - 1, 1); + zend_string *const_JG_ALEF_name = zend_string_init_interned("JG_ALEF", sizeof("JG_ALEF") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_ALEF_name, &const_JG_ALEF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_ALEF_name); + zend_string_release_ex(const_JG_ALEF_name, true); zval const_JG_BEH_value; ZVAL_LONG(&const_JG_BEH_value, U_JG_BEH); - zend_string *const_JG_BEH_name = zend_string_init_interned("JG_BEH", sizeof("JG_BEH") - 1, 1); + zend_string *const_JG_BEH_name = zend_string_init_interned("JG_BEH", sizeof("JG_BEH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_BEH_name, &const_JG_BEH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_BEH_name); + zend_string_release_ex(const_JG_BEH_name, true); zval const_JG_BETH_value; ZVAL_LONG(&const_JG_BETH_value, U_JG_BETH); - zend_string *const_JG_BETH_name = zend_string_init_interned("JG_BETH", sizeof("JG_BETH") - 1, 1); + zend_string *const_JG_BETH_name = zend_string_init_interned("JG_BETH", sizeof("JG_BETH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_BETH_name, &const_JG_BETH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_BETH_name); + zend_string_release_ex(const_JG_BETH_name, true); zval const_JG_DAL_value; ZVAL_LONG(&const_JG_DAL_value, U_JG_DAL); - zend_string *const_JG_DAL_name = zend_string_init_interned("JG_DAL", sizeof("JG_DAL") - 1, 1); + zend_string *const_JG_DAL_name = zend_string_init_interned("JG_DAL", sizeof("JG_DAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_DAL_name, &const_JG_DAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_DAL_name); + zend_string_release_ex(const_JG_DAL_name, true); zval const_JG_DALATH_RISH_value; ZVAL_LONG(&const_JG_DALATH_RISH_value, U_JG_DALATH_RISH); - zend_string *const_JG_DALATH_RISH_name = zend_string_init_interned("JG_DALATH_RISH", sizeof("JG_DALATH_RISH") - 1, 1); + zend_string *const_JG_DALATH_RISH_name = zend_string_init_interned("JG_DALATH_RISH", sizeof("JG_DALATH_RISH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_DALATH_RISH_name, &const_JG_DALATH_RISH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_DALATH_RISH_name); + zend_string_release_ex(const_JG_DALATH_RISH_name, true); zval const_JG_E_value; ZVAL_LONG(&const_JG_E_value, U_JG_E); - zend_string *const_JG_E_name = zend_string_init_interned("JG_E", sizeof("JG_E") - 1, 1); + zend_string *const_JG_E_name = zend_string_init_interned("JG_E", sizeof("JG_E") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_E_name, &const_JG_E_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_E_name); + zend_string_release_ex(const_JG_E_name, true); zval const_JG_FEH_value; ZVAL_LONG(&const_JG_FEH_value, U_JG_FEH); - zend_string *const_JG_FEH_name = zend_string_init_interned("JG_FEH", sizeof("JG_FEH") - 1, 1); + zend_string *const_JG_FEH_name = zend_string_init_interned("JG_FEH", sizeof("JG_FEH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_FEH_name, &const_JG_FEH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_FEH_name); + zend_string_release_ex(const_JG_FEH_name, true); zval const_JG_FINAL_SEMKATH_value; ZVAL_LONG(&const_JG_FINAL_SEMKATH_value, U_JG_FINAL_SEMKATH); - zend_string *const_JG_FINAL_SEMKATH_name = zend_string_init_interned("JG_FINAL_SEMKATH", sizeof("JG_FINAL_SEMKATH") - 1, 1); + zend_string *const_JG_FINAL_SEMKATH_name = zend_string_init_interned("JG_FINAL_SEMKATH", sizeof("JG_FINAL_SEMKATH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_FINAL_SEMKATH_name, &const_JG_FINAL_SEMKATH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_FINAL_SEMKATH_name); + zend_string_release_ex(const_JG_FINAL_SEMKATH_name, true); zval const_JG_GAF_value; ZVAL_LONG(&const_JG_GAF_value, U_JG_GAF); - zend_string *const_JG_GAF_name = zend_string_init_interned("JG_GAF", sizeof("JG_GAF") - 1, 1); + zend_string *const_JG_GAF_name = zend_string_init_interned("JG_GAF", sizeof("JG_GAF") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_GAF_name, &const_JG_GAF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_GAF_name); + zend_string_release_ex(const_JG_GAF_name, true); zval const_JG_GAMAL_value; ZVAL_LONG(&const_JG_GAMAL_value, U_JG_GAMAL); - zend_string *const_JG_GAMAL_name = zend_string_init_interned("JG_GAMAL", sizeof("JG_GAMAL") - 1, 1); + zend_string *const_JG_GAMAL_name = zend_string_init_interned("JG_GAMAL", sizeof("JG_GAMAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_GAMAL_name, &const_JG_GAMAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_GAMAL_name); + zend_string_release_ex(const_JG_GAMAL_name, true); zval const_JG_HAH_value; ZVAL_LONG(&const_JG_HAH_value, U_JG_HAH); - zend_string *const_JG_HAH_name = zend_string_init_interned("JG_HAH", sizeof("JG_HAH") - 1, 1); + zend_string *const_JG_HAH_name = zend_string_init_interned("JG_HAH", sizeof("JG_HAH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_HAH_name, &const_JG_HAH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_HAH_name); + zend_string_release_ex(const_JG_HAH_name, true); zval const_JG_TEH_MARBUTA_GOAL_value; ZVAL_LONG(&const_JG_TEH_MARBUTA_GOAL_value, U_JG_TEH_MARBUTA_GOAL); - zend_string *const_JG_TEH_MARBUTA_GOAL_name = zend_string_init_interned("JG_TEH_MARBUTA_GOAL", sizeof("JG_TEH_MARBUTA_GOAL") - 1, 1); + zend_string *const_JG_TEH_MARBUTA_GOAL_name = zend_string_init_interned("JG_TEH_MARBUTA_GOAL", sizeof("JG_TEH_MARBUTA_GOAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_TEH_MARBUTA_GOAL_name, &const_JG_TEH_MARBUTA_GOAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_TEH_MARBUTA_GOAL_name); + zend_string_release_ex(const_JG_TEH_MARBUTA_GOAL_name, true); zval const_JG_HAMZA_ON_HEH_GOAL_value; ZVAL_LONG(&const_JG_HAMZA_ON_HEH_GOAL_value, U_JG_HAMZA_ON_HEH_GOAL); - zend_string *const_JG_HAMZA_ON_HEH_GOAL_name = zend_string_init_interned("JG_HAMZA_ON_HEH_GOAL", sizeof("JG_HAMZA_ON_HEH_GOAL") - 1, 1); + zend_string *const_JG_HAMZA_ON_HEH_GOAL_name = zend_string_init_interned("JG_HAMZA_ON_HEH_GOAL", sizeof("JG_HAMZA_ON_HEH_GOAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_HAMZA_ON_HEH_GOAL_name, &const_JG_HAMZA_ON_HEH_GOAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_HAMZA_ON_HEH_GOAL_name); + zend_string_release_ex(const_JG_HAMZA_ON_HEH_GOAL_name, true); zval const_JG_HE_value; ZVAL_LONG(&const_JG_HE_value, U_JG_HE); - zend_string *const_JG_HE_name = zend_string_init_interned("JG_HE", sizeof("JG_HE") - 1, 1); + zend_string *const_JG_HE_name = zend_string_init_interned("JG_HE", sizeof("JG_HE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_HE_name, &const_JG_HE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_HE_name); + zend_string_release_ex(const_JG_HE_name, true); zval const_JG_HEH_value; ZVAL_LONG(&const_JG_HEH_value, U_JG_HEH); - zend_string *const_JG_HEH_name = zend_string_init_interned("JG_HEH", sizeof("JG_HEH") - 1, 1); + zend_string *const_JG_HEH_name = zend_string_init_interned("JG_HEH", sizeof("JG_HEH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_HEH_name, &const_JG_HEH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_HEH_name); + zend_string_release_ex(const_JG_HEH_name, true); zval const_JG_HEH_GOAL_value; ZVAL_LONG(&const_JG_HEH_GOAL_value, U_JG_HEH_GOAL); - zend_string *const_JG_HEH_GOAL_name = zend_string_init_interned("JG_HEH_GOAL", sizeof("JG_HEH_GOAL") - 1, 1); + zend_string *const_JG_HEH_GOAL_name = zend_string_init_interned("JG_HEH_GOAL", sizeof("JG_HEH_GOAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_HEH_GOAL_name, &const_JG_HEH_GOAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_HEH_GOAL_name); + zend_string_release_ex(const_JG_HEH_GOAL_name, true); zval const_JG_HETH_value; ZVAL_LONG(&const_JG_HETH_value, U_JG_HETH); - zend_string *const_JG_HETH_name = zend_string_init_interned("JG_HETH", sizeof("JG_HETH") - 1, 1); + zend_string *const_JG_HETH_name = zend_string_init_interned("JG_HETH", sizeof("JG_HETH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_HETH_name, &const_JG_HETH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_HETH_name); + zend_string_release_ex(const_JG_HETH_name, true); zval const_JG_KAF_value; ZVAL_LONG(&const_JG_KAF_value, U_JG_KAF); - zend_string *const_JG_KAF_name = zend_string_init_interned("JG_KAF", sizeof("JG_KAF") - 1, 1); + zend_string *const_JG_KAF_name = zend_string_init_interned("JG_KAF", sizeof("JG_KAF") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_KAF_name, &const_JG_KAF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_KAF_name); + zend_string_release_ex(const_JG_KAF_name, true); zval const_JG_KAPH_value; ZVAL_LONG(&const_JG_KAPH_value, U_JG_KAPH); - zend_string *const_JG_KAPH_name = zend_string_init_interned("JG_KAPH", sizeof("JG_KAPH") - 1, 1); + zend_string *const_JG_KAPH_name = zend_string_init_interned("JG_KAPH", sizeof("JG_KAPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_KAPH_name, &const_JG_KAPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_KAPH_name); + zend_string_release_ex(const_JG_KAPH_name, true); zval const_JG_KNOTTED_HEH_value; ZVAL_LONG(&const_JG_KNOTTED_HEH_value, U_JG_KNOTTED_HEH); - zend_string *const_JG_KNOTTED_HEH_name = zend_string_init_interned("JG_KNOTTED_HEH", sizeof("JG_KNOTTED_HEH") - 1, 1); + zend_string *const_JG_KNOTTED_HEH_name = zend_string_init_interned("JG_KNOTTED_HEH", sizeof("JG_KNOTTED_HEH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_KNOTTED_HEH_name, &const_JG_KNOTTED_HEH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_KNOTTED_HEH_name); + zend_string_release_ex(const_JG_KNOTTED_HEH_name, true); zval const_JG_LAM_value; ZVAL_LONG(&const_JG_LAM_value, U_JG_LAM); - zend_string *const_JG_LAM_name = zend_string_init_interned("JG_LAM", sizeof("JG_LAM") - 1, 1); + zend_string *const_JG_LAM_name = zend_string_init_interned("JG_LAM", sizeof("JG_LAM") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_LAM_name, &const_JG_LAM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_LAM_name); + zend_string_release_ex(const_JG_LAM_name, true); zval const_JG_LAMADH_value; ZVAL_LONG(&const_JG_LAMADH_value, U_JG_LAMADH); - zend_string *const_JG_LAMADH_name = zend_string_init_interned("JG_LAMADH", sizeof("JG_LAMADH") - 1, 1); + zend_string *const_JG_LAMADH_name = zend_string_init_interned("JG_LAMADH", sizeof("JG_LAMADH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_LAMADH_name, &const_JG_LAMADH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_LAMADH_name); + zend_string_release_ex(const_JG_LAMADH_name, true); zval const_JG_MEEM_value; ZVAL_LONG(&const_JG_MEEM_value, U_JG_MEEM); - zend_string *const_JG_MEEM_name = zend_string_init_interned("JG_MEEM", sizeof("JG_MEEM") - 1, 1); + zend_string *const_JG_MEEM_name = zend_string_init_interned("JG_MEEM", sizeof("JG_MEEM") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MEEM_name, &const_JG_MEEM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MEEM_name); + zend_string_release_ex(const_JG_MEEM_name, true); zval const_JG_MIM_value; ZVAL_LONG(&const_JG_MIM_value, U_JG_MIM); - zend_string *const_JG_MIM_name = zend_string_init_interned("JG_MIM", sizeof("JG_MIM") - 1, 1); + zend_string *const_JG_MIM_name = zend_string_init_interned("JG_MIM", sizeof("JG_MIM") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MIM_name, &const_JG_MIM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MIM_name); + zend_string_release_ex(const_JG_MIM_name, true); zval const_JG_NOON_value; ZVAL_LONG(&const_JG_NOON_value, U_JG_NOON); - zend_string *const_JG_NOON_name = zend_string_init_interned("JG_NOON", sizeof("JG_NOON") - 1, 1); + zend_string *const_JG_NOON_name = zend_string_init_interned("JG_NOON", sizeof("JG_NOON") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_NOON_name, &const_JG_NOON_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_NOON_name); + zend_string_release_ex(const_JG_NOON_name, true); zval const_JG_NUN_value; ZVAL_LONG(&const_JG_NUN_value, U_JG_NUN); - zend_string *const_JG_NUN_name = zend_string_init_interned("JG_NUN", sizeof("JG_NUN") - 1, 1); + zend_string *const_JG_NUN_name = zend_string_init_interned("JG_NUN", sizeof("JG_NUN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_NUN_name, &const_JG_NUN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_NUN_name); + zend_string_release_ex(const_JG_NUN_name, true); zval const_JG_PE_value; ZVAL_LONG(&const_JG_PE_value, U_JG_PE); - zend_string *const_JG_PE_name = zend_string_init_interned("JG_PE", sizeof("JG_PE") - 1, 1); + zend_string *const_JG_PE_name = zend_string_init_interned("JG_PE", sizeof("JG_PE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_PE_name, &const_JG_PE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_PE_name); + zend_string_release_ex(const_JG_PE_name, true); zval const_JG_QAF_value; ZVAL_LONG(&const_JG_QAF_value, U_JG_QAF); - zend_string *const_JG_QAF_name = zend_string_init_interned("JG_QAF", sizeof("JG_QAF") - 1, 1); + zend_string *const_JG_QAF_name = zend_string_init_interned("JG_QAF", sizeof("JG_QAF") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_QAF_name, &const_JG_QAF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_QAF_name); + zend_string_release_ex(const_JG_QAF_name, true); zval const_JG_QAPH_value; ZVAL_LONG(&const_JG_QAPH_value, U_JG_QAPH); - zend_string *const_JG_QAPH_name = zend_string_init_interned("JG_QAPH", sizeof("JG_QAPH") - 1, 1); + zend_string *const_JG_QAPH_name = zend_string_init_interned("JG_QAPH", sizeof("JG_QAPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_QAPH_name, &const_JG_QAPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_QAPH_name); + zend_string_release_ex(const_JG_QAPH_name, true); zval const_JG_REH_value; ZVAL_LONG(&const_JG_REH_value, U_JG_REH); - zend_string *const_JG_REH_name = zend_string_init_interned("JG_REH", sizeof("JG_REH") - 1, 1); + zend_string *const_JG_REH_name = zend_string_init_interned("JG_REH", sizeof("JG_REH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_REH_name, &const_JG_REH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_REH_name); + zend_string_release_ex(const_JG_REH_name, true); zval const_JG_REVERSED_PE_value; ZVAL_LONG(&const_JG_REVERSED_PE_value, U_JG_REVERSED_PE); - zend_string *const_JG_REVERSED_PE_name = zend_string_init_interned("JG_REVERSED_PE", sizeof("JG_REVERSED_PE") - 1, 1); + zend_string *const_JG_REVERSED_PE_name = zend_string_init_interned("JG_REVERSED_PE", sizeof("JG_REVERSED_PE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_REVERSED_PE_name, &const_JG_REVERSED_PE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_REVERSED_PE_name); + zend_string_release_ex(const_JG_REVERSED_PE_name, true); zval const_JG_SAD_value; ZVAL_LONG(&const_JG_SAD_value, U_JG_SAD); - zend_string *const_JG_SAD_name = zend_string_init_interned("JG_SAD", sizeof("JG_SAD") - 1, 1); + zend_string *const_JG_SAD_name = zend_string_init_interned("JG_SAD", sizeof("JG_SAD") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_SAD_name, &const_JG_SAD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_SAD_name); + zend_string_release_ex(const_JG_SAD_name, true); zval const_JG_SADHE_value; ZVAL_LONG(&const_JG_SADHE_value, U_JG_SADHE); - zend_string *const_JG_SADHE_name = zend_string_init_interned("JG_SADHE", sizeof("JG_SADHE") - 1, 1); + zend_string *const_JG_SADHE_name = zend_string_init_interned("JG_SADHE", sizeof("JG_SADHE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_SADHE_name, &const_JG_SADHE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_SADHE_name); + zend_string_release_ex(const_JG_SADHE_name, true); zval const_JG_SEEN_value; ZVAL_LONG(&const_JG_SEEN_value, U_JG_SEEN); - zend_string *const_JG_SEEN_name = zend_string_init_interned("JG_SEEN", sizeof("JG_SEEN") - 1, 1); + zend_string *const_JG_SEEN_name = zend_string_init_interned("JG_SEEN", sizeof("JG_SEEN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_SEEN_name, &const_JG_SEEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_SEEN_name); + zend_string_release_ex(const_JG_SEEN_name, true); zval const_JG_SEMKATH_value; ZVAL_LONG(&const_JG_SEMKATH_value, U_JG_SEMKATH); - zend_string *const_JG_SEMKATH_name = zend_string_init_interned("JG_SEMKATH", sizeof("JG_SEMKATH") - 1, 1); + zend_string *const_JG_SEMKATH_name = zend_string_init_interned("JG_SEMKATH", sizeof("JG_SEMKATH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_SEMKATH_name, &const_JG_SEMKATH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_SEMKATH_name); + zend_string_release_ex(const_JG_SEMKATH_name, true); zval const_JG_SHIN_value; ZVAL_LONG(&const_JG_SHIN_value, U_JG_SHIN); - zend_string *const_JG_SHIN_name = zend_string_init_interned("JG_SHIN", sizeof("JG_SHIN") - 1, 1); + zend_string *const_JG_SHIN_name = zend_string_init_interned("JG_SHIN", sizeof("JG_SHIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_SHIN_name, &const_JG_SHIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_SHIN_name); + zend_string_release_ex(const_JG_SHIN_name, true); zval const_JG_SWASH_KAF_value; ZVAL_LONG(&const_JG_SWASH_KAF_value, U_JG_SWASH_KAF); - zend_string *const_JG_SWASH_KAF_name = zend_string_init_interned("JG_SWASH_KAF", sizeof("JG_SWASH_KAF") - 1, 1); + zend_string *const_JG_SWASH_KAF_name = zend_string_init_interned("JG_SWASH_KAF", sizeof("JG_SWASH_KAF") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_SWASH_KAF_name, &const_JG_SWASH_KAF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_SWASH_KAF_name); + zend_string_release_ex(const_JG_SWASH_KAF_name, true); zval const_JG_SYRIAC_WAW_value; ZVAL_LONG(&const_JG_SYRIAC_WAW_value, U_JG_SYRIAC_WAW); - zend_string *const_JG_SYRIAC_WAW_name = zend_string_init_interned("JG_SYRIAC_WAW", sizeof("JG_SYRIAC_WAW") - 1, 1); + zend_string *const_JG_SYRIAC_WAW_name = zend_string_init_interned("JG_SYRIAC_WAW", sizeof("JG_SYRIAC_WAW") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_SYRIAC_WAW_name, &const_JG_SYRIAC_WAW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_SYRIAC_WAW_name); + zend_string_release_ex(const_JG_SYRIAC_WAW_name, true); zval const_JG_TAH_value; ZVAL_LONG(&const_JG_TAH_value, U_JG_TAH); - zend_string *const_JG_TAH_name = zend_string_init_interned("JG_TAH", sizeof("JG_TAH") - 1, 1); + zend_string *const_JG_TAH_name = zend_string_init_interned("JG_TAH", sizeof("JG_TAH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_TAH_name, &const_JG_TAH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_TAH_name); + zend_string_release_ex(const_JG_TAH_name, true); zval const_JG_TAW_value; ZVAL_LONG(&const_JG_TAW_value, U_JG_TAW); - zend_string *const_JG_TAW_name = zend_string_init_interned("JG_TAW", sizeof("JG_TAW") - 1, 1); + zend_string *const_JG_TAW_name = zend_string_init_interned("JG_TAW", sizeof("JG_TAW") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_TAW_name, &const_JG_TAW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_TAW_name); + zend_string_release_ex(const_JG_TAW_name, true); zval const_JG_TEH_MARBUTA_value; ZVAL_LONG(&const_JG_TEH_MARBUTA_value, U_JG_TEH_MARBUTA); - zend_string *const_JG_TEH_MARBUTA_name = zend_string_init_interned("JG_TEH_MARBUTA", sizeof("JG_TEH_MARBUTA") - 1, 1); + zend_string *const_JG_TEH_MARBUTA_name = zend_string_init_interned("JG_TEH_MARBUTA", sizeof("JG_TEH_MARBUTA") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_TEH_MARBUTA_name, &const_JG_TEH_MARBUTA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_TEH_MARBUTA_name); + zend_string_release_ex(const_JG_TEH_MARBUTA_name, true); zval const_JG_TETH_value; ZVAL_LONG(&const_JG_TETH_value, U_JG_TETH); - zend_string *const_JG_TETH_name = zend_string_init_interned("JG_TETH", sizeof("JG_TETH") - 1, 1); + zend_string *const_JG_TETH_name = zend_string_init_interned("JG_TETH", sizeof("JG_TETH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_TETH_name, &const_JG_TETH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_TETH_name); + zend_string_release_ex(const_JG_TETH_name, true); zval const_JG_WAW_value; ZVAL_LONG(&const_JG_WAW_value, U_JG_WAW); - zend_string *const_JG_WAW_name = zend_string_init_interned("JG_WAW", sizeof("JG_WAW") - 1, 1); + zend_string *const_JG_WAW_name = zend_string_init_interned("JG_WAW", sizeof("JG_WAW") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_WAW_name, &const_JG_WAW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_WAW_name); + zend_string_release_ex(const_JG_WAW_name, true); zval const_JG_YEH_value; ZVAL_LONG(&const_JG_YEH_value, U_JG_YEH); - zend_string *const_JG_YEH_name = zend_string_init_interned("JG_YEH", sizeof("JG_YEH") - 1, 1); + zend_string *const_JG_YEH_name = zend_string_init_interned("JG_YEH", sizeof("JG_YEH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_YEH_name, &const_JG_YEH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_YEH_name); + zend_string_release_ex(const_JG_YEH_name, true); zval const_JG_YEH_BARREE_value; ZVAL_LONG(&const_JG_YEH_BARREE_value, U_JG_YEH_BARREE); - zend_string *const_JG_YEH_BARREE_name = zend_string_init_interned("JG_YEH_BARREE", sizeof("JG_YEH_BARREE") - 1, 1); + zend_string *const_JG_YEH_BARREE_name = zend_string_init_interned("JG_YEH_BARREE", sizeof("JG_YEH_BARREE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_YEH_BARREE_name, &const_JG_YEH_BARREE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_YEH_BARREE_name); + zend_string_release_ex(const_JG_YEH_BARREE_name, true); zval const_JG_YEH_WITH_TAIL_value; ZVAL_LONG(&const_JG_YEH_WITH_TAIL_value, U_JG_YEH_WITH_TAIL); - zend_string *const_JG_YEH_WITH_TAIL_name = zend_string_init_interned("JG_YEH_WITH_TAIL", sizeof("JG_YEH_WITH_TAIL") - 1, 1); + zend_string *const_JG_YEH_WITH_TAIL_name = zend_string_init_interned("JG_YEH_WITH_TAIL", sizeof("JG_YEH_WITH_TAIL") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_YEH_WITH_TAIL_name, &const_JG_YEH_WITH_TAIL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_YEH_WITH_TAIL_name); + zend_string_release_ex(const_JG_YEH_WITH_TAIL_name, true); zval const_JG_YUDH_value; ZVAL_LONG(&const_JG_YUDH_value, U_JG_YUDH); - zend_string *const_JG_YUDH_name = zend_string_init_interned("JG_YUDH", sizeof("JG_YUDH") - 1, 1); + zend_string *const_JG_YUDH_name = zend_string_init_interned("JG_YUDH", sizeof("JG_YUDH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_YUDH_name, &const_JG_YUDH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_YUDH_name); + zend_string_release_ex(const_JG_YUDH_name, true); zval const_JG_YUDH_HE_value; ZVAL_LONG(&const_JG_YUDH_HE_value, U_JG_YUDH_HE); - zend_string *const_JG_YUDH_HE_name = zend_string_init_interned("JG_YUDH_HE", sizeof("JG_YUDH_HE") - 1, 1); + zend_string *const_JG_YUDH_HE_name = zend_string_init_interned("JG_YUDH_HE", sizeof("JG_YUDH_HE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_YUDH_HE_name, &const_JG_YUDH_HE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_YUDH_HE_name); + zend_string_release_ex(const_JG_YUDH_HE_name, true); zval const_JG_ZAIN_value; ZVAL_LONG(&const_JG_ZAIN_value, U_JG_ZAIN); - zend_string *const_JG_ZAIN_name = zend_string_init_interned("JG_ZAIN", sizeof("JG_ZAIN") - 1, 1); + zend_string *const_JG_ZAIN_name = zend_string_init_interned("JG_ZAIN", sizeof("JG_ZAIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_ZAIN_name, &const_JG_ZAIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_ZAIN_name); + zend_string_release_ex(const_JG_ZAIN_name, true); zval const_JG_FE_value; ZVAL_LONG(&const_JG_FE_value, U_JG_FE); - zend_string *const_JG_FE_name = zend_string_init_interned("JG_FE", sizeof("JG_FE") - 1, 1); + zend_string *const_JG_FE_name = zend_string_init_interned("JG_FE", sizeof("JG_FE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_FE_name, &const_JG_FE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_FE_name); + zend_string_release_ex(const_JG_FE_name, true); zval const_JG_KHAPH_value; ZVAL_LONG(&const_JG_KHAPH_value, U_JG_KHAPH); - zend_string *const_JG_KHAPH_name = zend_string_init_interned("JG_KHAPH", sizeof("JG_KHAPH") - 1, 1); + zend_string *const_JG_KHAPH_name = zend_string_init_interned("JG_KHAPH", sizeof("JG_KHAPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_KHAPH_name, &const_JG_KHAPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_KHAPH_name); + zend_string_release_ex(const_JG_KHAPH_name, true); zval const_JG_ZHAIN_value; ZVAL_LONG(&const_JG_ZHAIN_value, U_JG_ZHAIN); - zend_string *const_JG_ZHAIN_name = zend_string_init_interned("JG_ZHAIN", sizeof("JG_ZHAIN") - 1, 1); + zend_string *const_JG_ZHAIN_name = zend_string_init_interned("JG_ZHAIN", sizeof("JG_ZHAIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_ZHAIN_name, &const_JG_ZHAIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_ZHAIN_name); + zend_string_release_ex(const_JG_ZHAIN_name, true); zval const_JG_BURUSHASKI_YEH_BARREE_value; ZVAL_LONG(&const_JG_BURUSHASKI_YEH_BARREE_value, U_JG_BURUSHASKI_YEH_BARREE); - zend_string *const_JG_BURUSHASKI_YEH_BARREE_name = zend_string_init_interned("JG_BURUSHASKI_YEH_BARREE", sizeof("JG_BURUSHASKI_YEH_BARREE") - 1, 1); + zend_string *const_JG_BURUSHASKI_YEH_BARREE_name = zend_string_init_interned("JG_BURUSHASKI_YEH_BARREE", sizeof("JG_BURUSHASKI_YEH_BARREE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_BURUSHASKI_YEH_BARREE_name, &const_JG_BURUSHASKI_YEH_BARREE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_BURUSHASKI_YEH_BARREE_name); + zend_string_release_ex(const_JG_BURUSHASKI_YEH_BARREE_name, true); zval const_JG_FARSI_YEH_value; ZVAL_LONG(&const_JG_FARSI_YEH_value, U_JG_FARSI_YEH); - zend_string *const_JG_FARSI_YEH_name = zend_string_init_interned("JG_FARSI_YEH", sizeof("JG_FARSI_YEH") - 1, 1); + zend_string *const_JG_FARSI_YEH_name = zend_string_init_interned("JG_FARSI_YEH", sizeof("JG_FARSI_YEH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_FARSI_YEH_name, &const_JG_FARSI_YEH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_FARSI_YEH_name); + zend_string_release_ex(const_JG_FARSI_YEH_name, true); zval const_JG_NYA_value; ZVAL_LONG(&const_JG_NYA_value, U_JG_NYA); - zend_string *const_JG_NYA_name = zend_string_init_interned("JG_NYA", sizeof("JG_NYA") - 1, 1); + zend_string *const_JG_NYA_name = zend_string_init_interned("JG_NYA", sizeof("JG_NYA") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_NYA_name, &const_JG_NYA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_NYA_name); + zend_string_release_ex(const_JG_NYA_name, true); zval const_JG_ROHINGYA_YEH_value; ZVAL_LONG(&const_JG_ROHINGYA_YEH_value, U_JG_ROHINGYA_YEH); - zend_string *const_JG_ROHINGYA_YEH_name = zend_string_init_interned("JG_ROHINGYA_YEH", sizeof("JG_ROHINGYA_YEH") - 1, 1); + zend_string *const_JG_ROHINGYA_YEH_name = zend_string_init_interned("JG_ROHINGYA_YEH", sizeof("JG_ROHINGYA_YEH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_ROHINGYA_YEH_name, &const_JG_ROHINGYA_YEH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_ROHINGYA_YEH_name); + zend_string_release_ex(const_JG_ROHINGYA_YEH_name, true); zval const_JG_MANICHAEAN_ALEPH_value; ZVAL_LONG(&const_JG_MANICHAEAN_ALEPH_value, U_JG_MANICHAEAN_ALEPH); - zend_string *const_JG_MANICHAEAN_ALEPH_name = zend_string_init_interned("JG_MANICHAEAN_ALEPH", sizeof("JG_MANICHAEAN_ALEPH") - 1, 1); + zend_string *const_JG_MANICHAEAN_ALEPH_name = zend_string_init_interned("JG_MANICHAEAN_ALEPH", sizeof("JG_MANICHAEAN_ALEPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_ALEPH_name, &const_JG_MANICHAEAN_ALEPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_ALEPH_name); + zend_string_release_ex(const_JG_MANICHAEAN_ALEPH_name, true); zval const_JG_MANICHAEAN_AYIN_value; ZVAL_LONG(&const_JG_MANICHAEAN_AYIN_value, U_JG_MANICHAEAN_AYIN); - zend_string *const_JG_MANICHAEAN_AYIN_name = zend_string_init_interned("JG_MANICHAEAN_AYIN", sizeof("JG_MANICHAEAN_AYIN") - 1, 1); + zend_string *const_JG_MANICHAEAN_AYIN_name = zend_string_init_interned("JG_MANICHAEAN_AYIN", sizeof("JG_MANICHAEAN_AYIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_AYIN_name, &const_JG_MANICHAEAN_AYIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_AYIN_name); + zend_string_release_ex(const_JG_MANICHAEAN_AYIN_name, true); zval const_JG_MANICHAEAN_BETH_value; ZVAL_LONG(&const_JG_MANICHAEAN_BETH_value, U_JG_MANICHAEAN_BETH); - zend_string *const_JG_MANICHAEAN_BETH_name = zend_string_init_interned("JG_MANICHAEAN_BETH", sizeof("JG_MANICHAEAN_BETH") - 1, 1); + zend_string *const_JG_MANICHAEAN_BETH_name = zend_string_init_interned("JG_MANICHAEAN_BETH", sizeof("JG_MANICHAEAN_BETH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_BETH_name, &const_JG_MANICHAEAN_BETH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_BETH_name); + zend_string_release_ex(const_JG_MANICHAEAN_BETH_name, true); zval const_JG_MANICHAEAN_DALETH_value; ZVAL_LONG(&const_JG_MANICHAEAN_DALETH_value, U_JG_MANICHAEAN_DALETH); - zend_string *const_JG_MANICHAEAN_DALETH_name = zend_string_init_interned("JG_MANICHAEAN_DALETH", sizeof("JG_MANICHAEAN_DALETH") - 1, 1); + zend_string *const_JG_MANICHAEAN_DALETH_name = zend_string_init_interned("JG_MANICHAEAN_DALETH", sizeof("JG_MANICHAEAN_DALETH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_DALETH_name, &const_JG_MANICHAEAN_DALETH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_DALETH_name); + zend_string_release_ex(const_JG_MANICHAEAN_DALETH_name, true); zval const_JG_MANICHAEAN_DHAMEDH_value; ZVAL_LONG(&const_JG_MANICHAEAN_DHAMEDH_value, U_JG_MANICHAEAN_DHAMEDH); - zend_string *const_JG_MANICHAEAN_DHAMEDH_name = zend_string_init_interned("JG_MANICHAEAN_DHAMEDH", sizeof("JG_MANICHAEAN_DHAMEDH") - 1, 1); + zend_string *const_JG_MANICHAEAN_DHAMEDH_name = zend_string_init_interned("JG_MANICHAEAN_DHAMEDH", sizeof("JG_MANICHAEAN_DHAMEDH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_DHAMEDH_name, &const_JG_MANICHAEAN_DHAMEDH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_DHAMEDH_name); + zend_string_release_ex(const_JG_MANICHAEAN_DHAMEDH_name, true); zval const_JG_MANICHAEAN_FIVE_value; ZVAL_LONG(&const_JG_MANICHAEAN_FIVE_value, U_JG_MANICHAEAN_FIVE); - zend_string *const_JG_MANICHAEAN_FIVE_name = zend_string_init_interned("JG_MANICHAEAN_FIVE", sizeof("JG_MANICHAEAN_FIVE") - 1, 1); + zend_string *const_JG_MANICHAEAN_FIVE_name = zend_string_init_interned("JG_MANICHAEAN_FIVE", sizeof("JG_MANICHAEAN_FIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_FIVE_name, &const_JG_MANICHAEAN_FIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_FIVE_name); + zend_string_release_ex(const_JG_MANICHAEAN_FIVE_name, true); zval const_JG_MANICHAEAN_GIMEL_value; ZVAL_LONG(&const_JG_MANICHAEAN_GIMEL_value, U_JG_MANICHAEAN_GIMEL); - zend_string *const_JG_MANICHAEAN_GIMEL_name = zend_string_init_interned("JG_MANICHAEAN_GIMEL", sizeof("JG_MANICHAEAN_GIMEL") - 1, 1); + zend_string *const_JG_MANICHAEAN_GIMEL_name = zend_string_init_interned("JG_MANICHAEAN_GIMEL", sizeof("JG_MANICHAEAN_GIMEL") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_GIMEL_name, &const_JG_MANICHAEAN_GIMEL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_GIMEL_name); + zend_string_release_ex(const_JG_MANICHAEAN_GIMEL_name, true); zval const_JG_MANICHAEAN_HETH_value; ZVAL_LONG(&const_JG_MANICHAEAN_HETH_value, U_JG_MANICHAEAN_HETH); - zend_string *const_JG_MANICHAEAN_HETH_name = zend_string_init_interned("JG_MANICHAEAN_HETH", sizeof("JG_MANICHAEAN_HETH") - 1, 1); + zend_string *const_JG_MANICHAEAN_HETH_name = zend_string_init_interned("JG_MANICHAEAN_HETH", sizeof("JG_MANICHAEAN_HETH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_HETH_name, &const_JG_MANICHAEAN_HETH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_HETH_name); + zend_string_release_ex(const_JG_MANICHAEAN_HETH_name, true); zval const_JG_MANICHAEAN_HUNDRED_value; ZVAL_LONG(&const_JG_MANICHAEAN_HUNDRED_value, U_JG_MANICHAEAN_HUNDRED); - zend_string *const_JG_MANICHAEAN_HUNDRED_name = zend_string_init_interned("JG_MANICHAEAN_HUNDRED", sizeof("JG_MANICHAEAN_HUNDRED") - 1, 1); + zend_string *const_JG_MANICHAEAN_HUNDRED_name = zend_string_init_interned("JG_MANICHAEAN_HUNDRED", sizeof("JG_MANICHAEAN_HUNDRED") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_HUNDRED_name, &const_JG_MANICHAEAN_HUNDRED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_HUNDRED_name); + zend_string_release_ex(const_JG_MANICHAEAN_HUNDRED_name, true); zval const_JG_MANICHAEAN_KAPH_value; ZVAL_LONG(&const_JG_MANICHAEAN_KAPH_value, U_JG_MANICHAEAN_KAPH); - zend_string *const_JG_MANICHAEAN_KAPH_name = zend_string_init_interned("JG_MANICHAEAN_KAPH", sizeof("JG_MANICHAEAN_KAPH") - 1, 1); + zend_string *const_JG_MANICHAEAN_KAPH_name = zend_string_init_interned("JG_MANICHAEAN_KAPH", sizeof("JG_MANICHAEAN_KAPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_KAPH_name, &const_JG_MANICHAEAN_KAPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_KAPH_name); + zend_string_release_ex(const_JG_MANICHAEAN_KAPH_name, true); zval const_JG_MANICHAEAN_LAMEDH_value; ZVAL_LONG(&const_JG_MANICHAEAN_LAMEDH_value, U_JG_MANICHAEAN_LAMEDH); - zend_string *const_JG_MANICHAEAN_LAMEDH_name = zend_string_init_interned("JG_MANICHAEAN_LAMEDH", sizeof("JG_MANICHAEAN_LAMEDH") - 1, 1); + zend_string *const_JG_MANICHAEAN_LAMEDH_name = zend_string_init_interned("JG_MANICHAEAN_LAMEDH", sizeof("JG_MANICHAEAN_LAMEDH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_LAMEDH_name, &const_JG_MANICHAEAN_LAMEDH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_LAMEDH_name); + zend_string_release_ex(const_JG_MANICHAEAN_LAMEDH_name, true); zval const_JG_MANICHAEAN_MEM_value; ZVAL_LONG(&const_JG_MANICHAEAN_MEM_value, U_JG_MANICHAEAN_MEM); - zend_string *const_JG_MANICHAEAN_MEM_name = zend_string_init_interned("JG_MANICHAEAN_MEM", sizeof("JG_MANICHAEAN_MEM") - 1, 1); + zend_string *const_JG_MANICHAEAN_MEM_name = zend_string_init_interned("JG_MANICHAEAN_MEM", sizeof("JG_MANICHAEAN_MEM") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_MEM_name, &const_JG_MANICHAEAN_MEM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_MEM_name); + zend_string_release_ex(const_JG_MANICHAEAN_MEM_name, true); zval const_JG_MANICHAEAN_NUN_value; ZVAL_LONG(&const_JG_MANICHAEAN_NUN_value, U_JG_MANICHAEAN_NUN); - zend_string *const_JG_MANICHAEAN_NUN_name = zend_string_init_interned("JG_MANICHAEAN_NUN", sizeof("JG_MANICHAEAN_NUN") - 1, 1); + zend_string *const_JG_MANICHAEAN_NUN_name = zend_string_init_interned("JG_MANICHAEAN_NUN", sizeof("JG_MANICHAEAN_NUN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_NUN_name, &const_JG_MANICHAEAN_NUN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_NUN_name); + zend_string_release_ex(const_JG_MANICHAEAN_NUN_name, true); zval const_JG_MANICHAEAN_ONE_value; ZVAL_LONG(&const_JG_MANICHAEAN_ONE_value, U_JG_MANICHAEAN_ONE); - zend_string *const_JG_MANICHAEAN_ONE_name = zend_string_init_interned("JG_MANICHAEAN_ONE", sizeof("JG_MANICHAEAN_ONE") - 1, 1); + zend_string *const_JG_MANICHAEAN_ONE_name = zend_string_init_interned("JG_MANICHAEAN_ONE", sizeof("JG_MANICHAEAN_ONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_ONE_name, &const_JG_MANICHAEAN_ONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_ONE_name); + zend_string_release_ex(const_JG_MANICHAEAN_ONE_name, true); zval const_JG_MANICHAEAN_PE_value; ZVAL_LONG(&const_JG_MANICHAEAN_PE_value, U_JG_MANICHAEAN_PE); - zend_string *const_JG_MANICHAEAN_PE_name = zend_string_init_interned("JG_MANICHAEAN_PE", sizeof("JG_MANICHAEAN_PE") - 1, 1); + zend_string *const_JG_MANICHAEAN_PE_name = zend_string_init_interned("JG_MANICHAEAN_PE", sizeof("JG_MANICHAEAN_PE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_PE_name, &const_JG_MANICHAEAN_PE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_PE_name); + zend_string_release_ex(const_JG_MANICHAEAN_PE_name, true); zval const_JG_MANICHAEAN_QOPH_value; ZVAL_LONG(&const_JG_MANICHAEAN_QOPH_value, U_JG_MANICHAEAN_QOPH); - zend_string *const_JG_MANICHAEAN_QOPH_name = zend_string_init_interned("JG_MANICHAEAN_QOPH", sizeof("JG_MANICHAEAN_QOPH") - 1, 1); + zend_string *const_JG_MANICHAEAN_QOPH_name = zend_string_init_interned("JG_MANICHAEAN_QOPH", sizeof("JG_MANICHAEAN_QOPH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_QOPH_name, &const_JG_MANICHAEAN_QOPH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_QOPH_name); + zend_string_release_ex(const_JG_MANICHAEAN_QOPH_name, true); zval const_JG_MANICHAEAN_RESH_value; ZVAL_LONG(&const_JG_MANICHAEAN_RESH_value, U_JG_MANICHAEAN_RESH); - zend_string *const_JG_MANICHAEAN_RESH_name = zend_string_init_interned("JG_MANICHAEAN_RESH", sizeof("JG_MANICHAEAN_RESH") - 1, 1); + zend_string *const_JG_MANICHAEAN_RESH_name = zend_string_init_interned("JG_MANICHAEAN_RESH", sizeof("JG_MANICHAEAN_RESH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_RESH_name, &const_JG_MANICHAEAN_RESH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_RESH_name); + zend_string_release_ex(const_JG_MANICHAEAN_RESH_name, true); zval const_JG_MANICHAEAN_SADHE_value; ZVAL_LONG(&const_JG_MANICHAEAN_SADHE_value, U_JG_MANICHAEAN_SADHE); - zend_string *const_JG_MANICHAEAN_SADHE_name = zend_string_init_interned("JG_MANICHAEAN_SADHE", sizeof("JG_MANICHAEAN_SADHE") - 1, 1); + zend_string *const_JG_MANICHAEAN_SADHE_name = zend_string_init_interned("JG_MANICHAEAN_SADHE", sizeof("JG_MANICHAEAN_SADHE") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_SADHE_name, &const_JG_MANICHAEAN_SADHE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_SADHE_name); + zend_string_release_ex(const_JG_MANICHAEAN_SADHE_name, true); zval const_JG_MANICHAEAN_SAMEKH_value; ZVAL_LONG(&const_JG_MANICHAEAN_SAMEKH_value, U_JG_MANICHAEAN_SAMEKH); - zend_string *const_JG_MANICHAEAN_SAMEKH_name = zend_string_init_interned("JG_MANICHAEAN_SAMEKH", sizeof("JG_MANICHAEAN_SAMEKH") - 1, 1); + zend_string *const_JG_MANICHAEAN_SAMEKH_name = zend_string_init_interned("JG_MANICHAEAN_SAMEKH", sizeof("JG_MANICHAEAN_SAMEKH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_SAMEKH_name, &const_JG_MANICHAEAN_SAMEKH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_SAMEKH_name); + zend_string_release_ex(const_JG_MANICHAEAN_SAMEKH_name, true); zval const_JG_MANICHAEAN_TAW_value; ZVAL_LONG(&const_JG_MANICHAEAN_TAW_value, U_JG_MANICHAEAN_TAW); - zend_string *const_JG_MANICHAEAN_TAW_name = zend_string_init_interned("JG_MANICHAEAN_TAW", sizeof("JG_MANICHAEAN_TAW") - 1, 1); + zend_string *const_JG_MANICHAEAN_TAW_name = zend_string_init_interned("JG_MANICHAEAN_TAW", sizeof("JG_MANICHAEAN_TAW") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_TAW_name, &const_JG_MANICHAEAN_TAW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_TAW_name); + zend_string_release_ex(const_JG_MANICHAEAN_TAW_name, true); zval const_JG_MANICHAEAN_TEN_value; ZVAL_LONG(&const_JG_MANICHAEAN_TEN_value, U_JG_MANICHAEAN_TEN); - zend_string *const_JG_MANICHAEAN_TEN_name = zend_string_init_interned("JG_MANICHAEAN_TEN", sizeof("JG_MANICHAEAN_TEN") - 1, 1); + zend_string *const_JG_MANICHAEAN_TEN_name = zend_string_init_interned("JG_MANICHAEAN_TEN", sizeof("JG_MANICHAEAN_TEN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_TEN_name, &const_JG_MANICHAEAN_TEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_TEN_name); + zend_string_release_ex(const_JG_MANICHAEAN_TEN_name, true); zval const_JG_MANICHAEAN_TETH_value; ZVAL_LONG(&const_JG_MANICHAEAN_TETH_value, U_JG_MANICHAEAN_TETH); - zend_string *const_JG_MANICHAEAN_TETH_name = zend_string_init_interned("JG_MANICHAEAN_TETH", sizeof("JG_MANICHAEAN_TETH") - 1, 1); + zend_string *const_JG_MANICHAEAN_TETH_name = zend_string_init_interned("JG_MANICHAEAN_TETH", sizeof("JG_MANICHAEAN_TETH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_TETH_name, &const_JG_MANICHAEAN_TETH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_TETH_name); + zend_string_release_ex(const_JG_MANICHAEAN_TETH_name, true); zval const_JG_MANICHAEAN_THAMEDH_value; ZVAL_LONG(&const_JG_MANICHAEAN_THAMEDH_value, U_JG_MANICHAEAN_THAMEDH); - zend_string *const_JG_MANICHAEAN_THAMEDH_name = zend_string_init_interned("JG_MANICHAEAN_THAMEDH", sizeof("JG_MANICHAEAN_THAMEDH") - 1, 1); + zend_string *const_JG_MANICHAEAN_THAMEDH_name = zend_string_init_interned("JG_MANICHAEAN_THAMEDH", sizeof("JG_MANICHAEAN_THAMEDH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_THAMEDH_name, &const_JG_MANICHAEAN_THAMEDH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_THAMEDH_name); + zend_string_release_ex(const_JG_MANICHAEAN_THAMEDH_name, true); zval const_JG_MANICHAEAN_TWENTY_value; ZVAL_LONG(&const_JG_MANICHAEAN_TWENTY_value, U_JG_MANICHAEAN_TWENTY); - zend_string *const_JG_MANICHAEAN_TWENTY_name = zend_string_init_interned("JG_MANICHAEAN_TWENTY", sizeof("JG_MANICHAEAN_TWENTY") - 1, 1); + zend_string *const_JG_MANICHAEAN_TWENTY_name = zend_string_init_interned("JG_MANICHAEAN_TWENTY", sizeof("JG_MANICHAEAN_TWENTY") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_TWENTY_name, &const_JG_MANICHAEAN_TWENTY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_TWENTY_name); + zend_string_release_ex(const_JG_MANICHAEAN_TWENTY_name, true); zval const_JG_MANICHAEAN_WAW_value; ZVAL_LONG(&const_JG_MANICHAEAN_WAW_value, U_JG_MANICHAEAN_WAW); - zend_string *const_JG_MANICHAEAN_WAW_name = zend_string_init_interned("JG_MANICHAEAN_WAW", sizeof("JG_MANICHAEAN_WAW") - 1, 1); + zend_string *const_JG_MANICHAEAN_WAW_name = zend_string_init_interned("JG_MANICHAEAN_WAW", sizeof("JG_MANICHAEAN_WAW") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_WAW_name, &const_JG_MANICHAEAN_WAW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_WAW_name); + zend_string_release_ex(const_JG_MANICHAEAN_WAW_name, true); zval const_JG_MANICHAEAN_YODH_value; ZVAL_LONG(&const_JG_MANICHAEAN_YODH_value, U_JG_MANICHAEAN_YODH); - zend_string *const_JG_MANICHAEAN_YODH_name = zend_string_init_interned("JG_MANICHAEAN_YODH", sizeof("JG_MANICHAEAN_YODH") - 1, 1); + zend_string *const_JG_MANICHAEAN_YODH_name = zend_string_init_interned("JG_MANICHAEAN_YODH", sizeof("JG_MANICHAEAN_YODH") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_YODH_name, &const_JG_MANICHAEAN_YODH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_YODH_name); + zend_string_release_ex(const_JG_MANICHAEAN_YODH_name, true); zval const_JG_MANICHAEAN_ZAYIN_value; ZVAL_LONG(&const_JG_MANICHAEAN_ZAYIN_value, U_JG_MANICHAEAN_ZAYIN); - zend_string *const_JG_MANICHAEAN_ZAYIN_name = zend_string_init_interned("JG_MANICHAEAN_ZAYIN", sizeof("JG_MANICHAEAN_ZAYIN") - 1, 1); + zend_string *const_JG_MANICHAEAN_ZAYIN_name = zend_string_init_interned("JG_MANICHAEAN_ZAYIN", sizeof("JG_MANICHAEAN_ZAYIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_MANICHAEAN_ZAYIN_name, &const_JG_MANICHAEAN_ZAYIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_MANICHAEAN_ZAYIN_name); + zend_string_release_ex(const_JG_MANICHAEAN_ZAYIN_name, true); zval const_JG_STRAIGHT_WAW_value; ZVAL_LONG(&const_JG_STRAIGHT_WAW_value, U_JG_STRAIGHT_WAW); - zend_string *const_JG_STRAIGHT_WAW_name = zend_string_init_interned("JG_STRAIGHT_WAW", sizeof("JG_STRAIGHT_WAW") - 1, 1); + zend_string *const_JG_STRAIGHT_WAW_name = zend_string_init_interned("JG_STRAIGHT_WAW", sizeof("JG_STRAIGHT_WAW") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_STRAIGHT_WAW_name, &const_JG_STRAIGHT_WAW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_STRAIGHT_WAW_name); + zend_string_release_ex(const_JG_STRAIGHT_WAW_name, true); zval const_JG_COUNT_value; ZVAL_LONG(&const_JG_COUNT_value, U_JG_COUNT); - zend_string *const_JG_COUNT_name = zend_string_init_interned("JG_COUNT", sizeof("JG_COUNT") - 1, 1); + zend_string *const_JG_COUNT_name = zend_string_init_interned("JG_COUNT", sizeof("JG_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_JG_COUNT_name, &const_JG_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_JG_COUNT_name); + zend_string_release_ex(const_JG_COUNT_name, true); zval const_GCB_OTHER_value; ZVAL_LONG(&const_GCB_OTHER_value, U_GCB_OTHER); - zend_string *const_GCB_OTHER_name = zend_string_init_interned("GCB_OTHER", sizeof("GCB_OTHER") - 1, 1); + zend_string *const_GCB_OTHER_name = zend_string_init_interned("GCB_OTHER", sizeof("GCB_OTHER") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_OTHER_name, &const_GCB_OTHER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_OTHER_name); + zend_string_release_ex(const_GCB_OTHER_name, true); zval const_GCB_CONTROL_value; ZVAL_LONG(&const_GCB_CONTROL_value, U_GCB_CONTROL); - zend_string *const_GCB_CONTROL_name = zend_string_init_interned("GCB_CONTROL", sizeof("GCB_CONTROL") - 1, 1); + zend_string *const_GCB_CONTROL_name = zend_string_init_interned("GCB_CONTROL", sizeof("GCB_CONTROL") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_CONTROL_name, &const_GCB_CONTROL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_CONTROL_name); + zend_string_release_ex(const_GCB_CONTROL_name, true); zval const_GCB_CR_value; ZVAL_LONG(&const_GCB_CR_value, U_GCB_CR); - zend_string *const_GCB_CR_name = zend_string_init_interned("GCB_CR", sizeof("GCB_CR") - 1, 1); + zend_string *const_GCB_CR_name = zend_string_init_interned("GCB_CR", sizeof("GCB_CR") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_CR_name, &const_GCB_CR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_CR_name); + zend_string_release_ex(const_GCB_CR_name, true); zval const_GCB_EXTEND_value; ZVAL_LONG(&const_GCB_EXTEND_value, U_GCB_EXTEND); - zend_string *const_GCB_EXTEND_name = zend_string_init_interned("GCB_EXTEND", sizeof("GCB_EXTEND") - 1, 1); + zend_string *const_GCB_EXTEND_name = zend_string_init_interned("GCB_EXTEND", sizeof("GCB_EXTEND") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_EXTEND_name, &const_GCB_EXTEND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_EXTEND_name); + zend_string_release_ex(const_GCB_EXTEND_name, true); zval const_GCB_L_value; ZVAL_LONG(&const_GCB_L_value, U_GCB_L); - zend_string *const_GCB_L_name = zend_string_init_interned("GCB_L", sizeof("GCB_L") - 1, 1); + zend_string *const_GCB_L_name = zend_string_init_interned("GCB_L", sizeof("GCB_L") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_L_name, &const_GCB_L_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_L_name); + zend_string_release_ex(const_GCB_L_name, true); zval const_GCB_LF_value; ZVAL_LONG(&const_GCB_LF_value, U_GCB_LF); - zend_string *const_GCB_LF_name = zend_string_init_interned("GCB_LF", sizeof("GCB_LF") - 1, 1); + zend_string *const_GCB_LF_name = zend_string_init_interned("GCB_LF", sizeof("GCB_LF") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_LF_name, &const_GCB_LF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_LF_name); + zend_string_release_ex(const_GCB_LF_name, true); zval const_GCB_LV_value; ZVAL_LONG(&const_GCB_LV_value, U_GCB_LV); - zend_string *const_GCB_LV_name = zend_string_init_interned("GCB_LV", sizeof("GCB_LV") - 1, 1); + zend_string *const_GCB_LV_name = zend_string_init_interned("GCB_LV", sizeof("GCB_LV") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_LV_name, &const_GCB_LV_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_LV_name); + zend_string_release_ex(const_GCB_LV_name, true); zval const_GCB_LVT_value; ZVAL_LONG(&const_GCB_LVT_value, U_GCB_LVT); - zend_string *const_GCB_LVT_name = zend_string_init_interned("GCB_LVT", sizeof("GCB_LVT") - 1, 1); + zend_string *const_GCB_LVT_name = zend_string_init_interned("GCB_LVT", sizeof("GCB_LVT") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_LVT_name, &const_GCB_LVT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_LVT_name); + zend_string_release_ex(const_GCB_LVT_name, true); zval const_GCB_T_value; ZVAL_LONG(&const_GCB_T_value, U_GCB_T); - zend_string *const_GCB_T_name = zend_string_init_interned("GCB_T", sizeof("GCB_T") - 1, 1); + zend_string *const_GCB_T_name = zend_string_init_interned("GCB_T", sizeof("GCB_T") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_T_name, &const_GCB_T_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_T_name); + zend_string_release_ex(const_GCB_T_name, true); zval const_GCB_V_value; ZVAL_LONG(&const_GCB_V_value, U_GCB_V); - zend_string *const_GCB_V_name = zend_string_init_interned("GCB_V", sizeof("GCB_V") - 1, 1); + zend_string *const_GCB_V_name = zend_string_init_interned("GCB_V", sizeof("GCB_V") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_V_name, &const_GCB_V_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_V_name); + zend_string_release_ex(const_GCB_V_name, true); zval const_GCB_SPACING_MARK_value; ZVAL_LONG(&const_GCB_SPACING_MARK_value, U_GCB_SPACING_MARK); - zend_string *const_GCB_SPACING_MARK_name = zend_string_init_interned("GCB_SPACING_MARK", sizeof("GCB_SPACING_MARK") - 1, 1); + zend_string *const_GCB_SPACING_MARK_name = zend_string_init_interned("GCB_SPACING_MARK", sizeof("GCB_SPACING_MARK") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_SPACING_MARK_name, &const_GCB_SPACING_MARK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_SPACING_MARK_name); + zend_string_release_ex(const_GCB_SPACING_MARK_name, true); zval const_GCB_PREPEND_value; ZVAL_LONG(&const_GCB_PREPEND_value, U_GCB_PREPEND); - zend_string *const_GCB_PREPEND_name = zend_string_init_interned("GCB_PREPEND", sizeof("GCB_PREPEND") - 1, 1); + zend_string *const_GCB_PREPEND_name = zend_string_init_interned("GCB_PREPEND", sizeof("GCB_PREPEND") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_PREPEND_name, &const_GCB_PREPEND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_PREPEND_name); + zend_string_release_ex(const_GCB_PREPEND_name, true); zval const_GCB_REGIONAL_INDICATOR_value; ZVAL_LONG(&const_GCB_REGIONAL_INDICATOR_value, U_GCB_REGIONAL_INDICATOR); - zend_string *const_GCB_REGIONAL_INDICATOR_name = zend_string_init_interned("GCB_REGIONAL_INDICATOR", sizeof("GCB_REGIONAL_INDICATOR") - 1, 1); + zend_string *const_GCB_REGIONAL_INDICATOR_name = zend_string_init_interned("GCB_REGIONAL_INDICATOR", sizeof("GCB_REGIONAL_INDICATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_REGIONAL_INDICATOR_name, &const_GCB_REGIONAL_INDICATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_REGIONAL_INDICATOR_name); + zend_string_release_ex(const_GCB_REGIONAL_INDICATOR_name, true); zval const_GCB_COUNT_value; ZVAL_LONG(&const_GCB_COUNT_value, U_GCB_COUNT); - zend_string *const_GCB_COUNT_name = zend_string_init_interned("GCB_COUNT", sizeof("GCB_COUNT") - 1, 1); + zend_string *const_GCB_COUNT_name = zend_string_init_interned("GCB_COUNT", sizeof("GCB_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_GCB_COUNT_name, &const_GCB_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GCB_COUNT_name); + zend_string_release_ex(const_GCB_COUNT_name, true); zval const_WB_OTHER_value; ZVAL_LONG(&const_WB_OTHER_value, U_WB_OTHER); - zend_string *const_WB_OTHER_name = zend_string_init_interned("WB_OTHER", sizeof("WB_OTHER") - 1, 1); + zend_string *const_WB_OTHER_name = zend_string_init_interned("WB_OTHER", sizeof("WB_OTHER") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_OTHER_name, &const_WB_OTHER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_OTHER_name); + zend_string_release_ex(const_WB_OTHER_name, true); zval const_WB_ALETTER_value; ZVAL_LONG(&const_WB_ALETTER_value, U_WB_ALETTER); - zend_string *const_WB_ALETTER_name = zend_string_init_interned("WB_ALETTER", sizeof("WB_ALETTER") - 1, 1); + zend_string *const_WB_ALETTER_name = zend_string_init_interned("WB_ALETTER", sizeof("WB_ALETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_ALETTER_name, &const_WB_ALETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_ALETTER_name); + zend_string_release_ex(const_WB_ALETTER_name, true); zval const_WB_FORMAT_value; ZVAL_LONG(&const_WB_FORMAT_value, U_WB_FORMAT); - zend_string *const_WB_FORMAT_name = zend_string_init_interned("WB_FORMAT", sizeof("WB_FORMAT") - 1, 1); + zend_string *const_WB_FORMAT_name = zend_string_init_interned("WB_FORMAT", sizeof("WB_FORMAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_FORMAT_name, &const_WB_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_FORMAT_name); + zend_string_release_ex(const_WB_FORMAT_name, true); zval const_WB_KATAKANA_value; ZVAL_LONG(&const_WB_KATAKANA_value, U_WB_KATAKANA); - zend_string *const_WB_KATAKANA_name = zend_string_init_interned("WB_KATAKANA", sizeof("WB_KATAKANA") - 1, 1); + zend_string *const_WB_KATAKANA_name = zend_string_init_interned("WB_KATAKANA", sizeof("WB_KATAKANA") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_KATAKANA_name, &const_WB_KATAKANA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_KATAKANA_name); + zend_string_release_ex(const_WB_KATAKANA_name, true); zval const_WB_MIDLETTER_value; ZVAL_LONG(&const_WB_MIDLETTER_value, U_WB_MIDLETTER); - zend_string *const_WB_MIDLETTER_name = zend_string_init_interned("WB_MIDLETTER", sizeof("WB_MIDLETTER") - 1, 1); + zend_string *const_WB_MIDLETTER_name = zend_string_init_interned("WB_MIDLETTER", sizeof("WB_MIDLETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_MIDLETTER_name, &const_WB_MIDLETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_MIDLETTER_name); + zend_string_release_ex(const_WB_MIDLETTER_name, true); zval const_WB_MIDNUM_value; ZVAL_LONG(&const_WB_MIDNUM_value, U_WB_MIDNUM); - zend_string *const_WB_MIDNUM_name = zend_string_init_interned("WB_MIDNUM", sizeof("WB_MIDNUM") - 1, 1); + zend_string *const_WB_MIDNUM_name = zend_string_init_interned("WB_MIDNUM", sizeof("WB_MIDNUM") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_MIDNUM_name, &const_WB_MIDNUM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_MIDNUM_name); + zend_string_release_ex(const_WB_MIDNUM_name, true); zval const_WB_NUMERIC_value; ZVAL_LONG(&const_WB_NUMERIC_value, U_WB_NUMERIC); - zend_string *const_WB_NUMERIC_name = zend_string_init_interned("WB_NUMERIC", sizeof("WB_NUMERIC") - 1, 1); + zend_string *const_WB_NUMERIC_name = zend_string_init_interned("WB_NUMERIC", sizeof("WB_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_NUMERIC_name, &const_WB_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_NUMERIC_name); + zend_string_release_ex(const_WB_NUMERIC_name, true); zval const_WB_EXTENDNUMLET_value; ZVAL_LONG(&const_WB_EXTENDNUMLET_value, U_WB_EXTENDNUMLET); - zend_string *const_WB_EXTENDNUMLET_name = zend_string_init_interned("WB_EXTENDNUMLET", sizeof("WB_EXTENDNUMLET") - 1, 1); + zend_string *const_WB_EXTENDNUMLET_name = zend_string_init_interned("WB_EXTENDNUMLET", sizeof("WB_EXTENDNUMLET") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_EXTENDNUMLET_name, &const_WB_EXTENDNUMLET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_EXTENDNUMLET_name); + zend_string_release_ex(const_WB_EXTENDNUMLET_name, true); zval const_WB_CR_value; ZVAL_LONG(&const_WB_CR_value, U_WB_CR); - zend_string *const_WB_CR_name = zend_string_init_interned("WB_CR", sizeof("WB_CR") - 1, 1); + zend_string *const_WB_CR_name = zend_string_init_interned("WB_CR", sizeof("WB_CR") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_CR_name, &const_WB_CR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_CR_name); + zend_string_release_ex(const_WB_CR_name, true); zval const_WB_EXTEND_value; ZVAL_LONG(&const_WB_EXTEND_value, U_WB_EXTEND); - zend_string *const_WB_EXTEND_name = zend_string_init_interned("WB_EXTEND", sizeof("WB_EXTEND") - 1, 1); + zend_string *const_WB_EXTEND_name = zend_string_init_interned("WB_EXTEND", sizeof("WB_EXTEND") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_EXTEND_name, &const_WB_EXTEND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_EXTEND_name); + zend_string_release_ex(const_WB_EXTEND_name, true); zval const_WB_LF_value; ZVAL_LONG(&const_WB_LF_value, U_WB_LF); - zend_string *const_WB_LF_name = zend_string_init_interned("WB_LF", sizeof("WB_LF") - 1, 1); + zend_string *const_WB_LF_name = zend_string_init_interned("WB_LF", sizeof("WB_LF") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_LF_name, &const_WB_LF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_LF_name); + zend_string_release_ex(const_WB_LF_name, true); zval const_WB_MIDNUMLET_value; ZVAL_LONG(&const_WB_MIDNUMLET_value, U_WB_MIDNUMLET); - zend_string *const_WB_MIDNUMLET_name = zend_string_init_interned("WB_MIDNUMLET", sizeof("WB_MIDNUMLET") - 1, 1); + zend_string *const_WB_MIDNUMLET_name = zend_string_init_interned("WB_MIDNUMLET", sizeof("WB_MIDNUMLET") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_MIDNUMLET_name, &const_WB_MIDNUMLET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_MIDNUMLET_name); + zend_string_release_ex(const_WB_MIDNUMLET_name, true); zval const_WB_NEWLINE_value; ZVAL_LONG(&const_WB_NEWLINE_value, U_WB_NEWLINE); - zend_string *const_WB_NEWLINE_name = zend_string_init_interned("WB_NEWLINE", sizeof("WB_NEWLINE") - 1, 1); + zend_string *const_WB_NEWLINE_name = zend_string_init_interned("WB_NEWLINE", sizeof("WB_NEWLINE") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_NEWLINE_name, &const_WB_NEWLINE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_NEWLINE_name); + zend_string_release_ex(const_WB_NEWLINE_name, true); zval const_WB_REGIONAL_INDICATOR_value; ZVAL_LONG(&const_WB_REGIONAL_INDICATOR_value, U_WB_REGIONAL_INDICATOR); - zend_string *const_WB_REGIONAL_INDICATOR_name = zend_string_init_interned("WB_REGIONAL_INDICATOR", sizeof("WB_REGIONAL_INDICATOR") - 1, 1); + zend_string *const_WB_REGIONAL_INDICATOR_name = zend_string_init_interned("WB_REGIONAL_INDICATOR", sizeof("WB_REGIONAL_INDICATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_REGIONAL_INDICATOR_name, &const_WB_REGIONAL_INDICATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_REGIONAL_INDICATOR_name); + zend_string_release_ex(const_WB_REGIONAL_INDICATOR_name, true); zval const_WB_HEBREW_LETTER_value; ZVAL_LONG(&const_WB_HEBREW_LETTER_value, U_WB_HEBREW_LETTER); - zend_string *const_WB_HEBREW_LETTER_name = zend_string_init_interned("WB_HEBREW_LETTER", sizeof("WB_HEBREW_LETTER") - 1, 1); + zend_string *const_WB_HEBREW_LETTER_name = zend_string_init_interned("WB_HEBREW_LETTER", sizeof("WB_HEBREW_LETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_HEBREW_LETTER_name, &const_WB_HEBREW_LETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_HEBREW_LETTER_name); + zend_string_release_ex(const_WB_HEBREW_LETTER_name, true); zval const_WB_SINGLE_QUOTE_value; ZVAL_LONG(&const_WB_SINGLE_QUOTE_value, U_WB_SINGLE_QUOTE); - zend_string *const_WB_SINGLE_QUOTE_name = zend_string_init_interned("WB_SINGLE_QUOTE", sizeof("WB_SINGLE_QUOTE") - 1, 1); + zend_string *const_WB_SINGLE_QUOTE_name = zend_string_init_interned("WB_SINGLE_QUOTE", sizeof("WB_SINGLE_QUOTE") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_SINGLE_QUOTE_name, &const_WB_SINGLE_QUOTE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_SINGLE_QUOTE_name); + zend_string_release_ex(const_WB_SINGLE_QUOTE_name, true); zval const_WB_DOUBLE_QUOTE_value; ZVAL_LONG(&const_WB_DOUBLE_QUOTE_value, U_WB_DOUBLE_QUOTE); - zend_string *const_WB_DOUBLE_QUOTE_name = zend_string_init_interned("WB_DOUBLE_QUOTE", sizeof("WB_DOUBLE_QUOTE") - 1, 1); + zend_string *const_WB_DOUBLE_QUOTE_name = zend_string_init_interned("WB_DOUBLE_QUOTE", sizeof("WB_DOUBLE_QUOTE") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_DOUBLE_QUOTE_name, &const_WB_DOUBLE_QUOTE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_DOUBLE_QUOTE_name); + zend_string_release_ex(const_WB_DOUBLE_QUOTE_name, true); zval const_WB_COUNT_value; ZVAL_LONG(&const_WB_COUNT_value, U_WB_COUNT); - zend_string *const_WB_COUNT_name = zend_string_init_interned("WB_COUNT", sizeof("WB_COUNT") - 1, 1); + zend_string *const_WB_COUNT_name = zend_string_init_interned("WB_COUNT", sizeof("WB_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_WB_COUNT_name, &const_WB_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WB_COUNT_name); + zend_string_release_ex(const_WB_COUNT_name, true); zval const_SB_OTHER_value; ZVAL_LONG(&const_SB_OTHER_value, U_SB_OTHER); - zend_string *const_SB_OTHER_name = zend_string_init_interned("SB_OTHER", sizeof("SB_OTHER") - 1, 1); + zend_string *const_SB_OTHER_name = zend_string_init_interned("SB_OTHER", sizeof("SB_OTHER") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_OTHER_name, &const_SB_OTHER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_OTHER_name); + zend_string_release_ex(const_SB_OTHER_name, true); zval const_SB_ATERM_value; ZVAL_LONG(&const_SB_ATERM_value, U_SB_ATERM); - zend_string *const_SB_ATERM_name = zend_string_init_interned("SB_ATERM", sizeof("SB_ATERM") - 1, 1); + zend_string *const_SB_ATERM_name = zend_string_init_interned("SB_ATERM", sizeof("SB_ATERM") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_ATERM_name, &const_SB_ATERM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_ATERM_name); + zend_string_release_ex(const_SB_ATERM_name, true); zval const_SB_CLOSE_value; ZVAL_LONG(&const_SB_CLOSE_value, U_SB_CLOSE); - zend_string *const_SB_CLOSE_name = zend_string_init_interned("SB_CLOSE", sizeof("SB_CLOSE") - 1, 1); + zend_string *const_SB_CLOSE_name = zend_string_init_interned("SB_CLOSE", sizeof("SB_CLOSE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_CLOSE_name, &const_SB_CLOSE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_CLOSE_name); + zend_string_release_ex(const_SB_CLOSE_name, true); zval const_SB_FORMAT_value; ZVAL_LONG(&const_SB_FORMAT_value, U_SB_FORMAT); - zend_string *const_SB_FORMAT_name = zend_string_init_interned("SB_FORMAT", sizeof("SB_FORMAT") - 1, 1); + zend_string *const_SB_FORMAT_name = zend_string_init_interned("SB_FORMAT", sizeof("SB_FORMAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_FORMAT_name, &const_SB_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_FORMAT_name); + zend_string_release_ex(const_SB_FORMAT_name, true); zval const_SB_LOWER_value; ZVAL_LONG(&const_SB_LOWER_value, U_SB_LOWER); - zend_string *const_SB_LOWER_name = zend_string_init_interned("SB_LOWER", sizeof("SB_LOWER") - 1, 1); + zend_string *const_SB_LOWER_name = zend_string_init_interned("SB_LOWER", sizeof("SB_LOWER") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_LOWER_name, &const_SB_LOWER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_LOWER_name); + zend_string_release_ex(const_SB_LOWER_name, true); zval const_SB_NUMERIC_value; ZVAL_LONG(&const_SB_NUMERIC_value, U_SB_NUMERIC); - zend_string *const_SB_NUMERIC_name = zend_string_init_interned("SB_NUMERIC", sizeof("SB_NUMERIC") - 1, 1); + zend_string *const_SB_NUMERIC_name = zend_string_init_interned("SB_NUMERIC", sizeof("SB_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_NUMERIC_name, &const_SB_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_NUMERIC_name); + zend_string_release_ex(const_SB_NUMERIC_name, true); zval const_SB_OLETTER_value; ZVAL_LONG(&const_SB_OLETTER_value, U_SB_OLETTER); - zend_string *const_SB_OLETTER_name = zend_string_init_interned("SB_OLETTER", sizeof("SB_OLETTER") - 1, 1); + zend_string *const_SB_OLETTER_name = zend_string_init_interned("SB_OLETTER", sizeof("SB_OLETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_OLETTER_name, &const_SB_OLETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_OLETTER_name); + zend_string_release_ex(const_SB_OLETTER_name, true); zval const_SB_SEP_value; ZVAL_LONG(&const_SB_SEP_value, U_SB_SEP); - zend_string *const_SB_SEP_name = zend_string_init_interned("SB_SEP", sizeof("SB_SEP") - 1, 1); + zend_string *const_SB_SEP_name = zend_string_init_interned("SB_SEP", sizeof("SB_SEP") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_SEP_name, &const_SB_SEP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_SEP_name); + zend_string_release_ex(const_SB_SEP_name, true); zval const_SB_SP_value; ZVAL_LONG(&const_SB_SP_value, U_SB_SP); - zend_string *const_SB_SP_name = zend_string_init_interned("SB_SP", sizeof("SB_SP") - 1, 1); + zend_string *const_SB_SP_name = zend_string_init_interned("SB_SP", sizeof("SB_SP") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_SP_name, &const_SB_SP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_SP_name); + zend_string_release_ex(const_SB_SP_name, true); zval const_SB_STERM_value; ZVAL_LONG(&const_SB_STERM_value, U_SB_STERM); - zend_string *const_SB_STERM_name = zend_string_init_interned("SB_STERM", sizeof("SB_STERM") - 1, 1); + zend_string *const_SB_STERM_name = zend_string_init_interned("SB_STERM", sizeof("SB_STERM") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_STERM_name, &const_SB_STERM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_STERM_name); + zend_string_release_ex(const_SB_STERM_name, true); zval const_SB_UPPER_value; ZVAL_LONG(&const_SB_UPPER_value, U_SB_UPPER); - zend_string *const_SB_UPPER_name = zend_string_init_interned("SB_UPPER", sizeof("SB_UPPER") - 1, 1); + zend_string *const_SB_UPPER_name = zend_string_init_interned("SB_UPPER", sizeof("SB_UPPER") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_UPPER_name, &const_SB_UPPER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_UPPER_name); + zend_string_release_ex(const_SB_UPPER_name, true); zval const_SB_CR_value; ZVAL_LONG(&const_SB_CR_value, U_SB_CR); - zend_string *const_SB_CR_name = zend_string_init_interned("SB_CR", sizeof("SB_CR") - 1, 1); + zend_string *const_SB_CR_name = zend_string_init_interned("SB_CR", sizeof("SB_CR") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_CR_name, &const_SB_CR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_CR_name); + zend_string_release_ex(const_SB_CR_name, true); zval const_SB_EXTEND_value; ZVAL_LONG(&const_SB_EXTEND_value, U_SB_EXTEND); - zend_string *const_SB_EXTEND_name = zend_string_init_interned("SB_EXTEND", sizeof("SB_EXTEND") - 1, 1); + zend_string *const_SB_EXTEND_name = zend_string_init_interned("SB_EXTEND", sizeof("SB_EXTEND") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_EXTEND_name, &const_SB_EXTEND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_EXTEND_name); + zend_string_release_ex(const_SB_EXTEND_name, true); zval const_SB_LF_value; ZVAL_LONG(&const_SB_LF_value, U_SB_LF); - zend_string *const_SB_LF_name = zend_string_init_interned("SB_LF", sizeof("SB_LF") - 1, 1); + zend_string *const_SB_LF_name = zend_string_init_interned("SB_LF", sizeof("SB_LF") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_LF_name, &const_SB_LF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_LF_name); + zend_string_release_ex(const_SB_LF_name, true); zval const_SB_SCONTINUE_value; ZVAL_LONG(&const_SB_SCONTINUE_value, U_SB_SCONTINUE); - zend_string *const_SB_SCONTINUE_name = zend_string_init_interned("SB_SCONTINUE", sizeof("SB_SCONTINUE") - 1, 1); + zend_string *const_SB_SCONTINUE_name = zend_string_init_interned("SB_SCONTINUE", sizeof("SB_SCONTINUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_SCONTINUE_name, &const_SB_SCONTINUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_SCONTINUE_name); + zend_string_release_ex(const_SB_SCONTINUE_name, true); zval const_SB_COUNT_value; ZVAL_LONG(&const_SB_COUNT_value, U_SB_COUNT); - zend_string *const_SB_COUNT_name = zend_string_init_interned("SB_COUNT", sizeof("SB_COUNT") - 1, 1); + zend_string *const_SB_COUNT_name = zend_string_init_interned("SB_COUNT", sizeof("SB_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SB_COUNT_name, &const_SB_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SB_COUNT_name); + zend_string_release_ex(const_SB_COUNT_name, true); zval const_LB_UNKNOWN_value; ZVAL_LONG(&const_LB_UNKNOWN_value, U_LB_UNKNOWN); - zend_string *const_LB_UNKNOWN_name = zend_string_init_interned("LB_UNKNOWN", sizeof("LB_UNKNOWN") - 1, 1); + zend_string *const_LB_UNKNOWN_name = zend_string_init_interned("LB_UNKNOWN", sizeof("LB_UNKNOWN") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_UNKNOWN_name, &const_LB_UNKNOWN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_UNKNOWN_name); + zend_string_release_ex(const_LB_UNKNOWN_name, true); zval const_LB_AMBIGUOUS_value; ZVAL_LONG(&const_LB_AMBIGUOUS_value, U_LB_AMBIGUOUS); - zend_string *const_LB_AMBIGUOUS_name = zend_string_init_interned("LB_AMBIGUOUS", sizeof("LB_AMBIGUOUS") - 1, 1); + zend_string *const_LB_AMBIGUOUS_name = zend_string_init_interned("LB_AMBIGUOUS", sizeof("LB_AMBIGUOUS") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_AMBIGUOUS_name, &const_LB_AMBIGUOUS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_AMBIGUOUS_name); + zend_string_release_ex(const_LB_AMBIGUOUS_name, true); zval const_LB_ALPHABETIC_value; ZVAL_LONG(&const_LB_ALPHABETIC_value, U_LB_ALPHABETIC); - zend_string *const_LB_ALPHABETIC_name = zend_string_init_interned("LB_ALPHABETIC", sizeof("LB_ALPHABETIC") - 1, 1); + zend_string *const_LB_ALPHABETIC_name = zend_string_init_interned("LB_ALPHABETIC", sizeof("LB_ALPHABETIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_ALPHABETIC_name, &const_LB_ALPHABETIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_ALPHABETIC_name); + zend_string_release_ex(const_LB_ALPHABETIC_name, true); zval const_LB_BREAK_BOTH_value; ZVAL_LONG(&const_LB_BREAK_BOTH_value, U_LB_BREAK_BOTH); - zend_string *const_LB_BREAK_BOTH_name = zend_string_init_interned("LB_BREAK_BOTH", sizeof("LB_BREAK_BOTH") - 1, 1); + zend_string *const_LB_BREAK_BOTH_name = zend_string_init_interned("LB_BREAK_BOTH", sizeof("LB_BREAK_BOTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_BREAK_BOTH_name, &const_LB_BREAK_BOTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_BREAK_BOTH_name); + zend_string_release_ex(const_LB_BREAK_BOTH_name, true); zval const_LB_BREAK_AFTER_value; ZVAL_LONG(&const_LB_BREAK_AFTER_value, U_LB_BREAK_AFTER); - zend_string *const_LB_BREAK_AFTER_name = zend_string_init_interned("LB_BREAK_AFTER", sizeof("LB_BREAK_AFTER") - 1, 1); + zend_string *const_LB_BREAK_AFTER_name = zend_string_init_interned("LB_BREAK_AFTER", sizeof("LB_BREAK_AFTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_BREAK_AFTER_name, &const_LB_BREAK_AFTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_BREAK_AFTER_name); + zend_string_release_ex(const_LB_BREAK_AFTER_name, true); zval const_LB_BREAK_BEFORE_value; ZVAL_LONG(&const_LB_BREAK_BEFORE_value, U_LB_BREAK_BEFORE); - zend_string *const_LB_BREAK_BEFORE_name = zend_string_init_interned("LB_BREAK_BEFORE", sizeof("LB_BREAK_BEFORE") - 1, 1); + zend_string *const_LB_BREAK_BEFORE_name = zend_string_init_interned("LB_BREAK_BEFORE", sizeof("LB_BREAK_BEFORE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_BREAK_BEFORE_name, &const_LB_BREAK_BEFORE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_BREAK_BEFORE_name); + zend_string_release_ex(const_LB_BREAK_BEFORE_name, true); zval const_LB_MANDATORY_BREAK_value; ZVAL_LONG(&const_LB_MANDATORY_BREAK_value, U_LB_MANDATORY_BREAK); - zend_string *const_LB_MANDATORY_BREAK_name = zend_string_init_interned("LB_MANDATORY_BREAK", sizeof("LB_MANDATORY_BREAK") - 1, 1); + zend_string *const_LB_MANDATORY_BREAK_name = zend_string_init_interned("LB_MANDATORY_BREAK", sizeof("LB_MANDATORY_BREAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_MANDATORY_BREAK_name, &const_LB_MANDATORY_BREAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_MANDATORY_BREAK_name); + zend_string_release_ex(const_LB_MANDATORY_BREAK_name, true); zval const_LB_CONTINGENT_BREAK_value; ZVAL_LONG(&const_LB_CONTINGENT_BREAK_value, U_LB_CONTINGENT_BREAK); - zend_string *const_LB_CONTINGENT_BREAK_name = zend_string_init_interned("LB_CONTINGENT_BREAK", sizeof("LB_CONTINGENT_BREAK") - 1, 1); + zend_string *const_LB_CONTINGENT_BREAK_name = zend_string_init_interned("LB_CONTINGENT_BREAK", sizeof("LB_CONTINGENT_BREAK") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_CONTINGENT_BREAK_name, &const_LB_CONTINGENT_BREAK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_CONTINGENT_BREAK_name); + zend_string_release_ex(const_LB_CONTINGENT_BREAK_name, true); zval const_LB_CLOSE_PUNCTUATION_value; ZVAL_LONG(&const_LB_CLOSE_PUNCTUATION_value, U_LB_CLOSE_PUNCTUATION); - zend_string *const_LB_CLOSE_PUNCTUATION_name = zend_string_init_interned("LB_CLOSE_PUNCTUATION", sizeof("LB_CLOSE_PUNCTUATION") - 1, 1); + zend_string *const_LB_CLOSE_PUNCTUATION_name = zend_string_init_interned("LB_CLOSE_PUNCTUATION", sizeof("LB_CLOSE_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_CLOSE_PUNCTUATION_name, &const_LB_CLOSE_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_CLOSE_PUNCTUATION_name); + zend_string_release_ex(const_LB_CLOSE_PUNCTUATION_name, true); zval const_LB_COMBINING_MARK_value; ZVAL_LONG(&const_LB_COMBINING_MARK_value, U_LB_COMBINING_MARK); - zend_string *const_LB_COMBINING_MARK_name = zend_string_init_interned("LB_COMBINING_MARK", sizeof("LB_COMBINING_MARK") - 1, 1); + zend_string *const_LB_COMBINING_MARK_name = zend_string_init_interned("LB_COMBINING_MARK", sizeof("LB_COMBINING_MARK") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_COMBINING_MARK_name, &const_LB_COMBINING_MARK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_COMBINING_MARK_name); + zend_string_release_ex(const_LB_COMBINING_MARK_name, true); zval const_LB_CARRIAGE_RETURN_value; ZVAL_LONG(&const_LB_CARRIAGE_RETURN_value, U_LB_CARRIAGE_RETURN); - zend_string *const_LB_CARRIAGE_RETURN_name = zend_string_init_interned("LB_CARRIAGE_RETURN", sizeof("LB_CARRIAGE_RETURN") - 1, 1); + zend_string *const_LB_CARRIAGE_RETURN_name = zend_string_init_interned("LB_CARRIAGE_RETURN", sizeof("LB_CARRIAGE_RETURN") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_CARRIAGE_RETURN_name, &const_LB_CARRIAGE_RETURN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_CARRIAGE_RETURN_name); + zend_string_release_ex(const_LB_CARRIAGE_RETURN_name, true); zval const_LB_EXCLAMATION_value; ZVAL_LONG(&const_LB_EXCLAMATION_value, U_LB_EXCLAMATION); - zend_string *const_LB_EXCLAMATION_name = zend_string_init_interned("LB_EXCLAMATION", sizeof("LB_EXCLAMATION") - 1, 1); + zend_string *const_LB_EXCLAMATION_name = zend_string_init_interned("LB_EXCLAMATION", sizeof("LB_EXCLAMATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_EXCLAMATION_name, &const_LB_EXCLAMATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_EXCLAMATION_name); + zend_string_release_ex(const_LB_EXCLAMATION_name, true); zval const_LB_GLUE_value; ZVAL_LONG(&const_LB_GLUE_value, U_LB_GLUE); - zend_string *const_LB_GLUE_name = zend_string_init_interned("LB_GLUE", sizeof("LB_GLUE") - 1, 1); + zend_string *const_LB_GLUE_name = zend_string_init_interned("LB_GLUE", sizeof("LB_GLUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_GLUE_name, &const_LB_GLUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_GLUE_name); + zend_string_release_ex(const_LB_GLUE_name, true); zval const_LB_HYPHEN_value; ZVAL_LONG(&const_LB_HYPHEN_value, U_LB_HYPHEN); - zend_string *const_LB_HYPHEN_name = zend_string_init_interned("LB_HYPHEN", sizeof("LB_HYPHEN") - 1, 1); + zend_string *const_LB_HYPHEN_name = zend_string_init_interned("LB_HYPHEN", sizeof("LB_HYPHEN") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_HYPHEN_name, &const_LB_HYPHEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_HYPHEN_name); + zend_string_release_ex(const_LB_HYPHEN_name, true); zval const_LB_IDEOGRAPHIC_value; ZVAL_LONG(&const_LB_IDEOGRAPHIC_value, U_LB_IDEOGRAPHIC); - zend_string *const_LB_IDEOGRAPHIC_name = zend_string_init_interned("LB_IDEOGRAPHIC", sizeof("LB_IDEOGRAPHIC") - 1, 1); + zend_string *const_LB_IDEOGRAPHIC_name = zend_string_init_interned("LB_IDEOGRAPHIC", sizeof("LB_IDEOGRAPHIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_IDEOGRAPHIC_name, &const_LB_IDEOGRAPHIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_IDEOGRAPHIC_name); + zend_string_release_ex(const_LB_IDEOGRAPHIC_name, true); zval const_LB_INSEPARABLE_value; ZVAL_LONG(&const_LB_INSEPARABLE_value, U_LB_INSEPARABLE); - zend_string *const_LB_INSEPARABLE_name = zend_string_init_interned("LB_INSEPARABLE", sizeof("LB_INSEPARABLE") - 1, 1); + zend_string *const_LB_INSEPARABLE_name = zend_string_init_interned("LB_INSEPARABLE", sizeof("LB_INSEPARABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_INSEPARABLE_name, &const_LB_INSEPARABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_INSEPARABLE_name); + zend_string_release_ex(const_LB_INSEPARABLE_name, true); zval const_LB_INSEPERABLE_value; ZVAL_LONG(&const_LB_INSEPERABLE_value, U_LB_INSEPERABLE); - zend_string *const_LB_INSEPERABLE_name = zend_string_init_interned("LB_INSEPERABLE", sizeof("LB_INSEPERABLE") - 1, 1); + zend_string *const_LB_INSEPERABLE_name = zend_string_init_interned("LB_INSEPERABLE", sizeof("LB_INSEPERABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_INSEPERABLE_name, &const_LB_INSEPERABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_INSEPERABLE_name); + zend_string_release_ex(const_LB_INSEPERABLE_name, true); zval const_LB_INFIX_NUMERIC_value; ZVAL_LONG(&const_LB_INFIX_NUMERIC_value, U_LB_INFIX_NUMERIC); - zend_string *const_LB_INFIX_NUMERIC_name = zend_string_init_interned("LB_INFIX_NUMERIC", sizeof("LB_INFIX_NUMERIC") - 1, 1); + zend_string *const_LB_INFIX_NUMERIC_name = zend_string_init_interned("LB_INFIX_NUMERIC", sizeof("LB_INFIX_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_INFIX_NUMERIC_name, &const_LB_INFIX_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_INFIX_NUMERIC_name); + zend_string_release_ex(const_LB_INFIX_NUMERIC_name, true); zval const_LB_LINE_FEED_value; ZVAL_LONG(&const_LB_LINE_FEED_value, U_LB_LINE_FEED); - zend_string *const_LB_LINE_FEED_name = zend_string_init_interned("LB_LINE_FEED", sizeof("LB_LINE_FEED") - 1, 1); + zend_string *const_LB_LINE_FEED_name = zend_string_init_interned("LB_LINE_FEED", sizeof("LB_LINE_FEED") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_LINE_FEED_name, &const_LB_LINE_FEED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_LINE_FEED_name); + zend_string_release_ex(const_LB_LINE_FEED_name, true); zval const_LB_NONSTARTER_value; ZVAL_LONG(&const_LB_NONSTARTER_value, U_LB_NONSTARTER); - zend_string *const_LB_NONSTARTER_name = zend_string_init_interned("LB_NONSTARTER", sizeof("LB_NONSTARTER") - 1, 1); + zend_string *const_LB_NONSTARTER_name = zend_string_init_interned("LB_NONSTARTER", sizeof("LB_NONSTARTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_NONSTARTER_name, &const_LB_NONSTARTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_NONSTARTER_name); + zend_string_release_ex(const_LB_NONSTARTER_name, true); zval const_LB_NUMERIC_value; ZVAL_LONG(&const_LB_NUMERIC_value, U_LB_NUMERIC); - zend_string *const_LB_NUMERIC_name = zend_string_init_interned("LB_NUMERIC", sizeof("LB_NUMERIC") - 1, 1); + zend_string *const_LB_NUMERIC_name = zend_string_init_interned("LB_NUMERIC", sizeof("LB_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_NUMERIC_name, &const_LB_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_NUMERIC_name); + zend_string_release_ex(const_LB_NUMERIC_name, true); zval const_LB_OPEN_PUNCTUATION_value; ZVAL_LONG(&const_LB_OPEN_PUNCTUATION_value, U_LB_OPEN_PUNCTUATION); - zend_string *const_LB_OPEN_PUNCTUATION_name = zend_string_init_interned("LB_OPEN_PUNCTUATION", sizeof("LB_OPEN_PUNCTUATION") - 1, 1); + zend_string *const_LB_OPEN_PUNCTUATION_name = zend_string_init_interned("LB_OPEN_PUNCTUATION", sizeof("LB_OPEN_PUNCTUATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_OPEN_PUNCTUATION_name, &const_LB_OPEN_PUNCTUATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_OPEN_PUNCTUATION_name); + zend_string_release_ex(const_LB_OPEN_PUNCTUATION_name, true); zval const_LB_POSTFIX_NUMERIC_value; ZVAL_LONG(&const_LB_POSTFIX_NUMERIC_value, U_LB_POSTFIX_NUMERIC); - zend_string *const_LB_POSTFIX_NUMERIC_name = zend_string_init_interned("LB_POSTFIX_NUMERIC", sizeof("LB_POSTFIX_NUMERIC") - 1, 1); + zend_string *const_LB_POSTFIX_NUMERIC_name = zend_string_init_interned("LB_POSTFIX_NUMERIC", sizeof("LB_POSTFIX_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_POSTFIX_NUMERIC_name, &const_LB_POSTFIX_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_POSTFIX_NUMERIC_name); + zend_string_release_ex(const_LB_POSTFIX_NUMERIC_name, true); zval const_LB_PREFIX_NUMERIC_value; ZVAL_LONG(&const_LB_PREFIX_NUMERIC_value, U_LB_PREFIX_NUMERIC); - zend_string *const_LB_PREFIX_NUMERIC_name = zend_string_init_interned("LB_PREFIX_NUMERIC", sizeof("LB_PREFIX_NUMERIC") - 1, 1); + zend_string *const_LB_PREFIX_NUMERIC_name = zend_string_init_interned("LB_PREFIX_NUMERIC", sizeof("LB_PREFIX_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_PREFIX_NUMERIC_name, &const_LB_PREFIX_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_PREFIX_NUMERIC_name); + zend_string_release_ex(const_LB_PREFIX_NUMERIC_name, true); zval const_LB_QUOTATION_value; ZVAL_LONG(&const_LB_QUOTATION_value, U_LB_QUOTATION); - zend_string *const_LB_QUOTATION_name = zend_string_init_interned("LB_QUOTATION", sizeof("LB_QUOTATION") - 1, 1); + zend_string *const_LB_QUOTATION_name = zend_string_init_interned("LB_QUOTATION", sizeof("LB_QUOTATION") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_QUOTATION_name, &const_LB_QUOTATION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_QUOTATION_name); + zend_string_release_ex(const_LB_QUOTATION_name, true); zval const_LB_COMPLEX_CONTEXT_value; ZVAL_LONG(&const_LB_COMPLEX_CONTEXT_value, U_LB_COMPLEX_CONTEXT); - zend_string *const_LB_COMPLEX_CONTEXT_name = zend_string_init_interned("LB_COMPLEX_CONTEXT", sizeof("LB_COMPLEX_CONTEXT") - 1, 1); + zend_string *const_LB_COMPLEX_CONTEXT_name = zend_string_init_interned("LB_COMPLEX_CONTEXT", sizeof("LB_COMPLEX_CONTEXT") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_COMPLEX_CONTEXT_name, &const_LB_COMPLEX_CONTEXT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_COMPLEX_CONTEXT_name); + zend_string_release_ex(const_LB_COMPLEX_CONTEXT_name, true); zval const_LB_SURROGATE_value; ZVAL_LONG(&const_LB_SURROGATE_value, U_LB_SURROGATE); - zend_string *const_LB_SURROGATE_name = zend_string_init_interned("LB_SURROGATE", sizeof("LB_SURROGATE") - 1, 1); + zend_string *const_LB_SURROGATE_name = zend_string_init_interned("LB_SURROGATE", sizeof("LB_SURROGATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_SURROGATE_name, &const_LB_SURROGATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_SURROGATE_name); + zend_string_release_ex(const_LB_SURROGATE_name, true); zval const_LB_SPACE_value; ZVAL_LONG(&const_LB_SPACE_value, U_LB_SPACE); - zend_string *const_LB_SPACE_name = zend_string_init_interned("LB_SPACE", sizeof("LB_SPACE") - 1, 1); + zend_string *const_LB_SPACE_name = zend_string_init_interned("LB_SPACE", sizeof("LB_SPACE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_SPACE_name, &const_LB_SPACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_SPACE_name); + zend_string_release_ex(const_LB_SPACE_name, true); zval const_LB_BREAK_SYMBOLS_value; ZVAL_LONG(&const_LB_BREAK_SYMBOLS_value, U_LB_BREAK_SYMBOLS); - zend_string *const_LB_BREAK_SYMBOLS_name = zend_string_init_interned("LB_BREAK_SYMBOLS", sizeof("LB_BREAK_SYMBOLS") - 1, 1); + zend_string *const_LB_BREAK_SYMBOLS_name = zend_string_init_interned("LB_BREAK_SYMBOLS", sizeof("LB_BREAK_SYMBOLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_BREAK_SYMBOLS_name, &const_LB_BREAK_SYMBOLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_BREAK_SYMBOLS_name); + zend_string_release_ex(const_LB_BREAK_SYMBOLS_name, true); zval const_LB_ZWSPACE_value; ZVAL_LONG(&const_LB_ZWSPACE_value, U_LB_ZWSPACE); - zend_string *const_LB_ZWSPACE_name = zend_string_init_interned("LB_ZWSPACE", sizeof("LB_ZWSPACE") - 1, 1); + zend_string *const_LB_ZWSPACE_name = zend_string_init_interned("LB_ZWSPACE", sizeof("LB_ZWSPACE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_ZWSPACE_name, &const_LB_ZWSPACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_ZWSPACE_name); + zend_string_release_ex(const_LB_ZWSPACE_name, true); zval const_LB_NEXT_LINE_value; ZVAL_LONG(&const_LB_NEXT_LINE_value, U_LB_NEXT_LINE); - zend_string *const_LB_NEXT_LINE_name = zend_string_init_interned("LB_NEXT_LINE", sizeof("LB_NEXT_LINE") - 1, 1); + zend_string *const_LB_NEXT_LINE_name = zend_string_init_interned("LB_NEXT_LINE", sizeof("LB_NEXT_LINE") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_NEXT_LINE_name, &const_LB_NEXT_LINE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_NEXT_LINE_name); + zend_string_release_ex(const_LB_NEXT_LINE_name, true); zval const_LB_WORD_JOINER_value; ZVAL_LONG(&const_LB_WORD_JOINER_value, U_LB_WORD_JOINER); - zend_string *const_LB_WORD_JOINER_name = zend_string_init_interned("LB_WORD_JOINER", sizeof("LB_WORD_JOINER") - 1, 1); + zend_string *const_LB_WORD_JOINER_name = zend_string_init_interned("LB_WORD_JOINER", sizeof("LB_WORD_JOINER") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_WORD_JOINER_name, &const_LB_WORD_JOINER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_WORD_JOINER_name); + zend_string_release_ex(const_LB_WORD_JOINER_name, true); zval const_LB_H2_value; ZVAL_LONG(&const_LB_H2_value, U_LB_H2); - zend_string *const_LB_H2_name = zend_string_init_interned("LB_H2", sizeof("LB_H2") - 1, 1); + zend_string *const_LB_H2_name = zend_string_init_interned("LB_H2", sizeof("LB_H2") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_H2_name, &const_LB_H2_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_H2_name); + zend_string_release_ex(const_LB_H2_name, true); zval const_LB_H3_value; ZVAL_LONG(&const_LB_H3_value, U_LB_H3); - zend_string *const_LB_H3_name = zend_string_init_interned("LB_H3", sizeof("LB_H3") - 1, 1); + zend_string *const_LB_H3_name = zend_string_init_interned("LB_H3", sizeof("LB_H3") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_H3_name, &const_LB_H3_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_H3_name); + zend_string_release_ex(const_LB_H3_name, true); zval const_LB_JL_value; ZVAL_LONG(&const_LB_JL_value, U_LB_JL); - zend_string *const_LB_JL_name = zend_string_init_interned("LB_JL", sizeof("LB_JL") - 1, 1); + zend_string *const_LB_JL_name = zend_string_init_interned("LB_JL", sizeof("LB_JL") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_JL_name, &const_LB_JL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_JL_name); + zend_string_release_ex(const_LB_JL_name, true); zval const_LB_JT_value; ZVAL_LONG(&const_LB_JT_value, U_LB_JT); - zend_string *const_LB_JT_name = zend_string_init_interned("LB_JT", sizeof("LB_JT") - 1, 1); + zend_string *const_LB_JT_name = zend_string_init_interned("LB_JT", sizeof("LB_JT") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_JT_name, &const_LB_JT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_JT_name); + zend_string_release_ex(const_LB_JT_name, true); zval const_LB_JV_value; ZVAL_LONG(&const_LB_JV_value, U_LB_JV); - zend_string *const_LB_JV_name = zend_string_init_interned("LB_JV", sizeof("LB_JV") - 1, 1); + zend_string *const_LB_JV_name = zend_string_init_interned("LB_JV", sizeof("LB_JV") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_JV_name, &const_LB_JV_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_JV_name); + zend_string_release_ex(const_LB_JV_name, true); zval const_LB_CLOSE_PARENTHESIS_value; ZVAL_LONG(&const_LB_CLOSE_PARENTHESIS_value, U_LB_CLOSE_PARENTHESIS); - zend_string *const_LB_CLOSE_PARENTHESIS_name = zend_string_init_interned("LB_CLOSE_PARENTHESIS", sizeof("LB_CLOSE_PARENTHESIS") - 1, 1); + zend_string *const_LB_CLOSE_PARENTHESIS_name = zend_string_init_interned("LB_CLOSE_PARENTHESIS", sizeof("LB_CLOSE_PARENTHESIS") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_CLOSE_PARENTHESIS_name, &const_LB_CLOSE_PARENTHESIS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_CLOSE_PARENTHESIS_name); + zend_string_release_ex(const_LB_CLOSE_PARENTHESIS_name, true); zval const_LB_CONDITIONAL_JAPANESE_STARTER_value; ZVAL_LONG(&const_LB_CONDITIONAL_JAPANESE_STARTER_value, U_LB_CONDITIONAL_JAPANESE_STARTER); - zend_string *const_LB_CONDITIONAL_JAPANESE_STARTER_name = zend_string_init_interned("LB_CONDITIONAL_JAPANESE_STARTER", sizeof("LB_CONDITIONAL_JAPANESE_STARTER") - 1, 1); + zend_string *const_LB_CONDITIONAL_JAPANESE_STARTER_name = zend_string_init_interned("LB_CONDITIONAL_JAPANESE_STARTER", sizeof("LB_CONDITIONAL_JAPANESE_STARTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_CONDITIONAL_JAPANESE_STARTER_name, &const_LB_CONDITIONAL_JAPANESE_STARTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_CONDITIONAL_JAPANESE_STARTER_name); + zend_string_release_ex(const_LB_CONDITIONAL_JAPANESE_STARTER_name, true); zval const_LB_HEBREW_LETTER_value; ZVAL_LONG(&const_LB_HEBREW_LETTER_value, U_LB_HEBREW_LETTER); - zend_string *const_LB_HEBREW_LETTER_name = zend_string_init_interned("LB_HEBREW_LETTER", sizeof("LB_HEBREW_LETTER") - 1, 1); + zend_string *const_LB_HEBREW_LETTER_name = zend_string_init_interned("LB_HEBREW_LETTER", sizeof("LB_HEBREW_LETTER") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_HEBREW_LETTER_name, &const_LB_HEBREW_LETTER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_HEBREW_LETTER_name); + zend_string_release_ex(const_LB_HEBREW_LETTER_name, true); zval const_LB_REGIONAL_INDICATOR_value; ZVAL_LONG(&const_LB_REGIONAL_INDICATOR_value, U_LB_REGIONAL_INDICATOR); - zend_string *const_LB_REGIONAL_INDICATOR_name = zend_string_init_interned("LB_REGIONAL_INDICATOR", sizeof("LB_REGIONAL_INDICATOR") - 1, 1); + zend_string *const_LB_REGIONAL_INDICATOR_name = zend_string_init_interned("LB_REGIONAL_INDICATOR", sizeof("LB_REGIONAL_INDICATOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_REGIONAL_INDICATOR_name, &const_LB_REGIONAL_INDICATOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_REGIONAL_INDICATOR_name); + zend_string_release_ex(const_LB_REGIONAL_INDICATOR_name, true); zval const_LB_COUNT_value; ZVAL_LONG(&const_LB_COUNT_value, U_LB_COUNT); - zend_string *const_LB_COUNT_name = zend_string_init_interned("LB_COUNT", sizeof("LB_COUNT") - 1, 1); + zend_string *const_LB_COUNT_name = zend_string_init_interned("LB_COUNT", sizeof("LB_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_LB_COUNT_name, &const_LB_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LB_COUNT_name); + zend_string_release_ex(const_LB_COUNT_name, true); zval const_NT_NONE_value; ZVAL_LONG(&const_NT_NONE_value, U_NT_NONE); - zend_string *const_NT_NONE_name = zend_string_init_interned("NT_NONE", sizeof("NT_NONE") - 1, 1); + zend_string *const_NT_NONE_name = zend_string_init_interned("NT_NONE", sizeof("NT_NONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_NT_NONE_name, &const_NT_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NT_NONE_name); + zend_string_release_ex(const_NT_NONE_name, true); zval const_NT_DECIMAL_value; ZVAL_LONG(&const_NT_DECIMAL_value, U_NT_DECIMAL); - zend_string *const_NT_DECIMAL_name = zend_string_init_interned("NT_DECIMAL", sizeof("NT_DECIMAL") - 1, 1); + zend_string *const_NT_DECIMAL_name = zend_string_init_interned("NT_DECIMAL", sizeof("NT_DECIMAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_NT_DECIMAL_name, &const_NT_DECIMAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NT_DECIMAL_name); + zend_string_release_ex(const_NT_DECIMAL_name, true); zval const_NT_DIGIT_value; ZVAL_LONG(&const_NT_DIGIT_value, U_NT_DIGIT); - zend_string *const_NT_DIGIT_name = zend_string_init_interned("NT_DIGIT", sizeof("NT_DIGIT") - 1, 1); + zend_string *const_NT_DIGIT_name = zend_string_init_interned("NT_DIGIT", sizeof("NT_DIGIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_NT_DIGIT_name, &const_NT_DIGIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NT_DIGIT_name); + zend_string_release_ex(const_NT_DIGIT_name, true); zval const_NT_NUMERIC_value; ZVAL_LONG(&const_NT_NUMERIC_value, U_NT_NUMERIC); - zend_string *const_NT_NUMERIC_name = zend_string_init_interned("NT_NUMERIC", sizeof("NT_NUMERIC") - 1, 1); + zend_string *const_NT_NUMERIC_name = zend_string_init_interned("NT_NUMERIC", sizeof("NT_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_NT_NUMERIC_name, &const_NT_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NT_NUMERIC_name); + zend_string_release_ex(const_NT_NUMERIC_name, true); zval const_NT_COUNT_value; ZVAL_LONG(&const_NT_COUNT_value, U_NT_COUNT); - zend_string *const_NT_COUNT_name = zend_string_init_interned("NT_COUNT", sizeof("NT_COUNT") - 1, 1); + zend_string *const_NT_COUNT_name = zend_string_init_interned("NT_COUNT", sizeof("NT_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_NT_COUNT_name, &const_NT_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NT_COUNT_name); + zend_string_release_ex(const_NT_COUNT_name, true); zval const_HST_NOT_APPLICABLE_value; ZVAL_LONG(&const_HST_NOT_APPLICABLE_value, U_HST_NOT_APPLICABLE); - zend_string *const_HST_NOT_APPLICABLE_name = zend_string_init_interned("HST_NOT_APPLICABLE", sizeof("HST_NOT_APPLICABLE") - 1, 1); + zend_string *const_HST_NOT_APPLICABLE_name = zend_string_init_interned("HST_NOT_APPLICABLE", sizeof("HST_NOT_APPLICABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_HST_NOT_APPLICABLE_name, &const_HST_NOT_APPLICABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HST_NOT_APPLICABLE_name); + zend_string_release_ex(const_HST_NOT_APPLICABLE_name, true); zval const_HST_LEADING_JAMO_value; ZVAL_LONG(&const_HST_LEADING_JAMO_value, U_HST_LEADING_JAMO); - zend_string *const_HST_LEADING_JAMO_name = zend_string_init_interned("HST_LEADING_JAMO", sizeof("HST_LEADING_JAMO") - 1, 1); + zend_string *const_HST_LEADING_JAMO_name = zend_string_init_interned("HST_LEADING_JAMO", sizeof("HST_LEADING_JAMO") - 1, true); zend_declare_typed_class_constant(class_entry, const_HST_LEADING_JAMO_name, &const_HST_LEADING_JAMO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HST_LEADING_JAMO_name); + zend_string_release_ex(const_HST_LEADING_JAMO_name, true); zval const_HST_VOWEL_JAMO_value; ZVAL_LONG(&const_HST_VOWEL_JAMO_value, U_HST_VOWEL_JAMO); - zend_string *const_HST_VOWEL_JAMO_name = zend_string_init_interned("HST_VOWEL_JAMO", sizeof("HST_VOWEL_JAMO") - 1, 1); + zend_string *const_HST_VOWEL_JAMO_name = zend_string_init_interned("HST_VOWEL_JAMO", sizeof("HST_VOWEL_JAMO") - 1, true); zend_declare_typed_class_constant(class_entry, const_HST_VOWEL_JAMO_name, &const_HST_VOWEL_JAMO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HST_VOWEL_JAMO_name); + zend_string_release_ex(const_HST_VOWEL_JAMO_name, true); zval const_HST_TRAILING_JAMO_value; ZVAL_LONG(&const_HST_TRAILING_JAMO_value, U_HST_TRAILING_JAMO); - zend_string *const_HST_TRAILING_JAMO_name = zend_string_init_interned("HST_TRAILING_JAMO", sizeof("HST_TRAILING_JAMO") - 1, 1); + zend_string *const_HST_TRAILING_JAMO_name = zend_string_init_interned("HST_TRAILING_JAMO", sizeof("HST_TRAILING_JAMO") - 1, true); zend_declare_typed_class_constant(class_entry, const_HST_TRAILING_JAMO_name, &const_HST_TRAILING_JAMO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HST_TRAILING_JAMO_name); + zend_string_release_ex(const_HST_TRAILING_JAMO_name, true); zval const_HST_LV_SYLLABLE_value; ZVAL_LONG(&const_HST_LV_SYLLABLE_value, U_HST_LV_SYLLABLE); - zend_string *const_HST_LV_SYLLABLE_name = zend_string_init_interned("HST_LV_SYLLABLE", sizeof("HST_LV_SYLLABLE") - 1, 1); + zend_string *const_HST_LV_SYLLABLE_name = zend_string_init_interned("HST_LV_SYLLABLE", sizeof("HST_LV_SYLLABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_HST_LV_SYLLABLE_name, &const_HST_LV_SYLLABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HST_LV_SYLLABLE_name); + zend_string_release_ex(const_HST_LV_SYLLABLE_name, true); zval const_HST_LVT_SYLLABLE_value; ZVAL_LONG(&const_HST_LVT_SYLLABLE_value, U_HST_LVT_SYLLABLE); - zend_string *const_HST_LVT_SYLLABLE_name = zend_string_init_interned("HST_LVT_SYLLABLE", sizeof("HST_LVT_SYLLABLE") - 1, 1); + zend_string *const_HST_LVT_SYLLABLE_name = zend_string_init_interned("HST_LVT_SYLLABLE", sizeof("HST_LVT_SYLLABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_HST_LVT_SYLLABLE_name, &const_HST_LVT_SYLLABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HST_LVT_SYLLABLE_name); + zend_string_release_ex(const_HST_LVT_SYLLABLE_name, true); zval const_HST_COUNT_value; ZVAL_LONG(&const_HST_COUNT_value, U_HST_COUNT); - zend_string *const_HST_COUNT_name = zend_string_init_interned("HST_COUNT", sizeof("HST_COUNT") - 1, 1); + zend_string *const_HST_COUNT_name = zend_string_init_interned("HST_COUNT", sizeof("HST_COUNT") - 1, true); zend_declare_typed_class_constant(class_entry, const_HST_COUNT_name, &const_HST_COUNT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_HST_COUNT_name); + zend_string_release_ex(const_HST_COUNT_name, true); zval const_FOLD_CASE_DEFAULT_value; ZVAL_LONG(&const_FOLD_CASE_DEFAULT_value, U_FOLD_CASE_DEFAULT); - zend_string *const_FOLD_CASE_DEFAULT_name = zend_string_init_interned("FOLD_CASE_DEFAULT", sizeof("FOLD_CASE_DEFAULT") - 1, 1); + zend_string *const_FOLD_CASE_DEFAULT_name = zend_string_init_interned("FOLD_CASE_DEFAULT", sizeof("FOLD_CASE_DEFAULT") - 1, true); zend_declare_typed_class_constant(class_entry, const_FOLD_CASE_DEFAULT_name, &const_FOLD_CASE_DEFAULT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FOLD_CASE_DEFAULT_name); + zend_string_release_ex(const_FOLD_CASE_DEFAULT_name, true); zval const_FOLD_CASE_EXCLUDE_SPECIAL_I_value; ZVAL_LONG(&const_FOLD_CASE_EXCLUDE_SPECIAL_I_value, U_FOLD_CASE_EXCLUDE_SPECIAL_I); - zend_string *const_FOLD_CASE_EXCLUDE_SPECIAL_I_name = zend_string_init_interned("FOLD_CASE_EXCLUDE_SPECIAL_I", sizeof("FOLD_CASE_EXCLUDE_SPECIAL_I") - 1, 1); + zend_string *const_FOLD_CASE_EXCLUDE_SPECIAL_I_name = zend_string_init_interned("FOLD_CASE_EXCLUDE_SPECIAL_I", sizeof("FOLD_CASE_EXCLUDE_SPECIAL_I") - 1, true); zend_declare_typed_class_constant(class_entry, const_FOLD_CASE_EXCLUDE_SPECIAL_I_name, &const_FOLD_CASE_EXCLUDE_SPECIAL_I_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FOLD_CASE_EXCLUDE_SPECIAL_I_name); + zend_string_release_ex(const_FOLD_CASE_EXCLUDE_SPECIAL_I_name, true); return class_entry; } diff --git a/ext/json/json.c b/ext/json/json.c index 9f91d39594ec..3ba53e959c5d 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Omar Kilani | | Jakub Zelenka | @@ -63,6 +61,8 @@ static PHP_GINIT_FUNCTION(json) #endif json_globals->encoder_depth = 0; json_globals->error_code = 0; + json_globals->error_line = 0; + json_globals->error_column = 0; json_globals->encode_max_depth = PHP_JSON_PARSER_DEFAULT_DEPTH; } /* }}} */ @@ -70,6 +70,8 @@ static PHP_GINIT_FUNCTION(json) static PHP_RINIT_FUNCTION(json) { JSON_G(error_code) = 0; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; return SUCCESS; } @@ -177,6 +179,18 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{ } /* }}} */ +static zend_string *php_json_get_error_msg_with_location(php_json_error_code error_code, size_t line, size_t column) /* {{{ */ +{ + const char *base_msg = php_json_get_error_msg(error_code); + + if (line > 0 && column > 0) { + return zend_strpprintf(0, "%s near location %zu:%zu", base_msg, line, column); + } + + return zend_string_init(base_msg, strlen(base_msg), 0); +} +/* }}} */ + PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, size_t str_len, zend_long options, zend_long depth) /* {{{ */ { php_json_parser parser; @@ -185,10 +199,17 @@ PHP_JSON_API zend_result php_json_decode_ex(zval *return_value, const char *str, if (php_json_yyparse(&parser)) { php_json_error_code error_code = php_json_parser_error_code(&parser); + size_t error_line = php_json_parser_error_line(&parser); + size_t error_column = php_json_parser_error_column(&parser); + if (!(options & PHP_JSON_THROW_ON_ERROR)) { JSON_G(error_code) = error_code; + JSON_G(error_line) = error_line; + JSON_G(error_column) = error_column; } else { - zend_throw_exception(php_json_exception_ce, php_json_get_error_msg(error_code), error_code); + zend_string *error_msg = php_json_get_error_msg_with_location(error_code, error_line, error_column); + zend_throw_exception(php_json_exception_ce, ZSTR_VAL(error_msg), error_code); + zend_string_release(error_msg); } RETVAL_NULL(); return FAILURE; @@ -208,7 +229,12 @@ PHP_JSON_API bool php_json_validate_ex(const char *str, size_t str_len, zend_lon if (php_json_yyparse(&parser)) { php_json_error_code error_code = php_json_parser_error_code(&parser); + size_t error_line = php_json_parser_error_line(&parser); + size_t error_column = php_json_parser_error_column(&parser); + JSON_G(error_code) = error_code; + JSON_G(error_line) = error_line; + JSON_G(error_column) = error_column; return false; } @@ -274,11 +300,15 @@ PHP_FUNCTION(json_decode) if (!(options & PHP_JSON_THROW_ON_ERROR)) { JSON_G(error_code) = PHP_JSON_ERROR_NONE; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; } if (!str_len) { if (!(options & PHP_JSON_THROW_ON_ERROR)) { JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; } else { zend_throw_exception(php_json_exception_ce, php_json_get_error_msg(PHP_JSON_ERROR_SYNTAX), PHP_JSON_ERROR_SYNTAX); } @@ -331,10 +361,14 @@ PHP_FUNCTION(json_validate) if (!str_len) { JSON_G(error_code) = PHP_JSON_ERROR_SYNTAX; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; RETURN_FALSE; } JSON_G(error_code) = PHP_JSON_ERROR_NONE; + JSON_G(error_line) = 0; + JSON_G(error_column) = 0; if (depth <= 0) { zend_argument_value_error(2, "must be greater than 0"); @@ -364,6 +398,10 @@ PHP_FUNCTION(json_last_error_msg) { ZEND_PARSE_PARAMETERS_NONE(); - RETURN_STRING(php_json_get_error_msg(JSON_G(error_code))); + RETVAL_STR(php_json_get_error_msg_with_location( + JSON_G(error_code), + JSON_G(error_line), + JSON_G(error_column) + )); } /* }}} */ diff --git a/ext/json/json_arginfo.h b/ext/json/json_arginfo.h index 6b1eb0f1a50a..87ba9cce3afd 100644 --- a/ext/json/json_arginfo.h +++ b/ext/json/json_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit json.stub.php instead. * Stub hash: 0ceb50047401c4b9e878c09cc518eacc274f7fff */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_json_encode, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index c147b8eb23d7..424315eca7ec 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Omar Kilani | | Jakub Zelenka | @@ -41,18 +39,6 @@ static zend_always_inline bool php_json_check_stack_limit(void) #endif } -static int php_json_determine_array_type(zval *val) /* {{{ */ -{ - zend_array *myht = Z_ARRVAL_P(val); - - if (myht) { - return zend_array_is_list(myht) ? PHP_JSON_OUTPUT_ARRAY : PHP_JSON_OUTPUT_OBJECT; - } - - return PHP_JSON_OUTPUT_ARRAY; -} -/* }}} */ - /* {{{ Pretty printing support functions */ static inline void php_json_pretty_print_char(smart_str *buf, int options, char c) /* {{{ */ @@ -63,12 +49,11 @@ static inline void php_json_pretty_print_char(smart_str *buf, int options, char } /* }}} */ -static inline void php_json_pretty_print_indent(smart_str *buf, int options, php_json_encoder *encoder) /* {{{ */ +static inline void php_json_pretty_print_indent(smart_str *buf, int options, const php_json_encoder *encoder) /* {{{ */ { - int i; - if (options & PHP_JSON_PRETTY_PRINT) { - for (i = 0; i < encoder->depth; ++i) { + smart_str_alloc(buf, encoder->depth * 4, 0); + for (int i = 0; i < encoder->depth; ++i) { smart_str_appendl(buf, " ", 4); } } @@ -122,7 +107,7 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */ { - int r, need_comma = 0; + bool encode_as_object = options & PHP_JSON_FORCE_OBJECT; HashTable *myht, *prop_ht; zend_refcounted *recursion_rc; @@ -138,7 +123,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, myht = Z_ARRVAL_P(val); recursion_rc = (zend_refcounted *)myht; prop_ht = NULL; - r = (options & PHP_JSON_FORCE_OBJECT) ? PHP_JSON_OUTPUT_OBJECT : php_json_determine_array_type(val); + encode_as_object = encode_as_object || !zend_array_is_list(myht); } else if (Z_OBJ_P(val)->properties == NULL && Z_OBJ_HT_P(val)->get_properties_for == NULL && Z_OBJ_HT_P(val)->get_properties == zend_std_get_properties @@ -146,9 +131,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, && !zend_object_is_lazy(Z_OBJ_P(val))) { /* Optimized version without rebuilding properties HashTable */ zend_object *obj = Z_OBJ_P(val); - zend_class_entry *ce = obj->ce; - zend_property_info *prop_info; - zval *prop; + const zend_class_entry *ce = obj->ce; if (GC_IS_RECURSIVE(obj)) { encoder->error_code = PHP_JSON_ERROR_RECURSION; @@ -163,7 +146,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, ++encoder->depth; for (int i = 0; i < ce->default_properties_count; i++) { - prop_info = ce->properties_info_table[i]; + zend_property_info *prop_info = ce->properties_info_table[i]; if (!prop_info) { continue; } @@ -171,17 +154,11 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, /* Skip protected and private members. */ continue; } - prop = OBJ_PROP(obj, prop_info->offset); + zval *prop = OBJ_PROP(obj, prop_info->offset); if (Z_TYPE_P(prop) == IS_UNDEF) { continue; } - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = 1; - } - php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); @@ -201,6 +178,14 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, PHP_JSON_HASH_UNPROTECT_RECURSION(obj); return FAILURE; } + + smart_str_appendc(buf, ','); + } + + bool empty = ZSTR_VAL(buf->s)[ZSTR_LEN(buf->s) - 1] != ','; + if (!empty) { + /* Drop the trailing comma. */ + ZSTR_LEN(buf->s)--; } PHP_JSON_HASH_UNPROTECT_RECURSION(obj); @@ -212,7 +197,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, } --encoder->depth; - if (need_comma) { + if (!empty) { php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); } @@ -228,7 +213,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, * referenced from a different place in the object graph. */ recursion_rc = (zend_refcounted *)obj; } - r = PHP_JSON_OUTPUT_OBJECT; + encode_as_object = true; } if (recursion_rc && GC_IS_RECURSIVE(recursion_rc)) { @@ -240,7 +225,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, PHP_JSON_HASH_PROTECT_RECURSION(recursion_rc); - if (r == PHP_JSON_OUTPUT_ARRAY) { + if (!encode_as_object) { smart_str_appendc(buf, '['); } else { smart_str_appendc(buf, '{'); @@ -250,27 +235,23 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, uint32_t i = myht ? zend_hash_num_elements(myht) : 0; + bool empty = true; if (i > 0) { zend_string *key; zval *data; zend_ulong index; ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) { + bool need_dtor = false; zval tmp; ZVAL_UNDEF(&tmp); - if (r == PHP_JSON_OUTPUT_ARRAY) { + if (!encode_as_object) { ZEND_ASSERT(Z_TYPE_P(data) != IS_PTR); - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = 1; - } - php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); - } else if (r == PHP_JSON_OUTPUT_OBJECT) { + } else { if (key) { if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) { /* Skip protected and private members. */ @@ -283,6 +264,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) { continue; } + need_dtor = true; data = zend_read_property_ex(prop_info->ce, Z_OBJ_P(val), prop_info->name, /* silent */ true, &tmp); if (EG(exception)) { PHP_JSON_HASH_UNPROTECT_RECURSION(recursion_rc); @@ -291,11 +273,6 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, } } - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = 1; - } php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); @@ -308,12 +285,6 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, smart_str_appendl(buf, "\"\"", 2); } } else { - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = 1; - } - php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); @@ -333,8 +304,18 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, zval_ptr_dtor(&tmp); return FAILURE; } - zval_ptr_dtor(&tmp); + if (UNEXPECTED(need_dtor)) { + zval_ptr_dtor(&tmp); + } + + smart_str_appendc(buf, ','); } ZEND_HASH_FOREACH_END(); + + empty = ZSTR_VAL(buf->s)[ZSTR_LEN(buf->s) - 1] != ','; + if (!empty) { + /* Drop the trailing comma. */ + ZSTR_LEN(buf->s)--; + } } PHP_JSON_HASH_UNPROTECT_RECURSION(recursion_rc); @@ -349,12 +330,12 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, --encoder->depth; /* Only keep closing bracket on same line for empty arrays/objects */ - if (need_comma) { + if (!empty) { php_json_pretty_print_char(buf, options, '\n'); php_json_pretty_print_indent(buf, options, encoder); } - if (r == PHP_JSON_OUTPUT_ARRAY) { + if (!encode_as_object) { smart_str_appendc(buf, ']'); } else { smart_str_appendc(buf, '}'); @@ -369,7 +350,6 @@ zend_result php_json_escape_string( smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder) /* {{{ */ { - unsigned int us; size_t pos, checkpoint; char *dst; @@ -407,7 +387,7 @@ zend_result php_json_escape_string( 0xffffffff, 0x500080c4, 0x10000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; - us = (unsigned char)s[pos]; + unsigned int us = (unsigned char)s[pos]; if (EXPECTED(!ZEND_BIT_TEST(charmap, us))) { pos++; len--; @@ -626,7 +606,7 @@ static zend_result php_json_encode_serializable_object(smart_str *buf, zend_obje static zend_result php_json_encode_serializable_enum(smart_str *buf, zval *val, int options, php_json_encoder *encoder) { - zend_class_entry *ce = Z_OBJCE_P(val); + const zend_class_entry *ce = Z_OBJCE_P(val); if (ce->enum_backing_type == IS_UNDEF) { encoder->error_code = PHP_JSON_ERROR_NON_BACKED_ENUM; smart_str_appendc(buf, '0'); diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index d570cddc91e4..cf296ed9db62 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -2,15 +2,13 @@ %code top { /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -41,6 +39,7 @@ int json_yydebug = 1; } +%locations %define api.prefix {php_json_yy} %define api.pure full %param { php_json_parser *parser } @@ -49,7 +48,6 @@ int json_yydebug = 1; zval value; } - %token PHP_JSON_T_NUL %token PHP_JSON_T_TRUE %token PHP_JSON_T_FALSE @@ -66,8 +64,8 @@ int json_yydebug = 1; %destructor { zval_ptr_dtor_nogc(&$$); } %code { -static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser); -static void php_json_yyerror(php_json_parser *parser, char const *msg); +static int php_json_yylex(union YYSTYPE *value, YYLTYPE *location, php_json_parser *parser); +static void php_json_yyerror(YYLTYPE *location, php_json_parser *parser, char const *msg); static int php_json_parser_array_create(php_json_parser *parser, zval *array); static int php_json_parser_object_create(php_json_parser *parser, zval *array); @@ -277,7 +275,7 @@ static int php_json_parser_object_update_validate(php_json_parser *parser, zval return SUCCESS; } -static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) +static int php_json_yylex(union YYSTYPE *value, YYLTYPE *location, php_json_parser *parser) { int token = php_json_scan(&parser->scanner); @@ -293,10 +291,15 @@ static int php_json_yylex(union YYSTYPE *value, php_json_parser *parser) value->value = parser->scanner.value; } + location->first_column = PHP_JSON_SCANNER_LOCATION(parser->scanner, first_column); + location->first_line = PHP_JSON_SCANNER_LOCATION(parser->scanner, first_line); + location->last_column = PHP_JSON_SCANNER_LOCATION(parser->scanner, last_column); + location->last_line = PHP_JSON_SCANNER_LOCATION(parser->scanner, last_line); + return token; } -static void php_json_yyerror(php_json_parser *parser, char const *msg) +static void php_json_yyerror(YYLTYPE *location, php_json_parser *parser, char const *msg) { if (!parser->scanner.errcode) { parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX; @@ -308,6 +311,16 @@ PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parse return parser->scanner.errcode; } +PHP_JSON_API size_t php_json_parser_error_line(const php_json_parser *parser) +{ + return parser->scanner.errloc.first_line; +} + +PHP_JSON_API size_t php_json_parser_error_column(const php_json_parser *parser) +{ + return parser->scanner.errloc.first_column; +} + static const php_json_parser_methods default_parser_methods = { php_json_parser_array_create, diff --git a/ext/json/json_scanner.re b/ext/json/json_scanner.re index 0debb3b03cb2..e4d25009132a 100644 --- a/ext/json/json_scanner.re +++ b/ext/json/json_scanner.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -52,6 +50,8 @@ #define PHP_JSON_INT_MAX_LENGTH (MAX_LENGTH_OF_LONG - 1) +#define PHP_JSON_TOKEN_LENGTH() ((size_t) (s->cursor - s->token)) +#define PHP_JSON_TOKEN_LOCATION(location) (s)->errloc.location static void php_json_scanner_copy_string(php_json_scanner *s, size_t esc_size) { @@ -96,6 +96,10 @@ void php_json_scanner_init(php_json_scanner *s, const char *str, size_t str_len, s->cursor = (php_json_ctype *) str; s->limit = (php_json_ctype *) str + str_len; s->options = options; + PHP_JSON_TOKEN_LOCATION(first_column) = 1; + PHP_JSON_TOKEN_LOCATION(first_line) = 1; + PHP_JSON_TOKEN_LOCATION(last_column) = 1; + PHP_JSON_TOKEN_LOCATION(last_line) = 1; PHP_JSON_CONDITION_SET(JS); } @@ -104,6 +108,8 @@ int php_json_scan(php_json_scanner *s) ZVAL_NULL(&s->value); std: + PHP_JSON_TOKEN_LOCATION(first_column) = s->errloc.last_column; + PHP_JSON_TOKEN_LOCATION(first_line) = s->errloc.last_line; s->token = s->cursor; /*!re2c @@ -149,27 +155,50 @@ std: UTF16_3 = UTFPREF ( ( ( HEXC | [efEF] ) HEX ) | ( [dD] HEX7 ) ) HEX{2} ; UTF16_4 = UTFPREF [dD] [89abAB] HEX{2} UTFPREF [dD] [c-fC-F] HEX{2} ; - "{" { return '{'; } - "}" { return '}'; } - "[" { return '['; } - "]" { return ']'; } - ":" { return ':'; } - "," { return ','; } + "{" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return '{'; + } + "}" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return '}'; + } + "[" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return '['; + } + "]" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return ']'; + } + ":" { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return ':'; + } + "," { + PHP_JSON_TOKEN_LOCATION(last_column)++; + return ','; + } "null" { + PHP_JSON_TOKEN_LOCATION(last_column) += 4; ZVAL_NULL(&s->value); return PHP_JSON_T_NUL; } "true" { + PHP_JSON_TOKEN_LOCATION(last_column) += 4; ZVAL_TRUE(&s->value); return PHP_JSON_T_TRUE; } "false" { + PHP_JSON_TOKEN_LOCATION(last_column) += 5; ZVAL_FALSE(&s->value); return PHP_JSON_T_FALSE; } INT { bool bigint = 0, negative = s->token[0] == '-'; - size_t digits = (size_t) (s->cursor - s->token - negative); + size_t digits = PHP_JSON_TOKEN_LENGTH(); + PHP_JSON_TOKEN_LOCATION(last_column) += digits; + digits -= negative; if (digits >= PHP_JSON_INT_MAX_LENGTH) { if (digits == PHP_JSON_INT_MAX_LENGTH) { int cmp = strncmp((char *) (s->token + negative), LONG_MIN_DIGITS, PHP_JSON_INT_MAX_LENGTH); @@ -192,10 +221,19 @@ std: } } FLOAT|EXP { + PHP_JSON_TOKEN_LOCATION(last_column) += PHP_JSON_TOKEN_LENGTH(); ZVAL_DOUBLE(&s->value, zend_strtod((char *) s->token, NULL)); return PHP_JSON_T_DOUBLE; } - NL|WS { goto std; } + NL { + PHP_JSON_TOKEN_LOCATION(last_line)++; + PHP_JSON_TOKEN_LOCATION(last_column) = 1; + goto std; + } + WS { + PHP_JSON_TOKEN_LOCATION(last_column) += PHP_JSON_TOKEN_LENGTH(); + goto std; + } EOI { if (s->limit < s->cursor) { return PHP_JSON_T_EOI; @@ -205,6 +243,7 @@ std: } } ["] { + PHP_JSON_TOKEN_LOCATION(last_column)++; s->str_start = s->cursor; s->str_esc = 0; s->utf8_invalid = 0; @@ -229,18 +268,22 @@ std: return PHP_JSON_T_ERROR; } UTF16_1 { + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 5; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_2 { + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 4; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_3 { + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 3; PHP_JSON_CONDITION_GOTO(STR_P1); } UTF16_4 { + PHP_JSON_TOKEN_LOCATION(last_column) += 1; s->str_esc += 8; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -249,6 +292,7 @@ std: return PHP_JSON_T_ERROR; } ESC { + PHP_JSON_TOKEN_LOCATION(last_column) += 2; s->str_esc++; PHP_JSON_CONDITION_GOTO(STR_P1); } @@ -257,6 +301,7 @@ std: return PHP_JSON_T_ERROR; } ["] { + PHP_JSON_TOKEN_LOCATION(last_column)++; zend_string *str; size_t len = (size_t)(s->cursor - s->str_start - s->str_esc - 1 + s->utf8_invalid_count); if (len == 0) { @@ -277,7 +322,22 @@ std: return PHP_JSON_T_STRING; } } - UTF8 { PHP_JSON_CONDITION_GOTO(STR_P1); } + UTF8_1 { + PHP_JSON_TOKEN_LOCATION(last_column)++; + PHP_JSON_CONDITION_GOTO(STR_P1); + } + UTF8_2 { + PHP_JSON_TOKEN_LOCATION(last_column) += 1; + PHP_JSON_CONDITION_GOTO(STR_P1); + } + UTF8_3 { + PHP_JSON_TOKEN_LOCATION(last_column) += 1; + PHP_JSON_CONDITION_GOTO(STR_P1); + } + UTF8_4 { + PHP_JSON_TOKEN_LOCATION(last_column) += 1; + PHP_JSON_CONDITION_GOTO(STR_P1); + } ANY { if (s->options & (PHP_JSON_INVALID_UTF8_IGNORE | PHP_JSON_INVALID_UTF8_SUBSTITUTE)) { if (s->options & PHP_JSON_INVALID_UTF8_SUBSTITUTE) { @@ -295,7 +355,6 @@ std: s->errcode = PHP_JSON_ERROR_UTF8; return PHP_JSON_T_ERROR; } - UTF16_1 { int utf16 = php_json_ucs2_to_int(s, 2); PHP_JSON_SCANNER_COPY_UTF(); diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 00c87eca53c9..e2728835ed42 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Omar Kilani | | Jakub Zelenka | @@ -79,10 +77,6 @@ typedef enum { #define PHP_JSON_INVALID_UTF8_SUBSTITUTE (1<<21) #define PHP_JSON_THROW_ON_ERROR (1<<22) -/* Internal flags */ -#define PHP_JSON_OUTPUT_ARRAY 0 -#define PHP_JSON_OUTPUT_OBJECT 1 - /* default depth */ #define PHP_JSON_PARSER_DEFAULT_DEPTH 512 @@ -90,6 +84,8 @@ ZEND_BEGIN_MODULE_GLOBALS(json) int encoder_depth; int encode_max_depth; php_json_error_code error_code; + size_t error_line; + size_t error_column; ZEND_END_MODULE_GLOBALS(json) PHP_JSON_API ZEND_EXTERN_MODULE_GLOBALS(json) diff --git a/ext/json/php_json_encoder.h b/ext/json/php_json_encoder.h index d66d71cb5538..30cc1d564fa5 100644 --- a/ext/json/php_json_encoder.h +++ b/ext/json/php_json_encoder.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ diff --git a/ext/json/php_json_parser.h b/ext/json/php_json_parser.h index 8aedce9ac55d..4a7d64307c43 100644 --- a/ext/json/php_json_parser.h +++ b/ext/json/php_json_parser.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -50,12 +48,20 @@ typedef struct _php_json_parser_methods { php_json_parser_func_object_end_t object_end; } php_json_parser_methods; + typedef struct _php_json_parser_location { + size_t first_line; + size_t first_column; + size_t last_line; + size_t last_column; +} php_json_parser_location; + struct _php_json_parser { php_json_scanner scanner; zval *return_value; int depth; int max_depth; php_json_parser_methods methods; + php_json_parser_location *location; }; PHP_JSON_API void php_json_parser_init_ex( @@ -77,6 +83,10 @@ PHP_JSON_API void php_json_parser_init( PHP_JSON_API php_json_error_code php_json_parser_error_code(const php_json_parser *parser); +PHP_JSON_API size_t php_json_parser_error_line(const php_json_parser *parser); + +PHP_JSON_API size_t php_json_parser_error_column(const php_json_parser *parser); + PHP_JSON_API int php_json_parse(php_json_parser *parser); int php_json_yyparse(php_json_parser *parser); diff --git a/ext/json/php_json_scanner.h b/ext/json/php_json_scanner.h index a49be68cd632..90460cf9952a 100644 --- a/ext/json/php_json_scanner.h +++ b/ext/json/php_json_scanner.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -22,6 +20,17 @@ typedef unsigned char php_json_ctype; +typedef struct _php_json_error_location { + /** first column of the error */ + size_t first_column; + /** first line of the error */ + size_t first_line; + /** last column of the error */ + size_t last_column; + /** last line of the error */ + size_t last_line; +} php_json_error_location; + typedef struct _php_json_scanner { php_json_ctype *cursor; /* cursor position */ php_json_ctype *token; /* token position */ @@ -35,10 +44,12 @@ typedef struct _php_json_scanner { int state; /* condition state */ int options; /* options */ php_json_error_code errcode; /* error type if there is an error */ + php_json_error_location errloc; /* error location */ int utf8_invalid; /* whether utf8 is invalid */ int utf8_invalid_count; /* number of extra character for invalid utf8 */ } php_json_scanner; +#define PHP_JSON_SCANNER_LOCATION(scanner, slocation) (scanner).errloc.slocation void php_json_scanner_init(php_json_scanner *scanner, const char *str, size_t str_len, int options); int php_json_scan(php_json_scanner *s); diff --git a/ext/json/tests/007.phpt b/ext/json/tests/007.phpt index dea641317e97..9a5ae654d636 100644 --- a/ext/json/tests/007.phpt +++ b/ext/json/tests/007.phpt @@ -24,14 +24,14 @@ int(0) string(8) "No error" NULL int(1) -string(28) "Maximum stack depth exceeded" +string(46) "Maximum stack depth exceeded near location 1:2" NULL int(2) -string(42) "State mismatch (invalid or malformed JSON)" +string(60) "State mismatch (invalid or malformed JSON) near location 1:3" NULL int(3) -string(53) "Control character error, possibly incorrectly encoded" +string(71) "Control character error, possibly incorrectly encoded near location 1:2" NULL int(4) -string(12) "Syntax error" +string(30) "Syntax error near location 1:3" Done diff --git a/ext/json/tests/bug62010.phpt b/ext/json/tests/bug62010.phpt index 2591231dcdda..862d7dc7e2c0 100644 --- a/ext/json/tests/bug62010.phpt +++ b/ext/json/tests/bug62010.phpt @@ -10,4 +10,4 @@ var_dump(json_last_error_msg()); --EXPECT-- NULL bool(true) -string(50) "Single unpaired UTF-16 surrogate in unicode escape" +string(68) "Single unpaired UTF-16 surrogate in unicode escape near location 1:1" diff --git a/ext/json/tests/bug68546.phpt b/ext/json/tests/bug68546.phpt index 8835a72c5eac..1847eabf3a8e 100644 --- a/ext/json/tests/bug68546.phpt +++ b/ext/json/tests/bug68546.phpt @@ -5,7 +5,7 @@ Bug #68546 (json_decode() Fatal error: Cannot access property started with '\0') var_dump(json_decode('{"key": {"\u0000": "aa"}}')); var_dump(json_last_error() === JSON_ERROR_INVALID_PROPERTY_NAME); -var_dump(json_decode('[{"key1": 0, "\u0000": 1}]')); +var_dump(json_decode('[{"key1": 0, "\u1234": 1, "\u0000": 1}]')); var_dump(json_last_error() === JSON_ERROR_INVALID_PROPERTY_NAME); var_dump(json_last_error_msg()); @@ -16,5 +16,5 @@ NULL bool(true) NULL bool(true) -string(36) "The decoded property name is invalid" +string(55) "The decoded property name is invalid near location 1:27" Done diff --git a/ext/json/tests/json_decode_exceptions.phpt b/ext/json/tests/json_decode_exceptions.phpt index 7dc2e7408a02..d53941682e45 100644 --- a/ext/json/tests/json_decode_exceptions.phpt +++ b/ext/json/tests/json_decode_exceptions.phpt @@ -13,7 +13,7 @@ try { --EXPECTF-- object(JsonException)#1 (7) { ["message":protected]=> - string(12) "Syntax error" + string(30) "Syntax error near location 1:2" ["string":"Exception":private]=> string(0) "" ["code":protected]=> diff --git a/ext/json/tests/json_last_error_msg_error_location_001.phpt b/ext/json/tests/json_last_error_msg_error_location_001.phpt new file mode 100644 index 000000000000..e0553f9f7d65 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_001.phpt @@ -0,0 +1,121 @@ +--TEST-- +json_last_error_msg() - Error location reporting with ASCII characters +--FILE-- + +--EXPECT-- +Testing errors at various locations with ASCII characters + +Error at position 1:1: +bool(false) +int(4) +string(30) "Syntax error near location 1:1" + +Error at position 1:10: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error at position 1:9: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Error at position 1:16: +bool(false) +int(4) +string(31) "Syntax error near location 1:16" + +Error at position 1:15: +bool(false) +int(4) +string(31) "Syntax error near location 1:15" + +Error at position 1:10: +bool(false) +int(4) +string(31) "Syntax error near location 1:10" + +Error at position 1:7: +bool(false) +int(4) +string(30) "Syntax error near location 1:7" + +Error at position 1:2: +bool(false) +int(4) +string(30) "Syntax error near location 1:2" + +Error at position 1:16: +bool(false) +int(4) +string(31) "Syntax error near location 1:16" + +Error at position 1:4: +bool(false) +int(4) +string(30) "Syntax error near location 1:4" + +Error at position 1:10: +bool(false) +int(4) +string(31) "Syntax error near location 1:10" + +Error at position 1:10: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + diff --git a/ext/json/tests/json_last_error_msg_error_location_002.phpt b/ext/json/tests/json_last_error_msg_error_location_002.phpt new file mode 100644 index 000000000000..df7fc981ccba --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_002.phpt @@ -0,0 +1,103 @@ +--TEST-- +json_last_error_msg() - Error location reporting with Unicode UTF-8 characters +--FILE-- + +--EXPECT-- +Testing error locations with Unicode UTF-8 characters + +Error after Japanese characters: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:12" + +Error after Russian characters: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Error after Chinese characters: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:8" + +Error after Arabic characters: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Error after Emoji: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:11" + +Error in mixed ASCII and UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:27" + +Error with UTF-8 escaped sequences: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error in object with multiple UTF-8 keys: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:22" + +Error in array with UTF-8 strings: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:18" + +Error in nested object with UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:15" + diff --git a/ext/json/tests/json_last_error_msg_error_location_003.phpt b/ext/json/tests/json_last_error_msg_error_location_003.phpt new file mode 100644 index 000000000000..ec5e6b9b4d65 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_003.phpt @@ -0,0 +1,72 @@ +--TEST-- +json_last_error_msg() - Error location reporting with multi-line JSON +--FILE-- + +--EXPECT-- +Testing error locations in multi-line JSON + +Error on line 2, column 13: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 2:13" + +Error on line 3, column 12: +bool(false) +int(4) +string(31) "Syntax error near location 3:12" + +Error on line 5, column 26: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 5:26" + +Error on line 7, column 1: +bool(false) +int(4) +string(30) "Syntax error near location 7:1" + diff --git a/ext/json/tests/json_last_error_msg_error_location_004.phpt b/ext/json/tests/json_last_error_msg_error_location_004.phpt new file mode 100644 index 000000000000..165449600fb3 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_004.phpt @@ -0,0 +1,93 @@ +--TEST-- +json_last_error_msg() - Error location reporting with deeply nested structures +--FILE-- + +--EXPECT-- +Testing error locations in deeply nested structures + +Error in deeply nested object: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:31" + +Error in deeply nested array: +bool(true) +int(0) +string(8) "No error" + +Error in mixed nested structures: +bool(true) +int(0) +string(8) "No error" + +Error at end of deep nesting: +bool(true) +int(0) +string(8) "No error" + +Error in middle of deep nesting: +bool(false) +int(4) +string(31) "Syntax error near location 1:21" + +Error in complex structure: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:93" + +Error in array of objects: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:68" + +Error in object with array values: +bool(false) +int(2) +string(61) "State mismatch (invalid or malformed JSON) near location 1:82" + diff --git a/ext/json/tests/json_last_error_msg_error_location_005.phpt b/ext/json/tests/json_last_error_msg_error_location_005.phpt new file mode 100644 index 000000000000..d12ce387e73e --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_005.phpt @@ -0,0 +1,103 @@ +--TEST-- +json_last_error_msg() - Error location reporting with UTF-16 surrogate pairs +--FILE-- + +--EXPECT-- +Testing error locations with UTF-16 surrogate pairs and escape sequences + +Error after UTF-16 escaped emoji: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:11" + +Error after multiple UTF-16 pairs: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with mixed UTF-8 and UTF-16: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:11" + +Error with UTF-16 in key: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Error with multiple UTF-16 keys: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:22" + +Error with BMP characters: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with supplementary plane: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:11" + +Error in array with UTF-16: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:12" + +Error in nested structure with UTF-16: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:18" + +Error with UTF-16 and control chars: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + diff --git a/ext/json/tests/json_last_error_msg_error_location_006.phpt b/ext/json/tests/json_last_error_msg_error_location_006.phpt new file mode 100644 index 000000000000..e6aab1af8f27 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_006.phpt @@ -0,0 +1,152 @@ +--TEST-- +json_last_error_msg() - Error location reporting edge cases +--FILE-- + +--EXPECT-- +Testing error location edge cases + +Error at position 1:1: +bool(false) +int(4) +string(12) "Syntax error" + +Error at position 1:1 with invalid char: +bool(false) +int(4) +string(30) "Syntax error near location 1:1" + +Error after leading whitespace: +bool(false) +int(4) +string(30) "Syntax error near location 1:5" + +Error with tabs and spaces: +bool(false) +int(4) +string(30) "Syntax error near location 2:3" + +Error after multiple newlines: +bool(false) +int(4) +string(30) "Syntax error near location 4:2" + +Error at end of long string: +bool(false) +int(4) +string(33) "Syntax error near location 1:1011" + +Error with very long key: +bool(false) +int(3) +string(73) "Control character error, possibly incorrectly encoded near location 1:506" + +Error after empty object: +bool(false) +int(4) +string(30) "Syntax error near location 1:3" + +Error after empty array: +bool(false) +int(4) +string(30) "Syntax error near location 1:3" + +Error with multiple root values: +bool(false) +int(4) +string(30) "Syntax error near location 1:3" + +Error after valid number: +bool(false) +int(4) +string(30) "Syntax error near location 1:4" + +Error after valid boolean: +bool(false) +int(4) +string(30) "Syntax error near location 1:5" + +Error after valid null: +bool(false) +int(4) +string(30) "Syntax error near location 1:5" + +Error after valid string: +bool(false) +int(4) +string(30) "Syntax error near location 1:7" + +Error with mixed whitespace: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 3:2" + diff --git a/ext/json/tests/json_last_error_msg_error_location_007.phpt b/ext/json/tests/json_last_error_msg_error_location_007.phpt new file mode 100644 index 000000000000..0e24889bbbbe --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_007.phpt @@ -0,0 +1,178 @@ +--TEST-- +json_last_error_msg() - Error location with various error types +--FILE-- + +--EXPECT-- +Testing error locations with different error types + +State mismatch - expected value: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +State mismatch - expected key: +bool(false) +int(4) +string(30) "Syntax error near location 1:2" + +State mismatch - trailing comma in object: +bool(false) +int(4) +string(31) "Syntax error near location 1:17" + +State mismatch - trailing comma in array: +bool(false) +int(4) +string(31) "Syntax error near location 1:10" + +Invalid number format - leading zero: +bool(false) +int(4) +string(31) "Syntax error near location 1:10" + +Invalid number format - multiple decimals: +bool(false) +int(4) +string(31) "Syntax error near location 1:12" + +Invalid number format - incomplete exponent: +bool(false) +int(4) +string(31) "Syntax error near location 1:10" + +Invalid number format - double sign: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Unclosed string: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Invalid escape sequence: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Incomplete unicode escape: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Invalid unicode escape: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Invalid true keyword: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Invalid false keyword: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Invalid null keyword: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + +Mismatched brackets - ] instead of }: +bool(false) +int(2) +string(61) "State mismatch (invalid or malformed JSON) near location 1:14" + +Mismatched brackets - } instead of ]: +bool(false) +int(2) +string(60) "State mismatch (invalid or malformed JSON) near location 1:7" + +Extra closing bracket: +bool(false) +int(4) +string(31) "Syntax error near location 1:15" + +Missing comma between elements: +bool(false) +int(4) +string(30) "Syntax error near location 1:4" + +Missing comma between object properties: +bool(false) +int(4) +string(30) "Syntax error near location 1:9" + diff --git a/ext/json/tests/json_last_error_msg_error_location_008.phpt b/ext/json/tests/json_last_error_msg_error_location_008.phpt new file mode 100644 index 000000000000..4d8a1012316b --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_008.phpt @@ -0,0 +1,182 @@ +--TEST-- +json_last_error_msg() - Error location with mixed UTF-8 multi-byte characters +--FILE-- + +--EXPECT-- +Testing error locations with various UTF-8 multi-byte character widths + +Error with 2-byte UTF-8 (Latin Extended): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with 2-byte UTF-8 (Greek): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:14" + +Error with 2-byte UTF-8 (Cyrillic): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:12" + +Error with 3-byte UTF-8 (Chinese): +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:8" + +Error with 3-byte UTF-8 (Japanese Hiragana): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with 3-byte UTF-8 (Japanese Katakana): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with 3-byte UTF-8 (Korean): +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:8" + +Error with 4-byte UTF-8 (Emoji faces): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:11" + +Error with 4-byte UTF-8 (Emoji objects): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:13" + +Error with 4-byte UTF-8 (Mathematical symbols): +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with mixed 1-2-3 byte UTF-8: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Error with mixed 2-3-4 byte UTF-8: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Error with all byte widths: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Error with UTF-8 key at start: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:7" + +Error with multiple UTF-8 keys: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:35" + +Error in array with mixed UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:25" + +Error in nested structure with various UTF-8: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:22" + +Error with combining diacritical marks: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with Hebrew: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + +Error with Arabic with diacritics: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:11" + diff --git a/ext/json/tests/json_last_error_msg_error_location_009.phpt b/ext/json/tests/json_last_error_msg_error_location_009.phpt new file mode 100644 index 000000000000..406179693ef6 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_009.phpt @@ -0,0 +1,110 @@ +--TEST-- +json_last_error_msg() - Error location with depth errors and complex nesting +--FILE-- + +--EXPECT-- +Testing error locations with depth-related issues + +Max depth error at specific location: +bool(false) +int(1) +string(47) "Maximum stack depth exceeded near location 1:21" + +Max depth error in array: +bool(false) +int(1) +string(46) "Maximum stack depth exceeded near location 1:5" + +Max depth error with mixed structures: +bool(false) +int(1) +string(46) "Maximum stack depth exceeded near location 1:7" + +Syntax error at deep nesting level: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:31" + +Syntax error in deep array: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:6" + +Error after valid deep structure: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:48" + +Error in middle of nested structure: +bool(false) +int(4) +string(31) "Syntax error near location 1:29" + +Error in array with nested objects: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:30" + +Error in deep UTF-8 structure: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:16" + +Valid deep structure within limit: +bool(true) +int(0) +string(8) "No error" + diff --git a/ext/json/tests/json_last_error_msg_error_location_010.phpt b/ext/json/tests/json_last_error_msg_error_location_010.phpt new file mode 100644 index 000000000000..108570205838 --- /dev/null +++ b/ext/json/tests/json_last_error_msg_error_location_010.phpt @@ -0,0 +1,164 @@ +--TEST-- +json_last_error_msg() - Error location with whitespace variations +--FILE-- + +--EXPECT-- +Testing error locations with various whitespace patterns + +Error after multiple spaces: +bool(false) +int(4) +string(30) "Syntax error near location 1:7" + +Error after tabs: +bool(false) +int(4) +string(30) "Syntax error near location 1:5" + +Error after mixed whitespace: +bool(false) +int(4) +string(30) "Syntax error near location 1:7" + +Error on second line: +bool(false) +int(4) +string(30) "Syntax error near location 2:2" + +Error with CRLF line endings: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 2:8" + +Error after blank lines: +bool(false) +int(4) +string(30) "Syntax error near location 4:2" + +Error in string with spaces: +bool(false) +int(3) +string(71) "Control character error, possibly incorrectly encoded near location 1:9" + +Error with whitespace around colon: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:12" + +Error with whitespace around comma: +bool(true) +int(0) +string(8) "No error" + +Error in pretty printed JSON: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 4:11" + +Error in heavily indented JSON: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 5:26" + +Error with mixed tabs and spaces: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 3:12" + +Error after whitespace-only line: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 3:12" + +Error in compact JSON: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:22" + +Error with regular spaces: +bool(false) +int(3) +string(72) "Control character error, possibly incorrectly encoded near location 1:10" + diff --git a/ext/json/tests/json_validate_002.phpt b/ext/json/tests/json_validate_002.phpt index 53f4e4f2c2ea..423564c4ad7c 100644 --- a/ext/json/tests/json_validate_002.phpt +++ b/ext/json/tests/json_validate_002.phpt @@ -23,13 +23,13 @@ int(4) string(12) "Syntax error" bool(false) int(4) -string(12) "Syntax error" +string(30) "Syntax error near location 1:1" bool(false) int(4) string(12) "Syntax error" bool(false) int(1) -string(28) "Maximum stack depth exceeded" +string(46) "Maximum stack depth exceeded near location 1:1" bool(true) int(0) string(8) "No error" @@ -44,7 +44,7 @@ int(0) string(8) "No error" bool(false) int(4) -string(12) "Syntax error" +string(30) "Syntax error near location 1:1" bool(true) int(0) string(8) "No error" diff --git a/ext/json/tests/json_validate_004.phpt b/ext/json/tests/json_validate_004.phpt index d8a798d94327..bd807defa140 100644 --- a/ext/json/tests/json_validate_004.phpt +++ b/ext/json/tests/json_validate_004.phpt @@ -23,16 +23,16 @@ json_validate_trycatchdump("[\"\xc1\xc1\",\"a\"]", 512, JSON_INVALID_UTF8_IGNORE Testing Invalid UTF-8 bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:1" bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:1" bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:1" bool(false) int(5) -string(56) "Malformed UTF-8 characters, possibly incorrectly encoded" +string(74) "Malformed UTF-8 characters, possibly incorrectly encoded near location 1:2" bool(true) int(0) string(8) "No error" diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4 index 7d0229f6868c..14174bd5dc26 100644 --- a/ext/ldap/config.m4 +++ b/ext/ldap/config.m4 @@ -60,15 +60,20 @@ if test "$PHP_LDAP" != "no"; then [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) AS_VAR_IF([PHP_LDAP], [yes], [ - PKG_CHECK_MODULES([LDAP], [lber ldap]) - PHP_LDAP_PKGCONFIG=true - ], [PHP_LDAP_CHECKS([$PHP_LDAP])]) + PKG_CHECK_MODULES([LDAP], [lber ldap], + PHP_LDAP_PKGCONFIG=true, PHP_LDAP_PKGCONFIG=false)]) AS_IF([test "$PHP_LDAP_PKGCONFIG" = true], [ PHP_EVAL_INCLINE([$LDAP_CFLAGS]) PHP_EVAL_LIBLINE([$LDAP_LIBS], [LDAP_SHARED_LIBADD]) ], [ - AS_VAR_IF([LDAP_DIR],, [AC_MSG_ERROR([Cannot find ldap.h])]) + AS_VAR_IF([PHP_LDAP], [yes], [ + for i in /usr/local /usr; do + PHP_LDAP_CHECKS([$i]) + done + ], [PHP_LDAP_CHECKS([$PHP_LDAP])]) + AC_MSG_CHECKING([for ldap.h]) + AS_VAR_IF([LDAP_DIR],, [AC_MSG_ERROR([Cannot find ldap.h])], AC_MSG_RESULT([$LDAP_DIR])) dnl -pc removal is a hack for clang MACHINE_INCLUDES=$($CC -dumpmachine | $SED 's/-pc//') @@ -86,14 +91,17 @@ if test "$PHP_LDAP" != "no"; then elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.12.1 || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/libclntsh.$SHLIB_SUFFIX_NAME.12.1; then PHP_ADD_LIBRARY_WITH_PATH([clntsh], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) AC_DEFINE([HAVE_ORALDAP], [1]) + AC_MSG_WARN([Build with Oracle Instant Client is deprecated as of PHP 8.5]) elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.11.1 || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/libclntsh.$SHLIB_SUFFIX_NAME.11.1; then PHP_ADD_LIBRARY_WITH_PATH([clntsh], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) AC_DEFINE([HAVE_ORALDAP], [1]) + AC_MSG_WARN([Build with Oracle Instant Client is deprecated as of PHP 8.5]) elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/libclntsh.$SHLIB_SUFFIX_NAME; then - PHP_ADD_LIBRARY_WITH_PATH([clntsh], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) - AC_DEFINE([HAVE_ORALDAP], [1]) + PHP_ADD_LIBRARY_WITH_PATH([clntsh], [$LDAP_LIBDIR], [LDAP_SHARED_LIBADD]) + AC_DEFINE([HAVE_ORALDAP], [1]) + AC_MSG_WARN([Build with Oracle Instant Client is deprecated as of PHP 8.5]) else AC_MSG_ERROR([Cannot find ldap libraries in $LDAP_LIBDIR.]) diff --git a/ext/ldap/config.w32 b/ext/ldap/config.w32 index f9bc8662ac50..c6a7049aa1c6 100644 --- a/ext/ldap/config.w32 +++ b/ext/ldap/config.w32 @@ -4,8 +4,8 @@ ARG_WITH("ldap", "LDAP support", "no"); if (PHP_LDAP != "no") { - if (CHECK_HEADER_ADD_INCLUDE("ldap.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && - CHECK_HEADER_ADD_INCLUDE("lber.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && + if (CHECK_HEADER("ldap.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && + CHECK_HEADER("lber.h", "CFLAGS_LDAP", PHP_PHP_BUILD + "\\include\\openldap;" + PHP_PHP_BUILD + "\\openldap\\include;" + PHP_LDAP) && SETUP_OPENSSL("ldap", PHP_LDAP) >= 2 && CHECK_LIB("oldap32_a.lib", "ldap", PHP_LDAP) && CHECK_LIB("olber32_a.lib", "ldap", PHP_LDAP)&& @@ -24,7 +24,7 @@ if (PHP_LDAP != "no") { AC_DEFINE('HAVE_LDAP_WHOAMI_S', 1); AC_DEFINE('HAVE_LDAP_REFRESH_S', 1); AC_DEFINE('HAVE_LDAP_EXTENDED_OPERATION', 1); - + AC_DEFINE('HAVE_3ARG_SETREBINDPROC', 1); } else { WARNING("ldap not enabled; libraries and headers not found"); } diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 0e9f953a2a2a..77322d2de59f 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Amitay Isaacs | | Eric Warnke | @@ -32,7 +30,6 @@ #include -#include "ext/standard/dl.h" #include "php_ldap.h" #ifdef PHP_WIN32 @@ -104,7 +101,7 @@ ZEND_GET_MODULE(ldap) #endif static inline ldap_linkdata *ldap_link_from_obj(zend_object *obj) { - return (ldap_linkdata *)((char *)(obj) - XtOffsetOf(ldap_linkdata, std)); + return ZEND_CONTAINER_OF(obj, ldap_linkdata, std); } #define Z_LDAP_LINK_P(zv) ldap_link_from_obj(Z_OBJ_P(zv)) @@ -151,7 +148,7 @@ static void ldap_link_free_obj(zend_object *obj) } static inline ldap_resultdata *ldap_result_from_obj(zend_object *obj) { - return (ldap_resultdata *)((char *)(obj) - XtOffsetOf(ldap_resultdata, std)); + return ZEND_CONTAINER_OF(obj, ldap_resultdata, std); } #define Z_LDAP_RESULT_P(zv) ldap_result_from_obj(Z_OBJ_P(zv)) @@ -188,7 +185,7 @@ static void ldap_result_free_obj(zend_object *obj) } static inline ldap_result_entry *ldap_result_entry_from_obj(zend_object *obj) { - return (ldap_result_entry *)((char *)(obj) - XtOffsetOf(ldap_result_entry, std)); + return ZEND_CONTAINER_OF(obj, ldap_result_entry, std); } #define Z_LDAP_RESULT_ENTRY_P(zv) ldap_result_entry_from_obj(Z_OBJ_P(zv)) @@ -274,11 +271,11 @@ static zend_string* php_ldap_try_get_ldap_value_from_zval(zval *zv) { /* The char pointer MUST refer to the char* of a zend_string struct */ static void php_ldap_zend_string_release_from_char_pointer(char *ptr) { - zend_string_release((zend_string*) (ptr - XtOffsetOf(zend_string, val))); + zend_string_release((zend_string*) (ptr - offsetof(zend_string, val))); } /* {{{ Parse controls from and to arrays */ -static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, int request) +static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, bool request) { array_init(array); @@ -292,10 +289,10 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) { int expire = 0, grace = 0, rc; LDAPPasswordPolicyError pperr; - zval value; rc = ldap_parse_passwordpolicy_control(ld, ctrl, &expire, &grace, &pperr); if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "expire", expire); add_assoc_long(&value, "grace", grace); @@ -310,7 +307,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } else if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_PAGEDRESULTS) == 0) { int lestimated, rc; struct berval lcookie = { 0L, NULL }; - zval value; if (ctrl->ldctl_value.bv_len) { /* ldap_parse_pageresponse_control() allocates lcookie.bv_val */ @@ -321,6 +317,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "size", lestimated); add_assoc_stringl(&value, "cookie", lcookie.bv_val, lcookie.bv_len); @@ -348,7 +345,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, add_assoc_stringl(&value, "dn", bv.bv_val, bv.bv_len); while (ber_scanf(ber, "{m" /*}*/, &bv) != LBER_ERROR) { - int i; BerVarray vals = NULL; zval tmp; @@ -358,7 +354,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } array_init(&tmp); - for (i = 0; vals[i].bv_val != NULL; i++) { + for (int i = 0; vals[i].bv_val != NULL; i++) { add_next_index_stringl(&tmp, vals[i].bv_val, vals[i].bv_len); } add_assoc_zval(&value, bv.bv_val, &tmp); @@ -372,7 +368,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, ber_free(ber, 1); } } else if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_SORTRESPONSE) == 0) { - zval value; int errcode, rc; char* attribute; @@ -382,6 +377,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, rc = -1; } if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "errcode", errcode); if (attribute) { @@ -395,7 +391,6 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, } else if (strcmp(ctrl->ldctl_oid, LDAP_CONTROL_VLVRESPONSE) == 0) { int target, count, errcode, rc; struct berval *context; - zval value; if (ctrl->ldctl_value.bv_len) { rc = ldap_parse_vlvresponse_control(ld, ctrl, &target, &count, &context, &errcode); @@ -403,6 +398,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, rc = -1; } if ( rc == LDAP_SUCCESS ) { + zval value; array_init(&value); add_assoc_long(&value, "target", target); add_assoc_long(&value, "count", count); @@ -427,7 +423,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashTable *control_ht) { zval* val; - zend_string *control_oid; + zend_string *control_oid, *control_oid_tmp; char** ldap_attrs = NULL; LDAPSortKey** sort_keys = NULL; zend_string *tmpstring = NULL, **tmpstrings1 = NULL, **tmpstrings2 = NULL; @@ -438,8 +434,8 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT return -1; } - control_oid = zval_get_string(val); - if (EG(exception)) { + control_oid = zval_try_get_tmp_string(val, &control_oid_tmp); + if (!control_oid) { return -1; } @@ -455,8 +451,8 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT if ((val = zend_hash_find(control_ht, ZSTR_KNOWN(ZEND_STR_VALUE))) != NULL) { if (Z_TYPE_P(val) != IS_ARRAY) { - tmpstring = zval_get_string(val); - if (EG(exception)) { + tmpstring = zval_try_get_string(val); + if (!tmpstring) { rc = -1; goto failure; } @@ -470,8 +466,8 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT pagesize = zval_get_long(tmp); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "cookie", sizeof("cookie") - 1)) != NULL) { - tmpstring = zval_get_string(tmp); - if (EG(exception)) { + tmpstring = zval_try_get_string(tmp); + if (!tmpstring) { rc = -1; goto failure; } @@ -479,20 +475,19 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT cookie.bv_len = ZSTR_LEN(tmpstring); } /* ldap_create_page_control_value() allocates memory for control_value.bv_val */ - control_value_alloc = 1; + control_value_alloc = true; rc = ldap_create_page_control_value(ld, pagesize, &cookie, &control_value); if (rc != LDAP_SUCCESS) { php_error_docref(NULL, E_WARNING, "Failed to create paged result control value: %s (%d)", ldap_err2string(rc), rc); } } else if (zend_string_equals_literal(control_oid, LDAP_CONTROL_ASSERT)) { zval* tmp; - zend_string* assert; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "filter", sizeof("filter") - 1)) == NULL) { rc = -1; zend_value_error("%s(): Control must have a \"filter\" key", get_active_function_name()); } else { - assert = zval_get_string(tmp); - if (EG(exception)) { + zend_string* assert = zval_try_get_string(tmp); + if (!assert) { rc = -1; goto failure; } @@ -501,7 +496,7 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT int success = LDAP_SUCCESS; ldap_set_option(ld, LDAP_OPT_RESULT_CODE, &success); /* ldap_create_assertion_control_value() allocates memory for control_value.bv_val */ - control_value_alloc = 1; + control_value_alloc = true; rc = ldap_create_assertion_control_value(ld, ZSTR_VAL(assert), &control_value); if (rc != LDAP_SUCCESS) { php_error_docref(NULL, E_WARNING, "Failed to create assert control value: %s (%d)", ldap_err2string(rc), rc); @@ -519,8 +514,8 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT rc = -1; php_error_docref(NULL, E_WARNING, "Failed to allocate control value"); } else { - tmpstring = zval_get_string(tmp); - if (EG(exception)) { + tmpstring = zval_try_get_string(tmp); + if (!tmpstring) { rc = -1; goto failure; } @@ -544,23 +539,22 @@ static int php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, const HashT rc = -1; php_error_docref(NULL, E_WARNING, "Failed to allocate control value"); } else { - int num_attribs, i; zval* attr; - num_attribs = zend_hash_num_elements(Z_ARRVAL_P(tmp)); + uint32_t num_attribs = zend_hash_num_elements(Z_ARRVAL_P(tmp)); ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0); tmpstrings1 = safe_emalloc(num_attribs, sizeof(zend_string*), 0); num_tmpstrings1 = 0; - for (i = 0; idefault_object_handlers = &ldap_link_object_handlers; memcpy(&ldap_link_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ldap_link_object_handlers.offset = XtOffsetOf(ldap_linkdata, std); + ldap_link_object_handlers.offset = offsetof(ldap_linkdata, std); ldap_link_object_handlers.free_obj = ldap_link_free_obj; ldap_link_object_handlers.get_constructor = ldap_link_get_constructor; ldap_link_object_handlers.clone_obj = NULL; @@ -895,7 +888,7 @@ PHP_MINIT_FUNCTION(ldap) ldap_result_ce->default_object_handlers = &ldap_result_object_handlers; memcpy(&ldap_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ldap_result_object_handlers.offset = XtOffsetOf(ldap_resultdata, std); + ldap_result_object_handlers.offset = offsetof(ldap_resultdata, std); ldap_result_object_handlers.free_obj = ldap_result_free_obj; ldap_result_object_handlers.get_constructor = ldap_result_get_constructor; ldap_result_object_handlers.clone_obj = NULL; @@ -906,7 +899,7 @@ PHP_MINIT_FUNCTION(ldap) ldap_result_entry_ce->default_object_handlers = &ldap_result_entry_object_handlers; memcpy(&ldap_result_entry_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - ldap_result_entry_object_handlers.offset = XtOffsetOf(ldap_result_entry, std); + ldap_result_entry_object_handlers.offset = offsetof(ldap_result_entry, std); ldap_result_entry_object_handlers.free_obj = ldap_result_entry_free_obj; ldap_result_entry_object_handlers.get_constructor = ldap_result_entry_get_constructor; ldap_result_entry_object_handlers.clone_obj = NULL; @@ -982,15 +975,15 @@ PHP_FUNCTION(ldap_connect) LDAP *ldap = NULL; if (ZEND_NUM_ARGS() > 2) { - zend_error(E_DEPRECATED, "Calling ldap_connect() with Oracle-specific arguments is deprecated, " - "use ldap_connect_wallet() instead"); + zend_error(E_DEPRECATED, "Calling ldap_connect() with Oracle-specific arguments is deprecated"); } else if (ZEND_NUM_ARGS() == 2) { zend_error(E_DEPRECATED, "Usage of ldap_connect with two arguments is deprecated"); } #ifdef HAVE_ORALDAP if (ZEND_NUM_ARGS() == 3 || ZEND_NUM_ARGS() == 4) { - WRONG_PARAM_COUNT; + zend_wrong_param_count(); + RETURN_THROWS(); } if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!lssl", &host, &hostlen, &port, &wallet, &walletlen, &walletpasswd, &walletpasswdlen, &authmode) != SUCCESS) { @@ -1226,9 +1219,6 @@ PHP_FUNCTION(ldap_bind_ext) HashTable *server_controls_ht = NULL; ldap_linkdata *ld; LDAPControl **lserverctrls = NULL; - ldap_resultdata *result; - LDAPMessage *ldap_res; - int rc; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|p!p!h!", &link, ldap_link_ce, &ldap_bind_dn, &ldap_bind_dnlen, &ldap_bind_pw, &ldap_bind_pwlen, &server_controls_ht) != SUCCESS) { RETURN_THROWS(); @@ -1249,6 +1239,7 @@ PHP_FUNCTION(ldap_bind_ext) /* ldap_simple_bind() is deprecated, use ldap_sasl_bind() instead */ struct berval cred; int msgid; + int rc; cred.bv_val = ldap_bind_pw; cred.bv_len = ldap_bind_pw ? ldap_bind_pwlen : 0; @@ -1261,6 +1252,7 @@ PHP_FUNCTION(ldap_bind_ext) goto cleanup; } + LDAPMessage *ldap_res; rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res); if (rc == -1) { php_error_docref(NULL, E_WARNING, "Bind operation failed"); @@ -1270,7 +1262,7 @@ PHP_FUNCTION(ldap_bind_ext) /* return a PHP control object */ object_init_ex(return_value, ldap_result_ce); - result = Z_LDAP_RESULT_P(return_value); + ldap_resultdata *result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; } @@ -1491,7 +1483,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) LDAPControl **lserverctrls = NULL; int ldap_attrsonly = 0, ldap_sizelimit = -1, ldap_timelimit = -1, ldap_deref = -1; int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1; - int ret = 1, ldap_errno, argcount = ZEND_NUM_ARGS(); + bool has_errors = false; ZEND_PARSE_PARAMETERS_START(3, 9) Z_PARAM_ZVAL(link) @@ -1507,7 +1499,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ZEND_PARSE_PARAMETERS_END(); /* Reverse -> fall through */ - switch (argcount) { + switch (ZEND_NUM_ARGS()) { case 9: case 8: ldap_deref = deref; @@ -1546,13 +1538,13 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ZVAL_DEREF(attribute_zv); if (Z_TYPE_P(attribute_zv) != IS_STRING) { zend_argument_type_error(4, "must be a list of strings, %s given", zend_zval_value_name(attribute_zv)); - ret = 0; + has_errors = true; goto cleanup; } zend_string *attribute = Z_STR_P(attribute_zv); if (zend_str_has_nul_byte(attribute)) { zend_argument_value_error(4, "must not contain strings with any null bytes"); - ret = 0; + has_errors = true; goto cleanup; } ldap_attrs[attribute_index++] = ZSTR_VAL(attribute); @@ -1568,12 +1560,12 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) uint32_t num_links = zend_hash_num_elements(Z_ARRVAL_P(link)); if (num_links == 0) { zend_argument_must_not_be_empty_error(1); - ret = 0; + has_errors = true; goto cleanup; } if (!zend_array_is_list(Z_ARRVAL_P(link))) { zend_argument_value_error(1, "must be a list"); - ret = 0; + has_errors = true; goto cleanup; } @@ -1581,19 +1573,19 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) if (base_dn_ht) { if (!zend_array_is_list(base_dn_ht)) { zend_argument_value_error(2, "must be a list"); - ret = 0; + has_errors = true; goto cleanup; } num_base_dns = zend_hash_num_elements(base_dn_ht); if (num_base_dns != num_links) { zend_argument_value_error(2, "must be the same size as argument #1"); - ret = 0; + has_errors = true; goto cleanup; } } else { if (zend_str_has_nul_byte(base_dn_str)) { zend_argument_value_error(2, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup; } ldap_base_dn = base_dn_str; @@ -1603,19 +1595,19 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) if (filter_ht) { if (!zend_array_is_list(filter_ht)) { zend_argument_value_error(3, "must be a list"); - ret = 0; + has_errors = true; goto cleanup; } num_filters = zend_hash_num_elements(filter_ht); if (num_filters != num_links) { zend_argument_value_error(3, "must be the same size as argument #1"); - ret = 0; + has_errors = true; goto cleanup; } } else { if (zend_str_has_nul_byte(filter_str)) { zend_argument_value_error(3, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup; } ldap_filter = filter_str; @@ -1632,14 +1624,14 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ZVAL_DEREF(link_zv); if (Z_TYPE_P(link_zv) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(link_zv), ldap_link_ce)) { zend_argument_value_error(1, "must be a list of LDAP\\Connection"); - ret = 0; + has_errors = true; goto cleanup_parallel; } ldap_linkdata *current_ld = Z_LDAP_LINK_P(link_zv); if (!current_ld->link) { zend_throw_error(NULL, "LDAP connection has already been closed"); - ret = 0; + has_errors = true; goto cleanup_parallel; } @@ -1649,13 +1641,13 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ZVAL_DEREF(base_dn_zv); if (Z_TYPE_P(base_dn_zv) != IS_STRING) { zend_argument_type_error(2, "must be a list of strings, %s given", zend_zval_value_name(base_dn_zv)); - ret = 0; + has_errors = true; goto cleanup_parallel; } ldap_base_dn = Z_STR_P(base_dn_zv); if (zend_str_has_nul_byte(ldap_base_dn)) { zend_argument_value_error(2, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup_parallel; } } @@ -1665,13 +1657,13 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ZVAL_DEREF(filter_zv); if (Z_TYPE_P(filter_zv) != IS_STRING) { zend_argument_type_error(3, "must be a list of strings, %s given", zend_zval_value_name(filter_zv)); - ret = 0; + has_errors = true; goto cleanup_parallel; } ldap_filter = Z_STR_P(filter_zv); if (zend_str_has_nul_byte(ldap_filter)) { zend_argument_value_error(3, "must not contain null bytes"); - ret = 0; + has_errors = true; goto cleanup_parallel; } } @@ -1721,26 +1713,26 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ld = Z_LDAP_LINK_P(link); if (!ld->link) { zend_throw_error(NULL, "LDAP connection has already been closed"); - ret = 0; + has_errors = true; goto cleanup; } if (!base_dn_str) { zend_argument_type_error(2, "must be of type string when argument #1 ($ldap) is an LDAP\\Connection instance"); - ret = 0; + has_errors = true; goto cleanup; } if (!filter_str) { zend_argument_type_error(3, "must be of type string when argument #1 ($ldap) is an LDAP\\Connection instance"); - ret = 0; + has_errors = true; goto cleanup; } if (server_controls_ht) { lserverctrls = php_ldap_controls_from_array(ld->link, server_controls_ht, 9); if (lserverctrls == NULL) { - ret = 0; + has_errors = true; goto cleanup; } } @@ -1748,7 +1740,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) php_set_opts(ld->link, ldap_sizelimit, ldap_timelimit, ldap_deref, &old_ldap_sizelimit, &old_ldap_timelimit, &old_ldap_deref); /* Run the actual search */ - ldap_errno = ldap_search_ext_s(ld->link, ZSTR_VAL(base_dn_str), scope, ZSTR_VAL(filter_str), ldap_attrs, ldap_attrsonly, lserverctrls, NULL, NULL, ldap_sizelimit, &ldap_res); + int ldap_errno = ldap_search_ext_s(ld->link, ZSTR_VAL(base_dn_str), scope, ZSTR_VAL(filter_str), ldap_attrs, ldap_attrsonly, lserverctrls, NULL, NULL, ldap_sizelimit, &ldap_res); if (ldap_errno != LDAP_SUCCESS && ldap_errno != LDAP_SIZELIMIT_EXCEEDED @@ -1765,7 +1757,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ldap_msgfree(ldap_res); } php_error_docref(NULL, E_WARNING, "Search: %s", ldap_err2string(ldap_errno)); - ret = 0; + has_errors = true; } else { if (ldap_errno == LDAP_SIZELIMIT_EXCEEDED) { php_error_docref(NULL, E_WARNING, "Partial search results returned: Sizelimit exceeded"); @@ -1791,8 +1783,8 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) if (ldap_attrs != NULL) { efree(ldap_attrs); } - if (!ret) { - RETVAL_BOOL(ret); + if (has_errors) { + RETVAL_FALSE; } if (lserverctrls) { _php_ldap_controls_free(&lserverctrls); @@ -1866,7 +1858,6 @@ PHP_FUNCTION(ldap_first_entry) { zval *link, *result; ldap_linkdata *ld; - ldap_result_entry *resultentry; ldap_resultdata *ldap_result; LDAPMessage *entry; @@ -1884,7 +1875,7 @@ PHP_FUNCTION(ldap_first_entry) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry->res, result); resultentry->data = entry; resultentry->ber = NULL; @@ -1897,7 +1888,7 @@ PHP_FUNCTION(ldap_next_entry) { zval *link, *result_entry; ldap_linkdata *ld; - ldap_result_entry *resultentry, *resultentry_next; + ldap_result_entry *resultentry; LDAPMessage *entry_next; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce) != SUCCESS) { @@ -1913,7 +1904,7 @@ PHP_FUNCTION(ldap_next_entry) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry_next->res, &resultentry->res); resultentry_next->data = entry_next; resultentry_next->ber = NULL; @@ -1927,14 +1918,10 @@ PHP_FUNCTION(ldap_get_entries) zval *link, *result; ldap_resultdata *ldap_result; LDAPMessage *ldap_result_entry; - zval tmp1, tmp2; ldap_linkdata *ld; LDAP *ldap; - int num_entries, num_attrib, num_values, i; + int num_entries; BerElement *ber; - char *attribute; - size_t attr_len; - struct berval **ldap_value; char *dn; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result, ldap_result_ce) != SUCCESS) { @@ -1965,23 +1952,25 @@ PHP_FUNCTION(ldap_get_entries) num_entries = 0; while (ldap_result_entry != NULL) { + zval tmp1; array_init(&tmp1); - num_attrib = 0; - attribute = ldap_first_attribute(ldap, ldap_result_entry, &ber); + int num_attrib = 0; + char *attribute = ldap_first_attribute(ldap, ldap_result_entry, &ber); while (attribute != NULL) { - ldap_value = ldap_get_values_len(ldap, ldap_result_entry, attribute); - num_values = ldap_count_values_len(ldap_value); + struct berval **ldap_value = ldap_get_values_len(ldap, ldap_result_entry, attribute); + int num_values = ldap_count_values_len(ldap_value); + zval tmp2; array_init(&tmp2); add_assoc_long(&tmp2, "count", num_values); - for (i = 0; i < num_values; i++) { + for (int i = 0; i < num_values; i++) { add_index_stringl(&tmp2, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len); } ldap_value_free_len(ldap_value); - attr_len = strlen(attribute); + size_t attr_len = strlen(attribute); zend_str_tolower(attribute, attr_len); zend_hash_str_update(Z_ARRVAL(tmp1), attribute, attr_len, &tmp2); add_index_string(&tmp1, num_attrib, attribute); @@ -2093,12 +2082,10 @@ PHP_FUNCTION(ldap_next_attribute) PHP_FUNCTION(ldap_get_attributes) { zval *link, *result_entry; - zval tmp; ldap_linkdata *ld; ldap_result_entry *resultentry; char *attribute; - struct berval **ldap_value; - int i, num_values, num_attrib; + int num_attrib; BerElement *ber; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce) != SUCCESS) { @@ -2115,12 +2102,13 @@ PHP_FUNCTION(ldap_get_attributes) attribute = ldap_first_attribute(ld->link, resultentry->data, &ber); while (attribute != NULL) { - ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute); - num_values = ldap_count_values_len(ldap_value); + struct berval **ldap_value = ldap_get_values_len(ld->link, resultentry->data, attribute); + int num_values = ldap_count_values_len(ldap_value); + zval tmp; array_init(&tmp); add_assoc_long(&tmp, "count", num_values); - for (i = 0; i < num_values; i++) { + for (int i = 0; i < num_values; i++) { add_index_stringl(&tmp, i, ldap_value[i]->bv_val, ldap_value[i]->bv_len); } ldap_value_free_len(ldap_value); @@ -2152,7 +2140,7 @@ PHP_FUNCTION(ldap_get_values_len) ldap_result_entry *resultentry; char *attr; struct berval **ldap_value_len; - int i, num_values; + int num_values; size_t attr_len; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OOp", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce, &attr, &attr_len) != SUCCESS) { @@ -2172,7 +2160,7 @@ PHP_FUNCTION(ldap_get_values_len) num_values = ldap_count_values_len(ldap_value_len); array_init(return_value); - for (i=0; ibv_val, ldap_value_len[i]->bv_len); } @@ -2267,7 +2255,7 @@ PHP_FUNCTION(ldap_dn2ufn) /* added to fix use of ldap_modify_add for doing an ldap_add, gerrit thomson. */ #define PHP_LD_FULL_ADD 0xff /* {{{ php_ldap_do_modify */ -static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) +static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, bool ext) { zval *link; ldap_linkdata *ld; @@ -2279,7 +2267,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) ldap_resultdata *result; LDAPMessage *ldap_res; size_t dn_len; - int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ + bool is_full_add = false; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oph/|h!", &link, ldap_link_ce, &dn, &dn_len, &attributes_ht, &server_controls_ht) != SUCCESS) { RETURN_THROWS(); @@ -2301,7 +2289,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) /* added by gerrit thomson to fix ldap_add using ldap_mod_add */ if (oper == PHP_LD_FULL_ADD) { oper = LDAP_MOD_ADD; - is_full_add = 1; + is_full_add = true; } /* end additional , gerrit thomson */ @@ -2350,9 +2338,14 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) SEPARATE_ARRAY(attribute_values); uint32_t num_values = zend_hash_num_elements(Z_ARRVAL_P(attribute_values)); if (num_values == 0) { - zend_argument_value_error(3, "attribute \"%s\" must be a non-empty list of attribute values", ZSTR_VAL(attribute)); - RETVAL_FALSE; - goto cleanup; + if (UNEXPECTED(oper == LDAP_MOD_ADD)) { + zend_argument_value_error(3, "attribute \"%s\" must be a non-empty list of attribute values", ZSTR_VAL(attribute)); + RETVAL_FALSE; + goto cleanup; + } + /* When we modify, we mean we delete the attribute */ + attribute_index++; + continue; } if (!php_ldap_is_numerically_indexed_array(Z_ARRVAL_P(attribute_values))) { zend_argument_value_error(3, "attribute \"%s\" must be an array of attribute values with numeric keys", ZSTR_VAL(attribute)); @@ -2396,7 +2389,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) /* check flag to see if do_mod was called to perform full add , gerrit thomson */ int ldap_status_code = LDAP_SUCCESS; int msgid; - if (is_full_add == 1) { + if (is_full_add) { if (ext) { ldap_status_code = ldap_add_ext(ld->link, dn, ldap_mods, lserverctrls, NULL, &msgid); } else { @@ -2439,7 +2432,9 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) object_init_ex(return_value, ldap_result_ce); result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; - } else RETVAL_TRUE; + } else { + RETVAL_TRUE; + } } cleanup: @@ -2469,14 +2464,14 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) PHP_FUNCTION(ldap_add) { /* use a newly define parameter into the do_modify so ldap_mod_add can be used the way it is supposed to be used , Gerrit THomson */ - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, false); } /* }}} */ /* {{{ Add entries to LDAP directory */ PHP_FUNCTION(ldap_add_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_LD_FULL_ADD, true); } /* }}} */ @@ -2485,54 +2480,52 @@ PHP_FUNCTION(ldap_add_ext) /* {{{ Replace attribute values with new ones */ PHP_FUNCTION(ldap_mod_replace) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, false); } /* }}} */ /* {{{ Replace attribute values with new ones */ PHP_FUNCTION(ldap_mod_replace_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_REPLACE, true); } /* }}} */ /* {{{ Add attribute values to current */ PHP_FUNCTION(ldap_mod_add) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, false); } /* }}} */ /* {{{ Add attribute values to current */ PHP_FUNCTION(ldap_mod_add_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_ADD, true); } /* }}} */ /* {{{ Delete attribute values */ PHP_FUNCTION(ldap_mod_del) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 0); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, false); } /* }}} */ /* {{{ Delete attribute values */ PHP_FUNCTION(ldap_mod_del_ext) { - php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, 1); + php_ldap_do_modify(INTERNAL_FUNCTION_PARAM_PASSTHRU, LDAP_MOD_DELETE, true); } /* }}} */ /* {{{ php_ldap_do_delete */ -static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) +static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, bool ext) { zval *link; HashTable *server_controls_ht = NULL; ldap_linkdata *ld; LDAPControl **lserverctrls = NULL; - ldap_resultdata *result; - LDAPMessage *ldap_res; char *dn; int rc, msgid; size_t dn_len; @@ -2562,6 +2555,7 @@ static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) RETVAL_FALSE; goto cleanup; } else if (ext) { + LDAPMessage *ldap_res; rc = ldap_result(ld->link, msgid, 1 /* LDAP_MSG_ALL */, NULL, &ldap_res); if (rc == -1) { php_error_docref(NULL, E_WARNING, "Delete operation failed"); @@ -2571,7 +2565,7 @@ static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) /* return a PHP control object */ object_init_ex(return_value, ldap_result_ce); - result = Z_LDAP_RESULT_P(return_value); + ldap_resultdata *result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; } else { RETVAL_TRUE; @@ -2589,14 +2583,14 @@ static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) /* {{{ Delete an entry from a directory */ PHP_FUNCTION(ldap_delete) { - php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ /* {{{ Delete an entry from a directory */ PHP_FUNCTION(ldap_delete_ext) { - php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_ldap_do_delete(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ @@ -2787,7 +2781,7 @@ PHP_FUNCTION(ldap_modify_batch) case LDAP_MODIFY_BATCH_REPLACE: ldap_operation = LDAP_MOD_REPLACE; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } /* fill in the basic info */ @@ -2806,8 +2800,8 @@ PHP_FUNCTION(ldap_modify_batch) zend_ulong value_index = 0; zval *modification_value_zv = NULL; ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(modification_values), modification_value_zv) { - zend_string *modval = zval_get_string(modification_value_zv); - if (EG(exception)) { + zend_string *modval = zval_try_get_string(modification_value_zv); + if (!modval) { RETVAL_FALSE; ldap_mods[modification_index]->mod_bvalues[value_index] = NULL; num_mods = modification_index + 1; @@ -3148,7 +3142,7 @@ PHP_FUNCTION(ldap_get_option) } RETURN_FALSE; } - _php_ldap_controls_to_array(ldap, ctrls, retval, 1); + _php_ldap_controls_to_array(ldap, ctrls, retval, true); } break; /* options not implemented case LDAP_OPT_API_INFO: @@ -3342,7 +3336,6 @@ PHP_FUNCTION(ldap_set_option) case LDAP_OPT_CLIENT_CONTROLS: { LDAPControl **ctrls; - int rc; if (Z_TYPE_P(newval) != IS_ARRAY) { zend_argument_type_error(3, "must be of type array for the LDAP_OPT_CLIENT_CONTROLS option, %s given", zend_zval_value_name(newval)); @@ -3354,7 +3347,7 @@ PHP_FUNCTION(ldap_set_option) if (ctrls == NULL) { RETURN_FALSE; } else { - rc = ldap_set_option(ldap, option, ctrls); + int rc = ldap_set_option(ldap, option, ctrls); _php_ldap_controls_free(&ctrls); if (rc != LDAP_SUCCESS) { RETURN_FALSE; @@ -3377,7 +3370,7 @@ PHP_FUNCTION(ldap_parse_result) ldap_linkdata *ld; ldap_resultdata *ldap_result; LDAPControl **lserverctrls = NULL; - char **lreferrals, **refp; + char **lreferrals; char *lmatcheddn, *lerrmsg; int rc, lerrcode; @@ -3405,7 +3398,7 @@ PHP_FUNCTION(ldap_parse_result) ZEND_TRY_ASSIGN_REF_LONG(errcode, lerrcode); if (serverctrls) { - _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, 0); + _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, false); } if (referrals) { referrals = zend_try_array_init(referrals); @@ -3413,7 +3406,7 @@ PHP_FUNCTION(ldap_parse_result) RETURN_THROWS(); } if (lreferrals != NULL) { - refp = lreferrals; + char **refp = lreferrals; while (*refp) { add_next_index_string(referrals, *refp); refp++; @@ -3526,7 +3519,6 @@ PHP_FUNCTION(ldap_first_reference) { zval *link, *result; ldap_linkdata *ld; - ldap_result_entry *resultentry; ldap_resultdata *ldap_result; LDAPMessage *entry; @@ -3544,7 +3536,7 @@ PHP_FUNCTION(ldap_first_reference) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry->res, result); resultentry->data = entry; resultentry->ber = NULL; @@ -3557,7 +3549,7 @@ PHP_FUNCTION(ldap_next_reference) { zval *link, *result_entry; ldap_linkdata *ld; - ldap_result_entry *resultentry, *resultentry_next; + ldap_result_entry *resultentry; LDAPMessage *entry_next; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce) != SUCCESS) { @@ -3573,7 +3565,7 @@ PHP_FUNCTION(ldap_next_reference) RETVAL_FALSE; } else { object_init_ex(return_value, ldap_result_entry_ce); - resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); + ldap_result_entry *resultentry_next = Z_LDAP_RESULT_ENTRY_P(return_value); ZVAL_COPY(&resultentry_next->res, &resultentry->res); resultentry_next->data = entry_next; resultentry_next->ber = NULL; @@ -3588,7 +3580,7 @@ PHP_FUNCTION(ldap_parse_reference) zval *link, *result_entry, *referrals; ldap_linkdata *ld; ldap_result_entry *resultentry; - char **lreferrals, **refp; + char **lreferrals; if (zend_parse_parameters(ZEND_NUM_ARGS(), "OOz", &link, ldap_link_ce, &result_entry, ldap_result_entry_ce, &referrals) != SUCCESS) { RETURN_THROWS(); @@ -3609,7 +3601,7 @@ PHP_FUNCTION(ldap_parse_reference) } if (lreferrals != NULL) { - refp = lreferrals; + char **refp = lreferrals; while (*refp) { add_next_index_string(referrals, *refp); refp++; @@ -3622,12 +3614,11 @@ PHP_FUNCTION(ldap_parse_reference) #endif /* {{{ php_ldap_do_rename */ -static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, int ext) +static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, bool ext) { zval *link; ldap_linkdata *ld; LDAPControl **lserverctrls = NULL; - ldap_resultdata *result; LDAPMessage *ldap_res; int rc, msgid; char *dn, *newrdn, *newparent; @@ -3689,7 +3680,7 @@ static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, int ext) /* return a PHP control object */ object_init_ex(return_value, ldap_result_ce); - result = Z_LDAP_RESULT_P(return_value); + ldap_resultdata *result = Z_LDAP_RESULT_P(return_value); result->result = ldap_res; } else { RETVAL_TRUE; @@ -3707,14 +3698,14 @@ static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, int ext) /* {{{ Modify the name of an entry */ PHP_FUNCTION(ldap_rename) { - php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ /* {{{ Modify the name of an entry */ PHP_FUNCTION(ldap_rename_ext) { - php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_ldap_do_rename(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ @@ -3725,7 +3716,8 @@ PHP_FUNCTION(ldap_rename_ext) */ static int _php_ldap_tls_newctx(LDAP *ld) { - int val = 0, i, opts[] = { + int val = 0, i; + int str_opts[] = { #if (LDAP_API_VERSION > 2000) LDAP_OPT_X_TLS_CACERTDIR, LDAP_OPT_X_TLS_CACERTFILE, @@ -3745,21 +3737,42 @@ static int _php_ldap_tls_newctx(LDAP *ld) #endif 0}; - for (i=0 ; opts[i] ; i++) { + for (i=0 ; str_opts[i] ; i++) { char *path = NULL; - ldap_get_option(ld, opts[i], &path); + ldap_get_option(ld, str_opts[i], &path); if (path) { /* already set locally */ ldap_memfree(path); } else { - ldap_get_option(NULL, opts[i], &path); + ldap_get_option(NULL, str_opts[i], &path); if (path) { /* set globally, inherit */ - ldap_set_option(ld, opts[i], path); + ldap_set_option(ld, str_opts[i], path); ldap_memfree(path); } } } +#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN + int int_opts[] = { + LDAP_OPT_X_TLS_PROTOCOL_MIN, +#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX + LDAP_OPT_X_TLS_PROTOCOL_MAX, +#endif + 0 + }; + for (i=0 ; int_opts[i] ; i++) { + int value = 0; + + ldap_get_option(ld, int_opts[i], &value); + if (value <= 0) { /* if value is not set already */ + ldap_get_option(NULL, int_opts[i], &value); + if (value > 0) { /* set globally, inherit */ + ldap_set_option(ld, int_opts[i], &value); + } + } + } +#endif + return ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &val); } @@ -3795,7 +3808,7 @@ PHP_FUNCTION(ldap_start_tls) #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) /* {{{ _ldap_rebind_proc() */ -int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgid, void *params) +static int _ldap_rebind_proc(LDAP *ldap, const char *url, ber_tag_t req, ber_int_t msgid, void *params) { ldap_linkdata *ld = NULL; int retval; @@ -3916,7 +3929,7 @@ static zend_string* php_ldap_do_escape(const bool *map, const char *value, size_ return ret; } -static void php_ldap_escape_map_set_chars(bool *map, const char *chars, const size_t charslen, char escape) +static void php_ldap_escape_map_set_chars(bool *map, const char *chars, const size_t charslen, bool escape) { size_t i = 0; while (i < charslen) { @@ -3928,9 +3941,8 @@ PHP_FUNCTION(ldap_escape) { char *value, *ignores; size_t valuelen = 0, ignoreslen = 0; - int i; zend_long flags = 0; - bool map[256] = {0}, havecharlist = 0; + bool map[256] = {0}, havecharlist = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|sl", &value, &valuelen, &ignores, &ignoreslen, &flags) != SUCCESS) { RETURN_THROWS(); @@ -3941,23 +3953,23 @@ PHP_FUNCTION(ldap_escape) } if (flags & PHP_LDAP_ESCAPE_FILTER) { - havecharlist = 1; - php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, 1); + havecharlist = true; + php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, true); } if (flags & PHP_LDAP_ESCAPE_DN) { - havecharlist = 1; - php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#\r", sizeof("\\,=+<>;\"#\r") - 1, 1); + havecharlist = true; + php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#\r", sizeof("\\,=+<>;\"#\r") - 1, true); } if (!havecharlist) { - for (i = 0; i < 256; i++) { - map[i] = 1; + for (uint16_t i = 0; i < 256; i++) { + map[i] = true; } } if (ignoreslen) { - php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0); + php_ldap_escape_map_set_chars(map, ignores, ignoreslen, false); } zend_string *result = php_ldap_do_escape(map, value, valuelen, flags); @@ -4212,7 +4224,7 @@ PHP_FUNCTION(ldap_exop_passwd) } if (serverctrls) { - _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, 0); + _php_ldap_controls_to_array(ld->link, lserverctrls, serverctrls, false); } /* return */ diff --git a/ext/ldap/ldap.stub.php b/ext/ldap/ldap.stub.php index f9f2aab85c40..52cf3828dba3 100644 --- a/ext/ldap/ldap.stub.php +++ b/ext/ldap/ldap.stub.php @@ -208,16 +208,19 @@ * @var int * @cvalue GSLC_SSL_NO_AUTH */ + #[\Deprecated(since: "8.5", message: "as it is broken since PHP 8.0")] const GSLC_SSL_NO_AUTH = UNKNOWN; /** * @var int * @cvalue GSLC_SSL_ONEWAY_AUTH */ + #[\Deprecated(since: "8.5", message: "as it is broken since PHP 8.0")] const GSLC_SSL_ONEWAY_AUTH = UNKNOWN; /** * @var int * @cvalue GSLC_SSL_TWOWAY_AUTH */ + #[\Deprecated(since: "8.5", message: "as it is broken since PHP 8.0")] const GSLC_SSL_TWOWAY_AUTH = UNKNOWN; #endif @@ -624,8 +627,10 @@ #endif #ifdef HAVE_ORALDAP + #[\Deprecated(since: "8.5", message: "as it is broken since PHP 8.0")] function ldap_connect(?string $uri = null, int $port = 389, string $wallet = UNKNOWN, #[\SensitiveParameter] string $password = UNKNOWN, int $auth_mode = GSLC_SSL_NO_AUTH): LDAP\Connection|false {} #ifdef LDAP_API_FEATURE_X_OPENLDAP + #[\Deprecated(since: "8.5", message: "as it is broken since PHP 8.0")] function ldap_connect_wallet(?string $uri = null, string $wallet, #[\SensitiveParameter] string $password, int $auth_mode = GSLC_SSL_NO_AUTH): LDAP\Connection|false {} #endif #else @@ -654,7 +659,7 @@ function ldap_list($ldap, array|string $base, array|string $filter, array $attri /** @param LDAP\Connection|array $ldap */ function ldap_search($ldap, array|string $base, array|string $filter, array $attributes = [], int $attributes_only = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): LDAP\Result|array|false {} - function ldap_free_result(LDAP\Result $result): bool {} + function ldap_free_result(LDAP\Result $result): true {} function ldap_count_entries(LDAP\Connection $ldap, LDAP\Result $result): int {} diff --git a/ext/ldap/ldap_arginfo.h b/ext/ldap/ldap_arginfo.h index 3341b736bb2f..8f5e7e34ba32 100644 --- a/ext/ldap/ldap_arginfo.h +++ b/ext/ldap/ldap_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: edd31d6c19c01bee6ddb04c747640c97f0bacba6 */ +/* This is a generated file, edit ldap.stub.php instead. + * Stub hash: 0dde8fd813f43640dee842c03365d7431858a56d */ #if defined(HAVE_ORALDAP) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_ldap_connect, 0, 0, LDAP\\Connection, MAY_BE_FALSE) @@ -75,7 +75,7 @@ ZEND_END_ARG_INFO() #define arginfo_ldap_search arginfo_ldap_read -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ldap_free_result, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ldap_free_result, 0, 1, IS_TRUE, 0) ZEND_ARG_OBJ_INFO(0, result, LDAP\\Result, 0) ZEND_END_ARG_INFO() @@ -434,10 +434,10 @@ ZEND_FUNCTION(ldap_parse_exop); static const zend_function_entry ext_functions[] = { #if defined(HAVE_ORALDAP) - ZEND_FE(ldap_connect, arginfo_ldap_connect) + ZEND_RAW_FENTRY("ldap_connect", zif_ldap_connect, arginfo_ldap_connect, ZEND_ACC_DEPRECATED, NULL, NULL) #endif #if defined(HAVE_ORALDAP) && defined(LDAP_API_FEATURE_X_OPENLDAP) - ZEND_FE(ldap_connect_wallet, arginfo_ldap_connect_wallet) + ZEND_RAW_FENTRY("ldap_connect_wallet", zif_ldap_connect_wallet, arginfo_ldap_connect_wallet, ZEND_ACC_DEPRECATED, NULL, NULL) #endif #if !(defined(HAVE_ORALDAP)) ZEND_FE(ldap_connect, arginfo_ldap_connect) @@ -593,9 +593,9 @@ static void register_ldap_symbols(int module_number) REGISTER_LONG_CONSTANT("LDAP_OPT_X_SASL_USERNAME", LDAP_OPT_X_SASL_USERNAME, CONST_PERSISTENT); #endif #if defined(HAVE_ORALDAP) - REGISTER_LONG_CONSTANT("GSLC_SSL_NO_AUTH", GSLC_SSL_NO_AUTH, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT); + zend_constant *const_GSLC_SSL_NO_AUTH = REGISTER_LONG_CONSTANT("GSLC_SSL_NO_AUTH", GSLC_SSL_NO_AUTH, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_GSLC_SSL_ONEWAY_AUTH = REGISTER_LONG_CONSTANT("GSLC_SSL_ONEWAY_AUTH", GSLC_SSL_ONEWAY_AUTH, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_GSLC_SSL_TWOWAY_AUTH = REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_DEPRECATED); #endif #if (LDAP_API_VERSION > 2000) REGISTER_LONG_CONSTANT("LDAP_OPT_X_TLS_REQUIRE_CERT", LDAP_OPT_X_TLS_REQUIRE_CERT, CONST_PERSISTENT); @@ -709,10 +709,24 @@ static void register_ldap_symbols(int module_number) #if defined(HAVE_ORALDAP) + zend_attribute *attribute_Deprecated_func_ldap_connect_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "ldap_connect", sizeof("ldap_connect") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_ldap_connect_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_ldap_connect_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_ldap_connect_0_arg1_str = zend_string_init("as it is broken since PHP 8.0", strlen("as it is broken since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_ldap_connect_0->args[1].value, attribute_Deprecated_func_ldap_connect_0_arg1_str); + attribute_Deprecated_func_ldap_connect_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "ldap_connect", sizeof("ldap_connect") - 1), 3, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); #endif #if defined(HAVE_ORALDAP) && defined(LDAP_API_FEATURE_X_OPENLDAP) + zend_attribute *attribute_Deprecated_func_ldap_connect_wallet_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "ldap_connect_wallet", sizeof("ldap_connect_wallet") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_ldap_connect_wallet_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_ldap_connect_wallet_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_ldap_connect_wallet_0_arg1_str = zend_string_init("as it is broken since PHP 8.0", strlen("as it is broken since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_func_ldap_connect_wallet_0->args[1].value, attribute_Deprecated_func_ldap_connect_wallet_0_arg1_str); + attribute_Deprecated_func_ldap_connect_wallet_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "ldap_connect_wallet", sizeof("ldap_connect_wallet") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); #endif @@ -729,6 +743,29 @@ static void register_ldap_symbols(int module_number) zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "ldap_exop_passwd", sizeof("ldap_exop_passwd") - 1), 3, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); #endif +#if defined(HAVE_ORALDAP) + + zend_attribute *attribute_Deprecated_const_GSLC_SSL_NO_AUTH_0 = zend_add_global_constant_attribute(const_GSLC_SSL_NO_AUTH, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_GSLC_SSL_NO_AUTH_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_GSLC_SSL_NO_AUTH_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_GSLC_SSL_NO_AUTH_0_arg1_str = zend_string_init("as it is broken since PHP 8.0", strlen("as it is broken since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_const_GSLC_SSL_NO_AUTH_0->args[1].value, attribute_Deprecated_const_GSLC_SSL_NO_AUTH_0_arg1_str); + attribute_Deprecated_const_GSLC_SSL_NO_AUTH_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_GSLC_SSL_ONEWAY_AUTH_0 = zend_add_global_constant_attribute(const_GSLC_SSL_ONEWAY_AUTH, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_GSLC_SSL_ONEWAY_AUTH_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_GSLC_SSL_ONEWAY_AUTH_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_GSLC_SSL_ONEWAY_AUTH_0_arg1_str = zend_string_init("as it is broken since PHP 8.0", strlen("as it is broken since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_const_GSLC_SSL_ONEWAY_AUTH_0->args[1].value, attribute_Deprecated_const_GSLC_SSL_ONEWAY_AUTH_0_arg1_str); + attribute_Deprecated_const_GSLC_SSL_ONEWAY_AUTH_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_GSLC_SSL_TWOWAY_AUTH_0 = zend_add_global_constant_attribute(const_GSLC_SSL_TWOWAY_AUTH, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_GSLC_SSL_TWOWAY_AUTH_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_GSLC_SSL_TWOWAY_AUTH_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_GSLC_SSL_TWOWAY_AUTH_0_arg1_str = zend_string_init("as it is broken since PHP 8.0", strlen("as it is broken since PHP 8.0"), 1); + ZVAL_STR(&attribute_Deprecated_const_GSLC_SSL_TWOWAY_AUTH_0->args[1].value, attribute_Deprecated_const_GSLC_SSL_TWOWAY_AUTH_0_arg1_str); + attribute_Deprecated_const_GSLC_SSL_TWOWAY_AUTH_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +#endif } static zend_class_entry *register_class_LDAP_Connection(void) diff --git a/ext/ldap/php_ldap.h b/ext/ldap/php_ldap.h index a8c4a77af801..a8591888fa83 100644 --- a/ext/ldap/php_ldap.h +++ b/ext/ldap/php_ldap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Amitay Isaacs | | Eric Warnke | diff --git a/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt b/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt index 8e2c4fb160de..fdee0cb43d6d 100644 --- a/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt +++ b/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt @@ -6,6 +6,7 @@ ldap memory_limit=-1 --SKIPIF-- diff --git a/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt b/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt index a69597084be6..ef64e25b89c6 100644 --- a/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt +++ b/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt @@ -6,6 +6,7 @@ ldap memory_limit=-1 --SKIPIF-- diff --git a/ext/ldap/tests/gh21262.phpt b/ext/ldap/tests/gh21262.phpt new file mode 100644 index 000000000000..3e414a9cbb12 --- /dev/null +++ b/ext/ldap/tests/gh21262.phpt @@ -0,0 +1,50 @@ +--TEST-- +GH-21262 (ldap_modify() too strict controls argument validation) +--EXTENSIONS-- +ldap +--FILE-- + 'value', + 'attribute2' => [], +]; + +// ldap_add() should still reject empty arrays +try { + ldap_add($ldap, $valid_dn, $entry_with_empty_array); +} catch (ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + +// ldap_mod_add() should still reject empty arrays +try { + ldap_mod_add($ldap, $valid_dn, $entry_with_empty_array); +} catch (ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + +// ldap_modify() should accept empty arrays (delete attribute) +try { + @ldap_modify($ldap, $valid_dn, $entry_with_empty_array); + echo "ldap_modify: no ValueError thrown", PHP_EOL; +} catch (ValueError $e) { + echo "ldap_modify: UNEXPECTED ValueError: ", $e->getMessage(), PHP_EOL; +} + +// ldap_mod_del() should accept empty arrays (delete attribute) +try { + @ldap_mod_del($ldap, $valid_dn, $entry_with_empty_array); + echo "ldap_mod_del: no ValueError thrown", PHP_EOL; +} catch (ValueError $e) { + echo "ldap_mod_del: UNEXPECTED ValueError: ", $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +ldap_add(): Argument #3 ($entry) attribute "attribute2" must be a non-empty list of attribute values +ldap_mod_add(): Argument #3 ($entry) attribute "attribute2" must be a non-empty list of attribute values +ldap_modify: no ValueError thrown +ldap_mod_del: no ValueError thrown diff --git a/ext/ldap/tests/ldap_set_option_leak_attrvalue_context.phpt b/ext/ldap/tests/ldap_set_option_leak_attrvalue_context.phpt new file mode 100644 index 000000000000..5829ad24faf5 --- /dev/null +++ b/ext/ldap/tests/ldap_set_option_leak_attrvalue_context.phpt @@ -0,0 +1,34 @@ +--TEST-- +ldap_set_option() - Leaks attrvalue and context +--EXTENSIONS-- +ldap +--FILE-- + "2.16.840.1.113730.3.4.9", "value" => ["attrvalue" => $attrvalue, "context" => $context, "before" => 0, "after" => 0]], +]; + +ldap_set_option($link, LDAP_OPT_CLIENT_CONTROLS, $controls); +ldap_get_option($link, LDAP_OPT_CLIENT_CONTROLS, $controls_out); + +var_dump($controls_out); +?> +--EXPECTF-- +array(1) { + ["2.16.840.1.113730.3.4.9"]=> + array(3) { + ["oid"]=> + string(23) "2.16.840.1.113730.3.4.9" + ["iscritical"]=> + bool(false) + ["value"]=> + string(28) "0%0%0 attrvaluecontext" + } +} diff --git a/ext/ldap/tests/ldap_start_tls_rc_max_version.conf b/ext/ldap/tests/ldap_start_tls_rc_max_version.conf new file mode 100644 index 000000000000..0cd03f8b8e19 --- /dev/null +++ b/ext/ldap/tests/ldap_start_tls_rc_max_version.conf @@ -0,0 +1 @@ +TLS_PROTOCOL_MAX 3.2 \ No newline at end of file diff --git a/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt new file mode 100644 index 000000000000..e983b97c4b4e --- /dev/null +++ b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt @@ -0,0 +1,45 @@ +--TEST-- +ldap_start_tls() - Basic ldap_start_tls test +--EXTENSIONS-- +ldap +--ENV-- +LDAPCONF={PWD}/ldap_start_tls_rc_max_version.conf +--SKIPIF-- + "OpenLDAP", + "min_version" => 20600, +]; +require_once __DIR__ .'/skipifbindfailure.inc'; +?> +--FILE-- + +--EXPECT-- +bool(false) +bool(false) +bool(false) diff --git a/ext/ldap/tests/skipifbindfailure.inc b/ext/ldap/tests/skipifbindfailure.inc index 1a0d0c6d1998..81c7998cfbb5 100644 --- a/ext/ldap/tests/skipifbindfailure.inc +++ b/ext/ldap/tests/skipifbindfailure.inc @@ -10,4 +10,37 @@ if ($skip_on_bind_failure) { ldap_unbind($link); } + +if (isset($require_vendor)) { + ob_start(); + phpinfo(INFO_MODULES); + $phpinfo = ob_get_clean(); + + // Extract the LDAP section specifically + if (preg_match('/^ldap\s*$(.*?)^[a-z_]+\s*$/ims', $phpinfo, $ldap_section_match)) { + $ldap_section = $ldap_section_match[1]; + + // Extract vendor info from the LDAP section only + if (preg_match('/Vendor Name\s*=>\s*(.+)/i', $ldap_section, $name_match) && + preg_match('/Vendor Version\s*=>\s*(\d+)/i', $ldap_section, $version_match)) { + + $vendor_name = trim($name_match[1]); + $vendor_version = (int)$version_match[1]; + + // Check vendor name if specified + if (isset($require_vendor['name']) && $vendor_name !== $require_vendor['name']) { + die("skip Requires {$require_vendor['name']} (detected: $vendor_name)"); + } + + // Check minimum version if specified + if (isset($require_vendor['min_version']) && $vendor_version < $require_vendor['min_version']) { + die("skip Requires minimum version {$require_vendor['min_version']} (detected: $vendor_version)"); + } + } else { + die("skip Cannot determine LDAP vendor information"); + } + } else { + die("skip LDAP extension information not found"); + } +} ?> diff --git a/ext/lexbor/config.m4 b/ext/lexbor/config.m4 index 3e67c10fdfc3..21fabcd0ddb0 100644 --- a/ext/lexbor/config.m4 +++ b/ext/lexbor/config.m4 @@ -2,7 +2,6 @@ PHP_LEXBOR_CFLAGS="-I@ext_srcdir@/" LEXBOR_DIR="lexbor" AC_DEFINE([HAVE_LEXBOR], [1], [Define to 1 if the PHP extension 'lexbor' is available.]) -AC_DEFINE([LEXBOR_VERSION], ["2.5.0"], [Define the main Lexbor version]) PHP_NEW_EXTENSION([lexbor], m4_normalize([ php_lexbor.c @@ -23,15 +22,23 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/core/shs.c $LEXBOR_DIR/core/str.c $LEXBOR_DIR/core/strtod.c + $LEXBOR_DIR/css/at_rule.c + $LEXBOR_DIR/css/at_rule/state.c + $LEXBOR_DIR/css/blank.c $LEXBOR_DIR/css/css.c + $LEXBOR_DIR/css/declaration.c $LEXBOR_DIR/css/log.c $LEXBOR_DIR/css/parser.c + $LEXBOR_DIR/css/property.c + $LEXBOR_DIR/css/property/state.c + $LEXBOR_DIR/css/rule.c $LEXBOR_DIR/css/selectors/pseudo_state.c $LEXBOR_DIR/css/selectors/pseudo.c $LEXBOR_DIR/css/selectors/selector.c $LEXBOR_DIR/css/selectors/selectors.c $LEXBOR_DIR/css/selectors/state.c $LEXBOR_DIR/css/state.c + $LEXBOR_DIR/css/stylesheet.c $LEXBOR_DIR/css/syntax/anb.c $LEXBOR_DIR/css/syntax/parser.c $LEXBOR_DIR/css/syntax/state.c @@ -39,6 +46,8 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/css/syntax/token.c $LEXBOR_DIR/css/syntax/tokenizer.c $LEXBOR_DIR/css/syntax/tokenizer/error.c + $LEXBOR_DIR/css/unit.c + $LEXBOR_DIR/css/value.c $LEXBOR_DIR/dom/interface.c $LEXBOR_DIR/dom/interfaces/attr.c $LEXBOR_DIR/dom/interfaces/cdata_section.c @@ -114,7 +123,9 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/html/interfaces/progress_element.c $LEXBOR_DIR/html/interfaces/quote_element.c $LEXBOR_DIR/html/interfaces/script_element.c + $LEXBOR_DIR/html/interfaces/search_element.c $LEXBOR_DIR/html/interfaces/select_element.c + $LEXBOR_DIR/html/interfaces/selectedcontent_element.c $LEXBOR_DIR/html/interfaces/slot_element.c $LEXBOR_DIR/html/interfaces/source_element.c $LEXBOR_DIR/html/interfaces/span_element.c @@ -135,6 +146,7 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/html/interfaces/video_element.c $LEXBOR_DIR/html/interfaces/window.c $LEXBOR_DIR/html/parser.c + $LEXBOR_DIR/html/tag.c $LEXBOR_DIR/html/token_attr.c $LEXBOR_DIR/html/token.c $LEXBOR_DIR/html/tokenizer.c @@ -164,8 +176,6 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ $LEXBOR_DIR/html/tree/insertion_mode/in_head_noscript.c $LEXBOR_DIR/html/tree/insertion_mode/in_head.c $LEXBOR_DIR/html/tree/insertion_mode/in_row.c - $LEXBOR_DIR/html/tree/insertion_mode/in_select_in_table.c - $LEXBOR_DIR/html/tree/insertion_mode/in_select.c $LEXBOR_DIR/html/tree/insertion_mode/in_table_body.c $LEXBOR_DIR/html/tree/insertion_mode/in_table_text.c $LEXBOR_DIR/html/tree/insertion_mode/in_table.c @@ -187,6 +197,8 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([ PHP_ADD_BUILD_DIR([ $ext_builddir/ $ext_builddir/$LEXBOR_DIR/core + $ext_builddir/$LEXBOR_DIR/css/at_rule + $ext_builddir/$LEXBOR_DIR/css/property $ext_builddir/$LEXBOR_DIR/css/selectors $ext_builddir/$LEXBOR_DIR/css/syntax/tokenizer $ext_builddir/$LEXBOR_DIR/css/tokenizer diff --git a/ext/lexbor/config.w32 b/ext/lexbor/config.w32 index bd1f3b383a7e..e75798e06187 100644 --- a/ext/lexbor/config.w32 +++ b/ext/lexbor/config.w32 @@ -8,11 +8,13 @@ ADD_SOURCES("ext/lexbor/lexbor/dom", "interface.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/dom/interfaces", "attr.c cdata_section.c character_data.c comment.c document.c document_fragment.c document_type.c element.c node.c processing_instruction.c shadow_root.c text.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/html/tokenizer", "error.c state_comment.c state_doctype.c state_rawtext.c state_rcdata.c state_script.c state.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/html/tree", "active_formatting.c open_elements.c error.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/html/tree/insertion_mode", "after_after_body.c after_after_frameset.c after_body.c after_frameset.c after_head.c before_head.c before_html.c foreign_content.c in_body.c in_caption.c in_cell.c in_column_group.c in_frameset.c in_head.c in_head_noscript.c initial.c in_row.c in_select.c in_select_in_table.c in_table_body.c in_table.c in_table_text.c in_template.c text.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/html", "encoding.c interface.c parser.c token.c token_attr.c tokenizer.c tree.c","lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/html/tree/insertion_mode", "after_after_body.c after_after_frameset.c after_body.c after_frameset.c after_head.c before_head.c before_html.c foreign_content.c in_body.c in_caption.c in_cell.c in_column_group.c in_frameset.c in_head.c in_head_noscript.c initial.c in_row.c in_table_body.c in_table.c in_table_text.c in_template.c text.c","lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/html", "encoding.c interface.c parser.c tag.c token.c token_attr.c tokenizer.c tree.c","lexbor"); ADD_SOURCES("ext/lexbor/lexbor/encoding", "decode.c encode.c encoding.c multi.c range.c res.c single.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/html/interfaces", "anchor_element.c area_element.c audio_element.c base_element.c body_element.c br_element.c button_element.c canvas_element.c data_element.c data_list_element.c details_element.c dialog_element.c directory_element.c div_element.c d_list_element.c document.c element.c embed_element.c field_set_element.c font_element.c form_element.c frame_element.c frame_set_element.c head_element.c heading_element.c hr_element.c html_element.c iframe_element.c image_element.c input_element.c label_element.c legend_element.c li_element.c link_element.c map_element.c marquee_element.c media_element.c menu_element.c meta_element.c meter_element.c mod_element.c object_element.c o_list_element.c opt_group_element.c option_element.c output_element.c paragraph_element.c param_element.c picture_element.c pre_element.c progress_element.c quote_element.c script_element.c select_element.c slot_element.c source_element.c span_element.c style_element.c table_caption_element.c table_cell_element.c table_col_element.c table_element.c table_row_element.c table_section_element.c template_element.c text_area_element.c time_element.c title_element.c track_element.c u_list_element.c unknown_element.c video_element.c window.c","lexbor"); -ADD_SOURCES("ext/lexbor/lexbor/css", "state.c log.c parser.c css.c","lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/html/interfaces", "anchor_element.c area_element.c audio_element.c base_element.c body_element.c br_element.c button_element.c canvas_element.c data_element.c data_list_element.c details_element.c dialog_element.c directory_element.c div_element.c d_list_element.c document.c element.c embed_element.c field_set_element.c font_element.c form_element.c frame_element.c frame_set_element.c head_element.c heading_element.c hr_element.c html_element.c iframe_element.c image_element.c input_element.c label_element.c legend_element.c li_element.c link_element.c map_element.c marquee_element.c media_element.c menu_element.c meta_element.c meter_element.c mod_element.c object_element.c o_list_element.c opt_group_element.c option_element.c output_element.c paragraph_element.c param_element.c picture_element.c pre_element.c progress_element.c quote_element.c script_element.c search_element.c select_element.c selectedcontent_element.c slot_element.c source_element.c span_element.c style_element.c table_caption_element.c table_cell_element.c table_col_element.c table_element.c table_row_element.c table_section_element.c template_element.c text_area_element.c time_element.c title_element.c track_element.c u_list_element.c unknown_element.c video_element.c window.c", "lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/css", "at_rule.c blank.c css.c declaration.c log.c parser.c property.c rule.c state.c stylesheet.c unit.c value.c", "lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/css/at_rule", "state.c", "lexbor"); +ADD_SOURCES("ext/lexbor/lexbor/css/property", "state.c", "lexbor"); ADD_SOURCES("ext/lexbor/lexbor/css/selectors", "state.c selectors.c selector.c pseudo_state.c pseudo.c","lexbor"); ADD_SOURCES("ext/lexbor/lexbor/css/syntax", "state.c parser.c syntax.c anb.c tokenizer.c token.c","lexbor"); ADD_SOURCES("ext/lexbor/lexbor/css/syntax/tokenizer", "error.c","lexbor"); @@ -24,6 +26,5 @@ ADD_SOURCES("ext/lexbor/lexbor/url", "url.c","lexbor"); ADD_FLAG("CFLAGS_LEXBOR", "/D LEXBOR_BUILDING /utf-8"); AC_DEFINE("HAVE_LEXBOR", 1, "Define to 1 if the PHP extension 'lexbor' is available."); -AC_DEFINE("LEXBOR_VERSION", "2.5.0", "Define the main Lexbor version") PHP_INSTALL_HEADERS("ext/lexbor", "php_lexbor.h lexbor/"); diff --git a/ext/lexbor/lexbor/core/base.h b/ext/lexbor/lexbor/core/base.h index 3c14dcff4cc3..e488dcf7334b 100644 --- a/ext/lexbor/lexbor/core/base.h +++ b/ext/lexbor/lexbor/core/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -26,8 +26,8 @@ extern "C" { #include "lexbor/core/types.h" #include "lexbor/core/lexbor.h" -#define LEXBOR_VERSION_MAJOR 1 -#define LEXBOR_VERSION_MINOR 8 +#define LEXBOR_VERSION_MAJOR 2 +#define LEXBOR_VERSION_MINOR 7 #define LEXBOR_VERSION_PATCH 0 #define LEXBOR_VERSION_STRING LEXBOR_STRINGIZE(LEXBOR_VERSION_MAJOR) "." \ @@ -39,6 +39,10 @@ extern "C" { #define lexbor_max(val1, val2) ((val1) > (val2) ? (val1) : (val2)) #define lexbor_min(val1, val2) ((val1) < (val2) ? (val1) : (val2)) +#define LEXBOR_STR_RES_MAP_CHAR_OTHER 0x00 +#define LEXBOR_STR_RES_MAP_CHAR_A_Z_a_z 0x01 +#define LEXBOR_STR_RES_MAP_CHAR_WHITESPACE 0x02 +#define LEXBOR_STR_RES_SLIP 0xFF /* * Very important!!! diff --git a/ext/lexbor/lexbor/core/def.h b/ext/lexbor/lexbor/core/def.h index 5a48f59e994d..c8b94400a2df 100644 --- a/ext/lexbor/lexbor/core/def.h +++ b/ext/lexbor/lexbor/core/def.h @@ -54,4 +54,6 @@ #define LXB_EXTERN extern LXB_API +#define lxb_size(_size) ((size_t) (_size)) + #endif /* LEXBOR_DEF_H */ diff --git a/ext/lexbor/lexbor/core/diyfp.c b/ext/lexbor/lexbor/core/diyfp.c index 62020bbc645e..7bdbcbbcb08f 100644 --- a/ext/lexbor/lexbor/core/diyfp.c +++ b/ext/lexbor/lexbor/core/diyfp.c @@ -1,16 +1,44 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_diyfp.c from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov * + * Based on nxt_diyfp.h from NGINX NJS project * An internal diy_fp implementation. * For details, see Loitsch, Florian. "Printing floating-point numbers quickly * and accurately with integers." ACM Sigplan Notices 45.6 (2010): 233-243. */ + #include "lexbor/core/diyfp.h" diff --git a/ext/lexbor/lexbor/core/diyfp.h b/ext/lexbor/lexbor/core/diyfp.h index 47fedb9da997..86c5336f2e03 100644 --- a/ext/lexbor/lexbor/core/diyfp.h +++ b/ext/lexbor/lexbor/core/diyfp.h @@ -1,11 +1,38 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_diyfp.h from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov * + * Based on nxt_diyfp.h from NGINX NJS project * An internal diy_fp implementation. * For details, see Loitsch, Florian. "Printing floating-point numbers quickly * and accurately with integers." ACM Sigplan Notices 45.6 (2010): 233-243. diff --git a/ext/lexbor/lexbor/core/dobject.h b/ext/lexbor/lexbor/core/dobject.h index c92930cfa932..69497fd40ec0 100644 --- a/ext/lexbor/lexbor/core/dobject.h +++ b/ext/lexbor/lexbor/core/dobject.h @@ -40,10 +40,6 @@ LXB_API lexbor_dobject_t * lexbor_dobject_destroy(lexbor_dobject_t *dobject, bool destroy_self); -LXB_API uint8_t * -lexbor_dobject_init_list_entries(lexbor_dobject_t *dobject, size_t pos); - - LXB_API void * lexbor_dobject_alloc(lexbor_dobject_t *dobject); diff --git a/ext/lexbor/lexbor/core/dtoa.c b/ext/lexbor/lexbor/core/dtoa.c index b1a4ee03258d..7da7ce013227 100644 --- a/ext/lexbor/lexbor/core/dtoa.c +++ b/ext/lexbor/lexbor/core/dtoa.c @@ -1,39 +1,36 @@ /* - * Copyright (C) Alexander Borisov - * - * Based on nxt_dtoa.c from NGINX NJS project - * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. - * - * Grisu2 algorithm implementation for printing floating-point numbers based - * upon the work of Milo Yip and Doug Currie. - * - * For algorithm information, see Loitsch, Florian. "Printing - * floating-point numbers quickly and accurately with integers." ACM Sigplan - * Notices 45.6 (2010): 233-243. - * - * Copyright (C) 2015 Doug Currie - * based on dtoa_milo.h - * Copyright (C) 2014 Milo Yip + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #include "lexbor/core/str.h" diff --git a/ext/lexbor/lexbor/core/dtoa.h b/ext/lexbor/lexbor/core/dtoa.h index c60c28803b7b..2d569cfff973 100644 --- a/ext/lexbor/lexbor/core/dtoa.h +++ b/ext/lexbor/lexbor/core/dtoa.h @@ -1,10 +1,36 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_dtoa.h from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) Nginx, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #ifndef LEXBOR_DTOA_H diff --git a/ext/lexbor/lexbor/core/hash.c b/ext/lexbor/lexbor/core/hash.c index 2fdd4caa9d98..c16466effd35 100644 --- a/ext/lexbor/lexbor/core/hash.c +++ b/ext/lexbor/lexbor/core/hash.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -10,9 +10,10 @@ #include "lexbor/core/str.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_MAP_UPPERCASE -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_uppercase[256]; +#endif /* Insert variable. */ diff --git a/ext/lexbor/lexbor/core/in.c b/ext/lexbor/lexbor/core/in.c index 9214e198950d..363256b732a4 100644 --- a/ext/lexbor/lexbor/core/in.c +++ b/ext/lexbor/lexbor/core/in.c @@ -1,11 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/core/in.h" -#include "lexbor/core/str_res.h" lexbor_in_t * @@ -65,7 +64,7 @@ lexbor_in_node_make(lexbor_in_t *incoming, lexbor_in_node_t *last_node, node->opt = LEXBOR_IN_OPT_UNDEF; node->begin = buf; - node->end = buf + buf_size; + node->end = buf ? (buf + buf_size) : NULL; node->use = buf; if (last_node != NULL) { diff --git a/ext/lexbor/lexbor/core/shs.c b/ext/lexbor/lexbor/core/shs.c index 679143bf45cc..c2753457d74a 100644 --- a/ext/lexbor/lexbor/core/shs.c +++ b/ext/lexbor/lexbor/core/shs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,10 @@ #include "lexbor/core/shs.h" #include "lexbor/core/str.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_MAP_UPPERCASE -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_uppercase[256]; +#endif #define lexbor_shs_make_id_m(key, size, table_size) \ (((((key[0] * key[size - 1]) * key[0]) + size) % table_size) + 0x01) diff --git a/ext/lexbor/lexbor/core/str.c b/ext/lexbor/lexbor/core/str.c index 0f04286bdea5..3d164ebf82dd 100644 --- a/ext/lexbor/lexbor/core/str.c +++ b/ext/lexbor/lexbor/core/str.c @@ -1,14 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/core/str.h" - -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_MAP_UPPERCASE #include "lexbor/core/str_res.h" @@ -80,6 +76,7 @@ lexbor_str_destroy(lexbor_str_t *str, lexbor_mraw_t *mraw, bool destroy_obj) } if (str->data != NULL) { + lexbor_str_clean(str); str->data = lexbor_mraw_free(mraw, str->data); } @@ -133,6 +130,10 @@ lexbor_str_append(lexbor_str_t *str, lexbor_mraw_t *mraw, { lxb_char_t *data_begin; + if (length == 0) { + return str->data; + } + lexbor_str_check_size_arg_m(str, lexbor_str_size(str), mraw, (length + 1), NULL); @@ -376,6 +377,30 @@ lexbor_str_whitespace_from_end(lexbor_str_t *target) return 0; } +lxb_char_t * +lexbor_str_copy_to(lexbor_str_t *str, const lxb_char_t *buff, size_t length) +{ + lxb_char_t *data_begin; + + data_begin = &str->data[str->length]; + memcpy(data_begin, buff, sizeof(lxb_char_t) * length); + + str->length += length; + + return data_begin; +} + +lxb_char_t * +lexbor_str_copy_to_with_null(lexbor_str_t *str, + const lxb_char_t *buff, size_t length) +{ + lxb_char_t *data_begin = lexbor_str_copy_to(str, buff, length); + + str->data[str->length] = '\0'; + + return data_begin; +} + /* * Data utils * TODO: All functions need optimization. diff --git a/ext/lexbor/lexbor/core/str.h b/ext/lexbor/lexbor/core/str.h index 3bee14537387..8e5f3806fe93 100644 --- a/ext/lexbor/lexbor/core/str.h +++ b/ext/lexbor/lexbor/core/str.h @@ -21,7 +21,6 @@ extern "C" { #define lexbor_str_len(str) lexbor_str_get(str, length) #define lexbor_str(p) {.data = (lxb_char_t *) (p), sizeof(p) - 1} - #define lexbor_str_check_size_arg_m(str, size, mraw, plus_len, return_fail) \ do { \ void *tmp; \ @@ -117,6 +116,12 @@ lexbor_str_whitespace_from_begin(lexbor_str_t *target); LXB_API size_t lexbor_str_whitespace_from_end(lexbor_str_t *target); +LXB_API lxb_char_t * +lexbor_str_copy_to(lexbor_str_t *str, const lxb_char_t *buff, size_t length); + +LXB_API lxb_char_t * +lexbor_str_copy_to_with_null(lexbor_str_t *str, + const lxb_char_t *buff, size_t length); /* Data utils */ /* diff --git a/ext/lexbor/lexbor/core/str_res.h b/ext/lexbor/lexbor/core/str_res.h index cebbda8aa534..be34a0eeb42c 100644 --- a/ext/lexbor/lexbor/core/str_res.h +++ b/ext/lexbor/lexbor/core/str_res.h @@ -1,32 +1,16 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ -#ifndef LEXBOR_STR_RES_H -#define LEXBOR_STR_RES_H -#define LEXBOR_STR_RES_MAP_CHAR_OTHER '\00' -#define LEXBOR_STR_RES_MAP_CHAR_A_Z_a_z '\01' -#define LEXBOR_STR_RES_MAP_CHAR_WHITESPACE '\02' +LXB_API const lxb_char_t +lexbor_str_res_ansi_replacement_character[4] = "\xEF\xBF\xBD"; -#define LEXBOR_STR_RES_SLIP 0xFF - -#endif /* LEXBOR_STR_RES_H */ - -#ifdef LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#ifndef LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER_ENABLED -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER_ENABLED -static const lxb_char_t -lexbor_str_res_ansi_replacement_character[] = "\xEF\xBF\xBD"; -#endif /* LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER */ - -#ifdef LEXBOR_STR_RES_MAP_NUM -#ifndef LEXBOR_STR_RES_MAP_NUM_ENABLED -#define LEXBOR_STR_RES_MAP_NUM_ENABLED -static const lxb_char_t lexbor_str_res_map_num[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_num[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -57,14 +41,10 @@ static const lxb_char_t lexbor_str_res_map_num[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_NUM_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_NUM */ - -#ifdef LEXBOR_STR_RES_MAP_HEX -#ifndef LEXBOR_STR_RES_MAP_HEX_ENABLED -#define LEXBOR_STR_RES_MAP_HEX_ENABLED -static const lxb_char_t lexbor_str_res_map_hex[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_hex[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -95,14 +75,10 @@ static const lxb_char_t lexbor_str_res_map_hex[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_HEX_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_HEX */ - -#ifdef LEXBOR_STR_RES_MAP_LOWERCASE -#ifndef LEXBOR_STR_RES_MAP_LOWERCASE_ENABLED -#define LEXBOR_STR_RES_MAP_LOWERCASE_ENABLED -static const lxb_char_t lexbor_str_res_map_lowercase[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_lowercase[256] = +{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, @@ -133,14 +109,10 @@ static const lxb_char_t lexbor_str_res_map_lowercase[] = { 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_LOWERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_LOWERCASE */ - -#ifdef LEXBOR_STR_RES_MAP_UPPERCASE -#ifndef LEXBOR_STR_RES_MAP_UPPERCASE_ENABLED -#define LEXBOR_STR_RES_MAP_UPPERCASE_ENABLED -static const lxb_char_t lexbor_str_res_map_uppercase[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_uppercase[256] = +{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, @@ -171,14 +143,10 @@ static const lxb_char_t lexbor_str_res_map_uppercase[] = { 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -#endif /* LEXBOR_STR_RES_MAP_UPPERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_UPPERCASE */ - -#ifdef LEXBOR_STR_RES_REPLACEMENT_CHARACTER -#ifndef LEXBOR_STR_RES_REPLACEMENT_CHARACTER_ENABLED -#define LEXBOR_STR_RES_REPLACEMENT_CHARACTER_ENABLED -static const size_t lexbor_str_res_replacement_character[] = { +LXB_API const size_t +lexbor_str_res_replacement_character[160] = +{ 65533, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, @@ -198,14 +166,10 @@ static const size_t lexbor_str_res_replacement_character[] = { 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376 }; -#endif /* LEXBOR_STR_RES_REPLACEMENT_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_REPLACEMENT_CHARACTER */ - -#ifdef LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER -#ifndef LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER_ENABLED -#define LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER_ENABLED -static const size_t lexbor_str_res_alphanumeric_character[] = { +LXB_API const size_t +lexbor_str_res_alphanumeric_character[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -236,14 +200,10 @@ static const size_t lexbor_str_res_alphanumeric_character[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER */ - -#ifdef LEXBOR_STR_RES_ALPHA_CHARACTER -#ifndef LEXBOR_STR_RES_ALPHA_CHARACTER_ENABLED -#define LEXBOR_STR_RES_ALPHA_CHARACTER_ENABLED -static const size_t lexbor_str_res_alpha_character[] = { +LXB_API const size_t +lexbor_str_res_alpha_character[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -274,14 +234,10 @@ static const size_t lexbor_str_res_alpha_character[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_STR_RES_ALPHA_CHARACTER_ENABLED */ -#endif /* LEXBOR_STR_RES_ALPHA_CHARACTER */ - -#ifdef LEXBOR_TOKENIZER_CHARS_MAP -#ifndef LEXBOR_TOKENIZER_CHARS_MAP_ENABLED -#define LEXBOR_TOKENIZER_CHARS_MAP_ENABLED -static const unsigned char lexbor_tokenizer_chars_map[] = { +LXB_API const unsigned char +lexbor_tokenizer_chars_map[256] = +{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x02, 0xff, 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -312,35 +268,24 @@ static const unsigned char lexbor_tokenizer_chars_map[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif /* LEXBOR_TOKENIZER_CHARS_MAP_ENABLED */ -#endif /* LEXBOR_TOKENIZER_CHARS_MAP */ - -#ifdef LEXBOR_STR_RES_MAP_HEX_TO_CHAR -#ifndef LEXBOR_STR_RES_MAP_HEX_TO_CHAR_ENABLED -#define LEXBOR_STR_RES_MAP_HEX_TO_CHAR_ENABLED -static const lxb_char_t lexbor_str_res_map_hex_to_char[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_hex_to_char[17] = +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x00 }; -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR */ -#ifdef LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE -#ifndef LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE_ENABLED -#define LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE_ENABLED -static const lxb_char_t lexbor_str_res_map_hex_to_char_lowercase[] = { +LXB_API const lxb_char_t +lexbor_str_res_map_hex_to_char_lowercase[17] = +{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x00 }; -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE */ - -#ifdef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE -#ifndef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_ENABLED -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_ENABLED -static const char * lexbor_str_res_char_to_two_hex_value[257] = { +LXB_API const char * +lexbor_str_res_char_to_two_hex_value[257] = +{ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", @@ -375,13 +320,10 @@ static const char * lexbor_str_res_char_to_two_hex_value[257] = { "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF", NULL }; -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_ENABLED */ -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE */ -#ifdef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE -#ifndef LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE_ENABLED -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE_ENABLED -static const char * lexbor_str_res_char_to_two_hex_value_lowercase[257] = { +LXB_API const char * +lexbor_str_res_char_to_two_hex_value_lowercase[257] = +{ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", @@ -416,5 +358,3 @@ static const char * lexbor_str_res_char_to_two_hex_value_lowercase[257] = { "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff", NULL }; -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE_ENABLED */ -#endif /* LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE */ diff --git a/ext/lexbor/lexbor/core/strtod.c b/ext/lexbor/lexbor/core/strtod.c index 6389fc3156fc..2dad45c109b5 100644 --- a/ext/lexbor/lexbor/core/strtod.c +++ b/ext/lexbor/lexbor/core/strtod.c @@ -1,14 +1,36 @@ /* - * Copyright (C) Alexander Borisov - * - * Based on nxt_strtod.c from NGINX NJS project + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * An internal strtod() implementation based upon V8 src/strtod.cc - * without bignum support. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright 2012 the V8 project authors. All rights reserved. - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #include diff --git a/ext/lexbor/lexbor/core/strtod.h b/ext/lexbor/lexbor/core/strtod.h index 7f15706bc946..0f834bab4868 100644 --- a/ext/lexbor/lexbor/core/strtod.h +++ b/ext/lexbor/lexbor/core/strtod.h @@ -1,10 +1,36 @@ /* - * Copyright (C) Alexander Borisov + * Copyright (C) 2015-2019 NGINX, Inc. + * Copyright (C) 2019-2025 F5, Inc. + * Copyright (C) 2015-2021 Igor Sysoev + * Copyright (C) 2017-2025 Dmitry Volyntsev + * Copyright (C) 2019-2022 Alexander Borisov + * Copyright (C) 2022-2025 Vadim Zhestikov + * All rights reserved. * - * Based on nxt_strtod.h from NGINX NJS project + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Copyright (C) Dmitry Volyntsev - * Copyright (C) Nginx, Inc. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (C) Alexander Borisov */ #ifndef LEXBOR_STRTOD_H diff --git a/ext/lexbor/lexbor/css/at_rule.c b/ext/lexbor/lexbor/css/at_rule.c new file mode 100644 index 000000000000..6c5435d22e06 --- /dev/null +++ b/ext/lexbor/lexbor/css/at_rule.c @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/at_rule.h" +#include "lexbor/css/css.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/at_rule/state.h" +#include "lexbor/css/at_rule/types.h" +#include "lexbor/css/at_rule/res.h" +#include "lexbor/core/serialize.h" + + +const lxb_css_entry_at_rule_data_t * +lxb_css_at_rule_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_at_rule_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_entry_at_rule_data_t * +lxb_css_at_rule_by_id(uintptr_t id) +{ + return &lxb_css_at_rule_data[id]; +} + +lxb_css_rule_at_t * +lxb_css_at_rule_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_at_rule_data_t **out_entry) +{ + void *prop; + const lxb_css_entry_at_rule_data_t *entry; + lxb_css_at_rule__custom_t *custom; + lxb_css_rule_at_t *at; + + at = lxb_css_rule_at_create(parser->memory); + if (at == NULL) { + return NULL; + } + + entry = lxb_css_at_rule_by_name(name, length); + if (entry == NULL) { + entry = lxb_css_at_rule_by_id(LXB_CSS_AT_RULE__CUSTOM); + + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + + custom = prop; + + (void) lexbor_str_init(&custom->name, parser->memory->mraw, length); + if (custom->name.data == NULL) { + goto failed; + } + + memcpy(custom->name.data, name, length); + + custom->name.length = length; + custom->name.data[custom->name.length] = 0x00; + } + else { + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + } + + at->type = entry->unique; + at->u.user = prop; + + if (out_entry != NULL) { + *out_entry = entry; + } + + return at; + +failed: + + if (prop != NULL) { + (void) entry->destroy(parser->memory, prop, true); + } + + if (at != NULL) { + (void) lxb_css_rule_at_destroy(at, true); + } + + if (out_entry != NULL) { + *out_entry = NULL; + } + + return NULL; +} + +void * +lxb_css_at_rule_destroy(lxb_css_memory_t *memory, void *value, + lxb_css_at_rule_type_t type, bool self_destroy) +{ + const lxb_css_entry_at_rule_data_t *data; + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return value; + } + + return data->destroy(memory, value, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_convert_to_undef(lxb_css_parser_t *parser, + lxb_css_rule_at_t *at) +{ + lxb_css_at_rule__undef_t *undef; + + undef = lxb_css_at_rule__undef_create(parser->memory); + if (undef == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + + undef->type = at->type; + + (void) lxb_css_at_rule_destroy(parser->memory, at, undef->type, false); + + at->type = LXB_CSS_AT_RULE__UNDEF; + at->u.undef = undef; + + return lxb_css_make_data(parser, &at->u.undef->prelude, + at->prelude_begin, at->prelude_end); +} + +lxb_status_t +lxb_css_at_rule_serialize(const void *style, lxb_css_at_rule_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_at_rule_data_t *data; + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return data->serialize(style, cb, ctx); +} + +lxb_status_t +lxb_css_at_rule_serialize_str(const void *style, lxb_css_at_rule_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_at_rule_data_t *data; + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return lxb_css_serialize_str_handler(style, str, mraw, data->serialize); +} + +lxb_status_t +lxb_css_at_rule_serialize_name(const void *style, lxb_css_at_rule_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_at_rule_data_t *data; + + if (type == LXB_CSS_AT_RULE__UNDEF) { + return lxb_css_at_rule__undef_serialize_name(style, cb, ctx); + } + else if (type == LXB_CSS_AT_RULE__CUSTOM) { + return lxb_css_at_rule__custom_serialize_name(style, cb, ctx); + } + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_at_rule_serialize_name_str(const void *style, lxb_css_at_rule_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_at_rule_data_t *data; + + if (type == LXB_CSS_AT_RULE__UNDEF) { + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_at_rule__undef_serialize_name); + } + else if (type == LXB_CSS_AT_RULE__CUSTOM) { + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_at_rule__custom_serialize_name); + } + + data = lxb_css_at_rule_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + if (str->data == NULL) { + lexbor_str_init(str, mraw, data->length); + if (str->data == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + + (void) lexbor_str_append(str, mraw, data->name, data->length); + + return LXB_STATUS_OK; +} + +/* _undef. */ + +void * +lxb_css_at_rule__undef_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_at_rule__undef_t)); +} + +void * +lxb_css_at_rule__undef_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_at_rule__undef_serialize(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + lxb_status_t status; + const lxb_css_entry_at_rule_data_t *data; + const lxb_css_at_rule__undef_t *undef = at; + + static const lxb_char_t wc_str[] = " "; + static const lxb_char_t lb_str[] = "{"; + static const lxb_char_t rb_str[] = "}"; + static const lxb_char_t sm_str[] = ";"; + + data = lxb_css_at_rule_by_id(undef->type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + if (undef->prelude.data != NULL) { + lexbor_serialize_write(cb, wc_str, (sizeof(wc_str) - 1), ctx, status); + lexbor_serialize_write(cb, undef->prelude.data, undef->prelude.length, + ctx, status); + } + + if (undef->block != NULL) { + lexbor_serialize_write(cb, lb_str, (sizeof(lb_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(undef->block, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, rb_str, (sizeof(rb_str) - 1), ctx, status); + } + else { + lexbor_serialize_write(cb, sm_str, (sizeof(sm_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_at_rule__undef_serialize_name(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + const lxb_css_entry_at_rule_data_t *data; + const lxb_css_at_rule__undef_t *undef = at; + + data = lxb_css_at_rule_by_id(undef->type); + if (data == NULL) { + return LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return cb(data->name, data->length, ctx); +} + +/* _custom. */ + +void * +lxb_css_at_rule__custom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_at_rule__custom_t)); +} + +void * +lxb_css_at_rule__custom_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_at_rule__custom_serialize(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + lxb_status_t status; + const lxb_css_at_rule__custom_t *custom = at; + + static const lxb_char_t ws_str[] = " "; + static const lxb_char_t lb_str[] = "{"; + static const lxb_char_t rb_str[] = "}"; + + + if (custom->prelude.data != NULL) { + lexbor_serialize_write(cb, ws_str, (sizeof(ws_str) - 1), ctx, status); + lexbor_serialize_write(cb, custom->prelude.data, custom->prelude.length, + ctx, status); + } + + if (custom->block != NULL) { + lexbor_serialize_write(cb, lb_str, (sizeof(lb_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(custom->block, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, rb_str, (sizeof(rb_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_at_rule__custom_serialize_name(const void *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + const lxb_css_at_rule__custom_t *custom = at; + + return cb(custom->name.data, custom->name.length, ctx); +} + +/* Media. */ + +void * +lxb_css_at_rule_media_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_at_rule_media_t)); +} + +void * +lxb_css_at_rule_media_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_at_rule__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_media_serialize(const void *style, lexbor_serialize_cb_f cb, + void *ctx) +{ + return LXB_STATUS_OK; +} + +/* Namespace. */ + +void * +lxb_css_at_rule_namespace_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_at_rule_namespace_t)); +} + +void * +lxb_css_at_rule_namespace_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_at_rule__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_namespace_serialize(const void *style, lexbor_serialize_cb_f cb, + void *ctx) +{ + return LXB_STATUS_OK; +} + +/* Font-face. */ + +void * +lxb_css_at_rule_font_face_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_at_rule_font_face_t)); +} + +void * +lxb_css_at_rule_font_face_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_at_rule__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_at_rule_font_face_serialize(const void *font_face, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_at_rule_font_face_t *ff = font_face; + + static const lxb_char_t lb_str[] = " {"; + static const lxb_char_t rb_str[] = "}"; + + if (ff->block != NULL) { + lexbor_serialize_write(cb, lb_str, (sizeof(lb_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(ff->block, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, rb_str, (sizeof(rb_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/at_rule.h b/ext/lexbor/lexbor/css/at_rule.h index a11455c14cd0..cacfa4c8cf2d 100644 --- a/ext/lexbor/lexbor/css/at_rule.h +++ b/ext/lexbor/lexbor/css/at_rule.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -19,19 +19,19 @@ extern "C" { typedef struct { lxb_css_at_rule_type_t type; lexbor_str_t prelude; - lexbor_str_t block; + lxb_css_rule_list_t *block; } lxb_css_at_rule__undef_t; typedef struct { - lexbor_str_t name; - lexbor_str_t prelude; - lexbor_str_t block; + lexbor_str_t name; + lexbor_str_t prelude; + lxb_css_rule_list_t *block; } lxb_css_at_rule__custom_t; typedef struct { - uintptr_t reserved; + lxb_css_rule_list_t *block; } lxb_css_at_rule_media_t; @@ -40,17 +40,31 @@ typedef struct { } lxb_css_at_rule_namespace_t; +typedef struct { + lxb_css_rule_list_t *block; +} +lxb_css_at_rule_font_face_t; -LXB_API const lxb_css_entry_data_t * + +LXB_API const lxb_css_entry_at_rule_data_t * lxb_css_at_rule_by_name(const lxb_char_t *name, size_t length); -LXB_API const lxb_css_entry_data_t * +LXB_API const lxb_css_entry_at_rule_data_t * lxb_css_at_rule_by_id(uintptr_t id); +LXB_API lxb_css_rule_at_t * +lxb_css_at_rule_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_at_rule_data_t **out_entry); + LXB_API void * lxb_css_at_rule_destroy(lxb_css_memory_t *memory, void *value, lxb_css_at_rule_type_t type, bool self_destroy); +LXB_API lxb_status_t +lxb_css_at_rule_convert_to_undef(lxb_css_parser_t *parser, + lxb_css_rule_at_t *at); + LXB_API lxb_status_t lxb_css_at_rule_serialize(const void *style, lxb_css_at_rule_type_t type, lexbor_serialize_cb_f cb, void *ctx); @@ -73,10 +87,6 @@ LXB_API void * lxb_css_at_rule__undef_destroy(lxb_css_memory_t *memory, void *style, bool self_destroy); LXB_API lxb_status_t -lxb_css_at_rule__undef_make(lxb_css_parser_t *parser, - lxb_css_at_rule__undef_t *undef, - const lxb_css_syntax_at_rule_offset_t *at_rule); -LXB_API lxb_status_t lxb_css_at_rule__undef_serialize(const void *style, lexbor_serialize_cb_f cb, void *ctx); LXB_API lxb_status_t @@ -92,10 +102,6 @@ LXB_API void * lxb_css_at_rule__custom_destroy(lxb_css_memory_t *memory, void *style, bool self_destroy); LXB_API lxb_status_t -lxb_css_at_rule__custom_make(lxb_css_parser_t *parser, - lxb_css_at_rule__custom_t *custom, - const lxb_css_syntax_at_rule_offset_t *at_rule); -LXB_API lxb_status_t lxb_css_at_rule__custom_serialize(const void *style, lexbor_serialize_cb_f cb, void *ctx); LXB_API lxb_status_t @@ -126,6 +132,18 @@ LXB_API lxb_status_t lxb_css_at_rule_namespace_serialize(const void *style, lexbor_serialize_cb_f cb, void *ctx); +/* Font-face. */ + +LXB_API void * +lxb_css_at_rule_font_face_create(lxb_css_memory_t *memory); + +LXB_API void * +lxb_css_at_rule_font_face_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy); + +LXB_API lxb_status_t +lxb_css_at_rule_font_face_serialize(const void *style, lexbor_serialize_cb_f cb, + void *ctx); #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/at_rule/const.h b/ext/lexbor/lexbor/css/at_rule/const.h index 961f933a2367..29ba3dd95488 100644 --- a/ext/lexbor/lexbor/css/at_rule/const.h +++ b/ext/lexbor/lexbor/css/at_rule/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -21,9 +21,10 @@ enum { LXB_CSS_AT_RULE__UNDEF = 0x0000, LXB_CSS_AT_RULE__CUSTOM = 0x0001, - LXB_CSS_AT_RULE_MEDIA = 0x0002, - LXB_CSS_AT_RULE_NAMESPACE = 0x0003, - LXB_CSS_AT_RULE__LAST_ENTRY = 0x0004 + LXB_CSS_AT_RULE_FONT_FACE = 0x0002, + LXB_CSS_AT_RULE_MEDIA = 0x0003, + LXB_CSS_AT_RULE_NAMESPACE = 0x0004, + LXB_CSS_AT_RULE__LAST_ENTRY = 0x0005 }; typedef uintptr_t lxb_css_at_rule_type_t; diff --git a/ext/lexbor/lexbor/css/at_rule/res.h b/ext/lexbor/lexbor/css/at_rule/res.h index 026a88ae0dd6..6604fb923f40 100644 --- a/ext/lexbor/lexbor/css/at_rule/res.h +++ b/ext/lexbor/lexbor/css/at_rule/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -18,16 +18,19 @@ #include "lexbor/css/at_rule/const.h" -static const lxb_css_entry_data_t lxb_css_at_rule_data[LXB_CSS_AT_RULE__LAST_ENTRY] = +static const lxb_css_entry_at_rule_data_t lxb_css_at_rule_data[LXB_CSS_AT_RULE__LAST_ENTRY] = { - {(lxb_char_t *) "#undef", 6, LXB_CSS_AT_RULE__UNDEF, lxb_css_at_rule_state__undef, + {(lxb_char_t *) "#undef", 6, LXB_CSS_AT_RULE__UNDEF, &lxb_css_at_rule__undef_cb, lxb_css_at_rule__undef_create, lxb_css_at_rule__undef_destroy, lxb_css_at_rule__undef_serialize, (void *) (uintptr_t) LXB_CSS_AT_RULE__UNDEF}, - {(lxb_char_t *) "#сustom", 7, LXB_CSS_AT_RULE__CUSTOM, lxb_css_at_rule_state__custom, + {(lxb_char_t *) "#сustom", 7, LXB_CSS_AT_RULE__CUSTOM, &lxb_css_at_rule__custom_cb, lxb_css_at_rule__custom_create, lxb_css_at_rule__custom_destroy, lxb_css_at_rule__custom_serialize, (void *) (uintptr_t) LXB_CSS_AT_RULE__CUSTOM}, - {(lxb_char_t *) "media", 5, LXB_CSS_AT_RULE_MEDIA, lxb_css_at_rule_state_media, + {(lxb_char_t *) "font-face", 9, LXB_CSS_AT_RULE_FONT_FACE, &lxb_css_at_rule_font_face_cb, + lxb_css_at_rule_font_face_create, lxb_css_at_rule_font_face_destroy, lxb_css_at_rule_font_face_serialize, + NULL}, + {(lxb_char_t *) "media", 5, LXB_CSS_AT_RULE_MEDIA, &lxb_css_at_rule_media_cb, lxb_css_at_rule_media_create, lxb_css_at_rule_media_destroy, lxb_css_at_rule_media_serialize, NULL}, - {(lxb_char_t *) "namespace", 9, LXB_CSS_AT_RULE_NAMESPACE, lxb_css_at_rule_state_namespace, + {(lxb_char_t *) "namespace", 9, LXB_CSS_AT_RULE_NAMESPACE, &lxb_css_at_rule_namespace_cb, lxb_css_at_rule_namespace_create, lxb_css_at_rule_namespace_destroy, lxb_css_at_rule_namespace_serialize, NULL} }; @@ -38,7 +41,7 @@ static const lexbor_shs_entry_t lxb_css_at_rule_shs[6] = {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"media", (void *) &lxb_css_at_rule_data[LXB_CSS_AT_RULE_MEDIA], 5, 0}, - {NULL, NULL, 0, 0}, + {"font-face", (void *) &lxb_css_at_rule_data[LXB_CSS_AT_RULE_FONT_FACE], 9, 0}, {"namespace", (void *) &lxb_css_at_rule_data[LXB_CSS_AT_RULE_NAMESPACE], 9, 0} }; diff --git a/ext/lexbor/lexbor/css/at_rule/state.c b/ext/lexbor/lexbor/css/at_rule/state.c new file mode 100644 index 000000000000..4df2f6085adf --- /dev/null +++ b/ext/lexbor/lexbor/css/at_rule/state.c @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/at_rule.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/rule.h" +#include "lexbor/css/blank.h" +#include "lexbor/css/at_rule/state.h" + + +/* Undef */ + +bool +lxb_css_at_rule__undef_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + /* Skip all prelude. */ + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule__undef_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + status = lxb_css_make_data(parser, &at->u.undef->prelude, + at->prelude_begin, at->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__undef_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule__undef_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + /* For _UNDEF and _CUSTOM, access here is not possible. */ + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule__undef_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + /* + * Here we do not check for failed because it cannot happen; we do not call + * failed anywhere in _UNDEF and _CUSTOM, we simply skip the tokens. + */ + + at->u.undef->block = block; + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Custom */ + +bool +lxb_css_at_rule__custom_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_at_rule__undef_prelude(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule__custom_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + status = lxb_css_make_data(parser, &at->u.custom->prelude, + at->prelude_begin, at->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__custom_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule__custom_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule__custom_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + /* + * Here we do not check for failed because it cannot happen; we do not call + * failed anywhere in _UNDEF and _CUSTOM, we simply skip the tokens. + */ + + at->u.custom->block = block; + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Namespace */ + +bool +lxb_css_at_rule_namespace_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule_namespace_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_namespace_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_parser_failed_set(parser, true); + + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule_namespace_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule_namespace_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + + if (failed) { + status = lxb_css_at_rule_convert_to_undef(parser, at); + if (status != LXB_STATUS_OK) { + return status; + } + + at->u.undef->block = lxb_css_syntax_returned(parser); + } + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Media */ + +bool +lxb_css_at_rule_media_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule_media_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_media_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule_media_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule_media_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *list = lxb_css_syntax_returned(parser); + + if (list != NULL && !failed) { + at->u.media->block = list; + } + else { + status = lxb_css_at_rule_convert_to_undef(parser, at); + if (status != LXB_STATUS_OK) { + return status; + } + + at->u.undef->block = list; + } + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +/* Font-face */ + +bool +lxb_css_at_rule_font_face_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + if (token->type != LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_at_rule_font_face_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_end = token->offset; + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_font_face_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_state_at_rule_block_begin(parser, token, ctx, out_rule); +} + +bool +lxb_css_at_rule_font_face_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + return lxb_css_at_rule__undef_prelude_failed(parser, token, ctx); +} + +lxb_status_t +lxb_css_at_rule_font_face_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + if (!failed) { + at->u.font_face->block = block; + } + else { + status = lxb_css_at_rule_convert_to_undef(parser, at); + if (status != LXB_STATUS_OK) { + return status; + } + + at->u.undef->block = block; + } + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/at_rule/state.h b/ext/lexbor/lexbor/css/at_rule/state.h index 65e17e40d0ff..337a23c86714 100644 --- a/ext/lexbor/lexbor/css/at_rule/state.h +++ b/ext/lexbor/lexbor/css/at_rule/state.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,18 +15,110 @@ extern "C" { LXB_API bool -lxb_css_at_rule_state__undef(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +lxb_css_at_rule__undef_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__undef_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__undef_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); LXB_API bool -lxb_css_at_rule_state__custom(lxb_css_parser_t *parser, +lxb_css_at_rule__undef_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__undef_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API bool +lxb_css_at_rule__custom_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__custom_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule__custom_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +LXB_API bool +lxb_css_at_rule__custom_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule__custom_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API bool +lxb_css_at_rule_namespace_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_namespace_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_namespace_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +LXB_API bool +lxb_css_at_rule_namespace_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_namespace_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API bool +lxb_css_at_rule_media_prelude(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_media_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_media_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); LXB_API bool -lxb_css_at_rule_state_media(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +lxb_css_at_rule_media_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_media_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + LXB_API bool -lxb_css_at_rule_state_namespace(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +lxb_css_at_rule_font_face_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_font_face_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_at_rule_font_face_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +LXB_API bool +lxb_css_at_rule_font_face_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +LXB_API lxb_status_t +lxb_css_at_rule_font_face_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/css/at_rule/types.h b/ext/lexbor/lexbor/css/at_rule/types.h new file mode 100644 index 000000000000..1079bb632230 --- /dev/null +++ b/ext/lexbor/lexbor/css/at_rule/types.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +/* + * Caution! + * This file generated by the script "utils/lexbor/css/names.py"! + * Do not change this file! + */ + + +#ifndef LXB_CSS_AT_RULE_TYPES_H +#define LXB_CSS_AT_RULE_TYPES_H + + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule__undef_cb = { + .prelude = lxb_css_at_rule__undef_prelude, + .prelude_end = lxb_css_at_rule__undef_prelude_end, + .block = lxb_css_at_rule__undef_block, + .cb.failed = lxb_css_at_rule__undef_prelude_failed, + .cb.end = lxb_css_at_rule__undef_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule__custom_cb = { + .prelude = lxb_css_at_rule__custom_prelude, + .prelude_end = lxb_css_at_rule__custom_prelude_end, + .block = lxb_css_at_rule__custom_block, + .cb.failed = lxb_css_at_rule__custom_prelude_failed, + .cb.end = lxb_css_at_rule__custom_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule_font_face_cb = { + .prelude = lxb_css_at_rule_font_face_prelude, + .prelude_end = lxb_css_at_rule_font_face_prelude_end, + .block = lxb_css_at_rule_font_face_block, + .cb.failed = lxb_css_at_rule_font_face_prelude_failed, + .cb.end = lxb_css_at_rule_font_face_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule_media_cb = { + .prelude = lxb_css_at_rule_media_prelude, + .prelude_end = lxb_css_at_rule_media_prelude_end, + .block = lxb_css_at_rule_media_block, + .cb.failed = lxb_css_at_rule_media_prelude_failed, + .cb.end = lxb_css_at_rule_media_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_at_rule_namespace_cb = { + .prelude = lxb_css_at_rule_namespace_prelude, + .prelude_end = lxb_css_at_rule_namespace_prelude_end, + .block = lxb_css_at_rule_namespace_block, + .cb.failed = lxb_css_at_rule_namespace_prelude_failed, + .cb.end = lxb_css_at_rule_namespace_end +}; + + + +#endif /* LXB_CSS_AT_RULE_TYPES_H */ diff --git a/ext/lexbor/lexbor/css/base.h b/ext/lexbor/lexbor/css/base.h index 3d3cdc6a7f28..26712ce7048f 100644 --- a/ext/lexbor/lexbor/css/base.h +++ b/ext/lexbor/lexbor/css/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2025 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -18,7 +18,7 @@ extern "C" { #define LXB_CSS_VERSION_MAJOR 1 -#define LXB_CSS_VERSION_MINOR 3 +#define LXB_CSS_VERSION_MINOR 4 #define LXB_CSS_VERSION_PATCH 0 #define LXB_CSS_VERSION_STRING \ @@ -45,6 +45,8 @@ typedef struct lxb_css_parser_error lxb_css_parser_error_t; typedef struct lxb_css_syntax_tokenizer lxb_css_syntax_tokenizer_t; typedef struct lxb_css_syntax_token lxb_css_syntax_token_t; +/* Callbacks. */ + typedef bool (*lxb_css_parser_state_f)(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); @@ -82,6 +84,21 @@ typedef struct { } lxb_css_entry_data_t; +typedef struct { + lxb_char_t *name; + size_t length; + uintptr_t unique; + + /* const lxb_css_syntax_cb_at_rule_t */ + const void *cbs; + + lxb_css_style_create_f create; + lxb_css_style_destroy_f destroy; + lxb_css_style_serialize_f serialize; + void *initial; +} +lxb_css_entry_at_rule_data_t; + typedef struct { lxb_char_t *name; size_t length; diff --git a/ext/lexbor/lexbor/css/blank.c b/ext/lexbor/lexbor/css/blank.c new file mode 100644 index 000000000000..80e60f76e198 --- /dev/null +++ b/ext/lexbor/lexbor/css/blank.c @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/blank.h" +#include "lexbor/css/state.h" +#include "lexbor/css/css.h" +#include "lexbor/css/at_rule/state.h" + + +static bool +lxb_css_blank_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_blank_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule); + +static bool +lxb_css_blank_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_blank_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +static bool +lxb_css_blank_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_blank_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_blank_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_blank_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_blank_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_blank_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +static bool +lxb_css_blank_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_blank_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static lxb_css_parser_state_f +lxb_css_blank_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +static bool +lxb_css_blank_declaration_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_blank_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed); + +static lxb_status_t +lxb_css_blank_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static bool +lxb_css_blank_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + + +static const lxb_css_syntax_cb_list_rules_t lxb_css_blank_list_rules = { + .at_rule = lxb_css_blank_at_rule_begin, + .qualified_rule = lxb_css_blank_qualified_rule_begin, + .next = lxb_css_blank_list_rules_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_blank_list_rules_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_blank_at_rule = { + .prelude = lxb_css_blank_at_rule_prelude, + .prelude_end = lxb_css_blank_at_rule_prelude_end, + .block = lxb_css_blank_at_rule_block_begin, + .cb.failed = lxb_css_blank_at_rule_prelude_failed, + .cb.end = lxb_css_blank_at_rule_end +}; + +static const lxb_css_syntax_cb_qualified_rule_t lxb_css_blank_qualified_rule = { + .prelude = lxb_css_blank_qualified_rule_prelude, + .prelude_end = lxb_css_blank_qualified_rule_prelude_end, + .block = lxb_css_blank_qualified_rule_block_begin, + .cb.failed = lxb_css_blank_qualified_rule_prelude_failed, + .cb.end = lxb_css_blank_qualified_rule_end +}; + +static const lxb_css_syntax_cb_block_t lxb_css_blank_block = { + .at_rule = lxb_css_blank_at_rule_begin, + .declarations = lxb_css_blank_declarations_begin, + .qualified_rule = lxb_css_blank_qualified_rule_begin, + .next = lxb_css_blank_block_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_blank_block_end, +}; + +static const lxb_css_syntax_cb_declarations_t lxb_css_blank_declaration = { + .name = lxb_css_blank_declaration_name, + .end = lxb_css_blank_declaration_end, + .cb.failed = lxb_css_blank_declarations_bad, + .cb.end = lxb_css_blank_declarations_end +}; + + +const lxb_css_syntax_cb_list_rules_t * +lxb_css_blank_cb_list_rules(void) +{ + return &lxb_css_blank_list_rules; +} + +const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_cb_at_rule(void) +{ + return &lxb_css_blank_at_rule; +} + +const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_cb_qualified_rule(void) +{ + return &lxb_css_blank_qualified_rule; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_blank_cb_block(void) +{ + return &lxb_css_blank_block; +} + +const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_cb_declarations(void) +{ + return &lxb_css_blank_declaration; +} + +static bool +lxb_css_blank_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule) +{ + return &lxb_css_blank_at_rule; +} + +static bool +lxb_css_blank_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_block; +} + +static bool +lxb_css_blank_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_qualified_rule; +} + +static bool +lxb_css_blank_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_block_t * +lxb_css_blank_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_block; +} + +static bool +lxb_css_blank_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static bool +lxb_css_blank_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return &lxb_css_blank_declaration; +} + +static lxb_css_parser_state_f +lxb_css_blank_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + return lxb_css_blank_declaration_value; +} + +static bool +lxb_css_blank_declaration_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_blank_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed) +{ + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_blank_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + return LXB_STATUS_OK; +} + +static bool +lxb_css_blank_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} diff --git a/ext/lexbor/lexbor/css/blank.h b/ext/lexbor/lexbor/css/blank.h new file mode 100644 index 000000000000..05a13bfa1207 --- /dev/null +++ b/ext/lexbor/lexbor/css/blank.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#ifndef LXB_CSS_BLANK_H +#define LXB_CSS_BLANK_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lexbor/css/base.h" +#include "lexbor/css/syntax/syntax.h" + + +LXB_API const lxb_css_syntax_cb_list_rules_t * +lxb_css_blank_cb_list_rules(void); + +LXB_API const lxb_css_syntax_cb_at_rule_t * +lxb_css_blank_cb_at_rule(void); + +LXB_API const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_blank_cb_qualified_rule(void); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_blank_cb_block(void); + +LXB_API const lxb_css_syntax_cb_declarations_t * +lxb_css_blank_cb_declarations(void); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LXB_CSS_BLANK_H */ diff --git a/ext/lexbor/lexbor/css/css.c b/ext/lexbor/lexbor/css/css.c index 3b6f0cb0f2f4..68c6c977e834 100644 --- a/ext/lexbor/lexbor/css/css.c +++ b/ext/lexbor/lexbor/css/css.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -155,15 +155,12 @@ lxb_css_memory_ref_dec_destroy(lxb_css_memory_t *memory) lxb_status_t lxb_css_make_data(lxb_css_parser_t *parser, lexbor_str_t *str, - uintptr_t begin, uintptr_t end) + size_t begin, size_t end) { - size_t length, offlen, len; - const lxb_char_t *pos; - const lexbor_str_t *tmp; + size_t length; + const lxb_char_t *p; - tmp = &parser->str; - - offlen = begin - parser->offset; + p = parser->tkz->in_begin; length = end - begin; if (str->data == NULL) { @@ -173,31 +170,9 @@ lxb_css_make_data(lxb_css_parser_t *parser, lexbor_str_t *str, } } - if (tmp->length > offlen) { - len = tmp->length - offlen; - - if (len >= length) { - memcpy(str->data + str->length, tmp->data + offlen, length); - goto done; - } - else { - memcpy(str->data + str->length, tmp->data + offlen, len); - } - - str->length += len; - - pos = parser->pos; - length -= len; - } - else { - pos = parser->pos + (offlen - tmp->length); - } - - memcpy(str->data + str->length, pos, length); - -done: + memcpy(str->data, p + begin, length); - str->length += length; + str->length = length; str->data[str->length] = '\0'; return LXB_STATUS_OK; diff --git a/ext/lexbor/lexbor/css/css.h b/ext/lexbor/lexbor/css/css.h index bb12978e3ee2..4ba7152334ba 100644 --- a/ext/lexbor/lexbor/css/css.h +++ b/ext/lexbor/lexbor/css/css.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -35,7 +35,7 @@ extern "C" { LXB_API lxb_status_t lxb_css_make_data(lxb_css_parser_t *parser, lexbor_str_t *str, - uintptr_t begin, uintptr_t end); + size_t begin, size_t end); LXB_API lxb_char_t * lxb_css_serialize_char_handler(const void *style, lxb_css_style_serialize_f cb, diff --git a/ext/lexbor/lexbor/css/declaration.c b/ext/lexbor/lexbor/css/declaration.c new file mode 100644 index 000000000000..e27571486f1f --- /dev/null +++ b/ext/lexbor/lexbor/css/declaration.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2022-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/declaration.h" + + +lxb_css_rule_declaration_t * +lxb_css_declaration_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_data_t **out_entry) +{ + void *prop; + const lxb_css_entry_data_t *entry; + lxb_css_property__custom_t *custom; + lxb_css_rule_declaration_t *declar; + + declar = lxb_css_rule_declaration_create(parser->memory); + if (declar == NULL) { + return NULL; + } + + entry = lxb_css_property_by_name(name, length); + if (entry == NULL) { + entry = lxb_css_property_by_id(LXB_CSS_PROPERTY__CUSTOM); + + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + + custom = prop; + + (void) lexbor_str_init(&custom->name, parser->memory->mraw, length); + if (custom->name.data == NULL) { + goto failed; + } + + memcpy(custom->name.data, name, length); + + custom->name.length = length; + custom->name.data[custom->name.length] = 0x00; + } + else { + prop = entry->create(parser->memory); + if (prop == NULL) { + goto failed; + } + } + + declar->type = entry->unique; + declar->u.user = prop; + + if (out_entry != NULL) { + *out_entry = entry; + } + + return declar; + +failed: + + if (prop != NULL) { + (void) entry->destroy(parser->memory, prop, true); + } + + if (declar != NULL) { + (void) lxb_css_rule_declaration_destroy(declar, true); + } + + if (out_entry != NULL) { + *out_entry = NULL; + } + + return NULL; +} + +lxb_css_rule_declaration_list_t * +lxb_css_declaration_list_parse(lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length) +{ + return lxb_css_syntax_parse_declarations(parser, + lxb_css_state_cb_declarations(), + data, length); +} diff --git a/ext/lexbor/lexbor/css/declaration.h b/ext/lexbor/lexbor/css/declaration.h index 1ea414e10bc7..53ab061aaa4c 100644 --- a/ext/lexbor/lexbor/css/declaration.h +++ b/ext/lexbor/lexbor/css/declaration.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Alexander Borisov + * Copyright (C) 2022-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,19 +15,14 @@ extern "C" { #include "lexbor/core/mraw.h" -LXB_API lxb_status_t -lxb_css_declaration_list_prepare(lxb_css_parser_t *parser, - lxb_css_memory_t *mem); +LXB_API lxb_css_rule_declaration_t * +lxb_css_declaration_create(lxb_css_parser_t *parser, + const lxb_char_t *name, size_t length, + const lxb_css_entry_data_t **out_entry); -LXB_API lxb_css_rule_declaration_list_t * -lxb_css_declaration_list_process(lxb_css_parser_t *parser, - const lxb_char_t *data, size_t length); - -LXB_API void -lxb_css_declaration_list_finish(lxb_css_parser_t *parser); LXB_API lxb_css_rule_declaration_list_t * -lxb_css_declaration_list_parse(lxb_css_parser_t *parser, lxb_css_memory_t *mem, +lxb_css_declaration_list_parse(lxb_css_parser_t *parser, const lxb_char_t *data, size_t length); diff --git a/ext/lexbor/lexbor/css/log.c b/ext/lexbor/lexbor/css/log.c index 08f6fc4fc5a1..d993e4715c62 100644 --- a/ext/lexbor/lexbor/css/log.c +++ b/ext/lexbor/lexbor/css/log.c @@ -152,7 +152,7 @@ lxb_css_log_format(lxb_css_log_t *log, lxb_css_log_type_t type, return NULL; } - msg = lxb_css_log_push(log, LXB_CSS_LOG_SYNTAX_ERROR, psize); + msg = lxb_css_log_push(log, type, psize); if (msg == NULL) { return NULL; } diff --git a/ext/lexbor/lexbor/css/parser.c b/ext/lexbor/lexbor/css/parser.c index 5ceffed0f970..625143864888 100644 --- a/ext/lexbor/lexbor/css/parser.c +++ b/ext/lexbor/lexbor/css/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -73,7 +73,6 @@ lxb_css_parser_init(lxb_css_parser_t *parser, lxb_css_syntax_tokenizer_t *tkz) parser->rules->context = NULL; /* Temp */ - parser->pos = NULL; parser->str.length = 0; parser->str_size = 4096; @@ -93,13 +92,35 @@ lxb_css_parser_init(lxb_css_parser_t *parser, lxb_css_syntax_tokenizer_t *tkz) parser->types_pos = NULL; parser->types_end = NULL; parser->stage = LXB_CSS_PARSER_CLEAN; - parser->receive_endings = false; parser->status = LXB_STATUS_OK; parser->fake_null = false; + parser->token_end.type = LXB_CSS_SYNTAX_TOKEN__END; return LXB_STATUS_OK; } +lxb_status_t +lxb_css_parser_selectors_init(lxb_css_parser_t *parser) +{ + lxb_status_t status; + + parser->selectors = lxb_css_selectors_create(); + status = lxb_css_selectors_init(parser->selectors); + if (status != LXB_STATUS_OK) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, true); + } + + return status; +} + +void +lxb_css_parser_selectors_destroy(lxb_css_parser_t *parser) +{ + if (parser->selectors != NULL) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, true); + } +} + void lxb_css_parser_clean(lxb_css_parser_t *parser) { @@ -111,7 +132,6 @@ lxb_css_parser_clean(lxb_css_parser_t *parser) parser->types_pos = parser->types_begin; parser->stage = LXB_CSS_PARSER_CLEAN; parser->status = LXB_STATUS_OK; - parser->pos = NULL; parser->str.length = 0; parser->fake_null = false; } @@ -331,6 +351,14 @@ lxb_css_parser_unexpected_data_status(lxb_css_parser_t *parser, return LXB_STATUS_ERROR_UNEXPECTED_DATA; } +void * +lxb_css_parser_memory_fail_null(lxb_css_parser_t *parser) +{ + parser->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + parser->loop = false; + return NULL; +} + bool lxb_css_parser_memory_fail(lxb_css_parser_t *parser) { @@ -347,3 +375,189 @@ lxb_css_parser_memory_fail_status(lxb_css_parser_t *parser) return LXB_STATUS_ERROR_MEMORY_ALLOCATION; } + +/* + * No-inline functions for ABI. + */ +lxb_status_t +lxb_css_parser_status_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_status(parser); +} + +lxb_css_memory_t * +lxb_css_parser_memory_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_memory(parser); +} + +void +lxb_css_parser_memory_set_noi(lxb_css_parser_t *parser, lxb_css_memory_t *memory) +{ + lxb_css_parser_memory_set(parser, memory); +} + +lxb_css_selectors_t * +lxb_css_parser_selectors_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_selectors(parser); +} + +void +lxb_css_parser_selectors_set_noi(lxb_css_parser_t *parser, + lxb_css_selectors_t *selectors) +{ + lxb_css_parser_selectors_set(parser, selectors); +} + +bool +lxb_css_parser_is_running_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_is_running(parser); +} + +bool +lxb_css_parser_status_is_unexpected_data_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_status_is_unexpected_data(parser); +} + +void +lxb_css_parser_failed_set_noi(lxb_css_parser_t *parser, bool is) +{ + lxb_css_parser_failed_set(parser, is); +} + +void +lxb_css_parser_failed_set_by_id_noi(lxb_css_parser_t *parser, int idx, bool is) +{ + lxb_css_parser_failed_set_by_id(parser, idx, is); +} + +bool +lxb_css_parser_is_failed_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_is_failed(parser); +} + +void +lxb_css_parser_set_ok_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_set_ok(parser); +} + +const lxb_char_t * +lxb_css_parser_buffer_noi(lxb_css_parser_t *parser, size_t *length) +{ + return lxb_css_parser_buffer(parser, length); +} + +void +lxb_css_parser_buffer_set_noi(lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length) +{ + lxb_css_parser_buffer_set(parser, data, length); +} + +lxb_css_parser_state_f +lxb_css_parser_state_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_state(parser); +} + +void +lxb_css_parser_state_set_noi(lxb_css_parser_t *parser, lxb_css_parser_state_f state) +{ + lxb_css_parser_state_set(parser, state); +} + +lxb_css_syntax_rule_t * +lxb_css_parser_current_rule_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_current_rule(parser); +} + +size_t +lxb_css_parser_rule_deep_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_rule_deep(parser); +} + +lxb_css_parser_state_t * +lxb_css_parser_states_pop_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_pop(parser); +} + +lxb_css_parser_state_t * +lxb_css_parser_states_to_root_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_to_root(parser); +} + +bool +lxb_css_parser_states_set_back_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_set_back(parser); +} + +void +lxb_css_parser_states_clean_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_states_clean(parser); +} + +lxb_css_parser_state_t * +lxb_css_parser_states_current_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_states_current(parser); +} + +void +lxb_css_parser_states_set_noi(lxb_css_parser_state_t *states, + lxb_css_parser_state_f state, void *context) +{ + lxb_css_parser_states_set(states, state, context); +} + +void +lxb_css_parser_states_up_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_states_up(parser); +} + +void +lxb_css_parser_states_down_noi(lxb_css_parser_t *parser) +{ + lxb_css_parser_states_down(parser); +} + +lxb_css_log_t * +lxb_css_parser_log_noi(lxb_css_parser_t *parser) +{ + return lxb_css_parser_log(parser); +} + +const lxb_css_syntax_token_t * +lxb_css_parser_token_end_noi(lxb_css_parser_t *parser, size_t offset) +{ + return lxb_css_parser_token_end(parser, offset); +} + +void +lxb_css_parser_set_context_noi(lxb_css_parser_t *parser, void *ctx) +{ + lxb_css_parser_set_context(parser, ctx); +} + +void +lxb_css_syntax_set_return_noi(lxb_css_parser_t *parser, void *value) +{ + lxb_css_syntax_set_return(parser, value); +} + +void * +lxb_css_syntax_returned_noi(lxb_css_parser_t *parser) +{ + return lxb_css_syntax_returned(parser); +} diff --git a/ext/lexbor/lexbor/css/parser.h b/ext/lexbor/lexbor/css/parser.h index 9a4dfae0b702..d703dcc2f13d 100644 --- a/ext/lexbor/lexbor/css/parser.h +++ b/ext/lexbor/lexbor/css/parser.h @@ -1,6 +1,5 @@ /* - - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -70,7 +69,6 @@ extern "C" { } \ while (false) - #define lxb_css_parser_token_status_wo_ws_m(parser, token) \ do { \ if ((token = lxb_css_syntax_parser_token(parser)) == NULL) { \ @@ -129,49 +127,44 @@ typedef enum { lxb_css_parser_stage_t; struct lxb_css_parser { - lxb_css_parser_state_f block; - void *context; - /* Modules */ - lxb_css_syntax_tokenizer_t *tkz; - lxb_css_selectors_t *selectors; - lxb_css_selectors_t *old_selectors; + lxb_css_syntax_tokenizer_t *tkz; + lxb_css_selectors_t *selectors; /* Memory for all structures. */ - lxb_css_memory_t *memory; - lxb_css_memory_t *old_memory; + lxb_css_memory_t *memory; /* Syntax parse rules. */ - lxb_css_syntax_rule_t *rules_begin; - lxb_css_syntax_rule_t *rules_end; - lxb_css_syntax_rule_t *rules; + lxb_css_syntax_rule_t *rules_begin; + lxb_css_syntax_rule_t *rules_end; + lxb_css_syntax_rule_t *rules; /* States */ - lxb_css_parser_state_t *states_begin; - lxb_css_parser_state_t *states_end; - lxb_css_parser_state_t *states; + lxb_css_parser_state_t *states_begin; + lxb_css_parser_state_t *states_end; + lxb_css_parser_state_t *states; /* Types */ - lxb_css_syntax_token_type_t *types_begin; - lxb_css_syntax_token_type_t *types_end; - lxb_css_syntax_token_type_t *types_pos; + lxb_css_syntax_token_type_t *types_begin; + lxb_css_syntax_token_type_t *types_end; + lxb_css_syntax_token_type_t *types_pos; - const lxb_char_t *pos; - uintptr_t offset; + lxb_css_syntax_token_t token_end; - lexbor_str_t str; - size_t str_size; + lexbor_str_t str; + size_t str_size; - lxb_css_log_t *log; + lxb_css_log_t *log; - lxb_css_parser_stage_t stage; + lxb_css_parser_stage_t stage; - bool loop; - bool fake_null; - bool my_tkz; - bool receive_endings; + lxb_css_syntax_declaration_offset_t offset; - lxb_status_t status; + bool loop; + bool fake_null; + bool my_tkz; + + lxb_status_t status; }; struct lxb_css_parser_state { @@ -185,47 +178,197 @@ struct lxb_css_parser_error { }; +/* + * Create a new CSS parser object. + * + * @return lxb_css_parser_t* if successful, otherwise NULL. + */ LXB_API lxb_css_parser_t * lxb_css_parser_create(void); +/* + * Initialize the CSS parser with a tokenizer. + * + * @param[in] parser Required. The CSS parser object. + * If NULL, the function returns + * LXB_STATUS_ERROR_OBJECT_IS_NULL. + * @param[in] tkz Optional. The tokenizer object. + * If NULL, a new tokenizer will be created and used. + * (In that case the parser manages the tokenizer lifetime.) + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ LXB_API lxb_status_t lxb_css_parser_init(lxb_css_parser_t *parser, lxb_css_syntax_tokenizer_t *tkz); +/* + * Initialize the Selectors module in the parser. + * + * Note: + * Be sure to destroy the Selectors object you created yourself using + * the lxb_css_parser_selectors_destroy() function. + * + * @param[in] parser Required. The CSS parser object. + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ +LXB_API lxb_status_t +lxb_css_parser_selectors_init(lxb_css_parser_t *parser); + +/* + * Destroy the selectors module in the parser. + * + * @param[in] parser Required. The CSS parser object. + */ +LXB_API void +lxb_css_parser_selectors_destroy(lxb_css_parser_t *parser); + +/* + * Clean the parser object. + * + * This resets internal parser state, but keeps allocated memory so the parser + * can be reused. + * + * @param[in] parser Required. The CSS parser object. + */ LXB_API void lxb_css_parser_clean(lxb_css_parser_t *parser); +/* + * Erase the parser object. + * + * This resets internal parser state and releases internal allocations owned by + * the parser so it can be re-initialized. + * + * @param[in] parser Required. The CSS parser object. + */ LXB_API void lxb_css_parser_erase(lxb_css_parser_t *parser); +/* + * Destroy the parser object. + * + * @param[in] parser Optional. The CSS parser object. + * If NULL, the function returns NULL. + * @param[in] self_destroy Optional flag. + * If true, also frees the parser object itself. + * If false, only inner resources are freed and the + * parser object remains valid. + * + * @return parser if self_destroy is false, otherwise NULL. + */ LXB_API lxb_css_parser_t * lxb_css_parser_destroy(lxb_css_parser_t *parser, bool self_destroy); -LXB_API lxb_css_parser_state_t * -lxb_css_parser_states_push(lxb_css_parser_t *parser, - lxb_css_parser_state_f state, - void *context, bool stop); - -LXB_API lxb_css_parser_state_t * -lxb_css_parser_states_next(lxb_css_parser_t *parser, - lxb_css_parser_state_f next, - lxb_css_parser_state_f back, void *ctx, bool root); - -LXB_API lxb_status_t -lxb_css_parser_types_push(lxb_css_parser_t *parser, - lxb_css_syntax_token_type_t type); - +/* + * Stop the parser main loop. + * + * This is a helper for state callbacks that want to immediately stop parsing + * without marking the current rule as failed. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_stop(lxb_css_parser_t *parser); +/* + * Fail the parser with a status and stop the main loop. + * + * This is used for hard errors (OOM, overflow, etc.). It sets parser->status + * and stops the parser loop. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] status Required. Status code describing the failure. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_fail(lxb_css_parser_t *parser, lxb_status_t status); +/* + * Mark the current token as unexpected. + * + * This is a specialized helper for the common "unexpected data" parse error. + * It sets parser->status to LXB_STATUS_ERROR_UNEXPECTED_DATA and marks the + * current rule as failed. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_unexpected(lxb_css_parser_t *parser); +/* + * Mark parsing of the current grammar/rule as successful. + * + * Why this function exists: + * - Most callbacks in the CSS parser work as a state machine: each callback + * receives the current token and returns bool to decide what to do next. + * - "Success" is not just a bool. The parser must switch to a special + * lxb_css_state_success state to properly handle trailing whitespace and + * the end-of-input token. + * - If you don't consume all tokens up to LXB_CSS_SYNTAX_TOKEN__END in the + * current rule and call this function, the parser will switch to "failed" + * mode. This is the same as calling the lxb_css_parser_failed() function. + * The exception is the LXB_CSS_SYNTAX_TOKEN_WHITESPACE token. If you are + * sure that only this token remains, the parser will simply exclude it. + * + * What it does: + * - Sets the current rule state to lxb_css_state_success. + * - Does not stop the parser loop by itself. + * + * Typical usage: + * - In css/property/state.c, after you have parsed and consumed the last token + * of a property value, you do: + * return lxb_css_parser_success(parser); + * - That transfers control to lxb_css_state_success, which consumes any + * whitespace and completes on LXB_CSS_SYNTAX_TOKEN__END. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ LXB_API bool lxb_css_parser_success(lxb_css_parser_t *parser); +/* + * Mark parsing of the current grammar/rule as failed. + * + * Why this function exists: + * - In the state machine, failure is also not "just return false". The parser + * needs to switch to a rule-specific recovery state so it can safely skip + * input until it is allowed to stop (usually until end-of-input or a known + * synchronisation point). + * + * What it does: + * - Sets the current rule state to the rule-specific "failed" handler + * (rule->cbx.cb->failed). + * - Sets rule->failed = true. + * - Does not directly change parser->status. Use lxb_css_parser_fail() or + * lxb_css_parser_unexpected() when you need a concrete status code. + * + * Typical usage: + * - In css/property/state.c, if a token doesn't match the expected grammar, + * you do: + * return lxb_css_parser_failed(parser); + * - That switches the parser into the failed handler. For properties this lets + * the parser consume/skip tokens until it reaches LXB_CSS_SYNTAX_TOKEN__END. + * (See lxb_css_state_failed(): it consumes tokens until end, then calls + * lxb_css_parser_success() to finish.) + * + * Important! + * The user sets the callback to "failed" and must decide what to do in this + * situation. If the user does not consume all tokens before + * LXB_CSS_SYNTAX_TOKEN__END, there will be an infinite loop. + * + * @param[in] parser Required. The CSS parser object. + * + * @return true (convenience return value, useful for state callbacks). + */ + LXB_API bool lxb_css_parser_failed(lxb_css_parser_t *parser); @@ -240,12 +383,64 @@ LXB_API lxb_status_t lxb_css_parser_unexpected_data_status(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token); +LXB_API void * +lxb_css_parser_memory_fail_null(lxb_css_parser_t *parser); + LXB_API bool lxb_css_parser_memory_fail(lxb_css_parser_t *parser); -lxb_status_t +LXB_API lxb_status_t lxb_css_parser_memory_fail_status(lxb_css_parser_t *parser); +/* + * Push a new state to the parser. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] state Required. State callback to execute. + * @param[in] context Optional user pointer associated with this state. + * Stored as-is; the parser doesn't own it. + * @param[in] stop If true, the pushed state is marked as a "stop point". + * This is used by the parser to stop/return control when + * this state is reached. + * + * @return lxb_css_parser_state_t* if successful, otherwise NULL. + */ +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_push(lxb_css_parser_t *parser, + lxb_css_parser_state_f state, + void *context, bool stop); + +/* + * Go to the next state in the parser. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] next Required. Next state callback. + * @param[in] back Required. State callback to return to. + * @param[in] ctx Optional user pointer for the next state. + * Stored as-is; the parser doesn't own it. + * @param[in] root If true, marks this state as a "root" state. Root states + * are used by helper functions (e.g. to rewind to root). + * + * @return lxb_css_parser_state_t* if successful, otherwise NULL. + */ +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_next(lxb_css_parser_t *parser, + lxb_css_parser_state_f next, + lxb_css_parser_state_f back, void *ctx, bool root); + +/* + * Push a token type to the parser. + * + * @param[in] parser Required. The CSS parser object. + * @param[in] type Required. Token type to push. + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ +LXB_API lxb_status_t +lxb_css_parser_types_push(lxb_css_parser_t *parser, + lxb_css_syntax_token_type_t type); + + /* * Inline functions */ @@ -350,32 +545,6 @@ lxb_css_parser_state_set(lxb_css_parser_t *parser, lxb_css_parser_state_f state) parser->rules->state = state; } -lxb_inline void -lxb_css_parser_state_block_set(lxb_css_parser_t *parser, - lxb_css_parser_state_f state) -{ - parser->block = state; -} - -lxb_inline void -lxb_css_parser_state_value_set(lxb_css_parser_t *parser, - lxb_css_parser_state_f state) -{ - lxb_css_parser_state_block_set(parser, state); -} - -lxb_inline void * -lxb_css_parser_context(lxb_css_parser_t *parser) -{ - return parser->context; -} - -lxb_inline void -lxb_css_parser_context_set(lxb_css_parser_t *parser, void *context) -{ - parser->context = context; -} - lxb_inline lxb_css_syntax_rule_t * lxb_css_parser_current_rule(lxb_css_parser_t *parser) { @@ -420,13 +589,6 @@ lxb_css_parser_states_set_back(lxb_css_parser_t *parser) return true; } -lxb_inline void -lxb_css_parser_states_change_back(lxb_css_parser_t *parser, - lxb_css_parser_state_f state) -{ - parser->rules->state_back = state; -} - lxb_inline void lxb_css_parser_states_clean(lxb_css_parser_t *parser) { @@ -465,47 +627,127 @@ lxb_css_parser_log(lxb_css_parser_t *parser) return parser->log; } -lxb_inline void -lxb_css_parser_offset_set(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token) +lxb_inline const lxb_css_syntax_token_t * +lxb_css_parser_token_end(lxb_css_parser_t *parser, size_t offset) { - if (parser->pos == NULL) { - if (token == NULL) { - parser->pos = parser->tkz->in_begin; - parser->offset = 0; - } - else { - parser->pos = lxb_css_syntax_token_base(token)->begin - + lxb_css_syntax_token_base(token)->length; - parser->offset = token->offset + lxb_css_syntax_token_base(token)->length; - } - } + parser->token_end.offset = offset; + return &parser->token_end; } -lxb_inline const lxb_css_syntax_list_rules_offset_t * -lxb_css_parser_list_rules_offset(lxb_css_parser_t *parser) +lxb_inline void +lxb_css_parser_set_context(lxb_css_parser_t *parser, void *ctx) { - return &parser->rules->u.list_rules; + parser->rules->context = ctx; } -lxb_inline const lxb_css_syntax_at_rule_offset_t * -lxb_css_parser_at_rule_offset(lxb_css_parser_t *parser) +lxb_inline void +lxb_css_syntax_set_return(lxb_css_parser_t *parser, void *value) { - return &parser->rules->u.at_rule; + parser->rules[-1].returned = value; } -lxb_inline const lxb_css_syntax_qualified_offset_t * -lxb_css_parser_qualified_rule_offset(lxb_css_parser_t *parser) +lxb_inline void * +lxb_css_syntax_returned(lxb_css_parser_t *parser) { - return &parser->rules->u.qualified; + return parser->rules->returned; } -lxb_inline const lxb_css_syntax_declarations_offset_t * -lxb_css_parser_declarations_offset(lxb_css_parser_t *parser) -{ - return &parser->rules->u.declarations; -} +/* + * No-inline functions for ABI. + */ +LXB_API lxb_status_t +lxb_css_parser_status_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_memory_t * +lxb_css_parser_memory_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_memory_set_noi(lxb_css_parser_t *parser, lxb_css_memory_t *memory); + +LXB_API lxb_css_selectors_t * +lxb_css_parser_selectors_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_selectors_set_noi(lxb_css_parser_t *parser, + lxb_css_selectors_t *selectors); + +LXB_API bool +lxb_css_parser_is_running_noi(lxb_css_parser_t *parser); + +LXB_API bool +lxb_css_parser_status_is_unexpected_data_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_failed_set_noi(lxb_css_parser_t *parser, bool is); + +LXB_API void +lxb_css_parser_failed_set_by_id_noi(lxb_css_parser_t *parser, int idx, bool is); + +LXB_API bool +lxb_css_parser_is_failed_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_set_ok_noi(lxb_css_parser_t *parser); + +LXB_API const lxb_char_t * +lxb_css_parser_buffer_noi(lxb_css_parser_t *parser, size_t *length); + +LXB_API void +lxb_css_parser_buffer_set_noi(lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length); + +LXB_API lxb_css_parser_state_f +lxb_css_parser_state_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_state_set_noi(lxb_css_parser_t *parser, + lxb_css_parser_state_f state); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_parser_current_rule_noi(lxb_css_parser_t *parser); + +LXB_API size_t +lxb_css_parser_rule_deep_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_pop_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_to_root_noi(lxb_css_parser_t *parser); + +LXB_API bool +lxb_css_parser_states_set_back_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_states_clean_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_parser_state_t * +lxb_css_parser_states_current_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_states_set_noi(lxb_css_parser_state_t *states, + lxb_css_parser_state_f state, void *context); + +LXB_API void +lxb_css_parser_states_up_noi(lxb_css_parser_t *parser); + +LXB_API void +lxb_css_parser_states_down_noi(lxb_css_parser_t *parser); + +LXB_API lxb_css_log_t * +lxb_css_parser_log_noi(lxb_css_parser_t *parser); + +LXB_API const lxb_css_syntax_token_t * +lxb_css_parser_token_end_noi(lxb_css_parser_t *parser, size_t offset); + +LXB_API void +lxb_css_parser_set_context_noi(lxb_css_parser_t *parser, void *ctx); + +LXB_API void +lxb_css_syntax_set_return_noi(lxb_css_parser_t *parser, void *value); +LXB_API void * +lxb_css_syntax_returned_noi(lxb_css_parser_t *parser); #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/property.c b/ext/lexbor/lexbor/css/property.c new file mode 100644 index 000000000000..6e460c3492f8 --- /dev/null +++ b/ext/lexbor/lexbor/css/property.c @@ -0,0 +1,3171 @@ +/* + * Copyright (C) 2021-2023 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/property.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/property/state.h" +#include "lexbor/css/property/res.h" +#include "lexbor/core/serialize.h" +#include "lexbor/core/conv.h" + + +const lxb_css_entry_data_t * +lxb_css_property_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_property_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_entry_data_t * +lxb_css_property_by_id(uintptr_t id) +{ + return &lxb_css_property_data[id]; +} + +const void * +lxb_css_property_initial_by_id(uintptr_t id) +{ + if (id >= LXB_CSS_PROPERTY__LAST_ENTRY) { + return NULL; + } + + return lxb_css_property_data[id].initial; +} + +void * +lxb_css_property_destroy(lxb_css_memory_t *memory, void *style, + lxb_css_property_type_t type, bool self_destroy) +{ + const lxb_css_entry_data_t *data; + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return style; + } + + return data->destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_serialize(const void *style, lxb_css_property_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_data_t *data; + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return data->serialize(style, cb, ctx); +} + +lxb_status_t +lxb_css_property_serialize_str(const void *style, lxb_css_property_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_data_t *data; + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return lxb_css_serialize_str_handler(style, str, mraw, data->serialize); +} + +lxb_status_t +lxb_css_property_serialize_name(const void *style, lxb_css_property_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_entry_data_t *data; + + switch (type) { + case LXB_CSS_PROPERTY__UNDEF: + return lxb_css_property__undef_serialize_name(style, cb, ctx); + + case LXB_CSS_PROPERTY__CUSTOM: + return lxb_css_property__custom_serialize_name(style, cb, ctx); + + default: + break; + } + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_property_serialize_name_str(const void *style, lxb_css_property_type_t type, + lexbor_mraw_t *mraw, lexbor_str_t *str) +{ + const lxb_css_entry_data_t *data; + + switch (type) { + case LXB_CSS_PROPERTY__UNDEF: + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_property__undef_serialize_name); + + case LXB_CSS_PROPERTY__CUSTOM: + return lxb_css_serialize_str_handler(style, str, mraw, + lxb_css_property__custom_serialize_name); + + default: + break; + } + + data = lxb_css_property_by_id(type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + if (str->data == NULL) { + lexbor_str_init(str, mraw, data->length); + if (str->data == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + + (void) lexbor_str_append(str, mraw, data->name, data->length); + + return LXB_STATUS_OK; +} + +/* _undef. */ + +void * +lxb_css_property__undef_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property__undef_t)); +} + +void * +lxb_css_property__undef_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_property__undef_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__undef_t *undef = style; + + return cb(undef->value.data, undef->value.length, ctx); +} + +lxb_status_t +lxb_css_property__undef_serialize_name(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__undef_t *undef = style; + const lxb_css_entry_data_t *data; + + if (undef->type == LXB_CSS_PROPERTY__UNDEF) { + return LXB_STATUS_OK; + } + + data = lxb_css_property_by_id(undef->type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_property__undef_serialize_value(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__undef_t *undef = style; + + if (undef->type == LXB_CSS_PROPERTY__UNDEF) { + return cb(undef->value.data, undef->value.length, ctx); + } + + return LXB_STATUS_OK; +} + +/* _custom. */ + +void * +lxb_css_property__custom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property__custom_t)); +} + +void * +lxb_css_property__custom_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + if (style == NULL) { + return NULL; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->mraw, style); + } + + return style; +} + +lxb_status_t +lxb_css_property__custom_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__custom_t *custom = style; + + if (custom->value.data == NULL) { + return LXB_STATUS_OK; + } + + return cb(custom->value.data, custom->value.length, ctx); +} + +lxb_status_t +lxb_css_property__custom_serialize_name(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__custom_t *custom = style; + + return cb(custom->name.data, custom->name.length, ctx); +} + +lxb_status_t +lxb_css_property__custom_serialize_value(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property__custom_t *custom = style; + + if (custom->value.data == NULL) { + return LXB_STATUS_OK; + } + + return cb(custom->value.data, custom->value.length, ctx); +} + +/* Display. */ + +void * +lxb_css_property_display_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_display_t)); +} + +void * +lxb_css_property_display_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_display_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_data_t *data; + const lxb_css_property_display_t *display = property; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + data = lxb_css_value_by_id(display->a); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + + if (display->b == LXB_CSS_PROPERTY__UNDEF) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + data = lxb_css_value_by_id(display->b); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + + if (display->c == LXB_CSS_PROPERTY__UNDEF) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + data = lxb_css_value_by_id(display->c); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + + return LXB_STATUS_OK; +} + +/* Order. */ + +void * +lxb_css_property_order_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_order_t)); +} + +void * +lxb_css_property_order_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_order_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_integer_type_sr(style, cb, ctx); +} + +/* Visibility. */ + +void * +lxb_css_property_visibility_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_visibility_t)); +} + +void * +lxb_css_property_visibility_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_visibility_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_visibility_t *vb = style; + + return lxb_css_value_serialize(vb->type, cb, ctx); +} + +/* Width. */ + +void * +lxb_css_property_width_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_width_t)); +} + +void * +lxb_css_property_width_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_width_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_width_t *width = property; + + switch (width->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(&width->u.length, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&width->u.percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(width->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Height. */ + +void * +lxb_css_property_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_height_t)); +} + +void * +lxb_css_property_height_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_height_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Box-sizing. */ + +void * +lxb_css_property_box_sizing_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_box_sizing_t)); +} + +void * +lxb_css_property_box_sizing_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_box_sizing_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_box_sizing_t *bsize = property; + + return lxb_css_value_serialize(bsize->type, cb, ctx); +} + +/* Min-width. */ + +void * +lxb_css_property_min_width_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_min_width_t)); +} + +void * +lxb_css_property_min_width_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_min_width_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Min-height. */ + +void * +lxb_css_property_min_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_min_height_t)); +} + +void * +lxb_css_property_min_height_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_min_height_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Max-width. */ + +void * +lxb_css_property_max_width_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_max_width_t)); +} + +void * +lxb_css_property_max_width_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_max_width_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Max-height. */ + +void * +lxb_css_property_max_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_max_height_t)); +} + +void * +lxb_css_property_max_height_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_max_height_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(property, cb, ctx); +} + +/* Margin. */ + +void * +lxb_css_property_margin_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_t)); +} + +void * +lxb_css_property_margin_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_margin_t *margin = property; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + /* Top. */ + + status = lxb_css_value_length_percentage_sr(&margin->top, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (margin->right.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + /* Right. */ + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_length_percentage_sr(&margin->right, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (margin->bottom.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + /* Bottom. */ + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_length_percentage_sr(&margin->bottom, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (margin->left.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + /* Left. */ + + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + return lxb_css_value_length_percentage_sr(&margin->left, cb, ctx); +} + +/* Margin-top. */ + +void * +lxb_css_property_margin_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_top_t)); +} + +void * +lxb_css_property_margin_top_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_top_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Margin-right. */ + +void * +lxb_css_property_margin_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_right_t)); +} + +void * +lxb_css_property_margin_right_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_right_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Margin-bottom. */ + +void * +lxb_css_property_margin_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_bottom_t)); +} + +void * +lxb_css_property_margin_bottom_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_bottom_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Margin-left. */ + +void * +lxb_css_property_margin_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_margin_left_t)); +} + +void * +lxb_css_property_margin_left_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_margin_left_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding. */ + +void * +lxb_css_property_padding_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_t)); +} + +void * +lxb_css_property_padding_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_margin_serialize(property, cb, ctx); +} + +/* Padding-top. */ + +void * +lxb_css_property_padding_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_top_t)); +} + +void * +lxb_css_property_padding_top_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_top_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding-right. */ + +void * +lxb_css_property_padding_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_right_t)); +} + +void * +lxb_css_property_padding_right_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_right_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding-bottom. */ + +void * +lxb_css_property_padding_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_bottom_t)); +} + +void * +lxb_css_property_padding_bottom_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_bottom_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Padding-left. */ + +void * +lxb_css_property_padding_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_padding_left_t)); +} + +void * +lxb_css_property_padding_left_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_padding_left_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(property, cb, ctx); +} + +/* Border. */ + +void * +lxb_css_property_border_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_t)); +} + +void * +lxb_css_property_border_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool ws_print; + lxb_status_t status; + const lxb_css_property_border_t *border = property; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + ws_print = false; + + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_length_type_sr(&border->width, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (border->style != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(border->style, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (border->color.type != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_color_serialize(&border->color, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Border-top. */ + +void * +lxb_css_property_border_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_top_t)); +} + +void * +lxb_css_property_border_top_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_top_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +/* Border-right. */ + +void * +lxb_css_property_border_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_right_t)); +} + +void * +lxb_css_property_border_right_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_right_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +/* Border-bottom. */ + +void * +lxb_css_property_border_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_bottom_t)); +} + +void * +lxb_css_property_border_bottom_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_bottom_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +/* Border-left. */ + +void * +lxb_css_property_border_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_border_left_t)); +} + +void * +lxb_css_property_border_left_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_border_left_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_border_serialize(property, cb, ctx); +} + +void * +lxb_css_property_border_top_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_top_color_t)); +} + +void * +lxb_css_property_border_top_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_top_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_border_right_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_right_color_t)); +} + +void * +lxb_css_property_border_right_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_right_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_border_bottom_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_bottom_color_t)); +} + +void * +lxb_css_property_border_bottom_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_bottom_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_border_left_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_border_left_color_t)); +} + +void * +lxb_css_property_border_left_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_border_left_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +void * +lxb_css_property_background_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_background_color_t)); +} + +void * +lxb_css_property_background_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_background_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(style, cb, ctx); +} + +/* Color. */ + +void * +lxb_css_property_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_color_t)); +} + +void * +lxb_css_property_color_destroy(lxb_css_memory_t *memory, + void *property, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, property, self_destroy); +} + +lxb_status_t +lxb_css_property_color_serialize(const void *property, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_color_serialize(property, cb, ctx); +} + +void * +lxb_css_property_opacity_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_opacity_t)); +} + +void * +lxb_css_property_opacity_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_opacity_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_percentage_sr(style, cb, ctx); +} + +void * +lxb_css_property_position_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_position_t)); +} + +void * +lxb_css_property_position_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_position_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_position_t *position = style; + + return lxb_css_value_serialize(position->type, cb, ctx); +} + +void * +lxb_css_property_top_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_top_t)); +} + +void * +lxb_css_property_top_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_top_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(style, cb, ctx); +} + +void * +lxb_css_property_right_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_right_t)); +} + +void * +lxb_css_property_right_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_right_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_bottom_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_bottom_t)); +} + +void * +lxb_css_property_bottom_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_bottom_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_left_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_left_t)); +} + +void * +lxb_css_property_left_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_left_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_block_start_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_block_start_t)); +} + +void * +lxb_css_property_inset_block_start_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_block_start_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_inline_start_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_inline_start_t)); +} + +void * +lxb_css_property_inset_inline_start_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_inline_start_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_block_end_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_block_end_t)); +} + +void * +lxb_css_property_inset_block_end_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_block_end_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +void * +lxb_css_property_inset_inline_end_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_inset_inline_end_t)); +} + +void * +lxb_css_property_inset_inline_end_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_inset_inline_end_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_top_serialize(style, cb, ctx); +} + +/* Text-transform. */ + +LXB_API void * +lxb_css_property_text_transform_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_transform_t)); +} + +LXB_API void * +lxb_css_property_text_transform_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_transform_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool ws_print; + lxb_status_t status; + const lxb_css_property_text_transform_t *tt = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + ws_print = false; + + if (tt->type_case != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(tt->type_case, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (tt->full_width != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(tt->full_width, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (tt->full_size_kana != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(tt->full_size_kana, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Text-align. */ + +LXB_API void * +lxb_css_property_text_align_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_align_t)); +} + +LXB_API void * +lxb_css_property_text_align_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_align_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_align_t *ta = style; + + return lxb_css_value_serialize(ta->type, cb, ctx); +} + +/* Text-align-all. */ + +LXB_API void * +lxb_css_property_text_align_all_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_align_all_t)); +} + +LXB_API void * +lxb_css_property_text_align_all_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_align_all_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_align_all_t *taa = style; + + return lxb_css_value_serialize(taa->type, cb, ctx); +} + +/* Text-align-last. */ + +LXB_API void * +lxb_css_property_text_align_last_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_align_last_t)); +} + +LXB_API void * +lxb_css_property_text_align_last_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_align_last_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_align_last_t *tal = style; + + return lxb_css_value_serialize(tal->type, cb, ctx); +} + +/* Text-justify. */ + +LXB_API void * +lxb_css_property_text_justify_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_justify_t)); +} + +LXB_API void * +lxb_css_property_text_justify_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_justify_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_justify_t *tj = style; + + return lxb_css_value_serialize(tj->type, cb, ctx); +} + +/* Text-indent. */ + +LXB_API void * +lxb_css_property_text_indent_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_indent_t)); +} + +LXB_API void * +lxb_css_property_text_indent_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_indent_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_text_indent_t *ti = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (ti->type == LXB_CSS_VALUE__LENGTH) { + status = lxb_css_value_length_percentage_sr(&ti->length, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + else if (ti->type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(ti->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (ti->hanging != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_serialize(ti->hanging, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (ti->each_line != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + return lxb_css_value_serialize(ti->each_line, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* White-space. */ + +LXB_API void * +lxb_css_property_white_space_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_white_space_t)); +} + +LXB_API void * +lxb_css_property_white_space_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_white_space_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_white_space_t *ws = style; + + return lxb_css_value_serialize(ws->type, cb, ctx); +} + +/* Tab-size. */ + +LXB_API void * +lxb_css_property_tab_size_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_tab_size_t)); +} + +LXB_API void * +lxb_css_property_tab_size_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_tab_size_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_length_sr(style, cb, ctx); +} + +/* Word-break. */ + +LXB_API void * +lxb_css_property_word_break_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_word_break_t)); +} + +LXB_API void * +lxb_css_property_word_break_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_word_break_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_word_break_t *wb = style; + + return lxb_css_value_serialize(wb->type, cb, ctx); +} + +/* Line-break. */ + +LXB_API void * +lxb_css_property_line_break_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_line_break_t)); +} + +LXB_API void * +lxb_css_property_line_break_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_line_break_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_line_break_t *lb = style; + + return lxb_css_value_serialize(lb->type, cb, ctx); +} + +/* Hyphens. */ + +LXB_API void * +lxb_css_property_hyphens_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_hyphens_t)); +} + +LXB_API void * +lxb_css_property_hyphens_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_hyphens_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_hyphens_t *hpns = style; + + return lxb_css_value_serialize(hpns->type, cb, ctx); +} + +/* Overflow-wrap. */ + +LXB_API void * +lxb_css_property_overflow_wrap_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_wrap_t)); +} + +LXB_API void * +lxb_css_property_overflow_wrap_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_wrap_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_wrap_t *ow = style; + + return lxb_css_value_serialize(ow->type, cb, ctx); +} + +/* Word-wrap. */ + +LXB_API void * +lxb_css_property_word_wrap_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_word_wrap_t)); +} + +LXB_API void * +lxb_css_property_word_wrap_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_word_wrap_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_word_wrap_t *ww = style; + + return lxb_css_value_serialize(ww->type, cb, ctx); +} + +/* Word-spacing. */ + +LXB_API void * +lxb_css_property_word_spacing_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_word_spacing_t)); +} + +LXB_API void * +lxb_css_property_word_spacing_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_word_spacing_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_type_sr(style, cb, ctx); +} + +/* Letter-spacing. */ + +LXB_API void * +lxb_css_property_letter_spacing_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_letter_spacing_t)); +} + +LXB_API void * +lxb_css_property_letter_spacing_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_letter_spacing_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_type_sr(style, cb, ctx); +} + +/* Hanging-punctuation. */ + +LXB_API void * +lxb_css_property_hanging_punctuation_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_hanging_punctuation_t)); +} + +LXB_API void * +lxb_css_property_hanging_punctuation_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_hanging_punctuation_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool ws_print; + lxb_status_t status; + const lxb_css_property_hanging_punctuation_t *hp = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + ws_print = false; + + if (hp->type_first != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(hp->type_first, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (hp->force_allow != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(hp->force_allow, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + ws_print = true; + } + + if (hp->last != LXB_CSS_VALUE__UNDEF) { + if (ws_print) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(hp->last, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Font-family. */ + +void * +lxb_css_property_font_family_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_family_t)); +} + +void * +lxb_css_property_font_family_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + lxb_css_property_font_family_t *ff = style; + lxb_css_property_family_name_t *name, *next; + + name = ff->first; + + while (name != NULL) { + next = name->next; + + if (!name->generic) { + (void) lexbor_str_destroy(&name->u.str, memory->mraw, false); + } + + lexbor_mraw_free(memory->mraw, name); + + name = next; + } + + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_family_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_font_family_t *ff = style; + const lxb_css_property_family_name_t *name; + + static const lexbor_str_t str_comma = lexbor_str(", "); + + name = ff->first; + + while (name != NULL) { + if (name->generic) { + status = lxb_css_value_serialize(name->u.type, cb, ctx); + } + else { + status = lxb_css_syntax_ident_or_string_serialize(name->u.str.data, + name->u.str.length, + cb, ctx); + } + + if (status != LXB_STATUS_OK) { + return status; + } + + name = name->next; + + if (name != NULL) { + lexbor_serialize_write(cb, str_comma.data, str_comma.length, + ctx, status); + } + } + + return LXB_STATUS_OK; +} + +/* Font-weight. */ + +void * +lxb_css_property_font_weight_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_weight_t)); +} + +void * +lxb_css_property_font_weight_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_weight_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_type_sr(style, cb, ctx); +} + +/* Font-stretch. */ + +void * +lxb_css_property_font_stretch_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_stretch_t)); +} + +void * +lxb_css_property_font_stretch_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_stretch_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_percentage_type_sr(style, cb, ctx); +} + +/* Font-style. */ + +void * +lxb_css_property_font_style_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_style_t)); +} + +void * +lxb_css_property_font_style_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +lxb_status_t +lxb_css_property_font_style_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_font_style_t *fs = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + status = lxb_css_value_serialize(fs->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (fs->angle.unit != (lxb_css_unit_angle_t) LXB_CSS_UNIT__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_angle_sr(&fs->angle, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + return LXB_STATUS_OK; +} + +/* Font-size. */ + +LXB_API void * +lxb_css_property_font_size_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_font_size_t)); +} + +LXB_API void * +lxb_css_property_font_size_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_font_size_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_type_sr(style, cb, ctx); +} + +/* Float-reference. */ + +LXB_API void * +lxb_css_property_float_reference_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_float_reference_t)); +} + +LXB_API void * +lxb_css_property_float_reference_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_reference_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_float_reference_t *fr = style; + + return lxb_css_value_serialize(fr->type, cb, ctx); +} + +/* Float. */ + +LXB_API void * +lxb_css_property_float_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_float_t)); +} + +LXB_API void * +lxb_css_property_float_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_float_t *flt = style; + + static const lexbor_str_t str_o = lexbor_str("("); + static const lexbor_str_t str_cm = lexbor_str(", "); + static const lexbor_str_t str_c = lexbor_str(")"); + + status = lxb_css_value_serialize(flt->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (flt->length.type != LXB_CSS_VALUE__LENGTH) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, str_o.data, str_o.length, ctx, status); + + status = lxb_css_value_length_sr(&flt->length.length, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (flt->snap_type == LXB_CSS_VALUE__UNDEF) { + return cb(str_c.data, str_c.length, ctx); + } + + lexbor_serialize_write(cb, str_cm.data, str_cm.length, ctx, status); + + status = lxb_css_value_serialize(flt->snap_type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(str_c.data, str_c.length, ctx); +} + +/* Clear. */ + +LXB_API void * +lxb_css_property_clear_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_clear_t)); +} + +LXB_API void * +lxb_css_property_clear_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_clear_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_clear_t *cls = style; + + return lxb_css_value_serialize(cls->type, cb, ctx); +} + +/* Float-defer. */ + +LXB_API void * +lxb_css_property_float_defer_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_float_defer_t)); +} + +LXB_API void * +lxb_css_property_float_defer_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_defer_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_float_defer_t *def = style; + + if (def->type == LXB_CSS_FLOAT_DEFER__INTEGER) { + return lxb_css_value_integer_sr(&def->integer, cb, ctx); + } + + return lxb_css_value_serialize(def->type, cb, ctx); +} + +/* Float-offset. */ + +LXB_API void * +lxb_css_property_float_offset_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_float_offset_t)); +} + +LXB_API void * +lxb_css_property_float_offset_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_float_offset_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(style, cb, ctx); +} + +/* Wrap-flow. */ + +LXB_API void * +lxb_css_property_wrap_flow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_wrap_flow_t)); +} + +LXB_API void * +lxb_css_property_wrap_flow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_wrap_flow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_wrap_flow_t *wf = style; + + return lxb_css_value_serialize(wf->type, cb, ctx); +} + +/* Wrap-through. */ + +LXB_API void * +lxb_css_property_wrap_through_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_wrap_through_t)); +} + +LXB_API void * +lxb_css_property_wrap_through_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_wrap_through_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_wrap_through_t *wt = style; + + return lxb_css_value_serialize(wt->type, cb, ctx); +} + +/* Flex-direction. */ + +LXB_API void * +lxb_css_property_flex_direction_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_direction_t)); +} + +LXB_API void * +lxb_css_property_flex_direction_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_direction_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_flex_direction_t *fd = style; + + return lxb_css_value_serialize(fd->type, cb, ctx); +} + +/* Flex-wrap. */ + +LXB_API void * +lxb_css_property_flex_wrap_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_wrap_t)); +} + +LXB_API void * +lxb_css_property_flex_wrap_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_wrap_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_flex_wrap_t *fw = style; + + return lxb_css_value_serialize(fw->type, cb, ctx); +} + +/* Flex-flow. */ + +LXB_API void * +lxb_css_property_flex_flow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_flow_t)); +} + +LXB_API void * +lxb_css_property_flex_flow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_flow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_flex_flow_t *ff = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (ff->type_direction != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(ff->type_direction, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (ff->wrap != LXB_CSS_VALUE__UNDEF) { + if (ff->type_direction != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(ff->wrap, cb, ctx); + } + + return LXB_STATUS_OK; +} + +/* Flex. */ + +LXB_API void * +lxb_css_property_flex_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_flex_t)); +} + +LXB_API void * +lxb_css_property_flex_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_flex_t *flex = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (flex->type != LXB_CSS_VALUE__UNDEF) { + return lxb_css_value_serialize(flex->type, cb, ctx); + } + + if (flex->grow.type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_number_sr(&flex->grow.number, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (flex->shrink.type != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + status = lxb_css_value_number_sr(&flex->shrink.number, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + } + + if (flex->basis.type == LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_OK; + } + + if (flex->grow.type != LXB_CSS_VALUE__UNDEF) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_property_flex_basis_serialize(&flex->basis, cb, ctx); +} + +/* Flex-grow. */ + +LXB_API void * +lxb_css_property_flex_grow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_grow_t)); +} + +LXB_API void * +lxb_css_property_flex_grow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_grow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_type_sr(style, cb, ctx); +} + +/* Flex-shrink. */ + +LXB_API void * +lxb_css_property_flex_shrink_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_shrink_t)); +} + +LXB_API void * +lxb_css_property_flex_shrink_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_shrink_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_type_sr(style, cb, ctx); +} + +/* Flex-basis. */ + +LXB_API void * +lxb_css_property_flex_basis_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_flex_basis_t)); +} + +LXB_API void * +lxb_css_property_flex_basis_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_flex_basis_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_width_serialize(style, cb, ctx); +} + +/* Justify-content. */ + +LXB_API void * +lxb_css_property_justify_content_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_justify_content_t)); +} + +LXB_API void * +lxb_css_property_justify_content_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_justify_content_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_justify_content_t *jc = style; + + return lxb_css_value_serialize(jc->type, cb, ctx); +} + +/* Align-items. */ + +LXB_API void * +lxb_css_property_align_items_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_align_items_t)); +} + +LXB_API void * +lxb_css_property_align_items_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_align_items_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_align_items_t *ai = style; + + return lxb_css_value_serialize(ai->type, cb, ctx); +} + +/* Align-self. */ + +LXB_API void * +lxb_css_property_align_self_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_align_self_t)); +} + +LXB_API void * +lxb_css_property_align_self_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_align_self_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_align_self_t *as = style; + + return lxb_css_value_serialize(as->type, cb, ctx); +} + +/* Align-content. */ + +LXB_API void * +lxb_css_property_align_content_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_align_content_t)); +} + +LXB_API void * +lxb_css_property_align_content_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_align_content_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_align_content_t *ac = style; + + return lxb_css_value_serialize(ac->type, cb, ctx); +} + +/* Dominant-baseline. */ + +LXB_API void * +lxb_css_property_dominant_baseline_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_dominant_baseline_t)); +} + +LXB_API void * +lxb_css_property_dominant_baseline_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_dominant_baseline_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_dominant_baseline_t *db = style; + + return lxb_css_value_serialize(db->type, cb, ctx); +} + +/* Vertical-align. */ + +LXB_API void * +lxb_css_property_vertical_align_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_vertical_align_t)); +} + +LXB_API void * +lxb_css_property_vertical_align_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_vertical_align_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool is; + lxb_status_t status; + const lxb_css_property_vertical_align_t *va = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + is = false; + + if (va->type != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(va->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + is = true; + } + + if (va->alignment.type != LXB_CSS_VALUE__UNDEF) { + if (is) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(va->alignment.type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + is = true; + } + + if (va->shift.type != LXB_CSS_VALUE__UNDEF) { + if (is) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_length_percentage_sr(&va->shift, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + return LXB_STATUS_OK; +} + +/* Baseline-source. */ + +LXB_API void * +lxb_css_property_baseline_source_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_baseline_source_t)); +} + +LXB_API void * +lxb_css_property_baseline_source_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_baseline_source_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_baseline_source_t *bs = style; + + return lxb_css_value_serialize(bs->type, cb, ctx); +} + +/* Alignment-baseline. */ + +LXB_API void * +lxb_css_property_alignment_baseline_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_alignment_baseline_t)); +} + +LXB_API void * +lxb_css_property_alignment_baseline_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_alignment_baseline_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_alignment_baseline_t *ab = style; + + return lxb_css_value_serialize(ab->type, cb, ctx); +} + +/* Baseline-shift. */ + +LXB_API void * +lxb_css_property_baseline_shift_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_baseline_shift_t)); +} + +LXB_API void * +lxb_css_property_baseline_shift_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_baseline_shift_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_length_percentage_sr(style, cb, ctx); +} + +/* Line-height. */ + +LXB_API void * +lxb_css_property_line_height_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_line_height_t)); +} + +LXB_API void * +lxb_css_property_line_height_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_line_height_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_number_length_percentage_type_sr(style, cb, ctx); +} + +/* Z-index. */ + +LXB_API void * +lxb_css_property_z_index_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_property_z_index_t)); +} + +LXB_API void * +lxb_css_property_z_index_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_z_index_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_value_integer_type_sr(style, cb, ctx); +} + +/* Direction. */ + +LXB_API void * +lxb_css_property_direction_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_direction_t)); +} + +LXB_API void * +lxb_css_property_direction_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_direction_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_direction_t *dr = style; + + return lxb_css_value_serialize(dr->type, cb, ctx); +} + +/* Unicode-bidi. */ + +LXB_API void * +lxb_css_property_unicode_bidi_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_unicode_bidi_t)); +} + +LXB_API void * +lxb_css_property_unicode_bidi_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_unicode_bidi_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_unicode_bidi_t *ub = style; + + return lxb_css_value_serialize(ub->type, cb, ctx); +} + +/* Writing-mode. */ + +LXB_API void * +lxb_css_property_writing_mode_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_writing_mode_t)); +} + +LXB_API void * +lxb_css_property_writing_mode_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_writing_mode_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_writing_mode_t *wm = style; + + return lxb_css_value_serialize(wm->type, cb, ctx); +} + +/* Text-orientation. */ + +LXB_API void * +lxb_css_property_text_orientation_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_orientation_t)); +} + +LXB_API void * +lxb_css_property_text_orientation_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_orientation_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_orientation_t *to = style; + + return lxb_css_value_serialize(to->type, cb, ctx); +} + +/* Text-combine-upright. */ + +LXB_API void * +lxb_css_property_text_combine_upright_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_combine_upright_t)); +} + +LXB_API void * +lxb_css_property_text_combine_upright_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_combine_upright_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_property_text_combine_upright_t *tcu = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + if (tcu->type == LXB_CSS_TEXT_COMBINE_UPRIGHT_DIGITS) { + status = lxb_css_value_serialize(tcu->type, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (tcu->digits.num != 0) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + + return lxb_css_value_integer_sr(&tcu->digits, cb, ctx); + } + + return LXB_STATUS_OK; + } + + return lxb_css_value_serialize(tcu->type, cb, ctx); +} + +/* Overflow-x. */ + +LXB_API void * +lxb_css_property_overflow_x_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_x_t)); +} + +LXB_API void * +lxb_css_property_overflow_x_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_x_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_x_t *ox = style; + + return lxb_css_value_serialize(ox->type, cb, ctx); +} + +/* Overflow-y. */ + +LXB_API void * +lxb_css_property_overflow_y_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_y_t)); +} + +LXB_API void * +lxb_css_property_overflow_y_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_y_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_y_t *oy = style; + + return lxb_css_value_serialize(oy->type, cb, ctx); +} + +/* Overflow-block. */ + +LXB_API void * +lxb_css_property_overflow_block_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_block_t)); +} + +LXB_API void * +lxb_css_property_overflow_block_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_block_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_block_t *ob = style; + + return lxb_css_value_serialize(ob->type, cb, ctx); +} + +/* Overflow-inline. */ + +LXB_API void * +lxb_css_property_overflow_inline_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_overflow_inline_t)); +} + +LXB_API void * +lxb_css_property_overflow_inline_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_overflow_inline_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_overflow_inline_t *oi = style; + + return lxb_css_value_serialize(oi->type, cb, ctx); +} + +/* Text-overflow. */ + +LXB_API void * +lxb_css_property_text_overflow_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_overflow_t)); +} + +LXB_API void * +lxb_css_property_text_overflow_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_overflow_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_overflow_t *to = style; + + return lxb_css_value_serialize(to->type, cb, ctx); +} + +/* Text-decoration-line. */ + +LXB_API void * +lxb_css_property_text_decoration_line_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_line_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_line_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_line_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool itis; + lxb_status_t status; + const lxb_css_property_text_decoration_line_t *tdl = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + itis = false; + + if (tdl->underline != LXB_CSS_VALUE__UNDEF) { + status = lxb_css_value_serialize(tdl->underline, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (tdl->overline != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(tdl->overline, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (tdl->line_through != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_value_serialize(tdl->line_through, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (tdl->blink != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_value_serialize(tdl->blink, cb, ctx); + } + + if (itis) { + return LXB_STATUS_OK; + } + + return lxb_css_value_serialize(tdl->type, cb, ctx); +} + +/* Text-decoration-style. */ + +LXB_API void * +lxb_css_property_text_decoration_style_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_style_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_style_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_style_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_property_text_decoration_style_t *tds = style; + + return lxb_css_value_serialize(tds->type, cb, ctx); +} + +/* Text-decoration-color. */ + +LXB_API void * +lxb_css_property_text_decoration_color_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_color_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_color_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_color_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_color_serialize(style, cb, ctx); +} + +/* Text-decoration. */ + +LXB_API void * +lxb_css_property_text_decoration_create(lxb_css_memory_t *memory) +{ + return lexbor_mraw_calloc(memory->mraw, + sizeof(lxb_css_property_text_decoration_t)); +} + +LXB_API void * +lxb_css_property_text_decoration_destroy(lxb_css_memory_t *memory, + void *style, bool self_destroy) +{ + return lxb_css_property__undef_destroy(memory, style, self_destroy); +} + +LXB_API lxb_status_t +lxb_css_property_text_decoration_serialize(const void *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + bool itis; + lxb_status_t status; + const lxb_css_property_text_decoration_t *td = style; + + static const lexbor_str_t str_ws = lexbor_str(" "); + + itis = false; + + if (td->line.type != LXB_CSS_VALUE__UNDEF + || td->line.underline != LXB_CSS_VALUE__UNDEF + || td->line.overline != LXB_CSS_VALUE__UNDEF + || td->line.line_through != LXB_CSS_VALUE__UNDEF + || td->line.blink != LXB_CSS_VALUE__UNDEF) + { + status = lxb_css_property_text_decoration_line_serialize(&td->line, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (td->style.type != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + status = lxb_css_property_text_decoration_style_serialize(&td->style, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + itis = true; + } + + if (td->color.type != LXB_CSS_VALUE__UNDEF) { + if (itis) { + lexbor_serialize_write(cb, str_ws.data, str_ws.length, ctx, status); + } + + return lxb_css_property_text_decoration_color_serialize(&td->color, + cb, ctx); + } + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/property/const.h b/ext/lexbor/lexbor/css/property/const.h index 8ee24481c6a3..4f90bc1c107b 100644 --- a/ext/lexbor/lexbor/css/property/const.h +++ b/ext/lexbor/lexbor/css/property/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/property/res.h b/ext/lexbor/lexbor/css/property/res.h index 35cce1959013..eb5b90304a09 100644 --- a/ext/lexbor/lexbor/css/property/res.h +++ b/ext/lexbor/lexbor/css/property/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/property/state.c b/ext/lexbor/lexbor/css/property/state.c new file mode 100644 index 000000000000..198ef145615d --- /dev/null +++ b/ext/lexbor/lexbor/css/property/state.c @@ -0,0 +1,5343 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/property.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/rule.h" +#include "lexbor/css/value.h" +#include "lexbor/css/unit.h" +#include "lexbor/css/property/state.h" +#include "lexbor/css/property/res.h" + + +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; +#endif + +#include "lexbor/core/conv.h" + + +#define lxb_css_property_state_check_token(parser, token) \ + if ((token) == NULL) { \ + return lxb_css_parser_memory_fail(parser); \ + } + +#define lxb_css_property_state_get_type(parser, token, type) \ + do { \ + lxb_css_syntax_parser_consume(parser); \ + \ + token = lxb_css_syntax_parser_token_wo_ws(parser); \ + lxb_css_property_state_check_token(parser, token); \ + \ + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { \ + return lxb_css_parser_success(parser); \ + } \ + \ + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, \ + lxb_css_syntax_token_ident(token)->length); \ + } \ + while (false) + +#define LXB_CSS_PROPERTY_STATE_HEX_MASK(n) \ + ((((uint32_t) 1 << (32 - (n))) - 1) << (n)) + + +static bool +lxb_css_property_state_color_rgba_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color); +static bool +lxb_css_property_state_color_hsla_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_hsla_t *hsl); + +static bool +lxb_css_property_state_length(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_length_t *length) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + length->num = lxb_css_syntax_token_dimension(token)->num.num; + length->is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + length->unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + if (lxb_css_syntax_token_number(token)->num != 0) { + return false; + } + + length->num = lxb_css_syntax_token_number(token)->num; + length->is_float = lxb_css_syntax_token_number(token)->is_float; + length->unit = LXB_CSS_UNIT__UNDEF; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_length_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_length_percentage_t *lp) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + lp->type = LXB_CSS_VALUE__LENGTH; + lp->u.length.num = lxb_css_syntax_token_dimension(token)->num.num; + lp->u.length.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + lp->u.length.unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + if (lxb_css_syntax_token_number(token)->num != 0) { + return false; + } + + lp->type = LXB_CSS_VALUE__NUMBER; + lp->u.length.num = lxb_css_syntax_token_number(token)->num; + lp->u.length.is_float = lxb_css_syntax_token_number(token)->is_float; + lp->u.length.unit = LXB_CSS_UNIT__UNDEF; + break; + + case LXB_CSS_SYNTAX_TOKEN_PERCENTAGE: + lp->type = LXB_CSS_VALUE__PERCENTAGE; + lp->u.percentage.num = lxb_css_syntax_token_percentage(token)->num; + lp->u.percentage.is_float = lxb_css_syntax_token_percentage(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_length_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_length_percentage_t *nlp) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + nlp->type = LXB_CSS_VALUE__LENGTH; + nlp->u.length.num = lxb_css_syntax_token_dimension(token)->num.num; + nlp->u.length.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + nlp->u.length.unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + nlp->type = LXB_CSS_VALUE__NUMBER; + nlp->u.number.num = lxb_css_syntax_token_number(token)->num; + nlp->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + case LXB_CSS_SYNTAX_TOKEN_PERCENTAGE: + nlp->type = LXB_CSS_VALUE__PERCENTAGE; + nlp->u.percentage.num = lxb_css_syntax_token_percentage(token)->num; + nlp->u.percentage.is_float = lxb_css_syntax_token_percentage(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_length(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_length_t *nl) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_absolute_relative_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + nl->type = LXB_CSS_VALUE__LENGTH; + nl->u.length.num = lxb_css_syntax_token_dimension(token)->num.num; + nl->u.length.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + nl->u.length.unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + nl->type = LXB_CSS_VALUE__NUMBER; + nl->u.number.num = lxb_css_syntax_token_number(token)->num; + nl->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_t *number) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_NUMBER) { + return false; + } + + number->num = lxb_css_syntax_token_number(token)->num; + number->is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_integer(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_integer_t *intg) +{ + long ln; + double num; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_NUMBER) { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + ln = lexbor_conv_double_to_long(num); + + num = num - (double) ln; + + if (num < 0.0 || num > 0.0) { + return false; + } + + intg->num = ln; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_percentage_t *perc) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + return false; + } + + perc->num = lxb_css_syntax_token_percentage(token)->num; + perc->is_float = lxb_css_syntax_token_percentage(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_percentage_none(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_percentage_t *np) +{ + double num; + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_NUMBER) { + np->type = LXB_CSS_VALUE__NUMBER; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + np->type = LXB_CSS_VALUE__PERCENTAGE; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + if (type != LXB_CSS_VALUE_NONE) { + return false; + } + + np->type = LXB_CSS_VALUE_NONE; + + lxb_css_syntax_parser_consume(parser); + + return true; + } + else { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + + np->u.number.num = num; + np->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_percentage_none(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_percentage_type_t *np) +{ + double num; + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + np->type = LXB_CSS_VALUE__PERCENTAGE; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + if (type != LXB_CSS_VALUE_NONE) { + return false; + } + + np->type = LXB_CSS_VALUE_NONE; + + lxb_css_syntax_parser_consume(parser); + + return true; + } + else { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + + np->percentage.num = num; + np->percentage.is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_number_percentage(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_number_percentage_t *np) +{ + double num; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_NUMBER) { + np->type = LXB_CSS_VALUE__NUMBER; + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_PERCENTAGE) { + np->type = LXB_CSS_VALUE__PERCENTAGE; + } + else { + return false; + } + + num = lxb_css_syntax_token_number(token)->num; + + np->u.number.num = num; + np->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_angle(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_angle_t *angle) +{ + const lxb_css_data_t *unit; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_DIMENSION) { + return false; + } + + unit = lxb_css_unit_angle_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + angle->num = lxb_css_syntax_token_dimension(token)->num.num; + angle->is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + angle->unit = (lxb_css_unit_angle_t) unit->unique; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +bool +lxb_css_property_state_width_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_width_t *width) +{ + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_AUTO: + case LXB_CSS_VALUE_MIN_CONTENT: + case LXB_CSS_VALUE_MAX_CONTENT: + width->type = type; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; + } + + return lxb_css_property_state_length_percentage(parser, token, + (lxb_css_value_length_percentage_t *)width); +} + +static bool +lxb_css_property_state_hue(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_hue_t *hue) +{ + const lxb_css_data_t *unit; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + unit = lxb_css_unit_angle_by_name(lxb_css_syntax_token_dimension(token)->str.data, + lxb_css_syntax_token_dimension(token)->str.length); + if (unit == NULL) { + return false; + } + + hue->type = LXB_CSS_VALUE__ANGLE; + hue->u.angle.num = lxb_css_syntax_token_dimension(token)->num.num; + hue->u.angle.is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + hue->u.angle.unit = (lxb_css_unit_angle_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + hue->type = LXB_CSS_VALUE__NUMBER; + hue->u.number.num = lxb_css_syntax_token_number(token)->num; + hue->u.number.is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +lxb_inline bool +lxb_css_property_state_hue_none(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_hue_t *hue) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_property_state_hue(parser, token, hue); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + if (type != LXB_CSS_VALUE_NONE) { + return false; + } + + hue->type = LXB_CSS_VALUE_NONE; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_hex(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color) +{ + size_t length; + uint32_t chex; + lxb_char_t ch; + const lxb_char_t *end, *p; + lxb_css_value_color_hex_rgba_t *rgba; + + length = token->types.hash.length; + + if (length > 8) { + return false; + } + + p = token->types.hash.data; + end = p + length; + + chex = 0; + + while (p < end) { + ch = lexbor_str_res_map_lowercase[lexbor_str_res_map_hex[*p]]; + + if (ch == 0xff) { + return false; + } + + chex = chex << 4 | ch; + + p++; + } + + rgba = &color->u.hex.rgba; + + switch (length) { + case 3: + rgba->r = chex >> 8; + rgba->g = chex >> 4 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->b = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->a = 0xff; + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_3; + break; + + case 4: + rgba->r = chex >> 12; + rgba->g = chex >> 8 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->b = chex >> 4 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + rgba->a = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(4); + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_4; + break; + + case 6: + rgba->r = chex >> 16; + rgba->g = chex >> 8 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->b = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->a = 0xff; + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_6; + break; + + case 8: + rgba->r = chex >> 24; + rgba->g = chex >> 16 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->b = chex >> 8 & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + rgba->a = chex & ~LXB_CSS_PROPERTY_STATE_HEX_MASK(8); + + color->u.hex.type = LXB_CSS_PROPERTY_COLOR_HEX_TYPE_8; + break; + + default: + return false; + } + + color->type = LXB_CSS_COLOR_HEX; + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_rgba(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_color_type_t type; + lxb_css_value_color_rgba_t *rgb; + const lxb_css_syntax_token_t *token; + + rgb = &color->u.rgb; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->r); + if (res == false) { + return false; + } + + type = rgb->r.type; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_COMMA) { + /* Deprecated format. */ + + if (type == LXB_CSS_VALUE_NONE) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + rgb->old = true; + + return lxb_css_property_state_color_rgba_old(parser, token, color); + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->g); + if (res == false) { + return false; + } + + if (type != rgb->g.type) { + if (type == LXB_CSS_VALUE_NONE) { + type = rgb->g.type; + } + else if (rgb->g.type != LXB_CSS_VALUE_NONE) { + return false; + } + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->b); + if (res == false) { + return false; + } + + if (type != rgb->b.type && type != LXB_CSS_VALUE_NONE + && rgb->b.type != LXB_CSS_VALUE_NONE) + { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else { + return false; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &rgb->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_rgba_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_rgba_t *rgb; + + rgb = &color->u.rgb; + + res = lxb_css_property_state_number_percentage(parser, token, &rgb->g); + if (res == false) { + return false; + } + + if (rgb->r.type != rgb->g.type) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage(parser, token, &rgb->b); + if (res == false) { + return false; + } + + if (rgb->r.type != rgb->b.type) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage(parser, token, &rgb->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_hsla(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_hsla_t *hsl; + const lxb_css_syntax_token_t *token; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + hsl = &color->u.hsl; + + res = lxb_css_property_state_hue_none(parser, token, &hsl->h); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_COMMA) { + /* Deprecated format. */ + + if (hsl->h.type == LXB_CSS_VALUE_NONE) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + hsl->old = true; + + return lxb_css_property_state_color_hsla_old(parser, token, hsl); + } + + res = lxb_css_property_state_percentage_none(parser, token, &hsl->s); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_percentage_none(parser, token, &hsl->l); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &hsl->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_hsla_old(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_hsla_t *hsl) +{ + bool res; + + res = lxb_css_property_state_percentage(parser, token, &hsl->s.percentage); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_percentage(parser, token, &hsl->l.percentage); + if (res == false) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + goto done; + } + else if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage(parser, token, &hsl->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + +done: + + lxb_css_syntax_parser_consume(parser); + + hsl->s.type = LXB_CSS_VALUE__PERCENTAGE; + hsl->l.type = LXB_CSS_VALUE__PERCENTAGE; + + return true; +} + +static bool +lxb_css_property_state_color_lab(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_lab_t *lab; + const lxb_css_syntax_token_t *token; + + lab = &color->u.lab; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lab->l); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lab->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lab->b); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else { + return false; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, + &lab->alpha); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +static bool +lxb_css_property_state_color_lch(lxb_css_parser_t *parser, + lxb_css_value_color_t *color) +{ + bool res; + lxb_css_value_color_lch_t *lch; + const lxb_css_syntax_token_t *token; + + lch = &color->u.lch; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lch->l); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number_percentage_none(parser, token, &lch->c); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_hue_none(parser, token, &lch->h); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { + if (lxb_css_syntax_token_delim(token)->character != '/') { + return false; + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + return true; + } + else { + return false; + } + + res = lxb_css_property_state_number_percentage_none(parser, token, &lch->a); + if (res == false) { + return false; + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +/* + * Return: + * true and status always LXB_STATUS_OK — token consumed, ok. + * false and status != LXB_STATUS_OK — token consumed, not ok. + * false and status == LXB_STATUS_OK — token not consumed, not ok. + */ +static bool +lxb_css_property_state_color_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_value_color_t *color, + lxb_status_t *status) +{ + bool res; + lxb_css_value_type_t type; + + *status = LXB_STATUS_OK; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_HASH: + color->type = LXB_CSS_VALUE_HEX; + + return lxb_css_property_state_color_hex(parser, token, color); + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + type = lxb_css_value_by_name(lxb_css_syntax_token_function(token)->data, + lxb_css_syntax_token_function(token)->length); + color->type = type; + + switch (type) { + /* */ + case LXB_CSS_VALUE_RGB: + case LXB_CSS_VALUE_RGBA: + res = lxb_css_property_state_color_rgba(parser, color); + break; + + case LXB_CSS_VALUE_HSL: + case LXB_CSS_VALUE_HSLA: + case LXB_CSS_VALUE_HWB: + res = lxb_css_property_state_color_hsla(parser, color); + break; + + case LXB_CSS_VALUE_LAB: + case LXB_CSS_VALUE_OKLAB: + res = lxb_css_property_state_color_lab(parser, color); + break; + + case LXB_CSS_VALUE_LCH: + case LXB_CSS_VALUE_OKLCH: + res = lxb_css_property_state_color_lch(parser, color); + break; + + case LXB_CSS_VALUE_COLOR: + default: + *status = LXB_STATUS_OK; + return false; + } + + if (!res) { + *status = LXB_STATUS_ERROR_UNEXPECTED_DATA; + } + + return res; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* */ + case LXB_CSS_VALUE_CURRENTCOLOR: + /* */ + case LXB_CSS_VALUE_CANVAS: + case LXB_CSS_VALUE_CANVASTEXT: + case LXB_CSS_VALUE_LINKTEXT: + case LXB_CSS_VALUE_VISITEDTEXT: + case LXB_CSS_VALUE_ACTIVETEXT: + case LXB_CSS_VALUE_BUTTONFACE: + case LXB_CSS_VALUE_BUTTONTEXT: + case LXB_CSS_VALUE_BUTTONBORDER: + case LXB_CSS_VALUE_FIELD: + case LXB_CSS_VALUE_FIELDTEXT: + case LXB_CSS_VALUE_HIGHLIGHT: + case LXB_CSS_VALUE_HIGHLIGHTTEXT: + case LXB_CSS_VALUE_SELECTEDITEM: + case LXB_CSS_VALUE_SELECTEDITEMTEXT: + case LXB_CSS_VALUE_MARK: + case LXB_CSS_VALUE_MARKTEXT: + case LXB_CSS_VALUE_GRAYTEXT: + case LXB_CSS_VALUE_ACCENTCOLOR: + case LXB_CSS_VALUE_ACCENTCOLORTEXT: + /* */ + case LXB_CSS_VALUE_TRANSPARENT: + /* */ + case LXB_CSS_VALUE_ALICEBLUE: + case LXB_CSS_VALUE_ANTIQUEWHITE: + case LXB_CSS_VALUE_AQUA: + case LXB_CSS_VALUE_AQUAMARINE: + case LXB_CSS_VALUE_AZURE: + case LXB_CSS_VALUE_BEIGE: + case LXB_CSS_VALUE_BISQUE: + case LXB_CSS_VALUE_BLACK: + case LXB_CSS_VALUE_BLANCHEDALMOND: + case LXB_CSS_VALUE_BLUE: + case LXB_CSS_VALUE_BLUEVIOLET: + case LXB_CSS_VALUE_BROWN: + case LXB_CSS_VALUE_BURLYWOOD: + case LXB_CSS_VALUE_CADETBLUE: + case LXB_CSS_VALUE_CHARTREUSE: + case LXB_CSS_VALUE_CHOCOLATE: + case LXB_CSS_VALUE_CORAL: + case LXB_CSS_VALUE_CORNFLOWERBLUE: + case LXB_CSS_VALUE_CORNSILK: + case LXB_CSS_VALUE_CRIMSON: + case LXB_CSS_VALUE_CYAN: + case LXB_CSS_VALUE_DARKBLUE: + case LXB_CSS_VALUE_DARKCYAN: + case LXB_CSS_VALUE_DARKGOLDENROD: + case LXB_CSS_VALUE_DARKGRAY: + case LXB_CSS_VALUE_DARKGREEN: + case LXB_CSS_VALUE_DARKGREY: + case LXB_CSS_VALUE_DARKKHAKI: + case LXB_CSS_VALUE_DARKMAGENTA: + case LXB_CSS_VALUE_DARKOLIVEGREEN: + case LXB_CSS_VALUE_DARKORANGE: + case LXB_CSS_VALUE_DARKORCHID: + case LXB_CSS_VALUE_DARKRED: + case LXB_CSS_VALUE_DARKSALMON: + case LXB_CSS_VALUE_DARKSEAGREEN: + case LXB_CSS_VALUE_DARKSLATEBLUE: + case LXB_CSS_VALUE_DARKSLATEGRAY: + case LXB_CSS_VALUE_DARKSLATEGREY: + case LXB_CSS_VALUE_DARKTURQUOISE: + case LXB_CSS_VALUE_DARKVIOLET: + case LXB_CSS_VALUE_DEEPPINK: + case LXB_CSS_VALUE_DEEPSKYBLUE: + case LXB_CSS_VALUE_DIMGRAY: + case LXB_CSS_VALUE_DIMGREY: + case LXB_CSS_VALUE_DODGERBLUE: + case LXB_CSS_VALUE_FIREBRICK: + case LXB_CSS_VALUE_FLORALWHITE: + case LXB_CSS_VALUE_FORESTGREEN: + case LXB_CSS_VALUE_FUCHSIA: + case LXB_CSS_VALUE_GAINSBORO: + case LXB_CSS_VALUE_GHOSTWHITE: + case LXB_CSS_VALUE_GOLD: + case LXB_CSS_VALUE_GOLDENROD: + case LXB_CSS_VALUE_GRAY: + case LXB_CSS_VALUE_GREEN: + case LXB_CSS_VALUE_GREENYELLOW: + case LXB_CSS_VALUE_GREY: + case LXB_CSS_VALUE_HONEYDEW: + case LXB_CSS_VALUE_HOTPINK: + case LXB_CSS_VALUE_INDIANRED: + case LXB_CSS_VALUE_INDIGO: + case LXB_CSS_VALUE_IVORY: + case LXB_CSS_VALUE_KHAKI: + case LXB_CSS_VALUE_LAVENDER: + case LXB_CSS_VALUE_LAVENDERBLUSH: + case LXB_CSS_VALUE_LAWNGREEN: + case LXB_CSS_VALUE_LEMONCHIFFON: + case LXB_CSS_VALUE_LIGHTBLUE: + case LXB_CSS_VALUE_LIGHTCORAL: + case LXB_CSS_VALUE_LIGHTCYAN: + case LXB_CSS_VALUE_LIGHTGOLDENRODYELLOW: + case LXB_CSS_VALUE_LIGHTGRAY: + case LXB_CSS_VALUE_LIGHTGREEN: + case LXB_CSS_VALUE_LIGHTGREY: + case LXB_CSS_VALUE_LIGHTPINK: + case LXB_CSS_VALUE_LIGHTSALMON: + case LXB_CSS_VALUE_LIGHTSEAGREEN: + case LXB_CSS_VALUE_LIGHTSKYBLUE: + case LXB_CSS_VALUE_LIGHTSLATEGRAY: + case LXB_CSS_VALUE_LIGHTSLATEGREY: + case LXB_CSS_VALUE_LIGHTSTEELBLUE: + case LXB_CSS_VALUE_LIGHTYELLOW: + case LXB_CSS_VALUE_LIME: + case LXB_CSS_VALUE_LIMEGREEN: + case LXB_CSS_VALUE_LINEN: + case LXB_CSS_VALUE_MAGENTA: + case LXB_CSS_VALUE_MAROON: + case LXB_CSS_VALUE_MEDIUMAQUAMARINE: + case LXB_CSS_VALUE_MEDIUMBLUE: + case LXB_CSS_VALUE_MEDIUMORCHID: + case LXB_CSS_VALUE_MEDIUMPURPLE: + case LXB_CSS_VALUE_MEDIUMSEAGREEN: + case LXB_CSS_VALUE_MEDIUMSLATEBLUE: + case LXB_CSS_VALUE_MEDIUMSPRINGGREEN: + case LXB_CSS_VALUE_MEDIUMTURQUOISE: + case LXB_CSS_VALUE_MEDIUMVIOLETRED: + case LXB_CSS_VALUE_MIDNIGHTBLUE: + case LXB_CSS_VALUE_MINTCREAM: + case LXB_CSS_VALUE_MISTYROSE: + case LXB_CSS_VALUE_MOCCASIN: + case LXB_CSS_VALUE_NAVAJOWHITE: + case LXB_CSS_VALUE_NAVY: + case LXB_CSS_VALUE_OLDLACE: + case LXB_CSS_VALUE_OLIVE: + case LXB_CSS_VALUE_OLIVEDRAB: + case LXB_CSS_VALUE_ORANGE: + case LXB_CSS_VALUE_ORANGERED: + case LXB_CSS_VALUE_ORCHID: + case LXB_CSS_VALUE_PALEGOLDENROD: + case LXB_CSS_VALUE_PALEGREEN: + case LXB_CSS_VALUE_PALETURQUOISE: + case LXB_CSS_VALUE_PALEVIOLETRED: + case LXB_CSS_VALUE_PAPAYAWHIP: + case LXB_CSS_VALUE_PEACHPUFF: + case LXB_CSS_VALUE_PERU: + case LXB_CSS_VALUE_PINK: + case LXB_CSS_VALUE_PLUM: + case LXB_CSS_VALUE_POWDERBLUE: + case LXB_CSS_VALUE_PURPLE: + case LXB_CSS_VALUE_REBECCAPURPLE: + case LXB_CSS_VALUE_RED: + case LXB_CSS_VALUE_ROSYBROWN: + case LXB_CSS_VALUE_ROYALBLUE: + case LXB_CSS_VALUE_SADDLEBROWN: + case LXB_CSS_VALUE_SALMON: + case LXB_CSS_VALUE_SANDYBROWN: + case LXB_CSS_VALUE_SEAGREEN: + case LXB_CSS_VALUE_SEASHELL: + case LXB_CSS_VALUE_SIENNA: + case LXB_CSS_VALUE_SILVER: + case LXB_CSS_VALUE_SKYBLUE: + case LXB_CSS_VALUE_SLATEBLUE: + case LXB_CSS_VALUE_SLATEGRAY: + case LXB_CSS_VALUE_SLATEGREY: + case LXB_CSS_VALUE_SNOW: + case LXB_CSS_VALUE_SPRINGGREEN: + case LXB_CSS_VALUE_STEELBLUE: + case LXB_CSS_VALUE_TAN: + case LXB_CSS_VALUE_TEAL: + case LXB_CSS_VALUE_THISTLE: + case LXB_CSS_VALUE_TOMATO: + case LXB_CSS_VALUE_TURQUOISE: + case LXB_CSS_VALUE_VIOLET: + case LXB_CSS_VALUE_WHEAT: + case LXB_CSS_VALUE_WHITE: + case LXB_CSS_VALUE_WHITESMOKE: + case LXB_CSS_VALUE_YELLOW: + case LXB_CSS_VALUE_YELLOWGREEN: + color->type = type; + break; + + default: + return false; + } + + break; + + default: + return false; + } + + lxb_css_syntax_parser_consume(parser); + + return true; +} + +bool +lxb_css_property_state__undef(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_failed(parser); +} + +bool +lxb_css_property_state__custom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_status_t status; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property__custom_t *custom = declar->u.custom; + + (void) lexbor_str_init(&custom->value, parser->memory->mraw, 0); + if (custom->value.data == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + status = lxb_css_syntax_token_serialize_str(token, &custom->value, + parser->memory->mraw); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_display(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_property_display_t *display; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + display = declar->u.display; + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + display->a = type; + goto inside_listitem; + + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->a = type; + goto outside_listitem; + + case LXB_CSS_DISPLAY_TABLE: + case LXB_CSS_DISPLAY_FLEX: + case LXB_CSS_DISPLAY_GRID: + case LXB_CSS_DISPLAY_RUBY: + display->a = type; + goto outside; + + /* */ + case LXB_CSS_DISPLAY_LIST_ITEM: + display->a = type; + goto listitem_only; + + /* */ + case LXB_CSS_DISPLAY_TABLE_ROW_GROUP: + case LXB_CSS_DISPLAY_TABLE_HEADER_GROUP: + case LXB_CSS_DISPLAY_TABLE_FOOTER_GROUP: + case LXB_CSS_DISPLAY_TABLE_ROW: + case LXB_CSS_DISPLAY_TABLE_CELL: + case LXB_CSS_DISPLAY_TABLE_COLUMN_GROUP: + case LXB_CSS_DISPLAY_TABLE_COLUMN: + case LXB_CSS_DISPLAY_TABLE_CAPTION: + case LXB_CSS_DISPLAY_RUBY_BASE: + case LXB_CSS_DISPLAY_RUBY_TEXT: + case LXB_CSS_DISPLAY_RUBY_BASE_CONTAINER: + case LXB_CSS_DISPLAY_RUBY_TEXT_CONTAINER: + /* */ + case LXB_CSS_DISPLAY_CONTENTS: + case LXB_CSS_DISPLAY_NONE: + /* */ + case LXB_CSS_DISPLAY_INLINE_BLOCK: + case LXB_CSS_DISPLAY_INLINE_TABLE: + case LXB_CSS_DISPLAY_INLINE_FLEX: + case LXB_CSS_DISPLAY_INLINE_GRID: + display->a = type; + goto done; + + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + display->a = type; + goto done; + + default: + return lxb_css_parser_failed(parser); + } + +inside_listitem: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->b = type; + break; + + case LXB_CSS_DISPLAY_TABLE: + case LXB_CSS_DISPLAY_FLEX: + case LXB_CSS_DISPLAY_GRID: + case LXB_CSS_DISPLAY_RUBY: + display->b = type; + goto done; + + case LXB_CSS_DISPLAY_LIST_ITEM: + display->b = type; + goto flow_only; + + default: + return lxb_css_parser_failed(parser); + } + +listitem: + + lxb_css_property_state_get_type(parser, token, type); + + if (type == LXB_CSS_DISPLAY_LIST_ITEM) { + display->c = type; + goto done; + } + + return lxb_css_parser_failed(parser); + +outside: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + if (display->b == LXB_CSS_PROPERTY__UNDEF) { + display->b = type; + } + else { + display->c = type; + } + + goto done; + + default: + return lxb_css_parser_failed(parser); + } + +outside_listitem: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + display->b = type; + goto listitem; + + case LXB_CSS_DISPLAY_LIST_ITEM: + display->b = type; + goto outside; + + default: + return lxb_css_parser_failed(parser); + } + +listitem_only: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_BLOCK: + case LXB_CSS_DISPLAY_INLINE: + case LXB_CSS_DISPLAY_RUN_IN: + display->b = type; + break; + + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->b = type; + goto outside; + + default: + return lxb_css_parser_failed(parser); + } + +flow_only: + + lxb_css_property_state_get_type(parser, token, type); + + switch (type) { + /* */ + case LXB_CSS_DISPLAY_FLOW: + case LXB_CSS_DISPLAY_FLOW_ROOT: + display->c = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + +done: + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_order(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_integer(parser, token, + &declar->u.order->integer); + if (res) { + declar->u.order->type = LXB_CSS_ORDER__INTEGER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.order->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_visibility(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_VISIBILITY_VISIBLE: + case LXB_CSS_VISIBILITY_HIDDEN: + case LXB_CSS_VISIBILITY_COLLAPSE: + declar->u.visibility->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_width(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_VALUE_AUTO: + case LXB_CSS_VALUE_MIN_CONTENT: + case LXB_CSS_VALUE_MAX_CONTENT: + declar->u.width->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + if (!lxb_css_property_state_length_percentage(parser, token, + declar->u.user)) + { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_width(parser, token, ctx); +} + +bool +lxb_css_property_state_box_sizing(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_VALUE_CONTENT_BOX: + case LXB_CSS_VALUE_BORDER_BOX: + declar->u.box_sizing->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_min_width(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_width(parser, token, ctx); +} + +bool +lxb_css_property_state_min_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_width(parser, token, ctx); +} + +bool +lxb_css_property_state_max_width(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_VALUE_NONE: + case LXB_CSS_VALUE_MIN_CONTENT: + case LXB_CSS_VALUE_MAX_CONTENT: + declar->u.width->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + if (!lxb_css_property_state_length_percentage(parser, token, + declar->u.user)) + { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_max_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_max_width(parser, token, ctx); +} + +static bool +lxb_css_property_state_mp(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_rule_declaration_t *declar, bool with_auto) +{ + unsigned int state; + lxb_css_value_type_t type; + lxb_css_property_margin_top_t *top; + + state = 1; + +next: + + switch (state) { + case 1: + top = &declar->u.margin->top; + break; + + case 2: + top = &declar->u.margin->right; + break; + + case 3: + top = &declar->u.margin->bottom; + break; + + case 4: + top = &declar->u.margin->left; + break; + + default: + return lxb_css_parser_failed(parser); + } + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + top->type = type; + break; + + case LXB_CSS_VALUE_AUTO: + if (with_auto) { + top->type = type; + break; + } + + /* Fall through. */ + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + } + else if (!lxb_css_property_state_length_percentage(parser, token, + (lxb_css_value_length_percentage_t *) top)) + { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + state++; + + goto next; +} + +static bool +lxb_css_property_state_mp_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_rule_declaration_t *declar, bool with_auto) +{ + lxb_css_value_type_t type; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.margin_top->type = type; + break; + + case LXB_CSS_VALUE_AUTO: + if (with_auto) { + declar->u.margin_top->type = type; + break; + } + + /* Fall through. */ + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + if (!lxb_css_property_state_length_percentage(parser, token, + declar->u.user)) + { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_margin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_margin_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_padding(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +bool +lxb_css_property_state_padding_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, false); +} + +static bool +lxb_css_property_state_line_width_style_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_border_t *border) +{ + lxb_status_t status; + lxb_css_value_type_t type; + const lxb_css_data_t *unit; + lxb_css_value_length_t *length; + lxb_css_syntax_token_string_t *str; + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_DIMENSION: + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + str = &lxb_css_syntax_token_dimension(token)->str; + + unit = lxb_css_unit_absolute_relative_by_name(str->data, + str->length); + if (unit == NULL) { + return false; + } + + length = &border->width.length; + + border->width.type = LXB_CSS_VALUE__LENGTH; + length->num = lxb_css_syntax_token_dimension(token)->num.num; + length->is_float = lxb_css_syntax_token_dimension(token)->num.is_float; + length->unit = (lxb_css_unit_t) unit->unique; + break; + + case LXB_CSS_SYNTAX_TOKEN_NUMBER: + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + length = &border->width.length; + + border->width.type = LXB_CSS_VALUE__NUMBER; + length->num = lxb_css_syntax_token_number(token)->num; + length->is_float = lxb_css_syntax_token_number(token)->is_float; + break; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_THIN: + case LXB_CSS_VALUE_MEDIUM: + case LXB_CSS_VALUE_THICK: + if (border->width.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + border->width.type = type; + break; + + case LXB_CSS_VALUE_NONE: + case LXB_CSS_VALUE_HIDDEN: + case LXB_CSS_VALUE_DOTTED: + case LXB_CSS_VALUE_DASHED: + case LXB_CSS_VALUE_SOLID: + case LXB_CSS_VALUE_DOUBLE: + case LXB_CSS_VALUE_GROOVE: + case LXB_CSS_VALUE_RIDGE: + case LXB_CSS_VALUE_INSET: + case LXB_CSS_VALUE_OUTSET: + if (border->style != LXB_CSS_VALUE__UNDEF) { + return false; + } + + border->style = type; + break; + + default: + goto color; + } + + break; + + default: + goto color; + } + + lxb_css_syntax_parser_consume(parser); + + return true; + +color: + + if (border->color.type != LXB_CSS_VALUE__UNDEF) { + return false; + } + + return lxb_css_property_state_color_handler(parser, token, &border->color, + &status); +} + +bool +lxb_css_property_state_border(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.border->style = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + break; + } + } + + res = lxb_css_property_state_line_width_style_color(parser, token, + declar->u.border); + if (!res) { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + res = lxb_css_property_state_line_width_style_color(parser, token, + declar->u.border); + if (!res) { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + res = lxb_css_property_state_line_width_style_color(parser, token, + declar->u.border); + if (!res) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_border_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_border(parser, token, ctx); +} + +bool +lxb_css_property_state_border_top_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_border_right_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_border_bottom_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_border_left_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_background_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_status_t status; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.color->type = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + break; + } + } + + res = lxb_css_property_state_color_handler(parser, token, + (lxb_css_value_color_t *) declar->u.color, + &status); + if (!res) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_opacity(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_opacity_t *opacity = declar->u.opacity; + + res = lxb_css_property_state_number_percentage(parser, token, + (lxb_css_value_number_percentage_t *) opacity); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + opacity->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_position(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_POSITION_STATIC: + case LXB_CSS_POSITION_RELATIVE: + case LXB_CSS_POSITION_ABSOLUTE: + case LXB_CSS_POSITION_STICKY: + case LXB_CSS_POSITION_FIXED: + declar->u.position->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_top(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_mp_top(parser, token, ctx, true); +} + +bool +lxb_css_property_state_right(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_bottom(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_left(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_block_start(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_inline_start(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_inset_inline_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_top(parser, token, ctx); +} + +bool +lxb_css_property_state_text_transform(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_transform_t *tt; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + tt = declar->u.text_transform; + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_TRANSFORM_NONE: + tt->type_case = type; + break; + + case LXB_CSS_TEXT_TRANSFORM_CAPITALIZE: + case LXB_CSS_TEXT_TRANSFORM_UPPERCASE: + case LXB_CSS_TEXT_TRANSFORM_LOWERCASE: + tt->type_case = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_WIDTH: + tt->full_width = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_SIZE_KANA: + tt->full_size_kana = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + case LXB_CSS_TEXT_TRANSFORM_CAPITALIZE: + case LXB_CSS_TEXT_TRANSFORM_UPPERCASE: + case LXB_CSS_TEXT_TRANSFORM_LOWERCASE: + if (tt->type_case != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + tt->type_case = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_WIDTH: + if (tt->full_width != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + tt->full_width = type; + goto next; + + case LXB_CSS_TEXT_TRANSFORM_FULL_SIZE_KANA: + if (tt->full_size_kana != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + tt->full_size_kana = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_text_align(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ALIGN_START: + case LXB_CSS_TEXT_ALIGN_END: + case LXB_CSS_TEXT_ALIGN_LEFT: + case LXB_CSS_TEXT_ALIGN_RIGHT: + case LXB_CSS_TEXT_ALIGN_CENTER: + case LXB_CSS_TEXT_ALIGN_JUSTIFY: + case LXB_CSS_TEXT_ALIGN_MATCH_PARENT: + case LXB_CSS_TEXT_ALIGN_JUSTIFY_ALL: + declar->u.text_align->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_align_all(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ALIGN_ALL_START: + case LXB_CSS_TEXT_ALIGN_ALL_END: + case LXB_CSS_TEXT_ALIGN_ALL_LEFT: + case LXB_CSS_TEXT_ALIGN_ALL_RIGHT: + case LXB_CSS_TEXT_ALIGN_ALL_CENTER: + case LXB_CSS_TEXT_ALIGN_ALL_JUSTIFY: + case LXB_CSS_TEXT_ALIGN_ALL_MATCH_PARENT: + declar->u.text_align_all->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_align_last(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ALIGN_LAST_AUTO: + case LXB_CSS_TEXT_ALIGN_LAST_START: + case LXB_CSS_TEXT_ALIGN_LAST_END: + case LXB_CSS_TEXT_ALIGN_LAST_LEFT: + case LXB_CSS_TEXT_ALIGN_LAST_RIGHT: + case LXB_CSS_TEXT_ALIGN_LAST_CENTER: + case LXB_CSS_TEXT_ALIGN_LAST_JUSTIFY: + case LXB_CSS_TEXT_ALIGN_LAST_MATCH_PARENT: + declar->u.text_align_last->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_justify(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_JUSTIFY_AUTO: + case LXB_CSS_TEXT_JUSTIFY_NONE: + case LXB_CSS_TEXT_JUSTIFY_INTER_WORD: + case LXB_CSS_TEXT_JUSTIFY_INTER_CHARACTER: + declar->u.text_justify->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_indent(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_indent_t *text_indent; + + text_indent = declar->u.text_indent; + + res = lxb_css_property_state_length_percentage(parser, token, + &text_indent->length); + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + text_indent->type = LXB_CSS_VALUE__LENGTH; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (!res) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + if (res) { + return lxb_css_parser_failed(parser); + } + + text_indent->type = type; + break; + + /* Local. */ + case LXB_CSS_TEXT_INDENT_HANGING: + text_indent->hanging = type; + goto next; + + case LXB_CSS_TEXT_INDENT_EACH_LINE: + text_indent->each_line = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_length_percentage(parser, token, + &text_indent->length); + if (res) { + if (text_indent->type != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + text_indent->type = LXB_CSS_VALUE__LENGTH; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (text_indent->type == LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + case LXB_CSS_TEXT_INDENT_HANGING: + if (text_indent->hanging != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + text_indent->hanging = type; + goto next; + + case LXB_CSS_TEXT_INDENT_EACH_LINE: + if (text_indent->each_line != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + text_indent->each_line = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_white_space(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WHITE_SPACE_NORMAL: + case LXB_CSS_WHITE_SPACE_PRE: + case LXB_CSS_WHITE_SPACE_NOWRAP: + case LXB_CSS_WHITE_SPACE_PRE_WRAP: + case LXB_CSS_WHITE_SPACE_BREAK_SPACES: + case LXB_CSS_WHITE_SPACE_PRE_LINE: + declar->u.white_space->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_tab_size(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_number_length(parser, token, + (lxb_css_value_number_length_t *) declar->u.tab_size); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + declar->u.tab_size->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_word_break(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WORD_BREAK_NORMAL: + case LXB_CSS_WORD_BREAK_KEEP_ALL: + case LXB_CSS_WORD_BREAK_BREAK_ALL: + case LXB_CSS_WORD_BREAK_BREAK_WORD: + declar->u.word_break->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_line_break(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_LINE_BREAK_AUTO: + case LXB_CSS_LINE_BREAK_LOOSE: + case LXB_CSS_LINE_BREAK_NORMAL: + case LXB_CSS_LINE_BREAK_STRICT: + case LXB_CSS_LINE_BREAK_ANYWHERE: + declar->u.line_break->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_hyphens(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_HYPHENS_NONE: + case LXB_CSS_HYPHENS_MANUAL: + case LXB_CSS_HYPHENS_AUTO: + declar->u.hyphens->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_overflow_wrap(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_OVERFLOW_WRAP_NORMAL: + case LXB_CSS_OVERFLOW_WRAP_BREAK_WORD: + case LXB_CSS_OVERFLOW_WRAP_ANYWHERE: + declar->u.overflow_wrap->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_word_wrap(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_wrap(parser, token, ctx); +} + +bool +lxb_css_property_state_word_spacing(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_length(parser, token, + &declar->u.word_spacing->length); + if (res) { + declar->u.word_spacing->type = LXB_CSS_VALUE__LENGTH; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WORD_SPACING_NORMAL: + declar->u.word_spacing->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_letter_spacing(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_word_spacing(parser, token, ctx); +} + +bool +lxb_css_property_state_hanging_punctuation(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_hanging_punctuation_t *hp; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + hp = declar->u.hanging_punctuation; + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_HANGING_PUNCTUATION_NONE: + hp->type_first = type; + break; + + case LXB_CSS_HANGING_PUNCTUATION_FIRST: + hp->type_first = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_FORCE_END: + case LXB_CSS_HANGING_PUNCTUATION_ALLOW_END: + hp->force_allow = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_LAST: + hp->last = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + switch (type) { + case LXB_CSS_HANGING_PUNCTUATION_FIRST: + if (hp->type_first != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + hp->type_first = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_FORCE_END: + case LXB_CSS_HANGING_PUNCTUATION_ALLOW_END: + if (hp->force_allow != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + hp->force_allow = type; + goto next; + + case LXB_CSS_HANGING_PUNCTUATION_LAST: + if (hp->last != LXB_CSS_VALUE__UNDEF) { + return lxb_css_parser_failed(parser); + } + + hp->last = type; + goto next; + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_font_family(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + size_t length; + const lxb_char_t *data; + lexbor_str_t *str; + lexbor_mraw_t *mraw; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_family_t *ff; + lxb_css_property_family_name_t *name; + + mraw = parser->memory->mraw; + ff = declar->u.font_family; + + while (token != NULL) { + name = lexbor_mraw_alloc(mraw, sizeof(lxb_css_property_family_name_t)); + if (name == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + if (token->type == LXB_CSS_SYNTAX_TOKEN_IDENT) { + data = lxb_css_syntax_token_ident(token)->data; + length = lxb_css_syntax_token_ident(token)->length; + + type = lxb_css_value_by_name(data, length); + if (type != LXB_CSS_VALUE__UNDEF) { + name->generic = true; + name->u.type = type; + + goto next; + } + } + else if (token->type == LXB_CSS_SYNTAX_TOKEN_STRING) { + data = lxb_css_syntax_token_string(token)->data; + length = lxb_css_syntax_token_string(token)->length; + } + else { + return lxb_css_parser_failed(parser); + } + + name->generic = false; + + str = &name->u.str; + + (void) lexbor_str_init(str, mraw, length); + if (name->u.str.data == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + memcpy(str->data, data, length); + + str->data[length] = '\0'; + str->length = length; + + next: + + if (ff->first == NULL) { + ff->first = name; + } + else { + ff->last->next = name; + } + + name->next = NULL; + name->prev = ff->last; + ff->last = name; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + } + + lxb_css_property_state_check_token(parser, token); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_weight(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx)\ +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_weight_t *fw = declar->u.font_weight; + + res = lxb_css_property_state_number(parser, token, &fw->number); + + if (res) { + if (fw->number.num < 1 || fw->number.num > 1000) { + return lxb_css_parser_failed(parser); + } + + fw->type = LXB_CSS_FONT_WEIGHT__NUMBER; + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_WEIGHT_NORMAL: + case LXB_CSS_FONT_WEIGHT_BOLD: + case LXB_CSS_FONT_WEIGHT_BOLDER: + case LXB_CSS_FONT_WEIGHT_LIGHTER: + fw->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_stretch(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_stretch_t *fs = declar->u.font_stretch; + + res = lxb_css_property_state_percentage(parser, token, &fs->percentage); + + if (res) { + if (fs->percentage.num < 0) { + return lxb_css_parser_failed(parser); + } + + fs->type = LXB_CSS_FONT_STRETCH__PERCENTAGE; + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_STRETCH_NORMAL: + case LXB_CSS_FONT_STRETCH_ULTRA_CONDENSED: + case LXB_CSS_FONT_STRETCH_EXTRA_CONDENSED: + case LXB_CSS_FONT_STRETCH_CONDENSED: + case LXB_CSS_FONT_STRETCH_SEMI_CONDENSED: + case LXB_CSS_FONT_STRETCH_SEMI_EXPANDED: + case LXB_CSS_FONT_STRETCH_EXPANDED: + case LXB_CSS_FONT_STRETCH_EXTRA_EXPANDED: + case LXB_CSS_FONT_STRETCH_ULTRA_EXPANDED: + fs->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_style(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_style_t *fs = declar->u.font_style; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_STYLE_NORMAL: + case LXB_CSS_FONT_STYLE_ITALIC: + fs->type = type; + break; + + case LXB_CSS_FONT_STYLE_OBLIQUE: + fs->type = type; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_angle(parser, token, &fs->angle); + + if (res) { + if (fs->angle.num < -90 || fs->angle.num > 90) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); + } + else { + fs->angle.unit = (lxb_css_unit_angle_t) LXB_CSS_UNIT__UNDEF; + } + + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_font_size(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_font_size_t *fs = declar->u.font_size; + + res = lxb_css_property_state_length_percentage(parser, token, &fs->length); + + if (res) { + if (fs->length.u.length.num < 0) { + return lxb_css_parser_failed(parser); + } + + fs->type = LXB_CSS_FONT_SIZE__LENGTH; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FONT_SIZE_XX_SMALL: + case LXB_CSS_FONT_SIZE_X_SMALL: + case LXB_CSS_FONT_SIZE_SMALL: + case LXB_CSS_FONT_SIZE_MEDIUM: + case LXB_CSS_FONT_SIZE_LARGE: + case LXB_CSS_FONT_SIZE_X_LARGE: + case LXB_CSS_FONT_SIZE_XX_LARGE: + case LXB_CSS_FONT_SIZE_XXX_LARGE: + case LXB_CSS_FONT_SIZE_MATH: + case LXB_CSS_FONT_SIZE_LARGER: + case LXB_CSS_FONT_SIZE_SMALLER: + fs->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float_reference(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLOAT_REFERENCE_INLINE: + case LXB_CSS_FLOAT_REFERENCE_COLUMN: + case LXB_CSS_FLOAT_REFERENCE_REGION: + case LXB_CSS_FLOAT_REFERENCE_PAGE: + declar->u.float_reference->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_float_t *fp = declar->u.floatp; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (token->type == LXB_CSS_SYNTAX_TOKEN_FUNCTION) { + goto snap; + } + + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLOAT_BLOCK_START: + case LXB_CSS_FLOAT_BLOCK_END: + case LXB_CSS_FLOAT_INLINE_START: + case LXB_CSS_FLOAT_INLINE_END: + case LXB_CSS_FLOAT_SNAP_BLOCK: + case LXB_CSS_FLOAT_SNAP_INLINE: + case LXB_CSS_FLOAT_LEFT: + case LXB_CSS_FLOAT_RIGHT: + case LXB_CSS_FLOAT_TOP: + case LXB_CSS_FLOAT_BOTTOM: + case LXB_CSS_FLOAT_NONE: + fp->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +snap: + + type = lxb_css_value_by_name(lxb_css_syntax_token_function(token)->data, + lxb_css_syntax_token_function(token)->length); + + if (type != LXB_CSS_FLOAT_SNAP_BLOCK + && type != LXB_CSS_FLOAT_SNAP_INLINE) + { + return lxb_css_parser_failed(parser); + } + + fp->type = type; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_length(parser, token, &fp->length.length); + if (!res) { + return lxb_css_parser_failed(parser); + } + + fp->length.type = LXB_CSS_VALUE__LENGTH; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_COMMA) { + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + fp->snap_type = LXB_CSS_VALUE__UNDEF; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_FLOAT_START: + case LXB_CSS_FLOAT_END: + if (fp->type != LXB_CSS_FLOAT_SNAP_BLOCK) { + return lxb_css_parser_failed(parser); + } + + fp->snap_type = type; + break; + + case LXB_CSS_FLOAT_LEFT: + case LXB_CSS_FLOAT_RIGHT: + if (fp->type != LXB_CSS_FLOAT_SNAP_INLINE) { + return lxb_css_parser_failed(parser); + } + + fp->snap_type = type; + break; + + case LXB_CSS_FLOAT_NEAR: + fp->snap_type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) { + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); +} + +bool +lxb_css_property_state_clear(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_CLEAR_INLINE_START: + case LXB_CSS_CLEAR_INLINE_END: + case LXB_CSS_CLEAR_BLOCK_START: + case LXB_CSS_CLEAR_BLOCK_END: + case LXB_CSS_CLEAR_LEFT: + case LXB_CSS_CLEAR_RIGHT: + case LXB_CSS_CLEAR_TOP: + case LXB_CSS_CLEAR_BOTTOM: + case LXB_CSS_CLEAR_NONE: + declar->u.clear->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float_defer(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_float_defer_t *fd = declar->u.float_defer; + + res = lxb_css_property_state_integer(parser, token, &fd->integer); + if (res) { + fd->type = LXB_CSS_FLOAT_DEFER__INTEGER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLOAT_DEFER_LAST: + case LXB_CSS_FLOAT_DEFER_NONE: + fd->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_float_offset(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_float_offset_t *fo = declar->u.float_offset; + + res = lxb_css_property_state_length_percentage(parser, token, + (lxb_css_value_length_percentage_t *) fo); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + fo->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_wrap_flow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WRAP_FLOW_AUTO: + case LXB_CSS_WRAP_FLOW_BOTH: + case LXB_CSS_WRAP_FLOW_START: + case LXB_CSS_WRAP_FLOW_END: + case LXB_CSS_WRAP_FLOW_MINIMUM: + case LXB_CSS_WRAP_FLOW_MAXIMUM: + case LXB_CSS_WRAP_FLOW_CLEAR: + declar->u.wrap_flow->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_wrap_through(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WRAP_THROUGH_WRAP: + case LXB_CSS_WRAP_THROUGH_NONE: + declar->u.wrap_through->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_direction(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_DIRECTION_ROW: + case LXB_CSS_FLEX_DIRECTION_ROW_REVERSE: + case LXB_CSS_FLEX_DIRECTION_COLUMN: + case LXB_CSS_FLEX_DIRECTION_COLUMN_REVERSE: + declar->u.flex_direction->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_wrap(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_WRAP_NOWRAP: + case LXB_CSS_FLEX_WRAP_WRAP: + case LXB_CSS_FLEX_WRAP_WRAP_REVERSE: + declar->u.flex_wrap->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_flow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_flow_t *ff = declar->u.flex_flow; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_DIRECTION_ROW: + case LXB_CSS_FLEX_DIRECTION_ROW_REVERSE: + case LXB_CSS_FLEX_DIRECTION_COLUMN: + case LXB_CSS_FLEX_DIRECTION_COLUMN_REVERSE: + ff->type_direction = type; + goto direction; + + case LXB_CSS_FLEX_WRAP_NOWRAP: + case LXB_CSS_FLEX_WRAP_WRAP: + case LXB_CSS_FLEX_WRAP_WRAP_REVERSE: + ff->wrap = type; + goto wrap; + + default: + return lxb_css_parser_failed(parser); + } + +direction: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_FLEX_WRAP_NOWRAP: + case LXB_CSS_FLEX_WRAP_WRAP: + case LXB_CSS_FLEX_WRAP_WRAP_REVERSE: + ff->wrap = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + goto done; + +wrap: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_success(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_FLEX_DIRECTION_ROW: + case LXB_CSS_FLEX_DIRECTION_ROW_REVERSE: + case LXB_CSS_FLEX_DIRECTION_COLUMN: + case LXB_CSS_FLEX_DIRECTION_COLUMN_REVERSE: + ff->type_direction = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + +done: + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +lxb_inline bool +lxb_css_property_state_flex_grow_shrink(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_flex_t *flex) +{ + bool res; + + res = lxb_css_property_state_number(parser, token, &flex->grow.number); + if (!res) { + return false; + } + + flex->grow.type = LXB_CSS_FLEX_GROW__NUMBER; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_number(parser, token, &flex->shrink.number); + if (res) { + flex->shrink.type = LXB_CSS_FLEX_SHRINK__NUMBER; + } + + return true; +} + +lxb_inline bool +lxb_css_property_state_flex_grow_basis(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_flex_t *flex) +{ + bool res; + lxb_css_value_type_t type; + + res = lxb_css_property_state_width_handler(parser, token, + (lxb_css_property_flex_basis_t *) &flex->basis); + if (res) { + return true; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + + if (type == LXB_CSS_FLEX_BASIS_CONTENT) { + flex->basis.type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + } + + return false; +} + +bool +lxb_css_property_state_flex(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_t *flex = declar->u.flex; + + res = lxb_css_property_state_flex_grow_shrink(parser, token, flex); + + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_flex_grow_basis(parser, token, flex); + + if (!res && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + flex->basis.type = LXB_CSS_VALUE__NUMBER; + flex->basis.u.length.num = flex->grow.number.num; + flex->basis.u.length.unit = LXB_CSS_UNIT__UNDEF; + flex->basis.u.length.is_float = flex->grow.number.is_float; + + flex->grow.type = LXB_CSS_VALUE__UNDEF; + + if (flex->shrink.type != LXB_CSS_VALUE__UNDEF) { + flex->grow = flex->shrink; + flex->shrink.type = LXB_CSS_VALUE__UNDEF; + + goto try_shrink_last; + } + + res = lxb_css_property_state_flex_grow_shrink(parser, token, flex); + if (!res) { + return lxb_css_parser_failed(parser); + } + } + + return lxb_css_parser_success(parser); + } + else { + res = lxb_css_property_state_flex_grow_basis(parser, token, flex); + + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + (void) lxb_css_property_state_flex_grow_shrink(parser, token, flex); + + return lxb_css_parser_success(parser); + } + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_FLEX_NONE: + flex->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); + +try_shrink_last: + + res = lxb_css_property_state_number(parser, token, &flex->shrink.number); + if (res) { + flex->shrink.type = LXB_CSS_FLEX_SHRINK__NUMBER; + } + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_grow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_grow_t *fg = declar->u.flex_grow; + + res = lxb_css_property_state_number(parser, token, &fg->number); + if (res) { + if (fg->number.num < 0) { + return lxb_css_parser_failed(parser); + } + + fg->type = LXB_CSS_FLEX_GROW__NUMBER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + fg->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_shrink(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_grow_t *fs = declar->u.flex_shrink; + + res = lxb_css_property_state_number(parser, token, &fs->number); + if (res) { + if (fs->number.num < 0) { + return lxb_css_parser_failed(parser); + } + + fs->type = LXB_CSS_FLEX_SHRINK__NUMBER; + + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + fs->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_flex_basis(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_flex_basis_t *fb = declar->u.flex_basis; + + res = lxb_css_property_state_width_handler(parser, token, + (lxb_css_property_width_t *) fb); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + case LXB_CSS_FLEX_BASIS_CONTENT: + fb->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_justify_content(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_JUSTIFY_CONTENT_FLEX_START: + case LXB_CSS_JUSTIFY_CONTENT_FLEX_END: + case LXB_CSS_JUSTIFY_CONTENT_CENTER: + case LXB_CSS_JUSTIFY_CONTENT_SPACE_BETWEEN: + case LXB_CSS_JUSTIFY_CONTENT_SPACE_AROUND: + declar->u.justify_content->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_align_items(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGN_ITEMS_FLEX_START: + case LXB_CSS_ALIGN_ITEMS_FLEX_END: + case LXB_CSS_ALIGN_ITEMS_CENTER: + case LXB_CSS_ALIGN_ITEMS_BASELINE: + case LXB_CSS_ALIGN_ITEMS_STRETCH: + declar->u.align_items->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_align_self(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGN_SELF_AUTO: + case LXB_CSS_ALIGN_SELF_FLEX_START: + case LXB_CSS_ALIGN_SELF_FLEX_END: + case LXB_CSS_ALIGN_SELF_CENTER: + case LXB_CSS_ALIGN_SELF_BASELINE: + case LXB_CSS_ALIGN_SELF_STRETCH: + declar->u.align_self->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_align_content(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGN_CONTENT_FLEX_START: + case LXB_CSS_ALIGN_CONTENT_FLEX_END: + case LXB_CSS_ALIGN_CONTENT_CENTER: + case LXB_CSS_ALIGN_CONTENT_SPACE_BETWEEN: + case LXB_CSS_ALIGN_CONTENT_SPACE_AROUND: + case LXB_CSS_ALIGN_CONTENT_STRETCH: + declar->u.align_content->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_dominant_baseline(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_DOMINANT_BASELINE_AUTO: + case LXB_CSS_DOMINANT_BASELINE_TEXT_BOTTOM: + case LXB_CSS_DOMINANT_BASELINE_ALPHABETIC: + case LXB_CSS_DOMINANT_BASELINE_IDEOGRAPHIC: + case LXB_CSS_DOMINANT_BASELINE_MIDDLE: + case LXB_CSS_DOMINANT_BASELINE_CENTRAL: + case LXB_CSS_DOMINANT_BASELINE_MATHEMATICAL: + case LXB_CSS_DOMINANT_BASELINE_HANGING: + case LXB_CSS_DOMINANT_BASELINE_TEXT_TOP: + declar->u.dominant_baseline->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_alignment_baseline_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_alignment_baseline_t *ab) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_ALIGNMENT_BASELINE_BASELINE: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_BOTTOM: + case LXB_CSS_ALIGNMENT_BASELINE_ALPHABETIC: + case LXB_CSS_ALIGNMENT_BASELINE_IDEOGRAPHIC: + case LXB_CSS_ALIGNMENT_BASELINE_MIDDLE: + case LXB_CSS_ALIGNMENT_BASELINE_CENTRAL: + case LXB_CSS_ALIGNMENT_BASELINE_MATHEMATICAL: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_TOP: + ab->type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + + default: + return false; + } +} + +bool +lxb_css_property_state_baseline_shift_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_baseline_shift_t *bs) +{ + bool res; + lxb_css_value_type_t type; + + res = lxb_css_property_state_length_percentage(parser, token, bs); + + if (res) { + return true; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_BASELINE_SHIFT_SUB: + case LXB_CSS_BASELINE_SHIFT_SUPER: + case LXB_CSS_BASELINE_SHIFT_TOP: + case LXB_CSS_BASELINE_SHIFT_CENTER: + case LXB_CSS_BASELINE_SHIFT_BOTTOM: + bs->type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + + default: + return false; + } +} + +bool +lxb_css_property_state_vertical_align(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + uint8_t maps; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_vertical_align_t *va = declar->u.vertical_align; + + maps = 0; + +again: + + res = lxb_css_property_state_alignment_baseline_h(parser, token, + &va->alignment); + if (res) { + if (maps & 1 << 1) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 1; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_baseline_shift_h(parser, token, + &va->shift); + if (res) { + if (maps & 1 << 2) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 2; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + } + else { + res = lxb_css_property_state_baseline_shift_h(parser, token, + &va->shift); + if (res) { + if (maps & 1 << 2) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 2; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_alignment_baseline_h(parser, token, + &va->alignment); + if (res) { + if (maps & 1 << 1) { + return lxb_css_parser_failed(parser); + } + + maps |= 1 << 1; + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + } + } + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + if (maps != 0) { + return lxb_css_parser_success(parser); + } + + return lxb_css_parser_failed(parser); + } + + if (maps & 1 << 3) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_VERTICAL_ALIGN_FIRST: + case LXB_CSS_VERTICAL_ALIGN_LAST: + va->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + maps = 1 << 3; + + goto again; +} + +bool +lxb_css_property_state_baseline_source(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_BASELINE_SOURCE_AUTO: + case LXB_CSS_BASELINE_SOURCE_FIRST: + case LXB_CSS_BASELINE_SOURCE_LAST: + declar->u.baseline_source->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_alignment_baseline(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_ALIGNMENT_BASELINE_BASELINE: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_BOTTOM: + case LXB_CSS_ALIGNMENT_BASELINE_ALPHABETIC: + case LXB_CSS_ALIGNMENT_BASELINE_IDEOGRAPHIC: + case LXB_CSS_ALIGNMENT_BASELINE_MIDDLE: + case LXB_CSS_ALIGNMENT_BASELINE_CENTRAL: + case LXB_CSS_ALIGNMENT_BASELINE_MATHEMATICAL: + case LXB_CSS_ALIGNMENT_BASELINE_TEXT_TOP: + declar->u.alignment_baseline->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_baseline_shift(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_length_percentage(parser, token, + declar->u.baseline_shift); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_BASELINE_SHIFT_SUB: + case LXB_CSS_BASELINE_SHIFT_SUPER: + case LXB_CSS_BASELINE_SHIFT_TOP: + case LXB_CSS_BASELINE_SHIFT_CENTER: + case LXB_CSS_BASELINE_SHIFT_BOTTOM: + declar->u.baseline_shift->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_line_height(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_number_length_percentage(parser, token, + declar->u.line_height); + if (res) { + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_LINE_HEIGHT_NORMAL: + declar->u.line_height->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_z_index(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + res = lxb_css_property_state_integer(parser, token, + &declar->u.z_index->integer); + if (res) { + declar->u.z_index->type = LXB_CSS_VALUE__INTEGER; + return lxb_css_parser_success(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_Z_INDEX_AUTO: + declar->u.line_height->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_direction(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_DIRECTION_LTR: + case LXB_CSS_DIRECTION_RTL: + declar->u.direction->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_unicode_bidi(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_UNICODE_BIDI_NORMAL: + case LXB_CSS_UNICODE_BIDI_EMBED: + case LXB_CSS_UNICODE_BIDI_ISOLATE: + case LXB_CSS_UNICODE_BIDI_BIDI_OVERRIDE: + case LXB_CSS_UNICODE_BIDI_ISOLATE_OVERRIDE: + case LXB_CSS_UNICODE_BIDI_PLAINTEXT: + declar->u.unicode_bidi->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_writing_mode(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_WRITING_MODE_HORIZONTAL_TB: + case LXB_CSS_WRITING_MODE_VERTICAL_RL: + case LXB_CSS_WRITING_MODE_VERTICAL_LR: + case LXB_CSS_WRITING_MODE_SIDEWAYS_RL: + case LXB_CSS_WRITING_MODE_SIDEWAYS_LR: + declar->u.writing_mode->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_orientation(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_ORIENTATION_MIXED: + case LXB_CSS_TEXT_ORIENTATION_UPRIGHT: + case LXB_CSS_TEXT_ORIENTATION_SIDEWAYS: + declar->u.text_orientation->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_combine_upright(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_combine_upright_t *tcu = declar->u.text_combine_upright; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_COMBINE_UPRIGHT_NONE: + case LXB_CSS_TEXT_COMBINE_UPRIGHT_ALL: + tcu->type = type; + break; + + case LXB_CSS_TEXT_COMBINE_UPRIGHT_DIGITS: + tcu->type = type; + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + res = lxb_css_property_state_integer(parser, token, + &tcu->digits); + if (res) { + if (tcu->digits.num != 2 && tcu->digits.num != 4) { + return lxb_css_parser_failed(parser); + } + } + + return lxb_css_parser_success(parser); + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_overflow_x(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_OVERFLOW_X_VISIBLE: + case LXB_CSS_OVERFLOW_X_HIDDEN: + case LXB_CSS_OVERFLOW_X_CLIP: + case LXB_CSS_OVERFLOW_X_SCROLL: + case LXB_CSS_OVERFLOW_X_AUTO: + declar->u.overflow_x->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_overflow_y(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_x(parser, token, ctx); +} + +bool +lxb_css_property_state_overflow_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_x(parser, token, ctx); +} + +bool +lxb_css_property_state_overflow_inline(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_overflow_x(parser, token, ctx); +} + +bool +lxb_css_property_state_text_overflow(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_OVERFLOW_CLIP: + case LXB_CSS_TEXT_OVERFLOW_ELLIPSIS: + declar->u.text_overflow->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +lxb_status_t +lxb_css_property_state_text_decoration_line_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_text_decoration_line_t *tdl) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return LXB_STATUS_NEXT; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_TEXT_DECORATION_LINE_NONE: + tdl->type = type; + + lxb_css_syntax_parser_consume(parser); + return LXB_STATUS_OK; + + default: + goto first; + } + +next: + + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token_wo_ws(parser); + if (token == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return LXB_STATUS_OK; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + +first: + + switch (type) { + case LXB_CSS_TEXT_DECORATION_LINE_UNDERLINE: + if (tdl->underline != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->underline = type; + goto next; + + case LXB_CSS_TEXT_DECORATION_LINE_OVERLINE: + if (tdl->overline != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->overline = type; + goto next; + + case LXB_CSS_TEXT_DECORATION_LINE_LINE_THROUGH: + if (tdl->line_through != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->line_through = type; + goto next; + + case LXB_CSS_TEXT_DECORATION_LINE_BLINK: + if (tdl->blink != LXB_CSS_VALUE__UNDEF) { + return LXB_STATUS_STOP; + } + + tdl->blink = type; + goto next; + + default: + if (tdl->underline != LXB_CSS_VALUE__UNDEF + || tdl->overline != LXB_CSS_VALUE__UNDEF + || tdl->line_through != LXB_CSS_VALUE__UNDEF + || tdl->blink != LXB_CSS_VALUE__UNDEF) + { + return LXB_STATUS_OK; + } + + return LXB_STATUS_NEXT; + } +} + +bool +lxb_css_property_state_text_decoration_line(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_status_t status; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_decoration_line_t *tdl = declar->u.text_decoration_line; + + status = lxb_css_property_state_text_decoration_line_h(parser, token, tdl); + + if (status == LXB_STATUS_OK) { + return lxb_css_parser_success(parser); + } + else if (status == LXB_STATUS_STOP) { + return lxb_css_parser_failed(parser); + } + else if (status != LXB_STATUS_NEXT) { + return lxb_css_parser_memory_fail(parser); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + tdl->type = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + return lxb_css_parser_failed(parser); + } +} + +bool +lxb_css_property_state_text_decoration_style_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_property_text_decoration_style_t *tds) +{ + lxb_css_value_type_t type; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return false; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + case LXB_CSS_TEXT_DECORATION_STYLE_SOLID: + case LXB_CSS_TEXT_DECORATION_STYLE_DOUBLE: + case LXB_CSS_TEXT_DECORATION_STYLE_DOTTED: + case LXB_CSS_TEXT_DECORATION_STYLE_DASHED: + case LXB_CSS_TEXT_DECORATION_STYLE_WAVY: + tds->type = type; + + lxb_css_syntax_parser_consume(parser); + return true; + + default: + return false; + } +} + +bool +lxb_css_property_state_text_decoration_style(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + return lxb_css_parser_failed(parser); + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + /* Local. */ + case LXB_CSS_TEXT_DECORATION_STYLE_SOLID: + case LXB_CSS_TEXT_DECORATION_STYLE_DOUBLE: + case LXB_CSS_TEXT_DECORATION_STYLE_DOTTED: + case LXB_CSS_TEXT_DECORATION_STYLE_DASHED: + case LXB_CSS_TEXT_DECORATION_STYLE_WAVY: + declar->u.text_decoration_style->type = type; + break; + + default: + return lxb_css_parser_failed(parser); + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_parser_success(parser); +} + +bool +lxb_css_property_state_text_decoration_color(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_property_state_color(parser, token, ctx); +} + +bool +lxb_css_property_state_text_decoration(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + bool res, line, style, color; + lxb_status_t status; + lxb_css_value_type_t type; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_property_text_decoration_t *td = declar->u.text_decoration; + + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) { + goto lsc; + } + + type = lxb_css_value_by_name(lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length); + switch (type) { + /* Global. */ + case LXB_CSS_VALUE_INITIAL: + case LXB_CSS_VALUE_INHERIT: + case LXB_CSS_VALUE_UNSET: + case LXB_CSS_VALUE_REVERT: + td->line.type = type; + + lxb_css_syntax_parser_consume(parser); + return lxb_css_parser_success(parser); + + default: + break; + } + +lsc: + + line = false; + style = false; + color = false; + + for (size_t i = 0; i < 3; i++) { + if (!line) { + status = lxb_css_property_state_text_decoration_line_h(parser, token, + &td->line); + if (status == LXB_STATUS_OK) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + line = true; + } + else if (status == LXB_STATUS_STOP) { + return lxb_css_parser_failed(parser); + } + else if (status != LXB_STATUS_NEXT) { + return lxb_css_parser_memory_fail(parser); + } + } + + if (!style) { + res = lxb_css_property_state_text_decoration_style_h(parser, token, + &td->style); + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + style = true; + } + } + + if (!color) { + res = lxb_css_property_state_color_handler(parser, token, + (lxb_css_value_color_t *) &td->color, + &status); + if (res) { + token = lxb_css_syntax_parser_token_wo_ws(parser); + lxb_css_property_state_check_token(parser, token); + + color = true; + } + else { + if (status != LXB_STATUS_OK) { + return lxb_css_parser_failed(parser); + } + } + } + } + + if (!line && !style && !color) { + return lxb_css_parser_failed(parser); + } + + return lxb_css_parser_success(parser); +} diff --git a/ext/lexbor/lexbor/css/property/types.h b/ext/lexbor/lexbor/css/property/types.h new file mode 100644 index 000000000000..3a23f125a698 --- /dev/null +++ b/ext/lexbor/lexbor/css/property/types.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2025 Alexander Borisov + * + * Author: Alexander Borisov + */ + +/* + * Caution! + * This file generated by the script "utils/lexbor/css/names.py"! + * Do not change this file! + */ + + +#ifndef LXB_CSS_PROPERTY_TYPES_H +#define LXB_CSS_PROPERTY_TYPES_H + + + + + +#endif /* LXB_CSS_PROPERTY_TYPES_H */ diff --git a/ext/lexbor/lexbor/css/rule.c b/ext/lexbor/lexbor/css/rule.c new file mode 100644 index 000000000000..5ee938730ea8 --- /dev/null +++ b/ext/lexbor/lexbor/css/rule.c @@ -0,0 +1,598 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/rule.h" +#include "lexbor/css/parser.h" +#include "lexbor/core/serialize.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/selectors/selectors.h" + + +void * +lxb_css_rule_destroy(lxb_css_rule_t *rule, bool self_destroy) +{ + switch (rule->type) { + case LXB_CSS_RULE_LIST: + return lxb_css_rule_list_destroy(lxb_css_rule_list(rule), + self_destroy); + case LXB_CSS_RULE_AT_RULE: + return lxb_css_rule_at_destroy(lxb_css_rule_at(rule), + self_destroy); + case LXB_CSS_RULE_STYLE: + return lxb_css_rule_style_destroy(lxb_css_rule_style(rule), + self_destroy); + case LXB_CSS_RULE_BAD_STYLE: + return lxb_css_rule_bad_style_destroy(lxb_css_rule_bad_style(rule), + self_destroy); + case LXB_CSS_RULE_DECLARATION: + return lxb_css_rule_declaration_destroy(lxb_css_rule_declaration(rule), + self_destroy); + case LXB_CSS_RULE_DECLARATION_LIST: + return lxb_css_rule_declaration_list_destroy(lxb_css_rule_declaration_list(rule), + self_destroy); + case LXB_CSS_RULE_STYLESHEET: + case LXB_CSS_RULE_UNDEF: + return NULL; + } + + return NULL; +} + +lxb_status_t +lxb_css_rule_serialize(const lxb_css_rule_t *rule, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (rule->type) { + case LXB_CSS_RULE_LIST: + return lxb_css_rule_list_serialize(lxb_css_rule_list(rule), cb, ctx); + + case LXB_CSS_RULE_AT_RULE: + return lxb_css_rule_at_serialize(lxb_css_rule_at(rule), cb, ctx); + + case LXB_CSS_RULE_STYLE: + return lxb_css_rule_style_serialize(lxb_css_rule_style(rule), + cb, ctx); + case LXB_CSS_RULE_BAD_STYLE: + return lxb_css_rule_bad_style_serialize(lxb_css_rule_bad_style(rule), + cb, ctx); + case LXB_CSS_RULE_DECLARATION: + return lxb_css_rule_declaration_serialize(lxb_css_rule_declaration(rule), + cb, ctx); + case LXB_CSS_RULE_DECLARATION_LIST: + return lxb_css_rule_declaration_list_serialize(lxb_css_rule_declaration_list(rule), + cb, ctx); + case LXB_CSS_RULE_STYLESHEET: + case LXB_CSS_RULE_UNDEF: + break; + } + + return LXB_STATUS_ERROR_WRONG_ARGS; +} + +lxb_status_t +lxb_css_rule_serialize_chain(const lxb_css_rule_t *rule, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + + static const lxb_char_t ws_str[] = "\n"; + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + + while (rule != NULL) { + lexbor_serialize_write(cb, ws_str, (sizeof(ws_str) - 1), ctx, status); + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_list_t * +lxb_css_rule_list_destroy(lxb_css_rule_list_t *list, bool self_destroy) +{ + lxb_css_rule_t *rule, *next, *parent; + lxb_css_rule_t *child_rule; + lxb_css_memory_t *memory; + lxb_css_rule_at_t *at; + lxb_css_rule_style_t *style; + lxb_css_rule_bad_style_t *bad; + lxb_css_rule_list_t *sub_list; + lxb_css_rule_declaration_list_t *declr_list; + + if (list == NULL) { + return NULL; + } + + rule = list->first; + memory = lxb_css_rule(list)->memory; + + while (rule != NULL) { + child_rule = NULL; + + switch (rule->type) { + case LXB_CSS_RULE_LIST: + sub_list = lxb_css_rule_list(rule); + + if (sub_list->first != NULL) { + child_rule = sub_list->first; + + sub_list->first = NULL; + sub_list->last = NULL; + } + break; + + case LXB_CSS_RULE_STYLE: + style = lxb_css_rule_style(rule); + + if (style->child != NULL) { + child_rule = lxb_css_rule(style->child); + style->child = NULL; + } + break; + + case LXB_CSS_RULE_BAD_STYLE: + bad = lxb_css_rule_bad_style(rule); + + if (bad->child != NULL) { + child_rule = lxb_css_rule(bad->child); + bad->child = NULL; + } + break; + + case LXB_CSS_RULE_AT_RULE: + at = lxb_css_rule_at(rule); + + if (at->type == LXB_CSS_AT_RULE_MEDIA) { + if (at->u.media != NULL && at->u.media->block != NULL) { + child_rule = lxb_css_rule(at->u.media->block); + at->u.media->block = NULL; + } + } + else if (at->type == LXB_CSS_AT_RULE__UNDEF) { + if (at->u.undef != NULL && at->u.undef->block != NULL) { + child_rule = lxb_css_rule(at->u.undef->block); + at->u.undef->block = NULL; + } + } + else if (at->type == LXB_CSS_AT_RULE__CUSTOM) { + if (at->u.custom != NULL && at->u.custom->block != NULL) { + child_rule = lxb_css_rule(at->u.custom->block); + at->u.custom->block = NULL; + } + } + else if (at->type == LXB_CSS_AT_RULE_FONT_FACE) { + if (at->u.font_face != NULL && at->u.font_face->block != NULL) { + child_rule = lxb_css_rule(at->u.font_face->block); + at->u.font_face->block = NULL; + } + } + break; + + case LXB_CSS_RULE_DECLARATION_LIST: + declr_list = lxb_css_rule_declaration_list(rule); + + if (declr_list->first != NULL) { + child_rule = declr_list->first; + + declr_list->first = NULL; + declr_list->last = NULL; + } + break; + + default: + break; + } + + if (child_rule != NULL) { + rule = child_rule; + continue; + } + + next = rule->next; + parent = rule->parent; + + (void) lxb_css_rule_destroy(rule, true); + + if (next != NULL) { + rule = next; + } + else { + if (parent == lxb_css_rule(list)) { + break; + } + + rule = parent; + } + } + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, list); + } + + list->first = NULL; + list->last = NULL; + + return list; +} + +lxb_status_t +lxb_css_rule_list_serialize(const lxb_css_rule_list_t *list, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + lxb_css_rule_t *rule; + + static const lxb_char_t nl_str[] = "\n"; + + rule = list->first; + + if (rule == NULL) { + return LXB_STATUS_OK; + } + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + + while (rule != NULL) { + lexbor_serialize_write(cb, nl_str, (sizeof(nl_str) - 1), ctx, status); + + status = lxb_css_rule_serialize(rule, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + rule = rule->next; + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_at_t * +lxb_css_rule_at_destroy(lxb_css_rule_at_t *at, bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(at)->memory; + + switch (at->type) { + case LXB_CSS_AT_RULE__UNDEF: + (void) lxb_css_at_rule__undef_destroy(memory, at->u.undef, true); + break; + + case LXB_CSS_AT_RULE_MEDIA: + (void) lxb_css_at_rule_media_destroy(memory, at->u.media, true); + break; + + case LXB_CSS_AT_RULE_NAMESPACE: + (void) lxb_css_at_rule_namespace_destroy(memory, at->u.ns, true); + break; + + case LXB_CSS_AT_RULE__LAST_ENTRY: + break; + } + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, at); + } + + return at; +} + +lxb_status_t +lxb_css_rule_at_serialize(const lxb_css_rule_at_t *at, lexbor_serialize_cb_f cb, + void *ctx) +{ + lxb_status_t status; + const lxb_css_at_rule__undef_t *undef; + const lxb_css_at_rule__custom_t *custom; + const lxb_css_entry_at_rule_data_t *data, *undata; + + static const lxb_char_t at_str[] = "@"; + + data = lxb_css_at_rule_by_id(at->type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, at_str, (sizeof(at_str) - 1), ctx, status); + + if (at->type == LXB_CSS_AT_RULE__UNDEF) { + undef = at->u.undef; + + undata = lxb_css_at_rule_by_id(undef->type); + if (undata == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, undata->name, undata->length, ctx, status); + } + else if (at->type == LXB_CSS_AT_RULE__CUSTOM) { + custom = at->u.custom; + + lexbor_serialize_write(cb, custom->name.data, + custom->name.length, ctx, status); + } + else { + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + } + + return data->serialize(at->u.user, cb, ctx); +} + +lxb_status_t +lxb_css_rule_at_serialize_name(const lxb_css_rule_at_t *at, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_at_rule_serialize_name(at->u.user, at->type, cb, ctx); +} + +lxb_css_rule_style_t * +lxb_css_rule_style_destroy(lxb_css_rule_style_t *style, bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(style)->memory; + + lxb_css_selector_list_destroy(style->selector); + (void) lxb_css_rule_declaration_list_destroy(style->declarations, true); + (void) lxb_css_rule_list_destroy(style->child, true); + + style->selector = NULL; + style->declarations = NULL; + style->child = NULL; + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, style); + } + + return style; +} + +lxb_status_t +lxb_css_rule_style_serialize(const lxb_css_rule_style_t *style, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + + static const lxb_char_t lc_str[] = " {"; + static const lxb_char_t rc_str[] = "}"; + static const lxb_char_t cm_str[] = "; "; + + status = lxb_css_selector_serialize_list_chain(style->selector, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (style->declarations != NULL) { + lexbor_serialize_write(cb, lc_str, (sizeof(lc_str) - 1), ctx, status); + + status = lxb_css_rule_declaration_list_serialize(style->declarations, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (style->child == NULL) { + lexbor_serialize_write(cb, rc_str, (sizeof(rc_str) - 1), + ctx, status); + } + } + + if (style->child != NULL && style->child->first != NULL) { + lexbor_serialize_write(cb, cm_str, (sizeof(cm_str) - 1), ctx, status); + + status = lxb_css_rule_list_serialize(style->child, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + } + + if (style->declarations != NULL) { + lexbor_serialize_write(cb, rc_str, (sizeof(rc_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_bad_style_t * +lxb_css_rule_bad_style_destroy(lxb_css_rule_bad_style_t *bad, bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(bad)->memory; + + (void) lexbor_str_destroy(&bad->selectors, memory->mraw, false); + bad->declarations = lxb_css_rule_declaration_list_destroy(bad->declarations, + true); + bad->child = lxb_css_rule_list_destroy(bad->child, true); + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, bad); + } + + return bad; +} + +lxb_status_t +lxb_css_rule_bad_style_serialize(const lxb_css_rule_bad_style_t *bad, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + + static const lxb_char_t lc_str[] = "{"; + static const lxb_char_t rc_str[] = "}"; + + if (bad->selectors.data != NULL) { + lexbor_serialize_write(cb, bad->selectors.data, bad->selectors.length, + ctx, status); + } + + if (bad->declarations != NULL) { + lexbor_serialize_write(cb, lc_str, (sizeof(lc_str) - 1), ctx, status); + + status = lxb_css_rule_declaration_list_serialize(bad->declarations, + cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(rc_str, (sizeof(rc_str) - 1), ctx); + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_declaration_list_t * +lxb_css_rule_declaration_list_destroy(lxb_css_rule_declaration_list_t *list, + bool self_destroy) +{ + lxb_css_rule_t *declr, *next; + + if (list == NULL) { + return NULL; + } + + declr = list->first; + + while (declr != NULL) { + next = declr->next; + (void) lxb_css_rule_destroy(declr, true); + declr = next; + } + + if (self_destroy) { + return lexbor_mraw_free(lxb_css_rule(list)->memory->tree, list); + } + + list->first = NULL; + list->last = NULL; + + return list; +} + +lxb_status_t +lxb_css_rule_declaration_list_serialize(const lxb_css_rule_declaration_list_t *list, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_rule_t *declr; + + static const lxb_char_t sm_str[] = "; "; + + declr = list->first; + + if (declr == NULL) { + return LXB_STATUS_OK; + } + + status = lxb_css_rule_serialize(declr, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + declr = declr->next; + + while (declr != NULL) { + lexbor_serialize_write(cb, sm_str, (sizeof(sm_str) - 1), ctx, status); + + status = lxb_css_rule_serialize(declr, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + declr = declr->next; + } + + return LXB_STATUS_OK; +} + +lxb_css_rule_declaration_t * +lxb_css_rule_declaration_destroy(lxb_css_rule_declaration_t *declr, + bool self_destroy) +{ + lxb_css_memory_t *memory = lxb_css_rule(declr)->memory; + + if (declr->u.user != NULL) { + declr->u.user = lxb_css_property_destroy(memory, declr->u.user, + declr->type, true); + } + + if (self_destroy) { + return lexbor_mraw_free(memory->tree, declr); + } + + return declr; +} + +lxb_status_t +lxb_css_rule_declaration_serialize(const lxb_css_rule_declaration_t *declaration, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + const lxb_css_entry_data_t *data, *undata; + const lxb_css_property__undef_t *undef; + const lxb_css_property__custom_t *custom; + + static const lxb_char_t cl_str[] = ": "; + static const lxb_char_t imp_str[] = " !important"; + + data = lxb_css_property_by_id(declaration->type); + if (data == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + if (declaration->type == LXB_CSS_PROPERTY__UNDEF) { + undef = declaration->u.undef; + + if (undef->type > LXB_CSS_PROPERTY__CUSTOM) { + undata = lxb_css_property_by_id(undef->type); + if (undata == NULL) { + return LXB_STATUS_ERROR_NOT_EXISTS; + } + + lexbor_serialize_write(cb, undata->name, undata->length, ctx, status); + lexbor_serialize_write(cb, cl_str, (sizeof(cl_str) - 1), ctx, status); + } + } + else if (declaration->type == LXB_CSS_PROPERTY__CUSTOM) { + custom = declaration->u.custom; + + lexbor_serialize_write(cb, custom->name.data, custom->name.length, + ctx, status); + lexbor_serialize_write(cb, cl_str, (sizeof(cl_str) - 1), ctx, status); + } + else { + lexbor_serialize_write(cb, data->name, data->length, ctx, status); + lexbor_serialize_write(cb, cl_str, (sizeof(cl_str) - 1), ctx, status); + } + + status = data->serialize(declaration->u.user, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (declaration->important && declaration->type != LXB_CSS_PROPERTY__UNDEF) { + lexbor_serialize_write(cb, imp_str, (sizeof(imp_str) - 1), ctx, status); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_rule_declaration_serialize_name(const lxb_css_rule_declaration_t *declr, + lexbor_serialize_cb_f cb, void *ctx) +{ + return lxb_css_property_serialize_name(declr->u.user, declr->type, cb, ctx); +} diff --git a/ext/lexbor/lexbor/css/rule.h b/ext/lexbor/lexbor/css/rule.h index bd191f9b6519..d192a0161ccd 100644 --- a/ext/lexbor/lexbor/css/rule.h +++ b/ext/lexbor/lexbor/css/rule.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -46,9 +46,6 @@ struct lxb_css_rule { lxb_css_rule_t *prev; lxb_css_rule_t *parent; - const lxb_char_t *begin; - const lxb_char_t *end; - lxb_css_memory_t *memory; size_t ref_count; }; @@ -68,10 +65,15 @@ struct lxb_css_rule_at { union { lxb_css_at_rule__undef_t *undef; lxb_css_at_rule__custom_t *custom; + lxb_css_at_rule_font_face_t *font_face; lxb_css_at_rule_media_t *media; lxb_css_at_rule_namespace_t *ns; void *user; } u; + + size_t name_begin; + size_t prelude_begin; + size_t prelude_end; }; struct lxb_css_rule_style { @@ -79,6 +81,10 @@ struct lxb_css_rule_style { lxb_css_selector_list_t *selector; lxb_css_rule_declaration_list_t *declarations; + lxb_css_rule_list_t *child; + + size_t prelude_begin; + size_t prelude_end; }; struct lxb_css_rule_bad_style { @@ -86,6 +92,10 @@ struct lxb_css_rule_bad_style { lexbor_str_t selectors; lxb_css_rule_declaration_list_t *declarations; + lxb_css_rule_list_t *child; + + size_t prelude_begin; + size_t prelude_end; }; struct lxb_css_rule_declaration_list { @@ -97,6 +107,16 @@ struct lxb_css_rule_declaration_list { size_t count; }; +typedef struct { + size_t name_begin; + size_t name_end; + size_t value_begin; + size_t value_end; + size_t important_begin; + size_t important_end; +} +lxb_css_rule_declaration_offset_t; + struct lxb_css_rule_declaration { lxb_css_rule_t rule; uintptr_t type; @@ -204,7 +224,9 @@ struct lxb_css_rule_declaration { void *user; } u; - bool important; + lxb_css_rule_declaration_offset_t offset; + + bool important; }; diff --git a/ext/lexbor/lexbor/css/selectors/base.h b/ext/lexbor/lexbor/css/selectors/base.h index 279c1e5f68c3..3151f74b04ee 100644 --- a/ext/lexbor/lexbor/css/selectors/base.h +++ b/ext/lexbor/lexbor/css/selectors/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Alexander Borisov + * Copyright (C) 2021-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_CSS_SELECTORS_VERSION_MAJOR 1 -#define LXB_CSS_SELECTORS_VERSION_MINOR 1 +#define LXB_CSS_SELECTORS_VERSION_MINOR 3 #define LXB_CSS_SELECTORS_VERSION_PATCH 0 #define LXB_CSS_SELECTORS_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_const.h b/ext/lexbor/lexbor/css/selectors/pseudo_const.h index 2b19f1888147..9fa5bb2177c7 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_const.h +++ b/ext/lexbor/lexbor/css/selectors/pseudo_const.h @@ -69,15 +69,16 @@ typedef enum { LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS = 0x0003, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS = 0x0004, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG = 0x0005, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT = 0x0006, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x0007, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL = 0x0008, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x0009, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL = 0x000a, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x000b, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x000c, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE = 0x000d, - LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION__LAST_ENTRY = 0x000e + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS = 0x0006, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT = 0x0007, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD = 0x0008, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL = 0x0009, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD = 0x000a, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL = 0x000b, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE = 0x000c, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE = 0x000d, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE = 0x000e, + LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION__LAST_ENTRY = 0x000f } lxb_css_selector_pseudo_class_function_id_t; diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_res.h b/ext/lexbor/lexbor/css/selectors/pseudo_res.h index 5ae6e048064c..108257406069 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_res.h +++ b/ext/lexbor/lexbor/css/selectors/pseudo_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -68,60 +68,64 @@ static const lxb_css_selectors_pseudo_data_func_t lxb_css_selectors_pseudo_data_ { {(lxb_char_t *) "#undef", 6, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION__UNDEF, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function__undef, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function__undef, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "current", 7, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_current, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_current, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "dir", 3, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_dir, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_dir, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "has", 3, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS, false, LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT, - {.state = lxb_css_selectors_state_pseudo_class_function_has, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_forgiving_relative}, true, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_has, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_forgiving_relative}, true, true}, {(lxb_char_t *) "is", 2, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_is, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_forgiving}, true, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_is, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_forgiving}, true, true}, {(lxb_char_t *) "lang", 4, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_lang, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_lang, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, + {(lxb_char_t *) "lexbor-contains", 15, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS, + false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, + {.value = lxb_css_selectors_state_pseudo_class_function_lexbor_contains, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "not", 3, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_not, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_not, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "nth-child", 9, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_child, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_child, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "nth-col", 7, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_col, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_col, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "nth-last-child", 14, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_last_child, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, true}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_last_child, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, true}, {(lxb_char_t *) "nth-last-col", 12, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_last_col, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_last_col, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "nth-last-of-type", 16, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_last_of_type, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_last_of_type, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "nth-of-type", 11, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_nth_of_type, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false}, + {.value = lxb_css_selectors_state_pseudo_class_function_nth_of_type, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false}, {(lxb_char_t *) "where", 5, LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_class_function_where, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_forgiving}, true, true} + {.value = lxb_css_selectors_state_pseudo_class_function_where, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_forgiving}, true, true} }; static const lxb_css_selectors_pseudo_data_t lxb_css_selectors_pseudo_data_pseudo_element[LXB_CSS_SELECTOR_PSEUDO_ELEMENT__LAST_ENTRY] = @@ -145,8 +149,8 @@ static const lxb_css_selectors_pseudo_data_func_t lxb_css_selectors_pseudo_data_ { {(lxb_char_t *) "#undef", 6, LXB_CSS_SELECTOR_PSEUDO_ELEMENT_FUNCTION__UNDEF, false, LXB_CSS_SELECTOR_COMBINATOR_CLOSE, - {.state = lxb_css_selectors_state_pseudo_element_function__undef, .block = NULL, - .failed = lxb_css_state_failed, .end = lxb_css_selectors_state_function_end}, false, false} + {.value = lxb_css_selectors_state_pseudo_element_function__undef, + .cb.failed = lxb_css_state_failed, .cb.end = lxb_css_selectors_state_function_end}, false, false} }; static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_shs[79] = @@ -232,46 +236,50 @@ static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_shs[79] = {NULL, NULL, 0, 0} }; -static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_function_shs[39] = +static const lexbor_shs_entry_t lxb_css_selectors_pseudo_class_function_shs[43] = { - {NULL, NULL, 38, 0}, + {NULL, NULL, 42, 0}, + {"nth-last-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE], 16, 0}, {NULL, NULL, 0, 0}, - {"current", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT], 7, 0}, {NULL, NULL, 0, 0}, - {"dir", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, + {"not", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT], 3, 0}, {NULL, NULL, 0, 0}, - {"is", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS], 2, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD], 9, 0}, {NULL, NULL, 0, 0}, + {"has", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-last-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD], 14, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, + {"nth-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL], 7, 0}, {NULL, NULL, 0, 0}, - {"where", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE], 5, 0}, + {"lexbor-contains", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS], 15, 0}, + {NULL, NULL, 0, 0}, + {"is", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS], 2, 0}, + {"nth-last-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL], 12, 0}, + {"current", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT], 7, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL], 7, 0}, {"lang", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG], 4, 0}, - {"has", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"nth-last-col", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL], 12, 0}, - {"nth-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE], 11, 0}, + {"nth-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD], 9, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"not", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT], 3, 0}, - {"nth-last-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE], 16, 0}, + {NULL, NULL, 0, 0}, + {"nth-last-child", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD], 14, 0}, + {"nth-of-type", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE], 11, 0}, + {NULL, NULL, 0, 0}, + {"dir", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR], 3, 0}, + {"where", (void *) &lxb_css_selectors_pseudo_data_pseudo_class_function[LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE], 5, 0}, {NULL, NULL, 0, 0} }; diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_state.c b/ext/lexbor/lexbor/css/selectors/pseudo_state.c index f40b089d1300..263ca52f35e4 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_state.c +++ b/ext/lexbor/lexbor/css/selectors/pseudo_state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -27,10 +27,9 @@ lxb_css_selectors_state_pseudo_of_back(lxb_css_parser_t *parser, static const lxb_css_syntax_cb_components_t lxb_css_selectors_comp = { - .state = lxb_css_selectors_state_complex_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_state_pseudo_of_end + .prelude = lxb_css_selectors_state_complex_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_state_pseudo_of_end }; @@ -182,6 +181,117 @@ lxb_css_selectors_state_pseudo_element_function__undef(lxb_css_parser_t *parser, return true; } +bool +lxb_css_selectors_state_pseudo_class_function_lexbor_contains(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_selectors_t *selectors; + lxb_css_selector_t *selector; + lxb_css_selector_contains_t *contains; + lexbor_str_t *str; + const lxb_char_t *data; + size_t length; + + selectors = parser->selectors; + selector = selectors->list_last->last; + +again: + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_STRING: + data = token->types.string.data; + length = token->types.string.length; + break; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + data = token->types.ident.data; + length = token->types.ident.length; + break; + + case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + goto again; + + default: + lxb_css_parser_unexpected_data(parser, token); + return lxb_css_parser_failed(parser); + } + + contains = lexbor_mraw_alloc(parser->memory->mraw, + sizeof(lxb_css_selector_contains_t)); + if (contains == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + contains->insensitive = false; + str = &contains->str; + + str->data = lexbor_mraw_alloc(parser->memory->mraw, + sizeof(lexbor_str_t)); + if (str->data == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + memcpy(str->data, data, length + 1); + + str->length = length; + str->data[length] = '\0'; + + selector->u.pseudo.data = contains; + +again_end: + + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN__END: + break; + + case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + goto again_end; + + case LXB_CSS_SYNTAX_TOKEN_IDENT: + data = token->types.ident.data; + length = token->types.ident.length; + + if (length == 1 && (*data == 'i' || *data == 'I')) { + contains->insensitive = true; + + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + + if (token->type == LXB_CSS_SYNTAX_TOKEN_WHITESPACE) { + lxb_css_syntax_parser_consume(parser); + lxb_css_parser_token_status_m(parser, token); + } + + if (token->type != LXB_CSS_SYNTAX_TOKEN__END) { + goto failed; + } + + break; + } + /* Fall through. */ + + default: + goto failed; + } + + parser->selectors->list = NULL; + + return lxb_css_parser_success(parser); + +failed: + + lexbor_mraw_free(parser->memory->mraw, contains->str.data); + lexbor_mraw_free(parser->memory->mraw, contains); + + lxb_css_parser_unexpected_data(parser, token); + return lxb_css_parser_failed(parser); +} + static bool lxb_css_selectors_state_pseudo_anb(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, @@ -268,10 +378,14 @@ lxb_css_selectors_state_pseudo_of_begin(lxb_css_parser_t *parser, return lxb_css_parser_memory_fail(parser); } - rule = lxb_css_syntax_parser_components_push(parser, token, + rule = lxb_css_syntax_parser_components_push(parser, + &lxb_css_selectors_comp, lxb_css_selectors_state_pseudo_of_back, - &lxb_css_selectors_comp, list, - LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); + list, LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); +// rule = lxb_css_syntax_parser_components_push(parser, token, +// lxb_css_selectors_state_pseudo_of_back, +// &lxb_css_selectors_comp, list, +// LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); if (rule == NULL) { lexbor_mraw_free(parser->memory->mraw, list->last->u.pseudo.data); diff --git a/ext/lexbor/lexbor/css/selectors/pseudo_state.h b/ext/lexbor/lexbor/css/selectors/pseudo_state.h index 5c5a31f94585..652e455f1f13 100644 --- a/ext/lexbor/lexbor/css/selectors/pseudo_state.h +++ b/ext/lexbor/lexbor/css/selectors/pseudo_state.h @@ -77,6 +77,10 @@ LXB_API bool lxb_css_selectors_state_pseudo_element_function__undef(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); +LXB_API bool +lxb_css_selectors_state_pseudo_class_function_lexbor_contains(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/selectors/selector.c b/ext/lexbor/lexbor/css/selectors/selector.c index e8bf96ba88cf..160d19fa45a2 100644 --- a/ext/lexbor/lexbor/css/selectors/selector.c +++ b/ext/lexbor/lexbor/css/selectors/selector.c @@ -638,11 +638,45 @@ lxb_css_selector_serialize_class(lxb_css_selector_t *selector, return LXB_STATUS_OK; } +static lxb_status_t +lxb_css_selector_serialize_escape_write(lxb_char_t *p, lxb_char_t *end, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_char_t *begin; + lxb_status_t status; + + begin = p; + + lxb_css_selector_serialize_write("\"", 1); + + while (p < end) { + if (*p == '"') { + if (begin < p) { + lxb_css_selector_serialize_write(begin, p - begin); + } + + lxb_css_selector_serialize_write("\\000022", 7); + + begin = p + 1; + } + + p++; + } + + if (begin < p) { + lxb_css_selector_serialize_write(begin, p - begin); + } + + lxb_css_selector_serialize_write("\"", 1); + + return LXB_STATUS_OK; +} + static lxb_status_t lxb_css_selector_serialize_attribute(lxb_css_selector_t *selector, lexbor_serialize_cb_f cb, void *ctx) { - lxb_char_t *p, *begin, *end; + lxb_char_t *p, *end; lxb_status_t status; lxb_css_selector_attribute_t *attr; @@ -686,30 +720,11 @@ lxb_css_selector_serialize_attribute(lxb_css_selector_t *selector, p = attr->value.data; end = attr->value.data + attr->value.length; - begin = p; - - lxb_css_selector_serialize_write("\"", 1); - - while (p < end) { - if (*p == '"') { - if (begin < p) { - lxb_css_selector_serialize_write(begin, p - begin); - } - - lxb_css_selector_serialize_write("\\000022", 7); - - begin = p + 1; - } - - p++; - } - - if (begin < p) { - lxb_css_selector_serialize_write(begin, p - begin); + status = lxb_css_selector_serialize_escape_write(p, end, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; } - lxb_css_selector_serialize_write("\"", 1); - if (attr->modifier != LXB_CSS_SELECTOR_MODIFIER_UNSET) { switch (attr->modifier) { case LXB_CSS_SELECTOR_MODIFIER_I: @@ -740,7 +755,9 @@ lxb_css_selector_serialize_pseudo_class_function(lxb_css_selector_t *selector, lexbor_serialize_cb_f cb, void *ctx) { lxb_status_t status; + lxb_char_t *p, *end; lxb_css_selector_pseudo_t *pseudo; + lxb_css_selector_contains_t *contains; const lxb_css_selectors_pseudo_data_func_t *pfunc; pseudo = &selector->u.pseudo; @@ -789,6 +806,22 @@ lxb_css_selector_serialize_pseudo_class_function(lxb_css_selector_t *selector, cb, ctx); break; + case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LEXBOR_CONTAINS: + contains = pseudo->data; + p = contains->str.data; + end = p + contains->str.length; + + status = lxb_css_selector_serialize_escape_write(p, end, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (contains->insensitive) { + lxb_css_selector_serialize_write(" i", 2); + } + + break; + default: status = LXB_STATUS_OK; break; diff --git a/ext/lexbor/lexbor/css/selectors/selector.h b/ext/lexbor/lexbor/css/selectors/selector.h index 52dbabc7ba5c..1862c868c8ce 100644 --- a/ext/lexbor/lexbor/css/selectors/selector.h +++ b/ext/lexbor/lexbor/css/selectors/selector.h @@ -80,6 +80,12 @@ typedef struct { } lxb_css_selector_anb_of_t; +typedef struct { + lexbor_str_t str; + bool insensitive; +} +lxb_css_selector_contains_t; + struct lxb_css_selector { lxb_css_selector_type_t type; lxb_css_selector_combinator_t combinator; diff --git a/ext/lexbor/lexbor/css/selectors/selectors.c b/ext/lexbor/lexbor/css/selectors/selectors.c index 52537873ef08..77586f4a65c6 100644 --- a/ext/lexbor/lexbor/css/selectors/selectors.c +++ b/ext/lexbor/lexbor/css/selectors/selectors.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -20,59 +20,51 @@ lxb_css_selectors_components_end(lxb_css_parser_t *parser, static const lxb_css_syntax_cb_components_t lxb_css_selectors_complex_list_cb = { - .state = lxb_css_selectors_state_complex_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_complex_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_compound_list_cb = { - .state = lxb_css_selectors_state_compound_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_compound_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_simple_list_cb = { - .state = lxb_css_selectors_state_simple_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_simple_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_relative_list_cb = { - .state = lxb_css_selectors_state_relative_list, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_relative_list, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_complex_cb = { - .state = lxb_css_selectors_state_complex, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_complex, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_compound_cb = { - .state = lxb_css_selectors_state_compound, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_compound, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_simple_cb = { - .state = lxb_css_selectors_state_simple, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_simple, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; static const lxb_css_syntax_cb_components_t lxb_css_selectors_relative_cb = { - .state = lxb_css_selectors_state_relative, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_selectors_components_end + .prelude = lxb_css_selectors_state_relative, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_selectors_components_end }; @@ -170,9 +162,7 @@ lxb_css_selectors_parse_relative_list(lxb_css_parser_t *parser, } static lxb_status_t -lxb_css_selectors_parse_prepare(lxb_css_parser_t *parser, - lxb_css_memory_t *memory, - lxb_css_selectors_t *selectors) +lxb_css_selectors_parse_prepare(lxb_css_parser_t *parser) { if (parser->stage != LXB_CSS_PARSER_CLEAN) { if (parser->stage == LXB_CSS_PARSER_RUN) { @@ -185,12 +175,6 @@ lxb_css_selectors_parse_prepare(lxb_css_parser_t *parser, parser->tkz->with_comment = false; parser->stage = LXB_CSS_PARSER_RUN; - parser->old_memory = parser->memory; - parser->old_selectors = parser->selectors; - - parser->memory = memory; - parser->selectors = selectors; - return LXB_STATUS_OK; } @@ -203,8 +187,7 @@ lxb_css_selectors_parse_process(lxb_css_parser_t *parser, lxb_css_parser_buffer_set(parser, data, length); - rule = lxb_css_syntax_parser_components_push(parser, NULL, NULL, - components, NULL, + rule = lxb_css_syntax_parser_components_push(parser, components, NULL, NULL, LXB_CSS_SYNTAX_TOKEN_UNDEF); if (rule == NULL) { return NULL; @@ -222,9 +205,6 @@ static void lxb_css_selectors_parse_finish(lxb_css_parser_t *parser) { parser->stage = LXB_CSS_PARSER_END; - - parser->memory = parser->old_memory; - parser->selectors = parser->old_selectors; } static lxb_css_selector_list_t * @@ -232,41 +212,45 @@ lxb_css_selectors_parse_list(lxb_css_parser_t *parser, const lxb_css_syntax_cb_components_t *components, const lxb_char_t *data, size_t length) { - lxb_css_memory_t *memory; - lxb_css_selectors_t *selectors; + bool my_mem, my_selectors; lxb_css_selector_list_t *list; - memory = parser->memory; - selectors = parser->selectors; + my_mem = false; + my_selectors = false; - if (selectors == NULL) { - selectors = lxb_css_selectors_create(); - parser->status = lxb_css_selectors_init(selectors); + if (parser->selectors == NULL) { + parser->selectors = lxb_css_selectors_create(); + parser->status = lxb_css_selectors_init(parser->selectors); if (parser->status != LXB_STATUS_OK) { - (void) lxb_css_selectors_destroy(selectors, true); + (void) lxb_css_selectors_destroy(parser->selectors, true); return NULL; } + + my_selectors = true; } else { - lxb_css_selectors_clean(selectors); + lxb_css_selectors_clean(parser->selectors); } - if (memory == NULL) { - memory = lxb_css_memory_create(); - parser->status = lxb_css_memory_init(memory, 256); + if (parser->memory == NULL) { + parser->memory = lxb_css_memory_create(); + parser->status = lxb_css_memory_init(parser->memory, 256); if (parser->status != LXB_STATUS_OK) { - if (selectors != parser->selectors) { - (void) lxb_css_selectors_destroy(selectors, true); + if (my_selectors) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, + true); } - (void) lxb_css_memory_destroy(memory, true); + (void) lxb_css_memory_destroy(parser->memory, true); return NULL; } + + my_mem = true; } - parser->status = lxb_css_selectors_parse_prepare(parser, memory, selectors); + parser->status = lxb_css_selectors_parse_prepare(parser); if (parser->status != LXB_STATUS_OK) { list = NULL; goto end; @@ -278,12 +262,12 @@ lxb_css_selectors_parse_list(lxb_css_parser_t *parser, end: - if (list == NULL && memory != parser->memory) { - (void) lxb_css_memory_destroy(memory, true); + if (list == NULL && my_mem) { + parser->memory = lxb_css_memory_destroy(parser->memory, true); } - if (selectors != parser->selectors) { - (void) lxb_css_selectors_destroy(selectors, true); + if (my_selectors) { + parser->selectors = lxb_css_selectors_destroy(parser->selectors, true); } return list; diff --git a/ext/lexbor/lexbor/css/selectors/state.c b/ext/lexbor/lexbor/css/selectors/state.c index 873e7d31cfda..1f0a391ac29a 100644 --- a/ext/lexbor/lexbor/css/selectors/state.c +++ b/ext/lexbor/lexbor/css/selectors/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -1557,8 +1557,8 @@ lxb_css_selectors_state_pseudo_class_function(lxb_css_parser_t *parser, selectors->comb_default = func->combinator; selectors->parent = selector; - rule = lxb_css_syntax_parser_function_push(parser, token, success, - &func->cb, selectors->list_last); + rule = lxb_css_syntax_consume_function(parser, token, &func->cb, + success, selectors->list_last); if (rule == NULL) { goto failed; } @@ -1663,8 +1663,8 @@ lxb_css_selectors_state_pseudo_element_function(lxb_css_parser_t *parser, selectors->comb_default = func->combinator; selectors->parent = selector; - rule = lxb_css_syntax_parser_function_push(parser, token, success, - &func->cb, selectors->list_last); + rule = lxb_css_syntax_consume_function(parser, token, &func->cb, + success, selectors->list_last); if (rule == NULL) { (void) lxb_css_parser_memory_fail(parser); return parser->status; @@ -1711,7 +1711,7 @@ lxb_css_selectors_state_function_end(lxb_css_parser_t *parser, lxb_css_selectors_t *selectors = parser->selectors; if (token->type == LXB_CSS_SYNTAX_TOKEN__EOF) { - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. End Of File in pseudo function", lxb_css_selectors_module_name); } @@ -1737,7 +1737,7 @@ lxb_css_selectors_state_function_end(lxb_css_parser_t *parser, return LXB_STATUS_OK; } - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. Pseudo function can't be empty: %S()", lxb_css_selectors_module_name, &selector->name); @@ -1783,7 +1783,7 @@ lxb_css_selectors_state_forgiving_cb(lxb_css_parser_t *parser, lxb_css_parser_set_ok(parser); if (token->type == LXB_CSS_SYNTAX_TOKEN__EOF) { - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. End Of File in pseudo function", lxb_css_selectors_module_name); } @@ -1814,7 +1814,7 @@ lxb_css_selectors_state_forgiving_cb(lxb_css_parser_t *parser, return LXB_STATUS_OK; } - (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_ERROR, + (void) lxb_css_log_format(parser->log, LXB_CSS_LOG_SYNTAX_ERROR, "%s. Pseudo function can't be empty: %S()", lxb_css_selectors_module_name, &selector->name); diff --git a/ext/lexbor/lexbor/css/state.c b/ext/lexbor/lexbor/css/state.c index 15a9614948f2..dda5310a9676 100644 --- a/ext/lexbor/lexbor/css/state.c +++ b/ext/lexbor/lexbor/css/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -9,6 +9,143 @@ #include "lexbor/css/at_rule/state.h" +static bool +lxb_css_state_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_state_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule); + +static bool +lxb_css_state_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_state_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +static bool +lxb_css_state_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_state_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_state_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); + +static lxb_status_t +lxb_css_state_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_block_t * +lxb_css_state_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static bool +lxb_css_state_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx); +static lxb_status_t +lxb_css_state_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); +static bool +lxb_css_state_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +static lxb_status_t +lxb_css_state_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_state_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static lxb_css_parser_state_f +lxb_css_state_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +static lxb_status_t +lxb_css_state_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed); + +static lxb_status_t +lxb_css_state_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed); + +static bool +lxb_css_state_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + + +static const lxb_css_syntax_cb_list_rules_t lxb_css_state_list_rules = { + .at_rule = lxb_css_state_at_rule_begin, + .qualified_rule = lxb_css_state_qualified_rule_begin, + .next = lxb_css_state_list_rules_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_state_list_rules_end +}; + +static const lxb_css_syntax_cb_at_rule_t lxb_css_state_at_rule = { + .prelude = lxb_css_state_at_rule_prelude, + .prelude_end = lxb_css_state_at_rule_prelude_end, + .block = lxb_css_state_at_rule_block_begin, + .cb.failed = lxb_css_state_at_rule_prelude_failed, + .cb.end = lxb_css_state_at_rule_end +}; + +static const lxb_css_syntax_cb_qualified_rule_t lxb_css_state_qualified_rule = { + .prelude = lxb_css_state_qualified_rule_prelude, + .prelude_end = lxb_css_state_qualified_rule_prelude_end, + .block = lxb_css_state_qualified_rule_block_begin, + .cb.failed = lxb_css_state_qualified_rule_prelude_failed, + .cb.end = lxb_css_state_qualified_rule_end +}; + +static const lxb_css_syntax_cb_block_t lxb_css_state_block = { + .at_rule = lxb_css_state_at_rule_begin, + .declarations = lxb_css_state_declarations_begin, + .qualified_rule = lxb_css_state_qualified_rule_begin, + .next = lxb_css_state_block_next, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_state_block_end, +}; + +static const lxb_css_syntax_cb_declarations_t lxb_css_state_declaration = { + .name = lxb_css_state_declaration_name, + .end = lxb_css_state_declaration_end, + .cb.failed = lxb_css_state_declarations_bad, + .cb.end = lxb_css_state_declarations_end +}; + + bool lxb_css_state_success(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx) @@ -49,3 +186,491 @@ lxb_css_state_stop(lxb_css_parser_t *parser, { return lxb_css_parser_stop(parser); } + +bool +lxb_css_state_blank(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + return lxb_css_parser_success(parser); +} + +const lxb_css_syntax_cb_list_rules_t * +lxb_css_state_cb_list_rules(void) +{ + return &lxb_css_state_list_rules; +} + +const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_cb_at_rule(void) +{ + return &lxb_css_state_at_rule; +} + +const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_cb_qualified_rule(void) +{ + return &lxb_css_state_qualified_rule; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_state_cb_block(void) +{ + return &lxb_css_state_block; +} + +const lxb_css_syntax_cb_declarations_t * +lxb_css_state_cb_declarations(void) +{ + return &lxb_css_state_declaration; +} + +static bool +lxb_css_state_list_rules_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + void *returned = lxb_css_syntax_returned(parser); + lxb_css_rule_list_t *list = ctx; + + if (returned != NULL) { + lxb_css_rule_list_append(list, returned); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_list_rules_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_list_t *list = ctx; + + lxb_css_syntax_set_return(parser, list); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_at_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx, + void **out_rule) +{ + lxb_css_rule_at_t *at; + const lxb_css_entry_at_rule_data_t *entry; + + at = lxb_css_at_rule_create(parser, lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length, + &entry); + if (at == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = at; + + return entry->cbs; +} + +static bool +lxb_css_state_at_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_at_t *at = ctx; + + at->prelude_begin = token->offset; + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_at_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_status_t status; + lxb_css_rule_at_t *at = ctx; + lxb_css_at_rule__custom_t *custom; + + at->prelude_end = token->offset; + + custom = at->u.custom; + + status = lxb_css_make_data(parser, &custom->prelude, at->prelude_begin, + at->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + return LXB_STATUS_OK; +} + +const lxb_css_syntax_cb_block_t * +lxb_css_state_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_list_t *list; + + list = lxb_css_rule_list_create(parser->memory); + if (list == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = list; + + return &lxb_css_state_block; +} + +static bool +lxb_css_state_at_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_at_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_at_t *at = ctx; + lxb_css_rule_list_t *block = lxb_css_syntax_returned(parser); + + at->u.custom->block = block; + + lxb_css_syntax_set_return(parser, at); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_qualified_rule_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_style_t *style; + + style = lxb_css_rule_style_create(parser->memory); + if (style == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = style; + + return &lxb_css_state_qualified_rule; +} + +static bool +lxb_css_state_qualified_rule_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + lxb_css_rule_style_t *style = ctx; + + lxb_css_selectors_clean(parser->selectors); + lxb_css_parser_state_set(parser, lxb_css_selectors_state_complex_list); + + style->prelude_begin = token->offset; + + return false; +} + +static lxb_status_t +lxb_css_state_qualified_rule_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + size_t begin; + lxb_status_t status; + lxb_css_rule_style_t *style = ctx; + lxb_css_rule_bad_style_t *bad; + + if (!failed) { + style->selector = parser->selectors->list; + style->prelude_end = token->offset; + + return LXB_STATUS_OK; + } + + begin = style->prelude_begin; + + (void) lxb_css_rule_style_destroy(style, true); + + bad = lxb_css_rule_bad_style_create(parser->memory); + if (bad == NULL) { + return lxb_css_parser_memory_fail_status(parser); + } + + bad->prelude_begin = begin; + bad->prelude_end = token->offset; + + status = lxb_css_make_data(parser, &bad->selectors, bad->prelude_begin, + bad->prelude_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + lxb_css_parser_set_context(parser, bad); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_block_t * +lxb_css_state_qualified_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_list_t *list; + + list = lxb_css_rule_list_create(parser->memory); + if (list == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = list; + + return &lxb_css_state_block; +} + +static bool +lxb_css_state_qualified_rule_prelude_failed(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx) +{ + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_qualified_rule_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_t *declrs; + lxb_css_rule_list_t *list; + lxb_css_rule_style_t *style; + lxb_css_rule_bad_style_t *bad; + + list = lxb_css_syntax_returned(parser); + + if (!failed) { + style = ctx; + + if (list != NULL && list->first != NULL + && list->first->type == LXB_CSS_RULE_DECLARATION_LIST) + { + declrs = list->first; + style->declarations = lxb_css_rule_declaration_list(declrs); + + declrs->parent = lxb_css_rule(style); + + if (list->first == list->last) { + list->last = NULL; + } + + if (declrs->next != NULL) { + declrs->next->prev = NULL; + } + + list->first = declrs->next; + declrs->next = NULL; + } + + style->child = list; + + lxb_css_syntax_set_return(parser, style); + } + else { + bad = ctx; + + if (list != NULL && list->first != NULL + && list->first->type == LXB_CSS_RULE_DECLARATION_LIST) + { + declrs = list->first; + bad->declarations = lxb_css_rule_declaration_list(declrs); + + declrs->parent = lxb_css_rule(bad); + + if (list->first == list->last) { + list->last = NULL; + } + + if (declrs->next != NULL) { + declrs->next->prev = NULL; + } + + list->first = declrs->next; + declrs->next = NULL; + } + + bad->child = list; + + lxb_css_syntax_set_return(parser, bad); + } + + return LXB_STATUS_OK; +} + +static bool +lxb_css_state_block_next(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + /* rule can be either a declaration list or an at rule. */ + + lxb_css_rule_t *rule = lxb_css_syntax_returned(parser); + lxb_css_rule_list_t *list = ctx; + + lxb_css_rule_list_append(list, rule); + + return lxb_css_parser_success(parser); +} + +static lxb_status_t +lxb_css_state_block_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_list_t *list = ctx; + + lxb_css_syntax_set_return(parser, list); + + return LXB_STATUS_OK; +} + +static const lxb_css_syntax_cb_declarations_t * +lxb_css_state_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + lxb_css_rule_declaration_list_t *list; + + list = lxb_css_rule_declaration_list_create(parser->memory); + if (list == NULL) { + return lxb_css_parser_memory_fail_null(parser); + } + + *out_rule = list; + + return &lxb_css_state_declaration; +} + +static lxb_css_parser_state_f +lxb_css_state_declaration_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule) +{ + const lxb_css_entry_data_t *entry; + lxb_css_rule_declaration_t *declar; + + declar = lxb_css_declaration_create(parser, + lxb_css_syntax_token_ident(token)->data, + lxb_css_syntax_token_ident(token)->length, + &entry); + if (declar == NULL) { + (void) lxb_css_parser_memory_fail_null(parser); + return NULL; + } + + /* We present an original position. */ + + declar->offset.name_begin = token->offset; + declar->offset.name_end = token->offset + + lxb_css_syntax_token_base(token)->length; + *out_rule = declar; + + return entry->state; +} + +static lxb_status_t +lxb_css_state_declaration_end(lxb_css_parser_t *parser, + void *declarations, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed) +{ + lxb_status_t status; + lxb_css_property__undef_t *undef; + lxb_css_rule_declaration_t *declar = ctx; + lxb_css_rule_declaration_list_t *list = declarations; + + declar->offset.value_begin = offset->value_begin; + declar->offset.value_end = offset->value_end; + declar->offset.important_begin = offset->important_begin; + declar->offset.important_end = offset->important_end; + declar->important = important; + + if (failed) { + lxb_css_rule_declaration_destroy(declar, false); + + undef = lxb_css_property__undef_create(parser->memory); + if (undef == NULL) { + return lxb_css_parser_memory_fail_status(parser); + } + + undef->type = declar->type; + + status = lxb_css_make_data(parser, &undef->value, + declar->offset.value_begin, + declar->offset.value_end); + if (status != LXB_STATUS_OK) { + return lxb_css_parser_memory_fail_status(parser); + } + + declar->u.undef = undef; + declar->type = LXB_CSS_PROPERTY__UNDEF; + } + + lxb_css_rule_declaration_list_append(list, lxb_css_rule(declar)); + + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_state_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, bool failed) +{ + lxb_css_rule_declaration_list_t *list = ctx; + + lxb_css_syntax_set_return(parser, list); + + return LXB_STATUS_OK; +} + +static bool +lxb_css_state_declarations_bad(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx) +{ + lxb_css_rule_declaration_t *declar; + + if (ctx == NULL) { + declar = lxb_css_rule_declaration_create(parser->memory); + if (declar == NULL) { + return lxb_css_parser_memory_fail(parser); + } + + lxb_css_parser_current_rule(parser)->context = declar; + declar->type = LXB_CSS_PROPERTY__UNDEF; + } + + while (token != NULL && token->type != LXB_CSS_SYNTAX_TOKEN__END) { + lxb_css_syntax_parser_consume(parser); + token = lxb_css_syntax_parser_token(parser); + } + + return lxb_css_parser_success(parser); +} diff --git a/ext/lexbor/lexbor/css/state.h b/ext/lexbor/lexbor/css/state.h index 0a2abd803634..6ecd50343928 100644 --- a/ext/lexbor/lexbor/css/state.h +++ b/ext/lexbor/lexbor/css/state.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,6 +12,7 @@ extern "C" { #endif #include "lexbor/css/base.h" +#include "lexbor/css/syntax/syntax.h" LXB_API bool @@ -26,6 +27,30 @@ LXB_API bool lxb_css_state_stop(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx); +LXB_API bool +lxb_css_state_blank(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, void *ctx); + +LXB_API const lxb_css_syntax_cb_list_rules_t * +lxb_css_state_cb_list_rules(void); + +LXB_API const lxb_css_syntax_cb_at_rule_t * +lxb_css_state_cb_at_rule(void); + +LXB_API const lxb_css_syntax_cb_qualified_rule_t * +lxb_css_state_cb_qualified_rule(void); + +LXB_API const lxb_css_syntax_cb_block_t * +lxb_css_state_cb_block(void); + +LXB_API const lxb_css_syntax_cb_declarations_t * +lxb_css_state_cb_declarations(void); + +const lxb_css_syntax_cb_block_t * +lxb_css_state_at_rule_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/stylesheet.c b/ext/lexbor/lexbor/css/stylesheet.c new file mode 100644 index 000000000000..f03f145721c4 --- /dev/null +++ b/ext/lexbor/lexbor/css/stylesheet.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2021-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/stylesheet.h" +#include "lexbor/css/parser.h" +#include "lexbor/css/at_rule.h" +#include "lexbor/css/property.h" +#include "lexbor/css/rule.h" +#include "lexbor/css/state.h" +#include "lexbor/css/selectors/selectors.h" +#include "lexbor/css/selectors/state.h" + + +lxb_css_stylesheet_t * +lxb_css_stylesheet_create(lxb_css_memory_t *memory) +{ + lxb_status_t status; + lxb_css_stylesheet_t *stylesheet; + + if (memory == NULL) { + memory = lxb_css_memory_create(); + status = lxb_css_memory_init(memory, 1024); + + if (status != LXB_STATUS_OK) { + (void) lxb_css_memory_destroy(memory, true); + return NULL; + } + } + else { + (void) lxb_css_memory_ref_inc(memory); + } + + stylesheet = lexbor_mraw_calloc(memory->mraw, sizeof(lxb_css_stylesheet_t)); + if (stylesheet == NULL) { + return NULL; + } + + stylesheet->memory = memory; + + return stylesheet; +} + +lxb_css_stylesheet_t * +lxb_css_stylesheet_destroy(lxb_css_stylesheet_t *sst, bool destroy_memory) +{ + if (sst == NULL) { + return NULL; + } + + if (destroy_memory) { + (void) lxb_css_memory_ref_dec_destroy(sst->memory); + return NULL; + } + + if (sst->root != NULL) { + (void) lxb_css_rule_destroy(sst->root, true); + } + + (void) lexbor_mraw_free(sst->memory->mraw, sst); + + return NULL; +} + +lxb_status_t +lxb_css_stylesheet_parse(lxb_css_stylesheet_t *sst, lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length) +{ + lxb_status_t status; + lxb_css_rule_list_t *list; + lxb_css_selectors_t selectors; + + if (sst == NULL || parser == NULL) { + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (parser->selectors == NULL) { + status = lxb_css_selectors_init(&selectors); + if (status != LXB_STATUS_OK) { + return status; + } + + parser->selectors = &selectors; + } + else { + lxb_css_selectors_clean(parser->selectors); + } + + parser->memory = sst->memory; + + list = lxb_css_syntax_parse_list_rules(parser, + lxb_css_state_cb_list_rules(), + data, length); + + if (parser->selectors == &selectors) { + parser->selectors = lxb_css_selectors_destroy(&selectors, false); + } + + if (list == NULL) { + sst->root = NULL; + return parser->status; + } + + sst->root = &list->rule; + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/stylesheet.h b/ext/lexbor/lexbor/css/stylesheet.h index 5f3e37d82e45..9d52f9897cc5 100644 --- a/ext/lexbor/lexbor/css/stylesheet.h +++ b/ext/lexbor/lexbor/css/stylesheet.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -25,26 +25,62 @@ struct lxb_css_stylesheet { void *element; /* lxb_html_style_element_t * */ }; +/* + * Create a new CSS stylesheet object. + * + * This function creates a stylesheet object which holds the parsed CSS rules. + * + * @param[in] memory Optional. A memory pool to use for allocations. + * If NULL, a new internal memory pool is created/managed + * by the stylesheet. + * + * @return A new lxb_css_stylesheet_t * or NULL on failure. + */ LXB_API lxb_css_stylesheet_t * lxb_css_stylesheet_create(lxb_css_memory_t *memory); +/* + * Destroy a CSS stylesheet object. + * + * @param[in] sst Optional. The stylesheet object to destroy. + * If NULL, the function returns NULL. + * @param[in] destroy_memory If true, the memory pool attached to + * the stylesheet is also destroyed. + * + * @return Always NULL. + */ LXB_API lxb_css_stylesheet_t * lxb_css_stylesheet_destroy(lxb_css_stylesheet_t *sst, bool destroy_memory); -LXB_API lxb_css_stylesheet_t * -lxb_css_stylesheet_parse(lxb_css_parser_t *parser, - const lxb_char_t *data, size_t length); - +/* + * Parse CSS content into the stylesheet. + * + * This function takes CSS text and builds the rule tree in the stylesheet. + * + * The function returns an error only in extremely unforeseen circumstances, + * such as the inability to allocate memory for objects. Any broken CSS will + * not cause an error. + * + * Selectors note: + * If the provided parser does not have an initialized selectors module, one + * will be created temporarily for this call. For better performance when + * parsing multiple stylesheets, initialize the selectors module in + * the parser once: + * + * lxb_css_parser_t *parser = lxb_css_parser_create(); + * lxb_css_parser_init(parser, NULL); + * lxb_css_parser_selectors_init(parser); + * + * @param[in] sst Required. The target stylesheet. + * @param[in] parser Required. An initialized CSS parser. + * @param[in] data Optional. The CSS text data. + * @param[in] length Required. Length of the data in bytes. + * + * @return LXB_STATUS_OK on success, or an error code on failure. + */ LXB_API lxb_status_t -lxb_css_stylesheet_prepare(lxb_css_parser_t *parser, lxb_css_memory_t *memory, - lxb_css_selectors_t *selectors); - -LXB_API lxb_css_stylesheet_t * -lxb_css_stylesheet_process(lxb_css_parser_t *parser, - const lxb_char_t *data, size_t length); - -LXB_API void -lxb_css_stylesheet_finish(lxb_css_parser_t *parser); +lxb_css_stylesheet_parse(lxb_css_stylesheet_t *sst, lxb_css_parser_t *parser, + const lxb_char_t *data, size_t length); #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/css/syntax/anb.c b/ext/lexbor/lexbor/css/syntax/anb.c index ffd1751cdabf..d3f7c7bfe0a6 100644 --- a/ext/lexbor/lexbor/css/syntax/anb.c +++ b/ext/lexbor/lexbor/css/syntax/anb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2022 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -38,10 +38,9 @@ lxb_css_syntax_anb_state_ident_data(lxb_css_parser_t *parser, static const lxb_css_syntax_cb_pipe_t lxb_css_syntax_anb_pipe = { - .state = lxb_css_syntax_anb_state, - .block = NULL, - .failed = lxb_css_state_failed, - .end = lxb_css_syntax_anb_end + .prelude = lxb_css_syntax_anb_state, + .cb.failed = lxb_css_state_failed, + .cb.end = lxb_css_syntax_anb_end }; @@ -66,8 +65,8 @@ lxb_css_syntax_anb_parse(lxb_css_parser_t *parser, lxb_css_parser_buffer_set(parser, data, length); - rule = lxb_css_syntax_parser_pipe_push(parser, NULL, - &lxb_css_syntax_anb_pipe, &anb, + rule = lxb_css_syntax_parser_pipe_push(parser, &lxb_css_syntax_anb_pipe, + NULL, &anb, LXB_CSS_SYNTAX_TOKEN_UNDEF); if (rule == NULL) { return anb; diff --git a/ext/lexbor/lexbor/css/syntax/base.h b/ext/lexbor/lexbor/css/syntax/base.h index 3dc981ba3da2..627fce4c7fa5 100644 --- a/ext/lexbor/lexbor/css/syntax/base.h +++ b/ext/lexbor/lexbor/css/syntax/base.h @@ -17,7 +17,7 @@ extern "C" { #define LXB_CSS_SYNTAX_VERSION_MAJOR 1 -#define LXB_CSS_SYNTAX_VERSION_MINOR 3 +#define LXB_CSS_SYNTAX_VERSION_MINOR 4 #define LXB_CSS_SYNTAX_VERSION_PATCH 0 #define LXB_CSS_SYNTAX_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/css/syntax/parser.c b/ext/lexbor/lexbor/css/syntax/parser.c index 5a3c7abf24f8..7e7e973f75d6 100644 --- a/ext/lexbor/lexbor/css/syntax/parser.c +++ b/ext/lexbor/lexbor/css/syntax/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2025 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -11,14 +11,11 @@ #include "lexbor/css/at_rule/state.h" -static const lxb_css_syntax_token_t lxb_css_syntax_token_terminated = -{ - .types.terminated = {.begin = NULL, .length = 0, .user_id = 0}, - .type = LXB_CSS_SYNTAX_TOKEN__END, - .offset = 0, - .cloned = false -}; +static const lexbor_str_t lxb_css_err_rc = lexbor_str("Unexpected token in " + "qualified rule: RC_BRACKET"); +static lxb_css_syntax_rule_t * +lxb_css_syntax_parser_stack_pop(lxb_css_parser_t *parser); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, @@ -35,28 +32,105 @@ lxb_css_syntax_parser_list_rules_qualified(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); -static bool +static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_at_rule_f cb, + bool nested); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end_consule_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule); +lxb_css_syntax_parser_qualified_rule_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_block_f cb); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_at(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_qualified(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_validate(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); -static bool -lxb_css_syntax_parser_declarations_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, @@ -69,40 +143,77 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_end_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_end_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_components(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_components_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + static const lxb_css_syntax_token_t * lxb_css_syntax_parser_function(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule); +lxb_css_syntax_parser_function_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); static const lxb_css_syntax_token_t * lxb_css_syntax_parser_pipe(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_pipe_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + lxb_inline const lxb_css_syntax_token_t * lxb_css_syntax_parser_failed(lxb_css_parser_t *parser, lxb_status_t status) @@ -111,6 +222,31 @@ lxb_css_syntax_parser_failed(lxb_css_parser_t *parser, lxb_status_t status) return NULL; } +lxb_inline const lxb_css_syntax_token_t * +lxb_css_syntax_token_parser_do_phase_again(lxb_css_parser_t *parser) +{ + parser->fake_null = true; + return NULL; +} + +lxb_inline const lxb_css_syntax_token_t * +lxb_css_syntax_parser_call_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token) +{ + lxb_css_syntax_rule_t *rules; + + (void) lxb_css_syntax_parser_stack_pop(parser); + + rules = parser->rules; + + if (parser->rules <= parser->rules_begin) { + rules->state = lxb_css_state_stop; + return token; + } + + return rules->back(parser, token, rules); +} + lxb_status_t lxb_css_syntax_parser_run(lxb_css_parser_t *parser) @@ -177,369 +313,259 @@ lxb_css_syntax_parser_consume(lxb_css_parser_t *parser) lxb_css_syntax_rule_t * lxb_css_syntax_parser_list_rules_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_list_rules_t *cb_rules, - void *ctx, bool top_level, - lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - - parser->rules->state = lxb_css_state_success; + + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_list_rules; - rule->state = cb_rules->cb.state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_list_rules; - rule->cbx.list_rules = cb_rules; - rule->context = ctx; - rule->block_end = stop; - rule->top_level = top_level; - - if (token != NULL) { - rule->u.list_rules.begin = token->offset; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_list_rules, + .state = lxb_css_state_blank, + .back = lxb_css_syntax_parser_list_rules_back, + .cbx.list_rules = cb_rules, + .context = ctx, + .block_end = stop + }; return rule; } lxb_css_syntax_rule_t * lxb_css_syntax_parser_at_rule_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_at_rule_t *at_rule, - void *ctx, lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool nested) { - lxb_status_t status; - lxb_css_syntax_at_rule_offset_t *at; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_at_rule; - rule->state = at_rule->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_at_rule; - rule->cbx.at_rule = at_rule; - rule->context = ctx; - rule->block_end = stop; - - if (token != NULL) { - at = &rule->u.at_rule; - - at->name = token->offset; - at->prelude = token->offset + lxb_css_syntax_token_base(token)->length; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_at_rule, + .state = at_rule->prelude, + .back = lxb_css_syntax_parser_at_back_to_prelude, + .cbx.at_rule = at_rule, + .context = ctx, + .block_end = stop, + .nested = nested + }; return rule; } lxb_css_syntax_rule_t * lxb_css_syntax_parser_qualified_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_qualified_rule_t *qualified, - void *ctx, lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool nested) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_qualified_rule; - rule->state = qualified->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_qualified_rule; - rule->cbx.qualified_rule = qualified; - rule->context = ctx; - rule->block_end = stop; - - if (token != NULL) { - rule->u.qualified.prelude = token->offset; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_qualified_rule, + .state = qualified->prelude, + .back = lxb_css_syntax_parser_qualified_back_to_prelude, + .cbx.qualified_rule = qualified, + .context = ctx, + .block_end = stop, + .nested = nested + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_declarations_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_declarations_t *declarations, - void *ctx, lxb_css_syntax_token_type_t stop) +lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_declarations; - rule->state = declarations->cb.state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_declarations; - rule->cbx.declarations = declarations; - rule->context = ctx; - rule->block_end = stop; - - if (token != NULL) { - rule->u.declarations.begin = token->offset; - } - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_block, + .state = lxb_css_state_blank, + .back = lxb_css_syntax_parser_block_back, + .cbx.block = block, + .context = ctx + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_components_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_components_t *comp, - void *ctx, lxb_css_syntax_token_type_t stop) +lxb_css_syntax_parser_declarations_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool name_validate, bool nested) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; + lxb_css_syntax_state_f phase; - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_components; - rule->state = comp->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_components; - rule->cbx.components = comp; - rule->context = ctx; - rule->block_end = stop; + phase = (!name_validate) ? lxb_css_syntax_parser_declarations_begin + : lxb_css_syntax_parser_declarations_validate; - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = phase, + .state = lxb_css_state_blank, + .back = lxb_css_syntax_parser_declaration_back_to_value, + .cbx.declarations = declr, + .context = ctx, + .block_end = stop, + .nested = nested + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_function_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_function_t *func, - void *ctx) +lxb_css_syntax_parser_components_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - if (token == NULL || token->type != LXB_CSS_SYNTAX_TOKEN_FUNCTION) { - parser->status = LXB_STATUS_ERROR_WRONG_ARGS; - return NULL; - } - - if (parser->rules > parser->rules_begin) { - rule = parser->rules; - - if (rule->deep != 0 - && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) - { - rule->deep--; - parser->types_pos--; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; } } - parser->rules->state = lxb_css_state_success; - - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; - } + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_function; - rule->state = func->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_function; - rule->cbx.func = func; - rule->context = ctx; - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_components, + .state = comp->prelude, + .back = lxb_css_syntax_parser_components_back_to_value, + .cbx.components = comp, + .context = ctx, + .block_end = stop + }; return rule; } lxb_css_syntax_rule_t * -lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_block_t *block, - void *ctx) +lxb_css_syntax_parser_function_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_function_t *func, + lxb_css_parser_state_f back, void *ctx) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - lxb_css_syntax_token_type_t block_end; - - if (token == NULL) { - parser->status = LXB_STATUS_ERROR_WRONG_ARGS; - return NULL; - } - - switch (token->type) { - case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: - block_end = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; - break; - - case LXB_CSS_SYNTAX_TOKEN_FUNCTION: - case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: - block_end = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; - break; - - case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: - block_end = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; - break; - default: - parser->status = LXB_STATUS_ERROR_WRONG_ARGS; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { return NULL; - } - - if (parser->rules > parser->rules_begin) { - rule = parser->rules; - - if (rule->deep != 0 && parser->types_pos[-1] == block_end) { - rule->deep--; - parser->types_pos--; } } - parser->rules->state = lxb_css_state_success; - - lxb_css_parser_offset_set(parser, token); - - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; - } + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_block; - rule->state = block->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_block; - rule->cbx.block = block; - rule->context = ctx; - rule->block_end = block_end; - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_function, + .state = func->value, + .back = lxb_css_syntax_parser_function_back, + .cbx.func = func, + .context = ctx + }; return rule; } lxb_css_syntax_rule_t * lxb_css_syntax_parser_pipe_push(lxb_css_parser_t *parser, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_pipe_t *pipe, - void *ctx, lxb_css_syntax_token_type_t stop) + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop) { - lxb_status_t status; lxb_css_syntax_rule_t *rule; - status = lxb_css_syntax_stack_expand(parser, 1); - if (status != LXB_STATUS_OK) { - parser->status = status; - return NULL; + if ((parser->rules + 1) >= parser->rules_end) { + parser->status = lxb_css_syntax_stack_expand(parser, 1); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } } - parser->rules->state = lxb_css_state_success; + parser->rules->back_state = back; rule = ++parser->rules; - memset(rule, 0x00, sizeof(lxb_css_syntax_rule_t)); - - rule->phase = lxb_css_syntax_parser_pipe; - rule->state = pipe->state; - rule->state_back = state_back; - rule->back = lxb_css_syntax_parser_pipe; - rule->cbx.pipe = pipe; - rule->context = ctx; - rule->block_end = stop; - - parser->context = NULL; + *rule = (lxb_css_syntax_rule_t) { + .phase = lxb_css_syntax_parser_pipe, + .state = pipe->prelude, + .back = lxb_css_syntax_parser_pipe_back, + .cbx.pipe = pipe, + .context = ctx, + .block_end = stop + }; return rule; } -lxb_css_syntax_rule_t * +static lxb_css_syntax_rule_t * lxb_css_syntax_parser_stack_pop(lxb_css_parser_t *parser) { return parser->rules--; @@ -554,12 +580,16 @@ lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, return token; } + rule->skip_consume = true; + begin: rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; switch (token->type) { case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + case LXB_CSS_SYNTAX_TOKEN_CDC: + case LXB_CSS_SYNTAX_TOKEN_CDO: lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -577,22 +607,6 @@ lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN__EOF: goto done; - case LXB_CSS_SYNTAX_TOKEN_CDC: - case LXB_CSS_SYNTAX_TOKEN_CDO: - if (rule->top_level) { - lxb_css_syntax_token_consume(parser->tkz); - - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } - - goto begin; - } - - /* fall through */ - default: if (rule->block_end == token->type && rule->deep == 0) { goto done; @@ -607,79 +621,136 @@ lxb_css_syntax_parser_list_rules(lxb_css_parser_t *parser, done: rule->phase = lxb_css_syntax_parser_end; - rule->skip_consume = true; - rule->u.list_rules.end = token->offset; - - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, 0); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_at(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { - if (rule->state != lxb_css_state_success) { - return token; - } + const lxb_css_syntax_cb_list_rules_t *list_rules = rule->cbx.list_rules; - rule = lxb_css_syntax_parser_at_rule_push(parser, token, - lxb_css_syntax_parser_list_rules_back, - rule->cbx.list_rules->at_rule, - rule->context, rule->block_end); - if (rule == NULL) { - return NULL; - } - - parser->fake_null = true; - - return NULL; + return lxb_css_syntax_parser_at_begin(parser, token, rule, list_rules->next, + list_rules->at_rule, false); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_qualified(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { - if (rule->state != lxb_css_state_success) { - return token; - } + void *qualified_ctx; + lxb_css_syntax_rule_t *qualified; + lxb_css_syntax_begin_qualified_rule_f cb; + const lxb_css_syntax_cb_list_rules_t *list_rules; + const lxb_css_syntax_cb_qualified_rule_t *cb_qualified; - rule = lxb_css_syntax_parser_qualified_push(parser, token, - lxb_css_syntax_parser_list_rules_back, - rule->cbx.list_rules->qualified_rule, - rule->context, rule->block_end); - if (rule == NULL) { - return NULL; + qualified_ctx = NULL; + list_rules = rule->cbx.list_rules; + cb = list_rules->qualified_rule; + + rule->skip_consume = false; + + cb_qualified = cb(parser, token, rule->context, &qualified_ctx); + if (cb_qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); } - parser->fake_null = true; + qualified = lxb_css_syntax_parser_qualified_push(parser, cb_qualified, + list_rules->next, + qualified_ctx, + rule->block_end, + false); + if (qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } - return NULL; + return lxb_css_syntax_token_parser_do_phase_again(parser); } -static bool +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * lxb_css_syntax_parser_list_rules_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx) + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - lxb_css_syntax_rule_t *rule; + rule->phase = lxb_css_syntax_parser_list_rules; + rule->state = rule->back_state; + rule->skip_consume = true; - if (token->type == LXB_CSS_SYNTAX_TOKEN__END) { - return lxb_css_parser_success(parser); + return token; +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_at_rule_f cb, + bool nested) +{ + void *at_rule_ctx; + lxb_css_syntax_rule_t *at_rule; + const lxb_css_syntax_cb_at_rule_t *cb_at_rule; + + at_rule_ctx = NULL; + rule->skip_consume = false; + + cb_at_rule = cb(parser, token, rule->context, &at_rule_ctx); + if (cb_at_rule == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); } - rule = parser->rules; - rule->state = rule->cbx.list_rules->next; + at_rule = lxb_css_syntax_parser_at_rule_push(parser, cb_at_rule, + back_state, at_rule_ctx, + rule->block_end, nested); + if (at_rule == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } + + lxb_css_syntax_token_consume(parser->tkz); + + token = lxb_css_syntax_token(parser->tkz); + if (token == NULL) { + return lxb_css_syntax_parser_failed(parser, parser->tkz->status); + } - return false; + if (token->type == LXB_CSS_SYNTAX_TOKEN_WHITESPACE) { + lxb_css_syntax_token_consume(parser->tkz); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); } +/* + * First call for this code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + * Rule -- lxb_css_syntax_rule_t with at_rule callbacks. + */ static const lxb_css_syntax_token_t * lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { lxb_status_t status; + const lxb_css_log_message_t *msg; if (rule->offset > token->offset) { return token; @@ -688,7 +759,7 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; + rule->phase = lxb_css_syntax_parser_at_prelude_end; goto done; } @@ -706,25 +777,11 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: if (rule->deep == 0) { - rule->phase = lxb_css_syntax_parser_start_block; - - rule->u.at_rule.prelude_end = token->offset; - rule->u.at_rule.block = token->offset - + lxb_css_syntax_token_base(token)->length; - + rule->phase = lxb_css_syntax_parser_at_block; + rule->back = lxb_css_syntax_parser_end_back; rule->skip_consume = true; - parser->block = rule->cbx.cb->block; - - lxb_css_syntax_token_consume(parser->tkz); - - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } - - token = &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } status = lxb_css_parser_types_push(parser, @@ -732,13 +789,25 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, break; case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - if (rule->deep == 1) { - goto done; + if (rule->deep != 0) { + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + } + else { + msg = lxb_css_log_format(parser->log, + LXB_CSS_LOG_SYNTAX_ERROR, + "%S", &lxb_css_err_rc); + if (msg == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); } - parser->types_pos--; - rule->deep--; + if (rule->nested) { + rule->phase = lxb_css_syntax_parser_at_prelude_end; + goto done; + } } return token; @@ -754,12 +823,14 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_at_prelude_end_consule_token; goto done; } return token; case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_at_prelude_end; goto done; default: @@ -776,17 +847,91 @@ lxb_css_syntax_parser_at_rule(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - if (rule->u.at_rule.prelude_end != 0) { - rule->u.at_rule.block_end = token->offset; + return lxb_css_parser_token_end(parser, token->offset); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + const lxb_css_syntax_cb_at_rule_t *at_rule = rule->cbx.at_rule; + + status = at_rule->prelude_end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - else { - rule->u.at_rule.prelude_end = token->offset; + + return lxb_css_syntax_parser_block_begin(parser, token, rule, + at_rule->prelude, at_rule->block); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + const lxb_css_syntax_cb_at_rule_t *at_rule = rule->cbx.at_rule; + + rule->phase = lxb_css_syntax_parser_end; + rule->state = lxb_css_state_success; + + status = at_rule->prelude_end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - return &lxb_css_syntax_token_terminated; + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_prelude_end_consule_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + const lxb_css_syntax_cb_at_rule_t *at_rule = rule->cbx.at_rule; + + rule->phase = lxb_css_syntax_parser_end_consume_token; + + status = at_rule->prelude_end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_at_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_at_rule; + rule->state = rule->back_state; + rule->skip_consume = false; + + return token; } static const lxb_css_syntax_token_t * @@ -795,8 +940,7 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule) { lxb_status_t status; - - /* It is necessary to avoid re-entry of the token into the phase. */ + const lxb_css_log_message_t *msg; if (rule->offset > token->offset) { return token; @@ -805,7 +949,6 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; goto done; } @@ -823,25 +966,11 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: if (rule->deep == 0) { - rule->phase = lxb_css_syntax_parser_start_block; - - rule->u.qualified.prelude_end = token->offset; - rule->u.qualified.block = token->offset - + lxb_css_syntax_token_base(token)->length; - + rule->phase = lxb_css_syntax_parser_qualified_rule_block; + rule->back = lxb_css_syntax_parser_end_back; rule->skip_consume = true; - parser->block = rule->cbx.cb->block; - - lxb_css_syntax_token_consume(parser->tkz); - - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } - - token = &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } status = lxb_css_parser_types_push(parser, @@ -849,13 +978,24 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, break; case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - if (rule->deep == 1) { - goto done; + if (rule->deep != 0) { + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + } + else { + msg = lxb_css_log_format(parser->log, + LXB_CSS_LOG_SYNTAX_ERROR, + "%S", &lxb_css_err_rc); + if (msg == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); } - parser->types_pos--; - rule->deep--; + if (rule->nested) { + goto done; + } } return token; @@ -868,7 +1008,7 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, } return token; - + case LXB_CSS_SYNTAX_TOKEN__EOF: goto done; @@ -886,23 +1026,113 @@ lxb_css_syntax_parser_qualified_rule(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_end; + rule->phase = lxb_css_syntax_parser_qualified_prelude_end; rule->skip_consume = true; - if (rule->u.qualified.block != 0) { - rule->u.qualified.block_end = token->offset; + return lxb_css_parser_token_end(parser, token->offset); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_rule_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; + + qualified_rule = rule->cbx.qualified_rule; + + parser->status = qualified_rule->prelude_end(parser, token, + rule->context, rule->failed); + if (parser->status != LXB_STATUS_OK) { + return NULL; } - else { - rule->u.qualified.prelude_end = token->offset; + + return lxb_css_syntax_parser_block_begin(parser, token, rule, + qualified_rule->prelude, + qualified_rule->block); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_prelude_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; + + qualified_rule = rule->cbx.qualified_rule; + + parser->status = qualified_rule->prelude_end(parser, token, + rule->context, rule->failed); + if (parser->status != LXB_STATUS_OK) { + return NULL; + } + + rule->phase = lxb_css_syntax_parser_end; + rule->state = lxb_css_state_success; + + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_qualified_back_to_prelude(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_qualified_rule; + rule->state = rule->back_state; + rule->skip_consume = false; + + return token; +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + lxb_css_parser_state_f back_state, + lxb_css_syntax_begin_block_f cb) +{ + void *block_ctx; + lxb_css_syntax_rule_t *block; + const lxb_css_syntax_cb_block_t *cb_block; + + block_ctx = NULL; + rule->skip_consume = false; + + cb_block = cb(parser, token, rule->context, &block_ctx); + if (cb_block == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); + } + + block = lxb_css_syntax_parser_block_push(parser, cb_block, back_state, + block_ctx); + if (block == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); } - return &lxb_css_syntax_token_terminated; + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_syntax_token_parser_do_phase_again(parser); } static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { if (rule->offset > token->offset) { return token; @@ -912,11 +1142,6 @@ lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; - if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; - goto done; - } - switch (token->type) { case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: @@ -930,93 +1155,221 @@ lxb_css_syntax_parser_declarations(lxb_css_parser_t *parser, goto begin; - case LXB_CSS_SYNTAX_TOKEN_IDENT: - rule->u.declarations.name_begin = token->offset; - - if (lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) { - rule->phase = lxb_css_syntax_parser_declarations_name; - parser->block = rule->cbx.cb->block; + case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: + if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_end_consume_token; + break; + } - return token; + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; } - rule->state = rule->cbx.cb->failed; - rule->phase = lxb_css_syntax_parser_declarations_drop; - rule->failed = true; + return token; + case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_end; break; case LXB_CSS_SYNTAX_TOKEN_AT_KEYWORD: - rule->u.declarations.name_begin = 0; - - rule = lxb_css_syntax_parser_at_rule_push(parser, token, - lxb_css_syntax_parser_declarations_back, - rule->cbx.declarations->at_rule, rule->context, - rule->block_end); - if (rule != NULL) { - parser->fake_null = true; - } + rule->phase = lxb_css_syntax_parser_block_at; + break; - return NULL; + case LXB_CSS_SYNTAX_TOKEN_IDENT: + if (lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) { + rule->phase = lxb_css_syntax_parser_block_declarations; + break; + } - case LXB_CSS_SYNTAX_TOKEN__EOF: - goto done; + /* Fall Through. */ default: - rule->state = rule->cbx.cb->failed; - rule->phase = lxb_css_syntax_parser_declarations_drop; - rule->failed = true; - - rule->u.declarations.name_begin = token->offset; + rule->phase = lxb_css_syntax_parser_block_qualified; break; } - parser->fake_null = true; + rule->skip_consume = true; - return NULL; + return lxb_css_parser_token_end(parser, 0); +} -done: +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_at(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + const lxb_css_syntax_cb_block_t *block = rule->cbx.block; - rule->phase = lxb_css_syntax_parser_end; - rule->state = lxb_css_state_success; - rule->skip_consume = true; + return lxb_css_syntax_parser_at_begin(parser, token, rule, + block->next, block->at_rule, true); +} - rule->u.declarations.name_begin = 0; - rule->u.declarations.end = token->offset; +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + void *declr_ctx; + lxb_css_syntax_rule_t *declr_rule; + lxb_css_syntax_begin_declarations_f cb; + const lxb_css_syntax_cb_block_t *block; + const lxb_css_syntax_cb_declarations_t *cb_declr; - parser->fake_null = true; + declr_ctx = NULL; + block = rule->cbx.block; + cb = block->declarations; - return NULL; + rule->skip_consume = false; + + cb_declr = cb(parser, token, rule->context, &declr_ctx); + if (cb_declr == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); + } + + declr_rule = lxb_css_syntax_parser_declarations_push(parser, cb_declr, + block->next, declr_ctx, + LXB_CSS_SYNTAX_TOKEN_RC_BRACKET, + false, true); + if (declr_rule == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); } -static bool -lxb_css_syntax_parser_declarations_back(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, void *ctx) +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_block_qualified(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - lxb_css_syntax_rule_t *rules = parser->rules; + void *qualified_ctx; + lxb_css_syntax_rule_t *qualified; + const lxb_css_syntax_cb_block_t *block; + lxb_css_syntax_begin_qualified_rule_f cb; + const lxb_css_syntax_cb_qualified_rule_t *cb_qualified; - rules->state = rules->cbx.declarations->cb.state; + qualified_ctx = NULL; + block = rule->cbx.block; + cb = block->qualified_rule; + + rule->skip_consume = false; - return rules->state(parser, token, ctx); + cb_qualified = cb(parser, token, rule->context, &qualified_ctx); + if (cb_qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); + } + + qualified = lxb_css_syntax_parser_qualified_push(parser, cb_qualified, + block->next, qualified_ctx, + LXB_CSS_SYNTAX_TOKEN_SEMICOLON, + true); + if (qualified == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_MEMORY_ALLOCATION); + } + + return lxb_css_syntax_token_parser_do_phase_again(parser); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_block_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - if (rule->offset > token->offset) { - return token; + rule->phase = lxb_css_syntax_parser_block; + rule->state = rule->back_state; + rule->skip_consume = true; + + return token; +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_validate(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT + || !lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) + { + rule->phase = lxb_css_syntax_parser_declarations_drop; + rule->state = rule->cbx.cb->failed; + rule->begin = token->offset; + rule->context_old = rule->context; + rule->context = NULL; + rule->failed = true; + + parser->offset.value_end = 0; + + return lxb_css_syntax_token_parser_do_phase_again(parser); } - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; + return lxb_css_syntax_parser_declarations_begin(parser, token, rule); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_begin(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + void *declr_ctx; + lxb_css_syntax_declaration_name_f cb; - return &lxb_css_syntax_token_terminated; + declr_ctx = NULL; + cb = rule->cbx.declarations->name; + + rule->state = cb(parser, token, rule->context, &declr_ctx); + if (rule->state == NULL) { + return lxb_css_syntax_parser_failed(parser, + LXB_STATUS_ERROR_UNEXPECTED_DATA); } + rule->phase = lxb_css_syntax_parser_declarations_name; + rule->context_old = rule->context; + rule->context = declr_ctx; rule->skip_consume = false; + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_syntax_token_parser_do_phase_again(parser); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ /* 1. */ if (token->type == LXB_CSS_SYNTAX_TOKEN_WHITESPACE) { @@ -1049,8 +1402,6 @@ lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, return NULL; } - rule->u.declarations.name_end = token->offset; - lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1069,12 +1420,12 @@ lxb_css_syntax_parser_declarations_name(lxb_css_parser_t *parser, } } - rule->u.declarations.value_begin = token->offset; + rule->begin = token->offset; + parser->offset.value_end = 0; /* 4. */ rule->phase = lxb_css_syntax_parser_declarations_value; - rule->state = parser->block; return lxb_css_syntax_parser_declarations_value(parser, token, rule); } @@ -1085,7 +1436,7 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule) { bool imp; - uintptr_t before_important; + size_t offset; lxb_status_t status; if (rule->offset > token->offset) { @@ -1097,7 +1448,6 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; goto done; } @@ -1115,7 +1465,7 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, return token; } - before_important = token->offset; + parser->offset.value_end = token->offset; lxb_css_syntax_token_consume(parser->tkz); @@ -1128,7 +1478,7 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, if (token->type == LXB_CSS_SYNTAX_TOKEN_DELIM) { rule->important = true; - rule->u.declarations.before_important = before_important; + parser->offset.important_begin = token->offset; lxb_css_syntax_token_consume(parser->tkz); @@ -1138,6 +1488,10 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, if (token == NULL) { return lxb_css_syntax_parser_failed(parser, parser->tkz->status); } + + parser->offset.important_end = token->offset + + lxb_css_syntax_token_base(token)->length; + lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1155,6 +1509,10 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, } } } + else { + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } goto again; @@ -1162,17 +1520,20 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, if (rule->deep == 0) { rule->phase = lxb_css_syntax_parser_declarations_next; - rule->u.declarations.value_end = token->offset; + offset = token->offset; - lxb_css_syntax_token_consume(parser->tkz); + parser->offset.value_begin = rule->begin; + parser->offset.end = offset; - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); + if (parser->offset.value_end == 0) { + parser->offset.value_end = offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; } - return &lxb_css_syntax_token_terminated; + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_parser_token_end(parser, offset); } return token; @@ -1190,9 +1551,11 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, return token; } - rule->u.declarations.before_important = token->offset; rule->important = true; + parser->offset.value_end = token->offset; + parser->offset.important_begin = token->offset; + lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1200,6 +1563,9 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, return lxb_css_syntax_parser_failed(parser, parser->tkz->status); } + parser->offset.important_end = token->offset + + lxb_css_syntax_token_base(token)->length; + lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1262,177 +1628,304 @@ lxb_css_syntax_parser_declarations_value(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_declarations_end; - rule->skip_consume = true; + parser->offset.value_begin = rule->begin; + parser->offset.end = token->offset; + + if (parser->offset.value_end == 0) { + parser->offset.value_end = token->offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } - rule->u.declarations.value_end = token->offset; - rule->u.declarations.end = token->offset; + rule->phase = lxb_css_syntax_parser_declaration_end; + rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { + size_t offset; lxb_status_t status; - lxb_css_syntax_declarations_offset_t *decl; - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; + if (rule->offset > token->offset) { + return token; + } - return &lxb_css_syntax_token_terminated; + rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; + + if (rule->block_end == token->type && rule->deep == 0) { + goto done; + } + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: + if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_declarations_next; + + offset = token->offset; + + parser->offset.value_begin = rule->begin; + parser->offset.end = offset; + + if (parser->offset.value_end == 0) { + parser->offset.value_end = offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } + + lxb_css_syntax_token_consume(parser->tkz); + + return lxb_css_parser_token_end(parser, offset); + } + + return token; + + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + status = lxb_css_parser_types_push(parser, + LXB_CSS_SYNTAX_TOKEN_RS_BRACKET); + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + status = lxb_css_parser_types_push(parser, + LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + status = lxb_css_parser_types_push(parser, + LXB_CSS_SYNTAX_TOKEN_RC_BRACKET); + break; + + case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: + if (rule->deep == 0) { + if (rule->nested) { + goto done; + } + } + else if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + + return token; + + case LXB_CSS_SYNTAX_TOKEN_RS_BRACKET: + case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: + if (rule->deep != 0 && parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + + return token; + + case LXB_CSS_SYNTAX_TOKEN__EOF: + goto done; + + default: + return token; } - status = rule->cbx.declarations->declaration_end(parser, rule->context, - rule->important, - rule->failed); if (status != LXB_STATUS_OK) { return lxb_css_syntax_parser_failed(parser, status); } - rule->phase = lxb_css_syntax_parser_declarations; - rule->state = rule->cbx.cb->state; + rule->deep++; - rule->skip_consume = false; - rule->important = false; - rule->failed = false; + return token; + +done: + + parser->offset.value_begin = rule->begin; + parser->offset.end = token->offset; - decl = &rule->u.declarations; + if (parser->offset.value_end == 0) { + parser->offset.value_end = token->offset; + parser->offset.important_begin = 0; + parser->offset.important_end = 0; + } - decl->name_begin = 0; - decl->name_end = 0; - decl->value_begin = 0; - decl->before_important = 0; - decl->value_end = 0; + rule->phase = lxb_css_syntax_parser_declaration_end; + rule->skip_consume = true; - return lxb_css_syntax_parser_declarations(parser, token, rule); + return lxb_css_parser_token_end(parser, token->offset); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_drop(lxb_css_parser_t *parser, +lxb_css_syntax_parser_declarations_next(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule) { + void *out_rule; lxb_status_t status; + lxb_css_syntax_declaration_name_f name; - /* It is necessary to avoid re-entry of the token into the phase. */ + if (rule->state != lxb_css_state_success) { + rule->skip_consume = true; - if (rule->offset > token->offset) { - return token; + return lxb_css_parser_token_end(parser, token->offset); } - rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; - - if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; - goto done; + status = rule->cbx.declarations->end(parser, rule->context_old, + rule->context, token, &parser->offset, + rule->important, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - switch (token->type) { - case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: - if (rule->deep == 0) { - rule->phase = lxb_css_syntax_parser_declarations_next; +begin: + + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_SEMICOLON: + case LXB_CSS_SYNTAX_TOKEN_WHITESPACE: + lxb_css_syntax_token_consume(parser->tkz); + + token = lxb_css_syntax_token(parser->tkz); + if (token == NULL) { + return lxb_css_syntax_parser_failed(parser, + parser->tkz->status); + } + + goto begin; - rule->u.declarations.name_end = token->offset; + case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_declarations_end; + break; - lxb_css_syntax_token_consume(parser->tkz); + case LXB_CSS_SYNTAX_TOKEN_IDENT: + if (lxb_css_syntax_tokenizer_lookup_colon(parser->tkz)) { + out_rule = NULL; + name = rule->cbx.declarations->name; + rule->skip_consume = true; - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { + rule->state = name(parser, token, rule->context, &out_rule); + if (rule->state == NULL) { return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); + LXB_STATUS_ERROR_UNEXPECTED_DATA); } - rule->skip_consume = true; - - return &lxb_css_syntax_token_terminated; - } + rule->context = out_rule; - return token; + lxb_css_syntax_token_consume(parser->tkz); - case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RS_BRACKET); - break; + rule->phase = lxb_css_syntax_parser_declarations_name; + rule->context = out_rule; - case LXB_CSS_SYNTAX_TOKEN_FUNCTION: - case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); - break; + break; + } - case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RC_BRACKET); - break; + /* Fall through. */ - case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - case LXB_CSS_SYNTAX_TOKEN_RS_BRACKET: - case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - parser->types_pos--; - rule->deep--; + default: + if (rule->nested) { + rule->phase = lxb_css_syntax_parser_declarations_end; } + else { + rule->phase = lxb_css_syntax_parser_declarations_drop; + rule->state = rule->cbx.cb->failed; + rule->begin = token->offset; + rule->context = NULL; + rule->failed = true; - return token; - - case LXB_CSS_SYNTAX_TOKEN__EOF: - goto done; + parser->offset.value_end = 0; - default: - return token; - } + return lxb_css_syntax_token_parser_do_phase_again(parser); + } - if (status != LXB_STATUS_OK) { - return lxb_css_syntax_parser_failed(parser, status); + break; } - rule->deep++; - - return token; + rule->skip_consume = false; + rule->important = false; + rule->failed = false; -done: + return lxb_css_syntax_token_parser_do_phase_again(parser); +} - rule->phase = lxb_css_syntax_parser_declarations_end; - rule->skip_consume = true; +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_declarations_value; + rule->state = rule->back_state; + rule->skip_consume = false; - rule->u.declarations.name_end = token->offset; - rule->u.declarations.end = token->offset; + return token; +} - return &lxb_css_syntax_token_terminated; +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declaration_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + return lxb_css_syntax_parser_declaration_end_handler(parser, token, + rule, false); } static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_declaration_end_handler(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token) { lxb_status_t status; - lxb_css_syntax_rule_t *rules; if (rule->state != lxb_css_state_success) { rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } - status = rule->cbx.declarations->declaration_end(parser, rule->context, - rule->important, - rule->failed); + status = rule->cbx.declarations->end(parser, rule->context_old, + rule->context, token, &parser->offset, + rule->important, rule->failed); if (status != LXB_STATUS_OK) { return lxb_css_syntax_parser_failed(parser, status); } + return lxb_css_syntax_parser_declarations_end_h(parser, token, + rule, skip_token); +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + return lxb_css_syntax_parser_declarations_end_h(parser, token, + rule, false); +} + +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_declarations_end_h(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule, + bool skip_token) +{ + lxb_status_t status; + /* This code will be called exclusively from the lxb_css_parser_run(...). */ + rule->context = rule->context_old; + status = rule->cbx.cb->end(parser, token, rule->context, false); if (status != LXB_STATUS_OK) { return lxb_css_syntax_parser_failed(parser, status); } - if (!rule->skip_ending) { + if (skip_token) { lxb_css_syntax_token_consume(parser->tkz); token = lxb_css_syntax_token(parser->tkz); @@ -1442,18 +1935,7 @@ lxb_css_syntax_parser_declarations_end(lxb_css_parser_t *parser, } } - (void) lxb_css_syntax_parser_stack_pop(parser); - - rules = parser->rules; - - if (parser->rules <= parser->rules_begin) { - rules->state = lxb_css_state_stop; - return token; - } - - rules->phase = rules->back; - - return rules->phase(parser, token, rules); + return lxb_css_syntax_parser_call_back(parser, token); } static const lxb_css_syntax_token_t * @@ -1470,7 +1952,6 @@ lxb_css_syntax_parser_components(lxb_css_parser_t *parser, rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; if (rule->block_end == token->type && rule->deep == 0) { - rule->skip_ending = true; goto done; } @@ -1521,7 +2002,23 @@ lxb_css_syntax_parser_components(lxb_css_parser_t *parser, rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_components_back_to_value(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_components; + rule->state = rule->back_state; + rule->skip_consume = false; + + return token; } static const lxb_css_syntax_token_t * @@ -1555,16 +2052,16 @@ lxb_css_syntax_parser_function(lxb_css_parser_t *parser, break; case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: - if (rule->deep != 0) { - if (parser->types_pos[-1] == token->type) { - parser->types_pos--; - rule->deep--; - } - } - else { + if (rule->deep == 0) { + rule->phase = lxb_css_syntax_parser_end_consume_token; goto done; } + if (parser->types_pos[-1] == token->type) { + parser->types_pos--; + rule->deep--; + } + return token; case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: @@ -1577,6 +2074,7 @@ lxb_css_syntax_parser_function(lxb_css_parser_t *parser, return token; case LXB_CSS_SYNTAX_TOKEN__EOF: + rule->phase = lxb_css_syntax_parser_end; goto done; default: @@ -1593,77 +2091,25 @@ lxb_css_syntax_parser_function(lxb_css_parser_t *parser, done: - rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ static const lxb_css_syntax_token_t * -lxb_css_syntax_parser_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +lxb_css_syntax_parser_function_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - lxb_status_t status; - - if (rule->offset > token->offset) { - return token; - } - - rule->offset = token->offset + lxb_css_syntax_token_base(token)->length; - - if (rule->block_end == token->type && rule->deep == 0) { - goto done; - } - - switch (token->type) { - case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RS_BRACKET); - break; - - case LXB_CSS_SYNTAX_TOKEN_FUNCTION: - case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS); - break; - - case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: - status = lxb_css_parser_types_push(parser, - LXB_CSS_SYNTAX_TOKEN_RC_BRACKET); - break; - - case LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS: - case LXB_CSS_SYNTAX_TOKEN_RS_BRACKET: - case LXB_CSS_SYNTAX_TOKEN_RC_BRACKET: - if (rule->deep != 0 && parser->types_pos[-1] == token->type) { - parser->types_pos--; - rule->deep--; - } - - return token; - - case LXB_CSS_SYNTAX_TOKEN__EOF: - goto done; - - default: - return token; - } - - if (status != LXB_STATUS_OK) { - return lxb_css_syntax_parser_failed(parser, status); - } - - rule->deep++; + rule->phase = lxb_css_syntax_parser_function; + rule->state = rule->back_state; + rule->skip_consume = false; return token; - -done: - - rule->phase = lxb_css_syntax_parser_end; - rule->skip_consume = true; - - return &lxb_css_syntax_token_terminated; } static const lxb_css_syntax_token_t * @@ -1677,31 +2123,41 @@ lxb_css_syntax_parser_pipe(lxb_css_parser_t *parser, rule->phase = lxb_css_syntax_parser_end; rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + return lxb_css_parser_token_end(parser, token->offset); } return token; } -const lxb_css_syntax_token_t * -lxb_css_syntax_parser_start_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule) +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_pipe_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) { - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; - - return &lxb_css_syntax_token_terminated; - } - - /* This code will be called exclusively from the lxb_css_parser_run(...). */ - + rule->phase = lxb_css_syntax_parser_pipe; + rule->state = rule->back_state; rule->skip_consume = false; - rule->phase = rule->back; - rule->state = parser->block; + return token; +} + +/* + * This code will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ +static const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_back(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + rule->phase = lxb_css_syntax_parser_end; + rule->state = lxb_css_state_blank; - return rule->back(parser, token, rule); + return token; } const lxb_css_syntax_token_t * @@ -1710,13 +2166,12 @@ lxb_css_syntax_parser_end(lxb_css_parser_t *parser, lxb_css_syntax_rule_t *rule) { lxb_status_t status; - lxb_css_syntax_rule_t *rules; lxb_css_syntax_cb_base_t *base; - if (rule->state != lxb_css_state_success) { - rule->skip_consume = true; + rule->skip_consume = true; - return &lxb_css_syntax_token_terminated; + if (rule->state != lxb_css_state_success) { + return lxb_css_parser_token_end(parser, token->offset); } /* This code will be called exclusively from the lxb_css_parser_run(...). */ @@ -1728,27 +2183,43 @@ lxb_css_syntax_parser_end(lxb_css_parser_t *parser, return lxb_css_syntax_parser_failed(parser, status); } - if (!rule->skip_ending) { - lxb_css_syntax_token_consume(parser->tkz); + rule->skip_consume = false; - token = lxb_css_syntax_token(parser->tkz); - if (token == NULL) { - return lxb_css_syntax_parser_failed(parser, - parser->tkz->status); - } + return lxb_css_syntax_parser_call_back(parser, token); +} + +const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_consume_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule) +{ + lxb_status_t status; + lxb_css_syntax_cb_base_t *base; + + rule->skip_consume = true; + + if (rule->state != lxb_css_state_success) { + return lxb_css_parser_token_end(parser, token->offset); } - (void) lxb_css_syntax_parser_stack_pop(parser); + /* This code will be called exclusively from the lxb_css_parser_run(...). */ - rules = parser->rules; + base = rule->cbx.user; - if (parser->rules <= parser->rules_begin) { - rules->state = lxb_css_state_stop; - return token; + status = base->end(parser, token, rule->context, rule->failed); + if (status != LXB_STATUS_OK) { + return lxb_css_syntax_parser_failed(parser, status); } - rules->phase = rules->back; - rules->state = rule->state_back; + rule->skip_consume = false; + + lxb_css_syntax_token_consume(parser->tkz); + + token = lxb_css_syntax_token(parser->tkz); + if (token == NULL) { + return lxb_css_syntax_parser_failed(parser, + parser->tkz->status); + } - return rules->phase(parser, token, rules); + return lxb_css_syntax_parser_call_back(parser, token); } diff --git a/ext/lexbor/lexbor/css/syntax/parser.h b/ext/lexbor/lexbor/css/syntax/parser.h index f41d62f1ff87..2e7aff644509 100644 --- a/ext/lexbor/lexbor/css/syntax/parser.h +++ b/ext/lexbor/lexbor/css/syntax/parser.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2025 Alexander Borisov + * Copyright (C) 2020-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -30,70 +30,63 @@ lxb_css_syntax_parser_consume(lxb_css_parser_t *parser); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_list_rules_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_list_rules_t *list_rules, - void *ctx, bool top_level, - lxb_css_syntax_token_type_t stop); + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_at_rule_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_at_rule_t *at_rule, - void *ctx, lxb_css_syntax_token_type_t stop); + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop, + bool nested); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_qualified_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_qualified_rule_t *qualified, - void *ctx, lxb_css_syntax_token_type_t stop); + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop, + bool nested); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_declarations_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_declarations_t *declarations, - void *ctx, lxb_css_syntax_token_type_t stop); + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop, + bool name_validate, bool nested); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_components_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, void *ctx, lxb_css_syntax_token_type_t stop); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_function_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_function_t *func, - void *ctx); - -LXB_API lxb_css_syntax_rule_t * -lxb_css_syntax_parser_block_push(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_parser_state_f state_back, - const lxb_css_syntax_cb_block_t *block, - void *ctx); + lxb_css_parser_state_f back, void *ctx); LXB_API lxb_css_syntax_rule_t * lxb_css_syntax_parser_pipe_push(lxb_css_parser_t *parser, - lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_pipe_t *pipe, - void *ctx, lxb_css_syntax_token_type_t stop); - -LXB_API const lxb_css_syntax_token_t * -lxb_css_syntax_parser_start_block(lxb_css_parser_t *parser, - const lxb_css_syntax_token_t *token, - lxb_css_syntax_rule_t *rule); + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop); LXB_API const lxb_css_syntax_token_t * lxb_css_syntax_parser_end(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); +LXB_API const lxb_css_syntax_token_t * +lxb_css_syntax_parser_end_consume_token(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_rule_t *rule); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/css/syntax/res.h b/ext/lexbor/lexbor/css/syntax/res.h index cd33446f81d5..7fa2f8ba705f 100644 --- a/ext/lexbor/lexbor/css/syntax/res.h +++ b/ext/lexbor/lexbor/css/syntax/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,12 +7,9 @@ #ifndef LEXBOR_CSS_SYNTAX_RES_H #define LEXBOR_CSS_SYNTAX_RES_H -#ifdef LXB_CSS_SYNTAX_RES_NAME_MAP -#ifndef LXB_CSS_SYNTAX_RES_NAME_MAP_ENABLED -#define LXB_CSS_SYNTAX_RES_NAME_MAP_ENABLED #define LXB_CSS_SYNTAX_RES_NAME_START 0x01 -static const lxb_char_t lxb_css_syntax_res_name_map[256] = +LXB_API const lxb_char_t lxb_css_syntax_res_name_map[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -42,7 +39,4 @@ static const lxb_char_t lxb_css_syntax_res_name_map[256] = 0x01, 0x01, 0x01, 0x01, 0x01 }; -#endif /* LXB_CSS_SYNTAX_RES_NAME_MAP_ENABLED */ -#endif /* LXB_CSS_SYNTAX_RES_NAME_MAP */ - #endif /* LEXBOR_CSS_SYNTAX_RES_H */ diff --git a/ext/lexbor/lexbor/css/syntax/state.c b/ext/lexbor/lexbor/css/syntax/state.c index 99cd30c1868f..a93731e11235 100644 --- a/ext/lexbor/lexbor/css/syntax/state.c +++ b/ext/lexbor/lexbor/css/syntax/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,12 +14,11 @@ #include "lexbor/css/syntax/syntax.h" #include "lexbor/css/syntax/tokenizer/error.h" -#define LXB_CSS_SYNTAX_RES_NAME_MAP #include "lexbor/css/syntax/res.h" -#define LEXBOR_STR_RES_MAP_HEX -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif #define LXB_CSS_SYNTAX_ERROR_CODEPOINT 0x1FFFFF @@ -1101,7 +1100,9 @@ lxb_css_syntax_state_consume_numeric(lxb_css_syntax_tokenizer_t *tkz, /* U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) */ do { - e_digit = (*data - 0x30) + e_digit * 0x0A; + if (e_digit < INT_MAX / 10) { + e_digit = (*data - 0x30) + e_digit * 0x0A; + } data += 1; @@ -1523,7 +1524,7 @@ lxb_css_syntax_state_url(lxb_css_syntax_tokenizer_t *tkz, lxb_css_syntax_tokenizer_error_add(tkz->parse_errors, data, LXB_CSS_SYNTAX_TOKENIZER_ERROR_EOINUR); - return lxb_css_syntax_state_string_set(tkz, token, data); + goto done; default: if (*data >= 0x80) { diff --git a/ext/lexbor/lexbor/css/syntax/state_res.h b/ext/lexbor/lexbor/css/syntax/state_res.h index 2f6e2899fdc0..e98909a5bff4 100644 --- a/ext/lexbor/lexbor/css/syntax/state_res.h +++ b/ext/lexbor/lexbor/css/syntax/state_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/syntax/syntax.c b/ext/lexbor/lexbor/css/syntax/syntax.c index b148d8a043c1..f8a1e944df23 100644 --- a/ext/lexbor/lexbor/css/syntax/syntax.c +++ b/ext/lexbor/lexbor/css/syntax/syntax.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -9,58 +9,315 @@ #include "lexbor/core/str.h" -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_HEX_TO_CHAR_LOWERCASE -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE_LOWERCASE -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex_to_char_lowercase[17]; + LXB_EXTERN const char *lexbor_str_res_char_to_two_hex_value_lowercase[257]; + LXB_EXTERN const lxb_char_t lxb_css_syntax_res_name_map[256]; +#endif -#define LXB_CSS_SYNTAX_RES_NAME_MAP -#include "lexbor/css/syntax/res.h" +static const lexbor_str_t lxb_css_syntax_str_ws = lexbor_str(" "); -static const lexbor_str_t lxb_str_ws = lexbor_str(" "); - - -lxb_status_t +lxb_css_rule_list_t * lxb_css_syntax_parse_list_rules(lxb_css_parser_t *parser, const lxb_css_syntax_cb_list_rules_t *cb, - const lxb_char_t *data, size_t length, - void *ctx, bool top_level) + const lxb_char_t *data, size_t length) { - lxb_status_t status; + lxb_css_rule_list_t *list; lxb_css_syntax_rule_t *rule; if (lxb_css_parser_is_running(parser)) { parser->status = LXB_STATUS_ERROR_WRONG_STAGE; - return parser->status; + return NULL; } lxb_css_parser_clean(parser); - lxb_css_parser_buffer_set(parser, data, length); - rule = lxb_css_syntax_parser_list_rules_push(parser, NULL, NULL, cb, - ctx, top_level, + list = lxb_css_rule_list_create(parser->memory); + if (list == NULL) { + parser->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + goto failed; + } + + rule = lxb_css_syntax_parser_list_rules_push(parser, cb, NULL, list, LXB_CSS_SYNTAX_TOKEN_UNDEF); if (rule == NULL) { - status = parser->status; - goto end; + goto failed; + } + + parser->tkz->with_comment = false; + parser->stage = LXB_CSS_PARSER_RUN; + + parser->status = lxb_css_syntax_parser_run(parser); + if (parser->status != LXB_STATUS_OK) { + goto failed; + } + + parser->stage = LXB_CSS_PARSER_END; + + return list; + +failed: + + if (list != NULL) { + lxb_css_rule_list_destroy(list, true); + } + + parser->stage = LXB_CSS_PARSER_END; + + return NULL; +} + +lxb_css_rule_declaration_list_t * +lxb_css_syntax_parse_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_declarations_t *cb, + const lxb_char_t *data, size_t length) +{ + lxb_css_rule_declaration_list_t *list; + lxb_css_syntax_rule_t *rule; + + if (lxb_css_parser_is_running(parser)) { + parser->status = LXB_STATUS_ERROR_WRONG_STAGE; + return NULL; + } + + lxb_css_parser_clean(parser); + lxb_css_parser_buffer_set(parser, data, length); + + list = lxb_css_rule_declaration_list_create(parser->memory); + if (list == NULL) { + parser->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + goto failed; + } + + rule = lxb_css_syntax_parser_declarations_push(parser, cb, NULL, list, + LXB_CSS_SYNTAX_TOKEN_UNDEF, + true, false); + if (rule == NULL) { + goto failed; } parser->tkz->with_comment = false; parser->stage = LXB_CSS_PARSER_RUN; - status = lxb_css_syntax_parser_run(parser); - if (status != LXB_STATUS_OK) { - /* Destroy StyleSheet. */ + parser->status = lxb_css_syntax_parser_run(parser); + if (parser->status != LXB_STATUS_OK) { + goto failed; } -end: + parser->stage = LXB_CSS_PARSER_END; + + return list; + +failed: + + if (list != NULL) { + lxb_css_rule_declaration_list_destroy(list, true); + } parser->stage = LXB_CSS_PARSER_END; - return status; + return NULL; +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_list_rules(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_list_rules_t *list_rules, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + return lxb_css_syntax_parser_list_rules_push(parser, list_rules, back, + ctx, stop); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_at_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_at_rule_t *at_rule, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_AT_KEYWORD) { + return NULL; + } + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0 + && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) + { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_syntax_parser_at_rule_push(parser, at_rule, back, ctx, + stop, false); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_qualified_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_qualified_rule_t *qualified, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + lxb_css_syntax_token_type_t type; + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0) { + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + type = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; + break; + + default: + type = LXB_CSS_SYNTAX_TOKEN_UNDEF; + break; + } + + + if (parser->types_pos[-1] == type) { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + } + + return lxb_css_syntax_parser_qualified_push(parser, qualified, back, + ctx, stop, false); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_LC_BRACKET) { + return NULL; + } + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0 + && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_RC_BRACKET) + { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_syntax_parser_block_push(parser, block, back, ctx); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop) +{ + lxb_css_syntax_token_type_t type; + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0) { + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + type = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; + break; + + default: + type = LXB_CSS_SYNTAX_TOKEN_UNDEF; + break; + } + + + if (parser->types_pos[-1] == type) { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + } + + return lxb_css_syntax_parser_declarations_push(parser, declr, back, + ctx, stop, true, false); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_components(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop) +{ + lxb_css_syntax_token_type_t type; + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0) { + switch (token->type) { + case LXB_CSS_SYNTAX_TOKEN_LS_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RS_BRACKET; + break; + + case LXB_CSS_SYNTAX_TOKEN_FUNCTION: + case LXB_CSS_SYNTAX_TOKEN_L_PARENTHESIS: + type = LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS; + break; + + case LXB_CSS_SYNTAX_TOKEN_LC_BRACKET: + type = LXB_CSS_SYNTAX_TOKEN_RC_BRACKET; + break; + + default: + type = LXB_CSS_SYNTAX_TOKEN_UNDEF; + break; + } + + + if (parser->types_pos[-1] == type) { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + } + + return lxb_css_syntax_parser_components_push(parser, comp, back, ctx, stop); +} + +lxb_css_syntax_rule_t * +lxb_css_syntax_consume_function(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_function_t *func, + lxb_css_parser_state_f back, void *ctx) +{ + if (token->type != LXB_CSS_SYNTAX_TOKEN_FUNCTION) { + return NULL; + } + + if (parser->rules > parser->rules_begin && parser->rules->deep != 0 + && parser->types_pos[-1] == LXB_CSS_SYNTAX_TOKEN_R_PARENTHESIS) + { + parser->types_pos -= 1; + parser->rules->deep -= 1; + } + + lxb_css_syntax_parser_consume(parser); + + return lxb_css_syntax_parser_function_push(parser, func, back, ctx); } lxb_status_t @@ -69,22 +326,20 @@ lxb_css_syntax_stack_expand(lxb_css_parser_t *parser, size_t count) size_t length, cur_len, size; lxb_css_syntax_rule_t *p; - if ((parser->rules + count) >= parser->rules_end) { - cur_len = parser->rules - parser->rules_begin; + cur_len = parser->rules - parser->rules_begin; - length = cur_len + count + 1024; - size = length * sizeof(lxb_css_syntax_rule_t); + length = cur_len + count + 1024; + size = length * sizeof(lxb_css_syntax_rule_t); - p = lexbor_realloc(parser->rules_begin, size); - if (p == NULL) { - return LXB_STATUS_ERROR_MEMORY_ALLOCATION; - } - - parser->rules_begin = p; - parser->rules_end = p + length; - parser->rules = p + cur_len; + p = lexbor_realloc(parser->rules_begin, size); + if (p == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; } + parser->rules_begin = p; + parser->rules_end = p + length; + parser->rules = p + cur_len; + return LXB_STATUS_OK; } @@ -166,8 +421,9 @@ lxb_css_syntax_ident_serialize(const lxb_char_t *data, size_t length, data = ++p; if (p < end && lexbor_str_res_map_hex[*p] != 0xff) { - lexbor_serialize_write(cb, lxb_str_ws.data, - lxb_str_ws.length, ctx, status); + lexbor_serialize_write(cb, lxb_css_syntax_str_ws.data, + lxb_css_syntax_str_ws.length, + ctx, status); } continue; @@ -231,8 +487,9 @@ lxb_css_syntax_string_serialize(const lxb_char_t *data, size_t length, p++; if (p < end && lexbor_str_res_map_hex[*p] != 0xff) { - lexbor_serialize_write(cb, lxb_str_ws.data, - lxb_str_ws.length, ctx, status); + lexbor_serialize_write(cb, lxb_css_syntax_str_ws.data, + lxb_css_syntax_str_ws.length, + ctx, status); } data = p; diff --git a/ext/lexbor/lexbor/css/syntax/syntax.h b/ext/lexbor/lexbor/css/syntax/syntax.h index 91ed9088f29a..08e9c5c8618d 100644 --- a/ext/lexbor/lexbor/css/syntax/syntax.h +++ b/ext/lexbor/lexbor/css/syntax/syntax.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Alexander Borisov + * Copyright (C) 2022-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,6 +12,7 @@ extern "C" { #endif #include "lexbor/css/syntax/tokenizer.h" +#include "lexbor/css/syntax/tokenizer.h" typedef struct lxb_css_syntax_rule lxb_css_syntax_rule_t; @@ -21,124 +22,211 @@ typedef const lxb_css_syntax_token_t * const lxb_css_syntax_token_t *token, lxb_css_syntax_rule_t *rule); -typedef lxb_status_t -(*lxb_css_syntax_declaration_end_f)(lxb_css_parser_t *parser, void *ctx, - bool important, bool failed); + +typedef struct lxb_css_syntax_cb_base lxb_css_syntax_cb_base_t; +typedef struct lxb_css_syntax_cb_list_rules lxb_css_syntax_cb_list_rules_t; +typedef struct lxb_css_syntax_cb_at_rule lxb_css_syntax_cb_at_rule_t; +typedef struct lxb_css_syntax_cb_qualified_rule lxb_css_syntax_cb_qualified_rule_t; +typedef struct lxb_css_syntax_cb_block lxb_css_syntax_cb_block_t; +typedef struct lxb_css_syntax_cb_declarations lxb_css_syntax_cb_declarations_t; +typedef struct lxb_css_syntax_cb_function lxb_css_syntax_cb_function_t; +typedef struct lxb_css_syntax_cb_components lxb_css_syntax_cb_components_t; +typedef struct lxb_css_syntax_cb_pipe lxb_css_syntax_cb_pipe_t; + +typedef struct lxb_css_syntax_declaration_offset lxb_css_syntax_declaration_offset_t; typedef lxb_status_t (*lxb_css_syntax_cb_done_f)(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx, bool failed); -typedef struct { - uintptr_t begin; - uintptr_t end; -} -lxb_css_syntax_list_rules_offset_t; - -typedef struct { - uintptr_t name; - uintptr_t prelude; - uintptr_t prelude_end; - uintptr_t block; - uintptr_t block_end; -} -lxb_css_syntax_at_rule_offset_t; - -typedef struct { - uintptr_t prelude; - uintptr_t prelude_end; - uintptr_t block; - uintptr_t block_end; -} -lxb_css_syntax_qualified_offset_t; - -typedef struct { - uintptr_t begin; - uintptr_t end; - uintptr_t name_begin; - uintptr_t name_end; - uintptr_t value_begin; - uintptr_t before_important; - uintptr_t value_end; -} -lxb_css_syntax_declarations_offset_t; - -typedef struct { - lxb_css_parser_state_f state; - lxb_css_parser_state_f block; +typedef const lxb_css_syntax_cb_at_rule_t * +(*lxb_css_syntax_begin_at_rule_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +typedef const lxb_css_syntax_cb_qualified_rule_t * +(*lxb_css_syntax_begin_qualified_rule_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +typedef const lxb_css_syntax_cb_block_t * +(*lxb_css_syntax_begin_block_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); + +typedef const lxb_css_syntax_cb_declarations_t * +(*lxb_css_syntax_begin_declarations_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +typedef lxb_css_parser_state_f +(*lxb_css_syntax_declaration_name_f)(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + void *ctx, void **out_rule); +typedef lxb_status_t +(*lxb_css_syntax_declaration_end_f)(lxb_css_parser_t *parser, + void *declaration, void *ctx, + const lxb_css_syntax_token_t *token, + lxb_css_syntax_declaration_offset_t *offset, + bool important, bool failed); + +struct lxb_css_syntax_cb_base { lxb_css_parser_state_f failed; lxb_css_syntax_cb_done_f end; -} -lxb_css_syntax_cb_base_t; +}; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_pipe_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_block_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_function_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_components_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_at_rule_t; -typedef lxb_css_syntax_cb_base_t lxb_css_syntax_cb_qualified_rule_t; +struct lxb_css_syntax_cb_list_rules { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f next; + lxb_css_syntax_begin_at_rule_f at_rule; + lxb_css_syntax_begin_qualified_rule_f qualified_rule; +}; + +struct lxb_css_syntax_cb_at_rule { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; + lxb_css_syntax_cb_done_f prelude_end; + lxb_css_syntax_begin_block_f block; +}; + +struct lxb_css_syntax_cb_qualified_rule { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; + lxb_css_syntax_cb_done_f prelude_end; + lxb_css_syntax_begin_block_f block; +}; + +struct lxb_css_syntax_cb_block { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f next; + lxb_css_syntax_begin_at_rule_f at_rule; + lxb_css_syntax_begin_declarations_f declarations; + lxb_css_syntax_begin_qualified_rule_f qualified_rule; +}; -typedef struct { +struct lxb_css_syntax_cb_declarations { lxb_css_syntax_cb_base_t cb; - lxb_css_syntax_declaration_end_f declaration_end; - const lxb_css_syntax_cb_at_rule_t *at_rule; -} -lxb_css_syntax_cb_declarations_t; - -typedef struct { - lxb_css_syntax_cb_base_t cb; - lxb_css_parser_state_f next; - const lxb_css_syntax_cb_at_rule_t *at_rule; - const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; -} -lxb_css_syntax_cb_list_rules_t; + lxb_css_syntax_declaration_name_f name; + lxb_css_syntax_declaration_end_f end; +}; + +struct lxb_css_syntax_cb_function { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f value; +}; + +struct lxb_css_syntax_cb_components { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; +}; + +struct lxb_css_syntax_cb_pipe { + lxb_css_syntax_cb_base_t cb; + lxb_css_parser_state_f prelude; +}; + +struct lxb_css_syntax_declaration_offset { + size_t value_begin; + size_t value_end; + size_t important_begin; + size_t important_end; + size_t end; +}; struct lxb_css_syntax_rule { lxb_css_syntax_state_f phase; lxb_css_parser_state_f state; - lxb_css_parser_state_f state_back; + + /* + * This callback will be called before rule->state is called. + * Exclusively from the lxb_css_parser_run(...). + */ lxb_css_syntax_state_f back; + lxb_css_parser_state_f back_state; + void *context; + void *context_old; + void *returned; union { const lxb_css_syntax_cb_base_t *cb; const lxb_css_syntax_cb_list_rules_t *list_rules; const lxb_css_syntax_cb_at_rule_t *at_rule; const lxb_css_syntax_cb_qualified_rule_t *qualified_rule; - const lxb_css_syntax_cb_declarations_t *declarations; const lxb_css_syntax_cb_components_t *components; + const lxb_css_syntax_cb_declarations_t *declarations; const lxb_css_syntax_cb_function_t *func; const lxb_css_syntax_cb_block_t *block; const lxb_css_syntax_cb_pipe_t *pipe; void *user; } cbx; - void *context; - - uintptr_t offset; - size_t deep; - lxb_css_syntax_token_type_t block_end; - bool skip_ending; - bool skip_consume; - bool important; - bool failed; - bool top_level; - - union { - lxb_css_syntax_list_rules_offset_t list_rules; - lxb_css_syntax_at_rule_offset_t at_rule; - lxb_css_syntax_qualified_offset_t qualified; - lxb_css_syntax_declarations_offset_t declarations; - void *user; - } u; + size_t offset; + size_t deep; + size_t begin; + lxb_css_syntax_token_type_t block_end; + bool nested; + bool skip_consume; + bool important; + bool failed; }; -LXB_API lxb_status_t +LXB_API lxb_css_rule_list_t * lxb_css_syntax_parse_list_rules(lxb_css_parser_t *parser, const lxb_css_syntax_cb_list_rules_t *cb, - const lxb_char_t *data, size_t length, - void *ctx, bool top_level); + const lxb_char_t *data, size_t length); + +LXB_API lxb_css_rule_declaration_list_t * +lxb_css_syntax_parse_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_declarations_t *cb, + const lxb_char_t *data, size_t length); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_list_rules(lxb_css_parser_t *parser, + const lxb_css_syntax_cb_list_rules_t *list_rules, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_at_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_at_rule_t *at_rule, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_qualified_rule(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_qualified_rule_t *qualified, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_block(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_block_t *block, + lxb_css_parser_state_f back, void *ctx); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_declarations(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_declarations_t *declr, + lxb_css_parser_state_f back, void *ctx, + lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_components(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_components_t *comp, + lxb_css_parser_state_f back, + void *ctx, lxb_css_syntax_token_type_t stop); + +LXB_API lxb_css_syntax_rule_t * +lxb_css_syntax_consume_function(lxb_css_parser_t *parser, + const lxb_css_syntax_token_t *token, + const lxb_css_syntax_cb_function_t *func, + lxb_css_parser_state_f back, void *ctx); + LXB_API lxb_status_t lxb_css_syntax_stack_expand(lxb_css_parser_t *parser, size_t count); @@ -159,6 +247,7 @@ LXB_API lxb_status_t lxb_css_syntax_ident_or_string_serialize(const lxb_char_t *data, size_t length, lexbor_serialize_cb_f cb, void *ctx); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/ext/lexbor/lexbor/css/syntax/token.c b/ext/lexbor/lexbor/css/syntax/token.c index be1cc7809c43..ff53c4531e8b 100644 --- a/ext/lexbor/lexbor/css/syntax/token.c +++ b/ext/lexbor/lexbor/css/syntax/token.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,15 +12,12 @@ #include "lexbor/css/parser.h" #include "lexbor/css/syntax/token.h" #include "lexbor/css/syntax/state.h" -#include "lexbor/css/syntax/state_res.h" - -#define LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP #include "lexbor/css/syntax/token_res.h" -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif lxb_css_syntax_token_t * lxb_css_syntax_tokenizer_token(lxb_css_syntax_tokenizer_t *tkz); diff --git a/ext/lexbor/lexbor/css/syntax/token_res.h b/ext/lexbor/lexbor/css/syntax/token_res.h index 7a8e1c4d2594..d5ee29cf3b22 100644 --- a/ext/lexbor/lexbor/css/syntax/token_res.h +++ b/ext/lexbor/lexbor/css/syntax/token_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,6 @@ #ifndef LEXBOR_CSS_SYNTAX_TOKEN_RES_H #define LEXBOR_CSS_SYNTAX_TOKEN_RES_H - -#ifdef LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP -#ifndef LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP_ENABLED -#define LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP_ENABLED static const lexbor_shs_entry_t lxb_css_syntax_token_res_name_shs_map[136] = { {NULL, NULL, 135, 0}, {NULL, NULL, 0, 0}, @@ -83,8 +79,4 @@ static const lexbor_shs_entry_t lxb_css_syntax_token_res_name_shs_map[136] = {NULL, NULL, 0, 0}, {"semicolon", (void *) LXB_CSS_SYNTAX_TOKEN_SEMICOLON, 9, 0} }; -#endif /* LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP_ENABLED */ -#endif /* LXB_CSS_SYNTAX_TOKEN_RES_NAME_SHS_MAP */ - - #endif /* LEXBOR_CSS_SYNTAX_TOKEN_RES_H */ diff --git a/ext/lexbor/lexbor/css/syntax/tokenizer.c b/ext/lexbor/lexbor/css/syntax/tokenizer.c index 9eecac657546..a44b2c7194a6 100644 --- a/ext/lexbor/lexbor/css/syntax/tokenizer.c +++ b/ext/lexbor/lexbor/css/syntax/tokenizer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,9 +12,10 @@ #include "lexbor/core/array.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; +#endif static const lxb_char_t lxb_css_syntax_tokenizer_important[] = "important"; @@ -297,7 +298,7 @@ lxb_css_syntax_tokenizer_lookup_important_ch(lxb_css_syntax_tokenizer_t *tkz, { static const size_t length = sizeof(lxb_css_syntax_tokenizer_important) - 1; - if (!(end - p >= length + if (!(lxb_size(end - p) >= length && lexbor_str_data_ncasecmp(p, lxb_css_syntax_tokenizer_important, length))) { diff --git a/ext/lexbor/lexbor/css/unit.c b/ext/lexbor/lexbor/css/unit.c new file mode 100644 index 000000000000..f3cc9c8ef28e --- /dev/null +++ b/ext/lexbor/lexbor/css/unit.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2021 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/unit/res.h" + + +const lxb_css_data_t * +lxb_css_unit_absolute_relative_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_absolute_relative_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_absolute_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_absolute_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_relative_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_relative_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_angle_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_angle_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_frequency_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_frequency_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_resolution_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_resolution_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_duration_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_unit_duration_shs, + name, length); + if (entry == NULL) { + return NULL; + } + + return entry->value; +} + +const lxb_css_data_t * +lxb_css_unit_by_id(lxb_css_type_t id) +{ + return &lxb_css_unit_data[id]; +} diff --git a/ext/lexbor/lexbor/css/unit/const.h b/ext/lexbor/lexbor/css/unit/const.h index 9b7ba1c311b1..9f5e515834e8 100644 --- a/ext/lexbor/lexbor/css/unit/const.h +++ b/ext/lexbor/lexbor/css/unit/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/unit/res.h b/ext/lexbor/lexbor/css/unit/res.h index 4cca189b6f45..ac24503d1a6f 100644 --- a/ext/lexbor/lexbor/css/unit/res.h +++ b/ext/lexbor/lexbor/css/unit/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/value.c b/ext/lexbor/lexbor/css/value.c new file mode 100644 index 000000000000..23e2472d625c --- /dev/null +++ b/ext/lexbor/lexbor/css/value.c @@ -0,0 +1,678 @@ +/* + * Copyright (C) 2022-2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/css/css.h" +#include "lexbor/css/value/res.h" + +#include "lexbor/core/serialize.h" +#include "lexbor/core/conv.h" + + +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex_to_char_lowercase[17]; + LXB_EXTERN const char *lexbor_str_res_char_to_two_hex_value_lowercase[257]; +#endif + +static const lexbor_str_t lxb_css_value_str_ws = lexbor_str(" "); +static const lexbor_str_t lxb_str_comma = lexbor_str(", "); +static const lexbor_str_t lxb_str_alpha = lexbor_str(" / "); +static const lexbor_str_t lxb_str_rp = lexbor_str(")"); + + +const lxb_css_data_t * +lxb_css_value_by_id(uintptr_t id) +{ + if (id < LXB_CSS_VALUE__LAST_ENTRY) { + return &lxb_css_value_data[id]; + } + + return NULL; +} + +lxb_css_value_type_t +lxb_css_value_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + entry = lexbor_shs_entry_get_lower_static(lxb_css_value_shs, name, length); + if (entry == NULL) { + return LXB_CSS_VALUE__UNDEF; + } + + return (lxb_css_value_type_t) (uintptr_t) entry->value; +} + +lxb_status_t +lxb_css_value_serialize(lxb_css_value_type_t type, + lexbor_serialize_cb_f cb, void *ctx) +{ + const lxb_css_data_t *data; + + if (type >= LXB_CSS_VALUE__LAST_ENTRY) { + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + data = &lxb_css_value_data[type]; + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_value_percentage_sr(const lxb_css_value_percentage_t *percent, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + + static const lexbor_str_t str_per = lexbor_str("%"); + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(percent->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + lexbor_serialize_write(cb, str_per.data, str_per.length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_sr(const lxb_css_value_length_t *len, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + const lxb_css_data_t *unit; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(len->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + if (len->unit == LXB_CSS_UNIT__UNDEF) { + return LXB_STATUS_OK; + } + + unit = lxb_css_unit_by_id(len->unit); + if (unit == NULL) { + return LXB_STATUS_OK; + } + + lexbor_serialize_write(cb, unit->name, unit->length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_sr(const lxb_css_value_number_t *number, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(number->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_integer_sr(const lxb_css_value_integer_t *integer, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_long_to_data(integer->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_percentage_sr(const lxb_css_value_length_percentage_t *lp, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (lp->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(&lp->u.length, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&lp->u.percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(lp->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_length_sr(const lxb_css_value_number_length_t *nl, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (nl->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(&nl->u.length, cb, ctx); + + default: + return lxb_css_value_serialize(nl->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_percentage_sr(const lxb_css_value_number_percentage_t *np, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (np->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&np->u.number, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&np->u.percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(np->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_type_sr(const lxb_css_value_length_type_t *lt, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (lt->type) { + case LXB_CSS_VALUE__LENGTH: + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_length_sr(<->length, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(lt->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_percentage_type_sr(const lxb_css_value_percentage_type_t *pt, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (pt->type) { + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&pt->percentage, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(pt->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_type_sr(const lxb_css_value_number_type_t *num, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (num->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&num->number, cb, ctx); + + default: + return lxb_css_value_serialize(num->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_integer_type_sr(const lxb_css_value_integer_type_t *num, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (num->type) { + case LXB_CSS_VALUE__INTEGER: + return lxb_css_value_integer_sr(&num->integer, cb, ctx); + + default: + return lxb_css_value_serialize(num->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_length_percentage_type_sr(const lxb_css_value_length_percentage_type_t *lpt, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (lpt->type) { + case LXB_CSS_VALUE__LENGTH: + return lxb_css_value_length_percentage_sr(&lpt->length, cb, ctx); + + default: + return lxb_css_value_serialize(lpt->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_number_length_percentage_type_sr(const lxb_css_value_number_length_percentage_t *nlp, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (nlp->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&nlp->u.number, cb, ctx); + + case LXB_CSS_VALUE__LENGTH: + return lxb_css_value_length_sr(&nlp->u.length, cb, ctx); + + case LXB_CSS_VALUE__PERCENTAGE: + return lxb_css_value_percentage_sr(&nlp->u.percentage, cb, ctx); + + default: + return lxb_css_value_serialize(nlp->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +lxb_status_t +lxb_css_value_angle_sr(const lxb_css_value_angle_t *angle, + lexbor_serialize_cb_f cb, void *ctx) +{ + size_t length; + lxb_char_t buf[128]; + lxb_status_t status; + const lxb_css_data_t *data; + + /* FIXME: If length != sizeof(buf)? */ + length = lexbor_conv_float_to_data(angle->num, buf, sizeof(buf)); + + lexbor_serialize_write(cb, buf, length, ctx, status); + + data = lxb_css_unit_by_id(angle->unit); + + return cb(data->name, data->length, ctx); +} + +lxb_status_t +lxb_css_value_hue_sr(const lxb_css_value_hue_t *hue, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (hue->type) { + case LXB_CSS_VALUE__NUMBER: + return lxb_css_value_number_sr(&hue->u.number, cb, ctx); + + case LXB_CSS_VALUE__ANGLE: + return lxb_css_value_angle_sr(&hue->u.angle, cb, ctx); + + case LXB_CSS_VALUE__UNDEF: + /* FIXME: ???? */ + break; + + default: + return lxb_css_value_serialize(hue->type, cb, ctx); + } + + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_value_color_hex_sr(const lxb_css_value_color_hex_t *hex, + lexbor_serialize_cb_f cb, void *ctx) +{ + lxb_status_t status; + static const lexbor_str_t str_hash = lexbor_str("#"); + const lxb_css_value_color_hex_rgba_t *rgba = &hex->rgba; + + const lxb_char_t *hmo = lexbor_str_res_map_hex_to_char_lowercase; + const char **hmt = lexbor_str_res_char_to_two_hex_value_lowercase; + + lexbor_serialize_write(cb, str_hash.data, str_hash.length, ctx, status); + + switch (hex->type) { + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_3: + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_4: + lexbor_serialize_write(cb, &hmo[rgba->r], 1, ctx, status); + lexbor_serialize_write(cb, &hmo[rgba->g], 1, ctx, status); + lexbor_serialize_write(cb, &hmo[rgba->b], 1, ctx, status); + + if (hex->type == LXB_CSS_PROPERTY_COLOR_HEX_TYPE_4) { + lexbor_serialize_write(cb, &hmo[rgba->a], 1, ctx, status); + } + + break; + + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_6: + case LXB_CSS_PROPERTY_COLOR_HEX_TYPE_8: + lexbor_serialize_write(cb, hmt[rgba->r], 2, ctx, status); + lexbor_serialize_write(cb, hmt[rgba->g], 2, ctx, status); + lexbor_serialize_write(cb, hmt[rgba->b], 2, ctx, status); + + if (hex->type == LXB_CSS_PROPERTY_COLOR_HEX_TYPE_8) { + lexbor_serialize_write(cb, hmt[rgba->a], 2, ctx, status); + } + + break; + + default: + break; + } + + return LXB_STATUS_OK; +} + +static lxb_status_t +lxb_css_value_color_rgb_sr(const lxb_css_value_color_rgba_t *rgb, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + const lexbor_str_t *sep; + static const lexbor_str_t str_rgb = lexbor_str("rgb("); + static const lexbor_str_t str_rgba = lexbor_str("rgba("); + + if (type == LXB_CSS_COLOR_RGB) { + lexbor_serialize_write(cb, str_rgb.data, str_rgb.length, ctx, status); + } + else { + lexbor_serialize_write(cb, str_rgba.data, str_rgba.length, ctx, status); + } + + sep = (rgb->old) ? &lxb_str_comma : &lxb_css_value_str_ws; + + status = lxb_css_value_number_percentage_sr(&rgb->r, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&rgb->g, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&rgb->b, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (rgb->a.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + sep = (rgb->old) ? &lxb_str_comma : &lxb_str_alpha; + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&rgb->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +static lxb_status_t +lxb_css_value_color_hsl_sr(const lxb_css_value_color_hsla_t *hsl, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + const lexbor_str_t *sep; + static const lexbor_str_t str_hsl = lexbor_str("hsl("); + static const lexbor_str_t str_hsla = lexbor_str("hsla("); + static const lexbor_str_t str_hwb = lexbor_str("hwb("); + + switch (type) { + case LXB_CSS_COLOR_HSL: + status = cb(str_hsl.data, str_hsl.length, ctx); + break; + + case LXB_CSS_COLOR_HSLA: + status = cb(str_hsla.data, str_hsla.length, ctx); + break; + + case LXB_CSS_COLOR_HWB: + status = cb(str_hwb.data, str_hwb.length, ctx); + break; + + default: + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (status != LXB_STATUS_OK) { + return status; + } + + sep = (hsl->old) ? &lxb_str_comma : &lxb_css_value_str_ws; + + status = lxb_css_value_hue_sr(&hsl->h, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_percentage_type_sr(&hsl->s, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_percentage_type_sr(&hsl->l, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (hsl->a.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + sep = (hsl->old) ? &lxb_str_comma : &lxb_str_alpha; + + lexbor_serialize_write(cb, sep->data, sep->length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&hsl->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +static lxb_status_t +lxb_css_value_color_lab_sr(const lxb_css_value_color_lab_t *lab, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + static const lexbor_str_t str_lab = lexbor_str("lab("); + static const lexbor_str_t str_oklab = lexbor_str("oklab("); + + switch (type) { + case LXB_CSS_COLOR_LAB: + status = cb(str_lab.data, str_lab.length, ctx); + break; + + case LXB_CSS_COLOR_OKLAB: + status = cb(str_oklab.data, str_oklab.length, ctx); + break; + + default: + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (status != LXB_STATUS_OK) { + return status; + } + + status = lxb_css_value_number_percentage_sr(&lab->l, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&lab->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&lab->b, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (lab->alpha.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + lexbor_serialize_write(cb, lxb_str_alpha.data, lxb_str_alpha.length, + ctx, status); + + status = lxb_css_value_number_percentage_sr(&lab->alpha, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +static lxb_status_t +lxb_css_value_color_lch_sr(const lxb_css_value_color_lch_t *lch, + lexbor_serialize_cb_f cb, void *ctx, + lxb_css_value_type_t type) +{ + lxb_status_t status; + static const lexbor_str_t str_lch = lexbor_str("lch("); + static const lexbor_str_t str_oklch = lexbor_str("oklch("); + + switch (type) { + case LXB_CSS_COLOR_LCH: + status = cb(str_lch.data, str_lch.length, ctx); + break; + + case LXB_CSS_COLOR_OKLCH: + status = cb(str_oklch.data, str_oklch.length, ctx); + break; + + default: + return LXB_STATUS_ERROR_WRONG_ARGS; + } + + if (status != LXB_STATUS_OK) { + return status; + } + + status = lxb_css_value_number_percentage_sr(&lch->l, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_number_percentage_sr(&lch->c, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_serialize_write(cb, lxb_css_value_str_ws.data, + lxb_css_value_str_ws.length, ctx, status); + + status = lxb_css_value_hue_sr(&lch->h, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + if (lch->a.type == LXB_CSS_VALUE__UNDEF) { + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); + } + + lexbor_serialize_write(cb, lxb_str_alpha.data, lxb_str_alpha.length, + ctx, status); + + status = lxb_css_value_number_percentage_sr(&lch->a, cb, ctx); + if (status != LXB_STATUS_OK) { + return status; + } + + return cb(lxb_str_rp.data, lxb_str_rp.length, ctx); +} + +lxb_status_t +lxb_css_value_color_serialize(const lxb_css_value_color_t *color, + lexbor_serialize_cb_f cb, void *ctx) +{ + switch (color->type) { + case LXB_CSS_COLOR_HEX: + return lxb_css_value_color_hex_sr(&color->u.hex, cb, ctx); + + case LXB_CSS_COLOR_RGB: + case LXB_CSS_COLOR_RGBA: + return lxb_css_value_color_rgb_sr(&color->u.rgb, cb, ctx, + color->type); + + case LXB_CSS_COLOR_HSL: + case LXB_CSS_COLOR_HSLA: + case LXB_CSS_COLOR_HWB: + return lxb_css_value_color_hsl_sr(&color->u.hsl, cb, ctx, + color->type); + + case LXB_CSS_COLOR_LAB: + case LXB_CSS_COLOR_OKLAB: + return lxb_css_value_color_lab_sr(&color->u.lab, cb, ctx, + color->type); + + case LXB_CSS_COLOR_LCH: + case LXB_CSS_COLOR_OKLCH: + return lxb_css_value_color_lch_sr(&color->u.lch, cb, ctx, + color->type); + + case LXB_CSS_VALUE__UNDEF: + break; + + default: + return lxb_css_value_serialize(color->type, cb, ctx); + } + + return LXB_STATUS_OK; +} diff --git a/ext/lexbor/lexbor/css/value/const.h b/ext/lexbor/lexbor/css/value/const.h index c9b5241e1d73..a7bd64c60349 100644 --- a/ext/lexbor/lexbor/css/value/const.h +++ b/ext/lexbor/lexbor/css/value/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/css/value/res.h b/ext/lexbor/lexbor/css/value/res.h index 79b3c6b0322f..180dc95f10e9 100644 --- a/ext/lexbor/lexbor/css/value/res.h +++ b/ext/lexbor/lexbor/css/value/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/dom/base.h b/ext/lexbor/lexbor/dom/base.h index 167e43d7691c..3894aa13ca6c 100644 --- a/ext/lexbor/lexbor/dom/base.h +++ b/ext/lexbor/lexbor/dom/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,8 +15,8 @@ extern "C" { #include "lexbor/core/base.h" -#define LXB_DOM_VERSION_MAJOR 1 -#define LXB_DOM_VERSION_MINOR 8 +#define LXB_DOM_VERSION_MAJOR 2 +#define LXB_DOM_VERSION_MINOR 0 #define LXB_DOM_VERSION_PATCH 0 #define LXB_DOM_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/dom/exception.c b/ext/lexbor/lexbor/dom/exception.c index 44fcf65d6b4e..5433ce42aac6 100644 --- a/ext/lexbor/lexbor/dom/exception.c +++ b/ext/lexbor/lexbor/dom/exception.c @@ -1,18 +1,372 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/dom/exception.h" +#include "lexbor/dom/interfaces/document.h" -/* - * No inline functions for ABI. - */ -void * -lxb_dom_exception_code_ref_set_noi(lxb_dom_exception_code_t *var, - lxb_dom_exception_code_t code) +typedef struct { + lexbor_str_t name; + lexbor_str_t message; +} +lxb_dom_exception_data_t; + + +static const lxb_dom_exception_data_t lxb_dom_exception_data[LXB_DOM_EXCEPTION__LAST_ENTRY] = +{ + { + lexbor_str("Error"), + lexbor_str("") + }, + { + lexbor_str("IndexSizeError"), + lexbor_str("Deprecated. Use RangeError instead.") + }, + { + lexbor_str("DOMStringSizeError"), + lexbor_str("") + }, + { + lexbor_str("HierarchyRequestError"), + lexbor_str("The operation would yield an incorrect node tree.") + }, + { + lexbor_str("WrongDocumentError"), + lexbor_str("The object is in the wrong document.") + }, + { + lexbor_str("InvalidCharacterError"), + lexbor_str("The string contains invalid characters.") + }, + { + lexbor_str("NoDataAllowedError"), + lexbor_str("") + }, + { + lexbor_str("NoModificationAllowedError"), + lexbor_str("The object can not be modified.") + }, + { + lexbor_str("NotFoundError"), + lexbor_str("The object can not be found here.") + }, + { + lexbor_str("NotSupportedError"), + lexbor_str("The operation is not supported.") + }, + { + lexbor_str("InUseAttributeError"), + lexbor_str("The attribute is in use by another element.") + }, + { + lexbor_str("InvalidStateError"), + lexbor_str("The object is in an invalid state.") + }, + { + lexbor_str("SyntaxError"), + lexbor_str("The string did not match the expected pattern.") + }, + { + lexbor_str("InvalidModificationError"), + lexbor_str("The object can not be modified in this way.") + }, + { + lexbor_str("NamespaceError"), + lexbor_str("The operation is not allowed by Namespaces in XML.") + }, + { + lexbor_str("InvalidAccessError"), + lexbor_str("Deprecated. Use TypeError for invalid arguments, " + "\"NotSupportedError\" DOMException for unsupported operations, " + "and \"NotAllowedError\" DOMException for denied requests instead.") + }, + { + lexbor_str("ValidationError"), + lexbor_str("") + }, + { + lexbor_str("TypeMismatchError"), + lexbor_str("Deprecated. Use TypeError instead.") + }, + { + lexbor_str("SecurityError"), + lexbor_str("The operation is insecure.") + }, + { + lexbor_str("NetworkError"), + lexbor_str("A network error occurred.") + }, + { + lexbor_str("AbortError"), + lexbor_str("The operation was aborted.") + }, + { + lexbor_str("URLMismatchError"), + lexbor_str("Deprecated.") + }, + { + lexbor_str("QuotaExceededError"), + lexbor_str("Deprecated. Use the QuotaExceededError DOMException-derived " + "interface instead.") + }, + { + lexbor_str("TimeoutError"), + lexbor_str("The operation timed out.") + }, + { + lexbor_str("InvalidNodeTypeError"), + lexbor_str("The supplied node is incorrect or has an incorrect ancestor " + "for this operation.") + }, + { + lexbor_str("DataCloneError"), + lexbor_str("The object can not be cloned.") + }, + { + lexbor_str("EncodingError"), + lexbor_str("The encoding operation (either encoded or decoding) failed.") + }, + { + lexbor_str("NotReadableError"), + lexbor_str("The I/O read operation failed.") + }, + { + lexbor_str("UnknownError"), + lexbor_str("The operation failed for an unknown transient reason " + "(e.g. out of memory).") + }, + { + lexbor_str("ConstraintError"), + lexbor_str("A mutation operation in a transaction failed because a " + "constraint was not satisfied.") + }, + { + lexbor_str("DataError"), + lexbor_str("Provided data is inadequate.") + }, + { + lexbor_str("TransactionInactiveError"), + lexbor_str("A request was placed against a transaction which is currently" + " not active, or which is finished.") + }, + { + lexbor_str("ReadOnlyError"), + lexbor_str("The mutating operation was attempted in a \"readonly\" transaction.") + }, + { + lexbor_str("VersionError"), + lexbor_str("An attempt was made to open a database using a lower version" + " than the existing version.") + }, + { + lexbor_str("OperationError"), + lexbor_str("The operation failed for an operation-specific reason.") + }, + { + lexbor_str("NotAllowedError"), + lexbor_str("The request is not allowed by the user agent or the platform" + " in the current context, possibly because the user denied permission.") + }, + { + lexbor_str("OptOutError"), + lexbor_str("The user opted out of the process.") + } +}; + + +lxb_dom_exception_t * +lxb_dom_exception_create(lxb_dom_document_t *document, + const lxb_char_t *message, size_t message_length, + const lxb_char_t *name, size_t name_length) +{ + lexbor_str_t *str; + const lxb_dom_exception_data_t *data; + lxb_dom_exception_t *exception; + + exception = lexbor_mraw_alloc(document->mraw, sizeof(lxb_dom_exception_t)); + if (exception == NULL) { + return NULL; + } + + exception->document = document; + + if (name != NULL && name_length > 0) { + exception->code = lxb_dom_exception_code_by_name(name, name_length); + } + else { + exception->code = LXB_DOM_EXCEPTION_ERR; + } + + /* Message. */ + + if (message == NULL || message_length == 0) { + data = &lxb_dom_exception_data[exception->code]; + exception->message = *((lexbor_str_t *) &data->message); + } + else { + str = &exception->message; + str->data = lexbor_mraw_alloc(document->mraw, message_length + 1); + if (str->data == NULL) { + goto failed; + } + + memcpy(str->data, message, message_length); + + str->data[message_length] = '\0'; + str->length = message_length; + } + + /* Name. */ + + if (exception->code != LXB_DOM_EXCEPTION_ERR + || name == NULL || name_length == 0) + { + data = &lxb_dom_exception_data[exception->code]; + exception->name = *((lexbor_str_t *) &data->name); + } + else { + str = &exception->name; + str->data = lexbor_mraw_alloc(document->mraw, name_length + 1); + if (str->data == NULL) { + if (exception->message.length != 0) { + lexbor_mraw_free(document->mraw, exception->message.data); + } + + goto failed; + } + + memcpy(str->data, name, name_length); + + str->data[name_length] = '\0'; + str->length = name_length; + } + + return exception; + +failed: + + lexbor_mraw_free(document->mraw, exception); + + return NULL; +} + +lxb_dom_exception_t * +lxb_dom_exception_create_by_code(lxb_dom_document_t *document, + const lxb_char_t *message, size_t length, + lxb_dom_exception_code_t code) { - return lxb_dom_exception_code_ref_set(var, code); + lexbor_str_t *str; + const lxb_dom_exception_data_t *data; + lxb_dom_exception_t *exception; + + if (code <= LXB_DOM_EXCEPTION_OK || code >= LXB_DOM_EXCEPTION__LAST_ENTRY) { + return NULL; + } + + exception = lexbor_mraw_alloc(document->mraw, sizeof(lxb_dom_exception_t)); + if (exception == NULL) { + return NULL; + } + + exception->document = document; + exception->code = code; + + data = &lxb_dom_exception_data[code]; + + /* Message. */ + + if (message == NULL || length == 0) { + exception->message = *((lexbor_str_t *) &data->message); + } + else { + str = &exception->message; + str->data = lexbor_mraw_alloc(document->mraw, length + 1); + if (str->data == NULL) { + goto failed; + } + + memcpy(str->data, message, length); + + str->data[length] = '\0'; + str->length = length; + } + + /* Name. */ + + exception->name = *((lexbor_str_t *) &data->name); + + return exception; + +failed: + + lexbor_mraw_free(document->mraw, exception); + + return NULL; +} + +lxb_dom_exception_t * +lxb_dom_exception_destroy(lxb_dom_exception_t *exception) +{ + const lxb_dom_exception_data_t *data; + lxb_dom_document_t *document = exception->document; + + data = &lxb_dom_exception_data[exception->code]; + + if (exception->message.data != NULL + && exception->message.data != data->message.data) + { + lexbor_mraw_free(document->mraw, exception->message.data); + } + + if (exception->name.data != NULL + && exception->name.data != data->name.data) + { + lexbor_mraw_free(document->mraw, exception->name.data); + } + + lexbor_mraw_free(document->mraw, exception); + + return NULL; +} + +const lexbor_str_t * +lxb_dom_exception_message_by_code(lxb_dom_exception_code_t code) +{ + if (code <= LXB_DOM_EXCEPTION_OK || code >= LXB_DOM_EXCEPTION__LAST_ENTRY) { + return NULL; + } + + return &lxb_dom_exception_data[code].message; +} + +const lexbor_str_t * +lxb_dom_exception_name_by_code(lxb_dom_exception_code_t code) +{ + if (code <= LXB_DOM_EXCEPTION_OK || code >= LXB_DOM_EXCEPTION__LAST_ENTRY) { + return NULL; + } + + return &lxb_dom_exception_data[code].name; +} + +lxb_dom_exception_code_t +lxb_dom_exception_code_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_str_t *str; + lxb_dom_exception_code_t code; + + for (code = 0; code < LXB_DOM_EXCEPTION__LAST_ENTRY; code++) { + str = &lxb_dom_exception_data[code].name; + + if (length == str->length + && lexbor_str_data_ncasecmp(str->data, name, length)) + { + return code; + } + } + + return LXB_DOM_EXCEPTION_ERR; } diff --git a/ext/lexbor/lexbor/dom/exception.h b/ext/lexbor/lexbor/dom/exception.h index 47a7cfee040c..b306ed1443a3 100644 --- a/ext/lexbor/lexbor/dom/exception.h +++ b/ext/lexbor/lexbor/dom/exception.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,58 +12,84 @@ extern "C" { #endif #include "lexbor/core/base.h" +#include "lexbor/core/str.h" +#include "lexbor/dom/interface.h" typedef enum { - LXB_DOM_INDEX_SIZE_ERR = 0x00, - LXB_DOM_DOMSTRING_SIZE_ERR, - LXB_DOM_HIERARCHY_REQUEST_ERR, - LXB_DOM_WRONG_DOCUMENT_ERR, - LXB_DOM_INVALID_CHARACTER_ERR, - LXB_DOM_NO_DATA_ALLOWED_ERR, - LXB_DOM_NO_MODIFICATION_ALLOWED_ERR, - LXB_DOM_NOT_FOUND_ERR, - LXB_DOM_NOT_SUPPORTED_ERR, - LXB_DOM_INUSE_ATTRIBUTE_ERR, - LXB_DOM_INVALID_STATE_ERR, - LXB_DOM_SYNTAX_ERR, - LXB_DOM_INVALID_MODIFICATION_ERR, - LXB_DOM_NAMESPACE_ERR, - LXB_DOM_INVALID_ACCESS_ERR, - LXB_DOM_VALIDATION_ERR, - LXB_DOM_TYPE_MISMATCH_ERR, - LXB_DOM_SECURITY_ERR, - LXB_DOM_NETWORK_ERR, - LXB_DOM_ABORT_ERR, - LXB_DOM_URL_MISMATCH_ERR, - LXB_DOM_QUOTA_EXCEEDED_ERR, - LXB_DOM_TIMEOUT_ERR, - LXB_DOM_INVALID_NODE_TYPE_ERR, - LXB_DOM_DATA_CLONE_ERR + LXB_DOM_EXCEPTION_OK = -1, + LXB_DOM_EXCEPTION_ERR = 0, + LXB_DOM_EXCEPTION_INDEX_SIZE_ERR = 1, /* Deprecated. */ + LXB_DOM_EXCEPTION_DOMSTRING_SIZE_ERR, + LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR, + LXB_DOM_EXCEPTION_WRONG_DOCUMENT_ERR, + LXB_DOM_EXCEPTION_INVALID_CHARACTER_ERR, + LXB_DOM_EXCEPTION_NO_DATA_ALLOWED_ERR, + LXB_DOM_EXCEPTION_NO_MODIFICATION_ALLOWED_ERR, + LXB_DOM_EXCEPTION_NOT_FOUND_ERR, + LXB_DOM_EXCEPTION_NOT_SUPPORTED_ERR, + LXB_DOM_EXCEPTION_INUSE_ATTRIBUTE_ERR, + LXB_DOM_EXCEPTION_INVALID_STATE_ERR, + LXB_DOM_EXCEPTION_SYNTAX_ERR, + LXB_DOM_EXCEPTION_INVALID_MODIFICATION_ERR, + LXB_DOM_EXCEPTION_NAMESPACE_ERR, + LXB_DOM_EXCEPTION_INVALID_ACCESS_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_VALIDATION_ERR, + LXB_DOM_EXCEPTION_TYPE_MISMATCH_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_SECURITY_ERR, + LXB_DOM_EXCEPTION_NETWORK_ERR, + LXB_DOM_EXCEPTION_ABORT_ERR, + LXB_DOM_EXCEPTION_URL_MISMATCH_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_QUOTA_EXCEEDED_ERR, /* Deprecated. */ + LXB_DOM_EXCEPTION_TIMEOUT_ERR, + LXB_DOM_EXCEPTION_INVALID_NODE_TYPE_ERR, + LXB_DOM_EXCEPTION_DATA_CLONE_ERR, + LXB_DOM_EXCEPTION_ENCODING_ERR, + LXB_DOM_EXCEPTION_NOT_READABLE_ERR, + LXB_DOM_EXCEPTION_UNKNOWN_ERR, + LXB_DOM_EXCEPTION_CONSTRAINT_ERR, + LXB_DOM_EXCEPTION_DATA_ERR, + LXB_DOM_EXCEPTION_TRANSACTION_INACTIVE_ERR, + LXB_DOM_EXCEPTION_READ_ONLY_ERR, + LXB_DOM_EXCEPTION_VERSION_ERR, + LXB_DOM_EXCEPTION_OPERATION_ERR, + LXB_DOM_EXCEPTION_NOT_ALLOWED_ERR, + LXB_DOM_EXCEPTION_OPT_OUT_ERR, + LXB_DOM_EXCEPTION__LAST_ENTRY } lxb_dom_exception_code_t; - -/* - * Inline functions - */ -lxb_inline void * -lxb_dom_exception_code_ref_set(lxb_dom_exception_code_t *var, - lxb_dom_exception_code_t code) -{ - if (var != NULL) { - *var = code; - } - - return NULL; +typedef struct { + lexbor_str_t name; + lexbor_str_t message; + lxb_dom_exception_code_t code; + lxb_dom_document_t *document; } +lxb_dom_exception_t; -/* - * No inline functions for ABI. - */ -LXB_API void * -lxb_dom_exception_code_ref_set_noi(lxb_dom_exception_code_t *var, - lxb_dom_exception_code_t code); + +LXB_API lxb_dom_exception_t * +lxb_dom_exception_create(lxb_dom_document_t *document, + const lxb_char_t *message, size_t message_length, + const lxb_char_t *name, size_t name_length); + +LXB_API lxb_dom_exception_t * +lxb_dom_exception_create_by_code(lxb_dom_document_t *document, + const lxb_char_t *message, size_t length, + lxb_dom_exception_code_t code); + +LXB_API lxb_dom_exception_t * +lxb_dom_exception_destroy(lxb_dom_exception_t *exception); + + +LXB_API const lexbor_str_t * +lxb_dom_exception_message_by_code(lxb_dom_exception_code_t code); + +LXB_API const lexbor_str_t * +lxb_dom_exception_name_by_code(lxb_dom_exception_code_t code); + +LXB_API lxb_dom_exception_code_t +lxb_dom_exception_code_by_name(const lxb_char_t *name, size_t length); #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/dom/interface.h b/ext/lexbor/lexbor/dom/interface.h index 3eb4b133e9cd..30753e0b43ab 100644 --- a/ext/lexbor/lexbor/dom/interface.h +++ b/ext/lexbor/lexbor/dom/interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,8 +16,6 @@ extern "C" { #include "lexbor/tag/const.h" #include "lexbor/ns/const.h" -#include "lexbor/dom/exception.h" - #define lxb_dom_interface_cdata_section(obj) ((lxb_dom_cdata_section_t *) (obj)) #define lxb_dom_interface_character_data(obj) ((lxb_dom_character_data_t *) (obj)) diff --git a/ext/lexbor/lexbor/dom/interfaces/attr_const.h b/ext/lexbor/lexbor/dom/interfaces/attr_const.h index 756ad5548e45..28afac5e0bdd 100644 --- a/ext/lexbor/lexbor/dom/interfaces/attr_const.h +++ b/ext/lexbor/lexbor/dom/interfaces/attr_const.h @@ -39,22 +39,23 @@ typedef enum { LXB_DOM_ATTR_ID = 0x0012, LXB_DOM_ATTR_IS = 0x0013, LXB_DOM_ATTR_MAXLENGTH = 0x0014, - LXB_DOM_ATTR_PLACEHOLDER = 0x0015, - LXB_DOM_ATTR_POOL = 0x0016, - LXB_DOM_ATTR_PUBLIC = 0x0017, - LXB_DOM_ATTR_READONLY = 0x0018, - LXB_DOM_ATTR_REQUIRED = 0x0019, - LXB_DOM_ATTR_SCHEME = 0x001a, - LXB_DOM_ATTR_SELECTED = 0x001b, - LXB_DOM_ATTR_SIZE = 0x001c, - LXB_DOM_ATTR_SLOT = 0x001d, - LXB_DOM_ATTR_SRC = 0x001e, - LXB_DOM_ATTR_STYLE = 0x001f, - LXB_DOM_ATTR_SYSTEM = 0x0020, - LXB_DOM_ATTR_TITLE = 0x0021, - LXB_DOM_ATTR_TYPE = 0x0022, - LXB_DOM_ATTR_WIDTH = 0x0023, - LXB_DOM_ATTR__LAST_ENTRY = 0x0024 + LXB_DOM_ATTR_MULTIPLE = 0x0015, + LXB_DOM_ATTR_PLACEHOLDER = 0x0016, + LXB_DOM_ATTR_POOL = 0x0017, + LXB_DOM_ATTR_PUBLIC = 0x0018, + LXB_DOM_ATTR_READONLY = 0x0019, + LXB_DOM_ATTR_REQUIRED = 0x001a, + LXB_DOM_ATTR_SCHEME = 0x001b, + LXB_DOM_ATTR_SELECTED = 0x001c, + LXB_DOM_ATTR_SIZE = 0x001d, + LXB_DOM_ATTR_SLOT = 0x001e, + LXB_DOM_ATTR_SRC = 0x001f, + LXB_DOM_ATTR_STYLE = 0x0020, + LXB_DOM_ATTR_SYSTEM = 0x0021, + LXB_DOM_ATTR_TITLE = 0x0022, + LXB_DOM_ATTR_TYPE = 0x0023, + LXB_DOM_ATTR_WIDTH = 0x0024, + LXB_DOM_ATTR__LAST_ENTRY = 0x0025 } lxb_dom_attr_id_enum_t; diff --git a/ext/lexbor/lexbor/dom/interfaces/attr_res.h b/ext/lexbor/lexbor/dom/interfaces/attr_res.h index 85aa2c5061fc..0796043cafd7 100644 --- a/ext/lexbor/lexbor/dom/interfaces/attr_res.h +++ b/ext/lexbor/lexbor/dom/interfaces/attr_res.h @@ -63,6 +63,8 @@ static const lxb_dom_attr_data_t lxb_dom_attr_res_data_default[LXB_DOM_ATTR__LAS LXB_DOM_ATTR_IS, 1, true}, {{.u.short_str = "maxlength", .length = 9, .next = NULL}, LXB_DOM_ATTR_MAXLENGTH, 1, true}, + {{.u.short_str = "multiple", .length = 8, .next = NULL}, + LXB_DOM_ATTR_MULTIPLE, 1, true}, {{.u.short_str = "placeholder", .length = 11, .next = NULL}, LXB_DOM_ATTR_PLACEHOLDER, 1, true}, {{.u.short_str = "pool", .length = 4, .next = NULL}, @@ -127,7 +129,7 @@ static const lexbor_shs_entry_t lxb_dom_attr_res_shs_data[40] = {"is", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_IS], 2, 0}, {"type", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_TYPE], 4, 0}, {"title", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_TITLE], 5, 0}, - {NULL, NULL, 0, 0}, + {"multiple", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_MULTIPLE], 8, 0}, {"for", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_FOR], 3, 0}, {"face", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_FACE], 4, 22}, {"alt", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_ALT], 3, 23}, @@ -135,7 +137,7 @@ static const lexbor_shs_entry_t lxb_dom_attr_res_shs_data[40] = {"charset", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_CHARSET], 7, 26}, {"maxlength", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_MAXLENGTH], 9, 0}, {NULL, NULL, 0, 0}, - {"checked", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_CHECKED], 7, 0}, + {"checked", (void *) &lxb_dom_attr_res_data_default[LXB_DOM_ATTR_CHECKED], 7, 30}, {NULL, NULL, 0, 0} }; diff --git a/ext/lexbor/lexbor/dom/interfaces/character_data.c b/ext/lexbor/lexbor/dom/interfaces/character_data.c index bbca1865b39d..12c7dfdd0d6c 100644 --- a/ext/lexbor/lexbor/dom/interfaces/character_data.c +++ b/ext/lexbor/lexbor/dom/interfaces/character_data.c @@ -22,7 +22,7 @@ lxb_dom_character_data_interface_create(lxb_dom_document_t *document) lxb_dom_node_t *node = lxb_dom_interface_node(element); node->owner_document = lxb_dom_document_owner(document); - node->type = LXB_DOM_NODE_TYPE_UNDEF; + node->type = LXB_DOM_NODE_TYPE_CHARACTER_DATA; return element; } diff --git a/ext/lexbor/lexbor/dom/interfaces/document_type.c b/ext/lexbor/lexbor/dom/interfaces/document_type.c index 8c7465f4d62b..46889162717f 100644 --- a/ext/lexbor/lexbor/dom/interfaces/document_type.c +++ b/ext/lexbor/lexbor/dom/interfaces/document_type.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -12,6 +12,10 @@ LXB_API lxb_dom_attr_data_t * lxb_dom_attr_qualified_name_append(lexbor_hash_t *hash, const lxb_char_t *name, size_t length); +LXB_API lxb_dom_attr_data_t * +lxb_dom_attr_local_name_append(lexbor_hash_t *hash, + const lxb_char_t *name, size_t length); + lxb_dom_document_type_t * lxb_dom_document_type_interface_create(lxb_dom_document_t *document) @@ -29,6 +33,8 @@ lxb_dom_document_type_interface_create(lxb_dom_document_t *document) node->owner_document = lxb_dom_document_owner(document); node->type = LXB_DOM_NODE_TYPE_DOCUMENT_TYPE; + element->name = LXB_DOM_ATTR_HTML; + return element; } @@ -105,6 +111,103 @@ lxb_dom_document_type_interface_destroy(lxb_dom_document_type_t *document_type) return NULL; } +lxb_dom_document_type_t * +lxb_dom_document_type_create(lxb_dom_document_t *document, + const lxb_char_t *name, size_t name_len, + const lxb_char_t *pub, size_t pub_len, + const lxb_char_t *sys, size_t sys_len, + lxb_dom_exception_code_t *code) +{ + lxb_dom_attr_data_t *data; + lxb_dom_document_type_t *doctype; + + if (!lxb_dom_document_type_valid_name(name, name_len)) { + if (code != NULL) { + *code = LXB_DOM_EXCEPTION_INVALID_CHARACTER_ERR; + } + + return NULL; + } + + doctype = lxb_dom_document_type_interface_create(document); + if (doctype == NULL) { + goto failed; + } + + data = lxb_dom_attr_local_name_append(document->attrs, name, name_len); + if (data == NULL) { + goto failed; + } + + doctype->name = data->attr_id; + + if (pub != NULL && pub_len != 0) { + doctype->public_id.data = lxb_dom_document_create_text(document, + pub_len + 1); + if (doctype->public_id.data == NULL) { + goto failed; + } + + (void) lexbor_str_copy_to_with_null(&doctype->public_id, pub, pub_len); + } + + if (sys != NULL && sys_len != 0) { + doctype->system_id.data = lxb_dom_document_create_text(document, + sys_len + 1); + if (doctype->system_id.data == NULL) { + goto failed; + } + + (void) lexbor_str_copy_to_with_null(&doctype->system_id, sys, sys_len); + } + + if (code != NULL) { + *code = LXB_DOM_EXCEPTION_OK; + } + + return doctype; + +failed: + + if (doctype != NULL && doctype->public_id.data != NULL) { + lxb_dom_document_destroy_text(document, doctype->public_id.data); + } + + if (code != NULL) { + *code = LXB_DOM_EXCEPTION_ERR; + } + + return NULL; +} + +bool +lxb_dom_document_type_valid_name(const lxb_char_t *name, size_t length) +{ + lxb_char_t c; + const lxb_char_t *end; + + if (name == NULL || length == 0) { + return false; + } + + end = name + length; + + while (name < end) { + c = *name++; + /* + * U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE, + * or U+0000 NULL, or U+003E (>) + */ + if (c == 0x09 || c == 0x0A || c == 0x0C || c == 0x0D || c == 0x20 + || c == 0x00 || c == 0x3E) + { + return false; + } + } + + return true; +} + /* * No inline functions for ABI. */ diff --git a/ext/lexbor/lexbor/dom/interfaces/document_type.h b/ext/lexbor/lexbor/dom/interfaces/document_type.h index 0e0d35d5e188..c7a1960af668 100644 --- a/ext/lexbor/lexbor/dom/interfaces/document_type.h +++ b/ext/lexbor/lexbor/dom/interfaces/document_type.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,6 @@ extern "C" { #include "lexbor/dom/interfaces/document.h" #include "lexbor/dom/interfaces/node.h" #include "lexbor/dom/interfaces/attr.h" -#include "lexbor/dom/interfaces/document_type.h" struct lxb_dom_document_type { @@ -38,6 +37,34 @@ lxb_dom_document_type_interface_clone(lxb_dom_document_t *document, LXB_API lxb_dom_document_type_t * lxb_dom_document_type_interface_destroy(lxb_dom_document_type_t *document_type); +/* + * Create DocumentType by specification. + * + * https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype + * + * @param[in] lxb_dom_document_t *. Not NULL. + * @param[in] const lxb_char_t *. Name. May be NULL, but then the return value + * will be NULL and an exception code will be recorded. + * @param[in] size_t. Length of name. May be 0, but then the return value + * will be NULL and an exception code will be recorded. + * @param[in] const lxb_char_t *. PublicID. Can be NULL. + * @param[in] size_t. Length of PublicID. Can be 0. + * @param[in] const lxb_char_t *. SystemID. Can be NULL. + * @param[in] size_t. Length of SystemID. Can be 0. + * @param[out] lxb_dom_exception_code_t. Can be NULL. If the variable is passed, + * the code will definitely be assigned. LXB_DOM_EXCEPTION_OK + * if successful. + * + * @return lxb_dom_document_type_t * if successful, otherwise NULL. + */ +LXB_API lxb_dom_document_type_t * +lxb_dom_document_type_create(lxb_dom_document_t *document, + const lxb_char_t *name, size_t name_len, + const lxb_char_t *pub, size_t pub_len, + const lxb_char_t *sys, size_t sys_len, + lxb_dom_exception_code_t *code); +LXB_API bool +lxb_dom_document_type_valid_name(const lxb_char_t *ame, size_t name_len); /* * Inline functions diff --git a/ext/lexbor/lexbor/dom/interfaces/element.c b/ext/lexbor/lexbor/dom/interfaces/element.c index 09d9736e5d8c..90d707d078bb 100644 --- a/ext/lexbor/lexbor/dom/interfaces/element.c +++ b/ext/lexbor/lexbor/dom/interfaces/element.c @@ -581,6 +581,18 @@ lxb_dom_element_is_set(lxb_dom_element_t *element, return LXB_STATUS_OK; } +lxb_dom_element_t * +lxb_dom_element_by_id(lxb_dom_element_t *root, + const lxb_char_t *qualified_name, size_t len) +{ + lxb_dom_node_t *node; + + node = lxb_dom_node_by_id(lxb_dom_interface_node(root), + qualified_name, len); + + return lxb_dom_interface_element(node); +} + lxb_status_t lxb_dom_elements_by_tag_name(lxb_dom_element_t *root, lxb_dom_collection_t *collection, diff --git a/ext/lexbor/lexbor/dom/interfaces/element.h b/ext/lexbor/lexbor/dom/interfaces/element.h index dd661d439cce..50d814fd3765 100644 --- a/ext/lexbor/lexbor/dom/interfaces/element.h +++ b/ext/lexbor/lexbor/dom/interfaces/element.h @@ -135,6 +135,10 @@ LXB_API lxb_status_t lxb_dom_element_is_set(lxb_dom_element_t *element, const lxb_char_t *is, size_t is_len); +LXB_API lxb_dom_element_t * +lxb_dom_element_by_id(lxb_dom_element_t *root, + const lxb_char_t *qualified_name, size_t len); + LXB_API lxb_status_t lxb_dom_elements_by_tag_name(lxb_dom_element_t *root, lxb_dom_collection_t *collection, diff --git a/ext/lexbor/lexbor/dom/interfaces/node.c b/ext/lexbor/lexbor/dom/interfaces/node.c index ade06fca1799..f2bbaa391e39 100644 --- a/ext/lexbor/lexbor/dom/interfaces/node.c +++ b/ext/lexbor/lexbor/dom/interfaces/node.c @@ -10,6 +10,7 @@ #include "lexbor/dom/interfaces/document_type.h" #include "lexbor/dom/interfaces/element.h" #include "lexbor/dom/interfaces/processing_instruction.h" +#include "lexbor/dom/interfaces/shadow_root.h" typedef struct lxb_dom_node_cb_ctx lxb_dom_node_cb_ctx_t; @@ -29,6 +30,13 @@ struct lxb_dom_node_cb_ctx { size_t value_length; }; +typedef struct { + lxb_dom_node_t *node; + const lxb_char_t *value; + size_t length; +} +lxb_dom_node_id_cb_ctx_t; + LXB_API lxb_dom_attr_data_t * lxb_dom_attr_local_name_append(lexbor_hash_t *hash, @@ -44,6 +52,9 @@ lxb_ns_append(lexbor_hash_t *hash, const lxb_char_t *link, size_t length); static lexbor_action_t lxb_dom_node_by_tag_name_cb(lxb_dom_node_t *node, void *ctx); +static lexbor_action_t +lxb_dom_node_by_id_cb(lxb_dom_node_t *node, void *ctx); + static lexbor_action_t lxb_dom_node_by_tag_name_cb_all(lxb_dom_node_t *node, void *ctx); @@ -248,11 +259,6 @@ lxb_dom_node_t * lxb_dom_node_destroy(lxb_dom_node_t *node) { lxb_dom_node_remove(node); - - if (node->owner_document->node_cb->destroy != NULL) { - node->owner_document->node_cb->destroy(node); - } - return lxb_dom_document_destroy_interface(node); } @@ -448,6 +454,373 @@ lxb_dom_node_insert_after(lxb_dom_node_t *to, lxb_dom_node_t *node) } } +lxb_dom_exception_code_t +lxb_dom_node_pre_insert_validity(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + size_t count; + lxb_dom_node_t *tmp; + + /* + * If parent is not a Document, DocumentFragment, or Element node, then + * throw a "HierarchyRequestError" DOMException. + */ + if (parent == NULL) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + switch (parent->type) { + case LXB_DOM_NODE_TYPE_ELEMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT: + break; + + default: + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + if (lxb_dom_node_host_including_inclusive_ancestor(node, parent)) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + /* + * If child is non-null and its parent is not parent, + * then throw a "NotFoundError" DOMException. + */ + if (child != NULL && parent != child->parent) { + return LXB_DOM_EXCEPTION_NOT_FOUND_ERR; + } + + /* + * If node is not a DocumentFragment, DocumentType, Element, + * or CharacterData node, then throw a "HierarchyRequestError" DOMException. + */ + if (node == NULL) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + switch (parent->type) { + case LXB_DOM_NODE_TYPE_ELEMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT: + case LXB_DOM_NODE_TYPE_DOCUMENT_TYPE: + case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT: + case LXB_DOM_NODE_TYPE_CHARACTER_DATA: + case LXB_DOM_NODE_TYPE_TEXT: + break; + + default: + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + /* + * If either node is a Text node and parent is a document, or node is + * a doctype and parent is not a document, then throw + * a "HierarchyRequestError" DOMException. + */ + if ((node->type == LXB_DOM_NODE_TYPE_TEXT + && parent->type == LXB_DOM_NODE_TYPE_DOCUMENT) + || (node->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE + && parent->type != LXB_DOM_NODE_TYPE_DOCUMENT)) + { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + if (parent->type != LXB_DOM_NODE_TYPE_DOCUMENT) { + return LXB_DOM_EXCEPTION_OK; + } + + switch (node->type) { + case LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT: + tmp = node->first_child; + + if (tmp == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + count = 0; + + do { + if (tmp->type == LXB_DOM_NODE_TYPE_TEXT) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + else if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT) { + count += 1; + + if (count > 1) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + } + + tmp = tmp->next; + } + while (tmp != NULL); + + if (count != 1) { + return LXB_DOM_EXCEPTION_OK; + } + + /* Fall Through. */ + + case LXB_DOM_NODE_TYPE_ELEMENT: + tmp = parent->first_child; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->next; + } + + if (child == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + if (child->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = child->next; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->next; + } + + break; + + case LXB_DOM_NODE_TYPE_DOCUMENT_TYPE: + tmp = parent->first_child; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_DOCUMENT_TYPE) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + else if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT + && child == NULL) + { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->next; + } + + if (child == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + tmp = child->prev; + + while (tmp != NULL) { + if (tmp->type == LXB_DOM_NODE_TYPE_ELEMENT) { + return LXB_DOM_EXCEPTION_HIERARCHY_REQUEST_ERR; + } + + tmp = tmp->prev; + } + + break; + + default: + break; + } + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_pre_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + lxb_dom_exception_code_t ex_code; + + ex_code = lxb_dom_node_pre_insert_validity(parent, node, child); + if (ex_code != LXB_DOM_EXCEPTION_OK) { + return ex_code; + } + + if (child == node) { + child = node->next; + } + + return lxb_dom_node_insert(parent, node, child, false); +} + +lxb_inline lxb_dom_exception_code_t +lxb_dom_node_insert_node(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child, bool suppress_observers) +{ + lxb_dom_exception_code_t code; + + code = lxb_dom_node_adopt(node); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + if (child == NULL) { + lxb_dom_node_insert_child(parent, node); + } + else { + lxb_dom_node_insert_before(child, node); + } + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child, bool suppress_observers) +{ + lxb_dom_node_t *tmp, *next; + lxb_dom_exception_code_t code; + + if (node->type == LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT) { + if (node->first_child == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + } + + /* TODO: live range. */ + + if (node->type != LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT) { + return lxb_dom_node_insert_node(parent, node, child, + suppress_observers); + } + + tmp = node->first_child; + + while (tmp != NULL) { + next = tmp->next; + + code = lxb_dom_node_insert_node(parent, tmp, child, + suppress_observers); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + tmp = next; + } + + /* TODO: Shadow and queue a tree mutation record. */ + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_insert_before_spec(lxb_dom_node_t *dst, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + return lxb_dom_node_pre_insert(dst, node, child); +} + +lxb_dom_exception_code_t +lxb_dom_node_append_child(lxb_dom_node_t *parent, lxb_dom_node_t *node) +{ + return lxb_dom_node_pre_insert(parent, node, NULL); +} + +lxb_dom_exception_code_t +lxb_dom_node_remove_child(lxb_dom_node_t *parent, lxb_dom_node_t *child) +{ + if (parent != child->parent) { + return LXB_DOM_EXCEPTION_NOT_FOUND_ERR; + } + + return lxb_dom_node_remove_spec(child, false); +} + +lxb_dom_exception_code_t +lxb_dom_node_replace_child(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child) +{ + lxb_dom_node_t *tmp, *next; + lxb_dom_node_t *before; + lxb_dom_exception_code_t code; + + code = lxb_dom_node_pre_insert_validity(parent, node, child); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + before = child->prev; + if (before == NULL) { + before = child->next; + } + + if (child->parent != NULL) { + code = lxb_dom_node_remove_spec(child, true); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + } + + if (node->type != LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT) { + return lxb_dom_node_insert_node(parent, node, before, true); + } + + tmp = node->first_child; + + while (tmp != NULL) { + next = tmp->next; + + code = lxb_dom_node_insert_node(parent, tmp, before, true); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + tmp = next; + } + + return LXB_DOM_EXCEPTION_OK; +} + +lxb_dom_exception_code_t +lxb_dom_node_replace_all_spec(lxb_dom_node_t *parent, lxb_dom_node_t *node) +{ + lxb_dom_node_t *child, *next; + lxb_dom_exception_code_t code; + + child = parent->first_child; + + while (child != NULL) { + next = child->next; + + code = lxb_dom_node_remove_spec(child, true); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + + child = next; + } + + return lxb_dom_node_append_child(parent, node); +} + +lxb_dom_exception_code_t +lxb_dom_node_remove_spec(lxb_dom_node_t *node, bool suppress_observers) +{ + if (node->parent == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + /* TODO: 3. Run the live range pre-remove steps, given node. */ + + /* + * TODO: For each NodeIterator object iterator whose root’s node document + * is node’s node document, run the NodeIterator pre-remove steps given + * node and iterator. + */ + + lxb_dom_node_remove(node); + + /* TODO: finish everything else. */ + + return LXB_DOM_EXCEPTION_OK; +} + void lxb_dom_node_remove_wo_events(lxb_dom_node_t *node) { @@ -622,6 +995,52 @@ lxb_dom_node_prepare_by(lxb_dom_document_t *document, return LXB_STATUS_OK; } +lxb_dom_node_t * +lxb_dom_node_by_id(lxb_dom_node_t *root, + const lxb_char_t *qualified_name, size_t len) +{ + lxb_dom_node_id_cb_ctx_t ctx; + + ctx.node = NULL; + ctx.value = qualified_name; + ctx.length = len; + + lxb_dom_node_simple_walk(root, lxb_dom_node_by_id_cb, &ctx); + + return ctx.node; +} + +static lexbor_action_t +lxb_dom_node_by_id_cb(lxb_dom_node_t *node, void *ctx) +{ + lxb_dom_node_id_cb_ctx_t *context; + const lxb_dom_attr_t *attr_id; + + if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) { + return LEXBOR_ACTION_OK; + } + + context = ctx; + attr_id = lxb_dom_interface_element(node)->attr_id; + + if (attr_id == NULL + || attr_id->value == NULL + || attr_id->value->length != context->length) + { + return LEXBOR_ACTION_OK; + } + + const lxb_char_t *data = attr_id->value->data; + size_t length = attr_id->value->length; + + if (lexbor_str_data_ncmp(context->value, data, length)) { + context->node = node; + return LEXBOR_ACTION_STOP; + } + + return LEXBOR_ACTION_OK; +} + lxb_status_t lxb_dom_node_by_tag_name(lxb_dom_node_t *root, lxb_dom_collection_t *collection, @@ -1283,6 +1702,47 @@ lxb_dom_node_is_empty(const lxb_dom_node_t *root) return true; } +bool +lxb_dom_node_host_including_inclusive_ancestor(const lxb_dom_node_t *node, + const lxb_dom_node_t *parent) +{ + const lxb_dom_shadow_root_t *root; + + while (parent != NULL) { + if (parent == node) { + return true; + } + + if (parent->type == LXB_DOM_NODE_TYPE_SHADOW_ROOT) { + root = lxb_dom_interface_shadow_root(parent); + parent = &root->host->node; + + continue; + } + + parent = parent->parent; + } + + return false; +} + +lxb_dom_exception_code_t +lxb_dom_node_adopt(lxb_dom_node_t *node) +{ + lxb_dom_exception_code_t code; + + if (node->parent != NULL) { + code = lxb_dom_node_remove_spec(node, false); + if (code != LXB_DOM_EXCEPTION_OK) { + return code; + } + } + + /* TODO: If document is not oldDocument steps. */ + + return LXB_DOM_EXCEPTION_OK; +} + lxb_tag_id_t lxb_dom_node_tag_id_noi(lxb_dom_node_t *node) { @@ -1318,3 +1778,9 @@ lxb_dom_node_last_child_noi(lxb_dom_node_t *node) { return lxb_dom_node_last_child(node); } + +lxb_dom_node_type_t +lxb_dom_node_type_noi(lxb_dom_node_t *node) +{ + return lxb_dom_node_type(node); +} diff --git a/ext/lexbor/lexbor/dom/interfaces/node.h b/ext/lexbor/lexbor/dom/interfaces/node.h index b5d2c5069f0d..b95373c51952 100644 --- a/ext/lexbor/lexbor/dom/interfaces/node.h +++ b/ext/lexbor/lexbor/dom/interfaces/node.h @@ -13,6 +13,7 @@ extern "C" { #include "lexbor/dom/interface.h" #include "lexbor/dom/collection.h" +#include "lexbor/dom/exception.h" #include "lexbor/dom/interfaces/event_target.h" @@ -59,7 +60,9 @@ typedef enum { LXB_DOM_NODE_TYPE_DOCUMENT_TYPE = 0x0A, LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT = 0x0B, LXB_DOM_NODE_TYPE_NOTATION = 0x0C, // historical - LXB_DOM_NODE_TYPE_LAST_ENTRY = 0x0D + LXB_DOM_NODE_TYPE_CHARACTER_DATA, + LXB_DOM_NODE_TYPE_SHADOW_ROOT, + LXB_DOM_NODE_TYPE_LAST_ENTRY } lxb_dom_node_type_t; @@ -135,12 +138,106 @@ lxb_dom_node_insert_after_wo_events(lxb_dom_node_t *to, lxb_dom_node_t *node); LXB_API void lxb_dom_node_insert_after(lxb_dom_node_t *to, lxb_dom_node_t *node); +LXB_API lxb_dom_exception_code_t +lxb_dom_node_pre_insert_validity(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_pre_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_insert(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child, bool suppress_observers); + +/* + * Add a node as a child. + * + * Function according to specification. Node.appendChild(node). + * + * The function not only adds a node as a child, but also validates + * the possibility of adding it. + * For example, the lxb_dom_node_insert_child() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where to add. Not NULL. + * @param[in] lxb_dom_node_t *. Who to add. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_append_child(lxb_dom_node_t *parent, lxb_dom_node_t *node); + +/* + * Insert before child. + * + * Function according to specification. Node.insertBefore(node, child). + * + * The function not only insert a node as a child, but also validates + * the possibility of adding it. + * For example, the lxb_dom_node_insert_before() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where to add. Not NULL. + * @param[in] lxb_dom_node_t *. Who to add. Not NULL. + * @param[in] lxb_dom_node_t *. The child before need to insert. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_insert_before_spec(lxb_dom_node_t *dst, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_remove_spec(lxb_dom_node_t *node, bool suppress_observers); + LXB_API void lxb_dom_node_remove_wo_events(lxb_dom_node_t *node); LXB_API void lxb_dom_node_remove(lxb_dom_node_t *node); +/* + * Removing a node. + * + * Function according to specification. Node.removeChild(node). + * + * The function not only removing a node, but also validates the possibility + * of adding it. + * For example, the lxb_dom_node_remove() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where remove. Not NULL. + * @param[in] lxb_dom_node_t *. Who remove. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_remove_child(lxb_dom_node_t *parent, lxb_dom_node_t *child); + +/* + * The function replaces the child with a node. + * + * Function according to specification. Node.replaceChild(node, child). + * + * The function not only replace a node, but also validates the possibility + * of adding it. + * For example, the lxb_dom_node_replace_all() function does not perform + * any validation. + * + * @param[in] lxb_dom_node_t *. Where replace. Not NULL. + * @param[in] lxb_dom_node_t *. Who replace. Not NULL. + * @param[in] lxb_dom_node_t *. Replaceable child. Not NULL. + * + * @return LXB_DOM_EXCEPTION_OK if successful, otherwise an error exception code. + */ +LXB_API lxb_dom_exception_code_t +lxb_dom_node_replace_child(lxb_dom_node_t *parent, lxb_dom_node_t *node, + lxb_dom_node_t *child); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_replace_all_spec(lxb_dom_node_t *parent, lxb_dom_node_t *node); + LXB_API lxb_status_t lxb_dom_node_replace_all(lxb_dom_node_t *parent, lxb_dom_node_t *node); @@ -148,6 +245,10 @@ LXB_API void lxb_dom_node_simple_walk(lxb_dom_node_t *root, lxb_dom_node_simple_walker_f walker_cb, void *ctx); +LXB_API lxb_dom_node_t * +lxb_dom_node_by_id(lxb_dom_node_t *root, + const lxb_char_t *qualified_name, size_t len); + LXB_API lxb_status_t lxb_dom_node_by_tag_name(lxb_dom_node_t *root, lxb_dom_collection_t *collection, const lxb_char_t *qualified_name, size_t len); @@ -193,6 +294,12 @@ lxb_dom_node_text_content_set(lxb_dom_node_t *node, LXB_API bool lxb_dom_node_is_empty(const lxb_dom_node_t *root); +LXB_API bool +lxb_dom_node_host_including_inclusive_ancestor(const lxb_dom_node_t *node, + const lxb_dom_node_t *parent); + +LXB_API lxb_dom_exception_code_t +lxb_dom_node_adopt(lxb_dom_node_t *node); /* * Inline functions @@ -233,6 +340,12 @@ lxb_dom_node_last_child(lxb_dom_node_t *node) return node->last_child; } +lxb_inline lxb_dom_node_type_t +lxb_dom_node_type(lxb_dom_node_t *node) +{ + return node->type; +} + /* * No inline functions for ABI. */ @@ -254,6 +367,9 @@ lxb_dom_node_first_child_noi(lxb_dom_node_t *node); LXB_API lxb_dom_node_t * lxb_dom_node_last_child_noi(lxb_dom_node_t *node); +LXB_API lxb_dom_node_type_t +lxb_dom_node_type_noi(lxb_dom_node_t *node); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/dom/interfaces/shadow_root.c b/ext/lexbor/lexbor/dom/interfaces/shadow_root.c index a7145bcec0d8..e2c332d58b28 100644 --- a/ext/lexbor/lexbor/dom/interfaces/shadow_root.c +++ b/ext/lexbor/lexbor/dom/interfaces/shadow_root.c @@ -22,7 +22,7 @@ lxb_dom_shadow_root_interface_create(lxb_dom_document_t *document) lxb_dom_node_t *node = lxb_dom_interface_node(element); node->owner_document = lxb_dom_document_owner(document); - node->type = LXB_DOM_NODE_TYPE_UNDEF; + node->type = LXB_DOM_NODE_TYPE_SHADOW_ROOT; return element; } diff --git a/ext/lexbor/lexbor/encoding/base.h b/ext/lexbor/lexbor/encoding/base.h index 88d74cc9bf8f..459287df3832 100644 --- a/ext/lexbor/lexbor/encoding/base.h +++ b/ext/lexbor/lexbor/encoding/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_ENCODING_VERSION_MAJOR 2 -#define LXB_ENCODING_VERSION_MINOR 2 +#define LXB_ENCODING_VERSION_MINOR 3 #define LXB_ENCODING_VERSION_PATCH 0 #define LXB_ENCODING_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/encoding/encode.c b/ext/lexbor/lexbor/encoding/encode.c index 4377fb31f58a..f9a4f9f8effb 100644 --- a/ext/lexbor/lexbor/encoding/encode.c +++ b/ext/lexbor/lexbor/encoding/encode.c @@ -111,6 +111,122 @@ return 1 +lxb_inline uint16_t +lxb_encoding_multi_big5_index(lxb_codepoint_t cp) +{ + if (cp > 0x2F8A7) { + return UINT16_MAX; + } + + if (cp < 65518) { + if (cp >= 167 && cp < 1106) { + return lxb_encoding_multi_big5_167_1106_map[cp - 167]; + } + else if (cp >= 8211) { + if (cp < 40882) { + return lxb_encoding_multi_big5_8211_40882_map[cp - 8211]; + } + else if (cp >= 64012) { + return lxb_encoding_multi_big5_64012_65518_map[cp - 64012]; + } + } + } + else if (cp >= 131210) { + if (cp < 172369) { + return lxb_encoding_multi_big5_131210_172369_map[cp - 131210]; + } + else if (cp >= 194708) { + if (cp < 194727) { + return lxb_encoding_multi_big5_194708_194727_map[cp - 194708]; + } + } + } + + return UINT16_MAX; +} + +lxb_inline uint16_t +lxb_encoding_multi_euc_kr_index(lxb_codepoint_t cp) +{ + if (cp > 0xFFE7) { + return UINT16_MAX; + } + + if (cp < 13278) { + if (cp >= 161 && cp < 1106) { + return lxb_encoding_multi_euc_kr_161_1106_map[cp - 161]; + } + else if (cp >= 8213) { + return lxb_encoding_multi_euc_kr_8213_13278_map[cp - 8213]; + } + } + else if (cp >= 19968) { + if (cp < 55204) { + return lxb_encoding_multi_euc_kr_19968_55204_map[cp - 19968]; + } + else if (cp >= 63744) { + if (cp < 65511) { + return lxb_encoding_multi_euc_kr_63744_65511_map[cp - 63744]; + } + } + } + + return UINT16_MAX; +} + +lxb_inline uint16_t +lxb_encoding_multi_gb18030_index(lxb_codepoint_t cp) +{ + if (cp > 0xFFE6) { + return UINT16_MAX; + } + + if (cp < 40892) { + if (cp >= 164 && cp < 1106) { + return lxb_encoding_multi_gb18030_164_1106_map[cp - 164]; + } + else if (cp >= 7743) { + return lxb_encoding_multi_gb18030_7743_40892_map[cp - 7743]; + } + } + else if (cp >= 57344) { + if (cp < 65510) { + return lxb_encoding_multi_gb18030_57344_65510_map[cp - 57344]; + } + } + + return UINT16_MAX; +} + +lxb_inline uint16_t +lxb_encoding_multi_jis0208_index(lxb_codepoint_t cp) +{ + if (cp > 0xFFE6) { + return UINT16_MAX; + } + + if (cp < 13262) { + if (cp >= 167 && cp < 1106) { + return lxb_encoding_multi_jis0208_167_1106_map[cp - 167]; + } + else if (cp >= 8208) { + return lxb_encoding_multi_jis0208_8208_13262_map[cp - 8208]; + } + } + else if (cp >= 19968) { + if (cp < 40865) { + return lxb_encoding_multi_jis0208_19968_40865_map[cp - 19968]; + } + else if (cp >= 63785) { + if (cp < 65510) { + return lxb_encoding_multi_jis0208_63785_65510_map[cp - 63785]; + } + } + } + + return UINT16_MAX; +} + lxb_status_t lxb_encoding_encode_default(lxb_encoding_encode_t *ctx, const lxb_codepoint_t **cps, const lxb_codepoint_t *end) @@ -327,10 +443,10 @@ lxb_encoding_encode_iso_2022_jp(lxb_encoding_encode_t *ctx, const lxb_codepoint_ unsigned state; lxb_codepoint_t cp; - size = 0; state = ctx->state; for (; *cps < end; (*cps)++) { + size = 0; cp = **cps; begin: diff --git a/ext/lexbor/lexbor/encoding/encoding.c b/ext/lexbor/lexbor/encoding/encoding.c index 19d3a1474688..2a43f0fd70a2 100644 --- a/ext/lexbor/lexbor/encoding/encoding.c +++ b/ext/lexbor/lexbor/encoding/encoding.c @@ -55,6 +55,74 @@ lxb_encoding_data_by_pre_name(const lxb_char_t *name, size_t length) return entry->value; } +lxb_encoding_t +lxb_encoding_prescan_validate(const lxb_char_t *name, size_t length) +{ + const lxb_encoding_data_t *data; + + data = lxb_encoding_data_by_pre_name(name, length); + if (data == NULL) { + return LXB_ENCODING_DEFAULT; + } + + if (data->encoding == LXB_ENCODING_UTF_16BE + || data->encoding == LXB_ENCODING_UTF_16LE) + { + return LXB_ENCODING_UTF_8; + } + + if (data->encoding == LXB_ENCODING_X_USER_DEFINED) { + return LXB_ENCODING_WINDOWS_1252; + } + + return data->encoding; +} + +const lxb_encoding_data_t * +lxb_encoding_data_prescan_validate(const lxb_char_t *name, size_t length) +{ + const lxb_encoding_data_t *data; + + data = lxb_encoding_data_by_pre_name(name, length); + if (data == NULL) { + return NULL; + } + + if (data->encoding == LXB_ENCODING_UTF_16BE + || data->encoding == LXB_ENCODING_UTF_16LE) + { + return lxb_encoding_data(LXB_ENCODING_UTF_8); + } + + if (data->encoding == LXB_ENCODING_X_USER_DEFINED) { + return lxb_encoding_data(LXB_ENCODING_WINDOWS_1252); + } + + return data; +} + +lxb_encoding_t +lxb_encoding_bom_sniff(const lxb_char_t *begin, size_t length) +{ + if (length >= 3) { + if (begin[0] == 0xEF && begin[1] == 0xBB && begin[2] == 0xBF) { + return LXB_ENCODING_UTF_8; + } + } + + if (length >= 2) { + if (begin[0] == 0xFE && begin[1] == 0xFF) { + return LXB_ENCODING_UTF_16BE; + } + + if (begin[0] == 0xFF && begin[1] == 0xFE) { + return LXB_ENCODING_UTF_16LE; + } + } + + return LXB_ENCODING_DEFAULT; +} + void lxb_encoding_utf_8_skip_bom(const lxb_char_t **begin, size_t *length) { @@ -100,6 +168,54 @@ lxb_encoding_utf_16le_skip_bom(const lxb_char_t **begin, size_t *length) } } +const lxb_encoding_data_t * +lxb_encoding_data_by_name(const lxb_char_t *name, size_t length) +{ + const lexbor_shs_entry_t *entry; + + if (length == 0) { + return NULL; + } + + entry = lexbor_shs_entry_get_lower_static(lxb_encoding_res_shs_entities, + name, length); + if (entry == NULL) { + return NULL; + } + + return (const lxb_encoding_data_t *) entry->value; +} + +const lxb_encoding_data_t * +lxb_encoding_data(lxb_encoding_t encoding) +{ + if (encoding >= LXB_ENCODING_LAST_ENTRY) { + return NULL; + } + + return &lxb_encoding_res_map[encoding]; +} + +lxb_encoding_encode_f +lxb_encoding_encode_function(lxb_encoding_t encoding) +{ + if (encoding >= LXB_ENCODING_LAST_ENTRY) { + return NULL; + } + + return lxb_encoding_res_map[encoding].encode; +} + +lxb_encoding_decode_f +lxb_encoding_decode_function(lxb_encoding_t encoding) +{ + if (encoding >= LXB_ENCODING_LAST_ENTRY) { + return NULL; + } + + return lxb_encoding_res_map[encoding].decode; +} + /* * No inline functions for ABI. */ diff --git a/ext/lexbor/lexbor/encoding/encoding.h b/ext/lexbor/lexbor/encoding/encoding.h index 7bda3ba5f56c..7e08a3687993 100644 --- a/ext/lexbor/lexbor/encoding/encoding.h +++ b/ext/lexbor/lexbor/encoding/encoding.h @@ -27,9 +27,18 @@ extern "C" { LXB_API const lxb_encoding_data_t * lxb_encoding_data_by_pre_name(const lxb_char_t *name, size_t length); +LXB_API lxb_encoding_t +lxb_encoding_prescan_validate(const lxb_char_t *name, size_t length); + +LXB_API const lxb_encoding_data_t * +lxb_encoding_data_prescan_validate(const lxb_char_t *name, size_t length); + /* * To skip BOM. */ +LXB_API lxb_encoding_t +lxb_encoding_bom_sniff(const lxb_char_t *begin, size_t length); + LXB_API void lxb_encoding_utf_8_skip_bom(const lxb_char_t **begin, size_t *length); @@ -39,6 +48,20 @@ lxb_encoding_utf_16be_skip_bom(const lxb_char_t **begin, size_t *length); LXB_API void lxb_encoding_utf_16le_skip_bom(const lxb_char_t **begin, size_t *length); +/* + * Encoding data. + */ +LXB_API const lxb_encoding_data_t * +lxb_encoding_data_by_name(const lxb_char_t *name, size_t length); + +LXB_API const lxb_encoding_data_t * +lxb_encoding_data(lxb_encoding_t encoding); + +LXB_API lxb_encoding_encode_f +lxb_encoding_encode_function(lxb_encoding_t encoding); + +LXB_API lxb_encoding_decode_f +lxb_encoding_decode_function(lxb_encoding_t encoding); /* * Inline functions @@ -305,54 +328,6 @@ lxb_encoding_decode_finish_single(lxb_encoding_decode_t *decode) /* * Encoding data. */ -lxb_inline const lxb_encoding_data_t * -lxb_encoding_data_by_name(const lxb_char_t *name, size_t length) -{ - const lexbor_shs_entry_t *entry; - - if (length == 0) { - return NULL; - } - - entry = lexbor_shs_entry_get_lower_static(lxb_encoding_res_shs_entities, - name, length); - if (entry == NULL) { - return NULL; - } - - return (const lxb_encoding_data_t *) entry->value; -} - -lxb_inline const lxb_encoding_data_t * -lxb_encoding_data(lxb_encoding_t encoding) -{ - if (encoding >= LXB_ENCODING_LAST_ENTRY) { - return NULL; - } - - return &lxb_encoding_res_map[encoding]; -} - -lxb_inline lxb_encoding_encode_f -lxb_encoding_encode_function(lxb_encoding_t encoding) -{ - if (encoding >= LXB_ENCODING_LAST_ENTRY) { - return NULL; - } - - return lxb_encoding_res_map[encoding].encode; -} - -lxb_inline lxb_encoding_decode_f -lxb_encoding_decode_function(lxb_encoding_t encoding) -{ - if (encoding >= LXB_ENCODING_LAST_ENTRY) { - return NULL; - } - - return lxb_encoding_res_map[encoding].decode; -} - lxb_inline lxb_status_t lxb_encoding_data_call_encode(lxb_encoding_data_t *encoding_data, lxb_encoding_encode_t *ctx, const lxb_codepoint_t **cp, const lxb_codepoint_t *end) diff --git a/ext/lexbor/lexbor/encoding/multi.c b/ext/lexbor/lexbor/encoding/multi.c index 78cd93ea82b1..2651648c5c96 100644 --- a/ext/lexbor/lexbor/encoding/multi.c +++ b/ext/lexbor/lexbor/encoding/multi.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/encoding/multi.h b/ext/lexbor/lexbor/encoding/multi.h index 4e6da7b4728b..a4c5def5ba6a 100644 --- a/ext/lexbor/lexbor/encoding/multi.h +++ b/ext/lexbor/lexbor/encoding/multi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Alexander Borisov + * Copyright (C) 2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -19,7 +19,7 @@ extern "C" { #include "lexbor/encoding/base.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN lxb_codepoint_t lxb_encoding_multi_big5_map[19782]; LXB_EXTERN lxb_codepoint_t lxb_encoding_multi_euc_kr_map[23750]; LXB_EXTERN lxb_codepoint_t lxb_encoding_multi_gb18030_map[23940]; @@ -53,161 +53,7 @@ LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_167_1106_map[939]; LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_8208_13262_map[5054]; LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_19968_40865_map[20897]; LXB_EXTERN uint16_t lxb_encoding_multi_jis0208_63785_65510_map[1725]; - -lxb_inline uint16_t -lxb_encoding_multi_big5_index(lxb_codepoint_t cp) -{ - if (cp > 0x2F8A7) { - return UINT16_MAX; - } - - if (cp < 65518) { - if (cp >= 167 && cp < 1106) { - return lxb_encoding_multi_big5_167_1106_map[cp - 167]; - } - else if (cp >= 8211) { - if (cp < 40882) { - return lxb_encoding_multi_big5_8211_40882_map[cp - 8211]; - } - else if (cp >= 64012) { - return lxb_encoding_multi_big5_64012_65518_map[cp - 64012]; - } - } - } - else if (cp >= 131210) { - if (cp < 172369) { - return lxb_encoding_multi_big5_131210_172369_map[cp - 131210]; - } - else if (cp >= 194708) { - if (cp < 194727) { - return lxb_encoding_multi_big5_194708_194727_map[cp - 194708]; - } - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_euc_kr_index(lxb_codepoint_t cp) -{ - if (cp > 0xFFE7) { - return UINT16_MAX; - } - - if (cp < 13278) { - if (cp >= 161 && cp < 1106) { - return lxb_encoding_multi_euc_kr_161_1106_map[cp - 161]; - } - else if (cp >= 8213) { - return lxb_encoding_multi_euc_kr_8213_13278_map[cp - 8213]; - } - } - else if (cp >= 19968) { - if (cp < 55204) { - return lxb_encoding_multi_euc_kr_19968_55204_map[cp - 19968]; - } - else if (cp >= 63744) { - if (cp < 65511) { - return lxb_encoding_multi_euc_kr_63744_65511_map[cp - 63744]; - } - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_gb18030_index(lxb_codepoint_t cp) -{ - if (cp > 0xFFE6) { - return UINT16_MAX; - } - - if (cp < 40892) { - if (cp >= 164 && cp < 1106) { - return lxb_encoding_multi_gb18030_164_1106_map[cp - 164]; - } - else if (cp >= 7743) { - return lxb_encoding_multi_gb18030_7743_40892_map[cp - 7743]; - } - } - else if (cp >= 57344) { - if (cp < 65510) { - return lxb_encoding_multi_gb18030_57344_65510_map[cp - 57344]; - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_iso_2022_jp_katakana_index(lxb_codepoint_t cp) -{ - if (cp >= 12289 && cp < 12541) { - return lxb_encoding_multi_iso_2022_jp_katakana_12289_12541_map[cp - 12289]; - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_jis0212_index(lxb_codepoint_t cp) -{ - if (cp > 0xFF5F) { - return UINT16_MAX; - } - - if (cp < 8483) { - if (cp >= 161 && cp < 1120) { - return lxb_encoding_multi_jis0212_161_1120_map[cp - 161]; - } - else if (cp >= 8470) { - return lxb_encoding_multi_jis0212_8470_8483_map[cp - 8470]; - } - } - else if (cp >= 19970) { - if (cp < 40870) { - return lxb_encoding_multi_jis0212_19970_40870_map[cp - 19970]; - } - else if (cp >= 65374) { - if (cp < 65375) { - return lxb_encoding_multi_jis0212_65374_65375_map[cp - 65374]; - } - } - } - - return UINT16_MAX; -} - -lxb_inline uint16_t -lxb_encoding_multi_jis0208_index(lxb_codepoint_t cp) -{ - if (cp > 0xFFE6) { - return UINT16_MAX; - } - - if (cp < 13262) { - if (cp >= 167 && cp < 1106) { - return lxb_encoding_multi_jis0208_167_1106_map[cp - 167]; - } - else if (cp >= 8208) { - return lxb_encoding_multi_jis0208_8208_13262_map[cp - 8208]; - } - } - else if (cp >= 19968) { - if (cp < 40865) { - return lxb_encoding_multi_jis0208_19968_40865_map[cp - 19968]; - } - else if (cp >= 63785) { - if (cp < 65510) { - return lxb_encoding_multi_jis0208_63785_65510_map[cp - 63785]; - } - } - } - - return UINT16_MAX; -} +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/encoding/range.h b/ext/lexbor/lexbor/encoding/range.h index 18b331034423..ed9833d1cce9 100644 --- a/ext/lexbor/lexbor/encoding/range.h +++ b/ext/lexbor/lexbor/encoding/range.h @@ -23,8 +23,9 @@ extern "C" { #define LXB_ENCODING_RANGE_INDEX_GB18030_SIZE 207 - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN const lxb_encoding_range_index_t lxb_encoding_range_index_gb18030[207]; +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/encoding/res.h b/ext/lexbor/lexbor/encoding/res.h index 46a9f91ae9a9..25334ebd27cf 100644 --- a/ext/lexbor/lexbor/encoding/res.h +++ b/ext/lexbor/lexbor/encoding/res.h @@ -22,10 +22,10 @@ extern "C" { #include "lexbor/encoding/base.h" #include "lexbor/core/shs.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN const lxb_encoding_data_t lxb_encoding_res_map[LXB_ENCODING_LAST_ENTRY]; LXB_EXTERN const lexbor_shs_entry_t lxb_encoding_res_shs_entities[220]; - +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/encoding/single.h b/ext/lexbor/lexbor/encoding/single.h index 906279bf33e7..c2a4271ac90c 100644 --- a/ext/lexbor/lexbor/encoding/single.h +++ b/ext/lexbor/lexbor/encoding/single.h @@ -51,7 +51,7 @@ extern "C" { #define LXB_ENCODING_SINGLE_HASH_WINDOWS_874_SIZE 359 #define LXB_ENCODING_SINGLE_HASH_X_MAC_CYRILLIC_SIZE 373 - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN LXB_EXTERN const lxb_encoding_single_index_t lxb_encoding_single_index_ibm866[128]; LXB_EXTERN const lxb_encoding_single_index_t lxb_encoding_single_index_iso_8859_10[128]; LXB_EXTERN const lxb_encoding_single_index_t lxb_encoding_single_index_iso_8859_13[128]; @@ -107,6 +107,7 @@ LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_windows_1257[356]; LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_windows_1258[406]; LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_windows_874[360]; LXB_EXTERN const lexbor_shs_hash_t lxb_encoding_single_hash_x_mac_cyrillic[374]; +#endif /* !LEXBOR_DISABLE_INTERNAL_EXTERN */ #ifdef __cplusplus diff --git a/ext/lexbor/lexbor/html/base.h b/ext/lexbor/lexbor/html/base.h index a701dc35c680..570222c6de5e 100644 --- a/ext/lexbor/lexbor/html/base.h +++ b/ext/lexbor/lexbor/html/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,7 +15,7 @@ extern "C" { #define LXB_HTML_VERSION_MAJOR 2 -#define LXB_HTML_VERSION_MINOR 6 +#define LXB_HTML_VERSION_MINOR 8 #define LXB_HTML_VERSION_PATCH 0 #define LXB_HTML_VERSION_STRING LEXBOR_STRINGIZE(LXB_HTML_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/html/encoding.c b/ext/lexbor/lexbor/html/encoding.c index 5368400dab84..857661246b5c 100644 --- a/ext/lexbor/lexbor/html/encoding.c +++ b/ext/lexbor/lexbor/html/encoding.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -9,6 +9,31 @@ #include "lexbor/core/str.h" +typedef struct { + lexbor_str_t alias; + lexbor_str_t name; +} +lxb_html_encoding_name_t; + +static const lxb_html_encoding_name_t lxb_html_encoding_names[] = { + /* UTF-16BE */ + { lexbor_str("unicodefffe"), lexbor_str("UTF-8") }, + { lexbor_str("utf-16be"), lexbor_str("UTF-8") }, + + /* UTF-16LE */ + { lexbor_str("csunicode"), lexbor_str("UTF-8") }, + { lexbor_str("iso-10646-ucs-2"), lexbor_str("UTF-8") }, + { lexbor_str("ucs-2"), lexbor_str("UTF-8") }, + { lexbor_str("unicode"), lexbor_str("UTF-8") }, + { lexbor_str("unicodefeff"), lexbor_str("UTF-8") }, + { lexbor_str("utf-16"), lexbor_str("UTF-8") }, + { lexbor_str("utf-16le"), lexbor_str("UTF-8") }, + + /* x-user-defined */ + { lexbor_str("x-user-defined"), lexbor_str("windows-1252") } +}; + + static const lxb_char_t * lxb_html_encoding_meta(lxb_html_encoding_t *em, const lxb_char_t *data, const lxb_char_t *end); @@ -99,6 +124,73 @@ lxb_html_encoding_destroy(lxb_html_encoding_t *em, bool self_destroy) return em; } +const lxb_char_t * +lxb_html_encoding_prescan(lxb_html_encoding_t *em, const lxb_char_t *data, + const lxb_char_t *end, size_t *out_length) +{ + size_t len, length; + lxb_status_t status; + lxb_html_encoding_entry_t *entry; + const lxb_html_encoding_name_t *name; + + static const lexbor_str_t lxb_html_encoding_utf_16le = lexbor_str("UTF-16LE"); + static const lexbor_str_t lxb_html_encoding_utf_16be = lexbor_str("UTF-16BE"); + + len = end - data; + + /* Prescan for UTF-16 XML declarations: If position points to. */ + if (len >= 6) { + if (data[0] == 0x3C && data[1] == 0x00 && data[2] == 0x3F + && data[3] == 0x00 && data[4] == 0x78 && data[5] == 0x00) + { + *out_length = lxb_html_encoding_utf_16le.length; + return lxb_html_encoding_utf_16le.data; + } + + if (data[0] == 0x00 && data[1] == 0x3C && data[2] == 0x00 + && data[3] == 0x3F && data[4] == 0x00 && data[5] == 0x78) + { + *out_length = lxb_html_encoding_utf_16be.length; + return lxb_html_encoding_utf_16be.data; + } + } + + status = lxb_html_encoding_determine(em, data, end); + if (status != LXB_STATUS_OK) { + goto EMPTY; + } + + if (lxb_html_encoding_meta_length(em) == 0) { + goto EMPTY; + } + + entry = lxb_html_encoding_meta_entry(em, 0); + len = entry->end - entry->name; + length = sizeof(lxb_html_encoding_names) / sizeof(lxb_html_encoding_name_t); + + for (size_t i = 0; i < length; i++) { + name = &lxb_html_encoding_names[i]; + + if (len == name->alias.length + && lexbor_str_data_ncasecmp(entry->name, name->alias.data, + name->alias.length)) + { + *out_length = lxb_html_encoding_names[i].name.length; + return lxb_html_encoding_names[i].name.data; + } + } + + *out_length = entry->end - entry->name; + + return entry->name; + +EMPTY: + + *out_length = 0; + + return NULL; +} + lxb_status_t lxb_html_encoding_determine(lxb_html_encoding_t *em, const lxb_char_t *data, const lxb_char_t *end) @@ -381,12 +473,12 @@ lxb_html_encoding_content(const lxb_char_t *data, const lxb_char_t *end, for (; data < end; data++) { if (*data == **name_end) { - break; + *name_end = data; + goto done; } } - *name_end = data; - goto done; + return NULL; } name = data; diff --git a/ext/lexbor/lexbor/html/encoding.h b/ext/lexbor/lexbor/html/encoding.h index ec65778f715e..ad5a6198f945 100644 --- a/ext/lexbor/lexbor/html/encoding.h +++ b/ext/lexbor/lexbor/html/encoding.h @@ -1,5 +1,14 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov + * + * Functions for detecting encoding in an HTML byte stream. + * + * The HTML parser accepts only UTF-8 input. The detected encoding can be used + * with the Encoding module to convert the original byte stream from its + * encoding to UTF-8 before passing it to the parser. + * + * By specification: + * https://html.spec.whatwg.org/#determining-the-character-encoding * * Author: Alexander Borisov */ @@ -12,12 +21,13 @@ extern "C" { #endif #include "lexbor/html/base.h" - #include "lexbor/core/array_obj.h" typedef struct { + /* Pointer to the beginning of the encoding name in the original data. */ const lxb_char_t *name; + /* Pointer to the end of the encoding name in the original data. */ const lxb_char_t *end; } lxb_html_encoding_entry_t; @@ -29,17 +39,101 @@ typedef struct { lxb_html_encoding_t; +/* + * Initialization of the lxb_html_encoding_t object. + * + * The object can be allocated on the stack or created using + * lxb_html_encoding_create() function. + * + * @param[in] lxb_html_encoding_t * + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ LXB_API lxb_status_t lxb_html_encoding_init(lxb_html_encoding_t *em); +/* + * Destruction of the lxb_html_encoding_t object. + * + * Releases internal resources of the object. + * If the object was created using lxb_html_encoding_create(), set self_destroy + * to true. + * + * @param[in] lxb_html_encoding_t * + * @param[in] If true, the object itself will be freed. + * + * @return NULL if self_destroy is true. Pointer to the object if false. + */ LXB_API lxb_html_encoding_t * lxb_html_encoding_destroy(lxb_html_encoding_t *em, bool self_destroy); +/* + * Prescan a byte stream to determine its encoding. + * + * By specification: + * https://html.spec.whatwg.org/#prescan-a-byte-stream-to-determine-its-encoding + * + * Returns the validated encoding name if found, or NULL otherwise. + * + * Important: + * The returned pointer is not guaranteed to point into the input data stream. + * It may reference an internal static string (e.g. when the found encoding name + * is matched against a known alias). Do not assume the returned pointer lies + * within the [data, end) range. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * @param[in] Pointer to the beginning of the data. Not NULL. + * @param[in] Pointer to the end of the data. Not NULL. + * @param[out] Length of the returned encoding name. Not NULL. + * + * @return Pointer to the encoding name, or NULL if no encoding was found. + */ +LXB_API const lxb_char_t * +lxb_html_encoding_prescan(lxb_html_encoding_t *em, const lxb_char_t *data, + const lxb_char_t *end, size_t *out_length); +/* + * Prescan a byte stream to determine its encoding. + * + * Implementation of the HTML specification algorithm for extracting encoding + * from tags. Scans raw HTML bytes looking for and + * declarations. + * + * Results can be retrieved using lxb_html_encoding_meta_entry() and + * lxb_html_encoding_meta_length() functions. + * + * Important: + * The HTML specification requires that if the determined charset is + * UTF-16BE/LE, it must be replaced with UTF-8, and if it is x-user-defined, + * it must be replaced with windows-1252. This function does not perform these + * replacements because it returns pointers to the original data (start and end + * of the found encoding name), which can be useful for developers. To get the + * validated encoding according to the specification, use the + * lxb_encoding_data_prescan_validate()/lxb_encoding_prescan_validate() + * functions from the Encoding module, or handle these cases manually. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * @param[in] Pointer to the beginning of the data. Not NULL. + * @param[in] Pointer to the end of the data. Not NULL. + * + * @return LXB_STATUS_OK if successful, otherwise an error status value. + */ LXB_API lxb_status_t lxb_html_encoding_determine(lxb_html_encoding_t *em, const lxb_char_t *data, const lxb_char_t *end); +/* + * Extract encoding name from a Content-Type string. + * + * Parses the value of a content attribute looking for "charset=" + * pattern. For example, from "text/html; charset=utf-8" extracts "utf-8". + * + * @param[in] Pointer to the beginning of the content string. Not NULL. + * @param[in] Pointer to the end of the content string. Not NULL. + * @param[out] Pointer to the end of the encoding name. Not NULL. + * + * @return Pointer to the beginning of the encoding name, or NULL if not found. + */ LXB_API const lxb_char_t * lxb_html_encoding_content(const lxb_char_t *data, const lxb_char_t *end, const lxb_char_t **name_end); @@ -48,6 +142,14 @@ lxb_html_encoding_content(const lxb_char_t *data, const lxb_char_t *end, /* * Inline functions */ + +/* + * Create an lxb_html_encoding_t object on the heap. + * + * The object must be initialized using lxb_html_encoding_init() after creation. + * + * @return Pointer to a new object, or NULL if memory allocation failed. + */ lxb_inline lxb_html_encoding_t * lxb_html_encoding_create(void) { @@ -55,6 +157,14 @@ lxb_html_encoding_create(void) sizeof(lxb_html_encoding_t)); } +/* + * Clean the lxb_html_encoding_t object for reuse. + * + * Resets internal state so the object can be used for a new prescan without + * reallocation. Does not free memory. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + */ lxb_inline void lxb_html_encoding_clean(lxb_html_encoding_t *em) { @@ -62,18 +172,45 @@ lxb_html_encoding_clean(lxb_html_encoding_t *em) lexbor_array_obj_clean(&em->result); } +/* + * Get an encoding entry from the results by index. + * + * Returns a pointer to the lxb_html_encoding_entry_t which contains pointers + * to the beginning and end of the encoding name in the original data. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * @param[in] Index of the entry. + * + * @return Pointer to the entry, or NULL if the index is out of bounds. + */ lxb_inline lxb_html_encoding_entry_t * lxb_html_encoding_meta_entry(lxb_html_encoding_t *em, size_t idx) { return (lxb_html_encoding_entry_t *) lexbor_array_obj_get(&em->result, idx); } +/* + * Get the number of encoding entries found. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * + * @return Number of entries in the result. + */ lxb_inline size_t lxb_html_encoding_meta_length(lxb_html_encoding_t *em) { return lexbor_array_obj_length(&em->result); } +/* + * Get the result array object directly. + * + * Returns the internal array of lxb_html_encoding_entry_t entries. + * + * @param[in] lxb_html_encoding_t *. Not NULL. + * + * @return Pointer to the lexbor_array_obj_t with results. + */ lxb_inline lexbor_array_obj_t * lxb_html_encoding_meta_result(lxb_html_encoding_t *em) { diff --git a/ext/lexbor/lexbor/html/interface.c b/ext/lexbor/lexbor/html/interface.c index 1e7156d92a41..1b2a57c813e9 100644 --- a/ext/lexbor/lexbor/html/interface.c +++ b/ext/lexbor/lexbor/html/interface.c @@ -26,30 +26,33 @@ lxb_html_interface_create(lxb_html_document_t *document, lxb_tag_id_t tag_id, lxb_ns_id_t ns) { lxb_dom_node_t *node; + lxb_dom_element_t *domel; + lxb_html_unknown_element_t *unel; if (tag_id >= LXB_TAG__LAST_ENTRY) { if (ns == LXB_NS_HTML) { - lxb_html_unknown_element_t *unel; - unel = lxb_html_unknown_element_interface_create(document); node = lxb_dom_interface_node(unel); } else if (ns == LXB_NS_SVG) { /* TODO: For this need implement SVGElement */ - lxb_dom_element_t *domel; domel = lxb_dom_element_interface_create(&document->dom_document); node = lxb_dom_interface_node(domel); } else { - lxb_dom_element_t *domel; - domel = lxb_dom_element_interface_create(&document->dom_document); node = lxb_dom_interface_node(domel); } } else { - node = lxb_html_interface_res_constructors[tag_id][ns](document); + if (ns < LXB_NS__LAST_ENTRY) { + node = lxb_html_interface_res_constructors[tag_id][ns](document); + } + else { + domel = lxb_dom_element_interface_create(&document->dom_document); + node = lxb_dom_interface_node(domel); + } } if (node == NULL) { diff --git a/ext/lexbor/lexbor/html/interface.h b/ext/lexbor/lexbor/html/interface.h index a58a9e7474d7..503bef6345ac 100644 --- a/ext/lexbor/lexbor/html/interface.h +++ b/ext/lexbor/lexbor/html/interface.h @@ -71,6 +71,7 @@ extern "C" { #define lxb_html_interface_quote(obj) ((lxb_html_quote_element_t *) (obj)) #define lxb_html_interface_script(obj) ((lxb_html_script_element_t *) (obj)) #define lxb_html_interface_select(obj) ((lxb_html_select_element_t *) (obj)) +#define lxb_html_interface_selectedcontent(obj) ((lxb_html_selectedcontent_element_t *) obj) #define lxb_html_interface_slot(obj) ((lxb_html_slot_element_t *) (obj)) #define lxb_html_interface_source(obj) ((lxb_html_source_element_t *) (obj)) #define lxb_html_interface_span(obj) ((lxb_html_span_element_t *) (obj)) @@ -146,6 +147,8 @@ typedef struct lxb_html_progress_element lxb_html_progress_element_t; typedef struct lxb_html_quote_element lxb_html_quote_element_t; typedef struct lxb_html_script_element lxb_html_script_element_t; typedef struct lxb_html_select_element lxb_html_select_element_t; +typedef struct lxb_html_selectedcontent_element lxb_html_selectedcontent_element_t; +typedef struct lxb_html_search_element lxb_html_search_element_t; typedef struct lxb_html_slot_element lxb_html_slot_element_t; typedef struct lxb_html_source_element lxb_html_source_element_t; typedef struct lxb_html_span_element lxb_html_span_element_t; diff --git a/ext/lexbor/lexbor/html/interface_res.h b/ext/lexbor/lexbor/html/interface_res.h index 08667af19ba8..8a2f765c30ff 100644 --- a/ext/lexbor/lexbor/html/interface_res.h +++ b/ext/lexbor/lexbor/html/interface_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,12 +14,10 @@ #ifndef LXB_HTML_INTERFACE_RES_H #define LXB_HTML_INTERFACE_RES_H -#endif /* LXB_HTML_INTERFACE_RES_H */ - #ifdef LXB_TAG_CONST_VERSION -#ifndef LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#ifndef LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 #error Mismatched tags version! See "lexbor/tag/const.h". -#endif /* LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 */ +#endif /* LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 */ #else #error You need to include "lexbor/tag/const.h". #endif /* LXB_TAG_CONST_VERSION */ @@ -97,7 +95,9 @@ #include "lexbor/html/interfaces/progress_element.h" #include "lexbor/html/interfaces/quote_element.h" #include "lexbor/html/interfaces/script_element.h" +#include "lexbor/html/interfaces/search_element.h" #include "lexbor/html/interfaces/select_element.h" +#include "lexbor/html/interfaces/selectedcontent_element.h" #include "lexbor/html/interfaces/slot_element.h" #include "lexbor/html/interfaces/source_element.h" #include "lexbor/html/interfaces/span_element.h" @@ -118,4332 +118,5305 @@ #include "lexbor/html/interfaces/video_element.h" #include "lexbor/html/interfaces/window.h" -#ifdef LXB_HTML_INTERFACE_RES_CONSTRUCTORS -#ifndef LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED -#define LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED +lxb_inline void * +lxb_dom_element_interface_create_wrapper(void *interface) +{ + return lxb_dom_element_interface_create(interface); +} + +lxb_inline void * +lxb_dom_element_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_element_interface_create_wrapper(void *interface) +{ + return lxb_html_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_dom_text_interface_create_wrapper(void *interface) +{ + return lxb_dom_text_interface_create(interface); +} + +lxb_inline void * +lxb_dom_text_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_text_interface_destroy(interface); +} + +lxb_inline void * +lxb_dom_document_interface_create_wrapper(void *interface) +{ + return lxb_dom_document_interface_create(interface); +} + +lxb_inline void * +lxb_dom_document_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_document_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_document_interface_create_wrapper(void *interface) +{ + return lxb_html_document_interface_create(interface); +} + +lxb_inline void * +lxb_html_document_interface_destroy_wrapper(void *interface) +{ + return lxb_html_document_interface_destroy(interface); +} + +lxb_inline void * +lxb_dom_comment_interface_create_wrapper(void *interface) +{ + return lxb_dom_comment_interface_create(interface); +} + +lxb_inline void * +lxb_dom_comment_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_comment_interface_destroy(interface); +} + +lxb_inline void * +lxb_dom_document_type_interface_create_wrapper(void *interface) +{ + return lxb_dom_document_type_interface_create(interface); +} + +lxb_inline void * +lxb_dom_document_type_interface_destroy_wrapper(void *interface) +{ + return lxb_dom_document_type_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_anchor_element_interface_create_wrapper(void *interface) +{ + return lxb_html_anchor_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_anchor_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_anchor_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_unknown_element_interface_create_wrapper(void *interface) +{ + return lxb_html_unknown_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_unknown_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_unknown_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_area_element_interface_create_wrapper(void *interface) +{ + return lxb_html_area_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_area_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_area_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_audio_element_interface_create_wrapper(void *interface) +{ + return lxb_html_audio_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_audio_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_audio_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_base_element_interface_create_wrapper(void *interface) +{ + return lxb_html_base_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_base_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_base_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_quote_element_interface_create_wrapper(void *interface) +{ + return lxb_html_quote_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_quote_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_quote_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_body_element_interface_create_wrapper(void *interface) +{ + return lxb_html_body_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_body_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_body_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_br_element_interface_create_wrapper(void *interface) +{ + return lxb_html_br_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_br_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_br_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_button_element_interface_create_wrapper(void *interface) +{ + return lxb_html_button_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_button_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_button_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_canvas_element_interface_create_wrapper(void *interface) +{ + return lxb_html_canvas_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_canvas_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_canvas_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_caption_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_caption_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_caption_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_caption_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_col_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_col_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_col_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_col_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_data_element_interface_create_wrapper(void *interface) +{ + return lxb_html_data_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_data_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_data_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_data_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_data_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_data_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_data_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_mod_element_interface_create_wrapper(void *interface) +{ + return lxb_html_mod_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_mod_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_mod_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_details_element_interface_create_wrapper(void *interface) +{ + return lxb_html_details_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_details_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_details_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_dialog_element_interface_create_wrapper(void *interface) +{ + return lxb_html_dialog_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_dialog_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_dialog_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_directory_element_interface_create_wrapper(void *interface) +{ + return lxb_html_directory_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_directory_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_directory_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_div_element_interface_create_wrapper(void *interface) +{ + return lxb_html_div_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_div_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_div_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_d_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_d_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_d_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_d_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_embed_element_interface_create_wrapper(void *interface) +{ + return lxb_html_embed_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_embed_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_embed_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_field_set_element_interface_create_wrapper(void *interface) +{ + return lxb_html_field_set_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_field_set_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_field_set_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_font_element_interface_create_wrapper(void *interface) +{ + return lxb_html_font_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_font_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_font_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_form_element_interface_create_wrapper(void *interface) +{ + return lxb_html_form_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_form_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_form_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_frame_element_interface_create_wrapper(void *interface) +{ + return lxb_html_frame_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_frame_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_frame_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_frame_set_element_interface_create_wrapper(void *interface) +{ + return lxb_html_frame_set_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_frame_set_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_frame_set_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_heading_element_interface_create_wrapper(void *interface) +{ + return lxb_html_heading_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_heading_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_heading_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_head_element_interface_create_wrapper(void *interface) +{ + return lxb_html_head_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_head_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_head_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_hr_element_interface_create_wrapper(void *interface) +{ + return lxb_html_hr_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_hr_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_hr_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_html_element_interface_create_wrapper(void *interface) +{ + return lxb_html_html_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_html_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_html_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_iframe_element_interface_create_wrapper(void *interface) +{ + return lxb_html_iframe_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_iframe_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_iframe_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_image_element_interface_create_wrapper(void *interface) +{ + return lxb_html_image_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_image_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_image_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_input_element_interface_create_wrapper(void *interface) +{ + return lxb_html_input_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_input_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_input_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_label_element_interface_create_wrapper(void *interface) +{ + return lxb_html_label_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_label_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_label_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_legend_element_interface_create_wrapper(void *interface) +{ + return lxb_html_legend_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_legend_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_legend_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_li_element_interface_create_wrapper(void *interface) +{ + return lxb_html_li_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_li_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_li_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_link_element_interface_create_wrapper(void *interface) +{ + return lxb_html_link_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_link_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_link_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_pre_element_interface_create_wrapper(void *interface) +{ + return lxb_html_pre_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_pre_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_pre_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_map_element_interface_create_wrapper(void *interface) +{ + return lxb_html_map_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_map_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_map_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_marquee_element_interface_create_wrapper(void *interface) +{ + return lxb_html_marquee_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_marquee_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_marquee_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_menu_element_interface_create_wrapper(void *interface) +{ + return lxb_html_menu_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_menu_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_menu_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_meta_element_interface_create_wrapper(void *interface) +{ + return lxb_html_meta_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_meta_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_meta_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_meter_element_interface_create_wrapper(void *interface) +{ + return lxb_html_meter_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_meter_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_meter_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_object_element_interface_create_wrapper(void *interface) +{ + return lxb_html_object_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_object_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_object_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_o_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_o_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_o_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_o_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_opt_group_element_interface_create_wrapper(void *interface) +{ + return lxb_html_opt_group_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_opt_group_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_opt_group_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_option_element_interface_create_wrapper(void *interface) +{ + return lxb_html_option_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_option_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_option_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_output_element_interface_create_wrapper(void *interface) +{ + return lxb_html_output_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_output_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_output_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_paragraph_element_interface_create_wrapper(void *interface) +{ + return lxb_html_paragraph_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_paragraph_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_paragraph_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_param_element_interface_create_wrapper(void *interface) +{ + return lxb_html_param_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_param_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_param_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_picture_element_interface_create_wrapper(void *interface) +{ + return lxb_html_picture_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_picture_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_picture_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_progress_element_interface_create_wrapper(void *interface) +{ + return lxb_html_progress_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_progress_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_progress_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_script_element_interface_create_wrapper(void *interface) +{ + return lxb_html_script_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_script_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_script_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_search_element_interface_create_wrapper(void *interface) +{ + return lxb_html_search_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_search_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_search_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_select_element_interface_create_wrapper(void *interface) +{ + return lxb_html_select_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_select_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_select_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_selectedcontent_element_interface_create_wrapper(void *interface) +{ + return lxb_html_selectedcontent_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_selectedcontent_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_selectedcontent_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_slot_element_interface_create_wrapper(void *interface) +{ + return lxb_html_slot_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_slot_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_slot_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_source_element_interface_create_wrapper(void *interface) +{ + return lxb_html_source_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_source_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_source_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_span_element_interface_create_wrapper(void *interface) +{ + return lxb_html_span_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_span_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_span_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_style_element_interface_create_wrapper(void *interface) +{ + return lxb_html_style_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_style_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_style_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_section_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_section_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_section_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_section_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_cell_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_cell_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_cell_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_cell_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_template_element_interface_create_wrapper(void *interface) +{ + return lxb_html_template_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_template_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_template_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_text_area_element_interface_create_wrapper(void *interface) +{ + return lxb_html_text_area_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_text_area_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_text_area_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_time_element_interface_create_wrapper(void *interface) +{ + return lxb_html_time_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_time_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_time_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_title_element_interface_create_wrapper(void *interface) +{ + return lxb_html_title_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_title_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_title_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_table_row_element_interface_create_wrapper(void *interface) +{ + return lxb_html_table_row_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_table_row_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_table_row_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_track_element_interface_create_wrapper(void *interface) +{ + return lxb_html_track_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_track_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_track_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_u_list_element_interface_create_wrapper(void *interface) +{ + return lxb_html_u_list_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_u_list_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_u_list_element_interface_destroy(interface); +} + +lxb_inline void * +lxb_html_video_element_interface_create_wrapper(void *interface) +{ + return lxb_html_video_element_interface_create(interface); +} + +lxb_inline void * +lxb_html_video_element_interface_destroy_wrapper(void *interface) +{ + return lxb_html_video_element_interface_destroy(interface); +} + + static lxb_dom_interface_constructor_f lxb_html_interface_res_constructors[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG__END_OF_FILE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG__TEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_text_interface_create_wrapper }, /* LXB_TAG__DOCUMENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_document_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_interface_create_wrapper }, /* LXB_TAG__EM_COMMENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_comment_interface_create_wrapper }, /* LXB_TAG__EM_DOCTYPE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_document_type_interface_create_wrapper }, /* LXB_TAG_A */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_anchor_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_anchor_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ABBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ACRONYM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ADDRESS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ALTGLYPH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ALTGLYPHDEF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ALTGLYPHITEM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANIMATECOLOR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANIMATEMOTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANIMATETRANSFORM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ANNOTATION_XML */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_APPLET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_AREA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_area_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_area_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ARTICLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ASIDE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_AUDIO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_audio_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_audio_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_B */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BASE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_base_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_base_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BASEFONT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BDI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BDO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BGSOUND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BIG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BLINK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BLOCKQUOTE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BODY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_body_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_body_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_br_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_br_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_BUTTON */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_button_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_button_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CANVAS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_canvas_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_canvas_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CAPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_caption_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_caption_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CENTER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CITE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CLIPPATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_CODE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_COL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_COLGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_col_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DATA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_data_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_data_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DATALIST */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_data_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_data_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DEL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DESC */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DETAILS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_details_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_details_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DFN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DIALOG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_dialog_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_dialog_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DIR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_directory_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_directory_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DIV */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_div_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_div_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_d_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_d_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_DT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_EM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_EMBED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_embed_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_embed_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEBLEND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECOLORMATRIX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECOMPOSITE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FECONVOLVEMATRIX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDISTANTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEDROPSHADOW */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFLOOD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEFUNCR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEGAUSSIANBLUR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEIMAGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEMERGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEMERGENODE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEMORPHOLOGY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEOFFSET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FEPOINTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FESPECULARLIGHTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FESPOTLIGHT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FETILE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FETURBULENCE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FIELDSET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_field_set_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_field_set_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FIGCAPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FIGURE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FONT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_font_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_font_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FOOTER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FOREIGNOBJECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FORM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_form_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_form_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FRAME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_frame_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_frame_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_FRAMESET */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_frame_set_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_frame_set_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_GLYPHREF */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H1 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H2 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H3 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H4 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H5 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_H6 */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_heading_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HEAD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_head_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_head_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HEADER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_hr_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_hr_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_HTML */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_I */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_IFRAME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_iframe_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_iframe_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_IMAGE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_IMG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_image_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_INPUT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_input_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_input_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_INS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_mod_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_ISINDEX */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_KBD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_KEYGEN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LABEL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_label_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_label_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LEGEND */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_legend_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_legend_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_li_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_li_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LINEARGRADIENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LINK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_link_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_link_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_LISTING */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MAIN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MALIGNMARK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MAP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_map_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_map_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MARK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MARQUEE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_marquee_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_marquee_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MENU */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_menu_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_menu_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_META */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_meta_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_meta_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_METER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_meter_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_meter_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MFENCED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MGLYPH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MI */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MTEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_MULTICOL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NAV */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NEXTID */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOEMBED */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOFRAMES */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_NOSCRIPT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OBJECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_object_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_object_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_o_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_o_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OPTGROUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_opt_group_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_opt_group_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OPTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_option_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_option_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_OUTPUT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_output_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_output_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_P */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_paragraph_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_paragraph_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PARAM */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_param_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_param_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PICTURE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_picture_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_picture_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PLAINTEXT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PRE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_PROGRESS */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_progress_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_progress_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_Q */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_quote_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RADIALGRADIENT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RTC */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_RUBY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_S */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SAMP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SCRIPT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_script_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_script_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + }, + /* LXB_TAG_SEARCH */ + { + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_search_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SECTION */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SELECT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_select_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_select_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper + }, + /* LXB_TAG_SELECTEDCONTENT */ + { + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_selectedcontent_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SLOT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_slot_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_slot_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SMALL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SOURCE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_source_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_source_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SPACER */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SPAN */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_span_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_span_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_STRIKE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_STRONG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_STYLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_style_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_style_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SUB */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SUMMARY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SUP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_SVG */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TABLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TBODY */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TEMPLATE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_template_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_template_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TEXTAREA */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_text_area_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_text_area_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TEXTPATH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TFOOT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TH */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_cell_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_THEAD */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_section_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TIME */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_time_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_time_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TITLE */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_title_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_title_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_table_row_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_table_row_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TRACK */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_track_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_track_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_TT */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_U */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_UL */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_u_list_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_u_list_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_VAR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_VIDEO */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_video_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_video_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_WBR */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper }, /* LXB_TAG_XMP */ { - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_unknown_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create, - (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_html_pre_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper, + (lxb_dom_interface_constructor_f) lxb_dom_element_interface_create_wrapper } }; -#endif /* LXB_HTML_INTERFACE_RES_CONSTRUCTORS_ENABLED */ -#endif /* LXB_HTML_INTERFACE_RES_CONSTRUCTORS */ -#ifdef LXB_HTML_INTERFACE_RES_DESTRUCTOR -#ifndef LXB_HTML_INTERFACE_RES_DESTRUCTOR_ENABLED -#define LXB_HTML_INTERFACE_RES_DESTRUCTOR_ENABLED static lxb_dom_interface_destructor_f lxb_html_interface_res_destructor[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG__END_OF_FILE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG__TEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_text_interface_destroy_wrapper }, /* LXB_TAG__DOCUMENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_document_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_interface_destroy_wrapper }, /* LXB_TAG__EM_COMMENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_comment_interface_destroy_wrapper }, /* LXB_TAG__EM_DOCTYPE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_document_type_interface_destroy_wrapper }, /* LXB_TAG_A */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_anchor_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_anchor_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ABBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ACRONYM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ADDRESS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ALTGLYPH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ALTGLYPHDEF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ALTGLYPHITEM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANIMATECOLOR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANIMATEMOTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANIMATETRANSFORM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ANNOTATION_XML */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_APPLET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_AREA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_area_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_area_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ARTICLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ASIDE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_AUDIO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_audio_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_audio_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_B */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BASE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_base_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_base_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BASEFONT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BDI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BDO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BGSOUND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BIG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BLINK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BLOCKQUOTE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BODY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_body_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_body_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_br_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_br_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_BUTTON */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_button_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_button_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CANVAS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_canvas_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_canvas_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CAPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_caption_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_caption_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CENTER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CITE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CLIPPATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_CODE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_COL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_COLGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_col_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DATA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_data_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_data_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DATALIST */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_data_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_data_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DEL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DESC */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DETAILS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_details_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_details_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DFN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DIALOG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_dialog_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_dialog_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DIR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_directory_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_directory_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DIV */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_div_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_div_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_d_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_d_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_DT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_EM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_EMBED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_embed_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_embed_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEBLEND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECOLORMATRIX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECOMPOSITE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FECONVOLVEMATRIX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDISTANTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEDROPSHADOW */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFLOOD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEFUNCR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEGAUSSIANBLUR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEIMAGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEMERGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEMERGENODE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEMORPHOLOGY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEOFFSET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FEPOINTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FESPECULARLIGHTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FESPOTLIGHT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FETILE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FETURBULENCE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FIELDSET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_field_set_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_field_set_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FIGCAPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FIGURE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FONT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_font_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_font_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FOOTER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FOREIGNOBJECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FORM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_form_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_form_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FRAME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_frame_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_frame_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_FRAMESET */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_frame_set_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_frame_set_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_GLYPHREF */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H1 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H2 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H3 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H4 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H5 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_H6 */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_heading_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HEAD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_head_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_head_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HEADER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_hr_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_hr_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_HTML */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_I */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_IFRAME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_iframe_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_iframe_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_IMAGE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_IMG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_image_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_INPUT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_input_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_input_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_INS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_mod_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_ISINDEX */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_KBD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_KEYGEN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LABEL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_label_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_label_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LEGEND */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_legend_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_legend_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_li_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_li_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LINEARGRADIENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LINK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_link_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_link_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_LISTING */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MAIN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MALIGNMARK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MAP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_map_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_map_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MARK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MARQUEE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_marquee_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_marquee_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MENU */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_menu_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_menu_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_META */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_meta_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_meta_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_METER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_meter_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_meter_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MFENCED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MGLYPH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MI */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MTEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_MULTICOL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NAV */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NEXTID */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOEMBED */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOFRAMES */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_NOSCRIPT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OBJECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_object_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_object_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_o_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_o_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OPTGROUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_opt_group_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_opt_group_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OPTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_option_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_option_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_OUTPUT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_output_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_output_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_P */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_paragraph_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_paragraph_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PARAM */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_param_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_param_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PICTURE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_picture_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_picture_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PLAINTEXT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PRE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_PROGRESS */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_progress_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_progress_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_Q */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_quote_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RADIALGRADIENT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RTC */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_RUBY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_S */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SAMP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SCRIPT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_script_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_script_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + }, + /* LXB_TAG_SEARCH */ + { + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_search_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SECTION */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SELECT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_select_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_select_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper + }, + /* LXB_TAG_SELECTEDCONTENT */ + { + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_selectedcontent_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SLOT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_slot_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_slot_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SMALL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SOURCE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_source_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_source_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SPACER */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SPAN */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_span_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_span_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_STRIKE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_STRONG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_STYLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_style_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_style_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SUB */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SUMMARY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SUP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_SVG */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TABLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TBODY */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TEMPLATE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_template_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_template_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TEXTAREA */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_text_area_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_text_area_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TEXTPATH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TFOOT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TH */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_cell_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_THEAD */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_section_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TIME */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_time_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_time_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TITLE */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_title_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_title_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_table_row_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_table_row_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TRACK */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_track_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_track_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_TT */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_U */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_UL */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_u_list_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_u_list_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_VAR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_VIDEO */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_video_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_video_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_WBR */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper }, /* LXB_TAG_XMP */ { - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_unknown_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy, - (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_html_pre_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper, + (lxb_dom_interface_destructor_f) lxb_dom_element_interface_destroy_wrapper } }; -#endif /* LXB_HTML_INTERFACE_RES_DESTRUCTOR_ENABLED */ -#endif /* LXB_HTML_INTERFACE_RES_DESTRUCTOR */ + +#endif /* LXB_HTML_INTERFACE_RES_H */ diff --git a/ext/lexbor/lexbor/html/interfaces/document.c b/ext/lexbor/lexbor/html/interfaces/document.c index 48f8403a9e91..b40c6c8692f1 100644 --- a/ext/lexbor/lexbor/html/interfaces/document.c +++ b/ext/lexbor/lexbor/html/interfaces/document.c @@ -11,16 +11,18 @@ #include "lexbor/html/interfaces/style_element.h" #include "lexbor/html/node.h" #include "lexbor/html/parser.h" +#include "lexbor/html/tokenizer.h" #include "lexbor/tag/tag.h" #include "lexbor/dom/interfaces/text.h" #include "lexbor/dom/interfaces/element.h" -#define LXB_HTML_TAG_RES_DATA -#define LXB_HTML_TAG_RES_SHS_DATA -#include "lexbor/html/tag_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY]; + LXB_EXTERN lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY]; +#endif lxb_status_t lxb_html_parse_chunk_prepare(lxb_html_parser_t *parser, @@ -33,12 +35,19 @@ static lexbor_action_t lxb_html_document_title_walker(lxb_dom_node_t *node, void *ctx); +lxb_inline lxb_dom_interface_t * +lxb_html_document_interface_create_handler(lxb_dom_document_t *document, + lxb_tag_id_t tag_id, lxb_ns_id_t ns) +{ + return lxb_html_interface_create(lxb_html_interface_document(document), + tag_id, ns); +} + lxb_html_document_t * lxb_html_document_interface_create(lxb_html_document_t *document) { lxb_status_t status; lxb_dom_document_t *doc; - lxb_dom_interface_create_f icreator; if (document != NULL) { doc = lexbor_mraw_calloc(lxb_html_document_mraw(document), @@ -52,10 +61,9 @@ lxb_html_document_interface_create(lxb_html_document_t *document) return NULL; } - icreator = (lxb_dom_interface_create_f) lxb_html_interface_create; - status = lxb_dom_document_init(doc, lxb_dom_interface_document(document), - icreator, lxb_html_interface_clone, + lxb_html_document_interface_create_handler, + lxb_html_interface_clone, lxb_html_interface_destroy, LXB_DOM_DOCUMENT_DTYPE_HTML, LXB_NS_HTML); if (status != LXB_STATUS_OK) { @@ -261,6 +269,7 @@ lxb_html_document_parser_prepare(lxb_html_document_t *document) { lxb_status_t status; lxb_dom_document_t *doc; + lxb_html_parser_t *parser; doc = lxb_dom_interface_document(document); @@ -272,6 +281,10 @@ lxb_html_document_parser_prepare(lxb_html_document_t *document) lxb_html_parser_destroy(doc->parser); return status; } + + parser = doc->parser; + + lxb_html_tokenizer_keep_duplicate_set(parser->tkz, true); } else if (lxb_html_parser_state(doc->parser) != LXB_HTML_PARSER_STATE_BEGIN) { lxb_html_parser_clean(doc->parser); diff --git a/ext/lexbor/lexbor/html/interfaces/option_element.c b/ext/lexbor/lexbor/html/interfaces/option_element.c index 77e1e23d3878..19f085da0423 100644 --- a/ext/lexbor/lexbor/html/interfaces/option_element.c +++ b/ext/lexbor/lexbor/html/interfaces/option_element.c @@ -5,6 +5,8 @@ */ #include "lexbor/html/interfaces/option_element.h" +#include "lexbor/html/interfaces/select_element.h" +#include "lexbor/html/interfaces/selectedcontent_element.h" #include "lexbor/html/interfaces/document.h" @@ -33,3 +35,48 @@ lxb_html_option_element_interface_destroy(lxb_html_option_element_t *option_elem (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(option_element)); return NULL; } + +lxb_dom_exception_code_t +lxb_html_option_maybe_clone_to_selectedcontent(lxb_html_option_element_t *option) +{ + bool is; + lxb_dom_node_t *select; + lxb_html_select_element_t *select_el; + lxb_html_selectedcontent_element_t *sel_content; + + is = lxb_html_option_element_selectedness(lxb_html_interface_option(option)); + if (!is) { + return LXB_DOM_EXCEPTION_OK; + } + + select = lxb_dom_interface_node(option); + + do { + select = select->parent; + + if (select == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + } + while (select->local_name != LXB_TAG_SELECT || select->ns != LXB_NS_HTML); + + select_el = lxb_html_interface_select(select); + + sel_content = lxb_html_select_get_enabled_selectedcontent(select_el); + if (sel_content == NULL) { + return LXB_DOM_EXCEPTION_OK; + } + + return lxb_html_selectedcontent_clone_option(sel_content, option); +} + +bool +lxb_html_option_element_selectedness(lxb_html_option_element_t *option) +{ + lxb_dom_attr_t *selected; + + selected = lxb_dom_element_attr_by_id(lxb_dom_interface_element(option), + LXB_DOM_ATTR_SELECTED); + + return selected != NULL; +} diff --git a/ext/lexbor/lexbor/html/interfaces/option_element.h b/ext/lexbor/lexbor/html/interfaces/option_element.h index a59763898def..99d4977aa031 100644 --- a/ext/lexbor/lexbor/html/interfaces/option_element.h +++ b/ext/lexbor/lexbor/html/interfaces/option_element.h @@ -27,6 +27,13 @@ LXB_API lxb_html_option_element_t * lxb_html_option_element_interface_destroy(lxb_html_option_element_t *option_element); +LXB_API lxb_dom_exception_code_t +lxb_html_option_maybe_clone_to_selectedcontent(lxb_html_option_element_t *option); + +LXB_API bool +lxb_html_option_element_selectedness(lxb_html_option_element_t *option); + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/ext/lexbor/lexbor/html/interfaces/search_element.c b/ext/lexbor/lexbor/html/interfaces/search_element.c new file mode 100644 index 000000000000..00ca2a6ba3fc --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/search_element.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/html/interfaces/search_element.h" +#include "lexbor/html/interfaces/document.h" + + +lxb_html_search_element_t * +lxb_html_search_element_interface_create(lxb_html_document_t *document) +{ + lxb_html_search_element_t *element; + + element = lexbor_mraw_calloc(document->dom_document.mraw, + sizeof(lxb_html_search_element_t)); + if (element == NULL) { + return NULL; + } + + lxb_dom_node_t *node = lxb_dom_interface_node(element); + + node->owner_document = lxb_html_document_original_ref(document); + node->type = LXB_DOM_NODE_TYPE_ELEMENT; + + return element; +} + +lxb_html_search_element_t * +lxb_html_search_element_interface_destroy(lxb_html_search_element_t *search_element) +{ + (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(search_element)); + return NULL; +} diff --git a/ext/lexbor/lexbor/html/interfaces/search_element.h b/ext/lexbor/lexbor/html/interfaces/search_element.h new file mode 100644 index 000000000000..a42862176409 --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/search_element.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#ifndef LEXBOR_HTML_SEARCH_ELEMENT_H +#define LEXBOR_HTML_SEARCH_ELEMENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lexbor/html/interface.h" +#include "lexbor/html/interfaces/element.h" + + +struct lxb_html_search_element { + lxb_html_element_t element; +}; + + +LXB_API lxb_html_search_element_t * +lxb_html_search_element_interface_create(lxb_html_document_t *document); + +LXB_API lxb_html_search_element_t * +lxb_html_search_element_interface_destroy(lxb_html_search_element_t *search_element); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LEXBOR_HTML_SEARCH_ELEMENT_H */ diff --git a/ext/lexbor/lexbor/html/interfaces/select_element.c b/ext/lexbor/lexbor/html/interfaces/select_element.c index 69f8abe8dd51..8b338dc76da7 100644 --- a/ext/lexbor/lexbor/html/interfaces/select_element.c +++ b/ext/lexbor/lexbor/html/interfaces/select_element.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -8,6 +8,10 @@ #include "lexbor/html/interfaces/document.h" +static lexbor_action_t +lxb_html_select_find_selectedcontent_cb(lxb_dom_node_t *node, void *ctx); + + lxb_html_select_element_t * lxb_html_select_element_interface_create(lxb_html_document_t *document) { @@ -33,3 +37,44 @@ lxb_html_select_element_interface_destroy(lxb_html_select_element_t *select_elem (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(select_element)); return NULL; } + +lxb_html_selectedcontent_element_t * +lxb_html_select_get_enabled_selectedcontent(lxb_html_select_element_t *el) +{ + lxb_dom_attr_t *multiple; + lxb_dom_node_t *selectedcontent, *node; + + multiple = lxb_dom_element_attr_by_id(lxb_dom_interface_element(el), + LXB_DOM_ATTR_MULTIPLE); + if (multiple != NULL) { + return NULL; + } + + selectedcontent = NULL; + node = lxb_dom_interface_node(el); + + lxb_dom_node_simple_walk(node, lxb_html_select_find_selectedcontent_cb, + &selectedcontent); + if (selectedcontent == NULL) { + return NULL; + } + + return lxb_html_interface_selectedcontent(selectedcontent); +} + +static lexbor_action_t +lxb_html_select_find_selectedcontent_cb(lxb_dom_node_t *node, void *ctx) +{ + lxb_dom_node_t **selectedcontent; + + if (node->local_name == LXB_TAG_SELECTEDCONTENT + && node->ns == LXB_NS_HTML) + { + selectedcontent = ctx; + *selectedcontent = node; + + return LEXBOR_ACTION_STOP; + } + + return LEXBOR_ACTION_OK; +} diff --git a/ext/lexbor/lexbor/html/interfaces/select_element.h b/ext/lexbor/lexbor/html/interfaces/select_element.h index 8676db5da902..03e20d197cd3 100644 --- a/ext/lexbor/lexbor/html/interfaces/select_element.h +++ b/ext/lexbor/lexbor/html/interfaces/select_element.h @@ -26,6 +26,8 @@ lxb_html_select_element_interface_create(lxb_html_document_t *document); LXB_API lxb_html_select_element_t * lxb_html_select_element_interface_destroy(lxb_html_select_element_t *select_element); +LXB_API lxb_html_selectedcontent_element_t * +lxb_html_select_get_enabled_selectedcontent(lxb_html_select_element_t *el); #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.c b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.c new file mode 100644 index 000000000000..41b1c0d58b8f --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2025 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/dom/interfaces/document_fragment.h" +#include "lexbor/html/interfaces/selectedcontent_element.h" +#include "lexbor/html/interfaces/document.h" + + +lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_create(lxb_html_document_t *document) +{ + lxb_html_selectedcontent_element_t *element; + + element = lexbor_mraw_calloc(document->dom_document.mraw, + sizeof(lxb_html_selectedcontent_element_t)); + if (element == NULL) { + return NULL; + } + + lxb_dom_node_t *node = lxb_dom_interface_node(element); + + node->owner_document = lxb_html_document_original_ref(document); + node->type = LXB_DOM_NODE_TYPE_ELEMENT; + + return element; +} + +lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_destroy(lxb_html_selectedcontent_element_t *selectedcontent_element) +{ + (void) lxb_dom_node_interface_destroy(lxb_dom_interface_node(selectedcontent_element)); + return NULL; +} + +lxb_dom_exception_code_t +lxb_html_selectedcontent_clone_option(lxb_html_selectedcontent_element_t *sc, + lxb_html_option_element_t *option) +{ + lxb_dom_node_t *node, *child, *opt_node; + lxb_dom_document_fragment_t fragment; + + memset(&fragment, 0x00, sizeof(lxb_dom_document_fragment_t)); + + opt_node = lxb_dom_interface_node(option); + + fragment.node.type = LXB_DOM_NODE_TYPE_DOCUMENT_FRAGMENT; + fragment.node.owner_document = opt_node->owner_document; + + node = opt_node->first_child; + + while (node != NULL) { + child = lxb_dom_node_clone(node, true); + if (child == NULL) { + return LXB_DOM_EXCEPTION_ERR; + } + + lxb_dom_node_insert_child_wo_events(lxb_dom_interface_node(&fragment), + child); + node = node->next; + } + + return lxb_dom_node_replace_all_spec(lxb_dom_interface_node(sc), + lxb_dom_interface_node(&fragment)); +} diff --git a/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.h b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.h new file mode 100644 index 000000000000..5d38b59f501c --- /dev/null +++ b/ext/lexbor/lexbor/html/interfaces/selectedcontent_element.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2025 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#ifndef LEXBOR_HTML_SELECTEDCONTENT_ELEMENT_H +#define LEXBOR_HTML_SELECTEDCONTENT_ELEMENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lexbor/html/interface.h" +#include "lexbor/html/interfaces/element.h" + + +struct lxb_html_selectedcontent_element { + lxb_html_element_t element; +}; + + +LXB_API lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_create(lxb_html_document_t *document); + +LXB_API lxb_html_selectedcontent_element_t * +lxb_html_selectedcontent_element_interface_destroy(lxb_html_selectedcontent_element_t *selectedcontent_element); + +LXB_API lxb_dom_exception_code_t +lxb_html_selectedcontent_clone_option(lxb_html_selectedcontent_element_t *sc, + lxb_html_option_element_t *option); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LEXBOR_HTML_SELECTEDCONTENT_ELEMENT_H */ diff --git a/ext/lexbor/lexbor/html/parser.c b/ext/lexbor/lexbor/html/parser.c index caca15e4be26..7d051045101e 100644 --- a/ext/lexbor/lexbor/html/parser.c +++ b/ext/lexbor/lexbor/html/parser.c @@ -13,9 +13,10 @@ #include "lexbor/html/tree/template_insertion.h" #include "lexbor/html/tree/insertion_mode.h" -#define LXB_HTML_TAG_RES_DATA -#define LXB_HTML_TAG_RES_SHS_DATA -#include "lexbor/html/tag_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY]; + LXB_EXTERN lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY]; +#endif static void @@ -43,6 +44,8 @@ lxb_html_parser_init(lxb_html_parser_t *parser) return status; } + lxb_html_tokenizer_keep_duplicate_set(parser->tkz, true); + /* Tree */ parser->tree = lxb_html_tree_create(); status = lxb_html_tree_init(parser->tree, parser->tkz); @@ -339,7 +342,9 @@ lxb_html_parse_fragment_chunk_destroy(lxb_html_parser_t *parser) parser->tree->fragment = NULL; } - if (lxb_html_document_is_original(parser->tree->document) == false) { + if (parser->tree->document != NULL + && lxb_html_document_is_original(parser->tree->document) == false) + { if (parser->root != NULL) { doc = lxb_dom_interface_node(parser->tree->document)->owner_document; parser->root->parent = &doc->node; diff --git a/ext/lexbor/lexbor/html/style.c b/ext/lexbor/lexbor/html/style.c deleted file mode 100644 index b07dbf12cae0..000000000000 --- a/ext/lexbor/lexbor/html/style.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2022-2023 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#include "lexbor/html/style.h" - - -uintptr_t -lxb_html_style_id_by_name(lxb_html_document_t *doc, - const lxb_char_t *name, size_t size) -{ - const lxb_css_entry_data_t *data; - - data = lxb_css_property_by_name(name, size); - - if (data == NULL) { - return lxb_html_document_css_customs_find_id(doc, name, size); - } - - return data->unique; -} diff --git a/ext/lexbor/lexbor/html/style.h b/ext/lexbor/lexbor/html/style.h deleted file mode 100644 index 10800bcd6593..000000000000 --- a/ext/lexbor/lexbor/html/style.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2022-2023 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#ifndef LEXBOR_HTML_STYLE_H -#define LEXBOR_HTML_STYLE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lexbor/core/avl.h" -#include "lexbor/css/selectors/selector.h" -#include "lexbor/html/interfaces/document.h" - - -typedef struct lxb_html_style_weak lxb_html_style_weak_t; - -struct lxb_html_style_weak { - void *value; - lxb_css_selector_specificity_t sp; - - lxb_html_style_weak_t *next; -}; - -typedef struct { - lexbor_avl_node_t entry; - lxb_html_style_weak_t *weak; - - lxb_css_selector_specificity_t sp; -} -lxb_html_style_node_t; - - -LXB_API uintptr_t -lxb_html_style_id_by_name(lxb_html_document_t *doc, - const lxb_char_t *name, size_t size); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LEXBOR_HTML_STYLE_H */ diff --git a/ext/lexbor/lexbor/html/tag.c b/ext/lexbor/lexbor/html/tag.c new file mode 100644 index 000000000000..48f894963c56 --- /dev/null +++ b/ext/lexbor/lexbor/html/tag.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2026 Alexander Borisov + * + * Author: Alexander Borisov + */ + +#include "lexbor/html/tag.h" +#include "lexbor/html/tag_res.h" + + +bool +lxb_html_tag_is_category(lxb_tag_id_t tag_id, lxb_ns_id_t ns, + lxb_html_tag_category_t cat) +{ + if (tag_id < LXB_TAG__LAST_ENTRY && ns < LXB_NS__LAST_ENTRY) { + return lxb_html_tag_res_cats[tag_id][ns] & cat; + } + + return (LXB_HTML_TAG_CATEGORY_ORDINARY) & cat; +} + +const lxb_html_tag_fixname_t * +lxb_html_tag_fixname_svg(lxb_tag_id_t tag_id) +{ + if (tag_id >= LXB_TAG__LAST_ENTRY) { + return NULL; + } + + return &lxb_html_tag_res_fixname_svg[tag_id]; +} diff --git a/ext/lexbor/lexbor/html/tag.h b/ext/lexbor/lexbor/html/tag.h index 6570d7d40b7c..b559d31f6882 100644 --- a/ext/lexbor/lexbor/html/tag.h +++ b/ext/lexbor/lexbor/html/tag.h @@ -28,8 +28,7 @@ enum lxb_html_tag_category { LXB_HTML_TAG_CATEGORY_SCOPE = 0x0008, LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM = 0x0010, LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON = 0x0020, - LXB_HTML_TAG_CATEGORY_SCOPE_TABLE = 0x0040, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT = 0x0080, + LXB_HTML_TAG_CATEGORY_SCOPE_TABLE = 0x0040 }; typedef struct { @@ -39,35 +38,17 @@ typedef struct { lxb_html_tag_fixname_t; -#define LXB_HTML_TAG_RES_CATS -#define LXB_HTML_TAG_RES_FIXNAME_SVG -#include "lexbor/html/tag_res.h" +LXB_API bool +lxb_html_tag_is_category(lxb_tag_id_t tag_id, lxb_ns_id_t ns, + lxb_html_tag_category_t cat); + +LXB_API const lxb_html_tag_fixname_t * +lxb_html_tag_fixname_svg(lxb_tag_id_t tag_id); /* * Inline functions */ -lxb_inline bool -lxb_html_tag_is_category(lxb_tag_id_t tag_id, lxb_ns_id_t ns, - lxb_html_tag_category_t cat) -{ - if (tag_id < LXB_TAG__LAST_ENTRY && ns < LXB_NS__LAST_ENTRY) { - return lxb_html_tag_res_cats[tag_id][ns] & cat; - } - - return (LXB_HTML_TAG_CATEGORY_ORDINARY|LXB_HTML_TAG_CATEGORY_SCOPE_SELECT) & cat; -} - -lxb_inline const lxb_html_tag_fixname_t * -lxb_html_tag_fixname_svg(lxb_tag_id_t tag_id) -{ - if (tag_id >= LXB_TAG__LAST_ENTRY) { - return NULL; - } - - return &lxb_html_tag_res_fixname_svg[tag_id]; -} - lxb_inline bool lxb_html_tag_is_void(lxb_tag_id_t tag_id) { diff --git a/ext/lexbor/lexbor/html/tag_res.h b/ext/lexbor/lexbor/html/tag_res.h index 97c28640ccd1..5e2453a59f2a 100644 --- a/ext/lexbor/lexbor/html/tag_res.h +++ b/ext/lexbor/lexbor/html/tag_res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,14 +14,10 @@ #ifndef LXB_HTML_TAG_RES_H #define LXB_HTML_TAG_RES_H -#include "lexbor/html/tag.h" - -#endif /* LXB_HTML_TAG_RES_H */ - #ifdef LXB_TAG_CONST_VERSION -#ifndef LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#ifndef LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 #error Mismatched tags version! See "lexbor/tag/const.h". -#endif /* LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 */ +#endif /* LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 */ #else #error You need to include "lexbor/tag/const.h". #endif /* LXB_TAG_CONST_VERSION */ @@ -34,1835 +30,1476 @@ #error You need to include "lexbor/ns/const.h". #endif /* LXB_NS_CONST_VERSION */ -#ifdef LXB_HTML_TAG_RES_CATS -#ifndef LXB_HTML_TAG_RES_CATS_ENABLED -#define LXB_HTML_TAG_RES_CATS_ENABLED -static lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = +LXB_API lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG__END_OF_FILE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG__TEXT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG__DOCUMENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG__EM_COMMENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG__EM_DOCTYPE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY_ORDINARY }, /* LXB_TAG_A */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ABBR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ACRONYM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ADDRESS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ALTGLYPH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ALTGLYPHDEF */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ALTGLYPHITEM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANIMATECOLOR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANIMATEMOTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANIMATETRANSFORM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ANNOTATION_XML */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_APPLET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_AREA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ARTICLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ASIDE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_AUDIO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_B */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BASE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BASEFONT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BDI */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BDO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BGSOUND */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BIG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BLINK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BLOCKQUOTE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BODY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_BUTTON */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CANVAS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CAPTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CENTER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CITE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CLIPPATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_CODE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_COL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_COLGROUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DATA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DATALIST */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DEL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DESC */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DETAILS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DFN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DIALOG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DIR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DIV */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_DT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_EM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_EMBED */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEBLEND */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECOLORMATRIX */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECOMPONENTTRANSFER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECOMPOSITE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FECONVOLVEMATRIX */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDIFFUSELIGHTING */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDISPLACEMENTMAP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDISTANTLIGHT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEDROPSHADOW */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFLOOD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCB */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEFUNCR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEGAUSSIANBLUR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEIMAGE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEMERGE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEMERGENODE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEMORPHOLOGY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEOFFSET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FEPOINTLIGHT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FESPECULARLIGHTING */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FESPOTLIGHT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FETILE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FETURBULENCE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FIELDSET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FIGCAPTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FIGURE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FONT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FOOTER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FOREIGNOBJECT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FORM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FRAME */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_FRAMESET */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_GLYPHREF */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H1 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H2 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H3 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H4 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H5 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_H6 */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HEAD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HEADER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HGROUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_HTML */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SCOPE_TABLE |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_I */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_IFRAME */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_IMAGE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_IMG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_INPUT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_INS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_ISINDEX */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_KBD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_KEYGEN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LABEL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LEGEND */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LI */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LINEARGRADIENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LINK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_LISTING */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MAIN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MALIGNMARK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MAP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MARK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MARQUEE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MENU */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_META */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_METER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MFENCED */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MGLYPH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_ORDINARY, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_ORDINARY, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MI */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MTEXT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_MULTICOL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NAV */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NEXTID */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOBR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOEMBED */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOFRAMES */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_NOSCRIPT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OBJECT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OPTGROUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OPTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_OUTPUT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_P */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PARAM */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PICTURE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PLAINTEXT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PRE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_PROGRESS */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_Q */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RADIALGRADIENT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RB */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RTC */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_RUBY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_S */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SAMP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SCRIPT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF + }, + /* LXB_TAG_SEARCH */ + { + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SECTION */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SELECT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SCOPE + |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON + |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF + }, + /* LXB_TAG_SELECTEDCONTENT */ + { + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SLOT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SMALL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SOURCE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SPACER */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SPAN */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_STRIKE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_STRONG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_STYLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SUB */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SUMMARY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SUP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_SVG */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TABLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SCOPE_TABLE |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TBODY */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TEMPLATE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SCOPE_TABLE |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TEXTAREA */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TEXTPATH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TFOOT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TH */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_THEAD */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TIME */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TITLE */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE |LXB_HTML_TAG_CATEGORY_SCOPE_BUTTON |LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TRACK */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_TT */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_U */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_FORMATTING - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_FORMATTING,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_UL */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY_SCOPE_LIST_ITEM - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_VAR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_VIDEO */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_ORDINARY - |LXB_HTML_TAG_CATEGORY_SCOPE_SELECT, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_ORDINARY,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_WBR */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF }, /* LXB_TAG_XMP */ { - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT - |LXB_HTML_TAG_CATEGORY_SPECIAL, - LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF, - LXB_HTML_TAG_CATEGORY__UNDEF, LXB_HTML_TAG_CATEGORY__UNDEF + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY_SPECIAL,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF, + LXB_HTML_TAG_CATEGORY__UNDEF,LXB_HTML_TAG_CATEGORY__UNDEF } }; -#endif /* LXB_HTML_TAG_RES_CATS_ENABLED */ -#endif /* LXB_HTML_TAG_RES_CATS */ -#ifdef LXB_HTML_TAG_RES_FIXNAME_SVG -#ifndef LXB_HTML_TAG_RES_FIXNAME_SVG_ENABLED -#define LXB_HTML_TAG_RES_FIXNAME_SVG_ENABLED -static lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] = +LXB_API lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] = { /* LXB_TAG__UNDEF */ {NULL, 0}, @@ -2188,10 +1825,14 @@ static lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] {NULL, 0}, /* LXB_TAG_SCRIPT */ {NULL, 0}, + /* LXB_TAG_SEARCH */ + {NULL, 0}, /* LXB_TAG_SECTION */ {NULL, 0}, /* LXB_TAG_SELECT */ {NULL, 0}, + /* LXB_TAG_SELECTEDCONTENT */ + {NULL, 0}, /* LXB_TAG_SLOT */ {NULL, 0}, /* LXB_TAG_SMALL */ @@ -2256,7 +1897,7 @@ static lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY] {NULL, 0}, /* LXB_TAG_XMP */ {NULL, 0}, - + }; -#endif /* LXB_HTML_TAG_RES_FIXNAME_SVG_ENABLED */ -#endif /* LXB_HTML_TAG_RES_FIXNAME_SVG */ + +#endif /* LXB_HTML_TAG_RES_H */ diff --git a/ext/lexbor/lexbor/html/token.c b/ext/lexbor/lexbor/html/token.c index 0f5d076adf59..d4ab1bbb767d 100644 --- a/ext/lexbor/lexbor/html/token.c +++ b/ext/lexbor/lexbor/html/token.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,11 +7,12 @@ #include "lexbor/html/token.h" #include "lexbor/html/tokenizer.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_NUM -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_num[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif #include "lexbor/dom/interfaces/document_type.h" diff --git a/ext/lexbor/lexbor/html/tokenizer.c b/ext/lexbor/lexbor/html/tokenizer.c index 0bd9aec504f0..1d9f3781255d 100644 --- a/ext/lexbor/lexbor/html/tokenizer.c +++ b/ext/lexbor/lexbor/html/tokenizer.c @@ -11,19 +11,20 @@ #include "lexbor/html/tokenizer/state_script.h" #include "lexbor/html/tree.h" -#define LXB_HTML_TAG_RES_DATA -#define LXB_HTML_TAG_RES_SHS_DATA -#include "lexbor/html/tag_res.h" + +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN lxb_html_tag_category_t lxb_html_tag_res_cats[LXB_TAG__LAST_ENTRY][LXB_NS__LAST_ENTRY]; + LXB_EXTERN lxb_html_tag_fixname_t lxb_html_tag_res_fixname_svg[LXB_TAG__LAST_ENTRY]; +#endif #define LXB_HTML_TKZ_TEMP_SIZE (4096 * 4) enum { - LXB_HTML_TOKENIZER_OPT_UNDEF = 0x00, - LXB_HTML_TOKENIZER_OPT_TAGS_SELF = 0x01, - LXB_HTML_TOKENIZER_OPT_ATTRS_SELF = 0x02, - LXB_HTML_TOKENIZER_OPT_ATTRS_MRAW_SELF = 0x04 + LXB_HTML_TOKENIZER_OPT_TAGS_SELF = 1 << 0, + LXB_HTML_TOKENIZER_OPT_ATTRS_SELF = 1 << 1, + LXB_HTML_TOKENIZER_OPT_ATTRS_MRAW_SELF = 1 << 2 }; @@ -206,6 +207,8 @@ lxb_html_tokenizer_clean(lxb_html_tokenizer_t *tkz) tkz->is_eof = false; tkz->status = LXB_STATUS_OK; + tkz->utf8_buf_len = 0; + tkz->pos = tkz->start; lexbor_mraw_clean(tkz->mraw); @@ -304,12 +307,268 @@ lxb_html_tokenizer_begin(lxb_html_tokenizer_t *tkz) return LXB_STATUS_OK; } +/* + * Input stream validation. + * + * Per the HTML spec §13.2.3.5: surrogates, noncharacters, and controls + * (other than ASCII whitespace and NULL) in the input stream are parse errors. + * + * This is a fast linear scan that only fires when + * LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT is set. + */ + +/* + * Lookup: 1 if the byte is a single-byte control that needs reporting. + * Covers 0x01–0x08, 0x0B, 0x0E–0x1F, 0x7F. + * Excludes 0x00 (handled by tokenizer as UNNUCH), 0x09 (TAB), 0x0A (LF), + * 0x0C (FF), 0x0D (CR), 0x20 (SPACE). + */ +static const lxb_char_t +lxb_html_tkz_validate_ctl[256] = +{ +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ +/* 0 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, +/* 1 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +/* 8+ */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void +lxb_html_tokenizer_validate_codepoint(lxb_html_tokenizer_t *tkz, + uint32_t cp, const lxb_char_t *pos) +{ + /* C1 controls: U+0080–U+009F */ + if (cp >= 0x0080 && cp <= 0x009F) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_COCHININST); + return; + } + + /* Surrogates: U+D800–U+DFFF */ + if (cp >= 0xD800 && cp <= 0xDFFF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_SUININST); + return; + } + + /* Noncharacters: U+FDD0–U+FDEF */ + if (cp >= 0xFDD0 && cp <= 0xFDEF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_NOININST); + return; + } + + /* Noncharacters: U+xFFFE and U+xFFFF on every plane */ + if ((cp & 0xFFFE) == 0xFFFE && cp <= 0x10FFFF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, pos, + LXB_HTML_TOKENIZER_ERROR_NOININST); + } +} + +static void +lxb_html_tokenizer_validate_flush_utf8(lxb_html_tokenizer_t *tkz, + const lxb_char_t *pos) +{ + uint32_t cp; + unsigned len = tkz->utf8_buf_len; + const lxb_char_t *b = tkz->utf8_buf; + + if (len < 2) { + goto done; + } + + if ((b[0] & 0xE0) == 0xC0) { + cp = ((uint32_t)(b[0] & 0x1F) << 6) | (b[1] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, pos); + goto done; + } + + if (len < 3) { + goto done; + } + + if ((b[0] & 0xF0) == 0xE0) { + cp = ((uint32_t)(b[0] & 0x0F) << 12) + | ((uint32_t)(b[1] & 0x3F) << 6) + | (b[2] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, pos); + goto done; + } + + if (len < 4) { + goto done; + } + + if ((b[0] & 0xF8) == 0xF0) { + cp = ((uint32_t)(b[0] & 0x07) << 18) + | ((uint32_t)(b[1] & 0x3F) << 12) + | ((uint32_t)(b[2] & 0x3F) << 6) + | (b[3] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, pos); + } + +done: + + tkz->utf8_buf_len = 0; +} + +static void +lxb_html_tokenizer_validate_input(lxb_html_tokenizer_t *tkz, + const lxb_char_t *data, size_t size) +{ + uint32_t cp; + unsigned need, len; + const lxb_char_t *p, *end; + + p = data; + end = data + size; + + /* Continue incomplete UTF-8 sequence from previous chunk. */ + if (tkz->utf8_buf_len > 0) { + lxb_char_t lead = tkz->utf8_buf[0]; + + if ((lead & 0xE0) == 0xC0) { + need = 2; + } + else if ((lead & 0xF0) == 0xE0) { + need = 3; + } + else { + need = 4; + } + + while (tkz->utf8_buf_len < need && p < end) { + if ((*p & 0xC0) != 0x80) { + /* Broken sequence, skip. */ + tkz->utf8_buf_len = 0; + break; + } + + tkz->utf8_buf[tkz->utf8_buf_len++] = *p++; + } + + if (tkz->utf8_buf_len == need) { + lxb_html_tokenizer_validate_flush_utf8(tkz, data); + } + else if (p >= end) { + /* Still incomplete, wait for more data. */ + return; + } + else { + /* Broken sequence was reset above. */ + } + } + + while (p < end) { + lxb_char_t b = *p; + + /* Fast path: printable ASCII (0x20–0x7E), TAB, LF, FF, CR, NULL. */ + if (b < 0x80) { + if (lxb_html_tkz_validate_ctl[b]) { + lxb_html_tokenizer_error_add(tkz->parse_errors, p, + LXB_HTML_TOKENIZER_ERROR_COCHININST); + } + + p++; + continue; + } + + /* Multi-byte UTF-8. Determine expected length. */ + if ((b & 0xE0) == 0xC0) { + need = 2; + } + else if ((b & 0xF0) == 0xE0) { + need = 3; + } + else if ((b & 0xF8) == 0xF0) { + need = 4; + } + else { + /* Invalid lead byte or continuation byte, skip. */ + p++; + continue; + } + + /* Check if the full sequence is available in this chunk. */ + if ((unsigned)(end - p) < need) { + /* Save partial sequence for next chunk. */ + len = (unsigned)(end - p); + memcpy(tkz->utf8_buf, p, len); + tkz->utf8_buf_len = len; + return; + } + + /* Quick filter: only decode if lead byte can start a bad codepoint. + * + * 0xC2 -> C1 controls (U+0080–U+009F): second byte 0x80–0x9F + * 0xED -> surrogates (U+D800–U+DFFF): second byte 0xA0–0xBF + * 0xEF -> nonchars U+FDD0–U+FDEF (0xEF 0xB7 0x90–0xAF) + * and U+FFFE/U+FFFF (0xEF 0xBF 0xBE/0xBF) + * 0xF0–0xF4 -> nonchars U+xFFFE/U+xFFFF on planes 1–16 + */ + if (b == 0xC2) { + if (p[1] <= 0x9F) { + cp = ((uint32_t)(b & 0x1F) << 6) | (p[1] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, p); + } + } + else if (b == 0xED) { + if (p[1] >= 0xA0) { + cp = ((uint32_t)(b & 0x0F) << 12) + | ((uint32_t)(p[1] & 0x3F) << 6) + | (p[2] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, p); + } + } + else if (b == 0xEF) { + if (p[1] == 0xB7 && p[2] >= 0x90 && p[2] <= 0xAF) { + /* U+FDD0–U+FDEF */ + lxb_html_tokenizer_error_add(tkz->parse_errors, p, + LXB_HTML_TOKENIZER_ERROR_NOININST); + } + else if (p[1] == 0xBF && (p[2] == 0xBE || p[2] == 0xBF)) { + /* U+FFFE, U+FFFF */ + lxb_html_tokenizer_error_add(tkz->parse_errors, p, + LXB_HTML_TOKENIZER_ERROR_NOININST); + } + } + else if (b >= 0xF0 && b <= 0xF4) { + /* 4-byte: check for xFFFE/xFFFF. */ + if (p[2] == 0xBF && (p[3] == 0xBE || p[3] == 0xBF)) { + cp = ((uint32_t)(b & 0x07) << 18) + | ((uint32_t)(p[1] & 0x3F) << 12) + | ((uint32_t)(p[2] & 0x3F) << 6) + | (p[3] & 0x3F); + lxb_html_tokenizer_validate_codepoint(tkz, cp, p); + } + } + + p += need; + } +} + lxb_status_t lxb_html_tokenizer_chunk(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, size_t size) { const lxb_char_t *end = data + size; + if (tkz->opt & LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT) { + lxb_html_tokenizer_validate_input(tkz, data, size); + } + tkz->is_eof = false; tkz->status = LXB_STATUS_OK; tkz->last = end; @@ -457,6 +716,46 @@ lxb_html_tokenizer_set_state_by_tag(lxb_html_tokenizer_t *tkz, bool scripting, } } +void +lxb_html_tokenizer_attr_last_duplicate(lxb_html_tokenizer_t *tkz) +{ + lxb_html_token_t *token; + lxb_html_token_attr_t *attr, *last; + + token = tkz->token; + attr = token->attr_first; + last = token->attr_last; + + while (attr != last) { + if (attr->name == last->name) { + lxb_html_tokenizer_error_add(tkz->parse_errors, last->name_begin, + LXB_HTML_TOKENIZER_ERROR_DUAT); + + lxb_html_token_attr_remove(token, last); + lxb_html_token_attr_destroy(last, tkz->dobj_token_attr); + return; + } + + attr = attr->next; + } +} + +void +lxb_html_tokenizer_validate_close_tag(lxb_html_tokenizer_t *tkz) +{ + if (tkz->token->attr_last != NULL) { + lxb_html_tokenizer_error_add(tkz->parse_errors, + tkz->token->attr_last->name_begin, + LXB_HTML_TOKENIZER_ERROR_ENTAWIAT); + } + + if (tkz->token->type & LXB_HTML_TOKEN_TYPE_CLOSE_SELF) { + lxb_html_tokenizer_error_add(tkz->parse_errors, tkz->token->end, + LXB_HTML_TOKENIZER_ERROR_ENTAWITRSO); + } +} + + /* * No inline functions for ABI. */ @@ -508,6 +807,13 @@ lxb_html_tokenizer_tree_set_noi(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_tree_set(tkz, tree); } +void +lxb_html_tokenizer_input_validation_set_noi(lxb_html_tokenizer_t *tkz, + bool enabled) +{ + lxb_html_tokenizer_input_validation_set(tkz, enabled); +} + lexbor_mraw_t * lxb_html_tokenizer_mraw_noi(lxb_html_tokenizer_t *tkz) { @@ -519,3 +825,10 @@ lxb_html_tokenizer_tags_noi(lxb_html_tokenizer_t *tkz) { return lxb_html_tokenizer_tags(tkz); } + +void +lxb_html_tokenizer_keep_duplicate_set_noi(lxb_html_tokenizer_t *tkz, + bool keep) +{ + lxb_html_tokenizer_keep_duplicate_set(tkz, keep); +} diff --git a/ext/lexbor/lexbor/html/tokenizer.h b/ext/lexbor/lexbor/html/tokenizer.h index 74bb55ef0fd7..aa1ac37d996d 100644 --- a/ext/lexbor/lexbor/html/tokenizer.h +++ b/ext/lexbor/lexbor/html/tokenizer.h @@ -21,6 +21,12 @@ extern "C" { #include "lexbor/ns/ns.h" +enum { + LXB_HTML_TOKENIZER_OPT_UNDEF = 0x00, + LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT = 1 << 3, + LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE = 1 << 4 +}; + /* State */ typedef const lxb_char_t * (*lxb_html_tokenizer_state_f)(lxb_html_tokenizer_t *tkz, @@ -90,6 +96,10 @@ struct lxb_html_tokenizer { lxb_status_t status; bool is_eof; + /* Input stream validation (for cross-chunk UTF-8). */ + lxb_char_t utf8_buf[4]; + unsigned utf8_buf_len; + lxb_html_tokenizer_t *base; size_t ref_count; }; @@ -97,8 +107,9 @@ struct lxb_html_tokenizer { #include "lexbor/html/tokenizer/error.h" - -extern const lxb_char_t *lxb_html_tokenizer_eof; +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t *lxb_html_tokenizer_eof; +#endif LXB_API lxb_html_tokenizer_t * lxb_html_tokenizer_create(void); @@ -156,6 +167,11 @@ LXB_API void lxb_html_tokenizer_set_state_by_tag(lxb_html_tokenizer_t *tkz, bool scripting, lxb_tag_id_t tag_id, lxb_ns_id_t ns); +LXB_API void +lxb_html_tokenizer_attr_last_duplicate(lxb_html_tokenizer_t *tkz); + +LXB_API void +lxb_html_tokenizer_validate_close_tag(lxb_html_tokenizer_t *tkz); /* * Inline functions @@ -250,6 +266,28 @@ lxb_html_tokenizer_mraw(lxb_html_tokenizer_t *tkz) return tkz->mraw; } +lxb_inline void +lxb_html_tokenizer_input_validation_set(lxb_html_tokenizer_t *tkz, bool enabled) +{ + if (enabled) { + tkz->opt |= LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT; + } + else { + tkz->opt &= ~LXB_HTML_TOKENIZER_OPT_VALIDATE_INPUT; + } +} + +lxb_inline void +lxb_html_tokenizer_keep_duplicate_set(lxb_html_tokenizer_t *tkz, bool keep) +{ + if (keep) { + tkz->opt |= LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE; + } + else { + tkz->opt &= ~LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE; + } +} + lxb_inline lxb_status_t lxb_html_tokenizer_temp_realloc(lxb_html_tokenizer_t *tkz, size_t size) { @@ -331,12 +369,20 @@ LXB_API void lxb_html_tokenizer_tree_set_noi(lxb_html_tokenizer_t *tkz, lxb_html_tree_t *tree); +LXB_API void +lxb_html_tokenizer_input_validation_set_noi(lxb_html_tokenizer_t *tkz, + bool enabled); + LXB_API lexbor_mraw_t * lxb_html_tokenizer_mraw_noi(lxb_html_tokenizer_t *tkz); LXB_API lexbor_hash_t * lxb_html_tokenizer_tags_noi(lxb_html_tokenizer_t *tkz); +LXB_API void +lxb_html_tokenizer_keep_duplicate_set_noi(lxb_html_tokenizer_t *tkz, + bool keep); + #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/html/tokenizer/error.c b/ext/lexbor/lexbor/html/tokenizer/error.c index c2381ad97c87..241fac509768 100644 --- a/ext/lexbor/lexbor/html/tokenizer/error.c +++ b/ext/lexbor/lexbor/html/tokenizer/error.c @@ -1,9 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ +#include "lexbor/core/str.h" #include "lexbor/html/tokenizer/error.h" @@ -26,3 +27,76 @@ lxb_html_tokenizer_error_add(lexbor_array_obj_t *parse_errors, return entry; } + +const lxb_char_t * +lxb_html_tokenizer_error_to_string(lxb_html_tokenizer_error_id_t id, + size_t *len) +{ + static const lexbor_str_t unknown = lexbor_str("unknown error"); + + static const lexbor_str_t errors[LXB_HTML_TOKENIZER_ERROR_LAST_ENTRY] = { + lexbor_str("abrupt closing of empty comment"), + lexbor_str("abrupt doctype public identifier"), + lexbor_str("abrupt doctype system identifier"), + lexbor_str("absence of digits in numeric character reference"), + lexbor_str("cdata in html content"), + lexbor_str("character reference outside unicode range"), + lexbor_str("control character in input stream"), + lexbor_str("control character reference"), + lexbor_str("end tag with attributes"), + lexbor_str("duplicate attribute"), + lexbor_str("end tag with trailing solidus"), + lexbor_str("eof before tag name"), + lexbor_str("eof in cdata"), + lexbor_str("eof in comment"), + lexbor_str("eof in doctype"), + lexbor_str("eof in script html comment like text"), + lexbor_str("eof in tag"), + lexbor_str("incorrectly closed comment"), + lexbor_str("incorrectly opened comment"), + lexbor_str("invalid character sequence after doctype name"), + lexbor_str("invalid first character of tag name"), + lexbor_str("missing attribute value"), + lexbor_str("missing doctype name"), + lexbor_str("missing doctype public identifier"), + lexbor_str("missing doctype system identifier"), + lexbor_str("missing end tag name"), + lexbor_str("missing quote before doctype public identifier"), + lexbor_str("missing quote before doctype system identifier"), + lexbor_str("missing semicolon after character reference"), + lexbor_str("missing whitespace after doctype public keyword"), + lexbor_str("missing whitespace after doctype system keyword"), + lexbor_str("missing whitespace before doctype name"), + lexbor_str("missing whitespace between attributes"), + lexbor_str("missing whitespace between doctype public and system identifiers"), + lexbor_str("nested comment"), + lexbor_str("noncharacter character reference"), + lexbor_str("noncharacter in input stream"), + lexbor_str("non void html element start tag with trailing solidus"), + lexbor_str("null character reference"), + lexbor_str("surrogate character reference"), + lexbor_str("surrogate in input stream"), + lexbor_str("unexpected character after doctype system identifier"), + lexbor_str("unexpected character in attribute name"), + lexbor_str("unexpected character in unquoted attribute value"), + lexbor_str("unexpected equals sign before attribute name"), + lexbor_str("unexpected null character"), + lexbor_str("unexpected question mark instead of tag name"), + lexbor_str("unexpected solidus in tag"), + lexbor_str("unknown named character reference") + }; + + if (id >= (sizeof(errors) / sizeof(lexbor_str_t))) { + if (len != NULL) { + *len = unknown.length; + } + + return unknown.data; + } + + if (len != NULL) { + *len = errors[id].length; + } + + return errors[id].data; +} diff --git a/ext/lexbor/lexbor/html/tokenizer/error.h b/ext/lexbor/lexbor/html/tokenizer/error.h index 2685f039d510..617ff636935b 100644 --- a/ext/lexbor/lexbor/html/tokenizer/error.h +++ b/ext/lexbor/lexbor/html/tokenizer/error.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -21,102 +21,103 @@ typedef enum { /* abrupt-closing-of-empty-comment */ LXB_HTML_TOKENIZER_ERROR_ABCLOFEMCO = 0x0000, /* abrupt-doctype-public-identifier */ - LXB_HTML_TOKENIZER_ERROR_ABDOPUID = 0x0001, + LXB_HTML_TOKENIZER_ERROR_ABDOPUID, /* abrupt-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_ABDOSYID = 0x0002, + LXB_HTML_TOKENIZER_ERROR_ABDOSYID, /* absence-of-digits-in-numeric-character-reference */ - LXB_HTML_TOKENIZER_ERROR_ABOFDIINNUCHRE = 0x0003, + LXB_HTML_TOKENIZER_ERROR_ABOFDIINNUCHRE, /* cdata-in-html-content */ - LXB_HTML_TOKENIZER_ERROR_CDINHTCO = 0x0004, + LXB_HTML_TOKENIZER_ERROR_CDINHTCO, /* character-reference-outside-unicode-range */ - LXB_HTML_TOKENIZER_ERROR_CHREOUUNRA = 0x0005, + LXB_HTML_TOKENIZER_ERROR_CHREOUUNRA, /* control-character-in-input-stream */ - LXB_HTML_TOKENIZER_ERROR_COCHININST = 0x0006, + LXB_HTML_TOKENIZER_ERROR_COCHININST, /* control-character-reference */ - LXB_HTML_TOKENIZER_ERROR_COCHRE = 0x0007, + LXB_HTML_TOKENIZER_ERROR_COCHRE, /* end-tag-with-attributes */ - LXB_HTML_TOKENIZER_ERROR_ENTAWIAT = 0x0008, + LXB_HTML_TOKENIZER_ERROR_ENTAWIAT, /* duplicate-attribute */ - LXB_HTML_TOKENIZER_ERROR_DUAT = 0x0009, + LXB_HTML_TOKENIZER_ERROR_DUAT, /* end-tag-with-trailing-solidus */ - LXB_HTML_TOKENIZER_ERROR_ENTAWITRSO = 0x000A, + LXB_HTML_TOKENIZER_ERROR_ENTAWITRSO, /* eof-before-tag-name */ - LXB_HTML_TOKENIZER_ERROR_EOBETANA = 0x000B, + LXB_HTML_TOKENIZER_ERROR_EOBETANA, /* eof-in-cdata */ - LXB_HTML_TOKENIZER_ERROR_EOINCD = 0x000C, + LXB_HTML_TOKENIZER_ERROR_EOINCD, /* eof-in-comment */ - LXB_HTML_TOKENIZER_ERROR_EOINCO = 0x000D, + LXB_HTML_TOKENIZER_ERROR_EOINCO, /* eof-in-doctype */ - LXB_HTML_TOKENIZER_ERROR_EOINDO = 0x000E, + LXB_HTML_TOKENIZER_ERROR_EOINDO, /* eof-in-script-html-comment-like-text */ - LXB_HTML_TOKENIZER_ERROR_EOINSCHTCOLITE = 0x000F, + LXB_HTML_TOKENIZER_ERROR_EOINSCHTCOLITE, /* eof-in-tag */ - LXB_HTML_TOKENIZER_ERROR_EOINTA = 0x0010, + LXB_HTML_TOKENIZER_ERROR_EOINTA, /* incorrectly-closed-comment */ - LXB_HTML_TOKENIZER_ERROR_INCLCO = 0x0011, + LXB_HTML_TOKENIZER_ERROR_INCLCO, /* incorrectly-opened-comment */ - LXB_HTML_TOKENIZER_ERROR_INOPCO = 0x0012, + LXB_HTML_TOKENIZER_ERROR_INOPCO, /* invalid-character-sequence-after-doctype-name */ - LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA = 0x0013, + LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA, /* invalid-first-character-of-tag-name */ - LXB_HTML_TOKENIZER_ERROR_INFICHOFTANA = 0x0014, + LXB_HTML_TOKENIZER_ERROR_INFICHOFTANA, /* missing-attribute-value */ - LXB_HTML_TOKENIZER_ERROR_MIATVA = 0x0015, + LXB_HTML_TOKENIZER_ERROR_MIATVA, /* missing-doctype-name */ - LXB_HTML_TOKENIZER_ERROR_MIDONA = 0x0016, + LXB_HTML_TOKENIZER_ERROR_MIDONA, /* missing-doctype-public-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIDOPUID = 0x0017, + LXB_HTML_TOKENIZER_ERROR_MIDOPUID, /* missing-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIDOSYID = 0x0018, + LXB_HTML_TOKENIZER_ERROR_MIDOSYID, /* missing-end-tag-name */ - LXB_HTML_TOKENIZER_ERROR_MIENTANA = 0x0019, + LXB_HTML_TOKENIZER_ERROR_MIENTANA, /* missing-quote-before-doctype-public-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIQUBEDOPUID = 0x001A, + LXB_HTML_TOKENIZER_ERROR_MIQUBEDOPUID, /* missing-quote-before-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_MIQUBEDOSYID = 0x001B, + LXB_HTML_TOKENIZER_ERROR_MIQUBEDOSYID, /* missing-semicolon-after-character-reference */ - LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE = 0x001C, + LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE, /* missing-whitespace-after-doctype-public-keyword */ - LXB_HTML_TOKENIZER_ERROR_MIWHAFDOPUKE = 0x001D, + LXB_HTML_TOKENIZER_ERROR_MIWHAFDOPUKE, /* missing-whitespace-after-doctype-system-keyword */ - LXB_HTML_TOKENIZER_ERROR_MIWHAFDOSYKE = 0x001E, + LXB_HTML_TOKENIZER_ERROR_MIWHAFDOSYKE, /* missing-whitespace-before-doctype-name */ - LXB_HTML_TOKENIZER_ERROR_MIWHBEDONA = 0x001F, + LXB_HTML_TOKENIZER_ERROR_MIWHBEDONA, /* missing-whitespace-between-attributes */ - LXB_HTML_TOKENIZER_ERROR_MIWHBEAT = 0x0020, + LXB_HTML_TOKENIZER_ERROR_MIWHBEAT, /* missing-whitespace-between-doctype-public-and-system-identifiers */ - LXB_HTML_TOKENIZER_ERROR_MIWHBEDOPUANSYID = 0x0021, + LXB_HTML_TOKENIZER_ERROR_MIWHBEDOPUANSYID, /* nested-comment */ - LXB_HTML_TOKENIZER_ERROR_NECO = 0x0022, + LXB_HTML_TOKENIZER_ERROR_NECO, /* noncharacter-character-reference */ - LXB_HTML_TOKENIZER_ERROR_NOCHRE = 0x0023, + LXB_HTML_TOKENIZER_ERROR_NOCHRE, /* noncharacter-in-input-stream */ - LXB_HTML_TOKENIZER_ERROR_NOININST = 0x0024, + LXB_HTML_TOKENIZER_ERROR_NOININST, /* non-void-html-element-start-tag-with-trailing-solidus */ - LXB_HTML_TOKENIZER_ERROR_NOVOHTELSTTAWITRSO = 0x0025, + LXB_HTML_TOKENIZER_ERROR_NOVOHTELSTTAWITRSO, /* null-character-reference */ - LXB_HTML_TOKENIZER_ERROR_NUCHRE = 0x0026, + LXB_HTML_TOKENIZER_ERROR_NUCHRE, /* surrogate-character-reference */ - LXB_HTML_TOKENIZER_ERROR_SUCHRE = 0x0027, + LXB_HTML_TOKENIZER_ERROR_SUCHRE, /* surrogate-in-input-stream */ - LXB_HTML_TOKENIZER_ERROR_SUININST = 0x0028, + LXB_HTML_TOKENIZER_ERROR_SUININST, /* unexpected-character-after-doctype-system-identifier */ - LXB_HTML_TOKENIZER_ERROR_UNCHAFDOSYID = 0x0029, + LXB_HTML_TOKENIZER_ERROR_UNCHAFDOSYID, /* unexpected-character-in-attribute-name */ - LXB_HTML_TOKENIZER_ERROR_UNCHINATNA = 0x002A, + LXB_HTML_TOKENIZER_ERROR_UNCHINATNA, /* unexpected-character-in-unquoted-attribute-value */ - LXB_HTML_TOKENIZER_ERROR_UNCHINUNATVA = 0x002B, + LXB_HTML_TOKENIZER_ERROR_UNCHINUNATVA, /* unexpected-equals-sign-before-attribute-name */ - LXB_HTML_TOKENIZER_ERROR_UNEQSIBEATNA = 0x002C, + LXB_HTML_TOKENIZER_ERROR_UNEQSIBEATNA, /* unexpected-null-character */ - LXB_HTML_TOKENIZER_ERROR_UNNUCH = 0x002D, + LXB_HTML_TOKENIZER_ERROR_UNNUCH, /* unexpected-question-mark-instead-of-tag-name */ - LXB_HTML_TOKENIZER_ERROR_UNQUMAINOFTANA = 0x002E, + LXB_HTML_TOKENIZER_ERROR_UNQUMAINOFTANA, /* unexpected-solidus-in-tag */ - LXB_HTML_TOKENIZER_ERROR_UNSOINTA = 0x002F, + LXB_HTML_TOKENIZER_ERROR_UNSOINTA, /* unknown-named-character-reference */ - LXB_HTML_TOKENIZER_ERROR_UNNACHRE = 0x0030, - LXB_HTML_TOKENIZER_ERROR_LAST_ENTRY = 0x0031, + LXB_HTML_TOKENIZER_ERROR_UNNACHRE, + + LXB_HTML_TOKENIZER_ERROR_LAST_ENTRY } lxb_html_tokenizer_error_id_t; @@ -132,10 +133,13 @@ lxb_html_tokenizer_error_add(lexbor_array_obj_t *parse_errors, const lxb_char_t *pos, lxb_html_tokenizer_error_id_t id); +LXB_API const lxb_char_t * +lxb_html_tokenizer_error_to_string(lxb_html_tokenizer_error_id_t id, + size_t *len); + #ifdef __cplusplus } /* extern "C" */ #endif #endif /* LEXBOR_HTML_TOKENIZER_ERROR_H */ - diff --git a/ext/lexbor/lexbor/html/tokenizer/res.h b/ext/lexbor/lexbor/html/tokenizer/res.h index 5ec5c68bf65d..55c77f9e6c39 100644 --- a/ext/lexbor/lexbor/html/tokenizer/res.h +++ b/ext/lexbor/lexbor/html/tokenizer/res.h @@ -1,12 +1,12 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ /* - * Caution!!! Important!!! - * This file is generated by the script + * Important! + * This file generated by the script * "utils/lexbor/html/tokenizer_entities_bst.py"! * Do not change this file! */ @@ -15,12 +15,6 @@ #ifndef LXB_HTML_TOKENIZER_RES_H #define LXB_HTML_TOKENIZER_RES_H -#endif /* LXB_HTML_TOKENIZER_RES */ - - -#ifdef LXB_HTML_TOKENIZER_RES_ENTITIES_SBST -#ifndef LXB_HTML_TOKENIZER_RES_ENTITIES_SBST_ENABLED -#define LXB_HTML_TOKENIZER_RES_ENTITIES_SBST_ENABLED static const lexbor_sbst_entry_static_t lxb_html_tokenizer_res_entities_sbst[] = { {0x00, {0}, 0, 0, 0, 0}, {0x61, {0}, 0, 3, 2, 53}, @@ -4951,6 +4945,6 @@ static const lexbor_sbst_entry_static_t lxb_html_tokenizer_res_entities_sbst[] = {0x3b, "\xd1\x8e", 2, 0, 0, 0}, {0x70, {0}, 0, 0, 0, 9852}, {0x66, {0}, 0, 0, 0, 9853}, {0x3b, "\xf0\x9d\x95\xaa", 4, 0, 0, 0} }; -#endif /* LXB_HTML_TOKENIZER_RES_ENTITIES_SBST_ENABLED */ -#endif /* LXB_HTML_TOKENIZER_RES_ENTITIES_SBST */ + +#endif /* LXB_HTML_TOKENIZER_RES */ diff --git a/ext/lexbor/lexbor/html/tokenizer/state.c b/ext/lexbor/lexbor/html/tokenizer/state.c index 207b909a1892..6c3cbebe92a3 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state.c +++ b/ext/lexbor/lexbor/html/tokenizer/state.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -8,16 +8,16 @@ #include "lexbor/html/tokenizer/state_comment.h" #include "lexbor/html/tokenizer/state_doctype.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER -#define LEXBOR_STR_RES_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_NUM -#include "lexbor/core/str_res.h" -#include "lexbor/core/swar.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_num[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const size_t lexbor_str_res_alphanumeric_character[256]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; + LXB_EXTERN const size_t lexbor_str_res_replacement_character[160]; +#endif -#define LXB_HTML_TOKENIZER_RES_ENTITIES_SBST +#include "lexbor/core/swar.h" #include "lexbor/html/tokenizer/res.h" @@ -123,11 +123,6 @@ lxb_html_tokenizer_state_markup_declaration_cdata(lxb_html_tokenizer_t *tkz, const lxb_char_t *end); /* CDATA Section */ -static const lxb_char_t * -lxb_html_tokenizer_state_cdata_section_before(lxb_html_tokenizer_t *tkz, - const lxb_char_t *data, - const lxb_char_t *end); - static const lxb_char_t * lxb_html_tokenizer_state_cdata_section(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, @@ -282,7 +277,7 @@ lxb_html_tokenizer_state_data(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_token_set_end_eof(tkz); } - if (tkz->token->begin != tkz->token->end) { + if (tkz->pos != tkz->start) { tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_append_data_m(tkz, data); @@ -381,7 +376,7 @@ lxb_html_tokenizer_state_plaintext(lxb_html_tokenizer_t *tkz, } lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1451,8 +1446,8 @@ lxb_html_tokenizer_state_markup_declaration_open(lxb_html_tokenizer_t *tkz, else if (*data == 0x5B) { if ((end - data) < 7) { tkz->markup = (lxb_char_t *) "[CDATA["; - tkz->state = lxb_html_tokenizer_state_markup_declaration_cdata; + return data; } @@ -1469,6 +1464,9 @@ lxb_html_tokenizer_state_markup_declaration_open(lxb_html_tokenizer_t *tkz, return data; } + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_CDINHTCO); + tkz->state = lxb_html_tokenizer_state_bogus_comment_before; return data; @@ -1504,6 +1502,8 @@ lxb_html_tokenizer_state_markup_declaration_comment(lxb_html_tokenizer_t *tkz, return (data + 1); } + lxb_html_tokenizer_state_append_m(tkz, "-", 1); + lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_INOPCO); @@ -1538,6 +1538,8 @@ lxb_html_tokenizer_state_markup_declaration_doctype(lxb_html_tokenizer_t *tkz, return data; } + lxb_html_tokenizer_state_append_m(tkz, data, (end - data)); + tkz->markup = pos; return end; @@ -1575,6 +1577,9 @@ lxb_html_tokenizer_state_markup_declaration_cdata(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_append_m(tkz, "[CDATA", 6); + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_CDINHTCO); + tkz->state = lxb_html_tokenizer_state_bogus_comment_before; return data; } @@ -1587,7 +1592,7 @@ lxb_html_tokenizer_state_markup_declaration_cdata(lxb_html_tokenizer_t *tkz, /* * Helper function. No in the specification. For 12.2.5.69 */ -static const lxb_char_t * +const lxb_char_t * lxb_html_tokenizer_state_cdata_section_before(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end) @@ -1661,7 +1666,7 @@ lxb_html_tokenizer_state_cdata_section(lxb_html_tokenizer_t *tkz, } lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1726,7 +1731,7 @@ lxb_html_tokenizer_state_cdata_section_end(lxb_html_tokenizer_t *tkz, tkz->state = lxb_html_tokenizer_state_data_before; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return (data + 1); } @@ -1857,9 +1862,28 @@ lxb_html_tokenizer_state_char_ref_named(lxb_html_tokenizer_t *tkz, */ /* U+003B SEMICOLON character (;) */ if (tkz->is_attribute && tkz->entity_match->key != 0x3B) { + lxb_char_t ch; + + /* + * The "next input character" per the spec is the character immediately + * after the matched entity, not the character that broke the SBST + * lookup. For example, for "¬i;" the match is "¬" + * and the next input character is 'i', not ';'. + * + * If there are trailing characters in the buffer after the match, + * the next input character is the first one after entity_end. + * Otherwise it is *data (the character that terminated the SBST). + */ + if (&tkz->start[tkz->entity_end + 1] < tkz->pos) { + ch = tkz->start[tkz->entity_end + 1]; + } + else { + ch = *data; + } + /* U+003D EQUALS SIGN character (=) or ASCII alphanumeric */ - if (*data == 0x3D - || lexbor_str_res_alphanumeric_character[*data] != LEXBOR_STR_RES_SLIP) + if (ch == 0x3D + || lexbor_str_res_alphanumeric_character[ch] != LEXBOR_STR_RES_SLIP) { return data; } @@ -1902,16 +1926,30 @@ lxb_html_tokenizer_state_char_ref_ambiguous_ampersand(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end) { - /* ASCII alphanumeric */ - /* Skipped, not need */ + const lxb_char_t *begin = data; - /* U+003B SEMICOLON (;) */ - if (*data == 0x3B) { - lxb_html_tokenizer_error_add(tkz->parse_errors, data, - LXB_HTML_TOKENIZER_ERROR_UNNACHRE); + while (data < end) { + /* Not ASCII alphanumeric */ + if (lexbor_str_res_alphanumeric_character[ *data ] == LEXBOR_STR_RES_SLIP) { + lxb_html_tokenizer_state_append_m(tkz, begin, (data - begin)); + + /* U+003B SEMICOLON (;) */ + if (*data == 0x3B) { + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_UNNACHRE); + } + + tkz->state = tkz->state_return; + + return data; + } + + data += 1; } - tkz->state = tkz->state_return; + if (begin < data) { + lxb_html_tokenizer_state_append_m(tkz, begin, (data - begin)); + } return data; } @@ -2002,6 +2040,10 @@ lxb_html_tokenizer_state_char_ref_hexademical(lxb_html_tokenizer_t *tkz, if (*data == ';') { data++; } + else { + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE); + } return lxb_html_tokenizer_state_char_ref_numeric_end(tkz, data, end); } @@ -2032,6 +2074,10 @@ lxb_html_tokenizer_state_char_ref_decimal(lxb_html_tokenizer_t *tkz, if (*data == ';') { data++; } + else { + lxb_html_tokenizer_error_add(tkz->parse_errors, data, + LXB_HTML_TOKENIZER_ERROR_MISEAFCHRE); + } return lxb_html_tokenizer_state_char_ref_numeric_end(tkz, data, end); } diff --git a/ext/lexbor/lexbor/html/tokenizer/state.h b/ext/lexbor/lexbor/html/tokenizer/state.h index 5b095b4249d5..52eaa9a2c07b 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state.h +++ b/ext/lexbor/lexbor/html/tokenizer/state.h @@ -110,6 +110,10 @@ extern "C" { #define lxb_html_tokenizer_state_token_attr_add_m(tkz, attr, v_return) \ do { \ + if (!(tkz->opt & LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE)) { \ + lxb_html_tokenizer_attr_last_duplicate(tkz); \ + } \ + \ attr = lxb_html_token_attr_append(tkz->token, tkz->dobj_token_attr); \ if (attr == NULL) { \ tkz->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; \ @@ -145,6 +149,14 @@ extern "C" { (tkz->token->attr_last->value_end = tkz->last) #define _lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ + if (!(tkz->opt & LXB_HTML_TOKENIZER_OPT_ATTR_KEEP_DUPLICATE)) { \ + lxb_html_tokenizer_attr_last_duplicate(tkz); \ + } \ + \ + if (tkz->token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { \ + lxb_html_tokenizer_validate_close_tag(tkz); \ + } \ + \ tkz->token = tkz->callback_token_done(tkz, tkz->token, \ tkz->callback_token_ctx); \ if (tkz->token == NULL) { \ @@ -154,23 +166,32 @@ extern "C" { return v_end; \ } -#define lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ +#define lxb_html_tokenizer_state_token_text_done_m(tkz, v_end) \ do { \ - if (tkz->token->begin != tkz->token->end) { \ - _lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ + if (tkz->token->text_start != tkz->token->text_end) { \ + _lxb_html_tokenizer_state_token_done_m(tkz, v_end); \ } \ lxb_html_token_clean(tkz->token); \ tkz->pos = tkz->start; \ } \ while (0) -#define lxb_html_tokenizer_state_token_done_wo_check_m(tkz, v_end) \ +#define lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ do { \ _lxb_html_tokenizer_state_token_done_m(tkz, v_end) \ lxb_html_token_clean(tkz->token); \ + tkz->pos = tkz->start; \ } \ while (0) +/* + * This macro is alias; it serves to ensure that when reading the code, + * we clearly understand where checks are not necessary, i.e., we are 100% sure + * that the token has been collected and is ready to be sent. + */ +#define lxb_html_tokenizer_state_token_done_wo_check_m(tkz, v_end) \ + lxb_html_tokenizer_state_token_done_m(tkz, v_end) + #define lxb_html_tokenizer_state_set_text(tkz) \ do { \ tkz->token->text_start = tkz->start; \ @@ -180,7 +201,7 @@ extern "C" { #define lxb_html_tokenizer_state_token_emit_text_not_empty_m(tkz, v_end) \ do { \ - if (tkz->token->begin != tkz->token->end) { \ + if (tkz->start != tkz->pos) { \ tkz->token->tag_id = LXB_TAG__TEXT; \ \ lxb_html_tokenizer_state_set_text(tkz); \ @@ -211,6 +232,11 @@ lxb_html_tokenizer_state_self_closing_start_tag(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end); +LXB_API const lxb_char_t * +lxb_html_tokenizer_state_cdata_section_before(lxb_html_tokenizer_t *tkz, + const lxb_char_t *data, + const lxb_char_t *end); + LXB_API const lxb_char_t * lxb_html_tokenizer_state_cr(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end); diff --git a/ext/lexbor/lexbor/html/tokenizer/state_comment.c b/ext/lexbor/lexbor/html/tokenizer/state_comment.c index fd1c2ead980b..870b54578c62 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_comment.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_comment.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,9 +7,9 @@ #include "lexbor/html/tokenizer/state_comment.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN +LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; +#endif static const lxb_char_t * lxb_html_tokenizer_state_comment_start(lxb_html_tokenizer_t *tkz, @@ -143,8 +143,6 @@ lxb_html_tokenizer_state_comment_start_dash(lxb_html_tokenizer_t *tkz, /* EOF */ else if (*data == 0x00) { if (tkz->is_eof) { - lxb_html_tokenizer_state_append_m(tkz, "-", 1); - lxb_html_tokenizer_error_add(tkz->parse_errors, tkz->last, LXB_HTML_TOKENIZER_ERROR_EOINCO); @@ -452,8 +450,12 @@ lxb_html_tokenizer_state_comment_end_bang(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, const lxb_char_t *end) { + static const lexbor_str_t two = lexbor_str("--!"); + /* U+002D HYPHEN-MINUS (-) */ if (*data == 0x2D) { + lxb_html_tokenizer_state_append_m(tkz, two.data, two.length); + tkz->state = lxb_html_tokenizer_state_comment_end_dash; return (data + 1); @@ -481,6 +483,11 @@ lxb_html_tokenizer_state_comment_end_bang(lxb_html_tokenizer_t *tkz, return end; } + + lxb_html_tokenizer_state_append_m(tkz, two.data, two.length); + } + else { + lxb_html_tokenizer_state_append_m(tkz, two.data, two.length); } tkz->state = lxb_html_tokenizer_state_comment; diff --git a/ext/lexbor/lexbor/html/tokenizer/state_doctype.c b/ext/lexbor/lexbor/html/tokenizer/state_doctype.c index 90466789cc09..7ccb02e08b2a 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_doctype.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_doctype.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,9 @@ #include "lexbor/html/tokenizer/state_doctype.h" #include "lexbor/html/tokenizer/state.h" - -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; +#endif lxb_dom_attr_data_t * lxb_dom_attr_local_name_append(lexbor_hash_t *hash, @@ -527,6 +526,7 @@ lxb_html_tokenizer_state_doctype_after_name_public(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA); + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; tkz->state = lxb_html_tokenizer_state_doctype_bogus; return data; @@ -577,6 +577,7 @@ lxb_html_tokenizer_state_doctype_after_name_system(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_INCHSEAFDONA); + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; tkz->state = lxb_html_tokenizer_state_doctype_bogus; return data; @@ -797,6 +798,7 @@ lxb_html_tokenizer_state_doctype_public_identifier_double_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOPUID); @@ -912,6 +914,7 @@ lxb_html_tokenizer_state_doctype_public_identifier_single_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOPUID); @@ -1350,6 +1353,7 @@ lxb_html_tokenizer_state_doctype_system_identifier_double_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOSYID); @@ -1465,6 +1469,7 @@ lxb_html_tokenizer_state_doctype_system_identifier_single_quoted(lxb_html_tokeni /* U+003E GREATER-THAN SIGN (>) */ case 0x3E: tkz->state = lxb_html_tokenizer_state_data_before; + tkz->token->type |= LXB_HTML_TOKEN_TYPE_FORCE_QUIRKS; lxb_html_tokenizer_error_add(tkz->parse_errors, data, LXB_HTML_TOKENIZER_ERROR_ABDOSYID); diff --git a/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c b/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c index 6629ca910342..456266b6e33a 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_rawtext.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,10 @@ #include "lexbor/html/tokenizer/state_rawtext.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; +#endif const lxb_tag_data_t * lxb_tag_append_lower(lexbor_hash_t *hash, @@ -114,7 +114,7 @@ lxb_html_tokenizer_state_rawtext(lxb_html_tokenizer_t *tkz, tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -246,7 +246,7 @@ lxb_html_tokenizer_state_rawtext_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -291,7 +291,7 @@ lxb_html_tokenizer_state_rawtext_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; diff --git a/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c b/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c index f47dc7e87a22..02e68b324546 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_rcdata.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,10 +7,10 @@ #include "lexbor/html/tokenizer/state_rcdata.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; +#endif const lxb_tag_data_t * lxb_tag_append_lower(lexbor_hash_t *hash, @@ -123,7 +123,7 @@ lxb_html_tokenizer_state_rcdata(lxb_html_tokenizer_t *tkz, tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -255,7 +255,7 @@ lxb_html_tokenizer_state_rcdata_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -300,7 +300,7 @@ lxb_html_tokenizer_state_rcdata_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; diff --git a/ext/lexbor/lexbor/html/tokenizer/state_script.c b/ext/lexbor/lexbor/html/tokenizer/state_script.c index 188cf08f9f6f..26e694f8f517 100644 --- a/ext/lexbor/lexbor/html/tokenizer/state_script.c +++ b/ext/lexbor/lexbor/html/tokenizer/state_script.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -7,12 +7,11 @@ #include "lexbor/html/tokenizer/state_script.h" #include "lexbor/html/tokenizer/state.h" -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; + LXB_EXTERN const size_t lexbor_str_res_replacement_character[160]; + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; +#endif const lxb_tag_data_t * lxb_tag_append_lower(lexbor_hash_t *hash, @@ -203,7 +202,7 @@ lxb_html_tokenizer_state_script_data(lxb_html_tokenizer_t *tkz, tkz->token->tag_id = LXB_TAG__TEXT; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -347,7 +346,7 @@ lxb_html_tokenizer_state_script_data_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -364,6 +363,7 @@ lxb_html_tokenizer_state_script_data_end_tag_name(lxb_html_tokenizer_t *tkz, if (lexbor_str_res_alpha_character[*data] == LEXBOR_STR_RES_SLIP) { + lxb_html_tokenizer_state_append_data_m(tkz, data); goto anything_else; } @@ -390,7 +390,7 @@ lxb_html_tokenizer_state_script_data_end_tag_name(lxb_html_tokenizer_t *tkz, tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -516,7 +516,7 @@ lxb_html_tokenizer_state_script_data_escaped(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -580,7 +580,7 @@ lxb_html_tokenizer_state_script_data_escaped_dash(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -757,7 +757,7 @@ lxb_html_tokenizer_state_script_data_escaped_end_tag_name( tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -801,7 +801,7 @@ lxb_html_tokenizer_state_script_data_escaped_end_tag_name( tkz->pos = &tkz->start[tkz->entity_start]; lxb_html_tokenizer_state_set_text(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); /* Init close token */ tkz->token->tag_id = tkz->tmp_tag_id; @@ -946,7 +946,7 @@ lxb_html_tokenizer_state_script_data_double_escaped(lxb_html_tokenizer_t *tkz, lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1010,7 +1010,7 @@ lxb_html_tokenizer_state_script_data_double_escaped_dash(lxb_html_tokenizer_t *t lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } @@ -1076,7 +1076,7 @@ lxb_html_tokenizer_state_script_data_double_escaped_dash_dash( lxb_html_tokenizer_state_set_text(tkz); lxb_html_tokenizer_state_token_set_end_eof(tkz); - lxb_html_tokenizer_state_token_done_m(tkz, end); + lxb_html_tokenizer_state_token_text_done_m(tkz, end); return end; } diff --git a/ext/lexbor/lexbor/html/tree.c b/ext/lexbor/lexbor/html/tree.c index 91bfd17ee1db..3f4c18d7fa40 100644 --- a/ext/lexbor/lexbor/html/tree.c +++ b/ext/lexbor/lexbor/html/tree.c @@ -19,6 +19,7 @@ #include "lexbor/html/interface.h" #include "lexbor/html/interfaces/template_element.h" #include "lexbor/html/interfaces/unknown_element.h" +#include "lexbor/html/interfaces/option_element.h" #include "lexbor/html/tokenizer/state_rawtext.h" #include "lexbor/html/tokenizer/state_rcdata.h" @@ -390,7 +391,8 @@ lxb_html_tree_appropriate_place_inserting_node(lxb_html_tree_t *tree, lxb_html_element_t * lxb_html_tree_insert_foreign_element(lxb_html_tree_t *tree, - lxb_html_token_t *token, lxb_ns_id_t ns) + lxb_html_token_t *token, lxb_ns_id_t ns, + bool only_add_stack) { lxb_status_t status; lxb_dom_node_t *pos; @@ -407,7 +409,9 @@ lxb_html_tree_insert_foreign_element(lxb_html_tree_t *tree, return NULL; } - lxb_html_tree_insert_node(pos, lxb_dom_interface_node(element), ipos); + if (only_add_stack == false) { + lxb_html_tree_insert_node(pos, lxb_dom_interface_node(element), ipos); + } status = lxb_html_tree_open_elements_push(tree, lxb_dom_interface_node(element)); @@ -1033,44 +1037,7 @@ lxb_html_tree_reset_insertion_mode_appropriately(lxb_html_tree_t *tree) continue; } - /* Step 4 */ - if (node->local_name == LXB_TAG_SELECT) { - /* Step 4.1 */ - if (last) { - tree->mode = lxb_html_tree_insertion_mode_in_select; - return; - } - - /* Step 4.2 */ - size_t ancestor = idx; - - for (;;) { - /* Step 4.3 */ - if (ancestor == 0) { - tree->mode = lxb_html_tree_insertion_mode_in_select; - return; - } - - /* Step 4.4 */ - ancestor--; - - /* Step 4.5 */ - lxb_dom_node_t *ancestor_node = list[ancestor]; - - if(lxb_html_tree_node_is(ancestor_node, LXB_TAG_TEMPLATE)) { - tree->mode = lxb_html_tree_insertion_mode_in_select; - return; - } - - /* Step 4.6 */ - else if(lxb_html_tree_node_is(ancestor_node, LXB_TAG_TABLE)) { - tree->mode = lxb_html_tree_insertion_mode_in_select_in_table; - return; - } - } - } - - /* Step 5-15 */ + /* Step 4-15 */ switch (node->local_name) { case LXB_TAG_TD: case LXB_TAG_TH: @@ -1309,6 +1276,41 @@ lxb_html_tree_element_in_scope_td_th(lxb_html_tree_t *tree) return NULL; } +lxb_dom_node_t * +lxb_html_tree_element_in_scope_option_optgroup(lxb_html_tree_t *tree) +{ + lxb_dom_node_t *node; + + size_t idx = tree->open_elements->length; + void **list = tree->open_elements->list; + + while (idx != 0) { + idx--; + node = list[idx]; + + switch (node->local_name) { + case LXB_TAG_OPTION: + case LXB_TAG_OPTGROUP: + if (node->ns == LXB_NS_HTML) { + return node; + } + + break; + + default: + break; + } + + if (lxb_html_tag_is_category(node->local_name, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE)) + { + return NULL; + } + } + + return NULL; +} + bool lxb_html_tree_check_scope_element(lxb_html_tree_t *tree) { @@ -1362,8 +1364,6 @@ lxb_html_tree_close_p_element(lxb_html_tree_t *tree, lxb_html_token_t *token) true); } -#include "lexbor/html/serialize.h" - bool lxb_html_tree_adoption_agency_algorithm(lxb_html_tree_t *tree, lxb_html_token_t *token, diff --git a/ext/lexbor/lexbor/html/tree.h b/ext/lexbor/lexbor/html/tree.h index 8ad32a4c1bec..7b2c62030497 100644 --- a/ext/lexbor/lexbor/html/tree.h +++ b/ext/lexbor/lexbor/html/tree.h @@ -114,7 +114,8 @@ lxb_html_tree_appropriate_place_inserting_node(lxb_html_tree_t *tree, LXB_API lxb_html_element_t * lxb_html_tree_insert_foreign_element(lxb_html_tree_t *tree, - lxb_html_token_t *token, lxb_ns_id_t ns); + lxb_html_token_t *token, lxb_ns_id_t ns, + bool only_add_stack); LXB_API lxb_html_element_t * lxb_html_tree_create_element_for_token(lxb_html_tree_t *tree, @@ -201,6 +202,9 @@ lxb_html_tree_element_in_scope_tbody_thead_tfoot(lxb_html_tree_t *tree); LXB_API lxb_dom_node_t * lxb_html_tree_element_in_scope_td_th(lxb_html_tree_t *tree); +LXB_API lxb_dom_node_t * +lxb_html_tree_element_in_scope_option_optgroup(lxb_html_tree_t *tree); + LXB_API bool lxb_html_tree_check_scope_element(lxb_html_tree_t *tree); @@ -307,7 +311,8 @@ lxb_inline lxb_html_element_t * lxb_html_tree_insert_html_element(lxb_html_tree_t *tree, lxb_html_token_t *token) { - return lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_HTML); + return lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_HTML, + false); } lxb_inline void @@ -374,6 +379,21 @@ lxb_html_tree_attach_document(lxb_html_tree_t *tree, lxb_html_document_t *doc) tree->document = doc; } +lxb_inline bool +lxb_html_tree_is_fragment(lxb_html_tree_t *tree) +{ + return tree->fragment != NULL; +} + +lxb_inline bool +lxb_html_tree_is_fragment_element(lxb_html_tree_t *tree, + lxb_tag_id_t tag_id, lxb_ns_id_t ns) +{ + lxb_dom_node_t *fragment = tree->fragment; + + return lxb_html_tree_is_fragment(tree) + && fragment->local_name == tag_id && fragment->ns == ns; +} #ifdef __cplusplus } /* extern "C" */ diff --git a/ext/lexbor/lexbor/html/tree/error.c b/ext/lexbor/lexbor/html/tree/error.c index 88ad8c44795a..ef36eab8d228 100644 --- a/ext/lexbor/lexbor/html/tree/error.c +++ b/ext/lexbor/lexbor/html/tree/error.c @@ -1,9 +1,10 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ +#include "lexbor/core/str.h" #include "lexbor/html/tree/error.h" @@ -27,3 +28,68 @@ lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, return entry; } + +const lxb_char_t * +lxb_html_tree_error_to_string(lxb_html_tree_error_id_t id, size_t *len) +{ + static const lexbor_str_t unknown = lexbor_str("unknown error"); + + static const lexbor_str_t errors[LXB_HTML_RULES_ERROR_LAST_ENTRY] = { + lexbor_str("unexpected token"), + lexbor_str("unexpected closed token"), + lexbor_str("null character"), + lexbor_str("unexpected character token"), + lexbor_str("unexpected token in initial mode"), + lexbor_str("bad doctype token in initial mode"), + lexbor_str("doctype token in before html mode"), + lexbor_str("unexpected closed token in before html mode"), + lexbor_str("doctype token in before head mode"), + lexbor_str("unexpected closed token in before head mode"), + lexbor_str("doctype token in head mode"), + lexbor_str("non void html element start tag with trailing solidus"), + lexbor_str("head token in head mode"), + lexbor_str("unexpected closed token in head mode"), + lexbor_str("template closed token without opening in head mode"), + lexbor_str("template element is not current in head mode"), + lexbor_str("doctype token in head noscript mode"), + lexbor_str("doctype token after head mode"), + lexbor_str("head token after head mode"), + lexbor_str("doctype token in body mode"), + lexbor_str("bad ending open elements is wrong"), + lexbor_str("open elements is wrong"), + lexbor_str("unexpected element in open elements stack"), + lexbor_str("missing element in open elements stack"), + lexbor_str("no body element in scope"), + lexbor_str("missing element in scope"), + lexbor_str("unexpected element in scope"), + lexbor_str("unexpected element in active formatting stack"), + lexbor_str("unexpected end of file"), + lexbor_str("characters in table text"), + lexbor_str("doctype token in table mode"), + lexbor_str("doctype token in select mode"), + lexbor_str("doctype token after body mode"), + lexbor_str("doctype token in frameset mode"), + lexbor_str("doctype token after frameset mode"), + lexbor_str("doctype token foreign content mode"), + lexbor_str("select in scope"), + lexbor_str("fragment parsing select in context parse input"), + lexbor_str("fragment parsing select in context parse select"), + lexbor_str("hr parsing select option optgroup in scope"), + lexbor_str("option parsing option in scope"), + lexbor_str("optgroup parsing option optgroup in scope") + }; + + if (id >= (sizeof(errors) / sizeof(lexbor_str_t))) { + if (len != NULL) { + *len = unknown.length; + } + + return unknown.data; + } + + if (len != NULL) { + *len = errors[id].length; + } + + return errors[id].data; +} diff --git a/ext/lexbor/lexbor/html/tree/error.h b/ext/lexbor/lexbor/html/tree/error.h index ed1859f355a6..b1867725ef98 100644 --- a/ext/lexbor/lexbor/html/tree/error.h +++ b/ext/lexbor/lexbor/html/tree/error.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -90,6 +90,18 @@ typedef enum { LXB_HTML_RULES_ERROR_DOTOAFFRMO, /* doctype-token-foreign-content-mode */ LXB_HTML_RULES_ERROR_DOTOFOCOMO, + /* select-in-scope */ + LXB_HTML_RULES_ERROR_SEINSC, + /* fragment-parsing-select-in-context-parse-input */ + LXB_HTML_RULES_ERROR_FRPASEINCOPAIN, + /* fragment-parsing-select-in-context-parse-select */ + LXB_HTML_RULES_ERROR_FRPASEINCOPASE, + /* hr-parsing-select-option-optgroup-in-scope */ + LXB_HTML_RULES_ERROR_HRPASEOPOPINSC, + /* option-parsing-option-in-scope */ + LXB_HTML_RULES_ERROR_OPPAOPINSC, + /* optgroup-parsing-option-optgroup-in-scope */ + LXB_HTML_RULES_ERROR_OPPAOPOPINSC, LXB_HTML_RULES_ERROR_LAST_ENTRY } @@ -108,10 +120,12 @@ LXB_API lxb_html_tree_error_t * lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, lxb_html_token_t *token, lxb_html_tree_error_id_t id); +LXB_API const lxb_char_t * +lxb_html_tree_error_to_string(lxb_html_tree_error_id_t id, size_t *len); + #ifdef __cplusplus } /* extern "C" */ #endif #endif /* LEXBOR_HTML_TREE_ERROR_H */ - diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode.h b/ext/lexbor/lexbor/html/tree/insertion_mode.h index 97cc29fa6aad..5817f3c015fd 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode.h +++ b/ext/lexbor/lexbor/html/tree/insertion_mode.h @@ -91,14 +91,6 @@ LXB_API bool lxb_html_tree_insertion_mode_in_cell(lxb_html_tree_t *tree, lxb_html_token_t *token); -LXB_API bool -lxb_html_tree_insertion_mode_in_select(lxb_html_tree_t *tree, - lxb_html_token_t *token); - -LXB_API bool -lxb_html_tree_insertion_mode_in_select_in_table(lxb_html_tree_t *tree, - lxb_html_token_t *token); - LXB_API bool lxb_html_tree_insertion_mode_in_template(lxb_html_tree_t *tree, lxb_html_token_t *token); diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c b/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c index 900557a59c33..7e546e34fd9c 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c +++ b/ext/lexbor/lexbor/html/tree/insertion_mode/foreign_content.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -8,10 +8,10 @@ #include "lexbor/html/tree/open_elements.h" #include "lexbor/html/interfaces/element.h" -#define LEXBOR_TOKENIZER_CHARS_MAP -#define LEXBOR_STR_RES_ANSI_REPLACEMENT_CHARACTER -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_ansi_replacement_character[4]; + LXB_EXTERN const unsigned char lexbor_tokenizer_chars_map[256]; +#endif lxb_status_t lxb_dom_element_qualified_name_set(lxb_dom_element_t *element, @@ -87,7 +87,8 @@ lxb_html_tree_insertion_mode_foreign_content_anything_else(lxb_html_tree_t *tree tree->before_append_attr = lxb_html_tree_adjust_attributes_svg; } - element = lxb_html_tree_insert_foreign_element(tree, token, node->ns); + element = lxb_html_tree_insert_foreign_element(tree, token, node->ns, + false); if (element == NULL) { tree->before_append_attr = NULL; tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -259,22 +260,19 @@ lxb_html_tree_insertion_mode_foreign_content_all(lxb_html_tree_t *tree, lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - if (tree->fragment != NULL) { - return lxb_html_tree_insertion_mode_foreign_content_anything_else(tree, - token); - } + node = lxb_html_tree_current_node(tree); - do { + while (node != NULL && + !(lxb_html_tree_mathml_text_integration_point(node) + || lxb_html_tree_html_integration_point(node) + || node->ns == LXB_NS_HTML)) + { lxb_html_tree_open_elements_pop(tree); node = lxb_html_tree_current_node(tree); } - while (node && - !(lxb_html_tree_mathml_text_integration_point(node) - || lxb_html_tree_html_integration_point(node) - || node->ns == LXB_NS_HTML)); - return false; + return tree->mode(tree, token); } bool @@ -286,6 +284,10 @@ lxb_html_tree_insertion_mode_foreign_content(lxb_html_tree_t *tree, case LXB_TAG_SCRIPT: return lxb_html_tree_insertion_mode_foreign_content_script_closed(tree, token); + case LXB_TAG_P: + case LXB_TAG_BR: + return lxb_html_tree_insertion_mode_foreign_content_all(tree, + token); default: return lxb_html_tree_insertion_mode_foreign_content_anything_else_closed(tree, token); diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c index 32cc40476948..38610c7cdd27 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c +++ b/ext/lexbor/lexbor/html/tree/insertion_mode/in_body.c @@ -1,19 +1,25 @@ /* - * Copyright (C) 2018-2020 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ -#define LEXBOR_TOKENIZER_CHARS_MAP -#include "lexbor/core/str_res.h" - #include "lexbor/html/tree/insertion_mode.h" #include "lexbor/html/tree/open_elements.h" #include "lexbor/html/tree/active_formatting.h" #include "lexbor/html/interfaces/head_element.h" +#include "lexbor/html/interfaces/option_element.h" #include "lexbor/html/tokenizer/state.h" +#include "lexbor/html/parser.h" #include "lexbor/html/tokenizer/state_rcdata.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const unsigned char lexbor_tokenizer_chars_map[256]; +#endif + +static bool +lxb_html_tree_insertion_mode_in_body_anything_else_closed(lxb_html_tree_t *tree, + lxb_html_token_t *token); /* * User case insertion mode. @@ -691,7 +697,7 @@ lxb_html_tree_insertion_mode_in_body_button(lxb_html_tree_t *tree, * "address", "article", "aside", "blockquote", "button", "center", "details", * "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", * "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", "section", - * "summary", "ul" + * "select", "summary", "ul" */ lxb_inline bool lxb_html_tree_insertion_mode_in_body_abcdfhlmnopsu_closed(lxb_html_tree_t *tree, @@ -1204,13 +1210,63 @@ lxb_html_tree_insertion_mode_in_body_br_closed(lxb_html_tree_t *tree, return lxb_html_tree_insertion_mode_in_body_abeikw(tree, token); } +lxb_inline bool +lxb_html_tree_insertion_mode_in_body_option_closed(lxb_html_tree_t *tree, + lxb_html_token_t *token) +{ + bool is; + size_t index; + lxb_dom_node_t *node; + lxb_html_option_element_t *option; + lxb_dom_exception_code_t code; + + node = lxb_html_tree_open_elements_find_reverse(tree, LXB_TAG_OPTION, + LXB_NS_HTML, &index); + + lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree, token); + + if (node != NULL) { + is = lxb_html_tree_open_elements_find_by_node(tree, node, &index); + + if (!is) { + option = lxb_html_interface_option(node); + + code = lxb_html_option_maybe_clone_to_selectedcontent(option); + if (code != LXB_DOM_EXCEPTION_OK) { + tree->status = LXB_STATUS_ERROR; + + return lxb_html_tree_process_abort(tree); + } + } + } + + return true; +} + lxb_inline bool lxb_html_tree_insertion_mode_in_body_input(lxb_html_tree_t *tree, lxb_html_token_t *token) { + bool is; + lxb_dom_node_t *node; lxb_dom_attr_t *attr; lxb_html_element_t *element; + is = lxb_html_tree_is_fragment_element(tree, LXB_TAG_SELECT, LXB_NS_HTML); + if (is) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_FRPASEINCOPAIN); + return true; + } + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_SEINSC); + lxb_html_tree_open_elements_pop_until_node(tree, node, true); + } + + tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); if (tree->status != LXB_STATUS_OK) { return lxb_html_tree_process_abort(tree); @@ -1277,6 +1333,19 @@ lxb_html_tree_insertion_mode_in_body_hr(lxb_html_tree_t *tree, lxb_html_tree_close_p_element(tree, token); } + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF, + LXB_NS__UNDEF); + + node = lxb_html_tree_element_in_scope_option_optgroup(tree); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_HRPASEOPOPINSC); + } + } + element = lxb_html_tree_insert_html_element(tree, token); if (element == NULL) { tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -1396,8 +1465,25 @@ lxb_inline bool lxb_html_tree_insertion_mode_in_body_select(lxb_html_tree_t *tree, lxb_html_token_t *token) { + bool is; + lxb_dom_node_t *node; lxb_html_element_t *element; + is = lxb_html_tree_is_fragment_element(tree, LXB_TAG_SELECT, LXB_NS_HTML); + if (is) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_FRPASEINCOPASE); + return true; + } + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_SEINSC); + lxb_html_tree_open_elements_pop_until_node(tree, node, true); + return true; + } + tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); if (tree->status != LXB_STATUS_OK) { return lxb_html_tree_process_abort(tree); @@ -1412,34 +1498,81 @@ lxb_html_tree_insertion_mode_in_body_select(lxb_html_tree_t *tree, tree->frameset_ok = false; - if (tree->mode == lxb_html_tree_insertion_mode_in_table - || tree->mode == lxb_html_tree_insertion_mode_in_caption - || tree->mode == lxb_html_tree_insertion_mode_in_table_body - || tree->mode == lxb_html_tree_insertion_mode_in_row - || tree->mode == lxb_html_tree_insertion_mode_in_cell) - { - tree->mode = lxb_html_tree_insertion_mode_in_select_in_table; + return true; +} + +/* + * "option" + */ +lxb_inline bool +lxb_html_tree_insertion_mode_in_body_option(lxb_html_tree_t *tree, + lxb_html_token_t *token) +{ + lxb_dom_node_t *node; + lxb_html_element_t *element; + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG_OPTGROUP, + LXB_NS_HTML); + + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_OPTION, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_OPPAOPINSC); + } } else { - tree->mode = lxb_html_tree_insertion_mode_in_select; + node = lxb_html_tree_current_node(tree); + if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { + lxb_html_tree_open_elements_pop(tree); + } + } + + tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); + if (tree->status != LXB_STATUS_OK) { + return lxb_html_tree_process_abort(tree); + } + + element = lxb_html_tree_insert_html_element(tree, token); + if (element == NULL) { + tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + + return lxb_html_tree_process_abort(tree); } return true; } /* - * "optgroup", "option" + * "optgroup" */ lxb_inline bool -lxb_html_tree_insertion_mode_in_body_optopt(lxb_html_tree_t *tree, - lxb_html_token_t *token) +lxb_html_tree_insertion_mode_in_body_optgroup(lxb_html_tree_t *tree, + lxb_html_token_t *token) { lxb_dom_node_t *node; lxb_html_element_t *element; - node = lxb_html_tree_current_node(tree); - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); + node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, + LXB_HTML_TAG_CATEGORY_SCOPE); + if (node != NULL) { + lxb_html_tree_generate_implied_end_tags(tree, LXB_TAG__UNDEF, + LXB_NS__UNDEF); + + node = lxb_html_tree_element_in_scope_option_optgroup(tree); + if (node != NULL) { + lxb_html_tree_parse_error(tree, token, + LXB_HTML_RULES_ERROR_OPPAOPOPINSC); + } + } + else { + node = lxb_html_tree_current_node(tree); + if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { + lxb_html_tree_open_elements_pop(tree); + } } tree->status = lxb_html_tree_active_formatting_reconstruct_elements(tree); @@ -1539,7 +1672,8 @@ lxb_html_tree_insertion_mode_in_body_math(lxb_html_tree_t *tree, tree->before_append_attr = lxb_html_tree_adjust_attributes_mathml; - element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_MATH); + element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_MATH, + false); if (element == NULL) { tree->before_append_attr = NULL; tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -1570,7 +1704,8 @@ lxb_html_tree_insertion_mode_in_body_svg(lxb_html_tree_t *tree, tree->before_append_attr = lxb_html_tree_adjust_attributes_svg; - element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_SVG); + element = lxb_html_tree_insert_foreign_element(tree, token, LXB_NS_SVG, + false); if (element == NULL) { tree->before_append_attr = NULL; tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; @@ -1643,7 +1778,7 @@ lxb_html_tree_insertion_mode_in_body_noscript(lxb_html_tree_t *tree, return true; } -lxb_inline bool +static bool lxb_html_tree_insertion_mode_in_body_anything_else_closed(lxb_html_tree_t *tree, lxb_html_token_t *token) { @@ -1719,7 +1854,9 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, case LXB_TAG_NAV: case LXB_TAG_OL: case LXB_TAG_PRE: + case LXB_TAG_SEARCH: case LXB_TAG_SECTION: + case LXB_TAG_SELECT: case LXB_TAG_SUMMARY: case LXB_TAG_UL: return lxb_html_tree_insertion_mode_in_body_abcdfhlmnopsu_closed(tree, @@ -1770,6 +1907,10 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, return lxb_html_tree_insertion_mode_in_body_br_closed(tree, token); + case LXB_TAG_OPTION: + return lxb_html_tree_insertion_mode_in_body_option_closed(tree, + token); + default: return lxb_html_tree_insertion_mode_in_body_anything_else_closed(tree, token); @@ -1831,6 +1972,7 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, case LXB_TAG_NAV: case LXB_TAG_OL: case LXB_TAG_P: + case LXB_TAG_SEARCH: case LXB_TAG_SECTION: case LXB_TAG_SUMMARY: case LXB_TAG_UL: @@ -1934,9 +2076,11 @@ lxb_html_tree_insertion_mode_in_body(lxb_html_tree_t *tree, case LXB_TAG_SELECT: return lxb_html_tree_insertion_mode_in_body_select(tree, token); - case LXB_TAG_OPTGROUP: case LXB_TAG_OPTION: - return lxb_html_tree_insertion_mode_in_body_optopt(tree, token); + return lxb_html_tree_insertion_mode_in_body_option(tree, token); + + case LXB_TAG_OPTGROUP: + return lxb_html_tree_insertion_mode_in_body_optgroup(tree, token); case LXB_TAG_RB: case LXB_TAG_RTC: diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c index 78e4c5919fe7..1b40ecf62d86 100644 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c +++ b/ext/lexbor/lexbor/html/tree/insertion_mode/in_head_noscript.c @@ -101,6 +101,13 @@ lxb_html_tree_insertion_mode_in_head_noscript_closed(lxb_html_tree_t *tree, token); } + if (token->tag_id == LXB_TAG_NOSCRIPT) { + lxb_html_tree_open_elements_pop(tree); + tree->mode = lxb_html_tree_insertion_mode_in_head; + + return true; + } + lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); return true; diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_select.c deleted file mode 100644 index b4eed2c5d3a8..000000000000 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2018-2020 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#include "lexbor/html/tree/insertion_mode.h" -#include "lexbor/html/tree/open_elements.h" - - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_text(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lexbor_str_t str; - - if (token->null_count != 0) { - lxb_html_tree_parse_error(tree, token, - LXB_HTML_RULES_ERROR_NUCH); - - tree->status = lxb_html_token_make_text_drop_null(token, &str, - tree->document->dom_document.text); - } - else { - tree->status = lxb_html_token_make_text(token, &str, - tree->document->dom_document.text); - } - - if (tree->status != LXB_STATUS_OK) { - return lxb_html_tree_process_abort(tree); - } - - /* Can be zero only if all NULL are gone */ - if (str.length == 0) { - lexbor_str_destroy(&str, tree->document->dom_document.text, false); - - return true; - } - - tree->status = lxb_html_tree_insert_character_for_data(tree, &str, NULL); - if (tree->status != LXB_STATUS_OK) { - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_comment(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_comment_t *comment; - - comment = lxb_html_tree_insert_comment(tree, token, NULL); - if (comment == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_doctype(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_DOTOINSEMO); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_html(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_body(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_option(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_element_t *element; - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); - } - - element = lxb_html_tree_insert_html_element(tree, token); - if (element == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_optgroup(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_element_t *element; - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); - } - - node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP)) { - lxb_html_tree_open_elements_pop(tree); - } - - element = lxb_html_tree_insert_html_element(tree, token); - if (element == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_hr(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_element_t *element; - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION)) { - lxb_html_tree_open_elements_pop(tree); - } - - node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP)) { - lxb_html_tree_open_elements_pop(tree); - } - - element = lxb_html_tree_insert_html_element(tree, token); - if (element == NULL) { - tree->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - - return lxb_html_tree_process_abort(tree); - } - - lxb_html_tree_open_elements_pop(tree); - - lxb_html_tree_acknowledge_token_self_closing(tree, token); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_optgroup_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION) - && tree->open_elements->length > 1) - { - node = lxb_html_tree_open_elements_get(tree, - tree->open_elements->length - 2); - if (node != NULL && lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP)) { - lxb_html_tree_open_elements_pop(tree); - } - } - - node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTGROUP) == false) { - lxb_html_tree_parse_error(tree, token, - LXB_HTML_RULES_ERROR_UNELINOPELST); - return true; - } - - lxb_html_tree_open_elements_pop(tree); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_option_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node = lxb_html_tree_current_node(tree); - - if (lxb_html_tree_node_is(node, LXB_TAG_OPTION) == false) { - lxb_html_tree_parse_error(tree, token, - LXB_HTML_RULES_ERROR_UNELINOPELST); - return true; - } - - lxb_html_tree_open_elements_pop(tree); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_select_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT); - if (node == NULL) { - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO); - - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_select(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT); - if (node == NULL) { - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return true; -} - -/* - * "input", "keygen", "textarea" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_ikt(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - node = lxb_html_tree_element_in_scope(tree, LXB_TAG_SELECT, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_SELECT); - if (node == NULL) { - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return false; -} - -/* - * A start tag whose tag name is one of: "script", "template" - * An end tag whose tag name is "template" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_st_open_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_head(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_end_of_file(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_body(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_anything_else(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - return true; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_anything_else_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO); - - return true; -} - -bool -lxb_html_tree_insertion_mode_in_select(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { - switch (token->tag_id) { - case LXB_TAG_OPTGROUP: - return lxb_html_tree_insertion_mode_in_select_optgroup_closed(tree, - token); - case LXB_TAG_OPTION: - return lxb_html_tree_insertion_mode_in_select_option_closed(tree, - token); - case LXB_TAG_SELECT: - return lxb_html_tree_insertion_mode_in_select_select_closed(tree, - token); - case LXB_TAG_TEMPLATE: - return lxb_html_tree_insertion_mode_in_select_st_open_closed(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_anything_else_closed(tree, - token); - } - } - - switch (token->tag_id) { - case LXB_TAG__TEXT: - return lxb_html_tree_insertion_mode_in_select_text(tree, token); - - case LXB_TAG__EM_COMMENT: - return lxb_html_tree_insertion_mode_in_select_comment(tree, token); - - case LXB_TAG__EM_DOCTYPE: - return lxb_html_tree_insertion_mode_in_select_doctype(tree, token); - - case LXB_TAG_HTML: - return lxb_html_tree_insertion_mode_in_select_html(tree, token); - - case LXB_TAG_OPTION: - return lxb_html_tree_insertion_mode_in_select_option(tree, token); - - case LXB_TAG_OPTGROUP: - return lxb_html_tree_insertion_mode_in_select_optgroup(tree, token); - - case LXB_TAG_HR: - return lxb_html_tree_insertion_mode_in_select_hr(tree, token); - - case LXB_TAG_SELECT: - return lxb_html_tree_insertion_mode_in_select_select(tree, token); - - case LXB_TAG_INPUT: - case LXB_TAG_KEYGEN: - case LXB_TAG_TEXTAREA: - return lxb_html_tree_insertion_mode_in_select_ikt(tree, token); - - case LXB_TAG_SCRIPT: - case LXB_TAG_TEMPLATE: - return lxb_html_tree_insertion_mode_in_select_st_open_closed(tree, - token); - case LXB_TAG__END_OF_FILE: - return lxb_html_tree_insertion_mode_in_select_end_of_file(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_anything_else(tree, - token); - } -} diff --git a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select_in_table.c b/ext/lexbor/lexbor/html/tree/insertion_mode/in_select_in_table.c deleted file mode 100644 index 7db2e259191e..000000000000 --- a/ext/lexbor/lexbor/html/tree/insertion_mode/in_select_in_table.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2018-2019 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#include "lexbor/html/tree/insertion_mode.h" -#include "lexbor/html/tree/open_elements.h" - - -/* - * "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_ct(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNTO); - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return false; -} - -/* - * "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th" - */ -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_ct_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - lxb_dom_node_t *node; - - lxb_html_tree_parse_error(tree, token, LXB_HTML_RULES_ERROR_UNCLTO); - - node = lxb_html_tree_element_in_scope(tree, token->tag_id, LXB_NS_HTML, - LXB_HTML_TAG_CATEGORY_SCOPE_TABLE); - if (node == NULL) { - return true; - } - - lxb_html_tree_open_elements_pop_until_tag_id(tree, LXB_TAG_SELECT, - LXB_NS_HTML, true); - - lxb_html_tree_reset_insertion_mode_appropriately(tree); - - return false; -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_anything_else(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_select(tree, token); -} - -lxb_inline bool -lxb_html_tree_insertion_mode_in_select_in_table_anything_else_closed(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else(tree, - token); -} - -bool -lxb_html_tree_insertion_mode_in_select_in_table(lxb_html_tree_t *tree, - lxb_html_token_t *token) -{ - if (token->tag_id >= LXB_TAG__LAST_ENTRY) { - if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else_closed(tree, - token); - } - - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else(tree, - token); - } - - if (token->type & LXB_HTML_TOKEN_TYPE_CLOSE) { - switch (token->tag_id) { - case LXB_TAG_CAPTION: - case LXB_TAG_TABLE: - case LXB_TAG_TBODY: - case LXB_TAG_TFOOT: - case LXB_TAG_THEAD: - case LXB_TAG_TR: - case LXB_TAG_TH: - case LXB_TAG_TD: - return lxb_html_tree_insertion_mode_in_select_in_table_ct_closed(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else_closed(tree, - token); - } - } - - switch (token->tag_id) { - case LXB_TAG_CAPTION: - case LXB_TAG_TABLE: - case LXB_TAG_TBODY: - case LXB_TAG_TFOOT: - case LXB_TAG_THEAD: - case LXB_TAG_TR: - case LXB_TAG_TH: - case LXB_TAG_TD: - return lxb_html_tree_insertion_mode_in_select_in_table_ct(tree, - token); - default: - return lxb_html_tree_insertion_mode_in_select_in_table_anything_else(tree, - token); - } -} diff --git a/ext/lexbor/lexbor/ns/base.h b/ext/lexbor/lexbor/ns/base.h index a5b01baa0e6c..94ee0b7f8719 100644 --- a/ext/lexbor/lexbor/ns/base.h +++ b/ext/lexbor/lexbor/ns/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Alexander Borisov + * Copyright (C) 2019-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_NS_VERSION_MAJOR 1 -#define LXB_NS_VERSION_MINOR 2 +#define LXB_NS_VERSION_MINOR 4 #define LXB_NS_VERSION_PATCH 0 #define LXB_NS_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/ns/const.h b/ext/lexbor/lexbor/ns/const.h index 463d8d4998bc..2115629b9bdd 100644 --- a/ext/lexbor/lexbor/ns/const.h +++ b/ext/lexbor/lexbor/ns/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ diff --git a/ext/lexbor/lexbor/ns/ns.c b/ext/lexbor/lexbor/ns/ns.c index 87e870cf627c..4ffd02519c94 100644 --- a/ext/lexbor/lexbor/ns/ns.c +++ b/ext/lexbor/lexbor/ns/ns.c @@ -1,13 +1,14 @@ /* - * Copyright (C) 2018-2019 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ #include "lexbor/core/shs.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#include "lexbor/core/str_res.h" +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; +#endif #include "lexbor/ns/ns.h" #include "lexbor/ns/res.h" diff --git a/ext/lexbor/lexbor/ns/res.h b/ext/lexbor/lexbor/ns/res.h index ca3ab04cb6e7..c953ab074696 100644 --- a/ext/lexbor/lexbor/ns/res.h +++ b/ext/lexbor/lexbor/ns/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2019 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -50,7 +50,7 @@ static const lxb_ns_prefix_data_t lxb_ns_prefix_res_data[LXB_NS__LAST_ENTRY] = {{.u.short_str = "xmlns", .length = 5, .next = NULL}, LXB_NS_XMLNS, 1, true} }; -static const lexbor_shs_entry_t lxb_ns_res_shs_data[] = +static const lexbor_shs_entry_t lxb_ns_res_shs_data[29] = { {NULL, NULL, 28, 0}, {"html", (void *) &lxb_ns_prefix_res_data[2], 4, 0}, {"xmlns", (void *) &lxb_ns_prefix_res_data[7], 5, 0}, {NULL, NULL, 0, 0}, @@ -69,7 +69,7 @@ static const lexbor_shs_entry_t lxb_ns_res_shs_data[] = {"xml", (void *) &lxb_ns_prefix_res_data[6], 3, 0} }; -static const lexbor_shs_entry_t lxb_ns_res_shs_link_data[] = +static const lexbor_shs_entry_t lxb_ns_res_shs_link_data[23] = { {NULL, NULL, 22, 0}, {"http://www.w3.org/1999/xhtml", (void *) &lxb_ns_res_data[2], 28, 0}, diff --git a/ext/lexbor/lexbor/punycode/base.h b/ext/lexbor/lexbor/punycode/base.h index de51606a69a6..ee0c08ae344e 100644 --- a/ext/lexbor/lexbor/punycode/base.h +++ b/ext/lexbor/lexbor/punycode/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Alexander Borisov + * Copyright (C) 2023-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,7 +15,7 @@ extern "C" { #define LXB_PUNYCODE_VERSION_MAJOR 1 -#define LXB_PUNYCODE_VERSION_MINOR 1 +#define LXB_PUNYCODE_VERSION_MINOR 2 #define LXB_PUNYCODE_VERSION_PATCH 0 #define LEXBOR_PUNYCODE_VERSION_STRING LEXBOR_STRINGIZE(LXB_PUNYCODE_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/punycode/punycode.c b/ext/lexbor/lexbor/punycode/punycode.c index 02465a4e00f1..4c3f22ea9bce 100644 --- a/ext/lexbor/lexbor/punycode/punycode.c +++ b/ext/lexbor/lexbor/punycode/punycode.c @@ -138,6 +138,13 @@ lxb_punycode_encode_body(const lxb_codepoint_t *cps, const lxb_codepoint_t *cps_ } if (p > buf) { + if (p >= end) { + p = lxb_punycode_encode_realloc(p, &buf, &end, buffer); + if (p == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + *p++ = LXB_PUNYCODE_DELIMITER; } diff --git a/ext/lexbor/lexbor/selectors/base.h b/ext/lexbor/lexbor/selectors/base.h index 64af0261a75c..19bdda73849a 100644 --- a/ext/lexbor/lexbor/selectors/base.h +++ b/ext/lexbor/lexbor/selectors/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 Alexander Borisov + * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -15,7 +15,7 @@ extern "C" { #define LXB_SELECTORS_VERSION_MAJOR 0 -#define LXB_SELECTORS_VERSION_MINOR 3 +#define LXB_SELECTORS_VERSION_MINOR 6 #define LXB_SELECTORS_VERSION_PATCH 0 #define LXB_SELECTORS_VERSION_STRING LEXBOR_STRINGIZE(LXB_SELECTORS_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/selectors/selectors.c b/ext/lexbor/lexbor/selectors/selectors.c deleted file mode 100644 index 8ad7fc0730c9..000000000000 --- a/ext/lexbor/lexbor/selectors/selectors.c +++ /dev/null @@ -1,1925 +0,0 @@ -/* - * Copyright (C) 2021-2024 Alexander Borisov - * - * Author: Alexander Borisov - */ - -#include "lexbor/selectors/selectors.h" - -#include - - -static lxb_status_t -lxb_selectors_state_tree(lxb_selectors_t *selectors, lxb_dom_node_t *root, - const lxb_css_selector_list_t *list); - -static lxb_status_t -lxb_selectors_state_run(lxb_selectors_t *selectors, lxb_dom_node_t *node, - const lxb_css_selector_list_t *list); - -static lxb_selectors_entry_t * -lxb_selectors_state_find(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); - -static lxb_selectors_entry_t * -lxb_selectors_state_find_check(lxb_selectors_t *selectors, lxb_dom_node_t *node, - const lxb_css_selector_t *selector, - lxb_selectors_entry_t *entry); - -static lxb_selectors_entry_t * -lxb_selectors_state_pseudo_class_function(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); - -static lxb_dom_node_t * -lxb_selectors_next_node(lxb_selectors_nested_t *main); - -static lxb_dom_node_t * -lxb_selectors_state_has_relative(lxb_dom_node_t *node, - const lxb_css_selector_t *selector); - -static lxb_selectors_entry_t * -lxb_selectors_state_after_find_has(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); - -static lxb_selectors_entry_t * -lxb_selectors_state_after_find(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); - -static lxb_selectors_entry_t * -lxb_selectors_state_after_nth_child(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); - -static bool -lxb_selectors_match(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, lxb_dom_node_t *node); - -static bool -lxb_selectors_match_element(const lxb_css_selector_t *selector, - lxb_dom_node_t *node, lxb_selectors_entry_t *entry); - -static bool -lxb_selectors_match_id(const lxb_css_selector_t *selector, lxb_dom_node_t *node); - -static bool -lxb_selectors_match_class(const lexbor_str_t *target, const lexbor_str_t *src, - bool quirks); - -static bool -lxb_selectors_match_attribute(const lxb_css_selector_t *selector, - lxb_dom_node_t *node, lxb_selectors_entry_t *entry); - -static bool -lxb_selectors_pseudo_class(const lxb_css_selector_t *selector, - const lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, - lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_element(const lxb_css_selector_t *selector, - const lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_class_disabled(const lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_class_first_child(const lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_class_first_of_type(const lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_class_last_child(const lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_class_last_of_type(const lxb_dom_node_t *node); - -static bool -lxb_selectors_pseudo_class_read_write(const lxb_dom_node_t *node); - -static bool -lxb_selectors_anb_calc(lxb_css_selector_anb_of_t *anb, size_t index); - -static lxb_status_t -lxb_selectors_cb_ok(lxb_dom_node_t *node, - lxb_css_selector_specificity_t spec, void *ctx); - -static lxb_status_t -lxb_selectors_cb_not(lxb_dom_node_t *node, - lxb_css_selector_specificity_t spec, void *ctx); - - -lxb_selectors_t * -lxb_selectors_create(void) -{ - return lexbor_calloc(1, sizeof(lxb_selectors_t)); -} - -lxb_status_t -lxb_selectors_init(lxb_selectors_t *selectors) -{ - lxb_status_t status; - - if (selectors == NULL) { - return LXB_STATUS_ERROR_INCOMPLETE_OBJECT; - } - - selectors->objs = lexbor_dobject_create(); - status = lexbor_dobject_init(selectors->objs, - 128, sizeof(lxb_selectors_entry_t)); - if (status != LXB_STATUS_OK) { - return status; - } - - selectors->nested = lexbor_dobject_create(); - status = lexbor_dobject_init(selectors->nested, - 64, sizeof(lxb_selectors_nested_t)); - if (status != LXB_STATUS_OK) { - return status; - } - - selectors->options = LXB_SELECTORS_OPT_DEFAULT; - - return LXB_STATUS_OK; -} - -void -lxb_selectors_clean(lxb_selectors_t *selectors) -{ - lexbor_dobject_clean(selectors->objs); - lexbor_dobject_clean(selectors->nested); -} - -lxb_selectors_t * -lxb_selectors_destroy(lxb_selectors_t *selectors, bool self_destroy) -{ - if (selectors == NULL) { - return NULL; - } - - selectors->objs = lexbor_dobject_destroy(selectors->objs, true); - selectors->nested = lexbor_dobject_destroy(selectors->nested, true); - - if (self_destroy) { - return lexbor_free(selectors); - } - - return selectors; -} - -lxb_inline lxb_dom_node_t * -lxb_selectors_descendant(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, - lxb_dom_node_t *node) -{ - node = node->parent; - - while (node != NULL) { - if (node->type == LXB_DOM_NODE_TYPE_ELEMENT - && lxb_selectors_match(selectors, entry, selector, node)) - { - return node; - } - - node = node->parent; - } - - return NULL; -} - -lxb_inline lxb_dom_node_t * -lxb_selectors_close(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, lxb_dom_node_t *node) -{ - if (lxb_selectors_match(selectors, entry, selector, node)) { - return node; - } - - return NULL; -} - -lxb_inline lxb_dom_node_t * -lxb_selectors_child(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, lxb_dom_node_t *root) -{ - root = root->parent; - - if (root != NULL && root->type == LXB_DOM_NODE_TYPE_ELEMENT - && lxb_selectors_match(selectors, entry, selector, root)) - { - return root; - } - - return NULL; -} - -lxb_inline lxb_dom_node_t * -lxb_selectors_sibling(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, lxb_dom_node_t *node) -{ - node = node->prev; - - while (node != NULL) { - if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) { - if (lxb_selectors_match(selectors, entry, selector, node)) { - return node; - } - - return NULL; - } - - node = node->prev; - } - - return NULL; -} - -lxb_inline lxb_dom_node_t * -lxb_selectors_following(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, lxb_dom_node_t *node) -{ - node = node->prev; - - while (node != NULL) { - if (node->type == LXB_DOM_NODE_TYPE_ELEMENT && - lxb_selectors_match(selectors, entry, selector, node)) - { - return node; - } - - node = node->prev; - } - - return NULL; -} - -lxb_status_t -lxb_selectors_find(lxb_selectors_t *selectors, lxb_dom_node_t *root, - const lxb_css_selector_list_t *list, - lxb_selectors_cb_f cb, void *ctx) -{ - lxb_selectors_entry_t *entry; - lxb_selectors_nested_t nested; - - entry = lexbor_dobject_calloc(selectors->objs); - if (entry == NULL) { - return LXB_STATUS_ERROR_MEMORY_ALLOCATION; - } - - entry->combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - entry->selector = list->last; - - nested.parent = NULL; - nested.entry = entry; - nested.cb = cb; - nested.ctx = ctx; - - selectors->current = &nested; - selectors->status = LXB_STATUS_OK; - - return lxb_selectors_state_tree(selectors, root, list); -} - -lxb_status_t -lxb_selectors_match_node(lxb_selectors_t *selectors, lxb_dom_node_t *node, - const lxb_css_selector_list_t *list, - lxb_selectors_cb_f cb, void *ctx) -{ - lxb_status_t status; - lxb_selectors_entry_t *entry; - lxb_selectors_nested_t nested; - - if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) { - return LXB_STATUS_OK; - } - - entry = lexbor_dobject_calloc(selectors->objs); - if (entry == NULL) { - return LXB_STATUS_ERROR_MEMORY_ALLOCATION; - } - - entry->combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - entry->selector = list->last; - - nested.parent = NULL; - nested.entry = entry; - nested.cb = cb; - nested.ctx = ctx; - - selectors->current = &nested; - selectors->status = LXB_STATUS_OK; - - status = lxb_selectors_state_run(selectors, node, list); - - lxb_selectors_clean(selectors); - - return status; -} - -lxb_status_t -lxb_selectors_find_reverse(lxb_selectors_t *selectors, lxb_dom_node_t *root, - lxb_css_selector_list_t *list, - lxb_selectors_cb_f cb, void *ctx) -{ - return lxb_selectors_find(selectors, root, list, cb, ctx); -} - -static lxb_status_t -lxb_selectors_state_tree(lxb_selectors_t *selectors, lxb_dom_node_t *root, - const lxb_css_selector_list_t *list) -{ - lxb_status_t status; - lxb_dom_node_t *node; - - if (selectors->options & LXB_SELECTORS_OPT_MATCH_ROOT) { - node = root; - - if (node->type == LXB_DOM_NODE_TYPE_DOCUMENT) { - node = root->first_child; - } - } - else { - node = root->first_child; - } - - if (node == NULL) { - goto out; - } - - do { - if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) { - goto next; - } - - status = lxb_selectors_state_run(selectors, node, list); - if (status != LXB_STATUS_OK) { - if (status == LXB_STATUS_STOP) { - break; - } - - lxb_selectors_clean(selectors); - - return status; - } - - if (node->first_child != NULL) { - node = node->first_child; - } - else { - - next: - - while (node != root && node->next == NULL) { - node = node->parent; - } - - if (node == root) { - break; - } - - node = node->next; - } - } - while (true); - -out: - lxb_selectors_clean(selectors); - - return LXB_STATUS_OK; -} - -static lxb_status_t -lxb_selectors_state_run(lxb_selectors_t *selectors, lxb_dom_node_t *node, - const lxb_css_selector_list_t *list) -{ - lxb_selectors_entry_t *entry; - - entry = selectors->current->entry; - - entry->node = node; - selectors->state = lxb_selectors_state_find; - selectors->first = entry; - -again: - - do { - entry = selectors->state(selectors, entry); - } - while (entry != NULL); - - if (selectors->current->parent != NULL - && selectors->status == LXB_STATUS_OK) - { - entry = selectors->current->entry; - selectors->state = selectors->current->return_state; - - goto again; - } - - return selectors->status; -} - -static lxb_selectors_entry_t * -lxb_selectors_state_find(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) -{ - lxb_dom_node_t *node; - lxb_selectors_entry_t *next; - const lxb_css_selector_t *selector; - const lxb_css_selector_anb_of_t *anb; - const lxb_css_selector_pseudo_t *pseudo; - - selector = entry->selector; - - if (selector->type == LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS_FUNCTION) { - pseudo = &selector->u.pseudo; - - /* Optimizing. */ - - switch (pseudo->type) { - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD: - anb = pseudo->data; - - if (anb->of != NULL) { - break; - } - - goto godoit; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE: - goto godoit; - - default: - break; - } - - if (entry->nested == NULL) { - next = lexbor_dobject_calloc(selectors->objs); - if (next == NULL) { - selectors->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - return NULL; - } - - next->combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - - entry->nested = lexbor_dobject_calloc(selectors->nested); - if (entry->nested == NULL) { - selectors->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - return NULL; - } - - entry->nested->entry = next; - entry->nested->parent = selectors->current; - } - - selectors->state = lxb_selectors_state_pseudo_class_function; - selectors->current->last = entry; - selectors->current = entry->nested; - - next = entry->nested->entry; - next->node = entry->node; - - return next; - } - -godoit: - - switch (entry->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - node = lxb_selectors_descendant(selectors, entry, - selector, entry->node); - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - node = lxb_selectors_close(selectors, entry, - selector, entry->node); - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - node = lxb_selectors_child(selectors, entry, - selector, entry->node); - break; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - node = lxb_selectors_sibling(selectors, entry, - selector, entry->node); - break; - - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = lxb_selectors_following(selectors, entry, - selector, entry->node); - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CELL: - default: - selectors->status = LXB_STATUS_ERROR; - return NULL; - } - - return lxb_selectors_state_find_check(selectors, node, selector, entry); -} - -static lxb_selectors_entry_t * -lxb_selectors_state_find_check(lxb_selectors_t *selectors, lxb_dom_node_t *node, - const lxb_css_selector_t *selector, - lxb_selectors_entry_t *entry) -{ - lxb_selectors_entry_t *next; - lxb_selectors_nested_t *current; - - if (node == NULL) { - - try_next: - - if (entry->next == NULL) { - - try_next_list: - - if (selector->list->next == NULL) { - return NULL; - } - - /* - * Try the following selectors from the selector list. - */ - - if (entry->following != NULL) { - entry->following->node = entry->node; - - if (selectors->current->parent == NULL) { - selectors->first = entry->following; - } - - return entry->following; - } - - next = lexbor_dobject_calloc(selectors->objs); - if (next == NULL) { - selectors->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - return NULL; - } - - next->combinator = LXB_CSS_SELECTOR_COMBINATOR_CLOSE; - next->selector = selector->list->next->last; - next->node = entry->node; - - entry->following = next; - - if (selectors->current->parent == NULL) { - selectors->first = next; - } - - return next; - } - - do { - entry = entry->next; - - while (entry->combinator == LXB_CSS_SELECTOR_COMBINATOR_CLOSE) { - if (entry->next == NULL) { - selector = entry->selector; - goto try_next; - } - - entry = entry->next; - } - - switch (entry->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - node = entry->node->parent; - - if (node == NULL - || node->type != LXB_DOM_NODE_TYPE_ELEMENT) - { - node = NULL; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = entry->node->prev; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - node = NULL; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CELL: - default: - selectors->status = LXB_STATUS_ERROR; - return NULL; - } - } - while (node == NULL); - - entry->node = node; - - return entry; - } - - if (selector->prev == NULL) { - current = selectors->current; - - selectors->status = current->cb(current->entry->node, - selector->list->specificity, - current->ctx); - - if ((selectors->options & LXB_SELECTORS_OPT_MATCH_FIRST) == 0 - && current->parent == NULL) - { - if (selectors->status == LXB_STATUS_OK) { - entry = selectors->first; - goto try_next_list; - } - } - - return NULL; - } - - if (entry->prev == NULL) { - next = lexbor_dobject_calloc(selectors->objs); - if (next == NULL) { - selectors->status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; - return NULL; - } - - next->combinator = selector->combinator; - next->selector = selector->prev; - next->node = node; - - next->next = entry; - entry->prev = next; - - return next; - } - - entry->prev->node = node; - - return entry->prev; -} - -static lxb_selectors_entry_t * -lxb_selectors_state_pseudo_class_function(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) -{ - lxb_dom_node_t *node, *base; - lxb_selectors_nested_t *current; - const lxb_css_selector_list_t *list; - lxb_css_selector_anb_of_t *anb; - const lxb_css_selector_pseudo_t *pseudo; - - current = selectors->current; - - base = lxb_selectors_next_node(current); - if (base == NULL) { - goto not_found; - } - - pseudo = ¤t->parent->last->selector->u.pseudo; - - switch (pseudo->type) { - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_HAS: - list = (lxb_css_selector_list_t *) pseudo->data; - node = lxb_selectors_state_has_relative(base, list->first); - - if (node == NULL) { - selectors->current = selectors->current->parent; - entry = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, NULL, - entry->selector, entry); - } - - current->root = base; - - current->entry->selector = list->last; - current->entry->node = node; - current->return_state = lxb_selectors_state_after_find_has; - current->cb = lxb_selectors_cb_ok; - current->ctx = ¤t->found; - current->found = false; - - selectors->state = lxb_selectors_state_find; - - return entry; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_CURRENT: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_IS: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_WHERE: - current->entry->selector = ((lxb_css_selector_list_t *) pseudo->data)->last; - current->entry->node = base; - current->return_state = lxb_selectors_state_after_find; - current->cb = lxb_selectors_cb_ok; - current->ctx = ¤t->found; - current->found = false; - - selectors->state = lxb_selectors_state_find; - - return entry; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NOT: - current->entry->selector = ((lxb_css_selector_list_t *) pseudo->data)->last; - current->entry->node = base; - current->return_state = lxb_selectors_state_after_find; - current->cb = lxb_selectors_cb_not; - current->ctx = ¤t->found; - current->found = true; - - selectors->state = lxb_selectors_state_find; - - return entry; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD: - anb = pseudo->data; - - current->entry->selector = anb->of->last; - current->entry->node = base; - current->return_state = lxb_selectors_state_after_nth_child; - current->cb = lxb_selectors_cb_ok; - current->ctx = ¤t->found; - current->root = base; - current->index = 0; - current->found = false; - - selectors->state = lxb_selectors_state_find; - - return entry; - - /* - * This one can only happen if the user has somehow messed up the - * selector. - */ - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL: - default: - break; - } - -not_found: - - selectors->current = selectors->current->parent; - entry = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, NULL, - entry->selector, entry); -} - -static lxb_dom_node_t * -lxb_selectors_next_node(lxb_selectors_nested_t *main) -{ - lxb_dom_node_t *node = main->entry->node; - - switch (main->parent->last->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - if (node->parent == NULL - || node->parent->type != LXB_DOM_NODE_TYPE_ELEMENT) - { - return NULL; - } - - return node->parent; - - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - return node; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->prev; - break; - - default: - return NULL; - } - - while (node != NULL) { - if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) { - break; - } - - node = node->prev; - } - - return node; -} - -static lxb_dom_node_t * -lxb_selectors_state_has_relative(lxb_dom_node_t *node, - const lxb_css_selector_t *selector) -{ - lxb_dom_node_t *root = node; - - switch (selector->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - node = node->first_child; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->next; - break; - - default: - return NULL; - } - - while (node != NULL) { - if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) { - break; - } - - while (node !=root && node->next == NULL && node->parent != NULL) { - node = node->parent; - } - - if (node == root) { - return NULL; - } - - node = node->next; - } - - return node; -} - -static lxb_selectors_entry_t * -lxb_selectors_state_after_find_has(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) -{ - lxb_dom_node_t *node; - lxb_selectors_entry_t *parent; - lxb_selectors_nested_t *current; - - if (selectors->current->found) { - node = selectors->current->root; - - selectors->current = selectors->current->parent; - parent = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); - } - - current = selectors->current; - node = entry->node; - - switch (entry->selector->list->first->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - if (node->first_child != NULL) { - node = node->first_child; - } - else { - - next: - - while (node != current->root && node->next == NULL) { - node = node->parent; - } - - if (node == current->root) { - goto failed; - } - - node = node->next; - } - - if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) { - goto next; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->next; - - while (node != NULL && node->type != LXB_DOM_NODE_TYPE_ELEMENT) { - node = node->next; - } - - if (node == NULL) { - goto failed; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - goto failed; - - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - case LXB_CSS_SELECTOR_COMBINATOR_CELL: - default: - selectors->status = LXB_STATUS_ERROR; - return NULL; - } - - entry->node = node; - selectors->state = lxb_selectors_state_find; - - return entry; - -failed: - - selectors->current = selectors->current->parent; - parent = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, NULL, - parent->selector, parent); -} - - -static lxb_selectors_entry_t * -lxb_selectors_state_after_find(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) -{ - lxb_dom_node_t *node; - lxb_selectors_entry_t *parent; - lxb_selectors_nested_t *current; - - current = selectors->current; - - if (current->found) { - node = entry->node; - - selectors->current = current->parent; - parent = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); - } - - node = entry->node; - - switch (current->parent->last->combinator) { - case LXB_CSS_SELECTOR_COMBINATOR_DESCENDANT: - if (node->parent != NULL - && node->parent->type == LXB_DOM_NODE_TYPE_ELEMENT) - { - node = node->parent; - } - else { - node = NULL; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_FOLLOWING: - node = node->prev; - - while (node != NULL && node->type != LXB_DOM_NODE_TYPE_ELEMENT) { - node = node->prev; - } - - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CHILD: - case LXB_CSS_SELECTOR_COMBINATOR_SIBLING: - case LXB_CSS_SELECTOR_COMBINATOR_CLOSE: - node = NULL; - break; - - case LXB_CSS_SELECTOR_COMBINATOR_CELL: - default: - selectors->status = LXB_STATUS_ERROR; - return NULL; - } - - if (node == NULL) { - selectors->current = current->parent; - parent = selectors->current->last; - - selectors->state = lxb_selectors_state_find; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); - } - - entry->node = node; - selectors->state = lxb_selectors_state_find; - - return entry; -} - -static lxb_selectors_entry_t * -lxb_selectors_state_after_nth_child(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry) -{ - bool found; - lxb_dom_node_t *node; - lxb_selectors_entry_t *parent; - lxb_selectors_nested_t *current; - const lxb_css_selector_t *selector; - const lxb_css_selector_pseudo_t *pseudo; - - current = selectors->current; - selector = current->parent->last->selector; - pseudo = &selector->u.pseudo; - - node = entry->node; - - if (current->found) { - current->index += 1; - } - else if (current->root == node) { - node = NULL; - goto done; - } - - if (pseudo->type == LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD) { - node = node->prev; - - while (node != NULL) { - if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) { - break; - } - - node = node->prev; - } - } - else { - node = node->next; - - while (node != NULL) { - if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) { - break; - } - - node = node->next; - } - } - - if (node == NULL) { - goto done; - } - - entry->node = node; - current->found = false; - selectors->state = lxb_selectors_state_find; - - return entry; - -done: - - if (current->index > 0) { - found = lxb_selectors_anb_calc(pseudo->data, current->index); - - node = (found) ? current->root : NULL; - } - - selectors->state = lxb_selectors_state_find; - selectors->current = selectors->current->parent; - - parent = selectors->current->last; - - return lxb_selectors_state_find_check(selectors, node, - parent->selector, parent); -} - -static bool -lxb_selectors_match(lxb_selectors_t *selectors, lxb_selectors_entry_t *entry, - const lxb_css_selector_t *selector, lxb_dom_node_t *node) -{ - lxb_dom_element_t *element; - - switch (selector->type) { - case LXB_CSS_SELECTOR_TYPE_ANY: - return true; - - case LXB_CSS_SELECTOR_TYPE_ELEMENT: - return lxb_selectors_match_element(selector, node, entry); - - case LXB_CSS_SELECTOR_TYPE_ID: - return lxb_selectors_match_id(selector, node); - - case LXB_CSS_SELECTOR_TYPE_CLASS: - element = lxb_dom_interface_element(node); - - if (element->attr_class == NULL - || element->attr_class->value == NULL) - { - return false; - } - - return lxb_selectors_match_class(element->attr_class->value, - &selector->name, true); - - case LXB_CSS_SELECTOR_TYPE_ATTRIBUTE: - return lxb_selectors_match_attribute(selector, node, entry); - - case LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS: - return lxb_selectors_pseudo_class(selector, node); - - case LXB_CSS_SELECTOR_TYPE_PSEUDO_CLASS_FUNCTION: - return lxb_selectors_pseudo_class_function(selector, node); - - case LXB_CSS_SELECTOR_TYPE_PSEUDO_ELEMENT: - return lxb_selectors_pseudo_element(selector, node); - - case LXB_CSS_SELECTOR_TYPE_PSEUDO_ELEMENT_FUNCTION: - return false; - - default: - break; - } - - return false; -} - -static bool -lxb_selectors_match_element(const lxb_css_selector_t *selector, - lxb_dom_node_t *node, lxb_selectors_entry_t *entry) -{ - lxb_tag_id_t tag_id; - - if (entry->id == 0) { - tag_id = lxb_tag_id_by_name(node->owner_document->tags, - selector->name.data, selector->name.length); - if (tag_id == LXB_TAG__UNDEF) { - return false; - } - - entry->id = tag_id; - } - - return node->local_name == entry->id; -} - -static bool -lxb_selectors_match_id(const lxb_css_selector_t *selector, lxb_dom_node_t *node) -{ - const lexbor_str_t *trg, *src; - lxb_dom_element_t *element; - - element = lxb_dom_interface_element(node); - - if (element->attr_id == NULL || element->attr_id->value == NULL) { - return false; - } - - trg = element->attr_id->value; - src = &selector->name; - - return trg->length == src->length - && lexbor_str_data_ncasecmp(trg->data, src->data, src->length); -} - -static bool -lxb_selectors_match_class(const lexbor_str_t *target, const lexbor_str_t *src, - bool quirks) -{ - lxb_char_t chr; - - if (target->length < src->length) { - return false; - } - - bool is_it = false; - - const lxb_char_t *data = target->data; - const lxb_char_t *pos = data; - const lxb_char_t *end = data + target->length; - - for (; data < end; data++) { - chr = *data; - - if (lexbor_utils_whitespace(chr, ==, ||)) { - - if ((size_t) (data - pos) == src->length) { - if (quirks) { - is_it = lexbor_str_data_ncasecmp(pos, src->data, src->length); - } - else { - is_it = lexbor_str_data_ncmp(pos, src->data, src->length); - } - - if (is_it) { - return true; - } - } - - if ((size_t) (end - data) < src->length) { - return false; - } - - pos = data + 1; - } - } - - if ((size_t) (end - pos) == src->length && src->length != 0) { - if (quirks) { - is_it = lexbor_str_data_ncasecmp(pos, src->data, src->length); - } - else { - is_it = lexbor_str_data_ncmp(pos, src->data, src->length); - } - } - - return is_it; -} - -static bool -lxb_selectors_match_attribute(const lxb_css_selector_t *selector, - lxb_dom_node_t *node, lxb_selectors_entry_t *entry) -{ - bool res, ins; - lxb_dom_attr_t *dom_attr; - lxb_dom_element_t *element; - const lexbor_str_t *trg, *src; - const lxb_dom_attr_data_t *attr_data; - const lxb_css_selector_attribute_t *attr; - - static const lexbor_str_t lxb_blank_str = { - .data = (lxb_char_t *) "", - .length = 0 - }; - - element = lxb_dom_interface_element(node); - attr = &selector->u.attribute; - - if (entry->id == 0) { - attr_data = lxb_dom_attr_data_by_local_name(node->owner_document->attrs, - selector->name.data, selector->name.length); - if (attr_data == NULL) { - return false; - } - - entry->id = attr_data->attr_id; - } - - dom_attr = lxb_dom_element_attr_by_id(element, entry->id); - if (dom_attr == NULL) { - return false; - } - - trg = dom_attr->value; - src = &attr->value; - - if (src->data == NULL) { - return true; - } - - if (trg == NULL) { - trg = &lxb_blank_str; - } - - ins = attr->modifier == LXB_CSS_SELECTOR_MODIFIER_I; - - switch (attr->match) { - case LXB_CSS_SELECTOR_MATCH_EQUAL: /* = */ - if (trg->length == src->length) { - if (ins) { - return lexbor_str_data_ncasecmp(trg->data, src->data, - src->length); - } - - return lexbor_str_data_ncmp(trg->data, src->data, - src->length); - } - - return false; - - case LXB_CSS_SELECTOR_MATCH_INCLUDE: /* ~= */ - return lxb_selectors_match_class(trg, src, ins); - - case LXB_CSS_SELECTOR_MATCH_DASH: /* |= */ - if (trg->length == src->length) { - if (ins) { - return lexbor_str_data_ncasecmp(trg->data, src->data, - src->length); - } - - return lexbor_str_data_ncmp(trg->data, src->data, - src->length); - } - - if (trg->length > src->length) { - if (ins) { - res = lexbor_str_data_ncasecmp(trg->data, - src->data, src->length); - } - else { - res = lexbor_str_data_ncmp(trg->data, - src->data, src->length); - } - - if (res && trg->data[src->length] == '-') { - return true; - } - } - - return false; - - case LXB_CSS_SELECTOR_MATCH_PREFIX: /* ^= */ - if (src->length != 0 && trg->length >= src->length) { - if (ins) { - return lexbor_str_data_ncasecmp(trg->data, src->data, - src->length); - } - - return lexbor_str_data_ncmp(trg->data, src->data, - src->length); - } - - return false; - - case LXB_CSS_SELECTOR_MATCH_SUFFIX: /* $= */ - if (src->length != 0 && trg->length >= src->length) { - size_t dif = trg->length - src->length; - - if (ins) { - return lexbor_str_data_ncasecmp(trg->data + dif, - src->data, src->length); - } - - return lexbor_str_data_ncmp(trg->data + dif, src->data, - src->length); - } - - return false; - - case LXB_CSS_SELECTOR_MATCH_SUBSTRING: /* *= */ - if (src->length == 0) { - return false; - } - - if (ins) { - return lexbor_str_data_ncasecmp_contain(trg->data, trg->length, - src->data, src->length); - } - - return lexbor_str_data_ncmp_contain(trg->data, trg->length, - src->data, src->length); - default: - break; - } - - return false; -} - -static bool -lxb_selectors_pseudo_class(const lxb_css_selector_t *selector, - const lxb_dom_node_t *node) -{ - lexbor_str_t *str; - lxb_dom_attr_t *attr; - const lxb_dom_node_t *root; - const lxb_css_selector_pseudo_t *pseudo = &selector->u.pseudo; - - static const lxb_char_t checkbox[] = "checkbox"; - static const size_t checkbox_length = sizeof(checkbox) / sizeof(lxb_char_t) - 1; - - static const lxb_char_t radio[] = "radio"; - static const size_t radio_length = sizeof(radio) / sizeof(lxb_char_t) - 1; - - switch (pseudo->type) { - case LXB_CSS_SELECTOR_PSEUDO_CLASS_ACTIVE: - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_ACTIVE); - return attr != NULL; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_ANY_LINK: - if(node->local_name == LXB_TAG_A || - node->local_name == LXB_TAG_AREA || - node->local_name == LXB_TAG_MAP) - { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_HREF); - return attr != NULL; - } - - return false; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_BLANK: - return lxb_dom_node_is_empty(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_CHECKED: - if (node->local_name == LXB_TAG_INPUT) { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_TYPE); - if (attr == NULL) { - return false; - } - - if (attr->value == NULL) { - return false; - } - - str = attr->value; - - if(str->length == 8) { - if (lexbor_str_data_ncasecmp(checkbox, str->data, checkbox_length)) { - goto check; - } - } - else if(str->length == 5) { - if (lexbor_str_data_ncasecmp(radio, str->data, radio_length)) { - goto check; - } - } - } - else if(node->local_name == LXB_TAG_OPTION) { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_SELECTED); - if (attr != NULL) { - return true; - } - } - else if(node->local_name >= LXB_TAG__LAST_ENTRY) { - goto check; - } - - return false; - - check: - - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_CHECKED); - if (attr != NULL) { - return true; - } - - return false; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_CURRENT: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_DEFAULT: - return false; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_DISABLED: - return lxb_selectors_pseudo_class_disabled(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_EMPTY: - root = node; - node = node->first_child; - - while (node != NULL) { - if (node->local_name != LXB_TAG__EM_COMMENT) { - return false; - } - - if (node->first_child != NULL) { - node = node->first_child; - } - else { - while (node != root && node->next == NULL) { - node = node->parent; - } - - if (node == root) { - break; - } - - node = node->next; - } - } - - return true; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_ENABLED: - return !lxb_selectors_pseudo_class_disabled(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FIRST_CHILD: - return lxb_selectors_pseudo_class_first_child(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FIRST_OF_TYPE: - return lxb_selectors_pseudo_class_first_of_type(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FOCUS: - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_FOCUS); - return attr != NULL; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FOCUS_VISIBLE: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FOCUS_WITHIN: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FULLSCREEN: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUTURE: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_HOVER: - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_HOVER); - return attr != NULL; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_IN_RANGE: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_INDETERMINATE: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_INVALID: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_LAST_CHILD: - return lxb_selectors_pseudo_class_last_child(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_LAST_OF_TYPE: - return lxb_selectors_pseudo_class_last_of_type(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_LINK: - if (node->local_name == LXB_TAG_A - || node->local_name == LXB_TAG_AREA - || node->local_name == LXB_TAG_LINK) - { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_HREF); - return attr != NULL; - } - - return false; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_LOCAL_LINK: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_ONLY_CHILD: - return lxb_selectors_pseudo_class_first_child(node) - && lxb_selectors_pseudo_class_last_child(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_ONLY_OF_TYPE: - return lxb_selectors_pseudo_class_first_of_type(node) - && lxb_selectors_pseudo_class_last_of_type(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_OPTIONAL: - if (node->local_name == LXB_TAG_INPUT - || node->local_name == LXB_TAG_SELECT - || node->local_name == LXB_TAG_TEXTAREA) - { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_REQUIRED); - return attr == NULL; - } - - return false; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_OUT_OF_RANGE: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_PAST: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_PLACEHOLDER_SHOWN: - if (node->local_name == LXB_TAG_INPUT - || node->local_name == LXB_TAG_TEXTAREA) - { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_PLACEHOLDER); - return attr != NULL; - } - - return false; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_READ_ONLY: - return !lxb_selectors_pseudo_class_read_write(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_READ_WRITE: - return lxb_selectors_pseudo_class_read_write(node); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_REQUIRED: - if (node->local_name == LXB_TAG_INPUT - || node->local_name == LXB_TAG_SELECT - || node->local_name == LXB_TAG_TEXTAREA) - { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_REQUIRED); - return attr != NULL; - } - - return false; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_ROOT: - return lxb_dom_document_root(node->owner_document) == node; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_SCOPE: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_TARGET: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_TARGET_WITHIN: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_USER_INVALID: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_VALID: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_VISITED: - break; - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_WARNING: - break; - } - - return false; -} - -static bool -lxb_selectors_pseudo_class_function(const lxb_css_selector_t *selector, - lxb_dom_node_t *node) -{ - size_t index; - lxb_dom_node_t *base; - const lxb_css_selector_pseudo_t *pseudo; - - pseudo = &selector->u.pseudo; - - switch (pseudo->type) { - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD: - index = 0; - - if (pseudo->type == LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_CHILD) { - while (node != NULL) { - if (node->local_name != LXB_TAG__TEXT - && node->local_name != LXB_TAG__EM_COMMENT) - { - index++; - } - - node = node->prev; - } - } - else { - while (node != NULL) { - if (node->local_name != LXB_TAG__TEXT - && node->local_name != LXB_TAG__EM_COMMENT) - { - index++; - } - - node = node->next; - } - } - - return lxb_selectors_anb_calc(pseudo->data, index); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE: - index = 0; - base = node; - - if (pseudo->type == LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE) { - while (node != NULL) { - if(node->local_name == base->local_name - && node->ns == base->ns) - { - index++; - } - - node = node->prev; - } - } - else { - while (node != NULL) { - if(node->local_name == base->local_name - && node->ns == base->ns) - { - index++; - } - - node = node->next; - } - } - - return lxb_selectors_anb_calc(pseudo->data, index); - - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_DIR: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_LANG: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_COL: - case LXB_CSS_SELECTOR_PSEUDO_CLASS_FUNCTION_NTH_LAST_COL: - default: - break; - } - - return false; -} - -static bool -lxb_selectors_pseudo_element(const lxb_css_selector_t *selector, - const lxb_dom_node_t *node) -{ - const lxb_css_selector_pseudo_t *pseudo = &selector->u.pseudo; - - switch (pseudo->type) { - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_AFTER: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_BACKDROP: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_BEFORE: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_FIRST_LETTER: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_FIRST_LINE: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_GRAMMAR_ERROR: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_INACTIVE_SELECTION: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_MARKER: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_PLACEHOLDER: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_SELECTION: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_SPELLING_ERROR: - case LXB_CSS_SELECTOR_PSEUDO_ELEMENT_TARGET_TEXT: - break; - } - - return false; -} - -static bool -lxb_selectors_pseudo_class_disabled(const lxb_dom_node_t *node) -{ - lxb_dom_attr_t *attr; - uintptr_t tag_id = node->local_name; - - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_DISABLED); - if (attr == NULL) { - return false; - } - - if (tag_id == LXB_TAG_BUTTON || tag_id == LXB_TAG_INPUT || - tag_id == LXB_TAG_SELECT || tag_id == LXB_TAG_TEXTAREA || - tag_id >= LXB_TAG__LAST_ENTRY) - { - return true; - } - - node = node->parent; - - while (node != NULL) { - if (node->local_name == LXB_TAG_FIELDSET - && node->first_child->local_name != LXB_TAG_LEGEND) - { - return true; - } - - node = node->parent; - } - - return false; -} - -static bool -lxb_selectors_pseudo_class_first_child(const lxb_dom_node_t *node) -{ - node = node->prev; - - while (node != NULL) { - if (node->local_name != LXB_TAG__TEXT - && node->local_name != LXB_TAG__EM_COMMENT) - { - return false; - } - - node = node->prev; - } - - return true; -} - -static bool -lxb_selectors_pseudo_class_first_of_type(const lxb_dom_node_t *node) -{ - const lxb_dom_node_t *root = node; - node = node->prev; - - while (node) { - if (node->local_name == root->local_name - && node->ns == root->ns) - { - return false; - } - - node = node->prev; - } - - return true; -} - -static bool -lxb_selectors_pseudo_class_last_child(const lxb_dom_node_t *node) -{ - node = node->next; - - while (node != NULL) { - if (node->local_name != LXB_TAG__TEXT - && node->local_name != LXB_TAG__EM_COMMENT) - { - return false; - } - - node = node->next; - } - - return true; -} - -static bool -lxb_selectors_pseudo_class_last_of_type(const lxb_dom_node_t *node) -{ - const lxb_dom_node_t *root = node; - node = node->next; - - while (node) { - if (node->local_name == root->local_name - && node->ns == root->ns) - { - return false; - } - - node = node->next; - } - - return true; -} - -static bool -lxb_selectors_pseudo_class_read_write(const lxb_dom_node_t *node) -{ - lxb_dom_attr_t *attr; - - if (node->local_name == LXB_TAG_INPUT - || node->local_name == LXB_TAG_TEXTAREA) - { - attr = lxb_dom_element_attr_by_id(lxb_dom_interface_element(node), - LXB_DOM_ATTR_READONLY); - if (attr != NULL) { - return false; - } - - return !lxb_selectors_pseudo_class_disabled(node); - } - - return false; -} - -static bool -lxb_selectors_anb_calc(lxb_css_selector_anb_of_t *anb, size_t index) -{ - double num; - - if (anb->anb.a == 0) { - if (anb->anb.b >= 0 && (size_t) anb->anb.b == index) { - return true; - } - } - else { - num = ((double) index - (double) anb->anb.b) / (double) anb->anb.a; - - if (num >= 0.0f && (num - trunc(num)) == 0.0f) { - return true; - } - } - - return false; -} - -static lxb_status_t -lxb_selectors_cb_ok(lxb_dom_node_t *node, - lxb_css_selector_specificity_t spec, void *ctx) -{ - *((bool *) ctx) = true; - return LXB_STATUS_OK; -} - -static lxb_status_t -lxb_selectors_cb_not(lxb_dom_node_t *node, - lxb_css_selector_specificity_t spec, void *ctx) -{ - *((bool *) ctx) = false; - return LXB_STATUS_OK; -} - -void -lxb_selectors_opt_set_noi(lxb_selectors_t *selectors, lxb_selectors_opt_t opt) -{ - lxb_selectors_opt_set(selectors, opt); -} - -const lxb_css_selector_list_t * -lxb_selectors_selector_noi(const lxb_selectors_t *selectors) -{ - return lxb_selectors_selector(selectors); -} diff --git a/ext/lexbor/lexbor/selectors/selectors.h b/ext/lexbor/lexbor/selectors/selectors.h deleted file mode 100644 index a9db864ff17f..000000000000 --- a/ext/lexbor/lexbor/selectors/selectors.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) 2021-2024 Alexander Borisov - * - * Author: Alexander Borisov - */ - - -#ifndef LEXBOR_SELECTORS_H -#define LEXBOR_SELECTORS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lexbor/selectors/base.h" -#include "lexbor/dom/dom.h" -#include "lexbor/css/selectors/selectors.h" -#include "lexbor/core/array_obj.h" - - -typedef enum { - LXB_SELECTORS_OPT_DEFAULT = 0x00, - - /* - * Includes the passed (root) node in the search. - * - * By default, the root node does not participate in selector searches, - * only its children. - * - * This behavior is logical, if you have found a node and then you want to - * search for other nodes in it, you don't need to check it again. - * - * But there are cases when it is necessary for root node to participate - * in the search. That's what this option is for. - */ - LXB_SELECTORS_OPT_MATCH_ROOT = 1 << 1, - - /* - * Stop searching after the first match with any of the selectors - * in the list. - * - * By default, the callback will be triggered for each selector list. - * That is, if your node matches different selector lists, it will be - * returned multiple times in the callback. - * - * For example: - * HTML:
test
- * Selectors: div, div[id="ok"], div:has(:not(a)) - * - * The default behavior will cause three callbacks with the same node (div). - * Because it will be found by every selector in the list. - * - * This option allows you to end the element check after the first match on - * any of the selectors. That is, the callback will be called only once - * for example above. This way we get rid of duplicates in the search. - */ - LXB_SELECTORS_OPT_MATCH_FIRST = 1 << 2 -} -lxb_selectors_opt_t; - -typedef struct lxb_selectors lxb_selectors_t; -typedef struct lxb_selectors_entry lxb_selectors_entry_t; -typedef struct lxb_selectors_nested lxb_selectors_nested_t; - -typedef lxb_status_t -(*lxb_selectors_cb_f)(lxb_dom_node_t *node, - lxb_css_selector_specificity_t spec, void *ctx); - -typedef lxb_selectors_entry_t * -(*lxb_selectors_state_cb_f)(lxb_selectors_t *selectors, - lxb_selectors_entry_t *entry); - -struct lxb_selectors_entry { - uintptr_t id; - lxb_css_selector_combinator_t combinator; - const lxb_css_selector_t *selector; - lxb_dom_node_t *node; - lxb_selectors_entry_t *next; - lxb_selectors_entry_t *prev; - lxb_selectors_entry_t *following; - lxb_selectors_nested_t *nested; -}; - -struct lxb_selectors_nested { - lxb_selectors_entry_t *entry; - lxb_selectors_state_cb_f return_state; - - lxb_selectors_cb_f cb; - void *ctx; - - lxb_dom_node_t *root; - lxb_selectors_entry_t *last; - lxb_selectors_nested_t *parent; - - size_t index; - bool found; -}; - -struct lxb_selectors { - lxb_selectors_state_cb_f state; - lexbor_dobject_t *objs; - lexbor_dobject_t *nested; - - lxb_selectors_nested_t *current; - lxb_selectors_entry_t *first; - - lxb_selectors_opt_t options; - lxb_status_t status; -}; - - -/* - * Create lxb_selectors_t object. - * - * @return lxb_selectors_t * if successful, otherwise NULL. - */ -LXB_API lxb_selectors_t * -lxb_selectors_create(void); - -/* - * Initialization of lxb_selectors_t object. - * - * Caches are initialized in this function. - * - * @param[in] lxb_selectors_t * - * - * @return LXB_STATUS_OK if successful, otherwise an error status value. - */ -LXB_API lxb_status_t -lxb_selectors_init(lxb_selectors_t *selectors); - -/* - * Clears the object. Returns object to states as after initialization. - * - * After each call to lxb_selectors_find() and lxb_selectors_find_for_node(), - * the lxb_selectors_t object is cleared. That is, you don't need to call this - * function every time after searching by a selector. - * - * @param[in] lxb_url_parser_t * - */ -LXB_API void -lxb_selectors_clean(lxb_selectors_t *selectors); - -/* - * Destroy lxb_selectors_t object. - * - * Destroying all caches. - * - * @param[in] lxb_selectors_t *. Can be NULL. - * @param[in] if false: only destroys internal caches. - * if true: destroys the lxb_selectors_t object and all internal caches. - * - * @return lxb_selectors_t * if self_destroy = false, otherwise NULL. - */ -LXB_API lxb_selectors_t * -lxb_selectors_destroy(lxb_selectors_t *selectors, bool self_destroy); - -/* - * Search for nodes by selector list. - * - * Default Behavior: - * 1. The root node does not participate in the search, only its child nodes. - * 2. If a node matches multiple selector lists, a callback with that node - * will be called on each list. - * For example: - * HTML:
- * Selectors: div, div[id="ok"], div:has(:not(a)) - * For each selector list, a callback with a "div" node will be called. - * - * To change the search behavior, see lxb_selectors_opt_set(). - * - * @param[in] lxb_selectors_t *. - * @param[in] lxb_dom_node_t *. The node from which the search will begin. - * @param[in] const lxb_css_selector_list_t *. Selectors List. - * @param[in] lxb_selectors_cb_f. Callback for a found node. - * @param[in] void *. Context for the callback. - * if true: destroys the lxb_selectors_t object and all internal caches. - * - * @return LXB_STATUS_OK if successful, otherwise an error status value. - */ -LXB_API lxb_status_t -lxb_selectors_find(lxb_selectors_t *selectors, lxb_dom_node_t *root, - const lxb_css_selector_list_t *list, - lxb_selectors_cb_f cb, void *ctx); - -/* - * Match a node to a Selectors List. - * - * In other words, the function checks which selector lists will find the - * specified node. - * - * Default Behavior: - * 1. If a node matches multiple selector lists, a callback with that node - * will be called on each list. - * For example: - * HTML:
- * Node: div - * Selectors: div, div[id="ok"], div:has(:not(a)) - * For each selector list, a callback with a "div" node will be called. - * - * To change the search behavior, see lxb_selectors_opt_set(). - * - * @param[in] lxb_selectors_t *. - * @param[in] lxb_dom_node_t *. The node from which the search will begin. - * @param[in] const lxb_css_selector_list_t *. Selectors List. - * @param[in] lxb_selectors_cb_f. Callback for a found node. - * @param[in] void *. Context for the callback. - * if true: destroys the lxb_selectors_t object and all internal caches. - * - * @return LXB_STATUS_OK if successful, otherwise an error status value. - */ -LXB_API lxb_status_t -lxb_selectors_match_node(lxb_selectors_t *selectors, lxb_dom_node_t *node, - const lxb_css_selector_list_t *list, - lxb_selectors_cb_f cb, void *ctx); - -/* - * Deprecated! - * This function does exactly the same thing as lxb_selectors_match_node(). - */ -LXB_API LXB_DEPRECATED(lxb_status_t -lxb_selectors_find_reverse(lxb_selectors_t *selectors, lxb_dom_node_t *root, - lxb_css_selector_list_t *list, - lxb_selectors_cb_f cb, void *ctx)); - -/* - * Inline functions. - */ - -/* - * The function sets the node search options. - * - * For more information, see lxb_selectors_opt_t. - * - * @param[in] lxb_selectors_t *. - * @param[in] lxb_selectors_opt_t. - */ -lxb_inline void -lxb_selectors_opt_set(lxb_selectors_t *selectors, lxb_selectors_opt_t opt) -{ - selectors->options = opt; -} - -/* - * Get the current selector. - * - * Function to get the selector by which the node was found. - * Use context (void *ctx) to pass the lxb_selectors_t object to the callback. - * - * @param[in] const lxb_selectors_t *. - * - * @return const lxb_css_selector_list_t *. - */ -lxb_inline const lxb_css_selector_list_t * -lxb_selectors_selector(const lxb_selectors_t *selectors) -{ - return selectors->current->entry->selector->list; -} - -/* - * Not inline for inline. - */ - -/* - * Same as lxb_selectors_opt_set() function, but not inline. - */ -LXB_API void -lxb_selectors_opt_set_noi(lxb_selectors_t *selectors, lxb_selectors_opt_t opt); - -/* - * Same as lxb_selectors_selector() function, but not inline. - */ -LXB_API const lxb_css_selector_list_t * -lxb_selectors_selector_noi(const lxb_selectors_t *selectors); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LEXBOR_SELECTORS_H */ diff --git a/ext/lexbor/lexbor/tag/base.h b/ext/lexbor/lexbor/tag/base.h index 94886ee4f47c..27ba326cf40f 100644 --- a/ext/lexbor/lexbor/tag/base.h +++ b/ext/lexbor/lexbor/tag/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2024 Alexander Borisov + * Copyright (C) 2019-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -16,7 +16,7 @@ extern "C" { #define LXB_TAG_VERSION_MAJOR 1 -#define LXB_TAG_VERSION_MINOR 3 +#define LXB_TAG_VERSION_MINOR 5 #define LXB_TAG_VERSION_PATCH 0 #define LXB_TAG_VERSION_STRING \ diff --git a/ext/lexbor/lexbor/tag/const.h b/ext/lexbor/lexbor/tag/const.h index 1a598d347472..b08e387da326 100644 --- a/ext/lexbor/lexbor/tag/const.h +++ b/ext/lexbor/lexbor/tag/const.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,8 +14,8 @@ #ifndef LXB_TAG_CONST_H #define LXB_TAG_CONST_H -#define LXB_TAG_CONST_VERSION "A161EC911182C3254E7A972D5C51DF86" -#define LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#define LXB_TAG_CONST_VERSION "5AB3094FB370521074947DC082575715" +#define LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 typedef uintptr_t lxb_tag_id_t; @@ -183,41 +183,43 @@ typedef enum { LXB_TAG_S = 0x009f, LXB_TAG_SAMP = 0x00a0, LXB_TAG_SCRIPT = 0x00a1, - LXB_TAG_SECTION = 0x00a2, - LXB_TAG_SELECT = 0x00a3, - LXB_TAG_SLOT = 0x00a4, - LXB_TAG_SMALL = 0x00a5, - LXB_TAG_SOURCE = 0x00a6, - LXB_TAG_SPACER = 0x00a7, - LXB_TAG_SPAN = 0x00a8, - LXB_TAG_STRIKE = 0x00a9, - LXB_TAG_STRONG = 0x00aa, - LXB_TAG_STYLE = 0x00ab, - LXB_TAG_SUB = 0x00ac, - LXB_TAG_SUMMARY = 0x00ad, - LXB_TAG_SUP = 0x00ae, - LXB_TAG_SVG = 0x00af, - LXB_TAG_TABLE = 0x00b0, - LXB_TAG_TBODY = 0x00b1, - LXB_TAG_TD = 0x00b2, - LXB_TAG_TEMPLATE = 0x00b3, - LXB_TAG_TEXTAREA = 0x00b4, - LXB_TAG_TEXTPATH = 0x00b5, - LXB_TAG_TFOOT = 0x00b6, - LXB_TAG_TH = 0x00b7, - LXB_TAG_THEAD = 0x00b8, - LXB_TAG_TIME = 0x00b9, - LXB_TAG_TITLE = 0x00ba, - LXB_TAG_TR = 0x00bb, - LXB_TAG_TRACK = 0x00bc, - LXB_TAG_TT = 0x00bd, - LXB_TAG_U = 0x00be, - LXB_TAG_UL = 0x00bf, - LXB_TAG_VAR = 0x00c0, - LXB_TAG_VIDEO = 0x00c1, - LXB_TAG_WBR = 0x00c2, - LXB_TAG_XMP = 0x00c3, - LXB_TAG__LAST_ENTRY = 0x00c4 + LXB_TAG_SEARCH = 0x00a2, + LXB_TAG_SECTION = 0x00a3, + LXB_TAG_SELECT = 0x00a4, + LXB_TAG_SELECTEDCONTENT = 0x00a5, + LXB_TAG_SLOT = 0x00a6, + LXB_TAG_SMALL = 0x00a7, + LXB_TAG_SOURCE = 0x00a8, + LXB_TAG_SPACER = 0x00a9, + LXB_TAG_SPAN = 0x00aa, + LXB_TAG_STRIKE = 0x00ab, + LXB_TAG_STRONG = 0x00ac, + LXB_TAG_STYLE = 0x00ad, + LXB_TAG_SUB = 0x00ae, + LXB_TAG_SUMMARY = 0x00af, + LXB_TAG_SUP = 0x00b0, + LXB_TAG_SVG = 0x00b1, + LXB_TAG_TABLE = 0x00b2, + LXB_TAG_TBODY = 0x00b3, + LXB_TAG_TD = 0x00b4, + LXB_TAG_TEMPLATE = 0x00b5, + LXB_TAG_TEXTAREA = 0x00b6, + LXB_TAG_TEXTPATH = 0x00b7, + LXB_TAG_TFOOT = 0x00b8, + LXB_TAG_TH = 0x00b9, + LXB_TAG_THEAD = 0x00ba, + LXB_TAG_TIME = 0x00bb, + LXB_TAG_TITLE = 0x00bc, + LXB_TAG_TR = 0x00bd, + LXB_TAG_TRACK = 0x00be, + LXB_TAG_TT = 0x00bf, + LXB_TAG_U = 0x00c0, + LXB_TAG_UL = 0x00c1, + LXB_TAG_VAR = 0x00c2, + LXB_TAG_VIDEO = 0x00c3, + LXB_TAG_WBR = 0x00c4, + LXB_TAG_XMP = 0x00c5, + LXB_TAG__LAST_ENTRY = 0x00c6 } lxb_tag_id_enum_t; diff --git a/ext/lexbor/lexbor/tag/res.h b/ext/lexbor/lexbor/tag/res.h index 4ad1f37e034e..5672d4a5a5f2 100644 --- a/ext/lexbor/lexbor/tag/res.h +++ b/ext/lexbor/lexbor/tag/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Alexander Borisov + * Copyright (C) 2018-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -17,9 +17,9 @@ #endif /* LXB_TAG_RES_H */ #ifdef LXB_TAG_CONST_VERSION -#ifndef LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 +#ifndef LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 #error Mismatched tags version! See "lexbor/tag/const.h". -#endif /* LXB_TAG_CONST_VERSION_A161EC911182C3254E7A972D5C51DF86 */ +#endif /* LXB_TAG_CONST_VERSION_5AB3094FB370521074947DC082575715 */ #else #error You need to include "lexbor/tag/const.h". #endif /* LXB_TAG_CONST_VERSION */ @@ -188,8 +188,10 @@ static const lxb_tag_data_t lxb_tag_res_data_default[LXB_TAG__LAST_ENTRY] = {{.u.short_str = "s", .length = 1, .next = NULL}, LXB_TAG_S, 1, true}, {{.u.short_str = "samp", .length = 4, .next = NULL}, LXB_TAG_SAMP, 1, true}, {{.u.short_str = "script", .length = 6, .next = NULL}, LXB_TAG_SCRIPT, 1, true}, + {{.u.short_str = "search", .length = 6, .next = NULL}, LXB_TAG_SEARCH, 1, true}, {{.u.short_str = "section", .length = 7, .next = NULL}, LXB_TAG_SECTION, 1, true}, {{.u.short_str = "select", .length = 6, .next = NULL}, LXB_TAG_SELECT, 1, true}, + {{.u.short_str = "selectedcontent", .length = 15, .next = NULL}, LXB_TAG_SELECTEDCONTENT, 1, true}, {{.u.short_str = "slot", .length = 4, .next = NULL}, LXB_TAG_SLOT, 1, true}, {{.u.short_str = "small", .length = 5, .next = NULL}, LXB_TAG_SMALL, 1, true}, {{.u.short_str = "source", .length = 6, .next = NULL}, LXB_TAG_SOURCE, 1, true}, @@ -389,8 +391,10 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] {{.u.short_str = "S", .length = 1, .next = NULL}, LXB_TAG_S, 1, true}, {{.u.short_str = "SAMP", .length = 4, .next = NULL}, LXB_TAG_SAMP, 1, true}, {{.u.short_str = "SCRIPT", .length = 6, .next = NULL}, LXB_TAG_SCRIPT, 1, true}, + {{.u.short_str = "SEARCH", .length = 6, .next = NULL}, LXB_TAG_SEARCH, 1, true}, {{.u.short_str = "SECTION", .length = 7, .next = NULL}, LXB_TAG_SECTION, 1, true}, {{.u.short_str = "SELECT", .length = 6, .next = NULL}, LXB_TAG_SELECT, 1, true}, + {{.u.short_str = "SELECTEDCONTENT", .length = 15, .next = NULL}, LXB_TAG_SELECTEDCONTENT, 1, true}, {{.u.short_str = "SLOT", .length = 4, .next = NULL}, LXB_TAG_SLOT, 1, true}, {{.u.short_str = "SMALL", .length = 5, .next = NULL}, LXB_TAG_SMALL, 1, true}, {{.u.short_str = "SOURCE", .length = 6, .next = NULL}, LXB_TAG_SOURCE, 1, true}, @@ -426,81 +430,81 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] }; #endif -static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[] = +static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[263] = { {NULL, NULL, 262, 0}, {"radialgradient", (void *) &lxb_tag_res_data_default[153], 14, 0}, {"fecomponenttransfer", (void *) &lxb_tag_res_data_default[58], 19, 0}, {"abbr", (void *) &lxb_tag_res_data_default[7], 4, 1}, {"feflood", (void *) &lxb_tag_res_data_default[65], 7, 0}, {"marquee", (void *) &lxb_tag_res_data_default[121], 7, 0}, {"feblend", (void *) &lxb_tag_res_data_default[56], 7, 4}, {"optgroup", (void *) &lxb_tag_res_data_default[142], 8, 0}, - {"video", (void *) &lxb_tag_res_data_default[193], 5, 10}, {"u", (void *) &lxb_tag_res_data_default[190], 1, 0}, + {"video", (void *) &lxb_tag_res_data_default[195], 5, 10}, {"u", (void *) &lxb_tag_res_data_default[192], 1, 0}, {"iframe", (void *) &lxb_tag_res_data_default[103], 6, 0}, {"animatecolor", (void *) &lxb_tag_res_data_default[13], 12, 0}, {"output", (void *) &lxb_tag_res_data_default[144], 6, 0}, {"figcaption", (void *) &lxb_tag_res_data_default[82], 10, 0}, {"mglyph", (void *) &lxb_tag_res_data_default[127], 6, 0}, {"!--", (void *) &lxb_tag_res_data_default[4], 3, 0}, {"fefuncg", (void *) &lxb_tag_res_data_default[68], 7, 0}, {"aside", (void *) &lxb_tag_res_data_default[20], 5, 0}, - {"style", (void *) &lxb_tag_res_data_default[171], 5, 0}, {"strike", (void *) &lxb_tag_res_data_default[169], 6, 0}, + {"style", (void *) &lxb_tag_res_data_default[173], 5, 0}, {"strike", (void *) &lxb_tag_res_data_default[171], 6, 0}, {"header", (void *) &lxb_tag_res_data_default[98], 6, 0}, {"glyphref", (void *) &lxb_tag_res_data_default[90], 8, 23}, {"label", (void *) &lxb_tag_res_data_default[111], 5, 0}, {"feconvolvematrix", (void *) &lxb_tag_res_data_default[60], 16, 0}, - {"altglyphdef", (void *) &lxb_tag_res_data_default[11], 11, 0}, {"title", (void *) &lxb_tag_res_data_default[186], 5, 0}, + {"altglyphdef", (void *) &lxb_tag_res_data_default[11], 11, 0}, {"title", (void *) &lxb_tag_res_data_default[188], 5, 0}, {"head", (void *) &lxb_tag_res_data_default[97], 4, 0}, {"noframes", (void *) &lxb_tag_res_data_default[138], 8, 0}, {"code", (void *) &lxb_tag_res_data_default[39], 4, 30}, {"rb", (void *) &lxb_tag_res_data_default[154], 2, 5}, {"blink", (void *) &lxb_tag_res_data_default[29], 5, 0}, {"image", (void *) &lxb_tag_res_data_default[104], 5, 0}, {"col", (void *) &lxb_tag_res_data_default[40], 3, 8}, {"object", (void *) &lxb_tag_res_data_default[140], 6, 12}, - {"template", (void *) &lxb_tag_res_data_default[179], 8, 36}, {"h2", (void *) &lxb_tag_res_data_default[92], 2, 13}, + {"template", (void *) &lxb_tag_res_data_default[181], 8, 36}, {"h2", (void *) &lxb_tag_res_data_default[92], 2, 13}, {"lineargradient", (void *) &lxb_tag_res_data_default[114], 14, 0}, {"math", (void *) &lxb_tag_res_data_default[122], 4, 0}, {"base", (void *) &lxb_tag_res_data_default[23], 4, 45}, {"dl", (void *) &lxb_tag_res_data_default[52], 2, 14}, - {"del", (void *) &lxb_tag_res_data_default[45], 3, 16}, {"svg", (void *) &lxb_tag_res_data_default[175], 3, 17}, + {"del", (void *) &lxb_tag_res_data_default[45], 3, 16}, {"svg", (void *) &lxb_tag_res_data_default[177], 3, 17}, {"dir", (void *) &lxb_tag_res_data_default[50], 3, 0}, {"article", (void *) &lxb_tag_res_data_default[19], 7, 0}, - {"strong", (void *) &lxb_tag_res_data_default[170], 6, 0}, {"dialog", (void *) &lxb_tag_res_data_default[49], 6, 0}, - {"details", (void *) &lxb_tag_res_data_default[47], 7, 0}, {"textpath", (void *) &lxb_tag_res_data_default[181], 8, 52}, + {"strong", (void *) &lxb_tag_res_data_default[172], 6, 0}, {"dialog", (void *) &lxb_tag_res_data_default[49], 6, 0}, + {"details", (void *) &lxb_tag_res_data_default[47], 7, 0}, {"textpath", (void *) &lxb_tag_res_data_default[183], 8, 52}, {"mark", (void *) &lxb_tag_res_data_default[120], 4, 0}, {"basefont", (void *) &lxb_tag_res_data_default[24], 8, 0}, {"fediffuselighting", (void *) &lxb_tag_res_data_default[61], 17, 0}, {"fespecularlighting", (void *) &lxb_tag_res_data_default[77], 18, 0}, {"blockquote", (void *) &lxb_tag_res_data_default[30], 10, 0}, {"script", (void *) &lxb_tag_res_data_default[161], 6, 58}, {"malignmark", (void *) &lxb_tag_res_data_default[118], 10, 0}, {"hr", (void *) &lxb_tag_res_data_default[100], 2, 18}, - {"source", (void *) &lxb_tag_res_data_default[166], 6, 19}, {"mn", (void *) &lxb_tag_res_data_default[129], 2, 0}, - {"select", (void *) &lxb_tag_res_data_default[163], 6, 0}, {"main", (void *) &lxb_tag_res_data_default[117], 4, 20}, + {"source", (void *) &lxb_tag_res_data_default[168], 6, 19}, {"mn", (void *) &lxb_tag_res_data_default[129], 2, 0}, + {"select", (void *) &lxb_tag_res_data_default[164], 6, 0}, {"main", (void *) &lxb_tag_res_data_default[117], 4, 20}, {"fieldset", (void *) &lxb_tag_res_data_default[81], 8, 62}, {"ins", (void *) &lxb_tag_res_data_default[107], 3, 0}, {"frameset", (void *) &lxb_tag_res_data_default[89], 8, 0}, {"button", (void *) &lxb_tag_res_data_default[33], 6, 0}, {"fecolormatrix", (void *) &lxb_tag_res_data_default[57], 13, 0}, {"q", (void *) &lxb_tag_res_data_default[152], 1, 0}, - {"animatemotion", (void *) &lxb_tag_res_data_default[14], 13, 0}, {"time", (void *) &lxb_tag_res_data_default[185], 4, 21}, - {"table", (void *) &lxb_tag_res_data_default[176], 5, 25}, {"h6", (void *) &lxb_tag_res_data_default[96], 2, 26}, + {"animatemotion", (void *) &lxb_tag_res_data_default[14], 13, 0}, {"time", (void *) &lxb_tag_res_data_default[187], 4, 21}, + {"table", (void *) &lxb_tag_res_data_default[178], 5, 25}, {"h6", (void *) &lxb_tag_res_data_default[96], 2, 26}, {"cite", (void *) &lxb_tag_res_data_default[37], 4, 28}, {"img", (void *) &lxb_tag_res_data_default[105], 3, 34}, {"fepointlight", (void *) &lxb_tag_res_data_default[76], 12, 0}, {"audio", (void *) &lxb_tag_res_data_default[21], 5, 0}, {"#end-of-file", (void *) &lxb_tag_res_data_default[1], 12, 0}, {"noscript", (void *) &lxb_tag_res_data_default[139], 8, 0}, - {"foreignobject", (void *) &lxb_tag_res_data_default[86], 13, 0}, {"spacer", (void *) &lxb_tag_res_data_default[167], 6, 0}, - {"samp", (void *) &lxb_tag_res_data_default[160], 4, 0}, {"altglyphitem", (void *) &lxb_tag_res_data_default[12], 12, 0}, - {"dt", (void *) &lxb_tag_res_data_default[53], 2, 0}, {"data", (void *) &lxb_tag_res_data_default[42], 4, 0}, + {"foreignobject", (void *) &lxb_tag_res_data_default[86], 13, 77}, {"selectedcontent", (void *) &lxb_tag_res_data_default[165], 15, 0}, + {"spacer", (void *) &lxb_tag_res_data_default[169], 6, 0}, {"samp", (void *) &lxb_tag_res_data_default[160], 4, 0}, + {"altglyphitem", (void *) &lxb_tag_res_data_default[12], 12, 0}, {"data", (void *) &lxb_tag_res_data_default[42], 4, 0}, {"mtext", (void *) &lxb_tag_res_data_default[132], 5, 0}, {"path", (void *) &lxb_tag_res_data_default[147], 4, 0}, - {"input", (void *) &lxb_tag_res_data_default[106], 5, 0}, {"th", (void *) &lxb_tag_res_data_default[183], 2, 38}, - {"p", (void *) &lxb_tag_res_data_default[145], 1, 0}, {"animatetransform", (void *) &lxb_tag_res_data_default[15], 16, 0}, - {"datalist", (void *) &lxb_tag_res_data_default[43], 8, 0}, {"small", (void *) &lxb_tag_res_data_default[165], 5, 0}, + {"input", (void *) &lxb_tag_res_data_default[106], 5, 0}, {"th", (void *) &lxb_tag_res_data_default[185], 2, 38}, + {"p", (void *) &lxb_tag_res_data_default[145], 1, 0}, {"dt", (void *) &lxb_tag_res_data_default[53], 2, 0}, + {"animatetransform", (void *) &lxb_tag_res_data_default[15], 16, 0}, {"datalist", (void *) &lxb_tag_res_data_default[43], 8, 0}, {"b", (void *) &lxb_tag_res_data_default[22], 1, 46}, {"nextid", (void *) &lxb_tag_res_data_default[135], 6, 47}, - {"noembed", (void *) &lxb_tag_res_data_default[137], 7, 0}, {"nav", (void *) &lxb_tag_res_data_default[134], 3, 0}, - {"bgsound", (void *) &lxb_tag_res_data_default[27], 7, 0}, {"slot", (void *) &lxb_tag_res_data_default[164], 4, 0}, - {"param", (void *) &lxb_tag_res_data_default[146], 5, 0}, {"font", (void *) &lxb_tag_res_data_default[84], 4, 53}, - {"figure", (void *) &lxb_tag_res_data_default[83], 6, 0}, {"femerge", (void *) &lxb_tag_res_data_default[72], 7, 0}, - {"femergenode", (void *) &lxb_tag_res_data_default[73], 11, 0}, {"feoffset", (void *) &lxb_tag_res_data_default[75], 8, 60}, - {"#text", (void *) &lxb_tag_res_data_default[2], 5, 0}, {"ul", (void *) &lxb_tag_res_data_default[191], 2, 0}, + {"noembed", (void *) &lxb_tag_res_data_default[137], 7, 0}, {"small", (void *) &lxb_tag_res_data_default[167], 5, 0}, + {"nav", (void *) &lxb_tag_res_data_default[134], 3, 0}, {"slot", (void *) &lxb_tag_res_data_default[166], 4, 0}, + {"search", (void *) &lxb_tag_res_data_default[162], 6, 0}, {"font", (void *) &lxb_tag_res_data_default[84], 4, 53}, + {"bgsound", (void *) &lxb_tag_res_data_default[27], 7, 0}, {"param", (void *) &lxb_tag_res_data_default[146], 5, 0}, + {"figure", (void *) &lxb_tag_res_data_default[83], 6, 0}, {"feoffset", (void *) &lxb_tag_res_data_default[75], 8, 60}, + {"#text", (void *) &lxb_tag_res_data_default[2], 5, 0}, {"femerge", (void *) &lxb_tag_res_data_default[72], 7, 0}, {"fespotlight", (void *) &lxb_tag_res_data_default[78], 11, 66}, {"form", (void *) &lxb_tag_res_data_default[87], 4, 72}, {"#document", (void *) &lxb_tag_res_data_default[3], 9, 76}, {"fedistantlight", (void *) &lxb_tag_res_data_default[63], 14, 0}, - {"track", (void *) &lxb_tag_res_data_default[188], 5, 0}, {"h3", (void *) &lxb_tag_res_data_default[93], 2, 77}, - {"h1", (void *) &lxb_tag_res_data_default[91], 2, 0}, {"i", (void *) &lxb_tag_res_data_default[102], 1, 0}, - {"altglyph", (void *) &lxb_tag_res_data_default[10], 8, 0}, {"legend", (void *) &lxb_tag_res_data_default[112], 6, 115}, - {"tbody", (void *) &lxb_tag_res_data_default[177], 5, 0}, {"address", (void *) &lxb_tag_res_data_default[9], 7, 0}, - {"caption", (void *) &lxb_tag_res_data_default[35], 7, 0}, {"option", (void *) &lxb_tag_res_data_default[143], 6, 0}, - {"sup", (void *) &lxb_tag_res_data_default[174], 3, 0}, {"body", (void *) &lxb_tag_res_data_default[31], 4, 78}, - {"progress", (void *) &lxb_tag_res_data_default[151], 8, 122}, {"acronym", (void *) &lxb_tag_res_data_default[8], 7, 0}, + {"track", (void *) &lxb_tag_res_data_default[190], 5, 0}, {"h3", (void *) &lxb_tag_res_data_default[93], 2, 78}, + {"femergenode", (void *) &lxb_tag_res_data_default[73], 11, 0}, {"i", (void *) &lxb_tag_res_data_default[102], 1, 0}, + {"ul", (void *) &lxb_tag_res_data_default[193], 2, 0}, {"h1", (void *) &lxb_tag_res_data_default[91], 2, 0}, + {"tbody", (void *) &lxb_tag_res_data_default[179], 5, 0}, {"altglyph", (void *) &lxb_tag_res_data_default[10], 8, 0}, + {"legend", (void *) &lxb_tag_res_data_default[112], 6, 117}, {"address", (void *) &lxb_tag_res_data_default[9], 7, 0}, + {"sup", (void *) &lxb_tag_res_data_default[176], 3, 0}, {"body", (void *) &lxb_tag_res_data_default[31], 4, 79}, + {"caption", (void *) &lxb_tag_res_data_default[35], 7, 0}, {"acronym", (void *) &lxb_tag_res_data_default[8], 7, 0}, + {"option", (void *) &lxb_tag_res_data_default[143], 6, 0}, {"progress", (void *) &lxb_tag_res_data_default[151], 8, 124}, {"fegaussianblur", (void *) &lxb_tag_res_data_default[70], 14, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"mi", (void *) &lxb_tag_res_data_default[128], 2, 79}, {NULL, NULL, 0, 0}, - {"dfn", (void *) &lxb_tag_res_data_default[48], 3, 0}, {"a", (void *) &lxb_tag_res_data_default[6], 1, 80}, - {"listing", (void *) &lxb_tag_res_data_default[116], 7, 87}, {"span", (void *) &lxb_tag_res_data_default[168], 4, 0}, + {"mi", (void *) &lxb_tag_res_data_default[128], 2, 80}, {NULL, NULL, 0, 0}, + {"dfn", (void *) &lxb_tag_res_data_default[48], 3, 0}, {"a", (void *) &lxb_tag_res_data_default[6], 1, 87}, + {"listing", (void *) &lxb_tag_res_data_default[116], 7, 88}, {"span", (void *) &lxb_tag_res_data_default[170], 4, 0}, {"area", (void *) &lxb_tag_res_data_default[18], 4, 0}, {"clippath", (void *) &lxb_tag_res_data_default[38], 8, 0}, - {"section", (void *) &lxb_tag_res_data_default[162], 7, 0}, {"li", (void *) &lxb_tag_res_data_default[113], 2, 88}, + {"section", (void *) &lxb_tag_res_data_default[163], 7, 0}, {"li", (void *) &lxb_tag_res_data_default[113], 2, 89}, {NULL, NULL, 0, 0}, {"html", (void *) &lxb_tag_res_data_default[101], 4, 0}, {NULL, NULL, 0, 0}, {"fedropshadow", (void *) &lxb_tag_res_data_default[64], 12, 0}, {"embed", (void *) &lxb_tag_res_data_default[55], 5, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"multicol", (void *) &lxb_tag_res_data_default[133], 8, 0}, - {"var", (void *) &lxb_tag_res_data_default[192], 3, 89}, {"rp", (void *) &lxb_tag_res_data_default[155], 2, 0}, + {"var", (void *) &lxb_tag_res_data_default[194], 3, 93}, {"rp", (void *) &lxb_tag_res_data_default[155], 2, 0}, {NULL, NULL, 0, 0}, {"link", (void *) &lxb_tag_res_data_default[115], 4, 0}, {"mo", (void *) &lxb_tag_res_data_default[130], 2, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"annotation-xml", (void *) &lxb_tag_res_data_default[16], 14, 0}, @@ -510,54 +514,54 @@ static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[] = {"fefuncb", (void *) &lxb_tag_res_data_default[67], 7, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"meter", (void *) &lxb_tag_res_data_default[125], 5, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {"tt", (void *) &lxb_tag_res_data_default[189], 2, 0}, - {"big", (void *) &lxb_tag_res_data_default[28], 3, 93}, {NULL, NULL, 0, 0}, - {"tfoot", (void *) &lxb_tag_res_data_default[182], 5, 0}, {"desc", (void *) &lxb_tag_res_data_default[46], 4, 0}, + {NULL, NULL, 0, 0}, {"tt", (void *) &lxb_tag_res_data_default[191], 2, 0}, + {"big", (void *) &lxb_tag_res_data_default[28], 3, 94}, {NULL, NULL, 0, 0}, + {"tfoot", (void *) &lxb_tag_res_data_default[184], 5, 0}, {"desc", (void *) &lxb_tag_res_data_default[46], 4, 96}, {"isindex", (void *) &lxb_tag_res_data_default[108], 7, 0}, {NULL, NULL, 0, 0}, {"menu", (void *) &lxb_tag_res_data_default[123], 4, 0}, {"hgroup", (void *) &lxb_tag_res_data_default[99], 6, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"wbr", (void *) &lxb_tag_res_data_default[194], 3, 0}, {NULL, NULL, 0, 0}, - {"pre", (void *) &lxb_tag_res_data_default[150], 3, 94}, {NULL, NULL, 0, 0}, + {"wbr", (void *) &lxb_tag_res_data_default[196], 3, 0}, {NULL, NULL, 0, 0}, + {"pre", (void *) &lxb_tag_res_data_default[150], 3, 98}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"picture", (void *) &lxb_tag_res_data_default[148], 7, 0}, {"h4", (void *) &lxb_tag_res_data_default[94], 2, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"meta", (void *) &lxb_tag_res_data_default[124], 4, 96}, {NULL, NULL, 0, 0}, + {"meta", (void *) &lxb_tag_res_data_default[124], 4, 99}, {NULL, NULL, 0, 0}, {"rtc", (void *) &lxb_tag_res_data_default[157], 3, 0}, {NULL, NULL, 0, 0}, - {"frame", (void *) &lxb_tag_res_data_default[88], 5, 0}, {"fetile", (void *) &lxb_tag_res_data_default[79], 6, 98}, - {"feimage", (void *) &lxb_tag_res_data_default[71], 7, 99}, {NULL, NULL, 0, 0}, - {"xmp", (void *) &lxb_tag_res_data_default[195], 3, 0}, {NULL, NULL, 0, 0}, - {"fecomposite", (void *) &lxb_tag_res_data_default[59], 11, 100}, {"feturbulence", (void *) &lxb_tag_res_data_default[80], 12, 0}, - {NULL, NULL, 0, 0}, {"summary", (void *) &lxb_tag_res_data_default[173], 7, 0}, + {"frame", (void *) &lxb_tag_res_data_default[88], 5, 0}, {"fetile", (void *) &lxb_tag_res_data_default[79], 6, 100}, + {"feimage", (void *) &lxb_tag_res_data_default[71], 7, 103}, {NULL, NULL, 0, 0}, + {"xmp", (void *) &lxb_tag_res_data_default[197], 3, 0}, {NULL, NULL, 0, 0}, + {"fecomposite", (void *) &lxb_tag_res_data_default[59], 11, 110}, {"feturbulence", (void *) &lxb_tag_res_data_default[80], 12, 0}, + {NULL, NULL, 0, 0}, {"summary", (void *) &lxb_tag_res_data_default[175], 7, 0}, {"mfenced", (void *) &lxb_tag_res_data_default[126], 7, 0}, {NULL, NULL, 0, 0}, - {"sub", (void *) &lxb_tag_res_data_default[172], 3, 0}, {"colgroup", (void *) &lxb_tag_res_data_default[41], 8, 0}, + {"sub", (void *) &lxb_tag_res_data_default[174], 3, 0}, {"colgroup", (void *) &lxb_tag_res_data_default[41], 8, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {"dd", (void *) &lxb_tag_res_data_default[44], 2, 103}, + {NULL, NULL, 0, 0}, {"dd", (void *) &lxb_tag_res_data_default[44], 2, 112}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"div", (void *) &lxb_tag_res_data_default[51], 3, 0}, {"textarea", (void *) &lxb_tag_res_data_default[180], 8, 0}, + {"div", (void *) &lxb_tag_res_data_default[51], 3, 0}, {"textarea", (void *) &lxb_tag_res_data_default[182], 8, 0}, {"!doctype", (void *) &lxb_tag_res_data_default[5], 8, 0}, {"applet", (void *) &lxb_tag_res_data_default[17], 6, 0}, - {NULL, NULL, 0, 0}, {"br", (void *) &lxb_tag_res_data_default[32], 2, 110}, + {NULL, NULL, 0, 0}, {"br", (void *) &lxb_tag_res_data_default[32], 2, 113}, {NULL, NULL, 0, 0}, {"keygen", (void *) &lxb_tag_res_data_default[110], 6, 0}, {"kbd", (void *) &lxb_tag_res_data_default[109], 3, 0}, {NULL, NULL, 0, 0}, {"plaintext", (void *) &lxb_tag_res_data_default[149], 9, 0}, {"s", (void *) &lxb_tag_res_data_default[159], 1, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {"bdo", (void *) &lxb_tag_res_data_default[26], 3, 0}, {"td", (void *) &lxb_tag_res_data_default[178], 2, 0}, + {"bdo", (void *) &lxb_tag_res_data_default[26], 3, 0}, {"td", (void *) &lxb_tag_res_data_default[180], 2, 0}, {"fefunca", (void *) &lxb_tag_res_data_default[66], 7, 0}, {"ol", (void *) &lxb_tag_res_data_default[141], 2, 0}, - {"thead", (void *) &lxb_tag_res_data_default[184], 5, 0}, {"nobr", (void *) &lxb_tag_res_data_default[136], 4, 112}, - {NULL, NULL, 0, 0}, {"tr", (void *) &lxb_tag_res_data_default[187], 2, 0}, + {"thead", (void *) &lxb_tag_res_data_default[186], 5, 0}, {"nobr", (void *) &lxb_tag_res_data_default[136], 4, 115}, + {NULL, NULL, 0, 0}, {"tr", (void *) &lxb_tag_res_data_default[189], 2, 0}, {"map", (void *) &lxb_tag_res_data_default[119], 3, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, - {NULL, NULL, 0, 0}, {"#undef", (void *) &lxb_tag_res_data_default[0], 6, 113}, + {NULL, NULL, 0, 0}, {"#undef", (void *) &lxb_tag_res_data_default[0], 6, 116}, {"em", (void *) &lxb_tag_res_data_default[54], 2, 0}, {NULL, NULL, 0, 0}, {"bdi", (void *) &lxb_tag_res_data_default[25], 3, 0}, {"femorphology", (void *) &lxb_tag_res_data_default[74], 12, 0}, - {"ms", (void *) &lxb_tag_res_data_default[131], 2, 116}, {"footer", (void *) &lxb_tag_res_data_default[85], 6, 0}, - {"fefuncr", (void *) &lxb_tag_res_data_default[69], 7, 0}, {"rt", (void *) &lxb_tag_res_data_default[156], 2, 117}, + {"ms", (void *) &lxb_tag_res_data_default[131], 2, 120}, {"footer", (void *) &lxb_tag_res_data_default[85], 6, 0}, + {"fefuncr", (void *) &lxb_tag_res_data_default[69], 7, 0}, {"rt", (void *) &lxb_tag_res_data_default[156], 2, 122}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0}, {"h5", (void *) &lxb_tag_res_data_default[95], 2, 0}, - {NULL, NULL, 0, 0}, {"ruby", (void *) &lxb_tag_res_data_default[158], 4, 120}, + {NULL, NULL, 0, 0}, {"ruby", (void *) &lxb_tag_res_data_default[158], 4, 123}, {"canvas", (void *) &lxb_tag_res_data_default[34], 6, 0}, {NULL, NULL, 0, 0}, {NULL, NULL, 0, 0} }; diff --git a/ext/lexbor/lexbor/unicode/base.h b/ext/lexbor/lexbor/unicode/base.h index 4797b563c335..3ca2b6b2d8fb 100644 --- a/ext/lexbor/lexbor/unicode/base.h +++ b/ext/lexbor/lexbor/unicode/base.h @@ -16,7 +16,7 @@ extern "C" { #define LXB_UNICODE_VERSION_MAJOR 0 -#define LXB_UNICODE_VERSION_MINOR 3 +#define LXB_UNICODE_VERSION_MINOR 4 #define LXB_UNICODE_VERSION_PATCH 0 #define LXB_UNICODE_VERSION_STRING LEXBOR_STRINGIZE(LXB_UNICODE_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/unicode/res.h b/ext/lexbor/lexbor/unicode/res.h index 9948cc6be1a7..cd5c2c7a1d8a 100644 --- a/ext/lexbor/lexbor/unicode/res.h +++ b/ext/lexbor/lexbor/unicode/res.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Alexander Borisov + * Copyright (C) 2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -2212,7 +2212,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 088C (2188) */ 1, /* 088D (2189) */ 1, /* 088E (2190) */ - 56, /* 088F (2191) */ + 1, /* 088F (2191) */ 56, /* 0890 (2192) */ 56, /* 0891 (2193) */ 56, /* 0892 (2194) */ @@ -3185,7 +3185,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 0C59 (3161) */ 1, /* 0C5A (3162) */ 56, /* 0C5B (3163) */ - 56, /* 0C5C (3164) */ + 1, /* 0C5C (3164) */ 1, /* 0C5D (3165) */ 56, /* 0C5E (3166) */ 56, /* 0C5F (3167) */ @@ -3313,7 +3313,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 56, /* 0CD9 (3289) */ 56, /* 0CDA (3290) */ 56, /* 0CDB (3291) */ - 56, /* 0CDC (3292) */ + 1, /* 0CDC (3292) */ 1, /* 0CDD (3293) */ 1, /* 0CDE (3294) */ 56, /* 0CDF (3295) */ @@ -6884,35 +6884,35 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 431, /* 1ACC (6860) */ 431, /* 1ACD (6861) */ 431, /* 1ACE (6862) */ - 56, /* 1ACF (6863) */ - 56, /* 1AD0 (6864) */ - 56, /* 1AD1 (6865) */ - 56, /* 1AD2 (6866) */ - 56, /* 1AD3 (6867) */ - 56, /* 1AD4 (6868) */ - 56, /* 1AD5 (6869) */ - 56, /* 1AD6 (6870) */ - 56, /* 1AD7 (6871) */ - 56, /* 1AD8 (6872) */ - 56, /* 1AD9 (6873) */ - 56, /* 1ADA (6874) */ - 56, /* 1ADB (6875) */ - 56, /* 1ADC (6876) */ - 56, /* 1ADD (6877) */ + 431, /* 1ACF (6863) */ + 431, /* 1AD0 (6864) */ + 431, /* 1AD1 (6865) */ + 431, /* 1AD2 (6866) */ + 431, /* 1AD3 (6867) */ + 431, /* 1AD4 (6868) */ + 431, /* 1AD5 (6869) */ + 431, /* 1AD6 (6870) */ + 431, /* 1AD7 (6871) */ + 431, /* 1AD8 (6872) */ + 431, /* 1AD9 (6873) */ + 431, /* 1ADA (6874) */ + 431, /* 1ADB (6875) */ + 431, /* 1ADC (6876) */ + 433, /* 1ADD (6877) */ 56, /* 1ADE (6878) */ 56, /* 1ADF (6879) */ - 56, /* 1AE0 (6880) */ - 56, /* 1AE1 (6881) */ - 56, /* 1AE2 (6882) */ - 56, /* 1AE3 (6883) */ - 56, /* 1AE4 (6884) */ - 56, /* 1AE5 (6885) */ - 56, /* 1AE6 (6886) */ - 56, /* 1AE7 (6887) */ - 56, /* 1AE8 (6888) */ - 56, /* 1AE9 (6889) */ - 56, /* 1AEA (6890) */ - 56, /* 1AEB (6891) */ + 431, /* 1AE0 (6880) */ + 431, /* 1AE1 (6881) */ + 431, /* 1AE2 (6882) */ + 431, /* 1AE3 (6883) */ + 431, /* 1AE4 (6884) */ + 431, /* 1AE5 (6885) */ + 433, /* 1AE6 (6886) */ + 431, /* 1AE7 (6887) */ + 431, /* 1AE8 (6888) */ + 431, /* 1AE9 (6889) */ + 431, /* 1AEA (6890) */ + 446, /* 1AEB (6891) */ 56, /* 1AEC (6892) */ 56, /* 1AED (6893) */ 56, /* 1AEE (6894) */ @@ -8406,7 +8406,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 20BE (8382) */ 1, /* 20BF (8383) */ 1, /* 20C0 (8384) */ - 56, /* 20C1 (8385) */ + 1, /* 20C1 (8385) */ 56, /* 20C2 (8386) */ 56, /* 20C3 (8387) */ 56, /* 20C4 (8388) */ @@ -11179,7 +11179,7 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* 2B93 (11155) */ 1, /* 2B94 (11156) */ 1, /* 2B95 (11157) */ - 56, /* 2B96 (11158) */ + 1, /* 2B96 (11158) */ 1, /* 2B97 (11159) */ 1, /* 2B98 (11160) */ 1, /* 2B99 (11161) */ @@ -42979,21 +42979,21 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 3245, /* A7CB (42955) */ 3246, /* A7CC (42956) */ 1, /* A7CD (42957) */ - 56, /* A7CE (42958) */ - 56, /* A7CF (42959) */ - 3247, /* A7D0 (42960) */ + 3247, /* A7CE (42958) */ + 1, /* A7CF (42959) */ + 3248, /* A7D0 (42960) */ 1, /* A7D1 (42961) */ - 56, /* A7D2 (42962) */ + 3249, /* A7D2 (42962) */ 1, /* A7D3 (42963) */ - 56, /* A7D4 (42964) */ + 3250, /* A7D4 (42964) */ 1, /* A7D5 (42965) */ - 3248, /* A7D6 (42966) */ + 3251, /* A7D6 (42966) */ 1, /* A7D7 (42967) */ - 3249, /* A7D8 (42968) */ + 3252, /* A7D8 (42968) */ 1, /* A7D9 (42969) */ - 3250, /* A7DA (42970) */ + 3253, /* A7DA (42970) */ 1, /* A7DB (42971) */ - 3251, /* A7DC (42972) */ + 3254, /* A7DC (42972) */ 56, /* A7DD (42973) */ 56, /* A7DE (42974) */ 56, /* A7DF (42975) */ @@ -43014,15 +43014,15 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 56, /* A7EE (42990) */ 56, /* A7EF (42991) */ 56, /* A7F0 (42992) */ - 56, /* A7F1 (42993) */ - 3252, /* A7F2 (42994) */ - 3253, /* A7F3 (42995) */ - 3254, /* A7F4 (42996) */ - 3255, /* A7F5 (42997) */ + 3255, /* A7F1 (42993) */ + 3256, /* A7F2 (42994) */ + 3257, /* A7F3 (42995) */ + 3258, /* A7F4 (42996) */ + 3259, /* A7F5 (42997) */ 1, /* A7F6 (42998) */ 1, /* A7F7 (42999) */ - 3256, /* A7F8 (43000) */ - 3257, /* A7F9 (43001) */ + 3260, /* A7F8 (43000) */ + 3261, /* A7F9 (43001) */ 1, /* A7FA (43002) */ 1, /* A7FB (43003) */ 1, /* A7FC (43004) */ @@ -43889,10 +43889,10 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* AB59 (43865) */ 1, /* AB5A (43866) */ 1, /* AB5B (43867) */ - 3258, /* AB5C (43868) */ - 3259, /* AB5D (43869) */ - 3260, /* AB5E (43870) */ - 3261, /* AB5F (43871) */ + 3262, /* AB5C (43868) */ + 3263, /* AB5D (43869) */ + 3264, /* AB5E (43870) */ + 3265, /* AB5F (43871) */ 1, /* AB60 (43872) */ 1, /* AB61 (43873) */ 1, /* AB62 (43874) */ @@ -43902,93 +43902,93 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 1, /* AB66 (43878) */ 1, /* AB67 (43879) */ 1, /* AB68 (43880) */ - 3262, /* AB69 (43881) */ + 3266, /* AB69 (43881) */ 1, /* AB6A (43882) */ 1, /* AB6B (43883) */ 56, /* AB6C (43884) */ 56, /* AB6D (43885) */ 56, /* AB6E (43886) */ 56, /* AB6F (43887) */ - 3263, /* AB70 (43888) */ - 3264, /* AB71 (43889) */ - 3265, /* AB72 (43890) */ - 3266, /* AB73 (43891) */ - 3267, /* AB74 (43892) */ - 3268, /* AB75 (43893) */ - 3269, /* AB76 (43894) */ - 3270, /* AB77 (43895) */ - 3271, /* AB78 (43896) */ - 3272, /* AB79 (43897) */ - 3273, /* AB7A (43898) */ - 3274, /* AB7B (43899) */ - 3275, /* AB7C (43900) */ - 3276, /* AB7D (43901) */ - 3277, /* AB7E (43902) */ - 3278, /* AB7F (43903) */ - 3279, /* AB80 (43904) */ - 3280, /* AB81 (43905) */ - 3281, /* AB82 (43906) */ - 3282, /* AB83 (43907) */ - 3283, /* AB84 (43908) */ - 3284, /* AB85 (43909) */ - 3285, /* AB86 (43910) */ - 3286, /* AB87 (43911) */ - 3287, /* AB88 (43912) */ - 3288, /* AB89 (43913) */ - 3289, /* AB8A (43914) */ - 3290, /* AB8B (43915) */ - 3291, /* AB8C (43916) */ - 3292, /* AB8D (43917) */ - 3293, /* AB8E (43918) */ - 3294, /* AB8F (43919) */ - 3295, /* AB90 (43920) */ - 3296, /* AB91 (43921) */ - 3297, /* AB92 (43922) */ - 3298, /* AB93 (43923) */ - 3299, /* AB94 (43924) */ - 3300, /* AB95 (43925) */ - 3301, /* AB96 (43926) */ - 3302, /* AB97 (43927) */ - 3303, /* AB98 (43928) */ - 3304, /* AB99 (43929) */ - 3305, /* AB9A (43930) */ - 3306, /* AB9B (43931) */ - 3307, /* AB9C (43932) */ - 3308, /* AB9D (43933) */ - 3309, /* AB9E (43934) */ - 3310, /* AB9F (43935) */ - 3311, /* ABA0 (43936) */ - 3312, /* ABA1 (43937) */ - 3313, /* ABA2 (43938) */ - 3314, /* ABA3 (43939) */ - 3315, /* ABA4 (43940) */ - 3316, /* ABA5 (43941) */ - 3317, /* ABA6 (43942) */ - 3318, /* ABA7 (43943) */ - 3319, /* ABA8 (43944) */ - 3320, /* ABA9 (43945) */ - 3321, /* ABAA (43946) */ - 3322, /* ABAB (43947) */ - 3323, /* ABAC (43948) */ - 3324, /* ABAD (43949) */ - 3325, /* ABAE (43950) */ - 3326, /* ABAF (43951) */ - 3327, /* ABB0 (43952) */ - 3328, /* ABB1 (43953) */ - 3329, /* ABB2 (43954) */ - 3330, /* ABB3 (43955) */ - 3331, /* ABB4 (43956) */ - 3332, /* ABB5 (43957) */ - 3333, /* ABB6 (43958) */ - 3334, /* ABB7 (43959) */ - 3335, /* ABB8 (43960) */ - 3336, /* ABB9 (43961) */ - 3337, /* ABBA (43962) */ - 3338, /* ABBB (43963) */ - 3339, /* ABBC (43964) */ - 3340, /* ABBD (43965) */ - 3341, /* ABBE (43966) */ - 3342, /* ABBF (43967) */ + 3267, /* AB70 (43888) */ + 3268, /* AB71 (43889) */ + 3269, /* AB72 (43890) */ + 3270, /* AB73 (43891) */ + 3271, /* AB74 (43892) */ + 3272, /* AB75 (43893) */ + 3273, /* AB76 (43894) */ + 3274, /* AB77 (43895) */ + 3275, /* AB78 (43896) */ + 3276, /* AB79 (43897) */ + 3277, /* AB7A (43898) */ + 3278, /* AB7B (43899) */ + 3279, /* AB7C (43900) */ + 3280, /* AB7D (43901) */ + 3281, /* AB7E (43902) */ + 3282, /* AB7F (43903) */ + 3283, /* AB80 (43904) */ + 3284, /* AB81 (43905) */ + 3285, /* AB82 (43906) */ + 3286, /* AB83 (43907) */ + 3287, /* AB84 (43908) */ + 3288, /* AB85 (43909) */ + 3289, /* AB86 (43910) */ + 3290, /* AB87 (43911) */ + 3291, /* AB88 (43912) */ + 3292, /* AB89 (43913) */ + 3293, /* AB8A (43914) */ + 3294, /* AB8B (43915) */ + 3295, /* AB8C (43916) */ + 3296, /* AB8D (43917) */ + 3297, /* AB8E (43918) */ + 3298, /* AB8F (43919) */ + 3299, /* AB90 (43920) */ + 3300, /* AB91 (43921) */ + 3301, /* AB92 (43922) */ + 3302, /* AB93 (43923) */ + 3303, /* AB94 (43924) */ + 3304, /* AB95 (43925) */ + 3305, /* AB96 (43926) */ + 3306, /* AB97 (43927) */ + 3307, /* AB98 (43928) */ + 3308, /* AB99 (43929) */ + 3309, /* AB9A (43930) */ + 3310, /* AB9B (43931) */ + 3311, /* AB9C (43932) */ + 3312, /* AB9D (43933) */ + 3313, /* AB9E (43934) */ + 3314, /* AB9F (43935) */ + 3315, /* ABA0 (43936) */ + 3316, /* ABA1 (43937) */ + 3317, /* ABA2 (43938) */ + 3318, /* ABA3 (43939) */ + 3319, /* ABA4 (43940) */ + 3320, /* ABA5 (43941) */ + 3321, /* ABA6 (43942) */ + 3322, /* ABA7 (43943) */ + 3323, /* ABA8 (43944) */ + 3324, /* ABA9 (43945) */ + 3325, /* ABAA (43946) */ + 3326, /* ABAB (43947) */ + 3327, /* ABAC (43948) */ + 3328, /* ABAD (43949) */ + 3329, /* ABAE (43950) */ + 3330, /* ABAF (43951) */ + 3331, /* ABB0 (43952) */ + 3332, /* ABB1 (43953) */ + 3333, /* ABB2 (43954) */ + 3334, /* ABB3 (43955) */ + 3335, /* ABB4 (43956) */ + 3336, /* ABB5 (43957) */ + 3337, /* ABB6 (43958) */ + 3338, /* ABB7 (43959) */ + 3339, /* ABB8 (43960) */ + 3340, /* ABB9 (43961) */ + 3341, /* ABBA (43962) */ + 3342, /* ABBB (43963) */ + 3343, /* ABBC (43964) */ + 3344, /* ABBD (43965) */ + 3345, /* ABBE (43966) */ + 3346, /* ABBF (43967) */ 1, /* ABC0 (43968) */ 1, /* ABC1 (43969) */ 1, /* ABC2 (43970) */ @@ -44053,11178 +44053,11178 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = 56, /* ABFD (44029) */ 56, /* ABFE (44030) */ 56, /* ABFF (44031) */ - 3343, /* AC00 (44032) */ - 3343, /* AC01 (44033) */ - 3343, /* AC02 (44034) */ - 3343, /* AC03 (44035) */ - 3343, /* AC04 (44036) */ - 3343, /* AC05 (44037) */ - 3343, /* AC06 (44038) */ - 3343, /* AC07 (44039) */ - 3343, /* AC08 (44040) */ - 3343, /* AC09 (44041) */ - 3343, /* AC0A (44042) */ - 3343, /* AC0B (44043) */ - 3343, /* AC0C (44044) */ - 3343, /* AC0D (44045) */ - 3343, /* AC0E (44046) */ - 3343, /* AC0F (44047) */ - 3343, /* AC10 (44048) */ - 3343, /* AC11 (44049) */ - 3343, /* AC12 (44050) */ - 3343, /* AC13 (44051) */ - 3343, /* AC14 (44052) */ - 3343, /* AC15 (44053) */ - 3343, /* AC16 (44054) */ - 3343, /* AC17 (44055) */ - 3343, /* AC18 (44056) */ - 3343, /* AC19 (44057) */ - 3343, /* AC1A (44058) */ - 3343, /* AC1B (44059) */ - 3343, /* AC1C (44060) */ - 3343, /* AC1D (44061) */ - 3343, /* AC1E (44062) */ - 3343, /* AC1F (44063) */ - 3343, /* AC20 (44064) */ - 3343, /* AC21 (44065) */ - 3343, /* AC22 (44066) */ - 3343, /* AC23 (44067) */ - 3343, /* AC24 (44068) */ - 3343, /* AC25 (44069) */ - 3343, /* AC26 (44070) */ - 3343, /* AC27 (44071) */ - 3343, /* AC28 (44072) */ - 3343, /* AC29 (44073) */ - 3343, /* AC2A (44074) */ - 3343, /* AC2B (44075) */ - 3343, /* AC2C (44076) */ - 3343, /* AC2D (44077) */ - 3343, /* AC2E (44078) */ - 3343, /* AC2F (44079) */ - 3343, /* AC30 (44080) */ - 3343, /* AC31 (44081) */ - 3343, /* AC32 (44082) */ - 3343, /* AC33 (44083) */ - 3343, /* AC34 (44084) */ - 3343, /* AC35 (44085) */ - 3343, /* AC36 (44086) */ - 3343, /* AC37 (44087) */ - 3343, /* AC38 (44088) */ - 3343, /* AC39 (44089) */ - 3343, /* AC3A (44090) */ - 3343, /* AC3B (44091) */ - 3343, /* AC3C (44092) */ - 3343, /* AC3D (44093) */ - 3343, /* AC3E (44094) */ - 3343, /* AC3F (44095) */ - 3343, /* AC40 (44096) */ - 3343, /* AC41 (44097) */ - 3343, /* AC42 (44098) */ - 3343, /* AC43 (44099) */ - 3343, /* AC44 (44100) */ - 3343, /* AC45 (44101) */ - 3343, /* AC46 (44102) */ - 3343, /* AC47 (44103) */ - 3343, /* AC48 (44104) */ - 3343, /* AC49 (44105) */ - 3343, /* AC4A (44106) */ - 3343, /* AC4B (44107) */ - 3343, /* AC4C (44108) */ - 3343, /* AC4D (44109) */ - 3343, /* AC4E (44110) */ - 3343, /* AC4F (44111) */ - 3343, /* AC50 (44112) */ - 3343, /* AC51 (44113) */ - 3343, /* AC52 (44114) */ - 3343, /* AC53 (44115) */ - 3343, /* AC54 (44116) */ - 3343, /* AC55 (44117) */ - 3343, /* AC56 (44118) */ - 3343, /* AC57 (44119) */ - 3343, /* AC58 (44120) */ - 3343, /* AC59 (44121) */ - 3343, /* AC5A (44122) */ - 3343, /* AC5B (44123) */ - 3343, /* AC5C (44124) */ - 3343, /* AC5D (44125) */ - 3343, /* AC5E (44126) */ - 3343, /* AC5F (44127) */ - 3343, /* AC60 (44128) */ - 3343, /* AC61 (44129) */ - 3343, /* AC62 (44130) */ - 3343, /* AC63 (44131) */ - 3343, /* AC64 (44132) */ - 3343, /* AC65 (44133) */ - 3343, /* AC66 (44134) */ - 3343, /* AC67 (44135) */ - 3343, /* AC68 (44136) */ - 3343, /* AC69 (44137) */ - 3343, /* AC6A (44138) */ - 3343, /* AC6B (44139) */ - 3343, /* AC6C (44140) */ - 3343, /* AC6D (44141) */ - 3343, /* AC6E (44142) */ - 3343, /* AC6F (44143) */ - 3343, /* AC70 (44144) */ - 3343, /* AC71 (44145) */ - 3343, /* AC72 (44146) */ - 3343, /* AC73 (44147) */ - 3343, /* AC74 (44148) */ - 3343, /* AC75 (44149) */ - 3343, /* AC76 (44150) */ - 3343, /* AC77 (44151) */ - 3343, /* AC78 (44152) */ - 3343, /* AC79 (44153) */ - 3343, /* AC7A (44154) */ - 3343, /* AC7B (44155) */ - 3343, /* AC7C (44156) */ - 3343, /* AC7D (44157) */ - 3343, /* AC7E (44158) */ - 3343, /* AC7F (44159) */ - 3343, /* AC80 (44160) */ - 3343, /* AC81 (44161) */ - 3343, /* AC82 (44162) */ - 3343, /* AC83 (44163) */ - 3343, /* AC84 (44164) */ - 3343, /* AC85 (44165) */ - 3343, /* AC86 (44166) */ - 3343, /* AC87 (44167) */ - 3343, /* AC88 (44168) */ - 3343, /* AC89 (44169) */ - 3343, /* AC8A (44170) */ - 3343, /* AC8B (44171) */ - 3343, /* AC8C (44172) */ - 3343, /* AC8D (44173) */ - 3343, /* AC8E (44174) */ - 3343, /* AC8F (44175) */ - 3343, /* AC90 (44176) */ - 3343, /* AC91 (44177) */ - 3343, /* AC92 (44178) */ - 3343, /* AC93 (44179) */ - 3343, /* AC94 (44180) */ - 3343, /* AC95 (44181) */ - 3343, /* AC96 (44182) */ - 3343, /* AC97 (44183) */ - 3343, /* AC98 (44184) */ - 3343, /* AC99 (44185) */ - 3343, /* AC9A (44186) */ - 3343, /* AC9B (44187) */ - 3343, /* AC9C (44188) */ - 3343, /* AC9D (44189) */ - 3343, /* AC9E (44190) */ - 3343, /* AC9F (44191) */ - 3343, /* ACA0 (44192) */ - 3343, /* ACA1 (44193) */ - 3343, /* ACA2 (44194) */ - 3343, /* ACA3 (44195) */ - 3343, /* ACA4 (44196) */ - 3343, /* ACA5 (44197) */ - 3343, /* ACA6 (44198) */ - 3343, /* ACA7 (44199) */ - 3343, /* ACA8 (44200) */ - 3343, /* ACA9 (44201) */ - 3343, /* ACAA (44202) */ - 3343, /* ACAB (44203) */ - 3343, /* ACAC (44204) */ - 3343, /* ACAD (44205) */ - 3343, /* ACAE (44206) */ - 3343, /* ACAF (44207) */ - 3343, /* ACB0 (44208) */ - 3343, /* ACB1 (44209) */ - 3343, /* ACB2 (44210) */ - 3343, /* ACB3 (44211) */ - 3343, /* ACB4 (44212) */ - 3343, /* ACB5 (44213) */ - 3343, /* ACB6 (44214) */ - 3343, /* ACB7 (44215) */ - 3343, /* ACB8 (44216) */ - 3343, /* ACB9 (44217) */ - 3343, /* ACBA (44218) */ - 3343, /* ACBB (44219) */ - 3343, /* ACBC (44220) */ - 3343, /* ACBD (44221) */ - 3343, /* ACBE (44222) */ - 3343, /* ACBF (44223) */ - 3343, /* ACC0 (44224) */ - 3343, /* ACC1 (44225) */ - 3343, /* ACC2 (44226) */ - 3343, /* ACC3 (44227) */ - 3343, /* ACC4 (44228) */ - 3343, /* ACC5 (44229) */ - 3343, /* ACC6 (44230) */ - 3343, /* ACC7 (44231) */ - 3343, /* ACC8 (44232) */ - 3343, /* ACC9 (44233) */ - 3343, /* ACCA (44234) */ - 3343, /* ACCB (44235) */ - 3343, /* ACCC (44236) */ - 3343, /* ACCD (44237) */ - 3343, /* ACCE (44238) */ - 3343, /* ACCF (44239) */ - 3343, /* ACD0 (44240) */ - 3343, /* ACD1 (44241) */ - 3343, /* ACD2 (44242) */ - 3343, /* ACD3 (44243) */ - 3343, /* ACD4 (44244) */ - 3343, /* ACD5 (44245) */ - 3343, /* ACD6 (44246) */ - 3343, /* ACD7 (44247) */ - 3343, /* ACD8 (44248) */ - 3343, /* ACD9 (44249) */ - 3343, /* ACDA (44250) */ - 3343, /* ACDB (44251) */ - 3343, /* ACDC (44252) */ - 3343, /* ACDD (44253) */ - 3343, /* ACDE (44254) */ - 3343, /* ACDF (44255) */ - 3343, /* ACE0 (44256) */ - 3343, /* ACE1 (44257) */ - 3343, /* ACE2 (44258) */ - 3343, /* ACE3 (44259) */ - 3343, /* ACE4 (44260) */ - 3343, /* ACE5 (44261) */ - 3343, /* ACE6 (44262) */ - 3343, /* ACE7 (44263) */ - 3343, /* ACE8 (44264) */ - 3343, /* ACE9 (44265) */ - 3343, /* ACEA (44266) */ - 3343, /* ACEB (44267) */ - 3343, /* ACEC (44268) */ - 3343, /* ACED (44269) */ - 3343, /* ACEE (44270) */ - 3343, /* ACEF (44271) */ - 3343, /* ACF0 (44272) */ - 3343, /* ACF1 (44273) */ - 3343, /* ACF2 (44274) */ - 3343, /* ACF3 (44275) */ - 3343, /* ACF4 (44276) */ - 3343, /* ACF5 (44277) */ - 3343, /* ACF6 (44278) */ - 3343, /* ACF7 (44279) */ - 3343, /* ACF8 (44280) */ - 3343, /* ACF9 (44281) */ - 3343, /* ACFA (44282) */ - 3343, /* ACFB (44283) */ - 3343, /* ACFC (44284) */ - 3343, /* ACFD (44285) */ - 3343, /* ACFE (44286) */ - 3343, /* ACFF (44287) */ - 3343, /* AD00 (44288) */ - 3343, /* AD01 (44289) */ - 3343, /* AD02 (44290) */ - 3343, /* AD03 (44291) */ - 3343, /* AD04 (44292) */ - 3343, /* AD05 (44293) */ - 3343, /* AD06 (44294) */ - 3343, /* AD07 (44295) */ - 3343, /* AD08 (44296) */ - 3343, /* AD09 (44297) */ - 3343, /* AD0A (44298) */ - 3343, /* AD0B (44299) */ - 3343, /* AD0C (44300) */ - 3343, /* AD0D (44301) */ - 3343, /* AD0E (44302) */ - 3343, /* AD0F (44303) */ - 3343, /* AD10 (44304) */ - 3343, /* AD11 (44305) */ - 3343, /* AD12 (44306) */ - 3343, /* AD13 (44307) */ - 3343, /* AD14 (44308) */ - 3343, /* AD15 (44309) */ - 3343, /* AD16 (44310) */ - 3343, /* AD17 (44311) */ - 3343, /* AD18 (44312) */ - 3343, /* AD19 (44313) */ - 3343, /* AD1A (44314) */ - 3343, /* AD1B (44315) */ - 3343, /* AD1C (44316) */ - 3343, /* AD1D (44317) */ - 3343, /* AD1E (44318) */ - 3343, /* AD1F (44319) */ - 3343, /* AD20 (44320) */ - 3343, /* AD21 (44321) */ - 3343, /* AD22 (44322) */ - 3343, /* AD23 (44323) */ - 3343, /* AD24 (44324) */ - 3343, /* AD25 (44325) */ - 3343, /* AD26 (44326) */ - 3343, /* AD27 (44327) */ - 3343, /* AD28 (44328) */ - 3343, /* AD29 (44329) */ - 3343, /* AD2A (44330) */ - 3343, /* AD2B (44331) */ - 3343, /* AD2C (44332) */ - 3343, /* AD2D (44333) */ - 3343, /* AD2E (44334) */ - 3343, /* AD2F (44335) */ - 3343, /* AD30 (44336) */ - 3343, /* AD31 (44337) */ - 3343, /* AD32 (44338) */ - 3343, /* AD33 (44339) */ - 3343, /* AD34 (44340) */ - 3343, /* AD35 (44341) */ - 3343, /* AD36 (44342) */ - 3343, /* AD37 (44343) */ - 3343, /* AD38 (44344) */ - 3343, /* AD39 (44345) */ - 3343, /* AD3A (44346) */ - 3343, /* AD3B (44347) */ - 3343, /* AD3C (44348) */ - 3343, /* AD3D (44349) */ - 3343, /* AD3E (44350) */ - 3343, /* AD3F (44351) */ - 3343, /* AD40 (44352) */ - 3343, /* AD41 (44353) */ - 3343, /* AD42 (44354) */ - 3343, /* AD43 (44355) */ - 3343, /* AD44 (44356) */ - 3343, /* AD45 (44357) */ - 3343, /* AD46 (44358) */ - 3343, /* AD47 (44359) */ - 3343, /* AD48 (44360) */ - 3343, /* AD49 (44361) */ - 3343, /* AD4A (44362) */ - 3343, /* AD4B (44363) */ - 3343, /* AD4C (44364) */ - 3343, /* AD4D (44365) */ - 3343, /* AD4E (44366) */ - 3343, /* AD4F (44367) */ - 3343, /* AD50 (44368) */ - 3343, /* AD51 (44369) */ - 3343, /* AD52 (44370) */ - 3343, /* AD53 (44371) */ - 3343, /* AD54 (44372) */ - 3343, /* AD55 (44373) */ - 3343, /* AD56 (44374) */ - 3343, /* AD57 (44375) */ - 3343, /* AD58 (44376) */ - 3343, /* AD59 (44377) */ - 3343, /* AD5A (44378) */ - 3343, /* AD5B (44379) */ - 3343, /* AD5C (44380) */ - 3343, /* AD5D (44381) */ - 3343, /* AD5E (44382) */ - 3343, /* AD5F (44383) */ - 3343, /* AD60 (44384) */ - 3343, /* AD61 (44385) */ - 3343, /* AD62 (44386) */ - 3343, /* AD63 (44387) */ - 3343, /* AD64 (44388) */ - 3343, /* AD65 (44389) */ - 3343, /* AD66 (44390) */ - 3343, /* AD67 (44391) */ - 3343, /* AD68 (44392) */ - 3343, /* AD69 (44393) */ - 3343, /* AD6A (44394) */ - 3343, /* AD6B (44395) */ - 3343, /* AD6C (44396) */ - 3343, /* AD6D (44397) */ - 3343, /* AD6E (44398) */ - 3343, /* AD6F (44399) */ - 3343, /* AD70 (44400) */ - 3343, /* AD71 (44401) */ - 3343, /* AD72 (44402) */ - 3343, /* AD73 (44403) */ - 3343, /* AD74 (44404) */ - 3343, /* AD75 (44405) */ - 3343, /* AD76 (44406) */ - 3343, /* AD77 (44407) */ - 3343, /* AD78 (44408) */ - 3343, /* AD79 (44409) */ - 3343, /* AD7A (44410) */ - 3343, /* AD7B (44411) */ - 3343, /* AD7C (44412) */ - 3343, /* AD7D (44413) */ - 3343, /* AD7E (44414) */ - 3343, /* AD7F (44415) */ - 3343, /* AD80 (44416) */ - 3343, /* AD81 (44417) */ - 3343, /* AD82 (44418) */ - 3343, /* AD83 (44419) */ - 3343, /* AD84 (44420) */ - 3343, /* AD85 (44421) */ - 3343, /* AD86 (44422) */ - 3343, /* AD87 (44423) */ - 3343, /* AD88 (44424) */ - 3343, /* AD89 (44425) */ - 3343, /* AD8A (44426) */ - 3343, /* AD8B (44427) */ - 3343, /* AD8C (44428) */ - 3343, /* AD8D (44429) */ - 3343, /* AD8E (44430) */ - 3343, /* AD8F (44431) */ - 3343, /* AD90 (44432) */ - 3343, /* AD91 (44433) */ - 3343, /* AD92 (44434) */ - 3343, /* AD93 (44435) */ - 3343, /* AD94 (44436) */ - 3343, /* AD95 (44437) */ - 3343, /* AD96 (44438) */ - 3343, /* AD97 (44439) */ - 3343, /* AD98 (44440) */ - 3343, /* AD99 (44441) */ - 3343, /* AD9A (44442) */ - 3343, /* AD9B (44443) */ - 3343, /* AD9C (44444) */ - 3343, /* AD9D (44445) */ - 3343, /* AD9E (44446) */ - 3343, /* AD9F (44447) */ - 3343, /* ADA0 (44448) */ - 3343, /* ADA1 (44449) */ - 3343, /* ADA2 (44450) */ - 3343, /* ADA3 (44451) */ - 3343, /* ADA4 (44452) */ - 3343, /* ADA5 (44453) */ - 3343, /* ADA6 (44454) */ - 3343, /* ADA7 (44455) */ - 3343, /* ADA8 (44456) */ - 3343, /* ADA9 (44457) */ - 3343, /* ADAA (44458) */ - 3343, /* ADAB (44459) */ - 3343, /* ADAC (44460) */ - 3343, /* ADAD (44461) */ - 3343, /* ADAE (44462) */ - 3343, /* ADAF (44463) */ - 3343, /* ADB0 (44464) */ - 3343, /* ADB1 (44465) */ - 3343, /* ADB2 (44466) */ - 3343, /* ADB3 (44467) */ - 3343, /* ADB4 (44468) */ - 3343, /* ADB5 (44469) */ - 3343, /* ADB6 (44470) */ - 3343, /* ADB7 (44471) */ - 3343, /* ADB8 (44472) */ - 3343, /* ADB9 (44473) */ - 3343, /* ADBA (44474) */ - 3343, /* ADBB (44475) */ - 3343, /* ADBC (44476) */ - 3343, /* ADBD (44477) */ - 3343, /* ADBE (44478) */ - 3343, /* ADBF (44479) */ - 3343, /* ADC0 (44480) */ - 3343, /* ADC1 (44481) */ - 3343, /* ADC2 (44482) */ - 3343, /* ADC3 (44483) */ - 3343, /* ADC4 (44484) */ - 3343, /* ADC5 (44485) */ - 3343, /* ADC6 (44486) */ - 3343, /* ADC7 (44487) */ - 3343, /* ADC8 (44488) */ - 3343, /* ADC9 (44489) */ - 3343, /* ADCA (44490) */ - 3343, /* ADCB (44491) */ - 3343, /* ADCC (44492) */ - 3343, /* ADCD (44493) */ - 3343, /* ADCE (44494) */ - 3343, /* ADCF (44495) */ - 3343, /* ADD0 (44496) */ - 3343, /* ADD1 (44497) */ - 3343, /* ADD2 (44498) */ - 3343, /* ADD3 (44499) */ - 3343, /* ADD4 (44500) */ - 3343, /* ADD5 (44501) */ - 3343, /* ADD6 (44502) */ - 3343, /* ADD7 (44503) */ - 3343, /* ADD8 (44504) */ - 3343, /* ADD9 (44505) */ - 3343, /* ADDA (44506) */ - 3343, /* ADDB (44507) */ - 3343, /* ADDC (44508) */ - 3343, /* ADDD (44509) */ - 3343, /* ADDE (44510) */ - 3343, /* ADDF (44511) */ - 3343, /* ADE0 (44512) */ - 3343, /* ADE1 (44513) */ - 3343, /* ADE2 (44514) */ - 3343, /* ADE3 (44515) */ - 3343, /* ADE4 (44516) */ - 3343, /* ADE5 (44517) */ - 3343, /* ADE6 (44518) */ - 3343, /* ADE7 (44519) */ - 3343, /* ADE8 (44520) */ - 3343, /* ADE9 (44521) */ - 3343, /* ADEA (44522) */ - 3343, /* ADEB (44523) */ - 3343, /* ADEC (44524) */ - 3343, /* ADED (44525) */ - 3343, /* ADEE (44526) */ - 3343, /* ADEF (44527) */ - 3343, /* ADF0 (44528) */ - 3343, /* ADF1 (44529) */ - 3343, /* ADF2 (44530) */ - 3343, /* ADF3 (44531) */ - 3343, /* ADF4 (44532) */ - 3343, /* ADF5 (44533) */ - 3343, /* ADF6 (44534) */ - 3343, /* ADF7 (44535) */ - 3343, /* ADF8 (44536) */ - 3343, /* ADF9 (44537) */ - 3343, /* ADFA (44538) */ - 3343, /* ADFB (44539) */ - 3343, /* ADFC (44540) */ - 3343, /* ADFD (44541) */ - 3343, /* ADFE (44542) */ - 3343, /* ADFF (44543) */ - 3343, /* AE00 (44544) */ - 3343, /* AE01 (44545) */ - 3343, /* AE02 (44546) */ - 3343, /* AE03 (44547) */ - 3343, /* AE04 (44548) */ - 3343, /* AE05 (44549) */ - 3343, /* AE06 (44550) */ - 3343, /* AE07 (44551) */ - 3343, /* AE08 (44552) */ - 3343, /* AE09 (44553) */ - 3343, /* AE0A (44554) */ - 3343, /* AE0B (44555) */ - 3343, /* AE0C (44556) */ - 3343, /* AE0D (44557) */ - 3343, /* AE0E (44558) */ - 3343, /* AE0F (44559) */ - 3343, /* AE10 (44560) */ - 3343, /* AE11 (44561) */ - 3343, /* AE12 (44562) */ - 3343, /* AE13 (44563) */ - 3343, /* AE14 (44564) */ - 3343, /* AE15 (44565) */ - 3343, /* AE16 (44566) */ - 3343, /* AE17 (44567) */ - 3343, /* AE18 (44568) */ - 3343, /* AE19 (44569) */ - 3343, /* AE1A (44570) */ - 3343, /* AE1B (44571) */ - 3343, /* AE1C (44572) */ - 3343, /* AE1D (44573) */ - 3343, /* AE1E (44574) */ - 3343, /* AE1F (44575) */ - 3343, /* AE20 (44576) */ - 3343, /* AE21 (44577) */ - 3343, /* AE22 (44578) */ - 3343, /* AE23 (44579) */ - 3343, /* AE24 (44580) */ - 3343, /* AE25 (44581) */ - 3343, /* AE26 (44582) */ - 3343, /* AE27 (44583) */ - 3343, /* AE28 (44584) */ - 3343, /* AE29 (44585) */ - 3343, /* AE2A (44586) */ - 3343, /* AE2B (44587) */ - 3343, /* AE2C (44588) */ - 3343, /* AE2D (44589) */ - 3343, /* AE2E (44590) */ - 3343, /* AE2F (44591) */ - 3343, /* AE30 (44592) */ - 3343, /* AE31 (44593) */ - 3343, /* AE32 (44594) */ - 3343, /* AE33 (44595) */ - 3343, /* AE34 (44596) */ - 3343, /* AE35 (44597) */ - 3343, /* AE36 (44598) */ - 3343, /* AE37 (44599) */ - 3343, /* AE38 (44600) */ - 3343, /* AE39 (44601) */ - 3343, /* AE3A (44602) */ - 3343, /* AE3B (44603) */ - 3343, /* AE3C (44604) */ - 3343, /* AE3D (44605) */ - 3343, /* AE3E (44606) */ - 3343, /* AE3F (44607) */ - 3343, /* AE40 (44608) */ - 3343, /* AE41 (44609) */ - 3343, /* AE42 (44610) */ - 3343, /* AE43 (44611) */ - 3343, /* AE44 (44612) */ - 3343, /* AE45 (44613) */ - 3343, /* AE46 (44614) */ - 3343, /* AE47 (44615) */ - 3343, /* AE48 (44616) */ - 3343, /* AE49 (44617) */ - 3343, /* AE4A (44618) */ - 3343, /* AE4B (44619) */ - 3343, /* AE4C (44620) */ - 3343, /* AE4D (44621) */ - 3343, /* AE4E (44622) */ - 3343, /* AE4F (44623) */ - 3343, /* AE50 (44624) */ - 3343, /* AE51 (44625) */ - 3343, /* AE52 (44626) */ - 3343, /* AE53 (44627) */ - 3343, /* AE54 (44628) */ - 3343, /* AE55 (44629) */ - 3343, /* AE56 (44630) */ - 3343, /* AE57 (44631) */ - 3343, /* AE58 (44632) */ - 3343, /* AE59 (44633) */ - 3343, /* AE5A (44634) */ - 3343, /* AE5B (44635) */ - 3343, /* AE5C (44636) */ - 3343, /* AE5D (44637) */ - 3343, /* AE5E (44638) */ - 3343, /* AE5F (44639) */ - 3343, /* AE60 (44640) */ - 3343, /* AE61 (44641) */ - 3343, /* AE62 (44642) */ - 3343, /* AE63 (44643) */ - 3343, /* AE64 (44644) */ - 3343, /* AE65 (44645) */ - 3343, /* AE66 (44646) */ - 3343, /* AE67 (44647) */ - 3343, /* AE68 (44648) */ - 3343, /* AE69 (44649) */ - 3343, /* AE6A (44650) */ - 3343, /* AE6B (44651) */ - 3343, /* AE6C (44652) */ - 3343, /* AE6D (44653) */ - 3343, /* AE6E (44654) */ - 3343, /* AE6F (44655) */ - 3343, /* AE70 (44656) */ - 3343, /* AE71 (44657) */ - 3343, /* AE72 (44658) */ - 3343, /* AE73 (44659) */ - 3343, /* AE74 (44660) */ - 3343, /* AE75 (44661) */ - 3343, /* AE76 (44662) */ - 3343, /* AE77 (44663) */ - 3343, /* AE78 (44664) */ - 3343, /* AE79 (44665) */ - 3343, /* AE7A (44666) */ - 3343, /* AE7B (44667) */ - 3343, /* AE7C (44668) */ - 3343, /* AE7D (44669) */ - 3343, /* AE7E (44670) */ - 3343, /* AE7F (44671) */ - 3343, /* AE80 (44672) */ - 3343, /* AE81 (44673) */ - 3343, /* AE82 (44674) */ - 3343, /* AE83 (44675) */ - 3343, /* AE84 (44676) */ - 3343, /* AE85 (44677) */ - 3343, /* AE86 (44678) */ - 3343, /* AE87 (44679) */ - 3343, /* AE88 (44680) */ - 3343, /* AE89 (44681) */ - 3343, /* AE8A (44682) */ - 3343, /* AE8B (44683) */ - 3343, /* AE8C (44684) */ - 3343, /* AE8D (44685) */ - 3343, /* AE8E (44686) */ - 3343, /* AE8F (44687) */ - 3343, /* AE90 (44688) */ - 3343, /* AE91 (44689) */ - 3343, /* AE92 (44690) */ - 3343, /* AE93 (44691) */ - 3343, /* AE94 (44692) */ - 3343, /* AE95 (44693) */ - 3343, /* AE96 (44694) */ - 3343, /* AE97 (44695) */ - 3343, /* AE98 (44696) */ - 3343, /* AE99 (44697) */ - 3343, /* AE9A (44698) */ - 3343, /* AE9B (44699) */ - 3343, /* AE9C (44700) */ - 3343, /* AE9D (44701) */ - 3343, /* AE9E (44702) */ - 3343, /* AE9F (44703) */ - 3343, /* AEA0 (44704) */ - 3343, /* AEA1 (44705) */ - 3343, /* AEA2 (44706) */ - 3343, /* AEA3 (44707) */ - 3343, /* AEA4 (44708) */ - 3343, /* AEA5 (44709) */ - 3343, /* AEA6 (44710) */ - 3343, /* AEA7 (44711) */ - 3343, /* AEA8 (44712) */ - 3343, /* AEA9 (44713) */ - 3343, /* AEAA (44714) */ - 3343, /* AEAB (44715) */ - 3343, /* AEAC (44716) */ - 3343, /* AEAD (44717) */ - 3343, /* AEAE (44718) */ - 3343, /* AEAF (44719) */ - 3343, /* AEB0 (44720) */ - 3343, /* AEB1 (44721) */ - 3343, /* AEB2 (44722) */ - 3343, /* AEB3 (44723) */ - 3343, /* AEB4 (44724) */ - 3343, /* AEB5 (44725) */ - 3343, /* AEB6 (44726) */ - 3343, /* AEB7 (44727) */ - 3343, /* AEB8 (44728) */ - 3343, /* AEB9 (44729) */ - 3343, /* AEBA (44730) */ - 3343, /* AEBB (44731) */ - 3343, /* AEBC (44732) */ - 3343, /* AEBD (44733) */ - 3343, /* AEBE (44734) */ - 3343, /* AEBF (44735) */ - 3343, /* AEC0 (44736) */ - 3343, /* AEC1 (44737) */ - 3343, /* AEC2 (44738) */ - 3343, /* AEC3 (44739) */ - 3343, /* AEC4 (44740) */ - 3343, /* AEC5 (44741) */ - 3343, /* AEC6 (44742) */ - 3343, /* AEC7 (44743) */ - 3343, /* AEC8 (44744) */ - 3343, /* AEC9 (44745) */ - 3343, /* AECA (44746) */ - 3343, /* AECB (44747) */ - 3343, /* AECC (44748) */ - 3343, /* AECD (44749) */ - 3343, /* AECE (44750) */ - 3343, /* AECF (44751) */ - 3343, /* AED0 (44752) */ - 3343, /* AED1 (44753) */ - 3343, /* AED2 (44754) */ - 3343, /* AED3 (44755) */ - 3343, /* AED4 (44756) */ - 3343, /* AED5 (44757) */ - 3343, /* AED6 (44758) */ - 3343, /* AED7 (44759) */ - 3343, /* AED8 (44760) */ - 3343, /* AED9 (44761) */ - 3343, /* AEDA (44762) */ - 3343, /* AEDB (44763) */ - 3343, /* AEDC (44764) */ - 3343, /* AEDD (44765) */ - 3343, /* AEDE (44766) */ - 3343, /* AEDF (44767) */ - 3343, /* AEE0 (44768) */ - 3343, /* AEE1 (44769) */ - 3343, /* AEE2 (44770) */ - 3343, /* AEE3 (44771) */ - 3343, /* AEE4 (44772) */ - 3343, /* AEE5 (44773) */ - 3343, /* AEE6 (44774) */ - 3343, /* AEE7 (44775) */ - 3343, /* AEE8 (44776) */ - 3343, /* AEE9 (44777) */ - 3343, /* AEEA (44778) */ - 3343, /* AEEB (44779) */ - 3343, /* AEEC (44780) */ - 3343, /* AEED (44781) */ - 3343, /* AEEE (44782) */ - 3343, /* AEEF (44783) */ - 3343, /* AEF0 (44784) */ - 3343, /* AEF1 (44785) */ - 3343, /* AEF2 (44786) */ - 3343, /* AEF3 (44787) */ - 3343, /* AEF4 (44788) */ - 3343, /* AEF5 (44789) */ - 3343, /* AEF6 (44790) */ - 3343, /* AEF7 (44791) */ - 3343, /* AEF8 (44792) */ - 3343, /* AEF9 (44793) */ - 3343, /* AEFA (44794) */ - 3343, /* AEFB (44795) */ - 3343, /* AEFC (44796) */ - 3343, /* AEFD (44797) */ - 3343, /* AEFE (44798) */ - 3343, /* AEFF (44799) */ - 3343, /* AF00 (44800) */ - 3343, /* AF01 (44801) */ - 3343, /* AF02 (44802) */ - 3343, /* AF03 (44803) */ - 3343, /* AF04 (44804) */ - 3343, /* AF05 (44805) */ - 3343, /* AF06 (44806) */ - 3343, /* AF07 (44807) */ - 3343, /* AF08 (44808) */ - 3343, /* AF09 (44809) */ - 3343, /* AF0A (44810) */ - 3343, /* AF0B (44811) */ - 3343, /* AF0C (44812) */ - 3343, /* AF0D (44813) */ - 3343, /* AF0E (44814) */ - 3343, /* AF0F (44815) */ - 3343, /* AF10 (44816) */ - 3343, /* AF11 (44817) */ - 3343, /* AF12 (44818) */ - 3343, /* AF13 (44819) */ - 3343, /* AF14 (44820) */ - 3343, /* AF15 (44821) */ - 3343, /* AF16 (44822) */ - 3343, /* AF17 (44823) */ - 3343, /* AF18 (44824) */ - 3343, /* AF19 (44825) */ - 3343, /* AF1A (44826) */ - 3343, /* AF1B (44827) */ - 3343, /* AF1C (44828) */ - 3343, /* AF1D (44829) */ - 3343, /* AF1E (44830) */ - 3343, /* AF1F (44831) */ - 3343, /* AF20 (44832) */ - 3343, /* AF21 (44833) */ - 3343, /* AF22 (44834) */ - 3343, /* AF23 (44835) */ - 3343, /* AF24 (44836) */ - 3343, /* AF25 (44837) */ - 3343, /* AF26 (44838) */ - 3343, /* AF27 (44839) */ - 3343, /* AF28 (44840) */ - 3343, /* AF29 (44841) */ - 3343, /* AF2A (44842) */ - 3343, /* AF2B (44843) */ - 3343, /* AF2C (44844) */ - 3343, /* AF2D (44845) */ - 3343, /* AF2E (44846) */ - 3343, /* AF2F (44847) */ - 3343, /* AF30 (44848) */ - 3343, /* AF31 (44849) */ - 3343, /* AF32 (44850) */ - 3343, /* AF33 (44851) */ - 3343, /* AF34 (44852) */ - 3343, /* AF35 (44853) */ - 3343, /* AF36 (44854) */ - 3343, /* AF37 (44855) */ - 3343, /* AF38 (44856) */ - 3343, /* AF39 (44857) */ - 3343, /* AF3A (44858) */ - 3343, /* AF3B (44859) */ - 3343, /* AF3C (44860) */ - 3343, /* AF3D (44861) */ - 3343, /* AF3E (44862) */ - 3343, /* AF3F (44863) */ - 3343, /* AF40 (44864) */ - 3343, /* AF41 (44865) */ - 3343, /* AF42 (44866) */ - 3343, /* AF43 (44867) */ - 3343, /* AF44 (44868) */ - 3343, /* AF45 (44869) */ - 3343, /* AF46 (44870) */ - 3343, /* AF47 (44871) */ - 3343, /* AF48 (44872) */ - 3343, /* AF49 (44873) */ - 3343, /* AF4A (44874) */ - 3343, /* AF4B (44875) */ - 3343, /* AF4C (44876) */ - 3343, /* AF4D (44877) */ - 3343, /* AF4E (44878) */ - 3343, /* AF4F (44879) */ - 3343, /* AF50 (44880) */ - 3343, /* AF51 (44881) */ - 3343, /* AF52 (44882) */ - 3343, /* AF53 (44883) */ - 3343, /* AF54 (44884) */ - 3343, /* AF55 (44885) */ - 3343, /* AF56 (44886) */ - 3343, /* AF57 (44887) */ - 3343, /* AF58 (44888) */ - 3343, /* AF59 (44889) */ - 3343, /* AF5A (44890) */ - 3343, /* AF5B (44891) */ - 3343, /* AF5C (44892) */ - 3343, /* AF5D (44893) */ - 3343, /* AF5E (44894) */ - 3343, /* AF5F (44895) */ - 3343, /* AF60 (44896) */ - 3343, /* AF61 (44897) */ - 3343, /* AF62 (44898) */ - 3343, /* AF63 (44899) */ - 3343, /* AF64 (44900) */ - 3343, /* AF65 (44901) */ - 3343, /* AF66 (44902) */ - 3343, /* AF67 (44903) */ - 3343, /* AF68 (44904) */ - 3343, /* AF69 (44905) */ - 3343, /* AF6A (44906) */ - 3343, /* AF6B (44907) */ - 3343, /* AF6C (44908) */ - 3343, /* AF6D (44909) */ - 3343, /* AF6E (44910) */ - 3343, /* AF6F (44911) */ - 3343, /* AF70 (44912) */ - 3343, /* AF71 (44913) */ - 3343, /* AF72 (44914) */ - 3343, /* AF73 (44915) */ - 3343, /* AF74 (44916) */ - 3343, /* AF75 (44917) */ - 3343, /* AF76 (44918) */ - 3343, /* AF77 (44919) */ - 3343, /* AF78 (44920) */ - 3343, /* AF79 (44921) */ - 3343, /* AF7A (44922) */ - 3343, /* AF7B (44923) */ - 3343, /* AF7C (44924) */ - 3343, /* AF7D (44925) */ - 3343, /* AF7E (44926) */ - 3343, /* AF7F (44927) */ - 3343, /* AF80 (44928) */ - 3343, /* AF81 (44929) */ - 3343, /* AF82 (44930) */ - 3343, /* AF83 (44931) */ - 3343, /* AF84 (44932) */ - 3343, /* AF85 (44933) */ - 3343, /* AF86 (44934) */ - 3343, /* AF87 (44935) */ - 3343, /* AF88 (44936) */ - 3343, /* AF89 (44937) */ - 3343, /* AF8A (44938) */ - 3343, /* AF8B (44939) */ - 3343, /* AF8C (44940) */ - 3343, /* AF8D (44941) */ - 3343, /* AF8E (44942) */ - 3343, /* AF8F (44943) */ - 3343, /* AF90 (44944) */ - 3343, /* AF91 (44945) */ - 3343, /* AF92 (44946) */ - 3343, /* AF93 (44947) */ - 3343, /* AF94 (44948) */ - 3343, /* AF95 (44949) */ - 3343, /* AF96 (44950) */ - 3343, /* AF97 (44951) */ - 3343, /* AF98 (44952) */ - 3343, /* AF99 (44953) */ - 3343, /* AF9A (44954) */ - 3343, /* AF9B (44955) */ - 3343, /* AF9C (44956) */ - 3343, /* AF9D (44957) */ - 3343, /* AF9E (44958) */ - 3343, /* AF9F (44959) */ - 3343, /* AFA0 (44960) */ - 3343, /* AFA1 (44961) */ - 3343, /* AFA2 (44962) */ - 3343, /* AFA3 (44963) */ - 3343, /* AFA4 (44964) */ - 3343, /* AFA5 (44965) */ - 3343, /* AFA6 (44966) */ - 3343, /* AFA7 (44967) */ - 3343, /* AFA8 (44968) */ - 3343, /* AFA9 (44969) */ - 3343, /* AFAA (44970) */ - 3343, /* AFAB (44971) */ - 3343, /* AFAC (44972) */ - 3343, /* AFAD (44973) */ - 3343, /* AFAE (44974) */ - 3343, /* AFAF (44975) */ - 3343, /* AFB0 (44976) */ - 3343, /* AFB1 (44977) */ - 3343, /* AFB2 (44978) */ - 3343, /* AFB3 (44979) */ - 3343, /* AFB4 (44980) */ - 3343, /* AFB5 (44981) */ - 3343, /* AFB6 (44982) */ - 3343, /* AFB7 (44983) */ - 3343, /* AFB8 (44984) */ - 3343, /* AFB9 (44985) */ - 3343, /* AFBA (44986) */ - 3343, /* AFBB (44987) */ - 3343, /* AFBC (44988) */ - 3343, /* AFBD (44989) */ - 3343, /* AFBE (44990) */ - 3343, /* AFBF (44991) */ - 3343, /* AFC0 (44992) */ - 3343, /* AFC1 (44993) */ - 3343, /* AFC2 (44994) */ - 3343, /* AFC3 (44995) */ - 3343, /* AFC4 (44996) */ - 3343, /* AFC5 (44997) */ - 3343, /* AFC6 (44998) */ - 3343, /* AFC7 (44999) */ - 3343, /* AFC8 (45000) */ - 3343, /* AFC9 (45001) */ - 3343, /* AFCA (45002) */ - 3343, /* AFCB (45003) */ - 3343, /* AFCC (45004) */ - 3343, /* AFCD (45005) */ - 3343, /* AFCE (45006) */ - 3343, /* AFCF (45007) */ - 3343, /* AFD0 (45008) */ - 3343, /* AFD1 (45009) */ - 3343, /* AFD2 (45010) */ - 3343, /* AFD3 (45011) */ - 3343, /* AFD4 (45012) */ - 3343, /* AFD5 (45013) */ - 3343, /* AFD6 (45014) */ - 3343, /* AFD7 (45015) */ - 3343, /* AFD8 (45016) */ - 3343, /* AFD9 (45017) */ - 3343, /* AFDA (45018) */ - 3343, /* AFDB (45019) */ - 3343, /* AFDC (45020) */ - 3343, /* AFDD (45021) */ - 3343, /* AFDE (45022) */ - 3343, /* AFDF (45023) */ - 3343, /* AFE0 (45024) */ - 3343, /* AFE1 (45025) */ - 3343, /* AFE2 (45026) */ - 3343, /* AFE3 (45027) */ - 3343, /* AFE4 (45028) */ - 3343, /* AFE5 (45029) */ - 3343, /* AFE6 (45030) */ - 3343, /* AFE7 (45031) */ - 3343, /* AFE8 (45032) */ - 3343, /* AFE9 (45033) */ - 3343, /* AFEA (45034) */ - 3343, /* AFEB (45035) */ - 3343, /* AFEC (45036) */ - 3343, /* AFED (45037) */ - 3343, /* AFEE (45038) */ - 3343, /* AFEF (45039) */ - 3343, /* AFF0 (45040) */ - 3343, /* AFF1 (45041) */ - 3343, /* AFF2 (45042) */ - 3343, /* AFF3 (45043) */ - 3343, /* AFF4 (45044) */ - 3343, /* AFF5 (45045) */ - 3343, /* AFF6 (45046) */ - 3343, /* AFF7 (45047) */ - 3343, /* AFF8 (45048) */ - 3343, /* AFF9 (45049) */ - 3343, /* AFFA (45050) */ - 3343, /* AFFB (45051) */ - 3343, /* AFFC (45052) */ - 3343, /* AFFD (45053) */ - 3343, /* AFFE (45054) */ - 3343, /* AFFF (45055) */ - 3343, /* B000 (45056) */ - 3343, /* B001 (45057) */ - 3343, /* B002 (45058) */ - 3343, /* B003 (45059) */ - 3343, /* B004 (45060) */ - 3343, /* B005 (45061) */ - 3343, /* B006 (45062) */ - 3343, /* B007 (45063) */ - 3343, /* B008 (45064) */ - 3343, /* B009 (45065) */ - 3343, /* B00A (45066) */ - 3343, /* B00B (45067) */ - 3343, /* B00C (45068) */ - 3343, /* B00D (45069) */ - 3343, /* B00E (45070) */ - 3343, /* B00F (45071) */ - 3343, /* B010 (45072) */ - 3343, /* B011 (45073) */ - 3343, /* B012 (45074) */ - 3343, /* B013 (45075) */ - 3343, /* B014 (45076) */ - 3343, /* B015 (45077) */ - 3343, /* B016 (45078) */ - 3343, /* B017 (45079) */ - 3343, /* B018 (45080) */ - 3343, /* B019 (45081) */ - 3343, /* B01A (45082) */ - 3343, /* B01B (45083) */ - 3343, /* B01C (45084) */ - 3343, /* B01D (45085) */ - 3343, /* B01E (45086) */ - 3343, /* B01F (45087) */ - 3343, /* B020 (45088) */ - 3343, /* B021 (45089) */ - 3343, /* B022 (45090) */ - 3343, /* B023 (45091) */ - 3343, /* B024 (45092) */ - 3343, /* B025 (45093) */ - 3343, /* B026 (45094) */ - 3343, /* B027 (45095) */ - 3343, /* B028 (45096) */ - 3343, /* B029 (45097) */ - 3343, /* B02A (45098) */ - 3343, /* B02B (45099) */ - 3343, /* B02C (45100) */ - 3343, /* B02D (45101) */ - 3343, /* B02E (45102) */ - 3343, /* B02F (45103) */ - 3343, /* B030 (45104) */ - 3343, /* B031 (45105) */ - 3343, /* B032 (45106) */ - 3343, /* B033 (45107) */ - 3343, /* B034 (45108) */ - 3343, /* B035 (45109) */ - 3343, /* B036 (45110) */ - 3343, /* B037 (45111) */ - 3343, /* B038 (45112) */ - 3343, /* B039 (45113) */ - 3343, /* B03A (45114) */ - 3343, /* B03B (45115) */ - 3343, /* B03C (45116) */ - 3343, /* B03D (45117) */ - 3343, /* B03E (45118) */ - 3343, /* B03F (45119) */ - 3343, /* B040 (45120) */ - 3343, /* B041 (45121) */ - 3343, /* B042 (45122) */ - 3343, /* B043 (45123) */ - 3343, /* B044 (45124) */ - 3343, /* B045 (45125) */ - 3343, /* B046 (45126) */ - 3343, /* B047 (45127) */ - 3343, /* B048 (45128) */ - 3343, /* B049 (45129) */ - 3343, /* B04A (45130) */ - 3343, /* B04B (45131) */ - 3343, /* B04C (45132) */ - 3343, /* B04D (45133) */ - 3343, /* B04E (45134) */ - 3343, /* B04F (45135) */ - 3343, /* B050 (45136) */ - 3343, /* B051 (45137) */ - 3343, /* B052 (45138) */ - 3343, /* B053 (45139) */ - 3343, /* B054 (45140) */ - 3343, /* B055 (45141) */ - 3343, /* B056 (45142) */ - 3343, /* B057 (45143) */ - 3343, /* B058 (45144) */ - 3343, /* B059 (45145) */ - 3343, /* B05A (45146) */ - 3343, /* B05B (45147) */ - 3343, /* B05C (45148) */ - 3343, /* B05D (45149) */ - 3343, /* B05E (45150) */ - 3343, /* B05F (45151) */ - 3343, /* B060 (45152) */ - 3343, /* B061 (45153) */ - 3343, /* B062 (45154) */ - 3343, /* B063 (45155) */ - 3343, /* B064 (45156) */ - 3343, /* B065 (45157) */ - 3343, /* B066 (45158) */ - 3343, /* B067 (45159) */ - 3343, /* B068 (45160) */ - 3343, /* B069 (45161) */ - 3343, /* B06A (45162) */ - 3343, /* B06B (45163) */ - 3343, /* B06C (45164) */ - 3343, /* B06D (45165) */ - 3343, /* B06E (45166) */ - 3343, /* B06F (45167) */ - 3343, /* B070 (45168) */ - 3343, /* B071 (45169) */ - 3343, /* B072 (45170) */ - 3343, /* B073 (45171) */ - 3343, /* B074 (45172) */ - 3343, /* B075 (45173) */ - 3343, /* B076 (45174) */ - 3343, /* B077 (45175) */ - 3343, /* B078 (45176) */ - 3343, /* B079 (45177) */ - 3343, /* B07A (45178) */ - 3343, /* B07B (45179) */ - 3343, /* B07C (45180) */ - 3343, /* B07D (45181) */ - 3343, /* B07E (45182) */ - 3343, /* B07F (45183) */ - 3343, /* B080 (45184) */ - 3343, /* B081 (45185) */ - 3343, /* B082 (45186) */ - 3343, /* B083 (45187) */ - 3343, /* B084 (45188) */ - 3343, /* B085 (45189) */ - 3343, /* B086 (45190) */ - 3343, /* B087 (45191) */ - 3343, /* B088 (45192) */ - 3343, /* B089 (45193) */ - 3343, /* B08A (45194) */ - 3343, /* B08B (45195) */ - 3343, /* B08C (45196) */ - 3343, /* B08D (45197) */ - 3343, /* B08E (45198) */ - 3343, /* B08F (45199) */ - 3343, /* B090 (45200) */ - 3343, /* B091 (45201) */ - 3343, /* B092 (45202) */ - 3343, /* B093 (45203) */ - 3343, /* B094 (45204) */ - 3343, /* B095 (45205) */ - 3343, /* B096 (45206) */ - 3343, /* B097 (45207) */ - 3343, /* B098 (45208) */ - 3343, /* B099 (45209) */ - 3343, /* B09A (45210) */ - 3343, /* B09B (45211) */ - 3343, /* B09C (45212) */ - 3343, /* B09D (45213) */ - 3343, /* B09E (45214) */ - 3343, /* B09F (45215) */ - 3343, /* B0A0 (45216) */ - 3343, /* B0A1 (45217) */ - 3343, /* B0A2 (45218) */ - 3343, /* B0A3 (45219) */ - 3343, /* B0A4 (45220) */ - 3343, /* B0A5 (45221) */ - 3343, /* B0A6 (45222) */ - 3343, /* B0A7 (45223) */ - 3343, /* B0A8 (45224) */ - 3343, /* B0A9 (45225) */ - 3343, /* B0AA (45226) */ - 3343, /* B0AB (45227) */ - 3343, /* B0AC (45228) */ - 3343, /* B0AD (45229) */ - 3343, /* B0AE (45230) */ - 3343, /* B0AF (45231) */ - 3343, /* B0B0 (45232) */ - 3343, /* B0B1 (45233) */ - 3343, /* B0B2 (45234) */ - 3343, /* B0B3 (45235) */ - 3343, /* B0B4 (45236) */ - 3343, /* B0B5 (45237) */ - 3343, /* B0B6 (45238) */ - 3343, /* B0B7 (45239) */ - 3343, /* B0B8 (45240) */ - 3343, /* B0B9 (45241) */ - 3343, /* B0BA (45242) */ - 3343, /* B0BB (45243) */ - 3343, /* B0BC (45244) */ - 3343, /* B0BD (45245) */ - 3343, /* B0BE (45246) */ - 3343, /* B0BF (45247) */ - 3343, /* B0C0 (45248) */ - 3343, /* B0C1 (45249) */ - 3343, /* B0C2 (45250) */ - 3343, /* B0C3 (45251) */ - 3343, /* B0C4 (45252) */ - 3343, /* B0C5 (45253) */ - 3343, /* B0C6 (45254) */ - 3343, /* B0C7 (45255) */ - 3343, /* B0C8 (45256) */ - 3343, /* B0C9 (45257) */ - 3343, /* B0CA (45258) */ - 3343, /* B0CB (45259) */ - 3343, /* B0CC (45260) */ - 3343, /* B0CD (45261) */ - 3343, /* B0CE (45262) */ - 3343, /* B0CF (45263) */ - 3343, /* B0D0 (45264) */ - 3343, /* B0D1 (45265) */ - 3343, /* B0D2 (45266) */ - 3343, /* B0D3 (45267) */ - 3343, /* B0D4 (45268) */ - 3343, /* B0D5 (45269) */ - 3343, /* B0D6 (45270) */ - 3343, /* B0D7 (45271) */ - 3343, /* B0D8 (45272) */ - 3343, /* B0D9 (45273) */ - 3343, /* B0DA (45274) */ - 3343, /* B0DB (45275) */ - 3343, /* B0DC (45276) */ - 3343, /* B0DD (45277) */ - 3343, /* B0DE (45278) */ - 3343, /* B0DF (45279) */ - 3343, /* B0E0 (45280) */ - 3343, /* B0E1 (45281) */ - 3343, /* B0E2 (45282) */ - 3343, /* B0E3 (45283) */ - 3343, /* B0E4 (45284) */ - 3343, /* B0E5 (45285) */ - 3343, /* B0E6 (45286) */ - 3343, /* B0E7 (45287) */ - 3343, /* B0E8 (45288) */ - 3343, /* B0E9 (45289) */ - 3343, /* B0EA (45290) */ - 3343, /* B0EB (45291) */ - 3343, /* B0EC (45292) */ - 3343, /* B0ED (45293) */ - 3343, /* B0EE (45294) */ - 3343, /* B0EF (45295) */ - 3343, /* B0F0 (45296) */ - 3343, /* B0F1 (45297) */ - 3343, /* B0F2 (45298) */ - 3343, /* B0F3 (45299) */ - 3343, /* B0F4 (45300) */ - 3343, /* B0F5 (45301) */ - 3343, /* B0F6 (45302) */ - 3343, /* B0F7 (45303) */ - 3343, /* B0F8 (45304) */ - 3343, /* B0F9 (45305) */ - 3343, /* B0FA (45306) */ - 3343, /* B0FB (45307) */ - 3343, /* B0FC (45308) */ - 3343, /* B0FD (45309) */ - 3343, /* B0FE (45310) */ - 3343, /* B0FF (45311) */ - 3343, /* B100 (45312) */ - 3343, /* B101 (45313) */ - 3343, /* B102 (45314) */ - 3343, /* B103 (45315) */ - 3343, /* B104 (45316) */ - 3343, /* B105 (45317) */ - 3343, /* B106 (45318) */ - 3343, /* B107 (45319) */ - 3343, /* B108 (45320) */ - 3343, /* B109 (45321) */ - 3343, /* B10A (45322) */ - 3343, /* B10B (45323) */ - 3343, /* B10C (45324) */ - 3343, /* B10D (45325) */ - 3343, /* B10E (45326) */ - 3343, /* B10F (45327) */ - 3343, /* B110 (45328) */ - 3343, /* B111 (45329) */ - 3343, /* B112 (45330) */ - 3343, /* B113 (45331) */ - 3343, /* B114 (45332) */ - 3343, /* B115 (45333) */ - 3343, /* B116 (45334) */ - 3343, /* B117 (45335) */ - 3343, /* B118 (45336) */ - 3343, /* B119 (45337) */ - 3343, /* B11A (45338) */ - 3343, /* B11B (45339) */ - 3343, /* B11C (45340) */ - 3343, /* B11D (45341) */ - 3343, /* B11E (45342) */ - 3343, /* B11F (45343) */ - 3343, /* B120 (45344) */ - 3343, /* B121 (45345) */ - 3343, /* B122 (45346) */ - 3343, /* B123 (45347) */ - 3343, /* B124 (45348) */ - 3343, /* B125 (45349) */ - 3343, /* B126 (45350) */ - 3343, /* B127 (45351) */ - 3343, /* B128 (45352) */ - 3343, /* B129 (45353) */ - 3343, /* B12A (45354) */ - 3343, /* B12B (45355) */ - 3343, /* B12C (45356) */ - 3343, /* B12D (45357) */ - 3343, /* B12E (45358) */ - 3343, /* B12F (45359) */ - 3343, /* B130 (45360) */ - 3343, /* B131 (45361) */ - 3343, /* B132 (45362) */ - 3343, /* B133 (45363) */ - 3343, /* B134 (45364) */ - 3343, /* B135 (45365) */ - 3343, /* B136 (45366) */ - 3343, /* B137 (45367) */ - 3343, /* B138 (45368) */ - 3343, /* B139 (45369) */ - 3343, /* B13A (45370) */ - 3343, /* B13B (45371) */ - 3343, /* B13C (45372) */ - 3343, /* B13D (45373) */ - 3343, /* B13E (45374) */ - 3343, /* B13F (45375) */ - 3343, /* B140 (45376) */ - 3343, /* B141 (45377) */ - 3343, /* B142 (45378) */ - 3343, /* B143 (45379) */ - 3343, /* B144 (45380) */ - 3343, /* B145 (45381) */ - 3343, /* B146 (45382) */ - 3343, /* B147 (45383) */ - 3343, /* B148 (45384) */ - 3343, /* B149 (45385) */ - 3343, /* B14A (45386) */ - 3343, /* B14B (45387) */ - 3343, /* B14C (45388) */ - 3343, /* B14D (45389) */ - 3343, /* B14E (45390) */ - 3343, /* B14F (45391) */ - 3343, /* B150 (45392) */ - 3343, /* B151 (45393) */ - 3343, /* B152 (45394) */ - 3343, /* B153 (45395) */ - 3343, /* B154 (45396) */ - 3343, /* B155 (45397) */ - 3343, /* B156 (45398) */ - 3343, /* B157 (45399) */ - 3343, /* B158 (45400) */ - 3343, /* B159 (45401) */ - 3343, /* B15A (45402) */ - 3343, /* B15B (45403) */ - 3343, /* B15C (45404) */ - 3343, /* B15D (45405) */ - 3343, /* B15E (45406) */ - 3343, /* B15F (45407) */ - 3343, /* B160 (45408) */ - 3343, /* B161 (45409) */ - 3343, /* B162 (45410) */ - 3343, /* B163 (45411) */ - 3343, /* B164 (45412) */ - 3343, /* B165 (45413) */ - 3343, /* B166 (45414) */ - 3343, /* B167 (45415) */ - 3343, /* B168 (45416) */ - 3343, /* B169 (45417) */ - 3343, /* B16A (45418) */ - 3343, /* B16B (45419) */ - 3343, /* B16C (45420) */ - 3343, /* B16D (45421) */ - 3343, /* B16E (45422) */ - 3343, /* B16F (45423) */ - 3343, /* B170 (45424) */ - 3343, /* B171 (45425) */ - 3343, /* B172 (45426) */ - 3343, /* B173 (45427) */ - 3343, /* B174 (45428) */ - 3343, /* B175 (45429) */ - 3343, /* B176 (45430) */ - 3343, /* B177 (45431) */ - 3343, /* B178 (45432) */ - 3343, /* B179 (45433) */ - 3343, /* B17A (45434) */ - 3343, /* B17B (45435) */ - 3343, /* B17C (45436) */ - 3343, /* B17D (45437) */ - 3343, /* B17E (45438) */ - 3343, /* B17F (45439) */ - 3343, /* B180 (45440) */ - 3343, /* B181 (45441) */ - 3343, /* B182 (45442) */ - 3343, /* B183 (45443) */ - 3343, /* B184 (45444) */ - 3343, /* B185 (45445) */ - 3343, /* B186 (45446) */ - 3343, /* B187 (45447) */ - 3343, /* B188 (45448) */ - 3343, /* B189 (45449) */ - 3343, /* B18A (45450) */ - 3343, /* B18B (45451) */ - 3343, /* B18C (45452) */ - 3343, /* B18D (45453) */ - 3343, /* B18E (45454) */ - 3343, /* B18F (45455) */ - 3343, /* B190 (45456) */ - 3343, /* B191 (45457) */ - 3343, /* B192 (45458) */ - 3343, /* B193 (45459) */ - 3343, /* B194 (45460) */ - 3343, /* B195 (45461) */ - 3343, /* B196 (45462) */ - 3343, /* B197 (45463) */ - 3343, /* B198 (45464) */ - 3343, /* B199 (45465) */ - 3343, /* B19A (45466) */ - 3343, /* B19B (45467) */ - 3343, /* B19C (45468) */ - 3343, /* B19D (45469) */ - 3343, /* B19E (45470) */ - 3343, /* B19F (45471) */ - 3343, /* B1A0 (45472) */ - 3343, /* B1A1 (45473) */ - 3343, /* B1A2 (45474) */ - 3343, /* B1A3 (45475) */ - 3343, /* B1A4 (45476) */ - 3343, /* B1A5 (45477) */ - 3343, /* B1A6 (45478) */ - 3343, /* B1A7 (45479) */ - 3343, /* B1A8 (45480) */ - 3343, /* B1A9 (45481) */ - 3343, /* B1AA (45482) */ - 3343, /* B1AB (45483) */ - 3343, /* B1AC (45484) */ - 3343, /* B1AD (45485) */ - 3343, /* B1AE (45486) */ - 3343, /* B1AF (45487) */ - 3343, /* B1B0 (45488) */ - 3343, /* B1B1 (45489) */ - 3343, /* B1B2 (45490) */ - 3343, /* B1B3 (45491) */ - 3343, /* B1B4 (45492) */ - 3343, /* B1B5 (45493) */ - 3343, /* B1B6 (45494) */ - 3343, /* B1B7 (45495) */ - 3343, /* B1B8 (45496) */ - 3343, /* B1B9 (45497) */ - 3343, /* B1BA (45498) */ - 3343, /* B1BB (45499) */ - 3343, /* B1BC (45500) */ - 3343, /* B1BD (45501) */ - 3343, /* B1BE (45502) */ - 3343, /* B1BF (45503) */ - 3343, /* B1C0 (45504) */ - 3343, /* B1C1 (45505) */ - 3343, /* B1C2 (45506) */ - 3343, /* B1C3 (45507) */ - 3343, /* B1C4 (45508) */ - 3343, /* B1C5 (45509) */ - 3343, /* B1C6 (45510) */ - 3343, /* B1C7 (45511) */ - 3343, /* B1C8 (45512) */ - 3343, /* B1C9 (45513) */ - 3343, /* B1CA (45514) */ - 3343, /* B1CB (45515) */ - 3343, /* B1CC (45516) */ - 3343, /* B1CD (45517) */ - 3343, /* B1CE (45518) */ - 3343, /* B1CF (45519) */ - 3343, /* B1D0 (45520) */ - 3343, /* B1D1 (45521) */ - 3343, /* B1D2 (45522) */ - 3343, /* B1D3 (45523) */ - 3343, /* B1D4 (45524) */ - 3343, /* B1D5 (45525) */ - 3343, /* B1D6 (45526) */ - 3343, /* B1D7 (45527) */ - 3343, /* B1D8 (45528) */ - 3343, /* B1D9 (45529) */ - 3343, /* B1DA (45530) */ - 3343, /* B1DB (45531) */ - 3343, /* B1DC (45532) */ - 3343, /* B1DD (45533) */ - 3343, /* B1DE (45534) */ - 3343, /* B1DF (45535) */ - 3343, /* B1E0 (45536) */ - 3343, /* B1E1 (45537) */ - 3343, /* B1E2 (45538) */ - 3343, /* B1E3 (45539) */ - 3343, /* B1E4 (45540) */ - 3343, /* B1E5 (45541) */ - 3343, /* B1E6 (45542) */ - 3343, /* B1E7 (45543) */ - 3343, /* B1E8 (45544) */ - 3343, /* B1E9 (45545) */ - 3343, /* B1EA (45546) */ - 3343, /* B1EB (45547) */ - 3343, /* B1EC (45548) */ - 3343, /* B1ED (45549) */ - 3343, /* B1EE (45550) */ - 3343, /* B1EF (45551) */ - 3343, /* B1F0 (45552) */ - 3343, /* B1F1 (45553) */ - 3343, /* B1F2 (45554) */ - 3343, /* B1F3 (45555) */ - 3343, /* B1F4 (45556) */ - 3343, /* B1F5 (45557) */ - 3343, /* B1F6 (45558) */ - 3343, /* B1F7 (45559) */ - 3343, /* B1F8 (45560) */ - 3343, /* B1F9 (45561) */ - 3343, /* B1FA (45562) */ - 3343, /* B1FB (45563) */ - 3343, /* B1FC (45564) */ - 3343, /* B1FD (45565) */ - 3343, /* B1FE (45566) */ - 3343, /* B1FF (45567) */ - 3343, /* B200 (45568) */ - 3343, /* B201 (45569) */ - 3343, /* B202 (45570) */ - 3343, /* B203 (45571) */ - 3343, /* B204 (45572) */ - 3343, /* B205 (45573) */ - 3343, /* B206 (45574) */ - 3343, /* B207 (45575) */ - 3343, /* B208 (45576) */ - 3343, /* B209 (45577) */ - 3343, /* B20A (45578) */ - 3343, /* B20B (45579) */ - 3343, /* B20C (45580) */ - 3343, /* B20D (45581) */ - 3343, /* B20E (45582) */ - 3343, /* B20F (45583) */ - 3343, /* B210 (45584) */ - 3343, /* B211 (45585) */ - 3343, /* B212 (45586) */ - 3343, /* B213 (45587) */ - 3343, /* B214 (45588) */ - 3343, /* B215 (45589) */ - 3343, /* B216 (45590) */ - 3343, /* B217 (45591) */ - 3343, /* B218 (45592) */ - 3343, /* B219 (45593) */ - 3343, /* B21A (45594) */ - 3343, /* B21B (45595) */ - 3343, /* B21C (45596) */ - 3343, /* B21D (45597) */ - 3343, /* B21E (45598) */ - 3343, /* B21F (45599) */ - 3343, /* B220 (45600) */ - 3343, /* B221 (45601) */ - 3343, /* B222 (45602) */ - 3343, /* B223 (45603) */ - 3343, /* B224 (45604) */ - 3343, /* B225 (45605) */ - 3343, /* B226 (45606) */ - 3343, /* B227 (45607) */ - 3343, /* B228 (45608) */ - 3343, /* B229 (45609) */ - 3343, /* B22A (45610) */ - 3343, /* B22B (45611) */ - 3343, /* B22C (45612) */ - 3343, /* B22D (45613) */ - 3343, /* B22E (45614) */ - 3343, /* B22F (45615) */ - 3343, /* B230 (45616) */ - 3343, /* B231 (45617) */ - 3343, /* B232 (45618) */ - 3343, /* B233 (45619) */ - 3343, /* B234 (45620) */ - 3343, /* B235 (45621) */ - 3343, /* B236 (45622) */ - 3343, /* B237 (45623) */ - 3343, /* B238 (45624) */ - 3343, /* B239 (45625) */ - 3343, /* B23A (45626) */ - 3343, /* B23B (45627) */ - 3343, /* B23C (45628) */ - 3343, /* B23D (45629) */ - 3343, /* B23E (45630) */ - 3343, /* B23F (45631) */ - 3343, /* B240 (45632) */ - 3343, /* B241 (45633) */ - 3343, /* B242 (45634) */ - 3343, /* B243 (45635) */ - 3343, /* B244 (45636) */ - 3343, /* B245 (45637) */ - 3343, /* B246 (45638) */ - 3343, /* B247 (45639) */ - 3343, /* B248 (45640) */ - 3343, /* B249 (45641) */ - 3343, /* B24A (45642) */ - 3343, /* B24B (45643) */ - 3343, /* B24C (45644) */ - 3343, /* B24D (45645) */ - 3343, /* B24E (45646) */ - 3343, /* B24F (45647) */ - 3343, /* B250 (45648) */ - 3343, /* B251 (45649) */ - 3343, /* B252 (45650) */ - 3343, /* B253 (45651) */ - 3343, /* B254 (45652) */ - 3343, /* B255 (45653) */ - 3343, /* B256 (45654) */ - 3343, /* B257 (45655) */ - 3343, /* B258 (45656) */ - 3343, /* B259 (45657) */ - 3343, /* B25A (45658) */ - 3343, /* B25B (45659) */ - 3343, /* B25C (45660) */ - 3343, /* B25D (45661) */ - 3343, /* B25E (45662) */ - 3343, /* B25F (45663) */ - 3343, /* B260 (45664) */ - 3343, /* B261 (45665) */ - 3343, /* B262 (45666) */ - 3343, /* B263 (45667) */ - 3343, /* B264 (45668) */ - 3343, /* B265 (45669) */ - 3343, /* B266 (45670) */ - 3343, /* B267 (45671) */ - 3343, /* B268 (45672) */ - 3343, /* B269 (45673) */ - 3343, /* B26A (45674) */ - 3343, /* B26B (45675) */ - 3343, /* B26C (45676) */ - 3343, /* B26D (45677) */ - 3343, /* B26E (45678) */ - 3343, /* B26F (45679) */ - 3343, /* B270 (45680) */ - 3343, /* B271 (45681) */ - 3343, /* B272 (45682) */ - 3343, /* B273 (45683) */ - 3343, /* B274 (45684) */ - 3343, /* B275 (45685) */ - 3343, /* B276 (45686) */ - 3343, /* B277 (45687) */ - 3343, /* B278 (45688) */ - 3343, /* B279 (45689) */ - 3343, /* B27A (45690) */ - 3343, /* B27B (45691) */ - 3343, /* B27C (45692) */ - 3343, /* B27D (45693) */ - 3343, /* B27E (45694) */ - 3343, /* B27F (45695) */ - 3343, /* B280 (45696) */ - 3343, /* B281 (45697) */ - 3343, /* B282 (45698) */ - 3343, /* B283 (45699) */ - 3343, /* B284 (45700) */ - 3343, /* B285 (45701) */ - 3343, /* B286 (45702) */ - 3343, /* B287 (45703) */ - 3343, /* B288 (45704) */ - 3343, /* B289 (45705) */ - 3343, /* B28A (45706) */ - 3343, /* B28B (45707) */ - 3343, /* B28C (45708) */ - 3343, /* B28D (45709) */ - 3343, /* B28E (45710) */ - 3343, /* B28F (45711) */ - 3343, /* B290 (45712) */ - 3343, /* B291 (45713) */ - 3343, /* B292 (45714) */ - 3343, /* B293 (45715) */ - 3343, /* B294 (45716) */ - 3343, /* B295 (45717) */ - 3343, /* B296 (45718) */ - 3343, /* B297 (45719) */ - 3343, /* B298 (45720) */ - 3343, /* B299 (45721) */ - 3343, /* B29A (45722) */ - 3343, /* B29B (45723) */ - 3343, /* B29C (45724) */ - 3343, /* B29D (45725) */ - 3343, /* B29E (45726) */ - 3343, /* B29F (45727) */ - 3343, /* B2A0 (45728) */ - 3343, /* B2A1 (45729) */ - 3343, /* B2A2 (45730) */ - 3343, /* B2A3 (45731) */ - 3343, /* B2A4 (45732) */ - 3343, /* B2A5 (45733) */ - 3343, /* B2A6 (45734) */ - 3343, /* B2A7 (45735) */ - 3343, /* B2A8 (45736) */ - 3343, /* B2A9 (45737) */ - 3343, /* B2AA (45738) */ - 3343, /* B2AB (45739) */ - 3343, /* B2AC (45740) */ - 3343, /* B2AD (45741) */ - 3343, /* B2AE (45742) */ - 3343, /* B2AF (45743) */ - 3343, /* B2B0 (45744) */ - 3343, /* B2B1 (45745) */ - 3343, /* B2B2 (45746) */ - 3343, /* B2B3 (45747) */ - 3343, /* B2B4 (45748) */ - 3343, /* B2B5 (45749) */ - 3343, /* B2B6 (45750) */ - 3343, /* B2B7 (45751) */ - 3343, /* B2B8 (45752) */ - 3343, /* B2B9 (45753) */ - 3343, /* B2BA (45754) */ - 3343, /* B2BB (45755) */ - 3343, /* B2BC (45756) */ - 3343, /* B2BD (45757) */ - 3343, /* B2BE (45758) */ - 3343, /* B2BF (45759) */ - 3343, /* B2C0 (45760) */ - 3343, /* B2C1 (45761) */ - 3343, /* B2C2 (45762) */ - 3343, /* B2C3 (45763) */ - 3343, /* B2C4 (45764) */ - 3343, /* B2C5 (45765) */ - 3343, /* B2C6 (45766) */ - 3343, /* B2C7 (45767) */ - 3343, /* B2C8 (45768) */ - 3343, /* B2C9 (45769) */ - 3343, /* B2CA (45770) */ - 3343, /* B2CB (45771) */ - 3343, /* B2CC (45772) */ - 3343, /* B2CD (45773) */ - 3343, /* B2CE (45774) */ - 3343, /* B2CF (45775) */ - 3343, /* B2D0 (45776) */ - 3343, /* B2D1 (45777) */ - 3343, /* B2D2 (45778) */ - 3343, /* B2D3 (45779) */ - 3343, /* B2D4 (45780) */ - 3343, /* B2D5 (45781) */ - 3343, /* B2D6 (45782) */ - 3343, /* B2D7 (45783) */ - 3343, /* B2D8 (45784) */ - 3343, /* B2D9 (45785) */ - 3343, /* B2DA (45786) */ - 3343, /* B2DB (45787) */ - 3343, /* B2DC (45788) */ - 3343, /* B2DD (45789) */ - 3343, /* B2DE (45790) */ - 3343, /* B2DF (45791) */ - 3343, /* B2E0 (45792) */ - 3343, /* B2E1 (45793) */ - 3343, /* B2E2 (45794) */ - 3343, /* B2E3 (45795) */ - 3343, /* B2E4 (45796) */ - 3343, /* B2E5 (45797) */ - 3343, /* B2E6 (45798) */ - 3343, /* B2E7 (45799) */ - 3343, /* B2E8 (45800) */ - 3343, /* B2E9 (45801) */ - 3343, /* B2EA (45802) */ - 3343, /* B2EB (45803) */ - 3343, /* B2EC (45804) */ - 3343, /* B2ED (45805) */ - 3343, /* B2EE (45806) */ - 3343, /* B2EF (45807) */ - 3343, /* B2F0 (45808) */ - 3343, /* B2F1 (45809) */ - 3343, /* B2F2 (45810) */ - 3343, /* B2F3 (45811) */ - 3343, /* B2F4 (45812) */ - 3343, /* B2F5 (45813) */ - 3343, /* B2F6 (45814) */ - 3343, /* B2F7 (45815) */ - 3343, /* B2F8 (45816) */ - 3343, /* B2F9 (45817) */ - 3343, /* B2FA (45818) */ - 3343, /* B2FB (45819) */ - 3343, /* B2FC (45820) */ - 3343, /* B2FD (45821) */ - 3343, /* B2FE (45822) */ - 3343, /* B2FF (45823) */ - 3343, /* B300 (45824) */ - 3343, /* B301 (45825) */ - 3343, /* B302 (45826) */ - 3343, /* B303 (45827) */ - 3343, /* B304 (45828) */ - 3343, /* B305 (45829) */ - 3343, /* B306 (45830) */ - 3343, /* B307 (45831) */ - 3343, /* B308 (45832) */ - 3343, /* B309 (45833) */ - 3343, /* B30A (45834) */ - 3343, /* B30B (45835) */ - 3343, /* B30C (45836) */ - 3343, /* B30D (45837) */ - 3343, /* B30E (45838) */ - 3343, /* B30F (45839) */ - 3343, /* B310 (45840) */ - 3343, /* B311 (45841) */ - 3343, /* B312 (45842) */ - 3343, /* B313 (45843) */ - 3343, /* B314 (45844) */ - 3343, /* B315 (45845) */ - 3343, /* B316 (45846) */ - 3343, /* B317 (45847) */ - 3343, /* B318 (45848) */ - 3343, /* B319 (45849) */ - 3343, /* B31A (45850) */ - 3343, /* B31B (45851) */ - 3343, /* B31C (45852) */ - 3343, /* B31D (45853) */ - 3343, /* B31E (45854) */ - 3343, /* B31F (45855) */ - 3343, /* B320 (45856) */ - 3343, /* B321 (45857) */ - 3343, /* B322 (45858) */ - 3343, /* B323 (45859) */ - 3343, /* B324 (45860) */ - 3343, /* B325 (45861) */ - 3343, /* B326 (45862) */ - 3343, /* B327 (45863) */ - 3343, /* B328 (45864) */ - 3343, /* B329 (45865) */ - 3343, /* B32A (45866) */ - 3343, /* B32B (45867) */ - 3343, /* B32C (45868) */ - 3343, /* B32D (45869) */ - 3343, /* B32E (45870) */ - 3343, /* B32F (45871) */ - 3343, /* B330 (45872) */ - 3343, /* B331 (45873) */ - 3343, /* B332 (45874) */ - 3343, /* B333 (45875) */ - 3343, /* B334 (45876) */ - 3343, /* B335 (45877) */ - 3343, /* B336 (45878) */ - 3343, /* B337 (45879) */ - 3343, /* B338 (45880) */ - 3343, /* B339 (45881) */ - 3343, /* B33A (45882) */ - 3343, /* B33B (45883) */ - 3343, /* B33C (45884) */ - 3343, /* B33D (45885) */ - 3343, /* B33E (45886) */ - 3343, /* B33F (45887) */ - 3343, /* B340 (45888) */ - 3343, /* B341 (45889) */ - 3343, /* B342 (45890) */ - 3343, /* B343 (45891) */ - 3343, /* B344 (45892) */ - 3343, /* B345 (45893) */ - 3343, /* B346 (45894) */ - 3343, /* B347 (45895) */ - 3343, /* B348 (45896) */ - 3343, /* B349 (45897) */ - 3343, /* B34A (45898) */ - 3343, /* B34B (45899) */ - 3343, /* B34C (45900) */ - 3343, /* B34D (45901) */ - 3343, /* B34E (45902) */ - 3343, /* B34F (45903) */ - 3343, /* B350 (45904) */ - 3343, /* B351 (45905) */ - 3343, /* B352 (45906) */ - 3343, /* B353 (45907) */ - 3343, /* B354 (45908) */ - 3343, /* B355 (45909) */ - 3343, /* B356 (45910) */ - 3343, /* B357 (45911) */ - 3343, /* B358 (45912) */ - 3343, /* B359 (45913) */ - 3343, /* B35A (45914) */ - 3343, /* B35B (45915) */ - 3343, /* B35C (45916) */ - 3343, /* B35D (45917) */ - 3343, /* B35E (45918) */ - 3343, /* B35F (45919) */ - 3343, /* B360 (45920) */ - 3343, /* B361 (45921) */ - 3343, /* B362 (45922) */ - 3343, /* B363 (45923) */ - 3343, /* B364 (45924) */ - 3343, /* B365 (45925) */ - 3343, /* B366 (45926) */ - 3343, /* B367 (45927) */ - 3343, /* B368 (45928) */ - 3343, /* B369 (45929) */ - 3343, /* B36A (45930) */ - 3343, /* B36B (45931) */ - 3343, /* B36C (45932) */ - 3343, /* B36D (45933) */ - 3343, /* B36E (45934) */ - 3343, /* B36F (45935) */ - 3343, /* B370 (45936) */ - 3343, /* B371 (45937) */ - 3343, /* B372 (45938) */ - 3343, /* B373 (45939) */ - 3343, /* B374 (45940) */ - 3343, /* B375 (45941) */ - 3343, /* B376 (45942) */ - 3343, /* B377 (45943) */ - 3343, /* B378 (45944) */ - 3343, /* B379 (45945) */ - 3343, /* B37A (45946) */ - 3343, /* B37B (45947) */ - 3343, /* B37C (45948) */ - 3343, /* B37D (45949) */ - 3343, /* B37E (45950) */ - 3343, /* B37F (45951) */ - 3343, /* B380 (45952) */ - 3343, /* B381 (45953) */ - 3343, /* B382 (45954) */ - 3343, /* B383 (45955) */ - 3343, /* B384 (45956) */ - 3343, /* B385 (45957) */ - 3343, /* B386 (45958) */ - 3343, /* B387 (45959) */ - 3343, /* B388 (45960) */ - 3343, /* B389 (45961) */ - 3343, /* B38A (45962) */ - 3343, /* B38B (45963) */ - 3343, /* B38C (45964) */ - 3343, /* B38D (45965) */ - 3343, /* B38E (45966) */ - 3343, /* B38F (45967) */ - 3343, /* B390 (45968) */ - 3343, /* B391 (45969) */ - 3343, /* B392 (45970) */ - 3343, /* B393 (45971) */ - 3343, /* B394 (45972) */ - 3343, /* B395 (45973) */ - 3343, /* B396 (45974) */ - 3343, /* B397 (45975) */ - 3343, /* B398 (45976) */ - 3343, /* B399 (45977) */ - 3343, /* B39A (45978) */ - 3343, /* B39B (45979) */ - 3343, /* B39C (45980) */ - 3343, /* B39D (45981) */ - 3343, /* B39E (45982) */ - 3343, /* B39F (45983) */ - 3343, /* B3A0 (45984) */ - 3343, /* B3A1 (45985) */ - 3343, /* B3A2 (45986) */ - 3343, /* B3A3 (45987) */ - 3343, /* B3A4 (45988) */ - 3343, /* B3A5 (45989) */ - 3343, /* B3A6 (45990) */ - 3343, /* B3A7 (45991) */ - 3343, /* B3A8 (45992) */ - 3343, /* B3A9 (45993) */ - 3343, /* B3AA (45994) */ - 3343, /* B3AB (45995) */ - 3343, /* B3AC (45996) */ - 3343, /* B3AD (45997) */ - 3343, /* B3AE (45998) */ - 3343, /* B3AF (45999) */ - 3343, /* B3B0 (46000) */ - 3343, /* B3B1 (46001) */ - 3343, /* B3B2 (46002) */ - 3343, /* B3B3 (46003) */ - 3343, /* B3B4 (46004) */ - 3343, /* B3B5 (46005) */ - 3343, /* B3B6 (46006) */ - 3343, /* B3B7 (46007) */ - 3343, /* B3B8 (46008) */ - 3343, /* B3B9 (46009) */ - 3343, /* B3BA (46010) */ - 3343, /* B3BB (46011) */ - 3343, /* B3BC (46012) */ - 3343, /* B3BD (46013) */ - 3343, /* B3BE (46014) */ - 3343, /* B3BF (46015) */ - 3343, /* B3C0 (46016) */ - 3343, /* B3C1 (46017) */ - 3343, /* B3C2 (46018) */ - 3343, /* B3C3 (46019) */ - 3343, /* B3C4 (46020) */ - 3343, /* B3C5 (46021) */ - 3343, /* B3C6 (46022) */ - 3343, /* B3C7 (46023) */ - 3343, /* B3C8 (46024) */ - 3343, /* B3C9 (46025) */ - 3343, /* B3CA (46026) */ - 3343, /* B3CB (46027) */ - 3343, /* B3CC (46028) */ - 3343, /* B3CD (46029) */ - 3343, /* B3CE (46030) */ - 3343, /* B3CF (46031) */ - 3343, /* B3D0 (46032) */ - 3343, /* B3D1 (46033) */ - 3343, /* B3D2 (46034) */ - 3343, /* B3D3 (46035) */ - 3343, /* B3D4 (46036) */ - 3343, /* B3D5 (46037) */ - 3343, /* B3D6 (46038) */ - 3343, /* B3D7 (46039) */ - 3343, /* B3D8 (46040) */ - 3343, /* B3D9 (46041) */ - 3343, /* B3DA (46042) */ - 3343, /* B3DB (46043) */ - 3343, /* B3DC (46044) */ - 3343, /* B3DD (46045) */ - 3343, /* B3DE (46046) */ - 3343, /* B3DF (46047) */ - 3343, /* B3E0 (46048) */ - 3343, /* B3E1 (46049) */ - 3343, /* B3E2 (46050) */ - 3343, /* B3E3 (46051) */ - 3343, /* B3E4 (46052) */ - 3343, /* B3E5 (46053) */ - 3343, /* B3E6 (46054) */ - 3343, /* B3E7 (46055) */ - 3343, /* B3E8 (46056) */ - 3343, /* B3E9 (46057) */ - 3343, /* B3EA (46058) */ - 3343, /* B3EB (46059) */ - 3343, /* B3EC (46060) */ - 3343, /* B3ED (46061) */ - 3343, /* B3EE (46062) */ - 3343, /* B3EF (46063) */ - 3343, /* B3F0 (46064) */ - 3343, /* B3F1 (46065) */ - 3343, /* B3F2 (46066) */ - 3343, /* B3F3 (46067) */ - 3343, /* B3F4 (46068) */ - 3343, /* B3F5 (46069) */ - 3343, /* B3F6 (46070) */ - 3343, /* B3F7 (46071) */ - 3343, /* B3F8 (46072) */ - 3343, /* B3F9 (46073) */ - 3343, /* B3FA (46074) */ - 3343, /* B3FB (46075) */ - 3343, /* B3FC (46076) */ - 3343, /* B3FD (46077) */ - 3343, /* B3FE (46078) */ - 3343, /* B3FF (46079) */ - 3343, /* B400 (46080) */ - 3343, /* B401 (46081) */ - 3343, /* B402 (46082) */ - 3343, /* B403 (46083) */ - 3343, /* B404 (46084) */ - 3343, /* B405 (46085) */ - 3343, /* B406 (46086) */ - 3343, /* B407 (46087) */ - 3343, /* B408 (46088) */ - 3343, /* B409 (46089) */ - 3343, /* B40A (46090) */ - 3343, /* B40B (46091) */ - 3343, /* B40C (46092) */ - 3343, /* B40D (46093) */ - 3343, /* B40E (46094) */ - 3343, /* B40F (46095) */ - 3343, /* B410 (46096) */ - 3343, /* B411 (46097) */ - 3343, /* B412 (46098) */ - 3343, /* B413 (46099) */ - 3343, /* B414 (46100) */ - 3343, /* B415 (46101) */ - 3343, /* B416 (46102) */ - 3343, /* B417 (46103) */ - 3343, /* B418 (46104) */ - 3343, /* B419 (46105) */ - 3343, /* B41A (46106) */ - 3343, /* B41B (46107) */ - 3343, /* B41C (46108) */ - 3343, /* B41D (46109) */ - 3343, /* B41E (46110) */ - 3343, /* B41F (46111) */ - 3343, /* B420 (46112) */ - 3343, /* B421 (46113) */ - 3343, /* B422 (46114) */ - 3343, /* B423 (46115) */ - 3343, /* B424 (46116) */ - 3343, /* B425 (46117) */ - 3343, /* B426 (46118) */ - 3343, /* B427 (46119) */ - 3343, /* B428 (46120) */ - 3343, /* B429 (46121) */ - 3343, /* B42A (46122) */ - 3343, /* B42B (46123) */ - 3343, /* B42C (46124) */ - 3343, /* B42D (46125) */ - 3343, /* B42E (46126) */ - 3343, /* B42F (46127) */ - 3343, /* B430 (46128) */ - 3343, /* B431 (46129) */ - 3343, /* B432 (46130) */ - 3343, /* B433 (46131) */ - 3343, /* B434 (46132) */ - 3343, /* B435 (46133) */ - 3343, /* B436 (46134) */ - 3343, /* B437 (46135) */ - 3343, /* B438 (46136) */ - 3343, /* B439 (46137) */ - 3343, /* B43A (46138) */ - 3343, /* B43B (46139) */ - 3343, /* B43C (46140) */ - 3343, /* B43D (46141) */ - 3343, /* B43E (46142) */ - 3343, /* B43F (46143) */ - 3343, /* B440 (46144) */ - 3343, /* B441 (46145) */ - 3343, /* B442 (46146) */ - 3343, /* B443 (46147) */ - 3343, /* B444 (46148) */ - 3343, /* B445 (46149) */ - 3343, /* B446 (46150) */ - 3343, /* B447 (46151) */ - 3343, /* B448 (46152) */ - 3343, /* B449 (46153) */ - 3343, /* B44A (46154) */ - 3343, /* B44B (46155) */ - 3343, /* B44C (46156) */ - 3343, /* B44D (46157) */ - 3343, /* B44E (46158) */ - 3343, /* B44F (46159) */ - 3343, /* B450 (46160) */ - 3343, /* B451 (46161) */ - 3343, /* B452 (46162) */ - 3343, /* B453 (46163) */ - 3343, /* B454 (46164) */ - 3343, /* B455 (46165) */ - 3343, /* B456 (46166) */ - 3343, /* B457 (46167) */ - 3343, /* B458 (46168) */ - 3343, /* B459 (46169) */ - 3343, /* B45A (46170) */ - 3343, /* B45B (46171) */ - 3343, /* B45C (46172) */ - 3343, /* B45D (46173) */ - 3343, /* B45E (46174) */ - 3343, /* B45F (46175) */ - 3343, /* B460 (46176) */ - 3343, /* B461 (46177) */ - 3343, /* B462 (46178) */ - 3343, /* B463 (46179) */ - 3343, /* B464 (46180) */ - 3343, /* B465 (46181) */ - 3343, /* B466 (46182) */ - 3343, /* B467 (46183) */ - 3343, /* B468 (46184) */ - 3343, /* B469 (46185) */ - 3343, /* B46A (46186) */ - 3343, /* B46B (46187) */ - 3343, /* B46C (46188) */ - 3343, /* B46D (46189) */ - 3343, /* B46E (46190) */ - 3343, /* B46F (46191) */ - 3343, /* B470 (46192) */ - 3343, /* B471 (46193) */ - 3343, /* B472 (46194) */ - 3343, /* B473 (46195) */ - 3343, /* B474 (46196) */ - 3343, /* B475 (46197) */ - 3343, /* B476 (46198) */ - 3343, /* B477 (46199) */ - 3343, /* B478 (46200) */ - 3343, /* B479 (46201) */ - 3343, /* B47A (46202) */ - 3343, /* B47B (46203) */ - 3343, /* B47C (46204) */ - 3343, /* B47D (46205) */ - 3343, /* B47E (46206) */ - 3343, /* B47F (46207) */ - 3343, /* B480 (46208) */ - 3343, /* B481 (46209) */ - 3343, /* B482 (46210) */ - 3343, /* B483 (46211) */ - 3343, /* B484 (46212) */ - 3343, /* B485 (46213) */ - 3343, /* B486 (46214) */ - 3343, /* B487 (46215) */ - 3343, /* B488 (46216) */ - 3343, /* B489 (46217) */ - 3343, /* B48A (46218) */ - 3343, /* B48B (46219) */ - 3343, /* B48C (46220) */ - 3343, /* B48D (46221) */ - 3343, /* B48E (46222) */ - 3343, /* B48F (46223) */ - 3343, /* B490 (46224) */ - 3343, /* B491 (46225) */ - 3343, /* B492 (46226) */ - 3343, /* B493 (46227) */ - 3343, /* B494 (46228) */ - 3343, /* B495 (46229) */ - 3343, /* B496 (46230) */ - 3343, /* B497 (46231) */ - 3343, /* B498 (46232) */ - 3343, /* B499 (46233) */ - 3343, /* B49A (46234) */ - 3343, /* B49B (46235) */ - 3343, /* B49C (46236) */ - 3343, /* B49D (46237) */ - 3343, /* B49E (46238) */ - 3343, /* B49F (46239) */ - 3343, /* B4A0 (46240) */ - 3343, /* B4A1 (46241) */ - 3343, /* B4A2 (46242) */ - 3343, /* B4A3 (46243) */ - 3343, /* B4A4 (46244) */ - 3343, /* B4A5 (46245) */ - 3343, /* B4A6 (46246) */ - 3343, /* B4A7 (46247) */ - 3343, /* B4A8 (46248) */ - 3343, /* B4A9 (46249) */ - 3343, /* B4AA (46250) */ - 3343, /* B4AB (46251) */ - 3343, /* B4AC (46252) */ - 3343, /* B4AD (46253) */ - 3343, /* B4AE (46254) */ - 3343, /* B4AF (46255) */ - 3343, /* B4B0 (46256) */ - 3343, /* B4B1 (46257) */ - 3343, /* B4B2 (46258) */ - 3343, /* B4B3 (46259) */ - 3343, /* B4B4 (46260) */ - 3343, /* B4B5 (46261) */ - 3343, /* B4B6 (46262) */ - 3343, /* B4B7 (46263) */ - 3343, /* B4B8 (46264) */ - 3343, /* B4B9 (46265) */ - 3343, /* B4BA (46266) */ - 3343, /* B4BB (46267) */ - 3343, /* B4BC (46268) */ - 3343, /* B4BD (46269) */ - 3343, /* B4BE (46270) */ - 3343, /* B4BF (46271) */ - 3343, /* B4C0 (46272) */ - 3343, /* B4C1 (46273) */ - 3343, /* B4C2 (46274) */ - 3343, /* B4C3 (46275) */ - 3343, /* B4C4 (46276) */ - 3343, /* B4C5 (46277) */ - 3343, /* B4C6 (46278) */ - 3343, /* B4C7 (46279) */ - 3343, /* B4C8 (46280) */ - 3343, /* B4C9 (46281) */ - 3343, /* B4CA (46282) */ - 3343, /* B4CB (46283) */ - 3343, /* B4CC (46284) */ - 3343, /* B4CD (46285) */ - 3343, /* B4CE (46286) */ - 3343, /* B4CF (46287) */ - 3343, /* B4D0 (46288) */ - 3343, /* B4D1 (46289) */ - 3343, /* B4D2 (46290) */ - 3343, /* B4D3 (46291) */ - 3343, /* B4D4 (46292) */ - 3343, /* B4D5 (46293) */ - 3343, /* B4D6 (46294) */ - 3343, /* B4D7 (46295) */ - 3343, /* B4D8 (46296) */ - 3343, /* B4D9 (46297) */ - 3343, /* B4DA (46298) */ - 3343, /* B4DB (46299) */ - 3343, /* B4DC (46300) */ - 3343, /* B4DD (46301) */ - 3343, /* B4DE (46302) */ - 3343, /* B4DF (46303) */ - 3343, /* B4E0 (46304) */ - 3343, /* B4E1 (46305) */ - 3343, /* B4E2 (46306) */ - 3343, /* B4E3 (46307) */ - 3343, /* B4E4 (46308) */ - 3343, /* B4E5 (46309) */ - 3343, /* B4E6 (46310) */ - 3343, /* B4E7 (46311) */ - 3343, /* B4E8 (46312) */ - 3343, /* B4E9 (46313) */ - 3343, /* B4EA (46314) */ - 3343, /* B4EB (46315) */ - 3343, /* B4EC (46316) */ - 3343, /* B4ED (46317) */ - 3343, /* B4EE (46318) */ - 3343, /* B4EF (46319) */ - 3343, /* B4F0 (46320) */ - 3343, /* B4F1 (46321) */ - 3343, /* B4F2 (46322) */ - 3343, /* B4F3 (46323) */ - 3343, /* B4F4 (46324) */ - 3343, /* B4F5 (46325) */ - 3343, /* B4F6 (46326) */ - 3343, /* B4F7 (46327) */ - 3343, /* B4F8 (46328) */ - 3343, /* B4F9 (46329) */ - 3343, /* B4FA (46330) */ - 3343, /* B4FB (46331) */ - 3343, /* B4FC (46332) */ - 3343, /* B4FD (46333) */ - 3343, /* B4FE (46334) */ - 3343, /* B4FF (46335) */ - 3343, /* B500 (46336) */ - 3343, /* B501 (46337) */ - 3343, /* B502 (46338) */ - 3343, /* B503 (46339) */ - 3343, /* B504 (46340) */ - 3343, /* B505 (46341) */ - 3343, /* B506 (46342) */ - 3343, /* B507 (46343) */ - 3343, /* B508 (46344) */ - 3343, /* B509 (46345) */ - 3343, /* B50A (46346) */ - 3343, /* B50B (46347) */ - 3343, /* B50C (46348) */ - 3343, /* B50D (46349) */ - 3343, /* B50E (46350) */ - 3343, /* B50F (46351) */ - 3343, /* B510 (46352) */ - 3343, /* B511 (46353) */ - 3343, /* B512 (46354) */ - 3343, /* B513 (46355) */ - 3343, /* B514 (46356) */ - 3343, /* B515 (46357) */ - 3343, /* B516 (46358) */ - 3343, /* B517 (46359) */ - 3343, /* B518 (46360) */ - 3343, /* B519 (46361) */ - 3343, /* B51A (46362) */ - 3343, /* B51B (46363) */ - 3343, /* B51C (46364) */ - 3343, /* B51D (46365) */ - 3343, /* B51E (46366) */ - 3343, /* B51F (46367) */ - 3343, /* B520 (46368) */ - 3343, /* B521 (46369) */ - 3343, /* B522 (46370) */ - 3343, /* B523 (46371) */ - 3343, /* B524 (46372) */ - 3343, /* B525 (46373) */ - 3343, /* B526 (46374) */ - 3343, /* B527 (46375) */ - 3343, /* B528 (46376) */ - 3343, /* B529 (46377) */ - 3343, /* B52A (46378) */ - 3343, /* B52B (46379) */ - 3343, /* B52C (46380) */ - 3343, /* B52D (46381) */ - 3343, /* B52E (46382) */ - 3343, /* B52F (46383) */ - 3343, /* B530 (46384) */ - 3343, /* B531 (46385) */ - 3343, /* B532 (46386) */ - 3343, /* B533 (46387) */ - 3343, /* B534 (46388) */ - 3343, /* B535 (46389) */ - 3343, /* B536 (46390) */ - 3343, /* B537 (46391) */ - 3343, /* B538 (46392) */ - 3343, /* B539 (46393) */ - 3343, /* B53A (46394) */ - 3343, /* B53B (46395) */ - 3343, /* B53C (46396) */ - 3343, /* B53D (46397) */ - 3343, /* B53E (46398) */ - 3343, /* B53F (46399) */ - 3343, /* B540 (46400) */ - 3343, /* B541 (46401) */ - 3343, /* B542 (46402) */ - 3343, /* B543 (46403) */ - 3343, /* B544 (46404) */ - 3343, /* B545 (46405) */ - 3343, /* B546 (46406) */ - 3343, /* B547 (46407) */ - 3343, /* B548 (46408) */ - 3343, /* B549 (46409) */ - 3343, /* B54A (46410) */ - 3343, /* B54B (46411) */ - 3343, /* B54C (46412) */ - 3343, /* B54D (46413) */ - 3343, /* B54E (46414) */ - 3343, /* B54F (46415) */ - 3343, /* B550 (46416) */ - 3343, /* B551 (46417) */ - 3343, /* B552 (46418) */ - 3343, /* B553 (46419) */ - 3343, /* B554 (46420) */ - 3343, /* B555 (46421) */ - 3343, /* B556 (46422) */ - 3343, /* B557 (46423) */ - 3343, /* B558 (46424) */ - 3343, /* B559 (46425) */ - 3343, /* B55A (46426) */ - 3343, /* B55B (46427) */ - 3343, /* B55C (46428) */ - 3343, /* B55D (46429) */ - 3343, /* B55E (46430) */ - 3343, /* B55F (46431) */ - 3343, /* B560 (46432) */ - 3343, /* B561 (46433) */ - 3343, /* B562 (46434) */ - 3343, /* B563 (46435) */ - 3343, /* B564 (46436) */ - 3343, /* B565 (46437) */ - 3343, /* B566 (46438) */ - 3343, /* B567 (46439) */ - 3343, /* B568 (46440) */ - 3343, /* B569 (46441) */ - 3343, /* B56A (46442) */ - 3343, /* B56B (46443) */ - 3343, /* B56C (46444) */ - 3343, /* B56D (46445) */ - 3343, /* B56E (46446) */ - 3343, /* B56F (46447) */ - 3343, /* B570 (46448) */ - 3343, /* B571 (46449) */ - 3343, /* B572 (46450) */ - 3343, /* B573 (46451) */ - 3343, /* B574 (46452) */ - 3343, /* B575 (46453) */ - 3343, /* B576 (46454) */ - 3343, /* B577 (46455) */ - 3343, /* B578 (46456) */ - 3343, /* B579 (46457) */ - 3343, /* B57A (46458) */ - 3343, /* B57B (46459) */ - 3343, /* B57C (46460) */ - 3343, /* B57D (46461) */ - 3343, /* B57E (46462) */ - 3343, /* B57F (46463) */ - 3343, /* B580 (46464) */ - 3343, /* B581 (46465) */ - 3343, /* B582 (46466) */ - 3343, /* B583 (46467) */ - 3343, /* B584 (46468) */ - 3343, /* B585 (46469) */ - 3343, /* B586 (46470) */ - 3343, /* B587 (46471) */ - 3343, /* B588 (46472) */ - 3343, /* B589 (46473) */ - 3343, /* B58A (46474) */ - 3343, /* B58B (46475) */ - 3343, /* B58C (46476) */ - 3343, /* B58D (46477) */ - 3343, /* B58E (46478) */ - 3343, /* B58F (46479) */ - 3343, /* B590 (46480) */ - 3343, /* B591 (46481) */ - 3343, /* B592 (46482) */ - 3343, /* B593 (46483) */ - 3343, /* B594 (46484) */ - 3343, /* B595 (46485) */ - 3343, /* B596 (46486) */ - 3343, /* B597 (46487) */ - 3343, /* B598 (46488) */ - 3343, /* B599 (46489) */ - 3343, /* B59A (46490) */ - 3343, /* B59B (46491) */ - 3343, /* B59C (46492) */ - 3343, /* B59D (46493) */ - 3343, /* B59E (46494) */ - 3343, /* B59F (46495) */ - 3343, /* B5A0 (46496) */ - 3343, /* B5A1 (46497) */ - 3343, /* B5A2 (46498) */ - 3343, /* B5A3 (46499) */ - 3343, /* B5A4 (46500) */ - 3343, /* B5A5 (46501) */ - 3343, /* B5A6 (46502) */ - 3343, /* B5A7 (46503) */ - 3343, /* B5A8 (46504) */ - 3343, /* B5A9 (46505) */ - 3343, /* B5AA (46506) */ - 3343, /* B5AB (46507) */ - 3343, /* B5AC (46508) */ - 3343, /* B5AD (46509) */ - 3343, /* B5AE (46510) */ - 3343, /* B5AF (46511) */ - 3343, /* B5B0 (46512) */ - 3343, /* B5B1 (46513) */ - 3343, /* B5B2 (46514) */ - 3343, /* B5B3 (46515) */ - 3343, /* B5B4 (46516) */ - 3343, /* B5B5 (46517) */ - 3343, /* B5B6 (46518) */ - 3343, /* B5B7 (46519) */ - 3343, /* B5B8 (46520) */ - 3343, /* B5B9 (46521) */ - 3343, /* B5BA (46522) */ - 3343, /* B5BB (46523) */ - 3343, /* B5BC (46524) */ - 3343, /* B5BD (46525) */ - 3343, /* B5BE (46526) */ - 3343, /* B5BF (46527) */ - 3343, /* B5C0 (46528) */ - 3343, /* B5C1 (46529) */ - 3343, /* B5C2 (46530) */ - 3343, /* B5C3 (46531) */ - 3343, /* B5C4 (46532) */ - 3343, /* B5C5 (46533) */ - 3343, /* B5C6 (46534) */ - 3343, /* B5C7 (46535) */ - 3343, /* B5C8 (46536) */ - 3343, /* B5C9 (46537) */ - 3343, /* B5CA (46538) */ - 3343, /* B5CB (46539) */ - 3343, /* B5CC (46540) */ - 3343, /* B5CD (46541) */ - 3343, /* B5CE (46542) */ - 3343, /* B5CF (46543) */ - 3343, /* B5D0 (46544) */ - 3343, /* B5D1 (46545) */ - 3343, /* B5D2 (46546) */ - 3343, /* B5D3 (46547) */ - 3343, /* B5D4 (46548) */ - 3343, /* B5D5 (46549) */ - 3343, /* B5D6 (46550) */ - 3343, /* B5D7 (46551) */ - 3343, /* B5D8 (46552) */ - 3343, /* B5D9 (46553) */ - 3343, /* B5DA (46554) */ - 3343, /* B5DB (46555) */ - 3343, /* B5DC (46556) */ - 3343, /* B5DD (46557) */ - 3343, /* B5DE (46558) */ - 3343, /* B5DF (46559) */ - 3343, /* B5E0 (46560) */ - 3343, /* B5E1 (46561) */ - 3343, /* B5E2 (46562) */ - 3343, /* B5E3 (46563) */ - 3343, /* B5E4 (46564) */ - 3343, /* B5E5 (46565) */ - 3343, /* B5E6 (46566) */ - 3343, /* B5E7 (46567) */ - 3343, /* B5E8 (46568) */ - 3343, /* B5E9 (46569) */ - 3343, /* B5EA (46570) */ - 3343, /* B5EB (46571) */ - 3343, /* B5EC (46572) */ - 3343, /* B5ED (46573) */ - 3343, /* B5EE (46574) */ - 3343, /* B5EF (46575) */ - 3343, /* B5F0 (46576) */ - 3343, /* B5F1 (46577) */ - 3343, /* B5F2 (46578) */ - 3343, /* B5F3 (46579) */ - 3343, /* B5F4 (46580) */ - 3343, /* B5F5 (46581) */ - 3343, /* B5F6 (46582) */ - 3343, /* B5F7 (46583) */ - 3343, /* B5F8 (46584) */ - 3343, /* B5F9 (46585) */ - 3343, /* B5FA (46586) */ - 3343, /* B5FB (46587) */ - 3343, /* B5FC (46588) */ - 3343, /* B5FD (46589) */ - 3343, /* B5FE (46590) */ - 3343, /* B5FF (46591) */ - 3343, /* B600 (46592) */ - 3343, /* B601 (46593) */ - 3343, /* B602 (46594) */ - 3343, /* B603 (46595) */ - 3343, /* B604 (46596) */ - 3343, /* B605 (46597) */ - 3343, /* B606 (46598) */ - 3343, /* B607 (46599) */ - 3343, /* B608 (46600) */ - 3343, /* B609 (46601) */ - 3343, /* B60A (46602) */ - 3343, /* B60B (46603) */ - 3343, /* B60C (46604) */ - 3343, /* B60D (46605) */ - 3343, /* B60E (46606) */ - 3343, /* B60F (46607) */ - 3343, /* B610 (46608) */ - 3343, /* B611 (46609) */ - 3343, /* B612 (46610) */ - 3343, /* B613 (46611) */ - 3343, /* B614 (46612) */ - 3343, /* B615 (46613) */ - 3343, /* B616 (46614) */ - 3343, /* B617 (46615) */ - 3343, /* B618 (46616) */ - 3343, /* B619 (46617) */ - 3343, /* B61A (46618) */ - 3343, /* B61B (46619) */ - 3343, /* B61C (46620) */ - 3343, /* B61D (46621) */ - 3343, /* B61E (46622) */ - 3343, /* B61F (46623) */ - 3343, /* B620 (46624) */ - 3343, /* B621 (46625) */ - 3343, /* B622 (46626) */ - 3343, /* B623 (46627) */ - 3343, /* B624 (46628) */ - 3343, /* B625 (46629) */ - 3343, /* B626 (46630) */ - 3343, /* B627 (46631) */ - 3343, /* B628 (46632) */ - 3343, /* B629 (46633) */ - 3343, /* B62A (46634) */ - 3343, /* B62B (46635) */ - 3343, /* B62C (46636) */ - 3343, /* B62D (46637) */ - 3343, /* B62E (46638) */ - 3343, /* B62F (46639) */ - 3343, /* B630 (46640) */ - 3343, /* B631 (46641) */ - 3343, /* B632 (46642) */ - 3343, /* B633 (46643) */ - 3343, /* B634 (46644) */ - 3343, /* B635 (46645) */ - 3343, /* B636 (46646) */ - 3343, /* B637 (46647) */ - 3343, /* B638 (46648) */ - 3343, /* B639 (46649) */ - 3343, /* B63A (46650) */ - 3343, /* B63B (46651) */ - 3343, /* B63C (46652) */ - 3343, /* B63D (46653) */ - 3343, /* B63E (46654) */ - 3343, /* B63F (46655) */ - 3343, /* B640 (46656) */ - 3343, /* B641 (46657) */ - 3343, /* B642 (46658) */ - 3343, /* B643 (46659) */ - 3343, /* B644 (46660) */ - 3343, /* B645 (46661) */ - 3343, /* B646 (46662) */ - 3343, /* B647 (46663) */ - 3343, /* B648 (46664) */ - 3343, /* B649 (46665) */ - 3343, /* B64A (46666) */ - 3343, /* B64B (46667) */ - 3343, /* B64C (46668) */ - 3343, /* B64D (46669) */ - 3343, /* B64E (46670) */ - 3343, /* B64F (46671) */ - 3343, /* B650 (46672) */ - 3343, /* B651 (46673) */ - 3343, /* B652 (46674) */ - 3343, /* B653 (46675) */ - 3343, /* B654 (46676) */ - 3343, /* B655 (46677) */ - 3343, /* B656 (46678) */ - 3343, /* B657 (46679) */ - 3343, /* B658 (46680) */ - 3343, /* B659 (46681) */ - 3343, /* B65A (46682) */ - 3343, /* B65B (46683) */ - 3343, /* B65C (46684) */ - 3343, /* B65D (46685) */ - 3343, /* B65E (46686) */ - 3343, /* B65F (46687) */ - 3343, /* B660 (46688) */ - 3343, /* B661 (46689) */ - 3343, /* B662 (46690) */ - 3343, /* B663 (46691) */ - 3343, /* B664 (46692) */ - 3343, /* B665 (46693) */ - 3343, /* B666 (46694) */ - 3343, /* B667 (46695) */ - 3343, /* B668 (46696) */ - 3343, /* B669 (46697) */ - 3343, /* B66A (46698) */ - 3343, /* B66B (46699) */ - 3343, /* B66C (46700) */ - 3343, /* B66D (46701) */ - 3343, /* B66E (46702) */ - 3343, /* B66F (46703) */ - 3343, /* B670 (46704) */ - 3343, /* B671 (46705) */ - 3343, /* B672 (46706) */ - 3343, /* B673 (46707) */ - 3343, /* B674 (46708) */ - 3343, /* B675 (46709) */ - 3343, /* B676 (46710) */ - 3343, /* B677 (46711) */ - 3343, /* B678 (46712) */ - 3343, /* B679 (46713) */ - 3343, /* B67A (46714) */ - 3343, /* B67B (46715) */ - 3343, /* B67C (46716) */ - 3343, /* B67D (46717) */ - 3343, /* B67E (46718) */ - 3343, /* B67F (46719) */ - 3343, /* B680 (46720) */ - 3343, /* B681 (46721) */ - 3343, /* B682 (46722) */ - 3343, /* B683 (46723) */ - 3343, /* B684 (46724) */ - 3343, /* B685 (46725) */ - 3343, /* B686 (46726) */ - 3343, /* B687 (46727) */ - 3343, /* B688 (46728) */ - 3343, /* B689 (46729) */ - 3343, /* B68A (46730) */ - 3343, /* B68B (46731) */ - 3343, /* B68C (46732) */ - 3343, /* B68D (46733) */ - 3343, /* B68E (46734) */ - 3343, /* B68F (46735) */ - 3343, /* B690 (46736) */ - 3343, /* B691 (46737) */ - 3343, /* B692 (46738) */ - 3343, /* B693 (46739) */ - 3343, /* B694 (46740) */ - 3343, /* B695 (46741) */ - 3343, /* B696 (46742) */ - 3343, /* B697 (46743) */ - 3343, /* B698 (46744) */ - 3343, /* B699 (46745) */ - 3343, /* B69A (46746) */ - 3343, /* B69B (46747) */ - 3343, /* B69C (46748) */ - 3343, /* B69D (46749) */ - 3343, /* B69E (46750) */ - 3343, /* B69F (46751) */ - 3343, /* B6A0 (46752) */ - 3343, /* B6A1 (46753) */ - 3343, /* B6A2 (46754) */ - 3343, /* B6A3 (46755) */ - 3343, /* B6A4 (46756) */ - 3343, /* B6A5 (46757) */ - 3343, /* B6A6 (46758) */ - 3343, /* B6A7 (46759) */ - 3343, /* B6A8 (46760) */ - 3343, /* B6A9 (46761) */ - 3343, /* B6AA (46762) */ - 3343, /* B6AB (46763) */ - 3343, /* B6AC (46764) */ - 3343, /* B6AD (46765) */ - 3343, /* B6AE (46766) */ - 3343, /* B6AF (46767) */ - 3343, /* B6B0 (46768) */ - 3343, /* B6B1 (46769) */ - 3343, /* B6B2 (46770) */ - 3343, /* B6B3 (46771) */ - 3343, /* B6B4 (46772) */ - 3343, /* B6B5 (46773) */ - 3343, /* B6B6 (46774) */ - 3343, /* B6B7 (46775) */ - 3343, /* B6B8 (46776) */ - 3343, /* B6B9 (46777) */ - 3343, /* B6BA (46778) */ - 3343, /* B6BB (46779) */ - 3343, /* B6BC (46780) */ - 3343, /* B6BD (46781) */ - 3343, /* B6BE (46782) */ - 3343, /* B6BF (46783) */ - 3343, /* B6C0 (46784) */ - 3343, /* B6C1 (46785) */ - 3343, /* B6C2 (46786) */ - 3343, /* B6C3 (46787) */ - 3343, /* B6C4 (46788) */ - 3343, /* B6C5 (46789) */ - 3343, /* B6C6 (46790) */ - 3343, /* B6C7 (46791) */ - 3343, /* B6C8 (46792) */ - 3343, /* B6C9 (46793) */ - 3343, /* B6CA (46794) */ - 3343, /* B6CB (46795) */ - 3343, /* B6CC (46796) */ - 3343, /* B6CD (46797) */ - 3343, /* B6CE (46798) */ - 3343, /* B6CF (46799) */ - 3343, /* B6D0 (46800) */ - 3343, /* B6D1 (46801) */ - 3343, /* B6D2 (46802) */ - 3343, /* B6D3 (46803) */ - 3343, /* B6D4 (46804) */ - 3343, /* B6D5 (46805) */ - 3343, /* B6D6 (46806) */ - 3343, /* B6D7 (46807) */ - 3343, /* B6D8 (46808) */ - 3343, /* B6D9 (46809) */ - 3343, /* B6DA (46810) */ - 3343, /* B6DB (46811) */ - 3343, /* B6DC (46812) */ - 3343, /* B6DD (46813) */ - 3343, /* B6DE (46814) */ - 3343, /* B6DF (46815) */ - 3343, /* B6E0 (46816) */ - 3343, /* B6E1 (46817) */ - 3343, /* B6E2 (46818) */ - 3343, /* B6E3 (46819) */ - 3343, /* B6E4 (46820) */ - 3343, /* B6E5 (46821) */ - 3343, /* B6E6 (46822) */ - 3343, /* B6E7 (46823) */ - 3343, /* B6E8 (46824) */ - 3343, /* B6E9 (46825) */ - 3343, /* B6EA (46826) */ - 3343, /* B6EB (46827) */ - 3343, /* B6EC (46828) */ - 3343, /* B6ED (46829) */ - 3343, /* B6EE (46830) */ - 3343, /* B6EF (46831) */ - 3343, /* B6F0 (46832) */ - 3343, /* B6F1 (46833) */ - 3343, /* B6F2 (46834) */ - 3343, /* B6F3 (46835) */ - 3343, /* B6F4 (46836) */ - 3343, /* B6F5 (46837) */ - 3343, /* B6F6 (46838) */ - 3343, /* B6F7 (46839) */ - 3343, /* B6F8 (46840) */ - 3343, /* B6F9 (46841) */ - 3343, /* B6FA (46842) */ - 3343, /* B6FB (46843) */ - 3343, /* B6FC (46844) */ - 3343, /* B6FD (46845) */ - 3343, /* B6FE (46846) */ - 3343, /* B6FF (46847) */ - 3343, /* B700 (46848) */ - 3343, /* B701 (46849) */ - 3343, /* B702 (46850) */ - 3343, /* B703 (46851) */ - 3343, /* B704 (46852) */ - 3343, /* B705 (46853) */ - 3343, /* B706 (46854) */ - 3343, /* B707 (46855) */ - 3343, /* B708 (46856) */ - 3343, /* B709 (46857) */ - 3343, /* B70A (46858) */ - 3343, /* B70B (46859) */ - 3343, /* B70C (46860) */ - 3343, /* B70D (46861) */ - 3343, /* B70E (46862) */ - 3343, /* B70F (46863) */ - 3343, /* B710 (46864) */ - 3343, /* B711 (46865) */ - 3343, /* B712 (46866) */ - 3343, /* B713 (46867) */ - 3343, /* B714 (46868) */ - 3343, /* B715 (46869) */ - 3343, /* B716 (46870) */ - 3343, /* B717 (46871) */ - 3343, /* B718 (46872) */ - 3343, /* B719 (46873) */ - 3343, /* B71A (46874) */ - 3343, /* B71B (46875) */ - 3343, /* B71C (46876) */ - 3343, /* B71D (46877) */ - 3343, /* B71E (46878) */ - 3343, /* B71F (46879) */ - 3343, /* B720 (46880) */ - 3343, /* B721 (46881) */ - 3343, /* B722 (46882) */ - 3343, /* B723 (46883) */ - 3343, /* B724 (46884) */ - 3343, /* B725 (46885) */ - 3343, /* B726 (46886) */ - 3343, /* B727 (46887) */ - 3343, /* B728 (46888) */ - 3343, /* B729 (46889) */ - 3343, /* B72A (46890) */ - 3343, /* B72B (46891) */ - 3343, /* B72C (46892) */ - 3343, /* B72D (46893) */ - 3343, /* B72E (46894) */ - 3343, /* B72F (46895) */ - 3343, /* B730 (46896) */ - 3343, /* B731 (46897) */ - 3343, /* B732 (46898) */ - 3343, /* B733 (46899) */ - 3343, /* B734 (46900) */ - 3343, /* B735 (46901) */ - 3343, /* B736 (46902) */ - 3343, /* B737 (46903) */ - 3343, /* B738 (46904) */ - 3343, /* B739 (46905) */ - 3343, /* B73A (46906) */ - 3343, /* B73B (46907) */ - 3343, /* B73C (46908) */ - 3343, /* B73D (46909) */ - 3343, /* B73E (46910) */ - 3343, /* B73F (46911) */ - 3343, /* B740 (46912) */ - 3343, /* B741 (46913) */ - 3343, /* B742 (46914) */ - 3343, /* B743 (46915) */ - 3343, /* B744 (46916) */ - 3343, /* B745 (46917) */ - 3343, /* B746 (46918) */ - 3343, /* B747 (46919) */ - 3343, /* B748 (46920) */ - 3343, /* B749 (46921) */ - 3343, /* B74A (46922) */ - 3343, /* B74B (46923) */ - 3343, /* B74C (46924) */ - 3343, /* B74D (46925) */ - 3343, /* B74E (46926) */ - 3343, /* B74F (46927) */ - 3343, /* B750 (46928) */ - 3343, /* B751 (46929) */ - 3343, /* B752 (46930) */ - 3343, /* B753 (46931) */ - 3343, /* B754 (46932) */ - 3343, /* B755 (46933) */ - 3343, /* B756 (46934) */ - 3343, /* B757 (46935) */ - 3343, /* B758 (46936) */ - 3343, /* B759 (46937) */ - 3343, /* B75A (46938) */ - 3343, /* B75B (46939) */ - 3343, /* B75C (46940) */ - 3343, /* B75D (46941) */ - 3343, /* B75E (46942) */ - 3343, /* B75F (46943) */ - 3343, /* B760 (46944) */ - 3343, /* B761 (46945) */ - 3343, /* B762 (46946) */ - 3343, /* B763 (46947) */ - 3343, /* B764 (46948) */ - 3343, /* B765 (46949) */ - 3343, /* B766 (46950) */ - 3343, /* B767 (46951) */ - 3343, /* B768 (46952) */ - 3343, /* B769 (46953) */ - 3343, /* B76A (46954) */ - 3343, /* B76B (46955) */ - 3343, /* B76C (46956) */ - 3343, /* B76D (46957) */ - 3343, /* B76E (46958) */ - 3343, /* B76F (46959) */ - 3343, /* B770 (46960) */ - 3343, /* B771 (46961) */ - 3343, /* B772 (46962) */ - 3343, /* B773 (46963) */ - 3343, /* B774 (46964) */ - 3343, /* B775 (46965) */ - 3343, /* B776 (46966) */ - 3343, /* B777 (46967) */ - 3343, /* B778 (46968) */ - 3343, /* B779 (46969) */ - 3343, /* B77A (46970) */ - 3343, /* B77B (46971) */ - 3343, /* B77C (46972) */ - 3343, /* B77D (46973) */ - 3343, /* B77E (46974) */ - 3343, /* B77F (46975) */ - 3343, /* B780 (46976) */ - 3343, /* B781 (46977) */ - 3343, /* B782 (46978) */ - 3343, /* B783 (46979) */ - 3343, /* B784 (46980) */ - 3343, /* B785 (46981) */ - 3343, /* B786 (46982) */ - 3343, /* B787 (46983) */ - 3343, /* B788 (46984) */ - 3343, /* B789 (46985) */ - 3343, /* B78A (46986) */ - 3343, /* B78B (46987) */ - 3343, /* B78C (46988) */ - 3343, /* B78D (46989) */ - 3343, /* B78E (46990) */ - 3343, /* B78F (46991) */ - 3343, /* B790 (46992) */ - 3343, /* B791 (46993) */ - 3343, /* B792 (46994) */ - 3343, /* B793 (46995) */ - 3343, /* B794 (46996) */ - 3343, /* B795 (46997) */ - 3343, /* B796 (46998) */ - 3343, /* B797 (46999) */ - 3343, /* B798 (47000) */ - 3343, /* B799 (47001) */ - 3343, /* B79A (47002) */ - 3343, /* B79B (47003) */ - 3343, /* B79C (47004) */ - 3343, /* B79D (47005) */ - 3343, /* B79E (47006) */ - 3343, /* B79F (47007) */ - 3343, /* B7A0 (47008) */ - 3343, /* B7A1 (47009) */ - 3343, /* B7A2 (47010) */ - 3343, /* B7A3 (47011) */ - 3343, /* B7A4 (47012) */ - 3343, /* B7A5 (47013) */ - 3343, /* B7A6 (47014) */ - 3343, /* B7A7 (47015) */ - 3343, /* B7A8 (47016) */ - 3343, /* B7A9 (47017) */ - 3343, /* B7AA (47018) */ - 3343, /* B7AB (47019) */ - 3343, /* B7AC (47020) */ - 3343, /* B7AD (47021) */ - 3343, /* B7AE (47022) */ - 3343, /* B7AF (47023) */ - 3343, /* B7B0 (47024) */ - 3343, /* B7B1 (47025) */ - 3343, /* B7B2 (47026) */ - 3343, /* B7B3 (47027) */ - 3343, /* B7B4 (47028) */ - 3343, /* B7B5 (47029) */ - 3343, /* B7B6 (47030) */ - 3343, /* B7B7 (47031) */ - 3343, /* B7B8 (47032) */ - 3343, /* B7B9 (47033) */ - 3343, /* B7BA (47034) */ - 3343, /* B7BB (47035) */ - 3343, /* B7BC (47036) */ - 3343, /* B7BD (47037) */ - 3343, /* B7BE (47038) */ - 3343, /* B7BF (47039) */ - 3343, /* B7C0 (47040) */ - 3343, /* B7C1 (47041) */ - 3343, /* B7C2 (47042) */ - 3343, /* B7C3 (47043) */ - 3343, /* B7C4 (47044) */ - 3343, /* B7C5 (47045) */ - 3343, /* B7C6 (47046) */ - 3343, /* B7C7 (47047) */ - 3343, /* B7C8 (47048) */ - 3343, /* B7C9 (47049) */ - 3343, /* B7CA (47050) */ - 3343, /* B7CB (47051) */ - 3343, /* B7CC (47052) */ - 3343, /* B7CD (47053) */ - 3343, /* B7CE (47054) */ - 3343, /* B7CF (47055) */ - 3343, /* B7D0 (47056) */ - 3343, /* B7D1 (47057) */ - 3343, /* B7D2 (47058) */ - 3343, /* B7D3 (47059) */ - 3343, /* B7D4 (47060) */ - 3343, /* B7D5 (47061) */ - 3343, /* B7D6 (47062) */ - 3343, /* B7D7 (47063) */ - 3343, /* B7D8 (47064) */ - 3343, /* B7D9 (47065) */ - 3343, /* B7DA (47066) */ - 3343, /* B7DB (47067) */ - 3343, /* B7DC (47068) */ - 3343, /* B7DD (47069) */ - 3343, /* B7DE (47070) */ - 3343, /* B7DF (47071) */ - 3343, /* B7E0 (47072) */ - 3343, /* B7E1 (47073) */ - 3343, /* B7E2 (47074) */ - 3343, /* B7E3 (47075) */ - 3343, /* B7E4 (47076) */ - 3343, /* B7E5 (47077) */ - 3343, /* B7E6 (47078) */ - 3343, /* B7E7 (47079) */ - 3343, /* B7E8 (47080) */ - 3343, /* B7E9 (47081) */ - 3343, /* B7EA (47082) */ - 3343, /* B7EB (47083) */ - 3343, /* B7EC (47084) */ - 3343, /* B7ED (47085) */ - 3343, /* B7EE (47086) */ - 3343, /* B7EF (47087) */ - 3343, /* B7F0 (47088) */ - 3343, /* B7F1 (47089) */ - 3343, /* B7F2 (47090) */ - 3343, /* B7F3 (47091) */ - 3343, /* B7F4 (47092) */ - 3343, /* B7F5 (47093) */ - 3343, /* B7F6 (47094) */ - 3343, /* B7F7 (47095) */ - 3343, /* B7F8 (47096) */ - 3343, /* B7F9 (47097) */ - 3343, /* B7FA (47098) */ - 3343, /* B7FB (47099) */ - 3343, /* B7FC (47100) */ - 3343, /* B7FD (47101) */ - 3343, /* B7FE (47102) */ - 3343, /* B7FF (47103) */ - 3343, /* B800 (47104) */ - 3343, /* B801 (47105) */ - 3343, /* B802 (47106) */ - 3343, /* B803 (47107) */ - 3343, /* B804 (47108) */ - 3343, /* B805 (47109) */ - 3343, /* B806 (47110) */ - 3343, /* B807 (47111) */ - 3343, /* B808 (47112) */ - 3343, /* B809 (47113) */ - 3343, /* B80A (47114) */ - 3343, /* B80B (47115) */ - 3343, /* B80C (47116) */ - 3343, /* B80D (47117) */ - 3343, /* B80E (47118) */ - 3343, /* B80F (47119) */ - 3343, /* B810 (47120) */ - 3343, /* B811 (47121) */ - 3343, /* B812 (47122) */ - 3343, /* B813 (47123) */ - 3343, /* B814 (47124) */ - 3343, /* B815 (47125) */ - 3343, /* B816 (47126) */ - 3343, /* B817 (47127) */ - 3343, /* B818 (47128) */ - 3343, /* B819 (47129) */ - 3343, /* B81A (47130) */ - 3343, /* B81B (47131) */ - 3343, /* B81C (47132) */ - 3343, /* B81D (47133) */ - 3343, /* B81E (47134) */ - 3343, /* B81F (47135) */ - 3343, /* B820 (47136) */ - 3343, /* B821 (47137) */ - 3343, /* B822 (47138) */ - 3343, /* B823 (47139) */ - 3343, /* B824 (47140) */ - 3343, /* B825 (47141) */ - 3343, /* B826 (47142) */ - 3343, /* B827 (47143) */ - 3343, /* B828 (47144) */ - 3343, /* B829 (47145) */ - 3343, /* B82A (47146) */ - 3343, /* B82B (47147) */ - 3343, /* B82C (47148) */ - 3343, /* B82D (47149) */ - 3343, /* B82E (47150) */ - 3343, /* B82F (47151) */ - 3343, /* B830 (47152) */ - 3343, /* B831 (47153) */ - 3343, /* B832 (47154) */ - 3343, /* B833 (47155) */ - 3343, /* B834 (47156) */ - 3343, /* B835 (47157) */ - 3343, /* B836 (47158) */ - 3343, /* B837 (47159) */ - 3343, /* B838 (47160) */ - 3343, /* B839 (47161) */ - 3343, /* B83A (47162) */ - 3343, /* B83B (47163) */ - 3343, /* B83C (47164) */ - 3343, /* B83D (47165) */ - 3343, /* B83E (47166) */ - 3343, /* B83F (47167) */ - 3343, /* B840 (47168) */ - 3343, /* B841 (47169) */ - 3343, /* B842 (47170) */ - 3343, /* B843 (47171) */ - 3343, /* B844 (47172) */ - 3343, /* B845 (47173) */ - 3343, /* B846 (47174) */ - 3343, /* B847 (47175) */ - 3343, /* B848 (47176) */ - 3343, /* B849 (47177) */ - 3343, /* B84A (47178) */ - 3343, /* B84B (47179) */ - 3343, /* B84C (47180) */ - 3343, /* B84D (47181) */ - 3343, /* B84E (47182) */ - 3343, /* B84F (47183) */ - 3343, /* B850 (47184) */ - 3343, /* B851 (47185) */ - 3343, /* B852 (47186) */ - 3343, /* B853 (47187) */ - 3343, /* B854 (47188) */ - 3343, /* B855 (47189) */ - 3343, /* B856 (47190) */ - 3343, /* B857 (47191) */ - 3343, /* B858 (47192) */ - 3343, /* B859 (47193) */ - 3343, /* B85A (47194) */ - 3343, /* B85B (47195) */ - 3343, /* B85C (47196) */ - 3343, /* B85D (47197) */ - 3343, /* B85E (47198) */ - 3343, /* B85F (47199) */ - 3343, /* B860 (47200) */ - 3343, /* B861 (47201) */ - 3343, /* B862 (47202) */ - 3343, /* B863 (47203) */ - 3343, /* B864 (47204) */ - 3343, /* B865 (47205) */ - 3343, /* B866 (47206) */ - 3343, /* B867 (47207) */ - 3343, /* B868 (47208) */ - 3343, /* B869 (47209) */ - 3343, /* B86A (47210) */ - 3343, /* B86B (47211) */ - 3343, /* B86C (47212) */ - 3343, /* B86D (47213) */ - 3343, /* B86E (47214) */ - 3343, /* B86F (47215) */ - 3343, /* B870 (47216) */ - 3343, /* B871 (47217) */ - 3343, /* B872 (47218) */ - 3343, /* B873 (47219) */ - 3343, /* B874 (47220) */ - 3343, /* B875 (47221) */ - 3343, /* B876 (47222) */ - 3343, /* B877 (47223) */ - 3343, /* B878 (47224) */ - 3343, /* B879 (47225) */ - 3343, /* B87A (47226) */ - 3343, /* B87B (47227) */ - 3343, /* B87C (47228) */ - 3343, /* B87D (47229) */ - 3343, /* B87E (47230) */ - 3343, /* B87F (47231) */ - 3343, /* B880 (47232) */ - 3343, /* B881 (47233) */ - 3343, /* B882 (47234) */ - 3343, /* B883 (47235) */ - 3343, /* B884 (47236) */ - 3343, /* B885 (47237) */ - 3343, /* B886 (47238) */ - 3343, /* B887 (47239) */ - 3343, /* B888 (47240) */ - 3343, /* B889 (47241) */ - 3343, /* B88A (47242) */ - 3343, /* B88B (47243) */ - 3343, /* B88C (47244) */ - 3343, /* B88D (47245) */ - 3343, /* B88E (47246) */ - 3343, /* B88F (47247) */ - 3343, /* B890 (47248) */ - 3343, /* B891 (47249) */ - 3343, /* B892 (47250) */ - 3343, /* B893 (47251) */ - 3343, /* B894 (47252) */ - 3343, /* B895 (47253) */ - 3343, /* B896 (47254) */ - 3343, /* B897 (47255) */ - 3343, /* B898 (47256) */ - 3343, /* B899 (47257) */ - 3343, /* B89A (47258) */ - 3343, /* B89B (47259) */ - 3343, /* B89C (47260) */ - 3343, /* B89D (47261) */ - 3343, /* B89E (47262) */ - 3343, /* B89F (47263) */ - 3343, /* B8A0 (47264) */ - 3343, /* B8A1 (47265) */ - 3343, /* B8A2 (47266) */ - 3343, /* B8A3 (47267) */ - 3343, /* B8A4 (47268) */ - 3343, /* B8A5 (47269) */ - 3343, /* B8A6 (47270) */ - 3343, /* B8A7 (47271) */ - 3343, /* B8A8 (47272) */ - 3343, /* B8A9 (47273) */ - 3343, /* B8AA (47274) */ - 3343, /* B8AB (47275) */ - 3343, /* B8AC (47276) */ - 3343, /* B8AD (47277) */ - 3343, /* B8AE (47278) */ - 3343, /* B8AF (47279) */ - 3343, /* B8B0 (47280) */ - 3343, /* B8B1 (47281) */ - 3343, /* B8B2 (47282) */ - 3343, /* B8B3 (47283) */ - 3343, /* B8B4 (47284) */ - 3343, /* B8B5 (47285) */ - 3343, /* B8B6 (47286) */ - 3343, /* B8B7 (47287) */ - 3343, /* B8B8 (47288) */ - 3343, /* B8B9 (47289) */ - 3343, /* B8BA (47290) */ - 3343, /* B8BB (47291) */ - 3343, /* B8BC (47292) */ - 3343, /* B8BD (47293) */ - 3343, /* B8BE (47294) */ - 3343, /* B8BF (47295) */ - 3343, /* B8C0 (47296) */ - 3343, /* B8C1 (47297) */ - 3343, /* B8C2 (47298) */ - 3343, /* B8C3 (47299) */ - 3343, /* B8C4 (47300) */ - 3343, /* B8C5 (47301) */ - 3343, /* B8C6 (47302) */ - 3343, /* B8C7 (47303) */ - 3343, /* B8C8 (47304) */ - 3343, /* B8C9 (47305) */ - 3343, /* B8CA (47306) */ - 3343, /* B8CB (47307) */ - 3343, /* B8CC (47308) */ - 3343, /* B8CD (47309) */ - 3343, /* B8CE (47310) */ - 3343, /* B8CF (47311) */ - 3343, /* B8D0 (47312) */ - 3343, /* B8D1 (47313) */ - 3343, /* B8D2 (47314) */ - 3343, /* B8D3 (47315) */ - 3343, /* B8D4 (47316) */ - 3343, /* B8D5 (47317) */ - 3343, /* B8D6 (47318) */ - 3343, /* B8D7 (47319) */ - 3343, /* B8D8 (47320) */ - 3343, /* B8D9 (47321) */ - 3343, /* B8DA (47322) */ - 3343, /* B8DB (47323) */ - 3343, /* B8DC (47324) */ - 3343, /* B8DD (47325) */ - 3343, /* B8DE (47326) */ - 3343, /* B8DF (47327) */ - 3343, /* B8E0 (47328) */ - 3343, /* B8E1 (47329) */ - 3343, /* B8E2 (47330) */ - 3343, /* B8E3 (47331) */ - 3343, /* B8E4 (47332) */ - 3343, /* B8E5 (47333) */ - 3343, /* B8E6 (47334) */ - 3343, /* B8E7 (47335) */ - 3343, /* B8E8 (47336) */ - 3343, /* B8E9 (47337) */ - 3343, /* B8EA (47338) */ - 3343, /* B8EB (47339) */ - 3343, /* B8EC (47340) */ - 3343, /* B8ED (47341) */ - 3343, /* B8EE (47342) */ - 3343, /* B8EF (47343) */ - 3343, /* B8F0 (47344) */ - 3343, /* B8F1 (47345) */ - 3343, /* B8F2 (47346) */ - 3343, /* B8F3 (47347) */ - 3343, /* B8F4 (47348) */ - 3343, /* B8F5 (47349) */ - 3343, /* B8F6 (47350) */ - 3343, /* B8F7 (47351) */ - 3343, /* B8F8 (47352) */ - 3343, /* B8F9 (47353) */ - 3343, /* B8FA (47354) */ - 3343, /* B8FB (47355) */ - 3343, /* B8FC (47356) */ - 3343, /* B8FD (47357) */ - 3343, /* B8FE (47358) */ - 3343, /* B8FF (47359) */ - 3343, /* B900 (47360) */ - 3343, /* B901 (47361) */ - 3343, /* B902 (47362) */ - 3343, /* B903 (47363) */ - 3343, /* B904 (47364) */ - 3343, /* B905 (47365) */ - 3343, /* B906 (47366) */ - 3343, /* B907 (47367) */ - 3343, /* B908 (47368) */ - 3343, /* B909 (47369) */ - 3343, /* B90A (47370) */ - 3343, /* B90B (47371) */ - 3343, /* B90C (47372) */ - 3343, /* B90D (47373) */ - 3343, /* B90E (47374) */ - 3343, /* B90F (47375) */ - 3343, /* B910 (47376) */ - 3343, /* B911 (47377) */ - 3343, /* B912 (47378) */ - 3343, /* B913 (47379) */ - 3343, /* B914 (47380) */ - 3343, /* B915 (47381) */ - 3343, /* B916 (47382) */ - 3343, /* B917 (47383) */ - 3343, /* B918 (47384) */ - 3343, /* B919 (47385) */ - 3343, /* B91A (47386) */ - 3343, /* B91B (47387) */ - 3343, /* B91C (47388) */ - 3343, /* B91D (47389) */ - 3343, /* B91E (47390) */ - 3343, /* B91F (47391) */ - 3343, /* B920 (47392) */ - 3343, /* B921 (47393) */ - 3343, /* B922 (47394) */ - 3343, /* B923 (47395) */ - 3343, /* B924 (47396) */ - 3343, /* B925 (47397) */ - 3343, /* B926 (47398) */ - 3343, /* B927 (47399) */ - 3343, /* B928 (47400) */ - 3343, /* B929 (47401) */ - 3343, /* B92A (47402) */ - 3343, /* B92B (47403) */ - 3343, /* B92C (47404) */ - 3343, /* B92D (47405) */ - 3343, /* B92E (47406) */ - 3343, /* B92F (47407) */ - 3343, /* B930 (47408) */ - 3343, /* B931 (47409) */ - 3343, /* B932 (47410) */ - 3343, /* B933 (47411) */ - 3343, /* B934 (47412) */ - 3343, /* B935 (47413) */ - 3343, /* B936 (47414) */ - 3343, /* B937 (47415) */ - 3343, /* B938 (47416) */ - 3343, /* B939 (47417) */ - 3343, /* B93A (47418) */ - 3343, /* B93B (47419) */ - 3343, /* B93C (47420) */ - 3343, /* B93D (47421) */ - 3343, /* B93E (47422) */ - 3343, /* B93F (47423) */ - 3343, /* B940 (47424) */ - 3343, /* B941 (47425) */ - 3343, /* B942 (47426) */ - 3343, /* B943 (47427) */ - 3343, /* B944 (47428) */ - 3343, /* B945 (47429) */ - 3343, /* B946 (47430) */ - 3343, /* B947 (47431) */ - 3343, /* B948 (47432) */ - 3343, /* B949 (47433) */ - 3343, /* B94A (47434) */ - 3343, /* B94B (47435) */ - 3343, /* B94C (47436) */ - 3343, /* B94D (47437) */ - 3343, /* B94E (47438) */ - 3343, /* B94F (47439) */ - 3343, /* B950 (47440) */ - 3343, /* B951 (47441) */ - 3343, /* B952 (47442) */ - 3343, /* B953 (47443) */ - 3343, /* B954 (47444) */ - 3343, /* B955 (47445) */ - 3343, /* B956 (47446) */ - 3343, /* B957 (47447) */ - 3343, /* B958 (47448) */ - 3343, /* B959 (47449) */ - 3343, /* B95A (47450) */ - 3343, /* B95B (47451) */ - 3343, /* B95C (47452) */ - 3343, /* B95D (47453) */ - 3343, /* B95E (47454) */ - 3343, /* B95F (47455) */ - 3343, /* B960 (47456) */ - 3343, /* B961 (47457) */ - 3343, /* B962 (47458) */ - 3343, /* B963 (47459) */ - 3343, /* B964 (47460) */ - 3343, /* B965 (47461) */ - 3343, /* B966 (47462) */ - 3343, /* B967 (47463) */ - 3343, /* B968 (47464) */ - 3343, /* B969 (47465) */ - 3343, /* B96A (47466) */ - 3343, /* B96B (47467) */ - 3343, /* B96C (47468) */ - 3343, /* B96D (47469) */ - 3343, /* B96E (47470) */ - 3343, /* B96F (47471) */ - 3343, /* B970 (47472) */ - 3343, /* B971 (47473) */ - 3343, /* B972 (47474) */ - 3343, /* B973 (47475) */ - 3343, /* B974 (47476) */ - 3343, /* B975 (47477) */ - 3343, /* B976 (47478) */ - 3343, /* B977 (47479) */ - 3343, /* B978 (47480) */ - 3343, /* B979 (47481) */ - 3343, /* B97A (47482) */ - 3343, /* B97B (47483) */ - 3343, /* B97C (47484) */ - 3343, /* B97D (47485) */ - 3343, /* B97E (47486) */ - 3343, /* B97F (47487) */ - 3343, /* B980 (47488) */ - 3343, /* B981 (47489) */ - 3343, /* B982 (47490) */ - 3343, /* B983 (47491) */ - 3343, /* B984 (47492) */ - 3343, /* B985 (47493) */ - 3343, /* B986 (47494) */ - 3343, /* B987 (47495) */ - 3343, /* B988 (47496) */ - 3343, /* B989 (47497) */ - 3343, /* B98A (47498) */ - 3343, /* B98B (47499) */ - 3343, /* B98C (47500) */ - 3343, /* B98D (47501) */ - 3343, /* B98E (47502) */ - 3343, /* B98F (47503) */ - 3343, /* B990 (47504) */ - 3343, /* B991 (47505) */ - 3343, /* B992 (47506) */ - 3343, /* B993 (47507) */ - 3343, /* B994 (47508) */ - 3343, /* B995 (47509) */ - 3343, /* B996 (47510) */ - 3343, /* B997 (47511) */ - 3343, /* B998 (47512) */ - 3343, /* B999 (47513) */ - 3343, /* B99A (47514) */ - 3343, /* B99B (47515) */ - 3343, /* B99C (47516) */ - 3343, /* B99D (47517) */ - 3343, /* B99E (47518) */ - 3343, /* B99F (47519) */ - 3343, /* B9A0 (47520) */ - 3343, /* B9A1 (47521) */ - 3343, /* B9A2 (47522) */ - 3343, /* B9A3 (47523) */ - 3343, /* B9A4 (47524) */ - 3343, /* B9A5 (47525) */ - 3343, /* B9A6 (47526) */ - 3343, /* B9A7 (47527) */ - 3343, /* B9A8 (47528) */ - 3343, /* B9A9 (47529) */ - 3343, /* B9AA (47530) */ - 3343, /* B9AB (47531) */ - 3343, /* B9AC (47532) */ - 3343, /* B9AD (47533) */ - 3343, /* B9AE (47534) */ - 3343, /* B9AF (47535) */ - 3343, /* B9B0 (47536) */ - 3343, /* B9B1 (47537) */ - 3343, /* B9B2 (47538) */ - 3343, /* B9B3 (47539) */ - 3343, /* B9B4 (47540) */ - 3343, /* B9B5 (47541) */ - 3343, /* B9B6 (47542) */ - 3343, /* B9B7 (47543) */ - 3343, /* B9B8 (47544) */ - 3343, /* B9B9 (47545) */ - 3343, /* B9BA (47546) */ - 3343, /* B9BB (47547) */ - 3343, /* B9BC (47548) */ - 3343, /* B9BD (47549) */ - 3343, /* B9BE (47550) */ - 3343, /* B9BF (47551) */ - 3343, /* B9C0 (47552) */ - 3343, /* B9C1 (47553) */ - 3343, /* B9C2 (47554) */ - 3343, /* B9C3 (47555) */ - 3343, /* B9C4 (47556) */ - 3343, /* B9C5 (47557) */ - 3343, /* B9C6 (47558) */ - 3343, /* B9C7 (47559) */ - 3343, /* B9C8 (47560) */ - 3343, /* B9C9 (47561) */ - 3343, /* B9CA (47562) */ - 3343, /* B9CB (47563) */ - 3343, /* B9CC (47564) */ - 3343, /* B9CD (47565) */ - 3343, /* B9CE (47566) */ - 3343, /* B9CF (47567) */ - 3343, /* B9D0 (47568) */ - 3343, /* B9D1 (47569) */ - 3343, /* B9D2 (47570) */ - 3343, /* B9D3 (47571) */ - 3343, /* B9D4 (47572) */ - 3343, /* B9D5 (47573) */ - 3343, /* B9D6 (47574) */ - 3343, /* B9D7 (47575) */ - 3343, /* B9D8 (47576) */ - 3343, /* B9D9 (47577) */ - 3343, /* B9DA (47578) */ - 3343, /* B9DB (47579) */ - 3343, /* B9DC (47580) */ - 3343, /* B9DD (47581) */ - 3343, /* B9DE (47582) */ - 3343, /* B9DF (47583) */ - 3343, /* B9E0 (47584) */ - 3343, /* B9E1 (47585) */ - 3343, /* B9E2 (47586) */ - 3343, /* B9E3 (47587) */ - 3343, /* B9E4 (47588) */ - 3343, /* B9E5 (47589) */ - 3343, /* B9E6 (47590) */ - 3343, /* B9E7 (47591) */ - 3343, /* B9E8 (47592) */ - 3343, /* B9E9 (47593) */ - 3343, /* B9EA (47594) */ - 3343, /* B9EB (47595) */ - 3343, /* B9EC (47596) */ - 3343, /* B9ED (47597) */ - 3343, /* B9EE (47598) */ - 3343, /* B9EF (47599) */ - 3343, /* B9F0 (47600) */ - 3343, /* B9F1 (47601) */ - 3343, /* B9F2 (47602) */ - 3343, /* B9F3 (47603) */ - 3343, /* B9F4 (47604) */ - 3343, /* B9F5 (47605) */ - 3343, /* B9F6 (47606) */ - 3343, /* B9F7 (47607) */ - 3343, /* B9F8 (47608) */ - 3343, /* B9F9 (47609) */ - 3343, /* B9FA (47610) */ - 3343, /* B9FB (47611) */ - 3343, /* B9FC (47612) */ - 3343, /* B9FD (47613) */ - 3343, /* B9FE (47614) */ - 3343, /* B9FF (47615) */ - 3343, /* BA00 (47616) */ - 3343, /* BA01 (47617) */ - 3343, /* BA02 (47618) */ - 3343, /* BA03 (47619) */ - 3343, /* BA04 (47620) */ - 3343, /* BA05 (47621) */ - 3343, /* BA06 (47622) */ - 3343, /* BA07 (47623) */ - 3343, /* BA08 (47624) */ - 3343, /* BA09 (47625) */ - 3343, /* BA0A (47626) */ - 3343, /* BA0B (47627) */ - 3343, /* BA0C (47628) */ - 3343, /* BA0D (47629) */ - 3343, /* BA0E (47630) */ - 3343, /* BA0F (47631) */ - 3343, /* BA10 (47632) */ - 3343, /* BA11 (47633) */ - 3343, /* BA12 (47634) */ - 3343, /* BA13 (47635) */ - 3343, /* BA14 (47636) */ - 3343, /* BA15 (47637) */ - 3343, /* BA16 (47638) */ - 3343, /* BA17 (47639) */ - 3343, /* BA18 (47640) */ - 3343, /* BA19 (47641) */ - 3343, /* BA1A (47642) */ - 3343, /* BA1B (47643) */ - 3343, /* BA1C (47644) */ - 3343, /* BA1D (47645) */ - 3343, /* BA1E (47646) */ - 3343, /* BA1F (47647) */ - 3343, /* BA20 (47648) */ - 3343, /* BA21 (47649) */ - 3343, /* BA22 (47650) */ - 3343, /* BA23 (47651) */ - 3343, /* BA24 (47652) */ - 3343, /* BA25 (47653) */ - 3343, /* BA26 (47654) */ - 3343, /* BA27 (47655) */ - 3343, /* BA28 (47656) */ - 3343, /* BA29 (47657) */ - 3343, /* BA2A (47658) */ - 3343, /* BA2B (47659) */ - 3343, /* BA2C (47660) */ - 3343, /* BA2D (47661) */ - 3343, /* BA2E (47662) */ - 3343, /* BA2F (47663) */ - 3343, /* BA30 (47664) */ - 3343, /* BA31 (47665) */ - 3343, /* BA32 (47666) */ - 3343, /* BA33 (47667) */ - 3343, /* BA34 (47668) */ - 3343, /* BA35 (47669) */ - 3343, /* BA36 (47670) */ - 3343, /* BA37 (47671) */ - 3343, /* BA38 (47672) */ - 3343, /* BA39 (47673) */ - 3343, /* BA3A (47674) */ - 3343, /* BA3B (47675) */ - 3343, /* BA3C (47676) */ - 3343, /* BA3D (47677) */ - 3343, /* BA3E (47678) */ - 3343, /* BA3F (47679) */ - 3343, /* BA40 (47680) */ - 3343, /* BA41 (47681) */ - 3343, /* BA42 (47682) */ - 3343, /* BA43 (47683) */ - 3343, /* BA44 (47684) */ - 3343, /* BA45 (47685) */ - 3343, /* BA46 (47686) */ - 3343, /* BA47 (47687) */ - 3343, /* BA48 (47688) */ - 3343, /* BA49 (47689) */ - 3343, /* BA4A (47690) */ - 3343, /* BA4B (47691) */ - 3343, /* BA4C (47692) */ - 3343, /* BA4D (47693) */ - 3343, /* BA4E (47694) */ - 3343, /* BA4F (47695) */ - 3343, /* BA50 (47696) */ - 3343, /* BA51 (47697) */ - 3343, /* BA52 (47698) */ - 3343, /* BA53 (47699) */ - 3343, /* BA54 (47700) */ - 3343, /* BA55 (47701) */ - 3343, /* BA56 (47702) */ - 3343, /* BA57 (47703) */ - 3343, /* BA58 (47704) */ - 3343, /* BA59 (47705) */ - 3343, /* BA5A (47706) */ - 3343, /* BA5B (47707) */ - 3343, /* BA5C (47708) */ - 3343, /* BA5D (47709) */ - 3343, /* BA5E (47710) */ - 3343, /* BA5F (47711) */ - 3343, /* BA60 (47712) */ - 3343, /* BA61 (47713) */ - 3343, /* BA62 (47714) */ - 3343, /* BA63 (47715) */ - 3343, /* BA64 (47716) */ - 3343, /* BA65 (47717) */ - 3343, /* BA66 (47718) */ - 3343, /* BA67 (47719) */ - 3343, /* BA68 (47720) */ - 3343, /* BA69 (47721) */ - 3343, /* BA6A (47722) */ - 3343, /* BA6B (47723) */ - 3343, /* BA6C (47724) */ - 3343, /* BA6D (47725) */ - 3343, /* BA6E (47726) */ - 3343, /* BA6F (47727) */ - 3343, /* BA70 (47728) */ - 3343, /* BA71 (47729) */ - 3343, /* BA72 (47730) */ - 3343, /* BA73 (47731) */ - 3343, /* BA74 (47732) */ - 3343, /* BA75 (47733) */ - 3343, /* BA76 (47734) */ - 3343, /* BA77 (47735) */ - 3343, /* BA78 (47736) */ - 3343, /* BA79 (47737) */ - 3343, /* BA7A (47738) */ - 3343, /* BA7B (47739) */ - 3343, /* BA7C (47740) */ - 3343, /* BA7D (47741) */ - 3343, /* BA7E (47742) */ - 3343, /* BA7F (47743) */ - 3343, /* BA80 (47744) */ - 3343, /* BA81 (47745) */ - 3343, /* BA82 (47746) */ - 3343, /* BA83 (47747) */ - 3343, /* BA84 (47748) */ - 3343, /* BA85 (47749) */ - 3343, /* BA86 (47750) */ - 3343, /* BA87 (47751) */ - 3343, /* BA88 (47752) */ - 3343, /* BA89 (47753) */ - 3343, /* BA8A (47754) */ - 3343, /* BA8B (47755) */ - 3343, /* BA8C (47756) */ - 3343, /* BA8D (47757) */ - 3343, /* BA8E (47758) */ - 3343, /* BA8F (47759) */ - 3343, /* BA90 (47760) */ - 3343, /* BA91 (47761) */ - 3343, /* BA92 (47762) */ - 3343, /* BA93 (47763) */ - 3343, /* BA94 (47764) */ - 3343, /* BA95 (47765) */ - 3343, /* BA96 (47766) */ - 3343, /* BA97 (47767) */ - 3343, /* BA98 (47768) */ - 3343, /* BA99 (47769) */ - 3343, /* BA9A (47770) */ - 3343, /* BA9B (47771) */ - 3343, /* BA9C (47772) */ - 3343, /* BA9D (47773) */ - 3343, /* BA9E (47774) */ - 3343, /* BA9F (47775) */ - 3343, /* BAA0 (47776) */ - 3343, /* BAA1 (47777) */ - 3343, /* BAA2 (47778) */ - 3343, /* BAA3 (47779) */ - 3343, /* BAA4 (47780) */ - 3343, /* BAA5 (47781) */ - 3343, /* BAA6 (47782) */ - 3343, /* BAA7 (47783) */ - 3343, /* BAA8 (47784) */ - 3343, /* BAA9 (47785) */ - 3343, /* BAAA (47786) */ - 3343, /* BAAB (47787) */ - 3343, /* BAAC (47788) */ - 3343, /* BAAD (47789) */ - 3343, /* BAAE (47790) */ - 3343, /* BAAF (47791) */ - 3343, /* BAB0 (47792) */ - 3343, /* BAB1 (47793) */ - 3343, /* BAB2 (47794) */ - 3343, /* BAB3 (47795) */ - 3343, /* BAB4 (47796) */ - 3343, /* BAB5 (47797) */ - 3343, /* BAB6 (47798) */ - 3343, /* BAB7 (47799) */ - 3343, /* BAB8 (47800) */ - 3343, /* BAB9 (47801) */ - 3343, /* BABA (47802) */ - 3343, /* BABB (47803) */ - 3343, /* BABC (47804) */ - 3343, /* BABD (47805) */ - 3343, /* BABE (47806) */ - 3343, /* BABF (47807) */ - 3343, /* BAC0 (47808) */ - 3343, /* BAC1 (47809) */ - 3343, /* BAC2 (47810) */ - 3343, /* BAC3 (47811) */ - 3343, /* BAC4 (47812) */ - 3343, /* BAC5 (47813) */ - 3343, /* BAC6 (47814) */ - 3343, /* BAC7 (47815) */ - 3343, /* BAC8 (47816) */ - 3343, /* BAC9 (47817) */ - 3343, /* BACA (47818) */ - 3343, /* BACB (47819) */ - 3343, /* BACC (47820) */ - 3343, /* BACD (47821) */ - 3343, /* BACE (47822) */ - 3343, /* BACF (47823) */ - 3343, /* BAD0 (47824) */ - 3343, /* BAD1 (47825) */ - 3343, /* BAD2 (47826) */ - 3343, /* BAD3 (47827) */ - 3343, /* BAD4 (47828) */ - 3343, /* BAD5 (47829) */ - 3343, /* BAD6 (47830) */ - 3343, /* BAD7 (47831) */ - 3343, /* BAD8 (47832) */ - 3343, /* BAD9 (47833) */ - 3343, /* BADA (47834) */ - 3343, /* BADB (47835) */ - 3343, /* BADC (47836) */ - 3343, /* BADD (47837) */ - 3343, /* BADE (47838) */ - 3343, /* BADF (47839) */ - 3343, /* BAE0 (47840) */ - 3343, /* BAE1 (47841) */ - 3343, /* BAE2 (47842) */ - 3343, /* BAE3 (47843) */ - 3343, /* BAE4 (47844) */ - 3343, /* BAE5 (47845) */ - 3343, /* BAE6 (47846) */ - 3343, /* BAE7 (47847) */ - 3343, /* BAE8 (47848) */ - 3343, /* BAE9 (47849) */ - 3343, /* BAEA (47850) */ - 3343, /* BAEB (47851) */ - 3343, /* BAEC (47852) */ - 3343, /* BAED (47853) */ - 3343, /* BAEE (47854) */ - 3343, /* BAEF (47855) */ - 3343, /* BAF0 (47856) */ - 3343, /* BAF1 (47857) */ - 3343, /* BAF2 (47858) */ - 3343, /* BAF3 (47859) */ - 3343, /* BAF4 (47860) */ - 3343, /* BAF5 (47861) */ - 3343, /* BAF6 (47862) */ - 3343, /* BAF7 (47863) */ - 3343, /* BAF8 (47864) */ - 3343, /* BAF9 (47865) */ - 3343, /* BAFA (47866) */ - 3343, /* BAFB (47867) */ - 3343, /* BAFC (47868) */ - 3343, /* BAFD (47869) */ - 3343, /* BAFE (47870) */ - 3343, /* BAFF (47871) */ - 3343, /* BB00 (47872) */ - 3343, /* BB01 (47873) */ - 3343, /* BB02 (47874) */ - 3343, /* BB03 (47875) */ - 3343, /* BB04 (47876) */ - 3343, /* BB05 (47877) */ - 3343, /* BB06 (47878) */ - 3343, /* BB07 (47879) */ - 3343, /* BB08 (47880) */ - 3343, /* BB09 (47881) */ - 3343, /* BB0A (47882) */ - 3343, /* BB0B (47883) */ - 3343, /* BB0C (47884) */ - 3343, /* BB0D (47885) */ - 3343, /* BB0E (47886) */ - 3343, /* BB0F (47887) */ - 3343, /* BB10 (47888) */ - 3343, /* BB11 (47889) */ - 3343, /* BB12 (47890) */ - 3343, /* BB13 (47891) */ - 3343, /* BB14 (47892) */ - 3343, /* BB15 (47893) */ - 3343, /* BB16 (47894) */ - 3343, /* BB17 (47895) */ - 3343, /* BB18 (47896) */ - 3343, /* BB19 (47897) */ - 3343, /* BB1A (47898) */ - 3343, /* BB1B (47899) */ - 3343, /* BB1C (47900) */ - 3343, /* BB1D (47901) */ - 3343, /* BB1E (47902) */ - 3343, /* BB1F (47903) */ - 3343, /* BB20 (47904) */ - 3343, /* BB21 (47905) */ - 3343, /* BB22 (47906) */ - 3343, /* BB23 (47907) */ - 3343, /* BB24 (47908) */ - 3343, /* BB25 (47909) */ - 3343, /* BB26 (47910) */ - 3343, /* BB27 (47911) */ - 3343, /* BB28 (47912) */ - 3343, /* BB29 (47913) */ - 3343, /* BB2A (47914) */ - 3343, /* BB2B (47915) */ - 3343, /* BB2C (47916) */ - 3343, /* BB2D (47917) */ - 3343, /* BB2E (47918) */ - 3343, /* BB2F (47919) */ - 3343, /* BB30 (47920) */ - 3343, /* BB31 (47921) */ - 3343, /* BB32 (47922) */ - 3343, /* BB33 (47923) */ - 3343, /* BB34 (47924) */ - 3343, /* BB35 (47925) */ - 3343, /* BB36 (47926) */ - 3343, /* BB37 (47927) */ - 3343, /* BB38 (47928) */ - 3343, /* BB39 (47929) */ - 3343, /* BB3A (47930) */ - 3343, /* BB3B (47931) */ - 3343, /* BB3C (47932) */ - 3343, /* BB3D (47933) */ - 3343, /* BB3E (47934) */ - 3343, /* BB3F (47935) */ - 3343, /* BB40 (47936) */ - 3343, /* BB41 (47937) */ - 3343, /* BB42 (47938) */ - 3343, /* BB43 (47939) */ - 3343, /* BB44 (47940) */ - 3343, /* BB45 (47941) */ - 3343, /* BB46 (47942) */ - 3343, /* BB47 (47943) */ - 3343, /* BB48 (47944) */ - 3343, /* BB49 (47945) */ - 3343, /* BB4A (47946) */ - 3343, /* BB4B (47947) */ - 3343, /* BB4C (47948) */ - 3343, /* BB4D (47949) */ - 3343, /* BB4E (47950) */ - 3343, /* BB4F (47951) */ - 3343, /* BB50 (47952) */ - 3343, /* BB51 (47953) */ - 3343, /* BB52 (47954) */ - 3343, /* BB53 (47955) */ - 3343, /* BB54 (47956) */ - 3343, /* BB55 (47957) */ - 3343, /* BB56 (47958) */ - 3343, /* BB57 (47959) */ - 3343, /* BB58 (47960) */ - 3343, /* BB59 (47961) */ - 3343, /* BB5A (47962) */ - 3343, /* BB5B (47963) */ - 3343, /* BB5C (47964) */ - 3343, /* BB5D (47965) */ - 3343, /* BB5E (47966) */ - 3343, /* BB5F (47967) */ - 3343, /* BB60 (47968) */ - 3343, /* BB61 (47969) */ - 3343, /* BB62 (47970) */ - 3343, /* BB63 (47971) */ - 3343, /* BB64 (47972) */ - 3343, /* BB65 (47973) */ - 3343, /* BB66 (47974) */ - 3343, /* BB67 (47975) */ - 3343, /* BB68 (47976) */ - 3343, /* BB69 (47977) */ - 3343, /* BB6A (47978) */ - 3343, /* BB6B (47979) */ - 3343, /* BB6C (47980) */ - 3343, /* BB6D (47981) */ - 3343, /* BB6E (47982) */ - 3343, /* BB6F (47983) */ - 3343, /* BB70 (47984) */ - 3343, /* BB71 (47985) */ - 3343, /* BB72 (47986) */ - 3343, /* BB73 (47987) */ - 3343, /* BB74 (47988) */ - 3343, /* BB75 (47989) */ - 3343, /* BB76 (47990) */ - 3343, /* BB77 (47991) */ - 3343, /* BB78 (47992) */ - 3343, /* BB79 (47993) */ - 3343, /* BB7A (47994) */ - 3343, /* BB7B (47995) */ - 3343, /* BB7C (47996) */ - 3343, /* BB7D (47997) */ - 3343, /* BB7E (47998) */ - 3343, /* BB7F (47999) */ - 3343, /* BB80 (48000) */ - 3343, /* BB81 (48001) */ - 3343, /* BB82 (48002) */ - 3343, /* BB83 (48003) */ - 3343, /* BB84 (48004) */ - 3343, /* BB85 (48005) */ - 3343, /* BB86 (48006) */ - 3343, /* BB87 (48007) */ - 3343, /* BB88 (48008) */ - 3343, /* BB89 (48009) */ - 3343, /* BB8A (48010) */ - 3343, /* BB8B (48011) */ - 3343, /* BB8C (48012) */ - 3343, /* BB8D (48013) */ - 3343, /* BB8E (48014) */ - 3343, /* BB8F (48015) */ - 3343, /* BB90 (48016) */ - 3343, /* BB91 (48017) */ - 3343, /* BB92 (48018) */ - 3343, /* BB93 (48019) */ - 3343, /* BB94 (48020) */ - 3343, /* BB95 (48021) */ - 3343, /* BB96 (48022) */ - 3343, /* BB97 (48023) */ - 3343, /* BB98 (48024) */ - 3343, /* BB99 (48025) */ - 3343, /* BB9A (48026) */ - 3343, /* BB9B (48027) */ - 3343, /* BB9C (48028) */ - 3343, /* BB9D (48029) */ - 3343, /* BB9E (48030) */ - 3343, /* BB9F (48031) */ - 3343, /* BBA0 (48032) */ - 3343, /* BBA1 (48033) */ - 3343, /* BBA2 (48034) */ - 3343, /* BBA3 (48035) */ - 3343, /* BBA4 (48036) */ - 3343, /* BBA5 (48037) */ - 3343, /* BBA6 (48038) */ - 3343, /* BBA7 (48039) */ - 3343, /* BBA8 (48040) */ - 3343, /* BBA9 (48041) */ - 3343, /* BBAA (48042) */ - 3343, /* BBAB (48043) */ - 3343, /* BBAC (48044) */ - 3343, /* BBAD (48045) */ - 3343, /* BBAE (48046) */ - 3343, /* BBAF (48047) */ - 3343, /* BBB0 (48048) */ - 3343, /* BBB1 (48049) */ - 3343, /* BBB2 (48050) */ - 3343, /* BBB3 (48051) */ - 3343, /* BBB4 (48052) */ - 3343, /* BBB5 (48053) */ - 3343, /* BBB6 (48054) */ - 3343, /* BBB7 (48055) */ - 3343, /* BBB8 (48056) */ - 3343, /* BBB9 (48057) */ - 3343, /* BBBA (48058) */ - 3343, /* BBBB (48059) */ - 3343, /* BBBC (48060) */ - 3343, /* BBBD (48061) */ - 3343, /* BBBE (48062) */ - 3343, /* BBBF (48063) */ - 3343, /* BBC0 (48064) */ - 3343, /* BBC1 (48065) */ - 3343, /* BBC2 (48066) */ - 3343, /* BBC3 (48067) */ - 3343, /* BBC4 (48068) */ - 3343, /* BBC5 (48069) */ - 3343, /* BBC6 (48070) */ - 3343, /* BBC7 (48071) */ - 3343, /* BBC8 (48072) */ - 3343, /* BBC9 (48073) */ - 3343, /* BBCA (48074) */ - 3343, /* BBCB (48075) */ - 3343, /* BBCC (48076) */ - 3343, /* BBCD (48077) */ - 3343, /* BBCE (48078) */ - 3343, /* BBCF (48079) */ - 3343, /* BBD0 (48080) */ - 3343, /* BBD1 (48081) */ - 3343, /* BBD2 (48082) */ - 3343, /* BBD3 (48083) */ - 3343, /* BBD4 (48084) */ - 3343, /* BBD5 (48085) */ - 3343, /* BBD6 (48086) */ - 3343, /* BBD7 (48087) */ - 3343, /* BBD8 (48088) */ - 3343, /* BBD9 (48089) */ - 3343, /* BBDA (48090) */ - 3343, /* BBDB (48091) */ - 3343, /* BBDC (48092) */ - 3343, /* BBDD (48093) */ - 3343, /* BBDE (48094) */ - 3343, /* BBDF (48095) */ - 3343, /* BBE0 (48096) */ - 3343, /* BBE1 (48097) */ - 3343, /* BBE2 (48098) */ - 3343, /* BBE3 (48099) */ - 3343, /* BBE4 (48100) */ - 3343, /* BBE5 (48101) */ - 3343, /* BBE6 (48102) */ - 3343, /* BBE7 (48103) */ - 3343, /* BBE8 (48104) */ - 3343, /* BBE9 (48105) */ - 3343, /* BBEA (48106) */ - 3343, /* BBEB (48107) */ - 3343, /* BBEC (48108) */ - 3343, /* BBED (48109) */ - 3343, /* BBEE (48110) */ - 3343, /* BBEF (48111) */ - 3343, /* BBF0 (48112) */ - 3343, /* BBF1 (48113) */ - 3343, /* BBF2 (48114) */ - 3343, /* BBF3 (48115) */ - 3343, /* BBF4 (48116) */ - 3343, /* BBF5 (48117) */ - 3343, /* BBF6 (48118) */ - 3343, /* BBF7 (48119) */ - 3343, /* BBF8 (48120) */ - 3343, /* BBF9 (48121) */ - 3343, /* BBFA (48122) */ - 3343, /* BBFB (48123) */ - 3343, /* BBFC (48124) */ - 3343, /* BBFD (48125) */ - 3343, /* BBFE (48126) */ - 3343, /* BBFF (48127) */ - 3343, /* BC00 (48128) */ - 3343, /* BC01 (48129) */ - 3343, /* BC02 (48130) */ - 3343, /* BC03 (48131) */ - 3343, /* BC04 (48132) */ - 3343, /* BC05 (48133) */ - 3343, /* BC06 (48134) */ - 3343, /* BC07 (48135) */ - 3343, /* BC08 (48136) */ - 3343, /* BC09 (48137) */ - 3343, /* BC0A (48138) */ - 3343, /* BC0B (48139) */ - 3343, /* BC0C (48140) */ - 3343, /* BC0D (48141) */ - 3343, /* BC0E (48142) */ - 3343, /* BC0F (48143) */ - 3343, /* BC10 (48144) */ - 3343, /* BC11 (48145) */ - 3343, /* BC12 (48146) */ - 3343, /* BC13 (48147) */ - 3343, /* BC14 (48148) */ - 3343, /* BC15 (48149) */ - 3343, /* BC16 (48150) */ - 3343, /* BC17 (48151) */ - 3343, /* BC18 (48152) */ - 3343, /* BC19 (48153) */ - 3343, /* BC1A (48154) */ - 3343, /* BC1B (48155) */ - 3343, /* BC1C (48156) */ - 3343, /* BC1D (48157) */ - 3343, /* BC1E (48158) */ - 3343, /* BC1F (48159) */ - 3343, /* BC20 (48160) */ - 3343, /* BC21 (48161) */ - 3343, /* BC22 (48162) */ - 3343, /* BC23 (48163) */ - 3343, /* BC24 (48164) */ - 3343, /* BC25 (48165) */ - 3343, /* BC26 (48166) */ - 3343, /* BC27 (48167) */ - 3343, /* BC28 (48168) */ - 3343, /* BC29 (48169) */ - 3343, /* BC2A (48170) */ - 3343, /* BC2B (48171) */ - 3343, /* BC2C (48172) */ - 3343, /* BC2D (48173) */ - 3343, /* BC2E (48174) */ - 3343, /* BC2F (48175) */ - 3343, /* BC30 (48176) */ - 3343, /* BC31 (48177) */ - 3343, /* BC32 (48178) */ - 3343, /* BC33 (48179) */ - 3343, /* BC34 (48180) */ - 3343, /* BC35 (48181) */ - 3343, /* BC36 (48182) */ - 3343, /* BC37 (48183) */ - 3343, /* BC38 (48184) */ - 3343, /* BC39 (48185) */ - 3343, /* BC3A (48186) */ - 3343, /* BC3B (48187) */ - 3343, /* BC3C (48188) */ - 3343, /* BC3D (48189) */ - 3343, /* BC3E (48190) */ - 3343, /* BC3F (48191) */ - 3343, /* BC40 (48192) */ - 3343, /* BC41 (48193) */ - 3343, /* BC42 (48194) */ - 3343, /* BC43 (48195) */ - 3343, /* BC44 (48196) */ - 3343, /* BC45 (48197) */ - 3343, /* BC46 (48198) */ - 3343, /* BC47 (48199) */ - 3343, /* BC48 (48200) */ - 3343, /* BC49 (48201) */ - 3343, /* BC4A (48202) */ - 3343, /* BC4B (48203) */ - 3343, /* BC4C (48204) */ - 3343, /* BC4D (48205) */ - 3343, /* BC4E (48206) */ - 3343, /* BC4F (48207) */ - 3343, /* BC50 (48208) */ - 3343, /* BC51 (48209) */ - 3343, /* BC52 (48210) */ - 3343, /* BC53 (48211) */ - 3343, /* BC54 (48212) */ - 3343, /* BC55 (48213) */ - 3343, /* BC56 (48214) */ - 3343, /* BC57 (48215) */ - 3343, /* BC58 (48216) */ - 3343, /* BC59 (48217) */ - 3343, /* BC5A (48218) */ - 3343, /* BC5B (48219) */ - 3343, /* BC5C (48220) */ - 3343, /* BC5D (48221) */ - 3343, /* BC5E (48222) */ - 3343, /* BC5F (48223) */ - 3343, /* BC60 (48224) */ - 3343, /* BC61 (48225) */ - 3343, /* BC62 (48226) */ - 3343, /* BC63 (48227) */ - 3343, /* BC64 (48228) */ - 3343, /* BC65 (48229) */ - 3343, /* BC66 (48230) */ - 3343, /* BC67 (48231) */ - 3343, /* BC68 (48232) */ - 3343, /* BC69 (48233) */ - 3343, /* BC6A (48234) */ - 3343, /* BC6B (48235) */ - 3343, /* BC6C (48236) */ - 3343, /* BC6D (48237) */ - 3343, /* BC6E (48238) */ - 3343, /* BC6F (48239) */ - 3343, /* BC70 (48240) */ - 3343, /* BC71 (48241) */ - 3343, /* BC72 (48242) */ - 3343, /* BC73 (48243) */ - 3343, /* BC74 (48244) */ - 3343, /* BC75 (48245) */ - 3343, /* BC76 (48246) */ - 3343, /* BC77 (48247) */ - 3343, /* BC78 (48248) */ - 3343, /* BC79 (48249) */ - 3343, /* BC7A (48250) */ - 3343, /* BC7B (48251) */ - 3343, /* BC7C (48252) */ - 3343, /* BC7D (48253) */ - 3343, /* BC7E (48254) */ - 3343, /* BC7F (48255) */ - 3343, /* BC80 (48256) */ - 3343, /* BC81 (48257) */ - 3343, /* BC82 (48258) */ - 3343, /* BC83 (48259) */ - 3343, /* BC84 (48260) */ - 3343, /* BC85 (48261) */ - 3343, /* BC86 (48262) */ - 3343, /* BC87 (48263) */ - 3343, /* BC88 (48264) */ - 3343, /* BC89 (48265) */ - 3343, /* BC8A (48266) */ - 3343, /* BC8B (48267) */ - 3343, /* BC8C (48268) */ - 3343, /* BC8D (48269) */ - 3343, /* BC8E (48270) */ - 3343, /* BC8F (48271) */ - 3343, /* BC90 (48272) */ - 3343, /* BC91 (48273) */ - 3343, /* BC92 (48274) */ - 3343, /* BC93 (48275) */ - 3343, /* BC94 (48276) */ - 3343, /* BC95 (48277) */ - 3343, /* BC96 (48278) */ - 3343, /* BC97 (48279) */ - 3343, /* BC98 (48280) */ - 3343, /* BC99 (48281) */ - 3343, /* BC9A (48282) */ - 3343, /* BC9B (48283) */ - 3343, /* BC9C (48284) */ - 3343, /* BC9D (48285) */ - 3343, /* BC9E (48286) */ - 3343, /* BC9F (48287) */ - 3343, /* BCA0 (48288) */ - 3343, /* BCA1 (48289) */ - 3343, /* BCA2 (48290) */ - 3343, /* BCA3 (48291) */ - 3343, /* BCA4 (48292) */ - 3343, /* BCA5 (48293) */ - 3343, /* BCA6 (48294) */ - 3343, /* BCA7 (48295) */ - 3343, /* BCA8 (48296) */ - 3343, /* BCA9 (48297) */ - 3343, /* BCAA (48298) */ - 3343, /* BCAB (48299) */ - 3343, /* BCAC (48300) */ - 3343, /* BCAD (48301) */ - 3343, /* BCAE (48302) */ - 3343, /* BCAF (48303) */ - 3343, /* BCB0 (48304) */ - 3343, /* BCB1 (48305) */ - 3343, /* BCB2 (48306) */ - 3343, /* BCB3 (48307) */ - 3343, /* BCB4 (48308) */ - 3343, /* BCB5 (48309) */ - 3343, /* BCB6 (48310) */ - 3343, /* BCB7 (48311) */ - 3343, /* BCB8 (48312) */ - 3343, /* BCB9 (48313) */ - 3343, /* BCBA (48314) */ - 3343, /* BCBB (48315) */ - 3343, /* BCBC (48316) */ - 3343, /* BCBD (48317) */ - 3343, /* BCBE (48318) */ - 3343, /* BCBF (48319) */ - 3343, /* BCC0 (48320) */ - 3343, /* BCC1 (48321) */ - 3343, /* BCC2 (48322) */ - 3343, /* BCC3 (48323) */ - 3343, /* BCC4 (48324) */ - 3343, /* BCC5 (48325) */ - 3343, /* BCC6 (48326) */ - 3343, /* BCC7 (48327) */ - 3343, /* BCC8 (48328) */ - 3343, /* BCC9 (48329) */ - 3343, /* BCCA (48330) */ - 3343, /* BCCB (48331) */ - 3343, /* BCCC (48332) */ - 3343, /* BCCD (48333) */ - 3343, /* BCCE (48334) */ - 3343, /* BCCF (48335) */ - 3343, /* BCD0 (48336) */ - 3343, /* BCD1 (48337) */ - 3343, /* BCD2 (48338) */ - 3343, /* BCD3 (48339) */ - 3343, /* BCD4 (48340) */ - 3343, /* BCD5 (48341) */ - 3343, /* BCD6 (48342) */ - 3343, /* BCD7 (48343) */ - 3343, /* BCD8 (48344) */ - 3343, /* BCD9 (48345) */ - 3343, /* BCDA (48346) */ - 3343, /* BCDB (48347) */ - 3343, /* BCDC (48348) */ - 3343, /* BCDD (48349) */ - 3343, /* BCDE (48350) */ - 3343, /* BCDF (48351) */ - 3343, /* BCE0 (48352) */ - 3343, /* BCE1 (48353) */ - 3343, /* BCE2 (48354) */ - 3343, /* BCE3 (48355) */ - 3343, /* BCE4 (48356) */ - 3343, /* BCE5 (48357) */ - 3343, /* BCE6 (48358) */ - 3343, /* BCE7 (48359) */ - 3343, /* BCE8 (48360) */ - 3343, /* BCE9 (48361) */ - 3343, /* BCEA (48362) */ - 3343, /* BCEB (48363) */ - 3343, /* BCEC (48364) */ - 3343, /* BCED (48365) */ - 3343, /* BCEE (48366) */ - 3343, /* BCEF (48367) */ - 3343, /* BCF0 (48368) */ - 3343, /* BCF1 (48369) */ - 3343, /* BCF2 (48370) */ - 3343, /* BCF3 (48371) */ - 3343, /* BCF4 (48372) */ - 3343, /* BCF5 (48373) */ - 3343, /* BCF6 (48374) */ - 3343, /* BCF7 (48375) */ - 3343, /* BCF8 (48376) */ - 3343, /* BCF9 (48377) */ - 3343, /* BCFA (48378) */ - 3343, /* BCFB (48379) */ - 3343, /* BCFC (48380) */ - 3343, /* BCFD (48381) */ - 3343, /* BCFE (48382) */ - 3343, /* BCFF (48383) */ - 3343, /* BD00 (48384) */ - 3343, /* BD01 (48385) */ - 3343, /* BD02 (48386) */ - 3343, /* BD03 (48387) */ - 3343, /* BD04 (48388) */ - 3343, /* BD05 (48389) */ - 3343, /* BD06 (48390) */ - 3343, /* BD07 (48391) */ - 3343, /* BD08 (48392) */ - 3343, /* BD09 (48393) */ - 3343, /* BD0A (48394) */ - 3343, /* BD0B (48395) */ - 3343, /* BD0C (48396) */ - 3343, /* BD0D (48397) */ - 3343, /* BD0E (48398) */ - 3343, /* BD0F (48399) */ - 3343, /* BD10 (48400) */ - 3343, /* BD11 (48401) */ - 3343, /* BD12 (48402) */ - 3343, /* BD13 (48403) */ - 3343, /* BD14 (48404) */ - 3343, /* BD15 (48405) */ - 3343, /* BD16 (48406) */ - 3343, /* BD17 (48407) */ - 3343, /* BD18 (48408) */ - 3343, /* BD19 (48409) */ - 3343, /* BD1A (48410) */ - 3343, /* BD1B (48411) */ - 3343, /* BD1C (48412) */ - 3343, /* BD1D (48413) */ - 3343, /* BD1E (48414) */ - 3343, /* BD1F (48415) */ - 3343, /* BD20 (48416) */ - 3343, /* BD21 (48417) */ - 3343, /* BD22 (48418) */ - 3343, /* BD23 (48419) */ - 3343, /* BD24 (48420) */ - 3343, /* BD25 (48421) */ - 3343, /* BD26 (48422) */ - 3343, /* BD27 (48423) */ - 3343, /* BD28 (48424) */ - 3343, /* BD29 (48425) */ - 3343, /* BD2A (48426) */ - 3343, /* BD2B (48427) */ - 3343, /* BD2C (48428) */ - 3343, /* BD2D (48429) */ - 3343, /* BD2E (48430) */ - 3343, /* BD2F (48431) */ - 3343, /* BD30 (48432) */ - 3343, /* BD31 (48433) */ - 3343, /* BD32 (48434) */ - 3343, /* BD33 (48435) */ - 3343, /* BD34 (48436) */ - 3343, /* BD35 (48437) */ - 3343, /* BD36 (48438) */ - 3343, /* BD37 (48439) */ - 3343, /* BD38 (48440) */ - 3343, /* BD39 (48441) */ - 3343, /* BD3A (48442) */ - 3343, /* BD3B (48443) */ - 3343, /* BD3C (48444) */ - 3343, /* BD3D (48445) */ - 3343, /* BD3E (48446) */ - 3343, /* BD3F (48447) */ - 3343, /* BD40 (48448) */ - 3343, /* BD41 (48449) */ - 3343, /* BD42 (48450) */ - 3343, /* BD43 (48451) */ - 3343, /* BD44 (48452) */ - 3343, /* BD45 (48453) */ - 3343, /* BD46 (48454) */ - 3343, /* BD47 (48455) */ - 3343, /* BD48 (48456) */ - 3343, /* BD49 (48457) */ - 3343, /* BD4A (48458) */ - 3343, /* BD4B (48459) */ - 3343, /* BD4C (48460) */ - 3343, /* BD4D (48461) */ - 3343, /* BD4E (48462) */ - 3343, /* BD4F (48463) */ - 3343, /* BD50 (48464) */ - 3343, /* BD51 (48465) */ - 3343, /* BD52 (48466) */ - 3343, /* BD53 (48467) */ - 3343, /* BD54 (48468) */ - 3343, /* BD55 (48469) */ - 3343, /* BD56 (48470) */ - 3343, /* BD57 (48471) */ - 3343, /* BD58 (48472) */ - 3343, /* BD59 (48473) */ - 3343, /* BD5A (48474) */ - 3343, /* BD5B (48475) */ - 3343, /* BD5C (48476) */ - 3343, /* BD5D (48477) */ - 3343, /* BD5E (48478) */ - 3343, /* BD5F (48479) */ - 3343, /* BD60 (48480) */ - 3343, /* BD61 (48481) */ - 3343, /* BD62 (48482) */ - 3343, /* BD63 (48483) */ - 3343, /* BD64 (48484) */ - 3343, /* BD65 (48485) */ - 3343, /* BD66 (48486) */ - 3343, /* BD67 (48487) */ - 3343, /* BD68 (48488) */ - 3343, /* BD69 (48489) */ - 3343, /* BD6A (48490) */ - 3343, /* BD6B (48491) */ - 3343, /* BD6C (48492) */ - 3343, /* BD6D (48493) */ - 3343, /* BD6E (48494) */ - 3343, /* BD6F (48495) */ - 3343, /* BD70 (48496) */ - 3343, /* BD71 (48497) */ - 3343, /* BD72 (48498) */ - 3343, /* BD73 (48499) */ - 3343, /* BD74 (48500) */ - 3343, /* BD75 (48501) */ - 3343, /* BD76 (48502) */ - 3343, /* BD77 (48503) */ - 3343, /* BD78 (48504) */ - 3343, /* BD79 (48505) */ - 3343, /* BD7A (48506) */ - 3343, /* BD7B (48507) */ - 3343, /* BD7C (48508) */ - 3343, /* BD7D (48509) */ - 3343, /* BD7E (48510) */ - 3343, /* BD7F (48511) */ - 3343, /* BD80 (48512) */ - 3343, /* BD81 (48513) */ - 3343, /* BD82 (48514) */ - 3343, /* BD83 (48515) */ - 3343, /* BD84 (48516) */ - 3343, /* BD85 (48517) */ - 3343, /* BD86 (48518) */ - 3343, /* BD87 (48519) */ - 3343, /* BD88 (48520) */ - 3343, /* BD89 (48521) */ - 3343, /* BD8A (48522) */ - 3343, /* BD8B (48523) */ - 3343, /* BD8C (48524) */ - 3343, /* BD8D (48525) */ - 3343, /* BD8E (48526) */ - 3343, /* BD8F (48527) */ - 3343, /* BD90 (48528) */ - 3343, /* BD91 (48529) */ - 3343, /* BD92 (48530) */ - 3343, /* BD93 (48531) */ - 3343, /* BD94 (48532) */ - 3343, /* BD95 (48533) */ - 3343, /* BD96 (48534) */ - 3343, /* BD97 (48535) */ - 3343, /* BD98 (48536) */ - 3343, /* BD99 (48537) */ - 3343, /* BD9A (48538) */ - 3343, /* BD9B (48539) */ - 3343, /* BD9C (48540) */ - 3343, /* BD9D (48541) */ - 3343, /* BD9E (48542) */ - 3343, /* BD9F (48543) */ - 3343, /* BDA0 (48544) */ - 3343, /* BDA1 (48545) */ - 3343, /* BDA2 (48546) */ - 3343, /* BDA3 (48547) */ - 3343, /* BDA4 (48548) */ - 3343, /* BDA5 (48549) */ - 3343, /* BDA6 (48550) */ - 3343, /* BDA7 (48551) */ - 3343, /* BDA8 (48552) */ - 3343, /* BDA9 (48553) */ - 3343, /* BDAA (48554) */ - 3343, /* BDAB (48555) */ - 3343, /* BDAC (48556) */ - 3343, /* BDAD (48557) */ - 3343, /* BDAE (48558) */ - 3343, /* BDAF (48559) */ - 3343, /* BDB0 (48560) */ - 3343, /* BDB1 (48561) */ - 3343, /* BDB2 (48562) */ - 3343, /* BDB3 (48563) */ - 3343, /* BDB4 (48564) */ - 3343, /* BDB5 (48565) */ - 3343, /* BDB6 (48566) */ - 3343, /* BDB7 (48567) */ - 3343, /* BDB8 (48568) */ - 3343, /* BDB9 (48569) */ - 3343, /* BDBA (48570) */ - 3343, /* BDBB (48571) */ - 3343, /* BDBC (48572) */ - 3343, /* BDBD (48573) */ - 3343, /* BDBE (48574) */ - 3343, /* BDBF (48575) */ - 3343, /* BDC0 (48576) */ - 3343, /* BDC1 (48577) */ - 3343, /* BDC2 (48578) */ - 3343, /* BDC3 (48579) */ - 3343, /* BDC4 (48580) */ - 3343, /* BDC5 (48581) */ - 3343, /* BDC6 (48582) */ - 3343, /* BDC7 (48583) */ - 3343, /* BDC8 (48584) */ - 3343, /* BDC9 (48585) */ - 3343, /* BDCA (48586) */ - 3343, /* BDCB (48587) */ - 3343, /* BDCC (48588) */ - 3343, /* BDCD (48589) */ - 3343, /* BDCE (48590) */ - 3343, /* BDCF (48591) */ - 3343, /* BDD0 (48592) */ - 3343, /* BDD1 (48593) */ - 3343, /* BDD2 (48594) */ - 3343, /* BDD3 (48595) */ - 3343, /* BDD4 (48596) */ - 3343, /* BDD5 (48597) */ - 3343, /* BDD6 (48598) */ - 3343, /* BDD7 (48599) */ - 3343, /* BDD8 (48600) */ - 3343, /* BDD9 (48601) */ - 3343, /* BDDA (48602) */ - 3343, /* BDDB (48603) */ - 3343, /* BDDC (48604) */ - 3343, /* BDDD (48605) */ - 3343, /* BDDE (48606) */ - 3343, /* BDDF (48607) */ - 3343, /* BDE0 (48608) */ - 3343, /* BDE1 (48609) */ - 3343, /* BDE2 (48610) */ - 3343, /* BDE3 (48611) */ - 3343, /* BDE4 (48612) */ - 3343, /* BDE5 (48613) */ - 3343, /* BDE6 (48614) */ - 3343, /* BDE7 (48615) */ - 3343, /* BDE8 (48616) */ - 3343, /* BDE9 (48617) */ - 3343, /* BDEA (48618) */ - 3343, /* BDEB (48619) */ - 3343, /* BDEC (48620) */ - 3343, /* BDED (48621) */ - 3343, /* BDEE (48622) */ - 3343, /* BDEF (48623) */ - 3343, /* BDF0 (48624) */ - 3343, /* BDF1 (48625) */ - 3343, /* BDF2 (48626) */ - 3343, /* BDF3 (48627) */ - 3343, /* BDF4 (48628) */ - 3343, /* BDF5 (48629) */ - 3343, /* BDF6 (48630) */ - 3343, /* BDF7 (48631) */ - 3343, /* BDF8 (48632) */ - 3343, /* BDF9 (48633) */ - 3343, /* BDFA (48634) */ - 3343, /* BDFB (48635) */ - 3343, /* BDFC (48636) */ - 3343, /* BDFD (48637) */ - 3343, /* BDFE (48638) */ - 3343, /* BDFF (48639) */ - 3343, /* BE00 (48640) */ - 3343, /* BE01 (48641) */ - 3343, /* BE02 (48642) */ - 3343, /* BE03 (48643) */ - 3343, /* BE04 (48644) */ - 3343, /* BE05 (48645) */ - 3343, /* BE06 (48646) */ - 3343, /* BE07 (48647) */ - 3343, /* BE08 (48648) */ - 3343, /* BE09 (48649) */ - 3343, /* BE0A (48650) */ - 3343, /* BE0B (48651) */ - 3343, /* BE0C (48652) */ - 3343, /* BE0D (48653) */ - 3343, /* BE0E (48654) */ - 3343, /* BE0F (48655) */ - 3343, /* BE10 (48656) */ - 3343, /* BE11 (48657) */ - 3343, /* BE12 (48658) */ - 3343, /* BE13 (48659) */ - 3343, /* BE14 (48660) */ - 3343, /* BE15 (48661) */ - 3343, /* BE16 (48662) */ - 3343, /* BE17 (48663) */ - 3343, /* BE18 (48664) */ - 3343, /* BE19 (48665) */ - 3343, /* BE1A (48666) */ - 3343, /* BE1B (48667) */ - 3343, /* BE1C (48668) */ - 3343, /* BE1D (48669) */ - 3343, /* BE1E (48670) */ - 3343, /* BE1F (48671) */ - 3343, /* BE20 (48672) */ - 3343, /* BE21 (48673) */ - 3343, /* BE22 (48674) */ - 3343, /* BE23 (48675) */ - 3343, /* BE24 (48676) */ - 3343, /* BE25 (48677) */ - 3343, /* BE26 (48678) */ - 3343, /* BE27 (48679) */ - 3343, /* BE28 (48680) */ - 3343, /* BE29 (48681) */ - 3343, /* BE2A (48682) */ - 3343, /* BE2B (48683) */ - 3343, /* BE2C (48684) */ - 3343, /* BE2D (48685) */ - 3343, /* BE2E (48686) */ - 3343, /* BE2F (48687) */ - 3343, /* BE30 (48688) */ - 3343, /* BE31 (48689) */ - 3343, /* BE32 (48690) */ - 3343, /* BE33 (48691) */ - 3343, /* BE34 (48692) */ - 3343, /* BE35 (48693) */ - 3343, /* BE36 (48694) */ - 3343, /* BE37 (48695) */ - 3343, /* BE38 (48696) */ - 3343, /* BE39 (48697) */ - 3343, /* BE3A (48698) */ - 3343, /* BE3B (48699) */ - 3343, /* BE3C (48700) */ - 3343, /* BE3D (48701) */ - 3343, /* BE3E (48702) */ - 3343, /* BE3F (48703) */ - 3343, /* BE40 (48704) */ - 3343, /* BE41 (48705) */ - 3343, /* BE42 (48706) */ - 3343, /* BE43 (48707) */ - 3343, /* BE44 (48708) */ - 3343, /* BE45 (48709) */ - 3343, /* BE46 (48710) */ - 3343, /* BE47 (48711) */ - 3343, /* BE48 (48712) */ - 3343, /* BE49 (48713) */ - 3343, /* BE4A (48714) */ - 3343, /* BE4B (48715) */ - 3343, /* BE4C (48716) */ - 3343, /* BE4D (48717) */ - 3343, /* BE4E (48718) */ - 3343, /* BE4F (48719) */ - 3343, /* BE50 (48720) */ - 3343, /* BE51 (48721) */ - 3343, /* BE52 (48722) */ - 3343, /* BE53 (48723) */ - 3343, /* BE54 (48724) */ - 3343, /* BE55 (48725) */ - 3343, /* BE56 (48726) */ - 3343, /* BE57 (48727) */ - 3343, /* BE58 (48728) */ - 3343, /* BE59 (48729) */ - 3343, /* BE5A (48730) */ - 3343, /* BE5B (48731) */ - 3343, /* BE5C (48732) */ - 3343, /* BE5D (48733) */ - 3343, /* BE5E (48734) */ - 3343, /* BE5F (48735) */ - 3343, /* BE60 (48736) */ - 3343, /* BE61 (48737) */ - 3343, /* BE62 (48738) */ - 3343, /* BE63 (48739) */ - 3343, /* BE64 (48740) */ - 3343, /* BE65 (48741) */ - 3343, /* BE66 (48742) */ - 3343, /* BE67 (48743) */ - 3343, /* BE68 (48744) */ - 3343, /* BE69 (48745) */ - 3343, /* BE6A (48746) */ - 3343, /* BE6B (48747) */ - 3343, /* BE6C (48748) */ - 3343, /* BE6D (48749) */ - 3343, /* BE6E (48750) */ - 3343, /* BE6F (48751) */ - 3343, /* BE70 (48752) */ - 3343, /* BE71 (48753) */ - 3343, /* BE72 (48754) */ - 3343, /* BE73 (48755) */ - 3343, /* BE74 (48756) */ - 3343, /* BE75 (48757) */ - 3343, /* BE76 (48758) */ - 3343, /* BE77 (48759) */ - 3343, /* BE78 (48760) */ - 3343, /* BE79 (48761) */ - 3343, /* BE7A (48762) */ - 3343, /* BE7B (48763) */ - 3343, /* BE7C (48764) */ - 3343, /* BE7D (48765) */ - 3343, /* BE7E (48766) */ - 3343, /* BE7F (48767) */ - 3343, /* BE80 (48768) */ - 3343, /* BE81 (48769) */ - 3343, /* BE82 (48770) */ - 3343, /* BE83 (48771) */ - 3343, /* BE84 (48772) */ - 3343, /* BE85 (48773) */ - 3343, /* BE86 (48774) */ - 3343, /* BE87 (48775) */ - 3343, /* BE88 (48776) */ - 3343, /* BE89 (48777) */ - 3343, /* BE8A (48778) */ - 3343, /* BE8B (48779) */ - 3343, /* BE8C (48780) */ - 3343, /* BE8D (48781) */ - 3343, /* BE8E (48782) */ - 3343, /* BE8F (48783) */ - 3343, /* BE90 (48784) */ - 3343, /* BE91 (48785) */ - 3343, /* BE92 (48786) */ - 3343, /* BE93 (48787) */ - 3343, /* BE94 (48788) */ - 3343, /* BE95 (48789) */ - 3343, /* BE96 (48790) */ - 3343, /* BE97 (48791) */ - 3343, /* BE98 (48792) */ - 3343, /* BE99 (48793) */ - 3343, /* BE9A (48794) */ - 3343, /* BE9B (48795) */ - 3343, /* BE9C (48796) */ - 3343, /* BE9D (48797) */ - 3343, /* BE9E (48798) */ - 3343, /* BE9F (48799) */ - 3343, /* BEA0 (48800) */ - 3343, /* BEA1 (48801) */ - 3343, /* BEA2 (48802) */ - 3343, /* BEA3 (48803) */ - 3343, /* BEA4 (48804) */ - 3343, /* BEA5 (48805) */ - 3343, /* BEA6 (48806) */ - 3343, /* BEA7 (48807) */ - 3343, /* BEA8 (48808) */ - 3343, /* BEA9 (48809) */ - 3343, /* BEAA (48810) */ - 3343, /* BEAB (48811) */ - 3343, /* BEAC (48812) */ - 3343, /* BEAD (48813) */ - 3343, /* BEAE (48814) */ - 3343, /* BEAF (48815) */ - 3343, /* BEB0 (48816) */ - 3343, /* BEB1 (48817) */ - 3343, /* BEB2 (48818) */ - 3343, /* BEB3 (48819) */ - 3343, /* BEB4 (48820) */ - 3343, /* BEB5 (48821) */ - 3343, /* BEB6 (48822) */ - 3343, /* BEB7 (48823) */ - 3343, /* BEB8 (48824) */ - 3343, /* BEB9 (48825) */ - 3343, /* BEBA (48826) */ - 3343, /* BEBB (48827) */ - 3343, /* BEBC (48828) */ - 3343, /* BEBD (48829) */ - 3343, /* BEBE (48830) */ - 3343, /* BEBF (48831) */ - 3343, /* BEC0 (48832) */ - 3343, /* BEC1 (48833) */ - 3343, /* BEC2 (48834) */ - 3343, /* BEC3 (48835) */ - 3343, /* BEC4 (48836) */ - 3343, /* BEC5 (48837) */ - 3343, /* BEC6 (48838) */ - 3343, /* BEC7 (48839) */ - 3343, /* BEC8 (48840) */ - 3343, /* BEC9 (48841) */ - 3343, /* BECA (48842) */ - 3343, /* BECB (48843) */ - 3343, /* BECC (48844) */ - 3343, /* BECD (48845) */ - 3343, /* BECE (48846) */ - 3343, /* BECF (48847) */ - 3343, /* BED0 (48848) */ - 3343, /* BED1 (48849) */ - 3343, /* BED2 (48850) */ - 3343, /* BED3 (48851) */ - 3343, /* BED4 (48852) */ - 3343, /* BED5 (48853) */ - 3343, /* BED6 (48854) */ - 3343, /* BED7 (48855) */ - 3343, /* BED8 (48856) */ - 3343, /* BED9 (48857) */ - 3343, /* BEDA (48858) */ - 3343, /* BEDB (48859) */ - 3343, /* BEDC (48860) */ - 3343, /* BEDD (48861) */ - 3343, /* BEDE (48862) */ - 3343, /* BEDF (48863) */ - 3343, /* BEE0 (48864) */ - 3343, /* BEE1 (48865) */ - 3343, /* BEE2 (48866) */ - 3343, /* BEE3 (48867) */ - 3343, /* BEE4 (48868) */ - 3343, /* BEE5 (48869) */ - 3343, /* BEE6 (48870) */ - 3343, /* BEE7 (48871) */ - 3343, /* BEE8 (48872) */ - 3343, /* BEE9 (48873) */ - 3343, /* BEEA (48874) */ - 3343, /* BEEB (48875) */ - 3343, /* BEEC (48876) */ - 3343, /* BEED (48877) */ - 3343, /* BEEE (48878) */ - 3343, /* BEEF (48879) */ - 3343, /* BEF0 (48880) */ - 3343, /* BEF1 (48881) */ - 3343, /* BEF2 (48882) */ - 3343, /* BEF3 (48883) */ - 3343, /* BEF4 (48884) */ - 3343, /* BEF5 (48885) */ - 3343, /* BEF6 (48886) */ - 3343, /* BEF7 (48887) */ - 3343, /* BEF8 (48888) */ - 3343, /* BEF9 (48889) */ - 3343, /* BEFA (48890) */ - 3343, /* BEFB (48891) */ - 3343, /* BEFC (48892) */ - 3343, /* BEFD (48893) */ - 3343, /* BEFE (48894) */ - 3343, /* BEFF (48895) */ - 3343, /* BF00 (48896) */ - 3343, /* BF01 (48897) */ - 3343, /* BF02 (48898) */ - 3343, /* BF03 (48899) */ - 3343, /* BF04 (48900) */ - 3343, /* BF05 (48901) */ - 3343, /* BF06 (48902) */ - 3343, /* BF07 (48903) */ - 3343, /* BF08 (48904) */ - 3343, /* BF09 (48905) */ - 3343, /* BF0A (48906) */ - 3343, /* BF0B (48907) */ - 3343, /* BF0C (48908) */ - 3343, /* BF0D (48909) */ - 3343, /* BF0E (48910) */ - 3343, /* BF0F (48911) */ - 3343, /* BF10 (48912) */ - 3343, /* BF11 (48913) */ - 3343, /* BF12 (48914) */ - 3343, /* BF13 (48915) */ - 3343, /* BF14 (48916) */ - 3343, /* BF15 (48917) */ - 3343, /* BF16 (48918) */ - 3343, /* BF17 (48919) */ - 3343, /* BF18 (48920) */ - 3343, /* BF19 (48921) */ - 3343, /* BF1A (48922) */ - 3343, /* BF1B (48923) */ - 3343, /* BF1C (48924) */ - 3343, /* BF1D (48925) */ - 3343, /* BF1E (48926) */ - 3343, /* BF1F (48927) */ - 3343, /* BF20 (48928) */ - 3343, /* BF21 (48929) */ - 3343, /* BF22 (48930) */ - 3343, /* BF23 (48931) */ - 3343, /* BF24 (48932) */ - 3343, /* BF25 (48933) */ - 3343, /* BF26 (48934) */ - 3343, /* BF27 (48935) */ - 3343, /* BF28 (48936) */ - 3343, /* BF29 (48937) */ - 3343, /* BF2A (48938) */ - 3343, /* BF2B (48939) */ - 3343, /* BF2C (48940) */ - 3343, /* BF2D (48941) */ - 3343, /* BF2E (48942) */ - 3343, /* BF2F (48943) */ - 3343, /* BF30 (48944) */ - 3343, /* BF31 (48945) */ - 3343, /* BF32 (48946) */ - 3343, /* BF33 (48947) */ - 3343, /* BF34 (48948) */ - 3343, /* BF35 (48949) */ - 3343, /* BF36 (48950) */ - 3343, /* BF37 (48951) */ - 3343, /* BF38 (48952) */ - 3343, /* BF39 (48953) */ - 3343, /* BF3A (48954) */ - 3343, /* BF3B (48955) */ - 3343, /* BF3C (48956) */ - 3343, /* BF3D (48957) */ - 3343, /* BF3E (48958) */ - 3343, /* BF3F (48959) */ - 3343, /* BF40 (48960) */ - 3343, /* BF41 (48961) */ - 3343, /* BF42 (48962) */ - 3343, /* BF43 (48963) */ - 3343, /* BF44 (48964) */ - 3343, /* BF45 (48965) */ - 3343, /* BF46 (48966) */ - 3343, /* BF47 (48967) */ - 3343, /* BF48 (48968) */ - 3343, /* BF49 (48969) */ - 3343, /* BF4A (48970) */ - 3343, /* BF4B (48971) */ - 3343, /* BF4C (48972) */ - 3343, /* BF4D (48973) */ - 3343, /* BF4E (48974) */ - 3343, /* BF4F (48975) */ - 3343, /* BF50 (48976) */ - 3343, /* BF51 (48977) */ - 3343, /* BF52 (48978) */ - 3343, /* BF53 (48979) */ - 3343, /* BF54 (48980) */ - 3343, /* BF55 (48981) */ - 3343, /* BF56 (48982) */ - 3343, /* BF57 (48983) */ - 3343, /* BF58 (48984) */ - 3343, /* BF59 (48985) */ - 3343, /* BF5A (48986) */ - 3343, /* BF5B (48987) */ - 3343, /* BF5C (48988) */ - 3343, /* BF5D (48989) */ - 3343, /* BF5E (48990) */ - 3343, /* BF5F (48991) */ - 3343, /* BF60 (48992) */ - 3343, /* BF61 (48993) */ - 3343, /* BF62 (48994) */ - 3343, /* BF63 (48995) */ - 3343, /* BF64 (48996) */ - 3343, /* BF65 (48997) */ - 3343, /* BF66 (48998) */ - 3343, /* BF67 (48999) */ - 3343, /* BF68 (49000) */ - 3343, /* BF69 (49001) */ - 3343, /* BF6A (49002) */ - 3343, /* BF6B (49003) */ - 3343, /* BF6C (49004) */ - 3343, /* BF6D (49005) */ - 3343, /* BF6E (49006) */ - 3343, /* BF6F (49007) */ - 3343, /* BF70 (49008) */ - 3343, /* BF71 (49009) */ - 3343, /* BF72 (49010) */ - 3343, /* BF73 (49011) */ - 3343, /* BF74 (49012) */ - 3343, /* BF75 (49013) */ - 3343, /* BF76 (49014) */ - 3343, /* BF77 (49015) */ - 3343, /* BF78 (49016) */ - 3343, /* BF79 (49017) */ - 3343, /* BF7A (49018) */ - 3343, /* BF7B (49019) */ - 3343, /* BF7C (49020) */ - 3343, /* BF7D (49021) */ - 3343, /* BF7E (49022) */ - 3343, /* BF7F (49023) */ - 3343, /* BF80 (49024) */ - 3343, /* BF81 (49025) */ - 3343, /* BF82 (49026) */ - 3343, /* BF83 (49027) */ - 3343, /* BF84 (49028) */ - 3343, /* BF85 (49029) */ - 3343, /* BF86 (49030) */ - 3343, /* BF87 (49031) */ - 3343, /* BF88 (49032) */ - 3343, /* BF89 (49033) */ - 3343, /* BF8A (49034) */ - 3343, /* BF8B (49035) */ - 3343, /* BF8C (49036) */ - 3343, /* BF8D (49037) */ - 3343, /* BF8E (49038) */ - 3343, /* BF8F (49039) */ - 3343, /* BF90 (49040) */ - 3343, /* BF91 (49041) */ - 3343, /* BF92 (49042) */ - 3343, /* BF93 (49043) */ - 3343, /* BF94 (49044) */ - 3343, /* BF95 (49045) */ - 3343, /* BF96 (49046) */ - 3343, /* BF97 (49047) */ - 3343, /* BF98 (49048) */ - 3343, /* BF99 (49049) */ - 3343, /* BF9A (49050) */ - 3343, /* BF9B (49051) */ - 3343, /* BF9C (49052) */ - 3343, /* BF9D (49053) */ - 3343, /* BF9E (49054) */ - 3343, /* BF9F (49055) */ - 3343, /* BFA0 (49056) */ - 3343, /* BFA1 (49057) */ - 3343, /* BFA2 (49058) */ - 3343, /* BFA3 (49059) */ - 3343, /* BFA4 (49060) */ - 3343, /* BFA5 (49061) */ - 3343, /* BFA6 (49062) */ - 3343, /* BFA7 (49063) */ - 3343, /* BFA8 (49064) */ - 3343, /* BFA9 (49065) */ - 3343, /* BFAA (49066) */ - 3343, /* BFAB (49067) */ - 3343, /* BFAC (49068) */ - 3343, /* BFAD (49069) */ - 3343, /* BFAE (49070) */ - 3343, /* BFAF (49071) */ - 3343, /* BFB0 (49072) */ - 3343, /* BFB1 (49073) */ - 3343, /* BFB2 (49074) */ - 3343, /* BFB3 (49075) */ - 3343, /* BFB4 (49076) */ - 3343, /* BFB5 (49077) */ - 3343, /* BFB6 (49078) */ - 3343, /* BFB7 (49079) */ - 3343, /* BFB8 (49080) */ - 3343, /* BFB9 (49081) */ - 3343, /* BFBA (49082) */ - 3343, /* BFBB (49083) */ - 3343, /* BFBC (49084) */ - 3343, /* BFBD (49085) */ - 3343, /* BFBE (49086) */ - 3343, /* BFBF (49087) */ - 3343, /* BFC0 (49088) */ - 3343, /* BFC1 (49089) */ - 3343, /* BFC2 (49090) */ - 3343, /* BFC3 (49091) */ - 3343, /* BFC4 (49092) */ - 3343, /* BFC5 (49093) */ - 3343, /* BFC6 (49094) */ - 3343, /* BFC7 (49095) */ - 3343, /* BFC8 (49096) */ - 3343, /* BFC9 (49097) */ - 3343, /* BFCA (49098) */ - 3343, /* BFCB (49099) */ - 3343, /* BFCC (49100) */ - 3343, /* BFCD (49101) */ - 3343, /* BFCE (49102) */ - 3343, /* BFCF (49103) */ - 3343, /* BFD0 (49104) */ - 3343, /* BFD1 (49105) */ - 3343, /* BFD2 (49106) */ - 3343, /* BFD3 (49107) */ - 3343, /* BFD4 (49108) */ - 3343, /* BFD5 (49109) */ - 3343, /* BFD6 (49110) */ - 3343, /* BFD7 (49111) */ - 3343, /* BFD8 (49112) */ - 3343, /* BFD9 (49113) */ - 3343, /* BFDA (49114) */ - 3343, /* BFDB (49115) */ - 3343, /* BFDC (49116) */ - 3343, /* BFDD (49117) */ - 3343, /* BFDE (49118) */ - 3343, /* BFDF (49119) */ - 3343, /* BFE0 (49120) */ - 3343, /* BFE1 (49121) */ - 3343, /* BFE2 (49122) */ - 3343, /* BFE3 (49123) */ - 3343, /* BFE4 (49124) */ - 3343, /* BFE5 (49125) */ - 3343, /* BFE6 (49126) */ - 3343, /* BFE7 (49127) */ - 3343, /* BFE8 (49128) */ - 3343, /* BFE9 (49129) */ - 3343, /* BFEA (49130) */ - 3343, /* BFEB (49131) */ - 3343, /* BFEC (49132) */ - 3343, /* BFED (49133) */ - 3343, /* BFEE (49134) */ - 3343, /* BFEF (49135) */ - 3343, /* BFF0 (49136) */ - 3343, /* BFF1 (49137) */ - 3343, /* BFF2 (49138) */ - 3343, /* BFF3 (49139) */ - 3343, /* BFF4 (49140) */ - 3343, /* BFF5 (49141) */ - 3343, /* BFF6 (49142) */ - 3343, /* BFF7 (49143) */ - 3343, /* BFF8 (49144) */ - 3343, /* BFF9 (49145) */ - 3343, /* BFFA (49146) */ - 3343, /* BFFB (49147) */ - 3343, /* BFFC (49148) */ - 3343, /* BFFD (49149) */ - 3343, /* BFFE (49150) */ - 3343, /* BFFF (49151) */ - 3343, /* C000 (49152) */ - 3343, /* C001 (49153) */ - 3343, /* C002 (49154) */ - 3343, /* C003 (49155) */ - 3343, /* C004 (49156) */ - 3343, /* C005 (49157) */ - 3343, /* C006 (49158) */ - 3343, /* C007 (49159) */ - 3343, /* C008 (49160) */ - 3343, /* C009 (49161) */ - 3343, /* C00A (49162) */ - 3343, /* C00B (49163) */ - 3343, /* C00C (49164) */ - 3343, /* C00D (49165) */ - 3343, /* C00E (49166) */ - 3343, /* C00F (49167) */ - 3343, /* C010 (49168) */ - 3343, /* C011 (49169) */ - 3343, /* C012 (49170) */ - 3343, /* C013 (49171) */ - 3343, /* C014 (49172) */ - 3343, /* C015 (49173) */ - 3343, /* C016 (49174) */ - 3343, /* C017 (49175) */ - 3343, /* C018 (49176) */ - 3343, /* C019 (49177) */ - 3343, /* C01A (49178) */ - 3343, /* C01B (49179) */ - 3343, /* C01C (49180) */ - 3343, /* C01D (49181) */ - 3343, /* C01E (49182) */ - 3343, /* C01F (49183) */ - 3343, /* C020 (49184) */ - 3343, /* C021 (49185) */ - 3343, /* C022 (49186) */ - 3343, /* C023 (49187) */ - 3343, /* C024 (49188) */ - 3343, /* C025 (49189) */ - 3343, /* C026 (49190) */ - 3343, /* C027 (49191) */ - 3343, /* C028 (49192) */ - 3343, /* C029 (49193) */ - 3343, /* C02A (49194) */ - 3343, /* C02B (49195) */ - 3343, /* C02C (49196) */ - 3343, /* C02D (49197) */ - 3343, /* C02E (49198) */ - 3343, /* C02F (49199) */ - 3343, /* C030 (49200) */ - 3343, /* C031 (49201) */ - 3343, /* C032 (49202) */ - 3343, /* C033 (49203) */ - 3343, /* C034 (49204) */ - 3343, /* C035 (49205) */ - 3343, /* C036 (49206) */ - 3343, /* C037 (49207) */ - 3343, /* C038 (49208) */ - 3343, /* C039 (49209) */ - 3343, /* C03A (49210) */ - 3343, /* C03B (49211) */ - 3343, /* C03C (49212) */ - 3343, /* C03D (49213) */ - 3343, /* C03E (49214) */ - 3343, /* C03F (49215) */ - 3343, /* C040 (49216) */ - 3343, /* C041 (49217) */ - 3343, /* C042 (49218) */ - 3343, /* C043 (49219) */ - 3343, /* C044 (49220) */ - 3343, /* C045 (49221) */ - 3343, /* C046 (49222) */ - 3343, /* C047 (49223) */ - 3343, /* C048 (49224) */ - 3343, /* C049 (49225) */ - 3343, /* C04A (49226) */ - 3343, /* C04B (49227) */ - 3343, /* C04C (49228) */ - 3343, /* C04D (49229) */ - 3343, /* C04E (49230) */ - 3343, /* C04F (49231) */ - 3343, /* C050 (49232) */ - 3343, /* C051 (49233) */ - 3343, /* C052 (49234) */ - 3343, /* C053 (49235) */ - 3343, /* C054 (49236) */ - 3343, /* C055 (49237) */ - 3343, /* C056 (49238) */ - 3343, /* C057 (49239) */ - 3343, /* C058 (49240) */ - 3343, /* C059 (49241) */ - 3343, /* C05A (49242) */ - 3343, /* C05B (49243) */ - 3343, /* C05C (49244) */ - 3343, /* C05D (49245) */ - 3343, /* C05E (49246) */ - 3343, /* C05F (49247) */ - 3343, /* C060 (49248) */ - 3343, /* C061 (49249) */ - 3343, /* C062 (49250) */ - 3343, /* C063 (49251) */ - 3343, /* C064 (49252) */ - 3343, /* C065 (49253) */ - 3343, /* C066 (49254) */ - 3343, /* C067 (49255) */ - 3343, /* C068 (49256) */ - 3343, /* C069 (49257) */ - 3343, /* C06A (49258) */ - 3343, /* C06B (49259) */ - 3343, /* C06C (49260) */ - 3343, /* C06D (49261) */ - 3343, /* C06E (49262) */ - 3343, /* C06F (49263) */ - 3343, /* C070 (49264) */ - 3343, /* C071 (49265) */ - 3343, /* C072 (49266) */ - 3343, /* C073 (49267) */ - 3343, /* C074 (49268) */ - 3343, /* C075 (49269) */ - 3343, /* C076 (49270) */ - 3343, /* C077 (49271) */ - 3343, /* C078 (49272) */ - 3343, /* C079 (49273) */ - 3343, /* C07A (49274) */ - 3343, /* C07B (49275) */ - 3343, /* C07C (49276) */ - 3343, /* C07D (49277) */ - 3343, /* C07E (49278) */ - 3343, /* C07F (49279) */ - 3343, /* C080 (49280) */ - 3343, /* C081 (49281) */ - 3343, /* C082 (49282) */ - 3343, /* C083 (49283) */ - 3343, /* C084 (49284) */ - 3343, /* C085 (49285) */ - 3343, /* C086 (49286) */ - 3343, /* C087 (49287) */ - 3343, /* C088 (49288) */ - 3343, /* C089 (49289) */ - 3343, /* C08A (49290) */ - 3343, /* C08B (49291) */ - 3343, /* C08C (49292) */ - 3343, /* C08D (49293) */ - 3343, /* C08E (49294) */ - 3343, /* C08F (49295) */ - 3343, /* C090 (49296) */ - 3343, /* C091 (49297) */ - 3343, /* C092 (49298) */ - 3343, /* C093 (49299) */ - 3343, /* C094 (49300) */ - 3343, /* C095 (49301) */ - 3343, /* C096 (49302) */ - 3343, /* C097 (49303) */ - 3343, /* C098 (49304) */ - 3343, /* C099 (49305) */ - 3343, /* C09A (49306) */ - 3343, /* C09B (49307) */ - 3343, /* C09C (49308) */ - 3343, /* C09D (49309) */ - 3343, /* C09E (49310) */ - 3343, /* C09F (49311) */ - 3343, /* C0A0 (49312) */ - 3343, /* C0A1 (49313) */ - 3343, /* C0A2 (49314) */ - 3343, /* C0A3 (49315) */ - 3343, /* C0A4 (49316) */ - 3343, /* C0A5 (49317) */ - 3343, /* C0A6 (49318) */ - 3343, /* C0A7 (49319) */ - 3343, /* C0A8 (49320) */ - 3343, /* C0A9 (49321) */ - 3343, /* C0AA (49322) */ - 3343, /* C0AB (49323) */ - 3343, /* C0AC (49324) */ - 3343, /* C0AD (49325) */ - 3343, /* C0AE (49326) */ - 3343, /* C0AF (49327) */ - 3343, /* C0B0 (49328) */ - 3343, /* C0B1 (49329) */ - 3343, /* C0B2 (49330) */ - 3343, /* C0B3 (49331) */ - 3343, /* C0B4 (49332) */ - 3343, /* C0B5 (49333) */ - 3343, /* C0B6 (49334) */ - 3343, /* C0B7 (49335) */ - 3343, /* C0B8 (49336) */ - 3343, /* C0B9 (49337) */ - 3343, /* C0BA (49338) */ - 3343, /* C0BB (49339) */ - 3343, /* C0BC (49340) */ - 3343, /* C0BD (49341) */ - 3343, /* C0BE (49342) */ - 3343, /* C0BF (49343) */ - 3343, /* C0C0 (49344) */ - 3343, /* C0C1 (49345) */ - 3343, /* C0C2 (49346) */ - 3343, /* C0C3 (49347) */ - 3343, /* C0C4 (49348) */ - 3343, /* C0C5 (49349) */ - 3343, /* C0C6 (49350) */ - 3343, /* C0C7 (49351) */ - 3343, /* C0C8 (49352) */ - 3343, /* C0C9 (49353) */ - 3343, /* C0CA (49354) */ - 3343, /* C0CB (49355) */ - 3343, /* C0CC (49356) */ - 3343, /* C0CD (49357) */ - 3343, /* C0CE (49358) */ - 3343, /* C0CF (49359) */ - 3343, /* C0D0 (49360) */ - 3343, /* C0D1 (49361) */ - 3343, /* C0D2 (49362) */ - 3343, /* C0D3 (49363) */ - 3343, /* C0D4 (49364) */ - 3343, /* C0D5 (49365) */ - 3343, /* C0D6 (49366) */ - 3343, /* C0D7 (49367) */ - 3343, /* C0D8 (49368) */ - 3343, /* C0D9 (49369) */ - 3343, /* C0DA (49370) */ - 3343, /* C0DB (49371) */ - 3343, /* C0DC (49372) */ - 3343, /* C0DD (49373) */ - 3343, /* C0DE (49374) */ - 3343, /* C0DF (49375) */ - 3343, /* C0E0 (49376) */ - 3343, /* C0E1 (49377) */ - 3343, /* C0E2 (49378) */ - 3343, /* C0E3 (49379) */ - 3343, /* C0E4 (49380) */ - 3343, /* C0E5 (49381) */ - 3343, /* C0E6 (49382) */ - 3343, /* C0E7 (49383) */ - 3343, /* C0E8 (49384) */ - 3343, /* C0E9 (49385) */ - 3343, /* C0EA (49386) */ - 3343, /* C0EB (49387) */ - 3343, /* C0EC (49388) */ - 3343, /* C0ED (49389) */ - 3343, /* C0EE (49390) */ - 3343, /* C0EF (49391) */ - 3343, /* C0F0 (49392) */ - 3343, /* C0F1 (49393) */ - 3343, /* C0F2 (49394) */ - 3343, /* C0F3 (49395) */ - 3343, /* C0F4 (49396) */ - 3343, /* C0F5 (49397) */ - 3343, /* C0F6 (49398) */ - 3343, /* C0F7 (49399) */ - 3343, /* C0F8 (49400) */ - 3343, /* C0F9 (49401) */ - 3343, /* C0FA (49402) */ - 3343, /* C0FB (49403) */ - 3343, /* C0FC (49404) */ - 3343, /* C0FD (49405) */ - 3343, /* C0FE (49406) */ - 3343, /* C0FF (49407) */ - 3343, /* C100 (49408) */ - 3343, /* C101 (49409) */ - 3343, /* C102 (49410) */ - 3343, /* C103 (49411) */ - 3343, /* C104 (49412) */ - 3343, /* C105 (49413) */ - 3343, /* C106 (49414) */ - 3343, /* C107 (49415) */ - 3343, /* C108 (49416) */ - 3343, /* C109 (49417) */ - 3343, /* C10A (49418) */ - 3343, /* C10B (49419) */ - 3343, /* C10C (49420) */ - 3343, /* C10D (49421) */ - 3343, /* C10E (49422) */ - 3343, /* C10F (49423) */ - 3343, /* C110 (49424) */ - 3343, /* C111 (49425) */ - 3343, /* C112 (49426) */ - 3343, /* C113 (49427) */ - 3343, /* C114 (49428) */ - 3343, /* C115 (49429) */ - 3343, /* C116 (49430) */ - 3343, /* C117 (49431) */ - 3343, /* C118 (49432) */ - 3343, /* C119 (49433) */ - 3343, /* C11A (49434) */ - 3343, /* C11B (49435) */ - 3343, /* C11C (49436) */ - 3343, /* C11D (49437) */ - 3343, /* C11E (49438) */ - 3343, /* C11F (49439) */ - 3343, /* C120 (49440) */ - 3343, /* C121 (49441) */ - 3343, /* C122 (49442) */ - 3343, /* C123 (49443) */ - 3343, /* C124 (49444) */ - 3343, /* C125 (49445) */ - 3343, /* C126 (49446) */ - 3343, /* C127 (49447) */ - 3343, /* C128 (49448) */ - 3343, /* C129 (49449) */ - 3343, /* C12A (49450) */ - 3343, /* C12B (49451) */ - 3343, /* C12C (49452) */ - 3343, /* C12D (49453) */ - 3343, /* C12E (49454) */ - 3343, /* C12F (49455) */ - 3343, /* C130 (49456) */ - 3343, /* C131 (49457) */ - 3343, /* C132 (49458) */ - 3343, /* C133 (49459) */ - 3343, /* C134 (49460) */ - 3343, /* C135 (49461) */ - 3343, /* C136 (49462) */ - 3343, /* C137 (49463) */ - 3343, /* C138 (49464) */ - 3343, /* C139 (49465) */ - 3343, /* C13A (49466) */ - 3343, /* C13B (49467) */ - 3343, /* C13C (49468) */ - 3343, /* C13D (49469) */ - 3343, /* C13E (49470) */ - 3343, /* C13F (49471) */ - 3343, /* C140 (49472) */ - 3343, /* C141 (49473) */ - 3343, /* C142 (49474) */ - 3343, /* C143 (49475) */ - 3343, /* C144 (49476) */ - 3343, /* C145 (49477) */ - 3343, /* C146 (49478) */ - 3343, /* C147 (49479) */ - 3343, /* C148 (49480) */ - 3343, /* C149 (49481) */ - 3343, /* C14A (49482) */ - 3343, /* C14B (49483) */ - 3343, /* C14C (49484) */ - 3343, /* C14D (49485) */ - 3343, /* C14E (49486) */ - 3343, /* C14F (49487) */ - 3343, /* C150 (49488) */ - 3343, /* C151 (49489) */ - 3343, /* C152 (49490) */ - 3343, /* C153 (49491) */ - 3343, /* C154 (49492) */ - 3343, /* C155 (49493) */ - 3343, /* C156 (49494) */ - 3343, /* C157 (49495) */ - 3343, /* C158 (49496) */ - 3343, /* C159 (49497) */ - 3343, /* C15A (49498) */ - 3343, /* C15B (49499) */ - 3343, /* C15C (49500) */ - 3343, /* C15D (49501) */ - 3343, /* C15E (49502) */ - 3343, /* C15F (49503) */ - 3343, /* C160 (49504) */ - 3343, /* C161 (49505) */ - 3343, /* C162 (49506) */ - 3343, /* C163 (49507) */ - 3343, /* C164 (49508) */ - 3343, /* C165 (49509) */ - 3343, /* C166 (49510) */ - 3343, /* C167 (49511) */ - 3343, /* C168 (49512) */ - 3343, /* C169 (49513) */ - 3343, /* C16A (49514) */ - 3343, /* C16B (49515) */ - 3343, /* C16C (49516) */ - 3343, /* C16D (49517) */ - 3343, /* C16E (49518) */ - 3343, /* C16F (49519) */ - 3343, /* C170 (49520) */ - 3343, /* C171 (49521) */ - 3343, /* C172 (49522) */ - 3343, /* C173 (49523) */ - 3343, /* C174 (49524) */ - 3343, /* C175 (49525) */ - 3343, /* C176 (49526) */ - 3343, /* C177 (49527) */ - 3343, /* C178 (49528) */ - 3343, /* C179 (49529) */ - 3343, /* C17A (49530) */ - 3343, /* C17B (49531) */ - 3343, /* C17C (49532) */ - 3343, /* C17D (49533) */ - 3343, /* C17E (49534) */ - 3343, /* C17F (49535) */ - 3343, /* C180 (49536) */ - 3343, /* C181 (49537) */ - 3343, /* C182 (49538) */ - 3343, /* C183 (49539) */ - 3343, /* C184 (49540) */ - 3343, /* C185 (49541) */ - 3343, /* C186 (49542) */ - 3343, /* C187 (49543) */ - 3343, /* C188 (49544) */ - 3343, /* C189 (49545) */ - 3343, /* C18A (49546) */ - 3343, /* C18B (49547) */ - 3343, /* C18C (49548) */ - 3343, /* C18D (49549) */ - 3343, /* C18E (49550) */ - 3343, /* C18F (49551) */ - 3343, /* C190 (49552) */ - 3343, /* C191 (49553) */ - 3343, /* C192 (49554) */ - 3343, /* C193 (49555) */ - 3343, /* C194 (49556) */ - 3343, /* C195 (49557) */ - 3343, /* C196 (49558) */ - 3343, /* C197 (49559) */ - 3343, /* C198 (49560) */ - 3343, /* C199 (49561) */ - 3343, /* C19A (49562) */ - 3343, /* C19B (49563) */ - 3343, /* C19C (49564) */ - 3343, /* C19D (49565) */ - 3343, /* C19E (49566) */ - 3343, /* C19F (49567) */ - 3343, /* C1A0 (49568) */ - 3343, /* C1A1 (49569) */ - 3343, /* C1A2 (49570) */ - 3343, /* C1A3 (49571) */ - 3343, /* C1A4 (49572) */ - 3343, /* C1A5 (49573) */ - 3343, /* C1A6 (49574) */ - 3343, /* C1A7 (49575) */ - 3343, /* C1A8 (49576) */ - 3343, /* C1A9 (49577) */ - 3343, /* C1AA (49578) */ - 3343, /* C1AB (49579) */ - 3343, /* C1AC (49580) */ - 3343, /* C1AD (49581) */ - 3343, /* C1AE (49582) */ - 3343, /* C1AF (49583) */ - 3343, /* C1B0 (49584) */ - 3343, /* C1B1 (49585) */ - 3343, /* C1B2 (49586) */ - 3343, /* C1B3 (49587) */ - 3343, /* C1B4 (49588) */ - 3343, /* C1B5 (49589) */ - 3343, /* C1B6 (49590) */ - 3343, /* C1B7 (49591) */ - 3343, /* C1B8 (49592) */ - 3343, /* C1B9 (49593) */ - 3343, /* C1BA (49594) */ - 3343, /* C1BB (49595) */ - 3343, /* C1BC (49596) */ - 3343, /* C1BD (49597) */ - 3343, /* C1BE (49598) */ - 3343, /* C1BF (49599) */ - 3343, /* C1C0 (49600) */ - 3343, /* C1C1 (49601) */ - 3343, /* C1C2 (49602) */ - 3343, /* C1C3 (49603) */ - 3343, /* C1C4 (49604) */ - 3343, /* C1C5 (49605) */ - 3343, /* C1C6 (49606) */ - 3343, /* C1C7 (49607) */ - 3343, /* C1C8 (49608) */ - 3343, /* C1C9 (49609) */ - 3343, /* C1CA (49610) */ - 3343, /* C1CB (49611) */ - 3343, /* C1CC (49612) */ - 3343, /* C1CD (49613) */ - 3343, /* C1CE (49614) */ - 3343, /* C1CF (49615) */ - 3343, /* C1D0 (49616) */ - 3343, /* C1D1 (49617) */ - 3343, /* C1D2 (49618) */ - 3343, /* C1D3 (49619) */ - 3343, /* C1D4 (49620) */ - 3343, /* C1D5 (49621) */ - 3343, /* C1D6 (49622) */ - 3343, /* C1D7 (49623) */ - 3343, /* C1D8 (49624) */ - 3343, /* C1D9 (49625) */ - 3343, /* C1DA (49626) */ - 3343, /* C1DB (49627) */ - 3343, /* C1DC (49628) */ - 3343, /* C1DD (49629) */ - 3343, /* C1DE (49630) */ - 3343, /* C1DF (49631) */ - 3343, /* C1E0 (49632) */ - 3343, /* C1E1 (49633) */ - 3343, /* C1E2 (49634) */ - 3343, /* C1E3 (49635) */ - 3343, /* C1E4 (49636) */ - 3343, /* C1E5 (49637) */ - 3343, /* C1E6 (49638) */ - 3343, /* C1E7 (49639) */ - 3343, /* C1E8 (49640) */ - 3343, /* C1E9 (49641) */ - 3343, /* C1EA (49642) */ - 3343, /* C1EB (49643) */ - 3343, /* C1EC (49644) */ - 3343, /* C1ED (49645) */ - 3343, /* C1EE (49646) */ - 3343, /* C1EF (49647) */ - 3343, /* C1F0 (49648) */ - 3343, /* C1F1 (49649) */ - 3343, /* C1F2 (49650) */ - 3343, /* C1F3 (49651) */ - 3343, /* C1F4 (49652) */ - 3343, /* C1F5 (49653) */ - 3343, /* C1F6 (49654) */ - 3343, /* C1F7 (49655) */ - 3343, /* C1F8 (49656) */ - 3343, /* C1F9 (49657) */ - 3343, /* C1FA (49658) */ - 3343, /* C1FB (49659) */ - 3343, /* C1FC (49660) */ - 3343, /* C1FD (49661) */ - 3343, /* C1FE (49662) */ - 3343, /* C1FF (49663) */ - 3343, /* C200 (49664) */ - 3343, /* C201 (49665) */ - 3343, /* C202 (49666) */ - 3343, /* C203 (49667) */ - 3343, /* C204 (49668) */ - 3343, /* C205 (49669) */ - 3343, /* C206 (49670) */ - 3343, /* C207 (49671) */ - 3343, /* C208 (49672) */ - 3343, /* C209 (49673) */ - 3343, /* C20A (49674) */ - 3343, /* C20B (49675) */ - 3343, /* C20C (49676) */ - 3343, /* C20D (49677) */ - 3343, /* C20E (49678) */ - 3343, /* C20F (49679) */ - 3343, /* C210 (49680) */ - 3343, /* C211 (49681) */ - 3343, /* C212 (49682) */ - 3343, /* C213 (49683) */ - 3343, /* C214 (49684) */ - 3343, /* C215 (49685) */ - 3343, /* C216 (49686) */ - 3343, /* C217 (49687) */ - 3343, /* C218 (49688) */ - 3343, /* C219 (49689) */ - 3343, /* C21A (49690) */ - 3343, /* C21B (49691) */ - 3343, /* C21C (49692) */ - 3343, /* C21D (49693) */ - 3343, /* C21E (49694) */ - 3343, /* C21F (49695) */ - 3343, /* C220 (49696) */ - 3343, /* C221 (49697) */ - 3343, /* C222 (49698) */ - 3343, /* C223 (49699) */ - 3343, /* C224 (49700) */ - 3343, /* C225 (49701) */ - 3343, /* C226 (49702) */ - 3343, /* C227 (49703) */ - 3343, /* C228 (49704) */ - 3343, /* C229 (49705) */ - 3343, /* C22A (49706) */ - 3343, /* C22B (49707) */ - 3343, /* C22C (49708) */ - 3343, /* C22D (49709) */ - 3343, /* C22E (49710) */ - 3343, /* C22F (49711) */ - 3343, /* C230 (49712) */ - 3343, /* C231 (49713) */ - 3343, /* C232 (49714) */ - 3343, /* C233 (49715) */ - 3343, /* C234 (49716) */ - 3343, /* C235 (49717) */ - 3343, /* C236 (49718) */ - 3343, /* C237 (49719) */ - 3343, /* C238 (49720) */ - 3343, /* C239 (49721) */ - 3343, /* C23A (49722) */ - 3343, /* C23B (49723) */ - 3343, /* C23C (49724) */ - 3343, /* C23D (49725) */ - 3343, /* C23E (49726) */ - 3343, /* C23F (49727) */ - 3343, /* C240 (49728) */ - 3343, /* C241 (49729) */ - 3343, /* C242 (49730) */ - 3343, /* C243 (49731) */ - 3343, /* C244 (49732) */ - 3343, /* C245 (49733) */ - 3343, /* C246 (49734) */ - 3343, /* C247 (49735) */ - 3343, /* C248 (49736) */ - 3343, /* C249 (49737) */ - 3343, /* C24A (49738) */ - 3343, /* C24B (49739) */ - 3343, /* C24C (49740) */ - 3343, /* C24D (49741) */ - 3343, /* C24E (49742) */ - 3343, /* C24F (49743) */ - 3343, /* C250 (49744) */ - 3343, /* C251 (49745) */ - 3343, /* C252 (49746) */ - 3343, /* C253 (49747) */ - 3343, /* C254 (49748) */ - 3343, /* C255 (49749) */ - 3343, /* C256 (49750) */ - 3343, /* C257 (49751) */ - 3343, /* C258 (49752) */ - 3343, /* C259 (49753) */ - 3343, /* C25A (49754) */ - 3343, /* C25B (49755) */ - 3343, /* C25C (49756) */ - 3343, /* C25D (49757) */ - 3343, /* C25E (49758) */ - 3343, /* C25F (49759) */ - 3343, /* C260 (49760) */ - 3343, /* C261 (49761) */ - 3343, /* C262 (49762) */ - 3343, /* C263 (49763) */ - 3343, /* C264 (49764) */ - 3343, /* C265 (49765) */ - 3343, /* C266 (49766) */ - 3343, /* C267 (49767) */ - 3343, /* C268 (49768) */ - 3343, /* C269 (49769) */ - 3343, /* C26A (49770) */ - 3343, /* C26B (49771) */ - 3343, /* C26C (49772) */ - 3343, /* C26D (49773) */ - 3343, /* C26E (49774) */ - 3343, /* C26F (49775) */ - 3343, /* C270 (49776) */ - 3343, /* C271 (49777) */ - 3343, /* C272 (49778) */ - 3343, /* C273 (49779) */ - 3343, /* C274 (49780) */ - 3343, /* C275 (49781) */ - 3343, /* C276 (49782) */ - 3343, /* C277 (49783) */ - 3343, /* C278 (49784) */ - 3343, /* C279 (49785) */ - 3343, /* C27A (49786) */ - 3343, /* C27B (49787) */ - 3343, /* C27C (49788) */ - 3343, /* C27D (49789) */ - 3343, /* C27E (49790) */ - 3343, /* C27F (49791) */ - 3343, /* C280 (49792) */ - 3343, /* C281 (49793) */ - 3343, /* C282 (49794) */ - 3343, /* C283 (49795) */ - 3343, /* C284 (49796) */ - 3343, /* C285 (49797) */ - 3343, /* C286 (49798) */ - 3343, /* C287 (49799) */ - 3343, /* C288 (49800) */ - 3343, /* C289 (49801) */ - 3343, /* C28A (49802) */ - 3343, /* C28B (49803) */ - 3343, /* C28C (49804) */ - 3343, /* C28D (49805) */ - 3343, /* C28E (49806) */ - 3343, /* C28F (49807) */ - 3343, /* C290 (49808) */ - 3343, /* C291 (49809) */ - 3343, /* C292 (49810) */ - 3343, /* C293 (49811) */ - 3343, /* C294 (49812) */ - 3343, /* C295 (49813) */ - 3343, /* C296 (49814) */ - 3343, /* C297 (49815) */ - 3343, /* C298 (49816) */ - 3343, /* C299 (49817) */ - 3343, /* C29A (49818) */ - 3343, /* C29B (49819) */ - 3343, /* C29C (49820) */ - 3343, /* C29D (49821) */ - 3343, /* C29E (49822) */ - 3343, /* C29F (49823) */ - 3343, /* C2A0 (49824) */ - 3343, /* C2A1 (49825) */ - 3343, /* C2A2 (49826) */ - 3343, /* C2A3 (49827) */ - 3343, /* C2A4 (49828) */ - 3343, /* C2A5 (49829) */ - 3343, /* C2A6 (49830) */ - 3343, /* C2A7 (49831) */ - 3343, /* C2A8 (49832) */ - 3343, /* C2A9 (49833) */ - 3343, /* C2AA (49834) */ - 3343, /* C2AB (49835) */ - 3343, /* C2AC (49836) */ - 3343, /* C2AD (49837) */ - 3343, /* C2AE (49838) */ - 3343, /* C2AF (49839) */ - 3343, /* C2B0 (49840) */ - 3343, /* C2B1 (49841) */ - 3343, /* C2B2 (49842) */ - 3343, /* C2B3 (49843) */ - 3343, /* C2B4 (49844) */ - 3343, /* C2B5 (49845) */ - 3343, /* C2B6 (49846) */ - 3343, /* C2B7 (49847) */ - 3343, /* C2B8 (49848) */ - 3343, /* C2B9 (49849) */ - 3343, /* C2BA (49850) */ - 3343, /* C2BB (49851) */ - 3343, /* C2BC (49852) */ - 3343, /* C2BD (49853) */ - 3343, /* C2BE (49854) */ - 3343, /* C2BF (49855) */ - 3343, /* C2C0 (49856) */ - 3343, /* C2C1 (49857) */ - 3343, /* C2C2 (49858) */ - 3343, /* C2C3 (49859) */ - 3343, /* C2C4 (49860) */ - 3343, /* C2C5 (49861) */ - 3343, /* C2C6 (49862) */ - 3343, /* C2C7 (49863) */ - 3343, /* C2C8 (49864) */ - 3343, /* C2C9 (49865) */ - 3343, /* C2CA (49866) */ - 3343, /* C2CB (49867) */ - 3343, /* C2CC (49868) */ - 3343, /* C2CD (49869) */ - 3343, /* C2CE (49870) */ - 3343, /* C2CF (49871) */ - 3343, /* C2D0 (49872) */ - 3343, /* C2D1 (49873) */ - 3343, /* C2D2 (49874) */ - 3343, /* C2D3 (49875) */ - 3343, /* C2D4 (49876) */ - 3343, /* C2D5 (49877) */ - 3343, /* C2D6 (49878) */ - 3343, /* C2D7 (49879) */ - 3343, /* C2D8 (49880) */ - 3343, /* C2D9 (49881) */ - 3343, /* C2DA (49882) */ - 3343, /* C2DB (49883) */ - 3343, /* C2DC (49884) */ - 3343, /* C2DD (49885) */ - 3343, /* C2DE (49886) */ - 3343, /* C2DF (49887) */ - 3343, /* C2E0 (49888) */ - 3343, /* C2E1 (49889) */ - 3343, /* C2E2 (49890) */ - 3343, /* C2E3 (49891) */ - 3343, /* C2E4 (49892) */ - 3343, /* C2E5 (49893) */ - 3343, /* C2E6 (49894) */ - 3343, /* C2E7 (49895) */ - 3343, /* C2E8 (49896) */ - 3343, /* C2E9 (49897) */ - 3343, /* C2EA (49898) */ - 3343, /* C2EB (49899) */ - 3343, /* C2EC (49900) */ - 3343, /* C2ED (49901) */ - 3343, /* C2EE (49902) */ - 3343, /* C2EF (49903) */ - 3343, /* C2F0 (49904) */ - 3343, /* C2F1 (49905) */ - 3343, /* C2F2 (49906) */ - 3343, /* C2F3 (49907) */ - 3343, /* C2F4 (49908) */ - 3343, /* C2F5 (49909) */ - 3343, /* C2F6 (49910) */ - 3343, /* C2F7 (49911) */ - 3343, /* C2F8 (49912) */ - 3343, /* C2F9 (49913) */ - 3343, /* C2FA (49914) */ - 3343, /* C2FB (49915) */ - 3343, /* C2FC (49916) */ - 3343, /* C2FD (49917) */ - 3343, /* C2FE (49918) */ - 3343, /* C2FF (49919) */ - 3343, /* C300 (49920) */ - 3343, /* C301 (49921) */ - 3343, /* C302 (49922) */ - 3343, /* C303 (49923) */ - 3343, /* C304 (49924) */ - 3343, /* C305 (49925) */ - 3343, /* C306 (49926) */ - 3343, /* C307 (49927) */ - 3343, /* C308 (49928) */ - 3343, /* C309 (49929) */ - 3343, /* C30A (49930) */ - 3343, /* C30B (49931) */ - 3343, /* C30C (49932) */ - 3343, /* C30D (49933) */ - 3343, /* C30E (49934) */ - 3343, /* C30F (49935) */ - 3343, /* C310 (49936) */ - 3343, /* C311 (49937) */ - 3343, /* C312 (49938) */ - 3343, /* C313 (49939) */ - 3343, /* C314 (49940) */ - 3343, /* C315 (49941) */ - 3343, /* C316 (49942) */ - 3343, /* C317 (49943) */ - 3343, /* C318 (49944) */ - 3343, /* C319 (49945) */ - 3343, /* C31A (49946) */ - 3343, /* C31B (49947) */ - 3343, /* C31C (49948) */ - 3343, /* C31D (49949) */ - 3343, /* C31E (49950) */ - 3343, /* C31F (49951) */ - 3343, /* C320 (49952) */ - 3343, /* C321 (49953) */ - 3343, /* C322 (49954) */ - 3343, /* C323 (49955) */ - 3343, /* C324 (49956) */ - 3343, /* C325 (49957) */ - 3343, /* C326 (49958) */ - 3343, /* C327 (49959) */ - 3343, /* C328 (49960) */ - 3343, /* C329 (49961) */ - 3343, /* C32A (49962) */ - 3343, /* C32B (49963) */ - 3343, /* C32C (49964) */ - 3343, /* C32D (49965) */ - 3343, /* C32E (49966) */ - 3343, /* C32F (49967) */ - 3343, /* C330 (49968) */ - 3343, /* C331 (49969) */ - 3343, /* C332 (49970) */ - 3343, /* C333 (49971) */ - 3343, /* C334 (49972) */ - 3343, /* C335 (49973) */ - 3343, /* C336 (49974) */ - 3343, /* C337 (49975) */ - 3343, /* C338 (49976) */ - 3343, /* C339 (49977) */ - 3343, /* C33A (49978) */ - 3343, /* C33B (49979) */ - 3343, /* C33C (49980) */ - 3343, /* C33D (49981) */ - 3343, /* C33E (49982) */ - 3343, /* C33F (49983) */ - 3343, /* C340 (49984) */ - 3343, /* C341 (49985) */ - 3343, /* C342 (49986) */ - 3343, /* C343 (49987) */ - 3343, /* C344 (49988) */ - 3343, /* C345 (49989) */ - 3343, /* C346 (49990) */ - 3343, /* C347 (49991) */ - 3343, /* C348 (49992) */ - 3343, /* C349 (49993) */ - 3343, /* C34A (49994) */ - 3343, /* C34B (49995) */ - 3343, /* C34C (49996) */ - 3343, /* C34D (49997) */ - 3343, /* C34E (49998) */ - 3343, /* C34F (49999) */ - 3343, /* C350 (50000) */ - 3343, /* C351 (50001) */ - 3343, /* C352 (50002) */ - 3343, /* C353 (50003) */ - 3343, /* C354 (50004) */ - 3343, /* C355 (50005) */ - 3343, /* C356 (50006) */ - 3343, /* C357 (50007) */ - 3343, /* C358 (50008) */ - 3343, /* C359 (50009) */ - 3343, /* C35A (50010) */ - 3343, /* C35B (50011) */ - 3343, /* C35C (50012) */ - 3343, /* C35D (50013) */ - 3343, /* C35E (50014) */ - 3343, /* C35F (50015) */ - 3343, /* C360 (50016) */ - 3343, /* C361 (50017) */ - 3343, /* C362 (50018) */ - 3343, /* C363 (50019) */ - 3343, /* C364 (50020) */ - 3343, /* C365 (50021) */ - 3343, /* C366 (50022) */ - 3343, /* C367 (50023) */ - 3343, /* C368 (50024) */ - 3343, /* C369 (50025) */ - 3343, /* C36A (50026) */ - 3343, /* C36B (50027) */ - 3343, /* C36C (50028) */ - 3343, /* C36D (50029) */ - 3343, /* C36E (50030) */ - 3343, /* C36F (50031) */ - 3343, /* C370 (50032) */ - 3343, /* C371 (50033) */ - 3343, /* C372 (50034) */ - 3343, /* C373 (50035) */ - 3343, /* C374 (50036) */ - 3343, /* C375 (50037) */ - 3343, /* C376 (50038) */ - 3343, /* C377 (50039) */ - 3343, /* C378 (50040) */ - 3343, /* C379 (50041) */ - 3343, /* C37A (50042) */ - 3343, /* C37B (50043) */ - 3343, /* C37C (50044) */ - 3343, /* C37D (50045) */ - 3343, /* C37E (50046) */ - 3343, /* C37F (50047) */ - 3343, /* C380 (50048) */ - 3343, /* C381 (50049) */ - 3343, /* C382 (50050) */ - 3343, /* C383 (50051) */ - 3343, /* C384 (50052) */ - 3343, /* C385 (50053) */ - 3343, /* C386 (50054) */ - 3343, /* C387 (50055) */ - 3343, /* C388 (50056) */ - 3343, /* C389 (50057) */ - 3343, /* C38A (50058) */ - 3343, /* C38B (50059) */ - 3343, /* C38C (50060) */ - 3343, /* C38D (50061) */ - 3343, /* C38E (50062) */ - 3343, /* C38F (50063) */ - 3343, /* C390 (50064) */ - 3343, /* C391 (50065) */ - 3343, /* C392 (50066) */ - 3343, /* C393 (50067) */ - 3343, /* C394 (50068) */ - 3343, /* C395 (50069) */ - 3343, /* C396 (50070) */ - 3343, /* C397 (50071) */ - 3343, /* C398 (50072) */ - 3343, /* C399 (50073) */ - 3343, /* C39A (50074) */ - 3343, /* C39B (50075) */ - 3343, /* C39C (50076) */ - 3343, /* C39D (50077) */ - 3343, /* C39E (50078) */ - 3343, /* C39F (50079) */ - 3343, /* C3A0 (50080) */ - 3343, /* C3A1 (50081) */ - 3343, /* C3A2 (50082) */ - 3343, /* C3A3 (50083) */ - 3343, /* C3A4 (50084) */ - 3343, /* C3A5 (50085) */ - 3343, /* C3A6 (50086) */ - 3343, /* C3A7 (50087) */ - 3343, /* C3A8 (50088) */ - 3343, /* C3A9 (50089) */ - 3343, /* C3AA (50090) */ - 3343, /* C3AB (50091) */ - 3343, /* C3AC (50092) */ - 3343, /* C3AD (50093) */ - 3343, /* C3AE (50094) */ - 3343, /* C3AF (50095) */ - 3343, /* C3B0 (50096) */ - 3343, /* C3B1 (50097) */ - 3343, /* C3B2 (50098) */ - 3343, /* C3B3 (50099) */ - 3343, /* C3B4 (50100) */ - 3343, /* C3B5 (50101) */ - 3343, /* C3B6 (50102) */ - 3343, /* C3B7 (50103) */ - 3343, /* C3B8 (50104) */ - 3343, /* C3B9 (50105) */ - 3343, /* C3BA (50106) */ - 3343, /* C3BB (50107) */ - 3343, /* C3BC (50108) */ - 3343, /* C3BD (50109) */ - 3343, /* C3BE (50110) */ - 3343, /* C3BF (50111) */ - 3343, /* C3C0 (50112) */ - 3343, /* C3C1 (50113) */ - 3343, /* C3C2 (50114) */ - 3343, /* C3C3 (50115) */ - 3343, /* C3C4 (50116) */ - 3343, /* C3C5 (50117) */ - 3343, /* C3C6 (50118) */ - 3343, /* C3C7 (50119) */ - 3343, /* C3C8 (50120) */ - 3343, /* C3C9 (50121) */ - 3343, /* C3CA (50122) */ - 3343, /* C3CB (50123) */ - 3343, /* C3CC (50124) */ - 3343, /* C3CD (50125) */ - 3343, /* C3CE (50126) */ - 3343, /* C3CF (50127) */ - 3343, /* C3D0 (50128) */ - 3343, /* C3D1 (50129) */ - 3343, /* C3D2 (50130) */ - 3343, /* C3D3 (50131) */ - 3343, /* C3D4 (50132) */ - 3343, /* C3D5 (50133) */ - 3343, /* C3D6 (50134) */ - 3343, /* C3D7 (50135) */ - 3343, /* C3D8 (50136) */ - 3343, /* C3D9 (50137) */ - 3343, /* C3DA (50138) */ - 3343, /* C3DB (50139) */ - 3343, /* C3DC (50140) */ - 3343, /* C3DD (50141) */ - 3343, /* C3DE (50142) */ - 3343, /* C3DF (50143) */ - 3343, /* C3E0 (50144) */ - 3343, /* C3E1 (50145) */ - 3343, /* C3E2 (50146) */ - 3343, /* C3E3 (50147) */ - 3343, /* C3E4 (50148) */ - 3343, /* C3E5 (50149) */ - 3343, /* C3E6 (50150) */ - 3343, /* C3E7 (50151) */ - 3343, /* C3E8 (50152) */ - 3343, /* C3E9 (50153) */ - 3343, /* C3EA (50154) */ - 3343, /* C3EB (50155) */ - 3343, /* C3EC (50156) */ - 3343, /* C3ED (50157) */ - 3343, /* C3EE (50158) */ - 3343, /* C3EF (50159) */ - 3343, /* C3F0 (50160) */ - 3343, /* C3F1 (50161) */ - 3343, /* C3F2 (50162) */ - 3343, /* C3F3 (50163) */ - 3343, /* C3F4 (50164) */ - 3343, /* C3F5 (50165) */ - 3343, /* C3F6 (50166) */ - 3343, /* C3F7 (50167) */ - 3343, /* C3F8 (50168) */ - 3343, /* C3F9 (50169) */ - 3343, /* C3FA (50170) */ - 3343, /* C3FB (50171) */ - 3343, /* C3FC (50172) */ - 3343, /* C3FD (50173) */ - 3343, /* C3FE (50174) */ - 3343, /* C3FF (50175) */ - 3343, /* C400 (50176) */ - 3343, /* C401 (50177) */ - 3343, /* C402 (50178) */ - 3343, /* C403 (50179) */ - 3343, /* C404 (50180) */ - 3343, /* C405 (50181) */ - 3343, /* C406 (50182) */ - 3343, /* C407 (50183) */ - 3343, /* C408 (50184) */ - 3343, /* C409 (50185) */ - 3343, /* C40A (50186) */ - 3343, /* C40B (50187) */ - 3343, /* C40C (50188) */ - 3343, /* C40D (50189) */ - 3343, /* C40E (50190) */ - 3343, /* C40F (50191) */ - 3343, /* C410 (50192) */ - 3343, /* C411 (50193) */ - 3343, /* C412 (50194) */ - 3343, /* C413 (50195) */ - 3343, /* C414 (50196) */ - 3343, /* C415 (50197) */ - 3343, /* C416 (50198) */ - 3343, /* C417 (50199) */ - 3343, /* C418 (50200) */ - 3343, /* C419 (50201) */ - 3343, /* C41A (50202) */ - 3343, /* C41B (50203) */ - 3343, /* C41C (50204) */ - 3343, /* C41D (50205) */ - 3343, /* C41E (50206) */ - 3343, /* C41F (50207) */ - 3343, /* C420 (50208) */ - 3343, /* C421 (50209) */ - 3343, /* C422 (50210) */ - 3343, /* C423 (50211) */ - 3343, /* C424 (50212) */ - 3343, /* C425 (50213) */ - 3343, /* C426 (50214) */ - 3343, /* C427 (50215) */ - 3343, /* C428 (50216) */ - 3343, /* C429 (50217) */ - 3343, /* C42A (50218) */ - 3343, /* C42B (50219) */ - 3343, /* C42C (50220) */ - 3343, /* C42D (50221) */ - 3343, /* C42E (50222) */ - 3343, /* C42F (50223) */ - 3343, /* C430 (50224) */ - 3343, /* C431 (50225) */ - 3343, /* C432 (50226) */ - 3343, /* C433 (50227) */ - 3343, /* C434 (50228) */ - 3343, /* C435 (50229) */ - 3343, /* C436 (50230) */ - 3343, /* C437 (50231) */ - 3343, /* C438 (50232) */ - 3343, /* C439 (50233) */ - 3343, /* C43A (50234) */ - 3343, /* C43B (50235) */ - 3343, /* C43C (50236) */ - 3343, /* C43D (50237) */ - 3343, /* C43E (50238) */ - 3343, /* C43F (50239) */ - 3343, /* C440 (50240) */ - 3343, /* C441 (50241) */ - 3343, /* C442 (50242) */ - 3343, /* C443 (50243) */ - 3343, /* C444 (50244) */ - 3343, /* C445 (50245) */ - 3343, /* C446 (50246) */ - 3343, /* C447 (50247) */ - 3343, /* C448 (50248) */ - 3343, /* C449 (50249) */ - 3343, /* C44A (50250) */ - 3343, /* C44B (50251) */ - 3343, /* C44C (50252) */ - 3343, /* C44D (50253) */ - 3343, /* C44E (50254) */ - 3343, /* C44F (50255) */ - 3343, /* C450 (50256) */ - 3343, /* C451 (50257) */ - 3343, /* C452 (50258) */ - 3343, /* C453 (50259) */ - 3343, /* C454 (50260) */ - 3343, /* C455 (50261) */ - 3343, /* C456 (50262) */ - 3343, /* C457 (50263) */ - 3343, /* C458 (50264) */ - 3343, /* C459 (50265) */ - 3343, /* C45A (50266) */ - 3343, /* C45B (50267) */ - 3343, /* C45C (50268) */ - 3343, /* C45D (50269) */ - 3343, /* C45E (50270) */ - 3343, /* C45F (50271) */ - 3343, /* C460 (50272) */ - 3343, /* C461 (50273) */ - 3343, /* C462 (50274) */ - 3343, /* C463 (50275) */ - 3343, /* C464 (50276) */ - 3343, /* C465 (50277) */ - 3343, /* C466 (50278) */ - 3343, /* C467 (50279) */ - 3343, /* C468 (50280) */ - 3343, /* C469 (50281) */ - 3343, /* C46A (50282) */ - 3343, /* C46B (50283) */ - 3343, /* C46C (50284) */ - 3343, /* C46D (50285) */ - 3343, /* C46E (50286) */ - 3343, /* C46F (50287) */ - 3343, /* C470 (50288) */ - 3343, /* C471 (50289) */ - 3343, /* C472 (50290) */ - 3343, /* C473 (50291) */ - 3343, /* C474 (50292) */ - 3343, /* C475 (50293) */ - 3343, /* C476 (50294) */ - 3343, /* C477 (50295) */ - 3343, /* C478 (50296) */ - 3343, /* C479 (50297) */ - 3343, /* C47A (50298) */ - 3343, /* C47B (50299) */ - 3343, /* C47C (50300) */ - 3343, /* C47D (50301) */ - 3343, /* C47E (50302) */ - 3343, /* C47F (50303) */ - 3343, /* C480 (50304) */ - 3343, /* C481 (50305) */ - 3343, /* C482 (50306) */ - 3343, /* C483 (50307) */ - 3343, /* C484 (50308) */ - 3343, /* C485 (50309) */ - 3343, /* C486 (50310) */ - 3343, /* C487 (50311) */ - 3343, /* C488 (50312) */ - 3343, /* C489 (50313) */ - 3343, /* C48A (50314) */ - 3343, /* C48B (50315) */ - 3343, /* C48C (50316) */ - 3343, /* C48D (50317) */ - 3343, /* C48E (50318) */ - 3343, /* C48F (50319) */ - 3343, /* C490 (50320) */ - 3343, /* C491 (50321) */ - 3343, /* C492 (50322) */ - 3343, /* C493 (50323) */ - 3343, /* C494 (50324) */ - 3343, /* C495 (50325) */ - 3343, /* C496 (50326) */ - 3343, /* C497 (50327) */ - 3343, /* C498 (50328) */ - 3343, /* C499 (50329) */ - 3343, /* C49A (50330) */ - 3343, /* C49B (50331) */ - 3343, /* C49C (50332) */ - 3343, /* C49D (50333) */ - 3343, /* C49E (50334) */ - 3343, /* C49F (50335) */ - 3343, /* C4A0 (50336) */ - 3343, /* C4A1 (50337) */ - 3343, /* C4A2 (50338) */ - 3343, /* C4A3 (50339) */ - 3343, /* C4A4 (50340) */ - 3343, /* C4A5 (50341) */ - 3343, /* C4A6 (50342) */ - 3343, /* C4A7 (50343) */ - 3343, /* C4A8 (50344) */ - 3343, /* C4A9 (50345) */ - 3343, /* C4AA (50346) */ - 3343, /* C4AB (50347) */ - 3343, /* C4AC (50348) */ - 3343, /* C4AD (50349) */ - 3343, /* C4AE (50350) */ - 3343, /* C4AF (50351) */ - 3343, /* C4B0 (50352) */ - 3343, /* C4B1 (50353) */ - 3343, /* C4B2 (50354) */ - 3343, /* C4B3 (50355) */ - 3343, /* C4B4 (50356) */ - 3343, /* C4B5 (50357) */ - 3343, /* C4B6 (50358) */ - 3343, /* C4B7 (50359) */ - 3343, /* C4B8 (50360) */ - 3343, /* C4B9 (50361) */ - 3343, /* C4BA (50362) */ - 3343, /* C4BB (50363) */ - 3343, /* C4BC (50364) */ - 3343, /* C4BD (50365) */ - 3343, /* C4BE (50366) */ - 3343, /* C4BF (50367) */ - 3343, /* C4C0 (50368) */ - 3343, /* C4C1 (50369) */ - 3343, /* C4C2 (50370) */ - 3343, /* C4C3 (50371) */ - 3343, /* C4C4 (50372) */ - 3343, /* C4C5 (50373) */ - 3343, /* C4C6 (50374) */ - 3343, /* C4C7 (50375) */ - 3343, /* C4C8 (50376) */ - 3343, /* C4C9 (50377) */ - 3343, /* C4CA (50378) */ - 3343, /* C4CB (50379) */ - 3343, /* C4CC (50380) */ - 3343, /* C4CD (50381) */ - 3343, /* C4CE (50382) */ - 3343, /* C4CF (50383) */ - 3343, /* C4D0 (50384) */ - 3343, /* C4D1 (50385) */ - 3343, /* C4D2 (50386) */ - 3343, /* C4D3 (50387) */ - 3343, /* C4D4 (50388) */ - 3343, /* C4D5 (50389) */ - 3343, /* C4D6 (50390) */ - 3343, /* C4D7 (50391) */ - 3343, /* C4D8 (50392) */ - 3343, /* C4D9 (50393) */ - 3343, /* C4DA (50394) */ - 3343, /* C4DB (50395) */ - 3343, /* C4DC (50396) */ - 3343, /* C4DD (50397) */ - 3343, /* C4DE (50398) */ - 3343, /* C4DF (50399) */ - 3343, /* C4E0 (50400) */ - 3343, /* C4E1 (50401) */ - 3343, /* C4E2 (50402) */ - 3343, /* C4E3 (50403) */ - 3343, /* C4E4 (50404) */ - 3343, /* C4E5 (50405) */ - 3343, /* C4E6 (50406) */ - 3343, /* C4E7 (50407) */ - 3343, /* C4E8 (50408) */ - 3343, /* C4E9 (50409) */ - 3343, /* C4EA (50410) */ - 3343, /* C4EB (50411) */ - 3343, /* C4EC (50412) */ - 3343, /* C4ED (50413) */ - 3343, /* C4EE (50414) */ - 3343, /* C4EF (50415) */ - 3343, /* C4F0 (50416) */ - 3343, /* C4F1 (50417) */ - 3343, /* C4F2 (50418) */ - 3343, /* C4F3 (50419) */ - 3343, /* C4F4 (50420) */ - 3343, /* C4F5 (50421) */ - 3343, /* C4F6 (50422) */ - 3343, /* C4F7 (50423) */ - 3343, /* C4F8 (50424) */ - 3343, /* C4F9 (50425) */ - 3343, /* C4FA (50426) */ - 3343, /* C4FB (50427) */ - 3343, /* C4FC (50428) */ - 3343, /* C4FD (50429) */ - 3343, /* C4FE (50430) */ - 3343, /* C4FF (50431) */ - 3343, /* C500 (50432) */ - 3343, /* C501 (50433) */ - 3343, /* C502 (50434) */ - 3343, /* C503 (50435) */ - 3343, /* C504 (50436) */ - 3343, /* C505 (50437) */ - 3343, /* C506 (50438) */ - 3343, /* C507 (50439) */ - 3343, /* C508 (50440) */ - 3343, /* C509 (50441) */ - 3343, /* C50A (50442) */ - 3343, /* C50B (50443) */ - 3343, /* C50C (50444) */ - 3343, /* C50D (50445) */ - 3343, /* C50E (50446) */ - 3343, /* C50F (50447) */ - 3343, /* C510 (50448) */ - 3343, /* C511 (50449) */ - 3343, /* C512 (50450) */ - 3343, /* C513 (50451) */ - 3343, /* C514 (50452) */ - 3343, /* C515 (50453) */ - 3343, /* C516 (50454) */ - 3343, /* C517 (50455) */ - 3343, /* C518 (50456) */ - 3343, /* C519 (50457) */ - 3343, /* C51A (50458) */ - 3343, /* C51B (50459) */ - 3343, /* C51C (50460) */ - 3343, /* C51D (50461) */ - 3343, /* C51E (50462) */ - 3343, /* C51F (50463) */ - 3343, /* C520 (50464) */ - 3343, /* C521 (50465) */ - 3343, /* C522 (50466) */ - 3343, /* C523 (50467) */ - 3343, /* C524 (50468) */ - 3343, /* C525 (50469) */ - 3343, /* C526 (50470) */ - 3343, /* C527 (50471) */ - 3343, /* C528 (50472) */ - 3343, /* C529 (50473) */ - 3343, /* C52A (50474) */ - 3343, /* C52B (50475) */ - 3343, /* C52C (50476) */ - 3343, /* C52D (50477) */ - 3343, /* C52E (50478) */ - 3343, /* C52F (50479) */ - 3343, /* C530 (50480) */ - 3343, /* C531 (50481) */ - 3343, /* C532 (50482) */ - 3343, /* C533 (50483) */ - 3343, /* C534 (50484) */ - 3343, /* C535 (50485) */ - 3343, /* C536 (50486) */ - 3343, /* C537 (50487) */ - 3343, /* C538 (50488) */ - 3343, /* C539 (50489) */ - 3343, /* C53A (50490) */ - 3343, /* C53B (50491) */ - 3343, /* C53C (50492) */ - 3343, /* C53D (50493) */ - 3343, /* C53E (50494) */ - 3343, /* C53F (50495) */ - 3343, /* C540 (50496) */ - 3343, /* C541 (50497) */ - 3343, /* C542 (50498) */ - 3343, /* C543 (50499) */ - 3343, /* C544 (50500) */ - 3343, /* C545 (50501) */ - 3343, /* C546 (50502) */ - 3343, /* C547 (50503) */ - 3343, /* C548 (50504) */ - 3343, /* C549 (50505) */ - 3343, /* C54A (50506) */ - 3343, /* C54B (50507) */ - 3343, /* C54C (50508) */ - 3343, /* C54D (50509) */ - 3343, /* C54E (50510) */ - 3343, /* C54F (50511) */ - 3343, /* C550 (50512) */ - 3343, /* C551 (50513) */ - 3343, /* C552 (50514) */ - 3343, /* C553 (50515) */ - 3343, /* C554 (50516) */ - 3343, /* C555 (50517) */ - 3343, /* C556 (50518) */ - 3343, /* C557 (50519) */ - 3343, /* C558 (50520) */ - 3343, /* C559 (50521) */ - 3343, /* C55A (50522) */ - 3343, /* C55B (50523) */ - 3343, /* C55C (50524) */ - 3343, /* C55D (50525) */ - 3343, /* C55E (50526) */ - 3343, /* C55F (50527) */ - 3343, /* C560 (50528) */ - 3343, /* C561 (50529) */ - 3343, /* C562 (50530) */ - 3343, /* C563 (50531) */ - 3343, /* C564 (50532) */ - 3343, /* C565 (50533) */ - 3343, /* C566 (50534) */ - 3343, /* C567 (50535) */ - 3343, /* C568 (50536) */ - 3343, /* C569 (50537) */ - 3343, /* C56A (50538) */ - 3343, /* C56B (50539) */ - 3343, /* C56C (50540) */ - 3343, /* C56D (50541) */ - 3343, /* C56E (50542) */ - 3343, /* C56F (50543) */ - 3343, /* C570 (50544) */ - 3343, /* C571 (50545) */ - 3343, /* C572 (50546) */ - 3343, /* C573 (50547) */ - 3343, /* C574 (50548) */ - 3343, /* C575 (50549) */ - 3343, /* C576 (50550) */ - 3343, /* C577 (50551) */ - 3343, /* C578 (50552) */ - 3343, /* C579 (50553) */ - 3343, /* C57A (50554) */ - 3343, /* C57B (50555) */ - 3343, /* C57C (50556) */ - 3343, /* C57D (50557) */ - 3343, /* C57E (50558) */ - 3343, /* C57F (50559) */ - 3343, /* C580 (50560) */ - 3343, /* C581 (50561) */ - 3343, /* C582 (50562) */ - 3343, /* C583 (50563) */ - 3343, /* C584 (50564) */ - 3343, /* C585 (50565) */ - 3343, /* C586 (50566) */ - 3343, /* C587 (50567) */ - 3343, /* C588 (50568) */ - 3343, /* C589 (50569) */ - 3343, /* C58A (50570) */ - 3343, /* C58B (50571) */ - 3343, /* C58C (50572) */ - 3343, /* C58D (50573) */ - 3343, /* C58E (50574) */ - 3343, /* C58F (50575) */ - 3343, /* C590 (50576) */ - 3343, /* C591 (50577) */ - 3343, /* C592 (50578) */ - 3343, /* C593 (50579) */ - 3343, /* C594 (50580) */ - 3343, /* C595 (50581) */ - 3343, /* C596 (50582) */ - 3343, /* C597 (50583) */ - 3343, /* C598 (50584) */ - 3343, /* C599 (50585) */ - 3343, /* C59A (50586) */ - 3343, /* C59B (50587) */ - 3343, /* C59C (50588) */ - 3343, /* C59D (50589) */ - 3343, /* C59E (50590) */ - 3343, /* C59F (50591) */ - 3343, /* C5A0 (50592) */ - 3343, /* C5A1 (50593) */ - 3343, /* C5A2 (50594) */ - 3343, /* C5A3 (50595) */ - 3343, /* C5A4 (50596) */ - 3343, /* C5A5 (50597) */ - 3343, /* C5A6 (50598) */ - 3343, /* C5A7 (50599) */ - 3343, /* C5A8 (50600) */ - 3343, /* C5A9 (50601) */ - 3343, /* C5AA (50602) */ - 3343, /* C5AB (50603) */ - 3343, /* C5AC (50604) */ - 3343, /* C5AD (50605) */ - 3343, /* C5AE (50606) */ - 3343, /* C5AF (50607) */ - 3343, /* C5B0 (50608) */ - 3343, /* C5B1 (50609) */ - 3343, /* C5B2 (50610) */ - 3343, /* C5B3 (50611) */ - 3343, /* C5B4 (50612) */ - 3343, /* C5B5 (50613) */ - 3343, /* C5B6 (50614) */ - 3343, /* C5B7 (50615) */ - 3343, /* C5B8 (50616) */ - 3343, /* C5B9 (50617) */ - 3343, /* C5BA (50618) */ - 3343, /* C5BB (50619) */ - 3343, /* C5BC (50620) */ - 3343, /* C5BD (50621) */ - 3343, /* C5BE (50622) */ - 3343, /* C5BF (50623) */ - 3343, /* C5C0 (50624) */ - 3343, /* C5C1 (50625) */ - 3343, /* C5C2 (50626) */ - 3343, /* C5C3 (50627) */ - 3343, /* C5C4 (50628) */ - 3343, /* C5C5 (50629) */ - 3343, /* C5C6 (50630) */ - 3343, /* C5C7 (50631) */ - 3343, /* C5C8 (50632) */ - 3343, /* C5C9 (50633) */ - 3343, /* C5CA (50634) */ - 3343, /* C5CB (50635) */ - 3343, /* C5CC (50636) */ - 3343, /* C5CD (50637) */ - 3343, /* C5CE (50638) */ - 3343, /* C5CF (50639) */ - 3343, /* C5D0 (50640) */ - 3343, /* C5D1 (50641) */ - 3343, /* C5D2 (50642) */ - 3343, /* C5D3 (50643) */ - 3343, /* C5D4 (50644) */ - 3343, /* C5D5 (50645) */ - 3343, /* C5D6 (50646) */ - 3343, /* C5D7 (50647) */ - 3343, /* C5D8 (50648) */ - 3343, /* C5D9 (50649) */ - 3343, /* C5DA (50650) */ - 3343, /* C5DB (50651) */ - 3343, /* C5DC (50652) */ - 3343, /* C5DD (50653) */ - 3343, /* C5DE (50654) */ - 3343, /* C5DF (50655) */ - 3343, /* C5E0 (50656) */ - 3343, /* C5E1 (50657) */ - 3343, /* C5E2 (50658) */ - 3343, /* C5E3 (50659) */ - 3343, /* C5E4 (50660) */ - 3343, /* C5E5 (50661) */ - 3343, /* C5E6 (50662) */ - 3343, /* C5E7 (50663) */ - 3343, /* C5E8 (50664) */ - 3343, /* C5E9 (50665) */ - 3343, /* C5EA (50666) */ - 3343, /* C5EB (50667) */ - 3343, /* C5EC (50668) */ - 3343, /* C5ED (50669) */ - 3343, /* C5EE (50670) */ - 3343, /* C5EF (50671) */ - 3343, /* C5F0 (50672) */ - 3343, /* C5F1 (50673) */ - 3343, /* C5F2 (50674) */ - 3343, /* C5F3 (50675) */ - 3343, /* C5F4 (50676) */ - 3343, /* C5F5 (50677) */ - 3343, /* C5F6 (50678) */ - 3343, /* C5F7 (50679) */ - 3343, /* C5F8 (50680) */ - 3343, /* C5F9 (50681) */ - 3343, /* C5FA (50682) */ - 3343, /* C5FB (50683) */ - 3343, /* C5FC (50684) */ - 3343, /* C5FD (50685) */ - 3343, /* C5FE (50686) */ - 3343, /* C5FF (50687) */ - 3343, /* C600 (50688) */ - 3343, /* C601 (50689) */ - 3343, /* C602 (50690) */ - 3343, /* C603 (50691) */ - 3343, /* C604 (50692) */ - 3343, /* C605 (50693) */ - 3343, /* C606 (50694) */ - 3343, /* C607 (50695) */ - 3343, /* C608 (50696) */ - 3343, /* C609 (50697) */ - 3343, /* C60A (50698) */ - 3343, /* C60B (50699) */ - 3343, /* C60C (50700) */ - 3343, /* C60D (50701) */ - 3343, /* C60E (50702) */ - 3343, /* C60F (50703) */ - 3343, /* C610 (50704) */ - 3343, /* C611 (50705) */ - 3343, /* C612 (50706) */ - 3343, /* C613 (50707) */ - 3343, /* C614 (50708) */ - 3343, /* C615 (50709) */ - 3343, /* C616 (50710) */ - 3343, /* C617 (50711) */ - 3343, /* C618 (50712) */ - 3343, /* C619 (50713) */ - 3343, /* C61A (50714) */ - 3343, /* C61B (50715) */ - 3343, /* C61C (50716) */ - 3343, /* C61D (50717) */ - 3343, /* C61E (50718) */ - 3343, /* C61F (50719) */ - 3343, /* C620 (50720) */ - 3343, /* C621 (50721) */ - 3343, /* C622 (50722) */ - 3343, /* C623 (50723) */ - 3343, /* C624 (50724) */ - 3343, /* C625 (50725) */ - 3343, /* C626 (50726) */ - 3343, /* C627 (50727) */ - 3343, /* C628 (50728) */ - 3343, /* C629 (50729) */ - 3343, /* C62A (50730) */ - 3343, /* C62B (50731) */ - 3343, /* C62C (50732) */ - 3343, /* C62D (50733) */ - 3343, /* C62E (50734) */ - 3343, /* C62F (50735) */ - 3343, /* C630 (50736) */ - 3343, /* C631 (50737) */ - 3343, /* C632 (50738) */ - 3343, /* C633 (50739) */ - 3343, /* C634 (50740) */ - 3343, /* C635 (50741) */ - 3343, /* C636 (50742) */ - 3343, /* C637 (50743) */ - 3343, /* C638 (50744) */ - 3343, /* C639 (50745) */ - 3343, /* C63A (50746) */ - 3343, /* C63B (50747) */ - 3343, /* C63C (50748) */ - 3343, /* C63D (50749) */ - 3343, /* C63E (50750) */ - 3343, /* C63F (50751) */ - 3343, /* C640 (50752) */ - 3343, /* C641 (50753) */ - 3343, /* C642 (50754) */ - 3343, /* C643 (50755) */ - 3343, /* C644 (50756) */ - 3343, /* C645 (50757) */ - 3343, /* C646 (50758) */ - 3343, /* C647 (50759) */ - 3343, /* C648 (50760) */ - 3343, /* C649 (50761) */ - 3343, /* C64A (50762) */ - 3343, /* C64B (50763) */ - 3343, /* C64C (50764) */ - 3343, /* C64D (50765) */ - 3343, /* C64E (50766) */ - 3343, /* C64F (50767) */ - 3343, /* C650 (50768) */ - 3343, /* C651 (50769) */ - 3343, /* C652 (50770) */ - 3343, /* C653 (50771) */ - 3343, /* C654 (50772) */ - 3343, /* C655 (50773) */ - 3343, /* C656 (50774) */ - 3343, /* C657 (50775) */ - 3343, /* C658 (50776) */ - 3343, /* C659 (50777) */ - 3343, /* C65A (50778) */ - 3343, /* C65B (50779) */ - 3343, /* C65C (50780) */ - 3343, /* C65D (50781) */ - 3343, /* C65E (50782) */ - 3343, /* C65F (50783) */ - 3343, /* C660 (50784) */ - 3343, /* C661 (50785) */ - 3343, /* C662 (50786) */ - 3343, /* C663 (50787) */ - 3343, /* C664 (50788) */ - 3343, /* C665 (50789) */ - 3343, /* C666 (50790) */ - 3343, /* C667 (50791) */ - 3343, /* C668 (50792) */ - 3343, /* C669 (50793) */ - 3343, /* C66A (50794) */ - 3343, /* C66B (50795) */ - 3343, /* C66C (50796) */ - 3343, /* C66D (50797) */ - 3343, /* C66E (50798) */ - 3343, /* C66F (50799) */ - 3343, /* C670 (50800) */ - 3343, /* C671 (50801) */ - 3343, /* C672 (50802) */ - 3343, /* C673 (50803) */ - 3343, /* C674 (50804) */ - 3343, /* C675 (50805) */ - 3343, /* C676 (50806) */ - 3343, /* C677 (50807) */ - 3343, /* C678 (50808) */ - 3343, /* C679 (50809) */ - 3343, /* C67A (50810) */ - 3343, /* C67B (50811) */ - 3343, /* C67C (50812) */ - 3343, /* C67D (50813) */ - 3343, /* C67E (50814) */ - 3343, /* C67F (50815) */ - 3343, /* C680 (50816) */ - 3343, /* C681 (50817) */ - 3343, /* C682 (50818) */ - 3343, /* C683 (50819) */ - 3343, /* C684 (50820) */ - 3343, /* C685 (50821) */ - 3343, /* C686 (50822) */ - 3343, /* C687 (50823) */ - 3343, /* C688 (50824) */ - 3343, /* C689 (50825) */ - 3343, /* C68A (50826) */ - 3343, /* C68B (50827) */ - 3343, /* C68C (50828) */ - 3343, /* C68D (50829) */ - 3343, /* C68E (50830) */ - 3343, /* C68F (50831) */ - 3343, /* C690 (50832) */ - 3343, /* C691 (50833) */ - 3343, /* C692 (50834) */ - 3343, /* C693 (50835) */ - 3343, /* C694 (50836) */ - 3343, /* C695 (50837) */ - 3343, /* C696 (50838) */ - 3343, /* C697 (50839) */ - 3343, /* C698 (50840) */ - 3343, /* C699 (50841) */ - 3343, /* C69A (50842) */ - 3343, /* C69B (50843) */ - 3343, /* C69C (50844) */ - 3343, /* C69D (50845) */ - 3343, /* C69E (50846) */ - 3343, /* C69F (50847) */ - 3343, /* C6A0 (50848) */ - 3343, /* C6A1 (50849) */ - 3343, /* C6A2 (50850) */ - 3343, /* C6A3 (50851) */ - 3343, /* C6A4 (50852) */ - 3343, /* C6A5 (50853) */ - 3343, /* C6A6 (50854) */ - 3343, /* C6A7 (50855) */ - 3343, /* C6A8 (50856) */ - 3343, /* C6A9 (50857) */ - 3343, /* C6AA (50858) */ - 3343, /* C6AB (50859) */ - 3343, /* C6AC (50860) */ - 3343, /* C6AD (50861) */ - 3343, /* C6AE (50862) */ - 3343, /* C6AF (50863) */ - 3343, /* C6B0 (50864) */ - 3343, /* C6B1 (50865) */ - 3343, /* C6B2 (50866) */ - 3343, /* C6B3 (50867) */ - 3343, /* C6B4 (50868) */ - 3343, /* C6B5 (50869) */ - 3343, /* C6B6 (50870) */ - 3343, /* C6B7 (50871) */ - 3343, /* C6B8 (50872) */ - 3343, /* C6B9 (50873) */ - 3343, /* C6BA (50874) */ - 3343, /* C6BB (50875) */ - 3343, /* C6BC (50876) */ - 3343, /* C6BD (50877) */ - 3343, /* C6BE (50878) */ - 3343, /* C6BF (50879) */ - 3343, /* C6C0 (50880) */ - 3343, /* C6C1 (50881) */ - 3343, /* C6C2 (50882) */ - 3343, /* C6C3 (50883) */ - 3343, /* C6C4 (50884) */ - 3343, /* C6C5 (50885) */ - 3343, /* C6C6 (50886) */ - 3343, /* C6C7 (50887) */ - 3343, /* C6C8 (50888) */ - 3343, /* C6C9 (50889) */ - 3343, /* C6CA (50890) */ - 3343, /* C6CB (50891) */ - 3343, /* C6CC (50892) */ - 3343, /* C6CD (50893) */ - 3343, /* C6CE (50894) */ - 3343, /* C6CF (50895) */ - 3343, /* C6D0 (50896) */ - 3343, /* C6D1 (50897) */ - 3343, /* C6D2 (50898) */ - 3343, /* C6D3 (50899) */ - 3343, /* C6D4 (50900) */ - 3343, /* C6D5 (50901) */ - 3343, /* C6D6 (50902) */ - 3343, /* C6D7 (50903) */ - 3343, /* C6D8 (50904) */ - 3343, /* C6D9 (50905) */ - 3343, /* C6DA (50906) */ - 3343, /* C6DB (50907) */ - 3343, /* C6DC (50908) */ - 3343, /* C6DD (50909) */ - 3343, /* C6DE (50910) */ - 3343, /* C6DF (50911) */ - 3343, /* C6E0 (50912) */ - 3343, /* C6E1 (50913) */ - 3343, /* C6E2 (50914) */ - 3343, /* C6E3 (50915) */ - 3343, /* C6E4 (50916) */ - 3343, /* C6E5 (50917) */ - 3343, /* C6E6 (50918) */ - 3343, /* C6E7 (50919) */ - 3343, /* C6E8 (50920) */ - 3343, /* C6E9 (50921) */ - 3343, /* C6EA (50922) */ - 3343, /* C6EB (50923) */ - 3343, /* C6EC (50924) */ - 3343, /* C6ED (50925) */ - 3343, /* C6EE (50926) */ - 3343, /* C6EF (50927) */ - 3343, /* C6F0 (50928) */ - 3343, /* C6F1 (50929) */ - 3343, /* C6F2 (50930) */ - 3343, /* C6F3 (50931) */ - 3343, /* C6F4 (50932) */ - 3343, /* C6F5 (50933) */ - 3343, /* C6F6 (50934) */ - 3343, /* C6F7 (50935) */ - 3343, /* C6F8 (50936) */ - 3343, /* C6F9 (50937) */ - 3343, /* C6FA (50938) */ - 3343, /* C6FB (50939) */ - 3343, /* C6FC (50940) */ - 3343, /* C6FD (50941) */ - 3343, /* C6FE (50942) */ - 3343, /* C6FF (50943) */ - 3343, /* C700 (50944) */ - 3343, /* C701 (50945) */ - 3343, /* C702 (50946) */ - 3343, /* C703 (50947) */ - 3343, /* C704 (50948) */ - 3343, /* C705 (50949) */ - 3343, /* C706 (50950) */ - 3343, /* C707 (50951) */ - 3343, /* C708 (50952) */ - 3343, /* C709 (50953) */ - 3343, /* C70A (50954) */ - 3343, /* C70B (50955) */ - 3343, /* C70C (50956) */ - 3343, /* C70D (50957) */ - 3343, /* C70E (50958) */ - 3343, /* C70F (50959) */ - 3343, /* C710 (50960) */ - 3343, /* C711 (50961) */ - 3343, /* C712 (50962) */ - 3343, /* C713 (50963) */ - 3343, /* C714 (50964) */ - 3343, /* C715 (50965) */ - 3343, /* C716 (50966) */ - 3343, /* C717 (50967) */ - 3343, /* C718 (50968) */ - 3343, /* C719 (50969) */ - 3343, /* C71A (50970) */ - 3343, /* C71B (50971) */ - 3343, /* C71C (50972) */ - 3343, /* C71D (50973) */ - 3343, /* C71E (50974) */ - 3343, /* C71F (50975) */ - 3343, /* C720 (50976) */ - 3343, /* C721 (50977) */ - 3343, /* C722 (50978) */ - 3343, /* C723 (50979) */ - 3343, /* C724 (50980) */ - 3343, /* C725 (50981) */ - 3343, /* C726 (50982) */ - 3343, /* C727 (50983) */ - 3343, /* C728 (50984) */ - 3343, /* C729 (50985) */ - 3343, /* C72A (50986) */ - 3343, /* C72B (50987) */ - 3343, /* C72C (50988) */ - 3343, /* C72D (50989) */ - 3343, /* C72E (50990) */ - 3343, /* C72F (50991) */ - 3343, /* C730 (50992) */ - 3343, /* C731 (50993) */ - 3343, /* C732 (50994) */ - 3343, /* C733 (50995) */ - 3343, /* C734 (50996) */ - 3343, /* C735 (50997) */ - 3343, /* C736 (50998) */ - 3343, /* C737 (50999) */ - 3343, /* C738 (51000) */ - 3343, /* C739 (51001) */ - 3343, /* C73A (51002) */ - 3343, /* C73B (51003) */ - 3343, /* C73C (51004) */ - 3343, /* C73D (51005) */ - 3343, /* C73E (51006) */ - 3343, /* C73F (51007) */ - 3343, /* C740 (51008) */ - 3343, /* C741 (51009) */ - 3343, /* C742 (51010) */ - 3343, /* C743 (51011) */ - 3343, /* C744 (51012) */ - 3343, /* C745 (51013) */ - 3343, /* C746 (51014) */ - 3343, /* C747 (51015) */ - 3343, /* C748 (51016) */ - 3343, /* C749 (51017) */ - 3343, /* C74A (51018) */ - 3343, /* C74B (51019) */ - 3343, /* C74C (51020) */ - 3343, /* C74D (51021) */ - 3343, /* C74E (51022) */ - 3343, /* C74F (51023) */ - 3343, /* C750 (51024) */ - 3343, /* C751 (51025) */ - 3343, /* C752 (51026) */ - 3343, /* C753 (51027) */ - 3343, /* C754 (51028) */ - 3343, /* C755 (51029) */ - 3343, /* C756 (51030) */ - 3343, /* C757 (51031) */ - 3343, /* C758 (51032) */ - 3343, /* C759 (51033) */ - 3343, /* C75A (51034) */ - 3343, /* C75B (51035) */ - 3343, /* C75C (51036) */ - 3343, /* C75D (51037) */ - 3343, /* C75E (51038) */ - 3343, /* C75F (51039) */ - 3343, /* C760 (51040) */ - 3343, /* C761 (51041) */ - 3343, /* C762 (51042) */ - 3343, /* C763 (51043) */ - 3343, /* C764 (51044) */ - 3343, /* C765 (51045) */ - 3343, /* C766 (51046) */ - 3343, /* C767 (51047) */ - 3343, /* C768 (51048) */ - 3343, /* C769 (51049) */ - 3343, /* C76A (51050) */ - 3343, /* C76B (51051) */ - 3343, /* C76C (51052) */ - 3343, /* C76D (51053) */ - 3343, /* C76E (51054) */ - 3343, /* C76F (51055) */ - 3343, /* C770 (51056) */ - 3343, /* C771 (51057) */ - 3343, /* C772 (51058) */ - 3343, /* C773 (51059) */ - 3343, /* C774 (51060) */ - 3343, /* C775 (51061) */ - 3343, /* C776 (51062) */ - 3343, /* C777 (51063) */ - 3343, /* C778 (51064) */ - 3343, /* C779 (51065) */ - 3343, /* C77A (51066) */ - 3343, /* C77B (51067) */ - 3343, /* C77C (51068) */ - 3343, /* C77D (51069) */ - 3343, /* C77E (51070) */ - 3343, /* C77F (51071) */ - 3343, /* C780 (51072) */ - 3343, /* C781 (51073) */ - 3343, /* C782 (51074) */ - 3343, /* C783 (51075) */ - 3343, /* C784 (51076) */ - 3343, /* C785 (51077) */ - 3343, /* C786 (51078) */ - 3343, /* C787 (51079) */ - 3343, /* C788 (51080) */ - 3343, /* C789 (51081) */ - 3343, /* C78A (51082) */ - 3343, /* C78B (51083) */ - 3343, /* C78C (51084) */ - 3343, /* C78D (51085) */ - 3343, /* C78E (51086) */ - 3343, /* C78F (51087) */ - 3343, /* C790 (51088) */ - 3343, /* C791 (51089) */ - 3343, /* C792 (51090) */ - 3343, /* C793 (51091) */ - 3343, /* C794 (51092) */ - 3343, /* C795 (51093) */ - 3343, /* C796 (51094) */ - 3343, /* C797 (51095) */ - 3343, /* C798 (51096) */ - 3343, /* C799 (51097) */ - 3343, /* C79A (51098) */ - 3343, /* C79B (51099) */ - 3343, /* C79C (51100) */ - 3343, /* C79D (51101) */ - 3343, /* C79E (51102) */ - 3343, /* C79F (51103) */ - 3343, /* C7A0 (51104) */ - 3343, /* C7A1 (51105) */ - 3343, /* C7A2 (51106) */ - 3343, /* C7A3 (51107) */ - 3343, /* C7A4 (51108) */ - 3343, /* C7A5 (51109) */ - 3343, /* C7A6 (51110) */ - 3343, /* C7A7 (51111) */ - 3343, /* C7A8 (51112) */ - 3343, /* C7A9 (51113) */ - 3343, /* C7AA (51114) */ - 3343, /* C7AB (51115) */ - 3343, /* C7AC (51116) */ - 3343, /* C7AD (51117) */ - 3343, /* C7AE (51118) */ - 3343, /* C7AF (51119) */ - 3343, /* C7B0 (51120) */ - 3343, /* C7B1 (51121) */ - 3343, /* C7B2 (51122) */ - 3343, /* C7B3 (51123) */ - 3343, /* C7B4 (51124) */ - 3343, /* C7B5 (51125) */ - 3343, /* C7B6 (51126) */ - 3343, /* C7B7 (51127) */ - 3343, /* C7B8 (51128) */ - 3343, /* C7B9 (51129) */ - 3343, /* C7BA (51130) */ - 3343, /* C7BB (51131) */ - 3343, /* C7BC (51132) */ - 3343, /* C7BD (51133) */ - 3343, /* C7BE (51134) */ - 3343, /* C7BF (51135) */ - 3343, /* C7C0 (51136) */ - 3343, /* C7C1 (51137) */ - 3343, /* C7C2 (51138) */ - 3343, /* C7C3 (51139) */ - 3343, /* C7C4 (51140) */ - 3343, /* C7C5 (51141) */ - 3343, /* C7C6 (51142) */ - 3343, /* C7C7 (51143) */ - 3343, /* C7C8 (51144) */ - 3343, /* C7C9 (51145) */ - 3343, /* C7CA (51146) */ - 3343, /* C7CB (51147) */ - 3343, /* C7CC (51148) */ - 3343, /* C7CD (51149) */ - 3343, /* C7CE (51150) */ - 3343, /* C7CF (51151) */ - 3343, /* C7D0 (51152) */ - 3343, /* C7D1 (51153) */ - 3343, /* C7D2 (51154) */ - 3343, /* C7D3 (51155) */ - 3343, /* C7D4 (51156) */ - 3343, /* C7D5 (51157) */ - 3343, /* C7D6 (51158) */ - 3343, /* C7D7 (51159) */ - 3343, /* C7D8 (51160) */ - 3343, /* C7D9 (51161) */ - 3343, /* C7DA (51162) */ - 3343, /* C7DB (51163) */ - 3343, /* C7DC (51164) */ - 3343, /* C7DD (51165) */ - 3343, /* C7DE (51166) */ - 3343, /* C7DF (51167) */ - 3343, /* C7E0 (51168) */ - 3343, /* C7E1 (51169) */ - 3343, /* C7E2 (51170) */ - 3343, /* C7E3 (51171) */ - 3343, /* C7E4 (51172) */ - 3343, /* C7E5 (51173) */ - 3343, /* C7E6 (51174) */ - 3343, /* C7E7 (51175) */ - 3343, /* C7E8 (51176) */ - 3343, /* C7E9 (51177) */ - 3343, /* C7EA (51178) */ - 3343, /* C7EB (51179) */ - 3343, /* C7EC (51180) */ - 3343, /* C7ED (51181) */ - 3343, /* C7EE (51182) */ - 3343, /* C7EF (51183) */ - 3343, /* C7F0 (51184) */ - 3343, /* C7F1 (51185) */ - 3343, /* C7F2 (51186) */ - 3343, /* C7F3 (51187) */ - 3343, /* C7F4 (51188) */ - 3343, /* C7F5 (51189) */ - 3343, /* C7F6 (51190) */ - 3343, /* C7F7 (51191) */ - 3343, /* C7F8 (51192) */ - 3343, /* C7F9 (51193) */ - 3343, /* C7FA (51194) */ - 3343, /* C7FB (51195) */ - 3343, /* C7FC (51196) */ - 3343, /* C7FD (51197) */ - 3343, /* C7FE (51198) */ - 3343, /* C7FF (51199) */ - 3343, /* C800 (51200) */ - 3343, /* C801 (51201) */ - 3343, /* C802 (51202) */ - 3343, /* C803 (51203) */ - 3343, /* C804 (51204) */ - 3343, /* C805 (51205) */ - 3343, /* C806 (51206) */ - 3343, /* C807 (51207) */ - 3343, /* C808 (51208) */ - 3343, /* C809 (51209) */ - 3343, /* C80A (51210) */ - 3343, /* C80B (51211) */ - 3343, /* C80C (51212) */ - 3343, /* C80D (51213) */ - 3343, /* C80E (51214) */ - 3343, /* C80F (51215) */ - 3343, /* C810 (51216) */ - 3343, /* C811 (51217) */ - 3343, /* C812 (51218) */ - 3343, /* C813 (51219) */ - 3343, /* C814 (51220) */ - 3343, /* C815 (51221) */ - 3343, /* C816 (51222) */ - 3343, /* C817 (51223) */ - 3343, /* C818 (51224) */ - 3343, /* C819 (51225) */ - 3343, /* C81A (51226) */ - 3343, /* C81B (51227) */ - 3343, /* C81C (51228) */ - 3343, /* C81D (51229) */ - 3343, /* C81E (51230) */ - 3343, /* C81F (51231) */ - 3343, /* C820 (51232) */ - 3343, /* C821 (51233) */ - 3343, /* C822 (51234) */ - 3343, /* C823 (51235) */ - 3343, /* C824 (51236) */ - 3343, /* C825 (51237) */ - 3343, /* C826 (51238) */ - 3343, /* C827 (51239) */ - 3343, /* C828 (51240) */ - 3343, /* C829 (51241) */ - 3343, /* C82A (51242) */ - 3343, /* C82B (51243) */ - 3343, /* C82C (51244) */ - 3343, /* C82D (51245) */ - 3343, /* C82E (51246) */ - 3343, /* C82F (51247) */ - 3343, /* C830 (51248) */ - 3343, /* C831 (51249) */ - 3343, /* C832 (51250) */ - 3343, /* C833 (51251) */ - 3343, /* C834 (51252) */ - 3343, /* C835 (51253) */ - 3343, /* C836 (51254) */ - 3343, /* C837 (51255) */ - 3343, /* C838 (51256) */ - 3343, /* C839 (51257) */ - 3343, /* C83A (51258) */ - 3343, /* C83B (51259) */ - 3343, /* C83C (51260) */ - 3343, /* C83D (51261) */ - 3343, /* C83E (51262) */ - 3343, /* C83F (51263) */ - 3343, /* C840 (51264) */ - 3343, /* C841 (51265) */ - 3343, /* C842 (51266) */ - 3343, /* C843 (51267) */ - 3343, /* C844 (51268) */ - 3343, /* C845 (51269) */ - 3343, /* C846 (51270) */ - 3343, /* C847 (51271) */ - 3343, /* C848 (51272) */ - 3343, /* C849 (51273) */ - 3343, /* C84A (51274) */ - 3343, /* C84B (51275) */ - 3343, /* C84C (51276) */ - 3343, /* C84D (51277) */ - 3343, /* C84E (51278) */ - 3343, /* C84F (51279) */ - 3343, /* C850 (51280) */ - 3343, /* C851 (51281) */ - 3343, /* C852 (51282) */ - 3343, /* C853 (51283) */ - 3343, /* C854 (51284) */ - 3343, /* C855 (51285) */ - 3343, /* C856 (51286) */ - 3343, /* C857 (51287) */ - 3343, /* C858 (51288) */ - 3343, /* C859 (51289) */ - 3343, /* C85A (51290) */ - 3343, /* C85B (51291) */ - 3343, /* C85C (51292) */ - 3343, /* C85D (51293) */ - 3343, /* C85E (51294) */ - 3343, /* C85F (51295) */ - 3343, /* C860 (51296) */ - 3343, /* C861 (51297) */ - 3343, /* C862 (51298) */ - 3343, /* C863 (51299) */ - 3343, /* C864 (51300) */ - 3343, /* C865 (51301) */ - 3343, /* C866 (51302) */ - 3343, /* C867 (51303) */ - 3343, /* C868 (51304) */ - 3343, /* C869 (51305) */ - 3343, /* C86A (51306) */ - 3343, /* C86B (51307) */ - 3343, /* C86C (51308) */ - 3343, /* C86D (51309) */ - 3343, /* C86E (51310) */ - 3343, /* C86F (51311) */ - 3343, /* C870 (51312) */ - 3343, /* C871 (51313) */ - 3343, /* C872 (51314) */ - 3343, /* C873 (51315) */ - 3343, /* C874 (51316) */ - 3343, /* C875 (51317) */ - 3343, /* C876 (51318) */ - 3343, /* C877 (51319) */ - 3343, /* C878 (51320) */ - 3343, /* C879 (51321) */ - 3343, /* C87A (51322) */ - 3343, /* C87B (51323) */ - 3343, /* C87C (51324) */ - 3343, /* C87D (51325) */ - 3343, /* C87E (51326) */ - 3343, /* C87F (51327) */ - 3343, /* C880 (51328) */ - 3343, /* C881 (51329) */ - 3343, /* C882 (51330) */ - 3343, /* C883 (51331) */ - 3343, /* C884 (51332) */ - 3343, /* C885 (51333) */ - 3343, /* C886 (51334) */ - 3343, /* C887 (51335) */ - 3343, /* C888 (51336) */ - 3343, /* C889 (51337) */ - 3343, /* C88A (51338) */ - 3343, /* C88B (51339) */ - 3343, /* C88C (51340) */ - 3343, /* C88D (51341) */ - 3343, /* C88E (51342) */ - 3343, /* C88F (51343) */ - 3343, /* C890 (51344) */ - 3343, /* C891 (51345) */ - 3343, /* C892 (51346) */ - 3343, /* C893 (51347) */ - 3343, /* C894 (51348) */ - 3343, /* C895 (51349) */ - 3343, /* C896 (51350) */ - 3343, /* C897 (51351) */ - 3343, /* C898 (51352) */ - 3343, /* C899 (51353) */ - 3343, /* C89A (51354) */ - 3343, /* C89B (51355) */ - 3343, /* C89C (51356) */ - 3343, /* C89D (51357) */ - 3343, /* C89E (51358) */ - 3343, /* C89F (51359) */ - 3343, /* C8A0 (51360) */ - 3343, /* C8A1 (51361) */ - 3343, /* C8A2 (51362) */ - 3343, /* C8A3 (51363) */ - 3343, /* C8A4 (51364) */ - 3343, /* C8A5 (51365) */ - 3343, /* C8A6 (51366) */ - 3343, /* C8A7 (51367) */ - 3343, /* C8A8 (51368) */ - 3343, /* C8A9 (51369) */ - 3343, /* C8AA (51370) */ - 3343, /* C8AB (51371) */ - 3343, /* C8AC (51372) */ - 3343, /* C8AD (51373) */ - 3343, /* C8AE (51374) */ - 3343, /* C8AF (51375) */ - 3343, /* C8B0 (51376) */ - 3343, /* C8B1 (51377) */ - 3343, /* C8B2 (51378) */ - 3343, /* C8B3 (51379) */ - 3343, /* C8B4 (51380) */ - 3343, /* C8B5 (51381) */ - 3343, /* C8B6 (51382) */ - 3343, /* C8B7 (51383) */ - 3343, /* C8B8 (51384) */ - 3343, /* C8B9 (51385) */ - 3343, /* C8BA (51386) */ - 3343, /* C8BB (51387) */ - 3343, /* C8BC (51388) */ - 3343, /* C8BD (51389) */ - 3343, /* C8BE (51390) */ - 3343, /* C8BF (51391) */ - 3343, /* C8C0 (51392) */ - 3343, /* C8C1 (51393) */ - 3343, /* C8C2 (51394) */ - 3343, /* C8C3 (51395) */ - 3343, /* C8C4 (51396) */ - 3343, /* C8C5 (51397) */ - 3343, /* C8C6 (51398) */ - 3343, /* C8C7 (51399) */ - 3343, /* C8C8 (51400) */ - 3343, /* C8C9 (51401) */ - 3343, /* C8CA (51402) */ - 3343, /* C8CB (51403) */ - 3343, /* C8CC (51404) */ - 3343, /* C8CD (51405) */ - 3343, /* C8CE (51406) */ - 3343, /* C8CF (51407) */ - 3343, /* C8D0 (51408) */ - 3343, /* C8D1 (51409) */ - 3343, /* C8D2 (51410) */ - 3343, /* C8D3 (51411) */ - 3343, /* C8D4 (51412) */ - 3343, /* C8D5 (51413) */ - 3343, /* C8D6 (51414) */ - 3343, /* C8D7 (51415) */ - 3343, /* C8D8 (51416) */ - 3343, /* C8D9 (51417) */ - 3343, /* C8DA (51418) */ - 3343, /* C8DB (51419) */ - 3343, /* C8DC (51420) */ - 3343, /* C8DD (51421) */ - 3343, /* C8DE (51422) */ - 3343, /* C8DF (51423) */ - 3343, /* C8E0 (51424) */ - 3343, /* C8E1 (51425) */ - 3343, /* C8E2 (51426) */ - 3343, /* C8E3 (51427) */ - 3343, /* C8E4 (51428) */ - 3343, /* C8E5 (51429) */ - 3343, /* C8E6 (51430) */ - 3343, /* C8E7 (51431) */ - 3343, /* C8E8 (51432) */ - 3343, /* C8E9 (51433) */ - 3343, /* C8EA (51434) */ - 3343, /* C8EB (51435) */ - 3343, /* C8EC (51436) */ - 3343, /* C8ED (51437) */ - 3343, /* C8EE (51438) */ - 3343, /* C8EF (51439) */ - 3343, /* C8F0 (51440) */ - 3343, /* C8F1 (51441) */ - 3343, /* C8F2 (51442) */ - 3343, /* C8F3 (51443) */ - 3343, /* C8F4 (51444) */ - 3343, /* C8F5 (51445) */ - 3343, /* C8F6 (51446) */ - 3343, /* C8F7 (51447) */ - 3343, /* C8F8 (51448) */ - 3343, /* C8F9 (51449) */ - 3343, /* C8FA (51450) */ - 3343, /* C8FB (51451) */ - 3343, /* C8FC (51452) */ - 3343, /* C8FD (51453) */ - 3343, /* C8FE (51454) */ - 3343, /* C8FF (51455) */ - 3343, /* C900 (51456) */ - 3343, /* C901 (51457) */ - 3343, /* C902 (51458) */ - 3343, /* C903 (51459) */ - 3343, /* C904 (51460) */ - 3343, /* C905 (51461) */ - 3343, /* C906 (51462) */ - 3343, /* C907 (51463) */ - 3343, /* C908 (51464) */ - 3343, /* C909 (51465) */ - 3343, /* C90A (51466) */ - 3343, /* C90B (51467) */ - 3343, /* C90C (51468) */ - 3343, /* C90D (51469) */ - 3343, /* C90E (51470) */ - 3343, /* C90F (51471) */ - 3343, /* C910 (51472) */ - 3343, /* C911 (51473) */ - 3343, /* C912 (51474) */ - 3343, /* C913 (51475) */ - 3343, /* C914 (51476) */ - 3343, /* C915 (51477) */ - 3343, /* C916 (51478) */ - 3343, /* C917 (51479) */ - 3343, /* C918 (51480) */ - 3343, /* C919 (51481) */ - 3343, /* C91A (51482) */ - 3343, /* C91B (51483) */ - 3343, /* C91C (51484) */ - 3343, /* C91D (51485) */ - 3343, /* C91E (51486) */ - 3343, /* C91F (51487) */ - 3343, /* C920 (51488) */ - 3343, /* C921 (51489) */ - 3343, /* C922 (51490) */ - 3343, /* C923 (51491) */ - 3343, /* C924 (51492) */ - 3343, /* C925 (51493) */ - 3343, /* C926 (51494) */ - 3343, /* C927 (51495) */ - 3343, /* C928 (51496) */ - 3343, /* C929 (51497) */ - 3343, /* C92A (51498) */ - 3343, /* C92B (51499) */ - 3343, /* C92C (51500) */ - 3343, /* C92D (51501) */ - 3343, /* C92E (51502) */ - 3343, /* C92F (51503) */ - 3343, /* C930 (51504) */ - 3343, /* C931 (51505) */ - 3343, /* C932 (51506) */ - 3343, /* C933 (51507) */ - 3343, /* C934 (51508) */ - 3343, /* C935 (51509) */ - 3343, /* C936 (51510) */ - 3343, /* C937 (51511) */ - 3343, /* C938 (51512) */ - 3343, /* C939 (51513) */ - 3343, /* C93A (51514) */ - 3343, /* C93B (51515) */ - 3343, /* C93C (51516) */ - 3343, /* C93D (51517) */ - 3343, /* C93E (51518) */ - 3343, /* C93F (51519) */ - 3343, /* C940 (51520) */ - 3343, /* C941 (51521) */ - 3343, /* C942 (51522) */ - 3343, /* C943 (51523) */ - 3343, /* C944 (51524) */ - 3343, /* C945 (51525) */ - 3343, /* C946 (51526) */ - 3343, /* C947 (51527) */ - 3343, /* C948 (51528) */ - 3343, /* C949 (51529) */ - 3343, /* C94A (51530) */ - 3343, /* C94B (51531) */ - 3343, /* C94C (51532) */ - 3343, /* C94D (51533) */ - 3343, /* C94E (51534) */ - 3343, /* C94F (51535) */ - 3343, /* C950 (51536) */ - 3343, /* C951 (51537) */ - 3343, /* C952 (51538) */ - 3343, /* C953 (51539) */ - 3343, /* C954 (51540) */ - 3343, /* C955 (51541) */ - 3343, /* C956 (51542) */ - 3343, /* C957 (51543) */ - 3343, /* C958 (51544) */ - 3343, /* C959 (51545) */ - 3343, /* C95A (51546) */ - 3343, /* C95B (51547) */ - 3343, /* C95C (51548) */ - 3343, /* C95D (51549) */ - 3343, /* C95E (51550) */ - 3343, /* C95F (51551) */ - 3343, /* C960 (51552) */ - 3343, /* C961 (51553) */ - 3343, /* C962 (51554) */ - 3343, /* C963 (51555) */ - 3343, /* C964 (51556) */ - 3343, /* C965 (51557) */ - 3343, /* C966 (51558) */ - 3343, /* C967 (51559) */ - 3343, /* C968 (51560) */ - 3343, /* C969 (51561) */ - 3343, /* C96A (51562) */ - 3343, /* C96B (51563) */ - 3343, /* C96C (51564) */ - 3343, /* C96D (51565) */ - 3343, /* C96E (51566) */ - 3343, /* C96F (51567) */ - 3343, /* C970 (51568) */ - 3343, /* C971 (51569) */ - 3343, /* C972 (51570) */ - 3343, /* C973 (51571) */ - 3343, /* C974 (51572) */ - 3343, /* C975 (51573) */ - 3343, /* C976 (51574) */ - 3343, /* C977 (51575) */ - 3343, /* C978 (51576) */ - 3343, /* C979 (51577) */ - 3343, /* C97A (51578) */ - 3343, /* C97B (51579) */ - 3343, /* C97C (51580) */ - 3343, /* C97D (51581) */ - 3343, /* C97E (51582) */ - 3343, /* C97F (51583) */ - 3343, /* C980 (51584) */ - 3343, /* C981 (51585) */ - 3343, /* C982 (51586) */ - 3343, /* C983 (51587) */ - 3343, /* C984 (51588) */ - 3343, /* C985 (51589) */ - 3343, /* C986 (51590) */ - 3343, /* C987 (51591) */ - 3343, /* C988 (51592) */ - 3343, /* C989 (51593) */ - 3343, /* C98A (51594) */ - 3343, /* C98B (51595) */ - 3343, /* C98C (51596) */ - 3343, /* C98D (51597) */ - 3343, /* C98E (51598) */ - 3343, /* C98F (51599) */ - 3343, /* C990 (51600) */ - 3343, /* C991 (51601) */ - 3343, /* C992 (51602) */ - 3343, /* C993 (51603) */ - 3343, /* C994 (51604) */ - 3343, /* C995 (51605) */ - 3343, /* C996 (51606) */ - 3343, /* C997 (51607) */ - 3343, /* C998 (51608) */ - 3343, /* C999 (51609) */ - 3343, /* C99A (51610) */ - 3343, /* C99B (51611) */ - 3343, /* C99C (51612) */ - 3343, /* C99D (51613) */ - 3343, /* C99E (51614) */ - 3343, /* C99F (51615) */ - 3343, /* C9A0 (51616) */ - 3343, /* C9A1 (51617) */ - 3343, /* C9A2 (51618) */ - 3343, /* C9A3 (51619) */ - 3343, /* C9A4 (51620) */ - 3343, /* C9A5 (51621) */ - 3343, /* C9A6 (51622) */ - 3343, /* C9A7 (51623) */ - 3343, /* C9A8 (51624) */ - 3343, /* C9A9 (51625) */ - 3343, /* C9AA (51626) */ - 3343, /* C9AB (51627) */ - 3343, /* C9AC (51628) */ - 3343, /* C9AD (51629) */ - 3343, /* C9AE (51630) */ - 3343, /* C9AF (51631) */ - 3343, /* C9B0 (51632) */ - 3343, /* C9B1 (51633) */ - 3343, /* C9B2 (51634) */ - 3343, /* C9B3 (51635) */ - 3343, /* C9B4 (51636) */ - 3343, /* C9B5 (51637) */ - 3343, /* C9B6 (51638) */ - 3343, /* C9B7 (51639) */ - 3343, /* C9B8 (51640) */ - 3343, /* C9B9 (51641) */ - 3343, /* C9BA (51642) */ - 3343, /* C9BB (51643) */ - 3343, /* C9BC (51644) */ - 3343, /* C9BD (51645) */ - 3343, /* C9BE (51646) */ - 3343, /* C9BF (51647) */ - 3343, /* C9C0 (51648) */ - 3343, /* C9C1 (51649) */ - 3343, /* C9C2 (51650) */ - 3343, /* C9C3 (51651) */ - 3343, /* C9C4 (51652) */ - 3343, /* C9C5 (51653) */ - 3343, /* C9C6 (51654) */ - 3343, /* C9C7 (51655) */ - 3343, /* C9C8 (51656) */ - 3343, /* C9C9 (51657) */ - 3343, /* C9CA (51658) */ - 3343, /* C9CB (51659) */ - 3343, /* C9CC (51660) */ - 3343, /* C9CD (51661) */ - 3343, /* C9CE (51662) */ - 3343, /* C9CF (51663) */ - 3343, /* C9D0 (51664) */ - 3343, /* C9D1 (51665) */ - 3343, /* C9D2 (51666) */ - 3343, /* C9D3 (51667) */ - 3343, /* C9D4 (51668) */ - 3343, /* C9D5 (51669) */ - 3343, /* C9D6 (51670) */ - 3343, /* C9D7 (51671) */ - 3343, /* C9D8 (51672) */ - 3343, /* C9D9 (51673) */ - 3343, /* C9DA (51674) */ - 3343, /* C9DB (51675) */ - 3343, /* C9DC (51676) */ - 3343, /* C9DD (51677) */ - 3343, /* C9DE (51678) */ - 3343, /* C9DF (51679) */ - 3343, /* C9E0 (51680) */ - 3343, /* C9E1 (51681) */ - 3343, /* C9E2 (51682) */ - 3343, /* C9E3 (51683) */ - 3343, /* C9E4 (51684) */ - 3343, /* C9E5 (51685) */ - 3343, /* C9E6 (51686) */ - 3343, /* C9E7 (51687) */ - 3343, /* C9E8 (51688) */ - 3343, /* C9E9 (51689) */ - 3343, /* C9EA (51690) */ - 3343, /* C9EB (51691) */ - 3343, /* C9EC (51692) */ - 3343, /* C9ED (51693) */ - 3343, /* C9EE (51694) */ - 3343, /* C9EF (51695) */ - 3343, /* C9F0 (51696) */ - 3343, /* C9F1 (51697) */ - 3343, /* C9F2 (51698) */ - 3343, /* C9F3 (51699) */ - 3343, /* C9F4 (51700) */ - 3343, /* C9F5 (51701) */ - 3343, /* C9F6 (51702) */ - 3343, /* C9F7 (51703) */ - 3343, /* C9F8 (51704) */ - 3343, /* C9F9 (51705) */ - 3343, /* C9FA (51706) */ - 3343, /* C9FB (51707) */ - 3343, /* C9FC (51708) */ - 3343, /* C9FD (51709) */ - 3343, /* C9FE (51710) */ - 3343, /* C9FF (51711) */ - 3343, /* CA00 (51712) */ - 3343, /* CA01 (51713) */ - 3343, /* CA02 (51714) */ - 3343, /* CA03 (51715) */ - 3343, /* CA04 (51716) */ - 3343, /* CA05 (51717) */ - 3343, /* CA06 (51718) */ - 3343, /* CA07 (51719) */ - 3343, /* CA08 (51720) */ - 3343, /* CA09 (51721) */ - 3343, /* CA0A (51722) */ - 3343, /* CA0B (51723) */ - 3343, /* CA0C (51724) */ - 3343, /* CA0D (51725) */ - 3343, /* CA0E (51726) */ - 3343, /* CA0F (51727) */ - 3343, /* CA10 (51728) */ - 3343, /* CA11 (51729) */ - 3343, /* CA12 (51730) */ - 3343, /* CA13 (51731) */ - 3343, /* CA14 (51732) */ - 3343, /* CA15 (51733) */ - 3343, /* CA16 (51734) */ - 3343, /* CA17 (51735) */ - 3343, /* CA18 (51736) */ - 3343, /* CA19 (51737) */ - 3343, /* CA1A (51738) */ - 3343, /* CA1B (51739) */ - 3343, /* CA1C (51740) */ - 3343, /* CA1D (51741) */ - 3343, /* CA1E (51742) */ - 3343, /* CA1F (51743) */ - 3343, /* CA20 (51744) */ - 3343, /* CA21 (51745) */ - 3343, /* CA22 (51746) */ - 3343, /* CA23 (51747) */ - 3343, /* CA24 (51748) */ - 3343, /* CA25 (51749) */ - 3343, /* CA26 (51750) */ - 3343, /* CA27 (51751) */ - 3343, /* CA28 (51752) */ - 3343, /* CA29 (51753) */ - 3343, /* CA2A (51754) */ - 3343, /* CA2B (51755) */ - 3343, /* CA2C (51756) */ - 3343, /* CA2D (51757) */ - 3343, /* CA2E (51758) */ - 3343, /* CA2F (51759) */ - 3343, /* CA30 (51760) */ - 3343, /* CA31 (51761) */ - 3343, /* CA32 (51762) */ - 3343, /* CA33 (51763) */ - 3343, /* CA34 (51764) */ - 3343, /* CA35 (51765) */ - 3343, /* CA36 (51766) */ - 3343, /* CA37 (51767) */ - 3343, /* CA38 (51768) */ - 3343, /* CA39 (51769) */ - 3343, /* CA3A (51770) */ - 3343, /* CA3B (51771) */ - 3343, /* CA3C (51772) */ - 3343, /* CA3D (51773) */ - 3343, /* CA3E (51774) */ - 3343, /* CA3F (51775) */ - 3343, /* CA40 (51776) */ - 3343, /* CA41 (51777) */ - 3343, /* CA42 (51778) */ - 3343, /* CA43 (51779) */ - 3343, /* CA44 (51780) */ - 3343, /* CA45 (51781) */ - 3343, /* CA46 (51782) */ - 3343, /* CA47 (51783) */ - 3343, /* CA48 (51784) */ - 3343, /* CA49 (51785) */ - 3343, /* CA4A (51786) */ - 3343, /* CA4B (51787) */ - 3343, /* CA4C (51788) */ - 3343, /* CA4D (51789) */ - 3343, /* CA4E (51790) */ - 3343, /* CA4F (51791) */ - 3343, /* CA50 (51792) */ - 3343, /* CA51 (51793) */ - 3343, /* CA52 (51794) */ - 3343, /* CA53 (51795) */ - 3343, /* CA54 (51796) */ - 3343, /* CA55 (51797) */ - 3343, /* CA56 (51798) */ - 3343, /* CA57 (51799) */ - 3343, /* CA58 (51800) */ - 3343, /* CA59 (51801) */ - 3343, /* CA5A (51802) */ - 3343, /* CA5B (51803) */ - 3343, /* CA5C (51804) */ - 3343, /* CA5D (51805) */ - 3343, /* CA5E (51806) */ - 3343, /* CA5F (51807) */ - 3343, /* CA60 (51808) */ - 3343, /* CA61 (51809) */ - 3343, /* CA62 (51810) */ - 3343, /* CA63 (51811) */ - 3343, /* CA64 (51812) */ - 3343, /* CA65 (51813) */ - 3343, /* CA66 (51814) */ - 3343, /* CA67 (51815) */ - 3343, /* CA68 (51816) */ - 3343, /* CA69 (51817) */ - 3343, /* CA6A (51818) */ - 3343, /* CA6B (51819) */ - 3343, /* CA6C (51820) */ - 3343, /* CA6D (51821) */ - 3343, /* CA6E (51822) */ - 3343, /* CA6F (51823) */ - 3343, /* CA70 (51824) */ - 3343, /* CA71 (51825) */ - 3343, /* CA72 (51826) */ - 3343, /* CA73 (51827) */ - 3343, /* CA74 (51828) */ - 3343, /* CA75 (51829) */ - 3343, /* CA76 (51830) */ - 3343, /* CA77 (51831) */ - 3343, /* CA78 (51832) */ - 3343, /* CA79 (51833) */ - 3343, /* CA7A (51834) */ - 3343, /* CA7B (51835) */ - 3343, /* CA7C (51836) */ - 3343, /* CA7D (51837) */ - 3343, /* CA7E (51838) */ - 3343, /* CA7F (51839) */ - 3343, /* CA80 (51840) */ - 3343, /* CA81 (51841) */ - 3343, /* CA82 (51842) */ - 3343, /* CA83 (51843) */ - 3343, /* CA84 (51844) */ - 3343, /* CA85 (51845) */ - 3343, /* CA86 (51846) */ - 3343, /* CA87 (51847) */ - 3343, /* CA88 (51848) */ - 3343, /* CA89 (51849) */ - 3343, /* CA8A (51850) */ - 3343, /* CA8B (51851) */ - 3343, /* CA8C (51852) */ - 3343, /* CA8D (51853) */ - 3343, /* CA8E (51854) */ - 3343, /* CA8F (51855) */ - 3343, /* CA90 (51856) */ - 3343, /* CA91 (51857) */ - 3343, /* CA92 (51858) */ - 3343, /* CA93 (51859) */ - 3343, /* CA94 (51860) */ - 3343, /* CA95 (51861) */ - 3343, /* CA96 (51862) */ - 3343, /* CA97 (51863) */ - 3343, /* CA98 (51864) */ - 3343, /* CA99 (51865) */ - 3343, /* CA9A (51866) */ - 3343, /* CA9B (51867) */ - 3343, /* CA9C (51868) */ - 3343, /* CA9D (51869) */ - 3343, /* CA9E (51870) */ - 3343, /* CA9F (51871) */ - 3343, /* CAA0 (51872) */ - 3343, /* CAA1 (51873) */ - 3343, /* CAA2 (51874) */ - 3343, /* CAA3 (51875) */ - 3343, /* CAA4 (51876) */ - 3343, /* CAA5 (51877) */ - 3343, /* CAA6 (51878) */ - 3343, /* CAA7 (51879) */ - 3343, /* CAA8 (51880) */ - 3343, /* CAA9 (51881) */ - 3343, /* CAAA (51882) */ - 3343, /* CAAB (51883) */ - 3343, /* CAAC (51884) */ - 3343, /* CAAD (51885) */ - 3343, /* CAAE (51886) */ - 3343, /* CAAF (51887) */ - 3343, /* CAB0 (51888) */ - 3343, /* CAB1 (51889) */ - 3343, /* CAB2 (51890) */ - 3343, /* CAB3 (51891) */ - 3343, /* CAB4 (51892) */ - 3343, /* CAB5 (51893) */ - 3343, /* CAB6 (51894) */ - 3343, /* CAB7 (51895) */ - 3343, /* CAB8 (51896) */ - 3343, /* CAB9 (51897) */ - 3343, /* CABA (51898) */ - 3343, /* CABB (51899) */ - 3343, /* CABC (51900) */ - 3343, /* CABD (51901) */ - 3343, /* CABE (51902) */ - 3343, /* CABF (51903) */ - 3343, /* CAC0 (51904) */ - 3343, /* CAC1 (51905) */ - 3343, /* CAC2 (51906) */ - 3343, /* CAC3 (51907) */ - 3343, /* CAC4 (51908) */ - 3343, /* CAC5 (51909) */ - 3343, /* CAC6 (51910) */ - 3343, /* CAC7 (51911) */ - 3343, /* CAC8 (51912) */ - 3343, /* CAC9 (51913) */ - 3343, /* CACA (51914) */ - 3343, /* CACB (51915) */ - 3343, /* CACC (51916) */ - 3343, /* CACD (51917) */ - 3343, /* CACE (51918) */ - 3343, /* CACF (51919) */ - 3343, /* CAD0 (51920) */ - 3343, /* CAD1 (51921) */ - 3343, /* CAD2 (51922) */ - 3343, /* CAD3 (51923) */ - 3343, /* CAD4 (51924) */ - 3343, /* CAD5 (51925) */ - 3343, /* CAD6 (51926) */ - 3343, /* CAD7 (51927) */ - 3343, /* CAD8 (51928) */ - 3343, /* CAD9 (51929) */ - 3343, /* CADA (51930) */ - 3343, /* CADB (51931) */ - 3343, /* CADC (51932) */ - 3343, /* CADD (51933) */ - 3343, /* CADE (51934) */ - 3343, /* CADF (51935) */ - 3343, /* CAE0 (51936) */ - 3343, /* CAE1 (51937) */ - 3343, /* CAE2 (51938) */ - 3343, /* CAE3 (51939) */ - 3343, /* CAE4 (51940) */ - 3343, /* CAE5 (51941) */ - 3343, /* CAE6 (51942) */ - 3343, /* CAE7 (51943) */ - 3343, /* CAE8 (51944) */ - 3343, /* CAE9 (51945) */ - 3343, /* CAEA (51946) */ - 3343, /* CAEB (51947) */ - 3343, /* CAEC (51948) */ - 3343, /* CAED (51949) */ - 3343, /* CAEE (51950) */ - 3343, /* CAEF (51951) */ - 3343, /* CAF0 (51952) */ - 3343, /* CAF1 (51953) */ - 3343, /* CAF2 (51954) */ - 3343, /* CAF3 (51955) */ - 3343, /* CAF4 (51956) */ - 3343, /* CAF5 (51957) */ - 3343, /* CAF6 (51958) */ - 3343, /* CAF7 (51959) */ - 3343, /* CAF8 (51960) */ - 3343, /* CAF9 (51961) */ - 3343, /* CAFA (51962) */ - 3343, /* CAFB (51963) */ - 3343, /* CAFC (51964) */ - 3343, /* CAFD (51965) */ - 3343, /* CAFE (51966) */ - 3343, /* CAFF (51967) */ - 3343, /* CB00 (51968) */ - 3343, /* CB01 (51969) */ - 3343, /* CB02 (51970) */ - 3343, /* CB03 (51971) */ - 3343, /* CB04 (51972) */ - 3343, /* CB05 (51973) */ - 3343, /* CB06 (51974) */ - 3343, /* CB07 (51975) */ - 3343, /* CB08 (51976) */ - 3343, /* CB09 (51977) */ - 3343, /* CB0A (51978) */ - 3343, /* CB0B (51979) */ - 3343, /* CB0C (51980) */ - 3343, /* CB0D (51981) */ - 3343, /* CB0E (51982) */ - 3343, /* CB0F (51983) */ - 3343, /* CB10 (51984) */ - 3343, /* CB11 (51985) */ - 3343, /* CB12 (51986) */ - 3343, /* CB13 (51987) */ - 3343, /* CB14 (51988) */ - 3343, /* CB15 (51989) */ - 3343, /* CB16 (51990) */ - 3343, /* CB17 (51991) */ - 3343, /* CB18 (51992) */ - 3343, /* CB19 (51993) */ - 3343, /* CB1A (51994) */ - 3343, /* CB1B (51995) */ - 3343, /* CB1C (51996) */ - 3343, /* CB1D (51997) */ - 3343, /* CB1E (51998) */ - 3343, /* CB1F (51999) */ - 3343, /* CB20 (52000) */ - 3343, /* CB21 (52001) */ - 3343, /* CB22 (52002) */ - 3343, /* CB23 (52003) */ - 3343, /* CB24 (52004) */ - 3343, /* CB25 (52005) */ - 3343, /* CB26 (52006) */ - 3343, /* CB27 (52007) */ - 3343, /* CB28 (52008) */ - 3343, /* CB29 (52009) */ - 3343, /* CB2A (52010) */ - 3343, /* CB2B (52011) */ - 3343, /* CB2C (52012) */ - 3343, /* CB2D (52013) */ - 3343, /* CB2E (52014) */ - 3343, /* CB2F (52015) */ - 3343, /* CB30 (52016) */ - 3343, /* CB31 (52017) */ - 3343, /* CB32 (52018) */ - 3343, /* CB33 (52019) */ - 3343, /* CB34 (52020) */ - 3343, /* CB35 (52021) */ - 3343, /* CB36 (52022) */ - 3343, /* CB37 (52023) */ - 3343, /* CB38 (52024) */ - 3343, /* CB39 (52025) */ - 3343, /* CB3A (52026) */ - 3343, /* CB3B (52027) */ - 3343, /* CB3C (52028) */ - 3343, /* CB3D (52029) */ - 3343, /* CB3E (52030) */ - 3343, /* CB3F (52031) */ - 3343, /* CB40 (52032) */ - 3343, /* CB41 (52033) */ - 3343, /* CB42 (52034) */ - 3343, /* CB43 (52035) */ - 3343, /* CB44 (52036) */ - 3343, /* CB45 (52037) */ - 3343, /* CB46 (52038) */ - 3343, /* CB47 (52039) */ - 3343, /* CB48 (52040) */ - 3343, /* CB49 (52041) */ - 3343, /* CB4A (52042) */ - 3343, /* CB4B (52043) */ - 3343, /* CB4C (52044) */ - 3343, /* CB4D (52045) */ - 3343, /* CB4E (52046) */ - 3343, /* CB4F (52047) */ - 3343, /* CB50 (52048) */ - 3343, /* CB51 (52049) */ - 3343, /* CB52 (52050) */ - 3343, /* CB53 (52051) */ - 3343, /* CB54 (52052) */ - 3343, /* CB55 (52053) */ - 3343, /* CB56 (52054) */ - 3343, /* CB57 (52055) */ - 3343, /* CB58 (52056) */ - 3343, /* CB59 (52057) */ - 3343, /* CB5A (52058) */ - 3343, /* CB5B (52059) */ - 3343, /* CB5C (52060) */ - 3343, /* CB5D (52061) */ - 3343, /* CB5E (52062) */ - 3343, /* CB5F (52063) */ - 3343, /* CB60 (52064) */ - 3343, /* CB61 (52065) */ - 3343, /* CB62 (52066) */ - 3343, /* CB63 (52067) */ - 3343, /* CB64 (52068) */ - 3343, /* CB65 (52069) */ - 3343, /* CB66 (52070) */ - 3343, /* CB67 (52071) */ - 3343, /* CB68 (52072) */ - 3343, /* CB69 (52073) */ - 3343, /* CB6A (52074) */ - 3343, /* CB6B (52075) */ - 3343, /* CB6C (52076) */ - 3343, /* CB6D (52077) */ - 3343, /* CB6E (52078) */ - 3343, /* CB6F (52079) */ - 3343, /* CB70 (52080) */ - 3343, /* CB71 (52081) */ - 3343, /* CB72 (52082) */ - 3343, /* CB73 (52083) */ - 3343, /* CB74 (52084) */ - 3343, /* CB75 (52085) */ - 3343, /* CB76 (52086) */ - 3343, /* CB77 (52087) */ - 3343, /* CB78 (52088) */ - 3343, /* CB79 (52089) */ - 3343, /* CB7A (52090) */ - 3343, /* CB7B (52091) */ - 3343, /* CB7C (52092) */ - 3343, /* CB7D (52093) */ - 3343, /* CB7E (52094) */ - 3343, /* CB7F (52095) */ - 3343, /* CB80 (52096) */ - 3343, /* CB81 (52097) */ - 3343, /* CB82 (52098) */ - 3343, /* CB83 (52099) */ - 3343, /* CB84 (52100) */ - 3343, /* CB85 (52101) */ - 3343, /* CB86 (52102) */ - 3343, /* CB87 (52103) */ - 3343, /* CB88 (52104) */ - 3343, /* CB89 (52105) */ - 3343, /* CB8A (52106) */ - 3343, /* CB8B (52107) */ - 3343, /* CB8C (52108) */ - 3343, /* CB8D (52109) */ - 3343, /* CB8E (52110) */ - 3343, /* CB8F (52111) */ - 3343, /* CB90 (52112) */ - 3343, /* CB91 (52113) */ - 3343, /* CB92 (52114) */ - 3343, /* CB93 (52115) */ - 3343, /* CB94 (52116) */ - 3343, /* CB95 (52117) */ - 3343, /* CB96 (52118) */ - 3343, /* CB97 (52119) */ - 3343, /* CB98 (52120) */ - 3343, /* CB99 (52121) */ - 3343, /* CB9A (52122) */ - 3343, /* CB9B (52123) */ - 3343, /* CB9C (52124) */ - 3343, /* CB9D (52125) */ - 3343, /* CB9E (52126) */ - 3343, /* CB9F (52127) */ - 3343, /* CBA0 (52128) */ - 3343, /* CBA1 (52129) */ - 3343, /* CBA2 (52130) */ - 3343, /* CBA3 (52131) */ - 3343, /* CBA4 (52132) */ - 3343, /* CBA5 (52133) */ - 3343, /* CBA6 (52134) */ - 3343, /* CBA7 (52135) */ - 3343, /* CBA8 (52136) */ - 3343, /* CBA9 (52137) */ - 3343, /* CBAA (52138) */ - 3343, /* CBAB (52139) */ - 3343, /* CBAC (52140) */ - 3343, /* CBAD (52141) */ - 3343, /* CBAE (52142) */ - 3343, /* CBAF (52143) */ - 3343, /* CBB0 (52144) */ - 3343, /* CBB1 (52145) */ - 3343, /* CBB2 (52146) */ - 3343, /* CBB3 (52147) */ - 3343, /* CBB4 (52148) */ - 3343, /* CBB5 (52149) */ - 3343, /* CBB6 (52150) */ - 3343, /* CBB7 (52151) */ - 3343, /* CBB8 (52152) */ - 3343, /* CBB9 (52153) */ - 3343, /* CBBA (52154) */ - 3343, /* CBBB (52155) */ - 3343, /* CBBC (52156) */ - 3343, /* CBBD (52157) */ - 3343, /* CBBE (52158) */ - 3343, /* CBBF (52159) */ - 3343, /* CBC0 (52160) */ - 3343, /* CBC1 (52161) */ - 3343, /* CBC2 (52162) */ - 3343, /* CBC3 (52163) */ - 3343, /* CBC4 (52164) */ - 3343, /* CBC5 (52165) */ - 3343, /* CBC6 (52166) */ - 3343, /* CBC7 (52167) */ - 3343, /* CBC8 (52168) */ - 3343, /* CBC9 (52169) */ - 3343, /* CBCA (52170) */ - 3343, /* CBCB (52171) */ - 3343, /* CBCC (52172) */ - 3343, /* CBCD (52173) */ - 3343, /* CBCE (52174) */ - 3343, /* CBCF (52175) */ - 3343, /* CBD0 (52176) */ - 3343, /* CBD1 (52177) */ - 3343, /* CBD2 (52178) */ - 3343, /* CBD3 (52179) */ - 3343, /* CBD4 (52180) */ - 3343, /* CBD5 (52181) */ - 3343, /* CBD6 (52182) */ - 3343, /* CBD7 (52183) */ - 3343, /* CBD8 (52184) */ - 3343, /* CBD9 (52185) */ - 3343, /* CBDA (52186) */ - 3343, /* CBDB (52187) */ - 3343, /* CBDC (52188) */ - 3343, /* CBDD (52189) */ - 3343, /* CBDE (52190) */ - 3343, /* CBDF (52191) */ - 3343, /* CBE0 (52192) */ - 3343, /* CBE1 (52193) */ - 3343, /* CBE2 (52194) */ - 3343, /* CBE3 (52195) */ - 3343, /* CBE4 (52196) */ - 3343, /* CBE5 (52197) */ - 3343, /* CBE6 (52198) */ - 3343, /* CBE7 (52199) */ - 3343, /* CBE8 (52200) */ - 3343, /* CBE9 (52201) */ - 3343, /* CBEA (52202) */ - 3343, /* CBEB (52203) */ - 3343, /* CBEC (52204) */ - 3343, /* CBED (52205) */ - 3343, /* CBEE (52206) */ - 3343, /* CBEF (52207) */ - 3343, /* CBF0 (52208) */ - 3343, /* CBF1 (52209) */ - 3343, /* CBF2 (52210) */ - 3343, /* CBF3 (52211) */ - 3343, /* CBF4 (52212) */ - 3343, /* CBF5 (52213) */ - 3343, /* CBF6 (52214) */ - 3343, /* CBF7 (52215) */ - 3343, /* CBF8 (52216) */ - 3343, /* CBF9 (52217) */ - 3343, /* CBFA (52218) */ - 3343, /* CBFB (52219) */ - 3343, /* CBFC (52220) */ - 3343, /* CBFD (52221) */ - 3343, /* CBFE (52222) */ - 3343, /* CBFF (52223) */ - 3343, /* CC00 (52224) */ - 3343, /* CC01 (52225) */ - 3343, /* CC02 (52226) */ - 3343, /* CC03 (52227) */ - 3343, /* CC04 (52228) */ - 3343, /* CC05 (52229) */ - 3343, /* CC06 (52230) */ - 3343, /* CC07 (52231) */ - 3343, /* CC08 (52232) */ - 3343, /* CC09 (52233) */ - 3343, /* CC0A (52234) */ - 3343, /* CC0B (52235) */ - 3343, /* CC0C (52236) */ - 3343, /* CC0D (52237) */ - 3343, /* CC0E (52238) */ - 3343, /* CC0F (52239) */ - 3343, /* CC10 (52240) */ - 3343, /* CC11 (52241) */ - 3343, /* CC12 (52242) */ - 3343, /* CC13 (52243) */ - 3343, /* CC14 (52244) */ - 3343, /* CC15 (52245) */ - 3343, /* CC16 (52246) */ - 3343, /* CC17 (52247) */ - 3343, /* CC18 (52248) */ - 3343, /* CC19 (52249) */ - 3343, /* CC1A (52250) */ - 3343, /* CC1B (52251) */ - 3343, /* CC1C (52252) */ - 3343, /* CC1D (52253) */ - 3343, /* CC1E (52254) */ - 3343, /* CC1F (52255) */ - 3343, /* CC20 (52256) */ - 3343, /* CC21 (52257) */ - 3343, /* CC22 (52258) */ - 3343, /* CC23 (52259) */ - 3343, /* CC24 (52260) */ - 3343, /* CC25 (52261) */ - 3343, /* CC26 (52262) */ - 3343, /* CC27 (52263) */ - 3343, /* CC28 (52264) */ - 3343, /* CC29 (52265) */ - 3343, /* CC2A (52266) */ - 3343, /* CC2B (52267) */ - 3343, /* CC2C (52268) */ - 3343, /* CC2D (52269) */ - 3343, /* CC2E (52270) */ - 3343, /* CC2F (52271) */ - 3343, /* CC30 (52272) */ - 3343, /* CC31 (52273) */ - 3343, /* CC32 (52274) */ - 3343, /* CC33 (52275) */ - 3343, /* CC34 (52276) */ - 3343, /* CC35 (52277) */ - 3343, /* CC36 (52278) */ - 3343, /* CC37 (52279) */ - 3343, /* CC38 (52280) */ - 3343, /* CC39 (52281) */ - 3343, /* CC3A (52282) */ - 3343, /* CC3B (52283) */ - 3343, /* CC3C (52284) */ - 3343, /* CC3D (52285) */ - 3343, /* CC3E (52286) */ - 3343, /* CC3F (52287) */ - 3343, /* CC40 (52288) */ - 3343, /* CC41 (52289) */ - 3343, /* CC42 (52290) */ - 3343, /* CC43 (52291) */ - 3343, /* CC44 (52292) */ - 3343, /* CC45 (52293) */ - 3343, /* CC46 (52294) */ - 3343, /* CC47 (52295) */ - 3343, /* CC48 (52296) */ - 3343, /* CC49 (52297) */ - 3343, /* CC4A (52298) */ - 3343, /* CC4B (52299) */ - 3343, /* CC4C (52300) */ - 3343, /* CC4D (52301) */ - 3343, /* CC4E (52302) */ - 3343, /* CC4F (52303) */ - 3343, /* CC50 (52304) */ - 3343, /* CC51 (52305) */ - 3343, /* CC52 (52306) */ - 3343, /* CC53 (52307) */ - 3343, /* CC54 (52308) */ - 3343, /* CC55 (52309) */ - 3343, /* CC56 (52310) */ - 3343, /* CC57 (52311) */ - 3343, /* CC58 (52312) */ - 3343, /* CC59 (52313) */ - 3343, /* CC5A (52314) */ - 3343, /* CC5B (52315) */ - 3343, /* CC5C (52316) */ - 3343, /* CC5D (52317) */ - 3343, /* CC5E (52318) */ - 3343, /* CC5F (52319) */ - 3343, /* CC60 (52320) */ - 3343, /* CC61 (52321) */ - 3343, /* CC62 (52322) */ - 3343, /* CC63 (52323) */ - 3343, /* CC64 (52324) */ - 3343, /* CC65 (52325) */ - 3343, /* CC66 (52326) */ - 3343, /* CC67 (52327) */ - 3343, /* CC68 (52328) */ - 3343, /* CC69 (52329) */ - 3343, /* CC6A (52330) */ - 3343, /* CC6B (52331) */ - 3343, /* CC6C (52332) */ - 3343, /* CC6D (52333) */ - 3343, /* CC6E (52334) */ - 3343, /* CC6F (52335) */ - 3343, /* CC70 (52336) */ - 3343, /* CC71 (52337) */ - 3343, /* CC72 (52338) */ - 3343, /* CC73 (52339) */ - 3343, /* CC74 (52340) */ - 3343, /* CC75 (52341) */ - 3343, /* CC76 (52342) */ - 3343, /* CC77 (52343) */ - 3343, /* CC78 (52344) */ - 3343, /* CC79 (52345) */ - 3343, /* CC7A (52346) */ - 3343, /* CC7B (52347) */ - 3343, /* CC7C (52348) */ - 3343, /* CC7D (52349) */ - 3343, /* CC7E (52350) */ - 3343, /* CC7F (52351) */ - 3343, /* CC80 (52352) */ - 3343, /* CC81 (52353) */ - 3343, /* CC82 (52354) */ - 3343, /* CC83 (52355) */ - 3343, /* CC84 (52356) */ - 3343, /* CC85 (52357) */ - 3343, /* CC86 (52358) */ - 3343, /* CC87 (52359) */ - 3343, /* CC88 (52360) */ - 3343, /* CC89 (52361) */ - 3343, /* CC8A (52362) */ - 3343, /* CC8B (52363) */ - 3343, /* CC8C (52364) */ - 3343, /* CC8D (52365) */ - 3343, /* CC8E (52366) */ - 3343, /* CC8F (52367) */ - 3343, /* CC90 (52368) */ - 3343, /* CC91 (52369) */ - 3343, /* CC92 (52370) */ - 3343, /* CC93 (52371) */ - 3343, /* CC94 (52372) */ - 3343, /* CC95 (52373) */ - 3343, /* CC96 (52374) */ - 3343, /* CC97 (52375) */ - 3343, /* CC98 (52376) */ - 3343, /* CC99 (52377) */ - 3343, /* CC9A (52378) */ - 3343, /* CC9B (52379) */ - 3343, /* CC9C (52380) */ - 3343, /* CC9D (52381) */ - 3343, /* CC9E (52382) */ - 3343, /* CC9F (52383) */ - 3343, /* CCA0 (52384) */ - 3343, /* CCA1 (52385) */ - 3343, /* CCA2 (52386) */ - 3343, /* CCA3 (52387) */ - 3343, /* CCA4 (52388) */ - 3343, /* CCA5 (52389) */ - 3343, /* CCA6 (52390) */ - 3343, /* CCA7 (52391) */ - 3343, /* CCA8 (52392) */ - 3343, /* CCA9 (52393) */ - 3343, /* CCAA (52394) */ - 3343, /* CCAB (52395) */ - 3343, /* CCAC (52396) */ - 3343, /* CCAD (52397) */ - 3343, /* CCAE (52398) */ - 3343, /* CCAF (52399) */ - 3343, /* CCB0 (52400) */ - 3343, /* CCB1 (52401) */ - 3343, /* CCB2 (52402) */ - 3343, /* CCB3 (52403) */ - 3343, /* CCB4 (52404) */ - 3343, /* CCB5 (52405) */ - 3343, /* CCB6 (52406) */ - 3343, /* CCB7 (52407) */ - 3343, /* CCB8 (52408) */ - 3343, /* CCB9 (52409) */ - 3343, /* CCBA (52410) */ - 3343, /* CCBB (52411) */ - 3343, /* CCBC (52412) */ - 3343, /* CCBD (52413) */ - 3343, /* CCBE (52414) */ - 3343, /* CCBF (52415) */ - 3343, /* CCC0 (52416) */ - 3343, /* CCC1 (52417) */ - 3343, /* CCC2 (52418) */ - 3343, /* CCC3 (52419) */ - 3343, /* CCC4 (52420) */ - 3343, /* CCC5 (52421) */ - 3343, /* CCC6 (52422) */ - 3343, /* CCC7 (52423) */ - 3343, /* CCC8 (52424) */ - 3343, /* CCC9 (52425) */ - 3343, /* CCCA (52426) */ - 3343, /* CCCB (52427) */ - 3343, /* CCCC (52428) */ - 3343, /* CCCD (52429) */ - 3343, /* CCCE (52430) */ - 3343, /* CCCF (52431) */ - 3343, /* CCD0 (52432) */ - 3343, /* CCD1 (52433) */ - 3343, /* CCD2 (52434) */ - 3343, /* CCD3 (52435) */ - 3343, /* CCD4 (52436) */ - 3343, /* CCD5 (52437) */ - 3343, /* CCD6 (52438) */ - 3343, /* CCD7 (52439) */ - 3343, /* CCD8 (52440) */ - 3343, /* CCD9 (52441) */ - 3343, /* CCDA (52442) */ - 3343, /* CCDB (52443) */ - 3343, /* CCDC (52444) */ - 3343, /* CCDD (52445) */ - 3343, /* CCDE (52446) */ - 3343, /* CCDF (52447) */ - 3343, /* CCE0 (52448) */ - 3343, /* CCE1 (52449) */ - 3343, /* CCE2 (52450) */ - 3343, /* CCE3 (52451) */ - 3343, /* CCE4 (52452) */ - 3343, /* CCE5 (52453) */ - 3343, /* CCE6 (52454) */ - 3343, /* CCE7 (52455) */ - 3343, /* CCE8 (52456) */ - 3343, /* CCE9 (52457) */ - 3343, /* CCEA (52458) */ - 3343, /* CCEB (52459) */ - 3343, /* CCEC (52460) */ - 3343, /* CCED (52461) */ - 3343, /* CCEE (52462) */ - 3343, /* CCEF (52463) */ - 3343, /* CCF0 (52464) */ - 3343, /* CCF1 (52465) */ - 3343, /* CCF2 (52466) */ - 3343, /* CCF3 (52467) */ - 3343, /* CCF4 (52468) */ - 3343, /* CCF5 (52469) */ - 3343, /* CCF6 (52470) */ - 3343, /* CCF7 (52471) */ - 3343, /* CCF8 (52472) */ - 3343, /* CCF9 (52473) */ - 3343, /* CCFA (52474) */ - 3343, /* CCFB (52475) */ - 3343, /* CCFC (52476) */ - 3343, /* CCFD (52477) */ - 3343, /* CCFE (52478) */ - 3343, /* CCFF (52479) */ - 3343, /* CD00 (52480) */ - 3343, /* CD01 (52481) */ - 3343, /* CD02 (52482) */ - 3343, /* CD03 (52483) */ - 3343, /* CD04 (52484) */ - 3343, /* CD05 (52485) */ - 3343, /* CD06 (52486) */ - 3343, /* CD07 (52487) */ - 3343, /* CD08 (52488) */ - 3343, /* CD09 (52489) */ - 3343, /* CD0A (52490) */ - 3343, /* CD0B (52491) */ - 3343, /* CD0C (52492) */ - 3343, /* CD0D (52493) */ - 3343, /* CD0E (52494) */ - 3343, /* CD0F (52495) */ - 3343, /* CD10 (52496) */ - 3343, /* CD11 (52497) */ - 3343, /* CD12 (52498) */ - 3343, /* CD13 (52499) */ - 3343, /* CD14 (52500) */ - 3343, /* CD15 (52501) */ - 3343, /* CD16 (52502) */ - 3343, /* CD17 (52503) */ - 3343, /* CD18 (52504) */ - 3343, /* CD19 (52505) */ - 3343, /* CD1A (52506) */ - 3343, /* CD1B (52507) */ - 3343, /* CD1C (52508) */ - 3343, /* CD1D (52509) */ - 3343, /* CD1E (52510) */ - 3343, /* CD1F (52511) */ - 3343, /* CD20 (52512) */ - 3343, /* CD21 (52513) */ - 3343, /* CD22 (52514) */ - 3343, /* CD23 (52515) */ - 3343, /* CD24 (52516) */ - 3343, /* CD25 (52517) */ - 3343, /* CD26 (52518) */ - 3343, /* CD27 (52519) */ - 3343, /* CD28 (52520) */ - 3343, /* CD29 (52521) */ - 3343, /* CD2A (52522) */ - 3343, /* CD2B (52523) */ - 3343, /* CD2C (52524) */ - 3343, /* CD2D (52525) */ - 3343, /* CD2E (52526) */ - 3343, /* CD2F (52527) */ - 3343, /* CD30 (52528) */ - 3343, /* CD31 (52529) */ - 3343, /* CD32 (52530) */ - 3343, /* CD33 (52531) */ - 3343, /* CD34 (52532) */ - 3343, /* CD35 (52533) */ - 3343, /* CD36 (52534) */ - 3343, /* CD37 (52535) */ - 3343, /* CD38 (52536) */ - 3343, /* CD39 (52537) */ - 3343, /* CD3A (52538) */ - 3343, /* CD3B (52539) */ - 3343, /* CD3C (52540) */ - 3343, /* CD3D (52541) */ - 3343, /* CD3E (52542) */ - 3343, /* CD3F (52543) */ - 3343, /* CD40 (52544) */ - 3343, /* CD41 (52545) */ - 3343, /* CD42 (52546) */ - 3343, /* CD43 (52547) */ - 3343, /* CD44 (52548) */ - 3343, /* CD45 (52549) */ - 3343, /* CD46 (52550) */ - 3343, /* CD47 (52551) */ - 3343, /* CD48 (52552) */ - 3343, /* CD49 (52553) */ - 3343, /* CD4A (52554) */ - 3343, /* CD4B (52555) */ - 3343, /* CD4C (52556) */ - 3343, /* CD4D (52557) */ - 3343, /* CD4E (52558) */ - 3343, /* CD4F (52559) */ - 3343, /* CD50 (52560) */ - 3343, /* CD51 (52561) */ - 3343, /* CD52 (52562) */ - 3343, /* CD53 (52563) */ - 3343, /* CD54 (52564) */ - 3343, /* CD55 (52565) */ - 3343, /* CD56 (52566) */ - 3343, /* CD57 (52567) */ - 3343, /* CD58 (52568) */ - 3343, /* CD59 (52569) */ - 3343, /* CD5A (52570) */ - 3343, /* CD5B (52571) */ - 3343, /* CD5C (52572) */ - 3343, /* CD5D (52573) */ - 3343, /* CD5E (52574) */ - 3343, /* CD5F (52575) */ - 3343, /* CD60 (52576) */ - 3343, /* CD61 (52577) */ - 3343, /* CD62 (52578) */ - 3343, /* CD63 (52579) */ - 3343, /* CD64 (52580) */ - 3343, /* CD65 (52581) */ - 3343, /* CD66 (52582) */ - 3343, /* CD67 (52583) */ - 3343, /* CD68 (52584) */ - 3343, /* CD69 (52585) */ - 3343, /* CD6A (52586) */ - 3343, /* CD6B (52587) */ - 3343, /* CD6C (52588) */ - 3343, /* CD6D (52589) */ - 3343, /* CD6E (52590) */ - 3343, /* CD6F (52591) */ - 3343, /* CD70 (52592) */ - 3343, /* CD71 (52593) */ - 3343, /* CD72 (52594) */ - 3343, /* CD73 (52595) */ - 3343, /* CD74 (52596) */ - 3343, /* CD75 (52597) */ - 3343, /* CD76 (52598) */ - 3343, /* CD77 (52599) */ - 3343, /* CD78 (52600) */ - 3343, /* CD79 (52601) */ - 3343, /* CD7A (52602) */ - 3343, /* CD7B (52603) */ - 3343, /* CD7C (52604) */ - 3343, /* CD7D (52605) */ - 3343, /* CD7E (52606) */ - 3343, /* CD7F (52607) */ - 3343, /* CD80 (52608) */ - 3343, /* CD81 (52609) */ - 3343, /* CD82 (52610) */ - 3343, /* CD83 (52611) */ - 3343, /* CD84 (52612) */ - 3343, /* CD85 (52613) */ - 3343, /* CD86 (52614) */ - 3343, /* CD87 (52615) */ - 3343, /* CD88 (52616) */ - 3343, /* CD89 (52617) */ - 3343, /* CD8A (52618) */ - 3343, /* CD8B (52619) */ - 3343, /* CD8C (52620) */ - 3343, /* CD8D (52621) */ - 3343, /* CD8E (52622) */ - 3343, /* CD8F (52623) */ - 3343, /* CD90 (52624) */ - 3343, /* CD91 (52625) */ - 3343, /* CD92 (52626) */ - 3343, /* CD93 (52627) */ - 3343, /* CD94 (52628) */ - 3343, /* CD95 (52629) */ - 3343, /* CD96 (52630) */ - 3343, /* CD97 (52631) */ - 3343, /* CD98 (52632) */ - 3343, /* CD99 (52633) */ - 3343, /* CD9A (52634) */ - 3343, /* CD9B (52635) */ - 3343, /* CD9C (52636) */ - 3343, /* CD9D (52637) */ - 3343, /* CD9E (52638) */ - 3343, /* CD9F (52639) */ - 3343, /* CDA0 (52640) */ - 3343, /* CDA1 (52641) */ - 3343, /* CDA2 (52642) */ - 3343, /* CDA3 (52643) */ - 3343, /* CDA4 (52644) */ - 3343, /* CDA5 (52645) */ - 3343, /* CDA6 (52646) */ - 3343, /* CDA7 (52647) */ - 3343, /* CDA8 (52648) */ - 3343, /* CDA9 (52649) */ - 3343, /* CDAA (52650) */ - 3343, /* CDAB (52651) */ - 3343, /* CDAC (52652) */ - 3343, /* CDAD (52653) */ - 3343, /* CDAE (52654) */ - 3343, /* CDAF (52655) */ - 3343, /* CDB0 (52656) */ - 3343, /* CDB1 (52657) */ - 3343, /* CDB2 (52658) */ - 3343, /* CDB3 (52659) */ - 3343, /* CDB4 (52660) */ - 3343, /* CDB5 (52661) */ - 3343, /* CDB6 (52662) */ - 3343, /* CDB7 (52663) */ - 3343, /* CDB8 (52664) */ - 3343, /* CDB9 (52665) */ - 3343, /* CDBA (52666) */ - 3343, /* CDBB (52667) */ - 3343, /* CDBC (52668) */ - 3343, /* CDBD (52669) */ - 3343, /* CDBE (52670) */ - 3343, /* CDBF (52671) */ - 3343, /* CDC0 (52672) */ - 3343, /* CDC1 (52673) */ - 3343, /* CDC2 (52674) */ - 3343, /* CDC3 (52675) */ - 3343, /* CDC4 (52676) */ - 3343, /* CDC5 (52677) */ - 3343, /* CDC6 (52678) */ - 3343, /* CDC7 (52679) */ - 3343, /* CDC8 (52680) */ - 3343, /* CDC9 (52681) */ - 3343, /* CDCA (52682) */ - 3343, /* CDCB (52683) */ - 3343, /* CDCC (52684) */ - 3343, /* CDCD (52685) */ - 3343, /* CDCE (52686) */ - 3343, /* CDCF (52687) */ - 3343, /* CDD0 (52688) */ - 3343, /* CDD1 (52689) */ - 3343, /* CDD2 (52690) */ - 3343, /* CDD3 (52691) */ - 3343, /* CDD4 (52692) */ - 3343, /* CDD5 (52693) */ - 3343, /* CDD6 (52694) */ - 3343, /* CDD7 (52695) */ - 3343, /* CDD8 (52696) */ - 3343, /* CDD9 (52697) */ - 3343, /* CDDA (52698) */ - 3343, /* CDDB (52699) */ - 3343, /* CDDC (52700) */ - 3343, /* CDDD (52701) */ - 3343, /* CDDE (52702) */ - 3343, /* CDDF (52703) */ - 3343, /* CDE0 (52704) */ - 3343, /* CDE1 (52705) */ - 3343, /* CDE2 (52706) */ - 3343, /* CDE3 (52707) */ - 3343, /* CDE4 (52708) */ - 3343, /* CDE5 (52709) */ - 3343, /* CDE6 (52710) */ - 3343, /* CDE7 (52711) */ - 3343, /* CDE8 (52712) */ - 3343, /* CDE9 (52713) */ - 3343, /* CDEA (52714) */ - 3343, /* CDEB (52715) */ - 3343, /* CDEC (52716) */ - 3343, /* CDED (52717) */ - 3343, /* CDEE (52718) */ - 3343, /* CDEF (52719) */ - 3343, /* CDF0 (52720) */ - 3343, /* CDF1 (52721) */ - 3343, /* CDF2 (52722) */ - 3343, /* CDF3 (52723) */ - 3343, /* CDF4 (52724) */ - 3343, /* CDF5 (52725) */ - 3343, /* CDF6 (52726) */ - 3343, /* CDF7 (52727) */ - 3343, /* CDF8 (52728) */ - 3343, /* CDF9 (52729) */ - 3343, /* CDFA (52730) */ - 3343, /* CDFB (52731) */ - 3343, /* CDFC (52732) */ - 3343, /* CDFD (52733) */ - 3343, /* CDFE (52734) */ - 3343, /* CDFF (52735) */ - 3343, /* CE00 (52736) */ - 3343, /* CE01 (52737) */ - 3343, /* CE02 (52738) */ - 3343, /* CE03 (52739) */ - 3343, /* CE04 (52740) */ - 3343, /* CE05 (52741) */ - 3343, /* CE06 (52742) */ - 3343, /* CE07 (52743) */ - 3343, /* CE08 (52744) */ - 3343, /* CE09 (52745) */ - 3343, /* CE0A (52746) */ - 3343, /* CE0B (52747) */ - 3343, /* CE0C (52748) */ - 3343, /* CE0D (52749) */ - 3343, /* CE0E (52750) */ - 3343, /* CE0F (52751) */ - 3343, /* CE10 (52752) */ - 3343, /* CE11 (52753) */ - 3343, /* CE12 (52754) */ - 3343, /* CE13 (52755) */ - 3343, /* CE14 (52756) */ - 3343, /* CE15 (52757) */ - 3343, /* CE16 (52758) */ - 3343, /* CE17 (52759) */ - 3343, /* CE18 (52760) */ - 3343, /* CE19 (52761) */ - 3343, /* CE1A (52762) */ - 3343, /* CE1B (52763) */ - 3343, /* CE1C (52764) */ - 3343, /* CE1D (52765) */ - 3343, /* CE1E (52766) */ - 3343, /* CE1F (52767) */ - 3343, /* CE20 (52768) */ - 3343, /* CE21 (52769) */ - 3343, /* CE22 (52770) */ - 3343, /* CE23 (52771) */ - 3343, /* CE24 (52772) */ - 3343, /* CE25 (52773) */ - 3343, /* CE26 (52774) */ - 3343, /* CE27 (52775) */ - 3343, /* CE28 (52776) */ - 3343, /* CE29 (52777) */ - 3343, /* CE2A (52778) */ - 3343, /* CE2B (52779) */ - 3343, /* CE2C (52780) */ - 3343, /* CE2D (52781) */ - 3343, /* CE2E (52782) */ - 3343, /* CE2F (52783) */ - 3343, /* CE30 (52784) */ - 3343, /* CE31 (52785) */ - 3343, /* CE32 (52786) */ - 3343, /* CE33 (52787) */ - 3343, /* CE34 (52788) */ - 3343, /* CE35 (52789) */ - 3343, /* CE36 (52790) */ - 3343, /* CE37 (52791) */ - 3343, /* CE38 (52792) */ - 3343, /* CE39 (52793) */ - 3343, /* CE3A (52794) */ - 3343, /* CE3B (52795) */ - 3343, /* CE3C (52796) */ - 3343, /* CE3D (52797) */ - 3343, /* CE3E (52798) */ - 3343, /* CE3F (52799) */ - 3343, /* CE40 (52800) */ - 3343, /* CE41 (52801) */ - 3343, /* CE42 (52802) */ - 3343, /* CE43 (52803) */ - 3343, /* CE44 (52804) */ - 3343, /* CE45 (52805) */ - 3343, /* CE46 (52806) */ - 3343, /* CE47 (52807) */ - 3343, /* CE48 (52808) */ - 3343, /* CE49 (52809) */ - 3343, /* CE4A (52810) */ - 3343, /* CE4B (52811) */ - 3343, /* CE4C (52812) */ - 3343, /* CE4D (52813) */ - 3343, /* CE4E (52814) */ - 3343, /* CE4F (52815) */ - 3343, /* CE50 (52816) */ - 3343, /* CE51 (52817) */ - 3343, /* CE52 (52818) */ - 3343, /* CE53 (52819) */ - 3343, /* CE54 (52820) */ - 3343, /* CE55 (52821) */ - 3343, /* CE56 (52822) */ - 3343, /* CE57 (52823) */ - 3343, /* CE58 (52824) */ - 3343, /* CE59 (52825) */ - 3343, /* CE5A (52826) */ - 3343, /* CE5B (52827) */ - 3343, /* CE5C (52828) */ - 3343, /* CE5D (52829) */ - 3343, /* CE5E (52830) */ - 3343, /* CE5F (52831) */ - 3343, /* CE60 (52832) */ - 3343, /* CE61 (52833) */ - 3343, /* CE62 (52834) */ - 3343, /* CE63 (52835) */ - 3343, /* CE64 (52836) */ - 3343, /* CE65 (52837) */ - 3343, /* CE66 (52838) */ - 3343, /* CE67 (52839) */ - 3343, /* CE68 (52840) */ - 3343, /* CE69 (52841) */ - 3343, /* CE6A (52842) */ - 3343, /* CE6B (52843) */ - 3343, /* CE6C (52844) */ - 3343, /* CE6D (52845) */ - 3343, /* CE6E (52846) */ - 3343, /* CE6F (52847) */ - 3343, /* CE70 (52848) */ - 3343, /* CE71 (52849) */ - 3343, /* CE72 (52850) */ - 3343, /* CE73 (52851) */ - 3343, /* CE74 (52852) */ - 3343, /* CE75 (52853) */ - 3343, /* CE76 (52854) */ - 3343, /* CE77 (52855) */ - 3343, /* CE78 (52856) */ - 3343, /* CE79 (52857) */ - 3343, /* CE7A (52858) */ - 3343, /* CE7B (52859) */ - 3343, /* CE7C (52860) */ - 3343, /* CE7D (52861) */ - 3343, /* CE7E (52862) */ - 3343, /* CE7F (52863) */ - 3343, /* CE80 (52864) */ - 3343, /* CE81 (52865) */ - 3343, /* CE82 (52866) */ - 3343, /* CE83 (52867) */ - 3343, /* CE84 (52868) */ - 3343, /* CE85 (52869) */ - 3343, /* CE86 (52870) */ - 3343, /* CE87 (52871) */ - 3343, /* CE88 (52872) */ - 3343, /* CE89 (52873) */ - 3343, /* CE8A (52874) */ - 3343, /* CE8B (52875) */ - 3343, /* CE8C (52876) */ - 3343, /* CE8D (52877) */ - 3343, /* CE8E (52878) */ - 3343, /* CE8F (52879) */ - 3343, /* CE90 (52880) */ - 3343, /* CE91 (52881) */ - 3343, /* CE92 (52882) */ - 3343, /* CE93 (52883) */ - 3343, /* CE94 (52884) */ - 3343, /* CE95 (52885) */ - 3343, /* CE96 (52886) */ - 3343, /* CE97 (52887) */ - 3343, /* CE98 (52888) */ - 3343, /* CE99 (52889) */ - 3343, /* CE9A (52890) */ - 3343, /* CE9B (52891) */ - 3343, /* CE9C (52892) */ - 3343, /* CE9D (52893) */ - 3343, /* CE9E (52894) */ - 3343, /* CE9F (52895) */ - 3343, /* CEA0 (52896) */ - 3343, /* CEA1 (52897) */ - 3343, /* CEA2 (52898) */ - 3343, /* CEA3 (52899) */ - 3343, /* CEA4 (52900) */ - 3343, /* CEA5 (52901) */ - 3343, /* CEA6 (52902) */ - 3343, /* CEA7 (52903) */ - 3343, /* CEA8 (52904) */ - 3343, /* CEA9 (52905) */ - 3343, /* CEAA (52906) */ - 3343, /* CEAB (52907) */ - 3343, /* CEAC (52908) */ - 3343, /* CEAD (52909) */ - 3343, /* CEAE (52910) */ - 3343, /* CEAF (52911) */ - 3343, /* CEB0 (52912) */ - 3343, /* CEB1 (52913) */ - 3343, /* CEB2 (52914) */ - 3343, /* CEB3 (52915) */ - 3343, /* CEB4 (52916) */ - 3343, /* CEB5 (52917) */ - 3343, /* CEB6 (52918) */ - 3343, /* CEB7 (52919) */ - 3343, /* CEB8 (52920) */ - 3343, /* CEB9 (52921) */ - 3343, /* CEBA (52922) */ - 3343, /* CEBB (52923) */ - 3343, /* CEBC (52924) */ - 3343, /* CEBD (52925) */ - 3343, /* CEBE (52926) */ - 3343, /* CEBF (52927) */ - 3343, /* CEC0 (52928) */ - 3343, /* CEC1 (52929) */ - 3343, /* CEC2 (52930) */ - 3343, /* CEC3 (52931) */ - 3343, /* CEC4 (52932) */ - 3343, /* CEC5 (52933) */ - 3343, /* CEC6 (52934) */ - 3343, /* CEC7 (52935) */ - 3343, /* CEC8 (52936) */ - 3343, /* CEC9 (52937) */ - 3343, /* CECA (52938) */ - 3343, /* CECB (52939) */ - 3343, /* CECC (52940) */ - 3343, /* CECD (52941) */ - 3343, /* CECE (52942) */ - 3343, /* CECF (52943) */ - 3343, /* CED0 (52944) */ - 3343, /* CED1 (52945) */ - 3343, /* CED2 (52946) */ - 3343, /* CED3 (52947) */ - 3343, /* CED4 (52948) */ - 3343, /* CED5 (52949) */ - 3343, /* CED6 (52950) */ - 3343, /* CED7 (52951) */ - 3343, /* CED8 (52952) */ - 3343, /* CED9 (52953) */ - 3343, /* CEDA (52954) */ - 3343, /* CEDB (52955) */ - 3343, /* CEDC (52956) */ - 3343, /* CEDD (52957) */ - 3343, /* CEDE (52958) */ - 3343, /* CEDF (52959) */ - 3343, /* CEE0 (52960) */ - 3343, /* CEE1 (52961) */ - 3343, /* CEE2 (52962) */ - 3343, /* CEE3 (52963) */ - 3343, /* CEE4 (52964) */ - 3343, /* CEE5 (52965) */ - 3343, /* CEE6 (52966) */ - 3343, /* CEE7 (52967) */ - 3343, /* CEE8 (52968) */ - 3343, /* CEE9 (52969) */ - 3343, /* CEEA (52970) */ - 3343, /* CEEB (52971) */ - 3343, /* CEEC (52972) */ - 3343, /* CEED (52973) */ - 3343, /* CEEE (52974) */ - 3343, /* CEEF (52975) */ - 3343, /* CEF0 (52976) */ - 3343, /* CEF1 (52977) */ - 3343, /* CEF2 (52978) */ - 3343, /* CEF3 (52979) */ - 3343, /* CEF4 (52980) */ - 3343, /* CEF5 (52981) */ - 3343, /* CEF6 (52982) */ - 3343, /* CEF7 (52983) */ - 3343, /* CEF8 (52984) */ - 3343, /* CEF9 (52985) */ - 3343, /* CEFA (52986) */ - 3343, /* CEFB (52987) */ - 3343, /* CEFC (52988) */ - 3343, /* CEFD (52989) */ - 3343, /* CEFE (52990) */ - 3343, /* CEFF (52991) */ - 3343, /* CF00 (52992) */ - 3343, /* CF01 (52993) */ - 3343, /* CF02 (52994) */ - 3343, /* CF03 (52995) */ - 3343, /* CF04 (52996) */ - 3343, /* CF05 (52997) */ - 3343, /* CF06 (52998) */ - 3343, /* CF07 (52999) */ - 3343, /* CF08 (53000) */ - 3343, /* CF09 (53001) */ - 3343, /* CF0A (53002) */ - 3343, /* CF0B (53003) */ - 3343, /* CF0C (53004) */ - 3343, /* CF0D (53005) */ - 3343, /* CF0E (53006) */ - 3343, /* CF0F (53007) */ - 3343, /* CF10 (53008) */ - 3343, /* CF11 (53009) */ - 3343, /* CF12 (53010) */ - 3343, /* CF13 (53011) */ - 3343, /* CF14 (53012) */ - 3343, /* CF15 (53013) */ - 3343, /* CF16 (53014) */ - 3343, /* CF17 (53015) */ - 3343, /* CF18 (53016) */ - 3343, /* CF19 (53017) */ - 3343, /* CF1A (53018) */ - 3343, /* CF1B (53019) */ - 3343, /* CF1C (53020) */ - 3343, /* CF1D (53021) */ - 3343, /* CF1E (53022) */ - 3343, /* CF1F (53023) */ - 3343, /* CF20 (53024) */ - 3343, /* CF21 (53025) */ - 3343, /* CF22 (53026) */ - 3343, /* CF23 (53027) */ - 3343, /* CF24 (53028) */ - 3343, /* CF25 (53029) */ - 3343, /* CF26 (53030) */ - 3343, /* CF27 (53031) */ - 3343, /* CF28 (53032) */ - 3343, /* CF29 (53033) */ - 3343, /* CF2A (53034) */ - 3343, /* CF2B (53035) */ - 3343, /* CF2C (53036) */ - 3343, /* CF2D (53037) */ - 3343, /* CF2E (53038) */ - 3343, /* CF2F (53039) */ - 3343, /* CF30 (53040) */ - 3343, /* CF31 (53041) */ - 3343, /* CF32 (53042) */ - 3343, /* CF33 (53043) */ - 3343, /* CF34 (53044) */ - 3343, /* CF35 (53045) */ - 3343, /* CF36 (53046) */ - 3343, /* CF37 (53047) */ - 3343, /* CF38 (53048) */ - 3343, /* CF39 (53049) */ - 3343, /* CF3A (53050) */ - 3343, /* CF3B (53051) */ - 3343, /* CF3C (53052) */ - 3343, /* CF3D (53053) */ - 3343, /* CF3E (53054) */ - 3343, /* CF3F (53055) */ - 3343, /* CF40 (53056) */ - 3343, /* CF41 (53057) */ - 3343, /* CF42 (53058) */ - 3343, /* CF43 (53059) */ - 3343, /* CF44 (53060) */ - 3343, /* CF45 (53061) */ - 3343, /* CF46 (53062) */ - 3343, /* CF47 (53063) */ - 3343, /* CF48 (53064) */ - 3343, /* CF49 (53065) */ - 3343, /* CF4A (53066) */ - 3343, /* CF4B (53067) */ - 3343, /* CF4C (53068) */ - 3343, /* CF4D (53069) */ - 3343, /* CF4E (53070) */ - 3343, /* CF4F (53071) */ - 3343, /* CF50 (53072) */ - 3343, /* CF51 (53073) */ - 3343, /* CF52 (53074) */ - 3343, /* CF53 (53075) */ - 3343, /* CF54 (53076) */ - 3343, /* CF55 (53077) */ - 3343, /* CF56 (53078) */ - 3343, /* CF57 (53079) */ - 3343, /* CF58 (53080) */ - 3343, /* CF59 (53081) */ - 3343, /* CF5A (53082) */ - 3343, /* CF5B (53083) */ - 3343, /* CF5C (53084) */ - 3343, /* CF5D (53085) */ - 3343, /* CF5E (53086) */ - 3343, /* CF5F (53087) */ - 3343, /* CF60 (53088) */ - 3343, /* CF61 (53089) */ - 3343, /* CF62 (53090) */ - 3343, /* CF63 (53091) */ - 3343, /* CF64 (53092) */ - 3343, /* CF65 (53093) */ - 3343, /* CF66 (53094) */ - 3343, /* CF67 (53095) */ - 3343, /* CF68 (53096) */ - 3343, /* CF69 (53097) */ - 3343, /* CF6A (53098) */ - 3343, /* CF6B (53099) */ - 3343, /* CF6C (53100) */ - 3343, /* CF6D (53101) */ - 3343, /* CF6E (53102) */ - 3343, /* CF6F (53103) */ - 3343, /* CF70 (53104) */ - 3343, /* CF71 (53105) */ - 3343, /* CF72 (53106) */ - 3343, /* CF73 (53107) */ - 3343, /* CF74 (53108) */ - 3343, /* CF75 (53109) */ - 3343, /* CF76 (53110) */ - 3343, /* CF77 (53111) */ - 3343, /* CF78 (53112) */ - 3343, /* CF79 (53113) */ - 3343, /* CF7A (53114) */ - 3343, /* CF7B (53115) */ - 3343, /* CF7C (53116) */ - 3343, /* CF7D (53117) */ - 3343, /* CF7E (53118) */ - 3343, /* CF7F (53119) */ - 3343, /* CF80 (53120) */ - 3343, /* CF81 (53121) */ - 3343, /* CF82 (53122) */ - 3343, /* CF83 (53123) */ - 3343, /* CF84 (53124) */ - 3343, /* CF85 (53125) */ - 3343, /* CF86 (53126) */ - 3343, /* CF87 (53127) */ - 3343, /* CF88 (53128) */ - 3343, /* CF89 (53129) */ - 3343, /* CF8A (53130) */ - 3343, /* CF8B (53131) */ - 3343, /* CF8C (53132) */ - 3343, /* CF8D (53133) */ - 3343, /* CF8E (53134) */ - 3343, /* CF8F (53135) */ - 3343, /* CF90 (53136) */ - 3343, /* CF91 (53137) */ - 3343, /* CF92 (53138) */ - 3343, /* CF93 (53139) */ - 3343, /* CF94 (53140) */ - 3343, /* CF95 (53141) */ - 3343, /* CF96 (53142) */ - 3343, /* CF97 (53143) */ - 3343, /* CF98 (53144) */ - 3343, /* CF99 (53145) */ - 3343, /* CF9A (53146) */ - 3343, /* CF9B (53147) */ - 3343, /* CF9C (53148) */ - 3343, /* CF9D (53149) */ - 3343, /* CF9E (53150) */ - 3343, /* CF9F (53151) */ - 3343, /* CFA0 (53152) */ - 3343, /* CFA1 (53153) */ - 3343, /* CFA2 (53154) */ - 3343, /* CFA3 (53155) */ - 3343, /* CFA4 (53156) */ - 3343, /* CFA5 (53157) */ - 3343, /* CFA6 (53158) */ - 3343, /* CFA7 (53159) */ - 3343, /* CFA8 (53160) */ - 3343, /* CFA9 (53161) */ - 3343, /* CFAA (53162) */ - 3343, /* CFAB (53163) */ - 3343, /* CFAC (53164) */ - 3343, /* CFAD (53165) */ - 3343, /* CFAE (53166) */ - 3343, /* CFAF (53167) */ - 3343, /* CFB0 (53168) */ - 3343, /* CFB1 (53169) */ - 3343, /* CFB2 (53170) */ - 3343, /* CFB3 (53171) */ - 3343, /* CFB4 (53172) */ - 3343, /* CFB5 (53173) */ - 3343, /* CFB6 (53174) */ - 3343, /* CFB7 (53175) */ - 3343, /* CFB8 (53176) */ - 3343, /* CFB9 (53177) */ - 3343, /* CFBA (53178) */ - 3343, /* CFBB (53179) */ - 3343, /* CFBC (53180) */ - 3343, /* CFBD (53181) */ - 3343, /* CFBE (53182) */ - 3343, /* CFBF (53183) */ - 3343, /* CFC0 (53184) */ - 3343, /* CFC1 (53185) */ - 3343, /* CFC2 (53186) */ - 3343, /* CFC3 (53187) */ - 3343, /* CFC4 (53188) */ - 3343, /* CFC5 (53189) */ - 3343, /* CFC6 (53190) */ - 3343, /* CFC7 (53191) */ - 3343, /* CFC8 (53192) */ - 3343, /* CFC9 (53193) */ - 3343, /* CFCA (53194) */ - 3343, /* CFCB (53195) */ - 3343, /* CFCC (53196) */ - 3343, /* CFCD (53197) */ - 3343, /* CFCE (53198) */ - 3343, /* CFCF (53199) */ - 3343, /* CFD0 (53200) */ - 3343, /* CFD1 (53201) */ - 3343, /* CFD2 (53202) */ - 3343, /* CFD3 (53203) */ - 3343, /* CFD4 (53204) */ - 3343, /* CFD5 (53205) */ - 3343, /* CFD6 (53206) */ - 3343, /* CFD7 (53207) */ - 3343, /* CFD8 (53208) */ - 3343, /* CFD9 (53209) */ - 3343, /* CFDA (53210) */ - 3343, /* CFDB (53211) */ - 3343, /* CFDC (53212) */ - 3343, /* CFDD (53213) */ - 3343, /* CFDE (53214) */ - 3343, /* CFDF (53215) */ - 3343, /* CFE0 (53216) */ - 3343, /* CFE1 (53217) */ - 3343, /* CFE2 (53218) */ - 3343, /* CFE3 (53219) */ - 3343, /* CFE4 (53220) */ - 3343, /* CFE5 (53221) */ - 3343, /* CFE6 (53222) */ - 3343, /* CFE7 (53223) */ - 3343, /* CFE8 (53224) */ - 3343, /* CFE9 (53225) */ - 3343, /* CFEA (53226) */ - 3343, /* CFEB (53227) */ - 3343, /* CFEC (53228) */ - 3343, /* CFED (53229) */ - 3343, /* CFEE (53230) */ - 3343, /* CFEF (53231) */ - 3343, /* CFF0 (53232) */ - 3343, /* CFF1 (53233) */ - 3343, /* CFF2 (53234) */ - 3343, /* CFF3 (53235) */ - 3343, /* CFF4 (53236) */ - 3343, /* CFF5 (53237) */ - 3343, /* CFF6 (53238) */ - 3343, /* CFF7 (53239) */ - 3343, /* CFF8 (53240) */ - 3343, /* CFF9 (53241) */ - 3343, /* CFFA (53242) */ - 3343, /* CFFB (53243) */ - 3343, /* CFFC (53244) */ - 3343, /* CFFD (53245) */ - 3343, /* CFFE (53246) */ - 3343, /* CFFF (53247) */ - 3343, /* D000 (53248) */ - 3343, /* D001 (53249) */ - 3343, /* D002 (53250) */ - 3343, /* D003 (53251) */ - 3343, /* D004 (53252) */ - 3343, /* D005 (53253) */ - 3343, /* D006 (53254) */ - 3343, /* D007 (53255) */ - 3343, /* D008 (53256) */ - 3343, /* D009 (53257) */ - 3343, /* D00A (53258) */ - 3343, /* D00B (53259) */ - 3343, /* D00C (53260) */ - 3343, /* D00D (53261) */ - 3343, /* D00E (53262) */ - 3343, /* D00F (53263) */ - 3343, /* D010 (53264) */ - 3343, /* D011 (53265) */ - 3343, /* D012 (53266) */ - 3343, /* D013 (53267) */ - 3343, /* D014 (53268) */ - 3343, /* D015 (53269) */ - 3343, /* D016 (53270) */ - 3343, /* D017 (53271) */ - 3343, /* D018 (53272) */ - 3343, /* D019 (53273) */ - 3343, /* D01A (53274) */ - 3343, /* D01B (53275) */ - 3343, /* D01C (53276) */ - 3343, /* D01D (53277) */ - 3343, /* D01E (53278) */ - 3343, /* D01F (53279) */ - 3343, /* D020 (53280) */ - 3343, /* D021 (53281) */ - 3343, /* D022 (53282) */ - 3343, /* D023 (53283) */ - 3343, /* D024 (53284) */ - 3343, /* D025 (53285) */ - 3343, /* D026 (53286) */ - 3343, /* D027 (53287) */ - 3343, /* D028 (53288) */ - 3343, /* D029 (53289) */ - 3343, /* D02A (53290) */ - 3343, /* D02B (53291) */ - 3343, /* D02C (53292) */ - 3343, /* D02D (53293) */ - 3343, /* D02E (53294) */ - 3343, /* D02F (53295) */ - 3343, /* D030 (53296) */ - 3343, /* D031 (53297) */ - 3343, /* D032 (53298) */ - 3343, /* D033 (53299) */ - 3343, /* D034 (53300) */ - 3343, /* D035 (53301) */ - 3343, /* D036 (53302) */ - 3343, /* D037 (53303) */ - 3343, /* D038 (53304) */ - 3343, /* D039 (53305) */ - 3343, /* D03A (53306) */ - 3343, /* D03B (53307) */ - 3343, /* D03C (53308) */ - 3343, /* D03D (53309) */ - 3343, /* D03E (53310) */ - 3343, /* D03F (53311) */ - 3343, /* D040 (53312) */ - 3343, /* D041 (53313) */ - 3343, /* D042 (53314) */ - 3343, /* D043 (53315) */ - 3343, /* D044 (53316) */ - 3343, /* D045 (53317) */ - 3343, /* D046 (53318) */ - 3343, /* D047 (53319) */ - 3343, /* D048 (53320) */ - 3343, /* D049 (53321) */ - 3343, /* D04A (53322) */ - 3343, /* D04B (53323) */ - 3343, /* D04C (53324) */ - 3343, /* D04D (53325) */ - 3343, /* D04E (53326) */ - 3343, /* D04F (53327) */ - 3343, /* D050 (53328) */ - 3343, /* D051 (53329) */ - 3343, /* D052 (53330) */ - 3343, /* D053 (53331) */ - 3343, /* D054 (53332) */ - 3343, /* D055 (53333) */ - 3343, /* D056 (53334) */ - 3343, /* D057 (53335) */ - 3343, /* D058 (53336) */ - 3343, /* D059 (53337) */ - 3343, /* D05A (53338) */ - 3343, /* D05B (53339) */ - 3343, /* D05C (53340) */ - 3343, /* D05D (53341) */ - 3343, /* D05E (53342) */ - 3343, /* D05F (53343) */ - 3343, /* D060 (53344) */ - 3343, /* D061 (53345) */ - 3343, /* D062 (53346) */ - 3343, /* D063 (53347) */ - 3343, /* D064 (53348) */ - 3343, /* D065 (53349) */ - 3343, /* D066 (53350) */ - 3343, /* D067 (53351) */ - 3343, /* D068 (53352) */ - 3343, /* D069 (53353) */ - 3343, /* D06A (53354) */ - 3343, /* D06B (53355) */ - 3343, /* D06C (53356) */ - 3343, /* D06D (53357) */ - 3343, /* D06E (53358) */ - 3343, /* D06F (53359) */ - 3343, /* D070 (53360) */ - 3343, /* D071 (53361) */ - 3343, /* D072 (53362) */ - 3343, /* D073 (53363) */ - 3343, /* D074 (53364) */ - 3343, /* D075 (53365) */ - 3343, /* D076 (53366) */ - 3343, /* D077 (53367) */ - 3343, /* D078 (53368) */ - 3343, /* D079 (53369) */ - 3343, /* D07A (53370) */ - 3343, /* D07B (53371) */ - 3343, /* D07C (53372) */ - 3343, /* D07D (53373) */ - 3343, /* D07E (53374) */ - 3343, /* D07F (53375) */ - 3343, /* D080 (53376) */ - 3343, /* D081 (53377) */ - 3343, /* D082 (53378) */ - 3343, /* D083 (53379) */ - 3343, /* D084 (53380) */ - 3343, /* D085 (53381) */ - 3343, /* D086 (53382) */ - 3343, /* D087 (53383) */ - 3343, /* D088 (53384) */ - 3343, /* D089 (53385) */ - 3343, /* D08A (53386) */ - 3343, /* D08B (53387) */ - 3343, /* D08C (53388) */ - 3343, /* D08D (53389) */ - 3343, /* D08E (53390) */ - 3343, /* D08F (53391) */ - 3343, /* D090 (53392) */ - 3343, /* D091 (53393) */ - 3343, /* D092 (53394) */ - 3343, /* D093 (53395) */ - 3343, /* D094 (53396) */ - 3343, /* D095 (53397) */ - 3343, /* D096 (53398) */ - 3343, /* D097 (53399) */ - 3343, /* D098 (53400) */ - 3343, /* D099 (53401) */ - 3343, /* D09A (53402) */ - 3343, /* D09B (53403) */ - 3343, /* D09C (53404) */ - 3343, /* D09D (53405) */ - 3343, /* D09E (53406) */ - 3343, /* D09F (53407) */ - 3343, /* D0A0 (53408) */ - 3343, /* D0A1 (53409) */ - 3343, /* D0A2 (53410) */ - 3343, /* D0A3 (53411) */ - 3343, /* D0A4 (53412) */ - 3343, /* D0A5 (53413) */ - 3343, /* D0A6 (53414) */ - 3343, /* D0A7 (53415) */ - 3343, /* D0A8 (53416) */ - 3343, /* D0A9 (53417) */ - 3343, /* D0AA (53418) */ - 3343, /* D0AB (53419) */ - 3343, /* D0AC (53420) */ - 3343, /* D0AD (53421) */ - 3343, /* D0AE (53422) */ - 3343, /* D0AF (53423) */ - 3343, /* D0B0 (53424) */ - 3343, /* D0B1 (53425) */ - 3343, /* D0B2 (53426) */ - 3343, /* D0B3 (53427) */ - 3343, /* D0B4 (53428) */ - 3343, /* D0B5 (53429) */ - 3343, /* D0B6 (53430) */ - 3343, /* D0B7 (53431) */ - 3343, /* D0B8 (53432) */ - 3343, /* D0B9 (53433) */ - 3343, /* D0BA (53434) */ - 3343, /* D0BB (53435) */ - 3343, /* D0BC (53436) */ - 3343, /* D0BD (53437) */ - 3343, /* D0BE (53438) */ - 3343, /* D0BF (53439) */ - 3343, /* D0C0 (53440) */ - 3343, /* D0C1 (53441) */ - 3343, /* D0C2 (53442) */ - 3343, /* D0C3 (53443) */ - 3343, /* D0C4 (53444) */ - 3343, /* D0C5 (53445) */ - 3343, /* D0C6 (53446) */ - 3343, /* D0C7 (53447) */ - 3343, /* D0C8 (53448) */ - 3343, /* D0C9 (53449) */ - 3343, /* D0CA (53450) */ - 3343, /* D0CB (53451) */ - 3343, /* D0CC (53452) */ - 3343, /* D0CD (53453) */ - 3343, /* D0CE (53454) */ - 3343, /* D0CF (53455) */ - 3343, /* D0D0 (53456) */ - 3343, /* D0D1 (53457) */ - 3343, /* D0D2 (53458) */ - 3343, /* D0D3 (53459) */ - 3343, /* D0D4 (53460) */ - 3343, /* D0D5 (53461) */ - 3343, /* D0D6 (53462) */ - 3343, /* D0D7 (53463) */ - 3343, /* D0D8 (53464) */ - 3343, /* D0D9 (53465) */ - 3343, /* D0DA (53466) */ - 3343, /* D0DB (53467) */ - 3343, /* D0DC (53468) */ - 3343, /* D0DD (53469) */ - 3343, /* D0DE (53470) */ - 3343, /* D0DF (53471) */ - 3343, /* D0E0 (53472) */ - 3343, /* D0E1 (53473) */ - 3343, /* D0E2 (53474) */ - 3343, /* D0E3 (53475) */ - 3343, /* D0E4 (53476) */ - 3343, /* D0E5 (53477) */ - 3343, /* D0E6 (53478) */ - 3343, /* D0E7 (53479) */ - 3343, /* D0E8 (53480) */ - 3343, /* D0E9 (53481) */ - 3343, /* D0EA (53482) */ - 3343, /* D0EB (53483) */ - 3343, /* D0EC (53484) */ - 3343, /* D0ED (53485) */ - 3343, /* D0EE (53486) */ - 3343, /* D0EF (53487) */ - 3343, /* D0F0 (53488) */ - 3343, /* D0F1 (53489) */ - 3343, /* D0F2 (53490) */ - 3343, /* D0F3 (53491) */ - 3343, /* D0F4 (53492) */ - 3343, /* D0F5 (53493) */ - 3343, /* D0F6 (53494) */ - 3343, /* D0F7 (53495) */ - 3343, /* D0F8 (53496) */ - 3343, /* D0F9 (53497) */ - 3343, /* D0FA (53498) */ - 3343, /* D0FB (53499) */ - 3343, /* D0FC (53500) */ - 3343, /* D0FD (53501) */ - 3343, /* D0FE (53502) */ - 3343, /* D0FF (53503) */ - 3343, /* D100 (53504) */ - 3343, /* D101 (53505) */ - 3343, /* D102 (53506) */ - 3343, /* D103 (53507) */ - 3343, /* D104 (53508) */ - 3343, /* D105 (53509) */ - 3343, /* D106 (53510) */ - 3343, /* D107 (53511) */ - 3343, /* D108 (53512) */ - 3343, /* D109 (53513) */ - 3343, /* D10A (53514) */ - 3343, /* D10B (53515) */ - 3343, /* D10C (53516) */ - 3343, /* D10D (53517) */ - 3343, /* D10E (53518) */ - 3343, /* D10F (53519) */ - 3343, /* D110 (53520) */ - 3343, /* D111 (53521) */ - 3343, /* D112 (53522) */ - 3343, /* D113 (53523) */ - 3343, /* D114 (53524) */ - 3343, /* D115 (53525) */ - 3343, /* D116 (53526) */ - 3343, /* D117 (53527) */ - 3343, /* D118 (53528) */ - 3343, /* D119 (53529) */ - 3343, /* D11A (53530) */ - 3343, /* D11B (53531) */ - 3343, /* D11C (53532) */ - 3343, /* D11D (53533) */ - 3343, /* D11E (53534) */ - 3343, /* D11F (53535) */ - 3343, /* D120 (53536) */ - 3343, /* D121 (53537) */ - 3343, /* D122 (53538) */ - 3343, /* D123 (53539) */ - 3343, /* D124 (53540) */ - 3343, /* D125 (53541) */ - 3343, /* D126 (53542) */ - 3343, /* D127 (53543) */ - 3343, /* D128 (53544) */ - 3343, /* D129 (53545) */ - 3343, /* D12A (53546) */ - 3343, /* D12B (53547) */ - 3343, /* D12C (53548) */ - 3343, /* D12D (53549) */ - 3343, /* D12E (53550) */ - 3343, /* D12F (53551) */ - 3343, /* D130 (53552) */ - 3343, /* D131 (53553) */ - 3343, /* D132 (53554) */ - 3343, /* D133 (53555) */ - 3343, /* D134 (53556) */ - 3343, /* D135 (53557) */ - 3343, /* D136 (53558) */ - 3343, /* D137 (53559) */ - 3343, /* D138 (53560) */ - 3343, /* D139 (53561) */ - 3343, /* D13A (53562) */ - 3343, /* D13B (53563) */ - 3343, /* D13C (53564) */ - 3343, /* D13D (53565) */ - 3343, /* D13E (53566) */ - 3343, /* D13F (53567) */ - 3343, /* D140 (53568) */ - 3343, /* D141 (53569) */ - 3343, /* D142 (53570) */ - 3343, /* D143 (53571) */ - 3343, /* D144 (53572) */ - 3343, /* D145 (53573) */ - 3343, /* D146 (53574) */ - 3343, /* D147 (53575) */ - 3343, /* D148 (53576) */ - 3343, /* D149 (53577) */ - 3343, /* D14A (53578) */ - 3343, /* D14B (53579) */ - 3343, /* D14C (53580) */ - 3343, /* D14D (53581) */ - 3343, /* D14E (53582) */ - 3343, /* D14F (53583) */ - 3343, /* D150 (53584) */ - 3343, /* D151 (53585) */ - 3343, /* D152 (53586) */ - 3343, /* D153 (53587) */ - 3343, /* D154 (53588) */ - 3343, /* D155 (53589) */ - 3343, /* D156 (53590) */ - 3343, /* D157 (53591) */ - 3343, /* D158 (53592) */ - 3343, /* D159 (53593) */ - 3343, /* D15A (53594) */ - 3343, /* D15B (53595) */ - 3343, /* D15C (53596) */ - 3343, /* D15D (53597) */ - 3343, /* D15E (53598) */ - 3343, /* D15F (53599) */ - 3343, /* D160 (53600) */ - 3343, /* D161 (53601) */ - 3343, /* D162 (53602) */ - 3343, /* D163 (53603) */ - 3343, /* D164 (53604) */ - 3343, /* D165 (53605) */ - 3343, /* D166 (53606) */ - 3343, /* D167 (53607) */ - 3343, /* D168 (53608) */ - 3343, /* D169 (53609) */ - 3343, /* D16A (53610) */ - 3343, /* D16B (53611) */ - 3343, /* D16C (53612) */ - 3343, /* D16D (53613) */ - 3343, /* D16E (53614) */ - 3343, /* D16F (53615) */ - 3343, /* D170 (53616) */ - 3343, /* D171 (53617) */ - 3343, /* D172 (53618) */ - 3343, /* D173 (53619) */ - 3343, /* D174 (53620) */ - 3343, /* D175 (53621) */ - 3343, /* D176 (53622) */ - 3343, /* D177 (53623) */ - 3343, /* D178 (53624) */ - 3343, /* D179 (53625) */ - 3343, /* D17A (53626) */ - 3343, /* D17B (53627) */ - 3343, /* D17C (53628) */ - 3343, /* D17D (53629) */ - 3343, /* D17E (53630) */ - 3343, /* D17F (53631) */ - 3343, /* D180 (53632) */ - 3343, /* D181 (53633) */ - 3343, /* D182 (53634) */ - 3343, /* D183 (53635) */ - 3343, /* D184 (53636) */ - 3343, /* D185 (53637) */ - 3343, /* D186 (53638) */ - 3343, /* D187 (53639) */ - 3343, /* D188 (53640) */ - 3343, /* D189 (53641) */ - 3343, /* D18A (53642) */ - 3343, /* D18B (53643) */ - 3343, /* D18C (53644) */ - 3343, /* D18D (53645) */ - 3343, /* D18E (53646) */ - 3343, /* D18F (53647) */ - 3343, /* D190 (53648) */ - 3343, /* D191 (53649) */ - 3343, /* D192 (53650) */ - 3343, /* D193 (53651) */ - 3343, /* D194 (53652) */ - 3343, /* D195 (53653) */ - 3343, /* D196 (53654) */ - 3343, /* D197 (53655) */ - 3343, /* D198 (53656) */ - 3343, /* D199 (53657) */ - 3343, /* D19A (53658) */ - 3343, /* D19B (53659) */ - 3343, /* D19C (53660) */ - 3343, /* D19D (53661) */ - 3343, /* D19E (53662) */ - 3343, /* D19F (53663) */ - 3343, /* D1A0 (53664) */ - 3343, /* D1A1 (53665) */ - 3343, /* D1A2 (53666) */ - 3343, /* D1A3 (53667) */ - 3343, /* D1A4 (53668) */ - 3343, /* D1A5 (53669) */ - 3343, /* D1A6 (53670) */ - 3343, /* D1A7 (53671) */ - 3343, /* D1A8 (53672) */ - 3343, /* D1A9 (53673) */ - 3343, /* D1AA (53674) */ - 3343, /* D1AB (53675) */ - 3343, /* D1AC (53676) */ - 3343, /* D1AD (53677) */ - 3343, /* D1AE (53678) */ - 3343, /* D1AF (53679) */ - 3343, /* D1B0 (53680) */ - 3343, /* D1B1 (53681) */ - 3343, /* D1B2 (53682) */ - 3343, /* D1B3 (53683) */ - 3343, /* D1B4 (53684) */ - 3343, /* D1B5 (53685) */ - 3343, /* D1B6 (53686) */ - 3343, /* D1B7 (53687) */ - 3343, /* D1B8 (53688) */ - 3343, /* D1B9 (53689) */ - 3343, /* D1BA (53690) */ - 3343, /* D1BB (53691) */ - 3343, /* D1BC (53692) */ - 3343, /* D1BD (53693) */ - 3343, /* D1BE (53694) */ - 3343, /* D1BF (53695) */ - 3343, /* D1C0 (53696) */ - 3343, /* D1C1 (53697) */ - 3343, /* D1C2 (53698) */ - 3343, /* D1C3 (53699) */ - 3343, /* D1C4 (53700) */ - 3343, /* D1C5 (53701) */ - 3343, /* D1C6 (53702) */ - 3343, /* D1C7 (53703) */ - 3343, /* D1C8 (53704) */ - 3343, /* D1C9 (53705) */ - 3343, /* D1CA (53706) */ - 3343, /* D1CB (53707) */ - 3343, /* D1CC (53708) */ - 3343, /* D1CD (53709) */ - 3343, /* D1CE (53710) */ - 3343, /* D1CF (53711) */ - 3343, /* D1D0 (53712) */ - 3343, /* D1D1 (53713) */ - 3343, /* D1D2 (53714) */ - 3343, /* D1D3 (53715) */ - 3343, /* D1D4 (53716) */ - 3343, /* D1D5 (53717) */ - 3343, /* D1D6 (53718) */ - 3343, /* D1D7 (53719) */ - 3343, /* D1D8 (53720) */ - 3343, /* D1D9 (53721) */ - 3343, /* D1DA (53722) */ - 3343, /* D1DB (53723) */ - 3343, /* D1DC (53724) */ - 3343, /* D1DD (53725) */ - 3343, /* D1DE (53726) */ - 3343, /* D1DF (53727) */ - 3343, /* D1E0 (53728) */ - 3343, /* D1E1 (53729) */ - 3343, /* D1E2 (53730) */ - 3343, /* D1E3 (53731) */ - 3343, /* D1E4 (53732) */ - 3343, /* D1E5 (53733) */ - 3343, /* D1E6 (53734) */ - 3343, /* D1E7 (53735) */ - 3343, /* D1E8 (53736) */ - 3343, /* D1E9 (53737) */ - 3343, /* D1EA (53738) */ - 3343, /* D1EB (53739) */ - 3343, /* D1EC (53740) */ - 3343, /* D1ED (53741) */ - 3343, /* D1EE (53742) */ - 3343, /* D1EF (53743) */ - 3343, /* D1F0 (53744) */ - 3343, /* D1F1 (53745) */ - 3343, /* D1F2 (53746) */ - 3343, /* D1F3 (53747) */ - 3343, /* D1F4 (53748) */ - 3343, /* D1F5 (53749) */ - 3343, /* D1F6 (53750) */ - 3343, /* D1F7 (53751) */ - 3343, /* D1F8 (53752) */ - 3343, /* D1F9 (53753) */ - 3343, /* D1FA (53754) */ - 3343, /* D1FB (53755) */ - 3343, /* D1FC (53756) */ - 3343, /* D1FD (53757) */ - 3343, /* D1FE (53758) */ - 3343, /* D1FF (53759) */ - 3343, /* D200 (53760) */ - 3343, /* D201 (53761) */ - 3343, /* D202 (53762) */ - 3343, /* D203 (53763) */ - 3343, /* D204 (53764) */ - 3343, /* D205 (53765) */ - 3343, /* D206 (53766) */ - 3343, /* D207 (53767) */ - 3343, /* D208 (53768) */ - 3343, /* D209 (53769) */ - 3343, /* D20A (53770) */ - 3343, /* D20B (53771) */ - 3343, /* D20C (53772) */ - 3343, /* D20D (53773) */ - 3343, /* D20E (53774) */ - 3343, /* D20F (53775) */ - 3343, /* D210 (53776) */ - 3343, /* D211 (53777) */ - 3343, /* D212 (53778) */ - 3343, /* D213 (53779) */ - 3343, /* D214 (53780) */ - 3343, /* D215 (53781) */ - 3343, /* D216 (53782) */ - 3343, /* D217 (53783) */ - 3343, /* D218 (53784) */ - 3343, /* D219 (53785) */ - 3343, /* D21A (53786) */ - 3343, /* D21B (53787) */ - 3343, /* D21C (53788) */ - 3343, /* D21D (53789) */ - 3343, /* D21E (53790) */ - 3343, /* D21F (53791) */ - 3343, /* D220 (53792) */ - 3343, /* D221 (53793) */ - 3343, /* D222 (53794) */ - 3343, /* D223 (53795) */ - 3343, /* D224 (53796) */ - 3343, /* D225 (53797) */ - 3343, /* D226 (53798) */ - 3343, /* D227 (53799) */ - 3343, /* D228 (53800) */ - 3343, /* D229 (53801) */ - 3343, /* D22A (53802) */ - 3343, /* D22B (53803) */ - 3343, /* D22C (53804) */ - 3343, /* D22D (53805) */ - 3343, /* D22E (53806) */ - 3343, /* D22F (53807) */ - 3343, /* D230 (53808) */ - 3343, /* D231 (53809) */ - 3343, /* D232 (53810) */ - 3343, /* D233 (53811) */ - 3343, /* D234 (53812) */ - 3343, /* D235 (53813) */ - 3343, /* D236 (53814) */ - 3343, /* D237 (53815) */ - 3343, /* D238 (53816) */ - 3343, /* D239 (53817) */ - 3343, /* D23A (53818) */ - 3343, /* D23B (53819) */ - 3343, /* D23C (53820) */ - 3343, /* D23D (53821) */ - 3343, /* D23E (53822) */ - 3343, /* D23F (53823) */ - 3343, /* D240 (53824) */ - 3343, /* D241 (53825) */ - 3343, /* D242 (53826) */ - 3343, /* D243 (53827) */ - 3343, /* D244 (53828) */ - 3343, /* D245 (53829) */ - 3343, /* D246 (53830) */ - 3343, /* D247 (53831) */ - 3343, /* D248 (53832) */ - 3343, /* D249 (53833) */ - 3343, /* D24A (53834) */ - 3343, /* D24B (53835) */ - 3343, /* D24C (53836) */ - 3343, /* D24D (53837) */ - 3343, /* D24E (53838) */ - 3343, /* D24F (53839) */ - 3343, /* D250 (53840) */ - 3343, /* D251 (53841) */ - 3343, /* D252 (53842) */ - 3343, /* D253 (53843) */ - 3343, /* D254 (53844) */ - 3343, /* D255 (53845) */ - 3343, /* D256 (53846) */ - 3343, /* D257 (53847) */ - 3343, /* D258 (53848) */ - 3343, /* D259 (53849) */ - 3343, /* D25A (53850) */ - 3343, /* D25B (53851) */ - 3343, /* D25C (53852) */ - 3343, /* D25D (53853) */ - 3343, /* D25E (53854) */ - 3343, /* D25F (53855) */ - 3343, /* D260 (53856) */ - 3343, /* D261 (53857) */ - 3343, /* D262 (53858) */ - 3343, /* D263 (53859) */ - 3343, /* D264 (53860) */ - 3343, /* D265 (53861) */ - 3343, /* D266 (53862) */ - 3343, /* D267 (53863) */ - 3343, /* D268 (53864) */ - 3343, /* D269 (53865) */ - 3343, /* D26A (53866) */ - 3343, /* D26B (53867) */ - 3343, /* D26C (53868) */ - 3343, /* D26D (53869) */ - 3343, /* D26E (53870) */ - 3343, /* D26F (53871) */ - 3343, /* D270 (53872) */ - 3343, /* D271 (53873) */ - 3343, /* D272 (53874) */ - 3343, /* D273 (53875) */ - 3343, /* D274 (53876) */ - 3343, /* D275 (53877) */ - 3343, /* D276 (53878) */ - 3343, /* D277 (53879) */ - 3343, /* D278 (53880) */ - 3343, /* D279 (53881) */ - 3343, /* D27A (53882) */ - 3343, /* D27B (53883) */ - 3343, /* D27C (53884) */ - 3343, /* D27D (53885) */ - 3343, /* D27E (53886) */ - 3343, /* D27F (53887) */ - 3343, /* D280 (53888) */ - 3343, /* D281 (53889) */ - 3343, /* D282 (53890) */ - 3343, /* D283 (53891) */ - 3343, /* D284 (53892) */ - 3343, /* D285 (53893) */ - 3343, /* D286 (53894) */ - 3343, /* D287 (53895) */ - 3343, /* D288 (53896) */ - 3343, /* D289 (53897) */ - 3343, /* D28A (53898) */ - 3343, /* D28B (53899) */ - 3343, /* D28C (53900) */ - 3343, /* D28D (53901) */ - 3343, /* D28E (53902) */ - 3343, /* D28F (53903) */ - 3343, /* D290 (53904) */ - 3343, /* D291 (53905) */ - 3343, /* D292 (53906) */ - 3343, /* D293 (53907) */ - 3343, /* D294 (53908) */ - 3343, /* D295 (53909) */ - 3343, /* D296 (53910) */ - 3343, /* D297 (53911) */ - 3343, /* D298 (53912) */ - 3343, /* D299 (53913) */ - 3343, /* D29A (53914) */ - 3343, /* D29B (53915) */ - 3343, /* D29C (53916) */ - 3343, /* D29D (53917) */ - 3343, /* D29E (53918) */ - 3343, /* D29F (53919) */ - 3343, /* D2A0 (53920) */ - 3343, /* D2A1 (53921) */ - 3343, /* D2A2 (53922) */ - 3343, /* D2A3 (53923) */ - 3343, /* D2A4 (53924) */ - 3343, /* D2A5 (53925) */ - 3343, /* D2A6 (53926) */ - 3343, /* D2A7 (53927) */ - 3343, /* D2A8 (53928) */ - 3343, /* D2A9 (53929) */ - 3343, /* D2AA (53930) */ - 3343, /* D2AB (53931) */ - 3343, /* D2AC (53932) */ - 3343, /* D2AD (53933) */ - 3343, /* D2AE (53934) */ - 3343, /* D2AF (53935) */ - 3343, /* D2B0 (53936) */ - 3343, /* D2B1 (53937) */ - 3343, /* D2B2 (53938) */ - 3343, /* D2B3 (53939) */ - 3343, /* D2B4 (53940) */ - 3343, /* D2B5 (53941) */ - 3343, /* D2B6 (53942) */ - 3343, /* D2B7 (53943) */ - 3343, /* D2B8 (53944) */ - 3343, /* D2B9 (53945) */ - 3343, /* D2BA (53946) */ - 3343, /* D2BB (53947) */ - 3343, /* D2BC (53948) */ - 3343, /* D2BD (53949) */ - 3343, /* D2BE (53950) */ - 3343, /* D2BF (53951) */ - 3343, /* D2C0 (53952) */ - 3343, /* D2C1 (53953) */ - 3343, /* D2C2 (53954) */ - 3343, /* D2C3 (53955) */ - 3343, /* D2C4 (53956) */ - 3343, /* D2C5 (53957) */ - 3343, /* D2C6 (53958) */ - 3343, /* D2C7 (53959) */ - 3343, /* D2C8 (53960) */ - 3343, /* D2C9 (53961) */ - 3343, /* D2CA (53962) */ - 3343, /* D2CB (53963) */ - 3343, /* D2CC (53964) */ - 3343, /* D2CD (53965) */ - 3343, /* D2CE (53966) */ - 3343, /* D2CF (53967) */ - 3343, /* D2D0 (53968) */ - 3343, /* D2D1 (53969) */ - 3343, /* D2D2 (53970) */ - 3343, /* D2D3 (53971) */ - 3343, /* D2D4 (53972) */ - 3343, /* D2D5 (53973) */ - 3343, /* D2D6 (53974) */ - 3343, /* D2D7 (53975) */ - 3343, /* D2D8 (53976) */ - 3343, /* D2D9 (53977) */ - 3343, /* D2DA (53978) */ - 3343, /* D2DB (53979) */ - 3343, /* D2DC (53980) */ - 3343, /* D2DD (53981) */ - 3343, /* D2DE (53982) */ - 3343, /* D2DF (53983) */ - 3343, /* D2E0 (53984) */ - 3343, /* D2E1 (53985) */ - 3343, /* D2E2 (53986) */ - 3343, /* D2E3 (53987) */ - 3343, /* D2E4 (53988) */ - 3343, /* D2E5 (53989) */ - 3343, /* D2E6 (53990) */ - 3343, /* D2E7 (53991) */ - 3343, /* D2E8 (53992) */ - 3343, /* D2E9 (53993) */ - 3343, /* D2EA (53994) */ - 3343, /* D2EB (53995) */ - 3343, /* D2EC (53996) */ - 3343, /* D2ED (53997) */ - 3343, /* D2EE (53998) */ - 3343, /* D2EF (53999) */ - 3343, /* D2F0 (54000) */ - 3343, /* D2F1 (54001) */ - 3343, /* D2F2 (54002) */ - 3343, /* D2F3 (54003) */ - 3343, /* D2F4 (54004) */ - 3343, /* D2F5 (54005) */ - 3343, /* D2F6 (54006) */ - 3343, /* D2F7 (54007) */ - 3343, /* D2F8 (54008) */ - 3343, /* D2F9 (54009) */ - 3343, /* D2FA (54010) */ - 3343, /* D2FB (54011) */ - 3343, /* D2FC (54012) */ - 3343, /* D2FD (54013) */ - 3343, /* D2FE (54014) */ - 3343, /* D2FF (54015) */ - 3343, /* D300 (54016) */ - 3343, /* D301 (54017) */ - 3343, /* D302 (54018) */ - 3343, /* D303 (54019) */ - 3343, /* D304 (54020) */ - 3343, /* D305 (54021) */ - 3343, /* D306 (54022) */ - 3343, /* D307 (54023) */ - 3343, /* D308 (54024) */ - 3343, /* D309 (54025) */ - 3343, /* D30A (54026) */ - 3343, /* D30B (54027) */ - 3343, /* D30C (54028) */ - 3343, /* D30D (54029) */ - 3343, /* D30E (54030) */ - 3343, /* D30F (54031) */ - 3343, /* D310 (54032) */ - 3343, /* D311 (54033) */ - 3343, /* D312 (54034) */ - 3343, /* D313 (54035) */ - 3343, /* D314 (54036) */ - 3343, /* D315 (54037) */ - 3343, /* D316 (54038) */ - 3343, /* D317 (54039) */ - 3343, /* D318 (54040) */ - 3343, /* D319 (54041) */ - 3343, /* D31A (54042) */ - 3343, /* D31B (54043) */ - 3343, /* D31C (54044) */ - 3343, /* D31D (54045) */ - 3343, /* D31E (54046) */ - 3343, /* D31F (54047) */ - 3343, /* D320 (54048) */ - 3343, /* D321 (54049) */ - 3343, /* D322 (54050) */ - 3343, /* D323 (54051) */ - 3343, /* D324 (54052) */ - 3343, /* D325 (54053) */ - 3343, /* D326 (54054) */ - 3343, /* D327 (54055) */ - 3343, /* D328 (54056) */ - 3343, /* D329 (54057) */ - 3343, /* D32A (54058) */ - 3343, /* D32B (54059) */ - 3343, /* D32C (54060) */ - 3343, /* D32D (54061) */ - 3343, /* D32E (54062) */ - 3343, /* D32F (54063) */ - 3343, /* D330 (54064) */ - 3343, /* D331 (54065) */ - 3343, /* D332 (54066) */ - 3343, /* D333 (54067) */ - 3343, /* D334 (54068) */ - 3343, /* D335 (54069) */ - 3343, /* D336 (54070) */ - 3343, /* D337 (54071) */ - 3343, /* D338 (54072) */ - 3343, /* D339 (54073) */ - 3343, /* D33A (54074) */ - 3343, /* D33B (54075) */ - 3343, /* D33C (54076) */ - 3343, /* D33D (54077) */ - 3343, /* D33E (54078) */ - 3343, /* D33F (54079) */ - 3343, /* D340 (54080) */ - 3343, /* D341 (54081) */ - 3343, /* D342 (54082) */ - 3343, /* D343 (54083) */ - 3343, /* D344 (54084) */ - 3343, /* D345 (54085) */ - 3343, /* D346 (54086) */ - 3343, /* D347 (54087) */ - 3343, /* D348 (54088) */ - 3343, /* D349 (54089) */ - 3343, /* D34A (54090) */ - 3343, /* D34B (54091) */ - 3343, /* D34C (54092) */ - 3343, /* D34D (54093) */ - 3343, /* D34E (54094) */ - 3343, /* D34F (54095) */ - 3343, /* D350 (54096) */ - 3343, /* D351 (54097) */ - 3343, /* D352 (54098) */ - 3343, /* D353 (54099) */ - 3343, /* D354 (54100) */ - 3343, /* D355 (54101) */ - 3343, /* D356 (54102) */ - 3343, /* D357 (54103) */ - 3343, /* D358 (54104) */ - 3343, /* D359 (54105) */ - 3343, /* D35A (54106) */ - 3343, /* D35B (54107) */ - 3343, /* D35C (54108) */ - 3343, /* D35D (54109) */ - 3343, /* D35E (54110) */ - 3343, /* D35F (54111) */ - 3343, /* D360 (54112) */ - 3343, /* D361 (54113) */ - 3343, /* D362 (54114) */ - 3343, /* D363 (54115) */ - 3343, /* D364 (54116) */ - 3343, /* D365 (54117) */ - 3343, /* D366 (54118) */ - 3343, /* D367 (54119) */ - 3343, /* D368 (54120) */ - 3343, /* D369 (54121) */ - 3343, /* D36A (54122) */ - 3343, /* D36B (54123) */ - 3343, /* D36C (54124) */ - 3343, /* D36D (54125) */ - 3343, /* D36E (54126) */ - 3343, /* D36F (54127) */ - 3343, /* D370 (54128) */ - 3343, /* D371 (54129) */ - 3343, /* D372 (54130) */ - 3343, /* D373 (54131) */ - 3343, /* D374 (54132) */ - 3343, /* D375 (54133) */ - 3343, /* D376 (54134) */ - 3343, /* D377 (54135) */ - 3343, /* D378 (54136) */ - 3343, /* D379 (54137) */ - 3343, /* D37A (54138) */ - 3343, /* D37B (54139) */ - 3343, /* D37C (54140) */ - 3343, /* D37D (54141) */ - 3343, /* D37E (54142) */ - 3343, /* D37F (54143) */ - 3343, /* D380 (54144) */ - 3343, /* D381 (54145) */ - 3343, /* D382 (54146) */ - 3343, /* D383 (54147) */ - 3343, /* D384 (54148) */ - 3343, /* D385 (54149) */ - 3343, /* D386 (54150) */ - 3343, /* D387 (54151) */ - 3343, /* D388 (54152) */ - 3343, /* D389 (54153) */ - 3343, /* D38A (54154) */ - 3343, /* D38B (54155) */ - 3343, /* D38C (54156) */ - 3343, /* D38D (54157) */ - 3343, /* D38E (54158) */ - 3343, /* D38F (54159) */ - 3343, /* D390 (54160) */ - 3343, /* D391 (54161) */ - 3343, /* D392 (54162) */ - 3343, /* D393 (54163) */ - 3343, /* D394 (54164) */ - 3343, /* D395 (54165) */ - 3343, /* D396 (54166) */ - 3343, /* D397 (54167) */ - 3343, /* D398 (54168) */ - 3343, /* D399 (54169) */ - 3343, /* D39A (54170) */ - 3343, /* D39B (54171) */ - 3343, /* D39C (54172) */ - 3343, /* D39D (54173) */ - 3343, /* D39E (54174) */ - 3343, /* D39F (54175) */ - 3343, /* D3A0 (54176) */ - 3343, /* D3A1 (54177) */ - 3343, /* D3A2 (54178) */ - 3343, /* D3A3 (54179) */ - 3343, /* D3A4 (54180) */ - 3343, /* D3A5 (54181) */ - 3343, /* D3A6 (54182) */ - 3343, /* D3A7 (54183) */ - 3343, /* D3A8 (54184) */ - 3343, /* D3A9 (54185) */ - 3343, /* D3AA (54186) */ - 3343, /* D3AB (54187) */ - 3343, /* D3AC (54188) */ - 3343, /* D3AD (54189) */ - 3343, /* D3AE (54190) */ - 3343, /* D3AF (54191) */ - 3343, /* D3B0 (54192) */ - 3343, /* D3B1 (54193) */ - 3343, /* D3B2 (54194) */ - 3343, /* D3B3 (54195) */ - 3343, /* D3B4 (54196) */ - 3343, /* D3B5 (54197) */ - 3343, /* D3B6 (54198) */ - 3343, /* D3B7 (54199) */ - 3343, /* D3B8 (54200) */ - 3343, /* D3B9 (54201) */ - 3343, /* D3BA (54202) */ - 3343, /* D3BB (54203) */ - 3343, /* D3BC (54204) */ - 3343, /* D3BD (54205) */ - 3343, /* D3BE (54206) */ - 3343, /* D3BF (54207) */ - 3343, /* D3C0 (54208) */ - 3343, /* D3C1 (54209) */ - 3343, /* D3C2 (54210) */ - 3343, /* D3C3 (54211) */ - 3343, /* D3C4 (54212) */ - 3343, /* D3C5 (54213) */ - 3343, /* D3C6 (54214) */ - 3343, /* D3C7 (54215) */ - 3343, /* D3C8 (54216) */ - 3343, /* D3C9 (54217) */ - 3343, /* D3CA (54218) */ - 3343, /* D3CB (54219) */ - 3343, /* D3CC (54220) */ - 3343, /* D3CD (54221) */ - 3343, /* D3CE (54222) */ - 3343, /* D3CF (54223) */ - 3343, /* D3D0 (54224) */ - 3343, /* D3D1 (54225) */ - 3343, /* D3D2 (54226) */ - 3343, /* D3D3 (54227) */ - 3343, /* D3D4 (54228) */ - 3343, /* D3D5 (54229) */ - 3343, /* D3D6 (54230) */ - 3343, /* D3D7 (54231) */ - 3343, /* D3D8 (54232) */ - 3343, /* D3D9 (54233) */ - 3343, /* D3DA (54234) */ - 3343, /* D3DB (54235) */ - 3343, /* D3DC (54236) */ - 3343, /* D3DD (54237) */ - 3343, /* D3DE (54238) */ - 3343, /* D3DF (54239) */ - 3343, /* D3E0 (54240) */ - 3343, /* D3E1 (54241) */ - 3343, /* D3E2 (54242) */ - 3343, /* D3E3 (54243) */ - 3343, /* D3E4 (54244) */ - 3343, /* D3E5 (54245) */ - 3343, /* D3E6 (54246) */ - 3343, /* D3E7 (54247) */ - 3343, /* D3E8 (54248) */ - 3343, /* D3E9 (54249) */ - 3343, /* D3EA (54250) */ - 3343, /* D3EB (54251) */ - 3343, /* D3EC (54252) */ - 3343, /* D3ED (54253) */ - 3343, /* D3EE (54254) */ - 3343, /* D3EF (54255) */ - 3343, /* D3F0 (54256) */ - 3343, /* D3F1 (54257) */ - 3343, /* D3F2 (54258) */ - 3343, /* D3F3 (54259) */ - 3343, /* D3F4 (54260) */ - 3343, /* D3F5 (54261) */ - 3343, /* D3F6 (54262) */ - 3343, /* D3F7 (54263) */ - 3343, /* D3F8 (54264) */ - 3343, /* D3F9 (54265) */ - 3343, /* D3FA (54266) */ - 3343, /* D3FB (54267) */ - 3343, /* D3FC (54268) */ - 3343, /* D3FD (54269) */ - 3343, /* D3FE (54270) */ - 3343, /* D3FF (54271) */ - 3343, /* D400 (54272) */ - 3343, /* D401 (54273) */ - 3343, /* D402 (54274) */ - 3343, /* D403 (54275) */ - 3343, /* D404 (54276) */ - 3343, /* D405 (54277) */ - 3343, /* D406 (54278) */ - 3343, /* D407 (54279) */ - 3343, /* D408 (54280) */ - 3343, /* D409 (54281) */ - 3343, /* D40A (54282) */ - 3343, /* D40B (54283) */ - 3343, /* D40C (54284) */ - 3343, /* D40D (54285) */ - 3343, /* D40E (54286) */ - 3343, /* D40F (54287) */ - 3343, /* D410 (54288) */ - 3343, /* D411 (54289) */ - 3343, /* D412 (54290) */ - 3343, /* D413 (54291) */ - 3343, /* D414 (54292) */ - 3343, /* D415 (54293) */ - 3343, /* D416 (54294) */ - 3343, /* D417 (54295) */ - 3343, /* D418 (54296) */ - 3343, /* D419 (54297) */ - 3343, /* D41A (54298) */ - 3343, /* D41B (54299) */ - 3343, /* D41C (54300) */ - 3343, /* D41D (54301) */ - 3343, /* D41E (54302) */ - 3343, /* D41F (54303) */ - 3343, /* D420 (54304) */ - 3343, /* D421 (54305) */ - 3343, /* D422 (54306) */ - 3343, /* D423 (54307) */ - 3343, /* D424 (54308) */ - 3343, /* D425 (54309) */ - 3343, /* D426 (54310) */ - 3343, /* D427 (54311) */ - 3343, /* D428 (54312) */ - 3343, /* D429 (54313) */ - 3343, /* D42A (54314) */ - 3343, /* D42B (54315) */ - 3343, /* D42C (54316) */ - 3343, /* D42D (54317) */ - 3343, /* D42E (54318) */ - 3343, /* D42F (54319) */ - 3343, /* D430 (54320) */ - 3343, /* D431 (54321) */ - 3343, /* D432 (54322) */ - 3343, /* D433 (54323) */ - 3343, /* D434 (54324) */ - 3343, /* D435 (54325) */ - 3343, /* D436 (54326) */ - 3343, /* D437 (54327) */ - 3343, /* D438 (54328) */ - 3343, /* D439 (54329) */ - 3343, /* D43A (54330) */ - 3343, /* D43B (54331) */ - 3343, /* D43C (54332) */ - 3343, /* D43D (54333) */ - 3343, /* D43E (54334) */ - 3343, /* D43F (54335) */ - 3343, /* D440 (54336) */ - 3343, /* D441 (54337) */ - 3343, /* D442 (54338) */ - 3343, /* D443 (54339) */ - 3343, /* D444 (54340) */ - 3343, /* D445 (54341) */ - 3343, /* D446 (54342) */ - 3343, /* D447 (54343) */ - 3343, /* D448 (54344) */ - 3343, /* D449 (54345) */ - 3343, /* D44A (54346) */ - 3343, /* D44B (54347) */ - 3343, /* D44C (54348) */ - 3343, /* D44D (54349) */ - 3343, /* D44E (54350) */ - 3343, /* D44F (54351) */ - 3343, /* D450 (54352) */ - 3343, /* D451 (54353) */ - 3343, /* D452 (54354) */ - 3343, /* D453 (54355) */ - 3343, /* D454 (54356) */ - 3343, /* D455 (54357) */ - 3343, /* D456 (54358) */ - 3343, /* D457 (54359) */ - 3343, /* D458 (54360) */ - 3343, /* D459 (54361) */ - 3343, /* D45A (54362) */ - 3343, /* D45B (54363) */ - 3343, /* D45C (54364) */ - 3343, /* D45D (54365) */ - 3343, /* D45E (54366) */ - 3343, /* D45F (54367) */ - 3343, /* D460 (54368) */ - 3343, /* D461 (54369) */ - 3343, /* D462 (54370) */ - 3343, /* D463 (54371) */ - 3343, /* D464 (54372) */ - 3343, /* D465 (54373) */ - 3343, /* D466 (54374) */ - 3343, /* D467 (54375) */ - 3343, /* D468 (54376) */ - 3343, /* D469 (54377) */ - 3343, /* D46A (54378) */ - 3343, /* D46B (54379) */ - 3343, /* D46C (54380) */ - 3343, /* D46D (54381) */ - 3343, /* D46E (54382) */ - 3343, /* D46F (54383) */ - 3343, /* D470 (54384) */ - 3343, /* D471 (54385) */ - 3343, /* D472 (54386) */ - 3343, /* D473 (54387) */ - 3343, /* D474 (54388) */ - 3343, /* D475 (54389) */ - 3343, /* D476 (54390) */ - 3343, /* D477 (54391) */ - 3343, /* D478 (54392) */ - 3343, /* D479 (54393) */ - 3343, /* D47A (54394) */ - 3343, /* D47B (54395) */ - 3343, /* D47C (54396) */ - 3343, /* D47D (54397) */ - 3343, /* D47E (54398) */ - 3343, /* D47F (54399) */ - 3343, /* D480 (54400) */ - 3343, /* D481 (54401) */ - 3343, /* D482 (54402) */ - 3343, /* D483 (54403) */ - 3343, /* D484 (54404) */ - 3343, /* D485 (54405) */ - 3343, /* D486 (54406) */ - 3343, /* D487 (54407) */ - 3343, /* D488 (54408) */ - 3343, /* D489 (54409) */ - 3343, /* D48A (54410) */ - 3343, /* D48B (54411) */ - 3343, /* D48C (54412) */ - 3343, /* D48D (54413) */ - 3343, /* D48E (54414) */ - 3343, /* D48F (54415) */ - 3343, /* D490 (54416) */ - 3343, /* D491 (54417) */ - 3343, /* D492 (54418) */ - 3343, /* D493 (54419) */ - 3343, /* D494 (54420) */ - 3343, /* D495 (54421) */ - 3343, /* D496 (54422) */ - 3343, /* D497 (54423) */ - 3343, /* D498 (54424) */ - 3343, /* D499 (54425) */ - 3343, /* D49A (54426) */ - 3343, /* D49B (54427) */ - 3343, /* D49C (54428) */ - 3343, /* D49D (54429) */ - 3343, /* D49E (54430) */ - 3343, /* D49F (54431) */ - 3343, /* D4A0 (54432) */ - 3343, /* D4A1 (54433) */ - 3343, /* D4A2 (54434) */ - 3343, /* D4A3 (54435) */ - 3343, /* D4A4 (54436) */ - 3343, /* D4A5 (54437) */ - 3343, /* D4A6 (54438) */ - 3343, /* D4A7 (54439) */ - 3343, /* D4A8 (54440) */ - 3343, /* D4A9 (54441) */ - 3343, /* D4AA (54442) */ - 3343, /* D4AB (54443) */ - 3343, /* D4AC (54444) */ - 3343, /* D4AD (54445) */ - 3343, /* D4AE (54446) */ - 3343, /* D4AF (54447) */ - 3343, /* D4B0 (54448) */ - 3343, /* D4B1 (54449) */ - 3343, /* D4B2 (54450) */ - 3343, /* D4B3 (54451) */ - 3343, /* D4B4 (54452) */ - 3343, /* D4B5 (54453) */ - 3343, /* D4B6 (54454) */ - 3343, /* D4B7 (54455) */ - 3343, /* D4B8 (54456) */ - 3343, /* D4B9 (54457) */ - 3343, /* D4BA (54458) */ - 3343, /* D4BB (54459) */ - 3343, /* D4BC (54460) */ - 3343, /* D4BD (54461) */ - 3343, /* D4BE (54462) */ - 3343, /* D4BF (54463) */ - 3343, /* D4C0 (54464) */ - 3343, /* D4C1 (54465) */ - 3343, /* D4C2 (54466) */ - 3343, /* D4C3 (54467) */ - 3343, /* D4C4 (54468) */ - 3343, /* D4C5 (54469) */ - 3343, /* D4C6 (54470) */ - 3343, /* D4C7 (54471) */ - 3343, /* D4C8 (54472) */ - 3343, /* D4C9 (54473) */ - 3343, /* D4CA (54474) */ - 3343, /* D4CB (54475) */ - 3343, /* D4CC (54476) */ - 3343, /* D4CD (54477) */ - 3343, /* D4CE (54478) */ - 3343, /* D4CF (54479) */ - 3343, /* D4D0 (54480) */ - 3343, /* D4D1 (54481) */ - 3343, /* D4D2 (54482) */ - 3343, /* D4D3 (54483) */ - 3343, /* D4D4 (54484) */ - 3343, /* D4D5 (54485) */ - 3343, /* D4D6 (54486) */ - 3343, /* D4D7 (54487) */ - 3343, /* D4D8 (54488) */ - 3343, /* D4D9 (54489) */ - 3343, /* D4DA (54490) */ - 3343, /* D4DB (54491) */ - 3343, /* D4DC (54492) */ - 3343, /* D4DD (54493) */ - 3343, /* D4DE (54494) */ - 3343, /* D4DF (54495) */ - 3343, /* D4E0 (54496) */ - 3343, /* D4E1 (54497) */ - 3343, /* D4E2 (54498) */ - 3343, /* D4E3 (54499) */ - 3343, /* D4E4 (54500) */ - 3343, /* D4E5 (54501) */ - 3343, /* D4E6 (54502) */ - 3343, /* D4E7 (54503) */ - 3343, /* D4E8 (54504) */ - 3343, /* D4E9 (54505) */ - 3343, /* D4EA (54506) */ - 3343, /* D4EB (54507) */ - 3343, /* D4EC (54508) */ - 3343, /* D4ED (54509) */ - 3343, /* D4EE (54510) */ - 3343, /* D4EF (54511) */ - 3343, /* D4F0 (54512) */ - 3343, /* D4F1 (54513) */ - 3343, /* D4F2 (54514) */ - 3343, /* D4F3 (54515) */ - 3343, /* D4F4 (54516) */ - 3343, /* D4F5 (54517) */ - 3343, /* D4F6 (54518) */ - 3343, /* D4F7 (54519) */ - 3343, /* D4F8 (54520) */ - 3343, /* D4F9 (54521) */ - 3343, /* D4FA (54522) */ - 3343, /* D4FB (54523) */ - 3343, /* D4FC (54524) */ - 3343, /* D4FD (54525) */ - 3343, /* D4FE (54526) */ - 3343, /* D4FF (54527) */ - 3343, /* D500 (54528) */ - 3343, /* D501 (54529) */ - 3343, /* D502 (54530) */ - 3343, /* D503 (54531) */ - 3343, /* D504 (54532) */ - 3343, /* D505 (54533) */ - 3343, /* D506 (54534) */ - 3343, /* D507 (54535) */ - 3343, /* D508 (54536) */ - 3343, /* D509 (54537) */ - 3343, /* D50A (54538) */ - 3343, /* D50B (54539) */ - 3343, /* D50C (54540) */ - 3343, /* D50D (54541) */ - 3343, /* D50E (54542) */ - 3343, /* D50F (54543) */ - 3343, /* D510 (54544) */ - 3343, /* D511 (54545) */ - 3343, /* D512 (54546) */ - 3343, /* D513 (54547) */ - 3343, /* D514 (54548) */ - 3343, /* D515 (54549) */ - 3343, /* D516 (54550) */ - 3343, /* D517 (54551) */ - 3343, /* D518 (54552) */ - 3343, /* D519 (54553) */ - 3343, /* D51A (54554) */ - 3343, /* D51B (54555) */ - 3343, /* D51C (54556) */ - 3343, /* D51D (54557) */ - 3343, /* D51E (54558) */ - 3343, /* D51F (54559) */ - 3343, /* D520 (54560) */ - 3343, /* D521 (54561) */ - 3343, /* D522 (54562) */ - 3343, /* D523 (54563) */ - 3343, /* D524 (54564) */ - 3343, /* D525 (54565) */ - 3343, /* D526 (54566) */ - 3343, /* D527 (54567) */ - 3343, /* D528 (54568) */ - 3343, /* D529 (54569) */ - 3343, /* D52A (54570) */ - 3343, /* D52B (54571) */ - 3343, /* D52C (54572) */ - 3343, /* D52D (54573) */ - 3343, /* D52E (54574) */ - 3343, /* D52F (54575) */ - 3343, /* D530 (54576) */ - 3343, /* D531 (54577) */ - 3343, /* D532 (54578) */ - 3343, /* D533 (54579) */ - 3343, /* D534 (54580) */ - 3343, /* D535 (54581) */ - 3343, /* D536 (54582) */ - 3343, /* D537 (54583) */ - 3343, /* D538 (54584) */ - 3343, /* D539 (54585) */ - 3343, /* D53A (54586) */ - 3343, /* D53B (54587) */ - 3343, /* D53C (54588) */ - 3343, /* D53D (54589) */ - 3343, /* D53E (54590) */ - 3343, /* D53F (54591) */ - 3343, /* D540 (54592) */ - 3343, /* D541 (54593) */ - 3343, /* D542 (54594) */ - 3343, /* D543 (54595) */ - 3343, /* D544 (54596) */ - 3343, /* D545 (54597) */ - 3343, /* D546 (54598) */ - 3343, /* D547 (54599) */ - 3343, /* D548 (54600) */ - 3343, /* D549 (54601) */ - 3343, /* D54A (54602) */ - 3343, /* D54B (54603) */ - 3343, /* D54C (54604) */ - 3343, /* D54D (54605) */ - 3343, /* D54E (54606) */ - 3343, /* D54F (54607) */ - 3343, /* D550 (54608) */ - 3343, /* D551 (54609) */ - 3343, /* D552 (54610) */ - 3343, /* D553 (54611) */ - 3343, /* D554 (54612) */ - 3343, /* D555 (54613) */ - 3343, /* D556 (54614) */ - 3343, /* D557 (54615) */ - 3343, /* D558 (54616) */ - 3343, /* D559 (54617) */ - 3343, /* D55A (54618) */ - 3343, /* D55B (54619) */ - 3343, /* D55C (54620) */ - 3343, /* D55D (54621) */ - 3343, /* D55E (54622) */ - 3343, /* D55F (54623) */ - 3343, /* D560 (54624) */ - 3343, /* D561 (54625) */ - 3343, /* D562 (54626) */ - 3343, /* D563 (54627) */ - 3343, /* D564 (54628) */ - 3343, /* D565 (54629) */ - 3343, /* D566 (54630) */ - 3343, /* D567 (54631) */ - 3343, /* D568 (54632) */ - 3343, /* D569 (54633) */ - 3343, /* D56A (54634) */ - 3343, /* D56B (54635) */ - 3343, /* D56C (54636) */ - 3343, /* D56D (54637) */ - 3343, /* D56E (54638) */ - 3343, /* D56F (54639) */ - 3343, /* D570 (54640) */ - 3343, /* D571 (54641) */ - 3343, /* D572 (54642) */ - 3343, /* D573 (54643) */ - 3343, /* D574 (54644) */ - 3343, /* D575 (54645) */ - 3343, /* D576 (54646) */ - 3343, /* D577 (54647) */ - 3343, /* D578 (54648) */ - 3343, /* D579 (54649) */ - 3343, /* D57A (54650) */ - 3343, /* D57B (54651) */ - 3343, /* D57C (54652) */ - 3343, /* D57D (54653) */ - 3343, /* D57E (54654) */ - 3343, /* D57F (54655) */ - 3343, /* D580 (54656) */ - 3343, /* D581 (54657) */ - 3343, /* D582 (54658) */ - 3343, /* D583 (54659) */ - 3343, /* D584 (54660) */ - 3343, /* D585 (54661) */ - 3343, /* D586 (54662) */ - 3343, /* D587 (54663) */ - 3343, /* D588 (54664) */ - 3343, /* D589 (54665) */ - 3343, /* D58A (54666) */ - 3343, /* D58B (54667) */ - 3343, /* D58C (54668) */ - 3343, /* D58D (54669) */ - 3343, /* D58E (54670) */ - 3343, /* D58F (54671) */ - 3343, /* D590 (54672) */ - 3343, /* D591 (54673) */ - 3343, /* D592 (54674) */ - 3343, /* D593 (54675) */ - 3343, /* D594 (54676) */ - 3343, /* D595 (54677) */ - 3343, /* D596 (54678) */ - 3343, /* D597 (54679) */ - 3343, /* D598 (54680) */ - 3343, /* D599 (54681) */ - 3343, /* D59A (54682) */ - 3343, /* D59B (54683) */ - 3343, /* D59C (54684) */ - 3343, /* D59D (54685) */ - 3343, /* D59E (54686) */ - 3343, /* D59F (54687) */ - 3343, /* D5A0 (54688) */ - 3343, /* D5A1 (54689) */ - 3343, /* D5A2 (54690) */ - 3343, /* D5A3 (54691) */ - 3343, /* D5A4 (54692) */ - 3343, /* D5A5 (54693) */ - 3343, /* D5A6 (54694) */ - 3343, /* D5A7 (54695) */ - 3343, /* D5A8 (54696) */ - 3343, /* D5A9 (54697) */ - 3343, /* D5AA (54698) */ - 3343, /* D5AB (54699) */ - 3343, /* D5AC (54700) */ - 3343, /* D5AD (54701) */ - 3343, /* D5AE (54702) */ - 3343, /* D5AF (54703) */ - 3343, /* D5B0 (54704) */ - 3343, /* D5B1 (54705) */ - 3343, /* D5B2 (54706) */ - 3343, /* D5B3 (54707) */ - 3343, /* D5B4 (54708) */ - 3343, /* D5B5 (54709) */ - 3343, /* D5B6 (54710) */ - 3343, /* D5B7 (54711) */ - 3343, /* D5B8 (54712) */ - 3343, /* D5B9 (54713) */ - 3343, /* D5BA (54714) */ - 3343, /* D5BB (54715) */ - 3343, /* D5BC (54716) */ - 3343, /* D5BD (54717) */ - 3343, /* D5BE (54718) */ - 3343, /* D5BF (54719) */ - 3343, /* D5C0 (54720) */ - 3343, /* D5C1 (54721) */ - 3343, /* D5C2 (54722) */ - 3343, /* D5C3 (54723) */ - 3343, /* D5C4 (54724) */ - 3343, /* D5C5 (54725) */ - 3343, /* D5C6 (54726) */ - 3343, /* D5C7 (54727) */ - 3343, /* D5C8 (54728) */ - 3343, /* D5C9 (54729) */ - 3343, /* D5CA (54730) */ - 3343, /* D5CB (54731) */ - 3343, /* D5CC (54732) */ - 3343, /* D5CD (54733) */ - 3343, /* D5CE (54734) */ - 3343, /* D5CF (54735) */ - 3343, /* D5D0 (54736) */ - 3343, /* D5D1 (54737) */ - 3343, /* D5D2 (54738) */ - 3343, /* D5D3 (54739) */ - 3343, /* D5D4 (54740) */ - 3343, /* D5D5 (54741) */ - 3343, /* D5D6 (54742) */ - 3343, /* D5D7 (54743) */ - 3343, /* D5D8 (54744) */ - 3343, /* D5D9 (54745) */ - 3343, /* D5DA (54746) */ - 3343, /* D5DB (54747) */ - 3343, /* D5DC (54748) */ - 3343, /* D5DD (54749) */ - 3343, /* D5DE (54750) */ - 3343, /* D5DF (54751) */ - 3343, /* D5E0 (54752) */ - 3343, /* D5E1 (54753) */ - 3343, /* D5E2 (54754) */ - 3343, /* D5E3 (54755) */ - 3343, /* D5E4 (54756) */ - 3343, /* D5E5 (54757) */ - 3343, /* D5E6 (54758) */ - 3343, /* D5E7 (54759) */ - 3343, /* D5E8 (54760) */ - 3343, /* D5E9 (54761) */ - 3343, /* D5EA (54762) */ - 3343, /* D5EB (54763) */ - 3343, /* D5EC (54764) */ - 3343, /* D5ED (54765) */ - 3343, /* D5EE (54766) */ - 3343, /* D5EF (54767) */ - 3343, /* D5F0 (54768) */ - 3343, /* D5F1 (54769) */ - 3343, /* D5F2 (54770) */ - 3343, /* D5F3 (54771) */ - 3343, /* D5F4 (54772) */ - 3343, /* D5F5 (54773) */ - 3343, /* D5F6 (54774) */ - 3343, /* D5F7 (54775) */ - 3343, /* D5F8 (54776) */ - 3343, /* D5F9 (54777) */ - 3343, /* D5FA (54778) */ - 3343, /* D5FB (54779) */ - 3343, /* D5FC (54780) */ - 3343, /* D5FD (54781) */ - 3343, /* D5FE (54782) */ - 3343, /* D5FF (54783) */ - 3343, /* D600 (54784) */ - 3343, /* D601 (54785) */ - 3343, /* D602 (54786) */ - 3343, /* D603 (54787) */ - 3343, /* D604 (54788) */ - 3343, /* D605 (54789) */ - 3343, /* D606 (54790) */ - 3343, /* D607 (54791) */ - 3343, /* D608 (54792) */ - 3343, /* D609 (54793) */ - 3343, /* D60A (54794) */ - 3343, /* D60B (54795) */ - 3343, /* D60C (54796) */ - 3343, /* D60D (54797) */ - 3343, /* D60E (54798) */ - 3343, /* D60F (54799) */ - 3343, /* D610 (54800) */ - 3343, /* D611 (54801) */ - 3343, /* D612 (54802) */ - 3343, /* D613 (54803) */ - 3343, /* D614 (54804) */ - 3343, /* D615 (54805) */ - 3343, /* D616 (54806) */ - 3343, /* D617 (54807) */ - 3343, /* D618 (54808) */ - 3343, /* D619 (54809) */ - 3343, /* D61A (54810) */ - 3343, /* D61B (54811) */ - 3343, /* D61C (54812) */ - 3343, /* D61D (54813) */ - 3343, /* D61E (54814) */ - 3343, /* D61F (54815) */ - 3343, /* D620 (54816) */ - 3343, /* D621 (54817) */ - 3343, /* D622 (54818) */ - 3343, /* D623 (54819) */ - 3343, /* D624 (54820) */ - 3343, /* D625 (54821) */ - 3343, /* D626 (54822) */ - 3343, /* D627 (54823) */ - 3343, /* D628 (54824) */ - 3343, /* D629 (54825) */ - 3343, /* D62A (54826) */ - 3343, /* D62B (54827) */ - 3343, /* D62C (54828) */ - 3343, /* D62D (54829) */ - 3343, /* D62E (54830) */ - 3343, /* D62F (54831) */ - 3343, /* D630 (54832) */ - 3343, /* D631 (54833) */ - 3343, /* D632 (54834) */ - 3343, /* D633 (54835) */ - 3343, /* D634 (54836) */ - 3343, /* D635 (54837) */ - 3343, /* D636 (54838) */ - 3343, /* D637 (54839) */ - 3343, /* D638 (54840) */ - 3343, /* D639 (54841) */ - 3343, /* D63A (54842) */ - 3343, /* D63B (54843) */ - 3343, /* D63C (54844) */ - 3343, /* D63D (54845) */ - 3343, /* D63E (54846) */ - 3343, /* D63F (54847) */ - 3343, /* D640 (54848) */ - 3343, /* D641 (54849) */ - 3343, /* D642 (54850) */ - 3343, /* D643 (54851) */ - 3343, /* D644 (54852) */ - 3343, /* D645 (54853) */ - 3343, /* D646 (54854) */ - 3343, /* D647 (54855) */ - 3343, /* D648 (54856) */ - 3343, /* D649 (54857) */ - 3343, /* D64A (54858) */ - 3343, /* D64B (54859) */ - 3343, /* D64C (54860) */ - 3343, /* D64D (54861) */ - 3343, /* D64E (54862) */ - 3343, /* D64F (54863) */ - 3343, /* D650 (54864) */ - 3343, /* D651 (54865) */ - 3343, /* D652 (54866) */ - 3343, /* D653 (54867) */ - 3343, /* D654 (54868) */ - 3343, /* D655 (54869) */ - 3343, /* D656 (54870) */ - 3343, /* D657 (54871) */ - 3343, /* D658 (54872) */ - 3343, /* D659 (54873) */ - 3343, /* D65A (54874) */ - 3343, /* D65B (54875) */ - 3343, /* D65C (54876) */ - 3343, /* D65D (54877) */ - 3343, /* D65E (54878) */ - 3343, /* D65F (54879) */ - 3343, /* D660 (54880) */ - 3343, /* D661 (54881) */ - 3343, /* D662 (54882) */ - 3343, /* D663 (54883) */ - 3343, /* D664 (54884) */ - 3343, /* D665 (54885) */ - 3343, /* D666 (54886) */ - 3343, /* D667 (54887) */ - 3343, /* D668 (54888) */ - 3343, /* D669 (54889) */ - 3343, /* D66A (54890) */ - 3343, /* D66B (54891) */ - 3343, /* D66C (54892) */ - 3343, /* D66D (54893) */ - 3343, /* D66E (54894) */ - 3343, /* D66F (54895) */ - 3343, /* D670 (54896) */ - 3343, /* D671 (54897) */ - 3343, /* D672 (54898) */ - 3343, /* D673 (54899) */ - 3343, /* D674 (54900) */ - 3343, /* D675 (54901) */ - 3343, /* D676 (54902) */ - 3343, /* D677 (54903) */ - 3343, /* D678 (54904) */ - 3343, /* D679 (54905) */ - 3343, /* D67A (54906) */ - 3343, /* D67B (54907) */ - 3343, /* D67C (54908) */ - 3343, /* D67D (54909) */ - 3343, /* D67E (54910) */ - 3343, /* D67F (54911) */ - 3343, /* D680 (54912) */ - 3343, /* D681 (54913) */ - 3343, /* D682 (54914) */ - 3343, /* D683 (54915) */ - 3343, /* D684 (54916) */ - 3343, /* D685 (54917) */ - 3343, /* D686 (54918) */ - 3343, /* D687 (54919) */ - 3343, /* D688 (54920) */ - 3343, /* D689 (54921) */ - 3343, /* D68A (54922) */ - 3343, /* D68B (54923) */ - 3343, /* D68C (54924) */ - 3343, /* D68D (54925) */ - 3343, /* D68E (54926) */ - 3343, /* D68F (54927) */ - 3343, /* D690 (54928) */ - 3343, /* D691 (54929) */ - 3343, /* D692 (54930) */ - 3343, /* D693 (54931) */ - 3343, /* D694 (54932) */ - 3343, /* D695 (54933) */ - 3343, /* D696 (54934) */ - 3343, /* D697 (54935) */ - 3343, /* D698 (54936) */ - 3343, /* D699 (54937) */ - 3343, /* D69A (54938) */ - 3343, /* D69B (54939) */ - 3343, /* D69C (54940) */ - 3343, /* D69D (54941) */ - 3343, /* D69E (54942) */ - 3343, /* D69F (54943) */ - 3343, /* D6A0 (54944) */ - 3343, /* D6A1 (54945) */ - 3343, /* D6A2 (54946) */ - 3343, /* D6A3 (54947) */ - 3343, /* D6A4 (54948) */ - 3343, /* D6A5 (54949) */ - 3343, /* D6A6 (54950) */ - 3343, /* D6A7 (54951) */ - 3343, /* D6A8 (54952) */ - 3343, /* D6A9 (54953) */ - 3343, /* D6AA (54954) */ - 3343, /* D6AB (54955) */ - 3343, /* D6AC (54956) */ - 3343, /* D6AD (54957) */ - 3343, /* D6AE (54958) */ - 3343, /* D6AF (54959) */ - 3343, /* D6B0 (54960) */ - 3343, /* D6B1 (54961) */ - 3343, /* D6B2 (54962) */ - 3343, /* D6B3 (54963) */ - 3343, /* D6B4 (54964) */ - 3343, /* D6B5 (54965) */ - 3343, /* D6B6 (54966) */ - 3343, /* D6B7 (54967) */ - 3343, /* D6B8 (54968) */ - 3343, /* D6B9 (54969) */ - 3343, /* D6BA (54970) */ - 3343, /* D6BB (54971) */ - 3343, /* D6BC (54972) */ - 3343, /* D6BD (54973) */ - 3343, /* D6BE (54974) */ - 3343, /* D6BF (54975) */ - 3343, /* D6C0 (54976) */ - 3343, /* D6C1 (54977) */ - 3343, /* D6C2 (54978) */ - 3343, /* D6C3 (54979) */ - 3343, /* D6C4 (54980) */ - 3343, /* D6C5 (54981) */ - 3343, /* D6C6 (54982) */ - 3343, /* D6C7 (54983) */ - 3343, /* D6C8 (54984) */ - 3343, /* D6C9 (54985) */ - 3343, /* D6CA (54986) */ - 3343, /* D6CB (54987) */ - 3343, /* D6CC (54988) */ - 3343, /* D6CD (54989) */ - 3343, /* D6CE (54990) */ - 3343, /* D6CF (54991) */ - 3343, /* D6D0 (54992) */ - 3343, /* D6D1 (54993) */ - 3343, /* D6D2 (54994) */ - 3343, /* D6D3 (54995) */ - 3343, /* D6D4 (54996) */ - 3343, /* D6D5 (54997) */ - 3343, /* D6D6 (54998) */ - 3343, /* D6D7 (54999) */ - 3343, /* D6D8 (55000) */ - 3343, /* D6D9 (55001) */ - 3343, /* D6DA (55002) */ - 3343, /* D6DB (55003) */ - 3343, /* D6DC (55004) */ - 3343, /* D6DD (55005) */ - 3343, /* D6DE (55006) */ - 3343, /* D6DF (55007) */ - 3343, /* D6E0 (55008) */ - 3343, /* D6E1 (55009) */ - 3343, /* D6E2 (55010) */ - 3343, /* D6E3 (55011) */ - 3343, /* D6E4 (55012) */ - 3343, /* D6E5 (55013) */ - 3343, /* D6E6 (55014) */ - 3343, /* D6E7 (55015) */ - 3343, /* D6E8 (55016) */ - 3343, /* D6E9 (55017) */ - 3343, /* D6EA (55018) */ - 3343, /* D6EB (55019) */ - 3343, /* D6EC (55020) */ - 3343, /* D6ED (55021) */ - 3343, /* D6EE (55022) */ - 3343, /* D6EF (55023) */ - 3343, /* D6F0 (55024) */ - 3343, /* D6F1 (55025) */ - 3343, /* D6F2 (55026) */ - 3343, /* D6F3 (55027) */ - 3343, /* D6F4 (55028) */ - 3343, /* D6F5 (55029) */ - 3343, /* D6F6 (55030) */ - 3343, /* D6F7 (55031) */ - 3343, /* D6F8 (55032) */ - 3343, /* D6F9 (55033) */ - 3343, /* D6FA (55034) */ - 3343, /* D6FB (55035) */ - 3343, /* D6FC (55036) */ - 3343, /* D6FD (55037) */ - 3343, /* D6FE (55038) */ - 3343, /* D6FF (55039) */ - 3343, /* D700 (55040) */ - 3343, /* D701 (55041) */ - 3343, /* D702 (55042) */ - 3343, /* D703 (55043) */ - 3343, /* D704 (55044) */ - 3343, /* D705 (55045) */ - 3343, /* D706 (55046) */ - 3343, /* D707 (55047) */ - 3343, /* D708 (55048) */ - 3343, /* D709 (55049) */ - 3343, /* D70A (55050) */ - 3343, /* D70B (55051) */ - 3343, /* D70C (55052) */ - 3343, /* D70D (55053) */ - 3343, /* D70E (55054) */ - 3343, /* D70F (55055) */ - 3343, /* D710 (55056) */ - 3343, /* D711 (55057) */ - 3343, /* D712 (55058) */ - 3343, /* D713 (55059) */ - 3343, /* D714 (55060) */ - 3343, /* D715 (55061) */ - 3343, /* D716 (55062) */ - 3343, /* D717 (55063) */ - 3343, /* D718 (55064) */ - 3343, /* D719 (55065) */ - 3343, /* D71A (55066) */ - 3343, /* D71B (55067) */ - 3343, /* D71C (55068) */ - 3343, /* D71D (55069) */ - 3343, /* D71E (55070) */ - 3343, /* D71F (55071) */ - 3343, /* D720 (55072) */ - 3343, /* D721 (55073) */ - 3343, /* D722 (55074) */ - 3343, /* D723 (55075) */ - 3343, /* D724 (55076) */ - 3343, /* D725 (55077) */ - 3343, /* D726 (55078) */ - 3343, /* D727 (55079) */ - 3343, /* D728 (55080) */ - 3343, /* D729 (55081) */ - 3343, /* D72A (55082) */ - 3343, /* D72B (55083) */ - 3343, /* D72C (55084) */ - 3343, /* D72D (55085) */ - 3343, /* D72E (55086) */ - 3343, /* D72F (55087) */ - 3343, /* D730 (55088) */ - 3343, /* D731 (55089) */ - 3343, /* D732 (55090) */ - 3343, /* D733 (55091) */ - 3343, /* D734 (55092) */ - 3343, /* D735 (55093) */ - 3343, /* D736 (55094) */ - 3343, /* D737 (55095) */ - 3343, /* D738 (55096) */ - 3343, /* D739 (55097) */ - 3343, /* D73A (55098) */ - 3343, /* D73B (55099) */ - 3343, /* D73C (55100) */ - 3343, /* D73D (55101) */ - 3343, /* D73E (55102) */ - 3343, /* D73F (55103) */ - 3343, /* D740 (55104) */ - 3343, /* D741 (55105) */ - 3343, /* D742 (55106) */ - 3343, /* D743 (55107) */ - 3343, /* D744 (55108) */ - 3343, /* D745 (55109) */ - 3343, /* D746 (55110) */ - 3343, /* D747 (55111) */ - 3343, /* D748 (55112) */ - 3343, /* D749 (55113) */ - 3343, /* D74A (55114) */ - 3343, /* D74B (55115) */ - 3343, /* D74C (55116) */ - 3343, /* D74D (55117) */ - 3343, /* D74E (55118) */ - 3343, /* D74F (55119) */ - 3343, /* D750 (55120) */ - 3343, /* D751 (55121) */ - 3343, /* D752 (55122) */ - 3343, /* D753 (55123) */ - 3343, /* D754 (55124) */ - 3343, /* D755 (55125) */ - 3343, /* D756 (55126) */ - 3343, /* D757 (55127) */ - 3343, /* D758 (55128) */ - 3343, /* D759 (55129) */ - 3343, /* D75A (55130) */ - 3343, /* D75B (55131) */ - 3343, /* D75C (55132) */ - 3343, /* D75D (55133) */ - 3343, /* D75E (55134) */ - 3343, /* D75F (55135) */ - 3343, /* D760 (55136) */ - 3343, /* D761 (55137) */ - 3343, /* D762 (55138) */ - 3343, /* D763 (55139) */ - 3343, /* D764 (55140) */ - 3343, /* D765 (55141) */ - 3343, /* D766 (55142) */ - 3343, /* D767 (55143) */ - 3343, /* D768 (55144) */ - 3343, /* D769 (55145) */ - 3343, /* D76A (55146) */ - 3343, /* D76B (55147) */ - 3343, /* D76C (55148) */ - 3343, /* D76D (55149) */ - 3343, /* D76E (55150) */ - 3343, /* D76F (55151) */ - 3343, /* D770 (55152) */ - 3343, /* D771 (55153) */ - 3343, /* D772 (55154) */ - 3343, /* D773 (55155) */ - 3343, /* D774 (55156) */ - 3343, /* D775 (55157) */ - 3343, /* D776 (55158) */ - 3343, /* D777 (55159) */ - 3343, /* D778 (55160) */ - 3343, /* D779 (55161) */ - 3343, /* D77A (55162) */ - 3343, /* D77B (55163) */ - 3343, /* D77C (55164) */ - 3343, /* D77D (55165) */ - 3343, /* D77E (55166) */ - 3343, /* D77F (55167) */ - 3343, /* D780 (55168) */ - 3343, /* D781 (55169) */ - 3343, /* D782 (55170) */ - 3343, /* D783 (55171) */ - 3343, /* D784 (55172) */ - 3343, /* D785 (55173) */ - 3343, /* D786 (55174) */ - 3343, /* D787 (55175) */ - 3343, /* D788 (55176) */ - 3343, /* D789 (55177) */ - 3343, /* D78A (55178) */ - 3343, /* D78B (55179) */ - 3343, /* D78C (55180) */ - 3343, /* D78D (55181) */ - 3343, /* D78E (55182) */ - 3343, /* D78F (55183) */ - 3343, /* D790 (55184) */ - 3343, /* D791 (55185) */ - 3343, /* D792 (55186) */ - 3343, /* D793 (55187) */ - 3343, /* D794 (55188) */ - 3343, /* D795 (55189) */ - 3343, /* D796 (55190) */ - 3343, /* D797 (55191) */ - 3343, /* D798 (55192) */ - 3343, /* D799 (55193) */ - 3343, /* D79A (55194) */ - 3343, /* D79B (55195) */ - 3343, /* D79C (55196) */ - 3343, /* D79D (55197) */ - 3343, /* D79E (55198) */ - 3343, /* D79F (55199) */ - 3343, /* D7A0 (55200) */ - 3343, /* D7A1 (55201) */ - 3343, /* D7A2 (55202) */ - 3343, /* D7A3 (55203) */ + 3347, /* AC00 (44032) */ + 3347, /* AC01 (44033) */ + 3347, /* AC02 (44034) */ + 3347, /* AC03 (44035) */ + 3347, /* AC04 (44036) */ + 3347, /* AC05 (44037) */ + 3347, /* AC06 (44038) */ + 3347, /* AC07 (44039) */ + 3347, /* AC08 (44040) */ + 3347, /* AC09 (44041) */ + 3347, /* AC0A (44042) */ + 3347, /* AC0B (44043) */ + 3347, /* AC0C (44044) */ + 3347, /* AC0D (44045) */ + 3347, /* AC0E (44046) */ + 3347, /* AC0F (44047) */ + 3347, /* AC10 (44048) */ + 3347, /* AC11 (44049) */ + 3347, /* AC12 (44050) */ + 3347, /* AC13 (44051) */ + 3347, /* AC14 (44052) */ + 3347, /* AC15 (44053) */ + 3347, /* AC16 (44054) */ + 3347, /* AC17 (44055) */ + 3347, /* AC18 (44056) */ + 3347, /* AC19 (44057) */ + 3347, /* AC1A (44058) */ + 3347, /* AC1B (44059) */ + 3347, /* AC1C (44060) */ + 3347, /* AC1D (44061) */ + 3347, /* AC1E (44062) */ + 3347, /* AC1F (44063) */ + 3347, /* AC20 (44064) */ + 3347, /* AC21 (44065) */ + 3347, /* AC22 (44066) */ + 3347, /* AC23 (44067) */ + 3347, /* AC24 (44068) */ + 3347, /* AC25 (44069) */ + 3347, /* AC26 (44070) */ + 3347, /* AC27 (44071) */ + 3347, /* AC28 (44072) */ + 3347, /* AC29 (44073) */ + 3347, /* AC2A (44074) */ + 3347, /* AC2B (44075) */ + 3347, /* AC2C (44076) */ + 3347, /* AC2D (44077) */ + 3347, /* AC2E (44078) */ + 3347, /* AC2F (44079) */ + 3347, /* AC30 (44080) */ + 3347, /* AC31 (44081) */ + 3347, /* AC32 (44082) */ + 3347, /* AC33 (44083) */ + 3347, /* AC34 (44084) */ + 3347, /* AC35 (44085) */ + 3347, /* AC36 (44086) */ + 3347, /* AC37 (44087) */ + 3347, /* AC38 (44088) */ + 3347, /* AC39 (44089) */ + 3347, /* AC3A (44090) */ + 3347, /* AC3B (44091) */ + 3347, /* AC3C (44092) */ + 3347, /* AC3D (44093) */ + 3347, /* AC3E (44094) */ + 3347, /* AC3F (44095) */ + 3347, /* AC40 (44096) */ + 3347, /* AC41 (44097) */ + 3347, /* AC42 (44098) */ + 3347, /* AC43 (44099) */ + 3347, /* AC44 (44100) */ + 3347, /* AC45 (44101) */ + 3347, /* AC46 (44102) */ + 3347, /* AC47 (44103) */ + 3347, /* AC48 (44104) */ + 3347, /* AC49 (44105) */ + 3347, /* AC4A (44106) */ + 3347, /* AC4B (44107) */ + 3347, /* AC4C (44108) */ + 3347, /* AC4D (44109) */ + 3347, /* AC4E (44110) */ + 3347, /* AC4F (44111) */ + 3347, /* AC50 (44112) */ + 3347, /* AC51 (44113) */ + 3347, /* AC52 (44114) */ + 3347, /* AC53 (44115) */ + 3347, /* AC54 (44116) */ + 3347, /* AC55 (44117) */ + 3347, /* AC56 (44118) */ + 3347, /* AC57 (44119) */ + 3347, /* AC58 (44120) */ + 3347, /* AC59 (44121) */ + 3347, /* AC5A (44122) */ + 3347, /* AC5B (44123) */ + 3347, /* AC5C (44124) */ + 3347, /* AC5D (44125) */ + 3347, /* AC5E (44126) */ + 3347, /* AC5F (44127) */ + 3347, /* AC60 (44128) */ + 3347, /* AC61 (44129) */ + 3347, /* AC62 (44130) */ + 3347, /* AC63 (44131) */ + 3347, /* AC64 (44132) */ + 3347, /* AC65 (44133) */ + 3347, /* AC66 (44134) */ + 3347, /* AC67 (44135) */ + 3347, /* AC68 (44136) */ + 3347, /* AC69 (44137) */ + 3347, /* AC6A (44138) */ + 3347, /* AC6B (44139) */ + 3347, /* AC6C (44140) */ + 3347, /* AC6D (44141) */ + 3347, /* AC6E (44142) */ + 3347, /* AC6F (44143) */ + 3347, /* AC70 (44144) */ + 3347, /* AC71 (44145) */ + 3347, /* AC72 (44146) */ + 3347, /* AC73 (44147) */ + 3347, /* AC74 (44148) */ + 3347, /* AC75 (44149) */ + 3347, /* AC76 (44150) */ + 3347, /* AC77 (44151) */ + 3347, /* AC78 (44152) */ + 3347, /* AC79 (44153) */ + 3347, /* AC7A (44154) */ + 3347, /* AC7B (44155) */ + 3347, /* AC7C (44156) */ + 3347, /* AC7D (44157) */ + 3347, /* AC7E (44158) */ + 3347, /* AC7F (44159) */ + 3347, /* AC80 (44160) */ + 3347, /* AC81 (44161) */ + 3347, /* AC82 (44162) */ + 3347, /* AC83 (44163) */ + 3347, /* AC84 (44164) */ + 3347, /* AC85 (44165) */ + 3347, /* AC86 (44166) */ + 3347, /* AC87 (44167) */ + 3347, /* AC88 (44168) */ + 3347, /* AC89 (44169) */ + 3347, /* AC8A (44170) */ + 3347, /* AC8B (44171) */ + 3347, /* AC8C (44172) */ + 3347, /* AC8D (44173) */ + 3347, /* AC8E (44174) */ + 3347, /* AC8F (44175) */ + 3347, /* AC90 (44176) */ + 3347, /* AC91 (44177) */ + 3347, /* AC92 (44178) */ + 3347, /* AC93 (44179) */ + 3347, /* AC94 (44180) */ + 3347, /* AC95 (44181) */ + 3347, /* AC96 (44182) */ + 3347, /* AC97 (44183) */ + 3347, /* AC98 (44184) */ + 3347, /* AC99 (44185) */ + 3347, /* AC9A (44186) */ + 3347, /* AC9B (44187) */ + 3347, /* AC9C (44188) */ + 3347, /* AC9D (44189) */ + 3347, /* AC9E (44190) */ + 3347, /* AC9F (44191) */ + 3347, /* ACA0 (44192) */ + 3347, /* ACA1 (44193) */ + 3347, /* ACA2 (44194) */ + 3347, /* ACA3 (44195) */ + 3347, /* ACA4 (44196) */ + 3347, /* ACA5 (44197) */ + 3347, /* ACA6 (44198) */ + 3347, /* ACA7 (44199) */ + 3347, /* ACA8 (44200) */ + 3347, /* ACA9 (44201) */ + 3347, /* ACAA (44202) */ + 3347, /* ACAB (44203) */ + 3347, /* ACAC (44204) */ + 3347, /* ACAD (44205) */ + 3347, /* ACAE (44206) */ + 3347, /* ACAF (44207) */ + 3347, /* ACB0 (44208) */ + 3347, /* ACB1 (44209) */ + 3347, /* ACB2 (44210) */ + 3347, /* ACB3 (44211) */ + 3347, /* ACB4 (44212) */ + 3347, /* ACB5 (44213) */ + 3347, /* ACB6 (44214) */ + 3347, /* ACB7 (44215) */ + 3347, /* ACB8 (44216) */ + 3347, /* ACB9 (44217) */ + 3347, /* ACBA (44218) */ + 3347, /* ACBB (44219) */ + 3347, /* ACBC (44220) */ + 3347, /* ACBD (44221) */ + 3347, /* ACBE (44222) */ + 3347, /* ACBF (44223) */ + 3347, /* ACC0 (44224) */ + 3347, /* ACC1 (44225) */ + 3347, /* ACC2 (44226) */ + 3347, /* ACC3 (44227) */ + 3347, /* ACC4 (44228) */ + 3347, /* ACC5 (44229) */ + 3347, /* ACC6 (44230) */ + 3347, /* ACC7 (44231) */ + 3347, /* ACC8 (44232) */ + 3347, /* ACC9 (44233) */ + 3347, /* ACCA (44234) */ + 3347, /* ACCB (44235) */ + 3347, /* ACCC (44236) */ + 3347, /* ACCD (44237) */ + 3347, /* ACCE (44238) */ + 3347, /* ACCF (44239) */ + 3347, /* ACD0 (44240) */ + 3347, /* ACD1 (44241) */ + 3347, /* ACD2 (44242) */ + 3347, /* ACD3 (44243) */ + 3347, /* ACD4 (44244) */ + 3347, /* ACD5 (44245) */ + 3347, /* ACD6 (44246) */ + 3347, /* ACD7 (44247) */ + 3347, /* ACD8 (44248) */ + 3347, /* ACD9 (44249) */ + 3347, /* ACDA (44250) */ + 3347, /* ACDB (44251) */ + 3347, /* ACDC (44252) */ + 3347, /* ACDD (44253) */ + 3347, /* ACDE (44254) */ + 3347, /* ACDF (44255) */ + 3347, /* ACE0 (44256) */ + 3347, /* ACE1 (44257) */ + 3347, /* ACE2 (44258) */ + 3347, /* ACE3 (44259) */ + 3347, /* ACE4 (44260) */ + 3347, /* ACE5 (44261) */ + 3347, /* ACE6 (44262) */ + 3347, /* ACE7 (44263) */ + 3347, /* ACE8 (44264) */ + 3347, /* ACE9 (44265) */ + 3347, /* ACEA (44266) */ + 3347, /* ACEB (44267) */ + 3347, /* ACEC (44268) */ + 3347, /* ACED (44269) */ + 3347, /* ACEE (44270) */ + 3347, /* ACEF (44271) */ + 3347, /* ACF0 (44272) */ + 3347, /* ACF1 (44273) */ + 3347, /* ACF2 (44274) */ + 3347, /* ACF3 (44275) */ + 3347, /* ACF4 (44276) */ + 3347, /* ACF5 (44277) */ + 3347, /* ACF6 (44278) */ + 3347, /* ACF7 (44279) */ + 3347, /* ACF8 (44280) */ + 3347, /* ACF9 (44281) */ + 3347, /* ACFA (44282) */ + 3347, /* ACFB (44283) */ + 3347, /* ACFC (44284) */ + 3347, /* ACFD (44285) */ + 3347, /* ACFE (44286) */ + 3347, /* ACFF (44287) */ + 3347, /* AD00 (44288) */ + 3347, /* AD01 (44289) */ + 3347, /* AD02 (44290) */ + 3347, /* AD03 (44291) */ + 3347, /* AD04 (44292) */ + 3347, /* AD05 (44293) */ + 3347, /* AD06 (44294) */ + 3347, /* AD07 (44295) */ + 3347, /* AD08 (44296) */ + 3347, /* AD09 (44297) */ + 3347, /* AD0A (44298) */ + 3347, /* AD0B (44299) */ + 3347, /* AD0C (44300) */ + 3347, /* AD0D (44301) */ + 3347, /* AD0E (44302) */ + 3347, /* AD0F (44303) */ + 3347, /* AD10 (44304) */ + 3347, /* AD11 (44305) */ + 3347, /* AD12 (44306) */ + 3347, /* AD13 (44307) */ + 3347, /* AD14 (44308) */ + 3347, /* AD15 (44309) */ + 3347, /* AD16 (44310) */ + 3347, /* AD17 (44311) */ + 3347, /* AD18 (44312) */ + 3347, /* AD19 (44313) */ + 3347, /* AD1A (44314) */ + 3347, /* AD1B (44315) */ + 3347, /* AD1C (44316) */ + 3347, /* AD1D (44317) */ + 3347, /* AD1E (44318) */ + 3347, /* AD1F (44319) */ + 3347, /* AD20 (44320) */ + 3347, /* AD21 (44321) */ + 3347, /* AD22 (44322) */ + 3347, /* AD23 (44323) */ + 3347, /* AD24 (44324) */ + 3347, /* AD25 (44325) */ + 3347, /* AD26 (44326) */ + 3347, /* AD27 (44327) */ + 3347, /* AD28 (44328) */ + 3347, /* AD29 (44329) */ + 3347, /* AD2A (44330) */ + 3347, /* AD2B (44331) */ + 3347, /* AD2C (44332) */ + 3347, /* AD2D (44333) */ + 3347, /* AD2E (44334) */ + 3347, /* AD2F (44335) */ + 3347, /* AD30 (44336) */ + 3347, /* AD31 (44337) */ + 3347, /* AD32 (44338) */ + 3347, /* AD33 (44339) */ + 3347, /* AD34 (44340) */ + 3347, /* AD35 (44341) */ + 3347, /* AD36 (44342) */ + 3347, /* AD37 (44343) */ + 3347, /* AD38 (44344) */ + 3347, /* AD39 (44345) */ + 3347, /* AD3A (44346) */ + 3347, /* AD3B (44347) */ + 3347, /* AD3C (44348) */ + 3347, /* AD3D (44349) */ + 3347, /* AD3E (44350) */ + 3347, /* AD3F (44351) */ + 3347, /* AD40 (44352) */ + 3347, /* AD41 (44353) */ + 3347, /* AD42 (44354) */ + 3347, /* AD43 (44355) */ + 3347, /* AD44 (44356) */ + 3347, /* AD45 (44357) */ + 3347, /* AD46 (44358) */ + 3347, /* AD47 (44359) */ + 3347, /* AD48 (44360) */ + 3347, /* AD49 (44361) */ + 3347, /* AD4A (44362) */ + 3347, /* AD4B (44363) */ + 3347, /* AD4C (44364) */ + 3347, /* AD4D (44365) */ + 3347, /* AD4E (44366) */ + 3347, /* AD4F (44367) */ + 3347, /* AD50 (44368) */ + 3347, /* AD51 (44369) */ + 3347, /* AD52 (44370) */ + 3347, /* AD53 (44371) */ + 3347, /* AD54 (44372) */ + 3347, /* AD55 (44373) */ + 3347, /* AD56 (44374) */ + 3347, /* AD57 (44375) */ + 3347, /* AD58 (44376) */ + 3347, /* AD59 (44377) */ + 3347, /* AD5A (44378) */ + 3347, /* AD5B (44379) */ + 3347, /* AD5C (44380) */ + 3347, /* AD5D (44381) */ + 3347, /* AD5E (44382) */ + 3347, /* AD5F (44383) */ + 3347, /* AD60 (44384) */ + 3347, /* AD61 (44385) */ + 3347, /* AD62 (44386) */ + 3347, /* AD63 (44387) */ + 3347, /* AD64 (44388) */ + 3347, /* AD65 (44389) */ + 3347, /* AD66 (44390) */ + 3347, /* AD67 (44391) */ + 3347, /* AD68 (44392) */ + 3347, /* AD69 (44393) */ + 3347, /* AD6A (44394) */ + 3347, /* AD6B (44395) */ + 3347, /* AD6C (44396) */ + 3347, /* AD6D (44397) */ + 3347, /* AD6E (44398) */ + 3347, /* AD6F (44399) */ + 3347, /* AD70 (44400) */ + 3347, /* AD71 (44401) */ + 3347, /* AD72 (44402) */ + 3347, /* AD73 (44403) */ + 3347, /* AD74 (44404) */ + 3347, /* AD75 (44405) */ + 3347, /* AD76 (44406) */ + 3347, /* AD77 (44407) */ + 3347, /* AD78 (44408) */ + 3347, /* AD79 (44409) */ + 3347, /* AD7A (44410) */ + 3347, /* AD7B (44411) */ + 3347, /* AD7C (44412) */ + 3347, /* AD7D (44413) */ + 3347, /* AD7E (44414) */ + 3347, /* AD7F (44415) */ + 3347, /* AD80 (44416) */ + 3347, /* AD81 (44417) */ + 3347, /* AD82 (44418) */ + 3347, /* AD83 (44419) */ + 3347, /* AD84 (44420) */ + 3347, /* AD85 (44421) */ + 3347, /* AD86 (44422) */ + 3347, /* AD87 (44423) */ + 3347, /* AD88 (44424) */ + 3347, /* AD89 (44425) */ + 3347, /* AD8A (44426) */ + 3347, /* AD8B (44427) */ + 3347, /* AD8C (44428) */ + 3347, /* AD8D (44429) */ + 3347, /* AD8E (44430) */ + 3347, /* AD8F (44431) */ + 3347, /* AD90 (44432) */ + 3347, /* AD91 (44433) */ + 3347, /* AD92 (44434) */ + 3347, /* AD93 (44435) */ + 3347, /* AD94 (44436) */ + 3347, /* AD95 (44437) */ + 3347, /* AD96 (44438) */ + 3347, /* AD97 (44439) */ + 3347, /* AD98 (44440) */ + 3347, /* AD99 (44441) */ + 3347, /* AD9A (44442) */ + 3347, /* AD9B (44443) */ + 3347, /* AD9C (44444) */ + 3347, /* AD9D (44445) */ + 3347, /* AD9E (44446) */ + 3347, /* AD9F (44447) */ + 3347, /* ADA0 (44448) */ + 3347, /* ADA1 (44449) */ + 3347, /* ADA2 (44450) */ + 3347, /* ADA3 (44451) */ + 3347, /* ADA4 (44452) */ + 3347, /* ADA5 (44453) */ + 3347, /* ADA6 (44454) */ + 3347, /* ADA7 (44455) */ + 3347, /* ADA8 (44456) */ + 3347, /* ADA9 (44457) */ + 3347, /* ADAA (44458) */ + 3347, /* ADAB (44459) */ + 3347, /* ADAC (44460) */ + 3347, /* ADAD (44461) */ + 3347, /* ADAE (44462) */ + 3347, /* ADAF (44463) */ + 3347, /* ADB0 (44464) */ + 3347, /* ADB1 (44465) */ + 3347, /* ADB2 (44466) */ + 3347, /* ADB3 (44467) */ + 3347, /* ADB4 (44468) */ + 3347, /* ADB5 (44469) */ + 3347, /* ADB6 (44470) */ + 3347, /* ADB7 (44471) */ + 3347, /* ADB8 (44472) */ + 3347, /* ADB9 (44473) */ + 3347, /* ADBA (44474) */ + 3347, /* ADBB (44475) */ + 3347, /* ADBC (44476) */ + 3347, /* ADBD (44477) */ + 3347, /* ADBE (44478) */ + 3347, /* ADBF (44479) */ + 3347, /* ADC0 (44480) */ + 3347, /* ADC1 (44481) */ + 3347, /* ADC2 (44482) */ + 3347, /* ADC3 (44483) */ + 3347, /* ADC4 (44484) */ + 3347, /* ADC5 (44485) */ + 3347, /* ADC6 (44486) */ + 3347, /* ADC7 (44487) */ + 3347, /* ADC8 (44488) */ + 3347, /* ADC9 (44489) */ + 3347, /* ADCA (44490) */ + 3347, /* ADCB (44491) */ + 3347, /* ADCC (44492) */ + 3347, /* ADCD (44493) */ + 3347, /* ADCE (44494) */ + 3347, /* ADCF (44495) */ + 3347, /* ADD0 (44496) */ + 3347, /* ADD1 (44497) */ + 3347, /* ADD2 (44498) */ + 3347, /* ADD3 (44499) */ + 3347, /* ADD4 (44500) */ + 3347, /* ADD5 (44501) */ + 3347, /* ADD6 (44502) */ + 3347, /* ADD7 (44503) */ + 3347, /* ADD8 (44504) */ + 3347, /* ADD9 (44505) */ + 3347, /* ADDA (44506) */ + 3347, /* ADDB (44507) */ + 3347, /* ADDC (44508) */ + 3347, /* ADDD (44509) */ + 3347, /* ADDE (44510) */ + 3347, /* ADDF (44511) */ + 3347, /* ADE0 (44512) */ + 3347, /* ADE1 (44513) */ + 3347, /* ADE2 (44514) */ + 3347, /* ADE3 (44515) */ + 3347, /* ADE4 (44516) */ + 3347, /* ADE5 (44517) */ + 3347, /* ADE6 (44518) */ + 3347, /* ADE7 (44519) */ + 3347, /* ADE8 (44520) */ + 3347, /* ADE9 (44521) */ + 3347, /* ADEA (44522) */ + 3347, /* ADEB (44523) */ + 3347, /* ADEC (44524) */ + 3347, /* ADED (44525) */ + 3347, /* ADEE (44526) */ + 3347, /* ADEF (44527) */ + 3347, /* ADF0 (44528) */ + 3347, /* ADF1 (44529) */ + 3347, /* ADF2 (44530) */ + 3347, /* ADF3 (44531) */ + 3347, /* ADF4 (44532) */ + 3347, /* ADF5 (44533) */ + 3347, /* ADF6 (44534) */ + 3347, /* ADF7 (44535) */ + 3347, /* ADF8 (44536) */ + 3347, /* ADF9 (44537) */ + 3347, /* ADFA (44538) */ + 3347, /* ADFB (44539) */ + 3347, /* ADFC (44540) */ + 3347, /* ADFD (44541) */ + 3347, /* ADFE (44542) */ + 3347, /* ADFF (44543) */ + 3347, /* AE00 (44544) */ + 3347, /* AE01 (44545) */ + 3347, /* AE02 (44546) */ + 3347, /* AE03 (44547) */ + 3347, /* AE04 (44548) */ + 3347, /* AE05 (44549) */ + 3347, /* AE06 (44550) */ + 3347, /* AE07 (44551) */ + 3347, /* AE08 (44552) */ + 3347, /* AE09 (44553) */ + 3347, /* AE0A (44554) */ + 3347, /* AE0B (44555) */ + 3347, /* AE0C (44556) */ + 3347, /* AE0D (44557) */ + 3347, /* AE0E (44558) */ + 3347, /* AE0F (44559) */ + 3347, /* AE10 (44560) */ + 3347, /* AE11 (44561) */ + 3347, /* AE12 (44562) */ + 3347, /* AE13 (44563) */ + 3347, /* AE14 (44564) */ + 3347, /* AE15 (44565) */ + 3347, /* AE16 (44566) */ + 3347, /* AE17 (44567) */ + 3347, /* AE18 (44568) */ + 3347, /* AE19 (44569) */ + 3347, /* AE1A (44570) */ + 3347, /* AE1B (44571) */ + 3347, /* AE1C (44572) */ + 3347, /* AE1D (44573) */ + 3347, /* AE1E (44574) */ + 3347, /* AE1F (44575) */ + 3347, /* AE20 (44576) */ + 3347, /* AE21 (44577) */ + 3347, /* AE22 (44578) */ + 3347, /* AE23 (44579) */ + 3347, /* AE24 (44580) */ + 3347, /* AE25 (44581) */ + 3347, /* AE26 (44582) */ + 3347, /* AE27 (44583) */ + 3347, /* AE28 (44584) */ + 3347, /* AE29 (44585) */ + 3347, /* AE2A (44586) */ + 3347, /* AE2B (44587) */ + 3347, /* AE2C (44588) */ + 3347, /* AE2D (44589) */ + 3347, /* AE2E (44590) */ + 3347, /* AE2F (44591) */ + 3347, /* AE30 (44592) */ + 3347, /* AE31 (44593) */ + 3347, /* AE32 (44594) */ + 3347, /* AE33 (44595) */ + 3347, /* AE34 (44596) */ + 3347, /* AE35 (44597) */ + 3347, /* AE36 (44598) */ + 3347, /* AE37 (44599) */ + 3347, /* AE38 (44600) */ + 3347, /* AE39 (44601) */ + 3347, /* AE3A (44602) */ + 3347, /* AE3B (44603) */ + 3347, /* AE3C (44604) */ + 3347, /* AE3D (44605) */ + 3347, /* AE3E (44606) */ + 3347, /* AE3F (44607) */ + 3347, /* AE40 (44608) */ + 3347, /* AE41 (44609) */ + 3347, /* AE42 (44610) */ + 3347, /* AE43 (44611) */ + 3347, /* AE44 (44612) */ + 3347, /* AE45 (44613) */ + 3347, /* AE46 (44614) */ + 3347, /* AE47 (44615) */ + 3347, /* AE48 (44616) */ + 3347, /* AE49 (44617) */ + 3347, /* AE4A (44618) */ + 3347, /* AE4B (44619) */ + 3347, /* AE4C (44620) */ + 3347, /* AE4D (44621) */ + 3347, /* AE4E (44622) */ + 3347, /* AE4F (44623) */ + 3347, /* AE50 (44624) */ + 3347, /* AE51 (44625) */ + 3347, /* AE52 (44626) */ + 3347, /* AE53 (44627) */ + 3347, /* AE54 (44628) */ + 3347, /* AE55 (44629) */ + 3347, /* AE56 (44630) */ + 3347, /* AE57 (44631) */ + 3347, /* AE58 (44632) */ + 3347, /* AE59 (44633) */ + 3347, /* AE5A (44634) */ + 3347, /* AE5B (44635) */ + 3347, /* AE5C (44636) */ + 3347, /* AE5D (44637) */ + 3347, /* AE5E (44638) */ + 3347, /* AE5F (44639) */ + 3347, /* AE60 (44640) */ + 3347, /* AE61 (44641) */ + 3347, /* AE62 (44642) */ + 3347, /* AE63 (44643) */ + 3347, /* AE64 (44644) */ + 3347, /* AE65 (44645) */ + 3347, /* AE66 (44646) */ + 3347, /* AE67 (44647) */ + 3347, /* AE68 (44648) */ + 3347, /* AE69 (44649) */ + 3347, /* AE6A (44650) */ + 3347, /* AE6B (44651) */ + 3347, /* AE6C (44652) */ + 3347, /* AE6D (44653) */ + 3347, /* AE6E (44654) */ + 3347, /* AE6F (44655) */ + 3347, /* AE70 (44656) */ + 3347, /* AE71 (44657) */ + 3347, /* AE72 (44658) */ + 3347, /* AE73 (44659) */ + 3347, /* AE74 (44660) */ + 3347, /* AE75 (44661) */ + 3347, /* AE76 (44662) */ + 3347, /* AE77 (44663) */ + 3347, /* AE78 (44664) */ + 3347, /* AE79 (44665) */ + 3347, /* AE7A (44666) */ + 3347, /* AE7B (44667) */ + 3347, /* AE7C (44668) */ + 3347, /* AE7D (44669) */ + 3347, /* AE7E (44670) */ + 3347, /* AE7F (44671) */ + 3347, /* AE80 (44672) */ + 3347, /* AE81 (44673) */ + 3347, /* AE82 (44674) */ + 3347, /* AE83 (44675) */ + 3347, /* AE84 (44676) */ + 3347, /* AE85 (44677) */ + 3347, /* AE86 (44678) */ + 3347, /* AE87 (44679) */ + 3347, /* AE88 (44680) */ + 3347, /* AE89 (44681) */ + 3347, /* AE8A (44682) */ + 3347, /* AE8B (44683) */ + 3347, /* AE8C (44684) */ + 3347, /* AE8D (44685) */ + 3347, /* AE8E (44686) */ + 3347, /* AE8F (44687) */ + 3347, /* AE90 (44688) */ + 3347, /* AE91 (44689) */ + 3347, /* AE92 (44690) */ + 3347, /* AE93 (44691) */ + 3347, /* AE94 (44692) */ + 3347, /* AE95 (44693) */ + 3347, /* AE96 (44694) */ + 3347, /* AE97 (44695) */ + 3347, /* AE98 (44696) */ + 3347, /* AE99 (44697) */ + 3347, /* AE9A (44698) */ + 3347, /* AE9B (44699) */ + 3347, /* AE9C (44700) */ + 3347, /* AE9D (44701) */ + 3347, /* AE9E (44702) */ + 3347, /* AE9F (44703) */ + 3347, /* AEA0 (44704) */ + 3347, /* AEA1 (44705) */ + 3347, /* AEA2 (44706) */ + 3347, /* AEA3 (44707) */ + 3347, /* AEA4 (44708) */ + 3347, /* AEA5 (44709) */ + 3347, /* AEA6 (44710) */ + 3347, /* AEA7 (44711) */ + 3347, /* AEA8 (44712) */ + 3347, /* AEA9 (44713) */ + 3347, /* AEAA (44714) */ + 3347, /* AEAB (44715) */ + 3347, /* AEAC (44716) */ + 3347, /* AEAD (44717) */ + 3347, /* AEAE (44718) */ + 3347, /* AEAF (44719) */ + 3347, /* AEB0 (44720) */ + 3347, /* AEB1 (44721) */ + 3347, /* AEB2 (44722) */ + 3347, /* AEB3 (44723) */ + 3347, /* AEB4 (44724) */ + 3347, /* AEB5 (44725) */ + 3347, /* AEB6 (44726) */ + 3347, /* AEB7 (44727) */ + 3347, /* AEB8 (44728) */ + 3347, /* AEB9 (44729) */ + 3347, /* AEBA (44730) */ + 3347, /* AEBB (44731) */ + 3347, /* AEBC (44732) */ + 3347, /* AEBD (44733) */ + 3347, /* AEBE (44734) */ + 3347, /* AEBF (44735) */ + 3347, /* AEC0 (44736) */ + 3347, /* AEC1 (44737) */ + 3347, /* AEC2 (44738) */ + 3347, /* AEC3 (44739) */ + 3347, /* AEC4 (44740) */ + 3347, /* AEC5 (44741) */ + 3347, /* AEC6 (44742) */ + 3347, /* AEC7 (44743) */ + 3347, /* AEC8 (44744) */ + 3347, /* AEC9 (44745) */ + 3347, /* AECA (44746) */ + 3347, /* AECB (44747) */ + 3347, /* AECC (44748) */ + 3347, /* AECD (44749) */ + 3347, /* AECE (44750) */ + 3347, /* AECF (44751) */ + 3347, /* AED0 (44752) */ + 3347, /* AED1 (44753) */ + 3347, /* AED2 (44754) */ + 3347, /* AED3 (44755) */ + 3347, /* AED4 (44756) */ + 3347, /* AED5 (44757) */ + 3347, /* AED6 (44758) */ + 3347, /* AED7 (44759) */ + 3347, /* AED8 (44760) */ + 3347, /* AED9 (44761) */ + 3347, /* AEDA (44762) */ + 3347, /* AEDB (44763) */ + 3347, /* AEDC (44764) */ + 3347, /* AEDD (44765) */ + 3347, /* AEDE (44766) */ + 3347, /* AEDF (44767) */ + 3347, /* AEE0 (44768) */ + 3347, /* AEE1 (44769) */ + 3347, /* AEE2 (44770) */ + 3347, /* AEE3 (44771) */ + 3347, /* AEE4 (44772) */ + 3347, /* AEE5 (44773) */ + 3347, /* AEE6 (44774) */ + 3347, /* AEE7 (44775) */ + 3347, /* AEE8 (44776) */ + 3347, /* AEE9 (44777) */ + 3347, /* AEEA (44778) */ + 3347, /* AEEB (44779) */ + 3347, /* AEEC (44780) */ + 3347, /* AEED (44781) */ + 3347, /* AEEE (44782) */ + 3347, /* AEEF (44783) */ + 3347, /* AEF0 (44784) */ + 3347, /* AEF1 (44785) */ + 3347, /* AEF2 (44786) */ + 3347, /* AEF3 (44787) */ + 3347, /* AEF4 (44788) */ + 3347, /* AEF5 (44789) */ + 3347, /* AEF6 (44790) */ + 3347, /* AEF7 (44791) */ + 3347, /* AEF8 (44792) */ + 3347, /* AEF9 (44793) */ + 3347, /* AEFA (44794) */ + 3347, /* AEFB (44795) */ + 3347, /* AEFC (44796) */ + 3347, /* AEFD (44797) */ + 3347, /* AEFE (44798) */ + 3347, /* AEFF (44799) */ + 3347, /* AF00 (44800) */ + 3347, /* AF01 (44801) */ + 3347, /* AF02 (44802) */ + 3347, /* AF03 (44803) */ + 3347, /* AF04 (44804) */ + 3347, /* AF05 (44805) */ + 3347, /* AF06 (44806) */ + 3347, /* AF07 (44807) */ + 3347, /* AF08 (44808) */ + 3347, /* AF09 (44809) */ + 3347, /* AF0A (44810) */ + 3347, /* AF0B (44811) */ + 3347, /* AF0C (44812) */ + 3347, /* AF0D (44813) */ + 3347, /* AF0E (44814) */ + 3347, /* AF0F (44815) */ + 3347, /* AF10 (44816) */ + 3347, /* AF11 (44817) */ + 3347, /* AF12 (44818) */ + 3347, /* AF13 (44819) */ + 3347, /* AF14 (44820) */ + 3347, /* AF15 (44821) */ + 3347, /* AF16 (44822) */ + 3347, /* AF17 (44823) */ + 3347, /* AF18 (44824) */ + 3347, /* AF19 (44825) */ + 3347, /* AF1A (44826) */ + 3347, /* AF1B (44827) */ + 3347, /* AF1C (44828) */ + 3347, /* AF1D (44829) */ + 3347, /* AF1E (44830) */ + 3347, /* AF1F (44831) */ + 3347, /* AF20 (44832) */ + 3347, /* AF21 (44833) */ + 3347, /* AF22 (44834) */ + 3347, /* AF23 (44835) */ + 3347, /* AF24 (44836) */ + 3347, /* AF25 (44837) */ + 3347, /* AF26 (44838) */ + 3347, /* AF27 (44839) */ + 3347, /* AF28 (44840) */ + 3347, /* AF29 (44841) */ + 3347, /* AF2A (44842) */ + 3347, /* AF2B (44843) */ + 3347, /* AF2C (44844) */ + 3347, /* AF2D (44845) */ + 3347, /* AF2E (44846) */ + 3347, /* AF2F (44847) */ + 3347, /* AF30 (44848) */ + 3347, /* AF31 (44849) */ + 3347, /* AF32 (44850) */ + 3347, /* AF33 (44851) */ + 3347, /* AF34 (44852) */ + 3347, /* AF35 (44853) */ + 3347, /* AF36 (44854) */ + 3347, /* AF37 (44855) */ + 3347, /* AF38 (44856) */ + 3347, /* AF39 (44857) */ + 3347, /* AF3A (44858) */ + 3347, /* AF3B (44859) */ + 3347, /* AF3C (44860) */ + 3347, /* AF3D (44861) */ + 3347, /* AF3E (44862) */ + 3347, /* AF3F (44863) */ + 3347, /* AF40 (44864) */ + 3347, /* AF41 (44865) */ + 3347, /* AF42 (44866) */ + 3347, /* AF43 (44867) */ + 3347, /* AF44 (44868) */ + 3347, /* AF45 (44869) */ + 3347, /* AF46 (44870) */ + 3347, /* AF47 (44871) */ + 3347, /* AF48 (44872) */ + 3347, /* AF49 (44873) */ + 3347, /* AF4A (44874) */ + 3347, /* AF4B (44875) */ + 3347, /* AF4C (44876) */ + 3347, /* AF4D (44877) */ + 3347, /* AF4E (44878) */ + 3347, /* AF4F (44879) */ + 3347, /* AF50 (44880) */ + 3347, /* AF51 (44881) */ + 3347, /* AF52 (44882) */ + 3347, /* AF53 (44883) */ + 3347, /* AF54 (44884) */ + 3347, /* AF55 (44885) */ + 3347, /* AF56 (44886) */ + 3347, /* AF57 (44887) */ + 3347, /* AF58 (44888) */ + 3347, /* AF59 (44889) */ + 3347, /* AF5A (44890) */ + 3347, /* AF5B (44891) */ + 3347, /* AF5C (44892) */ + 3347, /* AF5D (44893) */ + 3347, /* AF5E (44894) */ + 3347, /* AF5F (44895) */ + 3347, /* AF60 (44896) */ + 3347, /* AF61 (44897) */ + 3347, /* AF62 (44898) */ + 3347, /* AF63 (44899) */ + 3347, /* AF64 (44900) */ + 3347, /* AF65 (44901) */ + 3347, /* AF66 (44902) */ + 3347, /* AF67 (44903) */ + 3347, /* AF68 (44904) */ + 3347, /* AF69 (44905) */ + 3347, /* AF6A (44906) */ + 3347, /* AF6B (44907) */ + 3347, /* AF6C (44908) */ + 3347, /* AF6D (44909) */ + 3347, /* AF6E (44910) */ + 3347, /* AF6F (44911) */ + 3347, /* AF70 (44912) */ + 3347, /* AF71 (44913) */ + 3347, /* AF72 (44914) */ + 3347, /* AF73 (44915) */ + 3347, /* AF74 (44916) */ + 3347, /* AF75 (44917) */ + 3347, /* AF76 (44918) */ + 3347, /* AF77 (44919) */ + 3347, /* AF78 (44920) */ + 3347, /* AF79 (44921) */ + 3347, /* AF7A (44922) */ + 3347, /* AF7B (44923) */ + 3347, /* AF7C (44924) */ + 3347, /* AF7D (44925) */ + 3347, /* AF7E (44926) */ + 3347, /* AF7F (44927) */ + 3347, /* AF80 (44928) */ + 3347, /* AF81 (44929) */ + 3347, /* AF82 (44930) */ + 3347, /* AF83 (44931) */ + 3347, /* AF84 (44932) */ + 3347, /* AF85 (44933) */ + 3347, /* AF86 (44934) */ + 3347, /* AF87 (44935) */ + 3347, /* AF88 (44936) */ + 3347, /* AF89 (44937) */ + 3347, /* AF8A (44938) */ + 3347, /* AF8B (44939) */ + 3347, /* AF8C (44940) */ + 3347, /* AF8D (44941) */ + 3347, /* AF8E (44942) */ + 3347, /* AF8F (44943) */ + 3347, /* AF90 (44944) */ + 3347, /* AF91 (44945) */ + 3347, /* AF92 (44946) */ + 3347, /* AF93 (44947) */ + 3347, /* AF94 (44948) */ + 3347, /* AF95 (44949) */ + 3347, /* AF96 (44950) */ + 3347, /* AF97 (44951) */ + 3347, /* AF98 (44952) */ + 3347, /* AF99 (44953) */ + 3347, /* AF9A (44954) */ + 3347, /* AF9B (44955) */ + 3347, /* AF9C (44956) */ + 3347, /* AF9D (44957) */ + 3347, /* AF9E (44958) */ + 3347, /* AF9F (44959) */ + 3347, /* AFA0 (44960) */ + 3347, /* AFA1 (44961) */ + 3347, /* AFA2 (44962) */ + 3347, /* AFA3 (44963) */ + 3347, /* AFA4 (44964) */ + 3347, /* AFA5 (44965) */ + 3347, /* AFA6 (44966) */ + 3347, /* AFA7 (44967) */ + 3347, /* AFA8 (44968) */ + 3347, /* AFA9 (44969) */ + 3347, /* AFAA (44970) */ + 3347, /* AFAB (44971) */ + 3347, /* AFAC (44972) */ + 3347, /* AFAD (44973) */ + 3347, /* AFAE (44974) */ + 3347, /* AFAF (44975) */ + 3347, /* AFB0 (44976) */ + 3347, /* AFB1 (44977) */ + 3347, /* AFB2 (44978) */ + 3347, /* AFB3 (44979) */ + 3347, /* AFB4 (44980) */ + 3347, /* AFB5 (44981) */ + 3347, /* AFB6 (44982) */ + 3347, /* AFB7 (44983) */ + 3347, /* AFB8 (44984) */ + 3347, /* AFB9 (44985) */ + 3347, /* AFBA (44986) */ + 3347, /* AFBB (44987) */ + 3347, /* AFBC (44988) */ + 3347, /* AFBD (44989) */ + 3347, /* AFBE (44990) */ + 3347, /* AFBF (44991) */ + 3347, /* AFC0 (44992) */ + 3347, /* AFC1 (44993) */ + 3347, /* AFC2 (44994) */ + 3347, /* AFC3 (44995) */ + 3347, /* AFC4 (44996) */ + 3347, /* AFC5 (44997) */ + 3347, /* AFC6 (44998) */ + 3347, /* AFC7 (44999) */ + 3347, /* AFC8 (45000) */ + 3347, /* AFC9 (45001) */ + 3347, /* AFCA (45002) */ + 3347, /* AFCB (45003) */ + 3347, /* AFCC (45004) */ + 3347, /* AFCD (45005) */ + 3347, /* AFCE (45006) */ + 3347, /* AFCF (45007) */ + 3347, /* AFD0 (45008) */ + 3347, /* AFD1 (45009) */ + 3347, /* AFD2 (45010) */ + 3347, /* AFD3 (45011) */ + 3347, /* AFD4 (45012) */ + 3347, /* AFD5 (45013) */ + 3347, /* AFD6 (45014) */ + 3347, /* AFD7 (45015) */ + 3347, /* AFD8 (45016) */ + 3347, /* AFD9 (45017) */ + 3347, /* AFDA (45018) */ + 3347, /* AFDB (45019) */ + 3347, /* AFDC (45020) */ + 3347, /* AFDD (45021) */ + 3347, /* AFDE (45022) */ + 3347, /* AFDF (45023) */ + 3347, /* AFE0 (45024) */ + 3347, /* AFE1 (45025) */ + 3347, /* AFE2 (45026) */ + 3347, /* AFE3 (45027) */ + 3347, /* AFE4 (45028) */ + 3347, /* AFE5 (45029) */ + 3347, /* AFE6 (45030) */ + 3347, /* AFE7 (45031) */ + 3347, /* AFE8 (45032) */ + 3347, /* AFE9 (45033) */ + 3347, /* AFEA (45034) */ + 3347, /* AFEB (45035) */ + 3347, /* AFEC (45036) */ + 3347, /* AFED (45037) */ + 3347, /* AFEE (45038) */ + 3347, /* AFEF (45039) */ + 3347, /* AFF0 (45040) */ + 3347, /* AFF1 (45041) */ + 3347, /* AFF2 (45042) */ + 3347, /* AFF3 (45043) */ + 3347, /* AFF4 (45044) */ + 3347, /* AFF5 (45045) */ + 3347, /* AFF6 (45046) */ + 3347, /* AFF7 (45047) */ + 3347, /* AFF8 (45048) */ + 3347, /* AFF9 (45049) */ + 3347, /* AFFA (45050) */ + 3347, /* AFFB (45051) */ + 3347, /* AFFC (45052) */ + 3347, /* AFFD (45053) */ + 3347, /* AFFE (45054) */ + 3347, /* AFFF (45055) */ + 3347, /* B000 (45056) */ + 3347, /* B001 (45057) */ + 3347, /* B002 (45058) */ + 3347, /* B003 (45059) */ + 3347, /* B004 (45060) */ + 3347, /* B005 (45061) */ + 3347, /* B006 (45062) */ + 3347, /* B007 (45063) */ + 3347, /* B008 (45064) */ + 3347, /* B009 (45065) */ + 3347, /* B00A (45066) */ + 3347, /* B00B (45067) */ + 3347, /* B00C (45068) */ + 3347, /* B00D (45069) */ + 3347, /* B00E (45070) */ + 3347, /* B00F (45071) */ + 3347, /* B010 (45072) */ + 3347, /* B011 (45073) */ + 3347, /* B012 (45074) */ + 3347, /* B013 (45075) */ + 3347, /* B014 (45076) */ + 3347, /* B015 (45077) */ + 3347, /* B016 (45078) */ + 3347, /* B017 (45079) */ + 3347, /* B018 (45080) */ + 3347, /* B019 (45081) */ + 3347, /* B01A (45082) */ + 3347, /* B01B (45083) */ + 3347, /* B01C (45084) */ + 3347, /* B01D (45085) */ + 3347, /* B01E (45086) */ + 3347, /* B01F (45087) */ + 3347, /* B020 (45088) */ + 3347, /* B021 (45089) */ + 3347, /* B022 (45090) */ + 3347, /* B023 (45091) */ + 3347, /* B024 (45092) */ + 3347, /* B025 (45093) */ + 3347, /* B026 (45094) */ + 3347, /* B027 (45095) */ + 3347, /* B028 (45096) */ + 3347, /* B029 (45097) */ + 3347, /* B02A (45098) */ + 3347, /* B02B (45099) */ + 3347, /* B02C (45100) */ + 3347, /* B02D (45101) */ + 3347, /* B02E (45102) */ + 3347, /* B02F (45103) */ + 3347, /* B030 (45104) */ + 3347, /* B031 (45105) */ + 3347, /* B032 (45106) */ + 3347, /* B033 (45107) */ + 3347, /* B034 (45108) */ + 3347, /* B035 (45109) */ + 3347, /* B036 (45110) */ + 3347, /* B037 (45111) */ + 3347, /* B038 (45112) */ + 3347, /* B039 (45113) */ + 3347, /* B03A (45114) */ + 3347, /* B03B (45115) */ + 3347, /* B03C (45116) */ + 3347, /* B03D (45117) */ + 3347, /* B03E (45118) */ + 3347, /* B03F (45119) */ + 3347, /* B040 (45120) */ + 3347, /* B041 (45121) */ + 3347, /* B042 (45122) */ + 3347, /* B043 (45123) */ + 3347, /* B044 (45124) */ + 3347, /* B045 (45125) */ + 3347, /* B046 (45126) */ + 3347, /* B047 (45127) */ + 3347, /* B048 (45128) */ + 3347, /* B049 (45129) */ + 3347, /* B04A (45130) */ + 3347, /* B04B (45131) */ + 3347, /* B04C (45132) */ + 3347, /* B04D (45133) */ + 3347, /* B04E (45134) */ + 3347, /* B04F (45135) */ + 3347, /* B050 (45136) */ + 3347, /* B051 (45137) */ + 3347, /* B052 (45138) */ + 3347, /* B053 (45139) */ + 3347, /* B054 (45140) */ + 3347, /* B055 (45141) */ + 3347, /* B056 (45142) */ + 3347, /* B057 (45143) */ + 3347, /* B058 (45144) */ + 3347, /* B059 (45145) */ + 3347, /* B05A (45146) */ + 3347, /* B05B (45147) */ + 3347, /* B05C (45148) */ + 3347, /* B05D (45149) */ + 3347, /* B05E (45150) */ + 3347, /* B05F (45151) */ + 3347, /* B060 (45152) */ + 3347, /* B061 (45153) */ + 3347, /* B062 (45154) */ + 3347, /* B063 (45155) */ + 3347, /* B064 (45156) */ + 3347, /* B065 (45157) */ + 3347, /* B066 (45158) */ + 3347, /* B067 (45159) */ + 3347, /* B068 (45160) */ + 3347, /* B069 (45161) */ + 3347, /* B06A (45162) */ + 3347, /* B06B (45163) */ + 3347, /* B06C (45164) */ + 3347, /* B06D (45165) */ + 3347, /* B06E (45166) */ + 3347, /* B06F (45167) */ + 3347, /* B070 (45168) */ + 3347, /* B071 (45169) */ + 3347, /* B072 (45170) */ + 3347, /* B073 (45171) */ + 3347, /* B074 (45172) */ + 3347, /* B075 (45173) */ + 3347, /* B076 (45174) */ + 3347, /* B077 (45175) */ + 3347, /* B078 (45176) */ + 3347, /* B079 (45177) */ + 3347, /* B07A (45178) */ + 3347, /* B07B (45179) */ + 3347, /* B07C (45180) */ + 3347, /* B07D (45181) */ + 3347, /* B07E (45182) */ + 3347, /* B07F (45183) */ + 3347, /* B080 (45184) */ + 3347, /* B081 (45185) */ + 3347, /* B082 (45186) */ + 3347, /* B083 (45187) */ + 3347, /* B084 (45188) */ + 3347, /* B085 (45189) */ + 3347, /* B086 (45190) */ + 3347, /* B087 (45191) */ + 3347, /* B088 (45192) */ + 3347, /* B089 (45193) */ + 3347, /* B08A (45194) */ + 3347, /* B08B (45195) */ + 3347, /* B08C (45196) */ + 3347, /* B08D (45197) */ + 3347, /* B08E (45198) */ + 3347, /* B08F (45199) */ + 3347, /* B090 (45200) */ + 3347, /* B091 (45201) */ + 3347, /* B092 (45202) */ + 3347, /* B093 (45203) */ + 3347, /* B094 (45204) */ + 3347, /* B095 (45205) */ + 3347, /* B096 (45206) */ + 3347, /* B097 (45207) */ + 3347, /* B098 (45208) */ + 3347, /* B099 (45209) */ + 3347, /* B09A (45210) */ + 3347, /* B09B (45211) */ + 3347, /* B09C (45212) */ + 3347, /* B09D (45213) */ + 3347, /* B09E (45214) */ + 3347, /* B09F (45215) */ + 3347, /* B0A0 (45216) */ + 3347, /* B0A1 (45217) */ + 3347, /* B0A2 (45218) */ + 3347, /* B0A3 (45219) */ + 3347, /* B0A4 (45220) */ + 3347, /* B0A5 (45221) */ + 3347, /* B0A6 (45222) */ + 3347, /* B0A7 (45223) */ + 3347, /* B0A8 (45224) */ + 3347, /* B0A9 (45225) */ + 3347, /* B0AA (45226) */ + 3347, /* B0AB (45227) */ + 3347, /* B0AC (45228) */ + 3347, /* B0AD (45229) */ + 3347, /* B0AE (45230) */ + 3347, /* B0AF (45231) */ + 3347, /* B0B0 (45232) */ + 3347, /* B0B1 (45233) */ + 3347, /* B0B2 (45234) */ + 3347, /* B0B3 (45235) */ + 3347, /* B0B4 (45236) */ + 3347, /* B0B5 (45237) */ + 3347, /* B0B6 (45238) */ + 3347, /* B0B7 (45239) */ + 3347, /* B0B8 (45240) */ + 3347, /* B0B9 (45241) */ + 3347, /* B0BA (45242) */ + 3347, /* B0BB (45243) */ + 3347, /* B0BC (45244) */ + 3347, /* B0BD (45245) */ + 3347, /* B0BE (45246) */ + 3347, /* B0BF (45247) */ + 3347, /* B0C0 (45248) */ + 3347, /* B0C1 (45249) */ + 3347, /* B0C2 (45250) */ + 3347, /* B0C3 (45251) */ + 3347, /* B0C4 (45252) */ + 3347, /* B0C5 (45253) */ + 3347, /* B0C6 (45254) */ + 3347, /* B0C7 (45255) */ + 3347, /* B0C8 (45256) */ + 3347, /* B0C9 (45257) */ + 3347, /* B0CA (45258) */ + 3347, /* B0CB (45259) */ + 3347, /* B0CC (45260) */ + 3347, /* B0CD (45261) */ + 3347, /* B0CE (45262) */ + 3347, /* B0CF (45263) */ + 3347, /* B0D0 (45264) */ + 3347, /* B0D1 (45265) */ + 3347, /* B0D2 (45266) */ + 3347, /* B0D3 (45267) */ + 3347, /* B0D4 (45268) */ + 3347, /* B0D5 (45269) */ + 3347, /* B0D6 (45270) */ + 3347, /* B0D7 (45271) */ + 3347, /* B0D8 (45272) */ + 3347, /* B0D9 (45273) */ + 3347, /* B0DA (45274) */ + 3347, /* B0DB (45275) */ + 3347, /* B0DC (45276) */ + 3347, /* B0DD (45277) */ + 3347, /* B0DE (45278) */ + 3347, /* B0DF (45279) */ + 3347, /* B0E0 (45280) */ + 3347, /* B0E1 (45281) */ + 3347, /* B0E2 (45282) */ + 3347, /* B0E3 (45283) */ + 3347, /* B0E4 (45284) */ + 3347, /* B0E5 (45285) */ + 3347, /* B0E6 (45286) */ + 3347, /* B0E7 (45287) */ + 3347, /* B0E8 (45288) */ + 3347, /* B0E9 (45289) */ + 3347, /* B0EA (45290) */ + 3347, /* B0EB (45291) */ + 3347, /* B0EC (45292) */ + 3347, /* B0ED (45293) */ + 3347, /* B0EE (45294) */ + 3347, /* B0EF (45295) */ + 3347, /* B0F0 (45296) */ + 3347, /* B0F1 (45297) */ + 3347, /* B0F2 (45298) */ + 3347, /* B0F3 (45299) */ + 3347, /* B0F4 (45300) */ + 3347, /* B0F5 (45301) */ + 3347, /* B0F6 (45302) */ + 3347, /* B0F7 (45303) */ + 3347, /* B0F8 (45304) */ + 3347, /* B0F9 (45305) */ + 3347, /* B0FA (45306) */ + 3347, /* B0FB (45307) */ + 3347, /* B0FC (45308) */ + 3347, /* B0FD (45309) */ + 3347, /* B0FE (45310) */ + 3347, /* B0FF (45311) */ + 3347, /* B100 (45312) */ + 3347, /* B101 (45313) */ + 3347, /* B102 (45314) */ + 3347, /* B103 (45315) */ + 3347, /* B104 (45316) */ + 3347, /* B105 (45317) */ + 3347, /* B106 (45318) */ + 3347, /* B107 (45319) */ + 3347, /* B108 (45320) */ + 3347, /* B109 (45321) */ + 3347, /* B10A (45322) */ + 3347, /* B10B (45323) */ + 3347, /* B10C (45324) */ + 3347, /* B10D (45325) */ + 3347, /* B10E (45326) */ + 3347, /* B10F (45327) */ + 3347, /* B110 (45328) */ + 3347, /* B111 (45329) */ + 3347, /* B112 (45330) */ + 3347, /* B113 (45331) */ + 3347, /* B114 (45332) */ + 3347, /* B115 (45333) */ + 3347, /* B116 (45334) */ + 3347, /* B117 (45335) */ + 3347, /* B118 (45336) */ + 3347, /* B119 (45337) */ + 3347, /* B11A (45338) */ + 3347, /* B11B (45339) */ + 3347, /* B11C (45340) */ + 3347, /* B11D (45341) */ + 3347, /* B11E (45342) */ + 3347, /* B11F (45343) */ + 3347, /* B120 (45344) */ + 3347, /* B121 (45345) */ + 3347, /* B122 (45346) */ + 3347, /* B123 (45347) */ + 3347, /* B124 (45348) */ + 3347, /* B125 (45349) */ + 3347, /* B126 (45350) */ + 3347, /* B127 (45351) */ + 3347, /* B128 (45352) */ + 3347, /* B129 (45353) */ + 3347, /* B12A (45354) */ + 3347, /* B12B (45355) */ + 3347, /* B12C (45356) */ + 3347, /* B12D (45357) */ + 3347, /* B12E (45358) */ + 3347, /* B12F (45359) */ + 3347, /* B130 (45360) */ + 3347, /* B131 (45361) */ + 3347, /* B132 (45362) */ + 3347, /* B133 (45363) */ + 3347, /* B134 (45364) */ + 3347, /* B135 (45365) */ + 3347, /* B136 (45366) */ + 3347, /* B137 (45367) */ + 3347, /* B138 (45368) */ + 3347, /* B139 (45369) */ + 3347, /* B13A (45370) */ + 3347, /* B13B (45371) */ + 3347, /* B13C (45372) */ + 3347, /* B13D (45373) */ + 3347, /* B13E (45374) */ + 3347, /* B13F (45375) */ + 3347, /* B140 (45376) */ + 3347, /* B141 (45377) */ + 3347, /* B142 (45378) */ + 3347, /* B143 (45379) */ + 3347, /* B144 (45380) */ + 3347, /* B145 (45381) */ + 3347, /* B146 (45382) */ + 3347, /* B147 (45383) */ + 3347, /* B148 (45384) */ + 3347, /* B149 (45385) */ + 3347, /* B14A (45386) */ + 3347, /* B14B (45387) */ + 3347, /* B14C (45388) */ + 3347, /* B14D (45389) */ + 3347, /* B14E (45390) */ + 3347, /* B14F (45391) */ + 3347, /* B150 (45392) */ + 3347, /* B151 (45393) */ + 3347, /* B152 (45394) */ + 3347, /* B153 (45395) */ + 3347, /* B154 (45396) */ + 3347, /* B155 (45397) */ + 3347, /* B156 (45398) */ + 3347, /* B157 (45399) */ + 3347, /* B158 (45400) */ + 3347, /* B159 (45401) */ + 3347, /* B15A (45402) */ + 3347, /* B15B (45403) */ + 3347, /* B15C (45404) */ + 3347, /* B15D (45405) */ + 3347, /* B15E (45406) */ + 3347, /* B15F (45407) */ + 3347, /* B160 (45408) */ + 3347, /* B161 (45409) */ + 3347, /* B162 (45410) */ + 3347, /* B163 (45411) */ + 3347, /* B164 (45412) */ + 3347, /* B165 (45413) */ + 3347, /* B166 (45414) */ + 3347, /* B167 (45415) */ + 3347, /* B168 (45416) */ + 3347, /* B169 (45417) */ + 3347, /* B16A (45418) */ + 3347, /* B16B (45419) */ + 3347, /* B16C (45420) */ + 3347, /* B16D (45421) */ + 3347, /* B16E (45422) */ + 3347, /* B16F (45423) */ + 3347, /* B170 (45424) */ + 3347, /* B171 (45425) */ + 3347, /* B172 (45426) */ + 3347, /* B173 (45427) */ + 3347, /* B174 (45428) */ + 3347, /* B175 (45429) */ + 3347, /* B176 (45430) */ + 3347, /* B177 (45431) */ + 3347, /* B178 (45432) */ + 3347, /* B179 (45433) */ + 3347, /* B17A (45434) */ + 3347, /* B17B (45435) */ + 3347, /* B17C (45436) */ + 3347, /* B17D (45437) */ + 3347, /* B17E (45438) */ + 3347, /* B17F (45439) */ + 3347, /* B180 (45440) */ + 3347, /* B181 (45441) */ + 3347, /* B182 (45442) */ + 3347, /* B183 (45443) */ + 3347, /* B184 (45444) */ + 3347, /* B185 (45445) */ + 3347, /* B186 (45446) */ + 3347, /* B187 (45447) */ + 3347, /* B188 (45448) */ + 3347, /* B189 (45449) */ + 3347, /* B18A (45450) */ + 3347, /* B18B (45451) */ + 3347, /* B18C (45452) */ + 3347, /* B18D (45453) */ + 3347, /* B18E (45454) */ + 3347, /* B18F (45455) */ + 3347, /* B190 (45456) */ + 3347, /* B191 (45457) */ + 3347, /* B192 (45458) */ + 3347, /* B193 (45459) */ + 3347, /* B194 (45460) */ + 3347, /* B195 (45461) */ + 3347, /* B196 (45462) */ + 3347, /* B197 (45463) */ + 3347, /* B198 (45464) */ + 3347, /* B199 (45465) */ + 3347, /* B19A (45466) */ + 3347, /* B19B (45467) */ + 3347, /* B19C (45468) */ + 3347, /* B19D (45469) */ + 3347, /* B19E (45470) */ + 3347, /* B19F (45471) */ + 3347, /* B1A0 (45472) */ + 3347, /* B1A1 (45473) */ + 3347, /* B1A2 (45474) */ + 3347, /* B1A3 (45475) */ + 3347, /* B1A4 (45476) */ + 3347, /* B1A5 (45477) */ + 3347, /* B1A6 (45478) */ + 3347, /* B1A7 (45479) */ + 3347, /* B1A8 (45480) */ + 3347, /* B1A9 (45481) */ + 3347, /* B1AA (45482) */ + 3347, /* B1AB (45483) */ + 3347, /* B1AC (45484) */ + 3347, /* B1AD (45485) */ + 3347, /* B1AE (45486) */ + 3347, /* B1AF (45487) */ + 3347, /* B1B0 (45488) */ + 3347, /* B1B1 (45489) */ + 3347, /* B1B2 (45490) */ + 3347, /* B1B3 (45491) */ + 3347, /* B1B4 (45492) */ + 3347, /* B1B5 (45493) */ + 3347, /* B1B6 (45494) */ + 3347, /* B1B7 (45495) */ + 3347, /* B1B8 (45496) */ + 3347, /* B1B9 (45497) */ + 3347, /* B1BA (45498) */ + 3347, /* B1BB (45499) */ + 3347, /* B1BC (45500) */ + 3347, /* B1BD (45501) */ + 3347, /* B1BE (45502) */ + 3347, /* B1BF (45503) */ + 3347, /* B1C0 (45504) */ + 3347, /* B1C1 (45505) */ + 3347, /* B1C2 (45506) */ + 3347, /* B1C3 (45507) */ + 3347, /* B1C4 (45508) */ + 3347, /* B1C5 (45509) */ + 3347, /* B1C6 (45510) */ + 3347, /* B1C7 (45511) */ + 3347, /* B1C8 (45512) */ + 3347, /* B1C9 (45513) */ + 3347, /* B1CA (45514) */ + 3347, /* B1CB (45515) */ + 3347, /* B1CC (45516) */ + 3347, /* B1CD (45517) */ + 3347, /* B1CE (45518) */ + 3347, /* B1CF (45519) */ + 3347, /* B1D0 (45520) */ + 3347, /* B1D1 (45521) */ + 3347, /* B1D2 (45522) */ + 3347, /* B1D3 (45523) */ + 3347, /* B1D4 (45524) */ + 3347, /* B1D5 (45525) */ + 3347, /* B1D6 (45526) */ + 3347, /* B1D7 (45527) */ + 3347, /* B1D8 (45528) */ + 3347, /* B1D9 (45529) */ + 3347, /* B1DA (45530) */ + 3347, /* B1DB (45531) */ + 3347, /* B1DC (45532) */ + 3347, /* B1DD (45533) */ + 3347, /* B1DE (45534) */ + 3347, /* B1DF (45535) */ + 3347, /* B1E0 (45536) */ + 3347, /* B1E1 (45537) */ + 3347, /* B1E2 (45538) */ + 3347, /* B1E3 (45539) */ + 3347, /* B1E4 (45540) */ + 3347, /* B1E5 (45541) */ + 3347, /* B1E6 (45542) */ + 3347, /* B1E7 (45543) */ + 3347, /* B1E8 (45544) */ + 3347, /* B1E9 (45545) */ + 3347, /* B1EA (45546) */ + 3347, /* B1EB (45547) */ + 3347, /* B1EC (45548) */ + 3347, /* B1ED (45549) */ + 3347, /* B1EE (45550) */ + 3347, /* B1EF (45551) */ + 3347, /* B1F0 (45552) */ + 3347, /* B1F1 (45553) */ + 3347, /* B1F2 (45554) */ + 3347, /* B1F3 (45555) */ + 3347, /* B1F4 (45556) */ + 3347, /* B1F5 (45557) */ + 3347, /* B1F6 (45558) */ + 3347, /* B1F7 (45559) */ + 3347, /* B1F8 (45560) */ + 3347, /* B1F9 (45561) */ + 3347, /* B1FA (45562) */ + 3347, /* B1FB (45563) */ + 3347, /* B1FC (45564) */ + 3347, /* B1FD (45565) */ + 3347, /* B1FE (45566) */ + 3347, /* B1FF (45567) */ + 3347, /* B200 (45568) */ + 3347, /* B201 (45569) */ + 3347, /* B202 (45570) */ + 3347, /* B203 (45571) */ + 3347, /* B204 (45572) */ + 3347, /* B205 (45573) */ + 3347, /* B206 (45574) */ + 3347, /* B207 (45575) */ + 3347, /* B208 (45576) */ + 3347, /* B209 (45577) */ + 3347, /* B20A (45578) */ + 3347, /* B20B (45579) */ + 3347, /* B20C (45580) */ + 3347, /* B20D (45581) */ + 3347, /* B20E (45582) */ + 3347, /* B20F (45583) */ + 3347, /* B210 (45584) */ + 3347, /* B211 (45585) */ + 3347, /* B212 (45586) */ + 3347, /* B213 (45587) */ + 3347, /* B214 (45588) */ + 3347, /* B215 (45589) */ + 3347, /* B216 (45590) */ + 3347, /* B217 (45591) */ + 3347, /* B218 (45592) */ + 3347, /* B219 (45593) */ + 3347, /* B21A (45594) */ + 3347, /* B21B (45595) */ + 3347, /* B21C (45596) */ + 3347, /* B21D (45597) */ + 3347, /* B21E (45598) */ + 3347, /* B21F (45599) */ + 3347, /* B220 (45600) */ + 3347, /* B221 (45601) */ + 3347, /* B222 (45602) */ + 3347, /* B223 (45603) */ + 3347, /* B224 (45604) */ + 3347, /* B225 (45605) */ + 3347, /* B226 (45606) */ + 3347, /* B227 (45607) */ + 3347, /* B228 (45608) */ + 3347, /* B229 (45609) */ + 3347, /* B22A (45610) */ + 3347, /* B22B (45611) */ + 3347, /* B22C (45612) */ + 3347, /* B22D (45613) */ + 3347, /* B22E (45614) */ + 3347, /* B22F (45615) */ + 3347, /* B230 (45616) */ + 3347, /* B231 (45617) */ + 3347, /* B232 (45618) */ + 3347, /* B233 (45619) */ + 3347, /* B234 (45620) */ + 3347, /* B235 (45621) */ + 3347, /* B236 (45622) */ + 3347, /* B237 (45623) */ + 3347, /* B238 (45624) */ + 3347, /* B239 (45625) */ + 3347, /* B23A (45626) */ + 3347, /* B23B (45627) */ + 3347, /* B23C (45628) */ + 3347, /* B23D (45629) */ + 3347, /* B23E (45630) */ + 3347, /* B23F (45631) */ + 3347, /* B240 (45632) */ + 3347, /* B241 (45633) */ + 3347, /* B242 (45634) */ + 3347, /* B243 (45635) */ + 3347, /* B244 (45636) */ + 3347, /* B245 (45637) */ + 3347, /* B246 (45638) */ + 3347, /* B247 (45639) */ + 3347, /* B248 (45640) */ + 3347, /* B249 (45641) */ + 3347, /* B24A (45642) */ + 3347, /* B24B (45643) */ + 3347, /* B24C (45644) */ + 3347, /* B24D (45645) */ + 3347, /* B24E (45646) */ + 3347, /* B24F (45647) */ + 3347, /* B250 (45648) */ + 3347, /* B251 (45649) */ + 3347, /* B252 (45650) */ + 3347, /* B253 (45651) */ + 3347, /* B254 (45652) */ + 3347, /* B255 (45653) */ + 3347, /* B256 (45654) */ + 3347, /* B257 (45655) */ + 3347, /* B258 (45656) */ + 3347, /* B259 (45657) */ + 3347, /* B25A (45658) */ + 3347, /* B25B (45659) */ + 3347, /* B25C (45660) */ + 3347, /* B25D (45661) */ + 3347, /* B25E (45662) */ + 3347, /* B25F (45663) */ + 3347, /* B260 (45664) */ + 3347, /* B261 (45665) */ + 3347, /* B262 (45666) */ + 3347, /* B263 (45667) */ + 3347, /* B264 (45668) */ + 3347, /* B265 (45669) */ + 3347, /* B266 (45670) */ + 3347, /* B267 (45671) */ + 3347, /* B268 (45672) */ + 3347, /* B269 (45673) */ + 3347, /* B26A (45674) */ + 3347, /* B26B (45675) */ + 3347, /* B26C (45676) */ + 3347, /* B26D (45677) */ + 3347, /* B26E (45678) */ + 3347, /* B26F (45679) */ + 3347, /* B270 (45680) */ + 3347, /* B271 (45681) */ + 3347, /* B272 (45682) */ + 3347, /* B273 (45683) */ + 3347, /* B274 (45684) */ + 3347, /* B275 (45685) */ + 3347, /* B276 (45686) */ + 3347, /* B277 (45687) */ + 3347, /* B278 (45688) */ + 3347, /* B279 (45689) */ + 3347, /* B27A (45690) */ + 3347, /* B27B (45691) */ + 3347, /* B27C (45692) */ + 3347, /* B27D (45693) */ + 3347, /* B27E (45694) */ + 3347, /* B27F (45695) */ + 3347, /* B280 (45696) */ + 3347, /* B281 (45697) */ + 3347, /* B282 (45698) */ + 3347, /* B283 (45699) */ + 3347, /* B284 (45700) */ + 3347, /* B285 (45701) */ + 3347, /* B286 (45702) */ + 3347, /* B287 (45703) */ + 3347, /* B288 (45704) */ + 3347, /* B289 (45705) */ + 3347, /* B28A (45706) */ + 3347, /* B28B (45707) */ + 3347, /* B28C (45708) */ + 3347, /* B28D (45709) */ + 3347, /* B28E (45710) */ + 3347, /* B28F (45711) */ + 3347, /* B290 (45712) */ + 3347, /* B291 (45713) */ + 3347, /* B292 (45714) */ + 3347, /* B293 (45715) */ + 3347, /* B294 (45716) */ + 3347, /* B295 (45717) */ + 3347, /* B296 (45718) */ + 3347, /* B297 (45719) */ + 3347, /* B298 (45720) */ + 3347, /* B299 (45721) */ + 3347, /* B29A (45722) */ + 3347, /* B29B (45723) */ + 3347, /* B29C (45724) */ + 3347, /* B29D (45725) */ + 3347, /* B29E (45726) */ + 3347, /* B29F (45727) */ + 3347, /* B2A0 (45728) */ + 3347, /* B2A1 (45729) */ + 3347, /* B2A2 (45730) */ + 3347, /* B2A3 (45731) */ + 3347, /* B2A4 (45732) */ + 3347, /* B2A5 (45733) */ + 3347, /* B2A6 (45734) */ + 3347, /* B2A7 (45735) */ + 3347, /* B2A8 (45736) */ + 3347, /* B2A9 (45737) */ + 3347, /* B2AA (45738) */ + 3347, /* B2AB (45739) */ + 3347, /* B2AC (45740) */ + 3347, /* B2AD (45741) */ + 3347, /* B2AE (45742) */ + 3347, /* B2AF (45743) */ + 3347, /* B2B0 (45744) */ + 3347, /* B2B1 (45745) */ + 3347, /* B2B2 (45746) */ + 3347, /* B2B3 (45747) */ + 3347, /* B2B4 (45748) */ + 3347, /* B2B5 (45749) */ + 3347, /* B2B6 (45750) */ + 3347, /* B2B7 (45751) */ + 3347, /* B2B8 (45752) */ + 3347, /* B2B9 (45753) */ + 3347, /* B2BA (45754) */ + 3347, /* B2BB (45755) */ + 3347, /* B2BC (45756) */ + 3347, /* B2BD (45757) */ + 3347, /* B2BE (45758) */ + 3347, /* B2BF (45759) */ + 3347, /* B2C0 (45760) */ + 3347, /* B2C1 (45761) */ + 3347, /* B2C2 (45762) */ + 3347, /* B2C3 (45763) */ + 3347, /* B2C4 (45764) */ + 3347, /* B2C5 (45765) */ + 3347, /* B2C6 (45766) */ + 3347, /* B2C7 (45767) */ + 3347, /* B2C8 (45768) */ + 3347, /* B2C9 (45769) */ + 3347, /* B2CA (45770) */ + 3347, /* B2CB (45771) */ + 3347, /* B2CC (45772) */ + 3347, /* B2CD (45773) */ + 3347, /* B2CE (45774) */ + 3347, /* B2CF (45775) */ + 3347, /* B2D0 (45776) */ + 3347, /* B2D1 (45777) */ + 3347, /* B2D2 (45778) */ + 3347, /* B2D3 (45779) */ + 3347, /* B2D4 (45780) */ + 3347, /* B2D5 (45781) */ + 3347, /* B2D6 (45782) */ + 3347, /* B2D7 (45783) */ + 3347, /* B2D8 (45784) */ + 3347, /* B2D9 (45785) */ + 3347, /* B2DA (45786) */ + 3347, /* B2DB (45787) */ + 3347, /* B2DC (45788) */ + 3347, /* B2DD (45789) */ + 3347, /* B2DE (45790) */ + 3347, /* B2DF (45791) */ + 3347, /* B2E0 (45792) */ + 3347, /* B2E1 (45793) */ + 3347, /* B2E2 (45794) */ + 3347, /* B2E3 (45795) */ + 3347, /* B2E4 (45796) */ + 3347, /* B2E5 (45797) */ + 3347, /* B2E6 (45798) */ + 3347, /* B2E7 (45799) */ + 3347, /* B2E8 (45800) */ + 3347, /* B2E9 (45801) */ + 3347, /* B2EA (45802) */ + 3347, /* B2EB (45803) */ + 3347, /* B2EC (45804) */ + 3347, /* B2ED (45805) */ + 3347, /* B2EE (45806) */ + 3347, /* B2EF (45807) */ + 3347, /* B2F0 (45808) */ + 3347, /* B2F1 (45809) */ + 3347, /* B2F2 (45810) */ + 3347, /* B2F3 (45811) */ + 3347, /* B2F4 (45812) */ + 3347, /* B2F5 (45813) */ + 3347, /* B2F6 (45814) */ + 3347, /* B2F7 (45815) */ + 3347, /* B2F8 (45816) */ + 3347, /* B2F9 (45817) */ + 3347, /* B2FA (45818) */ + 3347, /* B2FB (45819) */ + 3347, /* B2FC (45820) */ + 3347, /* B2FD (45821) */ + 3347, /* B2FE (45822) */ + 3347, /* B2FF (45823) */ + 3347, /* B300 (45824) */ + 3347, /* B301 (45825) */ + 3347, /* B302 (45826) */ + 3347, /* B303 (45827) */ + 3347, /* B304 (45828) */ + 3347, /* B305 (45829) */ + 3347, /* B306 (45830) */ + 3347, /* B307 (45831) */ + 3347, /* B308 (45832) */ + 3347, /* B309 (45833) */ + 3347, /* B30A (45834) */ + 3347, /* B30B (45835) */ + 3347, /* B30C (45836) */ + 3347, /* B30D (45837) */ + 3347, /* B30E (45838) */ + 3347, /* B30F (45839) */ + 3347, /* B310 (45840) */ + 3347, /* B311 (45841) */ + 3347, /* B312 (45842) */ + 3347, /* B313 (45843) */ + 3347, /* B314 (45844) */ + 3347, /* B315 (45845) */ + 3347, /* B316 (45846) */ + 3347, /* B317 (45847) */ + 3347, /* B318 (45848) */ + 3347, /* B319 (45849) */ + 3347, /* B31A (45850) */ + 3347, /* B31B (45851) */ + 3347, /* B31C (45852) */ + 3347, /* B31D (45853) */ + 3347, /* B31E (45854) */ + 3347, /* B31F (45855) */ + 3347, /* B320 (45856) */ + 3347, /* B321 (45857) */ + 3347, /* B322 (45858) */ + 3347, /* B323 (45859) */ + 3347, /* B324 (45860) */ + 3347, /* B325 (45861) */ + 3347, /* B326 (45862) */ + 3347, /* B327 (45863) */ + 3347, /* B328 (45864) */ + 3347, /* B329 (45865) */ + 3347, /* B32A (45866) */ + 3347, /* B32B (45867) */ + 3347, /* B32C (45868) */ + 3347, /* B32D (45869) */ + 3347, /* B32E (45870) */ + 3347, /* B32F (45871) */ + 3347, /* B330 (45872) */ + 3347, /* B331 (45873) */ + 3347, /* B332 (45874) */ + 3347, /* B333 (45875) */ + 3347, /* B334 (45876) */ + 3347, /* B335 (45877) */ + 3347, /* B336 (45878) */ + 3347, /* B337 (45879) */ + 3347, /* B338 (45880) */ + 3347, /* B339 (45881) */ + 3347, /* B33A (45882) */ + 3347, /* B33B (45883) */ + 3347, /* B33C (45884) */ + 3347, /* B33D (45885) */ + 3347, /* B33E (45886) */ + 3347, /* B33F (45887) */ + 3347, /* B340 (45888) */ + 3347, /* B341 (45889) */ + 3347, /* B342 (45890) */ + 3347, /* B343 (45891) */ + 3347, /* B344 (45892) */ + 3347, /* B345 (45893) */ + 3347, /* B346 (45894) */ + 3347, /* B347 (45895) */ + 3347, /* B348 (45896) */ + 3347, /* B349 (45897) */ + 3347, /* B34A (45898) */ + 3347, /* B34B (45899) */ + 3347, /* B34C (45900) */ + 3347, /* B34D (45901) */ + 3347, /* B34E (45902) */ + 3347, /* B34F (45903) */ + 3347, /* B350 (45904) */ + 3347, /* B351 (45905) */ + 3347, /* B352 (45906) */ + 3347, /* B353 (45907) */ + 3347, /* B354 (45908) */ + 3347, /* B355 (45909) */ + 3347, /* B356 (45910) */ + 3347, /* B357 (45911) */ + 3347, /* B358 (45912) */ + 3347, /* B359 (45913) */ + 3347, /* B35A (45914) */ + 3347, /* B35B (45915) */ + 3347, /* B35C (45916) */ + 3347, /* B35D (45917) */ + 3347, /* B35E (45918) */ + 3347, /* B35F (45919) */ + 3347, /* B360 (45920) */ + 3347, /* B361 (45921) */ + 3347, /* B362 (45922) */ + 3347, /* B363 (45923) */ + 3347, /* B364 (45924) */ + 3347, /* B365 (45925) */ + 3347, /* B366 (45926) */ + 3347, /* B367 (45927) */ + 3347, /* B368 (45928) */ + 3347, /* B369 (45929) */ + 3347, /* B36A (45930) */ + 3347, /* B36B (45931) */ + 3347, /* B36C (45932) */ + 3347, /* B36D (45933) */ + 3347, /* B36E (45934) */ + 3347, /* B36F (45935) */ + 3347, /* B370 (45936) */ + 3347, /* B371 (45937) */ + 3347, /* B372 (45938) */ + 3347, /* B373 (45939) */ + 3347, /* B374 (45940) */ + 3347, /* B375 (45941) */ + 3347, /* B376 (45942) */ + 3347, /* B377 (45943) */ + 3347, /* B378 (45944) */ + 3347, /* B379 (45945) */ + 3347, /* B37A (45946) */ + 3347, /* B37B (45947) */ + 3347, /* B37C (45948) */ + 3347, /* B37D (45949) */ + 3347, /* B37E (45950) */ + 3347, /* B37F (45951) */ + 3347, /* B380 (45952) */ + 3347, /* B381 (45953) */ + 3347, /* B382 (45954) */ + 3347, /* B383 (45955) */ + 3347, /* B384 (45956) */ + 3347, /* B385 (45957) */ + 3347, /* B386 (45958) */ + 3347, /* B387 (45959) */ + 3347, /* B388 (45960) */ + 3347, /* B389 (45961) */ + 3347, /* B38A (45962) */ + 3347, /* B38B (45963) */ + 3347, /* B38C (45964) */ + 3347, /* B38D (45965) */ + 3347, /* B38E (45966) */ + 3347, /* B38F (45967) */ + 3347, /* B390 (45968) */ + 3347, /* B391 (45969) */ + 3347, /* B392 (45970) */ + 3347, /* B393 (45971) */ + 3347, /* B394 (45972) */ + 3347, /* B395 (45973) */ + 3347, /* B396 (45974) */ + 3347, /* B397 (45975) */ + 3347, /* B398 (45976) */ + 3347, /* B399 (45977) */ + 3347, /* B39A (45978) */ + 3347, /* B39B (45979) */ + 3347, /* B39C (45980) */ + 3347, /* B39D (45981) */ + 3347, /* B39E (45982) */ + 3347, /* B39F (45983) */ + 3347, /* B3A0 (45984) */ + 3347, /* B3A1 (45985) */ + 3347, /* B3A2 (45986) */ + 3347, /* B3A3 (45987) */ + 3347, /* B3A4 (45988) */ + 3347, /* B3A5 (45989) */ + 3347, /* B3A6 (45990) */ + 3347, /* B3A7 (45991) */ + 3347, /* B3A8 (45992) */ + 3347, /* B3A9 (45993) */ + 3347, /* B3AA (45994) */ + 3347, /* B3AB (45995) */ + 3347, /* B3AC (45996) */ + 3347, /* B3AD (45997) */ + 3347, /* B3AE (45998) */ + 3347, /* B3AF (45999) */ + 3347, /* B3B0 (46000) */ + 3347, /* B3B1 (46001) */ + 3347, /* B3B2 (46002) */ + 3347, /* B3B3 (46003) */ + 3347, /* B3B4 (46004) */ + 3347, /* B3B5 (46005) */ + 3347, /* B3B6 (46006) */ + 3347, /* B3B7 (46007) */ + 3347, /* B3B8 (46008) */ + 3347, /* B3B9 (46009) */ + 3347, /* B3BA (46010) */ + 3347, /* B3BB (46011) */ + 3347, /* B3BC (46012) */ + 3347, /* B3BD (46013) */ + 3347, /* B3BE (46014) */ + 3347, /* B3BF (46015) */ + 3347, /* B3C0 (46016) */ + 3347, /* B3C1 (46017) */ + 3347, /* B3C2 (46018) */ + 3347, /* B3C3 (46019) */ + 3347, /* B3C4 (46020) */ + 3347, /* B3C5 (46021) */ + 3347, /* B3C6 (46022) */ + 3347, /* B3C7 (46023) */ + 3347, /* B3C8 (46024) */ + 3347, /* B3C9 (46025) */ + 3347, /* B3CA (46026) */ + 3347, /* B3CB (46027) */ + 3347, /* B3CC (46028) */ + 3347, /* B3CD (46029) */ + 3347, /* B3CE (46030) */ + 3347, /* B3CF (46031) */ + 3347, /* B3D0 (46032) */ + 3347, /* B3D1 (46033) */ + 3347, /* B3D2 (46034) */ + 3347, /* B3D3 (46035) */ + 3347, /* B3D4 (46036) */ + 3347, /* B3D5 (46037) */ + 3347, /* B3D6 (46038) */ + 3347, /* B3D7 (46039) */ + 3347, /* B3D8 (46040) */ + 3347, /* B3D9 (46041) */ + 3347, /* B3DA (46042) */ + 3347, /* B3DB (46043) */ + 3347, /* B3DC (46044) */ + 3347, /* B3DD (46045) */ + 3347, /* B3DE (46046) */ + 3347, /* B3DF (46047) */ + 3347, /* B3E0 (46048) */ + 3347, /* B3E1 (46049) */ + 3347, /* B3E2 (46050) */ + 3347, /* B3E3 (46051) */ + 3347, /* B3E4 (46052) */ + 3347, /* B3E5 (46053) */ + 3347, /* B3E6 (46054) */ + 3347, /* B3E7 (46055) */ + 3347, /* B3E8 (46056) */ + 3347, /* B3E9 (46057) */ + 3347, /* B3EA (46058) */ + 3347, /* B3EB (46059) */ + 3347, /* B3EC (46060) */ + 3347, /* B3ED (46061) */ + 3347, /* B3EE (46062) */ + 3347, /* B3EF (46063) */ + 3347, /* B3F0 (46064) */ + 3347, /* B3F1 (46065) */ + 3347, /* B3F2 (46066) */ + 3347, /* B3F3 (46067) */ + 3347, /* B3F4 (46068) */ + 3347, /* B3F5 (46069) */ + 3347, /* B3F6 (46070) */ + 3347, /* B3F7 (46071) */ + 3347, /* B3F8 (46072) */ + 3347, /* B3F9 (46073) */ + 3347, /* B3FA (46074) */ + 3347, /* B3FB (46075) */ + 3347, /* B3FC (46076) */ + 3347, /* B3FD (46077) */ + 3347, /* B3FE (46078) */ + 3347, /* B3FF (46079) */ + 3347, /* B400 (46080) */ + 3347, /* B401 (46081) */ + 3347, /* B402 (46082) */ + 3347, /* B403 (46083) */ + 3347, /* B404 (46084) */ + 3347, /* B405 (46085) */ + 3347, /* B406 (46086) */ + 3347, /* B407 (46087) */ + 3347, /* B408 (46088) */ + 3347, /* B409 (46089) */ + 3347, /* B40A (46090) */ + 3347, /* B40B (46091) */ + 3347, /* B40C (46092) */ + 3347, /* B40D (46093) */ + 3347, /* B40E (46094) */ + 3347, /* B40F (46095) */ + 3347, /* B410 (46096) */ + 3347, /* B411 (46097) */ + 3347, /* B412 (46098) */ + 3347, /* B413 (46099) */ + 3347, /* B414 (46100) */ + 3347, /* B415 (46101) */ + 3347, /* B416 (46102) */ + 3347, /* B417 (46103) */ + 3347, /* B418 (46104) */ + 3347, /* B419 (46105) */ + 3347, /* B41A (46106) */ + 3347, /* B41B (46107) */ + 3347, /* B41C (46108) */ + 3347, /* B41D (46109) */ + 3347, /* B41E (46110) */ + 3347, /* B41F (46111) */ + 3347, /* B420 (46112) */ + 3347, /* B421 (46113) */ + 3347, /* B422 (46114) */ + 3347, /* B423 (46115) */ + 3347, /* B424 (46116) */ + 3347, /* B425 (46117) */ + 3347, /* B426 (46118) */ + 3347, /* B427 (46119) */ + 3347, /* B428 (46120) */ + 3347, /* B429 (46121) */ + 3347, /* B42A (46122) */ + 3347, /* B42B (46123) */ + 3347, /* B42C (46124) */ + 3347, /* B42D (46125) */ + 3347, /* B42E (46126) */ + 3347, /* B42F (46127) */ + 3347, /* B430 (46128) */ + 3347, /* B431 (46129) */ + 3347, /* B432 (46130) */ + 3347, /* B433 (46131) */ + 3347, /* B434 (46132) */ + 3347, /* B435 (46133) */ + 3347, /* B436 (46134) */ + 3347, /* B437 (46135) */ + 3347, /* B438 (46136) */ + 3347, /* B439 (46137) */ + 3347, /* B43A (46138) */ + 3347, /* B43B (46139) */ + 3347, /* B43C (46140) */ + 3347, /* B43D (46141) */ + 3347, /* B43E (46142) */ + 3347, /* B43F (46143) */ + 3347, /* B440 (46144) */ + 3347, /* B441 (46145) */ + 3347, /* B442 (46146) */ + 3347, /* B443 (46147) */ + 3347, /* B444 (46148) */ + 3347, /* B445 (46149) */ + 3347, /* B446 (46150) */ + 3347, /* B447 (46151) */ + 3347, /* B448 (46152) */ + 3347, /* B449 (46153) */ + 3347, /* B44A (46154) */ + 3347, /* B44B (46155) */ + 3347, /* B44C (46156) */ + 3347, /* B44D (46157) */ + 3347, /* B44E (46158) */ + 3347, /* B44F (46159) */ + 3347, /* B450 (46160) */ + 3347, /* B451 (46161) */ + 3347, /* B452 (46162) */ + 3347, /* B453 (46163) */ + 3347, /* B454 (46164) */ + 3347, /* B455 (46165) */ + 3347, /* B456 (46166) */ + 3347, /* B457 (46167) */ + 3347, /* B458 (46168) */ + 3347, /* B459 (46169) */ + 3347, /* B45A (46170) */ + 3347, /* B45B (46171) */ + 3347, /* B45C (46172) */ + 3347, /* B45D (46173) */ + 3347, /* B45E (46174) */ + 3347, /* B45F (46175) */ + 3347, /* B460 (46176) */ + 3347, /* B461 (46177) */ + 3347, /* B462 (46178) */ + 3347, /* B463 (46179) */ + 3347, /* B464 (46180) */ + 3347, /* B465 (46181) */ + 3347, /* B466 (46182) */ + 3347, /* B467 (46183) */ + 3347, /* B468 (46184) */ + 3347, /* B469 (46185) */ + 3347, /* B46A (46186) */ + 3347, /* B46B (46187) */ + 3347, /* B46C (46188) */ + 3347, /* B46D (46189) */ + 3347, /* B46E (46190) */ + 3347, /* B46F (46191) */ + 3347, /* B470 (46192) */ + 3347, /* B471 (46193) */ + 3347, /* B472 (46194) */ + 3347, /* B473 (46195) */ + 3347, /* B474 (46196) */ + 3347, /* B475 (46197) */ + 3347, /* B476 (46198) */ + 3347, /* B477 (46199) */ + 3347, /* B478 (46200) */ + 3347, /* B479 (46201) */ + 3347, /* B47A (46202) */ + 3347, /* B47B (46203) */ + 3347, /* B47C (46204) */ + 3347, /* B47D (46205) */ + 3347, /* B47E (46206) */ + 3347, /* B47F (46207) */ + 3347, /* B480 (46208) */ + 3347, /* B481 (46209) */ + 3347, /* B482 (46210) */ + 3347, /* B483 (46211) */ + 3347, /* B484 (46212) */ + 3347, /* B485 (46213) */ + 3347, /* B486 (46214) */ + 3347, /* B487 (46215) */ + 3347, /* B488 (46216) */ + 3347, /* B489 (46217) */ + 3347, /* B48A (46218) */ + 3347, /* B48B (46219) */ + 3347, /* B48C (46220) */ + 3347, /* B48D (46221) */ + 3347, /* B48E (46222) */ + 3347, /* B48F (46223) */ + 3347, /* B490 (46224) */ + 3347, /* B491 (46225) */ + 3347, /* B492 (46226) */ + 3347, /* B493 (46227) */ + 3347, /* B494 (46228) */ + 3347, /* B495 (46229) */ + 3347, /* B496 (46230) */ + 3347, /* B497 (46231) */ + 3347, /* B498 (46232) */ + 3347, /* B499 (46233) */ + 3347, /* B49A (46234) */ + 3347, /* B49B (46235) */ + 3347, /* B49C (46236) */ + 3347, /* B49D (46237) */ + 3347, /* B49E (46238) */ + 3347, /* B49F (46239) */ + 3347, /* B4A0 (46240) */ + 3347, /* B4A1 (46241) */ + 3347, /* B4A2 (46242) */ + 3347, /* B4A3 (46243) */ + 3347, /* B4A4 (46244) */ + 3347, /* B4A5 (46245) */ + 3347, /* B4A6 (46246) */ + 3347, /* B4A7 (46247) */ + 3347, /* B4A8 (46248) */ + 3347, /* B4A9 (46249) */ + 3347, /* B4AA (46250) */ + 3347, /* B4AB (46251) */ + 3347, /* B4AC (46252) */ + 3347, /* B4AD (46253) */ + 3347, /* B4AE (46254) */ + 3347, /* B4AF (46255) */ + 3347, /* B4B0 (46256) */ + 3347, /* B4B1 (46257) */ + 3347, /* B4B2 (46258) */ + 3347, /* B4B3 (46259) */ + 3347, /* B4B4 (46260) */ + 3347, /* B4B5 (46261) */ + 3347, /* B4B6 (46262) */ + 3347, /* B4B7 (46263) */ + 3347, /* B4B8 (46264) */ + 3347, /* B4B9 (46265) */ + 3347, /* B4BA (46266) */ + 3347, /* B4BB (46267) */ + 3347, /* B4BC (46268) */ + 3347, /* B4BD (46269) */ + 3347, /* B4BE (46270) */ + 3347, /* B4BF (46271) */ + 3347, /* B4C0 (46272) */ + 3347, /* B4C1 (46273) */ + 3347, /* B4C2 (46274) */ + 3347, /* B4C3 (46275) */ + 3347, /* B4C4 (46276) */ + 3347, /* B4C5 (46277) */ + 3347, /* B4C6 (46278) */ + 3347, /* B4C7 (46279) */ + 3347, /* B4C8 (46280) */ + 3347, /* B4C9 (46281) */ + 3347, /* B4CA (46282) */ + 3347, /* B4CB (46283) */ + 3347, /* B4CC (46284) */ + 3347, /* B4CD (46285) */ + 3347, /* B4CE (46286) */ + 3347, /* B4CF (46287) */ + 3347, /* B4D0 (46288) */ + 3347, /* B4D1 (46289) */ + 3347, /* B4D2 (46290) */ + 3347, /* B4D3 (46291) */ + 3347, /* B4D4 (46292) */ + 3347, /* B4D5 (46293) */ + 3347, /* B4D6 (46294) */ + 3347, /* B4D7 (46295) */ + 3347, /* B4D8 (46296) */ + 3347, /* B4D9 (46297) */ + 3347, /* B4DA (46298) */ + 3347, /* B4DB (46299) */ + 3347, /* B4DC (46300) */ + 3347, /* B4DD (46301) */ + 3347, /* B4DE (46302) */ + 3347, /* B4DF (46303) */ + 3347, /* B4E0 (46304) */ + 3347, /* B4E1 (46305) */ + 3347, /* B4E2 (46306) */ + 3347, /* B4E3 (46307) */ + 3347, /* B4E4 (46308) */ + 3347, /* B4E5 (46309) */ + 3347, /* B4E6 (46310) */ + 3347, /* B4E7 (46311) */ + 3347, /* B4E8 (46312) */ + 3347, /* B4E9 (46313) */ + 3347, /* B4EA (46314) */ + 3347, /* B4EB (46315) */ + 3347, /* B4EC (46316) */ + 3347, /* B4ED (46317) */ + 3347, /* B4EE (46318) */ + 3347, /* B4EF (46319) */ + 3347, /* B4F0 (46320) */ + 3347, /* B4F1 (46321) */ + 3347, /* B4F2 (46322) */ + 3347, /* B4F3 (46323) */ + 3347, /* B4F4 (46324) */ + 3347, /* B4F5 (46325) */ + 3347, /* B4F6 (46326) */ + 3347, /* B4F7 (46327) */ + 3347, /* B4F8 (46328) */ + 3347, /* B4F9 (46329) */ + 3347, /* B4FA (46330) */ + 3347, /* B4FB (46331) */ + 3347, /* B4FC (46332) */ + 3347, /* B4FD (46333) */ + 3347, /* B4FE (46334) */ + 3347, /* B4FF (46335) */ + 3347, /* B500 (46336) */ + 3347, /* B501 (46337) */ + 3347, /* B502 (46338) */ + 3347, /* B503 (46339) */ + 3347, /* B504 (46340) */ + 3347, /* B505 (46341) */ + 3347, /* B506 (46342) */ + 3347, /* B507 (46343) */ + 3347, /* B508 (46344) */ + 3347, /* B509 (46345) */ + 3347, /* B50A (46346) */ + 3347, /* B50B (46347) */ + 3347, /* B50C (46348) */ + 3347, /* B50D (46349) */ + 3347, /* B50E (46350) */ + 3347, /* B50F (46351) */ + 3347, /* B510 (46352) */ + 3347, /* B511 (46353) */ + 3347, /* B512 (46354) */ + 3347, /* B513 (46355) */ + 3347, /* B514 (46356) */ + 3347, /* B515 (46357) */ + 3347, /* B516 (46358) */ + 3347, /* B517 (46359) */ + 3347, /* B518 (46360) */ + 3347, /* B519 (46361) */ + 3347, /* B51A (46362) */ + 3347, /* B51B (46363) */ + 3347, /* B51C (46364) */ + 3347, /* B51D (46365) */ + 3347, /* B51E (46366) */ + 3347, /* B51F (46367) */ + 3347, /* B520 (46368) */ + 3347, /* B521 (46369) */ + 3347, /* B522 (46370) */ + 3347, /* B523 (46371) */ + 3347, /* B524 (46372) */ + 3347, /* B525 (46373) */ + 3347, /* B526 (46374) */ + 3347, /* B527 (46375) */ + 3347, /* B528 (46376) */ + 3347, /* B529 (46377) */ + 3347, /* B52A (46378) */ + 3347, /* B52B (46379) */ + 3347, /* B52C (46380) */ + 3347, /* B52D (46381) */ + 3347, /* B52E (46382) */ + 3347, /* B52F (46383) */ + 3347, /* B530 (46384) */ + 3347, /* B531 (46385) */ + 3347, /* B532 (46386) */ + 3347, /* B533 (46387) */ + 3347, /* B534 (46388) */ + 3347, /* B535 (46389) */ + 3347, /* B536 (46390) */ + 3347, /* B537 (46391) */ + 3347, /* B538 (46392) */ + 3347, /* B539 (46393) */ + 3347, /* B53A (46394) */ + 3347, /* B53B (46395) */ + 3347, /* B53C (46396) */ + 3347, /* B53D (46397) */ + 3347, /* B53E (46398) */ + 3347, /* B53F (46399) */ + 3347, /* B540 (46400) */ + 3347, /* B541 (46401) */ + 3347, /* B542 (46402) */ + 3347, /* B543 (46403) */ + 3347, /* B544 (46404) */ + 3347, /* B545 (46405) */ + 3347, /* B546 (46406) */ + 3347, /* B547 (46407) */ + 3347, /* B548 (46408) */ + 3347, /* B549 (46409) */ + 3347, /* B54A (46410) */ + 3347, /* B54B (46411) */ + 3347, /* B54C (46412) */ + 3347, /* B54D (46413) */ + 3347, /* B54E (46414) */ + 3347, /* B54F (46415) */ + 3347, /* B550 (46416) */ + 3347, /* B551 (46417) */ + 3347, /* B552 (46418) */ + 3347, /* B553 (46419) */ + 3347, /* B554 (46420) */ + 3347, /* B555 (46421) */ + 3347, /* B556 (46422) */ + 3347, /* B557 (46423) */ + 3347, /* B558 (46424) */ + 3347, /* B559 (46425) */ + 3347, /* B55A (46426) */ + 3347, /* B55B (46427) */ + 3347, /* B55C (46428) */ + 3347, /* B55D (46429) */ + 3347, /* B55E (46430) */ + 3347, /* B55F (46431) */ + 3347, /* B560 (46432) */ + 3347, /* B561 (46433) */ + 3347, /* B562 (46434) */ + 3347, /* B563 (46435) */ + 3347, /* B564 (46436) */ + 3347, /* B565 (46437) */ + 3347, /* B566 (46438) */ + 3347, /* B567 (46439) */ + 3347, /* B568 (46440) */ + 3347, /* B569 (46441) */ + 3347, /* B56A (46442) */ + 3347, /* B56B (46443) */ + 3347, /* B56C (46444) */ + 3347, /* B56D (46445) */ + 3347, /* B56E (46446) */ + 3347, /* B56F (46447) */ + 3347, /* B570 (46448) */ + 3347, /* B571 (46449) */ + 3347, /* B572 (46450) */ + 3347, /* B573 (46451) */ + 3347, /* B574 (46452) */ + 3347, /* B575 (46453) */ + 3347, /* B576 (46454) */ + 3347, /* B577 (46455) */ + 3347, /* B578 (46456) */ + 3347, /* B579 (46457) */ + 3347, /* B57A (46458) */ + 3347, /* B57B (46459) */ + 3347, /* B57C (46460) */ + 3347, /* B57D (46461) */ + 3347, /* B57E (46462) */ + 3347, /* B57F (46463) */ + 3347, /* B580 (46464) */ + 3347, /* B581 (46465) */ + 3347, /* B582 (46466) */ + 3347, /* B583 (46467) */ + 3347, /* B584 (46468) */ + 3347, /* B585 (46469) */ + 3347, /* B586 (46470) */ + 3347, /* B587 (46471) */ + 3347, /* B588 (46472) */ + 3347, /* B589 (46473) */ + 3347, /* B58A (46474) */ + 3347, /* B58B (46475) */ + 3347, /* B58C (46476) */ + 3347, /* B58D (46477) */ + 3347, /* B58E (46478) */ + 3347, /* B58F (46479) */ + 3347, /* B590 (46480) */ + 3347, /* B591 (46481) */ + 3347, /* B592 (46482) */ + 3347, /* B593 (46483) */ + 3347, /* B594 (46484) */ + 3347, /* B595 (46485) */ + 3347, /* B596 (46486) */ + 3347, /* B597 (46487) */ + 3347, /* B598 (46488) */ + 3347, /* B599 (46489) */ + 3347, /* B59A (46490) */ + 3347, /* B59B (46491) */ + 3347, /* B59C (46492) */ + 3347, /* B59D (46493) */ + 3347, /* B59E (46494) */ + 3347, /* B59F (46495) */ + 3347, /* B5A0 (46496) */ + 3347, /* B5A1 (46497) */ + 3347, /* B5A2 (46498) */ + 3347, /* B5A3 (46499) */ + 3347, /* B5A4 (46500) */ + 3347, /* B5A5 (46501) */ + 3347, /* B5A6 (46502) */ + 3347, /* B5A7 (46503) */ + 3347, /* B5A8 (46504) */ + 3347, /* B5A9 (46505) */ + 3347, /* B5AA (46506) */ + 3347, /* B5AB (46507) */ + 3347, /* B5AC (46508) */ + 3347, /* B5AD (46509) */ + 3347, /* B5AE (46510) */ + 3347, /* B5AF (46511) */ + 3347, /* B5B0 (46512) */ + 3347, /* B5B1 (46513) */ + 3347, /* B5B2 (46514) */ + 3347, /* B5B3 (46515) */ + 3347, /* B5B4 (46516) */ + 3347, /* B5B5 (46517) */ + 3347, /* B5B6 (46518) */ + 3347, /* B5B7 (46519) */ + 3347, /* B5B8 (46520) */ + 3347, /* B5B9 (46521) */ + 3347, /* B5BA (46522) */ + 3347, /* B5BB (46523) */ + 3347, /* B5BC (46524) */ + 3347, /* B5BD (46525) */ + 3347, /* B5BE (46526) */ + 3347, /* B5BF (46527) */ + 3347, /* B5C0 (46528) */ + 3347, /* B5C1 (46529) */ + 3347, /* B5C2 (46530) */ + 3347, /* B5C3 (46531) */ + 3347, /* B5C4 (46532) */ + 3347, /* B5C5 (46533) */ + 3347, /* B5C6 (46534) */ + 3347, /* B5C7 (46535) */ + 3347, /* B5C8 (46536) */ + 3347, /* B5C9 (46537) */ + 3347, /* B5CA (46538) */ + 3347, /* B5CB (46539) */ + 3347, /* B5CC (46540) */ + 3347, /* B5CD (46541) */ + 3347, /* B5CE (46542) */ + 3347, /* B5CF (46543) */ + 3347, /* B5D0 (46544) */ + 3347, /* B5D1 (46545) */ + 3347, /* B5D2 (46546) */ + 3347, /* B5D3 (46547) */ + 3347, /* B5D4 (46548) */ + 3347, /* B5D5 (46549) */ + 3347, /* B5D6 (46550) */ + 3347, /* B5D7 (46551) */ + 3347, /* B5D8 (46552) */ + 3347, /* B5D9 (46553) */ + 3347, /* B5DA (46554) */ + 3347, /* B5DB (46555) */ + 3347, /* B5DC (46556) */ + 3347, /* B5DD (46557) */ + 3347, /* B5DE (46558) */ + 3347, /* B5DF (46559) */ + 3347, /* B5E0 (46560) */ + 3347, /* B5E1 (46561) */ + 3347, /* B5E2 (46562) */ + 3347, /* B5E3 (46563) */ + 3347, /* B5E4 (46564) */ + 3347, /* B5E5 (46565) */ + 3347, /* B5E6 (46566) */ + 3347, /* B5E7 (46567) */ + 3347, /* B5E8 (46568) */ + 3347, /* B5E9 (46569) */ + 3347, /* B5EA (46570) */ + 3347, /* B5EB (46571) */ + 3347, /* B5EC (46572) */ + 3347, /* B5ED (46573) */ + 3347, /* B5EE (46574) */ + 3347, /* B5EF (46575) */ + 3347, /* B5F0 (46576) */ + 3347, /* B5F1 (46577) */ + 3347, /* B5F2 (46578) */ + 3347, /* B5F3 (46579) */ + 3347, /* B5F4 (46580) */ + 3347, /* B5F5 (46581) */ + 3347, /* B5F6 (46582) */ + 3347, /* B5F7 (46583) */ + 3347, /* B5F8 (46584) */ + 3347, /* B5F9 (46585) */ + 3347, /* B5FA (46586) */ + 3347, /* B5FB (46587) */ + 3347, /* B5FC (46588) */ + 3347, /* B5FD (46589) */ + 3347, /* B5FE (46590) */ + 3347, /* B5FF (46591) */ + 3347, /* B600 (46592) */ + 3347, /* B601 (46593) */ + 3347, /* B602 (46594) */ + 3347, /* B603 (46595) */ + 3347, /* B604 (46596) */ + 3347, /* B605 (46597) */ + 3347, /* B606 (46598) */ + 3347, /* B607 (46599) */ + 3347, /* B608 (46600) */ + 3347, /* B609 (46601) */ + 3347, /* B60A (46602) */ + 3347, /* B60B (46603) */ + 3347, /* B60C (46604) */ + 3347, /* B60D (46605) */ + 3347, /* B60E (46606) */ + 3347, /* B60F (46607) */ + 3347, /* B610 (46608) */ + 3347, /* B611 (46609) */ + 3347, /* B612 (46610) */ + 3347, /* B613 (46611) */ + 3347, /* B614 (46612) */ + 3347, /* B615 (46613) */ + 3347, /* B616 (46614) */ + 3347, /* B617 (46615) */ + 3347, /* B618 (46616) */ + 3347, /* B619 (46617) */ + 3347, /* B61A (46618) */ + 3347, /* B61B (46619) */ + 3347, /* B61C (46620) */ + 3347, /* B61D (46621) */ + 3347, /* B61E (46622) */ + 3347, /* B61F (46623) */ + 3347, /* B620 (46624) */ + 3347, /* B621 (46625) */ + 3347, /* B622 (46626) */ + 3347, /* B623 (46627) */ + 3347, /* B624 (46628) */ + 3347, /* B625 (46629) */ + 3347, /* B626 (46630) */ + 3347, /* B627 (46631) */ + 3347, /* B628 (46632) */ + 3347, /* B629 (46633) */ + 3347, /* B62A (46634) */ + 3347, /* B62B (46635) */ + 3347, /* B62C (46636) */ + 3347, /* B62D (46637) */ + 3347, /* B62E (46638) */ + 3347, /* B62F (46639) */ + 3347, /* B630 (46640) */ + 3347, /* B631 (46641) */ + 3347, /* B632 (46642) */ + 3347, /* B633 (46643) */ + 3347, /* B634 (46644) */ + 3347, /* B635 (46645) */ + 3347, /* B636 (46646) */ + 3347, /* B637 (46647) */ + 3347, /* B638 (46648) */ + 3347, /* B639 (46649) */ + 3347, /* B63A (46650) */ + 3347, /* B63B (46651) */ + 3347, /* B63C (46652) */ + 3347, /* B63D (46653) */ + 3347, /* B63E (46654) */ + 3347, /* B63F (46655) */ + 3347, /* B640 (46656) */ + 3347, /* B641 (46657) */ + 3347, /* B642 (46658) */ + 3347, /* B643 (46659) */ + 3347, /* B644 (46660) */ + 3347, /* B645 (46661) */ + 3347, /* B646 (46662) */ + 3347, /* B647 (46663) */ + 3347, /* B648 (46664) */ + 3347, /* B649 (46665) */ + 3347, /* B64A (46666) */ + 3347, /* B64B (46667) */ + 3347, /* B64C (46668) */ + 3347, /* B64D (46669) */ + 3347, /* B64E (46670) */ + 3347, /* B64F (46671) */ + 3347, /* B650 (46672) */ + 3347, /* B651 (46673) */ + 3347, /* B652 (46674) */ + 3347, /* B653 (46675) */ + 3347, /* B654 (46676) */ + 3347, /* B655 (46677) */ + 3347, /* B656 (46678) */ + 3347, /* B657 (46679) */ + 3347, /* B658 (46680) */ + 3347, /* B659 (46681) */ + 3347, /* B65A (46682) */ + 3347, /* B65B (46683) */ + 3347, /* B65C (46684) */ + 3347, /* B65D (46685) */ + 3347, /* B65E (46686) */ + 3347, /* B65F (46687) */ + 3347, /* B660 (46688) */ + 3347, /* B661 (46689) */ + 3347, /* B662 (46690) */ + 3347, /* B663 (46691) */ + 3347, /* B664 (46692) */ + 3347, /* B665 (46693) */ + 3347, /* B666 (46694) */ + 3347, /* B667 (46695) */ + 3347, /* B668 (46696) */ + 3347, /* B669 (46697) */ + 3347, /* B66A (46698) */ + 3347, /* B66B (46699) */ + 3347, /* B66C (46700) */ + 3347, /* B66D (46701) */ + 3347, /* B66E (46702) */ + 3347, /* B66F (46703) */ + 3347, /* B670 (46704) */ + 3347, /* B671 (46705) */ + 3347, /* B672 (46706) */ + 3347, /* B673 (46707) */ + 3347, /* B674 (46708) */ + 3347, /* B675 (46709) */ + 3347, /* B676 (46710) */ + 3347, /* B677 (46711) */ + 3347, /* B678 (46712) */ + 3347, /* B679 (46713) */ + 3347, /* B67A (46714) */ + 3347, /* B67B (46715) */ + 3347, /* B67C (46716) */ + 3347, /* B67D (46717) */ + 3347, /* B67E (46718) */ + 3347, /* B67F (46719) */ + 3347, /* B680 (46720) */ + 3347, /* B681 (46721) */ + 3347, /* B682 (46722) */ + 3347, /* B683 (46723) */ + 3347, /* B684 (46724) */ + 3347, /* B685 (46725) */ + 3347, /* B686 (46726) */ + 3347, /* B687 (46727) */ + 3347, /* B688 (46728) */ + 3347, /* B689 (46729) */ + 3347, /* B68A (46730) */ + 3347, /* B68B (46731) */ + 3347, /* B68C (46732) */ + 3347, /* B68D (46733) */ + 3347, /* B68E (46734) */ + 3347, /* B68F (46735) */ + 3347, /* B690 (46736) */ + 3347, /* B691 (46737) */ + 3347, /* B692 (46738) */ + 3347, /* B693 (46739) */ + 3347, /* B694 (46740) */ + 3347, /* B695 (46741) */ + 3347, /* B696 (46742) */ + 3347, /* B697 (46743) */ + 3347, /* B698 (46744) */ + 3347, /* B699 (46745) */ + 3347, /* B69A (46746) */ + 3347, /* B69B (46747) */ + 3347, /* B69C (46748) */ + 3347, /* B69D (46749) */ + 3347, /* B69E (46750) */ + 3347, /* B69F (46751) */ + 3347, /* B6A0 (46752) */ + 3347, /* B6A1 (46753) */ + 3347, /* B6A2 (46754) */ + 3347, /* B6A3 (46755) */ + 3347, /* B6A4 (46756) */ + 3347, /* B6A5 (46757) */ + 3347, /* B6A6 (46758) */ + 3347, /* B6A7 (46759) */ + 3347, /* B6A8 (46760) */ + 3347, /* B6A9 (46761) */ + 3347, /* B6AA (46762) */ + 3347, /* B6AB (46763) */ + 3347, /* B6AC (46764) */ + 3347, /* B6AD (46765) */ + 3347, /* B6AE (46766) */ + 3347, /* B6AF (46767) */ + 3347, /* B6B0 (46768) */ + 3347, /* B6B1 (46769) */ + 3347, /* B6B2 (46770) */ + 3347, /* B6B3 (46771) */ + 3347, /* B6B4 (46772) */ + 3347, /* B6B5 (46773) */ + 3347, /* B6B6 (46774) */ + 3347, /* B6B7 (46775) */ + 3347, /* B6B8 (46776) */ + 3347, /* B6B9 (46777) */ + 3347, /* B6BA (46778) */ + 3347, /* B6BB (46779) */ + 3347, /* B6BC (46780) */ + 3347, /* B6BD (46781) */ + 3347, /* B6BE (46782) */ + 3347, /* B6BF (46783) */ + 3347, /* B6C0 (46784) */ + 3347, /* B6C1 (46785) */ + 3347, /* B6C2 (46786) */ + 3347, /* B6C3 (46787) */ + 3347, /* B6C4 (46788) */ + 3347, /* B6C5 (46789) */ + 3347, /* B6C6 (46790) */ + 3347, /* B6C7 (46791) */ + 3347, /* B6C8 (46792) */ + 3347, /* B6C9 (46793) */ + 3347, /* B6CA (46794) */ + 3347, /* B6CB (46795) */ + 3347, /* B6CC (46796) */ + 3347, /* B6CD (46797) */ + 3347, /* B6CE (46798) */ + 3347, /* B6CF (46799) */ + 3347, /* B6D0 (46800) */ + 3347, /* B6D1 (46801) */ + 3347, /* B6D2 (46802) */ + 3347, /* B6D3 (46803) */ + 3347, /* B6D4 (46804) */ + 3347, /* B6D5 (46805) */ + 3347, /* B6D6 (46806) */ + 3347, /* B6D7 (46807) */ + 3347, /* B6D8 (46808) */ + 3347, /* B6D9 (46809) */ + 3347, /* B6DA (46810) */ + 3347, /* B6DB (46811) */ + 3347, /* B6DC (46812) */ + 3347, /* B6DD (46813) */ + 3347, /* B6DE (46814) */ + 3347, /* B6DF (46815) */ + 3347, /* B6E0 (46816) */ + 3347, /* B6E1 (46817) */ + 3347, /* B6E2 (46818) */ + 3347, /* B6E3 (46819) */ + 3347, /* B6E4 (46820) */ + 3347, /* B6E5 (46821) */ + 3347, /* B6E6 (46822) */ + 3347, /* B6E7 (46823) */ + 3347, /* B6E8 (46824) */ + 3347, /* B6E9 (46825) */ + 3347, /* B6EA (46826) */ + 3347, /* B6EB (46827) */ + 3347, /* B6EC (46828) */ + 3347, /* B6ED (46829) */ + 3347, /* B6EE (46830) */ + 3347, /* B6EF (46831) */ + 3347, /* B6F0 (46832) */ + 3347, /* B6F1 (46833) */ + 3347, /* B6F2 (46834) */ + 3347, /* B6F3 (46835) */ + 3347, /* B6F4 (46836) */ + 3347, /* B6F5 (46837) */ + 3347, /* B6F6 (46838) */ + 3347, /* B6F7 (46839) */ + 3347, /* B6F8 (46840) */ + 3347, /* B6F9 (46841) */ + 3347, /* B6FA (46842) */ + 3347, /* B6FB (46843) */ + 3347, /* B6FC (46844) */ + 3347, /* B6FD (46845) */ + 3347, /* B6FE (46846) */ + 3347, /* B6FF (46847) */ + 3347, /* B700 (46848) */ + 3347, /* B701 (46849) */ + 3347, /* B702 (46850) */ + 3347, /* B703 (46851) */ + 3347, /* B704 (46852) */ + 3347, /* B705 (46853) */ + 3347, /* B706 (46854) */ + 3347, /* B707 (46855) */ + 3347, /* B708 (46856) */ + 3347, /* B709 (46857) */ + 3347, /* B70A (46858) */ + 3347, /* B70B (46859) */ + 3347, /* B70C (46860) */ + 3347, /* B70D (46861) */ + 3347, /* B70E (46862) */ + 3347, /* B70F (46863) */ + 3347, /* B710 (46864) */ + 3347, /* B711 (46865) */ + 3347, /* B712 (46866) */ + 3347, /* B713 (46867) */ + 3347, /* B714 (46868) */ + 3347, /* B715 (46869) */ + 3347, /* B716 (46870) */ + 3347, /* B717 (46871) */ + 3347, /* B718 (46872) */ + 3347, /* B719 (46873) */ + 3347, /* B71A (46874) */ + 3347, /* B71B (46875) */ + 3347, /* B71C (46876) */ + 3347, /* B71D (46877) */ + 3347, /* B71E (46878) */ + 3347, /* B71F (46879) */ + 3347, /* B720 (46880) */ + 3347, /* B721 (46881) */ + 3347, /* B722 (46882) */ + 3347, /* B723 (46883) */ + 3347, /* B724 (46884) */ + 3347, /* B725 (46885) */ + 3347, /* B726 (46886) */ + 3347, /* B727 (46887) */ + 3347, /* B728 (46888) */ + 3347, /* B729 (46889) */ + 3347, /* B72A (46890) */ + 3347, /* B72B (46891) */ + 3347, /* B72C (46892) */ + 3347, /* B72D (46893) */ + 3347, /* B72E (46894) */ + 3347, /* B72F (46895) */ + 3347, /* B730 (46896) */ + 3347, /* B731 (46897) */ + 3347, /* B732 (46898) */ + 3347, /* B733 (46899) */ + 3347, /* B734 (46900) */ + 3347, /* B735 (46901) */ + 3347, /* B736 (46902) */ + 3347, /* B737 (46903) */ + 3347, /* B738 (46904) */ + 3347, /* B739 (46905) */ + 3347, /* B73A (46906) */ + 3347, /* B73B (46907) */ + 3347, /* B73C (46908) */ + 3347, /* B73D (46909) */ + 3347, /* B73E (46910) */ + 3347, /* B73F (46911) */ + 3347, /* B740 (46912) */ + 3347, /* B741 (46913) */ + 3347, /* B742 (46914) */ + 3347, /* B743 (46915) */ + 3347, /* B744 (46916) */ + 3347, /* B745 (46917) */ + 3347, /* B746 (46918) */ + 3347, /* B747 (46919) */ + 3347, /* B748 (46920) */ + 3347, /* B749 (46921) */ + 3347, /* B74A (46922) */ + 3347, /* B74B (46923) */ + 3347, /* B74C (46924) */ + 3347, /* B74D (46925) */ + 3347, /* B74E (46926) */ + 3347, /* B74F (46927) */ + 3347, /* B750 (46928) */ + 3347, /* B751 (46929) */ + 3347, /* B752 (46930) */ + 3347, /* B753 (46931) */ + 3347, /* B754 (46932) */ + 3347, /* B755 (46933) */ + 3347, /* B756 (46934) */ + 3347, /* B757 (46935) */ + 3347, /* B758 (46936) */ + 3347, /* B759 (46937) */ + 3347, /* B75A (46938) */ + 3347, /* B75B (46939) */ + 3347, /* B75C (46940) */ + 3347, /* B75D (46941) */ + 3347, /* B75E (46942) */ + 3347, /* B75F (46943) */ + 3347, /* B760 (46944) */ + 3347, /* B761 (46945) */ + 3347, /* B762 (46946) */ + 3347, /* B763 (46947) */ + 3347, /* B764 (46948) */ + 3347, /* B765 (46949) */ + 3347, /* B766 (46950) */ + 3347, /* B767 (46951) */ + 3347, /* B768 (46952) */ + 3347, /* B769 (46953) */ + 3347, /* B76A (46954) */ + 3347, /* B76B (46955) */ + 3347, /* B76C (46956) */ + 3347, /* B76D (46957) */ + 3347, /* B76E (46958) */ + 3347, /* B76F (46959) */ + 3347, /* B770 (46960) */ + 3347, /* B771 (46961) */ + 3347, /* B772 (46962) */ + 3347, /* B773 (46963) */ + 3347, /* B774 (46964) */ + 3347, /* B775 (46965) */ + 3347, /* B776 (46966) */ + 3347, /* B777 (46967) */ + 3347, /* B778 (46968) */ + 3347, /* B779 (46969) */ + 3347, /* B77A (46970) */ + 3347, /* B77B (46971) */ + 3347, /* B77C (46972) */ + 3347, /* B77D (46973) */ + 3347, /* B77E (46974) */ + 3347, /* B77F (46975) */ + 3347, /* B780 (46976) */ + 3347, /* B781 (46977) */ + 3347, /* B782 (46978) */ + 3347, /* B783 (46979) */ + 3347, /* B784 (46980) */ + 3347, /* B785 (46981) */ + 3347, /* B786 (46982) */ + 3347, /* B787 (46983) */ + 3347, /* B788 (46984) */ + 3347, /* B789 (46985) */ + 3347, /* B78A (46986) */ + 3347, /* B78B (46987) */ + 3347, /* B78C (46988) */ + 3347, /* B78D (46989) */ + 3347, /* B78E (46990) */ + 3347, /* B78F (46991) */ + 3347, /* B790 (46992) */ + 3347, /* B791 (46993) */ + 3347, /* B792 (46994) */ + 3347, /* B793 (46995) */ + 3347, /* B794 (46996) */ + 3347, /* B795 (46997) */ + 3347, /* B796 (46998) */ + 3347, /* B797 (46999) */ + 3347, /* B798 (47000) */ + 3347, /* B799 (47001) */ + 3347, /* B79A (47002) */ + 3347, /* B79B (47003) */ + 3347, /* B79C (47004) */ + 3347, /* B79D (47005) */ + 3347, /* B79E (47006) */ + 3347, /* B79F (47007) */ + 3347, /* B7A0 (47008) */ + 3347, /* B7A1 (47009) */ + 3347, /* B7A2 (47010) */ + 3347, /* B7A3 (47011) */ + 3347, /* B7A4 (47012) */ + 3347, /* B7A5 (47013) */ + 3347, /* B7A6 (47014) */ + 3347, /* B7A7 (47015) */ + 3347, /* B7A8 (47016) */ + 3347, /* B7A9 (47017) */ + 3347, /* B7AA (47018) */ + 3347, /* B7AB (47019) */ + 3347, /* B7AC (47020) */ + 3347, /* B7AD (47021) */ + 3347, /* B7AE (47022) */ + 3347, /* B7AF (47023) */ + 3347, /* B7B0 (47024) */ + 3347, /* B7B1 (47025) */ + 3347, /* B7B2 (47026) */ + 3347, /* B7B3 (47027) */ + 3347, /* B7B4 (47028) */ + 3347, /* B7B5 (47029) */ + 3347, /* B7B6 (47030) */ + 3347, /* B7B7 (47031) */ + 3347, /* B7B8 (47032) */ + 3347, /* B7B9 (47033) */ + 3347, /* B7BA (47034) */ + 3347, /* B7BB (47035) */ + 3347, /* B7BC (47036) */ + 3347, /* B7BD (47037) */ + 3347, /* B7BE (47038) */ + 3347, /* B7BF (47039) */ + 3347, /* B7C0 (47040) */ + 3347, /* B7C1 (47041) */ + 3347, /* B7C2 (47042) */ + 3347, /* B7C3 (47043) */ + 3347, /* B7C4 (47044) */ + 3347, /* B7C5 (47045) */ + 3347, /* B7C6 (47046) */ + 3347, /* B7C7 (47047) */ + 3347, /* B7C8 (47048) */ + 3347, /* B7C9 (47049) */ + 3347, /* B7CA (47050) */ + 3347, /* B7CB (47051) */ + 3347, /* B7CC (47052) */ + 3347, /* B7CD (47053) */ + 3347, /* B7CE (47054) */ + 3347, /* B7CF (47055) */ + 3347, /* B7D0 (47056) */ + 3347, /* B7D1 (47057) */ + 3347, /* B7D2 (47058) */ + 3347, /* B7D3 (47059) */ + 3347, /* B7D4 (47060) */ + 3347, /* B7D5 (47061) */ + 3347, /* B7D6 (47062) */ + 3347, /* B7D7 (47063) */ + 3347, /* B7D8 (47064) */ + 3347, /* B7D9 (47065) */ + 3347, /* B7DA (47066) */ + 3347, /* B7DB (47067) */ + 3347, /* B7DC (47068) */ + 3347, /* B7DD (47069) */ + 3347, /* B7DE (47070) */ + 3347, /* B7DF (47071) */ + 3347, /* B7E0 (47072) */ + 3347, /* B7E1 (47073) */ + 3347, /* B7E2 (47074) */ + 3347, /* B7E3 (47075) */ + 3347, /* B7E4 (47076) */ + 3347, /* B7E5 (47077) */ + 3347, /* B7E6 (47078) */ + 3347, /* B7E7 (47079) */ + 3347, /* B7E8 (47080) */ + 3347, /* B7E9 (47081) */ + 3347, /* B7EA (47082) */ + 3347, /* B7EB (47083) */ + 3347, /* B7EC (47084) */ + 3347, /* B7ED (47085) */ + 3347, /* B7EE (47086) */ + 3347, /* B7EF (47087) */ + 3347, /* B7F0 (47088) */ + 3347, /* B7F1 (47089) */ + 3347, /* B7F2 (47090) */ + 3347, /* B7F3 (47091) */ + 3347, /* B7F4 (47092) */ + 3347, /* B7F5 (47093) */ + 3347, /* B7F6 (47094) */ + 3347, /* B7F7 (47095) */ + 3347, /* B7F8 (47096) */ + 3347, /* B7F9 (47097) */ + 3347, /* B7FA (47098) */ + 3347, /* B7FB (47099) */ + 3347, /* B7FC (47100) */ + 3347, /* B7FD (47101) */ + 3347, /* B7FE (47102) */ + 3347, /* B7FF (47103) */ + 3347, /* B800 (47104) */ + 3347, /* B801 (47105) */ + 3347, /* B802 (47106) */ + 3347, /* B803 (47107) */ + 3347, /* B804 (47108) */ + 3347, /* B805 (47109) */ + 3347, /* B806 (47110) */ + 3347, /* B807 (47111) */ + 3347, /* B808 (47112) */ + 3347, /* B809 (47113) */ + 3347, /* B80A (47114) */ + 3347, /* B80B (47115) */ + 3347, /* B80C (47116) */ + 3347, /* B80D (47117) */ + 3347, /* B80E (47118) */ + 3347, /* B80F (47119) */ + 3347, /* B810 (47120) */ + 3347, /* B811 (47121) */ + 3347, /* B812 (47122) */ + 3347, /* B813 (47123) */ + 3347, /* B814 (47124) */ + 3347, /* B815 (47125) */ + 3347, /* B816 (47126) */ + 3347, /* B817 (47127) */ + 3347, /* B818 (47128) */ + 3347, /* B819 (47129) */ + 3347, /* B81A (47130) */ + 3347, /* B81B (47131) */ + 3347, /* B81C (47132) */ + 3347, /* B81D (47133) */ + 3347, /* B81E (47134) */ + 3347, /* B81F (47135) */ + 3347, /* B820 (47136) */ + 3347, /* B821 (47137) */ + 3347, /* B822 (47138) */ + 3347, /* B823 (47139) */ + 3347, /* B824 (47140) */ + 3347, /* B825 (47141) */ + 3347, /* B826 (47142) */ + 3347, /* B827 (47143) */ + 3347, /* B828 (47144) */ + 3347, /* B829 (47145) */ + 3347, /* B82A (47146) */ + 3347, /* B82B (47147) */ + 3347, /* B82C (47148) */ + 3347, /* B82D (47149) */ + 3347, /* B82E (47150) */ + 3347, /* B82F (47151) */ + 3347, /* B830 (47152) */ + 3347, /* B831 (47153) */ + 3347, /* B832 (47154) */ + 3347, /* B833 (47155) */ + 3347, /* B834 (47156) */ + 3347, /* B835 (47157) */ + 3347, /* B836 (47158) */ + 3347, /* B837 (47159) */ + 3347, /* B838 (47160) */ + 3347, /* B839 (47161) */ + 3347, /* B83A (47162) */ + 3347, /* B83B (47163) */ + 3347, /* B83C (47164) */ + 3347, /* B83D (47165) */ + 3347, /* B83E (47166) */ + 3347, /* B83F (47167) */ + 3347, /* B840 (47168) */ + 3347, /* B841 (47169) */ + 3347, /* B842 (47170) */ + 3347, /* B843 (47171) */ + 3347, /* B844 (47172) */ + 3347, /* B845 (47173) */ + 3347, /* B846 (47174) */ + 3347, /* B847 (47175) */ + 3347, /* B848 (47176) */ + 3347, /* B849 (47177) */ + 3347, /* B84A (47178) */ + 3347, /* B84B (47179) */ + 3347, /* B84C (47180) */ + 3347, /* B84D (47181) */ + 3347, /* B84E (47182) */ + 3347, /* B84F (47183) */ + 3347, /* B850 (47184) */ + 3347, /* B851 (47185) */ + 3347, /* B852 (47186) */ + 3347, /* B853 (47187) */ + 3347, /* B854 (47188) */ + 3347, /* B855 (47189) */ + 3347, /* B856 (47190) */ + 3347, /* B857 (47191) */ + 3347, /* B858 (47192) */ + 3347, /* B859 (47193) */ + 3347, /* B85A (47194) */ + 3347, /* B85B (47195) */ + 3347, /* B85C (47196) */ + 3347, /* B85D (47197) */ + 3347, /* B85E (47198) */ + 3347, /* B85F (47199) */ + 3347, /* B860 (47200) */ + 3347, /* B861 (47201) */ + 3347, /* B862 (47202) */ + 3347, /* B863 (47203) */ + 3347, /* B864 (47204) */ + 3347, /* B865 (47205) */ + 3347, /* B866 (47206) */ + 3347, /* B867 (47207) */ + 3347, /* B868 (47208) */ + 3347, /* B869 (47209) */ + 3347, /* B86A (47210) */ + 3347, /* B86B (47211) */ + 3347, /* B86C (47212) */ + 3347, /* B86D (47213) */ + 3347, /* B86E (47214) */ + 3347, /* B86F (47215) */ + 3347, /* B870 (47216) */ + 3347, /* B871 (47217) */ + 3347, /* B872 (47218) */ + 3347, /* B873 (47219) */ + 3347, /* B874 (47220) */ + 3347, /* B875 (47221) */ + 3347, /* B876 (47222) */ + 3347, /* B877 (47223) */ + 3347, /* B878 (47224) */ + 3347, /* B879 (47225) */ + 3347, /* B87A (47226) */ + 3347, /* B87B (47227) */ + 3347, /* B87C (47228) */ + 3347, /* B87D (47229) */ + 3347, /* B87E (47230) */ + 3347, /* B87F (47231) */ + 3347, /* B880 (47232) */ + 3347, /* B881 (47233) */ + 3347, /* B882 (47234) */ + 3347, /* B883 (47235) */ + 3347, /* B884 (47236) */ + 3347, /* B885 (47237) */ + 3347, /* B886 (47238) */ + 3347, /* B887 (47239) */ + 3347, /* B888 (47240) */ + 3347, /* B889 (47241) */ + 3347, /* B88A (47242) */ + 3347, /* B88B (47243) */ + 3347, /* B88C (47244) */ + 3347, /* B88D (47245) */ + 3347, /* B88E (47246) */ + 3347, /* B88F (47247) */ + 3347, /* B890 (47248) */ + 3347, /* B891 (47249) */ + 3347, /* B892 (47250) */ + 3347, /* B893 (47251) */ + 3347, /* B894 (47252) */ + 3347, /* B895 (47253) */ + 3347, /* B896 (47254) */ + 3347, /* B897 (47255) */ + 3347, /* B898 (47256) */ + 3347, /* B899 (47257) */ + 3347, /* B89A (47258) */ + 3347, /* B89B (47259) */ + 3347, /* B89C (47260) */ + 3347, /* B89D (47261) */ + 3347, /* B89E (47262) */ + 3347, /* B89F (47263) */ + 3347, /* B8A0 (47264) */ + 3347, /* B8A1 (47265) */ + 3347, /* B8A2 (47266) */ + 3347, /* B8A3 (47267) */ + 3347, /* B8A4 (47268) */ + 3347, /* B8A5 (47269) */ + 3347, /* B8A6 (47270) */ + 3347, /* B8A7 (47271) */ + 3347, /* B8A8 (47272) */ + 3347, /* B8A9 (47273) */ + 3347, /* B8AA (47274) */ + 3347, /* B8AB (47275) */ + 3347, /* B8AC (47276) */ + 3347, /* B8AD (47277) */ + 3347, /* B8AE (47278) */ + 3347, /* B8AF (47279) */ + 3347, /* B8B0 (47280) */ + 3347, /* B8B1 (47281) */ + 3347, /* B8B2 (47282) */ + 3347, /* B8B3 (47283) */ + 3347, /* B8B4 (47284) */ + 3347, /* B8B5 (47285) */ + 3347, /* B8B6 (47286) */ + 3347, /* B8B7 (47287) */ + 3347, /* B8B8 (47288) */ + 3347, /* B8B9 (47289) */ + 3347, /* B8BA (47290) */ + 3347, /* B8BB (47291) */ + 3347, /* B8BC (47292) */ + 3347, /* B8BD (47293) */ + 3347, /* B8BE (47294) */ + 3347, /* B8BF (47295) */ + 3347, /* B8C0 (47296) */ + 3347, /* B8C1 (47297) */ + 3347, /* B8C2 (47298) */ + 3347, /* B8C3 (47299) */ + 3347, /* B8C4 (47300) */ + 3347, /* B8C5 (47301) */ + 3347, /* B8C6 (47302) */ + 3347, /* B8C7 (47303) */ + 3347, /* B8C8 (47304) */ + 3347, /* B8C9 (47305) */ + 3347, /* B8CA (47306) */ + 3347, /* B8CB (47307) */ + 3347, /* B8CC (47308) */ + 3347, /* B8CD (47309) */ + 3347, /* B8CE (47310) */ + 3347, /* B8CF (47311) */ + 3347, /* B8D0 (47312) */ + 3347, /* B8D1 (47313) */ + 3347, /* B8D2 (47314) */ + 3347, /* B8D3 (47315) */ + 3347, /* B8D4 (47316) */ + 3347, /* B8D5 (47317) */ + 3347, /* B8D6 (47318) */ + 3347, /* B8D7 (47319) */ + 3347, /* B8D8 (47320) */ + 3347, /* B8D9 (47321) */ + 3347, /* B8DA (47322) */ + 3347, /* B8DB (47323) */ + 3347, /* B8DC (47324) */ + 3347, /* B8DD (47325) */ + 3347, /* B8DE (47326) */ + 3347, /* B8DF (47327) */ + 3347, /* B8E0 (47328) */ + 3347, /* B8E1 (47329) */ + 3347, /* B8E2 (47330) */ + 3347, /* B8E3 (47331) */ + 3347, /* B8E4 (47332) */ + 3347, /* B8E5 (47333) */ + 3347, /* B8E6 (47334) */ + 3347, /* B8E7 (47335) */ + 3347, /* B8E8 (47336) */ + 3347, /* B8E9 (47337) */ + 3347, /* B8EA (47338) */ + 3347, /* B8EB (47339) */ + 3347, /* B8EC (47340) */ + 3347, /* B8ED (47341) */ + 3347, /* B8EE (47342) */ + 3347, /* B8EF (47343) */ + 3347, /* B8F0 (47344) */ + 3347, /* B8F1 (47345) */ + 3347, /* B8F2 (47346) */ + 3347, /* B8F3 (47347) */ + 3347, /* B8F4 (47348) */ + 3347, /* B8F5 (47349) */ + 3347, /* B8F6 (47350) */ + 3347, /* B8F7 (47351) */ + 3347, /* B8F8 (47352) */ + 3347, /* B8F9 (47353) */ + 3347, /* B8FA (47354) */ + 3347, /* B8FB (47355) */ + 3347, /* B8FC (47356) */ + 3347, /* B8FD (47357) */ + 3347, /* B8FE (47358) */ + 3347, /* B8FF (47359) */ + 3347, /* B900 (47360) */ + 3347, /* B901 (47361) */ + 3347, /* B902 (47362) */ + 3347, /* B903 (47363) */ + 3347, /* B904 (47364) */ + 3347, /* B905 (47365) */ + 3347, /* B906 (47366) */ + 3347, /* B907 (47367) */ + 3347, /* B908 (47368) */ + 3347, /* B909 (47369) */ + 3347, /* B90A (47370) */ + 3347, /* B90B (47371) */ + 3347, /* B90C (47372) */ + 3347, /* B90D (47373) */ + 3347, /* B90E (47374) */ + 3347, /* B90F (47375) */ + 3347, /* B910 (47376) */ + 3347, /* B911 (47377) */ + 3347, /* B912 (47378) */ + 3347, /* B913 (47379) */ + 3347, /* B914 (47380) */ + 3347, /* B915 (47381) */ + 3347, /* B916 (47382) */ + 3347, /* B917 (47383) */ + 3347, /* B918 (47384) */ + 3347, /* B919 (47385) */ + 3347, /* B91A (47386) */ + 3347, /* B91B (47387) */ + 3347, /* B91C (47388) */ + 3347, /* B91D (47389) */ + 3347, /* B91E (47390) */ + 3347, /* B91F (47391) */ + 3347, /* B920 (47392) */ + 3347, /* B921 (47393) */ + 3347, /* B922 (47394) */ + 3347, /* B923 (47395) */ + 3347, /* B924 (47396) */ + 3347, /* B925 (47397) */ + 3347, /* B926 (47398) */ + 3347, /* B927 (47399) */ + 3347, /* B928 (47400) */ + 3347, /* B929 (47401) */ + 3347, /* B92A (47402) */ + 3347, /* B92B (47403) */ + 3347, /* B92C (47404) */ + 3347, /* B92D (47405) */ + 3347, /* B92E (47406) */ + 3347, /* B92F (47407) */ + 3347, /* B930 (47408) */ + 3347, /* B931 (47409) */ + 3347, /* B932 (47410) */ + 3347, /* B933 (47411) */ + 3347, /* B934 (47412) */ + 3347, /* B935 (47413) */ + 3347, /* B936 (47414) */ + 3347, /* B937 (47415) */ + 3347, /* B938 (47416) */ + 3347, /* B939 (47417) */ + 3347, /* B93A (47418) */ + 3347, /* B93B (47419) */ + 3347, /* B93C (47420) */ + 3347, /* B93D (47421) */ + 3347, /* B93E (47422) */ + 3347, /* B93F (47423) */ + 3347, /* B940 (47424) */ + 3347, /* B941 (47425) */ + 3347, /* B942 (47426) */ + 3347, /* B943 (47427) */ + 3347, /* B944 (47428) */ + 3347, /* B945 (47429) */ + 3347, /* B946 (47430) */ + 3347, /* B947 (47431) */ + 3347, /* B948 (47432) */ + 3347, /* B949 (47433) */ + 3347, /* B94A (47434) */ + 3347, /* B94B (47435) */ + 3347, /* B94C (47436) */ + 3347, /* B94D (47437) */ + 3347, /* B94E (47438) */ + 3347, /* B94F (47439) */ + 3347, /* B950 (47440) */ + 3347, /* B951 (47441) */ + 3347, /* B952 (47442) */ + 3347, /* B953 (47443) */ + 3347, /* B954 (47444) */ + 3347, /* B955 (47445) */ + 3347, /* B956 (47446) */ + 3347, /* B957 (47447) */ + 3347, /* B958 (47448) */ + 3347, /* B959 (47449) */ + 3347, /* B95A (47450) */ + 3347, /* B95B (47451) */ + 3347, /* B95C (47452) */ + 3347, /* B95D (47453) */ + 3347, /* B95E (47454) */ + 3347, /* B95F (47455) */ + 3347, /* B960 (47456) */ + 3347, /* B961 (47457) */ + 3347, /* B962 (47458) */ + 3347, /* B963 (47459) */ + 3347, /* B964 (47460) */ + 3347, /* B965 (47461) */ + 3347, /* B966 (47462) */ + 3347, /* B967 (47463) */ + 3347, /* B968 (47464) */ + 3347, /* B969 (47465) */ + 3347, /* B96A (47466) */ + 3347, /* B96B (47467) */ + 3347, /* B96C (47468) */ + 3347, /* B96D (47469) */ + 3347, /* B96E (47470) */ + 3347, /* B96F (47471) */ + 3347, /* B970 (47472) */ + 3347, /* B971 (47473) */ + 3347, /* B972 (47474) */ + 3347, /* B973 (47475) */ + 3347, /* B974 (47476) */ + 3347, /* B975 (47477) */ + 3347, /* B976 (47478) */ + 3347, /* B977 (47479) */ + 3347, /* B978 (47480) */ + 3347, /* B979 (47481) */ + 3347, /* B97A (47482) */ + 3347, /* B97B (47483) */ + 3347, /* B97C (47484) */ + 3347, /* B97D (47485) */ + 3347, /* B97E (47486) */ + 3347, /* B97F (47487) */ + 3347, /* B980 (47488) */ + 3347, /* B981 (47489) */ + 3347, /* B982 (47490) */ + 3347, /* B983 (47491) */ + 3347, /* B984 (47492) */ + 3347, /* B985 (47493) */ + 3347, /* B986 (47494) */ + 3347, /* B987 (47495) */ + 3347, /* B988 (47496) */ + 3347, /* B989 (47497) */ + 3347, /* B98A (47498) */ + 3347, /* B98B (47499) */ + 3347, /* B98C (47500) */ + 3347, /* B98D (47501) */ + 3347, /* B98E (47502) */ + 3347, /* B98F (47503) */ + 3347, /* B990 (47504) */ + 3347, /* B991 (47505) */ + 3347, /* B992 (47506) */ + 3347, /* B993 (47507) */ + 3347, /* B994 (47508) */ + 3347, /* B995 (47509) */ + 3347, /* B996 (47510) */ + 3347, /* B997 (47511) */ + 3347, /* B998 (47512) */ + 3347, /* B999 (47513) */ + 3347, /* B99A (47514) */ + 3347, /* B99B (47515) */ + 3347, /* B99C (47516) */ + 3347, /* B99D (47517) */ + 3347, /* B99E (47518) */ + 3347, /* B99F (47519) */ + 3347, /* B9A0 (47520) */ + 3347, /* B9A1 (47521) */ + 3347, /* B9A2 (47522) */ + 3347, /* B9A3 (47523) */ + 3347, /* B9A4 (47524) */ + 3347, /* B9A5 (47525) */ + 3347, /* B9A6 (47526) */ + 3347, /* B9A7 (47527) */ + 3347, /* B9A8 (47528) */ + 3347, /* B9A9 (47529) */ + 3347, /* B9AA (47530) */ + 3347, /* B9AB (47531) */ + 3347, /* B9AC (47532) */ + 3347, /* B9AD (47533) */ + 3347, /* B9AE (47534) */ + 3347, /* B9AF (47535) */ + 3347, /* B9B0 (47536) */ + 3347, /* B9B1 (47537) */ + 3347, /* B9B2 (47538) */ + 3347, /* B9B3 (47539) */ + 3347, /* B9B4 (47540) */ + 3347, /* B9B5 (47541) */ + 3347, /* B9B6 (47542) */ + 3347, /* B9B7 (47543) */ + 3347, /* B9B8 (47544) */ + 3347, /* B9B9 (47545) */ + 3347, /* B9BA (47546) */ + 3347, /* B9BB (47547) */ + 3347, /* B9BC (47548) */ + 3347, /* B9BD (47549) */ + 3347, /* B9BE (47550) */ + 3347, /* B9BF (47551) */ + 3347, /* B9C0 (47552) */ + 3347, /* B9C1 (47553) */ + 3347, /* B9C2 (47554) */ + 3347, /* B9C3 (47555) */ + 3347, /* B9C4 (47556) */ + 3347, /* B9C5 (47557) */ + 3347, /* B9C6 (47558) */ + 3347, /* B9C7 (47559) */ + 3347, /* B9C8 (47560) */ + 3347, /* B9C9 (47561) */ + 3347, /* B9CA (47562) */ + 3347, /* B9CB (47563) */ + 3347, /* B9CC (47564) */ + 3347, /* B9CD (47565) */ + 3347, /* B9CE (47566) */ + 3347, /* B9CF (47567) */ + 3347, /* B9D0 (47568) */ + 3347, /* B9D1 (47569) */ + 3347, /* B9D2 (47570) */ + 3347, /* B9D3 (47571) */ + 3347, /* B9D4 (47572) */ + 3347, /* B9D5 (47573) */ + 3347, /* B9D6 (47574) */ + 3347, /* B9D7 (47575) */ + 3347, /* B9D8 (47576) */ + 3347, /* B9D9 (47577) */ + 3347, /* B9DA (47578) */ + 3347, /* B9DB (47579) */ + 3347, /* B9DC (47580) */ + 3347, /* B9DD (47581) */ + 3347, /* B9DE (47582) */ + 3347, /* B9DF (47583) */ + 3347, /* B9E0 (47584) */ + 3347, /* B9E1 (47585) */ + 3347, /* B9E2 (47586) */ + 3347, /* B9E3 (47587) */ + 3347, /* B9E4 (47588) */ + 3347, /* B9E5 (47589) */ + 3347, /* B9E6 (47590) */ + 3347, /* B9E7 (47591) */ + 3347, /* B9E8 (47592) */ + 3347, /* B9E9 (47593) */ + 3347, /* B9EA (47594) */ + 3347, /* B9EB (47595) */ + 3347, /* B9EC (47596) */ + 3347, /* B9ED (47597) */ + 3347, /* B9EE (47598) */ + 3347, /* B9EF (47599) */ + 3347, /* B9F0 (47600) */ + 3347, /* B9F1 (47601) */ + 3347, /* B9F2 (47602) */ + 3347, /* B9F3 (47603) */ + 3347, /* B9F4 (47604) */ + 3347, /* B9F5 (47605) */ + 3347, /* B9F6 (47606) */ + 3347, /* B9F7 (47607) */ + 3347, /* B9F8 (47608) */ + 3347, /* B9F9 (47609) */ + 3347, /* B9FA (47610) */ + 3347, /* B9FB (47611) */ + 3347, /* B9FC (47612) */ + 3347, /* B9FD (47613) */ + 3347, /* B9FE (47614) */ + 3347, /* B9FF (47615) */ + 3347, /* BA00 (47616) */ + 3347, /* BA01 (47617) */ + 3347, /* BA02 (47618) */ + 3347, /* BA03 (47619) */ + 3347, /* BA04 (47620) */ + 3347, /* BA05 (47621) */ + 3347, /* BA06 (47622) */ + 3347, /* BA07 (47623) */ + 3347, /* BA08 (47624) */ + 3347, /* BA09 (47625) */ + 3347, /* BA0A (47626) */ + 3347, /* BA0B (47627) */ + 3347, /* BA0C (47628) */ + 3347, /* BA0D (47629) */ + 3347, /* BA0E (47630) */ + 3347, /* BA0F (47631) */ + 3347, /* BA10 (47632) */ + 3347, /* BA11 (47633) */ + 3347, /* BA12 (47634) */ + 3347, /* BA13 (47635) */ + 3347, /* BA14 (47636) */ + 3347, /* BA15 (47637) */ + 3347, /* BA16 (47638) */ + 3347, /* BA17 (47639) */ + 3347, /* BA18 (47640) */ + 3347, /* BA19 (47641) */ + 3347, /* BA1A (47642) */ + 3347, /* BA1B (47643) */ + 3347, /* BA1C (47644) */ + 3347, /* BA1D (47645) */ + 3347, /* BA1E (47646) */ + 3347, /* BA1F (47647) */ + 3347, /* BA20 (47648) */ + 3347, /* BA21 (47649) */ + 3347, /* BA22 (47650) */ + 3347, /* BA23 (47651) */ + 3347, /* BA24 (47652) */ + 3347, /* BA25 (47653) */ + 3347, /* BA26 (47654) */ + 3347, /* BA27 (47655) */ + 3347, /* BA28 (47656) */ + 3347, /* BA29 (47657) */ + 3347, /* BA2A (47658) */ + 3347, /* BA2B (47659) */ + 3347, /* BA2C (47660) */ + 3347, /* BA2D (47661) */ + 3347, /* BA2E (47662) */ + 3347, /* BA2F (47663) */ + 3347, /* BA30 (47664) */ + 3347, /* BA31 (47665) */ + 3347, /* BA32 (47666) */ + 3347, /* BA33 (47667) */ + 3347, /* BA34 (47668) */ + 3347, /* BA35 (47669) */ + 3347, /* BA36 (47670) */ + 3347, /* BA37 (47671) */ + 3347, /* BA38 (47672) */ + 3347, /* BA39 (47673) */ + 3347, /* BA3A (47674) */ + 3347, /* BA3B (47675) */ + 3347, /* BA3C (47676) */ + 3347, /* BA3D (47677) */ + 3347, /* BA3E (47678) */ + 3347, /* BA3F (47679) */ + 3347, /* BA40 (47680) */ + 3347, /* BA41 (47681) */ + 3347, /* BA42 (47682) */ + 3347, /* BA43 (47683) */ + 3347, /* BA44 (47684) */ + 3347, /* BA45 (47685) */ + 3347, /* BA46 (47686) */ + 3347, /* BA47 (47687) */ + 3347, /* BA48 (47688) */ + 3347, /* BA49 (47689) */ + 3347, /* BA4A (47690) */ + 3347, /* BA4B (47691) */ + 3347, /* BA4C (47692) */ + 3347, /* BA4D (47693) */ + 3347, /* BA4E (47694) */ + 3347, /* BA4F (47695) */ + 3347, /* BA50 (47696) */ + 3347, /* BA51 (47697) */ + 3347, /* BA52 (47698) */ + 3347, /* BA53 (47699) */ + 3347, /* BA54 (47700) */ + 3347, /* BA55 (47701) */ + 3347, /* BA56 (47702) */ + 3347, /* BA57 (47703) */ + 3347, /* BA58 (47704) */ + 3347, /* BA59 (47705) */ + 3347, /* BA5A (47706) */ + 3347, /* BA5B (47707) */ + 3347, /* BA5C (47708) */ + 3347, /* BA5D (47709) */ + 3347, /* BA5E (47710) */ + 3347, /* BA5F (47711) */ + 3347, /* BA60 (47712) */ + 3347, /* BA61 (47713) */ + 3347, /* BA62 (47714) */ + 3347, /* BA63 (47715) */ + 3347, /* BA64 (47716) */ + 3347, /* BA65 (47717) */ + 3347, /* BA66 (47718) */ + 3347, /* BA67 (47719) */ + 3347, /* BA68 (47720) */ + 3347, /* BA69 (47721) */ + 3347, /* BA6A (47722) */ + 3347, /* BA6B (47723) */ + 3347, /* BA6C (47724) */ + 3347, /* BA6D (47725) */ + 3347, /* BA6E (47726) */ + 3347, /* BA6F (47727) */ + 3347, /* BA70 (47728) */ + 3347, /* BA71 (47729) */ + 3347, /* BA72 (47730) */ + 3347, /* BA73 (47731) */ + 3347, /* BA74 (47732) */ + 3347, /* BA75 (47733) */ + 3347, /* BA76 (47734) */ + 3347, /* BA77 (47735) */ + 3347, /* BA78 (47736) */ + 3347, /* BA79 (47737) */ + 3347, /* BA7A (47738) */ + 3347, /* BA7B (47739) */ + 3347, /* BA7C (47740) */ + 3347, /* BA7D (47741) */ + 3347, /* BA7E (47742) */ + 3347, /* BA7F (47743) */ + 3347, /* BA80 (47744) */ + 3347, /* BA81 (47745) */ + 3347, /* BA82 (47746) */ + 3347, /* BA83 (47747) */ + 3347, /* BA84 (47748) */ + 3347, /* BA85 (47749) */ + 3347, /* BA86 (47750) */ + 3347, /* BA87 (47751) */ + 3347, /* BA88 (47752) */ + 3347, /* BA89 (47753) */ + 3347, /* BA8A (47754) */ + 3347, /* BA8B (47755) */ + 3347, /* BA8C (47756) */ + 3347, /* BA8D (47757) */ + 3347, /* BA8E (47758) */ + 3347, /* BA8F (47759) */ + 3347, /* BA90 (47760) */ + 3347, /* BA91 (47761) */ + 3347, /* BA92 (47762) */ + 3347, /* BA93 (47763) */ + 3347, /* BA94 (47764) */ + 3347, /* BA95 (47765) */ + 3347, /* BA96 (47766) */ + 3347, /* BA97 (47767) */ + 3347, /* BA98 (47768) */ + 3347, /* BA99 (47769) */ + 3347, /* BA9A (47770) */ + 3347, /* BA9B (47771) */ + 3347, /* BA9C (47772) */ + 3347, /* BA9D (47773) */ + 3347, /* BA9E (47774) */ + 3347, /* BA9F (47775) */ + 3347, /* BAA0 (47776) */ + 3347, /* BAA1 (47777) */ + 3347, /* BAA2 (47778) */ + 3347, /* BAA3 (47779) */ + 3347, /* BAA4 (47780) */ + 3347, /* BAA5 (47781) */ + 3347, /* BAA6 (47782) */ + 3347, /* BAA7 (47783) */ + 3347, /* BAA8 (47784) */ + 3347, /* BAA9 (47785) */ + 3347, /* BAAA (47786) */ + 3347, /* BAAB (47787) */ + 3347, /* BAAC (47788) */ + 3347, /* BAAD (47789) */ + 3347, /* BAAE (47790) */ + 3347, /* BAAF (47791) */ + 3347, /* BAB0 (47792) */ + 3347, /* BAB1 (47793) */ + 3347, /* BAB2 (47794) */ + 3347, /* BAB3 (47795) */ + 3347, /* BAB4 (47796) */ + 3347, /* BAB5 (47797) */ + 3347, /* BAB6 (47798) */ + 3347, /* BAB7 (47799) */ + 3347, /* BAB8 (47800) */ + 3347, /* BAB9 (47801) */ + 3347, /* BABA (47802) */ + 3347, /* BABB (47803) */ + 3347, /* BABC (47804) */ + 3347, /* BABD (47805) */ + 3347, /* BABE (47806) */ + 3347, /* BABF (47807) */ + 3347, /* BAC0 (47808) */ + 3347, /* BAC1 (47809) */ + 3347, /* BAC2 (47810) */ + 3347, /* BAC3 (47811) */ + 3347, /* BAC4 (47812) */ + 3347, /* BAC5 (47813) */ + 3347, /* BAC6 (47814) */ + 3347, /* BAC7 (47815) */ + 3347, /* BAC8 (47816) */ + 3347, /* BAC9 (47817) */ + 3347, /* BACA (47818) */ + 3347, /* BACB (47819) */ + 3347, /* BACC (47820) */ + 3347, /* BACD (47821) */ + 3347, /* BACE (47822) */ + 3347, /* BACF (47823) */ + 3347, /* BAD0 (47824) */ + 3347, /* BAD1 (47825) */ + 3347, /* BAD2 (47826) */ + 3347, /* BAD3 (47827) */ + 3347, /* BAD4 (47828) */ + 3347, /* BAD5 (47829) */ + 3347, /* BAD6 (47830) */ + 3347, /* BAD7 (47831) */ + 3347, /* BAD8 (47832) */ + 3347, /* BAD9 (47833) */ + 3347, /* BADA (47834) */ + 3347, /* BADB (47835) */ + 3347, /* BADC (47836) */ + 3347, /* BADD (47837) */ + 3347, /* BADE (47838) */ + 3347, /* BADF (47839) */ + 3347, /* BAE0 (47840) */ + 3347, /* BAE1 (47841) */ + 3347, /* BAE2 (47842) */ + 3347, /* BAE3 (47843) */ + 3347, /* BAE4 (47844) */ + 3347, /* BAE5 (47845) */ + 3347, /* BAE6 (47846) */ + 3347, /* BAE7 (47847) */ + 3347, /* BAE8 (47848) */ + 3347, /* BAE9 (47849) */ + 3347, /* BAEA (47850) */ + 3347, /* BAEB (47851) */ + 3347, /* BAEC (47852) */ + 3347, /* BAED (47853) */ + 3347, /* BAEE (47854) */ + 3347, /* BAEF (47855) */ + 3347, /* BAF0 (47856) */ + 3347, /* BAF1 (47857) */ + 3347, /* BAF2 (47858) */ + 3347, /* BAF3 (47859) */ + 3347, /* BAF4 (47860) */ + 3347, /* BAF5 (47861) */ + 3347, /* BAF6 (47862) */ + 3347, /* BAF7 (47863) */ + 3347, /* BAF8 (47864) */ + 3347, /* BAF9 (47865) */ + 3347, /* BAFA (47866) */ + 3347, /* BAFB (47867) */ + 3347, /* BAFC (47868) */ + 3347, /* BAFD (47869) */ + 3347, /* BAFE (47870) */ + 3347, /* BAFF (47871) */ + 3347, /* BB00 (47872) */ + 3347, /* BB01 (47873) */ + 3347, /* BB02 (47874) */ + 3347, /* BB03 (47875) */ + 3347, /* BB04 (47876) */ + 3347, /* BB05 (47877) */ + 3347, /* BB06 (47878) */ + 3347, /* BB07 (47879) */ + 3347, /* BB08 (47880) */ + 3347, /* BB09 (47881) */ + 3347, /* BB0A (47882) */ + 3347, /* BB0B (47883) */ + 3347, /* BB0C (47884) */ + 3347, /* BB0D (47885) */ + 3347, /* BB0E (47886) */ + 3347, /* BB0F (47887) */ + 3347, /* BB10 (47888) */ + 3347, /* BB11 (47889) */ + 3347, /* BB12 (47890) */ + 3347, /* BB13 (47891) */ + 3347, /* BB14 (47892) */ + 3347, /* BB15 (47893) */ + 3347, /* BB16 (47894) */ + 3347, /* BB17 (47895) */ + 3347, /* BB18 (47896) */ + 3347, /* BB19 (47897) */ + 3347, /* BB1A (47898) */ + 3347, /* BB1B (47899) */ + 3347, /* BB1C (47900) */ + 3347, /* BB1D (47901) */ + 3347, /* BB1E (47902) */ + 3347, /* BB1F (47903) */ + 3347, /* BB20 (47904) */ + 3347, /* BB21 (47905) */ + 3347, /* BB22 (47906) */ + 3347, /* BB23 (47907) */ + 3347, /* BB24 (47908) */ + 3347, /* BB25 (47909) */ + 3347, /* BB26 (47910) */ + 3347, /* BB27 (47911) */ + 3347, /* BB28 (47912) */ + 3347, /* BB29 (47913) */ + 3347, /* BB2A (47914) */ + 3347, /* BB2B (47915) */ + 3347, /* BB2C (47916) */ + 3347, /* BB2D (47917) */ + 3347, /* BB2E (47918) */ + 3347, /* BB2F (47919) */ + 3347, /* BB30 (47920) */ + 3347, /* BB31 (47921) */ + 3347, /* BB32 (47922) */ + 3347, /* BB33 (47923) */ + 3347, /* BB34 (47924) */ + 3347, /* BB35 (47925) */ + 3347, /* BB36 (47926) */ + 3347, /* BB37 (47927) */ + 3347, /* BB38 (47928) */ + 3347, /* BB39 (47929) */ + 3347, /* BB3A (47930) */ + 3347, /* BB3B (47931) */ + 3347, /* BB3C (47932) */ + 3347, /* BB3D (47933) */ + 3347, /* BB3E (47934) */ + 3347, /* BB3F (47935) */ + 3347, /* BB40 (47936) */ + 3347, /* BB41 (47937) */ + 3347, /* BB42 (47938) */ + 3347, /* BB43 (47939) */ + 3347, /* BB44 (47940) */ + 3347, /* BB45 (47941) */ + 3347, /* BB46 (47942) */ + 3347, /* BB47 (47943) */ + 3347, /* BB48 (47944) */ + 3347, /* BB49 (47945) */ + 3347, /* BB4A (47946) */ + 3347, /* BB4B (47947) */ + 3347, /* BB4C (47948) */ + 3347, /* BB4D (47949) */ + 3347, /* BB4E (47950) */ + 3347, /* BB4F (47951) */ + 3347, /* BB50 (47952) */ + 3347, /* BB51 (47953) */ + 3347, /* BB52 (47954) */ + 3347, /* BB53 (47955) */ + 3347, /* BB54 (47956) */ + 3347, /* BB55 (47957) */ + 3347, /* BB56 (47958) */ + 3347, /* BB57 (47959) */ + 3347, /* BB58 (47960) */ + 3347, /* BB59 (47961) */ + 3347, /* BB5A (47962) */ + 3347, /* BB5B (47963) */ + 3347, /* BB5C (47964) */ + 3347, /* BB5D (47965) */ + 3347, /* BB5E (47966) */ + 3347, /* BB5F (47967) */ + 3347, /* BB60 (47968) */ + 3347, /* BB61 (47969) */ + 3347, /* BB62 (47970) */ + 3347, /* BB63 (47971) */ + 3347, /* BB64 (47972) */ + 3347, /* BB65 (47973) */ + 3347, /* BB66 (47974) */ + 3347, /* BB67 (47975) */ + 3347, /* BB68 (47976) */ + 3347, /* BB69 (47977) */ + 3347, /* BB6A (47978) */ + 3347, /* BB6B (47979) */ + 3347, /* BB6C (47980) */ + 3347, /* BB6D (47981) */ + 3347, /* BB6E (47982) */ + 3347, /* BB6F (47983) */ + 3347, /* BB70 (47984) */ + 3347, /* BB71 (47985) */ + 3347, /* BB72 (47986) */ + 3347, /* BB73 (47987) */ + 3347, /* BB74 (47988) */ + 3347, /* BB75 (47989) */ + 3347, /* BB76 (47990) */ + 3347, /* BB77 (47991) */ + 3347, /* BB78 (47992) */ + 3347, /* BB79 (47993) */ + 3347, /* BB7A (47994) */ + 3347, /* BB7B (47995) */ + 3347, /* BB7C (47996) */ + 3347, /* BB7D (47997) */ + 3347, /* BB7E (47998) */ + 3347, /* BB7F (47999) */ + 3347, /* BB80 (48000) */ + 3347, /* BB81 (48001) */ + 3347, /* BB82 (48002) */ + 3347, /* BB83 (48003) */ + 3347, /* BB84 (48004) */ + 3347, /* BB85 (48005) */ + 3347, /* BB86 (48006) */ + 3347, /* BB87 (48007) */ + 3347, /* BB88 (48008) */ + 3347, /* BB89 (48009) */ + 3347, /* BB8A (48010) */ + 3347, /* BB8B (48011) */ + 3347, /* BB8C (48012) */ + 3347, /* BB8D (48013) */ + 3347, /* BB8E (48014) */ + 3347, /* BB8F (48015) */ + 3347, /* BB90 (48016) */ + 3347, /* BB91 (48017) */ + 3347, /* BB92 (48018) */ + 3347, /* BB93 (48019) */ + 3347, /* BB94 (48020) */ + 3347, /* BB95 (48021) */ + 3347, /* BB96 (48022) */ + 3347, /* BB97 (48023) */ + 3347, /* BB98 (48024) */ + 3347, /* BB99 (48025) */ + 3347, /* BB9A (48026) */ + 3347, /* BB9B (48027) */ + 3347, /* BB9C (48028) */ + 3347, /* BB9D (48029) */ + 3347, /* BB9E (48030) */ + 3347, /* BB9F (48031) */ + 3347, /* BBA0 (48032) */ + 3347, /* BBA1 (48033) */ + 3347, /* BBA2 (48034) */ + 3347, /* BBA3 (48035) */ + 3347, /* BBA4 (48036) */ + 3347, /* BBA5 (48037) */ + 3347, /* BBA6 (48038) */ + 3347, /* BBA7 (48039) */ + 3347, /* BBA8 (48040) */ + 3347, /* BBA9 (48041) */ + 3347, /* BBAA (48042) */ + 3347, /* BBAB (48043) */ + 3347, /* BBAC (48044) */ + 3347, /* BBAD (48045) */ + 3347, /* BBAE (48046) */ + 3347, /* BBAF (48047) */ + 3347, /* BBB0 (48048) */ + 3347, /* BBB1 (48049) */ + 3347, /* BBB2 (48050) */ + 3347, /* BBB3 (48051) */ + 3347, /* BBB4 (48052) */ + 3347, /* BBB5 (48053) */ + 3347, /* BBB6 (48054) */ + 3347, /* BBB7 (48055) */ + 3347, /* BBB8 (48056) */ + 3347, /* BBB9 (48057) */ + 3347, /* BBBA (48058) */ + 3347, /* BBBB (48059) */ + 3347, /* BBBC (48060) */ + 3347, /* BBBD (48061) */ + 3347, /* BBBE (48062) */ + 3347, /* BBBF (48063) */ + 3347, /* BBC0 (48064) */ + 3347, /* BBC1 (48065) */ + 3347, /* BBC2 (48066) */ + 3347, /* BBC3 (48067) */ + 3347, /* BBC4 (48068) */ + 3347, /* BBC5 (48069) */ + 3347, /* BBC6 (48070) */ + 3347, /* BBC7 (48071) */ + 3347, /* BBC8 (48072) */ + 3347, /* BBC9 (48073) */ + 3347, /* BBCA (48074) */ + 3347, /* BBCB (48075) */ + 3347, /* BBCC (48076) */ + 3347, /* BBCD (48077) */ + 3347, /* BBCE (48078) */ + 3347, /* BBCF (48079) */ + 3347, /* BBD0 (48080) */ + 3347, /* BBD1 (48081) */ + 3347, /* BBD2 (48082) */ + 3347, /* BBD3 (48083) */ + 3347, /* BBD4 (48084) */ + 3347, /* BBD5 (48085) */ + 3347, /* BBD6 (48086) */ + 3347, /* BBD7 (48087) */ + 3347, /* BBD8 (48088) */ + 3347, /* BBD9 (48089) */ + 3347, /* BBDA (48090) */ + 3347, /* BBDB (48091) */ + 3347, /* BBDC (48092) */ + 3347, /* BBDD (48093) */ + 3347, /* BBDE (48094) */ + 3347, /* BBDF (48095) */ + 3347, /* BBE0 (48096) */ + 3347, /* BBE1 (48097) */ + 3347, /* BBE2 (48098) */ + 3347, /* BBE3 (48099) */ + 3347, /* BBE4 (48100) */ + 3347, /* BBE5 (48101) */ + 3347, /* BBE6 (48102) */ + 3347, /* BBE7 (48103) */ + 3347, /* BBE8 (48104) */ + 3347, /* BBE9 (48105) */ + 3347, /* BBEA (48106) */ + 3347, /* BBEB (48107) */ + 3347, /* BBEC (48108) */ + 3347, /* BBED (48109) */ + 3347, /* BBEE (48110) */ + 3347, /* BBEF (48111) */ + 3347, /* BBF0 (48112) */ + 3347, /* BBF1 (48113) */ + 3347, /* BBF2 (48114) */ + 3347, /* BBF3 (48115) */ + 3347, /* BBF4 (48116) */ + 3347, /* BBF5 (48117) */ + 3347, /* BBF6 (48118) */ + 3347, /* BBF7 (48119) */ + 3347, /* BBF8 (48120) */ + 3347, /* BBF9 (48121) */ + 3347, /* BBFA (48122) */ + 3347, /* BBFB (48123) */ + 3347, /* BBFC (48124) */ + 3347, /* BBFD (48125) */ + 3347, /* BBFE (48126) */ + 3347, /* BBFF (48127) */ + 3347, /* BC00 (48128) */ + 3347, /* BC01 (48129) */ + 3347, /* BC02 (48130) */ + 3347, /* BC03 (48131) */ + 3347, /* BC04 (48132) */ + 3347, /* BC05 (48133) */ + 3347, /* BC06 (48134) */ + 3347, /* BC07 (48135) */ + 3347, /* BC08 (48136) */ + 3347, /* BC09 (48137) */ + 3347, /* BC0A (48138) */ + 3347, /* BC0B (48139) */ + 3347, /* BC0C (48140) */ + 3347, /* BC0D (48141) */ + 3347, /* BC0E (48142) */ + 3347, /* BC0F (48143) */ + 3347, /* BC10 (48144) */ + 3347, /* BC11 (48145) */ + 3347, /* BC12 (48146) */ + 3347, /* BC13 (48147) */ + 3347, /* BC14 (48148) */ + 3347, /* BC15 (48149) */ + 3347, /* BC16 (48150) */ + 3347, /* BC17 (48151) */ + 3347, /* BC18 (48152) */ + 3347, /* BC19 (48153) */ + 3347, /* BC1A (48154) */ + 3347, /* BC1B (48155) */ + 3347, /* BC1C (48156) */ + 3347, /* BC1D (48157) */ + 3347, /* BC1E (48158) */ + 3347, /* BC1F (48159) */ + 3347, /* BC20 (48160) */ + 3347, /* BC21 (48161) */ + 3347, /* BC22 (48162) */ + 3347, /* BC23 (48163) */ + 3347, /* BC24 (48164) */ + 3347, /* BC25 (48165) */ + 3347, /* BC26 (48166) */ + 3347, /* BC27 (48167) */ + 3347, /* BC28 (48168) */ + 3347, /* BC29 (48169) */ + 3347, /* BC2A (48170) */ + 3347, /* BC2B (48171) */ + 3347, /* BC2C (48172) */ + 3347, /* BC2D (48173) */ + 3347, /* BC2E (48174) */ + 3347, /* BC2F (48175) */ + 3347, /* BC30 (48176) */ + 3347, /* BC31 (48177) */ + 3347, /* BC32 (48178) */ + 3347, /* BC33 (48179) */ + 3347, /* BC34 (48180) */ + 3347, /* BC35 (48181) */ + 3347, /* BC36 (48182) */ + 3347, /* BC37 (48183) */ + 3347, /* BC38 (48184) */ + 3347, /* BC39 (48185) */ + 3347, /* BC3A (48186) */ + 3347, /* BC3B (48187) */ + 3347, /* BC3C (48188) */ + 3347, /* BC3D (48189) */ + 3347, /* BC3E (48190) */ + 3347, /* BC3F (48191) */ + 3347, /* BC40 (48192) */ + 3347, /* BC41 (48193) */ + 3347, /* BC42 (48194) */ + 3347, /* BC43 (48195) */ + 3347, /* BC44 (48196) */ + 3347, /* BC45 (48197) */ + 3347, /* BC46 (48198) */ + 3347, /* BC47 (48199) */ + 3347, /* BC48 (48200) */ + 3347, /* BC49 (48201) */ + 3347, /* BC4A (48202) */ + 3347, /* BC4B (48203) */ + 3347, /* BC4C (48204) */ + 3347, /* BC4D (48205) */ + 3347, /* BC4E (48206) */ + 3347, /* BC4F (48207) */ + 3347, /* BC50 (48208) */ + 3347, /* BC51 (48209) */ + 3347, /* BC52 (48210) */ + 3347, /* BC53 (48211) */ + 3347, /* BC54 (48212) */ + 3347, /* BC55 (48213) */ + 3347, /* BC56 (48214) */ + 3347, /* BC57 (48215) */ + 3347, /* BC58 (48216) */ + 3347, /* BC59 (48217) */ + 3347, /* BC5A (48218) */ + 3347, /* BC5B (48219) */ + 3347, /* BC5C (48220) */ + 3347, /* BC5D (48221) */ + 3347, /* BC5E (48222) */ + 3347, /* BC5F (48223) */ + 3347, /* BC60 (48224) */ + 3347, /* BC61 (48225) */ + 3347, /* BC62 (48226) */ + 3347, /* BC63 (48227) */ + 3347, /* BC64 (48228) */ + 3347, /* BC65 (48229) */ + 3347, /* BC66 (48230) */ + 3347, /* BC67 (48231) */ + 3347, /* BC68 (48232) */ + 3347, /* BC69 (48233) */ + 3347, /* BC6A (48234) */ + 3347, /* BC6B (48235) */ + 3347, /* BC6C (48236) */ + 3347, /* BC6D (48237) */ + 3347, /* BC6E (48238) */ + 3347, /* BC6F (48239) */ + 3347, /* BC70 (48240) */ + 3347, /* BC71 (48241) */ + 3347, /* BC72 (48242) */ + 3347, /* BC73 (48243) */ + 3347, /* BC74 (48244) */ + 3347, /* BC75 (48245) */ + 3347, /* BC76 (48246) */ + 3347, /* BC77 (48247) */ + 3347, /* BC78 (48248) */ + 3347, /* BC79 (48249) */ + 3347, /* BC7A (48250) */ + 3347, /* BC7B (48251) */ + 3347, /* BC7C (48252) */ + 3347, /* BC7D (48253) */ + 3347, /* BC7E (48254) */ + 3347, /* BC7F (48255) */ + 3347, /* BC80 (48256) */ + 3347, /* BC81 (48257) */ + 3347, /* BC82 (48258) */ + 3347, /* BC83 (48259) */ + 3347, /* BC84 (48260) */ + 3347, /* BC85 (48261) */ + 3347, /* BC86 (48262) */ + 3347, /* BC87 (48263) */ + 3347, /* BC88 (48264) */ + 3347, /* BC89 (48265) */ + 3347, /* BC8A (48266) */ + 3347, /* BC8B (48267) */ + 3347, /* BC8C (48268) */ + 3347, /* BC8D (48269) */ + 3347, /* BC8E (48270) */ + 3347, /* BC8F (48271) */ + 3347, /* BC90 (48272) */ + 3347, /* BC91 (48273) */ + 3347, /* BC92 (48274) */ + 3347, /* BC93 (48275) */ + 3347, /* BC94 (48276) */ + 3347, /* BC95 (48277) */ + 3347, /* BC96 (48278) */ + 3347, /* BC97 (48279) */ + 3347, /* BC98 (48280) */ + 3347, /* BC99 (48281) */ + 3347, /* BC9A (48282) */ + 3347, /* BC9B (48283) */ + 3347, /* BC9C (48284) */ + 3347, /* BC9D (48285) */ + 3347, /* BC9E (48286) */ + 3347, /* BC9F (48287) */ + 3347, /* BCA0 (48288) */ + 3347, /* BCA1 (48289) */ + 3347, /* BCA2 (48290) */ + 3347, /* BCA3 (48291) */ + 3347, /* BCA4 (48292) */ + 3347, /* BCA5 (48293) */ + 3347, /* BCA6 (48294) */ + 3347, /* BCA7 (48295) */ + 3347, /* BCA8 (48296) */ + 3347, /* BCA9 (48297) */ + 3347, /* BCAA (48298) */ + 3347, /* BCAB (48299) */ + 3347, /* BCAC (48300) */ + 3347, /* BCAD (48301) */ + 3347, /* BCAE (48302) */ + 3347, /* BCAF (48303) */ + 3347, /* BCB0 (48304) */ + 3347, /* BCB1 (48305) */ + 3347, /* BCB2 (48306) */ + 3347, /* BCB3 (48307) */ + 3347, /* BCB4 (48308) */ + 3347, /* BCB5 (48309) */ + 3347, /* BCB6 (48310) */ + 3347, /* BCB7 (48311) */ + 3347, /* BCB8 (48312) */ + 3347, /* BCB9 (48313) */ + 3347, /* BCBA (48314) */ + 3347, /* BCBB (48315) */ + 3347, /* BCBC (48316) */ + 3347, /* BCBD (48317) */ + 3347, /* BCBE (48318) */ + 3347, /* BCBF (48319) */ + 3347, /* BCC0 (48320) */ + 3347, /* BCC1 (48321) */ + 3347, /* BCC2 (48322) */ + 3347, /* BCC3 (48323) */ + 3347, /* BCC4 (48324) */ + 3347, /* BCC5 (48325) */ + 3347, /* BCC6 (48326) */ + 3347, /* BCC7 (48327) */ + 3347, /* BCC8 (48328) */ + 3347, /* BCC9 (48329) */ + 3347, /* BCCA (48330) */ + 3347, /* BCCB (48331) */ + 3347, /* BCCC (48332) */ + 3347, /* BCCD (48333) */ + 3347, /* BCCE (48334) */ + 3347, /* BCCF (48335) */ + 3347, /* BCD0 (48336) */ + 3347, /* BCD1 (48337) */ + 3347, /* BCD2 (48338) */ + 3347, /* BCD3 (48339) */ + 3347, /* BCD4 (48340) */ + 3347, /* BCD5 (48341) */ + 3347, /* BCD6 (48342) */ + 3347, /* BCD7 (48343) */ + 3347, /* BCD8 (48344) */ + 3347, /* BCD9 (48345) */ + 3347, /* BCDA (48346) */ + 3347, /* BCDB (48347) */ + 3347, /* BCDC (48348) */ + 3347, /* BCDD (48349) */ + 3347, /* BCDE (48350) */ + 3347, /* BCDF (48351) */ + 3347, /* BCE0 (48352) */ + 3347, /* BCE1 (48353) */ + 3347, /* BCE2 (48354) */ + 3347, /* BCE3 (48355) */ + 3347, /* BCE4 (48356) */ + 3347, /* BCE5 (48357) */ + 3347, /* BCE6 (48358) */ + 3347, /* BCE7 (48359) */ + 3347, /* BCE8 (48360) */ + 3347, /* BCE9 (48361) */ + 3347, /* BCEA (48362) */ + 3347, /* BCEB (48363) */ + 3347, /* BCEC (48364) */ + 3347, /* BCED (48365) */ + 3347, /* BCEE (48366) */ + 3347, /* BCEF (48367) */ + 3347, /* BCF0 (48368) */ + 3347, /* BCF1 (48369) */ + 3347, /* BCF2 (48370) */ + 3347, /* BCF3 (48371) */ + 3347, /* BCF4 (48372) */ + 3347, /* BCF5 (48373) */ + 3347, /* BCF6 (48374) */ + 3347, /* BCF7 (48375) */ + 3347, /* BCF8 (48376) */ + 3347, /* BCF9 (48377) */ + 3347, /* BCFA (48378) */ + 3347, /* BCFB (48379) */ + 3347, /* BCFC (48380) */ + 3347, /* BCFD (48381) */ + 3347, /* BCFE (48382) */ + 3347, /* BCFF (48383) */ + 3347, /* BD00 (48384) */ + 3347, /* BD01 (48385) */ + 3347, /* BD02 (48386) */ + 3347, /* BD03 (48387) */ + 3347, /* BD04 (48388) */ + 3347, /* BD05 (48389) */ + 3347, /* BD06 (48390) */ + 3347, /* BD07 (48391) */ + 3347, /* BD08 (48392) */ + 3347, /* BD09 (48393) */ + 3347, /* BD0A (48394) */ + 3347, /* BD0B (48395) */ + 3347, /* BD0C (48396) */ + 3347, /* BD0D (48397) */ + 3347, /* BD0E (48398) */ + 3347, /* BD0F (48399) */ + 3347, /* BD10 (48400) */ + 3347, /* BD11 (48401) */ + 3347, /* BD12 (48402) */ + 3347, /* BD13 (48403) */ + 3347, /* BD14 (48404) */ + 3347, /* BD15 (48405) */ + 3347, /* BD16 (48406) */ + 3347, /* BD17 (48407) */ + 3347, /* BD18 (48408) */ + 3347, /* BD19 (48409) */ + 3347, /* BD1A (48410) */ + 3347, /* BD1B (48411) */ + 3347, /* BD1C (48412) */ + 3347, /* BD1D (48413) */ + 3347, /* BD1E (48414) */ + 3347, /* BD1F (48415) */ + 3347, /* BD20 (48416) */ + 3347, /* BD21 (48417) */ + 3347, /* BD22 (48418) */ + 3347, /* BD23 (48419) */ + 3347, /* BD24 (48420) */ + 3347, /* BD25 (48421) */ + 3347, /* BD26 (48422) */ + 3347, /* BD27 (48423) */ + 3347, /* BD28 (48424) */ + 3347, /* BD29 (48425) */ + 3347, /* BD2A (48426) */ + 3347, /* BD2B (48427) */ + 3347, /* BD2C (48428) */ + 3347, /* BD2D (48429) */ + 3347, /* BD2E (48430) */ + 3347, /* BD2F (48431) */ + 3347, /* BD30 (48432) */ + 3347, /* BD31 (48433) */ + 3347, /* BD32 (48434) */ + 3347, /* BD33 (48435) */ + 3347, /* BD34 (48436) */ + 3347, /* BD35 (48437) */ + 3347, /* BD36 (48438) */ + 3347, /* BD37 (48439) */ + 3347, /* BD38 (48440) */ + 3347, /* BD39 (48441) */ + 3347, /* BD3A (48442) */ + 3347, /* BD3B (48443) */ + 3347, /* BD3C (48444) */ + 3347, /* BD3D (48445) */ + 3347, /* BD3E (48446) */ + 3347, /* BD3F (48447) */ + 3347, /* BD40 (48448) */ + 3347, /* BD41 (48449) */ + 3347, /* BD42 (48450) */ + 3347, /* BD43 (48451) */ + 3347, /* BD44 (48452) */ + 3347, /* BD45 (48453) */ + 3347, /* BD46 (48454) */ + 3347, /* BD47 (48455) */ + 3347, /* BD48 (48456) */ + 3347, /* BD49 (48457) */ + 3347, /* BD4A (48458) */ + 3347, /* BD4B (48459) */ + 3347, /* BD4C (48460) */ + 3347, /* BD4D (48461) */ + 3347, /* BD4E (48462) */ + 3347, /* BD4F (48463) */ + 3347, /* BD50 (48464) */ + 3347, /* BD51 (48465) */ + 3347, /* BD52 (48466) */ + 3347, /* BD53 (48467) */ + 3347, /* BD54 (48468) */ + 3347, /* BD55 (48469) */ + 3347, /* BD56 (48470) */ + 3347, /* BD57 (48471) */ + 3347, /* BD58 (48472) */ + 3347, /* BD59 (48473) */ + 3347, /* BD5A (48474) */ + 3347, /* BD5B (48475) */ + 3347, /* BD5C (48476) */ + 3347, /* BD5D (48477) */ + 3347, /* BD5E (48478) */ + 3347, /* BD5F (48479) */ + 3347, /* BD60 (48480) */ + 3347, /* BD61 (48481) */ + 3347, /* BD62 (48482) */ + 3347, /* BD63 (48483) */ + 3347, /* BD64 (48484) */ + 3347, /* BD65 (48485) */ + 3347, /* BD66 (48486) */ + 3347, /* BD67 (48487) */ + 3347, /* BD68 (48488) */ + 3347, /* BD69 (48489) */ + 3347, /* BD6A (48490) */ + 3347, /* BD6B (48491) */ + 3347, /* BD6C (48492) */ + 3347, /* BD6D (48493) */ + 3347, /* BD6E (48494) */ + 3347, /* BD6F (48495) */ + 3347, /* BD70 (48496) */ + 3347, /* BD71 (48497) */ + 3347, /* BD72 (48498) */ + 3347, /* BD73 (48499) */ + 3347, /* BD74 (48500) */ + 3347, /* BD75 (48501) */ + 3347, /* BD76 (48502) */ + 3347, /* BD77 (48503) */ + 3347, /* BD78 (48504) */ + 3347, /* BD79 (48505) */ + 3347, /* BD7A (48506) */ + 3347, /* BD7B (48507) */ + 3347, /* BD7C (48508) */ + 3347, /* BD7D (48509) */ + 3347, /* BD7E (48510) */ + 3347, /* BD7F (48511) */ + 3347, /* BD80 (48512) */ + 3347, /* BD81 (48513) */ + 3347, /* BD82 (48514) */ + 3347, /* BD83 (48515) */ + 3347, /* BD84 (48516) */ + 3347, /* BD85 (48517) */ + 3347, /* BD86 (48518) */ + 3347, /* BD87 (48519) */ + 3347, /* BD88 (48520) */ + 3347, /* BD89 (48521) */ + 3347, /* BD8A (48522) */ + 3347, /* BD8B (48523) */ + 3347, /* BD8C (48524) */ + 3347, /* BD8D (48525) */ + 3347, /* BD8E (48526) */ + 3347, /* BD8F (48527) */ + 3347, /* BD90 (48528) */ + 3347, /* BD91 (48529) */ + 3347, /* BD92 (48530) */ + 3347, /* BD93 (48531) */ + 3347, /* BD94 (48532) */ + 3347, /* BD95 (48533) */ + 3347, /* BD96 (48534) */ + 3347, /* BD97 (48535) */ + 3347, /* BD98 (48536) */ + 3347, /* BD99 (48537) */ + 3347, /* BD9A (48538) */ + 3347, /* BD9B (48539) */ + 3347, /* BD9C (48540) */ + 3347, /* BD9D (48541) */ + 3347, /* BD9E (48542) */ + 3347, /* BD9F (48543) */ + 3347, /* BDA0 (48544) */ + 3347, /* BDA1 (48545) */ + 3347, /* BDA2 (48546) */ + 3347, /* BDA3 (48547) */ + 3347, /* BDA4 (48548) */ + 3347, /* BDA5 (48549) */ + 3347, /* BDA6 (48550) */ + 3347, /* BDA7 (48551) */ + 3347, /* BDA8 (48552) */ + 3347, /* BDA9 (48553) */ + 3347, /* BDAA (48554) */ + 3347, /* BDAB (48555) */ + 3347, /* BDAC (48556) */ + 3347, /* BDAD (48557) */ + 3347, /* BDAE (48558) */ + 3347, /* BDAF (48559) */ + 3347, /* BDB0 (48560) */ + 3347, /* BDB1 (48561) */ + 3347, /* BDB2 (48562) */ + 3347, /* BDB3 (48563) */ + 3347, /* BDB4 (48564) */ + 3347, /* BDB5 (48565) */ + 3347, /* BDB6 (48566) */ + 3347, /* BDB7 (48567) */ + 3347, /* BDB8 (48568) */ + 3347, /* BDB9 (48569) */ + 3347, /* BDBA (48570) */ + 3347, /* BDBB (48571) */ + 3347, /* BDBC (48572) */ + 3347, /* BDBD (48573) */ + 3347, /* BDBE (48574) */ + 3347, /* BDBF (48575) */ + 3347, /* BDC0 (48576) */ + 3347, /* BDC1 (48577) */ + 3347, /* BDC2 (48578) */ + 3347, /* BDC3 (48579) */ + 3347, /* BDC4 (48580) */ + 3347, /* BDC5 (48581) */ + 3347, /* BDC6 (48582) */ + 3347, /* BDC7 (48583) */ + 3347, /* BDC8 (48584) */ + 3347, /* BDC9 (48585) */ + 3347, /* BDCA (48586) */ + 3347, /* BDCB (48587) */ + 3347, /* BDCC (48588) */ + 3347, /* BDCD (48589) */ + 3347, /* BDCE (48590) */ + 3347, /* BDCF (48591) */ + 3347, /* BDD0 (48592) */ + 3347, /* BDD1 (48593) */ + 3347, /* BDD2 (48594) */ + 3347, /* BDD3 (48595) */ + 3347, /* BDD4 (48596) */ + 3347, /* BDD5 (48597) */ + 3347, /* BDD6 (48598) */ + 3347, /* BDD7 (48599) */ + 3347, /* BDD8 (48600) */ + 3347, /* BDD9 (48601) */ + 3347, /* BDDA (48602) */ + 3347, /* BDDB (48603) */ + 3347, /* BDDC (48604) */ + 3347, /* BDDD (48605) */ + 3347, /* BDDE (48606) */ + 3347, /* BDDF (48607) */ + 3347, /* BDE0 (48608) */ + 3347, /* BDE1 (48609) */ + 3347, /* BDE2 (48610) */ + 3347, /* BDE3 (48611) */ + 3347, /* BDE4 (48612) */ + 3347, /* BDE5 (48613) */ + 3347, /* BDE6 (48614) */ + 3347, /* BDE7 (48615) */ + 3347, /* BDE8 (48616) */ + 3347, /* BDE9 (48617) */ + 3347, /* BDEA (48618) */ + 3347, /* BDEB (48619) */ + 3347, /* BDEC (48620) */ + 3347, /* BDED (48621) */ + 3347, /* BDEE (48622) */ + 3347, /* BDEF (48623) */ + 3347, /* BDF0 (48624) */ + 3347, /* BDF1 (48625) */ + 3347, /* BDF2 (48626) */ + 3347, /* BDF3 (48627) */ + 3347, /* BDF4 (48628) */ + 3347, /* BDF5 (48629) */ + 3347, /* BDF6 (48630) */ + 3347, /* BDF7 (48631) */ + 3347, /* BDF8 (48632) */ + 3347, /* BDF9 (48633) */ + 3347, /* BDFA (48634) */ + 3347, /* BDFB (48635) */ + 3347, /* BDFC (48636) */ + 3347, /* BDFD (48637) */ + 3347, /* BDFE (48638) */ + 3347, /* BDFF (48639) */ + 3347, /* BE00 (48640) */ + 3347, /* BE01 (48641) */ + 3347, /* BE02 (48642) */ + 3347, /* BE03 (48643) */ + 3347, /* BE04 (48644) */ + 3347, /* BE05 (48645) */ + 3347, /* BE06 (48646) */ + 3347, /* BE07 (48647) */ + 3347, /* BE08 (48648) */ + 3347, /* BE09 (48649) */ + 3347, /* BE0A (48650) */ + 3347, /* BE0B (48651) */ + 3347, /* BE0C (48652) */ + 3347, /* BE0D (48653) */ + 3347, /* BE0E (48654) */ + 3347, /* BE0F (48655) */ + 3347, /* BE10 (48656) */ + 3347, /* BE11 (48657) */ + 3347, /* BE12 (48658) */ + 3347, /* BE13 (48659) */ + 3347, /* BE14 (48660) */ + 3347, /* BE15 (48661) */ + 3347, /* BE16 (48662) */ + 3347, /* BE17 (48663) */ + 3347, /* BE18 (48664) */ + 3347, /* BE19 (48665) */ + 3347, /* BE1A (48666) */ + 3347, /* BE1B (48667) */ + 3347, /* BE1C (48668) */ + 3347, /* BE1D (48669) */ + 3347, /* BE1E (48670) */ + 3347, /* BE1F (48671) */ + 3347, /* BE20 (48672) */ + 3347, /* BE21 (48673) */ + 3347, /* BE22 (48674) */ + 3347, /* BE23 (48675) */ + 3347, /* BE24 (48676) */ + 3347, /* BE25 (48677) */ + 3347, /* BE26 (48678) */ + 3347, /* BE27 (48679) */ + 3347, /* BE28 (48680) */ + 3347, /* BE29 (48681) */ + 3347, /* BE2A (48682) */ + 3347, /* BE2B (48683) */ + 3347, /* BE2C (48684) */ + 3347, /* BE2D (48685) */ + 3347, /* BE2E (48686) */ + 3347, /* BE2F (48687) */ + 3347, /* BE30 (48688) */ + 3347, /* BE31 (48689) */ + 3347, /* BE32 (48690) */ + 3347, /* BE33 (48691) */ + 3347, /* BE34 (48692) */ + 3347, /* BE35 (48693) */ + 3347, /* BE36 (48694) */ + 3347, /* BE37 (48695) */ + 3347, /* BE38 (48696) */ + 3347, /* BE39 (48697) */ + 3347, /* BE3A (48698) */ + 3347, /* BE3B (48699) */ + 3347, /* BE3C (48700) */ + 3347, /* BE3D (48701) */ + 3347, /* BE3E (48702) */ + 3347, /* BE3F (48703) */ + 3347, /* BE40 (48704) */ + 3347, /* BE41 (48705) */ + 3347, /* BE42 (48706) */ + 3347, /* BE43 (48707) */ + 3347, /* BE44 (48708) */ + 3347, /* BE45 (48709) */ + 3347, /* BE46 (48710) */ + 3347, /* BE47 (48711) */ + 3347, /* BE48 (48712) */ + 3347, /* BE49 (48713) */ + 3347, /* BE4A (48714) */ + 3347, /* BE4B (48715) */ + 3347, /* BE4C (48716) */ + 3347, /* BE4D (48717) */ + 3347, /* BE4E (48718) */ + 3347, /* BE4F (48719) */ + 3347, /* BE50 (48720) */ + 3347, /* BE51 (48721) */ + 3347, /* BE52 (48722) */ + 3347, /* BE53 (48723) */ + 3347, /* BE54 (48724) */ + 3347, /* BE55 (48725) */ + 3347, /* BE56 (48726) */ + 3347, /* BE57 (48727) */ + 3347, /* BE58 (48728) */ + 3347, /* BE59 (48729) */ + 3347, /* BE5A (48730) */ + 3347, /* BE5B (48731) */ + 3347, /* BE5C (48732) */ + 3347, /* BE5D (48733) */ + 3347, /* BE5E (48734) */ + 3347, /* BE5F (48735) */ + 3347, /* BE60 (48736) */ + 3347, /* BE61 (48737) */ + 3347, /* BE62 (48738) */ + 3347, /* BE63 (48739) */ + 3347, /* BE64 (48740) */ + 3347, /* BE65 (48741) */ + 3347, /* BE66 (48742) */ + 3347, /* BE67 (48743) */ + 3347, /* BE68 (48744) */ + 3347, /* BE69 (48745) */ + 3347, /* BE6A (48746) */ + 3347, /* BE6B (48747) */ + 3347, /* BE6C (48748) */ + 3347, /* BE6D (48749) */ + 3347, /* BE6E (48750) */ + 3347, /* BE6F (48751) */ + 3347, /* BE70 (48752) */ + 3347, /* BE71 (48753) */ + 3347, /* BE72 (48754) */ + 3347, /* BE73 (48755) */ + 3347, /* BE74 (48756) */ + 3347, /* BE75 (48757) */ + 3347, /* BE76 (48758) */ + 3347, /* BE77 (48759) */ + 3347, /* BE78 (48760) */ + 3347, /* BE79 (48761) */ + 3347, /* BE7A (48762) */ + 3347, /* BE7B (48763) */ + 3347, /* BE7C (48764) */ + 3347, /* BE7D (48765) */ + 3347, /* BE7E (48766) */ + 3347, /* BE7F (48767) */ + 3347, /* BE80 (48768) */ + 3347, /* BE81 (48769) */ + 3347, /* BE82 (48770) */ + 3347, /* BE83 (48771) */ + 3347, /* BE84 (48772) */ + 3347, /* BE85 (48773) */ + 3347, /* BE86 (48774) */ + 3347, /* BE87 (48775) */ + 3347, /* BE88 (48776) */ + 3347, /* BE89 (48777) */ + 3347, /* BE8A (48778) */ + 3347, /* BE8B (48779) */ + 3347, /* BE8C (48780) */ + 3347, /* BE8D (48781) */ + 3347, /* BE8E (48782) */ + 3347, /* BE8F (48783) */ + 3347, /* BE90 (48784) */ + 3347, /* BE91 (48785) */ + 3347, /* BE92 (48786) */ + 3347, /* BE93 (48787) */ + 3347, /* BE94 (48788) */ + 3347, /* BE95 (48789) */ + 3347, /* BE96 (48790) */ + 3347, /* BE97 (48791) */ + 3347, /* BE98 (48792) */ + 3347, /* BE99 (48793) */ + 3347, /* BE9A (48794) */ + 3347, /* BE9B (48795) */ + 3347, /* BE9C (48796) */ + 3347, /* BE9D (48797) */ + 3347, /* BE9E (48798) */ + 3347, /* BE9F (48799) */ + 3347, /* BEA0 (48800) */ + 3347, /* BEA1 (48801) */ + 3347, /* BEA2 (48802) */ + 3347, /* BEA3 (48803) */ + 3347, /* BEA4 (48804) */ + 3347, /* BEA5 (48805) */ + 3347, /* BEA6 (48806) */ + 3347, /* BEA7 (48807) */ + 3347, /* BEA8 (48808) */ + 3347, /* BEA9 (48809) */ + 3347, /* BEAA (48810) */ + 3347, /* BEAB (48811) */ + 3347, /* BEAC (48812) */ + 3347, /* BEAD (48813) */ + 3347, /* BEAE (48814) */ + 3347, /* BEAF (48815) */ + 3347, /* BEB0 (48816) */ + 3347, /* BEB1 (48817) */ + 3347, /* BEB2 (48818) */ + 3347, /* BEB3 (48819) */ + 3347, /* BEB4 (48820) */ + 3347, /* BEB5 (48821) */ + 3347, /* BEB6 (48822) */ + 3347, /* BEB7 (48823) */ + 3347, /* BEB8 (48824) */ + 3347, /* BEB9 (48825) */ + 3347, /* BEBA (48826) */ + 3347, /* BEBB (48827) */ + 3347, /* BEBC (48828) */ + 3347, /* BEBD (48829) */ + 3347, /* BEBE (48830) */ + 3347, /* BEBF (48831) */ + 3347, /* BEC0 (48832) */ + 3347, /* BEC1 (48833) */ + 3347, /* BEC2 (48834) */ + 3347, /* BEC3 (48835) */ + 3347, /* BEC4 (48836) */ + 3347, /* BEC5 (48837) */ + 3347, /* BEC6 (48838) */ + 3347, /* BEC7 (48839) */ + 3347, /* BEC8 (48840) */ + 3347, /* BEC9 (48841) */ + 3347, /* BECA (48842) */ + 3347, /* BECB (48843) */ + 3347, /* BECC (48844) */ + 3347, /* BECD (48845) */ + 3347, /* BECE (48846) */ + 3347, /* BECF (48847) */ + 3347, /* BED0 (48848) */ + 3347, /* BED1 (48849) */ + 3347, /* BED2 (48850) */ + 3347, /* BED3 (48851) */ + 3347, /* BED4 (48852) */ + 3347, /* BED5 (48853) */ + 3347, /* BED6 (48854) */ + 3347, /* BED7 (48855) */ + 3347, /* BED8 (48856) */ + 3347, /* BED9 (48857) */ + 3347, /* BEDA (48858) */ + 3347, /* BEDB (48859) */ + 3347, /* BEDC (48860) */ + 3347, /* BEDD (48861) */ + 3347, /* BEDE (48862) */ + 3347, /* BEDF (48863) */ + 3347, /* BEE0 (48864) */ + 3347, /* BEE1 (48865) */ + 3347, /* BEE2 (48866) */ + 3347, /* BEE3 (48867) */ + 3347, /* BEE4 (48868) */ + 3347, /* BEE5 (48869) */ + 3347, /* BEE6 (48870) */ + 3347, /* BEE7 (48871) */ + 3347, /* BEE8 (48872) */ + 3347, /* BEE9 (48873) */ + 3347, /* BEEA (48874) */ + 3347, /* BEEB (48875) */ + 3347, /* BEEC (48876) */ + 3347, /* BEED (48877) */ + 3347, /* BEEE (48878) */ + 3347, /* BEEF (48879) */ + 3347, /* BEF0 (48880) */ + 3347, /* BEF1 (48881) */ + 3347, /* BEF2 (48882) */ + 3347, /* BEF3 (48883) */ + 3347, /* BEF4 (48884) */ + 3347, /* BEF5 (48885) */ + 3347, /* BEF6 (48886) */ + 3347, /* BEF7 (48887) */ + 3347, /* BEF8 (48888) */ + 3347, /* BEF9 (48889) */ + 3347, /* BEFA (48890) */ + 3347, /* BEFB (48891) */ + 3347, /* BEFC (48892) */ + 3347, /* BEFD (48893) */ + 3347, /* BEFE (48894) */ + 3347, /* BEFF (48895) */ + 3347, /* BF00 (48896) */ + 3347, /* BF01 (48897) */ + 3347, /* BF02 (48898) */ + 3347, /* BF03 (48899) */ + 3347, /* BF04 (48900) */ + 3347, /* BF05 (48901) */ + 3347, /* BF06 (48902) */ + 3347, /* BF07 (48903) */ + 3347, /* BF08 (48904) */ + 3347, /* BF09 (48905) */ + 3347, /* BF0A (48906) */ + 3347, /* BF0B (48907) */ + 3347, /* BF0C (48908) */ + 3347, /* BF0D (48909) */ + 3347, /* BF0E (48910) */ + 3347, /* BF0F (48911) */ + 3347, /* BF10 (48912) */ + 3347, /* BF11 (48913) */ + 3347, /* BF12 (48914) */ + 3347, /* BF13 (48915) */ + 3347, /* BF14 (48916) */ + 3347, /* BF15 (48917) */ + 3347, /* BF16 (48918) */ + 3347, /* BF17 (48919) */ + 3347, /* BF18 (48920) */ + 3347, /* BF19 (48921) */ + 3347, /* BF1A (48922) */ + 3347, /* BF1B (48923) */ + 3347, /* BF1C (48924) */ + 3347, /* BF1D (48925) */ + 3347, /* BF1E (48926) */ + 3347, /* BF1F (48927) */ + 3347, /* BF20 (48928) */ + 3347, /* BF21 (48929) */ + 3347, /* BF22 (48930) */ + 3347, /* BF23 (48931) */ + 3347, /* BF24 (48932) */ + 3347, /* BF25 (48933) */ + 3347, /* BF26 (48934) */ + 3347, /* BF27 (48935) */ + 3347, /* BF28 (48936) */ + 3347, /* BF29 (48937) */ + 3347, /* BF2A (48938) */ + 3347, /* BF2B (48939) */ + 3347, /* BF2C (48940) */ + 3347, /* BF2D (48941) */ + 3347, /* BF2E (48942) */ + 3347, /* BF2F (48943) */ + 3347, /* BF30 (48944) */ + 3347, /* BF31 (48945) */ + 3347, /* BF32 (48946) */ + 3347, /* BF33 (48947) */ + 3347, /* BF34 (48948) */ + 3347, /* BF35 (48949) */ + 3347, /* BF36 (48950) */ + 3347, /* BF37 (48951) */ + 3347, /* BF38 (48952) */ + 3347, /* BF39 (48953) */ + 3347, /* BF3A (48954) */ + 3347, /* BF3B (48955) */ + 3347, /* BF3C (48956) */ + 3347, /* BF3D (48957) */ + 3347, /* BF3E (48958) */ + 3347, /* BF3F (48959) */ + 3347, /* BF40 (48960) */ + 3347, /* BF41 (48961) */ + 3347, /* BF42 (48962) */ + 3347, /* BF43 (48963) */ + 3347, /* BF44 (48964) */ + 3347, /* BF45 (48965) */ + 3347, /* BF46 (48966) */ + 3347, /* BF47 (48967) */ + 3347, /* BF48 (48968) */ + 3347, /* BF49 (48969) */ + 3347, /* BF4A (48970) */ + 3347, /* BF4B (48971) */ + 3347, /* BF4C (48972) */ + 3347, /* BF4D (48973) */ + 3347, /* BF4E (48974) */ + 3347, /* BF4F (48975) */ + 3347, /* BF50 (48976) */ + 3347, /* BF51 (48977) */ + 3347, /* BF52 (48978) */ + 3347, /* BF53 (48979) */ + 3347, /* BF54 (48980) */ + 3347, /* BF55 (48981) */ + 3347, /* BF56 (48982) */ + 3347, /* BF57 (48983) */ + 3347, /* BF58 (48984) */ + 3347, /* BF59 (48985) */ + 3347, /* BF5A (48986) */ + 3347, /* BF5B (48987) */ + 3347, /* BF5C (48988) */ + 3347, /* BF5D (48989) */ + 3347, /* BF5E (48990) */ + 3347, /* BF5F (48991) */ + 3347, /* BF60 (48992) */ + 3347, /* BF61 (48993) */ + 3347, /* BF62 (48994) */ + 3347, /* BF63 (48995) */ + 3347, /* BF64 (48996) */ + 3347, /* BF65 (48997) */ + 3347, /* BF66 (48998) */ + 3347, /* BF67 (48999) */ + 3347, /* BF68 (49000) */ + 3347, /* BF69 (49001) */ + 3347, /* BF6A (49002) */ + 3347, /* BF6B (49003) */ + 3347, /* BF6C (49004) */ + 3347, /* BF6D (49005) */ + 3347, /* BF6E (49006) */ + 3347, /* BF6F (49007) */ + 3347, /* BF70 (49008) */ + 3347, /* BF71 (49009) */ + 3347, /* BF72 (49010) */ + 3347, /* BF73 (49011) */ + 3347, /* BF74 (49012) */ + 3347, /* BF75 (49013) */ + 3347, /* BF76 (49014) */ + 3347, /* BF77 (49015) */ + 3347, /* BF78 (49016) */ + 3347, /* BF79 (49017) */ + 3347, /* BF7A (49018) */ + 3347, /* BF7B (49019) */ + 3347, /* BF7C (49020) */ + 3347, /* BF7D (49021) */ + 3347, /* BF7E (49022) */ + 3347, /* BF7F (49023) */ + 3347, /* BF80 (49024) */ + 3347, /* BF81 (49025) */ + 3347, /* BF82 (49026) */ + 3347, /* BF83 (49027) */ + 3347, /* BF84 (49028) */ + 3347, /* BF85 (49029) */ + 3347, /* BF86 (49030) */ + 3347, /* BF87 (49031) */ + 3347, /* BF88 (49032) */ + 3347, /* BF89 (49033) */ + 3347, /* BF8A (49034) */ + 3347, /* BF8B (49035) */ + 3347, /* BF8C (49036) */ + 3347, /* BF8D (49037) */ + 3347, /* BF8E (49038) */ + 3347, /* BF8F (49039) */ + 3347, /* BF90 (49040) */ + 3347, /* BF91 (49041) */ + 3347, /* BF92 (49042) */ + 3347, /* BF93 (49043) */ + 3347, /* BF94 (49044) */ + 3347, /* BF95 (49045) */ + 3347, /* BF96 (49046) */ + 3347, /* BF97 (49047) */ + 3347, /* BF98 (49048) */ + 3347, /* BF99 (49049) */ + 3347, /* BF9A (49050) */ + 3347, /* BF9B (49051) */ + 3347, /* BF9C (49052) */ + 3347, /* BF9D (49053) */ + 3347, /* BF9E (49054) */ + 3347, /* BF9F (49055) */ + 3347, /* BFA0 (49056) */ + 3347, /* BFA1 (49057) */ + 3347, /* BFA2 (49058) */ + 3347, /* BFA3 (49059) */ + 3347, /* BFA4 (49060) */ + 3347, /* BFA5 (49061) */ + 3347, /* BFA6 (49062) */ + 3347, /* BFA7 (49063) */ + 3347, /* BFA8 (49064) */ + 3347, /* BFA9 (49065) */ + 3347, /* BFAA (49066) */ + 3347, /* BFAB (49067) */ + 3347, /* BFAC (49068) */ + 3347, /* BFAD (49069) */ + 3347, /* BFAE (49070) */ + 3347, /* BFAF (49071) */ + 3347, /* BFB0 (49072) */ + 3347, /* BFB1 (49073) */ + 3347, /* BFB2 (49074) */ + 3347, /* BFB3 (49075) */ + 3347, /* BFB4 (49076) */ + 3347, /* BFB5 (49077) */ + 3347, /* BFB6 (49078) */ + 3347, /* BFB7 (49079) */ + 3347, /* BFB8 (49080) */ + 3347, /* BFB9 (49081) */ + 3347, /* BFBA (49082) */ + 3347, /* BFBB (49083) */ + 3347, /* BFBC (49084) */ + 3347, /* BFBD (49085) */ + 3347, /* BFBE (49086) */ + 3347, /* BFBF (49087) */ + 3347, /* BFC0 (49088) */ + 3347, /* BFC1 (49089) */ + 3347, /* BFC2 (49090) */ + 3347, /* BFC3 (49091) */ + 3347, /* BFC4 (49092) */ + 3347, /* BFC5 (49093) */ + 3347, /* BFC6 (49094) */ + 3347, /* BFC7 (49095) */ + 3347, /* BFC8 (49096) */ + 3347, /* BFC9 (49097) */ + 3347, /* BFCA (49098) */ + 3347, /* BFCB (49099) */ + 3347, /* BFCC (49100) */ + 3347, /* BFCD (49101) */ + 3347, /* BFCE (49102) */ + 3347, /* BFCF (49103) */ + 3347, /* BFD0 (49104) */ + 3347, /* BFD1 (49105) */ + 3347, /* BFD2 (49106) */ + 3347, /* BFD3 (49107) */ + 3347, /* BFD4 (49108) */ + 3347, /* BFD5 (49109) */ + 3347, /* BFD6 (49110) */ + 3347, /* BFD7 (49111) */ + 3347, /* BFD8 (49112) */ + 3347, /* BFD9 (49113) */ + 3347, /* BFDA (49114) */ + 3347, /* BFDB (49115) */ + 3347, /* BFDC (49116) */ + 3347, /* BFDD (49117) */ + 3347, /* BFDE (49118) */ + 3347, /* BFDF (49119) */ + 3347, /* BFE0 (49120) */ + 3347, /* BFE1 (49121) */ + 3347, /* BFE2 (49122) */ + 3347, /* BFE3 (49123) */ + 3347, /* BFE4 (49124) */ + 3347, /* BFE5 (49125) */ + 3347, /* BFE6 (49126) */ + 3347, /* BFE7 (49127) */ + 3347, /* BFE8 (49128) */ + 3347, /* BFE9 (49129) */ + 3347, /* BFEA (49130) */ + 3347, /* BFEB (49131) */ + 3347, /* BFEC (49132) */ + 3347, /* BFED (49133) */ + 3347, /* BFEE (49134) */ + 3347, /* BFEF (49135) */ + 3347, /* BFF0 (49136) */ + 3347, /* BFF1 (49137) */ + 3347, /* BFF2 (49138) */ + 3347, /* BFF3 (49139) */ + 3347, /* BFF4 (49140) */ + 3347, /* BFF5 (49141) */ + 3347, /* BFF6 (49142) */ + 3347, /* BFF7 (49143) */ + 3347, /* BFF8 (49144) */ + 3347, /* BFF9 (49145) */ + 3347, /* BFFA (49146) */ + 3347, /* BFFB (49147) */ + 3347, /* BFFC (49148) */ + 3347, /* BFFD (49149) */ + 3347, /* BFFE (49150) */ + 3347, /* BFFF (49151) */ + 3347, /* C000 (49152) */ + 3347, /* C001 (49153) */ + 3347, /* C002 (49154) */ + 3347, /* C003 (49155) */ + 3347, /* C004 (49156) */ + 3347, /* C005 (49157) */ + 3347, /* C006 (49158) */ + 3347, /* C007 (49159) */ + 3347, /* C008 (49160) */ + 3347, /* C009 (49161) */ + 3347, /* C00A (49162) */ + 3347, /* C00B (49163) */ + 3347, /* C00C (49164) */ + 3347, /* C00D (49165) */ + 3347, /* C00E (49166) */ + 3347, /* C00F (49167) */ + 3347, /* C010 (49168) */ + 3347, /* C011 (49169) */ + 3347, /* C012 (49170) */ + 3347, /* C013 (49171) */ + 3347, /* C014 (49172) */ + 3347, /* C015 (49173) */ + 3347, /* C016 (49174) */ + 3347, /* C017 (49175) */ + 3347, /* C018 (49176) */ + 3347, /* C019 (49177) */ + 3347, /* C01A (49178) */ + 3347, /* C01B (49179) */ + 3347, /* C01C (49180) */ + 3347, /* C01D (49181) */ + 3347, /* C01E (49182) */ + 3347, /* C01F (49183) */ + 3347, /* C020 (49184) */ + 3347, /* C021 (49185) */ + 3347, /* C022 (49186) */ + 3347, /* C023 (49187) */ + 3347, /* C024 (49188) */ + 3347, /* C025 (49189) */ + 3347, /* C026 (49190) */ + 3347, /* C027 (49191) */ + 3347, /* C028 (49192) */ + 3347, /* C029 (49193) */ + 3347, /* C02A (49194) */ + 3347, /* C02B (49195) */ + 3347, /* C02C (49196) */ + 3347, /* C02D (49197) */ + 3347, /* C02E (49198) */ + 3347, /* C02F (49199) */ + 3347, /* C030 (49200) */ + 3347, /* C031 (49201) */ + 3347, /* C032 (49202) */ + 3347, /* C033 (49203) */ + 3347, /* C034 (49204) */ + 3347, /* C035 (49205) */ + 3347, /* C036 (49206) */ + 3347, /* C037 (49207) */ + 3347, /* C038 (49208) */ + 3347, /* C039 (49209) */ + 3347, /* C03A (49210) */ + 3347, /* C03B (49211) */ + 3347, /* C03C (49212) */ + 3347, /* C03D (49213) */ + 3347, /* C03E (49214) */ + 3347, /* C03F (49215) */ + 3347, /* C040 (49216) */ + 3347, /* C041 (49217) */ + 3347, /* C042 (49218) */ + 3347, /* C043 (49219) */ + 3347, /* C044 (49220) */ + 3347, /* C045 (49221) */ + 3347, /* C046 (49222) */ + 3347, /* C047 (49223) */ + 3347, /* C048 (49224) */ + 3347, /* C049 (49225) */ + 3347, /* C04A (49226) */ + 3347, /* C04B (49227) */ + 3347, /* C04C (49228) */ + 3347, /* C04D (49229) */ + 3347, /* C04E (49230) */ + 3347, /* C04F (49231) */ + 3347, /* C050 (49232) */ + 3347, /* C051 (49233) */ + 3347, /* C052 (49234) */ + 3347, /* C053 (49235) */ + 3347, /* C054 (49236) */ + 3347, /* C055 (49237) */ + 3347, /* C056 (49238) */ + 3347, /* C057 (49239) */ + 3347, /* C058 (49240) */ + 3347, /* C059 (49241) */ + 3347, /* C05A (49242) */ + 3347, /* C05B (49243) */ + 3347, /* C05C (49244) */ + 3347, /* C05D (49245) */ + 3347, /* C05E (49246) */ + 3347, /* C05F (49247) */ + 3347, /* C060 (49248) */ + 3347, /* C061 (49249) */ + 3347, /* C062 (49250) */ + 3347, /* C063 (49251) */ + 3347, /* C064 (49252) */ + 3347, /* C065 (49253) */ + 3347, /* C066 (49254) */ + 3347, /* C067 (49255) */ + 3347, /* C068 (49256) */ + 3347, /* C069 (49257) */ + 3347, /* C06A (49258) */ + 3347, /* C06B (49259) */ + 3347, /* C06C (49260) */ + 3347, /* C06D (49261) */ + 3347, /* C06E (49262) */ + 3347, /* C06F (49263) */ + 3347, /* C070 (49264) */ + 3347, /* C071 (49265) */ + 3347, /* C072 (49266) */ + 3347, /* C073 (49267) */ + 3347, /* C074 (49268) */ + 3347, /* C075 (49269) */ + 3347, /* C076 (49270) */ + 3347, /* C077 (49271) */ + 3347, /* C078 (49272) */ + 3347, /* C079 (49273) */ + 3347, /* C07A (49274) */ + 3347, /* C07B (49275) */ + 3347, /* C07C (49276) */ + 3347, /* C07D (49277) */ + 3347, /* C07E (49278) */ + 3347, /* C07F (49279) */ + 3347, /* C080 (49280) */ + 3347, /* C081 (49281) */ + 3347, /* C082 (49282) */ + 3347, /* C083 (49283) */ + 3347, /* C084 (49284) */ + 3347, /* C085 (49285) */ + 3347, /* C086 (49286) */ + 3347, /* C087 (49287) */ + 3347, /* C088 (49288) */ + 3347, /* C089 (49289) */ + 3347, /* C08A (49290) */ + 3347, /* C08B (49291) */ + 3347, /* C08C (49292) */ + 3347, /* C08D (49293) */ + 3347, /* C08E (49294) */ + 3347, /* C08F (49295) */ + 3347, /* C090 (49296) */ + 3347, /* C091 (49297) */ + 3347, /* C092 (49298) */ + 3347, /* C093 (49299) */ + 3347, /* C094 (49300) */ + 3347, /* C095 (49301) */ + 3347, /* C096 (49302) */ + 3347, /* C097 (49303) */ + 3347, /* C098 (49304) */ + 3347, /* C099 (49305) */ + 3347, /* C09A (49306) */ + 3347, /* C09B (49307) */ + 3347, /* C09C (49308) */ + 3347, /* C09D (49309) */ + 3347, /* C09E (49310) */ + 3347, /* C09F (49311) */ + 3347, /* C0A0 (49312) */ + 3347, /* C0A1 (49313) */ + 3347, /* C0A2 (49314) */ + 3347, /* C0A3 (49315) */ + 3347, /* C0A4 (49316) */ + 3347, /* C0A5 (49317) */ + 3347, /* C0A6 (49318) */ + 3347, /* C0A7 (49319) */ + 3347, /* C0A8 (49320) */ + 3347, /* C0A9 (49321) */ + 3347, /* C0AA (49322) */ + 3347, /* C0AB (49323) */ + 3347, /* C0AC (49324) */ + 3347, /* C0AD (49325) */ + 3347, /* C0AE (49326) */ + 3347, /* C0AF (49327) */ + 3347, /* C0B0 (49328) */ + 3347, /* C0B1 (49329) */ + 3347, /* C0B2 (49330) */ + 3347, /* C0B3 (49331) */ + 3347, /* C0B4 (49332) */ + 3347, /* C0B5 (49333) */ + 3347, /* C0B6 (49334) */ + 3347, /* C0B7 (49335) */ + 3347, /* C0B8 (49336) */ + 3347, /* C0B9 (49337) */ + 3347, /* C0BA (49338) */ + 3347, /* C0BB (49339) */ + 3347, /* C0BC (49340) */ + 3347, /* C0BD (49341) */ + 3347, /* C0BE (49342) */ + 3347, /* C0BF (49343) */ + 3347, /* C0C0 (49344) */ + 3347, /* C0C1 (49345) */ + 3347, /* C0C2 (49346) */ + 3347, /* C0C3 (49347) */ + 3347, /* C0C4 (49348) */ + 3347, /* C0C5 (49349) */ + 3347, /* C0C6 (49350) */ + 3347, /* C0C7 (49351) */ + 3347, /* C0C8 (49352) */ + 3347, /* C0C9 (49353) */ + 3347, /* C0CA (49354) */ + 3347, /* C0CB (49355) */ + 3347, /* C0CC (49356) */ + 3347, /* C0CD (49357) */ + 3347, /* C0CE (49358) */ + 3347, /* C0CF (49359) */ + 3347, /* C0D0 (49360) */ + 3347, /* C0D1 (49361) */ + 3347, /* C0D2 (49362) */ + 3347, /* C0D3 (49363) */ + 3347, /* C0D4 (49364) */ + 3347, /* C0D5 (49365) */ + 3347, /* C0D6 (49366) */ + 3347, /* C0D7 (49367) */ + 3347, /* C0D8 (49368) */ + 3347, /* C0D9 (49369) */ + 3347, /* C0DA (49370) */ + 3347, /* C0DB (49371) */ + 3347, /* C0DC (49372) */ + 3347, /* C0DD (49373) */ + 3347, /* C0DE (49374) */ + 3347, /* C0DF (49375) */ + 3347, /* C0E0 (49376) */ + 3347, /* C0E1 (49377) */ + 3347, /* C0E2 (49378) */ + 3347, /* C0E3 (49379) */ + 3347, /* C0E4 (49380) */ + 3347, /* C0E5 (49381) */ + 3347, /* C0E6 (49382) */ + 3347, /* C0E7 (49383) */ + 3347, /* C0E8 (49384) */ + 3347, /* C0E9 (49385) */ + 3347, /* C0EA (49386) */ + 3347, /* C0EB (49387) */ + 3347, /* C0EC (49388) */ + 3347, /* C0ED (49389) */ + 3347, /* C0EE (49390) */ + 3347, /* C0EF (49391) */ + 3347, /* C0F0 (49392) */ + 3347, /* C0F1 (49393) */ + 3347, /* C0F2 (49394) */ + 3347, /* C0F3 (49395) */ + 3347, /* C0F4 (49396) */ + 3347, /* C0F5 (49397) */ + 3347, /* C0F6 (49398) */ + 3347, /* C0F7 (49399) */ + 3347, /* C0F8 (49400) */ + 3347, /* C0F9 (49401) */ + 3347, /* C0FA (49402) */ + 3347, /* C0FB (49403) */ + 3347, /* C0FC (49404) */ + 3347, /* C0FD (49405) */ + 3347, /* C0FE (49406) */ + 3347, /* C0FF (49407) */ + 3347, /* C100 (49408) */ + 3347, /* C101 (49409) */ + 3347, /* C102 (49410) */ + 3347, /* C103 (49411) */ + 3347, /* C104 (49412) */ + 3347, /* C105 (49413) */ + 3347, /* C106 (49414) */ + 3347, /* C107 (49415) */ + 3347, /* C108 (49416) */ + 3347, /* C109 (49417) */ + 3347, /* C10A (49418) */ + 3347, /* C10B (49419) */ + 3347, /* C10C (49420) */ + 3347, /* C10D (49421) */ + 3347, /* C10E (49422) */ + 3347, /* C10F (49423) */ + 3347, /* C110 (49424) */ + 3347, /* C111 (49425) */ + 3347, /* C112 (49426) */ + 3347, /* C113 (49427) */ + 3347, /* C114 (49428) */ + 3347, /* C115 (49429) */ + 3347, /* C116 (49430) */ + 3347, /* C117 (49431) */ + 3347, /* C118 (49432) */ + 3347, /* C119 (49433) */ + 3347, /* C11A (49434) */ + 3347, /* C11B (49435) */ + 3347, /* C11C (49436) */ + 3347, /* C11D (49437) */ + 3347, /* C11E (49438) */ + 3347, /* C11F (49439) */ + 3347, /* C120 (49440) */ + 3347, /* C121 (49441) */ + 3347, /* C122 (49442) */ + 3347, /* C123 (49443) */ + 3347, /* C124 (49444) */ + 3347, /* C125 (49445) */ + 3347, /* C126 (49446) */ + 3347, /* C127 (49447) */ + 3347, /* C128 (49448) */ + 3347, /* C129 (49449) */ + 3347, /* C12A (49450) */ + 3347, /* C12B (49451) */ + 3347, /* C12C (49452) */ + 3347, /* C12D (49453) */ + 3347, /* C12E (49454) */ + 3347, /* C12F (49455) */ + 3347, /* C130 (49456) */ + 3347, /* C131 (49457) */ + 3347, /* C132 (49458) */ + 3347, /* C133 (49459) */ + 3347, /* C134 (49460) */ + 3347, /* C135 (49461) */ + 3347, /* C136 (49462) */ + 3347, /* C137 (49463) */ + 3347, /* C138 (49464) */ + 3347, /* C139 (49465) */ + 3347, /* C13A (49466) */ + 3347, /* C13B (49467) */ + 3347, /* C13C (49468) */ + 3347, /* C13D (49469) */ + 3347, /* C13E (49470) */ + 3347, /* C13F (49471) */ + 3347, /* C140 (49472) */ + 3347, /* C141 (49473) */ + 3347, /* C142 (49474) */ + 3347, /* C143 (49475) */ + 3347, /* C144 (49476) */ + 3347, /* C145 (49477) */ + 3347, /* C146 (49478) */ + 3347, /* C147 (49479) */ + 3347, /* C148 (49480) */ + 3347, /* C149 (49481) */ + 3347, /* C14A (49482) */ + 3347, /* C14B (49483) */ + 3347, /* C14C (49484) */ + 3347, /* C14D (49485) */ + 3347, /* C14E (49486) */ + 3347, /* C14F (49487) */ + 3347, /* C150 (49488) */ + 3347, /* C151 (49489) */ + 3347, /* C152 (49490) */ + 3347, /* C153 (49491) */ + 3347, /* C154 (49492) */ + 3347, /* C155 (49493) */ + 3347, /* C156 (49494) */ + 3347, /* C157 (49495) */ + 3347, /* C158 (49496) */ + 3347, /* C159 (49497) */ + 3347, /* C15A (49498) */ + 3347, /* C15B (49499) */ + 3347, /* C15C (49500) */ + 3347, /* C15D (49501) */ + 3347, /* C15E (49502) */ + 3347, /* C15F (49503) */ + 3347, /* C160 (49504) */ + 3347, /* C161 (49505) */ + 3347, /* C162 (49506) */ + 3347, /* C163 (49507) */ + 3347, /* C164 (49508) */ + 3347, /* C165 (49509) */ + 3347, /* C166 (49510) */ + 3347, /* C167 (49511) */ + 3347, /* C168 (49512) */ + 3347, /* C169 (49513) */ + 3347, /* C16A (49514) */ + 3347, /* C16B (49515) */ + 3347, /* C16C (49516) */ + 3347, /* C16D (49517) */ + 3347, /* C16E (49518) */ + 3347, /* C16F (49519) */ + 3347, /* C170 (49520) */ + 3347, /* C171 (49521) */ + 3347, /* C172 (49522) */ + 3347, /* C173 (49523) */ + 3347, /* C174 (49524) */ + 3347, /* C175 (49525) */ + 3347, /* C176 (49526) */ + 3347, /* C177 (49527) */ + 3347, /* C178 (49528) */ + 3347, /* C179 (49529) */ + 3347, /* C17A (49530) */ + 3347, /* C17B (49531) */ + 3347, /* C17C (49532) */ + 3347, /* C17D (49533) */ + 3347, /* C17E (49534) */ + 3347, /* C17F (49535) */ + 3347, /* C180 (49536) */ + 3347, /* C181 (49537) */ + 3347, /* C182 (49538) */ + 3347, /* C183 (49539) */ + 3347, /* C184 (49540) */ + 3347, /* C185 (49541) */ + 3347, /* C186 (49542) */ + 3347, /* C187 (49543) */ + 3347, /* C188 (49544) */ + 3347, /* C189 (49545) */ + 3347, /* C18A (49546) */ + 3347, /* C18B (49547) */ + 3347, /* C18C (49548) */ + 3347, /* C18D (49549) */ + 3347, /* C18E (49550) */ + 3347, /* C18F (49551) */ + 3347, /* C190 (49552) */ + 3347, /* C191 (49553) */ + 3347, /* C192 (49554) */ + 3347, /* C193 (49555) */ + 3347, /* C194 (49556) */ + 3347, /* C195 (49557) */ + 3347, /* C196 (49558) */ + 3347, /* C197 (49559) */ + 3347, /* C198 (49560) */ + 3347, /* C199 (49561) */ + 3347, /* C19A (49562) */ + 3347, /* C19B (49563) */ + 3347, /* C19C (49564) */ + 3347, /* C19D (49565) */ + 3347, /* C19E (49566) */ + 3347, /* C19F (49567) */ + 3347, /* C1A0 (49568) */ + 3347, /* C1A1 (49569) */ + 3347, /* C1A2 (49570) */ + 3347, /* C1A3 (49571) */ + 3347, /* C1A4 (49572) */ + 3347, /* C1A5 (49573) */ + 3347, /* C1A6 (49574) */ + 3347, /* C1A7 (49575) */ + 3347, /* C1A8 (49576) */ + 3347, /* C1A9 (49577) */ + 3347, /* C1AA (49578) */ + 3347, /* C1AB (49579) */ + 3347, /* C1AC (49580) */ + 3347, /* C1AD (49581) */ + 3347, /* C1AE (49582) */ + 3347, /* C1AF (49583) */ + 3347, /* C1B0 (49584) */ + 3347, /* C1B1 (49585) */ + 3347, /* C1B2 (49586) */ + 3347, /* C1B3 (49587) */ + 3347, /* C1B4 (49588) */ + 3347, /* C1B5 (49589) */ + 3347, /* C1B6 (49590) */ + 3347, /* C1B7 (49591) */ + 3347, /* C1B8 (49592) */ + 3347, /* C1B9 (49593) */ + 3347, /* C1BA (49594) */ + 3347, /* C1BB (49595) */ + 3347, /* C1BC (49596) */ + 3347, /* C1BD (49597) */ + 3347, /* C1BE (49598) */ + 3347, /* C1BF (49599) */ + 3347, /* C1C0 (49600) */ + 3347, /* C1C1 (49601) */ + 3347, /* C1C2 (49602) */ + 3347, /* C1C3 (49603) */ + 3347, /* C1C4 (49604) */ + 3347, /* C1C5 (49605) */ + 3347, /* C1C6 (49606) */ + 3347, /* C1C7 (49607) */ + 3347, /* C1C8 (49608) */ + 3347, /* C1C9 (49609) */ + 3347, /* C1CA (49610) */ + 3347, /* C1CB (49611) */ + 3347, /* C1CC (49612) */ + 3347, /* C1CD (49613) */ + 3347, /* C1CE (49614) */ + 3347, /* C1CF (49615) */ + 3347, /* C1D0 (49616) */ + 3347, /* C1D1 (49617) */ + 3347, /* C1D2 (49618) */ + 3347, /* C1D3 (49619) */ + 3347, /* C1D4 (49620) */ + 3347, /* C1D5 (49621) */ + 3347, /* C1D6 (49622) */ + 3347, /* C1D7 (49623) */ + 3347, /* C1D8 (49624) */ + 3347, /* C1D9 (49625) */ + 3347, /* C1DA (49626) */ + 3347, /* C1DB (49627) */ + 3347, /* C1DC (49628) */ + 3347, /* C1DD (49629) */ + 3347, /* C1DE (49630) */ + 3347, /* C1DF (49631) */ + 3347, /* C1E0 (49632) */ + 3347, /* C1E1 (49633) */ + 3347, /* C1E2 (49634) */ + 3347, /* C1E3 (49635) */ + 3347, /* C1E4 (49636) */ + 3347, /* C1E5 (49637) */ + 3347, /* C1E6 (49638) */ + 3347, /* C1E7 (49639) */ + 3347, /* C1E8 (49640) */ + 3347, /* C1E9 (49641) */ + 3347, /* C1EA (49642) */ + 3347, /* C1EB (49643) */ + 3347, /* C1EC (49644) */ + 3347, /* C1ED (49645) */ + 3347, /* C1EE (49646) */ + 3347, /* C1EF (49647) */ + 3347, /* C1F0 (49648) */ + 3347, /* C1F1 (49649) */ + 3347, /* C1F2 (49650) */ + 3347, /* C1F3 (49651) */ + 3347, /* C1F4 (49652) */ + 3347, /* C1F5 (49653) */ + 3347, /* C1F6 (49654) */ + 3347, /* C1F7 (49655) */ + 3347, /* C1F8 (49656) */ + 3347, /* C1F9 (49657) */ + 3347, /* C1FA (49658) */ + 3347, /* C1FB (49659) */ + 3347, /* C1FC (49660) */ + 3347, /* C1FD (49661) */ + 3347, /* C1FE (49662) */ + 3347, /* C1FF (49663) */ + 3347, /* C200 (49664) */ + 3347, /* C201 (49665) */ + 3347, /* C202 (49666) */ + 3347, /* C203 (49667) */ + 3347, /* C204 (49668) */ + 3347, /* C205 (49669) */ + 3347, /* C206 (49670) */ + 3347, /* C207 (49671) */ + 3347, /* C208 (49672) */ + 3347, /* C209 (49673) */ + 3347, /* C20A (49674) */ + 3347, /* C20B (49675) */ + 3347, /* C20C (49676) */ + 3347, /* C20D (49677) */ + 3347, /* C20E (49678) */ + 3347, /* C20F (49679) */ + 3347, /* C210 (49680) */ + 3347, /* C211 (49681) */ + 3347, /* C212 (49682) */ + 3347, /* C213 (49683) */ + 3347, /* C214 (49684) */ + 3347, /* C215 (49685) */ + 3347, /* C216 (49686) */ + 3347, /* C217 (49687) */ + 3347, /* C218 (49688) */ + 3347, /* C219 (49689) */ + 3347, /* C21A (49690) */ + 3347, /* C21B (49691) */ + 3347, /* C21C (49692) */ + 3347, /* C21D (49693) */ + 3347, /* C21E (49694) */ + 3347, /* C21F (49695) */ + 3347, /* C220 (49696) */ + 3347, /* C221 (49697) */ + 3347, /* C222 (49698) */ + 3347, /* C223 (49699) */ + 3347, /* C224 (49700) */ + 3347, /* C225 (49701) */ + 3347, /* C226 (49702) */ + 3347, /* C227 (49703) */ + 3347, /* C228 (49704) */ + 3347, /* C229 (49705) */ + 3347, /* C22A (49706) */ + 3347, /* C22B (49707) */ + 3347, /* C22C (49708) */ + 3347, /* C22D (49709) */ + 3347, /* C22E (49710) */ + 3347, /* C22F (49711) */ + 3347, /* C230 (49712) */ + 3347, /* C231 (49713) */ + 3347, /* C232 (49714) */ + 3347, /* C233 (49715) */ + 3347, /* C234 (49716) */ + 3347, /* C235 (49717) */ + 3347, /* C236 (49718) */ + 3347, /* C237 (49719) */ + 3347, /* C238 (49720) */ + 3347, /* C239 (49721) */ + 3347, /* C23A (49722) */ + 3347, /* C23B (49723) */ + 3347, /* C23C (49724) */ + 3347, /* C23D (49725) */ + 3347, /* C23E (49726) */ + 3347, /* C23F (49727) */ + 3347, /* C240 (49728) */ + 3347, /* C241 (49729) */ + 3347, /* C242 (49730) */ + 3347, /* C243 (49731) */ + 3347, /* C244 (49732) */ + 3347, /* C245 (49733) */ + 3347, /* C246 (49734) */ + 3347, /* C247 (49735) */ + 3347, /* C248 (49736) */ + 3347, /* C249 (49737) */ + 3347, /* C24A (49738) */ + 3347, /* C24B (49739) */ + 3347, /* C24C (49740) */ + 3347, /* C24D (49741) */ + 3347, /* C24E (49742) */ + 3347, /* C24F (49743) */ + 3347, /* C250 (49744) */ + 3347, /* C251 (49745) */ + 3347, /* C252 (49746) */ + 3347, /* C253 (49747) */ + 3347, /* C254 (49748) */ + 3347, /* C255 (49749) */ + 3347, /* C256 (49750) */ + 3347, /* C257 (49751) */ + 3347, /* C258 (49752) */ + 3347, /* C259 (49753) */ + 3347, /* C25A (49754) */ + 3347, /* C25B (49755) */ + 3347, /* C25C (49756) */ + 3347, /* C25D (49757) */ + 3347, /* C25E (49758) */ + 3347, /* C25F (49759) */ + 3347, /* C260 (49760) */ + 3347, /* C261 (49761) */ + 3347, /* C262 (49762) */ + 3347, /* C263 (49763) */ + 3347, /* C264 (49764) */ + 3347, /* C265 (49765) */ + 3347, /* C266 (49766) */ + 3347, /* C267 (49767) */ + 3347, /* C268 (49768) */ + 3347, /* C269 (49769) */ + 3347, /* C26A (49770) */ + 3347, /* C26B (49771) */ + 3347, /* C26C (49772) */ + 3347, /* C26D (49773) */ + 3347, /* C26E (49774) */ + 3347, /* C26F (49775) */ + 3347, /* C270 (49776) */ + 3347, /* C271 (49777) */ + 3347, /* C272 (49778) */ + 3347, /* C273 (49779) */ + 3347, /* C274 (49780) */ + 3347, /* C275 (49781) */ + 3347, /* C276 (49782) */ + 3347, /* C277 (49783) */ + 3347, /* C278 (49784) */ + 3347, /* C279 (49785) */ + 3347, /* C27A (49786) */ + 3347, /* C27B (49787) */ + 3347, /* C27C (49788) */ + 3347, /* C27D (49789) */ + 3347, /* C27E (49790) */ + 3347, /* C27F (49791) */ + 3347, /* C280 (49792) */ + 3347, /* C281 (49793) */ + 3347, /* C282 (49794) */ + 3347, /* C283 (49795) */ + 3347, /* C284 (49796) */ + 3347, /* C285 (49797) */ + 3347, /* C286 (49798) */ + 3347, /* C287 (49799) */ + 3347, /* C288 (49800) */ + 3347, /* C289 (49801) */ + 3347, /* C28A (49802) */ + 3347, /* C28B (49803) */ + 3347, /* C28C (49804) */ + 3347, /* C28D (49805) */ + 3347, /* C28E (49806) */ + 3347, /* C28F (49807) */ + 3347, /* C290 (49808) */ + 3347, /* C291 (49809) */ + 3347, /* C292 (49810) */ + 3347, /* C293 (49811) */ + 3347, /* C294 (49812) */ + 3347, /* C295 (49813) */ + 3347, /* C296 (49814) */ + 3347, /* C297 (49815) */ + 3347, /* C298 (49816) */ + 3347, /* C299 (49817) */ + 3347, /* C29A (49818) */ + 3347, /* C29B (49819) */ + 3347, /* C29C (49820) */ + 3347, /* C29D (49821) */ + 3347, /* C29E (49822) */ + 3347, /* C29F (49823) */ + 3347, /* C2A0 (49824) */ + 3347, /* C2A1 (49825) */ + 3347, /* C2A2 (49826) */ + 3347, /* C2A3 (49827) */ + 3347, /* C2A4 (49828) */ + 3347, /* C2A5 (49829) */ + 3347, /* C2A6 (49830) */ + 3347, /* C2A7 (49831) */ + 3347, /* C2A8 (49832) */ + 3347, /* C2A9 (49833) */ + 3347, /* C2AA (49834) */ + 3347, /* C2AB (49835) */ + 3347, /* C2AC (49836) */ + 3347, /* C2AD (49837) */ + 3347, /* C2AE (49838) */ + 3347, /* C2AF (49839) */ + 3347, /* C2B0 (49840) */ + 3347, /* C2B1 (49841) */ + 3347, /* C2B2 (49842) */ + 3347, /* C2B3 (49843) */ + 3347, /* C2B4 (49844) */ + 3347, /* C2B5 (49845) */ + 3347, /* C2B6 (49846) */ + 3347, /* C2B7 (49847) */ + 3347, /* C2B8 (49848) */ + 3347, /* C2B9 (49849) */ + 3347, /* C2BA (49850) */ + 3347, /* C2BB (49851) */ + 3347, /* C2BC (49852) */ + 3347, /* C2BD (49853) */ + 3347, /* C2BE (49854) */ + 3347, /* C2BF (49855) */ + 3347, /* C2C0 (49856) */ + 3347, /* C2C1 (49857) */ + 3347, /* C2C2 (49858) */ + 3347, /* C2C3 (49859) */ + 3347, /* C2C4 (49860) */ + 3347, /* C2C5 (49861) */ + 3347, /* C2C6 (49862) */ + 3347, /* C2C7 (49863) */ + 3347, /* C2C8 (49864) */ + 3347, /* C2C9 (49865) */ + 3347, /* C2CA (49866) */ + 3347, /* C2CB (49867) */ + 3347, /* C2CC (49868) */ + 3347, /* C2CD (49869) */ + 3347, /* C2CE (49870) */ + 3347, /* C2CF (49871) */ + 3347, /* C2D0 (49872) */ + 3347, /* C2D1 (49873) */ + 3347, /* C2D2 (49874) */ + 3347, /* C2D3 (49875) */ + 3347, /* C2D4 (49876) */ + 3347, /* C2D5 (49877) */ + 3347, /* C2D6 (49878) */ + 3347, /* C2D7 (49879) */ + 3347, /* C2D8 (49880) */ + 3347, /* C2D9 (49881) */ + 3347, /* C2DA (49882) */ + 3347, /* C2DB (49883) */ + 3347, /* C2DC (49884) */ + 3347, /* C2DD (49885) */ + 3347, /* C2DE (49886) */ + 3347, /* C2DF (49887) */ + 3347, /* C2E0 (49888) */ + 3347, /* C2E1 (49889) */ + 3347, /* C2E2 (49890) */ + 3347, /* C2E3 (49891) */ + 3347, /* C2E4 (49892) */ + 3347, /* C2E5 (49893) */ + 3347, /* C2E6 (49894) */ + 3347, /* C2E7 (49895) */ + 3347, /* C2E8 (49896) */ + 3347, /* C2E9 (49897) */ + 3347, /* C2EA (49898) */ + 3347, /* C2EB (49899) */ + 3347, /* C2EC (49900) */ + 3347, /* C2ED (49901) */ + 3347, /* C2EE (49902) */ + 3347, /* C2EF (49903) */ + 3347, /* C2F0 (49904) */ + 3347, /* C2F1 (49905) */ + 3347, /* C2F2 (49906) */ + 3347, /* C2F3 (49907) */ + 3347, /* C2F4 (49908) */ + 3347, /* C2F5 (49909) */ + 3347, /* C2F6 (49910) */ + 3347, /* C2F7 (49911) */ + 3347, /* C2F8 (49912) */ + 3347, /* C2F9 (49913) */ + 3347, /* C2FA (49914) */ + 3347, /* C2FB (49915) */ + 3347, /* C2FC (49916) */ + 3347, /* C2FD (49917) */ + 3347, /* C2FE (49918) */ + 3347, /* C2FF (49919) */ + 3347, /* C300 (49920) */ + 3347, /* C301 (49921) */ + 3347, /* C302 (49922) */ + 3347, /* C303 (49923) */ + 3347, /* C304 (49924) */ + 3347, /* C305 (49925) */ + 3347, /* C306 (49926) */ + 3347, /* C307 (49927) */ + 3347, /* C308 (49928) */ + 3347, /* C309 (49929) */ + 3347, /* C30A (49930) */ + 3347, /* C30B (49931) */ + 3347, /* C30C (49932) */ + 3347, /* C30D (49933) */ + 3347, /* C30E (49934) */ + 3347, /* C30F (49935) */ + 3347, /* C310 (49936) */ + 3347, /* C311 (49937) */ + 3347, /* C312 (49938) */ + 3347, /* C313 (49939) */ + 3347, /* C314 (49940) */ + 3347, /* C315 (49941) */ + 3347, /* C316 (49942) */ + 3347, /* C317 (49943) */ + 3347, /* C318 (49944) */ + 3347, /* C319 (49945) */ + 3347, /* C31A (49946) */ + 3347, /* C31B (49947) */ + 3347, /* C31C (49948) */ + 3347, /* C31D (49949) */ + 3347, /* C31E (49950) */ + 3347, /* C31F (49951) */ + 3347, /* C320 (49952) */ + 3347, /* C321 (49953) */ + 3347, /* C322 (49954) */ + 3347, /* C323 (49955) */ + 3347, /* C324 (49956) */ + 3347, /* C325 (49957) */ + 3347, /* C326 (49958) */ + 3347, /* C327 (49959) */ + 3347, /* C328 (49960) */ + 3347, /* C329 (49961) */ + 3347, /* C32A (49962) */ + 3347, /* C32B (49963) */ + 3347, /* C32C (49964) */ + 3347, /* C32D (49965) */ + 3347, /* C32E (49966) */ + 3347, /* C32F (49967) */ + 3347, /* C330 (49968) */ + 3347, /* C331 (49969) */ + 3347, /* C332 (49970) */ + 3347, /* C333 (49971) */ + 3347, /* C334 (49972) */ + 3347, /* C335 (49973) */ + 3347, /* C336 (49974) */ + 3347, /* C337 (49975) */ + 3347, /* C338 (49976) */ + 3347, /* C339 (49977) */ + 3347, /* C33A (49978) */ + 3347, /* C33B (49979) */ + 3347, /* C33C (49980) */ + 3347, /* C33D (49981) */ + 3347, /* C33E (49982) */ + 3347, /* C33F (49983) */ + 3347, /* C340 (49984) */ + 3347, /* C341 (49985) */ + 3347, /* C342 (49986) */ + 3347, /* C343 (49987) */ + 3347, /* C344 (49988) */ + 3347, /* C345 (49989) */ + 3347, /* C346 (49990) */ + 3347, /* C347 (49991) */ + 3347, /* C348 (49992) */ + 3347, /* C349 (49993) */ + 3347, /* C34A (49994) */ + 3347, /* C34B (49995) */ + 3347, /* C34C (49996) */ + 3347, /* C34D (49997) */ + 3347, /* C34E (49998) */ + 3347, /* C34F (49999) */ + 3347, /* C350 (50000) */ + 3347, /* C351 (50001) */ + 3347, /* C352 (50002) */ + 3347, /* C353 (50003) */ + 3347, /* C354 (50004) */ + 3347, /* C355 (50005) */ + 3347, /* C356 (50006) */ + 3347, /* C357 (50007) */ + 3347, /* C358 (50008) */ + 3347, /* C359 (50009) */ + 3347, /* C35A (50010) */ + 3347, /* C35B (50011) */ + 3347, /* C35C (50012) */ + 3347, /* C35D (50013) */ + 3347, /* C35E (50014) */ + 3347, /* C35F (50015) */ + 3347, /* C360 (50016) */ + 3347, /* C361 (50017) */ + 3347, /* C362 (50018) */ + 3347, /* C363 (50019) */ + 3347, /* C364 (50020) */ + 3347, /* C365 (50021) */ + 3347, /* C366 (50022) */ + 3347, /* C367 (50023) */ + 3347, /* C368 (50024) */ + 3347, /* C369 (50025) */ + 3347, /* C36A (50026) */ + 3347, /* C36B (50027) */ + 3347, /* C36C (50028) */ + 3347, /* C36D (50029) */ + 3347, /* C36E (50030) */ + 3347, /* C36F (50031) */ + 3347, /* C370 (50032) */ + 3347, /* C371 (50033) */ + 3347, /* C372 (50034) */ + 3347, /* C373 (50035) */ + 3347, /* C374 (50036) */ + 3347, /* C375 (50037) */ + 3347, /* C376 (50038) */ + 3347, /* C377 (50039) */ + 3347, /* C378 (50040) */ + 3347, /* C379 (50041) */ + 3347, /* C37A (50042) */ + 3347, /* C37B (50043) */ + 3347, /* C37C (50044) */ + 3347, /* C37D (50045) */ + 3347, /* C37E (50046) */ + 3347, /* C37F (50047) */ + 3347, /* C380 (50048) */ + 3347, /* C381 (50049) */ + 3347, /* C382 (50050) */ + 3347, /* C383 (50051) */ + 3347, /* C384 (50052) */ + 3347, /* C385 (50053) */ + 3347, /* C386 (50054) */ + 3347, /* C387 (50055) */ + 3347, /* C388 (50056) */ + 3347, /* C389 (50057) */ + 3347, /* C38A (50058) */ + 3347, /* C38B (50059) */ + 3347, /* C38C (50060) */ + 3347, /* C38D (50061) */ + 3347, /* C38E (50062) */ + 3347, /* C38F (50063) */ + 3347, /* C390 (50064) */ + 3347, /* C391 (50065) */ + 3347, /* C392 (50066) */ + 3347, /* C393 (50067) */ + 3347, /* C394 (50068) */ + 3347, /* C395 (50069) */ + 3347, /* C396 (50070) */ + 3347, /* C397 (50071) */ + 3347, /* C398 (50072) */ + 3347, /* C399 (50073) */ + 3347, /* C39A (50074) */ + 3347, /* C39B (50075) */ + 3347, /* C39C (50076) */ + 3347, /* C39D (50077) */ + 3347, /* C39E (50078) */ + 3347, /* C39F (50079) */ + 3347, /* C3A0 (50080) */ + 3347, /* C3A1 (50081) */ + 3347, /* C3A2 (50082) */ + 3347, /* C3A3 (50083) */ + 3347, /* C3A4 (50084) */ + 3347, /* C3A5 (50085) */ + 3347, /* C3A6 (50086) */ + 3347, /* C3A7 (50087) */ + 3347, /* C3A8 (50088) */ + 3347, /* C3A9 (50089) */ + 3347, /* C3AA (50090) */ + 3347, /* C3AB (50091) */ + 3347, /* C3AC (50092) */ + 3347, /* C3AD (50093) */ + 3347, /* C3AE (50094) */ + 3347, /* C3AF (50095) */ + 3347, /* C3B0 (50096) */ + 3347, /* C3B1 (50097) */ + 3347, /* C3B2 (50098) */ + 3347, /* C3B3 (50099) */ + 3347, /* C3B4 (50100) */ + 3347, /* C3B5 (50101) */ + 3347, /* C3B6 (50102) */ + 3347, /* C3B7 (50103) */ + 3347, /* C3B8 (50104) */ + 3347, /* C3B9 (50105) */ + 3347, /* C3BA (50106) */ + 3347, /* C3BB (50107) */ + 3347, /* C3BC (50108) */ + 3347, /* C3BD (50109) */ + 3347, /* C3BE (50110) */ + 3347, /* C3BF (50111) */ + 3347, /* C3C0 (50112) */ + 3347, /* C3C1 (50113) */ + 3347, /* C3C2 (50114) */ + 3347, /* C3C3 (50115) */ + 3347, /* C3C4 (50116) */ + 3347, /* C3C5 (50117) */ + 3347, /* C3C6 (50118) */ + 3347, /* C3C7 (50119) */ + 3347, /* C3C8 (50120) */ + 3347, /* C3C9 (50121) */ + 3347, /* C3CA (50122) */ + 3347, /* C3CB (50123) */ + 3347, /* C3CC (50124) */ + 3347, /* C3CD (50125) */ + 3347, /* C3CE (50126) */ + 3347, /* C3CF (50127) */ + 3347, /* C3D0 (50128) */ + 3347, /* C3D1 (50129) */ + 3347, /* C3D2 (50130) */ + 3347, /* C3D3 (50131) */ + 3347, /* C3D4 (50132) */ + 3347, /* C3D5 (50133) */ + 3347, /* C3D6 (50134) */ + 3347, /* C3D7 (50135) */ + 3347, /* C3D8 (50136) */ + 3347, /* C3D9 (50137) */ + 3347, /* C3DA (50138) */ + 3347, /* C3DB (50139) */ + 3347, /* C3DC (50140) */ + 3347, /* C3DD (50141) */ + 3347, /* C3DE (50142) */ + 3347, /* C3DF (50143) */ + 3347, /* C3E0 (50144) */ + 3347, /* C3E1 (50145) */ + 3347, /* C3E2 (50146) */ + 3347, /* C3E3 (50147) */ + 3347, /* C3E4 (50148) */ + 3347, /* C3E5 (50149) */ + 3347, /* C3E6 (50150) */ + 3347, /* C3E7 (50151) */ + 3347, /* C3E8 (50152) */ + 3347, /* C3E9 (50153) */ + 3347, /* C3EA (50154) */ + 3347, /* C3EB (50155) */ + 3347, /* C3EC (50156) */ + 3347, /* C3ED (50157) */ + 3347, /* C3EE (50158) */ + 3347, /* C3EF (50159) */ + 3347, /* C3F0 (50160) */ + 3347, /* C3F1 (50161) */ + 3347, /* C3F2 (50162) */ + 3347, /* C3F3 (50163) */ + 3347, /* C3F4 (50164) */ + 3347, /* C3F5 (50165) */ + 3347, /* C3F6 (50166) */ + 3347, /* C3F7 (50167) */ + 3347, /* C3F8 (50168) */ + 3347, /* C3F9 (50169) */ + 3347, /* C3FA (50170) */ + 3347, /* C3FB (50171) */ + 3347, /* C3FC (50172) */ + 3347, /* C3FD (50173) */ + 3347, /* C3FE (50174) */ + 3347, /* C3FF (50175) */ + 3347, /* C400 (50176) */ + 3347, /* C401 (50177) */ + 3347, /* C402 (50178) */ + 3347, /* C403 (50179) */ + 3347, /* C404 (50180) */ + 3347, /* C405 (50181) */ + 3347, /* C406 (50182) */ + 3347, /* C407 (50183) */ + 3347, /* C408 (50184) */ + 3347, /* C409 (50185) */ + 3347, /* C40A (50186) */ + 3347, /* C40B (50187) */ + 3347, /* C40C (50188) */ + 3347, /* C40D (50189) */ + 3347, /* C40E (50190) */ + 3347, /* C40F (50191) */ + 3347, /* C410 (50192) */ + 3347, /* C411 (50193) */ + 3347, /* C412 (50194) */ + 3347, /* C413 (50195) */ + 3347, /* C414 (50196) */ + 3347, /* C415 (50197) */ + 3347, /* C416 (50198) */ + 3347, /* C417 (50199) */ + 3347, /* C418 (50200) */ + 3347, /* C419 (50201) */ + 3347, /* C41A (50202) */ + 3347, /* C41B (50203) */ + 3347, /* C41C (50204) */ + 3347, /* C41D (50205) */ + 3347, /* C41E (50206) */ + 3347, /* C41F (50207) */ + 3347, /* C420 (50208) */ + 3347, /* C421 (50209) */ + 3347, /* C422 (50210) */ + 3347, /* C423 (50211) */ + 3347, /* C424 (50212) */ + 3347, /* C425 (50213) */ + 3347, /* C426 (50214) */ + 3347, /* C427 (50215) */ + 3347, /* C428 (50216) */ + 3347, /* C429 (50217) */ + 3347, /* C42A (50218) */ + 3347, /* C42B (50219) */ + 3347, /* C42C (50220) */ + 3347, /* C42D (50221) */ + 3347, /* C42E (50222) */ + 3347, /* C42F (50223) */ + 3347, /* C430 (50224) */ + 3347, /* C431 (50225) */ + 3347, /* C432 (50226) */ + 3347, /* C433 (50227) */ + 3347, /* C434 (50228) */ + 3347, /* C435 (50229) */ + 3347, /* C436 (50230) */ + 3347, /* C437 (50231) */ + 3347, /* C438 (50232) */ + 3347, /* C439 (50233) */ + 3347, /* C43A (50234) */ + 3347, /* C43B (50235) */ + 3347, /* C43C (50236) */ + 3347, /* C43D (50237) */ + 3347, /* C43E (50238) */ + 3347, /* C43F (50239) */ + 3347, /* C440 (50240) */ + 3347, /* C441 (50241) */ + 3347, /* C442 (50242) */ + 3347, /* C443 (50243) */ + 3347, /* C444 (50244) */ + 3347, /* C445 (50245) */ + 3347, /* C446 (50246) */ + 3347, /* C447 (50247) */ + 3347, /* C448 (50248) */ + 3347, /* C449 (50249) */ + 3347, /* C44A (50250) */ + 3347, /* C44B (50251) */ + 3347, /* C44C (50252) */ + 3347, /* C44D (50253) */ + 3347, /* C44E (50254) */ + 3347, /* C44F (50255) */ + 3347, /* C450 (50256) */ + 3347, /* C451 (50257) */ + 3347, /* C452 (50258) */ + 3347, /* C453 (50259) */ + 3347, /* C454 (50260) */ + 3347, /* C455 (50261) */ + 3347, /* C456 (50262) */ + 3347, /* C457 (50263) */ + 3347, /* C458 (50264) */ + 3347, /* C459 (50265) */ + 3347, /* C45A (50266) */ + 3347, /* C45B (50267) */ + 3347, /* C45C (50268) */ + 3347, /* C45D (50269) */ + 3347, /* C45E (50270) */ + 3347, /* C45F (50271) */ + 3347, /* C460 (50272) */ + 3347, /* C461 (50273) */ + 3347, /* C462 (50274) */ + 3347, /* C463 (50275) */ + 3347, /* C464 (50276) */ + 3347, /* C465 (50277) */ + 3347, /* C466 (50278) */ + 3347, /* C467 (50279) */ + 3347, /* C468 (50280) */ + 3347, /* C469 (50281) */ + 3347, /* C46A (50282) */ + 3347, /* C46B (50283) */ + 3347, /* C46C (50284) */ + 3347, /* C46D (50285) */ + 3347, /* C46E (50286) */ + 3347, /* C46F (50287) */ + 3347, /* C470 (50288) */ + 3347, /* C471 (50289) */ + 3347, /* C472 (50290) */ + 3347, /* C473 (50291) */ + 3347, /* C474 (50292) */ + 3347, /* C475 (50293) */ + 3347, /* C476 (50294) */ + 3347, /* C477 (50295) */ + 3347, /* C478 (50296) */ + 3347, /* C479 (50297) */ + 3347, /* C47A (50298) */ + 3347, /* C47B (50299) */ + 3347, /* C47C (50300) */ + 3347, /* C47D (50301) */ + 3347, /* C47E (50302) */ + 3347, /* C47F (50303) */ + 3347, /* C480 (50304) */ + 3347, /* C481 (50305) */ + 3347, /* C482 (50306) */ + 3347, /* C483 (50307) */ + 3347, /* C484 (50308) */ + 3347, /* C485 (50309) */ + 3347, /* C486 (50310) */ + 3347, /* C487 (50311) */ + 3347, /* C488 (50312) */ + 3347, /* C489 (50313) */ + 3347, /* C48A (50314) */ + 3347, /* C48B (50315) */ + 3347, /* C48C (50316) */ + 3347, /* C48D (50317) */ + 3347, /* C48E (50318) */ + 3347, /* C48F (50319) */ + 3347, /* C490 (50320) */ + 3347, /* C491 (50321) */ + 3347, /* C492 (50322) */ + 3347, /* C493 (50323) */ + 3347, /* C494 (50324) */ + 3347, /* C495 (50325) */ + 3347, /* C496 (50326) */ + 3347, /* C497 (50327) */ + 3347, /* C498 (50328) */ + 3347, /* C499 (50329) */ + 3347, /* C49A (50330) */ + 3347, /* C49B (50331) */ + 3347, /* C49C (50332) */ + 3347, /* C49D (50333) */ + 3347, /* C49E (50334) */ + 3347, /* C49F (50335) */ + 3347, /* C4A0 (50336) */ + 3347, /* C4A1 (50337) */ + 3347, /* C4A2 (50338) */ + 3347, /* C4A3 (50339) */ + 3347, /* C4A4 (50340) */ + 3347, /* C4A5 (50341) */ + 3347, /* C4A6 (50342) */ + 3347, /* C4A7 (50343) */ + 3347, /* C4A8 (50344) */ + 3347, /* C4A9 (50345) */ + 3347, /* C4AA (50346) */ + 3347, /* C4AB (50347) */ + 3347, /* C4AC (50348) */ + 3347, /* C4AD (50349) */ + 3347, /* C4AE (50350) */ + 3347, /* C4AF (50351) */ + 3347, /* C4B0 (50352) */ + 3347, /* C4B1 (50353) */ + 3347, /* C4B2 (50354) */ + 3347, /* C4B3 (50355) */ + 3347, /* C4B4 (50356) */ + 3347, /* C4B5 (50357) */ + 3347, /* C4B6 (50358) */ + 3347, /* C4B7 (50359) */ + 3347, /* C4B8 (50360) */ + 3347, /* C4B9 (50361) */ + 3347, /* C4BA (50362) */ + 3347, /* C4BB (50363) */ + 3347, /* C4BC (50364) */ + 3347, /* C4BD (50365) */ + 3347, /* C4BE (50366) */ + 3347, /* C4BF (50367) */ + 3347, /* C4C0 (50368) */ + 3347, /* C4C1 (50369) */ + 3347, /* C4C2 (50370) */ + 3347, /* C4C3 (50371) */ + 3347, /* C4C4 (50372) */ + 3347, /* C4C5 (50373) */ + 3347, /* C4C6 (50374) */ + 3347, /* C4C7 (50375) */ + 3347, /* C4C8 (50376) */ + 3347, /* C4C9 (50377) */ + 3347, /* C4CA (50378) */ + 3347, /* C4CB (50379) */ + 3347, /* C4CC (50380) */ + 3347, /* C4CD (50381) */ + 3347, /* C4CE (50382) */ + 3347, /* C4CF (50383) */ + 3347, /* C4D0 (50384) */ + 3347, /* C4D1 (50385) */ + 3347, /* C4D2 (50386) */ + 3347, /* C4D3 (50387) */ + 3347, /* C4D4 (50388) */ + 3347, /* C4D5 (50389) */ + 3347, /* C4D6 (50390) */ + 3347, /* C4D7 (50391) */ + 3347, /* C4D8 (50392) */ + 3347, /* C4D9 (50393) */ + 3347, /* C4DA (50394) */ + 3347, /* C4DB (50395) */ + 3347, /* C4DC (50396) */ + 3347, /* C4DD (50397) */ + 3347, /* C4DE (50398) */ + 3347, /* C4DF (50399) */ + 3347, /* C4E0 (50400) */ + 3347, /* C4E1 (50401) */ + 3347, /* C4E2 (50402) */ + 3347, /* C4E3 (50403) */ + 3347, /* C4E4 (50404) */ + 3347, /* C4E5 (50405) */ + 3347, /* C4E6 (50406) */ + 3347, /* C4E7 (50407) */ + 3347, /* C4E8 (50408) */ + 3347, /* C4E9 (50409) */ + 3347, /* C4EA (50410) */ + 3347, /* C4EB (50411) */ + 3347, /* C4EC (50412) */ + 3347, /* C4ED (50413) */ + 3347, /* C4EE (50414) */ + 3347, /* C4EF (50415) */ + 3347, /* C4F0 (50416) */ + 3347, /* C4F1 (50417) */ + 3347, /* C4F2 (50418) */ + 3347, /* C4F3 (50419) */ + 3347, /* C4F4 (50420) */ + 3347, /* C4F5 (50421) */ + 3347, /* C4F6 (50422) */ + 3347, /* C4F7 (50423) */ + 3347, /* C4F8 (50424) */ + 3347, /* C4F9 (50425) */ + 3347, /* C4FA (50426) */ + 3347, /* C4FB (50427) */ + 3347, /* C4FC (50428) */ + 3347, /* C4FD (50429) */ + 3347, /* C4FE (50430) */ + 3347, /* C4FF (50431) */ + 3347, /* C500 (50432) */ + 3347, /* C501 (50433) */ + 3347, /* C502 (50434) */ + 3347, /* C503 (50435) */ + 3347, /* C504 (50436) */ + 3347, /* C505 (50437) */ + 3347, /* C506 (50438) */ + 3347, /* C507 (50439) */ + 3347, /* C508 (50440) */ + 3347, /* C509 (50441) */ + 3347, /* C50A (50442) */ + 3347, /* C50B (50443) */ + 3347, /* C50C (50444) */ + 3347, /* C50D (50445) */ + 3347, /* C50E (50446) */ + 3347, /* C50F (50447) */ + 3347, /* C510 (50448) */ + 3347, /* C511 (50449) */ + 3347, /* C512 (50450) */ + 3347, /* C513 (50451) */ + 3347, /* C514 (50452) */ + 3347, /* C515 (50453) */ + 3347, /* C516 (50454) */ + 3347, /* C517 (50455) */ + 3347, /* C518 (50456) */ + 3347, /* C519 (50457) */ + 3347, /* C51A (50458) */ + 3347, /* C51B (50459) */ + 3347, /* C51C (50460) */ + 3347, /* C51D (50461) */ + 3347, /* C51E (50462) */ + 3347, /* C51F (50463) */ + 3347, /* C520 (50464) */ + 3347, /* C521 (50465) */ + 3347, /* C522 (50466) */ + 3347, /* C523 (50467) */ + 3347, /* C524 (50468) */ + 3347, /* C525 (50469) */ + 3347, /* C526 (50470) */ + 3347, /* C527 (50471) */ + 3347, /* C528 (50472) */ + 3347, /* C529 (50473) */ + 3347, /* C52A (50474) */ + 3347, /* C52B (50475) */ + 3347, /* C52C (50476) */ + 3347, /* C52D (50477) */ + 3347, /* C52E (50478) */ + 3347, /* C52F (50479) */ + 3347, /* C530 (50480) */ + 3347, /* C531 (50481) */ + 3347, /* C532 (50482) */ + 3347, /* C533 (50483) */ + 3347, /* C534 (50484) */ + 3347, /* C535 (50485) */ + 3347, /* C536 (50486) */ + 3347, /* C537 (50487) */ + 3347, /* C538 (50488) */ + 3347, /* C539 (50489) */ + 3347, /* C53A (50490) */ + 3347, /* C53B (50491) */ + 3347, /* C53C (50492) */ + 3347, /* C53D (50493) */ + 3347, /* C53E (50494) */ + 3347, /* C53F (50495) */ + 3347, /* C540 (50496) */ + 3347, /* C541 (50497) */ + 3347, /* C542 (50498) */ + 3347, /* C543 (50499) */ + 3347, /* C544 (50500) */ + 3347, /* C545 (50501) */ + 3347, /* C546 (50502) */ + 3347, /* C547 (50503) */ + 3347, /* C548 (50504) */ + 3347, /* C549 (50505) */ + 3347, /* C54A (50506) */ + 3347, /* C54B (50507) */ + 3347, /* C54C (50508) */ + 3347, /* C54D (50509) */ + 3347, /* C54E (50510) */ + 3347, /* C54F (50511) */ + 3347, /* C550 (50512) */ + 3347, /* C551 (50513) */ + 3347, /* C552 (50514) */ + 3347, /* C553 (50515) */ + 3347, /* C554 (50516) */ + 3347, /* C555 (50517) */ + 3347, /* C556 (50518) */ + 3347, /* C557 (50519) */ + 3347, /* C558 (50520) */ + 3347, /* C559 (50521) */ + 3347, /* C55A (50522) */ + 3347, /* C55B (50523) */ + 3347, /* C55C (50524) */ + 3347, /* C55D (50525) */ + 3347, /* C55E (50526) */ + 3347, /* C55F (50527) */ + 3347, /* C560 (50528) */ + 3347, /* C561 (50529) */ + 3347, /* C562 (50530) */ + 3347, /* C563 (50531) */ + 3347, /* C564 (50532) */ + 3347, /* C565 (50533) */ + 3347, /* C566 (50534) */ + 3347, /* C567 (50535) */ + 3347, /* C568 (50536) */ + 3347, /* C569 (50537) */ + 3347, /* C56A (50538) */ + 3347, /* C56B (50539) */ + 3347, /* C56C (50540) */ + 3347, /* C56D (50541) */ + 3347, /* C56E (50542) */ + 3347, /* C56F (50543) */ + 3347, /* C570 (50544) */ + 3347, /* C571 (50545) */ + 3347, /* C572 (50546) */ + 3347, /* C573 (50547) */ + 3347, /* C574 (50548) */ + 3347, /* C575 (50549) */ + 3347, /* C576 (50550) */ + 3347, /* C577 (50551) */ + 3347, /* C578 (50552) */ + 3347, /* C579 (50553) */ + 3347, /* C57A (50554) */ + 3347, /* C57B (50555) */ + 3347, /* C57C (50556) */ + 3347, /* C57D (50557) */ + 3347, /* C57E (50558) */ + 3347, /* C57F (50559) */ + 3347, /* C580 (50560) */ + 3347, /* C581 (50561) */ + 3347, /* C582 (50562) */ + 3347, /* C583 (50563) */ + 3347, /* C584 (50564) */ + 3347, /* C585 (50565) */ + 3347, /* C586 (50566) */ + 3347, /* C587 (50567) */ + 3347, /* C588 (50568) */ + 3347, /* C589 (50569) */ + 3347, /* C58A (50570) */ + 3347, /* C58B (50571) */ + 3347, /* C58C (50572) */ + 3347, /* C58D (50573) */ + 3347, /* C58E (50574) */ + 3347, /* C58F (50575) */ + 3347, /* C590 (50576) */ + 3347, /* C591 (50577) */ + 3347, /* C592 (50578) */ + 3347, /* C593 (50579) */ + 3347, /* C594 (50580) */ + 3347, /* C595 (50581) */ + 3347, /* C596 (50582) */ + 3347, /* C597 (50583) */ + 3347, /* C598 (50584) */ + 3347, /* C599 (50585) */ + 3347, /* C59A (50586) */ + 3347, /* C59B (50587) */ + 3347, /* C59C (50588) */ + 3347, /* C59D (50589) */ + 3347, /* C59E (50590) */ + 3347, /* C59F (50591) */ + 3347, /* C5A0 (50592) */ + 3347, /* C5A1 (50593) */ + 3347, /* C5A2 (50594) */ + 3347, /* C5A3 (50595) */ + 3347, /* C5A4 (50596) */ + 3347, /* C5A5 (50597) */ + 3347, /* C5A6 (50598) */ + 3347, /* C5A7 (50599) */ + 3347, /* C5A8 (50600) */ + 3347, /* C5A9 (50601) */ + 3347, /* C5AA (50602) */ + 3347, /* C5AB (50603) */ + 3347, /* C5AC (50604) */ + 3347, /* C5AD (50605) */ + 3347, /* C5AE (50606) */ + 3347, /* C5AF (50607) */ + 3347, /* C5B0 (50608) */ + 3347, /* C5B1 (50609) */ + 3347, /* C5B2 (50610) */ + 3347, /* C5B3 (50611) */ + 3347, /* C5B4 (50612) */ + 3347, /* C5B5 (50613) */ + 3347, /* C5B6 (50614) */ + 3347, /* C5B7 (50615) */ + 3347, /* C5B8 (50616) */ + 3347, /* C5B9 (50617) */ + 3347, /* C5BA (50618) */ + 3347, /* C5BB (50619) */ + 3347, /* C5BC (50620) */ + 3347, /* C5BD (50621) */ + 3347, /* C5BE (50622) */ + 3347, /* C5BF (50623) */ + 3347, /* C5C0 (50624) */ + 3347, /* C5C1 (50625) */ + 3347, /* C5C2 (50626) */ + 3347, /* C5C3 (50627) */ + 3347, /* C5C4 (50628) */ + 3347, /* C5C5 (50629) */ + 3347, /* C5C6 (50630) */ + 3347, /* C5C7 (50631) */ + 3347, /* C5C8 (50632) */ + 3347, /* C5C9 (50633) */ + 3347, /* C5CA (50634) */ + 3347, /* C5CB (50635) */ + 3347, /* C5CC (50636) */ + 3347, /* C5CD (50637) */ + 3347, /* C5CE (50638) */ + 3347, /* C5CF (50639) */ + 3347, /* C5D0 (50640) */ + 3347, /* C5D1 (50641) */ + 3347, /* C5D2 (50642) */ + 3347, /* C5D3 (50643) */ + 3347, /* C5D4 (50644) */ + 3347, /* C5D5 (50645) */ + 3347, /* C5D6 (50646) */ + 3347, /* C5D7 (50647) */ + 3347, /* C5D8 (50648) */ + 3347, /* C5D9 (50649) */ + 3347, /* C5DA (50650) */ + 3347, /* C5DB (50651) */ + 3347, /* C5DC (50652) */ + 3347, /* C5DD (50653) */ + 3347, /* C5DE (50654) */ + 3347, /* C5DF (50655) */ + 3347, /* C5E0 (50656) */ + 3347, /* C5E1 (50657) */ + 3347, /* C5E2 (50658) */ + 3347, /* C5E3 (50659) */ + 3347, /* C5E4 (50660) */ + 3347, /* C5E5 (50661) */ + 3347, /* C5E6 (50662) */ + 3347, /* C5E7 (50663) */ + 3347, /* C5E8 (50664) */ + 3347, /* C5E9 (50665) */ + 3347, /* C5EA (50666) */ + 3347, /* C5EB (50667) */ + 3347, /* C5EC (50668) */ + 3347, /* C5ED (50669) */ + 3347, /* C5EE (50670) */ + 3347, /* C5EF (50671) */ + 3347, /* C5F0 (50672) */ + 3347, /* C5F1 (50673) */ + 3347, /* C5F2 (50674) */ + 3347, /* C5F3 (50675) */ + 3347, /* C5F4 (50676) */ + 3347, /* C5F5 (50677) */ + 3347, /* C5F6 (50678) */ + 3347, /* C5F7 (50679) */ + 3347, /* C5F8 (50680) */ + 3347, /* C5F9 (50681) */ + 3347, /* C5FA (50682) */ + 3347, /* C5FB (50683) */ + 3347, /* C5FC (50684) */ + 3347, /* C5FD (50685) */ + 3347, /* C5FE (50686) */ + 3347, /* C5FF (50687) */ + 3347, /* C600 (50688) */ + 3347, /* C601 (50689) */ + 3347, /* C602 (50690) */ + 3347, /* C603 (50691) */ + 3347, /* C604 (50692) */ + 3347, /* C605 (50693) */ + 3347, /* C606 (50694) */ + 3347, /* C607 (50695) */ + 3347, /* C608 (50696) */ + 3347, /* C609 (50697) */ + 3347, /* C60A (50698) */ + 3347, /* C60B (50699) */ + 3347, /* C60C (50700) */ + 3347, /* C60D (50701) */ + 3347, /* C60E (50702) */ + 3347, /* C60F (50703) */ + 3347, /* C610 (50704) */ + 3347, /* C611 (50705) */ + 3347, /* C612 (50706) */ + 3347, /* C613 (50707) */ + 3347, /* C614 (50708) */ + 3347, /* C615 (50709) */ + 3347, /* C616 (50710) */ + 3347, /* C617 (50711) */ + 3347, /* C618 (50712) */ + 3347, /* C619 (50713) */ + 3347, /* C61A (50714) */ + 3347, /* C61B (50715) */ + 3347, /* C61C (50716) */ + 3347, /* C61D (50717) */ + 3347, /* C61E (50718) */ + 3347, /* C61F (50719) */ + 3347, /* C620 (50720) */ + 3347, /* C621 (50721) */ + 3347, /* C622 (50722) */ + 3347, /* C623 (50723) */ + 3347, /* C624 (50724) */ + 3347, /* C625 (50725) */ + 3347, /* C626 (50726) */ + 3347, /* C627 (50727) */ + 3347, /* C628 (50728) */ + 3347, /* C629 (50729) */ + 3347, /* C62A (50730) */ + 3347, /* C62B (50731) */ + 3347, /* C62C (50732) */ + 3347, /* C62D (50733) */ + 3347, /* C62E (50734) */ + 3347, /* C62F (50735) */ + 3347, /* C630 (50736) */ + 3347, /* C631 (50737) */ + 3347, /* C632 (50738) */ + 3347, /* C633 (50739) */ + 3347, /* C634 (50740) */ + 3347, /* C635 (50741) */ + 3347, /* C636 (50742) */ + 3347, /* C637 (50743) */ + 3347, /* C638 (50744) */ + 3347, /* C639 (50745) */ + 3347, /* C63A (50746) */ + 3347, /* C63B (50747) */ + 3347, /* C63C (50748) */ + 3347, /* C63D (50749) */ + 3347, /* C63E (50750) */ + 3347, /* C63F (50751) */ + 3347, /* C640 (50752) */ + 3347, /* C641 (50753) */ + 3347, /* C642 (50754) */ + 3347, /* C643 (50755) */ + 3347, /* C644 (50756) */ + 3347, /* C645 (50757) */ + 3347, /* C646 (50758) */ + 3347, /* C647 (50759) */ + 3347, /* C648 (50760) */ + 3347, /* C649 (50761) */ + 3347, /* C64A (50762) */ + 3347, /* C64B (50763) */ + 3347, /* C64C (50764) */ + 3347, /* C64D (50765) */ + 3347, /* C64E (50766) */ + 3347, /* C64F (50767) */ + 3347, /* C650 (50768) */ + 3347, /* C651 (50769) */ + 3347, /* C652 (50770) */ + 3347, /* C653 (50771) */ + 3347, /* C654 (50772) */ + 3347, /* C655 (50773) */ + 3347, /* C656 (50774) */ + 3347, /* C657 (50775) */ + 3347, /* C658 (50776) */ + 3347, /* C659 (50777) */ + 3347, /* C65A (50778) */ + 3347, /* C65B (50779) */ + 3347, /* C65C (50780) */ + 3347, /* C65D (50781) */ + 3347, /* C65E (50782) */ + 3347, /* C65F (50783) */ + 3347, /* C660 (50784) */ + 3347, /* C661 (50785) */ + 3347, /* C662 (50786) */ + 3347, /* C663 (50787) */ + 3347, /* C664 (50788) */ + 3347, /* C665 (50789) */ + 3347, /* C666 (50790) */ + 3347, /* C667 (50791) */ + 3347, /* C668 (50792) */ + 3347, /* C669 (50793) */ + 3347, /* C66A (50794) */ + 3347, /* C66B (50795) */ + 3347, /* C66C (50796) */ + 3347, /* C66D (50797) */ + 3347, /* C66E (50798) */ + 3347, /* C66F (50799) */ + 3347, /* C670 (50800) */ + 3347, /* C671 (50801) */ + 3347, /* C672 (50802) */ + 3347, /* C673 (50803) */ + 3347, /* C674 (50804) */ + 3347, /* C675 (50805) */ + 3347, /* C676 (50806) */ + 3347, /* C677 (50807) */ + 3347, /* C678 (50808) */ + 3347, /* C679 (50809) */ + 3347, /* C67A (50810) */ + 3347, /* C67B (50811) */ + 3347, /* C67C (50812) */ + 3347, /* C67D (50813) */ + 3347, /* C67E (50814) */ + 3347, /* C67F (50815) */ + 3347, /* C680 (50816) */ + 3347, /* C681 (50817) */ + 3347, /* C682 (50818) */ + 3347, /* C683 (50819) */ + 3347, /* C684 (50820) */ + 3347, /* C685 (50821) */ + 3347, /* C686 (50822) */ + 3347, /* C687 (50823) */ + 3347, /* C688 (50824) */ + 3347, /* C689 (50825) */ + 3347, /* C68A (50826) */ + 3347, /* C68B (50827) */ + 3347, /* C68C (50828) */ + 3347, /* C68D (50829) */ + 3347, /* C68E (50830) */ + 3347, /* C68F (50831) */ + 3347, /* C690 (50832) */ + 3347, /* C691 (50833) */ + 3347, /* C692 (50834) */ + 3347, /* C693 (50835) */ + 3347, /* C694 (50836) */ + 3347, /* C695 (50837) */ + 3347, /* C696 (50838) */ + 3347, /* C697 (50839) */ + 3347, /* C698 (50840) */ + 3347, /* C699 (50841) */ + 3347, /* C69A (50842) */ + 3347, /* C69B (50843) */ + 3347, /* C69C (50844) */ + 3347, /* C69D (50845) */ + 3347, /* C69E (50846) */ + 3347, /* C69F (50847) */ + 3347, /* C6A0 (50848) */ + 3347, /* C6A1 (50849) */ + 3347, /* C6A2 (50850) */ + 3347, /* C6A3 (50851) */ + 3347, /* C6A4 (50852) */ + 3347, /* C6A5 (50853) */ + 3347, /* C6A6 (50854) */ + 3347, /* C6A7 (50855) */ + 3347, /* C6A8 (50856) */ + 3347, /* C6A9 (50857) */ + 3347, /* C6AA (50858) */ + 3347, /* C6AB (50859) */ + 3347, /* C6AC (50860) */ + 3347, /* C6AD (50861) */ + 3347, /* C6AE (50862) */ + 3347, /* C6AF (50863) */ + 3347, /* C6B0 (50864) */ + 3347, /* C6B1 (50865) */ + 3347, /* C6B2 (50866) */ + 3347, /* C6B3 (50867) */ + 3347, /* C6B4 (50868) */ + 3347, /* C6B5 (50869) */ + 3347, /* C6B6 (50870) */ + 3347, /* C6B7 (50871) */ + 3347, /* C6B8 (50872) */ + 3347, /* C6B9 (50873) */ + 3347, /* C6BA (50874) */ + 3347, /* C6BB (50875) */ + 3347, /* C6BC (50876) */ + 3347, /* C6BD (50877) */ + 3347, /* C6BE (50878) */ + 3347, /* C6BF (50879) */ + 3347, /* C6C0 (50880) */ + 3347, /* C6C1 (50881) */ + 3347, /* C6C2 (50882) */ + 3347, /* C6C3 (50883) */ + 3347, /* C6C4 (50884) */ + 3347, /* C6C5 (50885) */ + 3347, /* C6C6 (50886) */ + 3347, /* C6C7 (50887) */ + 3347, /* C6C8 (50888) */ + 3347, /* C6C9 (50889) */ + 3347, /* C6CA (50890) */ + 3347, /* C6CB (50891) */ + 3347, /* C6CC (50892) */ + 3347, /* C6CD (50893) */ + 3347, /* C6CE (50894) */ + 3347, /* C6CF (50895) */ + 3347, /* C6D0 (50896) */ + 3347, /* C6D1 (50897) */ + 3347, /* C6D2 (50898) */ + 3347, /* C6D3 (50899) */ + 3347, /* C6D4 (50900) */ + 3347, /* C6D5 (50901) */ + 3347, /* C6D6 (50902) */ + 3347, /* C6D7 (50903) */ + 3347, /* C6D8 (50904) */ + 3347, /* C6D9 (50905) */ + 3347, /* C6DA (50906) */ + 3347, /* C6DB (50907) */ + 3347, /* C6DC (50908) */ + 3347, /* C6DD (50909) */ + 3347, /* C6DE (50910) */ + 3347, /* C6DF (50911) */ + 3347, /* C6E0 (50912) */ + 3347, /* C6E1 (50913) */ + 3347, /* C6E2 (50914) */ + 3347, /* C6E3 (50915) */ + 3347, /* C6E4 (50916) */ + 3347, /* C6E5 (50917) */ + 3347, /* C6E6 (50918) */ + 3347, /* C6E7 (50919) */ + 3347, /* C6E8 (50920) */ + 3347, /* C6E9 (50921) */ + 3347, /* C6EA (50922) */ + 3347, /* C6EB (50923) */ + 3347, /* C6EC (50924) */ + 3347, /* C6ED (50925) */ + 3347, /* C6EE (50926) */ + 3347, /* C6EF (50927) */ + 3347, /* C6F0 (50928) */ + 3347, /* C6F1 (50929) */ + 3347, /* C6F2 (50930) */ + 3347, /* C6F3 (50931) */ + 3347, /* C6F4 (50932) */ + 3347, /* C6F5 (50933) */ + 3347, /* C6F6 (50934) */ + 3347, /* C6F7 (50935) */ + 3347, /* C6F8 (50936) */ + 3347, /* C6F9 (50937) */ + 3347, /* C6FA (50938) */ + 3347, /* C6FB (50939) */ + 3347, /* C6FC (50940) */ + 3347, /* C6FD (50941) */ + 3347, /* C6FE (50942) */ + 3347, /* C6FF (50943) */ + 3347, /* C700 (50944) */ + 3347, /* C701 (50945) */ + 3347, /* C702 (50946) */ + 3347, /* C703 (50947) */ + 3347, /* C704 (50948) */ + 3347, /* C705 (50949) */ + 3347, /* C706 (50950) */ + 3347, /* C707 (50951) */ + 3347, /* C708 (50952) */ + 3347, /* C709 (50953) */ + 3347, /* C70A (50954) */ + 3347, /* C70B (50955) */ + 3347, /* C70C (50956) */ + 3347, /* C70D (50957) */ + 3347, /* C70E (50958) */ + 3347, /* C70F (50959) */ + 3347, /* C710 (50960) */ + 3347, /* C711 (50961) */ + 3347, /* C712 (50962) */ + 3347, /* C713 (50963) */ + 3347, /* C714 (50964) */ + 3347, /* C715 (50965) */ + 3347, /* C716 (50966) */ + 3347, /* C717 (50967) */ + 3347, /* C718 (50968) */ + 3347, /* C719 (50969) */ + 3347, /* C71A (50970) */ + 3347, /* C71B (50971) */ + 3347, /* C71C (50972) */ + 3347, /* C71D (50973) */ + 3347, /* C71E (50974) */ + 3347, /* C71F (50975) */ + 3347, /* C720 (50976) */ + 3347, /* C721 (50977) */ + 3347, /* C722 (50978) */ + 3347, /* C723 (50979) */ + 3347, /* C724 (50980) */ + 3347, /* C725 (50981) */ + 3347, /* C726 (50982) */ + 3347, /* C727 (50983) */ + 3347, /* C728 (50984) */ + 3347, /* C729 (50985) */ + 3347, /* C72A (50986) */ + 3347, /* C72B (50987) */ + 3347, /* C72C (50988) */ + 3347, /* C72D (50989) */ + 3347, /* C72E (50990) */ + 3347, /* C72F (50991) */ + 3347, /* C730 (50992) */ + 3347, /* C731 (50993) */ + 3347, /* C732 (50994) */ + 3347, /* C733 (50995) */ + 3347, /* C734 (50996) */ + 3347, /* C735 (50997) */ + 3347, /* C736 (50998) */ + 3347, /* C737 (50999) */ + 3347, /* C738 (51000) */ + 3347, /* C739 (51001) */ + 3347, /* C73A (51002) */ + 3347, /* C73B (51003) */ + 3347, /* C73C (51004) */ + 3347, /* C73D (51005) */ + 3347, /* C73E (51006) */ + 3347, /* C73F (51007) */ + 3347, /* C740 (51008) */ + 3347, /* C741 (51009) */ + 3347, /* C742 (51010) */ + 3347, /* C743 (51011) */ + 3347, /* C744 (51012) */ + 3347, /* C745 (51013) */ + 3347, /* C746 (51014) */ + 3347, /* C747 (51015) */ + 3347, /* C748 (51016) */ + 3347, /* C749 (51017) */ + 3347, /* C74A (51018) */ + 3347, /* C74B (51019) */ + 3347, /* C74C (51020) */ + 3347, /* C74D (51021) */ + 3347, /* C74E (51022) */ + 3347, /* C74F (51023) */ + 3347, /* C750 (51024) */ + 3347, /* C751 (51025) */ + 3347, /* C752 (51026) */ + 3347, /* C753 (51027) */ + 3347, /* C754 (51028) */ + 3347, /* C755 (51029) */ + 3347, /* C756 (51030) */ + 3347, /* C757 (51031) */ + 3347, /* C758 (51032) */ + 3347, /* C759 (51033) */ + 3347, /* C75A (51034) */ + 3347, /* C75B (51035) */ + 3347, /* C75C (51036) */ + 3347, /* C75D (51037) */ + 3347, /* C75E (51038) */ + 3347, /* C75F (51039) */ + 3347, /* C760 (51040) */ + 3347, /* C761 (51041) */ + 3347, /* C762 (51042) */ + 3347, /* C763 (51043) */ + 3347, /* C764 (51044) */ + 3347, /* C765 (51045) */ + 3347, /* C766 (51046) */ + 3347, /* C767 (51047) */ + 3347, /* C768 (51048) */ + 3347, /* C769 (51049) */ + 3347, /* C76A (51050) */ + 3347, /* C76B (51051) */ + 3347, /* C76C (51052) */ + 3347, /* C76D (51053) */ + 3347, /* C76E (51054) */ + 3347, /* C76F (51055) */ + 3347, /* C770 (51056) */ + 3347, /* C771 (51057) */ + 3347, /* C772 (51058) */ + 3347, /* C773 (51059) */ + 3347, /* C774 (51060) */ + 3347, /* C775 (51061) */ + 3347, /* C776 (51062) */ + 3347, /* C777 (51063) */ + 3347, /* C778 (51064) */ + 3347, /* C779 (51065) */ + 3347, /* C77A (51066) */ + 3347, /* C77B (51067) */ + 3347, /* C77C (51068) */ + 3347, /* C77D (51069) */ + 3347, /* C77E (51070) */ + 3347, /* C77F (51071) */ + 3347, /* C780 (51072) */ + 3347, /* C781 (51073) */ + 3347, /* C782 (51074) */ + 3347, /* C783 (51075) */ + 3347, /* C784 (51076) */ + 3347, /* C785 (51077) */ + 3347, /* C786 (51078) */ + 3347, /* C787 (51079) */ + 3347, /* C788 (51080) */ + 3347, /* C789 (51081) */ + 3347, /* C78A (51082) */ + 3347, /* C78B (51083) */ + 3347, /* C78C (51084) */ + 3347, /* C78D (51085) */ + 3347, /* C78E (51086) */ + 3347, /* C78F (51087) */ + 3347, /* C790 (51088) */ + 3347, /* C791 (51089) */ + 3347, /* C792 (51090) */ + 3347, /* C793 (51091) */ + 3347, /* C794 (51092) */ + 3347, /* C795 (51093) */ + 3347, /* C796 (51094) */ + 3347, /* C797 (51095) */ + 3347, /* C798 (51096) */ + 3347, /* C799 (51097) */ + 3347, /* C79A (51098) */ + 3347, /* C79B (51099) */ + 3347, /* C79C (51100) */ + 3347, /* C79D (51101) */ + 3347, /* C79E (51102) */ + 3347, /* C79F (51103) */ + 3347, /* C7A0 (51104) */ + 3347, /* C7A1 (51105) */ + 3347, /* C7A2 (51106) */ + 3347, /* C7A3 (51107) */ + 3347, /* C7A4 (51108) */ + 3347, /* C7A5 (51109) */ + 3347, /* C7A6 (51110) */ + 3347, /* C7A7 (51111) */ + 3347, /* C7A8 (51112) */ + 3347, /* C7A9 (51113) */ + 3347, /* C7AA (51114) */ + 3347, /* C7AB (51115) */ + 3347, /* C7AC (51116) */ + 3347, /* C7AD (51117) */ + 3347, /* C7AE (51118) */ + 3347, /* C7AF (51119) */ + 3347, /* C7B0 (51120) */ + 3347, /* C7B1 (51121) */ + 3347, /* C7B2 (51122) */ + 3347, /* C7B3 (51123) */ + 3347, /* C7B4 (51124) */ + 3347, /* C7B5 (51125) */ + 3347, /* C7B6 (51126) */ + 3347, /* C7B7 (51127) */ + 3347, /* C7B8 (51128) */ + 3347, /* C7B9 (51129) */ + 3347, /* C7BA (51130) */ + 3347, /* C7BB (51131) */ + 3347, /* C7BC (51132) */ + 3347, /* C7BD (51133) */ + 3347, /* C7BE (51134) */ + 3347, /* C7BF (51135) */ + 3347, /* C7C0 (51136) */ + 3347, /* C7C1 (51137) */ + 3347, /* C7C2 (51138) */ + 3347, /* C7C3 (51139) */ + 3347, /* C7C4 (51140) */ + 3347, /* C7C5 (51141) */ + 3347, /* C7C6 (51142) */ + 3347, /* C7C7 (51143) */ + 3347, /* C7C8 (51144) */ + 3347, /* C7C9 (51145) */ + 3347, /* C7CA (51146) */ + 3347, /* C7CB (51147) */ + 3347, /* C7CC (51148) */ + 3347, /* C7CD (51149) */ + 3347, /* C7CE (51150) */ + 3347, /* C7CF (51151) */ + 3347, /* C7D0 (51152) */ + 3347, /* C7D1 (51153) */ + 3347, /* C7D2 (51154) */ + 3347, /* C7D3 (51155) */ + 3347, /* C7D4 (51156) */ + 3347, /* C7D5 (51157) */ + 3347, /* C7D6 (51158) */ + 3347, /* C7D7 (51159) */ + 3347, /* C7D8 (51160) */ + 3347, /* C7D9 (51161) */ + 3347, /* C7DA (51162) */ + 3347, /* C7DB (51163) */ + 3347, /* C7DC (51164) */ + 3347, /* C7DD (51165) */ + 3347, /* C7DE (51166) */ + 3347, /* C7DF (51167) */ + 3347, /* C7E0 (51168) */ + 3347, /* C7E1 (51169) */ + 3347, /* C7E2 (51170) */ + 3347, /* C7E3 (51171) */ + 3347, /* C7E4 (51172) */ + 3347, /* C7E5 (51173) */ + 3347, /* C7E6 (51174) */ + 3347, /* C7E7 (51175) */ + 3347, /* C7E8 (51176) */ + 3347, /* C7E9 (51177) */ + 3347, /* C7EA (51178) */ + 3347, /* C7EB (51179) */ + 3347, /* C7EC (51180) */ + 3347, /* C7ED (51181) */ + 3347, /* C7EE (51182) */ + 3347, /* C7EF (51183) */ + 3347, /* C7F0 (51184) */ + 3347, /* C7F1 (51185) */ + 3347, /* C7F2 (51186) */ + 3347, /* C7F3 (51187) */ + 3347, /* C7F4 (51188) */ + 3347, /* C7F5 (51189) */ + 3347, /* C7F6 (51190) */ + 3347, /* C7F7 (51191) */ + 3347, /* C7F8 (51192) */ + 3347, /* C7F9 (51193) */ + 3347, /* C7FA (51194) */ + 3347, /* C7FB (51195) */ + 3347, /* C7FC (51196) */ + 3347, /* C7FD (51197) */ + 3347, /* C7FE (51198) */ + 3347, /* C7FF (51199) */ + 3347, /* C800 (51200) */ + 3347, /* C801 (51201) */ + 3347, /* C802 (51202) */ + 3347, /* C803 (51203) */ + 3347, /* C804 (51204) */ + 3347, /* C805 (51205) */ + 3347, /* C806 (51206) */ + 3347, /* C807 (51207) */ + 3347, /* C808 (51208) */ + 3347, /* C809 (51209) */ + 3347, /* C80A (51210) */ + 3347, /* C80B (51211) */ + 3347, /* C80C (51212) */ + 3347, /* C80D (51213) */ + 3347, /* C80E (51214) */ + 3347, /* C80F (51215) */ + 3347, /* C810 (51216) */ + 3347, /* C811 (51217) */ + 3347, /* C812 (51218) */ + 3347, /* C813 (51219) */ + 3347, /* C814 (51220) */ + 3347, /* C815 (51221) */ + 3347, /* C816 (51222) */ + 3347, /* C817 (51223) */ + 3347, /* C818 (51224) */ + 3347, /* C819 (51225) */ + 3347, /* C81A (51226) */ + 3347, /* C81B (51227) */ + 3347, /* C81C (51228) */ + 3347, /* C81D (51229) */ + 3347, /* C81E (51230) */ + 3347, /* C81F (51231) */ + 3347, /* C820 (51232) */ + 3347, /* C821 (51233) */ + 3347, /* C822 (51234) */ + 3347, /* C823 (51235) */ + 3347, /* C824 (51236) */ + 3347, /* C825 (51237) */ + 3347, /* C826 (51238) */ + 3347, /* C827 (51239) */ + 3347, /* C828 (51240) */ + 3347, /* C829 (51241) */ + 3347, /* C82A (51242) */ + 3347, /* C82B (51243) */ + 3347, /* C82C (51244) */ + 3347, /* C82D (51245) */ + 3347, /* C82E (51246) */ + 3347, /* C82F (51247) */ + 3347, /* C830 (51248) */ + 3347, /* C831 (51249) */ + 3347, /* C832 (51250) */ + 3347, /* C833 (51251) */ + 3347, /* C834 (51252) */ + 3347, /* C835 (51253) */ + 3347, /* C836 (51254) */ + 3347, /* C837 (51255) */ + 3347, /* C838 (51256) */ + 3347, /* C839 (51257) */ + 3347, /* C83A (51258) */ + 3347, /* C83B (51259) */ + 3347, /* C83C (51260) */ + 3347, /* C83D (51261) */ + 3347, /* C83E (51262) */ + 3347, /* C83F (51263) */ + 3347, /* C840 (51264) */ + 3347, /* C841 (51265) */ + 3347, /* C842 (51266) */ + 3347, /* C843 (51267) */ + 3347, /* C844 (51268) */ + 3347, /* C845 (51269) */ + 3347, /* C846 (51270) */ + 3347, /* C847 (51271) */ + 3347, /* C848 (51272) */ + 3347, /* C849 (51273) */ + 3347, /* C84A (51274) */ + 3347, /* C84B (51275) */ + 3347, /* C84C (51276) */ + 3347, /* C84D (51277) */ + 3347, /* C84E (51278) */ + 3347, /* C84F (51279) */ + 3347, /* C850 (51280) */ + 3347, /* C851 (51281) */ + 3347, /* C852 (51282) */ + 3347, /* C853 (51283) */ + 3347, /* C854 (51284) */ + 3347, /* C855 (51285) */ + 3347, /* C856 (51286) */ + 3347, /* C857 (51287) */ + 3347, /* C858 (51288) */ + 3347, /* C859 (51289) */ + 3347, /* C85A (51290) */ + 3347, /* C85B (51291) */ + 3347, /* C85C (51292) */ + 3347, /* C85D (51293) */ + 3347, /* C85E (51294) */ + 3347, /* C85F (51295) */ + 3347, /* C860 (51296) */ + 3347, /* C861 (51297) */ + 3347, /* C862 (51298) */ + 3347, /* C863 (51299) */ + 3347, /* C864 (51300) */ + 3347, /* C865 (51301) */ + 3347, /* C866 (51302) */ + 3347, /* C867 (51303) */ + 3347, /* C868 (51304) */ + 3347, /* C869 (51305) */ + 3347, /* C86A (51306) */ + 3347, /* C86B (51307) */ + 3347, /* C86C (51308) */ + 3347, /* C86D (51309) */ + 3347, /* C86E (51310) */ + 3347, /* C86F (51311) */ + 3347, /* C870 (51312) */ + 3347, /* C871 (51313) */ + 3347, /* C872 (51314) */ + 3347, /* C873 (51315) */ + 3347, /* C874 (51316) */ + 3347, /* C875 (51317) */ + 3347, /* C876 (51318) */ + 3347, /* C877 (51319) */ + 3347, /* C878 (51320) */ + 3347, /* C879 (51321) */ + 3347, /* C87A (51322) */ + 3347, /* C87B (51323) */ + 3347, /* C87C (51324) */ + 3347, /* C87D (51325) */ + 3347, /* C87E (51326) */ + 3347, /* C87F (51327) */ + 3347, /* C880 (51328) */ + 3347, /* C881 (51329) */ + 3347, /* C882 (51330) */ + 3347, /* C883 (51331) */ + 3347, /* C884 (51332) */ + 3347, /* C885 (51333) */ + 3347, /* C886 (51334) */ + 3347, /* C887 (51335) */ + 3347, /* C888 (51336) */ + 3347, /* C889 (51337) */ + 3347, /* C88A (51338) */ + 3347, /* C88B (51339) */ + 3347, /* C88C (51340) */ + 3347, /* C88D (51341) */ + 3347, /* C88E (51342) */ + 3347, /* C88F (51343) */ + 3347, /* C890 (51344) */ + 3347, /* C891 (51345) */ + 3347, /* C892 (51346) */ + 3347, /* C893 (51347) */ + 3347, /* C894 (51348) */ + 3347, /* C895 (51349) */ + 3347, /* C896 (51350) */ + 3347, /* C897 (51351) */ + 3347, /* C898 (51352) */ + 3347, /* C899 (51353) */ + 3347, /* C89A (51354) */ + 3347, /* C89B (51355) */ + 3347, /* C89C (51356) */ + 3347, /* C89D (51357) */ + 3347, /* C89E (51358) */ + 3347, /* C89F (51359) */ + 3347, /* C8A0 (51360) */ + 3347, /* C8A1 (51361) */ + 3347, /* C8A2 (51362) */ + 3347, /* C8A3 (51363) */ + 3347, /* C8A4 (51364) */ + 3347, /* C8A5 (51365) */ + 3347, /* C8A6 (51366) */ + 3347, /* C8A7 (51367) */ + 3347, /* C8A8 (51368) */ + 3347, /* C8A9 (51369) */ + 3347, /* C8AA (51370) */ + 3347, /* C8AB (51371) */ + 3347, /* C8AC (51372) */ + 3347, /* C8AD (51373) */ + 3347, /* C8AE (51374) */ + 3347, /* C8AF (51375) */ + 3347, /* C8B0 (51376) */ + 3347, /* C8B1 (51377) */ + 3347, /* C8B2 (51378) */ + 3347, /* C8B3 (51379) */ + 3347, /* C8B4 (51380) */ + 3347, /* C8B5 (51381) */ + 3347, /* C8B6 (51382) */ + 3347, /* C8B7 (51383) */ + 3347, /* C8B8 (51384) */ + 3347, /* C8B9 (51385) */ + 3347, /* C8BA (51386) */ + 3347, /* C8BB (51387) */ + 3347, /* C8BC (51388) */ + 3347, /* C8BD (51389) */ + 3347, /* C8BE (51390) */ + 3347, /* C8BF (51391) */ + 3347, /* C8C0 (51392) */ + 3347, /* C8C1 (51393) */ + 3347, /* C8C2 (51394) */ + 3347, /* C8C3 (51395) */ + 3347, /* C8C4 (51396) */ + 3347, /* C8C5 (51397) */ + 3347, /* C8C6 (51398) */ + 3347, /* C8C7 (51399) */ + 3347, /* C8C8 (51400) */ + 3347, /* C8C9 (51401) */ + 3347, /* C8CA (51402) */ + 3347, /* C8CB (51403) */ + 3347, /* C8CC (51404) */ + 3347, /* C8CD (51405) */ + 3347, /* C8CE (51406) */ + 3347, /* C8CF (51407) */ + 3347, /* C8D0 (51408) */ + 3347, /* C8D1 (51409) */ + 3347, /* C8D2 (51410) */ + 3347, /* C8D3 (51411) */ + 3347, /* C8D4 (51412) */ + 3347, /* C8D5 (51413) */ + 3347, /* C8D6 (51414) */ + 3347, /* C8D7 (51415) */ + 3347, /* C8D8 (51416) */ + 3347, /* C8D9 (51417) */ + 3347, /* C8DA (51418) */ + 3347, /* C8DB (51419) */ + 3347, /* C8DC (51420) */ + 3347, /* C8DD (51421) */ + 3347, /* C8DE (51422) */ + 3347, /* C8DF (51423) */ + 3347, /* C8E0 (51424) */ + 3347, /* C8E1 (51425) */ + 3347, /* C8E2 (51426) */ + 3347, /* C8E3 (51427) */ + 3347, /* C8E4 (51428) */ + 3347, /* C8E5 (51429) */ + 3347, /* C8E6 (51430) */ + 3347, /* C8E7 (51431) */ + 3347, /* C8E8 (51432) */ + 3347, /* C8E9 (51433) */ + 3347, /* C8EA (51434) */ + 3347, /* C8EB (51435) */ + 3347, /* C8EC (51436) */ + 3347, /* C8ED (51437) */ + 3347, /* C8EE (51438) */ + 3347, /* C8EF (51439) */ + 3347, /* C8F0 (51440) */ + 3347, /* C8F1 (51441) */ + 3347, /* C8F2 (51442) */ + 3347, /* C8F3 (51443) */ + 3347, /* C8F4 (51444) */ + 3347, /* C8F5 (51445) */ + 3347, /* C8F6 (51446) */ + 3347, /* C8F7 (51447) */ + 3347, /* C8F8 (51448) */ + 3347, /* C8F9 (51449) */ + 3347, /* C8FA (51450) */ + 3347, /* C8FB (51451) */ + 3347, /* C8FC (51452) */ + 3347, /* C8FD (51453) */ + 3347, /* C8FE (51454) */ + 3347, /* C8FF (51455) */ + 3347, /* C900 (51456) */ + 3347, /* C901 (51457) */ + 3347, /* C902 (51458) */ + 3347, /* C903 (51459) */ + 3347, /* C904 (51460) */ + 3347, /* C905 (51461) */ + 3347, /* C906 (51462) */ + 3347, /* C907 (51463) */ + 3347, /* C908 (51464) */ + 3347, /* C909 (51465) */ + 3347, /* C90A (51466) */ + 3347, /* C90B (51467) */ + 3347, /* C90C (51468) */ + 3347, /* C90D (51469) */ + 3347, /* C90E (51470) */ + 3347, /* C90F (51471) */ + 3347, /* C910 (51472) */ + 3347, /* C911 (51473) */ + 3347, /* C912 (51474) */ + 3347, /* C913 (51475) */ + 3347, /* C914 (51476) */ + 3347, /* C915 (51477) */ + 3347, /* C916 (51478) */ + 3347, /* C917 (51479) */ + 3347, /* C918 (51480) */ + 3347, /* C919 (51481) */ + 3347, /* C91A (51482) */ + 3347, /* C91B (51483) */ + 3347, /* C91C (51484) */ + 3347, /* C91D (51485) */ + 3347, /* C91E (51486) */ + 3347, /* C91F (51487) */ + 3347, /* C920 (51488) */ + 3347, /* C921 (51489) */ + 3347, /* C922 (51490) */ + 3347, /* C923 (51491) */ + 3347, /* C924 (51492) */ + 3347, /* C925 (51493) */ + 3347, /* C926 (51494) */ + 3347, /* C927 (51495) */ + 3347, /* C928 (51496) */ + 3347, /* C929 (51497) */ + 3347, /* C92A (51498) */ + 3347, /* C92B (51499) */ + 3347, /* C92C (51500) */ + 3347, /* C92D (51501) */ + 3347, /* C92E (51502) */ + 3347, /* C92F (51503) */ + 3347, /* C930 (51504) */ + 3347, /* C931 (51505) */ + 3347, /* C932 (51506) */ + 3347, /* C933 (51507) */ + 3347, /* C934 (51508) */ + 3347, /* C935 (51509) */ + 3347, /* C936 (51510) */ + 3347, /* C937 (51511) */ + 3347, /* C938 (51512) */ + 3347, /* C939 (51513) */ + 3347, /* C93A (51514) */ + 3347, /* C93B (51515) */ + 3347, /* C93C (51516) */ + 3347, /* C93D (51517) */ + 3347, /* C93E (51518) */ + 3347, /* C93F (51519) */ + 3347, /* C940 (51520) */ + 3347, /* C941 (51521) */ + 3347, /* C942 (51522) */ + 3347, /* C943 (51523) */ + 3347, /* C944 (51524) */ + 3347, /* C945 (51525) */ + 3347, /* C946 (51526) */ + 3347, /* C947 (51527) */ + 3347, /* C948 (51528) */ + 3347, /* C949 (51529) */ + 3347, /* C94A (51530) */ + 3347, /* C94B (51531) */ + 3347, /* C94C (51532) */ + 3347, /* C94D (51533) */ + 3347, /* C94E (51534) */ + 3347, /* C94F (51535) */ + 3347, /* C950 (51536) */ + 3347, /* C951 (51537) */ + 3347, /* C952 (51538) */ + 3347, /* C953 (51539) */ + 3347, /* C954 (51540) */ + 3347, /* C955 (51541) */ + 3347, /* C956 (51542) */ + 3347, /* C957 (51543) */ + 3347, /* C958 (51544) */ + 3347, /* C959 (51545) */ + 3347, /* C95A (51546) */ + 3347, /* C95B (51547) */ + 3347, /* C95C (51548) */ + 3347, /* C95D (51549) */ + 3347, /* C95E (51550) */ + 3347, /* C95F (51551) */ + 3347, /* C960 (51552) */ + 3347, /* C961 (51553) */ + 3347, /* C962 (51554) */ + 3347, /* C963 (51555) */ + 3347, /* C964 (51556) */ + 3347, /* C965 (51557) */ + 3347, /* C966 (51558) */ + 3347, /* C967 (51559) */ + 3347, /* C968 (51560) */ + 3347, /* C969 (51561) */ + 3347, /* C96A (51562) */ + 3347, /* C96B (51563) */ + 3347, /* C96C (51564) */ + 3347, /* C96D (51565) */ + 3347, /* C96E (51566) */ + 3347, /* C96F (51567) */ + 3347, /* C970 (51568) */ + 3347, /* C971 (51569) */ + 3347, /* C972 (51570) */ + 3347, /* C973 (51571) */ + 3347, /* C974 (51572) */ + 3347, /* C975 (51573) */ + 3347, /* C976 (51574) */ + 3347, /* C977 (51575) */ + 3347, /* C978 (51576) */ + 3347, /* C979 (51577) */ + 3347, /* C97A (51578) */ + 3347, /* C97B (51579) */ + 3347, /* C97C (51580) */ + 3347, /* C97D (51581) */ + 3347, /* C97E (51582) */ + 3347, /* C97F (51583) */ + 3347, /* C980 (51584) */ + 3347, /* C981 (51585) */ + 3347, /* C982 (51586) */ + 3347, /* C983 (51587) */ + 3347, /* C984 (51588) */ + 3347, /* C985 (51589) */ + 3347, /* C986 (51590) */ + 3347, /* C987 (51591) */ + 3347, /* C988 (51592) */ + 3347, /* C989 (51593) */ + 3347, /* C98A (51594) */ + 3347, /* C98B (51595) */ + 3347, /* C98C (51596) */ + 3347, /* C98D (51597) */ + 3347, /* C98E (51598) */ + 3347, /* C98F (51599) */ + 3347, /* C990 (51600) */ + 3347, /* C991 (51601) */ + 3347, /* C992 (51602) */ + 3347, /* C993 (51603) */ + 3347, /* C994 (51604) */ + 3347, /* C995 (51605) */ + 3347, /* C996 (51606) */ + 3347, /* C997 (51607) */ + 3347, /* C998 (51608) */ + 3347, /* C999 (51609) */ + 3347, /* C99A (51610) */ + 3347, /* C99B (51611) */ + 3347, /* C99C (51612) */ + 3347, /* C99D (51613) */ + 3347, /* C99E (51614) */ + 3347, /* C99F (51615) */ + 3347, /* C9A0 (51616) */ + 3347, /* C9A1 (51617) */ + 3347, /* C9A2 (51618) */ + 3347, /* C9A3 (51619) */ + 3347, /* C9A4 (51620) */ + 3347, /* C9A5 (51621) */ + 3347, /* C9A6 (51622) */ + 3347, /* C9A7 (51623) */ + 3347, /* C9A8 (51624) */ + 3347, /* C9A9 (51625) */ + 3347, /* C9AA (51626) */ + 3347, /* C9AB (51627) */ + 3347, /* C9AC (51628) */ + 3347, /* C9AD (51629) */ + 3347, /* C9AE (51630) */ + 3347, /* C9AF (51631) */ + 3347, /* C9B0 (51632) */ + 3347, /* C9B1 (51633) */ + 3347, /* C9B2 (51634) */ + 3347, /* C9B3 (51635) */ + 3347, /* C9B4 (51636) */ + 3347, /* C9B5 (51637) */ + 3347, /* C9B6 (51638) */ + 3347, /* C9B7 (51639) */ + 3347, /* C9B8 (51640) */ + 3347, /* C9B9 (51641) */ + 3347, /* C9BA (51642) */ + 3347, /* C9BB (51643) */ + 3347, /* C9BC (51644) */ + 3347, /* C9BD (51645) */ + 3347, /* C9BE (51646) */ + 3347, /* C9BF (51647) */ + 3347, /* C9C0 (51648) */ + 3347, /* C9C1 (51649) */ + 3347, /* C9C2 (51650) */ + 3347, /* C9C3 (51651) */ + 3347, /* C9C4 (51652) */ + 3347, /* C9C5 (51653) */ + 3347, /* C9C6 (51654) */ + 3347, /* C9C7 (51655) */ + 3347, /* C9C8 (51656) */ + 3347, /* C9C9 (51657) */ + 3347, /* C9CA (51658) */ + 3347, /* C9CB (51659) */ + 3347, /* C9CC (51660) */ + 3347, /* C9CD (51661) */ + 3347, /* C9CE (51662) */ + 3347, /* C9CF (51663) */ + 3347, /* C9D0 (51664) */ + 3347, /* C9D1 (51665) */ + 3347, /* C9D2 (51666) */ + 3347, /* C9D3 (51667) */ + 3347, /* C9D4 (51668) */ + 3347, /* C9D5 (51669) */ + 3347, /* C9D6 (51670) */ + 3347, /* C9D7 (51671) */ + 3347, /* C9D8 (51672) */ + 3347, /* C9D9 (51673) */ + 3347, /* C9DA (51674) */ + 3347, /* C9DB (51675) */ + 3347, /* C9DC (51676) */ + 3347, /* C9DD (51677) */ + 3347, /* C9DE (51678) */ + 3347, /* C9DF (51679) */ + 3347, /* C9E0 (51680) */ + 3347, /* C9E1 (51681) */ + 3347, /* C9E2 (51682) */ + 3347, /* C9E3 (51683) */ + 3347, /* C9E4 (51684) */ + 3347, /* C9E5 (51685) */ + 3347, /* C9E6 (51686) */ + 3347, /* C9E7 (51687) */ + 3347, /* C9E8 (51688) */ + 3347, /* C9E9 (51689) */ + 3347, /* C9EA (51690) */ + 3347, /* C9EB (51691) */ + 3347, /* C9EC (51692) */ + 3347, /* C9ED (51693) */ + 3347, /* C9EE (51694) */ + 3347, /* C9EF (51695) */ + 3347, /* C9F0 (51696) */ + 3347, /* C9F1 (51697) */ + 3347, /* C9F2 (51698) */ + 3347, /* C9F3 (51699) */ + 3347, /* C9F4 (51700) */ + 3347, /* C9F5 (51701) */ + 3347, /* C9F6 (51702) */ + 3347, /* C9F7 (51703) */ + 3347, /* C9F8 (51704) */ + 3347, /* C9F9 (51705) */ + 3347, /* C9FA (51706) */ + 3347, /* C9FB (51707) */ + 3347, /* C9FC (51708) */ + 3347, /* C9FD (51709) */ + 3347, /* C9FE (51710) */ + 3347, /* C9FF (51711) */ + 3347, /* CA00 (51712) */ + 3347, /* CA01 (51713) */ + 3347, /* CA02 (51714) */ + 3347, /* CA03 (51715) */ + 3347, /* CA04 (51716) */ + 3347, /* CA05 (51717) */ + 3347, /* CA06 (51718) */ + 3347, /* CA07 (51719) */ + 3347, /* CA08 (51720) */ + 3347, /* CA09 (51721) */ + 3347, /* CA0A (51722) */ + 3347, /* CA0B (51723) */ + 3347, /* CA0C (51724) */ + 3347, /* CA0D (51725) */ + 3347, /* CA0E (51726) */ + 3347, /* CA0F (51727) */ + 3347, /* CA10 (51728) */ + 3347, /* CA11 (51729) */ + 3347, /* CA12 (51730) */ + 3347, /* CA13 (51731) */ + 3347, /* CA14 (51732) */ + 3347, /* CA15 (51733) */ + 3347, /* CA16 (51734) */ + 3347, /* CA17 (51735) */ + 3347, /* CA18 (51736) */ + 3347, /* CA19 (51737) */ + 3347, /* CA1A (51738) */ + 3347, /* CA1B (51739) */ + 3347, /* CA1C (51740) */ + 3347, /* CA1D (51741) */ + 3347, /* CA1E (51742) */ + 3347, /* CA1F (51743) */ + 3347, /* CA20 (51744) */ + 3347, /* CA21 (51745) */ + 3347, /* CA22 (51746) */ + 3347, /* CA23 (51747) */ + 3347, /* CA24 (51748) */ + 3347, /* CA25 (51749) */ + 3347, /* CA26 (51750) */ + 3347, /* CA27 (51751) */ + 3347, /* CA28 (51752) */ + 3347, /* CA29 (51753) */ + 3347, /* CA2A (51754) */ + 3347, /* CA2B (51755) */ + 3347, /* CA2C (51756) */ + 3347, /* CA2D (51757) */ + 3347, /* CA2E (51758) */ + 3347, /* CA2F (51759) */ + 3347, /* CA30 (51760) */ + 3347, /* CA31 (51761) */ + 3347, /* CA32 (51762) */ + 3347, /* CA33 (51763) */ + 3347, /* CA34 (51764) */ + 3347, /* CA35 (51765) */ + 3347, /* CA36 (51766) */ + 3347, /* CA37 (51767) */ + 3347, /* CA38 (51768) */ + 3347, /* CA39 (51769) */ + 3347, /* CA3A (51770) */ + 3347, /* CA3B (51771) */ + 3347, /* CA3C (51772) */ + 3347, /* CA3D (51773) */ + 3347, /* CA3E (51774) */ + 3347, /* CA3F (51775) */ + 3347, /* CA40 (51776) */ + 3347, /* CA41 (51777) */ + 3347, /* CA42 (51778) */ + 3347, /* CA43 (51779) */ + 3347, /* CA44 (51780) */ + 3347, /* CA45 (51781) */ + 3347, /* CA46 (51782) */ + 3347, /* CA47 (51783) */ + 3347, /* CA48 (51784) */ + 3347, /* CA49 (51785) */ + 3347, /* CA4A (51786) */ + 3347, /* CA4B (51787) */ + 3347, /* CA4C (51788) */ + 3347, /* CA4D (51789) */ + 3347, /* CA4E (51790) */ + 3347, /* CA4F (51791) */ + 3347, /* CA50 (51792) */ + 3347, /* CA51 (51793) */ + 3347, /* CA52 (51794) */ + 3347, /* CA53 (51795) */ + 3347, /* CA54 (51796) */ + 3347, /* CA55 (51797) */ + 3347, /* CA56 (51798) */ + 3347, /* CA57 (51799) */ + 3347, /* CA58 (51800) */ + 3347, /* CA59 (51801) */ + 3347, /* CA5A (51802) */ + 3347, /* CA5B (51803) */ + 3347, /* CA5C (51804) */ + 3347, /* CA5D (51805) */ + 3347, /* CA5E (51806) */ + 3347, /* CA5F (51807) */ + 3347, /* CA60 (51808) */ + 3347, /* CA61 (51809) */ + 3347, /* CA62 (51810) */ + 3347, /* CA63 (51811) */ + 3347, /* CA64 (51812) */ + 3347, /* CA65 (51813) */ + 3347, /* CA66 (51814) */ + 3347, /* CA67 (51815) */ + 3347, /* CA68 (51816) */ + 3347, /* CA69 (51817) */ + 3347, /* CA6A (51818) */ + 3347, /* CA6B (51819) */ + 3347, /* CA6C (51820) */ + 3347, /* CA6D (51821) */ + 3347, /* CA6E (51822) */ + 3347, /* CA6F (51823) */ + 3347, /* CA70 (51824) */ + 3347, /* CA71 (51825) */ + 3347, /* CA72 (51826) */ + 3347, /* CA73 (51827) */ + 3347, /* CA74 (51828) */ + 3347, /* CA75 (51829) */ + 3347, /* CA76 (51830) */ + 3347, /* CA77 (51831) */ + 3347, /* CA78 (51832) */ + 3347, /* CA79 (51833) */ + 3347, /* CA7A (51834) */ + 3347, /* CA7B (51835) */ + 3347, /* CA7C (51836) */ + 3347, /* CA7D (51837) */ + 3347, /* CA7E (51838) */ + 3347, /* CA7F (51839) */ + 3347, /* CA80 (51840) */ + 3347, /* CA81 (51841) */ + 3347, /* CA82 (51842) */ + 3347, /* CA83 (51843) */ + 3347, /* CA84 (51844) */ + 3347, /* CA85 (51845) */ + 3347, /* CA86 (51846) */ + 3347, /* CA87 (51847) */ + 3347, /* CA88 (51848) */ + 3347, /* CA89 (51849) */ + 3347, /* CA8A (51850) */ + 3347, /* CA8B (51851) */ + 3347, /* CA8C (51852) */ + 3347, /* CA8D (51853) */ + 3347, /* CA8E (51854) */ + 3347, /* CA8F (51855) */ + 3347, /* CA90 (51856) */ + 3347, /* CA91 (51857) */ + 3347, /* CA92 (51858) */ + 3347, /* CA93 (51859) */ + 3347, /* CA94 (51860) */ + 3347, /* CA95 (51861) */ + 3347, /* CA96 (51862) */ + 3347, /* CA97 (51863) */ + 3347, /* CA98 (51864) */ + 3347, /* CA99 (51865) */ + 3347, /* CA9A (51866) */ + 3347, /* CA9B (51867) */ + 3347, /* CA9C (51868) */ + 3347, /* CA9D (51869) */ + 3347, /* CA9E (51870) */ + 3347, /* CA9F (51871) */ + 3347, /* CAA0 (51872) */ + 3347, /* CAA1 (51873) */ + 3347, /* CAA2 (51874) */ + 3347, /* CAA3 (51875) */ + 3347, /* CAA4 (51876) */ + 3347, /* CAA5 (51877) */ + 3347, /* CAA6 (51878) */ + 3347, /* CAA7 (51879) */ + 3347, /* CAA8 (51880) */ + 3347, /* CAA9 (51881) */ + 3347, /* CAAA (51882) */ + 3347, /* CAAB (51883) */ + 3347, /* CAAC (51884) */ + 3347, /* CAAD (51885) */ + 3347, /* CAAE (51886) */ + 3347, /* CAAF (51887) */ + 3347, /* CAB0 (51888) */ + 3347, /* CAB1 (51889) */ + 3347, /* CAB2 (51890) */ + 3347, /* CAB3 (51891) */ + 3347, /* CAB4 (51892) */ + 3347, /* CAB5 (51893) */ + 3347, /* CAB6 (51894) */ + 3347, /* CAB7 (51895) */ + 3347, /* CAB8 (51896) */ + 3347, /* CAB9 (51897) */ + 3347, /* CABA (51898) */ + 3347, /* CABB (51899) */ + 3347, /* CABC (51900) */ + 3347, /* CABD (51901) */ + 3347, /* CABE (51902) */ + 3347, /* CABF (51903) */ + 3347, /* CAC0 (51904) */ + 3347, /* CAC1 (51905) */ + 3347, /* CAC2 (51906) */ + 3347, /* CAC3 (51907) */ + 3347, /* CAC4 (51908) */ + 3347, /* CAC5 (51909) */ + 3347, /* CAC6 (51910) */ + 3347, /* CAC7 (51911) */ + 3347, /* CAC8 (51912) */ + 3347, /* CAC9 (51913) */ + 3347, /* CACA (51914) */ + 3347, /* CACB (51915) */ + 3347, /* CACC (51916) */ + 3347, /* CACD (51917) */ + 3347, /* CACE (51918) */ + 3347, /* CACF (51919) */ + 3347, /* CAD0 (51920) */ + 3347, /* CAD1 (51921) */ + 3347, /* CAD2 (51922) */ + 3347, /* CAD3 (51923) */ + 3347, /* CAD4 (51924) */ + 3347, /* CAD5 (51925) */ + 3347, /* CAD6 (51926) */ + 3347, /* CAD7 (51927) */ + 3347, /* CAD8 (51928) */ + 3347, /* CAD9 (51929) */ + 3347, /* CADA (51930) */ + 3347, /* CADB (51931) */ + 3347, /* CADC (51932) */ + 3347, /* CADD (51933) */ + 3347, /* CADE (51934) */ + 3347, /* CADF (51935) */ + 3347, /* CAE0 (51936) */ + 3347, /* CAE1 (51937) */ + 3347, /* CAE2 (51938) */ + 3347, /* CAE3 (51939) */ + 3347, /* CAE4 (51940) */ + 3347, /* CAE5 (51941) */ + 3347, /* CAE6 (51942) */ + 3347, /* CAE7 (51943) */ + 3347, /* CAE8 (51944) */ + 3347, /* CAE9 (51945) */ + 3347, /* CAEA (51946) */ + 3347, /* CAEB (51947) */ + 3347, /* CAEC (51948) */ + 3347, /* CAED (51949) */ + 3347, /* CAEE (51950) */ + 3347, /* CAEF (51951) */ + 3347, /* CAF0 (51952) */ + 3347, /* CAF1 (51953) */ + 3347, /* CAF2 (51954) */ + 3347, /* CAF3 (51955) */ + 3347, /* CAF4 (51956) */ + 3347, /* CAF5 (51957) */ + 3347, /* CAF6 (51958) */ + 3347, /* CAF7 (51959) */ + 3347, /* CAF8 (51960) */ + 3347, /* CAF9 (51961) */ + 3347, /* CAFA (51962) */ + 3347, /* CAFB (51963) */ + 3347, /* CAFC (51964) */ + 3347, /* CAFD (51965) */ + 3347, /* CAFE (51966) */ + 3347, /* CAFF (51967) */ + 3347, /* CB00 (51968) */ + 3347, /* CB01 (51969) */ + 3347, /* CB02 (51970) */ + 3347, /* CB03 (51971) */ + 3347, /* CB04 (51972) */ + 3347, /* CB05 (51973) */ + 3347, /* CB06 (51974) */ + 3347, /* CB07 (51975) */ + 3347, /* CB08 (51976) */ + 3347, /* CB09 (51977) */ + 3347, /* CB0A (51978) */ + 3347, /* CB0B (51979) */ + 3347, /* CB0C (51980) */ + 3347, /* CB0D (51981) */ + 3347, /* CB0E (51982) */ + 3347, /* CB0F (51983) */ + 3347, /* CB10 (51984) */ + 3347, /* CB11 (51985) */ + 3347, /* CB12 (51986) */ + 3347, /* CB13 (51987) */ + 3347, /* CB14 (51988) */ + 3347, /* CB15 (51989) */ + 3347, /* CB16 (51990) */ + 3347, /* CB17 (51991) */ + 3347, /* CB18 (51992) */ + 3347, /* CB19 (51993) */ + 3347, /* CB1A (51994) */ + 3347, /* CB1B (51995) */ + 3347, /* CB1C (51996) */ + 3347, /* CB1D (51997) */ + 3347, /* CB1E (51998) */ + 3347, /* CB1F (51999) */ + 3347, /* CB20 (52000) */ + 3347, /* CB21 (52001) */ + 3347, /* CB22 (52002) */ + 3347, /* CB23 (52003) */ + 3347, /* CB24 (52004) */ + 3347, /* CB25 (52005) */ + 3347, /* CB26 (52006) */ + 3347, /* CB27 (52007) */ + 3347, /* CB28 (52008) */ + 3347, /* CB29 (52009) */ + 3347, /* CB2A (52010) */ + 3347, /* CB2B (52011) */ + 3347, /* CB2C (52012) */ + 3347, /* CB2D (52013) */ + 3347, /* CB2E (52014) */ + 3347, /* CB2F (52015) */ + 3347, /* CB30 (52016) */ + 3347, /* CB31 (52017) */ + 3347, /* CB32 (52018) */ + 3347, /* CB33 (52019) */ + 3347, /* CB34 (52020) */ + 3347, /* CB35 (52021) */ + 3347, /* CB36 (52022) */ + 3347, /* CB37 (52023) */ + 3347, /* CB38 (52024) */ + 3347, /* CB39 (52025) */ + 3347, /* CB3A (52026) */ + 3347, /* CB3B (52027) */ + 3347, /* CB3C (52028) */ + 3347, /* CB3D (52029) */ + 3347, /* CB3E (52030) */ + 3347, /* CB3F (52031) */ + 3347, /* CB40 (52032) */ + 3347, /* CB41 (52033) */ + 3347, /* CB42 (52034) */ + 3347, /* CB43 (52035) */ + 3347, /* CB44 (52036) */ + 3347, /* CB45 (52037) */ + 3347, /* CB46 (52038) */ + 3347, /* CB47 (52039) */ + 3347, /* CB48 (52040) */ + 3347, /* CB49 (52041) */ + 3347, /* CB4A (52042) */ + 3347, /* CB4B (52043) */ + 3347, /* CB4C (52044) */ + 3347, /* CB4D (52045) */ + 3347, /* CB4E (52046) */ + 3347, /* CB4F (52047) */ + 3347, /* CB50 (52048) */ + 3347, /* CB51 (52049) */ + 3347, /* CB52 (52050) */ + 3347, /* CB53 (52051) */ + 3347, /* CB54 (52052) */ + 3347, /* CB55 (52053) */ + 3347, /* CB56 (52054) */ + 3347, /* CB57 (52055) */ + 3347, /* CB58 (52056) */ + 3347, /* CB59 (52057) */ + 3347, /* CB5A (52058) */ + 3347, /* CB5B (52059) */ + 3347, /* CB5C (52060) */ + 3347, /* CB5D (52061) */ + 3347, /* CB5E (52062) */ + 3347, /* CB5F (52063) */ + 3347, /* CB60 (52064) */ + 3347, /* CB61 (52065) */ + 3347, /* CB62 (52066) */ + 3347, /* CB63 (52067) */ + 3347, /* CB64 (52068) */ + 3347, /* CB65 (52069) */ + 3347, /* CB66 (52070) */ + 3347, /* CB67 (52071) */ + 3347, /* CB68 (52072) */ + 3347, /* CB69 (52073) */ + 3347, /* CB6A (52074) */ + 3347, /* CB6B (52075) */ + 3347, /* CB6C (52076) */ + 3347, /* CB6D (52077) */ + 3347, /* CB6E (52078) */ + 3347, /* CB6F (52079) */ + 3347, /* CB70 (52080) */ + 3347, /* CB71 (52081) */ + 3347, /* CB72 (52082) */ + 3347, /* CB73 (52083) */ + 3347, /* CB74 (52084) */ + 3347, /* CB75 (52085) */ + 3347, /* CB76 (52086) */ + 3347, /* CB77 (52087) */ + 3347, /* CB78 (52088) */ + 3347, /* CB79 (52089) */ + 3347, /* CB7A (52090) */ + 3347, /* CB7B (52091) */ + 3347, /* CB7C (52092) */ + 3347, /* CB7D (52093) */ + 3347, /* CB7E (52094) */ + 3347, /* CB7F (52095) */ + 3347, /* CB80 (52096) */ + 3347, /* CB81 (52097) */ + 3347, /* CB82 (52098) */ + 3347, /* CB83 (52099) */ + 3347, /* CB84 (52100) */ + 3347, /* CB85 (52101) */ + 3347, /* CB86 (52102) */ + 3347, /* CB87 (52103) */ + 3347, /* CB88 (52104) */ + 3347, /* CB89 (52105) */ + 3347, /* CB8A (52106) */ + 3347, /* CB8B (52107) */ + 3347, /* CB8C (52108) */ + 3347, /* CB8D (52109) */ + 3347, /* CB8E (52110) */ + 3347, /* CB8F (52111) */ + 3347, /* CB90 (52112) */ + 3347, /* CB91 (52113) */ + 3347, /* CB92 (52114) */ + 3347, /* CB93 (52115) */ + 3347, /* CB94 (52116) */ + 3347, /* CB95 (52117) */ + 3347, /* CB96 (52118) */ + 3347, /* CB97 (52119) */ + 3347, /* CB98 (52120) */ + 3347, /* CB99 (52121) */ + 3347, /* CB9A (52122) */ + 3347, /* CB9B (52123) */ + 3347, /* CB9C (52124) */ + 3347, /* CB9D (52125) */ + 3347, /* CB9E (52126) */ + 3347, /* CB9F (52127) */ + 3347, /* CBA0 (52128) */ + 3347, /* CBA1 (52129) */ + 3347, /* CBA2 (52130) */ + 3347, /* CBA3 (52131) */ + 3347, /* CBA4 (52132) */ + 3347, /* CBA5 (52133) */ + 3347, /* CBA6 (52134) */ + 3347, /* CBA7 (52135) */ + 3347, /* CBA8 (52136) */ + 3347, /* CBA9 (52137) */ + 3347, /* CBAA (52138) */ + 3347, /* CBAB (52139) */ + 3347, /* CBAC (52140) */ + 3347, /* CBAD (52141) */ + 3347, /* CBAE (52142) */ + 3347, /* CBAF (52143) */ + 3347, /* CBB0 (52144) */ + 3347, /* CBB1 (52145) */ + 3347, /* CBB2 (52146) */ + 3347, /* CBB3 (52147) */ + 3347, /* CBB4 (52148) */ + 3347, /* CBB5 (52149) */ + 3347, /* CBB6 (52150) */ + 3347, /* CBB7 (52151) */ + 3347, /* CBB8 (52152) */ + 3347, /* CBB9 (52153) */ + 3347, /* CBBA (52154) */ + 3347, /* CBBB (52155) */ + 3347, /* CBBC (52156) */ + 3347, /* CBBD (52157) */ + 3347, /* CBBE (52158) */ + 3347, /* CBBF (52159) */ + 3347, /* CBC0 (52160) */ + 3347, /* CBC1 (52161) */ + 3347, /* CBC2 (52162) */ + 3347, /* CBC3 (52163) */ + 3347, /* CBC4 (52164) */ + 3347, /* CBC5 (52165) */ + 3347, /* CBC6 (52166) */ + 3347, /* CBC7 (52167) */ + 3347, /* CBC8 (52168) */ + 3347, /* CBC9 (52169) */ + 3347, /* CBCA (52170) */ + 3347, /* CBCB (52171) */ + 3347, /* CBCC (52172) */ + 3347, /* CBCD (52173) */ + 3347, /* CBCE (52174) */ + 3347, /* CBCF (52175) */ + 3347, /* CBD0 (52176) */ + 3347, /* CBD1 (52177) */ + 3347, /* CBD2 (52178) */ + 3347, /* CBD3 (52179) */ + 3347, /* CBD4 (52180) */ + 3347, /* CBD5 (52181) */ + 3347, /* CBD6 (52182) */ + 3347, /* CBD7 (52183) */ + 3347, /* CBD8 (52184) */ + 3347, /* CBD9 (52185) */ + 3347, /* CBDA (52186) */ + 3347, /* CBDB (52187) */ + 3347, /* CBDC (52188) */ + 3347, /* CBDD (52189) */ + 3347, /* CBDE (52190) */ + 3347, /* CBDF (52191) */ + 3347, /* CBE0 (52192) */ + 3347, /* CBE1 (52193) */ + 3347, /* CBE2 (52194) */ + 3347, /* CBE3 (52195) */ + 3347, /* CBE4 (52196) */ + 3347, /* CBE5 (52197) */ + 3347, /* CBE6 (52198) */ + 3347, /* CBE7 (52199) */ + 3347, /* CBE8 (52200) */ + 3347, /* CBE9 (52201) */ + 3347, /* CBEA (52202) */ + 3347, /* CBEB (52203) */ + 3347, /* CBEC (52204) */ + 3347, /* CBED (52205) */ + 3347, /* CBEE (52206) */ + 3347, /* CBEF (52207) */ + 3347, /* CBF0 (52208) */ + 3347, /* CBF1 (52209) */ + 3347, /* CBF2 (52210) */ + 3347, /* CBF3 (52211) */ + 3347, /* CBF4 (52212) */ + 3347, /* CBF5 (52213) */ + 3347, /* CBF6 (52214) */ + 3347, /* CBF7 (52215) */ + 3347, /* CBF8 (52216) */ + 3347, /* CBF9 (52217) */ + 3347, /* CBFA (52218) */ + 3347, /* CBFB (52219) */ + 3347, /* CBFC (52220) */ + 3347, /* CBFD (52221) */ + 3347, /* CBFE (52222) */ + 3347, /* CBFF (52223) */ + 3347, /* CC00 (52224) */ + 3347, /* CC01 (52225) */ + 3347, /* CC02 (52226) */ + 3347, /* CC03 (52227) */ + 3347, /* CC04 (52228) */ + 3347, /* CC05 (52229) */ + 3347, /* CC06 (52230) */ + 3347, /* CC07 (52231) */ + 3347, /* CC08 (52232) */ + 3347, /* CC09 (52233) */ + 3347, /* CC0A (52234) */ + 3347, /* CC0B (52235) */ + 3347, /* CC0C (52236) */ + 3347, /* CC0D (52237) */ + 3347, /* CC0E (52238) */ + 3347, /* CC0F (52239) */ + 3347, /* CC10 (52240) */ + 3347, /* CC11 (52241) */ + 3347, /* CC12 (52242) */ + 3347, /* CC13 (52243) */ + 3347, /* CC14 (52244) */ + 3347, /* CC15 (52245) */ + 3347, /* CC16 (52246) */ + 3347, /* CC17 (52247) */ + 3347, /* CC18 (52248) */ + 3347, /* CC19 (52249) */ + 3347, /* CC1A (52250) */ + 3347, /* CC1B (52251) */ + 3347, /* CC1C (52252) */ + 3347, /* CC1D (52253) */ + 3347, /* CC1E (52254) */ + 3347, /* CC1F (52255) */ + 3347, /* CC20 (52256) */ + 3347, /* CC21 (52257) */ + 3347, /* CC22 (52258) */ + 3347, /* CC23 (52259) */ + 3347, /* CC24 (52260) */ + 3347, /* CC25 (52261) */ + 3347, /* CC26 (52262) */ + 3347, /* CC27 (52263) */ + 3347, /* CC28 (52264) */ + 3347, /* CC29 (52265) */ + 3347, /* CC2A (52266) */ + 3347, /* CC2B (52267) */ + 3347, /* CC2C (52268) */ + 3347, /* CC2D (52269) */ + 3347, /* CC2E (52270) */ + 3347, /* CC2F (52271) */ + 3347, /* CC30 (52272) */ + 3347, /* CC31 (52273) */ + 3347, /* CC32 (52274) */ + 3347, /* CC33 (52275) */ + 3347, /* CC34 (52276) */ + 3347, /* CC35 (52277) */ + 3347, /* CC36 (52278) */ + 3347, /* CC37 (52279) */ + 3347, /* CC38 (52280) */ + 3347, /* CC39 (52281) */ + 3347, /* CC3A (52282) */ + 3347, /* CC3B (52283) */ + 3347, /* CC3C (52284) */ + 3347, /* CC3D (52285) */ + 3347, /* CC3E (52286) */ + 3347, /* CC3F (52287) */ + 3347, /* CC40 (52288) */ + 3347, /* CC41 (52289) */ + 3347, /* CC42 (52290) */ + 3347, /* CC43 (52291) */ + 3347, /* CC44 (52292) */ + 3347, /* CC45 (52293) */ + 3347, /* CC46 (52294) */ + 3347, /* CC47 (52295) */ + 3347, /* CC48 (52296) */ + 3347, /* CC49 (52297) */ + 3347, /* CC4A (52298) */ + 3347, /* CC4B (52299) */ + 3347, /* CC4C (52300) */ + 3347, /* CC4D (52301) */ + 3347, /* CC4E (52302) */ + 3347, /* CC4F (52303) */ + 3347, /* CC50 (52304) */ + 3347, /* CC51 (52305) */ + 3347, /* CC52 (52306) */ + 3347, /* CC53 (52307) */ + 3347, /* CC54 (52308) */ + 3347, /* CC55 (52309) */ + 3347, /* CC56 (52310) */ + 3347, /* CC57 (52311) */ + 3347, /* CC58 (52312) */ + 3347, /* CC59 (52313) */ + 3347, /* CC5A (52314) */ + 3347, /* CC5B (52315) */ + 3347, /* CC5C (52316) */ + 3347, /* CC5D (52317) */ + 3347, /* CC5E (52318) */ + 3347, /* CC5F (52319) */ + 3347, /* CC60 (52320) */ + 3347, /* CC61 (52321) */ + 3347, /* CC62 (52322) */ + 3347, /* CC63 (52323) */ + 3347, /* CC64 (52324) */ + 3347, /* CC65 (52325) */ + 3347, /* CC66 (52326) */ + 3347, /* CC67 (52327) */ + 3347, /* CC68 (52328) */ + 3347, /* CC69 (52329) */ + 3347, /* CC6A (52330) */ + 3347, /* CC6B (52331) */ + 3347, /* CC6C (52332) */ + 3347, /* CC6D (52333) */ + 3347, /* CC6E (52334) */ + 3347, /* CC6F (52335) */ + 3347, /* CC70 (52336) */ + 3347, /* CC71 (52337) */ + 3347, /* CC72 (52338) */ + 3347, /* CC73 (52339) */ + 3347, /* CC74 (52340) */ + 3347, /* CC75 (52341) */ + 3347, /* CC76 (52342) */ + 3347, /* CC77 (52343) */ + 3347, /* CC78 (52344) */ + 3347, /* CC79 (52345) */ + 3347, /* CC7A (52346) */ + 3347, /* CC7B (52347) */ + 3347, /* CC7C (52348) */ + 3347, /* CC7D (52349) */ + 3347, /* CC7E (52350) */ + 3347, /* CC7F (52351) */ + 3347, /* CC80 (52352) */ + 3347, /* CC81 (52353) */ + 3347, /* CC82 (52354) */ + 3347, /* CC83 (52355) */ + 3347, /* CC84 (52356) */ + 3347, /* CC85 (52357) */ + 3347, /* CC86 (52358) */ + 3347, /* CC87 (52359) */ + 3347, /* CC88 (52360) */ + 3347, /* CC89 (52361) */ + 3347, /* CC8A (52362) */ + 3347, /* CC8B (52363) */ + 3347, /* CC8C (52364) */ + 3347, /* CC8D (52365) */ + 3347, /* CC8E (52366) */ + 3347, /* CC8F (52367) */ + 3347, /* CC90 (52368) */ + 3347, /* CC91 (52369) */ + 3347, /* CC92 (52370) */ + 3347, /* CC93 (52371) */ + 3347, /* CC94 (52372) */ + 3347, /* CC95 (52373) */ + 3347, /* CC96 (52374) */ + 3347, /* CC97 (52375) */ + 3347, /* CC98 (52376) */ + 3347, /* CC99 (52377) */ + 3347, /* CC9A (52378) */ + 3347, /* CC9B (52379) */ + 3347, /* CC9C (52380) */ + 3347, /* CC9D (52381) */ + 3347, /* CC9E (52382) */ + 3347, /* CC9F (52383) */ + 3347, /* CCA0 (52384) */ + 3347, /* CCA1 (52385) */ + 3347, /* CCA2 (52386) */ + 3347, /* CCA3 (52387) */ + 3347, /* CCA4 (52388) */ + 3347, /* CCA5 (52389) */ + 3347, /* CCA6 (52390) */ + 3347, /* CCA7 (52391) */ + 3347, /* CCA8 (52392) */ + 3347, /* CCA9 (52393) */ + 3347, /* CCAA (52394) */ + 3347, /* CCAB (52395) */ + 3347, /* CCAC (52396) */ + 3347, /* CCAD (52397) */ + 3347, /* CCAE (52398) */ + 3347, /* CCAF (52399) */ + 3347, /* CCB0 (52400) */ + 3347, /* CCB1 (52401) */ + 3347, /* CCB2 (52402) */ + 3347, /* CCB3 (52403) */ + 3347, /* CCB4 (52404) */ + 3347, /* CCB5 (52405) */ + 3347, /* CCB6 (52406) */ + 3347, /* CCB7 (52407) */ + 3347, /* CCB8 (52408) */ + 3347, /* CCB9 (52409) */ + 3347, /* CCBA (52410) */ + 3347, /* CCBB (52411) */ + 3347, /* CCBC (52412) */ + 3347, /* CCBD (52413) */ + 3347, /* CCBE (52414) */ + 3347, /* CCBF (52415) */ + 3347, /* CCC0 (52416) */ + 3347, /* CCC1 (52417) */ + 3347, /* CCC2 (52418) */ + 3347, /* CCC3 (52419) */ + 3347, /* CCC4 (52420) */ + 3347, /* CCC5 (52421) */ + 3347, /* CCC6 (52422) */ + 3347, /* CCC7 (52423) */ + 3347, /* CCC8 (52424) */ + 3347, /* CCC9 (52425) */ + 3347, /* CCCA (52426) */ + 3347, /* CCCB (52427) */ + 3347, /* CCCC (52428) */ + 3347, /* CCCD (52429) */ + 3347, /* CCCE (52430) */ + 3347, /* CCCF (52431) */ + 3347, /* CCD0 (52432) */ + 3347, /* CCD1 (52433) */ + 3347, /* CCD2 (52434) */ + 3347, /* CCD3 (52435) */ + 3347, /* CCD4 (52436) */ + 3347, /* CCD5 (52437) */ + 3347, /* CCD6 (52438) */ + 3347, /* CCD7 (52439) */ + 3347, /* CCD8 (52440) */ + 3347, /* CCD9 (52441) */ + 3347, /* CCDA (52442) */ + 3347, /* CCDB (52443) */ + 3347, /* CCDC (52444) */ + 3347, /* CCDD (52445) */ + 3347, /* CCDE (52446) */ + 3347, /* CCDF (52447) */ + 3347, /* CCE0 (52448) */ + 3347, /* CCE1 (52449) */ + 3347, /* CCE2 (52450) */ + 3347, /* CCE3 (52451) */ + 3347, /* CCE4 (52452) */ + 3347, /* CCE5 (52453) */ + 3347, /* CCE6 (52454) */ + 3347, /* CCE7 (52455) */ + 3347, /* CCE8 (52456) */ + 3347, /* CCE9 (52457) */ + 3347, /* CCEA (52458) */ + 3347, /* CCEB (52459) */ + 3347, /* CCEC (52460) */ + 3347, /* CCED (52461) */ + 3347, /* CCEE (52462) */ + 3347, /* CCEF (52463) */ + 3347, /* CCF0 (52464) */ + 3347, /* CCF1 (52465) */ + 3347, /* CCF2 (52466) */ + 3347, /* CCF3 (52467) */ + 3347, /* CCF4 (52468) */ + 3347, /* CCF5 (52469) */ + 3347, /* CCF6 (52470) */ + 3347, /* CCF7 (52471) */ + 3347, /* CCF8 (52472) */ + 3347, /* CCF9 (52473) */ + 3347, /* CCFA (52474) */ + 3347, /* CCFB (52475) */ + 3347, /* CCFC (52476) */ + 3347, /* CCFD (52477) */ + 3347, /* CCFE (52478) */ + 3347, /* CCFF (52479) */ + 3347, /* CD00 (52480) */ + 3347, /* CD01 (52481) */ + 3347, /* CD02 (52482) */ + 3347, /* CD03 (52483) */ + 3347, /* CD04 (52484) */ + 3347, /* CD05 (52485) */ + 3347, /* CD06 (52486) */ + 3347, /* CD07 (52487) */ + 3347, /* CD08 (52488) */ + 3347, /* CD09 (52489) */ + 3347, /* CD0A (52490) */ + 3347, /* CD0B (52491) */ + 3347, /* CD0C (52492) */ + 3347, /* CD0D (52493) */ + 3347, /* CD0E (52494) */ + 3347, /* CD0F (52495) */ + 3347, /* CD10 (52496) */ + 3347, /* CD11 (52497) */ + 3347, /* CD12 (52498) */ + 3347, /* CD13 (52499) */ + 3347, /* CD14 (52500) */ + 3347, /* CD15 (52501) */ + 3347, /* CD16 (52502) */ + 3347, /* CD17 (52503) */ + 3347, /* CD18 (52504) */ + 3347, /* CD19 (52505) */ + 3347, /* CD1A (52506) */ + 3347, /* CD1B (52507) */ + 3347, /* CD1C (52508) */ + 3347, /* CD1D (52509) */ + 3347, /* CD1E (52510) */ + 3347, /* CD1F (52511) */ + 3347, /* CD20 (52512) */ + 3347, /* CD21 (52513) */ + 3347, /* CD22 (52514) */ + 3347, /* CD23 (52515) */ + 3347, /* CD24 (52516) */ + 3347, /* CD25 (52517) */ + 3347, /* CD26 (52518) */ + 3347, /* CD27 (52519) */ + 3347, /* CD28 (52520) */ + 3347, /* CD29 (52521) */ + 3347, /* CD2A (52522) */ + 3347, /* CD2B (52523) */ + 3347, /* CD2C (52524) */ + 3347, /* CD2D (52525) */ + 3347, /* CD2E (52526) */ + 3347, /* CD2F (52527) */ + 3347, /* CD30 (52528) */ + 3347, /* CD31 (52529) */ + 3347, /* CD32 (52530) */ + 3347, /* CD33 (52531) */ + 3347, /* CD34 (52532) */ + 3347, /* CD35 (52533) */ + 3347, /* CD36 (52534) */ + 3347, /* CD37 (52535) */ + 3347, /* CD38 (52536) */ + 3347, /* CD39 (52537) */ + 3347, /* CD3A (52538) */ + 3347, /* CD3B (52539) */ + 3347, /* CD3C (52540) */ + 3347, /* CD3D (52541) */ + 3347, /* CD3E (52542) */ + 3347, /* CD3F (52543) */ + 3347, /* CD40 (52544) */ + 3347, /* CD41 (52545) */ + 3347, /* CD42 (52546) */ + 3347, /* CD43 (52547) */ + 3347, /* CD44 (52548) */ + 3347, /* CD45 (52549) */ + 3347, /* CD46 (52550) */ + 3347, /* CD47 (52551) */ + 3347, /* CD48 (52552) */ + 3347, /* CD49 (52553) */ + 3347, /* CD4A (52554) */ + 3347, /* CD4B (52555) */ + 3347, /* CD4C (52556) */ + 3347, /* CD4D (52557) */ + 3347, /* CD4E (52558) */ + 3347, /* CD4F (52559) */ + 3347, /* CD50 (52560) */ + 3347, /* CD51 (52561) */ + 3347, /* CD52 (52562) */ + 3347, /* CD53 (52563) */ + 3347, /* CD54 (52564) */ + 3347, /* CD55 (52565) */ + 3347, /* CD56 (52566) */ + 3347, /* CD57 (52567) */ + 3347, /* CD58 (52568) */ + 3347, /* CD59 (52569) */ + 3347, /* CD5A (52570) */ + 3347, /* CD5B (52571) */ + 3347, /* CD5C (52572) */ + 3347, /* CD5D (52573) */ + 3347, /* CD5E (52574) */ + 3347, /* CD5F (52575) */ + 3347, /* CD60 (52576) */ + 3347, /* CD61 (52577) */ + 3347, /* CD62 (52578) */ + 3347, /* CD63 (52579) */ + 3347, /* CD64 (52580) */ + 3347, /* CD65 (52581) */ + 3347, /* CD66 (52582) */ + 3347, /* CD67 (52583) */ + 3347, /* CD68 (52584) */ + 3347, /* CD69 (52585) */ + 3347, /* CD6A (52586) */ + 3347, /* CD6B (52587) */ + 3347, /* CD6C (52588) */ + 3347, /* CD6D (52589) */ + 3347, /* CD6E (52590) */ + 3347, /* CD6F (52591) */ + 3347, /* CD70 (52592) */ + 3347, /* CD71 (52593) */ + 3347, /* CD72 (52594) */ + 3347, /* CD73 (52595) */ + 3347, /* CD74 (52596) */ + 3347, /* CD75 (52597) */ + 3347, /* CD76 (52598) */ + 3347, /* CD77 (52599) */ + 3347, /* CD78 (52600) */ + 3347, /* CD79 (52601) */ + 3347, /* CD7A (52602) */ + 3347, /* CD7B (52603) */ + 3347, /* CD7C (52604) */ + 3347, /* CD7D (52605) */ + 3347, /* CD7E (52606) */ + 3347, /* CD7F (52607) */ + 3347, /* CD80 (52608) */ + 3347, /* CD81 (52609) */ + 3347, /* CD82 (52610) */ + 3347, /* CD83 (52611) */ + 3347, /* CD84 (52612) */ + 3347, /* CD85 (52613) */ + 3347, /* CD86 (52614) */ + 3347, /* CD87 (52615) */ + 3347, /* CD88 (52616) */ + 3347, /* CD89 (52617) */ + 3347, /* CD8A (52618) */ + 3347, /* CD8B (52619) */ + 3347, /* CD8C (52620) */ + 3347, /* CD8D (52621) */ + 3347, /* CD8E (52622) */ + 3347, /* CD8F (52623) */ + 3347, /* CD90 (52624) */ + 3347, /* CD91 (52625) */ + 3347, /* CD92 (52626) */ + 3347, /* CD93 (52627) */ + 3347, /* CD94 (52628) */ + 3347, /* CD95 (52629) */ + 3347, /* CD96 (52630) */ + 3347, /* CD97 (52631) */ + 3347, /* CD98 (52632) */ + 3347, /* CD99 (52633) */ + 3347, /* CD9A (52634) */ + 3347, /* CD9B (52635) */ + 3347, /* CD9C (52636) */ + 3347, /* CD9D (52637) */ + 3347, /* CD9E (52638) */ + 3347, /* CD9F (52639) */ + 3347, /* CDA0 (52640) */ + 3347, /* CDA1 (52641) */ + 3347, /* CDA2 (52642) */ + 3347, /* CDA3 (52643) */ + 3347, /* CDA4 (52644) */ + 3347, /* CDA5 (52645) */ + 3347, /* CDA6 (52646) */ + 3347, /* CDA7 (52647) */ + 3347, /* CDA8 (52648) */ + 3347, /* CDA9 (52649) */ + 3347, /* CDAA (52650) */ + 3347, /* CDAB (52651) */ + 3347, /* CDAC (52652) */ + 3347, /* CDAD (52653) */ + 3347, /* CDAE (52654) */ + 3347, /* CDAF (52655) */ + 3347, /* CDB0 (52656) */ + 3347, /* CDB1 (52657) */ + 3347, /* CDB2 (52658) */ + 3347, /* CDB3 (52659) */ + 3347, /* CDB4 (52660) */ + 3347, /* CDB5 (52661) */ + 3347, /* CDB6 (52662) */ + 3347, /* CDB7 (52663) */ + 3347, /* CDB8 (52664) */ + 3347, /* CDB9 (52665) */ + 3347, /* CDBA (52666) */ + 3347, /* CDBB (52667) */ + 3347, /* CDBC (52668) */ + 3347, /* CDBD (52669) */ + 3347, /* CDBE (52670) */ + 3347, /* CDBF (52671) */ + 3347, /* CDC0 (52672) */ + 3347, /* CDC1 (52673) */ + 3347, /* CDC2 (52674) */ + 3347, /* CDC3 (52675) */ + 3347, /* CDC4 (52676) */ + 3347, /* CDC5 (52677) */ + 3347, /* CDC6 (52678) */ + 3347, /* CDC7 (52679) */ + 3347, /* CDC8 (52680) */ + 3347, /* CDC9 (52681) */ + 3347, /* CDCA (52682) */ + 3347, /* CDCB (52683) */ + 3347, /* CDCC (52684) */ + 3347, /* CDCD (52685) */ + 3347, /* CDCE (52686) */ + 3347, /* CDCF (52687) */ + 3347, /* CDD0 (52688) */ + 3347, /* CDD1 (52689) */ + 3347, /* CDD2 (52690) */ + 3347, /* CDD3 (52691) */ + 3347, /* CDD4 (52692) */ + 3347, /* CDD5 (52693) */ + 3347, /* CDD6 (52694) */ + 3347, /* CDD7 (52695) */ + 3347, /* CDD8 (52696) */ + 3347, /* CDD9 (52697) */ + 3347, /* CDDA (52698) */ + 3347, /* CDDB (52699) */ + 3347, /* CDDC (52700) */ + 3347, /* CDDD (52701) */ + 3347, /* CDDE (52702) */ + 3347, /* CDDF (52703) */ + 3347, /* CDE0 (52704) */ + 3347, /* CDE1 (52705) */ + 3347, /* CDE2 (52706) */ + 3347, /* CDE3 (52707) */ + 3347, /* CDE4 (52708) */ + 3347, /* CDE5 (52709) */ + 3347, /* CDE6 (52710) */ + 3347, /* CDE7 (52711) */ + 3347, /* CDE8 (52712) */ + 3347, /* CDE9 (52713) */ + 3347, /* CDEA (52714) */ + 3347, /* CDEB (52715) */ + 3347, /* CDEC (52716) */ + 3347, /* CDED (52717) */ + 3347, /* CDEE (52718) */ + 3347, /* CDEF (52719) */ + 3347, /* CDF0 (52720) */ + 3347, /* CDF1 (52721) */ + 3347, /* CDF2 (52722) */ + 3347, /* CDF3 (52723) */ + 3347, /* CDF4 (52724) */ + 3347, /* CDF5 (52725) */ + 3347, /* CDF6 (52726) */ + 3347, /* CDF7 (52727) */ + 3347, /* CDF8 (52728) */ + 3347, /* CDF9 (52729) */ + 3347, /* CDFA (52730) */ + 3347, /* CDFB (52731) */ + 3347, /* CDFC (52732) */ + 3347, /* CDFD (52733) */ + 3347, /* CDFE (52734) */ + 3347, /* CDFF (52735) */ + 3347, /* CE00 (52736) */ + 3347, /* CE01 (52737) */ + 3347, /* CE02 (52738) */ + 3347, /* CE03 (52739) */ + 3347, /* CE04 (52740) */ + 3347, /* CE05 (52741) */ + 3347, /* CE06 (52742) */ + 3347, /* CE07 (52743) */ + 3347, /* CE08 (52744) */ + 3347, /* CE09 (52745) */ + 3347, /* CE0A (52746) */ + 3347, /* CE0B (52747) */ + 3347, /* CE0C (52748) */ + 3347, /* CE0D (52749) */ + 3347, /* CE0E (52750) */ + 3347, /* CE0F (52751) */ + 3347, /* CE10 (52752) */ + 3347, /* CE11 (52753) */ + 3347, /* CE12 (52754) */ + 3347, /* CE13 (52755) */ + 3347, /* CE14 (52756) */ + 3347, /* CE15 (52757) */ + 3347, /* CE16 (52758) */ + 3347, /* CE17 (52759) */ + 3347, /* CE18 (52760) */ + 3347, /* CE19 (52761) */ + 3347, /* CE1A (52762) */ + 3347, /* CE1B (52763) */ + 3347, /* CE1C (52764) */ + 3347, /* CE1D (52765) */ + 3347, /* CE1E (52766) */ + 3347, /* CE1F (52767) */ + 3347, /* CE20 (52768) */ + 3347, /* CE21 (52769) */ + 3347, /* CE22 (52770) */ + 3347, /* CE23 (52771) */ + 3347, /* CE24 (52772) */ + 3347, /* CE25 (52773) */ + 3347, /* CE26 (52774) */ + 3347, /* CE27 (52775) */ + 3347, /* CE28 (52776) */ + 3347, /* CE29 (52777) */ + 3347, /* CE2A (52778) */ + 3347, /* CE2B (52779) */ + 3347, /* CE2C (52780) */ + 3347, /* CE2D (52781) */ + 3347, /* CE2E (52782) */ + 3347, /* CE2F (52783) */ + 3347, /* CE30 (52784) */ + 3347, /* CE31 (52785) */ + 3347, /* CE32 (52786) */ + 3347, /* CE33 (52787) */ + 3347, /* CE34 (52788) */ + 3347, /* CE35 (52789) */ + 3347, /* CE36 (52790) */ + 3347, /* CE37 (52791) */ + 3347, /* CE38 (52792) */ + 3347, /* CE39 (52793) */ + 3347, /* CE3A (52794) */ + 3347, /* CE3B (52795) */ + 3347, /* CE3C (52796) */ + 3347, /* CE3D (52797) */ + 3347, /* CE3E (52798) */ + 3347, /* CE3F (52799) */ + 3347, /* CE40 (52800) */ + 3347, /* CE41 (52801) */ + 3347, /* CE42 (52802) */ + 3347, /* CE43 (52803) */ + 3347, /* CE44 (52804) */ + 3347, /* CE45 (52805) */ + 3347, /* CE46 (52806) */ + 3347, /* CE47 (52807) */ + 3347, /* CE48 (52808) */ + 3347, /* CE49 (52809) */ + 3347, /* CE4A (52810) */ + 3347, /* CE4B (52811) */ + 3347, /* CE4C (52812) */ + 3347, /* CE4D (52813) */ + 3347, /* CE4E (52814) */ + 3347, /* CE4F (52815) */ + 3347, /* CE50 (52816) */ + 3347, /* CE51 (52817) */ + 3347, /* CE52 (52818) */ + 3347, /* CE53 (52819) */ + 3347, /* CE54 (52820) */ + 3347, /* CE55 (52821) */ + 3347, /* CE56 (52822) */ + 3347, /* CE57 (52823) */ + 3347, /* CE58 (52824) */ + 3347, /* CE59 (52825) */ + 3347, /* CE5A (52826) */ + 3347, /* CE5B (52827) */ + 3347, /* CE5C (52828) */ + 3347, /* CE5D (52829) */ + 3347, /* CE5E (52830) */ + 3347, /* CE5F (52831) */ + 3347, /* CE60 (52832) */ + 3347, /* CE61 (52833) */ + 3347, /* CE62 (52834) */ + 3347, /* CE63 (52835) */ + 3347, /* CE64 (52836) */ + 3347, /* CE65 (52837) */ + 3347, /* CE66 (52838) */ + 3347, /* CE67 (52839) */ + 3347, /* CE68 (52840) */ + 3347, /* CE69 (52841) */ + 3347, /* CE6A (52842) */ + 3347, /* CE6B (52843) */ + 3347, /* CE6C (52844) */ + 3347, /* CE6D (52845) */ + 3347, /* CE6E (52846) */ + 3347, /* CE6F (52847) */ + 3347, /* CE70 (52848) */ + 3347, /* CE71 (52849) */ + 3347, /* CE72 (52850) */ + 3347, /* CE73 (52851) */ + 3347, /* CE74 (52852) */ + 3347, /* CE75 (52853) */ + 3347, /* CE76 (52854) */ + 3347, /* CE77 (52855) */ + 3347, /* CE78 (52856) */ + 3347, /* CE79 (52857) */ + 3347, /* CE7A (52858) */ + 3347, /* CE7B (52859) */ + 3347, /* CE7C (52860) */ + 3347, /* CE7D (52861) */ + 3347, /* CE7E (52862) */ + 3347, /* CE7F (52863) */ + 3347, /* CE80 (52864) */ + 3347, /* CE81 (52865) */ + 3347, /* CE82 (52866) */ + 3347, /* CE83 (52867) */ + 3347, /* CE84 (52868) */ + 3347, /* CE85 (52869) */ + 3347, /* CE86 (52870) */ + 3347, /* CE87 (52871) */ + 3347, /* CE88 (52872) */ + 3347, /* CE89 (52873) */ + 3347, /* CE8A (52874) */ + 3347, /* CE8B (52875) */ + 3347, /* CE8C (52876) */ + 3347, /* CE8D (52877) */ + 3347, /* CE8E (52878) */ + 3347, /* CE8F (52879) */ + 3347, /* CE90 (52880) */ + 3347, /* CE91 (52881) */ + 3347, /* CE92 (52882) */ + 3347, /* CE93 (52883) */ + 3347, /* CE94 (52884) */ + 3347, /* CE95 (52885) */ + 3347, /* CE96 (52886) */ + 3347, /* CE97 (52887) */ + 3347, /* CE98 (52888) */ + 3347, /* CE99 (52889) */ + 3347, /* CE9A (52890) */ + 3347, /* CE9B (52891) */ + 3347, /* CE9C (52892) */ + 3347, /* CE9D (52893) */ + 3347, /* CE9E (52894) */ + 3347, /* CE9F (52895) */ + 3347, /* CEA0 (52896) */ + 3347, /* CEA1 (52897) */ + 3347, /* CEA2 (52898) */ + 3347, /* CEA3 (52899) */ + 3347, /* CEA4 (52900) */ + 3347, /* CEA5 (52901) */ + 3347, /* CEA6 (52902) */ + 3347, /* CEA7 (52903) */ + 3347, /* CEA8 (52904) */ + 3347, /* CEA9 (52905) */ + 3347, /* CEAA (52906) */ + 3347, /* CEAB (52907) */ + 3347, /* CEAC (52908) */ + 3347, /* CEAD (52909) */ + 3347, /* CEAE (52910) */ + 3347, /* CEAF (52911) */ + 3347, /* CEB0 (52912) */ + 3347, /* CEB1 (52913) */ + 3347, /* CEB2 (52914) */ + 3347, /* CEB3 (52915) */ + 3347, /* CEB4 (52916) */ + 3347, /* CEB5 (52917) */ + 3347, /* CEB6 (52918) */ + 3347, /* CEB7 (52919) */ + 3347, /* CEB8 (52920) */ + 3347, /* CEB9 (52921) */ + 3347, /* CEBA (52922) */ + 3347, /* CEBB (52923) */ + 3347, /* CEBC (52924) */ + 3347, /* CEBD (52925) */ + 3347, /* CEBE (52926) */ + 3347, /* CEBF (52927) */ + 3347, /* CEC0 (52928) */ + 3347, /* CEC1 (52929) */ + 3347, /* CEC2 (52930) */ + 3347, /* CEC3 (52931) */ + 3347, /* CEC4 (52932) */ + 3347, /* CEC5 (52933) */ + 3347, /* CEC6 (52934) */ + 3347, /* CEC7 (52935) */ + 3347, /* CEC8 (52936) */ + 3347, /* CEC9 (52937) */ + 3347, /* CECA (52938) */ + 3347, /* CECB (52939) */ + 3347, /* CECC (52940) */ + 3347, /* CECD (52941) */ + 3347, /* CECE (52942) */ + 3347, /* CECF (52943) */ + 3347, /* CED0 (52944) */ + 3347, /* CED1 (52945) */ + 3347, /* CED2 (52946) */ + 3347, /* CED3 (52947) */ + 3347, /* CED4 (52948) */ + 3347, /* CED5 (52949) */ + 3347, /* CED6 (52950) */ + 3347, /* CED7 (52951) */ + 3347, /* CED8 (52952) */ + 3347, /* CED9 (52953) */ + 3347, /* CEDA (52954) */ + 3347, /* CEDB (52955) */ + 3347, /* CEDC (52956) */ + 3347, /* CEDD (52957) */ + 3347, /* CEDE (52958) */ + 3347, /* CEDF (52959) */ + 3347, /* CEE0 (52960) */ + 3347, /* CEE1 (52961) */ + 3347, /* CEE2 (52962) */ + 3347, /* CEE3 (52963) */ + 3347, /* CEE4 (52964) */ + 3347, /* CEE5 (52965) */ + 3347, /* CEE6 (52966) */ + 3347, /* CEE7 (52967) */ + 3347, /* CEE8 (52968) */ + 3347, /* CEE9 (52969) */ + 3347, /* CEEA (52970) */ + 3347, /* CEEB (52971) */ + 3347, /* CEEC (52972) */ + 3347, /* CEED (52973) */ + 3347, /* CEEE (52974) */ + 3347, /* CEEF (52975) */ + 3347, /* CEF0 (52976) */ + 3347, /* CEF1 (52977) */ + 3347, /* CEF2 (52978) */ + 3347, /* CEF3 (52979) */ + 3347, /* CEF4 (52980) */ + 3347, /* CEF5 (52981) */ + 3347, /* CEF6 (52982) */ + 3347, /* CEF7 (52983) */ + 3347, /* CEF8 (52984) */ + 3347, /* CEF9 (52985) */ + 3347, /* CEFA (52986) */ + 3347, /* CEFB (52987) */ + 3347, /* CEFC (52988) */ + 3347, /* CEFD (52989) */ + 3347, /* CEFE (52990) */ + 3347, /* CEFF (52991) */ + 3347, /* CF00 (52992) */ + 3347, /* CF01 (52993) */ + 3347, /* CF02 (52994) */ + 3347, /* CF03 (52995) */ + 3347, /* CF04 (52996) */ + 3347, /* CF05 (52997) */ + 3347, /* CF06 (52998) */ + 3347, /* CF07 (52999) */ + 3347, /* CF08 (53000) */ + 3347, /* CF09 (53001) */ + 3347, /* CF0A (53002) */ + 3347, /* CF0B (53003) */ + 3347, /* CF0C (53004) */ + 3347, /* CF0D (53005) */ + 3347, /* CF0E (53006) */ + 3347, /* CF0F (53007) */ + 3347, /* CF10 (53008) */ + 3347, /* CF11 (53009) */ + 3347, /* CF12 (53010) */ + 3347, /* CF13 (53011) */ + 3347, /* CF14 (53012) */ + 3347, /* CF15 (53013) */ + 3347, /* CF16 (53014) */ + 3347, /* CF17 (53015) */ + 3347, /* CF18 (53016) */ + 3347, /* CF19 (53017) */ + 3347, /* CF1A (53018) */ + 3347, /* CF1B (53019) */ + 3347, /* CF1C (53020) */ + 3347, /* CF1D (53021) */ + 3347, /* CF1E (53022) */ + 3347, /* CF1F (53023) */ + 3347, /* CF20 (53024) */ + 3347, /* CF21 (53025) */ + 3347, /* CF22 (53026) */ + 3347, /* CF23 (53027) */ + 3347, /* CF24 (53028) */ + 3347, /* CF25 (53029) */ + 3347, /* CF26 (53030) */ + 3347, /* CF27 (53031) */ + 3347, /* CF28 (53032) */ + 3347, /* CF29 (53033) */ + 3347, /* CF2A (53034) */ + 3347, /* CF2B (53035) */ + 3347, /* CF2C (53036) */ + 3347, /* CF2D (53037) */ + 3347, /* CF2E (53038) */ + 3347, /* CF2F (53039) */ + 3347, /* CF30 (53040) */ + 3347, /* CF31 (53041) */ + 3347, /* CF32 (53042) */ + 3347, /* CF33 (53043) */ + 3347, /* CF34 (53044) */ + 3347, /* CF35 (53045) */ + 3347, /* CF36 (53046) */ + 3347, /* CF37 (53047) */ + 3347, /* CF38 (53048) */ + 3347, /* CF39 (53049) */ + 3347, /* CF3A (53050) */ + 3347, /* CF3B (53051) */ + 3347, /* CF3C (53052) */ + 3347, /* CF3D (53053) */ + 3347, /* CF3E (53054) */ + 3347, /* CF3F (53055) */ + 3347, /* CF40 (53056) */ + 3347, /* CF41 (53057) */ + 3347, /* CF42 (53058) */ + 3347, /* CF43 (53059) */ + 3347, /* CF44 (53060) */ + 3347, /* CF45 (53061) */ + 3347, /* CF46 (53062) */ + 3347, /* CF47 (53063) */ + 3347, /* CF48 (53064) */ + 3347, /* CF49 (53065) */ + 3347, /* CF4A (53066) */ + 3347, /* CF4B (53067) */ + 3347, /* CF4C (53068) */ + 3347, /* CF4D (53069) */ + 3347, /* CF4E (53070) */ + 3347, /* CF4F (53071) */ + 3347, /* CF50 (53072) */ + 3347, /* CF51 (53073) */ + 3347, /* CF52 (53074) */ + 3347, /* CF53 (53075) */ + 3347, /* CF54 (53076) */ + 3347, /* CF55 (53077) */ + 3347, /* CF56 (53078) */ + 3347, /* CF57 (53079) */ + 3347, /* CF58 (53080) */ + 3347, /* CF59 (53081) */ + 3347, /* CF5A (53082) */ + 3347, /* CF5B (53083) */ + 3347, /* CF5C (53084) */ + 3347, /* CF5D (53085) */ + 3347, /* CF5E (53086) */ + 3347, /* CF5F (53087) */ + 3347, /* CF60 (53088) */ + 3347, /* CF61 (53089) */ + 3347, /* CF62 (53090) */ + 3347, /* CF63 (53091) */ + 3347, /* CF64 (53092) */ + 3347, /* CF65 (53093) */ + 3347, /* CF66 (53094) */ + 3347, /* CF67 (53095) */ + 3347, /* CF68 (53096) */ + 3347, /* CF69 (53097) */ + 3347, /* CF6A (53098) */ + 3347, /* CF6B (53099) */ + 3347, /* CF6C (53100) */ + 3347, /* CF6D (53101) */ + 3347, /* CF6E (53102) */ + 3347, /* CF6F (53103) */ + 3347, /* CF70 (53104) */ + 3347, /* CF71 (53105) */ + 3347, /* CF72 (53106) */ + 3347, /* CF73 (53107) */ + 3347, /* CF74 (53108) */ + 3347, /* CF75 (53109) */ + 3347, /* CF76 (53110) */ + 3347, /* CF77 (53111) */ + 3347, /* CF78 (53112) */ + 3347, /* CF79 (53113) */ + 3347, /* CF7A (53114) */ + 3347, /* CF7B (53115) */ + 3347, /* CF7C (53116) */ + 3347, /* CF7D (53117) */ + 3347, /* CF7E (53118) */ + 3347, /* CF7F (53119) */ + 3347, /* CF80 (53120) */ + 3347, /* CF81 (53121) */ + 3347, /* CF82 (53122) */ + 3347, /* CF83 (53123) */ + 3347, /* CF84 (53124) */ + 3347, /* CF85 (53125) */ + 3347, /* CF86 (53126) */ + 3347, /* CF87 (53127) */ + 3347, /* CF88 (53128) */ + 3347, /* CF89 (53129) */ + 3347, /* CF8A (53130) */ + 3347, /* CF8B (53131) */ + 3347, /* CF8C (53132) */ + 3347, /* CF8D (53133) */ + 3347, /* CF8E (53134) */ + 3347, /* CF8F (53135) */ + 3347, /* CF90 (53136) */ + 3347, /* CF91 (53137) */ + 3347, /* CF92 (53138) */ + 3347, /* CF93 (53139) */ + 3347, /* CF94 (53140) */ + 3347, /* CF95 (53141) */ + 3347, /* CF96 (53142) */ + 3347, /* CF97 (53143) */ + 3347, /* CF98 (53144) */ + 3347, /* CF99 (53145) */ + 3347, /* CF9A (53146) */ + 3347, /* CF9B (53147) */ + 3347, /* CF9C (53148) */ + 3347, /* CF9D (53149) */ + 3347, /* CF9E (53150) */ + 3347, /* CF9F (53151) */ + 3347, /* CFA0 (53152) */ + 3347, /* CFA1 (53153) */ + 3347, /* CFA2 (53154) */ + 3347, /* CFA3 (53155) */ + 3347, /* CFA4 (53156) */ + 3347, /* CFA5 (53157) */ + 3347, /* CFA6 (53158) */ + 3347, /* CFA7 (53159) */ + 3347, /* CFA8 (53160) */ + 3347, /* CFA9 (53161) */ + 3347, /* CFAA (53162) */ + 3347, /* CFAB (53163) */ + 3347, /* CFAC (53164) */ + 3347, /* CFAD (53165) */ + 3347, /* CFAE (53166) */ + 3347, /* CFAF (53167) */ + 3347, /* CFB0 (53168) */ + 3347, /* CFB1 (53169) */ + 3347, /* CFB2 (53170) */ + 3347, /* CFB3 (53171) */ + 3347, /* CFB4 (53172) */ + 3347, /* CFB5 (53173) */ + 3347, /* CFB6 (53174) */ + 3347, /* CFB7 (53175) */ + 3347, /* CFB8 (53176) */ + 3347, /* CFB9 (53177) */ + 3347, /* CFBA (53178) */ + 3347, /* CFBB (53179) */ + 3347, /* CFBC (53180) */ + 3347, /* CFBD (53181) */ + 3347, /* CFBE (53182) */ + 3347, /* CFBF (53183) */ + 3347, /* CFC0 (53184) */ + 3347, /* CFC1 (53185) */ + 3347, /* CFC2 (53186) */ + 3347, /* CFC3 (53187) */ + 3347, /* CFC4 (53188) */ + 3347, /* CFC5 (53189) */ + 3347, /* CFC6 (53190) */ + 3347, /* CFC7 (53191) */ + 3347, /* CFC8 (53192) */ + 3347, /* CFC9 (53193) */ + 3347, /* CFCA (53194) */ + 3347, /* CFCB (53195) */ + 3347, /* CFCC (53196) */ + 3347, /* CFCD (53197) */ + 3347, /* CFCE (53198) */ + 3347, /* CFCF (53199) */ + 3347, /* CFD0 (53200) */ + 3347, /* CFD1 (53201) */ + 3347, /* CFD2 (53202) */ + 3347, /* CFD3 (53203) */ + 3347, /* CFD4 (53204) */ + 3347, /* CFD5 (53205) */ + 3347, /* CFD6 (53206) */ + 3347, /* CFD7 (53207) */ + 3347, /* CFD8 (53208) */ + 3347, /* CFD9 (53209) */ + 3347, /* CFDA (53210) */ + 3347, /* CFDB (53211) */ + 3347, /* CFDC (53212) */ + 3347, /* CFDD (53213) */ + 3347, /* CFDE (53214) */ + 3347, /* CFDF (53215) */ + 3347, /* CFE0 (53216) */ + 3347, /* CFE1 (53217) */ + 3347, /* CFE2 (53218) */ + 3347, /* CFE3 (53219) */ + 3347, /* CFE4 (53220) */ + 3347, /* CFE5 (53221) */ + 3347, /* CFE6 (53222) */ + 3347, /* CFE7 (53223) */ + 3347, /* CFE8 (53224) */ + 3347, /* CFE9 (53225) */ + 3347, /* CFEA (53226) */ + 3347, /* CFEB (53227) */ + 3347, /* CFEC (53228) */ + 3347, /* CFED (53229) */ + 3347, /* CFEE (53230) */ + 3347, /* CFEF (53231) */ + 3347, /* CFF0 (53232) */ + 3347, /* CFF1 (53233) */ + 3347, /* CFF2 (53234) */ + 3347, /* CFF3 (53235) */ + 3347, /* CFF4 (53236) */ + 3347, /* CFF5 (53237) */ + 3347, /* CFF6 (53238) */ + 3347, /* CFF7 (53239) */ + 3347, /* CFF8 (53240) */ + 3347, /* CFF9 (53241) */ + 3347, /* CFFA (53242) */ + 3347, /* CFFB (53243) */ + 3347, /* CFFC (53244) */ + 3347, /* CFFD (53245) */ + 3347, /* CFFE (53246) */ + 3347, /* CFFF (53247) */ + 3347, /* D000 (53248) */ + 3347, /* D001 (53249) */ + 3347, /* D002 (53250) */ + 3347, /* D003 (53251) */ + 3347, /* D004 (53252) */ + 3347, /* D005 (53253) */ + 3347, /* D006 (53254) */ + 3347, /* D007 (53255) */ + 3347, /* D008 (53256) */ + 3347, /* D009 (53257) */ + 3347, /* D00A (53258) */ + 3347, /* D00B (53259) */ + 3347, /* D00C (53260) */ + 3347, /* D00D (53261) */ + 3347, /* D00E (53262) */ + 3347, /* D00F (53263) */ + 3347, /* D010 (53264) */ + 3347, /* D011 (53265) */ + 3347, /* D012 (53266) */ + 3347, /* D013 (53267) */ + 3347, /* D014 (53268) */ + 3347, /* D015 (53269) */ + 3347, /* D016 (53270) */ + 3347, /* D017 (53271) */ + 3347, /* D018 (53272) */ + 3347, /* D019 (53273) */ + 3347, /* D01A (53274) */ + 3347, /* D01B (53275) */ + 3347, /* D01C (53276) */ + 3347, /* D01D (53277) */ + 3347, /* D01E (53278) */ + 3347, /* D01F (53279) */ + 3347, /* D020 (53280) */ + 3347, /* D021 (53281) */ + 3347, /* D022 (53282) */ + 3347, /* D023 (53283) */ + 3347, /* D024 (53284) */ + 3347, /* D025 (53285) */ + 3347, /* D026 (53286) */ + 3347, /* D027 (53287) */ + 3347, /* D028 (53288) */ + 3347, /* D029 (53289) */ + 3347, /* D02A (53290) */ + 3347, /* D02B (53291) */ + 3347, /* D02C (53292) */ + 3347, /* D02D (53293) */ + 3347, /* D02E (53294) */ + 3347, /* D02F (53295) */ + 3347, /* D030 (53296) */ + 3347, /* D031 (53297) */ + 3347, /* D032 (53298) */ + 3347, /* D033 (53299) */ + 3347, /* D034 (53300) */ + 3347, /* D035 (53301) */ + 3347, /* D036 (53302) */ + 3347, /* D037 (53303) */ + 3347, /* D038 (53304) */ + 3347, /* D039 (53305) */ + 3347, /* D03A (53306) */ + 3347, /* D03B (53307) */ + 3347, /* D03C (53308) */ + 3347, /* D03D (53309) */ + 3347, /* D03E (53310) */ + 3347, /* D03F (53311) */ + 3347, /* D040 (53312) */ + 3347, /* D041 (53313) */ + 3347, /* D042 (53314) */ + 3347, /* D043 (53315) */ + 3347, /* D044 (53316) */ + 3347, /* D045 (53317) */ + 3347, /* D046 (53318) */ + 3347, /* D047 (53319) */ + 3347, /* D048 (53320) */ + 3347, /* D049 (53321) */ + 3347, /* D04A (53322) */ + 3347, /* D04B (53323) */ + 3347, /* D04C (53324) */ + 3347, /* D04D (53325) */ + 3347, /* D04E (53326) */ + 3347, /* D04F (53327) */ + 3347, /* D050 (53328) */ + 3347, /* D051 (53329) */ + 3347, /* D052 (53330) */ + 3347, /* D053 (53331) */ + 3347, /* D054 (53332) */ + 3347, /* D055 (53333) */ + 3347, /* D056 (53334) */ + 3347, /* D057 (53335) */ + 3347, /* D058 (53336) */ + 3347, /* D059 (53337) */ + 3347, /* D05A (53338) */ + 3347, /* D05B (53339) */ + 3347, /* D05C (53340) */ + 3347, /* D05D (53341) */ + 3347, /* D05E (53342) */ + 3347, /* D05F (53343) */ + 3347, /* D060 (53344) */ + 3347, /* D061 (53345) */ + 3347, /* D062 (53346) */ + 3347, /* D063 (53347) */ + 3347, /* D064 (53348) */ + 3347, /* D065 (53349) */ + 3347, /* D066 (53350) */ + 3347, /* D067 (53351) */ + 3347, /* D068 (53352) */ + 3347, /* D069 (53353) */ + 3347, /* D06A (53354) */ + 3347, /* D06B (53355) */ + 3347, /* D06C (53356) */ + 3347, /* D06D (53357) */ + 3347, /* D06E (53358) */ + 3347, /* D06F (53359) */ + 3347, /* D070 (53360) */ + 3347, /* D071 (53361) */ + 3347, /* D072 (53362) */ + 3347, /* D073 (53363) */ + 3347, /* D074 (53364) */ + 3347, /* D075 (53365) */ + 3347, /* D076 (53366) */ + 3347, /* D077 (53367) */ + 3347, /* D078 (53368) */ + 3347, /* D079 (53369) */ + 3347, /* D07A (53370) */ + 3347, /* D07B (53371) */ + 3347, /* D07C (53372) */ + 3347, /* D07D (53373) */ + 3347, /* D07E (53374) */ + 3347, /* D07F (53375) */ + 3347, /* D080 (53376) */ + 3347, /* D081 (53377) */ + 3347, /* D082 (53378) */ + 3347, /* D083 (53379) */ + 3347, /* D084 (53380) */ + 3347, /* D085 (53381) */ + 3347, /* D086 (53382) */ + 3347, /* D087 (53383) */ + 3347, /* D088 (53384) */ + 3347, /* D089 (53385) */ + 3347, /* D08A (53386) */ + 3347, /* D08B (53387) */ + 3347, /* D08C (53388) */ + 3347, /* D08D (53389) */ + 3347, /* D08E (53390) */ + 3347, /* D08F (53391) */ + 3347, /* D090 (53392) */ + 3347, /* D091 (53393) */ + 3347, /* D092 (53394) */ + 3347, /* D093 (53395) */ + 3347, /* D094 (53396) */ + 3347, /* D095 (53397) */ + 3347, /* D096 (53398) */ + 3347, /* D097 (53399) */ + 3347, /* D098 (53400) */ + 3347, /* D099 (53401) */ + 3347, /* D09A (53402) */ + 3347, /* D09B (53403) */ + 3347, /* D09C (53404) */ + 3347, /* D09D (53405) */ + 3347, /* D09E (53406) */ + 3347, /* D09F (53407) */ + 3347, /* D0A0 (53408) */ + 3347, /* D0A1 (53409) */ + 3347, /* D0A2 (53410) */ + 3347, /* D0A3 (53411) */ + 3347, /* D0A4 (53412) */ + 3347, /* D0A5 (53413) */ + 3347, /* D0A6 (53414) */ + 3347, /* D0A7 (53415) */ + 3347, /* D0A8 (53416) */ + 3347, /* D0A9 (53417) */ + 3347, /* D0AA (53418) */ + 3347, /* D0AB (53419) */ + 3347, /* D0AC (53420) */ + 3347, /* D0AD (53421) */ + 3347, /* D0AE (53422) */ + 3347, /* D0AF (53423) */ + 3347, /* D0B0 (53424) */ + 3347, /* D0B1 (53425) */ + 3347, /* D0B2 (53426) */ + 3347, /* D0B3 (53427) */ + 3347, /* D0B4 (53428) */ + 3347, /* D0B5 (53429) */ + 3347, /* D0B6 (53430) */ + 3347, /* D0B7 (53431) */ + 3347, /* D0B8 (53432) */ + 3347, /* D0B9 (53433) */ + 3347, /* D0BA (53434) */ + 3347, /* D0BB (53435) */ + 3347, /* D0BC (53436) */ + 3347, /* D0BD (53437) */ + 3347, /* D0BE (53438) */ + 3347, /* D0BF (53439) */ + 3347, /* D0C0 (53440) */ + 3347, /* D0C1 (53441) */ + 3347, /* D0C2 (53442) */ + 3347, /* D0C3 (53443) */ + 3347, /* D0C4 (53444) */ + 3347, /* D0C5 (53445) */ + 3347, /* D0C6 (53446) */ + 3347, /* D0C7 (53447) */ + 3347, /* D0C8 (53448) */ + 3347, /* D0C9 (53449) */ + 3347, /* D0CA (53450) */ + 3347, /* D0CB (53451) */ + 3347, /* D0CC (53452) */ + 3347, /* D0CD (53453) */ + 3347, /* D0CE (53454) */ + 3347, /* D0CF (53455) */ + 3347, /* D0D0 (53456) */ + 3347, /* D0D1 (53457) */ + 3347, /* D0D2 (53458) */ + 3347, /* D0D3 (53459) */ + 3347, /* D0D4 (53460) */ + 3347, /* D0D5 (53461) */ + 3347, /* D0D6 (53462) */ + 3347, /* D0D7 (53463) */ + 3347, /* D0D8 (53464) */ + 3347, /* D0D9 (53465) */ + 3347, /* D0DA (53466) */ + 3347, /* D0DB (53467) */ + 3347, /* D0DC (53468) */ + 3347, /* D0DD (53469) */ + 3347, /* D0DE (53470) */ + 3347, /* D0DF (53471) */ + 3347, /* D0E0 (53472) */ + 3347, /* D0E1 (53473) */ + 3347, /* D0E2 (53474) */ + 3347, /* D0E3 (53475) */ + 3347, /* D0E4 (53476) */ + 3347, /* D0E5 (53477) */ + 3347, /* D0E6 (53478) */ + 3347, /* D0E7 (53479) */ + 3347, /* D0E8 (53480) */ + 3347, /* D0E9 (53481) */ + 3347, /* D0EA (53482) */ + 3347, /* D0EB (53483) */ + 3347, /* D0EC (53484) */ + 3347, /* D0ED (53485) */ + 3347, /* D0EE (53486) */ + 3347, /* D0EF (53487) */ + 3347, /* D0F0 (53488) */ + 3347, /* D0F1 (53489) */ + 3347, /* D0F2 (53490) */ + 3347, /* D0F3 (53491) */ + 3347, /* D0F4 (53492) */ + 3347, /* D0F5 (53493) */ + 3347, /* D0F6 (53494) */ + 3347, /* D0F7 (53495) */ + 3347, /* D0F8 (53496) */ + 3347, /* D0F9 (53497) */ + 3347, /* D0FA (53498) */ + 3347, /* D0FB (53499) */ + 3347, /* D0FC (53500) */ + 3347, /* D0FD (53501) */ + 3347, /* D0FE (53502) */ + 3347, /* D0FF (53503) */ + 3347, /* D100 (53504) */ + 3347, /* D101 (53505) */ + 3347, /* D102 (53506) */ + 3347, /* D103 (53507) */ + 3347, /* D104 (53508) */ + 3347, /* D105 (53509) */ + 3347, /* D106 (53510) */ + 3347, /* D107 (53511) */ + 3347, /* D108 (53512) */ + 3347, /* D109 (53513) */ + 3347, /* D10A (53514) */ + 3347, /* D10B (53515) */ + 3347, /* D10C (53516) */ + 3347, /* D10D (53517) */ + 3347, /* D10E (53518) */ + 3347, /* D10F (53519) */ + 3347, /* D110 (53520) */ + 3347, /* D111 (53521) */ + 3347, /* D112 (53522) */ + 3347, /* D113 (53523) */ + 3347, /* D114 (53524) */ + 3347, /* D115 (53525) */ + 3347, /* D116 (53526) */ + 3347, /* D117 (53527) */ + 3347, /* D118 (53528) */ + 3347, /* D119 (53529) */ + 3347, /* D11A (53530) */ + 3347, /* D11B (53531) */ + 3347, /* D11C (53532) */ + 3347, /* D11D (53533) */ + 3347, /* D11E (53534) */ + 3347, /* D11F (53535) */ + 3347, /* D120 (53536) */ + 3347, /* D121 (53537) */ + 3347, /* D122 (53538) */ + 3347, /* D123 (53539) */ + 3347, /* D124 (53540) */ + 3347, /* D125 (53541) */ + 3347, /* D126 (53542) */ + 3347, /* D127 (53543) */ + 3347, /* D128 (53544) */ + 3347, /* D129 (53545) */ + 3347, /* D12A (53546) */ + 3347, /* D12B (53547) */ + 3347, /* D12C (53548) */ + 3347, /* D12D (53549) */ + 3347, /* D12E (53550) */ + 3347, /* D12F (53551) */ + 3347, /* D130 (53552) */ + 3347, /* D131 (53553) */ + 3347, /* D132 (53554) */ + 3347, /* D133 (53555) */ + 3347, /* D134 (53556) */ + 3347, /* D135 (53557) */ + 3347, /* D136 (53558) */ + 3347, /* D137 (53559) */ + 3347, /* D138 (53560) */ + 3347, /* D139 (53561) */ + 3347, /* D13A (53562) */ + 3347, /* D13B (53563) */ + 3347, /* D13C (53564) */ + 3347, /* D13D (53565) */ + 3347, /* D13E (53566) */ + 3347, /* D13F (53567) */ + 3347, /* D140 (53568) */ + 3347, /* D141 (53569) */ + 3347, /* D142 (53570) */ + 3347, /* D143 (53571) */ + 3347, /* D144 (53572) */ + 3347, /* D145 (53573) */ + 3347, /* D146 (53574) */ + 3347, /* D147 (53575) */ + 3347, /* D148 (53576) */ + 3347, /* D149 (53577) */ + 3347, /* D14A (53578) */ + 3347, /* D14B (53579) */ + 3347, /* D14C (53580) */ + 3347, /* D14D (53581) */ + 3347, /* D14E (53582) */ + 3347, /* D14F (53583) */ + 3347, /* D150 (53584) */ + 3347, /* D151 (53585) */ + 3347, /* D152 (53586) */ + 3347, /* D153 (53587) */ + 3347, /* D154 (53588) */ + 3347, /* D155 (53589) */ + 3347, /* D156 (53590) */ + 3347, /* D157 (53591) */ + 3347, /* D158 (53592) */ + 3347, /* D159 (53593) */ + 3347, /* D15A (53594) */ + 3347, /* D15B (53595) */ + 3347, /* D15C (53596) */ + 3347, /* D15D (53597) */ + 3347, /* D15E (53598) */ + 3347, /* D15F (53599) */ + 3347, /* D160 (53600) */ + 3347, /* D161 (53601) */ + 3347, /* D162 (53602) */ + 3347, /* D163 (53603) */ + 3347, /* D164 (53604) */ + 3347, /* D165 (53605) */ + 3347, /* D166 (53606) */ + 3347, /* D167 (53607) */ + 3347, /* D168 (53608) */ + 3347, /* D169 (53609) */ + 3347, /* D16A (53610) */ + 3347, /* D16B (53611) */ + 3347, /* D16C (53612) */ + 3347, /* D16D (53613) */ + 3347, /* D16E (53614) */ + 3347, /* D16F (53615) */ + 3347, /* D170 (53616) */ + 3347, /* D171 (53617) */ + 3347, /* D172 (53618) */ + 3347, /* D173 (53619) */ + 3347, /* D174 (53620) */ + 3347, /* D175 (53621) */ + 3347, /* D176 (53622) */ + 3347, /* D177 (53623) */ + 3347, /* D178 (53624) */ + 3347, /* D179 (53625) */ + 3347, /* D17A (53626) */ + 3347, /* D17B (53627) */ + 3347, /* D17C (53628) */ + 3347, /* D17D (53629) */ + 3347, /* D17E (53630) */ + 3347, /* D17F (53631) */ + 3347, /* D180 (53632) */ + 3347, /* D181 (53633) */ + 3347, /* D182 (53634) */ + 3347, /* D183 (53635) */ + 3347, /* D184 (53636) */ + 3347, /* D185 (53637) */ + 3347, /* D186 (53638) */ + 3347, /* D187 (53639) */ + 3347, /* D188 (53640) */ + 3347, /* D189 (53641) */ + 3347, /* D18A (53642) */ + 3347, /* D18B (53643) */ + 3347, /* D18C (53644) */ + 3347, /* D18D (53645) */ + 3347, /* D18E (53646) */ + 3347, /* D18F (53647) */ + 3347, /* D190 (53648) */ + 3347, /* D191 (53649) */ + 3347, /* D192 (53650) */ + 3347, /* D193 (53651) */ + 3347, /* D194 (53652) */ + 3347, /* D195 (53653) */ + 3347, /* D196 (53654) */ + 3347, /* D197 (53655) */ + 3347, /* D198 (53656) */ + 3347, /* D199 (53657) */ + 3347, /* D19A (53658) */ + 3347, /* D19B (53659) */ + 3347, /* D19C (53660) */ + 3347, /* D19D (53661) */ + 3347, /* D19E (53662) */ + 3347, /* D19F (53663) */ + 3347, /* D1A0 (53664) */ + 3347, /* D1A1 (53665) */ + 3347, /* D1A2 (53666) */ + 3347, /* D1A3 (53667) */ + 3347, /* D1A4 (53668) */ + 3347, /* D1A5 (53669) */ + 3347, /* D1A6 (53670) */ + 3347, /* D1A7 (53671) */ + 3347, /* D1A8 (53672) */ + 3347, /* D1A9 (53673) */ + 3347, /* D1AA (53674) */ + 3347, /* D1AB (53675) */ + 3347, /* D1AC (53676) */ + 3347, /* D1AD (53677) */ + 3347, /* D1AE (53678) */ + 3347, /* D1AF (53679) */ + 3347, /* D1B0 (53680) */ + 3347, /* D1B1 (53681) */ + 3347, /* D1B2 (53682) */ + 3347, /* D1B3 (53683) */ + 3347, /* D1B4 (53684) */ + 3347, /* D1B5 (53685) */ + 3347, /* D1B6 (53686) */ + 3347, /* D1B7 (53687) */ + 3347, /* D1B8 (53688) */ + 3347, /* D1B9 (53689) */ + 3347, /* D1BA (53690) */ + 3347, /* D1BB (53691) */ + 3347, /* D1BC (53692) */ + 3347, /* D1BD (53693) */ + 3347, /* D1BE (53694) */ + 3347, /* D1BF (53695) */ + 3347, /* D1C0 (53696) */ + 3347, /* D1C1 (53697) */ + 3347, /* D1C2 (53698) */ + 3347, /* D1C3 (53699) */ + 3347, /* D1C4 (53700) */ + 3347, /* D1C5 (53701) */ + 3347, /* D1C6 (53702) */ + 3347, /* D1C7 (53703) */ + 3347, /* D1C8 (53704) */ + 3347, /* D1C9 (53705) */ + 3347, /* D1CA (53706) */ + 3347, /* D1CB (53707) */ + 3347, /* D1CC (53708) */ + 3347, /* D1CD (53709) */ + 3347, /* D1CE (53710) */ + 3347, /* D1CF (53711) */ + 3347, /* D1D0 (53712) */ + 3347, /* D1D1 (53713) */ + 3347, /* D1D2 (53714) */ + 3347, /* D1D3 (53715) */ + 3347, /* D1D4 (53716) */ + 3347, /* D1D5 (53717) */ + 3347, /* D1D6 (53718) */ + 3347, /* D1D7 (53719) */ + 3347, /* D1D8 (53720) */ + 3347, /* D1D9 (53721) */ + 3347, /* D1DA (53722) */ + 3347, /* D1DB (53723) */ + 3347, /* D1DC (53724) */ + 3347, /* D1DD (53725) */ + 3347, /* D1DE (53726) */ + 3347, /* D1DF (53727) */ + 3347, /* D1E0 (53728) */ + 3347, /* D1E1 (53729) */ + 3347, /* D1E2 (53730) */ + 3347, /* D1E3 (53731) */ + 3347, /* D1E4 (53732) */ + 3347, /* D1E5 (53733) */ + 3347, /* D1E6 (53734) */ + 3347, /* D1E7 (53735) */ + 3347, /* D1E8 (53736) */ + 3347, /* D1E9 (53737) */ + 3347, /* D1EA (53738) */ + 3347, /* D1EB (53739) */ + 3347, /* D1EC (53740) */ + 3347, /* D1ED (53741) */ + 3347, /* D1EE (53742) */ + 3347, /* D1EF (53743) */ + 3347, /* D1F0 (53744) */ + 3347, /* D1F1 (53745) */ + 3347, /* D1F2 (53746) */ + 3347, /* D1F3 (53747) */ + 3347, /* D1F4 (53748) */ + 3347, /* D1F5 (53749) */ + 3347, /* D1F6 (53750) */ + 3347, /* D1F7 (53751) */ + 3347, /* D1F8 (53752) */ + 3347, /* D1F9 (53753) */ + 3347, /* D1FA (53754) */ + 3347, /* D1FB (53755) */ + 3347, /* D1FC (53756) */ + 3347, /* D1FD (53757) */ + 3347, /* D1FE (53758) */ + 3347, /* D1FF (53759) */ + 3347, /* D200 (53760) */ + 3347, /* D201 (53761) */ + 3347, /* D202 (53762) */ + 3347, /* D203 (53763) */ + 3347, /* D204 (53764) */ + 3347, /* D205 (53765) */ + 3347, /* D206 (53766) */ + 3347, /* D207 (53767) */ + 3347, /* D208 (53768) */ + 3347, /* D209 (53769) */ + 3347, /* D20A (53770) */ + 3347, /* D20B (53771) */ + 3347, /* D20C (53772) */ + 3347, /* D20D (53773) */ + 3347, /* D20E (53774) */ + 3347, /* D20F (53775) */ + 3347, /* D210 (53776) */ + 3347, /* D211 (53777) */ + 3347, /* D212 (53778) */ + 3347, /* D213 (53779) */ + 3347, /* D214 (53780) */ + 3347, /* D215 (53781) */ + 3347, /* D216 (53782) */ + 3347, /* D217 (53783) */ + 3347, /* D218 (53784) */ + 3347, /* D219 (53785) */ + 3347, /* D21A (53786) */ + 3347, /* D21B (53787) */ + 3347, /* D21C (53788) */ + 3347, /* D21D (53789) */ + 3347, /* D21E (53790) */ + 3347, /* D21F (53791) */ + 3347, /* D220 (53792) */ + 3347, /* D221 (53793) */ + 3347, /* D222 (53794) */ + 3347, /* D223 (53795) */ + 3347, /* D224 (53796) */ + 3347, /* D225 (53797) */ + 3347, /* D226 (53798) */ + 3347, /* D227 (53799) */ + 3347, /* D228 (53800) */ + 3347, /* D229 (53801) */ + 3347, /* D22A (53802) */ + 3347, /* D22B (53803) */ + 3347, /* D22C (53804) */ + 3347, /* D22D (53805) */ + 3347, /* D22E (53806) */ + 3347, /* D22F (53807) */ + 3347, /* D230 (53808) */ + 3347, /* D231 (53809) */ + 3347, /* D232 (53810) */ + 3347, /* D233 (53811) */ + 3347, /* D234 (53812) */ + 3347, /* D235 (53813) */ + 3347, /* D236 (53814) */ + 3347, /* D237 (53815) */ + 3347, /* D238 (53816) */ + 3347, /* D239 (53817) */ + 3347, /* D23A (53818) */ + 3347, /* D23B (53819) */ + 3347, /* D23C (53820) */ + 3347, /* D23D (53821) */ + 3347, /* D23E (53822) */ + 3347, /* D23F (53823) */ + 3347, /* D240 (53824) */ + 3347, /* D241 (53825) */ + 3347, /* D242 (53826) */ + 3347, /* D243 (53827) */ + 3347, /* D244 (53828) */ + 3347, /* D245 (53829) */ + 3347, /* D246 (53830) */ + 3347, /* D247 (53831) */ + 3347, /* D248 (53832) */ + 3347, /* D249 (53833) */ + 3347, /* D24A (53834) */ + 3347, /* D24B (53835) */ + 3347, /* D24C (53836) */ + 3347, /* D24D (53837) */ + 3347, /* D24E (53838) */ + 3347, /* D24F (53839) */ + 3347, /* D250 (53840) */ + 3347, /* D251 (53841) */ + 3347, /* D252 (53842) */ + 3347, /* D253 (53843) */ + 3347, /* D254 (53844) */ + 3347, /* D255 (53845) */ + 3347, /* D256 (53846) */ + 3347, /* D257 (53847) */ + 3347, /* D258 (53848) */ + 3347, /* D259 (53849) */ + 3347, /* D25A (53850) */ + 3347, /* D25B (53851) */ + 3347, /* D25C (53852) */ + 3347, /* D25D (53853) */ + 3347, /* D25E (53854) */ + 3347, /* D25F (53855) */ + 3347, /* D260 (53856) */ + 3347, /* D261 (53857) */ + 3347, /* D262 (53858) */ + 3347, /* D263 (53859) */ + 3347, /* D264 (53860) */ + 3347, /* D265 (53861) */ + 3347, /* D266 (53862) */ + 3347, /* D267 (53863) */ + 3347, /* D268 (53864) */ + 3347, /* D269 (53865) */ + 3347, /* D26A (53866) */ + 3347, /* D26B (53867) */ + 3347, /* D26C (53868) */ + 3347, /* D26D (53869) */ + 3347, /* D26E (53870) */ + 3347, /* D26F (53871) */ + 3347, /* D270 (53872) */ + 3347, /* D271 (53873) */ + 3347, /* D272 (53874) */ + 3347, /* D273 (53875) */ + 3347, /* D274 (53876) */ + 3347, /* D275 (53877) */ + 3347, /* D276 (53878) */ + 3347, /* D277 (53879) */ + 3347, /* D278 (53880) */ + 3347, /* D279 (53881) */ + 3347, /* D27A (53882) */ + 3347, /* D27B (53883) */ + 3347, /* D27C (53884) */ + 3347, /* D27D (53885) */ + 3347, /* D27E (53886) */ + 3347, /* D27F (53887) */ + 3347, /* D280 (53888) */ + 3347, /* D281 (53889) */ + 3347, /* D282 (53890) */ + 3347, /* D283 (53891) */ + 3347, /* D284 (53892) */ + 3347, /* D285 (53893) */ + 3347, /* D286 (53894) */ + 3347, /* D287 (53895) */ + 3347, /* D288 (53896) */ + 3347, /* D289 (53897) */ + 3347, /* D28A (53898) */ + 3347, /* D28B (53899) */ + 3347, /* D28C (53900) */ + 3347, /* D28D (53901) */ + 3347, /* D28E (53902) */ + 3347, /* D28F (53903) */ + 3347, /* D290 (53904) */ + 3347, /* D291 (53905) */ + 3347, /* D292 (53906) */ + 3347, /* D293 (53907) */ + 3347, /* D294 (53908) */ + 3347, /* D295 (53909) */ + 3347, /* D296 (53910) */ + 3347, /* D297 (53911) */ + 3347, /* D298 (53912) */ + 3347, /* D299 (53913) */ + 3347, /* D29A (53914) */ + 3347, /* D29B (53915) */ + 3347, /* D29C (53916) */ + 3347, /* D29D (53917) */ + 3347, /* D29E (53918) */ + 3347, /* D29F (53919) */ + 3347, /* D2A0 (53920) */ + 3347, /* D2A1 (53921) */ + 3347, /* D2A2 (53922) */ + 3347, /* D2A3 (53923) */ + 3347, /* D2A4 (53924) */ + 3347, /* D2A5 (53925) */ + 3347, /* D2A6 (53926) */ + 3347, /* D2A7 (53927) */ + 3347, /* D2A8 (53928) */ + 3347, /* D2A9 (53929) */ + 3347, /* D2AA (53930) */ + 3347, /* D2AB (53931) */ + 3347, /* D2AC (53932) */ + 3347, /* D2AD (53933) */ + 3347, /* D2AE (53934) */ + 3347, /* D2AF (53935) */ + 3347, /* D2B0 (53936) */ + 3347, /* D2B1 (53937) */ + 3347, /* D2B2 (53938) */ + 3347, /* D2B3 (53939) */ + 3347, /* D2B4 (53940) */ + 3347, /* D2B5 (53941) */ + 3347, /* D2B6 (53942) */ + 3347, /* D2B7 (53943) */ + 3347, /* D2B8 (53944) */ + 3347, /* D2B9 (53945) */ + 3347, /* D2BA (53946) */ + 3347, /* D2BB (53947) */ + 3347, /* D2BC (53948) */ + 3347, /* D2BD (53949) */ + 3347, /* D2BE (53950) */ + 3347, /* D2BF (53951) */ + 3347, /* D2C0 (53952) */ + 3347, /* D2C1 (53953) */ + 3347, /* D2C2 (53954) */ + 3347, /* D2C3 (53955) */ + 3347, /* D2C4 (53956) */ + 3347, /* D2C5 (53957) */ + 3347, /* D2C6 (53958) */ + 3347, /* D2C7 (53959) */ + 3347, /* D2C8 (53960) */ + 3347, /* D2C9 (53961) */ + 3347, /* D2CA (53962) */ + 3347, /* D2CB (53963) */ + 3347, /* D2CC (53964) */ + 3347, /* D2CD (53965) */ + 3347, /* D2CE (53966) */ + 3347, /* D2CF (53967) */ + 3347, /* D2D0 (53968) */ + 3347, /* D2D1 (53969) */ + 3347, /* D2D2 (53970) */ + 3347, /* D2D3 (53971) */ + 3347, /* D2D4 (53972) */ + 3347, /* D2D5 (53973) */ + 3347, /* D2D6 (53974) */ + 3347, /* D2D7 (53975) */ + 3347, /* D2D8 (53976) */ + 3347, /* D2D9 (53977) */ + 3347, /* D2DA (53978) */ + 3347, /* D2DB (53979) */ + 3347, /* D2DC (53980) */ + 3347, /* D2DD (53981) */ + 3347, /* D2DE (53982) */ + 3347, /* D2DF (53983) */ + 3347, /* D2E0 (53984) */ + 3347, /* D2E1 (53985) */ + 3347, /* D2E2 (53986) */ + 3347, /* D2E3 (53987) */ + 3347, /* D2E4 (53988) */ + 3347, /* D2E5 (53989) */ + 3347, /* D2E6 (53990) */ + 3347, /* D2E7 (53991) */ + 3347, /* D2E8 (53992) */ + 3347, /* D2E9 (53993) */ + 3347, /* D2EA (53994) */ + 3347, /* D2EB (53995) */ + 3347, /* D2EC (53996) */ + 3347, /* D2ED (53997) */ + 3347, /* D2EE (53998) */ + 3347, /* D2EF (53999) */ + 3347, /* D2F0 (54000) */ + 3347, /* D2F1 (54001) */ + 3347, /* D2F2 (54002) */ + 3347, /* D2F3 (54003) */ + 3347, /* D2F4 (54004) */ + 3347, /* D2F5 (54005) */ + 3347, /* D2F6 (54006) */ + 3347, /* D2F7 (54007) */ + 3347, /* D2F8 (54008) */ + 3347, /* D2F9 (54009) */ + 3347, /* D2FA (54010) */ + 3347, /* D2FB (54011) */ + 3347, /* D2FC (54012) */ + 3347, /* D2FD (54013) */ + 3347, /* D2FE (54014) */ + 3347, /* D2FF (54015) */ + 3347, /* D300 (54016) */ + 3347, /* D301 (54017) */ + 3347, /* D302 (54018) */ + 3347, /* D303 (54019) */ + 3347, /* D304 (54020) */ + 3347, /* D305 (54021) */ + 3347, /* D306 (54022) */ + 3347, /* D307 (54023) */ + 3347, /* D308 (54024) */ + 3347, /* D309 (54025) */ + 3347, /* D30A (54026) */ + 3347, /* D30B (54027) */ + 3347, /* D30C (54028) */ + 3347, /* D30D (54029) */ + 3347, /* D30E (54030) */ + 3347, /* D30F (54031) */ + 3347, /* D310 (54032) */ + 3347, /* D311 (54033) */ + 3347, /* D312 (54034) */ + 3347, /* D313 (54035) */ + 3347, /* D314 (54036) */ + 3347, /* D315 (54037) */ + 3347, /* D316 (54038) */ + 3347, /* D317 (54039) */ + 3347, /* D318 (54040) */ + 3347, /* D319 (54041) */ + 3347, /* D31A (54042) */ + 3347, /* D31B (54043) */ + 3347, /* D31C (54044) */ + 3347, /* D31D (54045) */ + 3347, /* D31E (54046) */ + 3347, /* D31F (54047) */ + 3347, /* D320 (54048) */ + 3347, /* D321 (54049) */ + 3347, /* D322 (54050) */ + 3347, /* D323 (54051) */ + 3347, /* D324 (54052) */ + 3347, /* D325 (54053) */ + 3347, /* D326 (54054) */ + 3347, /* D327 (54055) */ + 3347, /* D328 (54056) */ + 3347, /* D329 (54057) */ + 3347, /* D32A (54058) */ + 3347, /* D32B (54059) */ + 3347, /* D32C (54060) */ + 3347, /* D32D (54061) */ + 3347, /* D32E (54062) */ + 3347, /* D32F (54063) */ + 3347, /* D330 (54064) */ + 3347, /* D331 (54065) */ + 3347, /* D332 (54066) */ + 3347, /* D333 (54067) */ + 3347, /* D334 (54068) */ + 3347, /* D335 (54069) */ + 3347, /* D336 (54070) */ + 3347, /* D337 (54071) */ + 3347, /* D338 (54072) */ + 3347, /* D339 (54073) */ + 3347, /* D33A (54074) */ + 3347, /* D33B (54075) */ + 3347, /* D33C (54076) */ + 3347, /* D33D (54077) */ + 3347, /* D33E (54078) */ + 3347, /* D33F (54079) */ + 3347, /* D340 (54080) */ + 3347, /* D341 (54081) */ + 3347, /* D342 (54082) */ + 3347, /* D343 (54083) */ + 3347, /* D344 (54084) */ + 3347, /* D345 (54085) */ + 3347, /* D346 (54086) */ + 3347, /* D347 (54087) */ + 3347, /* D348 (54088) */ + 3347, /* D349 (54089) */ + 3347, /* D34A (54090) */ + 3347, /* D34B (54091) */ + 3347, /* D34C (54092) */ + 3347, /* D34D (54093) */ + 3347, /* D34E (54094) */ + 3347, /* D34F (54095) */ + 3347, /* D350 (54096) */ + 3347, /* D351 (54097) */ + 3347, /* D352 (54098) */ + 3347, /* D353 (54099) */ + 3347, /* D354 (54100) */ + 3347, /* D355 (54101) */ + 3347, /* D356 (54102) */ + 3347, /* D357 (54103) */ + 3347, /* D358 (54104) */ + 3347, /* D359 (54105) */ + 3347, /* D35A (54106) */ + 3347, /* D35B (54107) */ + 3347, /* D35C (54108) */ + 3347, /* D35D (54109) */ + 3347, /* D35E (54110) */ + 3347, /* D35F (54111) */ + 3347, /* D360 (54112) */ + 3347, /* D361 (54113) */ + 3347, /* D362 (54114) */ + 3347, /* D363 (54115) */ + 3347, /* D364 (54116) */ + 3347, /* D365 (54117) */ + 3347, /* D366 (54118) */ + 3347, /* D367 (54119) */ + 3347, /* D368 (54120) */ + 3347, /* D369 (54121) */ + 3347, /* D36A (54122) */ + 3347, /* D36B (54123) */ + 3347, /* D36C (54124) */ + 3347, /* D36D (54125) */ + 3347, /* D36E (54126) */ + 3347, /* D36F (54127) */ + 3347, /* D370 (54128) */ + 3347, /* D371 (54129) */ + 3347, /* D372 (54130) */ + 3347, /* D373 (54131) */ + 3347, /* D374 (54132) */ + 3347, /* D375 (54133) */ + 3347, /* D376 (54134) */ + 3347, /* D377 (54135) */ + 3347, /* D378 (54136) */ + 3347, /* D379 (54137) */ + 3347, /* D37A (54138) */ + 3347, /* D37B (54139) */ + 3347, /* D37C (54140) */ + 3347, /* D37D (54141) */ + 3347, /* D37E (54142) */ + 3347, /* D37F (54143) */ + 3347, /* D380 (54144) */ + 3347, /* D381 (54145) */ + 3347, /* D382 (54146) */ + 3347, /* D383 (54147) */ + 3347, /* D384 (54148) */ + 3347, /* D385 (54149) */ + 3347, /* D386 (54150) */ + 3347, /* D387 (54151) */ + 3347, /* D388 (54152) */ + 3347, /* D389 (54153) */ + 3347, /* D38A (54154) */ + 3347, /* D38B (54155) */ + 3347, /* D38C (54156) */ + 3347, /* D38D (54157) */ + 3347, /* D38E (54158) */ + 3347, /* D38F (54159) */ + 3347, /* D390 (54160) */ + 3347, /* D391 (54161) */ + 3347, /* D392 (54162) */ + 3347, /* D393 (54163) */ + 3347, /* D394 (54164) */ + 3347, /* D395 (54165) */ + 3347, /* D396 (54166) */ + 3347, /* D397 (54167) */ + 3347, /* D398 (54168) */ + 3347, /* D399 (54169) */ + 3347, /* D39A (54170) */ + 3347, /* D39B (54171) */ + 3347, /* D39C (54172) */ + 3347, /* D39D (54173) */ + 3347, /* D39E (54174) */ + 3347, /* D39F (54175) */ + 3347, /* D3A0 (54176) */ + 3347, /* D3A1 (54177) */ + 3347, /* D3A2 (54178) */ + 3347, /* D3A3 (54179) */ + 3347, /* D3A4 (54180) */ + 3347, /* D3A5 (54181) */ + 3347, /* D3A6 (54182) */ + 3347, /* D3A7 (54183) */ + 3347, /* D3A8 (54184) */ + 3347, /* D3A9 (54185) */ + 3347, /* D3AA (54186) */ + 3347, /* D3AB (54187) */ + 3347, /* D3AC (54188) */ + 3347, /* D3AD (54189) */ + 3347, /* D3AE (54190) */ + 3347, /* D3AF (54191) */ + 3347, /* D3B0 (54192) */ + 3347, /* D3B1 (54193) */ + 3347, /* D3B2 (54194) */ + 3347, /* D3B3 (54195) */ + 3347, /* D3B4 (54196) */ + 3347, /* D3B5 (54197) */ + 3347, /* D3B6 (54198) */ + 3347, /* D3B7 (54199) */ + 3347, /* D3B8 (54200) */ + 3347, /* D3B9 (54201) */ + 3347, /* D3BA (54202) */ + 3347, /* D3BB (54203) */ + 3347, /* D3BC (54204) */ + 3347, /* D3BD (54205) */ + 3347, /* D3BE (54206) */ + 3347, /* D3BF (54207) */ + 3347, /* D3C0 (54208) */ + 3347, /* D3C1 (54209) */ + 3347, /* D3C2 (54210) */ + 3347, /* D3C3 (54211) */ + 3347, /* D3C4 (54212) */ + 3347, /* D3C5 (54213) */ + 3347, /* D3C6 (54214) */ + 3347, /* D3C7 (54215) */ + 3347, /* D3C8 (54216) */ + 3347, /* D3C9 (54217) */ + 3347, /* D3CA (54218) */ + 3347, /* D3CB (54219) */ + 3347, /* D3CC (54220) */ + 3347, /* D3CD (54221) */ + 3347, /* D3CE (54222) */ + 3347, /* D3CF (54223) */ + 3347, /* D3D0 (54224) */ + 3347, /* D3D1 (54225) */ + 3347, /* D3D2 (54226) */ + 3347, /* D3D3 (54227) */ + 3347, /* D3D4 (54228) */ + 3347, /* D3D5 (54229) */ + 3347, /* D3D6 (54230) */ + 3347, /* D3D7 (54231) */ + 3347, /* D3D8 (54232) */ + 3347, /* D3D9 (54233) */ + 3347, /* D3DA (54234) */ + 3347, /* D3DB (54235) */ + 3347, /* D3DC (54236) */ + 3347, /* D3DD (54237) */ + 3347, /* D3DE (54238) */ + 3347, /* D3DF (54239) */ + 3347, /* D3E0 (54240) */ + 3347, /* D3E1 (54241) */ + 3347, /* D3E2 (54242) */ + 3347, /* D3E3 (54243) */ + 3347, /* D3E4 (54244) */ + 3347, /* D3E5 (54245) */ + 3347, /* D3E6 (54246) */ + 3347, /* D3E7 (54247) */ + 3347, /* D3E8 (54248) */ + 3347, /* D3E9 (54249) */ + 3347, /* D3EA (54250) */ + 3347, /* D3EB (54251) */ + 3347, /* D3EC (54252) */ + 3347, /* D3ED (54253) */ + 3347, /* D3EE (54254) */ + 3347, /* D3EF (54255) */ + 3347, /* D3F0 (54256) */ + 3347, /* D3F1 (54257) */ + 3347, /* D3F2 (54258) */ + 3347, /* D3F3 (54259) */ + 3347, /* D3F4 (54260) */ + 3347, /* D3F5 (54261) */ + 3347, /* D3F6 (54262) */ + 3347, /* D3F7 (54263) */ + 3347, /* D3F8 (54264) */ + 3347, /* D3F9 (54265) */ + 3347, /* D3FA (54266) */ + 3347, /* D3FB (54267) */ + 3347, /* D3FC (54268) */ + 3347, /* D3FD (54269) */ + 3347, /* D3FE (54270) */ + 3347, /* D3FF (54271) */ + 3347, /* D400 (54272) */ + 3347, /* D401 (54273) */ + 3347, /* D402 (54274) */ + 3347, /* D403 (54275) */ + 3347, /* D404 (54276) */ + 3347, /* D405 (54277) */ + 3347, /* D406 (54278) */ + 3347, /* D407 (54279) */ + 3347, /* D408 (54280) */ + 3347, /* D409 (54281) */ + 3347, /* D40A (54282) */ + 3347, /* D40B (54283) */ + 3347, /* D40C (54284) */ + 3347, /* D40D (54285) */ + 3347, /* D40E (54286) */ + 3347, /* D40F (54287) */ + 3347, /* D410 (54288) */ + 3347, /* D411 (54289) */ + 3347, /* D412 (54290) */ + 3347, /* D413 (54291) */ + 3347, /* D414 (54292) */ + 3347, /* D415 (54293) */ + 3347, /* D416 (54294) */ + 3347, /* D417 (54295) */ + 3347, /* D418 (54296) */ + 3347, /* D419 (54297) */ + 3347, /* D41A (54298) */ + 3347, /* D41B (54299) */ + 3347, /* D41C (54300) */ + 3347, /* D41D (54301) */ + 3347, /* D41E (54302) */ + 3347, /* D41F (54303) */ + 3347, /* D420 (54304) */ + 3347, /* D421 (54305) */ + 3347, /* D422 (54306) */ + 3347, /* D423 (54307) */ + 3347, /* D424 (54308) */ + 3347, /* D425 (54309) */ + 3347, /* D426 (54310) */ + 3347, /* D427 (54311) */ + 3347, /* D428 (54312) */ + 3347, /* D429 (54313) */ + 3347, /* D42A (54314) */ + 3347, /* D42B (54315) */ + 3347, /* D42C (54316) */ + 3347, /* D42D (54317) */ + 3347, /* D42E (54318) */ + 3347, /* D42F (54319) */ + 3347, /* D430 (54320) */ + 3347, /* D431 (54321) */ + 3347, /* D432 (54322) */ + 3347, /* D433 (54323) */ + 3347, /* D434 (54324) */ + 3347, /* D435 (54325) */ + 3347, /* D436 (54326) */ + 3347, /* D437 (54327) */ + 3347, /* D438 (54328) */ + 3347, /* D439 (54329) */ + 3347, /* D43A (54330) */ + 3347, /* D43B (54331) */ + 3347, /* D43C (54332) */ + 3347, /* D43D (54333) */ + 3347, /* D43E (54334) */ + 3347, /* D43F (54335) */ + 3347, /* D440 (54336) */ + 3347, /* D441 (54337) */ + 3347, /* D442 (54338) */ + 3347, /* D443 (54339) */ + 3347, /* D444 (54340) */ + 3347, /* D445 (54341) */ + 3347, /* D446 (54342) */ + 3347, /* D447 (54343) */ + 3347, /* D448 (54344) */ + 3347, /* D449 (54345) */ + 3347, /* D44A (54346) */ + 3347, /* D44B (54347) */ + 3347, /* D44C (54348) */ + 3347, /* D44D (54349) */ + 3347, /* D44E (54350) */ + 3347, /* D44F (54351) */ + 3347, /* D450 (54352) */ + 3347, /* D451 (54353) */ + 3347, /* D452 (54354) */ + 3347, /* D453 (54355) */ + 3347, /* D454 (54356) */ + 3347, /* D455 (54357) */ + 3347, /* D456 (54358) */ + 3347, /* D457 (54359) */ + 3347, /* D458 (54360) */ + 3347, /* D459 (54361) */ + 3347, /* D45A (54362) */ + 3347, /* D45B (54363) */ + 3347, /* D45C (54364) */ + 3347, /* D45D (54365) */ + 3347, /* D45E (54366) */ + 3347, /* D45F (54367) */ + 3347, /* D460 (54368) */ + 3347, /* D461 (54369) */ + 3347, /* D462 (54370) */ + 3347, /* D463 (54371) */ + 3347, /* D464 (54372) */ + 3347, /* D465 (54373) */ + 3347, /* D466 (54374) */ + 3347, /* D467 (54375) */ + 3347, /* D468 (54376) */ + 3347, /* D469 (54377) */ + 3347, /* D46A (54378) */ + 3347, /* D46B (54379) */ + 3347, /* D46C (54380) */ + 3347, /* D46D (54381) */ + 3347, /* D46E (54382) */ + 3347, /* D46F (54383) */ + 3347, /* D470 (54384) */ + 3347, /* D471 (54385) */ + 3347, /* D472 (54386) */ + 3347, /* D473 (54387) */ + 3347, /* D474 (54388) */ + 3347, /* D475 (54389) */ + 3347, /* D476 (54390) */ + 3347, /* D477 (54391) */ + 3347, /* D478 (54392) */ + 3347, /* D479 (54393) */ + 3347, /* D47A (54394) */ + 3347, /* D47B (54395) */ + 3347, /* D47C (54396) */ + 3347, /* D47D (54397) */ + 3347, /* D47E (54398) */ + 3347, /* D47F (54399) */ + 3347, /* D480 (54400) */ + 3347, /* D481 (54401) */ + 3347, /* D482 (54402) */ + 3347, /* D483 (54403) */ + 3347, /* D484 (54404) */ + 3347, /* D485 (54405) */ + 3347, /* D486 (54406) */ + 3347, /* D487 (54407) */ + 3347, /* D488 (54408) */ + 3347, /* D489 (54409) */ + 3347, /* D48A (54410) */ + 3347, /* D48B (54411) */ + 3347, /* D48C (54412) */ + 3347, /* D48D (54413) */ + 3347, /* D48E (54414) */ + 3347, /* D48F (54415) */ + 3347, /* D490 (54416) */ + 3347, /* D491 (54417) */ + 3347, /* D492 (54418) */ + 3347, /* D493 (54419) */ + 3347, /* D494 (54420) */ + 3347, /* D495 (54421) */ + 3347, /* D496 (54422) */ + 3347, /* D497 (54423) */ + 3347, /* D498 (54424) */ + 3347, /* D499 (54425) */ + 3347, /* D49A (54426) */ + 3347, /* D49B (54427) */ + 3347, /* D49C (54428) */ + 3347, /* D49D (54429) */ + 3347, /* D49E (54430) */ + 3347, /* D49F (54431) */ + 3347, /* D4A0 (54432) */ + 3347, /* D4A1 (54433) */ + 3347, /* D4A2 (54434) */ + 3347, /* D4A3 (54435) */ + 3347, /* D4A4 (54436) */ + 3347, /* D4A5 (54437) */ + 3347, /* D4A6 (54438) */ + 3347, /* D4A7 (54439) */ + 3347, /* D4A8 (54440) */ + 3347, /* D4A9 (54441) */ + 3347, /* D4AA (54442) */ + 3347, /* D4AB (54443) */ + 3347, /* D4AC (54444) */ + 3347, /* D4AD (54445) */ + 3347, /* D4AE (54446) */ + 3347, /* D4AF (54447) */ + 3347, /* D4B0 (54448) */ + 3347, /* D4B1 (54449) */ + 3347, /* D4B2 (54450) */ + 3347, /* D4B3 (54451) */ + 3347, /* D4B4 (54452) */ + 3347, /* D4B5 (54453) */ + 3347, /* D4B6 (54454) */ + 3347, /* D4B7 (54455) */ + 3347, /* D4B8 (54456) */ + 3347, /* D4B9 (54457) */ + 3347, /* D4BA (54458) */ + 3347, /* D4BB (54459) */ + 3347, /* D4BC (54460) */ + 3347, /* D4BD (54461) */ + 3347, /* D4BE (54462) */ + 3347, /* D4BF (54463) */ + 3347, /* D4C0 (54464) */ + 3347, /* D4C1 (54465) */ + 3347, /* D4C2 (54466) */ + 3347, /* D4C3 (54467) */ + 3347, /* D4C4 (54468) */ + 3347, /* D4C5 (54469) */ + 3347, /* D4C6 (54470) */ + 3347, /* D4C7 (54471) */ + 3347, /* D4C8 (54472) */ + 3347, /* D4C9 (54473) */ + 3347, /* D4CA (54474) */ + 3347, /* D4CB (54475) */ + 3347, /* D4CC (54476) */ + 3347, /* D4CD (54477) */ + 3347, /* D4CE (54478) */ + 3347, /* D4CF (54479) */ + 3347, /* D4D0 (54480) */ + 3347, /* D4D1 (54481) */ + 3347, /* D4D2 (54482) */ + 3347, /* D4D3 (54483) */ + 3347, /* D4D4 (54484) */ + 3347, /* D4D5 (54485) */ + 3347, /* D4D6 (54486) */ + 3347, /* D4D7 (54487) */ + 3347, /* D4D8 (54488) */ + 3347, /* D4D9 (54489) */ + 3347, /* D4DA (54490) */ + 3347, /* D4DB (54491) */ + 3347, /* D4DC (54492) */ + 3347, /* D4DD (54493) */ + 3347, /* D4DE (54494) */ + 3347, /* D4DF (54495) */ + 3347, /* D4E0 (54496) */ + 3347, /* D4E1 (54497) */ + 3347, /* D4E2 (54498) */ + 3347, /* D4E3 (54499) */ + 3347, /* D4E4 (54500) */ + 3347, /* D4E5 (54501) */ + 3347, /* D4E6 (54502) */ + 3347, /* D4E7 (54503) */ + 3347, /* D4E8 (54504) */ + 3347, /* D4E9 (54505) */ + 3347, /* D4EA (54506) */ + 3347, /* D4EB (54507) */ + 3347, /* D4EC (54508) */ + 3347, /* D4ED (54509) */ + 3347, /* D4EE (54510) */ + 3347, /* D4EF (54511) */ + 3347, /* D4F0 (54512) */ + 3347, /* D4F1 (54513) */ + 3347, /* D4F2 (54514) */ + 3347, /* D4F3 (54515) */ + 3347, /* D4F4 (54516) */ + 3347, /* D4F5 (54517) */ + 3347, /* D4F6 (54518) */ + 3347, /* D4F7 (54519) */ + 3347, /* D4F8 (54520) */ + 3347, /* D4F9 (54521) */ + 3347, /* D4FA (54522) */ + 3347, /* D4FB (54523) */ + 3347, /* D4FC (54524) */ + 3347, /* D4FD (54525) */ + 3347, /* D4FE (54526) */ + 3347, /* D4FF (54527) */ + 3347, /* D500 (54528) */ + 3347, /* D501 (54529) */ + 3347, /* D502 (54530) */ + 3347, /* D503 (54531) */ + 3347, /* D504 (54532) */ + 3347, /* D505 (54533) */ + 3347, /* D506 (54534) */ + 3347, /* D507 (54535) */ + 3347, /* D508 (54536) */ + 3347, /* D509 (54537) */ + 3347, /* D50A (54538) */ + 3347, /* D50B (54539) */ + 3347, /* D50C (54540) */ + 3347, /* D50D (54541) */ + 3347, /* D50E (54542) */ + 3347, /* D50F (54543) */ + 3347, /* D510 (54544) */ + 3347, /* D511 (54545) */ + 3347, /* D512 (54546) */ + 3347, /* D513 (54547) */ + 3347, /* D514 (54548) */ + 3347, /* D515 (54549) */ + 3347, /* D516 (54550) */ + 3347, /* D517 (54551) */ + 3347, /* D518 (54552) */ + 3347, /* D519 (54553) */ + 3347, /* D51A (54554) */ + 3347, /* D51B (54555) */ + 3347, /* D51C (54556) */ + 3347, /* D51D (54557) */ + 3347, /* D51E (54558) */ + 3347, /* D51F (54559) */ + 3347, /* D520 (54560) */ + 3347, /* D521 (54561) */ + 3347, /* D522 (54562) */ + 3347, /* D523 (54563) */ + 3347, /* D524 (54564) */ + 3347, /* D525 (54565) */ + 3347, /* D526 (54566) */ + 3347, /* D527 (54567) */ + 3347, /* D528 (54568) */ + 3347, /* D529 (54569) */ + 3347, /* D52A (54570) */ + 3347, /* D52B (54571) */ + 3347, /* D52C (54572) */ + 3347, /* D52D (54573) */ + 3347, /* D52E (54574) */ + 3347, /* D52F (54575) */ + 3347, /* D530 (54576) */ + 3347, /* D531 (54577) */ + 3347, /* D532 (54578) */ + 3347, /* D533 (54579) */ + 3347, /* D534 (54580) */ + 3347, /* D535 (54581) */ + 3347, /* D536 (54582) */ + 3347, /* D537 (54583) */ + 3347, /* D538 (54584) */ + 3347, /* D539 (54585) */ + 3347, /* D53A (54586) */ + 3347, /* D53B (54587) */ + 3347, /* D53C (54588) */ + 3347, /* D53D (54589) */ + 3347, /* D53E (54590) */ + 3347, /* D53F (54591) */ + 3347, /* D540 (54592) */ + 3347, /* D541 (54593) */ + 3347, /* D542 (54594) */ + 3347, /* D543 (54595) */ + 3347, /* D544 (54596) */ + 3347, /* D545 (54597) */ + 3347, /* D546 (54598) */ + 3347, /* D547 (54599) */ + 3347, /* D548 (54600) */ + 3347, /* D549 (54601) */ + 3347, /* D54A (54602) */ + 3347, /* D54B (54603) */ + 3347, /* D54C (54604) */ + 3347, /* D54D (54605) */ + 3347, /* D54E (54606) */ + 3347, /* D54F (54607) */ + 3347, /* D550 (54608) */ + 3347, /* D551 (54609) */ + 3347, /* D552 (54610) */ + 3347, /* D553 (54611) */ + 3347, /* D554 (54612) */ + 3347, /* D555 (54613) */ + 3347, /* D556 (54614) */ + 3347, /* D557 (54615) */ + 3347, /* D558 (54616) */ + 3347, /* D559 (54617) */ + 3347, /* D55A (54618) */ + 3347, /* D55B (54619) */ + 3347, /* D55C (54620) */ + 3347, /* D55D (54621) */ + 3347, /* D55E (54622) */ + 3347, /* D55F (54623) */ + 3347, /* D560 (54624) */ + 3347, /* D561 (54625) */ + 3347, /* D562 (54626) */ + 3347, /* D563 (54627) */ + 3347, /* D564 (54628) */ + 3347, /* D565 (54629) */ + 3347, /* D566 (54630) */ + 3347, /* D567 (54631) */ + 3347, /* D568 (54632) */ + 3347, /* D569 (54633) */ + 3347, /* D56A (54634) */ + 3347, /* D56B (54635) */ + 3347, /* D56C (54636) */ + 3347, /* D56D (54637) */ + 3347, /* D56E (54638) */ + 3347, /* D56F (54639) */ + 3347, /* D570 (54640) */ + 3347, /* D571 (54641) */ + 3347, /* D572 (54642) */ + 3347, /* D573 (54643) */ + 3347, /* D574 (54644) */ + 3347, /* D575 (54645) */ + 3347, /* D576 (54646) */ + 3347, /* D577 (54647) */ + 3347, /* D578 (54648) */ + 3347, /* D579 (54649) */ + 3347, /* D57A (54650) */ + 3347, /* D57B (54651) */ + 3347, /* D57C (54652) */ + 3347, /* D57D (54653) */ + 3347, /* D57E (54654) */ + 3347, /* D57F (54655) */ + 3347, /* D580 (54656) */ + 3347, /* D581 (54657) */ + 3347, /* D582 (54658) */ + 3347, /* D583 (54659) */ + 3347, /* D584 (54660) */ + 3347, /* D585 (54661) */ + 3347, /* D586 (54662) */ + 3347, /* D587 (54663) */ + 3347, /* D588 (54664) */ + 3347, /* D589 (54665) */ + 3347, /* D58A (54666) */ + 3347, /* D58B (54667) */ + 3347, /* D58C (54668) */ + 3347, /* D58D (54669) */ + 3347, /* D58E (54670) */ + 3347, /* D58F (54671) */ + 3347, /* D590 (54672) */ + 3347, /* D591 (54673) */ + 3347, /* D592 (54674) */ + 3347, /* D593 (54675) */ + 3347, /* D594 (54676) */ + 3347, /* D595 (54677) */ + 3347, /* D596 (54678) */ + 3347, /* D597 (54679) */ + 3347, /* D598 (54680) */ + 3347, /* D599 (54681) */ + 3347, /* D59A (54682) */ + 3347, /* D59B (54683) */ + 3347, /* D59C (54684) */ + 3347, /* D59D (54685) */ + 3347, /* D59E (54686) */ + 3347, /* D59F (54687) */ + 3347, /* D5A0 (54688) */ + 3347, /* D5A1 (54689) */ + 3347, /* D5A2 (54690) */ + 3347, /* D5A3 (54691) */ + 3347, /* D5A4 (54692) */ + 3347, /* D5A5 (54693) */ + 3347, /* D5A6 (54694) */ + 3347, /* D5A7 (54695) */ + 3347, /* D5A8 (54696) */ + 3347, /* D5A9 (54697) */ + 3347, /* D5AA (54698) */ + 3347, /* D5AB (54699) */ + 3347, /* D5AC (54700) */ + 3347, /* D5AD (54701) */ + 3347, /* D5AE (54702) */ + 3347, /* D5AF (54703) */ + 3347, /* D5B0 (54704) */ + 3347, /* D5B1 (54705) */ + 3347, /* D5B2 (54706) */ + 3347, /* D5B3 (54707) */ + 3347, /* D5B4 (54708) */ + 3347, /* D5B5 (54709) */ + 3347, /* D5B6 (54710) */ + 3347, /* D5B7 (54711) */ + 3347, /* D5B8 (54712) */ + 3347, /* D5B9 (54713) */ + 3347, /* D5BA (54714) */ + 3347, /* D5BB (54715) */ + 3347, /* D5BC (54716) */ + 3347, /* D5BD (54717) */ + 3347, /* D5BE (54718) */ + 3347, /* D5BF (54719) */ + 3347, /* D5C0 (54720) */ + 3347, /* D5C1 (54721) */ + 3347, /* D5C2 (54722) */ + 3347, /* D5C3 (54723) */ + 3347, /* D5C4 (54724) */ + 3347, /* D5C5 (54725) */ + 3347, /* D5C6 (54726) */ + 3347, /* D5C7 (54727) */ + 3347, /* D5C8 (54728) */ + 3347, /* D5C9 (54729) */ + 3347, /* D5CA (54730) */ + 3347, /* D5CB (54731) */ + 3347, /* D5CC (54732) */ + 3347, /* D5CD (54733) */ + 3347, /* D5CE (54734) */ + 3347, /* D5CF (54735) */ + 3347, /* D5D0 (54736) */ + 3347, /* D5D1 (54737) */ + 3347, /* D5D2 (54738) */ + 3347, /* D5D3 (54739) */ + 3347, /* D5D4 (54740) */ + 3347, /* D5D5 (54741) */ + 3347, /* D5D6 (54742) */ + 3347, /* D5D7 (54743) */ + 3347, /* D5D8 (54744) */ + 3347, /* D5D9 (54745) */ + 3347, /* D5DA (54746) */ + 3347, /* D5DB (54747) */ + 3347, /* D5DC (54748) */ + 3347, /* D5DD (54749) */ + 3347, /* D5DE (54750) */ + 3347, /* D5DF (54751) */ + 3347, /* D5E0 (54752) */ + 3347, /* D5E1 (54753) */ + 3347, /* D5E2 (54754) */ + 3347, /* D5E3 (54755) */ + 3347, /* D5E4 (54756) */ + 3347, /* D5E5 (54757) */ + 3347, /* D5E6 (54758) */ + 3347, /* D5E7 (54759) */ + 3347, /* D5E8 (54760) */ + 3347, /* D5E9 (54761) */ + 3347, /* D5EA (54762) */ + 3347, /* D5EB (54763) */ + 3347, /* D5EC (54764) */ + 3347, /* D5ED (54765) */ + 3347, /* D5EE (54766) */ + 3347, /* D5EF (54767) */ + 3347, /* D5F0 (54768) */ + 3347, /* D5F1 (54769) */ + 3347, /* D5F2 (54770) */ + 3347, /* D5F3 (54771) */ + 3347, /* D5F4 (54772) */ + 3347, /* D5F5 (54773) */ + 3347, /* D5F6 (54774) */ + 3347, /* D5F7 (54775) */ + 3347, /* D5F8 (54776) */ + 3347, /* D5F9 (54777) */ + 3347, /* D5FA (54778) */ + 3347, /* D5FB (54779) */ + 3347, /* D5FC (54780) */ + 3347, /* D5FD (54781) */ + 3347, /* D5FE (54782) */ + 3347, /* D5FF (54783) */ + 3347, /* D600 (54784) */ + 3347, /* D601 (54785) */ + 3347, /* D602 (54786) */ + 3347, /* D603 (54787) */ + 3347, /* D604 (54788) */ + 3347, /* D605 (54789) */ + 3347, /* D606 (54790) */ + 3347, /* D607 (54791) */ + 3347, /* D608 (54792) */ + 3347, /* D609 (54793) */ + 3347, /* D60A (54794) */ + 3347, /* D60B (54795) */ + 3347, /* D60C (54796) */ + 3347, /* D60D (54797) */ + 3347, /* D60E (54798) */ + 3347, /* D60F (54799) */ + 3347, /* D610 (54800) */ + 3347, /* D611 (54801) */ + 3347, /* D612 (54802) */ + 3347, /* D613 (54803) */ + 3347, /* D614 (54804) */ + 3347, /* D615 (54805) */ + 3347, /* D616 (54806) */ + 3347, /* D617 (54807) */ + 3347, /* D618 (54808) */ + 3347, /* D619 (54809) */ + 3347, /* D61A (54810) */ + 3347, /* D61B (54811) */ + 3347, /* D61C (54812) */ + 3347, /* D61D (54813) */ + 3347, /* D61E (54814) */ + 3347, /* D61F (54815) */ + 3347, /* D620 (54816) */ + 3347, /* D621 (54817) */ + 3347, /* D622 (54818) */ + 3347, /* D623 (54819) */ + 3347, /* D624 (54820) */ + 3347, /* D625 (54821) */ + 3347, /* D626 (54822) */ + 3347, /* D627 (54823) */ + 3347, /* D628 (54824) */ + 3347, /* D629 (54825) */ + 3347, /* D62A (54826) */ + 3347, /* D62B (54827) */ + 3347, /* D62C (54828) */ + 3347, /* D62D (54829) */ + 3347, /* D62E (54830) */ + 3347, /* D62F (54831) */ + 3347, /* D630 (54832) */ + 3347, /* D631 (54833) */ + 3347, /* D632 (54834) */ + 3347, /* D633 (54835) */ + 3347, /* D634 (54836) */ + 3347, /* D635 (54837) */ + 3347, /* D636 (54838) */ + 3347, /* D637 (54839) */ + 3347, /* D638 (54840) */ + 3347, /* D639 (54841) */ + 3347, /* D63A (54842) */ + 3347, /* D63B (54843) */ + 3347, /* D63C (54844) */ + 3347, /* D63D (54845) */ + 3347, /* D63E (54846) */ + 3347, /* D63F (54847) */ + 3347, /* D640 (54848) */ + 3347, /* D641 (54849) */ + 3347, /* D642 (54850) */ + 3347, /* D643 (54851) */ + 3347, /* D644 (54852) */ + 3347, /* D645 (54853) */ + 3347, /* D646 (54854) */ + 3347, /* D647 (54855) */ + 3347, /* D648 (54856) */ + 3347, /* D649 (54857) */ + 3347, /* D64A (54858) */ + 3347, /* D64B (54859) */ + 3347, /* D64C (54860) */ + 3347, /* D64D (54861) */ + 3347, /* D64E (54862) */ + 3347, /* D64F (54863) */ + 3347, /* D650 (54864) */ + 3347, /* D651 (54865) */ + 3347, /* D652 (54866) */ + 3347, /* D653 (54867) */ + 3347, /* D654 (54868) */ + 3347, /* D655 (54869) */ + 3347, /* D656 (54870) */ + 3347, /* D657 (54871) */ + 3347, /* D658 (54872) */ + 3347, /* D659 (54873) */ + 3347, /* D65A (54874) */ + 3347, /* D65B (54875) */ + 3347, /* D65C (54876) */ + 3347, /* D65D (54877) */ + 3347, /* D65E (54878) */ + 3347, /* D65F (54879) */ + 3347, /* D660 (54880) */ + 3347, /* D661 (54881) */ + 3347, /* D662 (54882) */ + 3347, /* D663 (54883) */ + 3347, /* D664 (54884) */ + 3347, /* D665 (54885) */ + 3347, /* D666 (54886) */ + 3347, /* D667 (54887) */ + 3347, /* D668 (54888) */ + 3347, /* D669 (54889) */ + 3347, /* D66A (54890) */ + 3347, /* D66B (54891) */ + 3347, /* D66C (54892) */ + 3347, /* D66D (54893) */ + 3347, /* D66E (54894) */ + 3347, /* D66F (54895) */ + 3347, /* D670 (54896) */ + 3347, /* D671 (54897) */ + 3347, /* D672 (54898) */ + 3347, /* D673 (54899) */ + 3347, /* D674 (54900) */ + 3347, /* D675 (54901) */ + 3347, /* D676 (54902) */ + 3347, /* D677 (54903) */ + 3347, /* D678 (54904) */ + 3347, /* D679 (54905) */ + 3347, /* D67A (54906) */ + 3347, /* D67B (54907) */ + 3347, /* D67C (54908) */ + 3347, /* D67D (54909) */ + 3347, /* D67E (54910) */ + 3347, /* D67F (54911) */ + 3347, /* D680 (54912) */ + 3347, /* D681 (54913) */ + 3347, /* D682 (54914) */ + 3347, /* D683 (54915) */ + 3347, /* D684 (54916) */ + 3347, /* D685 (54917) */ + 3347, /* D686 (54918) */ + 3347, /* D687 (54919) */ + 3347, /* D688 (54920) */ + 3347, /* D689 (54921) */ + 3347, /* D68A (54922) */ + 3347, /* D68B (54923) */ + 3347, /* D68C (54924) */ + 3347, /* D68D (54925) */ + 3347, /* D68E (54926) */ + 3347, /* D68F (54927) */ + 3347, /* D690 (54928) */ + 3347, /* D691 (54929) */ + 3347, /* D692 (54930) */ + 3347, /* D693 (54931) */ + 3347, /* D694 (54932) */ + 3347, /* D695 (54933) */ + 3347, /* D696 (54934) */ + 3347, /* D697 (54935) */ + 3347, /* D698 (54936) */ + 3347, /* D699 (54937) */ + 3347, /* D69A (54938) */ + 3347, /* D69B (54939) */ + 3347, /* D69C (54940) */ + 3347, /* D69D (54941) */ + 3347, /* D69E (54942) */ + 3347, /* D69F (54943) */ + 3347, /* D6A0 (54944) */ + 3347, /* D6A1 (54945) */ + 3347, /* D6A2 (54946) */ + 3347, /* D6A3 (54947) */ + 3347, /* D6A4 (54948) */ + 3347, /* D6A5 (54949) */ + 3347, /* D6A6 (54950) */ + 3347, /* D6A7 (54951) */ + 3347, /* D6A8 (54952) */ + 3347, /* D6A9 (54953) */ + 3347, /* D6AA (54954) */ + 3347, /* D6AB (54955) */ + 3347, /* D6AC (54956) */ + 3347, /* D6AD (54957) */ + 3347, /* D6AE (54958) */ + 3347, /* D6AF (54959) */ + 3347, /* D6B0 (54960) */ + 3347, /* D6B1 (54961) */ + 3347, /* D6B2 (54962) */ + 3347, /* D6B3 (54963) */ + 3347, /* D6B4 (54964) */ + 3347, /* D6B5 (54965) */ + 3347, /* D6B6 (54966) */ + 3347, /* D6B7 (54967) */ + 3347, /* D6B8 (54968) */ + 3347, /* D6B9 (54969) */ + 3347, /* D6BA (54970) */ + 3347, /* D6BB (54971) */ + 3347, /* D6BC (54972) */ + 3347, /* D6BD (54973) */ + 3347, /* D6BE (54974) */ + 3347, /* D6BF (54975) */ + 3347, /* D6C0 (54976) */ + 3347, /* D6C1 (54977) */ + 3347, /* D6C2 (54978) */ + 3347, /* D6C3 (54979) */ + 3347, /* D6C4 (54980) */ + 3347, /* D6C5 (54981) */ + 3347, /* D6C6 (54982) */ + 3347, /* D6C7 (54983) */ + 3347, /* D6C8 (54984) */ + 3347, /* D6C9 (54985) */ + 3347, /* D6CA (54986) */ + 3347, /* D6CB (54987) */ + 3347, /* D6CC (54988) */ + 3347, /* D6CD (54989) */ + 3347, /* D6CE (54990) */ + 3347, /* D6CF (54991) */ + 3347, /* D6D0 (54992) */ + 3347, /* D6D1 (54993) */ + 3347, /* D6D2 (54994) */ + 3347, /* D6D3 (54995) */ + 3347, /* D6D4 (54996) */ + 3347, /* D6D5 (54997) */ + 3347, /* D6D6 (54998) */ + 3347, /* D6D7 (54999) */ + 3347, /* D6D8 (55000) */ + 3347, /* D6D9 (55001) */ + 3347, /* D6DA (55002) */ + 3347, /* D6DB (55003) */ + 3347, /* D6DC (55004) */ + 3347, /* D6DD (55005) */ + 3347, /* D6DE (55006) */ + 3347, /* D6DF (55007) */ + 3347, /* D6E0 (55008) */ + 3347, /* D6E1 (55009) */ + 3347, /* D6E2 (55010) */ + 3347, /* D6E3 (55011) */ + 3347, /* D6E4 (55012) */ + 3347, /* D6E5 (55013) */ + 3347, /* D6E6 (55014) */ + 3347, /* D6E7 (55015) */ + 3347, /* D6E8 (55016) */ + 3347, /* D6E9 (55017) */ + 3347, /* D6EA (55018) */ + 3347, /* D6EB (55019) */ + 3347, /* D6EC (55020) */ + 3347, /* D6ED (55021) */ + 3347, /* D6EE (55022) */ + 3347, /* D6EF (55023) */ + 3347, /* D6F0 (55024) */ + 3347, /* D6F1 (55025) */ + 3347, /* D6F2 (55026) */ + 3347, /* D6F3 (55027) */ + 3347, /* D6F4 (55028) */ + 3347, /* D6F5 (55029) */ + 3347, /* D6F6 (55030) */ + 3347, /* D6F7 (55031) */ + 3347, /* D6F8 (55032) */ + 3347, /* D6F9 (55033) */ + 3347, /* D6FA (55034) */ + 3347, /* D6FB (55035) */ + 3347, /* D6FC (55036) */ + 3347, /* D6FD (55037) */ + 3347, /* D6FE (55038) */ + 3347, /* D6FF (55039) */ + 3347, /* D700 (55040) */ + 3347, /* D701 (55041) */ + 3347, /* D702 (55042) */ + 3347, /* D703 (55043) */ + 3347, /* D704 (55044) */ + 3347, /* D705 (55045) */ + 3347, /* D706 (55046) */ + 3347, /* D707 (55047) */ + 3347, /* D708 (55048) */ + 3347, /* D709 (55049) */ + 3347, /* D70A (55050) */ + 3347, /* D70B (55051) */ + 3347, /* D70C (55052) */ + 3347, /* D70D (55053) */ + 3347, /* D70E (55054) */ + 3347, /* D70F (55055) */ + 3347, /* D710 (55056) */ + 3347, /* D711 (55057) */ + 3347, /* D712 (55058) */ + 3347, /* D713 (55059) */ + 3347, /* D714 (55060) */ + 3347, /* D715 (55061) */ + 3347, /* D716 (55062) */ + 3347, /* D717 (55063) */ + 3347, /* D718 (55064) */ + 3347, /* D719 (55065) */ + 3347, /* D71A (55066) */ + 3347, /* D71B (55067) */ + 3347, /* D71C (55068) */ + 3347, /* D71D (55069) */ + 3347, /* D71E (55070) */ + 3347, /* D71F (55071) */ + 3347, /* D720 (55072) */ + 3347, /* D721 (55073) */ + 3347, /* D722 (55074) */ + 3347, /* D723 (55075) */ + 3347, /* D724 (55076) */ + 3347, /* D725 (55077) */ + 3347, /* D726 (55078) */ + 3347, /* D727 (55079) */ + 3347, /* D728 (55080) */ + 3347, /* D729 (55081) */ + 3347, /* D72A (55082) */ + 3347, /* D72B (55083) */ + 3347, /* D72C (55084) */ + 3347, /* D72D (55085) */ + 3347, /* D72E (55086) */ + 3347, /* D72F (55087) */ + 3347, /* D730 (55088) */ + 3347, /* D731 (55089) */ + 3347, /* D732 (55090) */ + 3347, /* D733 (55091) */ + 3347, /* D734 (55092) */ + 3347, /* D735 (55093) */ + 3347, /* D736 (55094) */ + 3347, /* D737 (55095) */ + 3347, /* D738 (55096) */ + 3347, /* D739 (55097) */ + 3347, /* D73A (55098) */ + 3347, /* D73B (55099) */ + 3347, /* D73C (55100) */ + 3347, /* D73D (55101) */ + 3347, /* D73E (55102) */ + 3347, /* D73F (55103) */ + 3347, /* D740 (55104) */ + 3347, /* D741 (55105) */ + 3347, /* D742 (55106) */ + 3347, /* D743 (55107) */ + 3347, /* D744 (55108) */ + 3347, /* D745 (55109) */ + 3347, /* D746 (55110) */ + 3347, /* D747 (55111) */ + 3347, /* D748 (55112) */ + 3347, /* D749 (55113) */ + 3347, /* D74A (55114) */ + 3347, /* D74B (55115) */ + 3347, /* D74C (55116) */ + 3347, /* D74D (55117) */ + 3347, /* D74E (55118) */ + 3347, /* D74F (55119) */ + 3347, /* D750 (55120) */ + 3347, /* D751 (55121) */ + 3347, /* D752 (55122) */ + 3347, /* D753 (55123) */ + 3347, /* D754 (55124) */ + 3347, /* D755 (55125) */ + 3347, /* D756 (55126) */ + 3347, /* D757 (55127) */ + 3347, /* D758 (55128) */ + 3347, /* D759 (55129) */ + 3347, /* D75A (55130) */ + 3347, /* D75B (55131) */ + 3347, /* D75C (55132) */ + 3347, /* D75D (55133) */ + 3347, /* D75E (55134) */ + 3347, /* D75F (55135) */ + 3347, /* D760 (55136) */ + 3347, /* D761 (55137) */ + 3347, /* D762 (55138) */ + 3347, /* D763 (55139) */ + 3347, /* D764 (55140) */ + 3347, /* D765 (55141) */ + 3347, /* D766 (55142) */ + 3347, /* D767 (55143) */ + 3347, /* D768 (55144) */ + 3347, /* D769 (55145) */ + 3347, /* D76A (55146) */ + 3347, /* D76B (55147) */ + 3347, /* D76C (55148) */ + 3347, /* D76D (55149) */ + 3347, /* D76E (55150) */ + 3347, /* D76F (55151) */ + 3347, /* D770 (55152) */ + 3347, /* D771 (55153) */ + 3347, /* D772 (55154) */ + 3347, /* D773 (55155) */ + 3347, /* D774 (55156) */ + 3347, /* D775 (55157) */ + 3347, /* D776 (55158) */ + 3347, /* D777 (55159) */ + 3347, /* D778 (55160) */ + 3347, /* D779 (55161) */ + 3347, /* D77A (55162) */ + 3347, /* D77B (55163) */ + 3347, /* D77C (55164) */ + 3347, /* D77D (55165) */ + 3347, /* D77E (55166) */ + 3347, /* D77F (55167) */ + 3347, /* D780 (55168) */ + 3347, /* D781 (55169) */ + 3347, /* D782 (55170) */ + 3347, /* D783 (55171) */ + 3347, /* D784 (55172) */ + 3347, /* D785 (55173) */ + 3347, /* D786 (55174) */ + 3347, /* D787 (55175) */ + 3347, /* D788 (55176) */ + 3347, /* D789 (55177) */ + 3347, /* D78A (55178) */ + 3347, /* D78B (55179) */ + 3347, /* D78C (55180) */ + 3347, /* D78D (55181) */ + 3347, /* D78E (55182) */ + 3347, /* D78F (55183) */ + 3347, /* D790 (55184) */ + 3347, /* D791 (55185) */ + 3347, /* D792 (55186) */ + 3347, /* D793 (55187) */ + 3347, /* D794 (55188) */ + 3347, /* D795 (55189) */ + 3347, /* D796 (55190) */ + 3347, /* D797 (55191) */ + 3347, /* D798 (55192) */ + 3347, /* D799 (55193) */ + 3347, /* D79A (55194) */ + 3347, /* D79B (55195) */ + 3347, /* D79C (55196) */ + 3347, /* D79D (55197) */ + 3347, /* D79E (55198) */ + 3347, /* D79F (55199) */ + 3347, /* D7A0 (55200) */ + 3347, /* D7A1 (55201) */ + 3347, /* D7A2 (55202) */ + 3347, /* D7A3 (55203) */ 56, /* D7A4 (55204) */ 56, /* D7A5 (55205) */ 56, /* D7A6 (55206) */ @@ -57372,480 +57372,480 @@ static const uint16_t lxb_unicode_table_map_0_57345[57345] = static const uint16_t lxb_unicode_table_map_63743_83527[19784] = { 56, /* F8FF (63743) */ - 3344, /* F900 (63744) */ - 3345, /* F901 (63745) */ - 3346, /* F902 (63746) */ - 3347, /* F903 (63747) */ - 3348, /* F904 (63748) */ - 3349, /* F905 (63749) */ - 3350, /* F906 (63750) */ - 3351, /* F907 (63751) */ - 3351, /* F908 (63752) */ - 3352, /* F909 (63753) */ - 3353, /* F90A (63754) */ - 3354, /* F90B (63755) */ - 3355, /* F90C (63756) */ - 3356, /* F90D (63757) */ - 3357, /* F90E (63758) */ - 3358, /* F90F (63759) */ - 3359, /* F910 (63760) */ - 3360, /* F911 (63761) */ - 3361, /* F912 (63762) */ - 3362, /* F913 (63763) */ - 3363, /* F914 (63764) */ - 3364, /* F915 (63765) */ - 3365, /* F916 (63766) */ - 3366, /* F917 (63767) */ - 3367, /* F918 (63768) */ - 3368, /* F919 (63769) */ - 3369, /* F91A (63770) */ - 3370, /* F91B (63771) */ - 3371, /* F91C (63772) */ - 3372, /* F91D (63773) */ - 3373, /* F91E (63774) */ - 3374, /* F91F (63775) */ - 3375, /* F920 (63776) */ - 3376, /* F921 (63777) */ - 3377, /* F922 (63778) */ - 3378, /* F923 (63779) */ - 3379, /* F924 (63780) */ - 3380, /* F925 (63781) */ - 3381, /* F926 (63782) */ - 3382, /* F927 (63783) */ - 3383, /* F928 (63784) */ - 3384, /* F929 (63785) */ - 3385, /* F92A (63786) */ - 3386, /* F92B (63787) */ - 3387, /* F92C (63788) */ - 3388, /* F92D (63789) */ - 3389, /* F92E (63790) */ - 3390, /* F92F (63791) */ - 3391, /* F930 (63792) */ - 3392, /* F931 (63793) */ - 3393, /* F932 (63794) */ - 3394, /* F933 (63795) */ - 3395, /* F934 (63796) */ - 3396, /* F935 (63797) */ - 3397, /* F936 (63798) */ - 3398, /* F937 (63799) */ - 3399, /* F938 (63800) */ - 3400, /* F939 (63801) */ - 3401, /* F93A (63802) */ - 3402, /* F93B (63803) */ - 3403, /* F93C (63804) */ - 3404, /* F93D (63805) */ - 3405, /* F93E (63806) */ - 3406, /* F93F (63807) */ - 3407, /* F940 (63808) */ - 3408, /* F941 (63809) */ - 3409, /* F942 (63810) */ - 3410, /* F943 (63811) */ - 3411, /* F944 (63812) */ - 3412, /* F945 (63813) */ - 3413, /* F946 (63814) */ - 3414, /* F947 (63815) */ - 3415, /* F948 (63816) */ - 3416, /* F949 (63817) */ - 3417, /* F94A (63818) */ - 3418, /* F94B (63819) */ - 3419, /* F94C (63820) */ - 3420, /* F94D (63821) */ - 3421, /* F94E (63822) */ - 3422, /* F94F (63823) */ - 3423, /* F950 (63824) */ - 3424, /* F951 (63825) */ - 3425, /* F952 (63826) */ - 3426, /* F953 (63827) */ - 3427, /* F954 (63828) */ - 3428, /* F955 (63829) */ - 3429, /* F956 (63830) */ - 3430, /* F957 (63831) */ - 3431, /* F958 (63832) */ - 3432, /* F959 (63833) */ - 3433, /* F95A (63834) */ - 3434, /* F95B (63835) */ - 3363, /* F95C (63836) */ - 3435, /* F95D (63837) */ - 3436, /* F95E (63838) */ - 3437, /* F95F (63839) */ - 3438, /* F960 (63840) */ - 3439, /* F961 (63841) */ - 3440, /* F962 (63842) */ - 3441, /* F963 (63843) */ - 3442, /* F964 (63844) */ - 3443, /* F965 (63845) */ - 3444, /* F966 (63846) */ - 3445, /* F967 (63847) */ - 3446, /* F968 (63848) */ - 3447, /* F969 (63849) */ - 3448, /* F96A (63850) */ - 3449, /* F96B (63851) */ - 3450, /* F96C (63852) */ - 3451, /* F96D (63853) */ - 3452, /* F96E (63854) */ - 3453, /* F96F (63855) */ - 3454, /* F970 (63856) */ - 3455, /* F971 (63857) */ - 3456, /* F972 (63858) */ - 3457, /* F973 (63859) */ - 3458, /* F974 (63860) */ - 3459, /* F975 (63861) */ - 3460, /* F976 (63862) */ - 3461, /* F977 (63863) */ - 3462, /* F978 (63864) */ - 3463, /* F979 (63865) */ - 3464, /* F97A (63866) */ - 3465, /* F97B (63867) */ - 3466, /* F97C (63868) */ - 3467, /* F97D (63869) */ - 3468, /* F97E (63870) */ - 3469, /* F97F (63871) */ - 3470, /* F980 (63872) */ - 3471, /* F981 (63873) */ - 3472, /* F982 (63874) */ - 3473, /* F983 (63875) */ - 3474, /* F984 (63876) */ - 3475, /* F985 (63877) */ - 3476, /* F986 (63878) */ - 3477, /* F987 (63879) */ - 3478, /* F988 (63880) */ - 3479, /* F989 (63881) */ - 3480, /* F98A (63882) */ - 3481, /* F98B (63883) */ - 3482, /* F98C (63884) */ - 3483, /* F98D (63885) */ - 3484, /* F98E (63886) */ - 3485, /* F98F (63887) */ - 3486, /* F990 (63888) */ - 3487, /* F991 (63889) */ - 3488, /* F992 (63890) */ - 3489, /* F993 (63891) */ - 3490, /* F994 (63892) */ - 3491, /* F995 (63893) */ - 3492, /* F996 (63894) */ - 3493, /* F997 (63895) */ - 3494, /* F998 (63896) */ - 3495, /* F999 (63897) */ - 3496, /* F99A (63898) */ - 3497, /* F99B (63899) */ - 3498, /* F99C (63900) */ - 3499, /* F99D (63901) */ - 3500, /* F99E (63902) */ - 3501, /* F99F (63903) */ - 3502, /* F9A0 (63904) */ - 3453, /* F9A1 (63905) */ - 3503, /* F9A2 (63906) */ - 3504, /* F9A3 (63907) */ - 3505, /* F9A4 (63908) */ - 3506, /* F9A5 (63909) */ - 3507, /* F9A6 (63910) */ - 3508, /* F9A7 (63911) */ - 3509, /* F9A8 (63912) */ - 3510, /* F9A9 (63913) */ - 3437, /* F9AA (63914) */ - 3511, /* F9AB (63915) */ - 3512, /* F9AC (63916) */ - 3513, /* F9AD (63917) */ - 3514, /* F9AE (63918) */ - 3515, /* F9AF (63919) */ - 3516, /* F9B0 (63920) */ - 3517, /* F9B1 (63921) */ - 3518, /* F9B2 (63922) */ - 3519, /* F9B3 (63923) */ - 3520, /* F9B4 (63924) */ - 3521, /* F9B5 (63925) */ - 3522, /* F9B6 (63926) */ - 3523, /* F9B7 (63927) */ - 3524, /* F9B8 (63928) */ - 3525, /* F9B9 (63929) */ - 3526, /* F9BA (63930) */ - 3527, /* F9BB (63931) */ - 3528, /* F9BC (63932) */ - 3529, /* F9BD (63933) */ - 3530, /* F9BE (63934) */ - 3363, /* F9BF (63935) */ - 3531, /* F9C0 (63936) */ - 3532, /* F9C1 (63937) */ - 3533, /* F9C2 (63938) */ - 3534, /* F9C3 (63939) */ - 3535, /* F9C4 (63940) */ - 3536, /* F9C5 (63941) */ - 3537, /* F9C6 (63942) */ - 3538, /* F9C7 (63943) */ - 3539, /* F9C8 (63944) */ - 3540, /* F9C9 (63945) */ - 3541, /* F9CA (63946) */ - 3542, /* F9CB (63947) */ - 3543, /* F9CC (63948) */ - 3544, /* F9CD (63949) */ - 3545, /* F9CE (63950) */ - 3546, /* F9CF (63951) */ - 3547, /* F9D0 (63952) */ - 3548, /* F9D1 (63953) */ - 3549, /* F9D2 (63954) */ - 3550, /* F9D3 (63955) */ - 3551, /* F9D4 (63956) */ - 3552, /* F9D5 (63957) */ - 3553, /* F9D6 (63958) */ - 3554, /* F9D7 (63959) */ - 3555, /* F9D8 (63960) */ - 3556, /* F9D9 (63961) */ - 3557, /* F9DA (63962) */ - 3439, /* F9DB (63963) */ - 3558, /* F9DC (63964) */ - 3559, /* F9DD (63965) */ - 3560, /* F9DE (63966) */ - 3561, /* F9DF (63967) */ - 3562, /* F9E0 (63968) */ - 3563, /* F9E1 (63969) */ - 3564, /* F9E2 (63970) */ - 3565, /* F9E3 (63971) */ - 3566, /* F9E4 (63972) */ - 3567, /* F9E5 (63973) */ - 3568, /* F9E6 (63974) */ - 3569, /* F9E7 (63975) */ - 3570, /* F9E8 (63976) */ - 3571, /* F9E9 (63977) */ - 3572, /* F9EA (63978) */ - 3573, /* F9EB (63979) */ - 3574, /* F9EC (63980) */ - 3575, /* F9ED (63981) */ - 3576, /* F9EE (63982) */ - 3577, /* F9EF (63983) */ - 3578, /* F9F0 (63984) */ - 3579, /* F9F1 (63985) */ - 3580, /* F9F2 (63986) */ - 3581, /* F9F3 (63987) */ - 3582, /* F9F4 (63988) */ - 3583, /* F9F5 (63989) */ - 3584, /* F9F6 (63990) */ - 3585, /* F9F7 (63991) */ - 3586, /* F9F8 (63992) */ - 3587, /* F9F9 (63993) */ - 3588, /* F9FA (63994) */ - 3589, /* F9FB (63995) */ - 3590, /* F9FC (63996) */ - 3591, /* F9FD (63997) */ - 3592, /* F9FE (63998) */ - 3593, /* F9FF (63999) */ - 3594, /* FA00 (64000) */ - 3595, /* FA01 (64001) */ - 3596, /* FA02 (64002) */ - 3597, /* FA03 (64003) */ - 3598, /* FA04 (64004) */ - 3599, /* FA05 (64005) */ - 3600, /* FA06 (64006) */ - 3601, /* FA07 (64007) */ - 3602, /* FA08 (64008) */ - 3603, /* FA09 (64009) */ - 3604, /* FA0A (64010) */ - 3605, /* FA0B (64011) */ - 3606, /* FA0C (64012) */ - 3607, /* FA0D (64013) */ + 3348, /* F900 (63744) */ + 3349, /* F901 (63745) */ + 3350, /* F902 (63746) */ + 3351, /* F903 (63747) */ + 3352, /* F904 (63748) */ + 3353, /* F905 (63749) */ + 3354, /* F906 (63750) */ + 3355, /* F907 (63751) */ + 3355, /* F908 (63752) */ + 3356, /* F909 (63753) */ + 3357, /* F90A (63754) */ + 3358, /* F90B (63755) */ + 3359, /* F90C (63756) */ + 3360, /* F90D (63757) */ + 3361, /* F90E (63758) */ + 3362, /* F90F (63759) */ + 3363, /* F910 (63760) */ + 3364, /* F911 (63761) */ + 3365, /* F912 (63762) */ + 3366, /* F913 (63763) */ + 3367, /* F914 (63764) */ + 3368, /* F915 (63765) */ + 3369, /* F916 (63766) */ + 3370, /* F917 (63767) */ + 3371, /* F918 (63768) */ + 3372, /* F919 (63769) */ + 3373, /* F91A (63770) */ + 3374, /* F91B (63771) */ + 3375, /* F91C (63772) */ + 3376, /* F91D (63773) */ + 3377, /* F91E (63774) */ + 3378, /* F91F (63775) */ + 3379, /* F920 (63776) */ + 3380, /* F921 (63777) */ + 3381, /* F922 (63778) */ + 3382, /* F923 (63779) */ + 3383, /* F924 (63780) */ + 3384, /* F925 (63781) */ + 3385, /* F926 (63782) */ + 3386, /* F927 (63783) */ + 3387, /* F928 (63784) */ + 3388, /* F929 (63785) */ + 3389, /* F92A (63786) */ + 3390, /* F92B (63787) */ + 3391, /* F92C (63788) */ + 3392, /* F92D (63789) */ + 3393, /* F92E (63790) */ + 3394, /* F92F (63791) */ + 3395, /* F930 (63792) */ + 3396, /* F931 (63793) */ + 3397, /* F932 (63794) */ + 3398, /* F933 (63795) */ + 3399, /* F934 (63796) */ + 3400, /* F935 (63797) */ + 3401, /* F936 (63798) */ + 3402, /* F937 (63799) */ + 3403, /* F938 (63800) */ + 3404, /* F939 (63801) */ + 3405, /* F93A (63802) */ + 3406, /* F93B (63803) */ + 3407, /* F93C (63804) */ + 3408, /* F93D (63805) */ + 3409, /* F93E (63806) */ + 3410, /* F93F (63807) */ + 3411, /* F940 (63808) */ + 3412, /* F941 (63809) */ + 3413, /* F942 (63810) */ + 3414, /* F943 (63811) */ + 3415, /* F944 (63812) */ + 3416, /* F945 (63813) */ + 3417, /* F946 (63814) */ + 3418, /* F947 (63815) */ + 3419, /* F948 (63816) */ + 3420, /* F949 (63817) */ + 3421, /* F94A (63818) */ + 3422, /* F94B (63819) */ + 3423, /* F94C (63820) */ + 3424, /* F94D (63821) */ + 3425, /* F94E (63822) */ + 3426, /* F94F (63823) */ + 3427, /* F950 (63824) */ + 3428, /* F951 (63825) */ + 3429, /* F952 (63826) */ + 3430, /* F953 (63827) */ + 3431, /* F954 (63828) */ + 3432, /* F955 (63829) */ + 3433, /* F956 (63830) */ + 3434, /* F957 (63831) */ + 3435, /* F958 (63832) */ + 3436, /* F959 (63833) */ + 3437, /* F95A (63834) */ + 3438, /* F95B (63835) */ + 3367, /* F95C (63836) */ + 3439, /* F95D (63837) */ + 3440, /* F95E (63838) */ + 3441, /* F95F (63839) */ + 3442, /* F960 (63840) */ + 3443, /* F961 (63841) */ + 3444, /* F962 (63842) */ + 3445, /* F963 (63843) */ + 3446, /* F964 (63844) */ + 3447, /* F965 (63845) */ + 3448, /* F966 (63846) */ + 3449, /* F967 (63847) */ + 3450, /* F968 (63848) */ + 3451, /* F969 (63849) */ + 3452, /* F96A (63850) */ + 3453, /* F96B (63851) */ + 3454, /* F96C (63852) */ + 3455, /* F96D (63853) */ + 3456, /* F96E (63854) */ + 3457, /* F96F (63855) */ + 3458, /* F970 (63856) */ + 3459, /* F971 (63857) */ + 3460, /* F972 (63858) */ + 3461, /* F973 (63859) */ + 3462, /* F974 (63860) */ + 3463, /* F975 (63861) */ + 3464, /* F976 (63862) */ + 3465, /* F977 (63863) */ + 3466, /* F978 (63864) */ + 3467, /* F979 (63865) */ + 3468, /* F97A (63866) */ + 3469, /* F97B (63867) */ + 3470, /* F97C (63868) */ + 3471, /* F97D (63869) */ + 3472, /* F97E (63870) */ + 3473, /* F97F (63871) */ + 3474, /* F980 (63872) */ + 3475, /* F981 (63873) */ + 3476, /* F982 (63874) */ + 3477, /* F983 (63875) */ + 3478, /* F984 (63876) */ + 3479, /* F985 (63877) */ + 3480, /* F986 (63878) */ + 3481, /* F987 (63879) */ + 3482, /* F988 (63880) */ + 3483, /* F989 (63881) */ + 3484, /* F98A (63882) */ + 3485, /* F98B (63883) */ + 3486, /* F98C (63884) */ + 3487, /* F98D (63885) */ + 3488, /* F98E (63886) */ + 3489, /* F98F (63887) */ + 3490, /* F990 (63888) */ + 3491, /* F991 (63889) */ + 3492, /* F992 (63890) */ + 3493, /* F993 (63891) */ + 3494, /* F994 (63892) */ + 3495, /* F995 (63893) */ + 3496, /* F996 (63894) */ + 3497, /* F997 (63895) */ + 3498, /* F998 (63896) */ + 3499, /* F999 (63897) */ + 3500, /* F99A (63898) */ + 3501, /* F99B (63899) */ + 3502, /* F99C (63900) */ + 3503, /* F99D (63901) */ + 3504, /* F99E (63902) */ + 3505, /* F99F (63903) */ + 3506, /* F9A0 (63904) */ + 3457, /* F9A1 (63905) */ + 3507, /* F9A2 (63906) */ + 3508, /* F9A3 (63907) */ + 3509, /* F9A4 (63908) */ + 3510, /* F9A5 (63909) */ + 3511, /* F9A6 (63910) */ + 3512, /* F9A7 (63911) */ + 3513, /* F9A8 (63912) */ + 3514, /* F9A9 (63913) */ + 3441, /* F9AA (63914) */ + 3515, /* F9AB (63915) */ + 3516, /* F9AC (63916) */ + 3517, /* F9AD (63917) */ + 3518, /* F9AE (63918) */ + 3519, /* F9AF (63919) */ + 3520, /* F9B0 (63920) */ + 3521, /* F9B1 (63921) */ + 3522, /* F9B2 (63922) */ + 3523, /* F9B3 (63923) */ + 3524, /* F9B4 (63924) */ + 3525, /* F9B5 (63925) */ + 3526, /* F9B6 (63926) */ + 3527, /* F9B7 (63927) */ + 3528, /* F9B8 (63928) */ + 3529, /* F9B9 (63929) */ + 3530, /* F9BA (63930) */ + 3531, /* F9BB (63931) */ + 3532, /* F9BC (63932) */ + 3533, /* F9BD (63933) */ + 3534, /* F9BE (63934) */ + 3367, /* F9BF (63935) */ + 3535, /* F9C0 (63936) */ + 3536, /* F9C1 (63937) */ + 3537, /* F9C2 (63938) */ + 3538, /* F9C3 (63939) */ + 3539, /* F9C4 (63940) */ + 3540, /* F9C5 (63941) */ + 3541, /* F9C6 (63942) */ + 3542, /* F9C7 (63943) */ + 3543, /* F9C8 (63944) */ + 3544, /* F9C9 (63945) */ + 3545, /* F9CA (63946) */ + 3546, /* F9CB (63947) */ + 3547, /* F9CC (63948) */ + 3548, /* F9CD (63949) */ + 3549, /* F9CE (63950) */ + 3550, /* F9CF (63951) */ + 3551, /* F9D0 (63952) */ + 3552, /* F9D1 (63953) */ + 3553, /* F9D2 (63954) */ + 3554, /* F9D3 (63955) */ + 3555, /* F9D4 (63956) */ + 3556, /* F9D5 (63957) */ + 3557, /* F9D6 (63958) */ + 3558, /* F9D7 (63959) */ + 3559, /* F9D8 (63960) */ + 3560, /* F9D9 (63961) */ + 3561, /* F9DA (63962) */ + 3443, /* F9DB (63963) */ + 3562, /* F9DC (63964) */ + 3563, /* F9DD (63965) */ + 3564, /* F9DE (63966) */ + 3565, /* F9DF (63967) */ + 3566, /* F9E0 (63968) */ + 3567, /* F9E1 (63969) */ + 3568, /* F9E2 (63970) */ + 3569, /* F9E3 (63971) */ + 3570, /* F9E4 (63972) */ + 3571, /* F9E5 (63973) */ + 3572, /* F9E6 (63974) */ + 3573, /* F9E7 (63975) */ + 3574, /* F9E8 (63976) */ + 3575, /* F9E9 (63977) */ + 3576, /* F9EA (63978) */ + 3577, /* F9EB (63979) */ + 3578, /* F9EC (63980) */ + 3579, /* F9ED (63981) */ + 3580, /* F9EE (63982) */ + 3581, /* F9EF (63983) */ + 3582, /* F9F0 (63984) */ + 3583, /* F9F1 (63985) */ + 3584, /* F9F2 (63986) */ + 3585, /* F9F3 (63987) */ + 3586, /* F9F4 (63988) */ + 3587, /* F9F5 (63989) */ + 3588, /* F9F6 (63990) */ + 3589, /* F9F7 (63991) */ + 3590, /* F9F8 (63992) */ + 3591, /* F9F9 (63993) */ + 3592, /* F9FA (63994) */ + 3593, /* F9FB (63995) */ + 3594, /* F9FC (63996) */ + 3595, /* F9FD (63997) */ + 3596, /* F9FE (63998) */ + 3597, /* F9FF (63999) */ + 3598, /* FA00 (64000) */ + 3599, /* FA01 (64001) */ + 3600, /* FA02 (64002) */ + 3601, /* FA03 (64003) */ + 3602, /* FA04 (64004) */ + 3603, /* FA05 (64005) */ + 3604, /* FA06 (64006) */ + 3605, /* FA07 (64007) */ + 3606, /* FA08 (64008) */ + 3607, /* FA09 (64009) */ + 3608, /* FA0A (64010) */ + 3609, /* FA0B (64011) */ + 3610, /* FA0C (64012) */ + 3611, /* FA0D (64013) */ 1, /* FA0E (64014) */ 1, /* FA0F (64015) */ - 3608, /* FA10 (64016) */ + 3612, /* FA10 (64016) */ 1, /* FA11 (64017) */ - 3609, /* FA12 (64018) */ + 3613, /* FA12 (64018) */ 1, /* FA13 (64019) */ 1, /* FA14 (64020) */ - 3610, /* FA15 (64021) */ - 3611, /* FA16 (64022) */ - 3612, /* FA17 (64023) */ - 3613, /* FA18 (64024) */ - 3614, /* FA19 (64025) */ - 3615, /* FA1A (64026) */ - 3616, /* FA1B (64027) */ - 3617, /* FA1C (64028) */ - 3618, /* FA1D (64029) */ - 3619, /* FA1E (64030) */ + 3614, /* FA15 (64021) */ + 3615, /* FA16 (64022) */ + 3616, /* FA17 (64023) */ + 3617, /* FA18 (64024) */ + 3618, /* FA19 (64025) */ + 3619, /* FA1A (64026) */ + 3620, /* FA1B (64027) */ + 3621, /* FA1C (64028) */ + 3622, /* FA1D (64029) */ + 3623, /* FA1E (64030) */ 1, /* FA1F (64031) */ - 3620, /* FA20 (64032) */ + 3624, /* FA20 (64032) */ 1, /* FA21 (64033) */ - 3621, /* FA22 (64034) */ + 3625, /* FA22 (64034) */ 1, /* FA23 (64035) */ 1, /* FA24 (64036) */ - 3622, /* FA25 (64037) */ - 3623, /* FA26 (64038) */ + 3626, /* FA25 (64037) */ + 3627, /* FA26 (64038) */ 1, /* FA27 (64039) */ 1, /* FA28 (64040) */ 1, /* FA29 (64041) */ - 3624, /* FA2A (64042) */ - 3625, /* FA2B (64043) */ - 3626, /* FA2C (64044) */ - 3627, /* FA2D (64045) */ - 3628, /* FA2E (64046) */ - 3629, /* FA2F (64047) */ - 3630, /* FA30 (64048) */ - 3631, /* FA31 (64049) */ - 3632, /* FA32 (64050) */ - 3633, /* FA33 (64051) */ - 3634, /* FA34 (64052) */ - 3635, /* FA35 (64053) */ - 3636, /* FA36 (64054) */ - 3637, /* FA37 (64055) */ - 3638, /* FA38 (64056) */ - 3639, /* FA39 (64057) */ - 3640, /* FA3A (64058) */ - 3641, /* FA3B (64059) */ - 3642, /* FA3C (64060) */ - 3643, /* FA3D (64061) */ - 3644, /* FA3E (64062) */ - 3645, /* FA3F (64063) */ - 3646, /* FA40 (64064) */ - 3647, /* FA41 (64065) */ - 3648, /* FA42 (64066) */ - 3649, /* FA43 (64067) */ - 3650, /* FA44 (64068) */ - 3651, /* FA45 (64069) */ - 3652, /* FA46 (64070) */ - 3653, /* FA47 (64071) */ - 3654, /* FA48 (64072) */ - 3655, /* FA49 (64073) */ - 3656, /* FA4A (64074) */ - 3657, /* FA4B (64075) */ - 3658, /* FA4C (64076) */ - 3659, /* FA4D (64077) */ - 3660, /* FA4E (64078) */ - 3661, /* FA4F (64079) */ - 3662, /* FA50 (64080) */ - 3663, /* FA51 (64081) */ - 3664, /* FA52 (64082) */ - 3665, /* FA53 (64083) */ - 3666, /* FA54 (64084) */ - 3667, /* FA55 (64085) */ - 3668, /* FA56 (64086) */ - 3492, /* FA57 (64087) */ - 3669, /* FA58 (64088) */ - 3670, /* FA59 (64089) */ - 3671, /* FA5A (64090) */ - 3672, /* FA5B (64091) */ - 3673, /* FA5C (64092) */ - 3674, /* FA5D (64093) */ - 3674, /* FA5E (64094) */ - 3675, /* FA5F (64095) */ - 3676, /* FA60 (64096) */ - 3677, /* FA61 (64097) */ - 3678, /* FA62 (64098) */ - 3679, /* FA63 (64099) */ - 3680, /* FA64 (64100) */ - 3681, /* FA65 (64101) */ - 3682, /* FA66 (64102) */ - 3622, /* FA67 (64103) */ - 3683, /* FA68 (64104) */ - 3684, /* FA69 (64105) */ - 3685, /* FA6A (64106) */ - 3686, /* FA6B (64107) */ - 3687, /* FA6C (64108) */ - 3688, /* FA6D (64109) */ + 3628, /* FA2A (64042) */ + 3629, /* FA2B (64043) */ + 3630, /* FA2C (64044) */ + 3631, /* FA2D (64045) */ + 3632, /* FA2E (64046) */ + 3633, /* FA2F (64047) */ + 3634, /* FA30 (64048) */ + 3635, /* FA31 (64049) */ + 3636, /* FA32 (64050) */ + 3637, /* FA33 (64051) */ + 3638, /* FA34 (64052) */ + 3639, /* FA35 (64053) */ + 3640, /* FA36 (64054) */ + 3641, /* FA37 (64055) */ + 3642, /* FA38 (64056) */ + 3643, /* FA39 (64057) */ + 3644, /* FA3A (64058) */ + 3645, /* FA3B (64059) */ + 3646, /* FA3C (64060) */ + 3647, /* FA3D (64061) */ + 3648, /* FA3E (64062) */ + 3649, /* FA3F (64063) */ + 3650, /* FA40 (64064) */ + 3651, /* FA41 (64065) */ + 3652, /* FA42 (64066) */ + 3653, /* FA43 (64067) */ + 3654, /* FA44 (64068) */ + 3655, /* FA45 (64069) */ + 3656, /* FA46 (64070) */ + 3657, /* FA47 (64071) */ + 3658, /* FA48 (64072) */ + 3659, /* FA49 (64073) */ + 3660, /* FA4A (64074) */ + 3661, /* FA4B (64075) */ + 3662, /* FA4C (64076) */ + 3663, /* FA4D (64077) */ + 3664, /* FA4E (64078) */ + 3665, /* FA4F (64079) */ + 3666, /* FA50 (64080) */ + 3667, /* FA51 (64081) */ + 3668, /* FA52 (64082) */ + 3669, /* FA53 (64083) */ + 3670, /* FA54 (64084) */ + 3671, /* FA55 (64085) */ + 3672, /* FA56 (64086) */ + 3496, /* FA57 (64087) */ + 3673, /* FA58 (64088) */ + 3674, /* FA59 (64089) */ + 3675, /* FA5A (64090) */ + 3676, /* FA5B (64091) */ + 3677, /* FA5C (64092) */ + 3678, /* FA5D (64093) */ + 3678, /* FA5E (64094) */ + 3679, /* FA5F (64095) */ + 3680, /* FA60 (64096) */ + 3681, /* FA61 (64097) */ + 3682, /* FA62 (64098) */ + 3683, /* FA63 (64099) */ + 3684, /* FA64 (64100) */ + 3685, /* FA65 (64101) */ + 3686, /* FA66 (64102) */ + 3626, /* FA67 (64103) */ + 3687, /* FA68 (64104) */ + 3688, /* FA69 (64105) */ + 3689, /* FA6A (64106) */ + 3690, /* FA6B (64107) */ + 3691, /* FA6C (64108) */ + 3692, /* FA6D (64109) */ 56, /* FA6E (64110) */ 56, /* FA6F (64111) */ - 3689, /* FA70 (64112) */ - 3690, /* FA71 (64113) */ - 3691, /* FA72 (64114) */ - 3692, /* FA73 (64115) */ - 3693, /* FA74 (64116) */ - 3694, /* FA75 (64117) */ - 3695, /* FA76 (64118) */ - 3696, /* FA77 (64119) */ - 3636, /* FA78 (64120) */ - 3697, /* FA79 (64121) */ - 3698, /* FA7A (64122) */ - 3699, /* FA7B (64123) */ - 3608, /* FA7C (64124) */ - 3700, /* FA7D (64125) */ - 3701, /* FA7E (64126) */ - 3702, /* FA7F (64127) */ - 3703, /* FA80 (64128) */ - 3704, /* FA81 (64129) */ - 3705, /* FA82 (64130) */ - 3706, /* FA83 (64131) */ - 3707, /* FA84 (64132) */ - 3708, /* FA85 (64133) */ - 3709, /* FA86 (64134) */ - 3710, /* FA87 (64135) */ - 3711, /* FA88 (64136) */ - 3645, /* FA89 (64137) */ - 3712, /* FA8A (64138) */ - 3646, /* FA8B (64139) */ - 3713, /* FA8C (64140) */ - 3714, /* FA8D (64141) */ - 3715, /* FA8E (64142) */ - 3716, /* FA8F (64143) */ - 3717, /* FA90 (64144) */ - 3609, /* FA91 (64145) */ - 3384, /* FA92 (64146) */ - 3718, /* FA93 (64147) */ - 3719, /* FA94 (64148) */ - 3720, /* FA95 (64149) */ - 3454, /* FA96 (64150) */ - 3541, /* FA97 (64151) */ - 3721, /* FA98 (64152) */ - 3722, /* FA99 (64153) */ - 3653, /* FA9A (64154) */ - 3723, /* FA9B (64155) */ - 3654, /* FA9C (64156) */ - 3724, /* FA9D (64157) */ - 3725, /* FA9E (64158) */ - 3726, /* FA9F (64159) */ - 3611, /* FAA0 (64160) */ - 3727, /* FAA1 (64161) */ - 3728, /* FAA2 (64162) */ - 3729, /* FAA3 (64163) */ - 3730, /* FAA4 (64164) */ - 3731, /* FAA5 (64165) */ - 3612, /* FAA6 (64166) */ - 3732, /* FAA7 (64167) */ - 3733, /* FAA8 (64168) */ - 3734, /* FAA9 (64169) */ - 3735, /* FAAA (64170) */ - 3736, /* FAAB (64171) */ - 3737, /* FAAC (64172) */ - 3668, /* FAAD (64173) */ - 3738, /* FAAE (64174) */ - 3739, /* FAAF (64175) */ - 3492, /* FAB0 (64176) */ - 3740, /* FAB1 (64177) */ - 3672, /* FAB2 (64178) */ - 3741, /* FAB3 (64179) */ - 3742, /* FAB4 (64180) */ - 3743, /* FAB5 (64181) */ - 3744, /* FAB6 (64182) */ - 3745, /* FAB7 (64183) */ - 3677, /* FAB8 (64184) */ - 3746, /* FAB9 (64185) */ - 3621, /* FABA (64186) */ - 3747, /* FABB (64187) */ - 3678, /* FABC (64188) */ - 3435, /* FABD (64189) */ - 3748, /* FABE (64190) */ - 3679, /* FABF (64191) */ - 3749, /* FAC0 (64192) */ - 3681, /* FAC1 (64193) */ - 3750, /* FAC2 (64194) */ - 3751, /* FAC3 (64195) */ - 3752, /* FAC4 (64196) */ - 3753, /* FAC5 (64197) */ - 3754, /* FAC6 (64198) */ - 3683, /* FAC7 (64199) */ - 3617, /* FAC8 (64200) */ - 3755, /* FAC9 (64201) */ - 3684, /* FACA (64202) */ - 3756, /* FACB (64203) */ - 3685, /* FACC (64204) */ - 3757, /* FACD (64205) */ - 3351, /* FACE (64206) */ - 3758, /* FACF (64207) */ - 3759, /* FAD0 (64208) */ - 3760, /* FAD1 (64209) */ - 3761, /* FAD2 (64210) */ - 3762, /* FAD3 (64211) */ - 3763, /* FAD4 (64212) */ - 3764, /* FAD5 (64213) */ - 3765, /* FAD6 (64214) */ - 3766, /* FAD7 (64215) */ - 3767, /* FAD8 (64216) */ - 3768, /* FAD9 (64217) */ + 3693, /* FA70 (64112) */ + 3694, /* FA71 (64113) */ + 3695, /* FA72 (64114) */ + 3696, /* FA73 (64115) */ + 3697, /* FA74 (64116) */ + 3698, /* FA75 (64117) */ + 3699, /* FA76 (64118) */ + 3700, /* FA77 (64119) */ + 3640, /* FA78 (64120) */ + 3701, /* FA79 (64121) */ + 3702, /* FA7A (64122) */ + 3703, /* FA7B (64123) */ + 3612, /* FA7C (64124) */ + 3704, /* FA7D (64125) */ + 3705, /* FA7E (64126) */ + 3706, /* FA7F (64127) */ + 3707, /* FA80 (64128) */ + 3708, /* FA81 (64129) */ + 3709, /* FA82 (64130) */ + 3710, /* FA83 (64131) */ + 3711, /* FA84 (64132) */ + 3712, /* FA85 (64133) */ + 3713, /* FA86 (64134) */ + 3714, /* FA87 (64135) */ + 3715, /* FA88 (64136) */ + 3649, /* FA89 (64137) */ + 3716, /* FA8A (64138) */ + 3650, /* FA8B (64139) */ + 3717, /* FA8C (64140) */ + 3718, /* FA8D (64141) */ + 3719, /* FA8E (64142) */ + 3720, /* FA8F (64143) */ + 3721, /* FA90 (64144) */ + 3613, /* FA91 (64145) */ + 3388, /* FA92 (64146) */ + 3722, /* FA93 (64147) */ + 3723, /* FA94 (64148) */ + 3724, /* FA95 (64149) */ + 3458, /* FA96 (64150) */ + 3545, /* FA97 (64151) */ + 3725, /* FA98 (64152) */ + 3726, /* FA99 (64153) */ + 3657, /* FA9A (64154) */ + 3727, /* FA9B (64155) */ + 3658, /* FA9C (64156) */ + 3728, /* FA9D (64157) */ + 3729, /* FA9E (64158) */ + 3730, /* FA9F (64159) */ + 3615, /* FAA0 (64160) */ + 3731, /* FAA1 (64161) */ + 3732, /* FAA2 (64162) */ + 3733, /* FAA3 (64163) */ + 3734, /* FAA4 (64164) */ + 3735, /* FAA5 (64165) */ + 3616, /* FAA6 (64166) */ + 3736, /* FAA7 (64167) */ + 3737, /* FAA8 (64168) */ + 3738, /* FAA9 (64169) */ + 3739, /* FAAA (64170) */ + 3740, /* FAAB (64171) */ + 3741, /* FAAC (64172) */ + 3672, /* FAAD (64173) */ + 3742, /* FAAE (64174) */ + 3743, /* FAAF (64175) */ + 3496, /* FAB0 (64176) */ + 3744, /* FAB1 (64177) */ + 3676, /* FAB2 (64178) */ + 3745, /* FAB3 (64179) */ + 3746, /* FAB4 (64180) */ + 3747, /* FAB5 (64181) */ + 3748, /* FAB6 (64182) */ + 3749, /* FAB7 (64183) */ + 3681, /* FAB8 (64184) */ + 3750, /* FAB9 (64185) */ + 3625, /* FABA (64186) */ + 3751, /* FABB (64187) */ + 3682, /* FABC (64188) */ + 3439, /* FABD (64189) */ + 3752, /* FABE (64190) */ + 3683, /* FABF (64191) */ + 3753, /* FAC0 (64192) */ + 3685, /* FAC1 (64193) */ + 3754, /* FAC2 (64194) */ + 3755, /* FAC3 (64195) */ + 3756, /* FAC4 (64196) */ + 3757, /* FAC5 (64197) */ + 3758, /* FAC6 (64198) */ + 3687, /* FAC7 (64199) */ + 3621, /* FAC8 (64200) */ + 3759, /* FAC9 (64201) */ + 3688, /* FACA (64202) */ + 3760, /* FACB (64203) */ + 3689, /* FACC (64204) */ + 3761, /* FACD (64205) */ + 3355, /* FACE (64206) */ + 3762, /* FACF (64207) */ + 3763, /* FAD0 (64208) */ + 3764, /* FAD1 (64209) */ + 3765, /* FAD2 (64210) */ + 3766, /* FAD3 (64211) */ + 3767, /* FAD4 (64212) */ + 3768, /* FAD5 (64213) */ + 3769, /* FAD6 (64214) */ + 3770, /* FAD7 (64215) */ + 3771, /* FAD8 (64216) */ + 3772, /* FAD9 (64217) */ 56, /* FADA (64218) */ 56, /* FADB (64219) */ 56, /* FADC (64220) */ @@ -57884,13 +57884,13 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* FAFD (64253) */ 56, /* FAFE (64254) */ 56, /* FAFF (64255) */ - 3769, /* FB00 (64256) */ - 3770, /* FB01 (64257) */ - 3771, /* FB02 (64258) */ - 3772, /* FB03 (64259) */ - 3773, /* FB04 (64260) */ - 3774, /* FB05 (64261) */ - 3775, /* FB06 (64262) */ + 3773, /* FB00 (64256) */ + 3774, /* FB01 (64257) */ + 3775, /* FB02 (64258) */ + 3776, /* FB03 (64259) */ + 3777, /* FB04 (64260) */ + 3778, /* FB05 (64261) */ + 3779, /* FB06 (64262) */ 56, /* FB07 (64263) */ 56, /* FB08 (64264) */ 56, /* FB09 (64265) */ @@ -57903,165 +57903,165 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* FB10 (64272) */ 56, /* FB11 (64273) */ 56, /* FB12 (64274) */ - 3776, /* FB13 (64275) */ - 3777, /* FB14 (64276) */ - 3778, /* FB15 (64277) */ - 3779, /* FB16 (64278) */ - 3780, /* FB17 (64279) */ + 3780, /* FB13 (64275) */ + 3781, /* FB14 (64276) */ + 3782, /* FB15 (64277) */ + 3783, /* FB16 (64278) */ + 3784, /* FB17 (64279) */ 56, /* FB18 (64280) */ 56, /* FB19 (64281) */ 56, /* FB1A (64282) */ 56, /* FB1B (64283) */ 56, /* FB1C (64284) */ - 3781, /* FB1D (64285) */ - 3782, /* FB1E (64286) */ - 3783, /* FB1F (64287) */ - 3784, /* FB20 (64288) */ - 3785, /* FB21 (64289) */ - 3786, /* FB22 (64290) */ - 3787, /* FB23 (64291) */ - 3788, /* FB24 (64292) */ - 3789, /* FB25 (64293) */ - 3790, /* FB26 (64294) */ - 3791, /* FB27 (64295) */ - 3792, /* FB28 (64296) */ - 3793, /* FB29 (64297) */ - 3794, /* FB2A (64298) */ - 3795, /* FB2B (64299) */ - 3796, /* FB2C (64300) */ - 3797, /* FB2D (64301) */ - 3798, /* FB2E (64302) */ - 3799, /* FB2F (64303) */ - 3800, /* FB30 (64304) */ - 3801, /* FB31 (64305) */ - 3802, /* FB32 (64306) */ - 3803, /* FB33 (64307) */ - 3804, /* FB34 (64308) */ - 3805, /* FB35 (64309) */ - 3806, /* FB36 (64310) */ + 3785, /* FB1D (64285) */ + 3786, /* FB1E (64286) */ + 3787, /* FB1F (64287) */ + 3788, /* FB20 (64288) */ + 3789, /* FB21 (64289) */ + 3790, /* FB22 (64290) */ + 3791, /* FB23 (64291) */ + 3792, /* FB24 (64292) */ + 3793, /* FB25 (64293) */ + 3794, /* FB26 (64294) */ + 3795, /* FB27 (64295) */ + 3796, /* FB28 (64296) */ + 3797, /* FB29 (64297) */ + 3798, /* FB2A (64298) */ + 3799, /* FB2B (64299) */ + 3800, /* FB2C (64300) */ + 3801, /* FB2D (64301) */ + 3802, /* FB2E (64302) */ + 3803, /* FB2F (64303) */ + 3804, /* FB30 (64304) */ + 3805, /* FB31 (64305) */ + 3806, /* FB32 (64306) */ + 3807, /* FB33 (64307) */ + 3808, /* FB34 (64308) */ + 3809, /* FB35 (64309) */ + 3810, /* FB36 (64310) */ 56, /* FB37 (64311) */ - 3807, /* FB38 (64312) */ - 3808, /* FB39 (64313) */ - 3809, /* FB3A (64314) */ - 3810, /* FB3B (64315) */ - 3811, /* FB3C (64316) */ + 3811, /* FB38 (64312) */ + 3812, /* FB39 (64313) */ + 3813, /* FB3A (64314) */ + 3814, /* FB3B (64315) */ + 3815, /* FB3C (64316) */ 56, /* FB3D (64317) */ - 3812, /* FB3E (64318) */ + 3816, /* FB3E (64318) */ 56, /* FB3F (64319) */ - 3813, /* FB40 (64320) */ - 3814, /* FB41 (64321) */ + 3817, /* FB40 (64320) */ + 3818, /* FB41 (64321) */ 56, /* FB42 (64322) */ - 3815, /* FB43 (64323) */ - 3816, /* FB44 (64324) */ + 3819, /* FB43 (64323) */ + 3820, /* FB44 (64324) */ 56, /* FB45 (64325) */ - 3817, /* FB46 (64326) */ - 3818, /* FB47 (64327) */ - 3819, /* FB48 (64328) */ - 3820, /* FB49 (64329) */ - 3821, /* FB4A (64330) */ - 3822, /* FB4B (64331) */ - 3823, /* FB4C (64332) */ - 3824, /* FB4D (64333) */ - 3825, /* FB4E (64334) */ - 3826, /* FB4F (64335) */ - 3827, /* FB50 (64336) */ - 3828, /* FB51 (64337) */ - 3829, /* FB52 (64338) */ - 3830, /* FB53 (64339) */ - 3831, /* FB54 (64340) */ - 3832, /* FB55 (64341) */ - 3833, /* FB56 (64342) */ - 3834, /* FB57 (64343) */ - 3835, /* FB58 (64344) */ - 3836, /* FB59 (64345) */ - 3837, /* FB5A (64346) */ - 3838, /* FB5B (64347) */ - 3839, /* FB5C (64348) */ - 3840, /* FB5D (64349) */ - 3841, /* FB5E (64350) */ - 3842, /* FB5F (64351) */ - 3843, /* FB60 (64352) */ - 3844, /* FB61 (64353) */ - 3845, /* FB62 (64354) */ - 3846, /* FB63 (64355) */ - 3847, /* FB64 (64356) */ - 3848, /* FB65 (64357) */ - 3849, /* FB66 (64358) */ - 3850, /* FB67 (64359) */ - 3851, /* FB68 (64360) */ - 3852, /* FB69 (64361) */ - 3853, /* FB6A (64362) */ - 3854, /* FB6B (64363) */ - 3855, /* FB6C (64364) */ - 3856, /* FB6D (64365) */ - 3857, /* FB6E (64366) */ - 3858, /* FB6F (64367) */ - 3859, /* FB70 (64368) */ - 3860, /* FB71 (64369) */ - 3861, /* FB72 (64370) */ - 3862, /* FB73 (64371) */ - 3863, /* FB74 (64372) */ - 3864, /* FB75 (64373) */ - 3865, /* FB76 (64374) */ - 3866, /* FB77 (64375) */ - 3867, /* FB78 (64376) */ - 3868, /* FB79 (64377) */ - 3869, /* FB7A (64378) */ - 3870, /* FB7B (64379) */ - 3871, /* FB7C (64380) */ - 3872, /* FB7D (64381) */ - 3873, /* FB7E (64382) */ - 3874, /* FB7F (64383) */ - 3875, /* FB80 (64384) */ - 3876, /* FB81 (64385) */ - 3877, /* FB82 (64386) */ - 3878, /* FB83 (64387) */ - 3879, /* FB84 (64388) */ - 3880, /* FB85 (64389) */ - 3881, /* FB86 (64390) */ - 3882, /* FB87 (64391) */ - 3883, /* FB88 (64392) */ - 3884, /* FB89 (64393) */ - 3885, /* FB8A (64394) */ - 3886, /* FB8B (64395) */ - 3887, /* FB8C (64396) */ - 3888, /* FB8D (64397) */ - 3889, /* FB8E (64398) */ - 3890, /* FB8F (64399) */ - 3891, /* FB90 (64400) */ - 3892, /* FB91 (64401) */ - 3893, /* FB92 (64402) */ - 3894, /* FB93 (64403) */ - 3895, /* FB94 (64404) */ - 3896, /* FB95 (64405) */ - 3897, /* FB96 (64406) */ - 3898, /* FB97 (64407) */ - 3899, /* FB98 (64408) */ - 3900, /* FB99 (64409) */ - 3901, /* FB9A (64410) */ - 3902, /* FB9B (64411) */ - 3903, /* FB9C (64412) */ - 3904, /* FB9D (64413) */ - 3905, /* FB9E (64414) */ - 3906, /* FB9F (64415) */ - 3907, /* FBA0 (64416) */ - 3908, /* FBA1 (64417) */ - 3909, /* FBA2 (64418) */ - 3910, /* FBA3 (64419) */ - 3911, /* FBA4 (64420) */ - 3912, /* FBA5 (64421) */ - 3913, /* FBA6 (64422) */ - 3914, /* FBA7 (64423) */ - 3915, /* FBA8 (64424) */ - 3916, /* FBA9 (64425) */ - 3917, /* FBAA (64426) */ - 3918, /* FBAB (64427) */ - 3919, /* FBAC (64428) */ - 3920, /* FBAD (64429) */ - 3921, /* FBAE (64430) */ - 3922, /* FBAF (64431) */ - 3923, /* FBB0 (64432) */ - 3924, /* FBB1 (64433) */ + 3821, /* FB46 (64326) */ + 3822, /* FB47 (64327) */ + 3823, /* FB48 (64328) */ + 3824, /* FB49 (64329) */ + 3825, /* FB4A (64330) */ + 3826, /* FB4B (64331) */ + 3827, /* FB4C (64332) */ + 3828, /* FB4D (64333) */ + 3829, /* FB4E (64334) */ + 3830, /* FB4F (64335) */ + 3831, /* FB50 (64336) */ + 3832, /* FB51 (64337) */ + 3833, /* FB52 (64338) */ + 3834, /* FB53 (64339) */ + 3835, /* FB54 (64340) */ + 3836, /* FB55 (64341) */ + 3837, /* FB56 (64342) */ + 3838, /* FB57 (64343) */ + 3839, /* FB58 (64344) */ + 3840, /* FB59 (64345) */ + 3841, /* FB5A (64346) */ + 3842, /* FB5B (64347) */ + 3843, /* FB5C (64348) */ + 3844, /* FB5D (64349) */ + 3845, /* FB5E (64350) */ + 3846, /* FB5F (64351) */ + 3847, /* FB60 (64352) */ + 3848, /* FB61 (64353) */ + 3849, /* FB62 (64354) */ + 3850, /* FB63 (64355) */ + 3851, /* FB64 (64356) */ + 3852, /* FB65 (64357) */ + 3853, /* FB66 (64358) */ + 3854, /* FB67 (64359) */ + 3855, /* FB68 (64360) */ + 3856, /* FB69 (64361) */ + 3857, /* FB6A (64362) */ + 3858, /* FB6B (64363) */ + 3859, /* FB6C (64364) */ + 3860, /* FB6D (64365) */ + 3861, /* FB6E (64366) */ + 3862, /* FB6F (64367) */ + 3863, /* FB70 (64368) */ + 3864, /* FB71 (64369) */ + 3865, /* FB72 (64370) */ + 3866, /* FB73 (64371) */ + 3867, /* FB74 (64372) */ + 3868, /* FB75 (64373) */ + 3869, /* FB76 (64374) */ + 3870, /* FB77 (64375) */ + 3871, /* FB78 (64376) */ + 3872, /* FB79 (64377) */ + 3873, /* FB7A (64378) */ + 3874, /* FB7B (64379) */ + 3875, /* FB7C (64380) */ + 3876, /* FB7D (64381) */ + 3877, /* FB7E (64382) */ + 3878, /* FB7F (64383) */ + 3879, /* FB80 (64384) */ + 3880, /* FB81 (64385) */ + 3881, /* FB82 (64386) */ + 3882, /* FB83 (64387) */ + 3883, /* FB84 (64388) */ + 3884, /* FB85 (64389) */ + 3885, /* FB86 (64390) */ + 3886, /* FB87 (64391) */ + 3887, /* FB88 (64392) */ + 3888, /* FB89 (64393) */ + 3889, /* FB8A (64394) */ + 3890, /* FB8B (64395) */ + 3891, /* FB8C (64396) */ + 3892, /* FB8D (64397) */ + 3893, /* FB8E (64398) */ + 3894, /* FB8F (64399) */ + 3895, /* FB90 (64400) */ + 3896, /* FB91 (64401) */ + 3897, /* FB92 (64402) */ + 3898, /* FB93 (64403) */ + 3899, /* FB94 (64404) */ + 3900, /* FB95 (64405) */ + 3901, /* FB96 (64406) */ + 3902, /* FB97 (64407) */ + 3903, /* FB98 (64408) */ + 3904, /* FB99 (64409) */ + 3905, /* FB9A (64410) */ + 3906, /* FB9B (64411) */ + 3907, /* FB9C (64412) */ + 3908, /* FB9D (64413) */ + 3909, /* FB9E (64414) */ + 3910, /* FB9F (64415) */ + 3911, /* FBA0 (64416) */ + 3912, /* FBA1 (64417) */ + 3913, /* FBA2 (64418) */ + 3914, /* FBA3 (64419) */ + 3915, /* FBA4 (64420) */ + 3916, /* FBA5 (64421) */ + 3917, /* FBA6 (64422) */ + 3918, /* FBA7 (64423) */ + 3919, /* FBA8 (64424) */ + 3920, /* FBA9 (64425) */ + 3921, /* FBAA (64426) */ + 3922, /* FBAB (64427) */ + 3923, /* FBAC (64428) */ + 3924, /* FBAD (64429) */ + 3925, /* FBAE (64430) */ + 3926, /* FBAF (64431) */ + 3927, /* FBB0 (64432) */ + 3928, /* FBB1 (64433) */ 1, /* FBB2 (64434) */ 1, /* FBB3 (64435) */ 1, /* FBB4 (64436) */ @@ -58079,385 +58079,385 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* FBC0 (64448) */ 1, /* FBC1 (64449) */ 1, /* FBC2 (64450) */ - 56, /* FBC3 (64451) */ - 56, /* FBC4 (64452) */ - 56, /* FBC5 (64453) */ - 56, /* FBC6 (64454) */ - 56, /* FBC7 (64455) */ - 56, /* FBC8 (64456) */ - 56, /* FBC9 (64457) */ - 56, /* FBCA (64458) */ - 56, /* FBCB (64459) */ - 56, /* FBCC (64460) */ - 56, /* FBCD (64461) */ - 56, /* FBCE (64462) */ - 56, /* FBCF (64463) */ - 56, /* FBD0 (64464) */ - 56, /* FBD1 (64465) */ - 56, /* FBD2 (64466) */ - 3925, /* FBD3 (64467) */ - 3926, /* FBD4 (64468) */ - 3927, /* FBD5 (64469) */ - 3928, /* FBD6 (64470) */ - 3929, /* FBD7 (64471) */ - 3930, /* FBD8 (64472) */ - 3931, /* FBD9 (64473) */ - 3932, /* FBDA (64474) */ - 3933, /* FBDB (64475) */ - 3934, /* FBDC (64476) */ - 3935, /* FBDD (64477) */ - 3936, /* FBDE (64478) */ - 3937, /* FBDF (64479) */ - 3938, /* FBE0 (64480) */ - 3939, /* FBE1 (64481) */ - 3940, /* FBE2 (64482) */ - 3941, /* FBE3 (64483) */ - 3942, /* FBE4 (64484) */ - 3943, /* FBE5 (64485) */ - 3944, /* FBE6 (64486) */ - 3945, /* FBE7 (64487) */ - 3946, /* FBE8 (64488) */ - 3947, /* FBE9 (64489) */ - 3948, /* FBEA (64490) */ - 3949, /* FBEB (64491) */ - 3950, /* FBEC (64492) */ - 3951, /* FBED (64493) */ - 3952, /* FBEE (64494) */ - 3953, /* FBEF (64495) */ - 3954, /* FBF0 (64496) */ - 3955, /* FBF1 (64497) */ - 3956, /* FBF2 (64498) */ - 3957, /* FBF3 (64499) */ - 3958, /* FBF4 (64500) */ - 3959, /* FBF5 (64501) */ - 3960, /* FBF6 (64502) */ - 3961, /* FBF7 (64503) */ - 3962, /* FBF8 (64504) */ - 3963, /* FBF9 (64505) */ - 3964, /* FBFA (64506) */ - 3965, /* FBFB (64507) */ - 3966, /* FBFC (64508) */ - 3967, /* FBFD (64509) */ - 3968, /* FBFE (64510) */ - 3969, /* FBFF (64511) */ - 3970, /* FC00 (64512) */ - 3971, /* FC01 (64513) */ - 3972, /* FC02 (64514) */ - 3963, /* FC03 (64515) */ - 3973, /* FC04 (64516) */ - 3974, /* FC05 (64517) */ - 3975, /* FC06 (64518) */ - 3976, /* FC07 (64519) */ - 3977, /* FC08 (64520) */ - 3978, /* FC09 (64521) */ - 3979, /* FC0A (64522) */ - 3980, /* FC0B (64523) */ - 3981, /* FC0C (64524) */ - 3982, /* FC0D (64525) */ - 3983, /* FC0E (64526) */ - 3984, /* FC0F (64527) */ - 3985, /* FC10 (64528) */ - 3986, /* FC11 (64529) */ - 3987, /* FC12 (64530) */ - 3988, /* FC13 (64531) */ - 3989, /* FC14 (64532) */ - 3990, /* FC15 (64533) */ - 3991, /* FC16 (64534) */ - 3992, /* FC17 (64535) */ - 3993, /* FC18 (64536) */ - 3994, /* FC19 (64537) */ - 3995, /* FC1A (64538) */ - 3996, /* FC1B (64539) */ - 3997, /* FC1C (64540) */ - 3998, /* FC1D (64541) */ - 3999, /* FC1E (64542) */ - 4000, /* FC1F (64543) */ - 4001, /* FC20 (64544) */ - 4002, /* FC21 (64545) */ - 4003, /* FC22 (64546) */ - 4004, /* FC23 (64547) */ - 4005, /* FC24 (64548) */ - 4006, /* FC25 (64549) */ - 4007, /* FC26 (64550) */ - 4008, /* FC27 (64551) */ - 4009, /* FC28 (64552) */ - 4010, /* FC29 (64553) */ - 4011, /* FC2A (64554) */ - 4012, /* FC2B (64555) */ - 4013, /* FC2C (64556) */ - 4014, /* FC2D (64557) */ - 4015, /* FC2E (64558) */ - 4016, /* FC2F (64559) */ - 4017, /* FC30 (64560) */ - 4018, /* FC31 (64561) */ - 4019, /* FC32 (64562) */ - 4020, /* FC33 (64563) */ - 4021, /* FC34 (64564) */ - 4022, /* FC35 (64565) */ - 4023, /* FC36 (64566) */ - 4024, /* FC37 (64567) */ - 4025, /* FC38 (64568) */ - 4026, /* FC39 (64569) */ - 4027, /* FC3A (64570) */ - 4028, /* FC3B (64571) */ - 4029, /* FC3C (64572) */ - 4030, /* FC3D (64573) */ - 4031, /* FC3E (64574) */ - 4032, /* FC3F (64575) */ - 4033, /* FC40 (64576) */ - 4034, /* FC41 (64577) */ - 4035, /* FC42 (64578) */ - 4036, /* FC43 (64579) */ - 4037, /* FC44 (64580) */ - 4038, /* FC45 (64581) */ - 4039, /* FC46 (64582) */ - 4040, /* FC47 (64583) */ - 4041, /* FC48 (64584) */ - 4042, /* FC49 (64585) */ - 4043, /* FC4A (64586) */ - 4044, /* FC4B (64587) */ - 4045, /* FC4C (64588) */ - 4046, /* FC4D (64589) */ - 4047, /* FC4E (64590) */ - 4048, /* FC4F (64591) */ - 4049, /* FC50 (64592) */ - 4050, /* FC51 (64593) */ - 4051, /* FC52 (64594) */ - 4052, /* FC53 (64595) */ - 4053, /* FC54 (64596) */ - 4054, /* FC55 (64597) */ - 4055, /* FC56 (64598) */ - 4056, /* FC57 (64599) */ - 4057, /* FC58 (64600) */ - 4058, /* FC59 (64601) */ - 4059, /* FC5A (64602) */ - 4060, /* FC5B (64603) */ - 4061, /* FC5C (64604) */ - 4062, /* FC5D (64605) */ - 4063, /* FC5E (64606) */ - 4064, /* FC5F (64607) */ - 4065, /* FC60 (64608) */ - 4066, /* FC61 (64609) */ - 4067, /* FC62 (64610) */ - 4068, /* FC63 (64611) */ - 4069, /* FC64 (64612) */ - 4070, /* FC65 (64613) */ - 4071, /* FC66 (64614) */ - 4072, /* FC67 (64615) */ - 3964, /* FC68 (64616) */ - 4073, /* FC69 (64617) */ - 4074, /* FC6A (64618) */ - 4075, /* FC6B (64619) */ - 4076, /* FC6C (64620) */ - 4077, /* FC6D (64621) */ - 4078, /* FC6E (64622) */ - 4079, /* FC6F (64623) */ - 4080, /* FC70 (64624) */ - 4081, /* FC71 (64625) */ - 4082, /* FC72 (64626) */ - 4083, /* FC73 (64627) */ - 4084, /* FC74 (64628) */ - 4085, /* FC75 (64629) */ - 4086, /* FC76 (64630) */ - 4087, /* FC77 (64631) */ - 4088, /* FC78 (64632) */ - 4089, /* FC79 (64633) */ - 4090, /* FC7A (64634) */ - 4091, /* FC7B (64635) */ - 4092, /* FC7C (64636) */ - 4093, /* FC7D (64637) */ - 4094, /* FC7E (64638) */ - 4095, /* FC7F (64639) */ - 4096, /* FC80 (64640) */ - 4097, /* FC81 (64641) */ - 4098, /* FC82 (64642) */ - 4099, /* FC83 (64643) */ - 4100, /* FC84 (64644) */ - 4101, /* FC85 (64645) */ - 4102, /* FC86 (64646) */ - 4103, /* FC87 (64647) */ - 4104, /* FC88 (64648) */ - 4105, /* FC89 (64649) */ - 4106, /* FC8A (64650) */ - 4107, /* FC8B (64651) */ - 4108, /* FC8C (64652) */ - 4109, /* FC8D (64653) */ - 4110, /* FC8E (64654) */ - 4111, /* FC8F (64655) */ - 4112, /* FC90 (64656) */ - 4113, /* FC91 (64657) */ - 4114, /* FC92 (64658) */ - 4115, /* FC93 (64659) */ - 4116, /* FC94 (64660) */ - 4117, /* FC95 (64661) */ - 4118, /* FC96 (64662) */ - 4119, /* FC97 (64663) */ - 4120, /* FC98 (64664) */ - 4121, /* FC99 (64665) */ - 4122, /* FC9A (64666) */ - 4123, /* FC9B (64667) */ - 4124, /* FC9C (64668) */ - 4125, /* FC9D (64669) */ - 4126, /* FC9E (64670) */ - 4127, /* FC9F (64671) */ - 4128, /* FCA0 (64672) */ - 4129, /* FCA1 (64673) */ - 4130, /* FCA2 (64674) */ - 4131, /* FCA3 (64675) */ - 4132, /* FCA4 (64676) */ - 4133, /* FCA5 (64677) */ - 4134, /* FCA6 (64678) */ - 4135, /* FCA7 (64679) */ - 4136, /* FCA8 (64680) */ - 4137, /* FCA9 (64681) */ - 4138, /* FCAA (64682) */ - 4139, /* FCAB (64683) */ - 4140, /* FCAC (64684) */ - 4141, /* FCAD (64685) */ - 4142, /* FCAE (64686) */ - 4143, /* FCAF (64687) */ - 4144, /* FCB0 (64688) */ - 4145, /* FCB1 (64689) */ - 4146, /* FCB2 (64690) */ - 4147, /* FCB3 (64691) */ - 4148, /* FCB4 (64692) */ - 4149, /* FCB5 (64693) */ - 4150, /* FCB6 (64694) */ - 4151, /* FCB7 (64695) */ - 4152, /* FCB8 (64696) */ - 4153, /* FCB9 (64697) */ - 4154, /* FCBA (64698) */ - 4155, /* FCBB (64699) */ - 4156, /* FCBC (64700) */ - 4157, /* FCBD (64701) */ - 4158, /* FCBE (64702) */ - 4159, /* FCBF (64703) */ - 4160, /* FCC0 (64704) */ - 4161, /* FCC1 (64705) */ - 4162, /* FCC2 (64706) */ - 4163, /* FCC3 (64707) */ - 4164, /* FCC4 (64708) */ - 4165, /* FCC5 (64709) */ - 4166, /* FCC6 (64710) */ - 4167, /* FCC7 (64711) */ - 4168, /* FCC8 (64712) */ - 4169, /* FCC9 (64713) */ - 4170, /* FCCA (64714) */ - 4171, /* FCCB (64715) */ - 4172, /* FCCC (64716) */ - 4173, /* FCCD (64717) */ - 4174, /* FCCE (64718) */ - 4175, /* FCCF (64719) */ - 4176, /* FCD0 (64720) */ - 4177, /* FCD1 (64721) */ - 4178, /* FCD2 (64722) */ - 4179, /* FCD3 (64723) */ - 4180, /* FCD4 (64724) */ - 4181, /* FCD5 (64725) */ - 4182, /* FCD6 (64726) */ - 4183, /* FCD7 (64727) */ - 4184, /* FCD8 (64728) */ - 4185, /* FCD9 (64729) */ - 4186, /* FCDA (64730) */ - 4187, /* FCDB (64731) */ - 4188, /* FCDC (64732) */ - 4189, /* FCDD (64733) */ - 4190, /* FCDE (64734) */ - 4191, /* FCDF (64735) */ - 4192, /* FCE0 (64736) */ - 4193, /* FCE1 (64737) */ - 4194, /* FCE2 (64738) */ - 4195, /* FCE3 (64739) */ - 4196, /* FCE4 (64740) */ - 4197, /* FCE5 (64741) */ - 4198, /* FCE6 (64742) */ - 4199, /* FCE7 (64743) */ - 4200, /* FCE8 (64744) */ - 4201, /* FCE9 (64745) */ - 4202, /* FCEA (64746) */ - 4203, /* FCEB (64747) */ - 4204, /* FCEC (64748) */ - 4205, /* FCED (64749) */ - 4206, /* FCEE (64750) */ - 4207, /* FCEF (64751) */ - 4208, /* FCF0 (64752) */ - 4209, /* FCF1 (64753) */ - 4210, /* FCF2 (64754) */ - 4211, /* FCF3 (64755) */ - 4212, /* FCF4 (64756) */ - 4213, /* FCF5 (64757) */ - 4214, /* FCF6 (64758) */ - 4215, /* FCF7 (64759) */ - 4216, /* FCF8 (64760) */ - 4217, /* FCF9 (64761) */ - 4218, /* FCFA (64762) */ - 4219, /* FCFB (64763) */ - 4220, /* FCFC (64764) */ - 4221, /* FCFD (64765) */ - 4222, /* FCFE (64766) */ - 4223, /* FCFF (64767) */ - 4224, /* FD00 (64768) */ - 4225, /* FD01 (64769) */ - 4226, /* FD02 (64770) */ - 4227, /* FD03 (64771) */ - 4228, /* FD04 (64772) */ - 4229, /* FD05 (64773) */ - 4230, /* FD06 (64774) */ - 4231, /* FD07 (64775) */ - 4232, /* FD08 (64776) */ - 4233, /* FD09 (64777) */ - 4234, /* FD0A (64778) */ - 4235, /* FD0B (64779) */ - 4236, /* FD0C (64780) */ - 4237, /* FD0D (64781) */ - 4238, /* FD0E (64782) */ - 4239, /* FD0F (64783) */ - 4240, /* FD10 (64784) */ - 4241, /* FD11 (64785) */ - 4242, /* FD12 (64786) */ - 4243, /* FD13 (64787) */ - 4244, /* FD14 (64788) */ - 4245, /* FD15 (64789) */ - 4246, /* FD16 (64790) */ - 4247, /* FD17 (64791) */ - 4248, /* FD18 (64792) */ - 4249, /* FD19 (64793) */ - 4250, /* FD1A (64794) */ - 4251, /* FD1B (64795) */ - 4252, /* FD1C (64796) */ - 4253, /* FD1D (64797) */ - 4254, /* FD1E (64798) */ - 4255, /* FD1F (64799) */ - 4256, /* FD20 (64800) */ - 4257, /* FD21 (64801) */ - 4258, /* FD22 (64802) */ - 4259, /* FD23 (64803) */ - 4260, /* FD24 (64804) */ - 4261, /* FD25 (64805) */ - 4262, /* FD26 (64806) */ - 4263, /* FD27 (64807) */ - 4264, /* FD28 (64808) */ - 4265, /* FD29 (64809) */ - 4266, /* FD2A (64810) */ - 4267, /* FD2B (64811) */ - 4268, /* FD2C (64812) */ - 4269, /* FD2D (64813) */ - 4270, /* FD2E (64814) */ - 4271, /* FD2F (64815) */ - 4272, /* FD30 (64816) */ - 4273, /* FD31 (64817) */ - 4274, /* FD32 (64818) */ - 4275, /* FD33 (64819) */ - 4276, /* FD34 (64820) */ - 4277, /* FD35 (64821) */ - 4278, /* FD36 (64822) */ - 4279, /* FD37 (64823) */ - 4280, /* FD38 (64824) */ - 4281, /* FD39 (64825) */ - 4282, /* FD3A (64826) */ - 4283, /* FD3B (64827) */ - 4284, /* FD3C (64828) */ - 4285, /* FD3D (64829) */ + 1, /* FBC3 (64451) */ + 1, /* FBC4 (64452) */ + 1, /* FBC5 (64453) */ + 1, /* FBC6 (64454) */ + 1, /* FBC7 (64455) */ + 1, /* FBC8 (64456) */ + 1, /* FBC9 (64457) */ + 1, /* FBCA (64458) */ + 1, /* FBCB (64459) */ + 1, /* FBCC (64460) */ + 1, /* FBCD (64461) */ + 1, /* FBCE (64462) */ + 1, /* FBCF (64463) */ + 1, /* FBD0 (64464) */ + 1, /* FBD1 (64465) */ + 1, /* FBD2 (64466) */ + 3929, /* FBD3 (64467) */ + 3930, /* FBD4 (64468) */ + 3931, /* FBD5 (64469) */ + 3932, /* FBD6 (64470) */ + 3933, /* FBD7 (64471) */ + 3934, /* FBD8 (64472) */ + 3935, /* FBD9 (64473) */ + 3936, /* FBDA (64474) */ + 3937, /* FBDB (64475) */ + 3938, /* FBDC (64476) */ + 3939, /* FBDD (64477) */ + 3940, /* FBDE (64478) */ + 3941, /* FBDF (64479) */ + 3942, /* FBE0 (64480) */ + 3943, /* FBE1 (64481) */ + 3944, /* FBE2 (64482) */ + 3945, /* FBE3 (64483) */ + 3946, /* FBE4 (64484) */ + 3947, /* FBE5 (64485) */ + 3948, /* FBE6 (64486) */ + 3949, /* FBE7 (64487) */ + 3950, /* FBE8 (64488) */ + 3951, /* FBE9 (64489) */ + 3952, /* FBEA (64490) */ + 3953, /* FBEB (64491) */ + 3954, /* FBEC (64492) */ + 3955, /* FBED (64493) */ + 3956, /* FBEE (64494) */ + 3957, /* FBEF (64495) */ + 3958, /* FBF0 (64496) */ + 3959, /* FBF1 (64497) */ + 3960, /* FBF2 (64498) */ + 3961, /* FBF3 (64499) */ + 3962, /* FBF4 (64500) */ + 3963, /* FBF5 (64501) */ + 3964, /* FBF6 (64502) */ + 3965, /* FBF7 (64503) */ + 3966, /* FBF8 (64504) */ + 3967, /* FBF9 (64505) */ + 3968, /* FBFA (64506) */ + 3969, /* FBFB (64507) */ + 3970, /* FBFC (64508) */ + 3971, /* FBFD (64509) */ + 3972, /* FBFE (64510) */ + 3973, /* FBFF (64511) */ + 3974, /* FC00 (64512) */ + 3975, /* FC01 (64513) */ + 3976, /* FC02 (64514) */ + 3967, /* FC03 (64515) */ + 3977, /* FC04 (64516) */ + 3978, /* FC05 (64517) */ + 3979, /* FC06 (64518) */ + 3980, /* FC07 (64519) */ + 3981, /* FC08 (64520) */ + 3982, /* FC09 (64521) */ + 3983, /* FC0A (64522) */ + 3984, /* FC0B (64523) */ + 3985, /* FC0C (64524) */ + 3986, /* FC0D (64525) */ + 3987, /* FC0E (64526) */ + 3988, /* FC0F (64527) */ + 3989, /* FC10 (64528) */ + 3990, /* FC11 (64529) */ + 3991, /* FC12 (64530) */ + 3992, /* FC13 (64531) */ + 3993, /* FC14 (64532) */ + 3994, /* FC15 (64533) */ + 3995, /* FC16 (64534) */ + 3996, /* FC17 (64535) */ + 3997, /* FC18 (64536) */ + 3998, /* FC19 (64537) */ + 3999, /* FC1A (64538) */ + 4000, /* FC1B (64539) */ + 4001, /* FC1C (64540) */ + 4002, /* FC1D (64541) */ + 4003, /* FC1E (64542) */ + 4004, /* FC1F (64543) */ + 4005, /* FC20 (64544) */ + 4006, /* FC21 (64545) */ + 4007, /* FC22 (64546) */ + 4008, /* FC23 (64547) */ + 4009, /* FC24 (64548) */ + 4010, /* FC25 (64549) */ + 4011, /* FC26 (64550) */ + 4012, /* FC27 (64551) */ + 4013, /* FC28 (64552) */ + 4014, /* FC29 (64553) */ + 4015, /* FC2A (64554) */ + 4016, /* FC2B (64555) */ + 4017, /* FC2C (64556) */ + 4018, /* FC2D (64557) */ + 4019, /* FC2E (64558) */ + 4020, /* FC2F (64559) */ + 4021, /* FC30 (64560) */ + 4022, /* FC31 (64561) */ + 4023, /* FC32 (64562) */ + 4024, /* FC33 (64563) */ + 4025, /* FC34 (64564) */ + 4026, /* FC35 (64565) */ + 4027, /* FC36 (64566) */ + 4028, /* FC37 (64567) */ + 4029, /* FC38 (64568) */ + 4030, /* FC39 (64569) */ + 4031, /* FC3A (64570) */ + 4032, /* FC3B (64571) */ + 4033, /* FC3C (64572) */ + 4034, /* FC3D (64573) */ + 4035, /* FC3E (64574) */ + 4036, /* FC3F (64575) */ + 4037, /* FC40 (64576) */ + 4038, /* FC41 (64577) */ + 4039, /* FC42 (64578) */ + 4040, /* FC43 (64579) */ + 4041, /* FC44 (64580) */ + 4042, /* FC45 (64581) */ + 4043, /* FC46 (64582) */ + 4044, /* FC47 (64583) */ + 4045, /* FC48 (64584) */ + 4046, /* FC49 (64585) */ + 4047, /* FC4A (64586) */ + 4048, /* FC4B (64587) */ + 4049, /* FC4C (64588) */ + 4050, /* FC4D (64589) */ + 4051, /* FC4E (64590) */ + 4052, /* FC4F (64591) */ + 4053, /* FC50 (64592) */ + 4054, /* FC51 (64593) */ + 4055, /* FC52 (64594) */ + 4056, /* FC53 (64595) */ + 4057, /* FC54 (64596) */ + 4058, /* FC55 (64597) */ + 4059, /* FC56 (64598) */ + 4060, /* FC57 (64599) */ + 4061, /* FC58 (64600) */ + 4062, /* FC59 (64601) */ + 4063, /* FC5A (64602) */ + 4064, /* FC5B (64603) */ + 4065, /* FC5C (64604) */ + 4066, /* FC5D (64605) */ + 4067, /* FC5E (64606) */ + 4068, /* FC5F (64607) */ + 4069, /* FC60 (64608) */ + 4070, /* FC61 (64609) */ + 4071, /* FC62 (64610) */ + 4072, /* FC63 (64611) */ + 4073, /* FC64 (64612) */ + 4074, /* FC65 (64613) */ + 4075, /* FC66 (64614) */ + 4076, /* FC67 (64615) */ + 3968, /* FC68 (64616) */ + 4077, /* FC69 (64617) */ + 4078, /* FC6A (64618) */ + 4079, /* FC6B (64619) */ + 4080, /* FC6C (64620) */ + 4081, /* FC6D (64621) */ + 4082, /* FC6E (64622) */ + 4083, /* FC6F (64623) */ + 4084, /* FC70 (64624) */ + 4085, /* FC71 (64625) */ + 4086, /* FC72 (64626) */ + 4087, /* FC73 (64627) */ + 4088, /* FC74 (64628) */ + 4089, /* FC75 (64629) */ + 4090, /* FC76 (64630) */ + 4091, /* FC77 (64631) */ + 4092, /* FC78 (64632) */ + 4093, /* FC79 (64633) */ + 4094, /* FC7A (64634) */ + 4095, /* FC7B (64635) */ + 4096, /* FC7C (64636) */ + 4097, /* FC7D (64637) */ + 4098, /* FC7E (64638) */ + 4099, /* FC7F (64639) */ + 4100, /* FC80 (64640) */ + 4101, /* FC81 (64641) */ + 4102, /* FC82 (64642) */ + 4103, /* FC83 (64643) */ + 4104, /* FC84 (64644) */ + 4105, /* FC85 (64645) */ + 4106, /* FC86 (64646) */ + 4107, /* FC87 (64647) */ + 4108, /* FC88 (64648) */ + 4109, /* FC89 (64649) */ + 4110, /* FC8A (64650) */ + 4111, /* FC8B (64651) */ + 4112, /* FC8C (64652) */ + 4113, /* FC8D (64653) */ + 4114, /* FC8E (64654) */ + 4115, /* FC8F (64655) */ + 4116, /* FC90 (64656) */ + 4117, /* FC91 (64657) */ + 4118, /* FC92 (64658) */ + 4119, /* FC93 (64659) */ + 4120, /* FC94 (64660) */ + 4121, /* FC95 (64661) */ + 4122, /* FC96 (64662) */ + 4123, /* FC97 (64663) */ + 4124, /* FC98 (64664) */ + 4125, /* FC99 (64665) */ + 4126, /* FC9A (64666) */ + 4127, /* FC9B (64667) */ + 4128, /* FC9C (64668) */ + 4129, /* FC9D (64669) */ + 4130, /* FC9E (64670) */ + 4131, /* FC9F (64671) */ + 4132, /* FCA0 (64672) */ + 4133, /* FCA1 (64673) */ + 4134, /* FCA2 (64674) */ + 4135, /* FCA3 (64675) */ + 4136, /* FCA4 (64676) */ + 4137, /* FCA5 (64677) */ + 4138, /* FCA6 (64678) */ + 4139, /* FCA7 (64679) */ + 4140, /* FCA8 (64680) */ + 4141, /* FCA9 (64681) */ + 4142, /* FCAA (64682) */ + 4143, /* FCAB (64683) */ + 4144, /* FCAC (64684) */ + 4145, /* FCAD (64685) */ + 4146, /* FCAE (64686) */ + 4147, /* FCAF (64687) */ + 4148, /* FCB0 (64688) */ + 4149, /* FCB1 (64689) */ + 4150, /* FCB2 (64690) */ + 4151, /* FCB3 (64691) */ + 4152, /* FCB4 (64692) */ + 4153, /* FCB5 (64693) */ + 4154, /* FCB6 (64694) */ + 4155, /* FCB7 (64695) */ + 4156, /* FCB8 (64696) */ + 4157, /* FCB9 (64697) */ + 4158, /* FCBA (64698) */ + 4159, /* FCBB (64699) */ + 4160, /* FCBC (64700) */ + 4161, /* FCBD (64701) */ + 4162, /* FCBE (64702) */ + 4163, /* FCBF (64703) */ + 4164, /* FCC0 (64704) */ + 4165, /* FCC1 (64705) */ + 4166, /* FCC2 (64706) */ + 4167, /* FCC3 (64707) */ + 4168, /* FCC4 (64708) */ + 4169, /* FCC5 (64709) */ + 4170, /* FCC6 (64710) */ + 4171, /* FCC7 (64711) */ + 4172, /* FCC8 (64712) */ + 4173, /* FCC9 (64713) */ + 4174, /* FCCA (64714) */ + 4175, /* FCCB (64715) */ + 4176, /* FCCC (64716) */ + 4177, /* FCCD (64717) */ + 4178, /* FCCE (64718) */ + 4179, /* FCCF (64719) */ + 4180, /* FCD0 (64720) */ + 4181, /* FCD1 (64721) */ + 4182, /* FCD2 (64722) */ + 4183, /* FCD3 (64723) */ + 4184, /* FCD4 (64724) */ + 4185, /* FCD5 (64725) */ + 4186, /* FCD6 (64726) */ + 4187, /* FCD7 (64727) */ + 4188, /* FCD8 (64728) */ + 4189, /* FCD9 (64729) */ + 4190, /* FCDA (64730) */ + 4191, /* FCDB (64731) */ + 4192, /* FCDC (64732) */ + 4193, /* FCDD (64733) */ + 4194, /* FCDE (64734) */ + 4195, /* FCDF (64735) */ + 4196, /* FCE0 (64736) */ + 4197, /* FCE1 (64737) */ + 4198, /* FCE2 (64738) */ + 4199, /* FCE3 (64739) */ + 4200, /* FCE4 (64740) */ + 4201, /* FCE5 (64741) */ + 4202, /* FCE6 (64742) */ + 4203, /* FCE7 (64743) */ + 4204, /* FCE8 (64744) */ + 4205, /* FCE9 (64745) */ + 4206, /* FCEA (64746) */ + 4207, /* FCEB (64747) */ + 4208, /* FCEC (64748) */ + 4209, /* FCED (64749) */ + 4210, /* FCEE (64750) */ + 4211, /* FCEF (64751) */ + 4212, /* FCF0 (64752) */ + 4213, /* FCF1 (64753) */ + 4214, /* FCF2 (64754) */ + 4215, /* FCF3 (64755) */ + 4216, /* FCF4 (64756) */ + 4217, /* FCF5 (64757) */ + 4218, /* FCF6 (64758) */ + 4219, /* FCF7 (64759) */ + 4220, /* FCF8 (64760) */ + 4221, /* FCF9 (64761) */ + 4222, /* FCFA (64762) */ + 4223, /* FCFB (64763) */ + 4224, /* FCFC (64764) */ + 4225, /* FCFD (64765) */ + 4226, /* FCFE (64766) */ + 4227, /* FCFF (64767) */ + 4228, /* FD00 (64768) */ + 4229, /* FD01 (64769) */ + 4230, /* FD02 (64770) */ + 4231, /* FD03 (64771) */ + 4232, /* FD04 (64772) */ + 4233, /* FD05 (64773) */ + 4234, /* FD06 (64774) */ + 4235, /* FD07 (64775) */ + 4236, /* FD08 (64776) */ + 4237, /* FD09 (64777) */ + 4238, /* FD0A (64778) */ + 4239, /* FD0B (64779) */ + 4240, /* FD0C (64780) */ + 4241, /* FD0D (64781) */ + 4242, /* FD0E (64782) */ + 4243, /* FD0F (64783) */ + 4244, /* FD10 (64784) */ + 4245, /* FD11 (64785) */ + 4246, /* FD12 (64786) */ + 4247, /* FD13 (64787) */ + 4248, /* FD14 (64788) */ + 4249, /* FD15 (64789) */ + 4250, /* FD16 (64790) */ + 4251, /* FD17 (64791) */ + 4252, /* FD18 (64792) */ + 4253, /* FD19 (64793) */ + 4254, /* FD1A (64794) */ + 4255, /* FD1B (64795) */ + 4256, /* FD1C (64796) */ + 4257, /* FD1D (64797) */ + 4258, /* FD1E (64798) */ + 4259, /* FD1F (64799) */ + 4260, /* FD20 (64800) */ + 4261, /* FD21 (64801) */ + 4262, /* FD22 (64802) */ + 4263, /* FD23 (64803) */ + 4264, /* FD24 (64804) */ + 4265, /* FD25 (64805) */ + 4266, /* FD26 (64806) */ + 4267, /* FD27 (64807) */ + 4268, /* FD28 (64808) */ + 4269, /* FD29 (64809) */ + 4270, /* FD2A (64810) */ + 4271, /* FD2B (64811) */ + 4272, /* FD2C (64812) */ + 4273, /* FD2D (64813) */ + 4274, /* FD2E (64814) */ + 4275, /* FD2F (64815) */ + 4276, /* FD30 (64816) */ + 4277, /* FD31 (64817) */ + 4278, /* FD32 (64818) */ + 4279, /* FD33 (64819) */ + 4280, /* FD34 (64820) */ + 4281, /* FD35 (64821) */ + 4282, /* FD36 (64822) */ + 4283, /* FD37 (64823) */ + 4284, /* FD38 (64824) */ + 4285, /* FD39 (64825) */ + 4286, /* FD3A (64826) */ + 4287, /* FD3B (64827) */ + 4288, /* FD3C (64828) */ + 4289, /* FD3D (64829) */ 1, /* FD3E (64830) */ 1, /* FD3F (64831) */ 1, /* FD40 (64832) */ @@ -58476,133 +58476,133 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* FD4D (64845) */ 1, /* FD4E (64846) */ 1, /* FD4F (64847) */ - 4286, /* FD50 (64848) */ - 4287, /* FD51 (64849) */ - 4288, /* FD52 (64850) */ - 4289, /* FD53 (64851) */ - 4290, /* FD54 (64852) */ - 4291, /* FD55 (64853) */ - 4292, /* FD56 (64854) */ - 4293, /* FD57 (64855) */ - 4294, /* FD58 (64856) */ - 4295, /* FD59 (64857) */ - 4296, /* FD5A (64858) */ - 4297, /* FD5B (64859) */ - 4298, /* FD5C (64860) */ - 4299, /* FD5D (64861) */ - 4300, /* FD5E (64862) */ - 4301, /* FD5F (64863) */ - 4302, /* FD60 (64864) */ - 4303, /* FD61 (64865) */ - 4304, /* FD62 (64866) */ - 4305, /* FD63 (64867) */ - 4306, /* FD64 (64868) */ - 4307, /* FD65 (64869) */ - 4308, /* FD66 (64870) */ - 4309, /* FD67 (64871) */ - 4310, /* FD68 (64872) */ - 4311, /* FD69 (64873) */ - 4312, /* FD6A (64874) */ - 4313, /* FD6B (64875) */ - 4314, /* FD6C (64876) */ - 4315, /* FD6D (64877) */ - 4316, /* FD6E (64878) */ - 4317, /* FD6F (64879) */ - 4318, /* FD70 (64880) */ - 4319, /* FD71 (64881) */ - 4320, /* FD72 (64882) */ - 4321, /* FD73 (64883) */ - 4322, /* FD74 (64884) */ - 4323, /* FD75 (64885) */ - 4324, /* FD76 (64886) */ - 4325, /* FD77 (64887) */ - 4326, /* FD78 (64888) */ - 4327, /* FD79 (64889) */ - 4328, /* FD7A (64890) */ - 4329, /* FD7B (64891) */ - 4330, /* FD7C (64892) */ - 4331, /* FD7D (64893) */ - 4332, /* FD7E (64894) */ - 4333, /* FD7F (64895) */ - 4334, /* FD80 (64896) */ - 4335, /* FD81 (64897) */ - 4336, /* FD82 (64898) */ - 4337, /* FD83 (64899) */ - 4338, /* FD84 (64900) */ - 4339, /* FD85 (64901) */ - 4340, /* FD86 (64902) */ - 4341, /* FD87 (64903) */ - 4342, /* FD88 (64904) */ - 4343, /* FD89 (64905) */ - 4344, /* FD8A (64906) */ - 4345, /* FD8B (64907) */ - 4346, /* FD8C (64908) */ - 4347, /* FD8D (64909) */ - 4348, /* FD8E (64910) */ - 4349, /* FD8F (64911) */ - 56, /* FD90 (64912) */ - 56, /* FD91 (64913) */ - 4350, /* FD92 (64914) */ - 4351, /* FD93 (64915) */ - 4352, /* FD94 (64916) */ - 4353, /* FD95 (64917) */ - 4354, /* FD96 (64918) */ - 4355, /* FD97 (64919) */ - 4356, /* FD98 (64920) */ - 4357, /* FD99 (64921) */ - 4358, /* FD9A (64922) */ - 4359, /* FD9B (64923) */ - 4360, /* FD9C (64924) */ - 4361, /* FD9D (64925) */ - 4362, /* FD9E (64926) */ - 4363, /* FD9F (64927) */ - 4364, /* FDA0 (64928) */ - 4365, /* FDA1 (64929) */ - 4366, /* FDA2 (64930) */ - 4367, /* FDA3 (64931) */ - 4368, /* FDA4 (64932) */ - 4369, /* FDA5 (64933) */ - 4370, /* FDA6 (64934) */ - 4371, /* FDA7 (64935) */ - 4372, /* FDA8 (64936) */ - 4373, /* FDA9 (64937) */ - 4374, /* FDAA (64938) */ - 4375, /* FDAB (64939) */ - 4376, /* FDAC (64940) */ - 4377, /* FDAD (64941) */ - 4378, /* FDAE (64942) */ - 4379, /* FDAF (64943) */ - 4380, /* FDB0 (64944) */ - 4381, /* FDB1 (64945) */ - 4382, /* FDB2 (64946) */ - 4383, /* FDB3 (64947) */ - 4384, /* FDB4 (64948) */ - 4385, /* FDB5 (64949) */ - 4386, /* FDB6 (64950) */ - 4387, /* FDB7 (64951) */ - 4388, /* FDB8 (64952) */ - 4389, /* FDB9 (64953) */ - 4390, /* FDBA (64954) */ - 4391, /* FDBB (64955) */ - 4392, /* FDBC (64956) */ - 4393, /* FDBD (64957) */ - 4394, /* FDBE (64958) */ - 4395, /* FDBF (64959) */ - 4396, /* FDC0 (64960) */ - 4397, /* FDC1 (64961) */ - 4398, /* FDC2 (64962) */ - 4399, /* FDC3 (64963) */ - 4400, /* FDC4 (64964) */ - 4401, /* FDC5 (64965) */ - 4402, /* FDC6 (64966) */ - 4403, /* FDC7 (64967) */ - 56, /* FDC8 (64968) */ - 56, /* FDC9 (64969) */ - 56, /* FDCA (64970) */ - 56, /* FDCB (64971) */ - 56, /* FDCC (64972) */ - 56, /* FDCD (64973) */ - 56, /* FDCE (64974) */ + 4290, /* FD50 (64848) */ + 4291, /* FD51 (64849) */ + 4292, /* FD52 (64850) */ + 4293, /* FD53 (64851) */ + 4294, /* FD54 (64852) */ + 4295, /* FD55 (64853) */ + 4296, /* FD56 (64854) */ + 4297, /* FD57 (64855) */ + 4298, /* FD58 (64856) */ + 4299, /* FD59 (64857) */ + 4300, /* FD5A (64858) */ + 4301, /* FD5B (64859) */ + 4302, /* FD5C (64860) */ + 4303, /* FD5D (64861) */ + 4304, /* FD5E (64862) */ + 4305, /* FD5F (64863) */ + 4306, /* FD60 (64864) */ + 4307, /* FD61 (64865) */ + 4308, /* FD62 (64866) */ + 4309, /* FD63 (64867) */ + 4310, /* FD64 (64868) */ + 4311, /* FD65 (64869) */ + 4312, /* FD66 (64870) */ + 4313, /* FD67 (64871) */ + 4314, /* FD68 (64872) */ + 4315, /* FD69 (64873) */ + 4316, /* FD6A (64874) */ + 4317, /* FD6B (64875) */ + 4318, /* FD6C (64876) */ + 4319, /* FD6D (64877) */ + 4320, /* FD6E (64878) */ + 4321, /* FD6F (64879) */ + 4322, /* FD70 (64880) */ + 4323, /* FD71 (64881) */ + 4324, /* FD72 (64882) */ + 4325, /* FD73 (64883) */ + 4326, /* FD74 (64884) */ + 4327, /* FD75 (64885) */ + 4328, /* FD76 (64886) */ + 4329, /* FD77 (64887) */ + 4330, /* FD78 (64888) */ + 4331, /* FD79 (64889) */ + 4332, /* FD7A (64890) */ + 4333, /* FD7B (64891) */ + 4334, /* FD7C (64892) */ + 4335, /* FD7D (64893) */ + 4336, /* FD7E (64894) */ + 4337, /* FD7F (64895) */ + 4338, /* FD80 (64896) */ + 4339, /* FD81 (64897) */ + 4340, /* FD82 (64898) */ + 4341, /* FD83 (64899) */ + 4342, /* FD84 (64900) */ + 4343, /* FD85 (64901) */ + 4344, /* FD86 (64902) */ + 4345, /* FD87 (64903) */ + 4346, /* FD88 (64904) */ + 4347, /* FD89 (64905) */ + 4348, /* FD8A (64906) */ + 4349, /* FD8B (64907) */ + 4350, /* FD8C (64908) */ + 4351, /* FD8D (64909) */ + 4352, /* FD8E (64910) */ + 4353, /* FD8F (64911) */ + 1, /* FD90 (64912) */ + 1, /* FD91 (64913) */ + 4354, /* FD92 (64914) */ + 4355, /* FD93 (64915) */ + 4356, /* FD94 (64916) */ + 4357, /* FD95 (64917) */ + 4358, /* FD96 (64918) */ + 4359, /* FD97 (64919) */ + 4360, /* FD98 (64920) */ + 4361, /* FD99 (64921) */ + 4362, /* FD9A (64922) */ + 4363, /* FD9B (64923) */ + 4364, /* FD9C (64924) */ + 4365, /* FD9D (64925) */ + 4366, /* FD9E (64926) */ + 4367, /* FD9F (64927) */ + 4368, /* FDA0 (64928) */ + 4369, /* FDA1 (64929) */ + 4370, /* FDA2 (64930) */ + 4371, /* FDA3 (64931) */ + 4372, /* FDA4 (64932) */ + 4373, /* FDA5 (64933) */ + 4374, /* FDA6 (64934) */ + 4375, /* FDA7 (64935) */ + 4376, /* FDA8 (64936) */ + 4377, /* FDA9 (64937) */ + 4378, /* FDAA (64938) */ + 4379, /* FDAB (64939) */ + 4380, /* FDAC (64940) */ + 4381, /* FDAD (64941) */ + 4382, /* FDAE (64942) */ + 4383, /* FDAF (64943) */ + 4384, /* FDB0 (64944) */ + 4385, /* FDB1 (64945) */ + 4386, /* FDB2 (64946) */ + 4387, /* FDB3 (64947) */ + 4388, /* FDB4 (64948) */ + 4389, /* FDB5 (64949) */ + 4390, /* FDB6 (64950) */ + 4391, /* FDB7 (64951) */ + 4392, /* FDB8 (64952) */ + 4393, /* FDB9 (64953) */ + 4394, /* FDBA (64954) */ + 4395, /* FDBB (64955) */ + 4396, /* FDBC (64956) */ + 4397, /* FDBD (64957) */ + 4398, /* FDBE (64958) */ + 4399, /* FDBF (64959) */ + 4400, /* FDC0 (64960) */ + 4401, /* FDC1 (64961) */ + 4402, /* FDC2 (64962) */ + 4403, /* FDC3 (64963) */ + 4404, /* FDC4 (64964) */ + 4405, /* FDC5 (64965) */ + 4406, /* FDC6 (64966) */ + 4407, /* FDC7 (64967) */ + 1, /* FDC8 (64968) */ + 1, /* FDC9 (64969) */ + 1, /* FDCA (64970) */ + 1, /* FDCB (64971) */ + 1, /* FDCC (64972) */ + 1, /* FDCD (64973) */ + 1, /* FDCE (64974) */ 1, /* FDCF (64975) */ 56, /* FDD0 (64976) */ 56, /* FDD1 (64977) */ @@ -58636,19 +58636,19 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* FDED (65005) */ 56, /* FDEE (65006) */ 56, /* FDEF (65007) */ - 4404, /* FDF0 (65008) */ - 4405, /* FDF1 (65009) */ - 4406, /* FDF2 (65010) */ - 4407, /* FDF3 (65011) */ - 4408, /* FDF4 (65012) */ - 4409, /* FDF5 (65013) */ - 4410, /* FDF6 (65014) */ - 4411, /* FDF7 (65015) */ - 4412, /* FDF8 (65016) */ - 4413, /* FDF9 (65017) */ - 4414, /* FDFA (65018) */ - 4415, /* FDFB (65019) */ - 4416, /* FDFC (65020) */ + 4408, /* FDF0 (65008) */ + 4409, /* FDF1 (65009) */ + 4410, /* FDF2 (65010) */ + 4411, /* FDF3 (65011) */ + 4412, /* FDF4 (65012) */ + 4413, /* FDF5 (65013) */ + 4414, /* FDF6 (65014) */ + 4415, /* FDF7 (65015) */ + 4416, /* FDF8 (65016) */ + 4417, /* FDF9 (65017) */ + 4418, /* FDFA (65018) */ + 4419, /* FDFB (65019) */ + 4420, /* FDFC (65020) */ 1, /* FDFD (65021) */ 1, /* FDFE (65022) */ 1, /* FDFF (65023) */ @@ -58668,16 +58668,16 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 60, /* FE0D (65037) */ 60, /* FE0E (65038) */ 60, /* FE0F (65039) */ - 4417, /* FE10 (65040) */ - 4418, /* FE11 (65041) */ - 4419, /* FE12 (65042) */ - 4420, /* FE13 (65043) */ - 4421, /* FE14 (65044) */ - 4422, /* FE15 (65045) */ - 4423, /* FE16 (65046) */ - 4424, /* FE17 (65047) */ - 4425, /* FE18 (65048) */ - 4426, /* FE19 (65049) */ + 4421, /* FE10 (65040) */ + 4422, /* FE11 (65041) */ + 4423, /* FE12 (65042) */ + 4424, /* FE13 (65043) */ + 4425, /* FE14 (65044) */ + 4426, /* FE15 (65045) */ + 4427, /* FE16 (65046) */ + 4428, /* FE17 (65047) */ + 4429, /* FE18 (65048) */ + 4430, /* FE19 (65049) */ 56, /* FE1A (65050) */ 56, /* FE1B (65051) */ 56, /* FE1C (65052) */ @@ -58700,453 +58700,453 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 433, /* FE2D (65069) */ 431, /* FE2E (65070) */ 431, /* FE2F (65071) */ - 4427, /* FE30 (65072) */ - 4428, /* FE31 (65073) */ - 4429, /* FE32 (65074) */ - 4430, /* FE33 (65075) */ - 4430, /* FE34 (65076) */ - 4431, /* FE35 (65077) */ - 4432, /* FE36 (65078) */ - 4433, /* FE37 (65079) */ - 4434, /* FE38 (65080) */ - 4435, /* FE39 (65081) */ - 4436, /* FE3A (65082) */ - 4437, /* FE3B (65083) */ - 4438, /* FE3C (65084) */ - 4439, /* FE3D (65085) */ - 4440, /* FE3E (65086) */ - 4441, /* FE3F (65087) */ - 4442, /* FE40 (65088) */ - 4443, /* FE41 (65089) */ - 4444, /* FE42 (65090) */ - 4445, /* FE43 (65091) */ - 4446, /* FE44 (65092) */ + 4431, /* FE30 (65072) */ + 4432, /* FE31 (65073) */ + 4433, /* FE32 (65074) */ + 4434, /* FE33 (65075) */ + 4434, /* FE34 (65076) */ + 4435, /* FE35 (65077) */ + 4436, /* FE36 (65078) */ + 4437, /* FE37 (65079) */ + 4438, /* FE38 (65080) */ + 4439, /* FE39 (65081) */ + 4440, /* FE3A (65082) */ + 4441, /* FE3B (65083) */ + 4442, /* FE3C (65084) */ + 4443, /* FE3D (65085) */ + 4444, /* FE3E (65086) */ + 4445, /* FE3F (65087) */ + 4446, /* FE40 (65088) */ + 4447, /* FE41 (65089) */ + 4448, /* FE42 (65090) */ + 4449, /* FE43 (65091) */ + 4450, /* FE44 (65092) */ 1, /* FE45 (65093) */ 1, /* FE46 (65094) */ - 4447, /* FE47 (65095) */ - 4448, /* FE48 (65096) */ - 4449, /* FE49 (65097) */ - 4450, /* FE4A (65098) */ - 4451, /* FE4B (65099) */ - 4452, /* FE4C (65100) */ - 4453, /* FE4D (65101) */ - 4453, /* FE4E (65102) */ - 4453, /* FE4F (65103) */ - 4454, /* FE50 (65104) */ - 4455, /* FE51 (65105) */ - 4456, /* FE52 (65106) */ + 4451, /* FE47 (65095) */ + 4452, /* FE48 (65096) */ + 4453, /* FE49 (65097) */ + 4454, /* FE4A (65098) */ + 4455, /* FE4B (65099) */ + 4456, /* FE4C (65100) */ + 4457, /* FE4D (65101) */ + 4457, /* FE4E (65102) */ + 4457, /* FE4F (65103) */ + 4458, /* FE50 (65104) */ + 4459, /* FE51 (65105) */ + 4460, /* FE52 (65106) */ 56, /* FE53 (65107) */ - 4457, /* FE54 (65108) */ - 4458, /* FE55 (65109) */ - 4459, /* FE56 (65110) */ - 4460, /* FE57 (65111) */ - 4461, /* FE58 (65112) */ - 4462, /* FE59 (65113) */ - 4463, /* FE5A (65114) */ - 4464, /* FE5B (65115) */ - 4465, /* FE5C (65116) */ - 4466, /* FE5D (65117) */ - 4467, /* FE5E (65118) */ - 4468, /* FE5F (65119) */ - 4469, /* FE60 (65120) */ - 4470, /* FE61 (65121) */ - 4471, /* FE62 (65122) */ - 4472, /* FE63 (65123) */ - 4473, /* FE64 (65124) */ - 4474, /* FE65 (65125) */ - 4475, /* FE66 (65126) */ + 4461, /* FE54 (65108) */ + 4462, /* FE55 (65109) */ + 4463, /* FE56 (65110) */ + 4464, /* FE57 (65111) */ + 4465, /* FE58 (65112) */ + 4466, /* FE59 (65113) */ + 4467, /* FE5A (65114) */ + 4468, /* FE5B (65115) */ + 4469, /* FE5C (65116) */ + 4470, /* FE5D (65117) */ + 4471, /* FE5E (65118) */ + 4472, /* FE5F (65119) */ + 4473, /* FE60 (65120) */ + 4474, /* FE61 (65121) */ + 4475, /* FE62 (65122) */ + 4476, /* FE63 (65123) */ + 4477, /* FE64 (65124) */ + 4478, /* FE65 (65125) */ + 4479, /* FE66 (65126) */ 56, /* FE67 (65127) */ - 4476, /* FE68 (65128) */ - 4477, /* FE69 (65129) */ - 4478, /* FE6A (65130) */ - 4479, /* FE6B (65131) */ + 4480, /* FE68 (65128) */ + 4481, /* FE69 (65129) */ + 4482, /* FE6A (65130) */ + 4483, /* FE6B (65131) */ 56, /* FE6C (65132) */ 56, /* FE6D (65133) */ 56, /* FE6E (65134) */ 56, /* FE6F (65135) */ - 4480, /* FE70 (65136) */ - 4481, /* FE71 (65137) */ - 4482, /* FE72 (65138) */ + 4484, /* FE70 (65136) */ + 4485, /* FE71 (65137) */ + 4486, /* FE72 (65138) */ 1, /* FE73 (65139) */ - 4483, /* FE74 (65140) */ + 4487, /* FE74 (65140) */ 56, /* FE75 (65141) */ - 4484, /* FE76 (65142) */ - 4485, /* FE77 (65143) */ - 4486, /* FE78 (65144) */ - 4487, /* FE79 (65145) */ - 4488, /* FE7A (65146) */ - 4489, /* FE7B (65147) */ - 4490, /* FE7C (65148) */ - 4491, /* FE7D (65149) */ - 4492, /* FE7E (65150) */ - 4493, /* FE7F (65151) */ - 4494, /* FE80 (65152) */ - 4495, /* FE81 (65153) */ - 4496, /* FE82 (65154) */ - 4497, /* FE83 (65155) */ - 4498, /* FE84 (65156) */ - 4499, /* FE85 (65157) */ - 4500, /* FE86 (65158) */ - 4501, /* FE87 (65159) */ - 4502, /* FE88 (65160) */ - 4503, /* FE89 (65161) */ - 4504, /* FE8A (65162) */ - 4505, /* FE8B (65163) */ - 4506, /* FE8C (65164) */ - 4507, /* FE8D (65165) */ - 4508, /* FE8E (65166) */ - 4509, /* FE8F (65167) */ - 4510, /* FE90 (65168) */ - 4511, /* FE91 (65169) */ - 4512, /* FE92 (65170) */ - 4513, /* FE93 (65171) */ - 4514, /* FE94 (65172) */ - 4515, /* FE95 (65173) */ - 4516, /* FE96 (65174) */ - 4517, /* FE97 (65175) */ - 4518, /* FE98 (65176) */ - 4519, /* FE99 (65177) */ - 4520, /* FE9A (65178) */ - 4521, /* FE9B (65179) */ - 4522, /* FE9C (65180) */ - 4523, /* FE9D (65181) */ - 4524, /* FE9E (65182) */ - 4525, /* FE9F (65183) */ - 4526, /* FEA0 (65184) */ - 4527, /* FEA1 (65185) */ - 4528, /* FEA2 (65186) */ - 4529, /* FEA3 (65187) */ - 4530, /* FEA4 (65188) */ - 4531, /* FEA5 (65189) */ - 4532, /* FEA6 (65190) */ - 4533, /* FEA7 (65191) */ - 4534, /* FEA8 (65192) */ - 4535, /* FEA9 (65193) */ - 4536, /* FEAA (65194) */ - 4537, /* FEAB (65195) */ - 4538, /* FEAC (65196) */ - 4539, /* FEAD (65197) */ - 4540, /* FEAE (65198) */ - 4541, /* FEAF (65199) */ - 4542, /* FEB0 (65200) */ - 4543, /* FEB1 (65201) */ - 4544, /* FEB2 (65202) */ - 4545, /* FEB3 (65203) */ - 4546, /* FEB4 (65204) */ - 4547, /* FEB5 (65205) */ - 4548, /* FEB6 (65206) */ - 4549, /* FEB7 (65207) */ - 4550, /* FEB8 (65208) */ - 4551, /* FEB9 (65209) */ - 4552, /* FEBA (65210) */ - 4553, /* FEBB (65211) */ - 4554, /* FEBC (65212) */ - 4555, /* FEBD (65213) */ - 4556, /* FEBE (65214) */ - 4557, /* FEBF (65215) */ - 4558, /* FEC0 (65216) */ - 4559, /* FEC1 (65217) */ - 4560, /* FEC2 (65218) */ - 4561, /* FEC3 (65219) */ - 4562, /* FEC4 (65220) */ - 4563, /* FEC5 (65221) */ - 4564, /* FEC6 (65222) */ - 4565, /* FEC7 (65223) */ - 4566, /* FEC8 (65224) */ - 4567, /* FEC9 (65225) */ - 4568, /* FECA (65226) */ - 4569, /* FECB (65227) */ - 4570, /* FECC (65228) */ - 4571, /* FECD (65229) */ - 4572, /* FECE (65230) */ - 4573, /* FECF (65231) */ - 4574, /* FED0 (65232) */ - 4575, /* FED1 (65233) */ - 4576, /* FED2 (65234) */ - 4577, /* FED3 (65235) */ - 4578, /* FED4 (65236) */ - 4579, /* FED5 (65237) */ - 4580, /* FED6 (65238) */ - 4581, /* FED7 (65239) */ - 4582, /* FED8 (65240) */ - 4583, /* FED9 (65241) */ - 4584, /* FEDA (65242) */ - 4585, /* FEDB (65243) */ - 4586, /* FEDC (65244) */ - 4587, /* FEDD (65245) */ - 4588, /* FEDE (65246) */ - 4589, /* FEDF (65247) */ - 4590, /* FEE0 (65248) */ - 4591, /* FEE1 (65249) */ - 4592, /* FEE2 (65250) */ - 4593, /* FEE3 (65251) */ - 4594, /* FEE4 (65252) */ - 4595, /* FEE5 (65253) */ - 4596, /* FEE6 (65254) */ - 4597, /* FEE7 (65255) */ - 4598, /* FEE8 (65256) */ - 4599, /* FEE9 (65257) */ - 4600, /* FEEA (65258) */ - 4601, /* FEEB (65259) */ - 4602, /* FEEC (65260) */ - 4603, /* FEED (65261) */ - 4604, /* FEEE (65262) */ - 4605, /* FEEF (65263) */ - 4606, /* FEF0 (65264) */ - 4607, /* FEF1 (65265) */ - 4608, /* FEF2 (65266) */ - 4609, /* FEF3 (65267) */ - 4610, /* FEF4 (65268) */ - 4611, /* FEF5 (65269) */ - 4612, /* FEF6 (65270) */ - 4613, /* FEF7 (65271) */ - 4614, /* FEF8 (65272) */ - 4615, /* FEF9 (65273) */ - 4616, /* FEFA (65274) */ - 4617, /* FEFB (65275) */ - 4618, /* FEFC (65276) */ + 4488, /* FE76 (65142) */ + 4489, /* FE77 (65143) */ + 4490, /* FE78 (65144) */ + 4491, /* FE79 (65145) */ + 4492, /* FE7A (65146) */ + 4493, /* FE7B (65147) */ + 4494, /* FE7C (65148) */ + 4495, /* FE7D (65149) */ + 4496, /* FE7E (65150) */ + 4497, /* FE7F (65151) */ + 4498, /* FE80 (65152) */ + 4499, /* FE81 (65153) */ + 4500, /* FE82 (65154) */ + 4501, /* FE83 (65155) */ + 4502, /* FE84 (65156) */ + 4503, /* FE85 (65157) */ + 4504, /* FE86 (65158) */ + 4505, /* FE87 (65159) */ + 4506, /* FE88 (65160) */ + 4507, /* FE89 (65161) */ + 4508, /* FE8A (65162) */ + 4509, /* FE8B (65163) */ + 4510, /* FE8C (65164) */ + 4511, /* FE8D (65165) */ + 4512, /* FE8E (65166) */ + 4513, /* FE8F (65167) */ + 4514, /* FE90 (65168) */ + 4515, /* FE91 (65169) */ + 4516, /* FE92 (65170) */ + 4517, /* FE93 (65171) */ + 4518, /* FE94 (65172) */ + 4519, /* FE95 (65173) */ + 4520, /* FE96 (65174) */ + 4521, /* FE97 (65175) */ + 4522, /* FE98 (65176) */ + 4523, /* FE99 (65177) */ + 4524, /* FE9A (65178) */ + 4525, /* FE9B (65179) */ + 4526, /* FE9C (65180) */ + 4527, /* FE9D (65181) */ + 4528, /* FE9E (65182) */ + 4529, /* FE9F (65183) */ + 4530, /* FEA0 (65184) */ + 4531, /* FEA1 (65185) */ + 4532, /* FEA2 (65186) */ + 4533, /* FEA3 (65187) */ + 4534, /* FEA4 (65188) */ + 4535, /* FEA5 (65189) */ + 4536, /* FEA6 (65190) */ + 4537, /* FEA7 (65191) */ + 4538, /* FEA8 (65192) */ + 4539, /* FEA9 (65193) */ + 4540, /* FEAA (65194) */ + 4541, /* FEAB (65195) */ + 4542, /* FEAC (65196) */ + 4543, /* FEAD (65197) */ + 4544, /* FEAE (65198) */ + 4545, /* FEAF (65199) */ + 4546, /* FEB0 (65200) */ + 4547, /* FEB1 (65201) */ + 4548, /* FEB2 (65202) */ + 4549, /* FEB3 (65203) */ + 4550, /* FEB4 (65204) */ + 4551, /* FEB5 (65205) */ + 4552, /* FEB6 (65206) */ + 4553, /* FEB7 (65207) */ + 4554, /* FEB8 (65208) */ + 4555, /* FEB9 (65209) */ + 4556, /* FEBA (65210) */ + 4557, /* FEBB (65211) */ + 4558, /* FEBC (65212) */ + 4559, /* FEBD (65213) */ + 4560, /* FEBE (65214) */ + 4561, /* FEBF (65215) */ + 4562, /* FEC0 (65216) */ + 4563, /* FEC1 (65217) */ + 4564, /* FEC2 (65218) */ + 4565, /* FEC3 (65219) */ + 4566, /* FEC4 (65220) */ + 4567, /* FEC5 (65221) */ + 4568, /* FEC6 (65222) */ + 4569, /* FEC7 (65223) */ + 4570, /* FEC8 (65224) */ + 4571, /* FEC9 (65225) */ + 4572, /* FECA (65226) */ + 4573, /* FECB (65227) */ + 4574, /* FECC (65228) */ + 4575, /* FECD (65229) */ + 4576, /* FECE (65230) */ + 4577, /* FECF (65231) */ + 4578, /* FED0 (65232) */ + 4579, /* FED1 (65233) */ + 4580, /* FED2 (65234) */ + 4581, /* FED3 (65235) */ + 4582, /* FED4 (65236) */ + 4583, /* FED5 (65237) */ + 4584, /* FED6 (65238) */ + 4585, /* FED7 (65239) */ + 4586, /* FED8 (65240) */ + 4587, /* FED9 (65241) */ + 4588, /* FEDA (65242) */ + 4589, /* FEDB (65243) */ + 4590, /* FEDC (65244) */ + 4591, /* FEDD (65245) */ + 4592, /* FEDE (65246) */ + 4593, /* FEDF (65247) */ + 4594, /* FEE0 (65248) */ + 4595, /* FEE1 (65249) */ + 4596, /* FEE2 (65250) */ + 4597, /* FEE3 (65251) */ + 4598, /* FEE4 (65252) */ + 4599, /* FEE5 (65253) */ + 4600, /* FEE6 (65254) */ + 4601, /* FEE7 (65255) */ + 4602, /* FEE8 (65256) */ + 4603, /* FEE9 (65257) */ + 4604, /* FEEA (65258) */ + 4605, /* FEEB (65259) */ + 4606, /* FEEC (65260) */ + 4607, /* FEED (65261) */ + 4608, /* FEEE (65262) */ + 4609, /* FEEF (65263) */ + 4610, /* FEF0 (65264) */ + 4611, /* FEF1 (65265) */ + 4612, /* FEF2 (65266) */ + 4613, /* FEF3 (65267) */ + 4614, /* FEF4 (65268) */ + 4615, /* FEF5 (65269) */ + 4616, /* FEF6 (65270) */ + 4617, /* FEF7 (65271) */ + 4618, /* FEF8 (65272) */ + 4619, /* FEF9 (65273) */ + 4620, /* FEFA (65274) */ + 4621, /* FEFB (65275) */ + 4622, /* FEFC (65276) */ 56, /* FEFD (65277) */ 56, /* FEFE (65278) */ 60, /* FEFF (65279) */ 56, /* FF00 (65280) */ - 4619, /* FF01 (65281) */ - 4620, /* FF02 (65282) */ - 4621, /* FF03 (65283) */ - 4622, /* FF04 (65284) */ - 4623, /* FF05 (65285) */ - 4624, /* FF06 (65286) */ - 4625, /* FF07 (65287) */ - 4626, /* FF08 (65288) */ - 4627, /* FF09 (65289) */ - 4628, /* FF0A (65290) */ - 4629, /* FF0B (65291) */ - 4630, /* FF0C (65292) */ - 4631, /* FF0D (65293) */ - 4632, /* FF0E (65294) */ - 4633, /* FF0F (65295) */ - 4634, /* FF10 (65296) */ - 4635, /* FF11 (65297) */ - 4636, /* FF12 (65298) */ - 4637, /* FF13 (65299) */ - 4638, /* FF14 (65300) */ - 4639, /* FF15 (65301) */ - 4640, /* FF16 (65302) */ - 4641, /* FF17 (65303) */ - 4642, /* FF18 (65304) */ - 4643, /* FF19 (65305) */ - 4644, /* FF1A (65306) */ - 4645, /* FF1B (65307) */ - 4646, /* FF1C (65308) */ - 4647, /* FF1D (65309) */ - 4648, /* FF1E (65310) */ - 4649, /* FF1F (65311) */ - 4650, /* FF20 (65312) */ - 4651, /* FF21 (65313) */ - 4652, /* FF22 (65314) */ - 4653, /* FF23 (65315) */ - 4654, /* FF24 (65316) */ - 4655, /* FF25 (65317) */ - 4656, /* FF26 (65318) */ - 4657, /* FF27 (65319) */ - 4658, /* FF28 (65320) */ - 4659, /* FF29 (65321) */ - 4660, /* FF2A (65322) */ - 4661, /* FF2B (65323) */ - 4662, /* FF2C (65324) */ - 4663, /* FF2D (65325) */ - 4664, /* FF2E (65326) */ - 4665, /* FF2F (65327) */ - 4666, /* FF30 (65328) */ - 4667, /* FF31 (65329) */ - 4668, /* FF32 (65330) */ - 4669, /* FF33 (65331) */ - 4670, /* FF34 (65332) */ - 4671, /* FF35 (65333) */ - 4672, /* FF36 (65334) */ - 4673, /* FF37 (65335) */ - 4674, /* FF38 (65336) */ - 4675, /* FF39 (65337) */ - 4676, /* FF3A (65338) */ - 4677, /* FF3B (65339) */ - 4678, /* FF3C (65340) */ - 4679, /* FF3D (65341) */ - 4680, /* FF3E (65342) */ - 4681, /* FF3F (65343) */ - 4682, /* FF40 (65344) */ - 4683, /* FF41 (65345) */ - 4684, /* FF42 (65346) */ - 4685, /* FF43 (65347) */ - 4686, /* FF44 (65348) */ - 4687, /* FF45 (65349) */ - 4688, /* FF46 (65350) */ - 4689, /* FF47 (65351) */ - 4690, /* FF48 (65352) */ - 4691, /* FF49 (65353) */ - 4692, /* FF4A (65354) */ - 4693, /* FF4B (65355) */ - 4694, /* FF4C (65356) */ - 4695, /* FF4D (65357) */ - 4696, /* FF4E (65358) */ - 4697, /* FF4F (65359) */ - 4698, /* FF50 (65360) */ - 4699, /* FF51 (65361) */ - 4700, /* FF52 (65362) */ - 4701, /* FF53 (65363) */ - 4702, /* FF54 (65364) */ - 4703, /* FF55 (65365) */ - 4704, /* FF56 (65366) */ - 4705, /* FF57 (65367) */ - 4706, /* FF58 (65368) */ - 4707, /* FF59 (65369) */ - 4708, /* FF5A (65370) */ - 4709, /* FF5B (65371) */ - 4710, /* FF5C (65372) */ - 4711, /* FF5D (65373) */ - 4712, /* FF5E (65374) */ - 4713, /* FF5F (65375) */ - 4714, /* FF60 (65376) */ - 4715, /* FF61 (65377) */ - 4716, /* FF62 (65378) */ - 4717, /* FF63 (65379) */ - 4718, /* FF64 (65380) */ - 4719, /* FF65 (65381) */ - 4720, /* FF66 (65382) */ - 4721, /* FF67 (65383) */ - 4722, /* FF68 (65384) */ - 4723, /* FF69 (65385) */ - 4724, /* FF6A (65386) */ - 4725, /* FF6B (65387) */ - 4726, /* FF6C (65388) */ - 4727, /* FF6D (65389) */ - 4728, /* FF6E (65390) */ - 4729, /* FF6F (65391) */ - 4730, /* FF70 (65392) */ - 4731, /* FF71 (65393) */ - 4732, /* FF72 (65394) */ - 4733, /* FF73 (65395) */ - 4734, /* FF74 (65396) */ - 4735, /* FF75 (65397) */ - 4736, /* FF76 (65398) */ - 4737, /* FF77 (65399) */ - 4738, /* FF78 (65400) */ - 4739, /* FF79 (65401) */ - 4740, /* FF7A (65402) */ - 4741, /* FF7B (65403) */ - 4742, /* FF7C (65404) */ - 4743, /* FF7D (65405) */ - 4744, /* FF7E (65406) */ - 4745, /* FF7F (65407) */ - 4746, /* FF80 (65408) */ - 4747, /* FF81 (65409) */ - 4748, /* FF82 (65410) */ - 4749, /* FF83 (65411) */ - 4750, /* FF84 (65412) */ - 4751, /* FF85 (65413) */ - 4752, /* FF86 (65414) */ - 4753, /* FF87 (65415) */ - 4754, /* FF88 (65416) */ - 4755, /* FF89 (65417) */ - 4756, /* FF8A (65418) */ - 4757, /* FF8B (65419) */ - 4758, /* FF8C (65420) */ - 4759, /* FF8D (65421) */ - 4760, /* FF8E (65422) */ - 4761, /* FF8F (65423) */ - 4762, /* FF90 (65424) */ - 4763, /* FF91 (65425) */ - 4764, /* FF92 (65426) */ - 4765, /* FF93 (65427) */ - 4766, /* FF94 (65428) */ - 4767, /* FF95 (65429) */ - 4768, /* FF96 (65430) */ - 4769, /* FF97 (65431) */ - 4770, /* FF98 (65432) */ - 4771, /* FF99 (65433) */ - 4772, /* FF9A (65434) */ - 4773, /* FF9B (65435) */ - 4774, /* FF9C (65436) */ - 4775, /* FF9D (65437) */ - 4776, /* FF9E (65438) */ - 4777, /* FF9F (65439) */ - 4778, /* FFA0 (65440) */ - 4779, /* FFA1 (65441) */ - 4780, /* FFA2 (65442) */ - 4781, /* FFA3 (65443) */ - 4782, /* FFA4 (65444) */ - 4783, /* FFA5 (65445) */ - 4784, /* FFA6 (65446) */ - 4785, /* FFA7 (65447) */ - 4786, /* FFA8 (65448) */ - 4787, /* FFA9 (65449) */ - 4788, /* FFAA (65450) */ - 4789, /* FFAB (65451) */ - 4790, /* FFAC (65452) */ - 4791, /* FFAD (65453) */ - 4792, /* FFAE (65454) */ - 4793, /* FFAF (65455) */ - 4794, /* FFB0 (65456) */ - 4795, /* FFB1 (65457) */ - 4796, /* FFB2 (65458) */ - 4797, /* FFB3 (65459) */ - 4798, /* FFB4 (65460) */ - 4799, /* FFB5 (65461) */ - 4800, /* FFB6 (65462) */ - 4801, /* FFB7 (65463) */ - 4802, /* FFB8 (65464) */ - 4803, /* FFB9 (65465) */ - 4804, /* FFBA (65466) */ - 4805, /* FFBB (65467) */ - 4806, /* FFBC (65468) */ - 4807, /* FFBD (65469) */ - 4808, /* FFBE (65470) */ + 4623, /* FF01 (65281) */ + 4624, /* FF02 (65282) */ + 4625, /* FF03 (65283) */ + 4626, /* FF04 (65284) */ + 4627, /* FF05 (65285) */ + 4628, /* FF06 (65286) */ + 4629, /* FF07 (65287) */ + 4630, /* FF08 (65288) */ + 4631, /* FF09 (65289) */ + 4632, /* FF0A (65290) */ + 4633, /* FF0B (65291) */ + 4634, /* FF0C (65292) */ + 4635, /* FF0D (65293) */ + 4636, /* FF0E (65294) */ + 4637, /* FF0F (65295) */ + 4638, /* FF10 (65296) */ + 4639, /* FF11 (65297) */ + 4640, /* FF12 (65298) */ + 4641, /* FF13 (65299) */ + 4642, /* FF14 (65300) */ + 4643, /* FF15 (65301) */ + 4644, /* FF16 (65302) */ + 4645, /* FF17 (65303) */ + 4646, /* FF18 (65304) */ + 4647, /* FF19 (65305) */ + 4648, /* FF1A (65306) */ + 4649, /* FF1B (65307) */ + 4650, /* FF1C (65308) */ + 4651, /* FF1D (65309) */ + 4652, /* FF1E (65310) */ + 4653, /* FF1F (65311) */ + 4654, /* FF20 (65312) */ + 4655, /* FF21 (65313) */ + 4656, /* FF22 (65314) */ + 4657, /* FF23 (65315) */ + 4658, /* FF24 (65316) */ + 4659, /* FF25 (65317) */ + 4660, /* FF26 (65318) */ + 4661, /* FF27 (65319) */ + 4662, /* FF28 (65320) */ + 4663, /* FF29 (65321) */ + 4664, /* FF2A (65322) */ + 4665, /* FF2B (65323) */ + 4666, /* FF2C (65324) */ + 4667, /* FF2D (65325) */ + 4668, /* FF2E (65326) */ + 4669, /* FF2F (65327) */ + 4670, /* FF30 (65328) */ + 4671, /* FF31 (65329) */ + 4672, /* FF32 (65330) */ + 4673, /* FF33 (65331) */ + 4674, /* FF34 (65332) */ + 4675, /* FF35 (65333) */ + 4676, /* FF36 (65334) */ + 4677, /* FF37 (65335) */ + 4678, /* FF38 (65336) */ + 4679, /* FF39 (65337) */ + 4680, /* FF3A (65338) */ + 4681, /* FF3B (65339) */ + 4682, /* FF3C (65340) */ + 4683, /* FF3D (65341) */ + 4684, /* FF3E (65342) */ + 4685, /* FF3F (65343) */ + 4686, /* FF40 (65344) */ + 4687, /* FF41 (65345) */ + 4688, /* FF42 (65346) */ + 4689, /* FF43 (65347) */ + 4690, /* FF44 (65348) */ + 4691, /* FF45 (65349) */ + 4692, /* FF46 (65350) */ + 4693, /* FF47 (65351) */ + 4694, /* FF48 (65352) */ + 4695, /* FF49 (65353) */ + 4696, /* FF4A (65354) */ + 4697, /* FF4B (65355) */ + 4698, /* FF4C (65356) */ + 4699, /* FF4D (65357) */ + 4700, /* FF4E (65358) */ + 4701, /* FF4F (65359) */ + 4702, /* FF50 (65360) */ + 4703, /* FF51 (65361) */ + 4704, /* FF52 (65362) */ + 4705, /* FF53 (65363) */ + 4706, /* FF54 (65364) */ + 4707, /* FF55 (65365) */ + 4708, /* FF56 (65366) */ + 4709, /* FF57 (65367) */ + 4710, /* FF58 (65368) */ + 4711, /* FF59 (65369) */ + 4712, /* FF5A (65370) */ + 4713, /* FF5B (65371) */ + 4714, /* FF5C (65372) */ + 4715, /* FF5D (65373) */ + 4716, /* FF5E (65374) */ + 4717, /* FF5F (65375) */ + 4718, /* FF60 (65376) */ + 4719, /* FF61 (65377) */ + 4720, /* FF62 (65378) */ + 4721, /* FF63 (65379) */ + 4722, /* FF64 (65380) */ + 4723, /* FF65 (65381) */ + 4724, /* FF66 (65382) */ + 4725, /* FF67 (65383) */ + 4726, /* FF68 (65384) */ + 4727, /* FF69 (65385) */ + 4728, /* FF6A (65386) */ + 4729, /* FF6B (65387) */ + 4730, /* FF6C (65388) */ + 4731, /* FF6D (65389) */ + 4732, /* FF6E (65390) */ + 4733, /* FF6F (65391) */ + 4734, /* FF70 (65392) */ + 4735, /* FF71 (65393) */ + 4736, /* FF72 (65394) */ + 4737, /* FF73 (65395) */ + 4738, /* FF74 (65396) */ + 4739, /* FF75 (65397) */ + 4740, /* FF76 (65398) */ + 4741, /* FF77 (65399) */ + 4742, /* FF78 (65400) */ + 4743, /* FF79 (65401) */ + 4744, /* FF7A (65402) */ + 4745, /* FF7B (65403) */ + 4746, /* FF7C (65404) */ + 4747, /* FF7D (65405) */ + 4748, /* FF7E (65406) */ + 4749, /* FF7F (65407) */ + 4750, /* FF80 (65408) */ + 4751, /* FF81 (65409) */ + 4752, /* FF82 (65410) */ + 4753, /* FF83 (65411) */ + 4754, /* FF84 (65412) */ + 4755, /* FF85 (65413) */ + 4756, /* FF86 (65414) */ + 4757, /* FF87 (65415) */ + 4758, /* FF88 (65416) */ + 4759, /* FF89 (65417) */ + 4760, /* FF8A (65418) */ + 4761, /* FF8B (65419) */ + 4762, /* FF8C (65420) */ + 4763, /* FF8D (65421) */ + 4764, /* FF8E (65422) */ + 4765, /* FF8F (65423) */ + 4766, /* FF90 (65424) */ + 4767, /* FF91 (65425) */ + 4768, /* FF92 (65426) */ + 4769, /* FF93 (65427) */ + 4770, /* FF94 (65428) */ + 4771, /* FF95 (65429) */ + 4772, /* FF96 (65430) */ + 4773, /* FF97 (65431) */ + 4774, /* FF98 (65432) */ + 4775, /* FF99 (65433) */ + 4776, /* FF9A (65434) */ + 4777, /* FF9B (65435) */ + 4778, /* FF9C (65436) */ + 4779, /* FF9D (65437) */ + 4780, /* FF9E (65438) */ + 4781, /* FF9F (65439) */ + 4782, /* FFA0 (65440) */ + 4783, /* FFA1 (65441) */ + 4784, /* FFA2 (65442) */ + 4785, /* FFA3 (65443) */ + 4786, /* FFA4 (65444) */ + 4787, /* FFA5 (65445) */ + 4788, /* FFA6 (65446) */ + 4789, /* FFA7 (65447) */ + 4790, /* FFA8 (65448) */ + 4791, /* FFA9 (65449) */ + 4792, /* FFAA (65450) */ + 4793, /* FFAB (65451) */ + 4794, /* FFAC (65452) */ + 4795, /* FFAD (65453) */ + 4796, /* FFAE (65454) */ + 4797, /* FFAF (65455) */ + 4798, /* FFB0 (65456) */ + 4799, /* FFB1 (65457) */ + 4800, /* FFB2 (65458) */ + 4801, /* FFB3 (65459) */ + 4802, /* FFB4 (65460) */ + 4803, /* FFB5 (65461) */ + 4804, /* FFB6 (65462) */ + 4805, /* FFB7 (65463) */ + 4806, /* FFB8 (65464) */ + 4807, /* FFB9 (65465) */ + 4808, /* FFBA (65466) */ + 4809, /* FFBB (65467) */ + 4810, /* FFBC (65468) */ + 4811, /* FFBD (65469) */ + 4812, /* FFBE (65470) */ 56, /* FFBF (65471) */ 56, /* FFC0 (65472) */ 56, /* FFC1 (65473) */ - 4809, /* FFC2 (65474) */ - 4810, /* FFC3 (65475) */ - 4811, /* FFC4 (65476) */ - 4812, /* FFC5 (65477) */ - 4813, /* FFC6 (65478) */ - 4814, /* FFC7 (65479) */ + 4813, /* FFC2 (65474) */ + 4814, /* FFC3 (65475) */ + 4815, /* FFC4 (65476) */ + 4816, /* FFC5 (65477) */ + 4817, /* FFC6 (65478) */ + 4818, /* FFC7 (65479) */ 56, /* FFC8 (65480) */ 56, /* FFC9 (65481) */ - 4815, /* FFCA (65482) */ - 4816, /* FFCB (65483) */ - 4817, /* FFCC (65484) */ - 4818, /* FFCD (65485) */ - 4819, /* FFCE (65486) */ - 4820, /* FFCF (65487) */ + 4819, /* FFCA (65482) */ + 4820, /* FFCB (65483) */ + 4821, /* FFCC (65484) */ + 4822, /* FFCD (65485) */ + 4823, /* FFCE (65486) */ + 4824, /* FFCF (65487) */ 56, /* FFD0 (65488) */ 56, /* FFD1 (65489) */ - 4821, /* FFD2 (65490) */ - 4822, /* FFD3 (65491) */ - 4823, /* FFD4 (65492) */ - 4824, /* FFD5 (65493) */ - 4825, /* FFD6 (65494) */ - 4826, /* FFD7 (65495) */ + 4825, /* FFD2 (65490) */ + 4826, /* FFD3 (65491) */ + 4827, /* FFD4 (65492) */ + 4828, /* FFD5 (65493) */ + 4829, /* FFD6 (65494) */ + 4830, /* FFD7 (65495) */ 56, /* FFD8 (65496) */ 56, /* FFD9 (65497) */ - 4827, /* FFDA (65498) */ - 4828, /* FFDB (65499) */ - 4829, /* FFDC (65500) */ + 4831, /* FFDA (65498) */ + 4832, /* FFDB (65499) */ + 4833, /* FFDC (65500) */ 56, /* FFDD (65501) */ 56, /* FFDE (65502) */ 56, /* FFDF (65503) */ - 4830, /* FFE0 (65504) */ - 4831, /* FFE1 (65505) */ - 4832, /* FFE2 (65506) */ - 4833, /* FFE3 (65507) */ - 4834, /* FFE4 (65508) */ - 4835, /* FFE5 (65509) */ - 4836, /* FFE6 (65510) */ + 4834, /* FFE0 (65504) */ + 4835, /* FFE1 (65505) */ + 4836, /* FFE2 (65506) */ + 4837, /* FFE3 (65507) */ + 4838, /* FFE4 (65508) */ + 4839, /* FFE5 (65509) */ + 4840, /* FFE6 (65510) */ 56, /* FFE7 (65511) */ - 4837, /* FFE8 (65512) */ - 4838, /* FFE9 (65513) */ - 4839, /* FFEA (65514) */ - 4840, /* FFEB (65515) */ - 4841, /* FFEC (65516) */ - 4842, /* FFED (65517) */ - 4843, /* FFEE (65518) */ + 4841, /* FFE8 (65512) */ + 4842, /* FFE9 (65513) */ + 4843, /* FFEA (65514) */ + 4844, /* FFEB (65515) */ + 4845, /* FFEC (65516) */ + 4846, /* FFED (65517) */ + 4847, /* FFEE (65518) */ 56, /* FFEF (65519) */ 56, /* FFF0 (65520) */ 56, /* FFF1 (65521) */ @@ -60188,46 +60188,46 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 103FD (66557) */ 56, /* 103FE (66558) */ 56, /* 103FF (66559) */ - 4844, /* 10400 (66560) */ - 4845, /* 10401 (66561) */ - 4846, /* 10402 (66562) */ - 4847, /* 10403 (66563) */ - 4848, /* 10404 (66564) */ - 4849, /* 10405 (66565) */ - 4850, /* 10406 (66566) */ - 4851, /* 10407 (66567) */ - 4852, /* 10408 (66568) */ - 4853, /* 10409 (66569) */ - 4854, /* 1040A (66570) */ - 4855, /* 1040B (66571) */ - 4856, /* 1040C (66572) */ - 4857, /* 1040D (66573) */ - 4858, /* 1040E (66574) */ - 4859, /* 1040F (66575) */ - 4860, /* 10410 (66576) */ - 4861, /* 10411 (66577) */ - 4862, /* 10412 (66578) */ - 4863, /* 10413 (66579) */ - 4864, /* 10414 (66580) */ - 4865, /* 10415 (66581) */ - 4866, /* 10416 (66582) */ - 4867, /* 10417 (66583) */ - 4868, /* 10418 (66584) */ - 4869, /* 10419 (66585) */ - 4870, /* 1041A (66586) */ - 4871, /* 1041B (66587) */ - 4872, /* 1041C (66588) */ - 4873, /* 1041D (66589) */ - 4874, /* 1041E (66590) */ - 4875, /* 1041F (66591) */ - 4876, /* 10420 (66592) */ - 4877, /* 10421 (66593) */ - 4878, /* 10422 (66594) */ - 4879, /* 10423 (66595) */ - 4880, /* 10424 (66596) */ - 4881, /* 10425 (66597) */ - 4882, /* 10426 (66598) */ - 4883, /* 10427 (66599) */ + 4848, /* 10400 (66560) */ + 4849, /* 10401 (66561) */ + 4850, /* 10402 (66562) */ + 4851, /* 10403 (66563) */ + 4852, /* 10404 (66564) */ + 4853, /* 10405 (66565) */ + 4854, /* 10406 (66566) */ + 4855, /* 10407 (66567) */ + 4856, /* 10408 (66568) */ + 4857, /* 10409 (66569) */ + 4858, /* 1040A (66570) */ + 4859, /* 1040B (66571) */ + 4860, /* 1040C (66572) */ + 4861, /* 1040D (66573) */ + 4862, /* 1040E (66574) */ + 4863, /* 1040F (66575) */ + 4864, /* 10410 (66576) */ + 4865, /* 10411 (66577) */ + 4866, /* 10412 (66578) */ + 4867, /* 10413 (66579) */ + 4868, /* 10414 (66580) */ + 4869, /* 10415 (66581) */ + 4870, /* 10416 (66582) */ + 4871, /* 10417 (66583) */ + 4872, /* 10418 (66584) */ + 4873, /* 10419 (66585) */ + 4874, /* 1041A (66586) */ + 4875, /* 1041B (66587) */ + 4876, /* 1041C (66588) */ + 4877, /* 1041D (66589) */ + 4878, /* 1041E (66590) */ + 4879, /* 1041F (66591) */ + 4880, /* 10420 (66592) */ + 4881, /* 10421 (66593) */ + 4882, /* 10422 (66594) */ + 4883, /* 10423 (66595) */ + 4884, /* 10424 (66596) */ + 4885, /* 10425 (66597) */ + 4886, /* 10426 (66598) */ + 4887, /* 10427 (66599) */ 1, /* 10428 (66600) */ 1, /* 10429 (66601) */ 1, /* 1042A (66602) */ @@ -60364,42 +60364,42 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 104AD (66733) */ 56, /* 104AE (66734) */ 56, /* 104AF (66735) */ - 4884, /* 104B0 (66736) */ - 4885, /* 104B1 (66737) */ - 4886, /* 104B2 (66738) */ - 4887, /* 104B3 (66739) */ - 4888, /* 104B4 (66740) */ - 4889, /* 104B5 (66741) */ - 4890, /* 104B6 (66742) */ - 4891, /* 104B7 (66743) */ - 4892, /* 104B8 (66744) */ - 4893, /* 104B9 (66745) */ - 4894, /* 104BA (66746) */ - 4895, /* 104BB (66747) */ - 4896, /* 104BC (66748) */ - 4897, /* 104BD (66749) */ - 4898, /* 104BE (66750) */ - 4899, /* 104BF (66751) */ - 4900, /* 104C0 (66752) */ - 4901, /* 104C1 (66753) */ - 4902, /* 104C2 (66754) */ - 4903, /* 104C3 (66755) */ - 4904, /* 104C4 (66756) */ - 4905, /* 104C5 (66757) */ - 4906, /* 104C6 (66758) */ - 4907, /* 104C7 (66759) */ - 4908, /* 104C8 (66760) */ - 4909, /* 104C9 (66761) */ - 4910, /* 104CA (66762) */ - 4911, /* 104CB (66763) */ - 4912, /* 104CC (66764) */ - 4913, /* 104CD (66765) */ - 4914, /* 104CE (66766) */ - 4915, /* 104CF (66767) */ - 4916, /* 104D0 (66768) */ - 4917, /* 104D1 (66769) */ - 4918, /* 104D2 (66770) */ - 4919, /* 104D3 (66771) */ + 4888, /* 104B0 (66736) */ + 4889, /* 104B1 (66737) */ + 4890, /* 104B2 (66738) */ + 4891, /* 104B3 (66739) */ + 4892, /* 104B4 (66740) */ + 4893, /* 104B5 (66741) */ + 4894, /* 104B6 (66742) */ + 4895, /* 104B7 (66743) */ + 4896, /* 104B8 (66744) */ + 4897, /* 104B9 (66745) */ + 4898, /* 104BA (66746) */ + 4899, /* 104BB (66747) */ + 4900, /* 104BC (66748) */ + 4901, /* 104BD (66749) */ + 4902, /* 104BE (66750) */ + 4903, /* 104BF (66751) */ + 4904, /* 104C0 (66752) */ + 4905, /* 104C1 (66753) */ + 4906, /* 104C2 (66754) */ + 4907, /* 104C3 (66755) */ + 4908, /* 104C4 (66756) */ + 4909, /* 104C5 (66757) */ + 4910, /* 104C6 (66758) */ + 4911, /* 104C7 (66759) */ + 4912, /* 104C8 (66760) */ + 4913, /* 104C9 (66761) */ + 4914, /* 104CA (66762) */ + 4915, /* 104CB (66763) */ + 4916, /* 104CC (66764) */ + 4917, /* 104CD (66765) */ + 4918, /* 104CE (66766) */ + 4919, /* 104CF (66767) */ + 4920, /* 104D0 (66768) */ + 4921, /* 104D1 (66769) */ + 4922, /* 104D2 (66770) */ + 4923, /* 104D3 (66771) */ 56, /* 104D4 (66772) */ 56, /* 104D5 (66773) */ 56, /* 104D6 (66774) */ @@ -60556,44 +60556,44 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1056D (66925) */ 56, /* 1056E (66926) */ 1, /* 1056F (66927) */ - 4920, /* 10570 (66928) */ - 4921, /* 10571 (66929) */ - 4922, /* 10572 (66930) */ - 4923, /* 10573 (66931) */ - 4924, /* 10574 (66932) */ - 4925, /* 10575 (66933) */ - 4926, /* 10576 (66934) */ - 4927, /* 10577 (66935) */ - 4928, /* 10578 (66936) */ - 4929, /* 10579 (66937) */ - 4930, /* 1057A (66938) */ + 4924, /* 10570 (66928) */ + 4925, /* 10571 (66929) */ + 4926, /* 10572 (66930) */ + 4927, /* 10573 (66931) */ + 4928, /* 10574 (66932) */ + 4929, /* 10575 (66933) */ + 4930, /* 10576 (66934) */ + 4931, /* 10577 (66935) */ + 4932, /* 10578 (66936) */ + 4933, /* 10579 (66937) */ + 4934, /* 1057A (66938) */ 56, /* 1057B (66939) */ - 4931, /* 1057C (66940) */ - 4932, /* 1057D (66941) */ - 4933, /* 1057E (66942) */ - 4934, /* 1057F (66943) */ - 4935, /* 10580 (66944) */ - 4936, /* 10581 (66945) */ - 4937, /* 10582 (66946) */ - 4938, /* 10583 (66947) */ - 4939, /* 10584 (66948) */ - 4940, /* 10585 (66949) */ - 4941, /* 10586 (66950) */ - 4942, /* 10587 (66951) */ - 4943, /* 10588 (66952) */ - 4944, /* 10589 (66953) */ - 4945, /* 1058A (66954) */ + 4935, /* 1057C (66940) */ + 4936, /* 1057D (66941) */ + 4937, /* 1057E (66942) */ + 4938, /* 1057F (66943) */ + 4939, /* 10580 (66944) */ + 4940, /* 10581 (66945) */ + 4941, /* 10582 (66946) */ + 4942, /* 10583 (66947) */ + 4943, /* 10584 (66948) */ + 4944, /* 10585 (66949) */ + 4945, /* 10586 (66950) */ + 4946, /* 10587 (66951) */ + 4947, /* 10588 (66952) */ + 4948, /* 10589 (66953) */ + 4949, /* 1058A (66954) */ 56, /* 1058B (66955) */ - 4946, /* 1058C (66956) */ - 4947, /* 1058D (66957) */ - 4948, /* 1058E (66958) */ - 4949, /* 1058F (66959) */ - 4950, /* 10590 (66960) */ - 4951, /* 10591 (66961) */ - 4952, /* 10592 (66962) */ + 4950, /* 1058C (66956) */ + 4951, /* 1058D (66957) */ + 4952, /* 1058E (66958) */ + 4953, /* 1058F (66959) */ + 4954, /* 10590 (66960) */ + 4955, /* 10591 (66961) */ + 4956, /* 10592 (66962) */ 56, /* 10593 (66963) */ - 4953, /* 10594 (66964) */ - 4954, /* 10595 (66965) */ + 4957, /* 10594 (66964) */ + 4958, /* 10595 (66965) */ 56, /* 10596 (66966) */ 1, /* 10597 (66967) */ 1, /* 10598 (66968) */ @@ -60645,7 +60645,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105C6 (67014) */ 1, /* 105C7 (67015) */ 1, /* 105C8 (67016) */ - 4955, /* 105C9 (67017) */ + 4959, /* 105C9 (67017) */ 1, /* 105CA (67018) */ 1, /* 105CB (67019) */ 1, /* 105CC (67020) */ @@ -60654,7 +60654,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105CF (67023) */ 1, /* 105D0 (67024) */ 1, /* 105D1 (67025) */ - 4956, /* 105D2 (67026) */ + 4960, /* 105D2 (67026) */ 1, /* 105D3 (67027) */ 1, /* 105D4 (67028) */ 1, /* 105D5 (67029) */ @@ -60662,7 +60662,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105D7 (67031) */ 1, /* 105D8 (67032) */ 1, /* 105D9 (67033) */ - 4957, /* 105DA (67034) */ + 4961, /* 105DA (67034) */ 1, /* 105DB (67035) */ 1, /* 105DC (67036) */ 1, /* 105DD (67037) */ @@ -60672,7 +60672,7 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 105E1 (67041) */ 1, /* 105E2 (67042) */ 1, /* 105E3 (67043) */ - 4958, /* 105E4 (67044) */ + 4962, /* 105E4 (67044) */ 1, /* 105E5 (67045) */ 1, /* 105E6 (67046) */ 1, /* 105E7 (67047) */ @@ -61085,64 +61085,64 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1077E (67454) */ 56, /* 1077F (67455) */ 1, /* 10780 (67456) */ - 4959, /* 10781 (67457) */ - 4960, /* 10782 (67458) */ - 4961, /* 10783 (67459) */ - 4962, /* 10784 (67460) */ - 4963, /* 10785 (67461) */ + 4963, /* 10781 (67457) */ + 4964, /* 10782 (67458) */ + 4965, /* 10783 (67459) */ + 4966, /* 10784 (67460) */ + 4967, /* 10785 (67461) */ 56, /* 10786 (67462) */ - 4964, /* 10787 (67463) */ - 4965, /* 10788 (67464) */ - 4966, /* 10789 (67465) */ - 4967, /* 1078A (67466) */ - 4968, /* 1078B (67467) */ - 4969, /* 1078C (67468) */ - 4970, /* 1078D (67469) */ - 4971, /* 1078E (67470) */ - 4972, /* 1078F (67471) */ - 4973, /* 10790 (67472) */ - 4974, /* 10791 (67473) */ - 4975, /* 10792 (67474) */ - 4976, /* 10793 (67475) */ - 4977, /* 10794 (67476) */ - 4978, /* 10795 (67477) */ - 4979, /* 10796 (67478) */ - 4980, /* 10797 (67479) */ - 4981, /* 10798 (67480) */ - 4982, /* 10799 (67481) */ - 4983, /* 1079A (67482) */ - 4984, /* 1079B (67483) */ - 4985, /* 1079C (67484) */ - 4986, /* 1079D (67485) */ - 4987, /* 1079E (67486) */ - 4988, /* 1079F (67487) */ - 4989, /* 107A0 (67488) */ - 4990, /* 107A1 (67489) */ - 4991, /* 107A2 (67490) */ - 4992, /* 107A3 (67491) */ - 4993, /* 107A4 (67492) */ - 4994, /* 107A5 (67493) */ - 4995, /* 107A6 (67494) */ - 4996, /* 107A7 (67495) */ - 4997, /* 107A8 (67496) */ - 4998, /* 107A9 (67497) */ - 4999, /* 107AA (67498) */ - 5000, /* 107AB (67499) */ - 5001, /* 107AC (67500) */ - 5002, /* 107AD (67501) */ - 5003, /* 107AE (67502) */ - 5004, /* 107AF (67503) */ - 5005, /* 107B0 (67504) */ + 4968, /* 10787 (67463) */ + 4969, /* 10788 (67464) */ + 4970, /* 10789 (67465) */ + 4971, /* 1078A (67466) */ + 4972, /* 1078B (67467) */ + 4973, /* 1078C (67468) */ + 4974, /* 1078D (67469) */ + 4975, /* 1078E (67470) */ + 4976, /* 1078F (67471) */ + 4977, /* 10790 (67472) */ + 4978, /* 10791 (67473) */ + 4979, /* 10792 (67474) */ + 4980, /* 10793 (67475) */ + 4981, /* 10794 (67476) */ + 4982, /* 10795 (67477) */ + 4983, /* 10796 (67478) */ + 4984, /* 10797 (67479) */ + 4985, /* 10798 (67480) */ + 4986, /* 10799 (67481) */ + 4987, /* 1079A (67482) */ + 4988, /* 1079B (67483) */ + 4989, /* 1079C (67484) */ + 4990, /* 1079D (67485) */ + 4991, /* 1079E (67486) */ + 4992, /* 1079F (67487) */ + 4993, /* 107A0 (67488) */ + 4994, /* 107A1 (67489) */ + 4995, /* 107A2 (67490) */ + 4996, /* 107A3 (67491) */ + 4997, /* 107A4 (67492) */ + 4998, /* 107A5 (67493) */ + 4999, /* 107A6 (67494) */ + 5000, /* 107A7 (67495) */ + 5001, /* 107A8 (67496) */ + 5002, /* 107A9 (67497) */ + 5003, /* 107AA (67498) */ + 5004, /* 107AB (67499) */ + 5005, /* 107AC (67500) */ + 5006, /* 107AD (67501) */ + 5007, /* 107AE (67502) */ + 5008, /* 107AF (67503) */ + 5009, /* 107B0 (67504) */ 56, /* 107B1 (67505) */ - 5006, /* 107B2 (67506) */ - 5007, /* 107B3 (67507) */ - 5008, /* 107B4 (67508) */ - 5009, /* 107B5 (67509) */ - 5010, /* 107B6 (67510) */ - 5011, /* 107B7 (67511) */ - 5012, /* 107B8 (67512) */ - 5013, /* 107B9 (67513) */ - 5014, /* 107BA (67514) */ + 5010, /* 107B2 (67506) */ + 5011, /* 107B3 (67507) */ + 5012, /* 107B4 (67508) */ + 5013, /* 107B5 (67509) */ + 5014, /* 107B6 (67510) */ + 5015, /* 107B7 (67511) */ + 5016, /* 107B8 (67512) */ + 5017, /* 107B9 (67513) */ + 5018, /* 107BA (67514) */ 56, /* 107BB (67515) */ 56, /* 107BC (67516) */ 56, /* 107BD (67517) */ @@ -61532,32 +61532,32 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1093D (67901) */ 56, /* 1093E (67902) */ 1, /* 1093F (67903) */ - 56, /* 10940 (67904) */ - 56, /* 10941 (67905) */ - 56, /* 10942 (67906) */ - 56, /* 10943 (67907) */ - 56, /* 10944 (67908) */ - 56, /* 10945 (67909) */ - 56, /* 10946 (67910) */ - 56, /* 10947 (67911) */ - 56, /* 10948 (67912) */ - 56, /* 10949 (67913) */ - 56, /* 1094A (67914) */ - 56, /* 1094B (67915) */ - 56, /* 1094C (67916) */ - 56, /* 1094D (67917) */ - 56, /* 1094E (67918) */ - 56, /* 1094F (67919) */ - 56, /* 10950 (67920) */ - 56, /* 10951 (67921) */ - 56, /* 10952 (67922) */ - 56, /* 10953 (67923) */ - 56, /* 10954 (67924) */ - 56, /* 10955 (67925) */ - 56, /* 10956 (67926) */ - 56, /* 10957 (67927) */ - 56, /* 10958 (67928) */ - 56, /* 10959 (67929) */ + 1, /* 10940 (67904) */ + 1, /* 10941 (67905) */ + 1, /* 10942 (67906) */ + 1, /* 10943 (67907) */ + 1, /* 10944 (67908) */ + 1, /* 10945 (67909) */ + 1, /* 10946 (67910) */ + 1, /* 10947 (67911) */ + 1, /* 10948 (67912) */ + 1, /* 10949 (67913) */ + 1, /* 1094A (67914) */ + 1, /* 1094B (67915) */ + 1, /* 1094C (67916) */ + 1, /* 1094D (67917) */ + 1, /* 1094E (67918) */ + 1, /* 1094F (67919) */ + 1, /* 10950 (67920) */ + 1, /* 10951 (67921) */ + 1, /* 10952 (67922) */ + 1, /* 10953 (67923) */ + 1, /* 10954 (67924) */ + 1, /* 10955 (67925) */ + 1, /* 10956 (67926) */ + 1, /* 10957 (67927) */ + 1, /* 10958 (67928) */ + 1, /* 10959 (67929) */ 56, /* 1095A (67930) */ 56, /* 1095B (67931) */ 56, /* 1095C (67932) */ @@ -62364,57 +62364,57 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 10C7D (68733) */ 56, /* 10C7E (68734) */ 56, /* 10C7F (68735) */ - 5015, /* 10C80 (68736) */ - 5016, /* 10C81 (68737) */ - 5017, /* 10C82 (68738) */ - 5018, /* 10C83 (68739) */ - 5019, /* 10C84 (68740) */ - 5020, /* 10C85 (68741) */ - 5021, /* 10C86 (68742) */ - 5022, /* 10C87 (68743) */ - 5023, /* 10C88 (68744) */ - 5024, /* 10C89 (68745) */ - 5025, /* 10C8A (68746) */ - 5026, /* 10C8B (68747) */ - 5027, /* 10C8C (68748) */ - 5028, /* 10C8D (68749) */ - 5029, /* 10C8E (68750) */ - 5030, /* 10C8F (68751) */ - 5031, /* 10C90 (68752) */ - 5032, /* 10C91 (68753) */ - 5033, /* 10C92 (68754) */ - 5034, /* 10C93 (68755) */ - 5035, /* 10C94 (68756) */ - 5036, /* 10C95 (68757) */ - 5037, /* 10C96 (68758) */ - 5038, /* 10C97 (68759) */ - 5039, /* 10C98 (68760) */ - 5040, /* 10C99 (68761) */ - 5041, /* 10C9A (68762) */ - 5042, /* 10C9B (68763) */ - 5043, /* 10C9C (68764) */ - 5044, /* 10C9D (68765) */ - 5045, /* 10C9E (68766) */ - 5046, /* 10C9F (68767) */ - 5047, /* 10CA0 (68768) */ - 5048, /* 10CA1 (68769) */ - 5049, /* 10CA2 (68770) */ - 5050, /* 10CA3 (68771) */ - 5051, /* 10CA4 (68772) */ - 5052, /* 10CA5 (68773) */ - 5053, /* 10CA6 (68774) */ - 5054, /* 10CA7 (68775) */ - 5055, /* 10CA8 (68776) */ - 5056, /* 10CA9 (68777) */ - 5057, /* 10CAA (68778) */ - 5058, /* 10CAB (68779) */ - 5059, /* 10CAC (68780) */ - 5060, /* 10CAD (68781) */ - 5061, /* 10CAE (68782) */ - 5062, /* 10CAF (68783) */ - 5063, /* 10CB0 (68784) */ - 5064, /* 10CB1 (68785) */ - 5065, /* 10CB2 (68786) */ + 5019, /* 10C80 (68736) */ + 5020, /* 10C81 (68737) */ + 5021, /* 10C82 (68738) */ + 5022, /* 10C83 (68739) */ + 5023, /* 10C84 (68740) */ + 5024, /* 10C85 (68741) */ + 5025, /* 10C86 (68742) */ + 5026, /* 10C87 (68743) */ + 5027, /* 10C88 (68744) */ + 5028, /* 10C89 (68745) */ + 5029, /* 10C8A (68746) */ + 5030, /* 10C8B (68747) */ + 5031, /* 10C8C (68748) */ + 5032, /* 10C8D (68749) */ + 5033, /* 10C8E (68750) */ + 5034, /* 10C8F (68751) */ + 5035, /* 10C90 (68752) */ + 5036, /* 10C91 (68753) */ + 5037, /* 10C92 (68754) */ + 5038, /* 10C93 (68755) */ + 5039, /* 10C94 (68756) */ + 5040, /* 10C95 (68757) */ + 5041, /* 10C96 (68758) */ + 5042, /* 10C97 (68759) */ + 5043, /* 10C98 (68760) */ + 5044, /* 10C99 (68761) */ + 5045, /* 10C9A (68762) */ + 5046, /* 10C9B (68763) */ + 5047, /* 10C9C (68764) */ + 5048, /* 10C9D (68765) */ + 5049, /* 10C9E (68766) */ + 5050, /* 10C9F (68767) */ + 5051, /* 10CA0 (68768) */ + 5052, /* 10CA1 (68769) */ + 5053, /* 10CA2 (68770) */ + 5054, /* 10CA3 (68771) */ + 5055, /* 10CA4 (68772) */ + 5056, /* 10CA5 (68773) */ + 5057, /* 10CA6 (68774) */ + 5058, /* 10CA7 (68775) */ + 5059, /* 10CA8 (68776) */ + 5060, /* 10CA9 (68777) */ + 5061, /* 10CAA (68778) */ + 5062, /* 10CAB (68779) */ + 5063, /* 10CAC (68780) */ + 5064, /* 10CAD (68781) */ + 5065, /* 10CAE (68782) */ + 5066, /* 10CAF (68783) */ + 5067, /* 10CB0 (68784) */ + 5068, /* 10CB1 (68785) */ + 5069, /* 10CB2 (68786) */ 56, /* 10CB3 (68787) */ 56, /* 10CB4 (68788) */ 56, /* 10CB5 (68789) */ @@ -62572,28 +62572,28 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 10D4D (68941) */ 1, /* 10D4E (68942) */ 1, /* 10D4F (68943) */ - 5066, /* 10D50 (68944) */ - 5067, /* 10D51 (68945) */ - 5068, /* 10D52 (68946) */ - 5069, /* 10D53 (68947) */ - 5070, /* 10D54 (68948) */ - 5071, /* 10D55 (68949) */ - 5072, /* 10D56 (68950) */ - 5073, /* 10D57 (68951) */ - 5074, /* 10D58 (68952) */ - 5075, /* 10D59 (68953) */ - 5076, /* 10D5A (68954) */ - 5077, /* 10D5B (68955) */ - 5078, /* 10D5C (68956) */ - 5079, /* 10D5D (68957) */ - 5080, /* 10D5E (68958) */ - 5081, /* 10D5F (68959) */ - 5082, /* 10D60 (68960) */ - 5083, /* 10D61 (68961) */ - 5084, /* 10D62 (68962) */ - 5085, /* 10D63 (68963) */ - 5086, /* 10D64 (68964) */ - 5087, /* 10D65 (68965) */ + 5070, /* 10D50 (68944) */ + 5071, /* 10D51 (68945) */ + 5072, /* 10D52 (68946) */ + 5073, /* 10D53 (68947) */ + 5074, /* 10D54 (68948) */ + 5075, /* 10D55 (68949) */ + 5076, /* 10D56 (68950) */ + 5077, /* 10D57 (68951) */ + 5078, /* 10D58 (68952) */ + 5079, /* 10D59 (68953) */ + 5080, /* 10D5A (68954) */ + 5081, /* 10D5B (68955) */ + 5082, /* 10D5C (68956) */ + 5083, /* 10D5D (68957) */ + 5084, /* 10D5E (68958) */ + 5085, /* 10D5F (68959) */ + 5086, /* 10D60 (68960) */ + 5087, /* 10D61 (68961) */ + 5088, /* 10D62 (68962) */ + 5089, /* 10D63 (68963) */ + 5090, /* 10D64 (68964) */ + 5091, /* 10D65 (68965) */ 56, /* 10D66 (68966) */ 56, /* 10D67 (68967) */ 56, /* 10D68 (68968) */ @@ -62945,9 +62945,9 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 10EC2 (69314) */ 1, /* 10EC3 (69315) */ 1, /* 10EC4 (69316) */ - 56, /* 10EC5 (69317) */ - 56, /* 10EC6 (69318) */ - 56, /* 10EC7 (69319) */ + 1, /* 10EC5 (69317) */ + 1, /* 10EC6 (69318) */ + 1, /* 10EC7 (69319) */ 56, /* 10EC8 (69320) */ 56, /* 10EC9 (69321) */ 56, /* 10ECA (69322) */ @@ -62956,15 +62956,15 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 10ECD (69325) */ 56, /* 10ECE (69326) */ 56, /* 10ECF (69327) */ - 56, /* 10ED0 (69328) */ - 56, /* 10ED1 (69329) */ - 56, /* 10ED2 (69330) */ - 56, /* 10ED3 (69331) */ - 56, /* 10ED4 (69332) */ - 56, /* 10ED5 (69333) */ - 56, /* 10ED6 (69334) */ - 56, /* 10ED7 (69335) */ - 56, /* 10ED8 (69336) */ + 1, /* 10ED0 (69328) */ + 1, /* 10ED1 (69329) */ + 1, /* 10ED2 (69330) */ + 1, /* 10ED3 (69331) */ + 1, /* 10ED4 (69332) */ + 1, /* 10ED5 (69333) */ + 1, /* 10ED6 (69334) */ + 1, /* 10ED7 (69335) */ + 1, /* 10ED8 (69336) */ 56, /* 10ED9 (69337) */ 56, /* 10EDA (69338) */ 56, /* 10EDB (69339) */ @@ -62998,8 +62998,8 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 10EF7 (69367) */ 56, /* 10EF8 (69368) */ 56, /* 10EF9 (69369) */ - 56, /* 10EFA (69370) */ - 56, /* 10EFB (69371) */ + 433, /* 10EFA (69370) */ + 433, /* 10EFB (69371) */ 1, /* 10EFC (69372) */ 433, /* 10EFD (69373) */ 433, /* 10EFE (69374) */ @@ -63413,10 +63413,10 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 11096 (69782) */ 1, /* 11097 (69783) */ 1, /* 11098 (69784) */ - 5088, /* 11099 (69785) */ - 5089, /* 1109A (69786) */ - 5090, /* 1109B (69787) */ - 5091, /* 1109C (69788) */ + 5092, /* 11099 (69785) */ + 5093, /* 1109A (69786) */ + 5094, /* 1109B (69787) */ + 5095, /* 1109C (69788) */ 1, /* 1109D (69789) */ 1, /* 1109E (69790) */ 1, /* 1109F (69791) */ @@ -63425,13 +63425,13 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 110A2 (69794) */ 1, /* 110A3 (69795) */ 1, /* 110A4 (69796) */ - 5092, /* 110A5 (69797) */ + 5096, /* 110A5 (69797) */ 1, /* 110A6 (69798) */ 1, /* 110A7 (69799) */ 1, /* 110A8 (69800) */ 1, /* 110A9 (69801) */ 1, /* 110AA (69802) */ - 5093, /* 110AB (69803) */ + 5097, /* 110AB (69803) */ 1, /* 110AC (69804) */ 1, /* 110AD (69805) */ 1, /* 110AE (69806) */ @@ -63562,11 +63562,11 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 1112B (69931) */ 1, /* 1112C (69932) */ 1, /* 1112D (69933) */ - 5094, /* 1112E (69934) */ - 5095, /* 1112F (69935) */ + 5098, /* 1112E (69934) */ + 5099, /* 1112F (69935) */ 1, /* 11130 (69936) */ - 5096, /* 11131 (69937) */ - 5097, /* 11132 (69938) */ + 5100, /* 11131 (69937) */ + 5101, /* 11132 (69938) */ 852, /* 11133 (69939) */ 852, /* 11134 (69940) */ 56, /* 11135 (69941) */ @@ -64099,12 +64099,12 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 11344 (70468) */ 56, /* 11345 (70469) */ 56, /* 11346 (70470) */ - 5098, /* 11347 (70471) */ + 5102, /* 11347 (70471) */ 1, /* 11348 (70472) */ 56, /* 11349 (70473) */ 56, /* 1134A (70474) */ - 5099, /* 1134B (70475) */ - 5100, /* 1134C (70476) */ + 5103, /* 1134B (70475) */ + 5104, /* 1134C (70476) */ 852, /* 1134D (70477) */ 56, /* 1134E (70478) */ 56, /* 1134F (70479) */ @@ -64158,22 +64158,22 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1137F (70527) */ 1, /* 11380 (70528) */ 1, /* 11381 (70529) */ - 5101, /* 11382 (70530) */ - 5102, /* 11383 (70531) */ - 5103, /* 11384 (70532) */ - 5104, /* 11385 (70533) */ + 5105, /* 11382 (70530) */ + 5106, /* 11383 (70531) */ + 5107, /* 11384 (70532) */ + 5108, /* 11385 (70533) */ 1, /* 11386 (70534) */ 1, /* 11387 (70535) */ 1, /* 11388 (70536) */ 1, /* 11389 (70537) */ 56, /* 1138A (70538) */ - 5105, /* 1138B (70539) */ + 5109, /* 1138B (70539) */ 56, /* 1138C (70540) */ 56, /* 1138D (70541) */ - 5106, /* 1138E (70542) */ + 5110, /* 1138E (70542) */ 56, /* 1138F (70543) */ - 5107, /* 11390 (70544) */ - 5108, /* 11391 (70545) */ + 5111, /* 11390 (70544) */ + 5112, /* 11391 (70545) */ 1, /* 11392 (70546) */ 1, /* 11393 (70547) */ 1, /* 11394 (70548) */ @@ -64222,13 +64222,13 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 113BF (70591) */ 1, /* 113C0 (70592) */ 56, /* 113C1 (70593) */ - 5109, /* 113C2 (70594) */ + 5113, /* 113C2 (70594) */ 56, /* 113C3 (70595) */ 56, /* 113C4 (70596) */ - 5110, /* 113C5 (70597) */ + 5114, /* 113C5 (70597) */ 56, /* 113C6 (70598) */ - 5111, /* 113C7 (70599) */ - 5112, /* 113C8 (70600) */ + 5115, /* 113C7 (70599) */ + 5116, /* 113C8 (70600) */ 865, /* 113C9 (70601) */ 1, /* 113CA (70602) */ 56, /* 113CB (70603) */ @@ -64469,12 +64469,12 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 114B6 (70838) */ 1, /* 114B7 (70839) */ 1, /* 114B8 (70840) */ - 5113, /* 114B9 (70841) */ + 5117, /* 114B9 (70841) */ 865, /* 114BA (70842) */ - 5114, /* 114BB (70843) */ - 5115, /* 114BC (70844) */ + 5118, /* 114BB (70843) */ + 5119, /* 114BC (70844) */ 865, /* 114BD (70845) */ - 5116, /* 114BE (70846) */ + 5120, /* 114BE (70846) */ 1, /* 114BF (70847) */ 1, /* 114C0 (70848) */ 1, /* 114C1 (70849) */ @@ -64724,10 +64724,10 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 115B5 (71093) */ 56, /* 115B6 (71094) */ 56, /* 115B7 (71095) */ - 5117, /* 115B8 (71096) */ - 5118, /* 115B9 (71097) */ - 5119, /* 115BA (71098) */ - 5120, /* 115BB (71099) */ + 5121, /* 115B8 (71096) */ + 5122, /* 115B9 (71097) */ + 5123, /* 115BA (71098) */ + 5124, /* 115BB (71099) */ 1, /* 115BC (71100) */ 1, /* 115BD (71101) */ 1, /* 115BE (71102) */ @@ -65468,38 +65468,38 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 1189D (71837) */ 56, /* 1189E (71838) */ 56, /* 1189F (71839) */ - 5121, /* 118A0 (71840) */ - 5122, /* 118A1 (71841) */ - 5123, /* 118A2 (71842) */ - 5124, /* 118A3 (71843) */ - 5125, /* 118A4 (71844) */ - 5126, /* 118A5 (71845) */ - 5127, /* 118A6 (71846) */ - 5128, /* 118A7 (71847) */ - 5129, /* 118A8 (71848) */ - 5130, /* 118A9 (71849) */ - 5131, /* 118AA (71850) */ - 5132, /* 118AB (71851) */ - 5133, /* 118AC (71852) */ - 5134, /* 118AD (71853) */ - 5135, /* 118AE (71854) */ - 5136, /* 118AF (71855) */ - 5137, /* 118B0 (71856) */ - 5138, /* 118B1 (71857) */ - 5139, /* 118B2 (71858) */ - 5140, /* 118B3 (71859) */ - 5141, /* 118B4 (71860) */ - 5142, /* 118B5 (71861) */ - 5143, /* 118B6 (71862) */ - 5144, /* 118B7 (71863) */ - 5145, /* 118B8 (71864) */ - 5146, /* 118B9 (71865) */ - 5147, /* 118BA (71866) */ - 5148, /* 118BB (71867) */ - 5149, /* 118BC (71868) */ - 5150, /* 118BD (71869) */ - 5151, /* 118BE (71870) */ - 5152, /* 118BF (71871) */ + 5125, /* 118A0 (71840) */ + 5126, /* 118A1 (71841) */ + 5127, /* 118A2 (71842) */ + 5128, /* 118A3 (71843) */ + 5129, /* 118A4 (71844) */ + 5130, /* 118A5 (71845) */ + 5131, /* 118A6 (71846) */ + 5132, /* 118A7 (71847) */ + 5133, /* 118A8 (71848) */ + 5134, /* 118A9 (71849) */ + 5135, /* 118AA (71850) */ + 5136, /* 118AB (71851) */ + 5137, /* 118AC (71852) */ + 5138, /* 118AD (71853) */ + 5139, /* 118AE (71854) */ + 5140, /* 118AF (71855) */ + 5141, /* 118B0 (71856) */ + 5142, /* 118B1 (71857) */ + 5143, /* 118B2 (71858) */ + 5144, /* 118B3 (71859) */ + 5145, /* 118B4 (71860) */ + 5146, /* 118B5 (71861) */ + 5147, /* 118B6 (71862) */ + 5148, /* 118B7 (71863) */ + 5149, /* 118B8 (71864) */ + 5150, /* 118B9 (71865) */ + 5151, /* 118BA (71866) */ + 5152, /* 118BB (71867) */ + 5153, /* 118BC (71868) */ + 5154, /* 118BD (71869) */ + 5155, /* 118BE (71870) */ + 5156, /* 118BF (71871) */ 1, /* 118C0 (71872) */ 1, /* 118C1 (71873) */ 1, /* 118C2 (71874) */ @@ -65617,10 +65617,10 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 11932 (71986) */ 1, /* 11933 (71987) */ 1, /* 11934 (71988) */ - 5153, /* 11935 (71989) */ + 5157, /* 11935 (71989) */ 56, /* 11936 (71990) */ 1, /* 11937 (71991) */ - 5154, /* 11938 (71992) */ + 5158, /* 11938 (71992) */ 56, /* 11939 (71993) */ 56, /* 1193A (71994) */ 1, /* 1193B (71995) */ @@ -66172,14 +66172,14 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 11B5D (72541) */ 56, /* 11B5E (72542) */ 56, /* 11B5F (72543) */ - 56, /* 11B60 (72544) */ - 56, /* 11B61 (72545) */ - 56, /* 11B62 (72546) */ - 56, /* 11B63 (72547) */ - 56, /* 11B64 (72548) */ - 56, /* 11B65 (72549) */ - 56, /* 11B66 (72550) */ - 56, /* 11B67 (72551) */ + 1, /* 11B60 (72544) */ + 1, /* 11B61 (72545) */ + 1, /* 11B62 (72546) */ + 1, /* 11B63 (72547) */ + 1, /* 11B64 (72548) */ + 1, /* 11B65 (72549) */ + 1, /* 11B66 (72550) */ + 1, /* 11B67 (72551) */ 56, /* 11B68 (72552) */ 56, /* 11B69 (72553) */ 56, /* 11B6A (72554) */ @@ -66764,64 +66764,64 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 56, /* 11DAD (73133) */ 56, /* 11DAE (73134) */ 56, /* 11DAF (73135) */ - 56, /* 11DB0 (73136) */ - 56, /* 11DB1 (73137) */ - 56, /* 11DB2 (73138) */ - 56, /* 11DB3 (73139) */ - 56, /* 11DB4 (73140) */ - 56, /* 11DB5 (73141) */ - 56, /* 11DB6 (73142) */ - 56, /* 11DB7 (73143) */ - 56, /* 11DB8 (73144) */ - 56, /* 11DB9 (73145) */ - 56, /* 11DBA (73146) */ - 56, /* 11DBB (73147) */ - 56, /* 11DBC (73148) */ - 56, /* 11DBD (73149) */ - 56, /* 11DBE (73150) */ - 56, /* 11DBF (73151) */ - 56, /* 11DC0 (73152) */ - 56, /* 11DC1 (73153) */ - 56, /* 11DC2 (73154) */ - 56, /* 11DC3 (73155) */ - 56, /* 11DC4 (73156) */ - 56, /* 11DC5 (73157) */ - 56, /* 11DC6 (73158) */ - 56, /* 11DC7 (73159) */ - 56, /* 11DC8 (73160) */ - 56, /* 11DC9 (73161) */ - 56, /* 11DCA (73162) */ - 56, /* 11DCB (73163) */ - 56, /* 11DCC (73164) */ - 56, /* 11DCD (73165) */ - 56, /* 11DCE (73166) */ - 56, /* 11DCF (73167) */ - 56, /* 11DD0 (73168) */ - 56, /* 11DD1 (73169) */ - 56, /* 11DD2 (73170) */ - 56, /* 11DD3 (73171) */ - 56, /* 11DD4 (73172) */ - 56, /* 11DD5 (73173) */ - 56, /* 11DD6 (73174) */ - 56, /* 11DD7 (73175) */ - 56, /* 11DD8 (73176) */ - 56, /* 11DD9 (73177) */ - 56, /* 11DDA (73178) */ - 56, /* 11DDB (73179) */ + 1, /* 11DB0 (73136) */ + 1, /* 11DB1 (73137) */ + 1, /* 11DB2 (73138) */ + 1, /* 11DB3 (73139) */ + 1, /* 11DB4 (73140) */ + 1, /* 11DB5 (73141) */ + 1, /* 11DB6 (73142) */ + 1, /* 11DB7 (73143) */ + 1, /* 11DB8 (73144) */ + 1, /* 11DB9 (73145) */ + 1, /* 11DBA (73146) */ + 1, /* 11DBB (73147) */ + 1, /* 11DBC (73148) */ + 1, /* 11DBD (73149) */ + 1, /* 11DBE (73150) */ + 1, /* 11DBF (73151) */ + 1, /* 11DC0 (73152) */ + 1, /* 11DC1 (73153) */ + 1, /* 11DC2 (73154) */ + 1, /* 11DC3 (73155) */ + 1, /* 11DC4 (73156) */ + 1, /* 11DC5 (73157) */ + 1, /* 11DC6 (73158) */ + 1, /* 11DC7 (73159) */ + 1, /* 11DC8 (73160) */ + 1, /* 11DC9 (73161) */ + 1, /* 11DCA (73162) */ + 1, /* 11DCB (73163) */ + 1, /* 11DCC (73164) */ + 1, /* 11DCD (73165) */ + 1, /* 11DCE (73166) */ + 1, /* 11DCF (73167) */ + 1, /* 11DD0 (73168) */ + 1, /* 11DD1 (73169) */ + 1, /* 11DD2 (73170) */ + 1, /* 11DD3 (73171) */ + 1, /* 11DD4 (73172) */ + 1, /* 11DD5 (73173) */ + 1, /* 11DD6 (73174) */ + 1, /* 11DD7 (73175) */ + 1, /* 11DD8 (73176) */ + 1, /* 11DD9 (73177) */ + 1, /* 11DDA (73178) */ + 1, /* 11DDB (73179) */ 56, /* 11DDC (73180) */ 56, /* 11DDD (73181) */ 56, /* 11DDE (73182) */ 56, /* 11DDF (73183) */ - 56, /* 11DE0 (73184) */ - 56, /* 11DE1 (73185) */ - 56, /* 11DE2 (73186) */ - 56, /* 11DE3 (73187) */ - 56, /* 11DE4 (73188) */ - 56, /* 11DE5 (73189) */ - 56, /* 11DE6 (73190) */ - 56, /* 11DE7 (73191) */ - 56, /* 11DE8 (73192) */ - 56, /* 11DE9 (73193) */ + 1, /* 11DE0 (73184) */ + 1, /* 11DE1 (73185) */ + 1, /* 11DE2 (73186) */ + 1, /* 11DE3 (73187) */ + 1, /* 11DE4 (73188) */ + 1, /* 11DE5 (73189) */ + 1, /* 11DE6 (73190) */ + 1, /* 11DE7 (73191) */ + 1, /* 11DE8 (73192) */ + 1, /* 11DE9 (73193) */ 56, /* 11DEA (73194) */ 56, /* 11DEB (73195) */ 56, /* 11DEC (73196) */ @@ -77157,8 +77157,8 @@ static const uint16_t lxb_unicode_table_map_63743_83527[19784] = 1, /* 14646 (83526) */ }; -/* From: 16100; To: 18D08 */ -static const uint16_t lxb_unicode_table_map_90368_101641[11273] = +/* From: 16100; To: 18DF2 */ +static const uint16_t lxb_unicode_table_map_90368_101875[11507] = { 1, /* 16100 (90368) */ 1, /* 16101 (90369) */ @@ -77190,18 +77190,18 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 1611B (90395) */ 1, /* 1611C (90396) */ 1, /* 1611D (90397) */ - 5155, /* 1611E (90398) */ + 5159, /* 1611E (90398) */ 865, /* 1611F (90399) */ 865, /* 16120 (90400) */ - 5156, /* 16121 (90401) */ - 5157, /* 16122 (90402) */ - 5158, /* 16123 (90403) */ - 5159, /* 16124 (90404) */ - 5160, /* 16125 (90405) */ - 5161, /* 16126 (90406) */ - 5162, /* 16127 (90407) */ - 5163, /* 16128 (90408) */ - 5164, /* 16129 (90409) */ + 5160, /* 16121 (90401) */ + 5161, /* 16122 (90402) */ + 5162, /* 16123 (90403) */ + 5163, /* 16124 (90404) */ + 5164, /* 16125 (90405) */ + 5165, /* 16126 (90406) */ + 5166, /* 16127 (90407) */ + 5167, /* 16128 (90408) */ + 5168, /* 16129 (90409) */ 1, /* 1612A (90410) */ 1, /* 1612B (90411) */ 1, /* 1612C (90412) */ @@ -80331,14 +80331,14 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 16D60 (93536) */ 1, /* 16D61 (93537) */ 1, /* 16D62 (93538) */ - 5165, /* 16D63 (93539) */ + 5169, /* 16D63 (93539) */ 1, /* 16D64 (93540) */ 1, /* 16D65 (93541) */ 1, /* 16D66 (93542) */ - 5166, /* 16D67 (93543) */ - 5167, /* 16D68 (93544) */ - 5168, /* 16D69 (93545) */ - 5169, /* 16D6A (93546) */ + 5170, /* 16D67 (93543) */ + 5171, /* 16D68 (93544) */ + 5172, /* 16D69 (93545) */ + 5173, /* 16D6A (93546) */ 1, /* 16D6B (93547) */ 1, /* 16D6C (93548) */ 1, /* 16D6D (93549) */ @@ -80552,38 +80552,38 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 56, /* 16E3D (93757) */ 56, /* 16E3E (93758) */ 56, /* 16E3F (93759) */ - 5170, /* 16E40 (93760) */ - 5171, /* 16E41 (93761) */ - 5172, /* 16E42 (93762) */ - 5173, /* 16E43 (93763) */ - 5174, /* 16E44 (93764) */ - 5175, /* 16E45 (93765) */ - 5176, /* 16E46 (93766) */ - 5177, /* 16E47 (93767) */ - 5178, /* 16E48 (93768) */ - 5179, /* 16E49 (93769) */ - 5180, /* 16E4A (93770) */ - 5181, /* 16E4B (93771) */ - 5182, /* 16E4C (93772) */ - 5183, /* 16E4D (93773) */ - 5184, /* 16E4E (93774) */ - 5185, /* 16E4F (93775) */ - 5186, /* 16E50 (93776) */ - 5187, /* 16E51 (93777) */ - 5188, /* 16E52 (93778) */ - 5189, /* 16E53 (93779) */ - 5190, /* 16E54 (93780) */ - 5191, /* 16E55 (93781) */ - 5192, /* 16E56 (93782) */ - 5193, /* 16E57 (93783) */ - 5194, /* 16E58 (93784) */ - 5195, /* 16E59 (93785) */ - 5196, /* 16E5A (93786) */ - 5197, /* 16E5B (93787) */ - 5198, /* 16E5C (93788) */ - 5199, /* 16E5D (93789) */ - 5200, /* 16E5E (93790) */ - 5201, /* 16E5F (93791) */ + 5174, /* 16E40 (93760) */ + 5175, /* 16E41 (93761) */ + 5176, /* 16E42 (93762) */ + 5177, /* 16E43 (93763) */ + 5178, /* 16E44 (93764) */ + 5179, /* 16E45 (93765) */ + 5180, /* 16E46 (93766) */ + 5181, /* 16E47 (93767) */ + 5182, /* 16E48 (93768) */ + 5183, /* 16E49 (93769) */ + 5184, /* 16E4A (93770) */ + 5185, /* 16E4B (93771) */ + 5186, /* 16E4C (93772) */ + 5187, /* 16E4D (93773) */ + 5188, /* 16E4E (93774) */ + 5189, /* 16E4F (93775) */ + 5190, /* 16E50 (93776) */ + 5191, /* 16E51 (93777) */ + 5192, /* 16E52 (93778) */ + 5193, /* 16E53 (93779) */ + 5194, /* 16E54 (93780) */ + 5195, /* 16E55 (93781) */ + 5196, /* 16E56 (93782) */ + 5197, /* 16E57 (93783) */ + 5198, /* 16E58 (93784) */ + 5199, /* 16E59 (93785) */ + 5200, /* 16E5A (93786) */ + 5201, /* 16E5B (93787) */ + 5202, /* 16E5C (93788) */ + 5203, /* 16E5D (93789) */ + 5204, /* 16E5E (93790) */ + 5205, /* 16E5F (93791) */ 1, /* 16E60 (93792) */ 1, /* 16E61 (93793) */ 1, /* 16E62 (93794) */ @@ -80648,58 +80648,58 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 56, /* 16E9D (93853) */ 56, /* 16E9E (93854) */ 56, /* 16E9F (93855) */ - 56, /* 16EA0 (93856) */ - 56, /* 16EA1 (93857) */ - 56, /* 16EA2 (93858) */ - 56, /* 16EA3 (93859) */ - 56, /* 16EA4 (93860) */ - 56, /* 16EA5 (93861) */ - 56, /* 16EA6 (93862) */ - 56, /* 16EA7 (93863) */ - 56, /* 16EA8 (93864) */ - 56, /* 16EA9 (93865) */ - 56, /* 16EAA (93866) */ - 56, /* 16EAB (93867) */ - 56, /* 16EAC (93868) */ - 56, /* 16EAD (93869) */ - 56, /* 16EAE (93870) */ - 56, /* 16EAF (93871) */ - 56, /* 16EB0 (93872) */ - 56, /* 16EB1 (93873) */ - 56, /* 16EB2 (93874) */ - 56, /* 16EB3 (93875) */ - 56, /* 16EB4 (93876) */ - 56, /* 16EB5 (93877) */ - 56, /* 16EB6 (93878) */ - 56, /* 16EB7 (93879) */ - 56, /* 16EB8 (93880) */ + 5206, /* 16EA0 (93856) */ + 5207, /* 16EA1 (93857) */ + 5208, /* 16EA2 (93858) */ + 5209, /* 16EA3 (93859) */ + 5210, /* 16EA4 (93860) */ + 5211, /* 16EA5 (93861) */ + 5212, /* 16EA6 (93862) */ + 5213, /* 16EA7 (93863) */ + 5214, /* 16EA8 (93864) */ + 5215, /* 16EA9 (93865) */ + 5216, /* 16EAA (93866) */ + 5217, /* 16EAB (93867) */ + 5218, /* 16EAC (93868) */ + 5219, /* 16EAD (93869) */ + 5220, /* 16EAE (93870) */ + 5221, /* 16EAF (93871) */ + 5222, /* 16EB0 (93872) */ + 5223, /* 16EB1 (93873) */ + 5224, /* 16EB2 (93874) */ + 5225, /* 16EB3 (93875) */ + 5226, /* 16EB4 (93876) */ + 5227, /* 16EB5 (93877) */ + 5228, /* 16EB6 (93878) */ + 5229, /* 16EB7 (93879) */ + 5230, /* 16EB8 (93880) */ 56, /* 16EB9 (93881) */ 56, /* 16EBA (93882) */ - 56, /* 16EBB (93883) */ - 56, /* 16EBC (93884) */ - 56, /* 16EBD (93885) */ - 56, /* 16EBE (93886) */ - 56, /* 16EBF (93887) */ - 56, /* 16EC0 (93888) */ - 56, /* 16EC1 (93889) */ - 56, /* 16EC2 (93890) */ - 56, /* 16EC3 (93891) */ - 56, /* 16EC4 (93892) */ - 56, /* 16EC5 (93893) */ - 56, /* 16EC6 (93894) */ - 56, /* 16EC7 (93895) */ - 56, /* 16EC8 (93896) */ - 56, /* 16EC9 (93897) */ - 56, /* 16ECA (93898) */ - 56, /* 16ECB (93899) */ - 56, /* 16ECC (93900) */ - 56, /* 16ECD (93901) */ - 56, /* 16ECE (93902) */ - 56, /* 16ECF (93903) */ - 56, /* 16ED0 (93904) */ - 56, /* 16ED1 (93905) */ - 56, /* 16ED2 (93906) */ - 56, /* 16ED3 (93907) */ + 1, /* 16EBB (93883) */ + 1, /* 16EBC (93884) */ + 1, /* 16EBD (93885) */ + 1, /* 16EBE (93886) */ + 1, /* 16EBF (93887) */ + 1, /* 16EC0 (93888) */ + 1, /* 16EC1 (93889) */ + 1, /* 16EC2 (93890) */ + 1, /* 16EC3 (93891) */ + 1, /* 16EC4 (93892) */ + 1, /* 16EC5 (93893) */ + 1, /* 16EC6 (93894) */ + 1, /* 16EC7 (93895) */ + 1, /* 16EC8 (93896) */ + 1, /* 16EC9 (93897) */ + 1, /* 16ECA (93898) */ + 1, /* 16ECB (93899) */ + 1, /* 16ECC (93900) */ + 1, /* 16ECD (93901) */ + 1, /* 16ECE (93902) */ + 1, /* 16ECF (93903) */ + 1, /* 16ED0 (93904) */ + 1, /* 16ED1 (93905) */ + 1, /* 16ED2 (93906) */ + 1, /* 16ED3 (93907) */ 56, /* 16ED4 (93908) */ 56, /* 16ED5 (93909) */ 56, /* 16ED6 (93910) */ @@ -80984,13 +80984,13 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 56, /* 16FED (94189) */ 56, /* 16FEE (94190) */ 56, /* 16FEF (94191) */ - 5202, /* 16FF0 (94192) */ - 5202, /* 16FF1 (94193) */ - 56, /* 16FF2 (94194) */ - 56, /* 16FF3 (94195) */ - 56, /* 16FF4 (94196) */ - 56, /* 16FF5 (94197) */ - 56, /* 16FF6 (94198) */ + 5231, /* 16FF0 (94192) */ + 5231, /* 16FF1 (94193) */ + 1, /* 16FF2 (94194) */ + 1, /* 16FF3 (94195) */ + 1, /* 16FF4 (94196) */ + 1, /* 16FF5 (94197) */ + 1, /* 16FF6 (94198) */ 56, /* 16FF7 (94199) */ 56, /* 16FF8 (94200) */ 56, /* 16FF9 (94201) */ @@ -87136,14 +87136,14 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 187F5 (100341) */ 1, /* 187F6 (100342) */ 1, /* 187F7 (100343) */ - 56, /* 187F8 (100344) */ - 56, /* 187F9 (100345) */ - 56, /* 187FA (100346) */ - 56, /* 187FB (100347) */ - 56, /* 187FC (100348) */ - 56, /* 187FD (100349) */ - 56, /* 187FE (100350) */ - 56, /* 187FF (100351) */ + 1, /* 187F8 (100344) */ + 1, /* 187F9 (100345) */ + 1, /* 187FA (100346) */ + 1, /* 187FB (100347) */ + 1, /* 187FC (100348) */ + 1, /* 187FD (100349) */ + 1, /* 187FE (100350) */ + 1, /* 187FF (100351) */ 1, /* 18800 (100352) */ 1, /* 18801 (100353) */ 1, /* 18802 (100354) */ @@ -88433,10 +88433,244 @@ static const uint16_t lxb_unicode_table_map_90368_101641[11273] = 1, /* 18D06 (101638) */ 1, /* 18D07 (101639) */ 1, /* 18D08 (101640) */ + 1, /* 18D09 (101641) */ + 1, /* 18D0A (101642) */ + 1, /* 18D0B (101643) */ + 1, /* 18D0C (101644) */ + 1, /* 18D0D (101645) */ + 1, /* 18D0E (101646) */ + 1, /* 18D0F (101647) */ + 1, /* 18D10 (101648) */ + 1, /* 18D11 (101649) */ + 1, /* 18D12 (101650) */ + 1, /* 18D13 (101651) */ + 1, /* 18D14 (101652) */ + 1, /* 18D15 (101653) */ + 1, /* 18D16 (101654) */ + 1, /* 18D17 (101655) */ + 1, /* 18D18 (101656) */ + 1, /* 18D19 (101657) */ + 1, /* 18D1A (101658) */ + 1, /* 18D1B (101659) */ + 1, /* 18D1C (101660) */ + 1, /* 18D1D (101661) */ + 1, /* 18D1E (101662) */ + 56, /* 18D1F (101663) */ + 56, /* 18D20 (101664) */ + 56, /* 18D21 (101665) */ + 56, /* 18D22 (101666) */ + 56, /* 18D23 (101667) */ + 56, /* 18D24 (101668) */ + 56, /* 18D25 (101669) */ + 56, /* 18D26 (101670) */ + 56, /* 18D27 (101671) */ + 56, /* 18D28 (101672) */ + 56, /* 18D29 (101673) */ + 56, /* 18D2A (101674) */ + 56, /* 18D2B (101675) */ + 56, /* 18D2C (101676) */ + 56, /* 18D2D (101677) */ + 56, /* 18D2E (101678) */ + 56, /* 18D2F (101679) */ + 56, /* 18D30 (101680) */ + 56, /* 18D31 (101681) */ + 56, /* 18D32 (101682) */ + 56, /* 18D33 (101683) */ + 56, /* 18D34 (101684) */ + 56, /* 18D35 (101685) */ + 56, /* 18D36 (101686) */ + 56, /* 18D37 (101687) */ + 56, /* 18D38 (101688) */ + 56, /* 18D39 (101689) */ + 56, /* 18D3A (101690) */ + 56, /* 18D3B (101691) */ + 56, /* 18D3C (101692) */ + 56, /* 18D3D (101693) */ + 56, /* 18D3E (101694) */ + 56, /* 18D3F (101695) */ + 56, /* 18D40 (101696) */ + 56, /* 18D41 (101697) */ + 56, /* 18D42 (101698) */ + 56, /* 18D43 (101699) */ + 56, /* 18D44 (101700) */ + 56, /* 18D45 (101701) */ + 56, /* 18D46 (101702) */ + 56, /* 18D47 (101703) */ + 56, /* 18D48 (101704) */ + 56, /* 18D49 (101705) */ + 56, /* 18D4A (101706) */ + 56, /* 18D4B (101707) */ + 56, /* 18D4C (101708) */ + 56, /* 18D4D (101709) */ + 56, /* 18D4E (101710) */ + 56, /* 18D4F (101711) */ + 56, /* 18D50 (101712) */ + 56, /* 18D51 (101713) */ + 56, /* 18D52 (101714) */ + 56, /* 18D53 (101715) */ + 56, /* 18D54 (101716) */ + 56, /* 18D55 (101717) */ + 56, /* 18D56 (101718) */ + 56, /* 18D57 (101719) */ + 56, /* 18D58 (101720) */ + 56, /* 18D59 (101721) */ + 56, /* 18D5A (101722) */ + 56, /* 18D5B (101723) */ + 56, /* 18D5C (101724) */ + 56, /* 18D5D (101725) */ + 56, /* 18D5E (101726) */ + 56, /* 18D5F (101727) */ + 56, /* 18D60 (101728) */ + 56, /* 18D61 (101729) */ + 56, /* 18D62 (101730) */ + 56, /* 18D63 (101731) */ + 56, /* 18D64 (101732) */ + 56, /* 18D65 (101733) */ + 56, /* 18D66 (101734) */ + 56, /* 18D67 (101735) */ + 56, /* 18D68 (101736) */ + 56, /* 18D69 (101737) */ + 56, /* 18D6A (101738) */ + 56, /* 18D6B (101739) */ + 56, /* 18D6C (101740) */ + 56, /* 18D6D (101741) */ + 56, /* 18D6E (101742) */ + 56, /* 18D6F (101743) */ + 56, /* 18D70 (101744) */ + 56, /* 18D71 (101745) */ + 56, /* 18D72 (101746) */ + 56, /* 18D73 (101747) */ + 56, /* 18D74 (101748) */ + 56, /* 18D75 (101749) */ + 56, /* 18D76 (101750) */ + 56, /* 18D77 (101751) */ + 56, /* 18D78 (101752) */ + 56, /* 18D79 (101753) */ + 56, /* 18D7A (101754) */ + 56, /* 18D7B (101755) */ + 56, /* 18D7C (101756) */ + 56, /* 18D7D (101757) */ + 56, /* 18D7E (101758) */ + 56, /* 18D7F (101759) */ + 1, /* 18D80 (101760) */ + 1, /* 18D81 (101761) */ + 1, /* 18D82 (101762) */ + 1, /* 18D83 (101763) */ + 1, /* 18D84 (101764) */ + 1, /* 18D85 (101765) */ + 1, /* 18D86 (101766) */ + 1, /* 18D87 (101767) */ + 1, /* 18D88 (101768) */ + 1, /* 18D89 (101769) */ + 1, /* 18D8A (101770) */ + 1, /* 18D8B (101771) */ + 1, /* 18D8C (101772) */ + 1, /* 18D8D (101773) */ + 1, /* 18D8E (101774) */ + 1, /* 18D8F (101775) */ + 1, /* 18D90 (101776) */ + 1, /* 18D91 (101777) */ + 1, /* 18D92 (101778) */ + 1, /* 18D93 (101779) */ + 1, /* 18D94 (101780) */ + 1, /* 18D95 (101781) */ + 1, /* 18D96 (101782) */ + 1, /* 18D97 (101783) */ + 1, /* 18D98 (101784) */ + 1, /* 18D99 (101785) */ + 1, /* 18D9A (101786) */ + 1, /* 18D9B (101787) */ + 1, /* 18D9C (101788) */ + 1, /* 18D9D (101789) */ + 1, /* 18D9E (101790) */ + 1, /* 18D9F (101791) */ + 1, /* 18DA0 (101792) */ + 1, /* 18DA1 (101793) */ + 1, /* 18DA2 (101794) */ + 1, /* 18DA3 (101795) */ + 1, /* 18DA4 (101796) */ + 1, /* 18DA5 (101797) */ + 1, /* 18DA6 (101798) */ + 1, /* 18DA7 (101799) */ + 1, /* 18DA8 (101800) */ + 1, /* 18DA9 (101801) */ + 1, /* 18DAA (101802) */ + 1, /* 18DAB (101803) */ + 1, /* 18DAC (101804) */ + 1, /* 18DAD (101805) */ + 1, /* 18DAE (101806) */ + 1, /* 18DAF (101807) */ + 1, /* 18DB0 (101808) */ + 1, /* 18DB1 (101809) */ + 1, /* 18DB2 (101810) */ + 1, /* 18DB3 (101811) */ + 1, /* 18DB4 (101812) */ + 1, /* 18DB5 (101813) */ + 1, /* 18DB6 (101814) */ + 1, /* 18DB7 (101815) */ + 1, /* 18DB8 (101816) */ + 1, /* 18DB9 (101817) */ + 1, /* 18DBA (101818) */ + 1, /* 18DBB (101819) */ + 1, /* 18DBC (101820) */ + 1, /* 18DBD (101821) */ + 1, /* 18DBE (101822) */ + 1, /* 18DBF (101823) */ + 1, /* 18DC0 (101824) */ + 1, /* 18DC1 (101825) */ + 1, /* 18DC2 (101826) */ + 1, /* 18DC3 (101827) */ + 1, /* 18DC4 (101828) */ + 1, /* 18DC5 (101829) */ + 1, /* 18DC6 (101830) */ + 1, /* 18DC7 (101831) */ + 1, /* 18DC8 (101832) */ + 1, /* 18DC9 (101833) */ + 1, /* 18DCA (101834) */ + 1, /* 18DCB (101835) */ + 1, /* 18DCC (101836) */ + 1, /* 18DCD (101837) */ + 1, /* 18DCE (101838) */ + 1, /* 18DCF (101839) */ + 1, /* 18DD0 (101840) */ + 1, /* 18DD1 (101841) */ + 1, /* 18DD2 (101842) */ + 1, /* 18DD3 (101843) */ + 1, /* 18DD4 (101844) */ + 1, /* 18DD5 (101845) */ + 1, /* 18DD6 (101846) */ + 1, /* 18DD7 (101847) */ + 1, /* 18DD8 (101848) */ + 1, /* 18DD9 (101849) */ + 1, /* 18DDA (101850) */ + 1, /* 18DDB (101851) */ + 1, /* 18DDC (101852) */ + 1, /* 18DDD (101853) */ + 1, /* 18DDE (101854) */ + 1, /* 18DDF (101855) */ + 1, /* 18DE0 (101856) */ + 1, /* 18DE1 (101857) */ + 1, /* 18DE2 (101858) */ + 1, /* 18DE3 (101859) */ + 1, /* 18DE4 (101860) */ + 1, /* 18DE5 (101861) */ + 1, /* 18DE6 (101862) */ + 1, /* 18DE7 (101863) */ + 1, /* 18DE8 (101864) */ + 1, /* 18DE9 (101865) */ + 1, /* 18DEA (101866) */ + 1, /* 18DEB (101867) */ + 1, /* 18DEC (101868) */ + 1, /* 18DED (101869) */ + 1, /* 18DEE (101870) */ + 1, /* 18DEF (101871) */ + 1, /* 18DF0 (101872) */ + 1, /* 18DF1 (101873) */ + 1, /* 18DF2 (101874) */ }; -/* From: 1AFF0; To: 323AF */ -static const uint32_t lxb_unicode_table_map_110576_205744[95168] = +/* From: 1AFF0; To: 33479 */ +static const uint32_t lxb_unicode_table_map_110576_210042[99466] = { 1, /* 1AFF0 (110576) */ 1, /* 1AFF1 (110577) */ @@ -95836,45 +96070,45 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1CCD3 (117971) */ 1, /* 1CCD4 (117972) */ 1, /* 1CCD5 (117973) */ - 5203, /* 1CCD6 (117974) */ + 5232, /* 1CCD6 (117974) */ 1755, /* 1CCD7 (117975) */ 1730, /* 1CCD8 (117976) */ 1773, /* 1CCD9 (117977) */ 1757, /* 1CCDA (117978) */ 1758, /* 1CCDB (117979) */ - 5204, /* 1CCDC (117980) */ + 5233, /* 1CCDC (117980) */ 1737, /* 1CCDD (117981) */ 1740, /* 1CCDE (117982) */ - 5205, /* 1CCDF (117983) */ - 5206, /* 1CCE0 (117984) */ + 5234, /* 1CCDF (117983) */ + 5235, /* 1CCE0 (117984) */ 1741, /* 1CCE1 (117985) */ 1760, /* 1CCE2 (117986) */ 1743, /* 1CCE3 (117987) */ - 5207, /* 1CCE4 (117988) */ + 5236, /* 1CCE4 (117988) */ 1745, /* 1CCE5 (117989) */ 1746, /* 1CCE6 (117990) */ 1747, /* 1CCE7 (117991) */ - 5208, /* 1CCE8 (117992) */ - 5209, /* 1CCE9 (117993) */ - 5210, /* 1CCEA (117994) */ - 5211, /* 1CCEB (117995) */ - 5212, /* 1CCEC (117996) */ - 5213, /* 1CCED (117997) */ - 5214, /* 1CCEE (117998) */ + 5237, /* 1CCE8 (117992) */ + 5238, /* 1CCE9 (117993) */ + 5239, /* 1CCEA (117994) */ + 5240, /* 1CCEB (117995) */ + 5241, /* 1CCEC (117996) */ + 5242, /* 1CCED (117997) */ + 5243, /* 1CCEE (117998) */ 1751, /* 1CCEF (117999) */ - 5215, /* 1CCF0 (118000) */ - 5216, /* 1CCF1 (118001) */ - 5217, /* 1CCF2 (118002) */ - 5218, /* 1CCF3 (118003) */ - 5219, /* 1CCF4 (118004) */ - 5220, /* 1CCF5 (118005) */ - 5221, /* 1CCF6 (118006) */ - 5222, /* 1CCF7 (118007) */ - 5223, /* 1CCF8 (118008) */ - 5224, /* 1CCF9 (118009) */ - 56, /* 1CCFA (118010) */ - 56, /* 1CCFB (118011) */ - 56, /* 1CCFC (118012) */ + 5244, /* 1CCF0 (118000) */ + 5245, /* 1CCF1 (118001) */ + 5246, /* 1CCF2 (118002) */ + 5247, /* 1CCF3 (118003) */ + 5248, /* 1CCF4 (118004) */ + 5249, /* 1CCF5 (118005) */ + 5250, /* 1CCF6 (118006) */ + 5251, /* 1CCF7 (118007) */ + 5252, /* 1CCF8 (118008) */ + 5253, /* 1CCF9 (118009) */ + 1, /* 1CCFA (118010) */ + 1, /* 1CCFB (118011) */ + 1, /* 1CCFC (118012) */ 56, /* 1CCFD (118013) */ 56, /* 1CCFE (118014) */ 56, /* 1CCFF (118015) */ @@ -96320,29 +96554,29 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1CEB7 (118455) */ 56, /* 1CEB8 (118456) */ 56, /* 1CEB9 (118457) */ - 56, /* 1CEBA (118458) */ - 56, /* 1CEBB (118459) */ - 56, /* 1CEBC (118460) */ - 56, /* 1CEBD (118461) */ - 56, /* 1CEBE (118462) */ - 56, /* 1CEBF (118463) */ - 56, /* 1CEC0 (118464) */ - 56, /* 1CEC1 (118465) */ - 56, /* 1CEC2 (118466) */ - 56, /* 1CEC3 (118467) */ - 56, /* 1CEC4 (118468) */ - 56, /* 1CEC5 (118469) */ - 56, /* 1CEC6 (118470) */ - 56, /* 1CEC7 (118471) */ - 56, /* 1CEC8 (118472) */ - 56, /* 1CEC9 (118473) */ - 56, /* 1CECA (118474) */ - 56, /* 1CECB (118475) */ - 56, /* 1CECC (118476) */ - 56, /* 1CECD (118477) */ - 56, /* 1CECE (118478) */ - 56, /* 1CECF (118479) */ - 56, /* 1CED0 (118480) */ + 1, /* 1CEBA (118458) */ + 1, /* 1CEBB (118459) */ + 1, /* 1CEBC (118460) */ + 1, /* 1CEBD (118461) */ + 1, /* 1CEBE (118462) */ + 1, /* 1CEBF (118463) */ + 1, /* 1CEC0 (118464) */ + 1, /* 1CEC1 (118465) */ + 1, /* 1CEC2 (118466) */ + 1, /* 1CEC3 (118467) */ + 1, /* 1CEC4 (118468) */ + 1, /* 1CEC5 (118469) */ + 1, /* 1CEC6 (118470) */ + 1, /* 1CEC7 (118471) */ + 1, /* 1CEC8 (118472) */ + 1, /* 1CEC9 (118473) */ + 1, /* 1CECA (118474) */ + 1, /* 1CECB (118475) */ + 1, /* 1CECC (118476) */ + 1, /* 1CECD (118477) */ + 1, /* 1CECE (118478) */ + 1, /* 1CECF (118479) */ + 1, /* 1CED0 (118480) */ 56, /* 1CED1 (118481) */ 56, /* 1CED2 (118482) */ 56, /* 1CED3 (118483) */ @@ -96358,23 +96592,23 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1CEDD (118493) */ 56, /* 1CEDE (118494) */ 56, /* 1CEDF (118495) */ - 56, /* 1CEE0 (118496) */ - 56, /* 1CEE1 (118497) */ - 56, /* 1CEE2 (118498) */ - 56, /* 1CEE3 (118499) */ - 56, /* 1CEE4 (118500) */ - 56, /* 1CEE5 (118501) */ - 56, /* 1CEE6 (118502) */ - 56, /* 1CEE7 (118503) */ - 56, /* 1CEE8 (118504) */ - 56, /* 1CEE9 (118505) */ - 56, /* 1CEEA (118506) */ - 56, /* 1CEEB (118507) */ - 56, /* 1CEEC (118508) */ - 56, /* 1CEED (118509) */ - 56, /* 1CEEE (118510) */ - 56, /* 1CEEF (118511) */ - 56, /* 1CEF0 (118512) */ + 1, /* 1CEE0 (118496) */ + 1, /* 1CEE1 (118497) */ + 1, /* 1CEE2 (118498) */ + 1, /* 1CEE3 (118499) */ + 1, /* 1CEE4 (118500) */ + 1, /* 1CEE5 (118501) */ + 1, /* 1CEE6 (118502) */ + 1, /* 1CEE7 (118503) */ + 1, /* 1CEE8 (118504) */ + 1, /* 1CEE9 (118505) */ + 1, /* 1CEEA (118506) */ + 1, /* 1CEEB (118507) */ + 1, /* 1CEEC (118508) */ + 1, /* 1CEED (118509) */ + 1, /* 1CEEE (118510) */ + 1, /* 1CEEF (118511) */ + 1, /* 1CEF0 (118512) */ 56, /* 1CEF1 (118513) */ 56, /* 1CEF2 (118514) */ 56, /* 1CEF3 (118515) */ @@ -96989,20 +97223,20 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1D154 (119124) */ 1, /* 1D155 (119125) */ 1, /* 1D156 (119126) */ - 5225, /* 1D157 (119127) */ - 5226, /* 1D158 (119128) */ + 5254, /* 1D157 (119127) */ + 5255, /* 1D158 (119128) */ 1, /* 1D159 (119129) */ 1, /* 1D15A (119130) */ 1, /* 1D15B (119131) */ 1, /* 1D15C (119132) */ 1, /* 1D15D (119133) */ - 5227, /* 1D15E (119134) */ - 5228, /* 1D15F (119135) */ - 5229, /* 1D160 (119136) */ - 5230, /* 1D161 (119137) */ - 5231, /* 1D162 (119138) */ - 5232, /* 1D163 (119139) */ - 5233, /* 1D164 (119140) */ + 5256, /* 1D15E (119134) */ + 5257, /* 1D15F (119135) */ + 5258, /* 1D160 (119136) */ + 5259, /* 1D161 (119137) */ + 5260, /* 1D162 (119138) */ + 5261, /* 1D163 (119139) */ + 5262, /* 1D164 (119140) */ 930, /* 1D165 (119141) */ 930, /* 1D166 (119142) */ 438, /* 1D167 (119143) */ @@ -97011,7 +97245,7 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1D16A (119146) */ 1, /* 1D16B (119147) */ 1, /* 1D16C (119148) */ - 5234, /* 1D16D (119149) */ + 5263, /* 1D16D (119149) */ 930, /* 1D16E (119150) */ 930, /* 1D16F (119151) */ 930, /* 1D170 (119152) */ @@ -97087,14 +97321,14 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1D1B6 (119222) */ 1, /* 1D1B7 (119223) */ 1, /* 1D1B8 (119224) */ - 5235, /* 1D1B9 (119225) */ - 5236, /* 1D1BA (119226) */ - 5237, /* 1D1BB (119227) */ - 5238, /* 1D1BC (119228) */ - 5239, /* 1D1BD (119229) */ - 5240, /* 1D1BE (119230) */ - 5241, /* 1D1BF (119231) */ - 5242, /* 1D1C0 (119232) */ + 5264, /* 1D1B9 (119225) */ + 5265, /* 1D1BA (119226) */ + 5266, /* 1D1BB (119227) */ + 5267, /* 1D1BC (119228) */ + 5268, /* 1D1BD (119229) */ + 5269, /* 1D1BE (119230) */ + 5270, /* 1D1BF (119231) */ + 5271, /* 1D1C0 (119232) */ 1, /* 1D1C1 (119233) */ 1, /* 1D1C2 (119234) */ 1, /* 1D1C3 (119235) */ @@ -97670,1030 +97904,1030 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1D3FD (119805) */ 56, /* 1D3FE (119806) */ 56, /* 1D3FF (119807) */ - 5203, /* 1D400 (119808) */ + 5232, /* 1D400 (119808) */ 1755, /* 1D401 (119809) */ 1730, /* 1D402 (119810) */ 1773, /* 1D403 (119811) */ 1757, /* 1D404 (119812) */ 1758, /* 1D405 (119813) */ - 5204, /* 1D406 (119814) */ + 5233, /* 1D406 (119814) */ 1737, /* 1D407 (119815) */ 1740, /* 1D408 (119816) */ - 5205, /* 1D409 (119817) */ - 5206, /* 1D40A (119818) */ + 5234, /* 1D409 (119817) */ + 5235, /* 1D40A (119818) */ 1741, /* 1D40B (119819) */ 1760, /* 1D40C (119820) */ 1743, /* 1D40D (119821) */ - 5207, /* 1D40E (119822) */ + 5236, /* 1D40E (119822) */ 1745, /* 1D40F (119823) */ 1746, /* 1D410 (119824) */ 1747, /* 1D411 (119825) */ - 5208, /* 1D412 (119826) */ - 5209, /* 1D413 (119827) */ - 5210, /* 1D414 (119828) */ - 5211, /* 1D415 (119829) */ - 5212, /* 1D416 (119830) */ - 5213, /* 1D417 (119831) */ - 5214, /* 1D418 (119832) */ + 5237, /* 1D412 (119826) */ + 5238, /* 1D413 (119827) */ + 5239, /* 1D414 (119828) */ + 5240, /* 1D415 (119829) */ + 5241, /* 1D416 (119830) */ + 5242, /* 1D417 (119831) */ + 5243, /* 1D418 (119832) */ 1751, /* 1D419 (119833) */ - 5243, /* 1D41A (119834) */ - 5244, /* 1D41B (119835) */ - 5245, /* 1D41C (119836) */ + 5272, /* 1D41A (119834) */ + 5273, /* 1D41B (119835) */ + 5274, /* 1D41C (119836) */ 1774, /* 1D41D (119837) */ 1756, /* 1D41E (119838) */ - 5246, /* 1D41F (119839) */ + 5275, /* 1D41F (119839) */ 1736, /* 1D420 (119840) */ 1738, /* 1D421 (119841) */ 1766, /* 1D422 (119842) */ 1775, /* 1D423 (119843) */ - 5247, /* 1D424 (119844) */ + 5276, /* 1D424 (119844) */ 1742, /* 1D425 (119845) */ - 5248, /* 1D426 (119846) */ - 5249, /* 1D427 (119847) */ + 5277, /* 1D426 (119846) */ + 5278, /* 1D427 (119847) */ 1761, /* 1D428 (119848) */ - 5250, /* 1D429 (119849) */ - 5251, /* 1D42A (119850) */ - 5252, /* 1D42B (119851) */ - 5253, /* 1D42C (119852) */ - 5254, /* 1D42D (119853) */ - 5255, /* 1D42E (119854) */ - 5256, /* 1D42F (119855) */ - 5257, /* 1D430 (119856) */ - 5258, /* 1D431 (119857) */ - 5259, /* 1D432 (119858) */ - 5260, /* 1D433 (119859) */ - 5203, /* 1D434 (119860) */ + 5279, /* 1D429 (119849) */ + 5280, /* 1D42A (119850) */ + 5281, /* 1D42B (119851) */ + 5282, /* 1D42C (119852) */ + 5283, /* 1D42D (119853) */ + 5284, /* 1D42E (119854) */ + 5285, /* 1D42F (119855) */ + 5286, /* 1D430 (119856) */ + 5287, /* 1D431 (119857) */ + 5288, /* 1D432 (119858) */ + 5289, /* 1D433 (119859) */ + 5232, /* 1D434 (119860) */ 1755, /* 1D435 (119861) */ 1730, /* 1D436 (119862) */ 1773, /* 1D437 (119863) */ 1757, /* 1D438 (119864) */ 1758, /* 1D439 (119865) */ - 5204, /* 1D43A (119866) */ + 5233, /* 1D43A (119866) */ 1737, /* 1D43B (119867) */ 1740, /* 1D43C (119868) */ - 5205, /* 1D43D (119869) */ - 5206, /* 1D43E (119870) */ + 5234, /* 1D43D (119869) */ + 5235, /* 1D43E (119870) */ 1741, /* 1D43F (119871) */ 1760, /* 1D440 (119872) */ 1743, /* 1D441 (119873) */ - 5207, /* 1D442 (119874) */ + 5236, /* 1D442 (119874) */ 1745, /* 1D443 (119875) */ 1746, /* 1D444 (119876) */ 1747, /* 1D445 (119877) */ - 5208, /* 1D446 (119878) */ - 5209, /* 1D447 (119879) */ - 5210, /* 1D448 (119880) */ - 5211, /* 1D449 (119881) */ - 5212, /* 1D44A (119882) */ - 5213, /* 1D44B (119883) */ - 5214, /* 1D44C (119884) */ + 5237, /* 1D446 (119878) */ + 5238, /* 1D447 (119879) */ + 5239, /* 1D448 (119880) */ + 5240, /* 1D449 (119881) */ + 5241, /* 1D44A (119882) */ + 5242, /* 1D44B (119883) */ + 5243, /* 1D44C (119884) */ 1751, /* 1D44D (119885) */ - 5243, /* 1D44E (119886) */ - 5244, /* 1D44F (119887) */ - 5245, /* 1D450 (119888) */ + 5272, /* 1D44E (119886) */ + 5273, /* 1D44F (119887) */ + 5274, /* 1D450 (119888) */ 1774, /* 1D451 (119889) */ 1756, /* 1D452 (119890) */ - 5246, /* 1D453 (119891) */ + 5275, /* 1D453 (119891) */ 1736, /* 1D454 (119892) */ 56, /* 1D455 (119893) */ 1766, /* 1D456 (119894) */ 1775, /* 1D457 (119895) */ - 5247, /* 1D458 (119896) */ + 5276, /* 1D458 (119896) */ 1742, /* 1D459 (119897) */ - 5248, /* 1D45A (119898) */ - 5249, /* 1D45B (119899) */ + 5277, /* 1D45A (119898) */ + 5278, /* 1D45B (119899) */ 1761, /* 1D45C (119900) */ - 5250, /* 1D45D (119901) */ - 5251, /* 1D45E (119902) */ - 5252, /* 1D45F (119903) */ - 5253, /* 1D460 (119904) */ - 5254, /* 1D461 (119905) */ - 5255, /* 1D462 (119906) */ - 5256, /* 1D463 (119907) */ - 5257, /* 1D464 (119908) */ - 5258, /* 1D465 (119909) */ - 5259, /* 1D466 (119910) */ - 5260, /* 1D467 (119911) */ - 5203, /* 1D468 (119912) */ + 5279, /* 1D45D (119901) */ + 5280, /* 1D45E (119902) */ + 5281, /* 1D45F (119903) */ + 5282, /* 1D460 (119904) */ + 5283, /* 1D461 (119905) */ + 5284, /* 1D462 (119906) */ + 5285, /* 1D463 (119907) */ + 5286, /* 1D464 (119908) */ + 5287, /* 1D465 (119909) */ + 5288, /* 1D466 (119910) */ + 5289, /* 1D467 (119911) */ + 5232, /* 1D468 (119912) */ 1755, /* 1D469 (119913) */ 1730, /* 1D46A (119914) */ 1773, /* 1D46B (119915) */ 1757, /* 1D46C (119916) */ 1758, /* 1D46D (119917) */ - 5204, /* 1D46E (119918) */ + 5233, /* 1D46E (119918) */ 1737, /* 1D46F (119919) */ 1740, /* 1D470 (119920) */ - 5205, /* 1D471 (119921) */ - 5206, /* 1D472 (119922) */ + 5234, /* 1D471 (119921) */ + 5235, /* 1D472 (119922) */ 1741, /* 1D473 (119923) */ 1760, /* 1D474 (119924) */ 1743, /* 1D475 (119925) */ - 5207, /* 1D476 (119926) */ + 5236, /* 1D476 (119926) */ 1745, /* 1D477 (119927) */ 1746, /* 1D478 (119928) */ 1747, /* 1D479 (119929) */ - 5208, /* 1D47A (119930) */ - 5209, /* 1D47B (119931) */ - 5210, /* 1D47C (119932) */ - 5211, /* 1D47D (119933) */ - 5212, /* 1D47E (119934) */ - 5213, /* 1D47F (119935) */ - 5214, /* 1D480 (119936) */ + 5237, /* 1D47A (119930) */ + 5238, /* 1D47B (119931) */ + 5239, /* 1D47C (119932) */ + 5240, /* 1D47D (119933) */ + 5241, /* 1D47E (119934) */ + 5242, /* 1D47F (119935) */ + 5243, /* 1D480 (119936) */ 1751, /* 1D481 (119937) */ - 5243, /* 1D482 (119938) */ - 5244, /* 1D483 (119939) */ - 5245, /* 1D484 (119940) */ + 5272, /* 1D482 (119938) */ + 5273, /* 1D483 (119939) */ + 5274, /* 1D484 (119940) */ 1774, /* 1D485 (119941) */ 1756, /* 1D486 (119942) */ - 5246, /* 1D487 (119943) */ + 5275, /* 1D487 (119943) */ 1736, /* 1D488 (119944) */ 1738, /* 1D489 (119945) */ 1766, /* 1D48A (119946) */ 1775, /* 1D48B (119947) */ - 5247, /* 1D48C (119948) */ + 5276, /* 1D48C (119948) */ 1742, /* 1D48D (119949) */ - 5248, /* 1D48E (119950) */ - 5249, /* 1D48F (119951) */ + 5277, /* 1D48E (119950) */ + 5278, /* 1D48F (119951) */ 1761, /* 1D490 (119952) */ - 5250, /* 1D491 (119953) */ - 5251, /* 1D492 (119954) */ - 5252, /* 1D493 (119955) */ - 5253, /* 1D494 (119956) */ - 5254, /* 1D495 (119957) */ - 5255, /* 1D496 (119958) */ - 5256, /* 1D497 (119959) */ - 5257, /* 1D498 (119960) */ - 5258, /* 1D499 (119961) */ - 5259, /* 1D49A (119962) */ - 5260, /* 1D49B (119963) */ - 5203, /* 1D49C (119964) */ + 5279, /* 1D491 (119953) */ + 5280, /* 1D492 (119954) */ + 5281, /* 1D493 (119955) */ + 5282, /* 1D494 (119956) */ + 5283, /* 1D495 (119957) */ + 5284, /* 1D496 (119958) */ + 5285, /* 1D497 (119959) */ + 5286, /* 1D498 (119960) */ + 5287, /* 1D499 (119961) */ + 5288, /* 1D49A (119962) */ + 5289, /* 1D49B (119963) */ + 5232, /* 1D49C (119964) */ 56, /* 1D49D (119965) */ 1730, /* 1D49E (119966) */ 1773, /* 1D49F (119967) */ 56, /* 1D4A0 (119968) */ 56, /* 1D4A1 (119969) */ - 5204, /* 1D4A2 (119970) */ + 5233, /* 1D4A2 (119970) */ 56, /* 1D4A3 (119971) */ 56, /* 1D4A4 (119972) */ - 5205, /* 1D4A5 (119973) */ - 5206, /* 1D4A6 (119974) */ + 5234, /* 1D4A5 (119973) */ + 5235, /* 1D4A6 (119974) */ 56, /* 1D4A7 (119975) */ 56, /* 1D4A8 (119976) */ 1743, /* 1D4A9 (119977) */ - 5207, /* 1D4AA (119978) */ + 5236, /* 1D4AA (119978) */ 1745, /* 1D4AB (119979) */ 1746, /* 1D4AC (119980) */ 56, /* 1D4AD (119981) */ - 5208, /* 1D4AE (119982) */ - 5209, /* 1D4AF (119983) */ - 5210, /* 1D4B0 (119984) */ - 5211, /* 1D4B1 (119985) */ - 5212, /* 1D4B2 (119986) */ - 5213, /* 1D4B3 (119987) */ - 5214, /* 1D4B4 (119988) */ + 5237, /* 1D4AE (119982) */ + 5238, /* 1D4AF (119983) */ + 5239, /* 1D4B0 (119984) */ + 5240, /* 1D4B1 (119985) */ + 5241, /* 1D4B2 (119986) */ + 5242, /* 1D4B3 (119987) */ + 5243, /* 1D4B4 (119988) */ 1751, /* 1D4B5 (119989) */ - 5243, /* 1D4B6 (119990) */ - 5244, /* 1D4B7 (119991) */ - 5245, /* 1D4B8 (119992) */ + 5272, /* 1D4B6 (119990) */ + 5273, /* 1D4B7 (119991) */ + 5274, /* 1D4B8 (119992) */ 1774, /* 1D4B9 (119993) */ 56, /* 1D4BA (119994) */ - 5246, /* 1D4BB (119995) */ + 5275, /* 1D4BB (119995) */ 56, /* 1D4BC (119996) */ 1738, /* 1D4BD (119997) */ 1766, /* 1D4BE (119998) */ 1775, /* 1D4BF (119999) */ - 5247, /* 1D4C0 (120000) */ + 5276, /* 1D4C0 (120000) */ 1742, /* 1D4C1 (120001) */ - 5248, /* 1D4C2 (120002) */ - 5249, /* 1D4C3 (120003) */ + 5277, /* 1D4C2 (120002) */ + 5278, /* 1D4C3 (120003) */ 56, /* 1D4C4 (120004) */ - 5250, /* 1D4C5 (120005) */ - 5251, /* 1D4C6 (120006) */ - 5252, /* 1D4C7 (120007) */ - 5253, /* 1D4C8 (120008) */ - 5254, /* 1D4C9 (120009) */ - 5255, /* 1D4CA (120010) */ - 5256, /* 1D4CB (120011) */ - 5257, /* 1D4CC (120012) */ - 5258, /* 1D4CD (120013) */ - 5259, /* 1D4CE (120014) */ - 5260, /* 1D4CF (120015) */ - 5203, /* 1D4D0 (120016) */ + 5279, /* 1D4C5 (120005) */ + 5280, /* 1D4C6 (120006) */ + 5281, /* 1D4C7 (120007) */ + 5282, /* 1D4C8 (120008) */ + 5283, /* 1D4C9 (120009) */ + 5284, /* 1D4CA (120010) */ + 5285, /* 1D4CB (120011) */ + 5286, /* 1D4CC (120012) */ + 5287, /* 1D4CD (120013) */ + 5288, /* 1D4CE (120014) */ + 5289, /* 1D4CF (120015) */ + 5232, /* 1D4D0 (120016) */ 1755, /* 1D4D1 (120017) */ 1730, /* 1D4D2 (120018) */ 1773, /* 1D4D3 (120019) */ 1757, /* 1D4D4 (120020) */ 1758, /* 1D4D5 (120021) */ - 5204, /* 1D4D6 (120022) */ + 5233, /* 1D4D6 (120022) */ 1737, /* 1D4D7 (120023) */ 1740, /* 1D4D8 (120024) */ - 5205, /* 1D4D9 (120025) */ - 5206, /* 1D4DA (120026) */ + 5234, /* 1D4D9 (120025) */ + 5235, /* 1D4DA (120026) */ 1741, /* 1D4DB (120027) */ 1760, /* 1D4DC (120028) */ 1743, /* 1D4DD (120029) */ - 5207, /* 1D4DE (120030) */ + 5236, /* 1D4DE (120030) */ 1745, /* 1D4DF (120031) */ 1746, /* 1D4E0 (120032) */ 1747, /* 1D4E1 (120033) */ - 5208, /* 1D4E2 (120034) */ - 5209, /* 1D4E3 (120035) */ - 5210, /* 1D4E4 (120036) */ - 5211, /* 1D4E5 (120037) */ - 5212, /* 1D4E6 (120038) */ - 5213, /* 1D4E7 (120039) */ - 5214, /* 1D4E8 (120040) */ + 5237, /* 1D4E2 (120034) */ + 5238, /* 1D4E3 (120035) */ + 5239, /* 1D4E4 (120036) */ + 5240, /* 1D4E5 (120037) */ + 5241, /* 1D4E6 (120038) */ + 5242, /* 1D4E7 (120039) */ + 5243, /* 1D4E8 (120040) */ 1751, /* 1D4E9 (120041) */ - 5243, /* 1D4EA (120042) */ - 5244, /* 1D4EB (120043) */ - 5245, /* 1D4EC (120044) */ + 5272, /* 1D4EA (120042) */ + 5273, /* 1D4EB (120043) */ + 5274, /* 1D4EC (120044) */ 1774, /* 1D4ED (120045) */ 1756, /* 1D4EE (120046) */ - 5246, /* 1D4EF (120047) */ + 5275, /* 1D4EF (120047) */ 1736, /* 1D4F0 (120048) */ 1738, /* 1D4F1 (120049) */ 1766, /* 1D4F2 (120050) */ 1775, /* 1D4F3 (120051) */ - 5247, /* 1D4F4 (120052) */ + 5276, /* 1D4F4 (120052) */ 1742, /* 1D4F5 (120053) */ - 5248, /* 1D4F6 (120054) */ - 5249, /* 1D4F7 (120055) */ + 5277, /* 1D4F6 (120054) */ + 5278, /* 1D4F7 (120055) */ 1761, /* 1D4F8 (120056) */ - 5250, /* 1D4F9 (120057) */ - 5251, /* 1D4FA (120058) */ - 5252, /* 1D4FB (120059) */ - 5253, /* 1D4FC (120060) */ - 5254, /* 1D4FD (120061) */ - 5255, /* 1D4FE (120062) */ - 5256, /* 1D4FF (120063) */ - 5257, /* 1D500 (120064) */ - 5258, /* 1D501 (120065) */ - 5259, /* 1D502 (120066) */ - 5260, /* 1D503 (120067) */ - 5203, /* 1D504 (120068) */ + 5279, /* 1D4F9 (120057) */ + 5280, /* 1D4FA (120058) */ + 5281, /* 1D4FB (120059) */ + 5282, /* 1D4FC (120060) */ + 5283, /* 1D4FD (120061) */ + 5284, /* 1D4FE (120062) */ + 5285, /* 1D4FF (120063) */ + 5286, /* 1D500 (120064) */ + 5287, /* 1D501 (120065) */ + 5288, /* 1D502 (120066) */ + 5289, /* 1D503 (120067) */ + 5232, /* 1D504 (120068) */ 1755, /* 1D505 (120069) */ 56, /* 1D506 (120070) */ 1773, /* 1D507 (120071) */ 1757, /* 1D508 (120072) */ 1758, /* 1D509 (120073) */ - 5204, /* 1D50A (120074) */ + 5233, /* 1D50A (120074) */ 56, /* 1D50B (120075) */ 56, /* 1D50C (120076) */ - 5205, /* 1D50D (120077) */ - 5206, /* 1D50E (120078) */ + 5234, /* 1D50D (120077) */ + 5235, /* 1D50E (120078) */ 1741, /* 1D50F (120079) */ 1760, /* 1D510 (120080) */ 1743, /* 1D511 (120081) */ - 5207, /* 1D512 (120082) */ + 5236, /* 1D512 (120082) */ 1745, /* 1D513 (120083) */ 1746, /* 1D514 (120084) */ 56, /* 1D515 (120085) */ - 5208, /* 1D516 (120086) */ - 5209, /* 1D517 (120087) */ - 5210, /* 1D518 (120088) */ - 5211, /* 1D519 (120089) */ - 5212, /* 1D51A (120090) */ - 5213, /* 1D51B (120091) */ - 5214, /* 1D51C (120092) */ + 5237, /* 1D516 (120086) */ + 5238, /* 1D517 (120087) */ + 5239, /* 1D518 (120088) */ + 5240, /* 1D519 (120089) */ + 5241, /* 1D51A (120090) */ + 5242, /* 1D51B (120091) */ + 5243, /* 1D51C (120092) */ 56, /* 1D51D (120093) */ - 5243, /* 1D51E (120094) */ - 5244, /* 1D51F (120095) */ - 5245, /* 1D520 (120096) */ + 5272, /* 1D51E (120094) */ + 5273, /* 1D51F (120095) */ + 5274, /* 1D520 (120096) */ 1774, /* 1D521 (120097) */ 1756, /* 1D522 (120098) */ - 5246, /* 1D523 (120099) */ + 5275, /* 1D523 (120099) */ 1736, /* 1D524 (120100) */ 1738, /* 1D525 (120101) */ 1766, /* 1D526 (120102) */ 1775, /* 1D527 (120103) */ - 5247, /* 1D528 (120104) */ + 5276, /* 1D528 (120104) */ 1742, /* 1D529 (120105) */ - 5248, /* 1D52A (120106) */ - 5249, /* 1D52B (120107) */ + 5277, /* 1D52A (120106) */ + 5278, /* 1D52B (120107) */ 1761, /* 1D52C (120108) */ - 5250, /* 1D52D (120109) */ - 5251, /* 1D52E (120110) */ - 5252, /* 1D52F (120111) */ - 5253, /* 1D530 (120112) */ - 5254, /* 1D531 (120113) */ - 5255, /* 1D532 (120114) */ - 5256, /* 1D533 (120115) */ - 5257, /* 1D534 (120116) */ - 5258, /* 1D535 (120117) */ - 5259, /* 1D536 (120118) */ - 5260, /* 1D537 (120119) */ - 5203, /* 1D538 (120120) */ + 5279, /* 1D52D (120109) */ + 5280, /* 1D52E (120110) */ + 5281, /* 1D52F (120111) */ + 5282, /* 1D530 (120112) */ + 5283, /* 1D531 (120113) */ + 5284, /* 1D532 (120114) */ + 5285, /* 1D533 (120115) */ + 5286, /* 1D534 (120116) */ + 5287, /* 1D535 (120117) */ + 5288, /* 1D536 (120118) */ + 5289, /* 1D537 (120119) */ + 5232, /* 1D538 (120120) */ 1755, /* 1D539 (120121) */ 56, /* 1D53A (120122) */ 1773, /* 1D53B (120123) */ 1757, /* 1D53C (120124) */ 1758, /* 1D53D (120125) */ - 5204, /* 1D53E (120126) */ + 5233, /* 1D53E (120126) */ 56, /* 1D53F (120127) */ 1740, /* 1D540 (120128) */ - 5205, /* 1D541 (120129) */ - 5206, /* 1D542 (120130) */ + 5234, /* 1D541 (120129) */ + 5235, /* 1D542 (120130) */ 1741, /* 1D543 (120131) */ 1760, /* 1D544 (120132) */ 56, /* 1D545 (120133) */ - 5207, /* 1D546 (120134) */ + 5236, /* 1D546 (120134) */ 56, /* 1D547 (120135) */ 56, /* 1D548 (120136) */ 56, /* 1D549 (120137) */ - 5208, /* 1D54A (120138) */ - 5209, /* 1D54B (120139) */ - 5210, /* 1D54C (120140) */ - 5211, /* 1D54D (120141) */ - 5212, /* 1D54E (120142) */ - 5213, /* 1D54F (120143) */ - 5214, /* 1D550 (120144) */ + 5237, /* 1D54A (120138) */ + 5238, /* 1D54B (120139) */ + 5239, /* 1D54C (120140) */ + 5240, /* 1D54D (120141) */ + 5241, /* 1D54E (120142) */ + 5242, /* 1D54F (120143) */ + 5243, /* 1D550 (120144) */ 56, /* 1D551 (120145) */ - 5243, /* 1D552 (120146) */ - 5244, /* 1D553 (120147) */ - 5245, /* 1D554 (120148) */ + 5272, /* 1D552 (120146) */ + 5273, /* 1D553 (120147) */ + 5274, /* 1D554 (120148) */ 1774, /* 1D555 (120149) */ 1756, /* 1D556 (120150) */ - 5246, /* 1D557 (120151) */ + 5275, /* 1D557 (120151) */ 1736, /* 1D558 (120152) */ 1738, /* 1D559 (120153) */ 1766, /* 1D55A (120154) */ 1775, /* 1D55B (120155) */ - 5247, /* 1D55C (120156) */ + 5276, /* 1D55C (120156) */ 1742, /* 1D55D (120157) */ - 5248, /* 1D55E (120158) */ - 5249, /* 1D55F (120159) */ + 5277, /* 1D55E (120158) */ + 5278, /* 1D55F (120159) */ 1761, /* 1D560 (120160) */ - 5250, /* 1D561 (120161) */ - 5251, /* 1D562 (120162) */ - 5252, /* 1D563 (120163) */ - 5253, /* 1D564 (120164) */ - 5254, /* 1D565 (120165) */ - 5255, /* 1D566 (120166) */ - 5256, /* 1D567 (120167) */ - 5257, /* 1D568 (120168) */ - 5258, /* 1D569 (120169) */ - 5259, /* 1D56A (120170) */ - 5260, /* 1D56B (120171) */ - 5203, /* 1D56C (120172) */ + 5279, /* 1D561 (120161) */ + 5280, /* 1D562 (120162) */ + 5281, /* 1D563 (120163) */ + 5282, /* 1D564 (120164) */ + 5283, /* 1D565 (120165) */ + 5284, /* 1D566 (120166) */ + 5285, /* 1D567 (120167) */ + 5286, /* 1D568 (120168) */ + 5287, /* 1D569 (120169) */ + 5288, /* 1D56A (120170) */ + 5289, /* 1D56B (120171) */ + 5232, /* 1D56C (120172) */ 1755, /* 1D56D (120173) */ 1730, /* 1D56E (120174) */ 1773, /* 1D56F (120175) */ 1757, /* 1D570 (120176) */ 1758, /* 1D571 (120177) */ - 5204, /* 1D572 (120178) */ + 5233, /* 1D572 (120178) */ 1737, /* 1D573 (120179) */ 1740, /* 1D574 (120180) */ - 5205, /* 1D575 (120181) */ - 5206, /* 1D576 (120182) */ + 5234, /* 1D575 (120181) */ + 5235, /* 1D576 (120182) */ 1741, /* 1D577 (120183) */ 1760, /* 1D578 (120184) */ 1743, /* 1D579 (120185) */ - 5207, /* 1D57A (120186) */ + 5236, /* 1D57A (120186) */ 1745, /* 1D57B (120187) */ 1746, /* 1D57C (120188) */ 1747, /* 1D57D (120189) */ - 5208, /* 1D57E (120190) */ - 5209, /* 1D57F (120191) */ - 5210, /* 1D580 (120192) */ - 5211, /* 1D581 (120193) */ - 5212, /* 1D582 (120194) */ - 5213, /* 1D583 (120195) */ - 5214, /* 1D584 (120196) */ + 5237, /* 1D57E (120190) */ + 5238, /* 1D57F (120191) */ + 5239, /* 1D580 (120192) */ + 5240, /* 1D581 (120193) */ + 5241, /* 1D582 (120194) */ + 5242, /* 1D583 (120195) */ + 5243, /* 1D584 (120196) */ 1751, /* 1D585 (120197) */ - 5243, /* 1D586 (120198) */ - 5244, /* 1D587 (120199) */ - 5245, /* 1D588 (120200) */ + 5272, /* 1D586 (120198) */ + 5273, /* 1D587 (120199) */ + 5274, /* 1D588 (120200) */ 1774, /* 1D589 (120201) */ 1756, /* 1D58A (120202) */ - 5246, /* 1D58B (120203) */ + 5275, /* 1D58B (120203) */ 1736, /* 1D58C (120204) */ 1738, /* 1D58D (120205) */ 1766, /* 1D58E (120206) */ 1775, /* 1D58F (120207) */ - 5247, /* 1D590 (120208) */ + 5276, /* 1D590 (120208) */ 1742, /* 1D591 (120209) */ - 5248, /* 1D592 (120210) */ - 5249, /* 1D593 (120211) */ + 5277, /* 1D592 (120210) */ + 5278, /* 1D593 (120211) */ 1761, /* 1D594 (120212) */ - 5250, /* 1D595 (120213) */ - 5251, /* 1D596 (120214) */ - 5252, /* 1D597 (120215) */ - 5253, /* 1D598 (120216) */ - 5254, /* 1D599 (120217) */ - 5255, /* 1D59A (120218) */ - 5256, /* 1D59B (120219) */ - 5257, /* 1D59C (120220) */ - 5258, /* 1D59D (120221) */ - 5259, /* 1D59E (120222) */ - 5260, /* 1D59F (120223) */ - 5203, /* 1D5A0 (120224) */ + 5279, /* 1D595 (120213) */ + 5280, /* 1D596 (120214) */ + 5281, /* 1D597 (120215) */ + 5282, /* 1D598 (120216) */ + 5283, /* 1D599 (120217) */ + 5284, /* 1D59A (120218) */ + 5285, /* 1D59B (120219) */ + 5286, /* 1D59C (120220) */ + 5287, /* 1D59D (120221) */ + 5288, /* 1D59E (120222) */ + 5289, /* 1D59F (120223) */ + 5232, /* 1D5A0 (120224) */ 1755, /* 1D5A1 (120225) */ 1730, /* 1D5A2 (120226) */ 1773, /* 1D5A3 (120227) */ 1757, /* 1D5A4 (120228) */ 1758, /* 1D5A5 (120229) */ - 5204, /* 1D5A6 (120230) */ + 5233, /* 1D5A6 (120230) */ 1737, /* 1D5A7 (120231) */ 1740, /* 1D5A8 (120232) */ - 5205, /* 1D5A9 (120233) */ - 5206, /* 1D5AA (120234) */ + 5234, /* 1D5A9 (120233) */ + 5235, /* 1D5AA (120234) */ 1741, /* 1D5AB (120235) */ 1760, /* 1D5AC (120236) */ 1743, /* 1D5AD (120237) */ - 5207, /* 1D5AE (120238) */ + 5236, /* 1D5AE (120238) */ 1745, /* 1D5AF (120239) */ 1746, /* 1D5B0 (120240) */ 1747, /* 1D5B1 (120241) */ - 5208, /* 1D5B2 (120242) */ - 5209, /* 1D5B3 (120243) */ - 5210, /* 1D5B4 (120244) */ - 5211, /* 1D5B5 (120245) */ - 5212, /* 1D5B6 (120246) */ - 5213, /* 1D5B7 (120247) */ - 5214, /* 1D5B8 (120248) */ + 5237, /* 1D5B2 (120242) */ + 5238, /* 1D5B3 (120243) */ + 5239, /* 1D5B4 (120244) */ + 5240, /* 1D5B5 (120245) */ + 5241, /* 1D5B6 (120246) */ + 5242, /* 1D5B7 (120247) */ + 5243, /* 1D5B8 (120248) */ 1751, /* 1D5B9 (120249) */ - 5243, /* 1D5BA (120250) */ - 5244, /* 1D5BB (120251) */ - 5245, /* 1D5BC (120252) */ + 5272, /* 1D5BA (120250) */ + 5273, /* 1D5BB (120251) */ + 5274, /* 1D5BC (120252) */ 1774, /* 1D5BD (120253) */ 1756, /* 1D5BE (120254) */ - 5246, /* 1D5BF (120255) */ + 5275, /* 1D5BF (120255) */ 1736, /* 1D5C0 (120256) */ 1738, /* 1D5C1 (120257) */ 1766, /* 1D5C2 (120258) */ 1775, /* 1D5C3 (120259) */ - 5247, /* 1D5C4 (120260) */ + 5276, /* 1D5C4 (120260) */ 1742, /* 1D5C5 (120261) */ - 5248, /* 1D5C6 (120262) */ - 5249, /* 1D5C7 (120263) */ + 5277, /* 1D5C6 (120262) */ + 5278, /* 1D5C7 (120263) */ 1761, /* 1D5C8 (120264) */ - 5250, /* 1D5C9 (120265) */ - 5251, /* 1D5CA (120266) */ - 5252, /* 1D5CB (120267) */ - 5253, /* 1D5CC (120268) */ - 5254, /* 1D5CD (120269) */ - 5255, /* 1D5CE (120270) */ - 5256, /* 1D5CF (120271) */ - 5257, /* 1D5D0 (120272) */ - 5258, /* 1D5D1 (120273) */ - 5259, /* 1D5D2 (120274) */ - 5260, /* 1D5D3 (120275) */ - 5203, /* 1D5D4 (120276) */ + 5279, /* 1D5C9 (120265) */ + 5280, /* 1D5CA (120266) */ + 5281, /* 1D5CB (120267) */ + 5282, /* 1D5CC (120268) */ + 5283, /* 1D5CD (120269) */ + 5284, /* 1D5CE (120270) */ + 5285, /* 1D5CF (120271) */ + 5286, /* 1D5D0 (120272) */ + 5287, /* 1D5D1 (120273) */ + 5288, /* 1D5D2 (120274) */ + 5289, /* 1D5D3 (120275) */ + 5232, /* 1D5D4 (120276) */ 1755, /* 1D5D5 (120277) */ 1730, /* 1D5D6 (120278) */ 1773, /* 1D5D7 (120279) */ 1757, /* 1D5D8 (120280) */ 1758, /* 1D5D9 (120281) */ - 5204, /* 1D5DA (120282) */ + 5233, /* 1D5DA (120282) */ 1737, /* 1D5DB (120283) */ 1740, /* 1D5DC (120284) */ - 5205, /* 1D5DD (120285) */ - 5206, /* 1D5DE (120286) */ + 5234, /* 1D5DD (120285) */ + 5235, /* 1D5DE (120286) */ 1741, /* 1D5DF (120287) */ 1760, /* 1D5E0 (120288) */ 1743, /* 1D5E1 (120289) */ - 5207, /* 1D5E2 (120290) */ + 5236, /* 1D5E2 (120290) */ 1745, /* 1D5E3 (120291) */ 1746, /* 1D5E4 (120292) */ 1747, /* 1D5E5 (120293) */ - 5208, /* 1D5E6 (120294) */ - 5209, /* 1D5E7 (120295) */ - 5210, /* 1D5E8 (120296) */ - 5211, /* 1D5E9 (120297) */ - 5212, /* 1D5EA (120298) */ - 5213, /* 1D5EB (120299) */ - 5214, /* 1D5EC (120300) */ + 5237, /* 1D5E6 (120294) */ + 5238, /* 1D5E7 (120295) */ + 5239, /* 1D5E8 (120296) */ + 5240, /* 1D5E9 (120297) */ + 5241, /* 1D5EA (120298) */ + 5242, /* 1D5EB (120299) */ + 5243, /* 1D5EC (120300) */ 1751, /* 1D5ED (120301) */ - 5243, /* 1D5EE (120302) */ - 5244, /* 1D5EF (120303) */ - 5245, /* 1D5F0 (120304) */ + 5272, /* 1D5EE (120302) */ + 5273, /* 1D5EF (120303) */ + 5274, /* 1D5F0 (120304) */ 1774, /* 1D5F1 (120305) */ 1756, /* 1D5F2 (120306) */ - 5246, /* 1D5F3 (120307) */ + 5275, /* 1D5F3 (120307) */ 1736, /* 1D5F4 (120308) */ 1738, /* 1D5F5 (120309) */ 1766, /* 1D5F6 (120310) */ 1775, /* 1D5F7 (120311) */ - 5247, /* 1D5F8 (120312) */ + 5276, /* 1D5F8 (120312) */ 1742, /* 1D5F9 (120313) */ - 5248, /* 1D5FA (120314) */ - 5249, /* 1D5FB (120315) */ + 5277, /* 1D5FA (120314) */ + 5278, /* 1D5FB (120315) */ 1761, /* 1D5FC (120316) */ - 5250, /* 1D5FD (120317) */ - 5251, /* 1D5FE (120318) */ - 5252, /* 1D5FF (120319) */ - 5253, /* 1D600 (120320) */ - 5254, /* 1D601 (120321) */ - 5255, /* 1D602 (120322) */ - 5256, /* 1D603 (120323) */ - 5257, /* 1D604 (120324) */ - 5258, /* 1D605 (120325) */ - 5259, /* 1D606 (120326) */ - 5260, /* 1D607 (120327) */ - 5203, /* 1D608 (120328) */ + 5279, /* 1D5FD (120317) */ + 5280, /* 1D5FE (120318) */ + 5281, /* 1D5FF (120319) */ + 5282, /* 1D600 (120320) */ + 5283, /* 1D601 (120321) */ + 5284, /* 1D602 (120322) */ + 5285, /* 1D603 (120323) */ + 5286, /* 1D604 (120324) */ + 5287, /* 1D605 (120325) */ + 5288, /* 1D606 (120326) */ + 5289, /* 1D607 (120327) */ + 5232, /* 1D608 (120328) */ 1755, /* 1D609 (120329) */ 1730, /* 1D60A (120330) */ 1773, /* 1D60B (120331) */ 1757, /* 1D60C (120332) */ 1758, /* 1D60D (120333) */ - 5204, /* 1D60E (120334) */ + 5233, /* 1D60E (120334) */ 1737, /* 1D60F (120335) */ 1740, /* 1D610 (120336) */ - 5205, /* 1D611 (120337) */ - 5206, /* 1D612 (120338) */ + 5234, /* 1D611 (120337) */ + 5235, /* 1D612 (120338) */ 1741, /* 1D613 (120339) */ 1760, /* 1D614 (120340) */ 1743, /* 1D615 (120341) */ - 5207, /* 1D616 (120342) */ + 5236, /* 1D616 (120342) */ 1745, /* 1D617 (120343) */ 1746, /* 1D618 (120344) */ 1747, /* 1D619 (120345) */ - 5208, /* 1D61A (120346) */ - 5209, /* 1D61B (120347) */ - 5210, /* 1D61C (120348) */ - 5211, /* 1D61D (120349) */ - 5212, /* 1D61E (120350) */ - 5213, /* 1D61F (120351) */ - 5214, /* 1D620 (120352) */ + 5237, /* 1D61A (120346) */ + 5238, /* 1D61B (120347) */ + 5239, /* 1D61C (120348) */ + 5240, /* 1D61D (120349) */ + 5241, /* 1D61E (120350) */ + 5242, /* 1D61F (120351) */ + 5243, /* 1D620 (120352) */ 1751, /* 1D621 (120353) */ - 5243, /* 1D622 (120354) */ - 5244, /* 1D623 (120355) */ - 5245, /* 1D624 (120356) */ + 5272, /* 1D622 (120354) */ + 5273, /* 1D623 (120355) */ + 5274, /* 1D624 (120356) */ 1774, /* 1D625 (120357) */ 1756, /* 1D626 (120358) */ - 5246, /* 1D627 (120359) */ + 5275, /* 1D627 (120359) */ 1736, /* 1D628 (120360) */ 1738, /* 1D629 (120361) */ 1766, /* 1D62A (120362) */ 1775, /* 1D62B (120363) */ - 5247, /* 1D62C (120364) */ + 5276, /* 1D62C (120364) */ 1742, /* 1D62D (120365) */ - 5248, /* 1D62E (120366) */ - 5249, /* 1D62F (120367) */ + 5277, /* 1D62E (120366) */ + 5278, /* 1D62F (120367) */ 1761, /* 1D630 (120368) */ - 5250, /* 1D631 (120369) */ - 5251, /* 1D632 (120370) */ - 5252, /* 1D633 (120371) */ - 5253, /* 1D634 (120372) */ - 5254, /* 1D635 (120373) */ - 5255, /* 1D636 (120374) */ - 5256, /* 1D637 (120375) */ - 5257, /* 1D638 (120376) */ - 5258, /* 1D639 (120377) */ - 5259, /* 1D63A (120378) */ - 5260, /* 1D63B (120379) */ - 5203, /* 1D63C (120380) */ + 5279, /* 1D631 (120369) */ + 5280, /* 1D632 (120370) */ + 5281, /* 1D633 (120371) */ + 5282, /* 1D634 (120372) */ + 5283, /* 1D635 (120373) */ + 5284, /* 1D636 (120374) */ + 5285, /* 1D637 (120375) */ + 5286, /* 1D638 (120376) */ + 5287, /* 1D639 (120377) */ + 5288, /* 1D63A (120378) */ + 5289, /* 1D63B (120379) */ + 5232, /* 1D63C (120380) */ 1755, /* 1D63D (120381) */ 1730, /* 1D63E (120382) */ 1773, /* 1D63F (120383) */ 1757, /* 1D640 (120384) */ 1758, /* 1D641 (120385) */ - 5204, /* 1D642 (120386) */ + 5233, /* 1D642 (120386) */ 1737, /* 1D643 (120387) */ 1740, /* 1D644 (120388) */ - 5205, /* 1D645 (120389) */ - 5206, /* 1D646 (120390) */ + 5234, /* 1D645 (120389) */ + 5235, /* 1D646 (120390) */ 1741, /* 1D647 (120391) */ 1760, /* 1D648 (120392) */ 1743, /* 1D649 (120393) */ - 5207, /* 1D64A (120394) */ + 5236, /* 1D64A (120394) */ 1745, /* 1D64B (120395) */ 1746, /* 1D64C (120396) */ 1747, /* 1D64D (120397) */ - 5208, /* 1D64E (120398) */ - 5209, /* 1D64F (120399) */ - 5210, /* 1D650 (120400) */ - 5211, /* 1D651 (120401) */ - 5212, /* 1D652 (120402) */ - 5213, /* 1D653 (120403) */ - 5214, /* 1D654 (120404) */ + 5237, /* 1D64E (120398) */ + 5238, /* 1D64F (120399) */ + 5239, /* 1D650 (120400) */ + 5240, /* 1D651 (120401) */ + 5241, /* 1D652 (120402) */ + 5242, /* 1D653 (120403) */ + 5243, /* 1D654 (120404) */ 1751, /* 1D655 (120405) */ - 5243, /* 1D656 (120406) */ - 5244, /* 1D657 (120407) */ - 5245, /* 1D658 (120408) */ + 5272, /* 1D656 (120406) */ + 5273, /* 1D657 (120407) */ + 5274, /* 1D658 (120408) */ 1774, /* 1D659 (120409) */ 1756, /* 1D65A (120410) */ - 5246, /* 1D65B (120411) */ + 5275, /* 1D65B (120411) */ 1736, /* 1D65C (120412) */ 1738, /* 1D65D (120413) */ 1766, /* 1D65E (120414) */ 1775, /* 1D65F (120415) */ - 5247, /* 1D660 (120416) */ + 5276, /* 1D660 (120416) */ 1742, /* 1D661 (120417) */ - 5248, /* 1D662 (120418) */ - 5249, /* 1D663 (120419) */ + 5277, /* 1D662 (120418) */ + 5278, /* 1D663 (120419) */ 1761, /* 1D664 (120420) */ - 5250, /* 1D665 (120421) */ - 5251, /* 1D666 (120422) */ - 5252, /* 1D667 (120423) */ - 5253, /* 1D668 (120424) */ - 5254, /* 1D669 (120425) */ - 5255, /* 1D66A (120426) */ - 5256, /* 1D66B (120427) */ - 5257, /* 1D66C (120428) */ - 5258, /* 1D66D (120429) */ - 5259, /* 1D66E (120430) */ - 5260, /* 1D66F (120431) */ - 5203, /* 1D670 (120432) */ + 5279, /* 1D665 (120421) */ + 5280, /* 1D666 (120422) */ + 5281, /* 1D667 (120423) */ + 5282, /* 1D668 (120424) */ + 5283, /* 1D669 (120425) */ + 5284, /* 1D66A (120426) */ + 5285, /* 1D66B (120427) */ + 5286, /* 1D66C (120428) */ + 5287, /* 1D66D (120429) */ + 5288, /* 1D66E (120430) */ + 5289, /* 1D66F (120431) */ + 5232, /* 1D670 (120432) */ 1755, /* 1D671 (120433) */ 1730, /* 1D672 (120434) */ 1773, /* 1D673 (120435) */ 1757, /* 1D674 (120436) */ 1758, /* 1D675 (120437) */ - 5204, /* 1D676 (120438) */ + 5233, /* 1D676 (120438) */ 1737, /* 1D677 (120439) */ 1740, /* 1D678 (120440) */ - 5205, /* 1D679 (120441) */ - 5206, /* 1D67A (120442) */ + 5234, /* 1D679 (120441) */ + 5235, /* 1D67A (120442) */ 1741, /* 1D67B (120443) */ 1760, /* 1D67C (120444) */ 1743, /* 1D67D (120445) */ - 5207, /* 1D67E (120446) */ + 5236, /* 1D67E (120446) */ 1745, /* 1D67F (120447) */ 1746, /* 1D680 (120448) */ 1747, /* 1D681 (120449) */ - 5208, /* 1D682 (120450) */ - 5209, /* 1D683 (120451) */ - 5210, /* 1D684 (120452) */ - 5211, /* 1D685 (120453) */ - 5212, /* 1D686 (120454) */ - 5213, /* 1D687 (120455) */ - 5214, /* 1D688 (120456) */ + 5237, /* 1D682 (120450) */ + 5238, /* 1D683 (120451) */ + 5239, /* 1D684 (120452) */ + 5240, /* 1D685 (120453) */ + 5241, /* 1D686 (120454) */ + 5242, /* 1D687 (120455) */ + 5243, /* 1D688 (120456) */ 1751, /* 1D689 (120457) */ - 5243, /* 1D68A (120458) */ - 5244, /* 1D68B (120459) */ - 5245, /* 1D68C (120460) */ + 5272, /* 1D68A (120458) */ + 5273, /* 1D68B (120459) */ + 5274, /* 1D68C (120460) */ 1774, /* 1D68D (120461) */ 1756, /* 1D68E (120462) */ - 5246, /* 1D68F (120463) */ + 5275, /* 1D68F (120463) */ 1736, /* 1D690 (120464) */ 1738, /* 1D691 (120465) */ 1766, /* 1D692 (120466) */ 1775, /* 1D693 (120467) */ - 5247, /* 1D694 (120468) */ + 5276, /* 1D694 (120468) */ 1742, /* 1D695 (120469) */ - 5248, /* 1D696 (120470) */ - 5249, /* 1D697 (120471) */ + 5277, /* 1D696 (120470) */ + 5278, /* 1D697 (120471) */ 1761, /* 1D698 (120472) */ - 5250, /* 1D699 (120473) */ - 5251, /* 1D69A (120474) */ - 5252, /* 1D69B (120475) */ - 5253, /* 1D69C (120476) */ - 5254, /* 1D69D (120477) */ - 5255, /* 1D69E (120478) */ - 5256, /* 1D69F (120479) */ - 5257, /* 1D6A0 (120480) */ - 5258, /* 1D6A1 (120481) */ - 5259, /* 1D6A2 (120482) */ - 5260, /* 1D6A3 (120483) */ - 5261, /* 1D6A4 (120484) */ - 5262, /* 1D6A5 (120485) */ + 5279, /* 1D699 (120473) */ + 5280, /* 1D69A (120474) */ + 5281, /* 1D69B (120475) */ + 5282, /* 1D69C (120476) */ + 5283, /* 1D69D (120477) */ + 5284, /* 1D69E (120478) */ + 5285, /* 1D69F (120479) */ + 5286, /* 1D6A0 (120480) */ + 5287, /* 1D6A1 (120481) */ + 5288, /* 1D6A2 (120482) */ + 5289, /* 1D6A3 (120483) */ + 5290, /* 1D6A4 (120484) */ + 5291, /* 1D6A5 (120485) */ 56, /* 1D6A6 (120486) */ 56, /* 1D6A7 (120487) */ - 5263, /* 1D6A8 (120488) */ - 5264, /* 1D6A9 (120489) */ + 5292, /* 1D6A8 (120488) */ + 5293, /* 1D6A9 (120489) */ 1770, /* 1D6AA (120490) */ - 5265, /* 1D6AB (120491) */ - 5266, /* 1D6AC (120492) */ - 5267, /* 1D6AD (120493) */ - 5268, /* 1D6AE (120494) */ - 5269, /* 1D6AF (120495) */ - 5270, /* 1D6B0 (120496) */ - 5271, /* 1D6B1 (120497) */ - 5272, /* 1D6B2 (120498) */ - 5273, /* 1D6B3 (120499) */ - 5274, /* 1D6B4 (120500) */ - 5275, /* 1D6B5 (120501) */ - 5276, /* 1D6B6 (120502) */ + 5294, /* 1D6AB (120491) */ + 5295, /* 1D6AC (120492) */ + 5296, /* 1D6AD (120493) */ + 5297, /* 1D6AE (120494) */ + 5298, /* 1D6AF (120495) */ + 5299, /* 1D6B0 (120496) */ + 5300, /* 1D6B1 (120497) */ + 5301, /* 1D6B2 (120498) */ + 5302, /* 1D6B3 (120499) */ + 5303, /* 1D6B4 (120500) */ + 5304, /* 1D6B5 (120501) */ + 5305, /* 1D6B6 (120502) */ 1771, /* 1D6B7 (120503) */ - 5277, /* 1D6B8 (120504) */ - 5278, /* 1D6B9 (120505) */ - 5279, /* 1D6BA (120506) */ - 5280, /* 1D6BB (120507) */ - 5281, /* 1D6BC (120508) */ - 5282, /* 1D6BD (120509) */ - 5283, /* 1D6BE (120510) */ - 5284, /* 1D6BF (120511) */ - 5285, /* 1D6C0 (120512) */ - 5286, /* 1D6C1 (120513) */ - 5287, /* 1D6C2 (120514) */ - 5288, /* 1D6C3 (120515) */ + 5306, /* 1D6B8 (120504) */ + 5307, /* 1D6B9 (120505) */ + 5308, /* 1D6BA (120506) */ + 5309, /* 1D6BB (120507) */ + 5310, /* 1D6BC (120508) */ + 5311, /* 1D6BD (120509) */ + 5312, /* 1D6BE (120510) */ + 5313, /* 1D6BF (120511) */ + 5314, /* 1D6C0 (120512) */ + 5315, /* 1D6C1 (120513) */ + 5316, /* 1D6C2 (120514) */ + 5317, /* 1D6C3 (120515) */ 1769, /* 1D6C4 (120516) */ - 5289, /* 1D6C5 (120517) */ - 5290, /* 1D6C6 (120518) */ - 5291, /* 1D6C7 (120519) */ - 5292, /* 1D6C8 (120520) */ - 5293, /* 1D6C9 (120521) */ - 5294, /* 1D6CA (120522) */ - 5295, /* 1D6CB (120523) */ - 5296, /* 1D6CC (120524) */ - 5297, /* 1D6CD (120525) */ - 5298, /* 1D6CE (120526) */ - 5299, /* 1D6CF (120527) */ - 5300, /* 1D6D0 (120528) */ + 5318, /* 1D6C5 (120517) */ + 5319, /* 1D6C6 (120518) */ + 5320, /* 1D6C7 (120519) */ + 5321, /* 1D6C8 (120520) */ + 5322, /* 1D6C9 (120521) */ + 5323, /* 1D6CA (120522) */ + 5324, /* 1D6CB (120523) */ + 5325, /* 1D6CC (120524) */ + 5326, /* 1D6CD (120525) */ + 5327, /* 1D6CE (120526) */ + 5328, /* 1D6CF (120527) */ + 5329, /* 1D6D0 (120528) */ 1768, /* 1D6D1 (120529) */ - 5301, /* 1D6D2 (120530) */ - 5302, /* 1D6D3 (120531) */ - 5303, /* 1D6D4 (120532) */ - 5304, /* 1D6D5 (120533) */ - 5305, /* 1D6D6 (120534) */ - 5306, /* 1D6D7 (120535) */ - 5307, /* 1D6D8 (120536) */ - 5308, /* 1D6D9 (120537) */ - 5309, /* 1D6DA (120538) */ - 5310, /* 1D6DB (120539) */ - 5311, /* 1D6DC (120540) */ - 5312, /* 1D6DD (120541) */ - 5313, /* 1D6DE (120542) */ - 5314, /* 1D6DF (120543) */ - 5315, /* 1D6E0 (120544) */ - 5316, /* 1D6E1 (120545) */ - 5263, /* 1D6E2 (120546) */ - 5264, /* 1D6E3 (120547) */ + 5330, /* 1D6D2 (120530) */ + 5331, /* 1D6D3 (120531) */ + 5332, /* 1D6D4 (120532) */ + 5333, /* 1D6D5 (120533) */ + 5334, /* 1D6D6 (120534) */ + 5335, /* 1D6D7 (120535) */ + 5336, /* 1D6D8 (120536) */ + 5337, /* 1D6D9 (120537) */ + 5338, /* 1D6DA (120538) */ + 5339, /* 1D6DB (120539) */ + 5340, /* 1D6DC (120540) */ + 5341, /* 1D6DD (120541) */ + 5342, /* 1D6DE (120542) */ + 5343, /* 1D6DF (120543) */ + 5344, /* 1D6E0 (120544) */ + 5345, /* 1D6E1 (120545) */ + 5292, /* 1D6E2 (120546) */ + 5293, /* 1D6E3 (120547) */ 1770, /* 1D6E4 (120548) */ - 5265, /* 1D6E5 (120549) */ - 5266, /* 1D6E6 (120550) */ - 5267, /* 1D6E7 (120551) */ - 5268, /* 1D6E8 (120552) */ - 5269, /* 1D6E9 (120553) */ - 5270, /* 1D6EA (120554) */ - 5271, /* 1D6EB (120555) */ - 5272, /* 1D6EC (120556) */ - 5273, /* 1D6ED (120557) */ - 5274, /* 1D6EE (120558) */ - 5275, /* 1D6EF (120559) */ - 5276, /* 1D6F0 (120560) */ + 5294, /* 1D6E5 (120549) */ + 5295, /* 1D6E6 (120550) */ + 5296, /* 1D6E7 (120551) */ + 5297, /* 1D6E8 (120552) */ + 5298, /* 1D6E9 (120553) */ + 5299, /* 1D6EA (120554) */ + 5300, /* 1D6EB (120555) */ + 5301, /* 1D6EC (120556) */ + 5302, /* 1D6ED (120557) */ + 5303, /* 1D6EE (120558) */ + 5304, /* 1D6EF (120559) */ + 5305, /* 1D6F0 (120560) */ 1771, /* 1D6F1 (120561) */ - 5277, /* 1D6F2 (120562) */ - 5317, /* 1D6F3 (120563) */ - 5279, /* 1D6F4 (120564) */ - 5280, /* 1D6F5 (120565) */ - 5281, /* 1D6F6 (120566) */ - 5282, /* 1D6F7 (120567) */ - 5283, /* 1D6F8 (120568) */ - 5284, /* 1D6F9 (120569) */ - 5285, /* 1D6FA (120570) */ - 5286, /* 1D6FB (120571) */ - 5287, /* 1D6FC (120572) */ - 5288, /* 1D6FD (120573) */ + 5306, /* 1D6F2 (120562) */ + 5346, /* 1D6F3 (120563) */ + 5308, /* 1D6F4 (120564) */ + 5309, /* 1D6F5 (120565) */ + 5310, /* 1D6F6 (120566) */ + 5311, /* 1D6F7 (120567) */ + 5312, /* 1D6F8 (120568) */ + 5313, /* 1D6F9 (120569) */ + 5314, /* 1D6FA (120570) */ + 5315, /* 1D6FB (120571) */ + 5316, /* 1D6FC (120572) */ + 5317, /* 1D6FD (120573) */ 1769, /* 1D6FE (120574) */ - 5289, /* 1D6FF (120575) */ - 5290, /* 1D700 (120576) */ - 5291, /* 1D701 (120577) */ - 5292, /* 1D702 (120578) */ - 5293, /* 1D703 (120579) */ - 5294, /* 1D704 (120580) */ - 5295, /* 1D705 (120581) */ - 5296, /* 1D706 (120582) */ - 5297, /* 1D707 (120583) */ - 5298, /* 1D708 (120584) */ - 5299, /* 1D709 (120585) */ - 5300, /* 1D70A (120586) */ + 5318, /* 1D6FF (120575) */ + 5319, /* 1D700 (120576) */ + 5320, /* 1D701 (120577) */ + 5321, /* 1D702 (120578) */ + 5322, /* 1D703 (120579) */ + 5323, /* 1D704 (120580) */ + 5324, /* 1D705 (120581) */ + 5325, /* 1D706 (120582) */ + 5326, /* 1D707 (120583) */ + 5327, /* 1D708 (120584) */ + 5328, /* 1D709 (120585) */ + 5329, /* 1D70A (120586) */ 1768, /* 1D70B (120587) */ - 5301, /* 1D70C (120588) */ - 5302, /* 1D70D (120589) */ - 5303, /* 1D70E (120590) */ - 5304, /* 1D70F (120591) */ - 5305, /* 1D710 (120592) */ - 5306, /* 1D711 (120593) */ - 5307, /* 1D712 (120594) */ - 5308, /* 1D713 (120595) */ - 5309, /* 1D714 (120596) */ - 5310, /* 1D715 (120597) */ - 5318, /* 1D716 (120598) */ - 5319, /* 1D717 (120599) */ - 5320, /* 1D718 (120600) */ - 5321, /* 1D719 (120601) */ - 5322, /* 1D71A (120602) */ - 5323, /* 1D71B (120603) */ - 5263, /* 1D71C (120604) */ - 5264, /* 1D71D (120605) */ + 5330, /* 1D70C (120588) */ + 5331, /* 1D70D (120589) */ + 5332, /* 1D70E (120590) */ + 5333, /* 1D70F (120591) */ + 5334, /* 1D710 (120592) */ + 5335, /* 1D711 (120593) */ + 5336, /* 1D712 (120594) */ + 5337, /* 1D713 (120595) */ + 5338, /* 1D714 (120596) */ + 5339, /* 1D715 (120597) */ + 5347, /* 1D716 (120598) */ + 5348, /* 1D717 (120599) */ + 5349, /* 1D718 (120600) */ + 5350, /* 1D719 (120601) */ + 5351, /* 1D71A (120602) */ + 5352, /* 1D71B (120603) */ + 5292, /* 1D71C (120604) */ + 5293, /* 1D71D (120605) */ 1770, /* 1D71E (120606) */ - 5265, /* 1D71F (120607) */ - 5266, /* 1D720 (120608) */ - 5267, /* 1D721 (120609) */ - 5268, /* 1D722 (120610) */ - 5269, /* 1D723 (120611) */ - 5270, /* 1D724 (120612) */ - 5271, /* 1D725 (120613) */ - 5272, /* 1D726 (120614) */ - 5273, /* 1D727 (120615) */ - 5274, /* 1D728 (120616) */ - 5275, /* 1D729 (120617) */ - 5276, /* 1D72A (120618) */ + 5294, /* 1D71F (120607) */ + 5295, /* 1D720 (120608) */ + 5296, /* 1D721 (120609) */ + 5297, /* 1D722 (120610) */ + 5298, /* 1D723 (120611) */ + 5299, /* 1D724 (120612) */ + 5300, /* 1D725 (120613) */ + 5301, /* 1D726 (120614) */ + 5302, /* 1D727 (120615) */ + 5303, /* 1D728 (120616) */ + 5304, /* 1D729 (120617) */ + 5305, /* 1D72A (120618) */ 1771, /* 1D72B (120619) */ - 5277, /* 1D72C (120620) */ - 5324, /* 1D72D (120621) */ - 5279, /* 1D72E (120622) */ - 5280, /* 1D72F (120623) */ - 5281, /* 1D730 (120624) */ - 5282, /* 1D731 (120625) */ - 5283, /* 1D732 (120626) */ - 5284, /* 1D733 (120627) */ - 5285, /* 1D734 (120628) */ - 5286, /* 1D735 (120629) */ - 5287, /* 1D736 (120630) */ - 5288, /* 1D737 (120631) */ + 5306, /* 1D72C (120620) */ + 5353, /* 1D72D (120621) */ + 5308, /* 1D72E (120622) */ + 5309, /* 1D72F (120623) */ + 5310, /* 1D730 (120624) */ + 5311, /* 1D731 (120625) */ + 5312, /* 1D732 (120626) */ + 5313, /* 1D733 (120627) */ + 5314, /* 1D734 (120628) */ + 5315, /* 1D735 (120629) */ + 5316, /* 1D736 (120630) */ + 5317, /* 1D737 (120631) */ 1769, /* 1D738 (120632) */ - 5289, /* 1D739 (120633) */ - 5290, /* 1D73A (120634) */ - 5291, /* 1D73B (120635) */ - 5292, /* 1D73C (120636) */ - 5293, /* 1D73D (120637) */ - 5294, /* 1D73E (120638) */ - 5295, /* 1D73F (120639) */ - 5296, /* 1D740 (120640) */ - 5297, /* 1D741 (120641) */ - 5298, /* 1D742 (120642) */ - 5299, /* 1D743 (120643) */ - 5300, /* 1D744 (120644) */ + 5318, /* 1D739 (120633) */ + 5319, /* 1D73A (120634) */ + 5320, /* 1D73B (120635) */ + 5321, /* 1D73C (120636) */ + 5322, /* 1D73D (120637) */ + 5323, /* 1D73E (120638) */ + 5324, /* 1D73F (120639) */ + 5325, /* 1D740 (120640) */ + 5326, /* 1D741 (120641) */ + 5327, /* 1D742 (120642) */ + 5328, /* 1D743 (120643) */ + 5329, /* 1D744 (120644) */ 1768, /* 1D745 (120645) */ - 5301, /* 1D746 (120646) */ - 5302, /* 1D747 (120647) */ - 5303, /* 1D748 (120648) */ - 5304, /* 1D749 (120649) */ - 5305, /* 1D74A (120650) */ - 5306, /* 1D74B (120651) */ - 5307, /* 1D74C (120652) */ - 5308, /* 1D74D (120653) */ - 5309, /* 1D74E (120654) */ - 5310, /* 1D74F (120655) */ - 5325, /* 1D750 (120656) */ - 5326, /* 1D751 (120657) */ - 5327, /* 1D752 (120658) */ - 5328, /* 1D753 (120659) */ - 5329, /* 1D754 (120660) */ - 5330, /* 1D755 (120661) */ - 5263, /* 1D756 (120662) */ - 5264, /* 1D757 (120663) */ + 5330, /* 1D746 (120646) */ + 5331, /* 1D747 (120647) */ + 5332, /* 1D748 (120648) */ + 5333, /* 1D749 (120649) */ + 5334, /* 1D74A (120650) */ + 5335, /* 1D74B (120651) */ + 5336, /* 1D74C (120652) */ + 5337, /* 1D74D (120653) */ + 5338, /* 1D74E (120654) */ + 5339, /* 1D74F (120655) */ + 5354, /* 1D750 (120656) */ + 5355, /* 1D751 (120657) */ + 5356, /* 1D752 (120658) */ + 5357, /* 1D753 (120659) */ + 5358, /* 1D754 (120660) */ + 5359, /* 1D755 (120661) */ + 5292, /* 1D756 (120662) */ + 5293, /* 1D757 (120663) */ 1770, /* 1D758 (120664) */ - 5265, /* 1D759 (120665) */ - 5266, /* 1D75A (120666) */ - 5267, /* 1D75B (120667) */ - 5268, /* 1D75C (120668) */ - 5269, /* 1D75D (120669) */ - 5270, /* 1D75E (120670) */ - 5271, /* 1D75F (120671) */ - 5272, /* 1D760 (120672) */ - 5273, /* 1D761 (120673) */ - 5274, /* 1D762 (120674) */ - 5275, /* 1D763 (120675) */ - 5276, /* 1D764 (120676) */ + 5294, /* 1D759 (120665) */ + 5295, /* 1D75A (120666) */ + 5296, /* 1D75B (120667) */ + 5297, /* 1D75C (120668) */ + 5298, /* 1D75D (120669) */ + 5299, /* 1D75E (120670) */ + 5300, /* 1D75F (120671) */ + 5301, /* 1D760 (120672) */ + 5302, /* 1D761 (120673) */ + 5303, /* 1D762 (120674) */ + 5304, /* 1D763 (120675) */ + 5305, /* 1D764 (120676) */ 1771, /* 1D765 (120677) */ - 5277, /* 1D766 (120678) */ - 5331, /* 1D767 (120679) */ - 5279, /* 1D768 (120680) */ - 5280, /* 1D769 (120681) */ - 5281, /* 1D76A (120682) */ - 5282, /* 1D76B (120683) */ - 5283, /* 1D76C (120684) */ - 5284, /* 1D76D (120685) */ - 5285, /* 1D76E (120686) */ - 5286, /* 1D76F (120687) */ - 5287, /* 1D770 (120688) */ - 5288, /* 1D771 (120689) */ + 5306, /* 1D766 (120678) */ + 5360, /* 1D767 (120679) */ + 5308, /* 1D768 (120680) */ + 5309, /* 1D769 (120681) */ + 5310, /* 1D76A (120682) */ + 5311, /* 1D76B (120683) */ + 5312, /* 1D76C (120684) */ + 5313, /* 1D76D (120685) */ + 5314, /* 1D76E (120686) */ + 5315, /* 1D76F (120687) */ + 5316, /* 1D770 (120688) */ + 5317, /* 1D771 (120689) */ 1769, /* 1D772 (120690) */ - 5289, /* 1D773 (120691) */ - 5290, /* 1D774 (120692) */ - 5291, /* 1D775 (120693) */ - 5292, /* 1D776 (120694) */ - 5293, /* 1D777 (120695) */ - 5294, /* 1D778 (120696) */ - 5295, /* 1D779 (120697) */ - 5296, /* 1D77A (120698) */ - 5297, /* 1D77B (120699) */ - 5298, /* 1D77C (120700) */ - 5299, /* 1D77D (120701) */ - 5300, /* 1D77E (120702) */ + 5318, /* 1D773 (120691) */ + 5319, /* 1D774 (120692) */ + 5320, /* 1D775 (120693) */ + 5321, /* 1D776 (120694) */ + 5322, /* 1D777 (120695) */ + 5323, /* 1D778 (120696) */ + 5324, /* 1D779 (120697) */ + 5325, /* 1D77A (120698) */ + 5326, /* 1D77B (120699) */ + 5327, /* 1D77C (120700) */ + 5328, /* 1D77D (120701) */ + 5329, /* 1D77E (120702) */ 1768, /* 1D77F (120703) */ - 5301, /* 1D780 (120704) */ - 5302, /* 1D781 (120705) */ - 5303, /* 1D782 (120706) */ - 5304, /* 1D783 (120707) */ - 5305, /* 1D784 (120708) */ - 5306, /* 1D785 (120709) */ - 5307, /* 1D786 (120710) */ - 5308, /* 1D787 (120711) */ - 5309, /* 1D788 (120712) */ - 5310, /* 1D789 (120713) */ - 5332, /* 1D78A (120714) */ - 5333, /* 1D78B (120715) */ - 5334, /* 1D78C (120716) */ - 5335, /* 1D78D (120717) */ - 5336, /* 1D78E (120718) */ - 5337, /* 1D78F (120719) */ - 5263, /* 1D790 (120720) */ - 5264, /* 1D791 (120721) */ + 5330, /* 1D780 (120704) */ + 5331, /* 1D781 (120705) */ + 5332, /* 1D782 (120706) */ + 5333, /* 1D783 (120707) */ + 5334, /* 1D784 (120708) */ + 5335, /* 1D785 (120709) */ + 5336, /* 1D786 (120710) */ + 5337, /* 1D787 (120711) */ + 5338, /* 1D788 (120712) */ + 5339, /* 1D789 (120713) */ + 5361, /* 1D78A (120714) */ + 5362, /* 1D78B (120715) */ + 5363, /* 1D78C (120716) */ + 5364, /* 1D78D (120717) */ + 5365, /* 1D78E (120718) */ + 5366, /* 1D78F (120719) */ + 5292, /* 1D790 (120720) */ + 5293, /* 1D791 (120721) */ 1770, /* 1D792 (120722) */ - 5265, /* 1D793 (120723) */ - 5266, /* 1D794 (120724) */ - 5267, /* 1D795 (120725) */ - 5268, /* 1D796 (120726) */ - 5269, /* 1D797 (120727) */ - 5270, /* 1D798 (120728) */ - 5271, /* 1D799 (120729) */ - 5272, /* 1D79A (120730) */ - 5273, /* 1D79B (120731) */ - 5274, /* 1D79C (120732) */ - 5275, /* 1D79D (120733) */ - 5276, /* 1D79E (120734) */ + 5294, /* 1D793 (120723) */ + 5295, /* 1D794 (120724) */ + 5296, /* 1D795 (120725) */ + 5297, /* 1D796 (120726) */ + 5298, /* 1D797 (120727) */ + 5299, /* 1D798 (120728) */ + 5300, /* 1D799 (120729) */ + 5301, /* 1D79A (120730) */ + 5302, /* 1D79B (120731) */ + 5303, /* 1D79C (120732) */ + 5304, /* 1D79D (120733) */ + 5305, /* 1D79E (120734) */ 1771, /* 1D79F (120735) */ - 5277, /* 1D7A0 (120736) */ - 5338, /* 1D7A1 (120737) */ - 5279, /* 1D7A2 (120738) */ - 5280, /* 1D7A3 (120739) */ - 5281, /* 1D7A4 (120740) */ - 5282, /* 1D7A5 (120741) */ - 5283, /* 1D7A6 (120742) */ - 5284, /* 1D7A7 (120743) */ - 5285, /* 1D7A8 (120744) */ - 5286, /* 1D7A9 (120745) */ - 5287, /* 1D7AA (120746) */ - 5288, /* 1D7AB (120747) */ + 5306, /* 1D7A0 (120736) */ + 5367, /* 1D7A1 (120737) */ + 5308, /* 1D7A2 (120738) */ + 5309, /* 1D7A3 (120739) */ + 5310, /* 1D7A4 (120740) */ + 5311, /* 1D7A5 (120741) */ + 5312, /* 1D7A6 (120742) */ + 5313, /* 1D7A7 (120743) */ + 5314, /* 1D7A8 (120744) */ + 5315, /* 1D7A9 (120745) */ + 5316, /* 1D7AA (120746) */ + 5317, /* 1D7AB (120747) */ 1769, /* 1D7AC (120748) */ - 5289, /* 1D7AD (120749) */ - 5290, /* 1D7AE (120750) */ - 5291, /* 1D7AF (120751) */ - 5292, /* 1D7B0 (120752) */ - 5293, /* 1D7B1 (120753) */ - 5294, /* 1D7B2 (120754) */ - 5295, /* 1D7B3 (120755) */ - 5296, /* 1D7B4 (120756) */ - 5297, /* 1D7B5 (120757) */ - 5298, /* 1D7B6 (120758) */ - 5299, /* 1D7B7 (120759) */ - 5300, /* 1D7B8 (120760) */ + 5318, /* 1D7AD (120749) */ + 5319, /* 1D7AE (120750) */ + 5320, /* 1D7AF (120751) */ + 5321, /* 1D7B0 (120752) */ + 5322, /* 1D7B1 (120753) */ + 5323, /* 1D7B2 (120754) */ + 5324, /* 1D7B3 (120755) */ + 5325, /* 1D7B4 (120756) */ + 5326, /* 1D7B5 (120757) */ + 5327, /* 1D7B6 (120758) */ + 5328, /* 1D7B7 (120759) */ + 5329, /* 1D7B8 (120760) */ 1768, /* 1D7B9 (120761) */ - 5301, /* 1D7BA (120762) */ - 5302, /* 1D7BB (120763) */ - 5303, /* 1D7BC (120764) */ - 5304, /* 1D7BD (120765) */ - 5305, /* 1D7BE (120766) */ - 5306, /* 1D7BF (120767) */ - 5307, /* 1D7C0 (120768) */ - 5308, /* 1D7C1 (120769) */ - 5309, /* 1D7C2 (120770) */ - 5310, /* 1D7C3 (120771) */ - 5339, /* 1D7C4 (120772) */ - 5340, /* 1D7C5 (120773) */ - 5341, /* 1D7C6 (120774) */ - 5342, /* 1D7C7 (120775) */ - 5343, /* 1D7C8 (120776) */ - 5344, /* 1D7C9 (120777) */ - 5345, /* 1D7CA (120778) */ - 5346, /* 1D7CB (120779) */ + 5330, /* 1D7BA (120762) */ + 5331, /* 1D7BB (120763) */ + 5332, /* 1D7BC (120764) */ + 5333, /* 1D7BD (120765) */ + 5334, /* 1D7BE (120766) */ + 5335, /* 1D7BF (120767) */ + 5336, /* 1D7C0 (120768) */ + 5337, /* 1D7C1 (120769) */ + 5338, /* 1D7C2 (120770) */ + 5339, /* 1D7C3 (120771) */ + 5368, /* 1D7C4 (120772) */ + 5369, /* 1D7C5 (120773) */ + 5370, /* 1D7C6 (120774) */ + 5371, /* 1D7C7 (120775) */ + 5372, /* 1D7C8 (120776) */ + 5373, /* 1D7C9 (120777) */ + 5374, /* 1D7CA (120778) */ + 5375, /* 1D7CB (120779) */ 56, /* 1D7CC (120780) */ 56, /* 1D7CD (120781) */ - 5215, /* 1D7CE (120782) */ - 5216, /* 1D7CF (120783) */ - 5217, /* 1D7D0 (120784) */ - 5218, /* 1D7D1 (120785) */ - 5219, /* 1D7D2 (120786) */ - 5220, /* 1D7D3 (120787) */ - 5221, /* 1D7D4 (120788) */ - 5222, /* 1D7D5 (120789) */ - 5223, /* 1D7D6 (120790) */ - 5224, /* 1D7D7 (120791) */ - 5215, /* 1D7D8 (120792) */ - 5216, /* 1D7D9 (120793) */ - 5217, /* 1D7DA (120794) */ - 5218, /* 1D7DB (120795) */ - 5219, /* 1D7DC (120796) */ - 5220, /* 1D7DD (120797) */ - 5221, /* 1D7DE (120798) */ - 5222, /* 1D7DF (120799) */ - 5223, /* 1D7E0 (120800) */ - 5224, /* 1D7E1 (120801) */ - 5215, /* 1D7E2 (120802) */ - 5216, /* 1D7E3 (120803) */ - 5217, /* 1D7E4 (120804) */ - 5218, /* 1D7E5 (120805) */ - 5219, /* 1D7E6 (120806) */ - 5220, /* 1D7E7 (120807) */ - 5221, /* 1D7E8 (120808) */ - 5222, /* 1D7E9 (120809) */ - 5223, /* 1D7EA (120810) */ - 5224, /* 1D7EB (120811) */ - 5215, /* 1D7EC (120812) */ - 5216, /* 1D7ED (120813) */ - 5217, /* 1D7EE (120814) */ - 5218, /* 1D7EF (120815) */ - 5219, /* 1D7F0 (120816) */ - 5220, /* 1D7F1 (120817) */ - 5221, /* 1D7F2 (120818) */ - 5222, /* 1D7F3 (120819) */ - 5223, /* 1D7F4 (120820) */ - 5224, /* 1D7F5 (120821) */ - 5215, /* 1D7F6 (120822) */ - 5216, /* 1D7F7 (120823) */ - 5217, /* 1D7F8 (120824) */ - 5218, /* 1D7F9 (120825) */ - 5219, /* 1D7FA (120826) */ - 5220, /* 1D7FB (120827) */ - 5221, /* 1D7FC (120828) */ - 5222, /* 1D7FD (120829) */ - 5223, /* 1D7FE (120830) */ - 5224, /* 1D7FF (120831) */ + 5244, /* 1D7CE (120782) */ + 5245, /* 1D7CF (120783) */ + 5246, /* 1D7D0 (120784) */ + 5247, /* 1D7D1 (120785) */ + 5248, /* 1D7D2 (120786) */ + 5249, /* 1D7D3 (120787) */ + 5250, /* 1D7D4 (120788) */ + 5251, /* 1D7D5 (120789) */ + 5252, /* 1D7D6 (120790) */ + 5253, /* 1D7D7 (120791) */ + 5244, /* 1D7D8 (120792) */ + 5245, /* 1D7D9 (120793) */ + 5246, /* 1D7DA (120794) */ + 5247, /* 1D7DB (120795) */ + 5248, /* 1D7DC (120796) */ + 5249, /* 1D7DD (120797) */ + 5250, /* 1D7DE (120798) */ + 5251, /* 1D7DF (120799) */ + 5252, /* 1D7E0 (120800) */ + 5253, /* 1D7E1 (120801) */ + 5244, /* 1D7E2 (120802) */ + 5245, /* 1D7E3 (120803) */ + 5246, /* 1D7E4 (120804) */ + 5247, /* 1D7E5 (120805) */ + 5248, /* 1D7E6 (120806) */ + 5249, /* 1D7E7 (120807) */ + 5250, /* 1D7E8 (120808) */ + 5251, /* 1D7E9 (120809) */ + 5252, /* 1D7EA (120810) */ + 5253, /* 1D7EB (120811) */ + 5244, /* 1D7EC (120812) */ + 5245, /* 1D7ED (120813) */ + 5246, /* 1D7EE (120814) */ + 5247, /* 1D7EF (120815) */ + 5248, /* 1D7F0 (120816) */ + 5249, /* 1D7F1 (120817) */ + 5250, /* 1D7F2 (120818) */ + 5251, /* 1D7F3 (120819) */ + 5252, /* 1D7F4 (120820) */ + 5253, /* 1D7F5 (120821) */ + 5244, /* 1D7F6 (120822) */ + 5245, /* 1D7F7 (120823) */ + 5246, /* 1D7F8 (120824) */ + 5247, /* 1D7F9 (120825) */ + 5248, /* 1D7FA (120826) */ + 5249, /* 1D7FB (120827) */ + 5250, /* 1D7FC (120828) */ + 5251, /* 1D7FD (120829) */ + 5252, /* 1D7FE (120830) */ + 5253, /* 1D7FF (120831) */ 1, /* 1D800 (120832) */ 1, /* 1D801 (120833) */ 1, /* 1D802 (120834) */ @@ -100790,68 +101024,68 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E02D (122925) */ 56, /* 1E02E (122926) */ 56, /* 1E02F (122927) */ - 5347, /* 1E030 (122928) */ - 5348, /* 1E031 (122929) */ - 5349, /* 1E032 (122930) */ - 5350, /* 1E033 (122931) */ - 5351, /* 1E034 (122932) */ - 5352, /* 1E035 (122933) */ - 5353, /* 1E036 (122934) */ - 5354, /* 1E037 (122935) */ - 5355, /* 1E038 (122936) */ - 5356, /* 1E039 (122937) */ - 5357, /* 1E03A (122938) */ - 5358, /* 1E03B (122939) */ - 5359, /* 1E03C (122940) */ - 5360, /* 1E03D (122941) */ - 5361, /* 1E03E (122942) */ - 5362, /* 1E03F (122943) */ - 5363, /* 1E040 (122944) */ - 5364, /* 1E041 (122945) */ - 5365, /* 1E042 (122946) */ - 5366, /* 1E043 (122947) */ - 5367, /* 1E044 (122948) */ - 5368, /* 1E045 (122949) */ - 5369, /* 1E046 (122950) */ - 5370, /* 1E047 (122951) */ - 5371, /* 1E048 (122952) */ - 5372, /* 1E049 (122953) */ - 5373, /* 1E04A (122954) */ - 5374, /* 1E04B (122955) */ - 5375, /* 1E04C (122956) */ - 5376, /* 1E04D (122957) */ - 5377, /* 1E04E (122958) */ - 5378, /* 1E04F (122959) */ - 5379, /* 1E050 (122960) */ - 5380, /* 1E051 (122961) */ - 5381, /* 1E052 (122962) */ - 5382, /* 1E053 (122963) */ - 5383, /* 1E054 (122964) */ - 5384, /* 1E055 (122965) */ - 5385, /* 1E056 (122966) */ - 5386, /* 1E057 (122967) */ - 5387, /* 1E058 (122968) */ - 5388, /* 1E059 (122969) */ - 5389, /* 1E05A (122970) */ - 5390, /* 1E05B (122971) */ - 5391, /* 1E05C (122972) */ - 5392, /* 1E05D (122973) */ - 5393, /* 1E05E (122974) */ - 5394, /* 1E05F (122975) */ - 5395, /* 1E060 (122976) */ - 5396, /* 1E061 (122977) */ - 5397, /* 1E062 (122978) */ - 5398, /* 1E063 (122979) */ - 5399, /* 1E064 (122980) */ - 5400, /* 1E065 (122981) */ - 5401, /* 1E066 (122982) */ - 5402, /* 1E067 (122983) */ - 5403, /* 1E068 (122984) */ - 5404, /* 1E069 (122985) */ - 5405, /* 1E06A (122986) */ - 5406, /* 1E06B (122987) */ - 5407, /* 1E06C (122988) */ - 5408, /* 1E06D (122989) */ + 5376, /* 1E030 (122928) */ + 5377, /* 1E031 (122929) */ + 5378, /* 1E032 (122930) */ + 5379, /* 1E033 (122931) */ + 5380, /* 1E034 (122932) */ + 5381, /* 1E035 (122933) */ + 5382, /* 1E036 (122934) */ + 5383, /* 1E037 (122935) */ + 5384, /* 1E038 (122936) */ + 5385, /* 1E039 (122937) */ + 5386, /* 1E03A (122938) */ + 5387, /* 1E03B (122939) */ + 5388, /* 1E03C (122940) */ + 5389, /* 1E03D (122941) */ + 5390, /* 1E03E (122942) */ + 5391, /* 1E03F (122943) */ + 5392, /* 1E040 (122944) */ + 5393, /* 1E041 (122945) */ + 5394, /* 1E042 (122946) */ + 5395, /* 1E043 (122947) */ + 5396, /* 1E044 (122948) */ + 5397, /* 1E045 (122949) */ + 5398, /* 1E046 (122950) */ + 5399, /* 1E047 (122951) */ + 5400, /* 1E048 (122952) */ + 5401, /* 1E049 (122953) */ + 5402, /* 1E04A (122954) */ + 5403, /* 1E04B (122955) */ + 5404, /* 1E04C (122956) */ + 5405, /* 1E04D (122957) */ + 5406, /* 1E04E (122958) */ + 5407, /* 1E04F (122959) */ + 5408, /* 1E050 (122960) */ + 5409, /* 1E051 (122961) */ + 5410, /* 1E052 (122962) */ + 5411, /* 1E053 (122963) */ + 5412, /* 1E054 (122964) */ + 5413, /* 1E055 (122965) */ + 5414, /* 1E056 (122966) */ + 5415, /* 1E057 (122967) */ + 5416, /* 1E058 (122968) */ + 5417, /* 1E059 (122969) */ + 5418, /* 1E05A (122970) */ + 5419, /* 1E05B (122971) */ + 5420, /* 1E05C (122972) */ + 5421, /* 1E05D (122973) */ + 5422, /* 1E05E (122974) */ + 5423, /* 1E05F (122975) */ + 5424, /* 1E060 (122976) */ + 5425, /* 1E061 (122977) */ + 5426, /* 1E062 (122978) */ + 5427, /* 1E063 (122979) */ + 5428, /* 1E064 (122980) */ + 5429, /* 1E065 (122981) */ + 5430, /* 1E066 (122982) */ + 5431, /* 1E067 (122983) */ + 5432, /* 1E068 (122984) */ + 5433, /* 1E069 (122985) */ + 5434, /* 1E06A (122986) */ + 5435, /* 1E06B (122987) */ + 5436, /* 1E06C (122988) */ + 5437, /* 1E06D (122989) */ 56, /* 1E06E (122990) */ 56, /* 1E06F (122991) */ 56, /* 1E070 (122992) */ @@ -102470,60 +102704,60 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E6BD (124605) */ 56, /* 1E6BE (124606) */ 56, /* 1E6BF (124607) */ - 56, /* 1E6C0 (124608) */ - 56, /* 1E6C1 (124609) */ - 56, /* 1E6C2 (124610) */ - 56, /* 1E6C3 (124611) */ - 56, /* 1E6C4 (124612) */ - 56, /* 1E6C5 (124613) */ - 56, /* 1E6C6 (124614) */ - 56, /* 1E6C7 (124615) */ - 56, /* 1E6C8 (124616) */ - 56, /* 1E6C9 (124617) */ - 56, /* 1E6CA (124618) */ - 56, /* 1E6CB (124619) */ - 56, /* 1E6CC (124620) */ - 56, /* 1E6CD (124621) */ - 56, /* 1E6CE (124622) */ - 56, /* 1E6CF (124623) */ - 56, /* 1E6D0 (124624) */ - 56, /* 1E6D1 (124625) */ - 56, /* 1E6D2 (124626) */ - 56, /* 1E6D3 (124627) */ - 56, /* 1E6D4 (124628) */ - 56, /* 1E6D5 (124629) */ - 56, /* 1E6D6 (124630) */ - 56, /* 1E6D7 (124631) */ - 56, /* 1E6D8 (124632) */ - 56, /* 1E6D9 (124633) */ - 56, /* 1E6DA (124634) */ - 56, /* 1E6DB (124635) */ - 56, /* 1E6DC (124636) */ - 56, /* 1E6DD (124637) */ - 56, /* 1E6DE (124638) */ + 1, /* 1E6C0 (124608) */ + 1, /* 1E6C1 (124609) */ + 1, /* 1E6C2 (124610) */ + 1, /* 1E6C3 (124611) */ + 1, /* 1E6C4 (124612) */ + 1, /* 1E6C5 (124613) */ + 1, /* 1E6C6 (124614) */ + 1, /* 1E6C7 (124615) */ + 1, /* 1E6C8 (124616) */ + 1, /* 1E6C9 (124617) */ + 1, /* 1E6CA (124618) */ + 1, /* 1E6CB (124619) */ + 1, /* 1E6CC (124620) */ + 1, /* 1E6CD (124621) */ + 1, /* 1E6CE (124622) */ + 1, /* 1E6CF (124623) */ + 1, /* 1E6D0 (124624) */ + 1, /* 1E6D1 (124625) */ + 1, /* 1E6D2 (124626) */ + 1, /* 1E6D3 (124627) */ + 1, /* 1E6D4 (124628) */ + 1, /* 1E6D5 (124629) */ + 1, /* 1E6D6 (124630) */ + 1, /* 1E6D7 (124631) */ + 1, /* 1E6D8 (124632) */ + 1, /* 1E6D9 (124633) */ + 1, /* 1E6DA (124634) */ + 1, /* 1E6DB (124635) */ + 1, /* 1E6DC (124636) */ + 1, /* 1E6DD (124637) */ + 1, /* 1E6DE (124638) */ 56, /* 1E6DF (124639) */ - 56, /* 1E6E0 (124640) */ - 56, /* 1E6E1 (124641) */ - 56, /* 1E6E2 (124642) */ - 56, /* 1E6E3 (124643) */ - 56, /* 1E6E4 (124644) */ - 56, /* 1E6E5 (124645) */ - 56, /* 1E6E6 (124646) */ - 56, /* 1E6E7 (124647) */ - 56, /* 1E6E8 (124648) */ - 56, /* 1E6E9 (124649) */ - 56, /* 1E6EA (124650) */ - 56, /* 1E6EB (124651) */ - 56, /* 1E6EC (124652) */ - 56, /* 1E6ED (124653) */ - 56, /* 1E6EE (124654) */ - 56, /* 1E6EF (124655) */ - 56, /* 1E6F0 (124656) */ - 56, /* 1E6F1 (124657) */ - 56, /* 1E6F2 (124658) */ - 56, /* 1E6F3 (124659) */ - 56, /* 1E6F4 (124660) */ - 56, /* 1E6F5 (124661) */ + 1, /* 1E6E0 (124640) */ + 1, /* 1E6E1 (124641) */ + 1, /* 1E6E2 (124642) */ + 431, /* 1E6E3 (124643) */ + 1, /* 1E6E4 (124644) */ + 1, /* 1E6E5 (124645) */ + 431, /* 1E6E6 (124646) */ + 1, /* 1E6E7 (124647) */ + 1, /* 1E6E8 (124648) */ + 1, /* 1E6E9 (124649) */ + 1, /* 1E6EA (124650) */ + 1, /* 1E6EB (124651) */ + 1, /* 1E6EC (124652) */ + 1, /* 1E6ED (124653) */ + 431, /* 1E6EE (124654) */ + 431, /* 1E6EF (124655) */ + 1, /* 1E6F0 (124656) */ + 1, /* 1E6F1 (124657) */ + 1, /* 1E6F2 (124658) */ + 1, /* 1E6F3 (124659) */ + 1, /* 1E6F4 (124660) */ + 431, /* 1E6F5 (124661) */ 56, /* 1E6F6 (124662) */ 56, /* 1E6F7 (124663) */ 56, /* 1E6F8 (124664) */ @@ -102532,8 +102766,8 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E6FB (124667) */ 56, /* 1E6FC (124668) */ 56, /* 1E6FD (124669) */ - 56, /* 1E6FE (124670) */ - 56, /* 1E6FF (124671) */ + 1, /* 1E6FE (124670) */ + 1, /* 1E6FF (124671) */ 56, /* 1E700 (124672) */ 56, /* 1E701 (124673) */ 56, /* 1E702 (124674) */ @@ -103046,40 +103280,40 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1E8FD (125181) */ 56, /* 1E8FE (125182) */ 56, /* 1E8FF (125183) */ - 5409, /* 1E900 (125184) */ - 5410, /* 1E901 (125185) */ - 5411, /* 1E902 (125186) */ - 5412, /* 1E903 (125187) */ - 5413, /* 1E904 (125188) */ - 5414, /* 1E905 (125189) */ - 5415, /* 1E906 (125190) */ - 5416, /* 1E907 (125191) */ - 5417, /* 1E908 (125192) */ - 5418, /* 1E909 (125193) */ - 5419, /* 1E90A (125194) */ - 5420, /* 1E90B (125195) */ - 5421, /* 1E90C (125196) */ - 5422, /* 1E90D (125197) */ - 5423, /* 1E90E (125198) */ - 5424, /* 1E90F (125199) */ - 5425, /* 1E910 (125200) */ - 5426, /* 1E911 (125201) */ - 5427, /* 1E912 (125202) */ - 5428, /* 1E913 (125203) */ - 5429, /* 1E914 (125204) */ - 5430, /* 1E915 (125205) */ - 5431, /* 1E916 (125206) */ - 5432, /* 1E917 (125207) */ - 5433, /* 1E918 (125208) */ - 5434, /* 1E919 (125209) */ - 5435, /* 1E91A (125210) */ - 5436, /* 1E91B (125211) */ - 5437, /* 1E91C (125212) */ - 5438, /* 1E91D (125213) */ - 5439, /* 1E91E (125214) */ - 5440, /* 1E91F (125215) */ - 5441, /* 1E920 (125216) */ - 5442, /* 1E921 (125217) */ + 5438, /* 1E900 (125184) */ + 5439, /* 1E901 (125185) */ + 5440, /* 1E902 (125186) */ + 5441, /* 1E903 (125187) */ + 5442, /* 1E904 (125188) */ + 5443, /* 1E905 (125189) */ + 5444, /* 1E906 (125190) */ + 5445, /* 1E907 (125191) */ + 5446, /* 1E908 (125192) */ + 5447, /* 1E909 (125193) */ + 5448, /* 1E90A (125194) */ + 5449, /* 1E90B (125195) */ + 5450, /* 1E90C (125196) */ + 5451, /* 1E90D (125197) */ + 5452, /* 1E90E (125198) */ + 5453, /* 1E90F (125199) */ + 5454, /* 1E910 (125200) */ + 5455, /* 1E911 (125201) */ + 5456, /* 1E912 (125202) */ + 5457, /* 1E913 (125203) */ + 5458, /* 1E914 (125204) */ + 5459, /* 1E915 (125205) */ + 5460, /* 1E916 (125206) */ + 5461, /* 1E917 (125207) */ + 5462, /* 1E918 (125208) */ + 5463, /* 1E919 (125209) */ + 5464, /* 1E91A (125210) */ + 5465, /* 1E91B (125211) */ + 5466, /* 1E91C (125212) */ + 5467, /* 1E91D (125213) */ + 5468, /* 1E91E (125214) */ + 5469, /* 1E91F (125215) */ + 5470, /* 1E920 (125216) */ + 5471, /* 1E921 (125217) */ 1, /* 1E922 (125218) */ 1, /* 1E923 (125219) */ 1, /* 1E924 (125220) */ @@ -104326,194 +104560,194 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1EDFD (126461) */ 56, /* 1EDFE (126462) */ 56, /* 1EDFF (126463) */ - 5443, /* 1EE00 (126464) */ - 5444, /* 1EE01 (126465) */ - 5445, /* 1EE02 (126466) */ - 5446, /* 1EE03 (126467) */ + 5472, /* 1EE00 (126464) */ + 5473, /* 1EE01 (126465) */ + 5474, /* 1EE02 (126466) */ + 5475, /* 1EE03 (126467) */ 56, /* 1EE04 (126468) */ - 5447, /* 1EE05 (126469) */ - 5448, /* 1EE06 (126470) */ - 5449, /* 1EE07 (126471) */ - 5450, /* 1EE08 (126472) */ - 5451, /* 1EE09 (126473) */ - 5452, /* 1EE0A (126474) */ - 5453, /* 1EE0B (126475) */ - 5454, /* 1EE0C (126476) */ - 5455, /* 1EE0D (126477) */ - 5456, /* 1EE0E (126478) */ - 5457, /* 1EE0F (126479) */ - 5458, /* 1EE10 (126480) */ - 5459, /* 1EE11 (126481) */ - 5460, /* 1EE12 (126482) */ - 5461, /* 1EE13 (126483) */ - 5462, /* 1EE14 (126484) */ - 5463, /* 1EE15 (126485) */ - 5464, /* 1EE16 (126486) */ - 5465, /* 1EE17 (126487) */ - 5466, /* 1EE18 (126488) */ - 5467, /* 1EE19 (126489) */ - 5468, /* 1EE1A (126490) */ - 5469, /* 1EE1B (126491) */ - 5470, /* 1EE1C (126492) */ - 5471, /* 1EE1D (126493) */ - 5472, /* 1EE1E (126494) */ - 5473, /* 1EE1F (126495) */ + 5476, /* 1EE05 (126469) */ + 5477, /* 1EE06 (126470) */ + 5478, /* 1EE07 (126471) */ + 5479, /* 1EE08 (126472) */ + 5480, /* 1EE09 (126473) */ + 5481, /* 1EE0A (126474) */ + 5482, /* 1EE0B (126475) */ + 5483, /* 1EE0C (126476) */ + 5484, /* 1EE0D (126477) */ + 5485, /* 1EE0E (126478) */ + 5486, /* 1EE0F (126479) */ + 5487, /* 1EE10 (126480) */ + 5488, /* 1EE11 (126481) */ + 5489, /* 1EE12 (126482) */ + 5490, /* 1EE13 (126483) */ + 5491, /* 1EE14 (126484) */ + 5492, /* 1EE15 (126485) */ + 5493, /* 1EE16 (126486) */ + 5494, /* 1EE17 (126487) */ + 5495, /* 1EE18 (126488) */ + 5496, /* 1EE19 (126489) */ + 5497, /* 1EE1A (126490) */ + 5498, /* 1EE1B (126491) */ + 5499, /* 1EE1C (126492) */ + 5500, /* 1EE1D (126493) */ + 5501, /* 1EE1E (126494) */ + 5502, /* 1EE1F (126495) */ 56, /* 1EE20 (126496) */ - 5444, /* 1EE21 (126497) */ - 5445, /* 1EE22 (126498) */ + 5473, /* 1EE21 (126497) */ + 5474, /* 1EE22 (126498) */ 56, /* 1EE23 (126499) */ - 5474, /* 1EE24 (126500) */ + 5503, /* 1EE24 (126500) */ 56, /* 1EE25 (126501) */ 56, /* 1EE26 (126502) */ - 5449, /* 1EE27 (126503) */ + 5478, /* 1EE27 (126503) */ 56, /* 1EE28 (126504) */ - 5451, /* 1EE29 (126505) */ - 5452, /* 1EE2A (126506) */ - 5453, /* 1EE2B (126507) */ - 5454, /* 1EE2C (126508) */ - 5455, /* 1EE2D (126509) */ - 5456, /* 1EE2E (126510) */ - 5457, /* 1EE2F (126511) */ - 5458, /* 1EE30 (126512) */ - 5459, /* 1EE31 (126513) */ - 5460, /* 1EE32 (126514) */ + 5480, /* 1EE29 (126505) */ + 5481, /* 1EE2A (126506) */ + 5482, /* 1EE2B (126507) */ + 5483, /* 1EE2C (126508) */ + 5484, /* 1EE2D (126509) */ + 5485, /* 1EE2E (126510) */ + 5486, /* 1EE2F (126511) */ + 5487, /* 1EE30 (126512) */ + 5488, /* 1EE31 (126513) */ + 5489, /* 1EE32 (126514) */ 56, /* 1EE33 (126515) */ - 5462, /* 1EE34 (126516) */ - 5463, /* 1EE35 (126517) */ - 5464, /* 1EE36 (126518) */ - 5465, /* 1EE37 (126519) */ + 5491, /* 1EE34 (126516) */ + 5492, /* 1EE35 (126517) */ + 5493, /* 1EE36 (126518) */ + 5494, /* 1EE37 (126519) */ 56, /* 1EE38 (126520) */ - 5467, /* 1EE39 (126521) */ + 5496, /* 1EE39 (126521) */ 56, /* 1EE3A (126522) */ - 5469, /* 1EE3B (126523) */ + 5498, /* 1EE3B (126523) */ 56, /* 1EE3C (126524) */ 56, /* 1EE3D (126525) */ 56, /* 1EE3E (126526) */ 56, /* 1EE3F (126527) */ 56, /* 1EE40 (126528) */ 56, /* 1EE41 (126529) */ - 5445, /* 1EE42 (126530) */ + 5474, /* 1EE42 (126530) */ 56, /* 1EE43 (126531) */ 56, /* 1EE44 (126532) */ 56, /* 1EE45 (126533) */ 56, /* 1EE46 (126534) */ - 5449, /* 1EE47 (126535) */ + 5478, /* 1EE47 (126535) */ 56, /* 1EE48 (126536) */ - 5451, /* 1EE49 (126537) */ + 5480, /* 1EE49 (126537) */ 56, /* 1EE4A (126538) */ - 5453, /* 1EE4B (126539) */ + 5482, /* 1EE4B (126539) */ 56, /* 1EE4C (126540) */ - 5455, /* 1EE4D (126541) */ - 5456, /* 1EE4E (126542) */ - 5457, /* 1EE4F (126543) */ + 5484, /* 1EE4D (126541) */ + 5485, /* 1EE4E (126542) */ + 5486, /* 1EE4F (126543) */ 56, /* 1EE50 (126544) */ - 5459, /* 1EE51 (126545) */ - 5460, /* 1EE52 (126546) */ + 5488, /* 1EE51 (126545) */ + 5489, /* 1EE52 (126546) */ 56, /* 1EE53 (126547) */ - 5462, /* 1EE54 (126548) */ + 5491, /* 1EE54 (126548) */ 56, /* 1EE55 (126549) */ 56, /* 1EE56 (126550) */ - 5465, /* 1EE57 (126551) */ + 5494, /* 1EE57 (126551) */ 56, /* 1EE58 (126552) */ - 5467, /* 1EE59 (126553) */ + 5496, /* 1EE59 (126553) */ 56, /* 1EE5A (126554) */ - 5469, /* 1EE5B (126555) */ + 5498, /* 1EE5B (126555) */ 56, /* 1EE5C (126556) */ - 5471, /* 1EE5D (126557) */ + 5500, /* 1EE5D (126557) */ 56, /* 1EE5E (126558) */ - 5473, /* 1EE5F (126559) */ + 5502, /* 1EE5F (126559) */ 56, /* 1EE60 (126560) */ - 5444, /* 1EE61 (126561) */ - 5445, /* 1EE62 (126562) */ + 5473, /* 1EE61 (126561) */ + 5474, /* 1EE62 (126562) */ 56, /* 1EE63 (126563) */ - 5474, /* 1EE64 (126564) */ + 5503, /* 1EE64 (126564) */ 56, /* 1EE65 (126565) */ 56, /* 1EE66 (126566) */ - 5449, /* 1EE67 (126567) */ - 5450, /* 1EE68 (126568) */ - 5451, /* 1EE69 (126569) */ - 5452, /* 1EE6A (126570) */ + 5478, /* 1EE67 (126567) */ + 5479, /* 1EE68 (126568) */ + 5480, /* 1EE69 (126569) */ + 5481, /* 1EE6A (126570) */ 56, /* 1EE6B (126571) */ - 5454, /* 1EE6C (126572) */ - 5455, /* 1EE6D (126573) */ - 5456, /* 1EE6E (126574) */ - 5457, /* 1EE6F (126575) */ - 5458, /* 1EE70 (126576) */ - 5459, /* 1EE71 (126577) */ - 5460, /* 1EE72 (126578) */ + 5483, /* 1EE6C (126572) */ + 5484, /* 1EE6D (126573) */ + 5485, /* 1EE6E (126574) */ + 5486, /* 1EE6F (126575) */ + 5487, /* 1EE70 (126576) */ + 5488, /* 1EE71 (126577) */ + 5489, /* 1EE72 (126578) */ 56, /* 1EE73 (126579) */ - 5462, /* 1EE74 (126580) */ - 5463, /* 1EE75 (126581) */ - 5464, /* 1EE76 (126582) */ - 5465, /* 1EE77 (126583) */ + 5491, /* 1EE74 (126580) */ + 5492, /* 1EE75 (126581) */ + 5493, /* 1EE76 (126582) */ + 5494, /* 1EE77 (126583) */ 56, /* 1EE78 (126584) */ - 5467, /* 1EE79 (126585) */ - 5468, /* 1EE7A (126586) */ - 5469, /* 1EE7B (126587) */ - 5470, /* 1EE7C (126588) */ + 5496, /* 1EE79 (126585) */ + 5497, /* 1EE7A (126586) */ + 5498, /* 1EE7B (126587) */ + 5499, /* 1EE7C (126588) */ 56, /* 1EE7D (126589) */ - 5472, /* 1EE7E (126590) */ + 5501, /* 1EE7E (126590) */ 56, /* 1EE7F (126591) */ - 5443, /* 1EE80 (126592) */ - 5444, /* 1EE81 (126593) */ - 5445, /* 1EE82 (126594) */ - 5446, /* 1EE83 (126595) */ - 5474, /* 1EE84 (126596) */ - 5447, /* 1EE85 (126597) */ - 5448, /* 1EE86 (126598) */ - 5449, /* 1EE87 (126599) */ - 5450, /* 1EE88 (126600) */ - 5451, /* 1EE89 (126601) */ + 5472, /* 1EE80 (126592) */ + 5473, /* 1EE81 (126593) */ + 5474, /* 1EE82 (126594) */ + 5475, /* 1EE83 (126595) */ + 5503, /* 1EE84 (126596) */ + 5476, /* 1EE85 (126597) */ + 5477, /* 1EE86 (126598) */ + 5478, /* 1EE87 (126599) */ + 5479, /* 1EE88 (126600) */ + 5480, /* 1EE89 (126601) */ 56, /* 1EE8A (126602) */ - 5453, /* 1EE8B (126603) */ - 5454, /* 1EE8C (126604) */ - 5455, /* 1EE8D (126605) */ - 5456, /* 1EE8E (126606) */ - 5457, /* 1EE8F (126607) */ - 5458, /* 1EE90 (126608) */ - 5459, /* 1EE91 (126609) */ - 5460, /* 1EE92 (126610) */ - 5461, /* 1EE93 (126611) */ - 5462, /* 1EE94 (126612) */ - 5463, /* 1EE95 (126613) */ - 5464, /* 1EE96 (126614) */ - 5465, /* 1EE97 (126615) */ - 5466, /* 1EE98 (126616) */ - 5467, /* 1EE99 (126617) */ - 5468, /* 1EE9A (126618) */ - 5469, /* 1EE9B (126619) */ + 5482, /* 1EE8B (126603) */ + 5483, /* 1EE8C (126604) */ + 5484, /* 1EE8D (126605) */ + 5485, /* 1EE8E (126606) */ + 5486, /* 1EE8F (126607) */ + 5487, /* 1EE90 (126608) */ + 5488, /* 1EE91 (126609) */ + 5489, /* 1EE92 (126610) */ + 5490, /* 1EE93 (126611) */ + 5491, /* 1EE94 (126612) */ + 5492, /* 1EE95 (126613) */ + 5493, /* 1EE96 (126614) */ + 5494, /* 1EE97 (126615) */ + 5495, /* 1EE98 (126616) */ + 5496, /* 1EE99 (126617) */ + 5497, /* 1EE9A (126618) */ + 5498, /* 1EE9B (126619) */ 56, /* 1EE9C (126620) */ 56, /* 1EE9D (126621) */ 56, /* 1EE9E (126622) */ 56, /* 1EE9F (126623) */ 56, /* 1EEA0 (126624) */ - 5444, /* 1EEA1 (126625) */ - 5445, /* 1EEA2 (126626) */ - 5446, /* 1EEA3 (126627) */ + 5473, /* 1EEA1 (126625) */ + 5474, /* 1EEA2 (126626) */ + 5475, /* 1EEA3 (126627) */ 56, /* 1EEA4 (126628) */ - 5447, /* 1EEA5 (126629) */ - 5448, /* 1EEA6 (126630) */ - 5449, /* 1EEA7 (126631) */ - 5450, /* 1EEA8 (126632) */ - 5451, /* 1EEA9 (126633) */ + 5476, /* 1EEA5 (126629) */ + 5477, /* 1EEA6 (126630) */ + 5478, /* 1EEA7 (126631) */ + 5479, /* 1EEA8 (126632) */ + 5480, /* 1EEA9 (126633) */ 56, /* 1EEAA (126634) */ - 5453, /* 1EEAB (126635) */ - 5454, /* 1EEAC (126636) */ - 5455, /* 1EEAD (126637) */ - 5456, /* 1EEAE (126638) */ - 5457, /* 1EEAF (126639) */ - 5458, /* 1EEB0 (126640) */ - 5459, /* 1EEB1 (126641) */ - 5460, /* 1EEB2 (126642) */ - 5461, /* 1EEB3 (126643) */ - 5462, /* 1EEB4 (126644) */ - 5463, /* 1EEB5 (126645) */ - 5464, /* 1EEB6 (126646) */ - 5465, /* 1EEB7 (126647) */ - 5466, /* 1EEB8 (126648) */ - 5467, /* 1EEB9 (126649) */ - 5468, /* 1EEBA (126650) */ - 5469, /* 1EEBB (126651) */ + 5482, /* 1EEAB (126635) */ + 5483, /* 1EEAC (126636) */ + 5484, /* 1EEAD (126637) */ + 5485, /* 1EEAE (126638) */ + 5486, /* 1EEAF (126639) */ + 5487, /* 1EEB0 (126640) */ + 5488, /* 1EEB1 (126641) */ + 5489, /* 1EEB2 (126642) */ + 5490, /* 1EEB3 (126643) */ + 5491, /* 1EEB4 (126644) */ + 5492, /* 1EEB5 (126645) */ + 5493, /* 1EEB6 (126646) */ + 5494, /* 1EEB7 (126647) */ + 5495, /* 1EEB8 (126648) */ + 5496, /* 1EEB9 (126649) */ + 5497, /* 1EEBA (126650) */ + 5498, /* 1EEBB (126651) */ 56, /* 1EEBC (126652) */ 56, /* 1EEBD (126653) */ 56, /* 1EEBE (126654) */ @@ -105094,86 +105328,86 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F0FD (127229) */ 56, /* 1F0FE (127230) */ 56, /* 1F0FF (127231) */ - 5475, /* 1F100 (127232) */ - 5476, /* 1F101 (127233) */ - 5477, /* 1F102 (127234) */ - 5478, /* 1F103 (127235) */ - 5479, /* 1F104 (127236) */ - 5480, /* 1F105 (127237) */ - 5481, /* 1F106 (127238) */ - 5482, /* 1F107 (127239) */ - 5483, /* 1F108 (127240) */ - 5484, /* 1F109 (127241) */ - 5485, /* 1F10A (127242) */ + 5504, /* 1F100 (127232) */ + 5505, /* 1F101 (127233) */ + 5506, /* 1F102 (127234) */ + 5507, /* 1F103 (127235) */ + 5508, /* 1F104 (127236) */ + 5509, /* 1F105 (127237) */ + 5510, /* 1F106 (127238) */ + 5511, /* 1F107 (127239) */ + 5512, /* 1F108 (127240) */ + 5513, /* 1F109 (127241) */ + 5514, /* 1F10A (127242) */ 1, /* 1F10B (127243) */ 1, /* 1F10C (127244) */ 1, /* 1F10D (127245) */ 1, /* 1F10E (127246) */ 1, /* 1F10F (127247) */ - 5486, /* 1F110 (127248) */ - 5487, /* 1F111 (127249) */ - 5488, /* 1F112 (127250) */ - 5489, /* 1F113 (127251) */ - 5490, /* 1F114 (127252) */ - 5491, /* 1F115 (127253) */ - 5492, /* 1F116 (127254) */ - 5493, /* 1F117 (127255) */ - 5494, /* 1F118 (127256) */ - 5495, /* 1F119 (127257) */ - 5496, /* 1F11A (127258) */ - 5497, /* 1F11B (127259) */ - 5498, /* 1F11C (127260) */ - 5499, /* 1F11D (127261) */ - 5500, /* 1F11E (127262) */ - 5501, /* 1F11F (127263) */ - 5502, /* 1F120 (127264) */ - 5503, /* 1F121 (127265) */ - 5504, /* 1F122 (127266) */ - 5505, /* 1F123 (127267) */ - 5506, /* 1F124 (127268) */ - 5507, /* 1F125 (127269) */ - 5508, /* 1F126 (127270) */ - 5509, /* 1F127 (127271) */ - 5510, /* 1F128 (127272) */ - 5511, /* 1F129 (127273) */ - 5512, /* 1F12A (127274) */ + 5515, /* 1F110 (127248) */ + 5516, /* 1F111 (127249) */ + 5517, /* 1F112 (127250) */ + 5518, /* 1F113 (127251) */ + 5519, /* 1F114 (127252) */ + 5520, /* 1F115 (127253) */ + 5521, /* 1F116 (127254) */ + 5522, /* 1F117 (127255) */ + 5523, /* 1F118 (127256) */ + 5524, /* 1F119 (127257) */ + 5525, /* 1F11A (127258) */ + 5526, /* 1F11B (127259) */ + 5527, /* 1F11C (127260) */ + 5528, /* 1F11D (127261) */ + 5529, /* 1F11E (127262) */ + 5530, /* 1F11F (127263) */ + 5531, /* 1F120 (127264) */ + 5532, /* 1F121 (127265) */ + 5533, /* 1F122 (127266) */ + 5534, /* 1F123 (127267) */ + 5535, /* 1F124 (127268) */ + 5536, /* 1F125 (127269) */ + 5537, /* 1F126 (127270) */ + 5538, /* 1F127 (127271) */ + 5539, /* 1F128 (127272) */ + 5540, /* 1F129 (127273) */ + 5541, /* 1F12A (127274) */ 2005, /* 1F12B (127275) */ 2020, /* 1F12C (127276) */ - 5513, /* 1F12D (127277) */ - 5514, /* 1F12E (127278) */ + 5542, /* 1F12D (127277) */ + 5543, /* 1F12E (127278) */ 1, /* 1F12F (127279) */ - 5515, /* 1F130 (127280) */ - 5516, /* 1F131 (127281) */ - 5517, /* 1F132 (127282) */ - 5518, /* 1F133 (127283) */ - 5519, /* 1F134 (127284) */ - 5520, /* 1F135 (127285) */ - 5521, /* 1F136 (127286) */ - 5522, /* 1F137 (127287) */ - 5523, /* 1F138 (127288) */ - 5524, /* 1F139 (127289) */ - 5525, /* 1F13A (127290) */ - 5526, /* 1F13B (127291) */ - 5527, /* 1F13C (127292) */ - 5528, /* 1F13D (127293) */ - 5529, /* 1F13E (127294) */ - 5530, /* 1F13F (127295) */ - 5531, /* 1F140 (127296) */ - 5532, /* 1F141 (127297) */ - 5533, /* 1F142 (127298) */ - 5534, /* 1F143 (127299) */ - 5535, /* 1F144 (127300) */ - 5536, /* 1F145 (127301) */ - 5537, /* 1F146 (127302) */ - 5538, /* 1F147 (127303) */ - 5539, /* 1F148 (127304) */ - 5540, /* 1F149 (127305) */ - 5541, /* 1F14A (127306) */ + 5544, /* 1F130 (127280) */ + 5545, /* 1F131 (127281) */ + 5546, /* 1F132 (127282) */ + 5547, /* 1F133 (127283) */ + 5548, /* 1F134 (127284) */ + 5549, /* 1F135 (127285) */ + 5550, /* 1F136 (127286) */ + 5551, /* 1F137 (127287) */ + 5552, /* 1F138 (127288) */ + 5553, /* 1F139 (127289) */ + 5554, /* 1F13A (127290) */ + 5555, /* 1F13B (127291) */ + 5556, /* 1F13C (127292) */ + 5557, /* 1F13D (127293) */ + 5558, /* 1F13E (127294) */ + 5559, /* 1F13F (127295) */ + 5560, /* 1F140 (127296) */ + 5561, /* 1F141 (127297) */ + 5562, /* 1F142 (127298) */ + 5563, /* 1F143 (127299) */ + 5564, /* 1F144 (127300) */ + 5565, /* 1F145 (127301) */ + 5566, /* 1F146 (127302) */ + 5567, /* 1F147 (127303) */ + 5568, /* 1F148 (127304) */ + 5569, /* 1F149 (127305) */ + 5570, /* 1F14A (127306) */ 3053, /* 1F14B (127307) */ - 5542, /* 1F14C (127308) */ - 5543, /* 1F14D (127309) */ - 5544, /* 1F14E (127310) */ - 5545, /* 1F14F (127311) */ + 5571, /* 1F14C (127308) */ + 5572, /* 1F14D (127309) */ + 5573, /* 1F14E (127310) */ + 5574, /* 1F14F (127311) */ 1, /* 1F150 (127312) */ 1, /* 1F151 (127313) */ 1, /* 1F152 (127314) */ @@ -105200,9 +105434,9 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F167 (127335) */ 1, /* 1F168 (127336) */ 1, /* 1F169 (127337) */ - 5546, /* 1F16A (127338) */ - 5547, /* 1F16B (127339) */ - 5548, /* 1F16C (127340) */ + 5575, /* 1F16A (127338) */ + 5576, /* 1F16B (127339) */ + 5577, /* 1F16C (127340) */ 1, /* 1F16D (127341) */ 1, /* 1F16E (127342) */ 1, /* 1F16F (127343) */ @@ -105238,7 +105472,7 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F18D (127373) */ 1, /* 1F18E (127374) */ 1, /* 1F18F (127375) */ - 5549, /* 1F190 (127376) */ + 5578, /* 1F190 (127376) */ 1, /* 1F191 (127377) */ 1, /* 1F192 (127378) */ 1, /* 1F193 (127379) */ @@ -105350,9 +105584,9 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F1FD (127485) */ 1, /* 1F1FE (127486) */ 1, /* 1F1FF (127487) */ - 5550, /* 1F200 (127488) */ - 5551, /* 1F201 (127489) */ - 5552, /* 1F202 (127490) */ + 5579, /* 1F200 (127488) */ + 5580, /* 1F201 (127489) */ + 5581, /* 1F202 (127490) */ 56, /* 1F203 (127491) */ 56, /* 1F204 (127492) */ 56, /* 1F205 (127493) */ @@ -105366,63 +105600,63 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F20D (127501) */ 56, /* 1F20E (127502) */ 56, /* 1F20F (127503) */ - 5553, /* 1F210 (127504) */ - 5554, /* 1F211 (127505) */ - 5555, /* 1F212 (127506) */ - 5556, /* 1F213 (127507) */ - 5557, /* 1F214 (127508) */ - 5558, /* 1F215 (127509) */ - 5559, /* 1F216 (127510) */ - 5560, /* 1F217 (127511) */ - 5561, /* 1F218 (127512) */ - 5562, /* 1F219 (127513) */ - 5563, /* 1F21A (127514) */ - 5564, /* 1F21B (127515) */ - 5565, /* 1F21C (127516) */ - 5566, /* 1F21D (127517) */ - 5567, /* 1F21E (127518) */ - 5568, /* 1F21F (127519) */ - 5569, /* 1F220 (127520) */ - 5570, /* 1F221 (127521) */ - 5571, /* 1F222 (127522) */ - 5572, /* 1F223 (127523) */ - 5573, /* 1F224 (127524) */ - 5574, /* 1F225 (127525) */ - 5575, /* 1F226 (127526) */ - 5576, /* 1F227 (127527) */ - 5577, /* 1F228 (127528) */ - 5578, /* 1F229 (127529) */ - 5579, /* 1F22A (127530) */ - 5580, /* 1F22B (127531) */ - 5581, /* 1F22C (127532) */ - 5582, /* 1F22D (127533) */ - 5583, /* 1F22E (127534) */ - 5584, /* 1F22F (127535) */ - 5585, /* 1F230 (127536) */ - 5586, /* 1F231 (127537) */ - 5587, /* 1F232 (127538) */ - 5588, /* 1F233 (127539) */ - 5589, /* 1F234 (127540) */ - 5590, /* 1F235 (127541) */ - 5591, /* 1F236 (127542) */ - 5592, /* 1F237 (127543) */ - 5593, /* 1F238 (127544) */ - 5594, /* 1F239 (127545) */ - 5595, /* 1F23A (127546) */ - 5596, /* 1F23B (127547) */ + 5582, /* 1F210 (127504) */ + 5583, /* 1F211 (127505) */ + 5584, /* 1F212 (127506) */ + 5585, /* 1F213 (127507) */ + 5586, /* 1F214 (127508) */ + 5587, /* 1F215 (127509) */ + 5588, /* 1F216 (127510) */ + 5589, /* 1F217 (127511) */ + 5590, /* 1F218 (127512) */ + 5591, /* 1F219 (127513) */ + 5592, /* 1F21A (127514) */ + 5593, /* 1F21B (127515) */ + 5594, /* 1F21C (127516) */ + 5595, /* 1F21D (127517) */ + 5596, /* 1F21E (127518) */ + 5597, /* 1F21F (127519) */ + 5598, /* 1F220 (127520) */ + 5599, /* 1F221 (127521) */ + 5600, /* 1F222 (127522) */ + 5601, /* 1F223 (127523) */ + 5602, /* 1F224 (127524) */ + 5603, /* 1F225 (127525) */ + 5604, /* 1F226 (127526) */ + 5605, /* 1F227 (127527) */ + 5606, /* 1F228 (127528) */ + 5607, /* 1F229 (127529) */ + 5608, /* 1F22A (127530) */ + 5609, /* 1F22B (127531) */ + 5610, /* 1F22C (127532) */ + 5611, /* 1F22D (127533) */ + 5612, /* 1F22E (127534) */ + 5613, /* 1F22F (127535) */ + 5614, /* 1F230 (127536) */ + 5615, /* 1F231 (127537) */ + 5616, /* 1F232 (127538) */ + 5617, /* 1F233 (127539) */ + 5618, /* 1F234 (127540) */ + 5619, /* 1F235 (127541) */ + 5620, /* 1F236 (127542) */ + 5621, /* 1F237 (127543) */ + 5622, /* 1F238 (127544) */ + 5623, /* 1F239 (127545) */ + 5624, /* 1F23A (127546) */ + 5625, /* 1F23B (127547) */ 56, /* 1F23C (127548) */ 56, /* 1F23D (127549) */ 56, /* 1F23E (127550) */ 56, /* 1F23F (127551) */ - 5597, /* 1F240 (127552) */ - 5598, /* 1F241 (127553) */ - 5599, /* 1F242 (127554) */ - 5600, /* 1F243 (127555) */ - 5601, /* 1F244 (127556) */ - 5602, /* 1F245 (127557) */ - 5603, /* 1F246 (127558) */ - 5604, /* 1F247 (127559) */ - 5605, /* 1F248 (127560) */ + 5626, /* 1F240 (127552) */ + 5627, /* 1F241 (127553) */ + 5628, /* 1F242 (127554) */ + 5629, /* 1F243 (127555) */ + 5630, /* 1F244 (127556) */ + 5631, /* 1F245 (127557) */ + 5632, /* 1F246 (127558) */ + 5633, /* 1F247 (127559) */ + 5634, /* 1F248 (127560) */ 56, /* 1F249 (127561) */ 56, /* 1F24A (127562) */ 56, /* 1F24B (127563) */ @@ -105430,8 +105664,8 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F24D (127565) */ 56, /* 1F24E (127566) */ 56, /* 1F24F (127567) */ - 5606, /* 1F250 (127568) */ - 5607, /* 1F251 (127569) */ + 5635, /* 1F250 (127568) */ + 5636, /* 1F251 (127569) */ 56, /* 1F252 (127570) */ 56, /* 1F253 (127571) */ 56, /* 1F254 (127572) */ @@ -106590,7 +106824,7 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F6D5 (128725) */ 1, /* 1F6D6 (128726) */ 1, /* 1F6D7 (128727) */ - 56, /* 1F6D8 (128728) */ + 1, /* 1F6D8 (128728) */ 56, /* 1F6D9 (128729) */ 56, /* 1F6DA (128730) */ 56, /* 1F6DB (128731) */ @@ -106749,10 +106983,10 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1F774 (128884) */ 1, /* 1F775 (128885) */ 1, /* 1F776 (128886) */ - 56, /* 1F777 (128887) */ - 56, /* 1F778 (128888) */ - 56, /* 1F779 (128889) */ - 56, /* 1F77A (128890) */ + 1, /* 1F777 (128887) */ + 1, /* 1F778 (128888) */ + 1, /* 1F779 (128889) */ + 1, /* 1F77A (128890) */ 1, /* 1F77B (128891) */ 1, /* 1F77C (128892) */ 1, /* 1F77D (128893) */ @@ -107094,15 +107328,15 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 1F8CD (129229) */ 56, /* 1F8CE (129230) */ 56, /* 1F8CF (129231) */ - 56, /* 1F8D0 (129232) */ - 56, /* 1F8D1 (129233) */ - 56, /* 1F8D2 (129234) */ - 56, /* 1F8D3 (129235) */ - 56, /* 1F8D4 (129236) */ - 56, /* 1F8D5 (129237) */ - 56, /* 1F8D6 (129238) */ - 56, /* 1F8D7 (129239) */ - 56, /* 1F8D8 (129240) */ + 1, /* 1F8D0 (129232) */ + 1, /* 1F8D1 (129233) */ + 1, /* 1F8D2 (129234) */ + 1, /* 1F8D3 (129235) */ + 1, /* 1F8D4 (129236) */ + 1, /* 1F8D5 (129237) */ + 1, /* 1F8D6 (129238) */ + 1, /* 1F8D7 (129239) */ + 1, /* 1F8D8 (129240) */ 56, /* 1F8D9 (129241) */ 56, /* 1F8DA (129242) */ 56, /* 1F8DB (129243) */ @@ -107482,10 +107716,10 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FA51 (129617) */ 1, /* 1FA52 (129618) */ 1, /* 1FA53 (129619) */ - 56, /* 1FA54 (129620) */ - 56, /* 1FA55 (129621) */ - 56, /* 1FA56 (129622) */ - 56, /* 1FA57 (129623) */ + 1, /* 1FA54 (129620) */ + 1, /* 1FA55 (129621) */ + 1, /* 1FA56 (129622) */ + 1, /* 1FA57 (129623) */ 56, /* 1FA58 (129624) */ 56, /* 1FA59 (129625) */ 56, /* 1FA5A (129626) */ @@ -107536,11 +107770,11 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FA87 (129671) */ 1, /* 1FA88 (129672) */ 1, /* 1FA89 (129673) */ - 56, /* 1FA8A (129674) */ + 1, /* 1FA8A (129674) */ 56, /* 1FA8B (129675) */ 56, /* 1FA8C (129676) */ 56, /* 1FA8D (129677) */ - 56, /* 1FA8E (129678) */ + 1, /* 1FA8E (129678) */ 1, /* 1FA8F (129679) */ 1, /* 1FA90 (129680) */ 1, /* 1FA91 (129681) */ @@ -107598,12 +107832,12 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FAC5 (129733) */ 1, /* 1FAC6 (129734) */ 56, /* 1FAC7 (129735) */ - 56, /* 1FAC8 (129736) */ + 1, /* 1FAC8 (129736) */ 56, /* 1FAC9 (129737) */ 56, /* 1FACA (129738) */ 56, /* 1FACB (129739) */ 56, /* 1FACC (129740) */ - 56, /* 1FACD (129741) */ + 1, /* 1FACD (129741) */ 1, /* 1FACE (129742) */ 1, /* 1FACF (129743) */ 1, /* 1FAD0 (129744) */ @@ -107632,12 +107866,12 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FAE7 (129767) */ 1, /* 1FAE8 (129768) */ 1, /* 1FAE9 (129769) */ - 56, /* 1FAEA (129770) */ + 1, /* 1FAEA (129770) */ 56, /* 1FAEB (129771) */ 56, /* 1FAEC (129772) */ 56, /* 1FAED (129773) */ 56, /* 1FAEE (129774) */ - 56, /* 1FAEF (129775) */ + 1, /* 1FAEF (129775) */ 1, /* 1FAF0 (129776) */ 1, /* 1FAF1 (129777) */ 1, /* 1FAF2 (129778) */ @@ -107894,17 +108128,17 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 1FBED (130029) */ 1, /* 1FBEE (130030) */ 1, /* 1FBEF (130031) */ - 5215, /* 1FBF0 (130032) */ - 5216, /* 1FBF1 (130033) */ - 5217, /* 1FBF2 (130034) */ - 5218, /* 1FBF3 (130035) */ - 5219, /* 1FBF4 (130036) */ - 5220, /* 1FBF5 (130037) */ - 5221, /* 1FBF6 (130038) */ - 5222, /* 1FBF7 (130039) */ - 5223, /* 1FBF8 (130040) */ - 5224, /* 1FBF9 (130041) */ - 56, /* 1FBFA (130042) */ + 5244, /* 1FBF0 (130032) */ + 5245, /* 1FBF1 (130033) */ + 5246, /* 1FBF2 (130034) */ + 5247, /* 1FBF3 (130035) */ + 5248, /* 1FBF4 (130036) */ + 5249, /* 1FBF5 (130037) */ + 5250, /* 1FBF6 (130038) */ + 5251, /* 1FBF7 (130039) */ + 5252, /* 1FBF8 (130040) */ + 5253, /* 1FBF9 (130041) */ + 1, /* 1FBFA (130042) */ 56, /* 1FBFB (130043) */ 56, /* 1FBFC (130044) */ 56, /* 1FBFD (130045) */ @@ -155840,12 +156074,12 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 2B737 (177975) */ 1, /* 2B738 (177976) */ 1, /* 2B739 (177977) */ - 56, /* 2B73A (177978) */ - 56, /* 2B73B (177979) */ - 56, /* 2B73C (177980) */ - 56, /* 2B73D (177981) */ - 56, /* 2B73E (177982) */ - 56, /* 2B73F (177983) */ + 1, /* 2B73A (177978) */ + 1, /* 2B73B (177979) */ + 1, /* 2B73C (177980) */ + 1, /* 2B73D (177981) */ + 1, /* 2B73E (177982) */ + 1, /* 2B73F (177983) */ 1, /* 2B740 (177984) */ 1, /* 2B741 (177985) */ 1, /* 2B742 (177986) */ @@ -161832,18 +162066,18 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 2CE9F (183967) */ 1, /* 2CEA0 (183968) */ 1, /* 2CEA1 (183969) */ - 56, /* 2CEA2 (183970) */ - 56, /* 2CEA3 (183971) */ - 56, /* 2CEA4 (183972) */ - 56, /* 2CEA5 (183973) */ - 56, /* 2CEA6 (183974) */ - 56, /* 2CEA7 (183975) */ - 56, /* 2CEA8 (183976) */ - 56, /* 2CEA9 (183977) */ - 56, /* 2CEAA (183978) */ - 56, /* 2CEAB (183979) */ - 56, /* 2CEAC (183980) */ - 56, /* 2CEAD (183981) */ + 1, /* 2CEA2 (183970) */ + 1, /* 2CEA3 (183971) */ + 1, /* 2CEA4 (183972) */ + 1, /* 2CEA5 (183973) */ + 1, /* 2CEA6 (183974) */ + 1, /* 2CEA7 (183975) */ + 1, /* 2CEA8 (183976) */ + 1, /* 2CEA9 (183977) */ + 1, /* 2CEAA (183978) */ + 1, /* 2CEAB (183979) */ + 1, /* 2CEAC (183980) */ + 1, /* 2CEAD (183981) */ 56, /* 2CEAE (183982) */ 56, /* 2CEAF (183983) */ 1, /* 2CEB0 (183984) */ @@ -172422,548 +172656,548 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 56, /* 2F7FD (194557) */ 56, /* 2F7FE (194558) */ 56, /* 2F7FF (194559) */ - 5608, /* 2F800 (194560) */ - 5609, /* 2F801 (194561) */ - 5610, /* 2F802 (194562) */ - 5611, /* 2F803 (194563) */ - 5612, /* 2F804 (194564) */ - 3630, /* 2F805 (194565) */ - 5613, /* 2F806 (194566) */ - 5614, /* 2F807 (194567) */ - 5615, /* 2F808 (194568) */ - 5616, /* 2F809 (194569) */ - 3631, /* 2F80A (194570) */ - 5617, /* 2F80B (194571) */ - 5618, /* 2F80C (194572) */ - 5619, /* 2F80D (194573) */ - 3632, /* 2F80E (194574) */ - 5620, /* 2F80F (194575) */ - 5621, /* 2F810 (194576) */ - 5622, /* 2F811 (194577) */ - 5623, /* 2F812 (194578) */ - 5624, /* 2F813 (194579) */ - 5625, /* 2F814 (194580) */ - 5626, /* 2F815 (194581) */ - 5627, /* 2F816 (194582) */ - 5628, /* 2F817 (194583) */ - 5629, /* 2F818 (194584) */ - 5630, /* 2F819 (194585) */ - 5631, /* 2F81A (194586) */ - 3690, /* 2F81B (194587) */ - 5632, /* 2F81C (194588) */ - 5633, /* 2F81D (194589) */ - 5634, /* 2F81E (194590) */ - 5635, /* 2F81F (194591) */ - 5636, /* 2F820 (194592) */ - 5637, /* 2F821 (194593) */ - 5638, /* 2F822 (194594) */ - 5639, /* 2F823 (194595) */ - 5640, /* 2F824 (194596) */ - 3695, /* 2F825 (194597) */ - 3633, /* 2F826 (194598) */ - 3634, /* 2F827 (194599) */ - 3696, /* 2F828 (194600) */ - 5641, /* 2F829 (194601) */ - 5642, /* 2F82A (194602) */ - 3441, /* 2F82B (194603) */ - 5643, /* 2F82C (194604) */ - 3635, /* 2F82D (194605) */ - 5644, /* 2F82E (194606) */ - 5645, /* 2F82F (194607) */ - 5646, /* 2F830 (194608) */ - 5647, /* 2F831 (194609) */ - 5647, /* 2F832 (194610) */ - 5647, /* 2F833 (194611) */ - 5648, /* 2F834 (194612) */ - 5649, /* 2F835 (194613) */ - 5650, /* 2F836 (194614) */ - 5651, /* 2F837 (194615) */ - 5652, /* 2F838 (194616) */ - 5653, /* 2F839 (194617) */ - 5654, /* 2F83A (194618) */ - 5655, /* 2F83B (194619) */ - 5656, /* 2F83C (194620) */ - 5657, /* 2F83D (194621) */ - 5658, /* 2F83E (194622) */ - 5659, /* 2F83F (194623) */ - 5660, /* 2F840 (194624) */ - 5661, /* 2F841 (194625) */ - 5662, /* 2F842 (194626) */ - 5663, /* 2F843 (194627) */ - 5664, /* 2F844 (194628) */ - 5665, /* 2F845 (194629) */ - 5665, /* 2F846 (194630) */ - 3698, /* 2F847 (194631) */ - 5666, /* 2F848 (194632) */ - 5667, /* 2F849 (194633) */ - 5668, /* 2F84A (194634) */ - 5669, /* 2F84B (194635) */ - 3637, /* 2F84C (194636) */ - 5670, /* 2F84D (194637) */ - 5671, /* 2F84E (194638) */ - 5672, /* 2F84F (194639) */ - 3594, /* 2F850 (194640) */ - 5673, /* 2F851 (194641) */ - 5674, /* 2F852 (194642) */ - 5675, /* 2F853 (194643) */ - 5676, /* 2F854 (194644) */ - 5677, /* 2F855 (194645) */ - 5678, /* 2F856 (194646) */ - 5679, /* 2F857 (194647) */ - 5680, /* 2F858 (194648) */ - 5681, /* 2F859 (194649) */ - 5682, /* 2F85A (194650) */ - 5683, /* 2F85B (194651) */ - 5684, /* 2F85C (194652) */ - 5685, /* 2F85D (194653) */ - 5686, /* 2F85E (194654) */ - 5687, /* 2F85F (194655) */ - 5688, /* 2F860 (194656) */ - 5689, /* 2F861 (194657) */ - 5690, /* 2F862 (194658) */ - 5691, /* 2F863 (194659) */ - 5692, /* 2F864 (194660) */ - 5693, /* 2F865 (194661) */ - 5694, /* 2F866 (194662) */ - 5695, /* 2F867 (194663) */ - 5696, /* 2F868 (194664) */ - 5697, /* 2F869 (194665) */ - 5698, /* 2F86A (194666) */ - 5698, /* 2F86B (194667) */ - 5699, /* 2F86C (194668) */ - 5700, /* 2F86D (194669) */ - 5701, /* 2F86E (194670) */ - 3437, /* 2F86F (194671) */ - 5702, /* 2F870 (194672) */ - 5703, /* 2F871 (194673) */ - 5704, /* 2F872 (194674) */ - 5705, /* 2F873 (194675) */ - 5706, /* 2F874 (194676) */ - 5707, /* 2F875 (194677) */ - 5708, /* 2F876 (194678) */ - 5709, /* 2F877 (194679) */ - 3642, /* 2F878 (194680) */ - 5710, /* 2F879 (194681) */ - 5711, /* 2F87A (194682) */ - 5712, /* 2F87B (194683) */ - 5713, /* 2F87C (194684) */ - 5714, /* 2F87D (194685) */ - 5715, /* 2F87E (194686) */ - 5716, /* 2F87F (194687) */ - 5717, /* 2F880 (194688) */ - 5718, /* 2F881 (194689) */ - 5719, /* 2F882 (194690) */ - 5720, /* 2F883 (194691) */ - 5721, /* 2F884 (194692) */ - 5722, /* 2F885 (194693) */ - 5723, /* 2F886 (194694) */ - 5724, /* 2F887 (194695) */ - 5725, /* 2F888 (194696) */ - 5726, /* 2F889 (194697) */ - 5727, /* 2F88A (194698) */ - 5728, /* 2F88B (194699) */ - 5729, /* 2F88C (194700) */ - 5730, /* 2F88D (194701) */ - 3383, /* 2F88E (194702) */ - 5731, /* 2F88F (194703) */ - 5732, /* 2F890 (194704) */ - 5733, /* 2F891 (194705) */ - 5733, /* 2F892 (194706) */ - 5734, /* 2F893 (194707) */ - 5735, /* 2F894 (194708) */ - 5735, /* 2F895 (194709) */ - 5736, /* 2F896 (194710) */ - 5737, /* 2F897 (194711) */ - 5738, /* 2F898 (194712) */ - 5739, /* 2F899 (194713) */ - 5740, /* 2F89A (194714) */ - 5741, /* 2F89B (194715) */ - 5742, /* 2F89C (194716) */ - 5743, /* 2F89D (194717) */ - 5744, /* 2F89E (194718) */ - 5745, /* 2F89F (194719) */ - 5746, /* 2F8A0 (194720) */ - 5747, /* 2F8A1 (194721) */ - 5748, /* 2F8A2 (194722) */ - 3643, /* 2F8A3 (194723) */ - 5749, /* 2F8A4 (194724) */ - 5750, /* 2F8A5 (194725) */ - 5751, /* 2F8A6 (194726) */ - 5752, /* 2F8A7 (194727) */ - 3710, /* 2F8A8 (194728) */ - 5752, /* 2F8A9 (194729) */ - 5753, /* 2F8AA (194730) */ - 3645, /* 2F8AB (194731) */ - 5754, /* 2F8AC (194732) */ - 5755, /* 2F8AD (194733) */ - 5756, /* 2F8AE (194734) */ - 5757, /* 2F8AF (194735) */ - 3646, /* 2F8B0 (194736) */ - 3356, /* 2F8B1 (194737) */ - 5758, /* 2F8B2 (194738) */ - 5759, /* 2F8B3 (194739) */ - 5760, /* 2F8B4 (194740) */ - 5761, /* 2F8B5 (194741) */ - 5762, /* 2F8B6 (194742) */ - 5763, /* 2F8B7 (194743) */ - 5764, /* 2F8B8 (194744) */ - 5765, /* 2F8B9 (194745) */ - 5766, /* 2F8BA (194746) */ - 5767, /* 2F8BB (194747) */ - 5768, /* 2F8BC (194748) */ - 5769, /* 2F8BD (194749) */ - 5770, /* 2F8BE (194750) */ - 5771, /* 2F8BF (194751) */ - 5772, /* 2F8C0 (194752) */ - 5773, /* 2F8C1 (194753) */ - 5774, /* 2F8C2 (194754) */ - 5775, /* 2F8C3 (194755) */ - 5776, /* 2F8C4 (194756) */ - 5777, /* 2F8C5 (194757) */ - 5778, /* 2F8C6 (194758) */ - 5779, /* 2F8C7 (194759) */ - 3647, /* 2F8C8 (194760) */ - 5780, /* 2F8C9 (194761) */ - 5781, /* 2F8CA (194762) */ - 5782, /* 2F8CB (194763) */ - 5783, /* 2F8CC (194764) */ - 5784, /* 2F8CD (194765) */ - 5785, /* 2F8CE (194766) */ - 3649, /* 2F8CF (194767) */ - 5786, /* 2F8D0 (194768) */ - 5787, /* 2F8D1 (194769) */ - 5788, /* 2F8D2 (194770) */ - 5789, /* 2F8D3 (194771) */ - 5790, /* 2F8D4 (194772) */ - 5791, /* 2F8D5 (194773) */ - 5792, /* 2F8D6 (194774) */ - 5793, /* 2F8D7 (194775) */ - 3384, /* 2F8D8 (194776) */ - 3718, /* 2F8D9 (194777) */ - 5794, /* 2F8DA (194778) */ - 5795, /* 2F8DB (194779) */ - 5796, /* 2F8DC (194780) */ - 5797, /* 2F8DD (194781) */ - 5798, /* 2F8DE (194782) */ - 5799, /* 2F8DF (194783) */ - 5800, /* 2F8E0 (194784) */ - 5801, /* 2F8E1 (194785) */ - 3650, /* 2F8E2 (194786) */ - 5802, /* 2F8E3 (194787) */ - 5803, /* 2F8E4 (194788) */ - 5804, /* 2F8E5 (194789) */ - 5805, /* 2F8E6 (194790) */ - 3761, /* 2F8E7 (194791) */ - 5806, /* 2F8E8 (194792) */ - 5807, /* 2F8E9 (194793) */ - 5808, /* 2F8EA (194794) */ - 5809, /* 2F8EB (194795) */ - 5810, /* 2F8EC (194796) */ - 5811, /* 2F8ED (194797) */ - 5812, /* 2F8EE (194798) */ - 5813, /* 2F8EF (194799) */ - 5814, /* 2F8F0 (194800) */ - 5815, /* 2F8F1 (194801) */ - 5816, /* 2F8F2 (194802) */ - 5817, /* 2F8F3 (194803) */ - 5818, /* 2F8F4 (194804) */ - 3454, /* 2F8F5 (194805) */ - 5819, /* 2F8F6 (194806) */ - 5820, /* 2F8F7 (194807) */ - 5821, /* 2F8F8 (194808) */ - 5822, /* 2F8F9 (194809) */ - 5823, /* 2F8FA (194810) */ - 5824, /* 2F8FB (194811) */ - 5825, /* 2F8FC (194812) */ - 5826, /* 2F8FD (194813) */ - 5827, /* 2F8FE (194814) */ - 5828, /* 2F8FF (194815) */ - 5829, /* 2F900 (194816) */ - 3651, /* 2F901 (194817) */ - 3541, /* 2F902 (194818) */ - 5830, /* 2F903 (194819) */ - 5831, /* 2F904 (194820) */ - 5832, /* 2F905 (194821) */ - 5833, /* 2F906 (194822) */ - 5834, /* 2F907 (194823) */ - 5835, /* 2F908 (194824) */ - 5836, /* 2F909 (194825) */ - 5837, /* 2F90A (194826) */ - 3722, /* 2F90B (194827) */ - 5838, /* 2F90C (194828) */ - 5839, /* 2F90D (194829) */ - 5840, /* 2F90E (194830) */ - 5841, /* 2F90F (194831) */ - 5842, /* 2F910 (194832) */ - 5843, /* 2F911 (194833) */ - 5844, /* 2F912 (194834) */ - 5845, /* 2F913 (194835) */ - 3723, /* 2F914 (194836) */ - 5846, /* 2F915 (194837) */ - 5847, /* 2F916 (194838) */ - 5848, /* 2F917 (194839) */ - 5849, /* 2F918 (194840) */ - 5850, /* 2F919 (194841) */ - 5851, /* 2F91A (194842) */ - 5852, /* 2F91B (194843) */ - 5853, /* 2F91C (194844) */ - 5854, /* 2F91D (194845) */ - 5855, /* 2F91E (194846) */ - 5856, /* 2F91F (194847) */ - 5857, /* 2F920 (194848) */ - 3725, /* 2F921 (194849) */ - 5858, /* 2F922 (194850) */ - 5859, /* 2F923 (194851) */ - 5860, /* 2F924 (194852) */ - 5861, /* 2F925 (194853) */ - 5862, /* 2F926 (194854) */ - 5863, /* 2F927 (194855) */ - 5864, /* 2F928 (194856) */ - 5865, /* 2F929 (194857) */ - 5866, /* 2F92A (194858) */ - 5867, /* 2F92B (194859) */ - 5868, /* 2F92C (194860) */ - 5868, /* 2F92D (194861) */ - 5869, /* 2F92E (194862) */ - 5870, /* 2F92F (194863) */ - 3727, /* 2F930 (194864) */ - 5871, /* 2F931 (194865) */ - 5872, /* 2F932 (194866) */ - 5873, /* 2F933 (194867) */ - 5874, /* 2F934 (194868) */ - 5875, /* 2F935 (194869) */ - 5876, /* 2F936 (194870) */ - 5877, /* 2F937 (194871) */ - 3440, /* 2F938 (194872) */ - 5878, /* 2F939 (194873) */ - 5879, /* 2F93A (194874) */ - 5880, /* 2F93B (194875) */ - 5881, /* 2F93C (194876) */ - 5882, /* 2F93D (194877) */ - 5883, /* 2F93E (194878) */ - 5884, /* 2F93F (194879) */ - 3733, /* 2F940 (194880) */ - 5885, /* 2F941 (194881) */ - 5886, /* 2F942 (194882) */ - 5887, /* 2F943 (194883) */ - 5888, /* 2F944 (194884) */ - 5889, /* 2F945 (194885) */ - 5890, /* 2F946 (194886) */ - 5890, /* 2F947 (194887) */ - 3734, /* 2F948 (194888) */ - 3763, /* 2F949 (194889) */ - 5891, /* 2F94A (194890) */ - 5892, /* 2F94B (194891) */ - 5893, /* 2F94C (194892) */ - 5894, /* 2F94D (194893) */ - 5895, /* 2F94E (194894) */ - 3402, /* 2F94F (194895) */ - 3736, /* 2F950 (194896) */ - 5896, /* 2F951 (194897) */ - 5897, /* 2F952 (194898) */ - 3662, /* 2F953 (194899) */ - 5898, /* 2F954 (194900) */ - 5899, /* 2F955 (194901) */ - 3616, /* 2F956 (194902) */ - 5900, /* 2F957 (194903) */ - 5901, /* 2F958 (194904) */ - 3666, /* 2F959 (194905) */ - 5902, /* 2F95A (194906) */ - 5903, /* 2F95B (194907) */ - 5904, /* 2F95C (194908) */ - 5905, /* 2F95D (194909) */ - 5905, /* 2F95E (194910) */ - 5906, /* 2F95F (194911) */ - 5907, /* 2F960 (194912) */ - 5908, /* 2F961 (194913) */ - 5909, /* 2F962 (194914) */ - 5910, /* 2F963 (194915) */ - 5911, /* 2F964 (194916) */ - 5912, /* 2F965 (194917) */ - 5913, /* 2F966 (194918) */ - 5914, /* 2F967 (194919) */ - 5915, /* 2F968 (194920) */ - 5916, /* 2F969 (194921) */ - 5917, /* 2F96A (194922) */ - 5918, /* 2F96B (194923) */ - 5919, /* 2F96C (194924) */ - 5920, /* 2F96D (194925) */ - 5921, /* 2F96E (194926) */ - 5922, /* 2F96F (194927) */ - 5923, /* 2F970 (194928) */ - 5924, /* 2F971 (194929) */ - 5925, /* 2F972 (194930) */ - 5926, /* 2F973 (194931) */ - 5927, /* 2F974 (194932) */ - 5928, /* 2F975 (194933) */ - 5929, /* 2F976 (194934) */ - 5930, /* 2F977 (194935) */ - 5931, /* 2F978 (194936) */ - 5932, /* 2F979 (194937) */ - 3672, /* 2F97A (194938) */ - 5933, /* 2F97B (194939) */ - 5934, /* 2F97C (194940) */ - 5935, /* 2F97D (194941) */ - 5936, /* 2F97E (194942) */ - 5937, /* 2F97F (194943) */ - 5938, /* 2F980 (194944) */ - 5939, /* 2F981 (194945) */ - 5940, /* 2F982 (194946) */ - 5941, /* 2F983 (194947) */ - 5942, /* 2F984 (194948) */ - 5943, /* 2F985 (194949) */ - 5944, /* 2F986 (194950) */ - 5945, /* 2F987 (194951) */ - 5946, /* 2F988 (194952) */ - 5947, /* 2F989 (194953) */ - 5948, /* 2F98A (194954) */ - 5734, /* 2F98B (194955) */ - 5949, /* 2F98C (194956) */ - 5950, /* 2F98D (194957) */ - 5951, /* 2F98E (194958) */ - 5952, /* 2F98F (194959) */ - 5953, /* 2F990 (194960) */ - 5954, /* 2F991 (194961) */ - 5955, /* 2F992 (194962) */ - 5956, /* 2F993 (194963) */ - 5957, /* 2F994 (194964) */ - 5958, /* 2F995 (194965) */ - 5959, /* 2F996 (194966) */ - 5960, /* 2F997 (194967) */ - 3458, /* 2F998 (194968) */ - 5961, /* 2F999 (194969) */ - 5962, /* 2F99A (194970) */ - 5963, /* 2F99B (194971) */ - 5964, /* 2F99C (194972) */ - 5965, /* 2F99D (194973) */ - 5966, /* 2F99E (194974) */ - 3675, /* 2F99F (194975) */ - 5967, /* 2F9A0 (194976) */ - 5968, /* 2F9A1 (194977) */ - 5969, /* 2F9A2 (194978) */ - 5970, /* 2F9A3 (194979) */ - 5971, /* 2F9A4 (194980) */ - 5972, /* 2F9A5 (194981) */ - 5973, /* 2F9A6 (194982) */ - 5974, /* 2F9A7 (194983) */ - 5975, /* 2F9A8 (194984) */ - 5976, /* 2F9A9 (194985) */ - 5977, /* 2F9AA (194986) */ - 5978, /* 2F9AB (194987) */ - 5979, /* 2F9AC (194988) */ - 5980, /* 2F9AD (194989) */ - 5981, /* 2F9AE (194990) */ - 5982, /* 2F9AF (194991) */ - 5983, /* 2F9B0 (194992) */ - 5984, /* 2F9B1 (194993) */ - 5985, /* 2F9B2 (194994) */ - 5986, /* 2F9B3 (194995) */ - 3397, /* 2F9B4 (194996) */ - 5987, /* 2F9B5 (194997) */ - 5988, /* 2F9B6 (194998) */ - 5989, /* 2F9B7 (194999) */ - 5990, /* 2F9B8 (195000) */ - 5991, /* 2F9B9 (195001) */ - 5992, /* 2F9BA (195002) */ - 3743, /* 2F9BB (195003) */ - 5993, /* 2F9BC (195004) */ - 5994, /* 2F9BD (195005) */ - 5995, /* 2F9BE (195006) */ - 5996, /* 2F9BF (195007) */ - 5997, /* 2F9C0 (195008) */ - 5998, /* 2F9C1 (195009) */ - 5999, /* 2F9C2 (195010) */ - 6000, /* 2F9C3 (195011) */ - 6001, /* 2F9C4 (195012) */ - 6002, /* 2F9C5 (195013) */ - 6003, /* 2F9C6 (195014) */ - 6004, /* 2F9C7 (195015) */ - 6005, /* 2F9C8 (195016) */ - 6006, /* 2F9C9 (195017) */ - 6007, /* 2F9CA (195018) */ - 6008, /* 2F9CB (195019) */ - 6009, /* 2F9CC (195020) */ - 6010, /* 2F9CD (195021) */ - 6011, /* 2F9CE (195022) */ - 6012, /* 2F9CF (195023) */ - 3748, /* 2F9D0 (195024) */ - 3749, /* 2F9D1 (195025) */ - 6013, /* 2F9D2 (195026) */ - 6014, /* 2F9D3 (195027) */ - 6015, /* 2F9D4 (195028) */ - 6016, /* 2F9D5 (195029) */ - 6017, /* 2F9D6 (195030) */ - 6018, /* 2F9D7 (195031) */ - 6019, /* 2F9D8 (195032) */ - 6020, /* 2F9D9 (195033) */ - 6021, /* 2F9DA (195034) */ - 6022, /* 2F9DB (195035) */ - 6023, /* 2F9DC (195036) */ - 6024, /* 2F9DD (195037) */ - 6025, /* 2F9DE (195038) */ - 3750, /* 2F9DF (195039) */ - 6026, /* 2F9E0 (195040) */ - 6027, /* 2F9E1 (195041) */ - 6028, /* 2F9E2 (195042) */ - 6029, /* 2F9E3 (195043) */ - 6030, /* 2F9E4 (195044) */ - 6031, /* 2F9E5 (195045) */ - 6032, /* 2F9E6 (195046) */ - 6033, /* 2F9E7 (195047) */ - 6034, /* 2F9E8 (195048) */ - 6035, /* 2F9E9 (195049) */ - 6036, /* 2F9EA (195050) */ - 6037, /* 2F9EB (195051) */ - 6038, /* 2F9EC (195052) */ - 6039, /* 2F9ED (195053) */ - 6040, /* 2F9EE (195054) */ - 6041, /* 2F9EF (195055) */ - 6042, /* 2F9F0 (195056) */ - 6043, /* 2F9F1 (195057) */ - 6044, /* 2F9F2 (195058) */ - 6045, /* 2F9F3 (195059) */ - 6046, /* 2F9F4 (195060) */ - 6047, /* 2F9F5 (195061) */ - 6048, /* 2F9F6 (195062) */ - 6049, /* 2F9F7 (195063) */ - 6050, /* 2F9F8 (195064) */ - 6051, /* 2F9F9 (195065) */ - 6052, /* 2F9FA (195066) */ - 6053, /* 2F9FB (195067) */ - 6054, /* 2F9FC (195068) */ - 6055, /* 2F9FD (195069) */ - 3756, /* 2F9FE (195070) */ - 3756, /* 2F9FF (195071) */ - 6056, /* 2FA00 (195072) */ - 6057, /* 2FA01 (195073) */ - 6058, /* 2FA02 (195074) */ - 6059, /* 2FA03 (195075) */ - 6060, /* 2FA04 (195076) */ - 6061, /* 2FA05 (195077) */ - 6062, /* 2FA06 (195078) */ - 6063, /* 2FA07 (195079) */ - 6064, /* 2FA08 (195080) */ - 6065, /* 2FA09 (195081) */ - 3757, /* 2FA0A (195082) */ - 6066, /* 2FA0B (195083) */ - 6067, /* 2FA0C (195084) */ - 6068, /* 2FA0D (195085) */ - 6069, /* 2FA0E (195086) */ - 6070, /* 2FA0F (195087) */ - 6071, /* 2FA10 (195088) */ - 6072, /* 2FA11 (195089) */ - 6073, /* 2FA12 (195090) */ - 6074, /* 2FA13 (195091) */ - 6075, /* 2FA14 (195092) */ - 6076, /* 2FA15 (195093) */ - 6077, /* 2FA16 (195094) */ - 6078, /* 2FA17 (195095) */ - 6079, /* 2FA18 (195096) */ - 6080, /* 2FA19 (195097) */ - 6081, /* 2FA1A (195098) */ - 6082, /* 2FA1B (195099) */ - 6083, /* 2FA1C (195100) */ - 6084, /* 2FA1D (195101) */ + 5637, /* 2F800 (194560) */ + 5638, /* 2F801 (194561) */ + 5639, /* 2F802 (194562) */ + 5640, /* 2F803 (194563) */ + 5641, /* 2F804 (194564) */ + 3634, /* 2F805 (194565) */ + 5642, /* 2F806 (194566) */ + 5643, /* 2F807 (194567) */ + 5644, /* 2F808 (194568) */ + 5645, /* 2F809 (194569) */ + 3635, /* 2F80A (194570) */ + 5646, /* 2F80B (194571) */ + 5647, /* 2F80C (194572) */ + 5648, /* 2F80D (194573) */ + 3636, /* 2F80E (194574) */ + 5649, /* 2F80F (194575) */ + 5650, /* 2F810 (194576) */ + 5651, /* 2F811 (194577) */ + 5652, /* 2F812 (194578) */ + 5653, /* 2F813 (194579) */ + 5654, /* 2F814 (194580) */ + 5655, /* 2F815 (194581) */ + 5656, /* 2F816 (194582) */ + 5657, /* 2F817 (194583) */ + 5658, /* 2F818 (194584) */ + 5659, /* 2F819 (194585) */ + 5660, /* 2F81A (194586) */ + 3694, /* 2F81B (194587) */ + 5661, /* 2F81C (194588) */ + 5662, /* 2F81D (194589) */ + 5663, /* 2F81E (194590) */ + 5664, /* 2F81F (194591) */ + 5665, /* 2F820 (194592) */ + 5666, /* 2F821 (194593) */ + 5667, /* 2F822 (194594) */ + 5668, /* 2F823 (194595) */ + 5669, /* 2F824 (194596) */ + 3699, /* 2F825 (194597) */ + 3637, /* 2F826 (194598) */ + 3638, /* 2F827 (194599) */ + 3700, /* 2F828 (194600) */ + 5670, /* 2F829 (194601) */ + 5671, /* 2F82A (194602) */ + 3445, /* 2F82B (194603) */ + 5672, /* 2F82C (194604) */ + 3639, /* 2F82D (194605) */ + 5673, /* 2F82E (194606) */ + 5674, /* 2F82F (194607) */ + 5675, /* 2F830 (194608) */ + 5676, /* 2F831 (194609) */ + 5676, /* 2F832 (194610) */ + 5676, /* 2F833 (194611) */ + 5677, /* 2F834 (194612) */ + 5678, /* 2F835 (194613) */ + 5679, /* 2F836 (194614) */ + 5680, /* 2F837 (194615) */ + 5681, /* 2F838 (194616) */ + 5682, /* 2F839 (194617) */ + 5683, /* 2F83A (194618) */ + 5684, /* 2F83B (194619) */ + 5685, /* 2F83C (194620) */ + 5686, /* 2F83D (194621) */ + 5687, /* 2F83E (194622) */ + 5688, /* 2F83F (194623) */ + 5689, /* 2F840 (194624) */ + 5690, /* 2F841 (194625) */ + 5691, /* 2F842 (194626) */ + 5692, /* 2F843 (194627) */ + 5693, /* 2F844 (194628) */ + 5694, /* 2F845 (194629) */ + 5694, /* 2F846 (194630) */ + 3702, /* 2F847 (194631) */ + 5695, /* 2F848 (194632) */ + 5696, /* 2F849 (194633) */ + 5697, /* 2F84A (194634) */ + 5698, /* 2F84B (194635) */ + 3641, /* 2F84C (194636) */ + 5699, /* 2F84D (194637) */ + 5700, /* 2F84E (194638) */ + 5701, /* 2F84F (194639) */ + 3598, /* 2F850 (194640) */ + 5702, /* 2F851 (194641) */ + 5703, /* 2F852 (194642) */ + 5704, /* 2F853 (194643) */ + 5705, /* 2F854 (194644) */ + 5706, /* 2F855 (194645) */ + 5707, /* 2F856 (194646) */ + 5708, /* 2F857 (194647) */ + 5709, /* 2F858 (194648) */ + 5710, /* 2F859 (194649) */ + 5711, /* 2F85A (194650) */ + 5712, /* 2F85B (194651) */ + 5713, /* 2F85C (194652) */ + 5714, /* 2F85D (194653) */ + 5715, /* 2F85E (194654) */ + 5716, /* 2F85F (194655) */ + 5717, /* 2F860 (194656) */ + 5718, /* 2F861 (194657) */ + 5719, /* 2F862 (194658) */ + 5720, /* 2F863 (194659) */ + 5721, /* 2F864 (194660) */ + 5722, /* 2F865 (194661) */ + 5723, /* 2F866 (194662) */ + 5724, /* 2F867 (194663) */ + 5725, /* 2F868 (194664) */ + 5726, /* 2F869 (194665) */ + 5727, /* 2F86A (194666) */ + 5727, /* 2F86B (194667) */ + 5728, /* 2F86C (194668) */ + 5729, /* 2F86D (194669) */ + 5730, /* 2F86E (194670) */ + 3441, /* 2F86F (194671) */ + 5731, /* 2F870 (194672) */ + 5732, /* 2F871 (194673) */ + 5733, /* 2F872 (194674) */ + 5734, /* 2F873 (194675) */ + 5735, /* 2F874 (194676) */ + 5736, /* 2F875 (194677) */ + 5737, /* 2F876 (194678) */ + 5738, /* 2F877 (194679) */ + 3646, /* 2F878 (194680) */ + 5739, /* 2F879 (194681) */ + 5740, /* 2F87A (194682) */ + 5741, /* 2F87B (194683) */ + 5742, /* 2F87C (194684) */ + 5743, /* 2F87D (194685) */ + 5744, /* 2F87E (194686) */ + 5745, /* 2F87F (194687) */ + 5746, /* 2F880 (194688) */ + 5747, /* 2F881 (194689) */ + 5748, /* 2F882 (194690) */ + 5749, /* 2F883 (194691) */ + 5750, /* 2F884 (194692) */ + 5751, /* 2F885 (194693) */ + 5752, /* 2F886 (194694) */ + 5753, /* 2F887 (194695) */ + 5754, /* 2F888 (194696) */ + 5755, /* 2F889 (194697) */ + 5756, /* 2F88A (194698) */ + 5757, /* 2F88B (194699) */ + 5758, /* 2F88C (194700) */ + 5759, /* 2F88D (194701) */ + 3387, /* 2F88E (194702) */ + 5760, /* 2F88F (194703) */ + 5761, /* 2F890 (194704) */ + 5762, /* 2F891 (194705) */ + 5762, /* 2F892 (194706) */ + 5763, /* 2F893 (194707) */ + 5764, /* 2F894 (194708) */ + 5764, /* 2F895 (194709) */ + 5765, /* 2F896 (194710) */ + 5766, /* 2F897 (194711) */ + 5767, /* 2F898 (194712) */ + 5768, /* 2F899 (194713) */ + 5769, /* 2F89A (194714) */ + 5770, /* 2F89B (194715) */ + 5771, /* 2F89C (194716) */ + 5772, /* 2F89D (194717) */ + 5773, /* 2F89E (194718) */ + 5774, /* 2F89F (194719) */ + 5775, /* 2F8A0 (194720) */ + 5776, /* 2F8A1 (194721) */ + 5777, /* 2F8A2 (194722) */ + 3647, /* 2F8A3 (194723) */ + 5778, /* 2F8A4 (194724) */ + 5779, /* 2F8A5 (194725) */ + 5780, /* 2F8A6 (194726) */ + 5781, /* 2F8A7 (194727) */ + 3714, /* 2F8A8 (194728) */ + 5781, /* 2F8A9 (194729) */ + 5782, /* 2F8AA (194730) */ + 3649, /* 2F8AB (194731) */ + 5783, /* 2F8AC (194732) */ + 5784, /* 2F8AD (194733) */ + 5785, /* 2F8AE (194734) */ + 5786, /* 2F8AF (194735) */ + 3650, /* 2F8B0 (194736) */ + 3360, /* 2F8B1 (194737) */ + 5787, /* 2F8B2 (194738) */ + 5788, /* 2F8B3 (194739) */ + 5789, /* 2F8B4 (194740) */ + 5790, /* 2F8B5 (194741) */ + 5791, /* 2F8B6 (194742) */ + 5792, /* 2F8B7 (194743) */ + 5793, /* 2F8B8 (194744) */ + 5794, /* 2F8B9 (194745) */ + 5795, /* 2F8BA (194746) */ + 5796, /* 2F8BB (194747) */ + 5797, /* 2F8BC (194748) */ + 5798, /* 2F8BD (194749) */ + 5799, /* 2F8BE (194750) */ + 5800, /* 2F8BF (194751) */ + 5801, /* 2F8C0 (194752) */ + 5802, /* 2F8C1 (194753) */ + 5803, /* 2F8C2 (194754) */ + 5804, /* 2F8C3 (194755) */ + 5805, /* 2F8C4 (194756) */ + 5806, /* 2F8C5 (194757) */ + 5807, /* 2F8C6 (194758) */ + 5808, /* 2F8C7 (194759) */ + 3651, /* 2F8C8 (194760) */ + 5809, /* 2F8C9 (194761) */ + 5810, /* 2F8CA (194762) */ + 5811, /* 2F8CB (194763) */ + 5812, /* 2F8CC (194764) */ + 5813, /* 2F8CD (194765) */ + 5814, /* 2F8CE (194766) */ + 3653, /* 2F8CF (194767) */ + 5815, /* 2F8D0 (194768) */ + 5816, /* 2F8D1 (194769) */ + 5817, /* 2F8D2 (194770) */ + 5818, /* 2F8D3 (194771) */ + 5819, /* 2F8D4 (194772) */ + 5820, /* 2F8D5 (194773) */ + 5821, /* 2F8D6 (194774) */ + 5822, /* 2F8D7 (194775) */ + 3388, /* 2F8D8 (194776) */ + 3722, /* 2F8D9 (194777) */ + 5823, /* 2F8DA (194778) */ + 5824, /* 2F8DB (194779) */ + 5825, /* 2F8DC (194780) */ + 5826, /* 2F8DD (194781) */ + 5827, /* 2F8DE (194782) */ + 5828, /* 2F8DF (194783) */ + 5829, /* 2F8E0 (194784) */ + 5830, /* 2F8E1 (194785) */ + 3654, /* 2F8E2 (194786) */ + 5831, /* 2F8E3 (194787) */ + 5832, /* 2F8E4 (194788) */ + 5833, /* 2F8E5 (194789) */ + 5834, /* 2F8E6 (194790) */ + 3765, /* 2F8E7 (194791) */ + 5835, /* 2F8E8 (194792) */ + 5836, /* 2F8E9 (194793) */ + 5837, /* 2F8EA (194794) */ + 5838, /* 2F8EB (194795) */ + 5839, /* 2F8EC (194796) */ + 5840, /* 2F8ED (194797) */ + 5841, /* 2F8EE (194798) */ + 5842, /* 2F8EF (194799) */ + 5843, /* 2F8F0 (194800) */ + 5844, /* 2F8F1 (194801) */ + 5845, /* 2F8F2 (194802) */ + 5846, /* 2F8F3 (194803) */ + 5847, /* 2F8F4 (194804) */ + 3458, /* 2F8F5 (194805) */ + 5848, /* 2F8F6 (194806) */ + 5849, /* 2F8F7 (194807) */ + 5850, /* 2F8F8 (194808) */ + 5851, /* 2F8F9 (194809) */ + 5852, /* 2F8FA (194810) */ + 5853, /* 2F8FB (194811) */ + 5854, /* 2F8FC (194812) */ + 5855, /* 2F8FD (194813) */ + 5856, /* 2F8FE (194814) */ + 5857, /* 2F8FF (194815) */ + 5858, /* 2F900 (194816) */ + 3655, /* 2F901 (194817) */ + 3545, /* 2F902 (194818) */ + 5859, /* 2F903 (194819) */ + 5860, /* 2F904 (194820) */ + 5861, /* 2F905 (194821) */ + 5862, /* 2F906 (194822) */ + 5863, /* 2F907 (194823) */ + 5864, /* 2F908 (194824) */ + 5865, /* 2F909 (194825) */ + 5866, /* 2F90A (194826) */ + 3726, /* 2F90B (194827) */ + 5867, /* 2F90C (194828) */ + 5868, /* 2F90D (194829) */ + 5869, /* 2F90E (194830) */ + 5870, /* 2F90F (194831) */ + 5871, /* 2F910 (194832) */ + 5872, /* 2F911 (194833) */ + 5873, /* 2F912 (194834) */ + 5874, /* 2F913 (194835) */ + 3727, /* 2F914 (194836) */ + 5875, /* 2F915 (194837) */ + 5876, /* 2F916 (194838) */ + 5877, /* 2F917 (194839) */ + 5878, /* 2F918 (194840) */ + 5879, /* 2F919 (194841) */ + 5880, /* 2F91A (194842) */ + 5881, /* 2F91B (194843) */ + 5882, /* 2F91C (194844) */ + 5883, /* 2F91D (194845) */ + 5884, /* 2F91E (194846) */ + 5885, /* 2F91F (194847) */ + 5886, /* 2F920 (194848) */ + 3729, /* 2F921 (194849) */ + 5887, /* 2F922 (194850) */ + 5888, /* 2F923 (194851) */ + 5889, /* 2F924 (194852) */ + 5890, /* 2F925 (194853) */ + 5891, /* 2F926 (194854) */ + 5892, /* 2F927 (194855) */ + 5893, /* 2F928 (194856) */ + 5894, /* 2F929 (194857) */ + 5895, /* 2F92A (194858) */ + 5896, /* 2F92B (194859) */ + 5897, /* 2F92C (194860) */ + 5897, /* 2F92D (194861) */ + 5898, /* 2F92E (194862) */ + 5899, /* 2F92F (194863) */ + 3731, /* 2F930 (194864) */ + 5900, /* 2F931 (194865) */ + 5901, /* 2F932 (194866) */ + 5902, /* 2F933 (194867) */ + 5903, /* 2F934 (194868) */ + 5904, /* 2F935 (194869) */ + 5905, /* 2F936 (194870) */ + 5906, /* 2F937 (194871) */ + 3444, /* 2F938 (194872) */ + 5907, /* 2F939 (194873) */ + 5908, /* 2F93A (194874) */ + 5909, /* 2F93B (194875) */ + 5910, /* 2F93C (194876) */ + 5911, /* 2F93D (194877) */ + 5912, /* 2F93E (194878) */ + 5913, /* 2F93F (194879) */ + 3737, /* 2F940 (194880) */ + 5914, /* 2F941 (194881) */ + 5915, /* 2F942 (194882) */ + 5916, /* 2F943 (194883) */ + 5917, /* 2F944 (194884) */ + 5918, /* 2F945 (194885) */ + 5919, /* 2F946 (194886) */ + 5919, /* 2F947 (194887) */ + 3738, /* 2F948 (194888) */ + 3767, /* 2F949 (194889) */ + 5920, /* 2F94A (194890) */ + 5921, /* 2F94B (194891) */ + 5922, /* 2F94C (194892) */ + 5923, /* 2F94D (194893) */ + 5924, /* 2F94E (194894) */ + 3406, /* 2F94F (194895) */ + 3740, /* 2F950 (194896) */ + 5925, /* 2F951 (194897) */ + 5926, /* 2F952 (194898) */ + 3666, /* 2F953 (194899) */ + 5927, /* 2F954 (194900) */ + 5928, /* 2F955 (194901) */ + 3620, /* 2F956 (194902) */ + 5929, /* 2F957 (194903) */ + 5930, /* 2F958 (194904) */ + 3670, /* 2F959 (194905) */ + 5931, /* 2F95A (194906) */ + 5932, /* 2F95B (194907) */ + 5933, /* 2F95C (194908) */ + 5934, /* 2F95D (194909) */ + 5934, /* 2F95E (194910) */ + 5935, /* 2F95F (194911) */ + 5936, /* 2F960 (194912) */ + 5937, /* 2F961 (194913) */ + 5938, /* 2F962 (194914) */ + 5939, /* 2F963 (194915) */ + 5940, /* 2F964 (194916) */ + 5941, /* 2F965 (194917) */ + 5942, /* 2F966 (194918) */ + 5943, /* 2F967 (194919) */ + 5944, /* 2F968 (194920) */ + 5945, /* 2F969 (194921) */ + 5946, /* 2F96A (194922) */ + 5947, /* 2F96B (194923) */ + 5948, /* 2F96C (194924) */ + 5949, /* 2F96D (194925) */ + 5950, /* 2F96E (194926) */ + 5951, /* 2F96F (194927) */ + 5952, /* 2F970 (194928) */ + 5953, /* 2F971 (194929) */ + 5954, /* 2F972 (194930) */ + 5955, /* 2F973 (194931) */ + 5956, /* 2F974 (194932) */ + 5957, /* 2F975 (194933) */ + 5958, /* 2F976 (194934) */ + 5959, /* 2F977 (194935) */ + 5960, /* 2F978 (194936) */ + 5961, /* 2F979 (194937) */ + 3676, /* 2F97A (194938) */ + 5962, /* 2F97B (194939) */ + 5963, /* 2F97C (194940) */ + 5964, /* 2F97D (194941) */ + 5965, /* 2F97E (194942) */ + 5966, /* 2F97F (194943) */ + 5967, /* 2F980 (194944) */ + 5968, /* 2F981 (194945) */ + 5969, /* 2F982 (194946) */ + 5970, /* 2F983 (194947) */ + 5971, /* 2F984 (194948) */ + 5972, /* 2F985 (194949) */ + 5973, /* 2F986 (194950) */ + 5974, /* 2F987 (194951) */ + 5975, /* 2F988 (194952) */ + 5976, /* 2F989 (194953) */ + 5977, /* 2F98A (194954) */ + 5763, /* 2F98B (194955) */ + 5978, /* 2F98C (194956) */ + 5979, /* 2F98D (194957) */ + 5980, /* 2F98E (194958) */ + 5981, /* 2F98F (194959) */ + 5982, /* 2F990 (194960) */ + 5983, /* 2F991 (194961) */ + 5984, /* 2F992 (194962) */ + 5985, /* 2F993 (194963) */ + 5986, /* 2F994 (194964) */ + 5987, /* 2F995 (194965) */ + 5988, /* 2F996 (194966) */ + 5989, /* 2F997 (194967) */ + 3462, /* 2F998 (194968) */ + 5990, /* 2F999 (194969) */ + 5991, /* 2F99A (194970) */ + 5992, /* 2F99B (194971) */ + 5993, /* 2F99C (194972) */ + 5994, /* 2F99D (194973) */ + 5995, /* 2F99E (194974) */ + 3679, /* 2F99F (194975) */ + 5996, /* 2F9A0 (194976) */ + 5997, /* 2F9A1 (194977) */ + 5998, /* 2F9A2 (194978) */ + 5999, /* 2F9A3 (194979) */ + 6000, /* 2F9A4 (194980) */ + 6001, /* 2F9A5 (194981) */ + 6002, /* 2F9A6 (194982) */ + 6003, /* 2F9A7 (194983) */ + 6004, /* 2F9A8 (194984) */ + 6005, /* 2F9A9 (194985) */ + 6006, /* 2F9AA (194986) */ + 6007, /* 2F9AB (194987) */ + 6008, /* 2F9AC (194988) */ + 6009, /* 2F9AD (194989) */ + 6010, /* 2F9AE (194990) */ + 6011, /* 2F9AF (194991) */ + 6012, /* 2F9B0 (194992) */ + 6013, /* 2F9B1 (194993) */ + 6014, /* 2F9B2 (194994) */ + 6015, /* 2F9B3 (194995) */ + 3401, /* 2F9B4 (194996) */ + 6016, /* 2F9B5 (194997) */ + 6017, /* 2F9B6 (194998) */ + 6018, /* 2F9B7 (194999) */ + 6019, /* 2F9B8 (195000) */ + 6020, /* 2F9B9 (195001) */ + 6021, /* 2F9BA (195002) */ + 3747, /* 2F9BB (195003) */ + 6022, /* 2F9BC (195004) */ + 6023, /* 2F9BD (195005) */ + 6024, /* 2F9BE (195006) */ + 6025, /* 2F9BF (195007) */ + 6026, /* 2F9C0 (195008) */ + 6027, /* 2F9C1 (195009) */ + 6028, /* 2F9C2 (195010) */ + 6029, /* 2F9C3 (195011) */ + 6030, /* 2F9C4 (195012) */ + 6031, /* 2F9C5 (195013) */ + 6032, /* 2F9C6 (195014) */ + 6033, /* 2F9C7 (195015) */ + 6034, /* 2F9C8 (195016) */ + 6035, /* 2F9C9 (195017) */ + 6036, /* 2F9CA (195018) */ + 6037, /* 2F9CB (195019) */ + 6038, /* 2F9CC (195020) */ + 6039, /* 2F9CD (195021) */ + 6040, /* 2F9CE (195022) */ + 6041, /* 2F9CF (195023) */ + 3752, /* 2F9D0 (195024) */ + 3753, /* 2F9D1 (195025) */ + 6042, /* 2F9D2 (195026) */ + 6043, /* 2F9D3 (195027) */ + 6044, /* 2F9D4 (195028) */ + 6045, /* 2F9D5 (195029) */ + 6046, /* 2F9D6 (195030) */ + 6047, /* 2F9D7 (195031) */ + 6048, /* 2F9D8 (195032) */ + 6049, /* 2F9D9 (195033) */ + 6050, /* 2F9DA (195034) */ + 6051, /* 2F9DB (195035) */ + 6052, /* 2F9DC (195036) */ + 6053, /* 2F9DD (195037) */ + 6054, /* 2F9DE (195038) */ + 3754, /* 2F9DF (195039) */ + 6055, /* 2F9E0 (195040) */ + 6056, /* 2F9E1 (195041) */ + 6057, /* 2F9E2 (195042) */ + 6058, /* 2F9E3 (195043) */ + 6059, /* 2F9E4 (195044) */ + 6060, /* 2F9E5 (195045) */ + 6061, /* 2F9E6 (195046) */ + 6062, /* 2F9E7 (195047) */ + 6063, /* 2F9E8 (195048) */ + 6064, /* 2F9E9 (195049) */ + 6065, /* 2F9EA (195050) */ + 6066, /* 2F9EB (195051) */ + 6067, /* 2F9EC (195052) */ + 6068, /* 2F9ED (195053) */ + 6069, /* 2F9EE (195054) */ + 6070, /* 2F9EF (195055) */ + 6071, /* 2F9F0 (195056) */ + 6072, /* 2F9F1 (195057) */ + 6073, /* 2F9F2 (195058) */ + 6074, /* 2F9F3 (195059) */ + 6075, /* 2F9F4 (195060) */ + 6076, /* 2F9F5 (195061) */ + 6077, /* 2F9F6 (195062) */ + 6078, /* 2F9F7 (195063) */ + 6079, /* 2F9F8 (195064) */ + 6080, /* 2F9F9 (195065) */ + 6081, /* 2F9FA (195066) */ + 6082, /* 2F9FB (195067) */ + 6083, /* 2F9FC (195068) */ + 6084, /* 2F9FD (195069) */ + 3760, /* 2F9FE (195070) */ + 3760, /* 2F9FF (195071) */ + 6085, /* 2FA00 (195072) */ + 6086, /* 2FA01 (195073) */ + 6087, /* 2FA02 (195074) */ + 6088, /* 2FA03 (195075) */ + 6089, /* 2FA04 (195076) */ + 6090, /* 2FA05 (195077) */ + 6091, /* 2FA06 (195078) */ + 6092, /* 2FA07 (195079) */ + 6093, /* 2FA08 (195080) */ + 6094, /* 2FA09 (195081) */ + 3761, /* 2FA0A (195082) */ + 6095, /* 2FA0B (195083) */ + 6096, /* 2FA0C (195084) */ + 6097, /* 2FA0D (195085) */ + 6098, /* 2FA0E (195086) */ + 6099, /* 2FA0F (195087) */ + 6100, /* 2FA10 (195088) */ + 6101, /* 2FA11 (195089) */ + 6102, /* 2FA12 (195090) */ + 6103, /* 2FA13 (195091) */ + 6104, /* 2FA14 (195092) */ + 6105, /* 2FA15 (195093) */ + 6106, /* 2FA16 (195094) */ + 6107, /* 2FA17 (195095) */ + 6108, /* 2FA18 (195096) */ + 6109, /* 2FA19 (195097) */ + 6110, /* 2FA1A (195098) */ + 6111, /* 2FA1B (195099) */ + 6112, /* 2FA1C (195100) */ + 6113, /* 2FA1D (195101) */ 56, /* 2FA1E (195102) */ 56, /* 2FA1F (195103) */ 56, /* 2FA20 (195104) */ @@ -183606,6 +183840,4304 @@ static const uint32_t lxb_unicode_table_map_110576_205744[95168] = 1, /* 323AD (205741) */ 1, /* 323AE (205742) */ 1, /* 323AF (205743) */ + 1, /* 323B0 (205744) */ + 1, /* 323B1 (205745) */ + 1, /* 323B2 (205746) */ + 1, /* 323B3 (205747) */ + 1, /* 323B4 (205748) */ + 1, /* 323B5 (205749) */ + 1, /* 323B6 (205750) */ + 1, /* 323B7 (205751) */ + 1, /* 323B8 (205752) */ + 1, /* 323B9 (205753) */ + 1, /* 323BA (205754) */ + 1, /* 323BB (205755) */ + 1, /* 323BC (205756) */ + 1, /* 323BD (205757) */ + 1, /* 323BE (205758) */ + 1, /* 323BF (205759) */ + 1, /* 323C0 (205760) */ + 1, /* 323C1 (205761) */ + 1, /* 323C2 (205762) */ + 1, /* 323C3 (205763) */ + 1, /* 323C4 (205764) */ + 1, /* 323C5 (205765) */ + 1, /* 323C6 (205766) */ + 1, /* 323C7 (205767) */ + 1, /* 323C8 (205768) */ + 1, /* 323C9 (205769) */ + 1, /* 323CA (205770) */ + 1, /* 323CB (205771) */ + 1, /* 323CC (205772) */ + 1, /* 323CD (205773) */ + 1, /* 323CE (205774) */ + 1, /* 323CF (205775) */ + 1, /* 323D0 (205776) */ + 1, /* 323D1 (205777) */ + 1, /* 323D2 (205778) */ + 1, /* 323D3 (205779) */ + 1, /* 323D4 (205780) */ + 1, /* 323D5 (205781) */ + 1, /* 323D6 (205782) */ + 1, /* 323D7 (205783) */ + 1, /* 323D8 (205784) */ + 1, /* 323D9 (205785) */ + 1, /* 323DA (205786) */ + 1, /* 323DB (205787) */ + 1, /* 323DC (205788) */ + 1, /* 323DD (205789) */ + 1, /* 323DE (205790) */ + 1, /* 323DF (205791) */ + 1, /* 323E0 (205792) */ + 1, /* 323E1 (205793) */ + 1, /* 323E2 (205794) */ + 1, /* 323E3 (205795) */ + 1, /* 323E4 (205796) */ + 1, /* 323E5 (205797) */ + 1, /* 323E6 (205798) */ + 1, /* 323E7 (205799) */ + 1, /* 323E8 (205800) */ + 1, /* 323E9 (205801) */ + 1, /* 323EA (205802) */ + 1, /* 323EB (205803) */ + 1, /* 323EC (205804) */ + 1, /* 323ED (205805) */ + 1, /* 323EE (205806) */ + 1, /* 323EF (205807) */ + 1, /* 323F0 (205808) */ + 1, /* 323F1 (205809) */ + 1, /* 323F2 (205810) */ + 1, /* 323F3 (205811) */ + 1, /* 323F4 (205812) */ + 1, /* 323F5 (205813) */ + 1, /* 323F6 (205814) */ + 1, /* 323F7 (205815) */ + 1, /* 323F8 (205816) */ + 1, /* 323F9 (205817) */ + 1, /* 323FA (205818) */ + 1, /* 323FB (205819) */ + 1, /* 323FC (205820) */ + 1, /* 323FD (205821) */ + 1, /* 323FE (205822) */ + 1, /* 323FF (205823) */ + 1, /* 32400 (205824) */ + 1, /* 32401 (205825) */ + 1, /* 32402 (205826) */ + 1, /* 32403 (205827) */ + 1, /* 32404 (205828) */ + 1, /* 32405 (205829) */ + 1, /* 32406 (205830) */ + 1, /* 32407 (205831) */ + 1, /* 32408 (205832) */ + 1, /* 32409 (205833) */ + 1, /* 3240A (205834) */ + 1, /* 3240B (205835) */ + 1, /* 3240C (205836) */ + 1, /* 3240D (205837) */ + 1, /* 3240E (205838) */ + 1, /* 3240F (205839) */ + 1, /* 32410 (205840) */ + 1, /* 32411 (205841) */ + 1, /* 32412 (205842) */ + 1, /* 32413 (205843) */ + 1, /* 32414 (205844) */ + 1, /* 32415 (205845) */ + 1, /* 32416 (205846) */ + 1, /* 32417 (205847) */ + 1, /* 32418 (205848) */ + 1, /* 32419 (205849) */ + 1, /* 3241A (205850) */ + 1, /* 3241B (205851) */ + 1, /* 3241C (205852) */ + 1, /* 3241D (205853) */ + 1, /* 3241E (205854) */ + 1, /* 3241F (205855) */ + 1, /* 32420 (205856) */ + 1, /* 32421 (205857) */ + 1, /* 32422 (205858) */ + 1, /* 32423 (205859) */ + 1, /* 32424 (205860) */ + 1, /* 32425 (205861) */ + 1, /* 32426 (205862) */ + 1, /* 32427 (205863) */ + 1, /* 32428 (205864) */ + 1, /* 32429 (205865) */ + 1, /* 3242A (205866) */ + 1, /* 3242B (205867) */ + 1, /* 3242C (205868) */ + 1, /* 3242D (205869) */ + 1, /* 3242E (205870) */ + 1, /* 3242F (205871) */ + 1, /* 32430 (205872) */ + 1, /* 32431 (205873) */ + 1, /* 32432 (205874) */ + 1, /* 32433 (205875) */ + 1, /* 32434 (205876) */ + 1, /* 32435 (205877) */ + 1, /* 32436 (205878) */ + 1, /* 32437 (205879) */ + 1, /* 32438 (205880) */ + 1, /* 32439 (205881) */ + 1, /* 3243A (205882) */ + 1, /* 3243B (205883) */ + 1, /* 3243C (205884) */ + 1, /* 3243D (205885) */ + 1, /* 3243E (205886) */ + 1, /* 3243F (205887) */ + 1, /* 32440 (205888) */ + 1, /* 32441 (205889) */ + 1, /* 32442 (205890) */ + 1, /* 32443 (205891) */ + 1, /* 32444 (205892) */ + 1, /* 32445 (205893) */ + 1, /* 32446 (205894) */ + 1, /* 32447 (205895) */ + 1, /* 32448 (205896) */ + 1, /* 32449 (205897) */ + 1, /* 3244A (205898) */ + 1, /* 3244B (205899) */ + 1, /* 3244C (205900) */ + 1, /* 3244D (205901) */ + 1, /* 3244E (205902) */ + 1, /* 3244F (205903) */ + 1, /* 32450 (205904) */ + 1, /* 32451 (205905) */ + 1, /* 32452 (205906) */ + 1, /* 32453 (205907) */ + 1, /* 32454 (205908) */ + 1, /* 32455 (205909) */ + 1, /* 32456 (205910) */ + 1, /* 32457 (205911) */ + 1, /* 32458 (205912) */ + 1, /* 32459 (205913) */ + 1, /* 3245A (205914) */ + 1, /* 3245B (205915) */ + 1, /* 3245C (205916) */ + 1, /* 3245D (205917) */ + 1, /* 3245E (205918) */ + 1, /* 3245F (205919) */ + 1, /* 32460 (205920) */ + 1, /* 32461 (205921) */ + 1, /* 32462 (205922) */ + 1, /* 32463 (205923) */ + 1, /* 32464 (205924) */ + 1, /* 32465 (205925) */ + 1, /* 32466 (205926) */ + 1, /* 32467 (205927) */ + 1, /* 32468 (205928) */ + 1, /* 32469 (205929) */ + 1, /* 3246A (205930) */ + 1, /* 3246B (205931) */ + 1, /* 3246C (205932) */ + 1, /* 3246D (205933) */ + 1, /* 3246E (205934) */ + 1, /* 3246F (205935) */ + 1, /* 32470 (205936) */ + 1, /* 32471 (205937) */ + 1, /* 32472 (205938) */ + 1, /* 32473 (205939) */ + 1, /* 32474 (205940) */ + 1, /* 32475 (205941) */ + 1, /* 32476 (205942) */ + 1, /* 32477 (205943) */ + 1, /* 32478 (205944) */ + 1, /* 32479 (205945) */ + 1, /* 3247A (205946) */ + 1, /* 3247B (205947) */ + 1, /* 3247C (205948) */ + 1, /* 3247D (205949) */ + 1, /* 3247E (205950) */ + 1, /* 3247F (205951) */ + 1, /* 32480 (205952) */ + 1, /* 32481 (205953) */ + 1, /* 32482 (205954) */ + 1, /* 32483 (205955) */ + 1, /* 32484 (205956) */ + 1, /* 32485 (205957) */ + 1, /* 32486 (205958) */ + 1, /* 32487 (205959) */ + 1, /* 32488 (205960) */ + 1, /* 32489 (205961) */ + 1, /* 3248A (205962) */ + 1, /* 3248B (205963) */ + 1, /* 3248C (205964) */ + 1, /* 3248D (205965) */ + 1, /* 3248E (205966) */ + 1, /* 3248F (205967) */ + 1, /* 32490 (205968) */ + 1, /* 32491 (205969) */ + 1, /* 32492 (205970) */ + 1, /* 32493 (205971) */ + 1, /* 32494 (205972) */ + 1, /* 32495 (205973) */ + 1, /* 32496 (205974) */ + 1, /* 32497 (205975) */ + 1, /* 32498 (205976) */ + 1, /* 32499 (205977) */ + 1, /* 3249A (205978) */ + 1, /* 3249B (205979) */ + 1, /* 3249C (205980) */ + 1, /* 3249D (205981) */ + 1, /* 3249E (205982) */ + 1, /* 3249F (205983) */ + 1, /* 324A0 (205984) */ + 1, /* 324A1 (205985) */ + 1, /* 324A2 (205986) */ + 1, /* 324A3 (205987) */ + 1, /* 324A4 (205988) */ + 1, /* 324A5 (205989) */ + 1, /* 324A6 (205990) */ + 1, /* 324A7 (205991) */ + 1, /* 324A8 (205992) */ + 1, /* 324A9 (205993) */ + 1, /* 324AA (205994) */ + 1, /* 324AB (205995) */ + 1, /* 324AC (205996) */ + 1, /* 324AD (205997) */ + 1, /* 324AE (205998) */ + 1, /* 324AF (205999) */ + 1, /* 324B0 (206000) */ + 1, /* 324B1 (206001) */ + 1, /* 324B2 (206002) */ + 1, /* 324B3 (206003) */ + 1, /* 324B4 (206004) */ + 1, /* 324B5 (206005) */ + 1, /* 324B6 (206006) */ + 1, /* 324B7 (206007) */ + 1, /* 324B8 (206008) */ + 1, /* 324B9 (206009) */ + 1, /* 324BA (206010) */ + 1, /* 324BB (206011) */ + 1, /* 324BC (206012) */ + 1, /* 324BD (206013) */ + 1, /* 324BE (206014) */ + 1, /* 324BF (206015) */ + 1, /* 324C0 (206016) */ + 1, /* 324C1 (206017) */ + 1, /* 324C2 (206018) */ + 1, /* 324C3 (206019) */ + 1, /* 324C4 (206020) */ + 1, /* 324C5 (206021) */ + 1, /* 324C6 (206022) */ + 1, /* 324C7 (206023) */ + 1, /* 324C8 (206024) */ + 1, /* 324C9 (206025) */ + 1, /* 324CA (206026) */ + 1, /* 324CB (206027) */ + 1, /* 324CC (206028) */ + 1, /* 324CD (206029) */ + 1, /* 324CE (206030) */ + 1, /* 324CF (206031) */ + 1, /* 324D0 (206032) */ + 1, /* 324D1 (206033) */ + 1, /* 324D2 (206034) */ + 1, /* 324D3 (206035) */ + 1, /* 324D4 (206036) */ + 1, /* 324D5 (206037) */ + 1, /* 324D6 (206038) */ + 1, /* 324D7 (206039) */ + 1, /* 324D8 (206040) */ + 1, /* 324D9 (206041) */ + 1, /* 324DA (206042) */ + 1, /* 324DB (206043) */ + 1, /* 324DC (206044) */ + 1, /* 324DD (206045) */ + 1, /* 324DE (206046) */ + 1, /* 324DF (206047) */ + 1, /* 324E0 (206048) */ + 1, /* 324E1 (206049) */ + 1, /* 324E2 (206050) */ + 1, /* 324E3 (206051) */ + 1, /* 324E4 (206052) */ + 1, /* 324E5 (206053) */ + 1, /* 324E6 (206054) */ + 1, /* 324E7 (206055) */ + 1, /* 324E8 (206056) */ + 1, /* 324E9 (206057) */ + 1, /* 324EA (206058) */ + 1, /* 324EB (206059) */ + 1, /* 324EC (206060) */ + 1, /* 324ED (206061) */ + 1, /* 324EE (206062) */ + 1, /* 324EF (206063) */ + 1, /* 324F0 (206064) */ + 1, /* 324F1 (206065) */ + 1, /* 324F2 (206066) */ + 1, /* 324F3 (206067) */ + 1, /* 324F4 (206068) */ + 1, /* 324F5 (206069) */ + 1, /* 324F6 (206070) */ + 1, /* 324F7 (206071) */ + 1, /* 324F8 (206072) */ + 1, /* 324F9 (206073) */ + 1, /* 324FA (206074) */ + 1, /* 324FB (206075) */ + 1, /* 324FC (206076) */ + 1, /* 324FD (206077) */ + 1, /* 324FE (206078) */ + 1, /* 324FF (206079) */ + 1, /* 32500 (206080) */ + 1, /* 32501 (206081) */ + 1, /* 32502 (206082) */ + 1, /* 32503 (206083) */ + 1, /* 32504 (206084) */ + 1, /* 32505 (206085) */ + 1, /* 32506 (206086) */ + 1, /* 32507 (206087) */ + 1, /* 32508 (206088) */ + 1, /* 32509 (206089) */ + 1, /* 3250A (206090) */ + 1, /* 3250B (206091) */ + 1, /* 3250C (206092) */ + 1, /* 3250D (206093) */ + 1, /* 3250E (206094) */ + 1, /* 3250F (206095) */ + 1, /* 32510 (206096) */ + 1, /* 32511 (206097) */ + 1, /* 32512 (206098) */ + 1, /* 32513 (206099) */ + 1, /* 32514 (206100) */ + 1, /* 32515 (206101) */ + 1, /* 32516 (206102) */ + 1, /* 32517 (206103) */ + 1, /* 32518 (206104) */ + 1, /* 32519 (206105) */ + 1, /* 3251A (206106) */ + 1, /* 3251B (206107) */ + 1, /* 3251C (206108) */ + 1, /* 3251D (206109) */ + 1, /* 3251E (206110) */ + 1, /* 3251F (206111) */ + 1, /* 32520 (206112) */ + 1, /* 32521 (206113) */ + 1, /* 32522 (206114) */ + 1, /* 32523 (206115) */ + 1, /* 32524 (206116) */ + 1, /* 32525 (206117) */ + 1, /* 32526 (206118) */ + 1, /* 32527 (206119) */ + 1, /* 32528 (206120) */ + 1, /* 32529 (206121) */ + 1, /* 3252A (206122) */ + 1, /* 3252B (206123) */ + 1, /* 3252C (206124) */ + 1, /* 3252D (206125) */ + 1, /* 3252E (206126) */ + 1, /* 3252F (206127) */ + 1, /* 32530 (206128) */ + 1, /* 32531 (206129) */ + 1, /* 32532 (206130) */ + 1, /* 32533 (206131) */ + 1, /* 32534 (206132) */ + 1, /* 32535 (206133) */ + 1, /* 32536 (206134) */ + 1, /* 32537 (206135) */ + 1, /* 32538 (206136) */ + 1, /* 32539 (206137) */ + 1, /* 3253A (206138) */ + 1, /* 3253B (206139) */ + 1, /* 3253C (206140) */ + 1, /* 3253D (206141) */ + 1, /* 3253E (206142) */ + 1, /* 3253F (206143) */ + 1, /* 32540 (206144) */ + 1, /* 32541 (206145) */ + 1, /* 32542 (206146) */ + 1, /* 32543 (206147) */ + 1, /* 32544 (206148) */ + 1, /* 32545 (206149) */ + 1, /* 32546 (206150) */ + 1, /* 32547 (206151) */ + 1, /* 32548 (206152) */ + 1, /* 32549 (206153) */ + 1, /* 3254A (206154) */ + 1, /* 3254B (206155) */ + 1, /* 3254C (206156) */ + 1, /* 3254D (206157) */ + 1, /* 3254E (206158) */ + 1, /* 3254F (206159) */ + 1, /* 32550 (206160) */ + 1, /* 32551 (206161) */ + 1, /* 32552 (206162) */ + 1, /* 32553 (206163) */ + 1, /* 32554 (206164) */ + 1, /* 32555 (206165) */ + 1, /* 32556 (206166) */ + 1, /* 32557 (206167) */ + 1, /* 32558 (206168) */ + 1, /* 32559 (206169) */ + 1, /* 3255A (206170) */ + 1, /* 3255B (206171) */ + 1, /* 3255C (206172) */ + 1, /* 3255D (206173) */ + 1, /* 3255E (206174) */ + 1, /* 3255F (206175) */ + 1, /* 32560 (206176) */ + 1, /* 32561 (206177) */ + 1, /* 32562 (206178) */ + 1, /* 32563 (206179) */ + 1, /* 32564 (206180) */ + 1, /* 32565 (206181) */ + 1, /* 32566 (206182) */ + 1, /* 32567 (206183) */ + 1, /* 32568 (206184) */ + 1, /* 32569 (206185) */ + 1, /* 3256A (206186) */ + 1, /* 3256B (206187) */ + 1, /* 3256C (206188) */ + 1, /* 3256D (206189) */ + 1, /* 3256E (206190) */ + 1, /* 3256F (206191) */ + 1, /* 32570 (206192) */ + 1, /* 32571 (206193) */ + 1, /* 32572 (206194) */ + 1, /* 32573 (206195) */ + 1, /* 32574 (206196) */ + 1, /* 32575 (206197) */ + 1, /* 32576 (206198) */ + 1, /* 32577 (206199) */ + 1, /* 32578 (206200) */ + 1, /* 32579 (206201) */ + 1, /* 3257A (206202) */ + 1, /* 3257B (206203) */ + 1, /* 3257C (206204) */ + 1, /* 3257D (206205) */ + 1, /* 3257E (206206) */ + 1, /* 3257F (206207) */ + 1, /* 32580 (206208) */ + 1, /* 32581 (206209) */ + 1, /* 32582 (206210) */ + 1, /* 32583 (206211) */ + 1, /* 32584 (206212) */ + 1, /* 32585 (206213) */ + 1, /* 32586 (206214) */ + 1, /* 32587 (206215) */ + 1, /* 32588 (206216) */ + 1, /* 32589 (206217) */ + 1, /* 3258A (206218) */ + 1, /* 3258B (206219) */ + 1, /* 3258C (206220) */ + 1, /* 3258D (206221) */ + 1, /* 3258E (206222) */ + 1, /* 3258F (206223) */ + 1, /* 32590 (206224) */ + 1, /* 32591 (206225) */ + 1, /* 32592 (206226) */ + 1, /* 32593 (206227) */ + 1, /* 32594 (206228) */ + 1, /* 32595 (206229) */ + 1, /* 32596 (206230) */ + 1, /* 32597 (206231) */ + 1, /* 32598 (206232) */ + 1, /* 32599 (206233) */ + 1, /* 3259A (206234) */ + 1, /* 3259B (206235) */ + 1, /* 3259C (206236) */ + 1, /* 3259D (206237) */ + 1, /* 3259E (206238) */ + 1, /* 3259F (206239) */ + 1, /* 325A0 (206240) */ + 1, /* 325A1 (206241) */ + 1, /* 325A2 (206242) */ + 1, /* 325A3 (206243) */ + 1, /* 325A4 (206244) */ + 1, /* 325A5 (206245) */ + 1, /* 325A6 (206246) */ + 1, /* 325A7 (206247) */ + 1, /* 325A8 (206248) */ + 1, /* 325A9 (206249) */ + 1, /* 325AA (206250) */ + 1, /* 325AB (206251) */ + 1, /* 325AC (206252) */ + 1, /* 325AD (206253) */ + 1, /* 325AE (206254) */ + 1, /* 325AF (206255) */ + 1, /* 325B0 (206256) */ + 1, /* 325B1 (206257) */ + 1, /* 325B2 (206258) */ + 1, /* 325B3 (206259) */ + 1, /* 325B4 (206260) */ + 1, /* 325B5 (206261) */ + 1, /* 325B6 (206262) */ + 1, /* 325B7 (206263) */ + 1, /* 325B8 (206264) */ + 1, /* 325B9 (206265) */ + 1, /* 325BA (206266) */ + 1, /* 325BB (206267) */ + 1, /* 325BC (206268) */ + 1, /* 325BD (206269) */ + 1, /* 325BE (206270) */ + 1, /* 325BF (206271) */ + 1, /* 325C0 (206272) */ + 1, /* 325C1 (206273) */ + 1, /* 325C2 (206274) */ + 1, /* 325C3 (206275) */ + 1, /* 325C4 (206276) */ + 1, /* 325C5 (206277) */ + 1, /* 325C6 (206278) */ + 1, /* 325C7 (206279) */ + 1, /* 325C8 (206280) */ + 1, /* 325C9 (206281) */ + 1, /* 325CA (206282) */ + 1, /* 325CB (206283) */ + 1, /* 325CC (206284) */ + 1, /* 325CD (206285) */ + 1, /* 325CE (206286) */ + 1, /* 325CF (206287) */ + 1, /* 325D0 (206288) */ + 1, /* 325D1 (206289) */ + 1, /* 325D2 (206290) */ + 1, /* 325D3 (206291) */ + 1, /* 325D4 (206292) */ + 1, /* 325D5 (206293) */ + 1, /* 325D6 (206294) */ + 1, /* 325D7 (206295) */ + 1, /* 325D8 (206296) */ + 1, /* 325D9 (206297) */ + 1, /* 325DA (206298) */ + 1, /* 325DB (206299) */ + 1, /* 325DC (206300) */ + 1, /* 325DD (206301) */ + 1, /* 325DE (206302) */ + 1, /* 325DF (206303) */ + 1, /* 325E0 (206304) */ + 1, /* 325E1 (206305) */ + 1, /* 325E2 (206306) */ + 1, /* 325E3 (206307) */ + 1, /* 325E4 (206308) */ + 1, /* 325E5 (206309) */ + 1, /* 325E6 (206310) */ + 1, /* 325E7 (206311) */ + 1, /* 325E8 (206312) */ + 1, /* 325E9 (206313) */ + 1, /* 325EA (206314) */ + 1, /* 325EB (206315) */ + 1, /* 325EC (206316) */ + 1, /* 325ED (206317) */ + 1, /* 325EE (206318) */ + 1, /* 325EF (206319) */ + 1, /* 325F0 (206320) */ + 1, /* 325F1 (206321) */ + 1, /* 325F2 (206322) */ + 1, /* 325F3 (206323) */ + 1, /* 325F4 (206324) */ + 1, /* 325F5 (206325) */ + 1, /* 325F6 (206326) */ + 1, /* 325F7 (206327) */ + 1, /* 325F8 (206328) */ + 1, /* 325F9 (206329) */ + 1, /* 325FA (206330) */ + 1, /* 325FB (206331) */ + 1, /* 325FC (206332) */ + 1, /* 325FD (206333) */ + 1, /* 325FE (206334) */ + 1, /* 325FF (206335) */ + 1, /* 32600 (206336) */ + 1, /* 32601 (206337) */ + 1, /* 32602 (206338) */ + 1, /* 32603 (206339) */ + 1, /* 32604 (206340) */ + 1, /* 32605 (206341) */ + 1, /* 32606 (206342) */ + 1, /* 32607 (206343) */ + 1, /* 32608 (206344) */ + 1, /* 32609 (206345) */ + 1, /* 3260A (206346) */ + 1, /* 3260B (206347) */ + 1, /* 3260C (206348) */ + 1, /* 3260D (206349) */ + 1, /* 3260E (206350) */ + 1, /* 3260F (206351) */ + 1, /* 32610 (206352) */ + 1, /* 32611 (206353) */ + 1, /* 32612 (206354) */ + 1, /* 32613 (206355) */ + 1, /* 32614 (206356) */ + 1, /* 32615 (206357) */ + 1, /* 32616 (206358) */ + 1, /* 32617 (206359) */ + 1, /* 32618 (206360) */ + 1, /* 32619 (206361) */ + 1, /* 3261A (206362) */ + 1, /* 3261B (206363) */ + 1, /* 3261C (206364) */ + 1, /* 3261D (206365) */ + 1, /* 3261E (206366) */ + 1, /* 3261F (206367) */ + 1, /* 32620 (206368) */ + 1, /* 32621 (206369) */ + 1, /* 32622 (206370) */ + 1, /* 32623 (206371) */ + 1, /* 32624 (206372) */ + 1, /* 32625 (206373) */ + 1, /* 32626 (206374) */ + 1, /* 32627 (206375) */ + 1, /* 32628 (206376) */ + 1, /* 32629 (206377) */ + 1, /* 3262A (206378) */ + 1, /* 3262B (206379) */ + 1, /* 3262C (206380) */ + 1, /* 3262D (206381) */ + 1, /* 3262E (206382) */ + 1, /* 3262F (206383) */ + 1, /* 32630 (206384) */ + 1, /* 32631 (206385) */ + 1, /* 32632 (206386) */ + 1, /* 32633 (206387) */ + 1, /* 32634 (206388) */ + 1, /* 32635 (206389) */ + 1, /* 32636 (206390) */ + 1, /* 32637 (206391) */ + 1, /* 32638 (206392) */ + 1, /* 32639 (206393) */ + 1, /* 3263A (206394) */ + 1, /* 3263B (206395) */ + 1, /* 3263C (206396) */ + 1, /* 3263D (206397) */ + 1, /* 3263E (206398) */ + 1, /* 3263F (206399) */ + 1, /* 32640 (206400) */ + 1, /* 32641 (206401) */ + 1, /* 32642 (206402) */ + 1, /* 32643 (206403) */ + 1, /* 32644 (206404) */ + 1, /* 32645 (206405) */ + 1, /* 32646 (206406) */ + 1, /* 32647 (206407) */ + 1, /* 32648 (206408) */ + 1, /* 32649 (206409) */ + 1, /* 3264A (206410) */ + 1, /* 3264B (206411) */ + 1, /* 3264C (206412) */ + 1, /* 3264D (206413) */ + 1, /* 3264E (206414) */ + 1, /* 3264F (206415) */ + 1, /* 32650 (206416) */ + 1, /* 32651 (206417) */ + 1, /* 32652 (206418) */ + 1, /* 32653 (206419) */ + 1, /* 32654 (206420) */ + 1, /* 32655 (206421) */ + 1, /* 32656 (206422) */ + 1, /* 32657 (206423) */ + 1, /* 32658 (206424) */ + 1, /* 32659 (206425) */ + 1, /* 3265A (206426) */ + 1, /* 3265B (206427) */ + 1, /* 3265C (206428) */ + 1, /* 3265D (206429) */ + 1, /* 3265E (206430) */ + 1, /* 3265F (206431) */ + 1, /* 32660 (206432) */ + 1, /* 32661 (206433) */ + 1, /* 32662 (206434) */ + 1, /* 32663 (206435) */ + 1, /* 32664 (206436) */ + 1, /* 32665 (206437) */ + 1, /* 32666 (206438) */ + 1, /* 32667 (206439) */ + 1, /* 32668 (206440) */ + 1, /* 32669 (206441) */ + 1, /* 3266A (206442) */ + 1, /* 3266B (206443) */ + 1, /* 3266C (206444) */ + 1, /* 3266D (206445) */ + 1, /* 3266E (206446) */ + 1, /* 3266F (206447) */ + 1, /* 32670 (206448) */ + 1, /* 32671 (206449) */ + 1, /* 32672 (206450) */ + 1, /* 32673 (206451) */ + 1, /* 32674 (206452) */ + 1, /* 32675 (206453) */ + 1, /* 32676 (206454) */ + 1, /* 32677 (206455) */ + 1, /* 32678 (206456) */ + 1, /* 32679 (206457) */ + 1, /* 3267A (206458) */ + 1, /* 3267B (206459) */ + 1, /* 3267C (206460) */ + 1, /* 3267D (206461) */ + 1, /* 3267E (206462) */ + 1, /* 3267F (206463) */ + 1, /* 32680 (206464) */ + 1, /* 32681 (206465) */ + 1, /* 32682 (206466) */ + 1, /* 32683 (206467) */ + 1, /* 32684 (206468) */ + 1, /* 32685 (206469) */ + 1, /* 32686 (206470) */ + 1, /* 32687 (206471) */ + 1, /* 32688 (206472) */ + 1, /* 32689 (206473) */ + 1, /* 3268A (206474) */ + 1, /* 3268B (206475) */ + 1, /* 3268C (206476) */ + 1, /* 3268D (206477) */ + 1, /* 3268E (206478) */ + 1, /* 3268F (206479) */ + 1, /* 32690 (206480) */ + 1, /* 32691 (206481) */ + 1, /* 32692 (206482) */ + 1, /* 32693 (206483) */ + 1, /* 32694 (206484) */ + 1, /* 32695 (206485) */ + 1, /* 32696 (206486) */ + 1, /* 32697 (206487) */ + 1, /* 32698 (206488) */ + 1, /* 32699 (206489) */ + 1, /* 3269A (206490) */ + 1, /* 3269B (206491) */ + 1, /* 3269C (206492) */ + 1, /* 3269D (206493) */ + 1, /* 3269E (206494) */ + 1, /* 3269F (206495) */ + 1, /* 326A0 (206496) */ + 1, /* 326A1 (206497) */ + 1, /* 326A2 (206498) */ + 1, /* 326A3 (206499) */ + 1, /* 326A4 (206500) */ + 1, /* 326A5 (206501) */ + 1, /* 326A6 (206502) */ + 1, /* 326A7 (206503) */ + 1, /* 326A8 (206504) */ + 1, /* 326A9 (206505) */ + 1, /* 326AA (206506) */ + 1, /* 326AB (206507) */ + 1, /* 326AC (206508) */ + 1, /* 326AD (206509) */ + 1, /* 326AE (206510) */ + 1, /* 326AF (206511) */ + 1, /* 326B0 (206512) */ + 1, /* 326B1 (206513) */ + 1, /* 326B2 (206514) */ + 1, /* 326B3 (206515) */ + 1, /* 326B4 (206516) */ + 1, /* 326B5 (206517) */ + 1, /* 326B6 (206518) */ + 1, /* 326B7 (206519) */ + 1, /* 326B8 (206520) */ + 1, /* 326B9 (206521) */ + 1, /* 326BA (206522) */ + 1, /* 326BB (206523) */ + 1, /* 326BC (206524) */ + 1, /* 326BD (206525) */ + 1, /* 326BE (206526) */ + 1, /* 326BF (206527) */ + 1, /* 326C0 (206528) */ + 1, /* 326C1 (206529) */ + 1, /* 326C2 (206530) */ + 1, /* 326C3 (206531) */ + 1, /* 326C4 (206532) */ + 1, /* 326C5 (206533) */ + 1, /* 326C6 (206534) */ + 1, /* 326C7 (206535) */ + 1, /* 326C8 (206536) */ + 1, /* 326C9 (206537) */ + 1, /* 326CA (206538) */ + 1, /* 326CB (206539) */ + 1, /* 326CC (206540) */ + 1, /* 326CD (206541) */ + 1, /* 326CE (206542) */ + 1, /* 326CF (206543) */ + 1, /* 326D0 (206544) */ + 1, /* 326D1 (206545) */ + 1, /* 326D2 (206546) */ + 1, /* 326D3 (206547) */ + 1, /* 326D4 (206548) */ + 1, /* 326D5 (206549) */ + 1, /* 326D6 (206550) */ + 1, /* 326D7 (206551) */ + 1, /* 326D8 (206552) */ + 1, /* 326D9 (206553) */ + 1, /* 326DA (206554) */ + 1, /* 326DB (206555) */ + 1, /* 326DC (206556) */ + 1, /* 326DD (206557) */ + 1, /* 326DE (206558) */ + 1, /* 326DF (206559) */ + 1, /* 326E0 (206560) */ + 1, /* 326E1 (206561) */ + 1, /* 326E2 (206562) */ + 1, /* 326E3 (206563) */ + 1, /* 326E4 (206564) */ + 1, /* 326E5 (206565) */ + 1, /* 326E6 (206566) */ + 1, /* 326E7 (206567) */ + 1, /* 326E8 (206568) */ + 1, /* 326E9 (206569) */ + 1, /* 326EA (206570) */ + 1, /* 326EB (206571) */ + 1, /* 326EC (206572) */ + 1, /* 326ED (206573) */ + 1, /* 326EE (206574) */ + 1, /* 326EF (206575) */ + 1, /* 326F0 (206576) */ + 1, /* 326F1 (206577) */ + 1, /* 326F2 (206578) */ + 1, /* 326F3 (206579) */ + 1, /* 326F4 (206580) */ + 1, /* 326F5 (206581) */ + 1, /* 326F6 (206582) */ + 1, /* 326F7 (206583) */ + 1, /* 326F8 (206584) */ + 1, /* 326F9 (206585) */ + 1, /* 326FA (206586) */ + 1, /* 326FB (206587) */ + 1, /* 326FC (206588) */ + 1, /* 326FD (206589) */ + 1, /* 326FE (206590) */ + 1, /* 326FF (206591) */ + 1, /* 32700 (206592) */ + 1, /* 32701 (206593) */ + 1, /* 32702 (206594) */ + 1, /* 32703 (206595) */ + 1, /* 32704 (206596) */ + 1, /* 32705 (206597) */ + 1, /* 32706 (206598) */ + 1, /* 32707 (206599) */ + 1, /* 32708 (206600) */ + 1, /* 32709 (206601) */ + 1, /* 3270A (206602) */ + 1, /* 3270B (206603) */ + 1, /* 3270C (206604) */ + 1, /* 3270D (206605) */ + 1, /* 3270E (206606) */ + 1, /* 3270F (206607) */ + 1, /* 32710 (206608) */ + 1, /* 32711 (206609) */ + 1, /* 32712 (206610) */ + 1, /* 32713 (206611) */ + 1, /* 32714 (206612) */ + 1, /* 32715 (206613) */ + 1, /* 32716 (206614) */ + 1, /* 32717 (206615) */ + 1, /* 32718 (206616) */ + 1, /* 32719 (206617) */ + 1, /* 3271A (206618) */ + 1, /* 3271B (206619) */ + 1, /* 3271C (206620) */ + 1, /* 3271D (206621) */ + 1, /* 3271E (206622) */ + 1, /* 3271F (206623) */ + 1, /* 32720 (206624) */ + 1, /* 32721 (206625) */ + 1, /* 32722 (206626) */ + 1, /* 32723 (206627) */ + 1, /* 32724 (206628) */ + 1, /* 32725 (206629) */ + 1, /* 32726 (206630) */ + 1, /* 32727 (206631) */ + 1, /* 32728 (206632) */ + 1, /* 32729 (206633) */ + 1, /* 3272A (206634) */ + 1, /* 3272B (206635) */ + 1, /* 3272C (206636) */ + 1, /* 3272D (206637) */ + 1, /* 3272E (206638) */ + 1, /* 3272F (206639) */ + 1, /* 32730 (206640) */ + 1, /* 32731 (206641) */ + 1, /* 32732 (206642) */ + 1, /* 32733 (206643) */ + 1, /* 32734 (206644) */ + 1, /* 32735 (206645) */ + 1, /* 32736 (206646) */ + 1, /* 32737 (206647) */ + 1, /* 32738 (206648) */ + 1, /* 32739 (206649) */ + 1, /* 3273A (206650) */ + 1, /* 3273B (206651) */ + 1, /* 3273C (206652) */ + 1, /* 3273D (206653) */ + 1, /* 3273E (206654) */ + 1, /* 3273F (206655) */ + 1, /* 32740 (206656) */ + 1, /* 32741 (206657) */ + 1, /* 32742 (206658) */ + 1, /* 32743 (206659) */ + 1, /* 32744 (206660) */ + 1, /* 32745 (206661) */ + 1, /* 32746 (206662) */ + 1, /* 32747 (206663) */ + 1, /* 32748 (206664) */ + 1, /* 32749 (206665) */ + 1, /* 3274A (206666) */ + 1, /* 3274B (206667) */ + 1, /* 3274C (206668) */ + 1, /* 3274D (206669) */ + 1, /* 3274E (206670) */ + 1, /* 3274F (206671) */ + 1, /* 32750 (206672) */ + 1, /* 32751 (206673) */ + 1, /* 32752 (206674) */ + 1, /* 32753 (206675) */ + 1, /* 32754 (206676) */ + 1, /* 32755 (206677) */ + 1, /* 32756 (206678) */ + 1, /* 32757 (206679) */ + 1, /* 32758 (206680) */ + 1, /* 32759 (206681) */ + 1, /* 3275A (206682) */ + 1, /* 3275B (206683) */ + 1, /* 3275C (206684) */ + 1, /* 3275D (206685) */ + 1, /* 3275E (206686) */ + 1, /* 3275F (206687) */ + 1, /* 32760 (206688) */ + 1, /* 32761 (206689) */ + 1, /* 32762 (206690) */ + 1, /* 32763 (206691) */ + 1, /* 32764 (206692) */ + 1, /* 32765 (206693) */ + 1, /* 32766 (206694) */ + 1, /* 32767 (206695) */ + 1, /* 32768 (206696) */ + 1, /* 32769 (206697) */ + 1, /* 3276A (206698) */ + 1, /* 3276B (206699) */ + 1, /* 3276C (206700) */ + 1, /* 3276D (206701) */ + 1, /* 3276E (206702) */ + 1, /* 3276F (206703) */ + 1, /* 32770 (206704) */ + 1, /* 32771 (206705) */ + 1, /* 32772 (206706) */ + 1, /* 32773 (206707) */ + 1, /* 32774 (206708) */ + 1, /* 32775 (206709) */ + 1, /* 32776 (206710) */ + 1, /* 32777 (206711) */ + 1, /* 32778 (206712) */ + 1, /* 32779 (206713) */ + 1, /* 3277A (206714) */ + 1, /* 3277B (206715) */ + 1, /* 3277C (206716) */ + 1, /* 3277D (206717) */ + 1, /* 3277E (206718) */ + 1, /* 3277F (206719) */ + 1, /* 32780 (206720) */ + 1, /* 32781 (206721) */ + 1, /* 32782 (206722) */ + 1, /* 32783 (206723) */ + 1, /* 32784 (206724) */ + 1, /* 32785 (206725) */ + 1, /* 32786 (206726) */ + 1, /* 32787 (206727) */ + 1, /* 32788 (206728) */ + 1, /* 32789 (206729) */ + 1, /* 3278A (206730) */ + 1, /* 3278B (206731) */ + 1, /* 3278C (206732) */ + 1, /* 3278D (206733) */ + 1, /* 3278E (206734) */ + 1, /* 3278F (206735) */ + 1, /* 32790 (206736) */ + 1, /* 32791 (206737) */ + 1, /* 32792 (206738) */ + 1, /* 32793 (206739) */ + 1, /* 32794 (206740) */ + 1, /* 32795 (206741) */ + 1, /* 32796 (206742) */ + 1, /* 32797 (206743) */ + 1, /* 32798 (206744) */ + 1, /* 32799 (206745) */ + 1, /* 3279A (206746) */ + 1, /* 3279B (206747) */ + 1, /* 3279C (206748) */ + 1, /* 3279D (206749) */ + 1, /* 3279E (206750) */ + 1, /* 3279F (206751) */ + 1, /* 327A0 (206752) */ + 1, /* 327A1 (206753) */ + 1, /* 327A2 (206754) */ + 1, /* 327A3 (206755) */ + 1, /* 327A4 (206756) */ + 1, /* 327A5 (206757) */ + 1, /* 327A6 (206758) */ + 1, /* 327A7 (206759) */ + 1, /* 327A8 (206760) */ + 1, /* 327A9 (206761) */ + 1, /* 327AA (206762) */ + 1, /* 327AB (206763) */ + 1, /* 327AC (206764) */ + 1, /* 327AD (206765) */ + 1, /* 327AE (206766) */ + 1, /* 327AF (206767) */ + 1, /* 327B0 (206768) */ + 1, /* 327B1 (206769) */ + 1, /* 327B2 (206770) */ + 1, /* 327B3 (206771) */ + 1, /* 327B4 (206772) */ + 1, /* 327B5 (206773) */ + 1, /* 327B6 (206774) */ + 1, /* 327B7 (206775) */ + 1, /* 327B8 (206776) */ + 1, /* 327B9 (206777) */ + 1, /* 327BA (206778) */ + 1, /* 327BB (206779) */ + 1, /* 327BC (206780) */ + 1, /* 327BD (206781) */ + 1, /* 327BE (206782) */ + 1, /* 327BF (206783) */ + 1, /* 327C0 (206784) */ + 1, /* 327C1 (206785) */ + 1, /* 327C2 (206786) */ + 1, /* 327C3 (206787) */ + 1, /* 327C4 (206788) */ + 1, /* 327C5 (206789) */ + 1, /* 327C6 (206790) */ + 1, /* 327C7 (206791) */ + 1, /* 327C8 (206792) */ + 1, /* 327C9 (206793) */ + 1, /* 327CA (206794) */ + 1, /* 327CB (206795) */ + 1, /* 327CC (206796) */ + 1, /* 327CD (206797) */ + 1, /* 327CE (206798) */ + 1, /* 327CF (206799) */ + 1, /* 327D0 (206800) */ + 1, /* 327D1 (206801) */ + 1, /* 327D2 (206802) */ + 1, /* 327D3 (206803) */ + 1, /* 327D4 (206804) */ + 1, /* 327D5 (206805) */ + 1, /* 327D6 (206806) */ + 1, /* 327D7 (206807) */ + 1, /* 327D8 (206808) */ + 1, /* 327D9 (206809) */ + 1, /* 327DA (206810) */ + 1, /* 327DB (206811) */ + 1, /* 327DC (206812) */ + 1, /* 327DD (206813) */ + 1, /* 327DE (206814) */ + 1, /* 327DF (206815) */ + 1, /* 327E0 (206816) */ + 1, /* 327E1 (206817) */ + 1, /* 327E2 (206818) */ + 1, /* 327E3 (206819) */ + 1, /* 327E4 (206820) */ + 1, /* 327E5 (206821) */ + 1, /* 327E6 (206822) */ + 1, /* 327E7 (206823) */ + 1, /* 327E8 (206824) */ + 1, /* 327E9 (206825) */ + 1, /* 327EA (206826) */ + 1, /* 327EB (206827) */ + 1, /* 327EC (206828) */ + 1, /* 327ED (206829) */ + 1, /* 327EE (206830) */ + 1, /* 327EF (206831) */ + 1, /* 327F0 (206832) */ + 1, /* 327F1 (206833) */ + 1, /* 327F2 (206834) */ + 1, /* 327F3 (206835) */ + 1, /* 327F4 (206836) */ + 1, /* 327F5 (206837) */ + 1, /* 327F6 (206838) */ + 1, /* 327F7 (206839) */ + 1, /* 327F8 (206840) */ + 1, /* 327F9 (206841) */ + 1, /* 327FA (206842) */ + 1, /* 327FB (206843) */ + 1, /* 327FC (206844) */ + 1, /* 327FD (206845) */ + 1, /* 327FE (206846) */ + 1, /* 327FF (206847) */ + 1, /* 32800 (206848) */ + 1, /* 32801 (206849) */ + 1, /* 32802 (206850) */ + 1, /* 32803 (206851) */ + 1, /* 32804 (206852) */ + 1, /* 32805 (206853) */ + 1, /* 32806 (206854) */ + 1, /* 32807 (206855) */ + 1, /* 32808 (206856) */ + 1, /* 32809 (206857) */ + 1, /* 3280A (206858) */ + 1, /* 3280B (206859) */ + 1, /* 3280C (206860) */ + 1, /* 3280D (206861) */ + 1, /* 3280E (206862) */ + 1, /* 3280F (206863) */ + 1, /* 32810 (206864) */ + 1, /* 32811 (206865) */ + 1, /* 32812 (206866) */ + 1, /* 32813 (206867) */ + 1, /* 32814 (206868) */ + 1, /* 32815 (206869) */ + 1, /* 32816 (206870) */ + 1, /* 32817 (206871) */ + 1, /* 32818 (206872) */ + 1, /* 32819 (206873) */ + 1, /* 3281A (206874) */ + 1, /* 3281B (206875) */ + 1, /* 3281C (206876) */ + 1, /* 3281D (206877) */ + 1, /* 3281E (206878) */ + 1, /* 3281F (206879) */ + 1, /* 32820 (206880) */ + 1, /* 32821 (206881) */ + 1, /* 32822 (206882) */ + 1, /* 32823 (206883) */ + 1, /* 32824 (206884) */ + 1, /* 32825 (206885) */ + 1, /* 32826 (206886) */ + 1, /* 32827 (206887) */ + 1, /* 32828 (206888) */ + 1, /* 32829 (206889) */ + 1, /* 3282A (206890) */ + 1, /* 3282B (206891) */ + 1, /* 3282C (206892) */ + 1, /* 3282D (206893) */ + 1, /* 3282E (206894) */ + 1, /* 3282F (206895) */ + 1, /* 32830 (206896) */ + 1, /* 32831 (206897) */ + 1, /* 32832 (206898) */ + 1, /* 32833 (206899) */ + 1, /* 32834 (206900) */ + 1, /* 32835 (206901) */ + 1, /* 32836 (206902) */ + 1, /* 32837 (206903) */ + 1, /* 32838 (206904) */ + 1, /* 32839 (206905) */ + 1, /* 3283A (206906) */ + 1, /* 3283B (206907) */ + 1, /* 3283C (206908) */ + 1, /* 3283D (206909) */ + 1, /* 3283E (206910) */ + 1, /* 3283F (206911) */ + 1, /* 32840 (206912) */ + 1, /* 32841 (206913) */ + 1, /* 32842 (206914) */ + 1, /* 32843 (206915) */ + 1, /* 32844 (206916) */ + 1, /* 32845 (206917) */ + 1, /* 32846 (206918) */ + 1, /* 32847 (206919) */ + 1, /* 32848 (206920) */ + 1, /* 32849 (206921) */ + 1, /* 3284A (206922) */ + 1, /* 3284B (206923) */ + 1, /* 3284C (206924) */ + 1, /* 3284D (206925) */ + 1, /* 3284E (206926) */ + 1, /* 3284F (206927) */ + 1, /* 32850 (206928) */ + 1, /* 32851 (206929) */ + 1, /* 32852 (206930) */ + 1, /* 32853 (206931) */ + 1, /* 32854 (206932) */ + 1, /* 32855 (206933) */ + 1, /* 32856 (206934) */ + 1, /* 32857 (206935) */ + 1, /* 32858 (206936) */ + 1, /* 32859 (206937) */ + 1, /* 3285A (206938) */ + 1, /* 3285B (206939) */ + 1, /* 3285C (206940) */ + 1, /* 3285D (206941) */ + 1, /* 3285E (206942) */ + 1, /* 3285F (206943) */ + 1, /* 32860 (206944) */ + 1, /* 32861 (206945) */ + 1, /* 32862 (206946) */ + 1, /* 32863 (206947) */ + 1, /* 32864 (206948) */ + 1, /* 32865 (206949) */ + 1, /* 32866 (206950) */ + 1, /* 32867 (206951) */ + 1, /* 32868 (206952) */ + 1, /* 32869 (206953) */ + 1, /* 3286A (206954) */ + 1, /* 3286B (206955) */ + 1, /* 3286C (206956) */ + 1, /* 3286D (206957) */ + 1, /* 3286E (206958) */ + 1, /* 3286F (206959) */ + 1, /* 32870 (206960) */ + 1, /* 32871 (206961) */ + 1, /* 32872 (206962) */ + 1, /* 32873 (206963) */ + 1, /* 32874 (206964) */ + 1, /* 32875 (206965) */ + 1, /* 32876 (206966) */ + 1, /* 32877 (206967) */ + 1, /* 32878 (206968) */ + 1, /* 32879 (206969) */ + 1, /* 3287A (206970) */ + 1, /* 3287B (206971) */ + 1, /* 3287C (206972) */ + 1, /* 3287D (206973) */ + 1, /* 3287E (206974) */ + 1, /* 3287F (206975) */ + 1, /* 32880 (206976) */ + 1, /* 32881 (206977) */ + 1, /* 32882 (206978) */ + 1, /* 32883 (206979) */ + 1, /* 32884 (206980) */ + 1, /* 32885 (206981) */ + 1, /* 32886 (206982) */ + 1, /* 32887 (206983) */ + 1, /* 32888 (206984) */ + 1, /* 32889 (206985) */ + 1, /* 3288A (206986) */ + 1, /* 3288B (206987) */ + 1, /* 3288C (206988) */ + 1, /* 3288D (206989) */ + 1, /* 3288E (206990) */ + 1, /* 3288F (206991) */ + 1, /* 32890 (206992) */ + 1, /* 32891 (206993) */ + 1, /* 32892 (206994) */ + 1, /* 32893 (206995) */ + 1, /* 32894 (206996) */ + 1, /* 32895 (206997) */ + 1, /* 32896 (206998) */ + 1, /* 32897 (206999) */ + 1, /* 32898 (207000) */ + 1, /* 32899 (207001) */ + 1, /* 3289A (207002) */ + 1, /* 3289B (207003) */ + 1, /* 3289C (207004) */ + 1, /* 3289D (207005) */ + 1, /* 3289E (207006) */ + 1, /* 3289F (207007) */ + 1, /* 328A0 (207008) */ + 1, /* 328A1 (207009) */ + 1, /* 328A2 (207010) */ + 1, /* 328A3 (207011) */ + 1, /* 328A4 (207012) */ + 1, /* 328A5 (207013) */ + 1, /* 328A6 (207014) */ + 1, /* 328A7 (207015) */ + 1, /* 328A8 (207016) */ + 1, /* 328A9 (207017) */ + 1, /* 328AA (207018) */ + 1, /* 328AB (207019) */ + 1, /* 328AC (207020) */ + 1, /* 328AD (207021) */ + 1, /* 328AE (207022) */ + 1, /* 328AF (207023) */ + 1, /* 328B0 (207024) */ + 1, /* 328B1 (207025) */ + 1, /* 328B2 (207026) */ + 1, /* 328B3 (207027) */ + 1, /* 328B4 (207028) */ + 1, /* 328B5 (207029) */ + 1, /* 328B6 (207030) */ + 1, /* 328B7 (207031) */ + 1, /* 328B8 (207032) */ + 1, /* 328B9 (207033) */ + 1, /* 328BA (207034) */ + 1, /* 328BB (207035) */ + 1, /* 328BC (207036) */ + 1, /* 328BD (207037) */ + 1, /* 328BE (207038) */ + 1, /* 328BF (207039) */ + 1, /* 328C0 (207040) */ + 1, /* 328C1 (207041) */ + 1, /* 328C2 (207042) */ + 1, /* 328C3 (207043) */ + 1, /* 328C4 (207044) */ + 1, /* 328C5 (207045) */ + 1, /* 328C6 (207046) */ + 1, /* 328C7 (207047) */ + 1, /* 328C8 (207048) */ + 1, /* 328C9 (207049) */ + 1, /* 328CA (207050) */ + 1, /* 328CB (207051) */ + 1, /* 328CC (207052) */ + 1, /* 328CD (207053) */ + 1, /* 328CE (207054) */ + 1, /* 328CF (207055) */ + 1, /* 328D0 (207056) */ + 1, /* 328D1 (207057) */ + 1, /* 328D2 (207058) */ + 1, /* 328D3 (207059) */ + 1, /* 328D4 (207060) */ + 1, /* 328D5 (207061) */ + 1, /* 328D6 (207062) */ + 1, /* 328D7 (207063) */ + 1, /* 328D8 (207064) */ + 1, /* 328D9 (207065) */ + 1, /* 328DA (207066) */ + 1, /* 328DB (207067) */ + 1, /* 328DC (207068) */ + 1, /* 328DD (207069) */ + 1, /* 328DE (207070) */ + 1, /* 328DF (207071) */ + 1, /* 328E0 (207072) */ + 1, /* 328E1 (207073) */ + 1, /* 328E2 (207074) */ + 1, /* 328E3 (207075) */ + 1, /* 328E4 (207076) */ + 1, /* 328E5 (207077) */ + 1, /* 328E6 (207078) */ + 1, /* 328E7 (207079) */ + 1, /* 328E8 (207080) */ + 1, /* 328E9 (207081) */ + 1, /* 328EA (207082) */ + 1, /* 328EB (207083) */ + 1, /* 328EC (207084) */ + 1, /* 328ED (207085) */ + 1, /* 328EE (207086) */ + 1, /* 328EF (207087) */ + 1, /* 328F0 (207088) */ + 1, /* 328F1 (207089) */ + 1, /* 328F2 (207090) */ + 1, /* 328F3 (207091) */ + 1, /* 328F4 (207092) */ + 1, /* 328F5 (207093) */ + 1, /* 328F6 (207094) */ + 1, /* 328F7 (207095) */ + 1, /* 328F8 (207096) */ + 1, /* 328F9 (207097) */ + 1, /* 328FA (207098) */ + 1, /* 328FB (207099) */ + 1, /* 328FC (207100) */ + 1, /* 328FD (207101) */ + 1, /* 328FE (207102) */ + 1, /* 328FF (207103) */ + 1, /* 32900 (207104) */ + 1, /* 32901 (207105) */ + 1, /* 32902 (207106) */ + 1, /* 32903 (207107) */ + 1, /* 32904 (207108) */ + 1, /* 32905 (207109) */ + 1, /* 32906 (207110) */ + 1, /* 32907 (207111) */ + 1, /* 32908 (207112) */ + 1, /* 32909 (207113) */ + 1, /* 3290A (207114) */ + 1, /* 3290B (207115) */ + 1, /* 3290C (207116) */ + 1, /* 3290D (207117) */ + 1, /* 3290E (207118) */ + 1, /* 3290F (207119) */ + 1, /* 32910 (207120) */ + 1, /* 32911 (207121) */ + 1, /* 32912 (207122) */ + 1, /* 32913 (207123) */ + 1, /* 32914 (207124) */ + 1, /* 32915 (207125) */ + 1, /* 32916 (207126) */ + 1, /* 32917 (207127) */ + 1, /* 32918 (207128) */ + 1, /* 32919 (207129) */ + 1, /* 3291A (207130) */ + 1, /* 3291B (207131) */ + 1, /* 3291C (207132) */ + 1, /* 3291D (207133) */ + 1, /* 3291E (207134) */ + 1, /* 3291F (207135) */ + 1, /* 32920 (207136) */ + 1, /* 32921 (207137) */ + 1, /* 32922 (207138) */ + 1, /* 32923 (207139) */ + 1, /* 32924 (207140) */ + 1, /* 32925 (207141) */ + 1, /* 32926 (207142) */ + 1, /* 32927 (207143) */ + 1, /* 32928 (207144) */ + 1, /* 32929 (207145) */ + 1, /* 3292A (207146) */ + 1, /* 3292B (207147) */ + 1, /* 3292C (207148) */ + 1, /* 3292D (207149) */ + 1, /* 3292E (207150) */ + 1, /* 3292F (207151) */ + 1, /* 32930 (207152) */ + 1, /* 32931 (207153) */ + 1, /* 32932 (207154) */ + 1, /* 32933 (207155) */ + 1, /* 32934 (207156) */ + 1, /* 32935 (207157) */ + 1, /* 32936 (207158) */ + 1, /* 32937 (207159) */ + 1, /* 32938 (207160) */ + 1, /* 32939 (207161) */ + 1, /* 3293A (207162) */ + 1, /* 3293B (207163) */ + 1, /* 3293C (207164) */ + 1, /* 3293D (207165) */ + 1, /* 3293E (207166) */ + 1, /* 3293F (207167) */ + 1, /* 32940 (207168) */ + 1, /* 32941 (207169) */ + 1, /* 32942 (207170) */ + 1, /* 32943 (207171) */ + 1, /* 32944 (207172) */ + 1, /* 32945 (207173) */ + 1, /* 32946 (207174) */ + 1, /* 32947 (207175) */ + 1, /* 32948 (207176) */ + 1, /* 32949 (207177) */ + 1, /* 3294A (207178) */ + 1, /* 3294B (207179) */ + 1, /* 3294C (207180) */ + 1, /* 3294D (207181) */ + 1, /* 3294E (207182) */ + 1, /* 3294F (207183) */ + 1, /* 32950 (207184) */ + 1, /* 32951 (207185) */ + 1, /* 32952 (207186) */ + 1, /* 32953 (207187) */ + 1, /* 32954 (207188) */ + 1, /* 32955 (207189) */ + 1, /* 32956 (207190) */ + 1, /* 32957 (207191) */ + 1, /* 32958 (207192) */ + 1, /* 32959 (207193) */ + 1, /* 3295A (207194) */ + 1, /* 3295B (207195) */ + 1, /* 3295C (207196) */ + 1, /* 3295D (207197) */ + 1, /* 3295E (207198) */ + 1, /* 3295F (207199) */ + 1, /* 32960 (207200) */ + 1, /* 32961 (207201) */ + 1, /* 32962 (207202) */ + 1, /* 32963 (207203) */ + 1, /* 32964 (207204) */ + 1, /* 32965 (207205) */ + 1, /* 32966 (207206) */ + 1, /* 32967 (207207) */ + 1, /* 32968 (207208) */ + 1, /* 32969 (207209) */ + 1, /* 3296A (207210) */ + 1, /* 3296B (207211) */ + 1, /* 3296C (207212) */ + 1, /* 3296D (207213) */ + 1, /* 3296E (207214) */ + 1, /* 3296F (207215) */ + 1, /* 32970 (207216) */ + 1, /* 32971 (207217) */ + 1, /* 32972 (207218) */ + 1, /* 32973 (207219) */ + 1, /* 32974 (207220) */ + 1, /* 32975 (207221) */ + 1, /* 32976 (207222) */ + 1, /* 32977 (207223) */ + 1, /* 32978 (207224) */ + 1, /* 32979 (207225) */ + 1, /* 3297A (207226) */ + 1, /* 3297B (207227) */ + 1, /* 3297C (207228) */ + 1, /* 3297D (207229) */ + 1, /* 3297E (207230) */ + 1, /* 3297F (207231) */ + 1, /* 32980 (207232) */ + 1, /* 32981 (207233) */ + 1, /* 32982 (207234) */ + 1, /* 32983 (207235) */ + 1, /* 32984 (207236) */ + 1, /* 32985 (207237) */ + 1, /* 32986 (207238) */ + 1, /* 32987 (207239) */ + 1, /* 32988 (207240) */ + 1, /* 32989 (207241) */ + 1, /* 3298A (207242) */ + 1, /* 3298B (207243) */ + 1, /* 3298C (207244) */ + 1, /* 3298D (207245) */ + 1, /* 3298E (207246) */ + 1, /* 3298F (207247) */ + 1, /* 32990 (207248) */ + 1, /* 32991 (207249) */ + 1, /* 32992 (207250) */ + 1, /* 32993 (207251) */ + 1, /* 32994 (207252) */ + 1, /* 32995 (207253) */ + 1, /* 32996 (207254) */ + 1, /* 32997 (207255) */ + 1, /* 32998 (207256) */ + 1, /* 32999 (207257) */ + 1, /* 3299A (207258) */ + 1, /* 3299B (207259) */ + 1, /* 3299C (207260) */ + 1, /* 3299D (207261) */ + 1, /* 3299E (207262) */ + 1, /* 3299F (207263) */ + 1, /* 329A0 (207264) */ + 1, /* 329A1 (207265) */ + 1, /* 329A2 (207266) */ + 1, /* 329A3 (207267) */ + 1, /* 329A4 (207268) */ + 1, /* 329A5 (207269) */ + 1, /* 329A6 (207270) */ + 1, /* 329A7 (207271) */ + 1, /* 329A8 (207272) */ + 1, /* 329A9 (207273) */ + 1, /* 329AA (207274) */ + 1, /* 329AB (207275) */ + 1, /* 329AC (207276) */ + 1, /* 329AD (207277) */ + 1, /* 329AE (207278) */ + 1, /* 329AF (207279) */ + 1, /* 329B0 (207280) */ + 1, /* 329B1 (207281) */ + 1, /* 329B2 (207282) */ + 1, /* 329B3 (207283) */ + 1, /* 329B4 (207284) */ + 1, /* 329B5 (207285) */ + 1, /* 329B6 (207286) */ + 1, /* 329B7 (207287) */ + 1, /* 329B8 (207288) */ + 1, /* 329B9 (207289) */ + 1, /* 329BA (207290) */ + 1, /* 329BB (207291) */ + 1, /* 329BC (207292) */ + 1, /* 329BD (207293) */ + 1, /* 329BE (207294) */ + 1, /* 329BF (207295) */ + 1, /* 329C0 (207296) */ + 1, /* 329C1 (207297) */ + 1, /* 329C2 (207298) */ + 1, /* 329C3 (207299) */ + 1, /* 329C4 (207300) */ + 1, /* 329C5 (207301) */ + 1, /* 329C6 (207302) */ + 1, /* 329C7 (207303) */ + 1, /* 329C8 (207304) */ + 1, /* 329C9 (207305) */ + 1, /* 329CA (207306) */ + 1, /* 329CB (207307) */ + 1, /* 329CC (207308) */ + 1, /* 329CD (207309) */ + 1, /* 329CE (207310) */ + 1, /* 329CF (207311) */ + 1, /* 329D0 (207312) */ + 1, /* 329D1 (207313) */ + 1, /* 329D2 (207314) */ + 1, /* 329D3 (207315) */ + 1, /* 329D4 (207316) */ + 1, /* 329D5 (207317) */ + 1, /* 329D6 (207318) */ + 1, /* 329D7 (207319) */ + 1, /* 329D8 (207320) */ + 1, /* 329D9 (207321) */ + 1, /* 329DA (207322) */ + 1, /* 329DB (207323) */ + 1, /* 329DC (207324) */ + 1, /* 329DD (207325) */ + 1, /* 329DE (207326) */ + 1, /* 329DF (207327) */ + 1, /* 329E0 (207328) */ + 1, /* 329E1 (207329) */ + 1, /* 329E2 (207330) */ + 1, /* 329E3 (207331) */ + 1, /* 329E4 (207332) */ + 1, /* 329E5 (207333) */ + 1, /* 329E6 (207334) */ + 1, /* 329E7 (207335) */ + 1, /* 329E8 (207336) */ + 1, /* 329E9 (207337) */ + 1, /* 329EA (207338) */ + 1, /* 329EB (207339) */ + 1, /* 329EC (207340) */ + 1, /* 329ED (207341) */ + 1, /* 329EE (207342) */ + 1, /* 329EF (207343) */ + 1, /* 329F0 (207344) */ + 1, /* 329F1 (207345) */ + 1, /* 329F2 (207346) */ + 1, /* 329F3 (207347) */ + 1, /* 329F4 (207348) */ + 1, /* 329F5 (207349) */ + 1, /* 329F6 (207350) */ + 1, /* 329F7 (207351) */ + 1, /* 329F8 (207352) */ + 1, /* 329F9 (207353) */ + 1, /* 329FA (207354) */ + 1, /* 329FB (207355) */ + 1, /* 329FC (207356) */ + 1, /* 329FD (207357) */ + 1, /* 329FE (207358) */ + 1, /* 329FF (207359) */ + 1, /* 32A00 (207360) */ + 1, /* 32A01 (207361) */ + 1, /* 32A02 (207362) */ + 1, /* 32A03 (207363) */ + 1, /* 32A04 (207364) */ + 1, /* 32A05 (207365) */ + 1, /* 32A06 (207366) */ + 1, /* 32A07 (207367) */ + 1, /* 32A08 (207368) */ + 1, /* 32A09 (207369) */ + 1, /* 32A0A (207370) */ + 1, /* 32A0B (207371) */ + 1, /* 32A0C (207372) */ + 1, /* 32A0D (207373) */ + 1, /* 32A0E (207374) */ + 1, /* 32A0F (207375) */ + 1, /* 32A10 (207376) */ + 1, /* 32A11 (207377) */ + 1, /* 32A12 (207378) */ + 1, /* 32A13 (207379) */ + 1, /* 32A14 (207380) */ + 1, /* 32A15 (207381) */ + 1, /* 32A16 (207382) */ + 1, /* 32A17 (207383) */ + 1, /* 32A18 (207384) */ + 1, /* 32A19 (207385) */ + 1, /* 32A1A (207386) */ + 1, /* 32A1B (207387) */ + 1, /* 32A1C (207388) */ + 1, /* 32A1D (207389) */ + 1, /* 32A1E (207390) */ + 1, /* 32A1F (207391) */ + 1, /* 32A20 (207392) */ + 1, /* 32A21 (207393) */ + 1, /* 32A22 (207394) */ + 1, /* 32A23 (207395) */ + 1, /* 32A24 (207396) */ + 1, /* 32A25 (207397) */ + 1, /* 32A26 (207398) */ + 1, /* 32A27 (207399) */ + 1, /* 32A28 (207400) */ + 1, /* 32A29 (207401) */ + 1, /* 32A2A (207402) */ + 1, /* 32A2B (207403) */ + 1, /* 32A2C (207404) */ + 1, /* 32A2D (207405) */ + 1, /* 32A2E (207406) */ + 1, /* 32A2F (207407) */ + 1, /* 32A30 (207408) */ + 1, /* 32A31 (207409) */ + 1, /* 32A32 (207410) */ + 1, /* 32A33 (207411) */ + 1, /* 32A34 (207412) */ + 1, /* 32A35 (207413) */ + 1, /* 32A36 (207414) */ + 1, /* 32A37 (207415) */ + 1, /* 32A38 (207416) */ + 1, /* 32A39 (207417) */ + 1, /* 32A3A (207418) */ + 1, /* 32A3B (207419) */ + 1, /* 32A3C (207420) */ + 1, /* 32A3D (207421) */ + 1, /* 32A3E (207422) */ + 1, /* 32A3F (207423) */ + 1, /* 32A40 (207424) */ + 1, /* 32A41 (207425) */ + 1, /* 32A42 (207426) */ + 1, /* 32A43 (207427) */ + 1, /* 32A44 (207428) */ + 1, /* 32A45 (207429) */ + 1, /* 32A46 (207430) */ + 1, /* 32A47 (207431) */ + 1, /* 32A48 (207432) */ + 1, /* 32A49 (207433) */ + 1, /* 32A4A (207434) */ + 1, /* 32A4B (207435) */ + 1, /* 32A4C (207436) */ + 1, /* 32A4D (207437) */ + 1, /* 32A4E (207438) */ + 1, /* 32A4F (207439) */ + 1, /* 32A50 (207440) */ + 1, /* 32A51 (207441) */ + 1, /* 32A52 (207442) */ + 1, /* 32A53 (207443) */ + 1, /* 32A54 (207444) */ + 1, /* 32A55 (207445) */ + 1, /* 32A56 (207446) */ + 1, /* 32A57 (207447) */ + 1, /* 32A58 (207448) */ + 1, /* 32A59 (207449) */ + 1, /* 32A5A (207450) */ + 1, /* 32A5B (207451) */ + 1, /* 32A5C (207452) */ + 1, /* 32A5D (207453) */ + 1, /* 32A5E (207454) */ + 1, /* 32A5F (207455) */ + 1, /* 32A60 (207456) */ + 1, /* 32A61 (207457) */ + 1, /* 32A62 (207458) */ + 1, /* 32A63 (207459) */ + 1, /* 32A64 (207460) */ + 1, /* 32A65 (207461) */ + 1, /* 32A66 (207462) */ + 1, /* 32A67 (207463) */ + 1, /* 32A68 (207464) */ + 1, /* 32A69 (207465) */ + 1, /* 32A6A (207466) */ + 1, /* 32A6B (207467) */ + 1, /* 32A6C (207468) */ + 1, /* 32A6D (207469) */ + 1, /* 32A6E (207470) */ + 1, /* 32A6F (207471) */ + 1, /* 32A70 (207472) */ + 1, /* 32A71 (207473) */ + 1, /* 32A72 (207474) */ + 1, /* 32A73 (207475) */ + 1, /* 32A74 (207476) */ + 1, /* 32A75 (207477) */ + 1, /* 32A76 (207478) */ + 1, /* 32A77 (207479) */ + 1, /* 32A78 (207480) */ + 1, /* 32A79 (207481) */ + 1, /* 32A7A (207482) */ + 1, /* 32A7B (207483) */ + 1, /* 32A7C (207484) */ + 1, /* 32A7D (207485) */ + 1, /* 32A7E (207486) */ + 1, /* 32A7F (207487) */ + 1, /* 32A80 (207488) */ + 1, /* 32A81 (207489) */ + 1, /* 32A82 (207490) */ + 1, /* 32A83 (207491) */ + 1, /* 32A84 (207492) */ + 1, /* 32A85 (207493) */ + 1, /* 32A86 (207494) */ + 1, /* 32A87 (207495) */ + 1, /* 32A88 (207496) */ + 1, /* 32A89 (207497) */ + 1, /* 32A8A (207498) */ + 1, /* 32A8B (207499) */ + 1, /* 32A8C (207500) */ + 1, /* 32A8D (207501) */ + 1, /* 32A8E (207502) */ + 1, /* 32A8F (207503) */ + 1, /* 32A90 (207504) */ + 1, /* 32A91 (207505) */ + 1, /* 32A92 (207506) */ + 1, /* 32A93 (207507) */ + 1, /* 32A94 (207508) */ + 1, /* 32A95 (207509) */ + 1, /* 32A96 (207510) */ + 1, /* 32A97 (207511) */ + 1, /* 32A98 (207512) */ + 1, /* 32A99 (207513) */ + 1, /* 32A9A (207514) */ + 1, /* 32A9B (207515) */ + 1, /* 32A9C (207516) */ + 1, /* 32A9D (207517) */ + 1, /* 32A9E (207518) */ + 1, /* 32A9F (207519) */ + 1, /* 32AA0 (207520) */ + 1, /* 32AA1 (207521) */ + 1, /* 32AA2 (207522) */ + 1, /* 32AA3 (207523) */ + 1, /* 32AA4 (207524) */ + 1, /* 32AA5 (207525) */ + 1, /* 32AA6 (207526) */ + 1, /* 32AA7 (207527) */ + 1, /* 32AA8 (207528) */ + 1, /* 32AA9 (207529) */ + 1, /* 32AAA (207530) */ + 1, /* 32AAB (207531) */ + 1, /* 32AAC (207532) */ + 1, /* 32AAD (207533) */ + 1, /* 32AAE (207534) */ + 1, /* 32AAF (207535) */ + 1, /* 32AB0 (207536) */ + 1, /* 32AB1 (207537) */ + 1, /* 32AB2 (207538) */ + 1, /* 32AB3 (207539) */ + 1, /* 32AB4 (207540) */ + 1, /* 32AB5 (207541) */ + 1, /* 32AB6 (207542) */ + 1, /* 32AB7 (207543) */ + 1, /* 32AB8 (207544) */ + 1, /* 32AB9 (207545) */ + 1, /* 32ABA (207546) */ + 1, /* 32ABB (207547) */ + 1, /* 32ABC (207548) */ + 1, /* 32ABD (207549) */ + 1, /* 32ABE (207550) */ + 1, /* 32ABF (207551) */ + 1, /* 32AC0 (207552) */ + 1, /* 32AC1 (207553) */ + 1, /* 32AC2 (207554) */ + 1, /* 32AC3 (207555) */ + 1, /* 32AC4 (207556) */ + 1, /* 32AC5 (207557) */ + 1, /* 32AC6 (207558) */ + 1, /* 32AC7 (207559) */ + 1, /* 32AC8 (207560) */ + 1, /* 32AC9 (207561) */ + 1, /* 32ACA (207562) */ + 1, /* 32ACB (207563) */ + 1, /* 32ACC (207564) */ + 1, /* 32ACD (207565) */ + 1, /* 32ACE (207566) */ + 1, /* 32ACF (207567) */ + 1, /* 32AD0 (207568) */ + 1, /* 32AD1 (207569) */ + 1, /* 32AD2 (207570) */ + 1, /* 32AD3 (207571) */ + 1, /* 32AD4 (207572) */ + 1, /* 32AD5 (207573) */ + 1, /* 32AD6 (207574) */ + 1, /* 32AD7 (207575) */ + 1, /* 32AD8 (207576) */ + 1, /* 32AD9 (207577) */ + 1, /* 32ADA (207578) */ + 1, /* 32ADB (207579) */ + 1, /* 32ADC (207580) */ + 1, /* 32ADD (207581) */ + 1, /* 32ADE (207582) */ + 1, /* 32ADF (207583) */ + 1, /* 32AE0 (207584) */ + 1, /* 32AE1 (207585) */ + 1, /* 32AE2 (207586) */ + 1, /* 32AE3 (207587) */ + 1, /* 32AE4 (207588) */ + 1, /* 32AE5 (207589) */ + 1, /* 32AE6 (207590) */ + 1, /* 32AE7 (207591) */ + 1, /* 32AE8 (207592) */ + 1, /* 32AE9 (207593) */ + 1, /* 32AEA (207594) */ + 1, /* 32AEB (207595) */ + 1, /* 32AEC (207596) */ + 1, /* 32AED (207597) */ + 1, /* 32AEE (207598) */ + 1, /* 32AEF (207599) */ + 1, /* 32AF0 (207600) */ + 1, /* 32AF1 (207601) */ + 1, /* 32AF2 (207602) */ + 1, /* 32AF3 (207603) */ + 1, /* 32AF4 (207604) */ + 1, /* 32AF5 (207605) */ + 1, /* 32AF6 (207606) */ + 1, /* 32AF7 (207607) */ + 1, /* 32AF8 (207608) */ + 1, /* 32AF9 (207609) */ + 1, /* 32AFA (207610) */ + 1, /* 32AFB (207611) */ + 1, /* 32AFC (207612) */ + 1, /* 32AFD (207613) */ + 1, /* 32AFE (207614) */ + 1, /* 32AFF (207615) */ + 1, /* 32B00 (207616) */ + 1, /* 32B01 (207617) */ + 1, /* 32B02 (207618) */ + 1, /* 32B03 (207619) */ + 1, /* 32B04 (207620) */ + 1, /* 32B05 (207621) */ + 1, /* 32B06 (207622) */ + 1, /* 32B07 (207623) */ + 1, /* 32B08 (207624) */ + 1, /* 32B09 (207625) */ + 1, /* 32B0A (207626) */ + 1, /* 32B0B (207627) */ + 1, /* 32B0C (207628) */ + 1, /* 32B0D (207629) */ + 1, /* 32B0E (207630) */ + 1, /* 32B0F (207631) */ + 1, /* 32B10 (207632) */ + 1, /* 32B11 (207633) */ + 1, /* 32B12 (207634) */ + 1, /* 32B13 (207635) */ + 1, /* 32B14 (207636) */ + 1, /* 32B15 (207637) */ + 1, /* 32B16 (207638) */ + 1, /* 32B17 (207639) */ + 1, /* 32B18 (207640) */ + 1, /* 32B19 (207641) */ + 1, /* 32B1A (207642) */ + 1, /* 32B1B (207643) */ + 1, /* 32B1C (207644) */ + 1, /* 32B1D (207645) */ + 1, /* 32B1E (207646) */ + 1, /* 32B1F (207647) */ + 1, /* 32B20 (207648) */ + 1, /* 32B21 (207649) */ + 1, /* 32B22 (207650) */ + 1, /* 32B23 (207651) */ + 1, /* 32B24 (207652) */ + 1, /* 32B25 (207653) */ + 1, /* 32B26 (207654) */ + 1, /* 32B27 (207655) */ + 1, /* 32B28 (207656) */ + 1, /* 32B29 (207657) */ + 1, /* 32B2A (207658) */ + 1, /* 32B2B (207659) */ + 1, /* 32B2C (207660) */ + 1, /* 32B2D (207661) */ + 1, /* 32B2E (207662) */ + 1, /* 32B2F (207663) */ + 1, /* 32B30 (207664) */ + 1, /* 32B31 (207665) */ + 1, /* 32B32 (207666) */ + 1, /* 32B33 (207667) */ + 1, /* 32B34 (207668) */ + 1, /* 32B35 (207669) */ + 1, /* 32B36 (207670) */ + 1, /* 32B37 (207671) */ + 1, /* 32B38 (207672) */ + 1, /* 32B39 (207673) */ + 1, /* 32B3A (207674) */ + 1, /* 32B3B (207675) */ + 1, /* 32B3C (207676) */ + 1, /* 32B3D (207677) */ + 1, /* 32B3E (207678) */ + 1, /* 32B3F (207679) */ + 1, /* 32B40 (207680) */ + 1, /* 32B41 (207681) */ + 1, /* 32B42 (207682) */ + 1, /* 32B43 (207683) */ + 1, /* 32B44 (207684) */ + 1, /* 32B45 (207685) */ + 1, /* 32B46 (207686) */ + 1, /* 32B47 (207687) */ + 1, /* 32B48 (207688) */ + 1, /* 32B49 (207689) */ + 1, /* 32B4A (207690) */ + 1, /* 32B4B (207691) */ + 1, /* 32B4C (207692) */ + 1, /* 32B4D (207693) */ + 1, /* 32B4E (207694) */ + 1, /* 32B4F (207695) */ + 1, /* 32B50 (207696) */ + 1, /* 32B51 (207697) */ + 1, /* 32B52 (207698) */ + 1, /* 32B53 (207699) */ + 1, /* 32B54 (207700) */ + 1, /* 32B55 (207701) */ + 1, /* 32B56 (207702) */ + 1, /* 32B57 (207703) */ + 1, /* 32B58 (207704) */ + 1, /* 32B59 (207705) */ + 1, /* 32B5A (207706) */ + 1, /* 32B5B (207707) */ + 1, /* 32B5C (207708) */ + 1, /* 32B5D (207709) */ + 1, /* 32B5E (207710) */ + 1, /* 32B5F (207711) */ + 1, /* 32B60 (207712) */ + 1, /* 32B61 (207713) */ + 1, /* 32B62 (207714) */ + 1, /* 32B63 (207715) */ + 1, /* 32B64 (207716) */ + 1, /* 32B65 (207717) */ + 1, /* 32B66 (207718) */ + 1, /* 32B67 (207719) */ + 1, /* 32B68 (207720) */ + 1, /* 32B69 (207721) */ + 1, /* 32B6A (207722) */ + 1, /* 32B6B (207723) */ + 1, /* 32B6C (207724) */ + 1, /* 32B6D (207725) */ + 1, /* 32B6E (207726) */ + 1, /* 32B6F (207727) */ + 1, /* 32B70 (207728) */ + 1, /* 32B71 (207729) */ + 1, /* 32B72 (207730) */ + 1, /* 32B73 (207731) */ + 1, /* 32B74 (207732) */ + 1, /* 32B75 (207733) */ + 1, /* 32B76 (207734) */ + 1, /* 32B77 (207735) */ + 1, /* 32B78 (207736) */ + 1, /* 32B79 (207737) */ + 1, /* 32B7A (207738) */ + 1, /* 32B7B (207739) */ + 1, /* 32B7C (207740) */ + 1, /* 32B7D (207741) */ + 1, /* 32B7E (207742) */ + 1, /* 32B7F (207743) */ + 1, /* 32B80 (207744) */ + 1, /* 32B81 (207745) */ + 1, /* 32B82 (207746) */ + 1, /* 32B83 (207747) */ + 1, /* 32B84 (207748) */ + 1, /* 32B85 (207749) */ + 1, /* 32B86 (207750) */ + 1, /* 32B87 (207751) */ + 1, /* 32B88 (207752) */ + 1, /* 32B89 (207753) */ + 1, /* 32B8A (207754) */ + 1, /* 32B8B (207755) */ + 1, /* 32B8C (207756) */ + 1, /* 32B8D (207757) */ + 1, /* 32B8E (207758) */ + 1, /* 32B8F (207759) */ + 1, /* 32B90 (207760) */ + 1, /* 32B91 (207761) */ + 1, /* 32B92 (207762) */ + 1, /* 32B93 (207763) */ + 1, /* 32B94 (207764) */ + 1, /* 32B95 (207765) */ + 1, /* 32B96 (207766) */ + 1, /* 32B97 (207767) */ + 1, /* 32B98 (207768) */ + 1, /* 32B99 (207769) */ + 1, /* 32B9A (207770) */ + 1, /* 32B9B (207771) */ + 1, /* 32B9C (207772) */ + 1, /* 32B9D (207773) */ + 1, /* 32B9E (207774) */ + 1, /* 32B9F (207775) */ + 1, /* 32BA0 (207776) */ + 1, /* 32BA1 (207777) */ + 1, /* 32BA2 (207778) */ + 1, /* 32BA3 (207779) */ + 1, /* 32BA4 (207780) */ + 1, /* 32BA5 (207781) */ + 1, /* 32BA6 (207782) */ + 1, /* 32BA7 (207783) */ + 1, /* 32BA8 (207784) */ + 1, /* 32BA9 (207785) */ + 1, /* 32BAA (207786) */ + 1, /* 32BAB (207787) */ + 1, /* 32BAC (207788) */ + 1, /* 32BAD (207789) */ + 1, /* 32BAE (207790) */ + 1, /* 32BAF (207791) */ + 1, /* 32BB0 (207792) */ + 1, /* 32BB1 (207793) */ + 1, /* 32BB2 (207794) */ + 1, /* 32BB3 (207795) */ + 1, /* 32BB4 (207796) */ + 1, /* 32BB5 (207797) */ + 1, /* 32BB6 (207798) */ + 1, /* 32BB7 (207799) */ + 1, /* 32BB8 (207800) */ + 1, /* 32BB9 (207801) */ + 1, /* 32BBA (207802) */ + 1, /* 32BBB (207803) */ + 1, /* 32BBC (207804) */ + 1, /* 32BBD (207805) */ + 1, /* 32BBE (207806) */ + 1, /* 32BBF (207807) */ + 1, /* 32BC0 (207808) */ + 1, /* 32BC1 (207809) */ + 1, /* 32BC2 (207810) */ + 1, /* 32BC3 (207811) */ + 1, /* 32BC4 (207812) */ + 1, /* 32BC5 (207813) */ + 1, /* 32BC6 (207814) */ + 1, /* 32BC7 (207815) */ + 1, /* 32BC8 (207816) */ + 1, /* 32BC9 (207817) */ + 1, /* 32BCA (207818) */ + 1, /* 32BCB (207819) */ + 1, /* 32BCC (207820) */ + 1, /* 32BCD (207821) */ + 1, /* 32BCE (207822) */ + 1, /* 32BCF (207823) */ + 1, /* 32BD0 (207824) */ + 1, /* 32BD1 (207825) */ + 1, /* 32BD2 (207826) */ + 1, /* 32BD3 (207827) */ + 1, /* 32BD4 (207828) */ + 1, /* 32BD5 (207829) */ + 1, /* 32BD6 (207830) */ + 1, /* 32BD7 (207831) */ + 1, /* 32BD8 (207832) */ + 1, /* 32BD9 (207833) */ + 1, /* 32BDA (207834) */ + 1, /* 32BDB (207835) */ + 1, /* 32BDC (207836) */ + 1, /* 32BDD (207837) */ + 1, /* 32BDE (207838) */ + 1, /* 32BDF (207839) */ + 1, /* 32BE0 (207840) */ + 1, /* 32BE1 (207841) */ + 1, /* 32BE2 (207842) */ + 1, /* 32BE3 (207843) */ + 1, /* 32BE4 (207844) */ + 1, /* 32BE5 (207845) */ + 1, /* 32BE6 (207846) */ + 1, /* 32BE7 (207847) */ + 1, /* 32BE8 (207848) */ + 1, /* 32BE9 (207849) */ + 1, /* 32BEA (207850) */ + 1, /* 32BEB (207851) */ + 1, /* 32BEC (207852) */ + 1, /* 32BED (207853) */ + 1, /* 32BEE (207854) */ + 1, /* 32BEF (207855) */ + 1, /* 32BF0 (207856) */ + 1, /* 32BF1 (207857) */ + 1, /* 32BF2 (207858) */ + 1, /* 32BF3 (207859) */ + 1, /* 32BF4 (207860) */ + 1, /* 32BF5 (207861) */ + 1, /* 32BF6 (207862) */ + 1, /* 32BF7 (207863) */ + 1, /* 32BF8 (207864) */ + 1, /* 32BF9 (207865) */ + 1, /* 32BFA (207866) */ + 1, /* 32BFB (207867) */ + 1, /* 32BFC (207868) */ + 1, /* 32BFD (207869) */ + 1, /* 32BFE (207870) */ + 1, /* 32BFF (207871) */ + 1, /* 32C00 (207872) */ + 1, /* 32C01 (207873) */ + 1, /* 32C02 (207874) */ + 1, /* 32C03 (207875) */ + 1, /* 32C04 (207876) */ + 1, /* 32C05 (207877) */ + 1, /* 32C06 (207878) */ + 1, /* 32C07 (207879) */ + 1, /* 32C08 (207880) */ + 1, /* 32C09 (207881) */ + 1, /* 32C0A (207882) */ + 1, /* 32C0B (207883) */ + 1, /* 32C0C (207884) */ + 1, /* 32C0D (207885) */ + 1, /* 32C0E (207886) */ + 1, /* 32C0F (207887) */ + 1, /* 32C10 (207888) */ + 1, /* 32C11 (207889) */ + 1, /* 32C12 (207890) */ + 1, /* 32C13 (207891) */ + 1, /* 32C14 (207892) */ + 1, /* 32C15 (207893) */ + 1, /* 32C16 (207894) */ + 1, /* 32C17 (207895) */ + 1, /* 32C18 (207896) */ + 1, /* 32C19 (207897) */ + 1, /* 32C1A (207898) */ + 1, /* 32C1B (207899) */ + 1, /* 32C1C (207900) */ + 1, /* 32C1D (207901) */ + 1, /* 32C1E (207902) */ + 1, /* 32C1F (207903) */ + 1, /* 32C20 (207904) */ + 1, /* 32C21 (207905) */ + 1, /* 32C22 (207906) */ + 1, /* 32C23 (207907) */ + 1, /* 32C24 (207908) */ + 1, /* 32C25 (207909) */ + 1, /* 32C26 (207910) */ + 1, /* 32C27 (207911) */ + 1, /* 32C28 (207912) */ + 1, /* 32C29 (207913) */ + 1, /* 32C2A (207914) */ + 1, /* 32C2B (207915) */ + 1, /* 32C2C (207916) */ + 1, /* 32C2D (207917) */ + 1, /* 32C2E (207918) */ + 1, /* 32C2F (207919) */ + 1, /* 32C30 (207920) */ + 1, /* 32C31 (207921) */ + 1, /* 32C32 (207922) */ + 1, /* 32C33 (207923) */ + 1, /* 32C34 (207924) */ + 1, /* 32C35 (207925) */ + 1, /* 32C36 (207926) */ + 1, /* 32C37 (207927) */ + 1, /* 32C38 (207928) */ + 1, /* 32C39 (207929) */ + 1, /* 32C3A (207930) */ + 1, /* 32C3B (207931) */ + 1, /* 32C3C (207932) */ + 1, /* 32C3D (207933) */ + 1, /* 32C3E (207934) */ + 1, /* 32C3F (207935) */ + 1, /* 32C40 (207936) */ + 1, /* 32C41 (207937) */ + 1, /* 32C42 (207938) */ + 1, /* 32C43 (207939) */ + 1, /* 32C44 (207940) */ + 1, /* 32C45 (207941) */ + 1, /* 32C46 (207942) */ + 1, /* 32C47 (207943) */ + 1, /* 32C48 (207944) */ + 1, /* 32C49 (207945) */ + 1, /* 32C4A (207946) */ + 1, /* 32C4B (207947) */ + 1, /* 32C4C (207948) */ + 1, /* 32C4D (207949) */ + 1, /* 32C4E (207950) */ + 1, /* 32C4F (207951) */ + 1, /* 32C50 (207952) */ + 1, /* 32C51 (207953) */ + 1, /* 32C52 (207954) */ + 1, /* 32C53 (207955) */ + 1, /* 32C54 (207956) */ + 1, /* 32C55 (207957) */ + 1, /* 32C56 (207958) */ + 1, /* 32C57 (207959) */ + 1, /* 32C58 (207960) */ + 1, /* 32C59 (207961) */ + 1, /* 32C5A (207962) */ + 1, /* 32C5B (207963) */ + 1, /* 32C5C (207964) */ + 1, /* 32C5D (207965) */ + 1, /* 32C5E (207966) */ + 1, /* 32C5F (207967) */ + 1, /* 32C60 (207968) */ + 1, /* 32C61 (207969) */ + 1, /* 32C62 (207970) */ + 1, /* 32C63 (207971) */ + 1, /* 32C64 (207972) */ + 1, /* 32C65 (207973) */ + 1, /* 32C66 (207974) */ + 1, /* 32C67 (207975) */ + 1, /* 32C68 (207976) */ + 1, /* 32C69 (207977) */ + 1, /* 32C6A (207978) */ + 1, /* 32C6B (207979) */ + 1, /* 32C6C (207980) */ + 1, /* 32C6D (207981) */ + 1, /* 32C6E (207982) */ + 1, /* 32C6F (207983) */ + 1, /* 32C70 (207984) */ + 1, /* 32C71 (207985) */ + 1, /* 32C72 (207986) */ + 1, /* 32C73 (207987) */ + 1, /* 32C74 (207988) */ + 1, /* 32C75 (207989) */ + 1, /* 32C76 (207990) */ + 1, /* 32C77 (207991) */ + 1, /* 32C78 (207992) */ + 1, /* 32C79 (207993) */ + 1, /* 32C7A (207994) */ + 1, /* 32C7B (207995) */ + 1, /* 32C7C (207996) */ + 1, /* 32C7D (207997) */ + 1, /* 32C7E (207998) */ + 1, /* 32C7F (207999) */ + 1, /* 32C80 (208000) */ + 1, /* 32C81 (208001) */ + 1, /* 32C82 (208002) */ + 1, /* 32C83 (208003) */ + 1, /* 32C84 (208004) */ + 1, /* 32C85 (208005) */ + 1, /* 32C86 (208006) */ + 1, /* 32C87 (208007) */ + 1, /* 32C88 (208008) */ + 1, /* 32C89 (208009) */ + 1, /* 32C8A (208010) */ + 1, /* 32C8B (208011) */ + 1, /* 32C8C (208012) */ + 1, /* 32C8D (208013) */ + 1, /* 32C8E (208014) */ + 1, /* 32C8F (208015) */ + 1, /* 32C90 (208016) */ + 1, /* 32C91 (208017) */ + 1, /* 32C92 (208018) */ + 1, /* 32C93 (208019) */ + 1, /* 32C94 (208020) */ + 1, /* 32C95 (208021) */ + 1, /* 32C96 (208022) */ + 1, /* 32C97 (208023) */ + 1, /* 32C98 (208024) */ + 1, /* 32C99 (208025) */ + 1, /* 32C9A (208026) */ + 1, /* 32C9B (208027) */ + 1, /* 32C9C (208028) */ + 1, /* 32C9D (208029) */ + 1, /* 32C9E (208030) */ + 1, /* 32C9F (208031) */ + 1, /* 32CA0 (208032) */ + 1, /* 32CA1 (208033) */ + 1, /* 32CA2 (208034) */ + 1, /* 32CA3 (208035) */ + 1, /* 32CA4 (208036) */ + 1, /* 32CA5 (208037) */ + 1, /* 32CA6 (208038) */ + 1, /* 32CA7 (208039) */ + 1, /* 32CA8 (208040) */ + 1, /* 32CA9 (208041) */ + 1, /* 32CAA (208042) */ + 1, /* 32CAB (208043) */ + 1, /* 32CAC (208044) */ + 1, /* 32CAD (208045) */ + 1, /* 32CAE (208046) */ + 1, /* 32CAF (208047) */ + 1, /* 32CB0 (208048) */ + 1, /* 32CB1 (208049) */ + 1, /* 32CB2 (208050) */ + 1, /* 32CB3 (208051) */ + 1, /* 32CB4 (208052) */ + 1, /* 32CB5 (208053) */ + 1, /* 32CB6 (208054) */ + 1, /* 32CB7 (208055) */ + 1, /* 32CB8 (208056) */ + 1, /* 32CB9 (208057) */ + 1, /* 32CBA (208058) */ + 1, /* 32CBB (208059) */ + 1, /* 32CBC (208060) */ + 1, /* 32CBD (208061) */ + 1, /* 32CBE (208062) */ + 1, /* 32CBF (208063) */ + 1, /* 32CC0 (208064) */ + 1, /* 32CC1 (208065) */ + 1, /* 32CC2 (208066) */ + 1, /* 32CC3 (208067) */ + 1, /* 32CC4 (208068) */ + 1, /* 32CC5 (208069) */ + 1, /* 32CC6 (208070) */ + 1, /* 32CC7 (208071) */ + 1, /* 32CC8 (208072) */ + 1, /* 32CC9 (208073) */ + 1, /* 32CCA (208074) */ + 1, /* 32CCB (208075) */ + 1, /* 32CCC (208076) */ + 1, /* 32CCD (208077) */ + 1, /* 32CCE (208078) */ + 1, /* 32CCF (208079) */ + 1, /* 32CD0 (208080) */ + 1, /* 32CD1 (208081) */ + 1, /* 32CD2 (208082) */ + 1, /* 32CD3 (208083) */ + 1, /* 32CD4 (208084) */ + 1, /* 32CD5 (208085) */ + 1, /* 32CD6 (208086) */ + 1, /* 32CD7 (208087) */ + 1, /* 32CD8 (208088) */ + 1, /* 32CD9 (208089) */ + 1, /* 32CDA (208090) */ + 1, /* 32CDB (208091) */ + 1, /* 32CDC (208092) */ + 1, /* 32CDD (208093) */ + 1, /* 32CDE (208094) */ + 1, /* 32CDF (208095) */ + 1, /* 32CE0 (208096) */ + 1, /* 32CE1 (208097) */ + 1, /* 32CE2 (208098) */ + 1, /* 32CE3 (208099) */ + 1, /* 32CE4 (208100) */ + 1, /* 32CE5 (208101) */ + 1, /* 32CE6 (208102) */ + 1, /* 32CE7 (208103) */ + 1, /* 32CE8 (208104) */ + 1, /* 32CE9 (208105) */ + 1, /* 32CEA (208106) */ + 1, /* 32CEB (208107) */ + 1, /* 32CEC (208108) */ + 1, /* 32CED (208109) */ + 1, /* 32CEE (208110) */ + 1, /* 32CEF (208111) */ + 1, /* 32CF0 (208112) */ + 1, /* 32CF1 (208113) */ + 1, /* 32CF2 (208114) */ + 1, /* 32CF3 (208115) */ + 1, /* 32CF4 (208116) */ + 1, /* 32CF5 (208117) */ + 1, /* 32CF6 (208118) */ + 1, /* 32CF7 (208119) */ + 1, /* 32CF8 (208120) */ + 1, /* 32CF9 (208121) */ + 1, /* 32CFA (208122) */ + 1, /* 32CFB (208123) */ + 1, /* 32CFC (208124) */ + 1, /* 32CFD (208125) */ + 1, /* 32CFE (208126) */ + 1, /* 32CFF (208127) */ + 1, /* 32D00 (208128) */ + 1, /* 32D01 (208129) */ + 1, /* 32D02 (208130) */ + 1, /* 32D03 (208131) */ + 1, /* 32D04 (208132) */ + 1, /* 32D05 (208133) */ + 1, /* 32D06 (208134) */ + 1, /* 32D07 (208135) */ + 1, /* 32D08 (208136) */ + 1, /* 32D09 (208137) */ + 1, /* 32D0A (208138) */ + 1, /* 32D0B (208139) */ + 1, /* 32D0C (208140) */ + 1, /* 32D0D (208141) */ + 1, /* 32D0E (208142) */ + 1, /* 32D0F (208143) */ + 1, /* 32D10 (208144) */ + 1, /* 32D11 (208145) */ + 1, /* 32D12 (208146) */ + 1, /* 32D13 (208147) */ + 1, /* 32D14 (208148) */ + 1, /* 32D15 (208149) */ + 1, /* 32D16 (208150) */ + 1, /* 32D17 (208151) */ + 1, /* 32D18 (208152) */ + 1, /* 32D19 (208153) */ + 1, /* 32D1A (208154) */ + 1, /* 32D1B (208155) */ + 1, /* 32D1C (208156) */ + 1, /* 32D1D (208157) */ + 1, /* 32D1E (208158) */ + 1, /* 32D1F (208159) */ + 1, /* 32D20 (208160) */ + 1, /* 32D21 (208161) */ + 1, /* 32D22 (208162) */ + 1, /* 32D23 (208163) */ + 1, /* 32D24 (208164) */ + 1, /* 32D25 (208165) */ + 1, /* 32D26 (208166) */ + 1, /* 32D27 (208167) */ + 1, /* 32D28 (208168) */ + 1, /* 32D29 (208169) */ + 1, /* 32D2A (208170) */ + 1, /* 32D2B (208171) */ + 1, /* 32D2C (208172) */ + 1, /* 32D2D (208173) */ + 1, /* 32D2E (208174) */ + 1, /* 32D2F (208175) */ + 1, /* 32D30 (208176) */ + 1, /* 32D31 (208177) */ + 1, /* 32D32 (208178) */ + 1, /* 32D33 (208179) */ + 1, /* 32D34 (208180) */ + 1, /* 32D35 (208181) */ + 1, /* 32D36 (208182) */ + 1, /* 32D37 (208183) */ + 1, /* 32D38 (208184) */ + 1, /* 32D39 (208185) */ + 1, /* 32D3A (208186) */ + 1, /* 32D3B (208187) */ + 1, /* 32D3C (208188) */ + 1, /* 32D3D (208189) */ + 1, /* 32D3E (208190) */ + 1, /* 32D3F (208191) */ + 1, /* 32D40 (208192) */ + 1, /* 32D41 (208193) */ + 1, /* 32D42 (208194) */ + 1, /* 32D43 (208195) */ + 1, /* 32D44 (208196) */ + 1, /* 32D45 (208197) */ + 1, /* 32D46 (208198) */ + 1, /* 32D47 (208199) */ + 1, /* 32D48 (208200) */ + 1, /* 32D49 (208201) */ + 1, /* 32D4A (208202) */ + 1, /* 32D4B (208203) */ + 1, /* 32D4C (208204) */ + 1, /* 32D4D (208205) */ + 1, /* 32D4E (208206) */ + 1, /* 32D4F (208207) */ + 1, /* 32D50 (208208) */ + 1, /* 32D51 (208209) */ + 1, /* 32D52 (208210) */ + 1, /* 32D53 (208211) */ + 1, /* 32D54 (208212) */ + 1, /* 32D55 (208213) */ + 1, /* 32D56 (208214) */ + 1, /* 32D57 (208215) */ + 1, /* 32D58 (208216) */ + 1, /* 32D59 (208217) */ + 1, /* 32D5A (208218) */ + 1, /* 32D5B (208219) */ + 1, /* 32D5C (208220) */ + 1, /* 32D5D (208221) */ + 1, /* 32D5E (208222) */ + 1, /* 32D5F (208223) */ + 1, /* 32D60 (208224) */ + 1, /* 32D61 (208225) */ + 1, /* 32D62 (208226) */ + 1, /* 32D63 (208227) */ + 1, /* 32D64 (208228) */ + 1, /* 32D65 (208229) */ + 1, /* 32D66 (208230) */ + 1, /* 32D67 (208231) */ + 1, /* 32D68 (208232) */ + 1, /* 32D69 (208233) */ + 1, /* 32D6A (208234) */ + 1, /* 32D6B (208235) */ + 1, /* 32D6C (208236) */ + 1, /* 32D6D (208237) */ + 1, /* 32D6E (208238) */ + 1, /* 32D6F (208239) */ + 1, /* 32D70 (208240) */ + 1, /* 32D71 (208241) */ + 1, /* 32D72 (208242) */ + 1, /* 32D73 (208243) */ + 1, /* 32D74 (208244) */ + 1, /* 32D75 (208245) */ + 1, /* 32D76 (208246) */ + 1, /* 32D77 (208247) */ + 1, /* 32D78 (208248) */ + 1, /* 32D79 (208249) */ + 1, /* 32D7A (208250) */ + 1, /* 32D7B (208251) */ + 1, /* 32D7C (208252) */ + 1, /* 32D7D (208253) */ + 1, /* 32D7E (208254) */ + 1, /* 32D7F (208255) */ + 1, /* 32D80 (208256) */ + 1, /* 32D81 (208257) */ + 1, /* 32D82 (208258) */ + 1, /* 32D83 (208259) */ + 1, /* 32D84 (208260) */ + 1, /* 32D85 (208261) */ + 1, /* 32D86 (208262) */ + 1, /* 32D87 (208263) */ + 1, /* 32D88 (208264) */ + 1, /* 32D89 (208265) */ + 1, /* 32D8A (208266) */ + 1, /* 32D8B (208267) */ + 1, /* 32D8C (208268) */ + 1, /* 32D8D (208269) */ + 1, /* 32D8E (208270) */ + 1, /* 32D8F (208271) */ + 1, /* 32D90 (208272) */ + 1, /* 32D91 (208273) */ + 1, /* 32D92 (208274) */ + 1, /* 32D93 (208275) */ + 1, /* 32D94 (208276) */ + 1, /* 32D95 (208277) */ + 1, /* 32D96 (208278) */ + 1, /* 32D97 (208279) */ + 1, /* 32D98 (208280) */ + 1, /* 32D99 (208281) */ + 1, /* 32D9A (208282) */ + 1, /* 32D9B (208283) */ + 1, /* 32D9C (208284) */ + 1, /* 32D9D (208285) */ + 1, /* 32D9E (208286) */ + 1, /* 32D9F (208287) */ + 1, /* 32DA0 (208288) */ + 1, /* 32DA1 (208289) */ + 1, /* 32DA2 (208290) */ + 1, /* 32DA3 (208291) */ + 1, /* 32DA4 (208292) */ + 1, /* 32DA5 (208293) */ + 1, /* 32DA6 (208294) */ + 1, /* 32DA7 (208295) */ + 1, /* 32DA8 (208296) */ + 1, /* 32DA9 (208297) */ + 1, /* 32DAA (208298) */ + 1, /* 32DAB (208299) */ + 1, /* 32DAC (208300) */ + 1, /* 32DAD (208301) */ + 1, /* 32DAE (208302) */ + 1, /* 32DAF (208303) */ + 1, /* 32DB0 (208304) */ + 1, /* 32DB1 (208305) */ + 1, /* 32DB2 (208306) */ + 1, /* 32DB3 (208307) */ + 1, /* 32DB4 (208308) */ + 1, /* 32DB5 (208309) */ + 1, /* 32DB6 (208310) */ + 1, /* 32DB7 (208311) */ + 1, /* 32DB8 (208312) */ + 1, /* 32DB9 (208313) */ + 1, /* 32DBA (208314) */ + 1, /* 32DBB (208315) */ + 1, /* 32DBC (208316) */ + 1, /* 32DBD (208317) */ + 1, /* 32DBE (208318) */ + 1, /* 32DBF (208319) */ + 1, /* 32DC0 (208320) */ + 1, /* 32DC1 (208321) */ + 1, /* 32DC2 (208322) */ + 1, /* 32DC3 (208323) */ + 1, /* 32DC4 (208324) */ + 1, /* 32DC5 (208325) */ + 1, /* 32DC6 (208326) */ + 1, /* 32DC7 (208327) */ + 1, /* 32DC8 (208328) */ + 1, /* 32DC9 (208329) */ + 1, /* 32DCA (208330) */ + 1, /* 32DCB (208331) */ + 1, /* 32DCC (208332) */ + 1, /* 32DCD (208333) */ + 1, /* 32DCE (208334) */ + 1, /* 32DCF (208335) */ + 1, /* 32DD0 (208336) */ + 1, /* 32DD1 (208337) */ + 1, /* 32DD2 (208338) */ + 1, /* 32DD3 (208339) */ + 1, /* 32DD4 (208340) */ + 1, /* 32DD5 (208341) */ + 1, /* 32DD6 (208342) */ + 1, /* 32DD7 (208343) */ + 1, /* 32DD8 (208344) */ + 1, /* 32DD9 (208345) */ + 1, /* 32DDA (208346) */ + 1, /* 32DDB (208347) */ + 1, /* 32DDC (208348) */ + 1, /* 32DDD (208349) */ + 1, /* 32DDE (208350) */ + 1, /* 32DDF (208351) */ + 1, /* 32DE0 (208352) */ + 1, /* 32DE1 (208353) */ + 1, /* 32DE2 (208354) */ + 1, /* 32DE3 (208355) */ + 1, /* 32DE4 (208356) */ + 1, /* 32DE5 (208357) */ + 1, /* 32DE6 (208358) */ + 1, /* 32DE7 (208359) */ + 1, /* 32DE8 (208360) */ + 1, /* 32DE9 (208361) */ + 1, /* 32DEA (208362) */ + 1, /* 32DEB (208363) */ + 1, /* 32DEC (208364) */ + 1, /* 32DED (208365) */ + 1, /* 32DEE (208366) */ + 1, /* 32DEF (208367) */ + 1, /* 32DF0 (208368) */ + 1, /* 32DF1 (208369) */ + 1, /* 32DF2 (208370) */ + 1, /* 32DF3 (208371) */ + 1, /* 32DF4 (208372) */ + 1, /* 32DF5 (208373) */ + 1, /* 32DF6 (208374) */ + 1, /* 32DF7 (208375) */ + 1, /* 32DF8 (208376) */ + 1, /* 32DF9 (208377) */ + 1, /* 32DFA (208378) */ + 1, /* 32DFB (208379) */ + 1, /* 32DFC (208380) */ + 1, /* 32DFD (208381) */ + 1, /* 32DFE (208382) */ + 1, /* 32DFF (208383) */ + 1, /* 32E00 (208384) */ + 1, /* 32E01 (208385) */ + 1, /* 32E02 (208386) */ + 1, /* 32E03 (208387) */ + 1, /* 32E04 (208388) */ + 1, /* 32E05 (208389) */ + 1, /* 32E06 (208390) */ + 1, /* 32E07 (208391) */ + 1, /* 32E08 (208392) */ + 1, /* 32E09 (208393) */ + 1, /* 32E0A (208394) */ + 1, /* 32E0B (208395) */ + 1, /* 32E0C (208396) */ + 1, /* 32E0D (208397) */ + 1, /* 32E0E (208398) */ + 1, /* 32E0F (208399) */ + 1, /* 32E10 (208400) */ + 1, /* 32E11 (208401) */ + 1, /* 32E12 (208402) */ + 1, /* 32E13 (208403) */ + 1, /* 32E14 (208404) */ + 1, /* 32E15 (208405) */ + 1, /* 32E16 (208406) */ + 1, /* 32E17 (208407) */ + 1, /* 32E18 (208408) */ + 1, /* 32E19 (208409) */ + 1, /* 32E1A (208410) */ + 1, /* 32E1B (208411) */ + 1, /* 32E1C (208412) */ + 1, /* 32E1D (208413) */ + 1, /* 32E1E (208414) */ + 1, /* 32E1F (208415) */ + 1, /* 32E20 (208416) */ + 1, /* 32E21 (208417) */ + 1, /* 32E22 (208418) */ + 1, /* 32E23 (208419) */ + 1, /* 32E24 (208420) */ + 1, /* 32E25 (208421) */ + 1, /* 32E26 (208422) */ + 1, /* 32E27 (208423) */ + 1, /* 32E28 (208424) */ + 1, /* 32E29 (208425) */ + 1, /* 32E2A (208426) */ + 1, /* 32E2B (208427) */ + 1, /* 32E2C (208428) */ + 1, /* 32E2D (208429) */ + 1, /* 32E2E (208430) */ + 1, /* 32E2F (208431) */ + 1, /* 32E30 (208432) */ + 1, /* 32E31 (208433) */ + 1, /* 32E32 (208434) */ + 1, /* 32E33 (208435) */ + 1, /* 32E34 (208436) */ + 1, /* 32E35 (208437) */ + 1, /* 32E36 (208438) */ + 1, /* 32E37 (208439) */ + 1, /* 32E38 (208440) */ + 1, /* 32E39 (208441) */ + 1, /* 32E3A (208442) */ + 1, /* 32E3B (208443) */ + 1, /* 32E3C (208444) */ + 1, /* 32E3D (208445) */ + 1, /* 32E3E (208446) */ + 1, /* 32E3F (208447) */ + 1, /* 32E40 (208448) */ + 1, /* 32E41 (208449) */ + 1, /* 32E42 (208450) */ + 1, /* 32E43 (208451) */ + 1, /* 32E44 (208452) */ + 1, /* 32E45 (208453) */ + 1, /* 32E46 (208454) */ + 1, /* 32E47 (208455) */ + 1, /* 32E48 (208456) */ + 1, /* 32E49 (208457) */ + 1, /* 32E4A (208458) */ + 1, /* 32E4B (208459) */ + 1, /* 32E4C (208460) */ + 1, /* 32E4D (208461) */ + 1, /* 32E4E (208462) */ + 1, /* 32E4F (208463) */ + 1, /* 32E50 (208464) */ + 1, /* 32E51 (208465) */ + 1, /* 32E52 (208466) */ + 1, /* 32E53 (208467) */ + 1, /* 32E54 (208468) */ + 1, /* 32E55 (208469) */ + 1, /* 32E56 (208470) */ + 1, /* 32E57 (208471) */ + 1, /* 32E58 (208472) */ + 1, /* 32E59 (208473) */ + 1, /* 32E5A (208474) */ + 1, /* 32E5B (208475) */ + 1, /* 32E5C (208476) */ + 1, /* 32E5D (208477) */ + 1, /* 32E5E (208478) */ + 1, /* 32E5F (208479) */ + 1, /* 32E60 (208480) */ + 1, /* 32E61 (208481) */ + 1, /* 32E62 (208482) */ + 1, /* 32E63 (208483) */ + 1, /* 32E64 (208484) */ + 1, /* 32E65 (208485) */ + 1, /* 32E66 (208486) */ + 1, /* 32E67 (208487) */ + 1, /* 32E68 (208488) */ + 1, /* 32E69 (208489) */ + 1, /* 32E6A (208490) */ + 1, /* 32E6B (208491) */ + 1, /* 32E6C (208492) */ + 1, /* 32E6D (208493) */ + 1, /* 32E6E (208494) */ + 1, /* 32E6F (208495) */ + 1, /* 32E70 (208496) */ + 1, /* 32E71 (208497) */ + 1, /* 32E72 (208498) */ + 1, /* 32E73 (208499) */ + 1, /* 32E74 (208500) */ + 1, /* 32E75 (208501) */ + 1, /* 32E76 (208502) */ + 1, /* 32E77 (208503) */ + 1, /* 32E78 (208504) */ + 1, /* 32E79 (208505) */ + 1, /* 32E7A (208506) */ + 1, /* 32E7B (208507) */ + 1, /* 32E7C (208508) */ + 1, /* 32E7D (208509) */ + 1, /* 32E7E (208510) */ + 1, /* 32E7F (208511) */ + 1, /* 32E80 (208512) */ + 1, /* 32E81 (208513) */ + 1, /* 32E82 (208514) */ + 1, /* 32E83 (208515) */ + 1, /* 32E84 (208516) */ + 1, /* 32E85 (208517) */ + 1, /* 32E86 (208518) */ + 1, /* 32E87 (208519) */ + 1, /* 32E88 (208520) */ + 1, /* 32E89 (208521) */ + 1, /* 32E8A (208522) */ + 1, /* 32E8B (208523) */ + 1, /* 32E8C (208524) */ + 1, /* 32E8D (208525) */ + 1, /* 32E8E (208526) */ + 1, /* 32E8F (208527) */ + 1, /* 32E90 (208528) */ + 1, /* 32E91 (208529) */ + 1, /* 32E92 (208530) */ + 1, /* 32E93 (208531) */ + 1, /* 32E94 (208532) */ + 1, /* 32E95 (208533) */ + 1, /* 32E96 (208534) */ + 1, /* 32E97 (208535) */ + 1, /* 32E98 (208536) */ + 1, /* 32E99 (208537) */ + 1, /* 32E9A (208538) */ + 1, /* 32E9B (208539) */ + 1, /* 32E9C (208540) */ + 1, /* 32E9D (208541) */ + 1, /* 32E9E (208542) */ + 1, /* 32E9F (208543) */ + 1, /* 32EA0 (208544) */ + 1, /* 32EA1 (208545) */ + 1, /* 32EA2 (208546) */ + 1, /* 32EA3 (208547) */ + 1, /* 32EA4 (208548) */ + 1, /* 32EA5 (208549) */ + 1, /* 32EA6 (208550) */ + 1, /* 32EA7 (208551) */ + 1, /* 32EA8 (208552) */ + 1, /* 32EA9 (208553) */ + 1, /* 32EAA (208554) */ + 1, /* 32EAB (208555) */ + 1, /* 32EAC (208556) */ + 1, /* 32EAD (208557) */ + 1, /* 32EAE (208558) */ + 1, /* 32EAF (208559) */ + 1, /* 32EB0 (208560) */ + 1, /* 32EB1 (208561) */ + 1, /* 32EB2 (208562) */ + 1, /* 32EB3 (208563) */ + 1, /* 32EB4 (208564) */ + 1, /* 32EB5 (208565) */ + 1, /* 32EB6 (208566) */ + 1, /* 32EB7 (208567) */ + 1, /* 32EB8 (208568) */ + 1, /* 32EB9 (208569) */ + 1, /* 32EBA (208570) */ + 1, /* 32EBB (208571) */ + 1, /* 32EBC (208572) */ + 1, /* 32EBD (208573) */ + 1, /* 32EBE (208574) */ + 1, /* 32EBF (208575) */ + 1, /* 32EC0 (208576) */ + 1, /* 32EC1 (208577) */ + 1, /* 32EC2 (208578) */ + 1, /* 32EC3 (208579) */ + 1, /* 32EC4 (208580) */ + 1, /* 32EC5 (208581) */ + 1, /* 32EC6 (208582) */ + 1, /* 32EC7 (208583) */ + 1, /* 32EC8 (208584) */ + 1, /* 32EC9 (208585) */ + 1, /* 32ECA (208586) */ + 1, /* 32ECB (208587) */ + 1, /* 32ECC (208588) */ + 1, /* 32ECD (208589) */ + 1, /* 32ECE (208590) */ + 1, /* 32ECF (208591) */ + 1, /* 32ED0 (208592) */ + 1, /* 32ED1 (208593) */ + 1, /* 32ED2 (208594) */ + 1, /* 32ED3 (208595) */ + 1, /* 32ED4 (208596) */ + 1, /* 32ED5 (208597) */ + 1, /* 32ED6 (208598) */ + 1, /* 32ED7 (208599) */ + 1, /* 32ED8 (208600) */ + 1, /* 32ED9 (208601) */ + 1, /* 32EDA (208602) */ + 1, /* 32EDB (208603) */ + 1, /* 32EDC (208604) */ + 1, /* 32EDD (208605) */ + 1, /* 32EDE (208606) */ + 1, /* 32EDF (208607) */ + 1, /* 32EE0 (208608) */ + 1, /* 32EE1 (208609) */ + 1, /* 32EE2 (208610) */ + 1, /* 32EE3 (208611) */ + 1, /* 32EE4 (208612) */ + 1, /* 32EE5 (208613) */ + 1, /* 32EE6 (208614) */ + 1, /* 32EE7 (208615) */ + 1, /* 32EE8 (208616) */ + 1, /* 32EE9 (208617) */ + 1, /* 32EEA (208618) */ + 1, /* 32EEB (208619) */ + 1, /* 32EEC (208620) */ + 1, /* 32EED (208621) */ + 1, /* 32EEE (208622) */ + 1, /* 32EEF (208623) */ + 1, /* 32EF0 (208624) */ + 1, /* 32EF1 (208625) */ + 1, /* 32EF2 (208626) */ + 1, /* 32EF3 (208627) */ + 1, /* 32EF4 (208628) */ + 1, /* 32EF5 (208629) */ + 1, /* 32EF6 (208630) */ + 1, /* 32EF7 (208631) */ + 1, /* 32EF8 (208632) */ + 1, /* 32EF9 (208633) */ + 1, /* 32EFA (208634) */ + 1, /* 32EFB (208635) */ + 1, /* 32EFC (208636) */ + 1, /* 32EFD (208637) */ + 1, /* 32EFE (208638) */ + 1, /* 32EFF (208639) */ + 1, /* 32F00 (208640) */ + 1, /* 32F01 (208641) */ + 1, /* 32F02 (208642) */ + 1, /* 32F03 (208643) */ + 1, /* 32F04 (208644) */ + 1, /* 32F05 (208645) */ + 1, /* 32F06 (208646) */ + 1, /* 32F07 (208647) */ + 1, /* 32F08 (208648) */ + 1, /* 32F09 (208649) */ + 1, /* 32F0A (208650) */ + 1, /* 32F0B (208651) */ + 1, /* 32F0C (208652) */ + 1, /* 32F0D (208653) */ + 1, /* 32F0E (208654) */ + 1, /* 32F0F (208655) */ + 1, /* 32F10 (208656) */ + 1, /* 32F11 (208657) */ + 1, /* 32F12 (208658) */ + 1, /* 32F13 (208659) */ + 1, /* 32F14 (208660) */ + 1, /* 32F15 (208661) */ + 1, /* 32F16 (208662) */ + 1, /* 32F17 (208663) */ + 1, /* 32F18 (208664) */ + 1, /* 32F19 (208665) */ + 1, /* 32F1A (208666) */ + 1, /* 32F1B (208667) */ + 1, /* 32F1C (208668) */ + 1, /* 32F1D (208669) */ + 1, /* 32F1E (208670) */ + 1, /* 32F1F (208671) */ + 1, /* 32F20 (208672) */ + 1, /* 32F21 (208673) */ + 1, /* 32F22 (208674) */ + 1, /* 32F23 (208675) */ + 1, /* 32F24 (208676) */ + 1, /* 32F25 (208677) */ + 1, /* 32F26 (208678) */ + 1, /* 32F27 (208679) */ + 1, /* 32F28 (208680) */ + 1, /* 32F29 (208681) */ + 1, /* 32F2A (208682) */ + 1, /* 32F2B (208683) */ + 1, /* 32F2C (208684) */ + 1, /* 32F2D (208685) */ + 1, /* 32F2E (208686) */ + 1, /* 32F2F (208687) */ + 1, /* 32F30 (208688) */ + 1, /* 32F31 (208689) */ + 1, /* 32F32 (208690) */ + 1, /* 32F33 (208691) */ + 1, /* 32F34 (208692) */ + 1, /* 32F35 (208693) */ + 1, /* 32F36 (208694) */ + 1, /* 32F37 (208695) */ + 1, /* 32F38 (208696) */ + 1, /* 32F39 (208697) */ + 1, /* 32F3A (208698) */ + 1, /* 32F3B (208699) */ + 1, /* 32F3C (208700) */ + 1, /* 32F3D (208701) */ + 1, /* 32F3E (208702) */ + 1, /* 32F3F (208703) */ + 1, /* 32F40 (208704) */ + 1, /* 32F41 (208705) */ + 1, /* 32F42 (208706) */ + 1, /* 32F43 (208707) */ + 1, /* 32F44 (208708) */ + 1, /* 32F45 (208709) */ + 1, /* 32F46 (208710) */ + 1, /* 32F47 (208711) */ + 1, /* 32F48 (208712) */ + 1, /* 32F49 (208713) */ + 1, /* 32F4A (208714) */ + 1, /* 32F4B (208715) */ + 1, /* 32F4C (208716) */ + 1, /* 32F4D (208717) */ + 1, /* 32F4E (208718) */ + 1, /* 32F4F (208719) */ + 1, /* 32F50 (208720) */ + 1, /* 32F51 (208721) */ + 1, /* 32F52 (208722) */ + 1, /* 32F53 (208723) */ + 1, /* 32F54 (208724) */ + 1, /* 32F55 (208725) */ + 1, /* 32F56 (208726) */ + 1, /* 32F57 (208727) */ + 1, /* 32F58 (208728) */ + 1, /* 32F59 (208729) */ + 1, /* 32F5A (208730) */ + 1, /* 32F5B (208731) */ + 1, /* 32F5C (208732) */ + 1, /* 32F5D (208733) */ + 1, /* 32F5E (208734) */ + 1, /* 32F5F (208735) */ + 1, /* 32F60 (208736) */ + 1, /* 32F61 (208737) */ + 1, /* 32F62 (208738) */ + 1, /* 32F63 (208739) */ + 1, /* 32F64 (208740) */ + 1, /* 32F65 (208741) */ + 1, /* 32F66 (208742) */ + 1, /* 32F67 (208743) */ + 1, /* 32F68 (208744) */ + 1, /* 32F69 (208745) */ + 1, /* 32F6A (208746) */ + 1, /* 32F6B (208747) */ + 1, /* 32F6C (208748) */ + 1, /* 32F6D (208749) */ + 1, /* 32F6E (208750) */ + 1, /* 32F6F (208751) */ + 1, /* 32F70 (208752) */ + 1, /* 32F71 (208753) */ + 1, /* 32F72 (208754) */ + 1, /* 32F73 (208755) */ + 1, /* 32F74 (208756) */ + 1, /* 32F75 (208757) */ + 1, /* 32F76 (208758) */ + 1, /* 32F77 (208759) */ + 1, /* 32F78 (208760) */ + 1, /* 32F79 (208761) */ + 1, /* 32F7A (208762) */ + 1, /* 32F7B (208763) */ + 1, /* 32F7C (208764) */ + 1, /* 32F7D (208765) */ + 1, /* 32F7E (208766) */ + 1, /* 32F7F (208767) */ + 1, /* 32F80 (208768) */ + 1, /* 32F81 (208769) */ + 1, /* 32F82 (208770) */ + 1, /* 32F83 (208771) */ + 1, /* 32F84 (208772) */ + 1, /* 32F85 (208773) */ + 1, /* 32F86 (208774) */ + 1, /* 32F87 (208775) */ + 1, /* 32F88 (208776) */ + 1, /* 32F89 (208777) */ + 1, /* 32F8A (208778) */ + 1, /* 32F8B (208779) */ + 1, /* 32F8C (208780) */ + 1, /* 32F8D (208781) */ + 1, /* 32F8E (208782) */ + 1, /* 32F8F (208783) */ + 1, /* 32F90 (208784) */ + 1, /* 32F91 (208785) */ + 1, /* 32F92 (208786) */ + 1, /* 32F93 (208787) */ + 1, /* 32F94 (208788) */ + 1, /* 32F95 (208789) */ + 1, /* 32F96 (208790) */ + 1, /* 32F97 (208791) */ + 1, /* 32F98 (208792) */ + 1, /* 32F99 (208793) */ + 1, /* 32F9A (208794) */ + 1, /* 32F9B (208795) */ + 1, /* 32F9C (208796) */ + 1, /* 32F9D (208797) */ + 1, /* 32F9E (208798) */ + 1, /* 32F9F (208799) */ + 1, /* 32FA0 (208800) */ + 1, /* 32FA1 (208801) */ + 1, /* 32FA2 (208802) */ + 1, /* 32FA3 (208803) */ + 1, /* 32FA4 (208804) */ + 1, /* 32FA5 (208805) */ + 1, /* 32FA6 (208806) */ + 1, /* 32FA7 (208807) */ + 1, /* 32FA8 (208808) */ + 1, /* 32FA9 (208809) */ + 1, /* 32FAA (208810) */ + 1, /* 32FAB (208811) */ + 1, /* 32FAC (208812) */ + 1, /* 32FAD (208813) */ + 1, /* 32FAE (208814) */ + 1, /* 32FAF (208815) */ + 1, /* 32FB0 (208816) */ + 1, /* 32FB1 (208817) */ + 1, /* 32FB2 (208818) */ + 1, /* 32FB3 (208819) */ + 1, /* 32FB4 (208820) */ + 1, /* 32FB5 (208821) */ + 1, /* 32FB6 (208822) */ + 1, /* 32FB7 (208823) */ + 1, /* 32FB8 (208824) */ + 1, /* 32FB9 (208825) */ + 1, /* 32FBA (208826) */ + 1, /* 32FBB (208827) */ + 1, /* 32FBC (208828) */ + 1, /* 32FBD (208829) */ + 1, /* 32FBE (208830) */ + 1, /* 32FBF (208831) */ + 1, /* 32FC0 (208832) */ + 1, /* 32FC1 (208833) */ + 1, /* 32FC2 (208834) */ + 1, /* 32FC3 (208835) */ + 1, /* 32FC4 (208836) */ + 1, /* 32FC5 (208837) */ + 1, /* 32FC6 (208838) */ + 1, /* 32FC7 (208839) */ + 1, /* 32FC8 (208840) */ + 1, /* 32FC9 (208841) */ + 1, /* 32FCA (208842) */ + 1, /* 32FCB (208843) */ + 1, /* 32FCC (208844) */ + 1, /* 32FCD (208845) */ + 1, /* 32FCE (208846) */ + 1, /* 32FCF (208847) */ + 1, /* 32FD0 (208848) */ + 1, /* 32FD1 (208849) */ + 1, /* 32FD2 (208850) */ + 1, /* 32FD3 (208851) */ + 1, /* 32FD4 (208852) */ + 1, /* 32FD5 (208853) */ + 1, /* 32FD6 (208854) */ + 1, /* 32FD7 (208855) */ + 1, /* 32FD8 (208856) */ + 1, /* 32FD9 (208857) */ + 1, /* 32FDA (208858) */ + 1, /* 32FDB (208859) */ + 1, /* 32FDC (208860) */ + 1, /* 32FDD (208861) */ + 1, /* 32FDE (208862) */ + 1, /* 32FDF (208863) */ + 1, /* 32FE0 (208864) */ + 1, /* 32FE1 (208865) */ + 1, /* 32FE2 (208866) */ + 1, /* 32FE3 (208867) */ + 1, /* 32FE4 (208868) */ + 1, /* 32FE5 (208869) */ + 1, /* 32FE6 (208870) */ + 1, /* 32FE7 (208871) */ + 1, /* 32FE8 (208872) */ + 1, /* 32FE9 (208873) */ + 1, /* 32FEA (208874) */ + 1, /* 32FEB (208875) */ + 1, /* 32FEC (208876) */ + 1, /* 32FED (208877) */ + 1, /* 32FEE (208878) */ + 1, /* 32FEF (208879) */ + 1, /* 32FF0 (208880) */ + 1, /* 32FF1 (208881) */ + 1, /* 32FF2 (208882) */ + 1, /* 32FF3 (208883) */ + 1, /* 32FF4 (208884) */ + 1, /* 32FF5 (208885) */ + 1, /* 32FF6 (208886) */ + 1, /* 32FF7 (208887) */ + 1, /* 32FF8 (208888) */ + 1, /* 32FF9 (208889) */ + 1, /* 32FFA (208890) */ + 1, /* 32FFB (208891) */ + 1, /* 32FFC (208892) */ + 1, /* 32FFD (208893) */ + 1, /* 32FFE (208894) */ + 1, /* 32FFF (208895) */ + 1, /* 33000 (208896) */ + 1, /* 33001 (208897) */ + 1, /* 33002 (208898) */ + 1, /* 33003 (208899) */ + 1, /* 33004 (208900) */ + 1, /* 33005 (208901) */ + 1, /* 33006 (208902) */ + 1, /* 33007 (208903) */ + 1, /* 33008 (208904) */ + 1, /* 33009 (208905) */ + 1, /* 3300A (208906) */ + 1, /* 3300B (208907) */ + 1, /* 3300C (208908) */ + 1, /* 3300D (208909) */ + 1, /* 3300E (208910) */ + 1, /* 3300F (208911) */ + 1, /* 33010 (208912) */ + 1, /* 33011 (208913) */ + 1, /* 33012 (208914) */ + 1, /* 33013 (208915) */ + 1, /* 33014 (208916) */ + 1, /* 33015 (208917) */ + 1, /* 33016 (208918) */ + 1, /* 33017 (208919) */ + 1, /* 33018 (208920) */ + 1, /* 33019 (208921) */ + 1, /* 3301A (208922) */ + 1, /* 3301B (208923) */ + 1, /* 3301C (208924) */ + 1, /* 3301D (208925) */ + 1, /* 3301E (208926) */ + 1, /* 3301F (208927) */ + 1, /* 33020 (208928) */ + 1, /* 33021 (208929) */ + 1, /* 33022 (208930) */ + 1, /* 33023 (208931) */ + 1, /* 33024 (208932) */ + 1, /* 33025 (208933) */ + 1, /* 33026 (208934) */ + 1, /* 33027 (208935) */ + 1, /* 33028 (208936) */ + 1, /* 33029 (208937) */ + 1, /* 3302A (208938) */ + 1, /* 3302B (208939) */ + 1, /* 3302C (208940) */ + 1, /* 3302D (208941) */ + 1, /* 3302E (208942) */ + 1, /* 3302F (208943) */ + 1, /* 33030 (208944) */ + 1, /* 33031 (208945) */ + 1, /* 33032 (208946) */ + 1, /* 33033 (208947) */ + 1, /* 33034 (208948) */ + 1, /* 33035 (208949) */ + 1, /* 33036 (208950) */ + 1, /* 33037 (208951) */ + 1, /* 33038 (208952) */ + 1, /* 33039 (208953) */ + 1, /* 3303A (208954) */ + 1, /* 3303B (208955) */ + 1, /* 3303C (208956) */ + 1, /* 3303D (208957) */ + 1, /* 3303E (208958) */ + 1, /* 3303F (208959) */ + 1, /* 33040 (208960) */ + 1, /* 33041 (208961) */ + 1, /* 33042 (208962) */ + 1, /* 33043 (208963) */ + 1, /* 33044 (208964) */ + 1, /* 33045 (208965) */ + 1, /* 33046 (208966) */ + 1, /* 33047 (208967) */ + 1, /* 33048 (208968) */ + 1, /* 33049 (208969) */ + 1, /* 3304A (208970) */ + 1, /* 3304B (208971) */ + 1, /* 3304C (208972) */ + 1, /* 3304D (208973) */ + 1, /* 3304E (208974) */ + 1, /* 3304F (208975) */ + 1, /* 33050 (208976) */ + 1, /* 33051 (208977) */ + 1, /* 33052 (208978) */ + 1, /* 33053 (208979) */ + 1, /* 33054 (208980) */ + 1, /* 33055 (208981) */ + 1, /* 33056 (208982) */ + 1, /* 33057 (208983) */ + 1, /* 33058 (208984) */ + 1, /* 33059 (208985) */ + 1, /* 3305A (208986) */ + 1, /* 3305B (208987) */ + 1, /* 3305C (208988) */ + 1, /* 3305D (208989) */ + 1, /* 3305E (208990) */ + 1, /* 3305F (208991) */ + 1, /* 33060 (208992) */ + 1, /* 33061 (208993) */ + 1, /* 33062 (208994) */ + 1, /* 33063 (208995) */ + 1, /* 33064 (208996) */ + 1, /* 33065 (208997) */ + 1, /* 33066 (208998) */ + 1, /* 33067 (208999) */ + 1, /* 33068 (209000) */ + 1, /* 33069 (209001) */ + 1, /* 3306A (209002) */ + 1, /* 3306B (209003) */ + 1, /* 3306C (209004) */ + 1, /* 3306D (209005) */ + 1, /* 3306E (209006) */ + 1, /* 3306F (209007) */ + 1, /* 33070 (209008) */ + 1, /* 33071 (209009) */ + 1, /* 33072 (209010) */ + 1, /* 33073 (209011) */ + 1, /* 33074 (209012) */ + 1, /* 33075 (209013) */ + 1, /* 33076 (209014) */ + 1, /* 33077 (209015) */ + 1, /* 33078 (209016) */ + 1, /* 33079 (209017) */ + 1, /* 3307A (209018) */ + 1, /* 3307B (209019) */ + 1, /* 3307C (209020) */ + 1, /* 3307D (209021) */ + 1, /* 3307E (209022) */ + 1, /* 3307F (209023) */ + 1, /* 33080 (209024) */ + 1, /* 33081 (209025) */ + 1, /* 33082 (209026) */ + 1, /* 33083 (209027) */ + 1, /* 33084 (209028) */ + 1, /* 33085 (209029) */ + 1, /* 33086 (209030) */ + 1, /* 33087 (209031) */ + 1, /* 33088 (209032) */ + 1, /* 33089 (209033) */ + 1, /* 3308A (209034) */ + 1, /* 3308B (209035) */ + 1, /* 3308C (209036) */ + 1, /* 3308D (209037) */ + 1, /* 3308E (209038) */ + 1, /* 3308F (209039) */ + 1, /* 33090 (209040) */ + 1, /* 33091 (209041) */ + 1, /* 33092 (209042) */ + 1, /* 33093 (209043) */ + 1, /* 33094 (209044) */ + 1, /* 33095 (209045) */ + 1, /* 33096 (209046) */ + 1, /* 33097 (209047) */ + 1, /* 33098 (209048) */ + 1, /* 33099 (209049) */ + 1, /* 3309A (209050) */ + 1, /* 3309B (209051) */ + 1, /* 3309C (209052) */ + 1, /* 3309D (209053) */ + 1, /* 3309E (209054) */ + 1, /* 3309F (209055) */ + 1, /* 330A0 (209056) */ + 1, /* 330A1 (209057) */ + 1, /* 330A2 (209058) */ + 1, /* 330A3 (209059) */ + 1, /* 330A4 (209060) */ + 1, /* 330A5 (209061) */ + 1, /* 330A6 (209062) */ + 1, /* 330A7 (209063) */ + 1, /* 330A8 (209064) */ + 1, /* 330A9 (209065) */ + 1, /* 330AA (209066) */ + 1, /* 330AB (209067) */ + 1, /* 330AC (209068) */ + 1, /* 330AD (209069) */ + 1, /* 330AE (209070) */ + 1, /* 330AF (209071) */ + 1, /* 330B0 (209072) */ + 1, /* 330B1 (209073) */ + 1, /* 330B2 (209074) */ + 1, /* 330B3 (209075) */ + 1, /* 330B4 (209076) */ + 1, /* 330B5 (209077) */ + 1, /* 330B6 (209078) */ + 1, /* 330B7 (209079) */ + 1, /* 330B8 (209080) */ + 1, /* 330B9 (209081) */ + 1, /* 330BA (209082) */ + 1, /* 330BB (209083) */ + 1, /* 330BC (209084) */ + 1, /* 330BD (209085) */ + 1, /* 330BE (209086) */ + 1, /* 330BF (209087) */ + 1, /* 330C0 (209088) */ + 1, /* 330C1 (209089) */ + 1, /* 330C2 (209090) */ + 1, /* 330C3 (209091) */ + 1, /* 330C4 (209092) */ + 1, /* 330C5 (209093) */ + 1, /* 330C6 (209094) */ + 1, /* 330C7 (209095) */ + 1, /* 330C8 (209096) */ + 1, /* 330C9 (209097) */ + 1, /* 330CA (209098) */ + 1, /* 330CB (209099) */ + 1, /* 330CC (209100) */ + 1, /* 330CD (209101) */ + 1, /* 330CE (209102) */ + 1, /* 330CF (209103) */ + 1, /* 330D0 (209104) */ + 1, /* 330D1 (209105) */ + 1, /* 330D2 (209106) */ + 1, /* 330D3 (209107) */ + 1, /* 330D4 (209108) */ + 1, /* 330D5 (209109) */ + 1, /* 330D6 (209110) */ + 1, /* 330D7 (209111) */ + 1, /* 330D8 (209112) */ + 1, /* 330D9 (209113) */ + 1, /* 330DA (209114) */ + 1, /* 330DB (209115) */ + 1, /* 330DC (209116) */ + 1, /* 330DD (209117) */ + 1, /* 330DE (209118) */ + 1, /* 330DF (209119) */ + 1, /* 330E0 (209120) */ + 1, /* 330E1 (209121) */ + 1, /* 330E2 (209122) */ + 1, /* 330E3 (209123) */ + 1, /* 330E4 (209124) */ + 1, /* 330E5 (209125) */ + 1, /* 330E6 (209126) */ + 1, /* 330E7 (209127) */ + 1, /* 330E8 (209128) */ + 1, /* 330E9 (209129) */ + 1, /* 330EA (209130) */ + 1, /* 330EB (209131) */ + 1, /* 330EC (209132) */ + 1, /* 330ED (209133) */ + 1, /* 330EE (209134) */ + 1, /* 330EF (209135) */ + 1, /* 330F0 (209136) */ + 1, /* 330F1 (209137) */ + 1, /* 330F2 (209138) */ + 1, /* 330F3 (209139) */ + 1, /* 330F4 (209140) */ + 1, /* 330F5 (209141) */ + 1, /* 330F6 (209142) */ + 1, /* 330F7 (209143) */ + 1, /* 330F8 (209144) */ + 1, /* 330F9 (209145) */ + 1, /* 330FA (209146) */ + 1, /* 330FB (209147) */ + 1, /* 330FC (209148) */ + 1, /* 330FD (209149) */ + 1, /* 330FE (209150) */ + 1, /* 330FF (209151) */ + 1, /* 33100 (209152) */ + 1, /* 33101 (209153) */ + 1, /* 33102 (209154) */ + 1, /* 33103 (209155) */ + 1, /* 33104 (209156) */ + 1, /* 33105 (209157) */ + 1, /* 33106 (209158) */ + 1, /* 33107 (209159) */ + 1, /* 33108 (209160) */ + 1, /* 33109 (209161) */ + 1, /* 3310A (209162) */ + 1, /* 3310B (209163) */ + 1, /* 3310C (209164) */ + 1, /* 3310D (209165) */ + 1, /* 3310E (209166) */ + 1, /* 3310F (209167) */ + 1, /* 33110 (209168) */ + 1, /* 33111 (209169) */ + 1, /* 33112 (209170) */ + 1, /* 33113 (209171) */ + 1, /* 33114 (209172) */ + 1, /* 33115 (209173) */ + 1, /* 33116 (209174) */ + 1, /* 33117 (209175) */ + 1, /* 33118 (209176) */ + 1, /* 33119 (209177) */ + 1, /* 3311A (209178) */ + 1, /* 3311B (209179) */ + 1, /* 3311C (209180) */ + 1, /* 3311D (209181) */ + 1, /* 3311E (209182) */ + 1, /* 3311F (209183) */ + 1, /* 33120 (209184) */ + 1, /* 33121 (209185) */ + 1, /* 33122 (209186) */ + 1, /* 33123 (209187) */ + 1, /* 33124 (209188) */ + 1, /* 33125 (209189) */ + 1, /* 33126 (209190) */ + 1, /* 33127 (209191) */ + 1, /* 33128 (209192) */ + 1, /* 33129 (209193) */ + 1, /* 3312A (209194) */ + 1, /* 3312B (209195) */ + 1, /* 3312C (209196) */ + 1, /* 3312D (209197) */ + 1, /* 3312E (209198) */ + 1, /* 3312F (209199) */ + 1, /* 33130 (209200) */ + 1, /* 33131 (209201) */ + 1, /* 33132 (209202) */ + 1, /* 33133 (209203) */ + 1, /* 33134 (209204) */ + 1, /* 33135 (209205) */ + 1, /* 33136 (209206) */ + 1, /* 33137 (209207) */ + 1, /* 33138 (209208) */ + 1, /* 33139 (209209) */ + 1, /* 3313A (209210) */ + 1, /* 3313B (209211) */ + 1, /* 3313C (209212) */ + 1, /* 3313D (209213) */ + 1, /* 3313E (209214) */ + 1, /* 3313F (209215) */ + 1, /* 33140 (209216) */ + 1, /* 33141 (209217) */ + 1, /* 33142 (209218) */ + 1, /* 33143 (209219) */ + 1, /* 33144 (209220) */ + 1, /* 33145 (209221) */ + 1, /* 33146 (209222) */ + 1, /* 33147 (209223) */ + 1, /* 33148 (209224) */ + 1, /* 33149 (209225) */ + 1, /* 3314A (209226) */ + 1, /* 3314B (209227) */ + 1, /* 3314C (209228) */ + 1, /* 3314D (209229) */ + 1, /* 3314E (209230) */ + 1, /* 3314F (209231) */ + 1, /* 33150 (209232) */ + 1, /* 33151 (209233) */ + 1, /* 33152 (209234) */ + 1, /* 33153 (209235) */ + 1, /* 33154 (209236) */ + 1, /* 33155 (209237) */ + 1, /* 33156 (209238) */ + 1, /* 33157 (209239) */ + 1, /* 33158 (209240) */ + 1, /* 33159 (209241) */ + 1, /* 3315A (209242) */ + 1, /* 3315B (209243) */ + 1, /* 3315C (209244) */ + 1, /* 3315D (209245) */ + 1, /* 3315E (209246) */ + 1, /* 3315F (209247) */ + 1, /* 33160 (209248) */ + 1, /* 33161 (209249) */ + 1, /* 33162 (209250) */ + 1, /* 33163 (209251) */ + 1, /* 33164 (209252) */ + 1, /* 33165 (209253) */ + 1, /* 33166 (209254) */ + 1, /* 33167 (209255) */ + 1, /* 33168 (209256) */ + 1, /* 33169 (209257) */ + 1, /* 3316A (209258) */ + 1, /* 3316B (209259) */ + 1, /* 3316C (209260) */ + 1, /* 3316D (209261) */ + 1, /* 3316E (209262) */ + 1, /* 3316F (209263) */ + 1, /* 33170 (209264) */ + 1, /* 33171 (209265) */ + 1, /* 33172 (209266) */ + 1, /* 33173 (209267) */ + 1, /* 33174 (209268) */ + 1, /* 33175 (209269) */ + 1, /* 33176 (209270) */ + 1, /* 33177 (209271) */ + 1, /* 33178 (209272) */ + 1, /* 33179 (209273) */ + 1, /* 3317A (209274) */ + 1, /* 3317B (209275) */ + 1, /* 3317C (209276) */ + 1, /* 3317D (209277) */ + 1, /* 3317E (209278) */ + 1, /* 3317F (209279) */ + 1, /* 33180 (209280) */ + 1, /* 33181 (209281) */ + 1, /* 33182 (209282) */ + 1, /* 33183 (209283) */ + 1, /* 33184 (209284) */ + 1, /* 33185 (209285) */ + 1, /* 33186 (209286) */ + 1, /* 33187 (209287) */ + 1, /* 33188 (209288) */ + 1, /* 33189 (209289) */ + 1, /* 3318A (209290) */ + 1, /* 3318B (209291) */ + 1, /* 3318C (209292) */ + 1, /* 3318D (209293) */ + 1, /* 3318E (209294) */ + 1, /* 3318F (209295) */ + 1, /* 33190 (209296) */ + 1, /* 33191 (209297) */ + 1, /* 33192 (209298) */ + 1, /* 33193 (209299) */ + 1, /* 33194 (209300) */ + 1, /* 33195 (209301) */ + 1, /* 33196 (209302) */ + 1, /* 33197 (209303) */ + 1, /* 33198 (209304) */ + 1, /* 33199 (209305) */ + 1, /* 3319A (209306) */ + 1, /* 3319B (209307) */ + 1, /* 3319C (209308) */ + 1, /* 3319D (209309) */ + 1, /* 3319E (209310) */ + 1, /* 3319F (209311) */ + 1, /* 331A0 (209312) */ + 1, /* 331A1 (209313) */ + 1, /* 331A2 (209314) */ + 1, /* 331A3 (209315) */ + 1, /* 331A4 (209316) */ + 1, /* 331A5 (209317) */ + 1, /* 331A6 (209318) */ + 1, /* 331A7 (209319) */ + 1, /* 331A8 (209320) */ + 1, /* 331A9 (209321) */ + 1, /* 331AA (209322) */ + 1, /* 331AB (209323) */ + 1, /* 331AC (209324) */ + 1, /* 331AD (209325) */ + 1, /* 331AE (209326) */ + 1, /* 331AF (209327) */ + 1, /* 331B0 (209328) */ + 1, /* 331B1 (209329) */ + 1, /* 331B2 (209330) */ + 1, /* 331B3 (209331) */ + 1, /* 331B4 (209332) */ + 1, /* 331B5 (209333) */ + 1, /* 331B6 (209334) */ + 1, /* 331B7 (209335) */ + 1, /* 331B8 (209336) */ + 1, /* 331B9 (209337) */ + 1, /* 331BA (209338) */ + 1, /* 331BB (209339) */ + 1, /* 331BC (209340) */ + 1, /* 331BD (209341) */ + 1, /* 331BE (209342) */ + 1, /* 331BF (209343) */ + 1, /* 331C0 (209344) */ + 1, /* 331C1 (209345) */ + 1, /* 331C2 (209346) */ + 1, /* 331C3 (209347) */ + 1, /* 331C4 (209348) */ + 1, /* 331C5 (209349) */ + 1, /* 331C6 (209350) */ + 1, /* 331C7 (209351) */ + 1, /* 331C8 (209352) */ + 1, /* 331C9 (209353) */ + 1, /* 331CA (209354) */ + 1, /* 331CB (209355) */ + 1, /* 331CC (209356) */ + 1, /* 331CD (209357) */ + 1, /* 331CE (209358) */ + 1, /* 331CF (209359) */ + 1, /* 331D0 (209360) */ + 1, /* 331D1 (209361) */ + 1, /* 331D2 (209362) */ + 1, /* 331D3 (209363) */ + 1, /* 331D4 (209364) */ + 1, /* 331D5 (209365) */ + 1, /* 331D6 (209366) */ + 1, /* 331D7 (209367) */ + 1, /* 331D8 (209368) */ + 1, /* 331D9 (209369) */ + 1, /* 331DA (209370) */ + 1, /* 331DB (209371) */ + 1, /* 331DC (209372) */ + 1, /* 331DD (209373) */ + 1, /* 331DE (209374) */ + 1, /* 331DF (209375) */ + 1, /* 331E0 (209376) */ + 1, /* 331E1 (209377) */ + 1, /* 331E2 (209378) */ + 1, /* 331E3 (209379) */ + 1, /* 331E4 (209380) */ + 1, /* 331E5 (209381) */ + 1, /* 331E6 (209382) */ + 1, /* 331E7 (209383) */ + 1, /* 331E8 (209384) */ + 1, /* 331E9 (209385) */ + 1, /* 331EA (209386) */ + 1, /* 331EB (209387) */ + 1, /* 331EC (209388) */ + 1, /* 331ED (209389) */ + 1, /* 331EE (209390) */ + 1, /* 331EF (209391) */ + 1, /* 331F0 (209392) */ + 1, /* 331F1 (209393) */ + 1, /* 331F2 (209394) */ + 1, /* 331F3 (209395) */ + 1, /* 331F4 (209396) */ + 1, /* 331F5 (209397) */ + 1, /* 331F6 (209398) */ + 1, /* 331F7 (209399) */ + 1, /* 331F8 (209400) */ + 1, /* 331F9 (209401) */ + 1, /* 331FA (209402) */ + 1, /* 331FB (209403) */ + 1, /* 331FC (209404) */ + 1, /* 331FD (209405) */ + 1, /* 331FE (209406) */ + 1, /* 331FF (209407) */ + 1, /* 33200 (209408) */ + 1, /* 33201 (209409) */ + 1, /* 33202 (209410) */ + 1, /* 33203 (209411) */ + 1, /* 33204 (209412) */ + 1, /* 33205 (209413) */ + 1, /* 33206 (209414) */ + 1, /* 33207 (209415) */ + 1, /* 33208 (209416) */ + 1, /* 33209 (209417) */ + 1, /* 3320A (209418) */ + 1, /* 3320B (209419) */ + 1, /* 3320C (209420) */ + 1, /* 3320D (209421) */ + 1, /* 3320E (209422) */ + 1, /* 3320F (209423) */ + 1, /* 33210 (209424) */ + 1, /* 33211 (209425) */ + 1, /* 33212 (209426) */ + 1, /* 33213 (209427) */ + 1, /* 33214 (209428) */ + 1, /* 33215 (209429) */ + 1, /* 33216 (209430) */ + 1, /* 33217 (209431) */ + 1, /* 33218 (209432) */ + 1, /* 33219 (209433) */ + 1, /* 3321A (209434) */ + 1, /* 3321B (209435) */ + 1, /* 3321C (209436) */ + 1, /* 3321D (209437) */ + 1, /* 3321E (209438) */ + 1, /* 3321F (209439) */ + 1, /* 33220 (209440) */ + 1, /* 33221 (209441) */ + 1, /* 33222 (209442) */ + 1, /* 33223 (209443) */ + 1, /* 33224 (209444) */ + 1, /* 33225 (209445) */ + 1, /* 33226 (209446) */ + 1, /* 33227 (209447) */ + 1, /* 33228 (209448) */ + 1, /* 33229 (209449) */ + 1, /* 3322A (209450) */ + 1, /* 3322B (209451) */ + 1, /* 3322C (209452) */ + 1, /* 3322D (209453) */ + 1, /* 3322E (209454) */ + 1, /* 3322F (209455) */ + 1, /* 33230 (209456) */ + 1, /* 33231 (209457) */ + 1, /* 33232 (209458) */ + 1, /* 33233 (209459) */ + 1, /* 33234 (209460) */ + 1, /* 33235 (209461) */ + 1, /* 33236 (209462) */ + 1, /* 33237 (209463) */ + 1, /* 33238 (209464) */ + 1, /* 33239 (209465) */ + 1, /* 3323A (209466) */ + 1, /* 3323B (209467) */ + 1, /* 3323C (209468) */ + 1, /* 3323D (209469) */ + 1, /* 3323E (209470) */ + 1, /* 3323F (209471) */ + 1, /* 33240 (209472) */ + 1, /* 33241 (209473) */ + 1, /* 33242 (209474) */ + 1, /* 33243 (209475) */ + 1, /* 33244 (209476) */ + 1, /* 33245 (209477) */ + 1, /* 33246 (209478) */ + 1, /* 33247 (209479) */ + 1, /* 33248 (209480) */ + 1, /* 33249 (209481) */ + 1, /* 3324A (209482) */ + 1, /* 3324B (209483) */ + 1, /* 3324C (209484) */ + 1, /* 3324D (209485) */ + 1, /* 3324E (209486) */ + 1, /* 3324F (209487) */ + 1, /* 33250 (209488) */ + 1, /* 33251 (209489) */ + 1, /* 33252 (209490) */ + 1, /* 33253 (209491) */ + 1, /* 33254 (209492) */ + 1, /* 33255 (209493) */ + 1, /* 33256 (209494) */ + 1, /* 33257 (209495) */ + 1, /* 33258 (209496) */ + 1, /* 33259 (209497) */ + 1, /* 3325A (209498) */ + 1, /* 3325B (209499) */ + 1, /* 3325C (209500) */ + 1, /* 3325D (209501) */ + 1, /* 3325E (209502) */ + 1, /* 3325F (209503) */ + 1, /* 33260 (209504) */ + 1, /* 33261 (209505) */ + 1, /* 33262 (209506) */ + 1, /* 33263 (209507) */ + 1, /* 33264 (209508) */ + 1, /* 33265 (209509) */ + 1, /* 33266 (209510) */ + 1, /* 33267 (209511) */ + 1, /* 33268 (209512) */ + 1, /* 33269 (209513) */ + 1, /* 3326A (209514) */ + 1, /* 3326B (209515) */ + 1, /* 3326C (209516) */ + 1, /* 3326D (209517) */ + 1, /* 3326E (209518) */ + 1, /* 3326F (209519) */ + 1, /* 33270 (209520) */ + 1, /* 33271 (209521) */ + 1, /* 33272 (209522) */ + 1, /* 33273 (209523) */ + 1, /* 33274 (209524) */ + 1, /* 33275 (209525) */ + 1, /* 33276 (209526) */ + 1, /* 33277 (209527) */ + 1, /* 33278 (209528) */ + 1, /* 33279 (209529) */ + 1, /* 3327A (209530) */ + 1, /* 3327B (209531) */ + 1, /* 3327C (209532) */ + 1, /* 3327D (209533) */ + 1, /* 3327E (209534) */ + 1, /* 3327F (209535) */ + 1, /* 33280 (209536) */ + 1, /* 33281 (209537) */ + 1, /* 33282 (209538) */ + 1, /* 33283 (209539) */ + 1, /* 33284 (209540) */ + 1, /* 33285 (209541) */ + 1, /* 33286 (209542) */ + 1, /* 33287 (209543) */ + 1, /* 33288 (209544) */ + 1, /* 33289 (209545) */ + 1, /* 3328A (209546) */ + 1, /* 3328B (209547) */ + 1, /* 3328C (209548) */ + 1, /* 3328D (209549) */ + 1, /* 3328E (209550) */ + 1, /* 3328F (209551) */ + 1, /* 33290 (209552) */ + 1, /* 33291 (209553) */ + 1, /* 33292 (209554) */ + 1, /* 33293 (209555) */ + 1, /* 33294 (209556) */ + 1, /* 33295 (209557) */ + 1, /* 33296 (209558) */ + 1, /* 33297 (209559) */ + 1, /* 33298 (209560) */ + 1, /* 33299 (209561) */ + 1, /* 3329A (209562) */ + 1, /* 3329B (209563) */ + 1, /* 3329C (209564) */ + 1, /* 3329D (209565) */ + 1, /* 3329E (209566) */ + 1, /* 3329F (209567) */ + 1, /* 332A0 (209568) */ + 1, /* 332A1 (209569) */ + 1, /* 332A2 (209570) */ + 1, /* 332A3 (209571) */ + 1, /* 332A4 (209572) */ + 1, /* 332A5 (209573) */ + 1, /* 332A6 (209574) */ + 1, /* 332A7 (209575) */ + 1, /* 332A8 (209576) */ + 1, /* 332A9 (209577) */ + 1, /* 332AA (209578) */ + 1, /* 332AB (209579) */ + 1, /* 332AC (209580) */ + 1, /* 332AD (209581) */ + 1, /* 332AE (209582) */ + 1, /* 332AF (209583) */ + 1, /* 332B0 (209584) */ + 1, /* 332B1 (209585) */ + 1, /* 332B2 (209586) */ + 1, /* 332B3 (209587) */ + 1, /* 332B4 (209588) */ + 1, /* 332B5 (209589) */ + 1, /* 332B6 (209590) */ + 1, /* 332B7 (209591) */ + 1, /* 332B8 (209592) */ + 1, /* 332B9 (209593) */ + 1, /* 332BA (209594) */ + 1, /* 332BB (209595) */ + 1, /* 332BC (209596) */ + 1, /* 332BD (209597) */ + 1, /* 332BE (209598) */ + 1, /* 332BF (209599) */ + 1, /* 332C0 (209600) */ + 1, /* 332C1 (209601) */ + 1, /* 332C2 (209602) */ + 1, /* 332C3 (209603) */ + 1, /* 332C4 (209604) */ + 1, /* 332C5 (209605) */ + 1, /* 332C6 (209606) */ + 1, /* 332C7 (209607) */ + 1, /* 332C8 (209608) */ + 1, /* 332C9 (209609) */ + 1, /* 332CA (209610) */ + 1, /* 332CB (209611) */ + 1, /* 332CC (209612) */ + 1, /* 332CD (209613) */ + 1, /* 332CE (209614) */ + 1, /* 332CF (209615) */ + 1, /* 332D0 (209616) */ + 1, /* 332D1 (209617) */ + 1, /* 332D2 (209618) */ + 1, /* 332D3 (209619) */ + 1, /* 332D4 (209620) */ + 1, /* 332D5 (209621) */ + 1, /* 332D6 (209622) */ + 1, /* 332D7 (209623) */ + 1, /* 332D8 (209624) */ + 1, /* 332D9 (209625) */ + 1, /* 332DA (209626) */ + 1, /* 332DB (209627) */ + 1, /* 332DC (209628) */ + 1, /* 332DD (209629) */ + 1, /* 332DE (209630) */ + 1, /* 332DF (209631) */ + 1, /* 332E0 (209632) */ + 1, /* 332E1 (209633) */ + 1, /* 332E2 (209634) */ + 1, /* 332E3 (209635) */ + 1, /* 332E4 (209636) */ + 1, /* 332E5 (209637) */ + 1, /* 332E6 (209638) */ + 1, /* 332E7 (209639) */ + 1, /* 332E8 (209640) */ + 1, /* 332E9 (209641) */ + 1, /* 332EA (209642) */ + 1, /* 332EB (209643) */ + 1, /* 332EC (209644) */ + 1, /* 332ED (209645) */ + 1, /* 332EE (209646) */ + 1, /* 332EF (209647) */ + 1, /* 332F0 (209648) */ + 1, /* 332F1 (209649) */ + 1, /* 332F2 (209650) */ + 1, /* 332F3 (209651) */ + 1, /* 332F4 (209652) */ + 1, /* 332F5 (209653) */ + 1, /* 332F6 (209654) */ + 1, /* 332F7 (209655) */ + 1, /* 332F8 (209656) */ + 1, /* 332F9 (209657) */ + 1, /* 332FA (209658) */ + 1, /* 332FB (209659) */ + 1, /* 332FC (209660) */ + 1, /* 332FD (209661) */ + 1, /* 332FE (209662) */ + 1, /* 332FF (209663) */ + 1, /* 33300 (209664) */ + 1, /* 33301 (209665) */ + 1, /* 33302 (209666) */ + 1, /* 33303 (209667) */ + 1, /* 33304 (209668) */ + 1, /* 33305 (209669) */ + 1, /* 33306 (209670) */ + 1, /* 33307 (209671) */ + 1, /* 33308 (209672) */ + 1, /* 33309 (209673) */ + 1, /* 3330A (209674) */ + 1, /* 3330B (209675) */ + 1, /* 3330C (209676) */ + 1, /* 3330D (209677) */ + 1, /* 3330E (209678) */ + 1, /* 3330F (209679) */ + 1, /* 33310 (209680) */ + 1, /* 33311 (209681) */ + 1, /* 33312 (209682) */ + 1, /* 33313 (209683) */ + 1, /* 33314 (209684) */ + 1, /* 33315 (209685) */ + 1, /* 33316 (209686) */ + 1, /* 33317 (209687) */ + 1, /* 33318 (209688) */ + 1, /* 33319 (209689) */ + 1, /* 3331A (209690) */ + 1, /* 3331B (209691) */ + 1, /* 3331C (209692) */ + 1, /* 3331D (209693) */ + 1, /* 3331E (209694) */ + 1, /* 3331F (209695) */ + 1, /* 33320 (209696) */ + 1, /* 33321 (209697) */ + 1, /* 33322 (209698) */ + 1, /* 33323 (209699) */ + 1, /* 33324 (209700) */ + 1, /* 33325 (209701) */ + 1, /* 33326 (209702) */ + 1, /* 33327 (209703) */ + 1, /* 33328 (209704) */ + 1, /* 33329 (209705) */ + 1, /* 3332A (209706) */ + 1, /* 3332B (209707) */ + 1, /* 3332C (209708) */ + 1, /* 3332D (209709) */ + 1, /* 3332E (209710) */ + 1, /* 3332F (209711) */ + 1, /* 33330 (209712) */ + 1, /* 33331 (209713) */ + 1, /* 33332 (209714) */ + 1, /* 33333 (209715) */ + 1, /* 33334 (209716) */ + 1, /* 33335 (209717) */ + 1, /* 33336 (209718) */ + 1, /* 33337 (209719) */ + 1, /* 33338 (209720) */ + 1, /* 33339 (209721) */ + 1, /* 3333A (209722) */ + 1, /* 3333B (209723) */ + 1, /* 3333C (209724) */ + 1, /* 3333D (209725) */ + 1, /* 3333E (209726) */ + 1, /* 3333F (209727) */ + 1, /* 33340 (209728) */ + 1, /* 33341 (209729) */ + 1, /* 33342 (209730) */ + 1, /* 33343 (209731) */ + 1, /* 33344 (209732) */ + 1, /* 33345 (209733) */ + 1, /* 33346 (209734) */ + 1, /* 33347 (209735) */ + 1, /* 33348 (209736) */ + 1, /* 33349 (209737) */ + 1, /* 3334A (209738) */ + 1, /* 3334B (209739) */ + 1, /* 3334C (209740) */ + 1, /* 3334D (209741) */ + 1, /* 3334E (209742) */ + 1, /* 3334F (209743) */ + 1, /* 33350 (209744) */ + 1, /* 33351 (209745) */ + 1, /* 33352 (209746) */ + 1, /* 33353 (209747) */ + 1, /* 33354 (209748) */ + 1, /* 33355 (209749) */ + 1, /* 33356 (209750) */ + 1, /* 33357 (209751) */ + 1, /* 33358 (209752) */ + 1, /* 33359 (209753) */ + 1, /* 3335A (209754) */ + 1, /* 3335B (209755) */ + 1, /* 3335C (209756) */ + 1, /* 3335D (209757) */ + 1, /* 3335E (209758) */ + 1, /* 3335F (209759) */ + 1, /* 33360 (209760) */ + 1, /* 33361 (209761) */ + 1, /* 33362 (209762) */ + 1, /* 33363 (209763) */ + 1, /* 33364 (209764) */ + 1, /* 33365 (209765) */ + 1, /* 33366 (209766) */ + 1, /* 33367 (209767) */ + 1, /* 33368 (209768) */ + 1, /* 33369 (209769) */ + 1, /* 3336A (209770) */ + 1, /* 3336B (209771) */ + 1, /* 3336C (209772) */ + 1, /* 3336D (209773) */ + 1, /* 3336E (209774) */ + 1, /* 3336F (209775) */ + 1, /* 33370 (209776) */ + 1, /* 33371 (209777) */ + 1, /* 33372 (209778) */ + 1, /* 33373 (209779) */ + 1, /* 33374 (209780) */ + 1, /* 33375 (209781) */ + 1, /* 33376 (209782) */ + 1, /* 33377 (209783) */ + 1, /* 33378 (209784) */ + 1, /* 33379 (209785) */ + 1, /* 3337A (209786) */ + 1, /* 3337B (209787) */ + 1, /* 3337C (209788) */ + 1, /* 3337D (209789) */ + 1, /* 3337E (209790) */ + 1, /* 3337F (209791) */ + 1, /* 33380 (209792) */ + 1, /* 33381 (209793) */ + 1, /* 33382 (209794) */ + 1, /* 33383 (209795) */ + 1, /* 33384 (209796) */ + 1, /* 33385 (209797) */ + 1, /* 33386 (209798) */ + 1, /* 33387 (209799) */ + 1, /* 33388 (209800) */ + 1, /* 33389 (209801) */ + 1, /* 3338A (209802) */ + 1, /* 3338B (209803) */ + 1, /* 3338C (209804) */ + 1, /* 3338D (209805) */ + 1, /* 3338E (209806) */ + 1, /* 3338F (209807) */ + 1, /* 33390 (209808) */ + 1, /* 33391 (209809) */ + 1, /* 33392 (209810) */ + 1, /* 33393 (209811) */ + 1, /* 33394 (209812) */ + 1, /* 33395 (209813) */ + 1, /* 33396 (209814) */ + 1, /* 33397 (209815) */ + 1, /* 33398 (209816) */ + 1, /* 33399 (209817) */ + 1, /* 3339A (209818) */ + 1, /* 3339B (209819) */ + 1, /* 3339C (209820) */ + 1, /* 3339D (209821) */ + 1, /* 3339E (209822) */ + 1, /* 3339F (209823) */ + 1, /* 333A0 (209824) */ + 1, /* 333A1 (209825) */ + 1, /* 333A2 (209826) */ + 1, /* 333A3 (209827) */ + 1, /* 333A4 (209828) */ + 1, /* 333A5 (209829) */ + 1, /* 333A6 (209830) */ + 1, /* 333A7 (209831) */ + 1, /* 333A8 (209832) */ + 1, /* 333A9 (209833) */ + 1, /* 333AA (209834) */ + 1, /* 333AB (209835) */ + 1, /* 333AC (209836) */ + 1, /* 333AD (209837) */ + 1, /* 333AE (209838) */ + 1, /* 333AF (209839) */ + 1, /* 333B0 (209840) */ + 1, /* 333B1 (209841) */ + 1, /* 333B2 (209842) */ + 1, /* 333B3 (209843) */ + 1, /* 333B4 (209844) */ + 1, /* 333B5 (209845) */ + 1, /* 333B6 (209846) */ + 1, /* 333B7 (209847) */ + 1, /* 333B8 (209848) */ + 1, /* 333B9 (209849) */ + 1, /* 333BA (209850) */ + 1, /* 333BB (209851) */ + 1, /* 333BC (209852) */ + 1, /* 333BD (209853) */ + 1, /* 333BE (209854) */ + 1, /* 333BF (209855) */ + 1, /* 333C0 (209856) */ + 1, /* 333C1 (209857) */ + 1, /* 333C2 (209858) */ + 1, /* 333C3 (209859) */ + 1, /* 333C4 (209860) */ + 1, /* 333C5 (209861) */ + 1, /* 333C6 (209862) */ + 1, /* 333C7 (209863) */ + 1, /* 333C8 (209864) */ + 1, /* 333C9 (209865) */ + 1, /* 333CA (209866) */ + 1, /* 333CB (209867) */ + 1, /* 333CC (209868) */ + 1, /* 333CD (209869) */ + 1, /* 333CE (209870) */ + 1, /* 333CF (209871) */ + 1, /* 333D0 (209872) */ + 1, /* 333D1 (209873) */ + 1, /* 333D2 (209874) */ + 1, /* 333D3 (209875) */ + 1, /* 333D4 (209876) */ + 1, /* 333D5 (209877) */ + 1, /* 333D6 (209878) */ + 1, /* 333D7 (209879) */ + 1, /* 333D8 (209880) */ + 1, /* 333D9 (209881) */ + 1, /* 333DA (209882) */ + 1, /* 333DB (209883) */ + 1, /* 333DC (209884) */ + 1, /* 333DD (209885) */ + 1, /* 333DE (209886) */ + 1, /* 333DF (209887) */ + 1, /* 333E0 (209888) */ + 1, /* 333E1 (209889) */ + 1, /* 333E2 (209890) */ + 1, /* 333E3 (209891) */ + 1, /* 333E4 (209892) */ + 1, /* 333E5 (209893) */ + 1, /* 333E6 (209894) */ + 1, /* 333E7 (209895) */ + 1, /* 333E8 (209896) */ + 1, /* 333E9 (209897) */ + 1, /* 333EA (209898) */ + 1, /* 333EB (209899) */ + 1, /* 333EC (209900) */ + 1, /* 333ED (209901) */ + 1, /* 333EE (209902) */ + 1, /* 333EF (209903) */ + 1, /* 333F0 (209904) */ + 1, /* 333F1 (209905) */ + 1, /* 333F2 (209906) */ + 1, /* 333F3 (209907) */ + 1, /* 333F4 (209908) */ + 1, /* 333F5 (209909) */ + 1, /* 333F6 (209910) */ + 1, /* 333F7 (209911) */ + 1, /* 333F8 (209912) */ + 1, /* 333F9 (209913) */ + 1, /* 333FA (209914) */ + 1, /* 333FB (209915) */ + 1, /* 333FC (209916) */ + 1, /* 333FD (209917) */ + 1, /* 333FE (209918) */ + 1, /* 333FF (209919) */ + 1, /* 33400 (209920) */ + 1, /* 33401 (209921) */ + 1, /* 33402 (209922) */ + 1, /* 33403 (209923) */ + 1, /* 33404 (209924) */ + 1, /* 33405 (209925) */ + 1, /* 33406 (209926) */ + 1, /* 33407 (209927) */ + 1, /* 33408 (209928) */ + 1, /* 33409 (209929) */ + 1, /* 3340A (209930) */ + 1, /* 3340B (209931) */ + 1, /* 3340C (209932) */ + 1, /* 3340D (209933) */ + 1, /* 3340E (209934) */ + 1, /* 3340F (209935) */ + 1, /* 33410 (209936) */ + 1, /* 33411 (209937) */ + 1, /* 33412 (209938) */ + 1, /* 33413 (209939) */ + 1, /* 33414 (209940) */ + 1, /* 33415 (209941) */ + 1, /* 33416 (209942) */ + 1, /* 33417 (209943) */ + 1, /* 33418 (209944) */ + 1, /* 33419 (209945) */ + 1, /* 3341A (209946) */ + 1, /* 3341B (209947) */ + 1, /* 3341C (209948) */ + 1, /* 3341D (209949) */ + 1, /* 3341E (209950) */ + 1, /* 3341F (209951) */ + 1, /* 33420 (209952) */ + 1, /* 33421 (209953) */ + 1, /* 33422 (209954) */ + 1, /* 33423 (209955) */ + 1, /* 33424 (209956) */ + 1, /* 33425 (209957) */ + 1, /* 33426 (209958) */ + 1, /* 33427 (209959) */ + 1, /* 33428 (209960) */ + 1, /* 33429 (209961) */ + 1, /* 3342A (209962) */ + 1, /* 3342B (209963) */ + 1, /* 3342C (209964) */ + 1, /* 3342D (209965) */ + 1, /* 3342E (209966) */ + 1, /* 3342F (209967) */ + 1, /* 33430 (209968) */ + 1, /* 33431 (209969) */ + 1, /* 33432 (209970) */ + 1, /* 33433 (209971) */ + 1, /* 33434 (209972) */ + 1, /* 33435 (209973) */ + 1, /* 33436 (209974) */ + 1, /* 33437 (209975) */ + 1, /* 33438 (209976) */ + 1, /* 33439 (209977) */ + 1, /* 3343A (209978) */ + 1, /* 3343B (209979) */ + 1, /* 3343C (209980) */ + 1, /* 3343D (209981) */ + 1, /* 3343E (209982) */ + 1, /* 3343F (209983) */ + 1, /* 33440 (209984) */ + 1, /* 33441 (209985) */ + 1, /* 33442 (209986) */ + 1, /* 33443 (209987) */ + 1, /* 33444 (209988) */ + 1, /* 33445 (209989) */ + 1, /* 33446 (209990) */ + 1, /* 33447 (209991) */ + 1, /* 33448 (209992) */ + 1, /* 33449 (209993) */ + 1, /* 3344A (209994) */ + 1, /* 3344B (209995) */ + 1, /* 3344C (209996) */ + 1, /* 3344D (209997) */ + 1, /* 3344E (209998) */ + 1, /* 3344F (209999) */ + 1, /* 33450 (210000) */ + 1, /* 33451 (210001) */ + 1, /* 33452 (210002) */ + 1, /* 33453 (210003) */ + 1, /* 33454 (210004) */ + 1, /* 33455 (210005) */ + 1, /* 33456 (210006) */ + 1, /* 33457 (210007) */ + 1, /* 33458 (210008) */ + 1, /* 33459 (210009) */ + 1, /* 3345A (210010) */ + 1, /* 3345B (210011) */ + 1, /* 3345C (210012) */ + 1, /* 3345D (210013) */ + 1, /* 3345E (210014) */ + 1, /* 3345F (210015) */ + 1, /* 33460 (210016) */ + 1, /* 33461 (210017) */ + 1, /* 33462 (210018) */ + 1, /* 33463 (210019) */ + 1, /* 33464 (210020) */ + 1, /* 33465 (210021) */ + 1, /* 33466 (210022) */ + 1, /* 33467 (210023) */ + 1, /* 33468 (210024) */ + 1, /* 33469 (210025) */ + 1, /* 3346A (210026) */ + 1, /* 3346B (210027) */ + 1, /* 3346C (210028) */ + 1, /* 3346D (210029) */ + 1, /* 3346E (210030) */ + 1, /* 3346F (210031) */ + 1, /* 33470 (210032) */ + 1, /* 33471 (210033) */ + 1, /* 33472 (210034) */ + 1, /* 33473 (210035) */ + 1, /* 33474 (210036) */ + 1, /* 33475 (210037) */ + 1, /* 33476 (210038) */ + 1, /* 33477 (210039) */ + 1, /* 33478 (210040) */ + 1, /* 33479 (210041) */ }; /* From: E0001; To: E01EF */ @@ -184130,6093 +188662,6122 @@ static const uint16_t lxb_unicode_table_map_1114109_1114110[1] = }; -static const lxb_unicode_entry_t lxb_unicode_entries[6085] = +static const lxb_unicode_entry_t lxb_unicode_entries[6114] = { {0, 0}, - {0, 2}, - {4898, 2}, - {4917, 2}, - {5037, 2}, - {4936, 181}, - {5109, 171}, - {4880, 7}, - {5117, 101}, - {4981, 551}, - {5057, 184}, - {5073, 286}, - {4885, 29}, - {4828, 482}, - {5006, 68}, - {5087, 320}, - {4947, 268}, - {5027, 134}, - {4961, 131}, - {4833, 485}, - {4956, 307}, - {0, 191}, - {4980, 37}, - {5042, 544}, - {4877, 198}, - {4950, 57}, - {5095, 107}, - {4859, 44}, - {5053, 162}, - {5039, 120}, - {5065, 5}, - {5016, 2}, - {4970, 2}, - {4840, 2}, - {4957, 2}, - {5002, 2}, - {5041, 2}, - {4995, 2}, - {5059, 2}, - {4983, 2}, - {4899, 2}, - {4962, 2}, - {5101, 2}, - {4901, 2}, - {4978, 2}, - {4997, 2}, - {5046, 2}, - {5072, 2}, - {4987, 2}, - {4914, 2}, - {4974, 2}, - {5105, 2}, - {4913, 2}, - {4986, 2}, - {4949, 2}, - {4900, 2}, {0, 1}, - {1410, 722}, - {3338, 445}, - {1487, 181}, - {0, 13}, - {1069, 444}, - {3139, 731}, - {2328, 432}, - {823, 176}, - {2025, 291}, - {1817, 3783}, - {1733, 222}, - {142, 485}, - {3907, 3840}, - {487, 2642}, - {4501, 2018}, - {2403, 2058}, - {3068, 1844}, - {2696, 2271}, - {2761, 792}, - {3951, 1047}, - {4504, 2692}, - {4865, 487}, - {3694, 3656}, - {3689, 3913}, - {2780, 3113}, - {1519, 3848}, - {3327, 3661}, - {3556, 325}, - {3627, 2809}, - {4265, 3050}, - {3692, 2132}, - {0, 16}, - {4525, 1832}, - {1592, 2219}, - {696, 3128}, - {4180, 2301}, - {1257, 2525}, - {888, 2038}, - {4984, 2826}, - {1589, 172}, - {3513, 2206}, - {1908, 560}, - {1853, 463}, - {377, 1573}, - {0, 404}, - {0, 22}, - {811, 2}, - {729, 2}, - {2410, 2}, - {1844, 2}, - {3506, 2}, - {2132, 2}, - {4965, 2}, - {1932, 2}, - {3125, 2}, - {1299, 2}, - {1680, 2}, - {1622, 2}, - {352, 2}, - {957, 2}, - {3737, 2}, - {675, 2}, - {3547, 2}, - {2309, 2}, - {3008, 2}, - {2784, 2}, - {2710, 2}, - {4062, 2}, - {4954, 2}, - {3777, 2}, - {3652, 2}, - {2778, 2}, - {1497, 2}, - {3357, 2}, - {3637, 2}, - {4280, 2373}, - {3650, 2}, - {873, 951}, - {4541, 2}, - {3562, 1011}, - {4598, 2}, - {1111, 1068}, - {4006, 2}, - {3653, 3135}, - {3727, 2}, - {2940, 2119}, - {3557, 2}, - {1609, 3265}, - {2649, 2}, - {3496, 3664}, - {4648, 2}, - {0, 3703}, - {3852, 540}, - {3791, 2}, - {2878, 2902}, - {3494, 2}, - {1834, 464}, - {2568, 2}, - {4123, 3440}, - {2871, 2}, - {1683, 3477}, - {3468, 2}, - {3121, 857}, - {3169, 2}, - {4643, 2646}, - {4121, 2}, - {1049, 771}, - {4377, 2}, - {329, 2886}, - {1326, 2}, - {2509, 2843}, - {1915, 2}, - {0, 1693}, - {971, 3646}, - {334, 2}, - {4296, 1507}, - {1252, 2}, - {651, 2736}, - {1631, 2}, - {2827, 2790}, - {2216, 2}, - {1991, 1481}, - {1255, 748}, - {653, 748}, - {4568, 1710}, - {974, 2}, - {2739, 3492}, - {3722, 2}, - {4267, 3223}, - {4603, 2}, - {4519, 2377}, - {3331, 2}, - {2738, 1685}, - {1948, 2}, - {3623, 1340}, - {2532, 1340}, - {0, 233}, - {4425, 1705}, - {4642, 2}, - {4726, 652}, - {3123, 2}, - {2530, 3309}, - {2104, 2}, - {3396, 3369}, - {0, 1831}, - {2411, 1754}, - {3059, 2}, - {2705, 2563}, - {2767, 2}, - {3956, 690}, - {4514, 2}, - {0, 571}, - {852, 3172}, - {1994, 2}, - {3149, 3139}, - {1408, 2}, - {1627, 1066}, - {1704, 2}, - {278, 2223}, - {856, 2}, - {3679, 1132}, - {610, 2}, - {627, 2501}, - {1619, 2}, - {2797, 2566}, - {2246, 2}, - {2004, 1753}, - {1925, 2}, - {1263, 3407}, - {626, 2}, - {0, 1952}, - {2007, 1967}, - {877, 2}, - {4397, 1916}, - {215, 2}, - {629, 2641}, - {547, 2}, - {1349, 827}, - {2002, 2}, - {2759, 2479}, - {1648, 2}, - {2085, 2983}, - {808, 2}, - {4335, 2946}, - {136, 2}, - {384, 1296}, - {471, 2}, - {1418, 3760}, - {2081, 946}, - {2522, 2}, - {1721, 882}, - {179, 2}, - {1421, 3166}, - {2707, 2}, - {2035, 544}, - {0, 3052}, - {0, 3127}, - {0, 2153}, - {0, 2659}, - {0, 2957}, - {0, 395}, - {0, 43}, - {0, 2763}, - {0, 298}, - {0, 1041}, - {0, 133}, - {0, 1286}, - {0, 374}, - {0, 2071}, - {0, 1218}, - {0, 175}, - {0, 3866}, - {0, 1950}, - {0, 1803}, - {0, 895}, - {3300, 1192}, - {2786, 2}, - {0, 2276}, - {0, 3723}, - {0, 2097}, - {0, 3861}, - {0, 3027}, - {0, 369}, - {0, 987}, - {3609, 2267}, - {2444, 2}, - {0, 1772}, - {0, 973}, - {0, 2541}, - {0, 1300}, - {5012, 1646}, - {0, 1798}, - {0, 2457}, - {2844, 668}, - {2204, 668}, - {1979, 668}, - {1900, 1788}, - {1228, 1788}, - {672, 1788}, - {4620, 2880}, - {955, 2880}, - {1978, 2880}, - {903, 2337}, - {4376, 2}, - {252, 3479}, - {676, 2}, - {594, 2678}, - {1391, 2}, - {1976, 1449}, - {2733, 2}, - {1685, 1533}, - {2042, 2}, - {831, 1493}, - {4309, 2}, - {174, 132}, - {445, 2}, - {513, 1331}, - {1463, 2}, - {2487, 3722}, - {1763, 2}, - {106, 709}, - {1469, 2}, - {2647, 790}, - {2097, 2}, - {0, 3315}, - {832, 1853}, - {105, 2}, - {4428, 3481}, - {1114, 2}, - {3968, 1585}, - {3050, 2}, - {1867, 1489}, - {3585, 2}, - {3209, 2786}, - {3287, 2}, - {4487, 2}, - {3971, 2818}, - {1177, 2818}, - {4226, 2818}, - {2122, 3421}, - {772, 2}, - {0, 3483}, - {0, 3269}, - {503, 845}, - {439, 2}, - {1535, 2629}, - {2123, 2}, - {2562, 797}, - {1831, 2}, - {4720, 2778}, - {3432, 2}, - {2214, 2730}, - {2835, 2}, - {2610, 1591}, - {2535, 2}, - {4203, 3569}, - {4719, 2}, - {484, 1640}, - {3899, 2}, - {4518, 1001}, - {3591, 2}, - {2418, 1063}, - {3047, 2}, - {2674, 3144}, - {2742, 2}, - {3941, 2109}, - {4515, 2}, - {612, 3271}, - {3681, 2}, - {2498, 661}, - {3918, 2}, - {319, 572}, - {4461, 2}, - {4652, 3679}, - {4735, 2}, - {3129, 1679}, - {2502, 2}, - {2020, 3527}, - {3401, 2}, - {0, 3088}, - {4017, 3059}, - {1107, 2}, - {0, 1422}, - {0, 649}, - {0, 1240}, - {2119, 3620}, - {744, 2}, - {4229, 3676}, - {86, 2}, - {542, 578}, - {460, 2}, - {1558, 2852}, - {2116, 2}, - {2592, 522}, - {1875, 2}, - {544, 477}, - {1737, 2}, - {3000, 418}, - {2317, 2}, - {0, 3270}, - {0, 2397}, - {0, 3425}, - {0, 1170}, - {0, 1393}, - {0, 1605}, - {0, 2230}, - {0, 1266}, - {0, 3865}, - {0, 301}, - {0, 3041}, - {0, 52}, - {0, 2353}, - {5103, 2}, - {4457, 29}, - {1067, 2598}, - {3932, 68}, - {3052, 37}, - {1802, 1532}, - {3636, 1267}, - {3276, 2762}, - {3354, 44}, - {4543, 120}, - {3140, 3571}, - {2329, 2307}, - {1147, 953}, - {2262, 2004}, - {3456, 1052}, - {1696, 742}, - {613, 2071}, - {1149, 268}, - {3943, 544}, - {281, 162}, - {4239, 2467}, - {4764, 2}, - {4773, 2}, - {4785, 2}, - {4774, 2}, - {4765, 2}, - {4793, 2}, - {4759, 2}, - {4767, 2}, - {4776, 2}, - {4758, 2}, - {2458, 1121}, - {3013, 868}, - {2734, 1891}, - {3935, 2159}, - {4760, 480}, - {4805, 2}, - {4779, 2}, - {0, 3508}, - {0, 3469}, - {2454, 874}, - {0, 2602}, - {3988, 2806}, - {3224, 530}, - {0, 3919}, - {4659, 1577}, - {1131, 383}, - {4145, 41}, - {3915, 1045}, - {3838, 1263}, - {2922, 1522}, - {1812, 201}, - {794, 1907}, - {2043, 710}, - {3219, 2}, - {4851, 59}, - {0, 106}, - {0, 215}, - {0, 173}, - {5107, 15}, - {0, 278}, - {5082, 155}, - {0, 72}, - {5125, 480}, - {0, 615}, - {0, 1324}, - {0, 291}, - {0, 205}, - {0, 64}, - {4854, 83}, - {0, 36}, - {4866, 240}, + {5003, 1}, + {4934, 1}, + {5123, 1}, + {5119, 196}, + {5000, 158}, + {5033, 48}, + {5008, 57}, + {4832, 154}, + {5012, 187}, + {4918, 169}, + {5130, 119}, + {4944, 167}, + {4883, 4}, + {5128, 163}, + {4991, 115}, + {5019, 55}, + {5014, 22}, + {4844, 157}, + {4987, 160}, + {0, 397}, + {5081, 54}, + {4904, 80}, + {4851, 139}, + {5075, 213}, + {5028, 76}, + {4996, 150}, + {4985, 212}, + {4869, 19}, + {4850, 67}, + {4843, 1}, + {4855, 1}, + {5029, 1}, + {5038, 1}, + {4990, 1}, + {5027, 1}, + {5085, 1}, + {5015, 1}, + {5084, 1}, + {4865, 1}, + {5031, 1}, + {5099, 1}, + {4984, 1}, + {4906, 1}, + {4964, 1}, + {4916, 1}, + {4926, 1}, + {4866, 1}, + {5080, 1}, + {4902, 1}, + {4859, 1}, + {4974, 1}, + {5107, 1}, + {5079, 1}, + {5093, 1}, + {0, 2}, + {1247, 291}, + {228, 2803}, + {1914, 196}, + {0, 20}, + {1462, 1967}, + {3575, 89}, + {4719, 21}, + {3297, 608}, + {1248, 726}, + {2754, 2344}, + {4654, 206}, + {2054, 157}, + {235, 1136}, + {1548, 3105}, + {2613, 1368}, + {3741, 1427}, + {2830, 2049}, + {4280, 1684}, + {2826, 2739}, + {618, 310}, + {4588, 2563}, + {4901, 1923}, + {833, 1842}, + {3470, 439}, + {2064, 3405}, + {4574, 366}, + {3134, 830}, + {4003, 78}, + {3130, 3842}, + {977, 1488}, + {3749, 3178}, + {0, 888}, + {498, 1031}, + {1206, 3698}, + {4372, 880}, + {2422, 3661}, + {982, 3366}, + {1849, 3891}, + {4969, 2786}, + {1500, 1185}, + {4192, 1378}, + {2949, 3288}, + {1951, 176}, + {3427, 3200}, + {0, 81}, + {0, 658}, + {37, 1}, + {2344, 1}, + {4649, 1}, + {386, 1}, + {2604, 1}, + {3700, 1}, + {5069, 1}, + {2127, 1}, + {4659, 1}, + {3344, 1}, + {4068, 1}, + {3348, 1}, + {722, 1}, + {3811, 1}, + {1877, 1}, + {580, 1}, + {4179, 1}, + {1568, 1}, + {563, 1}, + {2191, 1}, + {565, 1}, + {2879, 1}, + {5078, 1}, + {3354, 1}, + {1044, 1}, + {4254, 1}, + {2225, 1}, + {849, 1}, + {848, 1}, + {3236, 277}, + {1337, 1}, + {4010, 3695}, + {2820, 1}, + {4597, 737}, + {826, 1}, + {3486, 647}, + {4199, 1}, + {2901, 980}, + {4200, 1}, + {2216, 1733}, + {2622, 1}, + {446, 2243}, + {1727, 1}, + {1402, 227}, + {2902, 1}, + {0, 309}, + {825, 628}, + {1665, 1}, + {4146, 1428}, + {1104, 1}, + {3100, 2838}, + {4332, 1}, + {4580, 2985}, + {847, 1}, + {3449, 2920}, + {4257, 1}, + {2850, 2680}, + {4255, 1}, + {2165, 3785}, + {2618, 1}, + {370, 430}, + {1734, 1}, + {3060, 1720}, + {1572, 1}, + {4176, 1776}, + {2688, 1}, + {0, 2056}, + {134, 747}, + {4490, 1}, + {2408, 3191}, + {1237, 1}, + {192, 3700}, + {4125, 1}, + {1460, 3663}, + {667, 1}, + {2110, 3887}, + {2791, 1180}, + {2391, 1180}, + {4441, 1370}, + {3268, 1}, + {2635, 443}, + {1691, 1}, + {2789, 838}, + {4311, 1}, + {2790, 3851}, + {681, 1}, + {4607, 3176}, + {1995, 1}, + {808, 1018}, + {4150, 1018}, + {0, 1207}, + {3861, 3119}, + {3598, 1}, + {3862, 416}, + {1396, 1}, + {3305, 903}, + {1186, 1}, + {2479, 3541}, + {0, 1181}, + {1404, 3348}, + {409, 1}, + {2038, 3157}, + {412, 1}, + {3020, 2453}, + {2301, 1}, + {0, 1953}, + {3384, 1915}, + {1993, 1}, + {4517, 1863}, + {3207, 1}, + {3926, 2103}, + {3209, 1}, + {899, 851}, + {3662, 1}, + {1710, 3282}, + {424, 1}, + {2741, 2890}, + {1919, 1}, + {3881, 2955}, + {2980, 1}, + {4436, 2764}, + {2979, 1}, + {457, 3814}, + {4714, 1}, + {0, 465}, + {1532, 3516}, + {2912, 1}, + {275, 3447}, + {1887, 1}, + {933, 3265}, + {1888, 1}, + {3967, 2565}, + {1228, 1}, + {3324, 2086}, + {4348, 1}, + {4643, 3751}, + {935, 1}, + {3526, 3796}, + {4471, 1}, + {2911, 3620}, + {4472, 1}, + {1955, 2967}, + {2685, 648}, + {625, 1}, + {1837, 3349}, + {1473, 1}, + {2978, 2428}, + {190, 1}, + {1920, 80}, + {0, 663}, + {0, 248}, + {0, 3666}, + {0, 930}, + {0, 1596}, {0, 130}, - {0, 1260}, - {5085, 1418}, - {0, 78}, - {0, 287}, - {0, 216}, - {4864, 297}, - {3382, 908}, - {2084, 1009}, - {2516, 2}, - {3908, 2}, - {325, 2}, - {4450, 2}, - {4666, 2}, - {4910, 2}, - {4992, 2}, - {4850, 2}, - {4825, 2}, - {5068, 2}, - {5015, 2}, - {5051, 2}, - {4976, 2}, - {3706, 2}, - {2726, 2}, - {1545, 2}, - {3303, 2}, - {3534, 2}, - {0, 1620}, - {4254, 106}, - {3707, 72}, - {911, 1418}, - {4510, 1907}, - {3346, 1009}, - {4246, 78}, - {755, 36}, - {0, 3138}, - {0, 2117}, - {0, 1213}, - {0, 1279}, - {0, 1235}, - {0, 2998}, - {0, 12}, - {0, 3065}, - {0, 529}, - {0, 2386}, - {0, 3237}, - {0, 2589}, - {721, 615}, - {2390, 240}, - {1271, 130}, - {3734, 72}, - {3519, 15}, - {0, 370}, - {446, 130}, + {0, 2447}, + {0, 2030}, + {0, 1164}, + {0, 278}, + {0, 1651}, + {0, 2733}, + {0, 958}, + {0, 2020}, + {0, 788}, + {0, 752}, + {0, 3219}, + {0, 1281}, + {0, 2691}, + {0, 743}, + {2785, 3527}, + {2400, 1}, + {0, 1194}, + {0, 1977}, + {0, 1511}, + {0, 1469}, + {0, 2639}, + {0, 3390}, + {0, 279}, + {1813, 2608}, + {3831, 1}, + {0, 1258}, + {0, 677}, + {0, 2983}, + {0, 2378}, + {5076, 915}, + {0, 3555}, + {0, 3840}, + {1386, 42}, + {493, 42}, + {2000, 42}, + {490, 2124}, + {2957, 2124}, + {2285, 2124}, + {4318, 615}, + {3076, 615}, + {3737, 615}, + {494, 2490}, + {2609, 1}, + {3976, 1903}, + {3140, 1}, + {3977, 3089}, + {1885, 1}, + {3453, 2259}, + {724, 1}, + {2059, 2008}, + {2353, 1}, + {3139, 3079}, + {1172, 1}, + {1961, 1245}, + {495, 1}, + {1964, 2491}, + {4470, 1}, + {2812, 3462}, + {4000, 1}, + {3767, 3121}, + {491, 1}, + {2624, 3170}, + {3933, 1}, + {0, 3416}, + {1925, 2308}, + {3480, 1}, + {795, 1779}, + {2045, 1}, + {3294, 470}, + {2497, 1}, + {4427, 413}, + {3557, 1}, + {3890, 26}, + {3559, 1}, + {1122, 1}, + {4139, 1061}, + {1484, 1061}, + {354, 1061}, + {2529, 3142}, + {1662, 1}, + {0, 3211}, + {0, 3900}, + {4196, 3393}, + {2895, 1}, + {536, 2330}, + {4511, 1}, + {2034, 1818}, + {771, 1}, + {335, 1137}, + {4148, 1}, + {1599, 1217}, + {534, 1}, + {2219, 895}, + {535, 1}, + {2907, 2188}, + {2484, 1}, + {4402, 2652}, + {3300, 1}, + {1695, 3350}, + {2647, 1}, + {471, 3402}, + {1369, 1}, + {1130, 3216}, + {1372, 1}, + {3887, 2510}, + {802, 1}, + {3397, 2015}, + {4619, 1}, + {2738, 3867}, + {1917, 1}, + {3875, 3927}, + {2974, 1}, + {4434, 3690}, + {2975, 1}, + {462, 3097}, + {4720, 1}, + {2084, 1699}, + {1006, 1}, + {0, 1238}, + {2375, 1323}, + {1017, 1}, + {0, 1580}, + {0, 106}, + {0, 3602}, + {97, 2667}, + {4044, 1}, + {1412, 2605}, + {417, 1}, + {2043, 2367}, + {415, 1}, + {3017, 3461}, + {2294, 1}, + {4216, 1121}, + {3212, 1}, + {3692, 3776}, + {402, 1}, + {2545, 3821}, + {3995, 1}, + {0, 3542}, + {0, 616}, + {0, 3563}, + {0, 3245}, + {0, 342}, + {0, 3935}, {0, 1725}, - {0, 3101}, - {0, 2432}, - {0, 1280}, - {3726, 3302}, - {3253, 1586}, - {0, 2680}, - {3927, 2204}, - {0, 591}, - {0, 3473}, - {4919, 100}, - {4435, 2888}, - {0, 702}, - {0, 1593}, - {0, 3502}, - {0, 1283}, - {355, 2429}, - {1048, 1974}, - {1539, 249}, - {0, 1784}, - {4836, 319}, - {0, 1364}, - {0, 1146}, - {4955, 2411}, - {0, 1104}, - {4963, 1084}, - {4857, 584}, - {5075, 1661}, - {4826, 2130}, - {187, 433}, - {4903, 1462}, - {0, 2340}, - {0, 1814}, - {0, 516}, - {5076, 1115}, - {0, 170}, - {0, 2392}, - {0, 636}, - {0, 203}, - {5000, 2047}, - {0, 1696}, - {0, 316}, - {0, 1906}, - {5119, 142}, - {0, 1400}, - {0, 475}, - {0, 2535}, - {4930, 425}, - {0, 1665}, - {4928, 2738}, - {0, 2665}, - {0, 1166}, - {4835, 2}, - {5058, 2}, - {4938, 2}, - {5040, 2}, - {4939, 2}, - {4863, 2}, - {2093, 2}, - {4998, 2}, - {4891, 2}, - {5044, 2}, - {5115, 2}, - {4929, 2}, - {4991, 2}, - {4090, 2}, - {3488, 2}, - {3861, 2}, - {4922, 2}, - {1799, 2}, - {3630, 2}, - {2526, 2}, - {4747, 2}, - {0, 1787}, - {0, 1509}, + {0, 2214}, + {0, 1764}, + {0, 2042}, + {0, 763}, + {0, 3183}, + {0, 2975}, + {4874, 1}, + {3985, 119}, + {2875, 2984}, + {1866, 4}, + {2766, 54}, + {638, 382}, + {1504, 863}, + {1265, 83}, + {1503, 150}, + {3747, 19}, + {2056, 1179}, + {712, 3017}, + {1830, 2942}, + {2674, 1986}, + {578, 2996}, + {1550, 2420}, + {3712, 2020}, + {945, 115}, + {3635, 80}, + {4651, 212}, + {4479, 203}, + {4762, 1}, + {4774, 1}, + {4791, 1}, + {4776, 1}, + {4771, 1}, + {4797, 1}, + {4765, 1}, + {4760, 1}, + {4775, 1}, + {4767, 1}, + {4363, 3595}, + {3619, 3523}, + {3618, 283}, + {1060, 2747}, + {4761, 369}, + {4779, 1}, + {4780, 1}, + {0, 2128}, + {0, 2182}, + {2610, 1891}, + {0, 1216}, + {2756, 2840}, + {4485, 2411}, + {0, 1228}, + {2476, 2246}, + {4450, 1305}, + {3562, 2184}, + {3866, 1569}, + {3564, 2212}, + {1116, 137}, + {1467, 1944}, + {772, 1919}, + {4512, 71}, + {1986, 1}, + {4837, 254}, + {0, 341}, + {0, 583}, + {0, 27}, + {4957, 6}, + {0, 112}, + {4917, 927}, + {0, 94}, + {5122, 369}, + {0, 533}, + {0, 186}, + {0, 726}, + {0, 1575}, + {0, 484}, + {5048, 2239}, + {0, 15}, + {5129, 351}, + {0, 123}, + {0, 887}, + {4888, 314}, + {0, 697}, + {0, 258}, + {0, 807}, + {4942, 63}, + {1397, 3518}, + {55, 1606}, + {475, 1}, + {3779, 1}, + {1699, 1}, + {67, 1}, + {2322, 1}, + {4961, 1}, + {4884, 1}, + {5118, 1}, + {5010, 1}, + {5127, 1}, + {5001, 1}, + {5057, 1}, + {4992, 1}, + {1868, 1}, + {2775, 1}, + {608, 1}, + {1515, 1}, + {1272, 1}, {0, 2913}, - {0, 3530}, + {3745, 341}, + {991, 94}, + {3520, 314}, + {4743, 1919}, + {4447, 1606}, + {1291, 697}, + {3307, 15}, + {0, 3799}, + {0, 2783}, + {0, 1350}, + {0, 1012}, + {0, 946}, + {0, 689}, + {0, 1968}, + {0, 2472}, + {0, 3209}, + {0, 1754}, {0, 1825}, - {0, 2051}, - {0, 3531}, - {0, 2720}, - {0, 3756}, - {0, 2080}, - {4846, 2543}, - {4887, 2}, - {1902, 160}, - {654, 2}, - {0, 1338}, - {0, 518}, - {0, 2508}, - {0, 976}, - {0, 2727}, - {0, 2916}, - {0, 3742}, - {0, 2716}, - {0, 763}, - {0, 3544}, - {0, 2040}, - {0, 1006}, - {0, 1804}, - {0, 3617}, - {0, 2574}, - {0, 271}, - {0, 1386}, - {0, 573}, - {0, 2667}, - {0, 3890}, - {0, 1972}, - {0, 926}, - {0, 2202}, - {0, 3873}, - {0, 2154}, - {0, 1770}, - {0, 691}, - {0, 2017}, - {0, 3798}, - {0, 2950}, - {0, 671}, - {0, 1781}, - {0, 971}, - {2752, 3340}, - {4499, 2}, - {0, 1404}, - {0, 1595}, - {0, 2891}, - {0, 3098}, - {0, 2520}, - {0, 334}, - {2362, 2057}, - {178, 2}, - {3521, 1051}, - {4055, 2}, - {0, 1846}, - {3946, 3551}, - {2732, 2}, - {5123, 56}, - {5055, 2}, - {2149, 2483}, - {434, 2}, - {3289, 3366}, - {3699, 2}, - {2571, 2274}, - {3510, 2}, - {0, 187}, - {2811, 2766}, - {1917, 2}, - {2050, 1060}, - {507, 2}, - {3208, 2110}, - {3755, 2}, - {5029, 794}, - {4944, 2}, - {3680, 2740}, - {3021, 2}, - {3867, 3008}, - {1244, 2}, - {1087, 744}, - {1454, 2}, - {4553, 1834}, - {2971, 2}, - {4173, 1044}, - {4227, 2}, - {3044, 2928}, - {3656, 2}, - {0, 2074}, - {492, 3609}, - {2030, 2}, - {0, 2784}, - {0, 3817}, - {0, 2048}, - {0, 303}, - {0, 2682}, - {0, 3503}, - {0, 2435}, - {0, 252}, - {0, 1886}, - {0, 3852}, - {0, 3051}, - {0, 3654}, - {0, 1992}, - {0, 3526}, - {0, 1417}, - {0, 322}, - {0, 1716}, - {0, 3436}, - {0, 2690}, - {0, 292}, - {0, 1433}, - {0, 623}, - {0, 2584}, - {0, 3458}, - {0, 1361}, - {0, 217}, - {0, 1637}, + {0, 216}, + {4528, 533}, + {590, 351}, + {604, 123}, + {2818, 94}, + {1998, 6}, + {0, 491}, + {3715, 123}, + {0, 2818}, + {0, 2771}, + {0, 1812}, + {0, 2401}, + {4226, 1897}, + {1399, 3386}, + {0, 315}, + {1630, 3136}, + {0, 1916}, + {0, 75}, + {5067, 660}, + {2418, 2637}, + {0, 1674}, + {0, 2977}, + {0, 1562}, + {0, 3659}, + {284, 1060}, + {149, 3884}, + {4276, 1543}, + {0, 2598}, + {5007, 402}, {0, 713}, - {0, 3255}, - {0, 1876}, - {0, 1635}, - {0, 2487}, - {0, 539}, - {0, 2265}, - {0, 1363}, - {0, 2805}, - {0, 3279}, - {0, 1000}, - {0, 893}, - {0, 2434}, - {0, 3102}, - {0, 2052}, - {0, 3916}, - {0, 1842}, - {0, 2893}, - {0, 1469}, - {0, 863}, - {0, 3384}, - {0, 2342}, - {0, 842}, - {0, 574}, - {0, 3313}, - {0, 1677}, - {0, 3143}, - {0, 270}, - {0, 3655}, - {0, 2451}, - {0, 2014}, - {0, 2618}, - {0, 1095}, - {0, 210}, - {0, 3154}, - {0, 1373}, - {0, 3359}, - {0, 548}, - {1811, 2094}, - {4784, 2}, - {4791, 2}, - {4813, 2}, - {4795, 2}, - {4814, 2}, - {4794, 2}, - {4817, 2}, - {4800, 2}, - {4786, 2}, - {4823, 2}, - {4775, 2}, - {4796, 2}, - {4811, 2}, - {4798, 2}, - {4812, 2}, - {4799, 2}, - {4821, 2}, - {4788, 2}, - {4973, 2}, - {5031, 2}, - {5084, 2}, - {5110, 2}, - {4948, 2}, - {5030, 2}, - {4911, 2}, - {5062, 2}, - {4844, 2}, - {5092, 2}, - {4845, 2}, - {5024, 2}, - {4856, 2}, - {4888, 2}, - {5081, 2}, - {4977, 2}, - {5033, 2}, - {4909, 2}, - {4953, 2}, - {5120, 2}, - {4883, 2}, - {5080, 2}, - {5097, 2}, - {4787, 2}, - {4804, 2}, - {4801, 2}, - {2185, 2}, - {2556, 2}, - {2718, 2}, - {4625, 2}, - {1439, 2}, - {5089, 2}, - {4862, 2}, - {5122, 2}, - {4797, 2}, - {4778, 2}, - {4820, 2}, - {4815, 2}, - {4803, 2}, - {4822, 2}, - {4542, 3463}, - {1526, 1487}, - {777, 2270}, - {1958, 4}, - {4135, 2}, - {5067, 2}, - {2021, 2}, - {4958, 2}, - {1600, 2}, - {5049, 2}, - {4818, 2}, - {4842, 2}, - {4941, 2}, - {5023, 2}, - {5116, 2}, - {5001, 2}, - {4906, 2}, - {5003, 2}, - {1521, 2}, - {5096, 2}, - {4969, 2}, - {5129, 2}, - {2963, 2}, - {4892, 2}, - {357, 2}, - {4763, 2}, - {4783, 2}, - {3252, 239}, - {4033, 3162}, - {2099, 1345}, - {165, 3357}, - {1323, 532}, - {2453, 3826}, - {59, 2638}, - {1876, 1797}, - {4940, 2}, - {4843, 2}, - {5114, 2}, - {4782, 2}, - {4761, 2}, - {4852, 2}, - {3107, 2}, - {4158, 2}, - {1161, 677}, - {1703, 3043}, - {941, 2460}, - {4905, 2}, - {4982, 2}, - {5118, 2}, - {5018, 2}, - {4896, 2}, - {1458, 3621}, - {2494, 2582}, - {4868, 2}, - {2500, 49}, - {2648, 1715}, - {2370, 3896}, - {3380, 2450}, - {5022, 2}, - {4886, 2}, - {4996, 2}, - {994, 2}, - {1688, 2}, - {1839, 2}, - {419, 2464}, - {1503, 1970}, - {4890, 2}, - {1778, 2}, - {5060, 2}, - {4873, 2}, - {1547, 2}, - {433, 2}, - {4193, 2}, - {5034, 2}, - {2538, 2}, - {4806, 2}, - {4762, 2}, - {4841, 2}, - {4018, 2}, - {4912, 2}, - {1233, 2}, - {1080, 2}, - {4616, 2}, - {2965, 2}, - {4920, 2}, - {5011, 2}, - {3073, 2}, - {4279, 2}, - {1809, 2}, - {4771, 2}, - {4943, 2}, - {1186, 2}, - {2369, 2}, - {814, 2}, - {978, 2}, - {465, 262}, - {4808, 2}, - {4792, 2}, - {2543, 2516}, - {4802, 2}, - {4781, 2}, - {2240, 1968}, - {652, 3789}, - {3900, 2131}, - {4777, 2}, - {5104, 2}, - {4942, 2}, - {3371, 2810}, - {4988, 2}, - {4736, 3628}, - {4990, 2}, - {4391, 1704}, - {5013, 2}, - {1217, 2857}, - {5045, 2}, - {226, 1427}, - {3390, 2025}, - {4819, 2}, - {4789, 2}, - {3477, 3396}, - {4807, 2}, - {3917, 3912}, - {3415, 2619}, - {4472, 1829}, - {3628, 2448}, - {1522, 879}, - {3435, 2114}, - {4975, 2}, - {5112, 2}, - {1747, 1603}, - {4921, 2}, - {2552, 1013}, - {5020, 2}, - {3213, 2897}, - {4993, 2}, - {2425, 1728}, - {4918, 2}, - {4332, 3713}, - {4967, 2}, - {5028, 2}, - {2644, 2029}, - {4855, 2}, - {2889, 2}, - {0, 93}, - {0, 3578}, - {0, 2321}, - {0, 2136}, - {0, 2504}, - {0, 958}, - {0, 27}, - {0, 3234}, - {0, 1238}, - {0, 3467}, - {0, 393}, - {0, 3746}, - {0, 2537}, - {0, 1917}, - {0, 1510}, - {0, 3765}, - {0, 3156}, - {0, 206}, - {0, 2261}, - {0, 556}, - {0, 3363}, - {0, 997}, - {0, 1624}, - {0, 2804}, - {0, 804}, - {0, 2382}, - {0, 3058}, - {0, 2024}, - {0, 3859}, - {0, 1756}, - {0, 2819}, - {0, 1388}, - {0, 915}, - {0, 3323}, - {0, 1439}, - {0, 3708}, - {0, 3509}, - {0, 454}, - {0, 143}, - {0, 1630}, - {2868, 368}, - {0, 1429}, - {0, 2308}, - {0, 313}, - {0, 2560}, - {0, 1706}, - {0, 3077}, - {4927, 2}, - {2525, 2}, - {4926, 2}, - {396, 2}, - {5005, 2}, - {4400, 2}, - {5099, 2}, - {879, 2}, - {5083, 2}, - {35, 2}, - {4972, 2}, - {4536, 2}, - {4952, 2}, - {2169, 2}, - {5093, 2}, - {615, 2}, - {5130, 2}, - {4861, 2}, - {2741, 2}, - {3385, 2}, - {4946, 2}, - {2822, 2}, - {0, 1115}, - {0, 1885}, - {0, 1217}, - {0, 3464}, - {0, 411}, - {0, 2604}, - {0, 3}, - {0, 3243}, - {0, 844}, - {0, 1447}, - {0, 2919}, - {0, 308}, - {0, 2885}, - {0, 2676}, - {0, 1558}, - {0, 368}, - {0, 1305}, - {0, 2437}, - {0, 1987}, - {0, 277}, - {0, 3790}, - {0, 616}, - {0, 3104}, - {0, 2440}, - {0, 1314}, - {0, 3288}, - {0, 1561}, - {0, 2675}, - {0, 2194}, + {0, 488}, + {4915, 1235}, + {0, 1229}, + {4860, 1301}, + {5117, 266}, + {4941, 2173}, + {4968, 633}, + {2416, 2937}, + {5068, 848}, + {0, 925}, + {0, 2449}, + {0, 1762}, + {4847, 2058}, + {0, 1143}, + {0, 612}, + {0, 652}, + {0, 876}, + {5002, 1317}, + {0, 681}, + {0, 1774}, + {0, 417}, + {5049, 2208}, + {0, 890}, + {0, 2480}, + {0, 1421}, + {5066, 1612}, + {0, 928}, + {4952, 1602}, + {0, 476}, + {0, 2004}, + {4933, 1}, + {4838, 1}, + {4909, 1}, + {4946, 1}, + {5131, 1}, + {5102, 1}, + {2680, 1}, + {4830, 1}, + {5036, 1}, + {5020, 1}, + {4882, 1}, + {5043, 1}, + {4963, 1}, + {1000, 1}, + {2707, 1}, + {3048, 1}, + {4970, 1}, + {1033, 1}, + {1432, 1}, + {1561, 1}, + {3338, 1}, + {0, 1138}, + {0, 184}, + {0, 2527}, + {0, 3804}, + {0, 2542}, + {0, 61}, + {0, 2741}, + {0, 2876}, + {0, 3312}, + {0, 2851}, + {4929, 813}, + {4947, 1}, + {3349, 2394}, + {1932, 1}, + {0, 2337}, + {0, 3623}, + {0, 2294}, + {0, 3387}, + {0, 2063}, + {0, 3545}, + {0, 3389}, + {0, 2959}, + {0, 2232}, + {0, 3732}, + {0, 1397}, + {0, 1254}, + {0, 655}, + {0, 1283}, + {0, 2577}, + {0, 1204}, + {0, 1015}, + {0, 1556}, + {0, 1045}, + {0, 622}, + {0, 3046}, + {0, 2640}, + {0, 3345}, + {0, 1087}, + {0, 1080}, + {0, 1952}, + {0, 2143}, {0, 562}, - {0, 3589}, - {0, 3856}, - {0, 1643}, - {0, 1882}, - {0, 2745}, - {0, 807}, - {0, 2936}, - {0, 2127}, - {0, 2572}, - {0, 3881}, - {0, 76}, - {0, 1735}, - {0, 3887}, - {0, 3277}, - {0, 194}, - {0, 2400}, - {0, 1147}, - {0, 1632}, - {0, 2774}, - {4195, 181}, - {2536, 487}, - {3306, 171}, - {1671, 101}, - {889, 551}, - {2872, 298}, - {4651, 286}, - {3593, 29}, - {2472, 482}, - {4714, 68}, - {3084, 320}, - {1355, 268}, - {3498, 134}, - {3638, 131}, - {2407, 485}, - {459, 649}, - {1666, 307}, - {2033, 37}, - {468, 198}, - {1432, 57}, - {3058, 44}, - {1970, 2696}, - {572, 1743}, - {3194, 3552}, - {3812, 171}, - {2787, 101}, - {3425, 551}, - {3882, 1041}, - {2850, 133}, - {2960, 1645}, - {2044, 286}, - {659, 320}, - {3085, 134}, - {3886, 1831}, - {3443, 2659}, - {3806, 3838}, - {2867, 197}, - {4073, 307}, - {792, 198}, - {931, 57}, - {1583, 3601}, - {4458, 1950}, - {2484, 107}, - {3760, 1158}, - {4661, 106}, - {2631, 215}, - {4120, 173}, - {486, 78}, - {4324, 287}, - {4443, 482}, - {2838, 37}, - {919, 57}, - {1303, 107}, - {125, 106}, - {1138, 215}, - {1373, 240}, - {557, 78}, - {4611, 287}, - {4132, 516}, - {2869, 2243}, - {2175, 7}, - {2542, 2746}, - {2709, 16}, - {1433, 184}, - {830, 1353}, - {1903, 673}, - {1815, 1796}, - {712, 175}, - {2406, 1218}, - {3257, 376}, - {1739, 3194}, - {1584, 2673}, - {950, 1144}, - {2851, 3016}, - {4707, 894}, - {3573, 3615}, - {2622, 196}, - {4656, 1803}, - {3192, 2657}, - {4263, 85}, - {408, 895}, - {576, 2463}, - {1965, 1657}, - {4134, 3027}, - {3466, 1409}, - {4548, 2230}, - {3903, 1772}, - {3403, 149}, - {4463, 973}, - {3296, 1266}, - {1879, 5}, - {1706, 3320}, - {913, 565}, - {2899, 1646}, - {4678, 72}, - {4810, 2}, - {4790, 2}, - {269, 3883}, - {4630, 2}, - {4482, 1983}, - {2727, 2}, - {1038, 922}, - {1791, 2}, - {601, 2195}, - {820, 2}, - {1776, 3849}, - {172, 2}, - {3937, 2581}, - {746, 2}, - {884, 254}, - {1677, 2}, - {4347, 1397}, - {2598, 2}, - {3666, 588}, - {4692, 2}, - {2503, 2695}, - {4154, 2}, - {4449, 3460}, - {643, 2}, - {490, 1359}, - {2032, 2}, - {4067, 238}, - {3528, 2}, - {4752, 1644}, - {3712, 2}, - {3620, 3491}, - {4275, 2}, - {3092, 2616}, - {1639, 2}, - {1777, 212}, - {851, 2}, - {2966, 1374}, - {4618, 2}, - {3384, 553}, - {2750, 2}, - {4498, 2647}, - {3318, 2}, - {1905, 3496}, - {2817, 2}, - {2956, 1445}, - {4305, 2}, - {1770, 288}, - {1076, 2}, - {2242, 1692}, - {1554, 2}, - {1041, 3428}, - {2165, 2}, - {2518, 3308}, - {2218, 2}, - {2361, 1689}, - {181, 2}, - {3523, 630}, - {4056, 2}, - {2799, 1446}, - {3295, 2}, - {3945, 3226}, - {2729, 2}, - {2892, 824}, - {1981, 2}, - {2150, 3038}, - {432, 2}, - {3288, 3869}, - {3697, 2}, - {2570, 2844}, - {3511, 2}, - {3741, 931}, - {2935, 2}, - {2812, 2413}, - {1916, 2}, - {2047, 633}, - {508, 2}, - {3211, 1741}, - {3758, 2}, - {2491, 364}, - {3580, 2}, - {3676, 2379}, - {3019, 2}, - {3868, 2685}, - {1241, 2}, - {1086, 300}, - {1457, 2}, - {4555, 1440}, - {2972, 2}, - {4174, 626}, - {4225, 2}, - {3042, 2587}, - {3655, 2}, - {4448, 1707}, - {644, 2}, - {491, 3293}, - {2031, 2}, - {4065, 2445}, - {3533, 2}, - {4750, 2979}, - {3713, 2}, - {3618, 1682}, - {4277, 2}, - {189, 747}, - {4557, 2}, - {4686, 3006}, - {2481, 2}, - {1240, 3812}, - {1563, 2}, - {524, 2777}, - {887, 2}, - {1701, 704}, - {248, 2}, - {4181, 1237}, - {967, 2}, - {813, 3352}, - {1760, 2}, - {4291, 2506}, - {2691, 2}, - {3865, 3159}, - {4486, 2}, - {2744, 1343}, - {3926, 2}, - {2550, 3639}, - {2195, 2}, - {2321, 2140}, - {133, 2}, - {3551, 1137}, - {4001, 2}, - {2840, 1936}, - {3333, 2}, - {3990, 3717}, - {2773, 2}, - {3873, 2802}, - {1238, 2}, - {1089, 1125}, - {1450, 2}, - {4562, 2155}, - {2980, 2}, - {4166, 855}, - {4220, 2}, - {3035, 2900}, - {3645, 2}, - {370, 3670}, - {4695, 2}, - {4572, 2201}, - {2658, 2}, - {1102, 1183}, - {1731, 2}, - {658, 1979}, - {748, 2}, - {1869, 3643}, - {61, 2}, - {4409, 2}, - {685, 2}, - {528, 2}, - {2090, 2}, - {4021, 935}, - {3559, 2979}, - {0, 3872}, - {4635, 580}, - {287, 2}, - {91, 2341}, - {2462, 2}, - {3685, 3225}, - {3351, 2}, - {4375, 2578}, - {4045, 2}, - {3226, 629}, - {4595, 2}, - {4701, 3106}, - {364, 2}, - {203, 890}, - {2379, 2}, - {3750, 1954}, - {3281, 2}, - {4424, 1153}, - {3944, 2}, - {3291, 3032}, - {4505, 2}, - {3097, 2869}, - {1635, 2}, - {1783, 1176}, - {847, 2}, - {2969, 2211}, - {4626, 2}, - {3376, 938}, - {2748, 2}, - {4493, 2828}, - {3316, 2}, - {2548, 1994}, - {2197, 2}, - {2324, 3879}, - {126, 2}, - {3546, 3084}, - {4007, 2}, - {2839, 3692}, - {3337, 2}, - {3985, 1887}, - {2775, 2}, - {2067, 494}, - {2961, 2}, - {2825, 2304}, - {4433, 2}, - {1644, 3171}, - {1231, 2}, - {2371, 2518}, - {1407, 2}, - {1184, 384}, - {2009, 2}, - {3372, 2049}, - {1333, 2}, - {1489, 3532}, - {1120, 2}, - {2687, 2721}, - {4340, 2}, - {3106, 3751}, - {3045, 2}, - {4233, 2076}, - {3607, 2}, - {1656, 2671}, - {3205, 2}, - {3358, 321}, - {3984, 2}, - {2130, 1415}, - {94, 2}, - {1372, 608}, - {2343, 2}, - {124, 2575}, - {1756, 2}, - {592, 3510}, - {4367, 2}, - {4245, 1435}, - {3031, 2}, - {759, 294}, - {1518, 2}, - {283, 1699}, - {1109, 2}, - {1444, 3426}, - {531, 2}, - {4091, 2613}, - {908, 2}, - {771, 219}, - {1877, 2}, - {4258, 1362}, - {2791, 2}, - {3805, 538}, - {4586, 2}, - {2659, 2660}, - {4035, 2}, - {0, 2366}, - {0, 541}, - {0, 1638}, - {894, 2}, - {511, 2}, - {2077, 2}, - {1094, 2}, - {985, 2}, - {4175, 2}, - {4009, 2}, - {3222, 2}, - {516, 3103}, - {2325, 733}, - {1242, 3705}, - {69, 347}, - {2457, 1898}, - {751, 2522}, - {916, 3215}, - {4081, 1926}, - {3931, 2}, - {3297, 2}, - {448, 2}, - {2399, 2}, - {1175, 2}, - {175, 2}, - {2298, 3447}, - {2569, 2137}, - {2736, 1372}, - {4491, 2260}, - {1543, 208}, - {718, 2494}, - {835, 2}, - {2358, 2}, - {1658, 2}, - {3202, 2}, - {3350, 2}, - {3989, 2}, - {2135, 2}, - {90, 2}, - {1375, 2596}, - {2339, 2139}, - {134, 647}, - {1750, 3534}, - {3615, 1776}, - {1540, 3150}, - {1395, 3761}, - {1180, 1103}, - {2573, 2}, - {4395, 2}, - {3282, 2}, - {2808, 2}, - {4431, 2}, - {3369, 2}, - {2014, 2}, - {2880, 2}, - {3027, 2565}, - {4230, 1708}, - {1846, 3406}, - {1016, 1425}, - {2264, 2310}, - {1464, 1847}, - {1116, 74}, - {2059, 3878}, - {1642, 2}, - {3090, 2}, - {3223, 2}, - {4004, 2}, - {2065, 2}, - {122, 2}, - {95, 3199}, - {1838, 1099}, - {645, 2224}, - {4447, 714}, - {4316, 438}, - {2984, 3445}, - {312, 2}, - {999, 2}, - {1517, 2}, - {381, 2}, - {4208, 2}, - {938, 2}, - {790, 2}, - {1729, 2}, - {2660, 2410}, - {4532, 2781}, - {3964, 1160}, - {3902, 2105}, - {3780, 2}, - {3563, 2}, - {152, 2}, - {2079, 2}, - {958, 2}, - {407, 2}, - {2110, 2}, - {1019, 2}, - {862, 989}, - {4136, 2472}, - {3987, 2715}, - {3353, 1931}, - {427, 3541}, - {2455, 2141}, - {1159, 2917}, - {156, 1502}, - {2326, 2}, - {805, 383}, - {933, 2}, - {4216, 1045}, - {4071, 2}, - {3277, 1263}, - {494, 2}, - {2383, 1522}, - {1225, 2}, - {42, 201}, - {2397, 2}, - {737, 1907}, - {2188, 2}, - {2554, 710}, - {1440, 1600}, - {838, 657}, - {1899, 161}, - {1820, 349}, - {717, 2251}, - {2412, 735}, - {1641, 1222}, - {3091, 3090}, - {3225, 1600}, - {4003, 657}, - {2064, 161}, - {138, 349}, - {1300, 2251}, - {2427, 735}, - {87, 1222}, - {1841, 3090}, - {3553, 1107}, - {1441, 2626}, - {1290, 1654}, - {1237, 1854}, - {2551, 3232}, - {4432, 86}, - {3271, 2334}, - {2929, 429}, - {4393, 1107}, - {3507, 2626}, - {1890, 1654}, - {2861, 1854}, - {2999, 3232}, - {4343, 86}, - {1746, 2334}, - {1117, 429}, - {2208, 1951}, - {1525, 1094}, - {1015, 1161}, - {2137, 2725}, - {3715, 3036}, - {998, 613}, - {1140, 888}, - {1345, 1691}, - {4654, 1951}, - {2876, 1094}, - {3958, 1161}, - {4446, 2725}, - {2849, 3036}, - {3884, 613}, - {2746, 888}, - {2435, 1691}, - {2278, 2}, - {258, 2}, - {3452, 909}, - {4117, 1871}, - {3015, 2183}, - {4191, 2}, - {2493, 195}, - {1549, 3040}, - {3579, 552}, - {3441, 819}, - {3793, 383}, - {2267, 1871}, - {546, 3422}, - {1848, 480}, - {1914, 3422}, - {692, 3073}, - {1308, 1250}, - {3298, 2839}, - {1874, 214}, - {1714, 1100}, - {2903, 2}, - {4682, 3566}, - {3597, 817}, - {2508, 1045}, - {4694, 2863}, - {3118, 1263}, - {3516, 214}, - {1473, 3696}, - {1332, 3498}, - {1261, 471}, - {2501, 2}, - {4470, 2}, - {3245, 2}, - {2887, 945}, - {3577, 2}, - {1550, 2}, - {1398, 2143}, - {1198, 2918}, - {2581, 1139}, - {4398, 1522}, - {2815, 2388}, - {4413, 3712}, - {3381, 413}, - {4219, 2}, - {458, 2}, - {607, 2}, - {2001, 2728}, - {4092, 2}, - {3495, 2}, - {4509, 2}, - {3875, 2}, - {3367, 3891}, - {4429, 81}, - {3717, 1113}, - {997, 1907}, - {1137, 2817}, - {1348, 1760}, - {4655, 1577}, - {2874, 1064}, - {2852, 1199}, - {3883, 1316}, - {881, 1215}, - {3938, 2}, - {3308, 546}, - {450, 2502}, - {2402, 201}, - {1202, 3155}, - {192, 710}, - {2350, 1316}, - {833, 176}, - {4480, 754}, - {272, 722}, - {2290, 722}, - {216, 722}, - {3687, 3362}, - {4022, 720}, - {402, 1}, - {1523, 1}, - {3143, 1}, - {1006, 2222}, - {2770, 281}, - {3173, 1680}, - {2986, 3063}, - {1423, 3695}, - {2702, 2703}, - {2028, 1058}, - {4053, 3079}, - {3518, 785}, - {3682, 1581}, - {2611, 50}, - {4353, 482}, - {4478, 30}, - {3416, 800}, - {4503, 167}, - {48, 1077}, - {251, 105}, - {2266, 637}, - {3792, 420}, - {3176, 362}, - {4235, 447}, - {4150, 755}, - {3105, 28}, - {4688, 131}, - {1051, 50}, - {3664, 222}, - {3800, 731}, - {3453, 432}, - {259, 30}, - {1955, 800}, - {740, 167}, - {668, 1077}, - {1936, 105}, - {1254, 637}, - {3925, 420}, - {760, 362}, - {900, 447}, - {1699, 755}, - {4370, 28}, - {3690, 181}, - {4711, 551}, - {2480, 485}, - {4184, 162}, - {3733, 1041}, - {1123, 29}, - {1268, 320}, - {1344, 268}, - {4725, 134}, - {2857, 131}, - {4031, 307}, - {4379, 544}, - {2885, 198}, - {3030, 1275}, - {1511, 1528}, - {374, 2859}, - {111, 7}, - {4386, 1539}, - {3057, 2812}, - {703, 705}, - {1533, 133}, - {1062, 2499}, - {522, 286}, - {71, 29}, - {85, 29}, - {3703, 1693}, - {431, 482}, - {415, 268}, - {632, 268}, - {582, 131}, - {1985, 667}, - {286, 307}, - {598, 191}, - {166, 37}, - {2782, 1651}, - {2393, 3846}, - {2248, 3236}, - {151, 5}, - {3069, 297}, - {1664, 320}, - {3177, 2692}, - {467, 171}, - {46, 551}, - {298, 551}, - {774, 184}, - {0, 1126}, - {426, 134}, - {616, 485}, - {3111, 1547}, - {3234, 1807}, - {4028, 2807}, - {2069, 700}, - {144, 482}, - {2449, 2486}, - {56, 36}, - {1866, 215}, - {635, 215}, - {74, 36}, - {4344, 716}, - {284, 101}, - {271, 101}, - {559, 68}, - {2762, 3779}, - {3970, 317}, - {1226, 3586}, - {3901, 1336}, - {3763, 2108}, - {3554, 3083}, - {115, 1070}, - {2060, 2849}, - {925, 1852}, - {404, 2319}, - {2139, 3556}, - {1017, 612}, - {868, 70}, - {4112, 2713}, - {3952, 2473}, - {3330, 1678}, - {375, 482}, - {2416, 521}, - {1146, 791}, - {112, 1769}, - {2330, 107}, - {786, 3851}, - {946, 1062}, - {4197, 140}, - {4050, 1048}, - {3256, 162}, - {477, 2073}, - {2347, 3394}, - {1218, 268}, - {5, 7}, - {2405, 101}, - {704, 134}, - {2202, 482}, - {2524, 521}, - {2699, 791}, - {4601, 1769}, - {1419, 107}, - {822, 3851}, - {1887, 1062}, - {1798, 140}, - {723, 1048}, - {2391, 162}, - {1604, 2073}, - {3108, 3394}, - {3233, 268}, - {4029, 7}, - {2070, 101}, - {139, 134}, - {0, 2420}, - {4412, 1333}, - {4837, 2}, - {4870, 2}, - {5021, 2}, - {3953, 2}, - {3328, 2}, - {1832, 2}, - {3940, 2}, - {2166, 2}, - {31, 2}, - {5090, 2}, - {5056, 2}, - {4834, 2}, - {4872, 2}, - {2257, 2}, - {5032, 2}, - {4415, 2}, - {4951, 2}, - {2344, 2}, - {5098, 2}, - {1829, 2}, - {4959, 2}, - {3161, 2}, - {339, 680}, - {1634, 3499}, - {3232, 694}, - {3109, 408}, - {4924, 2}, - {275, 2}, - {5063, 2}, - {4196, 2}, - {4985, 2}, - {2215, 2}, - {5108, 2}, - {209, 2}, - {4923, 2}, - {1430, 2}, - {4858, 2}, - {3439, 2}, - {5050, 2}, - {4935, 2}, - {2497, 2}, - {1258, 2}, - {1587, 2}, - {541, 2}, - {907, 2}, - {5061, 2}, - {4853, 2}, - {3732, 2}, - {1124, 2}, - {4931, 2}, - {5009, 2}, - {4723, 2}, - {2856, 2}, - {5121, 2}, - {4894, 2}, - {5111, 2}, - {4893, 2}, - {4159, 2}, - {3077, 2}, - {4904, 2}, - {5019, 2}, - {1096, 2}, - {247, 2}, - {5074, 2}, - {4831, 2}, - {1052, 2}, - {3662, 2}, - {4916, 2}, - {5086, 2}, - {4832, 2}, - {5007, 2}, - {4932, 2}, - {4933, 2}, - {1735, 2}, - {1974, 2}, - {566, 2}, - {1378, 2}, - {4838, 2}, - {5069, 2}, - {4875, 2}, - {5066, 2}, - {1340, 2}, - {678, 2}, - {4489, 2}, - {77, 2}, - {3080, 2}, - {4708, 2}, - {4300, 2}, - {537, 2}, - {267, 1271}, - {82, 1724}, - {3119, 222}, - {4188, 731}, - {1941, 432}, - {332, 30}, - {1475, 800}, - {2293, 167}, - {254, 1077}, - {1705, 105}, - {2939, 637}, - {2071, 1414}, - {1933, 2167}, - {680, 3000}, - {3110, 1162}, - {3916, 2782}, - {2679, 1960}, - {3463, 2409}, - {3787, 3630}, - {2888, 525}, - {2382, 3895}, - {2662, 1714}, - {2483, 1961}, - {4703, 2779}, - {1318, 880}, - {932, 2992}, - {2054, 2165}, - {1686, 2634}, - {912, 3828}, - {2280, 165}, - {2160, 526}, - {3017, 3064}, - {2866, 2390}, - {4352, 1228}, - {1673, 3241}, - {1129, 1497}, - {2434, 2591}, - {1309, 2142}, - {1267, 643}, - {1912, 3529}, - {2080, 3066}, - {2936, 663}, - {2802, 1}, - {4407, 1}, - {1608, 1}, - {1214, 1}, - {2354, 1}, - {1380, 1}, - {1193, 1}, - {1983, 1}, - {1115, 1}, - {3723, 1}, - {3856, 1}, - {3364, 1}, - {345, 1}, - {1886, 1}, - {827, 1}, - {588, 1}, - {1999, 1}, - {1174, 1}, - {469, 1}, - {4337, 1}, - {4464, 2247}, - {2853, 1056}, - {940, 746}, - {1328, 738}, - {162, 1411}, - {1162, 345}, - {1354, 1900}, - {579, 2528}, - {4716, 341}, - {337, 2997}, - {171, 2318}, - {2345, 472}, - {3730, 1138}, - {3260, 1713}, - {4417, 1571}, - {3922, 1747}, - {3305, 443}, - {4481, 2837}, - {834, 402}, - {3991, 3365}, - {4153, 2937}, - {3081, 279}, - {664, 2737}, - {2180, 1092}, - {1100, 3333}, - {242, 431}, - {2287, 181}, - {883, 171}, - {102, 7}, - {1249, 101}, - {1103, 551}, - {1462, 184}, - {4571, 286}, - {2988, 29}, - {4152, 482}, - {4231, 68}, - {3048, 320}, - {3660, 268}, - {2540, 134}, - {2179, 131}, - {2305, 485}, - {113, 307}, - {3541, 191}, - {163, 37}, - {2848, 544}, - {3326, 198}, - {3976, 57}, - {2764, 107}, - {1291, 44}, - {3421, 162}, - {3550, 120}, - {3767, 5}, - {2322, 181}, - {519, 171}, - {1572, 7}, - {2118, 101}, - {424, 551}, - {1506, 184}, - {3133, 286}, - {1585, 29}, - {1741, 482}, - {800, 68}, - {2998, 320}, - {4578, 268}, - {3436, 134}, - {2779, 131}, - {4517, 485}, - {3339, 307}, - {3491, 191}, - {1377, 37}, - {1529, 544}, - {1036, 198}, - {2793, 57}, - {4253, 107}, - {3189, 44}, - {3002, 162}, - {4327, 120}, - {3570, 5}, - {3413, 50}, - {1171, 3561}, - {4302, 999}, - {457, 1878}, - {4494, 354}, - {1274, 2749}, - {4867, 2}, - {0, 642}, - {0, 967}, - {0, 920}, + {0, 2106}, + {0, 451}, + {0, 2916}, + {0, 3032}, + {0, 2779}, + {504, 499}, + {4550, 1}, + {0, 2071}, + {0, 2947}, + {0, 2664}, + {0, 3112}, + {0, 3358}, + {0, 2921}, + {2560, 1453}, + {2273, 1}, + {1970, 1320}, + {3777, 1}, + {0, 740}, + {1049, 1348}, + {4076, 1}, + {5120, 68}, + {5064, 1}, + {4578, 1801}, + {123, 1}, + {503, 1909}, + {3369, 1}, + {3323, 280}, + {3145, 1}, + {0, 1946}, + {292, 1099}, + {3360, 1}, + {2563, 2614}, + {2272, 1}, + {1972, 2545}, + {3776, 1}, + {5070, 3679}, + {4972, 1}, + {1051, 2520}, + {4078, 1}, + {2582, 2452}, + {707, 1}, + {306, 1024}, + {4711, 1}, + {4456, 1195}, + {1461, 1}, + {1752, 1710}, + {1864, 1}, + {3627, 1153}, + {1763, 1}, + {0, 142}, + {4286, 2682}, + {470, 1}, {0, 2827}, - {0, 3001}, - {0, 3678}, - {0, 2371}, - {0, 3548}, - {0, 1277}, - {0, 1456}, - {0, 3904}, - {0, 3344}, - {0, 3290}, - {0, 1401}, - {0, 1608}, - {0, 314}, - {0, 3694}, - {0, 2303}, - {0, 682}, - {0, 832}, - {0, 2590}, - {0, 2970}, - {0, 2813}, - {0, 937}, - {0, 988}, - {0, 1890}, - {0, 381}, - {0, 2160}, + {0, 3253}, + {0, 2811}, + {0, 1955}, + {0, 3406}, + {0, 3528}, + {0, 3090}, {0, 3497}, - {0, 3375}, - {0, 1824}, - {0, 1407}, - {0, 1568}, - {0, 3331}, - {0, 3268}, - {0, 2556}, - {0, 3839}, - {0, 2497}, - {0, 1086}, - {0, 1164}, - {0, 2407}, - {0, 2733}, - {0, 3078}, - {0, 1106}, - {0, 753}, - {0, 2196}, - {0, 1662}, + {0, 3795}, + {0, 1495}, + {0, 1635}, + {0, 1145}, + {0, 1589}, + {0, 3931}, + {0, 1643}, + {0, 1475}, {0, 962}, - {0, 2158}, - {0, 2980}, - {0, 3116}, - {0, 356}, - {0, 3049}, - {0, 3884}, - {0, 3740}, - {0, 1743}, - {0, 3615}, - {0, 2696}, - {0, 2243}, - {0, 1335}, - {0, 2517}, - {3423, 68}, - {1364, 107}, - {0, 40}, - {0, 1911}, - {0, 3306}, - {0, 2078}, - {0, 1303}, - {0, 3482}, - {0, 655}, - {0, 3338}, - {0, 1925}, - {0, 1674}, - {0, 3157}, - {0, 3071}, - {0, 2035}, - {0, 3218}, - {0, 3832}, - {0, 1768}, - {0, 2399}, - {0, 1249}, - {0, 3831}, - {0, 3216}, - {0, 1499}, - {0, 1318}, - {0, 2338}, - {0, 985}, - {0, 67}, - {0, 2592}, - {0, 3274}, - {0, 96}, - {0, 3026}, - {0, 2344}, - {0, 396}, - {0, 1621}, - {0, 2579}, - {0, 729}, - {0, 453}, - {0, 2384}, - {0, 2650}, - {0, 1548}, - {0, 3635}, - {0, 3442}, - {0, 1232}, - {0, 2179}, - {0, 2956}, - {0, 230}, - {0, 1109}, - {0, 2712}, - {0, 555}, - {0, 3412}, - {0, 1963}, - {0, 1722}, - {0, 3185}, - {0, 3614}, - {0, 1765}, - {0, 3321}, - {0, 3915}, - {4544, 2610}, - {2643, 2085}, - {2626, 1718}, - {1384, 1655}, - {2151, 3579}, - {1002, 1569}, - {3454, 2163}, - {1035, 547}, - {4345, 3543}, - {164, 892}, - {4546, 2780}, - {2846, 1128}, - {1893, 3120}, - {4628, 1830}, - {3924, 1986}, - {2758, 3525}, - {257, 3738}, - {2790, 3720}, - {1676, 1905}, - {3571, 2112}, - {1530, 878}, - {4702, 961}, - {358, 1664}, - {2908, 3922}, - {3617, 3799}, - {4218, 1297}, - {1954, 1896}, - {4257, 2075}, - {1139, 3736}, - {4034, 3685}, - {770, 2994}, - {3539, 3871}, - {1443, 2455}, - {3933, 1046}, - {4636, 1189}, - {3184, 2447}, - {739, 2701}, - {3187, 3110}, - {2426, 1122}, - {2854, 798}, - {1963, 825}, - {2612, 596}, - {2258, 2003}, - {4411, 3385}, - {3728, 3517}, - {2981, 1997}, - {670, 1226}, - {3003, 1498}, - {1304, 3450}, - {3359, 3206}, - {1744, 2633}, - {4679, 2199}, - {208, 473}, - {2821, 2931}, - {3532, 3060}, - {4338, 265}, - {1937, 732}, - {4325, 224}, - {1260, 3096}, - {3967, 2741}, - {791, 3830}, - {3182, 2237}, - {1665, 3645}, - {3857, 1470}, - {4293, 1298}, - {3542, 3796}, - {1253, 3456}, - {3572, 3186}, - {1909, 1205}, - {2789, 1717}, - {2333, 164}, - {4301, 1111}, - {521, 1538}, - {2794, 3820}, - {3207, 1307}, - {4647, 1437}, - {2400, 1790}, - {4627, 1659}, - {730, 3829}, - {3858, 3591}, - {1176, 3095}, - {510, 2606}, - {4312, 3741}, - {2394, 1557}, - {1655, 1730}, - {253, 3707}, - {2766, 3145}, - {280, 968}, - {3965, 1156}, - {1259, 1323}, - {3808, 621}, - {660, 2825}, - {4438, 3130}, - {2253, 1819}, - {1805, 1971}, - {67, 3507}, - {2602, 3754}, - {80, 3709}, - {4118, 1928}, - {1112, 2098}, - {3672, 901}, - {1913, 1752}, - {2823, 139}, - {212, 2884}, - {714, 2752}, - {2428, 457}, - {4653, 1129}, - {2446, 734}, - {3183, 2719}, - {1474, 3068}, - {3605, 3616}, - {4149, 3659}, - {991, 2220}, - {3492, 761}, - {3070, 944}, - {3668, 2686}, - {1347, 2908}, - {3671, 2894}, - {563, 840}, - {4581, 1079}, - {79, 1945}, - {3405, 2026}, - {1295, 563}, - {4089, 3109}, - {4497, 2971}, - {3335, 146}, - {886, 829}, - {3342, 1050}, - {2277, 2905}, - {2994, 2874}, - {2121, 3803}, - {4570, 3054}, - {185, 3329}, - {3055, 2090}, - {3482, 2208}, - {4349, 3294}, - {2117, 3528}, - {4380, 3906}, - {1001, 2149}, - {4189, 1860}, - {915, 1143}, - {3794, 1673}, - {1201, 954}, - {3135, 2536}, - {2701, 2694}, - {3999, 936}, - {1573, 14}, - {4030, 656}, - {311, 2603}, - {4238, 2023}, - {533, 3480}, - {3464, 1196}, - {1389, 1565}, - {4209, 3748}, - {4619, 1791}, - {3246, 1403}, - {943, 1823}, - {3215, 2162}, - {2213, 1382}, - {3011, 3576}, - {2051, 3018}, - {4350, 1806}, - {614, 2823}, - {2531, 150}, - {3263, 144}, - {4566, 2973}, - {2181, 2593}, - {4582, 2296}, - {937, 18}, - {3669, 622}, - {1110, 1325}, - {843, 2174}, - {3994, 511}, - {1515, 2934}, - {1968, 3020}, - {1196, 223}, - {3643, 788}, - {1185, 1102}, - {4278, 3075}, - {351, 2704}, - {4634, 3864}, - {4012, 3520}, - {829, 2965}, - {3619, 412}, - {2909, 601}, - {3790, 2830}, - {1505, 2280}, - {3819, 2611}, - {382, 648}, - {4722, 87}, - {289, 1636}, - {4161, 3715}, - {981, 2291}, - {3484, 697}, - {3061, 869}, - {3657, 2612}, - {1360, 2960}, - {3683, 2834}, - {545, 924}, - {4597, 1002}, - {93, 1495}, - {3099, 757}, - {1630, 1458}, - {3824, 3653}, - {4260, 3545}, - {3575, 1517}, - {1150, 2193}, - {3616, 1775}, - {1949, 3581}, - {2678, 3843}, - {2456, 2729}, - {669, 759}, - {4427, 3180}, - {2250, 1757}, - {1800, 1130}, - {57, 2045}, - {2613, 3801}, - {1837, 722}, - {0, 327}, - {4780, 2}, - {2928, 2032}, - {1967, 3580}, - {4224, 3862}, - {4827, 2}, - {5078, 2}, - {3814, 2}, - {4966, 2}, - {3795, 2}, - {5036, 2}, - {4704, 2}, - {4839, 2}, - {4369, 2}, - {4847, 2}, - {2553, 2}, - {4860, 2}, - {4590, 2}, - {5038, 2}, - {4554, 2}, - {4971, 2}, - {3654, 2}, - {5054, 2}, - {2864, 2}, - {5094, 2}, - {4743, 2}, - {5070, 2}, - {2664, 2}, - {4937, 2}, - {2671, 2}, - {4960, 2}, - {1472, 2}, - {4882, 2}, - {1189, 2}, - {5004, 2}, - {2722, 2}, - {5052, 2}, - {3930, 2}, - {753, 2}, - {4829, 2}, - {2834, 2}, - {3853, 2}, - {4878, 2}, - {3877, 2}, - {475, 2}, - {4889, 2}, - {372, 2}, - {768, 2}, - {5017, 2}, - {1436, 2}, - {1896, 2}, - {1461, 2}, - {4770, 2}, - {3269, 2655}, - {4574, 897}, - {5048, 2}, - {4569, 2}, - {944, 2571}, - {4849, 2}, - {4879, 2}, - {3670, 2}, - {4994, 2}, - {3278, 2}, - {5008, 2}, - {4192, 2}, - {4881, 2}, - {4151, 2}, - {5124, 2}, - {4351, 2}, - {4902, 2}, - {4724, 2}, - {4908, 2}, - {2923, 2}, - {4925, 2}, - {4244, 2}, - {5126, 2}, - {4234, 2}, - {4884, 2}, - {4014, 2}, - {4989, 2}, - {2485, 2}, - {4999, 2}, - {4387, 2}, - {4945, 2}, - {564, 2}, - {4964, 2}, - {1346, 2}, - {4897, 2}, - {1878, 2}, - {5127, 2}, - {3661, 2}, - {575, 2}, - {5106, 2}, - {60, 2}, - {4010, 2}, - {5077, 2}, - {3622, 2}, - {2911, 2}, - {4871, 2}, - {1504, 2}, - {3815, 2}, - {5014, 2}, - {4729, 2}, - {282, 2}, - {4848, 2}, - {5071, 2}, - {5025, 2}, - {5010, 2}, - {1156, 2}, - {3851, 2}, - {1546, 2}, - {2925, 2}, - {2356, 2}, - {4907, 2}, - {2624, 2}, - {3345, 1114}, - {2991, 452}, - {3739, 1909}, - {1294, 1771}, - {3736, 2511}, - {648, 503}, - {4492, 269}, - {183, 1503}, - {2656, 1165}, - {2373, 726}, - {4264, 1182}, - {3829, 1579}, - {2877, 1375}, - {392, 1857}, - {2896, 1384}, - {1493, 1837}, - {3126, 2147}, - {1710, 3042}, - {2386, 2329}, - {2642, 3025}, - {406, 1504}, - {1153, 896}, - {1997, 1127}, - {4289, 782}, - {1996, 2213}, - {3639, 1744}, - {1615, 1255}, - {3154, 550}, - {2234, 703}, - {2478, 1195}, - {577, 461}, - {1026, 1762}, - {2163, 1472}, - {4403, 1488}, - {2156, 3399}, - {3497, 1990}, - {1766, 2036}, - {3294, 816}, - {371, 1826}, - {4687, 124}, - {1964, 860}, - {1513, 1032}, - {452, 390}, - {2931, 1200}, - {441, 681}, - {3842, 1220}, - {826, 1383}, - {3934, 3570}, - {3389, 3387}, - {1306, 1526}, - {4133, 241}, - {4540, 850}, - {3312, 13}, - {875, 2963}, - {3293, 2840}, - {2254, 916}, - {2951, 1014}, - {2155, 1868}, - {4212, 2079}, - {930, 640}, - {3465, 3061}, - {3040, 2929}, - {3714, 35}, - {1414, 917}, - {3709, 964}, - {606, 2968}, - {4609, 2801}, - {16, 3766}, - {2959, 3115}, - {2056, 3374}, - {4549, 2019}, - {4142, 2157}, - {2593, 3259}, - {32, 3587}, - {2563, 3874}, - {1824, 2190}, - {3366, 1812}, - {1388, 1098}, - {3171, 1742}, - {1674, 1030}, - {3904, 2470}, - {4333, 2608}, - {3526, 861}, - {1234, 125}, - {3522, 592}, - {1898, 2663}, - {2730, 2272}, - {2360, 3423}, - {4087, 1134}, - {901, 1492}, - {3402, 3800}, - {2974, 3921}, - {3724, 1471}, - {1282, 1759}, - {3748, 2203}, - {2594, 1655}, - {2270, 892}, - {4462, 263}, - {3773, 38}, - {2953, 491}, - {657, 108}, - {2952, 765}, - {1288, 116}, - {3292, 547}, - {1765, 1253}, - {3280, 3917}, - {1720, 391}, - {3674, 963}, - {4364, 1128}, - {1316, 2315}, - {3378, 3688}, - {858, 1351}, - {11, 1258}, - {1835, 3762}, - {4116, 3486}, - {1870, 3151}, - {2601, 1344}, - {2105, 1653}, - {3049, 51}, - {3395, 760}, - {1302, 1455}, - {4125, 3657}, - {4534, 3547}, - {3304, 1513}, - {880, 2191}, - {3301, 1773}, - {2259, 3583}, - {2943, 3844}, - {2159, 2726}, - {3536, 481}, - {1456, 2188}, - {3974, 3465}, - {4674, 3332}, - {3164, 1774}, - {731, 1459}, - {3152, 1516}, - {2401, 3377}, - {2809, 3233}, - {1987, 2485}, - {3751, 3516}, - {3343, 407}, - {2618, 595}, - {4093, 2835}, - {1822, 2282}, - {4085, 2614}, - {33, 645}, - {4416, 82}, - {602, 1639}, - {2377, 1556}, - {2645, 1197}, - {418, 2605}, - {1163, 2461}, - {2008, 666}, - {4283, 353}, - {1988, 372}, - {3634, 2538}, - {1625, 2336}, - {3153, 3367}, - {497, 3292}, - {4323, 2760}, - {2448, 6}, - {1698, 253}, - {233, 3046}, - {2749, 2539}, - {210, 2368}, - {3939, 359}, - {1221, 427}, - {3832, 1365}, - {1632, 123}, - {3088, 1989}, - {1167, 3244}, - {422, 3129}, - {1557, 2005}, - {3843, 1740}, - {1537, 1212}, - {2930, 3188}, - {2346, 3424}, - {2728, 2273}, - {2172, 1717}, - {3012, 2453}, - {443, 2228}, - {4240, 3649}, - {2307, 1451}, - {1564, 1287}, - {338, 3788}, - {2703, 3471}, - {368, 3176}, - {4049, 1239}, - {1200, 1697}, - {3879, 183}, - {1561, 2189}, - {3578, 483}, - {798, 2915}, - {314, 3047}, - {1628, 251}, - {4074, 756}, - {1623, 452}, - {2714, 2511}, - {1990, 1503}, - {2810, 726}, - {2945, 3042}, - {2075, 2329}, - {4524, 896}, - {4115, 782}, - {2566, 2213}, - {18, 1255}, - {2588, 550}, - {1794, 703}, - {3399, 1195}, - {1412, 461}, - {2101, 1201}, - {2937, 867}, - {27, 2430}, - {867, 2288}, - {2286, 1023}, - {4551, 585}, - {2283, 114}, - {3347, 2233}, - {1315, 2632}, - {3461, 3212}, - {1938, 1999}, - {2803, 598}, - {230, 3100}, - {727, 2964}, - {2447, 110}, - {4680, 847}, - {2430, 1022}, - {1467, 1655}, - {3584, 892}, - {697, 263}, - {4406, 38}, - {2255, 2060}, - {1813, 1836}, - {78, 3289}, - {2629, 1986}, - {66, 3903}, - {4130, 1896}, - {1099, 1790}, - {3667, 1156}, - {3116, 968}, - {1606, 1659}, - {3845, 622}, - {4281, 1189}, - {3606, 1307}, - {1165, 1908}, - {3586, 2082}, - {1961, 3726}, - {2669, 3690}, - {2429, 2986}, - {3919, 2832}, - {1211, 3114}, - {3167, 1838}, - {2743, 1993}, - {3975, 3519}, - {1709, 825}, - {3961, 3718}, - {273, 1912}, - {4331, 2103}, - {394, 891}, - {2675, 1778}, - {2352, 248}, - {4287, 2889}, - {3848, 2761}, - {2900, 491}, - {414, 108}, - {2873, 765}, - {1528, 355}, - {3082, 805}, - {1678, 3602}, - {3479, 2238}, - {1381, 3642}, - {4205, 1474}, - {4612, 1301}, - {3230, 3793}, - {963, 3454}, - {3229, 3184}, - {2206, 1208}, - {3022, 1721}, - {2062, 158}, - {3797, 3590}, - {1194, 2424}, - {3130, 858}, - {2692, 698}, - {3992, 2474}, - {1581, 3092}, - {4044, 2717}, - {297, 745}, - {4247, 1110}, - {543, 1801}, - {2905, 600}, - {1984, 2000}, - {4745, 3389}, - {4061, 3521}, - {2670, 1991}, - {333, 1221}, - {2667, 1746}, - {1590, 3452}, - {3587, 3210}, - {1468, 2627}, - {4084, 1582}, - {906, 1178}, - {3407, 2620}, - {2982, 2481}, - {3729, 689}, - {1281, 336}, - {3746, 399}, - {622, 2531}, - {4511, 2346}, - {196, 602}, - {910, 996}, - {4076, 871}, - {1286, 1097}, - {2034, 979}, - {1108, 2255}, - {3438, 2091}, - {1104, 632}, - {4467, 1074}, - {62, 839}, - {4573, 65}, - {766, 898}, - {3928, 983}, - {1437, 204}, - {1897, 61}, - {1266, 2943}, - {3568, 2658}, - {1251, 2254}, - {4334, 180}, - {261, 403}, - {4699, 1233}, - {1883, 290}, - {3284, 1863}, - {1075, 462}, - {640, 244}, - {1324, 1530}, - {3785, 1614}, - {1320, 1349}, - {2997, 849}, - {2276, 692}, - {2490, 2387}, - {4248, 2320}, - {437, 2722}, - {2713, 741}, - {3144, 1116}, - {4712, 1793}, - {2338, 925}, - {4698, 1293}, - {799, 1321}, - {3798, 1672}, - {1250, 21}, - {2788, 631}, - {2392, 1922}, - {4307, 3360}, - {3874, 3435}, - {2855, 1631}, - {540, 1330}, - {2845, 1652}, - {1471, 3475}, - {3185, 3140}, - {1580, 2597}, - {3813, 3413}, - {1181, 3072}, - {3145, 549}, - {2716, 450}, - {4037, 2742}, - {1594, 2396}, - {3995, 2512}, - {335, 501}, - {4223, 264}, - {509, 1505}, - {4591, 1078}, - {167, 1701}, - {3072, 3845}, - {3499, 3776}, - {4368, 1262}, - {2136, 1937}, - {4362, 2042}, - {1027, 3813}, - {4164, 3658}, - {896, 2914}, - {2665, 1549}, - {2372, 1091}, - {4259, 2645}, - {3823, 2557}, - {2862, 799}, - {400, 227}, - {2906, 524}, - {1498, 2489}, - {3114, 2446}, - {1711, 3381}, - {4042, 2866}, - {815, 3197}, - {3635, 1810}, - {2920, 1895}, - {3804, 3434}, - {1527, 3806}, - {3799, 3629}, - {413, 1948}, - {4696, 2016}, - {260, 836}, - {2912, 492}, - {1975, 2184}, - {4693, 3462}, - {3998, 3336}, - {2700, 1779}, - {342, 1461}, - {2715, 1518}, - {1621, 3380}, - {3632, 3229}, - {1434, 2488}, - {1962, 2984}, - {2917, 3494}, - {373, 2125}, - {850, 2039}, - {2342, 3148}, - {4706, 3680}, - {2304, 3758}, - {3117, 2111}, - {1499, 1899}, - {3540, 970}, - {2127, 2306}, - {3064, 3691}, - {200, 1356}, - {989, 1256}, - {2211, 3759}, - {4576, 3484}, - {2177, 3149}, - {3250, 1337}, - {1352, 1658}, - {3409, 45}, - {411, 1431}, - {4269, 775}, - {2385, 2245}, - {1640, 2335}, - {330, 1105}, - {2673, 517}, - {296, 225}, - {4038, 2406}, - {1135, 2462}, - {3881, 3256}, - {3349, 3207}, - {1803, 2854}, - {3745, 234}, - {4430, 80}, - {3433, 2954}, - {1113, 2637}, - {3410, 2269}, - {2102, 156}, - {2599, 597}, - {2176, 1209}, - {3678, 1711}, - {1046, 1067}, - {3273, 2513}, - {2549, 2583}, - {4187, 815}, - {1740, 169}, - {4156, 543}, - {159, 2639}, - {4348, 2229}, - {663, 3457}, - {2628, 2564}, - {2251, 3880}, - {4426, 1642}, - {3743, 1541}, - {2992, 3575}, - {694, 3272}, - {2987, 3371}, - {1327, 1601}, - {3332, 1406}, - {1727, 375}, - {3561, 2113}, - {1427, 606}, - {3949, 3030}, - {4646, 2947}, - {3206, 94}, - {752, 887}, - {3174, 1010}, - {2450, 2985}, - {2843, 2848}, - {1944, 3727}, - {3756, 441}, - {1085, 2124}, - {3299, 3488}, - {2575, 3420}, - {4122, 1859}, - {1830, 1350}, - {4128, 1616}, - {63, 3356}, - {4468, 3295}, - {571, 2529}, - {2990, 333}, - {2026, 2305}, - {4513, 717}, - {4101, 814}, - {2633, 2586}, - {76, 2999}, - {2600, 2811}, - {1871, 883}, - {3408, 972}, - {1351, 1901}, - {1660, 1490}, - {3188, 1136}, - {1239, 2674}, - {504, 2534}, - {1417, 736}, - {3862, 272}, - {1442, 459}, - {2800, 2482}, - {2409, 2393}, - {2723, 3418}, - {3200, 3774}, - {1652, 2570}, - {3870, 1155}, - {4304, 1076}, - {3565, 611}, - {1272, 2796}, - {3549, 3012}, - {1926, 981}, - {2771, 940}, - {2320, 2054}, - {3361, 3164}, - {1797, 2793}, - {3738, 312}, - {4422, 179}, - {3424, 3013}, - {1127, 1859}, - {3419, 2325}, - {2089, 60}, - {2608, 662}, - {2192, 1281}, - {3978, 237}, - {707, 1799}, - {3531, 3208}, - {2820, 3283}, - {3914, 2180}, - {1483, 1527}, - {3893, 1442}, - {529, 3221}, - {4664, 3388}, - {307, 1675}, - {2138, 2244}, - {3053, 1675}, - {188, 1430}, - {980, 1320}, - {2201, 3805}, - {4588, 1265}, - {2191, 3191}, - {3238, 1265}, - {1362, 1729}, - {3420, 148}, - {103, 1}, - {4483, 2044}, - {2029, 3401}, - {1285, 1482}, - {679, 1947}, - {3009, 1}, - {677, 1703}, - {3784, 3438}, - {890, 3174}, - {4170, 2688}, - {1369, 3347}, - {3490, 3034}, - {993, 611}, - {202, 502}, - {1754, 2770}, - {4176, 2349}, - {1717, 2547}, - {2504, 451}, - {2112, 333}, - {2973, 1594}, - {2336, 982}, - {2697, 1650}, - {456, 1}, - {1197, 3811}, - {1969, 1315}, - {4251, 1880}, - {1951, 2092}, - {3601, 3775}, - {1582, 3699}, - {3180, 2978}, - {117, 1609}, - {4613, 1154}, - {2152, 2567}, - {1387, 2490}, - {560, 712}, - {3023, 330}, - {583, 434}, - {3651, 2558}, - {965, 2363}, - {4141, 3335}, - {1748, 2792}, - {3261, 3163}, - {1047, 1855}, - {611, 1946}, - {1374, 3476}, - {3686, 3770}, - {1361, 3668}, - {3038, 1893}, - {2194, 2059}, - {2609, 943}, - {3500, 1241}, - {1367, 826}, - {4190, 2443}, - {4589, 2295}, - {3274, 1049}, - {979, 567}, - {3258, 145}, - {2235, 2216}, - {3056, 2662}, - {2018, 3189}, - {1358, 3559}, - {3504, 2356}, - {0, 2343}, + {0, 1521}, + {0, 1210}, + {0, 2583}, + {0, 2473}, + {0, 3754}, + {0, 2485}, + {0, 3870}, + {0, 1690}, + {0, 1541}, + {0, 1041}, + {0, 2576}, + {0, 3124}, + {0, 2750}, + {0, 1792}, + {0, 2422}, + {0, 1914}, + {0, 3346}, + {0, 343}, + {0, 3154}, + {0, 1896}, + {0, 2718}, + {0, 3641}, + {0, 2414}, + {0, 1430}, + {0, 2769}, {0, 1342}, - {0, 3888}, - {0, 3276}, - {0, 1580}, - {0, 2787}, - {0, 625}, - {0, 903}, - {0, 2972}, - {0, 324}, - {0, 3160}, - {0, 2135}, - {0, 1369}, - {0, 3341}, - {0, 3767}, - {0, 1167}, - {0, 2322}, + {0, 3862}, + {0, 795}, + {0, 3682}, + {0, 1303}, + {0, 2389}, + {0, 419}, + {0, 2077}, {0, 3004}, - {0, 934}, - {0, 545}, - {0, 3414}, - {0, 1959}, - {0, 3898}, - {0, 3285}, - {0, 1599}, - {0, 1216}, - {0, 2290}, - {0, 1033}, - {0, 126}, - {0, 2640}, - {0, 3260}, - {0, 135}, - {0, 3112}, - {0, 2452}, - {0, 515}, - {0, 1508}, - {2919, 2535}, - {3633, 1665}, - {0, 2580}, - {0, 33}, - {0, 728}, - {0, 3675}, - {0, 1623}, - {0, 1864}, - {0, 3918}, - {0, 1943}, - {0, 3404}, - {0, 3598}, - {0, 2187}, - {0, 54}, - {0, 3297}, - {0, 2086}, - {0, 1310}, - {0, 3489}, - {0, 975}, - {0, 3910}, - {0, 1312}, - {0, 2089}, - {0, 3689}, - {0, 3863}, - {0, 1053}, - {0, 2441}, - {0, 3105}, - {0, 780}, - {0, 2006}, - {0, 3097}, - {0, 117}, - {0, 1027}, - {0, 2851}, - {0, 3648}, - {0, 740}, - {0, 2672}, - {0, 2879}, - {0, 1071}, - {0, 669}, - {0, 1554}, - {2143, 1554}, - {0, 129}, - {0, 2615}, - {0, 48}, - {0, 603}, - {0, 2754}, - {0, 1904}, - {0, 3325}, - {0, 3536}, - {0, 977}, - {0, 1796}, - {0, 635}, - {0, 2316}, - {0, 236}, - {0, 2952}, - {0, 2266}, - {0, 599}, - {0, 1820}, - {0, 2816}, - {0, 379}, - {0, 674}, - {0, 3019}, - {0, 1562}, - {0, 2598}, - {0, 1645}, - {0, 673}, - {0, 357}, - {0, 376}, - {0, 2328}, - {0, 3372}, - {0, 2673}, - {0, 3791}, - {0, 1491}, - {0, 3647}, + {0, 1650}, + {0, 3052}, + {0, 92}, + {0, 3507}, + {0, 377}, + {0, 3083}, + {0, 1966}, + {0, 3051}, + {0, 3530}, + {0, 627}, + {0, 3808}, + {0, 460}, + {0, 2813}, + {0, 2017}, + {2202, 2528}, + {4809, 1}, + {4796, 1}, + {4792, 1}, + {4808, 1}, + {4807, 1}, + {4794, 1}, + {4824, 1}, + {4823, 1}, + {4814, 1}, + {4782, 1}, + {4789, 1}, + {4804, 1}, + {4786, 1}, + {4790, 1}, + {4802, 1}, + {4819, 1}, + {4800, 1}, + {4821, 1}, + {5004, 1}, + {4899, 1}, + {4854, 1}, + {4875, 1}, + {5125, 1}, + {5124, 1}, + {5062, 1}, + {4903, 1}, + {5100, 1}, + {5046, 1}, + {4943, 1}, + {5098, 1}, + {4842, 1}, + {4892, 1}, + {4932, 1}, + {4857, 1}, + {4879, 1}, + {5073, 1}, + {5109, 1}, + {4890, 1}, + {4891, 1}, + {4835, 1}, + {4827, 1}, + {4788, 1}, + {4785, 1}, + {4806, 1}, + {1202, 1}, + {2942, 1}, + {3442, 1}, + {1410, 1}, + {1778, 1}, + {4939, 1}, + {4936, 1}, + {5034, 1}, + {4801, 1}, + {4778, 1}, + {4813, 1}, + {4815, 1}, + {4818, 1}, + {4787, 1}, + {4273, 1544}, + {4610, 2953}, + {1651, 275}, + {1615, 3410}, + {1387, 1}, + {5106, 1}, + {895, 1}, + {5105, 1}, + {2505, 1}, + {5111, 1}, + {4803, 1}, + {4960, 1}, + {4981, 1}, + {4872, 1}, + {4923, 1}, + {4908, 1}, + {4959, 1}, + {4853, 1}, + {2284, 1}, + {4885, 1}, + {4980, 1}, + {4925, 1}, + {3386, 1}, + {4831, 1}, + {576, 1}, + {4766, 1}, + {4777, 1}, + {4564, 1522}, + {107, 3023}, + {526, 1608}, + {3396, 3616}, + {3340, 1073}, + {3180, 3794}, + {1443, 1645}, + {3330, 2498}, + {5016, 1}, + {4900, 1}, + {5045, 1}, + {4783, 1}, + {4759, 1}, + {5013, 1}, + {2776, 1}, + {2194, 1}, + {2459, 538}, + {4121, 2768}, + {3908, 2956}, + {5114, 1}, + {5116, 1}, + {5061, 1}, + {5052, 1}, + {4858, 1}, + {4310, 2129}, + {894, 2902}, + {4911, 1}, + {784, 2819}, + {2512, 976}, + {782, 1571}, + {4448, 2618}, + {4913, 1}, + {4965, 1}, + {5024, 1}, + {1586, 1}, + {2867, 1}, + {3502, 1}, + {3682, 1052}, + {971, 3860}, + {5055, 1}, + {266, 1}, + {4868, 1}, + {4910, 1}, + {2620, 1}, + {2221, 1}, + {903, 1}, + {5051, 1}, + {4399, 1}, + {4825, 1}, + {4769, 1}, + {5089, 1}, + {1476, 1}, + {4998, 1}, + {2209, 1}, + {1390, 1}, + {3081, 1}, + {145, 1}, + {5094, 1}, + {4975, 1}, + {1933, 1}, + {3347, 1}, + {3586, 1}, + {4763, 1}, + {4893, 1}, + {1805, 1}, + {3383, 1}, + {1797, 1}, + {4679, 1}, + {4594, 205}, + {4820, 1}, + {4816, 1}, + {2485, 51}, + {4795, 1}, + {4781, 1}, + {1423, 576}, + {4267, 2740}, + {3373, 3895}, + {4793, 1}, + {5041, 1}, + {4876, 1}, + {3024, 1718}, + {4828, 1}, + {1606, 2699}, + {4919, 1}, + {2727, 3141}, + {4889, 1}, + {4145, 1775}, + {4886, 1}, + {4120, 3858}, + {4362, 1772}, + {4822, 1}, + {4784, 1}, + {3067, 2649}, + {4811, 1}, + {2718, 2397}, + {2103, 708}, + {2516, 3688}, + {4127, 777}, + {2379, 1287}, + {353, 1318}, + {5096, 1}, + {4954, 1}, + {2376, 3190}, + {4841, 1}, + {1286, 1239}, + {4861, 1}, + {2094, 1177}, + {4966, 1}, + {1193, 2596}, + {4873, 1}, + {3572, 3893}, + {5044, 1}, + {4940, 1}, + {2192, 2416}, + {4922, 1}, + {413, 1}, + {0, 2793}, + {0, 1773}, + {0, 3271}, + {0, 121}, + {0, 3306}, + {0, 2824}, + {0, 1872}, + {0, 2233}, + {0, 1726}, + {0, 3540}, + {0, 49}, + {0, 3304}, + {0, 1743}, + {0, 2856}, + {0, 1644}, + {0, 1196}, + {0, 3928}, + {0, 459}, + {0, 3807}, + {0, 1398}, + {0, 2507}, + {0, 1591}, + {0, 3836}, + {0, 1082}, + {0, 921}, + {0, 1413}, + {0, 2391}, + {0, 1711}, + {0, 2215}, + {0, 1208}, + {0, 3559}, + {0, 891}, + {0, 2265}, + {0, 1438}, + {0, 2814}, + {0, 3321}, + {0, 344}, + {0, 3596}, + {0, 3050}, + {0, 3192}, + {3482, 551}, + {0, 2748}, + {0, 1457}, + {0, 2874}, + {0, 392}, + {0, 3326}, + {0, 95}, + {4907, 1}, + {3968, 1}, + {5112, 1}, + {2451, 1}, + {5037, 1}, + {4534, 1}, + {4956, 1}, + {406, 1}, + {4896, 1}, + {3235, 1}, + {5060, 1}, + {947, 1}, + {4988, 1}, + {4481, 1}, + {4948, 1}, + {1070, 1}, + {4921, 1}, + {4880, 1}, + {2950, 1}, + {2821, 1}, + {4930, 1}, + {2916, 1}, + {0, 2058}, + {0, 1300}, + {0, 1595}, + {0, 896}, + {0, 3203}, + {0, 772}, + {0, 2568}, + {0, 1346}, + {0, 2383}, + {0, 742}, + {0, 3677}, + {0, 1445}, + {0, 809}, + {0, 3649}, + {0, 90}, + {0, 551}, + {0, 1654}, + {0, 2251}, + {0, 1450}, + {0, 3569}, + {0, 904}, + {0, 2066}, + {0, 408}, + {0, 3354}, + {0, 1109}, {0, 3455}, - {0, 1261}, - {0, 486}, - {0, 3459}, - {0, 1783}, - {0, 1519}, - {0, 3227}, - {0, 1657}, - {0, 2439}, - {0, 3588}, - {0, 1405}, - {0, 3378}, - {0, 3254}, - {0, 1304}, - {0, 47}, - {0, 2585}, - {0, 2767}, - {0, 1919}, - {3270, 7}, - {987, 184}, - {3266, 191}, - {0, 3897}, - {4667, 1693}, - {225, 571}, - {898, 728}, - {4183, 2381}, - {1256, 2980}, - {3866, 2323}, - {3363, 3573}, - {0, 1553}, - {0, 366}, - {0, 2100}, - {0, 619}, - {0, 3021}, - {0, 2938}, - {0, 77}, - {0, 912}, - {0, 991}, - {0, 3010}, - {0, 2820}, - {0, 3744}, - {0, 3652}, - {0, 2221}, + {0, 1798}, + {0, 3012}, + {0, 2021}, + {0, 3484}, + {0, 447}, + {0, 1707}, + {0, 1123}, + {0, 3880}, + {0, 374}, + {0, 3757}, + {0, 1455}, + {0, 2451}, + {0, 1658}, + {0, 3790}, + {0, 1157}, + {0, 2743}, + {0, 3109}, + {0, 8}, + {0, 3684}, + {0, 273}, + {0, 2766}, + {0, 217}, + {0, 3206}, + {962, 196}, + {3695, 1923}, + {4754, 158}, + {2239, 57}, + {2528, 154}, + {2806, 1164}, + {1105, 169}, + {954, 119}, + {706, 167}, + {3688, 4}, + {964, 163}, + {2122, 115}, + {3816, 55}, + {4283, 22}, + {176, 157}, + {3101, 106}, + {3629, 160}, + {3468, 54}, + {1771, 139}, + {3624, 213}, + {980, 150}, + {3117, 2043}, + {1672, 1778}, + {1358, 2177}, + {4331, 158}, + {4642, 57}, + {4542, 154}, + {400, 278}, + {4633, 1651}, + {893, 873}, + {380, 169}, + {3889, 163}, + {4168, 55}, + {2389, 1181}, + {2185, 930}, + {2751, 2220}, + {2076, 1465}, + {1944, 160}, + {3710, 139}, + {4469, 213}, + {674, 2722}, + {322, 1281}, + {3277, 76}, + {3446, 682}, + {3641, 341}, + {1893, 583}, + {3438, 27}, + {4539, 697}, + {1625, 258}, + {2465, 167}, + {2734, 54}, + {3031, 213}, + {1183, 76}, + {855, 341}, + {985, 583}, + {3903, 351}, + {864, 697}, + {3156, 258}, + {3647, 1762}, + {525, 1042}, + {1748, 48}, + {4565, 3692}, + {4069, 888}, + {1225, 187}, + {3014, 2562}, + {2580, 1333}, + {2683, 866}, + {2152, 752}, + {2546, 788}, + {376, 311}, + {3417, 1827}, + {3033, 2790}, + {2203, 1286}, + {2466, 2727}, + {4123, 597}, + {3748, 3149}, + {3912, 329}, + {1003, 2691}, + {3721, 1931}, + {2326, 1249}, + {4027, 743}, + {4678, 3598}, + {261, 340}, + {527, 2639}, + {3616, 1476}, + {3085, 1725}, + {3258, 1258}, + {1468, 3708}, + {3089, 677}, + {3199, 2214}, + {118, 67}, + {887, 744}, + {4061, 3319}, + {3847, 915}, + {2190, 94}, + {4817, 1}, + {4810, 1}, + {2784, 3594}, + {1101, 1}, + {672, 1241}, + {4458, 1}, + {4718, 1404}, + {1852, 1}, + {1416, 864}, + {1617, 1}, + {3299, 1362}, + {1411, 1}, + {4030, 1728}, + {2327, 1}, + {1798, 3193}, + {3224, 1}, + {3574, 3308}, + {651, 1}, + {78, 2880}, + {216, 1}, + {4401, 3291}, + {70, 1}, + {3782, 1902}, + {2026, 1}, + {1478, 3246}, + {3521, 1}, + {3255, 3138}, + {285, 1}, + {425, 2723}, + {529, 1}, + {4668, 3116}, + {434, 1}, + {472, 2849}, + {3493, 1}, + {2958, 197}, + {2120, 1}, + {2396, 97}, + {4180, 1}, + {3675, 1745}, + {3844, 1}, + {914, 31}, + {3652, 1}, + {2646, 1831}, + {814, 1}, + {219, 3298}, + {4655, 1}, + {4391, 3204}, + {1569, 1}, + {1667, 2784}, + {1796, 1}, + {3536, 3168}, + {1687, 1}, + {3944, 1525}, + {2266, 1}, + {1926, 3839}, + {3339, 1}, + {3579, 3894}, + {564, 1}, + {106, 2631}, + {325, 1}, + {4433, 3925}, + {120, 1}, + {3198, 2120}, + {119, 1}, + {885, 3535}, + {4062, 1}, + {3846, 3396}, + {2193, 1}, + {2291, 2969}, + {2394, 1}, + {2973, 3424}, + {2263, 1}, + {3943, 2231}, + {2264, 1}, + {1924, 765}, + {3341, 1}, + {3578, 905}, + {566, 1}, + {110, 1463}, + {328, 1}, + {4432, 882}, + {117, 1}, + {1906, 825}, + {4715, 1}, + {3929, 2405}, + {728, 1}, + {1098, 2327}, + {2878, 1}, + {2702, 3617}, + {2537, 1}, + {2012, 2300}, + {2696, 1}, + {3496, 3054}, + {456, 1}, + {1192, 531}, + {3815, 1}, + {4109, 418}, + {2453, 1}, + {1996, 2007}, + {2091, 1}, + {2699, 359}, + {2005, 1}, + {766, 3240}, + {2540, 1}, + {3291, 1883}, + {1867, 1}, + {1621, 1823}, + {4375, 1}, + {4606, 162}, + {4713, 1}, + {686, 1783}, + {4600, 1}, + {2030, 1444}, + {3784, 1}, + {4393, 3646}, + {573, 1}, + {225, 3581}, + {3355, 1}, + {3381, 2258}, + {3571, 1}, + {1808, 3570}, + {3372, 1}, + {2332, 3384}, + {4017, 1}, + {4637, 2055}, + {198, 1}, + {601, 2171}, + {3611, 1}, + {3127, 579}, + {3252, 1}, + {1536, 2205}, + {3114, 1}, + {3159, 401}, + {143, 1}, + {976, 2988}, + {4126, 1}, + {3804, 3060}, + {2208, 1}, + {2222, 3515}, + {2421, 1}, + {2917, 3081}, + {2248, 1}, + {1153, 3430}, + {2862, 1}, + {3507, 1982}, + {1466, 1}, + {1845, 2115}, + {4710, 1}, + {4262, 515}, + {4373, 1}, + {278, 2139}, + {4219, 1}, + {1942, 1}, + {3707, 1}, + {4465, 1}, + {676, 1}, + {321, 1282}, + {3280, 2007}, + {0, 1253}, + {511, 3188}, + {3440, 1}, + {2951, 1717}, + {2114, 1}, + {2427, 1877}, + {4141, 1}, + {3678, 245}, + {3799, 1}, + {943, 1840}, + {3708, 1}, + {1945, 1215}, + {3709, 1}, + {4468, 2588}, + {675, 1}, + {323, 2466}, + {3278, 1}, + {3445, 3746}, + {3640, 1}, + {1892, 2495}, + {3439, 1}, + {4487, 2538}, + {1565, 1}, + {1962, 997}, + {2788, 1}, + {2548, 1077}, + {804, 1}, + {1215, 1600}, + {1032, 1}, + {3960, 1129}, + {1227, 1}, + {136, 91}, + {3181, 1}, + {2665, 2759}, + {2384, 1}, + {2146, 2852}, + {3882, 1}, + {3981, 3296}, + {4097, 1}, + {1222, 2877}, + {3969, 1}, + {2829, 2050}, + {1034, 1}, + {644, 3376}, + {4446, 1}, + {4732, 3441}, + {1794, 1}, + {1431, 3029}, + {1560, 1}, + {3334, 3459}, + {1439, 1}, + {4016, 3779}, + {2331, 1}, + {1847, 1581}, + {3270, 1}, + {3511, 1652}, + {666, 1}, + {12, 1173}, + {243, 1}, + {4356, 1681}, + {21, 1}, + {609, 141}, + {3633, 1}, + {2815, 2679}, + {2003, 1}, + {2251, 2832}, + {4056, 1}, + {3810, 3262}, + {3716, 1}, + {742, 2800}, + {3797, 1}, + {3905, 3177}, + {2179, 1}, + {1360, 1734}, + {3395, 1}, + {3121, 1854}, + {112, 1}, + {559, 264}, + {384, 1}, + {4525, 1836}, + {593, 1}, + {1876, 58}, + {4738, 1}, + {3951, 2742}, + {768, 1}, + {1054, 2878}, + {2900, 1}, + {2690, 3310}, + {2578, 1}, + {1982, 2853}, + {2652, 1}, + {0, 1135}, + {0, 2646}, + {0, 2529}, + {4170, 1}, + {4021, 1}, + {1167, 1}, + {4167, 1}, + {2460, 1}, + {4164, 1}, + {4543, 1}, + {86, 1}, + {388, 3070}, + {3488, 66}, + {3216, 3492}, + {3120, 353}, + {1324, 3106}, + {3244, 1947}, + {236, 3657}, + {3243, 2393}, + {2602, 1}, + {2308, 1}, + {2081, 1}, + {3676, 1}, + {4174, 1}, + {4022, 1}, + {2616, 1227}, + {840, 745}, + {260, 3604}, + {4681, 325}, + {4336, 3717}, + {1600, 1506}, + {3515, 1}, + {1652, 1}, + {2169, 1}, + {3920, 1}, + {4232, 1}, + {421, 1}, + {30, 1}, + {3211, 1}, + {3524, 549}, + {3426, 3418}, + {1646, 2117}, + {3517, 2978}, + {4652, 2684}, + {1832, 3194}, + {2360, 146}, + {2640, 3715}, + {2847, 1}, + {1073, 1}, + {986, 1}, + {839, 1}, + {3731, 1}, + {996, 1}, + {3637, 1}, + {615, 1}, + {1058, 2238}, + {3667, 1867}, + {3955, 2381}, + {2298, 1038}, + {2129, 3681}, + {1947, 792}, + {2569, 2346}, + {2141, 1354}, + {3720, 1}, + {2075, 1}, + {1519, 1}, + {3560, 1}, + {3248, 1}, + {362, 1}, + {4647, 2434}, + {377, 1242}, + {509, 3585}, + {3437, 2313}, + {2948, 1335}, + {2115, 2850}, + {3679, 1}, + {3800, 1}, + {940, 1}, + {3706, 1}, + {2599, 1}, + {865, 1}, + {244, 1}, + {4662, 1}, + {1613, 1070}, + {1848, 764}, + {1627, 1328}, + {2247, 2111}, + {1884, 1}, + {3292, 1}, + {3646, 1}, + {556, 1}, + {156, 1}, + {318, 1}, + {4480, 1}, + {144, 1}, + {3157, 1007}, + {141, 1501}, + {974, 2461}, + {4129, 2135}, + {3803, 2591}, + {2210, 754}, + {2223, 3889}, + {2423, 1067}, + {2915, 1}, + {2246, 1305}, + {3945, 1}, + {2245, 1569}, + {1883, 1}, + {3293, 2212}, + {3644, 1}, + {558, 137}, + {158, 1}, + {320, 1944}, + {4478, 1}, + {142, 1919}, + {1901, 1}, + {4731, 71}, + {1035, 1572}, + {2882, 2052}, + {2668, 1662}, + {2544, 1767}, + {1949, 1178}, + {2684, 111}, + {3433, 1677}, + {524, 2471}, + {1208, 1572}, + {3834, 2052}, + {4093, 1662}, + {2493, 1767}, + {1969, 1178}, + {2149, 111}, + {2677, 1677}, + {1953, 2471}, + {745, 855}, + {2550, 3572}, + {3350, 96}, + {1930, 1803}, + {1564, 823}, + {4390, 1439}, + {4553, 1374}, + {4727, 398}, + {631, 855}, + {4566, 3572}, + {2077, 96}, + {3722, 1803}, + {4371, 823}, + {548, 1439}, + {245, 1374}, + {3284, 398}, + {3408, 2027}, + {3506, 9}, + {1839, 445}, + {3418, 1715}, + {1541, 2078}, + {4338, 3011}, + {3746, 555}, + {1124, 2196}, + {845, 2027}, + {2508, 9}, + {3034, 445}, + {2843, 1715}, + {2350, 2078}, + {3046, 3011}, + {2930, 555}, + {1219, 2196}, + {499, 1}, + {4316, 1}, + {4571, 2952}, + {1678, 276}, + {1592, 3409}, + {3185, 1}, + {1552, 2113}, + {257, 3536}, + {3226, 3031}, + {2617, 2123}, + {2324, 1305}, + {2066, 276}, + {3661, 3318}, + {4151, 369}, + {4007, 3318}, + {1147, 1998}, + {4188, 3061}, + {1898, 3612}, + {4722, 2227}, + {3978, 1237}, + {1037, 1}, + {2884, 3801}, + {2666, 834}, + {2559, 1569}, + {1957, 1384}, + {2672, 2212}, + {952, 2227}, + {2675, 2789}, + {3142, 1826}, + {1696, 2280}, + {1442, 1}, + {4206, 1}, + {4751, 1}, + {4572, 3315}, + {1900, 1}, + {4724, 1}, + {3979, 2483}, + {793, 2104}, + {1038, 2570}, + {2883, 137}, + {2556, 1010}, + {1958, 2602}, + {2673, 1536}, + {3957, 1}, + {2255, 1}, + {1873, 1}, + {3288, 3331}, + {3636, 1}, + {552, 1}, + {164, 1}, + {314, 1}, + {4476, 982}, + {153, 3911}, + {1234, 257}, + {2920, 1919}, + {3451, 2866}, + {1413, 1327}, + {1741, 2246}, + {4497, 560}, + {138, 2778}, + {4484, 1833}, + {3317, 2180}, + {727, 1}, + {3930, 948}, + {3711, 3340}, + {2049, 1944}, + {2435, 2909}, + {2257, 71}, + {2824, 1833}, + {2415, 608}, + {4335, 3873}, + {2063, 291}, + {2893, 291}, + {396, 291}, + {3755, 1524}, + {215, 3558}, + {2175, 2}, + {2607, 2}, + {166, 2}, + {336, 1844}, + {649, 2364}, + {3170, 3642}, + {3356, 719}, + {2689, 2090}, + {2132, 183}, + {4596, 1124}, + {4292, 3464}, + {1385, 1791}, + {3464, 2260}, + {3165, 360}, + {77, 167}, + {4591, 265}, + {607, 350}, + {592, 1141}, + {3503, 387}, + {2869, 529}, + {2041, 1546}, + {2340, 567}, + {3924, 1248}, + {3896, 454}, + {3724, 109}, + {861, 1821}, + {3910, 22}, + {2653, 360}, + {968, 206}, + {147, 89}, + {4601, 21}, + {4302, 265}, + {1392, 350}, + {1889, 1141}, + {1781, 387}, + {3455, 529}, + {1869, 1546}, + {4161, 567}, + {2463, 1248}, + {1631, 454}, + {3074, 109}, + {3420, 1821}, + {272, 196}, + {25, 154}, + {4264, 157}, + {238, 212}, + {3239, 278}, + {241, 119}, + {870, 163}, + {4047, 115}, + {3727, 55}, + {1992, 22}, + {2454, 160}, + {2333, 80}, + {2858, 139}, + {1648, 1708}, + {749, 564}, + {3791, 3395}, + {427, 48}, + {3792, 806}, + {479, 93}, + {131, 3584}, + {3069, 1651}, + {3431, 1451}, + {89, 169}, + {765, 119}, + {113, 119}, + {2968, 2056}, + {187, 167}, + {751, 115}, + {268, 115}, + {76, 22}, + {313, 1965}, + {379, 160}, + {42, 397}, + {394, 54}, + {2919, 116}, + {1233, 1729}, + {502, 2697}, + {983, 67}, + {1585, 63}, + {4158, 163}, + {2473, 2563}, + {729, 158}, + {486, 154}, + {270, 154}, + {18, 187}, + {0, 884}, + {253, 55}, + {599, 157}, + {4237, 557}, + {3915, 3472}, + {1314, 956}, + {987, 1704}, + {46, 167}, + {3038, 2156}, + {175, 15}, + {1110, 583}, + {1276, 583}, + {1068, 15}, + {628, 571}, + {346, 57}, + {830, 57}, + {258, 4}, + {1252, 3428}, + {4013, 528}, + {1768, 1255}, + {4563, 736}, + {4098, 3601}, + {916, 332}, + {1214, 3730}, + {2997, 1481}, + {2552, 2426}, + {2659, 1261}, + {2121, 3705}, + {2588, 684}, + {710, 1841}, + {2586, 289}, + {3327, 3283}, + {1918, 798}, + {1590, 167}, + {4416, 1701}, + {4570, 2674}, + {4750, 1862}, + {639, 76}, + {4560, 240}, + {1766, 2497}, + {4561, 1102}, + {4096, 1054}, + {919, 212}, + {1212, 1170}, + {3001, 2261}, + {2554, 115}, + {2663, 48}, + {2119, 57}, + {2585, 55}, + {4071, 167}, + {2431, 1701}, + {1745, 2674}, + {3190, 1862}, + {3454, 76}, + {437, 240}, + {312, 2497}, + {163, 1102}, + {4301, 1054}, + {286, 212}, + {1050, 1170}, + {2810, 2261}, + {3643, 115}, + {1624, 48}, + {1878, 57}, + {4675, 55}, + {0, 3292}, + {2212, 3276}, + {4978, 1}, + {5018, 1}, + {4897, 1}, + {210, 1}, + {4648, 1}, + {1494, 1}, + {4477, 1}, + {4700, 1}, + {1834, 1}, + {4839, 1}, + {4989, 1}, + {5011, 1}, + {5097, 1}, + {201, 1}, + {5053, 1}, + {2914, 1}, + {4997, 1}, + {1092, 1}, + {4878, 1}, + {1703, 1}, + {4877, 1}, + {4113, 1}, + {2116, 2296}, + {2504, 1400}, + {2502, 2980}, + {3303, 2041}, + {4928, 1}, + {2393, 1}, + {4867, 1}, + {3842, 1}, + {5115, 1}, + {2746, 1}, + {4914, 1}, + {2956, 1}, + {4971, 1}, + {2595, 1}, + {4898, 1}, + {247, 1}, + {5082, 1}, + {5035, 1}, + {920, 1}, + {1213, 1}, + {3002, 1}, + {2553, 1}, + {2662, 1}, + {5095, 1}, + {4976, 1}, + {3735, 1}, + {2068, 1}, + {5092, 1}, + {5091, 1}, + {3232, 1}, + {341, 1}, + {4938, 1}, + {5113, 1}, + {5074, 1}, + {4905, 1}, + {629, 1}, + {4431, 1}, + {5030, 1}, + {5077, 1}, + {1440, 1}, + {1587, 1}, + {5022, 1}, + {4871, 1}, + {4291, 1}, + {1434, 1}, + {4937, 1}, + {4953, 1}, + {5059, 1}, + {5110, 1}, + {5108, 1}, + {5039, 1}, + {735, 1}, + {975, 1}, + {3814, 1}, + {717, 1}, + {5021, 1}, + {5026, 1}, + {4979, 1}, + {5090, 1}, + {2832, 1}, + {2411, 1}, + {4626, 1}, + {1858, 1}, + {3736, 1}, + {992, 1}, + {2767, 1}, + {994, 1}, + {2204, 952}, + {1384, 641}, + {2996, 206}, + {2181, 89}, + {2492, 21}, + {4094, 265}, + {3774, 350}, + {3885, 1141}, + {1019, 387}, + {3770, 529}, + {2535, 1546}, + {769, 3577}, + {350, 702}, + {4739, 3235}, + {4426, 804}, + {1502, 2548}, + {1709, 1390}, + {1908, 2309}, + {3588, 832}, + {1721, 3613}, + {4048, 3064}, + {2305, 3452}, + {1822, 540}, + {3245, 3769}, + {3547, 406}, + {626, 2848}, + {61, 2002}, + {196, 3093}, + {4385, 362}, + {85, 3538}, + {3077, 2499}, + {87, 3760}, + {1016, 953}, + {4165, 3474}, + {3884, 1126}, + {2144, 2298}, + {2316, 1642}, + {2494, 2546}, + {3011, 1079}, + {2310, 3837}, + {4049, 1937}, + {2307, 269}, + {1824, 2}, + {3242, 2}, + {3548, 2}, + {621, 2}, + {57, 2}, + {193, 2}, + {4387, 2}, + {88, 2}, + {1800, 2}, + {4680, 2}, + {4029, 2}, + {841, 2}, + {1126, 2}, + {2822, 2}, + {2735, 2}, + {2644, 2}, + {2050, 2}, + {2723, 2}, + {3376, 2}, + {420, 2}, + {1318, 3085}, + {3919, 593}, + {4142, 703}, + {2425, 1288}, + {2022, 1415}, + {2207, 1502}, + {2728, 994}, + {2047, 365}, + {815, 781}, + {2641, 1262}, + {3254, 2250}, + {1831, 827}, + {1475, 2369}, + {4473, 29}, + {4520, 3501}, + {4683, 117}, + {554, 2387}, + {4500, 1310}, + {1999, 1702}, + {3669, 536}, + {4422, 159}, + {616, 3062}, + {342, 305}, + {3231, 1945}, + {3499, 1889}, + {3601, 1873}, + {1936, 196}, + {3478, 158}, + {932, 48}, + {4051, 57}, + {4674, 154}, + {255, 187}, + {555, 169}, + {3642, 119}, + {3086, 167}, + {3276, 4}, + {1485, 163}, + {3079, 115}, + {3204, 55}, + {105, 22}, + {930, 157}, + {4102, 160}, + {3838, 397}, + {2187, 54}, + {2258, 80}, + {2387, 139}, + {2961, 213}, + {2287, 76}, + {1114, 150}, + {2896, 212}, + {3541, 19}, + {1510, 67}, + {1816, 196}, + {4746, 158}, + {4214, 48}, + {4412, 57}, + {232, 154}, + {4198, 187}, + {1983, 169}, + {3672, 119}, + {4438, 167}, + {633, 4}, + {364, 163}, + {3253, 115}, + {3491, 55}, + {3612, 22}, + {1931, 157}, + {3483, 160}, + {477, 397}, + {3484, 54}, + {2981, 80}, + {2151, 139}, + {2392, 213}, + {4169, 76}, + {3648, 150}, + {3835, 212}, + {892, 19}, + {3673, 67}, + {1985, 360}, + {3112, 1151}, + {4677, 326}, + {1810, 1292}, + {3531, 1224}, + {1354, 1671}, + {5063, 1}, + {0, 381}, + {0, 1564}, + {0, 3117}, + {0, 2888}, + {0, 1570}, + {0, 575}, + {0, 511}, + {0, 1334}, + {0, 2236}, + {0, 1679}, + {0, 3509}, + {0, 2581}, + {0, 293}, + {0, 1756}, + {0, 2594}, + {0, 3435}, + {0, 2999}, + {0, 3660}, + {0, 916}, + {0, 3764}, + {0, 1992}, + {0, 1035}, + {0, 2721}, + {0, 3284}, + {0, 1019}, + {0, 2093}, + {0, 2092}, + {0, 771}, + {0, 3553}, + {0, 1191}, + {0, 3069}, + {0, 3871}, + {0, 1899}, + {0, 101}, + {0, 3879}, + {0, 3001}, + {0, 667}, + {0, 2198}, + {0, 3008}, + {0, 1810}, + {0, 3593}, + {0, 2720}, + {0, 1037}, + {0, 1634}, + {0, 2732}, + {0, 3722}, + {0, 1297}, + {0, 546}, + {0, 3724}, + {0, 773}, + {0, 2796}, + {0, 862}, + {0, 2523}, + {0, 659}, + {0, 2165}, + {0, 1778}, + {0, 3149}, + {0, 2043}, + {0, 1042}, + {0, 2677}, + {0, 3373}, + {2206, 4}, + {3878, 76}, + {0, 1273}, + {0, 596}, + {0, 3487}, + {0, 2336}, + {0, 1560}, + {0, 3111}, + {0, 220}, + {0, 2460}, + {0, 3289}, + {0, 605}, + {0, 2382}, + {0, 1901}, + {0, 3815}, + {0, 2808}, + {0, 2088}, + {0, 3714}, + {0, 2843}, + {0, 1039}, + {0, 1849}, + {0, 3009}, + {0, 902}, + {0, 1353}, + {0, 3521}, + {0, 2264}, + {0, 1533}, + {0, 3195}, + {0, 2776}, + {0, 1190}, + {0, 1739}, + {0, 2934}, {0, 758}, - {0, 939}, - {0, 2691}, - {0, 2912}, - {0, 2896}, - {0, 837}, - {0, 1075}, - {0, 1949}, - {0, 1354}, - {0, 718}, - {0, 2317}, - {0, 2391}, - {0, 1148}, - {0, 446}, + {0, 507}, + {0, 2242}, + {0, 3503}, {0, 295}, - {0, 2345}, - {0, 2532}, - {0, 3296}, - {0, 2123}, - {0, 440}, - {0, 2990}, - {0, 3067}, - {0, 293}, - {0, 721}, - {0, 1145}, - {0, 3028}, + {0, 2587}, + {0, 3199}, + {0, 1694}, + {0, 84}, + {0, 3365}, + {0, 1309}, + {0, 233}, + {0, 2488}, + {0, 3322}, + {0, 625}, + {0, 2352}, {0, 2756}, - {0, 3907}, - {0, 2935}, - {0, 3443}, - {0, 2173}, - {0, 2099}, - {0, 3196}, + {0, 1163}, + {0, 1727}, + {0, 2905}, + {0, 785}, + {0, 1855}, + {0, 2757}, + {0, 2846}, {0, 3636}, - {0, 3809}, - {0, 2050}, - {0, 1966}, - {0, 1055}, - {0, 1112}, - {0, 1535}, - {0, 3824}, - {0, 3892}, - {0, 1434}, - {0, 1785}, - {0, 2176}, - {0, 3833}, - {0, 3592}, - {0, 3093}, - {0, 2747}, - {0, 3214}, - {0, 1953}, - {0, 1861}, - {0, 3419}, - {0, 3835}, - {0, 3619}, - {0, 1795}, - {0, 2207}, - {0, 737}, - {0, 1884}, - {0, 71}, - {0, 2788}, - {0, 2875}, - {0, 624}, - {0, 984}, - {0, 902}, - {0, 2800}, - {4757, 2}, - {4172, 1542}, - {1716, 2170}, - {4179, 1806}, - {116, 3608}, - {4373, 3860}, - {682, 2708}, - {3322, 3080}, - {1825, 2045}, - {4418, 2129}, - {3417, 622}, - {1088, 3605}, - {3426, 3842}, - {146, 1914}, - {2621, 1780}, - {2198, 1123}, - {4359, 2101}, - {605, 617}, - {2521, 3035}, - {3254, 2948}, - {2693, 89}, - {2190, 875}, - {4594, 1003}, - {923, 2993}, - {3684, 2833}, - {1125, 3737}, - {3996, 2559}, - {841, 3882}, - {3625, 1648}, - {2914, 1552}, - {3796, 3568}, - {1501, 3263}, - {3810, 3361}, - {403, 1610}, - {4709, 1399}, - {279, 388}, - {3240, 3773}, - {1761, 2569}, - {3718, 1157}, - {4404, 1073}, - {3476, 928}, - {1030, 115}, - {3448, 3014}, - {2140, 980}, - {2471, 941}, - {2273, 2061}, - {4564, 310}, - {197, 1856}, - {3065, 3165}, - {3486, 3230}, - {4355, 2128}, - {2113, 1597}, - {4372, 1050}, - {1018, 3267}, - {3644, 2107}, - {904, 2362}, - {383, 2403}, - {4286, 3611}, - {2353, 1247}, - {1614, 1015}, - {301, 3834}, - {2650, 3417}, - {323, 3219}, - {4015, 1443}, - {1152, 1495}, - {3911, 273}, - {4273, 927}, - {397, 1295}, - {2690, 3554}, - {3127, 3662}, - {4756, 1668}, - {2368, 2055}, - {4731, 1921}, - {839, 3701}, - {3830, 3768}, - {1210, 2794}, - {4399, 650}, - {561, 2069}, - {2507, 3342}, - {3248, 3466}, - {4622, 1923}, - {2232, 1282}, - {4605, 1671}, - {992, 3501}, - {3695, 3161}, - {1061, 2573}, - {2921, 3400}, - {1957, 3085}, - {4727, 582}, - {4043, 405}, - {2720, 2723}, - {356, 2428}, - {1637, 436}, - {3621, 242}, - {812, 1180}, - {871, 1731}, - {2958, 1043}, - {1334, 2361}, - {1601, 2588}, - {1079, 834}, - {3383, 147}, - {1060, 570}, - {4437, 2679}, - {4, 2258}, - {4606, 3433}, - {1399, 3167}, - {3455, 2899}, - {956, 256}, - {158, 24}, - {1780, 2909}, - {1610, 2689}, - {1151, 2218}, - {2555, 150}, - {2148, 527}, - {2941, 1274}, - {38, 346}, - {4521, 1833}, - {2076, 3117}, - {1329, 3239}, - {647, 2151}, - {2964, 1592}, - {634, 1394}, - {3740, 3301}, - {859, 3349}, - {4201, 2351}, - {1223, 3704}, - {3897, 2299}, - {1713, 676}, - {2465, 825}, - {738, 2600}, - {3160, 2976}, - {702, 2815}, - {4641, 929}, - {479, 994}, - {4262, 1881}, - {1275, 2360}, - {3440, 3553}, - {895, 961}, - {68, 1463}, - {1806, 3899}, - {4077, 3334}, - {1810, 3286}, - {2572, 1412}, - {2037, 1596}, - {3071, 331}, - {641, 2072}, - {4459, 651}, - {2303, 3039}, - {1884, 2911}, - {45, 23}, - {2580, 942}, - {3, 956}, - {4096, 2974}, - {1063, 2797}, - {3696, 3772}, - {3827, 3631}, - {1166, 2253}, - {3089, 784}, - {2653, 911}, - {4052, 2654}, - {4069, 2867}, - {353, 808}, - {4271, 1038}, - {489, 1980}, - {1155, 1385}, - {3833, 687}, - {1646, 2285}, - {2387, 2415}, - {3101, 409}, - {779, 344}, - {4718, 2376}, - {390, 2554}, - {4320, 3275}, - {1029, 2148}, - {3704, 398}, - {1782, 2962}, - {2238, 3086}, - {961, 343}, - {3242, 693}, - {927, 1179}, - {4593, 3053}, - {552, 2775}, - {4453, 3886}, - {1512, 2906}, - {3629, 3468}, - {848, 2192}, - {367, 2066}, - {1599, 1749}, - {1567, 3784}, - {2682, 2028}, - {1946, 1938}, - {2829, 1088}, - {4537, 1130}, - {20, 1500}, - {2962, 3802}, - {3388, 3920}, - {4471, 1465}, - {2083, 1751}, - {1095, 2197}, - {1126, 3854}, - {4105, 3613}, - {926, 3070}, - {3039, 2724}, - {2153, 3235}, - {4621, 1985}, - {4211, 1836}, - {2506, 3397}, - {148, 3858}, - {2476, 3596}, - {1749, 1761}, - {3446, 2181}, - {1310, 769}, - {4137, 1927}, - {857, 17}, - {3379, 2764}, - {3781, 653}, - {1336, 949}, - {3764, 933}, - {681, 2824}, - {4531, 3007}, - {114, 3672}, - {4336, 2375}, - {483, 3542}, - {2755, 1309}, - {3172, 1475}, - {4684, 3909}, - {2443, 3316}, - {4649, 3298}, - {767, 18}, - {3888, 1613}, - {1133, 299}, - {2977, 3724}, - {2041, 2275}, - {4495, 685}, - {4088, 854}, - {2615, 2622}, - {51, 2967}, - {2616, 2846}, - {1843, 918}, - {3428, 1012}, - {1370, 1874}, - {3774, 400}, - {1068, 1079}, - {3321, 3522}, - {2597, 3398}, - {4147, 1835}, - {1859, 1379}, - {4102, 1584}, - {88, 3328}, - {4454, 3273}, - {553, 2552}, - {720, 3351}, - {3973, 3031}, - {1445, 607}, - {1904, 497}, - {1206, 2772}, - {3524, 2354}, - {1235, 2548}, - {4295, 437}, - {235, 14}, - {4753, 1578}, - {3981, 2023}, - {709, 568}, - {3530, 3111}, - {2819, 2982}, - {2689, 1040}, - {3909, 587}, - {853, 828}, - {2459, 373}, - {1922, 1555}, - {3779, 1042}, - {1339, 564}, - {3769, 138}, - {687, 2225}, - {3290, 2648}, - {130, 3200}, - {3199, 829}, - {3871, 1302}, - {763, 3326}, - {936, 1376}, - {2772, 1622}, - {2227, 3284}, - {1771, 3168}, - {140, 2067}, - {2517, 1686}, - {129, 1291}, - {4186, 3136}, - {1009, 3091}, - {3768, 2324}, - {2300, 2594}, - {656, 1828}, - {646, 1572}, - {155, 957}, - {2073, 58}, - {1289, 1454}, - {2061, 3495}, - {3429, 1683}, - {1842, 1319}, - {3228, 628}, - {1023, 1498}, - {201, 1133}, - {1787, 2668}, - {348, 255}, - {962, 743}, - {2437, 111}, - {922, 468}, - {1764, 2468}, - {506, 2402}, - {3809, 2711}, - {324, 2920}, - {810, 2882}, - {781, 2185}, - {1553, 2062}, - {417, 3178}, - {2897, 3665}, - {393, 3726}, - {3801, 2020}, - {795, 1941}, - {3960, 1083}, - {2187, 2507}, - {2544, 3114}, - {591, 575}, - {1042, 387}, - {573, 1392}, - {4358, 2438}, - {41, 1035}, - {1751, 211}, - {3352, 1545}, - {951, 830}, - {2049, 872}, - {1403, 3585}, - {1032, 1734}, - {3469, 2027}, - {1008, 1973}, - {747, 3539}, - {132, 1360}, - {2804, 53}, - {2147, 2484}, - {733, 2881}, - {121, 1700}, - {2223, 3600}, - {3759, 542}, - {2230, 2743}, - {3265, 1544}, - {1400, 1457}, - {3373, 484}, - {4623, 3911}, - {481, 1641}, - {2510, 1311}, - {149, 1913}, - {2474, 2088}, - {1752, 3730}, - {3447, 84}, - {1311, 2699}, - {1992, 1897}, - {1039, 3044}, - {4075, 3182}, - {315, 1663}, - {2636, 1308}, - {1595, 3123}, - {3583, 3490}, - {1449, 2313}, - {4374, 3250}, - {597, 2706}, - {2545, 151}, - {3272, 361}, - {4583, 3108}, - {2203, 188}, - {4561, 2442}, - {3646, 509}, - {1693, 1214}, - {3157, 859}, - {1229, 2426}, - {499, 2294}, - {1491, 1025}, - {2537, 1995}, - {2420, 2625}, - {2637, 3095}, - {1643, 466}, - {1574, 122}, - {23, 2235}, - {4717, 583}, - {385, 178}, - {4318, 1709}, - {1687, 803}, - {485, 3512}, - {1222, 3382}, - {1924, 1816}, - {4342, 1398}, - {3566, 3337}, - {1118, 3266}, - {3094, 2013}, - {1330, 3729}, - {3032, 2358}, - {878, 1177}, - {1873, 2283}, - {4129, 2836}, - {2630, 974}, - {3020, 2120}, - {1247, 2526}, - {1357, 3560}, - {1657, 1660}, - {2395, 1483}, - {3178, 3307}, - {4668, 1576}, - {1930, 8}, - {239, 2755}, - {1053, 634}, - {4675, 960}, - {2419, 914}, - {3204, 2841}, - {1451, 2989}, - {1864, 3069}, - {2765, 435}, - {1065, 1037}, - {2019, 493}, - {2595, 283}, - {2236, 1485}, - {1881, 558}, - {3283, 660}, - {299, 3045}, - {642, 2923}, - {1325, 10}, - {3786, 932}, - {1321, 950}, - {2996, 2981}, - {4328, 3461}, - {1262, 1733}, - {3962, 1264}, - {788, 536}, - {3604, 1587}, - {1538, 1173}, - {4072, 1173}, - {587, 3710}, - {3028, 3755}, - {1376, 2063}, - {3218, 1889}, - {1847, 986}, - {1953, 2359}, - {4824, 2}, - {1136, 382}, - {4040, 318}, - {778, 1547}, - {3124, 700}, - {1603, 1288}, - {3839, 3549}, - {4274, 3651}, - {3599, 1681}, - {1173, 2065}, - {3592, 1932}, - {1972, 420}, - {2657, 3777}, - {2433, 2791}, - {1552, 3192}, - {3589, 2870}, - {804, 220}, - {326, 75}, - {1636, 2939}, - {4066, 2652}, - {1613, 2248}, - {2724, 193}, - {1980, 561}, - {2801, 1244}, - {3574, 1840}, - {4060, 2838}, - {4744, 2709}, - {3098, 410}, - {782, 1181}, - {3100, 696}, - {2895, 3037}, - {3449, 1589}, - {1406, 1175}, - {4608, 2469}, - {3220, 695}, - {3237, 406}, - {2193, 2519}, - {3037, 2357}, - {2091, 3345}, - {3789, 2684}, - {1204, 3787}, - {3137, 1515}, - {2704, 1684}, - {4011, 3660}, - {1565, 3170}, - {4023, 1736}, - {306, 1736}, - {4241, 458}, - {526, 458}, - {2271, 458}, - {2591, 458}, - {631, 1466}, - {1064, 1466}, - {2057, 1466}, - {4451, 1466}, - {2092, 1479}, - {3418, 1479}, - {1855, 1479}, - {3236, 1479}, - {554, 1210}, - {4401, 1210}, - {2221, 1210}, - {1762, 1210}, - {119, 1473}, - {2475, 1473}, - {150, 1473}, - {4169, 1473}, - {1022, 235}, - {3783, 235}, - {1840, 235}, - {3310, 235}, - {1057, 654}, - {624, 654}, - {1307, 654}, - {3762, 654}, - {1337, 9}, - {2975, 9}, - {2297, 9}, - {2505, 9}, - {1906, 1764}, - {2826, 1764}, - {218, 1764}, - {719, 1764}, - {2436, 1839}, - {4650, 1839}, - {2438, 1839}, - {3181, 1839}, - {1478, 724}, - {3603, 724}, - {684, 724}, - {4419, 724}, - {2261, 121}, - {1823, 121}, - {99, 121}, - {2620, 121}, - {49, 42}, - {4140, 42}, - {1093, 614}, - {3649, 614}, - {1298, 1174}, - {3391, 1174}, - {863, 3733}, - {25, 3733}, - {1852, 1380}, - {4107, 1380}, - {1857, 2144}, - {2607, 2144}, - {2088, 670}, - {3036, 670}, - {1790, 670}, - {3214, 670}, - {1021, 1564}, - {569, 1564}, - {1397, 1564}, - {3721, 1564}, - {1394, 1822}, - {3074, 1822}, - {2220, 1822}, - {2574, 1822}, - {3217, 1332}, - {1775, 1332}, - {3700, 1332}, - {4384, 1332}, - {3450, 659}, - {1004, 659}, - {3473, 112}, - {2106, 112}, - {2512, 112}, - {2295, 112}, - {3095, 2949}, - {1629, 2949}, - {3825, 2102}, - {4261, 2102}, - {3576, 2102}, - {1143, 2102}, - {3614, 1020}, - {1947, 1020}, - {2681, 1020}, - {2463, 1020}, - {4165, 426}, - {982, 426}, - {3483, 3015}, - {3060, 3015}, - {2768, 764}, - {1929, 764}, - {2886, 764}, - {2274, 764}, - {2583, 821}, - {628, 821}, - {1059, 1059}, - {2052, 1059}, - {4456, 157}, - {2096, 157}, - {3400, 2270}, - {1880, 2669}, - {3247, 2669}, - {285, 772}, - {4632, 772}, - {1895, 3557}, - {1435, 3557}, - {534, 1537}, - {2859, 1537}, - {520, 1537}, - {3906, 1537}, - {749, 2121}, - {4000, 2121}, - {1681, 2951}, - {3166, 2951}, - {1212, 500}, - {476, 500}, - {1453, 2264}, - {3891, 2264}, - {1484, 559}, - {2831, 559}, - {2461, 109}, - {2680, 109}, - {1868, 2284}, - {3286, 2284}, - {1077, 1225}, - {649, 1225}, - {1331, 1225}, - {1071, 1313}, - {1317, 1313}, - {2989, 1313}, - {2281, 97}, - {2486, 97}, - {3302, 97}, - {1863, 97}, - {3754, 3318}, - {4442, 1766}, - {3362, 1230}, - {3394, 1811}, - {2023, 3217}, - {2589, 2510}, - {2243, 2697}, - {3151, 136}, - {1702, 2171}, - {3887, 3141}, - {4321, 947}, - {3514, 1809}, - {1219, 1424}, - {3537, 1231}, - {1885, 3403}, - {2751, 2252}, - {2376, 2454}, - {4086, 31}, - {899, 2991}, - {3404, 448}, - {2976, 557}, - {3725, 2458}, - {1283, 2314}, - {3749, 1732}, - {623, 618}, - {4506, 32}, - {204, 1666}, - {1989, 1598}, - {2890, 1168}, - {300, 1521}, - {787, 1252}, - {2351, 520}, - {4741, 137}, - {2375, 421}, - {3128, 2561}, - {1562, 577}, - {3538, 1057}, - {211, 843}, - {4676, 231}, - {1910, 62}, - {1452, 207}, - {474, 3024}, - {2807, 1566}, - {496, 1191}, - {3854, 311}, - {734, 380}, - {4070, 678}, - {1536, 168}, - {3611, 1958}, - {789, 338}, - {305, 385}, - {1617, 2037}, - {4047, 442}, - {1633, 1254}, - {2706, 1290}, - {1998, 2339}, - {2818, 2242}, - {2225, 3599}, - {2496, 930}, - {549, 812}, - {996, 706}, - {2146, 952}, - {4396, 1016}, - {2173, 2263}, - {3485, 789}, - {1779, 39}, - {3319, 19}, - {369, 2256}, - {4685, 848}, - {1966, 1416}, - {1514, 1317}, - {453, 2855}, - {2932, 3446}, - {442, 3202}, - {3841, 243}, - {828, 99}, - {3936, 141}, - {1624, 386}, - {3104, 512}, - {1130, 2298}, - {376, 177}, - {1531, 209}, - {3835, 779}, - {1560, 1096}, - {2913, 323}, - {2378, 1850}, - {2753, 3158}, - {92, 1649}, - {4490, 2198}, - {2036, 1625}, - {1287, 1529}, - {686, 3565}, - {3005, 2595}, - {671, 3358}, - {3778, 1615}, - {893, 1381}, - {4162, 401}, - {4496, 1039}, - {73, 1738}, - {2978, 3875}, - {3406, 3752}, - {4410, 1230}, - {2027, 1965}, - {1058, 1811}, - {4097, 3633}, - {995, 2942}, - {4633, 136}, - {277, 1976}, - {2842, 2171}, - {3544, 3141}, - {4294, 2015}, - {1888, 1726}, - {4308, 1231}, - {1205, 3175}, - {3948, 3403}, - {844, 2252}, - {2578, 3310}, - {2289, 2748}, - {4441, 31}, - {3752, 275}, - {2934, 2991}, - {636, 448}, - {2967, 1958}, - {1278, 338}, - {3314, 442}, - {1784, 1254}, - {1182, 1290}, - {3811, 930}, - {1571, 812}, - {2311, 706}, - {818, 952}, - {3136, 39}, - {845, 19}, - {4734, 2256}, - {464, 2577}, - {4310, 2855}, - {1654, 3500}, - {3193, 2977}, - {1246, 386}, - {512, 579}, - {1420, 512}, - {3859, 2298}, - {1438, 2595}, - {2796, 664}, - {2414, 63}, - {2719, 1649}, - {436, 476}, - {4249, 2198}, - {2319, 1625}, - {1576, 3318}, - {347, 1766}, - {2698, 1477}, - {361, 1230}, - {4057, 1370}, - {1192, 3217}, - {3869, 2510}, - {975, 2697}, - {4177, 136}, - {1350, 1124}, - {2111, 947}, - {1040, 1809}, - {3489, 1424}, - {1050, 1231}, - {4383, 1036}, - {199, 31}, - {4512, 557}, - {1645, 2458}, - {3079, 2314}, - {1154, 1732}, - {410, 618}, - {1548, 1666}, - {3850, 1598}, - {1544, 1168}, - {2927, 1521}, - {2355, 1252}, - {2735, 520}, - {350, 1977}, - {4705, 137}, - {1943, 421}, - {1496, 2561}, - {435, 577}, - {2918, 1057}, - {463, 843}, - {3826, 62}, - {846, 207}, - {3950, 3024}, - {715, 1566}, - {3969, 1191}, - {1446, 311}, - {1907, 380}, - {1209, 678}, - {3520, 168}, - {1230, 385}, - {4292, 2037}, - {237, 2339}, - {4754, 2242}, - {3983, 3599}, - {711, 930}, - {3529, 812}, - {2814, 1016}, - {3912, 2263}, - {1486, 789}, - {3895, 39}, - {532, 1072}, - {4662, 848}, - {302, 1416}, - {4146, 1317}, - {854, 2855}, - {3374, 243}, - {2955, 99}, - {3775, 141}, - {1343, 386}, - {3771, 2118}, - {691, 177}, - {4527, 209}, - {127, 1223}, - {3197, 323}, - {1651, 1850}, - {3872, 3158}, - {4306, 1649}, - {3567, 2134}, - {1270, 1230}, - {3548, 1370}, - {1923, 136}, - {2776, 1124}, - {2323, 1231}, - {585, 1036}, - {4381, 31}, - {2228, 1346}, - {1772, 1252}, - {141, 1468}, - {2511, 1525}, - {128, 1536}, - {4182, 930}, - {1010, 812}, - {3770, 39}, - {2301, 386}, - {2561, 2118}, - {639, 1649}, - {1073, 2134}, - {2068, 1865}, - {4477, 1334}, - {2066, 1626}, - {3431, 228}, - {1836, 495}, - {3221, 2515}, - {1020, 2417}, - {3710, 3076}, - {1788, 534}, - {2245, 422}, - {964, 1794}, - {3231, 1867}, - {918, 2493}, - {4587, 508}, - {558, 261}, - {4445, 1506}, - {328, 1069}, - {4739, 851}, - {2003, 899}, - {1551, 1322}, - {416, 1259}, - {2901, 1964}, - {395, 1647}, - {3807, 1377}, - {793, 1888}, - {3957, 2926}, - {2183, 1525}, - {2541, 1117}, - {593, 2425}, - {1043, 2550}, - {2115, 767}, - {4356, 228}, - {2131, 495}, - {3442, 2515}, - {1755, 2417}, - {3356, 3076}, - {960, 534}, - {4200, 422}, - {1401, 1794}, - {2164, 1867}, - {1028, 2493}, - {3475, 508}, - {1011, 261}, - {4371, 1506}, - {123, 1069}, - {4526, 851}, - {3816, 899}, - {1178, 1322}, - {3142, 1259}, - {2712, 1964}, - {4025, 1647}, - {1596, 1377}, - {4008, 1888}, - {317, 2926}, - {4236, 1525}, - {515, 1117}, - {1188, 2425}, - {3803, 2550}, - {1568, 767}, - {2308, 1377}, - {816, 1888}, - {3138, 2926}, - {849, 1525}, - {4738, 1468}, - {462, 1536}, - {4313, 231}, - {1045, 1598}, - {3675, 1168}, - {1726, 1521}, - {2182, 1377}, - {970, 1888}, - {3264, 2926}, - {984, 231}, - {4602, 62}, - {619, 1108}, - {4436, 1108}, - {4099, 719}, - {983, 1845}, - {3063, 1845}, - {2126, 332}, - {4559, 2829}, - {4157, 2714}, - {2528, 416}, - {176, 1186}, - {2547, 699}, - {1757, 699}, - {3509, 3033}, - {1292, 3558}, - {4079, 2895}, - {909, 3173}, - {3412, 1777}, - {2985, 1934}, - {3731, 1934}, - {1277, 3781}, - {3744, 1978}, - {637, 1978}, - {4500, 811}, - {190, 811}, - {4299, 1467}, - {530, 751}, - {2763, 751}, - {3175, 2385}, - {4629, 456}, - {2398, 456}, - {4644, 266}, - {710, 266}, - {3876, 2509}, - {1203, 866}, - {2970, 866}, - {2048, 1203}, - {4535, 1203}, - {4126, 3714}, - {2579, 1748}, - {44, 2011}, - {2576, 1996}, - {1816, 1996}, - {3368, 3819}, - {1393, 2853}, - {3735, 3391}, - {1106, 3099}, - {3323, 417}, - {2603, 417}, - {4078, 1327}, - {1807, 2419}, - {4100, 620}, - {7, 474}, - {4434, 229}, - {618, 1357}, - {461, 1357}, - {4228, 715}, - {2331, 715}, - {1588, 1152}, - {359, 1152}, - {2717, 449}, - {349, 302}, - {4064, 2352}, - {1187, 2524}, - {3860, 3299}, - {4237, 3650}, - {451, 2227}, - {4689, 2681}, - {2327, 2904}, - {4728, 2892}, - {785, 831}, - {3817, 1080}, - {1273, 1942}, - {4354, 1942}, - {609, 2921}, - {2529, 489}, - {3262, 658}, - {4565, 2214}, - {2184, 2214}, - {4584, 2683}, - {920, 566}, - {3693, 185}, - {1121, 1698}, - {2884, 419}, - {2000, 2138}, - {4730, 3515}, - {4046, 3392}, - {2635, 1843}, - {310, 1390}, - {2688, 1590}, - {1575, 3319}, - {3608, 3280}, - {1488, 2545}, - {891, 2599}, - {4095, 3747}, - {1276, 1563}, - {2022, 1723}, - {1092, 3706}, - {3414, 3142}, - {1122, 3505}, - {4444, 1667}, - {97, 1327}, - {4585, 620}, - {1359, 11}, - {3503, 1933}, - {968, 3146}, - {173, 3177}, - {1723, 1285}, - {4163, 337}, - {1743, 1285}, - {2468, 3146}, - {2142, 3474}, - {3004, 2326}, - {58, 3247}, - {4507, 2710}, - {2024, 103}, - {1279, 337}, - {667, 2011}, - {2983, 1467}, - {690, 2433}, - {3772, 274}, - {1236, 1634}, - {3847, 90}, - {4341, 776}, - {472, 1432}, - {2737, 3638}, - {3159, 3572}, - {4670, 1540}, - {2460, 2168}, - {4665, 1802}, - {764, 3604}, - {3890, 3867}, - {1144, 2702}, - {4474, 507}, - {953, 1607}, - {4199, 1159}, - {1404, 1}, - {2167, 1272}, - {1033, 530}, - {3472, 289}, - {1003, 428}, - {4366, 2555}, - {137, 2372}, - {4529, 1}, - {1626, 1}, - {2366, 701}, - {797, 2496}, - {796, 25}, - {4713, 755}, - {391, 28}, - {4330, 1151}, - {1365, 725}, - {3493, 2768}, - {966, 1421}, - {169, 1328}, - {1719, 3807}, - {4171, 3441}, - {1753, 3193}, - {2473, 1271}, - {2133, 1724}, - {3010, 153}, - {586, 2084}, - {4382, 506}, - {2226, 2933}, - {2513, 793}, - {135, 818}, - {4185, 2703}, - {1005, 2703}, - {3765, 2703}, - {1759, 2703}, - {565, 25}, - {1390, 1607}, - {3698, 1159}, - {1402, 1}, - {2229, 530}, - {2584, 1272}, - {3235, 428}, - {1767, 289}, - {3720, 701}, - {4405, 755}, - {3478, 28}, - {1024, 1151}, - {3444, 725}, - {2134, 2768}, - {2477, 1421}, - {2265, 1269}, - {3112, 1619}, - {1618, 1141}, - {3846, 420}, - {4282, 2505}, - {3610, 723}, - {1164, 296}, - {3582, 447}, - {2638, 1251}, - {2421, 3317}, - {4178, 2651}, - {976, 3810}, - {3648, 3437}, - {584, 1702}, - {4558, 1234}, - {1928, 496}, - {238, 3429}, - {732, 3350}, - {2452, 1792}, - {4673, 1438}, - {2422, 1524}, - {3201, 3416}, - {1448, 3238}, - {3581, 2478}, - {321, 2401}, - {4742, 3612}, - {2010, 1246}, - {1555, 1348}, - {420, 1348}, - {2891, 3220}, - {388, 3220}, - {3821, 1441}, - {780, 1441}, - {3954, 276}, - {1480, 276}, - {3515, 906}, - {728, 906}, - {234, 906}, - {1700, 906}, - {3980, 69}, - {1684, 69}, - {2781, 806}, - {1920, 806}, - {2881, 806}, - {2288, 806}, - {2577, 1877}, - {655, 1877}, - {1083, 1358}, - {2100, 1358}, - {4465, 1358}, - {2046, 1358}, - {3437, 260}, - {1833, 260}, - {3210, 260}, - {245, 260}, - {4645, 166}, - {1892, 166}, - {1431, 166}, - {525, 166}, - {2832, 79}, - {527, 79}, - {3894, 79}, - {765, 79}, - {4024, 1061}, - {1695, 1061}, - {3156, 1061}, - {1232, 1061}, - {500, 1347}, - {1492, 1347}, - {3910, 1520}, - {1447, 1520}, - {2860, 554}, - {2423, 554}, - {2640, 1163}, - {2950, 1163}, - {2072, 306}, - {4516, 306}, - {4106, 306}, - {2558, 306}, - {24, 786}, - {2596, 786}, - {1801, 786}, - {3387, 786}, - {1415, 163}, - {2095, 163}, - {2938, 163}, - {34, 163}, - {872, 371}, - {2292, 371}, - {4545, 371}, - {2275, 371}, - {3340, 199}, - {1322, 199}, - {3458, 199}, - {1939, 199}, - {2795, 1453}, - {229, 1453}, - {726, 1453}, - {2445, 1453}, - {4681, 329}, - {2431, 329}, - {3195, 329}, - {1466, 329}, - {3596, 498}, - {695, 498}, - {4414, 498}, - {2256, 498}, - {1814, 609}, - {81, 609}, - {2627, 609}, - {64, 609}, - {4127, 127}, - {1101, 127}, - {3659, 127}, - {3120, 127}, - {1605, 787}, - {3837, 787}, - {4270, 787}, - {3598, 787}, - {1170, 221}, - {3595, 221}, - {1971, 221}, - {2654, 221}, - {2432, 189}, - {3921, 189}, - {1207, 189}, - {3162, 189}, - {2740, 328}, - {3972, 328}, - {1712, 328}, - {3963, 328}, - {276, 95}, - {4326, 95}, - {401, 95}, - {2672, 95}, - {2363, 352}, - {4288, 352}, - {3849, 2121}, - {2904, 2121}, - {412, 304}, - {2870, 304}, - {1520, 304}, - {3083, 304}, - {1672, 2287}, - {3474, 2287}, - {1382, 904}, - {4207, 904}, - {4614, 778}, - {3244, 778}, - {952, 2785}, - {3216, 2785}, - {1199, 289}, - {3132, 1368}, - {2695, 1269}, - {3993, 3317}, - {1579, 2651}, - {4039, 1619}, - {295, 1326}, - {4255, 755}, - {539, 28}, - {2898, 1141}, - {1986, 420}, - {4748, 1607}, - {4068, 2505}, - {2677, 327}, - {327, 707}, - {2655, 50}, - {1586, 222}, - {3594, 731}, - {1465, 432}, - {2365, 30}, - {2663, 800}, - {428, 167}, - {1169, 1077}, - {2015, 105}, - {4272, 637}, - {1982, 1272}, - {3640, 530}, - {1611, 723}, - {3147, 447}, - {2651, 296}, - {2380, 428}, - {4266, 3810}, - {3831, 181}, - {2879, 171}, - {389, 7}, - {2894, 101}, - {1508, 551}, - {3102, 184}, - {1697, 286}, - {2470, 29}, - {2244, 482}, - {4392, 68}, - {3711, 320}, - {3026, 268}, - {551, 134}, - {3034, 131}, - {1363, 485}, - {3243, 307}, - {1862, 191}, - {4691, 37}, - {363, 544}, - {2916, 198}, - {3626, 57}, - {4232, 107}, - {1945, 44}, - {4242, 162}, - {1145, 120}, - {4019, 5}, - {762, 793}, - {1296, 1251}, - {3393, 818}, - {861, 2398}, - {22, 25}, - {1849, 1064}, - {4104, 181}, - {1860, 171}, - {2605, 7}, - {2082, 101}, - {3033, 551}, - {921, 184}, - {4217, 286}, - {1392, 29}, - {2158, 482}, - {1012, 68}, - {3445, 320}, - {1025, 268}, - {4357, 134}, - {147, 131}, - {4533, 485}, - {2063, 307}, - {2954, 191}, - {6, 37}, - {855, 544}, - {2269, 198}, - {4530, 57}, - {2299, 107}, - {3325, 44}, - {1335, 162}, - {3480, 120}, - {1679, 5}, - {3170, 1151}, - {1216, 1150}, - {480, 725}, - {1460, 2312}, - {3889, 2803}, - {1477, 2988}, - {2847, 327}, - {2442, 153}, - {2676, 2084}, - {905, 1159}, - {4082, 3889}, - {1293, 1631}, - {2040, 1523}, - {1119, 3563}, - {3427, 3281}, - {1091, 3354}, - {4476, 1611}, - {52, 1391}, - {4560, 394}, - {2272, 1870}, - {2590, 98}, - {633, 2776}, - {1066, 2346}, - {2058, 602}, - {4455, 996}, - {2086, 871}, - {3422, 1097}, - {1858, 979}, - {3241, 2255}, - {2170, 2091}, - {3016, 632}, - {153, 1074}, - {948, 839}, - {2233, 65}, - {4617, 898}, - {2219, 983}, - {3268, 204}, - {1396, 61}, - {3370, 2943}, - {3029, 2658}, - {2161, 2254}, - {4600, 180}, - {4194, 403}, - {2467, 1233}, - {131, 290}, - {2519, 1863}, - {1724, 462}, - {3470, 244}, - {1338, 1530}, - {2882, 1614}, - {2006, 1349}, - {4737, 849}, - {4048, 692}, - {2646, 2387}, - {304, 2320}, - {2683, 2722}, - {1566, 741}, - {3613, 1116}, - {1481, 1793}, - {4361, 925}, - {604, 1293}, - {2523, 1321}, - {3259, 1672}, - {4556, 21}, - {2196, 631}, - {4592, 1922}, - {928, 3700}, - {3688, 3771}, - {1128, 2798}, - {1682, 13}, - {3165, 452}, - {1213, 1909}, - {478, 1771}, - {1455, 2511}, - {3892, 503}, - {1482, 269}, - {2833, 1503}, - {2466, 1165}, - {2684, 726}, - {1142, 1182}, - {3844, 1579}, - {1607, 1375}, - {2348, 1857}, - {784, 1384}, - {3093, 1837}, - {806, 2147}, - {4690, 3042}, - {425, 2329}, - {4339, 3025}, - {2424, 1504}, - {2747, 896}, - {482, 1127}, - {1220, 782}, - {1919, 2213}, - {4322, 1744}, - {1927, 1255}, - {3555, 550}, - {1694, 703}, - {3113, 1195}, - {1319, 461}, - {1827, 1762}, - {4124, 1472}, - {1882, 1488}, - {2604, 3399}, - {2094, 1990}, - {3051, 2036}, - {1663, 816}, - {2404, 1826}, - {754, 124}, - {3203, 860}, - {750, 1032}, - {4671, 390}, - {1921, 1200}, - {2813, 681}, - {205, 1220}, - {701, 1383}, - {2415, 3570}, - {4663, 3387}, - {1479, 1526}, - {3612, 241}, - {2103, 850}, - {2284, 2769}, - {4550, 2347}, - {2282, 2544}, - {3348, 444}, - {1312, 339}, - {3459, 1588}, - {2946, 2031}, - {4522, 3107}, - {4114, 2975}, - {2565, 152}, - {14, 838}, - {2586, 1054}, - {1795, 2910}, - {3397, 2871}, - {0, 2858}, - {0, 3204}, - {0, 1786}, - {0, 1873}, - {0, 3431}, - {0, 3823}, - {0, 3626}, - {0, 1955}, - {0, 2008}, - {0, 856}, - {0, 1423}, - {0, 781}, - {0, 2249}, - {0, 2332}, - {0, 1101}, - {0, 513}, - {0, 218}, - {0, 2404}, - {0, 2465}, - {0, 3252}, - {0, 801}, - {0, 1268}, - {0, 3603}, - {0, 3671}, - {0, 1695}, + {4702, 1405}, + {3898, 3775}, + {691, 1697}, + {2885, 688}, + {1307, 3906}, + {3285, 2179}, + {1177, 1095}, + {1334, 1510}, + {4211, 3114}, + {1981, 1104}, + {3683, 2024}, + {1217, 1636}, + {989, 133}, + {2605, 3143}, + {979, 512}, + {3631, 2642}, + {819, 3444}, + {1683, 1473}, + {4532, 657}, + {2275, 1220}, + {3936, 2514}, + {3009, 422}, + {2697, 3033}, + {790, 2169}, + {2693, 2706}, + {549, 666}, + {2572, 1796}, + {4579, 3753}, + {1702, 2673}, + {4009, 1806}, + {2352, 861}, + {2587, 1116}, + {2845, 1770}, + {1275, 2717}, + {2861, 1158}, + {173, 3944}, + {2982, 3010}, + {4411, 911}, + {1507, 1252}, + {3823, 3016}, + {2117, 1344}, + {2679, 3820}, + {3036, 2791}, + {1170, 1939}, + {3030, 2891}, + {308, 992}, + {2888, 2019}, + {4213, 3574}, + {1331, 2421}, + {3659, 2023}, + {2007, 1105}, + {2147, 1610}, + {2449, 179}, + {4023, 3123}, + {2456, 636}, + {4489, 2619}, + {2295, 3488}, + {75, 1437}, + {3107, 679}, + {767, 3480}, + {2533, 2535}, + {2551, 2536}, + {2877, 3232}, + {1239, 335}, + {2866, 3336}, + {130, 1530}, + {3018, 148}, + {4394, 2266}, + {1544, 3709}, + {3856, 453}, + {2089, 1609}, + {2615, 1011}, + {2809, 1860}, + {1230, 2845}, + {2816, 1989}, + {31, 3759}, + {2960, 523}, + {4445, 654}, + {1559, 1468}, + {3863, 2986}, + {2220, 2559}, + {843, 1491}, + {1066, 336}, + {2913, 3229}, + {1055, 494}, + {3106, 2500}, + {1194, 3367}, + {1607, 1326}, + {4491, 842}, + {2218, 3382}, + {3869, 2660}, + {259, 2465}, + {624, 3324}, + {3458, 191}, + {611, 3431}, + {2768, 1539}, + {474, 432}, + {2016, 2301}, + {3691, 3674}, + {1380, 435}, + {4205, 1683}, + {4682, 2130}, + {4435, 732}, + {1417, 3589}, + {4424, 1162}, + {2490, 3104}, + {4285, 3855}, + {2831, 1921}, + {1076, 36}, + {3413, 3846}, + {391, 2963}, + {4334, 2586}, + {4749, 3174}, + {1746, 104}, + {4741, 3495}, + {2168, 1700}, + {4618, 519}, + {2517, 2425}, + {748, 3552}, + {3103, 506}, + {52, 1551}, + {1601, 759}, + {1823, 2146}, + {4501, 3059}, + {1811, 1755}, + {3830, 3550}, + {1655, 2047}, + {852, 728}, + {2650, 1680}, + {182, 2777}, + {3138, 3668}, + {1639, 3892}, + {1445, 2752}, + {4461, 1744}, + {1453, 3074}, + {3996, 1203}, + {1611, 2114}, + {1184, 3729}, + {2938, 2221}, + {543, 2109}, + {3551, 1008}, + {1828, 1071}, + {1594, 1852}, + {4277, 2870}, + {1576, 1973}, + {4156, 3777}, + {1424, 2973}, + {1080, 699}, + {2827, 1423}, + {448, 1672}, + {3363, 3845}, + {3514, 2556}, + {3343, 3198}, + {152, 40}, + {3351, 872}, + {1253, 1664}, + {3208, 548}, + {3921, 2404}, + {2236, 3028}, + {4510, 559}, + {1671, 1584}, + {1650, 1583}, + {1433, 228}, + {4475, 1419}, + {1429, 395}, + {4011, 2484}, + {1604, 3411}, + {1198, 1279}, + {2932, 877}, + {533, 2332}, + {3568, 2557}, + {501, 3763}, + {43, 2879}, + {3218, 1824}, + {29, 2995}, + {2807, 1013}, + {218, 1999}, + {2487, 3610}, + {4194, 2380}, + {1938, 2012}, + {4696, 1198}, + {3467, 2506}, + {3111, 3251}, + {274, 304}, + {3119, 3355}, + {1061, 1493}, + {3257, 469}, + {4144, 2230}, + {2452, 3738}, + {4691, 487}, + {1939, 1647}, + {2923, 1540}, + {2763, 234}, + {859, 3297}, + {2774, 410}, + {635, 2468}, + {2643, 3422}, + {4494, 1232}, + {1643, 933}, + {3938, 3426}, + {2268, 2603}, + {2093, 3098}, + {2488, 665}, + {4039, 780}, + {2495, 3864}, + {4437, 2127}, + {2355, 1183}, + {6, 2825}, + {3088, 3165}, + {741, 1167}, + {2567, 1949}, + {2441, 1112}, + {2162, 44}, + {3753, 3212}, + {2177, 290}, + {4756, 586}, + {2031, 3514}, + {2002, 291}, + {0, 1311}, + {4805, 1}, + {2825, 3899}, + {1084, 3630}, + {1422, 1976}, + {4958, 1}, + {4962, 1}, + {401, 1}, + {5086, 1}, + {4709, 1}, + {4983, 1}, + {4136, 1}, + {5040, 1}, + {3042, 1}, + {5058, 1}, + {738, 1}, + {5050, 1}, + {585, 1}, + {4912, 1}, + {4612, 1}, + {4870, 1}, + {4036, 1}, + {4849, 1}, + {2470, 1}, + {5088, 1}, + {3713, 1}, + {5103, 1}, + {4657, 1}, + {4951, 1}, + {476, 1}, + {4833, 1}, + {2908, 1}, + {4829, 1}, + {2584, 1}, + {5087, 1}, + {2579, 1}, + {5009, 1}, + {1178, 1}, + {713, 1}, + {5083, 1}, + {726, 1}, + {3424, 1}, + {5042, 1}, + {1929, 1}, + {4730, 1}, + {5006, 1}, + {4149, 1}, + {2846, 1}, + {4977, 1}, + {937, 1}, + {2577, 1}, + {746, 1}, + {4764, 1}, + {1577, 270}, + {4159, 2355}, + {4862, 1}, + {1081, 1}, + {2835, 1047}, + {5054, 1}, + {4864, 1}, + {4239, 1}, + {4852, 1}, + {1872, 1}, + {4863, 1}, + {2058, 1}, + {4993, 1}, + {2694, 1}, + {5121, 1}, + {3267, 1}, + {5065, 1}, + {4333, 1}, + {5032, 1}, + {1744, 1}, + {5023, 1}, + {2167, 1}, + {4894, 1}, + {2514, 1}, + {4935, 1}, + {3102, 1}, + {4949, 1}, + {248, 1}, + {4994, 1}, + {3441, 1}, + {5017, 1}, + {483, 1}, + {4950, 1}, + {3699, 1}, + {4967, 1}, + {4203, 1}, + {4986, 1}, + {2719, 1}, + {957, 1}, + {5101, 1}, + {213, 1}, + {1335, 1}, + {4881, 1}, + {4734, 1}, + {1779, 1}, + {4840, 1}, + {1928, 1}, + {890, 1}, + {5071, 1}, + {205, 1}, + {3264, 1}, + {4887, 1}, + {4895, 1}, + {4826, 1}, + {5005, 1}, + {2506, 1}, + {755, 1}, + {1750, 1}, + {4611, 1}, + {2365, 1}, + {5104, 1}, + {2823, 1}, + {1203, 3755}, + {2576, 28}, + {372, 3096}, + {2711, 525}, + {4704, 1363}, + {1905, 56}, + {4147, 1395}, + {2481, 748}, + {3906, 2898}, + {4074, 2462}, + {2242, 820}, + {4059, 3101}, + {1534, 2037}, + {3932, 988}, + {3210, 734}, + {140, 1753}, + {2631, 978}, + {821, 2194}, + {2178, 1749}, + {2430, 908}, + {3972, 1212}, + {2444, 1446}, + {4359, 361}, + {2282, 1577}, + {92, 388}, + {3160, 2862}, + {827, 854}, + {2628, 554}, + {1361, 468}, + {1742, 1417}, + {4752, 572}, + {1757, 1049}, + {3750, 1971}, + {1909, 2550}, + {910, 30}, + {2657, 1917}, + {185, 1156}, + {3279, 3184}, + {3393, 556}, + {3193, 2571}, + {357, 1811}, + {3200, 1369}, + {1132, 796}, + {3316, 2149}, + {4090, 3302}, + {2374, 250}, + {4624, 2159}, + {1855, 969}, + {3122, 391}, + {3452, 373}, + {627, 1657}, + {3469, 241}, + {851, 20}, + {3600, 2611}, + {3828, 242}, + {2143, 1786}, + {4403, 2617}, + {1474, 3347}, + {111, 2695}, + {435, 3948}, + {3550, 1075}, + {452, 3633}, + {2518, 1766}, + {581, 704}, + {2172, 2966}, + {3880, 3469}, + {1579, 715}, + {4466, 1925}, + {561, 2200}, + {315, 664}, + {3143, 3614}, + {300, 1098}, + {3032, 3037}, + {127, 3910}, + {2269, 1879}, + {3983, 128}, + {1688, 3917}, + {4493, 2894}, + {385, 2931}, + {168, 3702}, + {3325, 829}, + {178, 3813}, + {2852, 2051}, + {349, 959}, + {2377, 2780}, + {4087, 3238}, + {1809, 968}, + {4673, 2160}, + {4526, 589}, + {4306, 1267}, + {1549, 2307}, + {4290, 1628}, + {2328, 3453}, + {4452, 2653}, + {2965, 198}, + {594, 688}, + {281, 1104}, + {3182, 1394}, + {294, 2522}, + {3065, 480}, + {96, 1500}, + {2279, 349}, + {3948, 2798}, + {1668, 1510}, + {4515, 587}, + {850, 746}, + {1047, 2138}, + {2931, 3055}, + {1063, 1636}, + {3419, 1477}, + {3154, 318}, + {301, 3242}, + {3144, 474}, + {1162, 2521}, + {3287, 3353}, + {4131, 1312}, + {2419, 860}, + {4666, 3360}, + {1815, 2672}, + {389, 1029}, + {162, 1875}, + {3329, 2837}, + {181, 2003}, + {2854, 3748}, + {345, 2994}, + {2380, 672}, + {4092, 1458}, + {1812, 3003}, + {4676, 3876}, + {1274, 3810}, + {934, 2817}, + {2590, 1890}, + {953, 2927}, + {3530, 935}, + {764, 2067}, + {1718, 3571}, + {4547, 2436}, + {2300, 2076}, + {4052, 1131}, + {3883, 623}, + {2289, 2335}, + {4114, 1598}, + {1493, 3490}, + {3958, 2623}, + {3155, 230}, + {90, 1781}, + {2594, 2615}, + {875, 3342}, + {4166, 3933}, + {3806, 2686}, + {1960, 1817}, + {3818, 3015}, + {1841, 1149}, + {3665, 2163}, + {3475, 3670}, + {513, 2295}, + {2905, 2157}, + {1111, 957}, + {2385, 1247}, + {2211, 634}, + {3772, 3443}, + {2217, 175}, + {4706, 2284}, + {2069, 3159}, + {371, 1552}, + {3378, 1114}, + {1057, 3153}, + {2814, 2431}, + {2055, 2670}, + {2256, 3132}, + {4060, 165}, + {2243, 3450}, + {4218, 1627}, + {2404, 607}, + {339, 2386}, + {3359, 3592}, + {1024, 602}, + {2726, 1478}, + {2174, 453}, + {2433, 313}, + {2747, 3896}, + {2945, 2709}, + {1039, 1780}, + {2934, 3034}, + {242, 1097}, + {2804, 2186}, + {4321, 3648}, + {1446, 2338}, + {3780, 2192}, + {2021, 998}, + {2082, 999}, + {2226, 1912}, + {4099, 2816}, + {2235, 2034}, + {4260, 3824}, + {2369, 2908}, + {355, 28}, + {3322, 1363}, + {1012, 748}, + {2740, 2462}, + {4568, 2194}, + {4241, 1749}, + {1527, 1446}, + {4227, 1577}, + {2237, 388}, + {4392, 854}, + {3021, 554}, + {1254, 468}, + {3589, 1417}, + {690, 572}, + {1759, 2917}, + {1346, 3742}, + {4352, 803}, + {1362, 3838}, + {3963, 2025}, + {1477, 1002}, + {1292, 2746}, + {3052, 3256}, + {688, 995}, + {3597, 2185}, + {2445, 1970}, + {2160, 929}, + {3757, 3650}, + {2182, 1064}, + {4757, 2950}, + {2027, 3788}, + {432, 1784}, + {1074, 688}, + {2800, 1104}, + {2710, 1394}, + {2987, 2522}, + {1137, 86}, + {2994, 3494}, + {361, 1692}, + {2849, 512}, + {4242, 2433}, + {1365, 1796}, + {3685, 523}, + {1974, 842}, + {2929, 1326}, + {2762, 654}, + {863, 2332}, + {2777, 1158}, + {637, 1989}, + {2639, 3850}, + {4499, 1927}, + {1647, 59}, + {3940, 3859}, + {2271, 2970}, + {1298, 3185}, + {905, 2595}, + {2523, 1656}, + {922, 2272}, + {3558, 12}, + {739, 1344}, + {1736, 3351}, + {4605, 3086}, + {2357, 1357}, + {4002, 251}, + {709, 565}, + {1180, 1315}, + {3027, 2262}, + {1166, 1665}, + {3135, 480}, + {1315, 1500}, + {1469, 349}, + {4377, 1142}, + {2111, 1294}, + {3827, 3397}, + {946, 3427}, + {1262, 2360}, + {2857, 1456}, + {1268, 2464}, + {3332, 400}, + {1131, 1548}, + {1363, 3163}, + {4244, 2842}, + {2011, 1554}, + {3654, 522}, + {3786, 2097}, + {4189, 778}, + {2335, 3565}, + {4171, 1200}, + {1558, 3073}, + {4058, 3882}, + {3080, 1886}, + {32, 88}, + {2536, 3869}, + {758, 2992}, + {756, 2991}, + {1148, 3656}, + {3061, 909}, + {1159, 3758}, + {3178, 1981}, + {1281, 1021}, + {1486, 2729}, + {4343, 3290}, + {2088, 1032}, + {3860, 2099}, + {2759, 3526}, + {2925, 2222}, + {1053, 1347}, + {2910, 2561}, + {264, 568}, + {2787, 1659}, + {4330, 3259}, + {1430, 2753}, + {3769, 1661}, + {2040, 386}, + {988, 1101}, + {1218, 2885}, + {2817, 687}, + {1231, 1110}, + {3229, 2022}, + {1090, 1093}, + {1395, 2861}, + {4289, 1845}, + {2044, 1106}, + {3766, 1020}, + {44, 1979}, + {496, 751}, + {3638, 2388}, + {507, 1176}, + {2611, 1221}, + {658, 2525}, + {2107, 1941}, + {3795, 24}, + {1459, 3374}, + {4420, 1480}, + {4518, 496}, + {4319, 2247}, + {1618, 223}, + {4325, 504}, + {2319, 1557}, + {4454, 414}, + {2941, 255}, + {1181, 3286}, + {3501, 403}, + {595, 1696}, + {4240, 1954}, + {4567, 914}, + {1875, 912}, + {4586, 1051}, + {2060, 2593}, + {4707, 3088}, + {2695, 1763}, + {966, 253}, + {3269, 3771}, + {202, 2144}, + {1408, 1166}, + {1680, 2475}, + {4669, 1568}, + {1689, 2370}, + {3655, 244}, + {1843, 1448}, + {984, 3478}, + {2733, 2945}, + {303, 1435}, + {3336, 5}, + {1829, 396}, + {1593, 1467}, + {4275, 2351}, + {1575, 1578}, + {4157, 3399}, + {1425, 2493}, + {1079, 136}, + {2828, 1859}, + {450, 2489}, + {3364, 3524}, + {1640, 3520}, + {1444, 2278}, + {4460, 1306}, + {1451, 2607}, + {3998, 530}, + {1612, 1705}, + {1182, 3241}, + {2940, 2762}, + {544, 1695}, + {3553, 405}, + {3406, 1984}, + {3183, 869}, + {283, 3678}, + {3162, 1006}, + {1142, 2993}, + {3306, 3743}, + {4118, 1805}, + {2447, 221}, + {4687, 3752}, + {1791, 3075}, + {1854, 3076}, + {1551, 3587}, + {4307, 733}, + {1574, 3890}, + {4193, 2102}, + {1400, 1218}, + {1087, 2801}, + {2808, 3202}, + {418, 1211}, + {3390, 1983}, + {1863, 642}, + {1539, 1251}, + {4229, 2322}, + {1529, 1616}, + {4070, 3473}, + {1393, 2638}, + {1113, 259}, + {2874, 1769}, + {492, 2633}, + {3474, 3332}, + {4748, 2131}, + {4337, 731}, + {1357, 3588}, + {4347, 1161}, + {2446, 3102}, + {4202, 3853}, + {2898, 1922}, + {1143, 38}, + {3477, 3849}, + {485, 2964}, + {3966, 3043}, + {3744, 3599}, + {2173, 710}, + {3752, 3903}, + {1749, 2211}, + {3876, 1085}, + {3540, 2863}, + {586, 3130}, + {2969, 1078}, + {1188, 2028}, + {779, 1490}, + {1125, 339}, + {3000, 3230}, + {1141, 495}, + {3197, 2502}, + {1259, 3368}, + {1511, 1325}, + {4409, 840}, + {2140, 3381}, + {3802, 2657}, + {1067, 2906}, + {842, 3728}, + {2772, 800}, + {856, 3831}, + {3462, 2016}, + {1013, 990}, + {1814, 2754}, + {4629, 3260}, + {2370, 1000}, + {4133, 2193}, + {2909, 323}, + {2510, 1479}, + {921, 2540}, + {2521, 1367}, + {439, 3274}, + {2655, 2396}, + {4747, 558}, + {1912, 2039}, + {4152, 2403}, + {2472, 3131}, + {2681, 3333}, + {3035, 2430}, + {1169, 1383}, + {3029, 2537}, + {309, 461}, + {2889, 1517}, + {4212, 3173}, + {1333, 2834}, + {3660, 1523}, + {2008, 635}, + {2589, 581}, + {2844, 1264}, + {1273, 2290}, + {2860, 1623}, + {174, 3448}, + {2984, 2647}, + {4410, 202}, + {1508, 1822}, + {3825, 2658}, + {2118, 3380}, + {1967, 2935}, + {2346, 3707}, + {4175, 849}, + {2337, 3817}, + {4288, 2053}, + {2482, 965}, + {231, 2775}, + {3230, 3225}, + {898, 951}, + {2709, 2153}, + {2660, 2152}, + {3044, 685}, + {1157, 3603}, + {3056, 1118}, + {298, 3021}, + {2906, 3923}, + {4197, 1834}, + {1340, 180}, + {3668, 3929}, + {1994, 2936}, + {3916, 3471}, + {4065, 2286}, + {2253, 1289}, + {4073, 2622}, + {1545, 638}, + {3923, 1599}, + {3205, 3307}, + {129, 2696}, + {2623, 1590}, + {829, 458}, + {2164, 3099}, + {2440, 3564}, + {3956, 779}, + {2434, 3863}, + {4346, 2125}, + {2290, 1182}, + {104, 2826}, + {3177, 3166}, + {832, 1169}, + {2621, 1951}, + {1348, 2206}, + {1755, 675}, + {4745, 3622}, + {1747, 1111}, + {3740, 3041}, + {1915, 2053}, + {931, 1870}, + {2669, 113}, + {194, 3907}, + {3271, 2889}, + {3382, 2504}, + {3201, 3252}, + {343, 306}, + {3189, 3356}, + {1118, 1494}, + {3331, 471}, + {4100, 2229}, + {2390, 3736}, + {4632, 485}, + {1846, 833}, + {3109, 2014}, + {2708, 833}, + {617, 3704}, + {3461, 975}, + {837, 2904}, + {3607, 346}, + {3839, 1724}, + {2153, 346}, + {4415, 3822}, + {1463, 3049}, + {98, 2}, + {445, 2526}, + {3534, 1513}, + {436, 2045}, + {2501, 320}, + {591, 2}, + {2186, 3539}, + {3891, 2896}, + {1591, 1388}, + {4457, 118}, + {574, 464}, + {302, 1409}, + {3149, 2125}, + {310, 1529}, + {3039, 3335}, + {121, 2543}, + {2259, 52}, + {3975, 1935}, + {1679, 2152}, + {4502, 3467}, + {373, 3449}, + {180, 2329}, + {3313, 2}, + {161, 2668}, + {2839, 584}, + {360, 1639}, + {2388, 3301}, + {4103, 2712}, + {1821, 1646}, + {4661, 486}, + {4536, 2059}, + {4294, 805}, + {1573, 3741}, + {4304, 941}, + {2342, 2940}, + {4442, 3802}, + {2962, 1741}, + {1223, 301}, + {3561, 3797}, + {537, 3024}, + {584, 3025}, + {293, 3631}, + {3173, 644}, + {287, 3943}, + {3053, 2155}, + {108, 1139}, + {2288, 2857}, + {3961, 3151}, + {1673, 1150}, + {4509, 2057}, + {2936, 3548}, + {2755, 3080}, + {872, 2105}, + {2748, 2760}, + {645, 749}, + {2630, 1740}, + {4516, 3803}, + {1634, 2610}, + {3931, 1746}, + {2280, 932}, + {1211, 2289}, + {997, 3477}, + {0, 2342}, + {0, 378}, + {0, 1432}, + {0, 2626}, + {0, 239}, + {0, 3505}, + {0, 2240}, + {0, 1487}, + {0, 3207}, + {0, 3685}, + {0, 1990}, + {0, 919}, + {0, 3941}, + {0, 1846}, + {0, 723}, + {0, 3068}, + {0, 3554}, + {0, 950}, + {0, 2767}, + {0, 3719}, + {0, 2083}, + {0, 859}, + {0, 2432}, + {0, 1693}, + {0, 3239}, + {0, 2678}, + {0, 673}, + {0, 1782}, + {0, 2951}, + {0, 695}, + {0, 1225}, + {0, 3446}, + {0, 2292}, + {0, 1542}, + {0, 3147}, + {0, 3938}, + {2836, 1421}, + {1210, 928}, + {0, 3164}, + {0, 1555}, + {0, 527}, + {0, 2244}, + {0, 3519}, + {0, 286}, + {0, 2585}, + {0, 2541}, + {0, 3273}, + {0, 561}, + {0, 2406}, + {0, 1874}, + {0, 3772}, + {0, 2864}, + {0, 2209}, + {0, 3662}, + {0, 2829}, + {0, 972}, + {0, 1920}, + {0, 3103}, + {0, 824}, + {0, 1231}, + {0, 3456}, + {0, 2299}, + {0, 1538}, + {0, 3139}, + {0, 2685}, + {0, 1107}, + {0, 1789}, + {0, 2946}, + {0, 680}, + {0, 643}, + {0, 2320}, + {0, 3475}, + {0, 256}, + {0, 2632}, + {0, 3133}, + {0, 122}, + {3854, 122}, + {0, 1416}, + {0, 2448}, {0, 2046}, - {0, 1940}, - {0, 3640}, - {0, 3780}, - {0, 2901}, - {0, 3409}, - {0, 3074}, - {0, 531}, - {0, 423}, - {0, 2735}, - {0, 2412}, - {0, 2500}, + {0, 2441}, + {0, 2705}, + {0, 1140}, + {0, 1807}, + {0, 2987}, + {0, 1004}, + {0, 866}, + {0, 2107}, + {0, 3733}, + {0, 433}, + {0, 1471}, + {0, 2644}, + {0, 201}, + {0, 3739}, + {0, 2061}, + {0, 845}, + {0, 3886}, + {0, 1906}, + {0, 934}, + {0, 2984}, + {0, 873}, + {0, 1333}, + {0, 1626}, + {0, 311}, + {0, 2847}, + {0, 3546}, + {0, 2790}, + {0, 2579}, + {0, 1668}, + {0, 34}, + {0, 3337}, + {0, 1338}, + {0, 725}, + {0, 3067}, + {0, 3557}, + {0, 947}, + {0, 2765}, + {0, 340}, + {0, 2601}, + {0, 3187}, + {0, 3506}, + {0, 532}, + {0, 2445}, + {0, 543}, + {0, 1316}, + {0, 3493}, + {0, 2219}, + {0, 1503}, + {0, 3222}, + {0, 2362}, + {0, 354}, + {697, 80}, + {2731, 48}, + {517, 187}, + {1943, 397}, + {0, 2481}, + {3194, 2056}, + {3394, 1953}, + {4173, 527}, + {2458, 755}, + {2986, 773}, + {2715, 2091}, + {2100, 3434}, + {0, 260}, + {0, 1336}, + {0, 1337}, {0, 510}, - {0, 259}, - {0, 1511}, - {0, 3567}, - {0, 1851}, - {0, 2156}, - {0, 679}, - {0, 884}, + {0, 3534}, + {0, 13}, + {0, 2274}, + {0, 3169}, + {0, 1520}, + {0, 1187}, + {0, 3179}, + {0, 2368}, + {0, 2694}, + {0, 3949}, + {0, 1074}, + {0, 3634}, + {0, 1765}, + {0, 705}, + {0, 2965}, + {0, 3470}, + {0, 716}, + {0, 1924}, + {0, 3167}, + {0, 2578}, + {0, 1667}, + {0, 2257}, + {0, 33}, + {0, 1330}, + {0, 3339}, + {0, 3100}, {0, 1339}, - {0, 3562}, - {0, 3627}, - {0, 1629}, - {0, 2106}, - {0, 1872}, - {0, 3693}, - {0, 3728}, - {0, 2842}, - {0, 2995}, - {0, 3485}, - {0, 2122}, - {0, 2034}, - {0, 3153}, - {0, 3686}, - {0, 3764}, - {0, 2104}, - {0, 1915}, - {0, 959}, - {0, 2169}, - {0, 519}, - {0, 2945}, - {0, 3023}, - {0, 200}, - {0, 777}, - {0, 1090}, - {0, 3082}, - {0, 2700}, - {0, 3870}, - {0, 2631}, - {0, 3818}, - {0, 2873}, - {0, 3804}, - {0, 3057}, - {0, 3322}, - {0, 2083}, - {0, 2212}, - {0, 3303}, - {0, 3533}, + {0, 271}, + {0, 114}, + {0, 1622}, + {0, 2628}, + {0, 1263}, + {0, 3128}, + {0, 2318}, + {0, 363}, + {0, 2207}, + {0, 2325}, + {0, 3277}, + {0, 3737}, + {0, 2907}, + {0, 2062}, + {0, 2804}, + {0, 846}, + {0, 1911}, + {0, 3885}, + {0, 2505}, + {0, 1905}, + {0, 651}, + {0, 345}, + {0, 1504}, + {0, 2539}, + {0, 1386}, + {0, 3258}, + {0, 2419}, + {0, 570}, + {0, 2013}, + {0, 2408}, + {0, 3110}, + {0, 2899}, + {0, 3726}, + {0, 821}, + {0, 3828}, + {0, 2038}, + {0, 987}, + {0, 2735}, + {0, 3270}, + {0, 977}, + {0, 2195}, + {0, 1934}, + {0, 945}, + {0, 3835}, + {0, 808}, + {0, 2836}, + {0, 3694}, + {0, 2121}, + {0, 463}, + {4758, 1}, + {3907, 1086}, + {1704, 2210}, + {801, 1583}, + {2573, 2315}, + {63, 2199}, + {3092, 973}, + {4449, 1265}, + {1677, 586}, + {4665, 120}, + {2101, 2332}, + {4530, 3118}, + {2619, 1563}, + {816, 1091}, + {3146, 3107}, + {165, 2415}, + {4538, 2621}, + {4272, 3144}, + {1597, 147}, + {4282, 3465}, + {2366, 1615}, + {4429, 621}, + {2970, 2349}, + {1200, 3628}, + {3543, 617}, + {551, 1531}, + {4646, 1482}, + {4467, 324}, + {1438, 3247}, + {4455, 483}, + {2461, 2530}, + {4322, 3359}, + {2803, 1304}, + {1045, 852}, + {3370, 3357}, + {433, 2669}, + {598, 3947}, + {291, 2693}, + {3174, 1794}, + {297, 3022}, + {3057, 1117}, + {95, 1065}, + {2281, 3683}, + {3950, 2287}, + {1663, 2178}, + {4519, 943}, + {4523, 944}, + {4296, 1926}, + {1563, 2809}, + {4287, 2054}, + {2338, 3816}, + {4453, 2925}, + {2964, 728}, + {1232, 1408}, + {1465, 2919}, + {528, 3945}, + {3422, 769}, + {3150, 2087}, + {304, 3094}, + {1697, 1713}, + {1165, 3580}, + {3286, 2734}, + {4134, 986}, + {2426, 1670}, + {4670, 2603}, + {1819, 3664}, + {383, 1284}, + {170, 606}, + {3326, 3460}, + {179, 140}, + {2851, 2319}, + {348, 3129}, + {2378, 1576}, + {4086, 1088}, + {1807, 3134}, + {4672, 2400}, + {1269, 2273}, + {938, 3502}, + {2583, 553}, + {948, 3180}, + {3527, 1329}, + {770, 32}, + {1714, 2553}, + {4545, 3857}, + {2296, 53}, + {4050, 1429}, + {3886, 1838}, + {4107, 1055}, + {2293, 3765}, + {4116, 918}, + {1499, 2858}, + {3949, 3675}, + {93, 426}, + {2596, 3671}, + {876, 77}, + {4163, 2356}, + {1168, 853}, + {1956, 384}, + {1420, 3316}, + {1840, 1449}, + {3670, 243}, + {3472, 2613}, + {510, 3782}, + {2903, 236}, + {1109, 1349}, + {2383, 1066}, + {2213, 1848}, + {3768, 2873}, + {2215, 1969}, + {4703, 3773}, + {2072, 653}, + {369, 706}, + {3374, 1419}, + {1052, 2957}, + {2811, 3852}, + {2057, 188}, + {2250, 3000}, + {4063, 1957}, + {2244, 2884}, + {4223, 885}, + {2403, 1876}, + {340, 3908}, + {3362, 2477}, + {1027, 1871}, + {2729, 770}, + {2180, 753}, + {2429, 2142}, + {3970, 3063}, + {2443, 1344}, + {4360, 3549}, + {2283, 2782}, + {91, 960}, + {3161, 1676}, + {828, 2773}, + {2629, 3672}, + {2749, 2374}, + {2943, 3391}, + {1040, 422}, + {2935, 3287}, + {246, 1461}, + {2802, 200}, + {4323, 2656}, + {1448, 3766}, + {3785, 207}, + {2024, 1321}, + {2079, 1322}, + {2227, 574}, + {4095, 3498}, + {2232, 98}, + {518, 2224}, + {2373, 3220}, + {352, 1497}, + {3320, 1189}, + {1009, 3215}, + {2739, 2373}, + {4575, 2710}, + {4238, 3902}, + {1531, 1147}, + {4231, 3597}, + {2240, 1820}, + {3023, 2982}, + {1257, 3445}, + {3592, 645}, + {694, 1907}, + {1754, 3224}, + {1349, 2574}, + {4349, 1682}, + {1359, 2249}, + {1481, 1324}, + {1288, 3371}, + {3047, 3056}, + {683, 1319}, + {3594, 189}, + {2442, 178}, + {2163, 1611}, + {3754, 2661}, + {2176, 1244}, + {4755, 3146}, + {2032, 2303}, + {426, 431}, + {3400, 2151}, + {1072, 2291}, + {2798, 3231}, + {2712, 3687}, + {2985, 2923}, + {1139, 2029}, + {2998, 2812}, + {363, 815}, + {4249, 3854}, + {1367, 2549}, + {3686, 1930}, + {1975, 711}, + {2924, 290}, + {2765, 1515}, + {860, 2519}, + {2773, 1399}, + {634, 3243}, + {2645, 2427}, + {969, 517}, + {1644, 2084}, + {3939, 2438}, + {2267, 3162}, + {1294, 2928}, + {907, 3696}, + {2520, 836}, + {917, 3494}, + {3552, 2044}, + {743, 954}, + {1731, 2785}, + {4603, 3237}, + {2354, 967}, + {3997, 2166}, + {714, 1904}, + {1176, 991}, + {3028, 3800}, + {3137, 2787}, + {1311, 3731}, + {1472, 2112}, + {4382, 482}, + {2113, 3735}, + {3829, 2711}, + {950, 2690}, + {1260, 3940}, + {2859, 1081}, + {1270, 3629}, + {3337, 1761}, + {1127, 700}, + {1366, 2972}, + {4251, 877}, + {2013, 712}, + {3656, 1929}, + {3789, 327}, + {4187, 1486}, + {2339, 2547}, + {4178, 1377}, + {1566, 3280}, + {4054, 2407}, + {3083, 547}, + {34, 2031}, + {2541, 2398}, + {761, 3126}, + {754, 3125}, + {1149, 506}, + {3058, 1592}, + {1158, 2328}, + {3176, 107}, + {1283, 1280}, + {1483, 3408}, + {4339, 3038}, + {2086, 1285}, + {3859, 328}, + {1010, 1083}, + {4544, 1802}, + {1903, 2702}, + {4555, 2190}, + {2080, 3915}, + {4695, 3039}, + {2703, 875}, + {939, 1277}, + {3261, 2973}, + {224, 3832}, + {1319, 1672}, + {1776, 103}, + {4728, 3175}, + {1761, 578}, + {896, 1380}, + {227, 3412}, + {2424, 3160}, + {3973, 127}, + {2412, 683}, + {4366, 1593}, + {2274, 637}, + {125, 2363}, + {3152, 2871}, + {807, 629}, + {2642, 1516}, + {3012, 2047}, + {786, 3727}, + {546, 1246}, + {873, 316}, + {4001, 3805}, + {1031, 338}, + {2937, 3334}, + {237, 1528}, + {2801, 446}, + {4324, 2267}, + {1452, 3710}, + {711, 457}, + {2029, 1613}, + {891, 812}, + {720, 2068}, + {2881, 1993}, + {1308, 1618}, + {3282, 1653}, + {1175, 2823}, + {1336, 1186}, + {4215, 1519}, + {1973, 2831}, + {3684, 3625}, + {1156, 3574}, + {731, 2435}, + {2670, 1918}, + {438, 1553}, + {3141, 231}, + {909, 2026}, + {1911, 3590}, + {3289, 611}, + {2491, 2033}, + {1048, 1089}, + {1245, 1133}, + {972, 897}, + {2547, 2708}, + {965, 2168}, + {3505, 3920}, + {796, 3018}, + {1712, 59}, + {4587, 1234}, + {2321, 3027}, + {4032, 3806}, + {22, 2513}, + {3812, 2595}, + {1952, 312}, + {3821, 3361}, + {1774, 1508}, + {3663, 490}, + {3479, 2218}, + {2899, 481}, + {1115, 1637}, + {1160, 1638}, + {723, 134}, + {2682, 3140}, + {705, 603}, + {904, 2429}, + {1934, 1472}, + {2687, 656}, + {1394, 3436}, + {4143, 2511}, + {1042, 3861}, + {866, 2774}, + {2757, 1716}, + {329, 1154}, + {646, 2136}, + {869, 3711}, + {4641, 2268}, + {2399, 2141}, + {4115, 1056}, + {999, 132}, + {2592, 2582}, + {516, 1607}, + {2732, 618}, + {4688, 2353}, + {1838, 3638}, + {1201, 626}, + {2397, 1532}, + {3247, 62}, + {5, 2572}, + {3237, 545}, + {3095, 3522}, + {4038, 1379}, + {2368, 794}, + {4616, 3531}, + {1700, 2496}, + {1603, 3002}, + {1827, 3665}, + {4496, 913}, + {1817, 3768}, + {3822, 1994}, + {1654, 1040}, + {862, 2715}, + {171, 1027}, + {1895, 1582}, + {1518, 222}, + {4247, 3313}, + {1506, 393}, + {4083, 2482}, + {316, 878}, + {469, 3403}, + {3494, 2559}, + {1414, 1975}, + {2933, 1160}, + {1870, 1861}, + {1085, 2487}, + {2214, 1856}, + {398, 789}, + {1041, 302}, + {1857, 2887}, + {4531, 1956}, + {1978, 3787}, + {4663, 2948}, + {978, 1431}, + {280, 2384}, + {356, 1505}, + {4482, 3874}, + {3094, 867}, + {1645, 1758}, + {2138, 1213}, + {4504, 2096}, + {857, 2237}, + {116, 1025}, + {319, 1550}, + {568, 263}, + {3423, 3285}, + {579, 428}, + {414, 3433}, + {3725, 917}, + {3281, 2589}, + {1509, 100}, + {1948, 358}, + {4690, 516}, + {2730, 2424}, + {1002, 3551}, + {3310, 505}, + {3436, 1737}, + {2048, 738}, + {692, 2962}, + {2134, 1355}, + {4396, 3084}, + {1480, 3793}, + {13, 1605}, + {514, 171}, + {3123, 2252}, + {520, 632}, + {2600, 2616}, + {693, 3482}, + {2085, 1442}, + {3805, 692}, + {9, 1100}, + {3090, 1559}, + {730, 2875}, + {2571, 3573}, + {2329, 3792}, + {1971, 1864}, + {3793, 1864}, + {2006, 3071}, + {464, 857}, + {3460, 1298}, + {1121, 3066}, + {2892, 3749}, + {2532, 411}, + {4798, 1}, + {1780, 3686}, + {4053, 421}, + {2297, 557}, + {2361, 1704}, + {1946, 45}, + {3819, 3208}, + {1950, 537}, + {4541, 2590}, + {2090, 3512}, + {685, 1410}, + {3615, 567}, + {1287, 3504}, + {3015, 2454}, + {4577, 161}, + {4225, 1594}, + {1546, 2671}, + {4234, 1230}, + {2252, 3161}, + {4389, 2283}, + {3008, 412}, + {1236, 2170}, + {3584, 2282}, + {696, 3244}, + {1740, 1759}, + {4345, 3872}, + {1345, 760}, + {3959, 2770}, + {1492, 3566}, + {1300, 2069}, + {704, 3561}, + {2439, 2726}, + {2184, 3913}, + {2171, 3608}, + {4744, 1800}, + {454, 2997}, + {3414, 3439}, + {1083, 661}, + {2794, 1893}, + {2705, 1366}, + {3003, 479}, + {1117, 3344}, + {2990, 322}, + {344, 2413}, + {2855, 3257}, + {4266, 1003}, + {1379, 1003}, + {3689, 2333}, + {1966, 2333}, + {2922, 2333}, + {2779, 2333}, + {838, 837}, + {2771, 837}, + {613, 837}, + {2648, 837}, + {4506, 850}, + {1657, 850}, + {3942, 850}, + {2261, 850}, + {1290, 493}, + {925, 493}, + {2500, 493}, + {911, 493}, + {3535, 105}, + {747, 105}, + {1756, 105}, + {4623, 105}, + {2363, 2531}, + {3994, 2531}, + {718, 2531}, + {1163, 2531}, + {3040, 281}, + {1171, 281}, + {3148, 281}, + {1310, 281}, + {1457, 164}, + {4367, 164}, + {2104, 164}, + {3833, 164}, + {941, 131}, + {1277, 131}, + {2840, 131}, + {1266, 131}, + {3312, 394}, + {1136, 394}, + {1377, 394}, + {4270, 394}, + {2014, 2334}, + {3651, 2334}, + {3801, 2334}, + {4185, 2334}, + {2343, 811}, + {4191, 811}, + {1571, 811}, + {4041, 811}, + {3075, 3078}, + {23, 3078}, + {2527, 801}, + {775, 801}, + {737, 1134}, + {1152, 1134}, + {3054, 701}, + {1146, 701}, + {3172, 2675}, + {1301, 2675}, + {1490, 620}, + {4350, 620}, + {2098, 906}, + {3845, 906}, + {2561, 906}, + {2865, 906}, + {1255, 1832}, + {2871, 1832}, + {146, 1832}, + {3013, 1832}, + {4383, 1119}, + {1526, 1119}, + {3850, 1119}, + {2092, 1119}, + {734, 303}, + {1150, 303}, + {3050, 303}, + {1144, 303}, + {3171, 1243}, + {1304, 1243}, + {1487, 940}, + {4355, 940}, + {2097, 940}, + {3849, 940}, + {290, 2385}, + {597, 2385}, + {3403, 219}, + {588, 219}, + {2654, 219}, + {440, 219}, + {2037, 226}, + {3756, 226}, + {1421, 226}, + {4317, 226}, + {4694, 1193}, + {4419, 1193}, + {1364, 774}, + {4408, 774}, + {3025, 901}, + {663, 901}, + {3606, 901}, + {1891, 901}, + {1522, 2010}, + {4245, 2010}, + {1505, 1881}, + {4081, 1881}, + {1375, 1094}, + {1138, 1094}, + {2856, 275}, + {467, 2882}, + {3492, 2882}, + {3639, 2256}, + {3222, 2256}, + {33, 569}, + {3228, 569}, + {1229, 7}, + {3071, 7}, + {4046, 7}, + {2334, 7}, + {4592, 23}, + {1728, 23}, + {1735, 434}, + {1352, 434}, + {4344, 272}, + {1344, 272}, + {3952, 2357}, + {1495, 2357}, + {1297, 1046}, + {3059, 1046}, + {700, 2254}, + {3580, 2254}, + {4576, 2377}, + {4224, 2377}, + {1543, 389}, + {4233, 389}, + {2249, 389}, + {1496, 284}, + {3007, 284}, + {1240, 284}, + {3583, 573}, + {698, 573}, + {1738, 573}, + {1350, 573}, + {4342, 802}, + {1341, 2064}, + {3954, 735}, + {1295, 1751}, + {3063, 942}, + {702, 996}, + {3581, 2181}, + {2437, 646}, + {2183, 931}, + {3739, 2655}, + {2170, 1063}, + {4740, 2949}, + {2033, 3789}, + {451, 1785}, + {3415, 232}, + {1082, 497}, + {2795, 3082}, + {2706, 514}, + {3006, 3171}, + {1120, 85}, + {2992, 2914}, + {347, 1691}, + {2853, 513}, + {4269, 1371}, + {1376, 2552}, + {3690, 524}, + {1965, 455}, + {2918, 1076}, + {2778, 727}, + {836, 2692}, + {2770, 16}, + {610, 610}, + {2649, 1223}, + {4505, 1928}, + {1658, 60}, + {3941, 3476}, + {2265, 2612}, + {1293, 247}, + {928, 883}, + {2503, 1290}, + {913, 2271}, + {3538, 10}, + {744, 1345}, + {1758, 2981}, + {4620, 1960}, + {2364, 1358}, + {3992, 249}, + {721, 566}, + {1164, 790}, + {3041, 1375}, + {1174, 1666}, + {3151, 2494}, + {1309, 2569}, + {1458, 348}, + {4365, 1721}, + {2106, 1868}, + {3832, 793}, + {942, 2410}, + {1280, 1171}, + {2842, 441}, + {1267, 2463}, + {3314, 399}, + {1133, 1549}, + {1378, 1365}, + {4265, 333}, + {2015, 1496}, + {3650, 521}, + {3798, 2098}, + {4182, 347}, + {2341, 1276}, + {4190, 1201}, + {1567, 424}, + {4042, 3881}, + {3072, 1885}, + {24, 87}, + {2526, 261}, + {777, 2348}, + {733, 2990}, + {1151, 2802}, + {3051, 907}, + {1145, 1058}, + {3167, 1980}, + {1303, 1022}, + {1489, 2730}, + {4353, 2763}, + {2096, 1033}, + {3848, 1219}, + {2410, 1723}, + {2201, 709}, + {3718, 856}, + {2196, 1144}, + {4721, 3013}, + {2046, 2101}, + {422, 1847}, + {3429, 156}, + {1093, 3942}, + {2783, 2924}, + {4105, 526}, + {3893, 1343}, + {2078, 2245}, + {3901, 1687}, + {1899, 735}, + {3758, 2592}, + {375, 1751}, + {2781, 2584}, + {1102, 3429}, + {4556, 646}, + {4243, 2321}, + {1521, 931}, + {4259, 2655}, + {2233, 609}, + {4407, 1625}, + {2988, 1785}, + {1263, 2716}, + {3604, 232}, + {671, 497}, + {103, 993}, + {430, 1908}, + {3556, 514}, + {441, 2032}, + {2522, 3171}, + {587, 85}, + {2159, 790}, + {3872, 1375}, + {1581, 2569}, + {4459, 348}, + {521, 1721}, + {4, 1171}, + {3251, 441}, + {15, 2463}, + {2837, 399}, + {189, 1496}, + {2489, 521}, + {4154, 2098}, + {1913, 1509}, + {4717, 424}, + {3391, 1888}, + {3186, 974}, + {365, 2990}, + {3196, 831}, + {1140, 2802}, + {3319, 907}, + {4084, 2101}, + {2372, 500}, + {4631, 3720}, + {1853, 1723}, + {3346, 2918}, + {3518, 709}, + {393, 856}, + {3509, 802}, + {959, 2064}, + {3371, 937}, + {3781, 735}, + {2061, 2922}, + {4320, 942}, + {1415, 996}, + {3175, 2181}, + {3405, 646}, + {600, 720}, + {3410, 1063}, + {753, 2949}, + {3544, 3789}, + {3874, 1785}, + {2157, 143}, + {4428, 514}, + {1616, 2914}, + {1437, 1691}, + {1635, 513}, + {4645, 1371}, + {1626, 2552}, + {3701, 455}, + {1804, 1076}, + {1025, 727}, + {2752, 2692}, + {338, 16}, + {3298, 610}, + {3335, 613}, + {3522, 1223}, + {381, 1928}, + {3529, 60}, + {949, 3476}, + {3375, 2612}, + {3764, 247}, + {2071, 1290}, + {4326, 2271}, + {1409, 10}, + {2838, 1345}, + {2593, 2981}, + {1001, 1960}, + {2601, 1358}, + {522, 249}, + {2722, 566}, + {4685, 1666}, + {1835, 2494}, + {4108, 1868}, + {2407, 793}, + {1036, 2410}, + {880, 1171}, + {2745, 441}, + {867, 1549}, + {3430, 1365}, + {1028, 333}, + {1801, 1496}, + {4656, 3825}, + {2401, 347}, + {4111, 1276}, + {640, 1201}, + {252, 424}, + {3128, 87}, + {234, 261}, + {2939, 2348}, + {71, 2990}, + {2318, 1614}, + {3999, 1058}, + {1707, 1980}, + {4604, 2270}, + {4444, 2763}, + {4667, 1033}, + {1682, 1219}, + {4660, 1723}, + {2108, 1752}, + {4533, 735}, + {2614, 2922}, + {809, 646}, + {3153, 720}, + {159, 1785}, + {4723, 143}, + {4376, 514}, + {1323, 3543}, + {4364, 16}, + {2413, 2275}, + {4217, 639}, + {2886, 1518}, + {1173, 1171}, + {3498, 441}, + {458, 1496}, + {1787, 2990}, + {1622, 1614}, + {4314, 1723}, + {1610, 1752}, + {4138, 1165}, + {1454, 2145}, + {1043, 3699}, + {2797, 2263}, + {407, 1483}, + {3399, 1043}, + {1436, 797}, + {1649, 2116}, + {4634, 2390}, + {1659, 1735}, + {3693, 415}, + {1806, 2755}, + {1014, 989}, + {2769, 229}, + {351, 2663}, + {3295, 3640}, + {1556, 214}, + {1851, 1296}, + {4529, 1991}, + {1844, 2859}, + {3794, 108}, + {1685, 1853}, + {811, 1588}, + {2612, 630}, + {128, 1168}, + {3187, 722}, + {3328, 639}, + {3519, 550}, + {387, 3508}, + {3525, 64}, + {956, 1730}, + {3385, 2263}, + {3759, 1483}, + {2067, 1043}, + {4328, 797}, + {1406, 2116}, + {1441, 2390}, + {1641, 1735}, + {4640, 415}, + {1629, 2755}, + {3698, 989}, + {1799, 229}, + {1029, 2663}, + {2758, 3640}, + {333, 214}, + {3302, 1296}, + {132, 1991}, + {403, 2859}, + {3508, 108}, + {392, 1853}, + {2555, 1588}, + {557, 630}, + {2205, 1168}, + {3914, 722}, + {1623, 639}, + {4423, 550}, + {3179, 3508}, + {3401, 64}, + {603, 1730}, + {3411, 630}, + {757, 1168}, + {3539, 722}, + {3877, 639}, + {2161, 2275}, + {4430, 1518}, + {1620, 883}, + {2671, 1076}, + {3049, 727}, + {1154, 2692}, + {3066, 630}, + {296, 1168}, + {2897, 722}, + {4201, 883}, + {1347, 1290}, + {3664, 3040}, + {2001, 3040}, + {762, 2903}, + {2538, 2402}, + {3888, 2402}, + {4110, 3364}, + {2286, 467}, + {4119, 3264}, + {1488, 1387}, + {3947, 331}, + {3169, 2555}, + {99, 2555}, + {2591, 321}, + {881, 1278}, + {3974, 1526}, + {3729, 297}, + {2195, 3275}, + {3717, 456}, + {1767, 456}, + {3871, 3338}, + {3570, 816}, + {577, 816}, + {2966, 2627}, + {1189, 2627}, + {4101, 1537}, + {3894, 177}, + {2074, 177}, + {3899, 3442}, + {1896, 595}, + {3760, 595}, + {3380, 2372}, + {374, 2372}, + {2780, 582}, + {1097, 955}, + {1224, 955}, + {993, 1938}, + {2603, 1938}, + {981, 2065}, + {3628, 3798}, + {810, 429}, + {1686, 766}, + {4535, 766}, + {2270, 2938}, + {3937, 3934}, + {3965, 3936}, + {3738, 2687}, + {2189, 1816}, + {3751, 1816}, + {1760, 1036}, + {3879, 2162}, + {3537, 2100}, + {582, 2293}, + {2972, 2154}, + {1187, 539}, + {1320, 539}, + {1777, 1360}, + {4729, 1360}, + {1762, 1709}, + {3726, 1709}, + {1941, 2609}, + {897, 298}, + {2686, 1738}, + {229, 2597}, + {3256, 3413}, + {4261, 2158}, + {4546, 690}, + {2083, 3026}, + {4693, 3926}, + {2704, 1830}, + {936, 166}, + {3262, 3918}, + {221, 2930}, + {3904, 2930}, + {4089, 3576}, + {2231, 756}, + {4106, 3878}, + {1514, 1202}, + {3934, 1202}, + {3192, 2788}, + {167, 3217}, + {2638, 1192}, + {817, 1996}, + {1302, 1573}, + {912, 209}, + {2513, 3311}, + {926, 371}, + {3546, 2478}, + {736, 3400}, + {1743, 1295}, + {4608, 886}, + {2351, 3407}, + {4005, 2566}, + {1005, 2989}, + {1205, 3655}, + {2834, 910}, + {1216, 3756}, + {3246, 1978}, + {1069, 1023}, + {1418, 2731}, + {4278, 3293}, + {2025, 1036}, + {3783, 2100}, + {2720, 194}, + {2991, 1566}, + {1134, 2011}, + {3005, 1454}, + {359, 585}, + {2841, 2375}, + {4252, 585}, + {1371, 2011}, + {3680, 2379}, + {1980, 3218}, + {2863, 3425}, + {2564, 2347}, + {963, 1459}, + {2542, 2375}, + {395, 429}, + {2700, 1537}, + {4712, 3145}, + {1874, 2860}, + {2890, 1771}, + {1119, 814}, + {2457, 2276}, + {2137, 3513}, + {3697, 563}, + {2150, 3189}, + {4639, 1340}, + {2010, 46}, + {460, 2544}, + {3448, 3847}, + {1129, 37}, + {2887, 1424}, + {1661, 1293}, + {3416, 518}, + {3163, 473}, + {295, 2}, + {3184, 317}, + {1155, 2411}, + {3296, 357}, + {4112, 1259}, + {2438, 1001}, + {4684, 3261}, + {1803, 2}, + {3622, 2}, + {523, 2724}, + {2597, 650}, + {689, 938}, + {3813, 109}, + {1479, 1821}, + {4395, 841}, + {4228, 1403}, + {4590, 450}, + {1860, 3115}, + {4569, 294}, + {2053, 2444}, + {4716, 3234}, + {2698, 1678}, + {970, 952}, + {3273, 641}, + {186, 1617}, + {277, 449}, + {606, 3481}, + {3471, 580}, + {461, 170}, + {2009, 799}, + {3681, 183}, + {1373, 183}, + {4210, 183}, + {288, 183}, + {583, 938}, + {2658, 518}, + {447, 473}, + {2036, 2}, + {1426, 2411}, + {4309, 317}, + {3352, 1259}, + {3504, 357}, + {408, 2724}, + {3516, 109}, + {973, 1821}, + {3368, 841}, + {3773, 1403}, + {2052, 450}, + {4313, 3115}, + {1419, 192}, + {2570, 1630}, + {2868, 2248}, + {1249, 567}, + {2876, 3172}, + {139, 1352}, + {3010, 14}, + {4388, 454}, + {3843, 25}, + {2095, 1443}, + {2276, 1850}, + {2042, 741}, + {569, 2172}, + {3569, 404}, + {1220, 3676}, + {1977, 2366}, + {4186, 368}, + {2349, 3328}, + {4299, 1426}, + {2475, 268}, + {209, 2629}, + {3219, 3770}, + {884, 252}, + {2716, 1332}, + {3778, 1053}, + {3925, 1839}, + {2402, 2883}, + {3928, 1958}, + {1389, 1958}, + {4064, 676}, + {3345, 676}, + {332, 1436}, + {2744, 1436}, + {1004, 3651}, + {4082, 3651}, + {3895, 900}, + {2070, 900}, + {3892, 900}, + {1894, 900}, + {3771, 784}, + {3389, 784}, + {382, 509}, + {2786, 509}, + {1089, 509}, + {3988, 509}, + {3723, 2133}, + {2200, 2133}, + {3734, 936}, + {1775, 936}, + {3864, 936}, + {3567, 936}, + {571, 126}, + {2959, 126}, + {1199, 126}, + {1059, 126}, + {858, 409}, + {2764, 409}, + {844, 409}, + {3450, 409}, + {1015, 210}, + {1826, 210}, + {4638, 210}, + {2386, 210}, + {4122, 375}, + {4072, 375}, + {3909, 375}, + {2065, 375}, + {3917, 74}, + {1880, 74}, + {3775, 1256}, + {3366, 1256}, + {390, 285}, + {2793, 285}, + {1077, 508}, + {3055, 508}, + {2656, 786}, + {752, 786}, + {2661, 786}, + {596, 786}, + {2509, 70}, + {4602, 70}, + {1732, 70}, + {4026, 70}, + {2320, 204}, + {1244, 204}, + {967, 204}, + {2557, 204}, + {960, 135}, + {3512, 135}, + {800, 135}, + {1705, 135}, + {4582, 145}, + {2325, 145}, + {4025, 145}, + {399, 145}, + {151, 39}, + {3342, 39}, + {135, 39}, + {2864, 39}, + {334, 383}, + {2406, 383}, + {4079, 383}, + {1795, 383}, + {4686, 218}, + {4207, 218}, + {4599, 218}, + {1923, 218}, + {4595, 390}, + {2039, 390}, + {4735, 390}, + {2691, 390}, + {900, 11}, + {3225, 11}, + {263, 11}, + {4527, 11}, + {4303, 238}, + {1555, 238}, + {4293, 238}, + {2330, 238}, + {4451, 865}, + {2967, 865}, + {1235, 865}, + {3573, 865}, + {531, 1452}, + {1701, 1452}, + {1391, 1452}, + {4386, 1452}, + {1388, 1057}, + {3922, 1057}, + {1540, 1057}, + {1258, 1057}, + {3022, 898}, + {652, 898}, + {3621, 898}, + {1512, 898}, + {1890, 696}, + {4558, 696}, + {1897, 23}, + {3900, 23}, + {1719, 1090}, + {759, 1090}, + {2574, 1090}, + {79, 1090}, + {3078, 3568}, + {1325, 3568}, + {1784, 2095}, + {4725, 2095}, + {1769, 739}, + {3719, 739}, + {1935, 1757}, + {901, 1757}, + {3459, 357}, + {623, 3432}, + {3465, 192}, + {846, 1443}, + {3603, 1850}, + {3826, 1630}, + {2142, 1034}, + {4400, 109}, + {1470, 1821}, + {1530, 2248}, + {1871, 567}, + {4573, 518}, + {1861, 3172}, + {3913, 1311}, + {1708, 102}, + {797, 360}, + {2565, 206}, + {69, 89}, + {3087, 21}, + {3808, 265}, + {4162, 350}, + {2358, 1141}, + {4153, 387}, + {1582, 529}, + {4037, 1546}, + {3096, 317}, + {16, 2411}, + {2524, 1352}, + {785, 454}, + {2130, 14}, + {2462, 1259}, + {4004, 741}, + {2467, 196}, + {4462, 158}, + {2317, 48}, + {49, 57}, + {3126, 154}, + {789, 187}, + {2515, 169}, + {1449, 119}, + {1632, 167}, + {4650, 4}, + {1638, 163}, + {3704, 115}, + {1789, 55}, + {1021, 22}, + {2750, 157}, + {326, 160}, + {3308, 397}, + {3500, 54}, + {3073, 80}, + {223, 139}, + {3084, 213}, + {1095, 76}, + {3215, 150}, + {4184, 212}, + {2478, 19}, + {4726, 67}, + {1904, 170}, + {3147, 25}, + {3421, 799}, + {575, 3734}, + {3428, 938}, + {719, 560}, + {3563, 196}, + {3867, 158}, + {2197, 48}, + {4439, 57}, + {1605, 154}, + {68, 187}, + {482, 169}, + {3590, 119}, + {489, 167}, + {2627, 4}, + {641, 163}, + {2128, 115}, + {3851, 55}, + {1528, 22}, + {4357, 157}, + {614, 160}, + {273, 397}, + {3110, 54}, + {262, 80}, + {2921, 139}, + {84, 213}, + {2304, 76}, + {4018, 150}, + {1729, 212}, + {4593, 19}, + {508, 67}, + {26, 841}, + {3227, 1257}, + {47, 1403}, + {2813, 619}, + {204, 1603}, + {2480, 3327}, + {4181, 1311}, + {1927, 1617}, + {4705, 449}, + {4552, 473}, + {4268, 844}, + {1501, 244}, + {4253, 983}, + {2224, 2912}, + {4413, 3823}, + {3004, 1719}, + {1279, 334}, + {3610, 3819}, + {665, 3045}, + {647, 3044}, + {239, 3605}, + {3131, 678}, + {249, 1661}, + {2946, 386}, + {60, 1101}, + {2311, 2885}, + {3991, 687}, + {1692, 1110}, + {4614, 2022}, + {3617, 1093}, + {3241, 2861}, + {11, 1845}, + {3234, 1106}, + {1207, 1020}, + {3099, 1979}, + {4033, 751}, + {2362, 2388}, + {4622, 1176}, + {1690, 1221}, + {648, 2525}, + {240, 1941}, + {3132, 24}, + {251, 3374}, + {2947, 1480}, + {58, 496}, + {2312, 2247}, + {3990, 223}, + {1694, 504}, + {4613, 1557}, + {1046, 414}, + {871, 255}, + {2753, 3286}, + {879, 403}, + {3435, 1696}, + {1018, 1954}, + {1792, 914}, + {4644, 912}, + {2395, 1051}, + {4117, 2593}, + {3658, 3088}, + {4045, 1763}, + {2483, 253}, + {4057, 3771}, + {1405, 2144}, + {4172, 1166}, + {3221, 2475}, + {214, 3186}, + {2678, 1155}, + {958, 1959}, + {3986, 20}, + {3728, 28}, + {2199, 3096}, + {3732, 525}, + {1773, 1363}, + {3865, 56}, + {3565, 1395}, + {567, 748}, + {2954, 2898}, + {1197, 2462}, + {2323, 820}, + {1991, 3101}, + {3855, 2037}, + {1997, 988}, + {4513, 734}, + {2123, 1753}, + {643, 978}, + {3585, 2194}, + {1238, 1749}, + {3064, 908}, + {2139, 1212}, + {2455, 1446}, + {4015, 361}, + {2450, 1577}, + {4483, 388}, + {2309, 2862}, + {82, 854}, + {3116, 554}, + {778, 468}, + {2530, 1417}, + {1979, 572}, + {4300, 1049}, + {2474, 1971}, + {211, 2550}, + {3223, 30}, + {886, 1917}, + {2721, 1156}, + {1264, 3184}, + {2848, 556}, + {160, 2571}, + {2995, 1811}, + {4421, 1369}, + {1520, 796}, + {2131, 2149}, + {2464, 3302}, + {4008, 250}, + {2469, 2159}, + {4463, 969}, + {2314, 391}, + {791, 373}, + {2511, 1657}, + {3809, 241}, + {1584, 3329}, + {4034, 2358}, + {3097, 614}, + {14, 1967}, + {2525, 2345}, + {783, 3182}, + {2133, 1942}, + {4006, 3829}, + {2468, 819}, + {4464, 2815}, + {2315, 3706}, + {50, 2140}, + {3125, 438}, + {792, 3697}, + {0, 2797}, + {0, 3826}, + {0, 964}, + {0, 3723}, + {0, 1913}, + {0, 847}, + {0, 3053}, + {0, 3379}, + {0, 839}, + {0, 1809}, + {0, 1777}, + {0, 1128}, {0, 3914}, - {0, 2152}, - {0, 1858}, - {0, 948}, - {0, 1687}, - {0, 3902}, - {0, 3786}, - {0, 1278}, - {0, 1918}, - {0, 2053}, - {0, 3750}, - {0, 3667}, - {0, 3011}, + {0, 694}, + {0, 2704}, + {0, 3624}, + {0, 1948}, + {0, 631}, + {0, 3618}, {0, 2821}, - {0, 3132}, - {0, 1815}, - {0, 1969}, - {0, 3513}, - {0, 3711}, - {0, 1924}, - {0, 2096}, - {0, 905}, - {0, 1758}, - {0, 280}, - {0, 2883}, - {0, 465}, - {0, 1135}, - {1653, 2}, - {5128, 2}, - {4869, 2}, - {1385, 2}, - {2711, 3470}, - {1995, 3190}, - {2806, 487}, - {232, 3327}, - {4658, 3052}, - {1485, 460}, - {495, 2758}, - {2816, 2389}, - {473, 2533}, - {3878, 395}, - {705, 43}, - {4051, 1618}, - {1084, 955}, - {3757, 1676}, - {1856, 3900}, - {2285, 3378}, - {866, 1289}, - {3320, 374}, - {864, 2064}, - {4502, 1693}, - {630, 3673}, - {4389, 3002}, - {1428, 1559}, - {3558, 1194}, - {741, 2601}, - {246, 357}, - {1650, 675}, - {3929, 360}, - {1668, 378}, - {2725, 2540}, - {1901, 2331}, - {2933, 3373}, - {501, 2826}, - {4319, 3131}, - {2439, 1818}, - {1689, 191}, - {220, 3506}, - {2754, 3753}, - {217, 356}, - {3942, 1929}, - {1215, 2097}, - {3834, 900}, - {638, 3815}, - {4466, 2644}, - {2263, 1093}, - {1826, 987}, - {2, 2257}, - {43, 2944}, - {4080, 1081}, - {1078, 833}, - {3719, 2022}, - {4473, 1574}, - {625, 1187}, - {2585, 2621}, - {3311, 2475}, - {4538, 686}, - {0, 245}, - {0, 2394}, - {0, 2476}, - {0, 3242}, - {0, 3198}, - {0, 2865}, - {0, 213}, - {0, 66}, - {0, 2941}, - {0, 2656}, - {0, 2250}, - {0, 182}, - {0, 576}, - {0, 1229}, - {0, 1694}, - {0, 1085}, - {0, 2498}, - {0, 2576}, - {0, 802}, - {0, 186}, - {0, 533}, - {0, 2661}, - {0, 2215}, - {0, 3472}, - {0, 2553}, - {0, 3885}, - {0, 1628}, - {0, 1531}, - {0, 3564}, - {0, 3282}, - {0, 3355}, - {0, 1617}, - {0, 1387}, - {0, 397}, - {0, 2095}, - {0, 627}, - {0, 3022}, + {0, 3269}, + {0, 2518}, + {0, 1514}, + {0, 2409}, + {0, 319}, + {0, 1381}, + {0, 3544}, + {0, 2892}, + {0, 1385}, + {0, 124}, + {0, 125}, + {0, 1632}, + {0, 2635}, + {0, 1271}, + {0, 3135}, + {0, 2326}, + {0, 356}, + {0, 2203}, + {0, 2317}, + {0, 3268}, + {0, 50}, + {0, 1933}, + {0, 2551}, + {0, 3466}, + {0, 3812}, + {0, 2828}, + {0, 1887}, {0, 2932}, - {0, 73}, - {0, 907}, - {0, 990}, - {0, 3003}, - {0, 2822}, - {0, 3743}, - {0, 424}, - {0, 2133}, - {0, 3478}, - {0, 3410}, - {0, 1848}, - {0, 1367}, - {0, 1602}, - {0, 2887}, - {0, 2241}, - {0, 2677}, - {0, 589}, - {0, 174}, - {0, 1712}, - {0, 1202}, - {0, 865}, - {0, 2431}, - {0, 2289}, - {0, 1024}, - {0, 586}, - {0, 113}, + {0, 939}, + {0, 2070}, + {0, 3562}, + {0, 2437}, + {0, 2079}, + {0, 1120}, + {0, 1392}, + {0, 440}, + {0, 3378}, + {0, 287}, + {0, 2439}, + {0, 3227}, + {0, 1686}, + {0, 963}, + {0, 3233}, + {0, 2306}, + {0, 2503}, + {0, 3250}, + {0, 308}, + {0, 3352}, + {0, 1492}, + {0, 472}, {0, 2234}, - {0, 2630}, - {0, 3211}, - {0, 2364}, - {0, 3550}, - {0, 1284}, - {0, 1448}, - {0, 3901}, - {0, 3339}, - {5035, 2}, - {2865, 2}, - {4968, 2}, - {3086, 2}, - {5026, 2}, - {2224, 2}, - {2209, 2}, - {4579, 2}, - {4895, 2}, - {5100, 2}, - {4876, 2}, - {455, 2}, - {2910, 2}, - {5113, 2}, - {4054, 2}, - {4934, 2}, - {2017, 2}, - {4830, 2}, - {4508, 2}, - {5091, 2}, - {83, 2}, - {4769, 2}, - {2098, 2}, - {2174, 2}, - {4740, 2}, - {4915, 2}, - {1556, 2}, - {421, 2}, - {386, 2}, - {4979, 2}, - {5102, 2}, - {2039, 2}, - {3076, 2}, - {0, 523}, - {0, 2166}, - {0, 3432}, - {0, 3364}, + {0, 3740}, + {0, 489}, + {0, 1649}, + {0, 1587}, + {0, 153}, + {0, 2418}, + {0, 3122}, + {0, 3600}, + {0, 3042}, + {0, 2174}, + {0, 2713}, + {0, 674}, + {0, 1804}, + {0, 3745}, + {0, 2665}, + {0, 1795}, + {0, 129}, + {0, 1633}, + {0, 2634}, + {0, 1274}, + {0, 3137}, + {0, 2324}, + {0, 355}, + {0, 2202}, + {0, 2316}, + {0, 3267}, + {0, 3048}, + {0, 3609}, + {0, 693}, + {0, 3916}, + {0, 2189}, + {0, 2881}, + {0, 3108}, + {0, 1092}, + {0, 2018}, + {0, 1787}, + {0, 1146}, + {0, 3905}, + {0, 2681}, + {0, 3635}, + {3677, 1}, + {4999, 1}, + {4927, 1}, + {1370, 1}, + {3796, 3468}, + {1471, 714}, + {4398, 1923}, + {703, 2201}, + {188, 663}, + {200, 1096}, + {2977, 3035}, + {3, 3909}, + {2359, 1880}, + {4031, 130}, + {1739, 2447}, + {4589, 2895}, + {480, 2933}, + {62, 3701}, + {3272, 828}, + {53, 532}, + {2796, 2048}, + {254, 958}, + {2471, 2781}, + {4140, 2056}, + {1886, 970}, + {4742, 2161}, + {4615, 591}, + {4195, 1266}, + {1498, 2305}, + {4204, 1626}, + {2292, 3451}, + {4340, 2651}, + {3043, 199}, + {1284, 1808}, + {3620, 2643}, + {653, 3377}, + {662, 2786}, + {230, 2412}, + {3068, 1391}, + {206, 397}, + {2953, 477}, + {38, 1498}, + {2345, 862}, + {4055, 2799}, + {1772, 1511}, + {4551, 590}, + {3613, 1396}, + {3259, 436}, + {81, 3375}, + {3265, 279}, + {1195, 2440}, + {4014, 1688}, + {2302, 966}, + {4548, 3236}, + {1783, 2311}, + {661, 926}, + {233, 1964}, + {3070, 2976}, + {207, 1843}, + {2952, 3673}, + {0, 2492}, + {0, 3904}, + {0, 149}, + {0, 1373}, {0, 1813}, - {0, 1428}, - {0, 1550}, - {0, 3405}, - {0, 3258}, - {0, 2456}, - {0, 2405}, - {0, 3607}, - {0, 1273}, - {0, 1371}, - {0, 3836}, - {0, 3402}, - {0, 3222}, - {0, 1426}, + {0, 1103}, + {0, 3919}, + {0, 669}, + {0, 2707}, + {0, 3606}, + {0, 2006}, + {0, 594}, + {0, 3611}, + {0, 2792}, + {0, 3437}, + {0, 2314}, + {0, 1240}, + {0, 2645}, + {0, 604}, + {0, 1620}, + {0, 3294}, + {0, 2725}, + {0, 1624}, + {0, 501}, + {0, 155}, + {0, 1586}, + {0, 2666}, + {0, 1222}, + {0, 3152}, + {0, 2281}, + {0, 420}, + {0, 2175}, + {0, 2285}, + {0, 3248}, + {0, 3255}, + {0, 2501}, + {0, 1527}, + {0, 2395}, + {0, 337}, + {0, 1361}, + {0, 3533}, + {0, 2911}, + {0, 1372}, + {0, 151}, + {0, 1793}, + {0, 1148}, + {0, 3901}, + {0, 717}, + {0, 2689}, + {0, 3637}, + {0, 1963}, + {0, 1534}, + {0, 452}, + {0, 2255}, + {0, 3703}, + {0, 444}, + {0, 1601}, + {0, 822}, + {0, 2074}, + {0, 2897}, + {0, 1943}, + {0, 3693}, + {0, 2830}, + {0, 1174}, {0, 1512}, - {0, 257}, - {0, 1341}, - {0, 881}, - {0, 2350}, - {0, 2262}, - {0, 1008}, - {0, 610}, - {0, 91}, - {0, 2309}, - {0, 2623}, - {0, 3118}, - {0, 2789}, - {0, 3261}, - {5047, 2}, - {578, 2}, - {4768, 2}, - {1074, 2}, - {3285, 2}, - {2560, 2}, - {4109, 2}, - {1845, 2}, - {4143, 2}, - {55, 2}, - {4475, 2}, - {4772, 2}, - {5064, 2}, - {4766, 2}, - {265, 2}, - {2792, 2}, - {263, 2}, - {0, 1821}, - {0, 363}, - {0, 2814}, - {0, 2705}, - {0, 377}, - {0, 1190}, - {0, 672}, - {0, 2765}, - {0, 3017}, - {0, 3577}, - {0, 2277}, - {0, 3721}, - {0, 1396}, - {0, 1219}, - {0, 3725}, - {0, 3514}, - {0, 3119}, - {0, 1306}, - {0, 1633}, - {0, 92}, - {0, 3540}, - {0, 2378}, - {0, 913}, - {0, 739}, - {0, 2530}, - {0, 3062}, - {0, 2757}, - {0, 688}, - {0, 1142}, - {0, 1862}, - {0, 638}, - {0, 2081}, - {4816, 2}, - {161, 181}, - {1055, 286}, - {438, 68}, - {548, 320}, - {104, 485}, - {37, 544}, - {145, 198}, - {665, 57}, - {1, 107}, - {240, 44}, - {379, 162}, - {255, 120}, - {470, 50}, - {1134, 222}, - {12, 731}, - {182, 432}, - {21, 30}, - {440, 800}, - {662, 167}, - {313, 1077}, - {228, 105}, - {580, 637}, - {5088, 2}, - {4874, 2}, - {3631, 1408}, - {3377, 2514}, - {3501, 820}, - {3920, 3682}, - {1007, 2367}, - {3923, 1007}, - {3481, 2955}, - {4809, 2}, - {5043, 2}, - {5079, 2}, - {4479, 3411}, - {398, 2924}, - {4484, 232}, - {4285, 998}, - {3855, 3681}, - {1931, 1688}, - {84, 181}, - {186, 171}, - {214, 7}, - {745, 184}, - {1341, 320}, - {9, 134}, - {1044, 131}, - {600, 307}, - {207, 191}, - {262, 37}, - {47, 544}, - {331, 198}, - {288, 57}, - {405, 107}, - {493, 44}, - {28, 162}, - {293, 120}, - {100, 5}, - {769, 886}, - {917, 3785}, - {725, 59}, - {224, 106}, - {517, 173}, - {10, 15}, - {1502, 278}, - {870, 155}, - {154, 72}, - {110, 480}, - {599, 615}, - {227, 1324}, - {825, 291}, - {1034, 205}, - {194, 64}, - {934, 83}, - {650, 240}, - {2078, 72}, - {1828, 130}, - {454, 1260}, - {1422, 1418}, - {213, 78}, - {266, 287}, - {120, 216}, - {54, 297}, - {336, 499}, - {290, 59}, - {589, 106}, - {1195, 173}, - {574, 15}, - {2162, 278}, - {969, 155}, - {423, 72}, - {568, 480}, - {344, 615}, - {343, 1324}, - {40, 291}, - {198, 205}, - {1301, 64}, - {1248, 83}, - {674, 240}, - {409, 130}, - {98, 130}, - {292, 1260}, - {241, 1418}, - {876, 78}, - {988, 287}, - {1692, 216}, - {1148, 297}, - {1424, 192}, - {947, 15}, - {70, 72}, - {3313, 615}, - {775, 78}, - {2314, 240}, - {2296, 36}, - {742, 72}, - {1082, 15}, - {4026, 72}, - {2291, 615}, - {1732, 78}, - {4615, 240}, - {2340, 36}, - {1037, 72}, - {3434, 15}, - {3840, 72}, - {1054, 615}, - {4002, 78}, - {2053, 240}, - {1379, 36}, - {2639, 72}, - {4421, 15}, - {4268, 72}, - {4298, 615}, - {3014, 78}, - {1934, 240}, - {2557, 36}, - {949, 72}, - {366, 15}, - {2515, 72}, - {4111, 615}, - {4036, 78}, - {3982, 240}, - {3267, 36}, - {1649, 1213}, - {3457, 1213}, - {1675, 319}, - {3487, 1364}, - {3163, 1146}, - {2708, 2411}, - {807, 1104}, - {3279, 1084}, - {4488, 584}, - {4749, 1661}, - {4639, 2130}, - {2495, 1462}, - {2417, 2340}, - {3067, 1814}, - {4672, 1115}, - {4013, 170}, - {2381, 2392}, - {4599, 636}, - {3329, 203}, - {3115, 2047}, - {3198, 1696}, - {4206, 316}, - {706, 1906}, - {3663, 142}, - {2451, 1400}, - {1569, 425}, - {4746, 2738}, - {2200, 2665}, - {892, 2290}, - {803, 56}, - {761, 100}, - {1789, 702}, - {3155, 794}, - {1356, 3873}, - {4660, 971}, - {4020, 319}, - {2349, 1364}, - {4552, 1146}, - {3355, 2411}, - {3087, 1104}, - {3179, 1084}, - {4204, 584}, - {735, 1661}, - {3677, 2130}, - {756, 1462}, - {308, 2340}, - {3146, 1115}, - {954, 170}, - {2268, 636}, - {2341, 2047}, - {2464, 1696}, - {191, 316}, - {4631, 1906}, - {567, 142}, - {3896, 1400}, - {4243, 2535}, - {1534, 425}, - {3658, 763}, - {3006, 100}, - {2863, 3473}, - {2830, 1784}, - {4388, 926}, - {498, 903}, - {4575, 2154}, - {0, 285}, - {0, 3370}, + {0, 2820}, + {0, 3619}, + {0, 3834}, + {0, 2805}, + {0, 1936}, + {0, 2910}, + {0, 981}, + {0, 2035}, + {4955, 1}, + {1723, 1}, + {4836, 1}, + {2306, 1}, + {4995, 1}, + {2566, 1}, + {906, 1}, + {3409, 1}, + {4845, 1}, + {4834, 1}, + {4973, 1}, + {4128, 1}, + {3290, 1}, + {4945, 1}, + {122, 1}, + {4982, 1}, + {114, 1}, + {5047, 1}, + {3630, 1}, + {4856, 1}, + {680, 1}, + {4773, 1}, + {2254, 1}, + {1666, 1}, + {4248, 1}, + {4848, 1}, + {4298, 1}, + {2348, 1}, + {2955, 1}, + {5072, 1}, + {5056, 1}, + {2087, 1}, + {3858, 1}, + {0, 2728}, + {0, 3912}, + {0, 1127}, + {0, 3607}, + {0, 1799}, + {0, 671}, + {0, 2998}, + {0, 3440}, + {0, 662}, {0, 1894}, - {0, 2862}, - {0, 3249}, - {0, 2043}, - {0, 537}, - {0, 3201}, - {0, 2116}, - {0, 2175}, - {0, 1480}, - {0, 2330}, - {0, 978}, - {0, 3816}, - {0, 2466}, - {0, 810}, - {0, 2890}, - {0, 2021}, - {0, 3121}, - {0, 3251}, - {0, 3618}, - {0, 1193}, + {0, 598}, + {0, 1272}, {0, 2302}, + {0, 1631}, + {0, 3457}, + {0, 2662}, + {0, 190}, + {0, 1815}, + {0, 2650}, + {0, 3372}, + {0, 3148}, + {0, 2624}, + {0, 1640}, + {0, 2288}, + {0, 181}, {0, 1236}, - {0, 770}, - {0, 2687}, - {0, 3179}, - {0, 569}, - {0, 2847}, - {0, 2707}, - {0, 2395}, - {0, 1560}, - {0, 3697}, - {0, 835}, - {1070, 69}, - {708, 806}, - {1224, 166}, - {596, 1347}, - {143, 352}, - {514, 1163}, - {264, 79}, - {1141, 199}, - {556, 304}, - {1532, 787}, - {1098, 221}, - {29, 189}, - {354, 328}, - {219, 306}, - {13, 329}, - {1429, 609}, - {1661, 163}, - {316, 127}, - {1383, 554}, - {15, 786}, - {360, 1358}, - {231, 260}, - {1072, 1061}, - {2774, 1520}, - {1708, 371}, - {2005, 1453}, - {699, 498}, - {757, 469}, - {3309, 659}, - {3880, 1004}, - {3375, 326}, - {444, 95}, - {1872, 1}, - {3947, 3518}, - {2694, 3778}, - {2587, 864}, - {2546, 2480}, - {4669, 1575}, - {107, 992}, - {4297, 2374}, - {2499, 282}, - {3334, 3393}, - {39, 1827}, - {1758, 2247}, - {3552, 1056}, - {157, 746}, - {885, 738}, - {2582, 1411}, - {268, 345}, - {1578, 1900}, - {1865, 2528}, - {1742, 341}, - {736, 2997}, - {4202, 2318}, - {1243, 472}, - {2489, 1138}, - {3341, 1713}, - {8, 1571}, - {2757, 1747}, - {4041, 443}, - {4113, 2837}, - {4160, 402}, - {3158, 3365}, - {1785, 2937}, - {3564, 279}, - {1736, 2737}, - {2279, 1092}, - {4098, 3333}, - {1707, 431}, - {294, 3814}, - {2408, 1482}, - {2527, 1087}, - {3460, 181}, - {2993, 171}, - {1056, 7}, - {3545, 101}, - {4252, 551}, - {4440, 184}, - {4346, 286}, - {2805, 29}, - {2171, 482}, - {2783, 68}, - {1314, 320}, - {2120, 268}, - {3701, 134}, - {1495, 131}, - {538, 485}, - {555, 307}, - {661, 191}, - {1993, 37}, - {2968, 544}, - {2332, 198}, - {4256, 57}, - {3885, 107}, - {1894, 44}, - {4469, 162}, - {3462, 120}, - {3560, 5}, - {3600, 2693}, - {1183, 1149}, - {4108, 2300}, - {430, 3511}, - {1227, 20}, - {2312, 3825}, - {2948, 1243}, - {4710, 3134}, - {2335, 1727}, - {3315, 1930}, - {1509, 3346}, - {2488, 839}, - {1952, 3456}, - {2087, 1018}, - {2129, 2414}, - {502, 1395}, - {4390, 892}, - {249, 2527}, - {3702, 3300}, - {4439, 391}, - {1313, 2698}, - {3863, 2831}, - {2924, 2327}, - {2947, 1749}, - {3066, 3597}, - {4317, 684}, - {570, 1329}, - {4640, 3908}, - {1774, 1903}, - {2252, 2959}, - {4139, 139}, - {1669, 342}, - {341, 708}, - {36, 3857}, - {195, 1224}, - {2441, 2278}, - {2469, 3574}, - {1889, 1655}, - {2231, 263}, - {1804, 3089}, - {4547, 355}, - {2413, 108}, - {819, 805}, - {874, 3732}, - {986, 1382}, - {1690, 2421}, - {3212, 3637}, - {1425, 1486}, - {945, 3324}, - {65, 348}, - {3317, 2082}, - {776, 1790}, - {2313, 2568}, - {2294, 1211}, - {2210, 3847}, - {222, 1184}, - {869, 2459}, - {3186, 2617}, - {4700, 3005}, - {4539, 1984}, - {4580, 3390}, - {2756, 414}, - {2222, 2093}, - {2836, 3312}, - {935, 3537}, - {4624, 1883}, - {536, 3330}, - {118, 923}, - {902, 3734}, - {2564, 1242}, - {244, 1389}, - {1597, 1849}, - {1722, 119}, - {716, 3126}, - {4214, 2783}, - {1265, 644}, - {4528, 2077}, - {1821, 3169}, - {3979, 3305}, - {2634, 1140}, - {2520, 2240}, - {4637, 1299}, - {170, 711}, - {4329, 2609}, - {1013, 2996}, - {688, 1329}, - {3365, 3444}, - {1245, 3353}, - {1977, 3894}, - {2045, 766}, - {2108, 2624}, - {4402, 1188}, - {270, 2112}, - {3761, 3684}, - {4363, 995}, - {1386, 2246}, - {3788, 2348}, - {2858, 1211}, - {3018, 2182}, - {2979, 3213}, - {2189, 2186}, - {4213, 3304}, - {250, 3625}, - {89, 2369}, - {2367, 1452}, - {2559, 822}, - {1950, 488}, - {929, 2751}, - {3131, 2898}, - {4638, 2259}, - {4604, 1670}, - {4485, 3546}, - {2661, 762}, - {2302, 1248}, - {2926, 3876}, - {1081, 1975}, - {590, 2922}, - {3467, 46}, - {1191, 258}, - {1891, 768}, - {2168, 3893}, - {2038, 1276}, - {429, 2226}, - {4460, 3610}, - {340, 1737}, - {3041, 284}, - {449, 26}, - {1426, 877}, - {1405, 3782}, - {1172, 2365}, - {3766, 3683}, - {817, 1567}, - {2109, 246}, - {3716, 3056}, - {1510, 2907}, - {518, 2643}, - {581, 1292}, - {689, 3905}, - {2016, 1120}, - {2949, 1719}, - {2310, 3582}, - {3782, 3868}, - {4360, 752}, - {1413, 2521}, - {3820, 2527}, - {2837, 2958}, - {3046, 1935}, - {3001, 3343}, - {4276, 478}, - {620, 2041}, - {4697, 3253}, - {1305, 3584}, - {2141, 1119}, - {3708, 2380}, - {1507, 2217}, - {535, 2860}, - {562, 2070}, - {666, 247}, - {2957, 1962}, - {2337, 3376}, - {3007, 1782}, - {608, 351}, - {2893, 154}, - {3898, 813}, - {3673, 3745}, - {3776, 1402}, - {3641, 1997}, - {1280, 3623}, - {3078, 1514}, - {1745, 2732}, - {4610, 439}, - {2318, 528}, - {758, 1031}, - {939, 3669}, - {897, 1606}, - {1612, 2492}, - {3307, 3794}, - {1524, 1419}, - {2479, 795}, - {3360, 3841}, - {19, 1355}, - {2769, 1270}, - {4032, 1988}, - {4119, 3009}, - {4167, 315}, - {3148, 3228}, - {1769, 2877}, - {3569, 514}, - {1940, 1204}, - {1500, 2666}, - {2125, 730}, - {1105, 224}, - {1158, 1910}, - {1409, 415}, - {1718, 2007}, - {2798, 870}, - {3642, 3797}, - {399, 1294}, - {3062, 1478}, - {3742, 1805}, - {3836, 3055}, - {3864, 34}, - {3451, 3187}, - {1476, 2731}, - {3275, 590}, - {221, 2427}, - {824, 1494}, - {2686, 3555}, - {1792, 3195}, - {1638, 639}, - {1667, 2750}, - {942, 1763}, - {722, 2292}, - {3122, 3663}, - {990, 3538}, - {2247, 3262}, - {2384, 455}, - {4657, 309}, - {603, 2969}, - {2440, 1021}, - {1577, 3644}, - {4755, 1669}, - {2212, 1484}, - {882, 2172}, - {809, 2753}, - {773, 641}, - {1773, 3451}, - {3150, 3081}, - {1366, 118}, - {4683, 581}, - {3997, 3181}, - {2364, 2056}, - {4577, 2200}, - {3336, 1546}, - {3103, 2383}, - {3190, 969}, - {4210, 3792}, - {713, 2495}, - {3647, 853}, - {1591, 3453}, - {4733, 1920}, - {2178, 1755}, - {914, 1420}, - {783, 2523}, - {743, 919}, - {3168, 2408}, - {1368, 1026}, - {3196, 2236}, - {2668, 1745}, - {836, 3702}, - {3249, 3595}, - {4520, 3224}, - {4721, 392}, - {2389, 202}, - {3024, 2930}, - {1459, 2628}, - {1960, 1245}, - {3828, 3769}, - {1353, 3827}, - {693, 3383}, - {380, 305}, - {2157, 2033}, - {2828, 490}, - {2207, 2850}, - {3590, 3209}, - {1208, 2795}, - {3411, 2744}, - {4378, 2436}, - {4315, 1612}, - {4221, 3677}, - {2942, 823}, - {2012, 1450}, - {2619, 3822}, - {673, 749}, - {1031, 3853}, - {3054, 1413}, - {387, 1227}, - {1490, 1939}, - {1297, 340}, - {1179, 3246}, - {3747, 2864}, - {801, 470}, - {4423, 1464}, - {3705, 2471}, - {2145, 665}, - {4284, 846}, - {3512, 190}, - {3508, 3524}, - {3392, 1841}, - {4059, 2205}, - {2249, 3641}, - {1781, 1028}, - {4567, 2297}, - {2357, 2416}, - {724, 2734}, - {977, 2146}, - {860, 3124}, - {3344, 1808}, - {1559, 3448}, - {1796, 3535}, - {2237, 1171}, - {4168, 2444}, - {1616, 2286}, - {223, 2799}, - {184, 2012}, - {2315, 335}, - {2623, 1892}, - {2013, 3314}, - {50, 1501}, - {959, 2422}, - {2533, 1198}, - {303, 1034}, - {1691, 535}, - {1730, 3122}, - {1850, 2145}, - {821, 3094}, - {4094, 3439}, - {2614, 2210}, - {3239, 2718}, - {168, 389}, - {2652, 593}, - {3986, 1082}, - {4148, 3716}, - {4103, 1583}, - {3134, 2477}, - {1818, 3808}, - {3602, 1476}, - {101, 1767}, - {2539, 365}, - {322, 128}, - {1734, 3731}, - {1861, 1378}, - {837, 2423}, - {4083, 3634}, - {1132, 1496}, - {4110, 3593}, - {4596, 1131}, - {4016, 2232}, - {2785, 2872}, - {2482, 2087}, - {2606, 3311}, - {4732, 267}, - {30, 1944}, - {4250, 3386}, - {550, 774}, - {3502, 2562}, - {1157, 2636}, - {1918, 2903}, - {2128, 1866}, - {466, 505}, - {3691, 2739}, - {4452, 2177}, - {1284, 3264}, - {3913, 3205}, - {2883, 3666}, - {4311, 1436}, - {595, 841}, - {1342, 3449}, - {2114, 104}, - {1516, 3087}, - {523, 2503}, - {683, 3739}, - {2011, 1019}, - {2944, 1551}, - {2306, 2927}, - {3075, 1998}, - {1014, 3504}, - {3624, 3395}, - {4303, 3837}, - {4394, 683}, - {4420, 2607}, - {2875, 1750}, - {2074, 1089}, - {2721, 2239}, - {865, 467}, - {177, 3248}, - {3251, 2161}, - {842, 2009}, - {2388, 1690}, - {2241, 2279}, - {2260, 1172}, - {320, 3855}, - {4523, 2649}, - {447, 750}, - {26, 646}, - {972, 3125}, - {2514, 2030}, - {365, 2150}, - {1647, 1604}, - {1786, 2418}, - {1819, 1029}, - {802, 3735}, - {1190, 921}, - {1854, 2878}, - {2186, 2002}, - {4215, 3137}, - {1598, 3240}, - {243, 3606}, - {160, 1185}, - {96, 2293}, - {2374, 1206}, - {2567, 796}, - {1956, 2664}, - {4144, 2231}, - {4563, 1739}, - {1768, 3698}, - {4027, 3594}, - {2777, 3231}, - {2617, 2845}, - {4751, 1982}, - {17, 226}, - {4222, 2925}, - {1851, 2670}, - {2205, 1207}, - {4198, 3749}, - {1570, 3850}, - {291, 3408}, - {108, 350}, - {53, 2966}, - {2359, 2001}, - {1959, 2876}, - {2625, 594}, - {3227, 3183}, - {193, 2068}, - {2685, 2209}, - {3955, 1543}, - {4138, 965}, - {3141, 3795}, - {1793, 2491}, - {3588, 862}, - {2055, 159}, - {1371, 3427}, - {4385, 1879}, - {1942, 1789}, - {1269, 1460}, - {1000, 2549}, - {1090, 889}, - {1542, 3622}, - {3398, 2449}, - {1593, 1065}, - {3025, 1720}, - {3430, 2268}, - {621, 993}, - {2841, 1118}, - {3818, 479}, - {3753, 3278}, - {3517, 2953}, - {1411, 3379}, - {3191, 1957}, - {1470, 2311}, - {1973, 1627}, - {3822, 3632}, - {698, 3291}, - {378, 504}, - {505, 2861}, - {2154, 1869}, - {2824, 367}, - {2199, 2987}, - {3527, 3687}, - {2915, 1017}, - {1168, 656}, - {3505, 2355}, - {4408, 2759}, - {4290, 2178}, - {4314, 3203}, - {3043, 102}, - {1911, 1817}, - {2534, 3493}, - {700, 1352}, - {362, 2551}, - {3096, 783}, - {973, 885}, - {2396, 1791}, - {109, 2773}, - {4677, 3133}, - {617, 2126}, - {206, 1257}, - {840, 2635}, - {2666, 910}, - {180, 773}, - {1808, 250}, - {1620, 3348}, - {1659, 1875}, - {924, 2856}, - {3977, 3257}, - {1670, 3763}, - {2334, 873}, - {4058, 2653}, - {1728, 2546}, - {75, 3048}, - {309, 1800}, - {256, 3430}, - {2217, 605}, - {2745, 2164}, - {2144, 3147}, - {3966, 3487}, - {4715, 88}, - {1602, 2940}, - {4155, 3029}, - {2632, 2542}, - {2641, 1444}, - {2760, 3821}, - {4607, 1005}, - {236, 1570}, - {4365, 3674}, - {1715, 3152}, - {2316, 604}, - {4063, 2868}, - {1738, 2771}, - {72, 2370}, - {318, 1534}, - {274, 3624}, - {2239, 876}, - {2731, 1410}, - {2107, 3757}, - {346, 809}, - {2492, 727}, - {4131, 358}, - {4005, 3415}, - {3959, 1956}, - {3255, 2808}, - {1662, 3287}, - {3471, 2115}, - {1935, 1656}, - {1494, 2281}, - {2124, 1169}, - {1097, 430}, - {1160, 3245}, - {1264, 2010}, - {1416, 2961}, - {3525, 3368}, - {1725, 1902}, - {2902, 55}, - {3543, 3523}, - {488, 1981}, - {2995, 1458}, - {3665, 1366}, - {3905, 2193}, - {3802, 852}, - {3386, 3719}, - {1541, 2333}, - {3324, 966}, - {3535, 759}, - {2907, 3877} + {0, 3414}, + {0, 3020}, + {0, 1226}, + {0, 299}, + {0, 330}, + {0, 1484}, + {4931, 1}, + {1242, 1}, + {4768, 1}, + {4621, 1}, + {1907, 1}, + {4609, 1}, + {2023, 1}, + {4753, 1}, + {2667, 1}, + {927, 1}, + {3240, 1}, + {4772, 1}, + {5025, 1}, + {4770, 1}, + {2260, 1}, + {4379, 1}, + {3037, 1}, + {0, 3065}, + {0, 3578}, + {0, 729}, + {0, 3883}, + {0, 2085}, + {0, 1205}, + {0, 2810}, + {0, 3205}, + {0, 1214}, + {0, 1995}, + {0, 1961}, + {0, 923}, + {0, 3645}, + {0, 1059}, + {0, 2943}, + {0, 3780}, + {0, 1790}, + {0, 237}, + {0, 3784}, + {0, 3087}, + {0, 3532}, + {0, 2235}, + {0, 1356}, + {0, 2567}, + {0, 577}, + {0, 1663}, + {0, 3249}, + {0, 2749}, + {0, 1655}, + {0, 372}, + {0, 370}, + {0, 1460}, + {0, 73}, + {0, 1910}, + {0, 2508}, + {0, 3454}, + {0, 3226}, + {0, 2533}, + {0, 1499}, + {0, 2423}, + {0, 300}, + {0, 1393}, + {0, 3500}, + {0, 2939}, + {0, 1406}, + {0, 185}, + {0, 110}, + {0, 1619}, + {0, 2630}, + {0, 1260}, + {0, 3127}, + {0, 2312}, + {0, 367}, + {0, 2204}, + {0, 2323}, + {0, 3281}, + {0, 2835}, + {4812, 1}, + {1596, 196}, + {45, 169}, + {1562, 4}, + {682, 163}, + {27, 157}, + {276, 80}, + {94, 139}, + {2051, 213}, + {35, 76}, + {269, 150}, + {806, 212}, + {1725, 19}, + {923, 360}, + {805, 206}, + {17, 89}, + {715, 21}, + {835, 265}, + {155, 350}, + {212, 1141}, + {1209, 387}, + {708, 529}, + {542, 1546}, + {4924, 1}, + {5126, 1}, + {3481, 874}, + {1642, 352}, + {3158, 3415}, + {3788, 2459}, + {3964, 3626}, + {124, 1026}, + {1317, 3091}, + {4799, 1}, + {4846, 1}, + {4920, 1}, + {1553, 2446}, + {1753, 3865}, + {2534, 835}, + {2539, 3898}, + {831, 1382}, + {4177, 2512}, + {397, 196}, + {41, 158}, + {66, 48}, + {36, 187}, + {157, 163}, + {788, 55}, + {64, 22}, + {184, 160}, + {337, 397}, + {732, 54}, + {199, 80}, + {630, 139}, + {133, 213}, + {51, 76}, + {1086, 150}, + {1, 212}, + {888, 19}, + {250, 67}, + {4183, 3652}, + {1190, 3266}, + {54, 254}, + {812, 341}, + {177, 27}, + {1128, 6}, + {1185, 112}, + {780, 927}, + {2651, 94}, + {1020, 369}, + {48, 533}, + {532, 186}, + {411, 726}, + {944, 1575}, + {39, 484}, + {1094, 2239}, + {632, 351}, + {4035, 94}, + {787, 123}, + {1598, 887}, + {794, 314}, + {673, 697}, + {1241, 258}, + {1713, 807}, + {2019, 63}, + {545, 274}, + {83, 254}, + {299, 341}, + {453, 27}, + {740, 6}, + {1062, 112}, + {955, 927}, + {763, 94}, + {1226, 369}, + {2432, 533}, + {902, 186}, + {455, 726}, + {1299, 1575}, + {1940, 484}, + {1737, 2239}, + {203, 351}, + {2944, 123}, + {1161, 123}, + {547, 887}, + {877, 314}, + {1022, 697}, + {889, 258}, + {1256, 807}, + {1064, 63}, + {1674, 544}, + {3333, 6}, + {256, 94}, + {4495, 533}, + {1342, 697}, + {3444, 351}, + {1670, 15}, + {3311, 94}, + {3623, 6}, + {2109, 94}, + {1108, 533}, + {2782, 697}, + {2135, 351}, + {4124, 15}, + {1007, 94}, + {760, 6}, + {1609, 94}, + {1722, 533}, + {2562, 697}, + {1881, 351}, + {4636, 15}, + {1711, 94}, + {1088, 6}, + {4012, 94}, + {725, 533}, + {1588, 697}, + {1764, 351}, + {2499, 15}, + {1578, 94}, + {3250, 6}, + {539, 94}, + {4440, 533}, + {271, 697}, + {4733, 351}, + {2833, 15}, + {2676, 1350}, + {1910, 1350}, + {3447, 402}, + {1984, 713}, + {1987, 488}, + {3763, 1235}, + {1251, 1229}, + {2737, 1301}, + {2381, 266}, + {3026, 2173}, + {2156, 633}, + {150, 848}, + {619, 925}, + {3853, 2449}, + {4507, 2058}, + {1716, 1143}, + {3361, 612}, + {678, 652}, + {4405, 876}, + {305, 1317}, + {4635, 681}, + {2872, 1774}, + {2761, 417}, + {1788, 2208}, + {2136, 890}, + {3897, 1612}, + {1107, 1602}, + {2606, 476}, + {2229, 673}, + {2891, 68}, + {2004, 660}, + {330, 1674}, + {468, 3679}, + {3705, 1087}, + {654, 2779}, + {3528, 402}, + {1382, 713}, + {4522, 488}, + {183, 1235}, + {4209, 1229}, + {466, 1301}, + {2398, 266}, + {2017, 2173}, + {3443, 633}, + {3596, 848}, + {541, 925}, + {4220, 2058}, + {1675, 1143}, + {3203, 652}, + {1330, 1317}, + {3457, 681}, + {4067, 1774}, + {3694, 417}, + {488, 2208}, + {1246, 890}, + {2927, 1421}, + {1990, 1612}, + {3980, 2232}, + {853, 660}, + {3657, 75}, + {1123, 2598}, + {1785, 2640}, + {1374, 1487}, + {2873, 1080}, + {0, 3323}, + {0, 3691}, + {0, 1030}, + {0, 2009}, + {0, 144}, + {0, 3420}, + {0, 2479}, + {0, 787}, + {0, 3875}, + {0, 718}, + {0, 2253}, + {0, 2700}, + {0, 2089}, + {0, 1199}, + {0, 1376}, + {0, 2600}, + {0, 2636}, + {0, 810}, + {0, 3809}, + {0, 879}, + {0, 2417}, + {0, 2867}, + {0, 2075}, + {0, 961}, + {0, 1351}, + {0, 2515}, + {0, 3155}, + {0, 2060}, + {0, 2822}, + {0, 1988}, + {0, 3383}, + {0, 3747}, + {0, 818}, + {0, 1940}, + {172, 784}, + {2496, 509}, + {570, 409}, + {550, 74}, + {1278, 696}, + {868, 508}, + {669, 210}, + {2549, 145}, + {222, 1090}, + {2428, 238}, + {307, 865}, + {803, 1452}, + {572, 1057}, + {1954, 786}, + {19, 383}, + {924, 390}, + {102, 204}, + {59, 11}, + {656, 285}, + {1100, 70}, + {1726, 936}, + {716, 126}, + {195, 375}, + {773, 1256}, + {154, 135}, + {3407, 39}, + {431, 218}, + {2598, 2554}, + {378, 1243}, + {1820, 1470}, + {74, 262}, + {1637, 898}, + {1730, 2}, + {4327, 1567}, + {423, 3833}, + {4554, 3394}, + {28, 307}, + {2166, 1411}, + {2347, 1184}, + {3098, 3712}, + {2976, 1768}, + {1313, 3343}, + {3742, 296}, + {4295, 3085}, + {1075, 593}, + {7, 703}, + {3136, 1288}, + {1921, 1415}, + {4486, 1502}, + {560, 994}, + {4697, 365}, + {220, 781}, + {2035, 1262}, + {2477, 2250}, + {3233, 827}, + {2356, 2369}, + {3982, 29}, + {915, 3501}, + {2928, 117}, + {2198, 2387}, + {2701, 1310}, + {2486, 1702}, + {449, 536}, + {208, 159}, + {4155, 3062}, + {4028, 305}, + {2262, 1945}, + {2664, 1889}, + {1196, 1873}, + {3868, 3263}, + {3412, 2045}, + {3220, 3}, + {1733, 196}, + {4524, 158}, + {197, 48}, + {3532, 57}, + {1554, 154}, + {3260, 187}, + {1937, 169}, + {1078, 119}, + {882, 167}, + {4737, 4}, + {4583, 163}, + {1656, 115}, + {3266, 55}, + {562, 22}, + {4492, 157}, + {217, 160}, + {4698, 397}, + {2792, 54}, + {2717, 80}, + {1879, 139}, + {4488, 213}, + {1542, 76}, + {3379, 150}, + {2, 212}, + {4585, 19}, + {443, 67}, + {4315, 2683}, + {2805, 2455}, + {1435, 1291}, + {4627, 448}, + {1865, 2703}, + {2634, 3423}, + {1660, 152}, + {2148, 2443}, + {1030, 3479}, + {3840, 3774}, + {605, 668}, + {505, 1106}, + {1338, 148}, + {3195, 768}, + {1681, 3950}, + {1285, 3019}, + {813, 1104}, + {4540, 588}, + {1583, 1414}, + {4368, 2138}, + {444, 707}, + {3113, 3866}, + {1770, 1648}, + {3377, 815}, + {1407, 2701}, + {929, 3627}, + {1091, 2279}, + {4279, 1268}, + {4281, 2399}, + {1332, 1108}, + {3542, 732}, + {267, 1172}, + {4736, 2620}, + {538, 3095}, + {4443, 1797}, + {2498, 649}, + {2963, 1565}, + {1589, 688}, + {1595, 1394}, + {4381, 3621}, + {428, 1142}, + {3105, 1500}, + {1782, 1294}, + {3388, 1714}, + {1401, 3028}, + {908, 3937}, + {1096, 2361}, + {4284, 1629}, + {4160, 3341}, + {2417, 1788}, + {2507, 1927}, + {1056, 523}, + {3730, 3120}, + {776, 1882}, + {4043, 1130}, + {3533, 2150}, + {602, 3946}, + {3263, 767}, + {1922, 2339}, + {3523, 2736}, + {1570, 2176}, + {750, 1132}, + {1221, 1433}, + {4425, 2654}, + {1071, 35}, + {1557, 3491}, + {2971, 195}, + {4135, 2688}, + {2371, 466}, + {2568, 3228}, + {1099, 376}, + {3761, 2900}, + {4019, 1407}, + {3513, 282}, + {3104, 2119}, + {2313, 2807}, + {4085, 2134}, + {798, 2772}, + {2819, 2187}, + {2531, 3897}, + {2303, 757}, + {553, 1750}, + {72, 462}, + {3989, 3213}, + {4708, 1050}, + {1818, 2279}, + {3129, 1675}, + {419, 2331}, + {4329, 775}, + {20, 138}, + {4562, 3496}, + {2575, 3689}, + {1693, 1220}, + {1916, 2147}, + {4671, 3314}, + {10, 425}, + {3387, 3254}, + {1403, 1882}, + {3118, 1364}, + {1765, 2476}, + {331, 3537}, + {4557, 72}, + {3367, 2122}, + {3133, 2213}, + {3902, 3210}, + {3993, 2901}, + {80, 1009}, + {4246, 1660}, + {1664, 2310}, + {3214, 721}, + {1351, 182}, + {3434, 3525}, + {4088, 2564}, + {3714, 3725}, + {473, 1175}, + {459, 3781}, + {3365, 1331}, + {1523, 2604}, + {4689, 1269}, + {327, 3582}, + {4341, 3113}, + {650, 534}, + {2230, 1703}, + {2124, 817}, + {3602, 870}, + {4263, 1307}, + {1669, 2641}, + {3206, 1152}, + {1343, 640}, + {4104, 2228}, + {3703, 3827}, + {465, 750}, + {2692, 552}, + {2234, 3221}, + {3674, 624}, + {1103, 3092}, + {3953, 2625}, + {874, 1314}, + {1513, 99}, + {1628, 2040}, + {2637, 2761}, + {3463, 3643}, + {404, 1669}, + {4406, 2223}, + {1836, 588}, + {3357, 3841}, + {1497, 3489}, + {3577, 65}, + {3935, 1313}, + {3857, 985}, + {622, 3560}, + {3696, 2191}, + {2062, 3278}, + {2989, 478}, + {995, 3320}, + {4077, 1932}, + {1296, 1434}, + {3191, 2509}, + {3599, 2737}, + {2155, 2073}, + {2020, 385}, + {1261, 2108}, + {2724, 2676}, + {2405, 47}, + {3062, 686}, + {2126, 3888}, + {169, 992}, + {655, 3272}, + {3836, 520}, + {1447, 1673}, + {3605, 2216}, + {289, 1604}, + {4653, 3856}, + {701, 3483}, + {4384, 69}, + {2636, 1302}, + {3019, 979}, + {1516, 3567}, + {1327, 2751}, + {4274, 364}, + {668, 3300}, + {3353, 437}, + {1833, 2974}, + {3582, 2534}, + {1491, 1466}, + {820, 211}, + {1289, 2197}, + {4370, 2841}, + {3082, 2758}, + {101, 427}, + {1614, 502}, + {3549, 1437}, + {1882, 1418}, + {1464, 246}, + {226, 2164}, + {3490, 3848}, + {429, 1441}, + {4380, 2456}, + {1802, 1389}, + {3301, 3639}, + {1533, 3279}, + {3626, 407}, + {3984, 1547}, + {3807, 691}, + {657, 3761}, + {677, 1209}, + {3554, 2371}, + {1322, 1579}, + {109, 924}, + {4235, 292}, + {515, 3404}, + {2414, 1044}, + {3495, 3547}, + {4374, 2350}, + {1790, 1507}, + {3304, 3744}, + {1547, 3385}, + {3817, 1125}, + {670, 3658}, + {818, 1748}, + {2519, 3421}, + {2409, 267}, + {3841, 3362}, + {1305, 1997}, + {4075, 1485}, + {998, 2359}, + {1326, 3330}, + {1842, 3030}, + {2743, 1858}, + {3632, 724}, + {589, 2467}, + {4208, 1425}, + {1636, 2532}, + {3168, 1005}, + {1383, 503}, + {3487, 3309}, + {4130, 2354}, + {3666, 3930}, + {497, 893}, + {2158, 174}, + {2894, 3463}, + {878, 82}, + {3946, 2714}, + {1106, 2241}, + {3671, 1597}, + {3476, 1829}, + {1963, 3047}, + {2102, 3511}, + {3873, 1837}, + {1179, 2958}, + {2632, 1892}, + {2278, 3303}, + {2870, 3716}, + {512, 172}, + {3649, 3398}, + {4369, 730}, + {1580, 2474}, + {3497, 1420}, + {137, 2524}, + {4537, 1014}, + {478, 498}, + {2742, 2343}, + {2904, 3924}, + {1328, 899}, + {1517, 1851}, + {463, 43}, + {3164, 3438}, + {1633, 2118}, + {3489, 1621}, + {1381, 2277}, + {1011, 3181}, + {1112, 2929}, + {4258, 1722}, + {1368, 225}, + {4308, 3058}, + {636, 1731}, + {3309, 3005}, + {1786, 541}, + {1538, 3586}, + {854, 2745}, + {1243, 3369}, + {4404, 18}, + {1724, 1585}, + {4514, 3575}, + {265, 1206}, + {3545, 3615}, + {1619, 1359}, + {3249, 1760}, + {1862, 3077}, + {4701, 1685}, + {4699, 2458}, + {1793, 762}, + {3115, 3843}, + {442, 670}, + {4312, 2225}, + {8, 2719}, + {4584, 2132}, + {2558, 1401}, + {1720, 2575}, + {1717, 1474}, + {4508, 3877}, + {279, 783}, + {3555, 3921}, + {1608, 1706}, + {3238, 2148}, + {1065, 3579}, + {961, 2516}, + {4692, 1341}, + {3765, 3295}, + {1989, 2110}, + {2926, 2738}, + {918, 2167}, + {4137, 3499}, + {1204, 3939}, + {3918, 776}, + {3124, 1712}, + {3510, 475}, + {1902, 2392}, + {4658, 1197}, + {73, 3583}, + {3404, 1115}, + {1455, 2606}, + {3093, 3007}, + {1698, 1736}, + {1191, 782}, + {799, 1489}, + {4559, 2269}, + {951, 601}, + {2299, 2036}, + {3743, 2844}, + {4040, 920}, + {781, 3830}, + {1602, 2915}, + {1706, 3223}, + {2581, 442}, + {2713, 1987}, + {1023, 3214}, + {2028, 3158}, + {2799, 1742}, + {2367, 1250}, + {2543, 2560}, + {4474, 3529}, + {4581, 2795}, + {774, 2137}, + {3358, 1188}, + {1715, 3591}, + {4271, 1122}, + {405, 2599}, + {4617, 3014}, + {56, 791}, + {3217, 3196}, + {282, 2000}, + {4598, 2872}, + {1450, 2081}, + {3402, 3419}, + {3870, 1865}, + {4024, 600}, + {3275, 3197}, + {366, 2001}, + {1398, 2080}, + {3398, 3417}, + {3108, 868}, + {3911, 1866}, + {4020, 599}, + {65, 2558}, + {530, 892}, + {4236, 3750}, + {1684, 826}, + {3188, 2341}, + {1321, 2833}, + {3466, 1985}, + {4080, 1016}, + {3687, 1275}, + {481, 2470}, + {484, 1698}, + {3392, 3669}, + {1535, 1069}, + {4664, 3721}, + {358, 1462}, + {4378, 1895}, + {612, 2961}, + {2238, 3791}, + {2145, 2297}, + {3587, 1561}, + {3595, 2217}, + {540, 1028}, + {4221, 3647}, + {1676, 971}, + {3202, 2450}, + {1329, 2941}, + {3456, 1857}, + {4066, 889}, + {487, 2365}, + {1026, 79}, + {2714, 2979}, + {2241, 1878}, + {3653, 2926}, + {1135, 423}, + {3987, 949}, + {834, 3654}, + {1525, 2886}, + {1653, 3458}, + {2625, 235}, + {3432, 1299}, + {368, 3762}, + {4397, 881}, + {1856, 3818}, + {3315, 1535}, + {3609, 2865}, + {3927, 3653}, + {3824, 2659}, + {642, 1440}, + {3702, 3363}, + {2073, 1819}, + {3016, 3036}, + {990, 1747}, + {4091, 3150}, + {1306, 3556}, + {3837, 1084}, + {3213, 2183}, + {2125, 3485}, + {1988, 3072}, + {3762, 208}, + {1250, 3401}, + {2736, 288}, + {2382, 2854}, + {2154, 1574}, + {148, 380}, + {620, 1814}, + {3852, 2954}, + {4222, 1308}, + {1427, 3767}, + {3593, 871}, + {324, 3811}, + {4625, 1545}, + {664, 2072}, + {4414, 2869}, + {2626, 3644}, + {2983, 2648}, + {1524, 1447}, + {1356, 224}, + {4305, 3057}, + {684, 1732}, + {3318, 3006}, + {1859, 542}, + {3608, 1113}, + {824, 2744}, + {1316, 3370}, + {4358, 17}, + {191, 1689}, + {3283, 3667}, + {1751, 1072}, + {416, 1464}, + {4549, 1900}, + {40, 2960}, + {2188, 3786}, + {2336, 2304}, + {3091, 1558}, + {699, 41}, + {3576, 2944}, + {1339, 699}, + {4498, 2893}, + {126, 379}, + {4256, 984}, + {500, 3680}, + {2436, 2855}, + {1976, 3486}, + {3485, 193}, + {3473, 3201}, + {410, 2005}, + {4361, 2868}, + {1825, 2082}, + {3634, 872}, + {3962, 1869}, + {3787, 592}, + {687, 3325}, + {695, 535}, + {3566, 2839}, + {1353, 1974}, + {4503, 2794}, + {115, 215}, + {4250, 843}, + {506, 3783}, + {2448, 2968}, + {1968, 3156}, + {2725, 2580}, + {883, 922}, + {3971, 3778}, + {2018, 858}, + {2880, 2376}, + {2228, 2806}, + {2608, 1950}, + {4354, 1048}, + {4521, 1233}, + {822, 2486}, + {519, 3510}, + {3425, 1828}, + {1482, 2971}, + {4630, 1898}, + {317, 3299}, + {4417, 3718}, + {660, 1062}, + {2277, 1972}, + {2112, 173}, + {3625, 3388}, + {1959, 1412}, + {3733, 3932}, + {1282, 698}, + {2760, 3868}, + {2420, 1641}, + {2999, 2094}, + {2105, 2698}, + {100, 3632}, + {679, 2469}, + {3820, 1270}, + {3045, 1422}, + {1008, 2517}, + {4132, 1017}, + {1271, 492}, + {3790, 3317}, + {3166, 2340}, + {3645, 3922}, + {2099, 894}, + {1355, 3517}, + {4297, 1835}, + {3321, 1884}, + {1850, 3305}, + {3614, 3713}, + {1456, 1068}, + {823, 1962}, + {1312, 168}, + {4351, 3392}, + {4230, 2457}, + {1428, 761}, + {3591, 3844}, + {311, 665}, + {4628, 2226}, + {659, 1183}, + {4418, 2126}, + {2633, 1159}, + {2993, 1402}, + {1537, 2573}, + {3274, 1112}, + {367, 2442} }; static const lxb_codepoint_t lxb_unicode_decomposition_cps[6982] = @@ -191096,7 +195657,7 @@ static const lxb_codepoint_t lxb_unicode_decomposition_cps[6982] = 0x4D56, 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x2A600 }; -static const lxb_codepoint_t lxb_unicode_idna_cps[5400] = +static const lxb_codepoint_t lxb_unicode_idna_cps[5428] = { 0x0073, 0x0073, 0x03C3, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, @@ -191477,9364 +196038,9397 @@ static const lxb_codepoint_t lxb_unicode_idna_cps[5400] = 0xA791, 0xA793, 0xA797, 0xA799, 0xA79B, 0xA79D, 0xA79F, 0xA7A1, 0xA7A3, 0xA7A5, 0xA7A7, 0xA7A9, 0x026C, 0x029E, 0x0287, 0xAB53, 0xA7B5, 0xA7B7, 0xA7B9, 0xA7BB, 0xA7BD, 0xA7BF, 0xA7C1, 0xA7C3, - 0xA794, 0x1D8E, 0xA7C8, 0xA7CA, 0x0264, 0xA7CD, 0xA7D1, 0xA7D7, - 0xA7D9, 0xA7DB, 0x019B, 0xA7F6, 0xAB37, 0xAB52, 0x028D, 0x13A0, - 0x13A1, 0x13A2, 0x13A3, 0x13A4, 0x13A5, 0x13A6, 0x13A7, 0x13A8, - 0x13A9, 0x13AA, 0x13AB, 0x13AC, 0x13AD, 0x13AE, 0x13AF, 0x13B0, - 0x13B1, 0x13B2, 0x13B3, 0x13B4, 0x13B5, 0x13B6, 0x13B7, 0x13B8, - 0x13B9, 0x13BA, 0x13BB, 0x13BC, 0x13BD, 0x13BE, 0x13BF, 0x13C0, - 0x13C1, 0x13C2, 0x13C3, 0x13C4, 0x13C5, 0x13C6, 0x13C7, 0x13C8, - 0x13C9, 0x13CA, 0x13CB, 0x13CC, 0x13CD, 0x13CE, 0x13CF, 0x13D0, - 0x13D1, 0x13D2, 0x13D3, 0x13D4, 0x13D5, 0x13D6, 0x13D7, 0x13D8, - 0x13D9, 0x13DA, 0x13DB, 0x13DC, 0x13DD, 0x13DE, 0x13DF, 0x13E0, - 0x13E1, 0x13E2, 0x13E3, 0x13E4, 0x13E5, 0x13E6, 0x13E7, 0x13E8, - 0x13E9, 0x13EA, 0x13EB, 0x13EC, 0x13ED, 0x13EE, 0x13EF, 0x8C48, - 0x66F4, 0x8CC8, 0x6ED1, 0x4E32, 0x53E5, 0x5951, 0x5587, 0x5948, - 0x61F6, 0x7669, 0x7F85, 0x863F, 0x87BA, 0x88F8, 0x908F, 0x6A02, - 0x6D1B, 0x70D9, 0x73DE, 0x843D, 0x916A, 0x99F1, 0x4E82, 0x5375, - 0x6B04, 0x721B, 0x862D, 0x9E1E, 0x5D50, 0x6FEB, 0x85CD, 0x8964, - 0x62C9, 0x81D8, 0x881F, 0x5ECA, 0x6717, 0x6D6A, 0x72FC, 0x90CE, - 0x4F86, 0x51B7, 0x52DE, 0x64C4, 0x6AD3, 0x7210, 0x76E7, 0x8606, - 0x865C, 0x8DEF, 0x9732, 0x9B6F, 0x9DFA, 0x788C, 0x797F, 0x7DA0, - 0x83C9, 0x9304, 0x8AD6, 0x58DF, 0x5F04, 0x7C60, 0x807E, 0x7262, - 0x78CA, 0x8CC2, 0x96F7, 0x58D8, 0x5C62, 0x6A13, 0x6DDA, 0x6F0F, - 0x7D2F, 0x7E37, 0x964B, 0x52D2, 0x808B, 0x51DC, 0x51CC, 0x7A1C, - 0x7DBE, 0x83F1, 0x9675, 0x8B80, 0x62CF, 0x8AFE, 0x4E39, 0x5BE7, - 0x6012, 0x7387, 0x7570, 0x5317, 0x78FB, 0x4FBF, 0x5FA9, 0x4E0D, - 0x6CCC, 0x6578, 0x7D22, 0x53C3, 0x585E, 0x7701, 0x8449, 0x8AAA, - 0x6BBA, 0x6C88, 0x62FE, 0x82E5, 0x63A0, 0x7565, 0x4EAE, 0x5169, - 0x51C9, 0x6881, 0x7CE7, 0x826F, 0x8AD2, 0x91CF, 0x52F5, 0x5442, - 0x5EEC, 0x65C5, 0x6FFE, 0x792A, 0x95AD, 0x9A6A, 0x9E97, 0x9ECE, - 0x66C6, 0x6B77, 0x8F62, 0x5E74, 0x6190, 0x6200, 0x649A, 0x6F23, - 0x7149, 0x7489, 0x79CA, 0x7DF4, 0x806F, 0x8F26, 0x84EE, 0x9023, - 0x934A, 0x5217, 0x52A3, 0x54BD, 0x70C8, 0x88C2, 0x5EC9, 0x5FF5, - 0x637B, 0x6BAE, 0x7C3E, 0x7375, 0x56F9, 0x5DBA, 0x601C, 0x73B2, - 0x7469, 0x7F9A, 0x8046, 0x9234, 0x96F6, 0x9748, 0x9818, 0x4F8B, - 0x79AE, 0x91B4, 0x96B8, 0x60E1, 0x4E86, 0x50DA, 0x5BEE, 0x5C3F, - 0x6599, 0x71CE, 0x7642, 0x84FC, 0x907C, 0x6688, 0x962E, 0x5289, - 0x677B, 0x67F3, 0x6D41, 0x6E9C, 0x7409, 0x7559, 0x786B, 0x7D10, - 0x985E, 0x622E, 0x9678, 0x502B, 0x5D19, 0x6DEA, 0x8F2A, 0x5F8B, - 0x6144, 0x6817, 0x9686, 0x5229, 0x540F, 0x5C65, 0x6613, 0x674E, - 0x68A8, 0x6CE5, 0x7406, 0x75E2, 0x7F79, 0x88CF, 0x88E1, 0x96E2, - 0x533F, 0x6EBA, 0x541D, 0x71D0, 0x7498, 0x85FA, 0x96A3, 0x9C57, - 0x9E9F, 0x6797, 0x6DCB, 0x81E8, 0x7B20, 0x7C92, 0x72C0, 0x7099, - 0x8B58, 0x4EC0, 0x8336, 0x523A, 0x5207, 0x5EA6, 0x62D3, 0x7CD6, - 0x5B85, 0x6D1E, 0x66B4, 0x8F3B, 0x964D, 0x5ED3, 0x5140, 0x55C0, - 0x585A, 0x6674, 0x51DE, 0x732A, 0x76CA, 0x793C, 0x795E, 0x7965, - 0x798F, 0x9756, 0x7CBE, 0x8612, 0x8AF8, 0x9038, 0x90FD, 0x98EF, - 0x98FC, 0x9928, 0x9DB4, 0x90DE, 0x96B7, 0x4FAE, 0x50E7, 0x514D, - 0x52C9, 0x52E4, 0x5351, 0x559D, 0x5606, 0x5668, 0x5840, 0x58A8, - 0x5C64, 0x6094, 0x6168, 0x618E, 0x61F2, 0x654F, 0x65E2, 0x6691, - 0x6885, 0x6D77, 0x6E1A, 0x6F22, 0x716E, 0x722B, 0x7422, 0x7891, - 0x7949, 0x7948, 0x7950, 0x7956, 0x798D, 0x798E, 0x7A40, 0x7A81, - 0x7BC0, 0x7E09, 0x7E41, 0x7F72, 0x8005, 0x81ED, 0x8279, 0x8457, - 0x8910, 0x8996, 0x8B01, 0x8B39, 0x8CD3, 0x8D08, 0x8FB6, 0x96E3, - 0x97FF, 0x983B, 0x6075, 0x242EE, 0x8218, 0x4E26, 0x51B5, 0x5168, - 0x4F80, 0x5145, 0x5180, 0x52C7, 0x52FA, 0x5555, 0x5599, 0x55E2, - 0x58B3, 0x5944, 0x5954, 0x5A62, 0x5B28, 0x5ED2, 0x5ED9, 0x5F69, - 0x5FAD, 0x60D8, 0x614E, 0x6108, 0x6160, 0x6234, 0x63C4, 0x641C, - 0x6452, 0x6556, 0x671B, 0x6756, 0x6EDB, 0x6ECB, 0x701E, 0x77A7, - 0x7235, 0x72AF, 0x7471, 0x7506, 0x753B, 0x761D, 0x761F, 0x76DB, - 0x76F4, 0x774A, 0x7740, 0x78CC, 0x7AB1, 0x7C7B, 0x7D5B, 0x7F3E, - 0x8352, 0x83EF, 0x8779, 0x8941, 0x8986, 0x8ABF, 0x8ACB, 0x8AED, - 0x8B8A, 0x8F38, 0x9072, 0x9199, 0x9276, 0x967C, 0x97DB, 0x980B, - 0x9B12, 0x2284A, 0x22844, 0x233D5, 0x3B9D, 0x4018, 0x4039, 0x25249, - 0x25CD0, 0x27ED3, 0x9F43, 0x9F8E, 0x0066, 0x0066, 0x0066, 0x0069, - 0x0066, 0x006C, 0x0066, 0x0066, 0x0069, 0x0066, 0x0066, 0x006C, - 0x0073, 0x0074, 0x0574, 0x0576, 0x0574, 0x0565, 0x0574, 0x056B, - 0x057E, 0x0576, 0x0574, 0x056D, 0x05D9, 0x05B4, 0x05F2, 0x05B7, - 0x05E2, 0x05D4, 0x05DB, 0x05DC, 0x05DD, 0x05E8, 0x05EA, 0x05E9, - 0x05C1, 0x05E9, 0x05C2, 0x05E9, 0x05BC, 0x05C1, 0x05E9, 0x05BC, - 0x05C2, 0x05D0, 0x05B7, 0x05D0, 0x05B8, 0x05D0, 0x05BC, 0x05D1, - 0x05BC, 0x05D2, 0x05BC, 0x05D3, 0x05BC, 0x05D4, 0x05BC, 0x05D5, - 0x05BC, 0x05D6, 0x05BC, 0x05D8, 0x05BC, 0x05D9, 0x05BC, 0x05DA, - 0x05BC, 0x05DB, 0x05BC, 0x05DC, 0x05BC, 0x05DE, 0x05BC, 0x05E0, - 0x05BC, 0x05E1, 0x05BC, 0x05E3, 0x05BC, 0x05E4, 0x05BC, 0x05E6, - 0x05BC, 0x05E7, 0x05BC, 0x05E8, 0x05BC, 0x05EA, 0x05BC, 0x05D5, - 0x05B9, 0x05D1, 0x05BF, 0x05DB, 0x05BF, 0x05E4, 0x05BF, 0x05D0, - 0x05DC, 0x0671, 0x067B, 0x067E, 0x0680, 0x067A, 0x067F, 0x0679, - 0x06A4, 0x06A6, 0x0684, 0x0683, 0x0686, 0x0687, 0x068D, 0x068C, - 0x068E, 0x0688, 0x0698, 0x0691, 0x06A9, 0x06AF, 0x06B3, 0x06B1, - 0x06BA, 0x06BB, 0x06C0, 0x06C1, 0x06BE, 0x06D2, 0x06D3, 0x06AD, - 0x06C6, 0x06C8, 0x06CB, 0x06C5, 0x06C9, 0x06D0, 0x0649, 0x0626, - 0x0627, 0x0626, 0x06D5, 0x0626, 0x0648, 0x0626, 0x06C7, 0x0626, - 0x06C6, 0x0626, 0x06C8, 0x0626, 0x06D0, 0x0626, 0x0649, 0x06CC, - 0x0626, 0x062C, 0x0626, 0x062D, 0x0626, 0x0645, 0x0626, 0x064A, - 0x0628, 0x062C, 0x0628, 0x062D, 0x0628, 0x062E, 0x0628, 0x0645, - 0x0628, 0x0649, 0x0628, 0x064A, 0x062A, 0x062C, 0x062A, 0x062D, - 0x062A, 0x062E, 0x062A, 0x0645, 0x062A, 0x0649, 0x062A, 0x064A, - 0x062B, 0x062C, 0x062B, 0x0645, 0x062B, 0x0649, 0x062B, 0x064A, - 0x062C, 0x062D, 0x062C, 0x0645, 0x062D, 0x062C, 0x062D, 0x0645, - 0x062E, 0x062C, 0x062E, 0x062D, 0x062E, 0x0645, 0x0633, 0x062C, - 0x0633, 0x062D, 0x0633, 0x062E, 0x0633, 0x0645, 0x0635, 0x062D, - 0x0635, 0x0645, 0x0636, 0x062C, 0x0636, 0x062D, 0x0636, 0x062E, - 0x0636, 0x0645, 0x0637, 0x062D, 0x0637, 0x0645, 0x0638, 0x0645, - 0x0639, 0x062C, 0x0639, 0x0645, 0x063A, 0x062C, 0x063A, 0x0645, - 0x0641, 0x062C, 0x0641, 0x062D, 0x0641, 0x062E, 0x0641, 0x0645, - 0x0641, 0x0649, 0x0641, 0x064A, 0x0642, 0x062D, 0x0642, 0x0645, - 0x0642, 0x0649, 0x0642, 0x064A, 0x0643, 0x0627, 0x0643, 0x062C, - 0x0643, 0x062D, 0x0643, 0x062E, 0x0643, 0x0644, 0x0643, 0x0645, - 0x0643, 0x0649, 0x0643, 0x064A, 0x0644, 0x062C, 0x0644, 0x062D, - 0x0644, 0x062E, 0x0644, 0x0645, 0x0644, 0x0649, 0x0644, 0x064A, - 0x0645, 0x062C, 0x0645, 0x062D, 0x0645, 0x062E, 0x0645, 0x0645, - 0x0645, 0x0649, 0x0645, 0x064A, 0x0646, 0x062C, 0x0646, 0x062D, - 0x0646, 0x062E, 0x0646, 0x0645, 0x0646, 0x0649, 0x0646, 0x064A, - 0x0647, 0x062C, 0x0647, 0x0645, 0x0647, 0x0649, 0x0647, 0x064A, - 0x064A, 0x062C, 0x064A, 0x062D, 0x064A, 0x062E, 0x064A, 0x0645, - 0x064A, 0x0649, 0x064A, 0x064A, 0x0630, 0x0670, 0x0631, 0x0670, - 0x0649, 0x0670, 0x0020, 0x064C, 0x0651, 0x0020, 0x064D, 0x0651, - 0x0020, 0x064E, 0x0651, 0x0020, 0x064F, 0x0651, 0x0020, 0x0650, - 0x0651, 0x0020, 0x0651, 0x0670, 0x0626, 0x0631, 0x0626, 0x0632, - 0x0626, 0x0646, 0x0628, 0x0631, 0x0628, 0x0632, 0x0628, 0x0646, - 0x062A, 0x0631, 0x062A, 0x0632, 0x062A, 0x0646, 0x062B, 0x0631, - 0x062B, 0x0632, 0x062B, 0x0646, 0x0645, 0x0627, 0x0646, 0x0631, - 0x0646, 0x0632, 0x0646, 0x0646, 0x064A, 0x0631, 0x064A, 0x0632, - 0x064A, 0x0646, 0x0626, 0x062E, 0x0626, 0x0647, 0x0628, 0x0647, - 0x062A, 0x0647, 0x0635, 0x062E, 0x0644, 0x0647, 0x0646, 0x0647, - 0x0647, 0x0670, 0x064A, 0x0647, 0x062B, 0x0647, 0x0633, 0x0647, - 0x0634, 0x0645, 0x0634, 0x0647, 0x0640, 0x064E, 0x0651, 0x0640, - 0x064F, 0x0651, 0x0640, 0x0650, 0x0651, 0x0637, 0x0649, 0x0637, - 0x064A, 0x0639, 0x0649, 0x0639, 0x064A, 0x063A, 0x0649, 0x063A, - 0x064A, 0x0633, 0x0649, 0x0633, 0x064A, 0x0634, 0x0649, 0x0634, - 0x064A, 0x062D, 0x0649, 0x062D, 0x064A, 0x062C, 0x0649, 0x062C, - 0x064A, 0x062E, 0x0649, 0x062E, 0x064A, 0x0635, 0x0649, 0x0635, - 0x064A, 0x0636, 0x0649, 0x0636, 0x064A, 0x0634, 0x062C, 0x0634, - 0x062D, 0x0634, 0x062E, 0x0634, 0x0631, 0x0633, 0x0631, 0x0635, - 0x0631, 0x0636, 0x0631, 0x0627, 0x064B, 0x062A, 0x062C, 0x0645, - 0x062A, 0x062D, 0x062C, 0x062A, 0x062D, 0x0645, 0x062A, 0x062E, - 0x0645, 0x062A, 0x0645, 0x062C, 0x062A, 0x0645, 0x062D, 0x062A, - 0x0645, 0x062E, 0x062C, 0x0645, 0x062D, 0x062D, 0x0645, 0x064A, - 0x062D, 0x0645, 0x0649, 0x0633, 0x062D, 0x062C, 0x0633, 0x062C, - 0x062D, 0x0633, 0x062C, 0x0649, 0x0633, 0x0645, 0x062D, 0x0633, - 0x0645, 0x062C, 0x0633, 0x0645, 0x0645, 0x0635, 0x062D, 0x062D, - 0x0635, 0x0645, 0x0645, 0x0634, 0x062D, 0x0645, 0x0634, 0x062C, - 0x064A, 0x0634, 0x0645, 0x062E, 0x0634, 0x0645, 0x0645, 0x0636, - 0x062D, 0x0649, 0x0636, 0x062E, 0x0645, 0x0637, 0x0645, 0x062D, - 0x0637, 0x0645, 0x0645, 0x0637, 0x0645, 0x064A, 0x0639, 0x062C, - 0x0645, 0x0639, 0x0645, 0x0645, 0x0639, 0x0645, 0x0649, 0x063A, - 0x0645, 0x0645, 0x063A, 0x0645, 0x064A, 0x063A, 0x0645, 0x0649, - 0x0641, 0x062E, 0x0645, 0x0642, 0x0645, 0x062D, 0x0642, 0x0645, - 0x0645, 0x0644, 0x062D, 0x0645, 0x0644, 0x062D, 0x064A, 0x0644, - 0x062D, 0x0649, 0x0644, 0x062C, 0x062C, 0x0644, 0x062E, 0x0645, - 0x0644, 0x0645, 0x062D, 0x0645, 0x062D, 0x062C, 0x0645, 0x062D, - 0x0645, 0x0645, 0x062D, 0x064A, 0x0645, 0x062C, 0x062D, 0x0645, - 0x062C, 0x0645, 0x0645, 0x062E, 0x062C, 0x0645, 0x062E, 0x0645, - 0x0645, 0x062C, 0x062E, 0x0647, 0x0645, 0x062C, 0x0647, 0x0645, - 0x0645, 0x0646, 0x062D, 0x0645, 0x0646, 0x062D, 0x0649, 0x0646, - 0x062C, 0x0645, 0x0646, 0x062C, 0x0649, 0x0646, 0x0645, 0x064A, - 0x0646, 0x0645, 0x0649, 0x064A, 0x0645, 0x0645, 0x0628, 0x062E, - 0x064A, 0x062A, 0x062C, 0x064A, 0x062A, 0x062C, 0x0649, 0x062A, - 0x062E, 0x064A, 0x062A, 0x062E, 0x0649, 0x062A, 0x0645, 0x064A, - 0x062A, 0x0645, 0x0649, 0x062C, 0x0645, 0x064A, 0x062C, 0x062D, - 0x0649, 0x062C, 0x0645, 0x0649, 0x0633, 0x062E, 0x0649, 0x0635, - 0x062D, 0x064A, 0x0634, 0x062D, 0x064A, 0x0636, 0x062D, 0x064A, - 0x0644, 0x062C, 0x064A, 0x0644, 0x0645, 0x064A, 0x064A, 0x062D, - 0x064A, 0x064A, 0x062C, 0x064A, 0x064A, 0x0645, 0x064A, 0x0645, - 0x0645, 0x064A, 0x0642, 0x0645, 0x064A, 0x0646, 0x062D, 0x064A, - 0x0639, 0x0645, 0x064A, 0x0643, 0x0645, 0x064A, 0x0646, 0x062C, - 0x062D, 0x0645, 0x062E, 0x064A, 0x0644, 0x062C, 0x0645, 0x0643, - 0x0645, 0x0645, 0x062C, 0x062D, 0x064A, 0x062D, 0x062C, 0x064A, - 0x0645, 0x062C, 0x064A, 0x0641, 0x0645, 0x064A, 0x0628, 0x062D, - 0x064A, 0x0633, 0x062E, 0x064A, 0x0646, 0x062C, 0x064A, 0x0635, - 0x0644, 0x06D2, 0x0642, 0x0644, 0x06D2, 0x0627, 0x0644, 0x0644, - 0x0647, 0x0627, 0x0643, 0x0628, 0x0631, 0x0645, 0x062D, 0x0645, - 0x062F, 0x0635, 0x0644, 0x0639, 0x0645, 0x0631, 0x0633, 0x0648, - 0x0644, 0x0639, 0x0644, 0x064A, 0x0647, 0x0648, 0x0633, 0x0644, - 0x0645, 0x0635, 0x0644, 0x0649, 0x0635, 0x0644, 0x0649, 0x0020, - 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, - 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, 0x062C, 0x0644, - 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, 0x0631, 0x06CC, - 0x0627, 0x0644, 0x002C, 0x3001, 0x3016, 0x3017, 0x2014, 0x2013, - 0x005F, 0x007B, 0x007D, 0x3014, 0x3015, 0x3010, 0x3011, 0x300A, - 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x005B, 0x005D, 0x0023, - 0x0026, 0x002A, 0x002D, 0x003C, 0x003E, 0x005C, 0x0024, 0x0025, - 0x0040, 0x0020, 0x064B, 0x0640, 0x064B, 0x0640, 0x0651, 0x0020, - 0x0652, 0x0640, 0x0652, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, - 0x0629, 0x062F, 0x0632, 0x0644, 0x0622, 0x0644, 0x0623, 0x0644, - 0x0625, 0x0644, 0x0627, 0x0022, 0x0027, 0x002F, 0x005E, 0x007C, - 0x007E, 0x2985, 0x2986, 0x30FB, 0x30A1, 0x30A3, 0x30A5, 0x30A7, - 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3, 0x30FC, 0x30F3, 0x3099, - 0x309A, 0x00A2, 0x00A3, 0x00AC, 0x00A6, 0x00A5, 0x20A9, 0x2502, - 0x2190, 0x2191, 0x2192, 0x2193, 0x25A0, 0x25CB, 0x10428, 0x10429, - 0x1042A, 0x1042B, 0x1042C, 0x1042D, 0x1042E, 0x1042F, 0x10430, 0x10431, - 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, 0x10438, 0x10439, - 0x1043A, 0x1043B, 0x1043C, 0x1043D, 0x1043E, 0x1043F, 0x10440, 0x10441, - 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, 0x10448, 0x10449, - 0x1044A, 0x1044B, 0x1044C, 0x1044D, 0x1044E, 0x1044F, 0x104D8, 0x104D9, - 0x104DA, 0x104DB, 0x104DC, 0x104DD, 0x104DE, 0x104DF, 0x104E0, 0x104E1, - 0x104E2, 0x104E3, 0x104E4, 0x104E5, 0x104E6, 0x104E7, 0x104E8, 0x104E9, - 0x104EA, 0x104EB, 0x104EC, 0x104ED, 0x104EE, 0x104EF, 0x104F0, 0x104F1, - 0x104F2, 0x104F3, 0x104F4, 0x104F5, 0x104F6, 0x104F7, 0x104F8, 0x104F9, - 0x104FA, 0x104FB, 0x10597, 0x10598, 0x10599, 0x1059A, 0x1059B, 0x1059C, - 0x1059D, 0x1059E, 0x1059F, 0x105A0, 0x105A1, 0x105A3, 0x105A4, 0x105A5, - 0x105A6, 0x105A7, 0x105A8, 0x105A9, 0x105AA, 0x105AB, 0x105AC, 0x105AD, - 0x105AE, 0x105AF, 0x105B0, 0x105B1, 0x105B3, 0x105B4, 0x105B5, 0x105B6, - 0x105B7, 0x105B8, 0x105B9, 0x105BB, 0x105BC, 0x02D0, 0x02D1, 0x0299, - 0x02A3, 0xAB66, 0x02A5, 0x02A4, 0x1D91, 0x0258, 0x025E, 0x02A9, - 0x0262, 0x029B, 0x029C, 0x0267, 0x0284, 0x02AA, 0x02AB, 0x1DF04, - 0xA78E, 0x026E, 0x1DF05, 0x028E, 0x1DF06, 0x0276, 0x0277, 0x027A, - 0x1DF08, 0x027E, 0x02A8, 0x02A6, 0xAB67, 0x02A7, 0x2C71, 0x028F, - 0x02A1, 0x02A2, 0x0298, 0x01C0, 0x01C1, 0x01C2, 0x1DF0A, 0x1DF1E, - 0x10CC0, 0x10CC1, 0x10CC2, 0x10CC3, 0x10CC4, 0x10CC5, 0x10CC6, 0x10CC7, - 0x10CC8, 0x10CC9, 0x10CCA, 0x10CCB, 0x10CCC, 0x10CCD, 0x10CCE, 0x10CCF, - 0x10CD0, 0x10CD1, 0x10CD2, 0x10CD3, 0x10CD4, 0x10CD5, 0x10CD6, 0x10CD7, - 0x10CD8, 0x10CD9, 0x10CDA, 0x10CDB, 0x10CDC, 0x10CDD, 0x10CDE, 0x10CDF, - 0x10CE0, 0x10CE1, 0x10CE2, 0x10CE3, 0x10CE4, 0x10CE5, 0x10CE6, 0x10CE7, - 0x10CE8, 0x10CE9, 0x10CEA, 0x10CEB, 0x10CEC, 0x10CED, 0x10CEE, 0x10CEF, - 0x10CF0, 0x10CF1, 0x10CF2, 0x10D70, 0x10D71, 0x10D72, 0x10D73, 0x10D74, - 0x10D75, 0x10D76, 0x10D77, 0x10D78, 0x10D79, 0x10D7A, 0x10D7B, 0x10D7C, - 0x10D7D, 0x10D7E, 0x10D7F, 0x10D80, 0x10D81, 0x10D82, 0x10D83, 0x10D84, - 0x10D85, 0x118C0, 0x118C1, 0x118C2, 0x118C3, 0x118C4, 0x118C5, 0x118C6, - 0x118C7, 0x118C8, 0x118C9, 0x118CA, 0x118CB, 0x118CC, 0x118CD, 0x118CE, - 0x118CF, 0x118D0, 0x118D1, 0x118D2, 0x118D3, 0x118D4, 0x118D5, 0x118D6, - 0x118D7, 0x118D8, 0x118D9, 0x118DA, 0x118DB, 0x118DC, 0x118DD, 0x118DE, - 0x118DF, 0x16E60, 0x16E61, 0x16E62, 0x16E63, 0x16E64, 0x16E65, 0x16E66, - 0x16E67, 0x16E68, 0x16E69, 0x16E6A, 0x16E6B, 0x16E6C, 0x16E6D, 0x16E6E, - 0x16E6F, 0x16E70, 0x16E71, 0x16E72, 0x16E73, 0x16E74, 0x16E75, 0x16E76, - 0x16E77, 0x16E78, 0x16E79, 0x16E7A, 0x16E7B, 0x16E7C, 0x16E7D, 0x16E7E, - 0x16E7F, 0x1D157, 0x1D165, 0x1D158, 0x1D165, 0x1D158, 0x1D165, 0x1D16E, - 0x1D158, 0x1D165, 0x1D16F, 0x1D158, 0x1D165, 0x1D170, 0x1D158, 0x1D165, - 0x1D171, 0x1D158, 0x1D165, 0x1D172, 0x1D1B9, 0x1D165, 0x1D1BA, 0x1D165, - 0x1D1B9, 0x1D165, 0x1D16E, 0x1D1BA, 0x1D165, 0x1D16E, 0x1D1B9, 0x1D165, - 0x1D16F, 0x1D1BA, 0x1D165, 0x1D16F, 0x0131, 0x0237, 0x2207, 0x2202, - 0x1E922, 0x1E923, 0x1E924, 0x1E925, 0x1E926, 0x1E927, 0x1E928, 0x1E929, - 0x1E92A, 0x1E92B, 0x1E92C, 0x1E92D, 0x1E92E, 0x1E92F, 0x1E930, 0x1E931, - 0x1E932, 0x1E933, 0x1E934, 0x1E935, 0x1E936, 0x1E937, 0x1E938, 0x1E939, - 0x1E93A, 0x1E93B, 0x1E93C, 0x1E93D, 0x1E93E, 0x1E93F, 0x1E940, 0x1E941, - 0x1E942, 0x1E943, 0x066E, 0x06A1, 0x066F, 0x0030, 0x002C, 0x0031, - 0x002C, 0x0032, 0x002C, 0x0033, 0x002C, 0x0034, 0x002C, 0x0035, - 0x002C, 0x0036, 0x002C, 0x0037, 0x002C, 0x0038, 0x002C, 0x0039, - 0x002C, 0x3014, 0x0073, 0x3015, 0x0077, 0x007A, 0x0068, 0x0076, - 0x0073, 0x0064, 0x0070, 0x0070, 0x0076, 0x0077, 0x0063, 0x006D, - 0x0063, 0x006D, 0x0064, 0x006D, 0x0072, 0x0064, 0x006A, 0x307B, - 0x304B, 0x30B3, 0x30B3, 0x5B57, 0x53CC, 0x591A, 0x89E3, 0x4EA4, - 0x6620, 0x7121, 0x524D, 0x5F8C, 0x518D, 0x65B0, 0x521D, 0x7D42, - 0x8CA9, 0x58F0, 0x5439, 0x6F14, 0x6295, 0x6355, 0x904A, 0x6307, - 0x6253, 0x7981, 0x7A7A, 0x5408, 0x6E80, 0x7533, 0x5272, 0x55B6, - 0x914D, 0x3014, 0x672C, 0x3015, 0x3014, 0x4E09, 0x3015, 0x3014, - 0x4E8C, 0x3015, 0x3014, 0x5B89, 0x3015, 0x3014, 0x70B9, 0x3015, - 0x3014, 0x6253, 0x3015, 0x3014, 0x76D7, 0x3015, 0x3014, 0x52DD, - 0x3015, 0x3014, 0x6557, 0x3015, 0x5F97, 0x53EF, 0x4E3D, 0x4E38, - 0x4E41, 0x20122, 0x4F60, 0x4FBB, 0x5002, 0x507A, 0x5099, 0x50CF, - 0x349E, 0x2063A, 0x5154, 0x5164, 0x5177, 0x2051C, 0x34B9, 0x5167, - 0x2054B, 0x5197, 0x51A4, 0x4ECC, 0x51AC, 0x291DF, 0x5203, 0x34DF, - 0x523B, 0x5246, 0x5277, 0x3515, 0x5305, 0x5306, 0x5349, 0x535A, - 0x5373, 0x537D, 0x537F, 0x20A2C, 0x7070, 0x53CA, 0x53DF, 0x20B63, - 0x53EB, 0x53F1, 0x5406, 0x549E, 0x5438, 0x5448, 0x5468, 0x54A2, - 0x54F6, 0x5510, 0x5553, 0x5563, 0x5584, 0x55AB, 0x55B3, 0x55C2, - 0x5716, 0x5717, 0x5651, 0x5674, 0x58EE, 0x57CE, 0x57F4, 0x580D, - 0x578B, 0x5832, 0x5831, 0x58AC, 0x214E4, 0x58F2, 0x58F7, 0x5906, - 0x5922, 0x5962, 0x216A8, 0x216EA, 0x59EC, 0x5A1B, 0x5A27, 0x59D8, - 0x5A66, 0x36EE, 0x36FC, 0x5B08, 0x5B3E, 0x219C8, 0x5BC3, 0x5BD8, - 0x5BF3, 0x21B18, 0x5BFF, 0x5C06, 0x5F53, 0x3781, 0x5C60, 0x5CC0, - 0x5C8D, 0x21DE4, 0x5D43, 0x21DE6, 0x5D6E, 0x5D6B, 0x5D7C, 0x5DE1, - 0x5DE2, 0x382F, 0x5DFD, 0x5E28, 0x5E3D, 0x5E69, 0x3862, 0x22183, - 0x387C, 0x5EB0, 0x5EB3, 0x5EB6, 0x2A392, 0x22331, 0x8201, 0x5F22, - 0x38C7, 0x232B8, 0x261DA, 0x5F62, 0x5F6B, 0x38E3, 0x5F9A, 0x5FCD, - 0x5FD7, 0x5FF9, 0x6081, 0x393A, 0x391C, 0x226D4, 0x60C7, 0x6148, - 0x614C, 0x617A, 0x61B2, 0x61A4, 0x61AF, 0x61DE, 0x6210, 0x621B, - 0x625D, 0x62B1, 0x62D4, 0x6350, 0x22B0C, 0x633D, 0x62FC, 0x6368, - 0x6383, 0x63E4, 0x22BF1, 0x6422, 0x63C5, 0x63A9, 0x3A2E, 0x6469, - 0x647E, 0x649D, 0x6477, 0x3A6C, 0x656C, 0x2300A, 0x65E3, 0x66F8, - 0x6649, 0x3B19, 0x3B08, 0x3AE4, 0x5192, 0x5195, 0x6700, 0x669C, - 0x80AD, 0x43D9, 0x6721, 0x675E, 0x6753, 0x233C3, 0x3B49, 0x67FA, - 0x6785, 0x6852, 0x2346D, 0x688E, 0x681F, 0x6914, 0x6942, 0x69A3, - 0x69EA, 0x6AA8, 0x236A3, 0x6ADB, 0x3C18, 0x6B21, 0x238A7, 0x6B54, - 0x3C4E, 0x6B72, 0x6B9F, 0x6BBB, 0x23A8D, 0x21D0B, 0x23AFA, 0x6C4E, - 0x23CBC, 0x6CBF, 0x6CCD, 0x6C67, 0x6D16, 0x6D3E, 0x6D69, 0x6D78, - 0x6D85, 0x23D1E, 0x6D34, 0x6E2F, 0x6E6E, 0x3D33, 0x6EC7, 0x23ED1, - 0x6DF9, 0x6F6E, 0x23F5E, 0x23F8E, 0x6FC6, 0x7039, 0x701B, 0x3D96, - 0x704A, 0x707D, 0x7077, 0x70AD, 0x20525, 0x7145, 0x24263, 0x719C, - 0x243AB, 0x7228, 0x7250, 0x24608, 0x7280, 0x7295, 0x24735, 0x24814, - 0x737A, 0x738B, 0x3EAC, 0x73A5, 0x3EB8, 0x7447, 0x745C, 0x7485, - 0x74CA, 0x3F1B, 0x7524, 0x24C36, 0x753E, 0x24C92, 0x2219F, 0x7610, - 0x24FA1, 0x24FB8, 0x25044, 0x3FFC, 0x4008, 0x250F3, 0x250F2, 0x25119, - 0x25133, 0x771E, 0x771F, 0x778B, 0x4046, 0x4096, 0x2541D, 0x784E, - 0x40E3, 0x25626, 0x2569A, 0x256C5, 0x79EB, 0x412F, 0x7A4A, 0x7A4F, - 0x2597C, 0x25AA7, 0x7AEE, 0x4202, 0x25BAB, 0x7BC6, 0x7BC9, 0x4227, - 0x25C80, 0x7CD2, 0x42A0, 0x7CE8, 0x7CE3, 0x7D00, 0x25F86, 0x7D63, - 0x4301, 0x7DC7, 0x7E02, 0x7E45, 0x4334, 0x26228, 0x26247, 0x4359, - 0x262D9, 0x7F7A, 0x2633E, 0x7F95, 0x7FFA, 0x264DA, 0x26523, 0x8060, - 0x265A8, 0x8070, 0x2335F, 0x43D5, 0x80B2, 0x8103, 0x440B, 0x813E, - 0x5AB5, 0x267A7, 0x267B5, 0x23393, 0x2339C, 0x8204, 0x8F9E, 0x446B, - 0x8291, 0x828B, 0x829D, 0x52B3, 0x82B1, 0x82B3, 0x82BD, 0x82E6, - 0x26B3C, 0x831D, 0x8363, 0x83AD, 0x8323, 0x83BD, 0x83E7, 0x8353, - 0x83CA, 0x83CC, 0x83DC, 0x26C36, 0x26D6B, 0x26CD5, 0x452B, 0x84F1, - 0x84F3, 0x8516, 0x273CA, 0x8564, 0x26F2C, 0x455D, 0x4561, 0x26FB1, - 0x270D2, 0x456B, 0x8650, 0x8667, 0x8669, 0x86A9, 0x8688, 0x870E, - 0x86E2, 0x8728, 0x876B, 0x8786, 0x45D7, 0x87E1, 0x8801, 0x45F9, - 0x8860, 0x27667, 0x88D7, 0x88DE, 0x4635, 0x88FA, 0x34BB, 0x278AE, - 0x27966, 0x46BE, 0x46C7, 0x8AA0, 0x27CA8, 0x8CAB, 0x8CC1, 0x8D1B, - 0x8D77, 0x27F2F, 0x20804, 0x8DCB, 0x8DBC, 0x8DF0, 0x208DE, 0x8ED4, - 0x285D2, 0x285ED, 0x9094, 0x90F1, 0x9111, 0x2872E, 0x911B, 0x9238, - 0x92D7, 0x92D8, 0x927C, 0x93F9, 0x9415, 0x28BFA, 0x958B, 0x4995, - 0x95B7, 0x28D77, 0x49E6, 0x96C3, 0x5DB2, 0x9723, 0x29145, 0x2921A, - 0x4A6E, 0x4A76, 0x97E0, 0x2940A, 0x4AB2, 0x29496, 0x9829, 0x295B6, - 0x98E2, 0x4B33, 0x9929, 0x99A7, 0x99C2, 0x99FE, 0x4BCE, 0x29B30, - 0x9C40, 0x9CFD, 0x4CCE, 0x4CED, 0x9D67, 0x2A0CE, 0x4CF8, 0x2A105, - 0x2A20E, 0x2A291, 0x4D56, 0x9EFE, 0x9F05, 0x9F0F, 0x9F16, 0x2A600 + 0xA794, 0x1D8E, 0xA7C8, 0xA7CA, 0x0264, 0xA7CD, 0xA7CF, 0xA7D1, + 0xA7D3, 0xA7D5, 0xA7D7, 0xA7D9, 0xA7DB, 0x019B, 0xA7F6, 0xAB37, + 0xAB52, 0x028D, 0x13A0, 0x13A1, 0x13A2, 0x13A3, 0x13A4, 0x13A5, + 0x13A6, 0x13A7, 0x13A8, 0x13A9, 0x13AA, 0x13AB, 0x13AC, 0x13AD, + 0x13AE, 0x13AF, 0x13B0, 0x13B1, 0x13B2, 0x13B3, 0x13B4, 0x13B5, + 0x13B6, 0x13B7, 0x13B8, 0x13B9, 0x13BA, 0x13BB, 0x13BC, 0x13BD, + 0x13BE, 0x13BF, 0x13C0, 0x13C1, 0x13C2, 0x13C3, 0x13C4, 0x13C5, + 0x13C6, 0x13C7, 0x13C8, 0x13C9, 0x13CA, 0x13CB, 0x13CC, 0x13CD, + 0x13CE, 0x13CF, 0x13D0, 0x13D1, 0x13D2, 0x13D3, 0x13D4, 0x13D5, + 0x13D6, 0x13D7, 0x13D8, 0x13D9, 0x13DA, 0x13DB, 0x13DC, 0x13DD, + 0x13DE, 0x13DF, 0x13E0, 0x13E1, 0x13E2, 0x13E3, 0x13E4, 0x13E5, + 0x13E6, 0x13E7, 0x13E8, 0x13E9, 0x13EA, 0x13EB, 0x13EC, 0x13ED, + 0x13EE, 0x13EF, 0x8C48, 0x66F4, 0x8CC8, 0x6ED1, 0x4E32, 0x53E5, + 0x5951, 0x5587, 0x5948, 0x61F6, 0x7669, 0x7F85, 0x863F, 0x87BA, + 0x88F8, 0x908F, 0x6A02, 0x6D1B, 0x70D9, 0x73DE, 0x843D, 0x916A, + 0x99F1, 0x4E82, 0x5375, 0x6B04, 0x721B, 0x862D, 0x9E1E, 0x5D50, + 0x6FEB, 0x85CD, 0x8964, 0x62C9, 0x81D8, 0x881F, 0x5ECA, 0x6717, + 0x6D6A, 0x72FC, 0x90CE, 0x4F86, 0x51B7, 0x52DE, 0x64C4, 0x6AD3, + 0x7210, 0x76E7, 0x8606, 0x865C, 0x8DEF, 0x9732, 0x9B6F, 0x9DFA, + 0x788C, 0x797F, 0x7DA0, 0x83C9, 0x9304, 0x8AD6, 0x58DF, 0x5F04, + 0x7C60, 0x807E, 0x7262, 0x78CA, 0x8CC2, 0x96F7, 0x58D8, 0x5C62, + 0x6A13, 0x6DDA, 0x6F0F, 0x7D2F, 0x7E37, 0x964B, 0x52D2, 0x808B, + 0x51DC, 0x51CC, 0x7A1C, 0x7DBE, 0x83F1, 0x9675, 0x8B80, 0x62CF, + 0x8AFE, 0x4E39, 0x5BE7, 0x6012, 0x7387, 0x7570, 0x5317, 0x78FB, + 0x4FBF, 0x5FA9, 0x4E0D, 0x6CCC, 0x6578, 0x7D22, 0x53C3, 0x585E, + 0x7701, 0x8449, 0x8AAA, 0x6BBA, 0x6C88, 0x62FE, 0x82E5, 0x63A0, + 0x7565, 0x4EAE, 0x5169, 0x51C9, 0x6881, 0x7CE7, 0x826F, 0x8AD2, + 0x91CF, 0x52F5, 0x5442, 0x5EEC, 0x65C5, 0x6FFE, 0x792A, 0x95AD, + 0x9A6A, 0x9E97, 0x9ECE, 0x66C6, 0x6B77, 0x8F62, 0x5E74, 0x6190, + 0x6200, 0x649A, 0x6F23, 0x7149, 0x7489, 0x79CA, 0x7DF4, 0x806F, + 0x8F26, 0x84EE, 0x9023, 0x934A, 0x5217, 0x52A3, 0x54BD, 0x70C8, + 0x88C2, 0x5EC9, 0x5FF5, 0x637B, 0x6BAE, 0x7C3E, 0x7375, 0x56F9, + 0x5DBA, 0x601C, 0x73B2, 0x7469, 0x7F9A, 0x8046, 0x9234, 0x96F6, + 0x9748, 0x9818, 0x4F8B, 0x79AE, 0x91B4, 0x96B8, 0x60E1, 0x4E86, + 0x50DA, 0x5BEE, 0x5C3F, 0x6599, 0x71CE, 0x7642, 0x84FC, 0x907C, + 0x6688, 0x962E, 0x5289, 0x677B, 0x67F3, 0x6D41, 0x6E9C, 0x7409, + 0x7559, 0x786B, 0x7D10, 0x985E, 0x622E, 0x9678, 0x502B, 0x5D19, + 0x6DEA, 0x8F2A, 0x5F8B, 0x6144, 0x6817, 0x9686, 0x5229, 0x540F, + 0x5C65, 0x6613, 0x674E, 0x68A8, 0x6CE5, 0x7406, 0x75E2, 0x7F79, + 0x88CF, 0x88E1, 0x96E2, 0x533F, 0x6EBA, 0x541D, 0x71D0, 0x7498, + 0x85FA, 0x96A3, 0x9C57, 0x9E9F, 0x6797, 0x6DCB, 0x81E8, 0x7B20, + 0x7C92, 0x72C0, 0x7099, 0x8B58, 0x4EC0, 0x8336, 0x523A, 0x5207, + 0x5EA6, 0x62D3, 0x7CD6, 0x5B85, 0x6D1E, 0x66B4, 0x8F3B, 0x964D, + 0x5ED3, 0x5140, 0x55C0, 0x585A, 0x6674, 0x51DE, 0x732A, 0x76CA, + 0x793C, 0x795E, 0x7965, 0x798F, 0x9756, 0x7CBE, 0x8612, 0x8AF8, + 0x9038, 0x90FD, 0x98EF, 0x98FC, 0x9928, 0x9DB4, 0x90DE, 0x96B7, + 0x4FAE, 0x50E7, 0x514D, 0x52C9, 0x52E4, 0x5351, 0x559D, 0x5606, + 0x5668, 0x5840, 0x58A8, 0x5C64, 0x6094, 0x6168, 0x618E, 0x61F2, + 0x654F, 0x65E2, 0x6691, 0x6885, 0x6D77, 0x6E1A, 0x6F22, 0x716E, + 0x722B, 0x7422, 0x7891, 0x7949, 0x7948, 0x7950, 0x7956, 0x798D, + 0x798E, 0x7A40, 0x7A81, 0x7BC0, 0x7E09, 0x7E41, 0x7F72, 0x8005, + 0x81ED, 0x8279, 0x8457, 0x8910, 0x8996, 0x8B01, 0x8B39, 0x8CD3, + 0x8D08, 0x8FB6, 0x96E3, 0x97FF, 0x983B, 0x6075, 0x242EE, 0x8218, + 0x4E26, 0x51B5, 0x5168, 0x4F80, 0x5145, 0x5180, 0x52C7, 0x52FA, + 0x5555, 0x5599, 0x55E2, 0x58B3, 0x5944, 0x5954, 0x5A62, 0x5B28, + 0x5ED2, 0x5ED9, 0x5F69, 0x5FAD, 0x60D8, 0x614E, 0x6108, 0x6160, + 0x6234, 0x63C4, 0x641C, 0x6452, 0x6556, 0x671B, 0x6756, 0x6EDB, + 0x6ECB, 0x701E, 0x77A7, 0x7235, 0x72AF, 0x7471, 0x7506, 0x753B, + 0x761D, 0x761F, 0x76DB, 0x76F4, 0x774A, 0x7740, 0x78CC, 0x7AB1, + 0x7C7B, 0x7D5B, 0x7F3E, 0x8352, 0x83EF, 0x8779, 0x8941, 0x8986, + 0x8ABF, 0x8ACB, 0x8AED, 0x8B8A, 0x8F38, 0x9072, 0x9199, 0x9276, + 0x967C, 0x97DB, 0x980B, 0x9B12, 0x2284A, 0x22844, 0x233D5, 0x3B9D, + 0x4018, 0x4039, 0x25249, 0x25CD0, 0x27ED3, 0x9F43, 0x9F8E, 0x0066, + 0x0066, 0x0066, 0x0069, 0x0066, 0x006C, 0x0066, 0x0066, 0x0069, + 0x0066, 0x0066, 0x006C, 0x0073, 0x0074, 0x0574, 0x0576, 0x0574, + 0x0565, 0x0574, 0x056B, 0x057E, 0x0576, 0x0574, 0x056D, 0x05D9, + 0x05B4, 0x05F2, 0x05B7, 0x05E2, 0x05D4, 0x05DB, 0x05DC, 0x05DD, + 0x05E8, 0x05EA, 0x05E9, 0x05C1, 0x05E9, 0x05C2, 0x05E9, 0x05BC, + 0x05C1, 0x05E9, 0x05BC, 0x05C2, 0x05D0, 0x05B7, 0x05D0, 0x05B8, + 0x05D0, 0x05BC, 0x05D1, 0x05BC, 0x05D2, 0x05BC, 0x05D3, 0x05BC, + 0x05D4, 0x05BC, 0x05D5, 0x05BC, 0x05D6, 0x05BC, 0x05D8, 0x05BC, + 0x05D9, 0x05BC, 0x05DA, 0x05BC, 0x05DB, 0x05BC, 0x05DC, 0x05BC, + 0x05DE, 0x05BC, 0x05E0, 0x05BC, 0x05E1, 0x05BC, 0x05E3, 0x05BC, + 0x05E4, 0x05BC, 0x05E6, 0x05BC, 0x05E7, 0x05BC, 0x05E8, 0x05BC, + 0x05EA, 0x05BC, 0x05D5, 0x05B9, 0x05D1, 0x05BF, 0x05DB, 0x05BF, + 0x05E4, 0x05BF, 0x05D0, 0x05DC, 0x0671, 0x067B, 0x067E, 0x0680, + 0x067A, 0x067F, 0x0679, 0x06A4, 0x06A6, 0x0684, 0x0683, 0x0686, + 0x0687, 0x068D, 0x068C, 0x068E, 0x0688, 0x0698, 0x0691, 0x06A9, + 0x06AF, 0x06B3, 0x06B1, 0x06BA, 0x06BB, 0x06C0, 0x06C1, 0x06BE, + 0x06D2, 0x06D3, 0x06AD, 0x06C6, 0x06C8, 0x06CB, 0x06C5, 0x06C9, + 0x06D0, 0x0649, 0x0626, 0x0627, 0x0626, 0x06D5, 0x0626, 0x0648, + 0x0626, 0x06C7, 0x0626, 0x06C6, 0x0626, 0x06C8, 0x0626, 0x06D0, + 0x0626, 0x0649, 0x06CC, 0x0626, 0x062C, 0x0626, 0x062D, 0x0626, + 0x0645, 0x0626, 0x064A, 0x0628, 0x062C, 0x0628, 0x062D, 0x0628, + 0x062E, 0x0628, 0x0645, 0x0628, 0x0649, 0x0628, 0x064A, 0x062A, + 0x062C, 0x062A, 0x062D, 0x062A, 0x062E, 0x062A, 0x0645, 0x062A, + 0x0649, 0x062A, 0x064A, 0x062B, 0x062C, 0x062B, 0x0645, 0x062B, + 0x0649, 0x062B, 0x064A, 0x062C, 0x062D, 0x062C, 0x0645, 0x062D, + 0x062C, 0x062D, 0x0645, 0x062E, 0x062C, 0x062E, 0x062D, 0x062E, + 0x0645, 0x0633, 0x062C, 0x0633, 0x062D, 0x0633, 0x062E, 0x0633, + 0x0645, 0x0635, 0x062D, 0x0635, 0x0645, 0x0636, 0x062C, 0x0636, + 0x062D, 0x0636, 0x062E, 0x0636, 0x0645, 0x0637, 0x062D, 0x0637, + 0x0645, 0x0638, 0x0645, 0x0639, 0x062C, 0x0639, 0x0645, 0x063A, + 0x062C, 0x063A, 0x0645, 0x0641, 0x062C, 0x0641, 0x062D, 0x0641, + 0x062E, 0x0641, 0x0645, 0x0641, 0x0649, 0x0641, 0x064A, 0x0642, + 0x062D, 0x0642, 0x0645, 0x0642, 0x0649, 0x0642, 0x064A, 0x0643, + 0x0627, 0x0643, 0x062C, 0x0643, 0x062D, 0x0643, 0x062E, 0x0643, + 0x0644, 0x0643, 0x0645, 0x0643, 0x0649, 0x0643, 0x064A, 0x0644, + 0x062C, 0x0644, 0x062D, 0x0644, 0x062E, 0x0644, 0x0645, 0x0644, + 0x0649, 0x0644, 0x064A, 0x0645, 0x062C, 0x0645, 0x062D, 0x0645, + 0x062E, 0x0645, 0x0645, 0x0645, 0x0649, 0x0645, 0x064A, 0x0646, + 0x062C, 0x0646, 0x062D, 0x0646, 0x062E, 0x0646, 0x0645, 0x0646, + 0x0649, 0x0646, 0x064A, 0x0647, 0x062C, 0x0647, 0x0645, 0x0647, + 0x0649, 0x0647, 0x064A, 0x064A, 0x062C, 0x064A, 0x062D, 0x064A, + 0x062E, 0x064A, 0x0645, 0x064A, 0x0649, 0x064A, 0x064A, 0x0630, + 0x0670, 0x0631, 0x0670, 0x0649, 0x0670, 0x0020, 0x064C, 0x0651, + 0x0020, 0x064D, 0x0651, 0x0020, 0x064E, 0x0651, 0x0020, 0x064F, + 0x0651, 0x0020, 0x0650, 0x0651, 0x0020, 0x0651, 0x0670, 0x0626, + 0x0631, 0x0626, 0x0632, 0x0626, 0x0646, 0x0628, 0x0631, 0x0628, + 0x0632, 0x0628, 0x0646, 0x062A, 0x0631, 0x062A, 0x0632, 0x062A, + 0x0646, 0x062B, 0x0631, 0x062B, 0x0632, 0x062B, 0x0646, 0x0645, + 0x0627, 0x0646, 0x0631, 0x0646, 0x0632, 0x0646, 0x0646, 0x064A, + 0x0631, 0x064A, 0x0632, 0x064A, 0x0646, 0x0626, 0x062E, 0x0626, + 0x0647, 0x0628, 0x0647, 0x062A, 0x0647, 0x0635, 0x062E, 0x0644, + 0x0647, 0x0646, 0x0647, 0x0647, 0x0670, 0x064A, 0x0647, 0x062B, + 0x0647, 0x0633, 0x0647, 0x0634, 0x0645, 0x0634, 0x0647, 0x0640, + 0x064E, 0x0651, 0x0640, 0x064F, 0x0651, 0x0640, 0x0650, 0x0651, + 0x0637, 0x0649, 0x0637, 0x064A, 0x0639, 0x0649, 0x0639, 0x064A, + 0x063A, 0x0649, 0x063A, 0x064A, 0x0633, 0x0649, 0x0633, 0x064A, + 0x0634, 0x0649, 0x0634, 0x064A, 0x062D, 0x0649, 0x062D, 0x064A, + 0x062C, 0x0649, 0x062C, 0x064A, 0x062E, 0x0649, 0x062E, 0x064A, + 0x0635, 0x0649, 0x0635, 0x064A, 0x0636, 0x0649, 0x0636, 0x064A, + 0x0634, 0x062C, 0x0634, 0x062D, 0x0634, 0x062E, 0x0634, 0x0631, + 0x0633, 0x0631, 0x0635, 0x0631, 0x0636, 0x0631, 0x0627, 0x064B, + 0x062A, 0x062C, 0x0645, 0x062A, 0x062D, 0x062C, 0x062A, 0x062D, + 0x0645, 0x062A, 0x062E, 0x0645, 0x062A, 0x0645, 0x062C, 0x062A, + 0x0645, 0x062D, 0x062A, 0x0645, 0x062E, 0x062C, 0x0645, 0x062D, + 0x062D, 0x0645, 0x064A, 0x062D, 0x0645, 0x0649, 0x0633, 0x062D, + 0x062C, 0x0633, 0x062C, 0x062D, 0x0633, 0x062C, 0x0649, 0x0633, + 0x0645, 0x062D, 0x0633, 0x0645, 0x062C, 0x0633, 0x0645, 0x0645, + 0x0635, 0x062D, 0x062D, 0x0635, 0x0645, 0x0645, 0x0634, 0x062D, + 0x0645, 0x0634, 0x062C, 0x064A, 0x0634, 0x0645, 0x062E, 0x0634, + 0x0645, 0x0645, 0x0636, 0x062D, 0x0649, 0x0636, 0x062E, 0x0645, + 0x0637, 0x0645, 0x062D, 0x0637, 0x0645, 0x0645, 0x0637, 0x0645, + 0x064A, 0x0639, 0x062C, 0x0645, 0x0639, 0x0645, 0x0645, 0x0639, + 0x0645, 0x0649, 0x063A, 0x0645, 0x0645, 0x063A, 0x0645, 0x064A, + 0x063A, 0x0645, 0x0649, 0x0641, 0x062E, 0x0645, 0x0642, 0x0645, + 0x062D, 0x0642, 0x0645, 0x0645, 0x0644, 0x062D, 0x0645, 0x0644, + 0x062D, 0x064A, 0x0644, 0x062D, 0x0649, 0x0644, 0x062C, 0x062C, + 0x0644, 0x062E, 0x0645, 0x0644, 0x0645, 0x062D, 0x0645, 0x062D, + 0x062C, 0x0645, 0x062D, 0x0645, 0x0645, 0x062D, 0x064A, 0x0645, + 0x062C, 0x062D, 0x0645, 0x062C, 0x0645, 0x0645, 0x062E, 0x062C, + 0x0645, 0x062E, 0x0645, 0x0645, 0x062C, 0x062E, 0x0647, 0x0645, + 0x062C, 0x0647, 0x0645, 0x0645, 0x0646, 0x062D, 0x0645, 0x0646, + 0x062D, 0x0649, 0x0646, 0x062C, 0x0645, 0x0646, 0x062C, 0x0649, + 0x0646, 0x0645, 0x064A, 0x0646, 0x0645, 0x0649, 0x064A, 0x0645, + 0x0645, 0x0628, 0x062E, 0x064A, 0x062A, 0x062C, 0x064A, 0x062A, + 0x062C, 0x0649, 0x062A, 0x062E, 0x064A, 0x062A, 0x062E, 0x0649, + 0x062A, 0x0645, 0x064A, 0x062A, 0x0645, 0x0649, 0x062C, 0x0645, + 0x064A, 0x062C, 0x062D, 0x0649, 0x062C, 0x0645, 0x0649, 0x0633, + 0x062E, 0x0649, 0x0635, 0x062D, 0x064A, 0x0634, 0x062D, 0x064A, + 0x0636, 0x062D, 0x064A, 0x0644, 0x062C, 0x064A, 0x0644, 0x0645, + 0x064A, 0x064A, 0x062D, 0x064A, 0x064A, 0x062C, 0x064A, 0x064A, + 0x0645, 0x064A, 0x0645, 0x0645, 0x064A, 0x0642, 0x0645, 0x064A, + 0x0646, 0x062D, 0x064A, 0x0639, 0x0645, 0x064A, 0x0643, 0x0645, + 0x064A, 0x0646, 0x062C, 0x062D, 0x0645, 0x062E, 0x064A, 0x0644, + 0x062C, 0x0645, 0x0643, 0x0645, 0x0645, 0x062C, 0x062D, 0x064A, + 0x062D, 0x062C, 0x064A, 0x0645, 0x062C, 0x064A, 0x0641, 0x0645, + 0x064A, 0x0628, 0x062D, 0x064A, 0x0633, 0x062E, 0x064A, 0x0646, + 0x062C, 0x064A, 0x0635, 0x0644, 0x06D2, 0x0642, 0x0644, 0x06D2, + 0x0627, 0x0644, 0x0644, 0x0647, 0x0627, 0x0643, 0x0628, 0x0631, + 0x0645, 0x062D, 0x0645, 0x062F, 0x0635, 0x0644, 0x0639, 0x0645, + 0x0631, 0x0633, 0x0648, 0x0644, 0x0639, 0x0644, 0x064A, 0x0647, + 0x0648, 0x0633, 0x0644, 0x0645, 0x0635, 0x0644, 0x0649, 0x0635, + 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, + 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, + 0x0645, 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, + 0x0647, 0x0631, 0x06CC, 0x0627, 0x0644, 0x002C, 0x3001, 0x3016, + 0x3017, 0x2014, 0x2013, 0x005F, 0x007B, 0x007D, 0x3014, 0x3015, + 0x3010, 0x3011, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, + 0x005B, 0x005D, 0x0023, 0x0026, 0x002A, 0x002D, 0x003C, 0x003E, + 0x005C, 0x0024, 0x0025, 0x0040, 0x0020, 0x064B, 0x0640, 0x064B, + 0x0640, 0x0651, 0x0020, 0x0652, 0x0640, 0x0652, 0x0621, 0x0622, + 0x0623, 0x0624, 0x0625, 0x0629, 0x062F, 0x0632, 0x0644, 0x0622, + 0x0644, 0x0623, 0x0644, 0x0625, 0x0644, 0x0627, 0x0022, 0x0027, + 0x002F, 0x005E, 0x007C, 0x007E, 0x2985, 0x2986, 0x30FB, 0x30A1, + 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3, + 0x30FC, 0x30F3, 0x3099, 0x309A, 0x00A2, 0x00A3, 0x00AC, 0x00A6, + 0x00A5, 0x20A9, 0x2502, 0x2190, 0x2191, 0x2192, 0x2193, 0x25A0, + 0x25CB, 0x10428, 0x10429, 0x1042A, 0x1042B, 0x1042C, 0x1042D, 0x1042E, + 0x1042F, 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, + 0x10437, 0x10438, 0x10439, 0x1043A, 0x1043B, 0x1043C, 0x1043D, 0x1043E, + 0x1043F, 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, + 0x10447, 0x10448, 0x10449, 0x1044A, 0x1044B, 0x1044C, 0x1044D, 0x1044E, + 0x1044F, 0x104D8, 0x104D9, 0x104DA, 0x104DB, 0x104DC, 0x104DD, 0x104DE, + 0x104DF, 0x104E0, 0x104E1, 0x104E2, 0x104E3, 0x104E4, 0x104E5, 0x104E6, + 0x104E7, 0x104E8, 0x104E9, 0x104EA, 0x104EB, 0x104EC, 0x104ED, 0x104EE, + 0x104EF, 0x104F0, 0x104F1, 0x104F2, 0x104F3, 0x104F4, 0x104F5, 0x104F6, + 0x104F7, 0x104F8, 0x104F9, 0x104FA, 0x104FB, 0x10597, 0x10598, 0x10599, + 0x1059A, 0x1059B, 0x1059C, 0x1059D, 0x1059E, 0x1059F, 0x105A0, 0x105A1, + 0x105A3, 0x105A4, 0x105A5, 0x105A6, 0x105A7, 0x105A8, 0x105A9, 0x105AA, + 0x105AB, 0x105AC, 0x105AD, 0x105AE, 0x105AF, 0x105B0, 0x105B1, 0x105B3, + 0x105B4, 0x105B5, 0x105B6, 0x105B7, 0x105B8, 0x105B9, 0x105BB, 0x105BC, + 0x02D0, 0x02D1, 0x0299, 0x02A3, 0xAB66, 0x02A5, 0x02A4, 0x1D91, + 0x0258, 0x025E, 0x02A9, 0x0262, 0x029B, 0x029C, 0x0267, 0x0284, + 0x02AA, 0x02AB, 0x1DF04, 0xA78E, 0x026E, 0x1DF05, 0x028E, 0x1DF06, + 0x0276, 0x0277, 0x027A, 0x1DF08, 0x027E, 0x02A8, 0x02A6, 0xAB67, + 0x02A7, 0x2C71, 0x028F, 0x02A1, 0x02A2, 0x0298, 0x01C0, 0x01C1, + 0x01C2, 0x1DF0A, 0x1DF1E, 0x10CC0, 0x10CC1, 0x10CC2, 0x10CC3, 0x10CC4, + 0x10CC5, 0x10CC6, 0x10CC7, 0x10CC8, 0x10CC9, 0x10CCA, 0x10CCB, 0x10CCC, + 0x10CCD, 0x10CCE, 0x10CCF, 0x10CD0, 0x10CD1, 0x10CD2, 0x10CD3, 0x10CD4, + 0x10CD5, 0x10CD6, 0x10CD7, 0x10CD8, 0x10CD9, 0x10CDA, 0x10CDB, 0x10CDC, + 0x10CDD, 0x10CDE, 0x10CDF, 0x10CE0, 0x10CE1, 0x10CE2, 0x10CE3, 0x10CE4, + 0x10CE5, 0x10CE6, 0x10CE7, 0x10CE8, 0x10CE9, 0x10CEA, 0x10CEB, 0x10CEC, + 0x10CED, 0x10CEE, 0x10CEF, 0x10CF0, 0x10CF1, 0x10CF2, 0x10D70, 0x10D71, + 0x10D72, 0x10D73, 0x10D74, 0x10D75, 0x10D76, 0x10D77, 0x10D78, 0x10D79, + 0x10D7A, 0x10D7B, 0x10D7C, 0x10D7D, 0x10D7E, 0x10D7F, 0x10D80, 0x10D81, + 0x10D82, 0x10D83, 0x10D84, 0x10D85, 0x118C0, 0x118C1, 0x118C2, 0x118C3, + 0x118C4, 0x118C5, 0x118C6, 0x118C7, 0x118C8, 0x118C9, 0x118CA, 0x118CB, + 0x118CC, 0x118CD, 0x118CE, 0x118CF, 0x118D0, 0x118D1, 0x118D2, 0x118D3, + 0x118D4, 0x118D5, 0x118D6, 0x118D7, 0x118D8, 0x118D9, 0x118DA, 0x118DB, + 0x118DC, 0x118DD, 0x118DE, 0x118DF, 0x16E60, 0x16E61, 0x16E62, 0x16E63, + 0x16E64, 0x16E65, 0x16E66, 0x16E67, 0x16E68, 0x16E69, 0x16E6A, 0x16E6B, + 0x16E6C, 0x16E6D, 0x16E6E, 0x16E6F, 0x16E70, 0x16E71, 0x16E72, 0x16E73, + 0x16E74, 0x16E75, 0x16E76, 0x16E77, 0x16E78, 0x16E79, 0x16E7A, 0x16E7B, + 0x16E7C, 0x16E7D, 0x16E7E, 0x16E7F, 0x16EBB, 0x16EBC, 0x16EBD, 0x16EBE, + 0x16EBF, 0x16EC0, 0x16EC1, 0x16EC2, 0x16EC3, 0x16EC4, 0x16EC5, 0x16EC6, + 0x16EC7, 0x16EC8, 0x16EC9, 0x16ECA, 0x16ECB, 0x16ECC, 0x16ECD, 0x16ECE, + 0x16ECF, 0x16ED0, 0x16ED1, 0x16ED2, 0x16ED3, 0x1D157, 0x1D165, 0x1D158, + 0x1D165, 0x1D158, 0x1D165, 0x1D16E, 0x1D158, 0x1D165, 0x1D16F, 0x1D158, + 0x1D165, 0x1D170, 0x1D158, 0x1D165, 0x1D171, 0x1D158, 0x1D165, 0x1D172, + 0x1D1B9, 0x1D165, 0x1D1BA, 0x1D165, 0x1D1B9, 0x1D165, 0x1D16E, 0x1D1BA, + 0x1D165, 0x1D16E, 0x1D1B9, 0x1D165, 0x1D16F, 0x1D1BA, 0x1D165, 0x1D16F, + 0x0131, 0x0237, 0x2207, 0x2202, 0x1E922, 0x1E923, 0x1E924, 0x1E925, + 0x1E926, 0x1E927, 0x1E928, 0x1E929, 0x1E92A, 0x1E92B, 0x1E92C, 0x1E92D, + 0x1E92E, 0x1E92F, 0x1E930, 0x1E931, 0x1E932, 0x1E933, 0x1E934, 0x1E935, + 0x1E936, 0x1E937, 0x1E938, 0x1E939, 0x1E93A, 0x1E93B, 0x1E93C, 0x1E93D, + 0x1E93E, 0x1E93F, 0x1E940, 0x1E941, 0x1E942, 0x1E943, 0x066E, 0x06A1, + 0x066F, 0x0030, 0x002C, 0x0031, 0x002C, 0x0032, 0x002C, 0x0033, + 0x002C, 0x0034, 0x002C, 0x0035, 0x002C, 0x0036, 0x002C, 0x0037, + 0x002C, 0x0038, 0x002C, 0x0039, 0x002C, 0x3014, 0x0073, 0x3015, + 0x0077, 0x007A, 0x0068, 0x0076, 0x0073, 0x0064, 0x0070, 0x0070, + 0x0076, 0x0077, 0x0063, 0x006D, 0x0063, 0x006D, 0x0064, 0x006D, + 0x0072, 0x0064, 0x006A, 0x307B, 0x304B, 0x30B3, 0x30B3, 0x5B57, + 0x53CC, 0x591A, 0x89E3, 0x4EA4, 0x6620, 0x7121, 0x524D, 0x5F8C, + 0x518D, 0x65B0, 0x521D, 0x7D42, 0x8CA9, 0x58F0, 0x5439, 0x6F14, + 0x6295, 0x6355, 0x904A, 0x6307, 0x6253, 0x7981, 0x7A7A, 0x5408, + 0x6E80, 0x7533, 0x5272, 0x55B6, 0x914D, 0x3014, 0x672C, 0x3015, + 0x3014, 0x4E09, 0x3015, 0x3014, 0x4E8C, 0x3015, 0x3014, 0x5B89, + 0x3015, 0x3014, 0x70B9, 0x3015, 0x3014, 0x6253, 0x3015, 0x3014, + 0x76D7, 0x3015, 0x3014, 0x52DD, 0x3015, 0x3014, 0x6557, 0x3015, + 0x5F97, 0x53EF, 0x4E3D, 0x4E38, 0x4E41, 0x20122, 0x4F60, 0x4FBB, + 0x5002, 0x507A, 0x5099, 0x50CF, 0x349E, 0x2063A, 0x5154, 0x5164, + 0x5177, 0x2051C, 0x34B9, 0x5167, 0x2054B, 0x5197, 0x51A4, 0x4ECC, + 0x51AC, 0x291DF, 0x5203, 0x34DF, 0x523B, 0x5246, 0x5277, 0x3515, + 0x5305, 0x5306, 0x5349, 0x535A, 0x5373, 0x537D, 0x537F, 0x20A2C, + 0x7070, 0x53CA, 0x53DF, 0x20B63, 0x53EB, 0x53F1, 0x5406, 0x549E, + 0x5438, 0x5448, 0x5468, 0x54A2, 0x54F6, 0x5510, 0x5553, 0x5563, + 0x5584, 0x55AB, 0x55B3, 0x55C2, 0x5716, 0x5717, 0x5651, 0x5674, + 0x58EE, 0x57CE, 0x57F4, 0x580D, 0x578B, 0x5832, 0x5831, 0x58AC, + 0x214E4, 0x58F2, 0x58F7, 0x5906, 0x5922, 0x5962, 0x216A8, 0x216EA, + 0x59EC, 0x5A1B, 0x5A27, 0x59D8, 0x5A66, 0x36EE, 0x36FC, 0x5B08, + 0x5B3E, 0x219C8, 0x5BC3, 0x5BD8, 0x5BF3, 0x21B18, 0x5BFF, 0x5C06, + 0x5F53, 0x3781, 0x5C60, 0x5CC0, 0x5C8D, 0x21DE4, 0x5D43, 0x21DE6, + 0x5D6E, 0x5D6B, 0x5D7C, 0x5DE1, 0x5DE2, 0x382F, 0x5DFD, 0x5E28, + 0x5E3D, 0x5E69, 0x3862, 0x22183, 0x387C, 0x5EB0, 0x5EB3, 0x5EB6, + 0x2A392, 0x22331, 0x8201, 0x5F22, 0x38C7, 0x232B8, 0x261DA, 0x5F62, + 0x5F6B, 0x38E3, 0x5F9A, 0x5FCD, 0x5FD7, 0x5FF9, 0x6081, 0x393A, + 0x391C, 0x226D4, 0x60C7, 0x6148, 0x614C, 0x617A, 0x61B2, 0x61A4, + 0x61AF, 0x61DE, 0x6210, 0x621B, 0x625D, 0x62B1, 0x62D4, 0x6350, + 0x22B0C, 0x633D, 0x62FC, 0x6368, 0x6383, 0x63E4, 0x22BF1, 0x6422, + 0x63C5, 0x63A9, 0x3A2E, 0x6469, 0x647E, 0x649D, 0x6477, 0x3A6C, + 0x656C, 0x2300A, 0x65E3, 0x66F8, 0x6649, 0x3B19, 0x3B08, 0x3AE4, + 0x5192, 0x5195, 0x6700, 0x669C, 0x80AD, 0x43D9, 0x6721, 0x675E, + 0x6753, 0x233C3, 0x3B49, 0x67FA, 0x6785, 0x6852, 0x2346D, 0x688E, + 0x681F, 0x6914, 0x6942, 0x69A3, 0x69EA, 0x6AA8, 0x236A3, 0x6ADB, + 0x3C18, 0x6B21, 0x238A7, 0x6B54, 0x3C4E, 0x6B72, 0x6B9F, 0x6BBB, + 0x23A8D, 0x21D0B, 0x23AFA, 0x6C4E, 0x23CBC, 0x6CBF, 0x6CCD, 0x6C67, + 0x6D16, 0x6D3E, 0x6D69, 0x6D78, 0x6D85, 0x23D1E, 0x6D34, 0x6E2F, + 0x6E6E, 0x3D33, 0x6EC7, 0x23ED1, 0x6DF9, 0x6F6E, 0x23F5E, 0x23F8E, + 0x6FC6, 0x7039, 0x701B, 0x3D96, 0x704A, 0x707D, 0x7077, 0x70AD, + 0x20525, 0x7145, 0x24263, 0x719C, 0x243AB, 0x7228, 0x7250, 0x24608, + 0x7280, 0x7295, 0x24735, 0x24814, 0x737A, 0x738B, 0x3EAC, 0x73A5, + 0x3EB8, 0x7447, 0x745C, 0x7485, 0x74CA, 0x3F1B, 0x7524, 0x24C36, + 0x753E, 0x24C92, 0x2219F, 0x7610, 0x24FA1, 0x24FB8, 0x25044, 0x3FFC, + 0x4008, 0x250F3, 0x250F2, 0x25119, 0x25133, 0x771E, 0x771F, 0x778B, + 0x4046, 0x4096, 0x2541D, 0x784E, 0x40E3, 0x25626, 0x2569A, 0x256C5, + 0x79EB, 0x412F, 0x7A4A, 0x7A4F, 0x2597C, 0x25AA7, 0x7AEE, 0x4202, + 0x25BAB, 0x7BC6, 0x7BC9, 0x4227, 0x25C80, 0x7CD2, 0x42A0, 0x7CE8, + 0x7CE3, 0x7D00, 0x25F86, 0x7D63, 0x4301, 0x7DC7, 0x7E02, 0x7E45, + 0x4334, 0x26228, 0x26247, 0x4359, 0x262D9, 0x7F7A, 0x2633E, 0x7F95, + 0x7FFA, 0x264DA, 0x26523, 0x8060, 0x265A8, 0x8070, 0x2335F, 0x43D5, + 0x80B2, 0x8103, 0x440B, 0x813E, 0x5AB5, 0x267A7, 0x267B5, 0x23393, + 0x2339C, 0x8204, 0x8F9E, 0x446B, 0x8291, 0x828B, 0x829D, 0x52B3, + 0x82B1, 0x82B3, 0x82BD, 0x82E6, 0x26B3C, 0x831D, 0x8363, 0x83AD, + 0x8323, 0x83BD, 0x83E7, 0x8353, 0x83CA, 0x83CC, 0x83DC, 0x26C36, + 0x26D6B, 0x26CD5, 0x452B, 0x84F1, 0x84F3, 0x8516, 0x273CA, 0x8564, + 0x26F2C, 0x455D, 0x4561, 0x26FB1, 0x270D2, 0x456B, 0x8650, 0x8667, + 0x8669, 0x86A9, 0x8688, 0x870E, 0x86E2, 0x8728, 0x876B, 0x8786, + 0x45D7, 0x87E1, 0x8801, 0x45F9, 0x8860, 0x27667, 0x88D7, 0x88DE, + 0x4635, 0x88FA, 0x34BB, 0x278AE, 0x27966, 0x46BE, 0x46C7, 0x8AA0, + 0x27CA8, 0x8CAB, 0x8CC1, 0x8D1B, 0x8D77, 0x27F2F, 0x20804, 0x8DCB, + 0x8DBC, 0x8DF0, 0x208DE, 0x8ED4, 0x285D2, 0x285ED, 0x9094, 0x90F1, + 0x9111, 0x2872E, 0x911B, 0x9238, 0x92D7, 0x92D8, 0x927C, 0x93F9, + 0x9415, 0x28BFA, 0x958B, 0x4995, 0x95B7, 0x28D77, 0x49E6, 0x96C3, + 0x5DB2, 0x9723, 0x29145, 0x2921A, 0x4A6E, 0x4A76, 0x97E0, 0x2940A, + 0x4AB2, 0x29496, 0x9829, 0x295B6, 0x98E2, 0x4B33, 0x9929, 0x99A7, + 0x99C2, 0x99FE, 0x4BCE, 0x29B30, 0x9C40, 0x9CFD, 0x4CCE, 0x4CED, + 0x9D67, 0x2A0CE, 0x4CF8, 0x2A105, 0x2A20E, 0x2A291, 0x4D56, 0x9EFE, + 0x9F05, 0x9F0F, 0x9F16, 0x2A600 }; -static const lxb_unicode_normalization_entry_t lxb_unicode_normalization_entries[5131] = +static const lxb_unicode_normalization_entry_t lxb_unicode_normalization_entries[5132] = { {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6059, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5504, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4812, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4882, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4874, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2433, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3178, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6472, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4700, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6122, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6482, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4606, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1637, 276}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6950, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6930, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2888, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 549, 104}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1703, 292}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1372, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1788, 307}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4380, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6186, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1457, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5316, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4736, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1710, 295}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5746, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4486, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4806, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1841, 314}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4752, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1878, 327}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1040, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 413, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5411, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6818, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 350, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2900, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 683, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1243, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6335, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2942, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1700, 291}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2843, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3566, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4702, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 76, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6050, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4338, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1400, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3403, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6897, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2888, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6031, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6807, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 316, 92}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6049, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6486, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6746, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6172, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 906, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6176, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6019, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2750, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6040, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1267, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2245, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6952, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5272, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 286, 85}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4508, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3096, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1370, 260}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1061, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6762, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6552, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6057, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5920, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6427, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3566, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4532, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1804, 309}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 117}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 204, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2702, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5310, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 677, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2790, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6830, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4653, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1333, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3030, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6703, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 338, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6719, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4638, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3124, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4538, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6156, 457}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6640, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4506, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1850, 317}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3424, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1869, 324}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1627, 272}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2638, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4563, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4514, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 431, 101}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5280, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4416, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6085, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4342, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6083, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4733, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6904, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2309, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 202, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1448, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1861, 321}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1856, 319}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 871, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6870, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3442, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 416, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6826, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1656, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6572, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2233, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4359, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 340, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3028, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2400, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4804, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 18, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4830, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6897, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 739, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3688, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1610, 266}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 419, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1630, 273}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1847, 316}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3249, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2417, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4488, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2257, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3190, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4538, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6581, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1261, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4281, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2918, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 320, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4713, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3255, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2897, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3147, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 354, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6892, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 210, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2431, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1057, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2944, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4722, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1277, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4727, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1, 54}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6065, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 15, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1646, 279}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4607, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6033, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2092, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6601, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2886, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4780, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3080, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6107, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4392, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6727, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6470, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 314, 91}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4778, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 393, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1033, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3352, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6661, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4490, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3176, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6606, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4846, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 677, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4410, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 593, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2930, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6885, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3610, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6065, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 308, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5838, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4510, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 733, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4404, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4512, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3222, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4338, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2414, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2316, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3180, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1850, 317}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1406, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1146, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2260, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3433, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2333, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4877, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1223, 256}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3116, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 210, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 222, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 703, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4750, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2491, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6716, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 104, 73}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4317, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4683, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6804, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4734, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6702, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 58, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6910, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 4258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6680, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4714, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6655, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2421, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 78, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2846, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2804, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6039, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 434, 102}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1045, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1643, 278}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3020, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6170, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6686, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4888, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6724, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 332, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 76, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1273, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 8, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6649, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2950, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 407, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 441, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1684, 285}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6692, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4544, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6918, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4500, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2939, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1433, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4652, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4728, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 288, 86}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3222, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4593, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6739, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1859, 320}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6034, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4566, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 134, 79}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3164, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 312, 90}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4850, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4984, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3262, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6358, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1263, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 64, 64}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1608, 265}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4472, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5426, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 129}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1020, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1646, 279}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4764, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4496, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6553, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3170, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1883, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6511, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4739, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3046, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2391, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6277, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1847, 316}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6752, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3544, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4396, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1271, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 202, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4446, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2960, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1618, 269}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2033, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1806, 310}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2906, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2260, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4790, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1856, 319}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3142, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4640, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4514, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4788, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6178, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4812, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4407, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3112, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4368, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4582, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4863, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3403, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4354, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4572, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6109, 445}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6561, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6028, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1317, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6879, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1615, 268}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1341, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5489, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1790, 308}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4537, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 142, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2640, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4846, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5830, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4498, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4694, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2037, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 8, 5730, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2384, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1875, 326}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2690, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3518, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3421, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6575, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 82, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1630, 273}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3246, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 570, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5369, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6722, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1725, 300}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6436, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1494, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 264, 84}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 268, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 549, 104}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1697, 290}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6331, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5282, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3512, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4508, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3170, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6736, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 154, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6406, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3172, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2910, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4718, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1223, 256}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6561, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 535, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6708, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4903, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2864, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 116}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6703, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6028, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6816, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 434, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 416, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6906, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2939, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 725, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6923, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1368, 259}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6696, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6653, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4877, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6053, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3409, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6176, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4398, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6472, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6283, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2003, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4498, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1844, 315}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 110, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1141, 254}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 114, 75}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1183, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5797, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2342, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 375, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1488, 264}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4134, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1255, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1634, 275}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 62, 63}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2826, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6877, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1275, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4332, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4858, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 104, 73}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3174, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5504, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4401, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6673, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 666, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5435, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 32, 56}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6871, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2335, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6718, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6854, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1482, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2262, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1053, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6046, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6317, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3204, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5420, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3114, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6721, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 92, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1939, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3249, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2816, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4676, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3216, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2559, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6800, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2884, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6316, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4419, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4434, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4332, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4704, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6874, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4413, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1706, 293}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2511, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3540, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4386, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 395, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1722, 299}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1492, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6636, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3174, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4140, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 342, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 352, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6037, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3034, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1958, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4148, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2800, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4716, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4818, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1319, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 755, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6647, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6942, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 216, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6661, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1403, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6954, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 238, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4638, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6885, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3491, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2770, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4870, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4879, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4946, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6019, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4960, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4788, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 751, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3532, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4677, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4750, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4786, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 399, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3022, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2228, 334}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6698, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4886, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1955, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 422, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3590, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 434, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6892, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3012, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2877, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4277, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5609, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1506, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 124, 78}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3890, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4504, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6174, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3090, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2954, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6599, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2886, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3152, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2941, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6502, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3572, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6238, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4704, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5393, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1243, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4552, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6786, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6774, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2791, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6526, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1438, 262}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5474, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6172, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4486, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2784, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 162, 81}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6164, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 36, 59}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1670, 284}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2045, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 176, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6722, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4739, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 641, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5420, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6927, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1157, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1019, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3092, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 286, 85}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6478, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5585, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1105, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3526, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5591, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6122, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 332, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3034, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4721, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 42, 60}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2255, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2788, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3433, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1719, 298}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6880, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2092, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2156, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5369, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6178, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4550, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4686, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6770, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3080, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1124, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3427, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 557, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5221, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4655, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1863, 322}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1317, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 50, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5468, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 62, 63}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2780, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6858, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4374, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6682, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6882, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4816, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4569, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2423, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 154, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4581, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 296, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 96, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3112, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3379, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5752, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 282, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 212, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3415, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1427, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4563, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6652, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1772, 305}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1486, 263}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6298, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2852, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1688, 287}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6923, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6962, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2830, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6653, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6043, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6470, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2786, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1049, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3538, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 94, 72}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 178, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 401, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6599, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4464, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 541, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6957, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4714, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6713, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4593, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1442, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2118, 333}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6478, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6755, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4827, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1265, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1019, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6424, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6946, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4478, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4506, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 348, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2423, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4583, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2852, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1750, 303}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 2, 599, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6748, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2850, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 955, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1730, 302}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2986, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3799, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6259, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6581, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 168, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6686, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 751, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4575, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6714, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4784, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4275, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6320, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 18, 5712, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3544, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6840, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3514, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4652, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3945, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3885, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1333, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4110, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4532, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1612, 267}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 410, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2774, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3018, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6692, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3718, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6174, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 258, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6059, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6424, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4496, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3110, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6756, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1343, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6415, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 570, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2818, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4401, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4674, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1713, 296}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4340, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6349, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1275, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4510, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 428, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3212, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4468, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1472, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1446, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4942, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 208, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2923, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5278, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4547, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 128}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3282, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2333, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3582, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6948, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4636, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6190, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5582, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4752, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5510, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6812, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5320, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1640, 277}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6468, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1037, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6734, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1430, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6706, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1031, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6742, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2417, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6476, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4607, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5498, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4609, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 11, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6526, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3340, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3186, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6058, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4096, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 481, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2435, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 170, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1790, 308}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4702, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 82, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1754, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 72, 66}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6030, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6774, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4868, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2816, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3084, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4755, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6327, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 565, 106}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 819, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3076, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4874, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5941, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2414, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2780, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3036, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6045, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 70, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 332}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6790, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4730, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 304, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4189, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 88, 71}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2533, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4952, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2766, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 242, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6883, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4692, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4656, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6716, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 513, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5181, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2867, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6712, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6677, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2278, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 867, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2942, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4366, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 383, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2638, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2316, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 7, 3318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 218, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 262, 83}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6464, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1040, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 547, 103}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1033, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2871, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4569, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6874, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1490, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2930, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2503, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6438, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4501, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2147, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3696, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2900, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3457, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3704, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4746, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2902, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5331, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 214, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6636, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4526, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4682, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 350, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3168, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4873, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4710, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5408, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5221, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2435, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6591, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6039, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4561, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2806, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4073, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1776, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6563, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6882, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6843, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4625, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 310, 89}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6714, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6750, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6643, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3123, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1309, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6721, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6659, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 18, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 591, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3784, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6154, 456}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6514, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2846, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1427, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 108, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4384, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2912, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3040, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6277, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6085, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4458, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5621, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 10, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4108, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5265, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 93}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 404, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4786, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6873, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3180, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2358, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4755, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3550, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1478, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4587, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1612, 267}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6180, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1844, 315}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 330, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6457, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1359, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4926, 426}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 685, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3991, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3240, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6538, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1853, 318}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5389, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 843, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2499, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6268, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2084, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3659, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2910, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4491, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2934, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 900, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6746, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6241, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 431, 101}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 476, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5399, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6458, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 86, 69}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1700, 291}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4516, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6727, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 721, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4384, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3168, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3145, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6704, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1826, 311}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1255, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6585, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5353, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6566, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1893, 330}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4494, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4299, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4425, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4488, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6900, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4824, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6706, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 216, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6933, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5320, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4452, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4873, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4643, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 673, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6710, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4452, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2899, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3692, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6137, 453}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4850, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1710, 295}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2296, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1686, 286}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 300, 88}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6658, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6733, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3166, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3514, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 587, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5836, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4518, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2896, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6418, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2574, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6031, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5282, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2248, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5738, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 164, 82}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6572, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1668, 283}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4425, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6458, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 503, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 117}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4818, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2449, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4478, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 290, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6186, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4553, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6788, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2547, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6725, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 156, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6327, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4673, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 192, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4948, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2407, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4227, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6156, 457}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4632, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3142, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4725, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 767, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2342, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6053, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4780, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3088, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6720, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6559, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 108, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6483, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6748, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6947, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 575, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6734, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1488, 264}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1124, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2640, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6641, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5353, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2892, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 360, 96}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3243, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1454, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1632, 274}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1881, 328}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 583, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6927, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4354, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1708, 294}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6466, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6325, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4374, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2553, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2909, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 585, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2708, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2402, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6736, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1686, 286}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6674, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6550, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 882, 225}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1490, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3355, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1403, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6696, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4858, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1659, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1719, 298}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 348, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6670, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5369, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1506, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 64, 64}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1031, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 626, 126}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4836, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1885, 329}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1837, 312}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 395, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 316, 92}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 320, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1418, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2110, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2154, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1893, 330}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4716, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3116, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6111, 446}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3144, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6299, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 15, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 296, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 93}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 703, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 874, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1353, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1909, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4918, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 72, 66}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4778, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 342, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2125, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6946, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 413, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1430, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 419, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4084, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1939, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 713, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4894, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4658, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4843, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6864, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6752, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 242, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1235, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 0, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1241, 258}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2818, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3508, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6780, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4748, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1269, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2984, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 266, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2696, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4869, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 24, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5956, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6430, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 80, 67}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 262, 83}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5296, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5764, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3415, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 581, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4585, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 401, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6597, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2245, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 40, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4581, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1774, 306}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5259, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4718, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1656, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5540, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4712, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2969, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 930, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4476, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6690, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6952, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 218, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6944, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1374, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6569, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 88, 71}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2272, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4871, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4851, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2806, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3166, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6449, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2873, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3512, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6474, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 362, 97}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2330, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6682, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4641, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 186, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2883, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1688, 287}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3904, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4643, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3501, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4964, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 112, 74}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5429, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6397, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2690, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1323, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 865, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1872, 325}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1640, 277}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1374, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5866, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4673, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2553, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 425, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6957, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1059, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4347, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4549, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6829, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6283, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 116}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2405, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 941, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 697, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6432, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5408, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2428, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 150, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 491, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1325, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1875, 326}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 124, 78}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6568, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5561, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 246, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 861, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6335, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1448, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6518, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6579, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2926, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 172, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1670, 284}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3424, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1331, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1542, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4134, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6091, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3418, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6418, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1175, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3185, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 739, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6943, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6694, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4458, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4599, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5402, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4419, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3331, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4175, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4610, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1728, 301}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4559, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4555, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 272, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6061, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6071, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1654, 282}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6524, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5986, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2433, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1045, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1503, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6899, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4090, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5471, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6333, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 563, 105}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1053, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 78, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6051, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2059, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 404, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1722, 299}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4816, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3473, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3156, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 921, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3266, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6868, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1457, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4281, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 222, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 358, 95}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4590, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3430, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4730, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6654, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 683, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6482, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 675, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2864, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4428, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2984, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4701, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6851, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6715, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4487, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6749, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3108, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6864, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2770, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4853, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6256, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1327, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 60, 62}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1878, 327}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4728, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2684, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4596, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3130, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3358, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 156, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1826, 311}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 511, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3532, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4656, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6867, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1512, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1279, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3558, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 28, 55}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5300, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2407, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2912, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2272, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 266, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 354, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 114, 75}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3665, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4561, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6816, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4942, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 641, 127}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1027, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6954, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 719, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 399, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 240, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 957, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3526, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2405, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4962, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4640, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3767, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2820, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 943, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1442, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3400, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5085, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4688, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6502, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6942, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 30, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4869, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 268, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6625, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2262, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4740, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1311, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6850, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 122, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 40, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2319, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 112, 74}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 358, 95}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2785, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6130, 450}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2841, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 298, 87}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6638, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1143, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4946, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 439, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 733, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1618, 269}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4503, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4725, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4273, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2821, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1482, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4658, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6320, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 489, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6508, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6590, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1466, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6886, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4080, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2059, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2491, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2431, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5980, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 176, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 964, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6034, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5331, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 260, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4096, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6403, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2945, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2873, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 451, 100}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6474, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4317, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2458, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3098, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 166, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5582, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2547, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1153, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6607, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4960, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5373, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6973, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2118, 333}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3572, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2952, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3088, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4502, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3862, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3791, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4557, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1981, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3436, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3154, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6046, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3999, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2885, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4670, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4003, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5091, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 465, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6158, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 150, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4584, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6713, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6806, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6447, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6585, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3210, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4590, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 871, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1246, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4703, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4770, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1436, 261}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5462, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4351, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3202, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5259, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1323, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2267, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6740, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6073, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4888, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6539, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3112, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4035, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2897, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 110, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2927, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 597, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6268, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2084, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6544, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1194, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3548, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4390, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6697, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6883, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1750, 303}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4903, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2296, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1565, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4422, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4668, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3172, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3243, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 451, 100}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3036, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3016, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 749, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2376, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4053, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5417, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1652, 281}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 84, 68}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2255, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6932, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 387, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 21, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1668, 283}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2096, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 855, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 152, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4446, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1725, 300}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2702, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4736, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2964, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3146, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1454, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2123, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4244, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 587, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5840, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5766, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1239, 257}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4720, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3114, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6778, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 912, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3078, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5636, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6607, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 902, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2693, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4806, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6867, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6704, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3442, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 11, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4434, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6949, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2960, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4659, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6718, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4455, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 264, 84}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2863, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4661, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2962, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6464, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 26, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2882, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3700, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 874, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6808, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6105, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6612, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6071, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3418, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4625, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1774, 306}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1089, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6912, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1424, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4954, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4958, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6677, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5211, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 641, 127}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5268, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 356, 94}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1433, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 236, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4926, 426}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4649, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4505, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6436, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 964, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2943, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3801, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2840, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2425, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2460, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3771, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3885, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6656, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 254, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4540, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6554, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5820, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2911, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 581, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2257, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6670, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3306, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6406, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4599, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2451, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3298, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6688, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2265, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5450, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2829, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3646, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6490, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6690, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1691, 288}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5962, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4866, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4584, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 425, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1536, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6479, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 930, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1627, 272}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6865, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5353, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2458, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2327, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4970, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4509, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2923, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4550, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3920, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6819, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4492, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2714, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4404, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2932, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4800, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 136, 80}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3108, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 30, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2916, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1478, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 26, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2513, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3040, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 36, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4443, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6647, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 580, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1409, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6111, 446}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 725, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1418, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3165, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3148, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1146, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1654, 282}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2110, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4088, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 356, 94}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3266, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3046, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4366, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4997, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2800, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1728, 301}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5099, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3258, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6067, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3163, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6202, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1446, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1107, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6033, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4706, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4482, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 302, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 44, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2433, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6308, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 15, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 238, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1307, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6676, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1469, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1, 54}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6740, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3110, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 657, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3489, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3969, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1694, 289}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1866, 323}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6623, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4208, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4476, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2648, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3187, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1741, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3070, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 898, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1500, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4802, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6137, 453}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4679, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 841, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4571, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4661, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 908, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3246, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 260, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4986, 0}, {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5093, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5262, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3597, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6709, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5429, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4703, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4756, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6884, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3985, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6238, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 924, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2096, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 977, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4809, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4962, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2774, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4577, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 589, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6299, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6563, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 180, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 910, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6151, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2961, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4522, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6300, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 689, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2881, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 168, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3146, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3704, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6788, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4464, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6903, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 84, 68}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6730, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5417, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6729, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 68, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6889, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2278, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 713, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1139, 253}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4719, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3193, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6901, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4724, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4271, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1233, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 128}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3282, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1460, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6352, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2352, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5923, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 152, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6038, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1363, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4053, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 138, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1839, 313}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3072, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6631, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1004, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4948, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2973, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2154, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4817, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 456, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6872, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2123, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6434, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4372, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2878, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2842, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5606, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 360, 96}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5151, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1716, 297}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1239, 257}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6810, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 48, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 919, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3848, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4468, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3787, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 128, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3136, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2944, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4526, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4826, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4688, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4060, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1335, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6323, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2830, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 116, 76}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6930, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4751, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 8, 5730, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 723, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4909, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2248, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6683, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1598, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 146, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3002, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2963, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6318, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3078, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2883, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3048, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2885, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2868, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6609, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4574, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3012, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3997, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 521, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2280, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4416, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2251, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5840, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 52, 61}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 36, 59}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 727, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 338, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 312, 90}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1881, 328}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2959, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3449, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4606, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4431, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2906, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3720, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3090, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4605, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3445, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 70, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 957, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1372, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6049, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 375, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1093, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4392, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 626, 126}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6022, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 352, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 300, 88}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4474, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6598, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3175, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5345, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1237, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3173, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6579, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4511, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4982, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5962, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2358, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4653, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6951, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2402, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4978, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5091, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2894, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 230, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5097, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 669, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 557, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3138, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4032, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2812, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2051, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4026, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6132, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2330, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4340, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6043, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4108, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6956, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5111, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4413, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5004, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5810, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4513, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4706, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5035, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 194, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6609, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5899, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 910, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5201, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2577, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 869, 221}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1017, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6900, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 170, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6523, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3209, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6804, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6462, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6735, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5923, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6544, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2952, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1637, 276}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1568, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1305, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 48, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5838, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 44, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6358, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4680, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2898, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 407, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4762, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3181, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4487, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4734, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1859, 320}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3136, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4601, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6676, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5414, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4407, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4511, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4708, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3741, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2087, 331}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4273, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2410, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6602, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3150, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4470, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6457, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3949, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1018, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3152, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 4258, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6573, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 280, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2924, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 284, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1703, 292}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 565, 106}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6555, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1634, 275}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6432, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5944, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1049, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5824, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5023, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 949, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 130, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6747, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 667, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5486, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 102, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1649, 280}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1643, 278}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6730, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6280, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1307, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2705, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2954, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5552, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6490, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3096, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6058, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 226, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6030, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2979, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6800, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1409, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3148, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1363, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4753, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1249, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1839, 313}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 637, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 449, 99}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 8, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1037, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 501, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6642, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4032, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6723, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3205, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1406, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3325, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5284, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6888, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4084, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 984, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6540, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4995, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4682, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4748, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4733, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5314, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6610, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2460, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6658, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 663, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6719, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4867, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6214, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4359, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5177, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6850, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3154, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6886, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6966, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4539, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4277, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3543, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1494, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3651, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4690, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 813, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 92, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 876, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 96, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 701, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1961, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6625, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5244, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1837, 312}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4680, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6587, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4326, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4879, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1279, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2267, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6590, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3436, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6306, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2918, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3688, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 727, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4507, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5300, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 897, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5127, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4654, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3406, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1281, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 4253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 882, 225}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 801, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2953, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 164, 82}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2909, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3799, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4774, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6818, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1565, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5341, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4647, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1600, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 978, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2858, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4767, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4505, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3654, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3092, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5552, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2955, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6894, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3753, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6797, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4623, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6700, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3122, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4545, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5219, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6643, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4917, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3156, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3430, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 162, 81}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6430, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2877, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3216, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4528, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4857, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6164, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2645, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 691, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4143, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6462, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6644, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1281, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4475, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 749, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5065, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4737, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1313, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3104, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2196, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5459, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3026, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3461, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6325, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3965, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2223, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 976, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4693, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5826, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 18, 5712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4279, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5185, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6312, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 897, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2346, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1834, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1015, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2974, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 15, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4727, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6937, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1708, 294}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5244, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4275, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 912, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6142, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2720, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6148, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2782, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 673, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6042, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3018, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1652, 281}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 226, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2801, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 2, 599, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1043, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2228, 334}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3406, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1415, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 32, 56}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6868, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 270, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6960, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3528, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4886, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1831, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6936, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2827, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 449, 99}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5141, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2339, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 364, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4715, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6925, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 4253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6527, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6292, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1472, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6764, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1863, 322}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1697, 290}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1309, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2940, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3678, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6673, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2913, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1303, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6247, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 144, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1624, 271}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3084, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4984, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6846, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6557, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4868, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 986, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1370, 260}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3070, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6208, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 984, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5709, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 178, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2205, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 397, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6833, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3985, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6587, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2280, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6813, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2949, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6305, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3066, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4535, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6780, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 543, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 863, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5375, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6220, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6849, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2328, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 807, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1606, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6289, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3671, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6397, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3564, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1385, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5591, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5159, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3457, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2398, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6027, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2276, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6083, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 715, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1141, 254}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5303, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6928, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6732, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4950, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3578, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 116, 76}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6948, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5147, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1885, 329}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4813, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4608, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5423, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6061, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1649, 280}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3592, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3343, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3199, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4698, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2891, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 687, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2190, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3162, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5770, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4572, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6910, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3854, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3373, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6688, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3890, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4782, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 443, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 940, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 980, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6909, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 142, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1632, 274}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6638, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5021, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1091, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6655, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1221, 255}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6700, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3622, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2018, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5615, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4620, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5268, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6421, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5393, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1512, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1684, 285}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1713, 296}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 622, 129}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1072, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6496, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1706, 293}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5387, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5123, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3298, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6486, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4313, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1127, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4113, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4710, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6766, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4666, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6438, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6778, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6286, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2376, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6400, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2431, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2082, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2866, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6627, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 188, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 174, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5938, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5468, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4852, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6958, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 988, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1012, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1861, 321}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4677, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2870, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5001, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4398, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6846, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4708, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2879, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 46, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1061, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6939, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4011, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5405, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6403, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2959, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1325, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6744, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4330, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5765, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4477, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 761, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1621, 270}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4342, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 60, 62}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1269, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4473, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5773, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4746, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4005, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2907, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4437, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2087, 331}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3052, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 859, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3617, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 24, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6857, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4594, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1814, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2921, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6679, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3169, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6547, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6838, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 184, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2793, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2183, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1327, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6854, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 370, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 547, 103}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1752, 304}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1524, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 595, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1562, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3568, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6786, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4368, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1596, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2972, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4603, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 50, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 232, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6262, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4537, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4918, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1086, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6593, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1241, 258}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2946, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 130, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5792, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4497, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5079, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6728, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6161, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3534, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1277, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5157, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2832, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4721, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6341, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6265, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2525, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2758, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1115, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 410, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2850, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6906, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6711, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1798, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4839, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6047, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5075, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5917, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3388, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4882, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6532, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3530, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2559, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2825, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3171, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6649, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 456, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4396, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 616, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6918, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5438, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1283, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 934, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 334, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4686, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2823, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1515, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5681, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4844, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2335, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2776, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1051, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2903, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2929, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5337, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4489, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3718, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6541, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6902, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1181, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1139, 253}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5067, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4944, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6826, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3140, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6875, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4639, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3493, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 250, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3164, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2750, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5083, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5014, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4297, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6888, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6055, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 598, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6045, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5215, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5752, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6217, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5745, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1560, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3708, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2994, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2295, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2895, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4480, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4819, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6087, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6672, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2190, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1415, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6962, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1841, 314}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5187, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6839, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3550, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4694, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4047, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 288, 86}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6680, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1752, 304}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6687, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1659, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6013, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 387, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 192, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6710, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 288, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2905, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5769, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5010, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6875, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2304, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3070, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6036, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2777, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 902, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1985, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6812, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1730, 302}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5179, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 314, 91}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4547, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 945, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6539, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3144, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4512, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3207, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2626, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6904, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1353, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2811, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2428, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2171, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3349, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2717, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6813, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6259, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4227, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6725, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1412, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 248, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4029, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2980, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 445, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2201, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1973, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1484, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4573, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3214, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5054, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5361, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2055, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1795, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1221, 255}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1063, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 639, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4990, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6794, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4649, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4712, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3098, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5016, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6569, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 529, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3206, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1017, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4102, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2149, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4662, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 916, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6064, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5738, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5833, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6154, 456}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2243, 335}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2726, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1025, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4311, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6158, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6557, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1283, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 463, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5231, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3117, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1444, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2763, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4697, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5253, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2892, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1105, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 707, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5441, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 21, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2315, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 57}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1804, 309}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5654, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 849, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2778, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4989, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5105, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5663, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6087, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2194, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 652, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4110, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 272, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 517, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5109, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 503, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 236, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6694, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4586, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6008, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3132, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 54, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5217, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6525, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5747, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4684, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1828, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3255, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5465, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 951, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2982, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6068, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6496, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3162, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 136, 80}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2866, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5689, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3074, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 86, 69}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5107, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6855, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6576, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6316, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1811, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1397, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 593, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6559, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 668, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5432, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5233, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1772, 305}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5808, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4860, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5426, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1738, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5851, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6947, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 383, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 4230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 24, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6772, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2037, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2768, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5121, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2778, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1014, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3181, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5999, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3485, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 757, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3000, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1209, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3633, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1246, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5241, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5402, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5835, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4825, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1321, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6847, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4519, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2933, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6735, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3044, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2899, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1337, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1004, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 52, 61}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3907, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NOBREAK, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2251, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5265, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6865, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6751, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3042, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6323, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3914, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6675, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6077, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6499, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2887, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2935, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4823, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5570, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 431, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4578, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3613, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2289, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3391, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5235, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 715, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5803, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1063, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5501, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1602, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5357, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4297, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4440, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3692, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3100, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4647, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4495, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1391, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6779, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2967, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 140, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6307, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2410, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5133, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 234, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6556, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4553, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4575, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6943, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4966, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3177, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6614, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 987, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3542, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4382, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5817, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6229, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 869, 221}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3062, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1099, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2922, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 379, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4670, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4551, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4803, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6514, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1438, 262}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2781, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5453, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1023, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6311, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5022, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2948, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1368, 259}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2802, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6530, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6555, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 685, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6467, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4601, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 250, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 186, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5456, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4060, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2843, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 160, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4692, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 182, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 531, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2874, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2045, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2213, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6660, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6020, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 605, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6317, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 650, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5986, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4283, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5705, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 641, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4470, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4860, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6337, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5697, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5968, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5331, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4864, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1271, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3552, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6915, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 651, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2819, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3508, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2120, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6672, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4690, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1249, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3150, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6142, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4695, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6960, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4899, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5371, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3076, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6017, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1385, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1806, 310}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1869, 324}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1321, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4881, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3358, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6646, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1548, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 100, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2509, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6660, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4917, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6955, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6853, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4080, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5790, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3538, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2893, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 362, 97}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6612, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4299, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2465, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5007, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 461, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5227, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6304, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4469, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5878, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2837, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6105, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4713, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3590, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 248, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 252, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2847, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5075, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 614, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6427, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2858, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6798, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5435, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5153, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6691, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5081, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 527, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5498, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3176, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 298, 87}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1463, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3325, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2287, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4557, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 515, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5396, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5256, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5447, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 783, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5450, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5262, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6550, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5555, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 106, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5540, 0}, - {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5893, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 274, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1057, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3822, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2125, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1335, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3804, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6595, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6493, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1394, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2789, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1005, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2254, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5381, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2327, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1691, 288}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2925, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5203, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 282, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6852, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 775, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1203, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2230, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3124, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5567, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6593, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2788, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4666, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5125, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1883, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6685, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5411, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3211, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4516, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1592, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5032, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6582, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1754, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4169, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3340, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4954, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1444, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4422, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6145, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5486, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 322, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1475, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4597, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6928, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4729, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5423, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 389, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 393, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1466, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6388, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3186, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 200, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6532, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3621, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5147, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6551, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4994, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 575, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2903, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4676, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3708, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5215, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 428, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4740, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 46, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5796, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5609, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2100, 332}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 134, 79}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2933, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6262, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2339, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6060, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1500, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6806, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1610, 266}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1665, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6799, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6415, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2645, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1043, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3064, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5999, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6180, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3002, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2290, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6773, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 434, 102}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3630, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5024, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2549, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4556, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 158, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 7, 3318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4915, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4700, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6052, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1545, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3632, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3562, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3122, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1020, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1159, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4587, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 777, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4131, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6834, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 94, 72}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3832, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3120, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6667, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 719, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6600, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 747, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5015, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5239, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6525, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4544, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3196, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6859, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3270, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4615, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2398, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4279, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5444, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 967, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4372, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6575, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5165, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1231, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5399, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5193, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2451, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3334, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4802, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4560, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5405, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 906, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 827, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5103, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1003, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6232, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 212, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1319, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1866, 323}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6679, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6958, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3995, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6516, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2992, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6755, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2315, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4793, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2955, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 904, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 166, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 485, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3030, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 246, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4017, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2288, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6412, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2913, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3671, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3042, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6481, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2291, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4566, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1621, 270}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2588, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3355, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1615, 268}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1608, 265}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3558, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3634, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4472, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4088, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4698, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 106, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5744, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6170, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5247, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4696, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5195, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 68, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3794, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2946, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6038, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 469, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 992, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 144, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 148, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5131, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3876, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1003, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2523, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4507, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6449, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3628, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6937, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2699, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4837, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4637, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 497, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 483, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6695, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2957, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3076, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6040, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2868, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6674, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6302, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5781, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2776, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2815, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 88, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4756, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 563, 105}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3427, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6873, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4929, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3134, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5760, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 6, 3822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1694, 289}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5044, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4934, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6652, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6809, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3048, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3624, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5272, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6553, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6095, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4655, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6922, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2936, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5829, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 122, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 184, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6905, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 180, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6715, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5073, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5534, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1345, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5183, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 895, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5828, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4998, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6789, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4490, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 681, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2911, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5633, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6467, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 28, 55}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6468, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4492, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 54, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6480, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2874, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4522, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4094, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3056, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3202, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2501, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6349, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4520, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6097, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5250, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5935, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2421, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4386, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 234, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6737, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5762, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6434, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5013, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 379, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3620, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5063, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3455, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4504, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4609, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4745, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3078, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5135, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6329, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3608, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 172, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3058, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 252, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4559, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5546, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5588, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2879, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2243, 335}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1678, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3862, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2033, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4711, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6042, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6566, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5051, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3586, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4950, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4173, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 328, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3635, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5006, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6972, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3479, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6933, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5012, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 14, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3133, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4598, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6912, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 908, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 230, 1, 596, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5163, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4731, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4996, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3214, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6698, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6631, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1999, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 58, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6656, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1258, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3536, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6822, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6130, 450}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6640, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6476, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4683, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6618, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2571, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2636, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SMALL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2293, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4938, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3137, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1273, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2835, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5759, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6848, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 861, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2294, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1059, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3167, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6724, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5276, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3959, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4066, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5831, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6879, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4303, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2382, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6941, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3618, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5965, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2735, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5383, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2872, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6508, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 453, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5089, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4494, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5326, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2495, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1191, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1149, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 531, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2870, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 302, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 98, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6286, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4390, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6473, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2845, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1484, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 657, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 841, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4482, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 611, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5179, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3204, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4524, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4502, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 757, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4330, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1027, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5161, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3700, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2901, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6009, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1357, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3178, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4500, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1400, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 118, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 422, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 336, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 340, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2714, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6784, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6683, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5189, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 533, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 900, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3094, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5322, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5365, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6095, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5119, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5805, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3006, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4952, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3576, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 751, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 699, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2931, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2437, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 595, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1853, 318}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 953, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4848, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5914, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2223, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 604, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6364, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1424, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 66, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 204, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2856, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 56, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3188, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2965, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6202, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4821, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2219, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6903, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2891, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6920, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4852, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5121, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4428, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2927, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 476, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 624, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6726, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3212, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4449, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 278, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3619, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4518, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6934, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6301, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4519, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3199, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 664, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5367, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4484, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4842, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2786, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5057, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 945, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5477, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4380, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6702, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4489, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 662, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6459, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4919, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1624, 271}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4715, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4554, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3310, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6062, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6896, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 707, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6054, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5743, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1977, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6333, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4717, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5069, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6547, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 779, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6769, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2389, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 2394, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6538, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FRACTION, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2346, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 805, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1988, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3625, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3128, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5763, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2384, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2079, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 626, 0}, {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5742, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 731, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1235, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6852, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1079, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4722, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5167, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6664, 0}, - {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 42, 60}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4623, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5041, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4926, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 721, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 174, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6785, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5129, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 228, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6739, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 74, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3627, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4774, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 34, 57}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6027, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2285, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5025, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 126, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 889, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2274, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 138, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6795, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1267, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUB, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5324, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4674, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5316, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3529, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1261, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 240, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5603, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 787, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3104, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3000, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3082, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3050, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6037, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4817, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6791, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2884, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 521, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6109, 445}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3068, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4993, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3157, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6877, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2517, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6440, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6976, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3991, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6939, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5296, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4283, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 973, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5347, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6309, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6253, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1295, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5099, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 5697, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5351, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4800, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 160, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 330, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3626, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5101, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4499, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1788, 307}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2433, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 80, 67}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 594, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1716, 297}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6616, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 13, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5312, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3008, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6761, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 90, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5229, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4377, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1823, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4844, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6820, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4483, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3240, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5225, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1083, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3102, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2968, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6541, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4546, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3198, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 38, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 975, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 3278, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2758, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 1010, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 887, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2642, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1675, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2869, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2720, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5746, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5155, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5139, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3771, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4807, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6564, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4864, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2957, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6750, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5543, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 797, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4719, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2948, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 6370, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2318, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6733, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2439, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6732, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4580, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3115, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_NARROW, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5768, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 3397, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3629, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6533, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2990, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1343, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 755, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5669, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1263, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1200, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_VERTICAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5765, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5197, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1029, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 7, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 537, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5237, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2113, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_MEDIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5308, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2156, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_FINAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5814, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_WIDE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 344, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 4, 1981, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4724, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 5513, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3028, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 648, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 1486, 263}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_FONT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6292, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 3086, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_INITIAL, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 5143, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6471, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 224, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 1589, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2535, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_ISOLATED, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 5077, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2882, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 6036, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 652, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 4968, 0}, + {LXB_UNICODE_CANONICAL_SEPARATELY|LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4220, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 971, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 4011, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SQUARE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3857, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2880, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 2387, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 3, 2151, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 3141, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_MAYBE|LXB_UNICODE_QUICK_NFKD_NO, 0, 2, 6117, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_SUPER, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 963, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE__UNDEF, LXB_UNICODE_QUICK_NFC_NO|LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 4644, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_COMPAT, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 1, 2983, 0}, + {LXB_UNICODE_DECOMPOSITION_TYPE_CIRCLE, LXB_UNICODE_QUICK_NFKC_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 5, 3503, 0}, {0, LXB_UNICODE_QUICK_NFD_NO|LXB_UNICODE_QUICK_NFKD_NO, 0, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 1, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 220, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 240, 0, 0, 0}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 91, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 7, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 230, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 216, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 449}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 202, 0, 0, 0}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 444}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 439}, - {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 8, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 240, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 230, 0, 0, 0}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 9, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 8, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 220, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 7, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 1, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 444}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 91, 0, 0, 0}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 449}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 216, 0, 0, 0}, {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 447}, + {0, LXB_UNICODE_QUICK_NFC_MAYBE|LXB_UNICODE_QUICK_NFKC_MAYBE, 0, 0, 0, 439}, {0, LXB_UNICODE_QUICK__UNDEF, 230, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 220, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 18, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 1, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 216, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 220, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 9, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 28, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 233, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 234, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 224, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 122, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 17, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 7, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 9, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 222, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 232, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 16, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 30, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 25, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 130, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 218, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 228, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 107, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 202, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 13, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 11, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 19, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 27, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 31, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 20, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 35, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 30, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 18, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 21, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 23, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 15, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 32, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 232, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 10, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 216, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 13, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 118, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 34, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 31, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 233, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 84, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 132, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 103, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 228, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 202, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 26, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 226, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 214, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 20, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 24, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 27, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 22, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 10, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 36, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 19, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 224, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 32, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 12, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 33, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 11, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 222, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 218, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 132, 0, 0, 0}, {0, LXB_UNICODE_QUICK__UNDEF, 6, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 14, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 36, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 129, 0, 0, 232}, {0, LXB_UNICODE_QUICK__UNDEF, 29, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 24, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 35, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 17, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 26, 0, 0, 0}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 121}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 136}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 378}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 12}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 395}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 437}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 366}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 369}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 18}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 341}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 143}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 131}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 336}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 373}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 382}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 31}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 219}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 191}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 203}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 170}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 172}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 156}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 383}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 421}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 400}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 120}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 108}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 205}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 356}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 112}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 241}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 174}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 134}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 352}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 25}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 384}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 251}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 186}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 148}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 115}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 58}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 113}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 377}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 211}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 428}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 337}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 419}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 342}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 217}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 452}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 375}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 434}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 22}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 396}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 401}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 6}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 404}, + {0, LXB_UNICODE_QUICK__UNDEF, 16, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 33, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 107, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 214, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 34, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 23, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 103, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 25, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 129, 0, 0, 232}, + {0, LXB_UNICODE_QUICK__UNDEF, 15, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 14, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 84, 0, 0, 0}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 423}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 184}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 228}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 392}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 182}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 410}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 11}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 213}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 157}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 175}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 397}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 215}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 150}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 149}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 201}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 362}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 360}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 8}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 391}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 433}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 183}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 430}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 108}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 144}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 339}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 419}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 235}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 174}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 29}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 18}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 432}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 454}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 138}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 440}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 387}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 28}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 22}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 402}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 197}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 164}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 30}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 438}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 177}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 210}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 415}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 1}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 49}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 133}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 236}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 399}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 403}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 401}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 38}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 53}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 41}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 406}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 137}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 363}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 206}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 196}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 425}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 407}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 179}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 118}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 168}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 220}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 50}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 47}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 440}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 367}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 2}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 46}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 348}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 216}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 27}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 386}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 366}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 193}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 238}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 130}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 222}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 235}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 155}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 351}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 347}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 408}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 243}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 242}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 142}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 153}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 141}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 357}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 371}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 372}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 436}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 354}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 4}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 390}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 145}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 147}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 202}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 192}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 107}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 165}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 227}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 224}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 161}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 413}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 252}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 15}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 166}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 52}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 23}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 344}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 248}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 180}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 77}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 132}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 19}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 32}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 189}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 346}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 391}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 17}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 39}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 133}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 414}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 70}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 380}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 239}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 430}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 199}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 30}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 386}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 247}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 162}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 345}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 178}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 251}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 418}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 152}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 13}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 119}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 198}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 231}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 421}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 114}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 230}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 181}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 182}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 175}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 224}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 409}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 422}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 246}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 338}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 352}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 163}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 203}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 58}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 48}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 233}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 125}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 177}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 169}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 21}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 362}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 42}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 441}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 20}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 8}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 207}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 37}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 65}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 349}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 51}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 46}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 228}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 411}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 242}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 195}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 145}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 217}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 211}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 385}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 212}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 350}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 132}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 44}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 110}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 10}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 229}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 154}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 119}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 237}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 402}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 35}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 214}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 455}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 250}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 241}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 194}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 451}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 200}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 45}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 428}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 347}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 156}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 252}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 443}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 176}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 143}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 2}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 410}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 186}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 367}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 359}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 185}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 240}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 135}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 115}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 172}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 12}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 435}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 146}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 157}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 249}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 411}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 414}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 390}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 142}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 368}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 234}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 429}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 245}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 109}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 378}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 196}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 191}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 118}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 379}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 154}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 43}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 149}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 412}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 139}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 195}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 33}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 197}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 393}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 244}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 13}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 370}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 403}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 358}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 424}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 213}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 237}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 415}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 136}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 65}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 155}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 351}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 161}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 434}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 50}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 223}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 98}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 230}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 420}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 123}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 29}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 356}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 398}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 209}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 364}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 236}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 338}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 212}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 193}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 173}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 423}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 431}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 16}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 240}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 160}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 167}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 163}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 343}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 178}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 218}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 429}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 336}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 375}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 199}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 192}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 436}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 381}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 3}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 385}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 27}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 146}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 34}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 21}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 454}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 151}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 231}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 44}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 443}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 399}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 190}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 353}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 124}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 394}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 41}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 26}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 387}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 159}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 416}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 19}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 248}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 340}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 33}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 15}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 125}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 404}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 412}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 431}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 25}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 344}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 220}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 427}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 5}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 123}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 139}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 1}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 162}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 424}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 397}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 131}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 7}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 394}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 121}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 341}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 9}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 144}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 205}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 17}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 36}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 216}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 355}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 169}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 348}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 202}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 413}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 337}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 16}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 151}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 373}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 365}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 408}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 214}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 448}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 28}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 376}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 188}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 122}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 374}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 389}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 422}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 45}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 10}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 365}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 135}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 138}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 418}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 379}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 455}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 183}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 176}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 110}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 246}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 164}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 114}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 368}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 14}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 451}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 185}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 339}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 438}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 171}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 249}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 388}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 34}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 24}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 198}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 184}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 345}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 245}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 433}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 40}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 442}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 107}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 31}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 363}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 39}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 407}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 6}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 187}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 354}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 150}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 244}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 32}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 372}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 382}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 226}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 49}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 417}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 109}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 350}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 5}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 165}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 361}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 234}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 435}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 396}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 153}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 239}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 204}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 152}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 194}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 7}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 208}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 171}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 437}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 112}, {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 140}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 181}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 359}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 187}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 158}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 405}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 111}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 409}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 416}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 427}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 200}, - {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 250} -}; - -static const lxb_unicode_idna_entry_t lxb_unicode_idna_entries[3923] = -{ - {0, 0, 0}, - {LXB_UNICODE_IDNA_DISALLOWED, 0, 0}, - {LXB_UNICODE_IDNA_VALID, 0, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 673}, - {LXB_UNICODE_IDNA_MAPPED, 2, 532}, - {LXB_UNICODE_IDNA_MAPPED, 1, 27}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4264}, - {LXB_UNICODE_IDNA_MAPPED, 1, 327}, - {LXB_UNICODE_IDNA_IGNORED, 0, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1635}, - {LXB_UNICODE_IDNA_MAPPED, 1, 301}, - {LXB_UNICODE_IDNA_MAPPED, 1, 66}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3328}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1657}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3820}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4861}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2218}, - {LXB_UNICODE_IDNA_DEVIATION, 0, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3267}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4990}, - {LXB_UNICODE_IDNA_MAPPED, 1, 627}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1070}, - {LXB_UNICODE_IDNA_MAPPED, 1, 10}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1060}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3722}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3738}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2962}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5062}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1778}, - {LXB_UNICODE_IDNA_MAPPED, 1, 310}, - {LXB_UNICODE_IDNA_MAPPED, 1, 20}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1812}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1434}, - {LXB_UNICODE_IDNA_MAPPED, 1, 290}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3646}, - {LXB_UNICODE_IDNA_MAPPED, 1, 154}, - {LXB_UNICODE_IDNA_MAPPED, 1, 24}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4981}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3039}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3001}, - {LXB_UNICODE_IDNA_MAPPED, 2, 560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1059}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3443}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2972}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 22}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3403}, - {LXB_UNICODE_IDNA_MAPPED, 1, 297}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2730}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2192}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3766}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3926}, - {LXB_UNICODE_IDNA_MAPPED, 1, 308}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 12}, - {LXB_UNICODE_IDNA_MAPPED, 1, 526}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 304}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 898}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3579}, - {LXB_UNICODE_IDNA_MAPPED, 1, 706}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3053}, - {LXB_UNICODE_IDNA_MAPPED, 1, 314}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3732}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2525}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1016}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3459}, - {LXB_UNICODE_IDNA_MAPPED, 1, 737}, - {LXB_UNICODE_IDNA_MAPPED, 2, 944}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5355}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3143}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4306}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4715}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4740}, - {LXB_UNICODE_IDNA_MAPPED, 1, 621}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2605}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4444}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3838}, - {LXB_UNICODE_IDNA_MAPPED, 1, 344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 6}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5325}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 298}, - {LXB_UNICODE_IDNA_MAPPED, 1, 23}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1814}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3679}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2074}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3413}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3657}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4679}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3164}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5089}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4939}, - {LXB_UNICODE_IDNA_MAPPED, 1, 26}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3485}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2000}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1756}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1799}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2953}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3788}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2999}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2}, - {LXB_UNICODE_IDNA_MAPPED, 1, 16}, - {LXB_UNICODE_IDNA_MAPPED, 1, 196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 158}, - {LXB_UNICODE_IDNA_MAPPED, 1, 15}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2956}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3702}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1591}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1165}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3840}, - {LXB_UNICODE_IDNA_MAPPED, 1, 377}, - {LXB_UNICODE_IDNA_MAPPED, 1, 659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1653}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2907}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1614}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3221}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 741}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3471}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5025}, - {LXB_UNICODE_IDNA_MAPPED, 1, 303}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3665}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2115}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 922}, - {LXB_UNICODE_IDNA_MAPPED, 1, 25}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1559}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1235}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1062}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3782}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2551}, - {LXB_UNICODE_IDNA_MAPPED, 1, 369}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4}, - {LXB_UNICODE_IDNA_MAPPED, 1, 74}, - {LXB_UNICODE_IDNA_MAPPED, 1, 300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 163}, - {LXB_UNICODE_IDNA_MAPPED, 2, 35}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3488}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4627}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2046}, - {LXB_UNICODE_IDNA_MAPPED, 1, 8}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4635}, - {LXB_UNICODE_IDNA_MAPPED, 1, 446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3474}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5147}, - {LXB_UNICODE_IDNA_MAPPED, 1, 19}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4791}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 710}, - {LXB_UNICODE_IDNA_MAPPED, 2, 972}, - {LXB_UNICODE_IDNA_MAPPED, 1, 735}, - {LXB_UNICODE_IDNA_MAPPED, 1, 720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 21}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3762}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5114}, - {LXB_UNICODE_IDNA_MAPPED, 1, 372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 307}, - {LXB_UNICODE_IDNA_MAPPED, 1, 638}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3768}, - {LXB_UNICODE_IDNA_MAPPED, 1, 882}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3850}, - {LXB_UNICODE_IDNA_MAPPED, 1, 519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3433}, - {LXB_UNICODE_IDNA_MAPPED, 1, 760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4622}, - {LXB_UNICODE_IDNA_MAPPED, 2, 985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 299}, - {LXB_UNICODE_IDNA_MAPPED, 1, 316}, - {LXB_UNICODE_IDNA_MAPPED, 1, 484}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4478}, - {LXB_UNICODE_IDNA_MAPPED, 1, 863}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3577}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 40}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1546}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2502}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5271}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2334}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3965}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1477}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3764}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 115}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3010}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2739}, - {LXB_UNICODE_IDNA_MAPPED, 1, 756}, - {LXB_UNICODE_IDNA_MAPPED, 2, 534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 311}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1767}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3214}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3836}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2202}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4616}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4996}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5020}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2098}, - {LXB_UNICODE_IDNA_MAPPED, 1, 352}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5339}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2056}, - {LXB_UNICODE_IDNA_MAPPED, 1, 466}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1979}, - {LXB_UNICODE_IDNA_MAPPED, 1, 750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3228}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4982}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4500}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3720}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3987}, - {LXB_UNICODE_IDNA_MAPPED, 2, 572}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1811}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1544}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5202}, - {LXB_UNICODE_IDNA_MAPPED, 1, 14}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1723}, - {LXB_UNICODE_IDNA_MAPPED, 1, 513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 413}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3186}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4300}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3914}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4415}, - {LXB_UNICODE_IDNA_MAPPED, 1, 685}, - {LXB_UNICODE_IDNA_MAPPED, 1, 302}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4569}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1037}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4843}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4792}, - {LXB_UNICODE_IDNA_MAPPED, 1, 9}, - {LXB_UNICODE_IDNA_MAPPED, 1, 315}, - {LXB_UNICODE_IDNA_MAPPED, 1, 766}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1045}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 37}, - {LXB_UNICODE_IDNA_MAPPED, 1, 478}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3083}, - {LXB_UNICODE_IDNA_MAPPED, 1, 859}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3075}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 785}, - {LXB_UNICODE_IDNA_MAPPED, 1, 251}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 462}, - {LXB_UNICODE_IDNA_MAPPED, 1, 532}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 18}, - {LXB_UNICODE_IDNA_MAPPED, 1, 678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3169}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3776}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2717}, - {LXB_UNICODE_IDNA_MAPPED, 1, 664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5046}, - {LXB_UNICODE_IDNA_MAPPED, 1, 375}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 354}, - {LXB_UNICODE_IDNA_MAPPED, 1, 13}, - {LXB_UNICODE_IDNA_MAPPED, 1, 853}, - {LXB_UNICODE_IDNA_MAPPED, 1, 474}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3856}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 62}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4828}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1706}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3836}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3768}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3262}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4027}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 437}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5166}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2170}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4279}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5139}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4888}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3286}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3235}, - {LXB_UNICODE_IDNA_MAPPED, 1, 873}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4900}, - {LXB_UNICODE_IDNA_MAPPED, 2, 924}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5278}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5024}, - {LXB_UNICODE_IDNA_MAPPED, 1, 528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1955}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1428}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3020}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5376}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4592}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3472}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1067}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4722}, - {LXB_UNICODE_IDNA_MAPPED, 1, 782}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5189}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3048}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 661}, - {LXB_UNICODE_IDNA_MAPPED, 1, 174}, - {LXB_UNICODE_IDNA_MAPPED, 1, 333}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3754}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1958}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 160}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4725}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3016}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3778}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1403}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3558}, - {LXB_UNICODE_IDNA_MAPPED, 1, 289}, - {LXB_UNICODE_IDNA_MAPPED, 1, 846}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3788}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3842}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3158}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1759}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1819}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3291}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3355}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3883}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1339}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 79}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3210}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3615}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1916}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1187}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3285}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1672}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1011}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4920}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5054}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4036}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 241}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4210}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1066}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3754}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3977}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4495}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3661}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1994}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1049}, - {LXB_UNICODE_IDNA_MAPPED, 2, 948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5385}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 34}, - {LXB_UNICODE_IDNA_MAPPED, 1, 363}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2850}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 904}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3080}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2619}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3792}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1333}, - {LXB_UNICODE_IDNA_MAPPED, 2, 31}, - {LXB_UNICODE_IDNA_MAPPED, 2, 29}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3074}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1068}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3726}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4147}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2251}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2811}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1468}, - {LXB_UNICODE_IDNA_MAPPED, 1, 658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5077}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4081}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1594}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3634}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4576}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1747}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2201}, - {LXB_UNICODE_IDNA_MAPPED, 1, 77}, - {LXB_UNICODE_IDNA_MAPPED, 1, 91}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4571}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3484}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5235}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3414}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5142}, - {LXB_UNICODE_IDNA_MAPPED, 3, 998}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1318}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1541}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4132}, - {LXB_UNICODE_IDNA_MAPPED, 1, 379}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3928}, - {LXB_UNICODE_IDNA_MAPPED, 1, 240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5011}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5305}, - {LXB_UNICODE_IDNA_MAPPED, 1, 277}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1881}, - {LXB_UNICODE_IDNA_MAPPED, 1, 11}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2050}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 17}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3028}, - {LXB_UNICODE_IDNA_MAPPED, 1, 56}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4970}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4189}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5123}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1813}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 842}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3967}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3877}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4790}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3673}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2266}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1722}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5314}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5210}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4387}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4366}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3476}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1661}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3844}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4477}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5049}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 367}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 399}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4527}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3750}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 239}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4689}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2337}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1208}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3233}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 284}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4494}, - {LXB_UNICODE_IDNA_MAPPED, 2, 542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4636}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3975}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5173}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3538}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 865}, - {LXB_UNICODE_IDNA_MAPPED, 1, 491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 89}, - {LXB_UNICODE_IDNA_MAPPED, 1, 868}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3448}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2944}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1029}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 523}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 7}, - {LXB_UNICODE_IDNA_MAPPED, 1, 975}, - {LXB_UNICODE_IDNA_MAPPED, 1, 762}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3870}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1480}, - {LXB_UNICODE_IDNA_MAPPED, 1, 640}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3524}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 76}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 695}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1611}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 743}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4201}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2904}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4819}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 125}, - {LXB_UNICODE_IDNA_MAPPED, 1, 226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 415}, - {LXB_UNICODE_IDNA_MAPPED, 1, 509}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3428}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4628}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 237}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3922}, - {LXB_UNICODE_IDNA_MAPPED, 1, 822}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3209}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3487}, - {LXB_UNICODE_IDNA_MAPPED, 1, 360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2065}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4678}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3377}, - {LXB_UNICODE_IDNA_MAPPED, 1, 752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4670}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5065}, - {LXB_UNICODE_IDNA_MAPPED, 1, 342}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5181}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5282}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1919}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1530}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2536}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2071}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3013}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2137}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1673}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2179}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3002}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5365}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5351}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2598}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 855}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4714}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2696}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1141}, - {LXB_UNICODE_IDNA_MAPPED, 2, 960}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 305}, - {LXB_UNICODE_IDNA_MAPPED, 1, 687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3140}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3050}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1579}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 480}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3123}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2931}, - {LXB_UNICODE_IDNA_MAPPED, 1, 787}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4651}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3408}, - {LXB_UNICODE_IDNA_MAPPED, 1, 826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 771}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3008}, - {LXB_UNICODE_IDNA_MAPPED, 1, 371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1065}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4751}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5070}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1775}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5086}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1377}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4942}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1931}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 886}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 233}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3264}, - {LXB_UNICODE_IDNA_MAPPED, 1, 117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3330}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3640}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1440}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1636}, - {LXB_UNICODE_IDNA_MAPPED, 2, 920}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3656}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3525}, - {LXB_UNICODE_IDNA_MAPPED, 1, 225}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2733}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1281}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3924}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5145}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1952}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1089}, - {LXB_UNICODE_IDNA_MAPPED, 2, 184}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 428}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4727}, - {LXB_UNICODE_IDNA_MAPPED, 1, 726}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3017}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4591}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3247}, - {LXB_UNICODE_IDNA_MAPPED, 2, 550}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4505}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1761}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5230}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3347}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4615}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3283}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4748}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 124}, - {LXB_UNICODE_IDNA_MAPPED, 1, 424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2207}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3295}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1185}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3613}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1682}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2123}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4042}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4374}, - {LXB_UNICODE_IDNA_MAPPED, 1, 346}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1745}, - {LXB_UNICODE_IDNA_MAPPED, 1, 798}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1084}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 296}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4949}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2846}, - {LXB_UNICODE_IDNA_MAPPED, 1, 486}, - {LXB_UNICODE_IDNA_MAPPED, 1, 903}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4141}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1106}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3070}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4021}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 28}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3644}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1726}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5375}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2963}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5052}, - {LXB_UNICODE_IDNA_MAPPED, 1, 33}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1545}, - {LXB_UNICODE_IDNA_MAPPED, 1, 871}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1596}, - {LXB_UNICODE_IDNA_MAPPED, 2, 928}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3118}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2993}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2211}, - {LXB_UNICODE_IDNA_MAPPED, 2, 269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3412}, - {LXB_UNICODE_IDNA_MAPPED, 1, 453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2131}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 794}, - {LXB_UNICODE_IDNA_MAPPED, 2, 106}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5134}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5244}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4075}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5006}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1421}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1069}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2058}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1690}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1700}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1851}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1602}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 406}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3663}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1815}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4955}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4017}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3326}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 96}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3667}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5338}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2486}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4531}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4423}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2986}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1740}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5330}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3275}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1053}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1665}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 200}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 53}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4389}, - {LXB_UNICODE_IDNA_MAPPED, 1, 450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5040}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5262}, - {LXB_UNICODE_IDNA_MAPPED, 1, 214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2331}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4482}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4634}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3490}, - {LXB_UNICODE_IDNA_MAPPED, 1, 645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 701}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3279}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5374}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4807}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4069}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5026}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2648}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2548}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1754}, - {LXB_UNICODE_IDNA_MAPPED, 1, 991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 966}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4757}, - {LXB_UNICODE_IDNA_MAPPED, 1, 530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4969}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5131}, - {LXB_UNICODE_IDNA_MAPPED, 1, 774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1529}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 139}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1615}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3435}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4177}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4825}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2187}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1607}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 508}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3762}, - {LXB_UNICODE_IDNA_MAPPED, 1, 675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 212}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5146}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2076}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1768}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3993}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4471}, - {LXB_UNICODE_IDNA_MAPPED, 1, 94}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3478}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1757}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5290}, - {LXB_UNICODE_IDNA_MAPPED, 1, 505}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4833}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4674}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5056}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2181}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3436}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 280}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1509}, - {LXB_UNICODE_IDNA_MAPPED, 3, 604}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4710}, - {LXB_UNICODE_IDNA_MAPPED, 1, 146}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4506}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5331}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4788}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2607}, - {LXB_UNICODE_IDNA_MAPPED, 2, 962}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 828}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 733}, - {LXB_UNICODE_IDNA_MAPPED, 1, 167}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1738}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2189}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3995}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4602}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3125}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2932}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4421}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4567}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4655}, - {LXB_UNICODE_IDNA_MAPPED, 1, 318}, - {LXB_UNICODE_IDNA_MAPPED, 2, 966}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 384}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 218}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 209}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 343}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 400}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 215}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 442}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 124}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 383}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 369}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 247}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 208}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 168}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 377}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 159}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 406}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 141}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 130}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 137}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 70}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 160}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 420}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 441}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 179}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 361}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 23}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 98}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 364}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 77}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 52}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 47}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 20}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 353}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 395}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 37}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 35}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 380}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 393}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 388}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 219}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 376}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 358}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 357}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 53}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 222}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 355}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 233}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 342}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 173}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 40}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 170}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 417}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 148}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 389}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 425}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 189}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 188}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 51}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 371}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 180}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 370}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 190}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 243}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 360}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 206}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 349}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 207}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 134}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 120}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 4}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 158}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 405}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 111}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 3}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 167}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 166}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 452}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 122}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 14}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 113}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 11}, + {0, LXB_UNICODE_QUICK__UNDEF, 0, 0, 0, 147} +}; + +static const lxb_unicode_idna_entry_t lxb_unicode_idna_entries[3951] = +{ + {0, 0, 0}, + {LXB_UNICODE_IDNA_VALID, 0, 0}, + {LXB_UNICODE_IDNA_DISALLOWED, 0, 0}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 12}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 301}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3672}, + {LXB_UNICODE_IDNA_MAPPED, 1, 709}, + {LXB_UNICODE_IDNA_MAPPED, 2, 952}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3773}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2092}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3055}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 310}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3751}, {LXB_UNICODE_IDNA_MAPPED, 1, 5337}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3276}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3054}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4743}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 653}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1771}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1779}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3352}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 746}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 419}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3187}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3163}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3251}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 778}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3529}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3332}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2943}, - {LXB_UNICODE_IDNA_MAPPED, 2, 819}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1634}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1400}, - {LXB_UNICODE_IDNA_MAPPED, 1, 835}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3062}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2706}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3167}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3268}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2886}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1001}, - {LXB_UNICODE_IDNA_MAPPED, 1, 145}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4549}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3331}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 81}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3810}, - {LXB_UNICODE_IDNA_MAPPED, 2, 263}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5170}, + {LXB_UNICODE_IDNA_MAPPED, 1, 26}, + {LXB_UNICODE_IDNA_IGNORED, 0, 0}, + {LXB_UNICODE_IDNA_MAPPED, 1, 34}, + {LXB_UNICODE_IDNA_MAPPED, 1, 16}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3673}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1718}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1324}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1751}, + {LXB_UNICODE_IDNA_MAPPED, 1, 763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3076}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3025}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4957}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1597}, + {LXB_UNICODE_IDNA_MAPPED, 18, 4343}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3769}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5347}, + {LXB_UNICODE_IDNA_MAPPED, 2, 184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5154}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1701}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3564}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4332}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5}, + {LXB_UNICODE_IDNA_MAPPED, 1, 631}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4505}, + {LXB_UNICODE_IDNA_MAPPED, 2, 574}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2808}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3208}, + {LXB_UNICODE_IDNA_MAPPED, 1, 20}, + {LXB_UNICODE_IDNA_MAPPED, 1, 15}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1722}, + {LXB_UNICODE_IDNA_MAPPED, 1, 6}, + {LXB_UNICODE_IDNA_MAPPED, 1, 862}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2085}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3759}, + {LXB_UNICODE_IDNA_MAPPED, 1, 391}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 317}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4018}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5038}, + {LXB_UNICODE_IDNA_MAPPED, 1, 871}, + {LXB_UNICODE_IDNA_MAPPED, 1, 27}, + {LXB_UNICODE_IDNA_MAPPED, 1, 442}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5064}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 296}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4993}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 343}, + {LXB_UNICODE_IDNA_MAPPED, 1, 23}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3218}, + {LXB_UNICODE_IDNA_MAPPED, 1, 62}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 0}, + {LXB_UNICODE_IDNA_MAPPED, 1, 79}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5130}, + {LXB_UNICODE_IDNA_MAPPED, 1, 258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1472}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3729}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2079}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3839}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2131}, + {LXB_UNICODE_IDNA_MAPPED, 1, 33}, + {LXB_UNICODE_IDNA_MAPPED, 1, 681}, + {LXB_UNICODE_IDNA_MAPPED, 1, 837}, + {LXB_UNICODE_IDNA_MAPPED, 1, 512}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 304}, + {LXB_UNICODE_IDNA_MAPPED, 1, 667}, + {LXB_UNICODE_IDNA_MAPPED, 2, 938}, + {LXB_UNICODE_IDNA_MAPPED, 1, 761}, {LXB_UNICODE_IDNA_MAPPED, 1, 3269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3402}, - {LXB_UNICODE_IDNA_MAPPED, 1, 626}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4525}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1510}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1820}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1780}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5287}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1576}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5096}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 430}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3503}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2977}, - {LXB_UNICODE_IDNA_MAPPED, 1, 401}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3007}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2183}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3166}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2704}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3124}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1457}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1401}, - {LXB_UNICODE_IDNA_MAPPED, 1, 910}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4656}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3055}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4839}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 642}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4779}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1688}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3145}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4827}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5361}, - {LXB_UNICODE_IDNA_MAPPED, 1, 409}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4766}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4713}, - {LXB_UNICODE_IDNA_MAPPED, 1, 319}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 82}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3353}, - {LXB_UNICODE_IDNA_MAPPED, 2, 611}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3181}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5320}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4875}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5080}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3481}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2990}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5152}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5251}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1795}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5034}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5172}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3432}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3936}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3280}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5030}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1410}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4432}, {LXB_UNICODE_IDNA_MAPPED, 1, 3376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 54}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1169}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2901}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1616}, - {LXB_UNICODE_IDNA_MAPPED, 1, 439}, - {LXB_UNICODE_IDNA_MAPPED, 2, 267}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4459}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3098}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1288}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3760}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1049}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 448}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3736}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 221}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1022}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 128}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 83}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3991}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1126}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2996}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3940}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3067}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1063}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2277}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1602}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3641}, + {LXB_UNICODE_IDNA_MAPPED, 1, 233}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3361}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4002}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1069}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4770}, + {LXB_UNICODE_IDNA_MAPPED, 2, 928}, + {LXB_UNICODE_IDNA_MAPPED, 1, 302}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2730}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3082}, + {LXB_UNICODE_IDNA_MAPPED, 1, 14}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1091}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1330}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 10}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3136}, + {LXB_UNICODE_IDNA_MAPPED, 1, 624}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2998}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4494}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4552}, + {LXB_UNICODE_IDNA_MAPPED, 1, 153}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1501}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3757}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 293}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4983}, + {LXB_UNICODE_IDNA_MAPPED, 1, 21}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3193}, + {LXB_UNICODE_IDNA_MAPPED, 1, 852}, + {LXB_UNICODE_IDNA_MAPPED, 1, 457}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3939}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4824}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 890}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1555}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4621}, + {LXB_UNICODE_IDNA_MAPPED, 1, 24}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4662}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4893}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4540}, + {LXB_UNICODE_IDNA_MAPPED, 1, 7}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4643}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 17}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1345}, + {LXB_UNICODE_IDNA_MAPPED, 1, 18}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 13}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3644}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2006}, {LXB_UNICODE_IDNA_MAPPED, 3, 4180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4608}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5182}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3426}, - {LXB_UNICODE_IDNA_MAPPED, 1, 359}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1415}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3308}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5233}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4532}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2317}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1354}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4605}, - {LXB_UNICODE_IDNA_MAPPED, 2, 952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 518}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2182}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1793}, - {LXB_UNICODE_IDNA_MAPPED, 1, 901}, - {LXB_UNICODE_IDNA_MAPPED, 2, 987}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4476}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 891}, - {LXB_UNICODE_IDNA_MAPPED, 1, 358}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1420}, - {LXB_UNICODE_IDNA_MAPPED, 2, 934}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4019}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1478}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1017}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 368}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2212}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4011}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5304}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 11}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 9}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5142}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5390}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5128}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1979}, + {LXB_UNICODE_IDNA_MAPPED, 1, 77}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4078}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3293}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1541}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4716}, {LXB_UNICODE_IDNA_MAPPED, 1, 5002}, - {LXB_UNICODE_IDNA_MAPPED, 1, 272}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1527}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3138}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3934}, - {LXB_UNICODE_IDNA_MAPPED, 1, 810}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1098}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1739}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1500}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1595}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1703}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 130}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4572}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 806}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1004}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4946}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4749}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1629}, - {LXB_UNICODE_IDNA_MAPPED, 1, 731}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3085}, - {LXB_UNICODE_IDNA_MAPPED, 1, 356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3073}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4856}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4377}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 830}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2840}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2692}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1577}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3161}, - {LXB_UNICODE_IDNA_MAPPED, 1, 722}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4371}, - {LXB_UNICODE_IDNA_MAPPED, 1, 908}, - {LXB_UNICODE_IDNA_MAPPED, 2, 954}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1198}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4418}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1416}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1725}, - {LXB_UNICODE_IDNA_MAPPED, 1, 385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2940}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5161}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5241}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3544}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3648}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 833}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3500}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2159}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3296}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3215}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3601}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1727}, - {LXB_UNICODE_IDNA_MAPPED, 1, 816}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4904}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5259}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4039}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4612}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4957}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1523}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4726}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4813}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1746}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1640}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1943}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5171}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2060}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4673}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5050}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1557}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5274}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2111}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2538}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4902}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2018}, - {LXB_UNICODE_IDNA_MAPPED, 1, 323}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3477}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1027}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4734}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1762}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2147}, - {LXB_UNICODE_IDNA_MAPPED, 2, 930}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3944}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4891}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1535}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5137}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4629}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3692}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3714}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1474}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2198}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3874}, - {LXB_UNICODE_IDNA_MAPPED, 1, 325}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4815}, - {LXB_UNICODE_IDNA_MAPPED, 1, 799}, - {LXB_UNICODE_IDNA_MAPPED, 1, 629}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2042}, - {LXB_UNICODE_IDNA_MAPPED, 1, 234}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4936}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4865}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3591}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4977}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1451}, - {LXB_UNICODE_IDNA_MAPPED, 3, 980}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3748}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1817}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3794}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1743}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5335}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1830}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3999}, - {LXB_UNICODE_IDNA_MAPPED, 1, 312}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3027}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 292}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3536}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 257}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4483}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5043}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4701}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3234}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1071}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4553}, - {LXB_UNICODE_IDNA_MAPPED, 1, 324}, - {LXB_UNICODE_IDNA_MAPPED, 1, 337}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3202}, - {LXB_UNICODE_IDNA_MAPPED, 1, 349}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4685}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4276}, - {LXB_UNICODE_IDNA_MAPPED, 1, 159}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2034}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3561}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4584}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5000}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2215}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5058}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 143}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1553}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 180}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3387}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3038}, - {LXB_UNICODE_IDNA_MAPPED, 1, 682}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4738}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3338}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2975}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2979}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3685}, - {LXB_UNICODE_IDNA_MAPPED, 1, 690}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2824}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1025}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3828}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3407}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2216}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1578}, - {LXB_UNICODE_IDNA_MAPPED, 1, 306}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4428}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4123}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4884}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 197}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3655}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1177}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1432}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1117}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4507}, - {LXB_UNICODE_IDNA_MAPPED, 2, 113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2926}, - {LXB_UNICODE_IDNA_MAPPED, 1, 803}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1842}, - {LXB_UNICODE_IDNA_MAPPED, 2, 538}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4417}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4412}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2631}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1827}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5328}, - {LXB_UNICODE_IDNA_MAPPED, 1, 725}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3069}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5042}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2454}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4138}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 755}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 483}, - {LXB_UNICODE_IDNA_MAPPED, 1, 864}, - {LXB_UNICODE_IDNA_MAPPED, 1, 493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 355}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4665}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2937}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3932}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4702}, - {LXB_UNICODE_IDNA_MAPPED, 1, 880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 761}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1729}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3389}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3359}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3650}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1763}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1731}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3282}, - {LXB_UNICODE_IDNA_MAPPED, 1, 414}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4648}, - {LXB_UNICODE_IDNA_MAPPED, 1, 652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4937}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4225}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3430}, - {LXB_UNICODE_IDNA_MAPPED, 1, 246}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3241}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4733}, - {LXB_UNICODE_IDNA_MAPPED, 1, 751}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3494}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5028}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1644}, - {LXB_UNICODE_IDNA_MAPPED, 1, 432}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3035}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2590}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1408}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4753}, - {LXB_UNICODE_IDNA_MAPPED, 1, 740}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5372}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3260}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5136}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 854}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 313}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5039}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4472}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 895}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4706}, - {LXB_UNICODE_IDNA_MAPPED, 2, 589}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 662}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2768}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2481}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4313}, - {LXB_UNICODE_IDNA_MAPPED, 1, 479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 858}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5216}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1564}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3959}, - {LXB_UNICODE_IDNA_MAPPED, 1, 655}, - {LXB_UNICODE_IDNA_MAPPED, 1, 786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4414}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3185}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5359}, - {LXB_UNICODE_IDNA_MAPPED, 1, 765}, - {LXB_UNICODE_IDNA_MAPPED, 1, 772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 676}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4686}, - {LXB_UNICODE_IDNA_MAPPED, 1, 193}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5132}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4968}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3766}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3404}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3451}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1691}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5295}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5143}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3312}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3635}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4072}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1552}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1749}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3638}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2106}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3339}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5187}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3930}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5059}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3636}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4802}, - {LXB_UNICODE_IDNA_MAPPED, 2, 104}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3508}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5083}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3523}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4898}, - {LXB_UNICODE_IDNA_MAPPED, 2, 528}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3024}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1805}, - {LXB_UNICODE_IDNA_MAPPED, 1, 195}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5067}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1689}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5195}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1257}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1536}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1454}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3309}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5169}, - {LXB_UNICODE_IDNA_MAPPED, 1, 917}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1724}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1737}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2273}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2960}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1047}, {LXB_UNICODE_IDNA_MAPPED, 1, 387}, - {LXB_UNICODE_IDNA_MAPPED, 1, 635}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4501}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4707}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1863}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5030}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3625}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1899}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1694}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2400}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3031}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3868}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3746}, - {LXB_UNICODE_IDNA_MAPPED, 1, 293}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4436}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3886}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1766}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2756}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1073}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3868}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2203}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4643}, - {LXB_UNICODE_IDNA_MAPPED, 1, 256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5369}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3100}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3954}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1561}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1079}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4325}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2575}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3127}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5286}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3434}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5094}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1471}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2314}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4695}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3152}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3047}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2998}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3380}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1940}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1572}, - {LXB_UNICODE_IDNA_MAPPED, 1, 681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4588}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4823}, - {LXB_UNICODE_IDNA_MAPPED, 1, 692}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3019}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4246}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3653}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1641}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4995}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1494}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5362}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1327}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3401}, - {LXB_UNICODE_IDNA_MAPPED, 1, 78}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4611}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4837}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3510}, - {LXB_UNICODE_IDNA_MAPPED, 3, 286}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2929}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1055}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5184}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 339}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3541}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3607}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4228}, - {LXB_UNICODE_IDNA_MAPPED, 1, 217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 347}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2813}, - {LXB_UNICODE_IDNA_MAPPED, 1, 433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4769}, + {LXB_UNICODE_IDNA_MAPPED, 1, 306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 8}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4708}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1582}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5355}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4267}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4961}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3}, + {LXB_UNICODE_IDNA_MAPPED, 1, 760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1810}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4596}, {LXB_UNICODE_IDNA_MAPPED, 1, 3261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3174}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2949}, - {LXB_UNICODE_IDNA_MAPPED, 2, 918}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4666}, - {LXB_UNICODE_IDNA_MAPPED, 2, 609}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 247}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5036}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1391}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2838}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4440}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3343}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2204}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3877}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2633}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4580}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 320}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2965}, - {LXB_UNICODE_IDNA_MAPPED, 1, 643}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3866}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3013}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2609}, + {LXB_UNICODE_IDNA_MAPPED, 1, 271}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3753}, + {LXB_UNICODE_IDNA_MAPPED, 2, 572}, + {LXB_UNICODE_IDNA_MAPPED, 1, 40}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3264}, {LXB_UNICODE_IDNA_MAPPED, 1, 5311}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4642}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4510}, - {LXB_UNICODE_IDNA_MAPPED, 1, 660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2223}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5075}, + {LXB_UNICODE_IDNA_MAPPED, 1, 25}, + {LXB_UNICODE_IDNA_MAPPED, 1, 22}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3994}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 332}, {LXB_UNICODE_IDNA_MAPPED, 1, 713}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4739}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1679}, - {LXB_UNICODE_IDNA_MAPPED, 1, 485}, - {LXB_UNICODE_IDNA_MAPPED, 1, 869}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1937}, - {LXB_UNICODE_IDNA_MAPPED, 1, 219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3454}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2572}, - {LXB_UNICODE_IDNA_MAPPED, 1, 698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 757}, - {LXB_UNICODE_IDNA_MAPPED, 1, 718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 181}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3151}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3862}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2819}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1091}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2226}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1845}, - {LXB_UNICODE_IDNA_MAPPED, 2, 938}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 739}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2475}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1566}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3507}, - {LXB_UNICODE_IDNA_MAPPED, 1, 361}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1423}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 382}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3740}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1440}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5329}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3663}, + {LXB_UNICODE_IDNA_MAPPED, 1, 87}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1651}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3988}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1928}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3415}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3719}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1681}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3227}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4741}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2929}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1160}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1768}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1770}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 825}, {LXB_UNICODE_IDNA_MAPPED, 1, 5082}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4974}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3203}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1630}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1443}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2764}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4582}, - {LXB_UNICODE_IDNA_MAPPED, 1, 511}, - {LXB_UNICODE_IDNA_MAPPED, 2, 41}, - {LXB_UNICODE_IDNA_MAPPED, 1, 228}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1040}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3564}, - {LXB_UNICODE_IDNA_MAPPED, 1, 793}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3406}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3627}, - {LXB_UNICODE_IDNA_MAPPED, 1, 112}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4550}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4785}, - {LXB_UNICODE_IDNA_MAPPED, 1, 770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5239}, - {LXB_UNICODE_IDNA_MAPPED, 2, 964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 767}, - {LXB_UNICODE_IDNA_MAPPED, 1, 99}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4630}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4486}, - {LXB_UNICODE_IDNA_MAPPED, 1, 374}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2044}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4207}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 149}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3783}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1762}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2096}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3892}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2995}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1017}, + {LXB_UNICODE_IDNA_MAPPED, 1, 315}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3050}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3841}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4856}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3509}, {LXB_UNICODE_IDNA_MAPPED, 1, 860}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3446}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2280}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4403}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2792}, - {LXB_UNICODE_IDNA_MAPPED, 2, 585}, - {LXB_UNICODE_IDNA_MAPPED, 1, 116}, - {LXB_UNICODE_IDNA_MAPPED, 1, 666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 789}, - {LXB_UNICODE_IDNA_MAPPED, 1, 893}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 108}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1060}, + {LXB_UNICODE_IDNA_MAPPED, 1, 360}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5110}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3962}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1281}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3081}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3676}, + {LXB_UNICODE_IDNA_MAPPED, 1, 711}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4818}, + {LXB_UNICODE_IDNA_MAPPED, 2, 530}, + {LXB_UNICODE_IDNA_MAPPED, 2, 968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 80}, + {LXB_UNICODE_IDNA_MAPPED, 1, 157}, + {LXB_UNICODE_IDNA_MAPPED, 1, 175}, + {LXB_UNICODE_IDNA_MAPPED, 1, 445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3643}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 274}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3873}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2966}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4522}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5313}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 28}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1468}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4875}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4057}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4153}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4764}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2852}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3493}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1672}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1351}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2750}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4863}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4531}, + {LXB_UNICODE_IDNA_MAPPED, 1, 88}, + {LXB_UNICODE_IDNA_MAPPED, 1, 54}, + {LXB_UNICODE_IDNA_MAPPED, 1, 728}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3431}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2026}, + {LXB_UNICODE_IDNA_MAPPED, 1, 313}, + {LXB_UNICODE_IDNA_MAPPED, 1, 340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1367}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1824}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4489}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2788}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4048}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3630}, {LXB_UNICODE_IDNA_MAPPED, 2, 2540}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4672}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1324}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1212}, - {LXB_UNICODE_IDNA_MAPPED, 2, 562}, - {LXB_UNICODE_IDNA_MAPPED, 1, 475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3153}, + {LXB_UNICODE_IDNA_MAPPED, 1, 881}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3348}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3366}, + {LXB_UNICODE_IDNA_MAPPED, 1, 735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4722}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4042}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1123}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1552}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1571}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3394}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 298}, + {LXB_UNICODE_IDNA_MAPPED, 1, 246}, + {LXB_UNICODE_IDNA_MAPPED, 1, 493}, + {LXB_UNICODE_IDNA_MAPPED, 1, 657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3102}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2774}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3827}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1815}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1061}, + {LXB_UNICODE_IDNA_MAPPED, 1, 311}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4783}, + {LXB_UNICODE_IDNA_MAPPED, 1, 873}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4558}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4501}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3516}, + {LXB_UNICODE_IDNA_MAPPED, 1, 793}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1059}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1739}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3088}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5069}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 60}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4776}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3883}, + {LXB_UNICODE_IDNA_MAPPED, 1, 277}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4754}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1766}, + {LXB_UNICODE_IDNA_MAPPED, 1, 700}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4965}, + {LXB_UNICODE_IDNA_MAPPED, 1, 514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2926}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5350}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 256}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2179}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1741}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3483}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3646}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1653}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 19}, + {LXB_UNICODE_IDNA_MAPPED, 2, 948}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2108}, + {LXB_UNICODE_IDNA_MAPPED, 1, 809}, + {LXB_UNICODE_IDNA_MAPPED, 1, 354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2207}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4406}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2309}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1220}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3731}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1683}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3559}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3588}, + {LXB_UNICODE_IDNA_MAPPED, 1, 205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2204}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 376}, + {LXB_UNICODE_IDNA_MAPPED, 1, 791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 507}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3563}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5286}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3833}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4988}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5079}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3511}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4105}, + {LXB_UNICODE_IDNA_MAPPED, 1, 96}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3299}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3010}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3674}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1588}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4607}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5071}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4463}, + {LXB_UNICODE_IDNA_MAPPED, 1, 58}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4520}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3809}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 109}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4674}, + {LXB_UNICODE_IDNA_MAPPED, 2, 954}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3397}, + {LXB_UNICODE_IDNA_MAPPED, 1, 696}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4671}, {LXB_UNICODE_IDNA_MAPPED, 1, 1558}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5301}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1483}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4249}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 334}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3906}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4869}, - {LXB_UNICODE_IDNA_MAPPED, 2, 615}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2778}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1068}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3743}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3400}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 638}, + {LXB_UNICODE_IDNA_MAPPED, 1, 521}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4977}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3129}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2798}, + {LXB_UNICODE_IDNA_MAPPED, 1, 135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4963}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4033}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 204}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4534}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4374}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1830}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5205}, + {LXB_UNICODE_IDNA_MAPPED, 1, 384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4602}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5044}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3626}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3155}, + {LXB_UNICODE_IDNA_MAPPED, 1, 308}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2762}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2835}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 356}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4537}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 333}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3640}, {LXB_UNICODE_IDNA_MAPPED, 1, 1573}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3216}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3734}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 707}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3633}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4988}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5265}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 781}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1794}, - {LXB_UNICODE_IDNA_MAPPED, 1, 716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5109}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2149}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1330}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3304}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3313}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1590}, - {LXB_UNICODE_IDNA_MAPPED, 1, 133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 122}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 650}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1702}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4568}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1809}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1019}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3324}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1748}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5072}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3642}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1486}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3690}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1449}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1158}, - {LXB_UNICODE_IDNA_MAPPED, 1, 423}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2199}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5149}, + {LXB_UNICODE_IDNA_MAPPED, 1, 431}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3927}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5080}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2202}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1465}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3053}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1383}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1503}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3735}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 817}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3517}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3317}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1605}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5058}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3823}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1565}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3741}, {LXB_UNICODE_IDNA_MAPPED, 1, 1720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 177}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1869}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1893}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 888}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4057}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2963}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1064}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2288}, + {LXB_UNICODE_IDNA_MAPPED, 1, 790}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 305}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5013}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5363}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3566}, + {LXB_UNICODE_IDNA_MAPPED, 2, 550}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4141}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1214}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5166}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5333}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3038}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3466}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 884}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4014}, + {LXB_UNICODE_IDNA_MAPPED, 1, 661}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3202}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1744}, + {LXB_UNICODE_IDNA_MAPPED, 2, 962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1755}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1099}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1022}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 425}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4320}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1073}, {LXB_UNICODE_IDNA_MAPPED, 1, 2097}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3137}, - {LXB_UNICODE_IDNA_MAPPED, 1, 429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3030}, - {LXB_UNICODE_IDNA_MAPPED, 1, 353}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3104}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 386}, - {LXB_UNICODE_IDNA_MAPPED, 2, 186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5294}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1565}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1643}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2213}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3979}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3116}, - {LXB_UNICODE_IDNA_MAPPED, 1, 727}, - {LXB_UNICODE_IDNA_MAPPED, 2, 548}, - {LXB_UNICODE_IDNA_MAPPED, 1, 182}, - {LXB_UNICODE_IDNA_MAPPED, 6, 2744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5349}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2135}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4333}, - {LXB_UNICODE_IDNA_MAPPED, 1, 166}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1066}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3671}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3108}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1106}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3690}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3267}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1382}, + {LXB_UNICODE_IDNA_MAPPED, 2, 576}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4748}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4391}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2596}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 299}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2824}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1704}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1817}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4905}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4605}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4591}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5361}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1288}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4630}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4084}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4702}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5216}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3441}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4637}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3191}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2015}, + {LXB_UNICODE_IDNA_MAPPED, 2, 35}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3907}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 370}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3941}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4454}, + {LXB_UNICODE_IDNA_MAPPED, 2, 188}, + {LXB_UNICODE_IDNA_MAPPED, 1, 243}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3150}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3654}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 417}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1912}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5026}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1478}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3462}, + {LXB_UNICODE_IDNA_MAPPED, 1, 519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 89}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3388}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4008}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 362}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1973}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1543}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3385}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2675}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5020}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1191}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2992}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2865}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3283}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 83}, + {LXB_UNICODE_IDNA_MAPPED, 1, 145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4920}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3101}, + {LXB_UNICODE_IDNA_MAPPED, 1, 371}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3234}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1566}, {LXB_UNICODE_IDNA_MAPPED, 1, 410}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5060}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1650}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5158}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1507}, + {LXB_UNICODE_IDNA_DEVIATION, 0, 0}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 344}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3622}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4700}, + {LXB_UNICODE_IDNA_MAPPED, 1, 148}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1413}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4626}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4697}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1869}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2951}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4547}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2715}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4416}, + {LXB_UNICODE_IDNA_MAPPED, 1, 178}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4448}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1547}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2991}, + {LXB_UNICODE_IDNA_MAPPED, 1, 374}, + {LXB_UNICODE_IDNA_MAPPED, 1, 722}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3383}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1141}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2643}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5055}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 326}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5092}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3534}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4564}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4478}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2954}, + {LXB_UNICODE_IDNA_MAPPED, 1, 528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 314}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3344}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3652}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1194}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3067}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3235}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4907}, + {LXB_UNICODE_IDNA_MAPPED, 2, 597}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3867}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3311}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3346}, + {LXB_UNICODE_IDNA_MAPPED, 1, 355}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4577}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1782}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3070}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4829}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1042}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3937}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5001}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4012}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2939}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5118}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3028}, + {LXB_UNICODE_IDNA_MAPPED, 1, 37}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1616}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4726}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5144}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1591}, {LXB_UNICODE_IDNA_MAPPED, 3, 2359}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1792}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4693}, - {LXB_UNICODE_IDNA_MAPPED, 1, 366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4561}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5326}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4598}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1582}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3014}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4721}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1645}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1407}, - {LXB_UNICODE_IDNA_MAPPED, 1, 390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1755}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4847}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3400}, - {LXB_UNICODE_IDNA_MAPPED, 3, 599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1502}, - {LXB_UNICODE_IDNA_MAPPED, 1, 121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 67}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3236}, - {LXB_UNICODE_IDNA_MAPPED, 1, 454}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3358}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2080}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1732}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3643}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5149}, - {LXB_UNICODE_IDNA_MAPPED, 1, 502}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 51}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1731}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3695}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 82}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3522}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4426}, {LXB_UNICODE_IDNA_MAPPED, 1, 440}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 676}, + {LXB_UNICODE_IDNA_MAPPED, 1, 167}, + {LXB_UNICODE_IDNA_MAPPED, 1, 742}, + {LXB_UNICODE_IDNA_MAPPED, 1, 879}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1818}, + {LXB_UNICODE_IDNA_MAPPED, 1, 100}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1724}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5023}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 163}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3248}, + {LXB_UNICODE_IDNA_MAPPED, 1, 915}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3047}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4975}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1610}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3600}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5180}, + {LXB_UNICODE_IDNA_MAPPED, 1, 252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 907}, + {LXB_UNICODE_IDNA_MAPPED, 1, 780}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4108}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4936}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4903}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3247}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1404}, + {LXB_UNICODE_IDNA_MAPPED, 1, 672}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5203}, + {LXB_UNICODE_IDNA_MAPPED, 2, 602}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2119}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2692}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1692}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3492}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3787}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5238}, {LXB_UNICODE_IDNA_MAPPED, 1, 897}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4664}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4938}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3858}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4503}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1132}, - {LXB_UNICODE_IDNA_MAPPED, 1, 202}, - {LXB_UNICODE_IDNA_MAPPED, 2, 940}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2865}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3170}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1730}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4548}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2629}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1628}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3112}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2966}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3956}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5209}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3981}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1773}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5316}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4443}, - {LXB_UNICODE_IDNA_MAPPED, 2, 968}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4512}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3354}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5341}, - {LXB_UNICODE_IDNA_MAPPED, 1, 488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4416}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5293}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2826}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 699}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4932}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3119}, - {LXB_UNICODE_IDNA_MAPPED, 1, 668}, - {LXB_UNICODE_IDNA_MAPPED, 1, 467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 841}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4007}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3552}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1402}, - {LXB_UNICODE_IDNA_MAPPED, 1, 274}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5167}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4794}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 874}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2443}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1303}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5390}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4886}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3004}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1507}, - {LXB_UNICODE_IDNA_MAPPED, 1, 376}, - {LXB_UNICODE_IDNA_MAPPED, 1, 295}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2083}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1719}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5053}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1435}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2094}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3456}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3136}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4524}, - {LXB_UNICODE_IDNA_MAPPED, 1, 137}, - {LXB_UNICODE_IDNA_MAPPED, 1, 634}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3042}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3193}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3201}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4565}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1442}, - {LXB_UNICODE_IDNA_MAPPED, 1, 877}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3327}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4601}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4871}, - {LXB_UNICODE_IDNA_MAPPED, 1, 913}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3566}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4267}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4060}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5009}, - {LXB_UNICODE_IDNA_MAPPED, 1, 807}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2292}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3803}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 503}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1759}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3974}, + {LXB_UNICODE_IDNA_MAPPED, 2, 41}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4393}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3650}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2062}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1198}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2840}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1079}, + {LXB_UNICODE_IDNA_MAPPED, 1, 316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3125}, + {LXB_UNICODE_IDNA_MAPPED, 1, 679}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4837}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3402}, + {LXB_UNICODE_IDNA_MAPPED, 1, 396}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4309}, {LXB_UNICODE_IDNA_MAPPED, 1, 3307}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5138}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3425}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4183}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2968}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5203}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1609}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2868}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2788}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3068}, - {LXB_UNICODE_IDNA_MAPPED, 1, 165}, - {LXB_UNICODE_IDNA_MAPPED, 2, 950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3111}, - {LXB_UNICODE_IDNA_MAPPED, 1, 829}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4469}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5378}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5309}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3784}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4069}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4852}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3114}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4676}, + {LXB_UNICODE_IDNA_MAPPED, 2, 942}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2981}, + {LXB_UNICODE_IDNA_MAPPED, 1, 784}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5256}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4586}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1796}, + {LXB_UNICODE_IDNA_MAPPED, 1, 61}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3925}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1206}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2764}, + {LXB_UNICODE_IDNA_MAPPED, 1, 991}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3323}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3638}, + {LXB_UNICODE_IDNA_MAPPED, 1, 110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4473}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2505}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4380}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1577}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5368}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4438}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 364}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2623}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3220}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1743}, + {LXB_UNICODE_IDNA_MAPPED, 2, 934}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3869}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3551}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5375}, {LXB_UNICODE_IDNA_MAPPED, 1, 2946}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1202}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5021}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1482}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4001}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3097}, - {LXB_UNICODE_IDNA_MAPPED, 1, 136}, - {LXB_UNICODE_IDNA_MAPPED, 2, 576}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4562}, - {LXB_UNICODE_IDNA_MAPPED, 2, 570}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1583}, - {LXB_UNICODE_IDNA_MAPPED, 1, 418}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3440}, - {LXB_UNICODE_IDNA_MAPPED, 1, 351}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4979}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3902}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3938}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 817}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3281}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5270}, - {LXB_UNICODE_IDNA_MAPPED, 1, 745}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4914}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3320}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1503}, - {LXB_UNICODE_IDNA_MAPPED, 1, 684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5044}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1752}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2145}, - {LXB_UNICODE_IDNA_MAPPED, 1, 471}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2091}, - {LXB_UNICODE_IDNA_MAPPED, 1, 837}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3482}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2070}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2139}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1842}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 257}, + {LXB_UNICODE_IDNA_MAPPED, 1, 747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3815}, + {LXB_UNICODE_IDNA_MAPPED, 1, 727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5250}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2317}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1643}, + {LXB_UNICODE_IDNA_MAPPED, 1, 718}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4781}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 372}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3485}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4839}, + {LXB_UNICODE_IDNA_MAPPED, 1, 69}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5294}, + {LXB_UNICODE_IDNA_MAPPED, 1, 783}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3767}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3242}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4234}, + {LXB_UNICODE_IDNA_MAPPED, 1, 312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 66}, {LXB_UNICODE_IDNA_MAPPED, 1, 5280}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5255}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1531}, - {LXB_UNICODE_IDNA_MAPPED, 2, 265}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2012}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2987}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5055}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5387}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5165}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 516}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3904}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 425}, - {LXB_UNICODE_IDNA_MAPPED, 3, 47}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1786}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4809}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4610}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1638}, - {LXB_UNICODE_IDNA_MAPPED, 1, 648}, - {LXB_UNICODE_IDNA_MAPPED, 2, 591}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1610}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3439}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3306}, - {LXB_UNICODE_IDNA_MAPPED, 2, 619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5247}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4454}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1707}, + {LXB_UNICODE_IDNA_MAPPED, 1, 378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5254}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5127}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5152}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3674}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 118}, + {LXB_UNICODE_IDNA_MAPPED, 1, 686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 781}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3655}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3849}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1736}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2141}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3474}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1395}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3513}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2936}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5097}, + {LXB_UNICODE_IDNA_MAPPED, 1, 365}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4614}, + {LXB_UNICODE_IDNA_MAPPED, 1, 303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2071}, + {LXB_UNICODE_IDNA_MAPPED, 1, 151}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3707}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2916}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1687}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3019}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1893}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3711}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3933}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4513}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3660}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2844}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3172}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 325}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3031}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1029}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5287}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2942}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2637}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1190}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3325}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4093}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1101}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1967}, + {LXB_UNICODE_IDNA_MAPPED, 1, 160}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4843}, + {LXB_UNICODE_IDNA_MAPPED, 1, 475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4467}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2631}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4611}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3328}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1764}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4589}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5276}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3134}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3923}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2770}, + {LXB_UNICODE_IDNA_MAPPED, 2, 562}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3120}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5066}, + {LXB_UNICODE_IDNA_MAPPED, 1, 84}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4690}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5351}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1730}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3986}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3331}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1534}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3913}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2068}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3701}, + {LXB_UNICODE_IDNA_MAPPED, 1, 833}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2046}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2048}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2536}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4375}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3007}, {LXB_UNICODE_IDNA_MAPPED, 1, 5122}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1753}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3790}, - {LXB_UNICODE_IDNA_MAPPED, 1, 72}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 408}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5012}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2296}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4797}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2782}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1704}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4487}, - {LXB_UNICODE_IDNA_MAPPED, 1, 373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 847}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 500}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4555}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5092}, - {LXB_UNICODE_IDNA_MAPPED, 1, 438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 50}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2079}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3168}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 910}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4998}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1005}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 324}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1664}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5148}, + {LXB_UNICODE_IDNA_MAPPED, 1, 414}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5260}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5404}, + {LXB_UNICODE_IDNA_MAPPED, 2, 113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2188}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2147}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3855}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 453}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3507}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4794}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5274}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4822}, + {LXB_UNICODE_IDNA_MAPPED, 1, 67}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2153}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3861}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4431}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1398}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1419}, + {LXB_UNICODE_IDNA_MAPPED, 1, 895}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3477}, + {LXB_UNICODE_IDNA_MAPPED, 1, 485}, + {LXB_UNICODE_IDNA_MAPPED, 1, 723}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3972}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5100}, + {LXB_UNICODE_IDNA_MAPPED, 1, 416}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3680}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1714}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1748}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4979}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2212}, + {LXB_UNICODE_IDNA_MAPPED, 2, 568}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4410}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3839}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 350}, + {LXB_UNICODE_IDNA_MAPPED, 2, 207}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5388}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3711}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2073}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3167}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3229}, + {LXB_UNICODE_IDNA_MAPPED, 1, 917}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5415}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 906}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1630}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5340}, + {LXB_UNICODE_IDNA_MAPPED, 2, 542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3064}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1776}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 834}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2475}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3341}, + {LXB_UNICODE_IDNA_MAPPED, 1, 644}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5307}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3130}, + {LXB_UNICODE_IDNA_MAPPED, 1, 421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3197}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3139}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4569}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2185}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4579}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1787}, + {LXB_UNICODE_IDNA_MAPPED, 1, 447}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3535}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2180}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4624}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1539}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2988}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4915}, + {LXB_UNICODE_IDNA_MAPPED, 1, 690}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2183}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2720}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1700}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5334}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1991}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5209}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3166}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3657}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 239}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5235}, + {LXB_UNICODE_IDNA_MAPPED, 1, 698}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1049}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5106}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4476}, + {LXB_UNICODE_IDNA_MAPPED, 1, 836}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4931}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1908}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4948}, {LXB_UNICODE_IDNA_MAPPED, 1, 3421}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3550}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4585}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3565}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5284}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3651}, + {LXB_UNICODE_IDNA_MAPPED, 1, 867}, + {LXB_UNICODE_IDNA_MAPPED, 3, 41}, + {LXB_UNICODE_IDNA_MAPPED, 1, 215}, + {LXB_UNICODE_IDNA_MAPPED, 1, 386}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2874}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1062}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2101}, + {LXB_UNICODE_IDNA_MAPPED, 1, 369}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3871}, + {LXB_UNICODE_IDNA_MAPPED, 1, 470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4572}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3278}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4664}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1952}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2883}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1363}, {LXB_UNICODE_IDNA_MAPPED, 1, 5019}, - {LXB_UNICODE_IDNA_MAPPED, 1, 161}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 706}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3488}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 156}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3959}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1698}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4010}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2706}, {LXB_UNICODE_IDNA_MAPPED, 2, 1171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1516}, - {LXB_UNICODE_IDNA_MAPPED, 1, 851}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4943}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1437}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 395}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1490}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2974}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3457}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2980}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1622}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2185}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2828}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4923}, - {LXB_UNICODE_IDNA_MAPPED, 2, 524}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4650}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4566}, - {LXB_UNICODE_IDNA_MAPPED, 1, 171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1588}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3092}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3049}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3139}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2095}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4523}, - {LXB_UNICODE_IDNA_MAPPED, 1, 909}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3176}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 449}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2439}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4916}, + {LXB_UNICODE_IDNA_MAPPED, 1, 850}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5006}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2192}, + {LXB_UNICODE_IDNA_MAPPED, 2, 613}, + {LXB_UNICODE_IDNA_MAPPED, 2, 926}, + {LXB_UNICODE_IDNA_MAPPED, 2, 259}, + {LXB_UNICODE_IDNA_MAPPED, 2, 106}, + {LXB_UNICODE_IDNA_MAPPED, 1, 121}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2698}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1695}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4867}, + {LXB_UNICODE_IDNA_MAPPED, 1, 74}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3408}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3059}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5233}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1406}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4207}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3664}, + {LXB_UNICODE_IDNA_MAPPED, 1, 169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5207}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4833}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2123}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3831}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1624}, + {LXB_UNICODE_IDNA_MAPPED, 1, 413}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4729}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 650}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5094}, + {LXB_UNICODE_IDNA_MAPPED, 1, 477}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2373}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3504}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4732}, + {LXB_UNICODE_IDNA_MAPPED, 1, 827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 281}, + {LXB_UNICODE_IDNA_MAPPED, 1, 216}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2366}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3863}, {LXB_UNICODE_IDNA_MAPPED, 1, 1508}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2596}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2193}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4646}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3755}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1372}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4720}, + {LXB_UNICODE_IDNA_MAPPED, 1, 878}, + {LXB_UNICODE_IDNA_MAPPED, 1, 285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 358}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3582}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5380}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 357}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4717}, + {LXB_UNICODE_IDNA_MAPPED, 2, 987}, + {LXB_UNICODE_IDNA_MAPPED, 1, 230}, + {LXB_UNICODE_IDNA_MAPPED, 2, 611}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4635}, + {LXB_UNICODE_IDNA_MAPPED, 1, 745}, + {LXB_UNICODE_IDNA_MAPPED, 1, 901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3296}, + {LXB_UNICODE_IDNA_MAPPED, 1, 196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3391}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1067}, + {LXB_UNICODE_IDNA_MAPPED, 1, 737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5228}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1527}, + {LXB_UNICODE_IDNA_MAPPED, 1, 821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 409}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3871}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1049}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4773}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1135}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3085}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2598}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4592}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1805}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4913}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5010}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4555}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5261}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3829}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3374}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1656}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 165}, + {LXB_UNICODE_IDNA_MAPPED, 2, 819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 411}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3365}, + {LXB_UNICODE_IDNA_MAPPED, 1, 731}, + {LXB_UNICODE_IDNA_MAPPED, 3, 604}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1294}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2669}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3769}, + {LXB_UNICODE_IDNA_MAPPED, 2, 0}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1370}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4369}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2102}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4231}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3996}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1423}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3553}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 359}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 505}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3158}, + {LXB_UNICODE_IDNA_MAPPED, 1, 289}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2283}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5017}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5319}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1474}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1706}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1839}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5039}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5029}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3039}, + {LXB_UNICODE_IDNA_MAPPED, 1, 373}, {LXB_UNICODE_IDNA_MAPPED, 2, 607}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 322}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3942}, - {LXB_UNICODE_IDNA_MAPPED, 1, 85}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3670}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4518}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3079}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2621}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2424}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5334}, - {LXB_UNICODE_IDNA_MAPPED, 1, 703}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 580}, - {LXB_UNICODE_IDNA_MAPPED, 1, 65}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4661}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3946}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2936}, - {LXB_UNICODE_IDNA_MAPPED, 1, 624}, - {LXB_UNICODE_IDNA_MAPPED, 1, 879}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 885}, - {LXB_UNICODE_IDNA_MAPPED, 1, 805}, - {LXB_UNICODE_IDNA_MAPPED, 1, 915}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1265}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1002}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3651}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 439}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3266}, + {LXB_UNICODE_IDNA_MAPPED, 1, 231}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3288}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1576}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1019}, + {LXB_UNICODE_IDNA_MAPPED, 1, 908}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3204}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3077}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5008}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4408}, + {LXB_UNICODE_IDNA_MAPPED, 1, 726}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 904}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3052}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3027}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3080}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4328}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 501}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3892}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1529}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 674}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 441}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3228}, + {LXB_UNICODE_IDNA_MAPPED, 1, 323}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4844}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4398}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 899}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4746}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2095}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3781}, {LXB_UNICODE_IDNA_MAPPED, 1, 5175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1733}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3290}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1627}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3239}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4547}, - {LXB_UNICODE_IDNA_MAPPED, 1, 150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 422}, - {LXB_UNICODE_IDNA_MAPPED, 1, 811}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1787}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1425}, - {LXB_UNICODE_IDNA_MAPPED, 2, 275}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1404}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5237}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1646}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1495}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5352}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4690}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1194}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4526}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3128}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3704}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5084}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3091}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1660}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4801}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 748}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4990}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3817}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3624}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2546}, + {LXB_UNICODE_IDNA_MAPPED, 3, 47}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 108}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3737}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4661}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4622}, + {LXB_UNICODE_IDNA_MAPPED, 2, 946}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3789}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4834}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3351}, + {LXB_UNICODE_IDNA_MAPPED, 1, 75}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3468}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4490}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4810}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2572}, + {LXB_UNICODE_IDNA_MAPPED, 1, 983}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4493}, {LXB_UNICODE_IDNA_MAPPED, 1, 3105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5212}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5323}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1475}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2754}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3325}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4962}, - {LXB_UNICODE_IDNA_MAPPED, 2, 970}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3420}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2971}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1884}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2048}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1791}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1866}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3302}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1695}, - {LXB_UNICODE_IDNA_MAPPED, 1, 694}, - {LXB_UNICODE_IDNA_MAPPED, 1, 747}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1422}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4039}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2796}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5087}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1202}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4601}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1811}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4606}, + {LXB_UNICODE_IDNA_MAPPED, 1, 408}, + {LXB_UNICODE_IDNA_MAPPED, 1, 640}, {LXB_UNICODE_IDNA_MAPPED, 1, 3314}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3864}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5425}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 746}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1489}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4768}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4967}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3178}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3569}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4865}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 646}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4906}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2999}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1746}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5146}, + {LXB_UNICODE_IDNA_MAPPED, 1, 380}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5402}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1637}, + {LXB_UNICODE_IDNA_MAPPED, 8, 4361}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5120}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 50}, + {LXB_UNICODE_IDNA_MAPPED, 1, 90}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3209}, + {LXB_UNICODE_IDNA_MAPPED, 1, 499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2927}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4951}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5047}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2234}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1546}, + {LXB_UNICODE_IDNA_MAPPED, 1, 654}, + {LXB_UNICODE_IDNA_MAPPED, 2, 944}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5085}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3533}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1738}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5328}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 684}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 438}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4276}, + {LXB_UNICODE_IDNA_MAPPED, 1, 702}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2106}, + {LXB_UNICODE_IDNA_MAPPED, 1, 663}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1872}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4755}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3260}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5267}, + {LXB_UNICODE_IDNA_MAPPED, 1, 782}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5341}, + {LXB_UNICODE_IDNA_MAPPED, 1, 720}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5074}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1567}, + {LXB_UNICODE_IDNA_MAPPED, 1, 172}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4855}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3011}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1506}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5188}, + {LXB_UNICODE_IDNA_MAPPED, 1, 474}, + {LXB_UNICODE_IDNA_MAPPED, 1, 740}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2025}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2198}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3152}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3349}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2932}, + {LXB_UNICODE_IDNA_MAPPED, 1, 64}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5214}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4533}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1674}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2754}, + {LXB_UNICODE_IDNA_MAPPED, 1, 468}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3272}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4603}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4762}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1814}, + {LXB_UNICODE_IDNA_MAPPED, 1, 911}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3042}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3500}, + {LXB_UNICODE_IDNA_MAPPED, 1, 883}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3433}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3919}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4683}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2784}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3389}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2581}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3957}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3058}, + {LXB_UNICODE_IDNA_MAPPED, 1, 476}, + {LXB_UNICODE_IDNA_MAPPED, 2, 534}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2590}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1032}, + {LXB_UNICODE_IDNA_MAPPED, 1, 769}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4655}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3396}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3151}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3463}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1458}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5296}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1011}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4075}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2958}, + {LXB_UNICODE_IDNA_MAPPED, 1, 352}, + {LXB_UNICODE_IDNA_MAPPED, 2, 526}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5323}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5091}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2109}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3815}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3508}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1609}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1988}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3414}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 415}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2203}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5346}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3537}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1438}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5272}, + {LXB_UNICODE_IDNA_MAPPED, 1, 348}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1378}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4921}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4270}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4857}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1381}, + {LXB_UNICODE_IDNA_MAPPED, 2, 564}, + {LXB_UNICODE_IDNA_MAPPED, 2, 918}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5315}, + {LXB_UNICODE_IDNA_MAPPED, 1, 307}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1740}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 848}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3480}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1650}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4644}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4539}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4006}, + {LXB_UNICODE_IDNA_MAPPED, 1, 471}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3359}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3384}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3577}, + {LXB_UNICODE_IDNA_MAPPED, 1, 669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 152}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5133}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1919}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 835}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 383}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5061}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3527}, + {LXB_UNICODE_IDNA_MAPPED, 1, 319}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3458}, + {LXB_UNICODE_IDNA_MAPPED, 2, 538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1559}, {LXB_UNICODE_IDNA_MAPPED, 1, 1540}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 815}, - {LXB_UNICODE_IDNA_MAPPED, 1, 420}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1810}, - {LXB_UNICODE_IDNA_MAPPED, 1, 341}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 75}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5285}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 834}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4543}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1741}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3294}, + {LXB_UNICODE_IDNA_MAPPED, 1, 381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3401}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3945}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3146}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4388}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4771}, {LXB_UNICODE_IDNA_MAPPED, 1, 4638}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2910}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5017}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 68}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1601}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3060}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1035}, - {LXB_UNICODE_IDNA_MAPPED, 1, 129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 902}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4986}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4165}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2027}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5157}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3083}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2603}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4641}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3909}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3020}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2012}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4926}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4395}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4553}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1500}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3437}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3438}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2826}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4714}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5396}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1261}, + {LXB_UNICODE_IDNA_MAPPED, 1, 473}, + {LXB_UNICODE_IDNA_MAPPED, 1, 635}, + {LXB_UNICODE_IDNA_MAPPED, 2, 546}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2832}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1679}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4909}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 158}, + {LXB_UNICODE_IDNA_MAPPED, 1, 849}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3406}, + {LXB_UNICODE_IDNA_MAPPED, 1, 682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1767}, + {LXB_UNICODE_IDNA_MAPPED, 1, 704}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2170}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4999}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2178}, + {LXB_UNICODE_IDNA_MAPPED, 2, 922}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4749}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1644}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2100}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3074}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3024}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5034}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3188}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1375}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1638}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5059}, + {LXB_UNICODE_IDNA_MAPPED, 1, 346}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4980}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3254}, + {LXB_UNICODE_IDNA_MAPPED, 2, 930}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1386}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1617}, + {LXB_UNICODE_IDNA_MAPPED, 1, 851}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1589}, + {LXB_UNICODE_IDNA_MAPPED, 1, 52}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5178}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4525}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3897}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4610}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5338}, + {LXB_UNICODE_IDNA_MAPPED, 1, 483}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2948}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1471}, + {LXB_UNICODE_IDNA_MAPPED, 6, 2303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2208}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 229}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1604}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1153}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1339}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5014}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1102}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 697}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1071}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 648}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5204}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4923}, + {LXB_UNICODE_IDNA_MAPPED, 2, 956}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3449}, + {LXB_UNICODE_IDNA_MAPPED, 1, 823}, + {LXB_UNICODE_IDNA_MAPPED, 2, 581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4442}, + {LXB_UNICODE_IDNA_MAPPED, 1, 97}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3799}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5161}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3865}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2776}, {LXB_UNICODE_IDNA_MAPPED, 1, 248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5264}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5198}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2067}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 749}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1093}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4020}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5164}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5331}, + {LXB_UNICODE_IDNA_MAPPED, 1, 85}, + {LXB_UNICODE_IDNA_MAPPED, 1, 858}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3980}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5212}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3521}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4156}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1462}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2904}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2850}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5227}, + {LXB_UNICODE_IDNA_MAPPED, 1, 633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1622}, + {LXB_UNICODE_IDNA_MAPPED, 1, 762}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2913}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5304}, {LXB_UNICODE_IDNA_MAPPED, 1, 5108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1550}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2104}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5234}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4947}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4668}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 723}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2766}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4960}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1285}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1735}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4976}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3697}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3949}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1732}, + {LXB_UNICODE_IDNA_MAPPED, 1, 330}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1613}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1390}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3503}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3596}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5176}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3343}, + {LXB_UNICODE_IDNA_MAPPED, 1, 367}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2215}, + {LXB_UNICODE_IDNA_MAPPED, 1, 250}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3066}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1778}, + {LXB_UNICODE_IDNA_MAPPED, 2, 924}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4871}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1521}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4306}, + {LXB_UNICODE_IDNA_MAPPED, 2, 591}, + {LXB_UNICODE_IDNA_MAPPED, 1, 622}, + {LXB_UNICODE_IDNA_MAPPED, 1, 375}, + {LXB_UNICODE_IDNA_MAPPED, 2, 587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 98}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4475}, + {LXB_UNICODE_IDNA_MAPPED, 1, 716}, + {LXB_UNICODE_IDNA_MAPPED, 1, 203}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2032}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1931}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2952}, + {LXB_UNICODE_IDNA_MAPPED, 1, 798}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2078}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3717}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4571}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4928}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2989}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4740}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1053}, + {LXB_UNICODE_IDNA_MAPPED, 1, 489}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4663}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3164}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4551}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4919}, + {LXB_UNICODE_IDNA_MAPPED, 1, 692}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4696}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3616}, + {LXB_UNICODE_IDNA_MAPPED, 1, 443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3368}, + {LXB_UNICODE_IDNA_MAPPED, 2, 940}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4548}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2337}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3005}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4597}, {LXB_UNICODE_IDNA_MAPPED, 1, 4474}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4626}, - {LXB_UNICODE_IDNA_MAPPED, 2, 926}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3274}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2195}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2184}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3822}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4606}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 881}, - {LXB_UNICODE_IDNA_MAPPED, 1, 639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4712}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3814}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3012}, - {LXB_UNICODE_IDNA_MAPPED, 1, 176}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1416}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4623}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5317}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4709}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4123}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1946}, + {LXB_UNICODE_IDNA_MAPPED, 1, 214}, {LXB_UNICODE_IDNA_MAPPED, 1, 5302}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2532}, - {LXB_UNICODE_IDNA_MAPPED, 2, 530}, - {LXB_UNICODE_IDNA_MAPPED, 1, 52}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2025}, - {LXB_UNICODE_IDNA_MAPPED, 1, 445}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3346}, - {LXB_UNICODE_IDNA_MAPPED, 1, 169}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4731}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3280}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1070}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 796}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 331}, + {LXB_UNICODE_IDNA_MAPPED, 3, 995}, + {LXB_UNICODE_IDNA_MAPPED, 1, 729}, {LXB_UNICODE_IDNA_MAPPED, 1, 5383}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1925}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3501}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2224}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5163}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4419}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2063}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4676}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2951}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5073}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5260}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3480}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2898}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1656}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5134}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 764}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3656}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1025}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2656}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5411}, + {LXB_UNICODE_IDNA_MAPPED, 1, 861}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5137}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3210}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4412}, + {LXB_UNICODE_IDNA_MAPPED, 1, 826}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 57}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4617}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1035}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1716}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2938}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1452}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4402}, {LXB_UNICODE_IDNA_MAPPED, 1, 5153}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1631}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 859}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1485}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5117}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2266}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1561}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3489}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1158}, + {LXB_UNICODE_IDNA_MAPPED, 1, 127}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3547}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5244}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 893}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3801}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5360}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2727}, {LXB_UNICODE_IDNA_MAPPED, 1, 3246}, - {LXB_UNICODE_IDNA_MAPPED, 2, 0}, - {LXB_UNICODE_IDNA_MAPPED, 1, 70}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4814}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 843}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2643}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2448}, - {LXB_UNICODE_IDNA_MAPPED, 2, 261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 663}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5310}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4432}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3468}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3732}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 627}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1360}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2972}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1854}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3243}, + {LXB_UNICODE_IDNA_MAPPED, 1, 824}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5284}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1790}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4582}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3667}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4930}, + {LXB_UNICODE_IDNA_MAPPED, 1, 795}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5412}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3837}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4511}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3921}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1357}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1887}, + {LXB_UNICODE_IDNA_MAPPED, 1, 280}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5139}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4701}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5268}, + {LXB_UNICODE_IDNA_MAPPED, 1, 495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 338}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 754}, + {LXB_UNICODE_IDNA_MAPPED, 1, 191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3330}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3100}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3018}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3284}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3915}, + {LXB_UNICODE_IDNA_MAPPED, 1, 444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3097}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2050}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3413}, + {LXB_UNICODE_IDNA_MAPPED, 1, 295}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2979}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1596}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 56}, {LXB_UNICODE_IDNA_MAPPED, 1, 3071}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1315}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1783}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2084}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3347}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3310}, + {LXB_UNICODE_IDNA_MAPPED, 1, 736}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5046}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4506}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3122}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2811}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4688}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1277}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4853}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4679}, + {LXB_UNICODE_IDNA_MAPPED, 1, 294}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 875}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5378}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2709}, + {LXB_UNICODE_IDNA_MAPPED, 1, 423}, + {LXB_UNICODE_IDNA_MAPPED, 1, 125}, {LXB_UNICODE_IDNA_MAPPED, 1, 2209}, - {LXB_UNICODE_IDNA_MAPPED, 1, 623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2941}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3045}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3398}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2727}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4285}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4881}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3021}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1735}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4803}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4595}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4475}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 946}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2492}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1456}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 365}, - {LXB_UNICODE_IDNA_MAPPED, 1, 823}, - {LXB_UNICODE_IDNA_MAPPED, 1, 507}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2925}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1463}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3076}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4961}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4711}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3244}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 254}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3369}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5321}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2922}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3499}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3254}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3218}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3177}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4993}, - {LXB_UNICODE_IDNA_MAPPED, 1, 867}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4763}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1988}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4967}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5368}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4373}, - {LXB_UNICODE_IDNA_MAPPED, 1, 80}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4841}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3336}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3287}, - {LXB_UNICODE_IDNA_MAPPED, 1, 111}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 783}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5016}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3044}, - {LXB_UNICODE_IDNA_MAPPED, 1, 646}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5095}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1469}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 330}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2208}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4578}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3072}, - {LXB_UNICODE_IDNA_MAPPED, 1, 370}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4822}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2260}, - {LXB_UNICODE_IDNA_MAPPED, 1, 243}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4430}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1450}, - {LXB_UNICODE_IDNA_MAPPED, 1, 711}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 462}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3495}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4415}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4451}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4734}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5416}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4615}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1089}, + {LXB_UNICODE_IDNA_MAPPED, 1, 516}, + {LXB_UNICODE_IDNA_MAPPED, 2, 31}, + {LXB_UNICODE_IDNA_MAPPED, 1, 327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2070}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1749}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5365}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1709}, + {LXB_UNICODE_IDNA_MAPPED, 1, 170}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2189}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3853}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 815}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2376}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2314}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5259}, + {LXB_UNICODE_IDNA_MAPPED, 2, 265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5224}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4849}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1563}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2935}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3998}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1397}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3404}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3476}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4733}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5112}, + {LXB_UNICODE_IDNA_MAPPED, 2, 978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5247}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1226}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1860}, + {LXB_UNICODE_IDNA_MAPPED, 1, 385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5357}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 792}, + {LXB_UNICODE_IDNA_MAPPED, 1, 194}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4823}, + {LXB_UNICODE_IDNA_MAPPED, 1, 530}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3109}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2766}, + {LXB_UNICODE_IDNA_MAPPED, 1, 224}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1535}, + {LXB_UNICODE_IDNA_MAPPED, 1, 161}, + {LXB_UNICODE_IDNA_MAPPED, 1, 694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2064}, {LXB_UNICODE_IDNA_MAPPED, 1, 3416}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3178}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4699}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2505}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1417}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5106}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 906}, - {LXB_UNICODE_IDNA_MAPPED, 1, 357}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 779}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4876}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3284}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5154}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3971}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5250}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4126}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1176}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4896}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5170}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5193}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2119}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4013}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3479}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5066}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3212}, - {LXB_UNICODE_IDNA_MAPPED, 1, 350}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2062}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4675}, - {LXB_UNICODE_IDNA_MAPPED, 1, 336}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 465}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5128}, - {LXB_UNICODE_IDNA_MAPPED, 1, 683}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 689}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2984}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3475}, + {LXB_UNICODE_IDNA_MAPPED, 2, 950}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3305}, + {LXB_UNICODE_IDNA_MAPPED, 1, 155}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3355}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3917}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3419}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1729}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3116}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5031}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 715}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3324}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2786}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3001}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1615}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 51}, + {LXB_UNICODE_IDNA_MAPPED, 1, 842}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1798}, + {LXB_UNICODE_IDNA_MAPPED, 2, 920}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2629}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3175}, + {LXB_UNICODE_IDNA_MAPPED, 1, 805}, + {LXB_UNICODE_IDNA_MAPPED, 1, 99}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 368}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2838}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4847}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3015}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3094}, + {LXB_UNICODE_IDNA_MAPPED, 1, 402}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3693}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4099}, + {LXB_UNICODE_IDNA_MAPPED, 1, 687}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1896}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3403}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3606}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 432}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5324}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5050}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4677}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4842}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1905}, + {LXB_UNICODE_IDNA_MAPPED, 1, 508}, + {LXB_UNICODE_IDNA_MAPPED, 2, 958}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4517}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5248}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5242}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5359}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2945}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4728}, + {LXB_UNICODE_IDNA_MAPPED, 1, 140}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1448}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4832}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3048}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1402}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5397}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3505}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2117}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3825}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2155}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4132}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3875}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2364}, + {LXB_UNICODE_IDNA_MAPPED, 1, 128}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1003}, {LXB_UNICODE_IDNA_MAPPED, 3, 2895}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 791}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1524}, - {LXB_UNICODE_IDNA_MAPPED, 2, 602}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5299}, - {LXB_UNICODE_IDNA_MAPPED, 2, 566}, - {LXB_UNICODE_IDNA_MAPPED, 1, 515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2958}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2026}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 183}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3730}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4905}, - {LXB_UNICODE_IDNA_MAPPED, 2, 554}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1949}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2509}, - {LXB_UNICODE_IDNA_MAPPED, 1, 738}, - {LXB_UNICODE_IDNA_MAPPED, 2, 568}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4480}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 271}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3415}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3611}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 911}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1150}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2125}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4614}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4618}, + {LXB_UNICODE_IDNA_MAPPED, 1, 426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3008}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5052}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 909}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3335}, + {LXB_UNICODE_IDNA_MAPPED, 2, 972}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1625}, + {LXB_UNICODE_IDNA_MAPPED, 1, 816}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5156}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4969}, + {LXB_UNICODE_IDNA_MAPPED, 1, 774}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3128}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4994}, + {LXB_UNICODE_IDNA_MAPPED, 1, 966}, + {LXB_UNICODE_IDNA_MAPPED, 2, 186}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2696}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5423}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 278}, + {LXB_UNICODE_IDNA_MAPPED, 2, 556}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1590}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2417}, {LXB_UNICODE_IDNA_MAPPED, 1, 5185}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4405}, - {LXB_UNICODE_IDNA_MAPPED, 1, 140}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4835}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2165}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2682}, - {LXB_UNICODE_IDNA_MAPPED, 1, 443}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3444}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1908}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4419}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4971}, + {LXB_UNICODE_IDNA_MAPPED, 1, 913}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5232}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1819}, + {LXB_UNICODE_IDNA_MAPPED, 1, 818}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4462}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3454}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2218}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1611}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4986}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5193}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4932}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3300}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2641}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2639}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4138}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2871}, {LXB_UNICODE_IDNA_MAPPED, 3, 1103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 490}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2414}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2340}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2844}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5289}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5037}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 883}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5098}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4375}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1964}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1803}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4590}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4129}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1955}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5083}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1431}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3329}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5200}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1512}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3590}, + {LXB_UNICODE_IDNA_MAPPED, 1, 806}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4404}, + {LXB_UNICODE_IDNA_MAPPED, 1, 361}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4545}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4650}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4945}, + {LXB_UNICODE_IDNA_MAPPED, 1, 717}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3170}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1494}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1027}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5308}, + {LXB_UNICODE_IDNA_MAPPED, 1, 290}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2069}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2038}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4973}, + {LXB_UNICODE_IDNA_MAPPED, 1, 218}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3370}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5042}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2044}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2538}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1734}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3121}, + {LXB_UNICODE_IDNA_MAPPED, 2, 964}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5076}, {LXB_UNICODE_IDNA_MAPPED, 1, 1414}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4632}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1087}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 131}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1031}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5221}, - {LXB_UNICODE_IDNA_MAPPED, 1, 625}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 801}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 400}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4087}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1721}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2263}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2544}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4755}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3969}, - {LXB_UNICODE_IDNA_MAPPED, 2, 574}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1433}, - {LXB_UNICODE_IDNA_MAPPED, 1, 845}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 436}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5007}, - {LXB_UNICODE_IDNA_MAPPED, 1, 875}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5104}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4156}, - {LXB_UNICODE_IDNA_MAPPED, 1, 71}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3505}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4877}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1306}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3133}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1784}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4559}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 808}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3089}, + {LXB_UNICODE_IDNA_MAPPED, 1, 377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2975}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3131}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 292}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4995}, + {LXB_UNICODE_IDNA_MAPPED, 1, 249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5060}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3041}, + {LXB_UNICODE_IDNA_MAPPED, 1, 719}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1627}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5035}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3270}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5422}, + {LXB_UNICODE_IDNA_MAPPED, 2, 985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5021}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1676}, + {LXB_UNICODE_IDNA_MAPPED, 1, 779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 406}, + {LXB_UNICODE_IDNA_MAPPED, 1, 628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4535}, {LXB_UNICODE_IDNA_MAPPED, 1, 4745}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3077}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4579}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2672}, - {LXB_UNICODE_IDNA_MAPPED, 1, 380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1632}, - {LXB_UNICODE_IDNA_MAPPED, 1, 633}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1961}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4594}, - {LXB_UNICODE_IDNA_MAPPED, 1, 179}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5358}, - {LXB_UNICODE_IDNA_MAPPED, 1, 396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4451}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4237}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5347}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5296}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3363}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4640}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4372}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1412}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2327}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3149}, - {LXB_UNICODE_IDNA_MAPPED, 1, 665}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3756}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 123}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3506}, {LXB_UNICODE_IDNA_MAPPED, 1, 892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 132}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2842}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4901}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3160}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2690}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1714}, - {LXB_UNICODE_IDNA_MAPPED, 1, 704}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 412}, - {LXB_UNICODE_IDNA_MAPPED, 1, 856}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4633}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3916}, - {LXB_UNICODE_IDNA_MAPPED, 1, 825}, + {LXB_UNICODE_IDNA_MAPPED, 1, 309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2931}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5132}, {LXB_UNICODE_IDNA_MAPPED, 1, 1466}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2961}, - {LXB_UNICODE_IDNA_MAPPED, 1, 749}, - {LXB_UNICODE_IDNA_MAPPED, 2, 558}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2546}, - {LXB_UNICODE_IDNA_MAPPED, 1, 481}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3040}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 86}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2964}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3895}, + {LXB_UNICODE_IDNA_MAPPED, 3, 286}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2200}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4396}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3287}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1315}, + {LXB_UNICODE_IDNA_MAPPED, 1, 683}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3529}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4830}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4672}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3075}, + {LXB_UNICODE_IDNA_MAPPED, 1, 802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 193}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1055}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2099}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 653}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1556}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3398}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3453}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5215}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3947}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2091}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3200}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3056}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3953}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5158}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2280}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4912}, + {LXB_UNICODE_IDNA_MAPPED, 3, 998}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4648}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3592}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3586}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1982}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4651}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4715}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2919}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2600}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3301}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2957}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 400}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1961}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1180}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5271}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1257}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2984}, {LXB_UNICODE_IDNA_MAPPED, 1, 788}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3219}, - {LXB_UNICODE_IDNA_MAPPED, 1, 332}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1397}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1261}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1459}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1655}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3399}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3872}, - {LXB_UNICODE_IDNA_MAPPED, 1, 884}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 255}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4240}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3248}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4590}, - {LXB_UNICODE_IDNA_MAPPED, 1, 281}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 672}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1946}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1570}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1797}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4950}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1676}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 862}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1928}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3000}, - {LXB_UNICODE_IDNA_MAPPED, 1, 759}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4908}, - {LXB_UNICODE_IDNA_MAPPED, 1, 517}, - {LXB_UNICODE_IDNA_MAPPED, 2, 597}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1586}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4704}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3298}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5345}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1806}, + {LXB_UNICODE_IDNA_MAPPED, 1, 202}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1204}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5000}, {LXB_UNICODE_IDNA_MAPPED, 1, 4613}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3349}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4717}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4956}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3483}, - {LXB_UNICODE_IDNA_MAPPED, 2, 936}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5116}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 903}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4634}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3132}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4503}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3194}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2993}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3905}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2388}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4778}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3090}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4500}, + {LXB_UNICODE_IDNA_MAPPED, 1, 786}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3360}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2819}, {LXB_UNICODE_IDNA_MAPPED, 1, 213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4681}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4536}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2068}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1539}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5336}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5207}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2530}, - {LXB_UNICODE_IDNA_MAPPED, 2, 546}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2557}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2954}, - {LXB_UNICODE_IDNA_MAPPED, 1, 138}, - {LXB_UNICODE_IDNA_MAPPED, 3, 44}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4999}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4604}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2322}, - {LXB_UNICODE_IDNA_MAPPED, 1, 95}, - {LXB_UNICODE_IDNA_MAPPED, 1, 763}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3385}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5243}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4399}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3583}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5346}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3277}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1710}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4625}, - {LXB_UNICODE_IDNA_MAPPED, 1, 736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 151}, - {LXB_UNICODE_IDNA_MAPPED, 1, 866}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4637}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2913}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1801}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5263}, - {LXB_UNICODE_IDNA_MAPPED, 1, 384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 416}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3410}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3666}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 852}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2994}, - {LXB_UNICODE_IDNA_MAPPED, 1, 730}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 693}, - {LXB_UNICODE_IDNA_MAPPED, 1, 680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 192}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 340}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 463}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4198}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3621}, - {LXB_UNICODE_IDNA_MAPPED, 1, 784}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1604}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4817}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 477}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3063}, - {LXB_UNICODE_IDNA_MAPPED, 1, 55}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4854}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1633}, - {LXB_UNICODE_IDNA_MAPPED, 1, 753}, - {LXB_UNICODE_IDNA_MAPPED, 1, 715}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3700}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4879}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4534}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1525}, - {LXB_UNICODE_IDNA_MAPPED, 8, 4358}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1047}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1668}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4724}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3131}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3597}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4291}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4981}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3637}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3647}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1916}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1437}, + {LXB_UNICODE_IDNA_MAPPED, 1, 398}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2042}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4939}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5257}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2925}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5150}, + {LXB_UNICODE_IDNA_MAPPED, 2, 38}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4455}, + {LXB_UNICODE_IDNA_MAPPED, 1, 898}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4294}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3843}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3148}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5102}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2248}, {LXB_UNICODE_IDNA_MAPPED, 1, 1479}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1147}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4033}, - {LXB_UNICODE_IDNA_MAPPED, 1, 912}, - {LXB_UNICODE_IDNA_MAPPED, 1, 405}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2129}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3460}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5125}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3219}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4453}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5114}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2105}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4925}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3044}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3386}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1037}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5281}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 237}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3061}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5095}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3275}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3257}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5376}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 180}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1667}, + {LXB_UNICODE_IDNA_MAPPED, 1, 894}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 675}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3661}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2018}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1333}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 506}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 647}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 397}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4656}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2551}, + {LXB_UNICODE_IDNA_MAPPED, 2, 595}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3356}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4914}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3199}, + {LXB_UNICODE_IDNA_MAPPED, 1, 337}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4027}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1646}, + {LXB_UNICODE_IDNA_MAPPED, 1, 785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2971}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3353}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4488}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3805}, + {LXB_UNICODE_IDNA_MAPPED, 1, 284}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4600}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 498}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3141}, + {LXB_UNICODE_IDNA_MAPPED, 2, 619}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4840}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4541}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3107}, + {LXB_UNICODE_IDNA_MAPPED, 2, 269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1537}, + {LXB_UNICODE_IDNA_MAPPED, 1, 490}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1606}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1132}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3442}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2569}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1997}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2947}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2082}, + {LXB_UNICODE_IDNA_MAPPED, 1, 900}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3412}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1902}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4516}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3319}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4609}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3002}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5427}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4895}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4385}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3037}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 154}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3000}, + {LXB_UNICODE_IDNA_MAPPED, 1, 366}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5277}, + {LXB_UNICODE_IDNA_MAPPED, 1, 703}, + {LXB_UNICODE_IDNA_MAPPED, 1, 452}, + {LXB_UNICODE_IDNA_MAPPED, 1, 124}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3572}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4884}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5086}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5419}, {LXB_UNICODE_IDNA_MAPPED, 1, 5179}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1597}, - {LXB_UNICODE_IDNA_MAPPED, 1, 393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 849}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2210}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3211}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3318}, - {LXB_UNICODE_IDNA_MAPPED, 2, 956}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1878}, - {LXB_UNICODE_IDNA_MAPPED, 1, 402}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1014}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1699}, - {LXB_UNICODE_IDNA_MAPPED, 1, 216}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5031}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1418}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 102}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1351}, - {LXB_UNICODE_IDNA_MAPPED, 1, 383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5211}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4788}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1441}, + {LXB_UNICODE_IDNA_MAPPED, 1, 912}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1726}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3811}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2107}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1580}, + {LXB_UNICODE_IDNA_MAPPED, 1, 829}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5119}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5262}, + {LXB_UNICODE_IDNA_MAPPED, 2, 932}, + {LXB_UNICODE_IDNA_MAPPED, 1, 328}, + {LXB_UNICODE_IDNA_MAPPED, 1, 479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2220}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4991}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3245}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4826}, + {LXB_UNICODE_IDNA_MAPPED, 1, 379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3046}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1002}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1654}, + {LXB_UNICODE_IDNA_MAPPED, 1, 481}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5381}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3490}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1476}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 190}, + {LXB_UNICODE_IDNA_MAPPED, 1, 197}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4619}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2260}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3793}, + {LXB_UNICODE_IDNA_MAPPED, 1, 831}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3471}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1162}, + {LXB_UNICODE_IDNA_MAPPED, 2, 548}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4654}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4529}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3099}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1670}, + {LXB_UNICODE_IDNA_MAPPED, 1, 641}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5048}, + {LXB_UNICODE_IDNA_MAPPED, 1, 223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3446}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4845}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3313}, {LXB_UNICODE_IDNA_MAPPED, 1, 451}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1548}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3449}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5127}, - {LXB_UNICODE_IDNA_MAPPED, 1, 700}, - {LXB_UNICODE_IDNA_MAPPED, 1, 724}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3109}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3912}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1375}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5071}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4971}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5085}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3512}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3087}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4747}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4577}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5322}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 258}, - {LXB_UNICODE_IDNA_MAPPED, 1, 155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3329}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4728}, - {LXB_UNICODE_IDNA_MAPPED, 1, 447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3041}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4449}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5367}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3368}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5332}, - {LXB_UNICODE_IDNA_MAPPED, 1, 714}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3298}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4445}, - {LXB_UNICODE_IDNA_MAPPED, 1, 797}, - {LXB_UNICODE_IDNA_MAPPED, 1, 215}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1217}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 907}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1833}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1812}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1429}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5147}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2194}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2782}, + {LXB_UNICODE_IDNA_MAPPED, 1, 388}, + {LXB_UNICODE_IDNA_MAPPED, 2, 524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 869}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3156}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3642}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5121}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4761}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5073}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1549}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1550}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2575}, + {LXB_UNICODE_IDNA_MAPPED, 1, 832}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3104}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2968}, + {LXB_UNICODE_IDNA_MAPPED, 1, 390}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2806}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 449}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1265}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3350}, {LXB_UNICODE_IDNA_MAPPED, 2, 1200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4941}, - {LXB_UNICODE_IDNA_MAPPED, 1, 459}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4425}, - {LXB_UNICODE_IDNA_MAPPED, 1, 206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2930}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3121}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4719}, - {LXB_UNICODE_IDNA_MAPPED, 1, 103}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3569}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2859}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2715}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5126}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2698}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3271}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4448}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5164}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3126}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1782}, - {LXB_UNICODE_IDNA_MAPPED, 1, 809}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4433}, - {LXB_UNICODE_IDNA_MAPPED, 1, 644}, - {LXB_UNICODE_IDNA_MAPPED, 1, 494}, - {LXB_UNICODE_IDNA_MAPPED, 2, 282}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1101}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5379}, - {LXB_UNICODE_IDNA_MAPPED, 1, 63}, - {LXB_UNICODE_IDNA_MAPPED, 2, 581}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2656}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1081}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1399}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4723}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3250}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1018}, - {LXB_UNICODE_IDNA_MAPPED, 2, 207}, - {LXB_UNICODE_IDNA_MAPPED, 1, 651}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3057}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4559}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1651}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3333}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1580}, - {LXB_UNICODE_IDNA_MAPPED, 1, 73}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 836}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4030}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1674}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2088}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3147}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1686}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1922}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3502}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1336}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3595}, - {LXB_UNICODE_IDNA_MAPPED, 2, 983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3516}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4515}, - {LXB_UNICODE_IDNA_MAPPED, 1, 98}, - {LXB_UNICODE_IDNA_MAPPED, 1, 777}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5269}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3351}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4820}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2615}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5124}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2991}, - {LXB_UNICODE_IDNA_MAPPED, 1, 238}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4111}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2518}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3830}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5342}, - {LXB_UNICODE_IDNA_MAPPED, 2, 587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4462}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1076}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1750}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4507}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4854}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4045}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1640}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1569}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5229}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 55}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 139}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4747}, + {LXB_UNICODE_IDNA_MAPPED, 1, 673}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3795}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1004}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3465}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3286}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5187}, + {LXB_UNICODE_IDNA_MAPPED, 1, 486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 412}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3073}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3023}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5372}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1388}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 478}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3901}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2967}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1600}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1469}, + {LXB_UNICODE_IDNA_MAPPED, 1, 828}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3567}, + {LXB_UNICODE_IDNA_MAPPED, 1, 914}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3899}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2213}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1391}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2089}, + {LXB_UNICODE_IDNA_MAPPED, 2, 615}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 353}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5236}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4835}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3033}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1008}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1689}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 236}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5210}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 176}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4150}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2910}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1769}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3763}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 448}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1934}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3531}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1772}, + {LXB_UNICODE_IDNA_MAPPED, 2, 566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4917}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3142}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2672}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1925}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4713}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5028}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2928}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3084}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4772}, + {LXB_UNICODE_IDNA_MAPPED, 1, 772}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2996}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2409}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4497}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4836}, + {LXB_UNICODE_IDNA_MAPPED, 1, 345}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2398}, + {LXB_UNICODE_IDNA_MAPPED, 1, 173}, + {LXB_UNICODE_IDNA_MAPPED, 1, 419}, {LXB_UNICODE_IDNA_MAPPED, 1, 5018}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5315}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4795}, - {LXB_UNICODE_IDNA_MAPPED, 1, 983}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5141}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4621}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2353}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3278}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 832}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3574}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1504}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4598}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3012}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4636}, + {LXB_UNICODE_IDNA_MAPPED, 1, 868}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2607}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5327}, + {LXB_UNICODE_IDNA_MAPPED, 2, 593}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4595}, + {LXB_UNICODE_IDNA_MAPPED, 1, 219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1809}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4954}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3709}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3262}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2511}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2615}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5299}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1579}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3295}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4707}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3990}, + {LXB_UNICODE_IDNA_MAPPED, 1, 434}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4550}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 235}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3161}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2000}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3580}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1848}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1517}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1155}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3653}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5053}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1432}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2950}, + {LXB_UNICODE_IDNA_MAPPED, 1, 853}, + {LXB_UNICODE_IDNA_MAPPED, 1, 94}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 458}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4882}, + {LXB_UNICODE_IDNA_MAPPED, 1, 888}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2987}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1943}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4120}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4962}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4667}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3339}, + {LXB_UNICODE_IDNA_MAPPED, 1, 166}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3749}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3163}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3062}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1774}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2682}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1096}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5398}, + {LXB_UNICODE_IDNA_MAPPED, 2, 583}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4831}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4910}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3369}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4479}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3003}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1513}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4627}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3423}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2030}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3276}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3338}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2830}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4546}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5131}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3478}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3911}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1522}, + {LXB_UNICODE_IDNA_MAPPED, 1, 496}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5184}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 721}, + {LXB_UNICODE_IDNA_MAPPED, 1, 757}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4640}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3610}, + {LXB_UNICODE_IDNA_MAPPED, 1, 732}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4692}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2149}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3857}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4261}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3118}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4942}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5049}, {LXB_UNICODE_IDNA_MAPPED, 1, 5199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4538}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1618}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3122}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5281}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5048}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5254}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2995}, - {LXB_UNICODE_IDNA_MAPPED, 2, 188}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3445}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3419}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4570}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1592}, - {LXB_UNICODE_IDNA_MAPPED, 1, 679}, - {LXB_UNICODE_IDNA_MAPPED, 1, 97}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4667}, - {LXB_UNICODE_IDNA_MAPPED, 1, 345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2099}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4808}, - {LXB_UNICODE_IDNA_MAPPED, 1, 434}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4174}, - {LXB_UNICODE_IDNA_MAPPED, 1, 503}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1606}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3065}, - {LXB_UNICODE_IDNA_MAPPED, 2, 613}, + {LXB_UNICODE_IDNA_MAPPED, 1, 53}, + {LXB_UNICODE_IDNA_MAPPED, 2, 578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 863}, + {LXB_UNICODE_IDNA_MAPPED, 1, 707}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5335}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2066}, + {LXB_UNICODE_IDNA_MAPPED, 2, 275}, + {LXB_UNICODE_IDNA_MAPPED, 1, 662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4751}, + {LXB_UNICODE_IDNA_MAPPED, 1, 488}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5068}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1621}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2175}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2532}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3984}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1480}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5078}, + {LXB_UNICODE_IDNA_MAPPED, 1, 838}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2898}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5032}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2298}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3859}, + {LXB_UNICODE_IDNA_MAPPED, 1, 133}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3032}, + {LXB_UNICODE_IDNA_MAPPED, 1, 712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2943}, + {LXB_UNICODE_IDNA_MAPPED, 2, 552}, + {LXB_UNICODE_IDNA_MAPPED, 1, 500}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3602}, + {LXB_UNICODE_IDNA_MAPPED, 1, 335}, {LXB_UNICODE_IDNA_MAPPED, 1, 4972}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3227}, - {LXB_UNICODE_IDNA_MAPPED, 1, 813}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 90}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5208}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3300}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4998}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1605}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3448}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1460}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1618}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1023}, + {LXB_UNICODE_IDNA_MAPPED, 1, 430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4588}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 322}, + {LXB_UNICODE_IDNA_MAPPED, 1, 767}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3326}, + {LXB_UNICODE_IDNA_MAPPED, 1, 73}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3333}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4201}, + {LXB_UNICODE_IDNA_MAPPED, 3, 992}, + {LXB_UNICODE_IDNA_MAPPED, 1, 730}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1531}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 621}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5366}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5231}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1427}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4465}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1816}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4604}, + {LXB_UNICODE_IDNA_MAPPED, 1, 856}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2368}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3847}, + {LXB_UNICODE_IDNA_MAPPED, 2, 29}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3095}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4687}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4970}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1447}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3174}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4730}, + {LXB_UNICODE_IDNA_MAPPED, 1, 461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 522}, + {LXB_UNICODE_IDNA_MAPPED, 1, 655}, {LXB_UNICODE_IDNA_MAPPED, 1, 4460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3266}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3064}, - {LXB_UNICODE_IDNA_MAPPED, 1, 388}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2309}, {LXB_UNICODE_IDNA_MAPPED, 2, 2052}, - {LXB_UNICODE_IDNA_MAPPED, 1, 403}, - {LXB_UNICODE_IDNA_MAPPED, 1, 916}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1003}, - {LXB_UNICODE_IDNA_MAPPED, 1, 677}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3418}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4980}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3527}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4774}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5272}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4009}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5225}, - {LXB_UNICODE_IDNA_MAPPED, 1, 456}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1777}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5115}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1542}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4653}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4388}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3089}, - {LXB_UNICODE_IDNA_MAPPED, 1, 702}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3052}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3581}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4624}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3900}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2193}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4607}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4528}, - {LXB_UNICODE_IDNA_MAPPED, 1, 142}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3142}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3658}, - {LXB_UNICODE_IDNA_MAPPED, 1, 427}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3011}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5307}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2528}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4769}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1476}, - {LXB_UNICODE_IDNA_MAPPED, 1, 152}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5008}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4887}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1685}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5388}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3292}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1769}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2073}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1671}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5279}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3350}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1781}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5079}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1398}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1613}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2933}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3270}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4456}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3249}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3920}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2835}, - {LXB_UNICODE_IDNA_MAPPED, 1, 792}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1426}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3531}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3375}, - {LXB_UNICODE_IDNA_MAPPED, 1, 141}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2417}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2612}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2087}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5318}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4434}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3517}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3081}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3724}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1223}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3146}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1519}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4516}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4951}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1312}, - {LXB_UNICODE_IDNA_MAPPED, 1, 326}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2654}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1381}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4587}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4657}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2942}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4911}, - {LXB_UNICODE_IDNA_MAPPED, 1, 795}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3334}, - {LXB_UNICODE_IDNA_MAPPED, 1, 452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5045}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3056}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4558}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1884}, + {LXB_UNICODE_IDNA_MAPPED, 1, 334}, + {LXB_UNICODE_IDNA_MAPPED, 2, 560}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4684}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4484}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4848}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 626}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1696}, {LXB_UNICODE_IDNA_MAPPED, 3, 2701}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2723}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3165}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 732}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4729}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3018}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1663}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4652}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4529}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3770}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1736}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1462}, - {LXB_UNICODE_IDNA_MAPPED, 1, 173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3086}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5357}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2600}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3365}, - {LXB_UNICODE_IDNA_MAPPED, 1, 831}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4045}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3141}, - {LXB_UNICODE_IDNA_MAPPED, 2, 958}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3605}, - {LXB_UNICODE_IDNA_MAPPED, 1, 775}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3265}, - {LXB_UNICODE_IDNA_MAPPED, 1, 974}, - {LXB_UNICODE_IDNA_MAPPED, 1, 252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1734}, - {LXB_UNICODE_IDNA_MAPPED, 2, 552}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3462}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3526}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1982}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2054}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1429}, - {LXB_UNICODE_IDNA_MAPPED, 1, 64}, - {LXB_UNICODE_IDNA_MAPPED, 1, 469}, - {LXB_UNICODE_IDNA_MAPPED, 1, 148}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3297}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1620}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5061}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4997}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4540}, - {LXB_UNICODE_IDNA_MAPPED, 1, 647}, - {LXB_UNICODE_IDNA_MAPPED, 1, 231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1543}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4746}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1042}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1241}, - {LXB_UNICODE_IDNA_MAPPED, 1, 328}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1277}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3082}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1598}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3518}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1445}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2245}, - {LXB_UNICODE_IDNA_MAPPED, 2, 978}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1667}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 667}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1419}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1051}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3132}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5088}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4533}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2977}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4681}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3410}, + {LXB_UNICODE_IDNA_MAPPED, 1, 854}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5258}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4780}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3126}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1857}, + {LXB_UNICODE_IDNA_MAPPED, 1, 91}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5364}, + {LXB_UNICODE_IDNA_MAPPED, 2, 282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5077}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5218}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1562}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3021}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1223}, + {LXB_UNICODE_IDNA_MAPPED, 1, 759}, + {LXB_UNICODE_IDNA_MAPPED, 1, 905}, + {LXB_UNICODE_IDNA_MAPPED, 1, 395}, {LXB_UNICODE_IDNA_MAPPED, 1, 839}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3208}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3293}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5220}, - {LXB_UNICODE_IDNA_MAPPED, 1, 230}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4894}, - {LXB_UNICODE_IDNA_MAPPED, 2, 932}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3397}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2127}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5176}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1569}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1547}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2988}, - {LXB_UNICODE_IDNA_MAPPED, 1, 435}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2072}, - {LXB_UNICODE_IDNA_MAPPED, 1, 335}, - {LXB_UNICODE_IDNA_MAPPED, 1, 499}, - {LXB_UNICODE_IDNA_MAPPED, 1, 870}, - {LXB_UNICODE_IDNA_MAPPED, 1, 688}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2985}, - {LXB_UNICODE_IDNA_MAPPED, 1, 827}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4455}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1612}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1526}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3374}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2957}, - {LXB_UNICODE_IDNA_MAPPED, 1, 59}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2089}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1784}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1427}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3237}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4718}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4737}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1501}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4810}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5174}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3466}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5157}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5246}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4940}, - {LXB_UNICODE_IDNA_MAPPED, 1, 149}, - {LXB_UNICODE_IDNA_MAPPED, 1, 69}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2009}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1581}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4597}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4560}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5333}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4867}, - {LXB_UNICODE_IDNA_MAPPED, 1, 84}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5256}, - {LXB_UNICODE_IDNA_MAPPED, 1, 321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 127}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2234}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3706}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4255}, - {LXB_UNICODE_IDNA_MAPPED, 1, 512}, - {LXB_UNICODE_IDNA_MAPPED, 1, 222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1575}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4270}, + {LXB_UNICODE_IDNA_MAPPED, 1, 866}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5314}, {LXB_UNICODE_IDNA_MAPPED, 1, 5353}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 634}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3214}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4000}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1742}, {LXB_UNICODE_IDNA_MAPPED, 3, 2467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 889}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1839}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2974}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1018}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4841}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5358}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5325}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3231}, + {LXB_UNICODE_IDNA_MAPPED, 1, 664}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3539}, + {LXB_UNICODE_IDNA_MAPPED, 1, 393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 841}, + {LXB_UNICODE_IDNA_MAPPED, 1, 864}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1661}, + {LXB_UNICODE_IDNA_MAPPED, 1, 752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4567}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3669}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4414}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5289}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3494}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1380}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2736}, + {LXB_UNICODE_IDNA_MAPPED, 1, 131}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1533}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5349}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1793}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4583}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2794}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4678}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3112}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4966}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4997}, + {LXB_UNICODE_IDNA_MAPPED, 2, 558}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4024}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2772}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1483}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2514}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3093}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2058}, {LXB_UNICODE_IDNA_MAPPED, 1, 1023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1444}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3860}, - {LXB_UNICODE_IDNA_MAPPED, 1, 802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2935}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3205}, - {LXB_UNICODE_IDNA_MAPPED, 2, 536}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2862}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2712}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3171}, - {LXB_UNICODE_IDNA_MAPPED, 1, 147}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3226}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4944}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3631}, - {LXB_UNICODE_IDNA_MAPPED, 1, 844}, - {LXB_UNICODE_IDNA_MAPPED, 1, 126}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4054}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2796}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3908}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2040}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3422}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1701}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5091}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3463}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4689}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4440}, + {LXB_UNICODE_IDNA_MAPPED, 1, 320}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3731}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2060}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3931}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3179}, + {LXB_UNICODE_IDNA_MAPPED, 1, 93}, + {LXB_UNICODE_IDNA_MAPPED, 1, 437}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3935}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3304}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3886}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5285}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1890}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5160}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4186}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1794}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4512}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1463}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2619}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2662}, + {LXB_UNICODE_IDNA_MAPPED, 1, 363}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4767}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5278}, + {LXB_UNICODE_IDNA_MAPPED, 2, 263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4738}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5348}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2990}, + {LXB_UNICODE_IDNA_MAPPED, 1, 433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3497}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3713}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2074}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2953}, + {LXB_UNICODE_IDNA_MAPPED, 2, 966}, + {LXB_UNICODE_IDNA_MAPPED, 2, 528}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 132}, + {LXB_UNICODE_IDNA_MAPPED, 2, 554}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3236}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5343}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5269}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3523}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1599}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3068}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1780}, + {LXB_UNICODE_IDNA_MAPPED, 1, 144}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5370}, + {LXB_UNICODE_IDNA_MAPPED, 1, 777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2087}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5384}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3345}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1635}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 254}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4616}, + {LXB_UNICODE_IDNA_MAPPED, 1, 347}, + {LXB_UNICODE_IDNA_MAPPED, 1, 887}, {LXB_UNICODE_IDNA_MAPPED, 1, 5283}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1484}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5063}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2021}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2916}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4574}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2776}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3571}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 729}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5069}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3093}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4620}, - {LXB_UNICODE_IDNA_MAPPED, 1, 900}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4799}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3834}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5324}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4463}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5214}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1538}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2514}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2750}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5125}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4682}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2069}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4963}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 876}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1185}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3281}, + {LXB_UNICODE_IDNA_MAPPED, 1, 179}, + {LXB_UNICODE_IDNA_MAPPED, 1, 255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 92}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1568}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3006}, + {LXB_UNICODE_IDNA_MAPPED, 1, 810}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4243}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3845}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2137}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2135}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2331}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1866}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1663}, + {LXB_UNICODE_IDNA_MAPPED, 2, 267}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3618}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4698}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3239}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1412}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3472}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1875}, + {LXB_UNICODE_IDNA_MAPPED, 1, 509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5165}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5332}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1415}, {LXB_UNICODE_IDNA_MAPPED, 1, 1453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3184}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4413}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4705}, - {LXB_UNICODE_IDNA_MAPPED, 1, 110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5112}, - {LXB_UNICODE_IDNA_MAPPED, 1, 824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 773}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5047}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3172}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5268}, - {LXB_UNICODE_IDNA_MAPPED, 2, 942}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1905}, - {LXB_UNICODE_IDNA_MAPPED, 1, 628}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3319}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 331}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3889}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3238}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5257}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1253}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 674}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2006}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5386}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5140}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5236}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4796}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3469}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4811}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4481}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5013}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3037}, - {LXB_UNICODE_IDNA_MAPPED, 1, 487}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2511}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5343}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4697}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1788}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2955}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4720}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5076}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3154}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5213}, - {LXB_UNICODE_IDNA_MAPPED, 1, 86}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3496}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3175}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 211}, - {LXB_UNICODE_IDNA_MAPPED, 1, 242}, - {LXB_UNICODE_IDNA_MAPPED, 1, 224}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2581}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3362}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3289}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2928}, - {LXB_UNICODE_IDNA_MAPPED, 1, 709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5306}, - {LXB_UNICODE_IDNA_MAPPED, 1, 495}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4234}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4438}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4645}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2752}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3391}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2948}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3259}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5380}, - {LXB_UNICODE_IDNA_MAPPED, 1, 691}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2081}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1389}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5313}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1970}, - {LXB_UNICODE_IDNA_MAPPED, 1, 790}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1624}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2637}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3078}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2973}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3342}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4159}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4878}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3242}, - {LXB_UNICODE_IDNA_MAPPED, 1, 338}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4544}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4965}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4945}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1436}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3509}, - {LXB_UNICODE_IDNA_MAPPED, 1, 769}, - {LXB_UNICODE_IDNA_MAPPED, 1, 118}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3910}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5201}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4926}, - {LXB_UNICODE_IDNA_MAPPED, 1, 510}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5168}, - {LXB_UNICODE_IDNA_MAPPED, 1, 201}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3341}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4398}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3688}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4231}, - {LXB_UNICODE_IDNA_MAPPED, 1, 742}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1487}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4541}, - {LXB_UNICODE_IDNA_MAPPED, 1, 654}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4899}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3388}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4575}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3361}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1621}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4933}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1410}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1890}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1357}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1525}, + {LXB_UNICODE_IDNA_MAPPED, 2, 960}, + {LXB_UNICODE_IDNA_MAPPED, 1, 693}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3873}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5237}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1949}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1528}, + {LXB_UNICODE_IDNA_MAPPED, 2, 261}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3426}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4719}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3165}, + {LXB_UNICODE_IDNA_MAPPED, 2, 536}, {LXB_UNICODE_IDNA_MAPPED, 3, 2856}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2393}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3495}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4688}, - {LXB_UNICODE_IDNA_MAPPED, 1, 431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2938}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3199}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5010}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1388}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3571}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4873}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2798}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5340}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3243}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3956}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2859}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4171}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3428}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1647}, + {LXB_UNICODE_IDNA_MAPPED, 1, 845}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5116}, + {LXB_UNICODE_IDNA_MAPPED, 1, 975}, + {LXB_UNICODE_IDNA_MAPPED, 1, 429}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1511}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2034}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4580}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5303}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1788}, {LXB_UNICODE_IDNA_MAPPED, 1, 3364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 800}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4953}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4439}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4646}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2635}, - {LXB_UNICODE_IDNA_MAPPED, 2, 540}, - {LXB_UNICODE_IDNA_MAPPED, 3, 3874}, - {LXB_UNICODE_IDNA_MAPPED, 1, 522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2221}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3155}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1032}, - {LXB_UNICODE_IDNA_MAPPED, 1, 641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4692}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1342}, - {LXB_UNICODE_IDNA_MAPPED, 1, 444}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1967}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5389}, - {LXB_UNICODE_IDNA_MAPPED, 2, 119}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4793}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2584}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3022}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4596}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1785}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1406}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5022}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1902}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3036}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5308}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3372}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4022}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4544}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2448}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5135}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4562}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2780}, + {LXB_UNICODE_IDNA_MAPPED, 1, 659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 517}, + {LXB_UNICODE_IDNA_MAPPED, 1, 511}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4471}, + {LXB_UNICODE_IDNA_MAPPED, 1, 789}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1820}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3290}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5330}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5163}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 811}, + {LXB_UNICODE_IDNA_MAPPED, 3, 980}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1348}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3250}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4724}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3555}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3029}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2940}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 870}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3549}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5310}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2125}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1623}, {LXB_UNICODE_IDNA_MAPPED, 4, 2349}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5120}, - {LXB_UNICODE_IDNA_MAPPED, 1, 506}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1532}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1765}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2762}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2141}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4917}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4114}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4219}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4845}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1173}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5228}, - {LXB_UNICODE_IDNA_MAPPED, 2, 593}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3357}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1751}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3207}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2784}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4704}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3716}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2969}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4696}, - {LXB_UNICODE_IDNA_MAPPED, 1, 894}, - {LXB_UNICODE_IDNA_MAPPED, 1, 134}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5277}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4492}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4663}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4772}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1481}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2241}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2945}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5377}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3962}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3183}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2686}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3113}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2625}, - {LXB_UNICODE_IDNA_MAPPED, 1, 209}, - {LXB_UNICODE_IDNA_MAPPED, 2, 976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1803}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2024}, - {LXB_UNICODE_IDNA_MAPPED, 1, 244}, - {LXB_UNICODE_IDNA_MAPPED, 1, 861}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5292}, - {LXB_UNICODE_IDNA_MAPPED, 1, 768}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3880}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5350}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4466}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4691}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3225}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2364}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 476}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4401}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2794}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2353}, {LXB_UNICODE_IDNA_MAPPED, 1, 5177}, - {LXB_UNICODE_IDNA_MAPPED, 1, 92}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4383}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1473}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3090}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4952}, - {LXB_UNICODE_IDNA_MAPPED, 1, 905}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3832}, - {LXB_UNICODE_IDNA_MAPPED, 1, 878}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5159}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5218}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1537}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5087}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2151}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2109}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3026}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1555}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 482}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3029}, - {LXB_UNICODE_IDNA_MAPPED, 1, 754}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3532}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2388}, - {LXB_UNICODE_IDNA_MAPPED, 2, 526}, - {LXB_UNICODE_IDNA_MAPPED, 1, 670}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1887}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3200}, - {LXB_UNICODE_IDNA_MAPPED, 1, 630}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3301}, - {LXB_UNICODE_IDNA_MAPPED, 1, 279}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4573}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2038}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 343}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4282}, - {LXB_UNICODE_IDNA_MAPPED, 4, 2230}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2871}, - {LXB_UNICODE_IDNA_MAPPED, 1, 93}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4662}, - {LXB_UNICODE_IDNA_MAPPED, 1, 191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1639}, - {LXB_UNICODE_IDNA_MAPPED, 1, 203}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3649}, + {LXB_UNICODE_IDNA_MAPPED, 1, 195}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2892}, + {LXB_UNICODE_IDNA_MAPPED, 1, 813}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3723}, + {LXB_UNICODE_IDNA_MAPPED, 1, 515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3525}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1285}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2094}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4743}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2214}, + {LXB_UNICODE_IDNA_MAPPED, 1, 192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 465}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5027}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1229}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4918}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1719}, + {LXB_UNICODE_IDNA_MAPPED, 1, 228}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1690}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3079}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1728}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2980}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1594}, + {LXB_UNICODE_IDNA_MAPPED, 3, 44}, + {LXB_UNICODE_IDNA_MAPPED, 1, 874}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3140}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4568}, + {LXB_UNICODE_IDNA_MAPPED, 1, 708}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3111}, {LXB_UNICODE_IDNA_MAPPED, 1, 1439}, - {LXB_UNICODE_IDNA_MAPPED, 1, 210}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4517}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1836}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5354}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2623}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2976}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 758}, - {LXB_UNICODE_IDNA_MAPPED, 1, 109}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5327}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2422}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3405}, - {LXB_UNICODE_IDNA_MAPPED, 1, 764}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1405}, - {LXB_UNICODE_IDNA_MAPPED, 3, 995}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1182}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3918}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3204}, - {LXB_UNICODE_IDNA_MAPPED, 1, 348}, - {LXB_UNICODE_IDNA_MAPPED, 1, 464}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5227}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4258}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1584}, - {LXB_UNICODE_IDNA_MAPPED, 1, 278}, - {LXB_UNICODE_IDNA_MAPPED, 1, 657}, - {LXB_UNICODE_IDNA_MAPPED, 1, 857}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4858}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3491}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4736}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4216}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1912}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1533}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4829}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2092}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1670}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2143}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3356}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5148}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1504}, - {LXB_UNICODE_IDNA_MAPPED, 1, 472}, - {LXB_UNICODE_IDNA_MAPPED, 1, 229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1625}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 389}, - {LXB_UNICODE_IDNA_MAPPED, 1, 392}, - {LXB_UNICODE_IDNA_MAPPED, 1, 848}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4545}, - {LXB_UNICODE_IDNA_MAPPED, 1, 887}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5160}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3006}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4929}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5075}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4741}, - {LXB_UNICODE_IDNA_MAPPED, 1, 914}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3337}, + {LXB_UNICODE_IDNA_MAPPED, 1, 435}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5012}, {LXB_UNICODE_IDNA_MAPPED, 1, 1497}, - {LXB_UNICODE_IDNA_MAPPED, 1, 407}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1693}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4975}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1860}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1384}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3562}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4684}, - {LXB_UNICODE_IDNA_MAPPED, 1, 441}, - {LXB_UNICODE_IDNA_MAPPED, 1, 717}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3255}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3189}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5068}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1138}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3668}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4048}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2919}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3506}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1363}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4508}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4437}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4644}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3870}, - {LXB_UNICODE_IDNA_MAPPED, 2, 989}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4502}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3153}, - {LXB_UNICODE_IDNA_MAPPED, 1, 218}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1764}, - {LXB_UNICODE_IDNA_MAPPED, 2, 259}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4321}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3046}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4893}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2578}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1648}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4730}, - {LXB_UNICODE_IDNA_MAPPED, 1, 622}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1493}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1708}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4383}, + {LXB_UNICODE_IDNA_MAPPED, 1, 758}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1379}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3137}, + {LXB_UNICODE_IDNA_MAPPED, 1, 116}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4929}, + {LXB_UNICODE_IDNA_MAPPED, 1, 199}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1542}, + {LXB_UNICODE_IDNA_MAPPED, 1, 487}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3358}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3357}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4774}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3086}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3195}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2470}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2563}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2003}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2997}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 341}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4556}, + {LXB_UNICODE_IDNA_MAPPED, 1, 756}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2986}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3440}, + {LXB_UNICODE_IDNA_MAPPED, 2, 585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 209}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1502}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3143}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4300}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3297}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2959}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4712}, + {LXB_UNICODE_IDNA_MAPPED, 1, 734}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5305}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4647}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1994}, + {LXB_UNICODE_IDNA_MAPPED, 1, 494}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5371}, + {LXB_UNICODE_IDNA_MAPPED, 1, 123}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5226}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3381}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3320}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2110}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2961}, {LXB_UNICODE_IDNA_MAPPED, 1, 1697}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5004}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1872}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5014}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3437}, - {LXB_UNICODE_IDNA_MAPPED, 4, 1113}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1789}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2704}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 768}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3057}, + {LXB_UNICODE_IDNA_MAPPED, 1, 200}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4397}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2584}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1601}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3377}, + {LXB_UNICODE_IDNA_MAPPED, 1, 112}, + {LXB_UNICODE_IDNA_MAPPED, 1, 857}, + {LXB_UNICODE_IDNA_MAPPED, 1, 65}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3060}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3203}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5159}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 253}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1754}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2088}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4449}, {LXB_UNICODE_IDNA_MAPPED, 1, 3034}, - {LXB_UNICODE_IDNA_MAPPED, 1, 696}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2117}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1568}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5196}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5267}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5111}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3323}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4882}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2970}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3802}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 721}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2103}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4484}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4337}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3134}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5258}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4700}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3129}, - {LXB_UNICODE_IDNA_MAPPED, 1, 458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4987}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3179}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4409}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3316}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1485}, - {LXB_UNICODE_IDNA_MAPPED, 1, 734}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1599}, - {LXB_UNICODE_IDNA_MAPPED, 1, 411}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4812}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3115}, - {LXB_UNICODE_IDNA_MAPPED, 1, 235}, - {LXB_UNICODE_IDNA_MAPPED, 2, 556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5298}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5029}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5370}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4966}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4468}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4509}, - {LXB_UNICODE_IDNA_MAPPED, 2, 583}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2368}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1206}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3273}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5312}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3898}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1472}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3094}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4897}, - {LXB_UNICODE_IDNA_MAPPED, 4, 4317}, - {LXB_UNICODE_IDNA_MAPPED, 1, 804}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4489}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5151}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2105}, - {LXB_UNICODE_IDNA_MAPPED, 1, 818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5081}, + {LXB_UNICODE_IDNA_MAPPED, 1, 822}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4324}, + {LXB_UNICODE_IDNA_MAPPED, 2, 609}, + {LXB_UNICODE_IDNA_MAPPED, 1, 101}, + {LXB_UNICODE_IDNA_MAPPED, 1, 660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 750}, + {LXB_UNICODE_IDNA_MAPPED, 1, 889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1459}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5239}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5246}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1641}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 78}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5356}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2370}, + {LXB_UNICODE_IDNA_MAPPED, 1, 671}, + {LXB_UNICODE_IDNA_MAPPED, 1, 766}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4731}, + {LXB_UNICODE_IDNA_MAPPED, 1, 714}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2933}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3565}, + {LXB_UNICODE_IDNA_MAPPED, 1, 329}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4996}, + {LXB_UNICODE_IDNA_MAPPED, 1, 210}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1702}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4978}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3274}, + {LXB_UNICODE_IDNA_MAPPED, 1, 222}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4204}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4288}, + {LXB_UNICODE_IDNA_MAPPED, 1, 164}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3271}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5025}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3043}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3285}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2635}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4964}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1572}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2488}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3302}, {LXB_UNICODE_IDNA_MAPPED, 1, 1551}, - {LXB_UNICODE_IDNA_MAPPED, 1, 100}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3025}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2992}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2030}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4162}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3563}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3059}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1692}, - {LXB_UNICODE_IDNA_MAPPED, 1, 470}, - {LXB_UNICODE_IDNA_MAPPED, 1, 514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 57}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1857}, - {LXB_UNICODE_IDNA_MAPPED, 6, 2303}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1600}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3629}, - {LXB_UNICODE_IDNA_MAPPED, 1, 61}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3190}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5074}, - {LXB_UNICODE_IDNA_MAPPED, 1, 87}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3423}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5215}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4557}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2877}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5035}, - {LXB_UNICODE_IDNA_MAPPED, 1, 814}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4527}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4386}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1196}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1801}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2949}, + {LXB_UNICODE_IDNA_MAPPED, 1, 794}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2296}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1827}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3315}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3594}, + {LXB_UNICODE_IDNA_MAPPED, 1, 245}, + {LXB_UNICODE_IDNA_MAPPED, 1, 755}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3154}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4652}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4750}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1671}, + {LXB_UNICODE_IDNA_MAPPED, 6, 2744}, + {LXB_UNICODE_IDNA_MAPPED, 1, 460}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4989}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4653}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2067}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3634}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3106}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2173}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2534}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4376}, + {LXB_UNICODE_IDNA_MAPPED, 1, 855}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4877}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4817}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4561}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4504}, {LXB_UNICODE_IDNA_MAPPED, 1, 4485}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3335}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4586}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5363}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2964}, - {LXB_UNICODE_IDNA_MAPPED, 1, 236}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5130}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 227}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2433}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4782}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4760}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4994}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4958}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1518}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4521}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5319}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2981}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2086}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3119}, + {LXB_UNICODE_IDNA_MAPPED, 1, 623}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5057}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2969}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2548}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4060}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1177}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3091}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5043}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5089}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3352}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4779}, + {LXB_UNICODE_IDNA_MAPPED, 1, 130}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1150}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1400}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3510}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2206}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3259}, + {LXB_UNICODE_IDNA_MAPPED, 1, 76}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1442}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2151}, + {LXB_UNICODE_IDNA_MAPPED, 1, 753}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1176}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4264}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5197}, {LXB_UNICODE_IDNA_MAPPED, 1, 840}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1393}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1045}, - {LXB_UNICODE_IDNA_MAPPED, 3, 992}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4824}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5266}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2832}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4446}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3194}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5110}, - {LXB_UNICODE_IDNA_MAPPED, 1, 88}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3245}, - {LXB_UNICODE_IDNA_MAPPED, 1, 872}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1574}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1682}, + {LXB_UNICODE_IDNA_MAPPED, 1, 765}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5386}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5070}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2828}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1761}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5140}, + {LXB_UNICODE_IDNA_MAPPED, 1, 632}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5413}, + {LXB_UNICODE_IDNA_MAPPED, 1, 625}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 751}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5124}, + {LXB_UNICODE_IDNA_MAPPED, 1, 865}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4219}, + {LXB_UNICODE_IDNA_MAPPED, 1, 394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4987}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1001}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3222}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5406}, + {LXB_UNICODE_IDNA_MAPPED, 2, 976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 743}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5045}, {LXB_UNICODE_IDNA_MAPPED, 1, 656}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1586}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3546}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4564}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1008}, - {LXB_UNICODE_IDNA_MAPPED, 2, 617}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4096}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1680}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5183}, - {LXB_UNICODE_IDNA_MAPPED, 1, 808}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1477}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4820}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4437}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3959}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4452}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1014}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2414}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2566}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3395}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1553}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3026}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4066}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3078}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1031}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4927}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1937}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4873}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 420}, + {LXB_UNICODE_IDNA_MAPPED, 1, 492}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1773}, + {LXB_UNICODE_IDNA_MAPPED, 1, 122}, + {LXB_UNICODE_IDNA_MAPPED, 1, 146}, + {LXB_UNICODE_IDNA_MAPPED, 1, 220}, {LXB_UNICODE_IDNA_MAPPED, 1, 2093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5396}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1506}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4732}, - {LXB_UNICODE_IDNA_MAPPED, 1, 198}, - {LXB_UNICODE_IDNA_MAPPED, 1, 170}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3345}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4735}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2085}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4532}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1836}, + {LXB_UNICODE_IDNA_MAPPED, 1, 689}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1673}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2752}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3160}, + {LXB_UNICODE_IDNA_MAPPED, 1, 436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3157}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1845}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3432}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5301}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4030}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1473}, + {LXB_UNICODE_IDNA_MAPPED, 1, 71}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1575}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2499}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5169}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5336}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3289}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4711}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2197}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 843}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4599}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4521}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4472}, {LXB_UNICODE_IDNA_MAPPED, 2, 2617}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4514}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3498}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3458}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5191}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4895}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4935}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5252}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1517}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3148}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1505}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5222}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1431}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1571}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1578}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4850}, + {LXB_UNICODE_IDNA_MAPPED, 1, 804}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5105}, + {LXB_UNICODE_IDNA_MAPPED, 1, 339}, + {LXB_UNICODE_IDNA_MAPPED, 1, 401}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5391}, {LXB_UNICODE_IDNA_MAPPED, 1, 404}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4659}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3058}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5027}, - {LXB_UNICODE_IDNA_MAPPED, 1, 632}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4243}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1642}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5275}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4556}, - {LXB_UNICODE_IDNA_MAPPED, 1, 850}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3894}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4600}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1585}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3548}, - {LXB_UNICODE_IDNA_MAPPED, 1, 394}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5373}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2436}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2461}, - {LXB_UNICODE_IDNA_MAPPED, 1, 144}, - {LXB_UNICODE_IDNA_MAPPED, 1, 890}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1833}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5344}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4522}, - {LXB_UNICODE_IDNA_MAPPED, 1, 636}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1783}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2939}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3195}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5118}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2874}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4447}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3272}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3159}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2688}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2830}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2285}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3567}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4831}, + {LXB_UNICODE_IDNA_MAPPED, 1, 174}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3258}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 212}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4861}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1076}, + {LXB_UNICODE_IDNA_MAPPED, 1, 776}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5143}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2256}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4228}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5312}, + {LXB_UNICODE_IDNA_MAPPED, 1, 221}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3486}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5099}, + {LXB_UNICODE_IDNA_MAPPED, 1, 59}, + {LXB_UNICODE_IDNA_MAPPED, 1, 463}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4237}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3363}, + {LXB_UNICODE_IDNA_MAPPED, 2, 970}, + {LXB_UNICODE_IDNA_MAPPED, 2, 532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1655}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3380}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4718}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4785}, + {LXB_UNICODE_IDNA_MAPPED, 1, 201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 885}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5243}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4825}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5109}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1685}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4891}, + {LXB_UNICODE_IDNA_MAPPED, 1, 778}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4291}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1688}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2104}, {LXB_UNICODE_IDNA_MAPPED, 3, 1107}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4490}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4063}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3903}, + {LXB_UNICODE_IDNA_MAPPED, 1, 814}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1583}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4430}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3512}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3049}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1392}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3445}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4633}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5155}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3620}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4699}, + {LXB_UNICODE_IDNA_MAPPED, 1, 844}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4081}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1505}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3282}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2956}, + {LXB_UNICODE_IDNA_MAPPED, 1, 137}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2605}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2816}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4594}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1212}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1808}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4759}, + {LXB_UNICODE_IDNA_MAPPED, 1, 691}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2983}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4706}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5290}, + {LXB_UNICODE_IDNA_MAPPED, 1, 846}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 238}, + {LXB_UNICODE_IDNA_MAPPED, 1, 198}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5129}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1051}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3145}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4508}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2813}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4576}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1781}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3069}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2664}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1100}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2396}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1249}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2994}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3761}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2922}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2226}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4897}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1548}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4390}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3532}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 695}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5309}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5354}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1436}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1545}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5037}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1922}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4960}, + {LXB_UNICODE_IDNA_MAPPED, 1, 872}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2080}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1603}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4984}, + {LXB_UNICODE_IDNA_MAPPED, 1, 466}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3268}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4766}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1327}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3201}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1467}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2930}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3035}, + {LXB_UNICODE_IDNA_MAPPED, 1, 513}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5382}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5136}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3568}, + {LXB_UNICODE_IDNA_MAPPED, 4, 4316}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 812}, + {LXB_UNICODE_IDNA_MAPPED, 1, 136}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5410}, + {LXB_UNICODE_IDNA_MAPPED, 1, 318}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2965}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2277}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1456}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3467}, + {LXB_UNICODE_IDNA_MAPPED, 1, 273}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5003}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2157}, + {LXB_UNICODE_IDNA_MAPPED, 1, 168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5230}, + {LXB_UNICODE_IDNA_MAPPED, 1, 518}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3470}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4744}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4659}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3054}, + {LXB_UNICODE_IDNA_MAPPED, 1, 775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 974}, {LXB_UNICODE_IDNA_MAPPED, 1, 4992}, - {LXB_UNICODE_IDNA_MAPPED, 2, 38}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3305}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4789}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4552}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3623}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2036}, - {LXB_UNICODE_IDNA_MAPPED, 2, 578}, - {LXB_UNICODE_IDNA_MAPPED, 1, 686}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3023}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5097}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5038}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1235}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2792}, + {LXB_UNICODE_IDNA_MAPPED, 1, 630}, + {LXB_UNICODE_IDNA_MAPPED, 2, 119}, + {LXB_UNICODE_IDNA_MAPPED, 1, 242}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3951}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4491}, + {LXB_UNICODE_IDNA_MAPPED, 1, 403}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3022}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5101}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2889}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3251}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1614}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3519}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1607}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1405}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2941}, + {LXB_UNICODE_IDNA_MAPPED, 1, 182}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5306}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3030}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1033}, + {LXB_UNICODE_IDNA_MAPPED, 1, 651}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5041}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3608}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4515}, + {LXB_UNICODE_IDNA_MAPPED, 1, 244}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2690}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2121}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3604}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5067}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 685}, + {LXB_UNICODE_IDNA_MAPPED, 1, 803}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1899}, + {LXB_UNICODE_IDNA_MAPPED, 2, 936}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3541}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1536}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5172}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4189}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1192}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4725}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5194}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3185}, + {LXB_UNICODE_IDNA_MAPPED, 1, 801}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5011}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5208}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1084}, + {LXB_UNICODE_IDNA_MAPPED, 1, 902}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5167}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2356}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2424}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1592}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5234}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2021}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1417}, + {LXB_UNICODE_IDNA_MAPPED, 1, 744}, + {LXB_UNICODE_IDNA_MAPPED, 1, 272}, + {LXB_UNICODE_IDNA_MAPPED, 1, 658}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3279}, + {LXB_UNICODE_IDNA_MAPPED, 1, 738}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2451}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4543}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1120}, + {LXB_UNICODE_IDNA_MAPPED, 1, 234}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2645}, + {LXB_UNICODE_IDNA_MAPPED, 1, 880}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4447}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4628}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4695}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3614}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4563}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1666}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4631}, + {LXB_UNICODE_IDNA_MAPPED, 2, 983}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1208}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1786}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5174}, + {LXB_UNICODE_IDNA_MAPPED, 2, 540}, + {LXB_UNICODE_IDNA_MAPPED, 1, 787}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4483}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4685}, + {LXB_UNICODE_IDNA_MAPPED, 1, 143}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4922}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2717}, + {LXB_UNICODE_IDNA_MAPPED, 1, 399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4480}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3411}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4791}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4911}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3149}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3342}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1708}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2862}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1777}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3065}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4575}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1488}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4668}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3461}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5088}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3992}, + {LXB_UNICODE_IDNA_MAPPED, 1, 497}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5033}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5326}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4736}, + {LXB_UNICODE_IDNA_MAPPED, 1, 800}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5275}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2040}, + {LXB_UNICODE_IDNA_MAPPED, 1, 680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2072}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4418}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4816}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5298}, {LXB_UNICODE_IDNA_MAPPED, 1, 5288}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1554}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5057}, - {LXB_UNICODE_IDNA_MAPPED, 1, 426}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1513}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1806}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1705}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3310}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4246}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2139}, + {LXB_UNICODE_IDNA_MAPPED, 1, 876}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5107}, + {LXB_UNICODE_IDNA_MAPPED, 1, 349}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1394}, + {LXB_UNICODE_IDNA_MAPPED, 1, 70}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2976}, + {LXB_UNICODE_IDNA_MAPPED, 1, 103}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3189}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3473}, + {LXB_UNICODE_IDNA_MAPPED, 1, 150}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5339}, {LXB_UNICODE_IDNA_MAPPED, 1, 1619}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4539}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2772}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2366}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4382}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5186}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3095}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4400}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 796}, - {LXB_UNICODE_IDNA_MAPPED, 5, 2298}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4849}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4603}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4805}, - {LXB_UNICODE_IDNA_MAPPED, 1, 460}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4537}, - {LXB_UNICODE_IDNA_MAPPED, 3, 4108}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1562}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5360}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5133}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4467}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3101}, - {LXB_UNICODE_IDNA_MAPPED, 2, 4863}, - {LXB_UNICODE_IDNA_MAPPED, 2, 544}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5119}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1232}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1567}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1549}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1452}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1448}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3106}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3182}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3114}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4703}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5229}, - {LXB_UNICODE_IDNA_MAPPED, 1, 719}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1413}, - {LXB_UNICODE_IDNA_MAPPED, 3, 41}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5041}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1698}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1875}, - {LXB_UNICODE_IDNA_MAPPED, 2, 2283}, - {LXB_UNICODE_IDNA_MAPPED, 3, 1093}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4903}, - {LXB_UNICODE_IDNA_MAPPED, 1, 60}, - {LXB_UNICODE_IDNA_MAPPED, 1, 748}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5276}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1160}, - {LXB_UNICODE_IDNA_MAPPED, 1, 468}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5135}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3315}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5242}, - {LXB_UNICODE_IDNA_MAPPED, 1, 697}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4890}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5264}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1958}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3256}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4618}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1587}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3215}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3877}, + {LXB_UNICODE_IDNA_MAPPED, 1, 677}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2322}, + {LXB_UNICODE_IDNA_MAPPED, 1, 450}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5352}, + {LXB_UNICODE_IDNA_MAPPED, 1, 896}, + {LXB_UNICODE_IDNA_MAPPED, 1, 504}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3168}, + {LXB_UNICODE_IDNA_MAPPED, 1, 710}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2934}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3561}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3303}, + {LXB_UNICODE_IDNA_MAPPED, 3, 599}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4985}, + {LXB_UNICODE_IDNA_MAPPED, 1, 227}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4821}, + {LXB_UNICODE_IDNA_MAPPED, 1, 724}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4680}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3127}, + {LXB_UNICODE_IDNA_MAPPED, 1, 81}, {LXB_UNICODE_IDNA_MAPPED, 1, 3322}, - {LXB_UNICODE_IDNA_MAPPED, 1, 649}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3130}, - {LXB_UNICODE_IDNA_MAPPED, 1, 172}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1709}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2982}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1669}, - {LXB_UNICODE_IDNA_MAPPED, 1, 250}, - {LXB_UNICODE_IDNA_MAPPED, 1, 164}, - {LXB_UNICODE_IDNA_MAPPED, 18, 4340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4464}, + {LXB_UNICODE_IDNA_MAPPED, 1, 68}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3965}, + {LXB_UNICODE_IDNA_MAPPED, 1, 102}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4585}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1795}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4673}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2768}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1138}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4461}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2621}, + {LXB_UNICODE_IDNA_MAPPED, 1, 741}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3399}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3452}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4869}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5414}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1449}, + {LXB_UNICODE_IDNA_MAPPED, 1, 891}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5141}, + {LXB_UNICODE_IDNA_MAPPED, 1, 882}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5387}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2944}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3929}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5266}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1422}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4468}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1425}, {LXB_UNICODE_IDNA_MAPPED, 1, 5005}, - {LXB_UNICODE_IDNA_MAPPED, 1, 776}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4535}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1520}, - {LXB_UNICODE_IDNA_MAPPED, 1, 821}, - {LXB_UNICODE_IDNA_MAPPED, 1, 421}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1790}, - {LXB_UNICODE_IDNA_MAPPED, 2, 3892}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4978}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5399}, - {LXB_UNICODE_IDNA_MAPPED, 1, 899}, - {LXB_UNICODE_IDNA_MAPPED, 1, 838}, - {LXB_UNICODE_IDNA_MAPPED, 3, 2569}, - {LXB_UNICODE_IDNA_MAPPED, 1, 705}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3150}, - {LXB_UNICODE_IDNA_MAPPED, 1, 744}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1430}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4641}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3299}, - {LXB_UNICODE_IDNA_MAPPED, 1, 708}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2927}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4435}, - {LXB_UNICODE_IDNA_MAPPED, 1, 417}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1015}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3102}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4984}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4954}, - {LXB_UNICODE_IDNA_MAPPED, 2, 1210}, - {LXB_UNICODE_IDNA_MAPPED, 2, 564}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3043}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2947}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3257}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4583}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4687}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4551}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2082}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1387}, - {LXB_UNICODE_IDNA_MAPPED, 1, 5001}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3113}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3390}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2518}, {LXB_UNICODE_IDNA_MAPPED, 1, 1626}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3088}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4885}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3334}, + {LXB_UNICODE_IDNA_MAPPED, 1, 407}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3009}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3337}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2760}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3092}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1677}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3014}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4536}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2842}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2061}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2334}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5104}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4549}, + {LXB_UNICODE_IDNA_MAPPED, 1, 830}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4851}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1863}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3557}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5255}, + {LXB_UNICODE_IDNA_MAPPED, 1, 141}, + {LXB_UNICODE_IDNA_MAPPED, 5, 2344}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1516}, + {LXB_UNICODE_IDNA_MAPPED, 1, 480}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1716}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4252}, + {LXB_UNICODE_IDNA_MAPPED, 1, 701}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2143}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1564}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1241}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5093}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5293}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1396}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3212}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3263}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5320}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3475}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1217}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3965}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2217}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2973}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3233}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4899}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1490}, + {LXB_UNICODE_IDNA_MAPPED, 1, 240}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1634}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5374}, + {LXB_UNICODE_IDNA_MAPPED, 1, 847}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4739}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5007}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3226}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5369}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4742}, + {LXB_UNICODE_IDNA_MAPPED, 1, 95}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5344}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3496}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2076}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3715}, + {LXB_UNICODE_IDNA_MAPPED, 1, 705}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5270}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3526}, + {LXB_UNICODE_IDNA_MAPPED, 2, 544}, + {LXB_UNICODE_IDNA_MAPPED, 1, 467}, + {LXB_UNICODE_IDNA_MAPPED, 1, 142}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2854}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4102}, + {LXB_UNICODE_IDNA_MAPPED, 1, 321}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3332}, + {LXB_UNICODE_IDNA_MAPPED, 2, 989}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2848}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2907}, + {LXB_UNICODE_IDNA_MAPPED, 1, 389}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3393}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3429}, + {LXB_UNICODE_IDNA_MAPPED, 1, 639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 520}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4838}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1881}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5322}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4509}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1797}, + {LXB_UNICODE_IDNA_MAPPED, 1, 134}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1446}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3176}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2625}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5295}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4444}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1530}, + {LXB_UNICODE_IDNA_MAPPED, 1, 241}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2778}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4441}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2056}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3943}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4466}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5022}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3115}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4458}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5220}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2525}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3375}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4859}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4686}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3124}, + {LXB_UNICODE_IDNA_MAPPED, 1, 643}, + {LXB_UNICODE_IDNA_MAPPED, 4, 1273}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 770}, + {LXB_UNICODE_IDNA_MAPPED, 1, 183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5036}, + {LXB_UNICODE_IDNA_MAPPED, 1, 63}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5181}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5421}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1639}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1598}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4340}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5084}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2443}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2083}, + {LXB_UNICODE_IDNA_MAPPED, 1, 111}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3237}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2433}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3308}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1595}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5062}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3207}, + {LXB_UNICODE_IDNA_MAPPED, 2, 589}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2086}, + {LXB_UNICODE_IDNA_MAPPED, 2, 570}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3447}, + {LXB_UNICODE_IDNA_MAPPED, 1, 502}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2694}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1693}, + {LXB_UNICODE_IDNA_MAPPED, 2, 4802}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4908}, + {LXB_UNICODE_IDNA_MAPPED, 1, 225}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5395}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2133}, + {LXB_UNICODE_IDNA_MAPPED, 1, 482}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1408}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3598}, + {LXB_UNICODE_IDNA_MAPPED, 2, 1005}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3501}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4828}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1878}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5189}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4195}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1411}, + {LXB_UNICODE_IDNA_MAPPED, 1, 699}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3835}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2127}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4727}, + {LXB_UNICODE_IDNA_MAPPED, 1, 351}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3098}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3017}, + {LXB_UNICODE_IDNA_MAPPED, 2, 104}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5056}, + {LXB_UNICODE_IDNA_MAPPED, 1, 916}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2362}, + {LXB_UNICODE_IDNA_MAPPED, 1, 72}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1620}, + {LXB_UNICODE_IDNA_MAPPED, 2, 617}, + {LXB_UNICODE_IDNA_MAPPED, 1, 771}, + {LXB_UNICODE_IDNA_MAPPED, 1, 580}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2027}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4974}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4807}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1707}, + {LXB_UNICODE_IDNA_MAPPED, 1, 211}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4665}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3277}, + {LXB_UNICODE_IDNA_MAPPED, 4, 2457}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4620}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4573}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1493}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2733}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3244}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4581}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1789}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1016}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4693}, + {LXB_UNICODE_IDNA_MAPPED, 2, 3612}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4477}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3371}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4565}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1792}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4183}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4625}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3425}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5191}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5408}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2654}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5151}, + {LXB_UNICODE_IDNA_MAPPED, 1, 773}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4174}, + {LXB_UNICODE_IDNA_MAPPED, 1, 226}, + {LXB_UNICODE_IDNA_MAPPED, 1, 637}, + {LXB_UNICODE_IDNA_MAPPED, 2, 2660}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5126}, + {LXB_UNICODE_IDNA_MAPPED, 1, 472}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5393}, + {LXB_UNICODE_IDNA_MAPPED, 3, 1940}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4114}, + {LXB_UNICODE_IDNA_MAPPED, 1, 247}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4117}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4924}, + {LXB_UNICODE_IDNA_MAPPED, 1, 2960}, + {LXB_UNICODE_IDNA_MAPPED, 1, 5202}, {LXB_UNICODE_IDNA_MAPPED, 1, 3340}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2978}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3453}, - {LXB_UNICODE_IDNA_MAPPED, 2, 595}, - {LXB_UNICODE_IDNA_MAPPED, 1, 58}, - {LXB_UNICODE_IDNA_MAPPED, 1, 4546}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1488}, - {LXB_UNICODE_IDNA_MAPPED, 1, 501}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1818}, - {LXB_UNICODE_IDNA_MAPPED, 1, 2967}, - {LXB_UNICODE_IDNA_MAPPED, 1, 285}, - {LXB_UNICODE_IDNA_MAPPED, 1, 3311}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1807}, - {LXB_UNICODE_IDNA_MAPPED, 1, 1512} + {LXB_UNICODE_IDNA_MAPPED, 1, 2937}, + {LXB_UNICODE_IDNA_MAPPED, 3, 3883}, + {LXB_UNICODE_IDNA_MAPPED, 3, 2868}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1524}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3180}, + {LXB_UNICODE_IDNA_MAPPED, 3, 4933}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3162}, + {LXB_UNICODE_IDNA_MAPPED, 1, 1775}, + {LXB_UNICODE_IDNA_MAPPED, 1, 3063}, + {LXB_UNICODE_IDNA_MAPPED, 1, 4904} }; static const lxb_unicode_composition_entry_t lxb_unicode_composition_entries[458] = diff --git a/ext/lexbor/lexbor/unicode/unicode.c b/ext/lexbor/lexbor/unicode/unicode.c index 991fc0a38823..ced80b430a7c 100644 --- a/ext/lexbor/lexbor/unicode/unicode.c +++ b/ext/lexbor/lexbor/unicode/unicode.c @@ -451,7 +451,7 @@ lxb_unicode_normalize_body(lxb_unicode_normalizer_t *uc, const void *data, uc->starter = p; uc->ican = p; - if (p - buf >= uc->flush_cp) { + if (lxb_size(p - buf) >= uc->flush_cp) { if (!is_cp) { status = lxb_unicode_flush(uc, cb->cb, ctx); } @@ -887,7 +887,7 @@ lxb_unicode_entry(lxb_codepoint_t cp) return &lxb_unicode_entries[0]; } - if (cp < 205744) { + if (cp < 210042) { if (cp < 83527) { if (cp < 57345) { return &lxb_unicode_entries[lxb_unicode_table_map_0_57345[cp - 0]]; @@ -897,11 +897,11 @@ lxb_unicode_entry(lxb_codepoint_t cp) } } else if (cp >= 90368) { - if (cp < 101641) { - return &lxb_unicode_entries[lxb_unicode_table_map_90368_101641[cp - 90368]]; + if (cp < 101875) { + return &lxb_unicode_entries[lxb_unicode_table_map_90368_101875[cp - 90368]]; } else if (cp >= 110576) { - return &lxb_unicode_entries[lxb_unicode_table_map_110576_205744[cp - 110576]]; + return &lxb_unicode_entries[lxb_unicode_table_map_110576_210042[cp - 110576]]; } } } diff --git a/ext/lexbor/lexbor/url/base.h b/ext/lexbor/lexbor/url/base.h index c95377ab89e1..94d0e2a1901c 100644 --- a/ext/lexbor/lexbor/url/base.h +++ b/ext/lexbor/lexbor/url/base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Alexander Borisov + * Copyright (C) 2023-2025 Alexander Borisov * * Author: Alexander Borisov */ @@ -17,7 +17,7 @@ extern "C" { #define LXB_URL_VERSION_MAJOR 0 -#define LXB_URL_VERSION_MINOR 3 +#define LXB_URL_VERSION_MINOR 4 #define LXB_URL_VERSION_PATCH 0 #define LXB_URL_VERSION_STRING LEXBOR_STRINGIZE(LXB_URL_VERSION_MAJOR) "." \ diff --git a/ext/lexbor/lexbor/url/url.c b/ext/lexbor/lexbor/url/url.c index bbb3b5bbd3cb..a5b323f2df09 100644 --- a/ext/lexbor/lexbor/url/url.c +++ b/ext/lexbor/lexbor/url/url.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Alexander Borisov + * Copyright (C) 2023-2026 Alexander Borisov * * Author: Alexander Borisov */ @@ -14,14 +14,14 @@ #include "lexbor/core/swar.h" #include "lexbor/unicode/idna.h" -#define LEXBOR_STR_RES_MAP_LOWERCASE -#define LEXBOR_STR_RES_ALPHANUMERIC_CHARACTER -#define LEXBOR_STR_RES_ALPHA_CHARACTER -#define LEXBOR_STR_RES_CHAR_TO_TWO_HEX_VALUE -#define LEXBOR_STR_RES_MAP_HEX -#define LEXBOR_STR_RES_MAP_NUM -#include "lexbor/core/str_res.h" - +#ifndef LEXBOR_DISABLE_INTERNAL_EXTERN + LXB_EXTERN const lxb_char_t lexbor_str_res_map_lowercase[256]; + LXB_EXTERN const size_t lexbor_str_res_alphanumeric_character[256]; + LXB_EXTERN const size_t lexbor_str_res_alpha_character[256]; + LXB_EXTERN const char *lexbor_str_res_char_to_two_hex_value[257]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_num[256]; + LXB_EXTERN const lxb_char_t lexbor_str_res_map_hex[256]; +#endif #define LXB_URL_BUFFER_SIZE 4096 #define LXB_URL_BUFFER_NUM_SIZE 128 @@ -36,6 +36,7 @@ typedef enum { LXB_URL_MAP_PATH = 0x10, LXB_URL_MAP_USERINFO = 0x20, LXB_URL_MAP_COMPONENT = 0x40, + LXB_URL_MAP_X_WWW_FORM = 0x80, LXB_URL_MAP_ALL = 0xff } lxb_url_map_type_t; @@ -54,6 +55,13 @@ typedef struct { } lxb_url_idna_ctx_t; +typedef struct { + lexbor_str_t **out_buf; + size_t out_length; + size_t out_size; +} +lxb_url_search_params_ctx_t; + static const uint8_t lxb_url_map[256] = { @@ -89,22 +97,22 @@ static const uint8_t lxb_url_map[256] = LXB_URL_MAP_ALL, /* 0x1d */ LXB_URL_MAP_ALL, /* 0x1e */ LXB_URL_MAP_ALL, /* 0x1f */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT, /* 0x20 ( ) */ - LXB_URL_MAP_UNDEF, /* 0x21 (!) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT, /* 0x22 (") */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT, /* 0x23 (#) */ - LXB_URL_MAP_COMPONENT, /* 0x24 ($) */ - LXB_URL_MAP_UNDEF, /* 0x25 (%) */ - LXB_URL_MAP_COMPONENT, /* 0x26 (&) */ - LXB_URL_MAP_SPECIAL_QUERY, /* 0x27 (') */ - LXB_URL_MAP_UNDEF, /* 0x28 (() */ - LXB_URL_MAP_UNDEF, /* 0x29 ()) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x20 ( ) */ + LXB_URL_MAP_X_WWW_FORM, /* 0x21 (!) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x22 (") */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x23 (#) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x24 ($) */ + LXB_URL_MAP_X_WWW_FORM, /* 0x25 (%) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x26 (&) */ + LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_X_WWW_FORM, /* 0x27 (') */ + LXB_URL_MAP_X_WWW_FORM, /* 0x28 (() */ + LXB_URL_MAP_X_WWW_FORM, /* 0x29 ()) */ LXB_URL_MAP_UNDEF, /* 0x2a (*) */ - LXB_URL_MAP_COMPONENT, /* 0x2b (+) */ - LXB_URL_MAP_COMPONENT, /* 0x2c (,) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2b (+) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2c (,) */ LXB_URL_MAP_UNDEF, /* 0x2d (-) */ LXB_URL_MAP_UNDEF, /* 0x2e (.) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x2f (/) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2f (/) */ LXB_URL_MAP_UNDEF, /* 0x30 (0) */ LXB_URL_MAP_UNDEF, /* 0x31 (1) */ LXB_URL_MAP_UNDEF, /* 0x32 (2) */ @@ -115,13 +123,13 @@ static const uint8_t lxb_url_map[256] = LXB_URL_MAP_UNDEF, /* 0x37 (7) */ LXB_URL_MAP_UNDEF, /* 0x38 (8) */ LXB_URL_MAP_UNDEF, /* 0x39 (9) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x3a (:) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x3b (;) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT, /* 0x3c (<) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x3d (=) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT, /* 0x3e (>) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x3f (?) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x40 (@) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3a (:) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3b (;) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3c (<) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3d (=) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3e (>) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3f (?) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x40 (@) */ LXB_URL_MAP_UNDEF, /* 0x41 (A) */ LXB_URL_MAP_UNDEF, /* 0x42 (B) */ LXB_URL_MAP_UNDEF, /* 0x43 (C) */ @@ -148,12 +156,12 @@ static const uint8_t lxb_url_map[256] = LXB_URL_MAP_UNDEF, /* 0x58 (X) */ LXB_URL_MAP_UNDEF, /* 0x59 (Y) */ LXB_URL_MAP_UNDEF, /* 0x5a (Z) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x5b ([) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x5c (\) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x5d (]) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x5e (^) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5b ([) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5c (\) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5d (]) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5e (^) */ LXB_URL_MAP_UNDEF, /* 0x5f (_) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x60 (`) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x60 (`) */ LXB_URL_MAP_UNDEF, /* 0x61 (a) */ LXB_URL_MAP_UNDEF, /* 0x62 (b) */ LXB_URL_MAP_UNDEF, /* 0x63 (c) */ @@ -180,10 +188,10 @@ static const uint8_t lxb_url_map[256] = LXB_URL_MAP_UNDEF, /* 0x78 (x) */ LXB_URL_MAP_UNDEF, /* 0x79 (y) */ LXB_URL_MAP_UNDEF, /* 0x7a (z) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x7b ({) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x7c (|) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT, /* 0x7d (}) */ - LXB_URL_MAP_UNDEF, /* 0x7e (~) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7b ({) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7c (|) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7d (}) */ + LXB_URL_MAP_X_WWW_FORM, /* 0x7e (~) */ LXB_URL_MAP_ALL, /* 0x7f */ LXB_URL_MAP_ALL, /* 0x80 */ LXB_URL_MAP_ALL, /* 0x81 */ @@ -471,7 +479,7 @@ lxb_url_scheme_length = sizeof(lxb_url_scheme_res) / sizeof(lxb_url_scheme_data_ #define lxb_url_parse_return(data, buf, status) \ do { \ if ((buf) != (data)) { \ - lexbor_free((lxb_char_t *) (buf)); \ + parser->buffer = (lxb_char_t *) (buf); \ } \ return (status); \ } \ @@ -604,6 +612,10 @@ lxb_url_percent_decode(const lxb_char_t *data, const lxb_char_t *end, lexbor_str_t *str, lexbor_mraw_t *mraw, lxb_url_host_opt_t *opt); +static lxb_status_t +lxb_url_percent_decode_plus(const lxb_char_t *data, const lxb_char_t *end, + lexbor_str_t *str, lexbor_mraw_t *mraw); + static const lxb_char_t * lxb_url_path_part_by_index(const lxb_url_t *url, size_t index, size_t *out_length); @@ -613,6 +625,10 @@ lxb_url_host_set_h(lxb_url_t *url, lxb_url_parser_t *parser, const lxb_char_t *host, size_t length, lxb_url_state_t override_state); +static lxb_status_t +lxb_url_search_params_parse(lxb_url_search_params_t *search_params, + const lxb_char_t *query, size_t length); + lxb_url_parser_t * lxb_url_parser_create(void) @@ -645,6 +661,7 @@ lxb_url_parser_init(lxb_url_parser_t *parser, lexbor_mraw_t *mraw) parser->mraw = mraw; parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; return LXB_STATUS_OK; @@ -667,6 +684,10 @@ lxb_url_parser_clean(lxb_url_parser_t *parser) if (parser->log != NULL) { lexbor_plog_clean(parser->log); } + + if (parser->buffer != NULL) { + parser->buffer = lexbor_free(parser->buffer); + } } lxb_url_parser_t * @@ -679,6 +700,10 @@ lxb_url_parser_destroy(lxb_url_parser_t *parser, bool destroy_self) parser->log = lexbor_plog_destroy(parser->log, true); parser->idna = lxb_unicode_idna_destroy(parser->idna, true); + if (parser->buffer != NULL) { + parser->buffer = lexbor_free(parser->buffer); + } + if (destroy_self) { return lexbor_free(parser); } @@ -835,7 +860,7 @@ lxb_url_is_url_codepoint(lxb_codepoint_t cp) return lxb_url_codepoint_alphanumeric[(lxb_char_t) cp] != 0xFF; } -lxb_inline bool +bool lxb_url_is_special(const lxb_url_t *url) { return url->scheme.type != LXB_URL_SCHEMEL_TYPE__UNKNOWN; @@ -1004,27 +1029,34 @@ lxb_url_path_append_wo_slash(lxb_url_t *url, static lxb_status_t lxb_url_path_append(lxb_url_t *url, const lxb_char_t *data, size_t length) { - size_t len; - lxb_char_t *p; + lxb_char_t *p, *begin; lexbor_str_t *str; str = &url->path.str; if (str->data == NULL) { p = lexbor_str_init(str, url->mraw, length + 1); - if (p == NULL) { - return LXB_STATUS_ERROR_MEMORY_ALLOCATION; - } + } + else { + /* + 2 == begin '/' and end '\0' */ + p = lexbor_str_check_size(str, url->mraw, length + 2); + } + + if (p == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; } - len = str->length; - str->length += 1; + begin = &str->data[str->length]; + begin[0] = '/'; - p = lexbor_str_append(&url->path.str, url->mraw, data, length); + if (length > 0) { + memcpy(&begin[1], data, sizeof(lxb_char_t) * length); + } - str->data[len] = '/'; + str->length += length + 1; + str->data[str->length] = '\0'; - return (p != NULL) ? LXB_STATUS_OK : LXB_STATUS_ERROR_MEMORY_ALLOCATION; + return LXB_STATUS_OK; } static lxb_status_t @@ -1081,9 +1113,9 @@ lxb_url_host_copy(const lxb_url_host_t *src, lxb_url_host_t *dst, } } - if (src->type <= LXB_URL_HOST_TYPE_OPAQUE) { - dst->type = src->type; + dst->type = src->type; + if (src->type <= LXB_URL_HOST_TYPE_OPAQUE) { if (src->type == LXB_URL_HOST_TYPE__UNDEF) { return LXB_STATUS_OK; } @@ -1785,7 +1817,6 @@ lxb_url_parse_basic_h(lxb_url_parser_t *parser, lxb_url_t *url, if (override_state != LXB_URL_STATE__UNDEF && url->scheme.type == LXB_URL_SCHEMEL_TYPE_FILE) { - p -= 1; state = LXB_URL_STATE_FILE_HOST_STATE; goto again; } @@ -1818,7 +1849,7 @@ lxb_url_parse_basic_h(lxb_url_parser_t *parser, lxb_url_t *url, } if (override_state == LXB_URL_STATE_HOSTNAME_STATE) { - lxb_url_parse_return(orig_data, buf, LXB_STATUS_OK); + lxb_url_parse_return(orig_data, buf, LXB_STATUS_ERROR); } status = lxb_url_host_parse(parser, begin, p, &url->host, @@ -1906,7 +1937,7 @@ lxb_url_parse_basic_h(lxb_url_parser_t *parser, lxb_url_t *url, { if (begin == p) { if (override_state != LXB_URL_STATE__UNDEF) { - lxb_url_parse_return(orig_data, buf, LXB_STATUS_OK); + lxb_url_parse_return(orig_data, buf, LXB_STATUS_ERROR); } state = LXB_URL_STATE_PATH_START_STATE; @@ -3056,7 +3087,7 @@ lxb_url_remove_tab_newline(lxb_url_parser_t *parser, return NULL; } - buf = lexbor_malloc(*length); + buf = lexbor_malloc(*length + 1); if (buf == NULL) { return NULL; } @@ -3083,6 +3114,8 @@ lxb_url_remove_tab_newline(lxb_url_parser_t *parser, *length = p_buf - buf; + buf[*length] = '\0'; + return buf; } @@ -4012,6 +4045,50 @@ lxb_url_percent_decode(const lxb_char_t *data, const lxb_char_t *end, return LXB_STATUS_OK; } +static lxb_status_t +lxb_url_percent_decode_plus(const lxb_char_t *data, const lxb_char_t *end, + lexbor_str_t *str, lexbor_mraw_t *mraw) +{ + lxb_char_t c, *dp; + lxb_status_t status; + const lxb_char_t *p; + + status = lxb_url_str_init(str, mraw, (end - data) + 1); + if (status != LXB_STATUS_OK) { + return status; + } + + p = data; + dp = str->data; + + while (p < end) { + c = *p++; + + if (c != '%') { + if (c == '+') { + c = ' '; + } + + *dp++ = c; + continue; + } + + if (p + 2 <= end && lexbor_str_res_map_hex[p[0]] != 0xff + && lexbor_str_res_map_hex[p[1]] != 0xff) + { + c = lexbor_str_res_map_hex[p[0]] << 4 | lexbor_str_res_map_hex[p[1]]; + p += 2; + } + + *dp++ = c; + } + + *dp = '\0'; + str->length = dp - str->data; + + return LXB_STATUS_OK; +} + void lxb_url_erase(lxb_url_t *url) { @@ -4123,6 +4200,7 @@ lxb_url_api_href_set(lxb_url_t *url, lxb_url_parser_t *parser, parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; } origin_mraw = parser->mraw; @@ -4167,6 +4245,7 @@ lxb_url_api_protocol_set(lxb_url_t *url, lxb_url_parser_t *parser, parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; } status = lxb_url_parse_basic_h(parser, url, NULL, protocol, length, @@ -4246,7 +4325,8 @@ lxb_url_host_set_h(lxb_url_t *url, lxb_url_parser_t *parser, lxb_url_parser_t self_parser; const lxb_char_t tmp[1] = ""; - if (url->host.type == LXB_URL_HOST_TYPE_OPAQUE) { + /* If this’s URL has an opaque path, then return. */ + if (url->path.opaque) { return LXB_STATUS_OK; } @@ -4260,6 +4340,7 @@ lxb_url_host_set_h(lxb_url_t *url, lxb_url_parser_t *parser, parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; } old = url->host; @@ -4314,6 +4395,7 @@ lxb_url_api_port_set(lxb_url_t *url, lxb_url_parser_t *parser, parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; } status = lxb_url_parse_basic_h(parser, url, NULL, port, length, @@ -4348,6 +4430,7 @@ lxb_url_api_pathname_set(lxb_url_t *url, lxb_url_parser_t *parser, parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; } url->path.length = 0; @@ -4390,6 +4473,7 @@ lxb_url_api_search_set(lxb_url_t *url, lxb_url_parser_t *parser, parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; } status = lxb_url_parse_basic_h(parser, url, NULL, search, length, @@ -4429,6 +4513,7 @@ lxb_url_api_hash_set(lxb_url_t *url, lxb_url_parser_t *parser, parser->log = NULL; parser->idna = NULL; + parser->buffer = NULL; } status = lxb_url_parse_basic_h(parser, url, NULL, hash, length, @@ -4804,7 +4889,7 @@ lxb_url_serialize_fragment(const lxb_url_t *url, } lxb_url_t * -lxb_url_clone(lexbor_mraw_t *mraw, lxb_url_t *url) +lxb_url_clone(lexbor_mraw_t *mraw, const lxb_url_t *url) { lxb_status_t status; lxb_url_t *new_url; @@ -4862,3 +4947,747 @@ lxb_url_clone(lexbor_mraw_t *mraw, lxb_url_t *url) return NULL; } + +lxb_url_search_params_t * +lxb_url_search_params_init(lexbor_mraw_t *mraw, + const lxb_char_t *query, size_t length) +{ + lxb_status_t status; + lxb_url_search_params_t *sp; + + sp = lexbor_mraw_calloc(mraw, sizeof(lxb_url_search_params_t)); + if (sp == NULL) { + return NULL; + } + + sp->mraw = mraw; + sp->length = 0; + + status = lxb_url_search_params_parse(sp, query, length); + if (status != LXB_STATUS_OK) { + return lxb_url_search_params_destroy(sp); + } + + return sp; +} + +lxb_inline lxb_url_search_entry_t * +lxb_url_search_params_entry(lxb_url_search_params_t *search_params, + lxb_url_search_entry_t *last, lexbor_mraw_t *mraw, + const lxb_char_t *query, const lxb_char_t *p, + lxb_status_t *status) +{ + lxb_url_search_entry_t *entry; + + entry = lexbor_mraw_calloc(mraw, + sizeof(lxb_url_search_entry_t)); + if (entry == NULL) { + *status = LXB_STATUS_ERROR_MEMORY_ALLOCATION; + return NULL; + } + + last->next = entry; + entry->prev = last; + entry->next = NULL; + + search_params->length += 1; + + *status = lxb_url_percent_decode_plus(query, p, &entry->name, mraw); + + return entry; +} + +static lxb_status_t +lxb_url_search_params_parse(lxb_url_search_params_t *search_params, + const lxb_char_t *query, size_t length) +{ + lxb_char_t c; + lxb_status_t status; + const lxb_char_t *p, *end; + lexbor_mraw_t *mraw; + lxb_url_search_entry_t first, *last, *entry; + + if (query == NULL || length == 0) { + return LXB_STATUS_OK; + } + + if (*query == '?') { + query += 1; + length -= 1; + } + + p = query; + end = p + length; + mraw = search_params->mraw; + last = &first; + last->next = NULL; + last->prev = NULL; + + while (p < end) { + c = *p++; + + if (c == '=') { + entry = lxb_url_search_params_entry(search_params, last, mraw, + query, p - 1, &status); + if (status != LXB_STATUS_OK) { + return status; + } + + last = entry; + query = p; + + while (p < end) { + c = *p; + + if (c == '&') { + break; + } + + p += 1; + } + + status = lxb_url_percent_decode_plus(query, p, + &entry->value, mraw); + if (status != LXB_STATUS_OK) { + return status; + } + + p += 1; + query = p; + } + else if (c == '&') { + entry = lxb_url_search_params_entry(search_params, last, mraw, + query, p - 1, &status); + if (status != LXB_STATUS_OK) { + return status; + } + + last = entry; + + lexbor_str_init(&entry->value, mraw, 0); + if (entry->value.data == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + + query = p; + } + } + + if (query < p) { + entry = lxb_url_search_params_entry(search_params, last, mraw, + query, p, &status); + if (status != LXB_STATUS_OK) { + return status; + } + + lexbor_str_init(&entry->value, mraw, 0); + if (entry->value.data == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + + search_params->first = first.next; + + if (first.next != NULL) { + search_params->last = last; + search_params->first->prev = NULL; + } + else { + search_params->last = NULL; + } + + return LXB_STATUS_OK; +} + +lxb_url_search_params_t * +lxb_url_search_params_destroy(lxb_url_search_params_t *search_params) +{ + lxb_url_search_entry_t *entry, *next; + lexbor_mraw_t *mraw; + + if (search_params == NULL) { + return NULL; + } + + entry = search_params->first; + mraw = search_params->mraw; + + while (entry != NULL) { + next = entry->next; + + lexbor_str_destroy(&entry->name, mraw, false); + lexbor_str_destroy(&entry->value, mraw, false); + lexbor_mraw_free(mraw, entry); + + entry = next; + } + + return lexbor_mraw_free(mraw, search_params); +} + +static void +lxb_url_search_params_entry_destroy(lxb_url_search_params_t *search_params, + lxb_url_search_entry_t *entry) +{ + lexbor_mraw_t *mraw = search_params->mraw; + + lexbor_str_destroy(&entry->name, mraw, false); + lexbor_str_destroy(&entry->value, mraw, false); + lexbor_mraw_free(mraw, entry); +} + +static lxb_status_t +lxb_url_search_params_to_str(lexbor_str_t *str, lexbor_mraw_t *mraw, + const lxb_char_t *data, size_t length) +{ + if (data == NULL || length == 0) { + lexbor_str_init(str, mraw, 0); + } + else { + lexbor_str_init_append(str, mraw, data, length); + } + + return str->data != NULL ? LXB_STATUS_OK + : LXB_STATUS_ERROR_MEMORY_ALLOCATION; +} + +lxb_url_search_entry_t * +lxb_url_search_params_append(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length) +{ + lxb_status_t status; + lxb_url_search_entry_t *entry; + + entry = lexbor_mraw_calloc(search_params->mraw, + sizeof(lxb_url_search_entry_t)); + if (entry == NULL) { + return NULL; + } + + status = lxb_url_search_params_to_str(&entry->name, search_params->mraw, + name, name_length); + if (status != LXB_STATUS_OK) { + goto failed; + } + + status = lxb_url_search_params_to_str(&entry->value, search_params->mraw, + value, value_length); + if (status != LXB_STATUS_OK) { + goto failed; + } + + if (search_params->first == NULL) { + search_params->first = entry; + } + + if (search_params->last != NULL) { + search_params->last->next = entry; + } + + entry->prev = search_params->last; + entry->next = NULL; + search_params->last = entry; + + search_params->length += 1; + + return entry; + +failed: + + if (entry->name.data != NULL) { + lexbor_mraw_free(search_params->mraw, entry->name.data); + } + + if (entry->value.data != NULL) { + lexbor_mraw_free(search_params->mraw, entry->value.data); + } + + lexbor_mraw_free(search_params->mraw, entry); + + return NULL; +} + +static lexbor_action_t +lxb_url_search_params_delete_cb(lxb_url_search_params_t *sp, + lxb_url_search_entry_t *entry, void *ctx) +{ + if (sp->first == entry) { + sp->first = entry->next; + } + + if (sp->last == entry) { + sp->last = entry->prev; + } + + if (entry->next != NULL) { + entry->next->prev = entry->prev; + } + + if (entry->prev != NULL) { + entry->prev->next = entry->next; + } + + lxb_url_search_params_entry_destroy(sp, entry); + + sp->length -= 1; + + return LEXBOR_ACTION_OK; +} + +void +lxb_url_search_params_delete(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length) +{ + lxb_url_search_params_match(search_params, name, name_length, + value, value_length, + lxb_url_search_params_delete_cb, NULL); +} + +lxb_url_search_entry_t * +lxb_url_search_params_get_entry(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length) +{ + lexbor_str_t *str; + lxb_url_search_entry_t *entry; + + entry = search_params->first; + + while (entry != NULL) { + str = &entry->name; + + if (str->length == length + && memcmp(str->data, name, length) == 0) + { + return entry; + } + + entry = entry->next; + } + + return NULL; +} + +lexbor_str_t * +lxb_url_search_params_get(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length) +{ + lxb_url_search_entry_t *entry; + + entry = lxb_url_search_params_get_entry(search_params, name, length); + if (entry == NULL) { + return NULL; + } + + return &entry->value; +} + +static lexbor_action_t +lxb_url_search_params_get_all_cb(lxb_url_search_params_t *sp, + lxb_url_search_entry_t *entry, void *context) +{ + lxb_url_search_params_ctx_t *ctx = context; + + if (ctx->out_length >= ctx->out_size) { + return LEXBOR_ACTION_STOP; + } + + ctx->out_buf[ctx->out_length] = &entry->value; + ctx->out_length += 1; + + return LEXBOR_ACTION_OK; +} + +size_t +lxb_url_search_params_get_all(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length, + lexbor_str_t **out_buf, size_t out_size) +{ + lxb_url_search_params_ctx_t ctx; + + ctx.out_buf = out_buf; + ctx.out_length = 0; + ctx.out_size = out_size; + + lxb_url_search_params_match(search_params, name, length, NULL, 0, + lxb_url_search_params_get_all_cb, &ctx); + return ctx.out_length; +} + +static lexbor_action_t +lxb_url_search_params_get_count_cb(lxb_url_search_params_t *sp, + lxb_url_search_entry_t *entry, void *context) +{ + size_t *count = context; + + *count += 1; + + return LEXBOR_ACTION_OK; +} + +size_t +lxb_url_search_params_get_count(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length) +{ + size_t count = 0; + + lxb_url_search_params_match(search_params, name, length, NULL, 0, + lxb_url_search_params_get_count_cb, &count); + return count; +} + +lxb_url_search_entry_t * +lxb_url_search_params_match_entry(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length, + lxb_url_search_entry_t *entry) +{ + lexbor_str_t *str; + + if (entry == NULL) { + entry = search_params->first; + } + + while (entry != NULL) { + str = &entry->name; + + if (str->length == name_length + && memcmp(str->data, name, name_length) == 0) + { + if (value != NULL) { + str = &entry->value; + + if (str->length == value_length + && memcmp(str->data, value, value_length) == 0) + { + return entry; + } + } + else { + return entry; + } + } + + entry = entry->next; + } + + return NULL; +} + +void +lxb_url_search_params_match(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length, + lxb_url_search_params_match_f cb, void *ctx) +{ + lexbor_str_t *str; + lexbor_action_t action; + lxb_url_search_entry_t *entry, *next; + + entry = search_params->first; + + while (entry != NULL) { + str = &entry->name; + next = entry->next; + + if (str->length == name_length + && memcmp(str->data, name, name_length) == 0) + { + if (value != NULL) { + str = &entry->value; + + if (str->length == value_length + && memcmp(str->data, value, value_length) == 0) + { + action = cb(search_params, entry, ctx); + if (action == LEXBOR_ACTION_STOP) { + return; + } + } + } + else { + action = cb(search_params, entry, ctx); + if (action == LEXBOR_ACTION_STOP) { + return; + } + } + } + + entry = next; + } +} + +static lexbor_action_t +lxb_url_search_params_has_cb(lxb_url_search_params_t *sp, + lxb_url_search_entry_t *entry, void *ctx) +{ + bool *is = ctx; + + *is = true; + + return LEXBOR_ACTION_STOP; +} + +bool +lxb_url_search_params_has(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length) +{ + bool is = false; + + lxb_url_search_params_match(search_params, name, name_length, + value, value_length, + lxb_url_search_params_has_cb, &is); + return is; +} + +lxb_url_search_entry_t * +lxb_url_search_params_set(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length) +{ + bool changed; + lxb_status_t status; + lexbor_str_t *str, str_name, str_value; + lexbor_mraw_t *mraw; + lxb_url_search_entry_t *entry, *next, *root; + + mraw = search_params->mraw; + entry = search_params->first; + changed = false; + root = NULL; + + while (entry != NULL) { + str = &entry->name; + next = entry->next; + + if (str->length == name_length + && memcmp(str->data, name, name_length) == 0) + { + if (changed) { + lxb_url_search_params_delete_cb(search_params, entry, NULL); + entry = next; + continue; + } + + str_name = entry->name; + str_value = entry->value; + + status = lxb_url_search_params_to_str(&entry->name, mraw, + name, name_length); + if (status != LXB_STATUS_OK) { + goto failed; + } + + status = lxb_url_search_params_to_str(&entry->value, mraw, + value, value_length); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&entry->name, mraw, false); + goto failed; + } + + lexbor_str_destroy(&str_name, mraw, false); + lexbor_str_destroy(&str_value, mraw, false); + + changed = true; + root = entry; + } + + entry = next; + } + + if (!changed) { + return lxb_url_search_params_append(search_params, name, name_length, + value, value_length); + } + + return root; + +failed: + + entry->name = str_name; + entry->value = str_value; + + return NULL; +} + +lxb_inline int +lxb_url_search_params_compare(lxb_url_search_entry_t *first, + lxb_url_search_entry_t *second) +{ + return strcmp((const char *) first->name.data, + (const char *) second->name.data); +} + +void +lxb_url_search_params_sort(lxb_url_search_params_t *search_params) +{ + lxb_url_search_entry_t *root, *new_root, *node, *current; + + root = search_params->first; + + if (root == NULL) { + return; + } + + node = root; + root = root->next; + + node->next = NULL; + new_root = node; + + while (root != NULL) { + node = root; + root = root->next; + + if (lxb_url_search_params_compare(node, new_root) < 0) { + node->next = new_root; + new_root->prev = node; + new_root = node; + } + else { + current = new_root; + + while (current->next != NULL + && lxb_url_search_params_compare(node, current->next) >= 0) + { + current = current->next; + } + + node->next = current->next; + + if (current->next != NULL) { + current->next->prev = node; + } + + current->next = node; + node->prev = current; + } + } + + new_root->prev = NULL; + + search_params->first = new_root; + search_params->last = node->next != NULL ? node->next : node; +} + +static size_t +lxb_url_search_params_length(const lexbor_str_t *str) +{ + size_t length; + const lxb_char_t *p, *end; + + p = str->data; + end = p + str->length; + length = str->length; + + while (p < end) { + if (lxb_url_map[*p++] & LXB_URL_MAP_X_WWW_FORM) { + length += 2; + } + } + + return length; +} + +static lxb_char_t * +lxb_url_search_params_to_buf(const lexbor_str_t *str, lxb_char_t *buf) +{ + lxb_char_t c; + const lxb_char_t *p, *end; + + p = str->data; + end = p + str->length; + + while (p < end) { + c = *p; + + if (c == ' ') { + *buf++ = '+'; + } + else if (lxb_url_map[c] & LXB_URL_MAP_X_WWW_FORM) { + *buf++ = '%'; + *buf++ = lexbor_str_res_char_to_two_hex_value[c][0]; + *buf++ = lexbor_str_res_char_to_two_hex_value[c][1]; + } + else { + *buf++ = c; + } + + p += 1; + } + + return buf; +} + +lxb_status_t +lxb_url_search_params_serialize(lxb_url_search_params_t *search_params, + lexbor_callback_f cb, void *ctx) +{ + size_t length; + lxb_status_t status; + lxb_char_t *p, *begin; + lxb_url_search_entry_t *entry; + lxb_char_t buf[1024]; + + entry = search_params->first; + + if (entry == NULL) { + buf[0] = '\0'; + return cb(buf, 0, ctx); + } + + /* Calc length. */ + + length = 0; + + while (entry != NULL) { + length += lxb_url_search_params_length(&entry->name); + length += lxb_url_search_params_length(&entry->value); + length += 2; /* = and & */ + + entry = entry->next; + } + + if (length < sizeof(buf)) { + p = buf; + } + else { + p = lexbor_malloc(length); + if (p == NULL) { + return LXB_STATUS_ERROR_MEMORY_ALLOCATION; + } + } + + /* To buffer. */ + + begin = p; + entry = search_params->first; + + p = lxb_url_search_params_to_buf(&entry->name, p); + *p++ = '='; + p = lxb_url_search_params_to_buf(&entry->value, p); + + entry = entry->next; + + while (entry != NULL) { + *p++ = '&'; + + p = lxb_url_search_params_to_buf(&entry->name, p); + *p++ = '='; + p = lxb_url_search_params_to_buf(&entry->value, p); + + entry = entry->next; + } + + *p = '\0'; + + status = cb(begin, p - begin, ctx); + + if (buf != begin) { + lexbor_free(begin); + } + + return status; +} diff --git a/ext/lexbor/lexbor/url/url.h b/ext/lexbor/lexbor/url/url.h index 58952a0f910b..6cc6f1081c8a 100644 --- a/ext/lexbor/lexbor/url/url.h +++ b/ext/lexbor/lexbor/url/url.h @@ -168,9 +168,35 @@ typedef struct { lexbor_plog_t *log; lxb_unicode_idna_t *idna; + + lxb_char_t *buffer; } lxb_url_parser_t; +/* URLSearchParams */ + +typedef struct lxb_url_search_entry lxb_url_search_entry_t; + +struct lxb_url_search_entry { + lexbor_str_t name; + lexbor_str_t value; + + lxb_url_search_entry_t *next; + lxb_url_search_entry_t *prev; +}; + +typedef struct { + lxb_url_search_entry_t *first; + lxb_url_search_entry_t *last; + lexbor_mraw_t *mraw; + size_t length; +} +lxb_url_search_params_t; + +typedef lexbor_action_t +(*lxb_url_search_params_match_f)(lxb_url_search_params_t *sp, + lxb_url_search_entry_t *entry, void *ctx); + /* * Create lxb_url_parser_t object. @@ -463,7 +489,288 @@ lxb_url_serialize_fragment(const lxb_url_t *url, * @return a new URL object if successful, otherwise NULL value. */ LXB_API lxb_url_t * -lxb_url_clone(lexbor_mraw_t *mraw, lxb_url_t *url); +lxb_url_clone(lexbor_mraw_t *mraw, const lxb_url_t *url); + +/* URLSearchParams */ + +/* + * Initialization of lxb_url_search_params_t object. + * + * Corresponds to the URLSearchParams interface constructor. + * https://url.spec.whatwg.org/#interface-urlsearchparams + * + * @param[in] lexbor_mraw_t *. Not NULL. Can be taken from lxb_url_t. + * @param[in] const lxb_char_t *. Can be NULL. Query. + * @param[in] size_t. Can be 0. Length of query. + * + * @return lxb_url_search_params_t * if successful, otherwise NULL value. + */ +LXB_API lxb_url_search_params_t * +lxb_url_search_params_init(lexbor_mraw_t *mraw, + const lxb_char_t *params, size_t length); + +/* + * Destroy lxb_url_search_params_t object. + * + * Corresponds to the URLSearchParams interface constructor. + * https://url.spec.whatwg.org/#interface-urlsearchparams + * + * @param[in] lxb_url_search_params_t *. Not NULL. + * + * @return NULL value. + */ +LXB_API lxb_url_search_params_t * +lxb_url_search_params_destroy(lxb_url_search_params_t *search_params); + +/* + * Append a specified key/value pair as a new search parameter. + * + * Adds a new key-value pair to the end of the search parameters list. + * If a parameter with this name already exists, creates a duplicate. + * Equivalent to URLSearchParams.prototype.append(). + * https://url.spec.whatwg.org/#dom-urlsearchparams-append + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] name Parameter. Can be NULL. + * @param[in] name_length Length of parameter name. Can be 0. + * @param[in] value Parameter. Must not be NULL. Can be NULL. + * @param[in] Length of parameter value. Can be 0. + * + * @return lxb_url_search_entry_t * if successful, otherwise NULL value. + */ +LXB_API lxb_url_search_entry_t * +lxb_url_search_params_append(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length); + +/* + * Delete search parameters that match a name and value. + * + * Removes all search parameters that match the specified name and value. + * If only name is specified (value == NULL), removes all parameters with + * that name. + * Equivalent to URLSearchParams.prototype.delete(). + * https://url.spec.whatwg.org/#dom-urlsearchparams-delete + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] name Parameter. Must not be NULL. + * @param[in] name_length Length of parameter name. + * @param[in] value Parameter. Can be NULL. + * @param[in] Length of parameter value. Can be 0. + * + * @return void. + */ +LXB_API void +lxb_url_search_params_delete(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length); + +/* + * Get the first entry object associated with the given search parameter name. + * + * Returns the first search parameter entry with the specified name. + * Useful for obtaining both name and value of the parameter. + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Name of the parameter to find. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * + * @return Pointer to found parameter entry or NULL if parameter not found. + */ +LXB_API lxb_url_search_entry_t * +lxb_url_search_params_get_entry(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length); + +/* + * Get the first value associated with the given search parameter name. + * + * Returns the first value associated with the specified search parameter name. + * Equivalent to URLSearchParams.prototype.get(). + * https://url.spec.whatwg.org/#dom-urlsearchparams-get + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Name of the parameter to find. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * + * @return Pointer to string with parameter value or NULL if parameter not found. + */ +LXB_API lexbor_str_t * +lxb_url_search_params_get(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length); + +/* + * Get all values associated with the given search parameter name. + * + * Returns all values associated with the specified search parameter name. + * Fills the provided buffer with pointers to strings. + * Equivalent to URLSearchParams.prototype.getAll(). + * https://url.spec.whatwg.org/#dom-urlsearchparams-getall + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Name of the parameter to find. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * @param[out] Buffer for writing pointers to found strings. Must not be NULL. + * @param[in] Size of output buffer. + * + * @return Number of found values or 0 if parameter not found. + */ +LXB_API size_t +lxb_url_search_params_get_all(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length, + lexbor_str_t **out_buf, size_t out_size); + +/* + * Get the count of values associated with the given search parameter name. + * + * Returns the number of values associated with the specified search parameter + * name. Useful for determining buffer size before calling + * lxb_url_search_params_get_all. + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Name of the parameter to find. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * + * @return Number of found values or 0 if parameter not found. + */ +LXB_API size_t +lxb_url_search_params_get_count(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t length); + +/* + * Find an entry that matches with the specified name and, optionally, value, + * starting from a given entry. + * + * Searches for a parameter entry that matches the specified name and, + * optionally, value, starting the search from the specified position. + * Useful for iterating through duplicate parameters. + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Name of the parameter to find. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * @param[in] Value of the parameter to find. Can be NULL. + * @param[in] Length of parameter value. Can be 0. + * @param[in] Entry to start search from. May be NULL to search from beginning. + * + * @return Pointer to found entry or NULL if no match found. + */ +LXB_API lxb_url_search_entry_t * +lxb_url_search_params_match_entry(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length, + lxb_url_search_entry_t *entry); + +/* + * Check if a search parameter exists. + * + * Checks if a search parameter with the specified name and, optionally, value + * exists. + * If value is specified, checks for existence of specific name-value pair. + * Equivalent to URLSearchParams.prototype.has(). + * https://url.spec.whatwg.org/#dom-urlsearchparams-has + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Name of the parameter to find. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * @param[in] Value to check for. May be NULL to check only name. + * @param[in] Length of parameter value. Can be 0. + * + * @return true if parameter exists, false otherwise. + */ +LXB_API bool +lxb_url_search_params_has(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length); + +/* + * Set the value associated with a given search parameter. + * + * Sets the value for a search parameter with the specified name. + * If parameters with this name already exist, removes them all and creates + * a new one. + * If parameter doesn't exist, creates it. + * Equivalent to URLSearchParams.prototype.set(). + * https://url.spec.whatwg.org/#dom-urlsearchparams-set + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Parameter name to set. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * @param[in] Parameter value to set. Can be NULL. + * @param[in] Length of parameter value. Can be 0. + * + * @return Pointer to created or updated parameter entry or NULL on error. + */ +LXB_API lxb_url_search_entry_t * +lxb_url_search_params_set(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length); + +/* + * Iterate through all search parameters that match a name and, optionally, + * value. + * + * Iterates through all search parameters that match the specified name and, + * optionally, value, calling the callback function for each found parameter. + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Name of the parameter to find. Must not be NULL. + * @param[in] Length of parameter name. Can be 0. + * @param[in] Value to search for. May be NULL to search by name only. + * @param[in] Length of parameter value. Can be 0. + * @param[in] Callback function to process found parameters. Must not be NULL. + * @param[in] User context passed to callback function. Can be NULL. + * + * @return void. + */ +LXB_API void +lxb_url_search_params_match(lxb_url_search_params_t *search_params, + const lxb_char_t *name, size_t name_length, + const lxb_char_t *value, size_t value_length, + lxb_url_search_params_match_f cb, void *ctx); + +/* + * Sort all key/value pairs by their keys. + * + * Sorts all key-value pairs in alphabetical order by keys (parameter names). + * Equivalent to URLSearchParams.prototype.sort(). + * https://url.spec.whatwg.org/#dom-urlsearchparams-sort + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * + * @return void. + */ +LXB_API void +lxb_url_search_params_sort(lxb_url_search_params_t *search_params); + +/* + * Serialize search parameters into a URL query string format. + * + * Converts all search parameters into a properly encoded query string format + * according to the application/x-www-form-urlencoded specification. + * The serialized output is passed to the provided callback function. + * Equivalent to URLSearchParams.prototype.toString(). + * https://url.spec.whatwg.org/#concept-urlencoded-serializer + * + * The callback will be called only once. It will be passed a fully prepared + * string. + * + * @param[in] lxb_url_search_params_t *. Must not be NULL. + * @param[in] Callback function to receive serialized data chunks. Not NULL. + * @param[in] User context passed to callback function. May be NULL. + * + * @return LXB_STATUS_OK on success, error status on failure. + */ +LXB_API lxb_status_t +lxb_url_search_params_serialize(lxb_url_search_params_t *search_params, + lexbor_callback_f cb, void *ctx); + +/** + * Returns whether the URL is special. + * + * @param[in] lxb_url_t *. Cannot be NULL. + * @return true if URL is special, false otherwise. + */ +LXB_API bool +lxb_url_is_special(const lxb_url_t *url); /* * Inline functions. diff --git a/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch b/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch index 0da274053ec2..32d9d42d2bf1 100644 --- a/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch +++ b/ext/lexbor/patches/0001-Expose-line-and-column-information-for-use-in-PHP.patch @@ -1,4 +1,4 @@ -From 4c133fe5adfe4b8ccdd8b014d884b685143b9e66 Mon Sep 17 00:00:00 2001 +From 0cd2add6c46400b808329442f81451b369863983 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:08:59 +0200 Subject: [PATCH 1/6] Expose line and column information for use in PHP @@ -15,10 +15,10 @@ Subject: [PATCH 1/6] Expose line and column information for use in PHP 8 files changed, 48 insertions(+), 5 deletions(-) diff --git a/source/lexbor/dom/interfaces/node.h b/source/lexbor/dom/interfaces/node.h -index b052cf5..b5d2c50 100644 +index 6c74ac5..b95373c 100644 --- a/source/lexbor/dom/interfaces/node.h +++ b/source/lexbor/dom/interfaces/node.h -@@ -83,6 +83,8 @@ struct lxb_dom_node { +@@ -86,6 +86,8 @@ struct lxb_dom_node { lxb_dom_node_type_t type; @@ -41,10 +41,10 @@ index 79accd0..0b7f4fd 100644 const lxb_char_t *text_start; const lxb_char_t *text_end; diff --git a/source/lexbor/html/tokenizer.c b/source/lexbor/html/tokenizer.c -index 741bced..0bd9aec 100644 +index 22b88ed..1d9f378 100644 --- a/source/lexbor/html/tokenizer.c +++ b/source/lexbor/html/tokenizer.c -@@ -91,6 +91,7 @@ lxb_html_tokenizer_init(lxb_html_tokenizer_t *tkz) +@@ -92,6 +92,7 @@ lxb_html_tokenizer_init(lxb_html_tokenizer_t *tkz) tkz->pos = tkz->start; tkz->end = tkz->start + LXB_HTML_TKZ_TEMP_SIZE; @@ -52,7 +52,7 @@ index 741bced..0bd9aec 100644 tkz->tree = NULL; tkz->tags = NULL; -@@ -152,6 +153,8 @@ lxb_html_tokenizer_inherit(lxb_html_tokenizer_t *tkz_to, +@@ -153,6 +154,8 @@ lxb_html_tokenizer_inherit(lxb_html_tokenizer_t *tkz_to, tkz_to->start = tkz_from->start; tkz_to->end = tkz_from->end; tkz_to->pos = tkz_to->start; @@ -61,7 +61,7 @@ index 741bced..0bd9aec 100644 return LXB_STATUS_OK; } -@@ -312,7 +315,26 @@ lxb_html_tokenizer_chunk(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, +@@ -571,7 +574,26 @@ lxb_html_tokenizer_chunk(lxb_html_tokenizer_t *tkz, const lxb_char_t *data, tkz->last = end; while (data < end) { @@ -90,10 +90,10 @@ index 741bced..0bd9aec 100644 return tkz->status; diff --git a/source/lexbor/html/tokenizer.h b/source/lexbor/html/tokenizer.h -index ba9602f..74bb55e 100644 +index 12b7c81..aa1ac37 100644 --- a/source/lexbor/html/tokenizer.h +++ b/source/lexbor/html/tokenizer.h -@@ -73,6 +73,8 @@ struct lxb_html_tokenizer { +@@ -79,6 +79,8 @@ struct lxb_html_tokenizer { const lxb_char_t *end; const lxb_char_t *begin; const lxb_char_t *last; @@ -103,7 +103,7 @@ index ba9602f..74bb55e 100644 /* Entities */ const lexbor_sbst_entry_static_t *entity; diff --git a/source/lexbor/html/tokenizer/state.h b/source/lexbor/html/tokenizer/state.h -index 17939b9..5b095b4 100644 +index 5e91444..52eaa9a 100644 --- a/source/lexbor/html/tokenizer/state.h +++ b/source/lexbor/html/tokenizer/state.h @@ -90,6 +90,8 @@ extern "C" { @@ -116,10 +116,10 @@ index 17939b9..5b095b4 100644 while (0) diff --git a/source/lexbor/html/tree.c b/source/lexbor/html/tree.c -index ece26e9..91bfd17 100644 +index 062ea56..3f4c18d 100644 --- a/source/lexbor/html/tree.c +++ b/source/lexbor/html/tree.c -@@ -427,6 +427,9 @@ lxb_html_tree_create_element_for_token(lxb_html_tree_t *tree, +@@ -431,6 +431,9 @@ lxb_html_tree_create_element_for_token(lxb_html_tree_t *tree, return NULL; } @@ -129,7 +129,7 @@ index ece26e9..91bfd17 100644 lxb_status_t status; lxb_dom_element_t *element = lxb_dom_interface_element(node); -@@ -763,6 +766,11 @@ lxb_html_tree_insert_character_for_data(lxb_html_tree_t *tree, +@@ -767,6 +770,11 @@ lxb_html_tree_insert_character_for_data(lxb_html_tree_t *tree, lxb_dom_interface_text(text)->char_data.data = *str; @@ -141,7 +141,7 @@ index ece26e9..91bfd17 100644 if (ret_node != NULL) { *ret_node = text; } -@@ -802,6 +810,9 @@ lxb_html_tree_insert_comment(lxb_html_tree_t *tree, +@@ -806,6 +814,9 @@ lxb_html_tree_insert_comment(lxb_html_tree_t *tree, return NULL; } @@ -152,10 +152,10 @@ index ece26e9..91bfd17 100644 tree->document->dom_document.text); if (tree->status != LXB_STATUS_OK) { diff --git a/source/lexbor/html/tree/error.c b/source/lexbor/html/tree/error.c -index e6e43f4..88ad8c4 100644 +index ffdc55c..ef36eab 100644 --- a/source/lexbor/html/tree/error.c +++ b/source/lexbor/html/tree/error.c -@@ -21,8 +21,9 @@ lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, +@@ -22,8 +22,9 @@ lxb_html_tree_error_add(lexbor_array_obj_t *parse_errors, } entry->id = id; @@ -168,10 +168,10 @@ index e6e43f4..88ad8c4 100644 return entry; } diff --git a/source/lexbor/html/tree/error.h b/source/lexbor/html/tree/error.h -index 2fd06cb..ed1859f 100644 +index 7a212af..b186772 100644 --- a/source/lexbor/html/tree/error.h +++ b/source/lexbor/html/tree/error.h -@@ -97,8 +97,9 @@ lxb_html_tree_error_id_t; +@@ -109,8 +109,9 @@ lxb_html_tree_error_id_t; typedef struct { lxb_html_tree_error_id_t id; @@ -184,5 +184,5 @@ index 2fd06cb..ed1859f 100644 lxb_html_tree_error_t; -- -2.49.0 +2.51.2 diff --git a/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch b/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch index a2df20e3bae4..1902abf96e3a 100644 --- a/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch +++ b/ext/lexbor/patches/0002-Track-implied-added-nodes-for-options-use-in-PHP.patch @@ -1,4 +1,4 @@ -From eb5e3769950cd9c0bc59066d94d6da9291f43af8 Mon Sep 17 00:00:00 2001 +From a4c29ba8d1ea1065ce6bd4a34382d53140cf1924 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:18:51 +0200 Subject: [PATCH 2/6] Track implied added nodes for options use in PHP @@ -11,7 +11,7 @@ Subject: [PATCH 2/6] Track implied added nodes for options use in PHP 4 files changed, 8 insertions(+) diff --git a/source/lexbor/html/tree.h b/source/lexbor/html/tree.h -index 9564608..8ad32a4 100644 +index 4912efb..7b2c620 100644 --- a/source/lexbor/html/tree.h +++ b/source/lexbor/html/tree.h @@ -55,6 +55,9 @@ struct lxb_html_tree { @@ -63,5 +63,5 @@ index 05fe738..1e09cda 100644 break; -- -2.49.0 +2.51.2 diff --git a/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch b/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch index 4c3cdc67a65d..51f77483bc6e 100644 --- a/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch +++ b/ext/lexbor/patches/0003-Patch-utilities-and-data-structure-to-be-able-to-gen.patch @@ -1,4 +1,4 @@ -From de74c24d95342280266ebdac6f8dabc70ccfacab Mon Sep 17 00:00:00 2001 +From 46fc776449252e74795569759a19d13857a59069 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 24 Aug 2023 22:57:48 +0200 Subject: [PATCH 3/6] Patch utilities and data structure to be able to generate @@ -8,10 +8,10 @@ Changed the generation script to check if everything fits in 32-bits. And change the actual field types to 32-bits. This decreases the hash tables in size. --- - source/lexbor/core/shs.h | 4 +- - utils/lexbor/encoding/single-byte.py | 2 +- - utils/lexbor/lexbor/LXB.py | 12 +- - 3 files changed, 12 insertions(+), 6 deletions(-) + source/lexbor/core/shs.h | 4 ++-- + utils/lexbor/encoding/single-byte.py | 4 ++-- + utils/lexbor/lexbor/LXB.py | 12 +++++++++--- + 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/source/lexbor/core/shs.h b/source/lexbor/core/shs.h index 7a63a07..c84dfaa 100644 @@ -30,7 +30,7 @@ index 7a63a07..c84dfaa 100644 lexbor_shs_hash_t; diff --git a/utils/lexbor/encoding/single-byte.py b/utils/lexbor/encoding/single-byte.py -index 9a85d54..ec2023c 100755 +index d7d1bb2..5420c16 100755 --- a/utils/lexbor/encoding/single-byte.py +++ b/utils/lexbor/encoding/single-byte.py @@ -128,7 +128,7 @@ class SingleByte: @@ -42,6 +42,15 @@ index 9a85d54..ec2023c 100755 return hash_key.create(rate = 1) +@@ -161,7 +161,7 @@ def toHex(s): + lst = [] + + for ch in bytes(s, 'utf-8'): +- hv = hex(ch).replace('0x', '\\\\x') ++ hv = hex(ch).replace('0x', '\\x') + lst.append("'{}'".format(hv)) + + return ', '.join(lst) diff --git a/utils/lexbor/lexbor/LXB.py b/utils/lexbor/lexbor/LXB.py index 3e75812..2370c66 100755 --- a/utils/lexbor/lexbor/LXB.py @@ -84,5 +93,5 @@ index 3e75812..2370c66 100755 result.append("};") -- -2.49.0 +2.51.2 diff --git a/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch b/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch index c678146f2ada..6cb6658a164b 100644 --- a/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch +++ b/ext/lexbor/patches/0004-Remove-unused-upper-case-tag-static-data.patch @@ -1,4 +1,4 @@ -From 1837e6a296a2bac71e37e566435542f208b4fa23 Mon Sep 17 00:00:00 2001 +From ae9d7254ac129cc3be34de6fd34af27baf3bb396 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:26:47 +0100 Subject: [PATCH 4/6] Remove unused upper case tag static data @@ -9,10 +9,10 @@ Subject: [PATCH 4/6] Remove unused upper case tag static data 2 files changed, 4 insertions(+) diff --git a/source/lexbor/tag/res.h b/source/lexbor/tag/res.h -index c7190c5..4ad1f37 100644 +index 604757f..5672d4a 100644 --- a/source/lexbor/tag/res.h +++ b/source/lexbor/tag/res.h -@@ -224,6 +224,7 @@ static const lxb_tag_data_t lxb_tag_res_data_default[LXB_TAG__LAST_ENTRY] = +@@ -226,6 +226,7 @@ static const lxb_tag_data_t lxb_tag_res_data_default[LXB_TAG__LAST_ENTRY] = {{.u.short_str = "xmp", .length = 3, .next = NULL}, LXB_TAG_XMP, 1, true} }; @@ -20,13 +20,13 @@ index c7190c5..4ad1f37 100644 static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] = { {{.u.short_str = "#UNDEF", .length = 6, .next = NULL}, LXB_TAG__UNDEF, 1, true}, -@@ -423,6 +424,7 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] +@@ -427,6 +428,7 @@ static const lxb_tag_data_t lxb_tag_res_data_upper_default[LXB_TAG__LAST_ENTRY] {{.u.short_str = "WBR", .length = 3, .next = NULL}, LXB_TAG_WBR, 1, true}, {{.u.short_str = "XMP", .length = 3, .next = NULL}, LXB_TAG_XMP, 1, true} }; +#endif - static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[] = + static const lexbor_shs_entry_t lxb_tag_res_shs_data_default[263] = { diff --git a/source/lexbor/tag/tag.c b/source/lexbor/tag/tag.c index 780bc47..be5bb30 100644 @@ -49,5 +49,5 @@ index 780bc47..be5bb30 100644 /* * No inline functions for ABI. -- -2.49.0 +2.51.2 diff --git a/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch b/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch index bf2acce1a848..9ef6e305e498 100644 --- a/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch +++ b/ext/lexbor/patches/0005-Shrink-size-of-static-binary-search-tree.patch @@ -1,4 +1,4 @@ -From 065923a993a004b8891ad3992c99e7e63e77bad3 Mon Sep 17 00:00:00 2001 +From 19cf6183813e013dfe0eb2303c15eaf6e01b9faf Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:29:31 +0100 Subject: [PATCH 5/6] Shrink size of static binary search tree @@ -7,10 +7,9 @@ This also makes it more efficient on the data cache. --- source/lexbor/core/sbst.h | 19 ++++++++++++++----- source/lexbor/html/tokenizer/state.c | 2 +- - utils/lexbor/html/tmp/tokenizer_res.h | 2 +- - utils/lexbor/html/tokenizer_entities_bst.py | 10 +++++----- + utils/lexbor/html/tokenizer_entities_bst.py | 8 ++++---- utils/lexbor/lexbor/LXB.py | 2 +- - 5 files changed, 21 insertions(+), 12 deletions(-) + 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/source/lexbor/core/sbst.h b/source/lexbor/core/sbst.h index b0fbc54..15a1d40 100644 @@ -48,10 +47,10 @@ index b0fbc54..15a1d40 100644 lexbor_sbst_entry_static_t; diff --git a/source/lexbor/html/tokenizer/state.c b/source/lexbor/html/tokenizer/state.c -index 158aade..207b909 100644 +index db362c6..6c3cbeb 100644 --- a/source/lexbor/html/tokenizer/state.c +++ b/source/lexbor/html/tokenizer/state.c -@@ -1820,7 +1820,7 @@ lxb_html_tokenizer_state_char_ref_named(lxb_html_tokenizer_t *tkz, +@@ -1825,7 +1825,7 @@ lxb_html_tokenizer_state_char_ref_named(lxb_html_tokenizer_t *tkz, goto done; } @@ -60,21 +59,8 @@ index 158aade..207b909 100644 tkz->entity_end = (tkz->pos + (data - begin)) - tkz->start; tkz->entity_match = entry; } -diff --git a/utils/lexbor/html/tmp/tokenizer_res.h b/utils/lexbor/html/tmp/tokenizer_res.h -index b3701d5..73ab66e 100644 ---- a/utils/lexbor/html/tmp/tokenizer_res.h -+++ b/utils/lexbor/html/tmp/tokenizer_res.h -@@ -6,7 +6,7 @@ - - /* - * Caution!!! Important!!! -- * This file generated by the script -+ * This file is generated by the script - * "utils/lexbor/html/tokenizer_entities_bst.py"! - * Do not change this file! - */ diff --git a/utils/lexbor/html/tokenizer_entities_bst.py b/utils/lexbor/html/tokenizer_entities_bst.py -index 4fa0999..8bd83b2 100755 +index b34bca1..2bfea81 100755 --- a/utils/lexbor/html/tokenizer_entities_bst.py +++ b/utils/lexbor/html/tokenizer_entities_bst.py @@ -1,6 +1,6 @@ @@ -112,15 +98,8 @@ index 4fa0999..8bd83b2 100755 lst.append(hv) return ''.join(lst) -@@ -210,5 +210,5 @@ def entities_bst_print(bst): - - if __name__ == "__main__": - entities_bst("tmp/tokenizer_res.h", -- "../../../source/lexbor/html/tokenizer_res.h", -+ "../../../source/lexbor/html/tokenizer/res.h", - "data/entities.json"); diff --git a/utils/lexbor/lexbor/LXB.py b/utils/lexbor/lexbor/LXB.py -index 3e75812..b068ea3 100755 +index 2370c66..c41e645 100755 --- a/utils/lexbor/lexbor/LXB.py +++ b/utils/lexbor/lexbor/LXB.py @@ -27,7 +27,7 @@ class Temp: @@ -133,5 +112,5 @@ index 3e75812..b068ea3 100755 fh.close() -- -2.49.0 +2.51.2 diff --git a/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch b/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch index aa64d88ceb18..a643f9716488 100644 --- a/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch +++ b/ext/lexbor/patches/0006-Patch-out-unused-CSS-style-code.patch @@ -1,19 +1,17 @@ -From fbb1e8945c4b12d43e7fddc3c34670b5792e2dca Mon Sep 17 00:00:00 2001 +From 54399ee441d922d89c32909e2028f899f6091cd6 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 7 Jan 2024 21:59:28 +0100 Subject: [PATCH 6/6] Patch out unused CSS style code --- - source/lexbor/css/rule.h | 2 ++ - source/lexbor/style/dom/interfaces/document.c | 12 ++++++++---- - source/lexbor/style/html/interfaces/document.h | 2 ++ - 3 files changed, 12 insertions(+), 4 deletions(-) + source/lexbor/css/rule.h | 2 ++ + 1 file changed, 2 insertions(+) diff --git a/source/lexbor/css/rule.h b/source/lexbor/css/rule.h -index 7cc4f0b..bd191f9 100644 +index 308dced..d192a01 100644 --- a/source/lexbor/css/rule.h +++ b/source/lexbor/css/rule.h -@@ -339,6 +339,7 @@ lxb_css_rule_ref_dec(lxb_css_rule_t *rule) +@@ -361,6 +361,7 @@ lxb_css_rule_ref_dec(lxb_css_rule_t *rule) lxb_inline void lxb_css_rule_ref_dec_destroy(lxb_css_rule_t *rule) { @@ -21,7 +19,7 @@ index 7cc4f0b..bd191f9 100644 if (rule->ref_count > 0) { rule->ref_count--; } -@@ -346,6 +347,7 @@ lxb_css_rule_ref_dec_destroy(lxb_css_rule_t *rule) +@@ -368,6 +369,7 @@ lxb_css_rule_ref_dec_destroy(lxb_css_rule_t *rule) if (rule->ref_count == 0) { (void) lxb_css_rule_destroy(rule, true); } @@ -29,96 +27,6 @@ index 7cc4f0b..bd191f9 100644 } lxb_inline void -diff --git a/source/lexbor/style/dom/interfaces/document.c b/source/lexbor/style/dom/interfaces/document.c -index 8a63e8e..f885dc3 100644 ---- a/source/lexbor/style/dom/interfaces/document.c -+++ b/source/lexbor/style/dom/interfaces/document.c -@@ -280,6 +280,7 @@ lxb_status_t - lxb_dom_document_stylesheet_apply(lxb_dom_document_t *document, - lxb_css_stylesheet_t *sst) - { -+#if 0 - lxb_status_t status = LXB_STATUS_OK; - lxb_css_rule_t *rule; - lxb_css_rule_list_t *list; -@@ -310,7 +311,7 @@ lxb_dom_document_stylesheet_apply(lxb_dom_document_t *document, - - rule = rule->next; - } -- -+#endif - return LXB_STATUS_OK; - } - -@@ -329,6 +330,7 @@ lxb_status_t - lxb_dom_document_stylesheet_remove(lxb_dom_document_t *document, - lxb_css_stylesheet_t *sst) - { -+#if 0 - size_t i, length; - lxb_status_t status = LXB_STATUS_OK; - lxb_css_rule_t *rule; -@@ -372,13 +374,14 @@ lxb_dom_document_stylesheet_remove(lxb_dom_document_t *document, - length = lexbor_array_length(document->css->stylesheets); - } - } -- -+#endif - return LXB_STATUS_OK; - } - - lxb_status_t - lxb_dom_document_element_styles_attach(lxb_dom_element_t *element) - { -+#if 0 - lxb_status_t status = LXB_STATUS_OK; - lxb_css_rule_t *rule; - lexbor_array_t *ssts; -@@ -413,7 +416,7 @@ lxb_dom_document_element_styles_attach(lxb_dom_element_t *element) - rule = rule->next; - } - } -- -+#endif - return LXB_STATUS_OK; - } - -@@ -521,6 +524,7 @@ lxb_dom_document_style_attach_cb(lxb_dom_node_t *node, - lxb_status_t - lxb_document_apply_stylesheets(lxb_dom_document_t *document) - { -+#if 0 - size_t i, length; - lxb_status_t status; - lxb_css_stylesheet_t *sst; -@@ -539,6 +543,6 @@ lxb_document_apply_stylesheets(lxb_dom_document_t *document) - return status; - } - } -- -+#endif - return LXB_STATUS_OK; - } -diff --git a/source/lexbor/style/html/interfaces/document.h b/source/lexbor/style/html/interfaces/document.h -index 0307cd9..127c4cd 100644 ---- a/source/lexbor/style/html/interfaces/document.h -+++ b/source/lexbor/style/html/interfaces/document.h -@@ -134,6 +134,7 @@ lxb_html_document_stylesheet_destroy_all(lxb_html_document_t *document, - destroy_memory); - } - -+#if 0 - lxb_inline lxb_status_t - lxb_html_document_style_attach(lxb_html_document_t *document, - lxb_css_rule_style_t *style) -@@ -158,6 +159,7 @@ lxb_html_document_style_attach_by_element(lxb_html_document_t *document, - return lxb_dom_document_style_attach_by_element(lxb_dom_interface_document(document), - element, style); - } -+#endif - - lxb_inline lxb_status_t - lxb_html_document_apply_stylesheets(lxb_html_document_t *document) -- -2.49.0 +2.51.2 diff --git a/ext/lexbor/patches/0007-Add-Is_Special_Url_Support.patch b/ext/lexbor/patches/0007-Add-Is_Special_Url_Support.patch new file mode 100644 index 000000000000..6f5e126336d0 --- /dev/null +++ b/ext/lexbor/patches/0007-Add-Is_Special_Url_Support.patch @@ -0,0 +1,44 @@ +From 9181fce509ab9b37c02994545f3971687433e770 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= +Date: Sun, 17 May 2026 22:17:14 +0200 +Subject: [PATCH] Add lxb_url_is_special() to the public API (#362) + +As https://wiki.php.net/rfc/uri_followup#uri_type_detection relies on this information. +--- + source/lexbor/url/url.c | 2 +- + source/lexbor/url/url.h | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/source/lexbor/url/url.c b/source/lexbor/url/url.c +index 5a114346..a5b323f2 100644 +--- a/source/lexbor/url/url.c ++++ b/source/lexbor/url/url.c +@@ -860,7 +860,7 @@ lxb_url_is_url_codepoint(lxb_codepoint_t cp) + return lxb_url_codepoint_alphanumeric[(lxb_char_t) cp] != 0xFF; + } + +-lxb_inline bool ++bool + lxb_url_is_special(const lxb_url_t *url) + { + return url->scheme.type != LXB_URL_SCHEMEL_TYPE__UNKNOWN; +diff --git a/source/lexbor/url/url.h b/source/lexbor/url/url.h +index 4ed3f32a..6cc6f108 100644 +--- a/source/lexbor/url/url.h ++++ b/source/lexbor/url/url.h +@@ -763,6 +763,15 @@ LXB_API lxb_status_t + lxb_url_search_params_serialize(lxb_url_search_params_t *search_params, + lexbor_callback_f cb, void *ctx); + ++/** ++ * Returns whether the URL is special. ++ * ++ * @param[in] lxb_url_t *. Cannot be NULL. ++ * @return true if URL is special, false otherwise. ++ */ ++LXB_API bool ++lxb_url_is_special(const lxb_url_t *url); ++ + /* + * Inline functions. + */ \ No newline at end of file diff --git a/ext/lexbor/patches/README.md b/ext/lexbor/patches/README.md index 53d58e03da08..6c7b78fd59fa 100644 --- a/ext/lexbor/patches/README.md +++ b/ext/lexbor/patches/README.md @@ -1,7 +1,10 @@ # Lexbor patches +> [!IMPORTANT] +> This process was largely automated in update-lexbor.sh. + Upon syncing the Lexbor sources, the patches in this directory need to be applied. -The current Lexbor version is 2.5.0. +The current Lexbor version is 2.7.0. ## Overview diff --git a/ext/lexbor/patches/update-lexbor.sh b/ext/lexbor/patches/update-lexbor.sh new file mode 100755 index 000000000000..55e330a87644 --- /dev/null +++ b/ext/lexbor/patches/update-lexbor.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +set -e + +PATCHES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LEXBOR_REPO="https://github.com/lexbor/lexbor" +LEXBOR_REF="v2.7.0" +LEXBOR_BASE="$(cd "$PATCHES_DIR/.." && pwd)" +LEXBOR_DIR="$LEXBOR_BASE/lexbor" +LEXBOR_TMP_DIR="$LEXBOR_BASE/lexbor_tmp" +LEXBOR_COMPONENTS=(core css dom encoding html ns ports punycode selectors tag unicode url) + +# Clone +git clone "$LEXBOR_REPO" "$LEXBOR_TMP_DIR" +(cd "$LEXBOR_TMP_DIR" && git checkout "$LEXBOR_REF") + +# Apply patches +mapfile -t patches < <(ls "$PATCHES_DIR"/*.patch) +cd "$LEXBOR_TMP_DIR" +for patch in "${patches[@]}"; do + if ! git am -3 "$patch"; then + read -p "Patch $(basename "$patch") did not apply cleanly. Resolve, stage and press Enter to continue. " + git am --continue + fi +done + +# Refresh patches +NUM_PATCHES=${#patches[@]} +git format-patch "HEAD~$NUM_PATCHES" -o "$PATCHES_DIR" + +# Run code-generation tools +(cd "$LEXBOR_TMP_DIR/utils/lexbor/encoding" && python3 single-byte.py) +(cd "$LEXBOR_TMP_DIR/utils/lexbor/html" && python3 tokenizer_entities_bst.py) + +# (Re)move files +mv source/lexbor/encoding/multi_res.c source/lexbor/encoding/multi.c +mv source/lexbor/encoding/range_res.c source/lexbor/encoding/range.c +mv source/lexbor/encoding/single_res.c source/lexbor/encoding/single.c +rm source/lexbor/html/serialize.c +rm source/lexbor/ports/posix/lexbor/core/fs.c +rm source/lexbor/ports/posix/lexbor/core/perf.c +rm source/lexbor/ports/windows_nt/lexbor/core/fs.c +rm source/lexbor/ports/windows_nt/lexbor/core/perf.c +rm source/lexbor/selectors/selectors.c +rm source/lexbor/selectors/selectors.h +find . -name "*.cmake" -delete + +# Replace components +for dir in "${LEXBOR_COMPONENTS[@]}"; do + dst="$LEXBOR_DIR/$dir" + rm -rf "$dst" + cp -r "source/lexbor/$dir" "$dst" +done +rm -rf "$LEXBOR_TMP_DIR" diff --git a/ext/lexbor/php_lexbor.c b/ext/lexbor/php_lexbor.c index 9421af088422..85f840624402 100644 --- a/ext/lexbor/php_lexbor.c +++ b/ext/lexbor/php_lexbor.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | | Mate Kocsis | @@ -22,6 +20,7 @@ #include "php.h" #include "zend_globals.h" #include "ext/standard/info.h" +#include "lexbor/core/base.h" #include "lexbor/core/types.h" #include "lexbor/core/lexbor.h" @@ -53,7 +52,7 @@ static PHP_MINFO_FUNCTION(lexbor) { php_info_print_table_start(); php_info_print_table_row(2, "Lexbor support", "active"); - php_info_print_table_row(2, "Lexbor version", LEXBOR_VERSION); + php_info_print_table_row(2, "Lexbor version", LEXBOR_VERSION_STRING); php_info_print_table_end(); } @@ -72,7 +71,7 @@ zend_module_entry lexbor_module_entry = { NULL, /* per-request startup function */ NULL, /* per-request shutdown function */ PHP_MINFO(lexbor), /* information function */ - NULL, + PHP_VERSION, STANDARD_MODULE_PROPERTIES }; diff --git a/ext/lexbor/php_lexbor.h b/ext/lexbor/php_lexbor.h index fbdc71746dca..155998388549 100644 --- a/ext/lexbor/php_lexbor.h +++ b/ext/lexbor/php_lexbor.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | | Mate Kocsis | diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 index cc5f284dbc1c..072dd691f214 100644 --- a/ext/libxml/config.w32 +++ b/ext/libxml/config.w32 @@ -5,13 +5,13 @@ ARG_WITH("libxml", "LibXML support", "yes"); if (PHP_LIBXML == "yes") { if (CHECK_LIB("libxml2_a_dll.lib;libxml2_a.lib", "libxml") && ((PHP_ICONV != "no" && !PHP_ICONV_SHARED) || CHECK_LIB("libiconv_a.lib;iconv_a.lib;libiconv.lib;iconv.lib", "libxml")) && - CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2") && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2")) { + CHECK_HEADER("libxml/parser.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2") && + CHECK_HEADER("libxml/tree.h", "CFLAGS_LIBXML", PHP_PHP_BUILD + "\\include\\libxml2")) { if (GREP_HEADER("libxml/xmlversion.h", "#define\\s+LIBXML_VERSION\\s+(\\d+)", PHP_PHP_BUILD + "\\include\\libxml2") && +RegExp.$1 >= 20904) { - EXTENSION("libxml", "libxml.c mime_sniff.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + EXTENSION("libxml", "libxml.c mime_sniff.c image_svg.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_LIBXML", 1, "Define to 1 if the PHP extension 'libxml' is available."); ADD_FLAG("CFLAGS_LIBXML", "/D LIBXML_STATIC /D LIBXML_STATIC_FOR_DLL /D HAVE_WIN32_THREADS "); if (!PHP_LIBXML_SHARED) { diff --git a/ext/libxml/config0.m4 b/ext/libxml/config0.m4 index 67ffa9a78ce4..5b400751d1b5 100644 --- a/ext/libxml/config0.m4 +++ b/ext/libxml/config0.m4 @@ -12,7 +12,7 @@ if test "$PHP_LIBXML" != "no"; then AC_DEFINE([HAVE_LIBXML], [1], [Define to 1 if the PHP extension 'libxml' is available.]) PHP_NEW_EXTENSION([libxml], - [libxml.c mime_sniff.c], + [libxml.c mime_sniff.c image_svg.c], [$ext_shared],, [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_INSTALL_HEADERS([ext/libxml], [php_libxml.h]) diff --git a/ext/libxml/image_svg.c b/ext/libxml/image_svg.c new file mode 100644 index 000000000000..69343fe298b0 --- /dev/null +++ b/ext/libxml/image_svg.c @@ -0,0 +1,176 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Niels Dossche | + +----------------------------------------------------------------------+ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "image_svg.h" +#include "php_libxml.h" + +#include "ext/standard/php_image.h" + +#include + +#ifdef HAVE_LIBXML + +static int svg_image_type_id; + +static int php_libxml_svg_stream_read(void *context, char *buffer, int len) +{ + return php_stream_read(context, buffer, len); +} + +/* Sanity check that the input only contains characters valid for a dimension (numbers with units, e.g. 5cm). + * This also protects the user against injecting XSS. + * Only accept [0-9]+[a-zA-Z]* */ +static bool php_libxml_parse_dimension(const xmlChar *input, const xmlChar **unit_position) +{ + if (!(*input >= '0' && *input <= '9')) { + return false; + } + + input++; + + while (*input) { + if (!(*input >= '0' && *input <= '9')) { + if ((*input >= 'a' && *input <= 'z') || (*input >= 'A' && *input <= 'Z')) { + break; + } + return false; + } + input++; + } + + *unit_position = input; + + while (*input) { + if (!((*input >= 'a' && *input <= 'z') || (*input >= 'A' && *input <= 'Z'))) { + return false; + } + input++; + } + + return true; +} + +zend_result php_libxml_svg_image_handle(php_stream *stream, struct php_gfxinfo **result) +{ + if (php_stream_rewind(stream)) { + return FAILURE; + } + + /* Early check before doing more expensive work */ + if (php_stream_getc(stream) != '<') { + return FAILURE; + } + + if (php_stream_rewind(stream)) { + return FAILURE; + } + + PHP_LIBXML_SANITIZE_GLOBALS(reader_for_stream); + xmlTextReaderPtr reader = xmlReaderForIO( + php_libxml_svg_stream_read, + NULL, + stream, + NULL, + NULL, + XML_PARSE_NOWARNING | XML_PARSE_NOERROR | XML_PARSE_NONET + ); + PHP_LIBXML_RESTORE_GLOBALS(reader_for_stream); + + if (!reader) { + return FAILURE; + } + + bool is_svg = false; + while (xmlTextReaderRead(reader) == 1) { + if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) { + /* Root must be an svg element */ + const xmlChar *name = xmlTextReaderConstLocalName(reader); + if (!name || strcasecmp((const char *) name, "svg") != 0) { + break; + } + + xmlChar *width = xmlTextReaderGetAttribute(reader, BAD_CAST "width"); + xmlChar *height = xmlTextReaderGetAttribute(reader, BAD_CAST "height"); + const xmlChar *width_unit_position, *height_unit_position; + if (!width || !height + || !php_libxml_parse_dimension(width, &width_unit_position) + || !php_libxml_parse_dimension(height, &height_unit_position)) { + xmlFree(width); + xmlFree(height); + break; + } + + is_svg = true; + if (result) { + *result = ecalloc(1, sizeof(**result)); + (*result)->width = ZEND_STRTOL((const char *) width, NULL, 10); + (*result)->height = ZEND_STRTOL((const char *) height, NULL, 10); + if (*width_unit_position) { + (*result)->width_unit = zend_string_init((const char*) width_unit_position, + xmlStrlen(width_unit_position), false); + } + if (*height_unit_position) { + (*result)->height_unit = zend_string_init((const char*) height_unit_position, + xmlStrlen(height_unit_position), false); + } + } + + xmlFree(width); + xmlFree(height); + break; + } + } + + xmlFreeTextReader(reader); + + return is_svg ? SUCCESS : FAILURE; +} + +zend_result php_libxml_svg_image_identify(php_stream *stream) +{ + return php_libxml_svg_image_handle(stream, NULL); +} + +struct php_gfxinfo *php_libxml_svg_image_get_info(php_stream *stream) +{ + struct php_gfxinfo *result = NULL; + zend_result status = php_libxml_svg_image_handle(stream, &result); + ZEND_ASSERT((status == SUCCESS) == (result != NULL)); + return result; +} + +static const struct php_image_handler svg_image_handler = { + "image/svg+xml", + ".svg", + PHP_IMAGE_CONST_NAME("SVG"), + php_libxml_svg_image_identify, + php_libxml_svg_image_get_info, +}; + +void php_libxml_register_image_svg_handler(void) +{ + svg_image_type_id = php_image_register_handler(&svg_image_handler); +} + +zend_result php_libxml_unregister_image_svg_handler(void) +{ + return php_image_unregister_handler(svg_image_type_id); +} + +#endif diff --git a/ext/libxml/image_svg.h b/ext/libxml/image_svg.h new file mode 100644 index 000000000000..b665c2c8d912 --- /dev/null +++ b/ext/libxml/image_svg.h @@ -0,0 +1,23 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Niels Dossche | + +----------------------------------------------------------------------+ + */ + +#ifndef LIBXML_IMAGE_SVG +#define LIBXML_IMAGE_SVG + +#include "zend.h" + +void php_libxml_register_image_svg_handler(void); +zend_result php_libxml_unregister_image_svg_handler(void); + +#endif diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 03a89c7aad51..1f3d7c4d8789 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Shane Caraveo | | Wez Furlong | @@ -35,14 +33,15 @@ #include #include #include -#include #include #ifdef LIBXML_SCHEMAS_ENABLED #include #include +#include #endif #include "php_libxml.h" +#include "image_svg.h" #define PHP_LIBXML_LOADED_VERSION ((char *)xmlParserVersion) @@ -84,8 +83,14 @@ static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDo /* }}} */ +static const zend_module_dep libxml_deps[] = { + ZEND_MOD_REQUIRED("standard") + ZEND_MOD_END +}; + zend_module_entry libxml_module_entry = { - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER_EX, NULL, + libxml_deps, "libxml", /* extension name */ ext_functions, /* extension function list */ PHP_MINIT(libxml), /* extension-wide startup function */ @@ -335,7 +340,26 @@ PHP_LIBXML_API void php_libxml_node_free_list(xmlNodePtr node) if (ptr->_private) { const php_libxml_node_object *obj = ptr->_private; if (!obj->document || obj->document->class_type < PHP_LIBXML_CLASS_MODERN) { - xmlReconciliateNs(curnode->doc, curnode); + if (LIBXML_VERSION < 21300 && UNEXPECTED(curnode->doc == NULL)) { + /* xmlReconciliateNs() in these versions just uses the document for xmlNewReconciledNs(), + * which can create an oldNs xml namespace declaration via xmlSearchNs() -> xmlTreeEnsureXMLDecl(). */ + xmlDoc dummy; + memset(&dummy, 0, sizeof(dummy)); + dummy.type = XML_DOCUMENT_NODE; + curnode->doc = &dummy; + xmlReconciliateNs(curnode->doc, curnode); + curnode->doc = NULL; + + /* Append oldNs to current node's nsDef, which can be at most one node. */ + if (dummy.oldNs) { + ZEND_ASSERT(dummy.oldNs->next == NULL); + xmlNsPtr old = curnode->nsDef; + curnode->nsDef = dummy.oldNs; + dummy.oldNs->next = old; + } + } else { + xmlReconciliateNs(curnode->doc, curnode); + } } } } @@ -499,6 +523,7 @@ static int php_libxml_streams_IO_close(void *context) return php_stream_close((php_stream*)context); } +/* TODO: This needs to be replaced by context-specific APIs in the future! */ static xmlParserInputBufferPtr php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc) { @@ -533,13 +558,10 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc) } /* Allocate the Input buffer front-end. */ - ret = xmlAllocParserInputBuffer(enc); - if (ret != NULL) { - ret->context = context; - ret->readcallback = php_libxml_streams_IO_read; - ret->closecallback = php_libxml_streams_IO_close; - } else + ret = xmlParserInputBufferCreateIO(php_libxml_streams_IO_read, php_libxml_streams_IO_close, context, enc); + if (ret == NULL) { php_libxml_streams_IO_close(context); + } return ret; } @@ -588,11 +610,10 @@ php_libxml_output_buffer_create_filename(const char *URI, } /* Allocate the Output buffer front-end. */ - ret = xmlAllocOutputBuffer(encoder); - if (ret != NULL) { - ret->context = context; - ret->writecallback = php_libxml_streams_IO_write; - ret->closecallback = php_libxml_streams_IO_close; + ret = xmlOutputBufferCreateIO(php_libxml_streams_IO_write, php_libxml_streams_IO_close, context, encoder); + if (ret == NULL) { + php_libxml_streams_IO_close(context); + goto err; } return ret; @@ -779,6 +800,7 @@ static xmlParserInputPtr php_libxml_external_entity_loader(const char *URL, zend_string_release(callable_name); zval_ptr_dtor(&callable); } else { +#if LIBXML_VERSION < 21400 /* TODO: allow storing the encoding in the stream context? */ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; xmlParserInputBufferPtr pib = xmlAllocParserInputBuffer(enc); @@ -788,15 +810,24 @@ static xmlParserInputPtr php_libxml_external_entity_loader(const char *URL, } else { /* make stream not being closed when the zval is freed */ GC_ADDREF(stream->res); + + ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations") pib->context = stream; pib->readcallback = php_libxml_streams_IO_read; pib->closecallback = php_libxml_streams_IO_close; + ZEND_DIAGNOSTIC_IGNORED_END ret = xmlNewIOInputStream(context, pib, enc); if (ret == NULL) { xmlFreeParserInputBuffer(pib); } } +#else + /* make stream not being closed when the zval is freed */ + GC_ADDREF(stream->res); + ret = xmlNewInputFromIO(NULL, php_libxml_streams_IO_read, php_libxml_streams_IO_close, stream, 0); + /* Note: if ret == NULL, the close operation will be executed, so don't DELREF stream->res upon failure! */ +#endif } } else if (Z_TYPE(retval) != IS_NULL) { /* retval not string nor resource nor null; convert to string */ @@ -902,7 +933,16 @@ PHP_LIBXML_API void php_libxml_initialize(void) if (!php_libxml_initialized) { /* we should be the only one's to ever init!! */ ZEND_IGNORE_LEAKS_BEGIN(); + xmlInitParser(); +#ifdef ZTS +# ifdef LIBXML_SCHEMAS_ENABLED + xmlSchemaInitTypes(); +# endif +# ifdef LIBXML_RELAXNG_ENABLED + xmlRelaxNGInitTypes(); +# endif +#endif ZEND_IGNORE_LEAKS_END(); php_libxml_default_entity_loader = xmlGetExternalEntityLoader(); @@ -969,6 +1009,8 @@ static PHP_MINIT_FUNCTION(libxml) xmlOutputBufferCreateFilenameDefault(php_libxml_output_buffer_create_filename); } + php_libxml_register_image_svg_handler(); + return SUCCESS; } @@ -1010,7 +1052,7 @@ static PHP_MSHUTDOWN_FUNCTION(libxml) } php_libxml_shutdown(); - return SUCCESS; + return php_libxml_unregister_image_svg_handler(); } static zend_result php_libxml_post_deactivate(void) diff --git a/ext/libxml/libxml_arginfo.h b/ext/libxml/libxml_arginfo.h index b2eac9399df5..24459da5c0cb 100644 --- a/ext/libxml/libxml_arginfo.h +++ b/ext/libxml/libxml_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit libxml.stub.php instead. * Stub hash: 6dceb619736a3de55b84609a9e3aeb13405bbfde */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_libxml_set_streams_context, 0, 1, IS_VOID, 0) @@ -88,15 +88,10 @@ static void register_libxml_symbols(int module_number) zend_attribute *attribute_Deprecated_func_libxml_disable_entity_loader_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "libxml_disable_entity_loader", sizeof("libxml_disable_entity_loader") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_libxml_disable_entity_loader_0_arg0; - zend_string *attribute_Deprecated_func_libxml_disable_entity_loader_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_libxml_disable_entity_loader_0_arg0, attribute_Deprecated_func_libxml_disable_entity_loader_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_libxml_disable_entity_loader_0->args[0].value, &attribute_Deprecated_func_libxml_disable_entity_loader_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_libxml_disable_entity_loader_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_libxml_disable_entity_loader_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1; zend_string *attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1_str = zend_string_init("as external entity loading is disabled by default", strlen("as external entity loading is disabled by default"), 1); - ZVAL_STR(&attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1, attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_libxml_disable_entity_loader_0->args[1].value, &attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_libxml_disable_entity_loader_0->args[1].value, attribute_Deprecated_func_libxml_disable_entity_loader_0_arg1_str); attribute_Deprecated_func_libxml_disable_entity_loader_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } @@ -109,9 +104,9 @@ static zend_class_entry *register_class_LibXMLError(void) zval property_level_default_value; ZVAL_UNDEF(&property_level_default_value); - zend_string *property_level_name = zend_string_init("level", sizeof("level") - 1, 1); + zend_string *property_level_name = zend_string_init("level", sizeof("level") - 1, true); zend_declare_typed_property(class_entry, property_level_name, &property_level_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_level_name); + zend_string_release_ex(property_level_name, true); zval property_code_default_value; ZVAL_UNDEF(&property_code_default_value); @@ -119,9 +114,9 @@ static zend_class_entry *register_class_LibXMLError(void) zval property_column_default_value; ZVAL_UNDEF(&property_column_default_value); - zend_string *property_column_name = zend_string_init("column", sizeof("column") - 1, 1); + zend_string *property_column_name = zend_string_init("column", sizeof("column") - 1, true); zend_declare_typed_property(class_entry, property_column_name, &property_column_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_column_name); + zend_string_release_ex(property_column_name, true); zval property_message_default_value; ZVAL_UNDEF(&property_message_default_value); diff --git a/ext/libxml/mime_sniff.c b/ext/libxml/mime_sniff.c index 14034f3db267..88c3b2d96451 100644 --- a/ext/libxml/mime_sniff.c +++ b/ext/libxml/mime_sniff.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Niels Dossche | +----------------------------------------------------------------------+ diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h index eb10e7e4cb93..5896f70803f8 100644 --- a/ext/libxml/php_libxml.h +++ b/ext/libxml/php_libxml.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Shane Caraveo | | Wez Furlong | diff --git a/ext/libxml/tests/bug61367-write.phpt b/ext/libxml/tests/bug61367-write.phpt index c65341e1972b..f11f10952204 100644 --- a/ext/libxml/tests/bug61367-write.phpt +++ b/ext/libxml/tests/bug61367-write.phpt @@ -44,5 +44,5 @@ bool(true) Warning: DOMDocument::save(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d -Warning: DOMDocument::save(%s): Failed to open stream: Operation not permitted in %s on line %d +Warning: DOMDocument::save(%s): Failed to open stream: %r(Operation not permitted|Insufficient privileges)%r in %s on line %d bool(false) diff --git a/ext/libxml/tests/image/getimagesize.phpt b/ext/libxml/tests/image/getimagesize.phpt new file mode 100644 index 000000000000..22c099395c3d --- /dev/null +++ b/ext/libxml/tests/image/getimagesize.phpt @@ -0,0 +1,98 @@ +--TEST-- +getimagesize() with svg input +--EXTENSIONS-- +libxml +--FILE-- +", + "svg width=\"1\" height=\"1\"", + << + + +XML, + "", + "", + "", + "", + "", + "", + "", + "", +]; + +foreach ($inputs as $input) { + var_dump(getimagesizefromstring($input)); +} + +?> +--EXPECTF-- +bool(false) +bool(false) +array(6) { + [0]=> + int(4) + [1]=> + int(8) + [2]=> + int(%d) + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "cm" + ["height_unit"]=> + string(2) "cm" +} +array(7) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(%d) + [3]=> + string(20) "width="1" height="1"" + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" +} +array(7) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(%d) + [3]=> + string(20) "width="1" height="1"" + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" +} +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(%d) + ["mime"]=> + string(13) "image/svg+xml" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "mm" +} +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/libxml/tests/image/imagetype_svg.phpt b/ext/libxml/tests/image/imagetype_svg.phpt new file mode 100644 index 000000000000..4115e6a1c895 --- /dev/null +++ b/ext/libxml/tests/image/imagetype_svg.phpt @@ -0,0 +1,16 @@ +--TEST-- +imagetype API with svg extension +--EXTENSIONS-- +libxml +--FILE-- + IMAGETYPE_SVG); +var_dump(image_type_to_extension(IMAGETYPE_SVG)); +var_dump(image_type_to_mime_type(IMAGETYPE_SVG)); + +?> +--EXPECT-- +bool(true) +string(4) ".svg" +string(13) "image/svg+xml" diff --git a/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt b/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt index 7a7754746193..f1ab4fa89063 100644 --- a/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt +++ b/ext/libxml/tests/libxml_entity_loading_disabled_by_default.phpt @@ -30,7 +30,6 @@ function parseXML2($xml) { function parseXML3($xml) { $p = xml_parser_create(); xml_parse_into_struct($p, $xml, $vals, $index); - xml_parser_free($p); return var_export($vals, true); } diff --git a/ext/mbstring/config.w32 b/ext/mbstring/config.w32 index 070d3d73137a..7874da85a25d 100644 --- a/ext/mbstring/config.w32 +++ b/ext/mbstring/config.w32 @@ -5,7 +5,7 @@ ARG_ENABLE("mbregex", "multibyte regex support", "no"); if (PHP_MBSTRING != "no") { - if (CHECK_HEADER_ADD_INCLUDE("mbstring.h", "CFLAGS_MBSTRING", PHP_MBSTRING + ";" + PHP_PHP_BUILD + "\\include")) { + if (CHECK_HEADER("mbstring.h", "CFLAGS_MBSTRING", PHP_MBSTRING + ";" + PHP_PHP_BUILD + "\\include")) { EXTENSION("mbstring", "mbstring.c php_unicode.c mb_gpc.c", PHP_MBSTRING_SHARED); ADD_EXTENSION_DEP('mbstring', 'pcre'); @@ -42,7 +42,7 @@ if (PHP_MBSTRING != "no") { AC_DEFINE('HAVE_MBSTRING', 1, "Define to 1 if the PHP extension 'mbstring' is available."); if (PHP_MBREGEX != "no") { - if (CHECK_HEADER_ADD_INCLUDE("oniguruma.h", "CFLAGS_MBSTRING", PHP_MBREGEX) && + if (CHECK_HEADER("oniguruma.h", "CFLAGS_MBSTRING", PHP_MBREGEX) && CHECK_LIB("onig_a.lib;libonig_a.lib", "mbstring", PHP_MBSTRING)) { AC_DEFINE('HAVE_MBREGEX', 1, 'Define to 1 if mbstring has multibyte regex support enabled.'); diff --git a/ext/mbstring/gen_rare_cp_bitvec.php b/ext/mbstring/gen_rare_cp_bitvec.php index ca1e85cb3d89..6f71fd1a2f83 100755 --- a/ext/mbstring/gen_rare_cp_bitvec.php +++ b/ext/mbstring/gen_rare_cp_bitvec.php @@ -6,7 +6,7 @@ return; } -$bitvec = array_fill(0, (0xFFFF / 32) + 1, 0xFFFFFFFF); +$bitvec = array_fill(0, intdiv(0xFFFF, 32) + 1, 0xFFFFFFFF); $input = file_get_contents($argv[1]); foreach (explode("\n", $input) as $line) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cjk.c b/ext/mbstring/libmbfl/filters/mbfilter_cjk.c index bc14fe48f2cd..83bc34ae1b77 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cjk.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cjk.c @@ -21,15 +21,15 @@ * This macro converts uppercase ASCII values to Regional Indicator codepoints */ #define NFLAGS(c) (0x1F1A5+((unsigned int)(c))) -static const char nflags_s[10][2] = {"CN", "DE", "ES", "FR", "GB", "IT", "JP", "KR", "RU", "US"}; +static const char nflags_s[10][2] ZEND_NONSTRING = {"CN", "DE", "ES", "FR", "GB", "IT", "JP", "KR", "RU", "US"}; static const int nflags_code_kddi[10] = { 0x2549, 0x2546, 0x24C0, 0x2545, 0x2548, 0x2547, 0x2750, 0x254A, 0x24C1, 0x27F7 }; static const int nflags_code_sb[10] = { 0x2B0A, 0x2B05, 0x2B08, 0x2B04, 0x2B07, 0x2B06, 0x2B02, 0x2B0B, 0x2B09, 0x2B03 }; #define EMIT_KEYPAD_EMOJI(c) do { *snd = (c); return 0x20E3; } while(0) #define EMIT_FLAG_EMOJI(country) do { *snd = NFLAGS((country)[0]); return NFLAGS((country)[1]); } while(0) -static const char nflags_kddi[6][2] = {"FR", "DE", "IT", "GB", "CN", "KR"}; -static const char nflags_sb[10][2] = {"JP", "US", "FR", "DE", "IT", "GB", "ES", "RU", "CN", "KR"}; +static const char nflags_kddi[6][2] ZEND_NONSTRING = {"FR", "DE", "IT", "GB", "CN", "KR"}; +static const char nflags_sb[10][2] ZEND_NONSTRING = {"JP", "US", "FR", "DE", "IT", "GB", "ES", "RU", "CN", "KR"}; /* number -> (ku*94)+ten value for telephone keypad character */ #define DOCOMO_KEYPAD(n) ((n) == 0 ? 0x296F : (0x2965 + (n))) @@ -279,7 +279,7 @@ static int mbfl_filt_conv_jis_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -1836,7 +1836,7 @@ static int mbfl_filt_conv_jis2004_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -2528,7 +2528,7 @@ static int mbfl_filt_conv_cp5022x_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -4115,7 +4115,7 @@ static int mbfl_filt_conv_2022kr_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -4720,116 +4720,6 @@ const mbfl_encoding mbfl_encoding_2022kr = { * SJIS variants */ -static int mbfl_filt_conv_sjis_wchar(int c, mbfl_convert_filter *filter) -{ - int s1, s2, w; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* ASCII */ - CK((*filter->output_function)(c, filter->data)); - } else if (c > 0xA0 && c < 0xE0) { /* Kana */ - CK((*filter->output_function)(0xFEC0 + c, filter->data)); - } else if (c > 0x80 && c < 0xF0 && c != 0xA0) { /* Kanji, first byte */ - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* Kanji, second byte */ - filter->status = 0; - int c1 = filter->cache; - if (c >= 0x40 && c <= 0xFC && c != 0x7F) { - SJIS_DECODE(c1, c, s1, s2); - w = (s1 - 0x21)*94 + s2 - 0x21; - if (w >= 0 && w < jisx0208_ucs_table_size) { - w = jisx0208_ucs_table[w]; - if (!w) - w = MBFL_BAD_INPUT; - } else { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - } - - return 0; -} - -static int mbfl_filt_conv_sjis_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status && filter->status != 4) { - (*filter->output_function)(MBFL_BAD_INPUT, filter->data); - } - filter->status = 0; - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_sjis(int c, mbfl_convert_filter *filter) -{ - int c1, c2, s1 = 0, s2; - - if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { - s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; - } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { - s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; - } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { - s1 = ucs_i_jis_table[c - ucs_i_jis_table_min]; - } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { - s1 = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } - if (s1 <= 0) { - if (c == 0xA5) { /* YEN SIGN */ - s1 = 0x216F; /* FULLWIDTH YEN SIGN */ - } else if (c == 0xAF || c == 0x203E) { /* U+00AF is MACRON, U+203E is OVERLINE */ - s1 = 0x2131; /* FULLWIDTH MACRON */ - } else if (c == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ - s1 = 0x2140; - } else if (c == 0x2225) { /* PARALLEL TO */ - s1 = 0x2142; - } else if (c == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ - s1 = 0x215D; - } else if (c == 0xFFE0) { /* FULLWIDTH CENT SIGN */ - s1 = 0x2171; - } else if (c == 0xFFE1) { /* FULLWIDTH POUND SIGN */ - s1 = 0x2172; - } else if (c == 0xFFE2) { /* FULLWIDTH NOT SIGN */ - s1 = 0x224C; - } else if (c == 0) { - s1 = 0; - } else { - s1 = -1; - } - } else if (s1 >= 0x8080) { /* JIS X 0212; not supported */ - s1 = -1; - } - - if (s1 >= 0) { - if (s1 < 0x100) { /* Latin/Kana */ - CK((*filter->output_function)(s1, filter->data)); - } else { /* Kanji */ - c1 = (s1 >> 8) & 0xFF; - c2 = s1 & 0xFF; - SJIS_ENCODE(c1, c2, s1, s2); - CK((*filter->output_function)(s1, filter->data)); - CK((*filter->output_function)(s2, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - static const unsigned short sjis_decode_tbl1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFFFF, 0, 188, 376, 564, 752, 940, 1128, 1316, 1504, 1692, 1880, 2068, 2256, 2444, 2632, 2820, 3008, 3196, 3384, 3572, 3760, 3948, 4136, 4324, 4512, 4700, 4888, 5076, 5264, 5452, 5640, 0xFFFF, -6016, -5828, -5640, -5452, -5264, -5076, -4888, -4700, -4512, -4324, -4136, -3948, -3760, -3572, -3384, -3196, -3008, -2820, -2632, -2444, -2256, -2068, -1880, -1692, -1504, -1316, -1128, -940, -752, -564, -376, -188, 0, 188, 376, 564, 752, 940, 1128, 1316, 1504, 1692, 1880, 2068, 2256, 2444, 2632, 2820, 3008, 3196, 3384, 3572, 3760, 3948, 4136, 4324, 4512, 4700, 4888, 5076, 5264, 5452, 5640, 5828, 6016, 6204, 6392, 6580, 6768, 6956, 7144, 7332, 7520, 7708, 7896, 8084, 8272, 8460, 8648, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }; @@ -4955,1452 +4845,449 @@ static void mb_wchar_to_sjis(uint32_t *in, size_t len, mb_convert_buf *buf, bool MB_CONVERT_BUF_STORE(buf, out, limit); } -static int mbfl_filt_conv_sjis_mac_wchar(int c, mbfl_convert_filter *filter) +static size_t mb_sjismac_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { - int i, j, n; - int c1, s, s1, s2, w; + /* A single SJIS-Mac kuten code can convert to up to 5 Unicode codepoints, oh my! */ + ZEND_ASSERT(bufsize >= 5); - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80 && c != 0x5c) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c > 0xa0 && c < 0xe0) { /* kana */ - CK((*filter->output_function)(0xfec0 + c, filter->data)); - } else if (c > 0x80 && c <= 0xed && c != 0xa0) { /* kanji first char */ - filter->status = 1; - filter->cache = c; - } else if (c == 0x5c) { - CK((*filter->output_function)(0x00a5, filter->data)); - } else if (c == 0x80) { - CK((*filter->output_function)(0x005c, filter->data)); - } else if (c == 0xa0) { - CK((*filter->output_function)(0x00a0, filter->data)); - } else if (c == 0xfd) { - CK((*filter->output_function)(0x00a9, filter->data)); - } else if (c == 0xfe) { - CK((*filter->output_function)(0x2122, filter->data)); - } else if (c == 0xff) { - CK((*filter->output_function)(0x2026, filter->data)); - CK((*filter->output_function)(0xf87f, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; + unsigned char *p = *in, *e = p + *in_len; + uint32_t *out = buf, *limit = buf + bufsize; - case 1: /* kanji second char */ - filter->status = 0; - c1 = filter->cache; - if (c >= 0x40 && c <= 0xfc && c != 0x7f) { - w = 0; - SJIS_DECODE(c1, c, s1, s2); - s = (s1 - 0x21)*94 + s2 - 0x21; - if (s <= 0x89) { - if (s == 0x1c) { - w = 0x2014; /* EM DASH */ - } else if (s == 0x1f) { - w = 0xff3c; /* FULLWIDTH REVERSE SOLIDUS */ - } else if (s == 0x20) { - w = 0x301c; /* FULLWIDTH TILDE */ - } else if (s == 0x21) { - w = 0x2016; /* PARALLEL TO */ - } else if (s == 0x3c) { - w = 0x2212; /* FULLWIDTH HYPHEN-MINUS */ - } else if (s == 0x50) { - w = 0x00a2; /* FULLWIDTH CENT SIGN */ - } else if (s == 0x51) { - w = 0x00a3; /* FULLWIDTH POUND SIGN */ - } else if (s == 0x89) { - w = 0x00ac; /* FULLWIDTH NOT SIGN */ - } - } - - /* apple gaiji area 0x8540 - 0x886d */ - if (w == 0) { - for (i=0; i<7; i++) { - if (s >= code_tbl[i][0] && s <= code_tbl[i][1]) { - w = s - code_tbl[i][0] + code_tbl[i][2]; - break; - } - } - } + while (p < e && out < limit) { + unsigned char c = *p++; - if (w == 0) { + if (c <= 0x80 || c == 0xA0) { + if (c == 0x5C) { + *out++ = 0xA5; + } else if (c == 0x80) { + *out++ = 0x5C; + } else { + *out++ = c; + } + } else if (c >= 0xA1 && c <= 0xDF) { + *out++ = 0xFEC0 + c; + } else if (c <= 0xED) { + if (p == e) { + *out++ = MBFL_BAD_INPUT; + break; + } + unsigned char c2 = *p++; + uint32_t w = sjis_decode_tbl1[c] + sjis_decode_tbl2[c2]; - for (i=0; ioutput_function)(code_tbl_m[i][j], filter->data)); + if (w <= 0x89) { + if (w == 0x1C) { + *out++ = 0x2014; /* EM DASH */ + continue; + } else if (w == 0x1F) { + *out++ = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ + continue; + } else if (w == 0x20) { + *out++ = 0x301C; /* FULLWIDTH TILDE */ + continue; + } else if (w == 0x21) { + *out++ = 0x2016; /* PARALLEL TO */ + continue; + } else if (w == 0x3C) { + *out++ = 0x2212; /* FULLWIDTH HYPHEN-MINUS */ + continue; + } else if (w == 0x50) { + *out++ = 0xA2; /* FULLWIDTH CENT SIGN */ + continue; + } else if (w == 0x51) { + *out++ = 0xA3; /* FULLWIDTH POUND SIGN */ + continue; + } else if (w == 0x89) { + *out++ = 0xAC; /* FULLWIDTH NOT SIGN */ + continue; + } + } else { + if (w >= 0x2F0 && w <= 0x3A3) { + for (int i = 0; i < 7; i++) { + if (w >= code_tbl[i][0] && w <= code_tbl[i][1]) { + *out++ = w - code_tbl[i][0] + code_tbl[i][2]; + goto next_iteration; } - w = code_tbl_m[i][n-1]; - break; } } - } - if (w == 0) { - for (i=0; i<8; i++) { - if (s >= code_ofst_tbl[i][0] && s <= code_ofst_tbl[i][1]) { - w = code_map[i][s - code_ofst_tbl[i][0]]; - if (w == 0) { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - return 0; - } - s2 = 0; - if (s >= 0x043e && s <= 0x0441) { - s2 = 0xf87a; - } else if (s == 0x03b1 || s == 0x03b7) { - s2 = 0xf87f; - } else if (s == 0x04b8 || s == 0x04b9 || s == 0x04c4) { - s2 = 0x20dd; - } else if (s == 0x1ed9 || s == 0x1eda || s == 0x1ee8 || s == 0x1ef3 || - (s >= 0x1ef5 && s <= 0x1efb) || s == 0x1f05 || s == 0x1f06 || - s == 0x1f18 || (s >= 0x1ff2 && s <= 0x20a5)) { - s2 = 0xf87e; + if (w >= 0x340 && w <= 0x523) { + for (int i = 0; i < code_tbl_m_len; i++) { + if (w == code_tbl_m[i][0]) { + int n = 5; + if (code_tbl_m[i][1] == 0xF860) { + n = 3; + } else if (code_tbl_m[i][1] == 0xF861) { + n = 4; + } + if ((limit - out) < n) { + p -= 2; + goto finished; + } + for (int j = 1; j <= n; j++) { + *out++ = code_tbl_m[i][j]; + } + goto next_iteration; } - if (s2 > 0) { - CK((*filter->output_function)(w, filter->data)); - w = s2; + } + } + + if (w >= 0x3AC && w <= 0x20A5) { + for (int i = 0; i < 8; i++) { + if (w >= code_ofst_tbl[i][0] && w <= code_ofst_tbl[i][1]) { + uint32_t w2 = code_map[i][w - code_ofst_tbl[i][0]]; + if (!w2) { + *out++ = MBFL_BAD_INPUT; + goto next_iteration; + } + if ((limit - out) < 2) { + p -= 2; + goto finished; + } + *out++ = w2; + if (w >= 0x43E && w <= 0x441) { + *out++ = 0xF87A; + } else if (w == 0x3B1 || w == 0x3B7) { + *out++ = 0xF87F; + } else if (w == 0x4B8 || w == 0x4B9 || w == 0x4C4) { + *out++ = 0x20DD; + } else if (w == 0x1ED9 || w == 0x1EDA || w == 0x1EE8 || w == 0x1EF3 || (w >= 0x1EF5 && w <= 0x1EFB) || w == 0x1F05 || w == 0x1F06 || w == 0x1F18 || (w >= 0x1FF2 && w <= 0x20A5)) { + *out++ = 0xF87E; + } + goto next_iteration; } - break; } } } - if (w == 0 && s >= 0 && s < jisx0208_ucs_table_size) { /* X 0208 */ - w = jisx0208_ucs_table[s]; + if (w < jisx0208_ucs_table_size) { + w = jisx0208_ucs_table[w]; + if (!w) + w = MBFL_BAD_INPUT; + *out++ = w; + } else { + *out++ = MBFL_BAD_INPUT; } - - if (w <= 0) { - w = MBFL_BAD_INPUT; + } else if (c == 0xFD) { + *out++ = 0xA9; + } else if (c == 0xFE) { + *out++ = 0x2122; + } else if (c == 0xFF) { + if ((limit - out) < 2) { + p--; + break; } - CK((*filter->output_function)(w, filter->data)); + *out++ = 0x2026; + *out++ = 0xF87F; } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); + *out++ = MBFL_BAD_INPUT; } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); +next_iteration: ; } - return 0; +finished: + *in_len = e - p; + *in = p; + return out - buf; } -static int mbfl_filt_conv_wchar_sjis_mac(int c, mbfl_convert_filter *filter) +static bool process_s_form(uint32_t w, uint32_t w2, unsigned int *s) { - int i, c1, c2, s1 = 0, s2 = 0, mode; - - // a1: U+0000 -> U+046F - // a2: U+2000 -> U+30FF - // i: U+4E00 -> U+9FFF - // r: U+FF00 -> U+FFFF - - switch (filter->status) { - case 1: - c1 = filter->cache; - filter->cache = filter->status = 0; - - if (c == 0xf87a) { - for (i = 0; i < 4; i++) { - if (c1 == s_form_tbl[i+34+3+3]) { - s1 = s_form_sjis_tbl[i+34+3+3]; - break; - } - } - if (s1 <= 0) { - s2 = c1; - } - } else if (c == 0x20dd) { - for (i = 0; i < 3; i++) { - if (c1 == s_form_tbl[i+34+3]) { - s1 = s_form_sjis_tbl[i+34+3]; - break; - } - } - if (s1 <= 0) { - s2 = c1; - } - } else if (c == 0xf87f) { - for (i = 0; i < 3; i++) { - if (c1 == s_form_tbl[i+34]) { - s1 = s_form_sjis_tbl[i+34]; - break; - } - } - if (s1 <= 0) { - s2 = c1; - s1 = -1; - } - } else if (c == 0xf87e) { - for (i = 0; i < 34; i++) { - if (c1 == s_form_tbl[i]) { - s1 = s_form_sjis_tbl[i]; - break; - } - } - if (s1 <= 0) { - s2 = c1; - s1 = -1; - } - } else { - s2 = c1; - s1 = c; - } - - if (s2 > 0) { - for (i = 0; i < s_form_tbl_len; i++) { - if (c1 == s_form_tbl[i]) { - s1 = s_form_sjis_fallback_tbl[i]; - break; - } + if (w2 == 0xF87A) { + for (int i = 0; i < 4; i++) { + if (w == s_form_tbl[i+34+3+3]) { + *s = s_form_sjis_tbl[i+34+3+3]; + return true; } } - - if (s1 >= 0) { - if (s1 < 0x100) { - CK((*filter->output_function)(s1, filter->data)); - } else { - CK((*filter->output_function)((s1 >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s1 & 0xff, filter->data)); + } else if (w2 == 0x20DD) { + for (int i = 0; i < 3; i++) { + if (w == s_form_tbl[i+34+3]) { + *s = s_form_sjis_tbl[i+34+3]; + return true; } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - if (s2 <= 0 || s1 == -1) { - break; } - s1 = s2 = 0; - ZEND_FALLTHROUGH; - - case 0: - if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { - s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; - if (c == 0x5c) { - s1 = 0x80; - } else if (c == 0xa9) { - s1 = 0xfd; - } - } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { - s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; - if (c == 0x2122) { - s1 = 0xfe; - } else if (c == 0x2014) { - s1 = 0x213d; - } else if (c == 0x2116) { - s1 = 0x2c1d; - } - } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { - s1 = ucs_i_jis_table[c - ucs_i_jis_table_min]; - } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { - s1 = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } - - if (c >= 0x2000) { - for (i = 0; i < s_form_tbl_len; i++) { - if (c == s_form_tbl[i]) { - filter->status = 1; - filter->cache = c; - return 0; - } - } - - if (c == 0xf860 || c == 0xf861 || c == 0xf862) { - /* Apple 'transcoding hint' codepoints (from private use area) */ - filter->status = 2; - filter->cache = c; - return 0; + } else if (w2 == 0xF87F) { + for (int i = 0; i < 3; i++) { + if (w == s_form_tbl[i+34]) { + *s = s_form_sjis_tbl[i+34]; + return true; } } - - if (s1 <= 0) { - if (c == 0xa0) { - s1 = 0x00a0; - } else if (c == 0xa5) { /* YEN SIGN */ - /* Unicode has codepoint 0xFFE5 for a fullwidth Yen sign; - * convert codepoint 0xA5 to halfwidth Yen sign */ - s1 = 0x5c; /* HALFWIDTH YEN SIGN */ - } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ - s1 = 0x2140; + } else if (w2 == 0xF87E) { + for (int i = 0; i < 34; i++) { + if (w == s_form_tbl[i]) { + *s = s_form_sjis_tbl[i]; + return true; } } + } - if (s1 <= 0) { - for (i=0; i= wchar2sjis_mac_r_tbl[i][0] && c <= wchar2sjis_mac_r_tbl[i][1]) { - s1 = c - wchar2sjis_mac_r_tbl[i][0] + wchar2sjis_mac_r_tbl[i][2]; - break; - } - } - - if (s1 <= 0) { - for (i=0; i= wchar2sjis_mac_r_map[i][0] && c <= wchar2sjis_mac_r_map[i][1]) { - s1 = wchar2sjis_mac_code_map[i][c-wchar2sjis_mac_r_map[i][0]]; - break; - } - } - } - - if (s1 <= 0) { - for (i=0; i 0) { - c1 = s1/94+0x21; - c2 = s1-94*(c1-0x21)+0x21; - s1 = (c1 << 8) | c2; - s2 = 1; - } - } +/* For codepoints F860-F862, which are treated specially in MacJapanese */ +static int transcoding_hint_cp_width[3] = { 3, 4, 5 }; - if ((s1 <= 0) || (s1 >= 0x8080 && s2 == 0)) { /* not found or X 0212 */ - s1 = -1; - c1 = 0; +static void mb_wchar_to_sjismac(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) +{ + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); - if (c == 0) { - s1 = 0; - } else if (s1 <= 0) { - s1 = -1; - } - } + uint32_t w; - if (s1 >= 0) { - if (s1 < 0x100) { /* latin or kana */ - CK((*filter->output_function)(s1, filter->data)); - } else { /* kanji */ - c1 = (s1 >> 8) & 0xff; - c2 = s1 & 0xff; - SJIS_ENCODE(c1, c2, s1, s2); - CK((*filter->output_function)(s1, filter->data)); - CK((*filter->output_function)(s2, filter->data)); - } + if (buf->state) { + w = buf->state & 0xFFFF; + if (buf->state & 0xFF000000L) { + goto resume_transcoding_hint; } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - break; - - case 2: - c1 = filter->cache; - filter->cache = 0; - filter->status = 0; - if (c1 == 0xf860) { - for (i = 0; i < 5; i++) { - if (c == code_tbl_m[i][2]) { - filter->cache = c | 0x10000; - filter->status = 3; - break; - } - } - } else if (c1 == 0xf861) { - for (i = 0; i < 3; i++) { - if (c == code_tbl_m[i+5][2]) { - filter->cache = c | 0x20000; - filter->status = 3; - break; - } - } - } else if (c1 == 0xf862) { - for (i = 0; i < 4; i++) { - if (c == code_tbl_m[i+5+3][2]) { - filter->cache = c | 0x40000; - filter->status = 3; - break; - } - } - } - - if (filter->status == 0) { - /* Didn't find any of expected codepoints after Apple transcoding hint */ - CK(mbfl_filt_conv_illegal_output(c1, filter)); - return mbfl_filt_conv_wchar_sjis_mac(c, filter); + buf->state = 0; + goto process_codepoint; } - break; - - case 3: - s1 = 0; - c1 = filter->cache & 0xffff; - mode = (filter->cache & 0xf0000) >> 16; - - filter->cache = filter->status = 0; + } - if (mode == 0x1) { - for (i = 0; i < 5; i++) { - if (c1 == code_tbl_m[i][2] && c == code_tbl_m[i][3]) { - s1 = code_tbl_m[i][0]; - break; - } - } + while (len--) { + w = *in++; +process_codepoint: ; + unsigned int s = 0; - if (s1 > 0) { - c1 = s1/94+0x21; - c2 = s1-94*(c1-0x21)+0x21; - SJIS_ENCODE(c1, c2, s1, s2); - CK((*filter->output_function)(s1, filter->data)); - CK((*filter->output_function)(s2, filter->data)); + if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { + if (w == 0x5C) { + s = 0x80; + } else if (w == 0xA9) { + s = 0xFD; } else { - CK(mbfl_filt_conv_illegal_output(0xf860, filter)); - CK(mbfl_filt_conv_illegal_output(c1, filter)); - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - } else if (mode == 0x2) { - for (i = 0; i < 3; i++) { - if (c1 == code_tbl_m[i+5][2] && c == code_tbl_m[i+5][3]) { - filter->cache = c | 0x20000; - filter->status = 4; - break; - } + s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; } - } else if (mode == 0x4) { - for (i = 0; i < 4; i++) { - if (c1 == code_tbl_m[i+8][2] && c == code_tbl_m[i+8][3]) { - filter->cache = c | 0x40000; - filter->status = 4; - break; - } + } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { + if (w == 0x2122) { + s = 0xFE; + } else if (w == 0x2014) { + s = 0x213D; + } else if (w == 0x2116) { + s = 0x2C1D; + } else { + s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; } + } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { + s = ucs_i_jis_table[w - ucs_i_jis_table_min]; + } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { + s = ucs_r_jis_table[w - ucs_r_jis_table_min]; } - break; - case 4: - s1 = 0; - c1 = filter->cache & 0xffff; - mode = (filter->cache & 0xf0000) >> 16; - - filter->cache = 0; - filter->status = 0; + if (w >= 0x2000) { + for (int i = 0; i < s_form_tbl_len; i++) { + if (w == s_form_tbl[i]) { + if (!len) { + if (end) { + s = s_form_sjis_fallback_tbl[i]; + if (s) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); + } + } else { + buf->state = w; + } + MB_CONVERT_BUF_STORE(buf, out, limit); + return; + } + uint32_t w2 = *in++; + len--; - if (mode == 0x2) { - for (i = 0; i < 3; i++) { - if (c1 == code_tbl_m[i+5][3] && c == code_tbl_m[i+5][4]) { - s1 = code_tbl_m[i+5][0]; - break; - } - } + if (!process_s_form(w, w2, &s)) { + in--; len++; - if (s1 > 0) { - c1 = s1/94+0x21; - c2 = s1-94*(c1-0x21)+0x21; - SJIS_ENCODE(c1, c2, s1, s2); - CK((*filter->output_function)(s1, filter->data)); - CK((*filter->output_function)(s2, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(0xf861, filter)); - for (i = 0; i < 3; i++) { - if (c1 == code_tbl_m[i+5][3]) { - CK(mbfl_filt_conv_illegal_output(code_tbl_m[i+5][2], filter)); - break; + for (int i = 0; i < s_form_tbl_len; i++) { + if (w == s_form_tbl[i]) { + s = s_form_sjis_fallback_tbl[i]; + break; + } + } } - } - CK(mbfl_filt_conv_illegal_output(c1, filter)); - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - } else if (mode == 0x4) { - for (i = 0; i < 4; i++) { - if (c1 == code_tbl_m[i+8][3] && c == code_tbl_m[i+8][4]) { - filter->cache = c | 0x40000; - filter->status = 5; - break; - } - } - } - break; - - case 5: - s1 = 0; - c1 = filter->cache & 0xffff; - mode = (filter->cache & 0xf0000) >> 16; - filter->cache = filter->status = 0; + if (s <= 0xFF) { + out = mb_convert_buf_add(out, s); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); + } - if (mode == 0x4) { - for (i = 0; i < 4; i++) { - if (c1 == code_tbl_m[i+8][4] && c == code_tbl_m[i+8][5]) { - s1 = code_tbl_m[i+8][0]; - break; + goto next_iteration; } } - if (s1 > 0) { - c1 = s1/94+0x21; - c2 = s1-94*(c1-0x21)+0x21; - SJIS_ENCODE(c1, c2, s1, s2); - CK((*filter->output_function)(s1, filter->data)); - CK((*filter->output_function)(s2, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(0xf862, filter)); - for (i = 0; i < 4; i++) { - if (c1 == code_tbl_m[i+8][4]) { - CK(mbfl_filt_conv_illegal_output( code_tbl_m[i+8][2], filter)); - CK(mbfl_filt_conv_illegal_output( code_tbl_m[i+8][3], filter)); - break; + if (w == 0xF860 || w == 0xF861 || w == 0xF862) { + /* Apple 'transcoding hint' codepoints (from private use area) */ + if (!len) { + if (end) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); + } else { + buf->state = w; } + MB_CONVERT_BUF_STORE(buf, out, limit); + return; } - CK(mbfl_filt_conv_illegal_output(c1, filter)); - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - return 0; -} + uint32_t w2 = *in++; + len--; -static int mbfl_filt_conv_wchar_sjis_mac_flush(mbfl_convert_filter *filter) -{ - int i, c1, s1 = 0; - if (filter->status == 1 && filter->cache > 0) { - c1 = filter->cache; - for (i=0;i 0) { - CK((*filter->output_function)((s1 >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s1 & 0xff, filter->data)); - } - } - filter->cache = 0; - filter->status = 0; + for (int i = 0; i < code_tbl_m_len; i++) { + if (w == code_tbl_m[i][1] && w2 == code_tbl_m[i][2]) { + /* This might be a valid transcoding hint sequence */ + int index = 3; - if (filter->flush_function != NULL) { - return (*filter->flush_function)(filter->data); - } - - return 0; -} - -static size_t mb_sjismac_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) -{ - /* A single SJIS-Mac kuten code can convert to up to 5 Unicode codepoints, oh my! */ - ZEND_ASSERT(bufsize >= 5); - - unsigned char *p = *in, *e = p + *in_len; - uint32_t *out = buf, *limit = buf + bufsize; - - while (p < e && out < limit) { - unsigned char c = *p++; - - if (c <= 0x80 || c == 0xA0) { - if (c == 0x5C) { - *out++ = 0xA5; - } else if (c == 0x80) { - *out++ = 0x5C; - } else { - *out++ = c; - } - } else if (c >= 0xA1 && c <= 0xDF) { - *out++ = 0xFEC0 + c; - } else if (c <= 0xED) { - if (p == e) { - *out++ = MBFL_BAD_INPUT; - break; - } - unsigned char c2 = *p++; - uint32_t w = sjis_decode_tbl1[c] + sjis_decode_tbl2[c2]; - - if (w <= 0x89) { - if (w == 0x1C) { - *out++ = 0x2014; /* EM DASH */ - continue; - } else if (w == 0x1F) { - *out++ = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ - continue; - } else if (w == 0x20) { - *out++ = 0x301C; /* FULLWIDTH TILDE */ - continue; - } else if (w == 0x21) { - *out++ = 0x2016; /* PARALLEL TO */ - continue; - } else if (w == 0x3C) { - *out++ = 0x2212; /* FULLWIDTH HYPHEN-MINUS */ - continue; - } else if (w == 0x50) { - *out++ = 0xA2; /* FULLWIDTH CENT SIGN */ - continue; - } else if (w == 0x51) { - *out++ = 0xA3; /* FULLWIDTH POUND SIGN */ - continue; - } else if (w == 0x89) { - *out++ = 0xAC; /* FULLWIDTH NOT SIGN */ - continue; - } - } else { - if (w >= 0x2F0 && w <= 0x3A3) { - for (int i = 0; i < 7; i++) { - if (w >= code_tbl[i][0] && w <= code_tbl[i][1]) { - *out++ = w - code_tbl[i][0] + code_tbl[i][2]; - goto next_iteration; + if (buf->state) { +resume_transcoding_hint: + i = buf->state >> 24; + index = (buf->state >> 16) & 0xFF; + buf->state = 0; } - } - } - if (w >= 0x340 && w <= 0x523) { - for (int i = 0; i < code_tbl_m_len; i++) { - if (w == code_tbl_m[i][0]) { - int n = 5; - if (code_tbl_m[i][1] == 0xF860) { - n = 3; - } else if (code_tbl_m[i][1] == 0xF861) { - n = 4; - } - if ((limit - out) < n) { - p -= 2; - goto finished; - } - for (int j = 1; j <= n; j++) { - *out++ = code_tbl_m[i][j]; - } - goto next_iteration; - } - } - } + int expected = transcoding_hint_cp_width[w - 0xF860]; - if (w >= 0x3AC && w <= 0x20A5) { - for (int i = 0; i < 8; i++) { - if (w >= code_ofst_tbl[i][0] && w <= code_ofst_tbl[i][1]) { - uint32_t w2 = code_map[i][w - code_ofst_tbl[i][0]]; - if (!w2) { - *out++ = MBFL_BAD_INPUT; - goto next_iteration; - } - if ((limit - out) < 2) { - p -= 2; - goto finished; - } - *out++ = w2; - if (w >= 0x43E && w <= 0x441) { - *out++ = 0xF87A; - } else if (w == 0x3B1 || w == 0x3B7) { - *out++ = 0xF87F; - } else if (w == 0x4B8 || w == 0x4B9 || w == 0x4C4) { - *out++ = 0x20DD; - } else if (w == 0x1ED9 || w == 0x1EDA || w == 0x1EE8 || w == 0x1EF3 || (w >= 0x1EF5 && w <= 0x1EFB) || w == 0x1F05 || w == 0x1F06 || w == 0x1F18 || (w >= 0x1FF2 && w <= 0x20A5)) { - *out++ = 0xF87E; + while (index <= expected) { + if (!len) { + if (end) { + for (int j = 1; j < index; j++) { + MB_CONVERT_ERROR(buf, out, limit, code_tbl_m[i][j], mb_wchar_to_sjismac); + } + } else { + buf->state = (i << 24) | (index << 16) | (w & 0xFFFF); + } + MB_CONVERT_BUF_STORE(buf, out, limit); + return; } - goto next_iteration; - } - } - } - } - - if (w < jisx0208_ucs_table_size) { - w = jisx0208_ucs_table[w]; - if (!w) - w = MBFL_BAD_INPUT; - *out++ = w; - } else { - *out++ = MBFL_BAD_INPUT; - } - } else if (c == 0xFD) { - *out++ = 0xA9; - } else if (c == 0xFE) { - *out++ = 0x2122; - } else if (c == 0xFF) { - if ((limit - out) < 2) { - p--; - break; - } - *out++ = 0x2026; - *out++ = 0xF87F; - } else { - *out++ = MBFL_BAD_INPUT; - } -next_iteration: ; - } - -finished: - *in_len = e - p; - *in = p; - return out - buf; -} - -static bool process_s_form(uint32_t w, uint32_t w2, unsigned int *s) -{ - if (w2 == 0xF87A) { - for (int i = 0; i < 4; i++) { - if (w == s_form_tbl[i+34+3+3]) { - *s = s_form_sjis_tbl[i+34+3+3]; - return true; - } - } - } else if (w2 == 0x20DD) { - for (int i = 0; i < 3; i++) { - if (w == s_form_tbl[i+34+3]) { - *s = s_form_sjis_tbl[i+34+3]; - return true; - } - } - } else if (w2 == 0xF87F) { - for (int i = 0; i < 3; i++) { - if (w == s_form_tbl[i+34]) { - *s = s_form_sjis_tbl[i+34]; - return true; - } - } - } else if (w2 == 0xF87E) { - for (int i = 0; i < 34; i++) { - if (w == s_form_tbl[i]) { - *s = s_form_sjis_tbl[i]; - return true; - } - } - } - - return false; -} - -/* For codepoints F860-F862, which are treated specially in MacJapanese */ -static int transcoding_hint_cp_width[3] = { 3, 4, 5 }; - -static void mb_wchar_to_sjismac(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) -{ - unsigned char *out, *limit; - MB_CONVERT_BUF_LOAD(buf, out, limit); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len); - - uint32_t w; - - if (buf->state) { - w = buf->state & 0xFFFF; - if (buf->state & 0xFF000000L) { - goto resume_transcoding_hint; - } else { - buf->state = 0; - goto process_codepoint; - } - } - - while (len--) { - w = *in++; -process_codepoint: ; - unsigned int s = 0; - - if (w >= ucs_a1_jis_table_min && w < ucs_a1_jis_table_max) { - if (w == 0x5C) { - s = 0x80; - } else if (w == 0xA9) { - s = 0xFD; - } else { - s = ucs_a1_jis_table[w - ucs_a1_jis_table_min]; - } - } else if (w >= ucs_a2_jis_table_min && w < ucs_a2_jis_table_max) { - if (w == 0x2122) { - s = 0xFE; - } else if (w == 0x2014) { - s = 0x213D; - } else if (w == 0x2116) { - s = 0x2C1D; - } else { - s = ucs_a2_jis_table[w - ucs_a2_jis_table_min]; - } - } else if (w >= ucs_i_jis_table_min && w < ucs_i_jis_table_max) { - s = ucs_i_jis_table[w - ucs_i_jis_table_min]; - } else if (w >= ucs_r_jis_table_min && w < ucs_r_jis_table_max) { - s = ucs_r_jis_table[w - ucs_r_jis_table_min]; - } - - if (w >= 0x2000) { - for (int i = 0; i < s_form_tbl_len; i++) { - if (w == s_form_tbl[i]) { - if (!len) { - if (end) { - s = s_form_sjis_fallback_tbl[i]; - if (s) { - MB_CONVERT_BUF_ENSURE(buf, out, limit, 2); - out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); - } else { - MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); - } - } else { - buf->state = w; - } - MB_CONVERT_BUF_STORE(buf, out, limit); - return; - } - uint32_t w2 = *in++; - len--; - - if (!process_s_form(w, w2, &s)) { - in--; len++; - - for (int i = 0; i < s_form_tbl_len; i++) { - if (w == s_form_tbl[i]) { - s = s_form_sjis_fallback_tbl[i]; - break; - } - } - } - - if (s <= 0xFF) { - out = mb_convert_buf_add(out, s); - } else { - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); - out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); - } - - goto next_iteration; - } - } - - if (w == 0xF860 || w == 0xF861 || w == 0xF862) { - /* Apple 'transcoding hint' codepoints (from private use area) */ - if (!len) { - if (end) { - MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); - } else { - buf->state = w; - } - MB_CONVERT_BUF_STORE(buf, out, limit); - return; - } - - uint32_t w2 = *in++; - len--; - - for (int i = 0; i < code_tbl_m_len; i++) { - if (w == code_tbl_m[i][1] && w2 == code_tbl_m[i][2]) { - /* This might be a valid transcoding hint sequence */ - int index = 3; - - if (buf->state) { -resume_transcoding_hint: - i = buf->state >> 24; - index = (buf->state >> 16) & 0xFF; - buf->state = 0; - } - - int expected = transcoding_hint_cp_width[w - 0xF860]; - - while (index <= expected) { - if (!len) { - if (end) { - for (int j = 1; j < index; j++) { - MB_CONVERT_ERROR(buf, out, limit, code_tbl_m[i][j], mb_wchar_to_sjismac); - } - } else { - buf->state = (i << 24) | (index << 16) | (w & 0xFFFF); - } - MB_CONVERT_BUF_STORE(buf, out, limit); - return; - } - - w2 = *in++; - len--; - - if (w2 != code_tbl_m[i][index]) { - /* Didn't match */ - for (int j = 1; j < index; j++) { - MB_CONVERT_ERROR(buf, out, limit, code_tbl_m[i][j], mb_wchar_to_sjismac); - } - MB_CONVERT_ERROR(buf, out, limit, w2, mb_wchar_to_sjismac); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len); - goto next_iteration; - } - - index++; - } - - /* Successful match, emit SJIS-mac bytes */ - s = code_tbl_m[i][0]; - unsigned int c1 = (s / 94) + 0x21, c2 = (s % 94) + 0x21, s1, s2; - SJIS_ENCODE(c1, c2, s1, s2); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); - out = mb_convert_buf_add2(out, s1, s2); - goto next_iteration; - } - } - - /* No valid transcoding hint sequence found */ - in--; len++; - MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len); - continue; - } - } - - if (!s) { - if (w == 0xA0) { - s = 0xA0; - } else if (w == 0xA5) { /* YEN SIGN */ - /* Unicode has codepoint 0xFFE5 for a fullwidth Yen sign; - * convert codepoint 0xA5 to halfwidth Yen sign */ - s = 0x5C; /* HALFWIDTH YEN SIGN */ - } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ - s = 0x2140; - } else { - for (int i = 0; i < wchar2sjis_mac_r_tbl_len; i++) { - if (w >= wchar2sjis_mac_r_tbl[i][0] && w <= wchar2sjis_mac_r_tbl[i][1]) { - s = w - wchar2sjis_mac_r_tbl[i][0] + wchar2sjis_mac_r_tbl[i][2]; - s = (((s / 94) + 0x21) << 8) | ((s % 94) + 0x21); - goto found_kuten_code; - } - } - - for (int i = 0; i < wchar2sjis_mac_r_map_len; i++) { - if (w >= wchar2sjis_mac_r_map[i][0] && w <= wchar2sjis_mac_r_map[i][1]) { - s = wchar2sjis_mac_code_map[i][w - wchar2sjis_mac_r_map[i][0]]; - if (s) { - s = (((s / 94) + 0x21) << 8) | ((s % 94) + 0x21); - goto found_kuten_code; - } - } - } - - for (int i = 0; i < wchar2sjis_mac_wchar_tbl_len; i++) { - if (w == wchar2sjis_mac_wchar_tbl[i][0]) { - s = wchar2sjis_mac_wchar_tbl[i][1]; - s = (((s / 94) + 0x21) << 8) | ((s % 94) + 0x21); - goto found_kuten_code; - } - } - } - } - -found_kuten_code: - if ((!s && w) || s >= 0x8080) { - MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len); - } else if (s <= 0xFF) { - out = mb_convert_buf_add(out, s); - } else { - unsigned int c1 = (s >> 8) & 0xFF, c2 = s & 0xFF, s1, s2; - SJIS_ENCODE(c1, c2, s1, s2); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); - out = mb_convert_buf_add2(out, s1, s2); - } - -next_iteration: ; - } - - MB_CONVERT_BUF_STORE(buf, out, limit); -} - -int mbfilter_sjis_emoji_docomo2unicode(int s, int *snd) -{ - /* All three mobile vendors had emoji for numbers on a telephone keypad - * Unicode doesn't have those, but it has a combining character which puts - * a 'keypad button' around the following character, making it look like - * a key on a telephone or keyboard. That combining char is codepoint 0x20E3. */ - if (s >= mb_tbl_code2uni_docomo1_min && s <= mb_tbl_code2uni_docomo1_max) { - if ((s >= DOCOMO_KEYPAD(1) && s <= DOCOMO_KEYPAD(9)) || s == DOCOMO_KEYPAD(0) || s == DOCOMO_KEYPAD_HASH) { - EMIT_KEYPAD_EMOJI(convert_emoji_cp(mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min])); - } else { - *snd = 0; - return convert_emoji_cp(mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min]); - } - } - return 0; -} - -int mbfilter_sjis_emoji_sb2unicode(int s, int *snd) -{ - if (s >= mb_tbl_code2uni_sb1_min && s <= mb_tbl_code2uni_sb1_max) { - if (s == 0x2817 || (s >= 0x2823 && s <= 0x282C)) { - EMIT_KEYPAD_EMOJI(mb_tbl_code2uni_sb1[s - mb_tbl_code2uni_sb1_min]); - } else { - *snd = 0; - return convert_emoji_cp(mb_tbl_code2uni_sb1[s - mb_tbl_code2uni_sb1_min]); - } - } else if (s >= mb_tbl_code2uni_sb2_min && s <= mb_tbl_code2uni_sb2_max) { - *snd = 0; - return convert_emoji_cp(mb_tbl_code2uni_sb2[s - mb_tbl_code2uni_sb2_min]); - } else if (s >= mb_tbl_code2uni_sb3_min && s <= mb_tbl_code2uni_sb3_max) { - if (s >= 0x2B02 && s <= 0x2B0B) { - EMIT_FLAG_EMOJI(nflags_sb[s - 0x2B02]); - } else { - *snd = 0; - return convert_emoji_cp(mb_tbl_code2uni_sb3[s - mb_tbl_code2uni_sb3_min]); - } - } - return 0; -} - -int mbfilter_unicode2sjis_emoji_docomo(int c, int *s1, mbfl_convert_filter *filter) -{ - /* When converting SJIS-Mobile to Unicode, we convert keypad symbol emoji - * to a sequence of 2 codepoints, one of which is a combining character which - * adds the 'key' image around the other - * - * In the other direction, look for such sequences and convert them to a - * single emoji */ - if (filter->status == 1) { - int c1 = filter->cache; - filter->cache = filter->status = 0; - if (c == 0x20E3) { - if (c1 == '#') { - *s1 = 0x2964; - } else if (c1 == '0') { - *s1 = 0x296F; - } else { /* Previous character was '1'-'9' */ - *s1 = 0x2966 + (c1 - '1'); - } - return 1; - } else { - /* This character wasn't combining character to make keypad symbol, - * so pass the previous character through... and proceed to process the - * current character as usual - * (Single-byte ASCII characters are valid in Shift-JIS...) */ - CK((*filter->output_function)(c1, filter->data)); - } - } - - if (c == '#' || (c >= '0' && c <= '9')) { - filter->status = 1; - filter->cache = c; - return 0; - } - - if (c == 0xA9) { /* Copyright sign */ - *s1 = 0x29B5; - return 1; - } else if (c == 0x00AE) { /* Registered sign */ - *s1 = 0x29BA; - return 1; - } else if (c >= mb_tbl_uni_docomo2code2_min && c <= mb_tbl_uni_docomo2code2_max) { - int i = mbfl_bisec_srch2(c, mb_tbl_uni_docomo2code2_key, mb_tbl_uni_docomo2code2_len); - if (i >= 0) { - *s1 = mb_tbl_uni_docomo2code2_value[i]; - return 1; - } - } else if (c >= mb_tbl_uni_docomo2code3_min && c <= mb_tbl_uni_docomo2code3_max) { - int i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_docomo2code3_key, mb_tbl_uni_docomo2code3_len); - if (i >= 0) { - *s1 = mb_tbl_uni_docomo2code3_value[i]; - return 1; - } - } else if (c >= mb_tbl_uni_docomo2code5_min && c <= mb_tbl_uni_docomo2code5_max) { - int i = mbfl_bisec_srch2(c - 0xF0000, mb_tbl_uni_docomo2code5_key, mb_tbl_uni_docomo2code5_len); - if (i >= 0) { - *s1 = mb_tbl_uni_docomo2code5_val[i]; - return 1; - } - } - return 0; -} - -int mbfilter_unicode2sjis_emoji_kddi_sjis(int c, int *s1, mbfl_convert_filter *filter) -{ - if (filter->status == 1) { - int c1 = filter->cache; - filter->cache = filter->status = 0; - if (c == 0x20E3) { - if (c1 == '#') { - *s1 = 0x25BC; - } else if (c1 == '0') { - *s1 = 0x2830; - } else { /* Previous character was '1'-'9' */ - *s1 = 0x27a6 + (c1 - '1'); - } - return 1; - } else { - CK((*filter->output_function)(c1, filter->data)); - } - } else if (filter->status == 2) { - int c1 = filter->cache; - filter->cache = filter->status = 0; - if (c >= NFLAGS('B') && c <= NFLAGS('U')) { /* B for GB, U for RU */ - for (int i = 0; i < 10; i++) { - if (c1 == NFLAGS(nflags_s[i][0]) && c == NFLAGS(nflags_s[i][1])) { - *s1 = nflags_code_kddi[i]; - return 1; - } - } - } - - /* If none of the KDDI national flag emoji matched, then we have no way - * to convert the previous codepoint... */ - mbfl_filt_conv_illegal_output(c1, filter); - } - - if (c == '#' || (c >= '0' && c <= '9')) { - filter->status = 1; - filter->cache = c; - return 0; - } else if (c >= NFLAGS('C') && c <= NFLAGS('U')) { /* C for CN, U for US */ - filter->status = 2; - filter->cache = c; - return 0; - } - - if (c == 0xA9) { /* Copyright sign */ - *s1 = 0x27DC; - return 1; - } else if (c == 0xAE) { /* Registered sign */ - *s1 = 0x27DD; - return 1; - } else if (c >= mb_tbl_uni_kddi2code2_min && c <= mb_tbl_uni_kddi2code2_max) { - int i = mbfl_bisec_srch2(c, mb_tbl_uni_kddi2code2_key, mb_tbl_uni_kddi2code2_len); - if (i >= 0) { - *s1 = mb_tbl_uni_kddi2code2_value[i]; - return 1; - } - } else if (c >= mb_tbl_uni_kddi2code3_min && c <= mb_tbl_uni_kddi2code3_max) { - int i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_kddi2code3_key, mb_tbl_uni_kddi2code3_len); - if (i >= 0) { - *s1 = mb_tbl_uni_kddi2code3_value[i]; - return 1; - } - } else if (c >= mb_tbl_uni_kddi2code5_min && c <= mb_tbl_uni_kddi2code5_max) { - int i = mbfl_bisec_srch2(c - 0xF0000, mb_tbl_uni_kddi2code5_key, mb_tbl_uni_kddi2code5_len); - if (i >= 0) { - *s1 = mb_tbl_uni_kddi2code5_val[i]; - return 1; - } - } - return 0; -} - -int mbfilter_unicode2sjis_emoji_sb(int c, int *s1, mbfl_convert_filter *filter) -{ - if (filter->status == 1) { - int c1 = filter->cache; - filter->cache = filter->status = 0; - if (c == 0x20E3) { - if (c1 == '#') { - *s1 = 0x2817; - } else if (c1 == '0') { - *s1 = 0x282c; - } else { /* Previous character was '1'-'9' */ - *s1 = 0x2823 + (c1 - '1'); - } - return 1; - } else { - (*filter->output_function)(c1, filter->data); - } - } else if (filter->status == 2) { - int c1 = filter->cache; - filter->cache = filter->status = 0; - if (c >= NFLAGS('B') && c <= NFLAGS('U')) { /* B for GB, U for RU */ - for (int i = 0; i < 10; i++) { - if (c1 == NFLAGS(nflags_s[i][0]) && c == NFLAGS(nflags_s[i][1])) { - *s1 = nflags_code_sb[i]; - return 1; - } - } - } - - /* If none of the SoftBank national flag emoji matched, then we have no way - * to convert the previous codepoint... */ - mbfl_filt_conv_illegal_output(c1, filter); - } - - if (c == '#' || (c >= '0' && c <= '9')) { - filter->status = 1; - filter->cache = c; - return 0; - } else if (c >= NFLAGS('C') && c <= NFLAGS('U')) { /* C for CN, U for US */ - filter->status = 2; - filter->cache = c; - return 0; - } - - if (c == 0xA9) { /* Copyright sign */ - *s1 = 0x2855; - return 1; - } else if (c == 0xAE) { /* Registered sign */ - *s1 = 0x2856; - return 1; - } else if (c >= mb_tbl_uni_sb2code2_min && c <= mb_tbl_uni_sb2code2_max) { - int i = mbfl_bisec_srch2(c, mb_tbl_uni_sb2code2_key, mb_tbl_uni_sb2code2_len); - if (i >= 0) { - *s1 = mb_tbl_uni_sb2code2_value[i]; - return 1; - } - } else if (c >= mb_tbl_uni_sb2code3_min && c <= mb_tbl_uni_sb2code3_max) { - int i = mbfl_bisec_srch2(c - 0x10000, mb_tbl_uni_sb2code3_key, mb_tbl_uni_sb2code3_len); - if (i >= 0) { - *s1 = mb_tbl_uni_sb2code3_value[i]; - return 1; - } - } else if (c >= mb_tbl_uni_sb2code5_min && c <= mb_tbl_uni_sb2code5_max) { - int i = mbfl_bisec_srch2(c - 0xF0000, mb_tbl_uni_sb2code5_key, mb_tbl_uni_sb2code5_len); - if (i >= 0) { - *s1 = mb_tbl_uni_sb2code5_val[i]; - return 1; - } - } - return 0; -} - -static int mbfl_filt_conv_sjis_mobile_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, s, s1, s2, w, snd = 0; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* ASCII */ - if (filter->from == &mbfl_encoding_sjis_sb && c == 0x1B) { - /* ESC; escape sequences were used on older SoftBank phones for emoji */ - filter->cache = c; - filter->status = 2; - } else { - CK((*filter->output_function)(c, filter->data)); - } - } else if (c > 0xA0 && c < 0xE0) { /* Kana */ - CK((*filter->output_function)(0xFEC0 + c, filter->data)); - } else if (c > 0x80 && c < 0xFD && c != 0xA0) { /* Kanji, first byte */ - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* Kanji, second byte */ - filter->status = 0; - c1 = filter->cache; - if (c >= 0x40 && c <= 0xFC && c != 0x7F) { - w = 0; - SJIS_DECODE(c1, c, s1, s2); - s = ((s1 - 0x21) * 94) + s2 - 0x21; - if (s <= 137) { - if (s == 31) { - w = 0xFF3C; /* FULLWIDTH REVERSE SOLIDUS */ - } else if (s == 32) { - w = 0xFF5E; /* FULLWIDTH TILDE */ - } else if (s == 33) { - w = 0x2225; /* PARALLEL TO */ - } else if (s == 60) { - w = 0xFF0D; /* FULLWIDTH HYPHEN-MINUS */ - } else if (s == 80) { - w = 0xFFE0; /* FULLWIDTH CENT SIGN */ - } else if (s == 81) { - w = 0xFFE1; /* FULLWIDTH POUND SIGN */ - } else if (s == 137) { - w = 0xFFE2; /* FULLWIDTH NOT SIGN */ - } - } - if (w == 0) { - if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { /* vendor ext1 (13ku) */ - w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; - } else if (s >= 0 && s < jisx0208_ucs_table_size) { /* X 0208 */ - w = jisx0208_ucs_table[s]; - } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { /* vendor ext2 (89ku - 92ku) */ - w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; - } - - /* Emoji */ - if (filter->from == &mbfl_encoding_sjis_docomo && s >= mb_tbl_code2uni_docomo1_min && s <= mb_tbl_code2uni_docomo1_max) { - w = mbfilter_sjis_emoji_docomo2unicode(s, &snd); - if (snd > 0) { - CK((*filter->output_function)(snd, filter->data)); - } - } else if (filter->from == &mbfl_encoding_sjis_kddi && s >= mb_tbl_code2uni_kddi1_min && s <= mb_tbl_code2uni_kddi2_max) { - w = mbfilter_sjis_emoji_kddi2unicode(s, &snd); - if (snd > 0) { - CK((*filter->output_function)(snd, filter->data)); - } - } else if (filter->from == &mbfl_encoding_sjis_sb && s >= mb_tbl_code2uni_sb1_min && s <= mb_tbl_code2uni_sb3_max) { - w = mbfilter_sjis_emoji_sb2unicode(s, &snd); - if (snd > 0) { - CK((*filter->output_function)(snd, filter->data)); - } - } - - if (w == 0) { - if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { /* vendor ext3 (115ku - 119ku) */ - w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; - } else if (s >= (94*94) && s < (114*94)) { /* user (95ku - 114ku) */ - w = s - (94*94) + 0xe000; - } - } - } - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - /* ESC: Softbank Emoji */ - case 2: - if (c == '$') { - filter->cache = c; - filter->status++; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - filter->status = filter->cache = 0; - } - break; - - /* ESC $: Softbank Emoji */ - case 3: - if ((c >= 'E' && c <= 'G') || (c >= 'O' && c <= 'Q')) { - filter->cache = c; - filter->status++; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - filter->status = filter->cache = 0; - } - break; - - /* ESC $ [GEFOPQ]: Softbank Emoji */ - case 4: - c1 = filter->cache; - if (c == 0xF) { /* Terminate sequence of emoji */ - filter->status = filter->cache = 0; - return 0; - } else { - if (c1 == 'G' && c >= 0x21 && c <= 0x7a) { - s1 = (0x91 - 0x21) * 94; - } else if (c1 == 'E' && c >= 0x21 && c <= 0x7A) { - s1 = (0x8D - 0x21) * 94; - } else if (c1 == 'F' && c >= 0x21 && c <= 0x7A) { - s1 = (0x8E - 0x21) * 94; - } else if (c1 == 'O' && c >= 0x21 && c <= 0x6D) { - s1 = (0x92 - 0x21) * 94; - } else if (c1 == 'P' && c >= 0x21 && c <= 0x6C) { - s1 = (0x95 - 0x21) * 94; - } else if (c1 == 'Q' && c >= 0x21 && c <= 0x5E) { - s1 = (0x96 - 0x21) * 94; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - filter->status = filter->cache = 0; - return 0; - } - - w = mbfilter_sjis_emoji_sb2unicode(s1 + c - 0x21, &snd); - if (w > 0) { - if (snd > 0) { - CK((*filter->output_function)(snd, filter->data)); - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - filter->status = filter->cache = 0; - } - } - } - - return 0; -} - -static int mbfl_filt_conv_wchar_sjis_mobile(int c, mbfl_convert_filter *filter) -{ - int c1, c2, s1 = 0, s2 = 0; - - if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { - s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; - } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { - s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; - } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { - s1 = ucs_i_jis_table[c - ucs_i_jis_table_min]; - } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { - s1 = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } else if (c >= 0xE000 && c < (0xE000 + 20*94)) { - /* Private User Area (95ku - 114ku) */ - s1 = c - 0xE000; - c1 = (s1 / 94) + 0x7F; - c2 = (s1 % 94) + 0x21; - s1 = (c1 << 8) | c2; - s2 = 1; - } - - if (s1 <= 0) { - if (c == 0xA5) { /* YEN SIGN */ - s1 = 0x216F; /* FULLWIDTH YEN SIGN */ - } else if (c == 0xFF3c) { /* FULLWIDTH REVERSE SOLIDUS */ - s1 = 0x2140; - } else if (c == 0x2225) { /* PARALLEL TO */ - s1 = 0x2142; - } else if (c == 0xFF0D) { /* FULLWIDTH HYPHEN-MINUS */ - s1 = 0x215D; - } else if (c == 0xFFE0) { /* FULLWIDTH CENT SIGN */ - s1 = 0x2171; - } else if (c == 0xFFE1) { /* FULLWIDTH POUND SIGN */ - s1 = 0x2172; - } else if (c == 0xFFE2) { /* FULLWIDTH NOT SIGN */ - s1 = 0x224C; - } - } - if ((s1 <= 0) || (s1 >= 0x8080 && s2 == 0)) { /* not found or X 0212 */ - s1 = -1; + w2 = *in++; + len--; - /* CP932 vendor ext1 (13ku) */ - for (c1 = 0; c1 < cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; c1++) { - if (c == cp932ext1_ucs_table[c1]) { - s1 = (((c1 / 94) + 0x2D) << 8) + (c1 % 94) + 0x21; - break; + if (w2 != code_tbl_m[i][index]) { + /* Didn't match */ + for (int j = 1; j < index; j++) { + MB_CONVERT_ERROR(buf, out, limit, code_tbl_m[i][j], mb_wchar_to_sjismac); + } + MB_CONVERT_ERROR(buf, out, limit, w2, mb_wchar_to_sjismac); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + goto next_iteration; + } + + index++; + } + + /* Successful match, emit SJIS-mac bytes */ + s = code_tbl_m[i][0]; + unsigned int c1 = (s / 94) + 0x21, c2 = (s % 94) + 0x21, s1, s2; + SJIS_ENCODE(c1, c2, s1, s2); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, s1, s2); + goto next_iteration; + } + } + + /* No valid transcoding hint sequence found */ + in--; len++; + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + continue; } } - if (s1 <= 0) { - /* CP932 vendor ext2 (115ku - 119ku) */ - for (c1 = 0; c1 < cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; c1++) { - if (c == cp932ext2_ucs_table[c1]) { - s1 = (((c1 / 94) + 0x79) << 8) + (c1 % 94) + 0x21; - break; + if (!s) { + if (w == 0xA0) { + s = 0xA0; + } else if (w == 0xA5) { /* YEN SIGN */ + /* Unicode has codepoint 0xFFE5 for a fullwidth Yen sign; + * convert codepoint 0xA5 to halfwidth Yen sign */ + s = 0x5C; /* HALFWIDTH YEN SIGN */ + } else if (w == 0xFF3C) { /* FULLWIDTH REVERSE SOLIDUS */ + s = 0x2140; + } else { + for (int i = 0; i < wchar2sjis_mac_r_tbl_len; i++) { + if (w >= wchar2sjis_mac_r_tbl[i][0] && w <= wchar2sjis_mac_r_tbl[i][1]) { + s = w - wchar2sjis_mac_r_tbl[i][0] + wchar2sjis_mac_r_tbl[i][2]; + s = (((s / 94) + 0x21) << 8) | ((s % 94) + 0x21); + goto found_kuten_code; + } + } + + for (int i = 0; i < wchar2sjis_mac_r_map_len; i++) { + if (w >= wchar2sjis_mac_r_map[i][0] && w <= wchar2sjis_mac_r_map[i][1]) { + s = wchar2sjis_mac_code_map[i][w - wchar2sjis_mac_r_map[i][0]]; + if (s) { + s = (((s / 94) + 0x21) << 8) | ((s % 94) + 0x21); + goto found_kuten_code; + } + } + } + + for (int i = 0; i < wchar2sjis_mac_wchar_tbl_len; i++) { + if (w == wchar2sjis_mac_wchar_tbl[i][0]) { + s = wchar2sjis_mac_wchar_tbl[i][1]; + s = (((s / 94) + 0x21) << 8) | ((s % 94) + 0x21); + goto found_kuten_code; + } } } } - if (c == 0) { - s1 = 0; +found_kuten_code: + if ((!s && w) || s >= 0x8080) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_sjismac); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } else if (s <= 0xFF) { + out = mb_convert_buf_add(out, s); + } else { + unsigned int c1 = (s >> 8) & 0xFF, c2 = s & 0xFF, s1, s2; + SJIS_ENCODE(c1, c2, s1, s2); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, s1, s2); } - } - if ((filter->to == &mbfl_encoding_sjis_docomo && mbfilter_unicode2sjis_emoji_docomo(c, &s1, filter)) || - (filter->to == &mbfl_encoding_sjis_kddi && mbfilter_unicode2sjis_emoji_kddi_sjis(c, &s1, filter)) || - (filter->to == &mbfl_encoding_sjis_sb && mbfilter_unicode2sjis_emoji_sb(c, &s1, filter))) { - s1 = (((s1 / 94) + 0x21) << 8) | ((s1 % 94) + 0x21); +next_iteration: ; } - if (filter->status) { - return 0; - } + MB_CONVERT_BUF_STORE(buf, out, limit); +} - if (s1 >= 0) { - if (s1 < 0x100) { /* Latin/Kana */ - CK((*filter->output_function)(s1, filter->data)); - } else { /* Kanji */ - c1 = (s1 >> 8) & 0xff; - c2 = s1 & 0xff; - SJIS_ENCODE(c1, c2, s1, s2); - CK((*filter->output_function)(s1, filter->data)); - CK((*filter->output_function)(s2, filter->data)); +int mbfilter_sjis_emoji_docomo2unicode(int s, int *snd) +{ + /* All three mobile vendors had emoji for numbers on a telephone keypad + * Unicode doesn't have those, but it has a combining character which puts + * a 'keypad button' around the following character, making it look like + * a key on a telephone or keyboard. That combining char is codepoint 0x20E3. */ + if (s >= mb_tbl_code2uni_docomo1_min && s <= mb_tbl_code2uni_docomo1_max) { + if ((s >= DOCOMO_KEYPAD(1) && s <= DOCOMO_KEYPAD(9)) || s == DOCOMO_KEYPAD(0) || s == DOCOMO_KEYPAD_HASH) { + EMIT_KEYPAD_EMOJI(convert_emoji_cp(mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min])); + } else { + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_docomo1[s - mb_tbl_code2uni_docomo1_min]); } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); } - return 0; } -int mbfl_filt_conv_sjis_mobile_flush(mbfl_convert_filter *filter) +int mbfilter_sjis_emoji_sb2unicode(int s, int *snd) { - int c1 = filter->cache; - if (filter->status == 1 && (c1 == '#' || (c1 >= '0' && c1 <= '9'))) { - filter->cache = filter->status = 0; - CK((*filter->output_function)(c1, filter->data)); - } else if (filter->status == 2) { - /* First of a pair of Regional Indicator codepoints came at the end of a string */ - filter->cache = filter->status = 0; - mbfl_filt_conv_illegal_output(c1, filter); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); + if (s >= mb_tbl_code2uni_sb1_min && s <= mb_tbl_code2uni_sb1_max) { + if (s == 0x2817 || (s >= 0x2823 && s <= 0x282C)) { + EMIT_KEYPAD_EMOJI(mb_tbl_code2uni_sb1[s - mb_tbl_code2uni_sb1_min]); + } else { + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_sb1[s - mb_tbl_code2uni_sb1_min]); + } + } else if (s >= mb_tbl_code2uni_sb2_min && s <= mb_tbl_code2uni_sb2_max) { + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_sb2[s - mb_tbl_code2uni_sb2_min]); + } else if (s >= mb_tbl_code2uni_sb3_min && s <= mb_tbl_code2uni_sb3_max) { + if (s >= 0x2B02 && s <= 0x2B0B) { + EMIT_FLAG_EMOJI(nflags_sb[s - 0x2B02]); + } else { + *snd = 0; + return convert_emoji_cp(mb_tbl_code2uni_sb3[s - mb_tbl_code2uni_sb3_min]); + } } - return 0; } @@ -7345,198 +6232,13 @@ process_codepoint: ; out = mb_convert_buf_add(out, s); } else { unsigned int c1 = (s >> 8) & 0xFF, c2 = s & 0xFF, s1, s2; - SJIS_ENCODE(c1, c2, s1, s2); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); - out = mb_convert_buf_add2(out, s1, s2); - } - } - - MB_CONVERT_BUF_STORE(buf, out, limit); -} - -static int mbfl_filt_conv_cp932_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, s, s1, s2, w; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c > 0xa0 && c < 0xe0) { /* kana */ - CK((*filter->output_function)(0xfec0 + c, filter->data)); - } else if (c > 0x80 && c < 0xfd && c != 0xa0) { /* kanji first char */ - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* kanji second char */ - filter->status = 0; - c1 = filter->cache; - if (c >= 0x40 && c <= 0xfc && c != 0x7f) { - w = 0; - SJIS_DECODE(c1, c, s1, s2); - s = (s1 - 0x21)*94 + s2 - 0x21; - if (s <= 137) { - if (s == 31) { - w = 0xff3c; /* FULLWIDTH REVERSE SOLIDUS */ - } else if (s == 32) { - w = 0xff5e; /* FULLWIDTH TILDE */ - } else if (s == 33) { - w = 0x2225; /* PARALLEL TO */ - } else if (s == 60) { - w = 0xff0d; /* FULLWIDTH HYPHEN-MINUS */ - } else if (s == 80) { - w = 0xffe0; /* FULLWIDTH CENT SIGN */ - } else if (s == 81) { - w = 0xffe1; /* FULLWIDTH POUND SIGN */ - } else if (s == 137) { - w = 0xffe2; /* FULLWIDTH NOT SIGN */ - } - } - if (w == 0) { - if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { /* vendor ext1 (13ku) */ - w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; - } else if (s >= 0 && s < jisx0208_ucs_table_size) { /* X 0208 */ - w = jisx0208_ucs_table[s]; - } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { /* vendor ext2 (89ku - 92ku) */ - w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; - } else if (s >= cp932ext3_ucs_table_min && s < cp932ext3_ucs_table_max) { /* vendor ext3 (115ku - 119ku) */ - w = cp932ext3_ucs_table[s - cp932ext3_ucs_table_min]; - } else if (s >= (94*94) && s < (114*94)) { /* user (95ku - 114ku) */ - w = s - (94*94) + 0xe000; - } - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_cp932_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - (*filter->output_function)(MBFL_BAD_INPUT, filter->data); - filter->status = 0; - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_cp932(int c, mbfl_convert_filter *filter) -{ - int c1, c2, s1, s2; - - s1 = 0; - s2 = 0; - if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { - s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; - } else if (c == 0x203E) { - s1 = 0x7E; - } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { - s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; - } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { - s1 = ucs_i_jis_table[c - ucs_i_jis_table_min]; - } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { - s1 = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } else if (c >= 0xe000 && c < (0xe000 + 20*94)) { /* user (95ku - 114ku) */ - s1 = c - 0xe000; - c1 = s1/94 + 0x7f; - c2 = s1%94 + 0x21; - s1 = (c1 << 8) | c2; - s2 = 1; - } - if (s1 <= 0) { - if (c == 0xa5) { /* YEN SIGN */ - s1 = 0x5C; - } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ - s1 = 0x2140; - } else if (c == 0x2225) { /* PARALLEL TO */ - s1 = 0x2142; - } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ - s1 = 0x215d; - } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ - s1 = 0x2171; - } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ - s1 = 0x2172; - } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ - s1 = 0x224c; - } - } - if ((s1 <= 0) || (s1 >= 0x8080 && s2 == 0)) { /* not found or X 0212 */ - s1 = -1; - c1 = 0; - c2 = cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext1 (13ku) */ - if (c == cp932ext1_ucs_table[c1]) { - s1 = ((c1/94 + 0x2d) << 8) + (c1%94 + 0x21); - break; - } - c1++; - } - if (s1 <= 0) { - c1 = 0; - c2 = cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext3 (115ku - 119ku) */ - if (c == cp932ext3_ucs_table[c1]) { - s1 = ((c1/94 + 0x93) << 8) + (c1%94 + 0x21); - break; - } - c1++; - } - } - if (c == 0) { - s1 = 0; - } else if (s1 <= 0) { - s1 = -1; - } - } - if (s1 >= 0) { - if (s1 < 0x100) { /* latin or kana */ - CK((*filter->output_function)(s1, filter->data)); - } else { /* kanji */ - c1 = (s1 >> 8) & 0xff; - c2 = s1 & 0xff; - SJIS_ENCODE(c1, c2, s1, s2); - CK((*filter->output_function)(s1, filter->data)); - CK((*filter->output_function)(s2, filter->data)); + SJIS_ENCODE(c1, c2, s1, s2); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, s1, s2); } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); } - return 0; -} - -static int mbfl_filt_conv_wchar_sjiswin(int c, mbfl_convert_filter *filter) -{ - if (c == 0xA5) { - CK((*filter->output_function)(0x81, filter->data)); - CK((*filter->output_function)(0x8F, filter->data)); - } else if (c == 0x203E) { - CK((*filter->output_function)(0x81, filter->data)); - CK((*filter->output_function)(0x50, filter->data)); - } else { - return mbfl_filt_conv_wchar_cp932(c, filter); - } - return 0; + MB_CONVERT_BUF_STORE(buf, out, limit); } static size_t mb_cp932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) @@ -7823,26 +6525,6 @@ static const unsigned char mblen_table_sjis_mobile[] = { /* 0x81-0x9F,0xE0-0xFC static const char *mbfl_encoding_sjis_aliases[] = {"x-sjis", "SHIFT-JIS", NULL}; -static const struct mbfl_convert_vtbl vtbl_sjis_wchar = { - mbfl_no_encoding_sjis, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_sjis_wchar, - mbfl_filt_conv_sjis_wchar_flush, - NULL -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_sjis = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_sjis, - mbfl_filt_conv_common_flush, - NULL -}; - const mbfl_encoding mbfl_encoding_sjis = { mbfl_no_encoding_sjis, "SJIS", @@ -7850,8 +6532,8 @@ const mbfl_encoding mbfl_encoding_sjis = { mbfl_encoding_sjis_aliases, mblen_table_sjis, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_sjis_wchar, - &vtbl_wchar_sjis, + NULL, + NULL, mb_sjis_to_wchar, mb_wchar_to_sjis, NULL, @@ -7860,26 +6542,6 @@ const mbfl_encoding mbfl_encoding_sjis = { static const char *mbfl_encoding_sjis_mac_aliases[] = {"MacJapanese", "x-Mac-Japanese", NULL}; -static const struct mbfl_convert_vtbl vtbl_sjis_mac_wchar = { - mbfl_no_encoding_sjis_mac, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_sjis_mac_wchar, - mbfl_filt_conv_sjis_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_sjis_mac = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis_mac, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_sjis_mac, - mbfl_filt_conv_wchar_sjis_mac_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_sjis_mac = { mbfl_no_encoding_sjis_mac, "SJIS-mac", @@ -7887,8 +6549,8 @@ const mbfl_encoding mbfl_encoding_sjis_mac = { mbfl_encoding_sjis_mac_aliases, mblen_table_sjismac, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_sjis_mac_wchar, - &vtbl_wchar_sjis_mac, + NULL, + NULL, mb_sjismac_to_wchar, mb_wchar_to_sjismac, NULL, @@ -7899,26 +6561,6 @@ static const char *mbfl_encoding_sjis_docomo_aliases[] = {"SJIS-DOCOMO", "shift_ static const char *mbfl_encoding_sjis_kddi_aliases[] = {"SJIS-KDDI", "shift_jis-kddi", "x-sjis-emoji-kddi", NULL}; static const char *mbfl_encoding_sjis_sb_aliases[] = {"SJIS-SOFTBANK", "shift_jis-softbank", "x-sjis-emoji-softbank", NULL}; -static const struct mbfl_convert_vtbl vtbl_sjis_docomo_wchar = { - mbfl_no_encoding_sjis_docomo, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_sjis_mobile_wchar, - mbfl_filt_conv_sjis_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_sjis_docomo = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis_docomo, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_sjis_mobile, - mbfl_filt_conv_sjis_mobile_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_sjis_docomo = { mbfl_no_encoding_sjis_docomo, "SJIS-Mobile#DOCOMO", @@ -7926,31 +6568,11 @@ const mbfl_encoding mbfl_encoding_sjis_docomo = { mbfl_encoding_sjis_docomo_aliases, mblen_table_sjis_mobile, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_sjis_docomo_wchar, - &vtbl_wchar_sjis_docomo, - mb_sjis_docomo_to_wchar, - mb_wchar_to_sjis_docomo, - NULL, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_sjis_kddi_wchar = { - mbfl_no_encoding_sjis_kddi, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, NULL, - mbfl_filt_conv_sjis_mobile_wchar, - mbfl_filt_conv_sjis_wchar_flush, NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_sjis_kddi = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis_kddi, - mbfl_filt_conv_common_ctor, + mb_sjis_docomo_to_wchar, + mb_wchar_to_sjis_docomo, NULL, - mbfl_filt_conv_wchar_sjis_mobile, - mbfl_filt_conv_sjis_mobile_flush, NULL, }; @@ -7961,31 +6583,11 @@ const mbfl_encoding mbfl_encoding_sjis_kddi = { mbfl_encoding_sjis_kddi_aliases, mblen_table_sjis_mobile, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_sjis_kddi_wchar, - &vtbl_wchar_sjis_kddi, - mb_sjis_kddi_to_wchar, - mb_wchar_to_sjis_kddi, - NULL, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_sjis_sb_wchar = { - mbfl_no_encoding_sjis_sb, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, NULL, - mbfl_filt_conv_sjis_mobile_wchar, - mbfl_filt_conv_sjis_wchar_flush, NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_sjis_sb = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis_sb, - mbfl_filt_conv_common_ctor, + mb_sjis_kddi_to_wchar, + mb_wchar_to_sjis_kddi, NULL, - mbfl_filt_conv_wchar_sjis_mobile, - mbfl_filt_conv_sjis_mobile_flush, NULL, }; @@ -7996,8 +6598,8 @@ const mbfl_encoding mbfl_encoding_sjis_sb = { mbfl_encoding_sjis_sb_aliases, mblen_table_sjis_mobile, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_sjis_sb_wchar, - &vtbl_wchar_sjis_sb, + NULL, + NULL, mb_sjis_sb_to_wchar, mb_wchar_to_sjis_sb, NULL, @@ -8013,26 +6615,6 @@ const mbfl_encoding mbfl_encoding_sjis_sb = { static const char *mbfl_encoding_sjis2004_aliases[] = {"SJIS2004","Shift_JIS-2004", NULL}; -static const struct mbfl_convert_vtbl vtbl_sjis2004_wchar = { - mbfl_no_encoding_sjis2004, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_jis2004_wchar, - mbfl_filt_conv_jis2004_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_sjis2004 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjis2004, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_jis2004, - mbfl_filt_conv_wchar_jis2004_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_sjis2004 = { mbfl_no_encoding_sjis2004, "SJIS-2004", @@ -8040,8 +6622,8 @@ const mbfl_encoding mbfl_encoding_sjis2004 = { mbfl_encoding_sjis2004_aliases, mblen_table_sjis_mobile, /* Leading byte values used for SJIS-2004 are the same as mobile SJIS variants */ MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_sjis2004_wchar, - &vtbl_wchar_sjis2004, + NULL, + NULL, mb_sjis2004_to_wchar, mb_wchar_to_sjis2004, NULL, @@ -8074,253 +6656,65 @@ const mbfl_encoding mbfl_encoding_sjis2004 = { * • glibc's iconv converts U+203E to CP932 0x7E, which again agrees with * our mappings for "CP932". * • When converting Shift-JIS to CP932, the conversion goes through Unicode. - * Shift-JIS 0x7E converts to U+203E, so mapping U+203E to 0x7E means that - * 0x7E will go to 0x7E when converting Shift-JIS to CP932. - */ - -static const unsigned char mblen_table_sjiswin[] = { /* 0x81-0x9F,0xE0-0xFF */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 -}; - -static const char *mbfl_encoding_cp932_aliases[] = {"MS932", "Windows-31J", "MS_Kanji", NULL}; -static const char *mbfl_encoding_sjiswin_aliases[] = {"SJIS-ms", "SJIS-open", NULL}; - -static const struct mbfl_convert_vtbl vtbl_cp932_wchar = { - mbfl_no_encoding_cp932, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_cp932_wchar, - mbfl_filt_conv_cp932_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_cp932 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_cp932, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_cp932, - mbfl_filt_conv_common_flush, - NULL, -}; - -const mbfl_encoding mbfl_encoding_cp932 = { - mbfl_no_encoding_cp932, - "CP932", - "Shift_JIS", - mbfl_encoding_cp932_aliases, - mblen_table_sjiswin, - MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_cp932_wchar, - &vtbl_wchar_cp932, - mb_cp932_to_wchar, - mb_wchar_to_cp932, - NULL, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_sjiswin_wchar = { - mbfl_no_encoding_sjiswin, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_cp932_wchar, - mbfl_filt_conv_cp932_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_sjiswin = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_sjiswin, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_sjiswin, - mbfl_filt_conv_common_flush, - NULL, -}; - -const mbfl_encoding mbfl_encoding_sjiswin = { - mbfl_no_encoding_sjiswin, - "SJIS-win", - "Shift_JIS", - mbfl_encoding_sjiswin_aliases, - mblen_table_sjiswin, - MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_sjiswin_wchar, - &vtbl_wchar_sjiswin, - mb_cp932_to_wchar, - mb_wchar_to_sjiswin, - NULL, - NULL, -}; - -/* - * EUC variants - */ - -static int mbfl_filt_conv_eucjp_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, s, w = 0; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c > 0xa0 && c < 0xff) { /* X 0208 first char */ - filter->status = 1; - filter->cache = c; - } else if (c == 0x8e) { /* kana first char */ - filter->status = 2; - } else if (c == 0x8f) { /* X 0212 first char */ - filter->status = 3; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* got first half */ - filter->status = 0; - c1 = filter->cache; - if (c > 0xa0 && c < 0xff) { - s = (c1 - 0xa1)*94 + c - 0xa1; - if (s >= 0 && s < jisx0208_ucs_table_size) { - w = jisx0208_ucs_table[s]; - if (!w) - w = MBFL_BAD_INPUT; - } else { - w = MBFL_BAD_INPUT; - } - - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 2: /* got 0x8e */ - filter->status = 0; - if (c > 0xa0 && c < 0xe0) { - w = 0xfec0 + c; - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 3: /* got 0x8f, JIS X 0212 first byte */ - filter->status++; - filter->cache = c; - break; - - case 4: /* got 0x8f, JIS X 0212 second byte */ - filter->status = 0; - c1 = filter->cache; - if (c > 0xA0 && c < 0xFF && c1 > 0xA0 && c1 < 0xFF) { - s = (c1 - 0xa1)*94 + c - 0xa1; - if (s >= 0 && s < jisx0212_ucs_table_size) { - w = jisx0212_ucs_table[s]; - if (!w) - w = MBFL_BAD_INPUT; - } else { - w = MBFL_BAD_INPUT; - } - - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_eucjp_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - (*filter->output_function)(MBFL_BAD_INPUT, filter->data); - filter->status = 0; - } + * Shift-JIS 0x7E converts to U+203E, so mapping U+203E to 0x7E means that + * 0x7E will go to 0x7E when converting Shift-JIS to CP932. + */ - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } +static const unsigned char mblen_table_sjiswin[] = { /* 0x81-0x9F,0xE0-0xFF */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; - return 0; -} +static const char *mbfl_encoding_cp932_aliases[] = {"MS932", "Windows-31J", "MS_Kanji", NULL}; +static const char *mbfl_encoding_sjiswin_aliases[] = {"SJIS-ms", "SJIS-open", NULL}; -static int mbfl_filt_conv_wchar_eucjp(int c, mbfl_convert_filter *filter) -{ - int s = 0; +const mbfl_encoding mbfl_encoding_cp932 = { + mbfl_no_encoding_cp932, + "CP932", + "Shift_JIS", + mbfl_encoding_cp932_aliases, + mblen_table_sjiswin, + MBFL_ENCTYPE_GL_UNSAFE, + NULL, + NULL, + mb_cp932_to_wchar, + mb_wchar_to_cp932, + NULL, + NULL, +}; - if (c == 0xAF) { /* U+00AF is MACRON */ - s = 0xA2B4; /* Use JIS X 0212 overline */ - } else if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { - s = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; - } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { - s = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; - } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { - s = ucs_i_jis_table[c - ucs_i_jis_table_min]; - } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { - s = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } - if (s <= 0) { - if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ - s = 0x2140; - } else if (c == 0x2225) { /* PARALLEL TO */ - s = 0x2142; - } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ - s = 0x215d; - } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ - s = 0x2171; - } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ - s = 0x2172; - } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ - s = 0x224c; - } else if (c == 0) { - s = 0; - } else { - s = -1; - } - } - if (s >= 0) { - if (s < 0x80) { /* latin */ - CK((*filter->output_function)(s, filter->data)); - } else if (s < 0x100) { /* kana */ - CK((*filter->output_function)(0x8e, filter->data)); - CK((*filter->output_function)(s, filter->data)); - } else if (s < 0x8080) { /* X 0208 */ - CK((*filter->output_function)(((s >> 8) & 0xff) | 0x80, filter->data)); - CK((*filter->output_function)((s & 0xff) | 0x80, filter->data)); - } else { /* X 0212 */ - CK((*filter->output_function)(0x8f, filter->data)); - CK((*filter->output_function)(((s >> 8) & 0xff) | 0x80, filter->data)); - CK((*filter->output_function)((s & 0xff) | 0x80, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } +const mbfl_encoding mbfl_encoding_sjiswin = { + mbfl_no_encoding_sjiswin, + "SJIS-win", + "Shift_JIS", + mbfl_encoding_sjiswin_aliases, + mblen_table_sjiswin, + MBFL_ENCTYPE_GL_UNSAFE, + NULL, + NULL, + mb_cp932_to_wchar, + mb_wchar_to_sjiswin, + NULL, + NULL, +}; - return 0; -} +/* + * EUC variants + */ static size_t mb_eucjp_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { @@ -8428,267 +6822,20 @@ static void mb_wchar_to_eucjp(uint32_t *in, size_t len, mb_convert_buf *buf, boo continue; } } - - if (s < 0x80) { - out = mb_convert_buf_add(out, s); - } else if (s < 0x100) { - out = mb_convert_buf_add2(out, 0x8E, s); - } else if (s < 0x8080) { - out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); - } else { - MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 3); - out = mb_convert_buf_add3(out, 0x8F, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); - } - } - - MB_CONVERT_BUF_STORE(buf, out, limit); -} - -static int mbfl_filt_conv_eucjpwin_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, s, w, n; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c >= 0xa1 && c <= 0xfe) { /* CP932 first char */ - filter->status = 1; - filter->cache = c; - } else if (c == 0x8e) { /* kana first char */ - filter->status = 2; - } else if (c == 0x8f) { /* X 0212 first char */ - filter->status = 3; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* got first half */ - filter->status = 0; - c1 = filter->cache; - if (c > 0xa0 && c < 0xff) { - w = 0; - s = (c1 - 0xa1)*94 + c - 0xa1; - if (s <= 137) { - if (s == 31) { - w = 0xff3c; /* FULLWIDTH REVERSE SOLIDUS */ - } else if (s == 32) { - w = 0xff5e; /* FULLWIDTH TILDE */ - } else if (s == 33) { - w = 0x2225; /* PARALLEL TO */ - } else if (s == 60) { - w = 0xff0d; /* FULLWIDTH HYPHEN-MINUS */ - } else if (s == 80) { - w = 0xffe0; /* FULLWIDTH CENT SIGN */ - } else if (s == 81) { - w = 0xffe1; /* FULLWIDTH POUND SIGN */ - } else if (s == 137) { - w = 0xffe2; /* FULLWIDTH NOT SIGN */ - } - } - - if (w == 0) { - if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { /* vendor ext1 (13ku) */ - w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; - } else if (s >= 0 && s < jisx0208_ucs_table_size) { /* X 0208 */ - w = jisx0208_ucs_table[s]; - } else if (s >= (84 * 94)) { /* user (85ku - 94ku) */ - w = s - (84 * 94) + 0xe000; - } - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 2: /* got 0x8e, X0201 kana */ - filter->status = 0; - if (c > 0xa0 && c < 0xe0) { - w = 0xfec0 + c; - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 3: /* got 0x8f, X 0212 first char */ - filter->status++; - filter->cache = c; - break; - - case 4: /* got 0x8f, X 0212 second char */ - filter->status = 0; - c1 = filter->cache; - if (c1 > 0xa0 && c1 < 0xff && c > 0xa0 && c < 0xff) { - s = (c1 - 0xa1)*94 + c - 0xa1; - - if (s >= 0 && s < jisx0212_ucs_table_size) { - w = jisx0212_ucs_table[s]; - - if (w == 0x007e) { - w = 0xff5e; /* FULLWIDTH TILDE */ - } - } else if (s >= (82*94) && s < (84*94)) { /* vender ext3 (83ku - 84ku) <-> CP932 (115ku -120ku) */ - s = (c1 << 8) | c; - w = 0; - n = 0; - while (n < cp932ext3_eucjp_table_size) { - if (s == cp932ext3_eucjp_table[n]) { - if (n < (cp932ext3_ucs_table_max - cp932ext3_ucs_table_min)) { - w = cp932ext3_ucs_table[n]; - } - break; - } - n++; - } - } else if (s >= (84*94)) { /* user (85ku - 94ku) */ - w = s - (84*94) + (0xe000 + (94*10)); - } else { - w = 0; - } - - if (w == 0x00A6) { - w = 0xFFE4; /* FULLWIDTH BROKEN BAR */ - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_eucjpwin_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - (*filter->output_function)(MBFL_BAD_INPUT, filter->data); - filter->status = 0; - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_eucjpwin(int c, mbfl_convert_filter *filter) -{ - int c1, c2, s1 = 0; - - if (c == 0xAF) { /* U+00AF is MACRON */ - s1 = 0xA2B4; /* Use JIS X 0212 overline */ - } else if (c == 0x203E) { - s1 = 0x7E; - } else if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { - s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; - } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { - s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; - } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { - s1 = ucs_i_jis_table[c - ucs_i_jis_table_min]; - } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { - s1 = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } else if (c >= 0xe000 && c < (0xe000 + 10*94)) { /* user (X0208 85ku - 94ku) */ - s1 = c - 0xe000; - c1 = s1/94 + 0x75; - c2 = s1%94 + 0x21; - s1 = (c1 << 8) | c2; - } else if (c >= (0xe000 + 10*94) && c < (0xe000 + 20*94)) { /* user (X0212 85ku - 94ku) */ - s1 = c - (0xe000 + 10*94); - c1 = s1/94 + 0xf5; - c2 = s1%94 + 0xa1; - s1 = (c1 << 8) | c2; - } - - if (s1 == 0xa2f1) { - s1 = 0x2d62; /* NUMERO SIGN */ - } - - if (s1 <= 0) { - if (c == 0xa5) { /* YEN SIGN */ - s1 = 0x5C; - } else if (c == 0x2014) { - s1 = 0x213D; - } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ - s1 = 0x2140; - } else if (c == 0x2225) { /* PARALLEL TO */ - s1 = 0x2142; - } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ - s1 = 0x215d; - } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ - s1 = 0x2171; - } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ - s1 = 0x2172; - } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ - s1 = 0x224c; - } else { - s1 = -1; - c1 = 0; - c2 = cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext1 (13ku) */ - const int oh = cp932ext1_ucs_table_min / 94; - - if (c == cp932ext1_ucs_table[c1]) { - s1 = ((c1 / 94 + oh + 0x21) << 8) + (c1 % 94 + 0x21); - break; - } - c1++; - } - if (s1 < 0) { - c1 = 0; - c2 = cp932ext3_ucs_table_max - cp932ext3_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext3 (115ku - 119ku) */ - if (c == cp932ext3_ucs_table[c1]) { - if (c1 < cp932ext3_eucjp_table_size) { - s1 = cp932ext3_eucjp_table[c1]; - } - break; - } - c1++; - } - } - } - - if (c == 0) { - s1 = 0; - } else if (s1 <= 0) { - s1 = -1; - } - } - - if (s1 >= 0) { - if (s1 < 0x80) { /* latin */ - CK((*filter->output_function)(s1, filter->data)); - } else if (s1 < 0x100) { /* kana */ - CK((*filter->output_function)(0x8e, filter->data)); - CK((*filter->output_function)(s1, filter->data)); - } else if (s1 < 0x8080) { /* X 0208 */ - CK((*filter->output_function)(((s1 >> 8) & 0xff) | 0x80, filter->data)); - CK((*filter->output_function)((s1 & 0xff) | 0x80, filter->data)); - } else { /* X 0212 */ - CK((*filter->output_function)(0x8f, filter->data)); - CK((*filter->output_function)(((s1 >> 8) & 0xff) | 0x80, filter->data)); - CK((*filter->output_function)((s1 & 0xff) | 0x80, filter->data)); + + if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s < 0x100) { + out = mb_convert_buf_add2(out, 0x8E, s); + } else if (s < 0x8080) { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 3); + out = mb_convert_buf_add3(out, 0x8F, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); } - return 0; + MB_CONVERT_BUF_STORE(buf, out, limit); } static size_t mb_eucjpwin_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) @@ -8884,175 +7031,6 @@ static void mb_wchar_to_eucjpwin(uint32_t *in, size_t len, mb_convert_buf *buf, MB_CONVERT_BUF_STORE(buf, out, limit); } -static int mbfl_filt_conv_cp51932_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, s, w; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c >= 0xA1 && c <= 0xFE) { /* CP932, first byte */ - filter->status = 1; - filter->cache = c; - } else if (c == 0x8e) { /* kana first char */ - filter->status = 2; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* got first half */ - filter->status = 0; - c1 = filter->cache; - if (c > 0xa0 && c < 0xff) { - w = 0; - s = (c1 - 0xa1)*94 + c - 0xa1; - if (s <= 137) { - if (s == 31) { - w = 0xff3c; /* FULLWIDTH REVERSE SOLIDUS */ - } else if (s == 32) { - w = 0xff5e; /* FULLWIDTH TILDE */ - } else if (s == 33) { - w = 0x2225; /* PARALLEL TO */ - } else if (s == 60) { - w = 0xff0d; /* FULLWIDTH HYPHEN-MINUS */ - } else if (s == 80) { - w = 0xffe0; /* FULLWIDTH CENT SIGN */ - } else if (s == 81) { - w = 0xffe1; /* FULLWIDTH POUND SIGN */ - } else if (s == 137) { - w = 0xffe2; /* FULLWIDTH NOT SIGN */ - } - } - if (w == 0) { - if (s >= cp932ext1_ucs_table_min && s < cp932ext1_ucs_table_max) { /* vendor ext1 (13ku) */ - w = cp932ext1_ucs_table[s - cp932ext1_ucs_table_min]; - } else if (s >= 0 && s < jisx0208_ucs_table_size) { /* X 0208 */ - w = jisx0208_ucs_table[s]; - } else if (s >= cp932ext2_ucs_table_min && s < cp932ext2_ucs_table_max) { /* vendor ext2 (89ku - 92ku) */ - w = cp932ext2_ucs_table[s - cp932ext2_ucs_table_min]; - } - } - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 2: /* got 0x8e, X0201 kana */ - filter->status = 0; - if (c > 0xa0 && c < 0xe0) { - w = 0xfec0 + c; - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_cp51932_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - /* Input string was truncated */ - (*filter->output_function)(MBFL_BAD_INPUT, filter->data); - filter->status = 0; - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_cp51932(int c, mbfl_convert_filter *filter) -{ - int c1, c2, s1; - - s1 = 0; - if (c >= ucs_a1_jis_table_min && c < ucs_a1_jis_table_max) { - s1 = ucs_a1_jis_table[c - ucs_a1_jis_table_min]; - } else if (c >= ucs_a2_jis_table_min && c < ucs_a2_jis_table_max) { - s1 = ucs_a2_jis_table[c - ucs_a2_jis_table_min]; - } else if (c >= ucs_i_jis_table_min && c < ucs_i_jis_table_max) { - s1 = ucs_i_jis_table[c - ucs_i_jis_table_min]; - } else if (c >= ucs_r_jis_table_min && c < ucs_r_jis_table_max) { - s1 = ucs_r_jis_table[c - ucs_r_jis_table_min]; - } - if (s1 >= 0x8080) s1 = -1; /* we don't support JIS X0213 */ - if (s1 <= 0) { - if (c == 0xa5) { /* YEN SIGN */ - s1 = 0x216F; /* FULLWIDTH YEN SIGN */ - } else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */ - s1 = 0x2140; - } else if (c == 0x2225) { /* PARALLEL TO */ - s1 = 0x2142; - } else if (c == 0xff0d) { /* FULLWIDTH HYPHEN-MINUS */ - s1 = 0x215d; - } else if (c == 0xffe0) { /* FULLWIDTH CENT SIGN */ - s1 = 0x2171; - } else if (c == 0xffe1) { /* FULLWIDTH POUND SIGN */ - s1 = 0x2172; - } else if (c == 0xffe2) { /* FULLWIDTH NOT SIGN */ - s1 = 0x224c; - } else { - s1 = -1; - c1 = 0; - c2 = cp932ext1_ucs_table_max - cp932ext1_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext1 (13ku) */ - if (c == cp932ext1_ucs_table[c1]) { - s1 = ((c1/94 + 0x2d) << 8) + (c1%94 + 0x21); - break; - } - c1++; - } - if (s1 < 0) { - c1 = 0; - c2 = cp932ext2_ucs_table_max - cp932ext2_ucs_table_min; - while (c1 < c2) { /* CP932 vendor ext3 (115ku - 119ku) */ - if (c == cp932ext2_ucs_table[c1]) { - s1 = ((c1/94 + 0x79) << 8) +(c1%94 + 0x21); - break; - } - c1++; - } - } - } - if (c == 0) { - s1 = 0; - } else if (s1 <= 0) { - s1 = -1; - } - } - - if (s1 >= 0) { - if (s1 < 0x80) { /* latin */ - CK((*filter->output_function)(s1, filter->data)); - } else if (s1 < 0x100) { /* kana */ - CK((*filter->output_function)(0x8e, filter->data)); - CK((*filter->output_function)(s1, filter->data)); - } else if (s1 < 0x8080) { /* X 0208 */ - CK((*filter->output_function)(((s1 >> 8) & 0xff) | 0x80, filter->data)); - CK((*filter->output_function)((s1 & 0xff) | 0x80, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - static size_t mb_cp51932_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -9355,190 +7333,62 @@ process_codepoint: ; s = uni2jis_tbl[k][w - uni2jis_tbl_range[k][0]]; break; } - } - } - - /* Check for Japanese chars in compressed mapping area: U+1E00-U+4DBF */ - if (!s && w >= ucs_c1_jisx0213_min && w <= ucs_c1_jisx0213_max) { - int k = mbfl_bisec_srch(w, ucs_c1_jisx0213_tbl, ucs_c1_jisx0213_tbl_len); - if (k >= 0) { - s = ucs_c1_jisx0213_ofst[k] + w - ucs_c1_jisx0213_tbl[2*k]; - } - } - - /* Check for Japanese chars in CJK Unified Ideographs ext.B (U+2XXXX) */ - if (!s && w >= jisx0213_u5_tbl_min && w <= jisx0213_u5_tbl_max) { - int k = mbfl_bisec_srch2(w - 0x20000, jisx0213_u5_jis_key, jisx0213_u5_tbl_len); - if (k >= 0) { - s = jisx0213_u5_jis_tbl[k]; - } - } - - if (!s) { - /* CJK Compatibility Forms: U+FE30-U+FE4F */ - if (w == 0xFE45) { - s = 0x233E; - } else if (w == 0xFE46) { - s = 0x233D; - } else if (w >= 0xF91D && w <= 0xF9DC) { - /* CJK Compatibility Ideographs: U+F900-U+F92A */ - int k = mbfl_bisec_srch2(w, ucs_r2b_jisx0213_cmap_key, ucs_r2b_jisx0213_cmap_len); - if (k >= 0) { - s = ucs_r2b_jisx0213_cmap_val[k]; - } - } - } - - if (!s && w) { - MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_eucjp2004); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len); - } else if (s <= 0x7F) { - out = mb_convert_buf_add(out, s); - } else if (s <= 0xFF) { - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); - out = mb_convert_buf_add2(out, 0x8E, s); - } else if (s <= 0x7EFF) { - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); - out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) + 0x80, (s & 0xFF) + 0x80); - } else { - unsigned int s2 = s & 0xFF; - int k = ((s >> 8) & 0xFF) - 0x7F; - ZEND_ASSERT(k < jisx0213_p2_ofst_len); - s = jisx0213_p2_ofst[k] + 0x21; - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 3); - out = mb_convert_buf_add3(out, 0x8F, s | 0x80, s2 | 0x80); - } - } - - MB_CONVERT_BUF_STORE(buf, out, limit); -} - -static int mbfl_filt_conv_euccn_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, w; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if ((c >= 0xA1 && c <= 0xA9) || (c >= 0xB0 && c <= 0xF7)) { /* dbcs lead byte */ - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* dbcs second byte */ - filter->status = 0; - c1 = filter->cache; - if (c > 0xA0 && c < 0xFF) { - w = (c1 - 0x81)*192 + c - 0x40; - ZEND_ASSERT(w < cp936_ucs_table_size); - if (w == 0x1864) { - w = 0x30FB; - } else if (w == 0x186A) { - w = 0x2015; - } else if ((w >= 0x1921 && w <= 0x192A) || w == 0x1963 || (w >= 0x1C59 && w <= 0x1C7E) || (w >= 0x1DBB && w <= 0x1DC4)) { - w = 0; - } else { - w = cp936_ucs_table[w]; - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_euccn(int c, mbfl_convert_filter *filter) -{ - int s = 0; - - if (c >= ucs_a1_cp936_table_min && c < ucs_a1_cp936_table_max) { - if (c == 0xB7 || c == 0x144 || c == 0x148 || c == 0x251 || c == 0x261) { - s = 0; - } else { - s = ucs_a1_cp936_table[c - ucs_a1_cp936_table_min]; - } - } else if (c >= ucs_a2_cp936_table_min && c < ucs_a2_cp936_table_max) { - if (c == 0x2015) { - s = 0xA1AA; - } else if (c == 0x2014 || (c >= 0x2170 && c <= 0x2179)) { - s = 0; - } else { - s = ucs_a2_cp936_table[c - ucs_a2_cp936_table_min]; - } - } else if (c >= ucs_a3_cp936_table_min && c < ucs_a3_cp936_table_max) { - if (c == 0x30FB) { - s = 0xA1A4; - } else { - s = ucs_a3_cp936_table[c - ucs_a3_cp936_table_min]; - } - } else if (c >= ucs_i_cp936_table_min && c < ucs_i_cp936_table_max) { - s = ucs_i_cp936_table[c - ucs_i_cp936_table_min]; - } else if (c >= ucs_hff_cp936_table_min && c < ucs_hff_cp936_table_max) { - if (c == 0xFF04) { - s = 0xA1E7; - } else if (c == 0xFF5E) { - s = 0xA1AB; - } else if (c >= 0xFF01 && c <= 0xFF5D) { - s = c - 0xFF01 + 0xA3A1; - } else if (c >= 0xFFE0 && c <= 0xFFE5) { - s = ucs_hff_s_cp936_table[c - 0xFFE0]; + } } - } - - /* exclude CP936 extensions */ - if (((s >> 8) & 0xFF) < 0xA1 || (s & 0xFF) < 0xA1) { - s = 0; - } - if (s <= 0) { - if (c < 0x80) { - s = c; - } else if (s <= 0) { - s = -1; + /* Check for Japanese chars in compressed mapping area: U+1E00-U+4DBF */ + if (!s && w >= ucs_c1_jisx0213_min && w <= ucs_c1_jisx0213_max) { + int k = mbfl_bisec_srch(w, ucs_c1_jisx0213_tbl, ucs_c1_jisx0213_tbl_len); + if (k >= 0) { + s = ucs_c1_jisx0213_ofst[k] + w - ucs_c1_jisx0213_tbl[2*k]; + } } - } - if (s >= 0) { - if (s < 0x80) { /* latin */ - CK((*filter->output_function)(s, filter->data)); - } else { - CK((*filter->output_function)((s >> 8) & 0xFF, filter->data)); - CK((*filter->output_function)(s & 0xFF, filter->data)); + /* Check for Japanese chars in CJK Unified Ideographs ext.B (U+2XXXX) */ + if (!s && w >= jisx0213_u5_tbl_min && w <= jisx0213_u5_tbl_max) { + int k = mbfl_bisec_srch2(w - 0x20000, jisx0213_u5_jis_key, jisx0213_u5_tbl_len); + if (k >= 0) { + s = jisx0213_u5_jis_tbl[k]; + } } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - -static int mbfl_filt_conv_euccn_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status == 1) { - /* 2-byte character was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } + if (!s) { + /* CJK Compatibility Forms: U+FE30-U+FE4F */ + if (w == 0xFE45) { + s = 0x233E; + } else if (w == 0xFE46) { + s = 0x233D; + } else if (w >= 0xF91D && w <= 0xF9DC) { + /* CJK Compatibility Ideographs: U+F900-U+F92A */ + int k = mbfl_bisec_srch2(w, ucs_r2b_jisx0213_cmap_key, ucs_r2b_jisx0213_cmap_len); + if (k >= 0) { + s = ucs_r2b_jisx0213_cmap_val[k]; + } + } + } - if (filter->flush_function) { - (*filter->flush_function)(filter->data); + if (!s && w) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_eucjp2004); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } else if (s <= 0x7F) { + out = mb_convert_buf_add(out, s); + } else if (s <= 0xFF) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, 0x8E, s); + } else if (s <= 0x7EFF) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) + 0x80, (s & 0xFF) + 0x80); + } else { + unsigned int s2 = s & 0xFF; + int k = ((s >> 8) & 0xFF) - 0x7F; + ZEND_ASSERT(k < jisx0213_p2_ofst_len); + s = jisx0213_p2_ofst[k] + 0x21; + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 3); + out = mb_convert_buf_add3(out, 0x8F, s | 0x80, s2 | 0x80); + } } - return 0; + MB_CONVERT_BUF_STORE(buf, out, limit); } static size_t mb_euccn_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) @@ -9645,169 +7495,6 @@ static void mb_wchar_to_euccn(uint32_t *in, size_t len, mb_convert_buf *buf, boo MB_CONVERT_BUF_STORE(buf, out, limit); } -static int mbfl_filt_conv_euctw_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, s, w; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (((c >= 0xA1 && c <= 0xA6) || (c >= 0xC2 && c <= 0xFD)) && c != 0xC3) { /* 2-byte character, first byte */ - filter->status = 1; - filter->cache = c; - } else if (c == 0x8E) { /* 4-byte character, first byte */ - filter->status = 2; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* 2-byte character, second byte */ - filter->status = 0; - c1 = filter->cache; - if (c > 0xA0 && c < 0xFF) { - w = (c1 - 0xA1)*94 + (c - 0xA1); - if (w >= 0 && w < cns11643_1_ucs_table_size) { - w = cns11643_1_ucs_table[w]; - } else { - w = 0; - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - - CK((*filter->output_function)(w, filter->data)); - } else { - filter->status = filter->cache = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 2: /* got 0x8e, second byte */ - if (c == 0xA1 || c == 0xA2 || c == 0xAE) { - filter->status = 3; - filter->cache = c - 0xA1; - } else { - filter->status = filter->cache = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 3: /* got 0x8e, third byte */ - filter->status = 0; - c1 = filter->cache; - if (c >= 0xA1 && ((c1 == 0 && ((c >= 0xA1 && c <= 0xA6) || (c >= 0xC2 && c <= 0xFD)) && c != 0xC3) || - (c1 == 1 && c <= 0xF2) || (c1 == 13 && c <= 0xE7))) { - filter->status = 4; - filter->cache = (c1 << 8) + c - 0xA1; - } else { - filter->status = filter->cache = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 4: /* multi-byte character, fourth byte */ - filter->status = 0; - c1 = filter->cache; - if (c1 <= 0xDFF && c > 0xA0 && c < 0xFF) { - int plane = (c1 & 0xF00) >> 8; /* This is actually the CNS-11643 plane minus one */ - s = (c1 & 0xFF)*94 + c - 0xA1; - w = 0; - if (s >= 0) { - /* A later version of CNS-11643 moved all the characters in "plane 14" to "plane 3", - * and added tens of thousands more characters in planes 4, 5, 6, and 7 - * We only support the older version of CNS-11643 - * This is the same as iconv from glibc 2.2 */ - if (plane == 0 && s < cns11643_1_ucs_table_size) { - w = cns11643_1_ucs_table[s]; - } else if (plane == 1 && s < cns11643_2_ucs_table_size) { - w = cns11643_2_ucs_table[s]; - } else if (plane == 13 && s < cns11643_14_ucs_table_size) { - w = cns11643_14_ucs_table[s]; - } - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - - CK((*filter->output_function)(w, filter->data)); - } else { - filter->status = filter->cache = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_euctw(int c, mbfl_convert_filter *filter) -{ - int s = 0; - - if (c >= ucs_a1_cns11643_table_min && c < ucs_a1_cns11643_table_max) { - s = ucs_a1_cns11643_table[c - ucs_a1_cns11643_table_min]; - } else if (c >= ucs_a2_cns11643_table_min && c < ucs_a2_cns11643_table_max) { - s = ucs_a2_cns11643_table[c - ucs_a2_cns11643_table_min]; - } else if (c >= ucs_a3_cns11643_table_min && c < ucs_a3_cns11643_table_max) { - s = ucs_a3_cns11643_table[c - ucs_a3_cns11643_table_min]; - } else if (c >= ucs_i_cns11643_table_min && c < ucs_i_cns11643_table_max) { - s = ucs_i_cns11643_table[c - ucs_i_cns11643_table_min]; - } else if (c >= ucs_r_cns11643_table_min && c < ucs_r_cns11643_table_max) { - s = ucs_r_cns11643_table[c - ucs_r_cns11643_table_min]; - } - - if (s <= 0) { - if (c == 0) { - s = 0; - } else if (s <= 0) { - s = -1; - } - } - - if (s >= 0) { - int plane = (s & 0x1F0000) >> 16; - if (plane <= 1) { - if (s < 0x80) { /* latin */ - CK((*filter->output_function)(s, filter->data)); - } else { - s = (s & 0xFFFF) | 0x8080; - CK((*filter->output_function)((s >> 8) & 0xFF, filter->data)); - CK((*filter->output_function)(s & 0xFF, filter->data)); - } - } else { - s = (0x8EA00000 + (plane << 16)) | ((s & 0xFFFF) | 0x8080); - CK((*filter->output_function)(0x8e , filter->data)); - CK((*filter->output_function)((s >> 16) & 0xFF, filter->data)); - CK((*filter->output_function)((s >> 8) & 0xFF, filter->data)); - CK((*filter->output_function)(s & 0xFF, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - -static int mbfl_filt_conv_euctw_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - /* 2-byte or 4-byte character was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - static size_t mb_euctw_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -9870,172 +7557,59 @@ static size_t mb_euctw_to_wchar(unsigned char **in, size_t *in_len, uint32_t *bu *out++ = MBFL_BAD_INPUT; } else { *out++ = MBFL_BAD_INPUT; - } - } - - *in_len = e - p; - *in = p; - return out - buf; -} - -static void mb_wchar_to_euctw(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) -{ - unsigned char *out, *limit; - MB_CONVERT_BUF_LOAD(buf, out, limit); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); - - while (len--) { - uint32_t w = *in++; - unsigned int s = 0; - - if (w >= ucs_a1_cns11643_table_min && w < ucs_a1_cns11643_table_max) { - s = ucs_a1_cns11643_table[w - ucs_a1_cns11643_table_min]; - } else if (w >= ucs_a2_cns11643_table_min && w < ucs_a2_cns11643_table_max) { - s = ucs_a2_cns11643_table[w - ucs_a2_cns11643_table_min]; - } else if (w >= ucs_a3_cns11643_table_min && w < ucs_a3_cns11643_table_max) { - s = ucs_a3_cns11643_table[w - ucs_a3_cns11643_table_min]; - } else if (w >= ucs_i_cns11643_table_min && w < ucs_i_cns11643_table_max) { - s = ucs_i_cns11643_table[w - ucs_i_cns11643_table_min]; - } else if (w >= ucs_r_cns11643_table_min && w < ucs_r_cns11643_table_max) { - s = ucs_r_cns11643_table[w - ucs_r_cns11643_table_min]; - } - - if (!s) { - if (w == 0) { - out = mb_convert_buf_add(out, 0); - } else { - MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euctw); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); - } - } else { - unsigned int plane = s >> 16; - if (plane <= 1) { - if (s < 0x80) { - out = mb_convert_buf_add(out, s); - } else { - out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); - } - } else { - MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); - out = mb_convert_buf_add4(out, 0x8E, 0xA0 + plane, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); - } - } - } - - MB_CONVERT_BUF_STORE(buf, out, limit); -} - -static int mbfl_filt_conv_euckr_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, w, flag; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (((c >= 0xA1 && c <= 0xAC) || (c >= 0xB0 && c <= 0xFD)) && c != 0xC9) { /* dbcs lead byte */ - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* dbcs second byte */ - filter->status = 0; - c1 = filter->cache; - flag = 0; - if (c1 >= 0xa1 && c1 <= 0xc6) { - flag = 1; - } else if (c1 >= 0xc7 && c1 <= 0xfe && c1 != 0xc9) { - flag = 2; - } - if (flag > 0 && c >= 0xa1 && c <= 0xfe) { - if (flag == 1) { /* 1st: 0xa1..0xc6, 2nd: 0x41..0x7a, 0x81..0xfe */ - w = (c1 - 0x81)*190 + c - 0x41; - ZEND_ASSERT(w < uhc1_ucs_table_size); - w = uhc1_ucs_table[w]; - } else { /* 1st: 0xc7..0xc8,0xca..0xfe, 2nd: 0xa1..0xfe */ - w = (c1 - 0xc7)*94 + c - 0xa1; - ZEND_ASSERT(w < uhc3_ucs_table_size); - w = uhc3_ucs_table[w]; - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); + } } - return 0; + *in_len = e - p; + *in = p; + return out - buf; } -static int mbfl_filt_conv_wchar_euckr(int c, mbfl_convert_filter *filter) +static void mb_wchar_to_euctw(uint32_t *in, size_t len, mb_convert_buf *buf, bool end) { - int s = 0; - - if (c >= ucs_a1_uhc_table_min && c < ucs_a1_uhc_table_max) { - s = ucs_a1_uhc_table[c - ucs_a1_uhc_table_min]; - } else if (c >= ucs_a2_uhc_table_min && c < ucs_a2_uhc_table_max) { - s = ucs_a2_uhc_table[c - ucs_a2_uhc_table_min]; - } else if (c >= ucs_a3_uhc_table_min && c < ucs_a3_uhc_table_max) { - s = ucs_a3_uhc_table[c - ucs_a3_uhc_table_min]; - } else if (c >= ucs_i_uhc_table_min && c < ucs_i_uhc_table_max) { - s = ucs_i_uhc_table[c - ucs_i_uhc_table_min]; - } else if (c >= ucs_s_uhc_table_min && c < ucs_s_uhc_table_max) { - s = ucs_s_uhc_table[c - ucs_s_uhc_table_min]; - } else if (c >= ucs_r1_uhc_table_min && c < ucs_r1_uhc_table_max) { - s = ucs_r1_uhc_table[c - ucs_r1_uhc_table_min]; - } else if (c >= ucs_r2_uhc_table_min && c < ucs_r2_uhc_table_max) { - s = ucs_r2_uhc_table[c - ucs_r2_uhc_table_min]; - } + unsigned char *out, *limit; + MB_CONVERT_BUF_LOAD(buf, out, limit); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); - /* exclude UHC extension area (although we are using the UHC conversion tables) */ - if (((s >> 8) & 0xFF) < 0xA1 || (s & 0xFF) < 0xA1) { - s = 0; - } + while (len--) { + uint32_t w = *in++; + unsigned int s = 0; - if (s <= 0) { - if (c < 0x80) { - s = c; - } else { - s = -1; + if (w >= ucs_a1_cns11643_table_min && w < ucs_a1_cns11643_table_max) { + s = ucs_a1_cns11643_table[w - ucs_a1_cns11643_table_min]; + } else if (w >= ucs_a2_cns11643_table_min && w < ucs_a2_cns11643_table_max) { + s = ucs_a2_cns11643_table[w - ucs_a2_cns11643_table_min]; + } else if (w >= ucs_a3_cns11643_table_min && w < ucs_a3_cns11643_table_max) { + s = ucs_a3_cns11643_table[w - ucs_a3_cns11643_table_min]; + } else if (w >= ucs_i_cns11643_table_min && w < ucs_i_cns11643_table_max) { + s = ucs_i_cns11643_table[w - ucs_i_cns11643_table_min]; + } else if (w >= ucs_r_cns11643_table_min && w < ucs_r_cns11643_table_max) { + s = ucs_r_cns11643_table[w - ucs_r_cns11643_table_min]; } - } - if (s >= 0) { - if (s < 0x80) { /* latin */ - CK((*filter->output_function)(s, filter->data)); + if (!s) { + if (w == 0) { + out = mb_convert_buf_add(out, 0); + } else { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_euctw); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len * 2); + } } else { - CK((*filter->output_function)((s >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s & 0xff, filter->data)); + unsigned int plane = s >> 16; + if (plane <= 1) { + if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else { + out = mb_convert_buf_add2(out, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } + } else { + MB_CONVERT_BUF_ENSURE(buf, out, limit, (len * 2) + 4); + out = mb_convert_buf_add4(out, 0x8E, 0xA0 + plane, ((s >> 8) & 0xFF) | 0x80, (s & 0xFF) | 0x80); + } } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - -static int mbfl_filt_conv_euckr_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status == 1) { - /* 2-byte character was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); } - return 0; + MB_CONVERT_BUF_STORE(buf, out, limit); } static size_t mb_euckr_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) @@ -10129,101 +7703,6 @@ static void mb_wchar_to_euckr(uint32_t *in, size_t len, mb_convert_buf *buf, boo MB_CONVERT_BUF_STORE(buf, out, limit); } -static int mbfl_filt_conv_uhc_wchar(int c, mbfl_convert_filter *filter) -{ - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c > 0x80 && c < 0xfe && c != 0xc9) { /* dbcs lead byte */ - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* dbcs second byte */ - filter->status = 0; - int c1 = filter->cache, w = 0; - - if (c1 >= 0x81 && c1 <= 0xc6 && c >= 0x41 && c <= 0xfe) { - w = (c1 - 0x81)*190 + (c - 0x41); - if (w >= 0 && w < uhc1_ucs_table_size) { - w = uhc1_ucs_table[w]; - } - } else if (c1 >= 0xc7 && c1 < 0xfe && c >= 0xa1 && c <= 0xfe) { - w = (c1 - 0xc7)*94 + (c - 0xa1); - if (w >= 0 && w < uhc3_ucs_table_size) { - w = uhc3_ucs_table[w]; - } - } - - if (w == 0) { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_uhc_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status == 1) { - /* 2-byte character was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_uhc(int c, mbfl_convert_filter *filter) -{ - int s = 0; - - if (c >= ucs_a1_uhc_table_min && c < ucs_a1_uhc_table_max) { - s = ucs_a1_uhc_table[c - ucs_a1_uhc_table_min]; - } else if (c >= ucs_a2_uhc_table_min && c < ucs_a2_uhc_table_max) { - s = ucs_a2_uhc_table[c - ucs_a2_uhc_table_min]; - } else if (c >= ucs_a3_uhc_table_min && c < ucs_a3_uhc_table_max) { - s = ucs_a3_uhc_table[c - ucs_a3_uhc_table_min]; - } else if (c >= ucs_i_uhc_table_min && c < ucs_i_uhc_table_max) { - s = ucs_i_uhc_table[c - ucs_i_uhc_table_min]; - } else if (c >= ucs_s_uhc_table_min && c < ucs_s_uhc_table_max) { - s = ucs_s_uhc_table[c - ucs_s_uhc_table_min]; - } else if (c >= ucs_r1_uhc_table_min && c < ucs_r1_uhc_table_max) { - s = ucs_r1_uhc_table[c - ucs_r1_uhc_table_min]; - } else if (c >= ucs_r2_uhc_table_min && c < ucs_r2_uhc_table_max) { - s = ucs_r2_uhc_table[c - ucs_r2_uhc_table_min]; - } - - if (s == 0 && c != 0) { - s = -1; - } - - if (s >= 0) { - if (s < 0x80) { /* latin */ - CK((*filter->output_function)(s, filter->data)); - } else { - CK((*filter->output_function)((s >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s & 0xff, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - static size_t mb_uhc_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -10345,26 +7824,6 @@ static const unsigned char mblen_table_eucjp[] = { /* 0xA1-0xFE */ static const char *mbfl_encoding_euc_jp_aliases[] = {"EUC", "EUC_JP", "eucJP", "x-euc-jp", NULL}; -static const struct mbfl_convert_vtbl vtbl_eucjp_wchar = { - mbfl_no_encoding_euc_jp, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_eucjp_wchar, - mbfl_filt_conv_eucjp_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_eucjp = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_euc_jp, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_eucjp, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_euc_jp = { mbfl_no_encoding_euc_jp, "EUC-JP", @@ -10372,8 +7831,8 @@ const mbfl_encoding mbfl_encoding_euc_jp = { mbfl_encoding_euc_jp_aliases, mblen_table_eucjp, 0, - &vtbl_eucjp_wchar, - &vtbl_wchar_eucjp, + NULL, + NULL, mb_eucjp_to_wchar, mb_wchar_to_eucjp, NULL, @@ -10382,26 +7841,6 @@ const mbfl_encoding mbfl_encoding_euc_jp = { static const char *mbfl_encoding_eucjp2004_aliases[] = {"EUC_JP-2004", NULL}; -static const struct mbfl_convert_vtbl vtbl_eucjp2004_wchar = { - mbfl_no_encoding_eucjp2004, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_jis2004_wchar, - mbfl_filt_conv_jis2004_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_eucjp2004 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_eucjp2004, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_jis2004, - mbfl_filt_conv_wchar_jis2004_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_eucjp2004 = { mbfl_no_encoding_eucjp2004, "EUC-JP-2004", @@ -10409,8 +7848,8 @@ const mbfl_encoding mbfl_encoding_eucjp2004 = { mbfl_encoding_eucjp2004_aliases, mblen_table_eucjp, 0, - &vtbl_eucjp2004_wchar, - &vtbl_wchar_eucjp2004, + NULL, + NULL, mb_eucjp2004_to_wchar, mb_wchar_to_eucjp2004, NULL, @@ -10419,26 +7858,6 @@ const mbfl_encoding mbfl_encoding_eucjp2004 = { static const char *mbfl_encoding_eucjp_win_aliases[] = {"eucJP-open", "eucJP-ms", NULL}; -static const struct mbfl_convert_vtbl vtbl_eucjpwin_wchar = { - mbfl_no_encoding_eucjp_win, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_eucjpwin_wchar, - mbfl_filt_conv_eucjpwin_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_eucjpwin = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_eucjp_win, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_eucjpwin, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_eucjp_win = { mbfl_no_encoding_eucjp_win, "eucJP-win", @@ -10446,8 +7865,8 @@ const mbfl_encoding mbfl_encoding_eucjp_win = { mbfl_encoding_eucjp_win_aliases, mblen_table_eucjp, 0, - &vtbl_eucjpwin_wchar, - &vtbl_wchar_eucjpwin, + NULL, + NULL, mb_eucjpwin_to_wchar, mb_wchar_to_eucjpwin, NULL, @@ -10456,26 +7875,6 @@ const mbfl_encoding mbfl_encoding_eucjp_win = { static const char *mbfl_encoding_cp51932_aliases[] = {"cp51932", NULL}; -static const struct mbfl_convert_vtbl vtbl_cp51932_wchar = { - mbfl_no_encoding_cp51932, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_cp51932_wchar, - mbfl_filt_conv_cp51932_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_cp51932 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_cp51932, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_cp51932, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_cp51932 = { mbfl_no_encoding_cp51932, "CP51932", @@ -10483,8 +7882,8 @@ const mbfl_encoding mbfl_encoding_cp51932 = { mbfl_encoding_cp51932_aliases, mblen_table_eucjp, 0, - &vtbl_cp51932_wchar, - &vtbl_wchar_cp51932, + NULL, + NULL, mb_cp51932_to_wchar, mb_wchar_to_cp51932, NULL, @@ -10512,26 +7911,6 @@ static const unsigned char mblen_table_euccn[] = { /* 0xA1-0xFE */ static const char *mbfl_encoding_euc_cn_aliases[] = {"CN-GB", "EUC_CN", "eucCN", "x-euc-cn", "gb2312", NULL}; -static const struct mbfl_convert_vtbl vtbl_euccn_wchar = { - mbfl_no_encoding_euc_cn, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_euccn_wchar, - mbfl_filt_conv_euccn_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_euccn = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_euc_cn, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_euccn, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_euc_cn = { mbfl_no_encoding_euc_cn, "EUC-CN", @@ -10539,36 +7918,16 @@ const mbfl_encoding mbfl_encoding_euc_cn = { mbfl_encoding_euc_cn_aliases, mblen_table_euccn, 0, - &vtbl_euccn_wchar, - &vtbl_wchar_euccn, - mb_euccn_to_wchar, - mb_wchar_to_euccn, - NULL, - NULL, -}; - -static const char *mbfl_encoding_euc_tw_aliases[] = {"EUC_TW", "eucTW", "x-euc-tw", NULL}; - -static const struct mbfl_convert_vtbl vtbl_euctw_wchar = { - mbfl_no_encoding_euc_tw, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, NULL, - mbfl_filt_conv_euctw_wchar, - mbfl_filt_conv_euctw_wchar_flush, NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_euctw = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_euc_tw, - mbfl_filt_conv_common_ctor, + mb_euccn_to_wchar, + mb_wchar_to_euccn, NULL, - mbfl_filt_conv_wchar_euctw, - mbfl_filt_conv_common_flush, NULL, }; +static const char *mbfl_encoding_euc_tw_aliases[] = {"EUC_TW", "eucTW", "x-euc-tw", NULL}; + const mbfl_encoding mbfl_encoding_euc_tw = { mbfl_no_encoding_euc_tw, "EUC-TW", @@ -10576,8 +7935,8 @@ const mbfl_encoding mbfl_encoding_euc_tw = { mbfl_encoding_euc_tw_aliases, mblen_table_euccn, 0, - &vtbl_euctw_wchar, - &vtbl_wchar_euctw, + NULL, + NULL, mb_euctw_to_wchar, mb_wchar_to_euctw, NULL, @@ -10586,26 +7945,6 @@ const mbfl_encoding mbfl_encoding_euc_tw = { static const char *mbfl_encoding_euc_kr_aliases[] = {"EUC_KR", "eucKR", "x-euc-kr", NULL}; -static const struct mbfl_convert_vtbl vtbl_euckr_wchar = { - mbfl_no_encoding_euc_kr, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_euckr_wchar, - mbfl_filt_conv_euckr_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_euckr = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_euc_kr, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_euckr, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_euc_kr = { mbfl_no_encoding_euc_kr, "EUC-KR", @@ -10613,8 +7952,8 @@ const mbfl_encoding mbfl_encoding_euc_kr = { mbfl_encoding_euc_kr_aliases, mblen_table_euccn, 0, - &vtbl_euckr_wchar, - &vtbl_wchar_euckr, + NULL, + NULL, mb_euckr_to_wchar, mb_wchar_to_euckr, NULL, @@ -10646,26 +7985,6 @@ static const unsigned char mblen_table_81_to_fe[] = { /* 0x81-0xFE */ static const char *mbfl_encoding_uhc_aliases[] = {"CP949", NULL}; -static const struct mbfl_convert_vtbl vtbl_uhc_wchar = { - mbfl_no_encoding_uhc, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_uhc_wchar, - mbfl_filt_conv_uhc_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_uhc = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_uhc, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_uhc, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_uhc = { mbfl_no_encoding_uhc, "UHC", @@ -10673,8 +7992,8 @@ const mbfl_encoding mbfl_encoding_uhc = { mbfl_encoding_uhc_aliases, mblen_table_81_to_fe, 0, - &vtbl_uhc_wchar, - &vtbl_wchar_uhc, + NULL, + NULL, mb_uhc_to_wchar, mb_wchar_to_uhc, NULL, @@ -10685,284 +8004,6 @@ const mbfl_encoding mbfl_encoding_uhc = { * GB18030/CP936 */ -static int mbfl_filt_conv_gb18030_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, c2, c3, w = -1; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c > 0x80 && c < 0xff) { /* dbcs/qbcs lead byte */ - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* dbcs/qbcs second byte */ - c1 = filter->cache; - filter->status = 0; - - if (c1 >= 0x81 && c1 <= 0x84 && c >= 0x30 && c <= 0x39) { - /* 4 byte range: Unicode BMP */ - filter->status = 2; - filter->cache = (c1 << 8) | c; - return 0; - } else if (c1 >= 0x90 && c1 <= 0xe3 && c >= 0x30 && c <= 0x39) { - /* 4 byte range: Unicode 16 planes */ - filter->status = 2; - filter->cache = (c1 << 8) | c; - return 0; - } else if (((c1 >= 0xaa && c1 <= 0xaf) || (c1 >= 0xf8 && c1 <= 0xfe)) && (c >= 0xa1 && c <= 0xfe)) { - /* UDA part 1,2: U+E000-U+E4C5 */ - w = 94*(c1 >= 0xf8 ? c1 - 0xf2 : c1 - 0xaa) + (c - 0xa1) + 0xe000; - CK((*filter->output_function)(w, filter->data)); - } else if (c1 >= 0xa1 && c1 <= 0xa7 && c >= 0x40 && c < 0xa1 && c != 0x7f) { - /* UDA part3 : U+E4C6-U+E765*/ - w = 96*(c1 - 0xa1) + c - (c >= 0x80 ? 0x41 : 0x40) + 0xe4c6; - CK((*filter->output_function)(w, filter->data)); - } - - c2 = (c1 << 8) | c; - - if (w <= 0 && ( - (c2 >= 0xa2ab && c2 <= 0xa9f0 + (0xe80f-0xe801)) || - (c2 >= 0xd7fa && c2 <= 0xd7fa + (0xe814-0xe810)) || - (c2 >= 0xfe50 && c2 <= 0xfe80 + (0xe864-0xe844)) - )) { - for (size_t offset = 0; offset < mbfl_gb18030_pua_tbl_max; offset++) { - if (c2 >= mbfl_gb18030_pua_tbl[offset][2] && c2 <= mbfl_gb18030_pua_tbl[offset][2] + mbfl_gb18030_pua_tbl[offset][1] - mbfl_gb18030_pua_tbl[offset][0]) { - w = c2 - mbfl_gb18030_pua_tbl[offset][2] + mbfl_gb18030_pua_tbl[offset][0]; - CK((*filter->output_function)(w, filter->data)); - break; - } - } - } - - if (w <= 0) { - if ((c1 >= 0xa1 && c1 <= 0xa9 && c >= 0xa1 && c <= 0xfe) || - (c1 >= 0xb0 && c1 <= 0xf7 && c >= 0xa1 && c <= 0xfe) || - (c1 >= 0x81 && c1 <= 0xa0 && c >= 0x40 && c <= 0xfe && c != 0x7f) || - (c1 >= 0xaa && c1 <= 0xfe && c >= 0x40 && c <= 0xa0 && c != 0x7f) || - (c1 >= 0xa8 && c1 <= 0xa9 && c >= 0x40 && c <= 0xa0 && c != 0x7f)) { - w = (c1 - 0x81)*192 + c - 0x40; - ZEND_ASSERT(w < cp936_ucs_table_size); - CK((*filter->output_function)(cp936_ucs_table[w], filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - } - break; - - case 2: /* qbcs third byte */ - c1 = (filter->cache >> 8) & 0xff; - c2 = filter->cache & 0xff; - filter->status = filter->cache = 0; - if (((c1 >= 0x81 && c1 <= 0x84) || (c1 >= 0x90 && c1 <= 0xe3)) && c2 >= 0x30 && c2 <= 0x39 && c >= 0x81 && c <= 0xfe) { - filter->cache = (c1 << 16) | (c2 << 8) | c; - filter->status = 3; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 3: /* qbcs fourth byte */ - c1 = (filter->cache >> 16) & 0xff; - c2 = (filter->cache >> 8) & 0xff; - c3 = filter->cache & 0xff; - filter->status = filter->cache = 0; - if (((c1 >= 0x81 && c1 <= 0x84) || (c1 >= 0x90 && c1 <= 0xe3)) && c2 >= 0x30 && c2 <= 0x39 && c3 >= 0x81 && c3 <= 0xfe && c >= 0x30 && c <= 0x39) { - if (c1 >= 0x90 && c1 <= 0xe3) { - w = ((((c1 - 0x90)*10 + (c2 - 0x30))*126 + (c3 - 0x81)))*10 + (c - 0x30) + 0x10000; - if (w > 0x10FFFF) { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - return 0; - } - } else { /* Unicode BMP */ - w = (((c1 - 0x81)*10 + (c2 - 0x30))*126 + (c3 - 0x81))*10 + (c - 0x30); - if (w >= 0 && w <= 39419) { - int k = mbfl_bisec_srch(w, mbfl_gb2uni_tbl, mbfl_gb_uni_max); - w += mbfl_gb_uni_ofst[k]; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - return 0; - } - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_gb18030_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - /* multi-byte character was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_gb18030(int c, mbfl_convert_filter *filter) -{ - int k, k1, k2; - int c1, s = 0, s1 = 0; - - if (c >= ucs_a1_cp936_table_min && c < ucs_a1_cp936_table_max) { - if (c == 0x01f9) { - s = 0xa8bf; - } else { - s = ucs_a1_cp936_table[c - ucs_a1_cp936_table_min]; - } - } else if (c >= ucs_a2_cp936_table_min && c < ucs_a2_cp936_table_max) { - if (c == 0x20ac) { /* euro-sign */ - s = 0xa2e3; - } else { - s = ucs_a2_cp936_table[c - ucs_a2_cp936_table_min]; - } - } else if (c >= ucs_a3_cp936_table_min && c < ucs_a3_cp936_table_max) { - s = ucs_a3_cp936_table[c - ucs_a3_cp936_table_min]; - } else if (c >= ucs_i_cp936_table_min && c < ucs_i_cp936_table_max) { - s = ucs_i_cp936_table[c - ucs_i_cp936_table_min]; - } else if (c >= ucs_ci_cp936_table_min && c < ucs_ci_cp936_table_max) { - /* U+F900-FA2F CJK Compatibility Ideographs */ - if (c == 0xf92c) { - s = 0xfd9c; - } else if (c == 0xf979) { - s = 0xfd9d; - } else if (c == 0xf995) { - s = 0xfd9e; - } else if (c == 0xf9e7) { - s = 0xfd9f; - } else if (c == 0xf9f1) { - s = 0xfda0; - } else if (c >= 0xfa0c && c <= 0xfa29) { - s = ucs_ci_s_cp936_table[c - 0xfa0c]; - } - } else if (c >= ucs_cf_cp936_table_min && c < ucs_cf_cp936_table_max) { - /* FE30h CJK Compatibility Forms */ - s = ucs_cf_cp936_table[c - ucs_cf_cp936_table_min]; - } else if (c >= ucs_sfv_cp936_table_min && c < ucs_sfv_cp936_table_max) { - /* U+FE50-FE6F Small Form Variants */ - s = ucs_sfv_cp936_table[c - ucs_sfv_cp936_table_min]; - } else if (c >= ucs_hff_cp936_table_min && c < ucs_hff_cp936_table_max) { - /* U+FF00-FFFF HW/FW Forms */ - if (c == 0xff04) { - s = 0xa1e7; - } else if (c == 0xff5e) { - s = 0xa1ab; - } else if (c >= 0xff01 && c <= 0xff5d) { - s = c - 0xff01 + 0xa3a1; - } else if (c >= 0xffe0 && c <= 0xffe5) { - s = ucs_hff_s_cp936_table[c-0xffe0]; - } - } - - /* While GB18030 and CP936 are very similar, some mappings are different between these encodings; - * do a binary search in a table of differing codepoints to see if we have one */ - if (s <= 0 && c >= mbfl_gb18030_c_tbl_key[0] && c <= mbfl_gb18030_c_tbl_key[mbfl_gb18030_c_tbl_max-1]) { - k1 = mbfl_bisec_srch2(c, mbfl_gb18030_c_tbl_key, mbfl_gb18030_c_tbl_max); - if (k1 >= 0) { - s = mbfl_gb18030_c_tbl_val[k1]; - } - } - - if (c >= 0xe000 && c <= 0xe864) { /* PUA */ - if (c < 0xe766) { - if (c < 0xe4c6) { - c1 = c - 0xe000; - s = (c1 % 94) + 0xa1; - c1 /= 94; - s |= (c1 < 0x06 ? c1 + 0xaa : c1 + 0xf2) << 8; - } else { - c1 = c - 0xe4c6; - s = ((c1 / 96) + 0xa1) << 8; - c1 %= 96; - s |= c1 + (c1 >= 0x3f ? 0x41 : 0x40); - } - } else { - /* U+E766..U+E864 */ - k1 = 0; - k2 = mbfl_gb18030_pua_tbl_max; - while (k1 < k2) { - k = (k1 + k2) >> 1; - if (c < mbfl_gb18030_pua_tbl[k][0]) { - k2 = k; - } else if (c > mbfl_gb18030_pua_tbl[k][1]) { - k1 = k + 1; - } else { - s = c - mbfl_gb18030_pua_tbl[k][0] + mbfl_gb18030_pua_tbl[k][2]; - break; - } - } - } - } - - /* If we have not yet found a suitable mapping for this codepoint, it requires a 4-byte code */ - if (s <= 0 && c >= 0x0080 && c <= 0xffff) { - /* BMP */ - s = mbfl_bisec_srch(c, mbfl_uni2gb_tbl, mbfl_gb_uni_max); - if (s >= 0) { - c1 = c - mbfl_gb_uni_ofst[s]; - s = (c1 % 10) + 0x30; - c1 /= 10; - s |= ((c1 % 126) + 0x81) << 8; - c1 /= 126; - s |= ((c1 % 10) + 0x30) << 16; - c1 /= 10; - s1 = c1 + 0x81; - } - } else if (c >= 0x10000 && c <= 0x10ffff) { - /* Code set 3: Unicode U+10000..U+10FFFF */ - c1 = c - 0x10000; - s = (c1 % 10) + 0x30; - c1 /= 10; - s |= ((c1 % 126) + 0x81) << 8; - c1 /= 126; - s |= ((c1 % 10) + 0x30) << 16; - c1 /= 10; - s1 = c1 + 0x90; - } - - if (c == 0) { - s = 0; - } else if (s == 0) { - s = -1; - } - - if (s >= 0) { - if (s <= 0x80) { /* latin */ - CK((*filter->output_function)(s, filter->data)); - } else if (s1 > 0) { /* qbcs */ - CK((*filter->output_function)(s1 & 0xff, filter->data)); - CK((*filter->output_function)((s >> 16) & 0xff, filter->data)); - CK((*filter->output_function)((s >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s & 0xff, filter->data)); - } else { /* dbcs */ - CK((*filter->output_function)((s >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s & 0xff, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - static const unsigned short gb18030_pua_tbl3[] = { /* 0xFE50 */ 0x0000,0xE816,0xE817,0xE818,0x0000,0x0000,0x0000,0x0000, @@ -11183,217 +8224,38 @@ static void mb_wchar_to_gb18030(uint32_t *in, size_t len, mb_convert_buf *buf, b s = (c1 % 10) + 0x30; c1 /= 10; s |= ((c1 % 126) + 0x81) << 8; - c1 /= 126; - s |= ((c1 % 10) + 0x30) << 16; - c1 /= 10; - s |= (c1 + 0x81) << 24; - } - } else if (w >= 0x10000 && w <= 0x10FFFF) { - /* Code set 3: Unicode U+10000-U+10FFFF */ - unsigned int c1 = w - 0x10000; - s = (c1 % 10) + 0x30; - c1 /= 10; - s |= ((c1 % 126) + 0x81) << 8; - c1 /= 126; - s |= ((c1 % 10) + 0x30) << 16; - c1 /= 10; - s |= (c1 + 0x90) << 24; - } - - if (!s) { - MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_gb18030); - MB_CONVERT_BUF_ENSURE(buf, out, limit, len); - } else if (s < 0x80) { - out = mb_convert_buf_add(out, s); - } else if (s > 0xFFFFFF) { - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); - out = mb_convert_buf_add4(out, (s >> 24) & 0xFF, (s >> 16) & 0xFF, (s >> 8) & 0xFF, s & 0xFF); - } else { - MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); - out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); - } - } - - MB_CONVERT_BUF_STORE(buf, out, limit); -} - -static int mbfl_filt_conv_cp936_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, c2, w = -1; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (c == 0x80) { /* euro sign */ - CK((*filter->output_function)(0x20ac, filter->data)); - } else if (c < 0xff) { /* dbcs lead byte */ - filter->status = 1; - filter->cache = c; - } else { /* 0xff */ - CK((*filter->output_function)(0xf8f5, filter->data)); - } - break; - - case 1: /* dbcs second byte */ - filter->status = 0; - c1 = filter->cache; - - if (((c1 >= 0xaa && c1 <= 0xaf) || (c1 >= 0xf8 && c1 <= 0xfe)) && - (c >= 0xa1 && c <= 0xfe)) { - /* UDA part1,2: U+E000-U+E4C5 */ - w = 94*(c1 >= 0xf8 ? c1 - 0xf2 : c1 - 0xaa) + (c - 0xa1) + 0xe000; - CK((*filter->output_function)(w, filter->data)); - } else if (c1 >= 0xa1 && c1 <= 0xa7 && c >= 0x40 && c < 0xa1 && c != 0x7f) { - /* UDA part3 : U+E4C6-U+E765*/ - w = 96*(c1 - 0xa1) + c - (c >= 0x80 ? 0x41 : 0x40) + 0xe4c6; - CK((*filter->output_function)(w, filter->data)); - } - - c2 = (c1 << 8) | c; - - if (w <= 0 && ( - (c2 >= 0xa2ab && c2 <= 0xa9f0 + (0xe80f-0xe801)) || - (c2 >= 0xd7fa && c2 <= 0xd7fa + (0xe814-0xe810)) || - (c2 >= 0xfe50 && c2 <= 0xfe80 + (0xe864-0xe844)) - )) { - size_t k; - for (k = 0; k < mbfl_cp936_pua_tbl_max; k++) { - if (c2 >= mbfl_cp936_pua_tbl[k][2] && - c2 <= mbfl_cp936_pua_tbl[k][2] + - mbfl_cp936_pua_tbl[k][1] - mbfl_cp936_pua_tbl[k][0]) { - w = c2 - mbfl_cp936_pua_tbl[k][2] + mbfl_cp936_pua_tbl[k][0]; - CK((*filter->output_function)(w, filter->data)); - break; - } - } - } - - if (w <= 0) { - if (c1 < 0xff && c1 > 0x80 && c >= 0x40 && c < 0xff && c != 0x7f) { - w = (c1 - 0x81)*192 + c - 0x40; - ZEND_ASSERT(w < cp936_ucs_table_size); - CK((*filter->output_function)(cp936_ucs_table[w], filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_cp936_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - /* 2-byte character was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_cp936(int c, mbfl_convert_filter *filter) -{ - int k, k1, k2; - int c1, s = 0; - - if (c >= ucs_a1_cp936_table_min && c < ucs_a1_cp936_table_max) { - /* U+0000 - U+0451 */ - s = ucs_a1_cp936_table[c - ucs_a1_cp936_table_min]; - } else if (c >= ucs_a2_cp936_table_min && c < ucs_a2_cp936_table_max) { - /* U+2000 - U+26FF */ - if (c == 0x203e) { - s = 0xa3fe; - } else if (c == 0x2218) { - s = 0xa1e3; - } else if (c == 0x223c) { - s = 0xa1ab; - } else { - s = ucs_a2_cp936_table[c - ucs_a2_cp936_table_min]; - } - } else if (c >= ucs_a3_cp936_table_min && c < ucs_a3_cp936_table_max) { - /* U+2F00 - U+33FF */ - s = ucs_a3_cp936_table[c - ucs_a3_cp936_table_min]; - } else if (c >= ucs_i_cp936_table_min && c < ucs_i_cp936_table_max) { - /* U+4D00-9FFF CJK Unified Ideographs (+ Extension A) */ - s = ucs_i_cp936_table[c - ucs_i_cp936_table_min]; - } else if (c >= 0xe000 && c <= 0xe864) { /* PUA */ - if (c < 0xe766) { - if (c < 0xe4c6) { - c1 = c - 0xe000; - s = (c1 % 94) + 0xa1; c1 /= 94; - s |= (c1 < 0x06 ? c1 + 0xaa : c1 + 0xf2) << 8; - } else { - c1 = c - 0xe4c6; - s = ((c1 / 96) + 0xa1) << 8; c1 %= 96; - s |= c1 + (c1 >= 0x3f ? 0x41 : 0x40); - } - } else { - /* U+E766..U+E864 */ - k1 = 0; k2 = mbfl_cp936_pua_tbl_max; - while (k1 < k2) { - k = (k1 + k2) >> 1; - if (c < mbfl_cp936_pua_tbl[k][0]) { - k2 = k; - } else if (c > mbfl_cp936_pua_tbl[k][1]) { - k1 = k + 1; - } else { - s = c - mbfl_cp936_pua_tbl[k][0] + mbfl_cp936_pua_tbl[k][2]; - break; - } + c1 /= 126; + s |= ((c1 % 10) + 0x30) << 16; + c1 /= 10; + s |= (c1 + 0x81) << 24; } + } else if (w >= 0x10000 && w <= 0x10FFFF) { + /* Code set 3: Unicode U+10000-U+10FFFF */ + unsigned int c1 = w - 0x10000; + s = (c1 % 10) + 0x30; + c1 /= 10; + s |= ((c1 % 126) + 0x81) << 8; + c1 /= 126; + s |= ((c1 % 10) + 0x30) << 16; + c1 /= 10; + s |= (c1 + 0x90) << 24; } - } else if (c == 0xf8f5) { - s = 0xff; - } else if (c >= ucs_ci_cp936_table_min && c < ucs_ci_cp936_table_max) { - /* U+F900-FA2F CJK Compatibility Ideographs */ - s = ucs_ci_cp936_table[c - ucs_ci_cp936_table_min]; - } else if (c >= ucs_cf_cp936_table_min && c < ucs_cf_cp936_table_max) { - s = ucs_cf_cp936_table[c - ucs_cf_cp936_table_min]; - } else if (c >= ucs_sfv_cp936_table_min && c < ucs_sfv_cp936_table_max) { - s = ucs_sfv_cp936_table[c - ucs_sfv_cp936_table_min]; /* U+FE50-FE6F Small Form Variants */ - } else if (c >= ucs_hff_cp936_table_min && c < ucs_hff_cp936_table_max) { - /* U+FF00-FFFF HW/FW Forms */ - if (c == 0xff04) { - s = 0xa1e7; - } else if (c == 0xff5e) { - s = 0xa1ab; - } else if (c >= 0xff01 && c <= 0xff5d) { - s = c - 0xff01 + 0xa3a1; - } else if (c >= 0xffe0 && c <= 0xffe5) { - s = ucs_hff_s_cp936_table[c-0xffe0]; - } - } - - if (s <= 0) { - if (c == 0) { - s = 0; - } else if (s <= 0) { - s = -1; - } - } - if (s >= 0) { - if (s <= 0x80 || s == 0xff) { /* latin */ - CK((*filter->output_function)(s, filter->data)); + if (!s) { + MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_gb18030); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len); + } else if (s < 0x80) { + out = mb_convert_buf_add(out, s); + } else if (s > 0xFFFFFF) { + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 4); + out = mb_convert_buf_add4(out, (s >> 24) & 0xFF, (s >> 16) & 0xFF, (s >> 8) & 0xFF, s & 0xFF); } else { - CK((*filter->output_function)((s >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s & 0xff, filter->data)); + MB_CONVERT_BUF_ENSURE(buf, out, limit, len + 2); + out = mb_convert_buf_add2(out, (s >> 8) & 0xFF, s & 0xFF); } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); } - return 0; + MB_CONVERT_BUF_STORE(buf, out, limit); } static size_t mb_cp936_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) @@ -11915,26 +8777,6 @@ static zend_string* mb_cut_gb18030(unsigned char *str, size_t from, size_t len, static const char *mbfl_encoding_gb18030_aliases[] = {"gb-18030", "gb-18030-2000", NULL}; -static const struct mbfl_convert_vtbl vtbl_gb18030_wchar = { - mbfl_no_encoding_gb18030, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_gb18030_wchar, - mbfl_filt_conv_gb18030_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_gb18030 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_gb18030, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_gb18030, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_gb18030 = { mbfl_no_encoding_gb18030, "GB18030", @@ -11942,8 +8784,8 @@ const mbfl_encoding mbfl_encoding_gb18030 = { mbfl_encoding_gb18030_aliases, NULL, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_gb18030_wchar, - &vtbl_wchar_gb18030, + NULL, + NULL, mb_gb18030_to_wchar, mb_wchar_to_gb18030, NULL, @@ -11952,26 +8794,6 @@ const mbfl_encoding mbfl_encoding_gb18030 = { static const char *mbfl_encoding_cp936_aliases[] = {"CP-936", "GBK", NULL}; -static const struct mbfl_convert_vtbl vtbl_cp936_wchar = { - mbfl_no_encoding_cp936, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_cp936_wchar, - mbfl_filt_conv_cp936_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_cp936 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_cp936, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_cp936, - mbfl_filt_conv_common_flush, - NULL, -}; - const mbfl_encoding mbfl_encoding_cp936 = { mbfl_no_encoding_cp936, "CP936", @@ -11979,8 +8801,8 @@ const mbfl_encoding mbfl_encoding_cp936 = { mbfl_encoding_cp936_aliases, mblen_table_81_to_fe, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_cp936_wchar, - &vtbl_wchar_cp936, + NULL, + NULL, mb_cp936_to_wchar, mb_wchar_to_cp936, NULL, @@ -12025,247 +8847,6 @@ static inline int is_in_cp950_pua(int c1, int c) return 0; } -static int mbfl_filt_conv_big5_wchar(int c, mbfl_convert_filter *filter) -{ - int c1, w; - - switch (filter->status) { - case 0: - if (c >= 0 && c < 0x80) { /* latin */ - CK((*filter->output_function)(c, filter->data)); - } else if (filter->from->no_encoding != mbfl_no_encoding_cp950 && c > 0xA0 && c <= 0xF9 && c != 0xC8) { - filter->status = 1; - filter->cache = c; - } else if (filter->from->no_encoding == mbfl_no_encoding_cp950 && c > 0x80 && c <= 0xFE) { - filter->status = 1; - filter->cache = c; - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - case 1: /* dbcs second byte */ - filter->status = 0; - c1 = filter->cache; - if ((c > 0x3f && c < 0x7f) || (c > 0xa0 && c < 0xff)) { - if (c < 0x7f) { - w = (c1 - 0xa1)*157 + (c - 0x40); - } else { - w = (c1 - 0xa1)*157 + (c - 0xa1) + 0x3f; - } - if (w >= 0 && w < big5_ucs_table_size) { - w = big5_ucs_table[w]; - } else { - w = 0; - } - - if (filter->from->no_encoding == mbfl_no_encoding_cp950) { - /* PUA for CP950 */ - if (is_in_cp950_pua(c1, c)) { - int c2 = (c1 << 8) | c; - - size_t k; - for (k = 0; k < sizeof(cp950_pua_tbl) / (sizeof(unsigned short)*4); k++) { - if (c2 >= cp950_pua_tbl[k][2] && c2 <= cp950_pua_tbl[k][3]) { - break; - } - } - - if ((cp950_pua_tbl[k][2] & 0xff) == 0x40) { - w = 157*(c1 - (cp950_pua_tbl[k][2]>>8)) + c - (c >= 0xa1 ? 0x62 : 0x40) + cp950_pua_tbl[k][0]; - } else { - w = c2 - cp950_pua_tbl[k][2] + cp950_pua_tbl[k][0]; - } - } else if (c1 == 0xA1) { - if (c == 0x45) { - w = 0x2027; - } else if (c == 0x4E) { - w = 0xFE51; - } else if (c == 0x5A) { - w = 0x2574; - } else if (c == 0xC2) { - w = 0x00AF; - } else if (c == 0xC3) { - w = 0xFFE3; - } else if (c == 0xC5) { - w = 0x02CD; - } else if (c == 0xE3) { - w = 0xFF5E; - } else if (c == 0xF2) { - w = 0x2295; - } else if (c == 0xF3) { - w = 0x2299; - } else if (c == 0xFE) { - w = 0xFF0F; - } - } else if (c1 == 0xA2) { - if (c == 0x40) { - w = 0xFF3C; - } else if (c == 0x41) { - w = 0x2215; - } else if (c == 0x42) { - w = 0xFE68; - } else if (c == 0x46) { - w = 0xFFE0; - } else if (c == 0x47) { - w = 0xFFE1; - } else if (c == 0xCC) { - w = 0x5341; - } else if (c == 0xCE) { - w = 0x5345; - } - } - } - - if (w <= 0) { - w = MBFL_BAD_INPUT; - } - CK((*filter->output_function)(w, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_big5_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status == 1) { - /* 2-byte character was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_big5(int c, mbfl_convert_filter *filter) -{ - int s = 0; - - if (c >= ucs_a1_big5_table_min && c < ucs_a1_big5_table_max) { - s = ucs_a1_big5_table[c - ucs_a1_big5_table_min]; - } else if (c >= ucs_a2_big5_table_min && c < ucs_a2_big5_table_max) { - s = ucs_a2_big5_table[c - ucs_a2_big5_table_min]; - } else if (c >= ucs_a3_big5_table_min && c < ucs_a3_big5_table_max) { - s = ucs_a3_big5_table[c - ucs_a3_big5_table_min]; - } else if (c >= ucs_i_big5_table_min && c < ucs_i_big5_table_max) { - s = ucs_i_big5_table[c - ucs_i_big5_table_min]; - } else if (c >= ucs_r1_big5_table_min && c < ucs_r1_big5_table_max) { - s = ucs_r1_big5_table[c - ucs_r1_big5_table_min]; - } else if (c >= ucs_r2_big5_table_min && c < ucs_r2_big5_table_max) { - s = ucs_r2_big5_table[c - ucs_r2_big5_table_min]; - } - - if (filter->to->no_encoding == mbfl_no_encoding_cp950) { - if (c >= 0xe000 && c <= 0xf848) { /* PUA for CP950 */ - size_t k; - for (k = 0; k < sizeof(cp950_pua_tbl) / (sizeof(unsigned short)*4); k++) { - if (c <= cp950_pua_tbl[k][1]) { - break; - } - } - - int c1 = c - cp950_pua_tbl[k][0]; - if ((cp950_pua_tbl[k][2] & 0xff) == 0x40) { - int c2 = cp950_pua_tbl[k][2] >> 8; - s = ((c1 / 157) + c2) << 8; - c1 %= 157; - s |= c1 + (c1 >= 0x3f ? 0x62 : 0x40); - } else { - s = c1 + cp950_pua_tbl[k][2]; - } - } else if (c == 0x00A2) { - s = 0; - } else if (c == 0x00A3) { - s = 0; - } else if (c == 0x00AF) { - s = 0xA1C2; - } else if (c == 0x02CD) { - s = 0xA1C5; - } else if (c == 0x0401) { - s = 0; - } else if (c >= 0x0414 && c <= 0x041C) { - s = 0; - } else if (c >= 0x0423 && c <= 0x044F) { - s = 0; - } else if (c == 0x0451) { - s = 0; - } else if (c == 0x2022) { - s = 0; - } else if (c == 0x2027) { - s = 0xA145; - } else if (c == 0x203E) { - s = 0; - } else if (c == 0x2215) { - s = 0xA241; - } else if (c == 0x223C) { - s = 0; - } else if (c == 0x2295) { - s = 0xA1F2; - } else if (c == 0x2299) { - s = 0xA1F3; - } else if (c >= 0x2460 && c <= 0x247D) { - s = 0; - } else if (c == 0x2574) { - s = 0xA15A; - } else if (c == 0x2609) { - s = 0; - } else if (c == 0x2641) { - s = 0; - } else if (c == 0x3005 || (c >= 0x302A && c <= 0x30FF)) { - s = 0; - } else if (c == 0xFE51) { - s = 0xA14E; - } else if (c == 0xFE68) { - s = 0xA242; - } else if (c == 0xFF3C) { - s = 0xA240; - } else if (c == 0xFF5E) { - s = 0xA1E3; - } else if (c == 0xFF64) { - s = 0; - } else if (c == 0xFFE0) { - s = 0xA246; - } else if (c == 0xFFE1) { - s = 0xA247; - } else if (c == 0xFFE3) { - s = 0xA1C3; - } else if (c == 0xFF0F) { - s = 0xA1FE; - } - } - - if (s <= 0) { - if (c == 0) { - s = 0; - } else { - s = -1; - } - } - - if (s >= 0) { - if (s <= 0x80) { /* latin */ - CK((*filter->output_function)(s, filter->data)); - } else { - CK((*filter->output_function)((s >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(s & 0xff, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - static size_t mb_big5_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -12539,26 +9120,6 @@ static void mb_wchar_to_cp950(uint32_t *in, size_t len, mb_convert_buf *buf, boo static const char *mbfl_encoding_big5_aliases[] = {"CN-BIG5", "BIG-FIVE", "BIGFIVE", NULL}; -static const struct mbfl_convert_vtbl vtbl_big5_wchar = { - mbfl_no_encoding_big5, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_big5_wchar, - mbfl_filt_conv_big5_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_big5 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_big5, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_big5, - mbfl_filt_conv_common_flush, - NULL -}; - const mbfl_encoding mbfl_encoding_big5 = { mbfl_no_encoding_big5, "BIG-5", @@ -12566,31 +9127,11 @@ const mbfl_encoding mbfl_encoding_big5 = { mbfl_encoding_big5_aliases, mblen_table_81_to_fe, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_big5_wchar, - &vtbl_wchar_big5, - mb_big5_to_wchar, - mb_wchar_to_big5, NULL, NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_cp950_wchar = { - mbfl_no_encoding_cp950, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_big5_wchar, - mbfl_filt_conv_big5_wchar_flush, - NULL, -}; - -static const struct mbfl_convert_vtbl vtbl_wchar_cp950 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_cp950, - mbfl_filt_conv_common_ctor, + mb_big5_to_wchar, + mb_wchar_to_big5, NULL, - mbfl_filt_conv_wchar_big5, - mbfl_filt_conv_common_flush, NULL, }; @@ -12601,8 +9142,8 @@ const mbfl_encoding mbfl_encoding_cp950 = { NULL, mblen_table_81_to_fe, MBFL_ENCTYPE_GL_UNSAFE, - &vtbl_cp950_wchar, - &vtbl_wchar_cp950, + NULL, + NULL, mb_cp950_to_wchar, mb_wchar_to_cp950, NULL, @@ -12682,7 +9223,7 @@ static int mbfl_filt_conv_hz_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cjk.h b/ext/mbstring/libmbfl/filters/mbfilter_cjk.h index bb0e672bef44..f7e2184986c1 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cjk.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_cjk.h @@ -42,8 +42,4 @@ int mbfilter_sjis_emoji_docomo2unicode(int s, int *snd); int mbfilter_sjis_emoji_kddi2unicode(int s, int *snd); int mbfilter_sjis_emoji_sb2unicode(int s, int *snd); -int mbfilter_unicode2sjis_emoji_docomo(int c, int *s1, mbfl_convert_filter *filter); -int mbfilter_unicode2sjis_emoji_kddi_sjis(int c, int *s1, mbfl_convert_filter *filter); -int mbfilter_unicode2sjis_emoji_sb(int c, int *s1, mbfl_convert_filter *filter); - #endif /* MBFL_MBFILTER_CJK_H */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.h b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.h index f48ec7cb3d4c..6729edb272d6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.h @@ -33,10 +33,5 @@ #include "mbfilter.h" extern const mbfl_encoding mbfl_encoding_cp51932; -extern const struct mbfl_convert_vtbl vtbl_cp51932_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_cp51932; - -int mbfl_filt_conv_cp51932_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_cp51932(int c, mbfl_convert_filter *filter); #endif /* MBFL_MBFILTER_CP51932_H */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.c b/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.c index 7ced00fa536e..d8a536c0eea0 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -21,61 +19,10 @@ static inline uint32_t coalesce(uint32_t a, uint32_t b) return a ? a : b; } -/* Helper for single-byte encodings which use a conversion table */ -static int mbfl_conv_singlebyte_table(int c, mbfl_convert_filter *filter, int tbl_min, const unsigned short tbl[]) -{ - if (c >= 0 && c < tbl_min) { - CK((*filter->output_function)(c, filter->data)); - } else if (c < 0) { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } else { - CK((*filter->output_function)(coalesce(tbl[c - tbl_min], MBFL_BAD_INPUT), filter->data)); - } - return 0; -} - -static int mbfl_conv_reverselookup_table(int c, mbfl_convert_filter *filter, int tbl_min, const unsigned short tbl[]) -{ - if (c >= 0 && c < tbl_min) { - CK((*filter->output_function)(c, filter->data)); - } else if (c < 0 || c == MBFL_BAD_INPUT) { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } else { - for (int i = 0; i < 256 - tbl_min; i++) { - if (c == tbl[i]) { - CK((*filter->output_function)(i + tbl_min, filter->data)); - return 0; - } - } - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - /* Initialize data structures for a single-byte encoding */ #define DEF_SB(id, name, mime_name, aliases) \ - static int mbfl_filt_conv_##id##_wchar(int c, mbfl_convert_filter *filter); \ - static int mbfl_filt_conv_wchar_##id(int c, mbfl_convert_filter *filter); \ static size_t mb_##id##_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); \ static void mb_wchar_to_##id(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); \ - static const struct mbfl_convert_vtbl vtbl_##id##_wchar = { \ - mbfl_no_encoding_##id, \ - mbfl_no_encoding_wchar, \ - mbfl_filt_conv_common_ctor, \ - NULL, \ - mbfl_filt_conv_##id##_wchar, \ - mbfl_filt_conv_common_flush, \ - NULL \ - }; \ - static const struct mbfl_convert_vtbl vtbl_wchar_##id = { \ - mbfl_no_encoding_wchar, \ - mbfl_no_encoding_##id, \ - mbfl_filt_conv_common_ctor, \ - NULL, \ - mbfl_filt_conv_wchar_##id, \ - mbfl_filt_conv_common_flush, \ - NULL \ - }; \ const mbfl_encoding mbfl_encoding_##id = { \ mbfl_no_encoding_##id, \ name, \ @@ -83,8 +30,8 @@ static int mbfl_conv_reverselookup_table(int c, mbfl_convert_filter *filter, int aliases, \ NULL, \ MBFL_ENCTYPE_SBCS, \ - &vtbl_##id##_wchar, \ - &vtbl_wchar_##id, \ + NULL, \ + NULL, \ mb_##id##_to_wchar, \ mb_wchar_to_##id, \ NULL, \ @@ -93,12 +40,6 @@ static int mbfl_conv_reverselookup_table(int c, mbfl_convert_filter *filter, int /* For single-byte encodings which use a conversion table */ #define DEF_SB_TBL(id, name, mime_name, aliases, tbl_min, tbl) \ - static int mbfl_filt_conv_##id##_wchar(int c, mbfl_convert_filter *filter) { \ - return mbfl_conv_singlebyte_table(c, filter, tbl_min, tbl); \ - } \ - static int mbfl_filt_conv_wchar_##id(int c, mbfl_convert_filter *filter) { \ - return mbfl_conv_reverselookup_table(c, filter, tbl_min, tbl); \ - } \ static size_t mb_##id##_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) \ { \ unsigned char *p = *in, *e = p + *in_len; \ @@ -140,22 +81,6 @@ static int mbfl_conv_reverselookup_table(int c, mbfl_convert_filter *filter, int static const char *ascii_aliases[] = {"ANSI_X3.4-1968", "iso-ir-6", "ANSI_X3.4-1986", "ISO_646.irv:1991", "US-ASCII", "ISO646-US", "us", "IBM367", "IBM-367", "cp367", "csASCII", NULL}; DEF_SB(ascii, "ASCII", "US-ASCII", ascii_aliases); -static int mbfl_filt_conv_ascii_wchar(int c, mbfl_convert_filter *filter) -{ - CK((*filter->output_function)((c < 0x80) ? c : MBFL_BAD_INPUT, filter->data)); - return 0; -} - -static int mbfl_filt_conv_wchar_ascii(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < 0x80 && c != MBFL_BAD_INPUT) { - CK((*filter->output_function)(c, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - static size_t mb_ascii_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -195,21 +120,6 @@ static void mb_wchar_to_ascii(uint32_t *in, size_t len, mb_convert_buf *buf, boo static const char *iso8859_1_aliases[] = {"ISO8859-1", "latin1", NULL}; DEF_SB(8859_1, "ISO-8859-1", "ISO-8859-1", iso8859_1_aliases); -static int mbfl_filt_conv_8859_1_wchar(int c, mbfl_convert_filter *filter) -{ - return (*filter->output_function)(c, filter->data); -} - -static int mbfl_filt_conv_wchar_8859_1(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < 0x100 && c != MBFL_BAD_INPUT) { - CK((*filter->output_function)(c, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - static size_t mb_8859_1_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -494,38 +404,6 @@ static const unsigned short cp1252_ucs_table[] = { }; DEF_SB(cp1252, "Windows-1252", "Windows-1252", cp1252_aliases); -static int mbfl_filt_conv_wchar_cp1252(int c, mbfl_convert_filter *filter) -{ - if (c < 0 || c == MBFL_BAD_INPUT) { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } else if (c >= 0x100) { - for (int n = 0; n < 32; n++) { - if (c == cp1252_ucs_table[n]) { - CK((*filter->output_function)(0x80 + n, filter->data)); - return 0; - } - } - CK(mbfl_filt_conv_illegal_output(c, filter)); - } else if (c <= 0x7F || c >= 0xA0 || c == 0x81 || c == 0x8D || c == 0x8F || c == 0x90 || c == 0x9D) { - CK((*filter->output_function)(c, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - -static int mbfl_filt_conv_cp1252_wchar(int c, mbfl_convert_filter *filter) -{ - int s; - if (c >= 0x80 && c < 0xA0) { - s = coalesce(cp1252_ucs_table[c - 0x80], MBFL_BAD_INPUT); - } else { - s = c; - } - CK((*filter->output_function)(s, filter->data)); - return 0; -} - static size_t mb_cp1252_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -701,32 +579,6 @@ static const unsigned char ucs_armscii8_table[] = { }; DEF_SB(armscii8, "ArmSCII-8", "ArmSCII-8", armscii8_aliases); -static int mbfl_filt_conv_armscii8_wchar(int c, mbfl_convert_filter *filter) -{ - CK((*filter->output_function)((c < 0xA0) ? c : coalesce(armscii8_ucs_table[c - 0xA0], MBFL_BAD_INPUT), filter->data)); - return 0; -} - -static int mbfl_filt_conv_wchar_armscii8(int c, mbfl_convert_filter *filter) -{ - if (c >= 0x28 && c <= 0x2F) { - CK((*filter->output_function)(ucs_armscii8_table[c - 0x28], filter->data)); - } else if (c < 0 || c == MBFL_BAD_INPUT) { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } else if (c < 0xA0) { - CK((*filter->output_function)(c, filter->data)); - } else { - for (int n = 0; n < 0x60; n++) { - if (c == armscii8_ucs_table[n]) { - CK((*filter->output_function)(0xA0 + n, filter->data)); - return 0; - } - } - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - static size_t mb_armscii8_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h b/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h index 5cf331a51c7d..775ababfde08 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_singlebyte.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c index 01b569482b60..763941225355 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c @@ -30,7 +30,6 @@ #include "mbfilter.h" #include "mbfilter_ucs2.h" -static int mbfl_filt_conv_ucs2_wchar_flush(mbfl_convert_filter *filter); static size_t mb_ucs2_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static size_t mb_ucs2be_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static void mb_wchar_to_ucs2be(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); @@ -53,8 +52,8 @@ const mbfl_encoding mbfl_encoding_ucs2 = { mbfl_encoding_ucs2_aliases, NULL, MBFL_ENCTYPE_WCS2, - &vtbl_ucs2_wchar, - &vtbl_wchar_ucs2, + NULL, + NULL, mb_ucs2_to_wchar, mb_wchar_to_ucs2be, NULL, @@ -68,8 +67,8 @@ const mbfl_encoding mbfl_encoding_ucs2be = { mbfl_encoding_ucs2be_aliases, NULL, MBFL_ENCTYPE_WCS2, - &vtbl_ucs2be_wchar, - &vtbl_wchar_ucs2be, + NULL, + NULL, mb_ucs2be_to_wchar, mb_wchar_to_ucs2be, NULL, @@ -83,158 +82,14 @@ const mbfl_encoding mbfl_encoding_ucs2le = { mbfl_encoding_ucs2le_aliases, NULL, MBFL_ENCTYPE_WCS2, - &vtbl_ucs2le_wchar, - &vtbl_wchar_ucs2le, - mb_ucs2le_to_wchar, - mb_wchar_to_ucs2le, NULL, NULL, -}; - -const struct mbfl_convert_vtbl vtbl_ucs2_wchar = { - mbfl_no_encoding_ucs2, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_ucs2_wchar, - mbfl_filt_conv_ucs2_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_ucs2 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_ucs2, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_ucs2be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_ucs2be_wchar = { - mbfl_no_encoding_ucs2be, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_ucs2be_wchar, - mbfl_filt_conv_ucs2_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_ucs2be = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_ucs2be, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_ucs2be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_ucs2le_wchar = { - mbfl_no_encoding_ucs2le, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_ucs2le_wchar, - mbfl_filt_conv_ucs2_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_ucs2le = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_ucs2le, - mbfl_filt_conv_common_ctor, + mb_ucs2le_to_wchar, + mb_wchar_to_ucs2le, NULL, - mbfl_filt_conv_wchar_ucs2le, - mbfl_filt_conv_common_flush, NULL, }; -#define CK(statement) do { if ((statement) < 0) return (-1); } while (0) - -int mbfl_filt_conv_ucs2_wchar(int c, mbfl_convert_filter *filter) -{ - if (filter->status == 0) { - filter->status = 1; - filter->cache = c & 0xFF; - } else { - filter->status = 0; - int n = (filter->cache << 8) | (c & 0xFF); - if (n == 0xFFFE) { - /* Found little-endian byte order mark */ - filter->filter_function = mbfl_filt_conv_ucs2le_wchar; - } else { - filter->filter_function = mbfl_filt_conv_ucs2be_wchar; - if (n != 0xFEFF) { - CK((*filter->output_function)(n, filter->data)); - } - } - } - return 0; -} - -int mbfl_filt_conv_ucs2be_wchar(int c, mbfl_convert_filter *filter) -{ - if (filter->status == 0) { - filter->status = 1; - filter->cache = (c & 0xFF) << 8; - } else { - filter->status = 0; - CK((*filter->output_function)((c & 0xFF) | filter->cache, filter->data)); - } - return 0; -} - -int mbfl_filt_conv_wchar_ucs2be(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < MBFL_WCSPLANE_UCS2MAX) { - CK((*filter->output_function)((c >> 8) & 0xFF, filter->data)); - CK((*filter->output_function)(c & 0xFF, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - -int mbfl_filt_conv_ucs2le_wchar(int c, mbfl_convert_filter *filter) -{ - if (filter->status == 0) { - filter->status = 1; - filter->cache = c & 0xFF; - } else { - filter->status = 0; - CK((*filter->output_function)(((c & 0xFF) << 8) | filter->cache, filter->data)); - } - return 0; -} - -int mbfl_filt_conv_wchar_ucs2le(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < MBFL_WCSPLANE_UCS2MAX) { - CK((*filter->output_function)(c & 0xFF, filter->data)); - CK((*filter->output_function)((c >> 8) & 0xFF, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - return 0; -} - -static int mbfl_filt_conv_ucs2_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - /* Input string was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - #define DETECTED_BE 1 #define DETECTED_LE 2 diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.h b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.h index bbf567a49339..7e2993d8fbb5 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.h @@ -35,17 +35,5 @@ extern const mbfl_encoding mbfl_encoding_ucs2; extern const mbfl_encoding mbfl_encoding_ucs2be; extern const mbfl_encoding mbfl_encoding_ucs2le; -extern const struct mbfl_convert_vtbl vtbl_ucs2_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_ucs2; -extern const struct mbfl_convert_vtbl vtbl_ucs2be_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_ucs2be; -extern const struct mbfl_convert_vtbl vtbl_ucs2le_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_ucs2le; - -int mbfl_filt_conv_ucs2_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_ucs2be_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_ucs2be(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_ucs2le_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_ucs2le(int c, mbfl_convert_filter *filter); #endif /* MBFL_MBFILTER_UCS2_H */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c index 10b57061f7d9..1731eb48add7 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c @@ -44,8 +44,6 @@ static const char *mbfl_encoding_ucs4_aliases[] = {"ISO-10646-UCS-4", "UCS4", NU static const char *mbfl_encoding_ucs4be_aliases[] = {"byte4be", NULL}; static const char *mbfl_encoding_ucs4le_aliases[] = {"byte4le", NULL}; -static int mbfl_filt_conv_ucs4_wchar_flush(mbfl_convert_filter *filter); - const mbfl_encoding mbfl_encoding_ucs4 = { mbfl_no_encoding_ucs4, "UCS-4", @@ -53,8 +51,8 @@ const mbfl_encoding mbfl_encoding_ucs4 = { mbfl_encoding_ucs4_aliases, NULL, MBFL_ENCTYPE_WCS4, - &vtbl_ucs4_wchar, - &vtbl_wchar_ucs4, + NULL, + NULL, mb_ucs4_to_wchar, mb_wchar_to_ucs4be, NULL, @@ -68,8 +66,8 @@ const mbfl_encoding mbfl_encoding_ucs4be = { mbfl_encoding_ucs4be_aliases, NULL, MBFL_ENCTYPE_WCS4, - &vtbl_ucs4be_wchar, - &vtbl_wchar_ucs4be, + NULL, + NULL, mb_ucs4be_to_wchar, mb_wchar_to_ucs4be, NULL, @@ -83,239 +81,14 @@ const mbfl_encoding mbfl_encoding_ucs4le = { mbfl_encoding_ucs4le_aliases, NULL, MBFL_ENCTYPE_WCS4, - &vtbl_ucs4le_wchar, - &vtbl_wchar_ucs4le, - mb_ucs4le_to_wchar, - mb_wchar_to_ucs4le, - NULL, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_ucs4_wchar = { - mbfl_no_encoding_ucs4, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_ucs4_wchar, - mbfl_filt_conv_ucs4_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_ucs4 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_ucs4, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_ucs4be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_ucs4be_wchar = { - mbfl_no_encoding_ucs4be, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_ucs4be_wchar, - mbfl_filt_conv_ucs4_wchar_flush, NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_ucs4be = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_ucs4be, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_ucs4be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_ucs4le_wchar = { - mbfl_no_encoding_ucs4le, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_ucs4le_wchar, - mbfl_filt_conv_ucs4_wchar_flush, NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_ucs4le = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_ucs4le, - mbfl_filt_conv_common_ctor, + mb_ucs4le_to_wchar, + mb_wchar_to_ucs4le, NULL, - mbfl_filt_conv_wchar_ucs4le, - mbfl_filt_conv_common_flush, NULL, }; - -#define CK(statement) do { if ((statement) < 0) return (-1); } while (0) - -/* - * UCS-4 => wchar - */ -int mbfl_filt_conv_ucs4_wchar(int c, mbfl_convert_filter *filter) -{ - int n, endian; - - endian = filter->status & 0xff00; - switch (filter->status & 0xff) { - case 0: - if (endian) { - n = c & 0xff; - } else { - n = (c & 0xffu) << 24; - } - filter->cache = n; - filter->status++; - break; - case 1: - if (endian) { - n = (c & 0xff) << 8; - } else { - n = (c & 0xff) << 16; - } - filter->cache |= n; - filter->status++; - break; - case 2: - if (endian) { - n = (c & 0xff) << 16; - } else { - n = (c & 0xff) << 8; - } - filter->cache |= n; - filter->status++; - break; - default: - if (endian) { - n = (c & 0xffu) << 24; - } else { - n = c & 0xff; - } - n |= filter->cache; - filter->status &= ~0xff; - if ((n & 0xffff) == 0 && ((n >> 16) & 0xffff) == 0xfffe) { - if (endian) { - filter->status = 0; /* big-endian */ - } else { - filter->status = 0x100; /* little-endian */ - } - } else if (n != 0xfeff) { - CK((*filter->output_function)(n, filter->data)); - } - break; - } - - return 0; -} - -/* - * UCS-4BE => wchar - */ -int mbfl_filt_conv_ucs4be_wchar(int c, mbfl_convert_filter *filter) -{ - int n; - - if (filter->status == 0) { - filter->status = 1; - n = (c & 0xffu) << 24; - filter->cache = n; - } else if (filter->status == 1) { - filter->status = 2; - n = (c & 0xff) << 16; - filter->cache |= n; - } else if (filter->status == 2) { - filter->status = 3; - n = (c & 0xff) << 8; - filter->cache |= n; - } else { - filter->status = 0; - n = (c & 0xff) | filter->cache; - CK((*filter->output_function)(n, filter->data)); - } - return 0; -} - -/* - * wchar => UCS-4BE - */ -int mbfl_filt_conv_wchar_ucs4be(int c, mbfl_convert_filter *filter) -{ - if (c != MBFL_BAD_INPUT) { - CK((*filter->output_function)((c >> 24) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 16) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(c & 0xff, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - -/* - * UCS-4LE => wchar - */ -int mbfl_filt_conv_ucs4le_wchar(int c, mbfl_convert_filter *filter) -{ - int n; - - if (filter->status == 0) { - filter->status = 1; - n = (c & 0xff); - filter->cache = n; - } else if (filter->status == 1) { - filter->status = 2; - n = (c & 0xff) << 8; - filter->cache |= n; - } else if (filter->status == 2) { - filter->status = 3; - n = (c & 0xff) << 16; - filter->cache |= n; - } else { - filter->status = 0; - n = ((c & 0xffu) << 24) | filter->cache; - CK((*filter->output_function)(n, filter->data)); - } - return 0; -} - -/* - * wchar => UCS-4LE - */ -int mbfl_filt_conv_wchar_ucs4le(int c, mbfl_convert_filter *filter) -{ - if (c != MBFL_BAD_INPUT) { - CK((*filter->output_function)(c & 0xff, filter->data)); - CK((*filter->output_function)((c >> 8) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 16) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 24) & 0xff, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - -static int mbfl_filt_conv_ucs4_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status & 0xF) { - /* Input string was truncated */ - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - filter->status = 0; - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - #define DETECTED_BE 1 #define DETECTED_LE 2 diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.h b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.h index b5280f1bfb33..8b825784664d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.h @@ -33,17 +33,5 @@ extern const mbfl_encoding mbfl_encoding_ucs4; extern const mbfl_encoding mbfl_encoding_ucs4le; extern const mbfl_encoding mbfl_encoding_ucs4be; -extern const struct mbfl_convert_vtbl vtbl_ucs4_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_ucs4; -extern const struct mbfl_convert_vtbl vtbl_ucs4be_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_ucs4be; -extern const struct mbfl_convert_vtbl vtbl_ucs4le_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_ucs4le; - -int mbfl_filt_conv_ucs4_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_ucs4be_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_ucs4be(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_ucs4le_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_ucs4le(int c, mbfl_convert_filter *filter); #endif /* MBFL_MBFILTER_UCS4_H */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf16.c b/ext/mbstring/libmbfl/filters/mbfilter_utf16.c index 5f5958ad19b3..29c4caeb8d94 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf16.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf16.c @@ -173,7 +173,6 @@ static void mb_wchar_to_utf16le_default(uint32_t *in, size_t len, mb_convert_buf #endif -static int mbfl_filt_conv_utf16_wchar_flush(mbfl_convert_filter *filter); static size_t mb_utf16_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static zend_string* mb_cut_utf16(unsigned char *str, size_t from, size_t len, unsigned char *end); static zend_string* mb_cut_utf16be(unsigned char *str, size_t from, size_t len, unsigned char *end); @@ -188,8 +187,8 @@ const mbfl_encoding mbfl_encoding_utf16 = { mbfl_encoding_utf16_aliases, NULL, 0, - &vtbl_utf16_wchar, - &vtbl_wchar_utf16, + NULL, + NULL, mb_utf16_to_wchar, mb_wchar_to_utf16be, NULL, @@ -203,8 +202,8 @@ const mbfl_encoding mbfl_encoding_utf16be = { NULL, NULL, 0, - &vtbl_utf16be_wchar, - &vtbl_wchar_utf16be, + NULL, + NULL, mb_utf16be_to_wchar, mb_wchar_to_utf16be, NULL, @@ -218,270 +217,14 @@ const mbfl_encoding mbfl_encoding_utf16le = { NULL, NULL, 0, - &vtbl_utf16le_wchar, - &vtbl_wchar_utf16le, + NULL, + NULL, mb_utf16le_to_wchar, mb_wchar_to_utf16le, NULL, mb_cut_utf16le }; -const struct mbfl_convert_vtbl vtbl_utf16_wchar = { - mbfl_no_encoding_utf16, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf16_wchar, - mbfl_filt_conv_utf16_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf16 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf16, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf16be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf16be_wchar = { - mbfl_no_encoding_utf16be, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf16be_wchar, - mbfl_filt_conv_utf16_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf16be = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf16be, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf16be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf16le_wchar = { - mbfl_no_encoding_utf16le, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf16le_wchar, - mbfl_filt_conv_utf16_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf16le = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf16le, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf16le, - mbfl_filt_conv_common_flush, - NULL, -}; - -#define CK(statement) do { if ((statement) < 0) return (-1); } while (0) - -int mbfl_filt_conv_utf16_wchar(int c, mbfl_convert_filter *filter) -{ - /* Start with the assumption that the string is big-endian; - * If we find a little-endian BOM, then we will change that assumption */ - if (filter->status == 0) { - filter->cache = c & 0xFF; - filter->status = 1; - } else { - int n = (filter->cache << 8) | (c & 0xFF); - filter->cache = filter->status = 0; - if (n == 0xFFFE) { - /* Switch to little-endian mode */ - filter->filter_function = mbfl_filt_conv_utf16le_wchar; - } else { - filter->filter_function = mbfl_filt_conv_utf16be_wchar; - if (n >= 0xD800 && n <= 0xDBFF) { - filter->cache = n & 0x3FF; /* Pick out 10 data bits */ - filter->status = 2; - return 0; - } else if (n >= 0xDC00 && n <= 0xDFFF) { - /* This is wrong; second part of surrogate pair has come first */ - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } else if (n != 0xFEFF) { - CK((*filter->output_function)(n, filter->data)); - } - } - } - - return 0; -} - -int mbfl_filt_conv_utf16be_wchar(int c, mbfl_convert_filter *filter) -{ - int n; - - switch (filter->status) { - case 0: /* First byte */ - filter->cache = c & 0xFF; - filter->status = 1; - break; - - case 1: /* Second byte */ - n = (filter->cache << 8) | (c & 0xFF); - if (n >= 0xD800 && n <= 0xDBFF) { - filter->cache = n & 0x3FF; /* Pick out 10 data bits */ - filter->status = 2; - } else if (n >= 0xDC00 && n <= 0xDFFF) { - /* This is wrong; second part of surrogate pair has come first */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } else { - filter->status = 0; - CK((*filter->output_function)(n, filter->data)); - } - break; - - case 2: /* Second part of surrogate, first byte */ - filter->cache = (filter->cache << 8) | (c & 0xFF); - filter->status = 3; - break; - - case 3: /* Second part of surrogate, second byte */ - n = ((filter->cache & 0xFF) << 8) | (c & 0xFF); - if (n >= 0xD800 && n <= 0xDBFF) { - /* Wrong; that's the first half of a surrogate pair, not the second */ - filter->cache = n & 0x3FF; - filter->status = 2; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } else if (n >= 0xDC00 && n <= 0xDFFF) { - filter->status = 0; - n = ((filter->cache & 0x3FF00) << 2) + (n & 0x3FF) + 0x10000; - CK((*filter->output_function)(n, filter->data)); - } else { - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - CK((*filter->output_function)(n, filter->data)); - } - } - - return 0; -} - -int mbfl_filt_conv_wchar_utf16be(int c, mbfl_convert_filter *filter) -{ - int n; - - if (c >= 0 && c < MBFL_WCSPLANE_UCS2MAX) { - CK((*filter->output_function)((c >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(c & 0xff, filter->data)); - } else if (c >= MBFL_WCSPLANE_SUPMIN && c < MBFL_WCSPLANE_SUPMAX) { - n = ((c >> 10) - 0x40) | 0xd800; - CK((*filter->output_function)((n >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(n & 0xff, filter->data)); - n = (c & 0x3ff) | 0xdc00; - CK((*filter->output_function)((n >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(n & 0xff, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - -int mbfl_filt_conv_utf16le_wchar(int c, mbfl_convert_filter *filter) -{ - int n; - - switch (filter->status) { - case 0: - filter->cache = c & 0xff; - filter->status = 1; - break; - - case 1: - if ((c & 0xfc) == 0xd8) { - /* Looks like we have a surrogate pair here */ - filter->cache += ((c & 0x3) << 8); - filter->status = 2; - } else if ((c & 0xfc) == 0xdc) { - /* This is wrong; the second part of the surrogate pair has come first */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } else { - filter->status = 0; - CK((*filter->output_function)(filter->cache + ((c & 0xff) << 8), filter->data)); - } - break; - - case 2: - filter->cache = (filter->cache << 10) + (c & 0xff); - filter->status = 3; - break; - - case 3: - n = (filter->cache & 0xFF) | ((c & 0xFF) << 8); - if (n >= 0xD800 && n <= 0xDBFF) { - /* We previously saw the first part of a surrogate pair and were - * expecting the second part; this is another first part */ - filter->cache = n & 0x3FF; - filter->status = 2; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } else if (n >= 0xDC00 && n <= 0xDFFF) { - n = filter->cache + ((c & 0x3) << 8) + 0x10000; - filter->status = 0; - CK((*filter->output_function)(n, filter->data)); - } else { - /* The first part of a surrogate pair was followed by some other codepoint - * which is not part of a surrogate pair at all */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - CK((*filter->output_function)(n, filter->data)); - } - break; - } - - return 0; -} - -int mbfl_filt_conv_wchar_utf16le(int c, mbfl_convert_filter *filter) -{ - int n; - - if (c >= 0 && c < MBFL_WCSPLANE_UCS2MAX) { - CK((*filter->output_function)(c & 0xff, filter->data)); - CK((*filter->output_function)((c >> 8) & 0xff, filter->data)); - } else if (c >= MBFL_WCSPLANE_SUPMIN && c < MBFL_WCSPLANE_SUPMAX) { - n = ((c >> 10) - 0x40) | 0xd800; - CK((*filter->output_function)(n & 0xff, filter->data)); - CK((*filter->output_function)((n >> 8) & 0xff, filter->data)); - n = (c & 0x3ff) | 0xdc00; - CK((*filter->output_function)(n & 0xff, filter->data)); - CK((*filter->output_function)((n >> 8) & 0xff, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - -static int mbfl_filt_conv_utf16_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - /* Input string was truncated */ - filter->status = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - #define DETECTED_BE 1 #define DETECTED_LE 2 diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf16.h b/ext/mbstring/libmbfl/filters/mbfilter_utf16.h index 291628549deb..227912a49556 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf16.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf16.h @@ -34,19 +34,6 @@ extern const mbfl_encoding mbfl_encoding_utf16; extern const mbfl_encoding mbfl_encoding_utf16be; extern const mbfl_encoding mbfl_encoding_utf16le; -extern const struct mbfl_convert_vtbl vtbl_utf16_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf16; -extern const struct mbfl_convert_vtbl vtbl_utf16be_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf16be; -extern const struct mbfl_convert_vtbl vtbl_utf16le_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf16le; - -int mbfl_filt_conv_utf16_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_utf16be_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_utf16be(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_utf16le_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_utf16le(int c, mbfl_convert_filter *filter); - #ifdef ZEND_INTRIN_AVX2_FUNC_PTR void init_convert_utf16(void); #endif diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c index 81057d8c6e95..e82d5df5706c 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c @@ -30,7 +30,6 @@ #include "mbfilter.h" #include "mbfilter_utf32.h" -static int mbfl_filt_conv_utf32_wchar_flush(mbfl_convert_filter *filter); static size_t mb_utf32_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static size_t mb_utf32be_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static void mb_wchar_to_utf32be(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); @@ -46,8 +45,8 @@ const mbfl_encoding mbfl_encoding_utf32 = { mbfl_encoding_utf32_aliases, NULL, MBFL_ENCTYPE_WCS4, - &vtbl_utf32_wchar, - &vtbl_wchar_utf32, + NULL, + NULL, mb_utf32_to_wchar, mb_wchar_to_utf32be, NULL, @@ -61,8 +60,8 @@ const mbfl_encoding mbfl_encoding_utf32be = { NULL, NULL, MBFL_ENCTYPE_WCS4, - &vtbl_utf32be_wchar, - &vtbl_wchar_utf32be, + NULL, + NULL, mb_utf32be_to_wchar, mb_wchar_to_utf32be, NULL, @@ -76,178 +75,14 @@ const mbfl_encoding mbfl_encoding_utf32le = { NULL, NULL, MBFL_ENCTYPE_WCS4, - &vtbl_utf32le_wchar, - &vtbl_wchar_utf32le, - mb_utf32le_to_wchar, - mb_wchar_to_utf32le, - NULL, NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf32_wchar = { - mbfl_no_encoding_utf32, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, NULL, - mbfl_filt_conv_utf32_wchar, - mbfl_filt_conv_utf32_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf32 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf32, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf32be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf32be_wchar = { - mbfl_no_encoding_utf32be, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf32be_wchar, - mbfl_filt_conv_utf32_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf32be = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf32be, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf32be, - mbfl_filt_conv_common_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf32le_wchar = { - mbfl_no_encoding_utf32le, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf32le_wchar, - mbfl_filt_conv_utf32_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf32le = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf32le, - mbfl_filt_conv_common_ctor, + mb_utf32le_to_wchar, + mb_wchar_to_utf32le, NULL, - mbfl_filt_conv_wchar_utf32le, - mbfl_filt_conv_common_flush, NULL, }; -#define CK(statement) do { if ((statement) < 0) return (-1); } while (0) - -static int emit_char_if_valid(int n, mbfl_convert_filter *filter) -{ - if (n >= 0 && n < MBFL_WCSPLANE_UTF32MAX && (n < 0xD800 || n > 0xDFFF)) { - CK((*filter->output_function)(n, filter->data)); - } else { - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - return 0; -} - -int mbfl_filt_conv_utf32_wchar(int c, mbfl_convert_filter *filter) -{ - if (filter->status < 3) { - filter->cache = (filter->cache << 8) | (c & 0xFF); - filter->status++; - } else { - int n = ((unsigned int)filter->cache << 8) | (c & 0xFF); - filter->cache = filter->status = 0; - - if (n == 0xFFFE0000) { - /* Found a little-endian byte order mark */ - filter->filter_function = mbfl_filt_conv_utf32le_wchar; - } else { - filter->filter_function = mbfl_filt_conv_utf32be_wchar; - if (n != 0xFEFF) { - CK(emit_char_if_valid(n, filter)); - } - } - } - - return 0; -} - -int mbfl_filt_conv_utf32be_wchar(int c, mbfl_convert_filter *filter) -{ - if (filter->status < 3) { - filter->cache = (filter->cache << 8) | (c & 0xFF); - filter->status++; - } else { - int n = ((unsigned int)filter->cache << 8) | (c & 0xFF); - filter->cache = filter->status = 0; - CK(emit_char_if_valid(n, filter)); - } - return 0; -} - -int mbfl_filt_conv_wchar_utf32be(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < MBFL_WCSPLANE_UTF32MAX) { - CK((*filter->output_function)((c >> 24) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 16) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 8) & 0xff, filter->data)); - CK((*filter->output_function)(c & 0xff, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - -int mbfl_filt_conv_utf32le_wchar(int c, mbfl_convert_filter *filter) -{ - if (filter->status < 3) { - filter->cache |= ((c & 0xFFU) << (8 * filter->status)); - filter->status++; - } else { - int n = ((c & 0xFFU) << 24) | filter->cache; - filter->cache = filter->status = 0; - CK(emit_char_if_valid(n, filter)); - } - return 0; -} - -int mbfl_filt_conv_wchar_utf32le(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < MBFL_WCSPLANE_UTF32MAX) { - CK((*filter->output_function)(c & 0xff, filter->data)); - CK((*filter->output_function)((c >> 8) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 16) & 0xff, filter->data)); - CK((*filter->output_function)((c >> 24) & 0xff, filter->data)); - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - -static int mbfl_filt_conv_utf32_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - /* Input string was truncated */ - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - } - filter->cache = filter->status = 0; - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - #define DETECTED_BE 1 #define DETECTED_LE 2 diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf32.h b/ext/mbstring/libmbfl/filters/mbfilter_utf32.h index 58c69d72f16d..5f7585111698 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf32.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf32.h @@ -34,17 +34,4 @@ extern const mbfl_encoding mbfl_encoding_utf32; extern const mbfl_encoding mbfl_encoding_utf32be; extern const mbfl_encoding mbfl_encoding_utf32le; -extern const struct mbfl_convert_vtbl vtbl_utf32_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf32; -extern const struct mbfl_convert_vtbl vtbl_utf32be_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf32be; -extern const struct mbfl_convert_vtbl vtbl_utf32le_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf32le; - -int mbfl_filt_conv_utf32_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_utf32be_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_utf32be(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_utf32le_wchar(int c, mbfl_convert_filter *filter); -int mbfl_filt_conv_wchar_utf32le(int c, mbfl_convert_filter *filter); - #endif /* MBFL_MBFILTER_UTF32_H */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c index 87bdc590e6d5..0ee74c032140 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c @@ -260,7 +260,7 @@ int mbfl_filt_conv_utf7_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -368,7 +368,7 @@ int mbfl_filt_conv_wchar_utf7(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c index ac49e6a165b4..ba34255ebc13 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c @@ -282,7 +282,7 @@ int mbfl_filt_conv_utf7imap_wchar(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; @@ -409,7 +409,7 @@ int mbfl_filt_conv_wchar_utf7imap(int c, mbfl_convert_filter *filter) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } return 0; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c index 0786c8e7f314..80ac36be6dd4 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c @@ -52,14 +52,6 @@ const unsigned char mblen_table_utf8[] = { }; extern int mbfl_bisec_srch2(int w, const unsigned short tbl[], int n); -extern int mbfl_filt_conv_sjis_mobile_flush(mbfl_convert_filter *filter); - -static int mbfl_filt_conv_utf8_mobile_wchar(int c, mbfl_convert_filter *filter); -static int mbfl_filt_conv_wchar_utf8_mobile(int c, mbfl_convert_filter *filter); - -static int mbfl_filt_conv_utf8_wchar(int c, mbfl_convert_filter *filter); -static int mbfl_filt_conv_wchar_utf8(int c, mbfl_convert_filter *filter); -static int mbfl_filt_conv_utf8_wchar_flush(mbfl_convert_filter *filter); static size_t mb_utf8_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state); static void mb_wchar_to_utf8(uint32_t *in, size_t len, mb_convert_buf *buf, bool end); @@ -143,34 +135,14 @@ const mbfl_encoding mbfl_encoding_utf8 = { mbfl_encoding_utf8_aliases, mblen_table_utf8, 0, - &vtbl_utf8_wchar, - &vtbl_wchar_utf8, + NULL, + NULL, mb_utf8_to_wchar, mb_wchar_to_utf8, NULL, mb_cut_utf8 }; -const struct mbfl_convert_vtbl vtbl_utf8_wchar = { - mbfl_no_encoding_utf8, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf8_wchar, - mbfl_filt_conv_utf8_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf8 = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf8, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf8, - mbfl_filt_conv_common_flush, - NULL, -}; - static const char *mbfl_encoding_utf8_docomo_aliases[] = {"UTF-8-DOCOMO", "UTF8-DOCOMO", NULL}; static const char *mbfl_encoding_utf8_kddi_b_aliases[] = {"UTF-8-Mobile#KDDI", "UTF-8-KDDI", "UTF8-KDDI", NULL}; static const char *mbfl_encoding_utf8_sb_aliases[] = {"UTF-8-SOFTBANK", "UTF8-SOFTBANK", NULL}; @@ -182,8 +154,8 @@ const mbfl_encoding mbfl_encoding_utf8_docomo = { mbfl_encoding_utf8_docomo_aliases, mblen_table_utf8, 0, - &vtbl_utf8_docomo_wchar, - &vtbl_wchar_utf8_docomo, + NULL, + NULL, mb_utf8_docomo_to_wchar, mb_wchar_to_utf8_docomo, NULL, @@ -197,8 +169,8 @@ const mbfl_encoding mbfl_encoding_utf8_kddi_a = { NULL, mblen_table_utf8, 0, - &vtbl_utf8_kddi_a_wchar, - &vtbl_wchar_utf8_kddi_a, + NULL, + NULL, mb_utf8_kddi_a_to_wchar, mb_wchar_to_utf8_kddi_a, NULL, @@ -212,8 +184,8 @@ const mbfl_encoding mbfl_encoding_utf8_kddi_b = { mbfl_encoding_utf8_kddi_b_aliases, mblen_table_utf8, 0, - &vtbl_utf8_kddi_b_wchar, - &vtbl_wchar_utf8_kddi_b, + NULL, + NULL, mb_utf8_kddi_b_to_wchar, mb_wchar_to_utf8_kddi_b, NULL, @@ -227,222 +199,14 @@ const mbfl_encoding mbfl_encoding_utf8_sb = { mbfl_encoding_utf8_sb_aliases, mblen_table_utf8, 0, - &vtbl_utf8_sb_wchar, - &vtbl_wchar_utf8_sb, + NULL, + NULL, mb_utf8_sb_to_wchar, mb_wchar_to_utf8_sb, NULL, mb_cut_utf8, }; -const struct mbfl_convert_vtbl vtbl_utf8_docomo_wchar = { - mbfl_no_encoding_utf8_docomo, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf8_mobile_wchar, - mbfl_filt_conv_utf8_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf8_docomo = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf8_docomo, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf8_mobile, - mbfl_filt_conv_sjis_mobile_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf8_kddi_a_wchar = { - mbfl_no_encoding_utf8_kddi_a, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf8_mobile_wchar, - mbfl_filt_conv_utf8_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_a = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf8_kddi_a, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf8_mobile, - mbfl_filt_conv_sjis_mobile_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf8_kddi_b_wchar = { - mbfl_no_encoding_utf8_kddi_b, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf8_mobile_wchar, - mbfl_filt_conv_utf8_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_b = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf8_kddi_b, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf8_mobile, - mbfl_filt_conv_sjis_mobile_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_utf8_sb_wchar = { - mbfl_no_encoding_utf8_sb, - mbfl_no_encoding_wchar, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_utf8_mobile_wchar, - mbfl_filt_conv_utf8_wchar_flush, - NULL, -}; - -const struct mbfl_convert_vtbl vtbl_wchar_utf8_sb = { - mbfl_no_encoding_wchar, - mbfl_no_encoding_utf8_sb, - mbfl_filt_conv_common_ctor, - NULL, - mbfl_filt_conv_wchar_utf8_mobile, - mbfl_filt_conv_sjis_mobile_flush, - NULL, -}; - -#define CK(statement) do { if ((statement) < 0) return (-1); } while (0) - -static int mbfl_filt_put_invalid_char(mbfl_convert_filter *filter) -{ - filter->status = filter->cache = 0; - CK((*filter->output_function)(MBFL_BAD_INPUT, filter->data)); - return 0; -} - -static int mbfl_filt_conv_utf8_wchar(int c, mbfl_convert_filter *filter) -{ - int s, c1; - -retry: - switch (filter->status) { - case 0x00: - if (c < 0x80) { - CK((*filter->output_function)(c, filter->data)); - } else if (c >= 0xc2 && c <= 0xdf) { /* 2byte code first char: 0xc2-0xdf */ - filter->status = 0x10; - filter->cache = c & 0x1f; - } else if (c >= 0xe0 && c <= 0xef) { /* 3byte code first char: 0xe0-0xef */ - filter->status = 0x20; - filter->cache = c & 0xf; - } else if (c >= 0xf0 && c <= 0xf4) { /* 3byte code first char: 0xf0-0xf4 */ - filter->status = 0x30; - filter->cache = c & 0x7; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - } - break; - case 0x10: /* 2byte code 2nd char: 0x80-0xbf */ - case 0x21: /* 3byte code 3rd char: 0x80-0xbf */ - case 0x32: /* 4byte code 4th char: 0x80-0xbf */ - if (c >= 0x80 && c <= 0xbf) { - s = (filter->cache<<6) | (c & 0x3f); - filter->status = filter->cache = 0; - CK((*filter->output_function)(s, filter->data)); - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - case 0x20: /* 3byte code 2nd char: 0:0xa0-0xbf,D:0x80-9F,1-C,E-F:0x80-0x9f */ - s = (filter->cache<<6) | (c & 0x3f); - c1 = filter->cache & 0xf; - - if ((c >= 0x80 && c <= 0xbf) && - ((c1 == 0x0 && c >= 0xa0) || - (c1 == 0xd && c < 0xa0) || - (c1 > 0x0 && c1 != 0xd))) { - filter->cache = s; - filter->status++; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - case 0x30: /* 4byte code 2nd char: 0:0x90-0xbf,1-3:0x80-0xbf,4:0x80-0x8f */ - s = (filter->cache<<6) | (c & 0x3f); - c1 = filter->cache & 0x7; - - if ((c >= 0x80 && c <= 0xbf) && - ((c1 == 0x0 && c >= 0x90) || - (c1 == 0x4 && c < 0x90) || - (c1 > 0x0 && c1 != 0x4))) { - filter->cache = s; - filter->status++; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - case 0x31: /* 4byte code 3rd char: 0x80-0xbf */ - if (c >= 0x80 && c <= 0xbf) { - filter->cache = (filter->cache<<6) | (c & 0x3f); - filter->status++; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_utf8_wchar_flush(mbfl_convert_filter *filter) -{ - if (filter->status) { - (*filter->output_function)(MBFL_BAD_INPUT, filter->data); - filter->status = 0; - } - - if (filter->flush_function) { - (*filter->flush_function)(filter->data); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_utf8(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < 0x110000) { - if (c < 0x80) { - CK((*filter->output_function)(c, filter->data)); - } else if (c < 0x800) { - CK((*filter->output_function)(((c >> 6) & 0x1f) | 0xc0, filter->data)); - CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data)); - } else if (c < 0x10000) { - CK((*filter->output_function)(((c >> 12) & 0x0f) | 0xe0, filter->data)); - CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data)); - CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data)); - } else { - CK((*filter->output_function)(((c >> 18) & 0x07) | 0xf0, filter->data)); - CK((*filter->output_function)(((c >> 12) & 0x3f) | 0x80, filter->data)); - CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data)); - CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - static size_t mb_utf8_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state) { unsigned char *p = *in, *e = p + *in_len; @@ -581,143 +345,6 @@ static zend_string* mb_cut_utf8(unsigned char *str, size_t from, size_t len, uns return zend_string_init_fast((char*)start, _end - start); } -static int mbfl_filt_conv_utf8_mobile_wchar(int c, mbfl_convert_filter *filter) -{ - int s, s1 = 0, c1 = 0, snd = 0; - -retry: - switch (filter->status & 0xff) { - case 0x00: - if (c < 0x80) { - CK((*filter->output_function)(c, filter->data)); - } else if (c >= 0xc2 && c <= 0xdf) { /* 2byte code first char: 0xc2-0xdf */ - filter->status = 0x10; - filter->cache = c & 0x1f; - } else if (c >= 0xe0 && c <= 0xef) { /* 3byte code first char: 0xe0-0xef */ - filter->status = 0x20; - filter->cache = c & 0xf; - } else if (c >= 0xf0 && c <= 0xf4) { /* 3byte code first char: 0xf0-0xf4 */ - filter->status = 0x30; - filter->cache = c & 0x7; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - } - break; - - case 0x10: /* 2byte code 2nd char: 0x80-0xbf */ - case 0x21: /* 3byte code 3rd char: 0x80-0xbf */ - case 0x32: /* 4byte code 4th char: 0x80-0xbf */ - filter->status = 0; - if (c >= 0x80 && c <= 0xbf) { - s = (filter->cache << 6) | (c & 0x3f); - filter->cache = 0; - - if (filter->from->no_encoding == mbfl_no_encoding_utf8_docomo && mbfilter_conv_r_map_tbl(s, &s1, 4, mbfl_docomo2uni_pua)) { - s = mbfilter_sjis_emoji_docomo2unicode(s1, &snd); - } else if (filter->from->no_encoding == mbfl_no_encoding_utf8_kddi_a && mbfilter_conv_r_map_tbl(s, &s1, 7, mbfl_kddi2uni_pua)) { - s = mbfilter_sjis_emoji_kddi2unicode(s1, &snd); - } else if (filter->from->no_encoding == mbfl_no_encoding_utf8_kddi_b && mbfilter_conv_r_map_tbl(s, &s1, 8, mbfl_kddi2uni_pua_b)) { - s = mbfilter_sjis_emoji_kddi2unicode(s1, &snd); - } else if (filter->from->no_encoding == mbfl_no_encoding_utf8_sb && mbfilter_conv_r_map_tbl(s, &s1, 6, mbfl_sb2uni_pua)) { - s = mbfilter_sjis_emoji_sb2unicode(s1, &snd); - } - - if (snd > 0) { - CK((*filter->output_function)(snd, filter->data)); - } - CK((*filter->output_function)(s, filter->data)); - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - - case 0x20: /* 3byte code 2nd char: 0:0xa0-0xbf,D:0x80-9F,1-C,E-F:0x80-0x9f */ - s = (filter->cache << 6) | (c & 0x3f); - c1 = filter->cache & 0xf; - - if ((c >= 0x80 && c <= 0xbf) && - ((c1 == 0x0 && c >= 0xa0) || - (c1 == 0xd && c < 0xa0) || - (c1 > 0x0 && c1 != 0xd))) { - filter->cache = s; - filter->status++; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - - case 0x30: /* 4byte code 2nd char: 0:0x90-0xbf,1-3:0x80-0xbf,4:0x80-0x8f */ - s = (filter->cache << 6) | (c & 0x3f); - c1 = filter->cache & 0x7; - - if ((c >= 0x80 && c <= 0xbf) && - ((c1 == 0x0 && c >= 0x90) || - (c1 == 0x4 && c < 0x90) || - (c1 > 0x0 && c1 != 0x4))) { - filter->cache = s; - filter->status++; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - - case 0x31: /* 4byte code 3rd char: 0x80-0xbf */ - if (c >= 0x80 && c <= 0xbf) { - filter->cache = (filter->cache << 6) | (c & 0x3f); - filter->status++; - } else { - CK(mbfl_filt_put_invalid_char(filter)); - goto retry; - } - break; - - EMPTY_SWITCH_DEFAULT_CASE(); - } - - return 0; -} - -static int mbfl_filt_conv_wchar_utf8_mobile(int c, mbfl_convert_filter *filter) -{ - if (c >= 0 && c < 0x110000) { - int s1, c1; - - if ((filter->to->no_encoding == mbfl_no_encoding_utf8_docomo && mbfilter_unicode2sjis_emoji_docomo(c, &s1, filter) > 0 && mbfilter_conv_map_tbl(s1, &c1, 4, mbfl_docomo2uni_pua)) || - (filter->to->no_encoding == mbfl_no_encoding_utf8_kddi_a && mbfilter_unicode2sjis_emoji_kddi_sjis(c, &s1, filter) > 0 && mbfilter_conv_map_tbl(s1, &c1, 7, mbfl_kddi2uni_pua)) || - (filter->to->no_encoding == mbfl_no_encoding_utf8_kddi_b && mbfilter_unicode2sjis_emoji_kddi_sjis(c, &s1, filter) > 0 && mbfilter_conv_map_tbl(s1, &c1, 8, mbfl_kddi2uni_pua_b)) || - (filter->to->no_encoding == mbfl_no_encoding_utf8_sb && mbfilter_unicode2sjis_emoji_sb(c, &s1, filter) > 0 && mbfilter_conv_map_tbl(s1, &c1, 6, mbfl_sb2uni_pua))) { - c = c1; - } - - if (filter->status) { - return 0; - } - - if (c < 0x80) { - CK((*filter->output_function)(c, filter->data)); - } else if (c < 0x800) { - CK((*filter->output_function)(((c >> 6) & 0x1f) | 0xc0, filter->data)); - CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data)); - } else if (c < 0x10000) { - CK((*filter->output_function)(((c >> 12) & 0x0f) | 0xe0, filter->data)); - CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data)); - CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data)); - } else { - CK((*filter->output_function)(((c >> 18) & 0x07) | 0xf0, filter->data)); - CK((*filter->output_function)(((c >> 12) & 0x3f) | 0x80, filter->data)); - CK((*filter->output_function)(((c >> 6) & 0x3f) | 0x80, filter->data)); - CK((*filter->output_function)((c & 0x3f) | 0x80, filter->data)); - } - } else { - CK(mbfl_filt_conv_illegal_output(c, filter)); - } - - return 0; -} - /* Regional Indicator Unicode codepoints are from 0x1F1E6-0x1F1FF * These correspond to the letters A-Z * To display the flag emoji for a country, two unicode codepoints are combined, @@ -725,7 +352,7 @@ static int mbfl_filt_conv_wchar_utf8_mobile(int c, mbfl_convert_filter *filter) * This macro converts uppercase ASCII values to Regional Indicator codepoints */ #define NFLAGS(c) (0x1F1A5+(int)(c)) -static const char nflags_s[10][2] = {"CN","DE","ES","FR","GB","IT","JP","KR","RU","US"}; +static const char nflags_s[10][2] ZEND_NONSTRING = {"CN","DE","ES","FR","GB","IT","JP","KR","RU","US"}; static const int nflags_code_kddi[10] = { 0x2549, 0x2546, 0x24C0, 0x2545, 0x2548, 0x2547, 0x2750, 0x254A, 0x24C1, 0x27F7 }; static const int nflags_code_sb[10] = { 0x2B0A, 0x2B05, 0x2B08, 0x2B04, 0x2B07, 0x2B06, 0x2B02, 0x2B0B, 0x2B09, 0x2B03 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8.h b/ext/mbstring/libmbfl/filters/mbfilter_utf8.h index a1282515f34f..e574aebf8958 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8.h @@ -31,21 +31,9 @@ #define MBFL_MBFILTER_UTF8_H extern const mbfl_encoding mbfl_encoding_utf8; -extern const struct mbfl_convert_vtbl vtbl_utf8_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf8; - extern const mbfl_encoding mbfl_encoding_utf8_docomo; extern const mbfl_encoding mbfl_encoding_utf8_kddi_a; extern const mbfl_encoding mbfl_encoding_utf8_kddi_b; extern const mbfl_encoding mbfl_encoding_utf8_sb; -extern const struct mbfl_convert_vtbl vtbl_utf8_docomo_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf8_docomo; -extern const struct mbfl_convert_vtbl vtbl_utf8_kddi_a_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_a; -extern const struct mbfl_convert_vtbl vtbl_utf8_kddi_b_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_b; -extern const struct mbfl_convert_vtbl vtbl_utf8_sb_wchar; -extern const struct mbfl_convert_vtbl vtbl_wchar_utf8_sb; - #endif /* MBFL_MBFILTER_UTF8_H */ diff --git a/ext/mbstring/libmbfl/mbfl/eaw_table.h b/ext/mbstring/libmbfl/mbfl/eaw_table.h index 0150306835ba..7bdacccee29e 100644 --- a/ext/mbstring/libmbfl/mbfl/eaw_table.h +++ b/ext/mbstring/libmbfl/mbfl/eaw_table.h @@ -80,10 +80,10 @@ static const struct { { 0xff01, 0xff60 }, { 0xffe0, 0xffe6 }, { 0x16fe0, 0x16fe4 }, - { 0x16ff0, 0x16ff1 }, - { 0x17000, 0x187f7 }, - { 0x18800, 0x18cd5 }, - { 0x18cff, 0x18d08 }, + { 0x16ff0, 0x16ff6 }, + { 0x17000, 0x18cd5 }, + { 0x18cff, 0x18d1e }, + { 0x18d80, 0x18df2 }, { 0x1aff0, 0x1aff3 }, { 0x1aff5, 0x1affb }, { 0x1affd, 0x1affe }, @@ -125,7 +125,7 @@ static const struct { { 0x1f680, 0x1f6c5 }, { 0x1f6cc, 0x1f6cc }, { 0x1f6d0, 0x1f6d2 }, - { 0x1f6d5, 0x1f6d7 }, + { 0x1f6d5, 0x1f6d8 }, { 0x1f6dc, 0x1f6df }, { 0x1f6eb, 0x1f6ec }, { 0x1f6f4, 0x1f6fc }, @@ -135,11 +135,12 @@ static const struct { { 0x1f93c, 0x1f945 }, { 0x1f947, 0x1f9ff }, { 0x1fa70, 0x1fa7c }, - { 0x1fa80, 0x1fa89 }, - { 0x1fa8f, 0x1fac6 }, - { 0x1face, 0x1fadc }, - { 0x1fadf, 0x1fae9 }, - { 0x1faf0, 0x1faf8 }, + { 0x1fa80, 0x1fa8a }, + { 0x1fa8e, 0x1fac6 }, + { 0x1fac8, 0x1fac8 }, + { 0x1facd, 0x1fadc }, + { 0x1fadf, 0x1faea }, + { 0x1faef, 0x1faf8 }, { 0x20000, 0x2fffd }, { 0x30000, 0x3fffd }, }; diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index 1c30c9f41775..d2d68795fa0d 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -103,7 +103,6 @@ mbfl_strcut( size_t from, size_t length) { - const mbfl_encoding *encoding = string->encoding; mbfl_memory_device device; if (from >= string->len) { @@ -113,145 +112,97 @@ mbfl_strcut( mbfl_string_init(result); result->encoding = string->encoding; - if ((encoding->flag & (MBFL_ENCTYPE_SBCS | MBFL_ENCTYPE_WCS2 | MBFL_ENCTYPE_WCS4)) || encoding->mblen_table != NULL) { - const unsigned char *start = NULL; - const unsigned char *end = NULL; - unsigned char *w; - size_t sz; - - if (encoding->flag & MBFL_ENCTYPE_WCS2) { - from &= -2; - - if (length >= string->len - from) { - length = string->len - from; - } - - start = string->val + from; - end = start + (length & -2); - } else if (encoding->flag & MBFL_ENCTYPE_WCS4) { - from &= -4; - - if (length >= string->len - from) { - length = string->len - from; - } - - start = string->val + from; - end = start + (length & -4); - } else if ((encoding->flag & MBFL_ENCTYPE_SBCS)) { - if (length >= string->len - from) { - length = string->len - from; - } - - start = string->val + from; - end = start + length; - } else if (encoding->mblen_table != NULL) { - const unsigned char *mbtab = encoding->mblen_table; - const unsigned char *p, *q; - int m; - - /* search start position */ - for (m = 0, p = string->val, q = p + from; - p < q; p += (m = mbtab[*p])); - - if (p > q) { - p -= m; - } - - start = p; + mbfl_convert_filter *encoder = NULL; + mbfl_convert_filter *decoder = NULL; + const unsigned char *p, *q, *r; + struct { + mbfl_convert_filter encoder; + mbfl_convert_filter decoder; + const unsigned char *p; + size_t pos; + } bk, _bk; + + /* output code filter */ + if (!(decoder = mbfl_convert_filter_new( + &mbfl_encoding_wchar, + string->encoding, + mbfl_memory_device_output, 0, &device))) { + return NULL; + } - /* search end position */ - if (length >= string->len - (start - string->val)) { - end = string->val + string->len; - } else { - for (q = p + length; p < q; p += (m = mbtab[*p])); + /* wchar filter */ + if (!(encoder = mbfl_convert_filter_new( + string->encoding, + &mbfl_encoding_wchar, + mbfl_filter_output_null, + NULL, NULL))) { + mbfl_convert_filter_delete(decoder); + return NULL; + } - if (p > q) { - p -= m; - } - end = p; - } - } else { - /* never reached */ - return NULL; - } + mbfl_memory_device_init(&device, length + 8, 0); - /* allocate memory and copy string */ - sz = end - start; - w = ecalloc(sz + 8, sizeof(unsigned char)); + p = string->val; - memcpy(w, start, sz); - w[sz] = '\0'; - w[sz + 1] = '\0'; - w[sz + 2] = '\0'; - w[sz + 3] = '\0'; + /* search start position */ + for (q = string->val + from; p < q; p++) { + (*encoder->filter_function)(*p, encoder); + } - result->val = w; - result->len = sz; - } else { - mbfl_convert_filter *encoder = NULL; - mbfl_convert_filter *decoder = NULL; - const unsigned char *p, *q, *r; - struct { - mbfl_convert_filter encoder; - mbfl_convert_filter decoder; - const unsigned char *p; - size_t pos; - } bk, _bk; - - /* output code filter */ - if (!(decoder = mbfl_convert_filter_new( - &mbfl_encoding_wchar, - string->encoding, - mbfl_memory_device_output, 0, &device))) { - return NULL; - } + /* switch the drain direction */ + encoder->output_function = (output_function_t)decoder->filter_function; + encoder->flush_function = (flush_function_t)decoder->filter_flush; + encoder->data = decoder; - /* wchar filter */ - if (!(encoder = mbfl_convert_filter_new( - string->encoding, - &mbfl_encoding_wchar, - mbfl_filter_output_null, - NULL, NULL))) { - mbfl_convert_filter_delete(decoder); - return NULL; - } + q = string->val + string->len; - mbfl_memory_device_init(&device, length + 8, 0); + /* save the encoder, decoder state and the pointer */ + mbfl_convert_filter_copy(decoder, &_bk.decoder); + mbfl_convert_filter_copy(encoder, &_bk.encoder); + _bk.p = p; + _bk.pos = device.pos; - p = string->val; + if (length > q - p) { + length = q - p; + } - /* search start position */ - for (q = string->val + from; p < q; p++) { + if (length >= 20) { + /* output a little shorter than "length" */ + /* XXX: the constant "20" was determined purely on the heuristics. */ + for (r = p + length - 20; p < r; p++) { (*encoder->filter_function)(*p, encoder); } - /* switch the drain direction */ - encoder->output_function = (output_function_t)decoder->filter_function; - encoder->flush_function = (flush_function_t)decoder->filter_flush; - encoder->data = decoder; - - q = string->val + string->len; - - /* save the encoder, decoder state and the pointer */ - mbfl_convert_filter_copy(decoder, &_bk.decoder); - mbfl_convert_filter_copy(encoder, &_bk.encoder); - _bk.p = p; - _bk.pos = device.pos; - - if (length > q - p) { - length = q - p; - } + /* if the offset of the resulting string exceeds the length, + * then restore the state */ + if (device.pos > length) { + p = _bk.p; + device.pos = _bk.pos; + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); + mbfl_convert_filter_copy(&_bk.decoder, decoder); + mbfl_convert_filter_copy(&_bk.encoder, encoder); + bk = _bk; + } else { + /* save the encoder, decoder state and the pointer */ + mbfl_convert_filter_copy(decoder, &bk.decoder); + mbfl_convert_filter_copy(encoder, &bk.encoder); + bk.p = p; + bk.pos = device.pos; - if (length >= 20) { - /* output a little shorter than "length" */ - /* XXX: the constant "20" was determined purely on the heuristics. */ - for (r = p + length - 20; p < r; p++) { - (*encoder->filter_function)(*p, encoder); - } + /* flush the stream */ + (*encoder->filter_flush)(encoder); /* if the offset of the resulting string exceeds the length, * then restore the state */ if (device.pos > length) { + if (bk.decoder.filter_dtor) + bk.decoder.filter_dtor(&bk.decoder); + if (bk.encoder.filter_dtor) + bk.encoder.filter_dtor(&bk.encoder); + p = _bk.p; device.pos = _bk.pos; if (decoder->filter_dtor) @@ -262,86 +213,11 @@ mbfl_strcut( mbfl_convert_filter_copy(&_bk.encoder, encoder); bk = _bk; } else { - /* save the encoder, decoder state and the pointer */ - mbfl_convert_filter_copy(decoder, &bk.decoder); - mbfl_convert_filter_copy(encoder, &bk.encoder); - bk.p = p; - bk.pos = device.pos; - - /* flush the stream */ - (*encoder->filter_flush)(encoder); - - /* if the offset of the resulting string exceeds the length, - * then restore the state */ - if (device.pos > length) { - if (bk.decoder.filter_dtor) - bk.decoder.filter_dtor(&bk.decoder); - if (bk.encoder.filter_dtor) - bk.encoder.filter_dtor(&bk.encoder); - - p = _bk.p; - device.pos = _bk.pos; - if (decoder->filter_dtor) - decoder->filter_dtor(decoder); - if (encoder->filter_dtor) - encoder->filter_dtor(encoder); - mbfl_convert_filter_copy(&_bk.decoder, decoder); - mbfl_convert_filter_copy(&_bk.encoder, encoder); - bk = _bk; - } else { - if (_bk.decoder.filter_dtor) - _bk.decoder.filter_dtor(&_bk.decoder); - if (_bk.encoder.filter_dtor) - _bk.encoder.filter_dtor(&_bk.encoder); - - p = bk.p; - device.pos = bk.pos; - if (decoder->filter_dtor) - decoder->filter_dtor(decoder); - if (encoder->filter_dtor) - encoder->filter_dtor(encoder); - mbfl_convert_filter_copy(&bk.decoder, decoder); - mbfl_convert_filter_copy(&bk.encoder, encoder); - } - } - } else { - bk = _bk; - } - - /* detect end position */ - while (p < q) { - (*encoder->filter_function)(*p, encoder); - - if (device.pos > length) { - /* restore filter */ - p = bk.p; - device.pos = bk.pos; - if (decoder->filter_dtor) - decoder->filter_dtor(decoder); - if (encoder->filter_dtor) - encoder->filter_dtor(encoder); - mbfl_convert_filter_copy(&bk.decoder, decoder); - mbfl_convert_filter_copy(&bk.encoder, encoder); - break; - } - - p++; - - /* backup current state */ - mbfl_convert_filter_copy(decoder, &_bk.decoder); - mbfl_convert_filter_copy(encoder, &_bk.encoder); - _bk.pos = device.pos; - _bk.p = p; - - (*encoder->filter_flush)(encoder); - - if (device.pos > length) { if (_bk.decoder.filter_dtor) _bk.decoder.filter_dtor(&_bk.decoder); if (_bk.encoder.filter_dtor) _bk.encoder.filter_dtor(&_bk.encoder); - /* restore filter */ p = bk.p; device.pos = bk.pos; if (decoder->filter_dtor) @@ -350,39 +226,86 @@ mbfl_strcut( encoder->filter_dtor(encoder); mbfl_convert_filter_copy(&bk.decoder, decoder); mbfl_convert_filter_copy(&bk.encoder, encoder); - break; } + } + } else { + bk = _bk; + } - if (bk.decoder.filter_dtor) - bk.decoder.filter_dtor(&bk.decoder); - if (bk.encoder.filter_dtor) - bk.encoder.filter_dtor(&bk.encoder); + /* detect end position */ + while (p < q) { + (*encoder->filter_function)(*p, encoder); - p = _bk.p; - device.pos = _bk.pos; + if (device.pos > length) { + /* restore filter */ + p = bk.p; + device.pos = bk.pos; if (decoder->filter_dtor) decoder->filter_dtor(decoder); if (encoder->filter_dtor) encoder->filter_dtor(encoder); - mbfl_convert_filter_copy(&_bk.decoder, decoder); - mbfl_convert_filter_copy(&_bk.encoder, encoder); - - bk = _bk; + mbfl_convert_filter_copy(&bk.decoder, decoder); + mbfl_convert_filter_copy(&bk.encoder, encoder); + break; } - decoder->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE; + p++; + + /* backup current state */ + mbfl_convert_filter_copy(decoder, &_bk.decoder); + mbfl_convert_filter_copy(encoder, &_bk.encoder); + _bk.pos = device.pos; + _bk.p = p; + (*encoder->filter_flush)(encoder); + if (device.pos > length) { + if (_bk.decoder.filter_dtor) + _bk.decoder.filter_dtor(&_bk.decoder); + if (_bk.encoder.filter_dtor) + _bk.encoder.filter_dtor(&_bk.encoder); + + /* restore filter */ + p = bk.p; + device.pos = bk.pos; + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); + mbfl_convert_filter_copy(&bk.decoder, decoder); + mbfl_convert_filter_copy(&bk.encoder, encoder); + break; + } + if (bk.decoder.filter_dtor) bk.decoder.filter_dtor(&bk.decoder); if (bk.encoder.filter_dtor) bk.encoder.filter_dtor(&bk.encoder); - result = mbfl_memory_device_result(&device, result); + p = _bk.p; + device.pos = _bk.pos; + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); + mbfl_convert_filter_copy(&_bk.decoder, decoder); + mbfl_convert_filter_copy(&_bk.encoder, encoder); - mbfl_convert_filter_delete(encoder); - mbfl_convert_filter_delete(decoder); + bk = _bk; } + decoder->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE; + (*encoder->filter_flush)(encoder); + + if (bk.decoder.filter_dtor) + bk.decoder.filter_dtor(&bk.decoder); + if (bk.encoder.filter_dtor) + bk.encoder.filter_dtor(&bk.encoder); + + result = mbfl_memory_device_result(&device, result); + + mbfl_convert_filter_delete(encoder); + mbfl_convert_filter_delete(decoder); + return result; } diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c index 63ca5bc6a2e7..f7c99461719e 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_encoding.c @@ -342,7 +342,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len) /* search MIME charset name */ for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) { if ((*encoding)->mime_name) { - if (strncasecmp((*encoding)->mime_name, name, name_len) == 0 && (*encoding)->mime_name[name_len] == '\0') { + size_t mime_len = strlen((*encoding)->mime_name); + if (mime_len == name_len && strncasecmp((*encoding)->mime_name, name, name_len) == 0) { return *encoding; } } @@ -352,7 +353,8 @@ const mbfl_encoding *mbfl_name2encoding_ex(const char *name, size_t name_len) for (encoding = mbfl_encoding_ptr_list; *encoding; encoding++) { if ((*encoding)->aliases) { for (const char **alias = (*encoding)->aliases; *alias; alias++) { - if (strncasecmp(name, *alias, name_len) == 0 && (*alias)[name_len] == '\0') { + size_t alias_len = strlen(*alias); + if (alias_len == name_len && strncasecmp(name, *alias, name_len) == 0) { return *encoding; } } diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c index 4445a0dc5a1b..d0ee90266b52 100644 --- a/ext/mbstring/mb_gpc.c +++ b/ext/mbstring/mb_gpc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rui Hirokawa | | Moriyoshi Koizumi | diff --git a/ext/mbstring/mb_gpc.h b/ext/mbstring/mb_gpc.h index 63337755cdea..fdbb0c818238 100644 --- a/ext/mbstring/mb_gpc.h +++ b/ext/mbstring/mb_gpc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rui Hirokawa | | Moriyoshi Koizumi | diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 88f9b706ed24..faa21b11a0f7 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tsukada Takuya | | Rui Hirokawa | @@ -56,6 +54,7 @@ #include "mb_gpc.h" #ifdef HAVE_MBREGEX +# include "zend_attributes.h" # include "php_mbregex.h" #endif @@ -116,7 +115,8 @@ static const enum mbfl_no_encoding php_mb_default_identify_list_cn[] = { mbfl_no_encoding_ascii, mbfl_no_encoding_utf8, mbfl_no_encoding_euc_cn, - mbfl_no_encoding_cp936 + mbfl_no_encoding_cp936, + mbfl_no_encoding_gb18030_2022 }; static const enum mbfl_no_encoding php_mb_default_identify_list_tw_hk[] = { @@ -313,7 +313,7 @@ static zend_result php_mb_parse_encoding_list(const char *value, size_t value_le list = (const mbfl_encoding **)pecalloc(size, sizeof(mbfl_encoding*), persistent); entry = list; n = 0; - included_auto = 0; + included_auto = false; p1 = tmpstr; while (1) { const char *comma = memchr(p1, ',', endp - p1); @@ -333,7 +333,7 @@ static zend_result php_mb_parse_encoding_list(const char *value, size_t value_le const enum mbfl_no_encoding *src = MBSTRG(default_detect_order_list); const size_t identify_list_size = MBSTRG(default_detect_order_list_size); size_t i; - included_auto = 1; + included_auto = true; for (i = 0; i < identify_list_size; i++) { *entry++ = mbfl_no2encoding(*src++); n++; @@ -379,7 +379,7 @@ static zend_result php_mb_parse_encoding_array(HashTable *target_hash, const mbf size_t size = zend_hash_num_elements(target_hash) + MBSTRG(default_detect_order_list_size); const mbfl_encoding **list = ecalloc(size, sizeof(mbfl_encoding*)); const mbfl_encoding **entry = list; - bool included_auto = 0; + bool included_auto = false; size_t n = 0; zval *hash_entry; ZEND_HASH_FOREACH_VAL(target_hash, hash_entry) { @@ -396,7 +396,7 @@ static zend_result php_mb_parse_encoding_array(HashTable *target_hash, const mbf const size_t identify_list_size = MBSTRG(default_detect_order_list_size); size_t j; - included_auto = 1; + included_auto = true; for (j = 0; j < identify_list_size; j++) { *entry++ = mbfl_no2encoding(*src++); n++; @@ -624,7 +624,7 @@ static char *php_mb_rfc1867_getword(const zend_encoding *encoding, char **line, static char *php_mb_rfc1867_getword_conf(const zend_encoding *encoding, char *str) /* {{{ */ { - while (*str && isspace(*(unsigned char *)str)) { + while (*str && isspace((unsigned char)*str)) { ++str; } @@ -640,7 +640,7 @@ static char *php_mb_rfc1867_getword_conf(const zend_encoding *encoding, char *st } else { char *strend = str; - while (*strend && !isspace(*(unsigned char *)strend)) { + while (*strend && !isspace((unsigned char)*strend)) { ++strend; } return php_mb_rfc1867_substring_conf(encoding, str, strend - str, 0); @@ -718,6 +718,11 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) } MBSTRG(detect_order_list) = list; MBSTRG(detect_order_list_size) = size; + + if (stage == PHP_INI_STAGE_RUNTIME) { + php_mb_populate_current_detect_order_list(); + } + return SUCCESS; } /* }}} */ @@ -729,7 +734,7 @@ static zend_result _php_mb_ini_mbstring_http_input_set(const char *new_value, si list = (const mbfl_encoding**)pecalloc(1, sizeof(mbfl_encoding*), 1); *list = &mbfl_encoding_pass; size = 1; - } else if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, /* persistent */ 1, /* arg_num */ 0) || size == 0) { + } else if (FAILURE == php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, /* persistent */ true, /* arg_num */ 0) || size == 0) { return FAILURE; } if (MBSTRG(http_input_list)) { @@ -1160,8 +1165,8 @@ PHP_RSHUTDOWN_FUNCTION(mbstring) MBSTRG(outconv_state) = 0; if (MBSTRG(all_encodings_list)) { - GC_DELREF(MBSTRG(all_encodings_list)); - zend_array_destroy(MBSTRG(all_encodings_list)); + /* must be *array* release to remove from GC root buffer and free the hashtable itself */ + zend_array_release(MBSTRG(all_encodings_list)); MBSTRG(all_encodings_list) = NULL; } @@ -1210,17 +1215,17 @@ PHP_FUNCTION(mb_language) ZEND_PARSE_PARAMETERS_END(); if (name == NULL) { - RETVAL_STRING((char *)mbfl_no_language2name(MBSTRG(language))); + RETVAL_STRING(mbfl_no_language2name(MBSTRG(language))); } else { - zend_string *ini_name = ZSTR_INIT_LITERAL("mbstring.language", 0); + zend_string *ini_name = ZSTR_INIT_LITERAL("mbstring.language", false); if (FAILURE == zend_alter_ini_entry(ini_name, name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME)) { zend_argument_value_error(1, "must be a valid language, \"%s\" given", ZSTR_VAL(name)); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); RETURN_THROWS(); } // TODO Make return void RETVAL_TRUE; - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); } } /* }}} */ @@ -1503,7 +1508,7 @@ PHP_FUNCTION(mb_preferred_mime_name) php_error_docref(NULL, E_WARNING, "No MIME preferred name corresponding to \"%s\"", name); RETVAL_FALSE; } else { - RETVAL_STRING((char *)preferred_name); + RETVAL_STRING(preferred_name); } } /* }}} */ @@ -1584,10 +1589,22 @@ PHP_FUNCTION(mb_output_handler) if (SG(sapi_headers).send_default_content_type || free_mimetype) { const char *charset = encoding->mime_name; if (charset) { - char *p; - size_t len = spprintf(&p, 0, "Content-Type: %s; charset=%s", mimetype, charset); - if (sapi_add_header(p, len, 0) != FAILURE) { - SG(sapi_headers).send_default_content_type = 0; + /* Don't try to add a header if we are in an output handler; + * we aren't supposed to directly access the output globals + * from outside of main/output.c, so just try to get the flags + * for the currently running handler, will only succeed if + * there is a handler running. */ + int unused; + bool in_handler = php_output_handler_hook( + PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, + &unused + ) == SUCCESS; + if (!in_handler) { + char *p; + size_t len = spprintf(&p, 0, "Content-Type: %s; charset=%s", mimetype, charset); + if (sapi_add_header(p, len, 0) != FAILURE) { + SG(sapi_headers).send_default_content_type = 0; + } } } @@ -2089,8 +2106,34 @@ static zend_string* mb_get_substr_slow(unsigned char *in, size_t in_len, size_t uint32_t wchar_buf[128]; unsigned int state = 0; + /* For the below call to mb_convert_buf_init, we need to estimate how many bytes the output of this operation will need. + * If possible, we want to initialize the output buffer with enough space, so it is not necessary to grow it dynamically; + * At the same time, we don't want to make it huge and waste a lot of memory. + * + * `len` is the requested number of codepoints; we optimistically guess that each codepoint can be encoded in one byte. + * However, the caller may have requested a huge number of codepoints, more than are actually present in the input string; + * so we also use a 2nd estimate to avoid unnecessary, huge allocations: + * + * `in_len` is the number of input bytes, `from` is the number of codepoints to skip; again, if each leading codepoint is + * encoded in one byte, then there may be as many as `in_len - from` bytes remaining after skipping leading codepoints; + * that gives our 2nd estimate of the needed output buffer size. + * + * If `len == MBFL_SUBSTR_UNTIL_END`, then `len` will be the largest possible `size_t` value, and the `in_len - from` + * estimate will certainly be used instead. */ + + size_t initial_buf_size; + if (from > in_len) { + /* Normally, if `from > in_len`, then the output will definitely be empty, and in fact, `mb_get_substr` uses + * this fact to (usually) just return an empty string in such situations. + * But for SJIS-Mac, one byte can decode to more than one codepoint, so we can't assume the output will + * definitely be empty. If it's not... then our output buffer will be dynamically resized. */ + initial_buf_size = 0; + } else { + initial_buf_size = MIN(len, in_len - from); + } + mb_convert_buf buf; - mb_convert_buf_init(&buf, MIN(len, in_len - from), MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode)); + mb_convert_buf_init(&buf, initial_buf_size, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode)); while (in_len && len) { size_t out_len = enc->to_wchar(&in, &in_len, wchar_buf, 128, &state); @@ -2430,7 +2473,7 @@ PHP_FUNCTION(mb_strcut) if (len > string.len - from) { len = string.len - from; } - RETURN_STR(zend_string_init_fast((const char*)(string.val + from), len & -char_len)); + RETURN_STRINGL_FAST((const char*)(string.val + from), len & -char_len); } if (enc->mblen_table) { @@ -2453,7 +2496,7 @@ PHP_FUNCTION(mb_strcut) } end = p; } - RETURN_STR(zend_string_init_fast((const char*)start, end - start)); + RETURN_STRINGL_FAST((const char*)start, end - start); } ret = mbfl_strcut(&string, &result, from, len); @@ -2776,7 +2819,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons case IS_FALSE: case IS_LONG: case IS_DOUBLE: - ZVAL_COPY(&entry_tmp, entry); + ZVAL_COPY_VALUE(&entry_tmp, entry); break; case IS_ARRAY: chash = php_mb_convert_encoding_recursive( @@ -3370,8 +3413,9 @@ MBSTRING_API const mbfl_encoding* mb_guess_encoding_for_strings(const unsigned c return *elist; } - /* Allocate on stack; when we return, this array is automatically freed */ - struct candidate *array = alloca(elist_size * sizeof(struct candidate)); + /* Allocate on stack or heap */ + ALLOCA_FLAG(use_heap) + struct candidate *array = do_alloca(elist_size * sizeof(struct candidate), use_heap); elist_size = init_candidate_array(array, elist_size, elist, strings, str_lengths, n, strict, order_significant); while (n--) { @@ -3379,6 +3423,7 @@ MBSTRING_API const mbfl_encoding* mb_guess_encoding_for_strings(const unsigned c elist_size = count_demerits(array, elist_size, strict); if (elist_size == 0) { /* All candidates were eliminated */ + free_alloca(array, use_heap); return NULL; } } @@ -3390,7 +3435,10 @@ MBSTRING_API const mbfl_encoding* mb_guess_encoding_for_strings(const unsigned c best = i; } } - return array[best].enc; + + const mbfl_encoding *result = array[best].enc; + free_alloca(array, use_heap); + return result; } /* When doing 'strict' detection, any string which is invalid in the candidate encoding @@ -3468,7 +3516,7 @@ PHP_FUNCTION(mb_detect_encoding) RETURN_FALSE; } - RETVAL_STRING((char *)ret->name); + RETVAL_STRING(ret->name); } /* }}} */ @@ -3514,7 +3562,7 @@ PHP_FUNCTION(mb_encoding_aliases) array_init(return_value); if (encoding->aliases != NULL) { for (const char **alias = encoding->aliases; *alias; ++alias) { - add_next_index_string(return_value, (char *)*alias); + add_next_index_string(return_value, *alias); } } } @@ -3685,11 +3733,26 @@ PHP_FUNCTION(mb_convert_kana) RETVAL_STR(jp_kana_convert(str, enc, opt)); } +static zend_always_inline bool mb_check_stack_limit(void) +{ +#ifdef ZEND_CHECK_STACK_LIMIT + if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) { + zend_call_stack_size_error(); + return true; + } +#endif + return false; +} + static unsigned int mb_recursive_count_strings(zval *var) { unsigned int count = 0; ZVAL_DEREF(var); + if (mb_check_stack_limit()) { + return 0; + } + if (Z_TYPE_P(var) == IS_STRING) { count++; } else if (Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT) { @@ -3720,6 +3783,10 @@ static bool mb_recursive_find_strings(zval *var, const unsigned char **val_list, { ZVAL_DEREF(var); + if (mb_check_stack_limit()) { + return true; + } + if (Z_TYPE_P(var) == IS_STRING) { val_list[*count] = (const unsigned char*)Z_STRVAL_P(var); len_list[*count] = Z_STRLEN_P(var); @@ -3757,6 +3824,10 @@ static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_e { zval *entry, *orig_var; + if (mb_check_stack_limit()) { + return true; + } + orig_var = var; ZVAL_DEREF(var); @@ -3765,17 +3836,25 @@ static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_e zval_ptr_dtor(orig_var); ZVAL_STR(orig_var, ret); } else if (Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT) { - if (Z_TYPE_P(var) == IS_ARRAY) { - SEPARATE_ARRAY(var); - } - if (Z_REFCOUNTED_P(var)) { - if (Z_IS_RECURSIVE_P(var)) { + HashTable *ht = HASH_OF(var); + HashTable *orig_ht = ht; + + if (ht) { + if (GC_IS_RECURSIVE(ht)) { return true; } - Z_PROTECT_RECURSION_P(var); + + GC_TRY_PROTECT_RECURSION(ht); } - HashTable *ht = HASH_OF(var); + if (Z_TYPE_P(var) == IS_ARRAY) { + SEPARATE_ARRAY(var); + ht = Z_ARRVAL_P(var); + + if (ht && ht != orig_ht && !GC_IS_RECURSIVE(ht)) { + GC_TRY_PROTECT_RECURSION(ht); + } + } if (ht != NULL) { ZEND_HASH_FOREACH_VAL(ht, entry) { /* Can be a typed property declaration, in which case we need to remove the reference from the source list. @@ -3794,16 +3873,22 @@ static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_e } if (mb_recursive_convert_variable(entry, from_encoding, to_encoding)) { - if (Z_REFCOUNTED_P(var)) { - Z_UNPROTECT_RECURSION_P(var); + if (ht && ht != orig_ht) { + GC_TRY_UNPROTECT_RECURSION(ht); + } + if (orig_ht) { + GC_TRY_UNPROTECT_RECURSION(orig_ht); } return true; } } ZEND_HASH_FOREACH_END(); } - if (Z_REFCOUNTED_P(var)) { - Z_UNPROTECT_RECURSION_P(var); + if (ht && ht != orig_ht) { + GC_TRY_UNPROTECT_RECURSION(ht); + } + if (orig_ht) { + GC_TRY_UNPROTECT_RECURSION(orig_ht); } } @@ -3877,7 +3962,9 @@ PHP_FUNCTION(mb_convert_variables) efree(ZEND_VOIDP(elist)); efree(ZEND_VOIDP(val_list)); efree(len_list); - php_error_docref(NULL, E_WARNING, "Cannot handle recursive references"); + if (!EG(exception)) { + php_error_docref(NULL, E_WARNING, "Cannot handle recursive references"); + } RETURN_FALSE; } } @@ -3899,7 +3986,9 @@ PHP_FUNCTION(mb_convert_variables) zval *zv = &args[n]; ZVAL_DEREF(zv); if (mb_recursive_convert_variable(zv, from_encoding, to_encoding)) { - php_error_docref(NULL, E_WARNING, "Cannot handle recursive references"); + if (!EG(exception)) { + php_error_docref(NULL, E_WARNING, "Cannot handle recursive references"); + } RETURN_FALSE; } } @@ -4494,7 +4583,7 @@ PHP_FUNCTION(mb_send_mail) ZEND_PARSE_PARAMETERS_END(); if (str_headers) { - if (strlen(ZSTR_VAL(str_headers)) != ZSTR_LEN(str_headers)) { + if (UNEXPECTED(zend_str_has_nul_byte(str_headers))) { zend_argument_value_error(4, "must not contain any null bytes"); RETURN_THROWS(); } @@ -4678,14 +4767,14 @@ PHP_FUNCTION(mb_send_mail) str_headers = smart_str_extract(&str); - zend_string *force_extra_parameters = zend_ini_str_ex("mail.force_extra_parameters", strlen("mail.force_extra_parameters"), false, NULL); + zend_string *force_extra_parameters = zend_ini_str_literal("mail.force_extra_parameters"); if (force_extra_parameters) { extra_cmd = php_escape_shell_cmd(force_extra_parameters); } else if (extra_cmd) { extra_cmd = php_escape_shell_cmd(extra_cmd); } - RETVAL_BOOL(php_mail(to_r, ZSTR_VAL(subject), message, ZSTR_VAL(str_headers), extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)); + RETVAL_BOOL(php_mail(to_r, ZSTR_VAL(subject), message, ZSTR_VAL(str_headers), extra_cmd)); if (extra_cmd) { zend_string_release_ex(extra_cmd, 0); @@ -4714,7 +4803,7 @@ PHP_FUNCTION(mb_get_info) { zend_string *type = NULL; size_t n; - char *name; + const char *name; zval row; const mbfl_encoding **entry; const mbfl_language *lang = mbfl_no2language(MBSTRG(language)); @@ -4729,26 +4818,26 @@ PHP_FUNCTION(mb_get_info) if (!type || zend_string_equals_literal_ci(type, "all")) { array_init(return_value); if (MBSTRG(current_internal_encoding)) { - add_assoc_string(return_value, "internal_encoding", (char *)MBSTRG(current_internal_encoding)->name); + add_assoc_string(return_value, "internal_encoding", MBSTRG(current_internal_encoding)->name); } if (MBSTRG(http_input_identify)) { - add_assoc_string(return_value, "http_input", (char *)MBSTRG(http_input_identify)->name); + add_assoc_string(return_value, "http_input", MBSTRG(http_input_identify)->name); } if (MBSTRG(current_http_output_encoding)) { - add_assoc_string(return_value, "http_output", (char *)MBSTRG(current_http_output_encoding)->name); + add_assoc_string(return_value, "http_output", MBSTRG(current_http_output_encoding)->name); } add_assoc_str(return_value, "http_output_conv_mimetypes", - zend_ini_str("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes") - 1, 0) + zend_string_copy(zend_ini_str_literal("mbstring.http_output_conv_mimetypes")) ); - name = (char *)mbfl_no_encoding2name(lang->mail_charset); + name = mbfl_no_encoding2name(lang->mail_charset); add_assoc_string(return_value, "mail_charset", name); - name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding); + name = mbfl_no_encoding2name(lang->mail_header_encoding); add_assoc_string(return_value, "mail_header_encoding", name); - name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding); + name = mbfl_no_encoding2name(lang->mail_body_encoding); add_assoc_string(return_value, "mail_body_encoding", name); add_assoc_long(return_value, "illegal_chars", MBSTRG(illegalchars)); @@ -4759,7 +4848,7 @@ PHP_FUNCTION(mb_get_info) add_assoc_string(return_value, "encoding_translation", "Off"); } - name = (char *)mbfl_no_language2name(MBSTRG(language)); + name = mbfl_no_language2name(MBSTRG(language)); add_assoc_string(return_value, "language", name); // TODO Seems to always have one entry at least? @@ -4790,31 +4879,25 @@ PHP_FUNCTION(mb_get_info) } } else if (zend_string_equals_literal_ci(type, "internal_encoding")) { ZEND_ASSERT(MBSTRG(current_internal_encoding)); - RETURN_STRING((char *)MBSTRG(current_internal_encoding)->name); + RETURN_STRING(MBSTRG(current_internal_encoding)->name); } else if (zend_string_equals_literal_ci(type, "http_input")) { if (MBSTRG(http_input_identify)) { - RETURN_STRING((char *)MBSTRG(http_input_identify)->name); + RETURN_STRING(MBSTRG(http_input_identify)->name); } RETURN_NULL(); } else if (zend_string_equals_literal_ci(type, "http_output")) { ZEND_ASSERT(MBSTRG(current_http_output_encoding)); - RETURN_STRING((char *)MBSTRG(current_http_output_encoding)->name); + RETURN_STRING(MBSTRG(current_http_output_encoding)->name); } else if (zend_string_equals_literal_ci(type, "http_output_conv_mimetypes")) { - RETURN_STR( - zend_ini_str( - "mbstring.http_output_conv_mimetypes", - sizeof("mbstring.http_output_conv_mimetypes") - 1, - false - ) - ); + RETURN_STR_COPY(zend_ini_str_literal("mbstring.http_output_conv_mimetypes")); } else if (zend_string_equals_literal_ci(type, "mail_charset")) { - name = (char *)mbfl_no_encoding2name(lang->mail_charset); + name = mbfl_no_encoding2name(lang->mail_charset); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "mail_header_encoding")) { - name = (char *)mbfl_no_encoding2name(lang->mail_header_encoding); + name = mbfl_no_encoding2name(lang->mail_header_encoding); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "mail_body_encoding")) { - name = (char *)mbfl_no_encoding2name(lang->mail_body_encoding); + name = mbfl_no_encoding2name(lang->mail_body_encoding); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "illegal_chars")) { RETURN_LONG(MBSTRG(illegalchars)); @@ -4825,7 +4908,7 @@ PHP_FUNCTION(mb_get_info) RETURN_STRING("Off"); } } else if (zend_string_equals_literal_ci(type, "language")) { - name = (char *)mbfl_no_language2name(MBSTRG(language)); + name = mbfl_no_language2name(MBSTRG(language)); RETURN_STRING(name); } else if (zend_string_equals_literal_ci(type, "detect_order")) { // TODO Seems to always have one entry at least? @@ -5176,7 +5259,7 @@ static bool mb_fast_check_utf8_default(zend_string *str) } break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -5566,19 +5649,16 @@ static bool mb_check_str_encoding(zend_string *str, const mbfl_encoding *encodin static bool php_mb_check_encoding_recursive(HashTable *vars, const mbfl_encoding *encoding) { - zend_long idx; zend_string *key; zval *entry; bool valid = true; - (void)(idx); /* Suppress spurious compiler warning that `idx` is not used */ - if (GC_IS_RECURSIVE(vars)) { php_error_docref(NULL, E_WARNING, "Cannot not handle circular references"); return false; } GC_TRY_PROTECT_RECURSION(vars); - ZEND_HASH_FOREACH_KEY_VAL(vars, idx, key, entry) { + ZEND_HASH_FOREACH_STR_KEY_VAL(vars, key, entry) { ZVAL_DEREF(entry); if (key) { if (!mb_check_str_encoding(key, encoding)) { @@ -5841,6 +5921,11 @@ PHP_FUNCTION(mb_str_pad) } size_t pad_length = mb_get_strlen(pad, encoding); + if (pad_length == 0) { + /* Possible with invalidly encoded padding string. */ + zend_argument_must_not_be_empty_error(3); + RETURN_THROWS(); + } size_t num_mb_pad_chars = pad_to_length - input_length; @@ -5972,6 +6057,11 @@ static void php_mb_populate_current_detect_order_list(void) entry[i] = mbfl_no2encoding(src[i]); } } + + if (MBSTRG(current_detect_order_list) != NULL) { + efree(ZEND_VOIDP(MBSTRG(current_detect_order_list))); + } + MBSTRG(current_detect_order_list) = entry; MBSTRG(current_detect_order_list_size) = nentries; } @@ -6655,13 +6745,15 @@ static zend_string* mb_mime_header_decode(zend_string *input, const mbfl_encodin p = temp; /* Decoding of MIME encoded word was successful; * Try to collapse a run of whitespace */ - if (p < e && (*p == '\n' || *p == '\r')) { + if (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')) { do { p++; } while (p < e && (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')); /* We will only actually output a space if this is not immediately followed * by another valid encoded word */ space_pending = true; + } else { + space_pending = false; } continue; } diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 7256605bd246..c12c61290a15 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tsukada Takuya | | Hironori Sato | diff --git a/ext/mbstring/mbstring.stub.php b/ext/mbstring/mbstring.stub.php index af9c5cbb93ea..109a3ad564d8 100644 --- a/ext/mbstring/mbstring.stub.php +++ b/ext/mbstring/mbstring.stub.php @@ -7,6 +7,7 @@ * @var string * @cvalue php_mb_oniguruma_version */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] const MB_ONIGURUMA_VERSION = UNKNOWN; #endif @@ -197,57 +198,73 @@ function mb_str_pad(string $string, int $length, string $pad_string = " ", int $ #ifdef HAVE_MBREGEX /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_regex_encoding(?string $encoding = null): string|bool {} /** @param array $matches */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg(string $pattern, string $string, &$matches = null): bool {} /** @param array $matches */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_eregi(string $pattern, string $string, &$matches = null): bool {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_replace(string $pattern, string $replacement, string $string, ?string $options = null): string|false|null {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_eregi_replace(string $pattern, string $replacement, string $string, ?string $options = null): string|false|null {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_replace_callback(string $pattern, callable $callback, string $string, ?string $options = null): string|false|null {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_split(string $pattern, string $string, int $limit = -1): array|false {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_match(string $pattern, string $string, ?string $options = null): bool {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search(?string $pattern = null, ?string $options = null): bool {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_pos(?string $pattern = null, ?string $options = null): array|false {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_regs(?string $pattern = null, ?string $options = null): array|false {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_init(string $string, ?string $pattern = null, ?string $options = null): bool {} /** * @return array|false * @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_getregs(): array|false {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_getpos(): int {} +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_ereg_search_setpos(int $offset): bool {} /** @refcount 1 */ +#[\Deprecated(since: '8.6', message: "because the underlying library is no longer maintained")] function mb_regex_set_options(?string $options = null): string {} #endif diff --git a/ext/mbstring/mbstring_arginfo.h b/ext/mbstring/mbstring_arginfo.h index 230dddf96941..bc9db3d415c1 100644 --- a/ext/mbstring/mbstring_arginfo.h +++ b/ext/mbstring/mbstring_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 03c07f68bea7d7b96e6dc11f180f45663b859ed3 */ +/* This is a generated file, edit mbstring.stub.php instead. + * Stub hash: f02c317efd6814f902ea75c9d222893713546845 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mb_language, 0, 0, MAY_BE_STRING|MAY_BE_BOOL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, language, IS_STRING, 1, "null") @@ -413,22 +413,22 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(mb_chr, arginfo_mb_chr) ZEND_FE(mb_str_pad, arginfo_mb_str_pad) #if defined(HAVE_MBREGEX) - ZEND_FE(mb_regex_encoding, arginfo_mb_regex_encoding) - ZEND_FE(mb_ereg, arginfo_mb_ereg) - ZEND_FE(mb_eregi, arginfo_mb_eregi) - ZEND_FE(mb_ereg_replace, arginfo_mb_ereg_replace) - ZEND_FE(mb_eregi_replace, arginfo_mb_eregi_replace) - ZEND_FE(mb_ereg_replace_callback, arginfo_mb_ereg_replace_callback) - ZEND_FE(mb_split, arginfo_mb_split) - ZEND_FE(mb_ereg_match, arginfo_mb_ereg_match) - ZEND_FE(mb_ereg_search, arginfo_mb_ereg_search) - ZEND_FE(mb_ereg_search_pos, arginfo_mb_ereg_search_pos) - ZEND_FE(mb_ereg_search_regs, arginfo_mb_ereg_search_regs) - ZEND_FE(mb_ereg_search_init, arginfo_mb_ereg_search_init) - ZEND_FE(mb_ereg_search_getregs, arginfo_mb_ereg_search_getregs) - ZEND_FE(mb_ereg_search_getpos, arginfo_mb_ereg_search_getpos) - ZEND_FE(mb_ereg_search_setpos, arginfo_mb_ereg_search_setpos) - ZEND_FE(mb_regex_set_options, arginfo_mb_regex_set_options) + ZEND_RAW_FENTRY("mb_regex_encoding", zif_mb_regex_encoding, arginfo_mb_regex_encoding, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg", zif_mb_ereg, arginfo_mb_ereg, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_eregi", zif_mb_eregi, arginfo_mb_eregi, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_replace", zif_mb_ereg_replace, arginfo_mb_ereg_replace, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_eregi_replace", zif_mb_eregi_replace, arginfo_mb_eregi_replace, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_replace_callback", zif_mb_ereg_replace_callback, arginfo_mb_ereg_replace_callback, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_split", zif_mb_split, arginfo_mb_split, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_match", zif_mb_ereg_match, arginfo_mb_ereg_match, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search", zif_mb_ereg_search, arginfo_mb_ereg_search, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_pos", zif_mb_ereg_search_pos, arginfo_mb_ereg_search_pos, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_regs", zif_mb_ereg_search_regs, arginfo_mb_ereg_search_regs, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_init", zif_mb_ereg_search_init, arginfo_mb_ereg_search_init, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_getregs", zif_mb_ereg_search_getregs, arginfo_mb_ereg_search_getregs, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_getpos", zif_mb_ereg_search_getpos, arginfo_mb_ereg_search_getpos, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_ereg_search_setpos", zif_mb_ereg_search_setpos, arginfo_mb_ereg_search_setpos, ZEND_ACC_DEPRECATED, NULL, NULL) + ZEND_RAW_FENTRY("mb_regex_set_options", zif_mb_regex_set_options, arginfo_mb_regex_set_options, ZEND_ACC_DEPRECATED, NULL, NULL) #endif ZEND_FE_END }; @@ -436,7 +436,7 @@ static const zend_function_entry ext_functions[] = { static void register_mbstring_symbols(int module_number) { #if defined(HAVE_MBREGEX) - REGISTER_STRING_CONSTANT("MB_ONIGURUMA_VERSION", php_mb_oniguruma_version, CONST_PERSISTENT); + zend_constant *const_MB_ONIGURUMA_VERSION = REGISTER_STRING_CONSTANT("MB_ONIGURUMA_VERSION", php_mb_oniguruma_version, CONST_PERSISTENT | CONST_DEPRECATED); #endif REGISTER_LONG_CONSTANT("MB_CASE_UPPER", PHP_UNICODE_CASE_UPPER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MB_CASE_LOWER", PHP_UNICODE_CASE_LOWER, CONST_PERSISTENT); @@ -446,4 +446,145 @@ static void register_mbstring_symbols(int module_number) REGISTER_LONG_CONSTANT("MB_CASE_LOWER_SIMPLE", PHP_UNICODE_CASE_LOWER_SIMPLE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MB_CASE_TITLE_SIMPLE", PHP_UNICODE_CASE_TITLE_SIMPLE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MB_CASE_FOLD_SIMPLE", PHP_UNICODE_CASE_FOLD_SIMPLE, CONST_PERSISTENT); + +#if defined(HAVE_MBREGEX) + + zend_attribute *attribute_Deprecated_func_mb_regex_encoding_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_regex_encoding", sizeof("mb_regex_encoding") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_regex_encoding_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_encoding_0->args[0].value, attribute_Deprecated_func_mb_regex_encoding_0_arg0_str); + attribute_Deprecated_func_mb_regex_encoding_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_regex_encoding_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_encoding_0->args[1].value, attribute_Deprecated_func_mb_regex_encoding_0_arg1_str); + attribute_Deprecated_func_mb_regex_encoding_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg", sizeof("mb_ereg") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_0->args[0].value, attribute_Deprecated_func_mb_ereg_0_arg0_str); + attribute_Deprecated_func_mb_ereg_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_0->args[1].value, attribute_Deprecated_func_mb_ereg_0_arg1_str); + attribute_Deprecated_func_mb_ereg_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_eregi_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_eregi", sizeof("mb_eregi") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_eregi_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_0->args[0].value, attribute_Deprecated_func_mb_eregi_0_arg0_str); + attribute_Deprecated_func_mb_eregi_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_eregi_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_0->args[1].value, attribute_Deprecated_func_mb_eregi_0_arg1_str); + attribute_Deprecated_func_mb_eregi_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_replace_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_replace", sizeof("mb_ereg_replace") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_replace_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_0->args[0].value, attribute_Deprecated_func_mb_ereg_replace_0_arg0_str); + attribute_Deprecated_func_mb_ereg_replace_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_replace_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_0->args[1].value, attribute_Deprecated_func_mb_ereg_replace_0_arg1_str); + attribute_Deprecated_func_mb_ereg_replace_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_eregi_replace_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_eregi_replace", sizeof("mb_eregi_replace") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_eregi_replace_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_replace_0->args[0].value, attribute_Deprecated_func_mb_eregi_replace_0_arg0_str); + attribute_Deprecated_func_mb_eregi_replace_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_eregi_replace_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_eregi_replace_0->args[1].value, attribute_Deprecated_func_mb_eregi_replace_0_arg1_str); + attribute_Deprecated_func_mb_eregi_replace_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_replace_callback_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_replace_callback", sizeof("mb_ereg_replace_callback") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_replace_callback_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_callback_0->args[0].value, attribute_Deprecated_func_mb_ereg_replace_callback_0_arg0_str); + attribute_Deprecated_func_mb_ereg_replace_callback_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_replace_callback_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_replace_callback_0->args[1].value, attribute_Deprecated_func_mb_ereg_replace_callback_0_arg1_str); + attribute_Deprecated_func_mb_ereg_replace_callback_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_split_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_split", sizeof("mb_split") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_split_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_split_0->args[0].value, attribute_Deprecated_func_mb_split_0_arg0_str); + attribute_Deprecated_func_mb_split_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_split_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_split_0->args[1].value, attribute_Deprecated_func_mb_split_0_arg1_str); + attribute_Deprecated_func_mb_split_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_match_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_match", sizeof("mb_ereg_match") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_match_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_match_0->args[0].value, attribute_Deprecated_func_mb_ereg_match_0_arg0_str); + attribute_Deprecated_func_mb_ereg_match_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_match_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_match_0->args[1].value, attribute_Deprecated_func_mb_ereg_match_0_arg1_str); + attribute_Deprecated_func_mb_ereg_match_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search", sizeof("mb_ereg_search") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_pos_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_pos", sizeof("mb_ereg_search_pos") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_pos_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_pos_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_pos_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_pos_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_pos_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_pos_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_pos_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_pos_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_regs_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_regs", sizeof("mb_ereg_search_regs") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_regs_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_regs_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_regs_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_regs_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_regs_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_regs_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_regs_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_regs_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_init_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_init", sizeof("mb_ereg_search_init") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_init_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_init_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_init_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_init_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_init_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_init_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_init_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_init_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_getregs_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_getregs", sizeof("mb_ereg_search_getregs") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_getregs_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getregs_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_getregs_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_getregs_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_getregs_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getregs_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_getregs_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_getregs_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_getpos_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_getpos", sizeof("mb_ereg_search_getpos") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_getpos_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getpos_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_getpos_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_getpos_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_getpos_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_getpos_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_getpos_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_getpos_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_ereg_search_setpos_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_ereg_search_setpos", sizeof("mb_ereg_search_setpos") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_ereg_search_setpos_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_setpos_0->args[0].value, attribute_Deprecated_func_mb_ereg_search_setpos_0_arg0_str); + attribute_Deprecated_func_mb_ereg_search_setpos_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_ereg_search_setpos_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_ereg_search_setpos_0->args[1].value, attribute_Deprecated_func_mb_ereg_search_setpos_0_arg1_str); + attribute_Deprecated_func_mb_ereg_search_setpos_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_mb_regex_set_options_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mb_regex_set_options", sizeof("mb_regex_set_options") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_func_mb_regex_set_options_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_set_options_0->args[0].value, attribute_Deprecated_func_mb_regex_set_options_0_arg0_str); + attribute_Deprecated_func_mb_regex_set_options_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mb_regex_set_options_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_func_mb_regex_set_options_0->args[1].value, attribute_Deprecated_func_mb_regex_set_options_0_arg1_str); + attribute_Deprecated_func_mb_regex_set_options_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +#endif +#if defined(HAVE_MBREGEX) + + zend_attribute *attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0 = zend_add_global_constant_attribute(const_MB_ONIGURUMA_VERSION, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + zend_string *attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg0_str = zend_string_init("8.6", strlen("8.6"), 1); + ZVAL_STR(&attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[0].value, attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg0_str); + attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg1_str = zend_string_init("because the underlying library is no longer maintained", strlen("because the underlying library is no longer maintained"), 1); + ZVAL_STR(&attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[1].value, attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0_arg1_str); + attribute_Deprecated_const_MB_ONIGURUMA_VERSION_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +#endif } diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 26eeb78a3cbf..1043c4a46eb2 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tsukada Takuya | +----------------------------------------------------------------------+ @@ -409,8 +407,13 @@ int php_mb_regex_set_mbctype(const char *encname) if (mbctype == ONIG_ENCODING_UNDEF) { return FAILURE; } + const mbfl_encoding *mbfl_enc = mbfl_name2encoding(encname); + if (mbfl_enc == NULL) { + /* Encoding supported by Oniguruma but not by mbfl */ + return FAILURE; + } MBREX(current_mbctype) = mbctype; - MBREX(current_mbctype_mbfl_encoding) = mbfl_name2encoding(encname); + MBREX(current_mbctype_mbfl_encoding) = mbfl_enc; return SUCCESS; } /* }}} */ @@ -779,7 +782,7 @@ static inline void mb_regex_substitute( continue; } if (name_end[0] == delim) break; - if (maybe_num && !isdigit(name_end[0])) maybe_num = 0; + if (maybe_num && !isdigit((unsigned char)name_end[0])) maybe_num = 0; name_end++; } p = name_end + 1; @@ -1103,7 +1106,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache) == SUCCESS && !Z_ISUNDEF(retval)) { convert_to_string(&retval); - smart_str_appendl(&out_buf, Z_STRVAL(retval), Z_STRLEN(retval)); + smart_str_append(&out_buf, Z_STR(retval)); smart_str_free(&eval_buf); zval_ptr_dtor(&retval); } @@ -1303,11 +1306,7 @@ PHP_FUNCTION(mb_ereg_match) /* match */ err = onig_match_with_param(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, NULL, 0, mp); onig_free_match_param(mp); - if (err >= 0) { - RETVAL_TRUE; - } else { - RETVAL_FALSE; - } + RETURN_BOOL(err >= 0); } /* }}} */ @@ -1510,9 +1509,7 @@ PHP_FUNCTION(mb_ereg_search_getregs) int beg, end; OnigUChar *str; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (MBREX(search_regs) != NULL && Z_TYPE(MBREX(search_str)) == IS_STRING) { array_init(return_value); @@ -1548,9 +1545,7 @@ PHP_FUNCTION(mb_ereg_search_getregs) /* {{{ Get search start position */ PHP_FUNCTION(mb_ereg_search_getpos) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETVAL_LONG(MBREX(search_pos)); } diff --git a/ext/mbstring/php_mbregex.h b/ext/mbstring/php_mbregex.h index 18a762d5a614..41c98b6d7465 100644 --- a/ext/mbstring/php_mbregex.h +++ b/ext/mbstring/php_mbregex.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Moriyoshi Koizumi | +----------------------------------------------------------------------+ diff --git a/ext/mbstring/php_onig_compat.h b/ext/mbstring/php_onig_compat.h index c97ba0c5cb67..5a1fa8eeaaf1 100644 --- a/ext/mbstring/php_onig_compat.h +++ b/ext/mbstring/php_onig_compat.h @@ -5,4 +5,10 @@ #define regex_t php_mb_regex_t #define re_registers php_mb_re_registers +/* Required for some distros that conditionally override PV_. + * As we're in C99 this header is always available. */ +#ifndef HAVE_STDARG_H +# define HAVE_STDARG_H +#endif + #endif /* _PHP_ONIG_COMPAT_H */ diff --git a/ext/mbstring/php_unicode.c b/ext/mbstring/php_unicode.c index 988f5e9cc921..ce255e401364 100644 --- a/ext/mbstring/php_unicode.c +++ b/ext/mbstring/php_unicode.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong (wez@thebrainroom.com) | +----------------------------------------------------------------------+ @@ -180,7 +178,9 @@ static unsigned php_unicode_totitle_raw(unsigned code, const mbfl_encoding *enc) static unsigned php_unicode_tofold_raw(unsigned code, const mbfl_encoding *enc) { - if (code < 0x80) { + /* After the ASCII characters, the first codepoint with an special case-folded version + * is 0xB5 (MICRO SIGN) */ + if (code < 0xB5) { /* Fast path for ASCII */ if (code >= 0x41 && code <= 0x5A) { if (UNEXPECTED(enc == &mbfl_encoding_8859_9 && code == 0x49)) { @@ -461,7 +461,7 @@ MBSTRING_API zend_string *php_unicode_convert_case(php_case_mode case_mode, cons } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } converted_end = p; diff --git a/ext/mbstring/php_unicode.h b/ext/mbstring/php_unicode.h index 1326761943dc..ac96f9daee51 100644 --- a/ext/mbstring/php_unicode.h +++ b/ext/mbstring/php_unicode.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong (wez@thebrainroom.com) | +----------------------------------------------------------------------+ diff --git a/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt b/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt new file mode 100644 index 000000000000..e58be7e50d8a --- /dev/null +++ b/ext/mbstring/tests/GHSA-74r9-qxhc-fx53.phpt @@ -0,0 +1,50 @@ +--TEST-- +GHSA-74r9-qxhc-fx53: Out-of-bounds access in mbfl_name2encoding_ex() +--CREDITS-- +Akshay Jain (AkshayJainG) +--EXTENSIONS-- +mbstring +--FILE-- +getMessage(), "\n"; + } +} + +ini_set('mbstring.detect_order', $encoding); +ini_set('mbstring.detect_order', $alias); +ini_set('mbstring.http_output', $encoding); +ini_set('mbstring.http_output', $alias); + +test(fn () => mb_convert_encoding('foo', $encoding, $encoding)); +test(fn () => mb_convert_encoding('foo', $alias, $alias)); +test(fn () => mb_detect_encoding('foo', $encoding)); +test(fn () => mb_detect_encoding('foo', $alias)); +test(fn () => mb_convert_variables($encoding, $alias, $var)); +test(fn () => mb_detect_order($encoding)); +test(fn () => mb_detect_order($alias)); + +?> +--EXPECTF-- +Warning: ini_set(): INI setting contains invalid encoding "UTF-8" in %s on line %d + +Warning: ini_set(): INI setting contains invalid encoding "binary" in %s on line %d + +Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d + +Deprecated: ini_set(): Use of mbstring.http_output is deprecated in %s on line %d +ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "UTF-8" +ValueError: mb_convert_encoding(): Argument #3 ($from_encoding) contains invalid encoding "binary" +ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "UTF-8" +ValueError: mb_detect_encoding(): Argument #2 ($encodings) contains invalid encoding "binary" +ValueError: mb_convert_variables(): Argument #2 ($from_encoding) contains invalid encoding "binary" +ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "UTF-8" +ValueError: mb_detect_order(): Argument #1 ($encoding) contains invalid encoding "binary" diff --git a/ext/mbstring/tests/bug43994.phpt b/ext/mbstring/tests/bug43994.phpt index b4ae29ff40e7..cc6953808cc6 100644 --- a/ext/mbstring/tests/bug43994.phpt +++ b/ext/mbstring/tests/bug43994.phpt @@ -31,9 +31,13 @@ try { var_dump($mb_regs); ?> ---EXPECT-- +--EXPECTF-- Without $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg(): Argument #1 ($pattern) must not be empty With $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg(): Argument #1 ($pattern) must not be empty NULL diff --git a/ext/mbstring/tests/bug54494.phpt b/ext/mbstring/tests/bug54494.phpt index 29a4b2fb5992..c32a9ad6df11 100644 --- a/ext/mbstring/tests/bug54494.phpt +++ b/ext/mbstring/tests/bug54494.phpt @@ -2,12 +2,11 @@ Bug #54494: mb_substr() mishandles UTF-32LE and UCS-2LE --EXTENSIONS-- mbstring +--INI-- +internal_encoding=UTF-8 --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) bool(true) + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) diff --git a/ext/mbstring/tests/bug72164.phpt b/ext/mbstring/tests/bug72164.phpt index e4ed04ba5eba..2b8f3950d92c 100644 --- a/ext/mbstring/tests/bug72164.phpt +++ b/ext/mbstring/tests/bug72164.phpt @@ -19,5 +19,6 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Option "e" is not supported diff --git a/ext/mbstring/tests/bug72399.phpt b/ext/mbstring/tests/bug72399.phpt index 4d3ea6d28c0b..bf9880c0ab42 100644 --- a/ext/mbstring/tests/bug72399.phpt +++ b/ext/mbstring/tests/bug72399.phpt @@ -19,7 +19,12 @@ try { echo $e->getMessage() . \PHP_EOL; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(0) "" + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d No pattern was provided diff --git a/ext/mbstring/tests/bug72402.phpt b/ext/mbstring/tests/bug72402.phpt index 0441887e33c7..511c18bfec2c 100644 --- a/ext/mbstring/tests/bug72402.phpt +++ b/ext/mbstring/tests/bug72402.phpt @@ -17,5 +17,6 @@ try { } catch(Exception $e) {} ?> DONE ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace_callback() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d DONE diff --git a/ext/mbstring/tests/bug72691.phpt b/ext/mbstring/tests/bug72691.phpt index db299e9d9dbc..9147d149fcb3 100644 --- a/ext/mbstring/tests/bug72691.phpt +++ b/ext/mbstring/tests/bug72691.phpt @@ -27,23 +27,48 @@ mb_ereg_search('\Z'); var_dump(mb_ereg_search_getpos()); var_dump(mb_ereg_search_getregs()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(0) "" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(0) "" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "foo" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(0) "" diff --git a/ext/mbstring/tests/bug72693.phpt b/ext/mbstring/tests/bug72693.phpt index 6596eadd5fea..7b120164afab 100644 --- a/ext/mbstring/tests/bug72693.phpt +++ b/ext/mbstring/tests/bug72693.phpt @@ -26,18 +26,41 @@ var_dump(mb_ereg_search_getpos()); var_dump(mb_ereg_search('\Z')); var_dump(mb_ereg_search_getpos()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "foo" } + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) diff --git a/ext/mbstring/tests/bug72694.phpt b/ext/mbstring/tests/bug72694.phpt index ed7d2e79250e..0789f3620817 100644 --- a/ext/mbstring/tests/bug72694.phpt +++ b/ext/mbstring/tests/bug72694.phpt @@ -16,8 +16,17 @@ var_dump(mb_ereg_search_getpos()); var_dump(mb_ereg_search('\Z')); var_dump(mb_ereg_search_getpos()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(3) diff --git a/ext/mbstring/tests/bug72710.phpt b/ext/mbstring/tests/bug72710.phpt index ca1558c2ff1f..614abcf542f8 100644 --- a/ext/mbstring/tests/bug72710.phpt +++ b/ext/mbstring/tests/bug72710.phpt @@ -11,4 +11,6 @@ if (!function_exists('mb_ereg')) die('skip mbregex support not available'); mb_ereg('(?<0>a)', 'a'); ?> --EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): mbregex compile err: invalid group name <0> in %s on line %d diff --git a/ext/mbstring/tests/bug73532.phpt b/ext/mbstring/tests/bug73532.phpt index 27269296894c..1af3e2422904 100644 --- a/ext/mbstring/tests/bug73532.phpt +++ b/ext/mbstring/tests/bug73532.phpt @@ -10,5 +10,6 @@ if (!function_exists('mb_ereg')) die('skip mbregex support not available'); ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug73646.phpt b/ext/mbstring/tests/bug73646.phpt index 9897b866439e..7b3e98164989 100644 --- a/ext/mbstring/tests/bug73646.phpt +++ b/ext/mbstring/tests/bug73646.phpt @@ -11,5 +11,7 @@ if (!function_exists('mb_ereg')) die('skip mbregex support not available'); var_dump(mb_ereg_search_init(NULL)); ?> --EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Deprecated: mb_ereg_search_init(): Passing null to parameter #1 ($string) of type string is deprecated in %s on line %d bool(true) diff --git a/ext/mbstring/tests/bug76999.phpt b/ext/mbstring/tests/bug76999.phpt index 57e286af3b8a..5c6dc442573f 100644 --- a/ext/mbstring/tests/bug76999.phpt +++ b/ext/mbstring/tests/bug76999.phpt @@ -19,9 +19,20 @@ try { } var_dump(mb_regex_set_options()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "pr" + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "mr" + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(3) "imd" + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Option "a" is not supported + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "mr" diff --git a/ext/mbstring/tests/bug77367.phpt b/ext/mbstring/tests/bug77367.phpt index ad1dac2e07c8..f4a1a373a98f 100644 --- a/ext/mbstring/tests/bug77367.phpt +++ b/ext/mbstring/tests/bug77367.phpt @@ -11,5 +11,8 @@ if (!function_exists('mb_split')) die('skip mb_split() not available'); mb_regex_encoding('UTF-8'); var_dump(mb_split("\\w", "\xfc")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77370.phpt b/ext/mbstring/tests/bug77370.phpt index a2e3759c120a..8ccb169f83e0 100644 --- a/ext/mbstring/tests/bug77370.phpt +++ b/ext/mbstring/tests/bug77370.phpt @@ -11,5 +11,7 @@ if (!function_exists('mb_split')) die('skip mb_split() not available'); var_dump(mb_split(" \xfd","")); ?> --EXPECTF-- +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line 2 + Warning: mb_split(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77371.phpt b/ext/mbstring/tests/bug77371.phpt index 767533c66a4e..b4a88ffc5124 100644 --- a/ext/mbstring/tests/bug77371.phpt +++ b/ext/mbstring/tests/bug77371.phpt @@ -11,5 +11,7 @@ if (!function_exists('mb_ereg')) die('skip mb_ereg() not available'); var_dump(mb_ereg("()0\xfc00000\xfc00000\xfc00000\xfc","")); ?> --EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77381.phpt b/ext/mbstring/tests/bug77381.phpt index 76607bc9ceba..cde197c49a68 100644 --- a/ext/mbstring/tests/bug77381.phpt +++ b/ext/mbstring/tests/bug77381.phpt @@ -14,14 +14,22 @@ var_dump(mb_ereg("0000\\"."\xf5","0")); var_dump(mb_ereg("(?i)FFF00000000000000000\xfd","")); ?> --EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77418.phpt b/ext/mbstring/tests/bug77418.phpt index 352e125d689e..2227eef44a1b 100644 --- a/ext/mbstring/tests/bug77418.phpt +++ b/ext/mbstring/tests/bug77418.phpt @@ -12,5 +12,8 @@ mb_regex_encoding("UTF-32"); var_dump(mb_split("\x00\x00\x00\x5c\x00\x00\x00B","000000000000000000000000000000")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug77428.phpt b/ext/mbstring/tests/bug77428.phpt index c65cd000042f..71f9e09b0b1e 100644 --- a/ext/mbstring/tests/bug77428.phpt +++ b/ext/mbstring/tests/bug77428.phpt @@ -15,6 +15,9 @@ var_dump(mb_ereg_replace('(%)', '\\\1', 'a%c')); var_dump(mb_ereg_replace('(%)', '\\\\1', 'a%c')); ?> ---EXPECT-- -string(4) "a\%c" -string(4) "a\%c" +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +string(4) "a\%%c" + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +string(4) "a\%%c" diff --git a/ext/mbstring/tests/bug77514.phpt b/ext/mbstring/tests/bug77514.phpt index 4b33cca8a309..f6b7ca5d1808 100644 --- a/ext/mbstring/tests/bug77514.phpt +++ b/ext/mbstring/tests/bug77514.phpt @@ -13,5 +13,6 @@ $a="abc123"; var_dump(mb_ereg_replace("123","def\\",$a)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "abcdef\" diff --git a/ext/mbstring/tests/bug78559.phpt b/ext/mbstring/tests/bug78559.phpt index e107d1ba864a..18b1fe00f83a 100644 --- a/ext/mbstring/tests/bug78559.phpt +++ b/ext/mbstring/tests/bug78559.phpt @@ -12,5 +12,6 @@ $str = "5b5b5b5b5b5b5b492a5bce946b5c4b5d5c6b5c4b5d5c4b5d1cceb04b5d1cceb07a73717e $str = hex2bin($str); var_dump(mb_eregi($str, $str)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/bug78633.phpt b/ext/mbstring/tests/bug78633.phpt index a5dcd48b9bf9..42a1ccc4ed2d 100644 --- a/ext/mbstring/tests/bug78633.phpt +++ b/ext/mbstring/tests/bug78633.phpt @@ -15,5 +15,6 @@ if (is_bool($res)) { var_dump($res); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok diff --git a/ext/mbstring/tests/bug79441.phpt b/ext/mbstring/tests/bug79441.phpt index 243815d59670..7d89dd03ef27 100644 --- a/ext/mbstring/tests/bug79441.phpt +++ b/ext/mbstring/tests/bug79441.phpt @@ -2,10 +2,11 @@ Bug #79441 Segfault in mb_chr() if internal encoding is unsupported --EXTENSIONS-- mbstring +--INI-- +internal_encoding=utf-7 --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_init(): Argument #2 ($pattern) must not be empty + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d No pattern was provided diff --git a/ext/mbstring/tests/gb18030_2022_encoding.phpt b/ext/mbstring/tests/gb18030_2022_encoding.phpt index 6908e4fed75b..178e0f38e655 100644 --- a/ext/mbstring/tests/gb18030_2022_encoding.phpt +++ b/ext/mbstring/tests/gb18030_2022_encoding.phpt @@ -241,7 +241,7 @@ readGB18030_2022_ConversionTable(__DIR__ . '/data/GB18030-2022MappingTableBMP.tx findInvalidChars($toUnicode, $invalid, $truncated); function notFourByteCode($gb) { - return ((ord($gb) < 0x81 || ord($gb) > 0x84) && (ord($gb) < 0x90 || ord($gb) > 0xE3)) || + return ((ord($gb[0]) < 0x81 || ord($gb[0]) > 0x84) && (ord($gb[0]) < 0x90 || ord($gb[0]) > 0xE3)) || (strlen($gb) > 1 && (ord($gb[1]) < 0x30 || ord($gb[1]) > 0x39)); } diff --git a/ext/mbstring/tests/gb18030_encoding.phpt b/ext/mbstring/tests/gb18030_encoding.phpt index 52cb7ae54482..6c51fe35f204 100644 --- a/ext/mbstring/tests/gb18030_encoding.phpt +++ b/ext/mbstring/tests/gb18030_encoding.phpt @@ -240,7 +240,7 @@ $gb18030_BMP_Mappings = [ findInvalidChars($toUnicode, $invalid, $truncated); function notFourByteCode($gb) { - return ((ord($gb) < 0x81 || ord($gb) > 0x84) && (ord($gb) < 0x90 || ord($gb) > 0xE3)) || + return ((ord($gb[0]) < 0x81 || ord($gb[0]) > 0x84) && (ord($gb[0]) < 0x90 || ord($gb[0]) > 0xE3)) || (strlen($gb) > 1 && (ord($gb[1]) < 0x30 || ord($gb[1]) > 0x39)); } diff --git a/ext/mbstring/tests/gh18901.phpt b/ext/mbstring/tests/gh18901.phpt index 8d862a537c3b..55e41d48377d 100644 --- a/ext/mbstring/tests/gh18901.phpt +++ b/ext/mbstring/tests/gh18901.phpt @@ -13,7 +13,8 @@ foreach ($vals as $val) { var_dump(mb_split('\d', '123', $val)); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(0) "" @@ -24,6 +25,8 @@ array(4) { [3]=> string(0) "" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(0) "" @@ -34,6 +37,8 @@ array(4) { [3]=> string(0) "" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(0) "" @@ -44,10 +49,14 @@ array(4) { [3]=> string(0) "" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "123" } + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(3) "123" diff --git a/ext/mbstring/tests/gh19397.phpt b/ext/mbstring/tests/gh19397.phpt new file mode 100644 index 000000000000..e6e07b161c08 --- /dev/null +++ b/ext/mbstring/tests/gh19397.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-19397 (mb_list_encodings() can cause crashes on shutdown) +--EXTENSIONS-- +mbstring +--FILE-- + 0); +?> +--EXPECT-- +bool(true) diff --git a/ext/mbstring/tests/gh20674.phpt b/ext/mbstring/tests/gh20674.phpt new file mode 100644 index 000000000000..2fb8206037de --- /dev/null +++ b/ext/mbstring/tests/gh20674.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-20674 (mb_decode_mimeheader does not handle separator) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECTF-- +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(11) "The PHP 8.5" +string(3) "(a)" +string(5) "(a b)" +string(5) "(a b)" +string(4) "(ab)" +string(4) "(ab)" +string(4) "(ab)" diff --git a/ext/mbstring/tests/gh20832.phpt b/ext/mbstring/tests/gh20832.phpt new file mode 100644 index 000000000000..9a076dc4fe70 --- /dev/null +++ b/ext/mbstring/tests/gh20832.phpt @@ -0,0 +1,10 @@ +--TEST-- +Ensure mb_substr does not crash with MacJapanese input, when codepoints to skip are more than number of bytes in input string +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +string(1) "V" diff --git a/ext/mbstring/tests/gh20833.phpt b/ext/mbstring/tests/gh20833.phpt new file mode 100644 index 000000000000..099aa3379238 --- /dev/null +++ b/ext/mbstring/tests/gh20833.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-20833 (mb_str_pad() divide by zero if padding string is invalid in the encoding) +--EXTENSIONS-- +mbstring +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +ValueError: mb_str_pad(): Argument #3 ($pad_string) must not be empty diff --git a/ext/mbstring/tests/gh20836.phpt b/ext/mbstring/tests/gh20836.phpt new file mode 100644 index 000000000000..0bdb3a44f3b0 --- /dev/null +++ b/ext/mbstring/tests/gh20836.phpt @@ -0,0 +1,34 @@ +--TEST-- +GH-20836 (Stack overflow in mb_convert_variables with recursive array references) +--EXTENSIONS-- +mbstring +--FILE-- + ['level2' => ['level3' => 'data']]]; +var_dump(mb_convert_variables('utf-8', 'utf-8', $d)); + +echo "Done\n"; +?> +--EXPECTF-- +Warning: mb_convert_variables(): Cannot handle recursive references in %s on line %d +bool(false) + +Warning: mb_convert_variables(): Cannot handle recursive references in %s on line %d +bool(false) +string(5) "UTF-8" +string(5) "UTF-8" +Done diff --git a/ext/mbstring/tests/gh20836_stack_limit.phpt b/ext/mbstring/tests/gh20836_stack_limit.phpt new file mode 100644 index 000000000000..29d7f3f168cf --- /dev/null +++ b/ext/mbstring/tests/gh20836_stack_limit.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-20836 (Stack overflow in mb_convert_variables with recursive array references, stack limit case) +--EXTENSIONS-- +mbstring +--SKIPIF-- + +--INI-- +zend.max_allowed_stack_size=256K +--FILE-- + createDeepArray($depth - 1)]; +} + +// Create a deeply nested array that will trigger stack limit +$deepArray = createDeepArray(15000); + +mb_convert_variables('utf-8', 'utf-8', $deepArray); + +echo "Done\n"; +?> +--EXPECTF-- +Fatal error: Uncaught Error: Maximum call stack size of %d bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion? in %s:%d +Stack trace: +#0 %s(%d): mb_convert_variables('utf-8', 'utf-8', Array) +#1 {main} + thrown in %s on line %d diff --git a/ext/mbstring/tests/gh21223.phpt b/ext/mbstring/tests/gh21223.phpt new file mode 100644 index 000000000000..7138868af169 --- /dev/null +++ b/ext/mbstring/tests/gh21223.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-21223 (Stack overflow in mb_guess_encoding called via mb_detect_encoding) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +string(5) "UTF-8" +Done diff --git a/ext/mbstring/tests/gh7902.phpt b/ext/mbstring/tests/gh7902.phpt index 7182731005ff..e56c1792e172 100644 --- a/ext/mbstring/tests/gh7902.phpt +++ b/ext/mbstring/tests/gh7902.phpt @@ -8,9 +8,9 @@ if (str_contains(getcwd(), " ")) die("skip sendmail_path ini with spaces"); ?> --INI-- sendmail_path={MAIL:{PWD}/gh7902.eml} +internal_encoding=UTF-8 --FILE-- +--EXPECT-- +array(4) { + [0]=> + string(5) "UTF-8" + [1]=> + string(11) "ISO-8859-15" + [2]=> + string(10) "ISO-8859-1" + [3]=> + string(5) "ASCII" +} +array(3) { + [0]=> + string(5) "UTF-8" + [1]=> + string(10) "ISO-8859-1" + [2]=> + string(5) "ASCII" +} +array(1) { + [0]=> + string(5) "UTF-8" +} +array(1) { + [0]=> + string(5) "UTF-8" +} +array(1) { + [0]=> + string(5) "UTF-8" +} + diff --git a/ext/mbstring/tests/mb_encode_mimeheader_indent.phpt b/ext/mbstring/tests/mb_encode_mimeheader_indent.phpt index afaab29c8742..288401e0aee8 100644 --- a/ext/mbstring/tests/mb_encode_mimeheader_indent.phpt +++ b/ext/mbstring/tests/mb_encode_mimeheader_indent.phpt @@ -2,6 +2,8 @@ Test mb_encode_mimeheader() function : basic functionality, indent --EXTENSIONS-- mbstring +--INI-- +internal_encoding=utf-8 --FILE-- ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok diff --git a/ext/mbstring/tests/mb_ereg-compat-02.phpt b/ext/mbstring/tests/mb_ereg-compat-02.phpt index d30b9927cc53..a47f9c665bc8 100644 --- a/ext/mbstring/tests/mb_ereg-compat-02.phpt +++ b/ext/mbstring/tests/mb_ereg-compat-02.phpt @@ -19,7 +19,8 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build echo $registers[2]; echo "\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 1 This is a nice and simple string is diff --git a/ext/mbstring/tests/mb_ereg.phpt b/ext/mbstring/tests/mb_ereg.phpt index 53bb58e15a86..5b3f9c125fcd 100644 --- a/ext/mbstring/tests/mb_ereg.phpt +++ b/ext/mbstring/tests/mb_ereg.phpt @@ -31,16 +31,65 @@ output_handler= do_tests( $enc ); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)6162632064656620676869206a6b6c2064656620676869206a6b6c + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3e1a3e2a3e320a4a2a4aaa4a420a4aba4b3a4ca20a4efa4f1a4f320a3e1a3e2a3e320a4a2a4aaa4a420a4ab20a4b3a4ca20a4efa4f1a4f3 + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d (1)a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab20a4ada4ab20a4f2a4f020a3eda3faa3f8a3e6a3f020a4a6a4aaa4ab2020a4ada4ab20a4f2a4f0 diff --git a/ext/mbstring/tests/mb_ereg1.phpt b/ext/mbstring/tests/mb_ereg1.phpt index 813fe5e41ef0..a92b796423de 100644 --- a/ext/mbstring/tests/mb_ereg1.phpt +++ b/ext/mbstring/tests/mb_ereg1.phpt @@ -24,7 +24,8 @@ foreach ($a as $args) { var_dump($args); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) array(3) { [0]=> @@ -35,6 +36,8 @@ array(3) { array(0) { } } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ValueError: mb_ereg(): Argument #1 ($pattern) must not be empty array(3) { [0]=> @@ -44,6 +47,8 @@ array(3) { [2]=> string(0) "" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d TypeError: mb_ereg(): Argument #1 ($pattern) must be of type string, array given array(3) { [0]=> @@ -54,6 +59,8 @@ array(3) { [2]=> string(0) "" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d TypeError: mb_ereg(): Argument #2 ($string) must be of type string, array given array(3) { [0]=> @@ -64,6 +71,8 @@ array(3) { [2]=> string(0) "" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) array(3) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg2.phpt b/ext/mbstring/tests/mb_ereg2.phpt index f87b5c5410a8..22cd29199dda 100644 --- a/ext/mbstring/tests/mb_ereg2.phpt +++ b/ext/mbstring/tests/mb_ereg2.phpt @@ -18,13 +18,16 @@ var_dump($a, $b, $c); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(-1) int(-1) array(1) { [0]=> string(2) "-1" } + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(-1) int(-1) array(1) { diff --git a/ext/mbstring/tests/mb_ereg_basic.phpt b/ext/mbstring/tests/mb_ereg_basic.phpt index 094f2949ea43..d54f3bb3be80 100644 --- a/ext/mbstring/tests/mb_ereg_basic.phpt +++ b/ext/mbstring/tests/mb_ereg_basic.phpt @@ -71,15 +71,23 @@ function base64_encode_var_dump($regs) { } } ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : basic functionality *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Regex encoding set to utf-8 **-- ASCII String --** -- Without $regs argument-- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) --With $regs argument -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(2) { [0]=> @@ -87,6 +95,8 @@ array(2) { [1]=> string(24) "VGhpcyBpcyBhbiBFbmdsaXM=" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -95,9 +105,15 @@ array(1) { **-- Multibyte String --** -- Without $regs argument -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) -- With $regs argument -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(3) { [0]=> @@ -107,6 +123,8 @@ array(3) { [2]=> string(8) "MTIzNA==" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) array(0) { } diff --git a/ext/mbstring/tests/mb_ereg_dupnames.phpt b/ext/mbstring/tests/mb_ereg_dupnames.phpt index cf4444682f57..104dba927189 100644 --- a/ext/mbstring/tests/mb_ereg_dupnames.phpt +++ b/ext/mbstring/tests/mb_ereg_dupnames.phpt @@ -15,7 +15,10 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build mb_ereg($pattern, '中!', $m); var_dump($m); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(6) "中?" @@ -26,6 +29,8 @@ array(4) { ["punct"]=> string(3) "?" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(4) { [0]=> string(6) "中!" diff --git a/ext/mbstring/tests/mb_ereg_match_basic.phpt b/ext/mbstring/tests/mb_ereg_match_basic.phpt index d90d03ec35e8..671a72d27272 100644 --- a/ext/mbstring/tests/mb_ereg_match_basic.phpt +++ b/ext/mbstring/tests/mb_ereg_match_basic.phpt @@ -2,6 +2,8 @@ Test mb_ereg_match() function : basic functionality --EXTENSIONS-- mbstring +--INI-- +internal_encoding=UTF-8 --SKIPIF-- ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d *** Testing mb_ereg_match() : basic functionality *** -- ASCII string 1 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) -- ASCII string 2 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) -- Multibyte string 1 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) -- Multibyte string 2 -- + +Deprecated: Function mb_ereg_match() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) Done diff --git a/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt b/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt index 80c17b729d70..7756b49d2128 100644 --- a/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt +++ b/ext/mbstring/tests/mb_ereg_named_subpatterns.phpt @@ -16,7 +16,10 @@ function_exists('mb_ereg') or die("skip mb_ereg() is not available in this build mb_ereg('(\s*)(?\w+)', ' 中国', $m); var_dump($m); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(5) { [0]=> string(8) " 中国" @@ -29,6 +32,8 @@ array(5) { ["word"]=> string(6) "中国" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(5) { [0]=> string(3) "国" @@ -41,6 +46,8 @@ array(5) { ["word"]=> string(3) "国" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(3) { [0]=> string(8) " 中国" diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt index 9ce201725219..057460ff01e4 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-01.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","def",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt index 8fec03b486af..b9bebcf8d71f 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-02.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt index 0e589a8665bb..167eb6986c87 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-03.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="\\'test"; echo mb_ereg_replace("\\\\'","'",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 'test diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt index a9a4fc953281..70d29c8d1805 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-04.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="This is a nice and simple string"; echo mb_ereg_replace("^This","That",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d That is a nice and simple string diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt index 4e15d8bfb8eb..0eaa22615b10 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-05.phpt @@ -13,5 +13,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $b=mb_ereg_replace("abcd","",$a); echo "strlen(\$b)=".strlen($b); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d strlen($b)=0 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt index 396c8e870a26..6c169388387f 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-06.phpt @@ -11,5 +11,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab /* (counterpart: ext/standard/tests/reg/008.phpt) */ echo mb_ereg_replace("([a-z]*)([-=+|]*)([0-9]+)","\\3 \\1 \\2\n","abc+-|=123"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123 abc +-|= diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt index f0cd2edfe273..bc5ff9a6ca30 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-07.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc122222222223"; echo mb_ereg_replace("1(2*)3","\\1def\\1",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc2222222222def2222222222 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt index 8e23aba9cff9..8368e21a2a88 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-08.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","def\\0ghi",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef123ghi diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt index cb8fce9135d8..efa1eb0e9dc4 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-09.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123",'def\1ghi',$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef\1ghi diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt index 96c762bc4d5f..d280e93574cb 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-10.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="abc123"; echo mb_ereg_replace("123","def\\g\\\\hi\\",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abcdef\g\\hi\ diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt index a88f358b4b55..8f4b4fe5b295 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-11.phpt @@ -12,5 +12,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab $a="a\\2bxc"; echo mb_ereg_replace("a(.*)b(.*)c","\\1",$a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d \2 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt index 0f371053e508..1dbc9a0416de 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-12.phpt @@ -11,5 +11,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab /* (counterpart: ext/standard/tests/reg/015.phpt) */ echo mb_ereg_replace("^","z","abc123"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d zabc123 diff --git a/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt b/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt index a271eeff405c..4e6eaf017bc4 100644 --- a/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt +++ b/ext/mbstring/tests/mb_ereg_replace-compat-13.phpt @@ -11,5 +11,6 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab /* (counterpart: ext/standard/tests/reg/016.phpt) */ echo mb_ereg_replace('\?',"abc","?123?"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc123abc diff --git a/ext/mbstring/tests/mb_ereg_replace.phpt b/ext/mbstring/tests/mb_ereg_replace.phpt index 455b13e23ce5..1221b6b366b0 100644 --- a/ext/mbstring/tests/mb_ereg_replace.phpt +++ b/ext/mbstring/tests/mb_ereg_replace.phpt @@ -12,6 +12,11 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab print mb_ereg_replace( ' ', '-', 'a b c d e' )."\n"; print mb_ereg_replace( '([a-z]+)','[\\1]', 'abc def ghi' ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d a-b-c-d-e + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d [abc] [def] [ghi] diff --git a/ext/mbstring/tests/mb_ereg_replace_basic.phpt b/ext/mbstring/tests/mb_ereg_replace_basic.phpt index b0fcd7809f41..7faac7371abd 100644 --- a/ext/mbstring/tests/mb_ereg_replace_basic.phpt +++ b/ext/mbstring/tests/mb_ereg_replace_basic.phpt @@ -2,6 +2,8 @@ Test mb_ereg_replace() function : basic --EXTENSIONS-- mbstring +--INI-- +internal_encoding=UTF-8 --SKIPIF-- ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg_replace() : basic functionality *** +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + -- ASCII string 1 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(16) "6162632020313233" -- ASCII string 2 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(14) "61626320646566" -- Multibyte string 1 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(72) "e697a5e69cace8aa9e5f5f5f5f5f31323334efbc95efbc96efbc97efbc98efbc99e38082" -- Multibyte string 2 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(106) "e697a5e69cace8aa9ee38386e382ade382b9e38388e381a7e38199e380823031323334efbc95efbc96efbc97efbc98efbc99e38082" Done diff --git a/ext/mbstring/tests/mb_ereg_replace_callback.phpt b/ext/mbstring/tests/mb_ereg_replace_callback.phpt index 40120c03eab2..d4541d09cafa 100644 --- a/ext/mbstring/tests/mb_ereg_replace_callback.phpt +++ b/ext/mbstring/tests/mb_ereg_replace_callback.phpt @@ -18,6 +18,9 @@ echo mb_ereg_replace_callback('(?\w+) (?\d+).*', function ($m) { return sprintf("%s-%s", $m['digit'], $m['word']); }, $str), "\n"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace_callback() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d abc(3) 123(3) #",;(4) $foo(4) + +Deprecated: Function mb_ereg_replace_callback() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123-abc diff --git a/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt b/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt index 7e4d8e2e4940..8a58e95dffdf 100644 --- a/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt +++ b/ext/mbstring/tests/mb_ereg_replace_named_subpatterns.phpt @@ -26,12 +26,29 @@ function_exists('mb_ereg_replace') or die("skip mb_ereg_replace() is not availab // An unclosed backref is ignored echo mb_ereg_replace('(?\w+)', '-\k ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d _a_ _b_ _c_ _d_ _e_ + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123456789aa-a- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 123456789aa-a- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d a_\k<01> + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d -\1- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d -\k<>- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d -\k ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg_replace() : usage variations *** -- Iteration 1 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 2 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 3 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 4 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 5 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 6 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 7 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 8 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 9 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" -- Iteration 10 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(120) "string_valsstring_valtstring_valrstring_valistring_valnstring_valgstring_val_string_valvstring_valastring_vallstring_val" -- Iteration 11 -- + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "string_val" Done diff --git a/ext/mbstring/tests/mb_ereg_search.phpt b/ext/mbstring/tests/mb_ereg_search.phpt index f167b9d7607d..25f581b7dd8d 100644 --- a/ext/mbstring/tests/mb_ereg_search.phpt +++ b/ext/mbstring/tests/mb_ereg_search.phpt @@ -32,9 +32,26 @@ function_exists('mb_ereg_search') or die("skip mb_ereg_search() is not available while($r); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(9) "中国abc" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(3) "abc" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "字符" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "china" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "string" + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d diff --git a/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt index 6979816fe8e0..33ad520e5fe6 100644 --- a/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt +++ b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt @@ -14,8 +14,15 @@ var_dump(mb_ereg_search_getregs()); ?> --EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg_search(): Pattern is not valid under UTF-8 encoding in %s on line %d bool(false) + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt b/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt index 03161cf27cec..bcf73b6b3f40 100644 --- a/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt +++ b/ext/mbstring/tests/mb_ereg_search_named_subpatterns_1.phpt @@ -5,7 +5,7 @@ mbstring --SKIPIF-- --FILE-- =') or die("skip requires oniguruma >= 6.9.4"); +@version_compare(MB_ONIGURUMA_VERSION, '6.9.4', '>=') or die("skip requires oniguruma >= 6.9.4"); ?> --FILE-- =') or die("skip requires onigu mb_ereg_search('(?\s*)(?\w+)(?[?!])'); var_dump(mb_ereg_search_getregs()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(7) { [0]=> string(11) " 中国?" diff --git a/ext/mbstring/tests/mb_ereg_search_pos.phpt b/ext/mbstring/tests/mb_ereg_search_pos.phpt index 7f8f99f0c5d2..2c88cff01e04 100644 --- a/ext/mbstring/tests/mb_ereg_search_pos.phpt +++ b/ext/mbstring/tests/mb_ereg_search_pos.phpt @@ -22,7 +22,12 @@ else{ var_dump("false"); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(2) { [0]=> int(5) diff --git a/ext/mbstring/tests/mb_ereg_search_regs.phpt b/ext/mbstring/tests/mb_ereg_search_regs.phpt index eb883387e620..dd28df903729 100644 --- a/ext/mbstring/tests/mb_ereg_search_regs.phpt +++ b/ext/mbstring/tests/mb_ereg_search_regs.phpt @@ -22,7 +22,10 @@ function_exists('mb_ereg_search_regs') or die("skip mb_ereg_search_regs() not av ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_regs() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(1) { [0]=> string(4) "ов" diff --git a/ext/mbstring/tests/mb_ereg_search_setpos.phpt b/ext/mbstring/tests/mb_ereg_search_setpos.phpt index 6a953447174d..6153d86282df 100644 --- a/ext/mbstring/tests/mb_ereg_search_setpos.phpt +++ b/ext/mbstring/tests/mb_ereg_search_setpos.phpt @@ -35,38 +35,77 @@ foreach($positions as $pos) { } } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + * Position: 5 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(5) * Position: 20 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(20) * Position: 21 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(20) * Position: 25 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(20) * Position: 0 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) * Position: -5 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(15) * Position: -20 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) * Position: -30 : + +Deprecated: Function mb_ereg_search_setpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_ereg_search_setpos(): Argument #1 ($offset) is out of range + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d int(0) diff --git a/ext/mbstring/tests/mb_ereg_search_syntax.phpt b/ext/mbstring/tests/mb_ereg_search_syntax.phpt index 5e16a91c3695..f6b427a3c7e6 100644 --- a/ext/mbstring/tests/mb_ereg_search_syntax.phpt +++ b/ext/mbstring/tests/mb_ereg_search_syntax.phpt @@ -13,5 +13,8 @@ mb_ereg_search_init("a"); var_dump(mb_ereg_search("a\\{1,2\\}", "b")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_search() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) diff --git a/ext/mbstring/tests/mb_ereg_search_xxx.phpt b/ext/mbstring/tests/mb_ereg_search_xxx.phpt index 238dcc0e87a5..33d21052ecd3 100644 --- a/ext/mbstring/tests/mb_ereg_search_xxx.phpt +++ b/ext/mbstring/tests/mb_ereg_search_xxx.phpt @@ -35,48 +35,409 @@ output_handler= do_tests( $enc, 'x' ); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (5) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (EUC-JP) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (5) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (Shift_JIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (5) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (10) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (SJIS) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (7) ϡ + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_init() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (5) abcde + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (14) abdeabcf + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (22) abc + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getregs() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_search_getpos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d (UTF-8) (31) abcd + +Deprecated: Function mb_ereg_search_pos() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d diff --git a/ext/mbstring/tests/mb_ereg_variation3.phpt b/ext/mbstring/tests/mb_ereg_variation3.phpt index 329c5597d440..5735e8248ef2 100644 --- a/ext/mbstring/tests/mb_ereg_variation3.phpt +++ b/ext/mbstring/tests/mb_ereg_variation3.phpt @@ -5,7 +5,7 @@ mbstring --SKIPIF-- =') or die("skip requires oniguruma >= 6.1.0"); +@version_compare(MB_ONIGURUMA_VERSION, '6.1.0', '>=') or die("skip requires oniguruma >= 6.1.0"); ?> --FILE-- ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : variation *** +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + -- Iteration 1 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -77,6 +81,8 @@ array(1) { } -- Iteration 2 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -84,6 +90,8 @@ array(1) { } -- Iteration 3 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -91,6 +99,8 @@ array(1) { } -- Iteration 4 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -98,6 +108,8 @@ array(1) { } -- Iteration 5 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -105,6 +117,8 @@ array(1) { } -- Iteration 6 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -112,6 +126,8 @@ array(1) { } -- Iteration 7 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -119,6 +135,8 @@ array(1) { } -- Iteration 8 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -126,6 +144,8 @@ array(1) { } -- Iteration 9 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -133,6 +153,8 @@ array(1) { } -- Iteration 10 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -140,6 +162,8 @@ array(1) { } -- Iteration 11 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -147,6 +171,8 @@ array(1) { } -- Iteration 12 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation4.phpt b/ext/mbstring/tests/mb_ereg_variation4.phpt index 05b96a9bf40f..559c5fd467cd 100644 --- a/ext/mbstring/tests/mb_ereg_variation4.phpt +++ b/ext/mbstring/tests/mb_ereg_variation4.phpt @@ -69,10 +69,14 @@ function base64_encode_var_dump($regs) { echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + -- Iteration 1 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -80,6 +84,8 @@ array(1) { } -- Iteration 2 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -87,6 +93,8 @@ array(1) { } -- Iteration 3 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -94,12 +102,18 @@ array(1) { } -- Iteration 4 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 5 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 6 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -107,6 +121,8 @@ array(1) { } -- Iteration 7 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -114,9 +130,13 @@ array(1) { } -- Iteration 8 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 9 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -124,6 +144,8 @@ array(1) { } -- Iteration 10 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> @@ -131,12 +153,18 @@ array(1) { } -- Iteration 11 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 12 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(false) -- Iteration 13 -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation5.phpt b/ext/mbstring/tests/mb_ereg_variation5.phpt index 569162534dcd..37cb325bf84b 100644 --- a/ext/mbstring/tests/mb_ereg_variation5.phpt +++ b/ext/mbstring/tests/mb_ereg_variation5.phpt @@ -57,19 +57,29 @@ function base64_encode_var_dump($regs) { } } ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** -ASCII String without $regs arg: bool(true) +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +ASCII String without $regs arg: +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +bool(true) ASCII String with $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(52) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4gMDEyMzQ1Njc4OS4=" } -Multibyte String without $regs arg: bool(true) +Multibyte String without $regs arg: +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +bool(true) Multubyte String with $regs arg: + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation6.phpt b/ext/mbstring/tests/mb_ereg_variation6.phpt index cea3fcf661b2..33df1eaf051a 100644 --- a/ext/mbstring/tests/mb_ereg_variation6.phpt +++ b/ext/mbstring/tests/mb_ereg_variation6.phpt @@ -73,18 +73,24 @@ function base64_encode_var_dump($regs) { echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Regex encoding set to utf-8 --** Pattern is: \w+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(8) "VGhpcw==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -93,12 +99,16 @@ array(1) { --** Pattern is: \W+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(4) "IA==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -107,23 +117,31 @@ array(1) { --** Pattern is: \s+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(4) "IA==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) NULL --** Pattern is: \S+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(8) "VGhpcw==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -132,12 +150,16 @@ array(1) { --** Pattern is: \d+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(16) "MDEyMzQ1Njc4OQ==" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -146,12 +168,16 @@ array(1) { --** Pattern is: \D+ **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> string(36) "VGhpcyBpcyBhbiBFbmdsaXNoIHN0cmluZy4g" } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -160,12 +186,16 @@ array(1) { --** Pattern is: \b **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> bool(false) } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> @@ -174,12 +204,16 @@ array(1) { --** Pattern is: \B **-- -- ASCII String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> bool(false) } -- Multibyte String: -- + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(1) { [0]=> diff --git a/ext/mbstring/tests/mb_ereg_variation7.phpt b/ext/mbstring/tests/mb_ereg_variation7.phpt index 832bbbfb6f3b..8e6ad836668a 100644 --- a/ext/mbstring/tests/mb_ereg_variation7.phpt +++ b/ext/mbstring/tests/mb_ereg_variation7.phpt @@ -58,9 +58,13 @@ function base64_encode_var_dump($regs) { echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_ereg() : usage variations *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Regex encoding set to utf-8 + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(5) { [0]=> @@ -74,6 +78,8 @@ array(5) { [4]=> string(4) "ODk=" } + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) array(5) { [0]=> diff --git a/ext/mbstring/tests/mb_eregi.phpt b/ext/mbstring/tests/mb_eregi.phpt index 2cdef03a6cb4..1660f154fbf1 100644 --- a/ext/mbstring/tests/mb_eregi.phpt +++ b/ext/mbstring/tests/mb_eregi.phpt @@ -15,7 +15,14 @@ var_dump(mb_eregi('z', 'XYZ')); var_dump(mb_eregi('xyzp', 'XYZ')); var_dump(mb_eregi('ö', 'Öäü')); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) + +Deprecated: Function mb_eregi() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) diff --git a/ext/mbstring/tests/mb_eregi_replace.phpt b/ext/mbstring/tests/mb_eregi_replace.phpt index b03874701f95..89963c922761 100644 --- a/ext/mbstring/tests/mb_eregi_replace.phpt +++ b/ext/mbstring/tests/mb_eregi_replace.phpt @@ -33,7 +33,140 @@ function do_translit($st) { mb_regex_encoding('ISO-8859-1'); echo do_translit("Пеар"); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_eregi_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d Pear --CREDITS-- Testfest Wuerzburg 2009-06-20 (modified by rui 2011-10-15) diff --git a/ext/mbstring/tests/mb_output_handler_pattern-01.phpt b/ext/mbstring/tests/mb_output_handler_pattern-01.phpt index 99843098a3a8..006c08ead58a 100644 --- a/ext/mbstring/tests/mb_output_handler_pattern-01.phpt +++ b/ext/mbstring/tests/mb_output_handler_pattern-01.phpt @@ -2,9 +2,10 @@ mb_output_handler() and mbstring.http_output_conv_mimetypes (1) --EXTENSIONS-- mbstring +--INI-- +output_encoding=EUC-JP --FILE-- --EXPECTF-- *** Testing mb_regex_encoding() : basic functionality *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(%d) "%s" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" Done diff --git a/ext/mbstring/tests/mb_regex_encoding_error2.phpt b/ext/mbstring/tests/mb_regex_encoding_error2.phpt index 6874f5379a6a..ee665e5aa8bd 100644 --- a/ext/mbstring/tests/mb_regex_encoding_error2.phpt +++ b/ext/mbstring/tests/mb_regex_encoding_error2.phpt @@ -21,6 +21,8 @@ try { } ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_regex_encoding() : error conditions *** + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line 9 mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "unknown" given diff --git a/ext/mbstring/tests/mb_regex_encoding_variation2.phpt b/ext/mbstring/tests/mb_regex_encoding_variation2.phpt index 5d46b3ad7936..55d139eb3ad7 100644 --- a/ext/mbstring/tests/mb_regex_encoding_variation2.phpt +++ b/ext/mbstring/tests/mb_regex_encoding_variation2.phpt @@ -87,286 +87,622 @@ foreach($encoding as $enc) { } echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing mb_regex_encoding() : usage variations *** -- Iteration 1 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 2 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-4BE" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 3 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 4 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-2" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 5 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-2BE" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 6 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UCS-2LE" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 7 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 8 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" -- Iteration 9 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UCS-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" -- Iteration 10 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(7) "UCS-4LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" -- Iteration 11 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" -- Iteration 12 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "UTF-16" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" -- Iteration 13 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UTF-7" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" -- Iteration 14 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UTF7-IMAP" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" -- Iteration 15 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(8) "UTF-16LE" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" -- Iteration 16 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "UTF-8" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "ASCII" -- Iteration 17 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "ASCII" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" -- Iteration 18 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 19 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" -- Iteration 20 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-JP" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 21 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "ISO-2022-JP" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 22 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "JIS" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" -- Iteration 23 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "SJIS" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-1" -- Iteration 24 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-1" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-2" -- Iteration 25 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-2" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-3" -- Iteration 26 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-3" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-4" -- Iteration 27 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-4" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-5" -- Iteration 28 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-5" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-6" -- Iteration 29 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-6" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-7" -- Iteration 30 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-7" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-8" -- Iteration 31 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-8" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-9" -- Iteration 32 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(10) "ISO-8859-9" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-10" -- Iteration 33 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-10" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-13" -- Iteration 34 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-13" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-14" -- Iteration 35 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-14" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 36 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte2be" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 37 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte2le" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 38 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte4be" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 39 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "byte4le" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 40 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "BASE64" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 41 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "HTML-ENTITIES" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 42 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "7bit" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 43 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "8bit" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" -- Iteration 44 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(11) "ISO-8859-15" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" -- Iteration 45 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "CP936" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" -- Iteration 46 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "HZ" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" -- Iteration 47 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-CN" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" -- Iteration 48 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "CP950" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" -- Iteration 49 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-TW" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "BIG5" -- Iteration 50 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "BIG5" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 51 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "UHC" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 52 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "ISO-2022-KR" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 53 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "Windows-1251" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 54 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "Windows-1252" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 55 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d mb_regex_encoding(): Argument #1 ($encoding) must be a valid encoding, "CP866" given + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" -- Iteration 56 -- + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(6) "EUC-KR" + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(5) "KOI8R" Done diff --git a/ext/mbstring/tests/mb_regex_set_options.phpt b/ext/mbstring/tests/mb_regex_set_options.phpt index a5fb611cacf3..f6994049f502 100644 --- a/ext/mbstring/tests/mb_regex_set_options.phpt +++ b/ext/mbstring/tests/mb_regex_set_options.phpt @@ -14,5 +14,12 @@ function_exists('mb_regex_set_options') or die("skip\n"); mb_regex_set_options( '' ); print mb_ereg_replace(' -', '+', '- - - - -' ); ?> ---EXPECT-- -+ + + + +-++++ +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ++ + + + + +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d +-++++ diff --git a/ext/mbstring/tests/mb_split-compat-01.phpt b/ext/mbstring/tests/mb_split-compat-01.phpt index 69d398cb0de3..8c5dcc0b4f10 100644 --- a/ext/mbstring/tests/mb_split-compat-01.phpt +++ b/ext/mbstring/tests/mb_split-compat-01.phpt @@ -16,7 +16,8 @@ test"); echo $a[$i] . "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 4 this is diff --git a/ext/mbstring/tests/mb_split.phpt b/ext/mbstring/tests/mb_split.phpt index 208848ee2bf5..8b8df7411a81 100644 --- a/ext/mbstring/tests/mb_split.phpt +++ b/ext/mbstring/tests/mb_split.phpt @@ -33,13 +33,36 @@ function_exists('mb_split') or die("skip mb_split() is not available in this bui verify_split( "\xa1\xa1+", "\xa1\xa1\xa1\xa2\xa2\xa1\xa1\xa1\xa1\xa1\xa1\xa2\xa2\xa1\xa1\xa1", $i ); } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_regex_encoding() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d ok + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 2-2 + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 3-3 + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d 4-4 diff --git a/ext/mbstring/tests/mb_split_empty_match.phpt b/ext/mbstring/tests/mb_split_empty_match.phpt index 56ee59c31c6d..14604adfa98b 100644 --- a/ext/mbstring/tests/mb_split_empty_match.phpt +++ b/ext/mbstring/tests/mb_split_empty_match.phpt @@ -11,7 +11,10 @@ function_exists('mb_split') or die("skip mb_split() is not available in this bui mb_regex_set_options('m'); var_dump(mb_split('^', "a\nb\nc")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_regex_set_options() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + +Deprecated: Function mb_split() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d array(3) { [0]=> string(2) "a diff --git a/ext/mbstring/tests/mb_stripos_basic.phpt b/ext/mbstring/tests/mb_stripos_basic.phpt index 864a98cd8305..72ccb08610f3 100644 --- a/ext/mbstring/tests/mb_stripos_basic.phpt +++ b/ext/mbstring/tests/mb_stripos_basic.phpt @@ -2,6 +2,8 @@ Test mb_stripos() function : basic functionality --EXTENSIONS-- mbstring +--INI-- +internal_encoding=UTF-8 --FILE-- $value) { echo "--$key--\n"; try { diff --git a/ext/mbstring/tests/mb_substr_basic.phpt b/ext/mbstring/tests/mb_substr_basic.phpt index 31de868fb93c..acce6f5140d6 100644 --- a/ext/mbstring/tests/mb_substr_basic.phpt +++ b/ext/mbstring/tests/mb_substr_basic.phpt @@ -1,15 +1,11 @@ --TEST-- -Test mb_substr() function : basic functionality +Test mb_substr() function : basic functionality with ASCII characters and multibyte strings. --EXTENSIONS-- mbstring --INI-- internal_encoding=ISO-8859-1 --FILE-- @@ -24,8 +24,13 @@ var_dump(mb_ereg('\\s+$', $s)); echo 'OK'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) OK diff --git a/ext/mbstring/tests/mbregex_stack_limit2.phpt b/ext/mbstring/tests/mbregex_stack_limit2.phpt index 9c2efcc39ec2..e7860654f3c0 100644 --- a/ext/mbstring/tests/mbregex_stack_limit2.phpt +++ b/ext/mbstring/tests/mbregex_stack_limit2.phpt @@ -6,7 +6,7 @@ iconv --SKIPIF-- @@ -28,6 +28,10 @@ var_dump(mb_trim_regex(str_repeat(' ', 10000))); echo 'OK'; ?> --EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d + Warning: mb_ereg_replace(): mbregex search failure in php_mbereg_replace_exec(): match-stack limit over in %s on line %d + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(0) "" OK diff --git a/ext/mbstring/tests/php_gr_jp_10830.phpt b/ext/mbstring/tests/php_gr_jp_10830.phpt index 02b46c01d3db..4b7517fd6e0f 100644 --- a/ext/mbstring/tests/php_gr_jp_10830.phpt +++ b/ext/mbstring/tests/php_gr_jp_10830.phpt @@ -13,6 +13,7 @@ $a="aaa\n<>"; var_dump( mb_ereg("^[^><]+$",$a) ); var_dump( !!preg_match("/^[^><]+$/",$a) ); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) bool(false) diff --git a/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt b/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt index b9d82bf9af9f..4bf317499527 100644 --- a/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt +++ b/ext/mbstring/tests/php_gr_jp_dev_884-1.phpt @@ -12,6 +12,8 @@ set_time_limit(2); var_dump(preg_replace("/.*/", "b", "a")); var_dump(mb_ereg_replace(".*", "b", "a")); ?> ---EXPECT-- +--EXPECTF-- string(2) "bb" + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(2) "bb" diff --git a/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt b/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt index 51086285ed61..405a9f6bf96f 100644 --- a/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt +++ b/ext/mbstring/tests/php_gr_jp_dev_884-2.phpt @@ -13,8 +13,11 @@ var_dump(preg_replace("/C?$/", "Z", "ABC")); var_dump(mb_ereg_replace("C*$", "Z", "ABC")); var_dump(preg_replace("/C*$/", "Z", "ABC")); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "ABZZ" string(4) "ABZZ" + +Deprecated: Function mb_ereg_replace() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d string(4) "ABZZ" string(4) "ABZZ" diff --git a/ext/mbstring/tests/retry_limit.phpt b/ext/mbstring/tests/retry_limit.phpt index bcb1a1def5c0..1ada020e68c6 100644 --- a/ext/mbstring/tests/retry_limit.phpt +++ b/ext/mbstring/tests/retry_limit.phpt @@ -5,7 +5,7 @@ mbstring --SKIPIF-- = 6.9.3'); } ?> @@ -19,6 +19,9 @@ ini_set('mbstring.regex_retry_limit', '100000'); var_dump(mb_ereg($regex, $str)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(true) + +Deprecated: Function mb_ereg() is deprecated since 8.6, because the underlying library is no longer maintained in %s on line %d bool(false) diff --git a/ext/mbstring/tests/unicode_versions.phpt b/ext/mbstring/tests/unicode_versions.phpt index b5b20ae2852f..77cf8dc7d275 100644 --- a/ext/mbstring/tests/unicode_versions.phpt +++ b/ext/mbstring/tests/unicode_versions.phpt @@ -23,6 +23,9 @@ print "Emoji (\u{1F6DC}): " . mb_strwidth("\u{1F6DC}", 'UTF-8') . "\n"; // Changed in Unicode 16.0, U+2630...U+2637 are wide print "Emoji (\u{2630}): " . mb_strwidth("\u{2630}", 'UTF-8') . "\n"; +// New in Unicode 17.0, width=2 +print "Emoji (\u{1FAEA}): " . mb_strwidth("\u{1FAEA}", "UTF-8") . "\n"; + echo "Char case changes:\n"; print "Upper(\u{019b}) = \u{a7dc} : "; @@ -37,5 +40,6 @@ Sinhalese (අයේෂ්): 5 Emoji (🐘): 2 Emoji (🛜): 2 Emoji (☰): 2 +Emoji (🫪): 2 Char case changes: Upper(ƛ) = Ƛ : bool(true) diff --git a/ext/mbstring/tests/zh_CN_default_encodings.phpt b/ext/mbstring/tests/zh_CN_default_encodings.phpt new file mode 100644 index 000000000000..213c304b52c6 --- /dev/null +++ b/ext/mbstring/tests/zh_CN_default_encodings.phpt @@ -0,0 +1,24 @@ +--TEST-- +Default encodings in Simplified Chinese +--EXTENSIONS-- +mbstring +--INI-- +mbstring.language=Simplified Chinese +--FILE-- + +--EXPECT-- +array(5) { + [0]=> + string(5) "ASCII" + [1]=> + string(5) "UTF-8" + [2]=> + string(6) "EUC-CN" + [3]=> + string(5) "CP936" + [4]=> + string(12) "GB18030-2022" +} diff --git a/ext/mbstring/unicode_data.h b/ext/mbstring/unicode_data.h index b205e67b21f1..31de0e5c20a2 100644 --- a/ext/mbstring/unicode_data.h +++ b/ext/mbstring/unicode_data.h @@ -13,11 +13,11 @@ static const unsigned short _ucprop_size = 37; static const unsigned short _ucprop_offsets[] = { - 0x0000, 0x02ca, 0x0446, 0x0450, 0x04de, 0x04f6, 0x0586, 0x0594, - 0x0596, 0x0598, 0x059a, 0x05a0, 0x05a0, 0x0ab6, 0x0fe2, 0x0ff6, - 0x108c, 0x14ac, 0x152e, 0x1558, 0x1596, 0x170c, 0x1d18, 0x1db0, - 0x1dcc, 0x1dde, 0x1e0e, 0x1e20, 0x1e3a, 0x1e44, 0x1e4a, 0x1e58, - 0x2290, 0x230c, 0x233a, 0x24c6, 0x2604, 0x298c, 0x0000, 0x0000 + 0x0000, 0x02da, 0x045c, 0x0466, 0x04f6, 0x0510, 0x05a0, 0x05ae, + 0x05b0, 0x05b2, 0x05b4, 0x05ba, 0x05ba, 0x0ad8, 0x1008, 0x101c, + 0x10ba, 0x14ec, 0x1572, 0x159c, 0x15da, 0x175c, 0x1d7a, 0x1e12, + 0x1e2e, 0x1e40, 0x1e70, 0x1e82, 0x1e9c, 0x1ea6, 0x1eac, 0x1eba, + 0x2310, 0x238c, 0x23ba, 0x2548, 0x2684, 0x2a24, 0x0000, 0x0000 }; static const unsigned int _ucprop_ranges[] = { @@ -92,85 +92,87 @@ static const unsigned int _ucprop_ranges[] = { 0x00001a60, 0x00001a60, 0x00001a62, 0x00001a62, 0x00001a65, 0x00001a6c, 0x00001a73, 0x00001a7c, 0x00001a7f, 0x00001a7f, 0x00001ab0, 0x00001abd, - 0x00001abf, 0x00001ace, 0x00001b00, 0x00001b03, - 0x00001b34, 0x00001b34, 0x00001b36, 0x00001b3a, - 0x00001b3c, 0x00001b3c, 0x00001b42, 0x00001b42, - 0x00001b6b, 0x00001b73, 0x00001b80, 0x00001b81, - 0x00001ba2, 0x00001ba5, 0x00001ba8, 0x00001ba9, - 0x00001bab, 0x00001bad, 0x00001be6, 0x00001be6, - 0x00001be8, 0x00001be9, 0x00001bed, 0x00001bed, - 0x00001bef, 0x00001bf1, 0x00001c2c, 0x00001c33, - 0x00001c36, 0x00001c37, 0x00001cd0, 0x00001cd2, - 0x00001cd4, 0x00001ce0, 0x00001ce2, 0x00001ce8, - 0x00001ced, 0x00001ced, 0x00001cf4, 0x00001cf4, - 0x00001cf8, 0x00001cf9, 0x00001dc0, 0x00001dff, - 0x000020d0, 0x000020dc, 0x000020e1, 0x000020e1, - 0x000020e5, 0x000020f0, 0x00002cef, 0x00002cf1, - 0x00002d7f, 0x00002d7f, 0x00002de0, 0x00002dff, - 0x0000302a, 0x0000302d, 0x00003099, 0x0000309a, - 0x0000a66f, 0x0000a66f, 0x0000a674, 0x0000a67d, - 0x0000a69e, 0x0000a69f, 0x0000a6f0, 0x0000a6f1, - 0x0000a802, 0x0000a802, 0x0000a806, 0x0000a806, - 0x0000a80b, 0x0000a80b, 0x0000a825, 0x0000a826, - 0x0000a82c, 0x0000a82c, 0x0000a8c4, 0x0000a8c5, - 0x0000a8e0, 0x0000a8f1, 0x0000a8ff, 0x0000a8ff, - 0x0000a926, 0x0000a92d, 0x0000a947, 0x0000a951, - 0x0000a980, 0x0000a982, 0x0000a9b3, 0x0000a9b3, - 0x0000a9b6, 0x0000a9b9, 0x0000a9bc, 0x0000a9bd, - 0x0000a9e5, 0x0000a9e5, 0x0000aa29, 0x0000aa2e, - 0x0000aa31, 0x0000aa32, 0x0000aa35, 0x0000aa36, - 0x0000aa43, 0x0000aa43, 0x0000aa4c, 0x0000aa4c, - 0x0000aa7c, 0x0000aa7c, 0x0000aab0, 0x0000aab0, - 0x0000aab2, 0x0000aab4, 0x0000aab7, 0x0000aab8, - 0x0000aabe, 0x0000aabf, 0x0000aac1, 0x0000aac1, - 0x0000aaec, 0x0000aaed, 0x0000aaf6, 0x0000aaf6, - 0x0000abe5, 0x0000abe5, 0x0000abe8, 0x0000abe8, - 0x0000abed, 0x0000abed, 0x0000fb1e, 0x0000fb1e, - 0x0000fe00, 0x0000fe0f, 0x0000fe20, 0x0000fe2f, - 0x000101fd, 0x000101fd, 0x000102e0, 0x000102e0, - 0x00010376, 0x0001037a, 0x00010a01, 0x00010a03, - 0x00010a05, 0x00010a06, 0x00010a0c, 0x00010a0f, - 0x00010a38, 0x00010a3a, 0x00010a3f, 0x00010a3f, - 0x00010ae5, 0x00010ae6, 0x00010d24, 0x00010d27, - 0x00010d69, 0x00010d6d, 0x00010eab, 0x00010eac, - 0x00010efc, 0x00010eff, 0x00010f46, 0x00010f50, - 0x00010f82, 0x00010f85, 0x00011001, 0x00011001, - 0x00011038, 0x00011046, 0x00011070, 0x00011070, - 0x00011073, 0x00011074, 0x0001107f, 0x00011081, - 0x000110b3, 0x000110b6, 0x000110b9, 0x000110ba, - 0x000110c2, 0x000110c2, 0x00011100, 0x00011102, - 0x00011127, 0x0001112b, 0x0001112d, 0x00011134, - 0x00011173, 0x00011173, 0x00011180, 0x00011181, - 0x000111b6, 0x000111be, 0x000111c9, 0x000111cc, - 0x000111cf, 0x000111cf, 0x0001122f, 0x00011231, - 0x00011234, 0x00011234, 0x00011236, 0x00011237, - 0x0001123e, 0x0001123e, 0x00011241, 0x00011241, - 0x000112df, 0x000112df, 0x000112e3, 0x000112ea, - 0x00011300, 0x00011301, 0x0001133b, 0x0001133c, - 0x00011340, 0x00011340, 0x00011366, 0x0001136c, - 0x00011370, 0x00011374, 0x000113bb, 0x000113c0, - 0x000113ce, 0x000113ce, 0x000113d0, 0x000113d0, - 0x000113d2, 0x000113d2, 0x000113e1, 0x000113e2, - 0x00011438, 0x0001143f, 0x00011442, 0x00011444, - 0x00011446, 0x00011446, 0x0001145e, 0x0001145e, - 0x000114b3, 0x000114b8, 0x000114ba, 0x000114ba, - 0x000114bf, 0x000114c0, 0x000114c2, 0x000114c3, - 0x000115b2, 0x000115b5, 0x000115bc, 0x000115bd, - 0x000115bf, 0x000115c0, 0x000115dc, 0x000115dd, - 0x00011633, 0x0001163a, 0x0001163d, 0x0001163d, - 0x0001163f, 0x00011640, 0x000116ab, 0x000116ab, - 0x000116ad, 0x000116ad, 0x000116b0, 0x000116b5, - 0x000116b7, 0x000116b7, 0x0001171d, 0x0001171d, - 0x0001171f, 0x0001171f, 0x00011722, 0x00011725, - 0x00011727, 0x0001172b, 0x0001182f, 0x00011837, - 0x00011839, 0x0001183a, 0x0001193b, 0x0001193c, - 0x0001193e, 0x0001193e, 0x00011943, 0x00011943, - 0x000119d4, 0x000119d7, 0x000119da, 0x000119db, - 0x000119e0, 0x000119e0, 0x00011a01, 0x00011a0a, - 0x00011a33, 0x00011a38, 0x00011a3b, 0x00011a3e, - 0x00011a47, 0x00011a47, 0x00011a51, 0x00011a56, - 0x00011a59, 0x00011a5b, 0x00011a8a, 0x00011a96, - 0x00011a98, 0x00011a99, 0x00011c30, 0x00011c36, + 0x00001abf, 0x00001add, 0x00001ae0, 0x00001aeb, + 0x00001b00, 0x00001b03, 0x00001b34, 0x00001b34, + 0x00001b36, 0x00001b3a, 0x00001b3c, 0x00001b3c, + 0x00001b42, 0x00001b42, 0x00001b6b, 0x00001b73, + 0x00001b80, 0x00001b81, 0x00001ba2, 0x00001ba5, + 0x00001ba8, 0x00001ba9, 0x00001bab, 0x00001bad, + 0x00001be6, 0x00001be6, 0x00001be8, 0x00001be9, + 0x00001bed, 0x00001bed, 0x00001bef, 0x00001bf1, + 0x00001c2c, 0x00001c33, 0x00001c36, 0x00001c37, + 0x00001cd0, 0x00001cd2, 0x00001cd4, 0x00001ce0, + 0x00001ce2, 0x00001ce8, 0x00001ced, 0x00001ced, + 0x00001cf4, 0x00001cf4, 0x00001cf8, 0x00001cf9, + 0x00001dc0, 0x00001dff, 0x000020d0, 0x000020dc, + 0x000020e1, 0x000020e1, 0x000020e5, 0x000020f0, + 0x00002cef, 0x00002cf1, 0x00002d7f, 0x00002d7f, + 0x00002de0, 0x00002dff, 0x0000302a, 0x0000302d, + 0x00003099, 0x0000309a, 0x0000a66f, 0x0000a66f, + 0x0000a674, 0x0000a67d, 0x0000a69e, 0x0000a69f, + 0x0000a6f0, 0x0000a6f1, 0x0000a802, 0x0000a802, + 0x0000a806, 0x0000a806, 0x0000a80b, 0x0000a80b, + 0x0000a825, 0x0000a826, 0x0000a82c, 0x0000a82c, + 0x0000a8c4, 0x0000a8c5, 0x0000a8e0, 0x0000a8f1, + 0x0000a8ff, 0x0000a8ff, 0x0000a926, 0x0000a92d, + 0x0000a947, 0x0000a951, 0x0000a980, 0x0000a982, + 0x0000a9b3, 0x0000a9b3, 0x0000a9b6, 0x0000a9b9, + 0x0000a9bc, 0x0000a9bd, 0x0000a9e5, 0x0000a9e5, + 0x0000aa29, 0x0000aa2e, 0x0000aa31, 0x0000aa32, + 0x0000aa35, 0x0000aa36, 0x0000aa43, 0x0000aa43, + 0x0000aa4c, 0x0000aa4c, 0x0000aa7c, 0x0000aa7c, + 0x0000aab0, 0x0000aab0, 0x0000aab2, 0x0000aab4, + 0x0000aab7, 0x0000aab8, 0x0000aabe, 0x0000aabf, + 0x0000aac1, 0x0000aac1, 0x0000aaec, 0x0000aaed, + 0x0000aaf6, 0x0000aaf6, 0x0000abe5, 0x0000abe5, + 0x0000abe8, 0x0000abe8, 0x0000abed, 0x0000abed, + 0x0000fb1e, 0x0000fb1e, 0x0000fe00, 0x0000fe0f, + 0x0000fe20, 0x0000fe2f, 0x000101fd, 0x000101fd, + 0x000102e0, 0x000102e0, 0x00010376, 0x0001037a, + 0x00010a01, 0x00010a03, 0x00010a05, 0x00010a06, + 0x00010a0c, 0x00010a0f, 0x00010a38, 0x00010a3a, + 0x00010a3f, 0x00010a3f, 0x00010ae5, 0x00010ae6, + 0x00010d24, 0x00010d27, 0x00010d69, 0x00010d6d, + 0x00010eab, 0x00010eac, 0x00010efa, 0x00010eff, + 0x00010f46, 0x00010f50, 0x00010f82, 0x00010f85, + 0x00011001, 0x00011001, 0x00011038, 0x00011046, + 0x00011070, 0x00011070, 0x00011073, 0x00011074, + 0x0001107f, 0x00011081, 0x000110b3, 0x000110b6, + 0x000110b9, 0x000110ba, 0x000110c2, 0x000110c2, + 0x00011100, 0x00011102, 0x00011127, 0x0001112b, + 0x0001112d, 0x00011134, 0x00011173, 0x00011173, + 0x00011180, 0x00011181, 0x000111b6, 0x000111be, + 0x000111c9, 0x000111cc, 0x000111cf, 0x000111cf, + 0x0001122f, 0x00011231, 0x00011234, 0x00011234, + 0x00011236, 0x00011237, 0x0001123e, 0x0001123e, + 0x00011241, 0x00011241, 0x000112df, 0x000112df, + 0x000112e3, 0x000112ea, 0x00011300, 0x00011301, + 0x0001133b, 0x0001133c, 0x00011340, 0x00011340, + 0x00011366, 0x0001136c, 0x00011370, 0x00011374, + 0x000113bb, 0x000113c0, 0x000113ce, 0x000113ce, + 0x000113d0, 0x000113d0, 0x000113d2, 0x000113d2, + 0x000113e1, 0x000113e2, 0x00011438, 0x0001143f, + 0x00011442, 0x00011444, 0x00011446, 0x00011446, + 0x0001145e, 0x0001145e, 0x000114b3, 0x000114b8, + 0x000114ba, 0x000114ba, 0x000114bf, 0x000114c0, + 0x000114c2, 0x000114c3, 0x000115b2, 0x000115b5, + 0x000115bc, 0x000115bd, 0x000115bf, 0x000115c0, + 0x000115dc, 0x000115dd, 0x00011633, 0x0001163a, + 0x0001163d, 0x0001163d, 0x0001163f, 0x00011640, + 0x000116ab, 0x000116ab, 0x000116ad, 0x000116ad, + 0x000116b0, 0x000116b5, 0x000116b7, 0x000116b7, + 0x0001171d, 0x0001171d, 0x0001171f, 0x0001171f, + 0x00011722, 0x00011725, 0x00011727, 0x0001172b, + 0x0001182f, 0x00011837, 0x00011839, 0x0001183a, + 0x0001193b, 0x0001193c, 0x0001193e, 0x0001193e, + 0x00011943, 0x00011943, 0x000119d4, 0x000119d7, + 0x000119da, 0x000119db, 0x000119e0, 0x000119e0, + 0x00011a01, 0x00011a0a, 0x00011a33, 0x00011a38, + 0x00011a3b, 0x00011a3e, 0x00011a47, 0x00011a47, + 0x00011a51, 0x00011a56, 0x00011a59, 0x00011a5b, + 0x00011a8a, 0x00011a96, 0x00011a98, 0x00011a99, + 0x00011b60, 0x00011b60, 0x00011b62, 0x00011b64, + 0x00011b66, 0x00011b66, 0x00011c30, 0x00011c36, 0x00011c38, 0x00011c3d, 0x00011c3f, 0x00011c3f, 0x00011c92, 0x00011ca7, 0x00011caa, 0x00011cb0, 0x00011cb2, 0x00011cb3, 0x00011cb5, 0x00011cb6, @@ -198,6 +200,8 @@ static const unsigned int _ucprop_ranges[] = { 0x0001e08f, 0x0001e08f, 0x0001e130, 0x0001e136, 0x0001e2ae, 0x0001e2ae, 0x0001e2ec, 0x0001e2ef, 0x0001e4ec, 0x0001e4ef, 0x0001e5ee, 0x0001e5ef, + 0x0001e6e3, 0x0001e6e3, 0x0001e6e6, 0x0001e6e6, + 0x0001e6ee, 0x0001e6ef, 0x0001e6f5, 0x0001e6f5, 0x0001e8d0, 0x0001e8d6, 0x0001e944, 0x0001e94a, 0x000e0100, 0x000e01ef, 0x00000903, 0x00000903, 0x0000093b, 0x0000093b, 0x0000093e, 0x00000940, @@ -285,47 +289,49 @@ static const unsigned int _ucprop_ranges[] = { 0x00011942, 0x00011942, 0x000119d1, 0x000119d3, 0x000119dc, 0x000119df, 0x000119e4, 0x000119e4, 0x00011a39, 0x00011a39, 0x00011a57, 0x00011a58, - 0x00011a97, 0x00011a97, 0x00011c2f, 0x00011c2f, - 0x00011c3e, 0x00011c3e, 0x00011ca9, 0x00011ca9, - 0x00011cb1, 0x00011cb1, 0x00011cb4, 0x00011cb4, - 0x00011d8a, 0x00011d8e, 0x00011d93, 0x00011d94, - 0x00011d96, 0x00011d96, 0x00011ef5, 0x00011ef6, - 0x00011f03, 0x00011f03, 0x00011f34, 0x00011f35, - 0x00011f3e, 0x00011f3f, 0x00011f41, 0x00011f41, - 0x0001612a, 0x0001612c, 0x00016f51, 0x00016f87, - 0x00016ff0, 0x00016ff1, 0x0001d165, 0x0001d166, - 0x0001d16d, 0x0001d172, 0x00000488, 0x00000489, - 0x00001abe, 0x00001abe, 0x000020dd, 0x000020e0, - 0x000020e2, 0x000020e4, 0x0000a670, 0x0000a672, - 0x00000030, 0x00000039, 0x00000660, 0x00000669, - 0x000006f0, 0x000006f9, 0x000007c0, 0x000007c9, - 0x00000966, 0x0000096f, 0x000009e6, 0x000009ef, - 0x00000a66, 0x00000a6f, 0x00000ae6, 0x00000aef, - 0x00000b66, 0x00000b6f, 0x00000be6, 0x00000bef, - 0x00000c66, 0x00000c6f, 0x00000ce6, 0x00000cef, - 0x00000d66, 0x00000d6f, 0x00000de6, 0x00000def, - 0x00000e50, 0x00000e59, 0x00000ed0, 0x00000ed9, - 0x00000f20, 0x00000f29, 0x00001040, 0x00001049, - 0x00001090, 0x00001099, 0x000017e0, 0x000017e9, - 0x00001810, 0x00001819, 0x00001946, 0x0000194f, - 0x000019d0, 0x000019d9, 0x00001a80, 0x00001a89, - 0x00001a90, 0x00001a99, 0x00001b50, 0x00001b59, - 0x00001bb0, 0x00001bb9, 0x00001c40, 0x00001c49, - 0x00001c50, 0x00001c59, 0x0000a620, 0x0000a629, - 0x0000a8d0, 0x0000a8d9, 0x0000a900, 0x0000a909, - 0x0000a9d0, 0x0000a9d9, 0x0000a9f0, 0x0000a9f9, - 0x0000aa50, 0x0000aa59, 0x0000abf0, 0x0000abf9, - 0x0000ff10, 0x0000ff19, 0x000104a0, 0x000104a9, - 0x00010d30, 0x00010d39, 0x00010d40, 0x00010d49, - 0x00011066, 0x0001106f, 0x000110f0, 0x000110f9, - 0x00011136, 0x0001113f, 0x000111d0, 0x000111d9, - 0x000112f0, 0x000112f9, 0x00011450, 0x00011459, - 0x000114d0, 0x000114d9, 0x00011650, 0x00011659, - 0x000116c0, 0x000116c9, 0x000116d0, 0x000116e3, - 0x00011730, 0x00011739, 0x000118e0, 0x000118e9, - 0x00011950, 0x00011959, 0x00011bf0, 0x00011bf9, - 0x00011c50, 0x00011c59, 0x00011d50, 0x00011d59, - 0x00011da0, 0x00011da9, 0x00011f50, 0x00011f59, + 0x00011a97, 0x00011a97, 0x00011b61, 0x00011b61, + 0x00011b65, 0x00011b65, 0x00011b67, 0x00011b67, + 0x00011c2f, 0x00011c2f, 0x00011c3e, 0x00011c3e, + 0x00011ca9, 0x00011ca9, 0x00011cb1, 0x00011cb1, + 0x00011cb4, 0x00011cb4, 0x00011d8a, 0x00011d8e, + 0x00011d93, 0x00011d94, 0x00011d96, 0x00011d96, + 0x00011ef5, 0x00011ef6, 0x00011f03, 0x00011f03, + 0x00011f34, 0x00011f35, 0x00011f3e, 0x00011f3f, + 0x00011f41, 0x00011f41, 0x0001612a, 0x0001612c, + 0x00016f51, 0x00016f87, 0x00016ff0, 0x00016ff1, + 0x0001d165, 0x0001d166, 0x0001d16d, 0x0001d172, + 0x00000488, 0x00000489, 0x00001abe, 0x00001abe, + 0x000020dd, 0x000020e0, 0x000020e2, 0x000020e4, + 0x0000a670, 0x0000a672, 0x00000030, 0x00000039, + 0x00000660, 0x00000669, 0x000006f0, 0x000006f9, + 0x000007c0, 0x000007c9, 0x00000966, 0x0000096f, + 0x000009e6, 0x000009ef, 0x00000a66, 0x00000a6f, + 0x00000ae6, 0x00000aef, 0x00000b66, 0x00000b6f, + 0x00000be6, 0x00000bef, 0x00000c66, 0x00000c6f, + 0x00000ce6, 0x00000cef, 0x00000d66, 0x00000d6f, + 0x00000de6, 0x00000def, 0x00000e50, 0x00000e59, + 0x00000ed0, 0x00000ed9, 0x00000f20, 0x00000f29, + 0x00001040, 0x00001049, 0x00001090, 0x00001099, + 0x000017e0, 0x000017e9, 0x00001810, 0x00001819, + 0x00001946, 0x0000194f, 0x000019d0, 0x000019d9, + 0x00001a80, 0x00001a89, 0x00001a90, 0x00001a99, + 0x00001b50, 0x00001b59, 0x00001bb0, 0x00001bb9, + 0x00001c40, 0x00001c49, 0x00001c50, 0x00001c59, + 0x0000a620, 0x0000a629, 0x0000a8d0, 0x0000a8d9, + 0x0000a900, 0x0000a909, 0x0000a9d0, 0x0000a9d9, + 0x0000a9f0, 0x0000a9f9, 0x0000aa50, 0x0000aa59, + 0x0000abf0, 0x0000abf9, 0x0000ff10, 0x0000ff19, + 0x000104a0, 0x000104a9, 0x00010d30, 0x00010d39, + 0x00010d40, 0x00010d49, 0x00011066, 0x0001106f, + 0x000110f0, 0x000110f9, 0x00011136, 0x0001113f, + 0x000111d0, 0x000111d9, 0x000112f0, 0x000112f9, + 0x00011450, 0x00011459, 0x000114d0, 0x000114d9, + 0x00011650, 0x00011659, 0x000116c0, 0x000116c9, + 0x000116d0, 0x000116e3, 0x00011730, 0x00011739, + 0x000118e0, 0x000118e9, 0x00011950, 0x00011959, + 0x00011bf0, 0x00011bf9, 0x00011c50, 0x00011c59, + 0x00011d50, 0x00011d59, 0x00011da0, 0x00011da9, + 0x00011de0, 0x00011de9, 0x00011f50, 0x00011f59, 0x00016130, 0x00016139, 0x00016a60, 0x00016a69, 0x00016ac0, 0x00016ac9, 0x00016b50, 0x00016b59, 0x00016d70, 0x00016d79, 0x0001ccf0, 0x0001ccf9, @@ -338,351 +344,353 @@ static const unsigned int _ucprop_ranges[] = { 0x00003038, 0x0000303a, 0x0000a6e6, 0x0000a6ef, 0x00010140, 0x00010174, 0x00010341, 0x00010341, 0x0001034a, 0x0001034a, 0x000103d1, 0x000103d5, - 0x00012400, 0x0001246e, 0x000000b2, 0x000000b3, - 0x000000b9, 0x000000b9, 0x000000bc, 0x000000be, - 0x000009f4, 0x000009f9, 0x00000b72, 0x00000b77, - 0x00000bf0, 0x00000bf2, 0x00000c78, 0x00000c7e, - 0x00000d58, 0x00000d5e, 0x00000d70, 0x00000d78, - 0x00000f2a, 0x00000f33, 0x00001369, 0x0000137c, - 0x000017f0, 0x000017f9, 0x000019da, 0x000019da, - 0x00002070, 0x00002070, 0x00002074, 0x00002079, - 0x00002080, 0x00002089, 0x00002150, 0x0000215f, - 0x00002189, 0x00002189, 0x00002460, 0x0000249b, - 0x000024ea, 0x000024ff, 0x00002776, 0x00002793, - 0x00002cfd, 0x00002cfd, 0x00003192, 0x00003195, - 0x00003220, 0x00003229, 0x00003248, 0x0000324f, - 0x00003251, 0x0000325f, 0x00003280, 0x00003289, - 0x000032b1, 0x000032bf, 0x0000a830, 0x0000a835, - 0x00010107, 0x00010133, 0x00010175, 0x00010178, - 0x0001018a, 0x0001018b, 0x000102e1, 0x000102fb, - 0x00010320, 0x00010323, 0x00010858, 0x0001085f, - 0x00010879, 0x0001087f, 0x000108a7, 0x000108af, - 0x000108fb, 0x000108ff, 0x00010916, 0x0001091b, - 0x000109bc, 0x000109bd, 0x000109c0, 0x000109cf, - 0x000109d2, 0x000109ff, 0x00010a40, 0x00010a48, - 0x00010a7d, 0x00010a7e, 0x00010a9d, 0x00010a9f, - 0x00010aeb, 0x00010aef, 0x00010b58, 0x00010b5f, - 0x00010b78, 0x00010b7f, 0x00010ba9, 0x00010baf, - 0x00010cfa, 0x00010cff, 0x00010e60, 0x00010e7e, - 0x00010f1d, 0x00010f26, 0x00010f51, 0x00010f54, - 0x00010fc5, 0x00010fcb, 0x00011052, 0x00011065, - 0x000111e1, 0x000111f4, 0x0001173a, 0x0001173b, - 0x000118ea, 0x000118f2, 0x00011c5a, 0x00011c6c, - 0x00011fc0, 0x00011fd4, 0x00016b5b, 0x00016b61, - 0x00016e80, 0x00016e96, 0x0001d2c0, 0x0001d2d3, - 0x0001d2e0, 0x0001d2f3, 0x0001d360, 0x0001d378, - 0x0001e8c7, 0x0001e8cf, 0x0001ec71, 0x0001ecab, - 0x0001ecad, 0x0001ecaf, 0x0001ecb1, 0x0001ecb4, - 0x0001ed01, 0x0001ed2d, 0x0001ed2f, 0x0001ed3d, - 0x0001f100, 0x0001f10c, 0x00000020, 0x00000020, - 0x000000a0, 0x000000a0, 0x00001680, 0x00001680, - 0x00002000, 0x0000200a, 0x0000202f, 0x0000202f, - 0x0000205f, 0x0000205f, 0x00003000, 0x00003000, - 0x00002028, 0x00002028, 0x00002029, 0x00002029, - 0x0000d800, 0x0000dfff, 0x0000e000, 0x0000f8ff, - 0x000f0000, 0x000ffffd, 0x00100000, 0x0010fffd, - 0x00000041, 0x0000005a, 0x000000c0, 0x000000d6, - 0x000000d8, 0x000000de, 0x00000100, 0x00000100, - 0x00000102, 0x00000102, 0x00000104, 0x00000104, - 0x00000106, 0x00000106, 0x00000108, 0x00000108, - 0x0000010a, 0x0000010a, 0x0000010c, 0x0000010c, - 0x0000010e, 0x0000010e, 0x00000110, 0x00000110, - 0x00000112, 0x00000112, 0x00000114, 0x00000114, - 0x00000116, 0x00000116, 0x00000118, 0x00000118, - 0x0000011a, 0x0000011a, 0x0000011c, 0x0000011c, - 0x0000011e, 0x0000011e, 0x00000120, 0x00000120, - 0x00000122, 0x00000122, 0x00000124, 0x00000124, - 0x00000126, 0x00000126, 0x00000128, 0x00000128, - 0x0000012a, 0x0000012a, 0x0000012c, 0x0000012c, - 0x0000012e, 0x0000012e, 0x00000130, 0x00000130, - 0x00000132, 0x00000132, 0x00000134, 0x00000134, - 0x00000136, 0x00000136, 0x00000139, 0x00000139, - 0x0000013b, 0x0000013b, 0x0000013d, 0x0000013d, - 0x0000013f, 0x0000013f, 0x00000141, 0x00000141, - 0x00000143, 0x00000143, 0x00000145, 0x00000145, - 0x00000147, 0x00000147, 0x0000014a, 0x0000014a, - 0x0000014c, 0x0000014c, 0x0000014e, 0x0000014e, - 0x00000150, 0x00000150, 0x00000152, 0x00000152, - 0x00000154, 0x00000154, 0x00000156, 0x00000156, - 0x00000158, 0x00000158, 0x0000015a, 0x0000015a, - 0x0000015c, 0x0000015c, 0x0000015e, 0x0000015e, - 0x00000160, 0x00000160, 0x00000162, 0x00000162, - 0x00000164, 0x00000164, 0x00000166, 0x00000166, - 0x00000168, 0x00000168, 0x0000016a, 0x0000016a, - 0x0000016c, 0x0000016c, 0x0000016e, 0x0000016e, - 0x00000170, 0x00000170, 0x00000172, 0x00000172, - 0x00000174, 0x00000174, 0x00000176, 0x00000176, - 0x00000178, 0x00000179, 0x0000017b, 0x0000017b, - 0x0000017d, 0x0000017d, 0x00000181, 0x00000182, - 0x00000184, 0x00000184, 0x00000186, 0x00000187, - 0x00000189, 0x0000018b, 0x0000018e, 0x00000191, - 0x00000193, 0x00000194, 0x00000196, 0x00000198, - 0x0000019c, 0x0000019d, 0x0000019f, 0x000001a0, - 0x000001a2, 0x000001a2, 0x000001a4, 0x000001a4, - 0x000001a6, 0x000001a7, 0x000001a9, 0x000001a9, - 0x000001ac, 0x000001ac, 0x000001ae, 0x000001af, - 0x000001b1, 0x000001b3, 0x000001b5, 0x000001b5, - 0x000001b7, 0x000001b8, 0x000001bc, 0x000001bc, - 0x000001c4, 0x000001c4, 0x000001c7, 0x000001c7, - 0x000001ca, 0x000001ca, 0x000001cd, 0x000001cd, - 0x000001cf, 0x000001cf, 0x000001d1, 0x000001d1, - 0x000001d3, 0x000001d3, 0x000001d5, 0x000001d5, - 0x000001d7, 0x000001d7, 0x000001d9, 0x000001d9, - 0x000001db, 0x000001db, 0x000001de, 0x000001de, - 0x000001e0, 0x000001e0, 0x000001e2, 0x000001e2, - 0x000001e4, 0x000001e4, 0x000001e6, 0x000001e6, - 0x000001e8, 0x000001e8, 0x000001ea, 0x000001ea, - 0x000001ec, 0x000001ec, 0x000001ee, 0x000001ee, - 0x000001f1, 0x000001f1, 0x000001f4, 0x000001f4, - 0x000001f6, 0x000001f8, 0x000001fa, 0x000001fa, - 0x000001fc, 0x000001fc, 0x000001fe, 0x000001fe, - 0x00000200, 0x00000200, 0x00000202, 0x00000202, - 0x00000204, 0x00000204, 0x00000206, 0x00000206, - 0x00000208, 0x00000208, 0x0000020a, 0x0000020a, - 0x0000020c, 0x0000020c, 0x0000020e, 0x0000020e, - 0x00000210, 0x00000210, 0x00000212, 0x00000212, - 0x00000214, 0x00000214, 0x00000216, 0x00000216, - 0x00000218, 0x00000218, 0x0000021a, 0x0000021a, - 0x0000021c, 0x0000021c, 0x0000021e, 0x0000021e, - 0x00000220, 0x00000220, 0x00000222, 0x00000222, - 0x00000224, 0x00000224, 0x00000226, 0x00000226, - 0x00000228, 0x00000228, 0x0000022a, 0x0000022a, - 0x0000022c, 0x0000022c, 0x0000022e, 0x0000022e, - 0x00000230, 0x00000230, 0x00000232, 0x00000232, - 0x0000023a, 0x0000023b, 0x0000023d, 0x0000023e, - 0x00000241, 0x00000241, 0x00000243, 0x00000246, - 0x00000248, 0x00000248, 0x0000024a, 0x0000024a, - 0x0000024c, 0x0000024c, 0x0000024e, 0x0000024e, - 0x00000370, 0x00000370, 0x00000372, 0x00000372, - 0x00000376, 0x00000376, 0x0000037f, 0x0000037f, - 0x00000386, 0x00000386, 0x00000388, 0x0000038a, - 0x0000038c, 0x0000038c, 0x0000038e, 0x0000038f, - 0x00000391, 0x000003a1, 0x000003a3, 0x000003ab, - 0x000003cf, 0x000003cf, 0x000003d2, 0x000003d4, - 0x000003d8, 0x000003d8, 0x000003da, 0x000003da, - 0x000003dc, 0x000003dc, 0x000003de, 0x000003de, - 0x000003e0, 0x000003e0, 0x000003e2, 0x000003e2, - 0x000003e4, 0x000003e4, 0x000003e6, 0x000003e6, - 0x000003e8, 0x000003e8, 0x000003ea, 0x000003ea, - 0x000003ec, 0x000003ec, 0x000003ee, 0x000003ee, - 0x000003f4, 0x000003f4, 0x000003f7, 0x000003f7, - 0x000003f9, 0x000003fa, 0x000003fd, 0x0000042f, - 0x00000460, 0x00000460, 0x00000462, 0x00000462, - 0x00000464, 0x00000464, 0x00000466, 0x00000466, - 0x00000468, 0x00000468, 0x0000046a, 0x0000046a, - 0x0000046c, 0x0000046c, 0x0000046e, 0x0000046e, - 0x00000470, 0x00000470, 0x00000472, 0x00000472, - 0x00000474, 0x00000474, 0x00000476, 0x00000476, - 0x00000478, 0x00000478, 0x0000047a, 0x0000047a, - 0x0000047c, 0x0000047c, 0x0000047e, 0x0000047e, - 0x00000480, 0x00000480, 0x0000048a, 0x0000048a, - 0x0000048c, 0x0000048c, 0x0000048e, 0x0000048e, - 0x00000490, 0x00000490, 0x00000492, 0x00000492, - 0x00000494, 0x00000494, 0x00000496, 0x00000496, - 0x00000498, 0x00000498, 0x0000049a, 0x0000049a, - 0x0000049c, 0x0000049c, 0x0000049e, 0x0000049e, - 0x000004a0, 0x000004a0, 0x000004a2, 0x000004a2, - 0x000004a4, 0x000004a4, 0x000004a6, 0x000004a6, - 0x000004a8, 0x000004a8, 0x000004aa, 0x000004aa, - 0x000004ac, 0x000004ac, 0x000004ae, 0x000004ae, - 0x000004b0, 0x000004b0, 0x000004b2, 0x000004b2, - 0x000004b4, 0x000004b4, 0x000004b6, 0x000004b6, - 0x000004b8, 0x000004b8, 0x000004ba, 0x000004ba, - 0x000004bc, 0x000004bc, 0x000004be, 0x000004be, - 0x000004c0, 0x000004c1, 0x000004c3, 0x000004c3, - 0x000004c5, 0x000004c5, 0x000004c7, 0x000004c7, - 0x000004c9, 0x000004c9, 0x000004cb, 0x000004cb, - 0x000004cd, 0x000004cd, 0x000004d0, 0x000004d0, - 0x000004d2, 0x000004d2, 0x000004d4, 0x000004d4, - 0x000004d6, 0x000004d6, 0x000004d8, 0x000004d8, - 0x000004da, 0x000004da, 0x000004dc, 0x000004dc, - 0x000004de, 0x000004de, 0x000004e0, 0x000004e0, - 0x000004e2, 0x000004e2, 0x000004e4, 0x000004e4, - 0x000004e6, 0x000004e6, 0x000004e8, 0x000004e8, - 0x000004ea, 0x000004ea, 0x000004ec, 0x000004ec, - 0x000004ee, 0x000004ee, 0x000004f0, 0x000004f0, - 0x000004f2, 0x000004f2, 0x000004f4, 0x000004f4, - 0x000004f6, 0x000004f6, 0x000004f8, 0x000004f8, - 0x000004fa, 0x000004fa, 0x000004fc, 0x000004fc, - 0x000004fe, 0x000004fe, 0x00000500, 0x00000500, - 0x00000502, 0x00000502, 0x00000504, 0x00000504, - 0x00000506, 0x00000506, 0x00000508, 0x00000508, - 0x0000050a, 0x0000050a, 0x0000050c, 0x0000050c, - 0x0000050e, 0x0000050e, 0x00000510, 0x00000510, - 0x00000512, 0x00000512, 0x00000514, 0x00000514, - 0x00000516, 0x00000516, 0x00000518, 0x00000518, - 0x0000051a, 0x0000051a, 0x0000051c, 0x0000051c, - 0x0000051e, 0x0000051e, 0x00000520, 0x00000520, - 0x00000522, 0x00000522, 0x00000524, 0x00000524, - 0x00000526, 0x00000526, 0x00000528, 0x00000528, - 0x0000052a, 0x0000052a, 0x0000052c, 0x0000052c, - 0x0000052e, 0x0000052e, 0x00000531, 0x00000556, - 0x000010a0, 0x000010c5, 0x000010c7, 0x000010c7, - 0x000010cd, 0x000010cd, 0x000013a0, 0x000013f5, - 0x00001c89, 0x00001c89, 0x00001c90, 0x00001cba, - 0x00001cbd, 0x00001cbf, 0x00001e00, 0x00001e00, - 0x00001e02, 0x00001e02, 0x00001e04, 0x00001e04, - 0x00001e06, 0x00001e06, 0x00001e08, 0x00001e08, - 0x00001e0a, 0x00001e0a, 0x00001e0c, 0x00001e0c, - 0x00001e0e, 0x00001e0e, 0x00001e10, 0x00001e10, - 0x00001e12, 0x00001e12, 0x00001e14, 0x00001e14, - 0x00001e16, 0x00001e16, 0x00001e18, 0x00001e18, - 0x00001e1a, 0x00001e1a, 0x00001e1c, 0x00001e1c, - 0x00001e1e, 0x00001e1e, 0x00001e20, 0x00001e20, - 0x00001e22, 0x00001e22, 0x00001e24, 0x00001e24, - 0x00001e26, 0x00001e26, 0x00001e28, 0x00001e28, - 0x00001e2a, 0x00001e2a, 0x00001e2c, 0x00001e2c, - 0x00001e2e, 0x00001e2e, 0x00001e30, 0x00001e30, - 0x00001e32, 0x00001e32, 0x00001e34, 0x00001e34, - 0x00001e36, 0x00001e36, 0x00001e38, 0x00001e38, - 0x00001e3a, 0x00001e3a, 0x00001e3c, 0x00001e3c, - 0x00001e3e, 0x00001e3e, 0x00001e40, 0x00001e40, - 0x00001e42, 0x00001e42, 0x00001e44, 0x00001e44, - 0x00001e46, 0x00001e46, 0x00001e48, 0x00001e48, - 0x00001e4a, 0x00001e4a, 0x00001e4c, 0x00001e4c, - 0x00001e4e, 0x00001e4e, 0x00001e50, 0x00001e50, - 0x00001e52, 0x00001e52, 0x00001e54, 0x00001e54, - 0x00001e56, 0x00001e56, 0x00001e58, 0x00001e58, - 0x00001e5a, 0x00001e5a, 0x00001e5c, 0x00001e5c, - 0x00001e5e, 0x00001e5e, 0x00001e60, 0x00001e60, - 0x00001e62, 0x00001e62, 0x00001e64, 0x00001e64, - 0x00001e66, 0x00001e66, 0x00001e68, 0x00001e68, - 0x00001e6a, 0x00001e6a, 0x00001e6c, 0x00001e6c, - 0x00001e6e, 0x00001e6e, 0x00001e70, 0x00001e70, - 0x00001e72, 0x00001e72, 0x00001e74, 0x00001e74, - 0x00001e76, 0x00001e76, 0x00001e78, 0x00001e78, - 0x00001e7a, 0x00001e7a, 0x00001e7c, 0x00001e7c, - 0x00001e7e, 0x00001e7e, 0x00001e80, 0x00001e80, - 0x00001e82, 0x00001e82, 0x00001e84, 0x00001e84, - 0x00001e86, 0x00001e86, 0x00001e88, 0x00001e88, - 0x00001e8a, 0x00001e8a, 0x00001e8c, 0x00001e8c, - 0x00001e8e, 0x00001e8e, 0x00001e90, 0x00001e90, - 0x00001e92, 0x00001e92, 0x00001e94, 0x00001e94, - 0x00001e9e, 0x00001e9e, 0x00001ea0, 0x00001ea0, - 0x00001ea2, 0x00001ea2, 0x00001ea4, 0x00001ea4, - 0x00001ea6, 0x00001ea6, 0x00001ea8, 0x00001ea8, - 0x00001eaa, 0x00001eaa, 0x00001eac, 0x00001eac, - 0x00001eae, 0x00001eae, 0x00001eb0, 0x00001eb0, - 0x00001eb2, 0x00001eb2, 0x00001eb4, 0x00001eb4, - 0x00001eb6, 0x00001eb6, 0x00001eb8, 0x00001eb8, - 0x00001eba, 0x00001eba, 0x00001ebc, 0x00001ebc, - 0x00001ebe, 0x00001ebe, 0x00001ec0, 0x00001ec0, - 0x00001ec2, 0x00001ec2, 0x00001ec4, 0x00001ec4, - 0x00001ec6, 0x00001ec6, 0x00001ec8, 0x00001ec8, - 0x00001eca, 0x00001eca, 0x00001ecc, 0x00001ecc, - 0x00001ece, 0x00001ece, 0x00001ed0, 0x00001ed0, - 0x00001ed2, 0x00001ed2, 0x00001ed4, 0x00001ed4, - 0x00001ed6, 0x00001ed6, 0x00001ed8, 0x00001ed8, - 0x00001eda, 0x00001eda, 0x00001edc, 0x00001edc, - 0x00001ede, 0x00001ede, 0x00001ee0, 0x00001ee0, - 0x00001ee2, 0x00001ee2, 0x00001ee4, 0x00001ee4, - 0x00001ee6, 0x00001ee6, 0x00001ee8, 0x00001ee8, - 0x00001eea, 0x00001eea, 0x00001eec, 0x00001eec, - 0x00001eee, 0x00001eee, 0x00001ef0, 0x00001ef0, - 0x00001ef2, 0x00001ef2, 0x00001ef4, 0x00001ef4, - 0x00001ef6, 0x00001ef6, 0x00001ef8, 0x00001ef8, - 0x00001efa, 0x00001efa, 0x00001efc, 0x00001efc, - 0x00001efe, 0x00001efe, 0x00001f08, 0x00001f0f, - 0x00001f18, 0x00001f1d, 0x00001f28, 0x00001f2f, - 0x00001f38, 0x00001f3f, 0x00001f48, 0x00001f4d, - 0x00001f59, 0x00001f59, 0x00001f5b, 0x00001f5b, - 0x00001f5d, 0x00001f5d, 0x00001f5f, 0x00001f5f, - 0x00001f68, 0x00001f6f, 0x00001fb8, 0x00001fbb, - 0x00001fc8, 0x00001fcb, 0x00001fd8, 0x00001fdb, - 0x00001fe8, 0x00001fec, 0x00001ff8, 0x00001ffb, - 0x00002102, 0x00002102, 0x00002107, 0x00002107, - 0x0000210b, 0x0000210d, 0x00002110, 0x00002112, - 0x00002115, 0x00002115, 0x00002119, 0x0000211d, - 0x00002124, 0x00002124, 0x00002126, 0x00002126, - 0x00002128, 0x00002128, 0x0000212a, 0x0000212d, - 0x00002130, 0x00002133, 0x0000213e, 0x0000213f, - 0x00002145, 0x00002145, 0x00002183, 0x00002183, - 0x00002c00, 0x00002c2f, 0x00002c60, 0x00002c60, - 0x00002c62, 0x00002c64, 0x00002c67, 0x00002c67, - 0x00002c69, 0x00002c69, 0x00002c6b, 0x00002c6b, - 0x00002c6d, 0x00002c70, 0x00002c72, 0x00002c72, - 0x00002c75, 0x00002c75, 0x00002c7e, 0x00002c80, - 0x00002c82, 0x00002c82, 0x00002c84, 0x00002c84, - 0x00002c86, 0x00002c86, 0x00002c88, 0x00002c88, - 0x00002c8a, 0x00002c8a, 0x00002c8c, 0x00002c8c, - 0x00002c8e, 0x00002c8e, 0x00002c90, 0x00002c90, - 0x00002c92, 0x00002c92, 0x00002c94, 0x00002c94, - 0x00002c96, 0x00002c96, 0x00002c98, 0x00002c98, - 0x00002c9a, 0x00002c9a, 0x00002c9c, 0x00002c9c, - 0x00002c9e, 0x00002c9e, 0x00002ca0, 0x00002ca0, - 0x00002ca2, 0x00002ca2, 0x00002ca4, 0x00002ca4, - 0x00002ca6, 0x00002ca6, 0x00002ca8, 0x00002ca8, - 0x00002caa, 0x00002caa, 0x00002cac, 0x00002cac, - 0x00002cae, 0x00002cae, 0x00002cb0, 0x00002cb0, - 0x00002cb2, 0x00002cb2, 0x00002cb4, 0x00002cb4, - 0x00002cb6, 0x00002cb6, 0x00002cb8, 0x00002cb8, - 0x00002cba, 0x00002cba, 0x00002cbc, 0x00002cbc, - 0x00002cbe, 0x00002cbe, 0x00002cc0, 0x00002cc0, - 0x00002cc2, 0x00002cc2, 0x00002cc4, 0x00002cc4, - 0x00002cc6, 0x00002cc6, 0x00002cc8, 0x00002cc8, - 0x00002cca, 0x00002cca, 0x00002ccc, 0x00002ccc, - 0x00002cce, 0x00002cce, 0x00002cd0, 0x00002cd0, - 0x00002cd2, 0x00002cd2, 0x00002cd4, 0x00002cd4, - 0x00002cd6, 0x00002cd6, 0x00002cd8, 0x00002cd8, - 0x00002cda, 0x00002cda, 0x00002cdc, 0x00002cdc, - 0x00002cde, 0x00002cde, 0x00002ce0, 0x00002ce0, - 0x00002ce2, 0x00002ce2, 0x00002ceb, 0x00002ceb, - 0x00002ced, 0x00002ced, 0x00002cf2, 0x00002cf2, - 0x0000a640, 0x0000a640, 0x0000a642, 0x0000a642, - 0x0000a644, 0x0000a644, 0x0000a646, 0x0000a646, - 0x0000a648, 0x0000a648, 0x0000a64a, 0x0000a64a, - 0x0000a64c, 0x0000a64c, 0x0000a64e, 0x0000a64e, - 0x0000a650, 0x0000a650, 0x0000a652, 0x0000a652, - 0x0000a654, 0x0000a654, 0x0000a656, 0x0000a656, - 0x0000a658, 0x0000a658, 0x0000a65a, 0x0000a65a, - 0x0000a65c, 0x0000a65c, 0x0000a65e, 0x0000a65e, - 0x0000a660, 0x0000a660, 0x0000a662, 0x0000a662, - 0x0000a664, 0x0000a664, 0x0000a666, 0x0000a666, - 0x0000a668, 0x0000a668, 0x0000a66a, 0x0000a66a, - 0x0000a66c, 0x0000a66c, 0x0000a680, 0x0000a680, - 0x0000a682, 0x0000a682, 0x0000a684, 0x0000a684, - 0x0000a686, 0x0000a686, 0x0000a688, 0x0000a688, - 0x0000a68a, 0x0000a68a, 0x0000a68c, 0x0000a68c, - 0x0000a68e, 0x0000a68e, 0x0000a690, 0x0000a690, - 0x0000a692, 0x0000a692, 0x0000a694, 0x0000a694, - 0x0000a696, 0x0000a696, 0x0000a698, 0x0000a698, - 0x0000a69a, 0x0000a69a, 0x0000a722, 0x0000a722, - 0x0000a724, 0x0000a724, 0x0000a726, 0x0000a726, - 0x0000a728, 0x0000a728, 0x0000a72a, 0x0000a72a, - 0x0000a72c, 0x0000a72c, 0x0000a72e, 0x0000a72e, - 0x0000a732, 0x0000a732, 0x0000a734, 0x0000a734, - 0x0000a736, 0x0000a736, 0x0000a738, 0x0000a738, - 0x0000a73a, 0x0000a73a, 0x0000a73c, 0x0000a73c, - 0x0000a73e, 0x0000a73e, 0x0000a740, 0x0000a740, - 0x0000a742, 0x0000a742, 0x0000a744, 0x0000a744, - 0x0000a746, 0x0000a746, 0x0000a748, 0x0000a748, - 0x0000a74a, 0x0000a74a, 0x0000a74c, 0x0000a74c, - 0x0000a74e, 0x0000a74e, 0x0000a750, 0x0000a750, - 0x0000a752, 0x0000a752, 0x0000a754, 0x0000a754, - 0x0000a756, 0x0000a756, 0x0000a758, 0x0000a758, - 0x0000a75a, 0x0000a75a, 0x0000a75c, 0x0000a75c, - 0x0000a75e, 0x0000a75e, 0x0000a760, 0x0000a760, - 0x0000a762, 0x0000a762, 0x0000a764, 0x0000a764, - 0x0000a766, 0x0000a766, 0x0000a768, 0x0000a768, - 0x0000a76a, 0x0000a76a, 0x0000a76c, 0x0000a76c, - 0x0000a76e, 0x0000a76e, 0x0000a779, 0x0000a779, - 0x0000a77b, 0x0000a77b, 0x0000a77d, 0x0000a77e, - 0x0000a780, 0x0000a780, 0x0000a782, 0x0000a782, - 0x0000a784, 0x0000a784, 0x0000a786, 0x0000a786, - 0x0000a78b, 0x0000a78b, 0x0000a78d, 0x0000a78d, - 0x0000a790, 0x0000a790, 0x0000a792, 0x0000a792, - 0x0000a796, 0x0000a796, 0x0000a798, 0x0000a798, - 0x0000a79a, 0x0000a79a, 0x0000a79c, 0x0000a79c, - 0x0000a79e, 0x0000a79e, 0x0000a7a0, 0x0000a7a0, - 0x0000a7a2, 0x0000a7a2, 0x0000a7a4, 0x0000a7a4, - 0x0000a7a6, 0x0000a7a6, 0x0000a7a8, 0x0000a7a8, - 0x0000a7aa, 0x0000a7ae, 0x0000a7b0, 0x0000a7b4, - 0x0000a7b6, 0x0000a7b6, 0x0000a7b8, 0x0000a7b8, - 0x0000a7ba, 0x0000a7ba, 0x0000a7bc, 0x0000a7bc, - 0x0000a7be, 0x0000a7be, 0x0000a7c0, 0x0000a7c0, - 0x0000a7c2, 0x0000a7c2, 0x0000a7c4, 0x0000a7c7, - 0x0000a7c9, 0x0000a7c9, 0x0000a7cb, 0x0000a7cc, - 0x0000a7d0, 0x0000a7d0, 0x0000a7d6, 0x0000a7d6, + 0x00012400, 0x0001246e, 0x00016ff4, 0x00016ff6, + 0x000000b2, 0x000000b3, 0x000000b9, 0x000000b9, + 0x000000bc, 0x000000be, 0x000009f4, 0x000009f9, + 0x00000b72, 0x00000b77, 0x00000bf0, 0x00000bf2, + 0x00000c78, 0x00000c7e, 0x00000d58, 0x00000d5e, + 0x00000d70, 0x00000d78, 0x00000f2a, 0x00000f33, + 0x00001369, 0x0000137c, 0x000017f0, 0x000017f9, + 0x000019da, 0x000019da, 0x00002070, 0x00002070, + 0x00002074, 0x00002079, 0x00002080, 0x00002089, + 0x00002150, 0x0000215f, 0x00002189, 0x00002189, + 0x00002460, 0x0000249b, 0x000024ea, 0x000024ff, + 0x00002776, 0x00002793, 0x00002cfd, 0x00002cfd, + 0x00003192, 0x00003195, 0x00003220, 0x00003229, + 0x00003248, 0x0000324f, 0x00003251, 0x0000325f, + 0x00003280, 0x00003289, 0x000032b1, 0x000032bf, + 0x0000a830, 0x0000a835, 0x00010107, 0x00010133, + 0x00010175, 0x00010178, 0x0001018a, 0x0001018b, + 0x000102e1, 0x000102fb, 0x00010320, 0x00010323, + 0x00010858, 0x0001085f, 0x00010879, 0x0001087f, + 0x000108a7, 0x000108af, 0x000108fb, 0x000108ff, + 0x00010916, 0x0001091b, 0x000109bc, 0x000109bd, + 0x000109c0, 0x000109cf, 0x000109d2, 0x000109ff, + 0x00010a40, 0x00010a48, 0x00010a7d, 0x00010a7e, + 0x00010a9d, 0x00010a9f, 0x00010aeb, 0x00010aef, + 0x00010b58, 0x00010b5f, 0x00010b78, 0x00010b7f, + 0x00010ba9, 0x00010baf, 0x00010cfa, 0x00010cff, + 0x00010e60, 0x00010e7e, 0x00010f1d, 0x00010f26, + 0x00010f51, 0x00010f54, 0x00010fc5, 0x00010fcb, + 0x00011052, 0x00011065, 0x000111e1, 0x000111f4, + 0x0001173a, 0x0001173b, 0x000118ea, 0x000118f2, + 0x00011c5a, 0x00011c6c, 0x00011fc0, 0x00011fd4, + 0x00016b5b, 0x00016b61, 0x00016e80, 0x00016e96, + 0x0001d2c0, 0x0001d2d3, 0x0001d2e0, 0x0001d2f3, + 0x0001d360, 0x0001d378, 0x0001e8c7, 0x0001e8cf, + 0x0001ec71, 0x0001ecab, 0x0001ecad, 0x0001ecaf, + 0x0001ecb1, 0x0001ecb4, 0x0001ed01, 0x0001ed2d, + 0x0001ed2f, 0x0001ed3d, 0x0001f100, 0x0001f10c, + 0x00000020, 0x00000020, 0x000000a0, 0x000000a0, + 0x00001680, 0x00001680, 0x00002000, 0x0000200a, + 0x0000202f, 0x0000202f, 0x0000205f, 0x0000205f, + 0x00003000, 0x00003000, 0x00002028, 0x00002028, + 0x00002029, 0x00002029, 0x0000d800, 0x0000dfff, + 0x0000e000, 0x0000f8ff, 0x000f0000, 0x000ffffd, + 0x00100000, 0x0010fffd, 0x00000041, 0x0000005a, + 0x000000c0, 0x000000d6, 0x000000d8, 0x000000de, + 0x00000100, 0x00000100, 0x00000102, 0x00000102, + 0x00000104, 0x00000104, 0x00000106, 0x00000106, + 0x00000108, 0x00000108, 0x0000010a, 0x0000010a, + 0x0000010c, 0x0000010c, 0x0000010e, 0x0000010e, + 0x00000110, 0x00000110, 0x00000112, 0x00000112, + 0x00000114, 0x00000114, 0x00000116, 0x00000116, + 0x00000118, 0x00000118, 0x0000011a, 0x0000011a, + 0x0000011c, 0x0000011c, 0x0000011e, 0x0000011e, + 0x00000120, 0x00000120, 0x00000122, 0x00000122, + 0x00000124, 0x00000124, 0x00000126, 0x00000126, + 0x00000128, 0x00000128, 0x0000012a, 0x0000012a, + 0x0000012c, 0x0000012c, 0x0000012e, 0x0000012e, + 0x00000130, 0x00000130, 0x00000132, 0x00000132, + 0x00000134, 0x00000134, 0x00000136, 0x00000136, + 0x00000139, 0x00000139, 0x0000013b, 0x0000013b, + 0x0000013d, 0x0000013d, 0x0000013f, 0x0000013f, + 0x00000141, 0x00000141, 0x00000143, 0x00000143, + 0x00000145, 0x00000145, 0x00000147, 0x00000147, + 0x0000014a, 0x0000014a, 0x0000014c, 0x0000014c, + 0x0000014e, 0x0000014e, 0x00000150, 0x00000150, + 0x00000152, 0x00000152, 0x00000154, 0x00000154, + 0x00000156, 0x00000156, 0x00000158, 0x00000158, + 0x0000015a, 0x0000015a, 0x0000015c, 0x0000015c, + 0x0000015e, 0x0000015e, 0x00000160, 0x00000160, + 0x00000162, 0x00000162, 0x00000164, 0x00000164, + 0x00000166, 0x00000166, 0x00000168, 0x00000168, + 0x0000016a, 0x0000016a, 0x0000016c, 0x0000016c, + 0x0000016e, 0x0000016e, 0x00000170, 0x00000170, + 0x00000172, 0x00000172, 0x00000174, 0x00000174, + 0x00000176, 0x00000176, 0x00000178, 0x00000179, + 0x0000017b, 0x0000017b, 0x0000017d, 0x0000017d, + 0x00000181, 0x00000182, 0x00000184, 0x00000184, + 0x00000186, 0x00000187, 0x00000189, 0x0000018b, + 0x0000018e, 0x00000191, 0x00000193, 0x00000194, + 0x00000196, 0x00000198, 0x0000019c, 0x0000019d, + 0x0000019f, 0x000001a0, 0x000001a2, 0x000001a2, + 0x000001a4, 0x000001a4, 0x000001a6, 0x000001a7, + 0x000001a9, 0x000001a9, 0x000001ac, 0x000001ac, + 0x000001ae, 0x000001af, 0x000001b1, 0x000001b3, + 0x000001b5, 0x000001b5, 0x000001b7, 0x000001b8, + 0x000001bc, 0x000001bc, 0x000001c4, 0x000001c4, + 0x000001c7, 0x000001c7, 0x000001ca, 0x000001ca, + 0x000001cd, 0x000001cd, 0x000001cf, 0x000001cf, + 0x000001d1, 0x000001d1, 0x000001d3, 0x000001d3, + 0x000001d5, 0x000001d5, 0x000001d7, 0x000001d7, + 0x000001d9, 0x000001d9, 0x000001db, 0x000001db, + 0x000001de, 0x000001de, 0x000001e0, 0x000001e0, + 0x000001e2, 0x000001e2, 0x000001e4, 0x000001e4, + 0x000001e6, 0x000001e6, 0x000001e8, 0x000001e8, + 0x000001ea, 0x000001ea, 0x000001ec, 0x000001ec, + 0x000001ee, 0x000001ee, 0x000001f1, 0x000001f1, + 0x000001f4, 0x000001f4, 0x000001f6, 0x000001f8, + 0x000001fa, 0x000001fa, 0x000001fc, 0x000001fc, + 0x000001fe, 0x000001fe, 0x00000200, 0x00000200, + 0x00000202, 0x00000202, 0x00000204, 0x00000204, + 0x00000206, 0x00000206, 0x00000208, 0x00000208, + 0x0000020a, 0x0000020a, 0x0000020c, 0x0000020c, + 0x0000020e, 0x0000020e, 0x00000210, 0x00000210, + 0x00000212, 0x00000212, 0x00000214, 0x00000214, + 0x00000216, 0x00000216, 0x00000218, 0x00000218, + 0x0000021a, 0x0000021a, 0x0000021c, 0x0000021c, + 0x0000021e, 0x0000021e, 0x00000220, 0x00000220, + 0x00000222, 0x00000222, 0x00000224, 0x00000224, + 0x00000226, 0x00000226, 0x00000228, 0x00000228, + 0x0000022a, 0x0000022a, 0x0000022c, 0x0000022c, + 0x0000022e, 0x0000022e, 0x00000230, 0x00000230, + 0x00000232, 0x00000232, 0x0000023a, 0x0000023b, + 0x0000023d, 0x0000023e, 0x00000241, 0x00000241, + 0x00000243, 0x00000246, 0x00000248, 0x00000248, + 0x0000024a, 0x0000024a, 0x0000024c, 0x0000024c, + 0x0000024e, 0x0000024e, 0x00000370, 0x00000370, + 0x00000372, 0x00000372, 0x00000376, 0x00000376, + 0x0000037f, 0x0000037f, 0x00000386, 0x00000386, + 0x00000388, 0x0000038a, 0x0000038c, 0x0000038c, + 0x0000038e, 0x0000038f, 0x00000391, 0x000003a1, + 0x000003a3, 0x000003ab, 0x000003cf, 0x000003cf, + 0x000003d2, 0x000003d4, 0x000003d8, 0x000003d8, + 0x000003da, 0x000003da, 0x000003dc, 0x000003dc, + 0x000003de, 0x000003de, 0x000003e0, 0x000003e0, + 0x000003e2, 0x000003e2, 0x000003e4, 0x000003e4, + 0x000003e6, 0x000003e6, 0x000003e8, 0x000003e8, + 0x000003ea, 0x000003ea, 0x000003ec, 0x000003ec, + 0x000003ee, 0x000003ee, 0x000003f4, 0x000003f4, + 0x000003f7, 0x000003f7, 0x000003f9, 0x000003fa, + 0x000003fd, 0x0000042f, 0x00000460, 0x00000460, + 0x00000462, 0x00000462, 0x00000464, 0x00000464, + 0x00000466, 0x00000466, 0x00000468, 0x00000468, + 0x0000046a, 0x0000046a, 0x0000046c, 0x0000046c, + 0x0000046e, 0x0000046e, 0x00000470, 0x00000470, + 0x00000472, 0x00000472, 0x00000474, 0x00000474, + 0x00000476, 0x00000476, 0x00000478, 0x00000478, + 0x0000047a, 0x0000047a, 0x0000047c, 0x0000047c, + 0x0000047e, 0x0000047e, 0x00000480, 0x00000480, + 0x0000048a, 0x0000048a, 0x0000048c, 0x0000048c, + 0x0000048e, 0x0000048e, 0x00000490, 0x00000490, + 0x00000492, 0x00000492, 0x00000494, 0x00000494, + 0x00000496, 0x00000496, 0x00000498, 0x00000498, + 0x0000049a, 0x0000049a, 0x0000049c, 0x0000049c, + 0x0000049e, 0x0000049e, 0x000004a0, 0x000004a0, + 0x000004a2, 0x000004a2, 0x000004a4, 0x000004a4, + 0x000004a6, 0x000004a6, 0x000004a8, 0x000004a8, + 0x000004aa, 0x000004aa, 0x000004ac, 0x000004ac, + 0x000004ae, 0x000004ae, 0x000004b0, 0x000004b0, + 0x000004b2, 0x000004b2, 0x000004b4, 0x000004b4, + 0x000004b6, 0x000004b6, 0x000004b8, 0x000004b8, + 0x000004ba, 0x000004ba, 0x000004bc, 0x000004bc, + 0x000004be, 0x000004be, 0x000004c0, 0x000004c1, + 0x000004c3, 0x000004c3, 0x000004c5, 0x000004c5, + 0x000004c7, 0x000004c7, 0x000004c9, 0x000004c9, + 0x000004cb, 0x000004cb, 0x000004cd, 0x000004cd, + 0x000004d0, 0x000004d0, 0x000004d2, 0x000004d2, + 0x000004d4, 0x000004d4, 0x000004d6, 0x000004d6, + 0x000004d8, 0x000004d8, 0x000004da, 0x000004da, + 0x000004dc, 0x000004dc, 0x000004de, 0x000004de, + 0x000004e0, 0x000004e0, 0x000004e2, 0x000004e2, + 0x000004e4, 0x000004e4, 0x000004e6, 0x000004e6, + 0x000004e8, 0x000004e8, 0x000004ea, 0x000004ea, + 0x000004ec, 0x000004ec, 0x000004ee, 0x000004ee, + 0x000004f0, 0x000004f0, 0x000004f2, 0x000004f2, + 0x000004f4, 0x000004f4, 0x000004f6, 0x000004f6, + 0x000004f8, 0x000004f8, 0x000004fa, 0x000004fa, + 0x000004fc, 0x000004fc, 0x000004fe, 0x000004fe, + 0x00000500, 0x00000500, 0x00000502, 0x00000502, + 0x00000504, 0x00000504, 0x00000506, 0x00000506, + 0x00000508, 0x00000508, 0x0000050a, 0x0000050a, + 0x0000050c, 0x0000050c, 0x0000050e, 0x0000050e, + 0x00000510, 0x00000510, 0x00000512, 0x00000512, + 0x00000514, 0x00000514, 0x00000516, 0x00000516, + 0x00000518, 0x00000518, 0x0000051a, 0x0000051a, + 0x0000051c, 0x0000051c, 0x0000051e, 0x0000051e, + 0x00000520, 0x00000520, 0x00000522, 0x00000522, + 0x00000524, 0x00000524, 0x00000526, 0x00000526, + 0x00000528, 0x00000528, 0x0000052a, 0x0000052a, + 0x0000052c, 0x0000052c, 0x0000052e, 0x0000052e, + 0x00000531, 0x00000556, 0x000010a0, 0x000010c5, + 0x000010c7, 0x000010c7, 0x000010cd, 0x000010cd, + 0x000013a0, 0x000013f5, 0x00001c89, 0x00001c89, + 0x00001c90, 0x00001cba, 0x00001cbd, 0x00001cbf, + 0x00001e00, 0x00001e00, 0x00001e02, 0x00001e02, + 0x00001e04, 0x00001e04, 0x00001e06, 0x00001e06, + 0x00001e08, 0x00001e08, 0x00001e0a, 0x00001e0a, + 0x00001e0c, 0x00001e0c, 0x00001e0e, 0x00001e0e, + 0x00001e10, 0x00001e10, 0x00001e12, 0x00001e12, + 0x00001e14, 0x00001e14, 0x00001e16, 0x00001e16, + 0x00001e18, 0x00001e18, 0x00001e1a, 0x00001e1a, + 0x00001e1c, 0x00001e1c, 0x00001e1e, 0x00001e1e, + 0x00001e20, 0x00001e20, 0x00001e22, 0x00001e22, + 0x00001e24, 0x00001e24, 0x00001e26, 0x00001e26, + 0x00001e28, 0x00001e28, 0x00001e2a, 0x00001e2a, + 0x00001e2c, 0x00001e2c, 0x00001e2e, 0x00001e2e, + 0x00001e30, 0x00001e30, 0x00001e32, 0x00001e32, + 0x00001e34, 0x00001e34, 0x00001e36, 0x00001e36, + 0x00001e38, 0x00001e38, 0x00001e3a, 0x00001e3a, + 0x00001e3c, 0x00001e3c, 0x00001e3e, 0x00001e3e, + 0x00001e40, 0x00001e40, 0x00001e42, 0x00001e42, + 0x00001e44, 0x00001e44, 0x00001e46, 0x00001e46, + 0x00001e48, 0x00001e48, 0x00001e4a, 0x00001e4a, + 0x00001e4c, 0x00001e4c, 0x00001e4e, 0x00001e4e, + 0x00001e50, 0x00001e50, 0x00001e52, 0x00001e52, + 0x00001e54, 0x00001e54, 0x00001e56, 0x00001e56, + 0x00001e58, 0x00001e58, 0x00001e5a, 0x00001e5a, + 0x00001e5c, 0x00001e5c, 0x00001e5e, 0x00001e5e, + 0x00001e60, 0x00001e60, 0x00001e62, 0x00001e62, + 0x00001e64, 0x00001e64, 0x00001e66, 0x00001e66, + 0x00001e68, 0x00001e68, 0x00001e6a, 0x00001e6a, + 0x00001e6c, 0x00001e6c, 0x00001e6e, 0x00001e6e, + 0x00001e70, 0x00001e70, 0x00001e72, 0x00001e72, + 0x00001e74, 0x00001e74, 0x00001e76, 0x00001e76, + 0x00001e78, 0x00001e78, 0x00001e7a, 0x00001e7a, + 0x00001e7c, 0x00001e7c, 0x00001e7e, 0x00001e7e, + 0x00001e80, 0x00001e80, 0x00001e82, 0x00001e82, + 0x00001e84, 0x00001e84, 0x00001e86, 0x00001e86, + 0x00001e88, 0x00001e88, 0x00001e8a, 0x00001e8a, + 0x00001e8c, 0x00001e8c, 0x00001e8e, 0x00001e8e, + 0x00001e90, 0x00001e90, 0x00001e92, 0x00001e92, + 0x00001e94, 0x00001e94, 0x00001e9e, 0x00001e9e, + 0x00001ea0, 0x00001ea0, 0x00001ea2, 0x00001ea2, + 0x00001ea4, 0x00001ea4, 0x00001ea6, 0x00001ea6, + 0x00001ea8, 0x00001ea8, 0x00001eaa, 0x00001eaa, + 0x00001eac, 0x00001eac, 0x00001eae, 0x00001eae, + 0x00001eb0, 0x00001eb0, 0x00001eb2, 0x00001eb2, + 0x00001eb4, 0x00001eb4, 0x00001eb6, 0x00001eb6, + 0x00001eb8, 0x00001eb8, 0x00001eba, 0x00001eba, + 0x00001ebc, 0x00001ebc, 0x00001ebe, 0x00001ebe, + 0x00001ec0, 0x00001ec0, 0x00001ec2, 0x00001ec2, + 0x00001ec4, 0x00001ec4, 0x00001ec6, 0x00001ec6, + 0x00001ec8, 0x00001ec8, 0x00001eca, 0x00001eca, + 0x00001ecc, 0x00001ecc, 0x00001ece, 0x00001ece, + 0x00001ed0, 0x00001ed0, 0x00001ed2, 0x00001ed2, + 0x00001ed4, 0x00001ed4, 0x00001ed6, 0x00001ed6, + 0x00001ed8, 0x00001ed8, 0x00001eda, 0x00001eda, + 0x00001edc, 0x00001edc, 0x00001ede, 0x00001ede, + 0x00001ee0, 0x00001ee0, 0x00001ee2, 0x00001ee2, + 0x00001ee4, 0x00001ee4, 0x00001ee6, 0x00001ee6, + 0x00001ee8, 0x00001ee8, 0x00001eea, 0x00001eea, + 0x00001eec, 0x00001eec, 0x00001eee, 0x00001eee, + 0x00001ef0, 0x00001ef0, 0x00001ef2, 0x00001ef2, + 0x00001ef4, 0x00001ef4, 0x00001ef6, 0x00001ef6, + 0x00001ef8, 0x00001ef8, 0x00001efa, 0x00001efa, + 0x00001efc, 0x00001efc, 0x00001efe, 0x00001efe, + 0x00001f08, 0x00001f0f, 0x00001f18, 0x00001f1d, + 0x00001f28, 0x00001f2f, 0x00001f38, 0x00001f3f, + 0x00001f48, 0x00001f4d, 0x00001f59, 0x00001f59, + 0x00001f5b, 0x00001f5b, 0x00001f5d, 0x00001f5d, + 0x00001f5f, 0x00001f5f, 0x00001f68, 0x00001f6f, + 0x00001fb8, 0x00001fbb, 0x00001fc8, 0x00001fcb, + 0x00001fd8, 0x00001fdb, 0x00001fe8, 0x00001fec, + 0x00001ff8, 0x00001ffb, 0x00002102, 0x00002102, + 0x00002107, 0x00002107, 0x0000210b, 0x0000210d, + 0x00002110, 0x00002112, 0x00002115, 0x00002115, + 0x00002119, 0x0000211d, 0x00002124, 0x00002124, + 0x00002126, 0x00002126, 0x00002128, 0x00002128, + 0x0000212a, 0x0000212d, 0x00002130, 0x00002133, + 0x0000213e, 0x0000213f, 0x00002145, 0x00002145, + 0x00002183, 0x00002183, 0x00002c00, 0x00002c2f, + 0x00002c60, 0x00002c60, 0x00002c62, 0x00002c64, + 0x00002c67, 0x00002c67, 0x00002c69, 0x00002c69, + 0x00002c6b, 0x00002c6b, 0x00002c6d, 0x00002c70, + 0x00002c72, 0x00002c72, 0x00002c75, 0x00002c75, + 0x00002c7e, 0x00002c80, 0x00002c82, 0x00002c82, + 0x00002c84, 0x00002c84, 0x00002c86, 0x00002c86, + 0x00002c88, 0x00002c88, 0x00002c8a, 0x00002c8a, + 0x00002c8c, 0x00002c8c, 0x00002c8e, 0x00002c8e, + 0x00002c90, 0x00002c90, 0x00002c92, 0x00002c92, + 0x00002c94, 0x00002c94, 0x00002c96, 0x00002c96, + 0x00002c98, 0x00002c98, 0x00002c9a, 0x00002c9a, + 0x00002c9c, 0x00002c9c, 0x00002c9e, 0x00002c9e, + 0x00002ca0, 0x00002ca0, 0x00002ca2, 0x00002ca2, + 0x00002ca4, 0x00002ca4, 0x00002ca6, 0x00002ca6, + 0x00002ca8, 0x00002ca8, 0x00002caa, 0x00002caa, + 0x00002cac, 0x00002cac, 0x00002cae, 0x00002cae, + 0x00002cb0, 0x00002cb0, 0x00002cb2, 0x00002cb2, + 0x00002cb4, 0x00002cb4, 0x00002cb6, 0x00002cb6, + 0x00002cb8, 0x00002cb8, 0x00002cba, 0x00002cba, + 0x00002cbc, 0x00002cbc, 0x00002cbe, 0x00002cbe, + 0x00002cc0, 0x00002cc0, 0x00002cc2, 0x00002cc2, + 0x00002cc4, 0x00002cc4, 0x00002cc6, 0x00002cc6, + 0x00002cc8, 0x00002cc8, 0x00002cca, 0x00002cca, + 0x00002ccc, 0x00002ccc, 0x00002cce, 0x00002cce, + 0x00002cd0, 0x00002cd0, 0x00002cd2, 0x00002cd2, + 0x00002cd4, 0x00002cd4, 0x00002cd6, 0x00002cd6, + 0x00002cd8, 0x00002cd8, 0x00002cda, 0x00002cda, + 0x00002cdc, 0x00002cdc, 0x00002cde, 0x00002cde, + 0x00002ce0, 0x00002ce0, 0x00002ce2, 0x00002ce2, + 0x00002ceb, 0x00002ceb, 0x00002ced, 0x00002ced, + 0x00002cf2, 0x00002cf2, 0x0000a640, 0x0000a640, + 0x0000a642, 0x0000a642, 0x0000a644, 0x0000a644, + 0x0000a646, 0x0000a646, 0x0000a648, 0x0000a648, + 0x0000a64a, 0x0000a64a, 0x0000a64c, 0x0000a64c, + 0x0000a64e, 0x0000a64e, 0x0000a650, 0x0000a650, + 0x0000a652, 0x0000a652, 0x0000a654, 0x0000a654, + 0x0000a656, 0x0000a656, 0x0000a658, 0x0000a658, + 0x0000a65a, 0x0000a65a, 0x0000a65c, 0x0000a65c, + 0x0000a65e, 0x0000a65e, 0x0000a660, 0x0000a660, + 0x0000a662, 0x0000a662, 0x0000a664, 0x0000a664, + 0x0000a666, 0x0000a666, 0x0000a668, 0x0000a668, + 0x0000a66a, 0x0000a66a, 0x0000a66c, 0x0000a66c, + 0x0000a680, 0x0000a680, 0x0000a682, 0x0000a682, + 0x0000a684, 0x0000a684, 0x0000a686, 0x0000a686, + 0x0000a688, 0x0000a688, 0x0000a68a, 0x0000a68a, + 0x0000a68c, 0x0000a68c, 0x0000a68e, 0x0000a68e, + 0x0000a690, 0x0000a690, 0x0000a692, 0x0000a692, + 0x0000a694, 0x0000a694, 0x0000a696, 0x0000a696, + 0x0000a698, 0x0000a698, 0x0000a69a, 0x0000a69a, + 0x0000a722, 0x0000a722, 0x0000a724, 0x0000a724, + 0x0000a726, 0x0000a726, 0x0000a728, 0x0000a728, + 0x0000a72a, 0x0000a72a, 0x0000a72c, 0x0000a72c, + 0x0000a72e, 0x0000a72e, 0x0000a732, 0x0000a732, + 0x0000a734, 0x0000a734, 0x0000a736, 0x0000a736, + 0x0000a738, 0x0000a738, 0x0000a73a, 0x0000a73a, + 0x0000a73c, 0x0000a73c, 0x0000a73e, 0x0000a73e, + 0x0000a740, 0x0000a740, 0x0000a742, 0x0000a742, + 0x0000a744, 0x0000a744, 0x0000a746, 0x0000a746, + 0x0000a748, 0x0000a748, 0x0000a74a, 0x0000a74a, + 0x0000a74c, 0x0000a74c, 0x0000a74e, 0x0000a74e, + 0x0000a750, 0x0000a750, 0x0000a752, 0x0000a752, + 0x0000a754, 0x0000a754, 0x0000a756, 0x0000a756, + 0x0000a758, 0x0000a758, 0x0000a75a, 0x0000a75a, + 0x0000a75c, 0x0000a75c, 0x0000a75e, 0x0000a75e, + 0x0000a760, 0x0000a760, 0x0000a762, 0x0000a762, + 0x0000a764, 0x0000a764, 0x0000a766, 0x0000a766, + 0x0000a768, 0x0000a768, 0x0000a76a, 0x0000a76a, + 0x0000a76c, 0x0000a76c, 0x0000a76e, 0x0000a76e, + 0x0000a779, 0x0000a779, 0x0000a77b, 0x0000a77b, + 0x0000a77d, 0x0000a77e, 0x0000a780, 0x0000a780, + 0x0000a782, 0x0000a782, 0x0000a784, 0x0000a784, + 0x0000a786, 0x0000a786, 0x0000a78b, 0x0000a78b, + 0x0000a78d, 0x0000a78d, 0x0000a790, 0x0000a790, + 0x0000a792, 0x0000a792, 0x0000a796, 0x0000a796, + 0x0000a798, 0x0000a798, 0x0000a79a, 0x0000a79a, + 0x0000a79c, 0x0000a79c, 0x0000a79e, 0x0000a79e, + 0x0000a7a0, 0x0000a7a0, 0x0000a7a2, 0x0000a7a2, + 0x0000a7a4, 0x0000a7a4, 0x0000a7a6, 0x0000a7a6, + 0x0000a7a8, 0x0000a7a8, 0x0000a7aa, 0x0000a7ae, + 0x0000a7b0, 0x0000a7b4, 0x0000a7b6, 0x0000a7b6, + 0x0000a7b8, 0x0000a7b8, 0x0000a7ba, 0x0000a7ba, + 0x0000a7bc, 0x0000a7bc, 0x0000a7be, 0x0000a7be, + 0x0000a7c0, 0x0000a7c0, 0x0000a7c2, 0x0000a7c2, + 0x0000a7c4, 0x0000a7c7, 0x0000a7c9, 0x0000a7c9, + 0x0000a7cb, 0x0000a7cc, 0x0000a7ce, 0x0000a7ce, + 0x0000a7d0, 0x0000a7d0, 0x0000a7d2, 0x0000a7d2, + 0x0000a7d4, 0x0000a7d4, 0x0000a7d6, 0x0000a7d6, 0x0000a7d8, 0x0000a7d8, 0x0000a7da, 0x0000a7da, 0x0000a7dc, 0x0000a7dc, 0x0000a7f5, 0x0000a7f5, 0x0000ff21, 0x0000ff3a, 0x00010400, 0x00010427, @@ -690,326 +698,327 @@ static const unsigned int _ucprop_ranges[] = { 0x0001057c, 0x0001058a, 0x0001058c, 0x00010592, 0x00010594, 0x00010595, 0x00010c80, 0x00010cb2, 0x00010d50, 0x00010d65, 0x000118a0, 0x000118bf, - 0x00016e40, 0x00016e5f, 0x0001d400, 0x0001d419, - 0x0001d434, 0x0001d44d, 0x0001d468, 0x0001d481, - 0x0001d49c, 0x0001d49c, 0x0001d49e, 0x0001d49f, - 0x0001d4a2, 0x0001d4a2, 0x0001d4a5, 0x0001d4a6, - 0x0001d4a9, 0x0001d4ac, 0x0001d4ae, 0x0001d4b5, - 0x0001d4d0, 0x0001d4e9, 0x0001d504, 0x0001d505, - 0x0001d507, 0x0001d50a, 0x0001d50d, 0x0001d514, - 0x0001d516, 0x0001d51c, 0x0001d538, 0x0001d539, - 0x0001d53b, 0x0001d53e, 0x0001d540, 0x0001d544, - 0x0001d546, 0x0001d546, 0x0001d54a, 0x0001d550, - 0x0001d56c, 0x0001d585, 0x0001d5a0, 0x0001d5b9, - 0x0001d5d4, 0x0001d5ed, 0x0001d608, 0x0001d621, - 0x0001d63c, 0x0001d655, 0x0001d670, 0x0001d689, - 0x0001d6a8, 0x0001d6c0, 0x0001d6e2, 0x0001d6fa, - 0x0001d71c, 0x0001d734, 0x0001d756, 0x0001d76e, - 0x0001d790, 0x0001d7a8, 0x0001d7ca, 0x0001d7ca, - 0x0001e900, 0x0001e921, 0x00000061, 0x0000007a, - 0x000000b5, 0x000000b5, 0x000000df, 0x000000f6, - 0x000000f8, 0x000000ff, 0x00000101, 0x00000101, - 0x00000103, 0x00000103, 0x00000105, 0x00000105, - 0x00000107, 0x00000107, 0x00000109, 0x00000109, - 0x0000010b, 0x0000010b, 0x0000010d, 0x0000010d, - 0x0000010f, 0x0000010f, 0x00000111, 0x00000111, - 0x00000113, 0x00000113, 0x00000115, 0x00000115, - 0x00000117, 0x00000117, 0x00000119, 0x00000119, - 0x0000011b, 0x0000011b, 0x0000011d, 0x0000011d, - 0x0000011f, 0x0000011f, 0x00000121, 0x00000121, - 0x00000123, 0x00000123, 0x00000125, 0x00000125, - 0x00000127, 0x00000127, 0x00000129, 0x00000129, - 0x0000012b, 0x0000012b, 0x0000012d, 0x0000012d, - 0x0000012f, 0x0000012f, 0x00000131, 0x00000131, - 0x00000133, 0x00000133, 0x00000135, 0x00000135, - 0x00000137, 0x00000138, 0x0000013a, 0x0000013a, - 0x0000013c, 0x0000013c, 0x0000013e, 0x0000013e, - 0x00000140, 0x00000140, 0x00000142, 0x00000142, - 0x00000144, 0x00000144, 0x00000146, 0x00000146, - 0x00000148, 0x00000149, 0x0000014b, 0x0000014b, - 0x0000014d, 0x0000014d, 0x0000014f, 0x0000014f, - 0x00000151, 0x00000151, 0x00000153, 0x00000153, - 0x00000155, 0x00000155, 0x00000157, 0x00000157, - 0x00000159, 0x00000159, 0x0000015b, 0x0000015b, - 0x0000015d, 0x0000015d, 0x0000015f, 0x0000015f, - 0x00000161, 0x00000161, 0x00000163, 0x00000163, - 0x00000165, 0x00000165, 0x00000167, 0x00000167, - 0x00000169, 0x00000169, 0x0000016b, 0x0000016b, - 0x0000016d, 0x0000016d, 0x0000016f, 0x0000016f, - 0x00000171, 0x00000171, 0x00000173, 0x00000173, - 0x00000175, 0x00000175, 0x00000177, 0x00000177, - 0x0000017a, 0x0000017a, 0x0000017c, 0x0000017c, - 0x0000017e, 0x00000180, 0x00000183, 0x00000183, - 0x00000185, 0x00000185, 0x00000188, 0x00000188, - 0x0000018c, 0x0000018d, 0x00000192, 0x00000192, - 0x00000195, 0x00000195, 0x00000199, 0x0000019b, - 0x0000019e, 0x0000019e, 0x000001a1, 0x000001a1, - 0x000001a3, 0x000001a3, 0x000001a5, 0x000001a5, - 0x000001a8, 0x000001a8, 0x000001aa, 0x000001ab, - 0x000001ad, 0x000001ad, 0x000001b0, 0x000001b0, - 0x000001b4, 0x000001b4, 0x000001b6, 0x000001b6, - 0x000001b9, 0x000001ba, 0x000001bd, 0x000001bf, - 0x000001c6, 0x000001c6, 0x000001c9, 0x000001c9, - 0x000001cc, 0x000001cc, 0x000001ce, 0x000001ce, - 0x000001d0, 0x000001d0, 0x000001d2, 0x000001d2, - 0x000001d4, 0x000001d4, 0x000001d6, 0x000001d6, - 0x000001d8, 0x000001d8, 0x000001da, 0x000001da, - 0x000001dc, 0x000001dd, 0x000001df, 0x000001df, - 0x000001e1, 0x000001e1, 0x000001e3, 0x000001e3, - 0x000001e5, 0x000001e5, 0x000001e7, 0x000001e7, - 0x000001e9, 0x000001e9, 0x000001eb, 0x000001eb, - 0x000001ed, 0x000001ed, 0x000001ef, 0x000001f0, - 0x000001f3, 0x000001f3, 0x000001f5, 0x000001f5, - 0x000001f9, 0x000001f9, 0x000001fb, 0x000001fb, - 0x000001fd, 0x000001fd, 0x000001ff, 0x000001ff, - 0x00000201, 0x00000201, 0x00000203, 0x00000203, - 0x00000205, 0x00000205, 0x00000207, 0x00000207, - 0x00000209, 0x00000209, 0x0000020b, 0x0000020b, - 0x0000020d, 0x0000020d, 0x0000020f, 0x0000020f, - 0x00000211, 0x00000211, 0x00000213, 0x00000213, - 0x00000215, 0x00000215, 0x00000217, 0x00000217, - 0x00000219, 0x00000219, 0x0000021b, 0x0000021b, - 0x0000021d, 0x0000021d, 0x0000021f, 0x0000021f, - 0x00000221, 0x00000221, 0x00000223, 0x00000223, - 0x00000225, 0x00000225, 0x00000227, 0x00000227, - 0x00000229, 0x00000229, 0x0000022b, 0x0000022b, - 0x0000022d, 0x0000022d, 0x0000022f, 0x0000022f, - 0x00000231, 0x00000231, 0x00000233, 0x00000239, - 0x0000023c, 0x0000023c, 0x0000023f, 0x00000240, - 0x00000242, 0x00000242, 0x00000247, 0x00000247, - 0x00000249, 0x00000249, 0x0000024b, 0x0000024b, - 0x0000024d, 0x0000024d, 0x0000024f, 0x00000293, - 0x00000295, 0x000002af, 0x00000371, 0x00000371, - 0x00000373, 0x00000373, 0x00000377, 0x00000377, - 0x0000037b, 0x0000037d, 0x00000390, 0x00000390, - 0x000003ac, 0x000003ce, 0x000003d0, 0x000003d1, - 0x000003d5, 0x000003d7, 0x000003d9, 0x000003d9, - 0x000003db, 0x000003db, 0x000003dd, 0x000003dd, - 0x000003df, 0x000003df, 0x000003e1, 0x000003e1, - 0x000003e3, 0x000003e3, 0x000003e5, 0x000003e5, - 0x000003e7, 0x000003e7, 0x000003e9, 0x000003e9, - 0x000003eb, 0x000003eb, 0x000003ed, 0x000003ed, - 0x000003ef, 0x000003f3, 0x000003f5, 0x000003f5, - 0x000003f8, 0x000003f8, 0x000003fb, 0x000003fc, - 0x00000430, 0x0000045f, 0x00000461, 0x00000461, - 0x00000463, 0x00000463, 0x00000465, 0x00000465, - 0x00000467, 0x00000467, 0x00000469, 0x00000469, - 0x0000046b, 0x0000046b, 0x0000046d, 0x0000046d, - 0x0000046f, 0x0000046f, 0x00000471, 0x00000471, - 0x00000473, 0x00000473, 0x00000475, 0x00000475, - 0x00000477, 0x00000477, 0x00000479, 0x00000479, - 0x0000047b, 0x0000047b, 0x0000047d, 0x0000047d, - 0x0000047f, 0x0000047f, 0x00000481, 0x00000481, - 0x0000048b, 0x0000048b, 0x0000048d, 0x0000048d, - 0x0000048f, 0x0000048f, 0x00000491, 0x00000491, - 0x00000493, 0x00000493, 0x00000495, 0x00000495, - 0x00000497, 0x00000497, 0x00000499, 0x00000499, - 0x0000049b, 0x0000049b, 0x0000049d, 0x0000049d, - 0x0000049f, 0x0000049f, 0x000004a1, 0x000004a1, - 0x000004a3, 0x000004a3, 0x000004a5, 0x000004a5, - 0x000004a7, 0x000004a7, 0x000004a9, 0x000004a9, - 0x000004ab, 0x000004ab, 0x000004ad, 0x000004ad, - 0x000004af, 0x000004af, 0x000004b1, 0x000004b1, - 0x000004b3, 0x000004b3, 0x000004b5, 0x000004b5, - 0x000004b7, 0x000004b7, 0x000004b9, 0x000004b9, - 0x000004bb, 0x000004bb, 0x000004bd, 0x000004bd, - 0x000004bf, 0x000004bf, 0x000004c2, 0x000004c2, - 0x000004c4, 0x000004c4, 0x000004c6, 0x000004c6, - 0x000004c8, 0x000004c8, 0x000004ca, 0x000004ca, - 0x000004cc, 0x000004cc, 0x000004ce, 0x000004cf, - 0x000004d1, 0x000004d1, 0x000004d3, 0x000004d3, - 0x000004d5, 0x000004d5, 0x000004d7, 0x000004d7, - 0x000004d9, 0x000004d9, 0x000004db, 0x000004db, - 0x000004dd, 0x000004dd, 0x000004df, 0x000004df, - 0x000004e1, 0x000004e1, 0x000004e3, 0x000004e3, - 0x000004e5, 0x000004e5, 0x000004e7, 0x000004e7, - 0x000004e9, 0x000004e9, 0x000004eb, 0x000004eb, - 0x000004ed, 0x000004ed, 0x000004ef, 0x000004ef, - 0x000004f1, 0x000004f1, 0x000004f3, 0x000004f3, - 0x000004f5, 0x000004f5, 0x000004f7, 0x000004f7, - 0x000004f9, 0x000004f9, 0x000004fb, 0x000004fb, - 0x000004fd, 0x000004fd, 0x000004ff, 0x000004ff, - 0x00000501, 0x00000501, 0x00000503, 0x00000503, - 0x00000505, 0x00000505, 0x00000507, 0x00000507, - 0x00000509, 0x00000509, 0x0000050b, 0x0000050b, - 0x0000050d, 0x0000050d, 0x0000050f, 0x0000050f, - 0x00000511, 0x00000511, 0x00000513, 0x00000513, - 0x00000515, 0x00000515, 0x00000517, 0x00000517, - 0x00000519, 0x00000519, 0x0000051b, 0x0000051b, - 0x0000051d, 0x0000051d, 0x0000051f, 0x0000051f, - 0x00000521, 0x00000521, 0x00000523, 0x00000523, - 0x00000525, 0x00000525, 0x00000527, 0x00000527, - 0x00000529, 0x00000529, 0x0000052b, 0x0000052b, - 0x0000052d, 0x0000052d, 0x0000052f, 0x0000052f, - 0x00000560, 0x00000588, 0x000010d0, 0x000010fa, - 0x000010fd, 0x000010ff, 0x000013f8, 0x000013fd, - 0x00001c80, 0x00001c88, 0x00001c8a, 0x00001c8a, - 0x00001d00, 0x00001d2b, 0x00001d6b, 0x00001d77, - 0x00001d79, 0x00001d9a, 0x00001e01, 0x00001e01, - 0x00001e03, 0x00001e03, 0x00001e05, 0x00001e05, - 0x00001e07, 0x00001e07, 0x00001e09, 0x00001e09, - 0x00001e0b, 0x00001e0b, 0x00001e0d, 0x00001e0d, - 0x00001e0f, 0x00001e0f, 0x00001e11, 0x00001e11, - 0x00001e13, 0x00001e13, 0x00001e15, 0x00001e15, - 0x00001e17, 0x00001e17, 0x00001e19, 0x00001e19, - 0x00001e1b, 0x00001e1b, 0x00001e1d, 0x00001e1d, - 0x00001e1f, 0x00001e1f, 0x00001e21, 0x00001e21, - 0x00001e23, 0x00001e23, 0x00001e25, 0x00001e25, - 0x00001e27, 0x00001e27, 0x00001e29, 0x00001e29, - 0x00001e2b, 0x00001e2b, 0x00001e2d, 0x00001e2d, - 0x00001e2f, 0x00001e2f, 0x00001e31, 0x00001e31, - 0x00001e33, 0x00001e33, 0x00001e35, 0x00001e35, - 0x00001e37, 0x00001e37, 0x00001e39, 0x00001e39, - 0x00001e3b, 0x00001e3b, 0x00001e3d, 0x00001e3d, - 0x00001e3f, 0x00001e3f, 0x00001e41, 0x00001e41, - 0x00001e43, 0x00001e43, 0x00001e45, 0x00001e45, - 0x00001e47, 0x00001e47, 0x00001e49, 0x00001e49, - 0x00001e4b, 0x00001e4b, 0x00001e4d, 0x00001e4d, - 0x00001e4f, 0x00001e4f, 0x00001e51, 0x00001e51, - 0x00001e53, 0x00001e53, 0x00001e55, 0x00001e55, - 0x00001e57, 0x00001e57, 0x00001e59, 0x00001e59, - 0x00001e5b, 0x00001e5b, 0x00001e5d, 0x00001e5d, - 0x00001e5f, 0x00001e5f, 0x00001e61, 0x00001e61, - 0x00001e63, 0x00001e63, 0x00001e65, 0x00001e65, - 0x00001e67, 0x00001e67, 0x00001e69, 0x00001e69, - 0x00001e6b, 0x00001e6b, 0x00001e6d, 0x00001e6d, - 0x00001e6f, 0x00001e6f, 0x00001e71, 0x00001e71, - 0x00001e73, 0x00001e73, 0x00001e75, 0x00001e75, - 0x00001e77, 0x00001e77, 0x00001e79, 0x00001e79, - 0x00001e7b, 0x00001e7b, 0x00001e7d, 0x00001e7d, - 0x00001e7f, 0x00001e7f, 0x00001e81, 0x00001e81, - 0x00001e83, 0x00001e83, 0x00001e85, 0x00001e85, - 0x00001e87, 0x00001e87, 0x00001e89, 0x00001e89, - 0x00001e8b, 0x00001e8b, 0x00001e8d, 0x00001e8d, - 0x00001e8f, 0x00001e8f, 0x00001e91, 0x00001e91, - 0x00001e93, 0x00001e93, 0x00001e95, 0x00001e9d, - 0x00001e9f, 0x00001e9f, 0x00001ea1, 0x00001ea1, - 0x00001ea3, 0x00001ea3, 0x00001ea5, 0x00001ea5, - 0x00001ea7, 0x00001ea7, 0x00001ea9, 0x00001ea9, - 0x00001eab, 0x00001eab, 0x00001ead, 0x00001ead, - 0x00001eaf, 0x00001eaf, 0x00001eb1, 0x00001eb1, - 0x00001eb3, 0x00001eb3, 0x00001eb5, 0x00001eb5, - 0x00001eb7, 0x00001eb7, 0x00001eb9, 0x00001eb9, - 0x00001ebb, 0x00001ebb, 0x00001ebd, 0x00001ebd, - 0x00001ebf, 0x00001ebf, 0x00001ec1, 0x00001ec1, - 0x00001ec3, 0x00001ec3, 0x00001ec5, 0x00001ec5, - 0x00001ec7, 0x00001ec7, 0x00001ec9, 0x00001ec9, - 0x00001ecb, 0x00001ecb, 0x00001ecd, 0x00001ecd, - 0x00001ecf, 0x00001ecf, 0x00001ed1, 0x00001ed1, - 0x00001ed3, 0x00001ed3, 0x00001ed5, 0x00001ed5, - 0x00001ed7, 0x00001ed7, 0x00001ed9, 0x00001ed9, - 0x00001edb, 0x00001edb, 0x00001edd, 0x00001edd, - 0x00001edf, 0x00001edf, 0x00001ee1, 0x00001ee1, - 0x00001ee3, 0x00001ee3, 0x00001ee5, 0x00001ee5, - 0x00001ee7, 0x00001ee7, 0x00001ee9, 0x00001ee9, - 0x00001eeb, 0x00001eeb, 0x00001eed, 0x00001eed, - 0x00001eef, 0x00001eef, 0x00001ef1, 0x00001ef1, - 0x00001ef3, 0x00001ef3, 0x00001ef5, 0x00001ef5, - 0x00001ef7, 0x00001ef7, 0x00001ef9, 0x00001ef9, - 0x00001efb, 0x00001efb, 0x00001efd, 0x00001efd, - 0x00001eff, 0x00001f07, 0x00001f10, 0x00001f15, - 0x00001f20, 0x00001f27, 0x00001f30, 0x00001f37, - 0x00001f40, 0x00001f45, 0x00001f50, 0x00001f57, - 0x00001f60, 0x00001f67, 0x00001f70, 0x00001f7d, - 0x00001f80, 0x00001f87, 0x00001f90, 0x00001f97, - 0x00001fa0, 0x00001fa7, 0x00001fb0, 0x00001fb4, - 0x00001fb6, 0x00001fb7, 0x00001fbe, 0x00001fbe, - 0x00001fc2, 0x00001fc4, 0x00001fc6, 0x00001fc7, - 0x00001fd0, 0x00001fd3, 0x00001fd6, 0x00001fd7, - 0x00001fe0, 0x00001fe7, 0x00001ff2, 0x00001ff4, - 0x00001ff6, 0x00001ff7, 0x0000210a, 0x0000210a, - 0x0000210e, 0x0000210f, 0x00002113, 0x00002113, - 0x0000212f, 0x0000212f, 0x00002134, 0x00002134, - 0x00002139, 0x00002139, 0x0000213c, 0x0000213d, - 0x00002146, 0x00002149, 0x0000214e, 0x0000214e, - 0x00002184, 0x00002184, 0x00002c30, 0x00002c5f, - 0x00002c61, 0x00002c61, 0x00002c65, 0x00002c66, - 0x00002c68, 0x00002c68, 0x00002c6a, 0x00002c6a, - 0x00002c6c, 0x00002c6c, 0x00002c71, 0x00002c71, - 0x00002c73, 0x00002c74, 0x00002c76, 0x00002c7b, - 0x00002c81, 0x00002c81, 0x00002c83, 0x00002c83, - 0x00002c85, 0x00002c85, 0x00002c87, 0x00002c87, - 0x00002c89, 0x00002c89, 0x00002c8b, 0x00002c8b, - 0x00002c8d, 0x00002c8d, 0x00002c8f, 0x00002c8f, - 0x00002c91, 0x00002c91, 0x00002c93, 0x00002c93, - 0x00002c95, 0x00002c95, 0x00002c97, 0x00002c97, - 0x00002c99, 0x00002c99, 0x00002c9b, 0x00002c9b, - 0x00002c9d, 0x00002c9d, 0x00002c9f, 0x00002c9f, - 0x00002ca1, 0x00002ca1, 0x00002ca3, 0x00002ca3, - 0x00002ca5, 0x00002ca5, 0x00002ca7, 0x00002ca7, - 0x00002ca9, 0x00002ca9, 0x00002cab, 0x00002cab, - 0x00002cad, 0x00002cad, 0x00002caf, 0x00002caf, - 0x00002cb1, 0x00002cb1, 0x00002cb3, 0x00002cb3, - 0x00002cb5, 0x00002cb5, 0x00002cb7, 0x00002cb7, - 0x00002cb9, 0x00002cb9, 0x00002cbb, 0x00002cbb, - 0x00002cbd, 0x00002cbd, 0x00002cbf, 0x00002cbf, - 0x00002cc1, 0x00002cc1, 0x00002cc3, 0x00002cc3, - 0x00002cc5, 0x00002cc5, 0x00002cc7, 0x00002cc7, - 0x00002cc9, 0x00002cc9, 0x00002ccb, 0x00002ccb, - 0x00002ccd, 0x00002ccd, 0x00002ccf, 0x00002ccf, - 0x00002cd1, 0x00002cd1, 0x00002cd3, 0x00002cd3, - 0x00002cd5, 0x00002cd5, 0x00002cd7, 0x00002cd7, - 0x00002cd9, 0x00002cd9, 0x00002cdb, 0x00002cdb, - 0x00002cdd, 0x00002cdd, 0x00002cdf, 0x00002cdf, - 0x00002ce1, 0x00002ce1, 0x00002ce3, 0x00002ce4, - 0x00002cec, 0x00002cec, 0x00002cee, 0x00002cee, - 0x00002cf3, 0x00002cf3, 0x00002d00, 0x00002d25, - 0x00002d27, 0x00002d27, 0x00002d2d, 0x00002d2d, - 0x0000a641, 0x0000a641, 0x0000a643, 0x0000a643, - 0x0000a645, 0x0000a645, 0x0000a647, 0x0000a647, - 0x0000a649, 0x0000a649, 0x0000a64b, 0x0000a64b, - 0x0000a64d, 0x0000a64d, 0x0000a64f, 0x0000a64f, - 0x0000a651, 0x0000a651, 0x0000a653, 0x0000a653, - 0x0000a655, 0x0000a655, 0x0000a657, 0x0000a657, - 0x0000a659, 0x0000a659, 0x0000a65b, 0x0000a65b, - 0x0000a65d, 0x0000a65d, 0x0000a65f, 0x0000a65f, - 0x0000a661, 0x0000a661, 0x0000a663, 0x0000a663, - 0x0000a665, 0x0000a665, 0x0000a667, 0x0000a667, - 0x0000a669, 0x0000a669, 0x0000a66b, 0x0000a66b, - 0x0000a66d, 0x0000a66d, 0x0000a681, 0x0000a681, - 0x0000a683, 0x0000a683, 0x0000a685, 0x0000a685, - 0x0000a687, 0x0000a687, 0x0000a689, 0x0000a689, - 0x0000a68b, 0x0000a68b, 0x0000a68d, 0x0000a68d, - 0x0000a68f, 0x0000a68f, 0x0000a691, 0x0000a691, - 0x0000a693, 0x0000a693, 0x0000a695, 0x0000a695, - 0x0000a697, 0x0000a697, 0x0000a699, 0x0000a699, - 0x0000a69b, 0x0000a69b, 0x0000a723, 0x0000a723, - 0x0000a725, 0x0000a725, 0x0000a727, 0x0000a727, - 0x0000a729, 0x0000a729, 0x0000a72b, 0x0000a72b, - 0x0000a72d, 0x0000a72d, 0x0000a72f, 0x0000a731, - 0x0000a733, 0x0000a733, 0x0000a735, 0x0000a735, - 0x0000a737, 0x0000a737, 0x0000a739, 0x0000a739, - 0x0000a73b, 0x0000a73b, 0x0000a73d, 0x0000a73d, - 0x0000a73f, 0x0000a73f, 0x0000a741, 0x0000a741, - 0x0000a743, 0x0000a743, 0x0000a745, 0x0000a745, - 0x0000a747, 0x0000a747, 0x0000a749, 0x0000a749, - 0x0000a74b, 0x0000a74b, 0x0000a74d, 0x0000a74d, - 0x0000a74f, 0x0000a74f, 0x0000a751, 0x0000a751, - 0x0000a753, 0x0000a753, 0x0000a755, 0x0000a755, - 0x0000a757, 0x0000a757, 0x0000a759, 0x0000a759, - 0x0000a75b, 0x0000a75b, 0x0000a75d, 0x0000a75d, - 0x0000a75f, 0x0000a75f, 0x0000a761, 0x0000a761, - 0x0000a763, 0x0000a763, 0x0000a765, 0x0000a765, - 0x0000a767, 0x0000a767, 0x0000a769, 0x0000a769, - 0x0000a76b, 0x0000a76b, 0x0000a76d, 0x0000a76d, - 0x0000a76f, 0x0000a76f, 0x0000a771, 0x0000a778, - 0x0000a77a, 0x0000a77a, 0x0000a77c, 0x0000a77c, - 0x0000a77f, 0x0000a77f, 0x0000a781, 0x0000a781, - 0x0000a783, 0x0000a783, 0x0000a785, 0x0000a785, - 0x0000a787, 0x0000a787, 0x0000a78c, 0x0000a78c, - 0x0000a78e, 0x0000a78e, 0x0000a791, 0x0000a791, - 0x0000a793, 0x0000a795, 0x0000a797, 0x0000a797, - 0x0000a799, 0x0000a799, 0x0000a79b, 0x0000a79b, - 0x0000a79d, 0x0000a79d, 0x0000a79f, 0x0000a79f, - 0x0000a7a1, 0x0000a7a1, 0x0000a7a3, 0x0000a7a3, - 0x0000a7a5, 0x0000a7a5, 0x0000a7a7, 0x0000a7a7, - 0x0000a7a9, 0x0000a7a9, 0x0000a7af, 0x0000a7af, - 0x0000a7b5, 0x0000a7b5, 0x0000a7b7, 0x0000a7b7, - 0x0000a7b9, 0x0000a7b9, 0x0000a7bb, 0x0000a7bb, - 0x0000a7bd, 0x0000a7bd, 0x0000a7bf, 0x0000a7bf, - 0x0000a7c1, 0x0000a7c1, 0x0000a7c3, 0x0000a7c3, - 0x0000a7c8, 0x0000a7c8, 0x0000a7ca, 0x0000a7ca, - 0x0000a7cd, 0x0000a7cd, 0x0000a7d1, 0x0000a7d1, + 0x00016e40, 0x00016e5f, 0x00016ea0, 0x00016eb8, + 0x0001d400, 0x0001d419, 0x0001d434, 0x0001d44d, + 0x0001d468, 0x0001d481, 0x0001d49c, 0x0001d49c, + 0x0001d49e, 0x0001d49f, 0x0001d4a2, 0x0001d4a2, + 0x0001d4a5, 0x0001d4a6, 0x0001d4a9, 0x0001d4ac, + 0x0001d4ae, 0x0001d4b5, 0x0001d4d0, 0x0001d4e9, + 0x0001d504, 0x0001d505, 0x0001d507, 0x0001d50a, + 0x0001d50d, 0x0001d514, 0x0001d516, 0x0001d51c, + 0x0001d538, 0x0001d539, 0x0001d53b, 0x0001d53e, + 0x0001d540, 0x0001d544, 0x0001d546, 0x0001d546, + 0x0001d54a, 0x0001d550, 0x0001d56c, 0x0001d585, + 0x0001d5a0, 0x0001d5b9, 0x0001d5d4, 0x0001d5ed, + 0x0001d608, 0x0001d621, 0x0001d63c, 0x0001d655, + 0x0001d670, 0x0001d689, 0x0001d6a8, 0x0001d6c0, + 0x0001d6e2, 0x0001d6fa, 0x0001d71c, 0x0001d734, + 0x0001d756, 0x0001d76e, 0x0001d790, 0x0001d7a8, + 0x0001d7ca, 0x0001d7ca, 0x0001e900, 0x0001e921, + 0x00000061, 0x0000007a, 0x000000b5, 0x000000b5, + 0x000000df, 0x000000f6, 0x000000f8, 0x000000ff, + 0x00000101, 0x00000101, 0x00000103, 0x00000103, + 0x00000105, 0x00000105, 0x00000107, 0x00000107, + 0x00000109, 0x00000109, 0x0000010b, 0x0000010b, + 0x0000010d, 0x0000010d, 0x0000010f, 0x0000010f, + 0x00000111, 0x00000111, 0x00000113, 0x00000113, + 0x00000115, 0x00000115, 0x00000117, 0x00000117, + 0x00000119, 0x00000119, 0x0000011b, 0x0000011b, + 0x0000011d, 0x0000011d, 0x0000011f, 0x0000011f, + 0x00000121, 0x00000121, 0x00000123, 0x00000123, + 0x00000125, 0x00000125, 0x00000127, 0x00000127, + 0x00000129, 0x00000129, 0x0000012b, 0x0000012b, + 0x0000012d, 0x0000012d, 0x0000012f, 0x0000012f, + 0x00000131, 0x00000131, 0x00000133, 0x00000133, + 0x00000135, 0x00000135, 0x00000137, 0x00000138, + 0x0000013a, 0x0000013a, 0x0000013c, 0x0000013c, + 0x0000013e, 0x0000013e, 0x00000140, 0x00000140, + 0x00000142, 0x00000142, 0x00000144, 0x00000144, + 0x00000146, 0x00000146, 0x00000148, 0x00000149, + 0x0000014b, 0x0000014b, 0x0000014d, 0x0000014d, + 0x0000014f, 0x0000014f, 0x00000151, 0x00000151, + 0x00000153, 0x00000153, 0x00000155, 0x00000155, + 0x00000157, 0x00000157, 0x00000159, 0x00000159, + 0x0000015b, 0x0000015b, 0x0000015d, 0x0000015d, + 0x0000015f, 0x0000015f, 0x00000161, 0x00000161, + 0x00000163, 0x00000163, 0x00000165, 0x00000165, + 0x00000167, 0x00000167, 0x00000169, 0x00000169, + 0x0000016b, 0x0000016b, 0x0000016d, 0x0000016d, + 0x0000016f, 0x0000016f, 0x00000171, 0x00000171, + 0x00000173, 0x00000173, 0x00000175, 0x00000175, + 0x00000177, 0x00000177, 0x0000017a, 0x0000017a, + 0x0000017c, 0x0000017c, 0x0000017e, 0x00000180, + 0x00000183, 0x00000183, 0x00000185, 0x00000185, + 0x00000188, 0x00000188, 0x0000018c, 0x0000018d, + 0x00000192, 0x00000192, 0x00000195, 0x00000195, + 0x00000199, 0x0000019b, 0x0000019e, 0x0000019e, + 0x000001a1, 0x000001a1, 0x000001a3, 0x000001a3, + 0x000001a5, 0x000001a5, 0x000001a8, 0x000001a8, + 0x000001aa, 0x000001ab, 0x000001ad, 0x000001ad, + 0x000001b0, 0x000001b0, 0x000001b4, 0x000001b4, + 0x000001b6, 0x000001b6, 0x000001b9, 0x000001ba, + 0x000001bd, 0x000001bf, 0x000001c6, 0x000001c6, + 0x000001c9, 0x000001c9, 0x000001cc, 0x000001cc, + 0x000001ce, 0x000001ce, 0x000001d0, 0x000001d0, + 0x000001d2, 0x000001d2, 0x000001d4, 0x000001d4, + 0x000001d6, 0x000001d6, 0x000001d8, 0x000001d8, + 0x000001da, 0x000001da, 0x000001dc, 0x000001dd, + 0x000001df, 0x000001df, 0x000001e1, 0x000001e1, + 0x000001e3, 0x000001e3, 0x000001e5, 0x000001e5, + 0x000001e7, 0x000001e7, 0x000001e9, 0x000001e9, + 0x000001eb, 0x000001eb, 0x000001ed, 0x000001ed, + 0x000001ef, 0x000001f0, 0x000001f3, 0x000001f3, + 0x000001f5, 0x000001f5, 0x000001f9, 0x000001f9, + 0x000001fb, 0x000001fb, 0x000001fd, 0x000001fd, + 0x000001ff, 0x000001ff, 0x00000201, 0x00000201, + 0x00000203, 0x00000203, 0x00000205, 0x00000205, + 0x00000207, 0x00000207, 0x00000209, 0x00000209, + 0x0000020b, 0x0000020b, 0x0000020d, 0x0000020d, + 0x0000020f, 0x0000020f, 0x00000211, 0x00000211, + 0x00000213, 0x00000213, 0x00000215, 0x00000215, + 0x00000217, 0x00000217, 0x00000219, 0x00000219, + 0x0000021b, 0x0000021b, 0x0000021d, 0x0000021d, + 0x0000021f, 0x0000021f, 0x00000221, 0x00000221, + 0x00000223, 0x00000223, 0x00000225, 0x00000225, + 0x00000227, 0x00000227, 0x00000229, 0x00000229, + 0x0000022b, 0x0000022b, 0x0000022d, 0x0000022d, + 0x0000022f, 0x0000022f, 0x00000231, 0x00000231, + 0x00000233, 0x00000239, 0x0000023c, 0x0000023c, + 0x0000023f, 0x00000240, 0x00000242, 0x00000242, + 0x00000247, 0x00000247, 0x00000249, 0x00000249, + 0x0000024b, 0x0000024b, 0x0000024d, 0x0000024d, + 0x0000024f, 0x00000293, 0x00000296, 0x000002af, + 0x00000371, 0x00000371, 0x00000373, 0x00000373, + 0x00000377, 0x00000377, 0x0000037b, 0x0000037d, + 0x00000390, 0x00000390, 0x000003ac, 0x000003ce, + 0x000003d0, 0x000003d1, 0x000003d5, 0x000003d7, + 0x000003d9, 0x000003d9, 0x000003db, 0x000003db, + 0x000003dd, 0x000003dd, 0x000003df, 0x000003df, + 0x000003e1, 0x000003e1, 0x000003e3, 0x000003e3, + 0x000003e5, 0x000003e5, 0x000003e7, 0x000003e7, + 0x000003e9, 0x000003e9, 0x000003eb, 0x000003eb, + 0x000003ed, 0x000003ed, 0x000003ef, 0x000003f3, + 0x000003f5, 0x000003f5, 0x000003f8, 0x000003f8, + 0x000003fb, 0x000003fc, 0x00000430, 0x0000045f, + 0x00000461, 0x00000461, 0x00000463, 0x00000463, + 0x00000465, 0x00000465, 0x00000467, 0x00000467, + 0x00000469, 0x00000469, 0x0000046b, 0x0000046b, + 0x0000046d, 0x0000046d, 0x0000046f, 0x0000046f, + 0x00000471, 0x00000471, 0x00000473, 0x00000473, + 0x00000475, 0x00000475, 0x00000477, 0x00000477, + 0x00000479, 0x00000479, 0x0000047b, 0x0000047b, + 0x0000047d, 0x0000047d, 0x0000047f, 0x0000047f, + 0x00000481, 0x00000481, 0x0000048b, 0x0000048b, + 0x0000048d, 0x0000048d, 0x0000048f, 0x0000048f, + 0x00000491, 0x00000491, 0x00000493, 0x00000493, + 0x00000495, 0x00000495, 0x00000497, 0x00000497, + 0x00000499, 0x00000499, 0x0000049b, 0x0000049b, + 0x0000049d, 0x0000049d, 0x0000049f, 0x0000049f, + 0x000004a1, 0x000004a1, 0x000004a3, 0x000004a3, + 0x000004a5, 0x000004a5, 0x000004a7, 0x000004a7, + 0x000004a9, 0x000004a9, 0x000004ab, 0x000004ab, + 0x000004ad, 0x000004ad, 0x000004af, 0x000004af, + 0x000004b1, 0x000004b1, 0x000004b3, 0x000004b3, + 0x000004b5, 0x000004b5, 0x000004b7, 0x000004b7, + 0x000004b9, 0x000004b9, 0x000004bb, 0x000004bb, + 0x000004bd, 0x000004bd, 0x000004bf, 0x000004bf, + 0x000004c2, 0x000004c2, 0x000004c4, 0x000004c4, + 0x000004c6, 0x000004c6, 0x000004c8, 0x000004c8, + 0x000004ca, 0x000004ca, 0x000004cc, 0x000004cc, + 0x000004ce, 0x000004cf, 0x000004d1, 0x000004d1, + 0x000004d3, 0x000004d3, 0x000004d5, 0x000004d5, + 0x000004d7, 0x000004d7, 0x000004d9, 0x000004d9, + 0x000004db, 0x000004db, 0x000004dd, 0x000004dd, + 0x000004df, 0x000004df, 0x000004e1, 0x000004e1, + 0x000004e3, 0x000004e3, 0x000004e5, 0x000004e5, + 0x000004e7, 0x000004e7, 0x000004e9, 0x000004e9, + 0x000004eb, 0x000004eb, 0x000004ed, 0x000004ed, + 0x000004ef, 0x000004ef, 0x000004f1, 0x000004f1, + 0x000004f3, 0x000004f3, 0x000004f5, 0x000004f5, + 0x000004f7, 0x000004f7, 0x000004f9, 0x000004f9, + 0x000004fb, 0x000004fb, 0x000004fd, 0x000004fd, + 0x000004ff, 0x000004ff, 0x00000501, 0x00000501, + 0x00000503, 0x00000503, 0x00000505, 0x00000505, + 0x00000507, 0x00000507, 0x00000509, 0x00000509, + 0x0000050b, 0x0000050b, 0x0000050d, 0x0000050d, + 0x0000050f, 0x0000050f, 0x00000511, 0x00000511, + 0x00000513, 0x00000513, 0x00000515, 0x00000515, + 0x00000517, 0x00000517, 0x00000519, 0x00000519, + 0x0000051b, 0x0000051b, 0x0000051d, 0x0000051d, + 0x0000051f, 0x0000051f, 0x00000521, 0x00000521, + 0x00000523, 0x00000523, 0x00000525, 0x00000525, + 0x00000527, 0x00000527, 0x00000529, 0x00000529, + 0x0000052b, 0x0000052b, 0x0000052d, 0x0000052d, + 0x0000052f, 0x0000052f, 0x00000560, 0x00000588, + 0x000010d0, 0x000010fa, 0x000010fd, 0x000010ff, + 0x000013f8, 0x000013fd, 0x00001c80, 0x00001c88, + 0x00001c8a, 0x00001c8a, 0x00001d00, 0x00001d2b, + 0x00001d6b, 0x00001d77, 0x00001d79, 0x00001d9a, + 0x00001e01, 0x00001e01, 0x00001e03, 0x00001e03, + 0x00001e05, 0x00001e05, 0x00001e07, 0x00001e07, + 0x00001e09, 0x00001e09, 0x00001e0b, 0x00001e0b, + 0x00001e0d, 0x00001e0d, 0x00001e0f, 0x00001e0f, + 0x00001e11, 0x00001e11, 0x00001e13, 0x00001e13, + 0x00001e15, 0x00001e15, 0x00001e17, 0x00001e17, + 0x00001e19, 0x00001e19, 0x00001e1b, 0x00001e1b, + 0x00001e1d, 0x00001e1d, 0x00001e1f, 0x00001e1f, + 0x00001e21, 0x00001e21, 0x00001e23, 0x00001e23, + 0x00001e25, 0x00001e25, 0x00001e27, 0x00001e27, + 0x00001e29, 0x00001e29, 0x00001e2b, 0x00001e2b, + 0x00001e2d, 0x00001e2d, 0x00001e2f, 0x00001e2f, + 0x00001e31, 0x00001e31, 0x00001e33, 0x00001e33, + 0x00001e35, 0x00001e35, 0x00001e37, 0x00001e37, + 0x00001e39, 0x00001e39, 0x00001e3b, 0x00001e3b, + 0x00001e3d, 0x00001e3d, 0x00001e3f, 0x00001e3f, + 0x00001e41, 0x00001e41, 0x00001e43, 0x00001e43, + 0x00001e45, 0x00001e45, 0x00001e47, 0x00001e47, + 0x00001e49, 0x00001e49, 0x00001e4b, 0x00001e4b, + 0x00001e4d, 0x00001e4d, 0x00001e4f, 0x00001e4f, + 0x00001e51, 0x00001e51, 0x00001e53, 0x00001e53, + 0x00001e55, 0x00001e55, 0x00001e57, 0x00001e57, + 0x00001e59, 0x00001e59, 0x00001e5b, 0x00001e5b, + 0x00001e5d, 0x00001e5d, 0x00001e5f, 0x00001e5f, + 0x00001e61, 0x00001e61, 0x00001e63, 0x00001e63, + 0x00001e65, 0x00001e65, 0x00001e67, 0x00001e67, + 0x00001e69, 0x00001e69, 0x00001e6b, 0x00001e6b, + 0x00001e6d, 0x00001e6d, 0x00001e6f, 0x00001e6f, + 0x00001e71, 0x00001e71, 0x00001e73, 0x00001e73, + 0x00001e75, 0x00001e75, 0x00001e77, 0x00001e77, + 0x00001e79, 0x00001e79, 0x00001e7b, 0x00001e7b, + 0x00001e7d, 0x00001e7d, 0x00001e7f, 0x00001e7f, + 0x00001e81, 0x00001e81, 0x00001e83, 0x00001e83, + 0x00001e85, 0x00001e85, 0x00001e87, 0x00001e87, + 0x00001e89, 0x00001e89, 0x00001e8b, 0x00001e8b, + 0x00001e8d, 0x00001e8d, 0x00001e8f, 0x00001e8f, + 0x00001e91, 0x00001e91, 0x00001e93, 0x00001e93, + 0x00001e95, 0x00001e9d, 0x00001e9f, 0x00001e9f, + 0x00001ea1, 0x00001ea1, 0x00001ea3, 0x00001ea3, + 0x00001ea5, 0x00001ea5, 0x00001ea7, 0x00001ea7, + 0x00001ea9, 0x00001ea9, 0x00001eab, 0x00001eab, + 0x00001ead, 0x00001ead, 0x00001eaf, 0x00001eaf, + 0x00001eb1, 0x00001eb1, 0x00001eb3, 0x00001eb3, + 0x00001eb5, 0x00001eb5, 0x00001eb7, 0x00001eb7, + 0x00001eb9, 0x00001eb9, 0x00001ebb, 0x00001ebb, + 0x00001ebd, 0x00001ebd, 0x00001ebf, 0x00001ebf, + 0x00001ec1, 0x00001ec1, 0x00001ec3, 0x00001ec3, + 0x00001ec5, 0x00001ec5, 0x00001ec7, 0x00001ec7, + 0x00001ec9, 0x00001ec9, 0x00001ecb, 0x00001ecb, + 0x00001ecd, 0x00001ecd, 0x00001ecf, 0x00001ecf, + 0x00001ed1, 0x00001ed1, 0x00001ed3, 0x00001ed3, + 0x00001ed5, 0x00001ed5, 0x00001ed7, 0x00001ed7, + 0x00001ed9, 0x00001ed9, 0x00001edb, 0x00001edb, + 0x00001edd, 0x00001edd, 0x00001edf, 0x00001edf, + 0x00001ee1, 0x00001ee1, 0x00001ee3, 0x00001ee3, + 0x00001ee5, 0x00001ee5, 0x00001ee7, 0x00001ee7, + 0x00001ee9, 0x00001ee9, 0x00001eeb, 0x00001eeb, + 0x00001eed, 0x00001eed, 0x00001eef, 0x00001eef, + 0x00001ef1, 0x00001ef1, 0x00001ef3, 0x00001ef3, + 0x00001ef5, 0x00001ef5, 0x00001ef7, 0x00001ef7, + 0x00001ef9, 0x00001ef9, 0x00001efb, 0x00001efb, + 0x00001efd, 0x00001efd, 0x00001eff, 0x00001f07, + 0x00001f10, 0x00001f15, 0x00001f20, 0x00001f27, + 0x00001f30, 0x00001f37, 0x00001f40, 0x00001f45, + 0x00001f50, 0x00001f57, 0x00001f60, 0x00001f67, + 0x00001f70, 0x00001f7d, 0x00001f80, 0x00001f87, + 0x00001f90, 0x00001f97, 0x00001fa0, 0x00001fa7, + 0x00001fb0, 0x00001fb4, 0x00001fb6, 0x00001fb7, + 0x00001fbe, 0x00001fbe, 0x00001fc2, 0x00001fc4, + 0x00001fc6, 0x00001fc7, 0x00001fd0, 0x00001fd3, + 0x00001fd6, 0x00001fd7, 0x00001fe0, 0x00001fe7, + 0x00001ff2, 0x00001ff4, 0x00001ff6, 0x00001ff7, + 0x0000210a, 0x0000210a, 0x0000210e, 0x0000210f, + 0x00002113, 0x00002113, 0x0000212f, 0x0000212f, + 0x00002134, 0x00002134, 0x00002139, 0x00002139, + 0x0000213c, 0x0000213d, 0x00002146, 0x00002149, + 0x0000214e, 0x0000214e, 0x00002184, 0x00002184, + 0x00002c30, 0x00002c5f, 0x00002c61, 0x00002c61, + 0x00002c65, 0x00002c66, 0x00002c68, 0x00002c68, + 0x00002c6a, 0x00002c6a, 0x00002c6c, 0x00002c6c, + 0x00002c71, 0x00002c71, 0x00002c73, 0x00002c74, + 0x00002c76, 0x00002c7b, 0x00002c81, 0x00002c81, + 0x00002c83, 0x00002c83, 0x00002c85, 0x00002c85, + 0x00002c87, 0x00002c87, 0x00002c89, 0x00002c89, + 0x00002c8b, 0x00002c8b, 0x00002c8d, 0x00002c8d, + 0x00002c8f, 0x00002c8f, 0x00002c91, 0x00002c91, + 0x00002c93, 0x00002c93, 0x00002c95, 0x00002c95, + 0x00002c97, 0x00002c97, 0x00002c99, 0x00002c99, + 0x00002c9b, 0x00002c9b, 0x00002c9d, 0x00002c9d, + 0x00002c9f, 0x00002c9f, 0x00002ca1, 0x00002ca1, + 0x00002ca3, 0x00002ca3, 0x00002ca5, 0x00002ca5, + 0x00002ca7, 0x00002ca7, 0x00002ca9, 0x00002ca9, + 0x00002cab, 0x00002cab, 0x00002cad, 0x00002cad, + 0x00002caf, 0x00002caf, 0x00002cb1, 0x00002cb1, + 0x00002cb3, 0x00002cb3, 0x00002cb5, 0x00002cb5, + 0x00002cb7, 0x00002cb7, 0x00002cb9, 0x00002cb9, + 0x00002cbb, 0x00002cbb, 0x00002cbd, 0x00002cbd, + 0x00002cbf, 0x00002cbf, 0x00002cc1, 0x00002cc1, + 0x00002cc3, 0x00002cc3, 0x00002cc5, 0x00002cc5, + 0x00002cc7, 0x00002cc7, 0x00002cc9, 0x00002cc9, + 0x00002ccb, 0x00002ccb, 0x00002ccd, 0x00002ccd, + 0x00002ccf, 0x00002ccf, 0x00002cd1, 0x00002cd1, + 0x00002cd3, 0x00002cd3, 0x00002cd5, 0x00002cd5, + 0x00002cd7, 0x00002cd7, 0x00002cd9, 0x00002cd9, + 0x00002cdb, 0x00002cdb, 0x00002cdd, 0x00002cdd, + 0x00002cdf, 0x00002cdf, 0x00002ce1, 0x00002ce1, + 0x00002ce3, 0x00002ce4, 0x00002cec, 0x00002cec, + 0x00002cee, 0x00002cee, 0x00002cf3, 0x00002cf3, + 0x00002d00, 0x00002d25, 0x00002d27, 0x00002d27, + 0x00002d2d, 0x00002d2d, 0x0000a641, 0x0000a641, + 0x0000a643, 0x0000a643, 0x0000a645, 0x0000a645, + 0x0000a647, 0x0000a647, 0x0000a649, 0x0000a649, + 0x0000a64b, 0x0000a64b, 0x0000a64d, 0x0000a64d, + 0x0000a64f, 0x0000a64f, 0x0000a651, 0x0000a651, + 0x0000a653, 0x0000a653, 0x0000a655, 0x0000a655, + 0x0000a657, 0x0000a657, 0x0000a659, 0x0000a659, + 0x0000a65b, 0x0000a65b, 0x0000a65d, 0x0000a65d, + 0x0000a65f, 0x0000a65f, 0x0000a661, 0x0000a661, + 0x0000a663, 0x0000a663, 0x0000a665, 0x0000a665, + 0x0000a667, 0x0000a667, 0x0000a669, 0x0000a669, + 0x0000a66b, 0x0000a66b, 0x0000a66d, 0x0000a66d, + 0x0000a681, 0x0000a681, 0x0000a683, 0x0000a683, + 0x0000a685, 0x0000a685, 0x0000a687, 0x0000a687, + 0x0000a689, 0x0000a689, 0x0000a68b, 0x0000a68b, + 0x0000a68d, 0x0000a68d, 0x0000a68f, 0x0000a68f, + 0x0000a691, 0x0000a691, 0x0000a693, 0x0000a693, + 0x0000a695, 0x0000a695, 0x0000a697, 0x0000a697, + 0x0000a699, 0x0000a699, 0x0000a69b, 0x0000a69b, + 0x0000a723, 0x0000a723, 0x0000a725, 0x0000a725, + 0x0000a727, 0x0000a727, 0x0000a729, 0x0000a729, + 0x0000a72b, 0x0000a72b, 0x0000a72d, 0x0000a72d, + 0x0000a72f, 0x0000a731, 0x0000a733, 0x0000a733, + 0x0000a735, 0x0000a735, 0x0000a737, 0x0000a737, + 0x0000a739, 0x0000a739, 0x0000a73b, 0x0000a73b, + 0x0000a73d, 0x0000a73d, 0x0000a73f, 0x0000a73f, + 0x0000a741, 0x0000a741, 0x0000a743, 0x0000a743, + 0x0000a745, 0x0000a745, 0x0000a747, 0x0000a747, + 0x0000a749, 0x0000a749, 0x0000a74b, 0x0000a74b, + 0x0000a74d, 0x0000a74d, 0x0000a74f, 0x0000a74f, + 0x0000a751, 0x0000a751, 0x0000a753, 0x0000a753, + 0x0000a755, 0x0000a755, 0x0000a757, 0x0000a757, + 0x0000a759, 0x0000a759, 0x0000a75b, 0x0000a75b, + 0x0000a75d, 0x0000a75d, 0x0000a75f, 0x0000a75f, + 0x0000a761, 0x0000a761, 0x0000a763, 0x0000a763, + 0x0000a765, 0x0000a765, 0x0000a767, 0x0000a767, + 0x0000a769, 0x0000a769, 0x0000a76b, 0x0000a76b, + 0x0000a76d, 0x0000a76d, 0x0000a76f, 0x0000a76f, + 0x0000a771, 0x0000a778, 0x0000a77a, 0x0000a77a, + 0x0000a77c, 0x0000a77c, 0x0000a77f, 0x0000a77f, + 0x0000a781, 0x0000a781, 0x0000a783, 0x0000a783, + 0x0000a785, 0x0000a785, 0x0000a787, 0x0000a787, + 0x0000a78c, 0x0000a78c, 0x0000a78e, 0x0000a78e, + 0x0000a791, 0x0000a791, 0x0000a793, 0x0000a795, + 0x0000a797, 0x0000a797, 0x0000a799, 0x0000a799, + 0x0000a79b, 0x0000a79b, 0x0000a79d, 0x0000a79d, + 0x0000a79f, 0x0000a79f, 0x0000a7a1, 0x0000a7a1, + 0x0000a7a3, 0x0000a7a3, 0x0000a7a5, 0x0000a7a5, + 0x0000a7a7, 0x0000a7a7, 0x0000a7a9, 0x0000a7a9, + 0x0000a7af, 0x0000a7af, 0x0000a7b5, 0x0000a7b5, + 0x0000a7b7, 0x0000a7b7, 0x0000a7b9, 0x0000a7b9, + 0x0000a7bb, 0x0000a7bb, 0x0000a7bd, 0x0000a7bd, + 0x0000a7bf, 0x0000a7bf, 0x0000a7c1, 0x0000a7c1, + 0x0000a7c3, 0x0000a7c3, 0x0000a7c8, 0x0000a7c8, + 0x0000a7ca, 0x0000a7ca, 0x0000a7cd, 0x0000a7cd, + 0x0000a7cf, 0x0000a7cf, 0x0000a7d1, 0x0000a7d1, 0x0000a7d3, 0x0000a7d3, 0x0000a7d5, 0x0000a7d5, 0x0000a7d7, 0x0000a7d7, 0x0000a7d9, 0x0000a7d9, 0x0000a7db, 0x0000a7db, 0x0000a7f6, 0x0000a7f6, @@ -1021,228 +1030,231 @@ static const unsigned int _ucprop_ranges[] = { 0x000105a3, 0x000105b1, 0x000105b3, 0x000105b9, 0x000105bb, 0x000105bc, 0x00010cc0, 0x00010cf2, 0x00010d70, 0x00010d85, 0x000118c0, 0x000118df, - 0x00016e60, 0x00016e7f, 0x0001d41a, 0x0001d433, - 0x0001d44e, 0x0001d454, 0x0001d456, 0x0001d467, - 0x0001d482, 0x0001d49b, 0x0001d4b6, 0x0001d4b9, - 0x0001d4bb, 0x0001d4bb, 0x0001d4bd, 0x0001d4c3, - 0x0001d4c5, 0x0001d4cf, 0x0001d4ea, 0x0001d503, - 0x0001d51e, 0x0001d537, 0x0001d552, 0x0001d56b, - 0x0001d586, 0x0001d59f, 0x0001d5ba, 0x0001d5d3, - 0x0001d5ee, 0x0001d607, 0x0001d622, 0x0001d63b, - 0x0001d656, 0x0001d66f, 0x0001d68a, 0x0001d6a5, - 0x0001d6c2, 0x0001d6da, 0x0001d6dc, 0x0001d6e1, - 0x0001d6fc, 0x0001d714, 0x0001d716, 0x0001d71b, - 0x0001d736, 0x0001d74e, 0x0001d750, 0x0001d755, - 0x0001d770, 0x0001d788, 0x0001d78a, 0x0001d78f, - 0x0001d7aa, 0x0001d7c2, 0x0001d7c4, 0x0001d7c9, - 0x0001d7cb, 0x0001d7cb, 0x0001df00, 0x0001df09, - 0x0001df0b, 0x0001df1e, 0x0001df25, 0x0001df2a, - 0x0001e922, 0x0001e943, 0x000001c5, 0x000001c5, - 0x000001c8, 0x000001c8, 0x000001cb, 0x000001cb, - 0x000001f2, 0x000001f2, 0x00001f88, 0x00001f8f, - 0x00001f98, 0x00001f9f, 0x00001fa8, 0x00001faf, - 0x00001fbc, 0x00001fbc, 0x00001fcc, 0x00001fcc, - 0x00001ffc, 0x00001ffc, 0x000002b0, 0x000002c1, - 0x000002c6, 0x000002d1, 0x000002e0, 0x000002e4, - 0x000002ec, 0x000002ec, 0x000002ee, 0x000002ee, - 0x00000374, 0x00000374, 0x0000037a, 0x0000037a, - 0x00000559, 0x00000559, 0x00000640, 0x00000640, - 0x000006e5, 0x000006e6, 0x000007f4, 0x000007f5, - 0x000007fa, 0x000007fa, 0x0000081a, 0x0000081a, - 0x00000824, 0x00000824, 0x00000828, 0x00000828, - 0x000008c9, 0x000008c9, 0x00000971, 0x00000971, - 0x00000e46, 0x00000e46, 0x00000ec6, 0x00000ec6, - 0x000010fc, 0x000010fc, 0x000017d7, 0x000017d7, - 0x00001843, 0x00001843, 0x00001aa7, 0x00001aa7, - 0x00001c78, 0x00001c7d, 0x00001d2c, 0x00001d6a, - 0x00001d78, 0x00001d78, 0x00001d9b, 0x00001dbf, - 0x00002071, 0x00002071, 0x0000207f, 0x0000207f, - 0x00002090, 0x0000209c, 0x00002c7c, 0x00002c7d, - 0x00002d6f, 0x00002d6f, 0x00002e2f, 0x00002e2f, - 0x00003005, 0x00003005, 0x00003031, 0x00003035, - 0x0000303b, 0x0000303b, 0x0000309d, 0x0000309e, - 0x000030fc, 0x000030fe, 0x0000a015, 0x0000a015, - 0x0000a4f8, 0x0000a4fd, 0x0000a60c, 0x0000a60c, - 0x0000a67f, 0x0000a67f, 0x0000a69c, 0x0000a69d, - 0x0000a717, 0x0000a71f, 0x0000a770, 0x0000a770, - 0x0000a788, 0x0000a788, 0x0000a7f2, 0x0000a7f4, - 0x0000a7f8, 0x0000a7f9, 0x0000a9cf, 0x0000a9cf, - 0x0000a9e6, 0x0000a9e6, 0x0000aa70, 0x0000aa70, - 0x0000aadd, 0x0000aadd, 0x0000aaf3, 0x0000aaf4, - 0x0000ab5c, 0x0000ab5f, 0x0000ab69, 0x0000ab69, - 0x0000ff70, 0x0000ff70, 0x0000ff9e, 0x0000ff9f, - 0x00010780, 0x00010785, 0x00010787, 0x000107b0, - 0x000107b2, 0x000107ba, 0x00010d4e, 0x00010d4e, - 0x00010d6f, 0x00010d6f, 0x00016b40, 0x00016b43, - 0x00016d40, 0x00016d42, 0x00016d6b, 0x00016d6c, - 0x00016f93, 0x00016f9f, 0x00016fe0, 0x00016fe1, - 0x00016fe3, 0x00016fe3, 0x0001aff0, 0x0001aff3, + 0x00016e60, 0x00016e7f, 0x00016ebb, 0x00016ed3, + 0x0001d41a, 0x0001d433, 0x0001d44e, 0x0001d454, + 0x0001d456, 0x0001d467, 0x0001d482, 0x0001d49b, + 0x0001d4b6, 0x0001d4b9, 0x0001d4bb, 0x0001d4bb, + 0x0001d4bd, 0x0001d4c3, 0x0001d4c5, 0x0001d4cf, + 0x0001d4ea, 0x0001d503, 0x0001d51e, 0x0001d537, + 0x0001d552, 0x0001d56b, 0x0001d586, 0x0001d59f, + 0x0001d5ba, 0x0001d5d3, 0x0001d5ee, 0x0001d607, + 0x0001d622, 0x0001d63b, 0x0001d656, 0x0001d66f, + 0x0001d68a, 0x0001d6a5, 0x0001d6c2, 0x0001d6da, + 0x0001d6dc, 0x0001d6e1, 0x0001d6fc, 0x0001d714, + 0x0001d716, 0x0001d71b, 0x0001d736, 0x0001d74e, + 0x0001d750, 0x0001d755, 0x0001d770, 0x0001d788, + 0x0001d78a, 0x0001d78f, 0x0001d7aa, 0x0001d7c2, + 0x0001d7c4, 0x0001d7c9, 0x0001d7cb, 0x0001d7cb, + 0x0001df00, 0x0001df09, 0x0001df0b, 0x0001df1e, + 0x0001df25, 0x0001df2a, 0x0001e922, 0x0001e943, + 0x000001c5, 0x000001c5, 0x000001c8, 0x000001c8, + 0x000001cb, 0x000001cb, 0x000001f2, 0x000001f2, + 0x00001f88, 0x00001f8f, 0x00001f98, 0x00001f9f, + 0x00001fa8, 0x00001faf, 0x00001fbc, 0x00001fbc, + 0x00001fcc, 0x00001fcc, 0x00001ffc, 0x00001ffc, + 0x000002b0, 0x000002c1, 0x000002c6, 0x000002d1, + 0x000002e0, 0x000002e4, 0x000002ec, 0x000002ec, + 0x000002ee, 0x000002ee, 0x00000374, 0x00000374, + 0x0000037a, 0x0000037a, 0x00000559, 0x00000559, + 0x00000640, 0x00000640, 0x000006e5, 0x000006e6, + 0x000007f4, 0x000007f5, 0x000007fa, 0x000007fa, + 0x0000081a, 0x0000081a, 0x00000824, 0x00000824, + 0x00000828, 0x00000828, 0x000008c9, 0x000008c9, + 0x00000971, 0x00000971, 0x00000e46, 0x00000e46, + 0x00000ec6, 0x00000ec6, 0x000010fc, 0x000010fc, + 0x000017d7, 0x000017d7, 0x00001843, 0x00001843, + 0x00001aa7, 0x00001aa7, 0x00001c78, 0x00001c7d, + 0x00001d2c, 0x00001d6a, 0x00001d78, 0x00001d78, + 0x00001d9b, 0x00001dbf, 0x00002071, 0x00002071, + 0x0000207f, 0x0000207f, 0x00002090, 0x0000209c, + 0x00002c7c, 0x00002c7d, 0x00002d6f, 0x00002d6f, + 0x00002e2f, 0x00002e2f, 0x00003005, 0x00003005, + 0x00003031, 0x00003035, 0x0000303b, 0x0000303b, + 0x0000309d, 0x0000309e, 0x000030fc, 0x000030fe, + 0x0000a015, 0x0000a015, 0x0000a4f8, 0x0000a4fd, + 0x0000a60c, 0x0000a60c, 0x0000a67f, 0x0000a67f, + 0x0000a69c, 0x0000a69d, 0x0000a717, 0x0000a71f, + 0x0000a770, 0x0000a770, 0x0000a788, 0x0000a788, + 0x0000a7f1, 0x0000a7f4, 0x0000a7f8, 0x0000a7f9, + 0x0000a9cf, 0x0000a9cf, 0x0000a9e6, 0x0000a9e6, + 0x0000aa70, 0x0000aa70, 0x0000aadd, 0x0000aadd, + 0x0000aaf3, 0x0000aaf4, 0x0000ab5c, 0x0000ab5f, + 0x0000ab69, 0x0000ab69, 0x0000ff70, 0x0000ff70, + 0x0000ff9e, 0x0000ff9f, 0x00010780, 0x00010785, + 0x00010787, 0x000107b0, 0x000107b2, 0x000107ba, + 0x00010d4e, 0x00010d4e, 0x00010d6f, 0x00010d6f, + 0x00010ec5, 0x00010ec5, 0x00011dd9, 0x00011dd9, + 0x00016b40, 0x00016b43, 0x00016d40, 0x00016d42, + 0x00016d6b, 0x00016d6c, 0x00016f93, 0x00016f9f, + 0x00016fe0, 0x00016fe1, 0x00016fe3, 0x00016fe3, + 0x00016ff2, 0x00016ff3, 0x0001aff0, 0x0001aff3, 0x0001aff5, 0x0001affb, 0x0001affd, 0x0001affe, 0x0001e030, 0x0001e06d, 0x0001e137, 0x0001e13d, - 0x0001e4eb, 0x0001e4eb, 0x0001e94b, 0x0001e94b, - 0x000000aa, 0x000000aa, 0x000000ba, 0x000000ba, - 0x000001bb, 0x000001bb, 0x000001c0, 0x000001c3, - 0x00000294, 0x00000294, 0x000005d0, 0x000005ea, - 0x000005ef, 0x000005f2, 0x00000620, 0x0000063f, - 0x00000641, 0x0000064a, 0x0000066e, 0x0000066f, - 0x00000671, 0x000006d3, 0x000006d5, 0x000006d5, - 0x000006ee, 0x000006ef, 0x000006fa, 0x000006fc, - 0x000006ff, 0x000006ff, 0x00000710, 0x00000710, - 0x00000712, 0x0000072f, 0x0000074d, 0x000007a5, - 0x000007b1, 0x000007b1, 0x000007ca, 0x000007ea, - 0x00000800, 0x00000815, 0x00000840, 0x00000858, - 0x00000860, 0x0000086a, 0x00000870, 0x00000887, - 0x00000889, 0x0000088e, 0x000008a0, 0x000008c8, - 0x00000904, 0x00000939, 0x0000093d, 0x0000093d, - 0x00000950, 0x00000950, 0x00000958, 0x00000961, - 0x00000972, 0x00000980, 0x00000985, 0x0000098c, - 0x0000098f, 0x00000990, 0x00000993, 0x000009a8, - 0x000009aa, 0x000009b0, 0x000009b2, 0x000009b2, - 0x000009b6, 0x000009b9, 0x000009bd, 0x000009bd, - 0x000009ce, 0x000009ce, 0x000009dc, 0x000009dd, - 0x000009df, 0x000009e1, 0x000009f0, 0x000009f1, - 0x000009fc, 0x000009fc, 0x00000a05, 0x00000a0a, - 0x00000a0f, 0x00000a10, 0x00000a13, 0x00000a28, - 0x00000a2a, 0x00000a30, 0x00000a32, 0x00000a33, - 0x00000a35, 0x00000a36, 0x00000a38, 0x00000a39, - 0x00000a59, 0x00000a5c, 0x00000a5e, 0x00000a5e, - 0x00000a72, 0x00000a74, 0x00000a85, 0x00000a8d, - 0x00000a8f, 0x00000a91, 0x00000a93, 0x00000aa8, - 0x00000aaa, 0x00000ab0, 0x00000ab2, 0x00000ab3, - 0x00000ab5, 0x00000ab9, 0x00000abd, 0x00000abd, - 0x00000ad0, 0x00000ad0, 0x00000ae0, 0x00000ae1, - 0x00000af9, 0x00000af9, 0x00000b05, 0x00000b0c, - 0x00000b0f, 0x00000b10, 0x00000b13, 0x00000b28, - 0x00000b2a, 0x00000b30, 0x00000b32, 0x00000b33, - 0x00000b35, 0x00000b39, 0x00000b3d, 0x00000b3d, - 0x00000b5c, 0x00000b5d, 0x00000b5f, 0x00000b61, - 0x00000b71, 0x00000b71, 0x00000b83, 0x00000b83, - 0x00000b85, 0x00000b8a, 0x00000b8e, 0x00000b90, - 0x00000b92, 0x00000b95, 0x00000b99, 0x00000b9a, - 0x00000b9c, 0x00000b9c, 0x00000b9e, 0x00000b9f, - 0x00000ba3, 0x00000ba4, 0x00000ba8, 0x00000baa, - 0x00000bae, 0x00000bb9, 0x00000bd0, 0x00000bd0, - 0x00000c05, 0x00000c0c, 0x00000c0e, 0x00000c10, - 0x00000c12, 0x00000c28, 0x00000c2a, 0x00000c39, - 0x00000c3d, 0x00000c3d, 0x00000c58, 0x00000c5a, - 0x00000c5d, 0x00000c5d, 0x00000c60, 0x00000c61, - 0x00000c80, 0x00000c80, 0x00000c85, 0x00000c8c, - 0x00000c8e, 0x00000c90, 0x00000c92, 0x00000ca8, - 0x00000caa, 0x00000cb3, 0x00000cb5, 0x00000cb9, - 0x00000cbd, 0x00000cbd, 0x00000cdd, 0x00000cde, - 0x00000ce0, 0x00000ce1, 0x00000cf1, 0x00000cf2, - 0x00000d04, 0x00000d0c, 0x00000d0e, 0x00000d10, - 0x00000d12, 0x00000d3a, 0x00000d3d, 0x00000d3d, - 0x00000d4e, 0x00000d4e, 0x00000d54, 0x00000d56, - 0x00000d5f, 0x00000d61, 0x00000d7a, 0x00000d7f, - 0x00000d85, 0x00000d96, 0x00000d9a, 0x00000db1, - 0x00000db3, 0x00000dbb, 0x00000dbd, 0x00000dbd, - 0x00000dc0, 0x00000dc6, 0x00000e01, 0x00000e30, - 0x00000e32, 0x00000e33, 0x00000e40, 0x00000e45, - 0x00000e81, 0x00000e82, 0x00000e84, 0x00000e84, - 0x00000e86, 0x00000e8a, 0x00000e8c, 0x00000ea3, - 0x00000ea5, 0x00000ea5, 0x00000ea7, 0x00000eb0, - 0x00000eb2, 0x00000eb3, 0x00000ebd, 0x00000ebd, - 0x00000ec0, 0x00000ec4, 0x00000edc, 0x00000edf, - 0x00000f00, 0x00000f00, 0x00000f40, 0x00000f47, - 0x00000f49, 0x00000f6c, 0x00000f88, 0x00000f8c, - 0x00001000, 0x0000102a, 0x0000103f, 0x0000103f, - 0x00001050, 0x00001055, 0x0000105a, 0x0000105d, - 0x00001061, 0x00001061, 0x00001065, 0x00001066, - 0x0000106e, 0x00001070, 0x00001075, 0x00001081, - 0x0000108e, 0x0000108e, 0x00001100, 0x00001248, - 0x0000124a, 0x0000124d, 0x00001250, 0x00001256, - 0x00001258, 0x00001258, 0x0000125a, 0x0000125d, - 0x00001260, 0x00001288, 0x0000128a, 0x0000128d, - 0x00001290, 0x000012b0, 0x000012b2, 0x000012b5, - 0x000012b8, 0x000012be, 0x000012c0, 0x000012c0, - 0x000012c2, 0x000012c5, 0x000012c8, 0x000012d6, - 0x000012d8, 0x00001310, 0x00001312, 0x00001315, - 0x00001318, 0x0000135a, 0x00001380, 0x0000138f, - 0x00001401, 0x0000166c, 0x0000166f, 0x0000167f, - 0x00001681, 0x0000169a, 0x000016a0, 0x000016ea, - 0x000016f1, 0x000016f8, 0x00001700, 0x00001711, - 0x0000171f, 0x00001731, 0x00001740, 0x00001751, - 0x00001760, 0x0000176c, 0x0000176e, 0x00001770, - 0x00001780, 0x000017b3, 0x000017dc, 0x000017dc, - 0x00001820, 0x00001842, 0x00001844, 0x00001878, - 0x00001880, 0x00001884, 0x00001887, 0x000018a8, - 0x000018aa, 0x000018aa, 0x000018b0, 0x000018f5, - 0x00001900, 0x0000191e, 0x00001950, 0x0000196d, - 0x00001970, 0x00001974, 0x00001980, 0x000019ab, - 0x000019b0, 0x000019c9, 0x00001a00, 0x00001a16, - 0x00001a20, 0x00001a54, 0x00001b05, 0x00001b33, - 0x00001b45, 0x00001b4c, 0x00001b83, 0x00001ba0, - 0x00001bae, 0x00001baf, 0x00001bba, 0x00001be5, - 0x00001c00, 0x00001c23, 0x00001c4d, 0x00001c4f, - 0x00001c5a, 0x00001c77, 0x00001ce9, 0x00001cec, - 0x00001cee, 0x00001cf3, 0x00001cf5, 0x00001cf6, - 0x00001cfa, 0x00001cfa, 0x00002135, 0x00002138, - 0x00002d30, 0x00002d67, 0x00002d80, 0x00002d96, - 0x00002da0, 0x00002da6, 0x00002da8, 0x00002dae, - 0x00002db0, 0x00002db6, 0x00002db8, 0x00002dbe, - 0x00002dc0, 0x00002dc6, 0x00002dc8, 0x00002dce, - 0x00002dd0, 0x00002dd6, 0x00002dd8, 0x00002dde, - 0x00003006, 0x00003006, 0x0000303c, 0x0000303c, - 0x00003041, 0x00003096, 0x0000309f, 0x0000309f, - 0x000030a1, 0x000030fa, 0x000030ff, 0x000030ff, - 0x00003105, 0x0000312f, 0x00003131, 0x0000318e, - 0x000031a0, 0x000031bf, 0x000031f0, 0x000031ff, - 0x00003400, 0x00004dbf, 0x00004e00, 0x0000a014, - 0x0000a016, 0x0000a48c, 0x0000a4d0, 0x0000a4f7, - 0x0000a500, 0x0000a60b, 0x0000a610, 0x0000a61f, - 0x0000a62a, 0x0000a62b, 0x0000a66e, 0x0000a66e, - 0x0000a6a0, 0x0000a6e5, 0x0000a78f, 0x0000a78f, - 0x0000a7f7, 0x0000a7f7, 0x0000a7fb, 0x0000a801, - 0x0000a803, 0x0000a805, 0x0000a807, 0x0000a80a, - 0x0000a80c, 0x0000a822, 0x0000a840, 0x0000a873, - 0x0000a882, 0x0000a8b3, 0x0000a8f2, 0x0000a8f7, - 0x0000a8fb, 0x0000a8fb, 0x0000a8fd, 0x0000a8fe, - 0x0000a90a, 0x0000a925, 0x0000a930, 0x0000a946, - 0x0000a960, 0x0000a97c, 0x0000a984, 0x0000a9b2, - 0x0000a9e0, 0x0000a9e4, 0x0000a9e7, 0x0000a9ef, - 0x0000a9fa, 0x0000a9fe, 0x0000aa00, 0x0000aa28, - 0x0000aa40, 0x0000aa42, 0x0000aa44, 0x0000aa4b, - 0x0000aa60, 0x0000aa6f, 0x0000aa71, 0x0000aa76, - 0x0000aa7a, 0x0000aa7a, 0x0000aa7e, 0x0000aaaf, - 0x0000aab1, 0x0000aab1, 0x0000aab5, 0x0000aab6, - 0x0000aab9, 0x0000aabd, 0x0000aac0, 0x0000aac0, - 0x0000aac2, 0x0000aac2, 0x0000aadb, 0x0000aadc, - 0x0000aae0, 0x0000aaea, 0x0000aaf2, 0x0000aaf2, - 0x0000ab01, 0x0000ab06, 0x0000ab09, 0x0000ab0e, - 0x0000ab11, 0x0000ab16, 0x0000ab20, 0x0000ab26, - 0x0000ab28, 0x0000ab2e, 0x0000abc0, 0x0000abe2, - 0x0000ac00, 0x0000d7a3, 0x0000d7b0, 0x0000d7c6, - 0x0000d7cb, 0x0000d7fb, 0x0000f900, 0x0000fa6d, - 0x0000fa70, 0x0000fad9, 0x0000fb1d, 0x0000fb1d, - 0x0000fb1f, 0x0000fb28, 0x0000fb2a, 0x0000fb36, - 0x0000fb38, 0x0000fb3c, 0x0000fb3e, 0x0000fb3e, - 0x0000fb40, 0x0000fb41, 0x0000fb43, 0x0000fb44, - 0x0000fb46, 0x0000fbb1, 0x0000fbd3, 0x0000fd3d, - 0x0000fd50, 0x0000fd8f, 0x0000fd92, 0x0000fdc7, - 0x0000fdf0, 0x0000fdfb, 0x0000fe70, 0x0000fe74, - 0x0000fe76, 0x0000fefc, 0x0000ff66, 0x0000ff6f, - 0x0000ff71, 0x0000ff9d, 0x0000ffa0, 0x0000ffbe, - 0x0000ffc2, 0x0000ffc7, 0x0000ffca, 0x0000ffcf, - 0x0000ffd2, 0x0000ffd7, 0x0000ffda, 0x0000ffdc, - 0x00010000, 0x0001000b, 0x0001000d, 0x00010026, - 0x00010028, 0x0001003a, 0x0001003c, 0x0001003d, - 0x0001003f, 0x0001004d, 0x00010050, 0x0001005d, - 0x00010080, 0x000100fa, 0x00010280, 0x0001029c, - 0x000102a0, 0x000102d0, 0x00010300, 0x0001031f, - 0x0001032d, 0x00010340, 0x00010342, 0x00010349, - 0x00010350, 0x00010375, 0x00010380, 0x0001039d, - 0x000103a0, 0x000103c3, 0x000103c8, 0x000103cf, - 0x00010450, 0x0001049d, 0x00010500, 0x00010527, - 0x00010530, 0x00010563, 0x000105c0, 0x000105f3, - 0x00010600, 0x00010736, 0x00010740, 0x00010755, - 0x00010760, 0x00010767, 0x00010800, 0x00010805, - 0x00010808, 0x00010808, 0x0001080a, 0x00010835, - 0x00010837, 0x00010838, 0x0001083c, 0x0001083c, - 0x0001083f, 0x00010855, 0x00010860, 0x00010876, - 0x00010880, 0x0001089e, 0x000108e0, 0x000108f2, - 0x000108f4, 0x000108f5, 0x00010900, 0x00010915, - 0x00010920, 0x00010939, 0x00010980, 0x000109b7, + 0x0001e4eb, 0x0001e4eb, 0x0001e6ff, 0x0001e6ff, + 0x0001e94b, 0x0001e94b, 0x000000aa, 0x000000aa, + 0x000000ba, 0x000000ba, 0x000001bb, 0x000001bb, + 0x000001c0, 0x000001c3, 0x00000294, 0x00000295, + 0x000005d0, 0x000005ea, 0x000005ef, 0x000005f2, + 0x00000620, 0x0000063f, 0x00000641, 0x0000064a, + 0x0000066e, 0x0000066f, 0x00000671, 0x000006d3, + 0x000006d5, 0x000006d5, 0x000006ee, 0x000006ef, + 0x000006fa, 0x000006fc, 0x000006ff, 0x000006ff, + 0x00000710, 0x00000710, 0x00000712, 0x0000072f, + 0x0000074d, 0x000007a5, 0x000007b1, 0x000007b1, + 0x000007ca, 0x000007ea, 0x00000800, 0x00000815, + 0x00000840, 0x00000858, 0x00000860, 0x0000086a, + 0x00000870, 0x00000887, 0x00000889, 0x0000088f, + 0x000008a0, 0x000008c8, 0x00000904, 0x00000939, + 0x0000093d, 0x0000093d, 0x00000950, 0x00000950, + 0x00000958, 0x00000961, 0x00000972, 0x00000980, + 0x00000985, 0x0000098c, 0x0000098f, 0x00000990, + 0x00000993, 0x000009a8, 0x000009aa, 0x000009b0, + 0x000009b2, 0x000009b2, 0x000009b6, 0x000009b9, + 0x000009bd, 0x000009bd, 0x000009ce, 0x000009ce, + 0x000009dc, 0x000009dd, 0x000009df, 0x000009e1, + 0x000009f0, 0x000009f1, 0x000009fc, 0x000009fc, + 0x00000a05, 0x00000a0a, 0x00000a0f, 0x00000a10, + 0x00000a13, 0x00000a28, 0x00000a2a, 0x00000a30, + 0x00000a32, 0x00000a33, 0x00000a35, 0x00000a36, + 0x00000a38, 0x00000a39, 0x00000a59, 0x00000a5c, + 0x00000a5e, 0x00000a5e, 0x00000a72, 0x00000a74, + 0x00000a85, 0x00000a8d, 0x00000a8f, 0x00000a91, + 0x00000a93, 0x00000aa8, 0x00000aaa, 0x00000ab0, + 0x00000ab2, 0x00000ab3, 0x00000ab5, 0x00000ab9, + 0x00000abd, 0x00000abd, 0x00000ad0, 0x00000ad0, + 0x00000ae0, 0x00000ae1, 0x00000af9, 0x00000af9, + 0x00000b05, 0x00000b0c, 0x00000b0f, 0x00000b10, + 0x00000b13, 0x00000b28, 0x00000b2a, 0x00000b30, + 0x00000b32, 0x00000b33, 0x00000b35, 0x00000b39, + 0x00000b3d, 0x00000b3d, 0x00000b5c, 0x00000b5d, + 0x00000b5f, 0x00000b61, 0x00000b71, 0x00000b71, + 0x00000b83, 0x00000b83, 0x00000b85, 0x00000b8a, + 0x00000b8e, 0x00000b90, 0x00000b92, 0x00000b95, + 0x00000b99, 0x00000b9a, 0x00000b9c, 0x00000b9c, + 0x00000b9e, 0x00000b9f, 0x00000ba3, 0x00000ba4, + 0x00000ba8, 0x00000baa, 0x00000bae, 0x00000bb9, + 0x00000bd0, 0x00000bd0, 0x00000c05, 0x00000c0c, + 0x00000c0e, 0x00000c10, 0x00000c12, 0x00000c28, + 0x00000c2a, 0x00000c39, 0x00000c3d, 0x00000c3d, + 0x00000c58, 0x00000c5a, 0x00000c5c, 0x00000c5d, + 0x00000c60, 0x00000c61, 0x00000c80, 0x00000c80, + 0x00000c85, 0x00000c8c, 0x00000c8e, 0x00000c90, + 0x00000c92, 0x00000ca8, 0x00000caa, 0x00000cb3, + 0x00000cb5, 0x00000cb9, 0x00000cbd, 0x00000cbd, + 0x00000cdc, 0x00000cde, 0x00000ce0, 0x00000ce1, + 0x00000cf1, 0x00000cf2, 0x00000d04, 0x00000d0c, + 0x00000d0e, 0x00000d10, 0x00000d12, 0x00000d3a, + 0x00000d3d, 0x00000d3d, 0x00000d4e, 0x00000d4e, + 0x00000d54, 0x00000d56, 0x00000d5f, 0x00000d61, + 0x00000d7a, 0x00000d7f, 0x00000d85, 0x00000d96, + 0x00000d9a, 0x00000db1, 0x00000db3, 0x00000dbb, + 0x00000dbd, 0x00000dbd, 0x00000dc0, 0x00000dc6, + 0x00000e01, 0x00000e30, 0x00000e32, 0x00000e33, + 0x00000e40, 0x00000e45, 0x00000e81, 0x00000e82, + 0x00000e84, 0x00000e84, 0x00000e86, 0x00000e8a, + 0x00000e8c, 0x00000ea3, 0x00000ea5, 0x00000ea5, + 0x00000ea7, 0x00000eb0, 0x00000eb2, 0x00000eb3, + 0x00000ebd, 0x00000ebd, 0x00000ec0, 0x00000ec4, + 0x00000edc, 0x00000edf, 0x00000f00, 0x00000f00, + 0x00000f40, 0x00000f47, 0x00000f49, 0x00000f6c, + 0x00000f88, 0x00000f8c, 0x00001000, 0x0000102a, + 0x0000103f, 0x0000103f, 0x00001050, 0x00001055, + 0x0000105a, 0x0000105d, 0x00001061, 0x00001061, + 0x00001065, 0x00001066, 0x0000106e, 0x00001070, + 0x00001075, 0x00001081, 0x0000108e, 0x0000108e, + 0x00001100, 0x00001248, 0x0000124a, 0x0000124d, + 0x00001250, 0x00001256, 0x00001258, 0x00001258, + 0x0000125a, 0x0000125d, 0x00001260, 0x00001288, + 0x0000128a, 0x0000128d, 0x00001290, 0x000012b0, + 0x000012b2, 0x000012b5, 0x000012b8, 0x000012be, + 0x000012c0, 0x000012c0, 0x000012c2, 0x000012c5, + 0x000012c8, 0x000012d6, 0x000012d8, 0x00001310, + 0x00001312, 0x00001315, 0x00001318, 0x0000135a, + 0x00001380, 0x0000138f, 0x00001401, 0x0000166c, + 0x0000166f, 0x0000167f, 0x00001681, 0x0000169a, + 0x000016a0, 0x000016ea, 0x000016f1, 0x000016f8, + 0x00001700, 0x00001711, 0x0000171f, 0x00001731, + 0x00001740, 0x00001751, 0x00001760, 0x0000176c, + 0x0000176e, 0x00001770, 0x00001780, 0x000017b3, + 0x000017dc, 0x000017dc, 0x00001820, 0x00001842, + 0x00001844, 0x00001878, 0x00001880, 0x00001884, + 0x00001887, 0x000018a8, 0x000018aa, 0x000018aa, + 0x000018b0, 0x000018f5, 0x00001900, 0x0000191e, + 0x00001950, 0x0000196d, 0x00001970, 0x00001974, + 0x00001980, 0x000019ab, 0x000019b0, 0x000019c9, + 0x00001a00, 0x00001a16, 0x00001a20, 0x00001a54, + 0x00001b05, 0x00001b33, 0x00001b45, 0x00001b4c, + 0x00001b83, 0x00001ba0, 0x00001bae, 0x00001baf, + 0x00001bba, 0x00001be5, 0x00001c00, 0x00001c23, + 0x00001c4d, 0x00001c4f, 0x00001c5a, 0x00001c77, + 0x00001ce9, 0x00001cec, 0x00001cee, 0x00001cf3, + 0x00001cf5, 0x00001cf6, 0x00001cfa, 0x00001cfa, + 0x00002135, 0x00002138, 0x00002d30, 0x00002d67, + 0x00002d80, 0x00002d96, 0x00002da0, 0x00002da6, + 0x00002da8, 0x00002dae, 0x00002db0, 0x00002db6, + 0x00002db8, 0x00002dbe, 0x00002dc0, 0x00002dc6, + 0x00002dc8, 0x00002dce, 0x00002dd0, 0x00002dd6, + 0x00002dd8, 0x00002dde, 0x00003006, 0x00003006, + 0x0000303c, 0x0000303c, 0x00003041, 0x00003096, + 0x0000309f, 0x0000309f, 0x000030a1, 0x000030fa, + 0x000030ff, 0x000030ff, 0x00003105, 0x0000312f, + 0x00003131, 0x0000318e, 0x000031a0, 0x000031bf, + 0x000031f0, 0x000031ff, 0x00003400, 0x00004dbf, + 0x00004e00, 0x0000a014, 0x0000a016, 0x0000a48c, + 0x0000a4d0, 0x0000a4f7, 0x0000a500, 0x0000a60b, + 0x0000a610, 0x0000a61f, 0x0000a62a, 0x0000a62b, + 0x0000a66e, 0x0000a66e, 0x0000a6a0, 0x0000a6e5, + 0x0000a78f, 0x0000a78f, 0x0000a7f7, 0x0000a7f7, + 0x0000a7fb, 0x0000a801, 0x0000a803, 0x0000a805, + 0x0000a807, 0x0000a80a, 0x0000a80c, 0x0000a822, + 0x0000a840, 0x0000a873, 0x0000a882, 0x0000a8b3, + 0x0000a8f2, 0x0000a8f7, 0x0000a8fb, 0x0000a8fb, + 0x0000a8fd, 0x0000a8fe, 0x0000a90a, 0x0000a925, + 0x0000a930, 0x0000a946, 0x0000a960, 0x0000a97c, + 0x0000a984, 0x0000a9b2, 0x0000a9e0, 0x0000a9e4, + 0x0000a9e7, 0x0000a9ef, 0x0000a9fa, 0x0000a9fe, + 0x0000aa00, 0x0000aa28, 0x0000aa40, 0x0000aa42, + 0x0000aa44, 0x0000aa4b, 0x0000aa60, 0x0000aa6f, + 0x0000aa71, 0x0000aa76, 0x0000aa7a, 0x0000aa7a, + 0x0000aa7e, 0x0000aaaf, 0x0000aab1, 0x0000aab1, + 0x0000aab5, 0x0000aab6, 0x0000aab9, 0x0000aabd, + 0x0000aac0, 0x0000aac0, 0x0000aac2, 0x0000aac2, + 0x0000aadb, 0x0000aadc, 0x0000aae0, 0x0000aaea, + 0x0000aaf2, 0x0000aaf2, 0x0000ab01, 0x0000ab06, + 0x0000ab09, 0x0000ab0e, 0x0000ab11, 0x0000ab16, + 0x0000ab20, 0x0000ab26, 0x0000ab28, 0x0000ab2e, + 0x0000abc0, 0x0000abe2, 0x0000ac00, 0x0000d7a3, + 0x0000d7b0, 0x0000d7c6, 0x0000d7cb, 0x0000d7fb, + 0x0000f900, 0x0000fa6d, 0x0000fa70, 0x0000fad9, + 0x0000fb1d, 0x0000fb1d, 0x0000fb1f, 0x0000fb28, + 0x0000fb2a, 0x0000fb36, 0x0000fb38, 0x0000fb3c, + 0x0000fb3e, 0x0000fb3e, 0x0000fb40, 0x0000fb41, + 0x0000fb43, 0x0000fb44, 0x0000fb46, 0x0000fbb1, + 0x0000fbd3, 0x0000fd3d, 0x0000fd50, 0x0000fd8f, + 0x0000fd92, 0x0000fdc7, 0x0000fdf0, 0x0000fdfb, + 0x0000fe70, 0x0000fe74, 0x0000fe76, 0x0000fefc, + 0x0000ff66, 0x0000ff6f, 0x0000ff71, 0x0000ff9d, + 0x0000ffa0, 0x0000ffbe, 0x0000ffc2, 0x0000ffc7, + 0x0000ffca, 0x0000ffcf, 0x0000ffd2, 0x0000ffd7, + 0x0000ffda, 0x0000ffdc, 0x00010000, 0x0001000b, + 0x0001000d, 0x00010026, 0x00010028, 0x0001003a, + 0x0001003c, 0x0001003d, 0x0001003f, 0x0001004d, + 0x00010050, 0x0001005d, 0x00010080, 0x000100fa, + 0x00010280, 0x0001029c, 0x000102a0, 0x000102d0, + 0x00010300, 0x0001031f, 0x0001032d, 0x00010340, + 0x00010342, 0x00010349, 0x00010350, 0x00010375, + 0x00010380, 0x0001039d, 0x000103a0, 0x000103c3, + 0x000103c8, 0x000103cf, 0x00010450, 0x0001049d, + 0x00010500, 0x00010527, 0x00010530, 0x00010563, + 0x000105c0, 0x000105f3, 0x00010600, 0x00010736, + 0x00010740, 0x00010755, 0x00010760, 0x00010767, + 0x00010800, 0x00010805, 0x00010808, 0x00010808, + 0x0001080a, 0x00010835, 0x00010837, 0x00010838, + 0x0001083c, 0x0001083c, 0x0001083f, 0x00010855, + 0x00010860, 0x00010876, 0x00010880, 0x0001089e, + 0x000108e0, 0x000108f2, 0x000108f4, 0x000108f5, + 0x00010900, 0x00010915, 0x00010920, 0x00010939, + 0x00010940, 0x00010959, 0x00010980, 0x000109b7, 0x000109be, 0x000109bf, 0x00010a00, 0x00010a00, 0x00010a10, 0x00010a13, 0x00010a15, 0x00010a17, 0x00010a19, 0x00010a35, 0x00010a60, 0x00010a7c, @@ -1253,97 +1265,101 @@ static const unsigned int _ucprop_ranges[] = { 0x00010d00, 0x00010d23, 0x00010d4a, 0x00010d4d, 0x00010d4f, 0x00010d4f, 0x00010e80, 0x00010ea9, 0x00010eb0, 0x00010eb1, 0x00010ec2, 0x00010ec4, - 0x00010f00, 0x00010f1c, 0x00010f27, 0x00010f27, - 0x00010f30, 0x00010f45, 0x00010f70, 0x00010f81, - 0x00010fb0, 0x00010fc4, 0x00010fe0, 0x00010ff6, - 0x00011003, 0x00011037, 0x00011071, 0x00011072, - 0x00011075, 0x00011075, 0x00011083, 0x000110af, - 0x000110d0, 0x000110e8, 0x00011103, 0x00011126, - 0x00011144, 0x00011144, 0x00011147, 0x00011147, - 0x00011150, 0x00011172, 0x00011176, 0x00011176, - 0x00011183, 0x000111b2, 0x000111c1, 0x000111c4, - 0x000111da, 0x000111da, 0x000111dc, 0x000111dc, - 0x00011200, 0x00011211, 0x00011213, 0x0001122b, - 0x0001123f, 0x00011240, 0x00011280, 0x00011286, - 0x00011288, 0x00011288, 0x0001128a, 0x0001128d, - 0x0001128f, 0x0001129d, 0x0001129f, 0x000112a8, - 0x000112b0, 0x000112de, 0x00011305, 0x0001130c, - 0x0001130f, 0x00011310, 0x00011313, 0x00011328, - 0x0001132a, 0x00011330, 0x00011332, 0x00011333, - 0x00011335, 0x00011339, 0x0001133d, 0x0001133d, - 0x00011350, 0x00011350, 0x0001135d, 0x00011361, - 0x00011380, 0x00011389, 0x0001138b, 0x0001138b, - 0x0001138e, 0x0001138e, 0x00011390, 0x000113b5, - 0x000113b7, 0x000113b7, 0x000113d1, 0x000113d1, - 0x000113d3, 0x000113d3, 0x00011400, 0x00011434, - 0x00011447, 0x0001144a, 0x0001145f, 0x00011461, - 0x00011480, 0x000114af, 0x000114c4, 0x000114c5, - 0x000114c7, 0x000114c7, 0x00011580, 0x000115ae, - 0x000115d8, 0x000115db, 0x00011600, 0x0001162f, - 0x00011644, 0x00011644, 0x00011680, 0x000116aa, - 0x000116b8, 0x000116b8, 0x00011700, 0x0001171a, - 0x00011740, 0x00011746, 0x00011800, 0x0001182b, - 0x000118ff, 0x00011906, 0x00011909, 0x00011909, - 0x0001190c, 0x00011913, 0x00011915, 0x00011916, - 0x00011918, 0x0001192f, 0x0001193f, 0x0001193f, - 0x00011941, 0x00011941, 0x000119a0, 0x000119a7, - 0x000119aa, 0x000119d0, 0x000119e1, 0x000119e1, - 0x000119e3, 0x000119e3, 0x00011a00, 0x00011a00, - 0x00011a0b, 0x00011a32, 0x00011a3a, 0x00011a3a, - 0x00011a50, 0x00011a50, 0x00011a5c, 0x00011a89, - 0x00011a9d, 0x00011a9d, 0x00011ab0, 0x00011af8, - 0x00011bc0, 0x00011be0, 0x00011c00, 0x00011c08, - 0x00011c0a, 0x00011c2e, 0x00011c40, 0x00011c40, - 0x00011c72, 0x00011c8f, 0x00011d00, 0x00011d06, - 0x00011d08, 0x00011d09, 0x00011d0b, 0x00011d30, - 0x00011d46, 0x00011d46, 0x00011d60, 0x00011d65, - 0x00011d67, 0x00011d68, 0x00011d6a, 0x00011d89, - 0x00011d98, 0x00011d98, 0x00011ee0, 0x00011ef2, - 0x00011f02, 0x00011f02, 0x00011f04, 0x00011f10, - 0x00011f12, 0x00011f33, 0x00011fb0, 0x00011fb0, - 0x00012000, 0x00012399, 0x00012480, 0x00012543, - 0x00012f90, 0x00012ff0, 0x00013000, 0x0001342f, - 0x00013441, 0x00013446, 0x00013460, 0x000143fa, - 0x00014400, 0x00014646, 0x00016100, 0x0001611d, - 0x00016800, 0x00016a38, 0x00016a40, 0x00016a5e, - 0x00016a70, 0x00016abe, 0x00016ad0, 0x00016aed, - 0x00016b00, 0x00016b2f, 0x00016b63, 0x00016b77, - 0x00016b7d, 0x00016b8f, 0x00016d43, 0x00016d6a, - 0x00016f00, 0x00016f4a, 0x00016f50, 0x00016f50, - 0x00017000, 0x000187f7, 0x00018800, 0x00018cd5, - 0x00018cff, 0x00018d08, 0x0001b000, 0x0001b122, - 0x0001b132, 0x0001b132, 0x0001b150, 0x0001b152, - 0x0001b155, 0x0001b155, 0x0001b164, 0x0001b167, - 0x0001b170, 0x0001b2fb, 0x0001bc00, 0x0001bc6a, - 0x0001bc70, 0x0001bc7c, 0x0001bc80, 0x0001bc88, - 0x0001bc90, 0x0001bc99, 0x0001df0a, 0x0001df0a, - 0x0001e100, 0x0001e12c, 0x0001e14e, 0x0001e14e, - 0x0001e290, 0x0001e2ad, 0x0001e2c0, 0x0001e2eb, - 0x0001e4d0, 0x0001e4ea, 0x0001e5d0, 0x0001e5ed, - 0x0001e5f0, 0x0001e5f0, 0x0001e7e0, 0x0001e7e6, - 0x0001e7e8, 0x0001e7eb, 0x0001e7ed, 0x0001e7ee, - 0x0001e7f0, 0x0001e7fe, 0x0001e800, 0x0001e8c4, - 0x0001ee00, 0x0001ee03, 0x0001ee05, 0x0001ee1f, - 0x0001ee21, 0x0001ee22, 0x0001ee24, 0x0001ee24, - 0x0001ee27, 0x0001ee27, 0x0001ee29, 0x0001ee32, - 0x0001ee34, 0x0001ee37, 0x0001ee39, 0x0001ee39, - 0x0001ee3b, 0x0001ee3b, 0x0001ee42, 0x0001ee42, - 0x0001ee47, 0x0001ee47, 0x0001ee49, 0x0001ee49, - 0x0001ee4b, 0x0001ee4b, 0x0001ee4d, 0x0001ee4f, - 0x0001ee51, 0x0001ee52, 0x0001ee54, 0x0001ee54, - 0x0001ee57, 0x0001ee57, 0x0001ee59, 0x0001ee59, - 0x0001ee5b, 0x0001ee5b, 0x0001ee5d, 0x0001ee5d, - 0x0001ee5f, 0x0001ee5f, 0x0001ee61, 0x0001ee62, - 0x0001ee64, 0x0001ee64, 0x0001ee67, 0x0001ee6a, - 0x0001ee6c, 0x0001ee72, 0x0001ee74, 0x0001ee77, - 0x0001ee79, 0x0001ee7c, 0x0001ee7e, 0x0001ee7e, - 0x0001ee80, 0x0001ee89, 0x0001ee8b, 0x0001ee9b, - 0x0001eea1, 0x0001eea3, 0x0001eea5, 0x0001eea9, - 0x0001eeab, 0x0001eebb, 0x00020000, 0x0002a6df, - 0x0002a700, 0x0002b739, 0x0002b740, 0x0002b81d, - 0x0002b820, 0x0002cea1, 0x0002ceb0, 0x0002ebe0, + 0x00010ec6, 0x00010ec7, 0x00010f00, 0x00010f1c, + 0x00010f27, 0x00010f27, 0x00010f30, 0x00010f45, + 0x00010f70, 0x00010f81, 0x00010fb0, 0x00010fc4, + 0x00010fe0, 0x00010ff6, 0x00011003, 0x00011037, + 0x00011071, 0x00011072, 0x00011075, 0x00011075, + 0x00011083, 0x000110af, 0x000110d0, 0x000110e8, + 0x00011103, 0x00011126, 0x00011144, 0x00011144, + 0x00011147, 0x00011147, 0x00011150, 0x00011172, + 0x00011176, 0x00011176, 0x00011183, 0x000111b2, + 0x000111c1, 0x000111c4, 0x000111da, 0x000111da, + 0x000111dc, 0x000111dc, 0x00011200, 0x00011211, + 0x00011213, 0x0001122b, 0x0001123f, 0x00011240, + 0x00011280, 0x00011286, 0x00011288, 0x00011288, + 0x0001128a, 0x0001128d, 0x0001128f, 0x0001129d, + 0x0001129f, 0x000112a8, 0x000112b0, 0x000112de, + 0x00011305, 0x0001130c, 0x0001130f, 0x00011310, + 0x00011313, 0x00011328, 0x0001132a, 0x00011330, + 0x00011332, 0x00011333, 0x00011335, 0x00011339, + 0x0001133d, 0x0001133d, 0x00011350, 0x00011350, + 0x0001135d, 0x00011361, 0x00011380, 0x00011389, + 0x0001138b, 0x0001138b, 0x0001138e, 0x0001138e, + 0x00011390, 0x000113b5, 0x000113b7, 0x000113b7, + 0x000113d1, 0x000113d1, 0x000113d3, 0x000113d3, + 0x00011400, 0x00011434, 0x00011447, 0x0001144a, + 0x0001145f, 0x00011461, 0x00011480, 0x000114af, + 0x000114c4, 0x000114c5, 0x000114c7, 0x000114c7, + 0x00011580, 0x000115ae, 0x000115d8, 0x000115db, + 0x00011600, 0x0001162f, 0x00011644, 0x00011644, + 0x00011680, 0x000116aa, 0x000116b8, 0x000116b8, + 0x00011700, 0x0001171a, 0x00011740, 0x00011746, + 0x00011800, 0x0001182b, 0x000118ff, 0x00011906, + 0x00011909, 0x00011909, 0x0001190c, 0x00011913, + 0x00011915, 0x00011916, 0x00011918, 0x0001192f, + 0x0001193f, 0x0001193f, 0x00011941, 0x00011941, + 0x000119a0, 0x000119a7, 0x000119aa, 0x000119d0, + 0x000119e1, 0x000119e1, 0x000119e3, 0x000119e3, + 0x00011a00, 0x00011a00, 0x00011a0b, 0x00011a32, + 0x00011a3a, 0x00011a3a, 0x00011a50, 0x00011a50, + 0x00011a5c, 0x00011a89, 0x00011a9d, 0x00011a9d, + 0x00011ab0, 0x00011af8, 0x00011bc0, 0x00011be0, + 0x00011c00, 0x00011c08, 0x00011c0a, 0x00011c2e, + 0x00011c40, 0x00011c40, 0x00011c72, 0x00011c8f, + 0x00011d00, 0x00011d06, 0x00011d08, 0x00011d09, + 0x00011d0b, 0x00011d30, 0x00011d46, 0x00011d46, + 0x00011d60, 0x00011d65, 0x00011d67, 0x00011d68, + 0x00011d6a, 0x00011d89, 0x00011d98, 0x00011d98, + 0x00011db0, 0x00011dd8, 0x00011dda, 0x00011ddb, + 0x00011ee0, 0x00011ef2, 0x00011f02, 0x00011f02, + 0x00011f04, 0x00011f10, 0x00011f12, 0x00011f33, + 0x00011fb0, 0x00011fb0, 0x00012000, 0x00012399, + 0x00012480, 0x00012543, 0x00012f90, 0x00012ff0, + 0x00013000, 0x0001342f, 0x00013441, 0x00013446, + 0x00013460, 0x000143fa, 0x00014400, 0x00014646, + 0x00016100, 0x0001611d, 0x00016800, 0x00016a38, + 0x00016a40, 0x00016a5e, 0x00016a70, 0x00016abe, + 0x00016ad0, 0x00016aed, 0x00016b00, 0x00016b2f, + 0x00016b63, 0x00016b77, 0x00016b7d, 0x00016b8f, + 0x00016d43, 0x00016d6a, 0x00016f00, 0x00016f4a, + 0x00016f50, 0x00016f50, 0x00017000, 0x00018cd5, + 0x00018cff, 0x00018d1e, 0x00018d80, 0x00018df2, + 0x0001b000, 0x0001b122, 0x0001b132, 0x0001b132, + 0x0001b150, 0x0001b152, 0x0001b155, 0x0001b155, + 0x0001b164, 0x0001b167, 0x0001b170, 0x0001b2fb, + 0x0001bc00, 0x0001bc6a, 0x0001bc70, 0x0001bc7c, + 0x0001bc80, 0x0001bc88, 0x0001bc90, 0x0001bc99, + 0x0001df0a, 0x0001df0a, 0x0001e100, 0x0001e12c, + 0x0001e14e, 0x0001e14e, 0x0001e290, 0x0001e2ad, + 0x0001e2c0, 0x0001e2eb, 0x0001e4d0, 0x0001e4ea, + 0x0001e5d0, 0x0001e5ed, 0x0001e5f0, 0x0001e5f0, + 0x0001e6c0, 0x0001e6de, 0x0001e6e0, 0x0001e6e2, + 0x0001e6e4, 0x0001e6e5, 0x0001e6e7, 0x0001e6ed, + 0x0001e6f0, 0x0001e6f4, 0x0001e6fe, 0x0001e6fe, + 0x0001e7e0, 0x0001e7e6, 0x0001e7e8, 0x0001e7eb, + 0x0001e7ed, 0x0001e7ee, 0x0001e7f0, 0x0001e7fe, + 0x0001e800, 0x0001e8c4, 0x0001ee00, 0x0001ee03, + 0x0001ee05, 0x0001ee1f, 0x0001ee21, 0x0001ee22, + 0x0001ee24, 0x0001ee24, 0x0001ee27, 0x0001ee27, + 0x0001ee29, 0x0001ee32, 0x0001ee34, 0x0001ee37, + 0x0001ee39, 0x0001ee39, 0x0001ee3b, 0x0001ee3b, + 0x0001ee42, 0x0001ee42, 0x0001ee47, 0x0001ee47, + 0x0001ee49, 0x0001ee49, 0x0001ee4b, 0x0001ee4b, + 0x0001ee4d, 0x0001ee4f, 0x0001ee51, 0x0001ee52, + 0x0001ee54, 0x0001ee54, 0x0001ee57, 0x0001ee57, + 0x0001ee59, 0x0001ee59, 0x0001ee5b, 0x0001ee5b, + 0x0001ee5d, 0x0001ee5d, 0x0001ee5f, 0x0001ee5f, + 0x0001ee61, 0x0001ee62, 0x0001ee64, 0x0001ee64, + 0x0001ee67, 0x0001ee6a, 0x0001ee6c, 0x0001ee72, + 0x0001ee74, 0x0001ee77, 0x0001ee79, 0x0001ee7c, + 0x0001ee7e, 0x0001ee7e, 0x0001ee80, 0x0001ee89, + 0x0001ee8b, 0x0001ee9b, 0x0001eea1, 0x0001eea3, + 0x0001eea5, 0x0001eea9, 0x0001eeab, 0x0001eebb, + 0x00020000, 0x0002a6df, 0x0002a700, 0x0002b81d, + 0x0002b820, 0x0002cead, 0x0002ceb0, 0x0002ebe0, 0x0002ebf0, 0x0002ee5d, 0x0002f800, 0x0002fa1d, - 0x00030000, 0x0003134a, 0x00031350, 0x000323af, + 0x00030000, 0x0003134a, 0x00031350, 0x00033479, 0x0000002b, 0x0000002b, 0x0000003c, 0x0000003e, 0x0000007c, 0x0000007c, 0x0000007e, 0x0000007e, 0x000000ac, 0x000000ac, 0x000000b1, 0x000000b1, @@ -1371,18 +1387,19 @@ static const unsigned int _ucprop_ranges[] = { 0x0000ff1c, 0x0000ff1e, 0x0000ff5c, 0x0000ff5c, 0x0000ff5e, 0x0000ff5e, 0x0000ffe2, 0x0000ffe2, 0x0000ffe9, 0x0000ffec, 0x00010d8e, 0x00010d8f, - 0x0001d6c1, 0x0001d6c1, 0x0001d6db, 0x0001d6db, - 0x0001d6fb, 0x0001d6fb, 0x0001d715, 0x0001d715, - 0x0001d735, 0x0001d735, 0x0001d74f, 0x0001d74f, - 0x0001d76f, 0x0001d76f, 0x0001d789, 0x0001d789, - 0x0001d7a9, 0x0001d7a9, 0x0001d7c3, 0x0001d7c3, - 0x0001eef0, 0x0001eef1, 0x00000024, 0x00000024, + 0x0001cef0, 0x0001cef0, 0x0001d6c1, 0x0001d6c1, + 0x0001d6db, 0x0001d6db, 0x0001d6fb, 0x0001d6fb, + 0x0001d715, 0x0001d715, 0x0001d735, 0x0001d735, + 0x0001d74f, 0x0001d74f, 0x0001d76f, 0x0001d76f, + 0x0001d789, 0x0001d789, 0x0001d7a9, 0x0001d7a9, + 0x0001d7c3, 0x0001d7c3, 0x0001eef0, 0x0001eef1, + 0x0001f8d0, 0x0001f8d8, 0x00000024, 0x00000024, 0x000000a2, 0x000000a5, 0x0000058f, 0x0000058f, 0x0000060b, 0x0000060b, 0x000007fe, 0x000007ff, 0x000009f2, 0x000009f3, 0x000009fb, 0x000009fb, 0x00000af1, 0x00000af1, 0x00000bf9, 0x00000bf9, 0x00000e3f, 0x00000e3f, 0x000017db, 0x000017db, - 0x000020a0, 0x000020c0, 0x0000a838, 0x0000a838, + 0x000020a0, 0x000020c1, 0x0000a838, 0x0000a838, 0x0000fdfc, 0x0000fdfc, 0x0000fe69, 0x0000fe69, 0x0000ff04, 0x0000ff04, 0x0000ffe0, 0x0000ffe1, 0x0000ffe5, 0x0000ffe6, 0x00011fdd, 0x00011fe0, @@ -1442,60 +1459,63 @@ static const unsigned int _ucprop_ranges[] = { 0x00002670, 0x00002767, 0x00002794, 0x000027bf, 0x00002800, 0x000028ff, 0x00002b00, 0x00002b2f, 0x00002b45, 0x00002b46, 0x00002b4d, 0x00002b73, - 0x00002b76, 0x00002b95, 0x00002b97, 0x00002bff, - 0x00002ce5, 0x00002cea, 0x00002e50, 0x00002e51, - 0x00002e80, 0x00002e99, 0x00002e9b, 0x00002ef3, - 0x00002f00, 0x00002fd5, 0x00002ff0, 0x00002fff, - 0x00003004, 0x00003004, 0x00003012, 0x00003013, - 0x00003020, 0x00003020, 0x00003036, 0x00003037, - 0x0000303e, 0x0000303f, 0x00003190, 0x00003191, - 0x00003196, 0x0000319f, 0x000031c0, 0x000031e5, - 0x000031ef, 0x000031ef, 0x00003200, 0x0000321e, - 0x0000322a, 0x00003247, 0x00003250, 0x00003250, - 0x00003260, 0x0000327f, 0x0000328a, 0x000032b0, - 0x000032c0, 0x000033ff, 0x00004dc0, 0x00004dff, - 0x0000a490, 0x0000a4c6, 0x0000a828, 0x0000a82b, - 0x0000a836, 0x0000a837, 0x0000a839, 0x0000a839, - 0x0000aa77, 0x0000aa79, 0x0000fd40, 0x0000fd4f, - 0x0000fdcf, 0x0000fdcf, 0x0000fdfd, 0x0000fdff, - 0x0000ffe4, 0x0000ffe4, 0x0000ffe8, 0x0000ffe8, - 0x0000ffed, 0x0000ffee, 0x0000fffc, 0x0000fffd, - 0x00010137, 0x0001013f, 0x00010179, 0x00010189, - 0x0001018c, 0x0001018e, 0x00010190, 0x0001019c, - 0x000101a0, 0x000101a0, 0x000101d0, 0x000101fc, - 0x00010877, 0x00010878, 0x00010ac8, 0x00010ac8, + 0x00002b76, 0x00002bff, 0x00002ce5, 0x00002cea, + 0x00002e50, 0x00002e51, 0x00002e80, 0x00002e99, + 0x00002e9b, 0x00002ef3, 0x00002f00, 0x00002fd5, + 0x00002ff0, 0x00002fff, 0x00003004, 0x00003004, + 0x00003012, 0x00003013, 0x00003020, 0x00003020, + 0x00003036, 0x00003037, 0x0000303e, 0x0000303f, + 0x00003190, 0x00003191, 0x00003196, 0x0000319f, + 0x000031c0, 0x000031e5, 0x000031ef, 0x000031ef, + 0x00003200, 0x0000321e, 0x0000322a, 0x00003247, + 0x00003250, 0x00003250, 0x00003260, 0x0000327f, + 0x0000328a, 0x000032b0, 0x000032c0, 0x000033ff, + 0x00004dc0, 0x00004dff, 0x0000a490, 0x0000a4c6, + 0x0000a828, 0x0000a82b, 0x0000a836, 0x0000a837, + 0x0000a839, 0x0000a839, 0x0000aa77, 0x0000aa79, + 0x0000fbc3, 0x0000fbd2, 0x0000fd40, 0x0000fd4f, + 0x0000fd90, 0x0000fd91, 0x0000fdc8, 0x0000fdcf, + 0x0000fdfd, 0x0000fdff, 0x0000ffe4, 0x0000ffe4, + 0x0000ffe8, 0x0000ffe8, 0x0000ffed, 0x0000ffee, + 0x0000fffc, 0x0000fffd, 0x00010137, 0x0001013f, + 0x00010179, 0x00010189, 0x0001018c, 0x0001018e, + 0x00010190, 0x0001019c, 0x000101a0, 0x000101a0, + 0x000101d0, 0x000101fc, 0x00010877, 0x00010878, + 0x00010ac8, 0x00010ac8, 0x00010ed1, 0x00010ed8, 0x0001173f, 0x0001173f, 0x00011fd5, 0x00011fdc, 0x00011fe1, 0x00011ff1, 0x00016b3c, 0x00016b3f, 0x00016b45, 0x00016b45, 0x0001bc9c, 0x0001bc9c, - 0x0001cc00, 0x0001ccef, 0x0001cd00, 0x0001ceb3, - 0x0001cf50, 0x0001cfc3, 0x0001d000, 0x0001d0f5, - 0x0001d100, 0x0001d126, 0x0001d129, 0x0001d164, - 0x0001d16a, 0x0001d16c, 0x0001d183, 0x0001d184, - 0x0001d18c, 0x0001d1a9, 0x0001d1ae, 0x0001d1ea, - 0x0001d200, 0x0001d241, 0x0001d245, 0x0001d245, - 0x0001d300, 0x0001d356, 0x0001d800, 0x0001d9ff, - 0x0001da37, 0x0001da3a, 0x0001da6d, 0x0001da74, - 0x0001da76, 0x0001da83, 0x0001da85, 0x0001da86, - 0x0001e14f, 0x0001e14f, 0x0001ecac, 0x0001ecac, - 0x0001ed2e, 0x0001ed2e, 0x0001f000, 0x0001f02b, - 0x0001f030, 0x0001f093, 0x0001f0a0, 0x0001f0ae, - 0x0001f0b1, 0x0001f0bf, 0x0001f0c1, 0x0001f0cf, - 0x0001f0d1, 0x0001f0f5, 0x0001f10d, 0x0001f1ad, - 0x0001f1e6, 0x0001f202, 0x0001f210, 0x0001f23b, - 0x0001f240, 0x0001f248, 0x0001f250, 0x0001f251, - 0x0001f260, 0x0001f265, 0x0001f300, 0x0001f3fa, - 0x0001f400, 0x0001f6d7, 0x0001f6dc, 0x0001f6ec, - 0x0001f6f0, 0x0001f6fc, 0x0001f700, 0x0001f776, - 0x0001f77b, 0x0001f7d9, 0x0001f7e0, 0x0001f7eb, + 0x0001cc00, 0x0001ccef, 0x0001ccfa, 0x0001ccfc, + 0x0001cd00, 0x0001ceb3, 0x0001ceba, 0x0001ced0, + 0x0001cee0, 0x0001ceef, 0x0001cf50, 0x0001cfc3, + 0x0001d000, 0x0001d0f5, 0x0001d100, 0x0001d126, + 0x0001d129, 0x0001d164, 0x0001d16a, 0x0001d16c, + 0x0001d183, 0x0001d184, 0x0001d18c, 0x0001d1a9, + 0x0001d1ae, 0x0001d1ea, 0x0001d200, 0x0001d241, + 0x0001d245, 0x0001d245, 0x0001d300, 0x0001d356, + 0x0001d800, 0x0001d9ff, 0x0001da37, 0x0001da3a, + 0x0001da6d, 0x0001da74, 0x0001da76, 0x0001da83, + 0x0001da85, 0x0001da86, 0x0001e14f, 0x0001e14f, + 0x0001ecac, 0x0001ecac, 0x0001ed2e, 0x0001ed2e, + 0x0001f000, 0x0001f02b, 0x0001f030, 0x0001f093, + 0x0001f0a0, 0x0001f0ae, 0x0001f0b1, 0x0001f0bf, + 0x0001f0c1, 0x0001f0cf, 0x0001f0d1, 0x0001f0f5, + 0x0001f10d, 0x0001f1ad, 0x0001f1e6, 0x0001f202, + 0x0001f210, 0x0001f23b, 0x0001f240, 0x0001f248, + 0x0001f250, 0x0001f251, 0x0001f260, 0x0001f265, + 0x0001f300, 0x0001f3fa, 0x0001f400, 0x0001f6d8, + 0x0001f6dc, 0x0001f6ec, 0x0001f6f0, 0x0001f6fc, + 0x0001f700, 0x0001f7d9, 0x0001f7e0, 0x0001f7eb, 0x0001f7f0, 0x0001f7f0, 0x0001f800, 0x0001f80b, 0x0001f810, 0x0001f847, 0x0001f850, 0x0001f859, 0x0001f860, 0x0001f887, 0x0001f890, 0x0001f8ad, 0x0001f8b0, 0x0001f8bb, 0x0001f8c0, 0x0001f8c1, - 0x0001f900, 0x0001fa53, 0x0001fa60, 0x0001fa6d, - 0x0001fa70, 0x0001fa7c, 0x0001fa80, 0x0001fa89, - 0x0001fa8f, 0x0001fac6, 0x0001face, 0x0001fadc, - 0x0001fadf, 0x0001fae9, 0x0001faf0, 0x0001faf8, - 0x0001fb00, 0x0001fb92, 0x0001fb94, 0x0001fbef, + 0x0001f900, 0x0001fa57, 0x0001fa60, 0x0001fa6d, + 0x0001fa70, 0x0001fa7c, 0x0001fa80, 0x0001fa8a, + 0x0001fa8e, 0x0001fac6, 0x0001fac8, 0x0001fac8, + 0x0001facd, 0x0001fadc, 0x0001fadf, 0x0001faea, + 0x0001faef, 0x0001faf8, 0x0001fb00, 0x0001fb92, + 0x0001fb94, 0x0001fbef, 0x0001fbfa, 0x0001fbfa, 0x00000041, 0x0000005a, 0x00000061, 0x0000007a, 0x000000aa, 0x000000aa, 0x000000b5, 0x000000b5, 0x000000ba, 0x000000ba, 0x000000c0, 0x000000d6, @@ -1554,14 +1574,14 @@ static const unsigned int _ucprop_ranges[] = { 0x00000c05, 0x00000c0c, 0x00000c0e, 0x00000c10, 0x00000c12, 0x00000c28, 0x00000c2a, 0x00000c39, 0x00000c3d, 0x00000c3d, 0x00000c41, 0x00000c44, - 0x00000c58, 0x00000c5a, 0x00000c5d, 0x00000c5d, + 0x00000c58, 0x00000c5a, 0x00000c5c, 0x00000c5d, 0x00000c60, 0x00000c61, 0x00000c66, 0x00000c6f, 0x00000c77, 0x00000c77, 0x00000c7f, 0x00000c80, 0x00000c82, 0x00000c8c, 0x00000c8e, 0x00000c90, 0x00000c92, 0x00000ca8, 0x00000caa, 0x00000cb3, 0x00000cb5, 0x00000cb9, 0x00000cbd, 0x00000cc4, 0x00000cc6, 0x00000cc8, 0x00000cca, 0x00000ccb, - 0x00000cd5, 0x00000cd6, 0x00000cdd, 0x00000cde, + 0x00000cd5, 0x00000cd6, 0x00000cdc, 0x00000cde, 0x00000ce0, 0x00000ce1, 0x00000ce6, 0x00000cef, 0x00000cf1, 0x00000cf3, 0x00000d02, 0x00000d0c, 0x00000d0e, 0x00000d10, 0x00000d12, 0x00000d3a, @@ -1683,123 +1703,123 @@ static const unsigned int _ucprop_ranges[] = { 0x0000a4d0, 0x0000a60c, 0x0000a610, 0x0000a62b, 0x0000a640, 0x0000a66e, 0x0000a680, 0x0000a69d, 0x0000a6a0, 0x0000a6ef, 0x0000a6f2, 0x0000a6f7, - 0x0000a722, 0x0000a787, 0x0000a789, 0x0000a7cd, - 0x0000a7d0, 0x0000a7d1, 0x0000a7d3, 0x0000a7d3, - 0x0000a7d5, 0x0000a7dc, 0x0000a7f2, 0x0000a801, - 0x0000a803, 0x0000a805, 0x0000a807, 0x0000a80a, - 0x0000a80c, 0x0000a824, 0x0000a827, 0x0000a827, - 0x0000a830, 0x0000a837, 0x0000a840, 0x0000a873, - 0x0000a880, 0x0000a8c3, 0x0000a8ce, 0x0000a8d9, - 0x0000a8f2, 0x0000a8fe, 0x0000a900, 0x0000a925, - 0x0000a92e, 0x0000a946, 0x0000a952, 0x0000a953, - 0x0000a95f, 0x0000a97c, 0x0000a983, 0x0000a9b2, - 0x0000a9b4, 0x0000a9b5, 0x0000a9ba, 0x0000a9bb, - 0x0000a9be, 0x0000a9cd, 0x0000a9cf, 0x0000a9d9, - 0x0000a9de, 0x0000a9e4, 0x0000a9e6, 0x0000a9fe, - 0x0000aa00, 0x0000aa28, 0x0000aa2f, 0x0000aa30, - 0x0000aa33, 0x0000aa34, 0x0000aa40, 0x0000aa42, - 0x0000aa44, 0x0000aa4b, 0x0000aa4d, 0x0000aa4d, - 0x0000aa50, 0x0000aa59, 0x0000aa5c, 0x0000aa7b, - 0x0000aa7d, 0x0000aaaf, 0x0000aab1, 0x0000aab1, - 0x0000aab5, 0x0000aab6, 0x0000aab9, 0x0000aabd, - 0x0000aac0, 0x0000aac0, 0x0000aac2, 0x0000aac2, - 0x0000aadb, 0x0000aaeb, 0x0000aaee, 0x0000aaf5, - 0x0000ab01, 0x0000ab06, 0x0000ab09, 0x0000ab0e, - 0x0000ab11, 0x0000ab16, 0x0000ab20, 0x0000ab26, - 0x0000ab28, 0x0000ab2e, 0x0000ab30, 0x0000ab69, - 0x0000ab70, 0x0000abe4, 0x0000abe6, 0x0000abe7, - 0x0000abe9, 0x0000abec, 0x0000abf0, 0x0000abf9, - 0x0000ac00, 0x0000d7a3, 0x0000d7b0, 0x0000d7c6, - 0x0000d7cb, 0x0000d7fb, 0x0000d800, 0x0000fa6d, - 0x0000fa70, 0x0000fad9, 0x0000fb00, 0x0000fb06, - 0x0000fb13, 0x0000fb17, 0x0000ff21, 0x0000ff3a, - 0x0000ff41, 0x0000ff5a, 0x0000ff66, 0x0000ffbe, - 0x0000ffc2, 0x0000ffc7, 0x0000ffca, 0x0000ffcf, - 0x0000ffd2, 0x0000ffd7, 0x0000ffda, 0x0000ffdc, - 0x00010000, 0x0001000b, 0x0001000d, 0x00010026, - 0x00010028, 0x0001003a, 0x0001003c, 0x0001003d, - 0x0001003f, 0x0001004d, 0x00010050, 0x0001005d, - 0x00010080, 0x000100fa, 0x00010100, 0x00010100, - 0x00010102, 0x00010102, 0x00010107, 0x00010133, - 0x00010137, 0x0001013f, 0x0001018d, 0x0001018e, - 0x000101d0, 0x000101fc, 0x00010280, 0x0001029c, - 0x000102a0, 0x000102d0, 0x00010300, 0x00010323, - 0x0001032d, 0x0001034a, 0x00010350, 0x00010375, - 0x00010380, 0x0001039d, 0x0001039f, 0x000103c3, - 0x000103c8, 0x000103d5, 0x00010400, 0x0001049d, - 0x000104a0, 0x000104a9, 0x000104b0, 0x000104d3, - 0x000104d8, 0x000104fb, 0x00010500, 0x00010527, - 0x00010530, 0x00010563, 0x0001056f, 0x0001057a, - 0x0001057c, 0x0001058a, 0x0001058c, 0x00010592, - 0x00010594, 0x00010595, 0x00010597, 0x000105a1, - 0x000105a3, 0x000105b1, 0x000105b3, 0x000105b9, - 0x000105bb, 0x000105bc, 0x000105c0, 0x000105f3, - 0x00010600, 0x00010736, 0x00010740, 0x00010755, - 0x00010760, 0x00010767, 0x00010780, 0x00010785, - 0x00010787, 0x000107b0, 0x000107b2, 0x000107ba, - 0x00011000, 0x00011000, 0x00011002, 0x00011037, - 0x00011047, 0x0001104d, 0x00011066, 0x0001106f, - 0x00011071, 0x00011072, 0x00011075, 0x00011075, - 0x00011082, 0x000110b2, 0x000110b7, 0x000110b8, - 0x000110bb, 0x000110c1, 0x000110cd, 0x000110cd, - 0x000110d0, 0x000110e8, 0x000110f0, 0x000110f9, - 0x00011103, 0x00011126, 0x0001112c, 0x0001112c, - 0x00011136, 0x00011147, 0x00011150, 0x00011172, - 0x00011174, 0x00011176, 0x00011182, 0x000111b5, - 0x000111bf, 0x000111c8, 0x000111cd, 0x000111ce, - 0x000111d0, 0x000111df, 0x000111e1, 0x000111f4, - 0x00011200, 0x00011211, 0x00011213, 0x0001122e, - 0x00011232, 0x00011233, 0x00011235, 0x00011235, - 0x00011238, 0x0001123d, 0x0001123f, 0x00011240, - 0x00011280, 0x00011286, 0x00011288, 0x00011288, - 0x0001128a, 0x0001128d, 0x0001128f, 0x0001129d, - 0x0001129f, 0x000112a9, 0x000112b0, 0x000112de, - 0x000112e0, 0x000112e2, 0x000112f0, 0x000112f9, - 0x00011302, 0x00011303, 0x00011305, 0x0001130c, - 0x0001130f, 0x00011310, 0x00011313, 0x00011328, - 0x0001132a, 0x00011330, 0x00011332, 0x00011333, - 0x00011335, 0x00011339, 0x0001133d, 0x0001133f, - 0x00011341, 0x00011344, 0x00011347, 0x00011348, - 0x0001134b, 0x0001134d, 0x00011350, 0x00011350, - 0x00011357, 0x00011357, 0x0001135d, 0x00011363, - 0x00011380, 0x00011389, 0x0001138b, 0x0001138b, - 0x0001138e, 0x0001138e, 0x00011390, 0x000113b5, - 0x000113b7, 0x000113ba, 0x000113c2, 0x000113c2, - 0x000113c5, 0x000113c5, 0x000113c7, 0x000113ca, - 0x000113cc, 0x000113cd, 0x000113cf, 0x000113cf, - 0x000113d1, 0x000113d1, 0x000113d3, 0x000113d5, - 0x000113d7, 0x000113d8, 0x00011400, 0x00011437, - 0x00011440, 0x00011441, 0x00011445, 0x00011445, - 0x00011447, 0x0001145b, 0x0001145d, 0x0001145d, - 0x0001145f, 0x00011461, 0x00011480, 0x000114b2, - 0x000114b9, 0x000114b9, 0x000114bb, 0x000114be, - 0x000114c1, 0x000114c1, 0x000114c4, 0x000114c7, - 0x000114d0, 0x000114d9, 0x00011580, 0x000115b1, - 0x000115b8, 0x000115bb, 0x000115be, 0x000115be, - 0x000115c1, 0x000115db, 0x00011600, 0x00011632, - 0x0001163b, 0x0001163c, 0x0001163e, 0x0001163e, - 0x00011641, 0x00011644, 0x00011650, 0x00011659, - 0x00011680, 0x000116aa, 0x000116ac, 0x000116ac, - 0x000116ae, 0x000116af, 0x000116b6, 0x000116b6, - 0x000116b8, 0x000116b9, 0x000116c0, 0x000116c9, - 0x000116d0, 0x000116e3, 0x00011700, 0x0001171a, - 0x0001171e, 0x0001171e, 0x00011720, 0x00011721, - 0x00011726, 0x00011726, 0x00011730, 0x00011746, - 0x00011800, 0x0001182e, 0x00011838, 0x00011838, - 0x0001183b, 0x0001183b, 0x000118a0, 0x000118f2, - 0x000118ff, 0x00011906, 0x00011909, 0x00011909, - 0x0001190c, 0x00011913, 0x00011915, 0x00011916, - 0x00011918, 0x00011935, 0x00011937, 0x00011938, - 0x0001193d, 0x0001193d, 0x0001193f, 0x00011942, - 0x00011944, 0x00011946, 0x00011950, 0x00011959, - 0x000119a0, 0x000119a7, 0x000119aa, 0x000119d3, - 0x000119dc, 0x000119df, 0x000119e1, 0x000119e4, - 0x00011a00, 0x00011a00, 0x00011a07, 0x00011a08, - 0x00011a0b, 0x00011a32, 0x00011a39, 0x00011a3a, - 0x00011a3f, 0x00011a46, 0x00011a50, 0x00011a50, - 0x00011a57, 0x00011a58, 0x00011a5c, 0x00011a89, - 0x00011a97, 0x00011a97, 0x00011a9a, 0x00011aa2, - 0x00011ab0, 0x00011af8, 0x00011b00, 0x00011b09, + 0x0000a722, 0x0000a787, 0x0000a789, 0x0000a7dc, + 0x0000a7f1, 0x0000a801, 0x0000a803, 0x0000a805, + 0x0000a807, 0x0000a80a, 0x0000a80c, 0x0000a824, + 0x0000a827, 0x0000a827, 0x0000a830, 0x0000a837, + 0x0000a840, 0x0000a873, 0x0000a880, 0x0000a8c3, + 0x0000a8ce, 0x0000a8d9, 0x0000a8f2, 0x0000a8fe, + 0x0000a900, 0x0000a925, 0x0000a92e, 0x0000a946, + 0x0000a952, 0x0000a953, 0x0000a95f, 0x0000a97c, + 0x0000a983, 0x0000a9b2, 0x0000a9b4, 0x0000a9b5, + 0x0000a9ba, 0x0000a9bb, 0x0000a9be, 0x0000a9cd, + 0x0000a9cf, 0x0000a9d9, 0x0000a9de, 0x0000a9e4, + 0x0000a9e6, 0x0000a9fe, 0x0000aa00, 0x0000aa28, + 0x0000aa2f, 0x0000aa30, 0x0000aa33, 0x0000aa34, + 0x0000aa40, 0x0000aa42, 0x0000aa44, 0x0000aa4b, + 0x0000aa4d, 0x0000aa4d, 0x0000aa50, 0x0000aa59, + 0x0000aa5c, 0x0000aa7b, 0x0000aa7d, 0x0000aaaf, + 0x0000aab1, 0x0000aab1, 0x0000aab5, 0x0000aab6, + 0x0000aab9, 0x0000aabd, 0x0000aac0, 0x0000aac0, + 0x0000aac2, 0x0000aac2, 0x0000aadb, 0x0000aaeb, + 0x0000aaee, 0x0000aaf5, 0x0000ab01, 0x0000ab06, + 0x0000ab09, 0x0000ab0e, 0x0000ab11, 0x0000ab16, + 0x0000ab20, 0x0000ab26, 0x0000ab28, 0x0000ab2e, + 0x0000ab30, 0x0000ab69, 0x0000ab70, 0x0000abe4, + 0x0000abe6, 0x0000abe7, 0x0000abe9, 0x0000abec, + 0x0000abf0, 0x0000abf9, 0x0000ac00, 0x0000d7a3, + 0x0000d7b0, 0x0000d7c6, 0x0000d7cb, 0x0000d7fb, + 0x0000d800, 0x0000fa6d, 0x0000fa70, 0x0000fad9, + 0x0000fb00, 0x0000fb06, 0x0000fb13, 0x0000fb17, + 0x0000ff21, 0x0000ff3a, 0x0000ff41, 0x0000ff5a, + 0x0000ff66, 0x0000ffbe, 0x0000ffc2, 0x0000ffc7, + 0x0000ffca, 0x0000ffcf, 0x0000ffd2, 0x0000ffd7, + 0x0000ffda, 0x0000ffdc, 0x00010000, 0x0001000b, + 0x0001000d, 0x00010026, 0x00010028, 0x0001003a, + 0x0001003c, 0x0001003d, 0x0001003f, 0x0001004d, + 0x00010050, 0x0001005d, 0x00010080, 0x000100fa, + 0x00010100, 0x00010100, 0x00010102, 0x00010102, + 0x00010107, 0x00010133, 0x00010137, 0x0001013f, + 0x0001018d, 0x0001018e, 0x000101d0, 0x000101fc, + 0x00010280, 0x0001029c, 0x000102a0, 0x000102d0, + 0x00010300, 0x00010323, 0x0001032d, 0x0001034a, + 0x00010350, 0x00010375, 0x00010380, 0x0001039d, + 0x0001039f, 0x000103c3, 0x000103c8, 0x000103d5, + 0x00010400, 0x0001049d, 0x000104a0, 0x000104a9, + 0x000104b0, 0x000104d3, 0x000104d8, 0x000104fb, + 0x00010500, 0x00010527, 0x00010530, 0x00010563, + 0x0001056f, 0x0001057a, 0x0001057c, 0x0001058a, + 0x0001058c, 0x00010592, 0x00010594, 0x00010595, + 0x00010597, 0x000105a1, 0x000105a3, 0x000105b1, + 0x000105b3, 0x000105b9, 0x000105bb, 0x000105bc, + 0x000105c0, 0x000105f3, 0x00010600, 0x00010736, + 0x00010740, 0x00010755, 0x00010760, 0x00010767, + 0x00010780, 0x00010785, 0x00010787, 0x000107b0, + 0x000107b2, 0x000107ba, 0x00011000, 0x00011000, + 0x00011002, 0x00011037, 0x00011047, 0x0001104d, + 0x00011066, 0x0001106f, 0x00011071, 0x00011072, + 0x00011075, 0x00011075, 0x00011082, 0x000110b2, + 0x000110b7, 0x000110b8, 0x000110bb, 0x000110c1, + 0x000110cd, 0x000110cd, 0x000110d0, 0x000110e8, + 0x000110f0, 0x000110f9, 0x00011103, 0x00011126, + 0x0001112c, 0x0001112c, 0x00011136, 0x00011147, + 0x00011150, 0x00011172, 0x00011174, 0x00011176, + 0x00011182, 0x000111b5, 0x000111bf, 0x000111c8, + 0x000111cd, 0x000111ce, 0x000111d0, 0x000111df, + 0x000111e1, 0x000111f4, 0x00011200, 0x00011211, + 0x00011213, 0x0001122e, 0x00011232, 0x00011233, + 0x00011235, 0x00011235, 0x00011238, 0x0001123d, + 0x0001123f, 0x00011240, 0x00011280, 0x00011286, + 0x00011288, 0x00011288, 0x0001128a, 0x0001128d, + 0x0001128f, 0x0001129d, 0x0001129f, 0x000112a9, + 0x000112b0, 0x000112de, 0x000112e0, 0x000112e2, + 0x000112f0, 0x000112f9, 0x00011302, 0x00011303, + 0x00011305, 0x0001130c, 0x0001130f, 0x00011310, + 0x00011313, 0x00011328, 0x0001132a, 0x00011330, + 0x00011332, 0x00011333, 0x00011335, 0x00011339, + 0x0001133d, 0x0001133f, 0x00011341, 0x00011344, + 0x00011347, 0x00011348, 0x0001134b, 0x0001134d, + 0x00011350, 0x00011350, 0x00011357, 0x00011357, + 0x0001135d, 0x00011363, 0x00011380, 0x00011389, + 0x0001138b, 0x0001138b, 0x0001138e, 0x0001138e, + 0x00011390, 0x000113b5, 0x000113b7, 0x000113ba, + 0x000113c2, 0x000113c2, 0x000113c5, 0x000113c5, + 0x000113c7, 0x000113ca, 0x000113cc, 0x000113cd, + 0x000113cf, 0x000113cf, 0x000113d1, 0x000113d1, + 0x000113d3, 0x000113d5, 0x000113d7, 0x000113d8, + 0x00011400, 0x00011437, 0x00011440, 0x00011441, + 0x00011445, 0x00011445, 0x00011447, 0x0001145b, + 0x0001145d, 0x0001145d, 0x0001145f, 0x00011461, + 0x00011480, 0x000114b2, 0x000114b9, 0x000114b9, + 0x000114bb, 0x000114be, 0x000114c1, 0x000114c1, + 0x000114c4, 0x000114c7, 0x000114d0, 0x000114d9, + 0x00011580, 0x000115b1, 0x000115b8, 0x000115bb, + 0x000115be, 0x000115be, 0x000115c1, 0x000115db, + 0x00011600, 0x00011632, 0x0001163b, 0x0001163c, + 0x0001163e, 0x0001163e, 0x00011641, 0x00011644, + 0x00011650, 0x00011659, 0x00011680, 0x000116aa, + 0x000116ac, 0x000116ac, 0x000116ae, 0x000116af, + 0x000116b6, 0x000116b6, 0x000116b8, 0x000116b9, + 0x000116c0, 0x000116c9, 0x000116d0, 0x000116e3, + 0x00011700, 0x0001171a, 0x0001171e, 0x0001171e, + 0x00011720, 0x00011721, 0x00011726, 0x00011726, + 0x00011730, 0x00011746, 0x00011800, 0x0001182e, + 0x00011838, 0x00011838, 0x0001183b, 0x0001183b, + 0x000118a0, 0x000118f2, 0x000118ff, 0x00011906, + 0x00011909, 0x00011909, 0x0001190c, 0x00011913, + 0x00011915, 0x00011916, 0x00011918, 0x00011935, + 0x00011937, 0x00011938, 0x0001193d, 0x0001193d, + 0x0001193f, 0x00011942, 0x00011944, 0x00011946, + 0x00011950, 0x00011959, 0x000119a0, 0x000119a7, + 0x000119aa, 0x000119d3, 0x000119dc, 0x000119df, + 0x000119e1, 0x000119e4, 0x00011a00, 0x00011a00, + 0x00011a07, 0x00011a08, 0x00011a0b, 0x00011a32, + 0x00011a39, 0x00011a3a, 0x00011a3f, 0x00011a46, + 0x00011a50, 0x00011a50, 0x00011a57, 0x00011a58, + 0x00011a5c, 0x00011a89, 0x00011a97, 0x00011a97, + 0x00011a9a, 0x00011aa2, 0x00011ab0, 0x00011af8, + 0x00011b00, 0x00011b09, 0x00011b61, 0x00011b61, + 0x00011b65, 0x00011b65, 0x00011b67, 0x00011b67, 0x00011bc0, 0x00011be1, 0x00011bf0, 0x00011bf9, 0x00011c00, 0x00011c08, 0x00011c0a, 0x00011c2f, 0x00011c3e, 0x00011c45, 0x00011c50, 0x00011c6c, @@ -1811,6 +1831,7 @@ static const unsigned int _ucprop_ranges[] = { 0x00011d67, 0x00011d68, 0x00011d6a, 0x00011d8e, 0x00011d93, 0x00011d94, 0x00011d96, 0x00011d96, 0x00011d98, 0x00011d98, 0x00011da0, 0x00011da9, + 0x00011db0, 0x00011ddb, 0x00011de0, 0x00011de9, 0x00011ee0, 0x00011ef2, 0x00011ef5, 0x00011ef8, 0x00011f02, 0x00011f10, 0x00011f12, 0x00011f35, 0x00011f3e, 0x00011f3f, 0x00011f41, 0x00011f41, @@ -1829,11 +1850,12 @@ static const unsigned int _ucprop_ranges[] = { 0x00016b50, 0x00016b59, 0x00016b5b, 0x00016b61, 0x00016b63, 0x00016b77, 0x00016b7d, 0x00016b8f, 0x00016d40, 0x00016d79, 0x00016e40, 0x00016e9a, + 0x00016ea0, 0x00016eb8, 0x00016ebb, 0x00016ed3, 0x00016f00, 0x00016f4a, 0x00016f50, 0x00016f87, 0x00016f93, 0x00016f9f, 0x00016fe0, 0x00016fe1, - 0x00016fe3, 0x00016fe3, 0x00016ff0, 0x00016ff1, - 0x00017000, 0x000187f7, 0x00018800, 0x00018cd5, - 0x00018cff, 0x00018d08, 0x0001aff0, 0x0001aff3, + 0x00016fe3, 0x00016fe3, 0x00016ff0, 0x00016ff6, + 0x00017000, 0x00018cd5, 0x00018cff, 0x00018d1e, + 0x00018d80, 0x00018df2, 0x0001aff0, 0x0001aff3, 0x0001aff5, 0x0001affb, 0x0001affd, 0x0001affe, 0x0001b000, 0x0001b122, 0x0001b132, 0x0001b132, 0x0001b150, 0x0001b152, 0x0001b155, 0x0001b155, @@ -1872,186 +1894,189 @@ static const unsigned int _ucprop_ranges[] = { 0x0001e2f0, 0x0001e2f9, 0x0001e4d0, 0x0001e4eb, 0x0001e4f0, 0x0001e4f9, 0x0001e5d0, 0x0001e5ed, 0x0001e5f0, 0x0001e5fa, 0x0001e5ff, 0x0001e5ff, + 0x0001e6c0, 0x0001e6de, 0x0001e6e0, 0x0001e6e2, + 0x0001e6e4, 0x0001e6e5, 0x0001e6e7, 0x0001e6ed, + 0x0001e6f0, 0x0001e6f4, 0x0001e6fe, 0x0001e6ff, 0x0001e7e0, 0x0001e7e6, 0x0001e7e8, 0x0001e7eb, 0x0001e7ed, 0x0001e7ee, 0x0001e7f0, 0x0001e7fe, 0x0001f110, 0x0001f12e, 0x0001f130, 0x0001f169, 0x0001f170, 0x0001f1ac, 0x0001f1e6, 0x0001f202, 0x0001f210, 0x0001f23b, 0x0001f240, 0x0001f248, 0x0001f250, 0x0001f251, 0x00020000, 0x0002a6df, - 0x0002a700, 0x0002b739, 0x0002b740, 0x0002b81d, - 0x0002b820, 0x0002cea1, 0x0002ceb0, 0x0002ebe0, - 0x0002ebf0, 0x0002ee5d, 0x0002f800, 0x0002fa1d, - 0x00030000, 0x0003134a, 0x00031350, 0x000323af, - 0x000f0000, 0x000ffffd, 0x00100000, 0x0010fffd, - 0x000005be, 0x000005be, 0x000005c0, 0x000005c0, - 0x000005c3, 0x000005c3, 0x000005c6, 0x000005c6, - 0x000005d0, 0x000005ea, 0x000005ef, 0x000005f4, - 0x000007c0, 0x000007ea, 0x000007f4, 0x000007f5, - 0x000007fa, 0x000007fa, 0x000007fe, 0x00000815, - 0x0000081a, 0x0000081a, 0x00000824, 0x00000824, - 0x00000828, 0x00000828, 0x00000830, 0x0000083e, - 0x00000840, 0x00000858, 0x0000085e, 0x0000085e, - 0x0000200f, 0x0000200f, 0x0000fb1d, 0x0000fb1d, - 0x0000fb1f, 0x0000fb28, 0x0000fb2a, 0x0000fb36, - 0x0000fb38, 0x0000fb3c, 0x0000fb3e, 0x0000fb3e, - 0x0000fb40, 0x0000fb41, 0x0000fb43, 0x0000fb44, - 0x0000fb46, 0x0000fb4f, 0x00010800, 0x00010805, - 0x00010808, 0x00010808, 0x0001080a, 0x00010835, - 0x00010837, 0x00010838, 0x0001083c, 0x0001083c, - 0x0001083f, 0x00010855, 0x00010857, 0x0001089e, - 0x000108a7, 0x000108af, 0x000108e0, 0x000108f2, - 0x000108f4, 0x000108f5, 0x000108fb, 0x0001091b, - 0x00010920, 0x00010939, 0x0001093f, 0x0001093f, - 0x00010980, 0x000109b7, 0x000109bc, 0x000109cf, - 0x000109d2, 0x00010a00, 0x00010a10, 0x00010a13, - 0x00010a15, 0x00010a17, 0x00010a19, 0x00010a35, - 0x00010a40, 0x00010a48, 0x00010a50, 0x00010a58, - 0x00010a60, 0x00010a9f, 0x00010ac0, 0x00010ae4, - 0x00010aeb, 0x00010af6, 0x00010b00, 0x00010b35, - 0x00010b40, 0x00010b55, 0x00010b58, 0x00010b72, - 0x00010b78, 0x00010b91, 0x00010b99, 0x00010b9c, - 0x00010ba9, 0x00010baf, 0x00010c00, 0x00010c48, - 0x00010c80, 0x00010cb2, 0x00010cc0, 0x00010cf2, - 0x00010cfa, 0x00010cff, 0x00010d4a, 0x00010d65, - 0x00010d6f, 0x00010d85, 0x00010d8e, 0x00010d8f, - 0x00010e80, 0x00010ea9, 0x00010ead, 0x00010ead, - 0x00010eb0, 0x00010eb1, 0x00010f00, 0x00010f27, - 0x00010f70, 0x00010f81, 0x00010f86, 0x00010f89, - 0x00010fb0, 0x00010fcb, 0x00010fe0, 0x00010ff6, - 0x0001e800, 0x0001e8c4, 0x0001e8c7, 0x0001e8cf, - 0x0001e900, 0x0001e943, 0x0001e94b, 0x0001e94b, - 0x0001e950, 0x0001e959, 0x0001e95e, 0x0001e95f, - 0x00000030, 0x00000039, 0x000000b2, 0x000000b3, - 0x000000b9, 0x000000b9, 0x000006f0, 0x000006f9, - 0x00002070, 0x00002070, 0x00002074, 0x00002079, - 0x00002080, 0x00002089, 0x00002488, 0x0000249b, - 0x0000ff10, 0x0000ff19, 0x000102e1, 0x000102fb, - 0x0001ccf0, 0x0001ccf9, 0x0001d7ce, 0x0001d7ff, - 0x0001f100, 0x0001f10a, 0x0001fbf0, 0x0001fbf9, - 0x0000002b, 0x0000002b, 0x0000002d, 0x0000002d, - 0x0000207a, 0x0000207b, 0x0000208a, 0x0000208b, - 0x00002212, 0x00002212, 0x0000fb29, 0x0000fb29, - 0x0000fe62, 0x0000fe63, 0x0000ff0b, 0x0000ff0b, - 0x0000ff0d, 0x0000ff0d, 0x00000023, 0x00000025, - 0x000000a2, 0x000000a5, 0x000000b0, 0x000000b1, - 0x0000058f, 0x0000058f, 0x00000609, 0x0000060a, - 0x0000066a, 0x0000066a, 0x000009f2, 0x000009f3, - 0x000009fb, 0x000009fb, 0x00000af1, 0x00000af1, - 0x00000bf9, 0x00000bf9, 0x00000e3f, 0x00000e3f, - 0x000017db, 0x000017db, 0x00002030, 0x00002034, - 0x000020a0, 0x000020c0, 0x0000212e, 0x0000212e, - 0x00002213, 0x00002213, 0x0000a838, 0x0000a839, - 0x0000fe5f, 0x0000fe5f, 0x0000fe69, 0x0000fe6a, - 0x0000ff03, 0x0000ff05, 0x0000ffe0, 0x0000ffe1, - 0x0000ffe5, 0x0000ffe6, 0x00011fdd, 0x00011fe0, - 0x0001e2ff, 0x0001e2ff, 0x00000600, 0x00000605, - 0x00000660, 0x00000669, 0x0000066b, 0x0000066c, - 0x000006dd, 0x000006dd, 0x00000890, 0x00000891, - 0x000008e2, 0x000008e2, 0x00010d30, 0x00010d39, - 0x00010d40, 0x00010d49, 0x00010e60, 0x00010e7e, - 0x0000002c, 0x0000002c, 0x0000002e, 0x0000002f, - 0x0000003a, 0x0000003a, 0x000000a0, 0x000000a0, - 0x0000060c, 0x0000060c, 0x0000202f, 0x0000202f, - 0x00002044, 0x00002044, 0x0000fe50, 0x0000fe50, - 0x0000fe52, 0x0000fe52, 0x0000fe55, 0x0000fe55, - 0x0000ff0c, 0x0000ff0c, 0x0000ff0e, 0x0000ff0f, - 0x0000ff1a, 0x0000ff1a, 0x0000000a, 0x0000000a, - 0x0000000d, 0x0000000d, 0x0000001c, 0x0000001e, - 0x00000085, 0x00000085, 0x00002029, 0x00002029, - 0x00000009, 0x00000009, 0x0000000b, 0x0000000b, - 0x0000001f, 0x0000001f, 0x0000000c, 0x0000000c, - 0x00000020, 0x00000020, 0x00001680, 0x00001680, - 0x00002000, 0x0000200a, 0x00002028, 0x00002028, - 0x0000205f, 0x0000205f, 0x00003000, 0x00003000, - 0x00000000, 0x00000008, 0x0000000e, 0x0000001b, - 0x00000021, 0x00000022, 0x00000026, 0x0000002a, - 0x0000003b, 0x00000040, 0x0000005b, 0x00000060, - 0x0000007b, 0x00000084, 0x00000086, 0x0000009f, - 0x000000a1, 0x000000a1, 0x000000a6, 0x000000a9, - 0x000000ab, 0x000000af, 0x000000b4, 0x000000b4, - 0x000000b6, 0x000000b8, 0x000000bb, 0x000000bf, - 0x000000d7, 0x000000d7, 0x000000f7, 0x000000f7, - 0x000002b9, 0x000002ba, 0x000002c2, 0x000002cf, - 0x000002d2, 0x000002df, 0x000002e5, 0x000002ed, - 0x000002ef, 0x0000036f, 0x00000374, 0x00000375, - 0x0000037e, 0x0000037e, 0x00000384, 0x00000385, - 0x00000387, 0x00000387, 0x000003f6, 0x000003f6, - 0x00000483, 0x00000489, 0x0000058a, 0x0000058a, - 0x0000058d, 0x0000058e, 0x00000591, 0x000005bd, - 0x000005bf, 0x000005bf, 0x000005c1, 0x000005c2, - 0x000005c4, 0x000005c5, 0x000005c7, 0x000005c7, - 0x00000606, 0x00000607, 0x0000060e, 0x0000061a, - 0x0000064b, 0x0000065f, 0x00000670, 0x00000670, - 0x000006d6, 0x000006dc, 0x000006de, 0x000006e4, - 0x000006e7, 0x000006ed, 0x00000711, 0x00000711, - 0x00000730, 0x0000074a, 0x000007a6, 0x000007b0, - 0x000007eb, 0x000007f3, 0x000007f6, 0x000007f9, - 0x000007fd, 0x000007fd, 0x00000816, 0x00000819, - 0x0000081b, 0x00000823, 0x00000825, 0x00000827, - 0x00000829, 0x0000082d, 0x00000859, 0x0000085b, - 0x00000897, 0x0000089f, 0x000008ca, 0x000008e1, - 0x000008e3, 0x00000902, 0x0000093a, 0x0000093a, - 0x0000093c, 0x0000093c, 0x00000941, 0x00000948, - 0x0000094d, 0x0000094d, 0x00000951, 0x00000957, - 0x00000962, 0x00000963, 0x00000981, 0x00000981, - 0x000009bc, 0x000009bc, 0x000009c1, 0x000009c4, - 0x000009cd, 0x000009cd, 0x000009e2, 0x000009e3, - 0x000009fe, 0x000009fe, 0x00000a01, 0x00000a02, - 0x00000a3c, 0x00000a3c, 0x00000a41, 0x00000a42, - 0x00000a47, 0x00000a48, 0x00000a4b, 0x00000a4d, - 0x00000a51, 0x00000a51, 0x00000a70, 0x00000a71, - 0x00000a75, 0x00000a75, 0x00000a81, 0x00000a82, - 0x00000abc, 0x00000abc, 0x00000ac1, 0x00000ac5, - 0x00000ac7, 0x00000ac8, 0x00000acd, 0x00000acd, - 0x00000ae2, 0x00000ae3, 0x00000afa, 0x00000aff, - 0x00000b01, 0x00000b01, 0x00000b3c, 0x00000b3c, - 0x00000b3f, 0x00000b3f, 0x00000b41, 0x00000b44, - 0x00000b4d, 0x00000b4d, 0x00000b55, 0x00000b56, - 0x00000b62, 0x00000b63, 0x00000b82, 0x00000b82, - 0x00000bc0, 0x00000bc0, 0x00000bcd, 0x00000bcd, - 0x00000bf3, 0x00000bf8, 0x00000bfa, 0x00000bfa, - 0x00000c00, 0x00000c00, 0x00000c04, 0x00000c04, - 0x00000c3c, 0x00000c3c, 0x00000c3e, 0x00000c40, - 0x00000c46, 0x00000c48, 0x00000c4a, 0x00000c4d, - 0x00000c55, 0x00000c56, 0x00000c62, 0x00000c63, - 0x00000c78, 0x00000c7e, 0x00000c81, 0x00000c81, - 0x00000cbc, 0x00000cbc, 0x00000ccc, 0x00000ccd, - 0x00000ce2, 0x00000ce3, 0x00000d00, 0x00000d01, - 0x00000d3b, 0x00000d3c, 0x00000d41, 0x00000d44, - 0x00000d4d, 0x00000d4d, 0x00000d62, 0x00000d63, - 0x00000d81, 0x00000d81, 0x00000dca, 0x00000dca, - 0x00000dd2, 0x00000dd4, 0x00000dd6, 0x00000dd6, - 0x00000e31, 0x00000e31, 0x00000e34, 0x00000e3a, - 0x00000e47, 0x00000e4e, 0x00000eb1, 0x00000eb1, - 0x00000eb4, 0x00000ebc, 0x00000ec8, 0x00000ece, - 0x00000f18, 0x00000f19, 0x00000f35, 0x00000f35, - 0x00000f37, 0x00000f37, 0x00000f39, 0x00000f3d, - 0x00000f71, 0x00000f7e, 0x00000f80, 0x00000f84, - 0x00000f86, 0x00000f87, 0x00000f8d, 0x00000f97, - 0x00000f99, 0x00000fbc, 0x00000fc6, 0x00000fc6, - 0x0000102d, 0x00001030, 0x00001032, 0x00001037, - 0x00001039, 0x0000103a, 0x0000103d, 0x0000103e, - 0x00001058, 0x00001059, 0x0000105e, 0x00001060, - 0x00001071, 0x00001074, 0x00001082, 0x00001082, - 0x00001085, 0x00001086, 0x0000108d, 0x0000108d, - 0x0000109d, 0x0000109d, 0x0000135d, 0x0000135f, - 0x00001390, 0x00001399, 0x00001400, 0x00001400, - 0x0000169b, 0x0000169c, 0x00001712, 0x00001714, - 0x00001732, 0x00001733, 0x00001752, 0x00001753, - 0x00001772, 0x00001773, 0x000017b4, 0x000017b5, - 0x000017b7, 0x000017bd, 0x000017c6, 0x000017c6, - 0x000017c9, 0x000017d3, 0x000017dd, 0x000017dd, - 0x000017f0, 0x000017f9, 0x00001800, 0x0000180f, - 0x00001885, 0x00001886, 0x000018a9, 0x000018a9, - 0x00001920, 0x00001922, 0x00001927, 0x00001928, - 0x00001932, 0x00001932, 0x00001939, 0x0000193b, - 0x00001940, 0x00001940, 0x00001944, 0x00001945, - 0x000019de, 0x000019ff, 0x00001a17, 0x00001a18, - 0x00001a1b, 0x00001a1b, 0x00001a56, 0x00001a56, - 0x00001a58, 0x00001a5e, 0x00001a60, 0x00001a60, - 0x00001a62, 0x00001a62, 0x00001a65, 0x00001a6c, - 0x00001a73, 0x00001a7c, 0x00001a7f, 0x00001a7f, - 0x00001ab0, 0x00001ace, 0x00001b00, 0x00001b03, + 0x0002a700, 0x0002b81d, 0x0002b820, 0x0002cead, + 0x0002ceb0, 0x0002ebe0, 0x0002ebf0, 0x0002ee5d, + 0x0002f800, 0x0002fa1d, 0x00030000, 0x0003134a, + 0x00031350, 0x00033479, 0x000f0000, 0x000ffffd, + 0x00100000, 0x0010fffd, 0x000005be, 0x000005be, + 0x000005c0, 0x000005c0, 0x000005c3, 0x000005c3, + 0x000005c6, 0x000005c6, 0x000005d0, 0x000005ea, + 0x000005ef, 0x000005f4, 0x000007c0, 0x000007ea, + 0x000007f4, 0x000007f5, 0x000007fa, 0x000007fa, + 0x000007fe, 0x00000815, 0x0000081a, 0x0000081a, + 0x00000824, 0x00000824, 0x00000828, 0x00000828, + 0x00000830, 0x0000083e, 0x00000840, 0x00000858, + 0x0000085e, 0x0000085e, 0x0000200f, 0x0000200f, + 0x0000fb1d, 0x0000fb1d, 0x0000fb1f, 0x0000fb28, + 0x0000fb2a, 0x0000fb36, 0x0000fb38, 0x0000fb3c, + 0x0000fb3e, 0x0000fb3e, 0x0000fb40, 0x0000fb41, + 0x0000fb43, 0x0000fb44, 0x0000fb46, 0x0000fb4f, + 0x00010800, 0x00010805, 0x00010808, 0x00010808, + 0x0001080a, 0x00010835, 0x00010837, 0x00010838, + 0x0001083c, 0x0001083c, 0x0001083f, 0x00010855, + 0x00010857, 0x0001089e, 0x000108a7, 0x000108af, + 0x000108e0, 0x000108f2, 0x000108f4, 0x000108f5, + 0x000108fb, 0x0001091b, 0x00010920, 0x00010939, + 0x0001093f, 0x00010959, 0x00010980, 0x000109b7, + 0x000109bc, 0x000109cf, 0x000109d2, 0x00010a00, + 0x00010a10, 0x00010a13, 0x00010a15, 0x00010a17, + 0x00010a19, 0x00010a35, 0x00010a40, 0x00010a48, + 0x00010a50, 0x00010a58, 0x00010a60, 0x00010a9f, + 0x00010ac0, 0x00010ae4, 0x00010aeb, 0x00010af6, + 0x00010b00, 0x00010b35, 0x00010b40, 0x00010b55, + 0x00010b58, 0x00010b72, 0x00010b78, 0x00010b91, + 0x00010b99, 0x00010b9c, 0x00010ba9, 0x00010baf, + 0x00010c00, 0x00010c48, 0x00010c80, 0x00010cb2, + 0x00010cc0, 0x00010cf2, 0x00010cfa, 0x00010cff, + 0x00010d4a, 0x00010d65, 0x00010d6f, 0x00010d85, + 0x00010d8e, 0x00010d8f, 0x00010e80, 0x00010ea9, + 0x00010ead, 0x00010ead, 0x00010eb0, 0x00010eb1, + 0x00010f00, 0x00010f27, 0x00010f70, 0x00010f81, + 0x00010f86, 0x00010f89, 0x00010fb0, 0x00010fcb, + 0x00010fe0, 0x00010ff6, 0x0001e800, 0x0001e8c4, + 0x0001e8c7, 0x0001e8cf, 0x0001e900, 0x0001e943, + 0x0001e94b, 0x0001e94b, 0x0001e950, 0x0001e959, + 0x0001e95e, 0x0001e95f, 0x00000030, 0x00000039, + 0x000000b2, 0x000000b3, 0x000000b9, 0x000000b9, + 0x000006f0, 0x000006f9, 0x00002070, 0x00002070, + 0x00002074, 0x00002079, 0x00002080, 0x00002089, + 0x00002488, 0x0000249b, 0x0000ff10, 0x0000ff19, + 0x000102e1, 0x000102fb, 0x0001ccf0, 0x0001ccf9, + 0x0001d7ce, 0x0001d7ff, 0x0001f100, 0x0001f10a, + 0x0001fbf0, 0x0001fbf9, 0x0000002b, 0x0000002b, + 0x0000002d, 0x0000002d, 0x0000207a, 0x0000207b, + 0x0000208a, 0x0000208b, 0x00002212, 0x00002212, + 0x0000fb29, 0x0000fb29, 0x0000fe62, 0x0000fe63, + 0x0000ff0b, 0x0000ff0b, 0x0000ff0d, 0x0000ff0d, + 0x00000023, 0x00000025, 0x000000a2, 0x000000a5, + 0x000000b0, 0x000000b1, 0x0000058f, 0x0000058f, + 0x00000609, 0x0000060a, 0x0000066a, 0x0000066a, + 0x000009f2, 0x000009f3, 0x000009fb, 0x000009fb, + 0x00000af1, 0x00000af1, 0x00000bf9, 0x00000bf9, + 0x00000e3f, 0x00000e3f, 0x000017db, 0x000017db, + 0x00002030, 0x00002034, 0x000020a0, 0x000020c1, + 0x0000212e, 0x0000212e, 0x00002213, 0x00002213, + 0x0000a838, 0x0000a839, 0x0000fe5f, 0x0000fe5f, + 0x0000fe69, 0x0000fe6a, 0x0000ff03, 0x0000ff05, + 0x0000ffe0, 0x0000ffe1, 0x0000ffe5, 0x0000ffe6, + 0x00011fdd, 0x00011fe0, 0x0001e2ff, 0x0001e2ff, + 0x00000600, 0x00000605, 0x00000660, 0x00000669, + 0x0000066b, 0x0000066c, 0x000006dd, 0x000006dd, + 0x00000890, 0x00000891, 0x000008e2, 0x000008e2, + 0x00010d30, 0x00010d39, 0x00010d40, 0x00010d49, + 0x00010e60, 0x00010e7e, 0x0000002c, 0x0000002c, + 0x0000002e, 0x0000002f, 0x0000003a, 0x0000003a, + 0x000000a0, 0x000000a0, 0x0000060c, 0x0000060c, + 0x0000202f, 0x0000202f, 0x00002044, 0x00002044, + 0x0000fe50, 0x0000fe50, 0x0000fe52, 0x0000fe52, + 0x0000fe55, 0x0000fe55, 0x0000ff0c, 0x0000ff0c, + 0x0000ff0e, 0x0000ff0f, 0x0000ff1a, 0x0000ff1a, + 0x0000000a, 0x0000000a, 0x0000000d, 0x0000000d, + 0x0000001c, 0x0000001e, 0x00000085, 0x00000085, + 0x00002029, 0x00002029, 0x00000009, 0x00000009, + 0x0000000b, 0x0000000b, 0x0000001f, 0x0000001f, + 0x0000000c, 0x0000000c, 0x00000020, 0x00000020, + 0x00001680, 0x00001680, 0x00002000, 0x0000200a, + 0x00002028, 0x00002028, 0x0000205f, 0x0000205f, + 0x00003000, 0x00003000, 0x00000000, 0x00000008, + 0x0000000e, 0x0000001b, 0x00000021, 0x00000022, + 0x00000026, 0x0000002a, 0x0000003b, 0x00000040, + 0x0000005b, 0x00000060, 0x0000007b, 0x00000084, + 0x00000086, 0x0000009f, 0x000000a1, 0x000000a1, + 0x000000a6, 0x000000a9, 0x000000ab, 0x000000af, + 0x000000b4, 0x000000b4, 0x000000b6, 0x000000b8, + 0x000000bb, 0x000000bf, 0x000000d7, 0x000000d7, + 0x000000f7, 0x000000f7, 0x000002b9, 0x000002ba, + 0x000002c2, 0x000002cf, 0x000002d2, 0x000002df, + 0x000002e5, 0x000002ed, 0x000002ef, 0x0000036f, + 0x00000374, 0x00000375, 0x0000037e, 0x0000037e, + 0x00000384, 0x00000385, 0x00000387, 0x00000387, + 0x000003f6, 0x000003f6, 0x00000483, 0x00000489, + 0x0000058a, 0x0000058a, 0x0000058d, 0x0000058e, + 0x00000591, 0x000005bd, 0x000005bf, 0x000005bf, + 0x000005c1, 0x000005c2, 0x000005c4, 0x000005c5, + 0x000005c7, 0x000005c7, 0x00000606, 0x00000607, + 0x0000060e, 0x0000061a, 0x0000064b, 0x0000065f, + 0x00000670, 0x00000670, 0x000006d6, 0x000006dc, + 0x000006de, 0x000006e4, 0x000006e7, 0x000006ed, + 0x00000711, 0x00000711, 0x00000730, 0x0000074a, + 0x000007a6, 0x000007b0, 0x000007eb, 0x000007f3, + 0x000007f6, 0x000007f9, 0x000007fd, 0x000007fd, + 0x00000816, 0x00000819, 0x0000081b, 0x00000823, + 0x00000825, 0x00000827, 0x00000829, 0x0000082d, + 0x00000859, 0x0000085b, 0x00000897, 0x0000089f, + 0x000008ca, 0x000008e1, 0x000008e3, 0x00000902, + 0x0000093a, 0x0000093a, 0x0000093c, 0x0000093c, + 0x00000941, 0x00000948, 0x0000094d, 0x0000094d, + 0x00000951, 0x00000957, 0x00000962, 0x00000963, + 0x00000981, 0x00000981, 0x000009bc, 0x000009bc, + 0x000009c1, 0x000009c4, 0x000009cd, 0x000009cd, + 0x000009e2, 0x000009e3, 0x000009fe, 0x000009fe, + 0x00000a01, 0x00000a02, 0x00000a3c, 0x00000a3c, + 0x00000a41, 0x00000a42, 0x00000a47, 0x00000a48, + 0x00000a4b, 0x00000a4d, 0x00000a51, 0x00000a51, + 0x00000a70, 0x00000a71, 0x00000a75, 0x00000a75, + 0x00000a81, 0x00000a82, 0x00000abc, 0x00000abc, + 0x00000ac1, 0x00000ac5, 0x00000ac7, 0x00000ac8, + 0x00000acd, 0x00000acd, 0x00000ae2, 0x00000ae3, + 0x00000afa, 0x00000aff, 0x00000b01, 0x00000b01, + 0x00000b3c, 0x00000b3c, 0x00000b3f, 0x00000b3f, + 0x00000b41, 0x00000b44, 0x00000b4d, 0x00000b4d, + 0x00000b55, 0x00000b56, 0x00000b62, 0x00000b63, + 0x00000b82, 0x00000b82, 0x00000bc0, 0x00000bc0, + 0x00000bcd, 0x00000bcd, 0x00000bf3, 0x00000bf8, + 0x00000bfa, 0x00000bfa, 0x00000c00, 0x00000c00, + 0x00000c04, 0x00000c04, 0x00000c3c, 0x00000c3c, + 0x00000c3e, 0x00000c40, 0x00000c46, 0x00000c48, + 0x00000c4a, 0x00000c4d, 0x00000c55, 0x00000c56, + 0x00000c62, 0x00000c63, 0x00000c78, 0x00000c7e, + 0x00000c81, 0x00000c81, 0x00000cbc, 0x00000cbc, + 0x00000ccc, 0x00000ccd, 0x00000ce2, 0x00000ce3, + 0x00000d00, 0x00000d01, 0x00000d3b, 0x00000d3c, + 0x00000d41, 0x00000d44, 0x00000d4d, 0x00000d4d, + 0x00000d62, 0x00000d63, 0x00000d81, 0x00000d81, + 0x00000dca, 0x00000dca, 0x00000dd2, 0x00000dd4, + 0x00000dd6, 0x00000dd6, 0x00000e31, 0x00000e31, + 0x00000e34, 0x00000e3a, 0x00000e47, 0x00000e4e, + 0x00000eb1, 0x00000eb1, 0x00000eb4, 0x00000ebc, + 0x00000ec8, 0x00000ece, 0x00000f18, 0x00000f19, + 0x00000f35, 0x00000f35, 0x00000f37, 0x00000f37, + 0x00000f39, 0x00000f3d, 0x00000f71, 0x00000f7e, + 0x00000f80, 0x00000f84, 0x00000f86, 0x00000f87, + 0x00000f8d, 0x00000f97, 0x00000f99, 0x00000fbc, + 0x00000fc6, 0x00000fc6, 0x0000102d, 0x00001030, + 0x00001032, 0x00001037, 0x00001039, 0x0000103a, + 0x0000103d, 0x0000103e, 0x00001058, 0x00001059, + 0x0000105e, 0x00001060, 0x00001071, 0x00001074, + 0x00001082, 0x00001082, 0x00001085, 0x00001086, + 0x0000108d, 0x0000108d, 0x0000109d, 0x0000109d, + 0x0000135d, 0x0000135f, 0x00001390, 0x00001399, + 0x00001400, 0x00001400, 0x0000169b, 0x0000169c, + 0x00001712, 0x00001714, 0x00001732, 0x00001733, + 0x00001752, 0x00001753, 0x00001772, 0x00001773, + 0x000017b4, 0x000017b5, 0x000017b7, 0x000017bd, + 0x000017c6, 0x000017c6, 0x000017c9, 0x000017d3, + 0x000017dd, 0x000017dd, 0x000017f0, 0x000017f9, + 0x00001800, 0x0000180f, 0x00001885, 0x00001886, + 0x000018a9, 0x000018a9, 0x00001920, 0x00001922, + 0x00001927, 0x00001928, 0x00001932, 0x00001932, + 0x00001939, 0x0000193b, 0x00001940, 0x00001940, + 0x00001944, 0x00001945, 0x000019de, 0x000019ff, + 0x00001a17, 0x00001a18, 0x00001a1b, 0x00001a1b, + 0x00001a56, 0x00001a56, 0x00001a58, 0x00001a5e, + 0x00001a60, 0x00001a60, 0x00001a62, 0x00001a62, + 0x00001a65, 0x00001a6c, 0x00001a73, 0x00001a7c, + 0x00001a7f, 0x00001a7f, 0x00001ab0, 0x00001add, + 0x00001ae0, 0x00001aeb, 0x00001b00, 0x00001b03, 0x00001b34, 0x00001b34, 0x00001b36, 0x00001b3a, 0x00001b3c, 0x00001b3c, 0x00001b42, 0x00001b42, 0x00001b6b, 0x00001b73, 0x00001b80, 0x00001b81, @@ -2082,62 +2107,63 @@ static const unsigned int _ucprop_ranges[] = { 0x0000237b, 0x00002394, 0x00002396, 0x00002429, 0x00002440, 0x0000244a, 0x00002460, 0x00002487, 0x000024ea, 0x000026ab, 0x000026ad, 0x000027ff, - 0x00002900, 0x00002b73, 0x00002b76, 0x00002b95, - 0x00002b97, 0x00002bff, 0x00002ce5, 0x00002cea, - 0x00002cef, 0x00002cf1, 0x00002cf9, 0x00002cff, - 0x00002d7f, 0x00002d7f, 0x00002de0, 0x00002e5d, - 0x00002e80, 0x00002e99, 0x00002e9b, 0x00002ef3, - 0x00002f00, 0x00002fd5, 0x00002ff0, 0x00002fff, - 0x00003001, 0x00003004, 0x00003008, 0x00003020, - 0x0000302a, 0x0000302d, 0x00003030, 0x00003030, - 0x00003036, 0x00003037, 0x0000303d, 0x0000303f, - 0x00003099, 0x0000309c, 0x000030a0, 0x000030a0, - 0x000030fb, 0x000030fb, 0x000031c0, 0x000031e5, - 0x000031ef, 0x000031ef, 0x0000321d, 0x0000321e, - 0x00003250, 0x0000325f, 0x0000327c, 0x0000327e, - 0x000032b1, 0x000032bf, 0x000032cc, 0x000032cf, - 0x00003377, 0x0000337a, 0x000033de, 0x000033df, - 0x000033ff, 0x000033ff, 0x00004dc0, 0x00004dff, - 0x0000a490, 0x0000a4c6, 0x0000a60d, 0x0000a60f, - 0x0000a66f, 0x0000a67f, 0x0000a69e, 0x0000a69f, - 0x0000a6f0, 0x0000a6f1, 0x0000a700, 0x0000a721, - 0x0000a788, 0x0000a788, 0x0000a802, 0x0000a802, - 0x0000a806, 0x0000a806, 0x0000a80b, 0x0000a80b, - 0x0000a825, 0x0000a826, 0x0000a828, 0x0000a82c, - 0x0000a874, 0x0000a877, 0x0000a8c4, 0x0000a8c5, - 0x0000a8e0, 0x0000a8f1, 0x0000a8ff, 0x0000a8ff, - 0x0000a926, 0x0000a92d, 0x0000a947, 0x0000a951, - 0x0000a980, 0x0000a982, 0x0000a9b3, 0x0000a9b3, - 0x0000a9b6, 0x0000a9b9, 0x0000a9bc, 0x0000a9bd, - 0x0000a9e5, 0x0000a9e5, 0x0000aa29, 0x0000aa2e, - 0x0000aa31, 0x0000aa32, 0x0000aa35, 0x0000aa36, - 0x0000aa43, 0x0000aa43, 0x0000aa4c, 0x0000aa4c, - 0x0000aa7c, 0x0000aa7c, 0x0000aab0, 0x0000aab0, - 0x0000aab2, 0x0000aab4, 0x0000aab7, 0x0000aab8, - 0x0000aabe, 0x0000aabf, 0x0000aac1, 0x0000aac1, - 0x0000aaec, 0x0000aaed, 0x0000aaf6, 0x0000aaf6, - 0x0000ab6a, 0x0000ab6b, 0x0000abe5, 0x0000abe5, - 0x0000abe8, 0x0000abe8, 0x0000abed, 0x0000abed, - 0x0000fb1e, 0x0000fb1e, 0x0000fd3e, 0x0000fd4f, - 0x0000fdcf, 0x0000fdcf, 0x0000fdfd, 0x0000fe19, - 0x0000fe20, 0x0000fe4f, 0x0000fe51, 0x0000fe51, - 0x0000fe54, 0x0000fe54, 0x0000fe56, 0x0000fe5e, - 0x0000fe60, 0x0000fe61, 0x0000fe64, 0x0000fe66, - 0x0000fe68, 0x0000fe68, 0x0000fe6b, 0x0000fe6b, - 0x0000feff, 0x0000feff, 0x0000ff01, 0x0000ff02, - 0x0000ff06, 0x0000ff0a, 0x0000ff1b, 0x0000ff20, - 0x0000ff3b, 0x0000ff40, 0x0000ff5b, 0x0000ff65, - 0x0000ffe2, 0x0000ffe4, 0x0000ffe8, 0x0000ffee, - 0x0000fff9, 0x0000fffd, 0x00010101, 0x00010101, - 0x00010140, 0x0001018c, 0x00010190, 0x0001019c, - 0x000101a0, 0x000101a0, 0x000101fd, 0x000101fd, - 0x000102e0, 0x000102e0, 0x00010376, 0x0001037a, - 0x0001091f, 0x0001091f, 0x00010a01, 0x00010a03, - 0x00010a05, 0x00010a06, 0x00010a0c, 0x00010a0f, - 0x00010a38, 0x00010a3a, 0x00010a3f, 0x00010a3f, - 0x00010ae5, 0x00010ae6, 0x00010b39, 0x00010b3f, - 0x00010d24, 0x00010d27, 0x00010d69, 0x00010d6e, - 0x00010eab, 0x00010eac, 0x00010efc, 0x00010eff, + 0x00002900, 0x00002b73, 0x00002b76, 0x00002bff, + 0x00002ce5, 0x00002cea, 0x00002cef, 0x00002cf1, + 0x00002cf9, 0x00002cff, 0x00002d7f, 0x00002d7f, + 0x00002de0, 0x00002e5d, 0x00002e80, 0x00002e99, + 0x00002e9b, 0x00002ef3, 0x00002f00, 0x00002fd5, + 0x00002ff0, 0x00002fff, 0x00003001, 0x00003004, + 0x00003008, 0x00003020, 0x0000302a, 0x0000302d, + 0x00003030, 0x00003030, 0x00003036, 0x00003037, + 0x0000303d, 0x0000303f, 0x00003099, 0x0000309c, + 0x000030a0, 0x000030a0, 0x000030fb, 0x000030fb, + 0x000031c0, 0x000031e5, 0x000031ef, 0x000031ef, + 0x0000321d, 0x0000321e, 0x00003250, 0x0000325f, + 0x0000327c, 0x0000327e, 0x000032b1, 0x000032bf, + 0x000032cc, 0x000032cf, 0x00003377, 0x0000337a, + 0x000033de, 0x000033df, 0x000033ff, 0x000033ff, + 0x00004dc0, 0x00004dff, 0x0000a490, 0x0000a4c6, + 0x0000a60d, 0x0000a60f, 0x0000a66f, 0x0000a67f, + 0x0000a69e, 0x0000a69f, 0x0000a6f0, 0x0000a6f1, + 0x0000a700, 0x0000a721, 0x0000a788, 0x0000a788, + 0x0000a802, 0x0000a802, 0x0000a806, 0x0000a806, + 0x0000a80b, 0x0000a80b, 0x0000a825, 0x0000a826, + 0x0000a828, 0x0000a82c, 0x0000a874, 0x0000a877, + 0x0000a8c4, 0x0000a8c5, 0x0000a8e0, 0x0000a8f1, + 0x0000a8ff, 0x0000a8ff, 0x0000a926, 0x0000a92d, + 0x0000a947, 0x0000a951, 0x0000a980, 0x0000a982, + 0x0000a9b3, 0x0000a9b3, 0x0000a9b6, 0x0000a9b9, + 0x0000a9bc, 0x0000a9bd, 0x0000a9e5, 0x0000a9e5, + 0x0000aa29, 0x0000aa2e, 0x0000aa31, 0x0000aa32, + 0x0000aa35, 0x0000aa36, 0x0000aa43, 0x0000aa43, + 0x0000aa4c, 0x0000aa4c, 0x0000aa7c, 0x0000aa7c, + 0x0000aab0, 0x0000aab0, 0x0000aab2, 0x0000aab4, + 0x0000aab7, 0x0000aab8, 0x0000aabe, 0x0000aabf, + 0x0000aac1, 0x0000aac1, 0x0000aaec, 0x0000aaed, + 0x0000aaf6, 0x0000aaf6, 0x0000ab6a, 0x0000ab6b, + 0x0000abe5, 0x0000abe5, 0x0000abe8, 0x0000abe8, + 0x0000abed, 0x0000abed, 0x0000fb1e, 0x0000fb1e, + 0x0000fbc3, 0x0000fbd2, 0x0000fd3e, 0x0000fd4f, + 0x0000fd90, 0x0000fd91, 0x0000fdc8, 0x0000fdcf, + 0x0000fdfd, 0x0000fe19, 0x0000fe20, 0x0000fe4f, + 0x0000fe51, 0x0000fe51, 0x0000fe54, 0x0000fe54, + 0x0000fe56, 0x0000fe5e, 0x0000fe60, 0x0000fe61, + 0x0000fe64, 0x0000fe66, 0x0000fe68, 0x0000fe68, + 0x0000fe6b, 0x0000fe6b, 0x0000feff, 0x0000feff, + 0x0000ff01, 0x0000ff02, 0x0000ff06, 0x0000ff0a, + 0x0000ff1b, 0x0000ff20, 0x0000ff3b, 0x0000ff40, + 0x0000ff5b, 0x0000ff65, 0x0000ffe2, 0x0000ffe4, + 0x0000ffe8, 0x0000ffee, 0x0000fff9, 0x0000fffd, + 0x00010101, 0x00010101, 0x00010140, 0x0001018c, + 0x00010190, 0x0001019c, 0x000101a0, 0x000101a0, + 0x000101fd, 0x000101fd, 0x000102e0, 0x000102e0, + 0x00010376, 0x0001037a, 0x0001091f, 0x0001091f, + 0x00010a01, 0x00010a03, 0x00010a05, 0x00010a06, + 0x00010a0c, 0x00010a0f, 0x00010a38, 0x00010a3a, + 0x00010a3f, 0x00010a3f, 0x00010ae5, 0x00010ae6, + 0x00010b39, 0x00010b3f, 0x00010d24, 0x00010d27, + 0x00010d69, 0x00010d6e, 0x00010eab, 0x00010eac, + 0x00010ed0, 0x00010ed8, 0x00010efa, 0x00010eff, 0x00010f46, 0x00010f50, 0x00010f82, 0x00010f85, 0x00011001, 0x00011001, 0x00011038, 0x00011046, 0x00011052, 0x00011065, 0x00011070, 0x00011070, @@ -2176,25 +2202,28 @@ static const unsigned int _ucprop_ranges[] = { 0x00011a33, 0x00011a38, 0x00011a3b, 0x00011a3e, 0x00011a47, 0x00011a47, 0x00011a51, 0x00011a56, 0x00011a59, 0x00011a5b, 0x00011a8a, 0x00011a96, - 0x00011a98, 0x00011a99, 0x00011c30, 0x00011c36, - 0x00011c38, 0x00011c3d, 0x00011c92, 0x00011ca7, - 0x00011caa, 0x00011cb0, 0x00011cb2, 0x00011cb3, - 0x00011cb5, 0x00011cb6, 0x00011d31, 0x00011d36, - 0x00011d3a, 0x00011d3a, 0x00011d3c, 0x00011d3d, - 0x00011d3f, 0x00011d45, 0x00011d47, 0x00011d47, - 0x00011d90, 0x00011d91, 0x00011d95, 0x00011d95, - 0x00011d97, 0x00011d97, 0x00011ef3, 0x00011ef4, - 0x00011f00, 0x00011f01, 0x00011f36, 0x00011f3a, - 0x00011f40, 0x00011f40, 0x00011f42, 0x00011f42, - 0x00011f5a, 0x00011f5a, 0x00011fd5, 0x00011fdc, - 0x00011fe1, 0x00011ff1, 0x00013440, 0x00013440, - 0x00013447, 0x00013455, 0x0001611e, 0x00016129, - 0x0001612d, 0x0001612f, 0x00016af0, 0x00016af4, - 0x00016b30, 0x00016b36, 0x00016f4f, 0x00016f4f, - 0x00016f8f, 0x00016f92, 0x00016fe2, 0x00016fe2, - 0x00016fe4, 0x00016fe4, 0x0001bc9d, 0x0001bc9e, - 0x0001bca0, 0x0001bca3, 0x0001cc00, 0x0001ccd5, - 0x0001cd00, 0x0001ceb3, 0x0001cf00, 0x0001cf2d, + 0x00011a98, 0x00011a99, 0x00011b60, 0x00011b60, + 0x00011b62, 0x00011b64, 0x00011b66, 0x00011b66, + 0x00011c30, 0x00011c36, 0x00011c38, 0x00011c3d, + 0x00011c92, 0x00011ca7, 0x00011caa, 0x00011cb0, + 0x00011cb2, 0x00011cb3, 0x00011cb5, 0x00011cb6, + 0x00011d31, 0x00011d36, 0x00011d3a, 0x00011d3a, + 0x00011d3c, 0x00011d3d, 0x00011d3f, 0x00011d45, + 0x00011d47, 0x00011d47, 0x00011d90, 0x00011d91, + 0x00011d95, 0x00011d95, 0x00011d97, 0x00011d97, + 0x00011ef3, 0x00011ef4, 0x00011f00, 0x00011f01, + 0x00011f36, 0x00011f3a, 0x00011f40, 0x00011f40, + 0x00011f42, 0x00011f42, 0x00011f5a, 0x00011f5a, + 0x00011fd5, 0x00011fdc, 0x00011fe1, 0x00011ff1, + 0x00013440, 0x00013440, 0x00013447, 0x00013455, + 0x0001611e, 0x00016129, 0x0001612d, 0x0001612f, + 0x00016af0, 0x00016af4, 0x00016b30, 0x00016b36, + 0x00016f4f, 0x00016f4f, 0x00016f8f, 0x00016f92, + 0x00016fe2, 0x00016fe2, 0x00016fe4, 0x00016fe4, + 0x0001bc9d, 0x0001bc9e, 0x0001bca0, 0x0001bca3, + 0x0001cc00, 0x0001ccd5, 0x0001ccfa, 0x0001ccfc, + 0x0001cd00, 0x0001ceb3, 0x0001ceba, 0x0001ced0, + 0x0001cee0, 0x0001cef0, 0x0001cf00, 0x0001cf2d, 0x0001cf30, 0x0001cf46, 0x0001d167, 0x0001d169, 0x0001d173, 0x0001d182, 0x0001d185, 0x0001d18b, 0x0001d1aa, 0x0001d1ad, 0x0001d1e9, 0x0001d1ea, @@ -2212,26 +2241,29 @@ static const unsigned int _ucprop_ranges[] = { 0x0001e026, 0x0001e02a, 0x0001e08f, 0x0001e08f, 0x0001e130, 0x0001e136, 0x0001e2ae, 0x0001e2ae, 0x0001e2ec, 0x0001e2ef, 0x0001e4ec, 0x0001e4ef, - 0x0001e5ee, 0x0001e5ef, 0x0001e8d0, 0x0001e8d6, + 0x0001e5ee, 0x0001e5ef, 0x0001e6e3, 0x0001e6e3, + 0x0001e6e6, 0x0001e6e6, 0x0001e6ee, 0x0001e6ef, + 0x0001e6f5, 0x0001e6f5, 0x0001e8d0, 0x0001e8d6, 0x0001e944, 0x0001e94a, 0x0001eef0, 0x0001eef1, 0x0001f000, 0x0001f02b, 0x0001f030, 0x0001f093, 0x0001f0a0, 0x0001f0ae, 0x0001f0b1, 0x0001f0bf, 0x0001f0c1, 0x0001f0cf, 0x0001f0d1, 0x0001f0f5, 0x0001f10b, 0x0001f10f, 0x0001f12f, 0x0001f12f, 0x0001f16a, 0x0001f16f, 0x0001f1ad, 0x0001f1ad, - 0x0001f260, 0x0001f265, 0x0001f300, 0x0001f6d7, + 0x0001f260, 0x0001f265, 0x0001f300, 0x0001f6d8, 0x0001f6dc, 0x0001f6ec, 0x0001f6f0, 0x0001f6fc, - 0x0001f700, 0x0001f776, 0x0001f77b, 0x0001f7d9, - 0x0001f7e0, 0x0001f7eb, 0x0001f7f0, 0x0001f7f0, - 0x0001f800, 0x0001f80b, 0x0001f810, 0x0001f847, - 0x0001f850, 0x0001f859, 0x0001f860, 0x0001f887, - 0x0001f890, 0x0001f8ad, 0x0001f8b0, 0x0001f8bb, - 0x0001f8c0, 0x0001f8c1, 0x0001f900, 0x0001fa53, + 0x0001f700, 0x0001f7d9, 0x0001f7e0, 0x0001f7eb, + 0x0001f7f0, 0x0001f7f0, 0x0001f800, 0x0001f80b, + 0x0001f810, 0x0001f847, 0x0001f850, 0x0001f859, + 0x0001f860, 0x0001f887, 0x0001f890, 0x0001f8ad, + 0x0001f8b0, 0x0001f8bb, 0x0001f8c0, 0x0001f8c1, + 0x0001f8d0, 0x0001f8d8, 0x0001f900, 0x0001fa57, 0x0001fa60, 0x0001fa6d, 0x0001fa70, 0x0001fa7c, - 0x0001fa80, 0x0001fa89, 0x0001fa8f, 0x0001fac6, - 0x0001face, 0x0001fadc, 0x0001fadf, 0x0001fae9, - 0x0001faf0, 0x0001faf8, 0x0001fb00, 0x0001fb92, - 0x0001fb94, 0x0001fbef, 0x000e0001, 0x000e0001, + 0x0001fa80, 0x0001fa8a, 0x0001fa8e, 0x0001fac6, + 0x0001fac8, 0x0001fac8, 0x0001facd, 0x0001fadc, + 0x0001fadf, 0x0001faea, 0x0001faef, 0x0001faf8, + 0x0001fb00, 0x0001fb92, 0x0001fb94, 0x0001fbef, + 0x0001fbfa, 0x0001fbfa, 0x000e0001, 0x000e0001, 0x000e0020, 0x000e007f, 0x000e0100, 0x000e01ef, 0x00000608, 0x00000608, 0x0000060b, 0x0000060b, 0x0000060d, 0x0000060d, 0x0000061b, 0x0000064a, @@ -2240,12 +2272,12 @@ static const unsigned int _ucprop_ranges[] = { 0x000006fa, 0x0000070d, 0x0000070f, 0x00000710, 0x00000712, 0x0000072f, 0x0000074d, 0x000007a5, 0x000007b1, 0x000007b1, 0x00000860, 0x0000086a, - 0x00000870, 0x0000088e, 0x000008a0, 0x000008c9, + 0x00000870, 0x0000088f, 0x000008a0, 0x000008c9, 0x0000fb50, 0x0000fbc2, 0x0000fbd3, 0x0000fd3d, 0x0000fd50, 0x0000fd8f, 0x0000fd92, 0x0000fdc7, 0x0000fdf0, 0x0000fdfc, 0x0000fe70, 0x0000fe74, 0x0000fe76, 0x0000fefc, 0x00010d00, 0x00010d23, - 0x00010ec2, 0x00010ec4, 0x00010f30, 0x00010f45, + 0x00010ec2, 0x00010ec7, 0x00010f30, 0x00010f45, 0x00010f51, 0x00010f59, 0x0001ec71, 0x0001ecb4, 0x0001ed01, 0x0001ed3d, 0x0001ee00, 0x0001ee03, 0x0001ee05, 0x0001ee1f, 0x0001ee21, 0x0001ee22, @@ -2349,78 +2381,77 @@ static const unsigned int _ucprop_ranges[] = { 0x00010a50, 0x00010a58, 0x00010a7f, 0x00010a7f, 0x00010af0, 0x00010af6, 0x00010b39, 0x00010b3f, 0x00010b99, 0x00010b9c, 0x00010d6e, 0x00010d6e, - 0x00010ead, 0x00010ead, 0x00010f55, 0x00010f59, - 0x00010f86, 0x00010f89, 0x00011047, 0x0001104d, - 0x000110bb, 0x000110bc, 0x000110be, 0x000110c1, - 0x00011140, 0x00011143, 0x00011174, 0x00011175, - 0x000111c5, 0x000111c8, 0x000111cd, 0x000111cd, - 0x000111db, 0x000111db, 0x000111dd, 0x000111df, - 0x00011238, 0x0001123d, 0x000112a9, 0x000112a9, - 0x000113d4, 0x000113d5, 0x000113d7, 0x000113d8, - 0x0001144b, 0x0001144f, 0x0001145a, 0x0001145b, - 0x0001145d, 0x0001145d, 0x000114c6, 0x000114c6, - 0x000115c1, 0x000115d7, 0x00011641, 0x00011643, - 0x00011660, 0x0001166c, 0x000116b9, 0x000116b9, - 0x0001173c, 0x0001173e, 0x0001183b, 0x0001183b, - 0x00011944, 0x00011946, 0x000119e2, 0x000119e2, - 0x00011a3f, 0x00011a46, 0x00011a9a, 0x00011a9c, - 0x00011a9e, 0x00011aa2, 0x00011b00, 0x00011b09, - 0x00011be1, 0x00011be1, 0x00011c41, 0x00011c45, - 0x00011c70, 0x00011c71, 0x00011ef7, 0x00011ef8, - 0x00011f43, 0x00011f4f, 0x00011fff, 0x00011fff, - 0x00012470, 0x00012474, 0x00012ff1, 0x00012ff2, - 0x00016a6e, 0x00016a6f, 0x00016af5, 0x00016af5, - 0x00016b37, 0x00016b3b, 0x00016b44, 0x00016b44, - 0x00016d6d, 0x00016d6f, 0x00016e97, 0x00016e9a, - 0x00016fe2, 0x00016fe2, 0x0001bc9f, 0x0001bc9f, - 0x0001da87, 0x0001da8b, 0x0001e5ff, 0x0001e5ff, - 0x0001e95e, 0x0001e95f, 0x00000041, 0x0000005a, - 0x00000061, 0x0000007a, 0x000000aa, 0x000000aa, - 0x000000b5, 0x000000b5, 0x000000ba, 0x000000ba, - 0x000000c0, 0x000000d6, 0x000000d8, 0x000000f6, - 0x000000f8, 0x000001ba, 0x000001bc, 0x000001bf, - 0x000001c4, 0x00000293, 0x00000295, 0x000002b8, - 0x000002c0, 0x000002c1, 0x000002e0, 0x000002e4, - 0x00000345, 0x00000345, 0x00000370, 0x00000373, - 0x00000376, 0x00000377, 0x0000037a, 0x0000037d, - 0x0000037f, 0x0000037f, 0x00000386, 0x00000386, - 0x00000388, 0x0000038a, 0x0000038c, 0x0000038c, - 0x0000038e, 0x000003a1, 0x000003a3, 0x000003f5, - 0x000003f7, 0x00000481, 0x0000048a, 0x0000052f, - 0x00000531, 0x00000556, 0x00000560, 0x00000588, - 0x000010a0, 0x000010c5, 0x000010c7, 0x000010c7, - 0x000010cd, 0x000010cd, 0x000010d0, 0x000010fa, - 0x000010fc, 0x000010ff, 0x000013a0, 0x000013f5, - 0x000013f8, 0x000013fd, 0x00001c80, 0x00001c8a, - 0x00001c90, 0x00001cba, 0x00001cbd, 0x00001cbf, - 0x00001d00, 0x00001dbf, 0x00001e00, 0x00001f15, - 0x00001f18, 0x00001f1d, 0x00001f20, 0x00001f45, - 0x00001f48, 0x00001f4d, 0x00001f50, 0x00001f57, - 0x00001f59, 0x00001f59, 0x00001f5b, 0x00001f5b, - 0x00001f5d, 0x00001f5d, 0x00001f5f, 0x00001f7d, - 0x00001f80, 0x00001fb4, 0x00001fb6, 0x00001fbc, - 0x00001fbe, 0x00001fbe, 0x00001fc2, 0x00001fc4, - 0x00001fc6, 0x00001fcc, 0x00001fd0, 0x00001fd3, - 0x00001fd6, 0x00001fdb, 0x00001fe0, 0x00001fec, - 0x00001ff2, 0x00001ff4, 0x00001ff6, 0x00001ffc, - 0x00002071, 0x00002071, 0x0000207f, 0x0000207f, - 0x00002090, 0x0000209c, 0x00002102, 0x00002102, - 0x00002107, 0x00002107, 0x0000210a, 0x00002113, - 0x00002115, 0x00002115, 0x00002119, 0x0000211d, - 0x00002124, 0x00002124, 0x00002126, 0x00002126, - 0x00002128, 0x00002128, 0x0000212a, 0x0000212d, - 0x0000212f, 0x00002134, 0x00002139, 0x00002139, - 0x0000213c, 0x0000213f, 0x00002145, 0x00002149, - 0x0000214e, 0x0000214e, 0x00002160, 0x0000217f, - 0x00002183, 0x00002184, 0x000024b6, 0x000024e9, - 0x00002c00, 0x00002ce4, 0x00002ceb, 0x00002cee, - 0x00002cf2, 0x00002cf3, 0x00002d00, 0x00002d25, - 0x00002d27, 0x00002d27, 0x00002d2d, 0x00002d2d, - 0x0000a640, 0x0000a66d, 0x0000a680, 0x0000a69d, - 0x0000a722, 0x0000a787, 0x0000a78b, 0x0000a78e, - 0x0000a790, 0x0000a7cd, 0x0000a7d0, 0x0000a7d1, - 0x0000a7d3, 0x0000a7d3, 0x0000a7d5, 0x0000a7dc, - 0x0000a7f2, 0x0000a7f6, 0x0000a7f8, 0x0000a7fa, + 0x00010ead, 0x00010ead, 0x00010ed0, 0x00010ed0, + 0x00010f55, 0x00010f59, 0x00010f86, 0x00010f89, + 0x00011047, 0x0001104d, 0x000110bb, 0x000110bc, + 0x000110be, 0x000110c1, 0x00011140, 0x00011143, + 0x00011174, 0x00011175, 0x000111c5, 0x000111c8, + 0x000111cd, 0x000111cd, 0x000111db, 0x000111db, + 0x000111dd, 0x000111df, 0x00011238, 0x0001123d, + 0x000112a9, 0x000112a9, 0x000113d4, 0x000113d5, + 0x000113d7, 0x000113d8, 0x0001144b, 0x0001144f, + 0x0001145a, 0x0001145b, 0x0001145d, 0x0001145d, + 0x000114c6, 0x000114c6, 0x000115c1, 0x000115d7, + 0x00011641, 0x00011643, 0x00011660, 0x0001166c, + 0x000116b9, 0x000116b9, 0x0001173c, 0x0001173e, + 0x0001183b, 0x0001183b, 0x00011944, 0x00011946, + 0x000119e2, 0x000119e2, 0x00011a3f, 0x00011a46, + 0x00011a9a, 0x00011a9c, 0x00011a9e, 0x00011aa2, + 0x00011b00, 0x00011b09, 0x00011be1, 0x00011be1, + 0x00011c41, 0x00011c45, 0x00011c70, 0x00011c71, + 0x00011ef7, 0x00011ef8, 0x00011f43, 0x00011f4f, + 0x00011fff, 0x00011fff, 0x00012470, 0x00012474, + 0x00012ff1, 0x00012ff2, 0x00016a6e, 0x00016a6f, + 0x00016af5, 0x00016af5, 0x00016b37, 0x00016b3b, + 0x00016b44, 0x00016b44, 0x00016d6d, 0x00016d6f, + 0x00016e97, 0x00016e9a, 0x00016fe2, 0x00016fe2, + 0x0001bc9f, 0x0001bc9f, 0x0001da87, 0x0001da8b, + 0x0001e5ff, 0x0001e5ff, 0x0001e95e, 0x0001e95f, + 0x00000041, 0x0000005a, 0x00000061, 0x0000007a, + 0x000000aa, 0x000000aa, 0x000000b5, 0x000000b5, + 0x000000ba, 0x000000ba, 0x000000c0, 0x000000d6, + 0x000000d8, 0x000000f6, 0x000000f8, 0x000001ba, + 0x000001bc, 0x000001bf, 0x000001c4, 0x00000293, + 0x00000296, 0x000002b8, 0x000002c0, 0x000002c1, + 0x000002e0, 0x000002e4, 0x00000345, 0x00000345, + 0x00000370, 0x00000373, 0x00000376, 0x00000377, + 0x0000037a, 0x0000037d, 0x0000037f, 0x0000037f, + 0x00000386, 0x00000386, 0x00000388, 0x0000038a, + 0x0000038c, 0x0000038c, 0x0000038e, 0x000003a1, + 0x000003a3, 0x000003f5, 0x000003f7, 0x00000481, + 0x0000048a, 0x0000052f, 0x00000531, 0x00000556, + 0x00000560, 0x00000588, 0x000010a0, 0x000010c5, + 0x000010c7, 0x000010c7, 0x000010cd, 0x000010cd, + 0x000010d0, 0x000010fa, 0x000010fc, 0x000010ff, + 0x000013a0, 0x000013f5, 0x000013f8, 0x000013fd, + 0x00001c80, 0x00001c8a, 0x00001c90, 0x00001cba, + 0x00001cbd, 0x00001cbf, 0x00001d00, 0x00001dbf, + 0x00001e00, 0x00001f15, 0x00001f18, 0x00001f1d, + 0x00001f20, 0x00001f45, 0x00001f48, 0x00001f4d, + 0x00001f50, 0x00001f57, 0x00001f59, 0x00001f59, + 0x00001f5b, 0x00001f5b, 0x00001f5d, 0x00001f5d, + 0x00001f5f, 0x00001f7d, 0x00001f80, 0x00001fb4, + 0x00001fb6, 0x00001fbc, 0x00001fbe, 0x00001fbe, + 0x00001fc2, 0x00001fc4, 0x00001fc6, 0x00001fcc, + 0x00001fd0, 0x00001fd3, 0x00001fd6, 0x00001fdb, + 0x00001fe0, 0x00001fec, 0x00001ff2, 0x00001ff4, + 0x00001ff6, 0x00001ffc, 0x00002071, 0x00002071, + 0x0000207f, 0x0000207f, 0x00002090, 0x0000209c, + 0x00002102, 0x00002102, 0x00002107, 0x00002107, + 0x0000210a, 0x00002113, 0x00002115, 0x00002115, + 0x00002119, 0x0000211d, 0x00002124, 0x00002124, + 0x00002126, 0x00002126, 0x00002128, 0x00002128, + 0x0000212a, 0x0000212d, 0x0000212f, 0x00002134, + 0x00002139, 0x00002139, 0x0000213c, 0x0000213f, + 0x00002145, 0x00002149, 0x0000214e, 0x0000214e, + 0x00002160, 0x0000217f, 0x00002183, 0x00002184, + 0x000024b6, 0x000024e9, 0x00002c00, 0x00002ce4, + 0x00002ceb, 0x00002cee, 0x00002cf2, 0x00002cf3, + 0x00002d00, 0x00002d25, 0x00002d27, 0x00002d27, + 0x00002d2d, 0x00002d2d, 0x0000a640, 0x0000a66d, + 0x0000a680, 0x0000a69d, 0x0000a722, 0x0000a787, + 0x0000a78b, 0x0000a78e, 0x0000a790, 0x0000a7dc, + 0x0000a7f1, 0x0000a7f6, 0x0000a7f8, 0x0000a7fa, 0x0000ab30, 0x0000ab5a, 0x0000ab5c, 0x0000ab69, 0x0000ab70, 0x0000abbf, 0x0000fb00, 0x0000fb06, 0x0000fb13, 0x0000fb17, 0x0000ff21, 0x0000ff3a, @@ -2435,6 +2466,7 @@ static const unsigned int _ucprop_ranges[] = { 0x00010c80, 0x00010cb2, 0x00010cc0, 0x00010cf2, 0x00010d50, 0x00010d65, 0x00010d70, 0x00010d85, 0x000118a0, 0x000118df, 0x00016e40, 0x00016e7f, + 0x00016ea0, 0x00016eb8, 0x00016ebb, 0x00016ed3, 0x0001d400, 0x0001d454, 0x0001d456, 0x0001d49c, 0x0001d49e, 0x0001d49f, 0x0001d4a2, 0x0001d4a2, 0x0001d4a5, 0x0001d4a6, 0x0001d4a9, 0x0001d4ac, @@ -2536,77 +2568,78 @@ static const unsigned int _ucprop_ranges[] = { 0x00001a58, 0x00001a5e, 0x00001a60, 0x00001a60, 0x00001a62, 0x00001a62, 0x00001a65, 0x00001a6c, 0x00001a73, 0x00001a7c, 0x00001a7f, 0x00001a7f, - 0x00001aa7, 0x00001aa7, 0x00001ab0, 0x00001ace, - 0x00001b00, 0x00001b03, 0x00001b34, 0x00001b34, - 0x00001b36, 0x00001b3a, 0x00001b3c, 0x00001b3c, - 0x00001b42, 0x00001b42, 0x00001b6b, 0x00001b73, - 0x00001b80, 0x00001b81, 0x00001ba2, 0x00001ba5, - 0x00001ba8, 0x00001ba9, 0x00001bab, 0x00001bad, - 0x00001be6, 0x00001be6, 0x00001be8, 0x00001be9, - 0x00001bed, 0x00001bed, 0x00001bef, 0x00001bf1, - 0x00001c2c, 0x00001c33, 0x00001c36, 0x00001c37, - 0x00001c78, 0x00001c7d, 0x00001cd0, 0x00001cd2, - 0x00001cd4, 0x00001ce0, 0x00001ce2, 0x00001ce8, - 0x00001ced, 0x00001ced, 0x00001cf4, 0x00001cf4, - 0x00001cf8, 0x00001cf9, 0x00001d2c, 0x00001d6a, - 0x00001d78, 0x00001d78, 0x00001d9b, 0x00001dff, - 0x00001fbd, 0x00001fbd, 0x00001fbf, 0x00001fc1, - 0x00001fcd, 0x00001fcf, 0x00001fdd, 0x00001fdf, - 0x00001fed, 0x00001fef, 0x00001ffd, 0x00001ffe, - 0x0000200b, 0x0000200f, 0x00002018, 0x00002019, - 0x00002024, 0x00002024, 0x00002027, 0x00002027, - 0x0000202a, 0x0000202e, 0x00002060, 0x00002064, - 0x00002066, 0x0000206f, 0x00002071, 0x00002071, - 0x0000207f, 0x0000207f, 0x00002090, 0x0000209c, - 0x000020d0, 0x000020f0, 0x00002c7c, 0x00002c7d, - 0x00002cef, 0x00002cf1, 0x00002d6f, 0x00002d6f, - 0x00002d7f, 0x00002d7f, 0x00002de0, 0x00002dff, - 0x00002e2f, 0x00002e2f, 0x00003005, 0x00003005, - 0x0000302a, 0x0000302d, 0x00003031, 0x00003035, - 0x0000303b, 0x0000303b, 0x00003099, 0x0000309e, - 0x000030fc, 0x000030fe, 0x0000a015, 0x0000a015, - 0x0000a4f8, 0x0000a4fd, 0x0000a60c, 0x0000a60c, - 0x0000a66f, 0x0000a672, 0x0000a674, 0x0000a67d, - 0x0000a67f, 0x0000a67f, 0x0000a69c, 0x0000a69f, - 0x0000a6f0, 0x0000a6f1, 0x0000a700, 0x0000a721, - 0x0000a770, 0x0000a770, 0x0000a788, 0x0000a78a, - 0x0000a7f2, 0x0000a7f4, 0x0000a7f8, 0x0000a7f9, - 0x0000a802, 0x0000a802, 0x0000a806, 0x0000a806, - 0x0000a80b, 0x0000a80b, 0x0000a825, 0x0000a826, - 0x0000a82c, 0x0000a82c, 0x0000a8c4, 0x0000a8c5, - 0x0000a8e0, 0x0000a8f1, 0x0000a8ff, 0x0000a8ff, - 0x0000a926, 0x0000a92d, 0x0000a947, 0x0000a951, - 0x0000a980, 0x0000a982, 0x0000a9b3, 0x0000a9b3, - 0x0000a9b6, 0x0000a9b9, 0x0000a9bc, 0x0000a9bd, - 0x0000a9cf, 0x0000a9cf, 0x0000a9e5, 0x0000a9e6, - 0x0000aa29, 0x0000aa2e, 0x0000aa31, 0x0000aa32, - 0x0000aa35, 0x0000aa36, 0x0000aa43, 0x0000aa43, - 0x0000aa4c, 0x0000aa4c, 0x0000aa70, 0x0000aa70, - 0x0000aa7c, 0x0000aa7c, 0x0000aab0, 0x0000aab0, - 0x0000aab2, 0x0000aab4, 0x0000aab7, 0x0000aab8, - 0x0000aabe, 0x0000aabf, 0x0000aac1, 0x0000aac1, - 0x0000aadd, 0x0000aadd, 0x0000aaec, 0x0000aaed, - 0x0000aaf3, 0x0000aaf4, 0x0000aaf6, 0x0000aaf6, - 0x0000ab5b, 0x0000ab5f, 0x0000ab69, 0x0000ab6b, - 0x0000abe5, 0x0000abe5, 0x0000abe8, 0x0000abe8, - 0x0000abed, 0x0000abed, 0x0000fb1e, 0x0000fb1e, - 0x0000fbb2, 0x0000fbc2, 0x0000fe00, 0x0000fe0f, - 0x0000fe13, 0x0000fe13, 0x0000fe20, 0x0000fe2f, - 0x0000fe52, 0x0000fe52, 0x0000fe55, 0x0000fe55, - 0x0000feff, 0x0000feff, 0x0000ff07, 0x0000ff07, - 0x0000ff0e, 0x0000ff0e, 0x0000ff1a, 0x0000ff1a, - 0x0000ff3e, 0x0000ff3e, 0x0000ff40, 0x0000ff40, - 0x0000ff70, 0x0000ff70, 0x0000ff9e, 0x0000ff9f, - 0x0000ffe3, 0x0000ffe3, 0x0000fff9, 0x0000fffb, - 0x000101fd, 0x000101fd, 0x000102e0, 0x000102e0, - 0x00010376, 0x0001037a, 0x00010780, 0x00010785, - 0x00010787, 0x000107b0, 0x000107b2, 0x000107ba, - 0x00010a01, 0x00010a03, 0x00010a05, 0x00010a06, - 0x00010a0c, 0x00010a0f, 0x00010a38, 0x00010a3a, - 0x00010a3f, 0x00010a3f, 0x00010ae5, 0x00010ae6, - 0x00010d24, 0x00010d27, 0x00010d4e, 0x00010d4e, - 0x00010d69, 0x00010d6d, 0x00010d6f, 0x00010d6f, - 0x00010eab, 0x00010eac, 0x00010efc, 0x00010eff, + 0x00001aa7, 0x00001aa7, 0x00001ab0, 0x00001add, + 0x00001ae0, 0x00001aeb, 0x00001b00, 0x00001b03, + 0x00001b34, 0x00001b34, 0x00001b36, 0x00001b3a, + 0x00001b3c, 0x00001b3c, 0x00001b42, 0x00001b42, + 0x00001b6b, 0x00001b73, 0x00001b80, 0x00001b81, + 0x00001ba2, 0x00001ba5, 0x00001ba8, 0x00001ba9, + 0x00001bab, 0x00001bad, 0x00001be6, 0x00001be6, + 0x00001be8, 0x00001be9, 0x00001bed, 0x00001bed, + 0x00001bef, 0x00001bf1, 0x00001c2c, 0x00001c33, + 0x00001c36, 0x00001c37, 0x00001c78, 0x00001c7d, + 0x00001cd0, 0x00001cd2, 0x00001cd4, 0x00001ce0, + 0x00001ce2, 0x00001ce8, 0x00001ced, 0x00001ced, + 0x00001cf4, 0x00001cf4, 0x00001cf8, 0x00001cf9, + 0x00001d2c, 0x00001d6a, 0x00001d78, 0x00001d78, + 0x00001d9b, 0x00001dff, 0x00001fbd, 0x00001fbd, + 0x00001fbf, 0x00001fc1, 0x00001fcd, 0x00001fcf, + 0x00001fdd, 0x00001fdf, 0x00001fed, 0x00001fef, + 0x00001ffd, 0x00001ffe, 0x0000200b, 0x0000200f, + 0x00002018, 0x00002019, 0x00002024, 0x00002024, + 0x00002027, 0x00002027, 0x0000202a, 0x0000202e, + 0x00002060, 0x00002064, 0x00002066, 0x0000206f, + 0x00002071, 0x00002071, 0x0000207f, 0x0000207f, + 0x00002090, 0x0000209c, 0x000020d0, 0x000020f0, + 0x00002c7c, 0x00002c7d, 0x00002cef, 0x00002cf1, + 0x00002d6f, 0x00002d6f, 0x00002d7f, 0x00002d7f, + 0x00002de0, 0x00002dff, 0x00002e2f, 0x00002e2f, + 0x00003005, 0x00003005, 0x0000302a, 0x0000302d, + 0x00003031, 0x00003035, 0x0000303b, 0x0000303b, + 0x00003099, 0x0000309e, 0x000030fc, 0x000030fe, + 0x0000a015, 0x0000a015, 0x0000a4f8, 0x0000a4fd, + 0x0000a60c, 0x0000a60c, 0x0000a66f, 0x0000a672, + 0x0000a674, 0x0000a67d, 0x0000a67f, 0x0000a67f, + 0x0000a69c, 0x0000a69f, 0x0000a6f0, 0x0000a6f1, + 0x0000a700, 0x0000a721, 0x0000a770, 0x0000a770, + 0x0000a788, 0x0000a78a, 0x0000a7f1, 0x0000a7f4, + 0x0000a7f8, 0x0000a7f9, 0x0000a802, 0x0000a802, + 0x0000a806, 0x0000a806, 0x0000a80b, 0x0000a80b, + 0x0000a825, 0x0000a826, 0x0000a82c, 0x0000a82c, + 0x0000a8c4, 0x0000a8c5, 0x0000a8e0, 0x0000a8f1, + 0x0000a8ff, 0x0000a8ff, 0x0000a926, 0x0000a92d, + 0x0000a947, 0x0000a951, 0x0000a980, 0x0000a982, + 0x0000a9b3, 0x0000a9b3, 0x0000a9b6, 0x0000a9b9, + 0x0000a9bc, 0x0000a9bd, 0x0000a9cf, 0x0000a9cf, + 0x0000a9e5, 0x0000a9e6, 0x0000aa29, 0x0000aa2e, + 0x0000aa31, 0x0000aa32, 0x0000aa35, 0x0000aa36, + 0x0000aa43, 0x0000aa43, 0x0000aa4c, 0x0000aa4c, + 0x0000aa70, 0x0000aa70, 0x0000aa7c, 0x0000aa7c, + 0x0000aab0, 0x0000aab0, 0x0000aab2, 0x0000aab4, + 0x0000aab7, 0x0000aab8, 0x0000aabe, 0x0000aabf, + 0x0000aac1, 0x0000aac1, 0x0000aadd, 0x0000aadd, + 0x0000aaec, 0x0000aaed, 0x0000aaf3, 0x0000aaf4, + 0x0000aaf6, 0x0000aaf6, 0x0000ab5b, 0x0000ab5f, + 0x0000ab69, 0x0000ab6b, 0x0000abe5, 0x0000abe5, + 0x0000abe8, 0x0000abe8, 0x0000abed, 0x0000abed, + 0x0000fb1e, 0x0000fb1e, 0x0000fbb2, 0x0000fbc2, + 0x0000fe00, 0x0000fe0f, 0x0000fe13, 0x0000fe13, + 0x0000fe20, 0x0000fe2f, 0x0000fe52, 0x0000fe52, + 0x0000fe55, 0x0000fe55, 0x0000feff, 0x0000feff, + 0x0000ff07, 0x0000ff07, 0x0000ff0e, 0x0000ff0e, + 0x0000ff1a, 0x0000ff1a, 0x0000ff3e, 0x0000ff3e, + 0x0000ff40, 0x0000ff40, 0x0000ff70, 0x0000ff70, + 0x0000ff9e, 0x0000ff9f, 0x0000ffe3, 0x0000ffe3, + 0x0000fff9, 0x0000fffb, 0x000101fd, 0x000101fd, + 0x000102e0, 0x000102e0, 0x00010376, 0x0001037a, + 0x00010780, 0x00010785, 0x00010787, 0x000107b0, + 0x000107b2, 0x000107ba, 0x00010a01, 0x00010a03, + 0x00010a05, 0x00010a06, 0x00010a0c, 0x00010a0f, + 0x00010a38, 0x00010a3a, 0x00010a3f, 0x00010a3f, + 0x00010ae5, 0x00010ae6, 0x00010d24, 0x00010d27, + 0x00010d4e, 0x00010d4e, 0x00010d69, 0x00010d6d, + 0x00010d6f, 0x00010d6f, 0x00010eab, 0x00010eac, + 0x00010ec5, 0x00010ec5, 0x00010efa, 0x00010eff, 0x00010f46, 0x00010f50, 0x00010f82, 0x00010f85, 0x00011001, 0x00011001, 0x00011038, 0x00011046, 0x00011070, 0x00011070, 0x00011073, 0x00011074, @@ -2645,14 +2678,16 @@ static const unsigned int _ucprop_ranges[] = { 0x00011a3b, 0x00011a3e, 0x00011a47, 0x00011a47, 0x00011a51, 0x00011a56, 0x00011a59, 0x00011a5b, 0x00011a8a, 0x00011a96, 0x00011a98, 0x00011a99, - 0x00011c30, 0x00011c36, 0x00011c38, 0x00011c3d, - 0x00011c3f, 0x00011c3f, 0x00011c92, 0x00011ca7, - 0x00011caa, 0x00011cb0, 0x00011cb2, 0x00011cb3, - 0x00011cb5, 0x00011cb6, 0x00011d31, 0x00011d36, - 0x00011d3a, 0x00011d3a, 0x00011d3c, 0x00011d3d, - 0x00011d3f, 0x00011d45, 0x00011d47, 0x00011d47, - 0x00011d90, 0x00011d91, 0x00011d95, 0x00011d95, - 0x00011d97, 0x00011d97, 0x00011ef3, 0x00011ef4, + 0x00011b60, 0x00011b60, 0x00011b62, 0x00011b64, + 0x00011b66, 0x00011b66, 0x00011c30, 0x00011c36, + 0x00011c38, 0x00011c3d, 0x00011c3f, 0x00011c3f, + 0x00011c92, 0x00011ca7, 0x00011caa, 0x00011cb0, + 0x00011cb2, 0x00011cb3, 0x00011cb5, 0x00011cb6, + 0x00011d31, 0x00011d36, 0x00011d3a, 0x00011d3a, + 0x00011d3c, 0x00011d3d, 0x00011d3f, 0x00011d45, + 0x00011d47, 0x00011d47, 0x00011d90, 0x00011d91, + 0x00011d95, 0x00011d95, 0x00011d97, 0x00011d97, + 0x00011dd9, 0x00011dd9, 0x00011ef3, 0x00011ef4, 0x00011f00, 0x00011f01, 0x00011f36, 0x00011f3a, 0x00011f40, 0x00011f40, 0x00011f42, 0x00011f42, 0x00011f5a, 0x00011f5a, 0x00013430, 0x00013440, @@ -2662,1620 +2697,1657 @@ static const unsigned int _ucprop_ranges[] = { 0x00016d40, 0x00016d42, 0x00016d6b, 0x00016d6c, 0x00016f4f, 0x00016f4f, 0x00016f8f, 0x00016f9f, 0x00016fe0, 0x00016fe1, 0x00016fe3, 0x00016fe4, - 0x0001aff0, 0x0001aff3, 0x0001aff5, 0x0001affb, - 0x0001affd, 0x0001affe, 0x0001bc9d, 0x0001bc9e, - 0x0001bca0, 0x0001bca3, 0x0001cf00, 0x0001cf2d, - 0x0001cf30, 0x0001cf46, 0x0001d167, 0x0001d169, - 0x0001d173, 0x0001d182, 0x0001d185, 0x0001d18b, - 0x0001d1aa, 0x0001d1ad, 0x0001d242, 0x0001d244, - 0x0001da00, 0x0001da36, 0x0001da3b, 0x0001da6c, - 0x0001da75, 0x0001da75, 0x0001da84, 0x0001da84, - 0x0001da9b, 0x0001da9f, 0x0001daa1, 0x0001daaf, - 0x0001e000, 0x0001e006, 0x0001e008, 0x0001e018, - 0x0001e01b, 0x0001e021, 0x0001e023, 0x0001e024, - 0x0001e026, 0x0001e02a, 0x0001e030, 0x0001e06d, - 0x0001e08f, 0x0001e08f, 0x0001e130, 0x0001e13d, - 0x0001e2ae, 0x0001e2ae, 0x0001e2ec, 0x0001e2ef, - 0x0001e4eb, 0x0001e4ef, 0x0001e5ee, 0x0001e5ef, + 0x00016ff2, 0x00016ff3, 0x0001aff0, 0x0001aff3, + 0x0001aff5, 0x0001affb, 0x0001affd, 0x0001affe, + 0x0001bc9d, 0x0001bc9e, 0x0001bca0, 0x0001bca3, + 0x0001cf00, 0x0001cf2d, 0x0001cf30, 0x0001cf46, + 0x0001d167, 0x0001d169, 0x0001d173, 0x0001d182, + 0x0001d185, 0x0001d18b, 0x0001d1aa, 0x0001d1ad, + 0x0001d242, 0x0001d244, 0x0001da00, 0x0001da36, + 0x0001da3b, 0x0001da6c, 0x0001da75, 0x0001da75, + 0x0001da84, 0x0001da84, 0x0001da9b, 0x0001da9f, + 0x0001daa1, 0x0001daaf, 0x0001e000, 0x0001e006, + 0x0001e008, 0x0001e018, 0x0001e01b, 0x0001e021, + 0x0001e023, 0x0001e024, 0x0001e026, 0x0001e02a, + 0x0001e030, 0x0001e06d, 0x0001e08f, 0x0001e08f, + 0x0001e130, 0x0001e13d, 0x0001e2ae, 0x0001e2ae, + 0x0001e2ec, 0x0001e2ef, 0x0001e4eb, 0x0001e4ef, + 0x0001e5ee, 0x0001e5ef, 0x0001e6e3, 0x0001e6e3, + 0x0001e6e6, 0x0001e6e6, 0x0001e6ee, 0x0001e6ef, + 0x0001e6f5, 0x0001e6f5, 0x0001e6ff, 0x0001e6ff, 0x0001e8d0, 0x0001e8d6, 0x0001e944, 0x0001e94b, 0x0001f3fb, 0x0001f3ff, 0x000e0001, 0x000e0001, 0x000e0020, 0x000e007f, 0x000e0100, 0x000e01ef }; -static const unsigned _uccase_upper_g_size = 306; +static const unsigned _uccase_upper_g_size = 296; static const short _uccase_upper_g[] = { - 3332, 32, 1410, 122, 4805, 2, 25559, 556, - 94, 76, 416, 837, 187, 1295, 46, 592, - 84, 1561, 3990, 79, 536, 1310, 7720, 1, - 448, 643, 1767, 268, 535, 1298, 352, 1137, - 118, 11, 442, 70, -619, 33, 1186, 4346, - 1179, 2, 863, 924, 5932, 572, 252, 824, - 623, 170, 73, 1, -113, 189, -663, 176, - 4628, 183, 1162, 66, 550, 1406, 1580, 2160, - 45, 1073, 1123, 1120, 474, 27, -337, 6, - -852, 252, 3326, 22, 731, 44, 793, 873, - 1305, 2397, 545, 554, 1732, 1107, 897, 58, - 537, 1335, 99, 181, 16501, 19, 493, 2, - 520, 2024, 129, 565, 556, 331, 192, 44, - 516, 1, 2432, 197, -910, 82, 4898, 14, - -963, 1, 886, 1750, 1691, 1920, 616, 645, - 2555, 155, 77, 36, 10886, 22, 506, 520, - 1804, 16, 870, 9, -1321, 2097, 1547, 2548, - 702, 1259, 8016, 561, 21, 2099, 606, 1, - 325, 5, 3624, 16, 1341, 2, 2997, 63, - 202, 2577, 966, 893, 297, 558, 12, 1017, - 2683, 1, 4145, 708, 5119, 16, -989, 1, - 768, 12, 1026, 180, 703, 81, 4373, 968, - 564, 621, 676, 1, 2583, 69, 1315, 27, - -1048, 2, 1531, 187, 7, 350, 4635, 17, - 2013, 515, 1109, 3288, 1011, 1, 530, 564, - 1074, 18, 1471, 100, 825, 181, 1150, 212, - 1011, 12, 1614, 985, 1082, 84, 102, 14, - 166, 224, 822, 19, -1079, 1630, 4882, 161, - 309, 1620, 390, 601, -1467, 1177, 1155, 692, - 940, 4, -406, 1, 1028, 566, -1118, 348, - 2880, 9, 122, 1782, 55, 3, 579, 1034, - 1252, 37, 1531, 1410, -504, 1, 1199, 569, - -1169, 405, 1541, 29, 387, 1989, 33, 816, - 4142, 872, 1347, 517, 2656, 1393, -610, 1, - 1191, 31, 1294, 164, 16301, 10, 857, 602, - 32, 985, 2445, 1208, 323, 2159, 3138, 31, - 3063, 1, 1033, 35, 1048, 40, 1655, 50, - 1144, 577, 81, 170, 13582, 1154, 2882, 424, - 5094, 288 + 5173, 1327, 662, 96, -164, 48, -492, 1, + 365, 482, 321, 681, 4198, 272, 313, 2175, + 861, 42, 151, 387, 2049, 2, 126, 2543, + 1017, 18, 1026, 869, 1317, 1, 1026, 547, + -1089, 1, -235, 197, 1443, 970, 380, 589, + 322, 1290, 4261, 224, 375, 2601, 2433, 75, + 84, -78, 2350, 1, 233, 201, 1411, 36, + 490, 484, -981, 2, 2336, 3, 286, 65, + 3591, 553, -522, 685, 209, 535, 2717, 416, + 640, 610, 70, 1447, 887, 162, 76, 659, + 862, 1, 546, 1898, 5192, 11, 2941, 630, + 5, 4, 6427, 2, 1465, 79, 2714, 247, + 2133, 1592, 3167, 4, -1186, 1824, 9109, 126, + 201, 4990, 116, 9, 271, 1173, 2684, 2, + 3193, 5555, 187, 1, 598, 3070, 1789, 8, + 207, 18, 2105, 1, 378, 1393, -718, 2572, + -1149, 37, 528, 6943, 14669, 141, 1099, 1486, + 1219, 530, 5, 2073, 1868, 1, 852, 395, + 1236, 1, 1358, 969, 1801, 36, 117, 13, + 279, 4, 529, 31, 2582, 3135, -1156, 333, + 32767, 1410, 16838, 61, 239, -994, 1536, 2, + 520, 2958, 2821, 4, 560, 2608, -419, 3, + 594, 270, 3218, 506, 720, 2, 1026, 131, + 256, 718, 2657, 1591, 1672, 449, -1520, -927, + 540, 2, 1041, -1035, 1749, 7, 1121, 842, + 2419, 1, 776, 1239, -469, 33, 2144, 299, + 1400, 802, -77, 88, -85, 72, 533, 609, + 1851, 1666, 305, 8, -1564, -977, 4680, 27, + 107, 753, 1831, 6, 348, 1745, 2786, 2, + 535, 1897, 8874, 13, 2239, 157, 1703, 286, + 820, 9, 1240, 1631, 216, 768, 2977, 292, + -1162, 5, 1210, 946, 6605, 741, 49, 384, + 794, 2, 524, 241, 656, 12, 122, 1978, + 2495, 4, 8929, 575, 7400, 513, 1071, 32, + -479, 15, 651, 1024, 666, 854, 1797, 4, + 183, -412, 852, 6, 127, 1574, 2028, 1, + 69, 1571, 1799, 1, 485, 2664, 3076, 1 }; -static const unsigned _uccase_upper_table_size = 1552; +static const unsigned _uccase_upper_table_size = 1580; static const unsigned _uccase_upper_table[] = { - 0x0000012b, 0x0000012a, 0x00000271, 0x00002c6e, - 0x0000a687, 0x0000a686, 0x000013fb, 0x000013f3, - 0x0000050d, 0x0000050c, 0x00002cee, 0x00002ced, - 0x00001fa7, 0x02000045, 0x00001e8b, 0x00001e8a, - 0x00001f94, 0x02000024, 0x00002c44, 0x00002c14, - 0x0000a691, 0x0000a690, 0x00001f62, 0x00001f6a, - 0x000105b4, 0x0001058d, 0x00001e47, 0x00001e46, - 0x0000abab, 0x000013db, 0x0000024f, 0x0000024e, - 0x00001c81, 0x00000414, 0x0000a741, 0x0000a740, - 0x0000ab82, 0x000013b2, 0x00000078, 0x00000058, - 0x000010ed, 0x00001cad, 0x00010ce4, 0x00010ca4, - 0x00000493, 0x00000492, 0x00000430, 0x00000410, - 0x0000a72d, 0x0000a72c, 0x00000205, 0x00000204, - 0x0000abb2, 0x000013e2, 0x000001dd, 0x0000018e, - 0x000010f5, 0x00001cb5, 0x000104fa, 0x000104d2, - 0x0000049b, 0x0000049a, 0x000024da, 0x000024c0, - 0x00001e0b, 0x00001e0a, 0x00001fab, 0x0200010c, - 0x00001e9a, 0x02000097, 0x00002178, 0x00002168, - 0x0000a695, 0x0000a694, 0x00016e63, 0x00016e43, - 0x00002cb9, 0x00002cb8, 0x00000185, 0x00000184, - 0x00001e0d, 0x00001e0c, 0x00000142, 0x00000141, - 0x00010d70, 0x00010d50, 0x0000aba2, 0x000013d2, - 0x00001ec7, 0x00001ec6, 0x00001ecf, 0x00001ece, - 0x000000eb, 0x000000cb, 0x0000019b, 0x0000a7dc, - 0x00010d81, 0x00010d61, 0x00001ffc, 0x02000121, - 0x0000056d, 0x0000053d, 0x00010cd1, 0x00010c91, - 0x0001e92d, 0x0001e90b, 0x00000161, 0x00000160, - 0x0001043c, 0x00010414, 0x00000269, 0x00000196, - 0x0000a7db, 0x0000a7da, 0x0000a745, 0x0000a744, - 0x00002c5f, 0x00002c2f, 0x0000ab83, 0x000013b3, - 0x00000252, 0x00002c70, 0x00000242, 0x00000241, - 0x00000573, 0x00000543, 0x0000a7d9, 0x0000a7d8, - 0x00001f86, 0x02000012, 0x00001f02, 0x00001f0a, - 0x0000014d, 0x0000014c, 0x000104f2, 0x000104ca, - 0x0000a65b, 0x0000a65a, 0x000004bf, 0x000004be, - 0x00001f23, 0x00001f2b, 0x0000aba1, 0x000013d1, - 0x000001c9, 0x000001c7, 0x0000ab77, 0x000013a7, - 0x000104e4, 0x000104bc, 0x00000473, 0x00000472, - 0x00000390, 0x03000080, 0x00002cb7, 0x00002cb6, - 0x00000209, 0x00000208, 0x00001ef1, 0x00001ef0, - 0x0000217f, 0x0000216f, 0x00010cda, 0x00010c9a, - 0x00001fe2, 0x030000be, 0x00001ef5, 0x00001ef4, - 0x0000057a, 0x0000054a, 0x00010443, 0x0001041b, - 0x000001a3, 0x000001a2, 0x0000a781, 0x0000a780, - 0x000004e3, 0x000004e2, 0x0000a757, 0x0000a756, - 0x00010ced, 0x00010cad, 0x00002ccb, 0x00002cca, - 0x00001f32, 0x00001f3a, 0x0001059b, 0x00010574, - 0x000004cf, 0x000004c0, 0x0000a74f, 0x0000a74e, - 0x00001f11, 0x00001f19, 0x00000061, 0x00000041, - 0x0000a64f, 0x0000a64e, 0x00000477, 0x00000476, - 0x00010d7a, 0x00010d5a, 0x00002c68, 0x00002c67, - 0x000004f7, 0x000004f6, 0x00002d05, 0x000010a5, - 0x00000127, 0x00000126, 0x0001043a, 0x00010412, - 0x000010f2, 0x00001cb2, 0x000003ed, 0x000003ec, - 0x000104dd, 0x000104b5, 0x00001e71, 0x00001e70, - 0x000000e1, 0x000000c1, 0x000003f5, 0x00000395, - 0x000010d1, 0x00001c91, 0x0000013e, 0x0000013d, - 0x0000a7a7, 0x0000a7a6, 0x0000ff52, 0x0000ff32, - 0x000024e4, 0x000024ca, 0x0000051d, 0x0000051c, - 0x00000283, 0x000001a9, 0x000010d9, 0x00001c99, - 0x0000ff59, 0x0000ff39, 0x000003b0, 0x03000084, - 0x00001efb, 0x00001efa, 0x000118c2, 0x000118a2, - 0x0000ab72, 0x000013a2, 0x00001f35, 0x00001f3d, - 0x0000028b, 0x000001b2, 0x0000a69b, 0x0000a69a, - 0x000003cc, 0x0000038c, 0x00016e68, 0x00016e48, - 0x000003f0, 0x0000039a, 0x0000016b, 0x0000016a, - 0x00000272, 0x0000019d, 0x0000a661, 0x0000a660, - 0x000001cc, 0x000001ca, 0x00000451, 0x00000401, - 0x00001e07, 0x00001e06, 0x00001f37, 0x00001f3f, - 0x0001044a, 0x00010422, 0x0001e930, 0x0001e90e, - 0x000004fb, 0x000004fa, 0x000004d3, 0x000004d2, - 0x00002c9f, 0x00002c9e, 0x00000111, 0x00000110, - 0x00002c30, 0x00002c00, 0x00001fa6, 0x02000042, - 0x000000f0, 0x000000d0, 0x000104e2, 0x000104ba, - 0x00002d24, 0x000010c4, 0x00001ee7, 0x00001ee6, - 0x0000020b, 0x0000020a, 0x00002c89, 0x00002c88, - 0x000003c6, 0x000003a6, 0x0000a747, 0x0000a746, - 0x0000a76b, 0x0000a76a, 0x000004f5, 0x000004f4, - 0x0000ff5a, 0x0000ff3a, 0x0000ab75, 0x000013a5, - 0x000003af, 0x0000038a, 0x00001efd, 0x00001efc, - 0x00000101, 0x00000100, 0x0000a693, 0x0000a692, - 0x00001f9a, 0x020000f1, 0x000010dd, 0x00001c9d, - 0x00001f52, 0x0300009d, 0x000000df, 0x02000051, - 0x00000503, 0x00000502, 0x00010d7b, 0x00010d5b, - 0x0000fb01, 0x02000057, 0x000003c2, 0x000003a3, - 0x0000016d, 0x0000016c, 0x00000263, 0x00000194, - 0x0001044b, 0x00010423, 0x00000465, 0x00000464, - 0x000003ad, 0x00000388, 0x00001fb4, 0x02000127, - 0x0000abb1, 0x000013e1, 0x00001e25, 0x00001e24, - 0x00000148, 0x00000147, 0x0001e93c, 0x0001e91a, - 0x000000ee, 0x000000ce, 0x0000023f, 0x00002c7e, - 0x0000abba, 0x000013ea, 0x00001f00, 0x00001f08, - 0x00010d79, 0x00010d59, 0x000003cd, 0x0000038e, - 0x0000a651, 0x0000a650, 0x0000ab84, 0x000013b4, - 0x00002c58, 0x00002c28, 0x0000057b, 0x0000054b, - 0x000010fa, 0x00001cba, 0x00010ce8, 0x00010ca8, - 0x000004a1, 0x000004a0, 0x00002c95, 0x00002c94, - 0x00000567, 0x00000537, 0x0000a657, 0x0000a656, - 0x000000ed, 0x000000cd, 0x00001f8f, 0x020000e8, - 0x000000e4, 0x000000c4, 0x00001f9e, 0x020000fd, - 0x00001c86, 0x0000042a, 0x000118c8, 0x000118a8, - 0x0000a68f, 0x0000a68e, 0x0000011b, 0x0000011a, - 0x0000a77a, 0x0000a779, 0x0000015b, 0x0000015a, - 0x000001f2, 0x000001f1, 0x00010ce5, 0x00010ca5, - 0x00001e6b, 0x00001e6a, 0x00001f51, 0x00001f59, - 0x00001f12, 0x00001f1a, 0x0000a66b, 0x0000a66a, - 0x000104e9, 0x000104c1, 0x000024d4, 0x000024ba, - 0x00000073, 0x00000053, 0x00001f95, 0x02000027, - 0x00002c76, 0x00002c75, 0x0000a65d, 0x0000a65c, - 0x0000026b, 0x00002c62, 0x00000455, 0x00000405, - 0x00001ff6, 0x020000d0, 0x00001f70, 0x00001fba, - 0x0001042a, 0x00010402, 0x000013f8, 0x000013f0, - 0x000001e1, 0x000001e0, 0x00016e72, 0x00016e52, - 0x00002d0a, 0x000010aa, 0x00001e01, 0x00001e00, - 0x00000062, 0x00000042, 0x0000ab93, 0x000013c3, - 0x00001fc7, 0x0300013a, 0x000004d1, 0x000004d0, - 0x00000575, 0x00000545, 0x0000abbf, 0x000013ef, - 0x000118de, 0x000118be, 0x000010d5, 0x00001c95, - 0x00002d11, 0x000010b1, 0x0000047f, 0x0000047e, - 0x0000217b, 0x0000216b, 0x000105b7, 0x00010590, - 0x000118d0, 0x000118b0, 0x00001ead, 0x00001eac, - 0x00001f87, 0x02000015, 0x00002cbf, 0x00002cbe, - 0x0001043d, 0x00010415, 0x000000fd, 0x000000dd, - 0x000004d7, 0x000004d6, 0x00001e65, 0x00001e64, - 0x000118d8, 0x000118b8, 0x00002d02, 0x000010a2, - 0x0000a66d, 0x0000a66c, 0x0000a763, 0x0000a762, - 0x000004cc, 0x000004cb, 0x00001eed, 0x00001eec, - 0x00000153, 0x00000152, 0x00001e7b, 0x00001e7a, - 0x000104fb, 0x000104d3, 0x00002c5c, 0x00002c2c, - 0x000004e7, 0x000004e6, 0x0000ab78, 0x000013a8, - 0x00002d03, 0x000010a3, 0x00001e41, 0x00001e40, - 0x0001e92c, 0x0001e90a, 0x0000a72f, 0x0000a72e, - 0x000004b9, 0x000004b8, 0x000001fb, 0x000001fa, - 0x00016e61, 0x00016e41, 0x000001d2, 0x000001d1, - 0x0000ab7d, 0x000013ad, 0x000003b1, 0x00000391, - 0x0001e93d, 0x0001e91b, 0x000104e7, 0x000104bf, - 0x00001ec9, 0x00001ec8, 0x0000006e, 0x0000004e, - 0x00001fa9, 0x02000106, 0x000118df, 0x000118bf, - 0x000104f0, 0x000104c8, 0x00001c88, 0x0000a64a, - 0x000105b9, 0x00010592, 0x00001e19, 0x00001e18, - 0x00001ea9, 0x00001ea8, 0x000001bd, 0x000001bc, - 0x0001e92e, 0x0001e90c, 0x0001e93f, 0x0001e91d, - 0x0000046d, 0x0000046c, 0x000003ce, 0x0000038f, - 0x00001ee9, 0x00001ee8, 0x00000183, 0x00000182, - 0x0000ab95, 0x000013c5, 0x0000ff43, 0x0000ff23, - 0x0000a647, 0x0000a646, 0x0000a767, 0x0000a766, - 0x000104e3, 0x000104bb, 0x00002d09, 0x000010a9, - 0x00001e83, 0x00001e82, 0x00001f85, 0x0200000f, - 0x00002c91, 0x00002c90, 0x000004c6, 0x000004c5, - 0x000013fd, 0x000013f5, 0x000118cd, 0x000118ad, - 0x000003e5, 0x000003e4, 0x0000ab8f, 0x000013bf, - 0x000003db, 0x000003da, 0x0000049d, 0x0000049c, - 0x00001fa2, 0x02000036, 0x0000abbb, 0x000013eb, - 0x00001e9b, 0x00001e60, 0x000010eb, 0x00001cab, - 0x00010431, 0x00010409, 0x0000a655, 0x0000a654, - 0x000001eb, 0x000001ea, 0x0000ff4c, 0x0000ff2c, - 0x00001e51, 0x00001e50, 0x000024de, 0x000024c4, - 0x000118cb, 0x000118ab, 0x00010440, 0x00010418, - 0x000003b5, 0x00000395, 0x0000051f, 0x0000051e, - 0x000024db, 0x000024c1, 0x000000e7, 0x000000c7, - 0x000003f1, 0x000003a1, 0x0001e925, 0x0001e903, - 0x00002c40, 0x00002c10, 0x0001044c, 0x00010424, - 0x0000fb02, 0x0200005a, 0x00001fb0, 0x00001fb8, - 0x0000fb13, 0x0200006e, 0x00001ea3, 0x00001ea2, - 0x00002d0f, 0x000010af, 0x00010d7c, 0x00010d5c, - 0x00000505, 0x00000504, 0x00001e5b, 0x00001e5a, - 0x000118c3, 0x000118a3, 0x0000026f, 0x0000019c, - 0x0000ab9f, 0x000013cf, 0x0000011f, 0x0000011e, - 0x000004d5, 0x000004d4, 0x00000140, 0x0000013f, - 0x00001f42, 0x00001f4a, 0x00001e4b, 0x00001e4a, - 0x00000173, 0x00000172, 0x00010d74, 0x00010d54, - 0x00000444, 0x00000424, 0x0000a7a5, 0x0000a7a4, - 0x00001e21, 0x00001e20, 0x00001e3d, 0x00001e3c, - 0x0001e93a, 0x0001e918, 0x00010cec, 0x00010cac, - 0x00000495, 0x00000494, 0x0000a755, 0x0000a754, - 0x00002c36, 0x00002c06, 0x00001fad, 0x02000112, - 0x00000521, 0x00000520, 0x00001f73, 0x00001fc9, - 0x000010f7, 0x00001cb7, 0x000003bd, 0x0000039d, - 0x00002d04, 0x000010a4, 0x00002d08, 0x000010a8, - 0x000000e3, 0x000000c3, 0x00001e09, 0x00001e08, - 0x000000f1, 0x000000d1, 0x0000214e, 0x00002132, - 0x00000525, 0x00000524, 0x00010435, 0x0001040d, - 0x000003ba, 0x0000039a, 0x00000440, 0x00000420, - 0x00001e7f, 0x00001e7e, 0x0000217c, 0x0000216c, - 0x00002c38, 0x00002c08, 0x00010599, 0x00010572, - 0x0000044b, 0x0000042b, 0x000004c8, 0x000004c7, - 0x00001e93, 0x00001e92, 0x000003ae, 0x00000389, - 0x000004a7, 0x000004a6, 0x0000a685, 0x0000a684, - 0x00001e1b, 0x00001e1a, 0x000118db, 0x000118bb, - 0x00001e4d, 0x00001e4c, 0x00001f43, 0x00001f4b, - 0x000001e7, 0x000001e6, 0x00002d0e, 0x000010ae, - 0x00000450, 0x00000400, 0x000004dd, 0x000004dc, - 0x00001f90, 0x02000018, 0x000010f1, 0x00001cb1, - 0x00010ce6, 0x00010ca6, 0x0000a735, 0x0000a734, - 0x0000052d, 0x0000052c, 0x00016e70, 0x00016e50, - 0x00000203, 0x00000202, 0x00002d13, 0x000010b3, - 0x00010439, 0x00010411, 0x0000a64d, 0x0000a64c, - 0x000000fb, 0x000000db, 0x00001e1f, 0x00001e1e, - 0x000004ed, 0x000004ec, 0x0000abb6, 0x000013e6, - 0x000001cb, 0x000001ca, 0x000024e6, 0x000024cc, - 0x00002d01, 0x000010a1, 0x00001eb1, 0x00001eb0, - 0x00000569, 0x00000539, 0x00002cbb, 0x00002cba, - 0x0000fb03, 0x0300005d, 0x00000233, 0x00000232, - 0x0000043a, 0x0000041a, 0x00010445, 0x0001041d, - 0x0000057c, 0x0000054c, 0x00001ee5, 0x00001ee4, - 0x0000ab8b, 0x000013bb, 0x00001ebd, 0x00001ebc, - 0x000001a5, 0x000001a4, 0x000001ef, 0x000001ee, - 0x000001f5, 0x000001f4, 0x00001e8f, 0x00001e8e, - 0x0000ab98, 0x000013c8, 0x00002d00, 0x000010a0, - 0x00000149, 0x0200007d, 0x00010d83, 0x00010d63, - 0x00016e6e, 0x00016e4e, 0x00016e77, 0x00016e57, - 0x000003e3, 0x000003e2, 0x00000070, 0x00000050, - 0x00000155, 0x00000154, 0x0000a79f, 0x0000a79e, - 0x0000217e, 0x0000216e, 0x0000ff47, 0x0000ff27, - 0x000004df, 0x000004de, 0x00001f84, 0x0200000c, - 0x00001e5d, 0x00001e5c, 0x00001e37, 0x00001e36, - 0x000000e8, 0x000000c8, 0x00002173, 0x00002163, - 0x0000a7d7, 0x0000a7d6, 0x00010429, 0x00010401, - 0x00002cc3, 0x00002cc2, 0x00000207, 0x00000206, - 0x0001e922, 0x0001e900, 0x00002170, 0x00002160, - 0x0000a7a9, 0x0000a7a8, 0x00010cdd, 0x00010c9d, - 0x00002d07, 0x000010a7, 0x00002d10, 0x000010b0, - 0x00001e79, 0x00001e78, 0x00000377, 0x00000376, - 0x00010447, 0x0001041f, 0x00016e67, 0x00016e47, - 0x0000a791, 0x0000a790, 0x00001f04, 0x00001f0c, - 0x00001e2d, 0x00001e2c, 0x000001ad, 0x000001ac, - 0x000104f9, 0x000104d1, 0x0000045b, 0x0000040b, - 0x00000109, 0x00000108, 0x00001f92, 0x0200001e, - 0x00002c81, 0x00002c80, 0x0001e92b, 0x0001e909, - 0x00010cdf, 0x00010c9f, 0x0001044f, 0x00010427, - 0x0000a75d, 0x0000a75c, 0x00010cce, 0x00010c8e, - 0x00001e33, 0x00001e32, 0x0000abad, 0x000013dd, - 0x000001e9, 0x000001e8, 0x0000017c, 0x0000017b, - 0x00010cee, 0x00010cae, 0x0000047d, 0x0000047c, - 0x00002c3d, 0x00002c0d, 0x0000019e, 0x00000220, - 0x00001fd3, 0x030000b3, 0x000003c5, 0x000003a5, - 0x00010ce2, 0x00010ca2, 0x000010d8, 0x00001c98, - 0x0001059e, 0x00010577, 0x0000056a, 0x0000053a, - 0x0000ff56, 0x0000ff36, 0x0000a7bf, 0x0000a7be, - 0x00001fd1, 0x00001fd9, 0x00000229, 0x00000228, - 0x00001f01, 0x00001f09, 0x00001c80, 0x00000412, - 0x0000fb05, 0x02000065, 0x00002c53, 0x00002c23, - 0x00001f8c, 0x020000df, 0x0000ff58, 0x0000ff38, - 0x0000037c, 0x000003fe, 0x00001fe5, 0x00001fec, - 0x00001fe1, 0x00001fe9, 0x00002cad, 0x00002cac, - 0x000010fe, 0x00001cbe, 0x00010448, 0x00010420, - 0x000003ef, 0x000003ee, 0x000001ed, 0x000001ec, - 0x000024e0, 0x000024c6, 0x00001e63, 0x00001e62, - 0x00001f71, 0x00001fbb, 0x0000a79b, 0x0000a79a, - 0x0000a649, 0x0000a648, 0x000003b2, 0x00000392, - 0x00010ccd, 0x00010c8d, 0x000010dc, 0x00001c9c, - 0x00001f54, 0x030000a1, 0x00001fa8, 0x02000103, - 0x0000043c, 0x0000041c, 0x00001edb, 0x00001eda, - 0x00010ce9, 0x00010ca9, 0x000104d9, 0x000104b1, - 0x00002d15, 0x000010b5, 0x00000075, 0x00000055, - 0x00002ce3, 0x00002ce2, 0x000001e3, 0x000001e2, - 0x00016e7e, 0x00016e5e, 0x00000583, 0x00000553, - 0x00000576, 0x00000546, 0x00001f15, 0x00001f1d, - 0x000010d0, 0x00001c90, 0x00001f8e, 0x020000e5, - 0x00002d1c, 0x000010bc, 0x00010cd9, 0x00010c99, - 0x000104db, 0x000104b3, 0x000118da, 0x000118ba, - 0x000000e5, 0x000000c5, 0x000105bc, 0x00010595, - 0x000024e5, 0x000024cb, 0x00010cd2, 0x00010c92, - 0x00001e7d, 0x00001e7c, 0x000118ce, 0x000118ae, - 0x00002cdb, 0x00002cda, 0x00001f63, 0x00001f6b, - 0x00010cd8, 0x00010c98, 0x00000457, 0x00000407, - 0x000000fe, 0x000000de, 0x000003f2, 0x000003f9, - 0x00001e61, 0x00001e60, 0x0000ab97, 0x000013c7, - 0x0000006c, 0x0000004c, 0x0000a725, 0x0000a724, - 0x00010ce7, 0x00010ca7, 0x00002c8f, 0x00002c8e, - 0x0000ab9a, 0x000013ca, 0x00001ef7, 0x00001ef6, - 0x00001ee1, 0x00001ee0, 0x00001faa, 0x02000109, - 0x00010449, 0x00010421, 0x00000437, 0x00000417, - 0x00001fc4, 0x0200012d, 0x00002d12, 0x000010b2, - 0x00001e53, 0x00001e52, 0x0000024b, 0x0000024a, - 0x00002c59, 0x00002c29, 0x00016e74, 0x00016e54, - 0x0000a739, 0x0000a738, 0x00000447, 0x00000427, - 0x00000105, 0x00000104, 0x0000ab73, 0x000013a3, - 0x00010cde, 0x00010c9e, 0x00000433, 0x00000413, - 0x0001044d, 0x00010425, 0x00001ec5, 0x00001ec4, - 0x00001f9d, 0x020000fa, 0x0000aba3, 0x000013d3, - 0x00001fb7, 0x03000136, 0x000004a5, 0x000004a4, - 0x0000a749, 0x0000a748, 0x0000ab8c, 0x000013bc, - 0x00001f7c, 0x00001ffa, 0x00002cd5, 0x00002cd4, - 0x00001f89, 0x020000d6, 0x0001e92a, 0x0001e908, - 0x000003b4, 0x00000394, 0x00000463, 0x00000462, - 0x00010cf1, 0x00010cb1, 0x00002c9b, 0x00002c9a, - 0x00000195, 0x000001f6, 0x00000439, 0x00000419, - 0x0001e939, 0x0001e917, 0x0000a783, 0x0000a782, - 0x00000570, 0x00000540, 0x000003e9, 0x000003e8, - 0x0000010d, 0x0000010c, 0x00001e6d, 0x00001e6c, - 0x00002174, 0x00002164, 0x0000a737, 0x0000a736, - 0x00002c4a, 0x00002c1a, 0x0000ff50, 0x0000ff30, - 0x00002c55, 0x00002c25, 0x00010432, 0x0001040a, - 0x0000aba5, 0x000013d5, 0x0000a7c3, 0x0000a7c2, - 0x000004bb, 0x000004ba, 0x0000021d, 0x0000021c, - 0x00010cc7, 0x00010c87, 0x000000f9, 0x000000d9, - 0x000010ef, 0x00001caf, 0x00000121, 0x00000120, - 0x0000048d, 0x0000048c, 0x000105a0, 0x00010579, - 0x00001f7a, 0x00001fea, 0x00000067, 0x00000047, - 0x0001e929, 0x0001e907, 0x00001f96, 0x0200002a, - 0x000105a6, 0x0001057f, 0x000105bb, 0x00010594, - 0x00000436, 0x00000416, 0x00016e7b, 0x00016e5b, - 0x00001eab, 0x00001eaa, 0x0000abac, 0x000013dc, - 0x0000a7bd, 0x0000a7bc, 0x00002c6a, 0x00002c69, - 0x0000043e, 0x0000041e, 0x00000445, 0x00000425, - 0x000003c4, 0x000003a4, 0x00001f13, 0x00001f1b, - 0x000010e4, 0x00001ca4, 0x00010cd0, 0x00010c90, - 0x000004c4, 0x000004c3, 0x00010cc3, 0x00010c83, - 0x00001fbe, 0x00000399, 0x00000446, 0x00000426, - 0x00001e85, 0x00001e84, 0x000024e2, 0x000024c8, - 0x0000ff44, 0x0000ff24, 0x0000a683, 0x0000a682, - 0x00000571, 0x00000541, 0x00001f7b, 0x00001feb, - 0x0000013c, 0x0000013b, 0x0000017f, 0x00000053, - 0x000003c3, 0x000003a3, 0x0000ff4e, 0x0000ff2e, - 0x00010cd6, 0x00010c96, 0x0000ab94, 0x000013c4, - 0x00001e35, 0x00001e34, 0x0000ab79, 0x000013a9, - 0x00002c47, 0x00002c17, 0x000001da, 0x000001d9, - 0x00010cd5, 0x00010c95, 0x00001fa3, 0x02000039, - 0x0000ff42, 0x0000ff22, 0x00000177, 0x00000176, - 0x00000151, 0x00000150, 0x00010d82, 0x00010d62, - 0x000003b7, 0x00000397, 0x0000a76d, 0x0000a76c, - 0x0000ab86, 0x000013b6, 0x00002cdd, 0x00002cdc, - 0x00000529, 0x00000528, 0x000010e9, 0x00001ca9, - 0x0000a641, 0x0000a640, 0x00000469, 0x00000468, - 0x00000572, 0x00000542, 0x00000264, 0x0000a7cb, - 0x0000fb15, 0x02000074, 0x00000275, 0x0000019f, - 0x00010d75, 0x00010d55, 0x0000ff4b, 0x0000ff2b, - 0x00001e91, 0x00001e90, 0x0000a645, 0x0000a644, - 0x000004ca, 0x000004c9, 0x00001e8d, 0x00001e8c, - 0x00002c3e, 0x00002c0e, 0x00000443, 0x00000423, - 0x0000a681, 0x0000a680, 0x00000448, 0x00000428, - 0x00001d79, 0x0000a77d, 0x00001f05, 0x00001f0d, - 0x0000013a, 0x00000139, 0x00000253, 0x00000181, - 0x0000057e, 0x0000054e, 0x0000a76f, 0x0000a76e, - 0x0000ab96, 0x000013c6, 0x00001e57, 0x00001e56, - 0x0000ab81, 0x000013b1, 0x00010cc6, 0x00010c86, - 0x00001c8a, 0x00001c89, 0x00002c66, 0x0000023e, - 0x00000266, 0x0000a7aa, 0x00000066, 0x00000046, - 0x00001f64, 0x00001f6c, 0x00010446, 0x0001041e, - 0x000010f9, 0x00001cb9, 0x000010ea, 0x00001caa, - 0x00000438, 0x00000418, 0x00001f26, 0x00001f2e, - 0x0000abb8, 0x000013e8, 0x00001fc3, 0x0200004b, - 0x0000028a, 0x000001b1, 0x0000217d, 0x0000216d, - 0x00000471, 0x00000470, 0x0000a659, 0x0000a658, - 0x00002c99, 0x00002c98, 0x00001ff3, 0x0200004e, - 0x0000027d, 0x00002c64, 0x0001e932, 0x0001e910, - 0x0000ff53, 0x0000ff33, 0x00000479, 0x00000478, - 0x00000561, 0x00000531, 0x00000268, 0x00000197, - 0x00002cbd, 0x00002cbc, 0x0000ab85, 0x000013b5, - 0x0000ff48, 0x0000ff28, 0x00002cc9, 0x00002cc8, - 0x0000056f, 0x0000053f, 0x000118c5, 0x000118a5, - 0x000000b5, 0x0000039c, 0x00000163, 0x00000162, - 0x00010433, 0x0001040b, 0x0001e92f, 0x0001e90d, - 0x000024e3, 0x000024c9, 0x00010ce1, 0x00010ca1, - 0x00000063, 0x00000043, 0x00001f57, 0x00001f5f, - 0x00002c41, 0x00002c11, 0x00001e23, 0x00001e22, - 0x000104da, 0x000104b2, 0x000010d4, 0x00001c94, - 0x00000180, 0x00000243, 0x00001f76, 0x00001fda, - 0x0000014f, 0x0000014e, 0x0000028c, 0x00000245, - 0x00010cd4, 0x00010c94, 0x00010d78, 0x00010d58, - 0x000105a4, 0x0001057d, 0x00002ccf, 0x00002cce, - 0x000118c7, 0x000118a7, 0x0001e933, 0x0001e911, - 0x00001ecb, 0x00001eca, 0x0000045d, 0x0000040d, - 0x00016e69, 0x00016e49, 0x00001fc2, 0x0200012a, - 0x000118c1, 0x000118a1, 0x0000ab7c, 0x000013ac, - 0x00001faf, 0x02000118, 0x00002d22, 0x000010c2, - 0x0000ab9c, 0x000013cc, 0x00016e79, 0x00016e59, - 0x000118c0, 0x000118a0, 0x0000abb3, 0x000013e3, - 0x00002c5b, 0x00002c2b, 0x000003bc, 0x0000039c, - 0x0000045a, 0x0000040a, 0x0000a733, 0x0000a732, - 0x000118dc, 0x000118bc, 0x0000ab89, 0x000013b9, - 0x0000abbd, 0x000013ed, 0x00000259, 0x0000018f, - 0x00016e60, 0x00016e40, 0x0000a753, 0x0000a752, - 0x0000020d, 0x0000020c, 0x00000065, 0x00000045, - 0x0000abaa, 0x000013da, 0x000001e5, 0x000001e4, - 0x0001e934, 0x0001e912, 0x0000a793, 0x0000a792, - 0x00001fc6, 0x020000ac, 0x00001e4f, 0x00001e4e, - 0x00001f36, 0x00001f3e, 0x000001b9, 0x000001b8, - 0x00002c57, 0x00002c27, 0x000000f5, 0x000000d5, - 0x000004ad, 0x000004ac, 0x0000a643, 0x0000a642, - 0x0000057d, 0x0000054d, 0x00000076, 0x00000056, - 0x0001e924, 0x0001e902, 0x0001059a, 0x00010573, - 0x0000ff4f, 0x0000ff2f, 0x00010cdc, 0x00010c9c, - 0x00002d0c, 0x000010ac, 0x00010cd7, 0x00010c97, - 0x00002cc5, 0x00002cc4, 0x0000037b, 0x000003fd, - 0x000105b5, 0x0001058e, 0x000003c8, 0x000003a8, - 0x00001ee3, 0x00001ee2, 0x000024d3, 0x000024b9, - 0x00002ca5, 0x00002ca4, 0x0000abb9, 0x000013e9, - 0x00000282, 0x0000a7c5, 0x00002176, 0x00002166, - 0x0000a785, 0x0000a784, 0x00001f10, 0x00001f18, - 0x00001e75, 0x00001e74, 0x00010cdb, 0x00010c9b, - 0x00000261, 0x0000a7ac, 0x0000a663, 0x0000a662, - 0x00010cc1, 0x00010c81, 0x000105a7, 0x00010580, - 0x0000006d, 0x0000004d, 0x00001f56, 0x030000a5, - 0x000104e8, 0x000104c0, 0x0001e935, 0x0001e913, - 0x0000043d, 0x0000041d, 0x0000021f, 0x0000021e, - 0x00002c35, 0x00002c05, 0x0000019a, 0x0000023d, - 0x0001042c, 0x00010404, 0x00002ce1, 0x00002ce0, - 0x00010cea, 0x00010caa, 0x0000a78c, 0x0000a78b, - 0x000105af, 0x00010588, 0x00002c49, 0x00002c19, - 0x00001e29, 0x00001e28, 0x000010f8, 0x00001cb8, - 0x000000ea, 0x000000ca, 0x00002c4d, 0x00002c1d, - 0x000104f3, 0x000104cb, 0x00000454, 0x00000404, - 0x000118d9, 0x000118b9, 0x000001ce, 0x000001cd, - 0x0000037d, 0x000003ff, 0x000000f6, 0x000000d6, - 0x00002175, 0x00002165, 0x00001e59, 0x00001e58, - 0x000118ca, 0x000118aa, 0x00002cc7, 0x00002cc6, - 0x00001fa5, 0x0200003f, 0x000024e1, 0x000024c7, - 0x000003cb, 0x000003ab, 0x00001fbc, 0x0200011b, - 0x000010d6, 0x00001c96, 0x00002c85, 0x00002c84, - 0x00001f53, 0x00001f5b, 0x0000024d, 0x0000024c, - 0x00000171, 0x00000170, 0x0000a759, 0x0000a758, - 0x00002c6c, 0x00002c6b, 0x0000ab9e, 0x000013ce, - 0x00001fb2, 0x02000124, 0x00001e67, 0x00001e66, - 0x0000a77c, 0x0000a77b, 0x0000a7cd, 0x0000a7cc, - 0x000004e1, 0x000004e0, 0x00002c3f, 0x00002c0f, - 0x00002d17, 0x000010b7, 0x00001e5f, 0x00001e5e, - 0x00001f99, 0x020000ee, 0x0000044f, 0x0000042f, - 0x00016e78, 0x00016e58, 0x00000585, 0x00000555, - 0x0000044d, 0x0000042d, 0x00001eff, 0x00001efe, - 0x00000133, 0x00000132, 0x0000025c, 0x0000a7ab, - 0x0000a699, 0x0000a698, 0x0000056b, 0x0000053b, - 0x00000458, 0x00000408, 0x0000a7ca, 0x0000a7c9, - 0x000010ff, 0x00001cbf, 0x00000199, 0x00000198, - 0x000104ee, 0x000104c6, 0x00001ed1, 0x00001ed0, - 0x0000044a, 0x0000042a, 0x00010d7d, 0x00010d5d, - 0x00002cd1, 0x00002cd0, 0x00001d8e, 0x0000a7c6, - 0x0000029d, 0x0000a7b2, 0x00000225, 0x00000224, - 0x0000047b, 0x0000047a, 0x000104e5, 0x000104bd, - 0x000003b6, 0x00000396, 0x00001f55, 0x00001f5d, - 0x000104ed, 0x000104c5, 0x000003e7, 0x000003e6, - 0x0000a761, 0x0000a760, 0x000004ab, 0x000004aa, - 0x00002c65, 0x0000023a, 0x000010d7, 0x00001c97, - 0x00001e6f, 0x00001e6e, 0x00000213, 0x00000212, - 0x0000a73b, 0x0000a73a, 0x0000a7c8, 0x0000a7c7, - 0x000004eb, 0x000004ea, 0x00002d1f, 0x000010bf, - 0x00000072, 0x00000052, 0x00001f33, 0x00001f3b, - 0x000003d5, 0x000003a6, 0x00016e76, 0x00016e56, - 0x0000a77f, 0x0000a77e, 0x000024e7, 0x000024cd, - 0x00002c43, 0x00002c13, 0x000010e1, 0x00001ca1, - 0x00010436, 0x0001040e, 0x0000048b, 0x0000048a, - 0x000104df, 0x000104b7, 0x0000a74b, 0x0000a74a, - 0x00000453, 0x00000403, 0x00000137, 0x00000136, - 0x000001b6, 0x000001b5, 0x000104e6, 0x000104be, - 0x0000052f, 0x0000052e, 0x00002c54, 0x00002c24, - 0x000024d5, 0x000024bb, 0x00002cd7, 0x00002cd6, - 0x00001f8b, 0x020000dc, 0x00000249, 0x00000248, - 0x00002c51, 0x00002c21, 0x0000a7b7, 0x0000a7b6, - 0x00002c97, 0x00002c96, 0x0000ab9d, 0x000013cd, - 0x000118d1, 0x000118b1, 0x0000ab53, 0x0000a7b3, - 0x000010f4, 0x00001cb4, 0x0000a74d, 0x0000a74c, - 0x00010cef, 0x00010caf, 0x000104f1, 0x000104c9, - 0x0000abae, 0x000013de, 0x0001042d, 0x00010405, - 0x00001f65, 0x00001f6d, 0x00001ecd, 0x00001ecc, - 0x0000044e, 0x0000042e, 0x00001fd2, 0x030000af, - 0x000003c1, 0x000003a1, 0x00001e43, 0x00001e42, - 0x0000aba7, 0x000013d7, 0x00002184, 0x00002183, - 0x000004bd, 0x000004bc, 0x0000a73d, 0x0000a73c, - 0x000004ef, 0x000004ee, 0x00001e17, 0x00001e16, - 0x00000131, 0x00000049, 0x0001042f, 0x00010407, - 0x0000ff54, 0x0000ff34, 0x000001f3, 0x000001f1, - 0x00001f06, 0x00001f0e, 0x000105b3, 0x0001058c, - 0x00001f20, 0x00001f28, 0x000010de, 0x00001c9e, - 0x00010444, 0x0001041c, 0x00000565, 0x00000535, - 0x00000497, 0x00000496, 0x00000523, 0x00000522, - 0x00002cdf, 0x00002cde, 0x00001e98, 0x02000091, - 0x0000a7bb, 0x0000a7ba, 0x00002c45, 0x00002c15, - 0x0000a79d, 0x0000a79c, 0x00000579, 0x00000549, - 0x00002c83, 0x00002c82, 0x0000fb16, 0x02000077, - 0x00001ef9, 0x00001ef8, 0x00000217, 0x00000216, - 0x00002d18, 0x000010b8, 0x0000017e, 0x0000017d, - 0x00000441, 0x00000421, 0x0000057f, 0x0000054f, - 0x00001e87, 0x00001e86, 0x00000103, 0x00000102, - 0x00002c4e, 0x00002c1e, 0x0000a68b, 0x0000a68a, - 0x0000abbc, 0x000013ec, 0x000003ac, 0x00000386, - 0x00002c8b, 0x00002c8a, 0x00000159, 0x00000158, - 0x0000015d, 0x0000015c, 0x0001e938, 0x0001e916, - 0x00000584, 0x00000554, 0x000004b3, 0x000004b2, - 0x0000007a, 0x0000005a, 0x0000ab7f, 0x000013af, - 0x00010ce0, 0x00010ca0, 0x00000491, 0x00000490, - 0x00001ed7, 0x00001ed6, 0x0001059d, 0x00010576, - 0x00002cab, 0x00002caa, 0x00001e99, 0x02000094, - 0x00001f77, 0x00001fdb, 0x00010d84, 0x00010d64, - 0x000003b9, 0x00000399, 0x0000a799, 0x0000a798, - 0x00001fe7, 0x030000cc, 0x0000ab99, 0x000013c9, - 0x000001c5, 0x000001c4, 0x000104f4, 0x000104cc, - 0x0000217a, 0x0000216a, 0x0000046f, 0x0000046e, - 0x00000146, 0x00000145, 0x00002cb3, 0x00002cb2, - 0x0000fb17, 0x0200007a, 0x0000ab8d, 0x000013bd, - 0x0001e931, 0x0001e90f, 0x00002c3c, 0x00002c0c, - 0x000104ef, 0x000104c7, 0x0000020f, 0x0000020e, - 0x00002d06, 0x000010a6, 0x0001043b, 0x00010413, - 0x000010db, 0x00001c9b, 0x00000475, 0x00000474, - 0x000004b1, 0x000004b0, 0x000105a3, 0x0001057c, - 0x00010598, 0x00010571, 0x0000ab8e, 0x000013be, - 0x00001f41, 0x00001f49, 0x000104d8, 0x000104b0, - 0x000010d2, 0x00001c92, 0x00001eb9, 0x00001eb8, - 0x00001eb3, 0x00001eb2, 0x00016e6d, 0x00016e4d, - 0x000010f3, 0x00001cb3, 0x00001fa1, 0x02000033, - 0x00002cc1, 0x00002cc0, 0x0000006a, 0x0000004a, - 0x0000051b, 0x0000051a, 0x000001dc, 0x000001db, - 0x00001f78, 0x00001ff8, 0x00010437, 0x0001040f, - 0x00010cc8, 0x00010c88, 0x000000e2, 0x000000c2, - 0x0000a7d1, 0x0000a7d0, 0x00000434, 0x00000414, - 0x00001e27, 0x00001e26, 0x00016e66, 0x00016e46, - 0x000010e2, 0x00001ca2, 0x000003c9, 0x000003a9, - 0x00010cca, 0x00010c8a, 0x000004fd, 0x000004fc, - 0x0000056c, 0x0000053c, 0x000118c6, 0x000118a6, - 0x00000250, 0x00002c6f, 0x00002c48, 0x00002c18, - 0x0000ff55, 0x0000ff35, 0x00001f9f, 0x02000100, - 0x00016e6f, 0x00016e4f, 0x0000a729, 0x0000a728, - 0x00001e31, 0x00001e30, 0x0001e942, 0x0001e920, - 0x00000287, 0x0000a7b1, 0x000104eb, 0x000104c3, - 0x00001c83, 0x00000421, 0x000104dc, 0x000104b4, - 0x00000527, 0x00000526, 0x00000165, 0x00000164, - 0x0000011d, 0x0000011c, 0x00016e6c, 0x00016e4c, - 0x000001fd, 0x000001fc, 0x000105aa, 0x00010583, - 0x00016e75, 0x00016e55, 0x0000014b, 0x0000014a, - 0x00000578, 0x00000548, 0x00010d77, 0x00010d57, - 0x00000566, 0x00000536, 0x000003e1, 0x000003e0, - 0x00002c9d, 0x00002c9c, 0x000004f1, 0x000004f0, - 0x0000ab76, 0x000013a6, 0x00010d73, 0x00010d53, - 0x00010cf0, 0x00010cb0, 0x000105ac, 0x00010585, - 0x000105a5, 0x0001057e, 0x000004af, 0x000004ae, - 0x00001e13, 0x00001e12, 0x000010d3, 0x00001c93, - 0x00010cc4, 0x00010c84, 0x000013fa, 0x000013f2, - 0x0000050b, 0x0000050a, 0x000003bf, 0x0000039f, - 0x00002ca1, 0x00002ca0, 0x000010ee, 0x00001cae, - 0x00002c42, 0x00002c12, 0x000024e9, 0x000024cf, - 0x00016e6a, 0x00016e4a, 0x00001fd6, 0x020000b7, - 0x0000aba4, 0x000013d4, 0x00002c87, 0x00002c86, - 0x00001f7d, 0x00001ffb, 0x00000563, 0x00000533, - 0x000001f0, 0x02000088, 0x00001f44, 0x00001f4c, - 0x00001fa4, 0x0200003c, 0x00001f22, 0x00001f2a, - 0x0001e93e, 0x0001e91c, 0x00000211, 0x00000210, - 0x0000a653, 0x0000a652, 0x00000519, 0x00000518, - 0x000104f5, 0x000104cd, 0x0000006b, 0x0000004b, - 0x0000ab80, 0x000013b0, 0x00001ef3, 0x00001ef2, - 0x000010e8, 0x00001ca8, 0x000105a9, 0x00010582, - 0x0001059f, 0x00010578, 0x00002d1e, 0x000010be, - 0x0000010f, 0x0000010e, 0x00000265, 0x0000a78d, - 0x000000fc, 0x000000dc, 0x000000ff, 0x00000178, - 0x0001e937, 0x0001e915, 0x000105a1, 0x0001057a, - 0x000004ce, 0x000004cd, 0x000001ff, 0x000001fe, - 0x0001e926, 0x0001e904, 0x0000ab87, 0x000013b7, - 0x00001fd7, 0x030000ba, 0x00010ccb, 0x00010c8b, - 0x0000ab90, 0x000013c0, 0x00001f21, 0x00001f29, - 0x00001e96, 0x0200008b, 0x00001f8a, 0x020000d9, - 0x0000ff41, 0x0000ff21, 0x0000a697, 0x0000a696, - 0x0000a7b5, 0x0000a7b4, 0x00001f83, 0x02000009, - 0x00001e2f, 0x00001e2e, 0x00001f34, 0x00001f3c, - 0x00010d72, 0x00010d52, 0x0000050f, 0x0000050e, - 0x0000a787, 0x0000a786, 0x000105b8, 0x00010591, - 0x000118dd, 0x000118bd, 0x0000ab92, 0x000013c2, - 0x00001f14, 0x00001f1c, 0x0000a665, 0x0000a664, - 0x00001ebb, 0x00001eba, 0x00002c93, 0x00002c92, - 0x00001eef, 0x00001eee, 0x00001f45, 0x00001f4d, - 0x0001e923, 0x0001e901, 0x0000a64b, 0x0000a64a, - 0x000105ab, 0x00010584, 0x0000022b, 0x0000022a, - 0x000104e0, 0x000104b8, 0x00002d1d, 0x000010bd, - 0x00000077, 0x00000057, 0x0000abb4, 0x000013e4, - 0x00001c84, 0x00000422, 0x00000586, 0x00000556, - 0x00016e7d, 0x00016e5d, 0x00001f24, 0x00001f2c, - 0x00001e11, 0x00001e10, 0x0000ab7e, 0x000013ae, - 0x00001f91, 0x0200001b, 0x00001fe6, 0x020000c9, - 0x00002c56, 0x00002c26, 0x000003f8, 0x000003f7, - 0x0000017a, 0x00000179, 0x0000ab74, 0x000013a4, - 0x00001fb1, 0x00001fb9, 0x0000015f, 0x0000015e, - 0x00002177, 0x00002167, 0x0000a794, 0x0000a7c4, - 0x000004f9, 0x000004f8, 0x00002cb1, 0x00002cb0, - 0x00000068, 0x00000048, 0x00000280, 0x000001a6, - 0x00000509, 0x00000508, 0x000000f4, 0x000000d4, - 0x00000517, 0x00000516, 0x00000188, 0x00000187, - 0x000118d4, 0x000118b4, 0x0000a7a3, 0x0000a7a2, - 0x00000113, 0x00000112, 0x0000a75f, 0x0000a75e, - 0x00000513, 0x00000512, 0x00000071, 0x00000051, - 0x00000175, 0x00000174, 0x00001e69, 0x00001e68, - 0x000003d6, 0x000003a0, 0x000000e6, 0x000000c6, - 0x000010e0, 0x00001ca0, 0x00002c73, 0x00002c72, - 0x00002d19, 0x000010b9, 0x00010428, 0x00010400, - 0x0000ab9b, 0x000013cb, 0x00000192, 0x00000191, - 0x0000a7a1, 0x0000a7a0, 0x00000587, 0x0200006b, - 0x0000ff4d, 0x0000ff2d, 0x00001eb7, 0x00001eb6, - 0x0000ab71, 0x000013a1, 0x000105ad, 0x00010586, - 0x0000048f, 0x0000048e, 0x00000582, 0x00000552, - 0x000024d6, 0x000024bc, 0x0000026c, 0x0000a7ad, - 0x00002cf3, 0x00002cf2, 0x00001e95, 0x00001e94, - 0x00002d20, 0x000010c0, 0x0001e941, 0x0001e91f, - 0x000010da, 0x00001c9a, 0x000118d2, 0x000118b2, - 0x00001ea5, 0x00001ea4, 0x000001a1, 0x000001a0, - 0x00000201, 0x00000200, 0x00002c32, 0x00002c02, - 0x00000461, 0x00000460, 0x0000fb00, 0x02000054, - 0x00001e55, 0x00001e54, 0x00001f74, 0x00001fca, - 0x00000260, 0x00000193, 0x00000345, 0x00000399, - 0x000013f9, 0x000013f1, 0x00002cec, 0x00002ceb, - 0x0000fb06, 0x02000068, 0x0000aba0, 0x000013d0, - 0x000104ea, 0x000104c2, 0x00002c8d, 0x00002c8c, - 0x00001eb5, 0x00001eb4, 0x0000a689, 0x0000a688, - 0x000001c8, 0x000001c7, 0x00002d1a, 0x000010ba, - 0x00010430, 0x00010408, 0x00000227, 0x00000226, - 0x000003d7, 0x000003cf, 0x00016e7a, 0x00016e5a, - 0x00010cc5, 0x00010c85, 0x00001f80, 0x02000000, - 0x000003fb, 0x000003fa, 0x000010f0, 0x00001cb0, - 0x00010438, 0x00010410, 0x00001fcc, 0x0200011e, - 0x00001c87, 0x00000462, 0x0000018c, 0x0000018b, - 0x00001f9c, 0x020000f7, 0x0001e927, 0x0001e905, - 0x0001044e, 0x00010426, 0x0000043b, 0x0000041b, - 0x00000580, 0x00000550, 0x000105b0, 0x00010589, - 0x000024d7, 0x000024bd, 0x00002cd9, 0x00002cd8, - 0x00001f8d, 0x020000e2, 0x00010442, 0x0001041a, - 0x00000107, 0x00000106, 0x0000a7c1, 0x0000a7c0, - 0x0000abbe, 0x000013ee, 0x00002ca9, 0x00002ca8, - 0x0000012f, 0x0000012e, 0x0000ab91, 0x000013c1, - 0x00002c39, 0x00002c09, 0x0000ff51, 0x0000ff31, - 0x00001ed5, 0x00001ed4, 0x00002c61, 0x00002c60, - 0x00010cd3, 0x00010c93, 0x000003c0, 0x000003a0, - 0x00001f67, 0x00001f6f, 0x0001043f, 0x00010417, - 0x00001ff2, 0x02000130, 0x000000ec, 0x000000cc, - 0x00001ff7, 0x0300013e, 0x00001e45, 0x00001e44, - 0x0000aba9, 0x000013d9, 0x000003df, 0x000003de, - 0x00016e7c, 0x00016e5c, 0x0000ff46, 0x0000ff26, - 0x00001e05, 0x00001e04, 0x00001e2b, 0x00001e2a, - 0x0000ab7b, 0x000013ab, 0x00000254, 0x00000186, - 0x00016e62, 0x00016e42, 0x000004db, 0x000004da, - 0x0000052b, 0x0000052a, 0x00000215, 0x00000214, - 0x000001c6, 0x000001c4, 0x00001f88, 0x020000d3, - 0x000024dc, 0x000024c2, 0x000003bb, 0x0000039b, - 0x00000499, 0x00000498, 0x000024df, 0x000024c5, - 0x00001e0f, 0x00001e0e, 0x00001f25, 0x00001f2d, - 0x00002c50, 0x00002c20, 0x00002c4f, 0x00002c1f, - 0x0000046b, 0x0000046a, 0x000001d6, 0x000001d5, - 0x00001ec1, 0x00001ec0, 0x000118d5, 0x000118b5, - 0x0000010b, 0x0000010a, 0x0000016f, 0x0000016e, - 0x00010d7e, 0x00010d5e, 0x0000045c, 0x0000040c, - 0x000013fc, 0x000013f4, 0x00001c85, 0x00000422, - 0x00001e89, 0x00001e88, 0x00001f97, 0x0200002d, - 0x0001042b, 0x00010403, 0x000000f8, 0x000000d8, - 0x00000564, 0x00000534, 0x000118c4, 0x000118a4, - 0x00002ccd, 0x00002ccc, 0x000105b6, 0x0001058f, - 0x00000251, 0x00002c6d, 0x00002d21, 0x000010c1, - 0x000004d9, 0x000004d8, 0x00001f82, 0x02000006, - 0x00001e3f, 0x00001e3e, 0x00000135, 0x00000134, - 0x00002c34, 0x00002c04, 0x0000a769, 0x0000a768, - 0x000000fa, 0x000000da, 0x0000ab88, 0x000013b8, - 0x0000021b, 0x0000021a, 0x00002d2d, 0x000010cd, - 0x00001f81, 0x02000003, 0x000010df, 0x00001c9f, - 0x00000240, 0x00002c7f, 0x00002c5e, 0x00002c2e, - 0x00000431, 0x00000411, 0x000000ef, 0x000000cf, - 0x00002d0b, 0x000010ab, 0x00000288, 0x000001ae, - 0x00000256, 0x00000189, 0x00016e64, 0x00016e44, - 0x000001d8, 0x000001d7, 0x00002cb5, 0x00002cb4, - 0x0000012d, 0x0000012c, 0x00000257, 0x0000018a, - 0x00001e97, 0x0200008e, 0x0001e943, 0x0001e921, - 0x000104e1, 0x000104b9, 0x000105ae, 0x00010587, - 0x00016e65, 0x00016e45, 0x00002ca7, 0x00002ca6, - 0x0000abaf, 0x000013df, 0x000004a3, 0x000004a2, - 0x000000f2, 0x000000d2, 0x00001fa0, 0x02000030, - 0x00001d7d, 0x00002c63, 0x00000574, 0x00000544, - 0x00000169, 0x00000168, 0x00016e6b, 0x00016e4b, - 0x000010ec, 0x00001cac, 0x00010cc9, 0x00010c89, - 0x0000026a, 0x0000a7ae, 0x00001e77, 0x00001e76, - 0x000001df, 0x000001de, 0x00000117, 0x00000116, - 0x000024d8, 0x000024be, 0x00000577, 0x00000547, - 0x0000049f, 0x0000049e, 0x000001b0, 0x000001af, - 0x00000115, 0x00000114, 0x00001f9b, 0x020000f4, - 0x00002c52, 0x00002c22, 0x000003b8, 0x00000398, - 0x00002c5a, 0x00002c2a, 0x00010ccf, 0x00010c8f, - 0x000000e9, 0x000000c9, 0x00001e39, 0x00001e38, - 0x0000ab70, 0x000013a0, 0x00001ed3, 0x00001ed2, - 0x00002d25, 0x000010c5, 0x00001e3b, 0x00001e3a, - 0x00002ca3, 0x00002ca2, 0x00002d27, 0x000010c7, - 0x000000f3, 0x000000d3, 0x00000373, 0x00000372, - 0x0000ff57, 0x0000ff37, 0x00000449, 0x00000429, - 0x00010597, 0x00010570, 0x0000a68d, 0x0000a68c, - 0x0000abb7, 0x000013e7, 0x00001f60, 0x00001f68, - 0x00000289, 0x00000244, 0x000004a9, 0x000004a8, - 0x000003c7, 0x000003a7, 0x00001e1d, 0x00001e1c, - 0x00001ea1, 0x00001ea0, 0x00000167, 0x00000166, - 0x0000025b, 0x00000190, 0x000004e9, 0x000004e8, - 0x0000a751, 0x0000a750, 0x00010cf2, 0x00010cb2, - 0x0000006f, 0x0000004f, 0x0000aba8, 0x000013d8, - 0x000104ec, 0x000104c4, 0x00000125, 0x00000124, - 0x0000a797, 0x0000a796, 0x0000043f, 0x0000041f, - 0x00000511, 0x00000510, 0x00002d0d, 0x000010ad, - 0x0001043e, 0x00010416, 0x0000aba6, 0x000013d6, - 0x000003be, 0x0000039e, 0x000004f3, 0x000004f2, - 0x00001e73, 0x00001e72, 0x00002cd3, 0x00002cd2, - 0x00001fd0, 0x00001fd8, 0x00001edf, 0x00001ede, - 0x000118d3, 0x000118b3, 0x000024d2, 0x000024b8, - 0x0000ff45, 0x0000ff25, 0x00002d14, 0x000010b4, - 0x00000064, 0x00000044, 0x000010e7, 0x00001ca7, - 0x00001fb3, 0x02000048, 0x00000467, 0x00000466, - 0x0000ab8a, 0x000013ba, 0x00001ff4, 0x02000133, - 0x000118cc, 0x000118ac, 0x00001e81, 0x00001e80, - 0x000001d0, 0x000001cf, 0x000001d4, 0x000001d3, - 0x00016e71, 0x00016e51, 0x00000432, 0x00000412, - 0x000003ca, 0x000003aa, 0x00010ceb, 0x00010cab, - 0x00001f40, 0x00001f48, 0x0000023c, 0x0000023b, - 0x0000a669, 0x0000a668, 0x00002c3a, 0x00002c0a, - 0x000105b1, 0x0001058a, 0x00000562, 0x00000532, - 0x00001f30, 0x00001f38, 0x00010434, 0x0001040c, - 0x000003d1, 0x00000398, 0x0000a743, 0x0000a742, - 0x0000a7f6, 0x0000a7f5, 0x0000a72b, 0x0000a72a, - 0x000000e0, 0x000000c0, 0x00001f07, 0x00001f0f, - 0x0001059c, 0x00010575, 0x00010cc2, 0x00010c82, - 0x0000a65f, 0x0000a65e, 0x00000581, 0x00000551, - 0x00001eeb, 0x00001eea, 0x00000069, 0x00000049, - 0x0001e928, 0x0001e906, 0x00001c82, 0x0000041e, - 0x00010d71, 0x00010d51, 0x0000a765, 0x0000a764, - 0x000024d1, 0x000024b7, 0x000118d7, 0x000118b7, - 0x00010d7f, 0x00010d5f, 0x000003f3, 0x0000037f, - 0x00000119, 0x00000118, 0x00002171, 0x00002161, - 0x00001fe0, 0x00001fe8, 0x00001f98, 0x020000eb, - 0x00002caf, 0x00002cae, 0x000001a8, 0x000001a7, - 0x000024e8, 0x000024ce, 0x0001e940, 0x0001e91e, - 0x0000022d, 0x0000022c, 0x00001fac, 0x0200010f, - 0x00001fae, 0x02000115, 0x00001f66, 0x00001f6e, - 0x00002c4c, 0x00002c1c, 0x0000a667, 0x0000a666, - 0x0000a75b, 0x0000a75a, 0x0000056e, 0x0000053e, - 0x00000231, 0x00000230, 0x000001f9, 0x000001f8, - 0x00000442, 0x00000422, 0x00000247, 0x00000246, - 0x00002c37, 0x00002c07, 0x000004e5, 0x000004e4, - 0x00002c33, 0x00002c03, 0x00000129, 0x00000128, - 0x00000079, 0x00000059, 0x00001f79, 0x00001ff9, - 0x00001edd, 0x00001edc, 0x00002172, 0x00002162, - 0x00010ce3, 0x00010ca3, 0x0000abb0, 0x000013e0, - 0x00002c31, 0x00002c01, 0x000010fd, 0x00001cbd, - 0x00001fe3, 0x030000c2, 0x00000481, 0x00000480, - 0x0000ff4a, 0x0000ff2a, 0x00010d76, 0x00010d56, - 0x00002c5d, 0x00002c2d, 0x000010e6, 0x00001ca6, - 0x00001f93, 0x02000021, 0x000004b5, 0x000004b4, - 0x00002179, 0x00002169, 0x00001fe4, 0x020000c6, - 0x00001fb6, 0x020000a9, 0x00016e7f, 0x00016e5f, - 0x00000144, 0x00000143, 0x00000223, 0x00000222, - 0x00000501, 0x00000500, 0x0000045f, 0x0000040f, - 0x000104f7, 0x000104cf, 0x00001ed9, 0x00001ed8, - 0x000118d6, 0x000118b6, 0x000118c9, 0x000118a9, - 0x00002d23, 0x000010c3, 0x0000044c, 0x0000042c, - 0x00000123, 0x00000122, 0x0000022f, 0x0000022e, - 0x0000029e, 0x0000a7b0, 0x00001f27, 0x00001f2f, - 0x00002c4b, 0x00002c1b, 0x00002c46, 0x00002c16, - 0x0000ff49, 0x0000ff29, 0x000104de, 0x000104b6, - 0x00002d1b, 0x000010bb, 0x0001042e, 0x00010406, - 0x00001f31, 0x00001f39, 0x000003dd, 0x000003dc, - 0x000004b7, 0x000004b6, 0x0000fb04, 0x03000061, - 0x0000045e, 0x0000040e, 0x00001e15, 0x00001e14, - 0x000010e3, 0x00001ca3, 0x00001e03, 0x00001e02, - 0x000001bf, 0x000001f7, 0x00000435, 0x00000415, - 0x0000ab7a, 0x000013aa, 0x00000456, 0x00000406, - 0x00010d85, 0x00010d65, 0x00001f03, 0x00001f0b, - 0x000104f8, 0x000104d0, 0x00000507, 0x00000506, - 0x000105a8, 0x00010581, 0x000024dd, 0x000024c3, - 0x00001ea7, 0x00001ea6, 0x00001f75, 0x00001fcb, - 0x00010441, 0x00010419, 0x00000371, 0x00000370, - 0x00001f50, 0x0200009a, 0x000004c2, 0x000004c1, - 0x000003eb, 0x000003ea, 0x000118cf, 0x000118af, - 0x00000292, 0x000001b7, 0x000003d0, 0x00000392, - 0x00000219, 0x00000218, 0x00000452, 0x00000402, - 0x00002c3b, 0x00002c0b, 0x00000157, 0x00000156, - 0x00000074, 0x00000054, 0x00001f61, 0x00001f69, - 0x0000fb14, 0x02000071, 0x00016e73, 0x00016e53, - 0x000001b4, 0x000001b3, 0x000004ff, 0x000004fe, - 0x00001e49, 0x00001e48, 0x0001e936, 0x0001e914, - 0x000003d9, 0x000003d8, 0x000104f6, 0x000104ce, - 0x0000a73f, 0x0000a73e, 0x000024d0, 0x000024b6, - 0x00001ebf, 0x00001ebe, 0x000010e5, 0x00001ca5, - 0x00010cc0, 0x00010c80, 0x00000459, 0x00000409, - 0x00010ccc, 0x00010c8c, 0x0000a727, 0x0000a726, - 0x00000568, 0x00000538, 0x0000abb5, 0x000013e5, - 0x00002d16, 0x000010b6, 0x00010d80, 0x00010d60, - 0x000003b3, 0x00000393, 0x00000515, 0x00000514, - 0x000024d9, 0x000024bf, 0x00001eaf, 0x00001eae, - 0x00001f72, 0x00001fc8, 0x000010f6, 0x00001cb6, - 0x0001e93b, 0x0001e919, 0x0000a723, 0x0000a722, - 0x0000a7b9, 0x0000a7b8, 0x00001ec3, 0x00001ec2 + 0x0000007a, 0x0000005a, 0x000105a0, 0x00010579, + 0x00002d0e, 0x000010ae, 0x000003d5, 0x000003a6, + 0x0000a7b9, 0x0000a7b8, 0x00000373, 0x00000372, + 0x00001f92, 0x0200001e, 0x0000056f, 0x0000053f, + 0x00001e67, 0x00001e66, 0x00002d09, 0x000010a9, + 0x0000ab75, 0x000013a5, 0x0000217b, 0x0000216b, + 0x00010d7b, 0x00010d5b, 0x000003e9, 0x000003e8, + 0x000004e7, 0x000004e6, 0x00002c81, 0x00002c80, + 0x00001ee1, 0x00001ee0, 0x000000ec, 0x000000cc, + 0x00000436, 0x00000416, 0x00002c97, 0x00002c96, + 0x00002cec, 0x00002ceb, 0x0000045d, 0x0000040d, + 0x0001042e, 0x00010406, 0x00001eb9, 0x00001eb8, + 0x0000214e, 0x00002132, 0x00002cc5, 0x00002cc4, + 0x00016e6a, 0x00016e4a, 0x00001e43, 0x00001e42, + 0x00001f7c, 0x00001ffa, 0x0000015f, 0x0000015e, + 0x00010435, 0x0001040d, 0x0001e931, 0x0001e90f, + 0x00010cd6, 0x00010c96, 0x000105a3, 0x0001057c, + 0x000001f9, 0x000001f8, 0x00002d04, 0x000010a4, + 0x00000259, 0x0000018f, 0x00002c43, 0x00002c13, + 0x00001f87, 0x02000015, 0x00001f45, 0x00001f4d, + 0x0000a794, 0x0000a7c4, 0x00000377, 0x00000376, + 0x00001f36, 0x00001f3e, 0x0001042d, 0x00010405, + 0x000105a9, 0x00010582, 0x00002cb9, 0x00002cb8, + 0x000118c7, 0x000118a7, 0x00001f31, 0x00001f39, + 0x0000ab8c, 0x000013bc, 0x00002d22, 0x000010c2, + 0x00002c42, 0x00002c12, 0x00002cc9, 0x00002cc8, + 0x00001ea9, 0x00001ea8, 0x00002d2d, 0x000010cd, + 0x00001f62, 0x00001f6a, 0x000105b4, 0x0001058d, + 0x00001eed, 0x00001eec, 0x0001e922, 0x0001e900, + 0x000003c0, 0x000003a0, 0x00001fc3, 0x0200004b, + 0x000105bb, 0x00010594, 0x0000a723, 0x0000a722, + 0x00001fab, 0x0200010c, 0x00000578, 0x00000548, + 0x00001f75, 0x00001fcb, 0x0001e938, 0x0001e916, + 0x00001fb3, 0x02000048, 0x00001e97, 0x0200008e, + 0x000010ea, 0x00001caa, 0x000010ff, 0x00001cbf, + 0x0000019e, 0x00000220, 0x000004ad, 0x000004ac, + 0x00000211, 0x00000210, 0x00002c47, 0x00002c17, + 0x00001e0f, 0x00001e0e, 0x00010ccd, 0x00010c8d, + 0x0000abbe, 0x000013ee, 0x000000e6, 0x000000c6, + 0x00000253, 0x00000181, 0x0000a733, 0x0000a732, + 0x00016e6f, 0x00016e4f, 0x000118d7, 0x000118b7, + 0x00000167, 0x00000166, 0x000010d9, 0x00001c99, + 0x0000a781, 0x0000a780, 0x00000254, 0x00000186, + 0x00000477, 0x00000476, 0x0000a683, 0x0000a682, + 0x000013f9, 0x000013f1, 0x00000171, 0x00000170, + 0x0000019b, 0x0000a7dc, 0x00001fa9, 0x02000106, + 0x00001f54, 0x030000a1, 0x000003eb, 0x000003ea, + 0x000004eb, 0x000004ea, 0x00002c5e, 0x00002c2e, + 0x00002c3f, 0x00002c0f, 0x000010d2, 0x00001c92, + 0x00001f63, 0x00001f6b, 0x00010d7a, 0x00010d5a, + 0x00016ed1, 0x00016eb6, 0x00016e6e, 0x00016e4e, + 0x00000515, 0x00000514, 0x00001e59, 0x00001e58, + 0x0000a669, 0x0000a668, 0x00002cee, 0x00002ced, + 0x00000169, 0x00000168, 0x0000a7c3, 0x0000a7c2, + 0x00016ebf, 0x00016ea4, 0x000004d5, 0x000004d4, + 0x00010444, 0x0001041c, 0x00001f33, 0x00001f3b, + 0x0000ab76, 0x000013a6, 0x0000a7d1, 0x0000a7d0, + 0x00010d7c, 0x00010d5c, 0x000000ea, 0x000000ca, + 0x00001f14, 0x00001f1c, 0x0000aba9, 0x000013d9, + 0x0000029e, 0x0000a7b0, 0x00001f65, 0x00001f6d, + 0x00002c30, 0x00002c00, 0x0000043a, 0x0000041a, + 0x000105a4, 0x0001057d, 0x00000513, 0x00000512, + 0x0000010d, 0x0000010c, 0x00002cbb, 0x00002cba, + 0x000118df, 0x000118bf, 0x00010cc8, 0x00010c88, + 0x000010e4, 0x00001ca4, 0x00010448, 0x00010420, + 0x000004b3, 0x000004b2, 0x0000057c, 0x0000054c, + 0x0000006c, 0x0000004c, 0x000010d4, 0x00001c94, + 0x00000289, 0x00000244, 0x00001fe2, 0x030000be, + 0x00002178, 0x00002168, 0x0000fb00, 0x02000054, + 0x000003b8, 0x00000398, 0x00001e87, 0x00001e86, + 0x000010e1, 0x00001ca1, 0x0000a729, 0x0000a728, + 0x00001f83, 0x02000009, 0x0000a7a3, 0x0000a7a2, + 0x00016ecc, 0x00016eb1, 0x0000049d, 0x0000049c, + 0x00000113, 0x00000112, 0x00001f7b, 0x00001feb, + 0x00002d21, 0x000010c1, 0x0000a79d, 0x0000a79c, + 0x00002c48, 0x00002c18, 0x0000045c, 0x0000040c, + 0x000105b3, 0x0001058c, 0x00002d0d, 0x000010ad, + 0x00001e13, 0x00001e12, 0x0000051b, 0x0000051a, + 0x0000ab9d, 0x000013cd, 0x0000ab92, 0x000013c2, + 0x0000057a, 0x0000054a, 0x00000101, 0x00000100, + 0x00001e01, 0x00001e00, 0x000010e2, 0x00001ca2, + 0x00001ecd, 0x00001ecc, 0x00001f89, 0x020000d6, + 0x00000564, 0x00000534, 0x00010d77, 0x00010d57, + 0x00016ebc, 0x00016ea1, 0x00010d72, 0x00010d52, + 0x00001e75, 0x00001e74, 0x00001f8a, 0x020000d9, + 0x00001e77, 0x00001e76, 0x000003d6, 0x000003a0, + 0x0001e932, 0x0001e910, 0x00001fe6, 0x020000c9, + 0x0000006b, 0x0000004b, 0x0001e940, 0x0001e91e, + 0x00001fb4, 0x02000127, 0x0000ab73, 0x000013a3, + 0x00001f71, 0x00001fbb, 0x0000a75d, 0x0000a75c, + 0x000104f0, 0x000104c8, 0x00016ebb, 0x00016ea0, + 0x000001f5, 0x000001f4, 0x00001f84, 0x0200000c, + 0x000003c9, 0x000003a9, 0x000001d8, 0x000001d7, + 0x00010cec, 0x00010cac, 0x0000217d, 0x0000216d, + 0x00016e7b, 0x00016e5b, 0x00000456, 0x00000406, + 0x00001f8c, 0x020000df, 0x000003db, 0x000003da, + 0x00010ce4, 0x00010ca4, 0x00002d10, 0x000010b0, + 0x00002c91, 0x00002c90, 0x000003ce, 0x0000038f, + 0x00002c66, 0x0000023e, 0x000001f2, 0x000001f1, + 0x00001e6f, 0x00001e6e, 0x00001f41, 0x00001f49, + 0x0000a75f, 0x0000a75e, 0x00000250, 0x00002c6f, + 0x00000443, 0x00000423, 0x000003cd, 0x0000038e, + 0x0001e92f, 0x0001e90d, 0x00000439, 0x00000419, + 0x000000df, 0x02000051, 0x000010d3, 0x00001c93, + 0x0000a7cf, 0x0000a7ce, 0x00000282, 0x0000a7c5, + 0x000004b5, 0x000004b4, 0x00000260, 0x00000193, + 0x00001eb1, 0x00001eb0, 0x0000ab77, 0x000013a7, + 0x00001ef7, 0x00001ef6, 0x0000a743, 0x0000a742, + 0x000003ca, 0x000003aa, 0x0000ab83, 0x000013b3, + 0x0000052b, 0x0000052a, 0x00001fcc, 0x0200011e, + 0x00001f25, 0x00001f2d, 0x0000a72b, 0x0000a72a, + 0x00001d79, 0x0000a77d, 0x00002c58, 0x00002c28, + 0x00016ec6, 0x00016eab, 0x0001e93d, 0x0001e91b, + 0x000003c1, 0x000003a1, 0x00001e3f, 0x00001e3e, + 0x00001e98, 0x02000091, 0x0000a659, 0x0000a658, + 0x00002ca1, 0x00002ca0, 0x000003b6, 0x00000396, + 0x0001042f, 0x00010407, 0x00000511, 0x00000510, + 0x00002d13, 0x000010b3, 0x00000566, 0x00000536, + 0x000118cc, 0x000118ac, 0x00016ec5, 0x00016eaa, + 0x0000ff57, 0x0000ff37, 0x000004c4, 0x000004c3, + 0x0001e93c, 0x0001e91a, 0x00000137, 0x00000136, + 0x0000020b, 0x0000020a, 0x00001f81, 0x02000003, + 0x0000a791, 0x0000a790, 0x00000266, 0x0000a7aa, + 0x00010d73, 0x00010d53, 0x0001059a, 0x00010573, + 0x00000062, 0x00000042, 0x0000017e, 0x0000017d, + 0x00001efb, 0x00001efa, 0x000010dd, 0x00001c9d, + 0x00016e63, 0x00016e43, 0x000003bf, 0x0000039f, + 0x0000006f, 0x0000004f, 0x00001f93, 0x02000021, + 0x0000056a, 0x0000053a, 0x00001e73, 0x00001e72, + 0x0000021d, 0x0000021c, 0x00002172, 0x00002162, + 0x00000371, 0x00000370, 0x00000272, 0x0000019d, + 0x000000eb, 0x000000cb, 0x000003e3, 0x000003e2, + 0x00000068, 0x00000048, 0x000010fa, 0x00001cba, + 0x00001faa, 0x02000109, 0x0000aba4, 0x000013d4, + 0x0001043f, 0x00010417, 0x000004d9, 0x000004d8, + 0x00001fe1, 0x00001fe9, 0x00001edb, 0x00001eda, + 0x000010d5, 0x00001c95, 0x000010dc, 0x00001c9c, + 0x00000251, 0x00002c6d, 0x0000ff4d, 0x0000ff2d, + 0x0000026b, 0x00002c62, 0x00000268, 0x00000197, + 0x00001e53, 0x00001e52, 0x0000a655, 0x0000a654, + 0x0000a759, 0x0000a758, 0x0000023c, 0x0000023b, + 0x00000587, 0x0200006b, 0x0000ab8f, 0x000013bf, + 0x0001042c, 0x00010404, 0x00002c8f, 0x00002c8e, + 0x00000257, 0x0000018a, 0x00002c44, 0x00002c14, + 0x000001a1, 0x000001a0, 0x000003bb, 0x0000039b, + 0x000004ce, 0x000004cd, 0x00000517, 0x00000516, + 0x00002c41, 0x00002c11, 0x00002cc1, 0x00002cc0, + 0x00002c37, 0x00002c07, 0x0000a747, 0x0000a746, + 0x0000ff45, 0x0000ff25, 0x00000431, 0x00000411, + 0x0000052f, 0x0000052e, 0x00016e79, 0x00016e59, + 0x00002cb5, 0x00002cb4, 0x00001f20, 0x00001f28, + 0x00010cc2, 0x00010c82, 0x0000a7bb, 0x0000a7ba, + 0x0001044c, 0x00010424, 0x000004a5, 0x000004a4, + 0x00000064, 0x00000044, 0x00001fd7, 0x030000ba, + 0x00001f9f, 0x02000100, 0x00001f21, 0x00001f29, + 0x0000ab79, 0x000013a9, 0x00001e8b, 0x00001e8a, + 0x000104e1, 0x000104b9, 0x000000e2, 0x000000c2, + 0x0000011f, 0x0000011e, 0x0000ab8d, 0x000013bd, + 0x00002c5c, 0x00002c2c, 0x00000580, 0x00000550, + 0x0001043e, 0x00010416, 0x0000050b, 0x0000050a, + 0x0001e936, 0x0001e914, 0x00002c8b, 0x00002c8a, + 0x000001e3, 0x000001e2, 0x00001f8d, 0x020000e2, + 0x000001e9, 0x000001e8, 0x00016ec9, 0x00016eae, + 0x0001043c, 0x00010414, 0x00000579, 0x00000549, + 0x000000fa, 0x000000da, 0x00002d01, 0x000010a1, + 0x00000229, 0x00000228, 0x00001f79, 0x00001ff9, + 0x0000014d, 0x0000014c, 0x00010439, 0x00010411, + 0x00000073, 0x00000053, 0x00010ccf, 0x00010c8f, + 0x00002c3d, 0x00002c0d, 0x000010df, 0x00001c9f, + 0x000118d3, 0x000118b3, 0x0000a7a5, 0x0000a7a4, + 0x0000037b, 0x000003fd, 0x0001043b, 0x00010413, + 0x000000f9, 0x000000d9, 0x0000a65b, 0x0000a65a, + 0x0000016f, 0x0000016e, 0x0000a76b, 0x0000a76a, + 0x00010cde, 0x00010c9e, 0x00016ec1, 0x00016ea6, + 0x00010ce9, 0x00010ca9, 0x000004ef, 0x000004ee, + 0x0001e943, 0x0001e921, 0x00001edf, 0x00001ede, + 0x0000019a, 0x0000023d, 0x00001f66, 0x00001f6e, + 0x00002c40, 0x00002c10, 0x0000a7ca, 0x0000a7c9, + 0x00000453, 0x00000403, 0x000104e5, 0x000104bd, + 0x00001e57, 0x00001e56, 0x00001f53, 0x00001f5b, + 0x000118cf, 0x000118af, 0x00010ce8, 0x00010ca8, + 0x0000043e, 0x0000041e, 0x00002176, 0x00002166, + 0x000004d7, 0x000004d6, 0x000001f0, 0x02000088, + 0x00000442, 0x00000422, 0x00010cf2, 0x00010cb2, + 0x00002ce1, 0x00002ce0, 0x0000022f, 0x0000022e, + 0x000004bf, 0x000004be, 0x00001f73, 0x00001fc9, + 0x00002c4b, 0x00002c1b, 0x000001b9, 0x000001b8, + 0x0000a64f, 0x0000a64e, 0x0000a75b, 0x0000a75a, + 0x00001f9c, 0x020000f7, 0x00000433, 0x00000413, + 0x000000e5, 0x000000c5, 0x00010436, 0x0001040e, + 0x0000ab90, 0x000013c0, 0x0001e924, 0x0001e902, + 0x00010cc6, 0x00010c86, 0x000024d4, 0x000024ba, + 0x00010446, 0x0001041e, 0x000004a7, 0x000004a6, + 0x00000583, 0x00000553, 0x00001ea1, 0x00001ea0, + 0x000000f4, 0x000000d4, 0x00010cf1, 0x00010cb1, + 0x00002c76, 0x00002c75, 0x000010eb, 0x00001cab, + 0x0000ab81, 0x000013b1, 0x0000051d, 0x0000051c, + 0x0001e942, 0x0001e920, 0x0000fb17, 0x0200007a, + 0x0000a725, 0x0000a724, 0x00001faf, 0x02000118, + 0x0000fb05, 0x02000065, 0x00010ce5, 0x00010ca5, + 0x00000499, 0x00000498, 0x00001f80, 0x02000000, + 0x00000256, 0x00000189, 0x00001fad, 0x02000112, + 0x00000261, 0x0000a7ac, 0x00001f9e, 0x020000fd, + 0x0001059b, 0x00010574, 0x000118cd, 0x000118ad, + 0x00000501, 0x00000500, 0x00002d03, 0x000010a3, + 0x00002d18, 0x000010b8, 0x00000576, 0x00000546, + 0x00001c83, 0x00000421, 0x000000ff, 0x00000178, + 0x000004fb, 0x000004fa, 0x00000434, 0x00000414, + 0x00002ccf, 0x00002cce, 0x0000aba7, 0x000013d7, + 0x0000a68b, 0x0000a68a, 0x0000217a, 0x0000216a, + 0x00002c51, 0x00002c21, 0x00001f77, 0x00001fdb, + 0x00016e73, 0x00016e53, 0x00001ecf, 0x00001ece, + 0x000003d9, 0x000003d8, 0x0000abbf, 0x000013ef, + 0x0000050f, 0x0000050e, 0x0000ab74, 0x000013a4, + 0x000010e0, 0x00001ca0, 0x000004e5, 0x000004e4, + 0x0000015b, 0x0000015a, 0x00001ecb, 0x00001eca, + 0x0000ab71, 0x000013a1, 0x00001f12, 0x00001f1a, + 0x000003ae, 0x00000389, 0x00001ebb, 0x00001eba, + 0x00000461, 0x00000460, 0x0000013a, 0x00000139, + 0x00001e5b, 0x00001e5a, 0x00001fbc, 0x0200011b, + 0x0000a761, 0x0000a760, 0x00001fa4, 0x0200003c, + 0x0000046f, 0x0000046e, 0x00002c5b, 0x00002c2b, + 0x000001fb, 0x000001fa, 0x00000275, 0x0000019f, + 0x00001e85, 0x00001e84, 0x00016e7f, 0x00016e5f, + 0x0000a7d5, 0x0000a7d4, 0x000010fd, 0x00001cbd, + 0x000024e5, 0x000024cb, 0x00001f30, 0x00001f38, + 0x00016e7d, 0x00016e5d, 0x00001e45, 0x00001e44, + 0x0000ff56, 0x0000ff36, 0x0000abb1, 0x000013e1, + 0x00002c54, 0x00002c24, 0x00001f04, 0x00001f0c, + 0x000001e1, 0x000001e0, 0x00002d14, 0x000010b4, + 0x00002cb1, 0x00002cb0, 0x0000abbb, 0x000013eb, + 0x00010cca, 0x00010c8a, 0x00000148, 0x00000147, + 0x0000fb06, 0x02000068, 0x00016ebd, 0x00016ea2, + 0x00002cab, 0x00002caa, 0x00001e83, 0x00001e82, + 0x000001d2, 0x000001d1, 0x0000217c, 0x0000216c, + 0x0000a7b7, 0x0000a7b6, 0x0000057e, 0x0000054e, + 0x000013fc, 0x000013f4, 0x0000043d, 0x0000041d, + 0x00001e23, 0x00001e22, 0x0000043b, 0x0000041b, + 0x000105af, 0x00010588, 0x00001fa1, 0x02000033, + 0x0000056c, 0x0000053c, 0x000104e9, 0x000104c1, + 0x00000155, 0x00000154, 0x0000022d, 0x0000022c, + 0x00000451, 0x00000401, 0x000104f1, 0x000104c9, + 0x00001fd6, 0x020000b7, 0x00010449, 0x00010421, + 0x0000048b, 0x0000048a, 0x00002c9d, 0x00002c9c, + 0x00000519, 0x00000518, 0x00001e0d, 0x00001e0c, + 0x00000265, 0x0000a78d, 0x0000045e, 0x0000040e, + 0x000104eb, 0x000104c3, 0x0001e937, 0x0001e915, + 0x000004fd, 0x000004fc, 0x0001e93a, 0x0001e918, + 0x000118c5, 0x000118a5, 0x00002c38, 0x00002c08, + 0x0000a68d, 0x0000a68c, 0x0000fb03, 0x0300005d, + 0x0000037d, 0x000003ff, 0x00000473, 0x00000472, + 0x00000573, 0x00000543, 0x00001e63, 0x00001e62, + 0x00000582, 0x00000552, 0x00000078, 0x00000058, + 0x000010e9, 0x00001ca9, 0x0000ab86, 0x000013b6, + 0x000118c0, 0x000118a0, 0x00000061, 0x00000041, + 0x000003d1, 0x00000398, 0x00001f50, 0x0200009a, + 0x0000ab7b, 0x000013ab, 0x00000572, 0x00000542, + 0x000001fd, 0x000001fc, 0x0000ab88, 0x000013b8, + 0x0000a641, 0x0000a640, 0x000003ac, 0x00000386, + 0x00001f24, 0x00001f2c, 0x00000173, 0x00000172, + 0x0000a769, 0x0000a768, 0x00001f10, 0x00001f18, + 0x000104ef, 0x000104c7, 0x00002c55, 0x00002c25, + 0x000004d1, 0x000004d0, 0x0000017f, 0x00000053, + 0x000004cf, 0x000004c0, 0x0000044c, 0x0000042c, + 0x0000a7d9, 0x0000a7d8, 0x000003ef, 0x000003ee, + 0x00000217, 0x00000216, 0x00002c56, 0x00002c26, + 0x00002c4d, 0x00002c1d, 0x000001c6, 0x000001c4, + 0x00001f43, 0x00001f4b, 0x00002c6c, 0x00002c6b, + 0x00002c61, 0x00002c60, 0x000003c6, 0x000003a6, + 0x000003c2, 0x000003a3, 0x00001e1d, 0x00001e1c, + 0x00000142, 0x00000141, 0x00000280, 0x000001a6, + 0x0000013e, 0x0000013d, 0x0001e926, 0x0001e904, + 0x000003b9, 0x00000399, 0x000000e0, 0x000000c0, + 0x00001f57, 0x00001f5f, 0x00010d79, 0x00010d59, + 0x000001bd, 0x000001bc, 0x00001c81, 0x00000414, + 0x0000044a, 0x0000042a, 0x00002d16, 0x000010b6, + 0x00010597, 0x00010570, 0x00000521, 0x00000520, + 0x00001e25, 0x00001e24, 0x00001f23, 0x00001f2b, + 0x000024e6, 0x000024cc, 0x00001eb7, 0x00001eb6, + 0x00010ccb, 0x00010c8b, 0x00010430, 0x00010408, + 0x000118cb, 0x000118ab, 0x00002cbf, 0x00002cbe, + 0x00001e9b, 0x00001e60, 0x00000199, 0x00000198, + 0x0000a7a1, 0x0000a7a0, 0x00000227, 0x00000226, + 0x0000ab78, 0x000013a8, 0x00002c3e, 0x00002c0e, + 0x000001cc, 0x000001ca, 0x00001e37, 0x00001e36, + 0x000010e5, 0x00001ca5, 0x00000203, 0x00000202, + 0x0000ff48, 0x0000ff28, 0x0000044f, 0x0000042f, + 0x0000ff55, 0x0000ff35, 0x00001e03, 0x00001e02, + 0x00002c89, 0x00002c88, 0x00001e81, 0x00001e80, + 0x000000f6, 0x000000d6, 0x00010d70, 0x00010d50, + 0x00001f86, 0x02000012, 0x00000479, 0x00000478, + 0x00000577, 0x00000547, 0x00000079, 0x00000059, + 0x00000175, 0x00000174, 0x00001ff4, 0x02000133, + 0x000024e7, 0x000024cd, 0x0000028b, 0x000001b2, + 0x000003b5, 0x00000395, 0x000004ed, 0x000004ec, + 0x00010440, 0x00010418, 0x00002173, 0x00002163, + 0x00001c88, 0x0000a64a, 0x000001df, 0x000001de, + 0x000001cb, 0x000001ca, 0x00016ed0, 0x00016eb5, + 0x00000469, 0x00000468, 0x000000ef, 0x000000cf, + 0x00001f88, 0x020000d3, 0x0000018c, 0x0000018b, + 0x00000077, 0x00000057, 0x00010cf0, 0x00010cb0, + 0x000003ba, 0x0000039a, 0x0000025b, 0x00000190, + 0x000004dd, 0x000004dc, 0x00002cd3, 0x00002cd2, + 0x00001ef3, 0x00001ef2, 0x000010d7, 0x00001c97, + 0x000000b5, 0x0000039c, 0x00001fb2, 0x02000124, + 0x00001fc6, 0x020000ac, 0x0001e933, 0x0001e911, + 0x00001f76, 0x00001fda, 0x00001e49, 0x00001e48, + 0x00001fb7, 0x03000136, 0x0000a751, 0x0000a750, + 0x00000105, 0x00000104, 0x000004ca, 0x000004c9, + 0x000010e3, 0x00001ca3, 0x000000e7, 0x000000c7, + 0x00002c85, 0x00002c84, 0x00001ebd, 0x00001ebc, + 0x00001ff2, 0x02000130, 0x000105aa, 0x00010583, + 0x0001042b, 0x00010403, 0x0001043d, 0x00010415, + 0x000003b2, 0x00000392, 0x00001eb5, 0x00001eb4, + 0x00002d1e, 0x000010be, 0x000001d6, 0x000001d5, + 0x00000183, 0x00000182, 0x0000ff47, 0x0000ff27, + 0x0000037c, 0x000003fe, 0x0001e92d, 0x0001e90b, + 0x0000a681, 0x0000a680, 0x0000012f, 0x0000012e, + 0x0000a739, 0x0000a738, 0x00001fae, 0x02000115, + 0x00001ec7, 0x00001ec6, 0x00000213, 0x00000212, + 0x000004af, 0x000004ae, 0x00002cd7, 0x00002cd6, + 0x000105bc, 0x00010595, 0x00001f9b, 0x020000f4, + 0x000000fd, 0x000000dd, 0x00016ecd, 0x00016eb2, + 0x00001fc2, 0x0200012a, 0x000001ef, 0x000001ee, + 0x0000051f, 0x0000051e, 0x00001e15, 0x00001e14, + 0x00000450, 0x00000400, 0x000010f3, 0x00001cb3, + 0x00000107, 0x00000106, 0x000118c3, 0x000118a3, + 0x00000507, 0x00000506, 0x000003c7, 0x000003a7, + 0x00002ccd, 0x00002ccc, 0x00000201, 0x00000200, + 0x0000a697, 0x0000a696, 0x00000240, 0x00002c7f, + 0x0000ff51, 0x0000ff31, 0x0000047b, 0x0000047a, + 0x0000057b, 0x0000054b, 0x000003d7, 0x000003cf, + 0x00001e05, 0x00001e04, 0x00000066, 0x00000046, + 0x00001ff3, 0x0200004e, 0x000105b6, 0x0001058f, + 0x000003b7, 0x00000397, 0x0000006d, 0x0000004d, + 0x00010598, 0x00010571, 0x00016e72, 0x00016e52, + 0x0000ab7d, 0x000013ad, 0x000003f5, 0x00000395, + 0x00002c6a, 0x00002c69, 0x000024e3, 0x000024c9, + 0x00000467, 0x00000466, 0x00000565, 0x00000535, + 0x00001e7d, 0x00001e7c, 0x00000131, 0x00000049, + 0x0000a76d, 0x0000a76c, 0x00010ce3, 0x00010ca3, + 0x0000045b, 0x0000040b, 0x000003ed, 0x000003ec, + 0x000004e1, 0x000004e0, 0x0001e93b, 0x0001e919, + 0x00001f27, 0x00001f2f, 0x00010cea, 0x00010caa, + 0x00010438, 0x00010410, 0x000001a5, 0x000001a4, + 0x0000044d, 0x0000042d, 0x000104ea, 0x000104c2, + 0x00016ec2, 0x00016ea7, 0x00001e5f, 0x00001e5e, + 0x00001f55, 0x00001f5d, 0x00000209, 0x00000208, + 0x00001f52, 0x0300009d, 0x000104d8, 0x000104b0, + 0x0000022b, 0x0000022a, 0x00002c33, 0x00002c03, + 0x00002c87, 0x00002c86, 0x0000020f, 0x0000020e, + 0x00016ec4, 0x00016ea9, 0x0000a643, 0x0000a642, + 0x000001c8, 0x000001c7, 0x00001d8e, 0x0000a7c6, + 0x00001fb6, 0x020000a9, 0x000000f8, 0x000000d8, + 0x00001e47, 0x00001e46, 0x000003ad, 0x00000388, + 0x0000a767, 0x0000a766, 0x0000abbc, 0x000013ec, + 0x00002c52, 0x00002c22, 0x0000052d, 0x0000052c, + 0x00001e2f, 0x00001e2e, 0x00002cbd, 0x00002cbc, + 0x0000abb9, 0x000013e9, 0x00010cce, 0x00010c8e, + 0x000104f3, 0x000104cb, 0x0000ab7f, 0x000013af, + 0x000004a9, 0x000004a8, 0x000001a8, 0x000001a7, + 0x00001ea3, 0x00001ea2, 0x000024e8, 0x000024ce, + 0x0000a7a9, 0x0000a7a8, 0x000001ed, 0x000001ec, + 0x00001e7f, 0x00001e7e, 0x00000441, 0x00000421, + 0x00001f37, 0x00001f3f, 0x00001e17, 0x00001e16, + 0x00016e6d, 0x00016e4d, 0x000105a5, 0x0001057e, + 0x0000ff5a, 0x0000ff3a, 0x000104dd, 0x000104b5, + 0x0000abb8, 0x000013e8, 0x00000497, 0x00000496, + 0x000001c9, 0x000001c7, 0x00001e8d, 0x00001e8c, + 0x00001f07, 0x00001f0f, 0x0000a737, 0x0000a736, + 0x00000180, 0x00000243, 0x00001e96, 0x0200008b, + 0x000024dc, 0x000024c2, 0x0001e93f, 0x0001e91d, + 0x00001e09, 0x00001e08, 0x00001c82, 0x0000041e, + 0x0000ab93, 0x000013c3, 0x0000ff49, 0x0000ff29, + 0x000013f8, 0x000013f0, 0x0000017c, 0x0000017b, + 0x000105a6, 0x0001057f, 0x0000a661, 0x0000a660, + 0x00001e71, 0x00001e70, 0x000003b0, 0x03000084, + 0x000024d3, 0x000024b9, 0x00016e70, 0x00016e50, + 0x00000570, 0x00000540, 0x000000e1, 0x000000c1, + 0x00001e6b, 0x00001e6a, 0x000118ca, 0x000118aa, + 0x0000abb5, 0x000013e5, 0x00001f95, 0x02000027, + 0x00010d76, 0x00010d56, 0x00002c3c, 0x00002c0c, + 0x0000013c, 0x0000013b, 0x000001b4, 0x000001b3, + 0x00001ec5, 0x00001ec4, 0x00010cef, 0x00010caf, + 0x000000fe, 0x000000de, 0x00000233, 0x00000232, + 0x0000ab70, 0x000013a0, 0x00002cc3, 0x00002cc2, + 0x00002c34, 0x00002c04, 0x00001e55, 0x00001e54, + 0x0000a663, 0x0000a662, 0x000024d9, 0x000024bf, + 0x00010ce0, 0x00010ca0, 0x00010cd7, 0x00010c97, + 0x000104f5, 0x000104cd, 0x000004f5, 0x000004f4, + 0x00001fc7, 0x0300013a, 0x00010cdb, 0x00010c9b, + 0x00010cda, 0x00010c9a, 0x0000a7d3, 0x0000a7d2, + 0x000003c5, 0x000003a5, 0x000004bb, 0x000004ba, + 0x00001f9d, 0x020000fa, 0x0000ab53, 0x0000a7b3, + 0x00001e79, 0x00001e78, 0x000003f8, 0x000003f7, + 0x0000a74b, 0x0000a74a, 0x00016ecf, 0x00016eb4, + 0x0000021b, 0x0000021a, 0x00001f26, 0x00001f2e, + 0x00001ebf, 0x00001ebe, 0x00001f98, 0x020000eb, + 0x000118c1, 0x000118a1, 0x00010cc4, 0x00010c84, + 0x000024d8, 0x000024be, 0x00016ece, 0x00016eb3, + 0x000024e1, 0x000024c7, 0x000001b6, 0x000001b5, + 0x000010f9, 0x00001cb9, 0x0000ab8e, 0x000013be, + 0x0000ab7c, 0x000013ac, 0x0001044d, 0x00010425, + 0x00016e62, 0x00016e42, 0x000104e0, 0x000104b8, + 0x00002d20, 0x000010c0, 0x0000fb16, 0x02000077, + 0x00001f97, 0x0200002d, 0x0000a72d, 0x0000a72c, + 0x00000454, 0x00000404, 0x00000437, 0x00000417, + 0x00001f44, 0x00001f4c, 0x000000fc, 0x000000dc, + 0x00002c95, 0x00002c94, 0x000003f1, 0x000003a1, + 0x00001f8b, 0x020000dc, 0x00000444, 0x00000424, + 0x00000292, 0x000001b7, 0x000024e4, 0x000024ca, + 0x00002d12, 0x000010b2, 0x0000a783, 0x0000a782, + 0x00000586, 0x00000556, 0x0000006a, 0x0000004a, + 0x0000ab95, 0x000013c5, 0x0000abb6, 0x000013e6, + 0x00002c4c, 0x00002c1c, 0x000104f7, 0x000104cf, + 0x000000f5, 0x000000d5, 0x000001f3, 0x000001f1, + 0x00001e89, 0x00001e88, 0x00001f05, 0x00001f0d, + 0x00000264, 0x0000a7cb, 0x0000011b, 0x0000011a, + 0x00000475, 0x00000474, 0x00000569, 0x00000539, + 0x00001e6d, 0x00001e6c, 0x000010f1, 0x00001cb1, + 0x0000abb7, 0x000013e7, 0x00001eff, 0x00001efe, + 0x00001f32, 0x00001f3a, 0x0000aba8, 0x000013d8, + 0x00000065, 0x00000045, 0x00000215, 0x00000214, + 0x00001ee3, 0x00001ee2, 0x000001c5, 0x000001c4, + 0x00001f61, 0x00001f69, 0x0000026f, 0x0000019c, + 0x0001e92c, 0x0001e90a, 0x00000584, 0x00000554, + 0x00010442, 0x0001041a, 0x00002d1f, 0x000010bf, + 0x00000448, 0x00000428, 0x000024d1, 0x000024b7, + 0x000104e8, 0x000104c0, 0x0000044b, 0x0000042b, + 0x0000a65f, 0x0000a65e, 0x00010d7f, 0x00010d5f, + 0x00002cd1, 0x00002cd0, 0x00001ec9, 0x00001ec8, + 0x00010cdc, 0x00010c9c, 0x0000a7d7, 0x0000a7d6, + 0x00010d7d, 0x00010d5d, 0x000024df, 0x000024c5, + 0x00001f90, 0x02000018, 0x00000149, 0x0200007d, + 0x00001e41, 0x00001e40, 0x0000a651, 0x0000a650, + 0x0000a74f, 0x0000a74e, 0x0000ff43, 0x0000ff23, + 0x000104dc, 0x000104b4, 0x00010d75, 0x00010d55, + 0x000118c8, 0x000118a8, 0x0000012b, 0x0000012a, + 0x000000e4, 0x000000c4, 0x000010d0, 0x00001c90, + 0x00000287, 0x0000a7b1, 0x000104df, 0x000104b7, + 0x000004b1, 0x000004b0, 0x00010429, 0x00010401, + 0x00001f40, 0x00001f48, 0x00000144, 0x00000143, + 0x00000161, 0x00000160, 0x0000ff4c, 0x0000ff2c, + 0x00001c87, 0x00000462, 0x00002177, 0x00002167, + 0x00000525, 0x00000524, 0x00002d1b, 0x000010bb, + 0x000118da, 0x000118ba, 0x0000aba5, 0x000013d5, + 0x00001f99, 0x020000ee, 0x00002c50, 0x00002c20, + 0x00010432, 0x0001040a, 0x0001e93e, 0x0001e91c, + 0x00001fbe, 0x00000399, 0x00001e91, 0x00001e90, + 0x000010da, 0x00001c9a, 0x0000a799, 0x0000a798, + 0x000010ed, 0x00001cad, 0x00001e9a, 0x02000097, + 0x00010d71, 0x00010d51, 0x000105a1, 0x0001057a, + 0x000003be, 0x0000039e, 0x00001fe4, 0x020000c6, + 0x000104f4, 0x000104cc, 0x0000fb15, 0x02000074, + 0x00000445, 0x00000425, 0x000003df, 0x000003de, + 0x00016e66, 0x00016e46, 0x00000581, 0x00000551, + 0x000001ff, 0x000001fe, 0x00002d0c, 0x000010ac, + 0x000010f5, 0x00001cb5, 0x0000ab8b, 0x000013bb, + 0x0001e927, 0x0001e905, 0x0000057f, 0x0000054f, + 0x000013fb, 0x000013f3, 0x00000177, 0x00000176, + 0x00000459, 0x00000409, 0x00001ff6, 0x020000d0, + 0x0000ff4a, 0x0000ff2a, 0x00016ec3, 0x00016ea8, + 0x00000069, 0x00000049, 0x0000abb0, 0x000013e0, + 0x00001ee7, 0x00001ee6, 0x0001059c, 0x00010575, + 0x00001f51, 0x00001f59, 0x0000ab80, 0x000013b0, + 0x0000ab94, 0x000013c4, 0x00016e65, 0x00016e45, + 0x00000567, 0x00000537, 0x00001e5d, 0x00001e5c, + 0x0000aba2, 0x000013d2, 0x000024dd, 0x000024c3, + 0x0000014f, 0x0000014e, 0x0000045f, 0x0000040f, + 0x00016e76, 0x00016e56, 0x000004db, 0x000004da, + 0x00002cdb, 0x00002cda, 0x000118dc, 0x000118bc, + 0x000010db, 0x00001c9b, 0x00002d08, 0x000010a8, + 0x000003c3, 0x000003a3, 0x000118d6, 0x000118b6, + 0x00001fe5, 0x00001fec, 0x000000e3, 0x000000c3, + 0x00001e4d, 0x00001e4c, 0x0000a653, 0x0000a652, + 0x0000a753, 0x0000a752, 0x00016e68, 0x00016e48, + 0x00000263, 0x00000194, 0x00010cc3, 0x00010c83, + 0x00001fd0, 0x00001fd8, 0x000001d4, 0x000001d3, + 0x00001f22, 0x00001f2a, 0x00010ccc, 0x00010c8c, + 0x000010f8, 0x00001cb8, 0x0001044e, 0x00010426, + 0x000004b9, 0x000004b8, 0x00016ec7, 0x00016eac, + 0x00002c3b, 0x00002c0b, 0x000010e8, 0x00001ca8, + 0x0000fb01, 0x02000057, 0x0000a73d, 0x0000a73c, + 0x0000ff4b, 0x0000ff2b, 0x0000028a, 0x000001b1, + 0x00000529, 0x00000528, 0x0001e939, 0x0001e917, + 0x00002cad, 0x00002cac, 0x00002184, 0x00002183, + 0x00001fa5, 0x0200003f, 0x0000ab96, 0x000013c6, + 0x000105b8, 0x00010591, 0x0001043a, 0x00010412, + 0x00002c93, 0x00002c92, 0x0001059e, 0x00010577, + 0x00002d23, 0x000010c3, 0x0000a685, 0x0000a684, + 0x00001f9a, 0x020000f1, 0x0001059f, 0x00010578, + 0x000104e3, 0x000104bb, 0x00001e3b, 0x00001e3a, + 0x00001e1f, 0x00001e1e, 0x000001e7, 0x000001e6, + 0x0000ab9f, 0x000013cf, 0x0000ff58, 0x0000ff38, + 0x00000447, 0x00000427, 0x00000269, 0x00000196, + 0x00010d7e, 0x00010d5e, 0x00000140, 0x0000013f, + 0x00001e8f, 0x00001e8e, 0x0000056e, 0x0000053e, + 0x000105ae, 0x00010587, 0x0000abab, 0x000013db, + 0x00000471, 0x00000470, 0x00000575, 0x00000545, + 0x00001e3d, 0x00001e3c, 0x000001b0, 0x000001af, + 0x00001ec1, 0x00001ec0, 0x00010d74, 0x00010d54, + 0x00000432, 0x00000412, 0x00010441, 0x00010419, + 0x000004f1, 0x000004f0, 0x0000ab7e, 0x000013ae, + 0x00001eeb, 0x00001eea, 0x00002d11, 0x000010b1, + 0x00000219, 0x00000218, 0x00010cdf, 0x00010c9f, + 0x00002c59, 0x00002c29, 0x0000024f, 0x0000024e, + 0x000000e9, 0x000000c9, 0x000001e5, 0x000001e4, + 0x00001f15, 0x00001f1d, 0x00000345, 0x00000399, + 0x00001fe7, 0x030000cc, 0x0000fb04, 0x03000061, + 0x00001f02, 0x00001f0a, 0x000004df, 0x000004de, + 0x00000231, 0x00000230, 0x00001ed5, 0x00001ed4, + 0x00010ce6, 0x00010ca6, 0x0000a77f, 0x0000a77e, + 0x00010ceb, 0x00010cab, 0x00002c68, 0x00002c67, + 0x000104e2, 0x000104ba, 0x000000ed, 0x000000cd, + 0x00001e51, 0x00001e50, 0x000010f7, 0x00001cb7, + 0x0000abae, 0x000013de, 0x00016e60, 0x00016e40, + 0x0000016b, 0x0000016a, 0x00002170, 0x00002160, + 0x00002d02, 0x000010a2, 0x000105b0, 0x00010589, + 0x000104f2, 0x000104ca, 0x000004cc, 0x000004cb, + 0x00010d84, 0x00010d64, 0x00016eca, 0x00016eaf, + 0x000000f1, 0x000000d1, 0x00010433, 0x0001040b, + 0x0000024b, 0x0000024a, 0x00001e35, 0x00001e34, + 0x00002c99, 0x00002c98, 0x0000a65d, 0x0000a65c, + 0x0000ff59, 0x0000ff39, 0x000104e4, 0x000104bc, + 0x00001f7d, 0x00001ffb, 0x00016e75, 0x00016e55, + 0x0000010b, 0x0000010a, 0x00001c8a, 0x00001c89, + 0x00010cc0, 0x00010c80, 0x0000fb02, 0x0200005a, + 0x000104f6, 0x000104ce, 0x000004a1, 0x000004a0, + 0x00000121, 0x00000120, 0x00001f8f, 0x020000e8, + 0x00002d27, 0x000010c7, 0x0000fb14, 0x02000071, + 0x00002d00, 0x000010a0, 0x000000f2, 0x000000d2, + 0x000118c4, 0x000118a4, 0x000118d1, 0x000118b1, + 0x00001e19, 0x00001e18, 0x00010599, 0x00010572, + 0x000010e7, 0x00001ca7, 0x000004c8, 0x000004c7, + 0x00016e64, 0x00016e44, 0x00000503, 0x00000502, + 0x0000029d, 0x0000a7b2, 0x000010ec, 0x00001cac, + 0x0000ab91, 0x000013c1, 0x0000a693, 0x0000a692, + 0x0000a793, 0x0000a792, 0x00002c5f, 0x00002c2f, + 0x00010ce7, 0x00010ca7, 0x00000481, 0x00000480, + 0x0000ab7a, 0x000013aa, 0x00001e07, 0x00001e06, + 0x00002d24, 0x000010c4, 0x0000a72f, 0x0000a72e, + 0x00010cee, 0x00010cae, 0x00010443, 0x0001041b, + 0x00001eef, 0x00001eee, 0x000003f2, 0x000003f9, + 0x0000026c, 0x0000a7ad, 0x00001e7b, 0x00001e7a, + 0x00001fb1, 0x00001fb9, 0x000105b1, 0x0001058a, + 0x000010f4, 0x00001cb4, 0x00002ca7, 0x00002ca6, + 0x00000561, 0x00000531, 0x000010ef, 0x00001caf, + 0x0000ff53, 0x0000ff33, 0x00001ee9, 0x00001ee8, + 0x00016e7e, 0x00016e5e, 0x00010d83, 0x00010d63, + 0x000003e7, 0x000003e6, 0x000004f3, 0x000004f2, + 0x00002cdd, 0x00002cdc, 0x0000a647, 0x0000a646, + 0x00001fd3, 0x030000b3, 0x00002c5a, 0x00002c2a, + 0x0000217e, 0x0000216e, 0x000024e2, 0x000024c8, + 0x000024e9, 0x000024cf, 0x000003f3, 0x0000037f, + 0x00000252, 0x00002c70, 0x0000043c, 0x0000041c, + 0x000118c2, 0x000118a2, 0x00016e6c, 0x00016e4c, + 0x00000449, 0x00000429, 0x0000abac, 0x000013dc, + 0x0000a649, 0x0000a648, 0x000010d6, 0x00001c96, + 0x00001f85, 0x0200000f, 0x00001e39, 0x00001e38, + 0x00000192, 0x00000191, 0x0000ff46, 0x0000ff26, + 0x000004bd, 0x000004bc, 0x00010447, 0x0001041f, + 0x00002c36, 0x00002c06, 0x00001e65, 0x00001e64, + 0x0000a64d, 0x0000a64c, 0x0000a741, 0x0000a740, + 0x00002c3a, 0x00002c0a, 0x000104da, 0x000104b2, + 0x000105ad, 0x00010586, 0x00001e2b, 0x00001e2a, + 0x00002cb7, 0x00002cb6, 0x0000020d, 0x0000020c, + 0x000104fa, 0x000104d2, 0x00000458, 0x00000408, + 0x00000225, 0x00000224, 0x0001059d, 0x00010576, + 0x0000012d, 0x0000012c, 0x00001fac, 0x0200010f, + 0x0000a68f, 0x0000a68e, 0x00001fe0, 0x00001fe8, + 0x000024d2, 0x000024b8, 0x000118de, 0x000118be, + 0x00010cdd, 0x00010c9d, 0x000118d2, 0x000118b2, + 0x00002d19, 0x000010b9, 0x00001f11, 0x00001f19, + 0x00002d1d, 0x000010bd, 0x00001f74, 0x00001fca, + 0x00000223, 0x00000222, 0x00010cd1, 0x00010c91, + 0x000004b7, 0x000004b6, 0x00000109, 0x00000108, + 0x00000205, 0x00000204, 0x0000a699, 0x0000a698, + 0x0000a797, 0x0000a796, 0x00001c84, 0x00000422, + 0x00010cd3, 0x00010c93, 0x0000057d, 0x0000054d, + 0x000001ad, 0x000001ac, 0x00001e1b, 0x00001e1a, + 0x00002ca9, 0x00002ca8, 0x0000a77a, 0x0000a779, + 0x00010cd9, 0x00010c99, 0x000105b5, 0x0001058e, + 0x000004f9, 0x000004f8, 0x000003cb, 0x000003ab, + 0x000003e1, 0x000003e0, 0x00002c5d, 0x00002c2d, + 0x0000a689, 0x0000a688, 0x00010d80, 0x00010d60, + 0x000118d8, 0x000118b8, 0x00000463, 0x00000462, + 0x0000056d, 0x0000053d, 0x00001f64, 0x00001f6c, + 0x00002cf3, 0x00002cf2, 0x00001ef9, 0x00001ef8, + 0x00000146, 0x00000145, 0x00016e74, 0x00016e54, + 0x0000aba6, 0x000013d6, 0x00000063, 0x00000043, + 0x000003cc, 0x0000038c, 0x00001ed9, 0x00001ed8, + 0x00016ec0, 0x00016ea5, 0x0000a645, 0x0000a644, + 0x00000195, 0x000001f6, 0x0000ff42, 0x0000ff22, + 0x000118dd, 0x000118bd, 0x00002c39, 0x00002c09, + 0x00002d15, 0x000010b5, 0x00016e61, 0x00016e41, + 0x0000fb13, 0x0200006e, 0x00001fd1, 0x00001fd9, + 0x000024d6, 0x000024bc, 0x0000026a, 0x0000a7ae, + 0x00000165, 0x00000164, 0x0000ab9c, 0x000013cc, + 0x00000247, 0x00000246, 0x00001ff7, 0x0300013e, + 0x0000abba, 0x000013ea, 0x0001044a, 0x00010422, + 0x0000048f, 0x0000048e, 0x000024d0, 0x000024b6, + 0x00010431, 0x00010409, 0x000001bf, 0x000001f7, + 0x0000ff50, 0x0000ff30, 0x00010d81, 0x00010d61, + 0x000003bd, 0x0000039d, 0x000118d0, 0x000118b0, + 0x00002174, 0x00002164, 0x00001e31, 0x00001e30, + 0x0000017a, 0x00000179, 0x00001eab, 0x00001eaa, + 0x0001e928, 0x0001e906, 0x000118db, 0x000118bb, + 0x000003b3, 0x00000393, 0x000003d0, 0x00000392, + 0x00000127, 0x00000126, 0x00001ea5, 0x00001ea4, + 0x000104ee, 0x000104c6, 0x00002d0b, 0x000010ab, + 0x0000a73f, 0x0000a73e, 0x0000ff44, 0x0000ff24, + 0x0000abb2, 0x000013e2, 0x00000523, 0x00000522, + 0x00001e21, 0x00001e20, 0x0000a735, 0x0000a734, + 0x0000a727, 0x0000a726, 0x00000457, 0x00000407, + 0x0000a7a7, 0x0000a7a6, 0x00002171, 0x00002161, + 0x0000049b, 0x0000049a, 0x00000115, 0x00000114, + 0x00001e95, 0x00001e94, 0x0000a69b, 0x0000a69a, + 0x0000a79b, 0x0000a79a, 0x00000283, 0x000001a9, + 0x000003c4, 0x000003a4, 0x0000ab9a, 0x000013ca, + 0x00002c8d, 0x00002c8c, 0x00000242, 0x00000241, + 0x00010cc5, 0x00010c85, 0x0000025c, 0x0000a7ab, + 0x00016ebe, 0x00016ea3, 0x00002c4f, 0x00002c1f, + 0x000004f7, 0x000004f6, 0x000001da, 0x000001d9, + 0x00002c83, 0x00002c82, 0x00000119, 0x00000118, + 0x0000a687, 0x0000a686, 0x0000a785, 0x0000a784, + 0x0001042a, 0x00010402, 0x0000047d, 0x0000047c, + 0x00000571, 0x00000541, 0x00000075, 0x00000055, + 0x00000185, 0x00000184, 0x00001ef1, 0x00001ef0, + 0x0000ff54, 0x0000ff34, 0x000013fa, 0x000013f2, + 0x000010e6, 0x00001ca6, 0x00000067, 0x00000047, + 0x0001e941, 0x0001e91f, 0x000000ee, 0x000000ce, + 0x0000a66d, 0x0000a66c, 0x00000438, 0x00000418, + 0x000000e8, 0x000000c8, 0x00001f06, 0x00001f0e, + 0x000104e6, 0x000104be, 0x00001f03, 0x00001f0b, + 0x00002d17, 0x000010b7, 0x00001f67, 0x00001f6f, + 0x0000a763, 0x0000a762, 0x00010cd4, 0x00010c94, + 0x00001f60, 0x00001f68, 0x00002ce3, 0x00002ce2, + 0x0000a7bf, 0x0000a7be, 0x00000562, 0x00000532, + 0x00001ed7, 0x00001ed6, 0x00001fa0, 0x02000030, + 0x00002d06, 0x000010a6, 0x00002175, 0x00002165, + 0x00010ce1, 0x00010ca1, 0x000104fb, 0x000104d3, + 0x000118d4, 0x000118b4, 0x00001e4b, 0x00001e4a, + 0x00001f8e, 0x020000e5, 0x0000a74d, 0x0000a74c, + 0x00002cc7, 0x00002cc6, 0x00000435, 0x00000415, + 0x00010ced, 0x00010cad, 0x00001e33, 0x00001e32, + 0x00000133, 0x00000132, 0x000000fb, 0x000000db, + 0x00001ef5, 0x00001ef4, 0x000010f6, 0x00001cb6, + 0x00000452, 0x00000402, 0x00010cc7, 0x00010c87, + 0x00000574, 0x00000544, 0x00001ea7, 0x00001ea6, + 0x000003af, 0x0000038a, 0x00001fa6, 0x02000042, + 0x0000a7f6, 0x0000a7f5, 0x000104f9, 0x000104d1, + 0x00001f7a, 0x00001fea, 0x00000527, 0x00000526, + 0x00001e29, 0x00001e28, 0x0000abad, 0x000013dd, + 0x00000271, 0x00002c6e, 0x00001fa7, 0x02000045, + 0x00002c9f, 0x00002c9e, 0x00002c9b, 0x00002c9a, + 0x0000049f, 0x0000049e, 0x00000135, 0x00000134, + 0x00001e99, 0x02000094, 0x00001fa2, 0x02000036, + 0x00002c31, 0x00002c01, 0x00002cdf, 0x00002cde, + 0x000024d5, 0x000024bb, 0x00010445, 0x0001041d, + 0x0001e92e, 0x0001e90c, 0x00002d05, 0x000010a5, + 0x00001f72, 0x00001fc8, 0x00002d0a, 0x000010aa, + 0x000004c2, 0x000004c1, 0x00001f78, 0x00001ff8, + 0x00001f34, 0x00001f3c, 0x00000117, 0x00000116, + 0x000118d9, 0x000118b9, 0x00002ca5, 0x00002ca4, + 0x000000f0, 0x000000d0, 0x000105b7, 0x00010590, + 0x00000076, 0x00000056, 0x000118c9, 0x000118a9, + 0x00001f35, 0x00001f3d, 0x0001e929, 0x0001e907, + 0x00000153, 0x00000152, 0x00001efd, 0x00001efc, + 0x00000288, 0x000001ae, 0x00001f96, 0x0200002a, + 0x000010fe, 0x00001cbe, 0x000004e9, 0x000004e8, + 0x0000a7c8, 0x0000a7c7, 0x00001ee5, 0x00001ee4, + 0x0001e930, 0x0001e90e, 0x0000006e, 0x0000004e, + 0x00002c57, 0x00002c27, 0x00002c53, 0x00002c23, + 0x00016e69, 0x00016e49, 0x000003b4, 0x00000394, + 0x00001e61, 0x00001e60, 0x0000011d, 0x0000011c, + 0x0000a765, 0x0000a764, 0x00001f01, 0x00001f09, + 0x00000455, 0x00000405, 0x00016ecb, 0x00016eb0, + 0x000001dd, 0x0000018e, 0x00000159, 0x00000158, + 0x0000ab82, 0x000013b2, 0x000010d1, 0x00001c91, + 0x0000a7db, 0x0000a7da, 0x0000024d, 0x0000024c, + 0x00000585, 0x00000555, 0x000105ac, 0x00010585, + 0x00001f00, 0x00001f08, 0x00001e4f, 0x00001e4e, + 0x00000390, 0x03000080, 0x00000249, 0x00000248, + 0x000001dc, 0x000001db, 0x00000465, 0x00000464, + 0x00016e67, 0x00016e47, 0x000003c8, 0x000003a8, + 0x00000125, 0x00000124, 0x00001ec3, 0x00001ec2, + 0x00010cd0, 0x00010c90, 0x0000a7c1, 0x0000a7c0, + 0x00002c4a, 0x00002c1a, 0x0000a64b, 0x0000a64a, + 0x0000045a, 0x0000040a, 0x0001e935, 0x0001e913, + 0x0000abbd, 0x000013ed, 0x00001f70, 0x00001fba, + 0x00010d78, 0x00010d58, 0x0000ff41, 0x0000ff21, + 0x000104e7, 0x000104bf, 0x00000074, 0x00000054, + 0x0000aba0, 0x000013d0, 0x00000129, 0x00000128, + 0x0000abb3, 0x000013e3, 0x00002ca3, 0x00002ca2, + 0x000105a7, 0x00010580, 0x0000ff52, 0x0000ff32, + 0x000004a3, 0x000004a2, 0x00000111, 0x00000110, + 0x0000a77c, 0x0000a77b, 0x00002d07, 0x000010a7, + 0x000024d7, 0x000024bd, 0x00002c32, 0x00002c02, + 0x00000491, 0x00000490, 0x000105b9, 0x00010592, + 0x0000050d, 0x0000050c, 0x00001e11, 0x00001e10, + 0x00001c86, 0x0000042a, 0x0000ab9b, 0x000013cb, + 0x000004c6, 0x000004c5, 0x00010cc9, 0x00010c89, + 0x00000505, 0x00000504, 0x0000027d, 0x00002c64, + 0x00016e71, 0x00016e51, 0x00001ead, 0x00001eac, + 0x0000a695, 0x0000a694, 0x00016e77, 0x00016e57, + 0x00016ed3, 0x00016eb8, 0x0000ab8a, 0x000013ba, + 0x00001d7d, 0x00002c63, 0x000013fd, 0x000013f5, + 0x00001c85, 0x00000422, 0x0000ab85, 0x000013b5, + 0x00001f82, 0x02000006, 0x00002c35, 0x00002c05, + 0x00002d1a, 0x000010ba, 0x00000163, 0x00000162, + 0x00010437, 0x0001040f, 0x00002c73, 0x00002c72, + 0x0000a78c, 0x0000a78b, 0x00001f91, 0x0200001b, + 0x000003e5, 0x000003e4, 0x0000ff4f, 0x0000ff2f, + 0x0000046b, 0x0000046a, 0x00000103, 0x00000102, + 0x0000028c, 0x00000245, 0x0000a66b, 0x0000a66a, + 0x000024db, 0x000024c1, 0x00016e7a, 0x00016e5a, + 0x0000044e, 0x0000042e, 0x0000217f, 0x0000216f, + 0x000004ff, 0x000004fe, 0x00000151, 0x00000150, + 0x00001ed1, 0x00001ed0, 0x00010ce2, 0x00010ca2, + 0x0000021f, 0x0000021e, 0x000003b1, 0x00000391, + 0x0000048d, 0x0000048c, 0x000104db, 0x000104b3, + 0x0000010f, 0x0000010e, 0x00001f56, 0x030000a5, + 0x00002179, 0x00002169, 0x0000a755, 0x0000a754, + 0x00016e7c, 0x00016e5c, 0x0001044f, 0x00010427, + 0x000010ee, 0x00001cae, 0x000001a3, 0x000001a2, + 0x00002c45, 0x00002c15, 0x000004d3, 0x000004d2, + 0x0000ab9e, 0x000013ce, 0x0000a7b5, 0x0000a7b4, + 0x00016ed2, 0x00016eb7, 0x000004ab, 0x000004aa, + 0x00001fb0, 0x00001fb8, 0x000104ed, 0x000104c5, + 0x000118d5, 0x000118b5, 0x00001f13, 0x00001f1b, + 0x0000a745, 0x0000a744, 0x000118ce, 0x000118ae, + 0x0000ab89, 0x000013b9, 0x0000014b, 0x0000014a, + 0x00001e2d, 0x00001e2c, 0x00001fd2, 0x030000af, + 0x0000ab97, 0x000013c7, 0x00010cd2, 0x00010c92, + 0x0000ab87, 0x000013b7, 0x00001f94, 0x02000024, + 0x0000abaf, 0x000013df, 0x00000070, 0x00000050, + 0x00001ffc, 0x02000121, 0x00002d25, 0x000010c5, + 0x0000a7bd, 0x0000a7bc, 0x00010428, 0x00010400, + 0x00000495, 0x00000494, 0x000104d9, 0x000104b1, + 0x00000157, 0x00000156, 0x0000a73b, 0x0000a73a, + 0x0000a665, 0x0000a664, 0x0000aba1, 0x000013d1, + 0x0000ab72, 0x000013a2, 0x00010d82, 0x00010d62, + 0x000024de, 0x000024c4, 0x000001eb, 0x000001ea, + 0x00002caf, 0x00002cae, 0x00000207, 0x00000206, + 0x000010d8, 0x00001c98, 0x0000a79f, 0x0000a79e, + 0x00002cd9, 0x00002cd8, 0x00001c80, 0x00000412, + 0x0000ab84, 0x000013b4, 0x00000440, 0x00000420, + 0x00001e27, 0x00001e26, 0x000105ab, 0x00010584, + 0x00001fa8, 0x02000103, 0x000104f8, 0x000104d0, + 0x000003fb, 0x000003fa, 0x0001e92a, 0x0001e908, + 0x00001fc4, 0x0200012d, 0x00000568, 0x00000538, + 0x0001e934, 0x0001e912, 0x00000563, 0x00000533, + 0x0000a787, 0x0000a786, 0x0001e92b, 0x0001e909, + 0x0000046d, 0x0000046c, 0x0000056b, 0x0000053b, + 0x00001e69, 0x00001e68, 0x0000a657, 0x0000a656, + 0x0000a76f, 0x0000a76e, 0x00000446, 0x00000426, + 0x00002c46, 0x00002c16, 0x0001044b, 0x00010423, + 0x000004e3, 0x000004e2, 0x0000015d, 0x0000015c, + 0x00001edd, 0x00001edc, 0x000010de, 0x00001c9e, + 0x000000f3, 0x000000d3, 0x0000abb4, 0x000013e4, + 0x0001e923, 0x0001e901, 0x0000047f, 0x0000047e, + 0x00002cd5, 0x00002cd4, 0x00000188, 0x00000187, + 0x00001fe3, 0x030000c2, 0x0000a757, 0x0000a756, + 0x0000016d, 0x0000016c, 0x000104de, 0x000104b6, + 0x00010cd5, 0x00010c95, 0x00002c4e, 0x00002c1e, + 0x00002ccb, 0x00002cca, 0x00002c65, 0x0000023a, + 0x00010cd8, 0x00010c98, 0x0000a7cd, 0x0000a7cc, + 0x000001ce, 0x000001cd, 0x00001ed3, 0x00001ed2, + 0x00010d85, 0x00010d65, 0x00001f42, 0x00001f4a, + 0x0000043f, 0x0000041f, 0x000003bc, 0x0000039c, + 0x0000a749, 0x0000a748, 0x0000ff4e, 0x0000ff2e, + 0x000024e0, 0x000024c6, 0x000003f0, 0x0000039a, + 0x00000430, 0x00000410, 0x00002cb3, 0x00002cb2, + 0x00001eb3, 0x00001eb2, 0x00001fa3, 0x02000039, + 0x00010cc1, 0x00010c81, 0x00016ec8, 0x00016ead, + 0x000010f2, 0x00001cb2, 0x00000123, 0x00000122, + 0x00001eaf, 0x00001eae, 0x0000abaa, 0x000013da, + 0x0000023f, 0x00002c7e, 0x00010434, 0x0001040c, + 0x00016e78, 0x00016e58, 0x000024da, 0x000024c0, + 0x000118c6, 0x000118a6, 0x000001d0, 0x000001cf, + 0x0000a667, 0x0000a666, 0x0000aba3, 0x000013d3, + 0x00002c49, 0x00002c19, 0x00002d1c, 0x000010bc, + 0x0001e925, 0x0001e903, 0x00000493, 0x00000492, + 0x00000072, 0x00000052, 0x00001e93, 0x00001e92, + 0x0000a691, 0x0000a690, 0x000104ec, 0x000104c4, + 0x00002d0f, 0x000010af, 0x000010f0, 0x00001cb0, + 0x0000ab98, 0x000013c8, 0x00000509, 0x00000508, + 0x00001e0b, 0x00001e0a, 0x000003dd, 0x000003dc, + 0x0000ab99, 0x000013c9, 0x00016e6b, 0x00016e4b, + 0x000105a8, 0x00010581, 0x00000071, 0x00000051 }; -static const unsigned _uccase_lower_g_size = 274; +static const unsigned _uccase_lower_g_size = 339; static const short _uccase_lower_g[] = { - 19, -339, 8836, 631, 9135, 8, 27, -1063, - 10, 3627, 876, 27, 47, 16534, 60, 888, - 17, 64, 2, 5, 9, 1237, 18, 2342, - 111, 17, 359, 110, 69, 2640, 78, 354, - 228, 4917, 61, 260, 3, 2614, 9, 353, - 37, 68, 1061, 3015, 21, 4002, 962, 1724, - 446, 776, 17, 8978, 421, 336, 506, 8550, - 148, -474, 3259, 933, 1171, 413, 126, -1086, - 2, 3008, 295, 110, 16, -1061, 67, 598, - 126, 3575, 79, 98, 103, 693, 32, 749, - 3, 2501, 260, 1003, 15, 4463, 282, 349, - 16, 40, 6, 935, 546, 726, 2, 353, - 94, 928, 780, 7113, 39, 3599, 6035, 315, - 186, 4306, 16, 9259, 100, 82, 1069, 537, - 72, -686, 12102, 8064, 216, 95, 1761, 32767, - 8, 3436, 116, 1035, 14, 5405, 40, 1012, - 22, 135, 22, 1252, 589, 812, 8, 1721, - 10, 761, 84, 103, 36, 655, 600, 3517, - 11, 475, 1, 205, 17, 4384, 20, 5705, - 198, 741, 154, 8691, 28, 247, 739, 144, - 343, 703, 16, 32767, 809, 773, 806, 15951, - 270, 443, 360, 4365, 2648, 154, 109, -191, - 12, 11910, 43, 849, 2, 1876, 65, 460, - 19, 585, 1, 684, 391, 463, 203, 782, - 102, 2630, 679, 1610, 35, 5529, 84, 3992, - 1, 157, 8, 389, 1295, 1272, 153, 406, - 133, 1074, 59, 9484, 2, 264, 7316, 276, - 252, 520, 29, -220, 113, 15121, 525, 2091, - 283, 6976, 1, 13412, 647, 51, 285, 2206, - 3, 678, 17, 948, 114, 1233, 1, 38, - 19, 1583, 52, 803, 770, 1329, 380, 8813, - 66, 133, 256, 6495, 18, 7784, 53, 2867, - 4, 680, 34, 258, 1488, 1040, 19, 3566, - 844, 12080, 391, 7012, 1, 2670, 3227, 146, - 362, 1934 + 2657, 182, 11, 3707, 9309, 2, 2598, 245, + 521, 3500, 2366, 1, 57, 3082, -1357, 3638, + 4489, 2573, 646, -865, 3844, 3, -399, 132, + 41, -467, 9225, 16, 3073, 838, 2220, 606, + 1687, -71, 191, 148, 2573, 2042, 263, 2955, + 3, 2055, 2442, 3116, 935, 166, 3306, 2547, + 1115, 470, 516, 1064, 512, 9286, 1262, 38, + 270, 565, 756, 8014, 5285, 3296, 38, 1298, + 12, 574, 2572, 7250, 2, 2616, 28, 64, + 3676, 43, 1, 2574, 3532, 242, 3367, 2181, + 70, 800, 5195, 32767, 1076, 3784, 2565, 199, + -864, 3795, 4, -386, 143, 2051, 3282, 9328, + 2833, 9266, 675, 2245, 522, 3845, -20, 532, + 2570, 2970, 736, 2638, 2634, 175, -1268, 3373, + 12978, 943, 836, 3641, 5729, 1049, 66, 263, + 1147, 332, 2119, 2822, 66, 1353, 1604, 1498, + 9, 2461, 654, 872, 3475, 937, 65, 3233, + 7822, 2, 2605, 1, 167, 3841, 329, 65, + 2574, 2549, 2069, 1, 2707, 786, 174, 2947, + -1341, 72, -1248, 2177, 96, -831, 9341, 18, + -343, 2243, 3854, 2179, 689, 626, 4269, 884, + 196, 39, 270, -2, 2566, 2737, 2955, 649, + 2561, -459, 22, 2878, 332, 3772, 1768, 555, + 172, 3687, 2104, 169, 524, 1170, 421, 6443, + 3073, 501, 365, 518, 727, 54, 2315, 10847, + 610, 3584, 148, 8, 2695, 396, 1, 2595, + 6, 2053, 3572, 2722, 1, 4043, 2216, 547, + 132, 449, 763, 3570, 2415, 15812, 1, 32767, + 3606, 8, -791, 3613, 477, 3521, 3689, 1308, + 4020, 3417, 7, 4748, 783, 3078, 209, 3363, + 3088, 2180, 2509, 2566, 3079, 2560, 2072, 781, + 12740, 331, 3252, 900, 2030, 459, 2990, 3076, + 151, 25, 9, 406, 2836, 3084, 55, 1, + 3613, 159, 64, 2275, 10626, 36, 1647, 428, + 36, 3714, 302, 64, 2792, 11, 1731, 3733, + 2822, 1, 3969, 3596, 2248, 145, 140, 752, + 3332, -1244, 10190, 2, 32767, 92, 2, -585, + -229, 390, 9696, 1000, 2134, 9344, 3363, 178, + 737, 811, 3182, 2176, 2581, 2977, 164, 2570, + 3887, 3616, 1557, 3597, 227, 2329, 295, 3478, + 1683, 1105, 515, 4023, 2958, 28, 379, 257, + 257, 753, 2540, 35, 2, 3585, 1, 719, + 2310, 1005, 10 }; -static const unsigned _uccase_lower_table_size = 1460; +static const unsigned _uccase_lower_table_size = 1488; static const unsigned _uccase_lower_table[] = { - 0x00002cac, 0x00002cad, 0x00001e78, 0x00001e79, - 0x0000042d, 0x0000044d, 0x0000023d, 0x0000019a, - 0x00002169, 0x00002179, 0x00001fb9, 0x00001fb1, - 0x000013e9, 0x0000abb9, 0x000001a9, 0x00000283, - 0x000001c4, 0x000001c6, 0x000000c5, 0x000000e5, - 0x00000230, 0x00000231, 0x00000372, 0x00000373, - 0x00000232, 0x00000233, 0x00000053, 0x00000073, - 0x0000018a, 0x00000257, 0x00001ec0, 0x00001ec1, - 0x0000046c, 0x0000046d, 0x00010ca1, 0x00010ce1, - 0x00000536, 0x00000566, 0x00001e32, 0x00001e33, - 0x00010d59, 0x00010d79, 0x00001ec4, 0x00001ec5, - 0x00000200, 0x00000201, 0x000013bd, 0x0000ab8d, - 0x00001f48, 0x00001f40, 0x00000423, 0x00000443, - 0x00002c07, 0x00002c37, 0x000104bc, 0x000104e4, - 0x000013af, 0x0000ab7f, 0x00010caa, 0x00010cea, - 0x000004a8, 0x000004a9, 0x000024bf, 0x000024d9, - 0x000000d0, 0x000000f0, 0x00001e42, 0x00001e43, - 0x00010577, 0x0001059e, 0x00001e1a, 0x00001e1b, - 0x0000a750, 0x0000a751, 0x000000dd, 0x000000fd, - 0x00002c0c, 0x00002c3c, 0x0001e91b, 0x0001e93d, - 0x00002126, 0x000003c9, 0x00016e41, 0x00016e61, - 0x000010b4, 0x00002d14, 0x000001b3, 0x000001b4, - 0x00000050, 0x00000070, 0x00000122, 0x00000123, - 0x00000427, 0x00000447, 0x000013f5, 0x000013fd, - 0x00001e60, 0x00001e61, 0x00010c92, 0x00010cd2, - 0x00001f0a, 0x00001f02, 0x0000a662, 0x0000a663, - 0x0000040d, 0x0000045d, 0x000013d4, 0x0000aba4, - 0x000013ec, 0x0000abbc, 0x0000012e, 0x0000012f, - 0x00001ec8, 0x00001ec9, 0x00000498, 0x00000499, - 0x00001e22, 0x00001e23, 0x00010574, 0x0001059b, - 0x0000ff25, 0x0000ff45, 0x00000535, 0x00000565, - 0x000001e4, 0x000001e5, 0x000104b0, 0x000104d8, - 0x00000386, 0x000003ac, 0x000013ed, 0x0000abbd, - 0x00002c72, 0x00002c73, 0x000118a8, 0x000118c8, - 0x000003e0, 0x000003e1, 0x00010412, 0x0001043a, - 0x0000048a, 0x0000048b, 0x000013ee, 0x0000abbe, - 0x000000c0, 0x000000e0, 0x0001058f, 0x000105b6, - 0x0000016a, 0x0000016b, 0x0000a646, 0x0000a647, - 0x00000206, 0x00000207, 0x00000399, 0x000003b9, - 0x00002c17, 0x00002c47, 0x0000a79a, 0x0000a79b, - 0x000013b1, 0x0000ab81, 0x00002c9a, 0x00002c9b, - 0x00000428, 0x00000448, 0x000010bd, 0x00002d1d, - 0x0000053d, 0x0000056d, 0x00002166, 0x00002176, - 0x00000170, 0x00000171, 0x00010c9c, 0x00010cdc, - 0x000001a0, 0x000001a1, 0x0001057d, 0x000105a4, - 0x00002c29, 0x00002c59, 0x00010c8b, 0x00010ccb, - 0x00000051, 0x00000071, 0x00001f88, 0x00001f80, - 0x000013e6, 0x0000abb6, 0x000024b8, 0x000024d2, - 0x000004b8, 0x000004b9, 0x00016e56, 0x00016e76, - 0x00010586, 0x000105ad, 0x000013d7, 0x0000aba7, - 0x000013cf, 0x0000ab9f, 0x0000011e, 0x0000011f, - 0x00000043, 0x00000063, 0x000001c8, 0x000001c9, - 0x000010a9, 0x00002d09, 0x000001d3, 0x000001d4, - 0x000004cb, 0x000004cc, 0x00002c60, 0x00002c61, - 0x0000a724, 0x0000a725, 0x00002cda, 0x00002cdb, - 0x000024ca, 0x000024e4, 0x00000470, 0x00000471, - 0x000000db, 0x000000fb, 0x0000051a, 0x0000051b, - 0x00000516, 0x00000517, 0x0001057a, 0x000105a1, - 0x00000224, 0x00000225, 0x000001e8, 0x000001e9, - 0x000010ba, 0x00002d1a, 0x0000a78d, 0x00000265, - 0x000013c4, 0x0000ab94, 0x0001e905, 0x0001e927, - 0x000013c3, 0x0000ab93, 0x000003e4, 0x000003e5, - 0x000003ec, 0x000003ed, 0x00010415, 0x0001043d, - 0x0000046a, 0x0000046b, 0x00010422, 0x0001044a, - 0x00001ffb, 0x00001f7d, 0x0001e906, 0x0001e928, - 0x00001ee0, 0x00001ee1, 0x00000208, 0x00000209, - 0x0000a686, 0x0000a687, 0x00001e00, 0x00001e01, - 0x000013ac, 0x0000ab7c, 0x000013b8, 0x0000ab88, - 0x0000ff38, 0x0000ff58, 0x0000039d, 0x000003bd, - 0x00000422, 0x00000442, 0x000004e0, 0x000004e1, - 0x00001cba, 0x000010fa, 0x00001cb3, 0x000010f3, - 0x00001e6c, 0x00001e6d, 0x0000a684, 0x0000a685, - 0x00010c8d, 0x00010ccd, 0x0000a72e, 0x0000a72f, - 0x0000022c, 0x0000022d, 0x00001f9a, 0x00001f92, - 0x00000395, 0x000003b5, 0x00000114, 0x00000115, - 0x00001f8d, 0x00001f85, 0x00001c9a, 0x000010da, - 0x00000198, 0x00000199, 0x000013ce, 0x0000ab9e, - 0x00010c8f, 0x00010ccf, 0x00010588, 0x000105af, - 0x00010401, 0x00010429, 0x000004e8, 0x000004e9, - 0x00000396, 0x000003b6, 0x00001e5c, 0x00001e5d, - 0x0000a728, 0x0000a729, 0x00000193, 0x00000260, - 0x00001cac, 0x000010ec, 0x000024c9, 0x000024e3, - 0x00002c69, 0x00002c6a, 0x00010c9f, 0x00010cdf, - 0x0000a7c0, 0x0000a7c1, 0x0000a722, 0x0000a723, - 0x00000534, 0x00000564, 0x0000a754, 0x0000a755, - 0x000104b6, 0x000104de, 0x000118b0, 0x000118d0, - 0x00000214, 0x00000215, 0x00001f1c, 0x00001f14, - 0x00001e50, 0x00001e51, 0x00010c90, 0x00010cd0, - 0x000001b5, 0x000001b6, 0x00000510, 0x00000511, - 0x0000a64c, 0x0000a64d, 0x0000004e, 0x0000006e, - 0x000118ab, 0x000118cb, 0x000118b3, 0x000118d3, - 0x000104b9, 0x000104e1, 0x000001a2, 0x000001a3, - 0x00001e3e, 0x00001e3f, 0x00001f99, 0x00001f91, - 0x00000220, 0x0000019e, 0x00001fcb, 0x00001f75, - 0x00002cde, 0x00002cdf, 0x000013e1, 0x0000abb1, - 0x000013cc, 0x0000ab9c, 0x000001d7, 0x000001d8, - 0x00000389, 0x000003ae, 0x000010af, 0x00002d0f, - 0x0000a66c, 0x0000a66d, 0x000004f2, 0x000004f3, - 0x00001ca5, 0x000010e5, 0x000004f4, 0x000004f5, - 0x0000a68a, 0x0000a68b, 0x00001eaa, 0x00001eab, - 0x0000021a, 0x0000021b, 0x0000a7be, 0x0000a7bf, - 0x0000038f, 0x000003ce, 0x0000a79e, 0x0000a79f, - 0x0000ff31, 0x0000ff51, 0x000010b5, 0x00002d15, - 0x00016e55, 0x00016e75, 0x000010a8, 0x00002d08, - 0x00010c9d, 0x00010cdd, 0x000104cc, 0x000104f4, - 0x00000112, 0x00000113, 0x0000a654, 0x0000a655, - 0x0000a7ba, 0x0000a7bb, 0x0000a7b3, 0x0000ab53, - 0x000013e3, 0x0000abb3, 0x00000412, 0x00000432, - 0x00001efa, 0x00001efb, 0x0000a7ad, 0x0000026c, - 0x0001e920, 0x0001e942, 0x00016e58, 0x00016e78, - 0x00001cbd, 0x000010fd, 0x00000490, 0x00000491, - 0x00010ca7, 0x00010ce7, 0x00001e2c, 0x00001e2d, - 0x00001e56, 0x00001e57, 0x0000a75e, 0x0000a75f, - 0x00001f1d, 0x00001f15, 0x00010576, 0x0001059d, - 0x00002c20, 0x00002c50, 0x000013a2, 0x0000ab72, - 0x00002cbc, 0x00002cbd, 0x000024c1, 0x000024db, - 0x0000042b, 0x0000044b, 0x00002c21, 0x00002c51, - 0x0000216e, 0x0000217e, 0x00002c8a, 0x00002c8b, - 0x00001ff9, 0x00001f79, 0x00000544, 0x00000574, - 0x0000a688, 0x0000a689, 0x000001d1, 0x000001d2, - 0x0000020a, 0x0000020b, 0x00001cb5, 0x000010f5, - 0x00002c24, 0x00002c54, 0x0000a7d8, 0x0000a7d9, - 0x0000053f, 0x0000056f, 0x0000041d, 0x0000043d, - 0x00016e47, 0x00016e67, 0x000118b9, 0x000118d9, - 0x000010b8, 0x00002d18, 0x000013b3, 0x0000ab83, - 0x000024cd, 0x000024e7, 0x00002c84, 0x00002c85, - 0x000001f8, 0x000001f9, 0x000104ce, 0x000104f6, - 0x00001f3e, 0x00001f36, 0x0000024a, 0x0000024b, - 0x00001fe8, 0x00001fe0, 0x00001fc8, 0x00001f72, - 0x0000a782, 0x0000a783, 0x000013bf, 0x0000ab8f, - 0x000024c0, 0x000024da, 0x0000047c, 0x0000047d, - 0x00002c92, 0x00002c93, 0x00010c99, 0x00010cd9, - 0x00001e66, 0x00001e67, 0x00002c2d, 0x00002c5d, - 0x00010402, 0x0001042a, 0x000001f6, 0x00000195, - 0x000010c2, 0x00002d22, 0x00010ca6, 0x00010ce6, - 0x0001e913, 0x0001e935, 0x00002cae, 0x00002caf, - 0x000118aa, 0x000118ca, 0x00001cbe, 0x000010fe, - 0x0000004a, 0x0000006a, 0x0001040d, 0x00010435, - 0x000004ae, 0x000004af, 0x000000d4, 0x000000f4, - 0x00000522, 0x00000523, 0x0000a65a, 0x0000a65b, - 0x00001e0c, 0x00001e0d, 0x00000228, 0x00000229, - 0x00010c8c, 0x00010ccc, 0x00001feb, 0x00001f7b, - 0x0000a79c, 0x0000a79d, 0x0001e903, 0x0001e925, - 0x00002ca0, 0x00002ca1, 0x0000054b, 0x0000057b, - 0x000024bd, 0x000024d7, 0x000004d0, 0x000004d1, - 0x0000216c, 0x0000217c, 0x00000164, 0x00000165, - 0x00000468, 0x00000469, 0x0000a682, 0x0000a683, - 0x0000a7c5, 0x00000282, 0x0000a72c, 0x0000a72d, - 0x000013a1, 0x0000ab71, 0x000004bc, 0x000004bd, - 0x00000393, 0x000003b3, 0x00002165, 0x00002175, - 0x00002cd2, 0x00002cd3, 0x00016e49, 0x00016e69, - 0x00002c23, 0x00002c53, 0x000118b4, 0x000118d4, - 0x00010d52, 0x00010d72, 0x00000174, 0x00000175, - 0x00016e4a, 0x00016e6a, 0x000001a6, 0x00000280, - 0x00000388, 0x000003ad, 0x000010a5, 0x00002d05, - 0x000000cf, 0x000000ef, 0x00001ece, 0x00001ecf, - 0x00001faa, 0x00001fa2, 0x00000162, 0x00000163, - 0x00002c67, 0x00002c68, 0x00000409, 0x00000459, - 0x0000041c, 0x0000043c, 0x000001c7, 0x000001c9, - 0x00000520, 0x00000521, 0x00001e72, 0x00001e73, - 0x00000549, 0x00000579, 0x00001ed6, 0x00001ed7, - 0x00002ce2, 0x00002ce3, 0x00000244, 0x00000289, - 0x0000a78b, 0x0000a78c, 0x00000506, 0x00000507, - 0x000003a1, 0x000003c1, 0x000118bf, 0x000118df, - 0x000004fc, 0x000004fd, 0x0000ff35, 0x0000ff55, - 0x0001040b, 0x00010433, 0x000118a9, 0x000118c9, - 0x00000552, 0x00000582, 0x00001e54, 0x00001e55, - 0x00002c15, 0x00002c45, 0x00001ed2, 0x00001ed3, - 0x00001e80, 0x00001e81, 0x0000a650, 0x0000a651, - 0x00001f9c, 0x00001f94, 0x00001cbf, 0x000010ff, - 0x000013a6, 0x0000ab76, 0x00001faf, 0x00001fa7, - 0x0000ff39, 0x0000ff59, 0x00001e58, 0x00001e59, - 0x00000494, 0x00000495, 0x00000136, 0x00000137, - 0x00001ca3, 0x000010e3, 0x000104c1, 0x000104e9, - 0x00001e62, 0x00001e63, 0x00001c9f, 0x000010df, - 0x0000a7b1, 0x00000287, 0x0000a75c, 0x0000a75d, - 0x00001fca, 0x00001f74, 0x0000a65c, 0x0000a65d, - 0x00002c75, 0x00002c76, 0x0000039e, 0x000003be, - 0x00001c9c, 0x000010dc, 0x0000a7c4, 0x0000a794, - 0x00002c64, 0x0000027d, 0x00002c2b, 0x00002c5b, - 0x00000130, 0x02000142, 0x00001e12, 0x00001e13, - 0x000001fc, 0x000001fd, 0x00010d54, 0x00010d74, - 0x0000a76e, 0x0000a76f, 0x00000414, 0x00000434, - 0x00001fe9, 0x00001fe1, 0x00002ce0, 0x00002ce1, - 0x00010414, 0x0001043c, 0x000118b2, 0x000118d2, - 0x000004d8, 0x000004d9, 0x000004a2, 0x000004a3, - 0x000000c2, 0x000000e2, 0x0001041e, 0x00010446, - 0x00001e30, 0x00001e31, 0x00010d5f, 0x00010d7f, - 0x0000022a, 0x0000022b, 0x00010572, 0x00010599, - 0x0000020c, 0x0000020d, 0x0000a7ae, 0x0000026a, - 0x0001057c, 0x000105a3, 0x00002c9e, 0x00002c9f, - 0x00001e1e, 0x00001e1f, 0x00001f2b, 0x00001f23, - 0x0000018f, 0x00000259, 0x0000216a, 0x0000217a, - 0x00001eac, 0x00001ead, 0x000104d3, 0x000104fb, - 0x0000a694, 0x0000a695, 0x00000190, 0x0000025b, - 0x00001f0c, 0x00001f04, 0x00000212, 0x00000213, - 0x00001f8c, 0x00001f84, 0x0000a7d6, 0x0000a7d7, - 0x00001cb9, 0x000010f9, 0x000024bc, 0x000024d6, - 0x00001c97, 0x000010d7, 0x000010c0, 0x00002d20, - 0x00001f2f, 0x00001f27, 0x00001f5d, 0x00001f55, - 0x00010425, 0x0001044d, 0x00010c81, 0x00010cc1, - 0x000104cf, 0x000104f7, 0x00010587, 0x000105ae, - 0x0001040c, 0x00010434, 0x0000a760, 0x0000a761, - 0x000013c2, 0x0000ab92, 0x00001eae, 0x00001eaf, - 0x000004ba, 0x000004bb, 0x0001e914, 0x0001e936, - 0x0000ff26, 0x0000ff46, 0x00000411, 0x00000431, - 0x000003ff, 0x0000037d, 0x0000051e, 0x0000051f, - 0x0000016c, 0x0000016d, 0x000118a2, 0x000118c2, - 0x000010ab, 0x00002d0b, 0x00010c85, 0x00010cc5, - 0x00001f39, 0x00001f31, 0x0000a779, 0x0000a77a, - 0x0001e915, 0x0001e937, 0x00002cc6, 0x00002cc7, - 0x00001cb1, 0x000010f1, 0x000003e6, 0x000003e7, - 0x0000004c, 0x0000006c, 0x00010417, 0x0001043f, - 0x000004de, 0x000004df, 0x000104bf, 0x000104e7, - 0x00001e70, 0x00001e71, 0x0000a64e, 0x0000a64f, - 0x0000a642, 0x0000a643, 0x000013f4, 0x000013fc, - 0x000010ae, 0x00002d0e, 0x00001e04, 0x00001e05, - 0x0000a796, 0x0000a797, 0x00002ca6, 0x00002ca7, - 0x00002cb6, 0x00002cb7, 0x00000533, 0x00000563, - 0x00000512, 0x00000513, 0x00002c6f, 0x00000250, - 0x00002168, 0x00002178, 0x0000a7aa, 0x00000266, - 0x00000462, 0x00000463, 0x000001f4, 0x000001f5, - 0x00002167, 0x00002177, 0x00001f4a, 0x00001f42, - 0x0000a758, 0x0000a759, 0x00002ca4, 0x00002ca5, - 0x0001e916, 0x0001e938, 0x00002c2f, 0x00002c5f, - 0x000024ba, 0x000024d4, 0x00001cae, 0x000010ee, - 0x0000004f, 0x0000006f, 0x00001ca9, 0x000010e9, - 0x0000a656, 0x0000a657, 0x00000391, 0x000003b1, - 0x00000120, 0x00000121, 0x00000508, 0x00000509, - 0x000001ca, 0x000001cc, 0x00010418, 0x00010440, - 0x0000a748, 0x0000a749, 0x00001efc, 0x00001efd, - 0x00001eb8, 0x00001eb9, 0x00010ca4, 0x00010ce4, - 0x00000179, 0x0000017a, 0x00000056, 0x00000076, - 0x00000472, 0x00000473, 0x00010416, 0x0001043e, - 0x00010c9b, 0x00010cdb, 0x0001058e, 0x000105b5, - 0x00010d63, 0x00010d83, 0x00001ed4, 0x00001ed5, - 0x00001ef8, 0x00001ef9, 0x00001e7c, 0x00001e7d, - 0x00001f69, 0x00001f61, 0x0001e921, 0x0001e943, - 0x000003a8, 0x000003c8, 0x00001fbb, 0x00001f71, - 0x00001fda, 0x00001f76, 0x00000041, 0x00000061, - 0x0001040f, 0x00010437, 0x0000048e, 0x0000048f, - 0x00000059, 0x00000079, 0x00000528, 0x00000529, - 0x00010d64, 0x00010d84, 0x00001e3c, 0x00001e3d, - 0x00000419, 0x00000439, 0x00001f3b, 0x00001f33, - 0x000013f0, 0x000013f8, 0x0000a7f5, 0x0000a7f6, - 0x000013dc, 0x0000abac, 0x00002cba, 0x00002cbb, - 0x00000464, 0x00000465, 0x00000166, 0x00000167, - 0x00001ca6, 0x000010e6, 0x00010578, 0x0001059f, - 0x00001fd9, 0x00001fd1, 0x0000054c, 0x0000057c, - 0x00001e68, 0x00001e69, 0x0000a690, 0x0000a691, - 0x0000a7b8, 0x0000a7b9, 0x0000a73a, 0x0000a73b, - 0x00001fbc, 0x00001fb3, 0x00001c93, 0x000010d3, - 0x000004c0, 0x000004cf, 0x00001ca2, 0x000010e2, - 0x00001c96, 0x000010d6, 0x000010c4, 0x00002d24, - 0x000000da, 0x000000fa, 0x000004e6, 0x000004e7, - 0x00000397, 0x000003b7, 0x00000531, 0x00000561, - 0x00001e94, 0x00001e95, 0x000013c8, 0x0000ab98, - 0x0000018b, 0x0000018c, 0x0001e90d, 0x0001e92f, - 0x00002c70, 0x00000252, 0x000010a0, 0x00002d00, - 0x000010ad, 0x00002d0d, 0x00001ea8, 0x00001ea9, - 0x000001f1, 0x000001f3, 0x000010a2, 0x00002d02, - 0x000000c8, 0x000000e8, 0x0000053a, 0x0000056a, - 0x00001e36, 0x00001e37, 0x0000013d, 0x0000013e, - 0x0000021c, 0x0000021d, 0x0001058d, 0x000105b4, - 0x00002c12, 0x00002c42, 0x000013ab, 0x0000ab7b, - 0x00000370, 0x00000371, 0x00010592, 0x000105b9, - 0x00000545, 0x00000575, 0x0000a77b, 0x0000a77c, - 0x0000ff2b, 0x0000ff4b, 0x00001fac, 0x00001fa4, - 0x00001f19, 0x00001f11, 0x000104b7, 0x000104df, - 0x00001e46, 0x00001e47, 0x00010584, 0x000105ab, - 0x00000514, 0x00000515, 0x0000a73c, 0x0000a73d, - 0x00001fcc, 0x00001fc3, 0x00002c0e, 0x00002c3e, - 0x0001e91e, 0x0001e940, 0x00002cc8, 0x00002cc9, - 0x0000ff34, 0x0000ff54, 0x0000ff2a, 0x0000ff4a, - 0x000118ba, 0x000118da, 0x0000047a, 0x0000047b, - 0x00010423, 0x0001044b, 0x00000132, 0x00000133, - 0x000104cd, 0x000104f5, 0x000001fe, 0x000001ff, - 0x00000504, 0x00000505, 0x0000a756, 0x0000a757, - 0x00010ca0, 0x00010ce0, 0x0000a786, 0x0000a787, - 0x00001f5b, 0x00001f53, 0x000013ea, 0x0000abba, - 0x00002cf2, 0x00002cf3, 0x0000047e, 0x0000047f, - 0x00000408, 0x00000458, 0x00016e46, 0x00016e66, - 0x00000176, 0x00000177, 0x0000041a, 0x0000043a, - 0x00002c1b, 0x00002c4b, 0x000001e6, 0x000001e7, - 0x00001e0e, 0x00001e0f, 0x000024c3, 0x000024dd, - 0x0000a764, 0x0000a765, 0x000004c7, 0x000004c8, - 0x00001cb8, 0x000010f8, 0x000013d5, 0x0000aba5, - 0x0000038a, 0x000003af, 0x00000417, 0x00000437, - 0x00001ebe, 0x00001ebf, 0x00000548, 0x00000578, - 0x00010ca9, 0x00010ce9, 0x00001ee6, 0x00001ee7, - 0x0000a644, 0x0000a645, 0x000003a0, 0x000003c0, - 0x0001057f, 0x000105a6, 0x00002cc2, 0x00002cc3, - 0x000013b0, 0x0000ab80, 0x000013be, 0x0000ab8e, - 0x00002cbe, 0x00002cbf, 0x00000426, 0x00000446, - 0x0000054d, 0x0000057d, 0x000013a3, 0x0000ab73, - 0x0001041d, 0x00010445, 0x000000c9, 0x000000e9, - 0x00010c89, 0x00010cc9, 0x00000401, 0x00000451, - 0x00010571, 0x00010598, 0x00001f49, 0x00001f41, - 0x0000a732, 0x0000a733, 0x00001fa8, 0x00001fa0, - 0x00001e7a, 0x00001e7b, 0x0000012a, 0x0000012b, - 0x000024be, 0x000024d8, 0x00001e18, 0x00001e19, - 0x000004f8, 0x000004f9, 0x0000010a, 0x0000010b, - 0x000004b2, 0x000004b3, 0x00002163, 0x00002173, - 0x000010a1, 0x00002d01, 0x000104c3, 0x000104eb, - 0x000001ec, 0x000001ed, 0x0000020e, 0x0000020f, - 0x0000a746, 0x0000a747, 0x00000403, 0x00000453, - 0x00000241, 0x00000242, 0x00001e16, 0x00001e17, - 0x000003ea, 0x000003eb, 0x00000055, 0x00000075, - 0x00000476, 0x00000477, 0x000013ef, 0x0000abbf, - 0x000010c7, 0x00002d27, 0x00000154, 0x00000155, - 0x00000145, 0x00000146, 0x000001a7, 0x000001a8, - 0x00000126, 0x00000127, 0x000004be, 0x000004bf, - 0x0000a7a0, 0x0000a7a1, 0x000010a6, 0x00002d06, - 0x000024bb, 0x000024d5, 0x00001eca, 0x00001ecb, - 0x000010b7, 0x00002d17, 0x00001c99, 0x000010d9, - 0x000118af, 0x000118cf, 0x0000049e, 0x0000049f, - 0x000000d6, 0x000000f6, 0x00010585, 0x000105ac, - 0x00010d61, 0x00010d81, 0x00001e84, 0x00001e85, - 0x00001ef0, 0x00001ef1, 0x0000ff21, 0x0000ff41, - 0x00001ca7, 0x000010e7, 0x0000a7a4, 0x0000a7a5, - 0x000013bc, 0x0000ab8c, 0x0000ff32, 0x0000ff52, - 0x00002c1a, 0x00002c4a, 0x000013d9, 0x0000aba9, - 0x000004d2, 0x000004d3, 0x00002c6d, 0x00000251, - 0x00010403, 0x0001042b, 0x00000550, 0x00000580, - 0x0000a664, 0x0000a665, 0x00001f08, 0x00001f00, - 0x0000a740, 0x0000a741, 0x00000466, 0x00000467, - 0x00001f98, 0x00001f90, 0x00002c04, 0x00002c34, - 0x00002cca, 0x00002ccb, 0x000013dd, 0x0000abad, - 0x0000042e, 0x0000044e, 0x00000424, 0x00000444, - 0x0000039a, 0x000003ba, 0x000104c8, 0x000104f0, - 0x00000152, 0x00000153, 0x00010406, 0x0001042e, - 0x00001e90, 0x00001e91, 0x0000a692, 0x0000a693, - 0x00001f4b, 0x00001f43, 0x0000a74c, 0x0000a74d, - 0x00002c02, 0x00002c32, 0x00002c62, 0x0000026b, - 0x000003fa, 0x000003fb, 0x00000245, 0x0000028c, - 0x00001c91, 0x000010d1, 0x00000474, 0x00000475, - 0x00010cb0, 0x00010cf0, 0x00010413, 0x0001043b, - 0x000001f7, 0x000001bf, 0x00010420, 0x00010448, - 0x00001eda, 0x00001edb, 0x000104ca, 0x000104f2, - 0x000013cb, 0x0000ab9b, 0x0000a790, 0x0000a791, - 0x00016e5c, 0x00016e7c, 0x00002c98, 0x00002c99, - 0x00010c94, 0x00010cd4, 0x000003a7, 0x000003c7, - 0x0000004b, 0x0000006b, 0x000118a1, 0x000118c1, - 0x00001f6b, 0x00001f63, 0x00010cb2, 0x00010cf2, - 0x00001e44, 0x00001e45, 0x000104c0, 0x000104e8, - 0x00001eee, 0x00001eef, 0x0000023a, 0x00002c65, - 0x000104c6, 0x000104ee, 0x00002c26, 0x00002c56, - 0x0000040e, 0x0000045e, 0x0000038e, 0x000003cd, - 0x00001ca0, 0x000010e0, 0x0000ff2f, 0x0000ff4f, - 0x00001e14, 0x00001e15, 0x000004e2, 0x000004e3, - 0x0000040a, 0x0000045a, 0x0000011c, 0x0000011d, - 0x0000053e, 0x0000056e, 0x00001e5e, 0x00001e5f, - 0x00001f3a, 0x00001f32, 0x00016e50, 0x00016e70, - 0x0000a7ac, 0x00000261, 0x000104c4, 0x000104ec, - 0x0000a65e, 0x0000a65f, 0x0000216d, 0x0000217d, - 0x000024cc, 0x000024e6, 0x00016e54, 0x00016e74, - 0x000000c6, 0x000000e6, 0x00000518, 0x00000519, - 0x00001fad, 0x00001fa5, 0x00000524, 0x00000525, - 0x0000053c, 0x0000056c, 0x00001ea2, 0x00001ea3, - 0x00002c88, 0x00002c89, 0x00001f4c, 0x00001f44, - 0x0000a76a, 0x0000a76b, 0x00002c7e, 0x0000023f, - 0x000000d9, 0x000000f9, 0x00001ca8, 0x000010e8, - 0x00016e44, 0x00016e64, 0x000004a6, 0x000004a7, - 0x000118a3, 0x000118c3, 0x00010cad, 0x00010ced, - 0x0000052c, 0x0000052d, 0x0000015e, 0x0000015f, - 0x0000a7bc, 0x0000a7bd, 0x00002c09, 0x00002c39, - 0x000004dc, 0x000004dd, 0x0000a7a6, 0x0000a7a7, - 0x000013b4, 0x0000ab84, 0x000001db, 0x000001dc, - 0x00016e4f, 0x00016e6f, 0x00000406, 0x00000456, - 0x00000147, 0x00000148, 0x00000058, 0x00000078, - 0x00002c19, 0x00002c49, 0x00000102, 0x00000103, - 0x0001040a, 0x00010432, 0x000001ac, 0x000001ad, - 0x000001a4, 0x000001a5, 0x0000017b, 0x0000017c, - 0x0000a73e, 0x0000a73f, 0x000013bb, 0x0000ab8b, - 0x00002c2c, 0x00002c5c, 0x000013c0, 0x0000ab90, - 0x00001c95, 0x000010d5, 0x00001c90, 0x000010d0, - 0x00016e40, 0x00016e60, 0x000010b2, 0x00002d12, - 0x000118b5, 0x000118d5, 0x0000a68c, 0x0000a68d, - 0x000004fe, 0x000004ff, 0x00001e8e, 0x00001e8f, - 0x0000053b, 0x0000056b, 0x00001f38, 0x00001f30, - 0x00001f3f, 0x00001f37, 0x00001eb4, 0x00001eb5, - 0x000003a4, 0x000003c4, 0x0001e90e, 0x0001e930, - 0x0000ff23, 0x0000ff43, 0x000024c4, 0x000024de, - 0x000004b4, 0x000004b5, 0x000000d2, 0x000000f2, - 0x000010c5, 0x00002d25, 0x00000460, 0x00000461, - 0x0000015a, 0x0000015b, 0x00001ea6, 0x00001ea7, - 0x00000118, 0x00000119, 0x00010591, 0x000105b8, - 0x0000023b, 0x0000023c, 0x0000a77e, 0x0000a77f, - 0x0001e912, 0x0001e934, 0x000024cf, 0x000024e9, - 0x000003e8, 0x000003e9, 0x00000044, 0x00000064, - 0x000004ac, 0x000004ad, 0x000024b7, 0x000024d1, - 0x000000cc, 0x000000ec, 0x0000a7ab, 0x0000025c, - 0x0000019f, 0x00000275, 0x000010c3, 0x00002d23, - 0x0000a7b4, 0x0000a7b5, 0x00001ffa, 0x00001f7c, - 0x000013a5, 0x0000ab75, 0x0000041e, 0x0000043e, - 0x000013ba, 0x0000ab8a, 0x00016e51, 0x00016e71, - 0x00016e43, 0x00016e63, 0x00001f8b, 0x00001f83, - 0x00002183, 0x00002184, 0x000104bd, 0x000104e5, - 0x00000191, 0x00000192, 0x00000539, 0x00000569, - 0x00001e64, 0x00001e65, 0x00016e52, 0x00016e72, - 0x00000143, 0x00000144, 0x0000a738, 0x0000a739, - 0x00001fb8, 0x00001fb0, 0x00001f2c, 0x00001f24, - 0x000013de, 0x0000abae, 0x00010c84, 0x00010cc4, - 0x00001f9f, 0x00001f97, 0x00001f0f, 0x00001f07, - 0x00010c91, 0x00010cd1, 0x00001e28, 0x00001e29, - 0x0000013b, 0x0000013c, 0x0000a64a, 0x0000a64b, - 0x000001bc, 0x000001bd, 0x000013d2, 0x0000aba2, - 0x0000a762, 0x0000a763, 0x000013b2, 0x0000ab82, - 0x00002c0a, 0x00002c3a, 0x00001f1b, 0x00001f13, - 0x000001af, 0x000001b0, 0x00001ca1, 0x000010e1, - 0x0001e918, 0x0001e93a, 0x0000216f, 0x0000217f, - 0x000000c4, 0x000000e4, 0x00000538, 0x00000568, - 0x00000172, 0x00000173, 0x00010d57, 0x00010d77, - 0x00000218, 0x00000219, 0x000118ae, 0x000118ce, - 0x00010581, 0x000105a8, 0x00001f2e, 0x00001f26, - 0x000001b7, 0x00000292, 0x00000187, 0x00000188, - 0x0000040b, 0x0000045b, 0x000010be, 0x00002d1e, - 0x00002162, 0x00002172, 0x000118ad, 0x000118cd, - 0x0001e907, 0x0001e929, 0x000104b1, 0x000104d9, - 0x00001e26, 0x00001e27, 0x00010575, 0x0001059c, - 0x00016e5e, 0x00016e7e, 0x00001ef4, 0x00001ef5, - 0x00001caa, 0x000010ea, 0x00002c08, 0x00002c38, - 0x00016e5a, 0x00016e7a, 0x000003cf, 0x000003d7, - 0x00016e53, 0x00016e73, 0x000013c9, 0x0000ab99, - 0x00001e8a, 0x00001e8b, 0x0000a7cc, 0x0000a7cd, - 0x00000042, 0x00000062, 0x00002c03, 0x00002c33, - 0x000104c5, 0x000104ed, 0x00001e6e, 0x00001e6f, - 0x00001f1a, 0x00001f12, 0x00001f18, 0x00001f10, - 0x00010d62, 0x00010d82, 0x00001fae, 0x00001fa6, - 0x00001cb4, 0x000010f4, 0x000013e4, 0x0000abb4, - 0x0000ff33, 0x0000ff53, 0x00000537, 0x00000567, - 0x0000017d, 0x0000017e, 0x00010426, 0x0001044e, - 0x000024c5, 0x000024df, 0x00000168, 0x00000169, - 0x00001e9e, 0x000000df, 0x000001e0, 0x000001e1, - 0x0001e908, 0x0001e92a, 0x00002c27, 0x00002c57, - 0x0001e911, 0x0001e933, 0x00000108, 0x00000109, - 0x000001d5, 0x000001d6, 0x00002c00, 0x00002c30, - 0x000013c7, 0x0000ab97, 0x00000196, 0x00000269, - 0x000004a0, 0x000004a1, 0x000000ce, 0x000000ee, - 0x00010cb1, 0x00010cf1, 0x00000178, 0x000000ff, - 0x00010d53, 0x00010d73, 0x00000222, 0x00000223, - 0x0000010c, 0x0000010d, 0x00010404, 0x0001042c, - 0x0000a792, 0x0000a793, 0x00000376, 0x00000377, - 0x00002c1f, 0x00002c4f, 0x00000420, 0x00000440, - 0x000118b8, 0x000118d8, 0x00010d56, 0x00010d76, - 0x000004a4, 0x000004a5, 0x00001ffc, 0x00001ff3, - 0x000104c7, 0x000104ef, 0x0000a69a, 0x0000a69b, - 0x00010c87, 0x00010cc7, 0x00001ebc, 0x00001ebd, - 0x0000012c, 0x0000012d, 0x000013b7, 0x0000ab87, - 0x0000a7dc, 0x0000019b, 0x000013ca, 0x0000ab9a, - 0x00010c83, 0x00010cc3, 0x0000212b, 0x000000e5, - 0x0000216b, 0x0000217b, 0x00000405, 0x00000455, - 0x00002c25, 0x00002c55, 0x000001d9, 0x000001da, - 0x00000160, 0x00000161, 0x00001f28, 0x00001f20, - 0x00000186, 0x00000254, 0x00000543, 0x00000573, - 0x0000024e, 0x0000024f, 0x00001f89, 0x00001f81, - 0x00001c9d, 0x000010dd, 0x000010ac, 0x00002d0c, - 0x00002c63, 0x00001d7d, 0x00000052, 0x00000072, - 0x000118b7, 0x000118d7, 0x0000ff2c, 0x0000ff4c, - 0x00010c97, 0x00010cd7, 0x000013db, 0x0000abab, - 0x00000156, 0x00000157, 0x000013d3, 0x0000aba3, - 0x0000a660, 0x0000a661, 0x000013f2, 0x000013fa, - 0x000003f9, 0x000003f2, 0x00001f6c, 0x00001f64, - 0x00002c96, 0x00002c97, 0x00001ec2, 0x00001ec3, - 0x000003fe, 0x0000037c, 0x00001f09, 0x00001f01, - 0x0001041b, 0x00010443, 0x000000cb, 0x000000eb, - 0x000104b5, 0x000104dd, 0x00002c1d, 0x00002c4d, - 0x00001e3a, 0x00001e3b, 0x00002ced, 0x00002cee, - 0x0000a666, 0x0000a667, 0x0000a7d0, 0x0000a7d1, - 0x00001f8e, 0x00001f86, 0x000013d0, 0x0000aba0, - 0x00016e4e, 0x00016e6e, 0x00002cb2, 0x00002cb3, - 0x0000ff2d, 0x0000ff4d, 0x000010a7, 0x00002d07, - 0x00002160, 0x00002170, 0x00002164, 0x00002174, - 0x0000011a, 0x0000011b, 0x000104d1, 0x000104f9, - 0x0000a696, 0x0000a697, 0x0000041b, 0x0000043b, - 0x00001f3d, 0x00001f35, 0x00000226, 0x00000227, - 0x00001e06, 0x00001e07, 0x00002c2a, 0x00002c5a, - 0x000013a4, 0x0000ab74, 0x00002cd4, 0x00002cd5, - 0x00001c92, 0x000010d2, 0x00000429, 0x00000449, - 0x000000dc, 0x000000fc, 0x00010410, 0x00010438, - 0x000010bf, 0x00002d1f, 0x000104ba, 0x000104e2, - 0x000001ee, 0x000001ef, 0x00001cb7, 0x000010f7, - 0x00001eba, 0x00001ebb, 0x00010590, 0x000105b7, - 0x00001e10, 0x00001e11, 0x000003ee, 0x000003ef, - 0x000118b6, 0x000118d6, 0x000003de, 0x000003df, - 0x00000045, 0x00000065, 0x000013ad, 0x0000ab7d, - 0x000010b3, 0x00002d13, 0x00000532, 0x00000562, - 0x00001ec6, 0x00001ec7, 0x00000158, 0x00000159, - 0x00000216, 0x00000217, 0x00000202, 0x00000203, - 0x00010c82, 0x00010cc2, 0x00001e0a, 0x00001e0b, - 0x0001e919, 0x0001e93b, 0x000104c2, 0x000104ea, - 0x00002c0b, 0x00002c3b, 0x00000400, 0x00000450, - 0x00000046, 0x00000066, 0x000004aa, 0x000004ab, - 0x00000197, 0x00000268, 0x00000554, 0x00000584, - 0x00001e2e, 0x00001e2f, 0x00001e2a, 0x00001e2b, - 0x00000425, 0x00000445, 0x00001efe, 0x00001eff, - 0x00000421, 0x00000441, 0x00002c06, 0x00002c36, - 0x000013d6, 0x0000aba6, 0x000013a0, 0x0000ab70, - 0x00016e4b, 0x00016e6b, 0x000004b6, 0x000004b7, - 0x00010580, 0x000105a7, 0x0000010e, 0x0000010f, - 0x000013e5, 0x0000abb5, 0x00002c13, 0x00002c43, - 0x000010b9, 0x00002d19, 0x0000a68e, 0x0000a68f, - 0x00001f5f, 0x00001f57, 0x000000c1, 0x000000e1, - 0x000004e4, 0x000004e5, 0x0000037f, 0x000003f3, - 0x00002c14, 0x00002c44, 0x000000c3, 0x000000e3, - 0x00002cd6, 0x00002cd7, 0x0000046e, 0x0000046f, - 0x00002c8c, 0x00002c8d, 0x00001ca4, 0x000010e4, - 0x00000500, 0x00000501, 0x0000a780, 0x0000a781, - 0x00010c98, 0x00010cd8, 0x00000181, 0x00000253, - 0x00010c86, 0x00010cc6, 0x00001e52, 0x00001e53, - 0x0000a766, 0x0000a767, 0x0001041a, 0x00010442, - 0x0000ff29, 0x0000ff49, 0x00000141, 0x00000142, - 0x000003da, 0x000003db, 0x0000004d, 0x0000006d, - 0x000010aa, 0x00002d0a, 0x000001cf, 0x000001d0, - 0x0000052e, 0x0000052f, 0x00001e34, 0x00001e35, - 0x0000a640, 0x0000a641, 0x0000a72a, 0x0000a72b, - 0x00000204, 0x00000205, 0x00002c10, 0x00002c40, - 0x00010400, 0x00010428, 0x000013d1, 0x0000aba1, - 0x00002c9c, 0x00002c9d, 0x0000ff27, 0x0000ff47, - 0x00000402, 0x00000452, 0x00016e5d, 0x00016e7d, - 0x000118a7, 0x000118c7, 0x00000407, 0x00000457, - 0x00000556, 0x00000586, 0x00001e4a, 0x00001e4b, - 0x0000a648, 0x0000a649, 0x00001e24, 0x00001e25, - 0x000013eb, 0x0000abbb, 0x000001c5, 0x000001c6, - 0x00001f8a, 0x00001f82, 0x0001e91f, 0x0001e941, - 0x00002cb4, 0x00002cb5, 0x000003fd, 0x0000037b, - 0x000013c1, 0x0000ab91, 0x00001cb0, 0x000010f0, - 0x00010570, 0x00010597, 0x00001cb6, 0x000010f6, - 0x000000d3, 0x000000f3, 0x0000a66a, 0x0000a66b, - 0x00000184, 0x00000185, 0x000013b9, 0x0000ab89, - 0x00000541, 0x00000571, 0x00002c05, 0x00002c35, - 0x00001f4d, 0x00001f45, 0x0000a7c9, 0x0000a7ca, - 0x000003d8, 0x000003d9, 0x000024c6, 0x000024e0, - 0x0000042c, 0x0000044c, 0x00000542, 0x00000572, - 0x0000051c, 0x0000051d, 0x00000546, 0x00000576, - 0x0001041c, 0x00010444, 0x000004fa, 0x000004fb, - 0x000001ea, 0x000001eb, 0x000104b8, 0x000104e0, - 0x00001e86, 0x00001e87, 0x0001e909, 0x0001e92b, - 0x0001e90f, 0x0001e931, 0x000024c2, 0x000024dc, - 0x00016e59, 0x00016e79, 0x00010d60, 0x00010d80, - 0x00010411, 0x00010439, 0x000004c9, 0x000004ca, - 0x000104bb, 0x000104e3, 0x00000526, 0x00000527, - 0x00010d65, 0x00010d85, 0x00001ef2, 0x00001ef3, - 0x0000a7cb, 0x00000264, 0x0000a7c6, 0x00001d8e, - 0x00002c2e, 0x00002c5e, 0x000013a8, 0x0000ab78, - 0x00002ca2, 0x00002ca3, 0x00002cb0, 0x00002cb1, - 0x0001058a, 0x000105b1, 0x000010cd, 0x00002d2d, - 0x000104d2, 0x000104fa, 0x00001cab, 0x000010eb, - 0x0000039f, 0x000003bf, 0x00001e74, 0x00001e75, - 0x00001ef6, 0x00001ef7, 0x00010424, 0x0001044c, - 0x00001f0e, 0x00001f06, 0x0000a734, 0x0000a735, - 0x0000039c, 0x000003bc, 0x000003a6, 0x000003c6, - 0x000013da, 0x0000abaa, 0x00002c18, 0x00002c48, - 0x00001c94, 0x000010d4, 0x000024c7, 0x000024e1, - 0x00016e48, 0x00016e68, 0x0000a75a, 0x0000a75b, - 0x000004ea, 0x000004eb, 0x00000134, 0x00000135, - 0x00000182, 0x00000183, 0x000001de, 0x000001df, - 0x00001f3c, 0x00001f34, 0x00000547, 0x00000577, - 0x00002c94, 0x00002c95, 0x000013f1, 0x000013f9, - 0x00000243, 0x00000180, 0x00001c9e, 0x000010de, - 0x00016e5b, 0x00016e7b, 0x000118be, 0x000118de, - 0x00002c6b, 0x00002c6c, 0x00010c93, 0x00010cd3, - 0x0000016e, 0x0000016f, 0x0000a7b0, 0x0000029e, - 0x00001f9b, 0x00001f93, 0x0000a7b6, 0x0000a7b7, - 0x000003aa, 0x000003ca, 0x000003a3, 0x000003c3, - 0x0001e910, 0x0001e932, 0x00002caa, 0x00002cab, - 0x0000ff37, 0x0000ff57, 0x000001b2, 0x0000028b, - 0x00000048, 0x00000068, 0x00010407, 0x0001042f, - 0x000004d6, 0x000004d7, 0x000001b8, 0x000001b9, - 0x0000019c, 0x0000026f, 0x00001e02, 0x00001e03, - 0x00000139, 0x0000013a, 0x00001eec, 0x00001eed, - 0x00010589, 0x000105b0, 0x00001f9e, 0x00001f96, - 0x0001e901, 0x0001e923, 0x000013e0, 0x0000abb0, - 0x0000ff3a, 0x0000ff5a, 0x00002c11, 0x00002c41, - 0x00000054, 0x00000074, 0x00010419, 0x00010441, - 0x00000124, 0x00000125, 0x00002ceb, 0x00002cec, - 0x00010c8a, 0x00010cca, 0x0000018e, 0x000001dd, - 0x00010ca8, 0x00010ce8, 0x0000042f, 0x0000044f, - 0x0000ff2e, 0x0000ff4e, 0x000118ac, 0x000118cc, - 0x0000a74e, 0x0000a74f, 0x0000038c, 0x000003cc, - 0x00002cce, 0x00002ccf, 0x00016e57, 0x00016e77, - 0x00000540, 0x00000570, 0x0000052a, 0x0000052b, - 0x00001eb2, 0x00001eb3, 0x0000014c, 0x0000014d, - 0x00001e08, 0x00001e09, 0x0000039b, 0x000003bb, - 0x00000553, 0x00000583, 0x00001fab, 0x00001fa3, - 0x000104be, 0x000104e6, 0x00001ff8, 0x00001f78, - 0x000003ab, 0x000003cb, 0x000004c1, 0x000004c2, - 0x00010408, 0x00010430, 0x000004b0, 0x000004b1, - 0x00002cc4, 0x00002cc5, 0x00010ca3, 0x00010ce3, - 0x000013c5, 0x0000ab95, 0x00001e6a, 0x00001e6b, - 0x00010d51, 0x00010d71, 0x00001edc, 0x00001edd, - 0x0001e90a, 0x0001e92c, 0x00002c22, 0x00002c52, - 0x0000a798, 0x0000a799, 0x00002cb8, 0x00002cb9, - 0x00000410, 0x00000430, 0x00000398, 0x000003b8, - 0x0000050c, 0x0000050d, 0x0000005a, 0x0000007a, + 0x00000050, 0x00000070, 0x000004a8, 0x000004a9, + 0x000000c8, 0x000000e8, 0x000001c4, 0x000001c6, + 0x00002c03, 0x00002c33, 0x00000537, 0x00000567, + 0x00001e0e, 0x00001e0f, 0x00010420, 0x00010448, + 0x0000ff3a, 0x0000ff5a, 0x00016e5c, 0x00016e7c, + 0x00001f38, 0x00001f30, 0x00010d5e, 0x00010d7e, + 0x00001e5c, 0x00001e5d, 0x00010416, 0x0001043e, + 0x000010c1, 0x00002d21, 0x0000a666, 0x0000a667, + 0x0001e920, 0x0001e942, 0x00000492, 0x00000493, + 0x00001f8a, 0x00001f82, 0x000004da, 0x000004db, + 0x000000ca, 0x000000ea, 0x0000042d, 0x0000044d, + 0x00001e4c, 0x00001e4d, 0x00002cd0, 0x00002cd1, + 0x0000a72e, 0x0000a72f, 0x000118ba, 0x000118da, + 0x00000549, 0x00000579, 0x000004e0, 0x000004e1, + 0x00010c88, 0x00010cc8, 0x0000039f, 0x000003bf, + 0x00001caa, 0x000010ea, 0x00002c96, 0x00002c97, + 0x000013f0, 0x000013f8, 0x00000397, 0x000003b7, + 0x00001e0a, 0x00001e0b, 0x000001fe, 0x000001ff, + 0x00001e48, 0x00001e49, 0x000104cb, 0x000104f3, + 0x00001e86, 0x00001e87, 0x00010caf, 0x00010cef, + 0x00001f09, 0x00001f01, 0x00016eae, 0x00016ec9, + 0x0000019d, 0x00000272, 0x00002c2e, 0x00002c5e, + 0x0000a7bc, 0x0000a7bd, 0x000001d5, 0x000001d6, + 0x000000cf, 0x000000ef, 0x0000a644, 0x0000a645, + 0x0000a7b4, 0x0000a7b5, 0x000104c1, 0x000104e9, + 0x00001f3f, 0x00001f37, 0x000013a9, 0x0000ab79, + 0x0000a77d, 0x00001d79, 0x00001fc9, 0x00001f73, + 0x0000054b, 0x0000057b, 0x0000a65e, 0x0000a65f, + 0x000013cd, 0x0000ab9d, 0x00000370, 0x00000371, + 0x0000053c, 0x0000056c, 0x00010c85, 0x00010cc5, + 0x0000a726, 0x0000a727, 0x000001e0, 0x000001e1, + 0x00010414, 0x0001043c, 0x00000179, 0x0000017a, + 0x00002c16, 0x00002c46, 0x0000017d, 0x0000017e, + 0x000104bb, 0x000104e3, 0x00000222, 0x00000223, + 0x00016e55, 0x00016e75, 0x0000014c, 0x0000014d, + 0x00001fa9, 0x00001fa1, 0x000000cc, 0x000000ec, + 0x000013cc, 0x0000ab9c, 0x00001cad, 0x000010ed, + 0x0000049a, 0x0000049b, 0x0001057d, 0x000105a4, + 0x000118a0, 0x000118c0, 0x000000da, 0x000000fa, + 0x00000241, 0x00000242, 0x0000018b, 0x0000018c, + 0x000013a6, 0x0000ab76, 0x000003dc, 0x000003dd, + 0x00001cac, 0x000010ec, 0x000000c2, 0x000000e2, + 0x00002c10, 0x00002c40, 0x000004fe, 0x000004ff, + 0x00010592, 0x000105b9, 0x00000508, 0x00000509, + 0x00001e68, 0x00001e69, 0x00016e52, 0x00016e72, + 0x00016ea8, 0x00016ec3, 0x000004ec, 0x000004ed, + 0x00016eab, 0x00016ec6, 0x000001e2, 0x000001e3, + 0x00000543, 0x00000573, 0x00001fec, 0x00001fe5, + 0x00010584, 0x000105ab, 0x00016e59, 0x00016e79, + 0x00000534, 0x00000564, 0x000013e5, 0x0000abb5, + 0x00010d59, 0x00010d79, 0x00001ef2, 0x00001ef3, + 0x00016e5f, 0x00016e7f, 0x00001ebe, 0x00001ebf, + 0x000024ca, 0x000024e4, 0x0000ff2a, 0x0000ff4a, + 0x00010419, 0x00010441, 0x00000478, 0x00000479, + 0x0000a652, 0x0000a653, 0x00001ef6, 0x00001ef7, + 0x00010411, 0x00010439, 0x00001ffa, 0x00001f7c, + 0x000004d6, 0x000004d7, 0x00001fb8, 0x00001fb0, + 0x00000405, 0x00000455, 0x00000545, 0x00000575, + 0x000004d2, 0x000004d3, 0x0000216a, 0x0000217a, + 0x000003fe, 0x0000037c, 0x00001e3a, 0x00001e3b, + 0x00016eb8, 0x00016ed3, 0x00002c09, 0x00002c39, + 0x000118b5, 0x000118d5, 0x00001f1d, 0x00001f15, + 0x00010ca9, 0x00010ce9, 0x00001f8d, 0x00001f85, + 0x00000399, 0x000003b9, 0x00001e92, 0x00001e93, + 0x000004d8, 0x000004d9, 0x0000a766, 0x0000a767, + 0x00002cba, 0x00002cbb, 0x00000041, 0x00000061, + 0x00010d5a, 0x00010d7a, 0x0000a64e, 0x0000a64f, + 0x00000106, 0x00000107, 0x00001ec8, 0x00001ec9, + 0x00001cb8, 0x000010f8, 0x00016eb3, 0x00016ece, + 0x00000500, 0x00000501, 0x00001faa, 0x00001fa2, + 0x00016e49, 0x00016e69, 0x0000a7c6, 0x00001d8e, + 0x000001b5, 0x000001b6, 0x00001f08, 0x00001f00, + 0x000001f4, 0x000001f5, 0x00016eb1, 0x00016ecc, + 0x00002c6d, 0x00000251, 0x000104c7, 0x000104ef, + 0x00010c86, 0x00010cc6, 0x000010a9, 0x00002d09, + 0x00002cf2, 0x00002cf3, 0x00001ca3, 0x000010e3, + 0x0000a750, 0x0000a751, 0x0000a79c, 0x0000a79d, + 0x00001f3b, 0x00001f33, 0x00001c93, 0x000010d3, + 0x000001f2, 0x000001f3, 0x00002c94, 0x00002c95, + 0x00000126, 0x00000127, 0x00010574, 0x0001059b, + 0x00001edc, 0x00001edd, 0x00001f8f, 0x00001f87, + 0x00000174, 0x00000175, 0x00001e2a, 0x00001e2b, + 0x00002ca0, 0x00002ca1, 0x0000a748, 0x0000a749, + 0x00000498, 0x00000499, 0x00010572, 0x00010599, + 0x000001cd, 0x000001ce, 0x00001ec2, 0x00001ec3, + 0x0000015c, 0x0000015d, 0x00000496, 0x00000497, + 0x00000198, 0x00000199, 0x00001e8e, 0x00001e8f, + 0x000000de, 0x000000fe, 0x000104b7, 0x000104df, + 0x00016ea7, 0x00016ec2, 0x000010a1, 0x00002d01, + 0x000003a6, 0x000003c6, 0x000000d5, 0x000000f5, + 0x00000422, 0x00000442, 0x00001e6e, 0x00001e6f, + 0x00000058, 0x00000078, 0x00000423, 0x00000443, + 0x00002c1c, 0x00002c4c, 0x00002c9e, 0x00002c9f, + 0x00000120, 0x00000121, 0x00000531, 0x00000561, + 0x00001eb8, 0x00001eb9, 0x000104b2, 0x000104da, + 0x0000a7ce, 0x0000a7cf, 0x0000052c, 0x0000052d, + 0x00001fdb, 0x00001f77, 0x000013c1, 0x0000ab91, + 0x0000a7c0, 0x0000a7c1, 0x0000042e, 0x0000044e, + 0x000010b7, 0x00002d17, 0x0000037f, 0x000003f3, + 0x00001ed4, 0x00001ed5, 0x00000494, 0x00000495, + 0x00001f4a, 0x00001f42, 0x0000a786, 0x0000a787, + 0x0000a7d2, 0x0000a7d3, 0x00010401, 0x00010429, + 0x00010c9f, 0x00010cdf, 0x0000051a, 0x0000051b, + 0x00001e62, 0x00001e63, 0x00000429, 0x00000449, + 0x00001ea6, 0x00001ea7, 0x00002c80, 0x00002c81, + 0x00001eee, 0x00001eef, 0x000004b6, 0x000004b7, + 0x00001fab, 0x00001fa3, 0x00002cc0, 0x00002cc1, + 0x00016eb6, 0x00016ed1, 0x000118a5, 0x000118c5, + 0x00001e40, 0x00001e41, 0x0000023a, 0x00002c65, + 0x000013d7, 0x0000aba7, 0x000003a8, 0x000003c8, + 0x00001e80, 0x00001e81, 0x00000122, 0x00000123, + 0x0000a642, 0x0000a643, 0x0000024a, 0x0000024b, + 0x00001e06, 0x00001e07, 0x00002160, 0x00002170, + 0x0000a7c7, 0x0000a7c8, 0x000003ec, 0x000003ed, + 0x00001f5d, 0x00001f55, 0x000013ad, 0x0000ab7d, + 0x0000a7c9, 0x0000a7ca, 0x00002c6b, 0x00002c6c, + 0x00010422, 0x0001044a, 0x00016e4b, 0x00016e6b, + 0x0000a798, 0x0000a799, 0x0000010e, 0x0000010f, + 0x0000010c, 0x0000010d, 0x00000196, 0x00000269, + 0x0000a78b, 0x0000a78c, 0x00001f2c, 0x00001f24, + 0x00010d57, 0x00010d77, 0x00010ca4, 0x00010ce4, + 0x000013d0, 0x0000aba0, 0x00002ced, 0x00002cee, + 0x00001c9c, 0x000010dc, 0x0000a74c, 0x0000a74d, + 0x0000a78d, 0x00000265, 0x000001a2, 0x000001a3, + 0x00001c89, 0x00001c8a, 0x0000216c, 0x0000217c, + 0x000010c0, 0x00002d20, 0x00002c63, 0x00001d7d, + 0x00000470, 0x00000471, 0x00000424, 0x00000444, + 0x0000a698, 0x0000a699, 0x000001ea, 0x000001eb, + 0x0000023e, 0x00002c66, 0x0001057f, 0x000105a6, + 0x000024c4, 0x000024de, 0x00000145, 0x00000146, + 0x00001efe, 0x00001eff, 0x00000232, 0x00000233, + 0x0000a680, 0x0000a681, 0x000001b1, 0x0000028a, + 0x00010400, 0x00010428, 0x00000193, 0x00000260, + 0x000024cf, 0x000024e9, 0x0000016c, 0x0000016d, + 0x00000245, 0x0000028c, 0x00000547, 0x00000577, + 0x000010b3, 0x00002d13, 0x00000134, 0x00000135, + 0x00010590, 0x000105b7, 0x00000194, 0x00000263, + 0x00002c2c, 0x00002c5c, 0x00000048, 0x00000068, + 0x00010423, 0x0001044b, 0x0000212a, 0x0000006b, + 0x00001ee0, 0x00001ee1, 0x00001f5b, 0x00001f53, + 0x00000539, 0x00000569, 0x00001fda, 0x00001f76, + 0x00010c92, 0x00010cd2, 0x0000a762, 0x0000a763, + 0x00000536, 0x00000566, 0x00000166, 0x00000167, + 0x0000a74e, 0x0000a74f, 0x0000ff25, 0x0000ff45, + 0x00010406, 0x0001042e, 0x0000041a, 0x0000043a, + 0x0000a7ab, 0x0000025c, 0x0000ff2d, 0x0000ff4d, + 0x00016ea4, 0x00016ebf, 0x00001f3e, 0x00001f36, + 0x00002cd4, 0x00002cd5, 0x0001e91f, 0x0001e941, + 0x0001041b, 0x00010443, 0x00001c99, 0x000010d9, + 0x000104d1, 0x000104f9, 0x0001e911, 0x0001e933, + 0x00016e4c, 0x00016e6c, 0x00001e34, 0x00001e35, 0x000004d4, 0x000004d5, 0x00001f0b, 0x00001f03, - 0x0000054e, 0x0000057e, 0x000001ae, 0x00000288, - 0x000013b5, 0x0000ab85, 0x0000021e, 0x0000021f, - 0x00001ee4, 0x00001ee5, 0x00000394, 0x000003b4, - 0x00002c16, 0x00002c46, 0x0001e91c, 0x0001e93e, - 0x00002cc0, 0x00002cc1, 0x00002c01, 0x00002c31, - 0x00000189, 0x00000256, 0x000000ca, 0x000000ea, - 0x00001fdb, 0x00001f77, 0x00000502, 0x00000503, - 0x000118a6, 0x000118c6, 0x000001fa, 0x000001fb, - 0x000000de, 0x000000fe, 0x000010a3, 0x00002d03, - 0x00010d5e, 0x00010d7e, 0x000004c5, 0x000004c6, - 0x00001fba, 0x00001f70, 0x0000a7a2, 0x0000a7a3, - 0x00002cd8, 0x00002cd9, 0x00002c82, 0x00002c83, - 0x00000478, 0x00000479, 0x00001f6a, 0x00001f62, - 0x00010c8e, 0x00010cce, 0x00000106, 0x00000107, - 0x000004da, 0x000004db, 0x00001e88, 0x00001e89, - 0x00001ed8, 0x00001ed9, 0x00000551, 0x00000581, - 0x000013c6, 0x0000ab96, 0x000013e8, 0x0000abb8, - 0x00002cdc, 0x00002cdd, 0x00002c0f, 0x00002c3f, - 0x00001c9b, 0x000010db, 0x00016e42, 0x00016e62, - 0x00000496, 0x00000497, 0x0000040c, 0x0000045c, - 0x000004f6, 0x000004f7, 0x00010cab, 0x00010ceb, - 0x0000015c, 0x0000015d, 0x00010d55, 0x00010d75, - 0x00001e4c, 0x00001e4d, 0x00001cad, 0x000010ed, - 0x00000248, 0x00000249, 0x000013aa, 0x0000ab7a, - 0x0001e91d, 0x0001e93f, 0x00016e45, 0x00016e65, - 0x00000404, 0x00000454, 0x00001f29, 0x00001f21, - 0x00001cb2, 0x000010f2, 0x0001041f, 0x00010447, - 0x000001cb, 0x000001cc, 0x000104c9, 0x000104f1, - 0x000010b0, 0x00002d10, 0x00010573, 0x0001059a, - 0x000024b9, 0x000024d3, 0x0000a736, 0x0000a737, - 0x00001eb0, 0x00001eb1, 0x0000a7a8, 0x0000a7a9, - 0x000013d8, 0x0000aba8, 0x000024b6, 0x000024d0, - 0x00001c98, 0x000010d8, 0x000013e7, 0x0000abb7, - 0x000001f2, 0x000001f3, 0x000118bc, 0x000118dc, - 0x0000040f, 0x0000045f, 0x00010d5c, 0x00010d7c, - 0x0000a658, 0x0000a659, 0x00010cac, 0x00010cec, - 0x0000ff24, 0x0000ff44, 0x0000a74a, 0x0000a74b, - 0x00001fea, 0x00001f7a, 0x00002c1c, 0x00002c4c, - 0x0001e904, 0x0001e926, 0x000024c8, 0x000024e2, - 0x00000116, 0x00000117, 0x00010d50, 0x00010d70, - 0x000010bc, 0x00002d1c, 0x000104d0, 0x000104f8, - 0x0000014e, 0x0000014f, 0x00010d5d, 0x00010d7d, - 0x00001e1c, 0x00001e1d, 0x00001eea, 0x00001eeb, - 0x000003a9, 0x000003c9, 0x00000415, 0x00000435, - 0x0000ff30, 0x0000ff50, 0x00010c9e, 0x00010cde, - 0x00001f68, 0x00001f60, 0x000000d1, 0x000000f1, - 0x000001cd, 0x000001ce, 0x00000480, 0x00000481, - 0x000118b1, 0x000118d1, 0x00000047, 0x00000067, - 0x000001e2, 0x000001e3, 0x00001e5a, 0x00001e5b, - 0x0000049a, 0x0000049b, 0x00001ea0, 0x00001ea1, - 0x00001fa9, 0x00001fa1, 0x00000555, 0x00000585, - 0x0001e90c, 0x0001e92e, 0x00002ca8, 0x00002ca9, - 0x0000ff36, 0x0000ff56, 0x00001f6f, 0x00001f67, - 0x00000049, 0x00000069, 0x0000049c, 0x0000049d, - 0x000013f3, 0x000013fb, 0x0000014a, 0x0000014b, - 0x0000054a, 0x0000057a, 0x0000a698, 0x0000a699, - 0x00001caf, 0x000010ef, 0x0000a742, 0x0000a743, - 0x00010582, 0x000105a9, 0x00000210, 0x00000211, - 0x000013e2, 0x0000abb2, 0x00002ccc, 0x00002ccd, - 0x00002c8e, 0x00002c8f, 0x00016e4d, 0x00016e6d, - 0x0000042a, 0x0000044a, 0x00010ca5, 0x00010ce5, - 0x00001e4e, 0x00001e4f, 0x00000100, 0x00000101, - 0x0000a7b2, 0x0000029d, 0x000013df, 0x0000abaf, - 0x0001e90b, 0x0001e92d, 0x000003f7, 0x000003f8, - 0x00010c80, 0x00010cc0, 0x00001fec, 0x00001fe5, - 0x000001b1, 0x0000028a, 0x00010594, 0x000105bb, - 0x000010c1, 0x00002d21, 0x00010d5a, 0x00010d7a, - 0x0000054f, 0x0000057f, 0x000004ec, 0x000004ed, - 0x00010583, 0x000105aa, 0x00000150, 0x00000151, - 0x00010d5b, 0x00010d7b, 0x00001ede, 0x00001edf, - 0x000004c3, 0x000004c4, 0x00000413, 0x00000433, - 0x0000a668, 0x0000a669, 0x0001e900, 0x0001e922, - 0x00000128, 0x00000129, 0x00001f59, 0x00001f51, - 0x00000492, 0x00000493, 0x00010cae, 0x00010cee, - 0x00010405, 0x0001042d, 0x00001e82, 0x00001e83, - 0x0000050e, 0x0000050f, 0x00001e48, 0x00001e49, - 0x00010579, 0x000105a0, 0x0000024c, 0x0000024d, - 0x0000a768, 0x0000a769, 0x00001fd8, 0x00001fd0, - 0x00001ee8, 0x00001ee9, 0x000013a9, 0x0000ab79, - 0x000010bb, 0x00002d1b, 0x00016e4c, 0x00016e6c, - 0x000010a4, 0x00002d04, 0x0001e91a, 0x0001e93c, - 0x00010c96, 0x00010cd6, 0x00010421, 0x00010449, - 0x00000057, 0x00000077, 0x000104cb, 0x000104f3, - 0x00010595, 0x000105bc, 0x00010c9a, 0x00010cda, - 0x0000022e, 0x0000022f, 0x00001e7e, 0x00001e7f, - 0x0000a652, 0x0000a653, 0x00010c88, 0x00010cc8, - 0x00002c7f, 0x00000240, 0x000024ce, 0x000024e8, - 0x000004f0, 0x000004f1, 0x0000041f, 0x0000043f, - 0x000104b4, 0x000104dc, 0x00002c90, 0x00002c91, - 0x00000246, 0x00000247, 0x0001040e, 0x00010436, - 0x00001ed0, 0x00001ed1, 0x00010d58, 0x00010d78, - 0x00001f2a, 0x00001f22, 0x0001e917, 0x0001e939, - 0x0000ff22, 0x0000ff42, 0x000000c7, 0x000000e7, - 0x000003e2, 0x000003e3, 0x000003dc, 0x000003dd, - 0x0000048c, 0x0000048d, 0x000118a5, 0x000118c5, - 0x00010caf, 0x00010cef, 0x00001e40, 0x00001e41, - 0x0000a752, 0x0000a753, 0x0000013f, 0x00000140, - 0x00001f6d, 0x00001f65, 0x000013cd, 0x0000ab9d, - 0x00002c0d, 0x00002c3d, 0x000013b6, 0x0000ab86, - 0x000013a7, 0x0000ab77, 0x00001f0d, 0x00001f05, - 0x000118a0, 0x000118c0, 0x00000418, 0x00000438, - 0x0000212a, 0x0000006b, 0x00010ca2, 0x00010ce2, - 0x000010b1, 0x00002d11, 0x0000a7c2, 0x0000a7c3, - 0x0000019d, 0x00000272, 0x0000050a, 0x0000050b, - 0x000118a4, 0x000118c4, 0x0000a76c, 0x0000a76d, - 0x00016e5f, 0x00016e7f, 0x00001f6e, 0x00001f66, - 0x00002161, 0x00002171, 0x00001e20, 0x00001e21, - 0x000118bb, 0x000118db, 0x0000a784, 0x0000a785, - 0x000010b6, 0x00002d16, 0x00001f2d, 0x00001f25, - 0x0001057e, 0x000105a5, 0x0000a726, 0x0000a727, - 0x00001e92, 0x00001e93, 0x0000a680, 0x0000a681, - 0x00002c6e, 0x00000271, 0x0000a744, 0x0000a745, - 0x00001e8c, 0x00001e8d, 0x00001f9d, 0x00001f95, - 0x000118bd, 0x000118dd, 0x00002c86, 0x00002c87, - 0x00000110, 0x00000111, 0x00002132, 0x0000214e, - 0x000000d8, 0x000000f8, 0x00010c95, 0x00010cd5, - 0x00001e38, 0x00001e39, 0x000024cb, 0x000024e5, - 0x00001ee2, 0x00001ee3, 0x00001ea4, 0x00001ea5, - 0x00001fc9, 0x00001f73, 0x0000a77d, 0x00001d79, - 0x000013ae, 0x0000ab7e, 0x00002c80, 0x00002c81, - 0x000104b2, 0x000104da, 0x000003f4, 0x000003b8, - 0x00000416, 0x00000436, 0x00010409, 0x00010431, - 0x00001ecc, 0x00001ecd, 0x000104b3, 0x000104db, - 0x00001eb6, 0x00001eb7, 0x00000194, 0x00000263, - 0x000000d5, 0x000000f5, 0x0000023e, 0x00002c66, - 0x00001f8f, 0x00001f87, 0x00002c1e, 0x00002c4e, - 0x0000a7da, 0x0000a7db, 0x00000392, 0x000003b2, - 0x000004ee, 0x000004ef, 0x0000ff28, 0x0000ff48, - 0x000000cd, 0x000000ed, 0x00010427, 0x0001044f, - 0x000004cd, 0x000004ce, 0x00000104, 0x00000105, - 0x00001e76, 0x00001e77, 0x000003a5, 0x000003c5, - 0x00001c89, 0x00001c8a, 0x0001058c, 0x000105b3, - 0x0001e902, 0x0001e924, 0x0000a7c7, 0x0000a7c8, - 0x00002c28, 0x00002c58, 0x00002cd0, 0x00002cd1 + 0x000004c1, 0x000004c2, 0x00001e44, 0x00001e45, + 0x00002cd8, 0x00002cd9, 0x000013ea, 0x0000abba, + 0x000118bf, 0x000118df, 0x00001e3c, 0x00001e3d, + 0x00000468, 0x00000469, 0x0001e91d, 0x0001e93f, + 0x000003a9, 0x000003c9, 0x00001f0a, 0x00001f02, + 0x00010d61, 0x00010d81, 0x0000a66c, 0x0000a66d, + 0x000010c3, 0x00002d23, 0x000013de, 0x0000abae, + 0x0000054e, 0x0000057e, 0x0000a650, 0x0000a651, + 0x00010402, 0x0001042a, 0x000013aa, 0x0000ab7a, + 0x0001058f, 0x000105b6, 0x00002c20, 0x00002c50, + 0x00016eb2, 0x00016ecd, 0x000010ad, 0x00002d0d, + 0x00010582, 0x000105a9, 0x0000a7b6, 0x0000a7b7, + 0x000001b3, 0x000001b4, 0x00001e36, 0x00001e37, + 0x00010c9c, 0x00010cdc, 0x00010c8e, 0x00010cce, + 0x00002c15, 0x00002c45, 0x00000556, 0x00000586, + 0x00010c97, 0x00010cd7, 0x0000a744, 0x0000a745, + 0x00000049, 0x00000069, 0x00001c97, 0x000010d7, + 0x00000224, 0x00000225, 0x0000a728, 0x0000a729, + 0x00000406, 0x00000456, 0x00001c95, 0x000010d5, + 0x00010caa, 0x00010cea, 0x00001ee8, 0x00001ee9, + 0x00000181, 0x00000253, 0x00001eda, 0x00001edb, + 0x000004cd, 0x000004ce, 0x0000a690, 0x0000a691, + 0x00000170, 0x00000171, 0x000004f2, 0x000004f3, + 0x00001cb7, 0x000010f7, 0x0000a7b0, 0x0000029e, + 0x00000178, 0x000000ff, 0x00001f0d, 0x00001f05, + 0x00002167, 0x00002177, 0x0000a742, 0x0000a743, + 0x0000016a, 0x0000016b, 0x00000246, 0x00000247, + 0x00016e5e, 0x00016e7e, 0x000010a5, 0x00002d05, + 0x0000004f, 0x0000006f, 0x000104bd, 0x000104e5, + 0x000003e6, 0x000003e7, 0x00001ca6, 0x000010e6, + 0x000003e2, 0x000003e3, 0x00000548, 0x00000578, + 0x0000022c, 0x0000022d, 0x00001e70, 0x00001e71, + 0x0000020e, 0x0000020f, 0x0001057e, 0x000105a5, + 0x00010583, 0x000105aa, 0x00001e30, 0x00001e31, + 0x000003e4, 0x000003e5, 0x0000053f, 0x0000056f, + 0x00001feb, 0x00001f7b, 0x000010bb, 0x00002d1b, + 0x0000a7aa, 0x00000266, 0x0000040a, 0x0000045a, + 0x00001fe8, 0x00001fe0, 0x00002c0a, 0x00002c3a, + 0x00002132, 0x0000214e, 0x00016e5d, 0x00016e7d, + 0x00001e26, 0x00001e27, 0x000024cc, 0x000024e6, + 0x0000ff24, 0x0000ff44, 0x00010403, 0x0001042b, + 0x00001eea, 0x00001eeb, 0x000024bd, 0x000024d7, + 0x00001e5a, 0x00001e5b, 0x00010418, 0x00010440, + 0x00001eb4, 0x00001eb5, 0x0000024c, 0x0000024d, + 0x00001e56, 0x00001e57, 0x0000040d, 0x0000045d, + 0x00001cb4, 0x000010f4, 0x0001e913, 0x0001e935, + 0x0000a7a8, 0x0000a7a9, 0x000118a7, 0x000118c7, + 0x000001cb, 0x000001cc, 0x00001eec, 0x00001eed, + 0x00002c69, 0x00002c6a, 0x000118a3, 0x000118c3, + 0x0000041c, 0x0000043c, 0x00001cb5, 0x000010f5, + 0x00001fbc, 0x00001fb3, 0x0000038f, 0x000003ce, + 0x00001e42, 0x00001e43, 0x00010c8a, 0x00010cca, + 0x000013ec, 0x0000abbc, 0x0000039c, 0x000003bc, + 0x000104b4, 0x000104dc, 0x00000551, 0x00000581, + 0x000013b0, 0x0000ab80, 0x0000a686, 0x0000a687, + 0x00001fc8, 0x00001f72, 0x00010d65, 0x00010d85, + 0x000104c0, 0x000104e8, 0x000001b7, 0x00000292, + 0x0000022a, 0x0000022b, 0x00016ea3, 0x00016ebe, + 0x0000a7ac, 0x00000261, 0x00016eaa, 0x00016ec5, + 0x0000053d, 0x0000056d, 0x000013bb, 0x0000ab8b, + 0x0000a7b1, 0x00000287, 0x000104b3, 0x000104db, + 0x00000476, 0x00000477, 0x0001e915, 0x0001e937, + 0x00002c1a, 0x00002c4a, 0x00000391, 0x000003b1, + 0x00001eba, 0x00001ebb, 0x000000cb, 0x000000eb, + 0x000013bc, 0x0000ab8c, 0x0000015a, 0x0000015b, + 0x00000552, 0x00000582, 0x0000017b, 0x0000017c, + 0x0000a66a, 0x0000a66b, 0x00000158, 0x00000159, + 0x000118bb, 0x000118db, 0x00002183, 0x00002184, + 0x0000a69a, 0x0000a69b, 0x0000013d, 0x0000013e, + 0x00001cb1, 0x000010f1, 0x000013e3, 0x0000abb3, + 0x0000a7a2, 0x0000a7a3, 0x0000013b, 0x0000013c, + 0x0000048a, 0x0000048b, 0x0000216d, 0x0000217d, + 0x00002c01, 0x00002c31, 0x00001e90, 0x00001e91, + 0x0000053e, 0x0000056e, 0x00000187, 0x00000188, + 0x0000a780, 0x0000a781, 0x000000dd, 0x000000fd, + 0x00000412, 0x00000432, 0x000000c4, 0x000000e4, + 0x00016eb7, 0x00016ed2, 0x000001ac, 0x000001ad, + 0x000004a2, 0x000004a3, 0x00002c2d, 0x00002c5d, + 0x00001ee4, 0x00001ee5, 0x00000046, 0x00000066, + 0x0000040c, 0x0000045c, 0x0000022e, 0x0000022f, + 0x000013a8, 0x0000ab78, 0x00000104, 0x00000105, + 0x00000540, 0x00000570, 0x00002c84, 0x00002c85, + 0x000001fc, 0x000001fd, 0x000003fd, 0x0000037b, + 0x00000538, 0x00000568, 0x00001f6a, 0x00001f62, + 0x000024b8, 0x000024d2, 0x00001fca, 0x00001f74, + 0x0000046a, 0x0000046b, 0x00001e24, 0x00001e25, + 0x000024b6, 0x000024d0, 0x0000ff2f, 0x0000ff4f, + 0x00000413, 0x00000433, 0x00001f3c, 0x00001f34, + 0x000024c1, 0x000024db, 0x00001e9e, 0x000000df, + 0x00000411, 0x00000431, 0x0000012c, 0x0000012d, + 0x000013c3, 0x0000ab93, 0x00001cab, 0x000010eb, + 0x0000042a, 0x0000044a, 0x000004e6, 0x000004e7, + 0x000004be, 0x000004bf, 0x00001fba, 0x00001f70, + 0x000004ba, 0x000004bb, 0x00001eb0, 0x00001eb1, + 0x000003a0, 0x000003c0, 0x000013b6, 0x0000ab86, + 0x000118bd, 0x000118dd, 0x00001f8c, 0x00001f84, + 0x00010d60, 0x00010d80, 0x0000a7ad, 0x0000026c, + 0x00002c13, 0x00002c43, 0x00001e08, 0x00001e09, + 0x00010c84, 0x00010cc4, 0x00001efc, 0x00001efd, + 0x00000386, 0x000003ac, 0x000000d3, 0x000000f3, + 0x00010d58, 0x00010d78, 0x00002c19, 0x00002c49, + 0x00000102, 0x00000103, 0x000010b6, 0x00002d16, + 0x00010ca0, 0x00010ce0, 0x00016e43, 0x00016e63, + 0x00000143, 0x00000144, 0x000013e1, 0x0000abb1, + 0x000104b6, 0x000104de, 0x0000a790, 0x0000a791, + 0x00000212, 0x00000213, 0x00010588, 0x000105af, + 0x000013b1, 0x0000ab81, 0x0001e912, 0x0001e934, + 0x00016e58, 0x00016e78, 0x000003a1, 0x000003c1, + 0x00010c9e, 0x00010cde, 0x0000a73a, 0x0000a73b, + 0x00000372, 0x00000373, 0x0000046e, 0x0000046f, + 0x00010cb1, 0x00010cf1, 0x0000a724, 0x0000a725, + 0x000004e8, 0x000004e9, 0x00001c9f, 0x000010df, + 0x00010404, 0x0001042c, 0x00001e52, 0x00001e53, + 0x000001e4, 0x000001e5, 0x00001ea2, 0x00001ea3, + 0x0001e900, 0x0001e922, 0x00001e54, 0x00001e55, + 0x00000154, 0x00000155, 0x000004a6, 0x000004a7, + 0x00002169, 0x00002179, 0x000013c5, 0x0000ab95, + 0x000000d8, 0x000000f8, 0x00010c82, 0x00010cc2, + 0x0001e90a, 0x0001e92c, 0x000013a4, 0x0000ab74, + 0x00002c70, 0x00000252, 0x000104b1, 0x000104d9, + 0x00000132, 0x00000133, 0x000024cd, 0x000024e7, + 0x000000d6, 0x000000f6, 0x0001058e, 0x000105b5, + 0x000104ba, 0x000104e2, 0x000013a0, 0x0000ab70, + 0x0000a7a6, 0x0000a7a7, 0x00010c81, 0x00010cc1, + 0x000104be, 0x000104e6, 0x0001e910, 0x0001e932, + 0x0000ff29, 0x0000ff49, 0x0000050e, 0x0000050f, + 0x000004e4, 0x000004e5, 0x00010c94, 0x00010cd4, + 0x00016e50, 0x00016e70, 0x00016e5b, 0x00016e7b, + 0x00016eb5, 0x00016ed0, 0x0000a754, 0x0000a755, + 0x000013a1, 0x0000ab71, 0x00000528, 0x00000529, + 0x00000244, 0x00000289, 0x000024c9, 0x000024e3, + 0x0001e90f, 0x0001e931, 0x000004a0, 0x000004a1, + 0x00001fd8, 0x00001fd0, 0x000024ba, 0x000024d4, + 0x0000ff38, 0x0000ff58, 0x00002c25, 0x00002c55, + 0x000010b5, 0x00002d15, 0x000024c7, 0x000024e1, + 0x00002cd6, 0x00002cd7, 0x0001041d, 0x00010445, + 0x000001a7, 0x000001a8, 0x00002c2b, 0x00002c5b, + 0x00001e58, 0x00001e59, 0x0000040b, 0x0000045b, + 0x00001eca, 0x00001ecb, 0x00016eaf, 0x00016eca, + 0x000013f3, 0x000013fb, 0x000003ee, 0x000003ef, + 0x000010ae, 0x00002d0e, 0x00002c86, 0x00002c87, + 0x000013c2, 0x0000ab92, 0x000118a1, 0x000118c1, + 0x00001ed0, 0x00001ed1, 0x00010d62, 0x00010d82, + 0x0000ff35, 0x0000ff55, 0x000003ab, 0x000003cb, + 0x00001e94, 0x00001e95, 0x00010ca3, 0x00010ce3, + 0x0001e909, 0x0001e92b, 0x00002c0f, 0x00002c3f, + 0x00001e8a, 0x00001e8b, 0x0000050c, 0x0000050d, + 0x0001e90b, 0x0001e92d, 0x0000a760, 0x0000a761, + 0x0000004d, 0x0000006d, 0x00001f2f, 0x00001f27, + 0x00002c1f, 0x00002c4f, 0x00002cb6, 0x00002cb7, + 0x00001e8c, 0x00001e8d, 0x0000a73e, 0x0000a73f, + 0x0000a7b8, 0x0000a7b9, 0x000004e2, 0x000004e3, + 0x0001058a, 0x000105b1, 0x0000a662, 0x0000a663, + 0x0000a79a, 0x0000a79b, 0x0000a64a, 0x0000a64b, + 0x0000048e, 0x0000048f, 0x0000a768, 0x0000a769, + 0x0000a72a, 0x0000a72b, 0x00000214, 0x00000215, + 0x00001c9e, 0x000010de, 0x000001b8, 0x000001b9, + 0x0000ff36, 0x0000ff56, 0x00002c27, 0x00002c57, + 0x00001e72, 0x00001e73, 0x00000460, 0x00000461, + 0x0000a646, 0x0000a647, 0x00002c64, 0x0000027d, + 0x00001ea0, 0x00001ea1, 0x0000a756, 0x0000a757, + 0x0000a784, 0x0000a785, 0x0000014e, 0x0000014f, + 0x000010cd, 0x00002d2d, 0x000104b8, 0x000104e0, + 0x000013eb, 0x0000abbb, 0x000001ec, 0x000001ed, + 0x0000004b, 0x0000006b, 0x000001ae, 0x00000288, + 0x00016e51, 0x00016e71, 0x000003da, 0x000003db, + 0x0001057a, 0x000105a1, 0x00000189, 0x00000256, + 0x000024c5, 0x000024df, 0x00016e4e, 0x00016e6e, + 0x00010d55, 0x00010d75, 0x00002c02, 0x00002c32, + 0x000010a2, 0x00002d02, 0x00000200, 0x00000201, + 0x000118a4, 0x000118c4, 0x00010d54, 0x00010d74, + 0x000013bf, 0x0000ab8f, 0x00000044, 0x00000064, + 0x00016ea2, 0x00016ebd, 0x000004ea, 0x000004eb, + 0x0000a74a, 0x0000a74b, 0x00000051, 0x00000071, + 0x00000522, 0x00000523, 0x00001e2c, 0x00001e2d, + 0x00010586, 0x000105ad, 0x00001f8e, 0x00001f86, + 0x00000542, 0x00000572, 0x00001eb2, 0x00001eb3, + 0x000024c2, 0x000024dc, 0x00016e56, 0x00016e76, + 0x00000480, 0x00000481, 0x00001f4b, 0x00001f43, + 0x000024cb, 0x000024e5, 0x0000ff26, 0x0000ff46, + 0x00010409, 0x00010431, 0x00001f3a, 0x00001f32, + 0x00002cd2, 0x00002cd3, 0x00001f0f, 0x00001f07, + 0x00010407, 0x0001042f, 0x00001e02, 0x00001e03, + 0x00010cab, 0x00010ceb, 0x00001e60, 0x00001e61, + 0x00000407, 0x00000457, 0x00001faf, 0x00001fa7, + 0x00002c1e, 0x00002c4e, 0x00001e6a, 0x00001e6b, + 0x000118ad, 0x000118cd, 0x00001e00, 0x00001e01, + 0x00010d63, 0x00010d83, 0x000013c4, 0x0000ab94, + 0x000118ab, 0x000118cb, 0x000013dd, 0x0000abad, + 0x0000a64c, 0x0000a64d, 0x000010b1, 0x00002d11, + 0x00000396, 0x000003b6, 0x00001e16, 0x00001e17, + 0x00010578, 0x0001059f, 0x0000ff2b, 0x0000ff4b, + 0x0000a7dc, 0x0000019b, 0x00010571, 0x00010598, + 0x000001fa, 0x000001fb, 0x00002c22, 0x00002c52, + 0x000118aa, 0x000118ca, 0x000010ab, 0x00002d0b, + 0x00010ca5, 0x00010ce5, 0x00002c1d, 0x00002c4d, + 0x0000a758, 0x0000a759, 0x00001e84, 0x00001e85, + 0x0001e919, 0x0001e93b, 0x0000a7b3, 0x0000ab53, + 0x000004f0, 0x000004f1, 0x00010c80, 0x00010cc0, + 0x000104cc, 0x000104f4, 0x0000a77b, 0x0000a77c, + 0x00000043, 0x00000063, 0x00000124, 0x00000125, + 0x000000c6, 0x000000e6, 0x0000a658, 0x0000a659, + 0x00002cde, 0x00002cdf, 0x00001ebc, 0x00001ebd, + 0x00010424, 0x0001044c, 0x0000a734, 0x0000a735, + 0x000001d9, 0x000001da, 0x00001c90, 0x000010d0, + 0x0000018a, 0x00000257, 0x000010bc, 0x00002d1c, + 0x00002c62, 0x0000026b, 0x00000112, 0x00000113, + 0x00000186, 0x00000254, 0x0000a68c, 0x0000a68d, + 0x00002c60, 0x00002c61, 0x00000404, 0x00000454, + 0x00010577, 0x0001059e, 0x0000a75e, 0x0000a75f, + 0x00000420, 0x00000440, 0x00000401, 0x00000451, + 0x000001cf, 0x000001d0, 0x00002c2f, 0x00002c5f, + 0x0000039e, 0x000003be, 0x000010bf, 0x00002d1f, + 0x00010576, 0x0001059d, 0x00016e45, 0x00016e65, + 0x000004fc, 0x000004fd, 0x00000414, 0x00000434, + 0x00002cae, 0x00002caf, 0x00002c92, 0x00002c93, + 0x00016e4f, 0x00016e6f, 0x0001041f, 0x00010447, + 0x0000038a, 0x000003af, 0x000013c0, 0x0000ab90, + 0x0000004e, 0x0000006e, 0x00016ea0, 0x00016ebb, + 0x00010d5f, 0x00010d7f, 0x0001e918, 0x0001e93a, + 0x00000059, 0x00000079, 0x0000052a, 0x0000052b, + 0x000013e9, 0x0000abb9, 0x000010af, 0x00002d0f, + 0x00016e54, 0x00016e74, 0x00000526, 0x00000527, + 0x00001f1c, 0x00001f14, 0x00010c95, 0x00010cd5, + 0x0000ff22, 0x0000ff42, 0x0000047c, 0x0000047d, + 0x00000130, 0x02000142, 0x00002cda, 0x00002cdb, + 0x00001ef4, 0x00001ef5, 0x00010427, 0x0001044f, + 0x00001f49, 0x00001f41, 0x000104ce, 0x000104f6, + 0x000010ac, 0x00002d0c, 0x0001040b, 0x00010433, + 0x000003cf, 0x000003d7, 0x000004dc, 0x000004dd, + 0x0000a7d6, 0x0000a7d7, 0x00000415, 0x00000435, + 0x00001e0c, 0x00001e0d, 0x00001cbd, 0x000010fd, + 0x000013e6, 0x0000abb6, 0x0000040f, 0x0000045f, + 0x00001c98, 0x000010d8, 0x00000228, 0x00000229, + 0x000013ef, 0x0000abbf, 0x000118af, 0x000118cf, + 0x00001cb3, 0x000010f3, 0x00010d5b, 0x00010d7b, + 0x000013b3, 0x0000ab83, 0x000118bc, 0x000118dc, + 0x00001e38, 0x00001e39, 0x00001f88, 0x00001f80, + 0x0001e90e, 0x0001e930, 0x00001ef8, 0x00001ef9, + 0x000001f8, 0x000001f9, 0x0000212b, 0x000000e5, + 0x00002c1b, 0x00002c4b, 0x000003a7, 0x000003c7, + 0x00001ea4, 0x00001ea5, 0x00000464, 0x00000465, + 0x0000a7c5, 0x00000282, 0x0000a7d8, 0x0000a7d9, + 0x00010570, 0x00010597, 0x00002c88, 0x00002c89, + 0x000013d4, 0x0000aba4, 0x00016ea6, 0x00016ec1, + 0x00010417, 0x0001043f, 0x00010ca2, 0x00010ce2, + 0x00001ca4, 0x000010e4, 0x00001e7a, 0x00001e7b, + 0x00001e1e, 0x00001e1f, 0x00010c87, 0x00010cc7, + 0x0000a7c4, 0x0000a794, 0x00016e44, 0x00016e64, + 0x00001c92, 0x000010d2, 0x0000047a, 0x0000047b, + 0x00002cc6, 0x00002cc7, 0x000001a0, 0x000001a1, + 0x00000474, 0x00000475, 0x00010c9b, 0x00010cdb, + 0x00010c96, 0x00010cd6, 0x000001c7, 0x000001c9, + 0x00001f1a, 0x00001f12, 0x00002cbc, 0x00002cbd, + 0x00002cc2, 0x00002cc3, 0x00000176, 0x00000177, + 0x00001ca5, 0x000010e5, 0x0000041f, 0x0000043f, + 0x0000a77e, 0x0000a77f, 0x000003e0, 0x000003e1, + 0x00001e1c, 0x00001e1d, 0x0000012a, 0x0000012b, + 0x000118a8, 0x000118c8, 0x0000024e, 0x0000024f, + 0x00000520, 0x00000521, 0x000001af, 0x000001b0, + 0x00002c04, 0x00002c34, 0x00010c9a, 0x00010cda, + 0x00000204, 0x00000205, 0x00010426, 0x0001044e, + 0x000010a6, 0x00002d06, 0x000010be, 0x00002d1e, + 0x000118b9, 0x000118d9, 0x00002c8a, 0x00002c8b, + 0x000010a7, 0x00002d07, 0x00000052, 0x00000072, + 0x000118b8, 0x000118d8, 0x000004c9, 0x000004ca, + 0x0000a668, 0x0000a669, 0x00016e57, 0x00016e77, + 0x00000555, 0x00000585, 0x000004ac, 0x000004ad, + 0x0000021c, 0x0000021d, 0x00001f2e, 0x00001f26, + 0x0000053a, 0x0000056a, 0x00001f9a, 0x00001f92, + 0x00000218, 0x00000219, 0x0000ff27, 0x0000ff47, + 0x0000047e, 0x0000047f, 0x000003e8, 0x000003e9, + 0x000024bb, 0x000024d5, 0x00001ef0, 0x00001ef1, + 0x00010413, 0x0001043b, 0x00001f48, 0x00001f40, + 0x000104cd, 0x000104f5, 0x0000a7d4, 0x0000a7d5, + 0x0001041a, 0x00010442, 0x00001f0c, 0x00001f04, + 0x0001e91b, 0x0001e93d, 0x00001f5f, 0x00001f57, + 0x0000042f, 0x0000044f, 0x00001f98, 0x00001f90, + 0x00010ca1, 0x00010ce1, 0x000013d1, 0x0000aba1, + 0x0000039a, 0x000003ba, 0x00001eac, 0x00001ead, + 0x00002c8c, 0x00002c8d, 0x00002c8e, 0x00002c8f, + 0x000118be, 0x000118de, 0x00001e50, 0x00001e51, + 0x000104c4, 0x000104ec, 0x00002cb4, 0x00002cb5, + 0x000118b7, 0x000118d7, 0x00001ec6, 0x00001ec7, + 0x0000a72c, 0x0000a72d, 0x00002cb2, 0x00002cb3, + 0x000003fa, 0x000003fb, 0x00000226, 0x00000227, + 0x00010d64, 0x00010d84, 0x00001ee6, 0x00001ee7, + 0x000003a4, 0x000003c4, 0x00001f6c, 0x00001f64, + 0x000104c2, 0x000104ea, 0x00001ee2, 0x00001ee3, + 0x00001fa8, 0x00001fa0, 0x000003f7, 0x000003f8, + 0x000104d0, 0x000104f8, 0x00016e40, 0x00016e60, + 0x0000a75c, 0x0000a75d, 0x0000051e, 0x0000051f, + 0x0000a660, 0x0000a661, 0x00002168, 0x00002178, + 0x00000393, 0x000003b3, 0x000001a4, 0x000001a5, + 0x00002c29, 0x00002c59, 0x0000a79e, 0x0000a79f, + 0x00002c75, 0x00002c76, 0x00001e1a, 0x00001e1b, + 0x00002c0d, 0x00002c3d, 0x00016ea5, 0x00016ec0, + 0x00002c6f, 0x00000250, 0x00000502, 0x00000503, + 0x00000220, 0x0000019e, 0x0000a68e, 0x0000a68f, + 0x00000160, 0x00000161, 0x0000053b, 0x0000056b, + 0x000004bc, 0x000004bd, 0x0000a68a, 0x0000a68b, + 0x00002c17, 0x00002c47, 0x00000472, 0x00000473, + 0x00002165, 0x00002175, 0x00002c00, 0x00002c30, + 0x00000156, 0x00000157, 0x00010412, 0x0001043a, + 0x00001f8b, 0x00001f83, 0x00010c90, 0x00010cd0, + 0x00001ed2, 0x00001ed3, 0x0001057c, 0x000105a3, + 0x0000018f, 0x00000259, 0x0000a76e, 0x0000a76f, + 0x00000202, 0x00000203, 0x000004f4, 0x000004f5, + 0x000000c3, 0x000000e3, 0x000010a3, 0x00002d03, + 0x0000005a, 0x0000007a, 0x00000417, 0x00000437, + 0x00000114, 0x00000115, 0x000104c8, 0x000104f0, + 0x000004f8, 0x000004f9, 0x0000049c, 0x0000049d, + 0x0000a654, 0x0000a655, 0x00010d52, 0x00010d72, + 0x0000020c, 0x0000020d, 0x0000054a, 0x0000057a, + 0x00001fcc, 0x00001fc3, 0x000013bd, 0x0000ab8d, + 0x0000a7a4, 0x0000a7a5, 0x00000524, 0x00000525, + 0x00001f69, 0x00001f61, 0x00002c08, 0x00002c38, + 0x0000ff2c, 0x0000ff4c, 0x000104b9, 0x000104e1, + 0x00001f28, 0x00001f20, 0x000024bf, 0x000024d9, + 0x0000ff28, 0x0000ff48, 0x00000402, 0x00000452, + 0x00001f59, 0x00001f51, 0x0000a656, 0x0000a657, + 0x0001e91c, 0x0001e93e, 0x0001040c, 0x00010434, + 0x000013a5, 0x0000ab75, 0x00010cad, 0x00010ced, + 0x00001fb9, 0x00001fb1, 0x00000427, 0x00000447, + 0x00001cb6, 0x000010f6, 0x00010c9d, 0x00010cdd, + 0x000013b2, 0x0000ab82, 0x00000400, 0x00000450, + 0x00001e10, 0x00001e11, 0x00010c98, 0x00010cd8, + 0x000013c9, 0x0000ab99, 0x00000394, 0x000003b4, + 0x00001f1b, 0x00001f13, 0x00001f2d, 0x00001f25, + 0x00002c18, 0x00002c48, 0x0000039b, 0x000003bb, + 0x00001e3e, 0x00001e3f, 0x00002166, 0x00002176, + 0x000013d5, 0x0000aba5, 0x0000a7cb, 0x00000264, + 0x00001ffc, 0x00001ff3, 0x00001cb9, 0x000010f9, + 0x00001cba, 0x000010fa, 0x000001d1, 0x000001d2, + 0x000004ae, 0x000004af, 0x00000516, 0x00000517, + 0x00016e47, 0x00016e67, 0x00002c26, 0x00002c56, + 0x0000012e, 0x0000012f, 0x00010ca7, 0x00010ce7, + 0x0000a732, 0x0000a733, 0x00001e66, 0x00001e67, + 0x0000051c, 0x0000051d, 0x0000021e, 0x0000021f, + 0x0000a779, 0x0000a77a, 0x00002cdc, 0x00002cdd, + 0x00001fac, 0x00001fa4, 0x00010c8b, 0x00010ccb, + 0x00001ec4, 0x00001ec5, 0x00002ceb, 0x00002cec, + 0x00001ca7, 0x000010e7, 0x000000c9, 0x000000e9, + 0x00001f29, 0x00001f21, 0x000001de, 0x000001df, + 0x00001ca1, 0x000010e1, 0x00010cb0, 0x00010cf0, + 0x000013d6, 0x0000aba6, 0x00010421, 0x00010449, + 0x00000408, 0x00000458, 0x00016ea9, 0x00016ec4, + 0x000013f4, 0x000013fc, 0x00000162, 0x00000163, + 0x00001e28, 0x00001e29, 0x00016ead, 0x00016ec8, + 0x0000a740, 0x0000a741, 0x000001c5, 0x000001c6, + 0x000004a4, 0x000004a5, 0x00002c2a, 0x00002c5a, + 0x00001efa, 0x00001efb, 0x00000136, 0x00000137, + 0x00000504, 0x00000505, 0x000001a9, 0x00000283, + 0x000013a2, 0x0000ab72, 0x00000128, 0x00000129, + 0x00000409, 0x00000459, 0x000000c5, 0x000000e5, + 0x000010a0, 0x00002d00, 0x00000150, 0x00000151, + 0x0000054c, 0x0000057c, 0x000004d0, 0x000004d1, + 0x00001ff9, 0x00001f79, 0x00000055, 0x00000075, + 0x00000510, 0x00000511, 0x000000c1, 0x000000e1, + 0x0000a746, 0x0000a747, 0x0000011a, 0x0000011b, + 0x00000546, 0x00000576, 0x00001c9b, 0x000010db, + 0x0000a684, 0x0000a685, 0x0000a76a, 0x0000a76b, + 0x0000052e, 0x0000052f, 0x00001f3d, 0x00001f35, + 0x00002c72, 0x00002c73, 0x00002c11, 0x00002c41, + 0x0000049e, 0x0000049f, 0x000013df, 0x0000abaf, + 0x000024bc, 0x000024d6, 0x0000ff23, 0x0000ff43, + 0x00000418, 0x00000438, 0x000013c7, 0x0000ab97, + 0x000001f6, 0x00000195, 0x00001e5e, 0x00001e5f, + 0x0001040a, 0x00010432, 0x00001eb6, 0x00001eb7, + 0x000004de, 0x000004df, 0x0000a7cc, 0x0000a7cd, + 0x0000042c, 0x0000044c, 0x00000419, 0x00000439, + 0x000104d2, 0x000104fa, 0x00001e64, 0x00001e65, + 0x000003f4, 0x000003b8, 0x00001eaa, 0x00001eab, + 0x0001e901, 0x0001e923, 0x0000a7d0, 0x0000a7d1, + 0x000118ae, 0x000118ce, 0x00001ed8, 0x00001ed9, + 0x0000a7be, 0x0000a7bf, 0x000013cf, 0x0000ab9f, + 0x00000398, 0x000003b8, 0x00000403, 0x00000453, + 0x000003ea, 0x000003eb, 0x000013c6, 0x0000ab96, + 0x000003d8, 0x000003d9, 0x0000041b, 0x0000043b, + 0x00001f6e, 0x00001f66, 0x000013f2, 0x000013fa, + 0x000001d3, 0x000001d4, 0x00001e12, 0x00001e13, + 0x0000a65c, 0x0000a65d, 0x000013e2, 0x0000abb2, + 0x00002c28, 0x00002c58, 0x00001f6d, 0x00001f65, + 0x00010585, 0x000105ac, 0x0000ff33, 0x0000ff53, + 0x000000d2, 0x000000f2, 0x00001f18, 0x00001f10, + 0x00002c9a, 0x00002c9b, 0x0000a648, 0x0000a649, + 0x00016e48, 0x00016e68, 0x000004b2, 0x000004b3, + 0x000013ab, 0x0000ab7b, 0x000013b9, 0x0000ab89, + 0x0000019c, 0x0000026f, 0x00001c9d, 0x000010dd, + 0x00010ca8, 0x00010ce8, 0x000013da, 0x0000abaa, + 0x000001e8, 0x000001e9, 0x0000046c, 0x0000046d, + 0x0000a664, 0x0000a665, 0x000024c3, 0x000024dd, + 0x000001e6, 0x000001e7, 0x00001e76, 0x00001e77, + 0x00002164, 0x00002174, 0x0000a688, 0x0000a689, + 0x0000016e, 0x0000016f, 0x000004c5, 0x000004c6, + 0x00002163, 0x00002173, 0x0000a682, 0x0000a683, + 0x00000139, 0x0000013a, 0x00000243, 0x00000180, + 0x0000216e, 0x0000217e, 0x00001f9c, 0x00001f94, + 0x000001f7, 0x000001bf, 0x00010d56, 0x00010d76, + 0x00002ccc, 0x00002ccd, 0x000010c4, 0x00002d24, + 0x000013ca, 0x0000ab9a, 0x00000248, 0x00000249, + 0x00000118, 0x00000119, 0x000010a8, 0x00002d08, + 0x000000ce, 0x000000ee, 0x00010425, 0x0001044d, + 0x00000514, 0x00000515, 0x00016e42, 0x00016e62, + 0x00000053, 0x00000073, 0x0000040e, 0x0000045e, + 0x00002c12, 0x00002c42, 0x000010b0, 0x00002d10, + 0x00000042, 0x00000062, 0x00000541, 0x00000571, + 0x000000c0, 0x000000e0, 0x0000a752, 0x0000a753, + 0x0000ff31, 0x0000ff51, 0x00000532, 0x00000562, + 0x00000206, 0x00000207, 0x000024b9, 0x000024d3, + 0x0000ff2e, 0x0000ff4e, 0x000004f6, 0x000004f7, + 0x00001f99, 0x00001f91, 0x0001e907, 0x0001e929, + 0x0000ff21, 0x0000ff41, 0x000004b8, 0x000004b9, + 0x00001f4c, 0x00001f44, 0x00000216, 0x00000217, + 0x00001e7e, 0x00001e7f, 0x0001040e, 0x00010436, + 0x000013e0, 0x0000abb0, 0x00000518, 0x00000519, + 0x000003ff, 0x0000037d, 0x000004b0, 0x000004b1, + 0x00001fad, 0x00001fa5, 0x00002c6e, 0x00000271, + 0x000013cb, 0x0000ab9b, 0x00000426, 0x00000446, + 0x00001e2e, 0x00001e2f, 0x0001e90d, 0x0001e92f, + 0x00001e4a, 0x00001e4b, 0x000118b2, 0x000118d2, + 0x00001f19, 0x00001f11, 0x0001e905, 0x0001e927, + 0x000013b8, 0x0000ab88, 0x00000395, 0x000003b5, + 0x000000d9, 0x000000f9, 0x0001e921, 0x0001e943, + 0x000013dc, 0x0000abac, 0x00002cb8, 0x00002cb9, + 0x0000019f, 0x00000275, 0x00010cae, 0x00010cee, + 0x000013ba, 0x0000ab8a, 0x00016e5a, 0x00016e7a, + 0x000013af, 0x0000ab7f, 0x000003a3, 0x000003c3, + 0x00001e32, 0x00001e33, 0x0000a75a, 0x0000a75b, + 0x00001e4e, 0x00001e4f, 0x00010c8c, 0x00010ccc, + 0x0000a796, 0x0000a797, 0x00000110, 0x00000111, + 0x00001f39, 0x00001f31, 0x0001e914, 0x0001e936, + 0x0000a7b2, 0x0000029d, 0x00002c24, 0x00002c54, + 0x000104c3, 0x000104eb, 0x00010c99, 0x00010cd9, + 0x000010bd, 0x00002d1d, 0x00002ca4, 0x00002ca5, + 0x00001ed6, 0x00001ed7, 0x00002c05, 0x00002c35, + 0x00016e41, 0x00016e61, 0x000001d7, 0x000001d8, + 0x0001041e, 0x00010446, 0x00010579, 0x000105a0, + 0x0000a694, 0x0000a695, 0x00002ca2, 0x00002ca3, + 0x000104bf, 0x000104e7, 0x0000011e, 0x0000011f, + 0x0000a692, 0x0000a693, 0x00000182, 0x00000183, + 0x00010415, 0x0001043d, 0x0000216b, 0x0000217b, + 0x00001f2a, 0x00001f22, 0x00002c21, 0x00002c51, + 0x0000038e, 0x000003cd, 0x000000d4, 0x000000f4, + 0x0000a7ae, 0x0000026a, 0x0000a7da, 0x0000a7db, + 0x00001e6c, 0x00001e6d, 0x00000392, 0x000003b2, + 0x00016ea1, 0x00016ebc, 0x000000d0, 0x000000f0, + 0x000104b5, 0x000104dd, 0x00000388, 0x000003ad, + 0x000010b9, 0x00002d19, 0x0000013f, 0x00000140, + 0x00010595, 0x000105bc, 0x0000011c, 0x0000011d, + 0x00001cbe, 0x000010fe, 0x00000057, 0x00000077, + 0x00000553, 0x00000583, 0x00002c14, 0x00002c44, + 0x00010d50, 0x00010d70, 0x0000004a, 0x0000006a, + 0x00000512, 0x00000513, 0x0000041d, 0x0000043d, + 0x00002cbe, 0x00002cbf, 0x0000ff37, 0x0000ff57, + 0x00016e4a, 0x00016e6a, 0x00001f9b, 0x00001f93, + 0x00002c06, 0x00002c36, 0x0001e906, 0x0001e928, + 0x00000490, 0x00000491, 0x00001fd9, 0x00001fd1, + 0x000024be, 0x000024d8, 0x0000ff39, 0x0000ff59, + 0x000004b4, 0x000004b5, 0x00001f4d, 0x00001f45, + 0x00002cb0, 0x00002cb1, 0x00001f9d, 0x00001f95, + 0x0001040d, 0x00010435, 0x00001e20, 0x00001e21, + 0x00002c9c, 0x00002c9d, 0x00002162, 0x00002172, + 0x00000428, 0x00000448, 0x00001ece, 0x00001ecf, + 0x000024b7, 0x000024d1, 0x000013f1, 0x000013f9, + 0x000004aa, 0x000004ab, 0x00001ea8, 0x00001ea9, + 0x0000a782, 0x0000a783, 0x000013d3, 0x0000aba3, + 0x000118b1, 0x000118d1, 0x00001c9a, 0x000010da, + 0x00000462, 0x00000463, 0x000013d9, 0x0000aba9, + 0x00000389, 0x000003ae, 0x00001ca8, 0x000010e8, + 0x00002c90, 0x00002c91, 0x000013e8, 0x0000abb8, + 0x0000023b, 0x0000023c, 0x000000d1, 0x000000f1, + 0x0000a640, 0x0000a641, 0x00016e46, 0x00016e66, + 0x00000164, 0x00000165, 0x00001e82, 0x00001e83, + 0x00010c91, 0x00010cd1, 0x000013ce, 0x0000ab9e, + 0x00016eb4, 0x00016ecf, 0x00010575, 0x0001059c, + 0x000013b5, 0x0000ab85, 0x0000a7ba, 0x0000a7bb, + 0x0000010a, 0x0000010b, 0x00001f6f, 0x00001f67, + 0x00010cb2, 0x00010cf2, 0x000013d2, 0x0000aba2, + 0x00002c67, 0x00002c68, 0x0000054d, 0x0000057d, + 0x00010c8d, 0x00010ccd, 0x0000a7c2, 0x0000a7c3, + 0x00002caa, 0x00002cab, 0x00001ca0, 0x000010e0, + 0x000104ca, 0x000104f2, 0x00002cc4, 0x00002cc5, + 0x00002ce2, 0x00002ce3, 0x00001cb2, 0x000010f2, + 0x00010c8f, 0x00010ccf, 0x000013d8, 0x0000aba8, + 0x00010c83, 0x00010cc3, 0x00001cb0, 0x000010f0, + 0x00002c07, 0x00002c37, 0x0000a696, 0x0000a697, + 0x00002cce, 0x00002ccf, 0x00001ca9, 0x000010e9, + 0x00002161, 0x00002171, 0x0000a65a, 0x0000a65b, + 0x00000147, 0x00000148, 0x000004c7, 0x000004c8, + 0x00000191, 0x00000192, 0x000013c8, 0x0000ab98, + 0x000000db, 0x000000fb, 0x000104d3, 0x000104fb, + 0x0001e917, 0x0001e939, 0x000010ba, 0x00002d1a, + 0x000000dc, 0x000000fc, 0x00001f9f, 0x00001f97, + 0x00002cca, 0x00002ccb, 0x000010a4, 0x00002d04, + 0x000003de, 0x000003df, 0x00000416, 0x00000436, + 0x00002c82, 0x00002c83, 0x000024ce, 0x000024e8, + 0x00000054, 0x00000074, 0x000118b6, 0x000118d6, + 0x00000376, 0x00000377, 0x00001f2b, 0x00001f23, + 0x0001e908, 0x0001e92a, 0x00000544, 0x00000574, + 0x00001fea, 0x00001f7a, 0x00000190, 0x0000025b, + 0x0001e91a, 0x0001e93c, 0x00000535, 0x00000565, + 0x00001e22, 0x00001e23, 0x00010d5c, 0x00010d7c, + 0x0000ff30, 0x0000ff50, 0x0000041e, 0x0000043e, + 0x000010c7, 0x00002d27, 0x000104bc, 0x000104e4, + 0x0000ff32, 0x0000ff52, 0x00010408, 0x00010430, + 0x00001f6b, 0x00001f63, 0x000104cf, 0x000104f7, + 0x00001e78, 0x00001e79, 0x00010405, 0x0001042d, + 0x00001fae, 0x00001fa6, 0x000001c8, 0x000001c9, + 0x00001cae, 0x000010ee, 0x00000421, 0x00000441, + 0x000118a6, 0x000118c6, 0x00000466, 0x00000467, + 0x00001f89, 0x00001f81, 0x000118ac, 0x000118cc, + 0x000013a3, 0x0000ab73, 0x00001ede, 0x00001edf, + 0x000013ee, 0x0000abbe, 0x000118a9, 0x000118c9, + 0x00001ec0, 0x00001ec1, 0x0001e904, 0x0001e926, + 0x000013b4, 0x0000ab84, 0x000118b0, 0x000118d0, + 0x00001e14, 0x00001e15, 0x00002c0e, 0x00002c3e, + 0x00016eac, 0x00016ec7, 0x000118a2, 0x000118c2, + 0x00001ff8, 0x00001f78, 0x00010589, 0x000105b0, + 0x000013be, 0x0000ab8e, 0x000001bc, 0x000001bd, + 0x00000045, 0x00000065, 0x00010d51, 0x00010d71, + 0x0000ff34, 0x0000ff54, 0x00000208, 0x00000209, + 0x00001f68, 0x00001f60, 0x00010cac, 0x00010cec, + 0x0000a7a0, 0x0000a7a1, 0x0000054f, 0x0000057f, + 0x00000197, 0x00000268, 0x00010ca6, 0x00010ce6, + 0x000024c6, 0x000024e0, 0x00000210, 0x00000211, + 0x000010b8, 0x00002d18, 0x0001058d, 0x000105b4, + 0x0000a738, 0x0000a739, 0x0000020a, 0x0000020b, + 0x00001e46, 0x00001e47, 0x00000184, 0x00000185, + 0x0000a722, 0x0000a723, 0x00002ca8, 0x00002ca9, + 0x00001c94, 0x000010d4, 0x0000021a, 0x0000021b, + 0x00002cac, 0x00002cad, 0x00000141, 0x00000142, + 0x000004ee, 0x000004ef, 0x000003aa, 0x000003ca, + 0x00001cbf, 0x000010ff, 0x00000172, 0x00000173, + 0x000004c0, 0x000004cf, 0x00010580, 0x000105a7, + 0x0000a764, 0x0000a765, 0x000001f1, 0x000001f3, + 0x000104b0, 0x000104d8, 0x00010581, 0x000105a8, + 0x000013a7, 0x0000ab77, 0x00000100, 0x00000101, + 0x00001f0e, 0x00001f06, 0x000004cb, 0x000004cc, + 0x000010aa, 0x00002d0a, 0x00000047, 0x00000067, + 0x00000425, 0x00000445, 0x00000230, 0x00000231, + 0x00001ca2, 0x000010e2, 0x000004fa, 0x000004fb, + 0x00010594, 0x000105bb, 0x00000116, 0x00000117, + 0x00016e4d, 0x00016e6d, 0x0000004c, 0x0000006c, + 0x00000506, 0x00000507, 0x000104c6, 0x000104ee, + 0x000010b2, 0x00002d12, 0x000000cd, 0x000000ed, + 0x00000410, 0x00000430, 0x00001fe9, 0x00001fe1, + 0x0000018e, 0x000001dd, 0x0000a76c, 0x0000a76d, + 0x00000533, 0x00000563, 0x000003f9, 0x000003f2, + 0x000024c8, 0x000024e2, 0x0000a736, 0x0000a737, + 0x000004c3, 0x000004c4, 0x00001f9e, 0x00001f96, + 0x000024c0, 0x000024da, 0x00001e7c, 0x00001e7d, + 0x00010410, 0x00010438, 0x000010c5, 0x00002d25, + 0x00000550, 0x00000580, 0x0001e91e, 0x0001e940, + 0x0001040f, 0x00010437, 0x00001eae, 0x00001eaf, + 0x0001e902, 0x0001e924, 0x00001ffb, 0x00001f7d, + 0x0000042b, 0x0000044b, 0x00001caf, 0x000010ef, + 0x000001ca, 0x000001cc, 0x00001fbb, 0x00001f71, + 0x000118b4, 0x000118d4, 0x00001e18, 0x00001e19, + 0x00002c7e, 0x0000023f, 0x000013f5, 0x000013fd, + 0x000118b3, 0x000118d3, 0x00001ecc, 0x00001ecd, + 0x00010d53, 0x00010d73, 0x00016eb0, 0x00016ecb, + 0x0000039d, 0x000003bd, 0x00001e04, 0x00001e05, + 0x00010587, 0x000105ae, 0x0001e903, 0x0001e925, + 0x00002c23, 0x00002c53, 0x00010573, 0x0001059a, + 0x0001e90c, 0x0001e92e, 0x000013ae, 0x0000ab7e, + 0x000003a5, 0x000003c5, 0x000013e7, 0x0000abb7, + 0x0000014a, 0x0000014b, 0x00002126, 0x000003c9, + 0x00001e74, 0x00001e75, 0x00010591, 0x000105b8, + 0x00016e53, 0x00016e73, 0x000013b7, 0x0000ab87, + 0x000104c5, 0x000104ed, 0x000104c9, 0x000104f1, + 0x0000050a, 0x0000050b, 0x0000a792, 0x0000a793, + 0x00002ce0, 0x00002ce1, 0x00000108, 0x00000109, + 0x00010c89, 0x00010cc9, 0x0000a7f5, 0x0000a7f6, + 0x0000023d, 0x0000019a, 0x00001c96, 0x000010d6, + 0x00002c0b, 0x00002c3b, 0x000013db, 0x0000abab, + 0x00002ca6, 0x00002ca7, 0x00001c91, 0x000010d1, + 0x00010c93, 0x00010cd3, 0x000010c2, 0x00002d22, + 0x000001ee, 0x000001ef, 0x0001058c, 0x000105b3, + 0x0001e916, 0x0001e938, 0x00002cc8, 0x00002cc9, + 0x00000168, 0x00000169, 0x00001e88, 0x00001e89, + 0x0000216f, 0x0000217f, 0x0000a73c, 0x0000a73d, + 0x000001db, 0x000001dc, 0x0000048c, 0x0000048d, + 0x0000038c, 0x000003cc, 0x000013ed, 0x0000abbd, + 0x00000152, 0x00000153, 0x0001041c, 0x00010444, + 0x000001a6, 0x00000280, 0x000013e4, 0x0000abb4, + 0x000001b2, 0x0000028b, 0x000013ac, 0x0000ab7c, + 0x00002c98, 0x00002c99, 0x000010b4, 0x00002d14, + 0x0000015e, 0x0000015f, 0x00000554, 0x00000584, + 0x00002c7f, 0x00000240, 0x00002c0c, 0x00002c3c, + 0x00000056, 0x00000076, 0x00001fcb, 0x00001f75, + 0x000000c7, 0x000000e7, 0x00010d5d, 0x00010d7d }; static const unsigned _uccase_title_g_size = 35; @@ -4359,828 +4431,843 @@ static const unsigned _uccase_title_table[] = { 0x00001f93, 0x00001f9b }; -static const unsigned _uccase_fold_g_size = 293; +static const unsigned _uccase_fold_g_size = 298; static const short _uccase_fold_g[] = { - 3432, 570, 1, 102, 547, 152, 440, 46, - 546, 468, 6, 769, 1, 581, -753, 2134, - 130, 743, 372, 238, 1, 829, 1, 1007, - 158, 1146, 174, 1077, 760, 1041, 1091, 567, - 1591, 817, 630, 711, 225, 1808, 121, 2595, - 2831, 363, 601, 2677, 86, 1013, 12, 186, - 10, 201, 544, 2, 252, 4, 666, 1, - -297, 131, 173, 811, 461, 2, 355, 1, - 478, 8, 1544, 16, 531, 61, 1109, 1061, - 518, 926, 1380, 875, 1302, 1996, 109, 13793, - 119, -916, -870, 401, 2098, 551, 546, 83, - 521, 3, 512, 533, 167, 4, 20, 252, - 87, -1534, 51, -835, 129, 781, 323, 428, - 1, 397, 1, 1662, 78, 1120, 32, 232, - 59, 1673, 250, 976, 1486, 1526, 718, 2892, - 2869, 1306, 1, -1412, 2428, 5542, 519, 7772, - 459, 590, 1, 143, 2, 484, 247, 9, - 514, 1, 704, 7, -591, 744, 143, 168, - 266, 368, 913, 1, 86, 1, 1012, 140, - 796, 48, 842, 1049, 3775, 815, 714, 1421, - 182, 2899, 4758, 2493, 1590, -1189, 3441, 867, - 538, 520, 605, 4, 635, 249, 220, 516, - 166, 183, 6, 583, 63, 706, 121, 633, - 271, 1577, 5, 274, 1, 2442, 1, 535, - 413, 307, 787, 192, 857, 3329, 375, 1223, - 131, 790, 1785, 4374, 2147, 2028, 2317, -1449, - 4982, 4893, 325, 7004, 93, 256, 108, 513, - 1, 182, 2, 116, 390, 1, 322, 2182, - 313, 554, 15407, 12, 63, 22, 404, 1, - 405, 8, 3674, 203, 880, 581, 803, 214, - 2925, 191, 2747, 556, 1638, 2864, 2687, 2635, - 2450, 1845, 445, 2093, 4633, 52, 676, 1, - 536, 1, 4, 1, 5, 340, 1, 226, - 4, -151, -782, 502, 283, 75, 15, 300, - 16, 539, 1, 1128, 3, 1625, 1138, 1245, - 391, 2421, 1347, 1362, 1439, 136, 1598, 212, - 3221, 2388, 1158, 3173, 666 + 1, 400, 2, 1637, 933, 1790, 18, 1934, + 361, 1515, 1, 459, 1040, 1561, 90, 3805, + 669, 1434, 1, 505, 387, 1581, 273, 1308, + 24, 164, 1, 1334, 1323, 1895, 675, -1011, + 32, 3373, 1, 1069, 166, 272, 338, 8497, + 196, 1451, 266, 1106, 27, 1596, 535, -780, + 222, 944, 1114, 191, 51, 32, 732, 1298, + 472, 710, 38, 1116, 136, 1, 344, 1485, + 425, 637, 697, 151, 89, 1, 3, -1475, + 524, 596, 2993, 3024, 170, 9, 3, 14122, + 1183, 3845, 1269, 715, 67, 93, 6, -626, + 26, 653, 425, 1349, 10, 390, 8, 17497, + 1, -406, 1157, 1669, 28, -103, 1, 8908, + 1, 581, 1166, 1550, 1, 1327, 50, 1446, + 1, 370, 3278, 1168, 210, -1251, 394, 1217, + 1, -186, 747, 1383, 3229, -1174, 110, 619, + 1, 1507, 334, 1866, 257, 1062, 36, 78, + 38, 1092, 24, 1549, 464, 1704, 53, 569, + 77, 58, 1, 1387, 3244, -739, 127, 347, + 659, 1146, 5, 1, 16327, -1575, 524, 603, + 3461, 76, 26, 1, 33, 2536, 87, 538, + 266, 10827, 90, 40, 402, 1060, 1096, 266, + 1668, 1431, 11, 7, 857, 6023, 873, 2019, + 1254, 177, 70, 223, 1, -454, 30, 2530, + 545, 848, 124, 999, 2, 1169, 6, -208, + 788, 2073, 24, -72, 395, 218, 1, 152, + 618, 1550, 15, 1544, 641, 1186, 1, 359, + 6367, 348, 52, 1218, 731, 1457, 1, 692, + 10945, 1561, 604, -1124, 85, 179, 1, 717, + 168, 4645, 592, 1028, 439, 1155, 320, 829, + 322, 1896, 515, -853, 83, 1580, 6713, 339, + 179, 55, 1055, 1768, 900, 1001, 1494, 218, + 146, 1, 603, 1474, 17, 527, 4, 889, + 160, 48, 367, -1477, 925, 924, -1214, 4802, + 90, 1, 3, 6489, 1055, 167, 1483, 99, + 26, 3, 3, -699, 737, 3023, 94, 13291, + 67, 744, 1, 8829, 42, 1558, 933, 1449, + 66, -1368 }; -static const unsigned _uccase_fold_table_size = 1557; +static const unsigned _uccase_fold_table_size = 1585; static const unsigned _uccase_fold_table[] = { - 0x000024b9, 0x000024d3, 0x0000aba6, 0x000013d6, - 0x0000ab94, 0x000013c4, 0x00000045, 0x00000065, - 0x0000018e, 0x000001dd, 0x00001e10, 0x00001e11, - 0x000004ba, 0x000004bb, 0x000003e6, 0x000003e7, - 0x000010a3, 0x00002d03, 0x00000224, 0x00000225, - 0x00010c8b, 0x00010ccb, 0x00001fe9, 0x00001fe1, - 0x00001e5e, 0x00001e5f, 0x0000ff36, 0x0000ff56, - 0x0000a754, 0x0000a755, 0x0000020c, 0x0000020d, - 0x0000a642, 0x0000a643, 0x00001eaa, 0x00001eab, - 0x00001ed8, 0x00001ed9, 0x0000023e, 0x00002c66, - 0x00001c9b, 0x000010db, 0x00000187, 0x00000188, - 0x000010a2, 0x00002d02, 0x00001fbe, 0x000003b9, - 0x000004e0, 0x000004e1, 0x00001e12, 0x00001e13, - 0x000001f8, 0x000001f9, 0x000000c3, 0x000000e3, - 0x00001f8f, 0x020001f4, 0x00001e00, 0x00001e01, - 0x00001e1a, 0x00001e1b, 0x00010c8c, 0x00010ccc, - 0x0000a750, 0x0000a751, 0x000010a0, 0x00002d00, - 0x00002c80, 0x00002c81, 0x0000ff33, 0x0000ff53, - 0x00001c9a, 0x000010da, 0x00001fcc, 0x0200027a, - 0x0000011c, 0x0000011d, 0x0000053d, 0x0000056d, - 0x0000ff2b, 0x0000ff4b, 0x00001f2e, 0x00001f26, - 0x000000d4, 0x000000f4, 0x00010cb2, 0x00010cf2, - 0x000001b2, 0x0000028b, 0x0000a72a, 0x0000a72b, - 0x0000abb8, 0x000013e8, 0x0000ab91, 0x000013c1, - 0x00010c8d, 0x00010ccd, 0x00001ea8, 0x00001ea9, - 0x0000041b, 0x0000043b, 0x0000a728, 0x0000a729, - 0x00001e38, 0x00001e39, 0x000003d8, 0x000003d9, - 0x0000a77b, 0x0000a77c, 0x0000a792, 0x0000a793, - 0x00001e02, 0x00001e03, 0x0000a666, 0x0000a667, - 0x00001ed0, 0x00001ed1, 0x00000466, 0x00000467, - 0x00001fc8, 0x00001f72, 0x00000152, 0x00000153, - 0x000001f6, 0x00000195, 0x00010c89, 0x00010cc9, - 0x0000aba7, 0x000013d7, 0x000104c3, 0x000104eb, - 0x0000fb00, 0x020002b1, 0x000001ec, 0x000001ed, - 0x0000a79c, 0x0000a79d, 0x00000538, 0x00000568, - 0x00001e26, 0x00001e27, 0x00001e9b, 0x00001e61, - 0x0000a779, 0x0000a77a, 0x0000a76c, 0x0000a76d, - 0x00000421, 0x00000441, 0x0000a644, 0x0000a645, - 0x0000041a, 0x0000043a, 0x0001e901, 0x0001e923, - 0x0000a734, 0x0000a735, 0x00000141, 0x00000142, - 0x0000a680, 0x0000a681, 0x00001f08, 0x00001f00, - 0x000004a8, 0x000004a9, 0x0000a7b1, 0x00000287, - 0x0000053c, 0x0000056c, 0x0001058c, 0x000105b3, - 0x000000c2, 0x000000e2, 0x00001fa0, 0x02000227, - 0x000118ab, 0x000118cb, 0x00001c86, 0x0000044a, - 0x00000222, 0x00000223, 0x0000a7be, 0x0000a7bf, - 0x00001f4b, 0x00001f43, 0x00001e6a, 0x00001e6b, - 0x000003a9, 0x000003c9, 0x00016e41, 0x00016e61, - 0x000001b1, 0x0000028a, 0x00000134, 0x00000135, - 0x0000a68c, 0x0000a68d, 0x00001ef6, 0x00001ef7, - 0x00001f6b, 0x00001f63, 0x000001cb, 0x000001cc, - 0x00016e5f, 0x00016e7f, 0x0000a744, 0x0000a745, - 0x0000ab80, 0x000013b0, 0x000004ea, 0x000004eb, - 0x00000197, 0x00000268, 0x0000013f, 0x00000140, - 0x0000022c, 0x0000022d, 0x00001f89, 0x020001e2, - 0x00001fd8, 0x00001fd0, 0x000003a0, 0x000003c0, - 0x00001ee0, 0x00001ee1, 0x00002167, 0x00002177, - 0x000000d3, 0x000000f3, 0x00002c86, 0x00002c87, - 0x0000ff39, 0x0000ff59, 0x0000ab74, 0x000013a4, - 0x0000aba3, 0x000013d3, 0x000013f8, 0x000013f0, - 0x0000018b, 0x0000018c, 0x000010b5, 0x00002d15, - 0x00001f3a, 0x00001f32, 0x00001fa3, 0x02000230, - 0x0001e917, 0x0001e939, 0x00002c0d, 0x00002c3d, - 0x0000ff2c, 0x0000ff4c, 0x0000abb6, 0x000013e6, - 0x0001057f, 0x000105a6, 0x0000039e, 0x000003be, - 0x00010586, 0x000105ad, 0x000010be, 0x00002d1e, - 0x00001fc9, 0x00001f73, 0x00001e3a, 0x00001e3b, - 0x0000aba5, 0x000013d5, 0x00001ff8, 0x00001f78, - 0x0001e919, 0x0001e93b, 0x0000010e, 0x0000010f, - 0x00002cc8, 0x00002cc9, 0x0000ab88, 0x000013b8, - 0x00000470, 0x00000471, 0x00000394, 0x000003b4, - 0x00000156, 0x00000157, 0x000024ba, 0x000024d4, - 0x00000043, 0x00000063, 0x000004be, 0x000004bf, - 0x00000130, 0x02000192, 0x0001e911, 0x0001e933, - 0x00000132, 0x00000133, 0x0000a780, 0x0000a781, - 0x00001fb7, 0x03000263, 0x000001cd, 0x000001ce, - 0x000003c2, 0x000003c3, 0x00010583, 0x000105aa, - 0x00001cb5, 0x000010f5, 0x000004cd, 0x000004ce, - 0x0000a654, 0x0000a655, 0x00000412, 0x00000432, - 0x00001cb6, 0x000010f6, 0x00001c90, 0x000010d0, - 0x00010411, 0x00010439, 0x0000a7d6, 0x0000a7d7, - 0x00001f0a, 0x00001f02, 0x0000ab95, 0x000013c5, - 0x0000013d, 0x0000013e, 0x000001e4, 0x000001e5, - 0x000001de, 0x000001df, 0x0000004f, 0x0000006f, - 0x00010417, 0x0001043f, 0x00001ee2, 0x00001ee3, - 0x00002c0c, 0x00002c3c, 0x00000226, 0x00000227, - 0x0000216d, 0x0000217d, 0x00001f49, 0x00001f41, - 0x00001c9f, 0x000010df, 0x000118ac, 0x000118cc, - 0x00000050, 0x00000070, 0x000024b6, 0x000024d0, - 0x0000a64c, 0x0000a64d, 0x000118a9, 0x000118c9, - 0x00001e94, 0x00001e95, 0x00001e08, 0x00001e09, - 0x00010ca5, 0x00010ce5, 0x00000179, 0x0000017a, - 0x00001ca2, 0x000010e2, 0x00010c87, 0x00010cc7, - 0x000004e2, 0x000004e3, 0x00001c98, 0x000010d8, - 0x000001c8, 0x000001c9, 0x00001c9e, 0x000010de, - 0x000001c5, 0x000001c6, 0x00001fda, 0x00001f76, - 0x00001c95, 0x000010d5, 0x00001cb8, 0x000010f8, - 0x000024c6, 0x000024e0, 0x00000191, 0x00000192, - 0x00002c90, 0x00002c91, 0x0000ff2d, 0x0000ff4d, - 0x00010c9e, 0x00010cde, 0x0000abb5, 0x000013e5, - 0x0000aba1, 0x000013d1, 0x00002cde, 0x00002cdf, - 0x00001ee4, 0x00001ee5, 0x00001f86, 0x020001d9, - 0x000004c0, 0x000004cf, 0x00000370, 0x00000371, - 0x0000041f, 0x0000043f, 0x0000017d, 0x0000017e, - 0x000024c5, 0x000024df, 0x00010424, 0x0001044c, - 0x0000a7da, 0x0000a7db, 0x0000004c, 0x0000006c, - 0x00000041, 0x00000061, 0x000104b0, 0x000104d8, - 0x00001e36, 0x00001e37, 0x000003da, 0x000003db, - 0x000004b8, 0x000004b9, 0x00001c81, 0x00000434, - 0x00000118, 0x00000119, 0x0000a668, 0x0000a669, - 0x00010592, 0x000105b9, 0x000004ec, 0x000004ed, - 0x00010c96, 0x00010cd6, 0x0000014c, 0x0000014d, - 0x0000016a, 0x0000016b, 0x000000ca, 0x000000ea, - 0x000004b6, 0x000004b7, 0x0000054f, 0x0000057f, - 0x0000ab7b, 0x000013ab, 0x00000587, 0x020001a3, - 0x00010ca3, 0x00010ce3, 0x00001fb4, 0x0200025d, - 0x00001f29, 0x00001f21, 0x000003f7, 0x000003f8, - 0x00002c69, 0x00002c6a, 0x0000a7b8, 0x0000a7b9, - 0x000010c1, 0x00002d21, 0x00002cb2, 0x00002cb3, - 0x0000042b, 0x0000044b, 0x0001e903, 0x0001e925, - 0x0001041d, 0x00010445, 0x000118b8, 0x000118d8, - 0x00010595, 0x000105bc, 0x0000ff24, 0x0000ff44, - 0x000004aa, 0x000004ab, 0x00010c80, 0x00010cc0, - 0x00000196, 0x00000269, 0x000024ca, 0x000024e4, - 0x0000a738, 0x0000a739, 0x00001fa7, 0x0200023c, - 0x00001e99, 0x020001af, 0x00000243, 0x00000180, - 0x000104cb, 0x000104f3, 0x00010c91, 0x00010cd1, - 0x0000ff30, 0x0000ff50, 0x00001fb6, 0x02000260, - 0x00000400, 0x00000450, 0x0000a76a, 0x0000a76b, - 0x00010c95, 0x00010cd5, 0x0000a652, 0x0000a653, - 0x00002ce0, 0x00002ce1, 0x00001ca0, 0x000010e0, - 0x0000a736, 0x0000a737, 0x00000372, 0x00000373, - 0x000000c6, 0x000000e6, 0x000104b1, 0x000104d9, - 0x00001fb2, 0x02000257, 0x000004f4, 0x000004f5, - 0x000010a4, 0x00002d04, 0x00001e7e, 0x00001e7f, - 0x0000041d, 0x0000043d, 0x0000016c, 0x0000016d, - 0x00002cd8, 0x00002cd9, 0x00001fab, 0x02000248, - 0x0001e906, 0x0001e928, 0x0001e902, 0x0001e924, - 0x0000a768, 0x0000a769, 0x0000a7ac, 0x00000261, - 0x00001e98, 0x020001ac, 0x0000abbc, 0x000013ec, - 0x0000fb17, 0x020002d4, 0x00010d59, 0x00010d79, - 0x00002cd6, 0x00002cd7, 0x00001eba, 0x00001ebb, - 0x00001ee6, 0x00001ee7, 0x000004d0, 0x000004d1, - 0x00001cb7, 0x000010f7, 0x000118b3, 0x000118d3, - 0x0000a724, 0x0000a725, 0x0000a7c2, 0x0000a7c3, - 0x0000051c, 0x0000051d, 0x00000392, 0x000003b2, - 0x00010d64, 0x00010d84, 0x00000056, 0x00000076, - 0x00001fcb, 0x00001f75, 0x00002161, 0x00002171, - 0x00001e8c, 0x00001e8d, 0x000001cf, 0x000001d0, - 0x00010576, 0x0001059d, 0x0000015a, 0x0000015b, - 0x00002cca, 0x00002ccb, 0x00001e82, 0x00001e83, - 0x00000472, 0x00000473, 0x00001c88, 0x0000a64b, - 0x00000158, 0x00000159, 0x00010c84, 0x00010cc4, - 0x00001f2c, 0x00001f24, 0x00001f68, 0x00001f60, - 0x000003b0, 0x0300019f, 0x000104be, 0x000104e6, - 0x00000147, 0x00000148, 0x0000a78d, 0x00000265, - 0x00002c20, 0x00002c50, 0x00001ca6, 0x000010e6, - 0x0000abb3, 0x000013e3, 0x00010413, 0x0001043b, - 0x00000395, 0x000003b5, 0x00010418, 0x00010440, - 0x0000a656, 0x0000a657, 0x00000414, 0x00000434, - 0x00000462, 0x00000463, 0x000003ff, 0x0000037d, - 0x00000534, 0x00000564, 0x00010d62, 0x00010d82, - 0x00001fba, 0x00001f70, 0x000118a4, 0x000118c4, - 0x00010c8f, 0x00010ccf, 0x00000128, 0x00000129, - 0x00001c87, 0x00000463, 0x00001f5d, 0x00001f55, - 0x00001f9b, 0x02000218, 0x00010581, 0x000105a8, - 0x000001f1, 0x000001f3, 0x00000228, 0x00000229, - 0x000104cc, 0x000104f4, 0x00002c11, 0x00002c41, - 0x00001e9a, 0x020001b2, 0x0000048e, 0x0000048f, - 0x000104c6, 0x000104ee, 0x0000ff32, 0x0000ff52, - 0x00002c0e, 0x00002c3e, 0x000010bd, 0x00002d1d, - 0x00001e62, 0x00001e63, 0x00000547, 0x00000577, - 0x0000abab, 0x000013db, 0x00016e49, 0x00016e69, - 0x00016e54, 0x00016e74, 0x00016e40, 0x00016e60, - 0x000004e4, 0x000004e5, 0x000024c3, 0x000024dd, - 0x00000102, 0x00000103, 0x00000214, 0x00000215, - 0x00001f93, 0x02000200, 0x0000050a, 0x0000050b, - 0x00001e5c, 0x00001e5d, 0x000024cf, 0x000024e9, - 0x00002169, 0x00002179, 0x0000005a, 0x0000007a, - 0x00002c92, 0x00002c93, 0x00001e90, 0x00001e91, - 0x0000ab78, 0x000013a8, 0x00001f9a, 0x02000215, - 0x00000120, 0x00000121, 0x00000168, 0x00000169, - 0x00001fbc, 0x02000267, 0x0000a7c4, 0x0000a794, - 0x00000399, 0x000003b9, 0x00001e40, 0x00001e41, - 0x000004fe, 0x000004ff, 0x0000a7aa, 0x00000266, - 0x0000abbe, 0x000013ee, 0x00001c99, 0x000010d9, - 0x000024cd, 0x000024e7, 0x000104bc, 0x000104e4, - 0x00010570, 0x00010597, 0x000000c1, 0x000000e1, - 0x00002c82, 0x00002c83, 0x000003dc, 0x000003dd, - 0x00000424, 0x00000444, 0x0000aba2, 0x000013d2, - 0x00000506, 0x00000507, 0x0000ff2f, 0x0000ff4f, - 0x00001f6d, 0x00001f65, 0x000118af, 0x000118cf, - 0x000003e8, 0x000003e9, 0x0000015e, 0x0000015f, - 0x0000012a, 0x0000012b, 0x0000004b, 0x0000006b, - 0x00002c2b, 0x00002c5b, 0x00000536, 0x00000566, - 0x00010d5f, 0x00010d7f, 0x000001f0, 0x02000198, - 0x000000d2, 0x000000f2, 0x00001eec, 0x00001eed, - 0x00001e2a, 0x00001e2b, 0x00001e04, 0x00001e05, - 0x00001cb2, 0x000010f2, 0x00010c88, 0x00010cc8, - 0x00002ce2, 0x00002ce3, 0x00016e48, 0x00016e68, - 0x00000406, 0x00000456, 0x0001e905, 0x0001e927, - 0x0000abb7, 0x000013e7, 0x00001ca7, 0x000010e7, - 0x00016e56, 0x00016e76, 0x00001ff2, 0x0200029e, - 0x000004ac, 0x000004ad, 0x00010cad, 0x00010ced, - 0x00010cac, 0x00010cec, 0x00016e46, 0x00016e66, - 0x00001f5b, 0x00001f53, 0x0000abb0, 0x000013e0, - 0x00001e4e, 0x00001e4f, 0x000001b5, 0x000001b6, - 0x0000022e, 0x0000022f, 0x0000a74c, 0x0000a74d, - 0x000104b2, 0x000104da, 0x00001ca3, 0x000010e3, - 0x00000402, 0x00000452, 0x0000a732, 0x0000a733, - 0x00010d51, 0x00010d71, 0x000000d0, 0x000000f0, - 0x0000a690, 0x0000a691, 0x00001efa, 0x00001efb, - 0x0000aba4, 0x000013d4, 0x0000a7ad, 0x0000026c, - 0x00016e5d, 0x00016e7d, 0x0001058e, 0x000105b5, - 0x0000ab84, 0x000013b4, 0x0001040c, 0x00010434, - 0x00001e56, 0x00001e57, 0x0000017b, 0x0000017c, - 0x00000212, 0x00000213, 0x00001f6a, 0x00001f62, - 0x00001cb3, 0x000010f3, 0x000003a4, 0x000003c4, - 0x0000037f, 0x000003f3, 0x000118a8, 0x000118c8, - 0x00000420, 0x00000440, 0x00002cda, 0x00002cdb, - 0x0000ab9e, 0x000013ce, 0x00000492, 0x00000493, - 0x00010c9c, 0x00010cdc, 0x0000fb04, 0x030002be, - 0x00016e4f, 0x00016e6f, 0x0000a646, 0x0000a647, - 0x0000ab73, 0x000013a3, 0x000004d2, 0x000004d3, - 0x000003ee, 0x000003ef, 0x000001b8, 0x000001b9, - 0x00002132, 0x0000214e, 0x00001f84, 0x020001d3, - 0x00000549, 0x00000579, 0x00001fea, 0x00001f7a, - 0x0000fb15, 0x020002ce, 0x00002166, 0x00002176, - 0x0000a7ae, 0x0000026a, 0x00000428, 0x00000448, - 0x00001ea4, 0x00001ea5, 0x00001c84, 0x00000442, - 0x000004c5, 0x000004c6, 0x000000db, 0x000000fb, - 0x00002ccc, 0x00002ccd, 0x00001ed4, 0x00001ed5, - 0x00000474, 0x00000475, 0x00000245, 0x0000028c, - 0x00010cb0, 0x00010cf0, 0x00002162, 0x00002172, - 0x00001f0c, 0x00001f04, 0x00001f6c, 0x00001f64, - 0x0000a7cc, 0x0000a7cd, 0x00000391, 0x000003b1, - 0x0001e91b, 0x0001e93d, 0x00010d58, 0x00010d78, - 0x00002c22, 0x00002c52, 0x00001e18, 0x00001e19, - 0x00001e76, 0x00001e77, 0x00016e58, 0x00016e78, - 0x0000020a, 0x0000020b, 0x0001041f, 0x00010447, - 0x0000a658, 0x0000a659, 0x00001ec2, 0x00001ec3, - 0x00002183, 0x00002184, 0x000000d1, 0x000000f1, - 0x0000014e, 0x0000014f, 0x000004c3, 0x000004c4, - 0x00001f0b, 0x00001f03, 0x0000a726, 0x0000a727, - 0x00001ca8, 0x000010e8, 0x00001e7a, 0x00001e7b, - 0x0000ab99, 0x000013c9, 0x00000053, 0x00000073, - 0x00001fa4, 0x02000233, 0x00001fa1, 0x0200022a, - 0x00001eac, 0x00001ead, 0x00010d57, 0x00010d77, - 0x000104b4, 0x000104dc, 0x0001040d, 0x00010435, - 0x00000405, 0x00000455, 0x00001edc, 0x00001edd, - 0x000118bb, 0x000118db, 0x000001d3, 0x000001d4, - 0x00002c05, 0x00002c35, 0x00002cf2, 0x00002cf3, - 0x0000041e, 0x0000043e, 0x00001f6f, 0x00001f67, - 0x0000ab71, 0x000013a1, 0x00016e5b, 0x00016e7b, - 0x000104d2, 0x000104fa, 0x00001f4d, 0x00001f45, - 0x00001ffc, 0x020002ae, 0x00010421, 0x00010449, - 0x000001ca, 0x000001cc, 0x0000021e, 0x0000021f, - 0x00001f95, 0x02000206, 0x00001fdb, 0x00001f77, - 0x00001eca, 0x00001ecb, 0x00001fc4, 0x02000270, - 0x00010578, 0x0001059f, 0x000000de, 0x000000fe, - 0x00002c94, 0x00002c95, 0x00000554, 0x00000584, - 0x000118ae, 0x000118ce, 0x0000aba0, 0x000013d0, - 0x00000122, 0x00000123, 0x0000a7b3, 0x0000ab53, - 0x0000040d, 0x0000045d, 0x0000048a, 0x0000048b, - 0x00001fac, 0x0200024b, 0x00000248, 0x00000249, - 0x00000166, 0x00000167, 0x00000541, 0x00000571, - 0x00001f83, 0x020001d0, 0x00002c26, 0x00002c56, - 0x00001e72, 0x00001e73, 0x000104bd, 0x000104e5, - 0x0000a78b, 0x0000a78c, 0x000000c5, 0x000000e5, - 0x00000522, 0x00000523, 0x000003de, 0x000003df, - 0x00001c82, 0x0000043e, 0x0000ab9d, 0x000013cd, - 0x00000116, 0x00000117, 0x0000a66c, 0x0000a66d, - 0x00001ed6, 0x00001ed7, 0x0000047e, 0x0000047f, - 0x00000198, 0x00000199, 0x000118a7, 0x000118c7, - 0x000001ae, 0x00000288, 0x00000047, 0x00000067, - 0x00001f92, 0x020001fd, 0x0000050c, 0x0000050d, - 0x00000396, 0x000003b6, 0x000001f2, 0x000001f3, - 0x00002c25, 0x00002c55, 0x000000b5, 0x000003bc, - 0x00001e97, 0x020001a9, 0x00001e4c, 0x00001e4d, - 0x00000393, 0x000003b3, 0x00010caa, 0x00010cea, - 0x000118bf, 0x000118df, 0x00002cb4, 0x00002cb5, - 0x00001ec0, 0x00001ec1, 0x0001e907, 0x0001e929, - 0x0001e918, 0x0001e93a, 0x0000fb01, 0x020002b4, - 0x00002c08, 0x00002c38, 0x000000ce, 0x000000ee, - 0x000004ae, 0x000004af, 0x00001cac, 0x000010ec, - 0x00000194, 0x00000263, 0x000001e6, 0x000001e7, - 0x0000a73c, 0x0000a73d, 0x00001fa6, 0x02000239, - 0x0000054e, 0x0000057e, 0x0000ff2e, 0x0000ff4e, - 0x000003a1, 0x000003c1, 0x000004c7, 0x000004c8, - 0x00001f87, 0x020001dc, 0x00001efe, 0x00001eff, - 0x00000404, 0x00000454, 0x00001f2d, 0x00001f25, - 0x00002c2d, 0x00002c5d, 0x00002caa, 0x00002cab, - 0x0000a692, 0x0000a693, 0x00000200, 0x00000201, - 0x0000048c, 0x0000048d, 0x00010d65, 0x00010d85, - 0x00000186, 0x00000254, 0x00010ca9, 0x00010ce9, - 0x0000053f, 0x0000056f, 0x000001d1, 0x000001d2, - 0x00010401, 0x00010429, 0x00010c9a, 0x00010cda, - 0x000024c9, 0x000024e3, 0x00001f91, 0x020001fa, - 0x00000504, 0x00000505, 0x000003a6, 0x000003c6, - 0x00001cab, 0x000010eb, 0x0000216f, 0x0000217f, - 0x000024b7, 0x000024d1, 0x00002c9e, 0x00002c9f, - 0x00001e66, 0x00001e67, 0x0000a7dc, 0x0000019b, - 0x0000ab9c, 0x000013cc, 0x00016e57, 0x00016e77, - 0x00016e4b, 0x00016e6b, 0x00001f0f, 0x00001f07, - 0x00000422, 0x00000442, 0x000004d4, 0x000004d5, - 0x0000abaf, 0x000013df, 0x00000508, 0x00000509, - 0x0000a7b6, 0x0000a7b7, 0x00001f80, 0x020001c7, - 0x000004bc, 0x000004bd, 0x00001e2c, 0x00001e2d, - 0x00001ea6, 0x00001ea7, 0x00010d54, 0x00010d74, - 0x00001f99, 0x02000212, 0x000004f0, 0x000004f1, - 0x0000a786, 0x0000a787, 0x0001041e, 0x00010446, - 0x00001c80, 0x00000432, 0x00000551, 0x00000581, - 0x00002cce, 0x00002ccf, 0x00001ed2, 0x00001ed3, - 0x00000476, 0x00000477, 0x000118a0, 0x000118c0, - 0x00001e0e, 0x00001e0f, 0x00010589, 0x000105b0, - 0x00002c12, 0x00002c42, 0x0000042d, 0x0000044d, - 0x000104ce, 0x000104f6, 0x00001e0c, 0x00001e0d, - 0x00001ca1, 0x000010e1, 0x000010c7, 0x00002d27, - 0x00002c24, 0x00002c54, 0x00000552, 0x00000582, - 0x000010cd, 0x00002d2d, 0x0000ab77, 0x000013a7, - 0x00010cae, 0x00010cee, 0x000010ac, 0x00002d0c, - 0x0000052a, 0x0000052b, 0x00000418, 0x00000438, - 0x0000a764, 0x0000a765, 0x0001e904, 0x0001e926, - 0x0000053a, 0x0000056a, 0x000024bb, 0x000024d5, - 0x00001fe6, 0x02000297, 0x0000ab90, 0x000013c0, - 0x000010a6, 0x00002d06, 0x00001e4a, 0x00001e4b, - 0x000118bc, 0x000118dc, 0x0000a7b2, 0x0000029d, - 0x00001fa2, 0x0200022d, 0x00000546, 0x00000576, - 0x000003f1, 0x000003c1, 0x00002c75, 0x00002c76, - 0x000104bb, 0x000104e3, 0x000010c0, 0x00002d20, - 0x00001e64, 0x00001e65, 0x00001eb0, 0x00001eb1, - 0x000003a7, 0x000003c7, 0x00010d56, 0x00010d76, - 0x00002ca2, 0x00002ca3, 0x00000537, 0x00000567, - 0x0001057a, 0x000105a1, 0x0000049c, 0x0000049d, - 0x00002c0f, 0x00002c3f, 0x0000017f, 0x00000073, - 0x00002cdc, 0x00002cdd, 0x00010c92, 0x00010cd2, - 0x000004e8, 0x000004e9, 0x00001f8e, 0x020001f1, - 0x00002c27, 0x00002c57, 0x0000a782, 0x0000a783, - 0x00001f97, 0x0200020c, 0x00001f3d, 0x00001f35, - 0x0000052e, 0x0000052f, 0x000010a5, 0x00002d05, - 0x00000044, 0x00000064, 0x000000dd, 0x000000fd, - 0x00002c96, 0x00002c97, 0x0000a7ba, 0x0000a7bb, - 0x000010b8, 0x00002d18, 0x00001c91, 0x000010d1, - 0x00000124, 0x00000125, 0x00016e4d, 0x00016e6d, - 0x00001ee8, 0x00001ee9, 0x0000ab8c, 0x000013bc, - 0x000118a5, 0x000118c5, 0x00001c94, 0x000010d4, - 0x00010590, 0x000105b7, 0x00000049, 0x00000069, - 0x000000c0, 0x000000e0, 0x00001ff4, 0x020002a4, - 0x0000ab7f, 0x000013af, 0x0000021c, 0x0000021d, - 0x0000a75e, 0x0000a75f, 0x00001fbb, 0x00001f71, - 0x00016e50, 0x00016e70, 0x000003e0, 0x000003e1, - 0x0000042e, 0x0000044e, 0x0001e91f, 0x0001e941, - 0x00000110, 0x00000111, 0x00000403, 0x00000453, - 0x00001e8a, 0x00001e8b, 0x000104c0, 0x000104e8, - 0x00001fd2, 0x0300027d, 0x000104b9, 0x000104e1, - 0x0000a686, 0x0000a687, 0x0000a7d0, 0x0000a7d1, - 0x00010c90, 0x00010cd0, 0x0000050e, 0x0000050f, - 0x000001c7, 0x000001c9, 0x000001f4, 0x000001f5, - 0x000000df, 0x0200018f, 0x00001fb8, 0x00001fb0, - 0x0000a7a6, 0x0000a7a7, 0x00000189, 0x00000256, - 0x0000a684, 0x0000a685, 0x00002ced, 0x00002cee, - 0x0000a796, 0x0000a797, 0x00002cbc, 0x00002cbd, - 0x0000ab8b, 0x000013bb, 0x0001e909, 0x0001e92b, - 0x0000abb9, 0x000013e9, 0x00010d61, 0x00010d81, - 0x00010584, 0x000105ab, 0x00001f9d, 0x0200021e, - 0x000004b0, 0x000004b1, 0x0001e90c, 0x0001e92e, - 0x00010caf, 0x00010cef, 0x000001e0, 0x000001e1, - 0x00001f5f, 0x00001f57, 0x00002c16, 0x00002c46, - 0x00010425, 0x0001044d, 0x00001cb0, 0x000010f0, - 0x00001cae, 0x000010ee, 0x000004c1, 0x000004c2, - 0x00010cb1, 0x00010cf1, 0x000013f9, 0x000013f1, - 0x00001eee, 0x00001eef, 0x00010585, 0x000105ac, - 0x000000c4, 0x000000e4, 0x0000a65a, 0x0000a65b, - 0x0000a694, 0x0000a695, 0x00010c85, 0x00010cc5, - 0x0001e900, 0x0001e922, 0x00010587, 0x000105ae, - 0x00000182, 0x00000183, 0x00002c21, 0x00002c51, - 0x0000ab8a, 0x000013ba, 0x00000202, 0x00000203, - 0x00000555, 0x00000585, 0x00001e46, 0x00001e47, - 0x00000046, 0x00000066, 0x00001e06, 0x00001e07, - 0x0000ab97, 0x000013c7, 0x000003a8, 0x000003c8, - 0x000003a3, 0x000003c3, 0x00002c23, 0x00002c53, - 0x00000162, 0x00000163, 0x00010415, 0x0001043d, - 0x00001ef2, 0x00001ef3, 0x00001fd6, 0x02000285, - 0x0001e921, 0x0001e943, 0x0000038a, 0x000003af, - 0x0000a648, 0x0000a649, 0x00000540, 0x00000570, - 0x0000049a, 0x0000049b, 0x00002c6b, 0x00002c6c, - 0x00001e16, 0x00001e17, 0x000001bc, 0x000001bd, - 0x0001057e, 0x000105a5, 0x00001f81, 0x020001ca, - 0x00000429, 0x00000449, 0x000010b6, 0x00002d16, - 0x0000039d, 0x000003bd, 0x0000fb13, 0x020002c8, - 0x000003ec, 0x000003ed, 0x0000216b, 0x0000217b, - 0x00000208, 0x00000209, 0x0000ff3a, 0x0000ff5a, - 0x0000ab83, 0x000013b3, 0x0000a7c6, 0x00001d8e, - 0x00002cd0, 0x00002cd1, 0x00001ebc, 0x00001ebd, - 0x00000478, 0x00000479, 0x00000048, 0x00000068, - 0x000001f7, 0x000001bf, 0x0000010c, 0x0000010d, - 0x00000149, 0x02000195, 0x00000542, 0x00000572, - 0x00010406, 0x0001042e, 0x00000181, 0x00000253, - 0x00010412, 0x0001043a, 0x000010c5, 0x00002d25, - 0x00001f4a, 0x00001f42, 0x0000a760, 0x0000a761, - 0x000104ba, 0x000104e2, 0x000010bf, 0x00002d1f, - 0x0001e916, 0x0001e938, 0x00000535, 0x00000565, - 0x0000a65c, 0x0000a65d, 0x00001ec6, 0x00001ec7, - 0x0000ab70, 0x000013a0, 0x0000ab9a, 0x000013ca, - 0x0000014a, 0x0000014b, 0x0000a72e, 0x0000a72f, - 0x0000039b, 0x000003bb, 0x000004a2, 0x000004a3, - 0x0000a7cb, 0x00000264, 0x0000019c, 0x0000026f, - 0x0001e91d, 0x0001e93f, 0x00001f59, 0x00001f51, - 0x00001f56, 0x030001c3, 0x00000548, 0x00000578, - 0x00002c09, 0x00002c39, 0x00000054, 0x00000074, - 0x0000039f, 0x000003bf, 0x00001ff7, 0x030002aa, - 0x00001e68, 0x00001e69, 0x00001e80, 0x00001e81, - 0x0001041c, 0x00010444, 0x00000244, 0x00000289, - 0x0000216e, 0x0000217e, 0x00002c19, 0x00002c49, - 0x000004fa, 0x000004fb, 0x0000049e, 0x0000049f, - 0x0001e90d, 0x0001e92f, 0x00000184, 0x00000185, - 0x00000531, 0x00000561, 0x00000042, 0x00000062, - 0x00001faa, 0x02000245, 0x000003ab, 0x000003cb, - 0x00001ca9, 0x000010e9, 0x0000021a, 0x0000021b, - 0x00002cae, 0x00002caf, 0x00001fe2, 0x0300028c, - 0x00001f82, 0x020001cd, 0x00000376, 0x00000377, - 0x0000a77d, 0x00001d79, 0x000000d9, 0x000000f9, - 0x00002c98, 0x00002c99, 0x00001ea0, 0x00001ea1, - 0x00001ebe, 0x00001ebf, 0x0000ff2a, 0x0000ff4a, - 0x000003f5, 0x000003b5, 0x00000500, 0x00000501, - 0x0000216a, 0x0000217a, 0x00001f38, 0x00001f30, - 0x0000ab98, 0x000013c8, 0x0000ff26, 0x0000ff46, - 0x000003a5, 0x000003c5, 0x000001b7, 0x00000292, - 0x000118bd, 0x000118dd, 0x00002ca4, 0x00002ca5, - 0x00001e1e, 0x00001e1f, 0x00000423, 0x00000443, - 0x00002cb8, 0x00002cb9, 0x000000cc, 0x000000ec, - 0x00002c04, 0x00002c34, 0x00001e8e, 0x00001e8f, - 0x00001f98, 0x0200020f, 0x0000aba9, 0x000013d9, - 0x000001a2, 0x000001a3, 0x00002cc2, 0x00002cc3, - 0x00001e86, 0x00001e87, 0x000004f6, 0x000004f7, - 0x00001c93, 0x000010d3, 0x00001c83, 0x00000441, - 0x000001a9, 0x00000283, 0x00002c72, 0x00002c73, - 0x000004d6, 0x000004d7, 0x00000510, 0x00000511, - 0x00000388, 0x000003ad, 0x00010405, 0x0001042d, - 0x000024c0, 0x000024da, 0x00002c17, 0x00002c47, - 0x000013fd, 0x000013f5, 0x000010b2, 0x00002d12, - 0x0000023a, 0x00002c65, 0x0000a7b0, 0x0000029e, - 0x000001a6, 0x00000280, 0x00002cbe, 0x00002cbf, - 0x00001ec4, 0x00001ec5, 0x00001f3b, 0x00001f33, - 0x000000cf, 0x000000ef, 0x00010404, 0x0001042c, - 0x00016e5e, 0x00016e7e, 0x00001f1d, 0x00001f15, - 0x0000a790, 0x0000a791, 0x00001c92, 0x000010d2, - 0x00001e42, 0x00001e43, 0x00002c14, 0x00002c44, - 0x00001fa9, 0x02000242, 0x000104d1, 0x000104f9, - 0x00001ca5, 0x000010e5, 0x00001f90, 0x020001f7, - 0x0001057d, 0x000105a4, 0x000024c7, 0x000024e1, - 0x00002c60, 0x00002c61, 0x00002cba, 0x00002cbb, - 0x00000408, 0x00000458, 0x00016e43, 0x00016e63, - 0x00000246, 0x00000247, 0x0000013b, 0x0000013c, - 0x0000a696, 0x0000a697, 0x00001e44, 0x00001e45, - 0x000004ee, 0x000004ef, 0x0001e90f, 0x0001e931, - 0x000004cb, 0x000004cc, 0x00001cad, 0x000010ed, - 0x000001a0, 0x000001a1, 0x0000abba, 0x000013ea, - 0x00010572, 0x00010599, 0x00000174, 0x00000175, - 0x0001040a, 0x00010432, 0x00010c93, 0x00010cd3, - 0x00000528, 0x00000529, 0x0000042f, 0x0000044f, - 0x0000ab92, 0x000013c2, 0x00000417, 0x00000437, - 0x0000a74a, 0x0000a74b, 0x000010ad, 0x00002d0d, - 0x00001ea2, 0x00001ea3, 0x00001e88, 0x00001e89, - 0x0000ab87, 0x000013b7, 0x00010426, 0x0001044e, - 0x00000176, 0x00000177, 0x00010594, 0x000105bb, - 0x00001fc6, 0x02000273, 0x000004d8, 0x000004d9, - 0x000118a2, 0x000118c2, 0x00010d53, 0x00010d73, - 0x0000ff38, 0x0000ff58, 0x00001fa8, 0x0200023f, - 0x00000526, 0x00000527, 0x00001fc2, 0x0200026a, - 0x0000ab96, 0x000013c6, 0x0000a758, 0x0000a759, - 0x00001fd3, 0x03000281, 0x00002c06, 0x00002c36, - 0x00001efc, 0x00001efd, 0x0000042a, 0x0000044a, - 0x0000ab8d, 0x000013bd, 0x00010423, 0x0001044b, - 0x00000114, 0x00000115, 0x00001f88, 0x020001df, - 0x0000047a, 0x0000047b, 0x000118ba, 0x000118da, - 0x0001e910, 0x0001e932, 0x00002c15, 0x00002c45, - 0x000013fb, 0x000013f3, 0x00001eb8, 0x00001eb9, - 0x0000051a, 0x0000051b, 0x00010c8a, 0x00010cca, - 0x00010ca0, 0x00010ce0, 0x000118be, 0x000118de, - 0x00002c28, 0x00002c58, 0x00001e54, 0x00001e55, - 0x000003d0, 0x000003b2, 0x0000a7ab, 0x0000025c, - 0x0000ff29, 0x0000ff49, 0x000024cc, 0x000024e6, - 0x0000a65e, 0x0000a65f, 0x0000abbd, 0x000013ed, - 0x00010580, 0x000105a7, 0x0000a7c5, 0x00000282, - 0x0000004e, 0x0000006e, 0x000118b2, 0x000118d2, - 0x00001fb3, 0x0200025a, 0x00000494, 0x00000495, - 0x00001f94, 0x02000203, 0x0000fb05, 0x020002c2, - 0x000013fc, 0x000013f4, 0x00010403, 0x0001042b, - 0x0000ab86, 0x000013b6, 0x0000054a, 0x0000057a, - 0x0000a7d8, 0x0000a7d9, 0x00000230, 0x00000231, - 0x00001c89, 0x00001c8a, 0x000010a1, 0x00002d01, - 0x0000a64e, 0x0000a64f, 0x00001e2e, 0x00001e2f, - 0x0000022a, 0x0000022b, 0x000000c8, 0x000000e8, - 0x00000553, 0x00000583, 0x000024c2, 0x000024dc, - 0x00010ca2, 0x00010ce2, 0x000004a0, 0x000004a1, - 0x0000ab85, 0x000013b5, 0x00001e14, 0x00001e15, - 0x0000a64a, 0x0000a64b, 0x00001f4c, 0x00001f44, - 0x00001fe3, 0x03000290, 0x00001e60, 0x00001e61, - 0x000003aa, 0x000003ca, 0x0000212b, 0x000000e5, - 0x00010c99, 0x00010cd9, 0x00001f52, 0x030001bb, - 0x00000409, 0x00000459, 0x0000abad, 0x000013dd, - 0x00001cb4, 0x000010f4, 0x00002c02, 0x00002c32, - 0x00002c9a, 0x00002c9b, 0x00001ec8, 0x00001ec9, - 0x000118b7, 0x000118d7, 0x00000210, 0x00000211, - 0x00010422, 0x0001044a, 0x00016e51, 0x00016e71, - 0x0000ff22, 0x0000ff42, 0x00001f3f, 0x00001f37, - 0x000010c3, 0x00002d23, 0x0000ab8f, 0x000013bf, - 0x00010402, 0x0001042a, 0x00010d52, 0x00010d72, - 0x000000d8, 0x000000f8, 0x0001058a, 0x000105b1, - 0x00000398, 0x000003b8, 0x000104c2, 0x000104ea, - 0x00002165, 0x00002175, 0x000000cb, 0x000000eb, - 0x00002c07, 0x00002c37, 0x0000ff31, 0x0000ff51, - 0x000104c9, 0x000104f1, 0x0001040f, 0x00010437, - 0x00010d55, 0x00010d75, 0x00000544, 0x00000574, - 0x000118a1, 0x000118c1, 0x00001fca, 0x00001f74, - 0x000003fd, 0x0000037b, 0x0001041a, 0x00010442, - 0x0000010a, 0x0000010b, 0x0000ff34, 0x0000ff54, - 0x00001f96, 0x02000209, 0x00000512, 0x00000513, - 0x000001a4, 0x000001a5, 0x000001fe, 0x000001ff, - 0x00002c1b, 0x00002c4b, 0x0000aba8, 0x000013d8, - 0x00001e30, 0x00001e31, 0x0000a7a8, 0x0000a7a9, - 0x000003d1, 0x000003b8, 0x00001cbd, 0x000010fd, - 0x00010582, 0x000105a9, 0x00002cc0, 0x00002cc1, - 0x00000416, 0x00000436, 0x00000468, 0x00000469, - 0x00010ca1, 0x00010ce1, 0x000001b3, 0x000001b4, - 0x00010400, 0x00010428, 0x0000a75a, 0x0000a75b, - 0x000004b4, 0x000004b5, 0x0000a79e, 0x0000a79f, - 0x0001e91c, 0x0001e93e, 0x0000053b, 0x0000056b, - 0x00002c29, 0x00002c59, 0x00002c18, 0x00002c48, - 0x00001e24, 0x00001e25, 0x0000004a, 0x0000006a, - 0x0000a7a4, 0x0000a7a5, 0x00002168, 0x00002178, - 0x00002c62, 0x0000026b, 0x0000a72c, 0x0000a72d, - 0x0000040a, 0x0000045a, 0x00001c97, 0x000010d7, - 0x00002c6f, 0x00000250, 0x00000345, 0x000003b9, - 0x0000a698, 0x0000a699, 0x0000ff23, 0x0000ff43, - 0x0000a766, 0x0000a767, 0x0000abb1, 0x000013e1, - 0x00010420, 0x00010448, 0x0000a762, 0x0000a763, - 0x00001e84, 0x00001e85, 0x000004e6, 0x000004e7, - 0x00000160, 0x00000161, 0x00016e52, 0x00016e72, - 0x00000216, 0x00000217, 0x00001e50, 0x00001e51, - 0x00001f69, 0x00001f61, 0x00001eae, 0x00001eaf, - 0x000003fa, 0x000003fb, 0x00010c94, 0x00010cd4, - 0x000000dc, 0x000000fc, 0x00000545, 0x00000575, - 0x0000040f, 0x0000045f, 0x00001ef4, 0x00001ef5, - 0x000003f4, 0x000003b8, 0x0000023b, 0x0000023c, - 0x0000216c, 0x0000217c, 0x00002c1f, 0x00002c4f, - 0x0000ab7e, 0x000013ae, 0x000004da, 0x000004db, - 0x000001d5, 0x000001d6, 0x00010d5a, 0x00010d7a, - 0x00002c70, 0x00000252, 0x0000a682, 0x0000a683, - 0x0000fb06, 0x020002c5, 0x00001e20, 0x00001e21, - 0x000003e4, 0x000003e5, 0x000003d5, 0x000003c6, - 0x000000c9, 0x000000e9, 0x00002c88, 0x00002c89, - 0x00000520, 0x00000521, 0x00001caf, 0x000010ef, - 0x0001e91e, 0x0001e940, 0x0000040b, 0x0000045b, - 0x00002cd4, 0x00002cd5, 0x00001f9c, 0x0200021b, - 0x0000047c, 0x0000047d, 0x00016e4a, 0x00016e6a, - 0x00016e47, 0x00016e67, 0x000001ac, 0x000001ad, - 0x00002c1c, 0x00002c4c, 0x0000ff27, 0x0000ff47, - 0x00000464, 0x00000465, 0x00001e7c, 0x00001e7d, - 0x000104b5, 0x000104dd, 0x0000054d, 0x0000057d, - 0x00002c2a, 0x00002c5a, 0x000024bf, 0x000024d9, - 0x0000ab76, 0x000013a6, 0x00001c85, 0x00000442, - 0x00010ca4, 0x00010ce4, 0x00000100, 0x00000101, - 0x0000a660, 0x0000a661, 0x00001e32, 0x00001e33, - 0x0001e908, 0x0001e92a, 0x00010c8e, 0x00010cce, - 0x000001a7, 0x000001a8, 0x000024bd, 0x000024d7, - 0x00000533, 0x00000563, 0x000118b9, 0x000118d9, - 0x00010c86, 0x00010cc6, 0x00001e3e, 0x00001e3f, - 0x00010ca8, 0x00010ce8, 0x00000059, 0x00000079, - 0x00002c1a, 0x00002c4a, 0x0000054c, 0x0000057c, - 0x000010a9, 0x00002d09, 0x000104c5, 0x000104ed, - 0x00002c2f, 0x00002c5f, 0x00001ffb, 0x00001f7d, - 0x00001cbe, 0x000010fe, 0x00010cab, 0x00010ceb, - 0x00000206, 0x00000207, 0x000010a7, 0x00002d07, - 0x000010aa, 0x00002d0a, 0x000104cf, 0x000104f7, - 0x0000ff21, 0x0000ff41, 0x00010427, 0x0001044f, - 0x00001c9d, 0x000010dd, 0x000104bf, 0x000104e7, - 0x00002ceb, 0x00002cec, 0x0000ab82, 0x000013b2, - 0x0000a75c, 0x0000a75d, 0x00001e96, 0x020001a6, - 0x00000172, 0x00000173, 0x0000a73a, 0x0000a73b, - 0x00002c13, 0x00002c43, 0x00001ff3, 0x020002a1, - 0x00000413, 0x00000433, 0x000001d9, 0x000001da, - 0x00000218, 0x00000219, 0x000000da, 0x000000fa, - 0x00002c9c, 0x00002c9d, 0x00002ca6, 0x00002ca7, - 0x0000ab7c, 0x000013ac, 0x0000ab81, 0x000013b1, - 0x000010b4, 0x00002d14, 0x00016e53, 0x00016e73, - 0x000024c8, 0x000024e2, 0x00001e78, 0x00001e79, - 0x000004fc, 0x000004fd, 0x0000018f, 0x00000259, - 0x000010bc, 0x00002d1c, 0x0000a722, 0x0000a723, - 0x00010c83, 0x00010cc3, 0x000104d0, 0x000104f8, - 0x0000039a, 0x000003ba, 0x00001eb2, 0x00001eb3, - 0x0000a756, 0x0000a757, 0x00001f09, 0x00001f01, - 0x00002163, 0x00002173, 0x00001e92, 0x00001e93, - 0x0000ab7a, 0x000013aa, 0x00010574, 0x0001059b, - 0x000001af, 0x000001b0, 0x0000015c, 0x0000015d, - 0x00001ede, 0x00001edf, 0x0000046e, 0x0000046f, - 0x000003ea, 0x000003eb, 0x000104d3, 0x000104fb, - 0x00000190, 0x0000025b, 0x0000a742, 0x0000a743, - 0x00001f8a, 0x020001e5, 0x00000514, 0x00000515, - 0x00001e0a, 0x00001e0b, 0x000001c4, 0x000001c6, - 0x0000a748, 0x0000a749, 0x00001fc3, 0x0200026d, - 0x00001e34, 0x00001e35, 0x00001eb4, 0x00001eb5, - 0x000010b9, 0x00002d19, 0x0000a784, 0x0000a785, - 0x00000407, 0x00000457, 0x0000a66a, 0x0000a66b, - 0x000010a8, 0x00002d08, 0x0000046a, 0x0000046b, - 0x00010c9f, 0x00010cdf, 0x00000150, 0x00000151, - 0x00002c1d, 0x00002c4d, 0x00001f1c, 0x00001f14, - 0x0000ff25, 0x0000ff45, 0x00000108, 0x00000109, - 0x00002c00, 0x00002c30, 0x0001040e, 0x00010436, - 0x0000a746, 0x0000a747, 0x00001fae, 0x02000251, - 0x0001058d, 0x000105b4, 0x00010c98, 0x00010cd8, - 0x00016e44, 0x00016e64, 0x00002c67, 0x00002c68, - 0x00002c64, 0x0000027d, 0x00001e6c, 0x00001e6d, - 0x0000040c, 0x0000045c, 0x000104b7, 0x000104df, - 0x0000a640, 0x0000a641, 0x000118b4, 0x000118d4, - 0x0000a69a, 0x0000a69b, 0x00001fd9, 0x00001fd1, - 0x0001e90b, 0x0001e92d, 0x000003f9, 0x000003f2, - 0x00016e59, 0x00016e79, 0x0000ab9f, 0x000013cf, - 0x0000ab8e, 0x000013be, 0x00001fe4, 0x02000294, - 0x00001e52, 0x00001e53, 0x00016e4e, 0x00016e6e, - 0x00000220, 0x0000019e, 0x000104c4, 0x000104ec, - 0x00001fec, 0x00001fe5, 0x00001e5a, 0x00001e5b, - 0x00001cb9, 0x000010f9, 0x0000ab75, 0x000013a5, - 0x00000104, 0x00000105, 0x00002c8e, 0x00002c8f, - 0x000118ad, 0x000118cd, 0x0000abbf, 0x000013ef, - 0x0000abbb, 0x000013eb, 0x0001e90e, 0x0001e930, - 0x00010d60, 0x00010d80, 0x00002ca8, 0x00002ca9, - 0x00001f3c, 0x00001f34, 0x000004dc, 0x000004dd, - 0x00010591, 0x000105b8, 0x00001e48, 0x00001e49, - 0x0000a650, 0x0000a651, 0x0000abae, 0x000013de, - 0x000118b0, 0x000118d0, 0x0001e914, 0x0001e936, - 0x00001cba, 0x000010fa, 0x0001e91a, 0x0001e93c, - 0x000000c7, 0x000000e7, 0x00002c8a, 0x00002c8b, - 0x00001e9e, 0x020001b5, 0x000004f8, 0x000004f9, - 0x000104b6, 0x000104de, 0x00010407, 0x0001042f, - 0x000104ca, 0x000104f2, 0x00001eb6, 0x00001eb7, - 0x00001f2a, 0x00001f22, 0x00001f9f, 0x02000224, - 0x00000139, 0x0000013a, 0x00000106, 0x00000107, - 0x000118b1, 0x000118d1, 0x0000abb4, 0x000013e4, - 0x0000051e, 0x0000051f, 0x00010d50, 0x00010d70, - 0x000001e8, 0x000001e9, 0x00016e4c, 0x00016e6c, - 0x00002c2c, 0x00002c5c, 0x00000401, 0x00000451, - 0x00001f39, 0x00001f31, 0x0000024e, 0x0000024f, - 0x000024ce, 0x000024e8, 0x0000a7c0, 0x0000a7c1, - 0x0000a662, 0x0000a663, 0x00000539, 0x00000569, - 0x000104c1, 0x000104e9, 0x000104b8, 0x000104e0, - 0x00000543, 0x00000573, 0x00010410, 0x00010438, - 0x00001f1b, 0x00001f13, 0x00001f6e, 0x00001f66, - 0x00001fd7, 0x03000288, 0x00001c96, 0x000010d6, - 0x000118aa, 0x000118ca, 0x00010414, 0x0001043c, - 0x00001fb9, 0x00001fb1, 0x0000abaa, 0x000013da, - 0x00000389, 0x000003ae, 0x00000232, 0x00000233, - 0x00002cb0, 0x00002cb1, 0x00002c6e, 0x00000271, - 0x00001e6e, 0x00001e6f, 0x0000ab93, 0x000013c3, - 0x0001e90a, 0x0001e92c, 0x0000a740, 0x0000a741, - 0x000118a3, 0x000118c3, 0x0000052c, 0x0000052d, - 0x00001ffa, 0x00001f7c, 0x000004a4, 0x000004a5, - 0x00010d5d, 0x00010d7d, 0x0000018a, 0x00000257, - 0x000001d7, 0x000001d8, 0x0000004d, 0x0000006d, - 0x000004f2, 0x000004f3, 0x00000164, 0x00000165, - 0x000010b7, 0x00002d17, 0x00002160, 0x00002170, - 0x0000a7b4, 0x0000a7b5, 0x00001feb, 0x00001f7b, - 0x00001e58, 0x00001e59, 0x00001eda, 0x00001edb, - 0x00010d5c, 0x00010d7c, 0x000010ae, 0x00002d0e, - 0x000001db, 0x000001dc, 0x0000a688, 0x0000a689, - 0x00000411, 0x00000431, 0x000104b3, 0x000104db, - 0x00002c01, 0x00002c31, 0x00016e55, 0x00016e75, - 0x0000a7a2, 0x0000a7a3, 0x00001f3e, 0x00001f36, - 0x0000054b, 0x0000057b, 0x0000024a, 0x0000024b, - 0x00001e74, 0x00001e75, 0x000118a6, 0x000118c6, - 0x00001f8d, 0x020001ee, 0x00002c7f, 0x00000240, - 0x0000039c, 0x000003bc, 0x000003fe, 0x0000037c, - 0x00000052, 0x00000072, 0x000024cb, 0x000024e5, - 0x00016e5a, 0x00016e7a, 0x0000ff35, 0x0000ff55, - 0x00001f2b, 0x00001f23, 0x000104c7, 0x000104ef, - 0x0000011e, 0x0000011f, 0x00002164, 0x00002174, - 0x0000a7c9, 0x0000a7ca, 0x00001f28, 0x00001f20, - 0x0000ab79, 0x000013a9, 0x00000126, 0x00000127, - 0x00010588, 0x000105af, 0x0000020e, 0x0000020f, - 0x0000abb2, 0x000013e2, 0x00000516, 0x00000517, - 0x0000019f, 0x00000275, 0x000001fc, 0x000001fd, - 0x0000a7a0, 0x0000a7a1, 0x00001f0d, 0x00001f05, - 0x00001ece, 0x00001ecf, 0x00000193, 0x00000260, - 0x0000ab7d, 0x000013ad, 0x00001ca4, 0x000010e4, - 0x000010b0, 0x00002d10, 0x00002cc4, 0x00002cc5, - 0x00001f1a, 0x00001f12, 0x0000046c, 0x0000046d, - 0x00002126, 0x000003c9, 0x00016e45, 0x00016e65, - 0x00002c0a, 0x00002c3a, 0x00001f18, 0x00001f10, - 0x00000524, 0x00000525, 0x0001041b, 0x00010443, - 0x00001caa, 0x000010ea, 0x000001ee, 0x000001ef, - 0x00000051, 0x00000071, 0x0000053e, 0x0000056e, - 0x00001e28, 0x00001e29, 0x0001e915, 0x0001e937, - 0x000010c4, 0x00002d24, 0x00002c84, 0x00002c85, - 0x00001ff9, 0x00001f79, 0x00001ff6, 0x020002a7, - 0x0000040e, 0x0000045e, 0x0000fb14, 0x020002cb, - 0x00001cb1, 0x000010f1, 0x00010d63, 0x00010d83, - 0x00000498, 0x00000499, 0x000010b1, 0x00002d11, - 0x0000a79a, 0x0000a79b, 0x0000a7bc, 0x0000a7bd, - 0x00010d5b, 0x00010d7b, 0x00010d5e, 0x00010d7e, - 0x00010ca7, 0x00010ce7, 0x00002c1e, 0x00002c4e, - 0x000024c4, 0x000024de, 0x0000038f, 0x000003ce, - 0x0000a7f5, 0x0000a7f6, 0x0000012e, 0x0000012f, - 0x00001fe8, 0x00001fe0, 0x00001eea, 0x00001eeb, - 0x000003f0, 0x000003ba, 0x00001f0e, 0x00001f06, - 0x00000058, 0x00000078, 0x00002cac, 0x00002cad, - 0x00010575, 0x0001059c, 0x00001ef8, 0x00001ef9, - 0x00000397, 0x000003b7, 0x00010c82, 0x00010cc2, - 0x000024c1, 0x000024db, 0x00000532, 0x00000562, - 0x00000496, 0x00000497, 0x000004de, 0x000004df, - 0x00000170, 0x00000171, 0x00000415, 0x00000435, - 0x00000241, 0x00000242, 0x00001f85, 0x020001d6, - 0x00001e1c, 0x00001e1d, 0x000013fa, 0x000013f2, - 0x0001058f, 0x000105b6, 0x00010c97, 0x00010cd7, - 0x00000057, 0x00000077, 0x00002c8c, 0x00002c8d, - 0x00001ef0, 0x00001ef1, 0x000104c8, 0x000104f0, - 0x00001f2f, 0x00001f27, 0x00000112, 0x00000113, - 0x00010419, 0x00010441, 0x00000419, 0x00000439, - 0x00000480, 0x00000481, 0x0000ab9b, 0x000013cb, - 0x00010573, 0x0001059a, 0x00010409, 0x00010431, - 0x0000fb02, 0x020002b7, 0x00001fa5, 0x02000236, - 0x00000556, 0x00000586, 0x0000038e, 0x000003cd, - 0x000001fa, 0x000001fb, 0x000000d6, 0x000000f6, - 0x00002c2e, 0x00002c5e, 0x0000a76e, 0x0000a76f, - 0x000003d6, 0x000003c0, 0x00010577, 0x0001059e, - 0x000010ab, 0x00002d0b, 0x0000a77e, 0x0000a77f, - 0x0000a664, 0x0000a665, 0x00001ecc, 0x00001ecd, - 0x00000425, 0x00000445, 0x00001faf, 0x02000254, - 0x000024bc, 0x000024d6, 0x00016e42, 0x00016e62, - 0x00001fad, 0x0200024e, 0x000004b2, 0x000004b3, - 0x0000012c, 0x0000012d, 0x000104cd, 0x000104f5, - 0x000001e2, 0x000001e3, 0x000003cf, 0x000003d7, - 0x00002c10, 0x00002c40, 0x00000550, 0x00000580, - 0x0001057c, 0x000105a3, 0x00000204, 0x00000205, - 0x00002c03, 0x00002c33, 0x0000fb03, 0x030002ba, - 0x00001e22, 0x00001e23, 0x000010ba, 0x00002d1a, - 0x00000490, 0x00000491, 0x0000a74e, 0x0000a74f, - 0x00000145, 0x00000146, 0x0000a68e, 0x0000a68f, - 0x0000ab72, 0x000013a2, 0x000004a6, 0x000004a7, - 0x0000fb16, 0x020002d1, 0x0001e913, 0x0001e935, - 0x0000016e, 0x0000016f, 0x00001f50, 0x020001b8, - 0x00001f8b, 0x020001e8, 0x00001e3c, 0x00001e3d, - 0x00010c9b, 0x00010cdb, 0x0000a73e, 0x0000a73f, - 0x00000143, 0x00000144, 0x00000502, 0x00000503, - 0x00001e70, 0x00001e71, 0x00001cbf, 0x000010ff, - 0x00010ca6, 0x00010ce6, 0x000000cd, 0x000000ed, - 0x00002ca0, 0x00002ca1, 0x0000a68a, 0x0000a68b, - 0x0000ab89, 0x000013b9, 0x00001f48, 0x00001f40, - 0x00002c6d, 0x00000251, 0x00000178, 0x000000ff, - 0x0000212a, 0x0000006b, 0x00001fe7, 0x0300029a, - 0x0000a798, 0x0000a799, 0x0001e920, 0x0001e942, - 0x0001040b, 0x00010433, 0x00000055, 0x00000075, - 0x00010416, 0x0001043e, 0x00001f54, 0x030001bf, - 0x00000390, 0x0300019b, 0x000003e2, 0x000003e3, - 0x000024b8, 0x000024d2, 0x00010571, 0x00010598, - 0x0001e912, 0x0001e934, 0x0000ff37, 0x0000ff57, - 0x0000023d, 0x0000019a, 0x000024be, 0x000024d8, - 0x0000011a, 0x0000011b, 0x00002cd2, 0x00002cd3, - 0x000118b6, 0x000118d6, 0x0000041c, 0x0000043c, - 0x000000d5, 0x000000f5, 0x00010579, 0x000105a0, - 0x0000019d, 0x00000272, 0x000010b3, 0x00002d13, - 0x00010c81, 0x00010cc1, 0x00000518, 0x00000519, - 0x0000a752, 0x0000a753, 0x00000136, 0x00000137, - 0x00002c63, 0x00001d7d, 0x00001fc7, 0x03000276, - 0x00002c7e, 0x0000023f, 0x0000a7c7, 0x0000a7c8, - 0x0000042c, 0x0000044c, 0x00010408, 0x00010430, - 0x00010c9d, 0x00010cdd, 0x00002cc6, 0x00002cc7, - 0x00016e5c, 0x00016e7c, 0x00000460, 0x00000461, - 0x00001f8c, 0x020001eb, 0x00000154, 0x00000155, - 0x000004c9, 0x000004ca, 0x00001f19, 0x00001f11, - 0x00001f9e, 0x02000221, 0x00000386, 0x000003ac, - 0x00002c0b, 0x00002c3b, 0x000001ea, 0x000001eb, - 0x000010bb, 0x00002d1b, 0x0000abac, 0x000013dc, - 0x00000426, 0x00000446, 0x000118b5, 0x000118d5, - 0x0000024c, 0x0000024d, 0x000010af, 0x00002d0f, - 0x00001c9c, 0x000010dc, 0x00002cb6, 0x00002cb7, - 0x00000410, 0x00000430, 0x0000ff28, 0x0000ff48, - 0x0000038c, 0x000003cc, 0x000010c2, 0x00002d22, - 0x00000427, 0x00000447 + 0x00010d53, 0x00010d73, 0x000118b4, 0x000118d4, + 0x00001ca4, 0x000010e4, 0x00001ff2, 0x0200029e, + 0x0001057f, 0x000105a6, 0x00000149, 0x02000195, + 0x00001e44, 0x00001e45, 0x0000a768, 0x0000a769, + 0x000004dc, 0x000004dd, 0x00000506, 0x00000507, + 0x00000230, 0x00000231, 0x00001c92, 0x000010d2, + 0x0000051c, 0x0000051d, 0x00001f8f, 0x020001f4, + 0x000001d7, 0x000001d8, 0x0000abac, 0x000013dc, + 0x00001f3b, 0x00001f33, 0x00010ca9, 0x00010ce9, + 0x0000a7ac, 0x00000261, 0x00002c98, 0x00002c99, + 0x0000046a, 0x0000046b, 0x00016e53, 0x00016e73, + 0x00000549, 0x00000579, 0x0000a780, 0x0000a781, + 0x00001f52, 0x030001bb, 0x0001e904, 0x0001e926, + 0x0000aba0, 0x000013d0, 0x00001fae, 0x02000251, + 0x0000a7c2, 0x0000a7c3, 0x00000394, 0x000003b4, + 0x0001040f, 0x00010437, 0x00001eb4, 0x00001eb5, + 0x000001e4, 0x000001e5, 0x00010c9b, 0x00010cdb, + 0x000000cd, 0x000000ed, 0x00000386, 0x000003ac, + 0x0001041d, 0x00010445, 0x000104d3, 0x000104fb, + 0x000024c5, 0x000024df, 0x0000a7ab, 0x0000025c, + 0x00010d54, 0x00010d74, 0x00010caa, 0x00010cea, + 0x00001fe8, 0x00001fe0, 0x0000a694, 0x0000a695, + 0x00010580, 0x000105a7, 0x00002cb2, 0x00002cb3, + 0x00002cb4, 0x00002cb5, 0x00000553, 0x00000583, + 0x0000ff2f, 0x0000ff4f, 0x00000510, 0x00000511, + 0x0000a7dc, 0x0000019b, 0x00000170, 0x00000171, + 0x00001cbd, 0x000010fd, 0x00001f8e, 0x020001f1, + 0x00000132, 0x00000133, 0x0001041e, 0x00010446, + 0x0000047e, 0x0000047f, 0x00001ebc, 0x00001ebd, + 0x000118af, 0x000118cf, 0x000003d1, 0x000003b8, + 0x00000370, 0x00000371, 0x00016e54, 0x00016e74, + 0x000003d0, 0x000003b2, 0x00002c08, 0x00002c38, + 0x00010ca7, 0x00010ce7, 0x00000126, 0x00000127, + 0x00000423, 0x00000443, 0x00000428, 0x00000448, + 0x000010af, 0x00002d0f, 0x0000013d, 0x0000013e, + 0x00001f1b, 0x00001f13, 0x0000013f, 0x00000140, + 0x000001b5, 0x000001b6, 0x00010c9d, 0x00010cdd, + 0x00000147, 0x00000148, 0x00002cdc, 0x00002cdd, + 0x0000a734, 0x0000a735, 0x000004cb, 0x000004cc, + 0x0000fb16, 0x020002d1, 0x0000a72a, 0x0000a72b, + 0x00010d55, 0x00010d75, 0x0000019d, 0x00000272, + 0x000004c9, 0x000004ca, 0x000000dd, 0x000000fd, + 0x00010581, 0x000105a8, 0x000024c6, 0x000024e0, + 0x00000191, 0x00000192, 0x000118ab, 0x000118cb, + 0x0000ab74, 0x000013a4, 0x00000174, 0x00000175, + 0x0000a76e, 0x0000a76f, 0x0000011e, 0x0000011f, + 0x00000404, 0x00000454, 0x00001f91, 0x020001fa, + 0x00000134, 0x00000135, 0x00000399, 0x000003b9, + 0x00001e60, 0x00001e61, 0x00001f0b, 0x00001f03, + 0x0000004d, 0x0000006d, 0x000003f7, 0x000003f8, + 0x00001ef4, 0x00001ef5, 0x00016e55, 0x00016e75, + 0x00001fda, 0x00001f76, 0x000001b7, 0x00000292, + 0x00001f50, 0x020001b8, 0x00001ea6, 0x00001ea7, + 0x000024cc, 0x000024e6, 0x00000429, 0x00000449, + 0x000010a3, 0x00002d03, 0x0000021e, 0x0000021f, + 0x00002166, 0x00002176, 0x000000cb, 0x000000eb, + 0x00016e44, 0x00016e64, 0x0000ff30, 0x0000ff50, + 0x00000470, 0x00000471, 0x00001e58, 0x00001e59, + 0x00016e5c, 0x00016e7c, 0x000104c9, 0x000104f1, + 0x000010ba, 0x00002d1a, 0x0000a7d4, 0x0000a7d5, + 0x00010d56, 0x00010d76, 0x00001f1c, 0x00001f14, + 0x00001fd6, 0x02000285, 0x000001f6, 0x00000195, + 0x00010582, 0x000105a9, 0x0000ab97, 0x000013c7, + 0x000004e0, 0x000004e1, 0x00010c9f, 0x00010cdf, + 0x000104bc, 0x000104e4, 0x00002ceb, 0x00002cec, + 0x0000a758, 0x0000a759, 0x000000d9, 0x000000f9, + 0x0000051e, 0x0000051f, 0x00001f90, 0x020001f7, + 0x00010d5a, 0x00010d7a, 0x00001ffb, 0x00001f7d, + 0x00001fbe, 0x000003b9, 0x00002c26, 0x00002c56, + 0x000000c1, 0x000000e1, 0x00002c96, 0x00002c97, + 0x00000372, 0x00000373, 0x00016e56, 0x00016e76, + 0x0000a74a, 0x0000a74b, 0x000003a5, 0x000003c5, + 0x0001e913, 0x0001e935, 0x0000012a, 0x0000012b, + 0x00001f09, 0x00001f01, 0x0000042a, 0x0000044a, + 0x00002c1c, 0x00002c4c, 0x000001a4, 0x000001a5, + 0x000118a9, 0x000118c9, 0x000004a2, 0x000004a3, + 0x00001cb2, 0x000010f2, 0x00001c91, 0x000010d1, + 0x00002ca4, 0x00002ca5, 0x00010cab, 0x00010ceb, + 0x000003a9, 0x000003c9, 0x0000ab7f, 0x000013af, + 0x00010426, 0x0001044e, 0x00000206, 0x00000207, + 0x00010d57, 0x00010d77, 0x00002cc2, 0x00002cc3, + 0x00001fca, 0x00001f74, 0x0000a698, 0x0000a699, + 0x00010583, 0x000105aa, 0x000004ae, 0x000004af, + 0x00010412, 0x0001043a, 0x00001e34, 0x00001e35, + 0x00001f9b, 0x02000218, 0x00002c11, 0x00002c41, + 0x0001041f, 0x00010447, 0x0000a650, 0x0000a651, + 0x00002c69, 0x00002c6a, 0x00001f93, 0x02000200, + 0x00010d63, 0x00010d83, 0x0000abb0, 0x000013e0, + 0x000001a2, 0x000001a3, 0x0000ab95, 0x000013c5, + 0x00010413, 0x0001043b, 0x00016eae, 0x00016ec9, + 0x000004e8, 0x000004e9, 0x00016e57, 0x00016e77, + 0x0000a7b1, 0x00000287, 0x0000017d, 0x0000017e, + 0x00001f56, 0x030001c3, 0x0000017b, 0x0000017c, + 0x000003fd, 0x0000037b, 0x0000042b, 0x0000044b, + 0x000010a5, 0x00002d05, 0x00000041, 0x00000061, + 0x00001e66, 0x00001e67, 0x0001e917, 0x0001e939, + 0x00001ff6, 0x020002a7, 0x0000023a, 0x00002c65, + 0x00002c27, 0x00002c57, 0x00002c70, 0x00000252, + 0x00010cb1, 0x00010cf1, 0x000104cb, 0x000104f3, + 0x000003ee, 0x000003ef, 0x00001e32, 0x00001e33, + 0x00010d5b, 0x00010d7b, 0x00001e26, 0x00001e27, + 0x00001fac, 0x0200024b, 0x00016e40, 0x00016e60, + 0x00010584, 0x000105ab, 0x00000537, 0x00000567, + 0x00001eda, 0x00001edb, 0x00016e4a, 0x00016e6a, + 0x0000040d, 0x0000045d, 0x00002ced, 0x00002cee, + 0x0000a7da, 0x0000a7db, 0x00001c82, 0x0000043e, + 0x000003a1, 0x000003c1, 0x00001f92, 0x020001fd, + 0x00000136, 0x00000137, 0x0000a786, 0x0000a787, + 0x00001fbc, 0x02000267, 0x00001e3e, 0x00001e3f, + 0x000003da, 0x000003db, 0x00001cad, 0x000010ed, + 0x00002cac, 0x00002cad, 0x00016e58, 0x00016e78, + 0x0000038c, 0x000003cc, 0x00000508, 0x00000509, + 0x00001fe7, 0x0300029a, 0x000003f5, 0x000003b5, + 0x000003f9, 0x000003f2, 0x0000042c, 0x0000044c, + 0x000010a2, 0x00002d02, 0x00000042, 0x00000062, + 0x000004d0, 0x000004d1, 0x000001a6, 0x00000280, + 0x000001ec, 0x000001ed, 0x00010c88, 0x00010cc8, + 0x0000053d, 0x0000056d, 0x0000022a, 0x0000022b, + 0x00000392, 0x000003b2, 0x000104cd, 0x000104f5, + 0x00010424, 0x0001044c, 0x000004cd, 0x000004ce, + 0x00010d59, 0x00010d79, 0x0000ab94, 0x000013c4, + 0x000010b8, 0x00002d18, 0x0000a69a, 0x0000a69b, + 0x00010585, 0x000105ac, 0x0000aba9, 0x000013d9, + 0x0000aba1, 0x000013d1, 0x00010c96, 0x00010cd6, + 0x00002c13, 0x00002c43, 0x0000abbb, 0x000013eb, + 0x0000a752, 0x0000a753, 0x0000a78d, 0x00000265, + 0x00002cca, 0x00002ccb, 0x00001f95, 0x02000206, + 0x00016ea7, 0x00016ec2, 0x00016e42, 0x00016e62, + 0x00000460, 0x00000461, 0x00000197, 0x00000268, + 0x0001e912, 0x0001e934, 0x0000abb3, 0x000013e3, + 0x00001e54, 0x00001e55, 0x00016e59, 0x00016e79, + 0x000004d2, 0x000004d3, 0x0000fb15, 0x020002ce, + 0x000003a4, 0x000003c4, 0x00001e5e, 0x00001e5f, + 0x0000aba4, 0x000013d4, 0x0000042f, 0x0000044f, + 0x00002c14, 0x00002c44, 0x00000043, 0x00000063, + 0x00000189, 0x00000256, 0x00002ccc, 0x00002ccd, + 0x000001bc, 0x000001bd, 0x000104d2, 0x000104fa, + 0x0000046e, 0x0000046f, 0x00001cab, 0x000010eb, + 0x00000176, 0x00000177, 0x000104d1, 0x000104f9, + 0x000003f0, 0x000003ba, 0x00010caf, 0x00010cef, + 0x00010d5d, 0x00010d7d, 0x00000535, 0x00000565, + 0x00000222, 0x00000223, 0x0000abb1, 0x000013e1, + 0x00010586, 0x000105ad, 0x000004a8, 0x000004a9, + 0x0000fb14, 0x020002cb, 0x00010ca3, 0x00010ce3, + 0x000104b8, 0x000104e0, 0x00001cb4, 0x000010f4, + 0x0000a756, 0x0000a757, 0x0000ab90, 0x000013c0, + 0x0000216a, 0x0000217a, 0x00001f94, 0x02000203, + 0x0000a65a, 0x0000a65b, 0x00001f2f, 0x00001f27, + 0x00001faa, 0x02000245, 0x00001efa, 0x00001efb, + 0x00000492, 0x00000493, 0x000118a5, 0x000118c5, + 0x00000376, 0x00000377, 0x00016e5a, 0x00016e7a, + 0x0000ff2b, 0x0000ff4b, 0x00010414, 0x0001043c, + 0x00002cc6, 0x00002cc7, 0x00000130, 0x02000192, + 0x0000ab89, 0x000013b9, 0x0000042e, 0x0000044e, + 0x000010a4, 0x00002d04, 0x00000044, 0x00000064, + 0x00001ee6, 0x00001ee7, 0x00001ef0, 0x00001ef1, + 0x000001ea, 0x000001eb, 0x00001e2a, 0x00001e2b, + 0x00000550, 0x00000580, 0x000003aa, 0x000003ca, + 0x000000dc, 0x000000fc, 0x0000ff37, 0x0000ff57, + 0x00001f6a, 0x00001f62, 0x0000a64a, 0x0000a64b, + 0x0000054d, 0x0000057d, 0x00001ff3, 0x020002a1, + 0x00001e2e, 0x00001e2f, 0x000000da, 0x000000fa, + 0x00010587, 0x000105ae, 0x00002c6e, 0x00000271, + 0x00001ed8, 0x00001ed9, 0x00001c9c, 0x000010dc, + 0x000024cf, 0x000024e9, 0x000003b0, 0x0300019f, + 0x0000a754, 0x0000a755, 0x00001f3d, 0x00001f35, + 0x000118ac, 0x000118cc, 0x00002c06, 0x00002c36, + 0x0000a72e, 0x0000a72f, 0x0001e919, 0x0001e93b, + 0x00000420, 0x00000440, 0x00001fdb, 0x00001f77, + 0x00016ea1, 0x00016ebc, 0x00001cbf, 0x000010ff, + 0x000003a6, 0x000003c6, 0x00016e5b, 0x00016e7b, + 0x00016eb7, 0x00016ed2, 0x00001ca5, 0x000010e5, + 0x00000345, 0x000003b9, 0x0000016e, 0x0000016f, + 0x0000aba2, 0x000013d2, 0x00001fb6, 0x02000260, + 0x00002c28, 0x00002c58, 0x00000047, 0x00000067, + 0x00001e9e, 0x020001b5, 0x00001f3c, 0x00001f34, + 0x0000a750, 0x0000a751, 0x00002168, 0x00002178, + 0x0000038f, 0x000003ce, 0x00002c72, 0x00002c73, + 0x00001cbe, 0x000010fe, 0x0000ab7c, 0x000013ac, + 0x00016eaf, 0x00016eca, 0x0001058c, 0x000105b3, + 0x0000ff39, 0x0000ff59, 0x00000532, 0x00000562, + 0x00002c20, 0x00002c50, 0x0000a696, 0x0000a697, + 0x00000059, 0x00000079, 0x000004aa, 0x000004ab, + 0x0000ab70, 0x000013a0, 0x000000c0, 0x000000e0, + 0x00001e70, 0x00001e71, 0x00002cf2, 0x00002cf3, + 0x0000040b, 0x0000045b, 0x0000ab9c, 0x000013cc, + 0x00010592, 0x000105b9, 0x00001f96, 0x02000209, + 0x0000a660, 0x0000a661, 0x000118ba, 0x000118da, + 0x00002ca2, 0x00002ca3, 0x00016e41, 0x00016e61, + 0x000004de, 0x000004df, 0x0000054b, 0x0000057b, + 0x00002cb0, 0x00002cb1, 0x00016e5f, 0x00016e7f, + 0x0000ff27, 0x0000ff47, 0x00002cbc, 0x00002cbd, + 0x00001fc8, 0x00001f72, 0x00000122, 0x00000123, + 0x00010ca6, 0x00010ce6, 0x00000468, 0x00000469, + 0x000010a6, 0x00002d06, 0x00000046, 0x00000066, + 0x000118bf, 0x000118df, 0x00002c7f, 0x00000240, + 0x0000015c, 0x0000015d, 0x00001ca0, 0x000010e0, + 0x000010bd, 0x00002d1d, 0x0001e920, 0x0001e942, + 0x000000c5, 0x000000e5, 0x0000ab7d, 0x000013ad, + 0x000000c9, 0x000000e9, 0x0001e918, 0x0001e93a, + 0x00000198, 0x00000199, 0x00002c1d, 0x00002c4d, + 0x00001e48, 0x00001e49, 0x000001f4, 0x000001f5, + 0x00010589, 0x000105b0, 0x0000ab9b, 0x000013cb, + 0x0000040f, 0x0000045f, 0x00001c94, 0x000010d4, + 0x00002c23, 0x00002c53, 0x00001c83, 0x00000441, + 0x00002163, 0x00002173, 0x000104c6, 0x000104ee, + 0x00000424, 0x00000444, 0x00001f59, 0x00001f51, + 0x0000ff35, 0x0000ff55, 0x0000038e, 0x000003cd, + 0x00001e99, 0x020001af, 0x00010408, 0x00010430, + 0x0001e90d, 0x0001e92f, 0x00016ea0, 0x00016ebb, + 0x00001edc, 0x00001edd, 0x00016e5d, 0x00016e7d, + 0x00001cb8, 0x000010f8, 0x0000053c, 0x0000056c, + 0x0000fb01, 0x020002b4, 0x0000ff25, 0x0000ff45, + 0x00001e5a, 0x00001e5b, 0x00001f99, 0x02000212, + 0x000010a9, 0x00002d09, 0x00002c29, 0x00002c59, + 0x0000ff2c, 0x0000ff4c, 0x00001e98, 0x020001ac, + 0x0001e91d, 0x0001e93f, 0x00016eb3, 0x00016ece, + 0x00001fab, 0x02000248, 0x00001c9d, 0x000010dd, + 0x00001ea0, 0x00001ea1, 0x0000ab7e, 0x000013ae, + 0x0001041c, 0x00010444, 0x00001f5b, 0x00001f53, + 0x00000396, 0x000003b6, 0x0000018f, 0x00000259, + 0x0000a7b2, 0x0000029d, 0x000001e2, 0x000001e3, + 0x0001058d, 0x000105b4, 0x00001ca1, 0x000010e1, + 0x000104ca, 0x000104f2, 0x000000c2, 0x000000e2, + 0x00001ee8, 0x00001ee9, 0x00002ce0, 0x00002ce1, + 0x0000a75e, 0x0000a75f, 0x0001e901, 0x0001e923, + 0x000024c7, 0x000024e1, 0x00001e30, 0x00001e31, + 0x0000053f, 0x0000056f, 0x00000413, 0x00000433, + 0x00000193, 0x00000260, 0x0001e91a, 0x0001e93c, + 0x00001e68, 0x00001e69, 0x00001ca3, 0x000010e3, + 0x000118a4, 0x000118c4, 0x0000039a, 0x000003ba, + 0x00001f49, 0x00001f41, 0x00000422, 0x00000442, + 0x00001e1c, 0x00001e1d, 0x00000124, 0x00000125, + 0x000024b9, 0x000024d3, 0x00001fa0, 0x02000227, + 0x000010a8, 0x00002d08, 0x00000048, 0x00000068, + 0x00000551, 0x00000581, 0x000010a1, 0x00002d01, + 0x0000a656, 0x0000a657, 0x0000a682, 0x0000a683, + 0x000004ea, 0x000004eb, 0x00001fbb, 0x00001f71, + 0x0001e90b, 0x0001e92d, 0x00000415, 0x00000435, + 0x00001f69, 0x00001f61, 0x000010be, 0x00002d1e, + 0x00010d5f, 0x00010d7f, 0x00002160, 0x00002170, + 0x00001e7c, 0x00001e7d, 0x000001f7, 0x000001bf, + 0x00010423, 0x0001044b, 0x000004ac, 0x000004ad, + 0x00001e3c, 0x00001e3d, 0x00010c8c, 0x00010ccc, + 0x00016eb4, 0x00016ecf, 0x00001ca8, 0x000010e8, + 0x0000023d, 0x0000019a, 0x0001e900, 0x0001e922, + 0x00000401, 0x00000451, 0x00001f98, 0x0200020f, + 0x0000a726, 0x0000a727, 0x0001e90e, 0x0001e930, + 0x0000ab9f, 0x000013cf, 0x00002c2d, 0x00002c5d, + 0x00001ee2, 0x00001ee3, 0x00001e24, 0x00001e25, + 0x00001c93, 0x000010d3, 0x0000a73c, 0x0000a73d, + 0x0000ff26, 0x0000ff46, 0x00000522, 0x00000523, + 0x00001e02, 0x00001e03, 0x0000a74e, 0x0000a74f, + 0x0000040a, 0x0000045a, 0x00001f18, 0x00001f10, + 0x00000228, 0x00000229, 0x0000004b, 0x0000006b, + 0x000118b9, 0x000118d9, 0x00010d62, 0x00010d82, + 0x000001fc, 0x000001fd, 0x0000abb6, 0x000013e6, + 0x00001e64, 0x00001e65, 0x00001fe4, 0x02000294, + 0x000004b8, 0x000004b9, 0x0000ab80, 0x000013b0, + 0x000003f4, 0x000003b8, 0x0000a796, 0x0000a797, + 0x0000aba8, 0x000013d8, 0x000004c3, 0x000004c4, + 0x00001ff4, 0x020002a4, 0x00010ca2, 0x00010ce2, + 0x000013fb, 0x000013f3, 0x000004e2, 0x000004e3, + 0x0000abad, 0x000013dd, 0x00010ca1, 0x00010ce1, + 0x0000024c, 0x0000024d, 0x00001f2e, 0x00001f26, + 0x0000a742, 0x0000a743, 0x0001e903, 0x0001e925, + 0x00001faf, 0x02000254, 0x000010ab, 0x00002d0b, + 0x0000014e, 0x0000014f, 0x0001057e, 0x000105a5, + 0x00001e36, 0x00001e37, 0x00001efc, 0x00001efd, + 0x00010c81, 0x00010cc1, 0x00001f2b, 0x00001f23, + 0x00001e4a, 0x00001e4b, 0x00001e2c, 0x00001e2d, + 0x0000a748, 0x0000a749, 0x0001040c, 0x00010434, + 0x00001e1e, 0x00001e1f, 0x00000158, 0x00000159, + 0x0000abb4, 0x000013e4, 0x00001eb0, 0x00001eb1, + 0x000010aa, 0x00002d0a, 0x0000004a, 0x0000006a, + 0x000001b8, 0x000001b9, 0x00001cb0, 0x000010f0, + 0x000001f2, 0x000001f3, 0x00000390, 0x0300019b, + 0x000004ec, 0x000004ed, 0x00002cde, 0x00002cdf, + 0x00000102, 0x00000103, 0x0000ab83, 0x000013b3, + 0x0000a684, 0x0000a685, 0x00002c09, 0x00002c39, + 0x000024c1, 0x000024db, 0x00001f6d, 0x00001f65, + 0x00001e7e, 0x00001e7f, 0x000001f8, 0x000001f9, + 0x000003d6, 0x000003c0, 0x00010cac, 0x00010cec, + 0x00002ca6, 0x00002ca7, 0x000000c4, 0x000000e4, + 0x00000406, 0x00000456, 0x00001c99, 0x000010d9, + 0x0000a75a, 0x0000a75b, 0x0001e902, 0x0001e924, + 0x00010cae, 0x00010cee, 0x00001f9a, 0x02000215, + 0x00001c86, 0x0000044a, 0x00002164, 0x00002174, + 0x00001cb9, 0x000010f9, 0x00001efe, 0x00001eff, + 0x00010c80, 0x00010cc0, 0x00001ea2, 0x00001ea3, + 0x00001ee0, 0x00001ee1, 0x0000a73a, 0x0000a73b, + 0x0000ff28, 0x0000ff48, 0x00001f6c, 0x00001f64, + 0x00001e04, 0x00001e05, 0x00010d61, 0x00010d81, + 0x0000ab9a, 0x000013ca, 0x00001eb8, 0x00001eb9, + 0x000010ad, 0x00002d0d, 0x00000045, 0x00000065, + 0x000118bb, 0x000118db, 0x0001041a, 0x00010442, + 0x00016eac, 0x00016ec7, 0x0000abbe, 0x000013ee, + 0x00016eb5, 0x00016ed0, 0x0000fb00, 0x020002b1, + 0x00010cb2, 0x00010cf2, 0x0000ab82, 0x000013b2, + 0x000003fa, 0x000003fb, 0x0000a798, 0x0000a799, + 0x00001cb5, 0x000010f5, 0x000004e6, 0x000004e7, + 0x00002c22, 0x00002c52, 0x000000db, 0x000000fb, + 0x00010595, 0x000105bc, 0x000004b0, 0x000004b1, + 0x00016ead, 0x00016ec8, 0x0000ff24, 0x0000ff44, + 0x0000216b, 0x0000217b, 0x000003e2, 0x000003e3, + 0x000004d6, 0x000004d7, 0x0001e905, 0x0001e927, + 0x000010bb, 0x00002d1b, 0x00001e46, 0x00001e47, + 0x00000490, 0x00000491, 0x00002132, 0x0000214e, + 0x00001e97, 0x020001a9, 0x00002c24, 0x00002c54, + 0x00010c83, 0x00010cc3, 0x000004a0, 0x000004a1, + 0x00001eb6, 0x00001eb7, 0x00016e45, 0x00016e65, + 0x0000ab7a, 0x000013aa, 0x000004be, 0x000004bf, + 0x000003ec, 0x000003ed, 0x0000023b, 0x0000023c, + 0x00000541, 0x00000571, 0x00001fb8, 0x00001fb0, + 0x000010ac, 0x00002d0c, 0x0000004c, 0x0000006c, + 0x00000542, 0x00000572, 0x00001c87, 0x00000463, + 0x000001e8, 0x000001e9, 0x00002c82, 0x00002c83, + 0x000004ee, 0x000004ef, 0x00001e6c, 0x00001e6d, + 0x00000104, 0x00000105, 0x0000a7f5, 0x0000a7f6, + 0x00000419, 0x00000439, 0x0000a7ae, 0x0000026a, + 0x0000015e, 0x0000015f, 0x00000421, 0x00000441, + 0x0000a644, 0x0000a645, 0x00000187, 0x00000188, + 0x0001058f, 0x000105b6, 0x000004b4, 0x000004b5, + 0x0001e916, 0x0001e938, 0x000001af, 0x000001b0, + 0x0000fb13, 0x020002c8, 0x00001f0a, 0x00001f02, + 0x0000a75c, 0x0000a75d, 0x0001e906, 0x0001e928, + 0x00000516, 0x00000517, 0x000010a0, 0x00002d00, + 0x00010d58, 0x00010d78, 0x0001e911, 0x0001e933, + 0x00001e7a, 0x00001e7b, 0x0000aba5, 0x000013d5, + 0x00010c82, 0x00010cc2, 0x00001cb1, 0x000010f1, + 0x00001fa7, 0x0200023c, 0x00016e52, 0x00016e72, + 0x0000ff2a, 0x0000ff4a, 0x000004a6, 0x000004a7, + 0x00001e06, 0x00001e07, 0x00001cae, 0x000010ee, + 0x00000141, 0x00000142, 0x00001fa8, 0x0200023f, + 0x000010a7, 0x00002d07, 0x0000004f, 0x0000006f, + 0x000000d3, 0x000000f3, 0x00001ebe, 0x00001ebf, + 0x00016ea2, 0x00016ebd, 0x000118a0, 0x000118c0, + 0x00002cc0, 0x00002cc1, 0x00002cd6, 0x00002cd7, + 0x00001c88, 0x0000a64b, 0x0000ab84, 0x000013b4, + 0x000003a8, 0x000003c8, 0x0000a79a, 0x0000a79b, + 0x0001e91f, 0x0001e941, 0x000118b3, 0x000118d3, + 0x00001e80, 0x00001e81, 0x00000160, 0x00000161, + 0x00000181, 0x00000253, 0x000004b2, 0x000004b3, + 0x00001ee4, 0x00001ee5, 0x000000c8, 0x000000e8, + 0x0000ff31, 0x0000ff51, 0x00002c6f, 0x00000250, + 0x00010420, 0x00010448, 0x0001e907, 0x0001e929, + 0x000001a9, 0x00000283, 0x00001e3a, 0x00001e3b, + 0x00001caa, 0x000010ea, 0x0001057a, 0x000105a1, + 0x0000046c, 0x0000046d, 0x00001ca6, 0x000010e6, + 0x00010c85, 0x00010cc5, 0x00000543, 0x00000573, + 0x00001ef6, 0x00001ef7, 0x0000abab, 0x000013db, + 0x000104b1, 0x000104d9, 0x000118b8, 0x000118d8, + 0x000003c2, 0x000003c3, 0x000000d6, 0x000000f6, + 0x0000ff36, 0x0000ff56, 0x00001ff9, 0x00001f79, + 0x000010ae, 0x00002d0e, 0x0000004e, 0x0000006e, + 0x000118bd, 0x000118dd, 0x00001ede, 0x00001edf, + 0x0000015a, 0x0000015b, 0x00000243, 0x00000180, + 0x000004f0, 0x000004f1, 0x0000fb04, 0x030002be, + 0x00000106, 0x00000107, 0x0000ab87, 0x000013b7, + 0x0001040a, 0x00010432, 0x00001e1a, 0x00001e1b, + 0x00010570, 0x00010597, 0x00002cb8, 0x00002cb9, + 0x000010c4, 0x00002d24, 0x00001f19, 0x00001f11, + 0x0000a7c9, 0x0000a7ca, 0x00002cb6, 0x00002cb7, + 0x00000208, 0x00000209, 0x000000cc, 0x000000ec, + 0x0000048a, 0x0000048b, 0x00000216, 0x00000217, + 0x00000224, 0x00000225, 0x00010ca8, 0x00010ce8, + 0x000104ce, 0x000104f6, 0x000010bc, 0x00002d1c, + 0x00001eae, 0x00001eaf, 0x00002cba, 0x00002cbb, + 0x00000472, 0x00000473, 0x00002c2a, 0x00002c5a, + 0x00010c86, 0x00010cc6, 0x000024bb, 0x000024d5, + 0x00001e56, 0x00001e57, 0x0000a66c, 0x0000a66d, + 0x000104b0, 0x000104d8, 0x000010b9, 0x00002d19, + 0x00001e08, 0x00001e09, 0x00001e20, 0x00001e21, + 0x0000039b, 0x000003bb, 0x00001fa4, 0x02000233, + 0x000010b1, 0x00002d11, 0x00000051, 0x00000071, + 0x00000145, 0x00000146, 0x00001ec0, 0x00001ec1, + 0x00001ff8, 0x00001f78, 0x00010c98, 0x00010cd8, + 0x00016ea4, 0x00016ebf, 0x00010d64, 0x00010d84, + 0x00001c9e, 0x000010de, 0x0000ab86, 0x000013b6, + 0x000003fe, 0x0000037c, 0x0000a79c, 0x0000a79d, + 0x0000040c, 0x0000045c, 0x000118a3, 0x000118c3, + 0x00002c18, 0x00002c48, 0x000001c7, 0x000001c9, + 0x000013f8, 0x000013f0, 0x000004b6, 0x000004b7, + 0x00000226, 0x00000227, 0x000000ca, 0x000000ea, + 0x0000ab98, 0x000013c8, 0x00002ce2, 0x00002ce3, + 0x000003a0, 0x000003c0, 0x0001e909, 0x0001e92b, + 0x00002c07, 0x00002c37, 0x00000397, 0x000003b7, + 0x00000182, 0x00000183, 0x0000a686, 0x0000a687, + 0x00001fb2, 0x02000257, 0x00002c2c, 0x00002c5c, + 0x00010c87, 0x00010cc7, 0x000118b0, 0x000118d0, + 0x000024bd, 0x000024d7, 0x0000a722, 0x0000a723, + 0x000104b3, 0x000104db, 0x00002c17, 0x00002c47, + 0x0000a7d6, 0x0000a7d7, 0x00001c98, 0x000010d8, + 0x00010c9e, 0x00010cde, 0x00001f97, 0x0200020c, + 0x000010b0, 0x00002d10, 0x00000050, 0x00000070, + 0x000118a2, 0x000118c2, 0x00002cda, 0x00002cdb, + 0x00001e6e, 0x00001e6f, 0x0000a648, 0x0000a649, + 0x000004f2, 0x000004f3, 0x0000fb06, 0x020002c5, + 0x00000108, 0x00000109, 0x0000ab81, 0x000013b1, + 0x00001eaa, 0x00001eab, 0x0000018b, 0x0000018c, + 0x00000156, 0x00000157, 0x00002126, 0x000003c9, + 0x00001e84, 0x00001e85, 0x0000ff23, 0x0000ff43, + 0x000013fa, 0x000013f2, 0x000104cc, 0x000104f4, + 0x00001f9f, 0x02000224, 0x000003d8, 0x000003d9, + 0x0000a78b, 0x0000a78c, 0x00016ea3, 0x00016ebe, + 0x00001ca9, 0x000010e9, 0x00001fd3, 0x03000281, + 0x00002c63, 0x00001d7d, 0x0000a792, 0x0000a793, + 0x00000186, 0x00000254, 0x00010571, 0x00010598, + 0x00000478, 0x00000479, 0x00001eee, 0x00001eef, + 0x00010588, 0x000105af, 0x00002c6d, 0x00000251, + 0x00001e92, 0x00001e93, 0x00016e4e, 0x00016e6e, + 0x000104b2, 0x000104da, 0x00000534, 0x00000564, + 0x00001e0a, 0x00001e0b, 0x00001c9a, 0x000010da, + 0x0000ab72, 0x000013a2, 0x00000466, 0x00000467, + 0x000010b3, 0x00002d13, 0x00000053, 0x00000073, + 0x00000533, 0x00000563, 0x00001ec2, 0x00001ec3, + 0x000003de, 0x000003df, 0x00010421, 0x00010449, + 0x0000212b, 0x000000e5, 0x0000ab73, 0x000013a3, + 0x00000120, 0x00000121, 0x0000ab88, 0x000013b8, + 0x00010422, 0x0001044a, 0x0000a79e, 0x0000a79f, + 0x00000393, 0x000003b3, 0x000118a1, 0x000118c1, + 0x00002c64, 0x0000027d, 0x0000019c, 0x0000026f, + 0x000118b1, 0x000118d1, 0x0000ab77, 0x000013a7, + 0x0001e915, 0x0001e937, 0x000000ce, 0x000000ee, + 0x00002c8a, 0x00002c8b, 0x00000547, 0x00000577, + 0x0000a7b0, 0x0000029e, 0x0000ab9e, 0x000013ce, + 0x00000400, 0x00000450, 0x000024bf, 0x000024d9, + 0x00000184, 0x00000185, 0x0000a680, 0x0000a681, + 0x00000427, 0x00000447, 0x0000014a, 0x0000014b, + 0x00010c89, 0x00010cc9, 0x00016eb0, 0x00016ecb, + 0x0001e90f, 0x0001e931, 0x00016e5e, 0x00016e7e, + 0x000104b5, 0x000104dd, 0x000000d1, 0x000000f1, + 0x0000a7cb, 0x00000264, 0x0001e908, 0x0001e92a, + 0x000024ca, 0x000024e4, 0x00001fec, 0x00001fe5, + 0x000010b2, 0x00002d12, 0x00000052, 0x00000072, + 0x00010404, 0x0001042c, 0x0000037f, 0x000003f3, + 0x00000179, 0x0000017a, 0x000001b3, 0x000001b4, + 0x000004f4, 0x000004f5, 0x0001e90a, 0x0001e92c, + 0x0000010a, 0x0000010b, 0x0000ab8b, 0x000013bb, + 0x00000426, 0x00000446, 0x0000a7bc, 0x0000a7bd, + 0x0000021a, 0x0000021b, 0x00002c86, 0x00002c87, + 0x00001e86, 0x00001e87, 0x0000040e, 0x0000045e, + 0x0000a688, 0x0000a689, 0x0000a77d, 0x00001d79, + 0x00002c0d, 0x00002c3d, 0x000000c6, 0x000000e6, + 0x000118b7, 0x000118d7, 0x00001f3e, 0x00001f36, + 0x0000a760, 0x0000a761, 0x0000abaa, 0x000013da, + 0x000010c7, 0x00002d27, 0x00001e52, 0x00001e53, + 0x000000de, 0x000000fe, 0x00001e28, 0x00001e29, + 0x00001fb4, 0x0200025d, 0x00002c2e, 0x00002c5e, + 0x00010c8a, 0x00010cca, 0x0000a7ad, 0x0000026c, + 0x00002c03, 0x00002c33, 0x0000a664, 0x0000a665, + 0x000104b6, 0x000104de, 0x00002cce, 0x00002ccf, + 0x00001e0c, 0x00001e0d, 0x0000014c, 0x0000014d, + 0x00002c2f, 0x00002c5f, 0x00000464, 0x00000465, + 0x000010b5, 0x00002d15, 0x00000055, 0x00000075, + 0x0001040d, 0x00010435, 0x00001ec4, 0x00001ec5, + 0x00016eb8, 0x00016ed3, 0x0000ab7b, 0x000013ab, + 0x0000abb5, 0x000013e5, 0x0000fb02, 0x020002b7, + 0x000004da, 0x000004db, 0x0000ab8a, 0x000013ba, + 0x00002c92, 0x00002c93, 0x0000a7a0, 0x0000a7a1, + 0x00002c9a, 0x00002c9b, 0x00002c8c, 0x00002c8d, + 0x00002c62, 0x0000026b, 0x0000aba7, 0x000013d7, + 0x000013fc, 0x000013f4, 0x000004ba, 0x000004bb, + 0x0001041b, 0x00010443, 0x00002c25, 0x00002c55, + 0x000004c7, 0x000004c8, 0x0000021c, 0x0000021d, + 0x0000a7ce, 0x0000a7cf, 0x00002165, 0x00002175, + 0x00000403, 0x00000453, 0x0000a7b6, 0x0000a7b7, + 0x0000a65c, 0x0000a65d, 0x00000414, 0x00000434, + 0x0000053e, 0x0000056e, 0x0000a66a, 0x0000a66b, + 0x00010c8b, 0x00010ccb, 0x000024b7, 0x000024d1, + 0x0001e91c, 0x0001e93e, 0x000024c4, 0x000024de, + 0x000104b7, 0x000104df, 0x0000052e, 0x0000052f, + 0x0000a77e, 0x0000a77f, 0x00001c84, 0x00000442, + 0x00010c9c, 0x00010cdc, 0x0000041b, 0x0000043b, + 0x000010b4, 0x00002d14, 0x00000054, 0x00000074, + 0x00000544, 0x00000574, 0x00001f54, 0x030001bf, + 0x000000cf, 0x000000ef, 0x0000ff38, 0x0000ff58, + 0x000004f6, 0x000004f7, 0x00001f68, 0x00001f60, + 0x0000010c, 0x0000010d, 0x0000ab8d, 0x000013bd, + 0x00002cae, 0x00002caf, 0x0000a7ba, 0x0000a7bb, + 0x00016ea9, 0x00016ec4, 0x000118bc, 0x000118dc, + 0x00001e8a, 0x00001e8b, 0x000001c4, 0x000001c6, + 0x000003cf, 0x000003d7, 0x0000041d, 0x0000043d, + 0x00001fad, 0x0200024e, 0x00001fa5, 0x02000236, + 0x0000050c, 0x0000050d, 0x00010418, 0x00010440, + 0x0000a766, 0x0000a767, 0x0000ab96, 0x000013c6, + 0x00000528, 0x00000529, 0x00002cd8, 0x00002cd9, + 0x0000018e, 0x000001dd, 0x00010400, 0x00010428, + 0x00001e96, 0x020001a6, 0x00001ef2, 0x00001ef3, + 0x00010c84, 0x00010cc4, 0x000004d4, 0x000004d5, + 0x00001fb7, 0x03000263, 0x00001e38, 0x00001e39, + 0x00000545, 0x00000575, 0x00010416, 0x0001043e, + 0x00001e0e, 0x00001e0f, 0x0000216d, 0x0000217d, + 0x00000391, 0x000003b1, 0x00002c21, 0x00002c51, + 0x000010b7, 0x00002d17, 0x00010572, 0x00010599, + 0x00001ca7, 0x000010e7, 0x00001ec6, 0x00001ec7, + 0x00001f0f, 0x00001f07, 0x00002162, 0x00002172, + 0x00000496, 0x00000497, 0x00001fb9, 0x00001fb1, + 0x00001c90, 0x000010d0, 0x0000ab8c, 0x000013bc, + 0x00001f2a, 0x00001f22, 0x0000a7a2, 0x0000a7a3, + 0x0000abba, 0x000013ea, 0x00001cb3, 0x000010f3, + 0x00001e82, 0x00001e83, 0x000001c5, 0x000001c6, + 0x0000049e, 0x0000049f, 0x000001a7, 0x000001a8, + 0x00016e46, 0x00016e66, 0x000000d2, 0x000000f2, + 0x00000512, 0x00000513, 0x00001f2c, 0x00001f24, + 0x00001fa1, 0x0200022a, 0x000024c9, 0x000024e3, + 0x0000052a, 0x0000052b, 0x00001e4c, 0x00001e4d, + 0x00001cac, 0x000010ec, 0x00010401, 0x00010429, + 0x00001eba, 0x00001ebb, 0x000118be, 0x000118de, + 0x00010c8d, 0x00010ccd, 0x0000abb7, 0x000013e7, + 0x000000d0, 0x000000f0, 0x0000abb9, 0x000013e9, + 0x000104b9, 0x000104e1, 0x00000555, 0x00000585, + 0x00001e16, 0x00001e17, 0x0000016c, 0x0000016d, + 0x00002161, 0x00002171, 0x00001f8d, 0x020001ee, + 0x000010b6, 0x00002d16, 0x00000056, 0x00000076, + 0x000004e4, 0x000004e5, 0x00002183, 0x00002184, + 0x00001f4d, 0x00001f45, 0x0000049a, 0x0000049b, + 0x000004f8, 0x000004f9, 0x0000a724, 0x0000a725, + 0x0000010e, 0x0000010f, 0x0000ab8f, 0x000013bf, + 0x00001f3f, 0x00001f37, 0x0000a782, 0x0000a783, + 0x0000abaf, 0x000013df, 0x00002ca8, 0x00002ca9, + 0x000010c2, 0x00002d22, 0x00002167, 0x00002177, + 0x00001caf, 0x000010ef, 0x000024b6, 0x000024d0, + 0x00000417, 0x00000437, 0x00002c6b, 0x00002c6c, + 0x0000048c, 0x0000048d, 0x0001040e, 0x00010436, + 0x0000a764, 0x0000a765, 0x00002c1f, 0x00002c4f, + 0x00000554, 0x00000584, 0x00002c1e, 0x00002c4e, + 0x00000139, 0x0000013a, 0x00010402, 0x0001042a, + 0x0000ff33, 0x0000ff53, 0x0001e91e, 0x0001e940, + 0x00010c8e, 0x00010cce, 0x00002c80, 0x00002c81, + 0x00002c16, 0x00002c46, 0x0000024a, 0x0000024b, + 0x000104ba, 0x000104e2, 0x00016ea6, 0x00016ec1, + 0x00001e10, 0x00001e11, 0x00001cb6, 0x000010f6, + 0x0000054e, 0x0000057e, 0x00001fa6, 0x02000239, + 0x00000245, 0x0000028c, 0x00010574, 0x0001059b, + 0x000000c7, 0x000000e7, 0x00001ec8, 0x00001ec9, + 0x0000a65e, 0x0000a65f, 0x0000041e, 0x0000043e, + 0x00000425, 0x00000445, 0x00000202, 0x00000203, + 0x00010427, 0x0001044f, 0x0000ab8e, 0x000013be, + 0x00001f80, 0x020001c7, 0x0000a7a4, 0x0000a7a5, + 0x0000abb8, 0x000013e8, 0x0000a779, 0x0000a77a, + 0x000024c2, 0x000024dc, 0x0001e90c, 0x0001e92e, + 0x00001eea, 0x00001eeb, 0x000024bc, 0x000024d6, + 0x00010d60, 0x00010d80, 0x000001d9, 0x000001da, + 0x000010c1, 0x00002d21, 0x000001f1, 0x000001f3, + 0x00000100, 0x00000101, 0x00001e62, 0x00001e63, + 0x00002c0c, 0x00002c3c, 0x0000a7b4, 0x0000a7b5, + 0x0000018a, 0x00000257, 0x00010403, 0x0001042b, + 0x00000498, 0x00000499, 0x000118b2, 0x000118d2, + 0x00010c8f, 0x00010ccf, 0x00002cd2, 0x00002cd3, + 0x0000053b, 0x0000056b, 0x00000214, 0x00000215, + 0x000104bb, 0x000104e3, 0x000004c1, 0x000004c2, + 0x0000a74c, 0x0000a74d, 0x0000016a, 0x0000016b, + 0x00000538, 0x00000568, 0x00001f0c, 0x00001f04, + 0x00000587, 0x020001a3, 0x00010573, 0x0001059a, + 0x000118a7, 0x000118c7, 0x00001e42, 0x00001e43, + 0x000003ff, 0x0000037d, 0x00016ea5, 0x00016ec0, + 0x000004fa, 0x000004fb, 0x00001e8c, 0x00001e8d, + 0x00000110, 0x00000111, 0x00002c05, 0x00002c35, + 0x00001f81, 0x020001ca, 0x00001eec, 0x00001eed, + 0x00000210, 0x00000211, 0x0000ab91, 0x000013c1, + 0x00001e8e, 0x00001e8f, 0x000001c8, 0x000001c9, + 0x000024cb, 0x000024e5, 0x00010590, 0x000105b7, + 0x00016e47, 0x00016e67, 0x0000a7b3, 0x0000ab53, + 0x00002c10, 0x00002c40, 0x00002c12, 0x00002c42, + 0x0000a76a, 0x0000a76b, 0x0000ab79, 0x000013a9, + 0x00000552, 0x00000582, 0x0000a7c0, 0x0000a7c1, + 0x000001f0, 0x02000198, 0x00010407, 0x0001042f, + 0x00001fb3, 0x0200025a, 0x0000ff2d, 0x0000ff4d, + 0x00010c90, 0x00010cd0, 0x00002c9e, 0x00002c9f, + 0x00001f28, 0x00001f20, 0x000010cd, 0x00002d2d, + 0x000104b4, 0x000104dc, 0x00000546, 0x00000576, + 0x00001e12, 0x00001e13, 0x00000154, 0x00000155, + 0x0000052c, 0x0000052d, 0x00001f6f, 0x00001f67, + 0x00000166, 0x00000167, 0x00000058, 0x00000078, + 0x00002c8e, 0x00002c8f, 0x00001eca, 0x00001ecb, + 0x00000411, 0x00000431, 0x00001f1d, 0x00001f15, + 0x0000ab99, 0x000013c9, 0x00000200, 0x00000201, + 0x00001ff7, 0x030002aa, 0x000104cf, 0x000104f7, + 0x00001f82, 0x020001cd, 0x0000a7a6, 0x0000a7a7, + 0x0000aba6, 0x000013d6, 0x00002c84, 0x00002c85, + 0x00001e88, 0x00001e89, 0x000001cb, 0x000001cc, + 0x00000410, 0x00000430, 0x000004bc, 0x000004bd, + 0x0000a68e, 0x0000a68f, 0x0000048e, 0x0000048f, + 0x00000518, 0x00000519, 0x00010cad, 0x00010ced, + 0x0000020a, 0x0000020b, 0x0000041c, 0x0000043c, + 0x00002c90, 0x00002c91, 0x00001fe6, 0x02000297, + 0x000024cd, 0x000024e7, 0x00010405, 0x0001042d, + 0x00001eac, 0x00001ead, 0x000001fa, 0x000001fb, + 0x00010c91, 0x00010cd1, 0x00002c15, 0x00002c45, + 0x0000039c, 0x000003bc, 0x00000244, 0x00000289, + 0x000104bd, 0x000104e5, 0x00000520, 0x00000521, + 0x0000a7c6, 0x00001d8e, 0x00001c96, 0x000010d6, + 0x00002cc4, 0x00002cc5, 0x000010c5, 0x00002d25, + 0x0000a68c, 0x0000a68d, 0x00010575, 0x0001059c, + 0x000024c3, 0x000024dd, 0x0000013b, 0x0000013c, + 0x0000022c, 0x0000022d, 0x000024ce, 0x000024e8, + 0x000004fc, 0x000004fd, 0x00001e72, 0x00001e73, + 0x00000112, 0x00000113, 0x0000ab78, 0x000013a8, + 0x00001f83, 0x020001d0, 0x0000a654, 0x0000a655, + 0x0000abbc, 0x000013ec, 0x00001fe2, 0x0300028c, + 0x00016eb6, 0x00016ed1, 0x000001ca, 0x000001cc, + 0x0000ff34, 0x0000ff54, 0x000024be, 0x000024d8, + 0x00016e49, 0x00016e69, 0x000003f1, 0x000003c1, + 0x0000ff21, 0x0000ff41, 0x00002c0f, 0x00002c3f, + 0x0000a73e, 0x0000a73f, 0x0000abb2, 0x000013e2, + 0x0001058e, 0x000105b5, 0x00001ef8, 0x00001ef9, + 0x00002ca0, 0x00002ca1, 0x0001e914, 0x0001e936, + 0x00001fcc, 0x0200027a, 0x000001d1, 0x000001d2, + 0x00010c92, 0x00010cd2, 0x00010c9a, 0x00010cda, + 0x00001f38, 0x00001f30, 0x0000a740, 0x0000a741, + 0x000104be, 0x000104e6, 0x0000053a, 0x0000056a, + 0x00000389, 0x000003ae, 0x00000164, 0x00000165, + 0x00000524, 0x00000525, 0x00001e9a, 0x020001b2, + 0x00016eab, 0x00016ec6, 0x0000005a, 0x0000007a, + 0x00002c88, 0x00002c89, 0x00001ecc, 0x00001ecd, + 0x00000218, 0x00000219, 0x00002cbe, 0x00002cbf, + 0x000004d8, 0x000004d9, 0x00000232, 0x00000233, + 0x000000df, 0x0200018f, 0x000118a8, 0x000118c8, + 0x00001f84, 0x020001d3, 0x0000a7a8, 0x0000a7a9, + 0x00000494, 0x00000495, 0x0000212a, 0x0000006b, + 0x0000a7be, 0x0000a7bf, 0x00010419, 0x00010441, + 0x00001fe3, 0x03000290, 0x000024c8, 0x000024e2, + 0x000118ae, 0x000118ce, 0x000000d4, 0x000000f4, + 0x0000050a, 0x0000050b, 0x00001f6e, 0x00001f66, + 0x00001fd8, 0x00001fd0, 0x0000a77b, 0x0000a77c, + 0x0000054c, 0x0000057c, 0x00001f3a, 0x00001f32, + 0x00000212, 0x00000213, 0x0000216c, 0x0000217c, + 0x00001e5c, 0x00001e5d, 0x0000a658, 0x0000a659, + 0x00010c93, 0x00010cd3, 0x00000408, 0x00000458, + 0x000001db, 0x000001dc, 0x00000246, 0x00000247, + 0x000104bf, 0x000104e7, 0x00001fd7, 0x03000288, + 0x00001e14, 0x00001e15, 0x0000012e, 0x0000012f, + 0x00001fc7, 0x03000276, 0x00000474, 0x00000475, + 0x0000017f, 0x00000073, 0x00010577, 0x0001059e, + 0x00002c04, 0x00002c34, 0x00002caa, 0x00002cab, + 0x0000a652, 0x0000a653, 0x00001e6a, 0x00001e6b, + 0x000004fe, 0x000004ff, 0x00000204, 0x00000205, + 0x00000114, 0x00000115, 0x00002cd0, 0x00002cd1, + 0x00001f87, 0x020001dc, 0x0000a7b8, 0x0000a7b9, + 0x00001f0d, 0x00001f05, 0x000004c5, 0x000004c6, + 0x000001ac, 0x000001ad, 0x0000a736, 0x0000a737, + 0x0000ff3a, 0x0000ff5a, 0x000024b8, 0x000024d2, + 0x00016e4b, 0x00016e6b, 0x0000fb17, 0x020002d4, + 0x0000041f, 0x0000043f, 0x00001f48, 0x00001f40, + 0x00001e00, 0x00001e01, 0x00002c75, 0x00002c76, + 0x00001ca2, 0x000010e2, 0x00001f1a, 0x00001f12, + 0x000000c3, 0x000000e3, 0x000004a4, 0x000004a5, + 0x00001c89, 0x00001c8a, 0x00000150, 0x00000151, + 0x00010c94, 0x00010cd4, 0x0000a762, 0x0000a763, + 0x00002c94, 0x00002c95, 0x0000a728, 0x0000a729, + 0x000104c0, 0x000104e8, 0x0000a7c5, 0x00000282, + 0x00000241, 0x00000242, 0x00000152, 0x00000153, + 0x0000216f, 0x0000217f, 0x00001f9e, 0x02000221, + 0x00001fe9, 0x00001fe1, 0x00010578, 0x0001059f, + 0x00010406, 0x0001042e, 0x00001ece, 0x00001ecf, + 0x0000020e, 0x0000020f, 0x00000418, 0x00000438, + 0x00000502, 0x00000503, 0x00001c81, 0x00000434, + 0x0000fb03, 0x030002ba, 0x000024ba, 0x000024d4, + 0x00001f86, 0x020001d9, 0x0000a7aa, 0x00000266, + 0x0000abae, 0x000013de, 0x00000395, 0x000003b5, + 0x000118b6, 0x000118d6, 0x000001cf, 0x000001d0, + 0x0000ab75, 0x000013a5, 0x000004c0, 0x000004cf, + 0x00016e4c, 0x00016e6c, 0x00001e74, 0x00001e75, + 0x0000049c, 0x0000049d, 0x00001f29, 0x00001f21, + 0x0000a64e, 0x0000a64f, 0x000104c8, 0x000104f0, + 0x00001f9c, 0x0200021b, 0x00001e4e, 0x00001e4f, + 0x0000a662, 0x0000a663, 0x00000405, 0x00000455, + 0x000024c0, 0x000024da, 0x0000a746, 0x0000a747, + 0x00010c95, 0x00010cd5, 0x00000143, 0x00000144, + 0x00001f08, 0x00001f00, 0x000003e0, 0x000003e1, + 0x000104c1, 0x000104e9, 0x0000047c, 0x0000047d, + 0x0000a72c, 0x0000a72d, 0x000001fe, 0x000001ff, + 0x0000039f, 0x000003bf, 0x0000a784, 0x0000a785, + 0x0000a738, 0x0000a739, 0x00010579, 0x000105a0, + 0x00001c9f, 0x000010df, 0x000013fd, 0x000013f5, + 0x0000023e, 0x00002c66, 0x00010d5e, 0x00010d7e, + 0x00000500, 0x00000501, 0x00000220, 0x0000019e, + 0x00000116, 0x00000117, 0x00016eb1, 0x00016ecc, + 0x00001feb, 0x00001f7b, 0x00000172, 0x00000173, + 0x000000b5, 0x000003bc, 0x0000019f, 0x00000275, + 0x00001e90, 0x00001e91, 0x00001e22, 0x00001e23, + 0x00001c85, 0x00000442, 0x00002169, 0x00002179, + 0x00016e4d, 0x00016e6d, 0x00000531, 0x00000561, + 0x0000ab71, 0x000013a1, 0x00000398, 0x000003b8, + 0x0000a642, 0x0000a643, 0x00001fc3, 0x0200026d, + 0x00000526, 0x00000527, 0x0000a7d8, 0x0000a7d9, + 0x0000039e, 0x000003be, 0x00010411, 0x00010439, + 0x0000a732, 0x0000a733, 0x000001cd, 0x000001ce, + 0x00001fa9, 0x02000242, 0x000010c3, 0x00002d23, + 0x00000388, 0x000003ad, 0x00000248, 0x00000249, + 0x000104c2, 0x000104ea, 0x00000178, 0x000000ff, + 0x00001e18, 0x00001e19, 0x0001e91b, 0x0001e93d, + 0x00010ca0, 0x00010ce0, 0x00001ea4, 0x00001ea5, + 0x00000539, 0x00000569, 0x00001f2d, 0x00001f25, + 0x00002c60, 0x00002c61, 0x00001ed0, 0x00001ed1, + 0x00002c0b, 0x00002c3b, 0x00010594, 0x000105bb, + 0x00000504, 0x00000505, 0x0000abbd, 0x000013ed, + 0x0000011a, 0x0000011b, 0x000001a0, 0x000001a1, + 0x00001f88, 0x020001df, 0x0000038a, 0x000003af, + 0x000003e4, 0x000003e5, 0x00002cc8, 0x00002cc9, + 0x00010cb0, 0x00010cf0, 0x0000a68a, 0x0000a68b, + 0x000003ab, 0x000003cb, 0x00000476, 0x00000477, + 0x00016e48, 0x00016e68, 0x000000d8, 0x000000f8, + 0x00002c0e, 0x00002c3e, 0x00001f4a, 0x00001f42, + 0x0000a64c, 0x0000a64d, 0x0000ab85, 0x000013b5, + 0x00000402, 0x00000452, 0x00002c1a, 0x00002c4a, + 0x00000190, 0x0000025b, 0x0001040b, 0x00010433, + 0x00002c7e, 0x0000023f, 0x0000a668, 0x0000a669, + 0x00010c97, 0x00010cd7, 0x000003a3, 0x000003c3, + 0x00001f0e, 0x00001f06, 0x00016e43, 0x00016e63, + 0x000104c3, 0x000104eb, 0x00001fc2, 0x0200026a, + 0x0000020c, 0x0000020d, 0x0001e921, 0x0001e943, + 0x0000039d, 0x000003bd, 0x00001f5f, 0x00001f57, + 0x0000a690, 0x0000a691, 0x00000049, 0x00000069, + 0x000001b1, 0x0000028a, 0x0000abbf, 0x000013ef, + 0x0000022e, 0x0000022f, 0x00001eb2, 0x00001eb3, + 0x00000556, 0x00000586, 0x000000d5, 0x000000f5, + 0x00000118, 0x00000119, 0x00000514, 0x00000515, + 0x00001f8b, 0x020001e8, 0x00010d65, 0x00010d85, + 0x0000024e, 0x0000024f, 0x0000047a, 0x0000047b, + 0x00001ffc, 0x020002ae, 0x00000057, 0x00000077, + 0x000003a7, 0x000003c7, 0x00001f6b, 0x00001f63, + 0x00016e4f, 0x00016e6f, 0x0000fb05, 0x020002c2, + 0x0000054a, 0x0000057a, 0x00002c0a, 0x00002c3a, + 0x00001ea8, 0x00001ea9, 0x00010410, 0x00010438, + 0x0000042d, 0x0000044d, 0x000010c0, 0x00002d20, + 0x000001b2, 0x0000028b, 0x0000ff2e, 0x0000ff4e, + 0x00001c97, 0x000010d7, 0x000001e6, 0x000001e7, + 0x000118a6, 0x000118c6, 0x00002c19, 0x00002c49, + 0x00001fba, 0x00001f70, 0x00010ca5, 0x00010ce5, + 0x000104c4, 0x000104ec, 0x000003e6, 0x000003e7, + 0x0000a7c4, 0x0000a794, 0x00010d50, 0x00010d70, + 0x0000ab76, 0x000013a6, 0x00001ffa, 0x00001f7c, + 0x000001ae, 0x00000288, 0x0001057c, 0x000105a3, + 0x00000407, 0x00000457, 0x00001ed2, 0x00001ed3, + 0x00001c95, 0x000010d5, 0x00000409, 0x00000459, + 0x000010bf, 0x00002d1f, 0x00016ea8, 0x00016ec3, + 0x0000011c, 0x0000011d, 0x00016eaa, 0x00016ec5, + 0x00001f8a, 0x020001e5, 0x00001cba, 0x000010fa, + 0x0000ff32, 0x0000ff52, 0x00001fc4, 0x02000270, + 0x00001f5d, 0x00001f55, 0x000001d3, 0x000001d4, + 0x00001fcb, 0x00001f75, 0x00002c02, 0x00002c32, + 0x00016e50, 0x00016e70, 0x00002c01, 0x00002c31, + 0x0001e910, 0x0001e932, 0x00001fc6, 0x02000273, + 0x00000128, 0x00000129, 0x000003d5, 0x000003c6, + 0x00001f89, 0x020001e2, 0x000013f9, 0x000013f1, + 0x00000196, 0x00000269, 0x0000216e, 0x0000217e, + 0x00001fd9, 0x00001fd1, 0x0000a790, 0x0000a791, + 0x00010591, 0x000105b8, 0x00002c00, 0x00002c30, + 0x00001e78, 0x00001e79, 0x0000ff29, 0x0000ff49, + 0x000104c5, 0x000104ed, 0x000003ea, 0x000003eb, + 0x0000a7d2, 0x0000a7d3, 0x00010d51, 0x00010d71, + 0x00001cb7, 0x000010f7, 0x00001fd2, 0x0300027d, + 0x0000a692, 0x0000a693, 0x0001057d, 0x000105a4, + 0x00010425, 0x0001044d, 0x00001ed6, 0x00001ed7, + 0x00002c67, 0x00002c68, 0x00002c2b, 0x00002c5b, + 0x00000536, 0x00000566, 0x00010415, 0x0001043d, + 0x0000a76c, 0x0000a76d, 0x00000540, 0x00000570, + 0x00001f85, 0x020001d6, 0x0000012c, 0x0000012d, + 0x000118b5, 0x000118d5, 0x00001e76, 0x00001e77, + 0x00001e94, 0x00001e95, 0x000003dc, 0x000003dd, + 0x0000aba3, 0x000013d3, 0x00000462, 0x00000463, + 0x00016e51, 0x00016e71, 0x00002c9c, 0x00002c9d, + 0x0000041a, 0x0000043a, 0x00001f4c, 0x00001f44, + 0x00000162, 0x00000163, 0x00001f39, 0x00001f31, + 0x00000480, 0x00000481, 0x00001e40, 0x00001e41, + 0x0000a666, 0x0000a667, 0x00010409, 0x00010431, + 0x00002cd4, 0x00002cd5, 0x00001fa3, 0x02000230, + 0x00010c99, 0x00010cd9, 0x0000ab9d, 0x000013cd, + 0x00001e50, 0x00001e51, 0x00010417, 0x0001043f, + 0x0000054f, 0x0000057f, 0x000003e8, 0x000003e9, + 0x0000a7c7, 0x0000a7c8, 0x00010d52, 0x00010d72, + 0x00000548, 0x00000578, 0x00001fea, 0x00001f7a, + 0x000001ee, 0x000001ef, 0x00010576, 0x0001059d, + 0x000104d0, 0x000104f8, 0x00001ed4, 0x00001ed5, + 0x0000a744, 0x0000a745, 0x000118ad, 0x000118cd, + 0x00002c1b, 0x00002c4b, 0x00001f9d, 0x0200021e, + 0x00001c80, 0x00000432, 0x0000051a, 0x0000051b, + 0x00001f8c, 0x020001eb, 0x0000a646, 0x0000a647, + 0x0000ff22, 0x0000ff42, 0x00001c9b, 0x000010db, + 0x00010d5c, 0x00010d7c, 0x000001d5, 0x000001d6, + 0x00000412, 0x00000432, 0x00010ca4, 0x00010ce4, + 0x0000ab92, 0x000013c2, 0x00000168, 0x00000169, + 0x0000050e, 0x0000050f, 0x00001e9b, 0x00001e61, + 0x000001e0, 0x000001e1, 0x00001f4b, 0x00001f43, + 0x00001fa2, 0x0200022d, 0x0000a7cc, 0x0000a7cd, + 0x00000194, 0x00000263, 0x00016eb2, 0x00016ecd, + 0x000118aa, 0x000118ca, 0x000001de, 0x000001df, + 0x0001058a, 0x000105b1, 0x0000ab93, 0x000013c3, + 0x00001fc9, 0x00001f73, 0x0000a640, 0x0000a641, + 0x000104c7, 0x000104ef, 0x00000416, 0x00000436, + 0x0000a7d0, 0x0000a7d1 }; static const unsigned _uccase_extra_table[] = { diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index a8a75eff7086..b45e7416c773 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -32,7 +30,6 @@ #include "zend_exceptions.h" #include "ext/spl/spl_exceptions.h" #include "zend_interfaces.h" -#include "zend_attributes.h" #include "mysqli_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(mysqli) @@ -136,10 +133,6 @@ void php_clear_mysql(MY_MYSQL *mysql) { zend_string_release_ex(mysql->hash_key, 0); mysql->hash_key = NULL; } - if (!Z_ISUNDEF(mysql->li_read)) { - zval_ptr_dtor(&(mysql->li_read)); - ZVAL_UNDEF(&mysql->li_read); - } } /* }}} */ @@ -316,7 +309,7 @@ static int mysqli_object_has_property(zend_object *object, zend_string *name, in zval rv; zval *value = mysqli_read_property(object, name, BP_VAR_IS, cache_slot, &rv); if (value != &EG(uninitialized_zval)) { - has_property = zval_is_true(value); + has_property = zend_is_true(value); zval_ptr_dtor(value); } break; @@ -330,7 +323,7 @@ static int mysqli_object_has_property(zend_object *object, zend_string *name, in } break; } - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } else { has_property = zend_std_has_property(object, name, has_set_exists, cache_slot); @@ -365,12 +358,11 @@ HashTable *mysqli_object_get_debug_info(zend_object *object, int *is_temp) PHP_MYSQLI_EXPORT(zend_object *) mysqli_objects_new(zend_class_entry *class_type) { mysqli_object *intern; - zend_class_entry *mysqli_base_class; zend_object_handlers *handlers; intern = zend_object_alloc(sizeof(mysqli_object), class_type); - mysqli_base_class = class_type; + const zend_class_entry *mysqli_base_class = class_type; while (mysqli_base_class->type != ZEND_INTERNAL_CLASS && mysqli_base_class->parent != NULL) { mysqli_base_class = mysqli_base_class->parent; @@ -424,6 +416,19 @@ static const MYSQLND_REVERSE_API mysqli_reverse_api = { mysqli_convert_zv_to_mysqlnd }; +static PHP_INI_MH(OnUpdateDefaultPort) +{ + zend_long value = ZEND_ATOL(ZSTR_VAL(new_value)); + + if (value < 0 || value > USHRT_MAX) { + return FAILURE; + } + + MyG(default_port) = (unsigned short)value; + + return SUCCESS; +} + /* {{{ PHP_INI_BEGIN */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY_EX("mysqli.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mysqli_globals, mysqli_globals, display_link_numbers) @@ -433,7 +438,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("mysqli.default_host", NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_mysqli_globals, mysqli_globals) STD_PHP_INI_ENTRY("mysqli.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_mysqli_globals, mysqli_globals) STD_PHP_INI_ENTRY("mysqli.default_pw", NULL, PHP_INI_ALL, OnUpdateString, default_pw, zend_mysqli_globals, mysqli_globals) - STD_PHP_INI_ENTRY("mysqli.default_port", "3306", PHP_INI_ALL, OnUpdateLong, default_port, zend_mysqli_globals, mysqli_globals) + STD_PHP_INI_ENTRY("mysqli.default_port", "3306", PHP_INI_ALL, OnUpdateDefaultPort, default_port, zend_mysqli_globals, mysqli_globals) #ifdef PHP_MYSQL_UNIX_SOCK_ADDR STD_PHP_INI_ENTRY("mysqli.default_socket", MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals) #else @@ -474,7 +479,7 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_INI_ENTRIES(); memcpy(&mysqli_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - mysqli_object_handlers.offset = XtOffsetOf(mysqli_object, zo); + mysqli_object_handlers.offset = offsetof(mysqli_object, zo); mysqli_object_handlers.free_obj = mysqli_objects_free_storage; mysqli_object_handlers.clone_obj = NULL; mysqli_object_handlers.read_property = mysqli_read_property; @@ -715,9 +720,7 @@ PHP_METHOD(mysqli_result, __construct) PHP_METHOD(mysqli_result, getIterator) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_create_internal_iterator_zval(return_value, ZEND_THIS); } @@ -775,7 +778,7 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags } } } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) { zend_argument_value_error(ERROR_ARG_POS(2), "must be one of MYSQLI_NUM, MYSQLI_ASSOC, or MYSQLI_BOTH"); diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index de287b347dee..cc6b8c57404a 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -58,6 +58,11 @@ * @cvalue MYSQL_OPT_SSL_VERIFY_SERVER_CERT */ const MYSQLI_OPT_SSL_VERIFY_SERVER_CERT = UNKNOWN; +/** + * @var int + * @cvalue MYSQL_OPT_COMPRESS + */ +const MYSQLI_OPT_COMPRESS = UNKNOWN; /** * @var int @@ -136,8 +141,8 @@ /** * @var int * @cvalue MYSQLI_STORE_RESULT_COPY_DATA - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as the mysqli_store_result() parameter is unused since 8.1')] const MYSQLI_STORE_RESULT_COPY_DATA = UNKNOWN; /* for mysqli_fetch_assoc */ @@ -423,14 +428,14 @@ /** * @var int * @cvalue MYSQL_NO_DATA - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_NO_DATA = UNKNOWN; /** * @var int * @cvalue MYSQL_DATA_TRUNCATED - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_DATA_TRUNCATED = UNKNOWN; /* reporting */ @@ -469,87 +474,87 @@ /** * @var int * @cvalue SERVER_QUERY_NO_GOOD_INDEX_USED - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED = UNKNOWN; /** * @var int * @cvalue SERVER_QUERY_NO_INDEX_USED - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_QUERY_NO_INDEX_USED = UNKNOWN; /** * @var int * @cvalue SERVER_QUERY_WAS_SLOW - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_QUERY_WAS_SLOW = UNKNOWN; /** * @var int * @cvalue SERVER_PS_OUT_PARAMS - * @deprecated */ +#[\Deprecated(since: '8.1', message: 'as it was unused')] const MYSQLI_SERVER_PS_OUT_PARAMS = UNKNOWN; /** * @var int * @cvalue REFRESH_GRANT - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_GRANT = UNKNOWN; /** * @var int * @cvalue REFRESH_LOG - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_LOG = UNKNOWN; /** * @var int * @cvalue REFRESH_TABLES - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_TABLES = UNKNOWN; /** * @var int * @cvalue REFRESH_HOSTS - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_HOSTS = UNKNOWN; /** * @var int * @cvalue REFRESH_STATUS - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_STATUS = UNKNOWN; /** * @var int * @cvalue REFRESH_THREADS - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_THREADS = UNKNOWN; /** * @var int * @cvalue REFRESH_SLAVE - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_REPLICA = UNKNOWN; /** * @var int * @cvalue REFRESH_SLAVE - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_SLAVE = UNKNOWN; /** * @var int * @cvalue REFRESH_MASTER - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_MASTER = UNKNOWN; /** * @var int * @cvalue REFRESH_BACKUP_LOG - * @deprecated */ +#[\Deprecated(since: '8.4', message: 'as mysqli_refresh() is deprecated')] const MYSQLI_REFRESH_BACKUP_LOG = UNKNOWN; /** @@ -589,10 +594,7 @@ */ const MYSQLI_TRANS_COR_NO_RELEASE = UNKNOWN; -/** - * @var bool - * @deprecated - */ +#[\Deprecated(since: '8.2', message: 'as it is always false')] const MYSQLI_IS_MARIADB = false; final class mysqli_driver @@ -904,6 +906,11 @@ public function real_connect( */ public function real_escape_string(string $string): string {} + /** + * @alias mysqli_quote_string + */ + public function quote_string(string $string): string {} + /** * @tentative-return-type * @alias mysqli_reap_async_query @@ -1383,6 +1390,7 @@ function mysqli_error_list(mysqli $mysql): array {} function mysqli_stmt_execute(mysqli_stmt $statement, ?array $params = null): bool {} /** @alias mysqli_stmt_execute */ +#[\Deprecated(since: '8.5', message: "use mysqli_stmt_execute() instead")] function mysqli_execute(mysqli_stmt $statement, ?array $params = null): bool {} function mysqli_execute_query(mysqli $mysql, string $query, ?array $params = null): mysqli_result|bool {} @@ -1544,6 +1552,8 @@ function mysqli_real_escape_string(mysqli $mysql, string $string): string {} /** @alias mysqli_real_escape_string */ function mysqli_escape_string(mysqli $mysql, string $string): string {} +function mysqli_quote_string(mysqli $mysql, string $string): string {} + function mysqli_real_query(mysqli $mysql, string $query): bool {} /** @refcount 1 */ diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 5e2645740b26..c667712f85fe 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -324,10 +322,10 @@ PHP_FUNCTION(mysqli_data_seek) RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); if (mysqli_result_is_unbuffered(result)) { - if (getThis()) { + if (hasThis()) { zend_throw_error(NULL, "mysqli_result::data_seek() cannot be used in MYSQLI_USE_RESULT mode"); } else { zend_throw_error(NULL, "mysqli_data_seek() cannot be used in MYSQLI_USE_RESULT mode"); @@ -670,7 +668,7 @@ PHP_FUNCTION(mysqli_fetch_field) RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); if (!(field = mysql_fetch_field(result))) { RETURN_FALSE; @@ -694,7 +692,7 @@ PHP_FUNCTION(mysqli_fetch_fields) RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); array_init(return_value); num_fields = mysql_num_fields(result); @@ -727,7 +725,7 @@ PHP_FUNCTION(mysqli_fetch_field_direct) RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); if (offset >= (zend_long) mysql_num_fields(result)) { zend_argument_value_error(ERROR_ARG_POS(2), "must be less than the number of fields for this result set"); @@ -755,7 +753,7 @@ PHP_FUNCTION(mysqli_fetch_lengths) RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); // TODO Warning? if (!(ret = mysql_fetch_lengths(result))) { @@ -809,7 +807,7 @@ PHP_FUNCTION(mysqli_field_seek) RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); if ((uint32_t)fieldnr >= mysql_num_fields(result)) { zend_argument_value_error(ERROR_ARG_POS(2), "must be less than the number of fields for this result set"); @@ -830,7 +828,7 @@ PHP_FUNCTION(mysqli_field_tell) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); RETURN_LONG(mysql_field_tell(result)); } @@ -845,7 +843,7 @@ PHP_FUNCTION(mysqli_free_result) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); mysqli_free_result(result, false); MYSQLI_CLEAR_RESOURCE(mysql_result); @@ -855,10 +853,8 @@ PHP_FUNCTION(mysqli_free_result) /* {{{ Get MySQL client info */ PHP_FUNCTION(mysqli_get_client_info) { - if (getThis()) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + if (hasThis()) { + ZEND_PARSE_PARAMETERS_NONE(); } else { zval *mysql_link; @@ -878,9 +874,7 @@ PHP_FUNCTION(mysqli_get_client_info) /* {{{ Get MySQL client info */ PHP_FUNCTION(mysqli_get_client_version) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG((zend_long)mysql_get_client_version()); } @@ -1123,7 +1117,7 @@ PHP_FUNCTION(mysqli_num_fields) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); RETURN_LONG(mysql_num_fields(result)); } @@ -1138,7 +1132,7 @@ PHP_FUNCTION(mysqli_num_rows) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) { zend_throw_error(NULL, "mysqli_num_rows() cannot be used in MYSQLI_USE_RESULT mode"); @@ -1198,6 +1192,11 @@ PHP_FUNCTION(mysqli_options) MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_INITIALIZED); expected_type = mysqli_options_get_option_zval_type(mysql_option); + if (expected_type == IS_NULL) { + zend_argument_value_error(ERROR_ARG_POS(2), "must be MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, or one of the MYSQLI_OPT_* constants"); + RETURN_THROWS(); + } + if (expected_type != Z_TYPE_P(mysql_value)) { switch (expected_type) { case IS_STRING: @@ -1343,9 +1342,6 @@ PHP_FUNCTION(mysqli_real_query) } /* }}} */ -# define mysql_real_escape_string_quote(mysql, to, from, length, quote) \ - mysql_real_escape_string(mysql, to, from, length) - PHP_FUNCTION(mysqli_real_escape_string) { MY_MYSQL *mysql; zval *mysql_link = NULL; @@ -1359,12 +1355,35 @@ PHP_FUNCTION(mysqli_real_escape_string) { MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); newstr = zend_string_safe_alloc(2, escapestr_len, 0, 0); - ZSTR_LEN(newstr) = mysql_real_escape_string_quote(mysql->mysql, ZSTR_VAL(newstr), escapestr, escapestr_len, '\''); + ZSTR_LEN(newstr) = mysql_real_escape_string(mysql->mysql, ZSTR_VAL(newstr), escapestr, escapestr_len); newstr = zend_string_truncate(newstr, ZSTR_LEN(newstr), 0); RETURN_NEW_STR(newstr); } +PHP_FUNCTION(mysqli_quote_string) { + MY_MYSQL *mysql; + zval *mysql_link = NULL; + char *escapestr; + size_t escapestr_len; + zend_string *newstr; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &escapestr, &escapestr_len) == FAILURE) { + RETURN_THROWS(); + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); + + newstr = zend_string_safe_alloc(2, escapestr_len, 2, 0); + char *out = ZSTR_VAL(newstr); + *out++ = '\''; + out += mysql_real_escape_string(mysql->mysql, out, escapestr, escapestr_len); + *out++ = '\''; + *out = '\0'; + newstr = zend_string_truncate(newstr, out - ZSTR_VAL(newstr), 0); + + RETURN_NEW_STR(newstr); +} + /* {{{ Undo actions from current transaction */ PHP_FUNCTION(mysqli_rollback) { @@ -1408,10 +1427,7 @@ PHP_FUNCTION(mysqli_stmt_send_long_data) RETURN_THROWS(); } - if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) { - RETURN_FALSE; - } - RETURN_TRUE; + RETURN_BOOL(!mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)); } /* }}} */ @@ -1472,6 +1488,15 @@ PHP_FUNCTION(mysqli_stmt_data_seek) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); + if (!stmt->stmt->data || !stmt->stmt->data->result || !stmt->stmt->data->result->stored_data) { + if (hasThis()) { + zend_throw_error(NULL, "mysqli_stmt::data_seek(): No result set associated with the statement"); + } else { + zend_throw_error(NULL, "mysqli_stmt_data_seek(): No result set associated with the statement"); + } + RETURN_THROWS(); + } + mysql_stmt_data_seek(stmt->stmt, offset); } /* }}} */ @@ -1550,10 +1575,7 @@ PHP_FUNCTION(mysqli_stmt_reset) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); - if (mysql_stmt_reset(stmt->stmt)) { - RETURN_FALSE; - } - RETURN_TRUE; + RETURN_BOOL(!mysql_stmt_reset(stmt->stmt)); } /* }}} */ @@ -1950,9 +1972,7 @@ PHP_FUNCTION(mysqli_thread_id) /* {{{ Return whether thread safety is given or not */ PHP_FUNCTION(mysqli_thread_safe) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(mysql_thread_safe()); } diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 4e624d623d80..0121f36f3cfd 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 32baf7b0642af68dea551687bc44ae47d708d810 */ +/* This is a generated file, edit mysqli.stub.php instead. + * Stub hash: dc804bc50cd0a0e14dafc0e03564d5699d641db0 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -252,6 +252,8 @@ ZEND_END_ARG_INFO() #define arginfo_mysqli_escape_string arginfo_mysqli_real_escape_string +#define arginfo_mysqli_quote_string arginfo_mysqli_real_escape_string + #define arginfo_mysqli_real_query arginfo_mysqli_multi_query ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_reap_async_query, 0, 1, mysqli_result, MAY_BE_BOOL) @@ -527,6 +529,10 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_real_esca ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_quote_string, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_mysqli_reap_async_query, 0, 0, mysqli_result, MAY_BE_BOOL) ZEND_END_ARG_INFO() @@ -767,6 +773,7 @@ ZEND_FUNCTION(mysqli_report); ZEND_FUNCTION(mysqli_query); ZEND_FUNCTION(mysqli_real_connect); ZEND_FUNCTION(mysqli_real_escape_string); +ZEND_FUNCTION(mysqli_quote_string); ZEND_FUNCTION(mysqli_real_query); ZEND_FUNCTION(mysqli_reap_async_query); ZEND_FUNCTION(mysqli_release_savepoint); @@ -837,7 +844,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(mysqli_error, arginfo_mysqli_error) ZEND_FE(mysqli_error_list, arginfo_mysqli_error_list) ZEND_FE(mysqli_stmt_execute, arginfo_mysqli_stmt_execute) - ZEND_RAW_FENTRY("mysqli_execute", zif_mysqli_stmt_execute, arginfo_mysqli_execute, 0, NULL, NULL) + ZEND_RAW_FENTRY("mysqli_execute", zif_mysqli_stmt_execute, arginfo_mysqli_execute, ZEND_ACC_DEPRECATED, NULL, NULL) ZEND_FE(mysqli_execute_query, arginfo_mysqli_execute_query) ZEND_FE(mysqli_fetch_field, arginfo_mysqli_fetch_field) ZEND_FE(mysqli_fetch_fields, arginfo_mysqli_fetch_fields) @@ -883,6 +890,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(mysqli_real_connect, arginfo_mysqli_real_connect) ZEND_FE(mysqli_real_escape_string, arginfo_mysqli_real_escape_string) ZEND_RAW_FENTRY("mysqli_escape_string", zif_mysqli_real_escape_string, arginfo_mysqli_escape_string, 0, NULL, NULL) + ZEND_FE(mysqli_quote_string, arginfo_mysqli_quote_string) ZEND_FE(mysqli_real_query, arginfo_mysqli_real_query) ZEND_FE(mysqli_reap_async_query, arginfo_mysqli_reap_async_query) ZEND_FE(mysqli_release_savepoint, arginfo_mysqli_release_savepoint) @@ -957,6 +965,7 @@ static const zend_function_entry class_mysqli_methods[] = { ZEND_RAW_FENTRY("query", zif_mysqli_query, arginfo_class_mysqli_query, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("real_connect", zif_mysqli_real_connect, arginfo_class_mysqli_real_connect, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("real_escape_string", zif_mysqli_real_escape_string, arginfo_class_mysqli_real_escape_string, ZEND_ACC_PUBLIC, NULL, NULL) + ZEND_RAW_FENTRY("quote_string", zif_mysqli_quote_string, arginfo_class_mysqli_quote_string, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("reap_async_query", zif_mysqli_reap_async_query, arginfo_class_mysqli_reap_async_query, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("escape_string", zif_mysqli_real_escape_string, arginfo_class_mysqli_escape_string, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("real_query", zif_mysqli_real_query, arginfo_class_mysqli_real_query, ZEND_ACC_PUBLIC, NULL, NULL) @@ -1045,6 +1054,7 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_INT_AND_FLOAT_NATIVE", MYSQLND_OPT_INT_AND_FLOAT_NATIVE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MYSQLI_OPT_COMPRESS", MYSQL_OPT_COMPRESS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PUBLIC_KEY", MYSQL_SERVER_PUBLIC_KEY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS", CLIENT_COMPRESS, CONST_PERSISTENT); @@ -1059,7 +1069,7 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_STORE_RESULT_COPY_DATA = REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_ASSOC", MYSQLI_ASSOC, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_NUM", MYSQLI_NUM, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_BOTH", MYSQLI_BOTH, CONST_PERSISTENT); @@ -1114,28 +1124,28 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_NO_DATA = REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_DATA_TRUNCATED = REGISTER_LONG_CONSTANT("MYSQLI_DATA_TRUNCATED", MYSQL_DATA_TRUNCATED, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_INDEX", MYSQLI_REPORT_INDEX, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ERROR", MYSQLI_REPORT_ERROR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_STRICT", MYSQLI_REPORT_STRICT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ALL", MYSQLI_REPORT_ALL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_REPORT_OFF", MYSQLI_REPORT_OFF, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_DEBUG_TRACE_ENABLED", MYSQLND_DBG_ENABLED, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT", REFRESH_GRANT, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG", REFRESH_LOG, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES", REFRESH_TABLES, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_HOSTS", REFRESH_HOSTS, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_STATUS", REFRESH_STATUS, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_THREADS", REFRESH_THREADS, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_REPLICA", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER", REFRESH_MASTER, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED = REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED", SERVER_QUERY_NO_GOOD_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_SERVER_QUERY_NO_INDEX_USED = REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_NO_INDEX_USED", SERVER_QUERY_NO_INDEX_USED, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_SERVER_QUERY_WAS_SLOW = REGISTER_LONG_CONSTANT("MYSQLI_SERVER_QUERY_WAS_SLOW", SERVER_QUERY_WAS_SLOW, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_SERVER_PS_OUT_PARAMS = REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PS_OUT_PARAMS", SERVER_PS_OUT_PARAMS, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_GRANT = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_GRANT", REFRESH_GRANT, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_LOG = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_LOG", REFRESH_LOG, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_TABLES = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_TABLES", REFRESH_TABLES, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_HOSTS = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_HOSTS", REFRESH_HOSTS, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_STATUS = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_STATUS", REFRESH_STATUS, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_THREADS = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_THREADS", REFRESH_THREADS, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_REPLICA = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_REPLICA", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_SLAVE = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_SLAVE", REFRESH_SLAVE, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_MASTER = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_MASTER", REFRESH_MASTER, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_REFRESH_BACKUP_LOG = REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT", TRANS_START_WITH_CONSISTENT_SNAPSHOT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_WRITE", TRANS_START_READ_WRITE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_ONLY", TRANS_START_READ_ONLY, CONST_PERSISTENT); @@ -1143,50 +1153,154 @@ static void register_mysqli_symbols(int module_number) REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_AND_NO_CHAIN", TRANS_COR_AND_NO_CHAIN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_RELEASE", TRANS_COR_RELEASE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_NO_RELEASE", TRANS_COR_NO_RELEASE, CONST_PERSISTENT); - REGISTER_BOOL_CONSTANT("MYSQLI_IS_MARIADB", false, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_MYSQLI_IS_MARIADB = REGISTER_BOOL_CONSTANT("MYSQLI_IS_MARIADB", false, CONST_PERSISTENT | CONST_DEPRECATED); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_change_user", sizeof("mysqli_change_user") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_connect", sizeof("mysqli_connect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + zend_attribute *attribute_Deprecated_func_mysqli_execute_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_execute", sizeof("mysqli_execute") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_mysqli_execute_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_mysqli_execute_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_mysqli_execute_0_arg1_str = zend_string_init("use mysqli_stmt_execute() instead", strlen("use mysqli_stmt_execute() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_execute_0->args[1].value, attribute_Deprecated_func_mysqli_execute_0_arg1_str); + attribute_Deprecated_func_mysqli_execute_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + zend_attribute *attribute_Deprecated_func_mysqli_kill_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_kill", sizeof("mysqli_kill") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_mysqli_kill_0_arg0; - zend_string *attribute_Deprecated_func_mysqli_kill_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_kill_0_arg0, attribute_Deprecated_func_mysqli_kill_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_kill_0->args[0].value, &attribute_Deprecated_func_mysqli_kill_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mysqli_kill_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_mysqli_kill_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_mysqli_kill_0_arg1; zend_string *attribute_Deprecated_func_mysqli_kill_0_arg1_str = zend_string_init("use KILL CONNECTION/QUERY SQL statement instead", strlen("use KILL CONNECTION/QUERY SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_kill_0_arg1, attribute_Deprecated_func_mysqli_kill_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_kill_0->args[1].value, &attribute_Deprecated_func_mysqli_kill_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_kill_0->args[1].value, attribute_Deprecated_func_mysqli_kill_0_arg1_str); attribute_Deprecated_func_mysqli_kill_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_mysqli_ping_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_ping", sizeof("mysqli_ping") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_mysqli_ping_0_arg0; - zend_string *attribute_Deprecated_func_mysqli_ping_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_ping_0_arg0, attribute_Deprecated_func_mysqli_ping_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_ping_0->args[0].value, &attribute_Deprecated_func_mysqli_ping_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mysqli_ping_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_mysqli_ping_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_mysqli_ping_0_arg1; zend_string *attribute_Deprecated_func_mysqli_ping_0_arg1_str = zend_string_init("because the reconnect feature has been removed in PHP 8.2 and this function is now redundant", strlen("because the reconnect feature has been removed in PHP 8.2 and this function is now redundant"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_ping_0_arg1, attribute_Deprecated_func_mysqli_ping_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_ping_0->args[1].value, &attribute_Deprecated_func_mysqli_ping_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_ping_0->args[1].value, attribute_Deprecated_func_mysqli_ping_0_arg1_str); attribute_Deprecated_func_mysqli_ping_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_real_connect", sizeof("mysqli_real_connect") - 1), 3, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_attribute *attribute_Deprecated_func_mysqli_refresh_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "mysqli_refresh", sizeof("mysqli_refresh") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_mysqli_refresh_0_arg0; - zend_string *attribute_Deprecated_func_mysqli_refresh_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_refresh_0_arg0, attribute_Deprecated_func_mysqli_refresh_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_refresh_0->args[0].value, &attribute_Deprecated_func_mysqli_refresh_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_mysqli_refresh_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_mysqli_refresh_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_mysqli_refresh_0_arg1; zend_string *attribute_Deprecated_func_mysqli_refresh_0_arg1_str = zend_string_init("use FLUSH SQL statement instead", strlen("use FLUSH SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_mysqli_refresh_0_arg1, attribute_Deprecated_func_mysqli_refresh_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_mysqli_refresh_0->args[1].value, &attribute_Deprecated_func_mysqli_refresh_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_mysqli_refresh_0->args[1].value, attribute_Deprecated_func_mysqli_refresh_0_arg1_str); attribute_Deprecated_func_mysqli_refresh_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0 = zend_add_global_constant_attribute(const_MYSQLI_STORE_RESULT_COPY_DATA, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1_str = zend_string_init("as the mysqli_store_result() parameter is unused since 8.1", strlen("as the mysqli_store_result() parameter is unused since 8.1"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[1].value, attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0_arg1_str); + attribute_Deprecated_const_MYSQLI_STORE_RESULT_COPY_DATA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_NO_DATA_0 = zend_add_global_constant_attribute(const_MYSQLI_NO_DATA, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str = zend_string_init("as it was unused", strlen("as it was unused"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); + attribute_Deprecated_const_MYSQLI_NO_DATA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0 = zend_add_global_constant_attribute(const_MYSQLI_DATA_TRUNCATED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); + attribute_Deprecated_const_MYSQLI_DATA_TRUNCATED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_QUERY_NO_INDEX_USED, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_NO_INDEX_USED_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_QUERY_WAS_SLOW, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); + attribute_Deprecated_const_MYSQLI_SERVER_QUERY_WAS_SLOW_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0 = zend_add_global_constant_attribute(const_MYSQLI_SERVER_PS_OUT_PARAMS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[1].value, attribute_Deprecated_const_MYSQLI_NO_DATA_0_arg1_str); + attribute_Deprecated_const_MYSQLI_SERVER_PS_OUT_PARAMS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_GRANT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str = zend_string_init("as mysqli_refresh() is deprecated", strlen("as mysqli_refresh() is deprecated"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_LOG, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_LOG_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_TABLES, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_TABLES_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_HOSTS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_HOSTS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_STATUS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_STATUS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_THREADS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_THREADS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_REPLICA, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_REPLICA_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_SLAVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_SLAVE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_MASTER, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_MASTER_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0 = zend_add_global_constant_attribute(const_MYSQLI_REFRESH_BACKUP_LOG, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[1].value, attribute_Deprecated_const_MYSQLI_REFRESH_GRANT_0_arg1_str); + attribute_Deprecated_const_MYSQLI_REFRESH_BACKUP_LOG_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MYSQLI_IS_MARIADB_0 = zend_add_global_constant_attribute(const_MYSQLI_IS_MARIADB, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); + attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1_str = zend_string_init("as it is always false", strlen("as it is always false"), 1); + ZVAL_STR(&attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[1].value, attribute_Deprecated_const_MYSQLI_IS_MARIADB_0_arg1_str); + attribute_Deprecated_const_MYSQLI_IS_MARIADB_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_mysqli_driver(void) @@ -1198,27 +1312,27 @@ static zend_class_entry *register_class_mysqli_driver(void) zval property_client_info_default_value; ZVAL_UNDEF(&property_client_info_default_value); - zend_string *property_client_info_name = zend_string_init("client_info", sizeof("client_info") - 1, 1); + zend_string *property_client_info_name = zend_string_init("client_info", sizeof("client_info") - 1, true); zend_declare_typed_property(class_entry, property_client_info_name, &property_client_info_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_client_info_name); + zend_string_release_ex(property_client_info_name, true); zval property_client_version_default_value; ZVAL_UNDEF(&property_client_version_default_value); - zend_string *property_client_version_name = zend_string_init("client_version", sizeof("client_version") - 1, 1); + zend_string *property_client_version_name = zend_string_init("client_version", sizeof("client_version") - 1, true); zend_declare_typed_property(class_entry, property_client_version_name, &property_client_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_client_version_name); + zend_string_release_ex(property_client_version_name, true); zval property_driver_version_default_value; ZVAL_UNDEF(&property_driver_version_default_value); - zend_string *property_driver_version_name = zend_string_init("driver_version", sizeof("driver_version") - 1, 1); + zend_string *property_driver_version_name = zend_string_init("driver_version", sizeof("driver_version") - 1, true); zend_declare_typed_property(class_entry, property_driver_version_name, &property_driver_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_driver_version_name); + zend_string_release_ex(property_driver_version_name, true); zval property_report_mode_default_value; ZVAL_LONG(&property_report_mode_default_value, 0); - zend_string *property_report_mode_name = zend_string_init("report_mode", sizeof("report_mode") - 1, 1); + zend_string *property_report_mode_name = zend_string_init("report_mode", sizeof("report_mode") - 1, true); zend_declare_typed_property(class_entry, property_report_mode_name, &property_report_mode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_report_mode_name); + zend_string_release_ex(property_report_mode_name, true); return class_entry; } @@ -1232,111 +1346,111 @@ static zend_class_entry *register_class_mysqli(void) zval property_affected_rows_default_value; ZVAL_UNDEF(&property_affected_rows_default_value); - zend_string *property_affected_rows_name = zend_string_init("affected_rows", sizeof("affected_rows") - 1, 1); + zend_string *property_affected_rows_name = zend_string_init("affected_rows", sizeof("affected_rows") - 1, true); zend_declare_typed_property(class_entry, property_affected_rows_name, &property_affected_rows_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_STRING)); - zend_string_release(property_affected_rows_name); + zend_string_release_ex(property_affected_rows_name, true); zval property_client_info_default_value; ZVAL_UNDEF(&property_client_info_default_value); - zend_string *property_client_info_name = zend_string_init("client_info", sizeof("client_info") - 1, 1); + zend_string *property_client_info_name = zend_string_init("client_info", sizeof("client_info") - 1, true); zend_declare_typed_property(class_entry, property_client_info_name, &property_client_info_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_client_info_name); + zend_string_release_ex(property_client_info_name, true); zval property_client_version_default_value; ZVAL_UNDEF(&property_client_version_default_value); - zend_string *property_client_version_name = zend_string_init("client_version", sizeof("client_version") - 1, 1); + zend_string *property_client_version_name = zend_string_init("client_version", sizeof("client_version") - 1, true); zend_declare_typed_property(class_entry, property_client_version_name, &property_client_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_client_version_name); + zend_string_release_ex(property_client_version_name, true); zval property_connect_errno_default_value; ZVAL_UNDEF(&property_connect_errno_default_value); - zend_string *property_connect_errno_name = zend_string_init("connect_errno", sizeof("connect_errno") - 1, 1); + zend_string *property_connect_errno_name = zend_string_init("connect_errno", sizeof("connect_errno") - 1, true); zend_declare_typed_property(class_entry, property_connect_errno_name, &property_connect_errno_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_connect_errno_name); + zend_string_release_ex(property_connect_errno_name, true); zval property_connect_error_default_value; ZVAL_UNDEF(&property_connect_error_default_value); - zend_string *property_connect_error_name = zend_string_init("connect_error", sizeof("connect_error") - 1, 1); + zend_string *property_connect_error_name = zend_string_init("connect_error", sizeof("connect_error") - 1, true); zend_declare_typed_property(class_entry, property_connect_error_name, &property_connect_error_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_connect_error_name); + zend_string_release_ex(property_connect_error_name, true); zval property_errno_default_value; ZVAL_UNDEF(&property_errno_default_value); - zend_string *property_errno_name = zend_string_init("errno", sizeof("errno") - 1, 1); + zend_string *property_errno_name = zend_string_init("errno", sizeof("errno") - 1, true); zend_declare_typed_property(class_entry, property_errno_name, &property_errno_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_errno_name); + zend_string_release_ex(property_errno_name, true); zval property_error_default_value; ZVAL_UNDEF(&property_error_default_value); - zend_string *property_error_name = zend_string_init("error", sizeof("error") - 1, 1); + zend_string *property_error_name = zend_string_init("error", sizeof("error") - 1, true); zend_declare_typed_property(class_entry, property_error_name, &property_error_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_error_name); + zend_string_release_ex(property_error_name, true); zval property_error_list_default_value; ZVAL_UNDEF(&property_error_list_default_value); - zend_string *property_error_list_name = zend_string_init("error_list", sizeof("error_list") - 1, 1); + zend_string *property_error_list_name = zend_string_init("error_list", sizeof("error_list") - 1, true); zend_declare_typed_property(class_entry, property_error_list_name, &property_error_list_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release(property_error_list_name); + zend_string_release_ex(property_error_list_name, true); zval property_field_count_default_value; ZVAL_UNDEF(&property_field_count_default_value); - zend_string *property_field_count_name = zend_string_init("field_count", sizeof("field_count") - 1, 1); + zend_string *property_field_count_name = zend_string_init("field_count", sizeof("field_count") - 1, true); zend_declare_typed_property(class_entry, property_field_count_name, &property_field_count_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_field_count_name); + zend_string_release_ex(property_field_count_name, true); zval property_host_info_default_value; ZVAL_UNDEF(&property_host_info_default_value); - zend_string *property_host_info_name = zend_string_init("host_info", sizeof("host_info") - 1, 1); + zend_string *property_host_info_name = zend_string_init("host_info", sizeof("host_info") - 1, true); zend_declare_typed_property(class_entry, property_host_info_name, &property_host_info_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_host_info_name); + zend_string_release_ex(property_host_info_name, true); zval property_info_default_value; ZVAL_UNDEF(&property_info_default_value); - zend_string *property_info_name = zend_string_init("info", sizeof("info") - 1, 1); + zend_string *property_info_name = zend_string_init("info", sizeof("info") - 1, true); zend_declare_typed_property(class_entry, property_info_name, &property_info_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_info_name); + zend_string_release_ex(property_info_name, true); zval property_insert_id_default_value; ZVAL_UNDEF(&property_insert_id_default_value); - zend_string *property_insert_id_name = zend_string_init("insert_id", sizeof("insert_id") - 1, 1); + zend_string *property_insert_id_name = zend_string_init("insert_id", sizeof("insert_id") - 1, true); zend_declare_typed_property(class_entry, property_insert_id_name, &property_insert_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_STRING)); - zend_string_release(property_insert_id_name); + zend_string_release_ex(property_insert_id_name, true); zval property_server_info_default_value; ZVAL_UNDEF(&property_server_info_default_value); - zend_string *property_server_info_name = zend_string_init("server_info", sizeof("server_info") - 1, 1); + zend_string *property_server_info_name = zend_string_init("server_info", sizeof("server_info") - 1, true); zend_declare_typed_property(class_entry, property_server_info_name, &property_server_info_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_server_info_name); + zend_string_release_ex(property_server_info_name, true); zval property_server_version_default_value; ZVAL_UNDEF(&property_server_version_default_value); - zend_string *property_server_version_name = zend_string_init("server_version", sizeof("server_version") - 1, 1); + zend_string *property_server_version_name = zend_string_init("server_version", sizeof("server_version") - 1, true); zend_declare_typed_property(class_entry, property_server_version_name, &property_server_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_server_version_name); + zend_string_release_ex(property_server_version_name, true); zval property_sqlstate_default_value; ZVAL_UNDEF(&property_sqlstate_default_value); - zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, 1); + zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, true); zend_declare_typed_property(class_entry, property_sqlstate_name, &property_sqlstate_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_sqlstate_name); + zend_string_release_ex(property_sqlstate_name, true); zval property_protocol_version_default_value; ZVAL_UNDEF(&property_protocol_version_default_value); - zend_string *property_protocol_version_name = zend_string_init("protocol_version", sizeof("protocol_version") - 1, 1); + zend_string *property_protocol_version_name = zend_string_init("protocol_version", sizeof("protocol_version") - 1, true); zend_declare_typed_property(class_entry, property_protocol_version_name, &property_protocol_version_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_protocol_version_name); + zend_string_release_ex(property_protocol_version_name, true); zval property_thread_id_default_value; ZVAL_UNDEF(&property_thread_id_default_value); - zend_string *property_thread_id_name = zend_string_init("thread_id", sizeof("thread_id") - 1, 1); + zend_string *property_thread_id_name = zend_string_init("thread_id", sizeof("thread_id") - 1, true); zend_declare_typed_property(class_entry, property_thread_id_name, &property_thread_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_thread_id_name); + zend_string_release_ex(property_thread_id_name, true); zval property_warning_count_default_value; ZVAL_UNDEF(&property_warning_count_default_value); - zend_string *property_warning_count_name = zend_string_init("warning_count", sizeof("warning_count") - 1, 1); + zend_string *property_warning_count_name = zend_string_init("warning_count", sizeof("warning_count") - 1, true); zend_declare_typed_property(class_entry, property_warning_count_name, &property_warning_count_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_warning_count_name); + zend_string_release_ex(property_warning_count_name, true); zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "__construct", sizeof("__construct") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); @@ -1346,65 +1460,40 @@ static zend_class_entry *register_class_mysqli(void) zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "connect", sizeof("connect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_attribute *attribute_Deprecated_func_get_client_info_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "get_client_info", sizeof("get_client_info") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_get_client_info_0_arg0; - zend_string *attribute_Deprecated_func_get_client_info_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_get_client_info_0_arg0, attribute_Deprecated_func_get_client_info_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_get_client_info_0->args[0].value, &attribute_Deprecated_func_get_client_info_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_get_client_info_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_get_client_info_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_get_client_info_0_arg1; zend_string *attribute_Deprecated_func_get_client_info_0_arg1_str = zend_string_init("use mysqli_get_client_info() instead", strlen("use mysqli_get_client_info() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_get_client_info_0_arg1, attribute_Deprecated_func_get_client_info_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_get_client_info_0->args[1].value, &attribute_Deprecated_func_get_client_info_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_get_client_info_0->args[1].value, attribute_Deprecated_func_get_client_info_0_arg1_str); attribute_Deprecated_func_get_client_info_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_init_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "init", sizeof("init") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_init_0_arg0; - zend_string *attribute_Deprecated_func_init_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_init_0_arg0, attribute_Deprecated_func_init_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_init_0->args[0].value, &attribute_Deprecated_func_init_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_init_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_init_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_init_0_arg1; zend_string *attribute_Deprecated_func_init_0_arg1_str = zend_string_init("replace calls to parent::init() with parent::__construct()", strlen("replace calls to parent::init() with parent::__construct()"), 1); - ZVAL_STR(&attribute_Deprecated_func_init_0_arg1, attribute_Deprecated_func_init_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_init_0->args[1].value, &attribute_Deprecated_func_init_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_init_0->args[1].value, attribute_Deprecated_func_init_0_arg1_str); attribute_Deprecated_func_init_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_kill_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "kill", sizeof("kill") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_kill_0_arg0; - zend_string *attribute_Deprecated_func_kill_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_kill_0_arg0, attribute_Deprecated_func_kill_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_kill_0->args[0].value, &attribute_Deprecated_func_kill_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_kill_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_kill_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_kill_0_arg1; zend_string *attribute_Deprecated_func_kill_0_arg1_str = zend_string_init("use KILL CONNECTION/QUERY SQL statement instead", strlen("use KILL CONNECTION/QUERY SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_kill_0_arg1, attribute_Deprecated_func_kill_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_kill_0->args[1].value, &attribute_Deprecated_func_kill_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_kill_0->args[1].value, attribute_Deprecated_func_kill_0_arg1_str); attribute_Deprecated_func_kill_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_ping_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "ping", sizeof("ping") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_ping_0_arg0; - zend_string *attribute_Deprecated_func_ping_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_ping_0_arg0, attribute_Deprecated_func_ping_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_ping_0->args[0].value, &attribute_Deprecated_func_ping_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_ping_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_ping_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_ping_0_arg1; zend_string *attribute_Deprecated_func_ping_0_arg1_str = zend_string_init("because the reconnect feature has been removed in PHP 8.2 and this method is now redundant", strlen("because the reconnect feature has been removed in PHP 8.2 and this method is now redundant"), 1); - ZVAL_STR(&attribute_Deprecated_func_ping_0_arg1, attribute_Deprecated_func_ping_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_ping_0->args[1].value, &attribute_Deprecated_func_ping_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_ping_0->args[1].value, attribute_Deprecated_func_ping_0_arg1_str); attribute_Deprecated_func_ping_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "real_connect", sizeof("real_connect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_attribute *attribute_Deprecated_func_refresh_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "refresh", sizeof("refresh") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_refresh_0_arg0; - zend_string *attribute_Deprecated_func_refresh_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func_refresh_0_arg0, attribute_Deprecated_func_refresh_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_refresh_0->args[0].value, &attribute_Deprecated_func_refresh_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_refresh_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_refresh_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_refresh_0_arg1; zend_string *attribute_Deprecated_func_refresh_0_arg1_str = zend_string_init("use FLUSH SQL statement instead", strlen("use FLUSH SQL statement instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_refresh_0_arg1, attribute_Deprecated_func_refresh_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_refresh_0->args[1].value, &attribute_Deprecated_func_refresh_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_refresh_0->args[1].value, attribute_Deprecated_func_refresh_0_arg1_str); attribute_Deprecated_func_refresh_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; @@ -1420,27 +1509,27 @@ static zend_class_entry *register_class_mysqli_result(zend_class_entry *class_en zval property_current_field_default_value; ZVAL_UNDEF(&property_current_field_default_value); - zend_string *property_current_field_name = zend_string_init("current_field", sizeof("current_field") - 1, 1); + zend_string *property_current_field_name = zend_string_init("current_field", sizeof("current_field") - 1, true); zend_declare_typed_property(class_entry, property_current_field_name, &property_current_field_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_current_field_name); + zend_string_release_ex(property_current_field_name, true); zval property_field_count_default_value; ZVAL_UNDEF(&property_field_count_default_value); - zend_string *property_field_count_name = zend_string_init("field_count", sizeof("field_count") - 1, 1); + zend_string *property_field_count_name = zend_string_init("field_count", sizeof("field_count") - 1, true); zend_declare_typed_property(class_entry, property_field_count_name, &property_field_count_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_field_count_name); + zend_string_release_ex(property_field_count_name, true); zval property_lengths_default_value; ZVAL_UNDEF(&property_lengths_default_value); - zend_string *property_lengths_name = zend_string_init("lengths", sizeof("lengths") - 1, 1); + zend_string *property_lengths_name = zend_string_init("lengths", sizeof("lengths") - 1, true); zend_declare_typed_property(class_entry, property_lengths_name, &property_lengths_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release(property_lengths_name); + zend_string_release_ex(property_lengths_name, true); zval property_num_rows_default_value; ZVAL_UNDEF(&property_num_rows_default_value); - zend_string *property_num_rows_name = zend_string_init("num_rows", sizeof("num_rows") - 1, 1); + zend_string *property_num_rows_name = zend_string_init("num_rows", sizeof("num_rows") - 1, true); zend_declare_typed_property(class_entry, property_num_rows_name, &property_num_rows_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_STRING)); - zend_string_release(property_num_rows_name); + zend_string_release_ex(property_num_rows_name, true); zval property_type_default_value; ZVAL_UNDEF(&property_type_default_value); @@ -1458,63 +1547,63 @@ static zend_class_entry *register_class_mysqli_stmt(void) zval property_affected_rows_default_value; ZVAL_UNDEF(&property_affected_rows_default_value); - zend_string *property_affected_rows_name = zend_string_init("affected_rows", sizeof("affected_rows") - 1, 1); + zend_string *property_affected_rows_name = zend_string_init("affected_rows", sizeof("affected_rows") - 1, true); zend_declare_typed_property(class_entry, property_affected_rows_name, &property_affected_rows_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_STRING)); - zend_string_release(property_affected_rows_name); + zend_string_release_ex(property_affected_rows_name, true); zval property_insert_id_default_value; ZVAL_UNDEF(&property_insert_id_default_value); - zend_string *property_insert_id_name = zend_string_init("insert_id", sizeof("insert_id") - 1, 1); + zend_string *property_insert_id_name = zend_string_init("insert_id", sizeof("insert_id") - 1, true); zend_declare_typed_property(class_entry, property_insert_id_name, &property_insert_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_STRING)); - zend_string_release(property_insert_id_name); + zend_string_release_ex(property_insert_id_name, true); zval property_num_rows_default_value; ZVAL_UNDEF(&property_num_rows_default_value); - zend_string *property_num_rows_name = zend_string_init("num_rows", sizeof("num_rows") - 1, 1); + zend_string *property_num_rows_name = zend_string_init("num_rows", sizeof("num_rows") - 1, true); zend_declare_typed_property(class_entry, property_num_rows_name, &property_num_rows_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_STRING)); - zend_string_release(property_num_rows_name); + zend_string_release_ex(property_num_rows_name, true); zval property_param_count_default_value; ZVAL_UNDEF(&property_param_count_default_value); - zend_string *property_param_count_name = zend_string_init("param_count", sizeof("param_count") - 1, 1); + zend_string *property_param_count_name = zend_string_init("param_count", sizeof("param_count") - 1, true); zend_declare_typed_property(class_entry, property_param_count_name, &property_param_count_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_param_count_name); + zend_string_release_ex(property_param_count_name, true); zval property_field_count_default_value; ZVAL_UNDEF(&property_field_count_default_value); - zend_string *property_field_count_name = zend_string_init("field_count", sizeof("field_count") - 1, 1); + zend_string *property_field_count_name = zend_string_init("field_count", sizeof("field_count") - 1, true); zend_declare_typed_property(class_entry, property_field_count_name, &property_field_count_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_field_count_name); + zend_string_release_ex(property_field_count_name, true); zval property_errno_default_value; ZVAL_UNDEF(&property_errno_default_value); - zend_string *property_errno_name = zend_string_init("errno", sizeof("errno") - 1, 1); + zend_string *property_errno_name = zend_string_init("errno", sizeof("errno") - 1, true); zend_declare_typed_property(class_entry, property_errno_name, &property_errno_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_errno_name); + zend_string_release_ex(property_errno_name, true); zval property_error_default_value; ZVAL_UNDEF(&property_error_default_value); - zend_string *property_error_name = zend_string_init("error", sizeof("error") - 1, 1); + zend_string *property_error_name = zend_string_init("error", sizeof("error") - 1, true); zend_declare_typed_property(class_entry, property_error_name, &property_error_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_error_name); + zend_string_release_ex(property_error_name, true); zval property_error_list_default_value; ZVAL_UNDEF(&property_error_list_default_value); - zend_string *property_error_list_name = zend_string_init("error_list", sizeof("error_list") - 1, 1); + zend_string *property_error_list_name = zend_string_init("error_list", sizeof("error_list") - 1, true); zend_declare_typed_property(class_entry, property_error_list_name, &property_error_list_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release(property_error_list_name); + zend_string_release_ex(property_error_list_name, true); zval property_sqlstate_default_value; ZVAL_UNDEF(&property_sqlstate_default_value); - zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, 1); + zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, true); zend_declare_typed_property(class_entry, property_sqlstate_name, &property_sqlstate_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_sqlstate_name); + zend_string_release_ex(property_sqlstate_name, true); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); - zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_id_name); + zend_string_release_ex(property_id_name, true); return class_entry; } @@ -1532,15 +1621,15 @@ static zend_class_entry *register_class_mysqli_warning(void) zval property_sqlstate_default_value; ZVAL_UNDEF(&property_sqlstate_default_value); - zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, 1); + zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, true); zend_declare_typed_property(class_entry, property_sqlstate_name, &property_sqlstate_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_sqlstate_name); + zend_string_release_ex(property_sqlstate_name, true); zval property_errno_default_value; ZVAL_UNDEF(&property_errno_default_value); - zend_string *property_errno_name = zend_string_init("errno", sizeof("errno") - 1, 1); + zend_string *property_errno_name = zend_string_init("errno", sizeof("errno") - 1, true); zend_declare_typed_property(class_entry, property_errno_name, &property_errno_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_errno_name); + zend_string_release_ex(property_errno_name, true); return class_entry; } @@ -1555,9 +1644,9 @@ static zend_class_entry *register_class_mysqli_sql_exception(zend_class_entry *c zval property_sqlstate_default_value; zend_string *property_sqlstate_default_value_str = zend_string_init("00000", strlen("00000"), 1); ZVAL_STR(&property_sqlstate_default_value, property_sqlstate_default_value_str); - zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, 1); + zend_string *property_sqlstate_name = zend_string_init("sqlstate", sizeof("sqlstate") - 1, true); zend_declare_typed_property(class_entry, property_sqlstate_name, &property_sqlstate_default_value, ZEND_ACC_PROTECTED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_sqlstate_name); + zend_string_release_ex(property_sqlstate_name, true); return class_entry; } diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c index d2c94d881b44..dadb132efc21 100644 --- a/ext/mysqli/mysqli_driver.c +++ b/ext/mysqli/mysqli_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c index 7ebc29b60ba6..3f34b3e00501 100644 --- a/ext/mysqli/mysqli_exception.c +++ b/ext/mysqli/mysqli_exception.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ diff --git a/ext/mysqli/mysqli_mysqlnd.h b/ext/mysqli/mysqli_mysqlnd.h index 5fb8f542b8fc..b15644c8e1f6 100644 --- a/ext/mysqli/mysqli_mysqlnd.h +++ b/ext/mysqli/mysqli_mysqlnd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index e0e14eeccbc9..1e46aeedd93b 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -56,12 +54,12 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b size_t hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0; bool persistent = false, ssl = false; zend_long port = 0, flags = 0; - bool port_is_null = 1; + bool port_is_null = true; zend_string *hash_key = NULL; bool new_connection = false; zend_resource *le; mysqli_plist_entry *plist = NULL; - bool self_alloced = 0; + bool self_alloced = false; #if !defined(MYSQL_USE_MYSQLND) @@ -105,9 +103,8 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b } if (!mysql) { mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL)); - self_alloced = 1; + self_alloced = true; } - flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ } else { /* We have flags too */ if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|s!s!s!s!l!s!l", &object, mysqli_link_class_entry, @@ -118,11 +115,10 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b mysqli_resource = (Z_MYSQLI_P(object))->ptr; MYSQLI_FETCH_RESOURCE_CONN(mysql, object, MYSQLI_STATUS_INITIALIZED); - /* set some required options */ - flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ /* remove some insecure options */ flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */ } + flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */ if (!socket_len || !socket) { socket = MyG(default_socket); @@ -316,7 +312,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b mysql->hash_key = NULL; mysql->persistent = false; } - if (!is_real_connect && self_alloced) { + if (self_alloced) { efree(mysql); } RETVAL_FALSE; @@ -345,9 +341,7 @@ PHP_METHOD(mysqli, init) /* {{{ Returns the numerical value of the error message from last connect command */ PHP_FUNCTION(mysqli_connect_errno) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(MyG(error_no)); } @@ -356,9 +350,7 @@ PHP_FUNCTION(mysqli_connect_errno) /* {{{ Returns the text of the error message from previous MySQL operation */ PHP_FUNCTION(mysqli_connect_error) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (MyG(error_msg)) { RETURN_STRING(MyG(error_msg)); @@ -393,7 +385,7 @@ PHP_FUNCTION(mysqli_fetch_column) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &col_no) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES*, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES*, mysql_result, MYSQLI_STATUS_VALID); if (col_no < 0) { zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); @@ -425,7 +417,7 @@ PHP_FUNCTION(mysqli_fetch_all) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, MYSQLI_STATUS_VALID); if (!mode || (mode & ~MYSQLI_BOTH)) { zend_argument_value_error(ERROR_ARG_POS(2), "must be one of MYSQLI_NUM, MYSQLI_ASSOC, or MYSQLI_BOTH"); @@ -450,9 +442,7 @@ PHP_FUNCTION(mysqli_fetch_all) /* {{{ Returns statistics about the zval cache */ PHP_FUNCTION(mysqli_get_client_stats) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); mysqlnd_get_client_stats(return_value); } /* }}} */ @@ -973,8 +963,8 @@ PHP_FUNCTION(mysqli_get_charset) { MY_MYSQL *mysql; zval *mysql_link; - const char *name = NULL, *collation = NULL, *dir = NULL, *comment = NULL; - uint32_t minlength, maxlength, number, state; + const char *name = NULL, *collation = NULL; + uint32_t minlength, maxlength; const MYSQLND_CHARSET *cs; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { @@ -992,19 +982,15 @@ PHP_FUNCTION(mysqli_get_charset) collation = cs->collation; minlength = cs->char_minlen; maxlength = cs->char_maxlen; - number = cs->nr; - comment = cs->comment; - state = 1; /* all charsets are compiled in */ object_init(return_value); add_property_string(return_value, "charset", (name) ? (char *)name : ""); add_property_string(return_value, "collation",(collation) ? (char *)collation : ""); - add_property_string(return_value, "dir", (dir) ? (char *)dir : ""); + add_property_string(return_value, "dir", ""); /* Kept for backward compatibility */ add_property_long(return_value, "min_length", minlength); add_property_long(return_value, "max_length", maxlength); - add_property_long(return_value, "number", number); - add_property_long(return_value, "state", state); - add_property_string(return_value, "comment", (comment) ? (char *)comment : ""); + add_property_long(return_value, "number", 0); /* Kept for backward compatibility */ + add_property_long(return_value, "state", 1); /* Kept for backward compatibility */ } /* }}} */ @@ -1031,6 +1017,7 @@ PHP_FUNCTION(mysqli_begin_transaction) } if (FAIL == mysqlnd_begin_transaction(mysql->mysql, flags, name)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } RETURN_TRUE; @@ -1055,6 +1042,7 @@ PHP_FUNCTION(mysqli_savepoint) } if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } RETURN_TRUE; @@ -1078,6 +1066,7 @@ PHP_FUNCTION(mysqli_release_savepoint) RETURN_THROWS(); } if (FAIL == mysqlnd_release_savepoint(mysql->mysql, name)) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } RETURN_TRUE; @@ -1087,9 +1076,7 @@ PHP_FUNCTION(mysqli_release_savepoint) /* {{{ Returns information about open and cached links */ PHP_FUNCTION(mysqli_get_links_stats) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); add_assoc_long_ex(return_value, "total", sizeof("total") - 1, MyG(num_links)); diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h index f08d66b7287d..97d9300a2b79 100644 --- a/ext/mysqli/mysqli_priv.h +++ b/ext/mysqli/mysqli_priv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ @@ -55,7 +53,6 @@ extern void php_clear_mysql(MY_MYSQL *); extern MYSQLI_WARNING *php_get_warnings(MYSQLND_CONN_DATA * mysql); extern void php_clear_warnings(MYSQLI_WARNING *w); -extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type); extern void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error); extern void php_mysqli_report_index(const char *query, unsigned int status); extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno, char *format, ...); diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index 6d86a6ad4ca8..b54f6fd6ae44 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/mysqli_report.c b/ext/mysqli/mysqli_report.c index 68a7a5758475..28b5f151d729 100644 --- a/ext/mysqli/mysqli_report.c +++ b/ext/mysqli/mysqli_report.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ @@ -48,12 +46,12 @@ void php_mysqli_report_error(const char *sqlstate, int errorno, const char *erro /* {{{ void php_mysqli_report_index() */ void php_mysqli_report_index(const char *query, unsigned int status) { - char index[15]; + const char *index; if (status & SERVER_QUERY_NO_GOOD_INDEX_USED) { - strcpy(index, "Bad index"); + index = "Bad index"; } else if (status & SERVER_QUERY_NO_INDEX_USED) { - strcpy(index, "No index"); + index = "No index"; } else { return; } diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c index 3441e47d01a4..013f41d38d0b 100644 --- a/ext/mysqli/mysqli_result_iterator.c +++ b/ext/mysqli/mysqli_result_iterator.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -98,7 +96,7 @@ static void php_mysqli_result_iterator_move_forward(zend_object_iterator *iter) mysqli_object *intern = iterator->result; MYSQL_RES *result; - MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, MYSQLI_STATUS_VALID); zval_ptr_dtor(&iterator->current_row); php_mysqli_fetch_into_hash_aux(&iterator->current_row, result, MYSQLI_ASSOC); @@ -115,7 +113,7 @@ static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter) mysqli_object *intern = iterator->result; MYSQL_RES *result; - MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, "mysqli_result", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE_BY_OBJ(result, MYSQL_RES *, intern, MYSQLI_STATUS_VALID); if (mysqli_result_is_unbuffered(result)) { if (result->unbuf->eof_reached) { diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index b1427495a506..a276ccf0b1ff 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Georg Richter | +----------------------------------------------------------------------+ @@ -120,12 +118,10 @@ PHP_METHOD(mysqli_warning, next) MYSQLI_WARNING *w; mysqli_object *obj = Z_MYSQLI_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (obj->ptr) { - MYSQLI_FETCH_RESOURCE(w, MYSQLI_WARNING *, ZEND_THIS, "mysqli_warning", MYSQLI_STATUS_VALID); + MYSQLI_FETCH_RESOURCE(w, MYSQLI_WARNING *, ZEND_THIS, MYSQLI_STATUS_VALID); if (w && w->next) { w = w->next; diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h index 7ee999b41e04..5f995a4bbc53 100644 --- a/ext/mysqli/php_mysqli.h +++ b/ext/mysqli/php_mysqli.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h index c155281c8e4b..bd16ab9e56cf 100644 --- a/ext/mysqli/php_mysqli_structs.h +++ b/ext/mysqli/php_mysqli_structs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Georg Richter | | Andrey Hristov | @@ -38,32 +36,14 @@ enum mysqli_status { MYSQLI_STATUS_VALID }; -typedef struct { - char *val; - zend_ulong buflen; - zend_ulong output_len; - zend_ulong type; -} VAR_BUFFER; - -typedef struct { - unsigned int var_cnt; - VAR_BUFFER *buf; - zval *vars; - my_bool *is_null; -} BIND_BUFFER; - typedef struct { MYSQL_STMT *stmt; - BIND_BUFFER param; - BIND_BUFFER result; char *query; } MY_STMT; typedef struct { MYSQL *mysql; zend_string *hash_key; - zval li_read; - php_stream *li_stream; unsigned int multi_query; bool persistent; int async_result_fetch_type; @@ -82,7 +62,7 @@ typedef struct _mysqli_object { } mysqli_object; /* extends zend_object */ static inline mysqli_object *php_mysqli_fetch_object(zend_object *obj) { - return (mysqli_object *)((char*)(obj) - XtOffsetOf(mysqli_object, zo)); + return ZEND_CONTAINER_OF(obj, mysqli_object, zo); } #define Z_MYSQLI_P(zv) php_mysqli_fetch_object(Z_OBJ_P((zv))) @@ -177,7 +157,7 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul MYSQLI_REGISTER_RESOURCE_EX(__ptr, object)\ } -#define MYSQLI_FETCH_RESOURCE(__ptr, __type, __id, __name, __check) \ +#define MYSQLI_FETCH_RESOURCE(__ptr, __type, __id, __check) \ { \ MYSQLI_RESOURCE *my_res; \ mysqli_object *intern = Z_MYSQLI_P(__id); \ @@ -192,7 +172,7 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul }\ } -#define MYSQLI_FETCH_RESOURCE_BY_OBJ(__ptr, __type, __obj, __name, __check) \ +#define MYSQLI_FETCH_RESOURCE_BY_OBJ(__ptr, __type, __obj, __check) \ { \ MYSQLI_RESOURCE *my_res; \ if (!(my_res = (MYSQLI_RESOURCE *)(__obj->ptr))) {\ @@ -208,7 +188,7 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul #define MYSQLI_FETCH_RESOURCE_CONN(__ptr, __id, __check) \ { \ - MYSQLI_FETCH_RESOURCE((__ptr), MY_MYSQL *, (__id), "mysqli_link", (__check)); \ + MYSQLI_FETCH_RESOURCE((__ptr), MY_MYSQL *, (__id), (__check)); \ if (!(__ptr)->mysql) { \ zend_throw_error(NULL, "%s object is not fully initialized", ZSTR_VAL(Z_OBJCE_P(__id)->name)); \ RETURN_THROWS(); \ @@ -217,7 +197,7 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul #define MYSQLI_FETCH_RESOURCE_STMT(__ptr, __id, __check) \ { \ - MYSQLI_FETCH_RESOURCE((__ptr), MY_STMT *, (__id), "mysqli_stmt", (__check)); \ + MYSQLI_FETCH_RESOURCE((__ptr), MY_STMT *, (__id), (__check)); \ ZEND_ASSERT((__ptr)->stmt && "Missing statement?"); \ } @@ -236,21 +216,21 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul ZEND_BEGIN_MODULE_GLOBALS(mysqli) - zend_long num_links; - zend_long max_links; - zend_long num_active_persistent; - zend_long num_inactive_persistent; - zend_long max_persistent; + unsigned short default_port; bool allow_persistent; - zend_ulong default_port; + bool allow_local_infile; char *default_host; char *default_user; char *default_pw; char *default_socket; - bool allow_local_infile; char *local_infile_directory; - zend_long error_no; char *error_msg; + zend_long num_links; + zend_long max_links; + zend_long num_active_persistent; + zend_long num_inactive_persistent; + zend_long max_persistent; + zend_long error_no; zend_long report_mode; bool rollback_on_cached_plink; ZEND_END_MODULE_GLOBALS(mysqli) diff --git a/ext/mysqli/tests/bug67563.phpt b/ext/mysqli/tests/bug67563.phpt new file mode 100644 index 000000000000..275d79e30c79 --- /dev/null +++ b/ext/mysqli/tests/bug67563.phpt @@ -0,0 +1,37 @@ +--TEST-- +Fix bug #67563 (mysqli compiled with mysqlnd does not take ipv6 adress as parameter) +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--INI-- +max_execution_time=240 +--FILE-- +close(); + } +} + +print "done!"; +?> +--EXPECT-- +done! diff --git a/ext/mysqli/tests/bug77956.phpt b/ext/mysqli/tests/bug77956.phpt index 28cf694a606a..d5409f952751 100644 --- a/ext/mysqli/tests/bug77956.phpt +++ b/ext/mysqli/tests/bug77956.phpt @@ -57,5 +57,5 @@ $link->close(); unlink('bug77956.data'); ?> --EXPECT-- -[006] [2000] LOAD DATA LOCAL INFILE is forbidden, check related settings like mysqli.allow_local_infile|mysqli.local_infile_directory or PDO::MYSQL_ATTR_LOCAL_INFILE|PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY +[006] [2000] LOAD DATA LOCAL INFILE is forbidden, check related settings like mysqli.allow_local_infile|mysqli.local_infile_directory or Pdo\Mysql::ATTR_LOCAL_INFILE|Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY done diff --git a/ext/mysqli/tests/deprecated_constants.phpt b/ext/mysqli/tests/deprecated_constants.phpt index 9c8e06e50fe1..753863a3bf13 100644 --- a/ext/mysqli/tests/deprecated_constants.phpt +++ b/ext/mysqli/tests/deprecated_constants.phpt @@ -16,22 +16,22 @@ echo constant('MYSQLI_IS_MARIADB')."\n"; ?> --EXPECTF-- -Deprecated: Constant MYSQLI_NO_DATA is deprecated in %s +Deprecated: Constant MYSQLI_NO_DATA is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_DATA_TRUNCATED is deprecated in %s +Deprecated: Constant MYSQLI_DATA_TRUNCATED is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_QUERY_NO_INDEX_USED is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_QUERY_NO_INDEX_USED is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_QUERY_WAS_SLOW is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_QUERY_WAS_SLOW is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_SERVER_PS_OUT_PARAMS is deprecated in %s +Deprecated: Constant MYSQLI_SERVER_PS_OUT_PARAMS is deprecated since 8.1, as it was unused in %s %i -Deprecated: Constant MYSQLI_IS_MARIADB is deprecated in %s +Deprecated: Constant MYSQLI_IS_MARIADB is deprecated since 8.2, as it is always false in %s diff --git a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt index 594980ec0f82..81c15d53b84c 100644 --- a/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt +++ b/ext/mysqli/tests/fetch/mysqli_fetch_all_data_types_variation.phpt @@ -4,6 +4,9 @@ mysqli_fetch_all() data types variation mysqli --SKIPIF-- diff --git a/ext/mysqli/tests/gh20968.phpt b/ext/mysqli/tests/gh20968.phpt new file mode 100644 index 000000000000..e78e1378091e --- /dev/null +++ b/ext/mysqli/tests/gh20968.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-20968 mysqli_options() with invalid option should triggers ValueError +--EXTENSIONS-- +mysqli +--CONFLICTS-- +mysqli +--SKIPIF-- + +--FILE-- +options(10, 'invalid_option'); + var_dump($value); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECTF-- +mysqli::options(): Argument #%d ($option) must be MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, or one of the MYSQLI_OPT_* constants diff --git a/ext/mysqli/tests/gh9590.phpt b/ext/mysqli/tests/gh9590.phpt index 7f795e774229..78c1357fa9b2 100644 --- a/ext/mysqli/tests/gh9590.phpt +++ b/ext/mysqli/tests/gh9590.phpt @@ -12,6 +12,8 @@ if (mysqli_get_server_version($link) < 50012) if (!function_exists('posix_setrlimit') || !posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1)) die('skip Failed to set POSIX_RLIMIT_NOFILE'); +if (PHP_OS_FAMILY === 'Solaris') + die('skip Solaris LP64 FD_SETSIZE=65536 not practically exceedable here'); ?> --FILE-- errno, $link->error)); +?> +--FILE-- + +--CLEAN-- + +--EXPECT-- +Expecting an exception. +done! diff --git a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt index bada1d85a5ce..ccac6710edd1 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt @@ -43,6 +43,7 @@ require_once 'skipifconnectfailure.inc'; 'ping' => true, 'prepare' => true, 'query' => true, + 'quote_string' => true, 'real_connect' => true, 'real_escape_string' => true, 'real_query' => true, diff --git a/ext/mysqli/tests/mysqli_connect_port.phpt b/ext/mysqli/tests/mysqli_connect_port.phpt new file mode 100644 index 000000000000..cb7fd1d8d162 --- /dev/null +++ b/ext/mysqli/tests/mysqli_connect_port.phpt @@ -0,0 +1,31 @@ +--TEST-- +mysqli_connect() with port in host +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- + +Done +--EXPECTF-- +Done diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index 982fe47f75ce..0b5fa977ac1d 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -47,6 +47,7 @@ $expected_constants = array( "MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED"=> true, "MYSQLI_SERVER_QUERY_NO_INDEX_USED" => true, "MYSQLI_OPT_LOAD_DATA_LOCAL_DIR" => true, + "MYSQLI_OPT_COMPRESS" => true, "MYSQLI_IS_MARIADB" => true, "MYSQLI_TYPE_DECIMAL" => true, diff --git a/ext/mysqli/tests/mysqli_default_port_error.phpt b/ext/mysqli/tests/mysqli_default_port_error.phpt new file mode 100644 index 000000000000..7d3658417c96 --- /dev/null +++ b/ext/mysqli/tests/mysqli_default_port_error.phpt @@ -0,0 +1,21 @@ +--TEST-- +default_port ini setting +--EXTENSIONS-- +mysqli +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(false) diff --git a/ext/mysqli/tests/mysqli_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt index dacbd5349668..e65de2308ab4 100644 --- a/ext/mysqli/tests/mysqli_fetch_field.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field.phpt @@ -30,10 +30,6 @@ require_once 'skipifconnectfailure.inc'; /* label column, result set charset */ $tmp = mysqli_fetch_field($res); var_dump($tmp); - if ($tmp->charsetnr != $charsetInfo->number) { - printf("[004] Expecting charset %s/%d got %d\n", - $charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr); - } if ($tmp->db != $db) { printf("011] Expecting database '%s' got '%s'\n", $db, $tmp->db); diff --git a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt index 1fa84f36fae9..0f2a6c55841e 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt @@ -27,10 +27,6 @@ require_once 'skipifconnectfailure.inc'; $tmp = $res->fetch_field(); var_dump($tmp); - if ($tmp->charsetnr != $charsetInfo->number) { - printf("[005] Expecting charset %s/%d got %d\n", - $charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr); - } if ($tmp->db != $db) { printf("[007] Expecting database '%s' got '%s'\n", $db, $tmp->db); diff --git a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt index feb72cabf7a6..80e5cda06e93 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_types.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt @@ -90,6 +90,7 @@ require_once 'skipifconnectfailure.inc'; // MYSQLI_TYPE_GEOMETRY => array('GEOMETRY', 'TODO add testing'), MYSQLI_TYPE_NEWDECIMAL => array('DECIMAL', '1.1'), MYSQLI_TYPE_BIT => array('BIT', 0), + MYSQLI_TYPE_JSON => array('JSON', '[]'), ); foreach ($datatypes as $php_type => $datatype) { diff --git a/ext/mysqli/tests/mysqli_fetch_fields.phpt b/ext/mysqli/tests/mysqli_fetch_fields.phpt index 78df2ef75751..2257c4d9d060 100644 --- a/ext/mysqli/tests/mysqli_fetch_fields.phpt +++ b/ext/mysqli/tests/mysqli_fetch_fields.phpt @@ -26,16 +26,6 @@ require_once 'skipifconnectfailure.inc'; $fields = mysqli_fetch_fields($res); foreach ($fields as $k => $field) { var_dump($field); - switch ($k) { - case 1: - /* label column, result set charset */ - if ($field->charsetnr != $charsetInfo->number) { - printf("[004] Expecting charset %s/%d got %d\n", - $charsetInfo->charset, - $charsetInfo->number, $field->charsetnr); - } - break; - } } mysqli_free_result($res); diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt index 1308db7d4f86..af52bf6c97fb 100644 --- a/ext/mysqli/tests/mysqli_field_seek.phpt +++ b/ext/mysqli/tests/mysqli_field_seek.phpt @@ -80,10 +80,6 @@ require_once 'skipifconnectfailure.inc'; $field = mysqli_fetch_field($res); var_dump($field); /* label column, result set charset */ - if ($field->charsetnr != $charsetInfo->number) { - printf("[004] Expecting charset %s/%d got %d\n", - $charsetInfo->charset, $charsetInfo->number, $field->charsetnr); - } if ($field->length != $charsetInfo->max_length) { printf("[005] Expecting length %d got %d\n", $charsetInfo->max_length, $field->max_length); diff --git a/ext/mysqli/tests/mysqli_get_charset.phpt b/ext/mysqli/tests/mysqli_get_charset.phpt index 14f655f8b0b2..2752084372a9 100644 --- a/ext/mysqli/tests/mysqli_get_charset.phpt +++ b/ext/mysqli/tests/mysqli_get_charset.phpt @@ -15,6 +15,12 @@ require_once 'skipifconnectfailure.inc'; exit(1); } + // On some servers the default collation is not what we expect, + // so we need to set it explicitly to make sure that the test is deterministic. + mysqli_set_charset($link, 'utf8mb4'); + if (!$res = mysqli_query($link, "SET NAMES utf8mb4 COLLATE 'utf8mb4_general_ci'")) + printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + if (!$res = mysqli_query($link, 'SELECT @@character_set_connection AS charset, @@collation_connection AS collation')) printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); $tmp = mysqli_fetch_assoc($res); @@ -27,13 +33,6 @@ require_once 'skipifconnectfailure.inc'; if (!mysqli_fetch_assoc($res)) printf("[010] Cannot fetch Maxlen and/or Comment, test will fail: $sql\n"); - if (!$res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $collation_connection))) - printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - $tmp = mysqli_fetch_assoc($res); - mysqli_free_result($res); - if (!($id = $tmp['Id'])) - printf("[012] Cannot fetch Id/Number, test will fail\n"); - if (!$res = mysqli_query($link, sprintf("SHOW VARIABLES LIKE 'character_sets_dir'"))) printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); $tmp = mysqli_fetch_assoc($res); @@ -66,8 +65,8 @@ require_once 'skipifconnectfailure.inc'; if (!isset($charset->number) || !is_int($charset->number) || - ($charset->number !== (int)$id)) - printf("[021] Expecting int/%d, got %s/%s\n", $id, gettype($charset->number), $charset->number); + ($charset->number !== 0)) + printf("[021] Expecting int/%d, got %s/%s\n", 0, gettype($charset->number), $charset->number); if (!isset($charset->state) || !is_int($charset->state)) diff --git a/ext/mysqli/tests/mysqli_options.phpt b/ext/mysqli/tests/mysqli_options.phpt index 64e42dc752b1..44647f80d194 100644 --- a/ext/mysqli/tests/mysqli_options.phpt +++ b/ext/mysqli/tests/mysqli_options.phpt @@ -60,7 +60,13 @@ var_dump("MYSQLI_OPT_LOCAL_INFILE", mysqli_options($link, MYSQLI_OPT_LOCAL_INFIL var_dump("MYSQLI_INIT_COMMAND", mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0')); /* mysqli_real_connect() */ -var_dump("MYSQLI_CLIENT_SSL", mysqli_options($link, MYSQLI_CLIENT_SSL, 'not a mysqli_option')); +var_dump("MYSQLI_CLIENT_SSL"); + +try { + var_dump(mysqli_options($link, MYSQLI_CLIENT_SSL, 'not a mysqli_option')); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} mysqli_close($link); @@ -81,9 +87,6 @@ try { echo $e->getMessage() . "\n"; } -// invalid options do not generate errors -mysqli_options($link, -1, "Invalid option"); - print "done!"; ?> --EXPECTF-- @@ -110,7 +113,7 @@ bool(true) %s(19) "MYSQLI_INIT_COMMAND" bool(true) %s(17) "MYSQLI_CLIENT_SSL" -bool(false) +mysqli_options(): Argument #%d ($option) must be MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, or one of the MYSQLI_OPT_* constants Link closed mysqli object is already closed Unknown character set diff --git a/ext/mysqli/tests/mysqli_quote_string.phpt b/ext/mysqli/tests/mysqli_quote_string.phpt new file mode 100644 index 000000000000..b4a25aa3996f --- /dev/null +++ b/ext/mysqli/tests/mysqli_quote_string.phpt @@ -0,0 +1,86 @@ +--TEST-- +mysqli_quote_string() +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +$escaped = mysqli_quote_string($link, '" OR 1=1 -- foo'); +echo $escaped . "\n"; +$result = $link->query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +$escaped = mysqli_quote_string($link, "\n"); +if ($escaped !== "'\\n'") { + printf("[001] Expected '\\n', got %s\n", $escaped); +} + +$escaped = mysqli_quote_string($link, "\r"); +if ($escaped !== "'\\r'") { + printf("[002] Expected '\\r', got %s\n", $escaped); +} + +$escaped = mysqli_quote_string($link, "foo" . chr(0) . "bar"); +if ($escaped !== "'foo\\0bar'") { + printf("[003] Expected 'foo\\0bar', got %s\n", $escaped); +} + +echo "=====================\n"; + +// Test that the SQL injection is impossible with NO_BACKSLASH_ESCAPES mode +$link->query('SET @@sql_mode="NO_BACKSLASH_ESCAPES"'); + +echo $link->quote_string('\\') . "\n"; +echo $link->quote_string('"') . "\n"; +echo $link->quote_string("'") . "\n"; + +$escaped = $link->quote_string("\' \ \""); +echo $escaped . "\n"; +$result = $link->query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +$escaped = $link->quote_string('" OR 1=1 -- foo'); +echo $escaped . "\n"; +$result = $link->query("SELECT $escaped AS test"); +$value = $result->fetch_column(); +echo $value . "\n"; + +echo "done!"; +?> +--EXPECT-- +'\\' +'\"' +'\'' +'\\\' \\ \"' +\' \ " +'\" OR 1=1 -- foo' +" OR 1=1 -- foo +===================== +'\' +'"' +'''' +'\'' \ "' +\' \ " +'" OR 1=1 -- foo' +" OR 1=1 -- foo +done! diff --git a/ext/mysqli/tests/mysqli_real_connect_retry_attr.phpt b/ext/mysqli/tests/mysqli_real_connect_retry_attr.phpt new file mode 100644 index 000000000000..7f7731807428 --- /dev/null +++ b/ext/mysqli/tests/mysqli_real_connect_retry_attr.phpt @@ -0,0 +1,26 @@ +--TEST-- +mysqli_real_connect() retry on same handle does not corrupt mysqlnd connect_attr +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- + +--EXPECT-- +done! diff --git a/ext/mysqli/tests/mysqli_set_opt.phpt b/ext/mysqli/tests/mysqli_set_opt.phpt index 218e9f517786..4518201e4d1f 100644 --- a/ext/mysqli/tests/mysqli_set_opt.phpt +++ b/ext/mysqli/tests/mysqli_set_opt.phpt @@ -24,7 +24,12 @@ require_once 'skipifconnectfailure.inc'; var_dump(mysqli_set_opt($link, MYSQLI_OPT_CONNECT_TIMEOUT, 10)); var_dump(mysqli_set_opt($link, MYSQLI_OPT_LOCAL_INFILE, 1)); var_dump(mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0')); - var_dump(mysqli_set_opt($link, MYSQLI_CLIENT_SSL, 'not an mysqli_option')); + + try { + var_dump(mysqli_set_opt($link, MYSQLI_CLIENT_SSL, 'not an mysqli_option')); + } catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -48,6 +53,6 @@ bool(true) bool(true) bool(true) bool(true) -bool(false) +mysqli_set_opt(): Argument #2 ($option) must be MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, or one of the MYSQLI_OPT_* constants mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt index a36daebc7951..e4b913229cd0 100644 --- a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -25,6 +25,11 @@ require_once 'skipifconnectfailure.inc'; if (true !== ($tmp = mysqli_stmt_execute($stmt))) printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_data_seek($stmt, 1); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $id = null; if (!mysqli_stmt_bind_result($stmt, $id)) @@ -82,6 +87,7 @@ require_once 'skipifconnectfailure.inc'; ?> --EXPECT-- mysqli_stmt object is not fully initialized +mysqli_stmt_data_seek(): No result set associated with the statement int(3) int(1) int(1) diff --git a/ext/mysqli/tests/mysqli_stmt_execute_bind.phpt b/ext/mysqli/tests/mysqli_stmt_execute_bind.phpt index 5005cbf5fb5d..82d4be4ea18d 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute_bind.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute_bind.phpt @@ -118,7 +118,7 @@ $stmt = null; // 12. Only list arrays are allowed $stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); try { - $stmt->execute(['A'=>'abc', 2=>42, null=>$id]); + $stmt->execute(['A'=>'abc', 2=>42, ''=>$id]); } catch (ValueError $e) { echo '[008] '.$e->getMessage()."\n"; } diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt index dcc72108c7ef..600c8ae47993 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt @@ -42,11 +42,6 @@ require_once 'skipifconnectfailure.inc'; Label column, result set charset. All of the following columns are "too hot" - too server dependent */ - if ($field->charsetnr != $charsetInfo->number) { - printf("[004] Expecting charset %s/%d got %d\n", - $charsetInfo->charset, - $charsetInfo->number, $field->charsetnr); - } if ($field->length != $charsetInfo->max_length) { printf("[005] Expecting length %d got %d\n", $charsetInfo->max_length, $field->max_length); diff --git a/ext/mysqlnd/config.w32 b/ext/mysqlnd/config.w32 index cf6bf4b61ccc..e88b269c4863 100644 --- a/ext/mysqlnd/config.w32 +++ b/ext/mysqlnd/config.w32 @@ -29,7 +29,7 @@ if (PHP_MYSQLND != "no") { "php_mysqlnd.c "; EXTENSION("mysqlnd", mysqlnd_source, false, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); if (SETUP_ZLIB_LIB("mysqlnd", PHP_MYSQLND) && - CHECK_HEADER_ADD_INCLUDE("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) + CHECK_HEADER("zlib.h", "CFLAGS", "..\\zlib;" + php_usual_include_suspects) ) { AC_DEFINE("MYSQLND_COMPRESSION_ENABLED", 1, "Define to 1 if mysqlnd has compressed protocol support."); AC_DEFINE("MYSQLND_SSL_SUPPORTED", 1, "Define to 1 if mysqlnd core SSL is enabled."); diff --git a/ext/mysqlnd/mysql_float_to_double.h b/ext/mysqlnd/mysql_float_to_double.h index a15458b52de2..f92196e792c9 100644 --- a/ext/mysqlnd/mysql_float_to_double.h +++ b/ext/mysqlnd/mysql_float_to_double.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Keyur Govande | +----------------------------------------------------------------------+ diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 3336d1752afd..032438063bea 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_alloc.c b/ext/mysqlnd/mysqlnd_alloc.c index 06971b3487dd..187298ca9969 100644 --- a/ext/mysqlnd/mysqlnd_alloc.c +++ b/ext/mysqlnd/mysqlnd_alloc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -201,7 +199,7 @@ static void _mysqlnd_efree(void *ptr MYSQLND_MEM_D) #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -232,7 +230,7 @@ static void _mysqlnd_pefree(void *ptr, bool persistent MYSQLND_MEM_D) #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -264,7 +262,7 @@ static char * _mysqlnd_pememdup(const char * const ptr, size_t length, bool pers #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -295,7 +293,7 @@ static char * _mysqlnd_pestrndup(const char * const ptr, size_t length, bool per #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif @@ -336,7 +334,7 @@ static char * _mysqlnd_pestrdup(const char * const ptr, bool persistent MYSQLND_ TRACE_ALLOC_ENTER(mysqlnd_pestrdup_name); #if PHP_DEBUG { - char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); + const char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR); TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno); } #endif diff --git a/ext/mysqlnd/mysqlnd_alloc.h b/ext/mysqlnd/mysqlnd_alloc.h index deaef3748965..203d7207740a 100644 --- a/ext/mysqlnd/mysqlnd_alloc.h +++ b/ext/mysqlnd/mysqlnd_alloc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c index 691375b1a695..3504caa2dea1 100644 --- a/ext/mysqlnd/mysqlnd_auth.c +++ b/ext/mysqlnd/mysqlnd_auth.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -43,7 +41,6 @@ mysqlnd_run_authentication( const MYSQLND_STRING auth_plugin_data, const char * const auth_protocol, const unsigned int charset_no, - const MYSQLND_SESSION_OPTIONS * const session_options, const zend_ulong mysql_flags, const bool silent, const bool is_change_user @@ -110,7 +107,7 @@ mysqlnd_run_authentication( scrambled_data = auth_plugin->methods.get_auth_data( NULL, &scrambled_data_len, conn, user, passwd, passwd_len, plugin_data, plugin_data_len, - session_options, conn->protocol_frame_codec->data, + conn->protocol_frame_codec->data, mysql_flags); } @@ -118,7 +115,7 @@ mysqlnd_run_authentication( goto end; } if (FALSE == is_change_user) { - ret = mysqlnd_auth_handshake(conn, user, passwd, passwd_len, db, db_len, session_options, mysql_flags, + ret = mysqlnd_auth_handshake(conn, user, passwd, passwd_len, db, db_len, mysql_flags, charset_no, first_call, requested_protocol, @@ -177,14 +174,13 @@ static enum_func_status mysqlnd_switch_to_ssl_if_needed(MYSQLND_CONN_DATA * const conn, unsigned int charset_no, const size_t server_capabilities, - const MYSQLND_SESSION_OPTIONS * const session_options, const zend_ulong mysql_flags) { enum_func_status ret = FAIL; const MYSQLND_CHARSET * charset; DBG_ENTER("mysqlnd_switch_to_ssl_if_needed"); - if (session_options->charset_name && (charset = mysqlnd_find_charset_name(session_options->charset_name))) { + if (conn->options->charset_name && (charset = mysqlnd_find_charset_name(conn->options->charset_name))) { charset_no = charset->nr; } @@ -210,18 +206,17 @@ mysqlnd_connect_run_authentication( const char * const authentication_protocol, const unsigned int charset_no, const size_t server_capabilities, - const MYSQLND_SESSION_OPTIONS * const session_options, const zend_ulong mysql_flags ) { enum_func_status ret = FAIL; DBG_ENTER("mysqlnd_connect_run_authentication"); - ret = mysqlnd_switch_to_ssl_if_needed(conn, charset_no, server_capabilities, session_options, mysql_flags); + ret = mysqlnd_switch_to_ssl_if_needed(conn, charset_no, server_capabilities, mysql_flags); if (PASS == ret) { ret = mysqlnd_run_authentication(conn, user, passwd, passwd_len, db, db_len, authentication_plugin_data, authentication_protocol, - charset_no, session_options, mysql_flags, FALSE /*silent*/, FALSE/*is_change*/); + charset_no, mysql_flags, FALSE /*silent*/, FALSE/*is_change*/); } DBG_RETURN(ret); } @@ -236,7 +231,6 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, const size_t passwd_len, const char * const db, const size_t db_len, - const MYSQLND_SESSION_OPTIONS * const session_options, const zend_ulong mysql_flags, const unsigned int server_charset_no, const bool use_full_blown_auth_packet, @@ -281,8 +275,8 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, conn->payload_decoder_factory->m.init_auth_packet(&auth_packet); auth_packet.client_flags = mysql_flags; - auth_packet.max_packet_size = session_options->max_allowed_packet; - if (session_options->charset_name && (charset = mysqlnd_find_charset_name(session_options->charset_name))) { + auth_packet.max_packet_size = conn->options->max_allowed_packet; + if (conn->options->charset_name && (charset = mysqlnd_find_charset_name(conn->options->charset_name))) { auth_packet.charset_no = charset->nr; } else { auth_packet.charset_no = server_charset_no; @@ -556,7 +550,6 @@ mysqlnd_native_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len, - const MYSQLND_SESSION_OPTIONS * const session_options, const MYSQLND_PFC_DATA * const pfc_data, const zend_ulong mysql_flags ) @@ -592,7 +585,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_native_auth_plugin = "auth_plugin_mysql_native_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* no statistics , will be filled later if there are some */ @@ -617,7 +610,6 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self, size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len, - const MYSQLND_SESSION_OPTIONS * const session_options, const MYSQLND_PFC_DATA * const pfc_data, const zend_ulong mysql_flags ) @@ -646,7 +638,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin "auth_plugin_mysql_clear_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* no statistics , will be filled later if there are some */ @@ -820,7 +812,6 @@ mysqlnd_sha256_public_encrypt(MYSQLND_CONN_DATA * conn, mysqlnd_rsa_t server_pub /* {{{ mysqlnd_sha256_get_rsa_key */ static mysqlnd_rsa_t mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn, - const MYSQLND_SESSION_OPTIONS * const session_options, const MYSQLND_PFC_DATA * const pfc_data ) { @@ -894,7 +885,6 @@ mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len, - const MYSQLND_SESSION_OPTIONS * const session_options, const MYSQLND_PFC_DATA * const pfc_data, const zend_ulong mysql_flags ) @@ -916,7 +906,7 @@ mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self ret[passwd_len] = '\0'; } else { *auth_data_len = 0; - server_public_key = mysqlnd_sha256_get_rsa_key(conn, session_options, pfc_data); + server_public_key = mysqlnd_sha256_get_rsa_key(conn, pfc_data); if (server_public_key) { ALLOCA_FLAG(use_heap); @@ -944,7 +934,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_sha256_authentication_plu "auth_plugin_sha256_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel ", { NULL, /* no statistics , will be filled later if there are some */ @@ -1095,7 +1085,6 @@ mysqlnd_caching_sha2_get_auth_data(struct st_mysqlnd_authentication_plugin * sel size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len, - const MYSQLND_SESSION_OPTIONS * const session_options, const MYSQLND_PFC_DATA * const pfc_data, const zend_ulong mysql_flags ) @@ -1306,7 +1295,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_caching_sha2_auth_plugin "auth_plugin_caching_sha2_password", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Johannes Schlüter ", { NULL, /* no statistics , will be filled later if there are some */ diff --git a/ext/mysqlnd/mysqlnd_auth.h b/ext/mysqlnd/mysqlnd_auth.h index 2ba2321a77ad..f4a0f3146094 100644 --- a/ext/mysqlnd/mysqlnd_auth.h +++ b/ext/mysqlnd/mysqlnd_auth.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -24,7 +22,6 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, const size_t passwd_len, const char * const db, const size_t db_len, - const MYSQLND_SESSION_OPTIONS * const session_options, const zend_ulong mysql_flags, const unsigned int server_charset_no, const bool use_full_blown_auth_packet, @@ -75,7 +72,6 @@ mysqlnd_connect_run_authentication( const char * const authentication_protocol, const unsigned int charset_no, const size_t server_capabilities, - const MYSQLND_SESSION_OPTIONS * const session_options, const zend_ulong mysql_flags ); @@ -90,7 +86,6 @@ mysqlnd_run_authentication( const MYSQLND_STRING auth_plugin_data, const char * const auth_protocol, const unsigned int charset_no, - const MYSQLND_SESSION_OPTIONS * const session_options, const zend_ulong mysql_flags, const bool silent, const bool is_change_user diff --git a/ext/mysqlnd/mysqlnd_block_alloc.c b/ext/mysqlnd/mysqlnd_block_alloc.c index dafcbcc8bbb8..db836d3f7b92 100644 --- a/ext/mysqlnd/mysqlnd_block_alloc.c +++ b/ext/mysqlnd/mysqlnd_block_alloc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_block_alloc.h b/ext/mysqlnd/mysqlnd_block_alloc.h index 7c9aac3b8e5f..31f315235d72 100644 --- a/ext/mysqlnd/mysqlnd_block_alloc.h +++ b/ext/mysqlnd/mysqlnd_block_alloc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c index 3503e79357ad..eacf74240fd1 100644 --- a/ext/mysqlnd/mysqlnd_charset.c +++ b/ext/mysqlnd/mysqlnd_charset.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -575,257 +573,257 @@ static unsigned int mysqlnd_mbvalid_dispatch(enum mysqlnd_encoding_valid encodin /* {{{ mysqlnd_charsets */ const MYSQLND_CHARSET mysqlnd_charsets[] = { - { 1, "big5","big5_chinese_ci", 1, 2, "", mysqlnd_mbcharlen_big5_id, check_mb_big5_id, LOWEST_MB_BIG5}, - { 3, "dec8", "dec8_swedish_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 4, "cp850", "cp850_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 6, "hp8", "hp8_english_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 7, "koi8r", "koi8r_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 8, "latin1", "latin1_swedish_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 5, "latin1", "latin1_german1_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, /* should be after 0x8 because swedish_ci is the default collation */ - { 9, "latin2", "latin2_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 2, "latin2", "latin2_czech_cs", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, /* should be after 0x9 because general_ci is the default collation */ - { 10, "swe7", "swe7_swedish_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 11, "ascii", "ascii_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 12, "ujis", "ujis_japanese_ci", 1, 3, "", mysqlnd_mbcharlen_ujis_id, check_mb_ujis_id, LOWEST_MB_UJIS}, - { 13, "sjis", "sjis_japanese_ci", 1, 2, "", mysqlnd_mbcharlen_sjis_id, check_mb_sjis_id, LOWEST_MB_SJIS}, - { 16, "hebrew", "hebrew_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 17, "filename", "filename", 1, 5, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 18, "tis620", "tis620_thai_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 19, "euckr", "euckr_korean_ci", 1, 2, "", mysqlnd_mbcharlen_euckr_id, check_mb_euckr_id, LOWEST_MB_EUCKR}, - { 21, "latin2", "latin2_hungarian_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 27, "latin2", "latin2_croatian_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 22, "koi8u", "koi8u_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 24, "gb2312", "gb2312_chinese_ci", 1, 2, "", mysqlnd_mbcharlen_gb2312_id, check_mb_gb2312_id, LOWEST_MB_GB2312}, - { 25, "greek", "greek_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 26, "cp1250", "cp1250_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 28, "gbk", "gbk_chinese_ci", 1, 2, "", mysqlnd_mbcharlen_gbk_id, check_mb_gbk_id, LOWEST_MB_GBK}, - { 30, "latin5", "latin5_turkish_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 31, "latin1", "latin1_german2_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 15, "latin1", "latin1_danish_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 32, "armscii8", "armscii8_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 33, UTF8_MB3, UTF8_MB3"_general_ci", 1, 3, "UTF-8 Unicode", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 35, "ucs2", "ucs2_general_ci", 2, 2, "UCS-2 Unicode", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 36, "cp866", "cp866_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 37, "keybcs2", "keybcs2_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 38, "macce", "macce_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 39, "macroman", "macroman_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 40, "cp852", "cp852_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 41, "latin7", "latin7_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 20, "latin7", "latin7_estonian_cs", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 57, "cp1256", "cp1256_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 59, "cp1257", "cp1257_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 63, "binary", "binary", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 97, "eucjpms", "eucjpms_japanese_ci", 1, 3, "", mysqlnd_mbcharlen_eucjpms_id, check_mb_eucjpms_id, LOWEST_MB_EUCJPMS}, - { 29, "cp1257", "cp1257_lithuanian_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 31, "latin1", "latin1_german2_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 34, "cp1250", "cp1250_czech_cs", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 42, "latin7", "latin7_general_cs", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 43, "macce", "macce_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 44, "cp1250", "cp1250_croatian_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 45, UTF8_MB4, UTF8_MB4"_general_ci", 1, 4, "UTF-8 Unicode", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 46, UTF8_MB4, UTF8_MB4"_bin", 1, 4, "UTF-8 Unicode", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 47, "latin1", "latin1_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 48, "latin1", "latin1_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 49, "latin1", "latin1_general_cs", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 51, "cp1251", "cp1251_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 14, "cp1251", "cp1251_bulgarian_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 23, "cp1251", "cp1251_ukrainian_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 50, "cp1251", "cp1251_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 52, "cp1251", "cp1251_general_cs", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 53, "macroman", "macroman_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 54, "utf16", "utf16_general_ci", 2, 4, "UTF-16 Unicode", mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, - { 55, "utf16", "utf16_bin", 2, 4, "UTF-16 Unicode", mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, - { 56, "utf16le", "utf16le_general_ci", 2, 4, "UTF-16LE Unicode", mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, - { 58, "cp1257", "cp1257_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, -/*55*/{ 60, "utf32", "utf32_general_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*55*/{ 61, "utf32", "utf32_bin", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, - { 62, "utf16le", "utf16le_bin", 2, 4, "UTF-16LE Unicode", mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, - { 64, "armscii8", "armscii8_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 65, "ascii", "ascii_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 66, "cp1250", "cp1250_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 67, "cp1256", "cp1256_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 68, "cp866", "cp866_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 69, "dec8", "dec8_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 70, "greek", "greek_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 71, "hebrew", "hebrew_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 72, "hp8", "hp8_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 73, "keybcs2", "keybcs2_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 74, "koi8r", "koi8r_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 75, "koi8u", "koi8u_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 77, "latin2", "latin2_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 78, "latin5", "latin5_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 79, "latin7", "latin7_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 80, "cp850", "cp850_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 81, "cp852", "cp852_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 82, "swe7", "swe7_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 83, UTF8_MB3, UTF8_MB3"_bin", 1, 3, "UTF-8 Unicode", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 84, "big5", "big5_bin", 1, 2, "", mysqlnd_mbcharlen_big5_id, check_mb_big5_id, LOWEST_MB_BIG5}, - { 85, "euckr", "euckr_bin", 1, 2, "", mysqlnd_mbcharlen_euckr_id, check_mb_euckr_id, LOWEST_MB_EUCKR}, - { 86, "gb2312", "gb2312_bin", 1, 2, "", mysqlnd_mbcharlen_gb2312_id, check_mb_gb2312_id, LOWEST_MB_GB2312}, - { 87, "gbk", "gbk_bin", 1, 2, "", mysqlnd_mbcharlen_gbk_id, check_mb_gbk_id, LOWEST_MB_GBK}, - { 88, "sjis", "sjis_bin", 1, 2, "", mysqlnd_mbcharlen_sjis_id, check_mb_sjis_id, LOWEST_MB_SJIS}, - { 89, "tis620", "tis620_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 90, "ucs2", "ucs2_bin", 2, 2, "UCS-2 Unicode", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 91, "ujis", "ujis_bin", 1, 3, "", mysqlnd_mbcharlen_ujis_id, check_mb_ujis_id, LOWEST_MB_UJIS}, - { 92, "geostd8", "geostd8_general_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 93, "geostd8", "geostd8_bin", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 94, "latin1", "latin1_spanish_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 95, "cp932", "cp932_japanese_ci", 1, 2, "", mysqlnd_mbcharlen_cp932_id, check_mb_cp932_id, LOWEST_MB_CP932}, - { 96, "cp932", "cp932_bin", 1, 2, "", mysqlnd_mbcharlen_cp932_id, check_mb_cp932_id, LOWEST_MB_CP932}, - { 97, "eucjpms", "eucjpms_japanese_ci", 1, 3, "", mysqlnd_mbcharlen_eucjpms_id, check_mb_eucjpms_id, LOWEST_MB_EUCJPMS}, - { 98, "eucjpms", "eucjpms_bin", 1, 3, "", mysqlnd_mbcharlen_eucjpms_id, check_mb_eucjpms_id, LOWEST_MB_EUCJPMS}, - { 99, "cp1250", "cp1250_polish_ci", 1, 1, "", mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, - { 128, "ucs2", "ucs2_unicode_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 129, "ucs2", "ucs2_icelandic_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 130, "ucs2", "ucs2_latvian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 131, "ucs2", "ucs2_romanian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 132, "ucs2", "ucs2_slovenian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 133, "ucs2", "ucs2_polish_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 134, "ucs2", "ucs2_estonian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 135, "ucs2", "ucs2_spanish_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 136, "ucs2", "ucs2_swedish_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 137, "ucs2", "ucs2_turkish_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 138, "ucs2", "ucs2_czech_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 139, "ucs2", "ucs2_danish_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 140, "ucs2", "ucs2_lithuanian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 141, "ucs2", "ucs2_slovak_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 142, "ucs2", "ucs2_spanish2_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 143, "ucs2", "ucs2_roman_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 144, "ucs2", "ucs2_persian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 145, "ucs2", "ucs2_esperanto_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 146, "ucs2", "ucs2_hungarian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 147, "ucs2", "ucs2_sinhala_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 148, "ucs2", "ucs2_german2_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 149, "ucs2", "ucs2_croatian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 150, "ucs2", "ucs2_unicode_520_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - { 151, "ucs2", "ucs2_vietnamese_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, - -/*56*/{160, "utf32", "utf32_unicode_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{161, "utf32", "utf32_icelandic_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{162, "utf32", "utf32_latvian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{163, "utf32", "utf32_romanian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{164, "utf32", "utf32_slovenian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{165, "utf32", "utf32_polish_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{166, "utf32", "utf32_estonian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{167, "utf32", "utf32_spanish_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{168, "utf32", "utf32_swedish_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{169, "utf32", "utf32_turkish_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{170, "utf32", "utf32_czech_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{171, "utf32", "utf32_danish_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{172, "utf32", "utf32_lithuanian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{173, "utf32", "utf32_slovak_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{174, "utf32", "utf32_spanish2_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{175, "utf32", "utf32_roman_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{176, "utf32", "utf32_persian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{177, "utf32", "utf32_esperanto_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{178, "utf32", "utf32_hungarian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{179, "utf32", "utf32_sinhala_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{180, "utf32", "utf32_german2_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{181, "utf32", "utf32_croatian_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{182, "utf32", "utf32_unicode_520_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, -/*56*/{183, "utf32", "utf32_vietnamese_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, - - { 192, UTF8_MB3, UTF8_MB3"_unicode_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 193, UTF8_MB3, UTF8_MB3"_icelandic_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 194, UTF8_MB3, UTF8_MB3"_latvian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 195, UTF8_MB3, UTF8_MB3"_romanian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 196, UTF8_MB3, UTF8_MB3"_slovenian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 197, UTF8_MB3, UTF8_MB3"_polish_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 198, UTF8_MB3, UTF8_MB3"_estonian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 199, UTF8_MB3, UTF8_MB3"_spanish_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 200, UTF8_MB3, UTF8_MB3"_swedish_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 201, UTF8_MB3, UTF8_MB3"_turkish_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 202, UTF8_MB3, UTF8_MB3"_czech_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 203, UTF8_MB3, UTF8_MB3"_danish_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 204, UTF8_MB3, UTF8_MB3"_lithuanian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 205, UTF8_MB3, UTF8_MB3"_slovak_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 206, UTF8_MB3, UTF8_MB3"_spanish2_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 207, UTF8_MB3, UTF8_MB3"_roman_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 208, UTF8_MB3, UTF8_MB3"_persian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 209, UTF8_MB3, UTF8_MB3"_esperanto_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 210, UTF8_MB3, UTF8_MB3"_hungarian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 211, UTF8_MB3, UTF8_MB3"_sinhala_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 212, UTF8_MB3, UTF8_MB3"_german2_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 213, UTF8_MB3, UTF8_MB3"_croatian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 214, UTF8_MB3, UTF8_MB3"_unicode_520_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - { 215, UTF8_MB3, UTF8_MB3"_vietnamese_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, - - { 224, UTF8_MB4, UTF8_MB4"_unicode_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 225, UTF8_MB4, UTF8_MB4"_icelandic_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 226, UTF8_MB4, UTF8_MB4"_latvian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 227, UTF8_MB4, UTF8_MB4"_romanian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 228, UTF8_MB4, UTF8_MB4"_slovenian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 229, UTF8_MB4, UTF8_MB4"_polish_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 230, UTF8_MB4, UTF8_MB4"_estonian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 231, UTF8_MB4, UTF8_MB4"_spanish_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 232, UTF8_MB4, UTF8_MB4"_swedish_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 233, UTF8_MB4, UTF8_MB4"_turkish_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 234, UTF8_MB4, UTF8_MB4"_czech_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 235, UTF8_MB4, UTF8_MB4"_danish_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 236, UTF8_MB4, UTF8_MB4"_lithuanian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 237, UTF8_MB4, UTF8_MB4"_slovak_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 238, UTF8_MB4, UTF8_MB4"_spanish2_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 239, UTF8_MB4, UTF8_MB4"_roman_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 240, UTF8_MB4, UTF8_MB4"_persian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 241, UTF8_MB4, UTF8_MB4"_esperanto_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 242, UTF8_MB4, UTF8_MB4"_hungarian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 243, UTF8_MB4, UTF8_MB4"_sinhala_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 244, UTF8_MB4, UTF8_MB4"_german2_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 245, UTF8_MB4, UTF8_MB4"_croatian_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 246, UTF8_MB4, UTF8_MB4"_unicode_520_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 247, UTF8_MB4, UTF8_MB4"_vietnamese_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 248, "gb18030", "gb18030_chinese_ci", 1, 4, "", mysqlnd_mbcharlen_gb18030_id, my_ismbchar_gb18030_id, LOWEST_MB_GB18030}, - { 249, "gb18030", "gb18030_bin", 1, 4, "", mysqlnd_mbcharlen_gb18030_id, my_ismbchar_gb18030_id, LOWEST_MB_GB18030}, - - { 254, UTF8_MB3, UTF8_MB3"_general_cs", 1, 3, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 255, UTF8_MB4, UTF8_MB4"_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 256, UTF8_MB4, UTF8_MB4"_de_pb_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 257, UTF8_MB4, UTF8_MB4"_is_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 258, UTF8_MB4, UTF8_MB4"_lv_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 259, UTF8_MB4, UTF8_MB4"_ro_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 260, UTF8_MB4, UTF8_MB4"_sl_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 261, UTF8_MB4, UTF8_MB4"_pl_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 262, UTF8_MB4, UTF8_MB4"_et_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 263, UTF8_MB4, UTF8_MB4"_es_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 264, UTF8_MB4, UTF8_MB4"_sv_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 265, UTF8_MB4, UTF8_MB4"_tr_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 266, UTF8_MB4, UTF8_MB4"_cs_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 267, UTF8_MB4, UTF8_MB4"_da_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 268, UTF8_MB4, UTF8_MB4"_lt_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 269, UTF8_MB4, UTF8_MB4"_sk_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 270, UTF8_MB4, UTF8_MB4"_es_trad_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 271, UTF8_MB4, UTF8_MB4"_la_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 272, UTF8_MB4, UTF8_MB4"_fa_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 273, UTF8_MB4, UTF8_MB4"_eo_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 274, UTF8_MB4, UTF8_MB4"_hu_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 275, UTF8_MB4, UTF8_MB4"_hr_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 276, UTF8_MB4, UTF8_MB4"_si_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 277, UTF8_MB4, UTF8_MB4"_vi_0900_ai_ci", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 278, UTF8_MB4, UTF8_MB4"_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 279, UTF8_MB4, UTF8_MB4"_de_pb_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 280, UTF8_MB4, UTF8_MB4"_is_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 281, UTF8_MB4, UTF8_MB4"_lv_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 282, UTF8_MB4, UTF8_MB4"_ro_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 283, UTF8_MB4, UTF8_MB4"_sl_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 284, UTF8_MB4, UTF8_MB4"_pl_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 285, UTF8_MB4, UTF8_MB4"_et_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 286, UTF8_MB4, UTF8_MB4"_es_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 287, UTF8_MB4, UTF8_MB4"_sv_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 288, UTF8_MB4, UTF8_MB4"_tr_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 289, UTF8_MB4, UTF8_MB4"_cs_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 290, UTF8_MB4, UTF8_MB4"_da_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 291, UTF8_MB4, UTF8_MB4"_lt_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 292, UTF8_MB4, UTF8_MB4"_sk_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 293, UTF8_MB4, UTF8_MB4"_es_trad_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 294, UTF8_MB4, UTF8_MB4"_la_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 295, UTF8_MB4, UTF8_MB4"_fa_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 296, UTF8_MB4, UTF8_MB4"_eo_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 297, UTF8_MB4, UTF8_MB4"_hu_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 298, UTF8_MB4, UTF8_MB4"_hr_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 299, UTF8_MB4, UTF8_MB4"_si_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 300, UTF8_MB4, UTF8_MB4"_vi_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 303, UTF8_MB4, UTF8_MB4"_ja_0900_as_cs", 1, 4, "", mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, - { 0, NULL, NULL, 0, 0, NULL, mysqlnd_mbcharlen_null_id, check_null_id, 0x100} + { 1, "big5","big5_chinese_ci", 1, 2, mysqlnd_mbcharlen_big5_id, check_mb_big5_id, LOWEST_MB_BIG5}, + { 3, "dec8", "dec8_swedish_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 4, "cp850", "cp850_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 6, "hp8", "hp8_english_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 7, "koi8r", "koi8r_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 8, "latin1", "latin1_swedish_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 5, "latin1", "latin1_german1_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, /* should be after 0x8 because swedish_ci is the default collation */ + { 9, "latin2", "latin2_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 2, "latin2", "latin2_czech_cs", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, /* should be after 0x9 because general_ci is the default collation */ + { 10, "swe7", "swe7_swedish_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 11, "ascii", "ascii_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 12, "ujis", "ujis_japanese_ci", 1, 3, mysqlnd_mbcharlen_ujis_id, check_mb_ujis_id, LOWEST_MB_UJIS}, + { 13, "sjis", "sjis_japanese_ci", 1, 2, mysqlnd_mbcharlen_sjis_id, check_mb_sjis_id, LOWEST_MB_SJIS}, + { 16, "hebrew", "hebrew_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 17, "filename", "filename", 1, 5, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 18, "tis620", "tis620_thai_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 19, "euckr", "euckr_korean_ci", 1, 2, mysqlnd_mbcharlen_euckr_id, check_mb_euckr_id, LOWEST_MB_EUCKR}, + { 21, "latin2", "latin2_hungarian_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 27, "latin2", "latin2_croatian_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 22, "koi8u", "koi8u_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 24, "gb2312", "gb2312_chinese_ci", 1, 2, mysqlnd_mbcharlen_gb2312_id, check_mb_gb2312_id, LOWEST_MB_GB2312}, + { 25, "greek", "greek_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 26, "cp1250", "cp1250_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 28, "gbk", "gbk_chinese_ci", 1, 2, mysqlnd_mbcharlen_gbk_id, check_mb_gbk_id, LOWEST_MB_GBK}, + { 30, "latin5", "latin5_turkish_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 31, "latin1", "latin1_german2_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 15, "latin1", "latin1_danish_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 32, "armscii8", "armscii8_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 33, UTF8_MB3, UTF8_MB3"_general_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 35, "ucs2", "ucs2_general_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 36, "cp866", "cp866_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 37, "keybcs2", "keybcs2_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 38, "macce", "macce_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 39, "macroman", "macroman_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 40, "cp852", "cp852_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 41, "latin7", "latin7_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 20, "latin7", "latin7_estonian_cs", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 57, "cp1256", "cp1256_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 59, "cp1257", "cp1257_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 63, "binary", "binary", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 97, "eucjpms", "eucjpms_japanese_ci", 1, 3, mysqlnd_mbcharlen_eucjpms_id, check_mb_eucjpms_id, LOWEST_MB_EUCJPMS}, + { 29, "cp1257", "cp1257_lithuanian_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 31, "latin1", "latin1_german2_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 34, "cp1250", "cp1250_czech_cs", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 42, "latin7", "latin7_general_cs", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 43, "macce", "macce_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 44, "cp1250", "cp1250_croatian_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 45, UTF8_MB4, UTF8_MB4"_general_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 46, UTF8_MB4, UTF8_MB4"_bin", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 47, "latin1", "latin1_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 48, "latin1", "latin1_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 49, "latin1", "latin1_general_cs", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 51, "cp1251", "cp1251_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 14, "cp1251", "cp1251_bulgarian_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 23, "cp1251", "cp1251_ukrainian_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 50, "cp1251", "cp1251_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 52, "cp1251", "cp1251_general_cs", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 53, "macroman", "macroman_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 54, "utf16", "utf16_general_ci", 2, 4, mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, + { 55, "utf16", "utf16_bin", 2, 4, mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, + { 56, "utf16le", "utf16le_general_ci", 2, 4, mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, + { 58, "cp1257", "cp1257_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, +/*55*/{ 60, "utf32", "utf32_general_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*55*/{ 61, "utf32", "utf32_bin", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, + { 62, "utf16le", "utf16le_bin", 2, 4, mysqlnd_mbcharlen_utf16_id, check_mb_utf16_id, LOWEST_MB_UTF16}, + { 64, "armscii8", "armscii8_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 65, "ascii", "ascii_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 66, "cp1250", "cp1250_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 67, "cp1256", "cp1256_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 68, "cp866", "cp866_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 69, "dec8", "dec8_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 70, "greek", "greek_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 71, "hebrew", "hebrew_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 72, "hp8", "hp8_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 73, "keybcs2", "keybcs2_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 74, "koi8r", "koi8r_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 75, "koi8u", "koi8u_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 77, "latin2", "latin2_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 78, "latin5", "latin5_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 79, "latin7", "latin7_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 80, "cp850", "cp850_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 81, "cp852", "cp852_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 82, "swe7", "swe7_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 83, UTF8_MB3, UTF8_MB3"_bin", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 84, "big5", "big5_bin", 1, 2, mysqlnd_mbcharlen_big5_id, check_mb_big5_id, LOWEST_MB_BIG5}, + { 85, "euckr", "euckr_bin", 1, 2, mysqlnd_mbcharlen_euckr_id, check_mb_euckr_id, LOWEST_MB_EUCKR}, + { 86, "gb2312", "gb2312_bin", 1, 2, mysqlnd_mbcharlen_gb2312_id, check_mb_gb2312_id, LOWEST_MB_GB2312}, + { 87, "gbk", "gbk_bin", 1, 2, mysqlnd_mbcharlen_gbk_id, check_mb_gbk_id, LOWEST_MB_GBK}, + { 88, "sjis", "sjis_bin", 1, 2, mysqlnd_mbcharlen_sjis_id, check_mb_sjis_id, LOWEST_MB_SJIS}, + { 89, "tis620", "tis620_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 90, "ucs2", "ucs2_bin", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 91, "ujis", "ujis_bin", 1, 3, mysqlnd_mbcharlen_ujis_id, check_mb_ujis_id, LOWEST_MB_UJIS}, + { 92, "geostd8", "geostd8_general_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 93, "geostd8", "geostd8_bin", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 94, "latin1", "latin1_spanish_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 95, "cp932", "cp932_japanese_ci", 1, 2, mysqlnd_mbcharlen_cp932_id, check_mb_cp932_id, LOWEST_MB_CP932}, + { 96, "cp932", "cp932_bin", 1, 2, mysqlnd_mbcharlen_cp932_id, check_mb_cp932_id, LOWEST_MB_CP932}, + { 97, "eucjpms", "eucjpms_japanese_ci", 1, 3, mysqlnd_mbcharlen_eucjpms_id, check_mb_eucjpms_id, LOWEST_MB_EUCJPMS}, + { 98, "eucjpms", "eucjpms_bin", 1, 3, mysqlnd_mbcharlen_eucjpms_id, check_mb_eucjpms_id, LOWEST_MB_EUCJPMS}, + { 99, "cp1250", "cp1250_polish_ci", 1, 1, mysqlnd_mbcharlen_null_id, check_null_id, 0x100}, + { 128, "ucs2", "ucs2_unicode_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 129, "ucs2", "ucs2_icelandic_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 130, "ucs2", "ucs2_latvian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 131, "ucs2", "ucs2_romanian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 132, "ucs2", "ucs2_slovenian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 133, "ucs2", "ucs2_polish_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 134, "ucs2", "ucs2_estonian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 135, "ucs2", "ucs2_spanish_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 136, "ucs2", "ucs2_swedish_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 137, "ucs2", "ucs2_turkish_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 138, "ucs2", "ucs2_czech_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 139, "ucs2", "ucs2_danish_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 140, "ucs2", "ucs2_lithuanian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 141, "ucs2", "ucs2_slovak_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 142, "ucs2", "ucs2_spanish2_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 143, "ucs2", "ucs2_roman_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 144, "ucs2", "ucs2_persian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 145, "ucs2", "ucs2_esperanto_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 146, "ucs2", "ucs2_hungarian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 147, "ucs2", "ucs2_sinhala_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 148, "ucs2", "ucs2_german2_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 149, "ucs2", "ucs2_croatian_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 150, "ucs2", "ucs2_unicode_520_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + { 151, "ucs2", "ucs2_vietnamese_ci", 2, 2, mysqlnd_mbcharlen_ucs2_id, check_mb_ucs2_id, LOWEST_MB_UCS2}, + +/*56*/{160, "utf32", "utf32_unicode_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{161, "utf32", "utf32_icelandic_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{162, "utf32", "utf32_latvian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{163, "utf32", "utf32_romanian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{164, "utf32", "utf32_slovenian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{165, "utf32", "utf32_polish_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{166, "utf32", "utf32_estonian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{167, "utf32", "utf32_spanish_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{168, "utf32", "utf32_swedish_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{169, "utf32", "utf32_turkish_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{170, "utf32", "utf32_czech_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{171, "utf32", "utf32_danish_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{172, "utf32", "utf32_lithuanian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{173, "utf32", "utf32_slovak_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{174, "utf32", "utf32_spanish2_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{175, "utf32", "utf32_roman_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{176, "utf32", "utf32_persian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{177, "utf32", "utf32_esperanto_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{178, "utf32", "utf32_hungarian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{179, "utf32", "utf32_sinhala_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{180, "utf32", "utf32_german2_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{181, "utf32", "utf32_croatian_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{182, "utf32", "utf32_unicode_520_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, +/*56*/{183, "utf32", "utf32_vietnamese_ci", 4, 4, mysqlnd_mbcharlen_utf32_id, check_mb_utf32_id, LOWEST_MB_UTF32}, + + { 192, UTF8_MB3, UTF8_MB3"_unicode_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 193, UTF8_MB3, UTF8_MB3"_icelandic_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 194, UTF8_MB3, UTF8_MB3"_latvian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 195, UTF8_MB3, UTF8_MB3"_romanian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 196, UTF8_MB3, UTF8_MB3"_slovenian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 197, UTF8_MB3, UTF8_MB3"_polish_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 198, UTF8_MB3, UTF8_MB3"_estonian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 199, UTF8_MB3, UTF8_MB3"_spanish_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 200, UTF8_MB3, UTF8_MB3"_swedish_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 201, UTF8_MB3, UTF8_MB3"_turkish_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 202, UTF8_MB3, UTF8_MB3"_czech_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 203, UTF8_MB3, UTF8_MB3"_danish_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 204, UTF8_MB3, UTF8_MB3"_lithuanian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 205, UTF8_MB3, UTF8_MB3"_slovak_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 206, UTF8_MB3, UTF8_MB3"_spanish2_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 207, UTF8_MB3, UTF8_MB3"_roman_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 208, UTF8_MB3, UTF8_MB3"_persian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 209, UTF8_MB3, UTF8_MB3"_esperanto_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 210, UTF8_MB3, UTF8_MB3"_hungarian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 211, UTF8_MB3, UTF8_MB3"_sinhala_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 212, UTF8_MB3, UTF8_MB3"_german2_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 213, UTF8_MB3, UTF8_MB3"_croatian_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 214, UTF8_MB3, UTF8_MB3"_unicode_520_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + { 215, UTF8_MB3, UTF8_MB3"_vietnamese_ci", 1, 3, mysqlnd_mbcharlen_utf8mb3_id, check_mb_utf8mb3_valid_id, LOWEST_MB_UTF8MB3}, + + { 224, UTF8_MB4, UTF8_MB4"_unicode_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 225, UTF8_MB4, UTF8_MB4"_icelandic_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 226, UTF8_MB4, UTF8_MB4"_latvian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 227, UTF8_MB4, UTF8_MB4"_romanian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 228, UTF8_MB4, UTF8_MB4"_slovenian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 229, UTF8_MB4, UTF8_MB4"_polish_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 230, UTF8_MB4, UTF8_MB4"_estonian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 231, UTF8_MB4, UTF8_MB4"_spanish_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 232, UTF8_MB4, UTF8_MB4"_swedish_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 233, UTF8_MB4, UTF8_MB4"_turkish_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 234, UTF8_MB4, UTF8_MB4"_czech_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 235, UTF8_MB4, UTF8_MB4"_danish_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 236, UTF8_MB4, UTF8_MB4"_lithuanian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 237, UTF8_MB4, UTF8_MB4"_slovak_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 238, UTF8_MB4, UTF8_MB4"_spanish2_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 239, UTF8_MB4, UTF8_MB4"_roman_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 240, UTF8_MB4, UTF8_MB4"_persian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 241, UTF8_MB4, UTF8_MB4"_esperanto_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 242, UTF8_MB4, UTF8_MB4"_hungarian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 243, UTF8_MB4, UTF8_MB4"_sinhala_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 244, UTF8_MB4, UTF8_MB4"_german2_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 245, UTF8_MB4, UTF8_MB4"_croatian_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 246, UTF8_MB4, UTF8_MB4"_unicode_520_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 247, UTF8_MB4, UTF8_MB4"_vietnamese_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 248, "gb18030", "gb18030_chinese_ci", 1, 4, mysqlnd_mbcharlen_gb18030_id, my_ismbchar_gb18030_id, LOWEST_MB_GB18030}, + { 249, "gb18030", "gb18030_bin", 1, 4, mysqlnd_mbcharlen_gb18030_id, my_ismbchar_gb18030_id, LOWEST_MB_GB18030}, + + { 254, UTF8_MB3, UTF8_MB3"_general_cs", 1, 3, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 255, UTF8_MB4, UTF8_MB4"_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 256, UTF8_MB4, UTF8_MB4"_de_pb_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 257, UTF8_MB4, UTF8_MB4"_is_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 258, UTF8_MB4, UTF8_MB4"_lv_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 259, UTF8_MB4, UTF8_MB4"_ro_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 260, UTF8_MB4, UTF8_MB4"_sl_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 261, UTF8_MB4, UTF8_MB4"_pl_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 262, UTF8_MB4, UTF8_MB4"_et_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 263, UTF8_MB4, UTF8_MB4"_es_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 264, UTF8_MB4, UTF8_MB4"_sv_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 265, UTF8_MB4, UTF8_MB4"_tr_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 266, UTF8_MB4, UTF8_MB4"_cs_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 267, UTF8_MB4, UTF8_MB4"_da_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 268, UTF8_MB4, UTF8_MB4"_lt_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 269, UTF8_MB4, UTF8_MB4"_sk_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 270, UTF8_MB4, UTF8_MB4"_es_trad_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 271, UTF8_MB4, UTF8_MB4"_la_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 272, UTF8_MB4, UTF8_MB4"_fa_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 273, UTF8_MB4, UTF8_MB4"_eo_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 274, UTF8_MB4, UTF8_MB4"_hu_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 275, UTF8_MB4, UTF8_MB4"_hr_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 276, UTF8_MB4, UTF8_MB4"_si_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 277, UTF8_MB4, UTF8_MB4"_vi_0900_ai_ci", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 278, UTF8_MB4, UTF8_MB4"_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 279, UTF8_MB4, UTF8_MB4"_de_pb_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 280, UTF8_MB4, UTF8_MB4"_is_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 281, UTF8_MB4, UTF8_MB4"_lv_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 282, UTF8_MB4, UTF8_MB4"_ro_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 283, UTF8_MB4, UTF8_MB4"_sl_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 284, UTF8_MB4, UTF8_MB4"_pl_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 285, UTF8_MB4, UTF8_MB4"_et_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 286, UTF8_MB4, UTF8_MB4"_es_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 287, UTF8_MB4, UTF8_MB4"_sv_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 288, UTF8_MB4, UTF8_MB4"_tr_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 289, UTF8_MB4, UTF8_MB4"_cs_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 290, UTF8_MB4, UTF8_MB4"_da_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 291, UTF8_MB4, UTF8_MB4"_lt_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 292, UTF8_MB4, UTF8_MB4"_sk_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 293, UTF8_MB4, UTF8_MB4"_es_trad_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 294, UTF8_MB4, UTF8_MB4"_la_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 295, UTF8_MB4, UTF8_MB4"_fa_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 296, UTF8_MB4, UTF8_MB4"_eo_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 297, UTF8_MB4, UTF8_MB4"_hu_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 298, UTF8_MB4, UTF8_MB4"_hr_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 299, UTF8_MB4, UTF8_MB4"_si_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 300, UTF8_MB4, UTF8_MB4"_vi_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 303, UTF8_MB4, UTF8_MB4"_ja_0900_as_cs", 1, 4, mysqlnd_mbcharlen_utf8_id, check_mb_utf8_valid_id, LOWEST_MB_UTF8}, + { 0, NULL, NULL, 0, 0, mysqlnd_mbcharlen_null_id, check_null_id, 0x100} }; /* }}} */ @@ -969,40 +967,6 @@ PHPAPI zend_ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset /* }}} */ -static struct st_mysqlnd_plugin_charsets mysqlnd_plugin_charsets_plugin = -{ - { - MYSQLND_PLUGIN_API_VERSION, - "charsets", - MYSQLND_VERSION_ID, - PHP_MYSQLND_VERSION, - "PHP License 3.01", - "Andrey Hristov , Ulf Wendel , Georg Richter ", - { - NULL, /* no statistics , will be filled later if there are some */ - NULL, /* no statistics */ - }, - { - NULL /* plugin shutdown */ - } - }, - {/* methods */ - mysqlnd_find_charset_nr, - mysqlnd_find_charset_name, - mysqlnd_cset_escape_quotes, - mysqlnd_cset_escape_slashes - } -}; - - -/* {{{ mysqlnd_charsets_plugin_register */ -void -mysqlnd_charsets_plugin_register(void) -{ - mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_charsets_plugin); -} -/* }}} */ - #if MYSQLND_CHARSETS_SANITY_CHECK void mysqlnd_charsets_sanity_check(void) { diff --git a/ext/mysqlnd/mysqlnd_charset.h b/ext/mysqlnd/mysqlnd_charset.h index a2b1e2f14831..d5e621e38eb1 100644 --- a/ext/mysqlnd/mysqlnd_charset.h +++ b/ext/mysqlnd/mysqlnd_charset.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -28,18 +26,4 @@ PHPAPI zend_ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const chars PHPAPI zend_ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); -struct st_mysqlnd_plugin_charsets -{ - const struct st_mysqlnd_plugin_header plugin_header; - struct - { - const MYSQLND_CHARSET * (*const find_charset_by_nr)(unsigned int charsetnr); - const MYSQLND_CHARSET * (*const find_charset_by_name)(const char * const name); - zend_ulong (*const escape_quotes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); - zend_ulong (*const escape_slashes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); - } methods; -}; - -void mysqlnd_charsets_plugin_register(void); - #endif /* MYSQLND_CHARSET_H */ diff --git a/ext/mysqlnd/mysqlnd_commands.c b/ext/mysqlnd/mysqlnd_commands.c index 52731425e180..1bb38be089e6 100644 --- a/ext/mysqlnd/mysqlnd_commands.c +++ b/ext/mysqlnd/mysqlnd_commands.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -623,8 +621,7 @@ MYSQLND_METHOD(mysqlnd_command, handshake)(MYSQLND_CONN_DATA * const conn, const if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len, greet_packet.authentication_plugin_data, greet_packet.auth_protocol, - greet_packet.charset_no, greet_packet.server_capabilities, - conn->options, mysql_flags)) + greet_packet.charset_no, greet_packet.server_capabilities, mysql_flags)) { goto err; } diff --git a/ext/mysqlnd/mysqlnd_commands.h b/ext/mysqlnd/mysqlnd_commands.h index 4203b56ffc15..610de56325ae 100644 --- a/ext/mysqlnd/mysqlnd_commands.h +++ b/ext/mysqlnd/mysqlnd_commands.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index 42acb258665b..517b149c0b4d 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -508,6 +506,16 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn, } /* }}} */ +/* ipv6 addresses have at least two colons, which is how we can differentiate between domain names and addresses */ +static bool mysqlnd_fast_is_ipv6_address(const char *s) +{ + const char *first_colon = strchr(s, ':'); + if (!first_colon) { + return false; + } + return strchr(first_colon + 1, ':') != NULL; +} + /* {{{ mysqlnd_conn_data::get_scheme */ static MYSQLND_STRING MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_CSTRING hostname, MYSQLND_CSTRING *socket_or_pipe, unsigned int port, bool * unix_socket, bool * named_pipe) @@ -537,7 +545,31 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_scheme)(MYSQLND_CONN_DATA * conn, MYSQLND_ if (!port) { port = 3306; } - transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u", hostname.s, port); + + if (hostname.s[0] != '[' && mysqlnd_fast_is_ipv6_address(hostname.s)) { + /* IPv6 without square brackets so without port */ + transport.l = mnd_sprintf(&transport.s, 0, "tcp://[%s]:%u", hostname.s, port); + } else { + const char *p; + + /* IPv6 addresses are in the format [address]:port */ + if (hostname.s[0] == '[') { /* IPv6 */ + p = strchr(hostname.s, ']'); + if (p && p[1] != ':') { + p = NULL; + } + } else { /* IPv4 or name */ + p = strchr(hostname.s, ':'); + } + /* Could already contain a port number, in which case we should not add an extra port. + * See GH-8978. In a port doubling scenario, the first port would be used so we do the same to keep BC. */ + if (p) { + /* TODO: Ideally we should be able to get rid of this workaround in the future. */ + transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s", hostname.s); + } else { + transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u", hostname.s, port); + } + } } DBG_INF_FMT("transport=%s", transport.s? transport.s:"OOM"); DBG_RETURN(transport); @@ -1352,7 +1384,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn, /* XXX: passwords that have \0 inside work during auth, but in this case won't work with change user */ ret = mysqlnd_run_authentication(conn, user, passwd, passwd_len, db, strlen(db), conn->authentication_plugin_data, conn->options->auth_protocol, - 0 /*charset not used*/, conn->options, conn->server_capabilities, silent, TRUE/*is_change*/); + 0 /*charset not used*/, conn->server_capabilities, silent, TRUE/*is_change*/); /* Here we should close all statements. Unbuffered queries should not be a @@ -1525,17 +1557,14 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * cons zval attrz; zend_string *str; + str = zend_string_init(key, strlen(key), conn->persistent); + ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), conn->persistent)); if (conn->persistent) { - str = zend_string_init(key, strlen(key), 1); GC_MAKE_PERSISTENT_LOCAL(str); - ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), 1)); GC_MAKE_PERSISTENT_LOCAL(Z_COUNTED(attrz)); - } else { - str = zend_string_init(key, strlen(key), 0); - ZVAL_NEW_STR(&attrz, zend_string_init(value, strlen(value), 0)); } zend_hash_update(conn->options->connect_attr, str, &attrz); - zend_string_release_ex(str, 1); + zend_string_release_ex(str, conn->persistent); } break; default: diff --git a/ext/mysqlnd/mysqlnd_connection.h b/ext/mysqlnd/mysqlnd_connection.h index 39d7712b132c..ef71fbd4250c 100644 --- a/ext/mysqlnd/mysqlnd_connection.h +++ b/ext/mysqlnd/mysqlnd_connection.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index ff80c620bee1..80765f36131c 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -742,7 +740,7 @@ static struct st_mysqlnd_plugin_trace_log mysqlnd_plugin_trace_log_plugin = "debug_trace", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* no statistics , will be filled later if there are some */ diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h index 24eb67ca1a74..3710551bffd4 100644 --- a/ext/mysqlnd/mysqlnd_debug.h +++ b/ext/mysqlnd/mysqlnd_debug.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c index 2c1d997177aa..deef03b9a3c1 100644 --- a/ext/mysqlnd/mysqlnd_driver.c +++ b/ext/mysqlnd/mysqlnd_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -38,7 +36,7 @@ static struct st_mysqlnd_plugin_core mysqlnd_plugin_core = "mysqlnd", MYSQLND_VERSION_ID, PHP_MYSQLND_VERSION, - "PHP License 3.01", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov , Ulf Wendel , Georg Richter ", { NULL, /* will be filled later */ diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 851174032c40..abb5def974c8 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.c b/ext/mysqlnd/mysqlnd_ext_plugin.c index 2ca01d113e3b..5ba377e53433 100644 --- a/ext/mysqlnd/mysqlnd_ext_plugin.c +++ b/ext/mysqlnd/mysqlnd_ext_plugin.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.h b/ext/mysqlnd/mysqlnd_ext_plugin.h index 8780ff463045..84cf6c004be4 100644 --- a/ext/mysqlnd/mysqlnd_ext_plugin.h +++ b/ext/mysqlnd/mysqlnd_ext_plugin.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_libmysql_compat.h b/ext/mysqlnd/mysqlnd_libmysql_compat.h index 646b09d80f4c..0172b554caa0 100644 --- a/ext/mysqlnd/mysqlnd_libmysql_compat.h +++ b/ext/mysqlnd/mysqlnd_libmysql_compat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_loaddata.c b/ext/mysqlnd/mysqlnd_loaddata.c index ba2dabf95a2c..caa5205a08e1 100644 --- a/ext/mysqlnd/mysqlnd_loaddata.c +++ b/ext/mysqlnd/mysqlnd_loaddata.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -167,7 +165,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * const filenam SET_CLIENT_ERROR(conn->error_info, CR_LOAD_DATA_LOCAL_INFILE_REJECTED, UNKNOWN_SQLSTATE, "LOAD DATA LOCAL INFILE is forbidden, check related settings like " "mysqli.allow_local_infile|mysqli.local_infile_directory or " - "PDO::MYSQL_ATTR_LOCAL_INFILE|PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY"); + "Pdo\\Mysql::ATTR_LOCAL_INFILE|Pdo\\Mysql::ATTR_LOCAL_INFILE_DIRECTORY"); prerequisities_ok = FALSE; } diff --git a/ext/mysqlnd/mysqlnd_plugin.c b/ext/mysqlnd/mysqlnd_plugin.c index 4bd9894b8c4b..4209676daf10 100644 --- a/ext/mysqlnd/mysqlnd_plugin.c +++ b/ext/mysqlnd/mysqlnd_plugin.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -47,7 +45,7 @@ static struct st_mysqlnd_typeii_plugin_example mysqlnd_example_plugin = "example", 10001L, "1.00.01", - "PHP License", + "Modified BSD License (BSD-3-Clause)", "Andrey Hristov ", { NULL, /* will be filled later */ diff --git a/ext/mysqlnd/mysqlnd_plugin.h b/ext/mysqlnd/mysqlnd_plugin.h index 82b2142fc9fc..04dfcb79cc40 100644 --- a/ext/mysqlnd/mysqlnd_plugin.h +++ b/ext/mysqlnd/mysqlnd_plugin.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_portability.h b/ext/mysqlnd/mysqlnd_portability.h index 11ebf4d1bf8a..20dfe3429edf 100644 --- a/ext/mysqlnd/mysqlnd_portability.h +++ b/ext/mysqlnd/mysqlnd_portability.h @@ -284,15 +284,8 @@ typedef union { register) variable, M is a pointer to byte */ #ifndef float8get - -#ifdef WORDS_BIGENDIAN -#define float8get(V,M) memcpy((char*) &(V),(char*) (M), sizeof(double)) -#define float8store(T,V) memcpy((char*) (T),(char*) &(V), sizeof(double)) -#else -#define float8get(V,M) memcpy((char*) &(V),(char*) (M),sizeof(double)) -#define float8store(T,V) memcpy((char*) (T),(char*) &(V),sizeof(double)) -#endif /* WORDS_BIGENDIAN */ - -#endif /* float8get */ +# define float8get(V,M) memcpy((char*) &(V),(char*) (M),sizeof(double)) +# define float8store(T,V) memcpy((char*) (T),(char*) &(V),sizeof(double)) +#endif #endif /* MYSQLND_PORTABILITY_H */ diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index 1dbd1093dcac..daad00f0d3e6 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c index 570fba24d663..70a81befdd71 100644 --- a/ext/mysqlnd/mysqlnd_protocol_frame_codec.c +++ b/ext/mysqlnd/mysqlnd_protocol_frame_codec.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_protocol_frame_codec.h b/ext/mysqlnd/mysqlnd_protocol_frame_codec.h index 63aedddb12ea..1ed6f233365b 100644 --- a/ext/mysqlnd/mysqlnd_protocol_frame_codec.h +++ b/ext/mysqlnd/mysqlnd_protocol_frame_codec.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 5fad5281947e..b9b112161570 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -58,7 +56,7 @@ static bool mysqlnd_stmt_check_state(const MYSQLND_STMT_DATA *stmt) { const MYSQLND_CONN_DATA *conn = stmt->conn; if (stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE) { - return 0; + return false; } if (stmt->cursor_exists) { return GET_CONNECTION_STATE(&conn->state) == CONN_READY; diff --git a/ext/mysqlnd/mysqlnd_ps.h b/ext/mysqlnd/mysqlnd_ps.h index 107e7b6748b9..32af2d423e52 100644 --- a/ext/mysqlnd/mysqlnd_ps.h +++ b/ext/mysqlnd/mysqlnd_ps.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index a2e98cf358bb..934e3637d6aa 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -317,7 +315,7 @@ ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, const unsigned int p const zend_uchar * to = *row; t.time_type = MYSQLND_TIMESTAMP_DATE; - t.neg = 0; + t.neg = false; t.second_part = t.hour = t.minute = t.second = 0; @@ -354,7 +352,7 @@ ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, const unsigned i const zend_uchar * to = *row; t.time_type = MYSQLND_TIMESTAMP_DATETIME; - t.neg = 0; + t.neg = false; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; diff --git a/ext/mysqlnd/mysqlnd_read_buffer.c b/ext/mysqlnd/mysqlnd_read_buffer.c index 90963c99fa81..e662733e0a36 100644 --- a/ext/mysqlnd/mysqlnd_read_buffer.c +++ b/ext/mysqlnd/mysqlnd_read_buffer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_read_buffer.h b/ext/mysqlnd/mysqlnd_read_buffer.h index 7014f4369690..b3d4c9638303 100644 --- a/ext/mysqlnd/mysqlnd_read_buffer.h +++ b/ext/mysqlnd/mysqlnd_read_buffer.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index ae8dc77b4cd9..b4d0bdbd8d2c 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -722,9 +720,6 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c if (ret == FAIL) { COPY_CLIENT_ERROR(&set->error_info, row_packet.error_info); - } else { - /* libmysql's documentation says it should be so for SELECT statements */ - UPSERT_STATUS_SET_AFFECTED_ROWS(conn->upsert_status, set->row_count); } DBG_INF_FMT("ret=%s row_count=%u warnings=%u server_status=%u", ret == PASS? "PASS":"FAIL", @@ -1004,18 +999,11 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const unsigned int } } if (flags & MYSQLND_FETCH_ASSOC) { - /* zend_hash_quick_update needs length + trailing zero */ - /* QQ: Error handling ? */ - /* - zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether - the index is a numeric and convert it to it. This however means constant - hashing of the column name, which is not needed as it can be precomputed. - */ Z_TRY_ADDREF_P(data); - if (meta->fields[i].is_numeric == FALSE) { - zend_hash_update(row_ht, meta->fields[i].sname, data); + if (field->is_numeric == FALSE) { + zend_hash_update(row_ht, field->sname, data); } else { - zend_hash_index_update(row_ht, meta->fields[i].num_key, data); + zend_hash_index_update(row_ht, field->num_key, data); } } @@ -1038,10 +1026,9 @@ MYSQLND_METHOD(mysqlnd_res, fetch_row_c)(MYSQLND_RES * result) mysqlnd_result_free_prev_data(result); if (result->m.fetch_row(result, &row_data, 0, &fetched_anything) == PASS && fetched_anything) { unsigned field_count = result->field_count; - MYSQLND_FIELD *field = result->meta->fields; ret = mnd_emalloc(field_count * sizeof(char *)); - for (unsigned i = 0; i < field_count; i++, field++) { + for (unsigned i = 0; i < field_count; i++) { zval *data = &row_data[i]; if (Z_TYPE_P(data) != IS_NULL) { convert_to_string(data); diff --git a/ext/mysqlnd/mysqlnd_result.h b/ext/mysqlnd/mysqlnd_result.h index fe414f0cd65c..db90b4d963cc 100644 --- a/ext/mysqlnd/mysqlnd_result.h +++ b/ext/mysqlnd/mysqlnd_result.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c index 92896ccb408e..6a772973c395 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.c +++ b/ext/mysqlnd/mysqlnd_result_meta.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_result_meta.h b/ext/mysqlnd/mysqlnd_result_meta.h index e9726abae02a..d3c84776958a 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.h +++ b/ext/mysqlnd/mysqlnd_result_meta.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_reverse_api.c b/ext/mysqlnd/mysqlnd_reverse_api.c index 982aac065eb0..539c8adaaa60 100644 --- a/ext/mysqlnd/mysqlnd_reverse_api.c +++ b/ext/mysqlnd/mysqlnd_reverse_api.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Johannes Schlüter | diff --git a/ext/mysqlnd/mysqlnd_reverse_api.h b/ext/mysqlnd/mysqlnd_reverse_api.h index ee56666d5eaf..843fa728aacc 100644 --- a/ext/mysqlnd/mysqlnd_reverse_api.h +++ b/ext/mysqlnd/mysqlnd_reverse_api.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c index 0d94303ea366..33a47843c9c8 100644 --- a/ext/mysqlnd/mysqlnd_statistics.c +++ b/ext/mysqlnd/mysqlnd_statistics.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_statistics.h b/ext/mysqlnd/mysqlnd_statistics.h index 02cd64450cb6..a576f67ffdb1 100644 --- a/ext/mysqlnd/mysqlnd_statistics.h +++ b/ext/mysqlnd/mysqlnd_statistics.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index 9cbbf4a64f14..80d0abfcae6f 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -182,7 +180,6 @@ typedef struct st_mysqlnd_charset const char *collation; unsigned int char_minlen; unsigned int char_maxlen; - const char *comment; short mb_charlen; short mb_valid; unsigned int lowest_mb_byte; @@ -1323,7 +1320,6 @@ typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authen size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, - const MYSQLND_SESSION_OPTIONS * const session_options, const MYSQLND_PFC_DATA * const pfc_data, const zend_ulong mysql_flags ); diff --git a/ext/mysqlnd/mysqlnd_vio.c b/ext/mysqlnd/mysqlnd_vio.c index 67210f083a96..b6ea490e67b6 100644 --- a/ext/mysqlnd/mysqlnd_vio.c +++ b/ext/mysqlnd/mysqlnd_vio.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -26,7 +24,7 @@ #ifndef PHP_WIN32 #include #else -#include +#include #endif diff --git a/ext/mysqlnd/mysqlnd_vio.h b/ext/mysqlnd/mysqlnd_vio.h index a96fdb182b17..28f033bd749d 100644 --- a/ext/mysqlnd/mysqlnd_vio.h +++ b/ext/mysqlnd/mysqlnd_vio.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 36fd53233737..b957240a4088 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | @@ -461,7 +459,7 @@ php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet) packet->auth_protocol = estrdup(""); } else { /* Check if NUL present */ - char *null_terminator = memchr(p, '\0', remaining_size); + const char *null_terminator = memchr(p, '\0', remaining_size); size_t auth_protocol_len; if (null_terminator) { /* If present, do basically estrdup */ diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h index f24eb70f4a79..e5d38bc6737e 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/php_mysqlnd.c b/ext/mysqlnd/php_mysqlnd.c index c21697828a9a..f8b2d72ebab9 100644 --- a/ext/mysqlnd/php_mysqlnd.c +++ b/ext/mysqlnd/php_mysqlnd.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/mysqlnd/php_mysqlnd.h b/ext/mysqlnd/php_mysqlnd.h index e7a981a5de3e..4da59ed965e8 100644 --- a/ext/mysqlnd/php_mysqlnd.h +++ b/ext/mysqlnd/php_mysqlnd.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andrey Hristov | | Ulf Wendel | diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4 index 9baa8dbd8e64..645a4d52902e 100644 --- a/ext/odbc/config.m4 +++ b/ext/odbc/config.m4 @@ -7,179 +7,10 @@ AC_DEFUN([PHP_ODBC_CHECK_HEADER], [AS_IF([test ! -f "$ODBC_INCDIR/$1"], [AC_MSG_ERROR([ODBC header file '$ODBC_INCDIR/$1' not found!])])]) -dnl -dnl PHP_ODBC_FIND_SOLID_LIBS(libdir) -dnl -dnl Figure out which library file to link with for the Solid support. -dnl -AC_DEFUN([PHP_ODBC_FIND_SOLID_LIBS],[ - AC_MSG_CHECKING([Solid library file]) - ac_solid_uname_r=$(uname -r 2>/dev/null) - ac_solid_uname_s=$(uname -s 2>/dev/null) - case $ac_solid_uname_s in - AIX) ac_solid_os=a3x;; # a4x for AIX4/ Solid 2.3/3.0 only - HP-UX) ac_solid_os=h9x;; # h1x for hpux11, h0x for hpux10 - Linux) - if ldd -v /bin/sh | grep GLIBC > /dev/null; then - ac_solid_os=l2x - else - ac_solid_os=lux - fi - AC_DEFINE([SS_LINUX], [1], - [Define to 1 to be able to use the obsolete header file on - some Linux systems.]) - ;; - SunOS) - ac_solid_os=ssx;; # should we deal with SunOS 4? - FreeBSD) - if test $(expr $ac_solid_uname_r : '\(.\)') -gt "2"; then - ac_solid_os=fex - else - ac_solid_os=fbx - fi - AC_DEFINE([SS_FBX], [1], - [Define to 1 to be able to use the wchar defs in the obsolete - header file on some FreeBSD systems.]) - ;; - esac - - if test -f $1/soc${ac_solid_os}35.a; then - ac_solid_version=35 - ac_solid_prefix=soc - elif test -f $1/scl${ac_solid_os}30.a; then - ac_solid_version=30 - ac_solid_prefix=scl - elif test -f $1/scl${ac_solid_os}23.a; then - ac_solid_version=23 - ac_solid_prefix=scl - fi - -dnl Check for the library files, and setup the ODBC_LIBS path. -if test ! -f $1/lib${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.so && \ - test ! -f $1/lib${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.a; then - dnl we have an error and should bail out, as we can't find the libs! - echo "" - echo "*********************************************************************" - echo "* Unable to locate $1/lib${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.so or $1/lib${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.a" - echo "* Please correct this by creating the following links and reconfiguring:" - echo "* $1/lib${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.a -> $1/lib${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.a" - echo "* $1/${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.so -> $1/lib${ac_solid_prefix}${ac_solid_os}${ac_solid_version}.so" - echo "*********************************************************************" -else - ODBC_LFLAGS=-L$1 - ODBC_LIBS=-l${ac_solid_prefix}${ac_solid_os}${ac_solid_version} -fi - - AC_MSG_RESULT([$(echo $ODBC_LIBS | $SED -e 's!.*/!!')]) -]) - -dnl -dnl PHP_ODBC_FIND_EMPRESS_LIBS(libdir) -dnl -dnl Figure out which library file to link with for the Empress support. -dnl -AC_DEFUN([PHP_ODBC_FIND_EMPRESS_LIBS],[ - AC_MSG_CHECKING([Empress library file]) - ODBC_LIBS=$(echo $1/libempodbccl.so | cut -d' ' -f1) - if test ! -f $ODBC_LIBS; then - ODBC_LIBS=$(echo $1/libempodbccl.so | cut -d' ' -f1) - fi - AC_MSG_RESULT([$(echo $ODBC_LIBS | $SED -e 's!.*/!!')]) -]) - -dnl -dnl PHP_ODBC_FIND_EMPRESS_BCS_LIBS(libdir) -dnl -dnl Figure out which library file to link with for the Empress local access -dnl support. -dnl -AC_DEFUN([PHP_ODBC_FIND_EMPRESS_BCS_LIBS],[ - AC_MSG_CHECKING([Empress local access library file]) - ODBCBCS_LIBS=$(echo $1/libempodbcbcs.a | cut -d' ' -f1) - if test ! -f $ODBCBCS_LIBS; then - ODBCBCS_LIBS=$(echo $1/libempodbcbcs.a | cut -d' ' -f1) - fi - AC_MSG_RESULT([$(echo $ODBCBCS_LIBS | $SED -e 's!.*/!!')]) -]) - dnl dnl configure options dnl -PHP_ARG_WITH([odbcver],, - [AS_HELP_STRING([[--with-odbcver[=HEX]]], - [Force support for the passed ODBC version. A hex number is expected, - default 0x0350. Use the special value of 0 to prevent an explicit ODBCVER to - be defined.])], - [0x0350]) - -AS_VAR_IF([ODBC_TYPE],, [ -PHP_ARG_WITH([adabas], - [for Adabas support], - [AS_HELP_STRING([[--with-adabas[=DIR]]], - [Include Adabas D support [/usr/local]])]) - - AS_VAR_IF([PHP_ADABAS], [no], [], [ - AS_VAR_IF([PHP_ADABAS], [yes], [PHP_ADABAS=/usr/local]) - PHP_ADD_INCLUDE([$PHP_ADABAS/incl]) - PHP_ADD_LIBPATH([$PHP_ADABAS/$PHP_LIBDIR]) - ODBC_OBJS="$PHP_ADABAS/$PHP_LIBDIR/odbclib.a" - ODBC_LIB="$abs_builddir/ext/odbc/libodbc_adabas.a" - $srcdir/build/shtool mkdir -f -p ext/odbc - rm -f "$ODBC_LIB" - cp "$ODBC_OBJS" "$ODBC_LIB" - PHP_ADD_LIBRARY([sqlptc]) - PHP_ADD_LIBRARY([sqlrte]) - PHP_ADD_LIBRARY_WITH_PATH([odbc_adabas], [$abs_builddir/ext/odbc]) - ODBC_TYPE=adabas - ODBC_INCDIR=$PHP_ADABAS/incl - PHP_ODBC_CHECK_HEADER([sqlext.h]) - AC_DEFINE([HAVE_ADABAS], [1], - [Define to 1 if the odbc extension uses the Adabas D.]) - ]) -]) - -AS_VAR_IF([ODBC_TYPE],, [ -PHP_ARG_WITH([sapdb], - [for SAP DB support], - [AS_HELP_STRING([[--with-sapdb[=DIR]]], - [Include SAP DB support [/usr/local]])]) - - AS_VAR_IF([PHP_SAPDB], [no], [], [ - AS_VAR_IF([PHP_SAPDB], [yes], [PHP_SAPDB=/usr/local]) - PHP_ADD_INCLUDE([$PHP_SAPDB/incl]) - PHP_ADD_LIBPATH([$PHP_SAPDB/$PHP_LIBDIR]) - PHP_ADD_LIBRARY([sqlod]) - ODBC_TYPE=sapdb - AC_DEFINE([HAVE_SAPDB], [1], - [Define to 1 if the odbc extension uses the SAP DB.]) - ]) -]) - -AS_VAR_IF([ODBC_TYPE],, [ -PHP_ARG_WITH([solid], - [for Solid support], - [AS_HELP_STRING([[--with-solid[=DIR]]], - [Include Solid support [/usr/local/solid]])]) - - AS_VAR_IF([PHP_SOLID], [no], [], [ - AS_VAR_IF([PHP_SOLID], [yes], [PHP_SOLID=/usr/local/solid]) - ODBC_INCDIR=$PHP_SOLID/include - ODBC_LIBDIR=$PHP_SOLID/$PHP_LIBDIR - ODBC_CFLAGS=-I$ODBC_INCDIR - ODBC_TYPE=solid - if test -f $ODBC_LIBDIR/soc*35.a; then - AC_DEFINE([HAVE_SOLID_35], [1], [Define to 1 if Solid DB 3.5 is used.]) - elif test -f $ODBC_LIBDIR/scl*30.a; then - AC_DEFINE([HAVE_SOLID_30], [1], [Define to 1 if Solid DB 3.0 is used.]) - elif test -f $ODBC_LIBDIR/scl*23.a; then - AC_DEFINE([HAVE_SOLID], [1], - [Define to 1 if the odbc extension uses the Solid DB.]) - fi - PHP_ODBC_FIND_SOLID_LIBS([$ODBC_LIBDIR]) - ]) -]) - AS_VAR_IF([ODBC_TYPE],, [ PHP_ARG_WITH([ibm-db2], [for IBM DB2 support], @@ -217,70 +48,6 @@ PHP configure: ]) ]) -AS_VAR_IF([ODBC_TYPE],, [ -PHP_ARG_WITH([empress], - [for Empress support], - [AS_HELP_STRING([[--with-empress[=DIR]]], - [Include Empress support $EMPRESSPATH (Empress Version >= 8.60 - required)])]) - - AS_VAR_IF([PHP_EMPRESS], [no], [], [ - AS_VAR_IF([PHP_EMPRESS], [yes], [ - ODBC_INCDIR=$EMPRESSPATH/include/odbc - ODBC_LIBDIR=$EMPRESSPATH/shlib - ], [ - ODBC_INCDIR=$PHP_EMPRESS/include/odbc - ODBC_LIBDIR=$PHP_EMPRESS/shlib - ]) - ODBC_CFLAGS=-I$ODBC_INCDIR - ODBC_LFLAGS=-L$ODBC_LIBDIR - ODBC_TYPE=empress - AC_DEFINE([HAVE_EMPRESS], [1], - [Define to 1 if the odbc extension uses the Empress.]) - PHP_ODBC_FIND_EMPRESS_LIBS([$ODBC_LIBDIR]) - ]) -]) - -AS_VAR_IF([ODBC_TYPE],, [ -PHP_ARG_WITH([empress-bcs], - [for Empress local access support], - [AS_HELP_STRING([[--with-empress-bcs[=DIR]]], - [Include Empress Local Access support $EMPRESSPATH (Empress Version >= - 8.60 required)])]) - - AS_VAR_IF([PHP_EMPRESS_BCS], [no], [], [ - AS_VAR_IF([PHP_EMPRESS_BCS], [yes], [ - ODBC_INCDIR=$EMPRESSPATH/include/odbc - ODBC_LIBDIR=$EMPRESSPATH/shlib - ], [ - ODBC_INCDIR=$PHP_EMPRESS_BCS/include/odbc - ODBC_LIBDIR=$PHP_EMPRESS_BCS/shlib - ]) - CC="empocc -bcs";export CC; - LD="empocc -bcs";export LD; - ODBC_CFLAGS=-I$ODBC_INCDIR - ODBC_LFLAGS=-L$ODBC_LIBDIR - LIST=$(empocc -listlines -bcs -o a a.c) - - NEWLIST= - for I in $LIST - do - case $I in - $EMPRESSPATH/odbccl/lib/* | \ - $EMPRESSPATH/rdbms/lib/* | \ - $EMPRESSPATH/common/lib/*) - NEWLIST="$NEWLIST $I" - ;; - esac - done - ODBC_LIBS="-lempphpbcs -lms -lmscfg -lbasic -lbasic_os -lnlscstab -lnlsmsgtab -lm -ldl -lcrypt" - ODBC_TYPE=empress-bcs - AC_DEFINE([HAVE_EMPRESS], [1], - [Define to 1 if the odbc extension uses the Empress.]) - PHP_ODBC_FIND_EMPRESS_BCS_LIBS([$ODBC_LIBDIR]) - ]) -]) - AS_VAR_IF([ODBC_TYPE],, [ PHP_ARG_WITH([custom-odbc], [for a custom ODBC support], @@ -320,25 +87,6 @@ PHP_ARG_WITH([iodbc], ]) ]) -AS_VAR_IF([ODBC_TYPE],, [ -PHP_ARG_WITH([esoob], - [for Easysoft ODBC-ODBC Bridge support], - [AS_HELP_STRING([[--with-esoob[=DIR]]], - [Include Easysoft OOB support [/usr/local/easysoft/oob/client]])]) - - AS_VAR_IF([PHP_ESOOB], [no], [], [ - AS_VAR_IF([PHP_ESOOB], [yes], [PHP_ESOOB=/usr/local/easysoft/oob/client]) - ODBC_INCDIR=$PHP_ESOOB/include - ODBC_LIBDIR=$PHP_ESOOB/$PHP_LIBDIR - ODBC_LFLAGS=-L$ODBC_LIBDIR - ODBC_CFLAGS=-I$ODBC_INCDIR - ODBC_LIBS=-lesoobclient - ODBC_TYPE=esoob - AC_DEFINE([HAVE_ESOOB], [1], - [Define to 1 if the odbc extension uses the Easysoft OOB.]) - ]) -]) - AS_VAR_IF([ODBC_TYPE],, [ PHP_ARG_WITH([unixODBC], [whether to build with unixODBC support], @@ -367,64 +115,10 @@ PHP_ARG_WITH([unixODBC], ]) ]) -AS_VAR_IF([ODBC_TYPE],, [ -PHP_ARG_WITH([dbmaker], - [for DBMaker support], - [AS_HELP_STRING([[--with-dbmaker[=DIR]]], - [Include DBMaker support])]) - - AS_VAR_IF([PHP_DBMAKER], [no], [], [ - AS_VAR_IF([PHP_DBMAKER], [yes], [ - dnl Find dbmaker home directory - DBMAKER_HOME=$(grep "^dbmaker:" /etc/passwd | $AWK -F: '{print $6}') - - dnl check DBMaker version (from 5.0 to 2.0) - DBMAKER_VERSION=5.0 - - while test ! -d $DBMAKER_HOME/$DBMAKER_VERSION && test "$DBMAKER_VERSION" != "2.9"; do - DM_VER=$(echo $DBMAKER_VERSION | $SED -e 's/\.//' | $AWK '{ print $1-1;}') - MAJOR_V=$(echo $DM_VER | $AWK '{ print $1/10; }' | $AWK -F. '{ print $1; }') - MINOR_V=$(echo $DM_VER | $AWK '{ print $1%10; }') - DBMAKER_VERSION=$MAJOR_V.$MINOR_V - done - - AS_VAR_IF([DBMAKER_VERSION], [2.9], - [PHP_DBMAKER=$DBMAKER_HOME], - [PHP_DBMAKER=$DBMAKER_HOME/$DBMAKER_VERSION]) - ]) - - ODBC_INCDIR=$PHP_DBMAKER/include - ODBC_LIBDIR=$PHP_DBMAKER/$PHP_LIBDIR - ODBC_CFLAGS=-I$ODBC_INCDIR - ODBC_LFLAGS=-L$ODBC_LIBDIR - ODBC_LIBS="-ldmapic -lc" - ODBC_TYPE=dbmaker - - AC_DEFINE([HAVE_DBMAKER], [1], - [Define to 1 if the odbc extension uses the DBMaker.]) - - AS_VAR_IF([ext_shared], [yes], [ODBC_LIBS="-ldmapic -lc -lm"], [ - PHP_ADD_LIBRARY_WITH_PATH([dmapic], [$ODBC_LIBDIR]) - PHP_ADD_INCLUDE([$ODBC_INCDIR]) - ]) - ]) -]) - -AH_TEMPLATE([ODBCVER], [The highest supported ODBC version.]) -AS_VAR_IF([PHP_ODBCVER], [no], - [AC_DEFINE([ODBCVER], [0x0350])], - [AS_VAR_IF([PHP_ODBCVER], [0],, - [AC_DEFINE_UNQUOTED([ODBCVER], [$PHP_ODBCVER])])]) dnl Extension setup if test -n "$ODBC_TYPE"; then - AS_VAR_IF([ODBC_TYPE], [dbmaker],, [ - PHP_EVAL_LIBLINE([$ODBC_LFLAGS $ODBC_LIBS], [ODBC_SHARED_LIBADD]) - AS_VAR_IF([ODBC_TYPE], [solid],, - [AC_DEFINE([HAVE_SQLDATASOURCES], [1], - [Define to 1 if ODBC library has 'SQLDataSources', as a function or - macro.])]) - ]) + PHP_EVAL_LIBLINE([$ODBC_LFLAGS $ODBC_LIBS], [ODBC_SHARED_LIBADD]) AC_DEFINE([HAVE_UODBC], [1], [Define to 1 if the PHP extension 'odbc' is available.]) diff --git a/ext/odbc/config.w32 b/ext/odbc/config.w32 index 1030db44465b..242cc5992d46 100644 --- a/ext/odbc/config.w32 +++ b/ext/odbc/config.w32 @@ -1,20 +1,13 @@ // vim:ft=javascript ARG_ENABLE("odbc", "ODBC support", "no"); -ARG_WITH("odbcver", "Force support for the passed ODBC version. A hex number is expected, default 0x0350. Use the special value of 0 to prevent an explicit ODBCVER to be defined.", "0x0350"); if (PHP_ODBC == "yes") { if (CHECK_LIB("odbc32.lib", "odbc") && CHECK_LIB("odbccp32.lib", "odbc") - && CHECK_HEADER_ADD_INCLUDE("sql.h", "CFLAGS_ODBC") - && CHECK_HEADER_ADD_INCLUDE("sqlext.h", "CFLAGS_ODBC")) { + && CHECK_HEADER("sql.h", "CFLAGS_ODBC") + && CHECK_HEADER("sqlext.h", "CFLAGS_ODBC")) { EXTENSION("odbc", "php_odbc.c odbc_utils.c", PHP_ODBC_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_UODBC", 1, "Define to 1 if the PHP extension 'odbc' is available."); - AC_DEFINE("HAVE_SQLDATASOURCES", 1, "Define to 1 if ODBC library has 'SQLDataSources', as a function or macro."); - if ("no" == PHP_ODBCVER) { - AC_DEFINE("ODBCVER", "0x0350", "The highest supported ODBC version.", false); - } else if ("0" != PHP_ODBCVER) { - AC_DEFINE("ODBCVER", PHP_ODBCVER, "The highest supported ODBC version.", false); - } } else { WARNING("odbc support can't be enabled, libraries or header are missing (SDK)") PHP_ODBC = "no" diff --git a/ext/odbc/odbc.stub.php b/ext/odbc/odbc.stub.php index 8a54e913e88e..f88a71154f8f 100644 --- a/ext/odbc/odbc.stub.php +++ b/ext/odbc/odbc.stub.php @@ -233,8 +233,6 @@ class Result * @cvalue SQL_TIMESTAMP */ const SQL_TIMESTAMP = UNKNOWN; - -#if (defined(ODBCVER) && (ODBCVER >= 0x0300)) /** * @var int * @cvalue SQL_TYPE_DATE @@ -327,8 +325,6 @@ class Result */ const SQL_QUICK = UNKNOWN; -#endif - function odbc_close_all(): void {} function odbc_binmode(Odbc\Result $statement, int $mode): true {} @@ -341,20 +337,16 @@ function odbc_execute(Odbc\Result $statement, array $params = []): bool {} function odbc_cursor(Odbc\Result $statement): string|false {} -#ifdef HAVE_SQLDATASOURCES function odbc_data_source(Odbc\Connection $odbc, int $fetch_type): array|null|false {} -#endif function odbc_exec(Odbc\Connection $odbc, string $query): Odbc\Result|false {} /** @alias odbc_exec */ function odbc_do(Odbc\Connection $odbc, string $query): Odbc\Result|false {} -#ifdef PHP_ODBC_HAVE_FETCH_HASH function odbc_fetch_object(Odbc\Result $statement, ?int $row = null): stdClass|false {} function odbc_fetch_array(Odbc\Result $statement, ?int $row = null): array|false {} -#endif /** * @param array $array @@ -378,9 +370,7 @@ function odbc_close(Odbc\Connection $odbc): void {} function odbc_num_rows(Odbc\Result $statement): int {} -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) function odbc_next_result(Odbc\Result $statement): bool {} -#endif function odbc_num_fields(Odbc\Result $statement): int {} @@ -417,23 +407,19 @@ function odbc_gettypeinfo(Odbc\Connection $odbc, int $data_type = 0): Odbc\Resul function odbc_primarykeys(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table): Odbc\Result|false {} -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) function odbc_procedurecolumns(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null, ?string $column = null): Odbc\Result|false {} function odbc_procedures(Odbc\Connection $odbc, ?string $catalog = null, ?string $schema = null, ?string $procedure = null): Odbc\Result|false {} function odbc_foreignkeys(Odbc\Connection $odbc, ?string $pk_catalog, string $pk_schema, string $pk_table, string $fk_catalog, string $fk_schema, string $fk_table): Odbc\Result|false {} -#endif function odbc_specialcolumns(Odbc\Connection $odbc, int $type, ?string $catalog, string $schema, string $table, int $scope, int $nullable): Odbc\Result|false {} function odbc_statistics(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table, int $unique, int $accuracy): Odbc\Result|false {} -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) function odbc_tableprivileges(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table): Odbc\Result|false {} function odbc_columnprivileges(Odbc\Connection $odbc, ?string $catalog, string $schema, string $table, string $column): Odbc\Result|false {} -#endif /* odbc_utils.c */ diff --git a/ext/odbc/odbc_arginfo.h b/ext/odbc/odbc_arginfo.h index d458fee43383..badd1400148d 100644 --- a/ext/odbc/odbc_arginfo.h +++ b/ext/odbc/odbc_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: efd913e4fcacb2949dc5392857032ab9c59c818d */ +/* This is a generated file, edit odbc.stub.php instead. + * Stub hash: f9ba28767b256dbcea087a65aa4bb5f5b509d6f3 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_close_all, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() @@ -28,18 +28,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_cursor, 0, 1, MAY_BE_STRING ZEND_ARG_OBJ_INFO(0, statement, Odbc\\Result, 0) ZEND_END_ARG_INFO() -#if defined(HAVE_SQLDATASOURCES) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_data_source, 0, 2, MAY_BE_ARRAY|MAY_BE_NULL|MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, odbc, Odbc\\Connection, 0) ZEND_ARG_TYPE_INFO(0, fetch_type, IS_LONG, 0) ZEND_END_ARG_INFO() -#endif #define arginfo_odbc_exec arginfo_odbc_prepare #define arginfo_odbc_do arginfo_odbc_prepare -#if defined(PHP_ODBC_HAVE_FETCH_HASH) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_fetch_object, 0, 1, stdClass, MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, statement, Odbc\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") @@ -49,7 +46,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_fetch_array, 0, 1, MAY_BE_A ZEND_ARG_OBJ_INFO(0, statement, Odbc\\Result, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, row, IS_LONG, 1, "null") ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_fetch_into, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, statement, Odbc\\Result, 0) @@ -93,11 +89,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_num_rows, 0, 1, IS_LONG, 0) ZEND_ARG_OBJ_INFO(0, statement, Odbc\\Result, 0) ZEND_END_ARG_INFO() -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_next_result, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, statement, Odbc\\Result, 0) ZEND_END_ARG_INFO() -#endif #define arginfo_odbc_num_fields arginfo_odbc_num_rows @@ -174,7 +168,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_primarykeys, 0, 4, Odbc ZEND_ARG_TYPE_INFO(0, table, IS_STRING, 0) ZEND_END_ARG_INFO() -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_procedurecolumns, 0, 1, Odbc\\Result, MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, odbc, Odbc\\Connection, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, catalog, IS_STRING, 1, "null") @@ -199,7 +192,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_foreignkeys, 0, 7, Odbc ZEND_ARG_TYPE_INFO(0, fk_schema, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, fk_table, IS_STRING, 0) ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_specialcolumns, 0, 7, Odbc\\Result, MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, odbc, Odbc\\Connection, 0) @@ -220,13 +212,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_statistics, 0, 6, Odbc\ ZEND_ARG_TYPE_INFO(0, accuracy, IS_LONG, 0) ZEND_END_ARG_INFO() -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) -ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_tableprivileges, 0, 4, Odbc\\Result, MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, odbc, Odbc\\Connection, 0) - ZEND_ARG_TYPE_INFO(0, catalog, IS_STRING, 1) - ZEND_ARG_TYPE_INFO(0, schema, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, table, IS_STRING, 0) -ZEND_END_ARG_INFO() +#define arginfo_odbc_tableprivileges arginfo_odbc_primarykeys ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_columnprivileges, 0, 5, Odbc\\Result, MAY_BE_FALSE) ZEND_ARG_OBJ_INFO(0, odbc, Odbc\\Connection, 0) @@ -235,7 +221,6 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_odbc_columnprivileges, 0, 5, ZEND_ARG_TYPE_INFO(0, table, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, column, IS_STRING, 0) ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_connection_string_is_quoted, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) @@ -253,14 +238,10 @@ ZEND_FUNCTION(odbc_longreadlen); ZEND_FUNCTION(odbc_prepare); ZEND_FUNCTION(odbc_execute); ZEND_FUNCTION(odbc_cursor); -#if defined(HAVE_SQLDATASOURCES) ZEND_FUNCTION(odbc_data_source); -#endif ZEND_FUNCTION(odbc_exec); -#if defined(PHP_ODBC_HAVE_FETCH_HASH) ZEND_FUNCTION(odbc_fetch_object); ZEND_FUNCTION(odbc_fetch_array); -#endif ZEND_FUNCTION(odbc_fetch_into); ZEND_FUNCTION(odbc_fetch_row); ZEND_FUNCTION(odbc_result); @@ -270,9 +251,7 @@ ZEND_FUNCTION(odbc_connect); ZEND_FUNCTION(odbc_pconnect); ZEND_FUNCTION(odbc_close); ZEND_FUNCTION(odbc_num_rows); -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) ZEND_FUNCTION(odbc_next_result); -#endif ZEND_FUNCTION(odbc_num_fields); ZEND_FUNCTION(odbc_field_name); ZEND_FUNCTION(odbc_field_type); @@ -289,17 +268,13 @@ ZEND_FUNCTION(odbc_tables); ZEND_FUNCTION(odbc_columns); ZEND_FUNCTION(odbc_gettypeinfo); ZEND_FUNCTION(odbc_primarykeys); -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) ZEND_FUNCTION(odbc_procedurecolumns); ZEND_FUNCTION(odbc_procedures); ZEND_FUNCTION(odbc_foreignkeys); -#endif ZEND_FUNCTION(odbc_specialcolumns); ZEND_FUNCTION(odbc_statistics); -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) ZEND_FUNCTION(odbc_tableprivileges); ZEND_FUNCTION(odbc_columnprivileges); -#endif ZEND_FUNCTION(odbc_connection_string_is_quoted); ZEND_FUNCTION(odbc_connection_string_should_quote); ZEND_FUNCTION(odbc_connection_string_quote); @@ -311,15 +286,11 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(odbc_prepare, arginfo_odbc_prepare) ZEND_FE(odbc_execute, arginfo_odbc_execute) ZEND_FE(odbc_cursor, arginfo_odbc_cursor) -#if defined(HAVE_SQLDATASOURCES) ZEND_FE(odbc_data_source, arginfo_odbc_data_source) -#endif ZEND_FE(odbc_exec, arginfo_odbc_exec) ZEND_RAW_FENTRY("odbc_do", zif_odbc_exec, arginfo_odbc_do, 0, NULL, NULL) -#if defined(PHP_ODBC_HAVE_FETCH_HASH) ZEND_FE(odbc_fetch_object, arginfo_odbc_fetch_object) ZEND_FE(odbc_fetch_array, arginfo_odbc_fetch_array) -#endif ZEND_FE(odbc_fetch_into, arginfo_odbc_fetch_into) ZEND_FE(odbc_fetch_row, arginfo_odbc_fetch_row) ZEND_FE(odbc_result, arginfo_odbc_result) @@ -329,9 +300,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(odbc_pconnect, arginfo_odbc_pconnect) ZEND_FE(odbc_close, arginfo_odbc_close) ZEND_FE(odbc_num_rows, arginfo_odbc_num_rows) -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) ZEND_FE(odbc_next_result, arginfo_odbc_next_result) -#endif ZEND_FE(odbc_num_fields, arginfo_odbc_num_fields) ZEND_FE(odbc_field_name, arginfo_odbc_field_name) ZEND_FE(odbc_field_type, arginfo_odbc_field_type) @@ -349,17 +318,13 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(odbc_columns, arginfo_odbc_columns) ZEND_FE(odbc_gettypeinfo, arginfo_odbc_gettypeinfo) ZEND_FE(odbc_primarykeys, arginfo_odbc_primarykeys) -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) ZEND_FE(odbc_procedurecolumns, arginfo_odbc_procedurecolumns) ZEND_FE(odbc_procedures, arginfo_odbc_procedures) ZEND_FE(odbc_foreignkeys, arginfo_odbc_foreignkeys) -#endif ZEND_FE(odbc_specialcolumns, arginfo_odbc_specialcolumns) ZEND_FE(odbc_statistics, arginfo_odbc_statistics) -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) ZEND_FE(odbc_tableprivileges, arginfo_odbc_tableprivileges) ZEND_FE(odbc_columnprivileges, arginfo_odbc_columnprivileges) -#endif ZEND_FE(odbc_connection_string_is_quoted, arginfo_odbc_connection_string_is_quoted) ZEND_FE(odbc_connection_string_should_quote, arginfo_odbc_connection_string_should_quote) ZEND_FE(odbc_connection_string_quote, arginfo_odbc_connection_string_quote) @@ -408,7 +373,6 @@ static void register_odbc_symbols(int module_number) REGISTER_LONG_CONSTANT("SQL_DATE", SQL_DATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TIME", SQL_TIME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TIMESTAMP", SQL_TIMESTAMP, CONST_PERSISTENT); -#if (defined(ODBCVER) && (ODBCVER >= 0x0300)) REGISTER_LONG_CONSTANT("SQL_TYPE_DATE", SQL_TYPE_DATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TYPE_TIME", SQL_TYPE_TIME, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_TYPE_TIMESTAMP", SQL_TYPE_TIMESTAMP, CONST_PERSISTENT); @@ -426,14 +390,10 @@ static void register_odbc_symbols(int module_number) REGISTER_LONG_CONSTANT("SQL_INDEX_ALL", SQL_INDEX_ALL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_ENSURE", SQL_ENSURE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SQL_QUICK", SQL_QUICK, CONST_PERSISTENT); -#endif zend_attribute *attribute_Deprecated_func_odbc_result_all_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "odbc_result_all", sizeof("odbc_result_all") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_odbc_result_all_0_arg0; - zend_string *attribute_Deprecated_func_odbc_result_all_0_arg0_str = zend_string_init("8.1", strlen("8.1"), 1); - ZVAL_STR(&attribute_Deprecated_func_odbc_result_all_0_arg0, attribute_Deprecated_func_odbc_result_all_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_odbc_result_all_0->args[0].value, &attribute_Deprecated_func_odbc_result_all_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_odbc_result_all_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); attribute_Deprecated_func_odbc_result_all_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "odbc_connect", sizeof("odbc_connect") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); diff --git a/ext/odbc/odbc_utils.c b/ext/odbc/odbc_utils.c index bc6674b9b5e5..8468fa9a06c1 100644 --- a/ext/odbc/odbc_utils.c +++ b/ext/odbc/odbc_utils.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Calvin Buckley | +----------------------------------------------------------------------+ @@ -59,7 +57,7 @@ PHP_FUNCTION(odbc_connection_string_quote) Z_PARAM_STR(str) ZEND_PARSE_PARAMETERS_END(); - size_t new_size = php_odbc_connstr_estimate_quote_length(ZSTR_VAL(str)); + size_t new_size = php_odbc_connstr_get_quoted_length(ZSTR_VAL(str)); zend_string *new_string = zend_string_alloc(new_size, 0); php_odbc_connstr_quote(ZSTR_VAL(new_string), ZSTR_VAL(str), new_size); /* reset length */ diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 7bc3a8bc17d0..45d30f13a56f 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Andreas Karajannis | @@ -89,7 +87,7 @@ static void odbc_insert_new_result(odbc_connection *connection, zval *result) static inline odbc_link *odbc_link_from_obj(zend_object *obj) { - return (odbc_link *)((char *)(obj) - XtOffsetOf(odbc_link, std)); + return ZEND_CONTAINER_OF(obj, odbc_link, std); } static int _close_pconn_with_res(zval *zv, void *p) @@ -206,7 +204,7 @@ static void odbc_connection_free_obj(zend_object *obj) static inline odbc_result *odbc_result_from_obj(zend_object *obj) { - return (odbc_result *)((char *)(obj) - XtOffsetOf(odbc_result, std)); + return ZEND_CONTAINER_OF(obj, odbc_result, std); } static zend_object *odbc_result_create_object(zend_class_entry *class_type) @@ -253,10 +251,6 @@ static void odbc_result_free(odbc_result *res) /* If aborted via timer expiration, don't try to call any unixODBC function */ if (res->stmt && !(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { -#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35) - SQLTransact(res->conn_ptr->henv, res->conn_ptr->hdbc, - (SQLUSMALLINT) SQL_COMMIT); -#endif SQLFreeStmt(res->stmt,SQL_DROP); /* We don't want the connection to be closed after the last statement has been closed * Connections will be closed on shutdown @@ -346,21 +340,21 @@ static void _close_odbc_pconn(zend_resource *rsrc) /* {{{ PHP_INI_DISP(display_link_nums) */ static PHP_INI_DISP(display_link_nums) { - char *value; + const zend_string *value; if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) { - value = ZSTR_VAL(ini_entry->orig_value); + value = ini_entry->orig_value; } else if (ini_entry->value) { - value = ZSTR_VAL(ini_entry->value); + value = ini_entry->value; } else { value = NULL; } if (value) { - if (atoi(value) == -1) { + if (atoi(ZSTR_VAL(value)) == -1) { PUTS("Unlimited"); } else { - php_printf("%s", value); + php_output_write(ZSTR_VAL(value), ZSTR_LEN(value)); } } } @@ -513,7 +507,7 @@ PHP_MINIT_FUNCTION(odbc) odbc_connection_ce->default_object_handlers = &odbc_connection_object_handlers; memcpy(&odbc_connection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - odbc_connection_object_handlers.offset = XtOffsetOf(odbc_link, std); + odbc_connection_object_handlers.offset = offsetof(odbc_link, std); odbc_connection_object_handlers.free_obj = odbc_connection_free_obj; odbc_connection_object_handlers.get_constructor = odbc_connection_get_constructor; odbc_connection_object_handlers.clone_obj = NULL; @@ -525,7 +519,7 @@ PHP_MINIT_FUNCTION(odbc) odbc_result_ce->default_object_handlers = &odbc_result_object_handlers; memcpy(&odbc_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - odbc_result_object_handlers.offset = XtOffsetOf(odbc_result, std); + odbc_result_object_handlers.offset = offsetof(odbc_result, std); odbc_result_object_handlers.free_obj = odbc_result_free_obj; odbc_result_object_handlers.get_constructor = odbc_result_get_constructor; odbc_result_object_handlers.clone_obj = NULL; @@ -579,10 +573,6 @@ PHP_MINFO_FUNCTION(odbc) snprintf(buf, sizeof(buf), ZEND_LONG_FMT, ODBCG(num_links)); php_info_print_table_row(2, "Active Links", buf); php_info_print_table_row(2, "ODBC library", PHP_ODBC_TYPE); -#ifdef ODBCVER - snprintf(buf, sizeof(buf), "0x%.4x", ODBCVER); - php_info_print_table_row(2, "ODBCVER", buf); -#endif #ifndef PHP_WIN32 php_info_print_table_row(2, "ODBC_CFLAGS", PHP_ODBC_CFLAGS); php_info_print_table_row(2, "ODBC_LFLAGS", PHP_ODBC_LFLAGS); @@ -670,7 +660,6 @@ void odbc_bindcols(odbc_result *result) SQLSMALLINT colnamelen; /* Not used */ SQLLEN displaysize; SQLUSMALLINT colfieldid; - int charextraalloc; result->values = (odbc_result_value *) safe_emalloc(sizeof(odbc_result_value), result->numcols, 0); @@ -678,13 +667,13 @@ void odbc_bindcols(odbc_result *result) result->binmode = ODBCG(defaultbinmode); for(i = 0; i < result->numcols; i++) { - charextraalloc = 0; + bool char_extra_alloc = false; colfieldid = SQL_COLUMN_DISPLAY_SIZE; - rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), PHP_ODBC_SQL_DESC_NAME, + rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), SQL_DESC_NAME, result->values[i].name, sizeof(result->values[i].name), &colnamelen, 0); result->values[i].coltype = 0; - rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_TYPE, + rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_TYPE, NULL, 0, NULL, &result->values[i].coltype); /* Don't bind LONG / BINARY columns, so that fetch behaviour can @@ -696,37 +685,22 @@ void odbc_bindcols(odbc_result *result) case SQL_VARBINARY: case SQL_LONGVARBINARY: case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif result->values[i].value = NULL; break; - -#ifdef HAVE_ADABAS - case SQL_TIMESTAMP: - result->values[i].value = (char *)emalloc(27); - SQLBindCol(result->stmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, result->values[i].value, - 27, &result->values[i].vallen); - break; -#endif /* HAVE_ADABAS */ case SQL_CHAR: case SQL_VARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WCHAR: case SQL_WVARCHAR: colfieldid = SQL_DESC_OCTET_LENGTH; -#else - charextraalloc = 1; -#endif /* TODO: Check this is the intended behaviour */ ZEND_FALLTHROUGH; default: - rc = PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(i+1), colfieldid, + rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), colfieldid, NULL, 0, NULL, &displaysize); if (rc != SQL_SUCCESS) { displaysize = 0; } -#if defined(ODBCVER) && (ODBCVER >= 0x0300) if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && colfieldid == SQL_DESC_OCTET_LENGTH) { SQLINTEGER err; SQLCHAR errtxt[128]; @@ -742,7 +716,7 @@ void odbc_bindcols(odbc_result *result) } /* This is a quirk for ODBC 2.0 compatibility for broken driver implementations. */ - charextraalloc = 1; + char_extra_alloc = true; rc = SQLColAttributes(result->stmt, (SQLUSMALLINT)(i+1), SQL_COLUMN_DISPLAY_SIZE, NULL, 0, NULL, &displaysize); if (rc != SQL_SUCCESS) { @@ -756,7 +730,6 @@ void odbc_bindcols(odbc_result *result) result->values[i].value = NULL; break; } -#endif /* Workaround for drivers that report VARCHAR(MAX) columns as SQL_VARCHAR (bug #73725) */ if (SQL_VARCHAR == result->values[i].coltype && displaysize == 0) { result->values[i].coltype = SQL_LONGVARCHAR; @@ -769,7 +742,7 @@ void odbc_bindcols(odbc_result *result) displaysize += 3; } - if (charextraalloc) { + if (char_extra_alloc) { /* Since we don't know the exact # of bytes, allocate extra */ displaysize *= 4; } @@ -809,17 +782,7 @@ void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type) void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) { odbc_result *result; -#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) - /* this seems to be necessary for Solid2.3 ( tested by - * tammy@synchronis.com) and Solid 3.0 (tested by eric@terra.telemediair.nl) - * Solid does not seem to declare a SQLINTEGER, but it does declare a - * SQL_INTEGER which does not work (despite being the same type as a SDWORD. - * Solid 3.5 does not have this issue. - */ - SDWORD len; -#else SQLLEN len; -#endif zval *pv_res; zend_long pv_num; @@ -845,7 +808,7 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) RETURN_FALSE; } - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT) (type?SQL_COLUMN_SCALE:SQL_COLUMN_PRECISION), NULL, 0, NULL, &len); + SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT) (type?SQL_COLUMN_SCALE:SQL_COLUMN_PRECISION), NULL, 0, NULL, &len); RETURN_LONG(len); } @@ -858,9 +821,7 @@ PHP_FUNCTION(odbc_close_all) { zval *zv; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); /* Loop through the link list, now close all links and their results */ ZEND_HASH_FOREACH_VAL(&ODBCG(connections), zv) { @@ -899,9 +860,7 @@ PHP_FUNCTION(odbc_prepare) odbc_result *result = NULL; RETCODE rc; int i; -#ifdef HAVE_SQL_EXTENDED_FETCH SQLUINTEGER scrollopts; -#endif if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_conn, odbc_connection_ce, &query, &query_len) == FAILURE) { RETURN_THROWS(); @@ -916,7 +875,7 @@ PHP_FUNCTION(odbc_prepare) result->numparams = 0; result->param_info = NULL; - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -929,21 +888,17 @@ PHP_FUNCTION(odbc_prepare) RETURN_FALSE; } -#ifdef HAVE_SQL_EXTENDED_FETCH - /* Solid doesn't have ExtendedFetch, if DriverManager is used, get Info, - whether Driver supports ExtendedFetch */ rc = SQLGetInfo(conn->hdbc, SQL_FETCH_DIRECTION, (void *) &scrollopts, sizeof(scrollopts), NULL); if (rc == SQL_SUCCESS) { if ((result->fetch_abs = (scrollopts & SQL_FD_FETCH_ABSOLUTE))) { /* Try to set CURSOR_TYPE to dynamic. Driver will replace this with other type if not possible. */ - SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, ODBCG(default_cursortype)); + SQLSetStmtAttr(result->stmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) ODBCG(default_cursortype), 0); } } else { result->fetch_abs = 0; } -#endif rc = SQLPrepare(result->stmt, (SQLCHAR *) query, SQL_NTS); switch (rc) { @@ -1015,10 +970,9 @@ PHP_FUNCTION(odbc_execute) zval *pv_res, *tmp; HashTable *pv_param_ht = (HashTable *) &zend_empty_array; odbc_params_t *params = NULL; - char *filename; SQLSMALLINT ctype; odbc_result *result; - int i, ne; + int i; RETCODE rc; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|h", &pv_res, odbc_result_ce, &pv_param_ht) == FAILURE) { @@ -1029,8 +983,9 @@ PHP_FUNCTION(odbc_execute) CHECK_ODBC_RESULT(result); if (result->numparams > 0) { - if ((ne = zend_hash_num_elements(pv_param_ht)) < result->numparams) { - php_error_docref(NULL, E_WARNING, "Not enough parameters (%d should be %d) given", ne, result->numparams); + uint32_t ne = zend_hash_num_elements(pv_param_ht); + if (ne < result->numparams) { + php_error_docref(NULL, E_WARNING, "Not enough parameters (%" PRIu32 " should be %d) given", ne, result->numparams); RETURN_FALSE; } @@ -1063,11 +1018,11 @@ PHP_FUNCTION(odbc_execute) ZSTR_VAL(tmpstr)[0] == '\'' && ZSTR_VAL(tmpstr)[ZSTR_LEN(tmpstr) - 1] == '\'') { - if (ZSTR_LEN(tmpstr) != strlen(ZSTR_VAL(tmpstr))) { + if (UNEXPECTED(zend_str_has_nul_byte(tmpstr))) { odbc_release_params(result, params); RETURN_FALSE; } - filename = estrndup(&ZSTR_VAL(tmpstr)[1], ZSTR_LEN(tmpstr) - 2); + char *filename = estrndup(&ZSTR_VAL(tmpstr)[1], ZSTR_LEN(tmpstr) - 2); /* Check the basedir */ if (php_check_open_basedir(filename)) { @@ -1092,9 +1047,6 @@ PHP_FUNCTION(odbc_execute) (void *)(intptr_t)params[i-1].fp, 0, ¶ms[i-1].vallen); } else { -#ifdef HAVE_DBMAKER - precision = params[i-1].vallen; -#endif if (otype == IS_NULL) { params[i-1].vallen = SQL_NULL_DATA; } @@ -1222,7 +1174,6 @@ PHP_FUNCTION(odbc_cursor) } /* }}} */ -#ifdef HAVE_SQLDATASOURCES /* {{{ Return information about the currently connected data source */ PHP_FUNCTION(odbc_data_source) { @@ -1278,7 +1229,6 @@ PHP_FUNCTION(odbc_data_source) } /* }}} */ -#endif /* HAVE_SQLDATASOURCES */ /* {{{ Prepare and execute an SQL statement */ /* XXX Use flags */ @@ -1289,9 +1239,7 @@ PHP_FUNCTION(odbc_exec) size_t query_len; odbc_result *result = NULL; RETCODE rc; -#ifdef HAVE_SQL_EXTENDED_FETCH SQLUINTEGER scrollopts; -#endif if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os", &pv_conn, odbc_connection_ce, &query, &query_len) == FAILURE) { RETURN_THROWS(); @@ -1303,7 +1251,7 @@ PHP_FUNCTION(odbc_exec) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -1316,21 +1264,17 @@ PHP_FUNCTION(odbc_exec) RETURN_FALSE; } -#ifdef HAVE_SQL_EXTENDED_FETCH - /* Solid doesn't have ExtendedFetch, if DriverManager is used, get Info, - whether Driver supports ExtendedFetch */ rc = SQLGetInfo(conn->hdbc, SQL_FETCH_DIRECTION, (void *) &scrollopts, sizeof(scrollopts), NULL); if (rc == SQL_SUCCESS) { if ((result->fetch_abs = (scrollopts & SQL_FD_FETCH_ABSOLUTE))) { /* Try to set CURSOR_TYPE to dynamic. Driver will replace this with other type if not possible. */ - SQLSetStmtOption(result->stmt, SQL_CURSOR_TYPE, ODBCG(default_cursortype)); + SQLSetStmtAttr(result->stmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) ODBCG(default_cursortype), 0); } } else { result->fetch_abs = 0; } -#endif rc = SQLExecDirect(result->stmt, (SQLCHAR *) query, SQL_NTS); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA_FOUND) { @@ -1358,12 +1302,14 @@ PHP_FUNCTION(odbc_exec) } /* }}} */ -#ifdef PHP_ODBC_HAVE_FETCH_HASH -#define ODBC_NUM 1 -#define ODBC_OBJECT 2 +typedef enum php_odbc_fetch_result_type_t { + ODBC_NONE = 0, + ODBC_NUM = 1, + ODBC_OBJECT = 2, +} php_odbc_fetch_result_type_t; -/* {{{ php_odbc_fetch_hash */ -static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) +/* {{{ php_odbc_fetch */ +static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_odbc_fetch_result_type_t result_type) { int i; odbc_result *result; @@ -1372,63 +1318,84 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) char *buf = NULL; zend_long pv_row = 0; bool pv_row_is_null = true; - zval *pv_res, tmp; -#ifdef HAVE_SQL_EXTENDED_FETCH - SQLULEN crow; - SQLUSMALLINT RowStatus[1]; -#endif + zval *pv_res, *pv_res_arr, tmp; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l!", &pv_res, odbc_result_ce, &pv_row, &pv_row_is_null) == FAILURE) { - RETURN_THROWS(); + if (return_array || result_type == ODBC_NONE) { + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(pv_row, pv_row_is_null) + ZEND_PARSE_PARAMETERS_END(); + /* So we can use pv_res_arr for both return value and passed */ + pv_res_arr = return_value; + } else { + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) + Z_PARAM_ZVAL(pv_res_arr) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(pv_row, pv_row_is_null) + ZEND_PARSE_PARAMETERS_END(); } result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); - /* TODO deprecate $row argument values less than 1 after PHP 8.4 */ - -#ifndef HAVE_SQL_EXTENDED_FETCH - if (!pv_row_is_null && pv_row > 0) { - php_error_docref(NULL, E_WARNING, "Extended fetch functionality is not available, argument #3 ($row) is ignored"); + if (!pv_row_is_null && pv_row < 1) { + /* row arg no differs between callers */ + zend_argument_value_error(pv_res_arr == return_value ? 2 : 3, + "must be greater than or equal to 1"); + RETURN_THROWS(); } -#endif if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); RETURN_FALSE; } -#ifdef HAVE_SQL_EXTENDED_FETCH + /* If we're initializing a passed value into an array, do it before the fetch + * so that an empty result set will still be an array. + */ + if (!return_array && result_type) { + pv_res_arr = zend_try_array_init(pv_res_arr); + if (!pv_res_arr) { + RETURN_THROWS(); + } + } + if (result->fetch_abs) { if (!pv_row_is_null && pv_row > 0) { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,(SQLLEN)pv_row,&crow,RowStatus); + rc = SQLFetchScroll(result->stmt, SQL_FETCH_ABSOLUTE, (SQLLEN)pv_row); } else { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus); + rc = SQLFetchScroll(result->stmt, SQL_FETCH_NEXT, 1); } - } else -#endif - rc = SQLFetch(result->stmt); + } else { + rc = SQLFetch(result->stmt); + } if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { if (rc == SQL_ERROR) { -#ifdef HAVE_SQL_EXTENDED_FETCH - odbc_sql_error(result->conn_ptr, result->stmt, "SQLExtendedFetch"); -#else - odbc_sql_error(result->conn_ptr, result->stmt, "SQLFetch"); -#endif + odbc_sql_error(result->conn_ptr, result->stmt, "SQLFetchScroll"); } RETURN_FALSE; } - array_init(return_value); + /* ...but if returning an array, init only if we have a result set */ + if (return_array && result_type) { + array_init(pv_res_arr); + } -#ifdef HAVE_SQL_EXTENDED_FETCH if (!pv_row_is_null && pv_row > 0 && result->fetch_abs) result->fetched = (SQLLEN)pv_row; else -#endif result->fetched++; + /* For fetch_row, we don't return anything other than true, + * odbc_result will be used to fetch values instead. + */ + if (result_type == ODBC_NONE) { + RETURN_TRUE; + } + for(i = 0; i < result->numcols; i++) { sql_c_type = SQL_C_CHAR; @@ -1443,11 +1410,11 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) if (result->binmode == 1) { sql_c_type = SQL_C_BINARY; } + + /* TODO: Check this is the intended behaviour */ ZEND_FALLTHROUGH; case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) { ZVAL_EMPTY_STRING(&tmp); break; @@ -1461,7 +1428,9 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) if (rc == SQL_ERROR) { odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData"); efree(buf); - zval_ptr_dtor(return_value); + if (return_array) { + zval_ptr_dtor(pv_res_arr); + } RETURN_FALSE; } @@ -1495,18 +1464,23 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) } if (result_type & ODBC_NUM) { - zend_hash_index_update(Z_ARRVAL_P(return_value), i, &tmp); + zend_hash_index_update(Z_ARRVAL_P(pv_res_arr), i, &tmp); } else { if (!*(result->values[i].name) && Z_TYPE(tmp) == IS_STRING) { - zend_hash_update(Z_ARRVAL_P(return_value), Z_STR(tmp), &tmp); + zend_hash_update(Z_ARRVAL_P(pv_res_arr), Z_STR(tmp), &tmp); } else { - zend_hash_str_update(Z_ARRVAL_P(return_value), result->values[i].name, strlen(result->values[i].name), &tmp); + zend_hash_str_update(Z_ARRVAL_P(pv_res_arr), result->values[i].name, strlen(result->values[i].name), &tmp); } } } if (buf) { efree(buf); } + + /* return_value was set to an array otherwise */ + if (!return_array) { + RETURN_LONG(result->numcols); + } } /* }}} */ @@ -1514,7 +1488,7 @@ static void php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type) /* {{{ Fetch a result row as an object */ PHP_FUNCTION(odbc_fetch_object) { - php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, ODBC_OBJECT); + php_odbc_fetch(INTERNAL_FUNCTION_PARAM_PASSTHRU, true, ODBC_OBJECT); if (Z_TYPE_P(return_value) == IS_ARRAY) { object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value)); } @@ -1524,216 +1498,21 @@ PHP_FUNCTION(odbc_fetch_object) /* {{{ Fetch a result row as an associative array */ PHP_FUNCTION(odbc_fetch_array) { - php_odbc_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, ODBC_OBJECT); + php_odbc_fetch(INTERNAL_FUNCTION_PARAM_PASSTHRU, true, ODBC_OBJECT); } /* }}} */ -#endif /* {{{ Fetch one result row into an array */ PHP_FUNCTION(odbc_fetch_into) { - int i; - odbc_result *result; - RETCODE rc; - SQLSMALLINT sql_c_type; - char *buf = NULL; - zval *pv_res, *pv_res_arr, tmp; - zend_long pv_row = 0; - bool pv_row_is_null = true; -#ifdef HAVE_SQL_EXTENDED_FETCH - SQLULEN crow; - SQLUSMALLINT RowStatus[1]; -#endif /* HAVE_SQL_EXTENDED_FETCH */ - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oz|l!", &pv_res, odbc_result_ce, &pv_res_arr, &pv_row, &pv_row_is_null) == FAILURE) { - RETURN_THROWS(); - } - - result = Z_ODBC_RESULT_P(pv_res); - CHECK_ODBC_RESULT(result); - - /* TODO deprecate $row argument values less than 1 after PHP 8.4 */ - -#ifndef HAVE_SQL_EXTENDED_FETCH - if (!pv_row_is_null && pv_row > 0) { - php_error_docref(NULL, E_WARNING, "Extended fetch functionality is not available, argument #3 ($row) is ignored"); - } -#endif - - if (result->numcols == 0) { - php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); - RETURN_FALSE; - } - - pv_res_arr = zend_try_array_init(pv_res_arr); - if (!pv_res_arr) { - RETURN_THROWS(); - } - -#ifdef HAVE_SQL_EXTENDED_FETCH - if (result->fetch_abs) { - if (!pv_row_is_null && pv_row > 0) { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,(SQLLEN)pv_row,&crow,RowStatus); - } else { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus); - } - } else -#endif - rc = SQLFetch(result->stmt); - - if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - if (rc == SQL_ERROR) { -#ifdef HAVE_SQL_EXTENDED_FETCH - odbc_sql_error(result->conn_ptr, result->stmt, "SQLExtendedFetch"); -#else - odbc_sql_error(result->conn_ptr, result->stmt, "SQLFetch"); -#endif - } - RETURN_FALSE; - } - -#ifdef HAVE_SQL_EXTENDED_FETCH - if (!pv_row_is_null && pv_row > 0 && result->fetch_abs) - result->fetched = (SQLLEN)pv_row; - else -#endif - result->fetched++; - - for(i = 0; i < result->numcols; i++) { - sql_c_type = SQL_C_CHAR; - - switch(result->values[i].coltype) { - case SQL_BINARY: - case SQL_VARBINARY: - case SQL_LONGVARBINARY: - if (result->binmode <= 0) { - ZVAL_EMPTY_STRING(&tmp); - break; - } - if (result->binmode == 1) sql_c_type = SQL_C_BINARY; - - /* TODO: Check this is the intended behaviour */ - ZEND_FALLTHROUGH; - case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) - case SQL_WLONGVARCHAR: -#endif - if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) { - ZVAL_EMPTY_STRING(&tmp); - break; - } - - if (buf == NULL) { - buf = emalloc(result->longreadlen + 1); - } - rc = SQLGetData(result->stmt, (SQLUSMALLINT)(i + 1),sql_c_type, buf, result->longreadlen + 1, &result->values[i].vallen); - - if (rc == SQL_ERROR) { - odbc_sql_error(result->conn_ptr, result->stmt, "SQLGetData"); - efree(buf); - RETURN_FALSE; - } - if (rc == SQL_SUCCESS_WITH_INFO) { - ZVAL_STRINGL(&tmp, buf, result->longreadlen); - } else if (rc != SQL_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Cannot get data of column #%d (retcode %u)", i + 1, rc); - ZVAL_FALSE(&tmp); - } else if (result->values[i].vallen == SQL_NULL_DATA) { - ZVAL_NULL(&tmp); - break; - } else if (result->values[i].vallen == SQL_NO_TOTAL) { - php_error_docref(NULL, E_WARNING, "Cannot get data of column #%d (driver cannot determine length)", i + 1); - ZVAL_FALSE(&tmp); - } else { - ZVAL_STRINGL(&tmp, buf, result->values[i].vallen); - } - break; - - default: - if (result->values[i].vallen == SQL_NULL_DATA) { - ZVAL_NULL(&tmp); - break; - } else if (result->values[i].vallen == SQL_NO_TOTAL) { - php_error_docref(NULL, E_WARNING, "Cannot get data of column #%d (driver cannot determine length)", i + 1); - ZVAL_FALSE(&tmp); - break; - } - ZVAL_STRINGL(&tmp, result->values[i].value, result->values[i].vallen); - break; - } - zend_hash_index_update(Z_ARRVAL_P(pv_res_arr), i, &tmp); - } - if (buf) efree(buf); - RETURN_LONG(result->numcols); + php_odbc_fetch(INTERNAL_FUNCTION_PARAM_PASSTHRU, false, ODBC_NUM); } /* }}} */ /* {{{ Fetch a row */ PHP_FUNCTION(odbc_fetch_row) { - odbc_result *result; - RETCODE rc; - zval *pv_res; - zend_long pv_row = 0; - bool pv_row_is_null = true; -#ifdef HAVE_SQL_EXTENDED_FETCH - SQLULEN crow; - SQLUSMALLINT RowStatus[1]; -#endif - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|l!", &pv_res, odbc_result_ce, &pv_row, &pv_row_is_null) == FAILURE) { - RETURN_THROWS(); - } - - result = Z_ODBC_RESULT_P(pv_res); - CHECK_ODBC_RESULT(result); - -#ifndef HAVE_SQL_EXTENDED_FETCH - if (!pv_row_is_null) { - php_error_docref(NULL, E_WARNING, "Extended fetch functionality is not available, argument #3 ($row) is ignored"); - } -#else - if (!pv_row_is_null && pv_row < 1) { - php_error_docref(NULL, E_WARNING, "Argument #3 ($row) must be greater than or equal to 1"); - RETURN_FALSE; - } -#endif - - if (result->numcols == 0) { - php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); - RETURN_FALSE; - } - -#ifdef HAVE_SQL_EXTENDED_FETCH - if (result->fetch_abs) { - if (!pv_row_is_null) { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_ABSOLUTE,(SQLLEN)pv_row,&crow,RowStatus); - } else { - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus); - } - } else -#endif - rc = SQLFetch(result->stmt); - - if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - if (rc == SQL_ERROR) { -#ifdef HAVE_SQL_EXTENDED_FETCH - odbc_sql_error(result->conn_ptr, result->stmt, "SQLExtendedFetch"); -#else - odbc_sql_error(result->conn_ptr, result->stmt, "SQLFetch"); -#endif - } - RETURN_FALSE; - } - -#ifdef HAVE_SQL_EXTENDED_FETCH - if (!pv_row_is_null) { - result->fetched = (SQLLEN)pv_row; - } else -#endif - result->fetched++; - - RETURN_TRUE; + php_odbc_fetch(INTERNAL_FUNCTION_PARAM_PASSTHRU, false, ODBC_NONE); } /* }}} */ @@ -1750,10 +1529,6 @@ PHP_FUNCTION(odbc_result) RETCODE rc; SQLLEN fieldsize; zval *pv_res; -#ifdef HAVE_SQL_EXTENDED_FETCH - SQLULEN crow; - SQLUSMALLINT RowStatus[1]; -#endif ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce) @@ -1804,20 +1579,15 @@ PHP_FUNCTION(odbc_result) if (result->fetched == 0) { /* User forgot to call odbc_fetch_row(), or wants to reload the results, do it now */ -#ifdef HAVE_SQL_EXTENDED_FETCH - if (result->fetch_abs) - rc = SQLExtendedFetch(result->stmt, SQL_FETCH_NEXT, 1, &crow,RowStatus); - else -#endif + if (result->fetch_abs) { + rc = SQLFetchScroll(result->stmt, SQL_FETCH_NEXT, 1); + } else { rc = SQLFetch(result->stmt); + } if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { if (rc == SQL_ERROR) { -#ifdef HAVE_SQL_EXTENDED_FETCH - odbc_sql_error(result->conn_ptr, result->stmt, "SQLExtendedFetch"); -#else - odbc_sql_error(result->conn_ptr, result->stmt, "SQLFetch"); -#endif + odbc_sql_error(result->conn_ptr, result->stmt, "SQLFetchScroll"); } RETURN_FALSE; } @@ -1839,9 +1609,7 @@ PHP_FUNCTION(odbc_result) ZEND_FALLTHROUGH; case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif if (IS_SQL_LONG(result->values[field_ind].coltype)) { if (result->longreadlen <= 0) { break; @@ -1849,7 +1617,7 @@ PHP_FUNCTION(odbc_result) fieldsize = result->longreadlen; } } else { - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)(field_ind + 1), + SQLColAttribute(result->stmt, (SQLUSMALLINT)(field_ind + 1), (SQLUSMALLINT)((sql_c_type == SQL_C_BINARY) ? SQL_COLUMN_LENGTH : SQL_COLUMN_DISPLAY_SIZE), NULL, 0, NULL, &fieldsize); @@ -1885,10 +1653,7 @@ PHP_FUNCTION(odbc_result) /* Reduce fieldlen by 1 if we have char data. One day we might have binary strings... */ if ((result->values[field_ind].coltype == SQL_LONGVARCHAR) -#if defined(ODBCVER) && (ODBCVER >= 0x0300) - || (result->values[field_ind].coltype == SQL_WLONGVARCHAR) -#endif - ) { + || (result->values[field_ind].coltype == SQL_WLONGVARCHAR)) { fieldsize -= 1; } /* Don't duplicate result, saves one emalloc. @@ -1899,7 +1664,6 @@ PHP_FUNCTION(odbc_result) } ZSTR_VAL(field_str)[ZSTR_LEN(field_str)] = '\0'; RETURN_NEW_STR(field_str); - break; default: if (result->values[field_ind].vallen == SQL_NULL_DATA) { @@ -1965,10 +1729,6 @@ PHP_FUNCTION(odbc_result_all) char *pv_format = NULL; size_t i, pv_format_len = 0; SQLSMALLINT sql_c_type; -#ifdef HAVE_SQL_EXTENDED_FETCH - SQLULEN crow; - SQLUSMALLINT RowStatus[1]; -#endif if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s", &pv_res, odbc_result_ce, &pv_format, &pv_format_len) == FAILURE) { RETURN_THROWS(); @@ -1981,12 +1741,11 @@ PHP_FUNCTION(odbc_result_all) php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); RETURN_FALSE; } -#ifdef HAVE_SQL_EXTENDED_FETCH - if (result->fetch_abs) - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus); - else -#endif + if (result->fetch_abs) { + rc = SQLFetchScroll(result->stmt, SQL_FETCH_NEXT, 1); + } else { rc = SQLFetch(result->stmt); + } if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { php_printf("

No rows found

\n"); @@ -2024,9 +1783,7 @@ PHP_FUNCTION(odbc_result_all) /* TODO: Check this is the intended behaviour */ ZEND_FALLTHROUGH; case SQL_LONGVARCHAR: -#if defined(ODBCVER) && (ODBCVER >= 0x0300) case SQL_WLONGVARCHAR: -#endif if (IS_SQL_LONG(result->values[i].coltype) && result->longreadlen <= 0) { php_printf("Not printable"); @@ -2083,12 +1840,11 @@ PHP_FUNCTION(odbc_result_all) } php_printf("\n"); -#ifdef HAVE_SQL_EXTENDED_FETCH - if (result->fetch_abs) - rc = SQLExtendedFetch(result->stmt,SQL_FETCH_NEXT,1,&crow,RowStatus); - else -#endif + if (result->fetch_abs) { + rc = SQLFetchScroll(result->stmt, SQL_FETCH_NEXT, 1); + } else { rc = SQLFetch(result->stmt); + } } php_printf("\n"); if (buf) efree(buf); @@ -2157,20 +1913,8 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool return false; } -#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) - SQLSetConnectOption((link->connection->hdbc, SQL_TRANSLATE_OPTION, - SQL_SOLID_XLATOPT_NOCNV); -#endif -#ifdef HAVE_OPENLINK - { - char dsnbuf[1024]; - short dsnbuflen; - - rc = SQLDriverConnect(link->connection->hdbc, NULL, db, SQL_NTS, dsnbuf, sizeof(dsnbuf) - 1, &dsnbuflen, SQL_DRIVER_NOPROMPT); - } -#else if (cur_opt != SQL_CUR_DEFAULT) { - rc = SQLSetConnectOption(link->connection->hdbc, SQL_ODBC_CURSORS, cur_opt); + rc = SQLSetConnectAttr(link->connection->hdbc, SQL_ATTR_ODBC_CURSORS, (SQLPOINTER) (intptr_t) cur_opt, 0); if (rc != SQL_SUCCESS) { /* && rc != SQL_SUCCESS_WITH_INFO ? */ odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SQLSetConnectOption"); return false; @@ -2178,15 +1922,12 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool } /* Possible fix for bug #10250 * Needs testing on UnixODBC < 2.0.5 though. */ -#if defined(HAVE_EMPRESS) || defined(HAVE_UNIXODBC) || defined(PHP_WIN32) || defined (HAVE_IODBC) -/* * Uncomment the line above, and comment line below to fully test - * #ifdef HAVE_EMPRESS */ +#if defined(HAVE_UNIXODBC) || defined(PHP_WIN32) || defined (HAVE_IODBC) { int direct = 0; SQLCHAR dsnbuf[1024]; short dsnbuflen; - char *ldb = 0; - int ldb_len = 0; + char *ldb = NULL; /* a connection string may have = but not ; - i.e. "DSN=PHP" */ if (strstr((char*)db, "=")) { @@ -2210,9 +1951,9 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool if (use_uid_arg) { should_quote_uid = !php_odbc_connstr_is_quoted(uid) && php_odbc_connstr_should_quote(uid); if (should_quote_uid) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(uid); - uid_quoted = emalloc(estimated_length); - php_odbc_connstr_quote(uid_quoted, uid, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(uid); + uid_quoted = emalloc(quoted_length); + php_odbc_connstr_quote(uid_quoted, uid, quoted_length); } else { uid_quoted = uid; } @@ -2225,9 +1966,9 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool if (use_pwd_arg) { should_quote_pwd = !php_odbc_connstr_is_quoted(pwd) && php_odbc_connstr_should_quote(pwd); if (should_quote_pwd) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(pwd); - pwd_quoted = emalloc(estimated_length); - php_odbc_connstr_quote(pwd_quoted, pwd, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(pwd); + pwd_quoted = emalloc(quoted_length); + php_odbc_connstr_quote(pwd_quoted, pwd, quoted_length); } else { pwd_quoted = pwd; } @@ -2248,7 +1989,7 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool efree(pwd_quoted); } } else { - ldb_len = strlen(db)+1; + size_t ldb_len = strlen(db)+1; ldb = (char*) emalloc(ldb_len); memcpy(ldb, db, ldb_len); } @@ -2266,7 +2007,6 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool } #else rc = SQLConnect(link->connection->hdbc, (SQLCHAR *) db, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS); -#endif #endif if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SQLConnect"); @@ -2472,7 +2212,6 @@ PHP_FUNCTION(odbc_num_rows) } /* }}} */ -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) /* {{{ Checks if multiple results are available */ PHP_FUNCTION(odbc_next_result) { @@ -2519,7 +2258,6 @@ PHP_FUNCTION(odbc_next_result) } } /* }}} */ -#endif /* {{{ Get number of columns in a result */ PHP_FUNCTION(odbc_num_fields) @@ -2602,7 +2340,7 @@ PHP_FUNCTION(odbc_field_type) RETURN_FALSE; } - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL); + SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL); RETURN_STRING(tmp); } /* }}} */ @@ -2661,7 +2399,7 @@ PHP_FUNCTION(odbc_autocommit) { RETCODE rc; zval *pv_conn; - bool pv_onoff = 0; + bool pv_onoff = false; bool pv_onoff_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b!", &pv_conn, odbc_connection_ce, &pv_onoff, &pv_onoff_is_null) == FAILURE) { @@ -2672,7 +2410,7 @@ PHP_FUNCTION(odbc_autocommit) CHECK_ODBC_CONNECTION(conn); if (!pv_onoff_is_null) { - rc = SQLSetConnectOption(conn->hdbc, SQL_AUTOCOMMIT, pv_onoff ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF); + rc = SQLSetConnectAttr(conn->hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) (intptr_t) (pv_onoff ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF), 0); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(conn, SQL_NULL_HSTMT, "Set autocommit"); RETURN_FALSE; @@ -2681,7 +2419,7 @@ PHP_FUNCTION(odbc_autocommit) } else { SQLINTEGER status; - rc = SQLGetConnectOption(conn->hdbc, SQL_AUTOCOMMIT, (PTR)&status); + rc = SQLGetConnectAttr(conn->hdbc, SQL_ATTR_AUTOCOMMIT, &status, SQL_IS_INTEGER, NULL); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(conn, SQL_NULL_HSTMT, "Get commit status"); RETURN_FALSE; @@ -2783,7 +2521,7 @@ PHP_FUNCTION(odbc_setoption) php_error_docref(NULL, E_WARNING, "Unable to set option for persistent connection"); RETURN_FALSE; } - rc = SQLSetConnectOption(link->connection->hdbc, (unsigned short) pv_opt, pv_val); + rc = SQLSetConnectAttr(link->connection->hdbc, pv_opt, (SQLPOINTER) pv_val, 0); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(link->connection, SQL_NULL_HSTMT, "SetConnectOption"); RETURN_FALSE; @@ -2797,7 +2535,7 @@ PHP_FUNCTION(odbc_setoption) result = Z_ODBC_RESULT_P(pv_handle); CHECK_ODBC_RESULT(result); - rc = SQLSetStmtOption(result->stmt, (unsigned short) pv_opt, pv_val); + rc = SQLSetStmtAttr(result->stmt, pv_opt, (SQLPOINTER) pv_val, 0); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { odbc_sql_error(result->conn_ptr, result->stmt, "SetStmtOption"); @@ -2837,7 +2575,7 @@ PHP_FUNCTION(odbc_tables) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -2902,7 +2640,7 @@ PHP_FUNCTION(odbc_columns) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -2949,7 +2687,6 @@ PHP_FUNCTION(odbc_columns) } /* }}} */ -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) /* {{{ Returns a result identifier that can be used to fetch a list of columns and associated privileges for the specified table */ PHP_FUNCTION(odbc_columnprivileges) { @@ -2970,7 +2707,7 @@ PHP_FUNCTION(odbc_columnprivileges) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3009,9 +2746,7 @@ PHP_FUNCTION(odbc_columnprivileges) odbc_insert_new_result(conn, return_value); } /* }}} */ -#endif /* HAVE_DBMAKER || HAVE_SOLID*/ -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) /* {{{ Returns a result identifier to either a list of foreign keys in the specified table or a list of foreign keys in other tables that refer to the primary key in the specified table */ PHP_FUNCTION(odbc_foreignkeys) { @@ -3026,7 +2761,7 @@ PHP_FUNCTION(odbc_foreignkeys) RETURN_THROWS(); } -#if defined(HAVE_DBMAKER) || defined(HAVE_IBMDB2) +#if defined(HAVE_IBMDB2) #define EMPTY_TO_NULL(xstr) \ if ((int)strlen((xstr)) == 0) (xstr) = NULL @@ -3044,7 +2779,7 @@ PHP_FUNCTION(odbc_foreignkeys) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3085,7 +2820,6 @@ PHP_FUNCTION(odbc_foreignkeys) odbc_insert_new_result(conn, return_value); } /* }}} */ -#endif /* HAVE_SOLID */ /* {{{ Returns a result identifier containing information about data types supported by the data source */ PHP_FUNCTION(odbc_gettypeinfo) @@ -3108,7 +2842,7 @@ PHP_FUNCTION(odbc_gettypeinfo) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3163,7 +2897,7 @@ PHP_FUNCTION(odbc_primarykeys) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3202,7 +2936,6 @@ PHP_FUNCTION(odbc_primarykeys) } /* }}} */ -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) /* {{{ Returns a result identifier containing the list of input and output parameters, as well as the columns that make up the result set for the specified procedures */ PHP_FUNCTION(odbc_procedurecolumns) { @@ -3223,7 +2956,7 @@ PHP_FUNCTION(odbc_procedurecolumns) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3262,9 +2995,7 @@ PHP_FUNCTION(odbc_procedurecolumns) odbc_insert_new_result(conn, return_value); } /* }}} */ -#endif /* HAVE_SOLID */ -#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) /* {{{ Returns a result identifier containing the list of procedure names in a datasource */ PHP_FUNCTION(odbc_procedures) { @@ -3284,7 +3015,7 @@ PHP_FUNCTION(odbc_procedures) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3322,7 +3053,6 @@ PHP_FUNCTION(odbc_procedures) odbc_insert_new_result(conn, return_value); } /* }}} */ -#endif /* HAVE_SOLID */ /* {{{ Returns a result identifier containing either the optimal set of columns that uniquely identifies a row in the table or columns that are automatically updated when any value in the row is updated by a transaction */ PHP_FUNCTION(odbc_specialcolumns) @@ -3350,7 +3080,7 @@ PHP_FUNCTION(odbc_specialcolumns) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3416,7 +3146,7 @@ PHP_FUNCTION(odbc_statistics) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3457,7 +3187,6 @@ PHP_FUNCTION(odbc_statistics) } /* }}} */ -#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) /* {{{ Returns a result identifier containing a list of tables and the privileges associated with each table */ PHP_FUNCTION(odbc_tableprivileges) { @@ -3477,7 +3206,7 @@ PHP_FUNCTION(odbc_tableprivileges) object_init_ex(return_value, odbc_result_ce); result = Z_ODBC_RESULT_P(return_value); - rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); + rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { php_error_docref(NULL, E_WARNING, "SQLAllocStmt error 'Invalid Handle'"); zval_ptr_dtor(return_value); @@ -3515,6 +3244,5 @@ PHP_FUNCTION(odbc_tableprivileges) odbc_insert_new_result(conn, return_value); } /* }}} */ -#endif /* HAVE_DBMAKER */ #endif /* HAVE_UODBC */ diff --git a/ext/odbc/php_odbc.h b/ext/odbc/php_odbc.h index bc29623d7c2f..d2815b90d108 100644 --- a/ext/odbc/php_odbc.h +++ b/ext/odbc/php_odbc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Andreas Karajannis | @@ -31,10 +29,6 @@ extern zend_module_entry odbc_module_entry; #include "php_version.h" #define PHP_ODBC_VERSION PHP_VERSION -#if defined(HAVE_DBMAKER) || defined(PHP_WIN32) || defined(HAVE_IBMDB2) || defined(HAVE_UNIXODBC) || defined(HAVE_IODBC) -# define PHP_ODBC_HAVE_FETCH_HASH 1 -#endif - /* user functions */ PHP_MINIT_FUNCTION(odbc); PHP_MSHUTDOWN_FUNCTION(odbc); diff --git a/ext/odbc/php_odbc_includes.h b/ext/odbc/php_odbc_includes.h index e0c6330d7449..1c53e35bf43a 100644 --- a/ext/odbc/php_odbc_includes.h +++ b/ext/odbc/php_odbc_includes.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Sæther Bakken | | Andreas Karajannis | @@ -23,140 +21,31 @@ /* checking in the same order as in configure.ac */ -#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35) /* Solid Server */ - -#define ODBC_TYPE "Solid" -#if defined(HAVE_SOLID) -# include -# include -# include -#elif defined(HAVE_SOLID_30) -# include -# include -# include -#elif defined(HAVE_SOLID_35) -# include -# include -# include -# include -# include -#endif /* end: #if defined(HAVE_SOLID) */ -#undef HAVE_SQL_EXTENDED_FETCH -#define SQLSMALLINT SWORD -#define SQLUSMALLINT UWORD -#ifndef SQL_SUCCEEDED -#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) -#endif - -#elif defined(HAVE_EMPRESS) /* Empress */ - -#define ODBC_TYPE "Empress" -#include -#include -#undef HAVE_SQL_EXTENDED_FETCH - -#elif defined(HAVE_ADABAS) /* Adabas D */ - -#define ODBC_TYPE "Adabas D" -#include -#include -#include -#define HAVE_SQL_EXTENDED_FETCH 1 -#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) -#define SQLINTEGER ULONG -#define SQLUSMALLINT USHORT - -#elif defined(HAVE_SAPDB) /* SAP DB */ - -#define ODBC_TYPE "SAP DB" -#include -#include -#include -#define HAVE_SQL_EXTENDED_FETCH 1 -#define SQL_SUCCEEDED(rc) (((rc)&(~1))==0) - -#elif defined(HAVE_IODBC) /* iODBC library */ - -#ifdef CHAR -#undef CHAR -#endif - -#ifdef SQLCHAR -#undef SQLCHAR -#endif +#if defined(HAVE_IODBC) /* iODBC library */ #define ODBC_TYPE "iODBC" #include #include #include -#define HAVE_SQL_EXTENDED_FETCH 1 #elif defined(HAVE_UNIXODBC) /* unixODBC library */ -#ifdef CHAR -#undef CHAR -#endif - -#ifdef SQLCHAR -#undef SQLCHAR -#endif - #define ODBC_TYPE "unixODBC" -#undef ODBCVER -#include -#include -#define HAVE_SQL_EXTENDED_FETCH 1 - -#elif defined(HAVE_ESOOB) /* Easysoft ODBC-ODBC Bridge library */ - -#define ODBC_TYPE "ESOOB" #include #include -#define HAVE_SQL_EXTENDED_FETCH 1 - -#elif defined(HAVE_OPENLINK) /* OpenLink ODBC drivers */ - -#define ODBC_TYPE "Openlink" -#include -#include -#include -#include -#define HAVE_SQL_EXTENDED_FETCH 1 -#ifndef SQLSMALLINT -#define SQLSMALLINT SWORD -#endif -#ifndef SQLUSMALLINT -#define SQLUSMALLINT UWORD -#endif - -#elif defined(HAVE_DBMAKER) /* DBMaker */ - -#define ODBC_TYPE "DBMaker" -#undef ODBCVER -#define ODBCVER 0x0300 -#define HAVE_SQL_EXTENDED_FETCH 1 -#include - #elif defined(HAVE_CODBC) /* Custom ODBC */ #define ODBC_TYPE "Custom ODBC" -#define HAVE_SQL_EXTENDED_FETCH 1 #include #elif defined(HAVE_IBMDB2) /* DB2 CLI */ #define ODBC_TYPE "IBM DB2 CLI" -#define HAVE_SQL_EXTENDED_FETCH 1 #include -#ifdef DB268K -/* Need to include ASLM for 68K applications */ -#include -#endif #else /* MS ODBC */ -#define HAVE_SQL_EXTENDED_FETCH 1 #include #include #include @@ -176,10 +65,6 @@ #define ODBC_SQL_ENV_T SQLHANDLE #define ODBC_SQL_CONN_T SQLHANDLE #define ODBC_SQL_STMT_T SQLHANDLE -#elif defined( HAVE_SOLID_35 ) || defined( HAVE_SAPDB ) || defined ( HAVE_EMPRESS ) -#define ODBC_SQL_ENV_T SQLHENV -#define ODBC_SQL_CONN_T SQLHDBC -#define ODBC_SQL_STMT_T SQLHSTMT #else #define ODBC_SQL_ENV_T HENV #define ODBC_SQL_CONN_T HDBC @@ -220,9 +105,7 @@ typedef struct odbc_result { odbc_result_value *values; SQLSMALLINT numcols; SQLSMALLINT numparams; -# ifdef HAVE_SQL_EXTENDED_FETCH int fetch_abs; -# endif zend_long longreadlen; int binmode; int fetched; @@ -265,21 +148,8 @@ void odbc_bindcols(odbc_result *result); void odbc_sql_error(ODBC_SQL_ERROR_PARAMS); -#if defined(ODBCVER) && (ODBCVER >= 0x0300) #define IS_SQL_LONG(x) (x == SQL_LONGVARBINARY || x == SQL_LONGVARCHAR || x == SQL_WLONGVARCHAR) -#define PHP_ODBC_SQLCOLATTRIBUTE SQLColAttribute -#define PHP_ODBC_SQLALLOCSTMT(hdbc, phstmt) SQLAllocHandle(SQL_HANDLE_STMT, hdbc, phstmt) - -#define PHP_ODBC_SQL_DESC_NAME SQL_DESC_NAME -#else -#define IS_SQL_LONG(x) (x == SQL_LONGVARBINARY || x == SQL_LONGVARCHAR) - -#define PHP_ODBC_SQLCOLATTRIBUTE SQLColAttributes -#define PHP_ODBC_SQLALLOCSTMT SQLAllocStmt - -#define PHP_ODBC_SQL_DESC_NAME SQL_COLUMN_NAME -#endif #define IS_SQL_BINARY(x) (x == SQL_BINARY || x == SQL_VARBINARY || x == SQL_LONGVARBINARY) PHP_ODBC_API ZEND_EXTERN_MODULE_GLOBALS(odbc) diff --git a/ext/odbc/tests/odbc_fetch_array_001.phpt b/ext/odbc/tests/odbc_fetch_array_001.phpt index bf13ed25e4d6..e7d4ccf328b6 100644 --- a/ext/odbc/tests/odbc_fetch_array_001.phpt +++ b/ext/odbc/tests/odbc_fetch_array_001.phpt @@ -17,7 +17,7 @@ odbc_exec($conn, 'INSERT INTO fetch_array VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_array'); var_dump(odbc_fetch_array($res)); -var_dump(odbc_fetch_array($res, 0)); +var_dump(odbc_fetch_array($res, null)); var_dump(odbc_fetch_array($res, 2)); var_dump(odbc_fetch_array($res, 4)); diff --git a/ext/odbc/tests/odbc_fetch_into_001.phpt b/ext/odbc/tests/odbc_fetch_into_001.phpt index 19f7f79268c5..e420475f02cc 100644 --- a/ext/odbc/tests/odbc_fetch_into_001.phpt +++ b/ext/odbc/tests/odbc_fetch_into_001.phpt @@ -20,7 +20,7 @@ $arr = []; var_dump(odbc_fetch_into($res, $arr)); var_dump($arr); $arr = []; -var_dump(odbc_fetch_into($res, $arr, 0)); +var_dump(odbc_fetch_into($res, $arr, null)); var_dump($arr); $arr = []; var_dump(odbc_fetch_into($res, $arr, 2)); diff --git a/ext/odbc/tests/odbc_fetch_object_001.phpt b/ext/odbc/tests/odbc_fetch_object_001.phpt index 62a8fc3b2c7e..eb553409639f 100644 --- a/ext/odbc/tests/odbc_fetch_object_001.phpt +++ b/ext/odbc/tests/odbc_fetch_object_001.phpt @@ -17,7 +17,7 @@ odbc_exec($conn, 'INSERT INTO fetch_object VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_object'); var_dump(odbc_fetch_object($res)); -var_dump(odbc_fetch_object($res, 0)); +var_dump(odbc_fetch_object($res, null)); var_dump(odbc_fetch_object($res, 2)); var_dump(odbc_fetch_object($res, 4)); diff --git a/ext/odbc/tests/odbc_fetch_row_001.phpt b/ext/odbc/tests/odbc_fetch_row_001.phpt index 576bb15414ce..fbadc8272590 100644 --- a/ext/odbc/tests/odbc_fetch_row_001.phpt +++ b/ext/odbc/tests/odbc_fetch_row_001.phpt @@ -17,7 +17,11 @@ odbc_exec($conn, 'INSERT INTO fetch_row VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_row'); -var_dump(odbc_fetch_row($res, 0)); +try { + var_dump(odbc_fetch_row($res, 0)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump(odbc_fetch_row($res, null)); var_dump(odbc_result($res, 'test')); @@ -39,9 +43,8 @@ require 'config.inc'; $conn = odbc_connect($dsn, $user, $pass); odbc_exec($conn, 'DROP TABLE fetch_row'); ?> ---EXPECTF-- -Warning: odbc_fetch_row(): Argument #3 ($row) must be greater than or equal to 1 in %s on line %d -bool(false) +--EXPECT-- +odbc_fetch_row(): Argument #2 ($row) must be greater than or equal to 1 bool(true) string(1) "1" bool(true) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index a2b2d0fde8b4..3d005b3835a7 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -25,6 +23,7 @@ #include "zend_extensions.h" #include "zend_compile.h" #include "ZendAccelerator.h" +#include "zend_modules.h" #include "zend_persist.h" #include "zend_shared_alloc.h" #include "zend_accelerator_module.h" @@ -57,6 +56,8 @@ #ifdef HAVE_JIT # include "jit/zend_jit.h" +# include "Optimizer/zend_func_info.h" +# include "Optimizer/zend_call_graph.h" #endif #ifndef ZEND_WIN32 @@ -86,7 +87,6 @@ typedef int gid_t; #ifndef ZEND_WIN32 # include # include -# include # include # include #endif @@ -100,15 +100,13 @@ typedef int gid_t; #include "zend_simd.h" -ZEND_EXTENSION(); +static zend_extension opcache_extension_entry; #ifndef ZTS zend_accel_globals accel_globals; #else int accel_globals_id; -#if defined(COMPILE_DL_OPCACHE) -ZEND_TSRMLS_CACHE_DEFINE() -#endif +size_t accel_globals_offset; #endif /* Points to the structure shared across all PHP processes */ @@ -312,7 +310,7 @@ static inline void accel_restart_leave(void) #endif } -static inline int accel_restart_is_active(void) +static inline bool accel_restart_is_active(void) { if (ZCSG(restart_in_progress)) { #ifndef ZEND_WIN32 @@ -325,19 +323,19 @@ static inline int accel_restart_is_active(void) if (fcntl(lock_file, F_GETLK, &restart_check) == -1) { zend_accel_error(ACCEL_LOG_DEBUG, "RestartC: %s (%d)", strerror(errno), errno); - return FAILURE; + return true; } if (restart_check.l_type == F_UNLCK) { ZCSG(restart_in_progress) = false; - return 0; + return false; } else { - return 1; + return true; } #else return LOCKVAL(restart_in) != 0; #endif } - return 0; + return false; } /* Creates a read lock for SHM access */ @@ -591,13 +589,12 @@ static zend_string* ZEND_FASTCALL accel_new_interned_string_for_php(zend_string static zend_always_inline zend_string *accel_find_interned_string_ex(zend_ulong h, const char *str, size_t size) { zend_string_table_pos_t pos; - zend_string *s; /* check for existing interned string */ pos = *STRTAB_HASH_TO_SLOT(&ZCSG(interned_strings), h); if (EXPECTED(pos != STRTAB_INVALID_POS)) { do { - s = STRTAB_POS_TO_STR(&ZCSG(interned_strings), pos); + zend_string *s = STRTAB_POS_TO_STR(&ZCSG(interned_strings), pos); if (EXPECTED(ZSTR_H(s) == h) && zend_string_equals_cstr(s, str, size)) { return s; } @@ -663,8 +660,7 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int if (Z_FUNC(p->val)->common.function_name) { Z_FUNC(p->val)->common.function_name = new_interned_string(Z_FUNC(p->val)->common.function_name); } - if (Z_FUNC(p->val)->common.arg_info && - (Z_FUNC(p->val)->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))) { + if (Z_FUNC(p->val)->common.arg_info) { uint32_t i; uint32_t num_args = Z_FUNC(p->val)->common.num_args + 1; zend_arg_info *arg_info = Z_FUNC(p->val)->common.arg_info - 1; @@ -673,6 +669,12 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int num_args++; } for (i = 0 ; i < num_args; i++) { + if (i > 0) { + arg_info[i].name = new_interned_string(arg_info[i].name); + if (arg_info[i].default_value) { + arg_info[i].default_value = new_interned_string(arg_info[i].default_value); + } + } accel_copy_permanent_list_types(new_interned_string, arg_info[i].type); } } @@ -714,6 +716,23 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int if (Z_FUNC(q->val)->common.function_name) { Z_FUNC(q->val)->common.function_name = new_interned_string(Z_FUNC(q->val)->common.function_name); } + if (Z_FUNC(q->val)->common.scope == ce) { + uint32_t num_args = Z_FUNC(q->val)->common.num_args + 1; + zend_arg_info *arg_info = Z_FUNC(q->val)->common.arg_info - 1; + + if (Z_FUNC(q->val)->common.fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + for (uint32_t i = 0 ; i < num_args; i++) { + if (i > 0) { + arg_info[i].name = new_interned_string(arg_info[i].name); + if (arg_info[i].default_value) { + arg_info[i].default_value = new_interned_string(arg_info[i].default_value); + } + } + accel_copy_permanent_list_types(new_interned_string, arg_info[i].type); + } + } } ZEND_HASH_FOREACH_END(); ZEND_HASH_MAP_FOREACH_BUCKET(&ce->constants_table, q) { @@ -837,7 +856,6 @@ static void accel_use_shm_interned_strings(void) #ifndef ZEND_WIN32 static inline void kill_all_lockers(struct flock *mem_usage_check) { - int tries; /* so that other process won't try to force while we are busy cleaning up */ ZCSG(force_restart_time) = 0; while (mem_usage_check->l_pid > 0) { @@ -845,7 +863,7 @@ static inline void kill_all_lockers(struct flock *mem_usage_check) int signal = SIGTERM; errno = 0; bool success = false; - tries = 10; + int tries = 10; while (tries--) { zend_accel_error(ACCEL_LOG_WARNING, "Attempting to kill locker %d", mem_usage_check->l_pid); @@ -941,7 +959,7 @@ static inline bool accel_is_inactive(void) return false; } -static int zend_get_stream_timestamp(const char *filename, zend_stat_t *statbuf) +static zend_result zend_get_stream_timestamp(const char *filename, zend_stat_t *statbuf) { php_stream_wrapper *wrapper; php_stream_statbuf stream_statbuf; @@ -1033,7 +1051,7 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_ !EG(current_execute_data) && file_handle->primary_script) { - zend_stat_t *tmpbuf = sapi_module.get_stat(); + const zend_stat_t *tmpbuf = sapi_module.get_stat(); if (tmpbuf) { if (size) { @@ -1114,11 +1132,11 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_ return statbuf.st_mtime; } -static inline int do_validate_timestamps(zend_persistent_script *persistent_script, zend_file_handle *file_handle) +static inline zend_result do_validate_timestamps(const zend_persistent_script *persistent_script, zend_file_handle *file_handle) { zend_file_handle ps_handle; zend_string *full_path_ptr = NULL; - int ret; + zend_result ret; /** check that the persistent script is indeed the same file we cached * (if part of the path is a symlink than it possible that the user will change it) @@ -1202,8 +1220,6 @@ zend_string *accel_make_persistent_key(zend_string *str) { const char *path = ZSTR_VAL(str); size_t path_length = ZSTR_LEN(str); - char *key; - int key_length; ZEND_ASSERT(GC_REFCOUNT(ZCG(key)) == 1); ZSTR_LEN(ZCG(key)) = 0; @@ -1220,9 +1236,8 @@ zend_string *accel_make_persistent_key(zend_string *str) /* pass */ } else { const char *include_path = NULL, *cwd = NULL; - int include_path_len = 0, cwd_len = 0; - zend_string *parent_script = NULL; - size_t parent_script_len = 0; + size_t include_path_len = 0, cwd_len = 0; + const zend_string *parent_script = NULL; if (EXPECTED(ZCG(cwd_key_len))) { cwd = ZCG(cwd_key); @@ -1257,7 +1272,7 @@ zend_string *accel_make_persistent_key(zend_string *str) } if (str) { char buf[32]; - char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); + const char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); cwd_len = ZCG(cwd_key_len) = buf + sizeof(buf) - 1 - res; cwd = ZCG(cwd_key); @@ -1301,7 +1316,7 @@ zend_string *accel_make_persistent_key(zend_string *str) } if (str) { char buf[32]; - char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); + const char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, STRTAB_STR_TO_POS(&ZCSG(interned_strings), str)); include_path_len = ZCG(include_path_key_len) = buf + sizeof(buf) - 1 - res; include_path = ZCG(include_path_key); @@ -1325,10 +1340,10 @@ zend_string *accel_make_persistent_key(zend_string *str) * since in itself, it may include colons (which we use to separate * different components of the key) */ - key = ZSTR_VAL(ZCG(key)); + char *key = ZSTR_VAL(ZCG(key)); memcpy(key, path, path_length); key[path_length] = ':'; - key_length = path_length + 1; + size_t key_length = path_length + 1; memcpy(key + key_length, cwd, cwd_len); key_length += cwd_len; @@ -1346,7 +1361,7 @@ zend_string *accel_make_persistent_key(zend_string *str) if (EXPECTED(EG(current_execute_data)) && EXPECTED((parent_script = zend_get_executed_filename_ex()) != NULL)) { - parent_script_len = ZSTR_LEN(parent_script); + size_t parent_script_len = ZSTR_LEN(parent_script); while (parent_script_len > 0) { --parent_script_len; if (IS_SLASH(ZSTR_VAL(parent_script)[parent_script_len])) { @@ -1500,7 +1515,7 @@ static void zend_accel_add_key(zend_string *key, zend_accel_hash_entry *bucket) } } -static zend_always_inline bool is_phar_file(zend_string *filename) +static zend_always_inline bool is_phar_file(const zend_string *filename) { return filename && ZSTR_LEN(filename) >= sizeof(".phar") && !memcmp(ZSTR_VAL(filename) + ZSTR_LEN(filename) - (sizeof(".phar")-1), ".phar", sizeof(".phar")-1) && @@ -1734,19 +1749,11 @@ static void zend_accel_set_auto_globals(int mask) ZCG(auto_globals_mask) |= mask; } -static void replay_warnings(uint32_t num_warnings, zend_error_info **warnings) { - for (uint32_t i = 0; i < num_warnings; i++) { - zend_error_info *warning = warnings[i]; - zend_error_zstr_at(warning->type, warning->filename, warning->lineno, warning->message); - } -} - static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handle, int type, zend_op_array **op_array_p) { zend_persistent_script *new_persistent_script; uint32_t orig_functions_count, orig_class_count; zend_op_array *orig_active_op_array; - zval orig_user_error_handler; zend_op_array *op_array; bool do_bailout = false; accel_time_t timestamp = 0; @@ -1814,13 +1821,6 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl orig_active_op_array = CG(active_op_array); orig_functions_count = EG(function_table)->nNumUsed; orig_class_count = EG(class_table)->nNumUsed; - ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler)); - - /* Override them with ours */ - ZVAL_UNDEF(&EG(user_error_handler)); - if (ZCG(accel_directives).record_warnings) { - zend_begin_record_errors(); - } zend_try { orig_compiler_options = CG(compiler_options); @@ -1850,13 +1850,12 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl /* Restore originals */ CG(active_op_array) = orig_active_op_array; - EG(user_error_handler) = orig_user_error_handler; - EG(record_errors) = 0; if (!op_array) { /* compilation failed */ - zend_free_recorded_errors(); if (do_bailout) { + EG(record_errors) = false; + zend_free_recorded_errors(); zend_bailout(); } return NULL; @@ -1871,10 +1870,6 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl zend_accel_move_user_functions(CG(function_table), CG(function_table)->nNumUsed - orig_functions_count, &new_persistent_script->script); zend_accel_move_user_classes(CG(class_table), CG(class_table)->nNumUsed - orig_class_count, &new_persistent_script->script); zend_accel_build_delayed_early_binding_list(new_persistent_script); - new_persistent_script->num_warnings = EG(num_errors); - new_persistent_script->warnings = EG(errors); - EG(num_errors) = 0; - EG(errors) = NULL; efree(op_array); /* we have valid persistent_script, so it's safe to free op_array */ @@ -1956,7 +1951,7 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int } } } - replay_warnings(persistent_script->num_warnings, persistent_script->warnings); + zend_emit_recorded_errors_ex(persistent_script->num_warnings, persistent_script->warnings); if (persistent_script->ping_auto_globals_mask & ~ZCG(auto_globals_mask)) { zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask & ~ZCG(auto_globals_mask)); @@ -1965,18 +1960,32 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int return zend_accel_load_script(persistent_script, 1); } + zend_begin_record_errors(); + persistent_script = opcache_compile_file(file_handle, type, &op_array); if (persistent_script) { + if (ZCG(accel_directives).record_warnings) { + persistent_script->num_warnings = EG(errors).size; + persistent_script->warnings = EG(errors).errors; + } + from_memory = false; persistent_script = cache_script_in_file_cache(persistent_script, &from_memory); + + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + return zend_accel_load_script(persistent_script, from_memory); } + zend_emit_recorded_errors(); + zend_free_recorded_errors(); + return op_array; } -static int check_persistent_script_access(zend_persistent_script *persistent_script) +static bool check_persistent_script_access(const zend_persistent_script *persistent_script) { char *phar_path, *ptr; if ((ZSTR_LEN(persistent_script->script.filename)num_warnings = EG(errors).size; + persistent_script->warnings = EG(errors).errors; + } + /* See GH-17246: we disable GC so that user code cannot be executed during the optimizer run. */ bool orig_gc_state = gc_enable(false); persistent_script = cache_script_in_shared_memory(persistent_script, key, &from_shared_memory); @@ -2191,6 +2207,8 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) if (!persistent_script) { SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); + zend_emit_recorded_errors(); + zend_free_recorded_errors(); return op_array; } if (from_shared_memory) { @@ -2204,6 +2222,16 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) persistent_script->dynamic_members.last_used = ZCG(request_time); SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); + + /* We may have switched to an existing persistent script that was persisted in + * the meantime. Make sure to use its warnings if available. */ + if (ZCG(accel_directives).record_warnings) { + EG(record_errors) = false; + zend_emit_recorded_errors_ex(persistent_script->num_warnings, persistent_script->warnings); + } else { + zend_emit_recorded_errors(); + } + zend_free_recorded_errors(); } else { #ifndef ZEND_WIN32 @@ -2246,7 +2274,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); - replay_warnings(persistent_script->num_warnings, persistent_script->warnings); + zend_emit_recorded_errors_ex(persistent_script->num_warnings, persistent_script->warnings); from_shared_memory = true; } @@ -2258,7 +2286,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) return zend_accel_load_script(persistent_script, from_shared_memory); } -static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_cache_find(zend_inheritance_cache_entry *entry, zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, bool *needs_autoload_ptr) +static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_cache_find(zend_inheritance_cache_entry *entry, const zend_class_entry *ce, const zend_class_entry *parent, zend_class_entry **traits_and_interfaces, bool *needs_autoload_ptr) { uint32_t i; @@ -2280,10 +2308,10 @@ static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_c } if (found && entry->dependencies) { for (i = 0; i < entry->dependencies_count; i++) { - zend_class_entry *ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); + const zend_class_entry *dependency_ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (ce != entry->dependencies[i].ce) { - if (!ce) { + if (dependency_ce != entry->dependencies[i].ce) { + if (!dependency_ce) { needs_autoload = true; } else { found = false; @@ -2305,7 +2333,6 @@ static zend_always_inline zend_inheritance_cache_entry* zend_accel_inheritance_c static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces) { - uint32_t i; bool needs_autoload; zend_inheritance_cache_entry *entry = ce->inheritance_cache; @@ -2313,7 +2340,7 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, entry = zend_accel_inheritance_cache_find(entry, ce, parent, traits_and_interfaces, &needs_autoload); if (entry) { if (!needs_autoload) { - replay_warnings(entry->num_warnings, entry->warnings); + zend_emit_recorded_errors_ex(entry->num_warnings, entry->warnings); if (ZCSG(map_ptr_last) > CG(map_ptr_last)) { zend_map_ptr_extend(ZCSG(map_ptr_last)); } @@ -2324,10 +2351,10 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, return ce; } - for (i = 0; i < entry->dependencies_count; i++) { - zend_class_entry *ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, 0); + for (uint32_t i = 0; i < entry->dependencies_count; i++) { + const zend_class_entry *dependency_ce = zend_lookup_class_ex(entry->dependencies[i].name, NULL, 0); - if (ce == NULL) { + if (dependency_ce == NULL) { return NULL; } } @@ -2392,7 +2419,7 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, } ZCG(current_persistent_script) = &dummy; zend_persist_class_entry_calc(ce); - zend_persist_warnings_calc(EG(num_errors), EG(errors)); + zend_persist_warnings_calc(EG(errors).size, EG(errors).errors); size = dummy.size; zend_shared_alloc_clear_xlat_table(); @@ -2462,14 +2489,11 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce, JIT_G(on) = jit_on_old; #endif - entry->num_warnings = EG(num_errors); - entry->warnings = zend_persist_warnings(EG(num_errors), EG(errors)); + entry->num_warnings = EG(errors).size; + entry->warnings = zend_persist_warnings(EG(errors).size, EG(errors).errors); entry->next = proto->inheritance_cache; proto->inheritance_cache = entry; - EG(num_errors) = 0; - EG(errors) = NULL; - ZCSG(map_ptr_last) = CG(map_ptr_last); zend_shared_alloc_destroy_xlat_table(); @@ -2559,7 +2583,7 @@ static zend_string* persistent_zend_resolve_path(zend_string *filename) /* lookup by "not-real" path */ key = accel_make_persistent_key(filename); if (key) { - zend_accel_hash_entry *bucket = zend_accel_hash_find_entry(&ZCSG(hash), key); + const zend_accel_hash_entry *bucket = zend_accel_hash_find_entry(&ZCSG(hash), key); if (bucket != NULL) { zend_persistent_script *persistent_script = (zend_persistent_script *)bucket->data; if (!persistent_script->corrupted) { @@ -2838,39 +2862,12 @@ static void zps_startup_failure(const char *reason, const char *api_reason, int zend_llist_del_element(&zend_extensions, NULL, (int (*)(void *, void *))cb); } -static inline zend_result accel_find_sapi(void) +/* Return whether we are running a CLI (Command LIne) SAPI for which Opcache is + * disabled when `opcache.enable_cli=0` */ +static inline bool accel_sapi_is_cli(void) { - static const char *supported_sapis[] = { - "apache", - "fastcgi", - "cli-server", - "cgi-fcgi", - "fpm-fcgi", - "fpmi-fcgi", - "apache2handler", - "litespeed", - "uwsgi", - "fuzzer", - "frankenphp", - "ngx-php", - NULL - }; - const char **sapi_name; - - if (sapi_module.name) { - for (sapi_name = supported_sapis; *sapi_name; sapi_name++) { - if (strcmp(sapi_module.name, *sapi_name) == 0) { - return SUCCESS; - } - } - if (ZCG(accel_directives).enable_cli && ( - strcmp(sapi_module.name, "cli") == 0 - || strcmp(sapi_module.name, "phpdbg") == 0)) { - return SUCCESS; - } - } - - return FAILURE; + return strcmp(sapi_module.name, "cli") == 0 + || strcmp(sapi_module.name, "phpdbg") == 0; } static zend_result zend_accel_init_shm(void) @@ -2967,9 +2964,6 @@ static zend_result zend_accel_init_shm(void) static void accel_globals_ctor(zend_accel_globals *accel_globals) { -#if defined(COMPILE_DL_OPCACHE) && defined(ZTS) - ZEND_TSRMLS_CACHE_UPDATE(); -#endif memset(accel_globals, 0, sizeof(zend_accel_globals)); accel_globals->key = zend_string_alloc(ZCG_KEY_LEN, true); GC_MAKE_PERSISTENT_LOCAL(accel_globals->key); @@ -3000,10 +2994,22 @@ static void accel_globals_dtor(zend_accel_globals *accel_globals) # include # define MAP_HUGETLB MAP_ALIGNED_SUPER # endif +# if __has_include() +# include +# endif +# if __has_include() +# include +# endif # endif -# if defined(MAP_HUGETLB) || defined(MADV_HUGEPAGE) -static zend_result accel_remap_huge_pages(void *start, size_t size, size_t real_size, const char *name, size_t offset) +# define ZEND_HUGE_PAGE_SIZE (2UL * 1024 * 1024) + +# if (defined(__linux__) || defined(__FreeBSD__)) && (defined(MAP_HUGETLB) || defined(MADV_HUGEPAGE)) && defined(HAVE_ATTRIBUTE_ALIGNED) && defined(HAVE_ATTRIBUTE_SECTION) && __has_include() && __has_include() +static zend_result +__attribute__((section(".remap_stub"))) +__attribute__((aligned(ZEND_HUGE_PAGE_SIZE))) +zend_never_inline +accel_remap_huge_pages(void *start, size_t size, size_t real_size) { void *ret = MAP_FAILED; void *mem; @@ -3056,94 +3062,113 @@ static zend_result accel_remap_huge_pages(void *start, size_t size, size_t real_ // Given the MAP_FIXED flag the address can never diverge ZEND_ASSERT(ret == start); - zend_mmap_set_name(start, size, "zend_huge_code_pages"); + memcpy(start, mem, real_size); mprotect(start, size, PROT_READ | PROT_EXEC); + zend_mmap_set_name(start, size, "zend_huge_code_pages"); munmap(mem, size); return SUCCESS; } -static void accel_move_code_to_huge_pages(void) -{ +static int accel_dl_iterate_phdr_callback(struct dl_phdr_info *info, size_t size, void *data) { + if (info->dlpi_name == NULL || strcmp(info->dlpi_name, "") == 0) { + *((uintptr_t*)data) = info->dlpi_addr; + return 1; + } + return 0; +} + +static zend_result accel_find_program_section(ElfW(Shdr) *section) { + + uintptr_t base_addr; + if (dl_iterate_phdr(accel_dl_iterate_phdr_callback, &base_addr) != 1) { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": opcache.huge_code_pages: executable base address not found"); + return FAILURE; + } + #if defined(__linux__) - FILE *f; - long unsigned int huge_page_size = 2 * 1024 * 1024; - - f = fopen("/proc/self/maps", "r"); - if (f) { - long unsigned int start, end, offset, inode; - char perm[5], dev[10], name[MAXPATHLEN]; - int ret; - extern char *__progname; - char buffer[MAXPATHLEN]; - - while (fgets(buffer, MAXPATHLEN, f)) { - ret = sscanf(buffer, "%lx-%lx %4s %lx %9s %lu %s\n", &start, &end, perm, &offset, dev, &inode, name); - if (ret >= 6) { - /* try to find the php text segment and map it into huge pages - Lines without 'name' are going to be skipped */ - if (ret > 6 && perm[0] == 'r' && perm[1] == '-' && perm[2] == 'x' && name[0] == '/' \ - && strstr(name, __progname)) { - long unsigned int seg_start = ZEND_MM_ALIGNED_SIZE_EX(start, huge_page_size); - long unsigned int seg_end = (end & ~(huge_page_size-1L)); - long unsigned int real_end; - - ret = fscanf(f, "%lx-", &start); - if (ret == 1 && start == seg_end + huge_page_size) { - real_end = end; - seg_end = start; - } else { - real_end = seg_end; - } + FILE *f = fopen("/proc/self/exe", "r"); +#elif defined(__FreeBSD__) + char path[4096]; + int mib[4]; + size_t len = sizeof(path); - if (seg_end > seg_start) { - zend_accel_error(ACCEL_LOG_DEBUG, "remap to huge page %lx-%lx %s \n", seg_start, seg_end, name); - accel_remap_huge_pages((void*)seg_start, seg_end - seg_start, real_end - seg_start, name, offset + seg_start - start); - } - break; - } - } - } + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; /* Current process */ + + if (sysctl(mib, 4, path, &len, NULL, 0) == -1) { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": opcache.huge_code_pages: sysctl(KERN_PROC_PATHNAME) failed: %s (%d)", + strerror(errno), errno); + return FAILURE; + } + + FILE *f = fopen(path, "r"); +#endif + if (!f) { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": opcache.huge_code_pages: fopen(/proc/self/exe) failed: %s (%d)", + strerror(errno), errno); + return FAILURE; + } + + /* Read ELF header */ + ElfW(Ehdr) ehdr; + if (!fread(&ehdr, sizeof(ehdr), 1, f)) { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": opcache.huge_code_pages: fread() failed: %s (%d)", + strerror(errno), errno); fclose(f); + return FAILURE; } -#elif defined(__FreeBSD__) - size_t s = 0; - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()}; - long unsigned int huge_page_size = 2 * 1024 * 1024; - if (sysctl(mib, 4, NULL, &s, NULL, 0) == 0) { - s = s * 4 / 3; - void *addr = mmap(NULL, s, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); - if (addr != MAP_FAILED) { - if (sysctl(mib, 4, addr, &s, NULL, 0) == 0) { - uintptr_t start = (uintptr_t)addr; - uintptr_t end = start + s; - while (start < end) { - struct kinfo_vmentry *entry = (struct kinfo_vmentry *)start; - size_t sz = entry->kve_structsize; - if (sz == 0) { - break; - } - int permflags = entry->kve_protection; - if ((permflags & KVME_PROT_READ) && !(permflags & KVME_PROT_WRITE) && - (permflags & KVME_PROT_EXEC) && entry->kve_path[0] != '\0') { - long unsigned int seg_start = ZEND_MM_ALIGNED_SIZE_EX(start, huge_page_size); - long unsigned int seg_end = (end & ~(huge_page_size-1L)); - if (seg_end > seg_start) { - zend_accel_error(ACCEL_LOG_DEBUG, "remap to huge page %lx-%lx %s \n", seg_start, seg_end, entry->kve_path); - accel_remap_huge_pages((void*)seg_start, seg_end - seg_start, seg_end - seg_start, entry->kve_path, entry->kve_offset + seg_start - start); - // First relevant segment found is our binary - break; - } - } - start += sz; - } - } - munmap(addr, s); + + /* Read section headers */ + ElfW(Shdr) shdrs[ehdr.e_shnum]; + if (fseek(f, ehdr.e_shoff, SEEK_SET) != 0) { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": opcache.huge_code_pages: fseek() failed: %s (%d)", + strerror(errno), errno); + fclose(f); + return FAILURE; + } + if (fread(shdrs, sizeof(shdrs[0]), ehdr.e_shnum, f) != ehdr.e_shnum) { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": opcache.huge_code_pages: fread() failed: %s (%d)", + strerror(errno), errno); + fclose(f); + return FAILURE; + } + + fclose(f); + + /* Find the program section */ + for (ElfW(Half) idx = 0; idx < ehdr.e_shnum; idx++) { + ElfW(Shdr) *sh = &shdrs[idx]; + uintptr_t start = (uintptr_t)sh->sh_addr + base_addr; + zend_accel_error(ACCEL_LOG_DEBUG, "considering section %016" PRIxPTR "-%016" PRIxPTR " vs %016" PRIxPTR "\n", start, start + sh->sh_size, (uintptr_t)accel_find_program_section); + if ((uintptr_t)accel_find_program_section >= start && (uintptr_t)accel_find_program_section < start + sh->sh_size) { + *section = *sh; + section->sh_addr = (ElfW(Addr))start; + return SUCCESS; } } -#endif + + return FAILURE; +} + +static void accel_move_code_to_huge_pages(void) +{ + ElfW(Shdr) section; + if (accel_find_program_section(§ion) == FAILURE) { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": opcache.huge_code_pages: program section not found"); + return; + } + + uintptr_t start = ZEND_MM_ALIGNED_SIZE_EX(section.sh_addr, ZEND_HUGE_PAGE_SIZE); + uintptr_t end = (section.sh_addr + section.sh_size) & ~(ZEND_HUGE_PAGE_SIZE-1UL); + if (end > start) { + zend_accel_error(ACCEL_LOG_DEBUG, "remap to huge page %" PRIxPTR "-%" PRIxPTR "\n", start, end); + accel_remap_huge_pages((void*)start, end - start, end - start); + } } # else static void accel_move_code_to_huge_pages(void) @@ -3154,10 +3179,15 @@ static void accel_move_code_to_huge_pages(void) # endif /* defined(MAP_HUGETLB) || defined(MADV_HUGEPAGE) */ #endif /* HAVE_HUGE_CODE_PAGES */ +void start_accel_extension(void) +{ + zend_register_extension(&opcache_extension_entry, NULL); +} + static int accel_startup(zend_extension *extension) { #ifdef ZTS - accel_globals_id = ts_allocate_id(&accel_globals_id, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); + accel_globals_id = ts_allocate_fast_id(&accel_globals_id, &accel_globals_offset, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); #else accel_globals_ctor(&accel_globals); #endif @@ -3172,11 +3202,7 @@ static int accel_startup(zend_extension *extension) # endif #endif - if (start_accel_module() == FAILURE) { - accel_startup_ok = false; - zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": module registration failed!"); - return FAILURE; - } + zend_accel_register_ini_entries(); #ifdef ZEND_WIN32 if (UNEXPECTED(accel_gen_uname_id() == FAILURE)) { @@ -3195,15 +3221,9 @@ static int accel_startup(zend_extension *extension) } #endif - /* no supported SAPI found - disable acceleration and stop initialization */ - if (accel_find_sapi() == FAILURE) { + if (!ZCG(accel_directives).enable_cli && accel_sapi_is_cli()) { accel_startup_ok = false; - if (!ZCG(accel_directives).enable_cli && - strcmp(sapi_module.name, "cli") == 0) { - zps_startup_failure("Opcode Caching is disabled for CLI", NULL, accelerator_remove_cb); - } else { - zps_startup_failure("Opcode Caching is only supported in Apache, FPM, FastCGI, FrankenPHP, LiteSpeed and uWSGI SAPIs", NULL, accelerator_remove_cb); - } + zps_startup_failure("Opcode Caching is disabled for CLI", NULL, accelerator_remove_cb); return SUCCESS; } @@ -3272,6 +3292,12 @@ static zend_result accel_post_startup(void) accel_startup_ok = false; zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - probably not enough shared memory."); return SUCCESS; + case NO_SHM_BACKEND: + zend_accel_error(ACCEL_LOG_INFO, "Opcode Caching is disabled: No available SHM backend. Set opcache.enable=0 to hide this message."); + zps_startup_failure("No available SHM backend", NULL, accelerator_remove_cb); + /* Do not abort PHP startup */ + return SUCCESS; + case SUCCESSFULLY_REATTACHED: #ifdef HAVE_JIT reattached = true; @@ -3288,7 +3314,6 @@ static zend_result accel_post_startup(void) accel_startup_ok = false; zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - cannot reattach to exiting shared memory."); return SUCCESS; - break; #if ENABLE_FILE_CACHE_FALLBACK case ALLOC_FALLBACK: zend_shared_alloc_lock(); @@ -3296,7 +3321,6 @@ static zend_result accel_post_startup(void) fallback_process = true; zend_shared_alloc_unlock(); goto file_cache_fallback; - break; #endif } @@ -3507,6 +3531,8 @@ void accel_shutdown(void) if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), "include_path", sizeof("include_path")-1)) != NULL) { ini_entry->on_modify = orig_include_path_on_modify; } + + accel_startup_ok = false; } void zend_accel_schedule_restart(zend_accel_restart_reason reason) @@ -3612,7 +3638,7 @@ static void preload_shutdown(void) if (EG(function_table)) { ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(function_table), zv) { - zend_function *func = Z_PTR_P(zv); + const zend_function *func = Z_PTR_P(zv); if (func->type == ZEND_INTERNAL_FUNCTION) { break; } @@ -3621,7 +3647,7 @@ static void preload_shutdown(void) if (EG(class_table)) { ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) { - zend_class_entry *ce = Z_PTR_P(zv); + const zend_class_entry *ce = Z_PTR_P(zv); if (ce->type == ZEND_INTERNAL_CLASS && Z_TYPE_P(zv) != IS_ALIAS_PTR) { break; } @@ -3648,7 +3674,7 @@ static void preload_restart(void) } } -static size_t preload_try_strip_filename(zend_string *filename) { +static size_t preload_try_strip_filename(const zend_string *filename) { /*FIXME: better way to handle eval()'d code? see COMPILED_STRING_DESCRIPTION_FORMAT */ if (ZSTR_LEN(filename) > sizeof(" eval()'d code") && *(ZSTR_VAL(filename) + ZSTR_LEN(filename) - sizeof(" eval()'d code")) == ':') { @@ -3769,17 +3795,17 @@ static void preload_sort_classes(void *base, size_t count, size_t siz, compare_f Bucket *b2; Bucket *end = b1 + count; Bucket tmp; - zend_class_entry *ce, *p; + const zend_class_entry *ce, *p; while (b1 < end) { try_again: - ce = (zend_class_entry*)Z_PTR(b1->val); + ce = Z_PTR(b1->val); if (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) { p = ce->parent; if (p->type == ZEND_USER_CLASS) { b2 = b1 + 1; while (b2 < end) { - if (p == Z_PTR(b2->val)) { + if (p == Z_PTR(b2->val)) { tmp = *b1; *b1 = *b2; *b2 = tmp; @@ -3796,7 +3822,7 @@ static void preload_sort_classes(void *base, size_t count, size_t siz, compare_f if (p->type == ZEND_USER_CLASS) { b2 = b1 + 1; while (b2 < end) { - if (p == Z_PTR(b2->val)) { + if (p == Z_PTR(b2->val)) { tmp = *b1; *b1 = *b2; *b2 = tmp; @@ -3822,7 +3848,7 @@ static zend_result preload_resolve_deps(preload_error *error, const zend_class_e if (ce->parent_name) { zend_string *key = zend_string_tolower(ce->parent_name); - zend_class_entry *parent = zend_hash_find_ptr(EG(class_table), key); + const zend_class_entry *parent = zend_hash_find_ptr(EG(class_table), key); zend_string_release(key); if (!parent) { error->kind = "Unknown parent "; @@ -3833,7 +3859,7 @@ static zend_result preload_resolve_deps(preload_error *error, const zend_class_e if (ce->num_interfaces) { for (uint32_t i = 0; i < ce->num_interfaces; i++) { - zend_class_entry *interface = + const zend_class_entry *interface = zend_hash_find_ptr(EG(class_table), ce->interface_names[i].lc_name); if (!interface) { error->kind = "Unknown interface "; @@ -3845,7 +3871,7 @@ static zend_result preload_resolve_deps(preload_error *error, const zend_class_e if (ce->num_traits) { for (uint32_t i = 0; i < ce->num_traits; i++) { - zend_class_entry *trait = + const zend_class_entry *trait = zend_hash_find_ptr(EG(class_table), ce->trait_names[i].lc_name); if (!trait) { error->kind = "Unknown trait "; @@ -3888,10 +3914,9 @@ static bool preload_try_resolve_constants(zend_class_entry *ce) ce->ce_flags &= ~ZEND_ACC_HAS_AST_CONSTANTS; } if (ce->default_properties_count) { - uint32_t i; bool resolved = true; - for (i = 0; i < ce->default_properties_count; i++) { + for (uint32_t i = 0; i < ce->default_properties_count; i++) { zend_property_info *prop = ce->properties_info_table[i]; if (!prop) { continue; @@ -3951,7 +3976,7 @@ static void preload_error_cb(int type, zend_string *error_filename, const uint32 static void preload_remove_declares(zend_op_array *op_array) { zend_op *opline = op_array->opcodes; - zend_op *end = opline + op_array->last; + const zend_op *end = opline + op_array->last; uint32_t skip_dynamic_func_count = 0; zend_string *key; zend_op_array *func; @@ -4096,9 +4121,9 @@ static void preload_link(void) /* Remember the last error. */ zend_error_cb = orig_error_cb; EG(record_errors) = false; - ZEND_ASSERT(EG(num_errors) > 0); - zend_hash_update_ptr(&errors, key, EG(errors)[EG(num_errors)-1]); - EG(num_errors)--; + ZEND_ASSERT(EG(errors).size > 0); + zend_hash_update_ptr(&errors, key, EG(errors).errors[EG(errors).size-1]); + EG(errors).size--; } zend_end_try(); CG(in_compilation) = false; CG(compiled_filename) = NULL; @@ -4196,6 +4221,24 @@ static void preload_link(void) preload_remove_declares(op_array); } } ZEND_HASH_FOREACH_END(); + + if (ce->num_hooked_props > 0) { + zend_property_info *info; + + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, info) { + if (info->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (info->hooks[i]) { + op_array = &info->hooks[i]->op_array; + ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION); + if (!(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { + preload_remove_declares(op_array); + } + } + } + } + } ZEND_HASH_FOREACH_END(); + } } ZEND_HASH_FOREACH_END(); } @@ -4224,7 +4267,7 @@ static void preload_remove_empty_includes(void) if (script->empty) { bool empty = true; zend_op *opline = script->script.main_op_array.opcodes; - zend_op *end = opline + script->script.main_op_array.last; + const zend_op *end = opline + script->script.main_op_array.last; while (opline < end) { if (opline->opcode == ZEND_INCLUDE_OR_EVAL && @@ -4265,7 +4308,7 @@ static void preload_remove_empty_includes(void) /* remove empty includes */ ZEND_HASH_MAP_FOREACH_PTR(preload_scripts, script) { zend_op *opline = script->script.main_op_array.opcodes; - zend_op *end = opline + script->script.main_op_array.last; + const zend_op *end = opline + script->script.main_op_array.last; while (opline < end) { if (opline->opcode == ZEND_INCLUDE_OR_EVAL && @@ -4276,7 +4319,7 @@ static void preload_remove_empty_includes(void) zend_string *resolved_path = preload_resolve_path(Z_STR_P(RT_CONSTANT(opline, opline->op1))); if (resolved_path) { - zend_persistent_script *incl = zend_hash_find_ptr(preload_scripts, resolved_path); + const zend_persistent_script *incl = zend_hash_find_ptr(preload_scripts, resolved_path); if (incl && incl->empty && opline->result_type == IS_UNUSED) { MAKE_NOP(opline); } else { @@ -4294,9 +4337,8 @@ static void preload_remove_empty_includes(void) } ZEND_HASH_FOREACH_END(); } -static void preload_register_trait_methods(zend_class_entry *ce) { +static void preload_register_trait_methods(const zend_class_entry *ce) { zend_op_array *op_array; - zend_property_info *info; ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { if (!(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { @@ -4306,7 +4348,7 @@ static void preload_register_trait_methods(zend_class_entry *ce) { } ZEND_HASH_FOREACH_END(); if (ce->num_hooked_props > 0) { - ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, info) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, zend_property_info *info) { if (info->hooks) { for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { if (info->hooks[i]) { @@ -4328,23 +4370,25 @@ static void preload_fix_trait_op_array(zend_op_array *op_array) return; } - zend_op_array *orig_op_array = zend_shared_alloc_get_xlat_entry(op_array->refcount); + const zend_op_array *orig_op_array = zend_shared_alloc_get_xlat_entry(op_array->refcount); ZEND_ASSERT(orig_op_array && "Must be in xlat table"); zend_string *function_name = op_array->function_name; zend_class_entry *scope = op_array->scope; uint32_t fn_flags = op_array->fn_flags; + uint32_t fn_flags2 = op_array->fn_flags2; zend_function *prototype = op_array->prototype; HashTable *ht = op_array->static_variables; *op_array = *orig_op_array; op_array->function_name = function_name; op_array->scope = scope; op_array->fn_flags = fn_flags; + op_array->fn_flags2 = fn_flags2; op_array->prototype = prototype; op_array->static_variables = ht; } -static void preload_fix_trait_methods(zend_class_entry *ce) +static void preload_fix_trait_methods(const zend_class_entry *ce) { zend_op_array *op_array; @@ -4369,7 +4413,7 @@ static void preload_fix_trait_methods(zend_class_entry *ce) static void preload_optimize(zend_persistent_script *script) { - zend_class_entry *ce; + const zend_class_entry *ce; zend_persistent_script *tmp_script; zend_shared_alloc_init_xlat_table(); @@ -4466,10 +4510,10 @@ static zend_persistent_script* preload_script_in_shared_memory(zend_persistent_s static void preload_load(size_t orig_map_ptr_static_last) { /* Load into process tables */ - zend_script *script = &ZCSG(preload_script)->script; + const zend_script *script = &ZCSG(preload_script)->script; if (zend_hash_num_elements(&script->function_table)) { Bucket *p = script->function_table.arData; - Bucket *end = p + script->function_table.nNumUsed; + const Bucket *end = p + script->function_table.nNumUsed; zend_hash_extend(CG(function_table), CG(function_table)->nNumUsed + script->function_table.nNumUsed, 0); @@ -4480,7 +4524,7 @@ static void preload_load(size_t orig_map_ptr_static_last) if (zend_hash_num_elements(&script->class_table)) { Bucket *p = script->class_table.arData; - Bucket *end = p + script->class_table.nNumUsed; + const Bucket *end = p + script->class_table.nNumUsed; zend_hash_extend(CG(class_table), CG(class_table)->nNumUsed + script->class_table.nNumUsed, 0); @@ -4489,16 +4533,6 @@ static void preload_load(size_t orig_map_ptr_static_last) } } - if (EG(zend_constants)) { - EG(persistent_constants_count) = EG(zend_constants)->nNumUsed; - } - if (EG(function_table)) { - EG(persistent_functions_count) = EG(function_table)->nNumUsed; - } - if (EG(class_table)) { - EG(persistent_classes_count) = EG(class_table)->nNumUsed; - } - size_t old_map_ptr_last = CG(map_ptr_last); if (zend_map_ptr_static_last != ZCSG(map_ptr_static_last) || old_map_ptr_last != ZCSG(map_ptr_last)) { CG(map_ptr_last) = ZCSG(map_ptr_last); @@ -4537,6 +4571,39 @@ static void preload_load(size_t orig_map_ptr_static_last) } } +#if HAVE_JIT +static void zend_accel_clear_call_graph_ptrs(const zend_op_array *op_array) +{ + ZEND_ASSERT(ZEND_USER_CODE(op_array->type)); + zend_func_info *info = ZEND_FUNC_INFO(op_array); + if (info) { + info->caller_info = NULL; + info->callee_info = NULL; + } +} + +static void accel_reset_arena_info(const zend_persistent_script *script) +{ + const zend_op_array *op_array; + zend_class_entry *ce; + + zend_accel_clear_call_graph_ptrs(&script->script.main_op_array); + ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) { + zend_accel_clear_call_graph_ptrs(op_array); + } ZEND_HASH_FOREACH_END(); + ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { + if (op_array->scope == ce + && op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) + && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { + zend_accel_clear_call_graph_ptrs(op_array); + } + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); +} +#endif + static zend_result accel_preload(const char *config, bool in_child) { zend_file_handle file_handle; @@ -4583,7 +4650,6 @@ static zend_result accel_preload(const char *config, bool in_child) zend_destroy_file_handle(&file_handle); if (op_array) { zend_execute(op_array, NULL); - zend_exception_restore(); if (UNEXPECTED(EG(exception))) { if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { zend_user_exception_handler(); @@ -4735,6 +4801,12 @@ static zend_result accel_preload(const char *config, bool in_child) preload_load(orig_map_ptr_static_last); + /* Update persistent counts, as shutdown will discard anything past + * that, and these tables are aliases to global ones at this point. */ + EG(persistent_functions_count) = EG(function_table)->nNumUsed; + EG(persistent_classes_count) = EG(class_table)->nNumUsed; + EG(persistent_constants_count) = EG(zend_constants)->nNumUsed; + /* Store individual scripts with unlinked classes */ HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); @@ -4749,6 +4821,18 @@ static zend_result accel_preload(const char *config, bool in_child) } ZEND_HASH_FOREACH_END(); ZCSG(saved_scripts)[i] = NULL; +#if HAVE_JIT + /* During persisting, the JIT may trigger and fill in the call graph. + * The call graph info is allocated on the arena which will be gone after preloading. + * To prevent invalid accesses during normal requests, the arena data should be cleared. + * This has to be done after all scripts have been persisted because shared op arrays between + * scripts can change the call graph. */ + accel_reset_arena_info(ZCSG(preload_script)); + for (zend_persistent_script **scripts = ZCSG(saved_scripts); *scripts; scripts++) { + accel_reset_arena_info(*scripts); + } +#endif + zend_shared_alloc_save_state(); accel_interned_strings_save_state(); @@ -4811,6 +4895,8 @@ static zend_result accel_finish_startup_preload(bool in_child) bool old_reset_signals = SIGG(reset); #endif + ZCG(preloading) = true; + sapi_module.activate = NULL; sapi_module.deactivate = NULL; sapi_module.register_server_variables = NULL; @@ -4892,6 +4978,8 @@ static zend_result accel_finish_startup_preload(bool in_child) sapi_module.ub_write = orig_ub_write; sapi_module.flush = orig_flush; + ZCG(preloading) = false; + sapi_activate(); return ret; @@ -4958,6 +5046,7 @@ static zend_result accel_finish_startup_preload_subprocess(pid_t *pid) zend_accel_error(ACCEL_LOG_WARNING, "Preloading failed to setuid(%d)", pw->pw_uid); exit(1); } + php_child_init(); } return SUCCESS; @@ -5009,13 +5098,45 @@ static zend_result accel_finish_startup(void) exit(ret == SUCCESS ? 0 : 1); } else { /* parent */ - int status; +# ifdef HAVE_SIGPROCMASK + /* Interrupting the waitpid() call below with a signal would cause the + * process to exit. This is fine when the signal disposition is set to + * terminate the process, but not otherwise. + * When running the apache2handler, preloading is performed in the + * control process. SIGUSR1 and SIGHUP are used to tell the control + * process to restart children. Exiting when these signals are received + * would unexpectedly shutdown the server instead of restarting it. + * Block the USR1 and HUP signals from being delivered during the + * syscall when running the apache2handler SAPI, as these are not + * supposed to terminate the process. See GH-20051. */ + bool is_apache2handler = strcmp(sapi_module.name, "apache2handler") == 0; + sigset_t set, oldset; + if (is_apache2handler) { + if (sigemptyset(&set) + || sigaddset(&set, SIGUSR1) + || sigaddset(&set, SIGHUP)) { + ZEND_UNREACHABLE(); + } + if (sigprocmask(SIG_BLOCK, &set, &oldset)) { + ZEND_UNREACHABLE(); + } + } +# endif + int status; if (waitpid(pid, &status, 0) < 0) { zend_shared_alloc_unlock(); zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Preloading failed to waitpid(%d)", pid); } +# ifdef HAVE_SIGPROCMASK + if (is_apache2handler) { + if (sigprocmask(SIG_SETMASK, &oldset, NULL)) { + ZEND_UNREACHABLE(); + } + } +# endif + if (ZCSG(preload_script)) { preload_load(zend_map_ptr_static_last); } @@ -5037,12 +5158,12 @@ static void accel_activate(void) { } } -ZEND_EXT_API zend_extension zend_extension_entry = { +static zend_extension opcache_extension_entry = { ACCELERATOR_PRODUCT_NAME, /* name */ PHP_VERSION, /* version */ - "Zend Technologies", /* author */ - "http://www.zend.com/", /* URL */ - "Copyright (c)", /* copyright */ + "Zend by Perforce", /* author */ + "https://www.zend.com/", /* URL */ + "Copyright ©", /* copyright */ accel_startup, /* startup */ NULL, /* shutdown */ accel_activate, /* per-script activation */ diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 1bac9af9b8b7..91642e288d31 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -220,6 +218,7 @@ typedef struct _zend_accel_globals { #endif void *preloaded_internal_run_time_cache; size_t preloaded_internal_run_time_cache_size; + bool preloading; /* preallocated shared-memory block to save current script */ void *mem; zend_persistent_script *current_persistent_script; @@ -300,11 +299,9 @@ extern zend_accel_shared_globals *accel_shared_globals; #define ZCSG(element) (accel_shared_globals->element) #ifdef ZTS -# define ZCG(v) ZEND_TSRMG(accel_globals_id, zend_accel_globals *, v) +# define ZCG(v) ZEND_TSRMG_FAST(accel_globals_offset, zend_accel_globals *, v) extern int accel_globals_id; -# ifdef COMPILE_DL_OPCACHE -ZEND_TSRMLS_CACHE_EXTERN() -# endif +extern size_t accel_globals_offset; #else # define ZCG(v) (accel_globals.v) extern zend_accel_globals accel_globals; @@ -314,6 +311,7 @@ extern const char *zps_api_failure_reason; BEGIN_EXTERN_C() +void start_accel_extension(void); void accel_shutdown(void); ZEND_RINIT_FUNCTION(zend_accelerator); zend_result accel_post_deactivate(void); diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 index 8f6d5ab711b2..70138726c56e 100644 --- a/ext/opcache/config.m4 +++ b/ext/opcache/config.m4 @@ -1,9 +1,3 @@ -PHP_ARG_ENABLE([opcache], - [whether to enable Zend OPcache support], - [AS_HELP_STRING([--disable-opcache], - [Disable Zend OPcache support])], - [yes]) - PHP_ARG_ENABLE([huge-code-pages], [whether to enable copying PHP CODE pages into HUGE PAGES], [AS_HELP_STRING([--disable-huge-code-pages], @@ -25,89 +19,93 @@ PHP_ARG_WITH([capstone], [no], [no]) -if test "$PHP_OPCACHE" != "no"; then - dnl Always build as shared extension. - ext_shared=yes +AS_VAR_IF([PHP_HUGE_CODE_PAGES], [yes], + [AC_DEFINE([HAVE_HUGE_CODE_PAGES], [1], + [Define to 1 to enable copying PHP CODE pages into HUGE PAGES.])]) + +AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ + AS_CASE([$host_cpu], + [[i[34567]86*|x86*|aarch64|amd64]], [], + [ + AC_MSG_WARN([JIT not supported by host architecture]) + PHP_OPCACHE_JIT=no + ]) + + if test "$host_vendor" = "apple" && test "$host_cpu" = "aarch64" && test "$PHP_THREAD_SAFETY" = "yes"; then + AC_MSG_WARN([JIT not supported on Apple Silicon with ZTS]) + PHP_OPCACHE_JIT=no + fi +]) + +AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ + AC_DEFINE([HAVE_JIT], [1], [Define to 1 to enable JIT.]) + ZEND_JIT_SRC=m4_normalize([" + jit/ir/ir_cfg.c + jit/ir/ir_check.c + jit/ir/ir_dump.c + jit/ir/ir_emit.c + jit/ir/ir_gcm.c + jit/ir/ir_gdb.c + jit/ir/ir_patch.c + jit/ir/ir_perf.c + jit/ir/ir_ra.c + jit/ir/ir_save.c + jit/ir/ir_sccp.c + jit/ir/ir_strtab.c + jit/ir/ir.c + jit/zend_jit_vm_helpers.c + jit/zend_jit.c + "]) + + dnl Find out which ABI we are using. + AS_CASE([$host_alias], + [x86_64-*-darwin*], [ + IR_TARGET=IR_TARGET_X64 + DASM_FLAGS="-D X64APPLE=1 -D X64=1" + DASM_ARCH="x86" + TLS_TARGET="darwin" + ], + [*x86_64*|amd64-*-freebsd*], [ + IR_TARGET=IR_TARGET_X64 + DASM_FLAGS="-D X64=1" + DASM_ARCH="x86" + TLS_TARGET="x86_64" + ], + [[i[34567]86*|x86*]], [ + IR_TARGET=IR_TARGET_X86 + DASM_ARCH="x86" + TLS_TARGET="x86" + ], + [aarch64*], [ + IR_TARGET=IR_TARGET_AARCH64 + DASM_ARCH="aarch64" + TLS_TARGET="aarch64" + ]) - AS_VAR_IF([PHP_HUGE_CODE_PAGES], [yes], - [AC_DEFINE([HAVE_HUGE_CODE_PAGES], [1], - [Define to 1 to enable copying PHP CODE pages into HUGE PAGES.])]) + AS_VAR_IF([PHP_CAPSTONE], [yes], + [PKG_CHECK_MODULES([CAPSTONE], [capstone >= 3.0.0], [ + AC_DEFINE([HAVE_CAPSTONE], [1], [Define to 1 if Capstone is available.]) + PHP_EVAL_LIBLINE([$CAPSTONE_LIBS]) + PHP_EVAL_INCLINE([$CAPSTONE_CFLAGS]) + ZEND_JIT_SRC="$ZEND_JIT_SRC jit/ir/ir_disasm.c" + ])]) - AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ - AS_CASE([$host_cpu], - [[i[34567]86*|x86*|aarch64|amd64]], [], - [ - AC_MSG_WARN([JIT not supported by host architecture]) - PHP_OPCACHE_JIT=no - ]) + PHP_SUBST([IR_TARGET]) + PHP_SUBST([DASM_FLAGS]) + PHP_SUBST([DASM_ARCH]) - if test "$host_vendor" = "apple" && test "$host_cpu" = "aarch64" && test "$PHP_THREAD_SAFETY" = "yes"; then - AC_MSG_WARN([JIT not supported on Apple Silicon with ZTS]) - PHP_OPCACHE_JIT=no - fi - ]) + JIT_CFLAGS="-I@ext_builddir@/jit/ir -D$IR_TARGET -DIR_PHP" + AS_VAR_IF([ZEND_DEBUG], [yes], [JIT_CFLAGS="$JIT_CFLAGS -DIR_DEBUG"]) - AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ - AC_DEFINE([HAVE_JIT], [1], [Define to 1 to enable JIT.]) - ZEND_JIT_SRC=m4_normalize([" - jit/ir/ir_cfg.c - jit/ir/ir_check.c - jit/ir/ir_dump.c - jit/ir/ir_emit.c - jit/ir/ir_gcm.c - jit/ir/ir_gdb.c - jit/ir/ir_patch.c - jit/ir/ir_perf.c - jit/ir/ir_ra.c - jit/ir/ir_save.c - jit/ir/ir_sccp.c - jit/ir/ir_strtab.c - jit/ir/ir.c - jit/zend_jit_vm_helpers.c - jit/zend_jit.c - "]) - - dnl Find out which ABI we are using. - AS_CASE([$host_alias], - [x86_64-*-darwin*], [ - IR_TARGET=IR_TARGET_X64 - DASM_FLAGS="-D X64APPLE=1 -D X64=1" - DASM_ARCH="x86" - ], - [*x86_64*|amd64-*-freebsd*], [ - IR_TARGET=IR_TARGET_X64 - DASM_FLAGS="-D X64=1" - DASM_ARCH="x86" - ], - [[i[34567]86*|x86*]], [ - IR_TARGET=IR_TARGET_X86 - DASM_ARCH="x86" - ], - [aarch64*], [ - IR_TARGET=IR_TARGET_AARCH64 - DASM_ARCH="aarch64" - ]) - - AS_VAR_IF([PHP_CAPSTONE], [yes], - [PKG_CHECK_MODULES([CAPSTONE], [capstone >= 3.0.0], [ - AC_DEFINE([HAVE_CAPSTONE], [1], [Define to 1 if Capstone is available.]) - PHP_EVAL_LIBLINE([$CAPSTONE_LIBS], [OPCACHE_SHARED_LIBADD]) - PHP_EVAL_INCLINE([$CAPSTONE_CFLAGS]) - ZEND_JIT_SRC="$ZEND_JIT_SRC jit/ir/ir_disasm.c" - ])]) - - PHP_SUBST([IR_TARGET]) - PHP_SUBST([DASM_FLAGS]) - PHP_SUBST([DASM_ARCH]) - - JIT_CFLAGS="-I@ext_builddir@/jit/ir -D$IR_TARGET -DIR_PHP" - AS_VAR_IF([ZEND_DEBUG], [yes], [JIT_CFLAGS="$JIT_CFLAGS -DIR_DEBUG"]) + AS_VAR_IF([PHP_THREAD_SAFETY], [yes], [ + ZEND_JIT_SRC="$ZEND_JIT_SRC jit/tls/zend_jit_tls_$TLS_TARGET.c" ]) +]) - AC_CHECK_FUNCS([mprotect shm_create_largepage]) +AC_CHECK_FUNCS([mprotect shm_create_largepage]) - AC_CACHE_CHECK([for sysvipc shared memory support], [php_cv_shm_ipc], - [AC_RUN_IFELSE([AC_LANG_SOURCE([ +AC_CACHE_CHECK([for sysvipc shared memory support], [php_cv_shm_ipc], + [AC_RUN_IFELSE([AC_LANG_SOURCE([ #include #include #include @@ -309,56 +307,60 @@ int main(void) { } return 0; }]])], - [php_cv_shm_mmap_posix=yes], - [php_cv_shm_mmap_posix=no], - [php_cv_shm_mmap_posix=no]) - ]) + [php_cv_shm_mmap_posix=yes], + [php_cv_shm_mmap_posix=no], + [php_cv_shm_mmap_posix=no]) ]) - LIBS=$LIBS_save +]) +LIBS=$LIBS_save + +AS_VAR_IF([php_cv_shm_mmap_posix], [yes], [ + AC_DEFINE([HAVE_SHM_MMAP_POSIX], [1], + [Define to 1 if you have the POSIX mmap() SHM support.]) + AS_CASE([$ac_cv_search_shm_open], ["none required"|no], [], + [PHP_EVAL_LIBLINE([$ac_cv_search_shm_open])]) +]) + +PHP_NEW_EXTENSION([opcache], m4_normalize([ + shared_alloc_mmap.c + shared_alloc_posix.c + shared_alloc_shm.c + zend_accelerator_api.c + zend_accelerator_blacklist.c + zend_accelerator_debug.c + zend_accelerator_hash.c + zend_accelerator_module.c + zend_accelerator_util_funcs.c + zend_file_cache.c + zend_persist_calc.c + zend_persist.c + zend_shared_alloc.c + ZendAccelerator.c + $ZEND_JIT_SRC + ]), + [no],, + [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],, + [yes]) - AS_VAR_IF([php_cv_shm_mmap_posix], [yes], [ - AC_DEFINE([HAVE_SHM_MMAP_POSIX], [1], - [Define to 1 if you have the POSIX mmap() SHM support.]) - AS_CASE([$ac_cv_search_shm_open], ["none required"|no], [], - [PHP_EVAL_LIBLINE([$ac_cv_search_shm_open], [OPCACHE_SHARED_LIBADD])]) - ]) +PHP_ADD_EXTENSION_DEP(opcache, date) +PHP_ADD_EXTENSION_DEP(opcache, pcre) - PHP_NEW_EXTENSION([opcache], m4_normalize([ - shared_alloc_mmap.c - shared_alloc_posix.c - shared_alloc_shm.c - zend_accelerator_blacklist.c - zend_accelerator_debug.c - zend_accelerator_hash.c - zend_accelerator_module.c - zend_accelerator_util_funcs.c - zend_file_cache.c - zend_persist_calc.c - zend_persist.c - zend_shared_alloc.c - ZendAccelerator.c - $ZEND_JIT_SRC - ]), - [$ext_shared],, - [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],, - [yes]) - - PHP_ADD_EXTENSION_DEP(opcache, date) - PHP_ADD_EXTENSION_DEP(opcache, pcre) - - if test "$php_cv_shm_ipc" != "yes" && test "$php_cv_shm_mmap_posix" != "yes" && test "$php_cv_shm_mmap_anon" != "yes"; then - AC_MSG_FAILURE(m4_text_wrap([ - No supported shared memory caching support was found when configuring - opcache. - ])) - fi +if test "$php_cv_shm_ipc" != "yes" && test "$php_cv_shm_mmap_posix" != "yes" && test "$php_cv_shm_mmap_anon" != "yes"; then + AC_MSG_WARN(m4_text_wrap([ + No supported shared memory caching support was found when configuring + opcache. Opcache will be disabled. + ])) +fi - AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ - PHP_ADD_BUILD_DIR([ - $ext_builddir/jit - $ext_builddir/jit/ir - ]) - PHP_ADD_MAKEFILE_FRAGMENT([$ext_srcdir/jit/Makefile.frag]) +AS_VAR_IF([PHP_OPCACHE_JIT], [yes], [ + PHP_ADD_BUILD_DIR([ + $ext_builddir/jit + $ext_builddir/jit/ir ]) - PHP_SUBST([OPCACHE_SHARED_LIBADD]) -fi + AS_VAR_IF([PHP_THREAD_SAFETY], [yes], [ + PHP_ADD_BUILD_DIR([$ext_builddir/jit/tls]) + ]) + PHP_ADD_MAKEFILE_FRAGMENT([$ext_srcdir/jit/Makefile.frag]) +]) + +PHP_INSTALL_HEADERS([ext/opcache], [zend_accelerator_api.h]) diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32 index fa89ca1f18a3..397fa1bdd87d 100644 --- a/ext/opcache/config.w32 +++ b/ext/opcache/config.w32 @@ -1,69 +1,73 @@ -ARG_ENABLE("opcache", "whether to enable Zend OPcache support", "yes"); ARG_ENABLE("opcache-jit", "whether to enable JIT (not supported for ARM64)", "yes"); +PHP_OPCACHE="yes"; -if (PHP_OPCACHE != "no") { +ZEND_EXTENSION('opcache', "\ + ZendAccelerator.c \ + zend_accelerator_api.c \ + zend_accelerator_blacklist.c \ + zend_accelerator_debug.c \ + zend_accelerator_hash.c \ + zend_accelerator_module.c \ + zend_accelerator_util_funcs.c \ + zend_persist.c \ + zend_persist_calc.c \ + zend_file_cache.c \ + zend_shared_alloc.c \ + shared_alloc_win32.c", false, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); - ZEND_EXTENSION('opcache', "\ - ZendAccelerator.c \ - zend_accelerator_blacklist.c \ - zend_accelerator_debug.c \ - zend_accelerator_hash.c \ - zend_accelerator_module.c \ - zend_accelerator_util_funcs.c \ - zend_persist.c \ - zend_persist_calc.c \ - zend_file_cache.c \ - zend_shared_alloc.c \ - shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +ADD_EXTENSION_DEP('opcache', 'date'); +ADD_EXTENSION_DEP('opcache', 'hash'); +ADD_EXTENSION_DEP('opcache', 'pcre'); - ADD_EXTENSION_DEP('opcache', 'date'); - ADD_EXTENSION_DEP('opcache', 'hash'); - ADD_EXTENSION_DEP('opcache', 'pcre'); +if (PHP_OPCACHE_JIT == "yes") { + if (TARGET_ARCH == 'arm64') { + WARNING("JIT not enabled; not yet supported for ARM64"); + } else if (CHECK_HEADER("ir/ir.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) { + var dasm_flags = (X64 ? "-D X64=1" : "") + (X64 ? " -D X64WIN=1" : "") + " -D WIN=1"; + var ir_target = (X64 ? "IR_TARGET_X64" : "IR_TARGET_X86"); + var ir_src = "ir_strtab.c ir_cfg.c ir_sccp.c ir_gcm.c ir_ra.c ir_save.c \ + ir_dump.c ir_check.c ir_patch.c"; - if (PHP_OPCACHE_JIT == "yes") { - if (TARGET_ARCH == 'arm64') { - WARNING("JIT not enabled; not yet supported for ARM64"); - } else if (CHECK_HEADER_ADD_INCLUDE("ir/ir.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) { - var dasm_flags = (X64 ? "-D X64=1" : "") + (X64 ? " -D X64WIN=1" : "") + " -D WIN=1"; - var ir_target = (X64 ? "IR_TARGET_X64" : "IR_TARGET_X86"); - var ir_src = "ir_strtab.c ir_cfg.c ir_sccp.c ir_gcm.c ir_ra.c ir_save.c \ - ir_dump.c ir_check.c ir_patch.c"; + DEFINE("IR_TARGET", ir_target); + DEFINE("DASM_FLAGS", dasm_flags); + DEFINE("DASM_ARCH", "x86"); + DEFINE("TLS_TARGET", "win"); - DEFINE("IR_TARGET", ir_target); - DEFINE("DASM_FLAGS", dasm_flags); - DEFINE("DASM_ARCH", "x86"); + AC_DEFINE('HAVE_JIT', 1, 'Define to 1 to enable JIT.'); - AC_DEFINE('HAVE_JIT', 1, 'Define to 1 to enable JIT.'); - - ADD_FLAG("CFLAGS_OPCACHE", "/I \"ext\\opcache\\jit\\ir\" /D "+ir_target+" /D IR_PHP"); - if (PHP_DEBUG == "yes") { - ADD_FLAG("CFLAGS_OPCACHE", "/D IR_DEBUG"); - } + ADD_FLAG("CFLAGS_OPCACHE", "/I \"ext\\opcache\\jit\\ir\" /D "+ir_target+" /D IR_PHP"); + if (PHP_DEBUG == "yes") { + ADD_FLAG("CFLAGS_OPCACHE", "/D IR_DEBUG"); + } - if (CHECK_HEADER_ADD_INCLUDE("capstone\\capstone.h", "CFLAGS_OPCACHE", PHP_OPCACHE+ ";" + PHP_PHP_BUILD + "\\include") && - CHECK_LIB("capstone.lib", "opcache", PHP_OPCACHE)) { - AC_DEFINE('HAVE_CAPSTONE', 1, 'Define to 1 if Capstone is available.'); - ir_src += " ir_disasm.c"; - } + if (CHECK_HEADER("capstone\\capstone.h", "CFLAGS_OPCACHE", PHP_OPCACHE+ ";" + PHP_PHP_BUILD + "\\include") && + CHECK_LIB("capstone.lib", "opcache", PHP_OPCACHE)) { + AC_DEFINE('HAVE_CAPSTONE', 1, 'Define to 1 if Capstone is available.'); + ir_src += " ir_disasm.c"; + } - ADD_MAKEFILE_FRAGMENT(configure_module_dirname + "\\jit\\Makefile.frag.w32"); + ADD_MAKEFILE_FRAGMENT(configure_module_dirname + "\\jit\\Makefile.frag.w32"); - ADD_SOURCES(configure_module_dirname + "\\jit", - "zend_jit.c zend_jit_vm_helpers.c", - "opcache", "ext\\opcache\\jit"); - ADD_SOURCES(configure_module_dirname + "\\jit\\ir", - "ir.c", "opcache", "ext\\opcache\\jit\\ir"); - ADD_SOURCES(configure_module_dirname + "\\jit\\ir", - "ir_emit.c", "opcache", "ext\\opcache\\jit\\ir"); - ADD_SOURCES(configure_module_dirname + "\\jit\\ir", - ir_src, "opcache", "ext\\opcache\\jit\\ir"); - } else { - WARNING("JIT not enabled, headers not found"); + ADD_SOURCES(configure_module_dirname + "\\jit", + "zend_jit.c zend_jit_vm_helpers.c", + "opcache", "ext\\opcache\\jit"); + if (PHP_ZTS == "yes") { + ADD_SOURCES(configure_module_dirname + "\\jit\\tls", + "zend_jit_tls_win.c", + "opcache", "ext\\opcache\\jit\\tls"); } + ADD_SOURCES(configure_module_dirname + "\\jit\\ir", + "ir.c", "opcache", "ext\\opcache\\jit\\ir"); + ADD_SOURCES(configure_module_dirname + "\\jit\\ir", + "ir_emit.c", "opcache", "ext\\opcache\\jit\\ir"); + ADD_SOURCES(configure_module_dirname + "\\jit\\ir", + ir_src, "opcache", "ext\\opcache\\jit\\ir"); + } else { + WARNING("JIT not enabled, headers not found"); } - - ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname); - } +ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname); + +PHP_INSTALL_HEADERS("ext/opcache", "zend_accelerator_api.h"); diff --git a/ext/opcache/jit/Dockerfile.arm64.example b/ext/opcache/jit/Dockerfile.arm64.example index e7b6a03b2db8..6665f4ab81b7 100644 --- a/ext/opcache/jit/Dockerfile.arm64.example +++ b/ext/opcache/jit/Dockerfile.arm64.example @@ -12,4 +12,4 @@ ADD . /php-src/ WORKDIR /php-src RUN ./buildconf # Compile a minimal debug build. --enable-debug adds runtime assertions and is slower than regular builds. -RUN ./configure --enable-debug --disable-all --enable-opcache && make clean && make -j$(nproc) +RUN ./configure --enable-debug --disable-all && make clean && make -j$(nproc) diff --git a/ext/opcache/jit/README.md b/ext/opcache/jit/README.md index 6ec58378acc7..c87c625e845b 100644 --- a/ext/opcache/jit/README.md +++ b/ext/opcache/jit/README.md @@ -76,7 +76,7 @@ export LDFLAGS=-L/usr/lib/i386-linux-gnu export CFLAGS='-m32' export CXXFLAGS='-m32' export PKG_CONFIG=/usr/bin/i686-linux-gnu-pkg-config -./configure --disable-all --enable-opcache --build=i686-pc-linux-gnu +./configure --disable-all --build=i686-pc-linux-gnu make -j$(nproc) ``` diff --git a/ext/opcache/jit/ir/.gitignore b/ext/opcache/jit/ir/.gitignore index 7a37a4fd0593..367a68671bc0 100644 --- a/ext/opcache/jit/ir/.gitignore +++ b/ext/opcache/jit/ir/.gitignore @@ -20,3 +20,6 @@ tests/**/*.log win32/vcpkg win32/build_* + +fuzz/build/ +fuzz/corpus/ diff --git a/ext/opcache/jit/ir/LICENSE b/ext/opcache/jit/ir/LICENSE index c43a12a770f8..340f9c37225f 100644 --- a/ext/opcache/jit/ir/LICENSE +++ b/ext/opcache/jit/ir/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2022 Zend by Perforce +Copyright (c) 2025 Dmitry Stogov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/ext/opcache/jit/ir/ir.c b/ext/opcache/jit/ir/ir.c index a9f55cc0e466..f6a0cb60af98 100644 --- a/ext/opcache/jit/ir/ir.c +++ b/ext/opcache/jit/ir/ir.c @@ -118,7 +118,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted { char buf[128]; - if (insn->op == IR_FUNC || insn->op == IR_SYM) { + if (insn->op == IR_FUNC || insn->op == IR_SYM || insn->op == IR_LABEL) { fprintf(f, "%s", ir_get_str(ctx, insn->val.name)); return; } else if (insn->op == IR_STR) { @@ -161,6 +161,8 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted case IR_CHAR: if (insn->val.c == '\\') { fprintf(f, "'\\\\'"); + } else if (insn->val.c == '\'') { + fprintf(f, "'\\\''"); } else if (insn->val.c >= ' ') { fprintf(f, "'%c'", insn->val.c); } else if (insn->val.c == '\t') { @@ -172,7 +174,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted } else if (insn->val.c == '\0') { fprintf(f, "'\\0'"); } else { - fprintf(f, "%u", insn->val.c); + fprintf(f, "%u", (unsigned char)insn->val.c); } break; case IR_I8: @@ -227,6 +229,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted #define ir_op_flag_d0 ir_op_flag_d #define ir_op_flag_d1 (ir_op_flag_d | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_d1X1 (ir_op_flag_d | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) +#define ir_op_flag_d1X2 (ir_op_flag_d | 1 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_d2 (ir_op_flag_d | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_d2C (ir_op_flag_d | IR_OP_FLAG_COMMUTATIVE | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_d3 (ir_op_flag_d | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) @@ -247,6 +250,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted #define ir_op_flag_S1X1 (ir_op_flag_S | 1 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_S2 (ir_op_flag_S | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_S2X1 (ir_op_flag_S | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) +#define ir_op_flag_S3 (ir_op_flag_S | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_SN (ir_op_flag_S | IR_OP_FLAG_VAR_INPUTS) #define ir_op_flag_E (IR_OP_FLAG_CONTROL|IR_OP_FLAG_BB_END) #define ir_op_flag_E1 (ir_op_flag_E | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) @@ -269,6 +273,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted #define ir_op_flag_s3 (ir_op_flag_s | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_x1 (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_CALL | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_x2 (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_CALL | 2 | (2 << IR_OP_FLAG_OPERANDS_SHIFT)) +#define ir_op_flag_x2X1 (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_CALL | 2 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_x3 (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_CALL | 3 | (3 << IR_OP_FLAG_OPERANDS_SHIFT)) #define ir_op_flag_xN (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_CALL | IR_OP_FLAG_VAR_INPUTS) #define ir_op_flag_a1 (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_ALLOC | 1 | (1 << IR_OP_FLAG_OPERANDS_SHIFT)) @@ -280,6 +285,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted #define ir_op_kind_src IR_OPND_CONTROL #define ir_op_kind_reg IR_OPND_CONTROL_DEP #define ir_op_kind_ret IR_OPND_CONTROL_REF +#define ir_op_kind_grd IR_OPND_CONTROL_GUARD #define ir_op_kind_str IR_OPND_STR #define ir_op_kind_num IR_OPND_NUM #define ir_op_kind_fld IR_OPND_STR @@ -287,6 +293,7 @@ void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted #define ir_op_kind_prb IR_OPND_PROB #define ir_op_kind_opt IR_OPND_PROB #define ir_op_kind_pro IR_OPND_PROTO +#define ir_op_kind_lbl IR_OPND_LABEL_REF #define _IR_OP_FLAGS(name, flags, op1, op2, op3) \ IR_OP_FLAGS(ir_op_flag_ ## flags, ir_op_kind_ ## op1, ir_op_kind_ ## op2, ir_op_kind_ ## op3), @@ -391,6 +398,8 @@ void ir_init(ir_ctx *ctx, uint32_t flags, ir_ref consts_limit, ir_ref insns_limi ctx->insns_limit = insns_limit; ctx->consts_count = -(IR_TRUE - 1); ctx->consts_limit = consts_limit; + ctx->const_hash = ctx->_const_hash; + ctx->const_hash_mask = IR_CONST_HASH_SIZE - 1; ctx->fold_cse_limit = IR_UNUSED + 1; ctx->flags = flags; @@ -413,6 +422,9 @@ void ir_free(ir_ctx *ctx) { ir_insn *buf = ctx->ir_base - ctx->consts_limit; ir_mem_free(buf); + if (ctx->value_params) { + ir_mem_free(ctx->value_params); + } if (ctx->strtab.data) { ir_strtab_free(&ctx->strtab); } @@ -467,6 +479,10 @@ void ir_free(ir_ctx *ctx) ir_list_free((ir_list*)ctx->osr_entry_loads); ir_mem_free(ctx->osr_entry_loads); } + + if (ctx->const_hash_mask != IR_CONST_HASH_SIZE - 1) { + ir_mem_free(ctx->const_hash); + } } ir_ref ir_unique_const_addr(ir_ctx *ctx, uintptr_t addr) @@ -478,72 +494,64 @@ ir_ref ir_unique_const_addr(ir_ctx *ctx, uintptr_t addr) insn->val.u64 = addr; /* don't insert into constants chain */ insn->prev_const = IR_UNUSED; -#if 0 - insn->prev_const = ctx->prev_const_chain[IR_ADDR]; - ctx->prev_const_chain[IR_ADDR] = ref; -#endif -#if 0 - ir_insn *prev_insn, *next_insn; - ir_ref next; - - prev_insn = NULL; - next = ctx->prev_const_chain[IR_ADDR]; - while (next) { - next_insn = &ctx->ir_base[next]; - if (UNEXPECTED(next_insn->val.u64 >= addr)) { - break; - } - prev_insn = next_insn; - next = next_insn->prev_const; - } - - if (prev_insn) { - insn->prev_const = prev_insn->prev_const; - prev_insn->prev_const = ref; - } else { - insn->prev_const = ctx->prev_const_chain[IR_ADDR]; - ctx->prev_const_chain[IR_ADDR] = ref; - } -#endif return ref; } +IR_ALWAYS_INLINE uintptr_t ir_const_hash(ir_val val, uint32_t optx) +{ + return (val.u64 ^ (val.u64 >> 32) ^ optx); +} + +static IR_NEVER_INLINE void ir_const_hash_rehash(ir_ctx *ctx) +{ + ir_insn *insn; + ir_ref ref; + uintptr_t hash; + + if (ctx->const_hash_mask != IR_CONST_HASH_SIZE - 1) { + ir_mem_free(ctx->const_hash); + } + ctx->const_hash_mask = (ctx->const_hash_mask + 1) * 2 - 1; + ctx->const_hash = ir_mem_calloc(ctx->const_hash_mask + 1, sizeof(ir_ref)); + for (ref = IR_TRUE - 1; ref > -ctx->consts_count; ref--) { + insn = &ctx->ir_base[ref]; + hash = ir_const_hash(insn->val, insn->optx) & ctx->const_hash_mask; + insn->prev_const = ctx->const_hash[hash]; + ctx->const_hash[hash] = ref; + } +} + ir_ref ir_const_ex(ir_ctx *ctx, ir_val val, uint8_t type, uint32_t optx) { - ir_insn *insn, *prev_insn; + ir_insn *insn; ir_ref ref, prev; + uintptr_t hash; if (type == IR_BOOL) { return val.u64 ? IR_TRUE : IR_FALSE; } else if (type == IR_ADDR && val.u64 == 0) { return IR_NULL; } - prev_insn = NULL; - ref = ctx->prev_const_chain[type]; + + hash = ir_const_hash(val, optx) & ctx->const_hash_mask; + ref = ctx->const_hash[hash]; while (ref) { insn = &ctx->ir_base[ref]; - if (UNEXPECTED(insn->val.u64 >= val.u64)) { - if (insn->val.u64 == val.u64) { - if (insn->optx == optx) { - return ref; - } - } else { - break; - } + if (insn->val.u64 == val.u64 && insn->optx == optx) { + return ref; } - prev_insn = insn; ref = insn->prev_const; } - if (prev_insn) { - prev = prev_insn->prev_const; - prev_insn->prev_const = -ctx->consts_count; - } else { - prev = ctx->prev_const_chain[type]; - ctx->prev_const_chain[type] = -ctx->consts_count; + if ((uintptr_t)ctx->consts_count > ctx->const_hash_mask) { + ir_const_hash_rehash(ctx); + hash = ir_const_hash(val, optx) & ctx->const_hash_mask; } + prev = ctx->const_hash[hash]; + ctx->const_hash[hash] = -ctx->consts_count; + ref = ir_next_const(ctx); insn = &ctx->ir_base[ref]; insn->prev_const = prev; @@ -623,7 +631,7 @@ ir_ref ir_const_bool(ir_ctx *ctx, bool c) ir_ref ir_const_char(ir_ctx *ctx, char c) { ir_val val; - val.i64 = c; + val.i64 = (signed char)c; return ir_const(ctx, val, IR_CHAR); } @@ -685,6 +693,13 @@ ir_ref ir_const_str(ir_ctx *ctx, ir_ref str) return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_STR, IR_ADDR, 0)); } +ir_ref ir_const_label(ir_ctx *ctx, ir_ref str) +{ + ir_val val; + val.u64 = str; + return ir_const_ex(ctx, val, IR_ADDR, IR_OPTX(IR_LABEL, IR_ADDR, 0)); +} + ir_ref ir_str(ir_ctx *ctx, const char *s) { size_t len; @@ -803,7 +818,9 @@ ir_ref ir_proto(ir_ctx *ctx, uint8_t flags, ir_type ret_type, uint32_t params_co proto->flags = flags; proto->ret_type = ret_type; proto->params_count = params_count; - memcpy(proto->param_types, param_types, params_count); + if (params_count) { + memcpy(proto->param_types, param_types, params_count); + } return ir_strl(ctx, (const char *)proto, offsetof(ir_proto_t, param_types) + params_count); } @@ -844,7 +861,7 @@ ir_ref ir_emit3(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3) static ir_ref _ir_fold_cse(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3) { ir_ref ref = ctx->prev_insn_chain[opt & IR_OPT_OP_MASK]; - ir_insn *insn; + const ir_insn *insn; if (ref) { ir_ref limit = ctx->fold_cse_limit; @@ -873,6 +890,17 @@ static ir_ref _ir_fold_cse(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir return IR_UNUSED; } +IR_ALWAYS_INLINE ir_ref _ir_fold_cast(ir_ctx *ctx, ir_ref ref, ir_type type) +{ + if (ctx->ir_base[ref].type == type) { + return ref; + } else if (IR_IS_CONST_REF(ref) && !IR_IS_SYM_CONST(ctx->ir_base[ref].op)) { + return ir_const(ctx, ctx->ir_base[ref].val, type); + } else { + return ir_emit1(ctx, IR_OPT(IR_BITCAST, type), ref); + } +} + #define IR_FOLD(X) IR_FOLD1(X, __LINE__) #define IR_FOLD1(X, Y) IR_FOLD2(X, Y) #define IR_FOLD2(X, Y) case IR_RULE_ ## Y: @@ -929,7 +957,8 @@ static ir_ref _ir_fold_cse(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir * ANY and UNUSED ops are represented by 0 */ -ir_ref ir_folding(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3, ir_insn *op1_insn, ir_insn *op2_insn, ir_insn *op3_insn) +ir_ref ir_folding(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3, + const ir_insn *op1_insn, const ir_insn *op2_insn, const ir_insn *op3_insn) { uint8_t op; ir_ref ref; @@ -1080,7 +1109,7 @@ ir_ref ir_emit_N(ir_ctx *ctx, uint32_t opt, int32_t count) ir_ref *p, ref = ctx->insns_count; ir_insn *insn; - IR_ASSERT(count >= 0); + IR_ASSERT(count >= 0 && count < 65536); while (UNEXPECTED(ref + count/4 >= ctx->insns_limit)) { ir_grow_top(ctx); } @@ -1111,9 +1140,9 @@ void ir_set_op(ir_ctx *ctx, ir_ref ref, int32_t n, ir_ref val) ir_insn_set_op(insn, n, val); } -ir_ref ir_get_op(ir_ctx *ctx, ir_ref ref, int32_t n) +ir_ref ir_get_op(const ir_ctx *ctx, ir_ref ref, int32_t n) { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; #ifdef IR_DEBUG if (n > 3) { @@ -1152,7 +1181,7 @@ ir_ref ir_bind(ir_ctx *ctx, ir_ref var, ir_ref def) IR_ASSERT(var < 0); if (!ir_hashtab_add(ctx->binding, def, var)) { /* Add a copy with different binding */ - def = ir_emit2(ctx, IR_OPT(IR_COPY, ctx->ir_base[def].type), def, 1); + def = ir_emit2(ctx, IR_OPT(IR_COPY, ctx->ir_base[def].type), def, IR_COPY_HARD); ir_hashtab_add(ctx->binding, def, var); } return def; @@ -1394,13 +1423,21 @@ bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref) if (old_size < new_size) { /* Reallocate the whole edges buffer (this is inefficient) */ ctx->use_edges = ir_mem_realloc(ctx->use_edges, new_size); + if (n == ctx->use_edges_count) { + ctx->use_edges[n] = ref; + use_list->count++; + ctx->use_edges_count++; + return 1; + } } else if (n == ctx->use_edges_count) { ctx->use_edges[n] = ref; use_list->count++; ctx->use_edges_count++; return 0; } - memcpy(ctx->use_edges + ctx->use_edges_count, ctx->use_edges + use_list->refs, use_list->count * sizeof(ir_ref)); + if (use_list->count) { + memcpy(ctx->use_edges + ctx->use_edges_count, ctx->use_edges + use_list->refs, use_list->count * sizeof(ir_ref)); + } use_list->refs = ctx->use_edges_count; ctx->use_edges[use_list->refs + use_list->count] = ref; use_list->count++; @@ -1409,24 +1446,6 @@ bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref) } } -static int ir_ref_cmp(const void *p1, const void *p2) -{ - return *(ir_ref*)p1 - *(ir_ref*)p2; -} - -void ir_use_list_sort(ir_ctx *ctx, ir_ref ref) -{ - ir_use_list *use_list; - uint32_t n; - - IR_ASSERT(ref > 0); - use_list = &ctx->use_lists[ref]; - n = use_list->count; - if (n > 1) { - qsort(ctx->use_edges + use_list->refs, n, sizeof(ir_ref), ir_ref_cmp); - } -} - void ir_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref) { int i, j, n, *p, use; @@ -1827,11 +1846,52 @@ int ir_mem_unprotect(void *ptr, size_t size) int ir_mem_flush(void *ptr, size_t size) { - return 1; + return FlushInstructionCache(GetCurrentProcess(), ptr, size) == TRUE ? 1 : 0; } #else + +#if defined(__linux__) && defined(__x86_64__) && defined(PKEY_DISABLE_WRITE) +# define HAVE_PKEY_MPROTECT 1 +#endif + +#ifdef HAVE_PKEY_MPROTECT + +#ifndef PKEY_DISABLE_EXECUTE +# define PKEY_DISABLE_EXECUTE 0 +#endif + +int pkey_mprotect(void* addr, size_t len, int prot, int pkey) __attribute__((weak)); +int pkey_alloc(unsigned int, unsigned int) __attribute__((weak)); +int pkey_free(int) __attribute__((weak)); +int pkey_set(int, unsigned) __attribute__((weak)); + +static int ir_pkey = 0; +#endif + void *ir_mem_mmap(size_t size) { +#ifdef HAVE_PKEY_MPROTECT + if (!ir_pkey && pkey_mprotect) { + int key = pkey_alloc(0, PKEY_DISABLE_WRITE); + if (key > 0) { + ir_pkey = key; + } + } + if (ir_pkey > 0) { + void *ret = mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (ret == MAP_FAILED) { + return NULL; + } + if (pkey_mprotect(ret, size, PROT_EXEC|PROT_READ|PROT_WRITE, ir_pkey) != 0) { +#ifdef IR_DEBUG + fprintf(stderr, "pkey_mprotect() failed\n"); +#endif + munmap(ret, size); + return NULL; + } + return ret; + } +#endif int prot_flags = PROT_EXEC; #if defined(__NetBSD__) prot_flags |= PROT_MPROTECT(PROT_READ|PROT_WRITE); @@ -1846,11 +1906,28 @@ void *ir_mem_mmap(size_t size) int ir_mem_unmap(void *ptr, size_t size) { munmap(ptr, size); +#ifdef HAVE_PKEY_MPROTECT +// if (ir_pkey > 0) { +// pkey_free(ir_pkey); +// ir_pkey = 0; +// } +#endif return 1; } int ir_mem_protect(void *ptr, size_t size) { +#ifdef HAVE_PKEY_MPROTECT + if (ir_pkey > 0) { + if (pkey_set(ir_pkey, PKEY_DISABLE_WRITE)) { +#ifdef IR_DEBUG + fprintf(stderr, "mprotect() failed\n"); +#endif + return 0; + } + return 1; + } +#endif if (mprotect(ptr, size, PROT_READ | PROT_EXEC) != 0) { #ifdef IR_DEBUG fprintf(stderr, "mprotect() failed\n"); @@ -1862,6 +1939,17 @@ int ir_mem_protect(void *ptr, size_t size) int ir_mem_unprotect(void *ptr, size_t size) { +#ifdef HAVE_PKEY_MPROTECT + if (ir_pkey > 0) { + if (pkey_set(ir_pkey, PKEY_DISABLE_EXECUTE)) { +#ifdef IR_DEBUG + fprintf(stderr, "mprotect() failed\n"); +#endif + return 0; + } + return 1; + } +#endif if (mprotect(ptr, size, PROT_READ | PROT_WRITE) != 0) { #ifdef IR_DEBUG fprintf(stderr, "mprotect() failed\n"); @@ -1931,7 +2019,7 @@ static ir_alias ir_check_aliasing(ir_ctx *ctx, ir_ref addr1, ir_ref addr2) ir_alias ir_check_partial_aliasing(const ir_ctx *ctx, ir_ref addr1, ir_ref addr2, ir_type type1, ir_type type2) { - ir_insn *insn1, *insn2; + const ir_insn *insn1, *insn2; ir_ref base1, base2, off1, off2; /* this must be already check */ @@ -2023,9 +2111,9 @@ ir_alias ir_check_partial_aliasing(const ir_ctx *ctx, ir_ref addr1, ir_ref addr2 return IR_MAY_ALIAS; } -IR_ALWAYS_INLINE ir_ref ir_find_aliasing_load_i(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref addr, ir_ref limit) +IR_ALWAYS_INLINE ir_ref ir_find_aliasing_load_i(const ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref addr, ir_ref limit) { - ir_insn *insn; + const ir_insn *insn; uint32_t modified_regset = 0; while (ref > limit) { @@ -2064,7 +2152,29 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_load_i(ir_ctx *ctx, ir_ref ref, ir_type } } else if (insn->op == IR_RSTORE) { modified_regset |= (1 << insn->op3); - } else if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_CALL || insn->op == IR_VSTORE) { + } else if (insn->op == IR_CALL) { + const ir_insn *func = &ctx->ir_base[insn->op2]; + ir_ref func_proto; + const ir_proto_t *proto; + + if (func->op == IR_FUNC || func->op == IR_FUNC_ADDR) { + func_proto = func->proto; + } else if (func->op == IR_PROTO) { + func_proto = func->op2; + } else { + break; + } + if (!func_proto) { + break; + } + proto = (const ir_proto_t *)ir_get_str(ctx, func_proto); + if (!(proto->flags & (IR_CONST_FUNC|IR_PURE_FUNC))) { + break; + } + } else if (insn->op == IR_MERGE + || insn->op == IR_LOOP_BEGIN + || insn->op == IR_VSTORE + || (insn->op == IR_BEGIN && insn->op2)) { return IR_UNUSED; } ref = insn->op1; @@ -2073,14 +2183,14 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_load_i(ir_ctx *ctx, ir_ref ref, ir_type return IR_UNUSED; } -ir_ref ir_find_aliasing_load(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref addr) +ir_ref ir_find_aliasing_load(const ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref addr) { return ir_find_aliasing_load_i(ctx, ref, type, addr, (addr > 0 && addr < ref) ? addr : 1); } -IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vload_i(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref var) +IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vload_i(const ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref var) { - ir_insn *insn; + const ir_insn *insn; while (ref > var) { insn = &ctx->ir_base[ref]; @@ -2089,10 +2199,10 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vload_i(ir_ctx *ctx, ir_ref ref, ir_typ if (insn->type == type) { return ref; /* load forwarding (L2L) */ } else if (ir_type_size[insn->type] == ir_type_size[type]) { - return ir_fold1(ctx, IR_OPT(IR_BITCAST, type), ref); /* load forwarding with bitcast (L2L) */ + return ref; /* load forwarding with bitcast (L2L) */ } else if (ir_type_size[insn->type] > ir_type_size[type] && IR_IS_TYPE_INT(type) && IR_IS_TYPE_INT(insn->type)) { - return ir_fold1(ctx, IR_OPT(IR_TRUNC, type), ref); /* partial load forwarding (L2L) */ + return ref; /* partial load forwarding (L2L) */ } } } else if (insn->op == IR_VSTORE) { @@ -2102,15 +2212,37 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vload_i(ir_ctx *ctx, ir_ref ref, ir_typ if (type2 == type) { return insn->op3; /* store forwarding (S2L) */ } else if (ir_type_size[type2] == ir_type_size[type]) { - return ir_fold1(ctx, IR_OPT(IR_BITCAST, type), insn->op3); /* store forwarding with bitcast (S2L) */ + return insn->op3; /* store forwarding with bitcast (S2L) */ } else if (ir_type_size[type2] > ir_type_size[type] && IR_IS_TYPE_INT(type) && IR_IS_TYPE_INT(type2)) { - return ir_fold1(ctx, IR_OPT(IR_TRUNC, type), insn->op3); /* partial store forwarding (S2L) */ + return insn->op3; /* partial store forwarding (S2L) */ } else { break; } } - } else if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_CALL || insn->op == IR_STORE) { + } else if (insn->op == IR_CALL) { + const ir_insn *func = &ctx->ir_base[insn->op2]; + ir_ref func_proto; + const ir_proto_t *proto; + + if (func->op == IR_FUNC || func->op == IR_FUNC_ADDR) { + func_proto = func->proto; + } else if (func->op == IR_PROTO) { + func_proto = func->op2; + } else { + break; + } + if (!func_proto) { + break; + } + proto = (const ir_proto_t *)ir_get_str(ctx, func_proto); + if (!(proto->flags & (IR_CONST_FUNC|IR_PURE_FUNC))) { + break; + } + } else if (insn->op == IR_MERGE + || insn->op == IR_LOOP_BEGIN + || insn->op == IR_STORE + || (insn->op == IR_BEGIN && insn->op2)) { break; } ref = insn->op1; @@ -2119,7 +2251,7 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vload_i(ir_ctx *ctx, ir_ref ref, ir_typ return IR_UNUSED; } -ir_ref ir_find_aliasing_vload(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref var) +ir_ref ir_find_aliasing_vload(const ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref var) { return ir_find_aliasing_vload_i(ctx, ref, type, var); } @@ -2203,7 +2335,15 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_store_i(ir_ctx *ctx, ir_ref ref, ir_ref } } else if (insn->op == IR_GUARD || insn->op == IR_GUARD_NOT) { guarded = 1; - } else if (insn->op >= IR_START || insn->op == IR_CALL) { + } else if (insn->op >= IR_START) { + if (insn->op == IR_BEGIN && insn->op1 && !insn->op2) { + /* skip END */ + ref = insn->op1; + insn = &ctx->ir_base[ref]; + } else { + break; + } + } else if (insn->op == IR_CALL) { break; } next = ref; @@ -2284,7 +2424,15 @@ IR_ALWAYS_INLINE ir_ref ir_find_aliasing_vstore_i(ir_ctx *ctx, ir_ref ref, ir_re } } else if (insn->op == IR_GUARD || insn->op == IR_GUARD_NOT) { guarded = 1; - } else if (insn->op >= IR_START || insn->op == IR_CALL || insn->op == IR_LOAD || insn->op == IR_STORE) { + } else if (insn->op >= IR_START) { + if (insn->op == IR_BEGIN && insn->op1 && !insn->op2) { + /* skip END */ + ref = insn->op1; + insn = &ctx->ir_base[ref]; + } else { + break; + } + } else if (insn->op == IR_CALL || insn->op == IR_LOAD || insn->op == IR_STORE) { break; } next = ref; @@ -2299,6 +2447,37 @@ ir_ref ir_find_aliasing_vstore(ir_ctx *ctx, ir_ref ref, ir_ref var, ir_ref val) } /* IR Construction API */ +static ir_ref ir_last_guard(ir_ctx *ctx) +{ + ir_ref ref; + ir_insn *insn; + + IR_ASSERT(ctx->control); + ref = ctx->control; + while (1) { + insn = &ctx->ir_base[ref]; + if (IR_IS_BB_START(insn->op) || insn->op == IR_GUARD || insn->op == IR_GUARD_NOT) { + if (insn->op == IR_START) ref = IR_UNUSED; + break; + } + ref = insn->op1; + } + return ref; +} + +ir_ref _ir_DIV(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2) +{ + ir_ref guard = (IR_IS_TYPE_FP(type) || (IR_IS_CONST_REF(op2) && ctx->ir_base[op2].val.u64 != 0)) ? + IR_UNUSED : ir_last_guard(ctx); + return ir_fold3(ctx, IR_OPT(IR_DIV, type), op1, op2, guard); +} + +ir_ref _ir_MOD(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2) +{ + ir_ref guard = (IR_IS_CONST_REF(op2) && ctx->ir_base[op2].val.u64 != 0) ? + IR_UNUSED : ir_last_guard(ctx); + return ir_fold3(ctx, IR_OPT(IR_MOD, type), op1, op2, guard); +} ir_ref _ir_PARAM(ir_ctx *ctx, ir_type type, const char* name, ir_ref num) { @@ -2415,12 +2594,12 @@ void _ir_BEGIN(ir_ctx *ctx, ir_ref src) } } -static ir_ref _ir_fold_condition(ir_ctx *ctx, ir_ref ref) +static ir_ref _ir_fold_condition(const ir_ctx *ctx, ir_ref ref) { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; if (insn->op == IR_NE && IR_IS_CONST_REF(insn->op2)) { - ir_insn *op2_insn = &ctx->ir_base[insn->op2]; + const ir_insn *op2_insn = &ctx->ir_base[insn->op2]; if (IR_IS_TYPE_INT(op2_insn->type) && op2_insn->val.u64 == 0) { ref = insn->op1; @@ -2433,7 +2612,7 @@ static ir_ref _ir_fold_condition(ir_ctx *ctx, ir_ref ref) ref = insn->op1; insn = &ctx->ir_base[ref]; } else if (insn->op == IR_EQ && insn->op2 == IR_NULL) { - ir_insn *op1_insn = &ctx->ir_base[insn->op1]; + const ir_insn *op1_insn = &ctx->ir_base[insn->op1]; if (op1_insn->op == IR_ALLOCA || op1_insn->op == IR_VADDR) { return IR_FALSE; } @@ -2445,10 +2624,10 @@ static ir_ref _ir_fold_condition(ir_ctx *ctx, ir_ref ref) return ref; } -IR_ALWAYS_INLINE ir_ref ir_check_dominating_predicates_i(ir_ctx *ctx, ir_ref ref, ir_ref condition, ir_ref limit) +IR_ALWAYS_INLINE ir_ref ir_check_dominating_predicates_i(const ir_ctx *ctx, ir_ref ref, ir_ref condition, ir_ref limit) { - ir_insn *prev = NULL; - ir_insn *insn; + const ir_insn *prev = NULL; + const ir_insn *insn; while (ref > limit) { insn = &ctx->ir_base[ref]; @@ -2478,7 +2657,7 @@ IR_ALWAYS_INLINE ir_ref ir_check_dominating_predicates_i(ir_ctx *ctx, ir_ref ref return condition; } -ir_ref ir_check_dominating_predicates(ir_ctx *ctx, ir_ref ref, ir_ref condition) +ir_ref ir_check_dominating_predicates(const ir_ctx *ctx, ir_ref ref, ir_ref condition) { IR_ASSERT(!IR_IS_CONST_REF(condition)); return ir_check_dominating_predicates_i(ctx, ref, condition, (condition < ref) ? condition : 1); @@ -2619,7 +2798,7 @@ void _ir_MERGE_LIST(ir_ctx *ctx, ir_ref list) /* count inputs count */ do { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; IR_ASSERT(insn->op == IR_END); ref = insn->op2; @@ -2649,8 +2828,10 @@ void _ir_MERGE_LIST(ir_ctx *ctx, ir_ref list) ir_ref _ir_PHI_LIST(ir_ctx *ctx, ir_ref list) { - ir_insn *merge, *end; - ir_ref phi, *ops, i; + const ir_insn *merge; + const ir_ref *ops; + ir_insn *end; + ir_ref phi, i; ir_type type; if (list == IR_UNUSED) { @@ -2973,6 +3154,12 @@ void _ir_CASE_VAL(ir_ctx *ctx, ir_ref switch_ref, ir_ref val) ctx->control = ir_emit2(ctx, IR_CASE_VAL, switch_ref, val); } +void _ir_CASE_RANGE(ir_ctx *ctx, ir_ref switch_ref, ir_ref v1, ir_ref v2) +{ + IR_ASSERT(!ctx->control); + ctx->control = ir_emit3(ctx, IR_CASE_RANGE, switch_ref, v1, v2); +} + void _ir_CASE_DEFAULT(ir_ctx *ctx, ir_ref switch_ref) { IR_ASSERT(!ctx->control); @@ -3001,6 +3188,16 @@ void _ir_IJMP(ir_ctx *ctx, ir_ref addr) ctx->control = IR_UNUSED; } +ir_ref _ir_IGOTO(ir_ctx *ctx, ir_ref addr) +{ + ir_ref ref; + + IR_ASSERT(ctx->control); + ctx->control = ref = ir_emit2(ctx, IR_IGOTO, ctx->control, addr); + ctx->control = IR_UNUSED; + return ref; +} + ir_ref _ir_ADD_OFFSET(ir_ctx *ctx, ir_ref addr, uintptr_t offset) { if (offset) { @@ -3098,7 +3295,8 @@ ir_ref _ir_VLOAD(ir_ctx *ctx, ir_type type, ir_ref var) if (EXPECTED(ctx->flags & IR_OPT_FOLDING)) { ref = ir_find_aliasing_vload_i(ctx, ctx->control, type, var); if (ref) { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; + if (insn->type == type) { return ref; } else if (ir_type_size[insn->type] == ir_type_size[type]) { @@ -3123,6 +3321,18 @@ void _ir_VSTORE(ir_ctx *ctx, ir_ref var, ir_ref val) ctx->control = ir_emit3(ctx, IR_VSTORE, ctx->control, var, val); } +ir_ref _ir_VLOAD_v(ir_ctx *ctx, ir_type type, ir_ref var) +{ + IR_ASSERT(ctx->control); + return ctx->control = ir_emit2(ctx, IR_OPT(IR_VLOAD_v, type), ctx->control, var); +} + +void _ir_VSTORE_v(ir_ctx *ctx, ir_ref var, ir_ref val) +{ + IR_ASSERT(ctx->control); + ctx->control = ir_emit3(ctx, IR_VSTORE_v, ctx->control, var, val); +} + ir_ref _ir_TLS(ir_ctx *ctx, ir_ref index, ir_ref offset) { IR_ASSERT(ctx->control); @@ -3152,7 +3362,8 @@ ir_ref _ir_LOAD(ir_ctx *ctx, ir_type type, ir_ref addr) } ref = ir_find_aliasing_load_i(ctx, ctx->control, type, addr, (addr > 0) ? addr : 1); if (ref) { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; + if (insn->type == type) { return ref; } else if (ir_type_size[insn->type] == ir_type_size[type]) { @@ -3181,6 +3392,18 @@ void _ir_STORE(ir_ctx *ctx, ir_ref addr, ir_ref val) ctx->control = ir_emit3(ctx, IR_STORE, ctx->control, addr, val); } +ir_ref _ir_LOAD_v(ir_ctx *ctx, ir_type type, ir_ref addr) +{ + IR_ASSERT(ctx->control); + return ctx->control = ir_emit2(ctx, IR_OPT(IR_LOAD_v, type), ctx->control, addr); +} + +void _ir_STORE_v(ir_ctx *ctx, ir_ref addr, ir_ref val) +{ + IR_ASSERT(ctx->control); + ctx->control = ir_emit3(ctx, IR_STORE_v, ctx->control, addr, val); +} + void _ir_VA_START(ir_ctx *ctx, ir_ref list) { IR_ASSERT(ctx->control); @@ -3205,6 +3428,15 @@ ir_ref _ir_VA_ARG(ir_ctx *ctx, ir_type type, ir_ref list) return ctx->control = ir_emit2(ctx, IR_OPT(IR_VA_ARG, type), ctx->control, list); } +ir_ref _ir_VA_ARG_EX(ir_ctx *ctx, ir_type type, ir_ref list, size_t size, size_t align) +{ + IR_ASSERT(ctx->control); + IR_ASSERT(size <= 0x0fffffff); + IR_ASSERT(align != 0 && ((align & (align - 1)) == 0) && align <= 128); + return ctx->control = ir_emit3(ctx, IR_OPT(IR_VA_ARG, type), ctx->control, list, + (ir_ref)IR_VA_ARG_OP3(size, align)); +} + ir_ref _ir_BLOCK_BEGIN(ir_ctx *ctx) { IR_ASSERT(ctx->control); diff --git a/ext/opcache/jit/ir/ir.h b/ext/opcache/jit/ir/ir.h index ec5e57129c9a..01db4ecf6b15 100644 --- a/ext/opcache/jit/ir/ir.h +++ b/ext/opcache/jit/ir/ir.h @@ -210,12 +210,14 @@ typedef enum _ir_type { * arg - argument reference CALL/TAILCALL/CARG->CARG * src - reference to a previous control region (IF, IF_TRUE, IF_FALSE, MERGE, LOOP_BEGIN, LOOP_END, RETURN) * reg - data-control dependency on region (PHI, VAR, PARAM) + * grd - optional data-control dependency guard (DIV, MOD) * ret - reference to a previous RETURN instruction (RETURN) * str - string: variable/argument name (VAR, PARAM, CALL, TAILCALL) * num - number: argument number (PARAM) * prb - branch probability 1-99 (0 - unspecified): (IF_TRUE, IF_FALSE, CASE_VAL, CASE_DEFAULT) * opt - optional number * pro - function prototype + * lbl - label used as value (a reference to constant): (BEGIN) * * The order of IR opcodes is carefully selected for efficient folding. * - foldable instruction go first @@ -257,13 +259,15 @@ typedef enum _ir_type { _(UGE, d2, def, def, ___) /* unsigned greater or equal */ \ _(ULE, d2, def, def, ___) /* unsigned less or equal */ \ _(UGT, d2, def, def, ___) /* unsigned greater */ \ + _(ORDERED, d2, def, def, ___) /* both operands are not NAN */ \ + _(UNORDERED, d2, def, def, ___) /* one of operands is NAN */ \ \ /* arithmetic ops */ \ _(ADD, d2C, def, def, ___) /* addition */ \ _(SUB, d2, def, def, ___) /* subtraction (must be ADD+1) */ \ _(MUL, d2C, def, def, ___) /* multiplication */ \ - _(DIV, d2, def, def, ___) /* division */ \ - _(MOD, d2, def, def, ___) /* modulo */ \ + _(DIV, d3, def, def, grd) /* division */ \ + _(MOD, d3, def, def, grd) /* modulo */ \ _(NEG, d1, def, ___, ___) /* change sign */ \ _(ABS, d1, def, ___, ___) /* absolute value */ \ /* (LDEXP, MIN, MAX, FPMATH) */ \ @@ -310,6 +314,8 @@ typedef enum _ir_type { _(PHI, pN, reg, def, def) /* SSA Phi function */ \ _(COPY, d1X1, def, opt, ___) /* COPY (last foldable op) */ \ _(PI, p2, reg, def, ___) /* e-SSA Pi constraint ??? */ \ + _(ARGVAL, d1X2, def, num, num) /* pass struct arg by value */ \ + /* (op2 - size, op3 - align) */ \ /* (USE, RENAME) */ \ \ /* data ops */ \ @@ -318,6 +324,7 @@ typedef enum _ir_type { _(FUNC_ADDR, r0, ___, ___, ___) /* constant func ref */ \ _(FUNC, r0, ___, ___, ___) /* constant func ref */ \ _(SYM, r0, ___, ___, ___) /* constant symbol ref */ \ + _(LABEL, r0, ___, ___, ___) /* label address ref */ \ _(STR, r0, ___, ___, ___) /* constant str ref */ \ \ /* call ops */ \ @@ -330,11 +337,15 @@ typedef enum _ir_type { _(BLOCK_BEGIN, a1, src, ___, ___) /* stacksave */ \ _(BLOCK_END, a2, src, def, ___) /* stackrestore */ \ _(VLOAD, l2, src, var, ___) /* load value of local var */ \ + _(VLOAD_v, l2, src, var, ___) /* volatile variant of VLOAD */ \ _(VSTORE, s3, src, var, def) /* store value to local var */ \ + _(VSTORE_v, s3, src, var, def) /* volatile variant of VSTORE */ \ _(RLOAD, l1X2, src, num, opt) /* load value from register */ \ _(RSTORE, s2X1, src, def, num) /* store value into register */ \ _(LOAD, l2, src, ref, ___) /* load from memory */ \ + _(LOAD_v, l2, src, ref, ___) /* volatile variant of VLOAD */ \ _(STORE, s3, src, ref, def) /* store to memory */ \ + _(STORE_v, s3, src, ref, def) /* volatile variant of VSTORE */ \ _(TLS, l1X2, src, num, num) /* thread local variable */ \ _(TRAP, x1, src, ___, ___) /* DebugBreak */ \ /* memory reference ops (A, H, U, S, TMP, STR, NEW, X, V) ??? */ \ @@ -343,7 +354,8 @@ typedef enum _ir_type { _(VA_START, x2, src, def, ___) /* va_start(va_list) */ \ _(VA_END, x2, src, def, ___) /* va_end(va_list) */ \ _(VA_COPY, x3, src, def, def) /* va_copy(dst, stc) */ \ - _(VA_ARG, x2, src, def, ___) /* va_arg(va_list) */ \ + _(VA_ARG, x2X1, src, def, opt) /* va_arg(va_list) */ \ + /* op3 - (size<<3)+log2(align) */ \ \ /* guards */ \ _(GUARD, c3, src, def, def) /* IF without second successor */ \ @@ -355,10 +367,11 @@ typedef enum _ir_type { /* control-flow nodes */ \ _(START, S0X1, ret, ___, ___) /* function start */ \ _(ENTRY, S1X1, src, num, ___) /* entry with a fake src edge */ \ - _(BEGIN, S1, src, ___, ___) /* block start */ \ + _(BEGIN, S1X1, src, lbl, ___) /* block start, optional &&lbl */ \ _(IF_TRUE, S1X1, src, prb, ___) /* IF TRUE proj. */ \ _(IF_FALSE, S1X1, src, prb, ___) /* IF FALSE proj. */ \ _(CASE_VAL, S2X1, src, def, prb) /* switch proj. */ \ + _(CASE_RANGE, S3, src, def, def) /* switch proj. */ \ _(CASE_DEFAULT, S1X1, src, prb, ___) /* switch proj. */ \ _(MERGE, SN, src, src, src) /* control merge */ \ _(LOOP_BEGIN, SN, src, src, src) /* loop start */ \ @@ -366,10 +379,19 @@ typedef enum _ir_type { _(LOOP_END, E1, src, ___, ___) /* loop end */ \ _(IF, E2, src, def, ___) /* conditional control split */ \ _(SWITCH, E2, src, def, ___) /* multi-way control split */ \ + _(IGOTO, E2, src, def, ___) /* computed goto (internal) */ \ + _(IJMP, T2X1, src, def, ret) /* computed goto (terminating) */ \ _(RETURN, T2X1, src, def, ret) /* function return */ \ - _(IJMP, T2X1, src, def, ret) /* computed goto */ \ _(UNREACHABLE, T1X2, src, ___, ret) /* unreachable (tailcall, etc) */ \ \ + /* inline assembler */ \ + _(ASM, xN, src, def, def) /* GCC inline assembler */ \ + /* op2 - asm template string */ \ + /* op3 - asm constraint string */ \ + /* opN - asm input argument */ \ + _(ASM_OUT, x1, src, ___, ___) /* ASM data output projection */ \ + _(ASM_GOTO, E1, src, ___, ___) /* ASM goto (bb end after ASM) */ \ + \ /* deoptimization helper */ \ _(EXITCALL, x2, src, def, ___) /* save CPU regs and call op2 */ \ @@ -394,6 +416,13 @@ typedef enum _ir_op { #define IR_OPTX(op, type, n) ((uint32_t)(op) | ((uint32_t)(type) << IR_OPT_TYPE_SHIFT) | ((uint32_t)(n) << IR_OPT_INPUTS_SHIFT)) #define IR_OPT_TYPE(opt) (((opt) & IR_OPT_TYPE_MASK) >> IR_OPT_TYPE_SHIFT) +/* "opt" modifiers */ +#define IR_COPY_HARD (1<<0) + +#define IR_VA_ARG_SIZE(op3) (((uint32_t)(op3) >> 3)) +#define IR_VA_ARG_ALIGN(op3) (1U << ((uint32_t)(op3) & 0x7)) +#define IR_VA_ARG_OP3(s, a) (((s) << 3) | ir_ntzl(a)) + /* IR References */ typedef int32_t ir_ref; @@ -519,35 +548,36 @@ void ir_strtab_apply(const ir_strtab *strtab, ir_strtab_apply_t func); void ir_strtab_free(ir_strtab *strtab); /* IR Context Flags */ -#define IR_FUNCTION (1<<0) /* Generate a function. */ -#define IR_FASTCALL_FUNC (1<<1) /* Generate a function with fastcall calling convention, x86 32-bit only. */ -#define IR_VARARG_FUNC (1<<2) -#define IR_BUILTIN_FUNC (1<<3) -#define IR_STATIC (1<<4) -#define IR_EXTERN (1<<5) -#define IR_CONST (1<<6) - -#define IR_INITIALIZED (1<<7) /* sym data flag: constant or an initialized variable */ -#define IR_CONST_STRING (1<<8) /* sym data flag: constant string */ - -#define IR_SKIP_PROLOGUE (1<<8) /* Don't generate function prologue. */ -#define IR_USE_FRAME_POINTER (1<<9) -#define IR_PREALLOCATED_STACK (1<<10) -#define IR_NO_STACK_COMBINE (1<<11) -#define IR_START_BR_TARGET (1<<12) -#define IR_ENTRY_BR_TARGET (1<<13) -#define IR_GEN_ENDBR (1<<14) -#define IR_MERGE_EMPTY_ENTRIES (1<<15) - -#define IR_OPT_INLINE (1<<16) -#define IR_OPT_FOLDING (1<<17) -#define IR_OPT_CFG (1<<18) /* merge BBs, by remove END->BEGIN nodes during CFG construction */ -#define IR_OPT_MEM2SSA (1<<19) -#define IR_OPT_CODEGEN (1<<20) -#define IR_GEN_NATIVE (1<<21) -#define IR_GEN_CODE (1<<22) /* C or LLVM */ - -#define IR_GEN_CACHE_DEMOTE (1<<23) /* Demote the generated code from closest CPU caches */ +#define IR_PROTO_MASK 0xff +#define IR_CALL_CONV_MASK 0x0f + +#define IR_VARARG_FUNC (1<<4) +#define IR_CONST_FUNC (1<<5) +#define IR_PURE_FUNC (1<<6) + +#define IR_CONST (1<<5) +#define IR_INITIALIZED (1<<6) /* sym data flag: constant or an initialized variable */ +#define IR_CONST_STRING (1<<7) /* sym data flag: constant string */ + +#define IR_FUNCTION (1<<8) /* Generate a function. */ +#define IR_STATIC (1<<9) +#define IR_EXTERN (1<<10) + +#define IR_USE_FRAME_POINTER (1<<11) +#define IR_NO_STACK_COMBINE (1<<12) +#define IR_GEN_ENDBR (1<<13) +#define IR_GEN_CACHE_DEMOTE (1<<14) /* Demote the generated code from closest CPU caches */ + +#define IR_SKIP_PROLOGUE (1<<15) /* Don't generate function prologue. */ +#define IR_START_BR_TARGET (1<<16) +#define IR_ENTRY_BR_TARGET (1<<17) +#define IR_MERGE_EMPTY_ENTRIES (1<<18) + +#define IR_OPT_INLINE (1<<19) +#define IR_OPT_FOLDING (1<<20) +#define IR_OPT_CFG (1<<21) /* merge BBs, by remove END->BEGIN nodes during CFG construction */ +#define IR_OPT_MEM2SSA (1<<22) +#define IR_OPT_CODEGEN (1<<23) /* debug related */ #ifdef IR_DEBUG @@ -559,6 +589,24 @@ void ir_strtab_free(ir_strtab *strtab); # define IR_DEBUG_BB_SCHEDULE (1U<<31) #endif +/* Calling Conventions */ +#define IR_CC_DEFAULT 0x00 +#define IR_CC_BUILTIN 0x01 +#define IR_CC_FASTCALL 0x02 +#define IR_CC_PRESERVE_NONE 0x03 + +#if defined(IR_TARGET_X64) +# define IR_CC_X86_64_SYSV 0x08 +# define IR_CC_X86_64_MS 0x09 +#elif defined(IR_TARGET_AARCH64) +# define IR_CC_AARCH64_SYSV 0x08 +# define IR_CC_AARCH64_DARWIN 0x09 +#endif + +/* Deprecated constants */ +#define IR_BUILTIN_FUNC IR_CC_BUILTIN +#define IR_FASTCALL_FUNC IR_CC_FASTCALL + typedef struct _ir_ctx ir_ctx; typedef struct _ir_use_list ir_use_list; typedef struct _ir_block ir_block; @@ -582,12 +630,22 @@ typedef struct _ir_code_buffer { void *pos; } ir_code_buffer; +typedef struct { + int size; + int align; + int offset; +} ir_value_param; + +#define IR_CONST_HASH_SIZE 64 + struct _ir_ctx { ir_insn *ir_base; /* two directional array - instructions grow down, constants grow up */ ir_ref insns_count; /* number of instructions stored in instructions buffer */ ir_ref insns_limit; /* size of allocated instructions buffer (it's extended when overflow) */ ir_ref consts_count; /* number of constants stored in constants buffer */ ir_ref consts_limit; /* size of allocated constants buffer (it's extended when overflow) */ + uintptr_t const_hash_mask; + ir_ref *const_hash; uint32_t flags; /* IR context flags (see IR_* defines above) */ uint32_t flags2; /* IR context private flags (see IR_* defines in ir_private.h) */ ir_type ret_type; /* Function return type */ @@ -595,6 +653,7 @@ struct _ir_ctx { int32_t status; /* non-zero error code (see IR_ERROR_... macros), app may use negative codes */ ir_ref fold_cse_limit; /* CSE finds identical insns backward from "insn_count" to "fold_cse_limit" */ ir_insn fold_insn; /* temporary storage for folding engine */ + ir_value_param *value_params; /* information about "by-val" struct parameters */ ir_hashtab *binding; ir_use_list *use_lists; /* def->use lists for each instruction */ ir_ref *use_edges; /* the actual uses: use = ctx->use_edges[ctx->use_lists[def].refs + n] */ @@ -631,7 +690,6 @@ struct _ir_ctx { ir_ref vars; /* list of VARs (used by register allocator) */ }; ir_snapshot_create_t snapshot_create; - int32_t stack_frame_alignment; int32_t stack_frame_size; /* spill stack frame size (used by register allocator and code generator) */ int32_t call_stack_size; /* stack for parameter passing (used by register allocator and code generator) */ uint64_t used_preserved_regs; @@ -654,7 +712,7 @@ struct _ir_ctx { ir_loader *loader; ir_strtab strtab; ir_ref prev_insn_chain[IR_LAST_FOLDABLE_OP + 1]; - ir_ref prev_const_chain[IR_LAST_TYPE]; + ir_ref _const_hash[IR_CONST_HASH_SIZE]; }; /* Basic IR Construction API (implementation in ir.c) */ @@ -681,6 +739,7 @@ ir_ref ir_const_func_addr(ir_ctx *ctx, uintptr_t c, ir_ref proto); ir_ref ir_const_func(ir_ctx *ctx, ir_ref str, ir_ref proto); ir_ref ir_const_sym(ir_ctx *ctx, ir_ref str); ir_ref ir_const_str(ir_ctx *ctx, ir_ref str); +ir_ref ir_const_label(ir_ctx *ctx, ir_ref str); ir_ref ir_unique_const_addr(ir_ctx *ctx, uintptr_t c); @@ -694,7 +753,7 @@ const char *ir_get_strl(const ir_ctx *ctx, ir_ref idx, size_t *len); #define IR_MAX_PROTO_PARAMS 255 typedef struct _ir_proto_t { - uint8_t flags; + uint8_t flags; /* first 8 bits of ir_ctx.flags */ uint8_t ret_type; uint8_t params_count; uint8_t param_types[5]; @@ -719,7 +778,7 @@ ir_ref ir_emit3(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3); ir_ref ir_emit_N(ir_ctx *ctx, uint32_t opt, int32_t count); void ir_set_op(ir_ctx *ctx, ir_ref ref, int32_t n, ir_ref val); -ir_ref ir_get_op(ir_ctx *ctx, ir_ref ref, int32_t n); +ir_ref ir_get_op(const ir_ctx *ctx, ir_ref ref, int32_t n); IR_ALWAYS_INLINE void ir_set_op1(ir_ctx *ctx, ir_ref ref, ir_ref val) { @@ -813,13 +872,13 @@ int ir_reg_alloc(ir_ctx *ctx); int ir_regs_number(void); bool ir_reg_is_int(int32_t reg); const char *ir_reg_name(int8_t reg, ir_type type); -int32_t ir_get_spill_slot_offset(ir_ctx *ctx, ir_ref ref); +int32_t ir_get_spill_slot_offset(const ir_ctx *ctx, ir_ref ref); /* Target CPU instruction selection and code generation (see ir_x86.c) */ int ir_match(ir_ctx *ctx); void *ir_emit_code(ir_ctx *ctx, size_t *size); -bool ir_needs_thunk(ir_code_buffer *code_buffer, void *addr); +bool ir_needs_thunk(const ir_code_buffer *code_buffer, void *addr); void *ir_emit_thunk(ir_code_buffer *code_buffer, void *addr, size_t *size_ptr); void ir_fix_thunk(void *thunk_entry, void *addr); @@ -854,6 +913,9 @@ void ir_gdb_unregister_all(void); bool ir_gdb_present(void); /* IR load API (implementation in ir_load.c) */ +#define IR_RESOLVE_SYM_ADD_THUNK (1<<0) +#define IR_RESOLVE_SYM_SILENT (1<<1) + struct _ir_loader { uint32_t default_func_flags; bool (*init_module) (ir_loader *loader, const char *name, const char *filename, const char *target); @@ -870,9 +932,10 @@ struct _ir_loader { bool (*sym_data_end) (ir_loader *loader, uint32_t flags); bool (*func_init) (ir_loader *loader, ir_ctx *ctx, const char *name); bool (*func_process) (ir_loader *loader, ir_ctx *ctx, const char *name); - void*(*resolve_sym_name) (ir_loader *loader, const char *name, bool add_thunk); + void*(*resolve_sym_name) (ir_loader *loader, const char *name, uint32_t flags); bool (*has_sym) (ir_loader *loader, const char *name); bool (*add_sym) (ir_loader *loader, const char *name, void *addr); + bool (*add_label) (ir_loader *loader, const char *name, void *addr); }; void ir_loader_init(void); @@ -884,18 +947,21 @@ int ir_load_llvm_bitcode(ir_loader *loader, const char *filename); int ir_load_llvm_asm(ir_loader *loader, const char *filename); /* IR save API (implementation in ir_save.c) */ -#define IR_SAVE_CFG (1<<0) /* add info about CFG */ -#define IR_SAVE_CFG_MAP (1<<1) /* add info about CFG block assignment */ -#define IR_SAVE_USE_LISTS (1<<2) /* add info about def->use lists */ -#define IR_SAVE_RULES (1<<3) /* add info about selected code-generation rules */ -#define IR_SAVE_REGS (1<<4) /* add info about selected registers */ - +#define IR_SAVE_CFG (1<<0) /* add info about CFG */ +#define IR_SAVE_CFG_MAP (1<<1) /* add info about CFG block assignment */ +#define IR_SAVE_USE_LISTS (1<<2) /* add info about def->use lists */ +#define IR_SAVE_RULES (1<<3) /* add info about selected code-generation rules */ +#define IR_SAVE_REGS (1<<4) /* add info about selected registers */ +#define IR_SAVE_SAFE_NAMES (1<<5) /* add '@' prefix to symbol names */ + +void ir_print_func_proto(const ir_ctx *ctx, const char *name, bool prefix, FILE *f); void ir_print_proto(const ir_ctx *ctx, ir_ref proto, FILE *f); +void ir_print_proto_ex(uint8_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types, FILE *f); void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f); /* IR debug dump API (implementation in ir_dump.c) */ void ir_dump(const ir_ctx *ctx, FILE *f); -void ir_dump_dot(const ir_ctx *ctx, const char *name, FILE *f); +void ir_dump_dot(const ir_ctx *ctx, const char *name, const char *comments, FILE *f); void ir_dump_use_lists(const ir_ctx *ctx, FILE *f); void ir_dump_cfg(ir_ctx *ctx, FILE *f); void ir_dump_cfg_map(const ir_ctx *ctx, FILE *f); @@ -1012,6 +1078,7 @@ IR_ALWAYS_INLINE void *ir_jit_compile(ir_ctx *ctx, int opt_level, size_t *size) #define IR_ERROR_UNSUPPORTED_CODE_RULE 3 #define IR_ERROR_LINK 4 #define IR_ERROR_ENCODE 5 +#define IR_ERROR_TOO_LARGE 6 /* IR Memmory Allocation */ #ifndef ir_mem_malloc diff --git a/ext/opcache/jit/ir/ir_aarch64.dasc b/ext/opcache/jit/ir/ir_aarch64.dasc index 772eea7a5d78..fc4bb84f1e05 100644 --- a/ext/opcache/jit/ir/ir_aarch64.dasc +++ b/ext/opcache/jit/ir/ir_aarch64.dasc @@ -60,7 +60,7 @@ IR_ALWAYS_INLINE ir_mem IR_MEM(ir_reg base, int32_t offset, ir_reg index, int32_ #define ADR_IMM (1<<20) // signed imm21 #define ADRP_IMM (1LL<<32) // signed imm21 * 4096 -static bool aarch64_may_use_b(ir_code_buffer *code_buffer, const void *addr) +static bool aarch64_may_use_b(const ir_code_buffer *code_buffer, const void *addr) { if (code_buffer) { if (addr >= code_buffer->start && (char*)addr < (char*)code_buffer->end) { @@ -213,13 +213,21 @@ static bool aarch64_may_encode_addr_offset(int64_t offset, uint32_t type_size) |.endmacro typedef struct _ir_backend_data { - ir_reg_alloc_data ra_data; - uint32_t dessa_from_block; + ir_reg_alloc_data ra_data; dasm_State *dasm_state; ir_bitset emit_constants; int rodata_label, jmp_table_label; + bool resolved_label_syms; } ir_backend_data; +typedef struct _ir_aarch64_sysv_va_list { + void *stack; + void *gr_top; + void *vr_top; + int32_t gr_offset; + int32_t vr_offset; +} ir_aarch64_sysv_va_list; + #define IR_GP_REG_NAME(code, name64, name32) \ #name64, #define IR_GP_REG_NAME32(code, name64, name32) \ @@ -229,9 +237,11 @@ typedef struct _ir_backend_data { #define IR_FP_REG_NAME32(code, name64, name32, name16, name8) \ #name32, -static const char *_ir_reg_name[IR_REG_NUM] = { +static const char *_ir_reg_name[] = { IR_GP_REGS(IR_GP_REG_NAME) IR_FP_REGS(IR_FP_REG_NAME) + "ALL", + "SCRATCH", }; static const char *_ir_reg_name32[IR_REG_NUM] = { @@ -239,38 +249,11 @@ static const char *_ir_reg_name32[IR_REG_NUM] = { IR_FP_REGS(IR_FP_REG_NAME32) }; -/* Calling Convention */ -static const int8_t _ir_int_reg_params[IR_REG_INT_ARGS] = { - IR_REG_INT_ARG1, - IR_REG_INT_ARG2, - IR_REG_INT_ARG3, - IR_REG_INT_ARG4, - IR_REG_INT_ARG5, - IR_REG_INT_ARG6, - IR_REG_INT_ARG7, - IR_REG_INT_ARG8, -}; - -static const int8_t _ir_fp_reg_params[IR_REG_FP_ARGS] = { - IR_REG_FP_ARG1, - IR_REG_FP_ARG2, - IR_REG_FP_ARG3, - IR_REG_FP_ARG4, - IR_REG_FP_ARG5, - IR_REG_FP_ARG6, - IR_REG_FP_ARG7, - IR_REG_FP_ARG8, -}; - const char *ir_reg_name(int8_t reg, ir_type type) { if (reg >= IR_REG_NUM) { - if (reg == IR_REG_SCRATCH) { - return "SCRATCH"; - } else { - IR_ASSERT(reg == IR_REG_ALL); - return "ALL"; - } + IR_ASSERT((uint8_t)reg < sizeof(_ir_reg_name) / sizeof(_ir_reg_name[0])); + return _ir_reg_name[reg]; } IR_ASSERT(reg >= 0 && reg < IR_REG_NUM); if (type == IR_VOID) { @@ -283,6 +266,82 @@ const char *ir_reg_name(int8_t reg, ir_type type) } } +/* Calling Conventions */ +#define IR_REG_SCRATCH_AARCH64 IR_REG_SET_1 + +#define IR_REGSET_SCRATCH_AARCH64 \ + (IR_REGSET_INTERVAL(IR_REG_X0, IR_REG_X18) | \ + IR_REGSET_INTERVAL(IR_REG_V0, IR_REG_V7) | \ + IR_REGSET_INTERVAL(IR_REG_V16, IR_REG_V31)) + +const ir_regset ir_scratch_regset[] = { + IR_REGSET_GP | IR_REGSET_FP, + IR_REGSET_SCRATCH_AARCH64, +}; + +const ir_call_conv_dsc ir_call_conv_aarch64_sysv = { + 0, /* cleanup_stack_by_callee */ + 0, /* pass_struct_by_val */ + 1, /* sysv_varargs */ + 0, /* shadow_param_regs */ + 0, /* shadow_store_size */ + 8, /* int_param_regs_count */ + 8, /* fp_param_regs_count */ + IR_REG_X0 , /* int_ret_reg */ + IR_REG_V0, /* fp_ret_reg */ + IR_REG_NONE, /* fp_varargs_reg */ + IR_REG_SCRATCH_AARCH64, + (const int8_t[8]){IR_REG_X0, IR_REG_X1, IR_REG_X2, IR_REG_X3, IR_REG_X4, IR_REG_X5, IR_REG_X6, IR_REG_X7}, + (const int8_t[8]){IR_REG_V0, IR_REG_V1, IR_REG_V2, IR_REG_V3, IR_REG_V4, IR_REG_V5, IR_REG_V6, IR_REG_V7}, + IR_REGSET_INTERVAL(IR_REG_X19, IR_REG_X30) | IR_REGSET_INTERVAL(IR_REG_V8, IR_REG_V15), + +}; + +const ir_call_conv_dsc ir_call_conv_aarch64_darwin = { + 0, /* cleanup_stack_by_callee */ + 0, /* pass_struct_by_val */ + 0, /* sysv_varargs */ + 0, /* shadow_param_regs */ + 0, /* shadow_store_size */ + 8, /* int_param_regs_count */ + 8, /* fp_param_regs_count */ + IR_REG_X0 , /* int_ret_reg */ + IR_REG_V0, /* fp_ret_reg */ + IR_REG_NONE, /* fp_varargs_reg */ + IR_REG_SCRATCH_AARCH64, + (const int8_t[8]){IR_REG_X0, IR_REG_X1, IR_REG_X2, IR_REG_X3, IR_REG_X4, IR_REG_X5, IR_REG_X6, IR_REG_X7}, + (const int8_t[8]){IR_REG_V0, IR_REG_V1, IR_REG_V2, IR_REG_V3, IR_REG_V4, IR_REG_V5, IR_REG_V6, IR_REG_V7}, + IR_REGSET_INTERVAL(IR_REG_X19, IR_REG_X30) | IR_REGSET_INTERVAL(IR_REG_V8, IR_REG_V15), + +}; + +const ir_call_conv_dsc ir_call_conv_aarch64_preserve_none = { + 0, /* cleanup_stack_by_callee */ + 0, /* pass_struct_by_val */ + 1, /* sysv_varargs */ + 0, /* shadow_param_regs */ + 0, /* shadow_store_size */ + 23, /* int_param_regs_count */ + 8, /* fp_param_regs_count */ + IR_REG_X0 , /* int_ret_reg */ + IR_REG_V0, /* fp_ret_reg */ + IR_REG_NONE, /* fp_varargs_reg */ + IR_REG_ALL, + (const int8_t[23]){IR_REG_X20, IR_REG_X21, IR_REG_X22, IR_REG_X23, IR_REG_X24, IR_REG_X25, IR_REG_X26, IR_REG_X27, + IR_REG_X28, + IR_REG_X0, IR_REG_X1, IR_REG_X2, IR_REG_X3, IR_REG_X4, IR_REG_X5, IR_REG_X6, IR_REG_X7, + IR_REG_X10, IR_REG_X11, IR_REG_X12, IR_REG_X13, IR_REG_X14, IR_REG_X9}, + (const int8_t[8]){IR_REG_V0, IR_REG_V1, IR_REG_V2, IR_REG_V3, IR_REG_V4, IR_REG_V5, IR_REG_V6, IR_REG_V7}, + IR_REGSET_EMPTY, + +}; + +#ifdef __APPLE__ +# define ir_call_conv_default ir_call_conv_aarch64_darwin +#else +# define ir_call_conv_default ir_call_conv_aarch64_sysv +#endif + #define IR_RULES(_) \ _(CMP_INT) \ _(CMP_FP) \ @@ -315,6 +374,7 @@ const char *ir_reg_name(int8_t reg, ir_type type) _(RETURN_VOID) \ _(RETURN_INT) \ _(RETURN_FP) \ + _(IGOTO_DUP) \ #define IR_RULE_ENUM(name) IR_ ## name, @@ -340,6 +400,9 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co const ir_insn *insn; int n = 0; int flags = IR_USE_MUST_BE_IN_REG | IR_OP1_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; + const ir_proto_t *proto; + const ir_call_conv_dsc *cc; + ir_ref next; constraints->def_reg = IR_REG_NONE; constraints->hints_count = 0; @@ -385,7 +448,7 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co n++; break; } - } else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { + } else if (!IR_IS_CONST_REF(insn->op2) && ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n++; } @@ -397,6 +460,15 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co n++; } break; + case IR_INT2FP: + case IR_FP2INT: + insn = &ctx->ir_base[ref]; + n = 0; + if (IR_IS_CONST_REF(insn->op1)) { + constraints->tmp_regs[n] = IR_TMP_REG(1, ctx->ir_base[insn->op1].type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } + break; case IR_MUL_PWR2: case IR_DIV_PWR2: case IR_MOD_PWR2: @@ -404,8 +476,6 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co case IR_SHIFT_CONST: case IR_OP_INT: case IR_OP_FP: - case IR_INT2FP: - case IR_FP2INT: case IR_FP2FP: insn = &ctx->ir_base[ref]; n = 0; @@ -471,10 +541,16 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co if (IR_IS_CONST_REF(insn->op1)) { constraints->tmp_regs[n] = IR_TMP_REG(1, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n++; + } else if (ir_rule(ctx, insn->op1) == IR_STATIC_ALLOCA) { + constraints->tmp_regs[n] = IR_TMP_REG(1, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; } if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) { constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n++; + } else if (!IR_IS_CONST_REF(insn->op2) && ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { + constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; } break; case IR_CMP_INT: @@ -487,11 +563,13 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co constraints->tmp_regs[0] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; } - if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) { - insn = &ctx->ir_base[insn->op2]; - if (IR_IS_SYM_CONST(insn->op) || !aarch64_may_encode_imm12(insn->val.u64)) { - constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); - n++; + if (IR_IS_CONST_REF(insn->op2)) { + if (insn->op1 != insn->op2) { + insn = &ctx->ir_base[insn->op2]; + if (IR_IS_SYM_CONST(insn->op) || !aarch64_may_encode_imm12(insn->val.u64)) { + constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } } } else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); @@ -513,6 +591,7 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co } break; case IR_VSTORE: + case IR_VSTORE_v: insn = &ctx->ir_base[ref]; if (IR_IS_CONST_REF(insn->op3)) { insn = &ctx->ir_base[insn->op3]; @@ -567,17 +646,34 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co constraints->tmp_regs[n] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n++; break; + case IR_ARGVAL: + /* memcpy() clobbers all scratch registers */ + constraints->tmp_regs[0] = IR_SCRATCH_REG(IR_REG_SCRATCH_AARCH64, IR_DEF_SUB_REF - IR_SUB_REFS_COUNT, IR_USE_SUB_REF); + n = 1; + break; case IR_CALL: insn = &ctx->ir_base[ref]; - constraints->def_reg = (IR_IS_TYPE_INT(insn->type)) ? IR_REG_INT_RET1 : IR_REG_FP_RET1; - constraints->tmp_regs[0] = IR_SCRATCH_REG(IR_REG_SCRATCH, IR_USE_SUB_REF, IR_DEF_SUB_REF); + proto = ir_call_proto(ctx, insn); + cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + if (insn->type != IR_VOID) { + constraints->def_reg = (IR_IS_TYPE_INT(insn->type)) ? + cc->int_ret_reg : cc->fp_ret_reg; + } + constraints->tmp_regs[0] = IR_SCRATCH_REG(cc->scratch_reg, IR_USE_SUB_REF, IR_DEF_SUB_REF); n = 1; - IR_FALLTHROUGH; + if (insn->inputs_count > 2) { + goto get_arg_hints; + } + flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG; + break; case IR_TAILCALL: insn = &ctx->ir_base[ref]; if (insn->inputs_count > 2) { + proto = ir_call_proto(ctx, insn); + cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); +get_arg_hints: constraints->hints[2] = IR_REG_NONE; - constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints); + constraints->hints_count = ir_get_args_regs(ctx, insn, cc, constraints->hints); if (!IR_IS_CONST_REF(insn->op2)) { constraints->tmp_regs[n] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_USE_SUB_REF); n++; @@ -585,6 +681,19 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co } flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG; break; + case IR_IGOTO: + insn = &ctx->ir_base[ref]; + if (ctx->ir_base[insn->op1].op == IR_MERGE || ctx->ir_base[insn->op1].op == IR_LOOP_BEGIN) { + ir_insn *merge = &ctx->ir_base[insn->op1]; + ir_ref *p, n = merge->inputs_count; + + for (p = merge->ops + 1; n > 0; p++, n--) { + ir_ref input = *p; + IR_ASSERT(ctx->ir_base[input].op == IR_END || ctx->ir_base[input].op == IR_LOOP_END); + ctx->rules[input] = IR_IGOTO_DUP; + } + } + return insn->op; case IR_COND: insn = &ctx->ir_base[ref]; n = 0; @@ -614,7 +723,7 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co break; case IR_PARAM: constraints->def_reg = ir_get_param_reg(ctx, ref); - flags = 0; + flags = (constraints->def_reg != IR_REG_NONE) ? IR_USE_SHOULD_BE_IN_REG : 0; break; case IR_PI: case IR_PHI: @@ -625,38 +734,64 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co flags = IR_USE_SHOULD_BE_IN_REG; break; case IR_EXITCALL: - constraints->def_reg = IR_REG_INT_RET1; + cc = ir_get_call_conv_dsc(ctx->flags); + constraints->def_reg = cc->int_ret_reg; break; case IR_RSTORE: flags = IR_OP3_SHOULD_BE_IN_REG; break; case IR_RETURN_INT: + cc = ir_get_call_conv_dsc(ctx->flags); flags = IR_OP2_SHOULD_BE_IN_REG; - constraints->hints[2] = IR_REG_INT_RET1; + constraints->hints[2] = cc->int_ret_reg; constraints->hints_count = 3; break; case IR_RETURN_FP: + cc = ir_get_call_conv_dsc(ctx->flags); flags = IR_OP2_SHOULD_BE_IN_REG; - constraints->hints[2] = IR_REG_FP_RET1; + constraints->hints[2] = cc->fp_ret_reg; constraints->hints_count = 3; break; case IR_SNAPSHOT: flags = 0; + next = ir_next_control(ctx, ref); + if (ctx->ir_base[next].op == IR_GUARD || ctx->ir_base[next].op == IR_GUARD_NOT) { + flags = IR_EXTEND_INPUTS_TO_NEXT; + } break; case IR_VA_START: flags = IR_OP2_MUST_BE_IN_REG; constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; + insn = &ctx->ir_base[ref]; + if (IR_IS_CONST_REF(insn->op2)) { + constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n = 2; + } break; case IR_VA_ARG: - flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG; + flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_DEF_CONFLICTS_WITH_INPUT_REGS; constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_SAVE_SUB_REF); n = 1; + insn = &ctx->ir_base[ref]; + if (IR_IS_CONST_REF(insn->op2)) { + constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n = 2; + } break; case IR_VA_COPY: flags = IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; constraints->tmp_regs[0] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; + insn = &ctx->ir_base[ref]; + if (IR_IS_CONST_REF(insn->op2)) { + constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } + if (IR_IS_CONST_REF(insn->op3)) { + constraints->tmp_regs[n] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } break; } constraints->tmps_count = n; @@ -684,7 +819,8 @@ static void ir_match_fuse_addr(ir_ctx *ctx, ir_ref addr_ref, ir_type type) do { ir_insn *insn = &ctx->ir_base[*p]; - if (insn->op != IR_LOAD && (insn->op != IR_STORE || insn->op3 == addr_ref)) { + if (insn->op != IR_LOAD && insn->op != IR_LOAD_v + && ((insn->op != IR_STORE && insn->op != IR_STORE_v) || insn->op3 == addr_ref)) { return; } p++; @@ -695,6 +831,34 @@ static void ir_match_fuse_addr(ir_ctx *ctx, ir_ref addr_ref, ir_type type) } } +static bool all_usages_are_fusable(ir_ctx *ctx, ir_ref ref) +{ + ir_insn *insn = &ctx->ir_base[ref]; + + if (insn->op >= IR_EQ && insn->op <= IR_UNORDERED) { + ir_use_list *use_list = &ctx->use_lists[ref]; + ir_ref n = use_list->count; + + if (n > 0) { + ir_ref *p = ctx->use_edges + use_list->refs; + + do { + insn = &ctx->ir_base[*p]; + if (insn->op != IR_IF + && insn->op != IR_GUARD + && insn->op != IR_GUARD_NOT) { + return 0; + } + p++; + n--; + } while (n); + return 1; + } + } + return 0; +} + + static uint32_t ir_match_insn(ir_ctx *ctx, ir_ref ref) { ir_insn *op2_insn; @@ -717,6 +881,9 @@ static uint32_t ir_match_insn(ir_ctx *ctx, ir_ref ref) return IR_CMP_FP; } break; + case IR_ORDERED: + case IR_UNORDERED: + return IR_CMP_FP; case IR_ADD: case IR_SUB: if (IR_IS_TYPE_INT(insn->type)) { @@ -928,7 +1095,7 @@ binop_fp: ctx->flags2 |= IR_HAS_CALLS; return IR_CALL; case IR_VAR: - return IR_SKIPPED | IR_VAR; + return IR_STATIC_ALLOCA; case IR_PARAM: return ctx->use_lists[ref].count > 0 ? IR_PARAM : IR_SKIPPED | IR_PARAM; case IR_ALLOCA: @@ -945,6 +1112,7 @@ binop_fp: } return IR_ALLOCA; case IR_LOAD: + case IR_LOAD_v: ir_match_fuse_addr(ctx, insn->op2, insn->type); if (IR_IS_TYPE_INT(insn->type)) { return IR_LOAD_INT; @@ -953,6 +1121,7 @@ binop_fp: } break; case IR_STORE: + case IR_STORE_v: ir_match_fuse_addr(ctx, insn->op2, ctx->ir_base[insn->op3].type); if (IR_IS_TYPE_INT(ctx->ir_base[insn->op3].type)) { return IR_STORE_INT; @@ -996,6 +1165,7 @@ binop_fp: case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: @@ -1010,9 +1180,9 @@ binop_fp: return IR_RETURN_FP; } case IR_IF: - if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) { + if (!IR_IS_CONST_REF(insn->op2) && (ctx->use_lists[insn->op2].count == 1 || all_usages_are_fusable(ctx, insn->op2))) { op2_insn = &ctx->ir_base[insn->op2]; - if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT) { + if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) { if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) { ctx->rules[insn->op2] = IR_FUSED | IR_CMP_INT; return IR_CMP_AND_BRANCH_INT; @@ -1033,13 +1203,9 @@ binop_fp: } case IR_GUARD: case IR_GUARD_NOT: - if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) { + if (!IR_IS_CONST_REF(insn->op2) && (ctx->use_lists[insn->op2].count == 1 || all_usages_are_fusable(ctx, insn->op2))) { op2_insn = &ctx->ir_base[insn->op2]; - if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT - // TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP - && (insn->op2 == ref - 1 || - (insn->op2 == ctx->prev_ref[ref] - 1 - && ctx->ir_base[ctx->prev_ref[ref]].op == IR_SNAPSHOT))) { + if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) { if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) { ctx->rules[insn->op2] = IR_FUSED | IR_CMP_INT; return IR_GUARD_CMP_INT; @@ -1079,6 +1245,9 @@ binop_fp: ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP; } } + } else { + /* va_list may escape */ + ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP; } return IR_VA_START; case IR_VA_END: @@ -1095,8 +1264,16 @@ binop_fp: } } return IR_SKIPPED | IR_NOP; + case IR_ARGVAL: + return IR_FUSED | IR_ARGVAL; case IR_NOP: return IR_SKIPPED | IR_NOP; + case IR_ASM: + case IR_ASM_OUT: + case IR_ASM_GOTO: + fprintf(stderr, "ERROR: IR_ASM is not implemented yet\n"); + exit(1); + return IR_SKIPPED | IR_NOP; default: break; } @@ -1325,7 +1502,7 @@ static void ir_emit_load_imm_fp(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref sr } else if (type == IR_DOUBLE && insn->val.u64 == 0) { | fmov Rd(reg-IR_REG_FP_FIRST), xzr } else { - label = ir_const_label(ctx, src); + label = ir_get_const_label(ctx, src); if (type == IR_DOUBLE) { | ldr Rd(reg-IR_REG_FP_FIRST), =>label } else { @@ -1378,6 +1555,12 @@ static void ir_emit_load_mem(ir_ctx *ctx, ir_type type, ir_reg reg, ir_mem mem) } } +static int32_t ir_local_offset(ir_ctx *ctx, ir_insn *insn) +{ + IR_ASSERT(insn->op == IR_VAR || insn->op == IR_ALLOCA || insn->op == IR_VADDR); + return IR_SPILL_POS_TO_OFFSET(insn->op3); +} + static void ir_load_local_addr(ir_ctx *ctx, ir_reg reg, ir_ref src) { ir_backend_data *data = ctx->data; @@ -1391,16 +1574,46 @@ static void ir_load_local_addr(ir_ctx *ctx, ir_reg reg, ir_ref src) if (var_insn->op == IR_VADDR) { var_insn = &ctx->ir_base[var_insn->op1]; } - IR_ASSERT(var_insn->op == IR_VAR || var_insn->op == IR_ALLOCA); - offset = IR_SPILL_POS_TO_OFFSET(var_insn->op3); + offset = ir_local_offset(ctx, var_insn); if (aarch64_may_encode_imm12(offset)) { | add Rx(reg), Rx(base), #offset } else { ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); - | add sp, sp, Rx(IR_REG_INT_TMP) + | add Rx(reg), Rx(base), Rx(IR_REG_INT_TMP) + } +} + +static void ir_resolve_label_syms(ir_ctx *ctx) +{ + uint32_t b; + ir_block *bb; + + for (b = 1, bb = &ctx->cfg_blocks[b]; b <= ctx->cfg_blocks_count; bb++, b++) { + ir_insn *insn = &ctx->ir_base[bb->start]; + + if (insn->op == IR_BEGIN && insn->op2) { + IR_ASSERT(ctx->ir_base[insn->op2].op == IR_LABEL); + ctx->ir_base[insn->op2].val.u32_hi = b; + } } } +static void ir_emit_load_label_addr(ir_ctx *ctx, ir_reg reg, ir_insn *label) +{ + ir_backend_data *data = ctx->data; + dasm_State **Dst = &data->dasm_state; + + if (!data->resolved_label_syms) { + data->resolved_label_syms = 1; + ir_resolve_label_syms(ctx); + } + + IR_ASSERT(label->op == IR_LABEL); + int b = label->val.u32_hi; + + b = ir_skip_empty_target_blocks(ctx, b); + | adr Rx(reg), =>b +} static void ir_emit_load(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref src) { @@ -1415,9 +1628,11 @@ static void ir_emit_load(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref src) } else if (insn->op == IR_STR) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - int label = ir_const_label(ctx, src); + int label = ir_get_const_label(ctx, src); | adr Rx(reg), =>label + } else if (insn->op == IR_LABEL) { + ir_emit_load_label_addr(ctx, reg, insn); } else { ir_emit_load_imm_int(ctx, type, reg, insn->val.i64); } @@ -1586,19 +1801,31 @@ static void ir_emit_prologue(ir_ctx *ctx) offset = -(ctx->stack_frame_size+16); if (aarch64_may_encode_imm7_addr_offset(offset, 8)) { | stp x29, x30, [sp, #offset]! - } else { + } else if (aarch64_may_encode_imm12(ctx->stack_frame_size+16)) { | sub sp, sp, #(ctx->stack_frame_size+16) | stp x29, x30, [sp] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size+16); + | sub sp, sp, Rx(IR_REG_INT_TMP) + | stp x29, x30, [sp] } | mov x29, sp if (ctx->call_stack_size) { - | sub sp, sp, #(ctx->call_stack_size) + if (aarch64_may_encode_imm12(ctx->call_stack_size)) { + | sub sp, sp, #(ctx->call_stack_size) + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->call_stack_size); + | sub sp, sp, Rx(IR_REG_INT_TMP) + } } } else if (ctx->stack_frame_size + ctx->call_stack_size) { if (ctx->fixed_stack_red_zone) { IR_ASSERT(ctx->stack_frame_size + ctx->call_stack_size <= ctx->fixed_stack_red_zone); + } else if (aarch64_may_encode_imm12(ctx->stack_frame_size + ctx->call_stack_size)) { + | sub sp, sp, #(ctx->stack_frame_size + ctx->call_stack_size) } else { - | sub sp, sp, #(ctx->stack_frame_size + ctx->call_stack_size) + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size + ctx->call_stack_size); + | sub sp, sp, Rx(IR_REG_INT_TMP) } } if (ctx->used_preserved_regs) { @@ -1622,26 +1849,42 @@ static void ir_emit_prologue(ir_ctx *ctx) offset -= sizeof(void*) * 2; if (aarch64_may_encode_imm7_addr_offset(offset, 8)) { | stp Rx(prev), Rx(i), [Rx(fp), #offset] - } else { - IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8)); + } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) { | str Rx(prev), [Rx(fp), #offset] | str Rx(i), [Rx(fp), #(offset+8)] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] + | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8 + | str Rx(i), [Rx(fp), Rx(IR_REG_INT_TMP)] } prev = IR_REG_NONE; } else { if (prev < IR_REG_FP_FIRST) { offset -= sizeof(void*); - | str Rx(prev), [Rx(fp), #offset] - offset -= sizeof(void*); - | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, 8)) { + | str Rx(prev), [Rx(fp), #offset] + offset -= sizeof(void*); + | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + offset -= sizeof(void*); + | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] + | sub Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8 + | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } else { offset -= sizeof(void*) * 2; if (aarch64_may_encode_imm7_addr_offset(offset, 8)) { | stp Rd(prev-IR_REG_FP_FIRST), Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset] - } else { - IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8)); + } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) { | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset] | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), #(offset+8)] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] + | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8 + | str Rd(i-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] } } prev = IR_REG_NONE; @@ -1651,65 +1894,90 @@ static void ir_emit_prologue(ir_ctx *ctx) if (prev != IR_REG_NONE) { if (prev < IR_REG_FP_FIRST) { offset -= sizeof(void*); - | str Rx(prev), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, 8)) { + | str Rx(prev), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } else { offset -= sizeof(void*); - | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, 8)) { + | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | str Rd(prev-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } } } + if ((ctx->flags & IR_VARARG_FUNC) && (ctx->flags2 & IR_HAS_VA_START)) { -#ifndef __APPLE__ - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; - ir_reg fp; - int offset; - int i; + const ir_call_conv_dsc *cc = data->ra_data.cc; - if (ctx->flags & IR_USE_FRAME_POINTER) { - fp = IR_REG_FRAME_POINTER; + if (cc->sysv_varargs) { + ir_reg fp; + int offset; + int i; - offset = ctx->locals_area_size + sizeof(void*) * 2; - } else { - fp = IR_REG_STACK_POINTER; - offset = ctx->locals_area_size + ctx->call_stack_size; - } + if (ctx->flags & IR_USE_FRAME_POINTER) { + fp = IR_REG_FRAME_POINTER; + + offset = ctx->locals_area_size + sizeof(void*) * 2; + } else { + fp = IR_REG_STACK_POINTER; + offset = ctx->locals_area_size + ctx->call_stack_size; + } - if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < IR_REG_INT_ARGS) { - ir_reg prev = IR_REG_NONE; + if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < cc->int_param_regs_count) { + ir_reg prev = IR_REG_NONE; - /* skip named args */ - offset += sizeof(void*) * ctx->gp_reg_params; - for (i = ctx->gp_reg_params; i < IR_REG_INT_ARGS; i++) { - if (prev != IR_REG_NONE) { - if (aarch64_may_encode_imm7_addr_offset(offset, 8)) { - | stp Rx(prev), Rx(int_reg_params[i]), [Rx(fp), #offset] + /* skip named args */ + offset += sizeof(void*) * ctx->gp_reg_params; + for (i = ctx->gp_reg_params; i < cc->int_param_regs_count; i++) { + if (prev != IR_REG_NONE) { + if (aarch64_may_encode_imm7_addr_offset(offset, 8)) { + | stp Rx(prev), Rx(cc->int_param_regs[i]), [Rx(fp), #offset] + } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) { + | str Rx(prev), [Rx(fp), #offset] + | str Rx(cc->int_param_regs[i]), [Rx(fp), #(offset+8)] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] + | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8 + | str Rx(cc->int_param_regs[i]), [Rx(fp), Rx(IR_REG_INT_TMP)] + } + prev = IR_REG_NONE; + offset += sizeof(void*) * 2; } else { - IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8)); + prev = cc->int_param_regs[i]; + } + } + if (prev != IR_REG_NONE) { + if (aarch64_may_encode_addr_offset(offset + 8, 8)) { | str Rx(prev), [Rx(fp), #offset] - | str Rx(int_reg_params[i]), [Rx(fp), #(offset+8)] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | str Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] } - prev = IR_REG_NONE; - offset += sizeof(void*) * 2; - } else { - prev = int_reg_params[i]; + offset += sizeof(void*); } } - if (prev != IR_REG_NONE) { - | str Rx(prev), [Rx(fp), #offset] - offset += sizeof(void*); - } - } - if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < IR_REG_FP_ARGS) { - /* skip named args */ - offset += 16 * ctx->fp_reg_params; - for (i = ctx->fp_reg_params; i < IR_REG_FP_ARGS; i++) { - // TODO: Rd->Rq stur->str ??? - | str Rd(fp_reg_params[i]-IR_REG_FP_FIRST), [Rx(fp), #offset] - offset += 16; + if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < cc->fp_param_regs_count) { + /* skip named args */ + offset += 16 * ctx->fp_reg_params; + for (i = ctx->fp_reg_params; i < cc->fp_param_regs_count; i++) { + // TODO: Rd->Rq stur->str ??? + if (aarch64_may_encode_addr_offset(offset, 8)) { + | str Rd(cc->fp_param_regs[i]-IR_REG_FP_FIRST), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | str Rd(cc->fp_param_regs[i]-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] + } + offset += 16; + } } } -#endif } } @@ -1738,26 +2006,44 @@ static void ir_emit_epilogue(ir_ctx *ctx) offset -= sizeof(void*) * 2; if (aarch64_may_encode_imm7_addr_offset(offset, 8)) { | ldp Rx(prev), Rx(i), [Rx(fp), #offset] - } else { - IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8)); + } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) { | ldr Rx(prev), [Rx(fp), #offset] | ldr Rx(i), [Rx(fp), #(offset+8)] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | ldr Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] + | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8 + | ldr Rx(i), [Rx(fp), Rx(IR_REG_INT_TMP)] } prev = IR_REG_NONE; } else { if (prev < IR_REG_FP_FIRST) { offset -= sizeof(void*); - | ldr Rx(prev), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, 8)) { + | ldr Rx(prev), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | ldr Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] + } offset -= sizeof(void*); - | ldr Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, 8)) { + | ldr Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | ldr Rd(i-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } else { offset -= sizeof(void*) * 2; if (aarch64_may_encode_imm7_addr_offset(offset, 8)) { | ldp Rd(prev-IR_REG_FP_FIRST), Rd(i-IR_REG_FP_FIRST), [Rx(fp), #offset] - } else { - IR_ASSERT(aarch64_may_encode_addr_offset(offset, 8)); + } else if (aarch64_may_encode_addr_offset(offset + 8, 8)) { | ldr Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset] | ldr Rd(i-IR_REG_FP_FIRST), [Rx(fp), #(offset+8)] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | ldr Rx(prev-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] + | add Rx(IR_REG_INT_TMP), Rx(IR_REG_INT_TMP), #8 + | ldr Rx(i-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] } } prev = IR_REG_NONE; @@ -1767,10 +2053,20 @@ static void ir_emit_epilogue(ir_ctx *ctx) if (prev != IR_REG_NONE) { if (prev < IR_REG_FP_FIRST) { offset -= sizeof(void*); - | ldr Rx(prev), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, 8)) { + | ldr Rx(prev), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | ldr Rx(prev), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } else { offset -= sizeof(void*); - | ldr Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, 8)) { + | ldr Rd(prev-IR_REG_FP_FIRST), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | ldr Rd(prev-IR_REG_FP_FIRST), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } } } @@ -1781,15 +2077,22 @@ static void ir_emit_epilogue(ir_ctx *ctx) } if (aarch64_may_encode_imm7_addr_offset(ctx->stack_frame_size+16, 8)) { | ldp x29, x30, [sp], #(ctx->stack_frame_size+16) - } else { + } else if (aarch64_may_encode_imm12(ctx->stack_frame_size+16)) { | ldp x29, x30, [sp] | add sp, sp, #(ctx->stack_frame_size+16) + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size+16); + | ldp x29, x30, [sp] + | add sp, sp, Rx(IR_REG_INT_TMP) } } else if (ctx->stack_frame_size + ctx->call_stack_size) { if (ctx->fixed_stack_red_zone) { IR_ASSERT(ctx->stack_frame_size + ctx->call_stack_size <= ctx->fixed_stack_red_zone); - } else { + } else if (aarch64_may_encode_imm12(ctx->stack_frame_size + ctx->call_stack_size)) { | add sp, sp, #(ctx->stack_frame_size + ctx->call_stack_size) + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size + ctx->call_stack_size); + | add sp, sp, Rx(IR_REG_INT_TMP) } } } @@ -1812,6 +2115,9 @@ static void ir_emit_binop_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) op1_reg = IR_REG_NUM(op1_reg); ir_emit_load(ctx, type, op1_reg, op1); } + if (op2_reg == IR_REG_NONE && op1 == op2) { + op2_reg = op1_reg; + } if (op2_reg != IR_REG_NONE) { if (IR_REG_SPILLED(op2_reg)) { op2_reg = IR_REG_NUM(op2_reg); @@ -2815,7 +3121,7 @@ static void ir_emit_cmp_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) } } -static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref cmp_ref, ir_insn *cmp_insn) +static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref root, ir_ref cmp_ref, ir_insn *cmp_insn) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; @@ -2824,16 +3130,12 @@ static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref cmp_ref, ir_insn *cmp_ins ir_ref op1, op2; ir_reg op1_reg, op2_reg; - if (op == IR_LT || op == IR_LE) { - /* swap operands to avoid P flag check */ - op ^= 3; - op1 = cmp_insn->op2; - op2 = cmp_insn->op1; - op1_reg = ctx->regs[cmp_ref][2]; - op2_reg = ctx->regs[cmp_ref][1]; + op1 = cmp_insn->op1; + op2 = cmp_insn->op2; + if (UNEXPECTED(ctx->rules[cmp_ref] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, root, cmp_ref * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, root, cmp_ref * sizeof(ir_ref) + 2); } else { - op1 = cmp_insn->op1; - op2 = cmp_insn->op2; op1_reg = ctx->regs[cmp_ref][1]; op2_reg = ctx->regs[cmp_ref][2]; } @@ -2862,7 +3164,7 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - ir_op op = ir_emit_cmp_fp_common(ctx, def, insn); + ir_op op = ir_emit_cmp_fp_common(ctx, def, def, insn); ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); //??? ir_reg tmp_reg = ctx->regs[def][3]; // TODO: take into account vs flag @@ -2900,6 +3202,12 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) case IR_UGT: | cset Rw(def_reg), hi break; + case IR_ORDERED: + | cset Rw(def_reg), vc + break; + case IR_UNORDERED: + | cset Rw(def_reg), vs + break; } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, insn->type, def, def_reg); @@ -2974,7 +3282,7 @@ static void ir_emit_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint ir_get_true_false_blocks(ctx, b, &true_block, &false_block); if (true_block == next_block) { /* swap to avoid unconditional JMP */ - if (int_cmp || op == IR_EQ || op == IR_NE) { + if (int_cmp || op == IR_EQ || op == IR_NE || op == IR_ORDERED || op == IR_UNORDERED) { op ^= 1; // reverse } else { op ^= 5; // reverse @@ -3054,10 +3362,11 @@ static void ir_emit_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint case IR_UGT: | bhi =>true_block break; -// case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break; -// case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break; -// case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break; -// case IR_UGT: fprintf(stderr, "\tja .LL%d\n", true_block); break; + case IR_ORDERED: + | bvc =>true_block + break; + case IR_UNORDERED: + | bvs =>true_block } } if (false_block) { @@ -3072,8 +3381,15 @@ static void ir_emit_cmp_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_i ir_type type = ctx->ir_base[cmp_insn->op1].type; ir_ref op1 = cmp_insn->op1; ir_ref op2 = cmp_insn->op2; - ir_reg op1_reg = ctx->regs[insn->op2][1]; - ir_reg op2_reg = ctx->regs[insn->op2][2]; + ir_reg op1_reg, op2_reg; + + if (UNEXPECTED(ctx->rules[insn->op2] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 2); + } else { + op1_reg = ctx->regs[insn->op2][1]; + op2_reg = ctx->regs[insn->op2][2]; + } if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { op1_reg = IR_REG_NUM(op1_reg); @@ -3114,7 +3430,7 @@ static void ir_emit_cmp_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_i static void ir_emit_cmp_and_branch_fp(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint32_t next_block) { - ir_op op = ir_emit_cmp_fp_common(ctx, insn->op2, &ctx->ir_base[insn->op2]); + ir_op op = ir_emit_cmp_fp_common(ctx, def, insn->op2, &ctx->ir_base[insn->op2]); ir_emit_jcc(ctx, b, def, insn, next_block, op, 0); } @@ -3183,14 +3499,14 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn) op3_reg = op2_reg; } } - if (op3 != op2 && IR_REG_SPILLED(op3_reg)) { + if (IR_REG_SPILLED(op3_reg)) { op3_reg = IR_REG_NUM(op3_reg); ir_emit_load(ctx, type, op3_reg, op3); - if (op1 == op2) { + if (op1 == op3) { op1_reg = op3_reg; } } - if (op1 != op2 && op1 != op3 && IR_REG_SPILLED(op1_reg)) { + if (IR_REG_SPILLED(op1_reg)) { op1_reg = IR_REG_NUM(op1_reg); ir_emit_load(ctx, op1_type, op1_reg, op1); } @@ -3231,15 +3547,17 @@ static void ir_emit_return_void(ir_ctx *ctx) static void ir_emit_return_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn) { + ir_backend_data *data = ctx->data; + ir_reg ret_reg = data->ra_data.cc->int_ret_reg; ir_reg op2_reg = ctx->regs[ref][2]; - if (op2_reg != IR_REG_INT_RET1) { + if (op2_reg != ret_reg) { ir_type type = ctx->ir_base[insn->op2].type; if (op2_reg != IR_REG_NONE && !IR_REG_SPILLED(op2_reg)) { - ir_emit_mov(ctx, type, IR_REG_INT_RET1, op2_reg); + ir_emit_mov(ctx, type, ret_reg, op2_reg); } else { - ir_emit_load(ctx, type, IR_REG_INT_RET1, insn->op2); + ir_emit_load(ctx, type, ret_reg, insn->op2); } } ir_emit_return_void(ctx); @@ -3247,14 +3565,16 @@ static void ir_emit_return_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn) static void ir_emit_return_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn) { + ir_backend_data *data = ctx->data; + ir_reg ret_reg = data->ra_data.cc->fp_ret_reg; ir_reg op2_reg = ctx->regs[ref][2]; ir_type type = ctx->ir_base[insn->op2].type; - if (op2_reg != IR_REG_FP_RET1) { + if (op2_reg != ret_reg) { if (op2_reg != IR_REG_NONE && !IR_REG_SPILLED(op2_reg)) { - ir_emit_fp_mov(ctx, type, IR_REG_FP_RET1, op2_reg); + ir_emit_fp_mov(ctx, type, ret_reg, op2_reg); } else { - ir_emit_load(ctx, type, IR_REG_FP_RET1, insn->op2); + ir_emit_load(ctx, type, ret_reg, insn->op2); } } ir_emit_return_void(ctx); @@ -3307,25 +3627,52 @@ static void ir_emit_sext(ir_ctx *ctx, ir_ref def, ir_insn *insn) int32_t offset = ir_ref_spill_slot_offset(ctx, insn->op1, &fp); if (ir_type_size[src_type] == 1) { - if (ir_type_size[dst_type] == 2) { - | ldrsb Rw(def_reg), [Rx(fp), #offset] - } else if (ir_type_size[dst_type] == 4) { - | ldrsb Rw(def_reg), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, ir_type_size[src_type])) { + if (ir_type_size[dst_type] == 2) { + | ldrsb Rw(def_reg), [Rx(fp), #offset] + } else if (ir_type_size[dst_type] == 4) { + | ldrsb Rw(def_reg), [Rx(fp), #offset] + } else { + IR_ASSERT(ir_type_size[dst_type] == 8); + | ldrsb Rx(def_reg), [Rx(fp), #offset] + } } else { - IR_ASSERT(ir_type_size[dst_type] == 8); - | ldrsb Rx(def_reg), [Rx(fp), #offset] + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + if (ir_type_size[dst_type] == 2) { + | ldrsb Rw(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } else if (ir_type_size[dst_type] == 4) { + | ldrsb Rw(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } else { + IR_ASSERT(ir_type_size[dst_type] == 8); + | ldrsb Rx(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } } else if (ir_type_size[src_type] == 2) { - if (ir_type_size[dst_type] == 4) { - | ldrsh Rw(def_reg), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, ir_type_size[src_type])) { + if (ir_type_size[dst_type] == 4) { + | ldrsh Rw(def_reg), [Rx(fp), #offset] + } else { + IR_ASSERT(ir_type_size[dst_type] == 8); + | ldrsh Rx(def_reg), [Rx(fp), #offset] + } } else { - IR_ASSERT(ir_type_size[dst_type] == 8); - | ldrsh Rx(def_reg), [Rx(fp), #offset] + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + if (ir_type_size[dst_type] == 4) { + | ldrsh Rw(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } else { + IR_ASSERT(ir_type_size[dst_type] == 8); + | ldrsh Rx(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } } else { IR_ASSERT(ir_type_size[src_type] == 4); IR_ASSERT(ir_type_size[dst_type] == 8); - | ldrsw Rx(def_reg), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, ir_type_size[src_type])) { + | ldrsw Rx(def_reg), [Rx(fp), #offset] + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | ldrsw Rx(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } } if (IR_REG_SPILLED(ctx->regs[def][0])) { @@ -3365,14 +3712,27 @@ static void ir_emit_zext(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_reg fp; int32_t offset = ir_ref_spill_slot_offset(ctx, insn->op1, &fp); - if (ir_type_size[src_type] == 1) { - | ldrb Rw(def_reg), [Rx(fp), #offset] - } else if (ir_type_size[src_type] == 2) { - | ldrh Rw(def_reg), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, ir_type_size[src_type])) { + if (ir_type_size[src_type] == 1) { + | ldrb Rw(def_reg), [Rx(fp), #offset] + } else if (ir_type_size[src_type] == 2) { + | ldrh Rw(def_reg), [Rx(fp), #offset] + } else { + IR_ASSERT(ir_type_size[src_type] == 4); + IR_ASSERT(ir_type_size[dst_type] == 8); + | ldr Rw(def_reg), [Rx(fp), #offset] + } } else { - IR_ASSERT(ir_type_size[src_type] == 4); - IR_ASSERT(ir_type_size[dst_type] == 8); - | ldr Rw(def_reg), [Rx(fp), #offset] + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + if (ir_type_size[src_type] == 1) { + | ldrb Rw(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } else if (ir_type_size[src_type] == 2) { + | ldrh Rw(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } else { + IR_ASSERT(ir_type_size[src_type] == 4); + IR_ASSERT(ir_type_size[dst_type] == 8); + | ldr Rw(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } } if (IR_REG_SPILLED(ctx->regs[def][0])) { @@ -3471,11 +3831,21 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_reg fp; int32_t offset = ir_ref_spill_slot_offset(ctx, insn->op1, &fp); - if (src_type == IR_DOUBLE) { - | ldr Rx(def_reg), [Rx(fp), #offset] + if (aarch64_may_encode_addr_offset(offset, ir_type_size[src_type])) { + if (src_type == IR_DOUBLE) { + | ldr Rx(def_reg), [Rx(fp), #offset] + } else { + IR_ASSERT(src_type == IR_FLOAT); + | ldr Rw(def_reg), [Rx(fp), #offset] + } } else { - IR_ASSERT(src_type == IR_FLOAT); - | ldr Rw(def_reg), [Rx(fp), #offset] + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + if (src_type == IR_DOUBLE) { + | ldr Rx(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } else { + IR_ASSERT(src_type == IR_FLOAT); + | ldr Rw(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } } } } else if (IR_IS_TYPE_FP(dst_type)) { @@ -3497,12 +3867,22 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_reg fp; int32_t offset = ir_ref_spill_slot_offset(ctx, insn->op1, &fp); - if (dst_type == IR_DOUBLE) { - | ldr Rd(def_reg), [Rx(fp), #offset] - } else { - IR_ASSERT(src_type == IR_FLOAT); - | ldr Rs(def_reg), [Rx(fp), #offset] - } + if (aarch64_may_encode_addr_offset(offset, ir_type_size[src_type])) { + if (dst_type == IR_DOUBLE) { + | ldr Rd(def_reg), [Rx(fp), #offset] + } else { + IR_ASSERT(dst_type == IR_FLOAT); + | ldr Rs(def_reg), [Rx(fp), #offset] + } + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + if (dst_type == IR_DOUBLE) { + | ldr Rd(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } else { + IR_ASSERT(dst_type == IR_FLOAT); + | ldr Rs(def_reg), [Rx(fp), Rx(IR_REG_INT_TMP)] + } + } } } if (IR_REG_SPILLED(ctx->regs[def][0])) { @@ -3725,7 +4105,12 @@ static void ir_emit_vaddr(ir_ctx *ctx, ir_ref def, ir_insn *insn) IR_ASSERT(def_reg != IR_REG_NONE); offset = ir_var_spill_slot(ctx, insn->op1, &fp); - | add Rx(def_reg), Rx(fp), #offset + if (aarch64_may_encode_imm12(offset)) { + | add Rx(def_reg), Rx(fp), #offset + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, offset); + | add Rx(def_reg), Rx(fp), Rx(IR_REG_INT_TMP) + } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, type, def, def_reg); } @@ -3797,7 +4182,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) IR_ASSERT(!IR_IS_SYM_CONST(ctx->ir_base[addr_insn->op2].op)); if (ir_rule(ctx, addr_insn->op1) == IR_STATIC_ALLOCA) { reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[addr_insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[addr_insn->op1]); offset += ctx->ir_base[addr_insn->op2].val.i32; return IR_MEM_BO(reg, offset); } else { @@ -3815,7 +4200,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) } else { IR_ASSERT(addr_insn->op == IR_ALLOCA || addr_insn->op == IR_VADDR); reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[ref].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[ref]); return IR_MEM_BO(reg, offset); } } @@ -4113,7 +4498,12 @@ static void ir_emit_afree(ir_ctx *ctx, ir_ref def, ir_insn *insn) /* Stack must be 16 byte aligned */ size = IR_ALIGNED_SIZE(size, 16); - | add sp, sp, #size + if (aarch64_may_encode_imm12(size)) { + | add sp, sp, #size + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, size); + | add sp, sp, Rx(IR_REG_INT_TMP) + } if (!(ctx->flags & IR_USE_FRAME_POINTER)) { ctx->call_stack_size -= size; } @@ -4175,8 +4565,11 @@ static void ir_emit_frame_addr(ir_ctx *ctx, ir_ref def) if (ctx->flags & IR_USE_FRAME_POINTER) { | mov Rx(def_reg), Rx(IR_REG_X29) - } else { + } else if (aarch64_may_encode_imm12(ctx->stack_frame_size + ctx->call_stack_size)) { | add Rx(def_reg), Rx(IR_REG_X31), #(ctx->stack_frame_size + ctx->call_stack_size) + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, ctx->stack_frame_size + ctx->call_stack_size); + | add Rx(def_reg), Rx(IR_REG_X31), Rx(IR_REG_INT_TMP) } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, IR_ADDR, def, def_reg); @@ -4185,271 +4578,281 @@ static void ir_emit_frame_addr(ir_ctx *ctx, ir_ref def) static void ir_emit_va_start(ir_ctx *ctx, ir_ref def, ir_insn *insn) { -#ifdef __APPLE__ ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; dasm_State **Dst = &data->dasm_state; - ir_reg fp; - int arg_area_offset; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - int32_t offset; - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); - } - offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } + if (!cc->sysv_varargs) { + ir_reg fp; + int arg_area_offset; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + int32_t offset; - if (ctx->flags & IR_USE_FRAME_POINTER) { - fp = IR_REG_FRAME_POINTER; - arg_area_offset = ctx->stack_frame_size + sizeof(void*) * 2 + ctx->param_stack_size; - } else { - fp = IR_REG_STACK_POINTER; - arg_area_offset = ctx->call_stack_size + ctx->stack_frame_size + ctx->param_stack_size; - } - | add Rx(tmp_reg), Rx(fp), #arg_area_offset - | str Rx(tmp_reg), [Rx(op2_reg), #offset] -#else - ir_backend_data *data = ctx->data; - dasm_State **Dst = &data->dasm_state; - ir_reg fp; - int reg_save_area_offset; - int overflow_arg_area_offset; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - int32_t offset; + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); + } - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + if (ctx->flags & IR_USE_FRAME_POINTER) { + fp = IR_REG_FRAME_POINTER; + arg_area_offset = ctx->stack_frame_size + sizeof(void*) * 2 + ctx->param_stack_size; + } else { + fp = IR_REG_STACK_POINTER; + arg_area_offset = ctx->call_stack_size + ctx->stack_frame_size + ctx->param_stack_size; } - offset = 0; + | add Rx(tmp_reg), Rx(fp), #arg_area_offset + | str Rx(tmp_reg), [Rx(op2_reg), #offset] } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } + ir_reg fp; + int reg_save_area_offset; + int overflow_arg_area_offset; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + int32_t offset; - if (ctx->flags & IR_USE_FRAME_POINTER) { - fp = IR_REG_FRAME_POINTER; - reg_save_area_offset = ctx->locals_area_size + sizeof(void*) * 2; - overflow_arg_area_offset = ctx->stack_frame_size + sizeof(void*) * 2 + ctx->param_stack_size; - } else { - fp = IR_REG_STACK_POINTER; - reg_save_area_offset = ctx->locals_area_size + ctx->call_stack_size; - overflow_arg_area_offset = ctx->call_stack_size + ctx->stack_frame_size + ctx->param_stack_size; - } - - /* Set va_list.stack */ - | add Rx(tmp_reg), Rx(fp), #overflow_arg_area_offset - | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))] - if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < IR_REG_INT_ARGS) { - reg_save_area_offset += sizeof(void*) * IR_REG_INT_ARGS; - /* Set va_list.gr_top */ - if (overflow_arg_area_offset != reg_save_area_offset) { - | add Rx(tmp_reg), Rx(fp), #reg_save_area_offset - } - | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_top))] - /* Set va_list.gr_offset */ - | movn Rw(tmp_reg), #~(0 - (sizeof(void*) * (IR_REG_INT_ARGS - ctx->gp_reg_params))) - | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_offset))] - } else { - /* Set va_list.gr_offset */ - | str wzr, [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_offset))] - } - if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < IR_REG_FP_ARGS) { - reg_save_area_offset += 16 * IR_REG_FP_ARGS; - /* Set va_list.vr_top */ - if (overflow_arg_area_offset != reg_save_area_offset) { - | add Rx(tmp_reg), Rx(fp), #reg_save_area_offset - } - | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_top))] - /* Set va_list.vr_offset */ - | movn Rw(tmp_reg), #~(0 - (16 * (IR_REG_FP_ARGS - ctx->fp_reg_params))) - | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_offset))] - } else { - /* Set va_list.vr_offset */ - | str wzr, [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_offset))] + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); + } + + if (ctx->flags & IR_USE_FRAME_POINTER) { + fp = IR_REG_FRAME_POINTER; + reg_save_area_offset = ctx->locals_area_size + sizeof(void*) * 2; + overflow_arg_area_offset = ctx->stack_frame_size + sizeof(void*) * 2 + ctx->param_stack_size; + } else { + fp = IR_REG_STACK_POINTER; + reg_save_area_offset = ctx->locals_area_size + ctx->call_stack_size; + overflow_arg_area_offset = ctx->call_stack_size + ctx->stack_frame_size + ctx->param_stack_size; + } + + /* Set va_list.stack */ + | add Rx(tmp_reg), Rx(fp), #overflow_arg_area_offset + | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, stack))] + if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < cc->int_param_regs_count) { + reg_save_area_offset += sizeof(void*) * cc->int_param_regs_count; + /* Set va_list.gr_top */ + if (overflow_arg_area_offset != reg_save_area_offset) { + | add Rx(tmp_reg), Rx(fp), #reg_save_area_offset + } + | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, gr_top))] + /* Set va_list.gr_offset */ + | movn Rw(tmp_reg), #~(0 - (sizeof(void*) * (cc->int_param_regs_count - ctx->gp_reg_params))) + | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, gr_offset))] + } else { + /* Set va_list.gr_offset */ + | str wzr, [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, gr_offset))] + } + if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < cc->fp_param_regs_count) { + reg_save_area_offset += 16 * cc->fp_param_regs_count; + /* Set va_list.vr_top */ + if (overflow_arg_area_offset != reg_save_area_offset || ctx->gp_reg_params < cc->int_param_regs_count) { + | add Rx(tmp_reg), Rx(fp), #reg_save_area_offset + } + | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, vr_top))] + /* Set va_list.vr_offset */ + | movn Rw(tmp_reg), #~(0 - (16 * (cc->fp_param_regs_count - ctx->fp_reg_params))) + | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, vr_offset))] + } else { + /* Set va_list.vr_offset */ + | str wzr, [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, vr_offset))] + } } -#endif } static void ir_emit_va_copy(ir_ctx *ctx, ir_ref def, ir_insn *insn) { -#ifdef __APPLE__ ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; dasm_State **Dst = &data->dasm_state; - ir_reg tmp_reg = ctx->regs[def][1]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg op3_reg = ctx->regs[def][3]; - int32_t op2_offset, op3_offset; - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + if (!cc->sysv_varargs) { + ir_reg tmp_reg = ctx->regs[def][1]; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg op3_reg = ctx->regs[def][3]; + int32_t op2_offset, op3_offset; + + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + op2_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op2_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); } - op2_offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op2_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - if (op3_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op3_reg)) { - op3_reg = IR_REG_NUM(op3_reg); - ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); + if (op3_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op3_reg)) { + op3_reg = IR_REG_NUM(op3_reg); + ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); + } + op3_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); + op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op3_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op3]); } - op3_offset = 0; + | ldr Rx(tmp_reg), [Rx(op3_reg), #op3_offset] + | str Rx(tmp_reg), [Rx(op2_reg), #op2_offset] } else { - IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); - op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op3_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op3].op3); - } - | ldr Rx(tmp_reg), [Rx(op3_reg), #op3_offset] - | str Rx(tmp_reg), [Rx(op2_reg), #op2_offset] -#else - ir_backend_data *data = ctx->data; - dasm_State **Dst = &data->dasm_state; - ir_reg tmp_reg = ctx->regs[def][1]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg op3_reg = ctx->regs[def][3]; - int32_t op2_offset, op3_offset; + ir_reg tmp_reg = ctx->regs[def][1]; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg op3_reg = ctx->regs[def][3]; + int32_t op2_offset, op3_offset; - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + op2_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op2_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); } - op2_offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op2_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); + if (op3_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op3_reg)) { + op3_reg = IR_REG_NUM(op3_reg); + ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); + } + op3_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); + op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op3_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op3]); + } + | ldr Rx(tmp_reg), [Rx(op3_reg), #op3_offset] + | str Rx(tmp_reg), [Rx(op2_reg), #op2_offset] + | ldr Rx(tmp_reg), [Rx(op3_reg), #(op3_offset+8)] + | str Rx(tmp_reg), [Rx(op2_reg), #(op2_offset+8)] + | ldr Rx(tmp_reg), [Rx(op3_reg), #(op3_offset+16)] + | str Rx(tmp_reg), [Rx(op2_reg), #(op2_offset+16)] + | ldr Rx(tmp_reg), [Rx(op3_reg), #(op3_offset+24)] + | str Rx(tmp_reg), [Rx(op2_reg), #(op2_offset+24)] } - if (op3_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op3_reg)) { - op3_reg = IR_REG_NUM(op3_reg); - ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); - } - op3_offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); - op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op3_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op3].op3); - } - | ldr Rx(tmp_reg), [Rx(op3_reg), #op3_offset] - | str Rx(tmp_reg), [Rx(op2_reg), #op2_offset] - | ldr Rx(tmp_reg), [Rx(op3_reg), #(op3_offset+8)] - | str Rx(tmp_reg), [Rx(op2_reg), #(op2_offset+8)] - | ldr Rx(tmp_reg), [Rx(op3_reg), #(op3_offset+16)] - | str Rx(tmp_reg), [Rx(op2_reg), #(op2_offset+16)] - | ldr Rx(tmp_reg), [Rx(op3_reg), #(op3_offset+24)] - | str Rx(tmp_reg), [Rx(op2_reg), #(op2_offset+24)] -#endif } static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn) { -#ifdef __APPLE__ ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; dasm_State **Dst = &data->dasm_state; - ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - int32_t offset; - IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + if (!cc->sysv_varargs) { + ir_type type = insn->type; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + int32_t offset; + + IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); + } + | ldr Rx(tmp_reg), [Rx(op2_reg), #offset] + if (def_reg != IR_REG_NONE) { + ir_emit_load_mem(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0)); + } + | add Rx(tmp_reg), Rx(tmp_reg), #IR_MAX(ir_type_size[type], sizeof(void*)) + | str Rx(tmp_reg), [Rx(op2_reg), #offset] + if (def_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, type, def, def_reg); } - offset = 0; } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - | ldr Rx(tmp_reg), [Rx(op2_reg), #offset] - ir_emit_load_mem(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0)); - | add Rx(tmp_reg), Rx(tmp_reg), #IR_MAX(ir_type_size[type], sizeof(void*)) - | str Rx(tmp_reg), [Rx(op2_reg), #offset] - if (IR_REG_SPILLED(ctx->regs[def][0])) { - ir_emit_store(ctx, type, def, def_reg); - } -#else - ir_backend_data *data = ctx->data; - dasm_State **Dst = &data->dasm_state; - ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - int32_t offset; + ir_type type = insn->type; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + int32_t offset; - IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); + } + if (IR_IS_TYPE_INT(type)) { + | ldr Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, gr_offset))] + | cmp Rw(tmp_reg), wzr + | bge >1 + | ldr Rx(IR_REG_INT_TMP), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, gr_top))] + | sxtw Rx(tmp_reg), Rw(tmp_reg) + | add Rx(IR_REG_INT_TMP), Rx(tmp_reg), Rx(IR_REG_INT_TMP) + if (def_reg != IR_REG_NONE) { + | ldr Rx(def_reg), [Rx(IR_REG_INT_TMP)] + } + | add Rw(tmp_reg), Rw(tmp_reg), #sizeof(void*) + | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, gr_offset))] + | b >2 + |1: + | ldr Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, stack))] + if (def_reg != IR_REG_NONE) { + | ldr Rx(def_reg), [Rx(tmp_reg)] + } + | add Rx(tmp_reg), Rx(tmp_reg), #sizeof(void*) + | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, stack))] + |2: + } else { + | ldr Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, vr_offset))] + | cmp Rw(tmp_reg), wzr + | bge >1 + | ldr Rx(IR_REG_INT_TMP), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, vr_top))] + | sxtw Rx(tmp_reg), Rw(tmp_reg) + | add Rx(IR_REG_INT_TMP), Rx(tmp_reg), Rx(IR_REG_INT_TMP) + if (def_reg != IR_REG_NONE) { + | ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(IR_REG_INT_TMP)] + } + | add Rw(tmp_reg), Rw(tmp_reg), #16 + | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, vr_offset))] + | b >2 + |1: + | ldr Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, stack))] + if (def_reg != IR_REG_NONE) { + | ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(tmp_reg)] + } + | add Rx(tmp_reg), Rx(tmp_reg), #sizeof(void*) + | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_aarch64_sysv_va_list, stack))] + |2: + } + if (def_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, type, def, def_reg); } - offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - if (IR_IS_TYPE_INT(type)) { - | ldr Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_offset))] - | cmp Rw(tmp_reg), wzr - | bge >1 - | ldr Rx(IR_REG_INT_TMP), [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_top))] - | sxtw Rx(tmp_reg), Rw(tmp_reg) - | add Rx(IR_REG_INT_TMP), Rx(tmp_reg), Rx(IR_REG_INT_TMP) - | ldr Rx(def_reg), [Rx(IR_REG_INT_TMP)] - | add Rw(tmp_reg), Rw(tmp_reg), #sizeof(void*) - | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_offset))] - | b >2 - |1: - | ldr Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))] - | ldr Rx(def_reg), [Rx(tmp_reg)] - | add Rx(tmp_reg), Rx(tmp_reg), #sizeof(void*) - | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))] - |2: - } else { - | ldr Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_offset))] - | cmp Rw(tmp_reg), wzr - | bge >1 - | ldr Rx(IR_REG_INT_TMP), [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_top))] - | sxtw Rx(tmp_reg), Rw(tmp_reg) - | add Rx(IR_REG_INT_TMP), Rx(tmp_reg), Rx(IR_REG_INT_TMP) - | ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(IR_REG_INT_TMP)] - | add Rw(tmp_reg), Rw(tmp_reg), #16 - | str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_offset))] - | b >2 - |1: - | ldr Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))] - | ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(tmp_reg)] - | add Rx(tmp_reg), Rx(tmp_reg), #sizeof(void*) - | str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))] - |2: - } - if (IR_REG_SPILLED(ctx->regs[def][0])) { - ir_emit_store(ctx, type, def, def_reg); } -#endif } static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) @@ -4465,6 +4868,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) int count = 0; ir_val min, max; ir_reg op1_reg, op2_reg, tmp_reg; + bool has_case_range = 0; type = ctx->ir_base[insn->op2].type; if (IR_IS_TYPE_SIGNED(type)) { @@ -4493,6 +4897,22 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) max.u64 = (int64_t)IR_MAX(max.u64, val->val.u64); } count++; + } else if (use_insn->op == IR_CASE_RANGE) { + has_case_range = 1; + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + ir_insn *val2 = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val2->op)); + if (IR_IS_TYPE_SIGNED(type)) { + IR_ASSERT(IR_IS_TYPE_SIGNED(val->type)); + min.i64 = IR_MIN(min.i64, val->val.i64); + max.i64 = IR_MAX(max.i64, val2->val.i64); + } else { + IR_ASSERT(!IR_IS_TYPE_SIGNED(val->type)); + min.u64 = (int64_t)IR_MIN(min.u64, val->val.u64); + max.u64 = (int64_t)IR_MAX(max.u64, val2->val.u64); + } + count++; } else { IR_ASSERT(use_insn->op == IR_CASE_DEFAULT); default_label = ir_skip_empty_target_blocks(ctx, use_block); @@ -4510,7 +4930,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } /* Generate a table jmp or a sequence of calls */ - if (count > 2 && (max.i64-min.i64) < count * 8) { + if (!has_case_range && count > 2 && (max.i64-min.i64) < count * 8) { int *labels = ir_mem_malloc(sizeof(int) * (max.i64 - min.i64 + 1)); for (i = 0; i <= (max.i64 - min.i64); i++) { @@ -4585,7 +5005,8 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]); | .addr &addr - if (ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { + if (ctx->ir_base[bb->start].op1 == def + && ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { bb->flags |= IR_BB_EMPTY; } continue; @@ -4615,6 +5036,38 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } | beq =>label + } else if (use_insn->op == IR_CASE_RANGE) { + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (aarch64_may_encode_imm12(val->val.i64)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i64 + } else { + ir_emit_load_imm_int(ctx, type, tmp_reg, val->val.i64); + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg + + } + if (IR_IS_TYPE_SIGNED(type)) { + | blt >1 + } else { + | blo >1 + } + val = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (aarch64_may_encode_imm12(val->val.i64)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i64 + } else { + ir_emit_load_imm_int(ctx, type, tmp_reg, val->val.i64); + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg + + } + if (IR_IS_TYPE_SIGNED(type)) { + | ble =>label + } else { + | bls =>label + } + |1: } } if (default_label) { @@ -4623,46 +5076,58 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } } -static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn) +static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn, const ir_call_conv_dsc *cc, int32_t *copy_stack_ptr) { int j, n; ir_type type; int int_param = 0; int fp_param = 0; - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - int32_t used_stack = 0; -#ifdef __APPLE__ - const ir_proto_t *proto = ir_call_proto(ctx, insn); - int last_named_input = (proto && (proto->flags & IR_VARARG_FUNC)) ? proto->params_count + 2 : insn->inputs_count; -#endif + int32_t used_stack = 0, copy_stack = 0; + + /* On APPLE "unnamed" arguments always passed through stack */ + int last_named_input; + + if (!cc->sysv_varargs) { + const ir_proto_t *proto = ir_call_proto(ctx, insn); + last_named_input = (proto && (proto->flags & IR_VARARG_FUNC)) ? proto->params_count + 2 : insn->inputs_count; + } else { + last_named_input = insn->inputs_count; + } n = insn->inputs_count; for (j = 3; j <= n; j++) { - type = ctx->ir_base[ir_insn_op(insn, j)].type; -#ifdef __APPLE__ + ir_insn *arg = &ctx->ir_base[ir_insn_op(insn, j)]; + type = arg->type; + if (arg->op == IR_ARGVAL) { + int size = arg->op2; + int align = arg->op3; + copy_stack += size; + align = IR_MAX((int)sizeof(void*), align); + copy_stack = IR_ALIGNED_SIZE(copy_stack, align); + type = IR_ADDR; + } if (j > last_named_input) { used_stack += IR_MAX(sizeof(void*), ir_type_size[type]); - } else -#endif - if (IR_IS_TYPE_INT(type)) { - if (int_param >= int_reg_params_count) { + } else if (IR_IS_TYPE_INT(type)) { + if (int_param >= cc->int_param_regs_count) { used_stack += IR_MAX(sizeof(void*), ir_type_size[type]); } int_param++; } else { IR_ASSERT(IR_IS_TYPE_FP(type)); - if (fp_param >= fp_reg_params_count) { + if (fp_param >= cc->fp_param_regs_count) { used_stack += IR_MAX(sizeof(void*), ir_type_size[type]); } fp_param++; } } - return used_stack; + copy_stack = IR_ALIGNED_SIZE(copy_stack, 16); + *copy_stack_ptr = copy_stack; + return used_stack + copy_stack; } -static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg) +static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, const ir_call_conv_dsc *cc, ir_reg tmp_reg) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; @@ -4674,11 +5139,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg int int_param = 0; int fp_param = 0; int count = 0; - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; - int32_t used_stack, stack_offset = 0; + int32_t used_stack, copy_stack = 0, stack_offset = 0, copy_stack_offset = 0; ir_copy *copies; bool do_pass3 = 0; /* For temporaries we may use any scratch registers except for registers used for parameters */ @@ -4697,7 +5158,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg // TODO: support for preallocated stack used_stack = 0; } else { - used_stack = ir_call_used_stack(ctx, insn); + used_stack = ir_call_used_stack(ctx, insn, cc, ©_stack); /* Stack must be 16 byte aligned */ used_stack = IR_ALIGNED_SIZE(used_stack, 16); if (ctx->fixed_call_stack_size && used_stack <= ctx->fixed_call_stack_size) { @@ -4715,10 +5176,57 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg } } -#ifdef __APPLE__ - const ir_proto_t *proto = ir_call_proto(ctx, insn); - int last_named_input = (proto && (proto->flags & IR_VARARG_FUNC)) ? proto->params_count + 2 : insn->inputs_count; -#endif + /* On APPLE "unnamed" arguments always passed through stack */ + int last_named_input; + + if (!cc->sysv_varargs) { + const ir_proto_t *proto = ir_call_proto(ctx, insn); + last_named_input = (proto && (proto->flags & IR_VARARG_FUNC)) ? proto->params_count + 2 : insn->inputs_count; + } else { + last_named_input = insn->inputs_count; + } + + if (copy_stack) { + /* Copy struct arguments */ + for (j = 3; j <= n; j++) { + arg = ir_insn_op(insn, j); + src_reg = ir_get_alocated_reg(ctx, def, j); + arg_insn = &ctx->ir_base[arg]; + type = arg_insn->type; + + if (arg_insn->op == IR_ARGVAL) { + /* make a stack copy */ + void *addr = memcpy; + int size = arg_insn->op2; + int align = arg_insn->op3; + + copy_stack_offset += size; + align = IR_MAX((int)sizeof(void*), align); + copy_stack_offset = IR_ALIGNED_SIZE(copy_stack_offset, align); + src_reg = ctx->regs[arg][1]; + + | add Rx(ir_call_conv_default.int_param_regs[0]), sp, #(used_stack - copy_stack_offset) + if (src_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(src_reg)) { + src_reg = IR_REG_NUM(src_reg); + ir_emit_load(ctx, IR_ADDR, src_reg, arg_insn->op1); + } + | mov Rx(ir_call_conv_default.int_param_regs[1]), Rx(src_reg) + } else { + ir_emit_load(ctx, IR_ADDR, ir_call_conv_default.int_param_regs[1], arg_insn->op1); + } + ir_emit_load_imm_int(ctx, IR_ADDR, ir_call_conv_default.int_param_regs[2], size); + + if (aarch64_may_use_b(ctx->code_buffer, addr)) { + | bl &addr + } else { + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_INT_TMP, (intptr_t)addr); + | blr Rx(IR_REG_INT_TMP) + } + } + } + copy_stack_offset = 0; + } /* 1. move all register arguments that should be passed through stack * and collect arguments that should be passed through registers */ @@ -4728,29 +5236,37 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg src_reg = ir_get_alocated_reg(ctx, def, j); arg_insn = &ctx->ir_base[arg]; type = arg_insn->type; -#ifdef __APPLE__ + if (j > last_named_input) { + if (arg_insn->op == IR_ARGVAL) { + do_pass3 = 1; + continue; + } dst_reg = IR_REG_NONE; /* pass argument through stack */ - } else -#endif - if (IR_IS_TYPE_INT(type)) { - if (int_param < int_reg_params_count) { - dst_reg = int_reg_params[int_param]; + } else if (IR_IS_TYPE_INT(type)) { + if (int_param < cc->int_param_regs_count) { + dst_reg = cc->int_param_regs[int_param]; } else { dst_reg = IR_REG_NONE; /* pass argument through stack */ } int_param++; + if (arg_insn->op == IR_ARGVAL) { + do_pass3 = 1; + continue; + } } else { IR_ASSERT(IR_IS_TYPE_FP(type)); - if (fp_param < fp_reg_params_count) { - dst_reg = fp_reg_params[fp_param]; + if (fp_param < cc->fp_param_regs_count) { + dst_reg = cc->fp_param_regs[fp_param]; } else { dst_reg = IR_REG_NONE; /* pass argument through stack */ } fp_param++; } if (dst_reg != IR_REG_NONE) { - if (src_reg == IR_REG_NONE) { + if (IR_IS_CONST_REF(arg) || + src_reg == IR_REG_NONE || + (IR_REG_SPILLED(src_reg) && !IR_REGSET_IN(cc->preserved_regs, IR_REG_NUM(src_reg)))) { /* delay CONST->REG and MEM->REG moves to third pass */ do_pass3 = 1; } else { @@ -4794,29 +5310,50 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg src_reg = ir_get_alocated_reg(ctx, def, j); arg_insn = &ctx->ir_base[arg]; type = arg_insn->type; -#ifdef __APPLE__ + if (arg_insn->op == IR_ARGVAL) { + /* pass pointer to the copy on stack */ + int size = arg_insn->op2; + int align = arg_insn->op3; + + copy_stack_offset += size; + align = IR_MAX((int)sizeof(void*), align); + copy_stack_offset = IR_ALIGNED_SIZE(copy_stack_offset, align); + if (j > last_named_input) { + | add Rx(tmp_reg), sp, #(used_stack - copy_stack_offset) + ir_emit_store_mem_int(ctx, IR_ADDR, IR_MEM_BO(IR_REG_STACK_POINTER, stack_offset), tmp_reg); + } else if (int_param < cc->int_param_regs_count) { + dst_reg = cc->int_param_regs[int_param]; + | add Rx(dst_reg), sp, #(used_stack - copy_stack_offset) + } else { + | add Rx(tmp_reg), sp, #(used_stack - copy_stack_offset) + ir_emit_store_mem_int(ctx, IR_ADDR, IR_MEM_BO(IR_REG_STACK_POINTER, stack_offset), tmp_reg); + stack_offset += sizeof(void*); + } + int_param++; + continue; + } if (j > last_named_input) { dst_reg = IR_REG_NONE; /* pass argument through stack */ - } else -#endif - if (IR_IS_TYPE_INT(type)) { - if (int_param < int_reg_params_count) { - dst_reg = int_reg_params[int_param]; + } else if (IR_IS_TYPE_INT(type)) { + if (int_param < cc->int_param_regs_count) { + dst_reg = cc->int_param_regs[int_param]; } else { dst_reg = IR_REG_NONE; /* argument already passed through stack */ } int_param++; } else { IR_ASSERT(IR_IS_TYPE_FP(type)); - if (fp_param < fp_reg_params_count) { - dst_reg = fp_reg_params[fp_param]; + if (fp_param < cc->fp_param_regs_count) { + dst_reg = cc->fp_param_regs[fp_param]; } else { dst_reg = IR_REG_NONE; /* argument already passed through stack */ } fp_param++; } if (dst_reg != IR_REG_NONE) { - if (src_reg == IR_REG_NONE) { + if (IR_IS_CONST_REF(arg) || + src_reg == IR_REG_NONE || + (IR_REG_SPILLED(src_reg) && !IR_REGSET_IN(cc->preserved_regs, IR_REG_NUM(src_reg)))) { if (IR_IS_CONST_REF(arg) && IR_IS_TYPE_INT(type)) { if (ir_type_size[type] == 1) { type = IR_ADDR; @@ -4856,7 +5393,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg return used_stack; } -static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used_stack) +static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, const ir_call_conv_dsc *cc, int32_t used_stack) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; @@ -4891,27 +5428,27 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used if (IR_IS_TYPE_INT(insn->type)) { def_reg = IR_REG_NUM(ctx->regs[def][0]); if (def_reg != IR_REG_NONE) { - if (def_reg != IR_REG_INT_RET1) { - ir_emit_mov(ctx, insn->type, def_reg, IR_REG_INT_RET1); + if (def_reg != cc->int_ret_reg) { + ir_emit_mov(ctx, insn->type, def_reg, cc->int_ret_reg); } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, insn->type, def, def_reg); } } else if (ctx->use_lists[def].count > 1) { - ir_emit_store(ctx, insn->type, def, IR_REG_INT_RET1); + ir_emit_store(ctx, insn->type, def, cc->int_ret_reg); } } else { IR_ASSERT(IR_IS_TYPE_FP(insn->type)); def_reg = IR_REG_NUM(ctx->regs[def][0]); if (def_reg != IR_REG_NONE) { - if (def_reg != IR_REG_FP_RET1) { - ir_emit_fp_mov(ctx, insn->type, def_reg, IR_REG_FP_RET1); + if (def_reg != cc->fp_ret_reg) { + ir_emit_fp_mov(ctx, insn->type, def_reg, cc->fp_ret_reg); } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, insn->type, def, def_reg); } } else if (ctx->use_lists[def].count > 1) { - ir_emit_store(ctx, insn->type, def, IR_REG_FP_RET1); + ir_emit_store(ctx, insn->type, def, cc->fp_ret_reg); } } } @@ -4919,22 +5456,48 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn) { - int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); - ir_emit_call_ex(ctx, def, insn, used_stack); + const ir_proto_t *proto = ir_call_proto(ctx, insn); + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + int32_t used_stack = ir_emit_arguments(ctx, def, insn, cc, ctx->regs[def][1]); + ir_emit_call_ex(ctx, def, insn, cc, used_stack); } static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); + const ir_proto_t *proto = ir_call_proto(ctx, insn); + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + int32_t used_stack = ir_emit_arguments(ctx, def, insn, cc, ctx->regs[def][1]); if (used_stack != 0) { - ir_emit_call_ex(ctx, def, insn, used_stack); + ir_emit_call_ex(ctx, def, insn, cc, used_stack); ir_emit_return_void(ctx); return; } + /* Move op2 to a tmp register before epilogue if it's in + * used_preserved_regs, because it will be overridden. */ + + ir_reg op2_reg = IR_REG_NONE; + if (!IR_IS_CONST_REF(insn->op2)) { + op2_reg = ctx->regs[def][2]; + IR_ASSERT(op2_reg != IR_REG_NONE); + + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_INT_TMP; + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } else if (IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, IR_REG_NUM(op2_reg))) { + ir_reg orig_op2_reg = op2_reg; + op2_reg = IR_REG_INT_TMP; + + ir_type type = ctx->ir_base[insn->op2].type; + | ASM_REG_REG_OP mov, type, op2_reg, IR_REG_NUM(orig_op2_reg) + } else { + op2_reg = IR_REG_NUM(op2_reg); + } + } + ir_emit_epilogue(ctx); if (IR_IS_CONST_REF(insn->op2)) { @@ -4947,13 +5510,8 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) | br Rx(IR_REG_INT_TMP) } } else { - ir_reg op2_reg = ctx->regs[def][2]; - IR_ASSERT(op2_reg != IR_REG_NONE); - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); - } + IR_ASSERT(!IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, op2_reg)); | br Rx(op2_reg) } } @@ -4971,6 +5529,19 @@ static void ir_emit_ijmp(ir_ctx *ctx, ir_ref def, ir_insn *insn) } | br Rx(op2_reg) } else if (IR_IS_CONST_REF(insn->op2)) { + if (ctx->ir_base[insn->op2].op == IR_LABEL) { + if (!data->resolved_label_syms) { + data->resolved_label_syms = 1; + ir_resolve_label_syms(ctx); + } + + uint32_t target = ctx->ir_base[insn->op2].val.u32_hi; + target = ir_skip_empty_target_blocks(ctx, target); + + | b =>target + return; + } + void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]); if (aarch64_may_use_b(ctx->code_buffer, addr)) { @@ -5122,10 +5693,23 @@ static void ir_emit_guard_jcc(ir_ctx *ctx, uint8_t op, void *addr, bool int_cmp) case IR_GT: | bgt &addr break; -// case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break; -// case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break; -// case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break; -// case IR_UGT: fprintf(stderr, "\tja .LL%d\n", true_block); break; + case IR_ULT: + | blt &addr + break; + case IR_UGE: + | bhs &addr + break; + case IR_ULE: + | ble &addr + break; + case IR_UGT: + | bhi &addr + break; + case IR_ORDERED: + | bvc &addr + break; + case IR_UNORDERED: + | bvs &addr } } } @@ -5139,9 +5723,16 @@ static void ir_emit_guard_cmp_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn * ir_type type = ctx->ir_base[cmp_insn->op1].type; ir_ref op1 = cmp_insn->op1; ir_ref op2 = cmp_insn->op2; - ir_reg op1_reg = ctx->regs[insn->op2][1]; - ir_reg op2_reg = ctx->regs[insn->op2][2]; void *addr; + ir_reg op1_reg, op2_reg; + + if (UNEXPECTED(ctx->rules[insn->op2] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 2); + } else { + op1_reg = ctx->regs[insn->op2][1]; + op2_reg = ctx->regs[insn->op2][2]; + } if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { op1_reg = IR_REG_NUM(op1_reg); @@ -5195,11 +5786,15 @@ static void ir_emit_guard_cmp_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn * static void ir_emit_guard_cmp_fp(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) { - ir_op op = ir_emit_cmp_fp_common(ctx, insn->op2, &ctx->ir_base[insn->op2]); + ir_op op = ir_emit_cmp_fp_common(ctx, def, insn->op2, &ctx->ir_base[insn->op2]); void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op3]); if (insn->op == IR_GUARD) { - op ^= 1; // reverse + if (op == IR_EQ || op == IR_NE || op == IR_ORDERED || op == IR_UNORDERED) { + op ^= 1; // reverse + } else { + op ^= 5; // reverse + } } ir_emit_guard_jcc(ctx, op, addr, 0); } @@ -5285,6 +5880,7 @@ static void ir_emit_tls(ir_ctx *ctx, ir_ref def, ir_insn *insn) static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = &ir_call_conv_default; dasm_State **Dst = &data->dasm_state; ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); @@ -5324,10 +5920,10 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) | stp x2, x3, [sp, #-16]! | stp x0, x1, [sp, #-16]! - | mov Rx(IR_REG_INT_ARG2), sp - | add Rx(IR_REG_INT_ARG1), Rx(IR_REG_INT_ARG2), #(32*8+32*8) - | str Rx(IR_REG_INT_ARG1), [sp, #(31*8)] - | mov Rx(IR_REG_INT_ARG1), Rx(IR_REG_INT_TMP) + | mov Rx(cc->int_param_regs[1]), sp + | add Rx(cc->int_param_regs[0]), Rx(cc->int_param_regs[1]), #(32*8+32*8) + | str Rx(cc->int_param_regs[0]), [sp, #(31*8)] + | mov Rx(cc->int_param_regs[0]), Rx(IR_REG_INT_TMP) if (IR_IS_CONST_REF(insn->op2)) { void *addr = ir_call_addr(ctx, insn, &ctx->ir_base[insn->op2]); @@ -5344,8 +5940,8 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) | add sp, sp, #(32*8+32*8) - if (def_reg != IR_REG_INT_RET1) { - ir_emit_mov(ctx, insn->type, def_reg, IR_REG_INT_RET1); + if (def_reg != cc->int_ret_reg) { + ir_emit_mov(ctx, insn->type, def_reg, cc->int_ret_reg); } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, insn->type, def, def_reg); @@ -5356,6 +5952,7 @@ static void ir_emit_param_move(ir_ctx *ctx, uint8_t type, ir_reg from_reg, ir_re { ir_reg fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = IR_SPILL_POS_TO_OFFSET(offset); IR_ASSERT(from_reg != IR_REG_NONE || to_reg != IR_REG_NONE); if (IR_IS_TYPE_INT(type)) { @@ -5390,33 +5987,26 @@ static void ir_emit_load_params(ir_ctx *ctx) int fp_param_num = 0; ir_reg src_reg; ir_reg dst_reg; - // TODO: Calling convention specific - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; int32_t stack_offset = 0; + int32_t stack_start = ctx->stack_frame_size; - if (ctx->flags & IR_USE_FRAME_POINTER) { - stack_offset = sizeof(void*) * 2; /* skip old frame pointer and return address */ - } else { - stack_offset = ctx->stack_frame_size + ctx->call_stack_size; - } n = use_list->count; for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PARAM) { if (IR_IS_TYPE_INT(insn->type)) { - if (int_param_num < int_reg_params_count) { - src_reg = int_reg_params[int_param_num]; + if (int_param_num < cc->int_param_regs_count) { + src_reg = cc->int_param_regs[int_param_num]; } else { src_reg = IR_REG_NONE; } int_param_num++; } else { - if (fp_param_num < fp_reg_params_count) { - src_reg = fp_reg_params[fp_param_num]; + if (fp_param_num < cc->fp_param_regs_count) { + src_reg = cc->fp_param_regs[fp_param_num]; } else { src_reg = IR_REG_NONE; } @@ -5425,12 +6015,9 @@ static void ir_emit_load_params(ir_ctx *ctx) if (ctx->vregs[use]) { dst_reg = IR_REG_NUM(ctx->regs[use][0]); IR_ASSERT(src_reg != IR_REG_NONE || dst_reg != IR_REG_NONE || - stack_offset == ctx->live_intervals[ctx->vregs[use]]->stack_spill_pos + - ((ctx->flags & IR_USE_FRAME_POINTER) ? - -(ctx->stack_frame_size - ctx->stack_frame_alignment) : - ctx->call_stack_size)); + stack_start + stack_offset == ctx->live_intervals[ctx->vregs[use]]->stack_spill_pos); if (src_reg != dst_reg) { - ir_emit_param_move(ctx, insn->type, src_reg, dst_reg, use, stack_offset); + ir_emit_param_move(ctx, insn->type, src_reg, dst_reg, use, stack_start + stack_offset); } if (dst_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[use][0])) { ir_emit_store(ctx, insn->type, use, dst_reg); @@ -5459,10 +6046,9 @@ static ir_reg ir_get_free_reg(ir_type type, ir_regset available) return IR_REGSET_FIRST(available); } -static int ir_fix_dessa_tmps(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to) +static int ir_fix_dessa_tmps(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to, void *dessa_from_block) { - ir_backend_data *data = ctx->data; - ir_ref ref = ctx->cfg_blocks[data->dessa_from_block].end; + ir_ref ref = ctx->cfg_blocks[(intptr_t)dessa_from_block].end; if (to == 0) { if (IR_IS_TYPE_INT(type)) { @@ -5498,35 +6084,26 @@ static void ir_fix_param_spills(ir_ctx *ctx) int int_param_num = 0; int fp_param_num = 0; ir_reg src_reg; - // TODO: Calling convention specific - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; int32_t stack_offset = 0; - int32_t param_stack_size = 0; + int32_t stack_start = ctx->stack_frame_size; - if (ctx->flags & IR_USE_FRAME_POINTER) { - /* skip old frame pointer and return address */ - stack_offset = sizeof(void*) * 2 + (ctx->stack_frame_size - ctx->stack_frame_alignment); - } else { - stack_offset = ctx->stack_frame_size; - } n = use_list->count; for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PARAM) { if (IR_IS_TYPE_INT(insn->type)) { - if (int_param_num < int_reg_params_count) { - src_reg = int_reg_params[int_param_num]; + if (int_param_num < cc->int_param_regs_count) { + src_reg = cc->int_param_regs[int_param_num]; } else { src_reg = IR_REG_NONE; } int_param_num++; } else { - if (fp_param_num < fp_reg_params_count) { - src_reg = fp_reg_params[fp_param_num]; + if (fp_param_num < cc->fp_param_regs_count) { + src_reg = cc->fp_param_regs[fp_param_num]; } else { src_reg = IR_REG_NONE; } @@ -5538,23 +6115,21 @@ static void ir_fix_param_spills(ir_ctx *ctx) if ((ival->flags & IR_LIVE_INTERVAL_MEM_PARAM) && ival->stack_spill_pos == -1 && (ival->next || ival->reg == IR_REG_NONE)) { - ival->stack_spill_pos = stack_offset; + ival->stack_spill_pos = stack_start + stack_offset; } } if (sizeof(void*) == 8) { stack_offset += sizeof(void*); - param_stack_size += sizeof(void*); } else { stack_offset += IR_MAX(sizeof(void*), ir_type_size[insn->type]); - param_stack_size += IR_MAX(sizeof(void*), ir_type_size[insn->type]); } } } } - ctx->gp_reg_params = IR_MIN(int_param_num, int_reg_params_count); - ctx->fp_reg_params = IR_MIN(fp_param_num, fp_reg_params_count); - ctx->param_stack_size = param_stack_size; + ctx->gp_reg_params = IR_MIN(int_param_num, cc->int_param_regs_count); + ctx->fp_reg_params = IR_MIN(fp_param_num, cc->fp_param_regs_count); + ctx->param_stack_size = stack_offset; } static void ir_allocate_unique_spill_slots(ir_ctx *ctx) @@ -5564,11 +6139,13 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) ir_insn *insn; ir_ref i, n, j, *p; uint32_t *rule, insn_flags; - ir_backend_data *data = ctx->data; ir_regset available = 0; ir_target_constraints constraints; uint32_t def_flags; ir_reg reg; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; + ir_regset scratch = ir_scratch_regset[cc->scratch_reg - IR_REG_NUM]; ctx->regs = ir_mem_malloc(sizeof(ir_regs) * ctx->insns_count); memset(ctx->regs, IR_REG_NONE, sizeof(ir_regs) * ctx->insns_count); @@ -5590,10 +6167,12 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: case IR_LOOP_END: + case IR_IGOTO_DUP: break; default: def_flags = ir_get_target_constraints(ctx, i, &constraints); @@ -5602,7 +6181,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) && *rule != IR_CMP_AND_BRANCH_FP && *rule != IR_GUARD_CMP_INT && *rule != IR_GUARD_CMP_FP) { - available = IR_REGSET_SCRATCH; + available = scratch; } if (ctx->vregs[i]) { reg = constraints.def_reg; @@ -5610,7 +6189,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) IR_REGSET_EXCL(available, reg); ctx->regs[i][0] = reg | IR_REG_SPILL_STORE; } else if (def_flags & IR_USE_MUST_BE_IN_REG) { - if (insn->op == IR_VLOAD + if ((insn->op == IR_VLOAD || insn->op == IR_VLOAD_v) && ctx->live_intervals[ctx->vregs[i]] && ctx->live_intervals[ctx->vregs[i]]->stack_spill_pos != -1 && ir_is_same_mem_var(ctx, i, ctx->ir_base[insn->op2].op3)) { @@ -5632,7 +6211,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) if (insn->op == IR_PARAM && reg == IR_REG_NONE) { ival->flags |= IR_LIVE_INTERVAL_MEM_PARAM; } else { - ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type, &data->ra_data); + ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type); } } else if (insn->op == IR_PARAM) { IR_ASSERT(0 && "unexpected PARAM"); @@ -5643,14 +6222,14 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) ir_ref n = use_list->count; if (n > 0) { - int32_t stack_spill_pos = insn->op3 = ir_allocate_spill_slot(ctx, insn->type, &data->ra_data); + int32_t stack_spill_pos = insn->op3 = ir_allocate_spill_slot(ctx, insn->type); ir_ref i, *p, use; ir_insn *use_insn; for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { use = *p; use_insn = &ctx->ir_base[use]; - if (use_insn->op == IR_VLOAD) { + if (use_insn->op == IR_VLOAD || use_insn->op == IR_VLOAD_v) { if (ctx->vregs[use] && !ctx->live_intervals[ctx->vregs[use]]) { ir_live_interval *ival = ir_arena_alloc(&ctx->arena, sizeof(ir_live_interval)); @@ -5661,7 +6240,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) ival->vreg = ctx->vregs[use]; ival->stack_spill_pos = stack_spill_pos; } - } else if (use_insn->op == IR_VSTORE) { + } else if (use_insn->op == IR_VSTORE || use_insn->op == IR_STORE_v) { if (!IR_IS_CONST_REF(use_insn->op3) && ctx->vregs[use_insn->op3] && !ctx->live_intervals[ctx->vregs[use_insn->op3]]) { @@ -5698,10 +6277,13 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) } } ctx->regs[i][constraints.tmp_regs[n].num] = reg; - } else if (constraints.tmp_regs[n].reg == IR_REG_SCRATCH) { - available = IR_REGSET_DIFFERENCE(available, IR_REGSET_SCRATCH); } else { - IR_REGSET_EXCL(available, constraints.tmp_regs[n].reg); + reg = constraints.tmp_regs[n].reg; + if (reg >= IR_REG_NUM) { + available = IR_REGSET_DIFFERENCE(available, ir_scratch_regset[reg - IR_REG_NUM]); + } else { + IR_REGSET_EXCL(available, reg); + } } } while (n); } @@ -5737,8 +6319,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) rule += n; } if (bb->flags & IR_BB_DESSA_MOVES) { - data->dessa_from_block = b; - ir_gen_dessa_moves(ctx, b, ir_fix_dessa_tmps); + ir_gen_dessa_moves(ctx, b, ir_fix_dessa_tmps, (void*)(intptr_t)b); } } @@ -5755,7 +6336,11 @@ static void ir_preallocate_call_stack(ir_ctx *ctx) for (i = 1, insn = ctx->ir_base + 1; i < ctx->insns_count;) { if (insn->op == IR_CALL) { - call_stack_size = ir_call_used_stack(ctx, insn); + const ir_proto_t *proto = ir_call_proto(ctx, insn); + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + int32_t copy_stack; + + call_stack_size = ir_call_used_stack(ctx, insn, cc, ©_stack); if (call_stack_size > peak_call_stack_size) { peak_call_stack_size = call_stack_size; } @@ -5787,35 +6372,34 @@ void ir_fix_stack_frame(ir_ctx *ctx) } if ((ctx->flags & IR_VARARG_FUNC) && (ctx->flags2 & IR_HAS_VA_START)) { - if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < IR_REG_INT_ARGS) { - additional_size += sizeof(void*) * IR_REG_INT_ARGS; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; + + if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < cc->int_param_regs_count) { + additional_size += sizeof(void*) * cc->int_param_regs_count; } - if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < IR_REG_FP_ARGS) { - additional_size += 16 * IR_REG_FP_ARGS; + if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < cc->fp_param_regs_count) { + additional_size += 16 * cc->int_param_regs_count; } } ctx->stack_frame_size = IR_ALIGNED_SIZE(ctx->stack_frame_size, sizeof(void*)); ctx->stack_frame_size += additional_size; - ctx->stack_frame_alignment = 0; ctx->call_stack_size = 0; if (!(ctx->flags & IR_FUNCTION)) { while (IR_ALIGNED_SIZE(ctx->stack_frame_size, 16) != ctx->stack_frame_size) { ctx->stack_frame_size += sizeof(void*); - ctx->stack_frame_alignment += sizeof(void*); } } else { /* Stack must be 16 byte aligned */ if (!(ctx->flags & IR_FUNCTION)) { while (IR_ALIGNED_SIZE(ctx->stack_frame_size, 16) != ctx->stack_frame_size) { ctx->stack_frame_size += sizeof(void*); - ctx->stack_frame_alignment += sizeof(void*); } } else if (ctx->flags & IR_USE_FRAME_POINTER) { while (IR_ALIGNED_SIZE(ctx->stack_frame_size + sizeof(void*) * 2, 16) != ctx->stack_frame_size + sizeof(void*) * 2) { ctx->stack_frame_size += sizeof(void*); - ctx->stack_frame_alignment += sizeof(void*); } } else { if (!(ctx->flags & IR_NO_STACK_COMBINE)) { @@ -5824,7 +6408,6 @@ void ir_fix_stack_frame(ir_ctx *ctx) while (IR_ALIGNED_SIZE(ctx->stack_frame_size + ctx->call_stack_size, 16) != ctx->stack_frame_size + ctx->call_stack_size) { ctx->stack_frame_size += sizeof(void*); - ctx->stack_frame_alignment += sizeof(void*); } } } @@ -5860,18 +6443,21 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) int ret; void *entry; size_t size; + ir_ref igoto_dup_ref = IR_UNUSED; + uint32_t igoto_dup_block = 0; + data.ra_data.cc = ir_get_call_conv_dsc(ctx->flags); data.ra_data.unused_slot_4 = 0; data.ra_data.unused_slot_2 = 0; data.ra_data.unused_slot_1 = 0; data.ra_data.handled = NULL; data.rodata_label = 0; data.jmp_table_label = 0; + data.resolved_label_syms = 0; ctx->data = &data; if (!ctx->live_intervals) { ctx->stack_frame_size = 0; - ctx->stack_frame_alignment = 0; ctx->call_stack_size = 0; ctx->used_preserved_regs = 0; ir_allocate_unique_spill_slots(ctx); @@ -5893,7 +6479,6 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) } ctx->stack_frame_size = ctx->fixed_stack_frame_size; ctx->call_stack_size = ctx->fixed_call_stack_size; - ctx->stack_frame_alignment = 0; } Dst = &data.dasm_state; @@ -5903,6 +6488,14 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) dasm_setup(&data.dasm_state, dasm_actions); /* labels for each block + for each constant + rodata label + jmp_table label + for each entry + exit_table label */ dasm_growpc(&data.dasm_state, ctx->cfg_blocks_count + 1 + ctx->consts_count + 1 + 1 + 1 + ctx->entries_count + 1); + if (data.dasm_state->status != DASM_S_OK) { + IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM); + dasm_free(&data.dasm_state); + ctx->data = NULL; + ctx->status = IR_ERROR_TOO_LARGE; + return NULL; + } + data.emit_constants = ir_bitset_malloc(ctx->consts_count); if (!(ctx->flags & IR_SKIP_PROLOGUE)) { @@ -6095,6 +6688,35 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) case IR_TAILCALL: ir_emit_tailcall(ctx, i, insn); break; + case IR_IGOTO_DUP: + if (bb->flags & IR_BB_DESSA_MOVES) { + ir_emit_dessa_moves(ctx, b, bb); + } + IR_ASSERT(!igoto_dup_ref && !igoto_dup_block); + igoto_dup_ref = i; + igoto_dup_block = b; + b = ctx->cfg_edges[bb->successors]; + bb = &ctx->cfg_blocks[b]; + i = bb->start; + insn = &ctx->ir_base[i]; + rule = &ctx->rules[i]; + break; + case IR_IGOTO: + if ((ctx->ir_base[insn->op1].op == IR_MERGE || ctx->ir_base[insn->op1].op == IR_LOOP_BEGIN) + && (ctx->rules[ctx->ir_base[insn->op1].op1] & IR_RULE_MASK) == IR_IGOTO_DUP + && igoto_dup_ref) { + ir_emit_ijmp(ctx, i, insn); + b = igoto_dup_block; + bb = &ctx->cfg_blocks[b]; + i = igoto_dup_ref; + insn = &ctx->ir_base[i]; + rule = &ctx->rules[i]; + igoto_dup_block= 0; + igoto_dup_ref = 0; + break; + } + IR_ASSERT(!igoto_dup_ref && !igoto_dup_block); + IR_FALLTHROUGH; case IR_IJMP: ir_emit_ijmp(ctx, i, insn); break; @@ -6105,9 +6727,11 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) ir_emit_vaddr(ctx, i, insn); break; case IR_VLOAD: + case IR_VLOAD_v: ir_emit_vload(ctx, i, insn); break; case IR_VSTORE: + case IR_VSTORE_v: ir_emit_vstore(ctx, i, insn); break; case IR_RLOAD: @@ -6269,12 +6893,20 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) return NULL; } + if (data.dasm_state->status != DASM_S_OK) { + IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM); + dasm_free(&data.dasm_state); + ctx->data = NULL; + ctx->status = IR_ERROR_TOO_LARGE; + return NULL; + } + ret = dasm_link(&data.dasm_state, size_ptr); if (ret != DASM_S_OK) { - IR_ASSERT(0); + IR_ASSERT(ret == DASM_S_NOMEM); dasm_free(&data.dasm_state); ctx->data = NULL; - ctx->status = IR_ERROR_LINK; + ctx->status = (ret == DASM_S_NOMEM) ? IR_ERROR_TOO_LARGE : IR_ERROR_LINK; return NULL; } size = *size_ptr; @@ -6346,6 +6978,28 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) } while (i != 0); } + if ((ctx->flags2 & IR_HAS_BLOCK_ADDR) && ctx->loader && ctx->loader->add_label) { + for (b = 1, bb = &ctx->cfg_blocks[b]; b <= ctx->cfg_blocks_count; bb++, b++) { + ir_insn *insn = &ctx->ir_base[bb->start]; + + if (insn->op == IR_BEGIN && insn->op2) { + IR_ASSERT(ctx->ir_base[insn->op2].op == IR_LABEL); + ctx->ir_base[insn->op2].val.u32_hi = 0; + ctx->loader->add_label(ctx->loader, ir_get_str(ctx, ctx->ir_base[insn->op2].val.str), + (char*)entry + dasm_getpclabel(&data.dasm_state, ir_skip_empty_target_blocks(ctx, b))); + } + } + } else if (data.resolved_label_syms) { + for (b = 1, bb = &ctx->cfg_blocks[b]; b <= ctx->cfg_blocks_count; bb++, b++) { + ir_insn *insn = &ctx->ir_base[bb->start]; + + if (insn->op == IR_BEGIN && insn->op2) { + IR_ASSERT(ctx->ir_base[insn->op2].op == IR_LABEL); + ctx->ir_base[insn->op2].val.u32_hi = 0; + } + } + } + dasm_free(&data.dasm_state); if (ctx->code_buffer) { @@ -6537,7 +7191,7 @@ static int ir_add_veneer(dasm_State *Dst, void *buffer, uint32_t ins, int *b, ui return n; } -bool ir_needs_thunk(ir_code_buffer *code_buffer, void *addr) +bool ir_needs_thunk(const ir_code_buffer *code_buffer, void *addr) { return !aarch64_may_use_b(code_buffer, addr); } diff --git a/ext/opcache/jit/ir/ir_aarch64.h b/ext/opcache/jit/ir/ir_aarch64.h index 183d3ec2e1d8..e0817f9b3303 100644 --- a/ext/opcache/jit/ir/ir_aarch64.h +++ b/ext/opcache/jit/ir/ir_aarch64.h @@ -87,14 +87,15 @@ enum _ir_reg { IR_GP_REGS(IR_GP_REG_ENUM) IR_FP_REGS(IR_FP_REG_ENUM) IR_REG_NUM, + IR_REG_ALL = IR_REG_NUM, /* special name for regset */ + IR_REG_SET_1, /* special name for regset */ + IR_REG_SET_NUM, }; #define IR_REG_GP_FIRST IR_REG_X0 #define IR_REG_FP_FIRST IR_REG_V0 #define IR_REG_GP_LAST (IR_REG_FP_FIRST - 1) #define IR_REG_FP_LAST (IR_REG_NUM - 1) -#define IR_REG_SCRATCH (IR_REG_NUM) /* special name for regset */ -#define IR_REG_ALL (IR_REG_NUM + 1) /* special name for regset */ #define IR_REGSET_64BIT 1 @@ -125,65 +126,4 @@ enum _ir_reg { #define IR_REG_LR IR_REG_X30 #define IR_REG_ZR IR_REG_X31 -/* Calling Convention */ -#define IR_REG_INT_RET1 IR_REG_X0 -#define IR_REG_FP_RET1 IR_REG_V0 -#define IR_REG_INT_ARGS 8 -#define IR_REG_FP_ARGS 8 -#define IR_REG_INT_ARG1 IR_REG_X0 -#define IR_REG_INT_ARG2 IR_REG_X1 -#define IR_REG_INT_ARG3 IR_REG_X2 -#define IR_REG_INT_ARG4 IR_REG_X3 -#define IR_REG_INT_ARG5 IR_REG_X4 -#define IR_REG_INT_ARG6 IR_REG_X5 -#define IR_REG_INT_ARG7 IR_REG_X6 -#define IR_REG_INT_ARG8 IR_REG_X7 -#define IR_REG_FP_ARG1 IR_REG_V0 -#define IR_REG_FP_ARG2 IR_REG_V1 -#define IR_REG_FP_ARG3 IR_REG_V2 -#define IR_REG_FP_ARG4 IR_REG_V3 -#define IR_REG_FP_ARG5 IR_REG_V4 -#define IR_REG_FP_ARG6 IR_REG_V5 -#define IR_REG_FP_ARG7 IR_REG_V6 -#define IR_REG_FP_ARG8 IR_REG_V7 -#define IR_MAX_REG_ARGS 16 -#define IR_SHADOW_ARGS 0 - -# define IR_REGSET_SCRATCH \ - (IR_REGSET_INTERVAL(IR_REG_X0, IR_REG_X18) \ - | IR_REGSET_INTERVAL(IR_REG_V0, IR_REG_V7) \ - | IR_REGSET_INTERVAL(IR_REG_V16, IR_REG_V31)) - -# define IR_REGSET_PRESERVED \ - (IR_REGSET_INTERVAL(IR_REG_X19, IR_REG_X30) \ - | IR_REGSET_INTERVAL(IR_REG_V8, IR_REG_V15)) - -#ifndef __APPLE__ -typedef struct _ir_va_list { - void *stack; - void *gr_top; - void *vr_top; - int32_t gr_offset; - int32_t vr_offset; -} ir_va_list; -#endif - -typedef struct _ir_tmp_reg { - union { - uint8_t num; - int8_t reg; - }; - uint8_t type; - uint8_t start; - uint8_t end; -} ir_tmp_reg; - -struct _ir_target_constraints { - int8_t def_reg; - uint8_t tmps_count; - uint8_t hints_count; - ir_tmp_reg tmp_regs[3]; - int8_t hints[IR_MAX_REG_ARGS + 3]; -}; - #endif /* IR_AARCH64_H */ diff --git a/ext/opcache/jit/ir/ir_builder.h b/ext/opcache/jit/ir/ir_builder.h index 4e4ea53683af..9492945b1362 100644 --- a/ext/opcache/jit/ir/ir_builder.h +++ b/ext/opcache/jit/ir/ir_builder.h @@ -118,31 +118,31 @@ extern "C" { #define ir_MUL_D(_op1, _op2) ir_BINARY_OP_D(IR_MUL, (_op1), (_op2)) #define ir_MUL_F(_op1, _op2) ir_BINARY_OP_F(IR_MUL, (_op1), (_op2)) -#define ir_DIV(_type, _op1, _op2) ir_BINARY_OP(IR_DIV, (_type), (_op1), (_op2)) -#define ir_DIV_U8(_op1, _op2) ir_BINARY_OP_U8(IR_DIV, (_op1), (_op2)) -#define ir_DIV_U16(_op1, _op2) ir_BINARY_OP_U16(IR_DIV, (_op1), (_op2)) -#define ir_DIV_U32(_op1, _op2) ir_BINARY_OP_U32(IR_DIV, (_op1), (_op2)) -#define ir_DIV_U64(_op1, _op2) ir_BINARY_OP_U64(IR_DIV, (_op1), (_op2)) -#define ir_DIV_A(_op1, _op2) ir_BINARY_OP_A(IR_DIV, (_op1), (_op2)) -#define ir_DIV_C(_op1, _op2) ir_BINARY_OP_C(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I8(_op1, _op2) ir_BINARY_OP_I8(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I16(_op1, _op2) ir_BINARY_OP_I16(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I32(_op1, _op2) ir_BINARY_OP_I32(IR_DIV, (_op1), (_op2)) -#define ir_DIV_I64(_op1, _op2) ir_BINARY_OP_I64(IR_DIV, (_op1), (_op2)) +#define ir_DIV(_type, _op1, _op2) _ir_DIV(_ir_CTX, (_type), (_op1), (_op2)) +#define ir_DIV_U8(_op1, _op2) ir_DIV(IR_U8, (_op1), (_op2)) +#define ir_DIV_U16(_op1, _op2) ir_DIV(IR_U16, (_op1), (_op2)) +#define ir_DIV_U32(_op1, _op2) ir_DIV(IR_U32, (_op1), (_op2)) +#define ir_DIV_U64(_op1, _op2) ir_DIV(IR_U64, (_op1), (_op2)) +#define ir_DIV_A(_op1, _op2) ir_DIV(IR_ADDR, (_op1), (_op2)) +#define ir_DIV_C(_op1, _op2) ir_DIV(IR_CHAR, (_op1), (_op2)) +#define ir_DIV_I8(_op1, _op2) ir_DIV(IR_I8, (_op1), (_op2)) +#define ir_DIV_I16(_op1, _op2) ir_DIV(IR_I16, (_op1), (_op2)) +#define ir_DIV_I32(_op1, _op2) ir_DIV(IR_I32, (_op1), (_op2)) +#define ir_DIV_I64(_op1, _op2) ir_DIV(IR_I64, (_op1), (_op2)) #define ir_DIV_D(_op1, _op2) ir_BINARY_OP_D(IR_DIV, (_op1), (_op2)) #define ir_DIV_F(_op1, _op2) ir_BINARY_OP_F(IR_DIV, (_op1), (_op2)) -#define ir_MOD(_type, _op1, _op2) ir_BINARY_OP(IR_MOD, (_type), (_op1), (_op2)) -#define ir_MOD_U8(_op1, _op2) ir_BINARY_OP_U8(IR_MOD, (_op1), (_op2)) -#define ir_MOD_U16(_op1, _op2) ir_BINARY_OP_U16(IR_MOD, (_op1), (_op2)) -#define ir_MOD_U32(_op1, _op2) ir_BINARY_OP_U32(IR_MOD, (_op1), (_op2)) -#define ir_MOD_U64(_op1, _op2) ir_BINARY_OP_U64(IR_MOD, (_op1), (_op2)) -#define ir_MOD_A(_op1, _op2) ir_BINARY_OP_A(IR_MOD, (_op1), (_op2)) -#define ir_MOD_C(_op1, _op2) ir_BINARY_OP_C(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I8(_op1, _op2) ir_BINARY_OP_I8(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I16(_op1, _op2) ir_BINARY_OP_I16(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I32(_op1, _op2) ir_BINARY_OP_I32(IR_MOD, (_op1), (_op2)) -#define ir_MOD_I64(_op1, _op2) ir_BINARY_OP_I64(IR_MOD, (_op1), (_op2)) +#define ir_MOD(_type, _op1, _op2) _ir_MOD(_ir_CTX, (_type), (_op1), (_op2)) +#define ir_MOD_U8(_op1, _op2) ir_MOD(IR_U8, (_op1), (_op2)) +#define ir_MOD_U16(_op1, _op2) ir_MOD(IR_U16, (_op1), (_op2)) +#define ir_MOD_U32(_op1, _op2) ir_MOD(IR_U32, (_op1), (_op2)) +#define ir_MOD_U64(_op1, _op2) ir_MOD(IR_U64, (_op1), (_op2)) +#define ir_MOD_A(_op1, _op2) ir_MOD(IR_ADDR, (_op1), (_op2)) +#define ir_MOD_C(_op1, _op2) ir_MOD(IR_CHAR, (_op1), (_op2)) +#define ir_MOD_I8(_op1, _op2) ir_MOD(IR_I8, (_op1), (_op2)) +#define ir_MOD_I16(_op1, _op2) ir_MOD(IR_I16, (_op1), (_op2)) +#define ir_MOD_I32(_op1, _op2) ir_MOD(IR_I32, (_op1), (_op2)) +#define ir_MOD_I64(_op1, _op2) ir_MOD(IR_I64, (_op1), (_op2)) #define ir_NEG(_type, _op1) ir_UNARY_OP(IR_NEG, (_type), (_op1)) #define ir_NEG_C(_op1) ir_UNARY_OP_C(IR_NEG, (_op1)) @@ -490,20 +490,20 @@ extern "C" { #define ir_ADD_OFFSET(_addr, _offset) _ir_ADD_OFFSET(_ir_CTX, (_addr), (_offset)) /* Unfoldable variant of COPY */ -#define ir_HARD_COPY(_type, _op1) ir_BINARY_OP(IR_COPY, (_type), (_op1), 1) -#define ir_HARD_COPY_B(_op1) ir_BINARY_OP_B(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_U8(_op1) ir_BINARY_OP_U8(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_U16(_op1) ir_BINARY_OP_U16(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_U32(_op1) ir_BINARY_OP_U32(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_U64(_op1) ir_BINARY_OP_U64(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_A(_op1) ir_BINARY_OP_A(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_C(_op1) ir_BINARY_OP_C(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_I8(_op1) ir_BINARY_OP_I8(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_I16(_op1) ir_BINARY_OP_I16(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_I32(_op1) ir_BINARY_OP_I32(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_I64(_op1) ir_BINARY_OP_I64(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_D(_op1) ir_BINARY_OP_D(IR_COPY, (_op1), 1) -#define ir_HARD_COPY_F(_op1) ir_BINARY_OP_F(IR_COPY, (_op1), 1) +#define ir_HARD_COPY(_type, _op1) ir_emit2(_ir_CTX, IR_OPT(IR_COPY, (_type)), (_op1), IR_COPY_HARD) +#define ir_HARD_COPY_B(_op1) ir_HARD_COPY(IR_BOOL, _op1) +#define ir_HARD_COPY_U8(_op1) ir_HARD_COPY(IR_U8, _op1) +#define ir_HARD_COPY_U16(_op1) ir_HARD_COPY(IR_U16, _op1) +#define ir_HARD_COPY_U32(_op1) ir_HARD_COPY(IR_U32, _op1) +#define ir_HARD_COPY_U64(_op1) ir_HARD_COPY(IR_U64, _op1) +#define ir_HARD_COPY_A(_op1) ir_HARD_COPY(IR_ADDR, _op1) +#define ir_HARD_COPY_C(_op1) ir_HARD_COPY(IR_CHAR, _op1) +#define ir_HARD_COPY_I8(_op1) ir_HARD_COPY(IR_I8, _op1) +#define ir_HARD_COPY_I16(_op1) ir_HARD_COPY(IR_I16, _op1) +#define ir_HARD_COPY_I32(_op1) ir_HARD_COPY(IR_I32, _op1) +#define ir_HARD_COPY_I64(_op1) ir_HARD_COPY(IR_I64, _op1) +#define ir_HARD_COPY_D(_op1) ir_HARD_COPY(IR_DOUBLE, _op1) +#define ir_HARD_COPY_F(_op1) ir_HARD_COPY(IR_FLOAT, _op1) #define ir_PARAM(_type, _name, _num) _ir_PARAM(_ir_CTX, (_type), (_name), (_num)) #define ir_VAR(_type, _name) _ir_VAR(_ir_CTX, (_type), (_name)) @@ -544,6 +544,8 @@ extern "C" { #define ir_VLOAD_D(_var) _ir_VLOAD(_ir_CTX, IR_DOUBLE, (_var)) #define ir_VLOAD_F(_var) _ir_VLOAD(_ir_CTX, IR_FLOAT, (_var)) #define ir_VSTORE(_var, _val) _ir_VSTORE(_ir_CTX, (_var), (_val)) +#define ir_VLOAD_v(_type, _var) _ir_VLOAD_v(_ir_CTX, (_type), (_var)) +#define ir_VSTORE_v(_var, _val) _ir_VSTORE_v(_ir_CTX, (_var), (_val)) #define ir_RLOAD(_type, _reg) _ir_RLOAD(_ir_CTX, (_type), (_reg)) #define ir_RLOAD_B(_reg) _ir_RLOAD(_ir_CTX, IR_BOOL, (_reg)) #define ir_RLOAD_U8(_reg) _ir_RLOAD(_ir_CTX, IR_U8, (_reg)) @@ -574,6 +576,8 @@ extern "C" { #define ir_LOAD_D(_addr) _ir_LOAD(_ir_CTX, IR_DOUBLE, (_addr)) #define ir_LOAD_F(_addr) _ir_LOAD(_ir_CTX, IR_FLOAT, (_addr)) #define ir_STORE(_addr, _val) _ir_STORE(_ir_CTX, (_addr), (_val)) +#define ir_LOAD_v(_type, _addr) _ir_LOAD_v(_ir_CTX, (_type), (_addr)) +#define ir_STORE_v(_addr, _val) _ir_STORE_v(_ir_CTX, (_addr), (_val)) #define ir_TLS(_index, _offset) _ir_TLS(_ir_CTX, (_index), (_offset)) #define ir_TRAP() do {_ir_CTX->control = ir_emit1(_ir_CTX, IR_TRAP, _ir_CTX->control);} while (0) @@ -586,6 +590,7 @@ extern "C" { #define ir_VA_END(_list) _ir_VA_END(_ir_CTX, _list) #define ir_VA_COPY(_dst, _src) _ir_VA_COPY(_ir_CTX, _dst, _src) #define ir_VA_ARG(_list, _type) _ir_VA_ARG(_ir_CTX, _type, _list) +#define ir_VA_ARG_EX(_list, _type, s, a) _ir_VA_ARG_EX(_ir_CTX, _type, _list, s, a) #define ir_START() _ir_START(_ir_CTX) #define ir_ENTRY(_src, _num) _ir_ENTRY(_ir_CTX, (_src), (_num)) @@ -603,8 +608,10 @@ extern "C" { #define ir_LOOP_END() _ir_LOOP_END(_ir_CTX) #define ir_SWITCH(_val) _ir_SWITCH(_ir_CTX, (_val)) #define ir_CASE_VAL(_switch, _val) _ir_CASE_VAL(_ir_CTX, (_switch), (_val)) +#define ir_CASE_RANGE(_switch, _v1, _v2) _ir_CASE_RANGE(_ir_CTX, (_switch), (_v1), (_v2)) #define ir_CASE_DEFAULT(_switch) _ir_CASE_DEFAULT(_ir_CTX, (_switch)) #define ir_RETURN(_val) _ir_RETURN(_ir_CTX, (_val)) +#define ir_IGOTO(_addr) _ir_IGOTO(_ir_CTX, (_addr)) #define ir_IJMP(_addr) _ir_IJMP(_ir_CTX, (_addr)) #define ir_UNREACHABLE() _ir_UNREACHABLE(_ir_CTX) @@ -626,6 +633,8 @@ extern "C" { #define ir_MERGE_WITH_EMPTY_TRUE(_if) do {ir_ref end = ir_END(); ir_IF_TRUE(_if); ir_MERGE_2(end, ir_END());} while (0) #define ir_MERGE_WITH_EMPTY_FALSE(_if) do {ir_ref end = ir_END(); ir_IF_FALSE(_if); ir_MERGE_2(end, ir_END());} while (0) +ir_ref _ir_DIV(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2); +ir_ref _ir_MOD(ir_ctx *ctx, ir_type type, ir_ref op1, ir_ref op2); ir_ref _ir_ADD_OFFSET(ir_ctx *ctx, ir_ref addr, uintptr_t offset); ir_ref _ir_PHI_2(ir_ctx *ctx, ir_type type, ir_ref src1, ir_ref src2); ir_ref _ir_PHI_N(ir_ctx *ctx, ir_type type, ir_ref n, ir_ref *inputs); @@ -647,19 +656,24 @@ void _ir_TAILCALL_3(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_re void _ir_TAILCALL_4(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4); void _ir_TAILCALL_5(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4, ir_ref arg5); void _ir_TAILCALL_6(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4, ir_ref arg5, ir_ref arg6); -ir_ref _ir_TAILCALL_N(ir_ctx *ctx, ir_type type, ir_ref func, uint32_t count, ir_ref *args); +void _ir_TAILCALL_N(ir_ctx *ctx, ir_type type, ir_ref func, uint32_t count, ir_ref *args); ir_ref _ir_ALLOCA(ir_ctx *ctx, ir_ref size); void _ir_AFREE(ir_ctx *ctx, ir_ref size); ir_ref _ir_VLOAD(ir_ctx *ctx, ir_type type, ir_ref var); void _ir_VSTORE(ir_ctx *ctx, ir_ref var, ir_ref val); +ir_ref _ir_VLOAD_v(ir_ctx *ctx, ir_type type, ir_ref var); +void _ir_VSTORE_v(ir_ctx *ctx, ir_ref var, ir_ref val); ir_ref _ir_RLOAD(ir_ctx *ctx, ir_type type, ir_ref reg); void _ir_RSTORE(ir_ctx *ctx, ir_ref reg, ir_ref val); ir_ref _ir_LOAD(ir_ctx *ctx, ir_type type, ir_ref addr); void _ir_STORE(ir_ctx *ctx, ir_ref addr, ir_ref val); +ir_ref _ir_LOAD_v(ir_ctx *ctx, ir_type type, ir_ref addr); +void _ir_STORE_v(ir_ctx *ctx, ir_ref addr, ir_ref val); void _ir_VA_START(ir_ctx *ctx, ir_ref list); void _ir_VA_END(ir_ctx *ctx, ir_ref list); void _ir_VA_COPY(ir_ctx *ctx, ir_ref dst, ir_ref src); ir_ref _ir_VA_ARG(ir_ctx *ctx, ir_type type, ir_ref list); +ir_ref _ir_VA_ARG_EX(ir_ctx *ctx, ir_type type, ir_ref list, size_t size, size_t align); void _ir_START(ir_ctx *ctx); void _ir_ENTRY(ir_ctx *ctx, ir_ref src, ir_ref num); void _ir_BEGIN(ir_ctx *ctx, ir_ref src); @@ -682,8 +696,10 @@ ir_ref _ir_TLS(ir_ctx *ctx, ir_ref index, ir_ref offset); void _ir_UNREACHABLE(ir_ctx *ctx); ir_ref _ir_SWITCH(ir_ctx *ctx, ir_ref val); void _ir_CASE_VAL(ir_ctx *ctx, ir_ref switch_ref, ir_ref val); +void _ir_CASE_RANGE(ir_ctx *ctx, ir_ref switch_ref, ir_ref v1, ir_ref v2); void _ir_CASE_DEFAULT(ir_ctx *ctx, ir_ref switch_ref); void _ir_RETURN(ir_ctx *ctx, ir_ref val); +ir_ref _ir_IGOTO(ir_ctx *ctx, ir_ref addr); void _ir_IJMP(ir_ctx *ctx, ir_ref addr); void _ir_GUARD(ir_ctx *ctx, ir_ref condition, ir_ref addr); void _ir_GUARD_NOT(ir_ctx *ctx, ir_ref condition, ir_ref addr); diff --git a/ext/opcache/jit/ir/ir_cfg.c b/ext/opcache/jit/ir/ir_cfg.c index 01532c8ea3e3..92042ea8cbb5 100644 --- a/ext/opcache/jit/ir/ir_cfg.c +++ b/ext/opcache/jit/ir/ir_cfg.c @@ -5,6 +5,10 @@ * Authors: Dmitry Stogov */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include "ir.h" #include "ir_private.h" @@ -77,12 +81,86 @@ void ir_reset_cfg(ir_ctx *ctx) } } +static void ir_remove_phis_inputs(ir_ctx *ctx, ir_use_list *use_list, int new_inputs_count, ir_bitset life_inputs) +{ + ir_ref i, j, n, k, *p, *q, use; + ir_insn *use_insn; + + if (new_inputs_count == 1) { + for (k = use_list->count, p = q = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { + use = *p; + use_insn = &ctx->ir_base[use]; + if (use_insn->op == IR_PHI) { + /* Convert PHI to COPY */ + n = use_insn->inputs_count; + i = 2; + for (j = 2; j <= n; j++) { + ir_ref input = ir_insn_op(use_insn, j); + + if (ir_bitset_in(life_inputs, j - 1)) { + use_insn->op1 = ir_insn_op(use_insn, j); + } else if (input > 0) { + ir_use_list_remove_one(ctx, input, use); + } + } + use_insn->op = IR_COPY; + use_insn->inputs_count = 1; + for (j = 2; j <= n; j++) { + ir_insn_set_op(use_insn, j, IR_UNUSED); + } + continue; + } + + /*compact use list */ + if (p != q){ + *q = use; + } + q++; + } + + if (p != q) { + use_list->count -= (p - q); + do { + *q = IR_UNUSED; /* clenu-op the removed tail */ + q++; + } while (p != q); + } + } else { + for (k = use_list->count, p = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { + use = *p; + use_insn = &ctx->ir_base[use]; + if (use_insn->op == IR_PHI) { + n = use_insn->inputs_count; + i = 2; + for (j = 2; j <= n; j++) { + ir_ref input = ir_insn_op(use_insn, j); + + if (ir_bitset_in(life_inputs, j - 1)) { + IR_ASSERT(input); + if (i != j) { + ir_insn_set_op(use_insn, i, input); + } + i++; + } else if (input > 0) { + ir_use_list_remove_one(ctx, input, use); + } + } + use_insn->inputs_count = i - 1; + for (j = i; j <= n; j++) { + ir_insn_set_op(use_insn, j, IR_UNUSED); + } + } + } + } +} + static uint32_t IR_NEVER_INLINE ir_cfg_remove_dead_inputs(ir_ctx *ctx, uint32_t *_blocks, ir_block *blocks, uint32_t bb_count) { uint32_t b, count = 0; ir_block *bb = blocks + 1; ir_insn *insn; ir_ref i, j, n, *ops, input; + ir_bitset life_inputs = NULL; for (b = 1; b <= bb_count; b++, bb++) { bb->successors = count; @@ -96,12 +174,27 @@ static uint32_t IR_NEVER_INLINE ir_cfg_remove_dead_inputs(ir_ctx *ctx, uint32_t for (i = 1, j = 1; i <= n; i++) { input = ops[i]; if (_blocks[input]) { + if (life_inputs) { + ir_bitset_incl(life_inputs, i); + } if (i != j) { ops[j] = ops[i]; } j++; - } else if (input > 0) { - ir_use_list_remove_one(ctx, input, bb->start); + } else { + if (ctx->use_lists[bb->start].count > 1) { + /* Some inputs of this MERGE are deleted and we have to update the depended PHIs */ + if (!life_inputs) { + int k; + life_inputs = ir_bitset_malloc(n + 1); + for (k = 1; k < i; k++) { + ir_bitset_incl(life_inputs, k); + } + } + } + IR_ASSERT(input > 0); + IR_ASSERT(ctx->use_lists[input].count == 1 && ctx->use_edges[ctx->use_lists[input].refs] == bb->start); + CLEAR_USES(input); } } j--; @@ -115,6 +208,11 @@ static uint32_t IR_NEVER_INLINE ir_cfg_remove_dead_inputs(ir_ctx *ctx, uint32_t for (;j <= n; j++) { ops[j] = IR_UNUSED; } + if (life_inputs) { + ir_remove_phis_inputs(ctx, &ctx->use_lists[bb->start], insn->inputs_count, life_inputs); + ir_mem_free(life_inputs); + life_inputs = NULL; + } } } count += bb->predecessors_count; @@ -244,7 +342,6 @@ int ir_build_cfg(ir_ctx *ctx) _blocks[start] = b; _blocks[end] = b; IR_ASSERT(IR_IS_BB_START(insn->op)); - IR_ASSERT(end > start); bb->start = start; bb->end = end; bb->successors = count; @@ -376,8 +473,7 @@ static void ir_remove_predecessor(ir_ctx *ctx, ir_block *bb, uint32_t from) static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) { - ir_ref i, j, n, k, *p, *q, use; - ir_insn *use_insn; + ir_ref i, j, n; ir_use_list *use_list; ir_bitset life_inputs; ir_insn *insn = &ctx->ir_base[merge]; @@ -403,82 +499,17 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) } if (i == 1) { insn->op = IR_BEGIN; - insn->inputs_count = 1; - use_list = &ctx->use_lists[merge]; - if (use_list->count > 1) { - n++; - for (k = use_list->count, p = q = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { - use = *p; - use_insn = &ctx->ir_base[use]; - if (use_insn->op == IR_PHI) { - /* Convert PHI to COPY */ - i = 2; - for (j = 2; j <= n; j++) { - ir_ref input = ir_insn_op(use_insn, j); - - if (ir_bitset_in(life_inputs, j - 1)) { - use_insn->op1 = ir_insn_op(use_insn, j); - } else if (input > 0) { - ir_use_list_remove_one(ctx, input, use); - } - } - use_insn->op = IR_COPY; - use_insn->inputs_count = 1; - for (j = 2; j <= n; j++) { - ir_insn_set_op(use_insn, j, IR_UNUSED); - } - continue; - } - - /*compact use list */ - if (p != q){ - *q = use; - } - q++; - } - - if (p != q) { - use_list->count -= (p - q); - do { - *q = IR_UNUSED; /* clenu-op the removed tail */ - q++; - } while (p != q); - } - } - } else { - insn->inputs_count = i; + } + insn->inputs_count = i; - use_list = &ctx->use_lists[merge]; - if (use_list->count > 1) { - n++; - for (k = use_list->count, p = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { - use = *p; - use_insn = &ctx->ir_base[use]; - if (use_insn->op == IR_PHI) { - i = 2; - for (j = 2; j <= n; j++) { - ir_ref input = ir_insn_op(use_insn, j); - - if (ir_bitset_in(life_inputs, j - 1)) { - IR_ASSERT(input); - if (i != j) { - ir_insn_set_op(use_insn, i, input); - } - i++; - } else if (input > 0) { - ir_use_list_remove_one(ctx, input, use); - } - } - use_insn->inputs_count = i - 1; - for (j = i; j <= n; j++) { - ir_insn_set_op(use_insn, j, IR_UNUSED); - } - } - } - } + use_list = &ctx->use_lists[merge]; + if (use_list->count > 1) { + ir_remove_phis_inputs(ctx, use_list, i, life_inputs); } + ir_mem_free(life_inputs); - ir_use_list_remove_all(ctx, from, merge); + IR_ASSERT(ctx->use_lists[from].count == 1 && ctx->use_edges[ctx->use_lists[from].refs] == merge); + CLEAR_USES(from); } /* CFG constructed after SCCP pass doesn't have unreachable BBs, otherwise they should be removed */ @@ -583,58 +614,70 @@ static int ir_remove_unreachable_blocks(ir_ctx *ctx) return 1; } -#if 0 -static void compute_postnum(const ir_ctx *ctx, uint32_t *cur, uint32_t b) -{ - uint32_t i, *p; - ir_block *bb = &ctx->cfg_blocks[b]; - - if (bb->postnum != 0) { - return; - } - - if (bb->successors_count) { - bb->postnum = -1; /* Marker for "currently visiting" */ - p = ctx->cfg_edges + bb->successors; - i = bb->successors_count; - do { - compute_postnum(ctx, cur, *p); - p++; - } while (--i); - } - bb->postnum = (*cur)++; -} - /* Computes dominator tree using algorithm from "A Simple, Fast Dominance Algorithm" by * Cooper, Harvey and Kennedy. */ -int ir_build_dominators_tree(ir_ctx *ctx) +static IR_NEVER_INLINE int ir_build_dominators_tree_slow(ir_ctx *ctx) { - uint32_t blocks_count, b, postnum; + uint32_t blocks_count, b, postnum, i; ir_block *blocks, *bb; uint32_t *edges; + uint32_t *rpo = ir_mem_malloc((ctx->cfg_blocks_count + 1) * sizeof(uint32_t)); bool changed; + blocks = ctx->cfg_blocks; + edges = ctx->cfg_edges; + blocks_count = ctx->cfg_blocks_count; + ctx->flags2 &= ~IR_NO_LOOPS; postnum = 1; - compute_postnum(ctx, &postnum, 1); + ir_worklist work; + ir_worklist_init(&work, ctx->cfg_blocks_count + 1); + ir_worklist_push(&work, 1); + IR_ASSERT(blocks[1].next_succ == 0); + while (ir_worklist_len(&work)) { +next: + b = ir_worklist_peek(&work); + bb = &blocks[b]; + uint32_t n = bb->successors_count - bb->next_succ; + if (n) { + uint32_t *p = edges + bb->successors + bb->next_succ; + for (; n > 0; p++, n--) { + uint32_t succ = *p; + if (ir_worklist_push(&work, succ)) { + bb->next_succ = bb->successors_count - n + 1; + IR_ASSERT(blocks[succ].next_succ == 0); + goto next; + } + } + } - /* Find immediate dominators */ - blocks = ctx->cfg_blocks; - edges = ctx->cfg_edges; - blocks_count = ctx->cfg_blocks_count; + /* Start from bb->idom calculated by the fast dominators algorithm */ + // bb->idom = 0; + bb->next_succ = 0; + rpo[postnum] = b; + bb->postnum = postnum++; + ir_worklist_pop(&work); + } + ir_worklist_free(&work); + + IR_ASSERT(rpo[blocks_count] == 1); + + /* Find immediate dominators by iterative fixed-point algorithm */ blocks[1].idom = 1; do { changed = 0; + /* Iterating in Reverse Post Order */ - for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { + for (i = blocks_count - 1; i > 0; i--) { + b = rpo[i]; + bb = &blocks[b]; IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); + IR_ASSERT(bb->predecessors_count > 0); if (bb->predecessors_count == 1) { uint32_t pred_b = edges[bb->predecessors]; - if (blocks[pred_b].idom <= 0) { - //IR_ASSERT("Wrong blocks order: BB is before its single predecessor"); - } else if (bb->idom != pred_b) { + if (blocks[pred_b].idom > 0 && bb->idom != pred_b) { bb->idom = pred_b; changed = 1; } @@ -680,39 +723,40 @@ int ir_build_dominators_tree(ir_ctx *ctx) } } } while (changed); + + ir_mem_free(rpo); + + /* Build dominators tree */ blocks[1].idom = 0; blocks[1].dom_depth = 0; - /* Construct dominators tree */ + /* Construct children lists sorted by block number */ + for (b = blocks_count, bb = &blocks[b]; b >= 2; b--, bb--) { + ir_block *idom_bb = &blocks[bb->idom]; + bb->dom_depth = 0; + bb->dom_next_child = idom_bb->dom_child; + idom_bb->dom_child = b; + } + + /* Recalculate dom_depth for all blocks */ for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { - IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); - if (bb->idom > 0) { - ir_block *idom_bb = &blocks[bb->idom]; - - bb->dom_depth = idom_bb->dom_depth + 1; - /* Sort by block number to traverse children in pre-order */ - if (idom_bb->dom_child == 0) { - idom_bb->dom_child = b; - } else if (b < idom_bb->dom_child) { - bb->dom_next_child = idom_bb->dom_child; - idom_bb->dom_child = b; + uint32_t idom = bb->idom; + uint32_t dom_depth = 0; + while (idom) { + dom_depth++; + if (blocks[idom].dom_depth > 0) { + dom_depth += blocks[idom].dom_depth; + break; } else { - int child = idom_bb->dom_child; - ir_block *child_bb = &blocks[child]; - - while (child_bb->dom_next_child > 0 && b > child_bb->dom_next_child) { - child = child_bb->dom_next_child; - child_bb = &blocks[child]; - } - bb->dom_next_child = child_bb->dom_next_child; - child_bb->dom_next_child = b; + idom = blocks[idom].idom; } } + bb->dom_depth = dom_depth; } return 1; } -#else + /* A single pass modification of "A Simple, Fast Dominance Algorithm" by * Cooper, Harvey and Kennedy, that relays on IR block ordering. * It may fallback to the general slow fixed-point algorithm. */ @@ -735,7 +779,7 @@ int ir_build_dominators_tree(ir_ctx *ctx) blocks[1].idom = 1; blocks[1].dom_depth = 0; - /* Iterating in Reverse Post Order */ + /* Iterating in Reverse Post Order (relay on existing BB order and fall-back to slow algorithm) */ for (b = 2, bb = &blocks[2]; b <= blocks_count; b++, bb++) { IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); IR_ASSERT(bb->predecessors_count > 0); @@ -747,7 +791,12 @@ int ir_build_dominators_tree(ir_ctx *ctx) if (UNEXPECTED(idom >= b)) { /* In rare cases, LOOP_BEGIN.op1 may be a back-edge. Skip back-edges. */ ctx->flags2 &= ~IR_NO_LOOPS; - IR_ASSERT(k > 1 && "Wrong blocks order: BB is before its single predecessor"); + if (UNEXPECTED(k <= 1)) { + // IR_ASSERT(k > 1 && "Wrong blocks order: BB is before its single predecessor"); +slow_case: + ir_list_free(&worklist); + return ir_build_dominators_tree_slow(ctx); + } ir_list_push(&worklist, idom); while (1) { k--; @@ -756,7 +805,10 @@ int ir_build_dominators_tree(ir_ctx *ctx) if (idom < b) { break; } - IR_ASSERT(k > 0); + if (UNEXPECTED(k == 0)) { + // IR_ASSERT(0 && "Wrong blocks order: BB is before all its predecessors"); + goto slow_case; + } ir_list_push(&worklist, idom); } } @@ -784,25 +836,7 @@ int ir_build_dominators_tree(ir_ctx *ctx) } bb->idom = idom; idom_bb = &blocks[idom]; - bb->dom_depth = idom_bb->dom_depth + 1; - /* Sort by block number to traverse children in pre-order */ - if (idom_bb->dom_child == 0) { - idom_bb->dom_child = b; - } else if (b < idom_bb->dom_child) { - bb->dom_next_child = idom_bb->dom_child; - idom_bb->dom_child = b; - } else { - int child = idom_bb->dom_child; - ir_block *child_bb = &blocks[child]; - - while (child_bb->dom_next_child > 0 && b > child_bb->dom_next_child) { - child = child_bb->dom_next_child; - child_bb = &blocks[child]; - } - bb->dom_next_child = child_bb->dom_next_child; - child_bb->dom_next_child = b; - } } blocks[1].idom = 0; @@ -819,11 +853,14 @@ int ir_build_dominators_tree(ir_ctx *ctx) succ_b = ctx->cfg_edges[bb->successors]; if (bb->successors_count != 1) { /* LOOP_END/END may be linked with the following ENTRY by a fake edge */ - IR_ASSERT(bb->successors_count == 2); - if (blocks[succ_b].flags & IR_BB_ENTRY) { + if (bb->successors_count != 2) { + complete = 0; + break; + } else if (blocks[succ_b].flags & IR_BB_ENTRY) { succ_b = ctx->cfg_edges[bb->successors + 1]; - } else { - IR_ASSERT(blocks[ctx->cfg_edges[bb->successors + 1]].flags & IR_BB_ENTRY); + } else if (!(blocks[ctx->cfg_edges[bb->successors + 1]].flags & IR_BB_ENTRY)) { + complete = 0; + break; } } dom_depth = blocks[succ_b].dom_depth;; @@ -839,10 +876,18 @@ int ir_build_dominators_tree(ir_ctx *ctx) if (UNEXPECTED(!complete)) { ir_list_free(&worklist); + // TODO: this algorithm may be incorrect. Prove and/or switch to ir_build_dominators_tree_slow() ??? return ir_build_dominators_tree_iterative(ctx); } } + /* Construct children lists sorted by block number */ + for (b = blocks_count, bb = &blocks[b]; b >= 2; b--, bb--) { + ir_block *idom_bb = &blocks[bb->idom]; + bb->dom_next_child = idom_bb->dom_child; + idom_bb->dom_child = b; + } + ir_list_free(&worklist); return 1; @@ -863,8 +908,6 @@ static int ir_build_dominators_tree_iterative(ir_ctx *ctx) /* Clear the dominators tree, but keep already found dominators */ for (b = 0, bb = &blocks[0]; b <= blocks_count; b++, bb++) { bb->dom_depth = 0; - bb->dom_child = 0; - bb->dom_next_child = 0; } /* Find immediate dominators by iterative fixed-point algorithm */ @@ -882,20 +925,20 @@ static int ir_build_dominators_tree_iterative(ir_ctx *ctx) if (blocks[idom].idom == 0) { while (1) { k--; + if (UNEXPECTED(k == 0)) break; p++; idom = *p; if (blocks[idom].idom > 0) { break; } - IR_ASSERT(k > 0); } + if (UNEXPECTED(k == 0)) continue; } IR_ASSERT(k != 0); while (--k > 0) { uint32_t pred_b = *(++p); if (blocks[pred_b].idom > 0) { - IR_ASSERT(blocks[pred_b].idom > 0); while (idom != pred_b) { while (pred_b > idom) { pred_b = blocks[pred_b].idom; @@ -921,28 +964,17 @@ static int ir_build_dominators_tree_iterative(ir_ctx *ctx) ir_block *idom_bb = &blocks[idom]; bb->dom_depth = idom_bb->dom_depth + 1; - /* Sort by block number to traverse children in pre-order */ - if (idom_bb->dom_child == 0) { - idom_bb->dom_child = b; - } else if (b < idom_bb->dom_child) { - bb->dom_next_child = idom_bb->dom_child; - idom_bb->dom_child = b; - } else { - int child = idom_bb->dom_child; - ir_block *child_bb = &blocks[child]; + } - while (child_bb->dom_next_child > 0 && b > child_bb->dom_next_child) { - child = child_bb->dom_next_child; - child_bb = &blocks[child]; - } - bb->dom_next_child = child_bb->dom_next_child; - child_bb->dom_next_child = b; - } + /* Construct children lists sorted by block number */ + for (b = blocks_count, bb = &blocks[b]; b >= 2; b--, bb--) { + ir_block *idom_bb = &blocks[bb->idom]; + bb->dom_next_child = idom_bb->dom_child; + idom_bb->dom_child = b; } return 1; } -#endif static bool ir_dominates(const ir_block *blocks, uint32_t b1, uint32_t b2) { @@ -956,10 +988,107 @@ static bool ir_dominates(const ir_block *blocks, uint32_t b1, uint32_t b2) return b1 == b2; } +/* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ Graphs" and + * G. Ramalingam "Identifying Loops In Almost Linear Time". */ + +#define ENTRY_TIME(b) times[(b) * 2] +#define EXIT_TIME(b) times[(b) * 2 + 1] + +static IR_NEVER_INLINE void ir_collect_irreducible_loops(ir_ctx *ctx, uint32_t *times, ir_worklist *work, ir_list *list) +{ + ir_block *blocks = ctx->cfg_blocks; + uint32_t *edges = ctx->cfg_edges; + + IR_ASSERT(ir_list_len(list) != 0); + if (ir_list_len(list) > 1) { + /* Sort list to process irreducible loops in DFS order (insertion sort) */ + ir_ref *a = list->a.refs; + uint32_t n = ir_list_len(list); + uint32_t i = 1; + while (i < n) { + uint32_t j = i; + while (j > 0 && ENTRY_TIME(a[j-1]) > ENTRY_TIME(a[j])) { + ir_ref tmp = a[j]; + a[j] = a[j-1]; + a[j-1] = tmp; + j--; + } + i++; + } + } + while (ir_list_len(list)) { + uint32_t hdr = ir_list_pop(list); + ir_block *bb = &blocks[hdr]; + + IR_ASSERT(bb->flags & IR_BB_IRREDUCIBLE_LOOP); + IR_ASSERT(!bb->loop_depth); + if (!bb->loop_depth) { + /* process irreducible loop */ + + bb->flags |= IR_BB_LOOP_HEADER; + bb->loop_depth = 1; + if (ctx->ir_base[bb->start].op == IR_MERGE) { + ctx->ir_base[bb->start].op = IR_LOOP_BEGIN; + } + + /* find the closing edge(s) of the irreucible loop */ + IR_ASSERT(bb->predecessors_count > 1); + IR_ASSERT(ir_worklist_len(work) == 0); + ir_bitset_clear(work->visited, ir_bitset_len(ir_worklist_capasity(work))); + ir_bitset_incl(work->visited, hdr); + + uint32_t *p = &edges[bb->predecessors]; + uint32_t n = bb->predecessors_count; + do { + uint32_t pred = *p; + if (ENTRY_TIME(pred) > ENTRY_TIME(hdr) && EXIT_TIME(pred) < EXIT_TIME(hdr)) { + ir_worklist_push(work, pred); + } + p++; + } while (--n); + + /* collect members of the irreducible loop */ + while (ir_worklist_len(work)) { + uint32_t b = ir_worklist_pop(work); + + bb = &blocks[b]; + if (!bb->loop_header) { + bb->loop_header = hdr; + } + + uint32_t *p = &edges[bb->predecessors]; + uint32_t n = bb->predecessors_count; + + for (; n > 0; p++, n--) { + uint32_t pred = *p; + if (!ir_bitset_in(work->visited, pred)) { + if (blocks[pred].loop_header) { + if (blocks[pred].loop_header == b) continue; + do { + pred = blocks[pred].loop_header; + } while (blocks[pred].loop_header > 0); + } + if (ENTRY_TIME(pred) > ENTRY_TIME(hdr) && EXIT_TIME(pred) < EXIT_TIME(hdr)) { + /* "pred" is a descendant of "hdr" */ + ir_worklist_push(work, pred); + } else if (bb->predecessors_count > 1) { + /* another entry to the irreducible loop */ + bb->flags |= IR_BB_IRREDUCIBLE_LOOP; + if (ctx->ir_base[bb->start].op == IR_MERGE) { + ctx->ir_base[bb->start].op = IR_LOOP_BEGIN; + } + } + } + } + } + } + } +} + int ir_find_loops(ir_ctx *ctx) { - uint32_t i, j, n, count; - uint32_t *entry_times, *exit_times, *sorted_blocks, time = 1; + uint32_t b, j, n; + uint32_t *times, *sorted_blocks, time = 1; ir_block *blocks = ctx->cfg_blocks; uint32_t *edges = ctx->cfg_edges; ir_worklist work; @@ -968,57 +1097,49 @@ int ir_find_loops(ir_ctx *ctx) return 1; } - /* We don't materialize the DJ spanning tree explicitly, as we are only interested in ancestor - * queries. These are implemented by checking entry/exit times of the DFS search. */ + /* Compute entry/exit times for the CFG DFS spanning tree to perform ancestor and back-edge queries. */ ir_worklist_init(&work, ctx->cfg_blocks_count + 1); - entry_times = ir_mem_malloc((ctx->cfg_blocks_count + 1) * 3 * sizeof(uint32_t)); - exit_times = entry_times + ctx->cfg_blocks_count + 1; - sorted_blocks = exit_times + ctx->cfg_blocks_count + 1; - - memset(entry_times, 0, (ctx->cfg_blocks_count + 1) * sizeof(uint32_t)); + times = ir_mem_malloc((ctx->cfg_blocks_count + 1) * 3 * sizeof(uint32_t)); + sorted_blocks = times + (ctx->cfg_blocks_count + 1) * 2; + ir_bitset visited = ir_bitset_malloc(ctx->cfg_blocks_count + 1); ir_worklist_push(&work, 1); while (ir_worklist_len(&work)) { - ir_block *bb; - int child; - next: - i = ir_worklist_peek(&work); - if (!entry_times[i]) { - entry_times[i] = time++; - } + b = ir_worklist_peek(&work); + ir_block *bb = &blocks[b]; - /* Visit blocks immediately dominated by i. */ - bb = &blocks[i]; - for (child = bb->dom_child; child > 0; child = blocks[child].dom_next_child) { - if (ir_worklist_push(&work, child)) { - goto next; - } + if (!ir_bitset_in(visited, b)) { + ir_bitset_incl(visited, b); + ENTRY_TIME(b) = time++; } - /* Visit join edges. */ - if (bb->successors_count) { - uint32_t *p = edges + bb->successors; - for (j = 0; j < bb->successors_count; j++,p++) { + uint32_t n = bb->successors_count - bb->next_succ; + if (n) { + uint32_t *p = edges + bb->successors + bb->next_succ; + for (; n > 0; p++, n--) { uint32_t succ = *p; - - if (blocks[succ].idom == i) { - continue; - } else if (ir_worklist_push(&work, succ)) { + if (ir_worklist_push(&work, succ)) { + bb->next_succ = bb->successors_count - n + 1; + IR_ASSERT(blocks[succ].next_succ == 0); goto next; } } } - exit_times[i] = time++; + + bb->next_succ = 0; + EXIT_TIME(b) = time++; ir_worklist_pop(&work); } + ir_mem_free(visited); /* Sort blocks by level, which is the opposite order in which we want to process them */ + /* (Breadth First Search using "sorted_blocks" as a queue) */ sorted_blocks[1] = 1; j = 1; n = 2; while (j != n) { - i = j; + uint32_t i = j; j = n; for (; i < j; i++) { int child; @@ -1027,73 +1148,99 @@ int ir_find_loops(ir_ctx *ctx) } } } - count = n; + IR_ASSERT(n == ctx->cfg_blocks_count + 1); + +#if IR_DEBUG + uint32_t prev_dom_depth = blocks[sorted_blocks[n - 1]].dom_depth; +#endif + uint32_t irreducible_depth = 0; + ir_list irreducible_list = {0}; - /* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ Graphs". */ while (n > 1) { - i = sorted_blocks[--n]; - ir_block *bb = &blocks[i]; + b = sorted_blocks[--n]; + ir_block *bb = &blocks[b]; + + IR_ASSERT(bb->dom_depth <= prev_dom_depth); + + if (UNEXPECTED(bb->dom_depth < irreducible_depth)) { + ir_collect_irreducible_loops(ctx, times, &work, &irreducible_list); + irreducible_depth = 0; + } if (bb->predecessors_count > 1) { bool irreducible = 0; + uint32_t b_entry_time = ENTRY_TIME(b); + uint32_t b_exit_time = EXIT_TIME(b); uint32_t *p = &edges[bb->predecessors]; - j = bb->predecessors_count; - do { + for (j = bb->predecessors_count; j > 0; p++, j--) { uint32_t pred = *p; - /* A join edge is one for which the predecessor does not - immediately dominate the successor. */ - if (bb->idom != pred) { - /* In a loop back-edge (back-join edge), the successor dominates - the predecessor. */ - if (ir_dominates(blocks, i, pred)) { + /* Check back-edges */ + if (ENTRY_TIME(pred) >= b_entry_time && EXIT_TIME(pred) <= b_exit_time) { + if (ir_dominates(blocks, b, pred)) { + /* In a loop back-edge (back-join edge), the successor dominates + the predecessor. */ if (!ir_worklist_len(&work)) { ir_bitset_clear(work.visited, ir_bitset_len(ir_worklist_capasity(&work))); } - blocks[pred].loop_header = 0; /* support for merged loops */ ir_worklist_push(&work, pred); } else { - /* Otherwise it's a cross-join edge. See if it's a branch - to an ancestor on the DJ spanning tree. */ - if (entry_times[pred] > entry_times[i] && exit_times[pred] < exit_times[i]) { - irreducible = 1; - } + /* Otherwise it's a back-edge of irreducible loop. */ + irreducible = 1; + break; } } - p++; - } while (--j); + } if (UNEXPECTED(irreducible)) { - // TODO: Support for irreducible loops ??? bb->flags |= IR_BB_IRREDUCIBLE_LOOP; - ctx->flags2 |= IR_IRREDUCIBLE_CFG; - while (ir_worklist_len(&work)) { - ir_worklist_pop(&work); + ctx->flags2 |= IR_CFG_HAS_LOOPS | IR_IRREDUCIBLE_CFG; + /* Delay processing of all irreducible loops + * after all reducible loops with the same dominator tree depth + */ + irreducible_depth = bb->dom_depth; + if (!ir_list_capasity(&irreducible_list)) { + ir_list_init(&irreducible_list, 16); } + ir_list_push(&irreducible_list, b); + ir_list_clear(&work.l); } else if (ir_worklist_len(&work)) { + /* collect members of the reducible loop */ + uint32_t hdr = b; + bb->flags |= IR_BB_LOOP_HEADER; ctx->flags2 |= IR_CFG_HAS_LOOPS; bb->loop_depth = 1; + if (ctx->ir_base[bb->start].op == IR_MERGE) { + ctx->ir_base[bb->start].op = IR_LOOP_BEGIN; + } + ir_bitset_incl(work.visited, hdr); while (ir_worklist_len(&work)) { - j = ir_worklist_pop(&work); - while (blocks[j].loop_header > 0) { - j = blocks[j].loop_header; - } - if (j != i) { - ir_block *bb = &blocks[j]; - if (bb->idom == 0 && j != 1) { - /* Ignore blocks that are unreachable or only abnormally reachable. */ - continue; + b = ir_worklist_pop(&work); + if (b != hdr) { + ir_block *bb = &blocks[b]; + + if (!bb->loop_header) { + bb->loop_header = hdr; } - bb->loop_header = i; - if (bb->predecessors_count) { - uint32_t *p = &edges[bb->predecessors]; - j = bb->predecessors_count; - do { - ir_worklist_push(&work, *p); - p++; - } while (--j); + + uint32_t *p = &edges[bb->predecessors]; + uint32_t n = bb->predecessors_count; + for (; n > 0; p++, n--) { + uint32_t pred = *p; + if (!ir_bitset_in(work.visited, pred)) { + if (blocks[pred].loop_header) { + if (blocks[pred].loop_header == b) continue; + do { + pred = blocks[pred].loop_header; + } while (blocks[pred].loop_header > 0); + ir_worklist_push(&work, pred); + } else { + ir_bitset_incl(work.visited, pred); + ir_list_push_unchecked(&work.l, pred); + } + } } } } @@ -1101,10 +1248,16 @@ int ir_find_loops(ir_ctx *ctx) } } + IR_ASSERT(!irreducible_depth); + if (ir_list_capasity(&irreducible_list)) { + ir_list_free(&irreducible_list); + } + if (ctx->flags2 & IR_CFG_HAS_LOOPS) { - for (n = 1; n < count; n++) { - i = sorted_blocks[n]; - ir_block *bb = &blocks[i]; + n = ctx->cfg_blocks_count + 1; + for (j = 1; j < n; j++) { + b = sorted_blocks[j]; + ir_block *bb = &blocks[b]; if (bb->loop_header > 0) { ir_block *loop = &blocks[bb->loop_header]; uint32_t loop_depth = loop->loop_depth; @@ -1134,7 +1287,7 @@ int ir_find_loops(ir_ctx *ctx) } } - ir_mem_free(entry_times); + ir_mem_free(times); ir_worklist_free(&work); return 1; @@ -1334,8 +1487,38 @@ static void ir_dump_chains(ir_ctx *ctx, ir_chain *chains) } } } + +static bool ir_is_merged_loop_back_edge(ir_ctx *ctx, uint32_t hdr, uint32_t b) +{ + if (ctx->cfg_blocks[hdr].flags & IR_BB_LOOP_HEADER) { + uint32_t loop_depth = ctx->cfg_blocks[hdr].loop_depth; + + while (ctx->cfg_blocks[b].loop_depth > loop_depth) { + b = ctx->cfg_blocks[b].loop_header; + } + return b == hdr; + } + return 0; +} #endif +static bool ir_should_align_loop(ir_ctx *ctx, ir_chain *chains, uint32_t b, ir_block *bb) +{ + uint32_t n = bb->predecessors_count; + uint32_t *p = ctx->cfg_edges + bb->predecessors; + + for (; n > 0; p++, n--) { + uint32_t pred = *p; + if (chains[pred].head) { + if (ir_chain_head(chains, pred) == b) return 1; + } else { + if (ir_should_align_loop(ctx, chains, b, &ctx->cfg_blocks[pred])) return 1; + } + } + + return 0; +} + static int ir_schedule_blocks_bottom_up(ir_ctx *ctx) { uint32_t max_edges_count = ctx->cfg_edges_count / 2; @@ -1389,8 +1572,9 @@ static int ir_schedule_blocks_bottom_up(ir_ctx *ctx) goto restart; } } else if (b != predecessor && ctx->cfg_blocks[predecessor].loop_header != b) { - ir_dump_cfg(ctx, stderr); - IR_ASSERT(b == predecessor || ctx->cfg_blocks[predecessor].loop_header == b); + /* not a loop back-edge */ + IR_ASSERT(b == predecessor || ctx->cfg_blocks[predecessor].loop_header == b || + ir_is_merged_loop_back_edge(ctx, b, predecessor)); } } } @@ -1695,7 +1879,7 @@ static int ir_schedule_blocks_bottom_up(ir_ctx *ctx) if (chains[b].head == b) { bb = &ctx->cfg_blocks[b]; if (bb->loop_depth) { - if ((bb->flags & IR_BB_LOOP_HEADER) || ir_chain_head(chains, bb->loop_header) == b) { + if (ir_should_align_loop(ctx, chains, b, bb)) { bb->flags |= IR_BB_ALIGN_LOOP; } } diff --git a/ext/opcache/jit/ir/ir_check.c b/ext/opcache/jit/ir/ir_check.c index f12b4776fa1e..e1be7f6544df 100644 --- a/ext/opcache/jit/ir/ir_check.c +++ b/ext/opcache/jit/ir/ir_check.c @@ -36,16 +36,46 @@ void ir_consistency_check(void) IR_ASSERT((IR_UGT ^ 3) == IR_ULT); IR_ASSERT((IR_ULE ^ 3) == IR_UGE); IR_ASSERT((IR_UGE ^ 3) == IR_ULE); + IR_ASSERT((IR_ORDERED ^ 1) == IR_UNORDERED); IR_ASSERT(IR_ADD + 1 == IR_SUB); } -static bool ir_check_use_list(const ir_ctx *ctx, ir_ref from, ir_ref to) +typedef struct { + ir_arena *arena; + ir_bitset *use_set; + ir_bitset *input_set; +} ir_check_ctx; + +static bool ir_check_use_list(ir_check_ctx *check_ctx, const ir_ctx *ctx, ir_ref from, ir_ref to) { ir_ref n, *p; ir_use_list *use_list = &ctx->use_lists[from]; n = use_list->count; + if (n > 16) { + /* Avoid quadratic complexity by maintaining a temporary bit-set */ + ir_bitset set; + + if (!check_ctx->use_set || !(set = check_ctx->use_set[from])) { + if (!check_ctx->arena) { + check_ctx->arena = ir_arena_create(sizeof(ir_arena) + + ctx->insns_count * sizeof(ir_bitset) + + ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t)); + } + if (!check_ctx->use_set) { + check_ctx->use_set = ir_arena_alloc(&check_ctx->arena, ctx->insns_count * sizeof(ir_bitset)); + memset(check_ctx->use_set, 0, ctx->insns_count * sizeof(ir_bitset)); + } + check_ctx->use_set[from] = set = (ir_bitset)ir_arena_alloc(&check_ctx->arena, + ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t)); + memset(set, 0, ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t)); + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { + ir_bitset_incl(set, *p); + } + } + return ir_bitset_in(set, to); + } for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { if (*p == to) { return 1; @@ -54,12 +84,35 @@ static bool ir_check_use_list(const ir_ctx *ctx, ir_ref from, ir_ref to) return 0; } -static bool ir_check_input_list(const ir_ctx *ctx, ir_ref from, ir_ref to) +static bool ir_check_input_list(ir_check_ctx *check_ctx, const ir_ctx *ctx, ir_ref from, ir_ref to) { ir_insn *insn = &ctx->ir_base[to]; ir_ref n, j, *p; n = ir_input_edges_count(ctx, insn); + if (n > 16) { + /* Avoid quadratic complexity by maintaining a temporary bit-set */ + ir_bitset set; + + if (!check_ctx->input_set || !(set = check_ctx->input_set[to])) { + if (!check_ctx->arena) { + check_ctx->arena = ir_arena_create(sizeof(ir_arena) + + ctx->insns_count * sizeof(ir_bitset) + + ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t)); + } + if (!check_ctx->input_set) { + check_ctx->input_set = ir_arena_alloc(&check_ctx->arena, ctx->insns_count * sizeof(ir_bitset)); + memset(check_ctx->input_set, 0, ctx->insns_count * sizeof(ir_bitset)); + } + check_ctx->input_set[to] = set = (ir_bitset)ir_arena_alloc(&check_ctx->arena, + ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t)); + memset(set, 0, ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t)); + for (j = 1, p = insn->ops + 1; j <= n; j++, p++) { + if (*p > 0) ir_bitset_incl(set, *p); + } + } + return ir_bitset_in(set, from); + } for (j = 1, p = insn->ops + 1; j <= n; j++, p++) { if (*p == from) { return 1; @@ -93,6 +146,17 @@ bool ir_check(const ir_ctx *ctx) ir_type type; uint32_t flags; bool ok = 1; + ir_check_ctx check_ctx; + + if (ctx->insns_count < 1 || ctx->ir_base[1].op != IR_START) { + fprintf(stderr, "ir_base[1].op invalid opcode (%d)\n", + (ctx->insns_count < 1) ? IR_NOP : ctx->ir_base[0].op); + ok = 0; + } + + check_ctx.arena = NULL; + check_ctx.use_set = NULL; + check_ctx.input_set = NULL; for (i = IR_UNUSED + 1, insn = ctx->ir_base + i; i < ctx->insns_count;) { if (insn->op >= IR_LAST_OP) { @@ -213,13 +277,18 @@ bool ir_check(const ir_ctx *ctx) ok = 0; } } - break; - case IR_OPND_CONTROL_DEP: if ((ctx->flags2 & IR_LINEAR) && use >= i && !(insn->op == IR_LOOP_BEGIN)) { fprintf(stderr, "ir_base[%d].ops[%d] invalid forward reference (%d)\n", i, j, use); ok = 0; + } + break; + case IR_OPND_CONTROL_DEP: + if ((ctx->flags2 & IR_LINEAR) + && use >= i) { + fprintf(stderr, "ir_base[%d].ops[%d] invalid forward reference (%d)\n", i, j, use); + ok = 0; } else if (insn->op == IR_PHI) { ir_insn *merge_insn = &ctx->ir_base[insn->op1]; if (merge_insn->op != IR_MERGE && merge_insn->op != IR_LOOP_BEGIN) { @@ -234,6 +303,14 @@ bool ir_check(const ir_ctx *ctx) ok = 0; } break; + case IR_OPND_CONTROL_GUARD: + if (!(ir_op_flags[use_insn->op] & IR_OP_FLAG_BB_START) + && use_insn->op != IR_GUARD + && use_insn->op != IR_GUARD_NOT) { + fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) must be BB_START or GUARD\n", i, j, use); + ok = 0; + } + break; default: fprintf(stderr, "ir_base[%d].ops[%d] reference (%d) of unsupported kind\n", i, j, use); ok = 0; @@ -243,6 +320,8 @@ bool ir_check(const ir_ctx *ctx) /* pass (function returns void) */ } else if (insn->op == IR_BEGIN && j == 1) { /* pass (start of unreachable basic block) */ + } else if (IR_OPND_KIND(flags, j) == IR_OPND_CONTROL_GUARD) { + /* reference to control guard is optional */ } else if (IR_OPND_KIND(flags, j) != IR_OPND_CONTROL_REF && (insn->op != IR_SNAPSHOT || j == 1)) { fprintf(stderr, "ir_base[%d].ops[%d] missing reference (%d)\n", i, j, use); @@ -250,7 +329,7 @@ bool ir_check(const ir_ctx *ctx) } if (ctx->use_lists && use > 0 - && !ir_check_use_list(ctx, use, i)) { + && !ir_check_use_list(&check_ctx, ctx, use, i)) { fprintf(stderr, "ir_base[%d].ops[%d] is not in use list (%d)\n", i, j, use); ok = 0; } @@ -265,7 +344,9 @@ bool ir_check(const ir_ctx *ctx) } break; case IR_LOAD: + case IR_LOAD_v: case IR_STORE: + case IR_STORE_v: type = ctx->ir_base[insn->op2].type; if (type != IR_ADDR && (!IR_IS_TYPE_INT(type) || ir_type_size[type] != ir_type_size[IR_ADDR])) { @@ -275,7 +356,9 @@ bool ir_check(const ir_ctx *ctx) } break; case IR_VLOAD: + case IR_VLOAD_v: case IR_VSTORE: + case IR_VSTORE_v: if (ctx->ir_base[insn->op2].op != IR_VAR) { fprintf(stderr, "ir_base[%d].op2 must be 'VAR' (%s)\n", i, ir_op_name[ctx->ir_base[insn->op2].op]); @@ -308,7 +391,7 @@ bool ir_check(const ir_ctx *ctx) for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; - if (!ir_check_input_list(ctx, i, use)) { + if (!ir_check_input_list(&check_ctx, ctx, i, use)) { fprintf(stderr, "ir_base[%d] is in use list of ir_base[%d]\n", use, i); ok = 0; } @@ -345,6 +428,9 @@ bool ir_check(const ir_ctx *ctx) ok = 0; } break; + case IR_IGOTO: + case IR_ASM_GOTO: + break; default: /* skip data references */ count = n = use_list->count; @@ -388,9 +474,17 @@ bool ir_check(const ir_ctx *ctx) insn += n; } + if (check_ctx.arena) { + ir_arena_free(check_ctx.arena); + } + // if (!ok) { // ir_dump_codegen(ctx, stderr); // } + +#ifndef IR_CHECK_NO_ABORT IR_ASSERT(ok); +#endif + return ok; } diff --git a/ext/opcache/jit/ir/ir_dump.c b/ext/opcache/jit/ir/ir_dump.c index 54fddf50ac06..3b34294d1c76 100644 --- a/ext/opcache/jit/ir/ir_dump.c +++ b/ext/opcache/jit/ir/ir_dump.c @@ -8,6 +8,14 @@ #include "ir.h" #include "ir_private.h" +#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64) +# include "ir_x86.h" +#elif defined(IR_TARGET_AARCH64) +# include "ir_aarch64.h" +#else +# error "Unknown IR target" +#endif + void ir_dump(const ir_ctx *ctx, FILE *f) { ir_ref i, j, n, ref, *p; @@ -52,7 +60,7 @@ void ir_dump(const ir_ctx *ctx, FILE *f) } } -void ir_dump_dot(const ir_ctx *ctx, const char *name, FILE *f) +void ir_dump_dot(const ir_ctx *ctx, const char *name, const char *comments, FILE *f) { int DATA_WEIGHT = 0; int CONTROL_WEIGHT = 5; @@ -62,6 +70,13 @@ void ir_dump_dot(const ir_ctx *ctx, const char *name, FILE *f) uint32_t flags; fprintf(f, "digraph %s {\n", name); + fprintf(f, "\tlabelloc=t;\n"); + fprintf(f, "\tlabel=\""); + ir_print_func_proto(ctx, name, 0, f); + if (comments) { + fprintf(f, " # %s", comments); + } + fprintf(f, "\"\n"); fprintf(f, "\trankdir=TB;\n"); for (i = 1 - ctx->consts_count, insn = ctx->ir_base + i; i < IR_UNUSED; i++, insn++) { fprintf(f, "\tc%d [label=\"C%d: CONST %s(", -i, -i, ir_type_name[insn->type]); @@ -127,8 +142,14 @@ void ir_dump_dot(const ir_ctx *ctx, const char *name, FILE *f) break; case IR_OPND_CONTROL_DEP: case IR_OPND_CONTROL_REF: + case IR_OPND_CONTROL_GUARD: fprintf(f, "\tn%d -> n%d [style=dashed,dir=back,weight=%d];\n", ref, i, REF_WEIGHT); break; + case IR_OPND_LABEL_REF: + if (ref) { + fprintf(f, "\tc%d -> n%d [color=blue,weight=%d];\n", -ref, i, REF_WEIGHT); + } + break; } } } @@ -451,8 +472,8 @@ void ir_dump_live_ranges(const ir_ctx *ctx, FILE *f) } } #if 1 - n = ctx->vregs_count + ir_regs_number() + 2; - for (i = ctx->vregs_count + 1; i <= n; i++) { + n = ctx->vregs_count + 1 + IR_REG_SET_NUM; + for (i = ctx->vregs_count + 1; i < n; i++) { ir_live_interval *ival = ctx->live_intervals[i]; if (ival) { @@ -491,6 +512,8 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f) ir_print_proto(ctx, insn->proto, f); } else if (insn->op == IR_SYM) { fprintf(f, "sym(%s)", ir_get_str(ctx, insn->val.name)); + } else if (insn->op == IR_LABEL) { + fprintf(f, "label(%s)", ir_get_str(ctx, insn->val.name)); } else if (insn->op == IR_FUNC_ADDR) { fprintf(f, "func *"); ir_print_const(ctx, insn, f, true); @@ -628,6 +651,7 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f) case IR_OPND_CONTROL: case IR_OPND_CONTROL_DEP: case IR_OPND_CONTROL_REF: + case IR_OPND_CONTROL_GUARD: fprintf(f, "%sl_%d", first ? "(" : ", ", ref); first = 0; break; @@ -648,10 +672,18 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f) fprintf(f, "%s%d", first ? "(" : ", ", ref); first = 0; break; + case IR_OPND_LABEL_REF: + if (ref) { + IR_ASSERT(IR_IS_CONST_REF(ref)); + fprintf(f, "%sc_%d", first ? "(" : ", ", -ref); + } + break; } } else if (opnd_kind == IR_OPND_NUM) { fprintf(f, "%s%d", first ? "(" : ", ", ref); first = 0; + } else if (opnd_kind == IR_OPND_CONTROL_GUARD) { + /* skip */ } else if (j != n && (IR_IS_REF_OPND_KIND(opnd_kind) || (opnd_kind == IR_OPND_UNUSED && p[n-j]))) { fprintf(f, "%snull", first ? "(" : ", "); @@ -660,6 +692,12 @@ void ir_dump_codegen(const ir_ctx *ctx, FILE *f) } if (first) { fprintf(f, ";"); + } else if (ctx->value_params + && insn->op == IR_PARAM + && ctx->value_params[insn->op3 - 1].align) { + fprintf(f, ") ByVal(%d, %d);", + ctx->value_params[insn->op3 - 1].size, + ctx->value_params[insn->op3 - 1].align); } else { fprintf(f, ");"); } diff --git a/ext/opcache/jit/ir/ir_emit.c b/ext/opcache/jit/ir/ir_emit.c index c82655daf48d..92b66eb03588 100644 --- a/ext/opcache/jit/ir/ir_emit.c +++ b/ext/opcache/jit/ir/ir_emit.c @@ -5,6 +5,10 @@ * Authors: Dmitry Stogov */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include "ir.h" #if defined(IR_TARGET_X86) || defined(IR_TARGET_X64) @@ -32,8 +36,14 @@ do { \ size_t _sz = (sz), _need = (need); \ if (_sz < _need) { \ + size_t _limit = sizeof(t) * DASM_SEC2POS(1); \ + if (_need > _limit) { \ + Dst_REF->status = DASM_S_NOMEM; \ + return; \ + } \ if (_sz < 16) _sz = 16; \ while (_sz < _need) _sz += _sz; \ + if (_sz > _limit) _sz = _limit; \ (p) = (t *)ir_mem_realloc((p), _sz); \ (sz) = _sz; \ } \ @@ -57,18 +67,7 @@ typedef struct _ir_dessa_copy { int32_t to; /* [0..IR_REG_NUM) - CPU reg, [IR_REG_NUM...) - virtual reg */ } ir_dessa_copy; -#if IR_REG_INT_ARGS -static const int8_t _ir_int_reg_params[IR_REG_INT_ARGS]; -#else -static const int8_t *_ir_int_reg_params; -#endif -#if IR_REG_FP_ARGS -static const int8_t _ir_fp_reg_params[IR_REG_FP_ARGS]; -#else -static const int8_t *_ir_fp_reg_params; -#endif - -static const ir_proto_t *ir_call_proto(const ir_ctx *ctx, ir_insn *insn) +const ir_proto_t *ir_call_proto(const ir_ctx *ctx, const ir_insn *insn) { if (IR_IS_CONST_REF(insn->op2)) { const ir_insn *func = &ctx->ir_base[insn->op2]; @@ -84,49 +83,6 @@ static const ir_proto_t *ir_call_proto(const ir_ctx *ctx, ir_insn *insn) return NULL; } -#ifdef IR_HAVE_FASTCALL -static const int8_t _ir_int_fc_reg_params[IR_REG_INT_FCARGS]; -static const int8_t *_ir_fp_fc_reg_params; - -bool ir_is_fastcall(const ir_ctx *ctx, const ir_insn *insn) -{ - if (sizeof(void*) == 4) { - if (IR_IS_CONST_REF(insn->op2)) { - const ir_insn *func = &ctx->ir_base[insn->op2]; - - if (func->op == IR_FUNC || func->op == IR_FUNC_ADDR) { - if (func->proto) { - const ir_proto_t *proto = (const ir_proto_t *)ir_get_str(ctx, func->proto); - - return (proto->flags & IR_FASTCALL_FUNC) != 0; - } - } - } else if (ctx->ir_base[insn->op2].op == IR_PROTO) { - const ir_proto_t *proto = (const ir_proto_t *)ir_get_str(ctx, ctx->ir_base[insn->op2].op2); - - return (proto->flags & IR_FASTCALL_FUNC) != 0; - } - return 0; - } - return 0; -} -#else -bool ir_is_fastcall(const ir_ctx *ctx, const ir_insn *insn) -{ - return 0; -} -#endif - -bool ir_is_vararg(const ir_ctx *ctx, ir_insn *insn) -{ - const ir_proto_t *proto = ir_call_proto(ctx, insn); - - if (proto) { - return (proto->flags & IR_VARARG_FUNC) != 0; - } - return 0; -} - IR_ALWAYS_INLINE uint32_t ir_rule(const ir_ctx *ctx, ir_ref ref) { IR_ASSERT(!IR_IS_CONST_REF(ref)); @@ -147,19 +103,7 @@ static ir_reg ir_get_param_reg(const ir_ctx *ctx, ir_ref ref) ir_insn *insn; int int_param = 0; int fp_param = 0; - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; - -#ifdef IR_HAVE_FASTCALL - if (sizeof(void*) == 4 && (ctx->flags & IR_FASTCALL_FUNC)) { - int_reg_params_count = IR_REG_INT_FCARGS; - fp_reg_params_count = IR_REG_FP_FCARGS; - int_reg_params = _ir_int_fc_reg_params; - fp_reg_params = _ir_fp_fc_reg_params; - } -#endif + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(ctx->flags); for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { use = *p; @@ -167,87 +111,77 @@ static ir_reg ir_get_param_reg(const ir_ctx *ctx, ir_ref ref) if (insn->op == IR_PARAM) { if (IR_IS_TYPE_INT(insn->type)) { if (use == ref) { - if (int_param < int_reg_params_count) { - return int_reg_params[int_param]; + if (ctx->value_params && ctx->value_params[insn->op3 - 1].align && cc->pass_struct_by_val) { + /* struct passed by value on stack */ + return IR_REG_NONE; + } else if (int_param < cc->int_param_regs_count) { + return cc->int_param_regs[int_param]; } else { return IR_REG_NONE; } + } else if (ctx->value_params && ctx->value_params[insn->op3 - 1].align && cc->pass_struct_by_val) { + /* struct passed by value on stack */ + continue; } int_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - fp_param++; -#endif + if (cc->shadow_param_regs) { + fp_param++; + } } else { IR_ASSERT(IR_IS_TYPE_FP(insn->type)); if (use == ref) { - if (fp_param < fp_reg_params_count) { - return fp_reg_params[fp_param]; + if (fp_param < cc->fp_param_regs_count) { + return cc->fp_param_regs[fp_param]; } else { return IR_REG_NONE; } } fp_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - int_param++; -#endif + if (cc->shadow_param_regs) { + int_param++; + } } } } return IR_REG_NONE; } -static int ir_get_args_regs(const ir_ctx *ctx, const ir_insn *insn, int8_t *regs) +static int ir_get_args_regs(const ir_ctx *ctx, const ir_insn *insn, const ir_call_conv_dsc *cc, int8_t *regs) { int j, n; ir_type type; int int_param = 0; int fp_param = 0; int count = 0; - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; - -#ifdef IR_HAVE_FASTCALL - if (sizeof(void*) == 4 && ir_is_fastcall(ctx, insn)) { - int_reg_params_count = IR_REG_INT_FCARGS; - fp_reg_params_count = IR_REG_FP_FCARGS; - int_reg_params = _ir_int_fc_reg_params; - fp_reg_params = _ir_fp_fc_reg_params; - } -#endif n = insn->inputs_count; n = IR_MIN(n, IR_MAX_REG_ARGS + 2); for (j = 3; j <= n; j++) { - type = ctx->ir_base[ir_insn_op(insn, j)].type; + ir_insn *arg = &ctx->ir_base[ir_insn_op(insn, j)]; + type = arg->type; if (IR_IS_TYPE_INT(type)) { - if (int_param < int_reg_params_count) { - regs[j] = int_reg_params[int_param]; + if (int_param < cc->int_param_regs_count && arg->op != IR_ARGVAL) { + regs[j] = cc->int_param_regs[int_param]; count = j + 1; + int_param++; + if (cc->shadow_param_regs) { + fp_param++; + } } else { regs[j] = IR_REG_NONE; } - int_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - fp_param++; -#endif } else { IR_ASSERT(IR_IS_TYPE_FP(type)); - if (fp_param < fp_reg_params_count) { - regs[j] = fp_reg_params[fp_param]; + if (fp_param < cc->fp_param_regs_count) { + regs[j] = cc->fp_param_regs[fp_param]; count = j + 1; + fp_param++; + if (cc->shadow_param_regs) { + int_param++; + } } else { regs[j] = IR_REG_NONE; } - fp_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - int_param++; -#endif } } return count; @@ -309,7 +243,7 @@ static void* ir_sym_addr(ir_ctx *ctx, const ir_insn *addr_insn) { const char *name = ir_get_str(ctx, addr_insn->val.name); void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ? - ctx->loader->resolve_sym_name(ctx->loader, name, 0) : + ctx->loader->resolve_sym_name(ctx->loader, name, IR_RESOLVE_SYM_SILENT) : ir_resolve_sym_name(name); return addr; @@ -320,7 +254,7 @@ static void* ir_sym_val(ir_ctx *ctx, const ir_insn *addr_insn) { const char *name = ir_get_str(ctx, addr_insn->val.name); void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ? - ctx->loader->resolve_sym_name(ctx->loader, name, addr_insn->op == IR_FUNC) : + ctx->loader->resolve_sym_name(ctx->loader, name, addr_insn->op == IR_FUNC ? IR_RESOLVE_SYM_ADD_THUNK : 0) : ir_resolve_sym_name(name); IR_ASSERT(addr); @@ -399,12 +333,11 @@ static void ir_emit_dessa_moves(ir_ctx *ctx, int b, ir_block *bb); typedef struct _ir_common_backend_data { ir_reg_alloc_data ra_data; - uint32_t dessa_from_block; dasm_State *dasm_state; ir_bitset emit_constants; } ir_common_backend_data; -static int ir_const_label(ir_ctx *ctx, ir_ref ref) +static int ir_get_const_label(ir_ctx *ctx, ir_ref ref) { ir_common_backend_data *data = ctx->data; int label = ctx->cfg_blocks_count - ref; @@ -993,11 +926,16 @@ int ir_match(ir_ctx *ctx) entries_count++; } ctx->rules[start] = IR_SKIPPED | IR_NOP; + if (ctx->ir_base[start].op == IR_BEGIN && ctx->ir_base[start].op2) { + ctx->flags2 |= IR_HAS_BLOCK_ADDR; + } ref = bb->end; if (bb->successors_count == 1) { insn = &ctx->ir_base[ref]; if (insn->op == IR_END || insn->op == IR_LOOP_END) { - ctx->rules[ref] = insn->op; + if (!ctx->rules[ref]) { + ctx->rules[ref] = insn->op; + } ref = prev_ref[ref]; if (ref == start && ctx->cfg_edges[bb->successors] != b) { if (EXPECTED(!(bb->flags & IR_BB_ENTRY))) { @@ -1037,7 +975,7 @@ int ir_match(ir_ctx *ctx) return 1; } -int32_t ir_get_spill_slot_offset(ir_ctx *ctx, ir_ref ref) +int32_t ir_get_spill_slot_offset(const ir_ctx *ctx, ir_ref ref) { int32_t offset; @@ -1046,3 +984,32 @@ int32_t ir_get_spill_slot_offset(ir_ctx *ctx, ir_ref ref) IR_ASSERT(offset != -1); return IR_SPILL_POS_TO_OFFSET(offset); } + +const ir_call_conv_dsc *ir_get_call_conv_dsc(uint32_t flags) +{ +#ifdef IR_TARGET_X86 + if ((flags & IR_CALL_CONV_MASK) == IR_CC_FASTCALL) { + return &ir_call_conv_x86_fastcall; + } +#elif defined(IR_TARGET_X64) + switch (flags & IR_CALL_CONV_MASK) { + case IR_CC_DEFAULT: return &ir_call_conv_default; + case IR_CC_FASTCALL: return &ir_call_conv_default; + case IR_CC_PRESERVE_NONE: return &ir_call_conv_x86_64_preserve_none; + case IR_CC_X86_64_SYSV: return &ir_call_conv_x86_64_sysv; + case IR_CC_X86_64_MS: return &ir_call_conv_x86_64_ms; + default: break; + } +#elif defined(IR_TARGET_AARCH64) + switch (flags & IR_CALL_CONV_MASK) { + case IR_CC_DEFAULT: return &ir_call_conv_default; + case IR_CC_FASTCALL: return &ir_call_conv_default; + case IR_CC_PRESERVE_NONE: return &ir_call_conv_aarch64_preserve_none; + case IR_CC_AARCH64_SYSV: return &ir_call_conv_aarch64_sysv; + case IR_CC_AARCH64_DARWIN: return &ir_call_conv_aarch64_darwin; + default: break; + } +#endif + IR_ASSERT((flags & IR_CALL_CONV_MASK) == IR_CC_DEFAULT || (flags & IR_CALL_CONV_MASK) == IR_CC_BUILTIN); + return &ir_call_conv_default; +} diff --git a/ext/opcache/jit/ir/ir_fold.h b/ext/opcache/jit/ir/ir_fold.h index 88539e52ab08..cbe049be932c 100644 --- a/ext/opcache/jit/ir/ir_fold.h +++ b/ext/opcache/jit/ir/ir_fold.h @@ -274,6 +274,106 @@ IR_FOLD(UGT(C_FLOAT, C_FLOAT)) IR_FOLD_BOOL(!(op1_insn->val.f <= op2_insn->val.f)); } +IR_FOLD(ORDERED(C_FLOAT, C_FLOAT)) +{ + IR_FOLD_BOOL(!isnan(op1_insn->val.f) && !isnan(op2_insn->val.f)); +} + +IR_FOLD(ORDERED(C_DOUBLE, C_DOUBLE)) +{ + IR_FOLD_BOOL(!isnan(op1_insn->val.d) && !isnan(op2_insn->val.d)); +} + +IR_FOLD(UNORDERED(C_FLOAT, C_FLOAT)) +{ + IR_FOLD_BOOL(isnan(op1_insn->val.f) || isnan(op2_insn->val.f)); +} + +IR_FOLD(UNORDERED(C_DOUBLE, C_DOUBLE)) +{ + IR_FOLD_BOOL(isnan(op1_insn->val.d) || isnan(op2_insn->val.d)); +} + +IR_FOLD(EQ(_, C_FLOAT)) +IR_FOLD(LT(_, C_FLOAT)) +IR_FOLD(GE(_, C_FLOAT)) +IR_FOLD(LE(_, C_FLOAT)) +IR_FOLD(GT(_, C_FLOAT)) +{ + if (isnan(op2_insn->val.f)) { + IR_FOLD_COPY(IR_FALSE); + } + IR_FOLD_NEXT; +} + +IR_FOLD(NE(_, C_FLOAT)) +{ + if (isnan(op2_insn->val.f)) { + IR_FOLD_COPY(IR_TRUE); + } + IR_FOLD_NEXT; +} + +IR_FOLD(ORDERED(_, C_FLOAT)) +{ + if (isnan(op2_insn->val.f)) { + IR_FOLD_COPY(IR_FALSE); + } else { + op2 = op1; + IR_FOLD_RESTART; + } +} + +IR_FOLD(UNORDERED(_, C_FLOAT)) +{ + if (isnan(op2_insn->val.f)) { + IR_FOLD_COPY(IR_TRUE); + } else { + op2 = op1; + IR_FOLD_RESTART; + } +} + +IR_FOLD(EQ(_, C_DOUBLE)) +IR_FOLD(LT(_, C_DOUBLE)) +IR_FOLD(GE(_, C_DOUBLE)) +IR_FOLD(LE(_, C_DOUBLE)) +IR_FOLD(GT(_, C_DOUBLE)) +{ + if (isnan(op2_insn->val.d)) { + IR_FOLD_COPY(IR_FALSE); + } + IR_FOLD_NEXT; +} + +IR_FOLD(NE(_, C_DOUBLE)) +{ + if (isnan(op2_insn->val.d)) { + IR_FOLD_COPY(IR_TRUE); + } + IR_FOLD_NEXT; +} + +IR_FOLD(ORDERED(_, C_DOUBLE)) +{ + if (isnan(op2_insn->val.d)) { + IR_FOLD_COPY(IR_FALSE); + } else { + op2 = op1; + IR_FOLD_RESTART; + } +} + +IR_FOLD(UNORDERED(_, C_DOUBLE)) +{ + if (isnan(op2_insn->val.d)) { + IR_FOLD_COPY(IR_TRUE); + } else { + op2 = op1; + IR_FOLD_RESTART; + } +} + IR_FOLD(ADD(C_U8, C_U8)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); @@ -538,7 +638,8 @@ IR_FOLD(DIV(C_ADDR, C_ADDR)) IR_FOLD(DIV(C_I8, C_I8)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - if (op2_insn->val.i64 == 0) { + if (op2_insn->val.i64 == 0 + || (op2_insn->val.i64 == -1 && op1_insn->val.u8 == 0x80)) { /* division by zero */ IR_FOLD_EMIT; } @@ -548,7 +649,8 @@ IR_FOLD(DIV(C_I8, C_I8)) IR_FOLD(DIV(C_I16, C_I16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - if (op2_insn->val.i64 == 0) { + if (op2_insn->val.i64 == 0 + || (op2_insn->val.i64 == -1 && op1_insn->val.u16 == 0x8000)) { /* division by zero */ IR_FOLD_EMIT; } @@ -558,7 +660,8 @@ IR_FOLD(DIV(C_I16, C_I16)) IR_FOLD(DIV(C_I32, C_I32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - if (op2_insn->val.i64 == 0) { + if (op2_insn->val.i64 == 0 + || (op2_insn->val.i64 == -1 && op1_insn->val.u32 == 0x80000000)) { /* division by zero */ IR_FOLD_EMIT; } @@ -568,7 +671,8 @@ IR_FOLD(DIV(C_I32, C_I32)) IR_FOLD(DIV(C_I64, C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - if (op2_insn->val.i64 == 0) { + if (op2_insn->val.i64 == 0 + || (op2_insn->val.i64 == -1 && op1_insn->val.u64 == 0x8000000000000000)) { /* division by zero */ IR_FOLD_EMIT; } @@ -615,12 +719,27 @@ IR_FOLD(MOD(C_I64, C_I64)) } IR_FOLD(NEG(C_I8)) +{ + IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); + IR_FOLD_CONST_I((int8_t)(0 - op1_insn->val.u8)); +} + IR_FOLD(NEG(C_I16)) +{ + IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); + IR_FOLD_CONST_I((int16_t)(0 -op1_insn->val.u16)); +} + IR_FOLD(NEG(C_I32)) +{ + IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); + IR_FOLD_CONST_I((int32_t)(0 - op1_insn->val.u32)); +} + IR_FOLD(NEG(C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(-op1_insn->val.u64); + IR_FOLD_CONST_I(0 - op1_insn->val.u64); } IR_FOLD(NEG(C_DOUBLE)) @@ -636,8 +755,35 @@ IR_FOLD(NEG(C_FLOAT)) } IR_FOLD(ABS(C_I8)) +{ + IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); + if (op1_insn->val.i64 >= 0) { + IR_FOLD_COPY(op1); + } else { + IR_FOLD_CONST_I(-op1_insn->val.i8); + } +} + IR_FOLD(ABS(C_I16)) +{ + IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); + if (op1_insn->val.i64 >= 0) { + IR_FOLD_COPY(op1); + } else { + IR_FOLD_CONST_I(-op1_insn->val.i16); + } +} + IR_FOLD(ABS(C_I32)) +{ + IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); + if (op1_insn->val.i64 >= 0) { + IR_FOLD_COPY(op1); + } else { + IR_FOLD_CONST_I((int32_t)-op1_insn->val.u32); + } +} + IR_FOLD(ABS(C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); @@ -728,7 +874,7 @@ IR_FOLD(MUL_OV(C_U64, C_U64)) uint64_t res; IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); res = op1_insn->val.u64 * op2_insn->val.u64; - if (op1_insn->val.u64 != 0 && res / op1_insn->val.u64 != op2_insn->val.u64 && res <= max) { + if ((op1_insn->val.u64 != 0 && res / op1_insn->val.u64 != op2_insn->val.u64) || res > max) { IR_FOLD_NEXT; } IR_FOLD_CONST_U(res); @@ -745,7 +891,7 @@ IR_FOLD(MUL_OV(C_I64, C_I64)) int64_t res; IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); res = op1_insn->val.u64 * op2_insn->val.u64; - if (op1_insn->val.i64 != 0 && res / op1_insn->val.i64 != op2_insn->val.i64 && res >= min && res <= max) { + if ((op1_insn->val.i64 != 0 && res / op1_insn->val.i64 != op2_insn->val.i64) || res < min || res > max) { IR_FOLD_NEXT; } IR_FOLD_CONST_U(res); @@ -918,220 +1064,220 @@ IR_FOLD(SHL(C_U8, C_U8)) IR_FOLD(SHL(C_CHAR, C_CHAR)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u8 << op2_insn->val.u8); + IR_FOLD_CONST_U(op1_insn->val.u8 << (op2_insn->val.u8 & 0x7)); } IR_FOLD(SHL(C_I8, C_I8)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(op1_insn->val.i8 << op2_insn->val.i8); + IR_FOLD_CONST_I((int8_t)(op1_insn->val.u8 << (op2_insn->val.u8 & 0x7))); } IR_FOLD(SHL(C_U16, C_U16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u16 << op2_insn->val.u16); + IR_FOLD_CONST_U(op1_insn->val.u16 << (op2_insn->val.u16 & 0xf)); } IR_FOLD(SHL(C_I16, C_I16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(op1_insn->val.i16 << op2_insn->val.i16); + IR_FOLD_CONST_I((int16_t)(op1_insn->val.u16 << (op2_insn->val.u16 & 0xf))); } IR_FOLD(SHL(C_U32, C_U32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u32 << op2_insn->val.u32); + IR_FOLD_CONST_U(op1_insn->val.u32 << (op2_insn->val.u32 & 0x1f)); } IR_FOLD(SHL(C_I32, C_I32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(op1_insn->val.i32 << op2_insn->val.i32); + IR_FOLD_CONST_I((int32_t)(op1_insn->val.u32 << (op2_insn->val.u32 & 0x1f))); } IR_FOLD(SHL(C_U64, C_U64)) IR_FOLD(SHL(C_I64, C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u64 << op2_insn->val.u64); + IR_FOLD_CONST_U(op1_insn->val.u64 << (op2_insn->val.u64 & 0x3f)); } IR_FOLD(SHR(C_U8, C_U8)) IR_FOLD(SHR(C_CHAR, C_CHAR)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u8 >> op2_insn->val.u8); + IR_FOLD_CONST_U(op1_insn->val.u8 >> (op2_insn->val.u8 & 0x7)); } IR_FOLD(SHR(C_I8, C_I8)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I((int8_t)(op1_insn->val.u8 >> op2_insn->val.u8)); + IR_FOLD_CONST_I((int8_t)(op1_insn->val.u8 >> (op2_insn->val.u8 & 0x7))); } IR_FOLD(SHR(C_U16, C_U16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u16 >> op2_insn->val.u16); + IR_FOLD_CONST_U(op1_insn->val.u16 >> (op2_insn->val.u16 & 0xf)); } IR_FOLD(SHR(C_I16, C_I16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U((int16_t)(op1_insn->val.u16 >> op2_insn->val.u16)); + IR_FOLD_CONST_I((int16_t)(op1_insn->val.u16 >> (op2_insn->val.u16 & 0xf))); } IR_FOLD(SHR(C_U32, C_U32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u32 >> op2_insn->val.u32); + IR_FOLD_CONST_U(op1_insn->val.u32 >> (op2_insn->val.u32 & 0x1f)); } IR_FOLD(SHR(C_I32, C_I32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U((int32_t)(op1_insn->val.u32 >> op2_insn->val.u32)); + IR_FOLD_CONST_I((int32_t)(op1_insn->val.u32 >> (op2_insn->val.u32 & 0x1f))); } IR_FOLD(SHR(C_U64, C_U64)) IR_FOLD(SHR(C_I64, C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(op1_insn->val.u64 >> op2_insn->val.u64); + IR_FOLD_CONST_U(op1_insn->val.u64 >> (op2_insn->val.u64 & 0x3f)); } IR_FOLD(SAR(C_U8, C_U8)) IR_FOLD(SAR(C_CHAR, C_CHAR)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U((uint8_t)(op1_insn->val.i8 >> op2_insn->val.i8)); + IR_FOLD_CONST_U((uint8_t)(op1_insn->val.i8 >> (op2_insn->val.i8 & 0x7))); } IR_FOLD(SAR(C_I8, C_I8)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(op1_insn->val.i8 >> op2_insn->val.i8); + IR_FOLD_CONST_I(op1_insn->val.i8 >> (op2_insn->val.i8 & 0x7)); } IR_FOLD(SAR(C_U16, C_U16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U((uint16_t)(op1_insn->val.i16 >> op2_insn->val.i16)); + IR_FOLD_CONST_U((uint16_t)(op1_insn->val.i16 >> (op2_insn->val.i16 & 0xf))); } IR_FOLD(SAR(C_I16, C_I16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(op1_insn->val.i16 >> op2_insn->val.i16); + IR_FOLD_CONST_I(op1_insn->val.i16 >> (op2_insn->val.i16 & 0xf)); } IR_FOLD(SAR(C_U32, C_U32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U((uint32_t)(op1_insn->val.i32 >> op2_insn->val.i32)); + IR_FOLD_CONST_U((uint32_t)(op1_insn->val.i32 >> (op2_insn->val.i32 & 0x1f))); } IR_FOLD(SAR(C_I32, C_I32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(op1_insn->val.i32 >> op2_insn->val.i32); + IR_FOLD_CONST_I(op1_insn->val.i32 >> (op2_insn->val.i32 & 0x1f)); } IR_FOLD(SAR(C_U64, C_U64)) IR_FOLD(SAR(C_I64, C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I(op1_insn->val.i64 >> op2_insn->val.i64); + IR_FOLD_CONST_I(op1_insn->val.i64 >> (op2_insn->val.i64 & 0x3f)); } IR_FOLD(ROL(C_U8, C_U8)) IR_FOLD(ROL(C_CHAR, C_CHAR)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_rol8(op1_insn->val.u8, op2_insn->val.u8)); + IR_FOLD_CONST_U(ir_rol8(op1_insn->val.u8, (op2_insn->val.u8 & 0x7))); } IR_FOLD(ROL(C_I8, C_I8)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I((int8_t)ir_rol8(op1_insn->val.u8, op2_insn->val.u8)); + IR_FOLD_CONST_I((int8_t)ir_rol8(op1_insn->val.u8, (op2_insn->val.u8 & 0x7))); } IR_FOLD(ROL(C_U16, C_U16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_rol16(op1_insn->val.u16, op2_insn->val.u16)); + IR_FOLD_CONST_U(ir_rol16(op1_insn->val.u16, (op2_insn->val.u16 & 0xf))); } IR_FOLD(ROL(C_I16, C_I16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I((int16_t)ir_rol16(op1_insn->val.u16, op2_insn->val.u16)); + IR_FOLD_CONST_I((int16_t)ir_rol16(op1_insn->val.u16, (op2_insn->val.u16 & 0xf))); } IR_FOLD(ROL(C_U32, C_U32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_rol32(op1_insn->val.u32, op2_insn->val.u32)); + IR_FOLD_CONST_U(ir_rol32(op1_insn->val.u32, (op2_insn->val.u32 & 0x1f))); } IR_FOLD(ROL(C_I32, C_I32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I((int32_t)ir_rol32(op1_insn->val.u32, op2_insn->val.u32)); + IR_FOLD_CONST_I((int32_t)ir_rol32(op1_insn->val.u32, (op2_insn->val.u32 & 0x1f))); } IR_FOLD(ROL(C_U64, C_U64)) IR_FOLD(ROL(C_I64, C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_rol64(op1_insn->val.u64, op2_insn->val.u64)); + IR_FOLD_CONST_U(ir_rol64(op1_insn->val.u64, (op2_insn->val.u64 & 0x3f))); } IR_FOLD(ROR(C_U8, C_U8)) IR_FOLD(ROR(C_CHAR, C_CHAR)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_ror8(op1_insn->val.u8, op2_insn->val.u8)); + IR_FOLD_CONST_U(ir_ror8(op1_insn->val.u8, (op2_insn->val.u8 & 0x7))); } IR_FOLD(ROR(C_I8, C_I8)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I((int8_t)ir_ror8(op1_insn->val.u8, op2_insn->val.u8)); + IR_FOLD_CONST_I((int8_t)ir_ror8(op1_insn->val.u8, (op2_insn->val.u8 & 0x7))); } IR_FOLD(ROR(C_U16, C_U16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_ror16(op1_insn->val.u16, op2_insn->val.u16)); + IR_FOLD_CONST_U(ir_ror16(op1_insn->val.u16, (op2_insn->val.u16 & 0xf))); } IR_FOLD(ROR(C_I16, C_I16)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I((int16_t)ir_ror16(op1_insn->val.u16, op2_insn->val.u16)); + IR_FOLD_CONST_I((int16_t)ir_ror16(op1_insn->val.u16, (op2_insn->val.u16 & 0xf))); } IR_FOLD(ROR(C_U32, C_U32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_ror32(op1_insn->val.u32, op2_insn->val.u32)); + IR_FOLD_CONST_U(ir_ror32(op1_insn->val.u32, (op2_insn->val.u32 & 0x1f))); } IR_FOLD(ROR(C_I32, C_I32)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_I((int32_t)ir_ror32(op1_insn->val.u32, op2_insn->val.u32)); + IR_FOLD_CONST_I((int32_t)ir_ror32(op1_insn->val.u32, (op2_insn->val.u32 & 0x1f))); } IR_FOLD(ROR(C_U64, C_U64)) IR_FOLD(ROR(C_I64, C_I64)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - IR_FOLD_CONST_U(ir_ror64(op1_insn->val.u64, op2_insn->val.u64)); + IR_FOLD_CONST_U(ir_ror64(op1_insn->val.u64, (op2_insn->val.u64 & 0x3f))); } //IR_FOLD(BSWAP(CONST)) @@ -1273,6 +1419,9 @@ IR_FOLD(TRUNC(C_U64)) IR_FOLD_CONST_U(op1_insn->val.u16); case IR_U32: IR_FOLD_CONST_U(op1_insn->val.u32); + case IR_ADDR: + IR_ASSERT(sizeof(void*) == 4); + IR_FOLD_CONST_U(op1_insn->val.u32); } } @@ -1426,7 +1575,7 @@ IR_FOLD(FP2FP(C_DOUBLE)) IR_FOLD(COPY(_)) { IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type); - if (!op2) { + if (!(op2 & IR_COPY_HARD)) { IR_FOLD_COPY(op1); } /* skip CSE */ @@ -1530,44 +1679,6 @@ IR_FOLD(EQ(SEXT, C_I16)) IR_FOLD(EQ(SEXT, C_I32)) IR_FOLD(EQ(SEXT, C_I64)) IR_FOLD(EQ(SEXT, C_ADDR)) -{ - if (ctx->use_lists && ctx->use_lists[op1_insn->op1].count != 1) { - /* pass */ - } else if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { - opt = IR_OPT(IR_NOT, IR_BOOL); - op1 = op1_insn->op1; - op2 = IR_UNUSED; - IR_FOLD_RESTART; - } else { - ir_type type = ctx->ir_base[op1_insn->op1].type; - - if (op1_insn->op == IR_ZEXT - && (op2_insn->val.u64 >> (ir_type_size[type] * 8)) != 0) { - IR_FOLD_NEXT; - } - if (IR_IS_TYPE_SIGNED(type)) { - switch (ir_type_size[type]) { - case 1: val.i64 = op2_insn->val.i8; break; - case 2: val.i64 = op2_insn->val.i16; break; - case 4: val.i64 = op2_insn->val.i32; break; - default: val.u64 = op2_insn->val.u64; break; - } - } else { - switch (ir_type_size[type]) { - case 1: val.u64 = op2_insn->val.u8; break; - case 2: val.u64 = op2_insn->val.u16; break; - case 4: val.u64 = op2_insn->val.u32; break; - default: val.u64 = op2_insn->val.u64; break; - } - } - op1 = op1_insn->op1; - op2 = ir_const(ctx, val, type); - IR_FOLD_RESTART; - } - - IR_FOLD_NEXT; -} - IR_FOLD(NE(ZEXT, C_U16)) IR_FOLD(NE(ZEXT, C_U32)) IR_FOLD(NE(ZEXT, C_U64)) @@ -1582,16 +1693,93 @@ IR_FOLD(NE(SEXT, C_I16)) IR_FOLD(NE(SEXT, C_I32)) IR_FOLD(NE(SEXT, C_I64)) IR_FOLD(NE(SEXT, C_ADDR)) -{ - if (ctx->use_lists && ctx->use_lists[op1_insn->op1].count != 1) { +IR_FOLD(ULT(ZEXT, C_U16)) +IR_FOLD(ULT(ZEXT, C_U32)) +IR_FOLD(ULT(ZEXT, C_U64)) +IR_FOLD(ULT(ZEXT, C_I16)) +IR_FOLD(ULT(ZEXT, C_I32)) +IR_FOLD(ULT(ZEXT, C_I64)) +IR_FOLD(ULT(ZEXT, C_ADDR)) +IR_FOLD(UGE(ZEXT, C_U16)) +IR_FOLD(UGE(ZEXT, C_U32)) +IR_FOLD(UGE(ZEXT, C_U64)) +IR_FOLD(UGE(ZEXT, C_I16)) +IR_FOLD(UGE(ZEXT, C_I32)) +IR_FOLD(UGE(ZEXT, C_I64)) +IR_FOLD(UGE(ZEXT, C_ADDR)) +IR_FOLD(ULE(ZEXT, C_U16)) +IR_FOLD(ULE(ZEXT, C_U32)) +IR_FOLD(ULE(ZEXT, C_U64)) +IR_FOLD(ULE(ZEXT, C_I16)) +IR_FOLD(ULE(ZEXT, C_I32)) +IR_FOLD(ULE(ZEXT, C_I64)) +IR_FOLD(ULE(ZEXT, C_ADDR)) +IR_FOLD(UGT(ZEXT, C_U16)) +IR_FOLD(UGT(ZEXT, C_U32)) +IR_FOLD(UGT(ZEXT, C_U64)) +IR_FOLD(UGT(ZEXT, C_I16)) +IR_FOLD(UGT(ZEXT, C_I32)) +IR_FOLD(UGT(ZEXT, C_I64)) +IR_FOLD(UGT(ZEXT, C_ADDR)) +IR_FOLD(LT(SEXT, C_U16)) +IR_FOLD(LT(SEXT, C_U32)) +IR_FOLD(LT(SEXT, C_U64)) +IR_FOLD(LT(SEXT, C_I16)) +IR_FOLD(LT(SEXT, C_I32)) +IR_FOLD(LT(SEXT, C_I64)) +IR_FOLD(LT(SEXT, C_ADDR)) +IR_FOLD(GE(SEXT, C_U16)) +IR_FOLD(GE(SEXT, C_U32)) +IR_FOLD(GE(SEXT, C_U64)) +IR_FOLD(GE(SEXT, C_I16)) +IR_FOLD(GE(SEXT, C_I32)) +IR_FOLD(GE(SEXT, C_I64)) +IR_FOLD(GE(SEXT, C_ADDR)) +IR_FOLD(LE(SEXT, C_U16)) +IR_FOLD(LE(SEXT, C_U32)) +IR_FOLD(LE(SEXT, C_U64)) +IR_FOLD(LE(SEXT, C_I16)) +IR_FOLD(LE(SEXT, C_I32)) +IR_FOLD(LE(SEXT, C_I64)) +IR_FOLD(LE(SEXT, C_ADDR)) +IR_FOLD(GT(SEXT, C_U16)) +IR_FOLD(GT(SEXT, C_U32)) +IR_FOLD(GT(SEXT, C_U64)) +IR_FOLD(GT(SEXT, C_I16)) +IR_FOLD(GT(SEXT, C_I32)) +IR_FOLD(GT(SEXT, C_I64)) +IR_FOLD(GT(SEXT, C_ADDR)) +{ + if (ctx->use_lists && ctx->use_lists[op1].count != 1) { /* pass */ - } else if (op2_insn->val.u64 == 0 && ctx->ir_base[op1_insn->op1].type == IR_BOOL) { - IR_FOLD_COPY(op1_insn->op1); } else { ir_type type = ctx->ir_base[op1_insn->op1].type; - if (op1_insn->op == IR_ZEXT - && (op2_insn->val.u64 >> (ir_type_size[type] * 8)) != 0) { + if (type == IR_BOOL && op2_insn->val.u64 == 0) { + if ((opt & IR_OPT_OP_MASK) == IR_EQ) { + opt = IR_OPT(IR_NOT, IR_BOOL); + op1 = op1_insn->op1; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } else if ((opt & IR_OPT_OP_MASK) == IR_NE) { + IR_FOLD_COPY(op1_insn->op1); + } + } + if ((op2_insn->val.u64 >> (ir_type_size[type] * 8)) != 0 + && (op1_insn->op != IR_SEXT || (op2_insn->val.i64 >> (ir_type_size[type] * 8)) != -1)) { + if ((opt & IR_OPT_OP_MASK) == IR_EQ + || (opt & IR_OPT_OP_MASK) == IR_UGT + || (opt & IR_OPT_OP_MASK) == IR_UGE) { + IR_FOLD_COPY(IR_FALSE); + } else if ((opt & IR_OPT_OP_MASK) == IR_NE + || (opt & IR_OPT_OP_MASK) == IR_ULT + || (opt & IR_OPT_OP_MASK) == IR_ULE) { + IR_FOLD_COPY(IR_TRUE); + } else if ((opt & IR_OPT_OP_MASK) == IR_GT || (opt & IR_OPT_OP_MASK) == IR_GE) { + IR_FOLD_COPY(op2_insn->val.i64 >= 0 ? IR_FALSE : IR_TRUE); + } else if ((opt & IR_OPT_OP_MASK) == IR_LT || (opt & IR_OPT_OP_MASK) == IR_LE) { + IR_FOLD_COPY(op2_insn->val.i64 >= 0 ? IR_TRUE : IR_FALSE); + } IR_FOLD_NEXT; } if (IR_IS_TYPE_SIGNED(type)) { @@ -1616,6 +1804,43 @@ IR_FOLD(NE(SEXT, C_ADDR)) IR_FOLD_NEXT; } +IR_FOLD(EQ(ZEXT, ZEXT)) +IR_FOLD(NE(ZEXT, ZEXT)) +IR_FOLD(ULT(ZEXT, ZEXT)) +IR_FOLD(UGE(ZEXT, ZEXT)) +IR_FOLD(ULE(ZEXT, ZEXT)) +IR_FOLD(UGT(ZEXT, ZEXT)) +IR_FOLD(EQ(SEXT, SEXT)) +IR_FOLD(NE(SEXT, SEXT)) +IR_FOLD(LT(SEXT, SEXT)) +IR_FOLD(GE(SEXT, SEXT)) +IR_FOLD(LE(SEXT, SEXT)) +IR_FOLD(GT(SEXT, SEXT)) +{ + if (ctx->ir_base[op1_insn->op1].type == ctx->ir_base[op2_insn->op1].type + && (!ctx->use_lists || (ctx->use_lists[op1].count == 1 && ctx->use_lists[op2].count == 1))) { + op1 = op1_insn->op1; + op2 = op2_insn->op1; + IR_FOLD_RESTART; + } + IR_FOLD_NEXT; +} + +IR_FOLD(LT(ZEXT, ZEXT)) +IR_FOLD(GE(ZEXT, ZEXT)) +IR_FOLD(LE(ZEXT, ZEXT)) +IR_FOLD(GT(ZEXT, ZEXT)) +{ + if (ctx->ir_base[op1_insn->op1].type == ctx->ir_base[op2_insn->op1].type + && (!ctx->use_lists || (ctx->use_lists[op1].count == 1 && ctx->use_lists[op2].count == 1))) { + op1 = op1_insn->op1; + op2 = op2_insn->op1; + opt += 4; /* LT -> ULT, ... */ + IR_FOLD_RESTART; + } + IR_FOLD_NEXT; +} + IR_FOLD(NOT(EQ)) IR_FOLD(NOT(NE)) IR_FOLD(NOT(LT)) @@ -1626,6 +1851,8 @@ IR_FOLD(NOT(ULT)) IR_FOLD(NOT(UGE)) IR_FOLD(NOT(ULE)) IR_FOLD(NOT(UGT)) +IR_FOLD(NOT(ORDERED)) +IR_FOLD(NOT(UNORDERED)) { if (IR_IS_TYPE_INT(ctx->ir_base[op1_insn->op1].type)) { opt = op1_insn->opt ^ 1; @@ -1703,6 +1930,11 @@ IR_FOLD(SUB_OV(_, C_ADDR)) { if (op2_insn->val.u64 == 0) { /* a +/- 0 => a */ + if (op1_insn->type != IR_OPT_TYPE(opt)) { + opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK); + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } IR_FOLD_COPY(op1); } IR_FOLD_NEXT; @@ -1721,6 +1953,12 @@ IR_FOLD(ADD(C_ADDR, _)) { if (op1_insn->val.u64 == 0) { /* 0 + a => a */ + if (op2_insn->type != IR_OPT_TYPE(opt)) { + opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK); + op1 = op2; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } IR_FOLD_COPY(op2); } IR_FOLD_NEXT; @@ -1830,6 +2068,12 @@ IR_FOLD(ADD(SUB, _)) if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) { if (op1_insn->op2 == op2) { /* (a - b) + b => a */ + if (ctx->ir_base[op1_insn->op1].type != IR_OPT_TYPE(opt)) { + opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK); + op1 = op1_insn->op1; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } IR_FOLD_COPY(op1_insn->op1); } } @@ -1841,6 +2085,12 @@ IR_FOLD(ADD(_, SUB)) if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) { if (op2_insn->op2 == op1) { /* a + (b - a) => b */ + if (ctx->ir_base[op2_insn->op1].type != IR_OPT_TYPE(opt)) { + opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK); + op1 = op2_insn->op1; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } IR_FOLD_COPY(op2_insn->op1); } } @@ -1852,9 +2102,21 @@ IR_FOLD(SUB(ADD, _)) if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) { if (op1_insn->op1 == op2) { /* (a + b) - a => b */ + if (ctx->ir_base[op1_insn->op2].type != IR_OPT_TYPE(opt)) { + opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK); + op1 = op1_insn->op2; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } IR_FOLD_COPY(op1_insn->op2); } else if (op1_insn->op2 == op2) { /* (a + b) - a => b */ + if (ctx->ir_base[op1_insn->op1].type != IR_OPT_TYPE(opt)) { + opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK); + op1 = op1_insn->op1; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } IR_FOLD_COPY(op1_insn->op1); } } @@ -1900,6 +2162,12 @@ IR_FOLD(SUB(_, SUB)) if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) { if (op2_insn->op1 == op1) { /* a - (a - b) => b */ + if (ctx->ir_base[op2_insn->op2].type != IR_OPT_TYPE(opt)) { + opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK); + op1 = op2_insn->op2; + op2 = IR_UNUSED; + IR_FOLD_RESTART; + } IR_FOLD_COPY(op2_insn->op2); } } @@ -1909,25 +2177,27 @@ IR_FOLD(SUB(_, SUB)) IR_FOLD(SUB(ADD, ADD)) { if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) { - if (op1_insn->op1 == op2_insn->op1) { + if (op1 == op2) { + IR_FOLD_CONST_U(0); + } else if (op1_insn->op1 == op2_insn->op1) { /* (a + b) - (a + c) => b - c */ - op1 = op1_insn->op2; - op2 = op2_insn->op2; + op1 = _ir_fold_cast(ctx, op1_insn->op2, IR_OPT_TYPE(opt)); + op2 = _ir_fold_cast(ctx, op2_insn->op2, IR_OPT_TYPE(opt)); IR_FOLD_RESTART; } else if (op1_insn->op1 == op2_insn->op2) { /* (a + b) - (c + a) => b - c */ - op1 = op1_insn->op2; - op2 = op2_insn->op1; + op1 = _ir_fold_cast(ctx, op1_insn->op2, IR_OPT_TYPE(opt)); + op2 = _ir_fold_cast(ctx, op2_insn->op1, IR_OPT_TYPE(opt)); IR_FOLD_RESTART; } else if (op1_insn->op2 == op2_insn->op1) { /* (a + b) - (b + c) => a - c */ - op1 = op1_insn->op1; - op2 = op2_insn->op2; + op1 = _ir_fold_cast(ctx, op1_insn->op1, IR_OPT_TYPE(opt)); + op2 = _ir_fold_cast(ctx, op2_insn->op2, IR_OPT_TYPE(opt)); IR_FOLD_RESTART; } else if (op1_insn->op2 == op2_insn->op2) { /* (a + b) - (c + b) => a - c */ - op1 = op1_insn->op1; - op2 = op2_insn->op1; + op1 = _ir_fold_cast(ctx, op1_insn->op1, IR_OPT_TYPE(opt)); + op2 = _ir_fold_cast(ctx, op2_insn->op1, IR_OPT_TYPE(opt)); IR_FOLD_RESTART; } } @@ -2726,7 +2996,7 @@ IR_FOLD(ADD(ADD, C_ADDR)) /* (x + c1) + c2 => x + (c1 + c2) */ val.u64 = ctx->ir_base[op1_insn->op2].val.u64 + op2_insn->val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2741,7 +3011,7 @@ IR_FOLD(ADD(ADD, C_I64)) /* (x + c1) + c2 => x + (c1 + c2) */ val.i64 = ctx->ir_base[op1_insn->op2].val.u64 + op2_insn->val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2757,14 +3027,14 @@ IR_FOLD(ADD(SUB, C_ADDR)) /* (x - c1) + c2 => x + (c2 - c1) */ val.u64 = op2_insn->val.u64 - ctx->ir_base[op1_insn->op2].val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) { /* (c1 - x) + c2 => (c1 + c2) - x */ val.u64 = ctx->ir_base[op1_insn->op1].val.u64 + op2_insn->val.u64; opt++; /* ADD -> SUB */ op2 = op1_insn->op2; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2783,14 +3053,14 @@ IR_FOLD(ADD(SUB, C_I64)) opt++; /* ADD -> SUB */ } op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) { /* (c1 - x) + c2 => (c1 + c2) - x */ val.i64 = ctx->ir_base[op1_insn->op1].val.u64 + op2_insn->val.u64; opt++; /* ADD -> SUB */ op2 = op1_insn->op2; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2807,7 +3077,7 @@ IR_FOLD(SUB(ADD, C_ADDR)) val.u64 = ctx->ir_base[op1_insn->op2].val.u64 - op2_insn->val.u64; opt--; /* SUB -> ADD */ op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2827,7 +3097,7 @@ IR_FOLD(SUB(ADD, C_I64)) opt--; /* SUB -> ADD */ } op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2843,7 +3113,7 @@ IR_FOLD(SUB(C_ADDR, ADD)) /* c1 - (x + c2) => (c1 - c2) - x */ val.u64 = op1_insn->val.u64 - ctx->ir_base[op2_insn->op2].val.u64; op2 = op2_insn->op1; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2858,7 +3128,7 @@ IR_FOLD(SUB(C_I64, ADD)) /* c1 - (x + c2) => (c1 - c2) - x */ val.i64 = op1_insn->val.u64 - ctx->ir_base[op2_insn->op2].val.u64; op2 = op2_insn->op1; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2878,13 +3148,13 @@ IR_FOLD(SUB(SUB, C_ADDR)) opt--; /* SUB -> ADD */ } op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) { /* (c1 - x) - c2 => (c1 - c2) - x */ val.u64 = ctx->ir_base[op1_insn->op1].val.u64 - op2_insn->val.u64; op2 = op1_insn->op2; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2903,13 +3173,13 @@ IR_FOLD(SUB(SUB, C_I64)) opt--; /* SUB -> ADD */ } op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } else if (IR_IS_CONST_REF(op1_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op1_insn->op1].op)) { /* (c1 - x) - c2 => (c1 - c2) - x */ val.i64 = ctx->ir_base[op1_insn->op1].val.u64 - op2_insn->val.u64; op2 = op1_insn->op2; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2925,7 +3195,7 @@ IR_FOLD(SUB(C_ADDR, SUB)) /* c1 - (x - c2) => (c1 + c2) - x */ val.u64 = op1_insn->val.u64 + ctx->ir_base[op2_insn->op2].val.u64; op2 = op2_insn->op1; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op1_insn->type); IR_FOLD_RESTART; } else if (IR_IS_CONST_REF(op2_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op1].op)) { /* c1 - (c2 - x) => x + (c1 - c2) */ @@ -2935,7 +3205,7 @@ IR_FOLD(SUB(C_ADDR, SUB)) opt++; /* ADD -> SUB */ } op1 = op2_insn->op2; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op1_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2950,7 +3220,7 @@ IR_FOLD(SUB(C_I64, SUB)) /* c1 - (x - c2) => (c1 + c2) - x */ val.i64 = op1_insn->val.u64 + ctx->ir_base[op2_insn->op2].val.u64; op2 = op2_insn->op1; - op1 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op1 = ir_const(ctx, val, op1_insn->type); IR_FOLD_RESTART; } else if (IR_IS_CONST_REF(op2_insn->op1) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op1].op)) { /* c1 - (c2 - x) => x + (c1 - c2) */ @@ -2960,7 +3230,7 @@ IR_FOLD(SUB(C_I64, SUB)) opt++; /* ADD -> SUB */ } op1 = op2_insn->op2; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op1_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2976,7 +3246,7 @@ IR_FOLD(MUL(MUL, C_ADDR)) /* (x * c1) * c2 => x * (c1 * c2) */ val.u64 = ctx->ir_base[op1_insn->op2].val.u64 * op2_insn->val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -2991,7 +3261,7 @@ IR_FOLD(MUL(MUL, C_I64)) /* (x * c1) * c2 => x * (c1 * c2) */ val.i64 = ctx->ir_base[op1_insn->op2].val.u64 * op2_insn->val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -3011,7 +3281,7 @@ IR_FOLD(AND(AND, C_ADDR)) /* (x & c1) & c2 => x & (c1 & c2) */ val.u64 = ctx->ir_base[op1_insn->op2].val.u64 & op2_insn->val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -3031,7 +3301,7 @@ IR_FOLD(OR(OR, C_ADDR)) /* (x | c1) | c2 => x | (c1 | c2) */ val.u64 = ctx->ir_base[op1_insn->op2].val.u64 | op2_insn->val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -3051,7 +3321,7 @@ IR_FOLD(XOR(XOR, C_ADDR)) /* (x ^ c1) ^ c2 => x ^ (c1 ^ c2) */ val.u64 = ctx->ir_base[op1_insn->op2].val.u64 ^ op2_insn->val.u64; op1 = op1_insn->op1; - op2 = ir_const(ctx, val, IR_OPT_TYPE(opt)); + op2 = ir_const(ctx, val, op2_insn->type); IR_FOLD_RESTART; } IR_FOLD_NEXT; @@ -3120,6 +3390,8 @@ IR_FOLD(ADD(SHR, SHL)) /* Swap operands (move lower ref to op2) for better CSE */ IR_FOLD(MUL(_, _)) +IR_FOLD(ORDERED(_, _)) +IR_FOLD(UNORDERED(_, _)) IR_FOLD_NAMED(swap_ops) { if (op1 < op2) { /* move lower ref to op2 */ @@ -3243,5 +3515,84 @@ IR_FOLD(COND(_, _)) // TODO: COND(_, _, _) if (op2 == op3) { IR_FOLD_COPY(op2); } + + if (op1_insn->type == IR_BOOL) { + if (op2 == IR_TRUE) { + if (op3 == IR_FALSE) { + /* a ? true : false => a */ + IR_FOLD_COPY(op1); + } else { + /* a ? true : b => a | b */ + opt = IR_OPT(IR_OR, IR_BOOL); + op2 = op3; + op3 = IR_UNUSED; + IR_FOLD_RESTART; + } + } else if (op3 == IR_FALSE) { + /* a ? b : false => a & b */ + opt = IR_OPT(IR_AND, IR_BOOL); + op3 = IR_UNUSED; + IR_FOLD_RESTART; + } else if (op2 == IR_FALSE) { + if (op3 == IR_TRUE) { + /* a ? flase : true => !a */ + opt = IR_OPT(IR_NOT, IR_BOOL); + op2 = IR_UNUSED; + op3 = IR_UNUSED; + IR_FOLD_RESTART; + } + } else if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt)) + && IR_IS_CONST_REF(op2) + && IR_IS_CONST_REF(op3) + && op2_insn->val.u64 == 1 + && op3_insn->val.u64 == 0) { + if (ir_type_size[IR_OPT_TYPE(opt)] > 1) { + /* a ? 1 : 0 => ZEXT(a) */ + opt = IR_OPT(IR_ZEXT, IR_OPT_TYPE(opt)); + } else { + /* a ? 1 : 0 => BITCAST(a) */ + opt = IR_OPT(IR_BITCAST, IR_OPT_TYPE(opt)); + } + op2 = IR_UNUSED; + op3 = IR_UNUSED; + IR_FOLD_RESTART; + } + } else if (IR_IS_TYPE_INT(op1_insn->type)) { + if (op2 == IR_TRUE) { + if (op3 == IR_FALSE) { + opt = IR_OPT(IR_NE, IR_BOOL); + val.u64 = 0; + op2 = ir_const(ctx, val, op1_insn->type); + op3 = IR_UNUSED; + IR_FOLD_RESTART; + } + } else if (op2 == IR_FALSE) { + if (op3 == IR_TRUE) { + opt = IR_OPT(IR_EQ, IR_BOOL); + val.u64 = 0; + op2 = ir_const(ctx, val, op1_insn->type); + op3 = IR_UNUSED; + IR_FOLD_RESTART; + } + } + } + + if (op1_insn->op == IR_NE) { + if (IR_IS_CONST_REF(op1_insn->op2) + && IR_IS_TYPE_INT(ctx->ir_base[op1_insn->op2].type) + && ctx->ir_base[op1_insn->op2].val.u64 == 0) { + op1 = op1_insn->op1; + IR_FOLD_RESTART; + } + } else if (op1_insn->op == IR_EQ) { + if (IR_IS_CONST_REF(op1_insn->op2) + && IR_IS_TYPE_INT(ctx->ir_base[op1_insn->op2].type) + && ctx->ir_base[op1_insn->op2].val.u64 == 0) { + op1 = op1_insn->op1; + SWAP_REFS(op2, op3); + IR_FOLD_RESTART; + } + } + IR_FOLD_NEXT; } diff --git a/ext/opcache/jit/ir/ir_gcm.c b/ext/opcache/jit/ir/ir_gcm.c index 8bd6be5d10aa..b194eeb81770 100644 --- a/ext/opcache/jit/ir/ir_gcm.c +++ b/ext/opcache/jit/ir/ir_gcm.c @@ -148,7 +148,7 @@ static uint32_t ir_gcm_select_best_block(ir_ctx *ctx, ir_ref ref, uint32_t lca) } #if IR_GCM_SPLIT -/* Partially Dead Code Elimination through splitting the node and sunking the clones +/* Partially Dead Code Elimination through splitting the node and sinking the clones * * This code is based on the Benedikt Meurer's idea first implemented in V8. * See: https://codereview.chromium.org/899433005 @@ -262,7 +262,7 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) #endif /* 1.2. Iteratively check the predecessors of already found TOTALLY_USEFUL blocks and - * add them into TOTALLY_USEFUL set if all of their sucessors are already there. + * add them into TOTALLY_USEFUL set if all of their successors are already there. */ IR_SPARSE_SET_FOREACH(&data->totally_useful, i) { _push_predecessors(ctx, &ctx->cfg_blocks[i], data); @@ -309,6 +309,7 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) struct { ir_ref ref; uint32_t block; + uint32_t lca; uint32_t use_count; uint32_t use; } *clones = ir_mem_malloc(sizeof(*clones) * use_list->count); @@ -344,8 +345,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) clone = clones_count++; ir_hashtab_add(&hash, j, clone); clones[clone].block = j; + clones[clone].lca = i; clones[clone].use_count = 0; clones[clone].use = (uint32_t)-1; + } else { + clones[clone].lca = ir_gcm_find_lca(ctx, clones[clone].lca, i); } uses[uses_count].ref = use; uses[uses_count].block = i; @@ -367,8 +371,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) clone = clones_count++; ir_hashtab_add(&hash, j, clone); clones[clone].block = j; + clones[clone].lca = i; clones[clone].use_count = 0; clones[clone].use = -1; + } else { + clones[clone].lca = ir_gcm_find_lca(ctx, clones[clone].lca, i); } uses[uses_count].ref = use; uses[uses_count].block = i; @@ -378,6 +385,42 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) } } + /* Select best blocks to insert clones */ + for (i = 0; i < clones_count; i++) { + uint32_t b0 = clones[i].block; + uint32_t lca = clones[i].lca; + + if (b0 != lca) { + ir_block *bb = &ctx->cfg_blocks[lca]; + uint32_t loop_depth = bb->loop_depth; + + if (loop_depth) { + uint32_t b; + uint32_t best; + + best = b = lca; + do { + b = bb->dom_parent; + bb = &ctx->cfg_blocks[b]; + if (bb->loop_depth < loop_depth) { + if (!bb->loop_depth) { + best = b; + break; + } + loop_depth = bb->loop_depth; + best = b; + } + } while (b != b0); + lca = best; + } + clones[i].block = lca; + } + } + + // TODO: instead of inserting clone into the block where the expressin is partially available, + // we should insert PHI and the actual clones into the block sources where it's not available + // (similar to SSAPRE) + #ifdef IR_DEBUG if (ctx->flags & IR_DEBUG_GCM_SPLIT) { for (i = 0; i < clones_count; i++) { @@ -408,12 +451,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) } /* Reconstruct IR: Update DEF->USE lists, CFG mapping and etc */ - ctx->use_lists = ir_mem_realloc(ctx->use_lists, ctx->insns_count * sizeof(ir_use_list)); - ctx->cfg_map = ir_mem_realloc(ctx->cfg_map, ctx->insns_count * sizeof(uint32_t)); n = ctx->use_lists[ref].refs; for (i = 0; i < clones_count; i++) { clone = clones[i].ref; - if (clones[i].use_count == 1 + if (clones[i].block + && clones[i].use_count == 1 && ctx->cfg_blocks[clones[i].block].loop_depth >= ctx->cfg_blocks[uses[clones[i].use].block].loop_depth) { /* TOTALLY_USEFUL block may be a head of a diamond above the real usage. * Sink it down to the real usage block. @@ -427,6 +469,7 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) uint32_t u = clones[i].use; while (u != (uint32_t)-1) { + uint32_t src = uses[u].block; use = uses[u].ref; ctx->use_edges[n++] = use; u = uses[u].next; @@ -436,9 +479,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b) ir_ref k, l = insn->inputs_count; if (insn->op == IR_PHI) { - for (k = 1; k <= l; k++) { - if (ir_insn_op(insn, k) == ref) { - j = ctx->cfg_map[ir_insn_op(&ctx->ir_base[insn->op1], k - 1)]; + ir_insn *merge = &ctx->ir_base[insn->op1]; + for (k = 2; k <= l; k++) { + j = ctx->cfg_map[ir_insn_op(merge, k - 1)]; + if (j == src) { + IR_ASSERT(ir_insn_op(insn, k) == ref); if (j != clones[i].block) { uint32_t dom_depth = ctx->cfg_blocks[clones[i].block].dom_depth; while (ctx->cfg_blocks[j].dom_depth > dom_depth) { @@ -785,103 +830,308 @@ IR_ALWAYS_INLINE ir_ref ir_count_constant(ir_ref *_xlat, ir_ref ref) return 0; } +IR_ALWAYS_INLINE bool ir_is_good_bb_order(ir_ctx *ctx, uint32_t b, ir_block *bb, ir_ref start) +{ + ir_insn *insn = &ctx->ir_base[start]; + uint32_t n = insn->inputs_count; + ir_ref *p = insn->ops + 1; + + if (n == 1) { + return ctx->cfg_map[*p] < b; + } else { + IR_ASSERT(n > 1); + for (; n > 0; p++, n--) { + ir_ref input = *p; + + if (!IR_IS_CONST_REF(input)) { + uint32_t input_b = ctx->cfg_map[input]; + + if (input_b < b) { + /* ordered */ + } else if ((bb->flags & IR_BB_LOOP_HEADER) + && (input_b == b || ctx->cfg_blocks[input_b].loop_header == b)) { + /* back-edge of reducible loop */ + } else if ((bb->flags & IR_BB_IRREDUCIBLE_LOOP) + && (ctx->cfg_blocks[input_b].loop_header == bb->loop_header)) { + /* closing edge of irreducible loop */ + } else { + return 0; + } + } + } + return 1; + } +} + +static IR_NEVER_INLINE void ir_fix_bb_order(ir_ctx *ctx, ir_ref *_prev, ir_ref *_next) +{ + uint32_t b, succ, count, *q, *xlat; + ir_block *bb; + ir_ref ref, n, prev; + ir_worklist worklist; + ir_block *new_blocks; + +#if 0 + for (b = 1, bb = ctx->cfg_blocks + 1; b <= ctx->cfg_blocks_count; b++, bb++) { + if (!ir_is_good_bb_order(ctx, b, bb, bb->start)) { + goto fix; + } + } + return; + +fix: +#endif + count = ctx->cfg_blocks_count + 1; + new_blocks = ir_mem_malloc(count * sizeof(ir_block)); + xlat = ir_mem_malloc(count * sizeof(uint32_t)); + ir_worklist_init(&worklist, count); + ir_worklist_push(&worklist, 1); + /* Schedule blocks bottom-up. Place block only after all its successurs (except back-edges) are placed. */ + while (ir_worklist_len(&worklist) != 0) { +next: + b = ir_worklist_peek(&worklist); + bb = &ctx->cfg_blocks[b]; + n = bb->successors_count; + if (n == 1) { + succ = ctx->cfg_edges[bb->successors]; + if (ir_bitset_in(worklist.visited, succ)) { + /* already processed */ + } else if ((ctx->cfg_blocks[succ].flags & IR_BB_IRREDUCIBLE_LOOP) + && ((ctx->cfg_blocks[b].flags & IR_BB_LOOP_HEADER) ? + (ctx->cfg_blocks[succ].loop_header != b) : + (ctx->cfg_blocks[succ].loop_header != ctx->cfg_blocks[b].loop_header))) { + /* "side" entry of irreducible loop (ignore) */ + } else if (ir_worklist_push(&worklist, succ)) { + goto next; + } + } else if (n > 1) { + uint32_t best = 0; + uint32_t best_loop_depth = 0; + + q = ctx->cfg_edges + bb->successors + n; + do { + q--; + succ = *q; + if (ir_bitset_in(worklist.visited, succ)) { + /* already processed */ + } else if ((ctx->cfg_blocks[succ].flags & IR_BB_IRREDUCIBLE_LOOP) + && ((ctx->cfg_blocks[b].flags & IR_BB_LOOP_HEADER) ? + (ctx->cfg_blocks[succ].loop_header != b) : + (ctx->cfg_blocks[succ].loop_header != ctx->cfg_blocks[b].loop_header))) { + /* "side" entry of irreducible loop (ignore) */ + } else if (!best) { + best = succ; + best_loop_depth = ctx->cfg_blocks[best].loop_depth; + } else if (ctx->cfg_blocks[succ].loop_depth < best_loop_depth) { + /* prefer deeper loop */ + best = succ; + best_loop_depth = ctx->cfg_blocks[best].loop_depth; + } + n--; + } while (n > 0); + if (best) { + ir_worklist_push(&worklist, best); + goto next; + } + } + + /* All successors of "b" are placed. Now we can place "b" itself. */ + ir_worklist_pop(&worklist); + count--; + new_blocks[count] = *bb; + xlat[b] = count; + } + IR_ASSERT(count == 1); + xlat[0] = 0; + ir_worklist_free(&worklist); + + prev = 0; + for (b = 1, bb = new_blocks + 1; b <= ctx->cfg_blocks_count; b++, bb++) { + bb->idom = xlat[bb->idom]; + bb->loop_header = xlat[bb->loop_header]; + n = bb->successors_count; + if (n > 0) { + for (q = ctx->cfg_edges + bb->successors; n > 0; q++, n--) { + *q = xlat[*q]; + } + } + n = bb->predecessors_count; + if (n > 0) { + for (q = ctx->cfg_edges + bb->predecessors; n > 0; q++, n--) { + *q = xlat[*q]; + } + } + _next[prev] = bb->start; + _prev[bb->start] = prev; + prev = bb->end; + } + _next[0] = 0; + _next[prev] = 0; + + for (ref = 2; ref < ctx->insns_count; ref++) { + ctx->cfg_map[ref] = xlat[ctx->cfg_map[ref]]; + } + ir_mem_free(xlat); + + ir_mem_free(ctx->cfg_blocks); + ctx->cfg_blocks = new_blocks; +} + +#if IR_DEBUG +static void ir_schedule_print_list(const ir_ctx *ctx, uint32_t b, const ir_ref *_next, + ir_ref start, ir_ref end, const char *label) +{ + ir_ref ref; + + fprintf(stderr, " %s [%d", label, start); + ref = _next[start]; + while (ref != end) { + fprintf(stderr, ",%d", ref); + ref = _next[ref]; + } + fprintf(stderr, ",%d]\n", ref); +} +#endif + +/* Simple Stable Topological Sort */ +static void ir_schedule_topsort(const ir_ctx *ctx, uint32_t b, const ir_block *bb, + ir_ref *_xlat, ir_ref *_next, ir_ref *_prev, + ir_ref ref, ir_ref end, + ir_ref *insns_count, ir_ref *consts_count) +{ + ir_ref i = ref; + const ir_insn *insn; + + if (bb->successors_count > 1) { + ir_ref input, j = bb->end; + ir_insn *end = &ctx->ir_base[j]; + + if (end->op == IR_IF) { + /* Move condition closer to IF */ + input = end->op2; + if (input > 0 + && ctx->cfg_map[input] == b + && !_xlat[input] + && _prev[j] != input + && (!(ir_op_flags[ctx->ir_base[input].op] & IR_OP_FLAG_CONTROL) || end->op1 == input)) { + if (input == i) { + i = _next[i]; + insn = &ctx->ir_base[i]; + } + /* remove "input" */ + _prev[_next[input]] = _prev[input]; + _next[_prev[input]] = _next[input]; + /* insert before "j" */ + _prev[input] = _prev[j]; + _next[input] = j; + _next[_prev[j]] = input; + _prev[j] = input; + } + } + } + + while (i != end) { + ir_ref n, j, input; + const ir_ref *p; + +restart: + IR_ASSERT(ctx->cfg_map[i] == b); + insn = &ctx->ir_base[i]; + n = insn->inputs_count; + for (j = n, p = insn->ops + 1; j > 0; p++, j--) { + input = *p; + if (!_xlat[input]) { + /* input is not scheduled yet */ + if (input > 0) { + if (ctx->cfg_map[input] == b) { + /* "input" should be before "i" to satisfy dependency */ +#ifdef IR_DEBUG + if (ctx->flags & IR_DEBUG_SCHEDULE) { + fprintf(stderr, "Wrong dependency %d:%d -> %d\n", b, input, i); + } +#endif + /* remove "input" */ + _prev[_next[input]] = _prev[input]; + _next[_prev[input]] = _next[input]; + /* insert before "i" */ + _prev[input] = _prev[i]; + _next[input] = i; + _next[_prev[i]] = input; + _prev[i] = input; + /* restart from "input" */ + i = input; + goto restart; + } + } else if (input < IR_TRUE) { + *consts_count += ir_count_constant(_xlat, input); + } + } + } + + _xlat[i] = *insns_count; + *insns_count += ir_insn_inputs_to_len(n); + IR_ASSERT(_next[i] != IR_UNUSED); + i = _next[i]; + } +} + int ir_schedule(ir_ctx *ctx) { - ir_ctx new_ctx; ir_ref i, j, k, n, *p, *q, ref, new_ref, prev_ref, insns_count, consts_count, use_edges_count; ir_ref *_xlat; ir_ref *edges; ir_ref prev_b_end; - uint32_t b, prev_b; - uint32_t *_blocks = ctx->cfg_map; + uint32_t b; ir_ref *_next = ir_mem_malloc(ctx->insns_count * sizeof(ir_ref)); ir_ref *_prev = ir_mem_malloc(ctx->insns_count * sizeof(ir_ref)); - ir_ref _move_down = 0; ir_block *bb; - ir_insn *insn, *new_insn; + ir_insn *insn, *new_insn, *base; ir_use_list *lists, *use_list, *new_list; + bool bad_bb_order = 0; /* Create a double-linked list of nodes ordered by BB, respecting BB->start and BB->end */ - IR_ASSERT(_blocks[1] == 1); - prev_b = 1; - prev_b_end = ctx->cfg_blocks[1].end; + IR_ASSERT(ctx->cfg_map[1] == 1); + + /* link BB boundaries */ _prev[1] = 0; - _prev[prev_b_end] = 0; - for (i = 2, j = 1; i < ctx->insns_count; i++) { - b = _blocks[i]; - IR_ASSERT((int32_t)b >= 0); - if (b == prev_b && i <= prev_b_end) { - /* add to the end of the list */ - _next[j] = i; - _prev[i] = j; - j = i; - } else if (b > prev_b) { - bb = &ctx->cfg_blocks[b]; - if (i == bb->start) { - IR_ASSERT(bb->end > bb->start); - prev_b = b; - prev_b_end = bb->end; - _prev[bb->end] = 0; - /* add to the end of the list */ - _next[j] = i; - _prev[i] = j; - j = i; - } else { - IR_ASSERT(i != bb->end); - /* move down late (see the following loop) */ - _next[i] = _move_down; - _move_down = i; - } - } else if (b) { - bb = &ctx->cfg_blocks[b]; - IR_ASSERT(i != bb->start); - if (_prev[bb->end]) { - /* move up, insert before the end of the already scheduled BB */ - k = bb->end; - } else { - /* move up, insert at the end of the block */ - k = ctx->cfg_blocks[b + 1].start; - } - /* insert before "k" */ - _prev[i] = _prev[k]; - _next[i] = k; - _next[_prev[k]] = i; - _prev[k] = i; + prev_b_end = ctx->cfg_blocks[1].end; + _next[1] = prev_b_end; + _prev[prev_b_end] = 1; + for (b = 2, bb = ctx->cfg_blocks + 2; b <= ctx->cfg_blocks_count; b++, bb++) { + ir_ref start = bb->start; + ir_ref end = bb->end; + _next[prev_b_end] = start; + _prev[start] = prev_b_end; + _next[start] = end; + _prev[end] = start; + prev_b_end = end; + if (!ir_is_good_bb_order(ctx, b, bb, start)) { + bad_bb_order = 1; } } - _next[j] = 0; - - while (_move_down) { - i = _move_down; - _move_down = _next[i]; - b = _blocks[i]; + _next[prev_b_end] = 0; + + /* insert intermediate BB nodes */ + use_edges_count = ctx->use_lists[1].count; + for (i = 2, use_list = &ctx->use_lists[i]; i < ctx->insns_count; use_list++, i++) { + b = ctx->cfg_map[i]; + if (!b) continue; + use_edges_count += use_list->count; bb = &ctx->cfg_blocks[b]; - k = _next[bb->start]; - - if (bb->flags & (IR_BB_HAS_PHI|IR_BB_HAS_PI|IR_BB_HAS_PARAM|IR_BB_HAS_VAR)) { - /* insert after the start of the block and all PARAM, VAR, PI, PHI */ - insn = &ctx->ir_base[k]; - while (insn->op == IR_PHI || insn->op == IR_PARAM || insn->op == IR_VAR || insn->op == IR_PI) { - k = _next[k]; - insn = &ctx->ir_base[k]; - } + if (i != bb->start && i != bb->end) { + /* insert before "end" */ + ir_ref next = bb->end; + ir_ref prev = _prev[next]; + _prev[i] = prev; + _next[i] = next; + _next[prev] = i; + _prev[next] = i; } - - /* insert before "k" */ - _prev[i] = _prev[k]; - _next[i] = k; - _next[_prev[k]] = i; - _prev[k] = i; } -#ifdef IR_DEBUG - if (ctx->flags & IR_DEBUG_SCHEDULE) { - fprintf(stderr, "Before Schedule\n"); - for (i = 1; i != 0; i = _next[i]) { - fprintf(stderr, "%d -> %d\n", i, _blocks[i]); - } + if (bad_bb_order) { + ir_fix_bb_order(ctx, _prev, _next); } -#endif _xlat = ir_mem_calloc((ctx->consts_count + ctx->insns_count), sizeof(ir_ref)); _xlat += ctx->consts_count; @@ -892,18 +1142,34 @@ int ir_schedule(ir_ctx *ctx) insns_count = 1; consts_count = -(IR_TRUE - 1); - /* Topological sort according dependencies inside each basic block */ + /* Schedule instructions inside each BB (now just topological sort according to dependencies) */ for (b = 1, bb = ctx->cfg_blocks + 1; b <= ctx->cfg_blocks_count; b++, bb++) { ir_ref start; +#ifdef IR_DEBUG + if (ctx->flags & IR_DEBUG_SCHEDULE) { + fprintf(stderr, "BB%d\n", b); + ir_schedule_print_list(ctx, b, _next, bb->start, bb->end, "INITIAL"); + } +#endif + IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); /* Schedule BB start */ start = i = bb->start; _xlat[i] = bb->start = insns_count; insn = &ctx->ir_base[i]; - if (insn->op == IR_CASE_VAL) { + if (insn->op == IR_BEGIN) { + if (insn->op2) { + consts_count += ir_count_constant(_xlat, insn->op2); + } + } else if (insn->op == IR_CASE_VAL) { + IR_ASSERT(insn->op2 < IR_TRUE); + consts_count += ir_count_constant(_xlat, insn->op2); + } else if (insn->op == IR_CASE_RANGE) { IR_ASSERT(insn->op2 < IR_TRUE); consts_count += ir_count_constant(_xlat, insn->op2); + IR_ASSERT(insn->op3 < IR_TRUE); + consts_count += ir_count_constant(_xlat, insn->op3); } n = insn->inputs_count; insns_count += ir_insn_inputs_to_len(n); @@ -946,12 +1212,12 @@ int ir_schedule(ir_ctx *ctx) for (p = &ctx->use_edges[use_list->refs]; count > 0; p++, count--) { ir_ref use = *p; ir_insn *use_insn = &ctx->ir_base[use]; - if (!_xlat[use] && (_blocks[use] || use_insn->op == IR_PARAM)) { - IR_ASSERT(_blocks[use] == b || use_insn->op == IR_PARAM); + if (!_xlat[use] && ctx->cfg_map[use]) { if (use_insn->op == IR_PARAM || use_insn->op == IR_VAR || use_insn->op == IR_PI || use_insn->op == IR_PHI) { + IR_ASSERT(ctx->cfg_map[use] == b); if (_prev[use] != phis) { /* remove "use" */ _prev[_next[use]] = _prev[use]; @@ -984,70 +1250,20 @@ int ir_schedule(ir_ctx *ctx) insn = &ctx->ir_base[i]; } } - if (bb->successors_count > 1) { - ir_ref input, j = bb->end; - ir_insn *end = &ctx->ir_base[j]; - - if (end->op == IR_IF) { - /* Move condition closer to IF */ - input = end->op2; - if (input > 0 && _blocks[input] == b && !_xlat[input] && _prev[j] != input) { - if (input == i) { - i = _next[i]; - insn = &ctx->ir_base[i]; - } - /* remove "input" */ - _prev[_next[input]] = _prev[input]; - _next[_prev[input]] = _next[input]; - /* insert before "j" */ - _prev[input] = _prev[j]; - _next[input] = j; - _next[_prev[j]] = input; - _prev[j] = input; - } - } + + if (i != bb->end) { + ir_schedule_topsort(ctx, b, bb, _xlat, _next, _prev, i, bb->end, &insns_count, &consts_count); } - while (i != bb->end) { - ir_ref n, j, *p, input; -restart: - n = insn->inputs_count; - for (j = n, p = insn->ops + 1; j > 0; p++, j--) { - input = *p; - if (!_xlat[input]) { - /* input is not scheduled yet */ - if (input > 0) { - if (_blocks[input] == b) { - /* "input" should be before "i" to satisfy dependency */ #ifdef IR_DEBUG - if (ctx->flags & IR_DEBUG_SCHEDULE) { - fprintf(stderr, "Wrong dependency %d:%d -> %d\n", b, input, i); - } -#endif - /* remove "input" */ - _prev[_next[input]] = _prev[input]; - _next[_prev[input]] = _next[input]; - /* insert before "i" */ - _prev[input] = _prev[i]; - _next[input] = i; - _next[_prev[i]] = input; - _prev[i] = input; - /* restart from "input" */ - i = input; - insn = &ctx->ir_base[i]; - goto restart; - } - } else if (input < IR_TRUE) { - consts_count += ir_count_constant(_xlat, input); - } - } - } - _xlat[i] = insns_count; - insns_count += ir_insn_inputs_to_len(n); - i = _next[i]; - insn = &ctx->ir_base[i]; + if (ctx->flags & IR_DEBUG_SCHEDULE) { + ir_schedule_print_list(ctx, b, _next, start, bb->end, " FINAL"); } +#endif + /* Schedule BB end */ + i = bb->end; + insn = &ctx->ir_base[i]; _xlat[i] = bb->end = insns_count; insns_count++; if (IR_INPUT_EDGES_COUNT(ir_op_flags[insn->op]) == 2) { @@ -1057,15 +1273,6 @@ int ir_schedule(ir_ctx *ctx) } } -#ifdef IR_DEBUG - if (ctx->flags & IR_DEBUG_SCHEDULE) { - fprintf(stderr, "After Schedule\n"); - for (i = 1; i != 0; i = _next[i]) { - fprintf(stderr, "%d -> %d (%d)\n", i, _blocks[i], _xlat[i]); - } - } -#endif - #if 1 /* Check if scheduling didn't make any modifications */ if (consts_count == ctx->consts_count && insns_count == ctx->insns_count) { @@ -1093,106 +1300,55 @@ int ir_schedule(ir_ctx *ctx) ir_mem_free(_prev); - ir_init(&new_ctx, ctx->flags, consts_count, insns_count); - new_ctx.insns_count = insns_count; - new_ctx.flags2 = ctx->flags2; - new_ctx.ret_type = ctx->ret_type; - new_ctx.mflags = ctx->mflags; - new_ctx.spill_base = ctx->spill_base; - new_ctx.fixed_stack_red_zone = ctx->fixed_stack_red_zone; - new_ctx.fixed_stack_frame_size = ctx->fixed_stack_frame_size; - new_ctx.fixed_call_stack_size = ctx->fixed_call_stack_size; - new_ctx.fixed_regset = ctx->fixed_regset; - new_ctx.fixed_save_regset = ctx->fixed_save_regset; - new_ctx.entries_count = ctx->entries_count; -#if defined(IR_TARGET_AARCH64) - new_ctx.deoptimization_exits = ctx->deoptimization_exits; - new_ctx.get_exit_addr = ctx->get_exit_addr; - new_ctx.get_veneer = ctx->get_veneer; - new_ctx.set_veneer = ctx->set_veneer; -#endif - new_ctx.loader = ctx->loader; + uint32_t *map = ir_mem_calloc(insns_count, sizeof(uint32_t)); + _prev = ir_mem_malloc(insns_count * sizeof(ir_ref)); + lists = ir_mem_malloc(insns_count * sizeof(ir_use_list)); + ir_ref *use_edges = edges = ir_mem_malloc(use_edges_count * sizeof(ir_ref)); + base = ir_mem_malloc((consts_count + insns_count) * sizeof(ir_insn)); + base += consts_count; /* Copy constants */ - if (consts_count == ctx->consts_count) { - new_ctx.consts_count = consts_count; - ref = 1 - consts_count; - insn = &ctx->ir_base[ref]; - new_insn = &new_ctx.ir_base[ref]; - - memcpy(new_insn, insn, sizeof(ir_insn) * (IR_TRUE - ref)); - if (ctx->strtab.data) { - while (ref != IR_TRUE) { - if (new_insn->op == IR_FUNC_ADDR) { - if (new_insn->proto) { - size_t len; - const char *proto = ir_get_strl(ctx, new_insn->proto, &len); - new_insn->proto = ir_strl(&new_ctx, proto, len); - } - } else if (new_insn->op == IR_FUNC) { - new_insn->val.u64 = ir_str(&new_ctx, ir_get_str(ctx, new_insn->val.name)); - if (new_insn->proto) { - size_t len; - const char *proto = ir_get_strl(ctx, new_insn->proto, &len); - new_insn->proto = ir_strl(&new_ctx, proto, len); - } - } else if (new_insn->op == IR_SYM || new_insn->op == IR_STR) { - new_insn->val.u64 = ir_str(&new_ctx, ir_get_str(ctx, new_insn->val.name)); - } - new_insn++; - ref++; - } + if (ctx->consts_count == consts_count) { + memcpy(base - consts_count + 1, ctx->ir_base - consts_count + 1, sizeof(ir_insn) * consts_count); + for (j = -consts_count + 1; j < IR_TRUE; j++) { + _xlat[j] = j; } } else { - new_ref = -new_ctx.consts_count; - new_insn = &new_ctx.ir_base[new_ref]; - for (ref = IR_TRUE - 1, insn = &ctx->ir_base[ref]; ref > -ctx->consts_count; insn--, ref--) { - if (!_xlat[ref]) { - continue; + ir_insn *src = ctx->ir_base - ctx->consts_count + 1; + ir_insn *dst = base - consts_count + 1; + + i = -ctx->consts_count + 1; + j = -consts_count + 1; + while (i < IR_TRUE) { + if (_xlat[i]) { + *dst = *src; + dst->prev_const = 0; + _xlat[i] = j; + dst++; + j++; } - new_insn->optx = insn->optx; - new_insn->prev_const = 0; - if (insn->op == IR_FUNC_ADDR) { - new_insn->val.u64 = insn->val.u64; - if (insn->proto) { - size_t len; - const char *proto = ir_get_strl(ctx, insn->proto, &len); - new_insn->proto = ir_strl(&new_ctx, proto, len); - } else { - new_insn->proto = 0; - } - } else if (insn->op == IR_FUNC) { - new_insn->val.u64 = ir_str(&new_ctx, ir_get_str(ctx, insn->val.name)); - if (insn->proto) { - size_t len; - const char *proto = ir_get_strl(ctx, insn->proto, &len); - new_insn->proto = ir_strl(&new_ctx, proto, len); - } else { - new_insn->proto = 0; - } - } else if (insn->op == IR_SYM || insn->op == IR_STR) { - new_insn->val.u64 = ir_str(&new_ctx, ir_get_str(ctx, insn->val.name)); - } else { - new_insn->val.u64 = insn->val.u64; - } - _xlat[ref] = new_ref; - new_ref--; - new_insn--; + src++; + i++; } - new_ctx.consts_count = -new_ref; + IR_ASSERT(j == IR_TRUE); + base[IR_TRUE].optx = IR_OPT(IR_C_BOOL, IR_BOOL); + base[IR_TRUE].val.u64 = 1; + base[IR_FALSE].optx = IR_OPT(IR_C_BOOL, IR_BOOL); + base[IR_FALSE].val.u64 = 0; + base[IR_NULL].optx = IR_OPT(IR_C_ADDR, IR_ADDR); + base[IR_NULL].val.u64 = 0; + MAKE_NOP(&base[IR_UNUSED]); } - new_ctx.cfg_map = ir_mem_calloc(ctx->insns_count, sizeof(uint32_t)); - new_ctx.prev_ref = _prev = ir_mem_malloc(insns_count * sizeof(ir_ref)); - new_ctx.use_lists = lists = ir_mem_malloc(insns_count * sizeof(ir_use_list)); - new_ctx.use_edges = edges = ir_mem_malloc(ctx->use_edges_count * sizeof(ir_ref)); - /* Copy instructions, use lists and use edges */ +#ifdef IR_DEBUG + ir_ref orig_use_edges_count = use_edges_count; +#endif prev_ref = 0; use_edges_count = 0; for (i = 1; i != 0; i = _next[i]) { new_ref = _xlat[i]; - new_ctx.cfg_map[new_ref] = _blocks[i]; + map[new_ref] = ctx->cfg_map[i]; _prev[new_ref] = prev_ref; prev_ref = new_ref; @@ -1201,7 +1357,7 @@ int ir_schedule(ir_ctx *ctx) k = 0; if (n == 1) { ref = ctx->use_edges[use_list->refs]; - if (_xlat[ref]) { + if (EXPECTED(_xlat[ref])) { *edges = _xlat[ref]; edges++; k = 1; @@ -1210,7 +1366,7 @@ int ir_schedule(ir_ctx *ctx) p = &ctx->use_edges[use_list->refs]; while (n--) { ref = *p; - if (_xlat[ref]) { + if (EXPECTED(_xlat[ref])) { *edges = _xlat[ref]; edges++; k++; @@ -1224,7 +1380,7 @@ int ir_schedule(ir_ctx *ctx) new_list->count = k; insn = &ctx->ir_base[i]; - new_insn = &new_ctx.ir_base[new_ref]; + new_insn = &base[new_ref]; new_insn->optx = insn->optx; n = new_insn->inputs_count; @@ -1236,12 +1392,8 @@ int ir_schedule(ir_ctx *ctx) break; case 1: new_insn->op1 = _xlat[insn->op1]; - if (new_insn->op == IR_PARAM || insn->op == IR_VAR) { - new_insn->op2 = ir_str(&new_ctx, ir_get_str(ctx, insn->op2)); - } else if (new_insn->op == IR_PROTO) { - size_t len; - const char *proto = ir_get_strl(ctx, insn->op2, &len); - new_insn->op2 = ir_strl(&new_ctx, proto, len); + if (new_insn->op == IR_BEGIN && insn->op2) { + new_insn->op2 = _xlat[insn->op2]; } else { new_insn->op2 = insn->op2; } @@ -1257,6 +1409,8 @@ int ir_schedule(ir_ctx *ctx) switch (new_insn->op) { case IR_EQ: case IR_NE: + case IR_ORDERED: + case IR_UNORDERED: case IR_ADD: case IR_MUL: case IR_ADD_OV: @@ -1297,12 +1451,12 @@ int ir_schedule(ir_ctx *ctx) } /* Update list of terminators (IR_OPND_CONTROL_REF) */ - insn = &new_ctx.ir_base[1]; + insn = &base[1]; ref = insn->op1; if (ref) { insn->op1 = ref = _xlat[ref]; while (1) { - insn = &new_ctx.ir_base[ref]; + insn = &base[ref]; ref = insn->op3; if (!ref) { break; @@ -1311,35 +1465,33 @@ int ir_schedule(ir_ctx *ctx) } } - IR_ASSERT(ctx->use_edges_count >= use_edges_count); - new_ctx.use_edges_count = use_edges_count; - new_ctx.use_edges = ir_mem_realloc(new_ctx.use_edges, use_edges_count * sizeof(ir_ref)); - if (ctx->binding) { ir_xlat_binding(ctx, _xlat); - new_ctx.binding = ctx->binding; - ctx->binding = NULL; } _xlat -= ctx->consts_count; ir_mem_free(_xlat); + ir_mem_free(_next); - new_ctx.cfg_blocks_count = ctx->cfg_blocks_count; - new_ctx.cfg_edges_count = ctx->cfg_edges_count; - new_ctx.cfg_blocks = ctx->cfg_blocks; - new_ctx.cfg_edges = ctx->cfg_edges; - ctx->cfg_blocks = NULL; - ctx->cfg_edges = NULL; - ir_code_buffer *saved_code_buffer = ctx->code_buffer; - - ir_free(ctx); - IR_ASSERT(new_ctx.consts_count == new_ctx.consts_limit); - IR_ASSERT(new_ctx.insns_count == new_ctx.insns_limit); - memcpy(ctx, &new_ctx, sizeof(ir_ctx)); - ctx->code_buffer = saved_code_buffer; - ctx->flags2 |= IR_LINEAR; + /* Switch to new IR buffer */ + ir_mem_free(ctx->ir_base - ctx->consts_limit); + ctx->ir_base = base; + ctx->insns_count = ctx->insns_limit = insns_count; + ctx->consts_count = ctx->consts_limit = consts_count; - ir_mem_free(_next); + ir_mem_free(ctx->use_lists); + ir_mem_free(ctx->use_edges); + IR_ASSERT(orig_use_edges_count >= use_edges_count); + ctx->use_lists = lists; + ctx->use_edges = use_edges; + ctx->use_edges_count = use_edges_count; + + ir_mem_free(ctx->cfg_map); + ctx->cfg_map = map; + + ctx->prev_ref = _prev; + + ctx->flags2 |= IR_LINEAR; return 1; } diff --git a/ext/opcache/jit/ir/ir_gdb.c b/ext/opcache/jit/ir/ir_gdb.c index ecaf880301e6..41141bd28715 100644 --- a/ext/opcache/jit/ir/ir_gdb.c +++ b/ext/opcache/jit/ir/ir_gdb.c @@ -7,6 +7,10 @@ * Based on Mike Pall's implementation of GDB interface for LuaJIT. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include #include @@ -517,6 +521,8 @@ IR_NEVER_INLINE void __jit_debug_register_code(void) static bool ir_gdb_register_code(const void *object, size_t size) { ir_gdbjit_code_entry *entry; + ir_elf_header *elf_header; + ir_elf_sectheader *elf_section, *elf_section_end; entry = malloc(sizeof(ir_gdbjit_code_entry) + size); if (entry == NULL) { @@ -528,6 +534,17 @@ static bool ir_gdb_register_code(const void *object, size_t size) memcpy((char *)entry->symfile_addr, object, size); + elf_header = (ir_elf_header*)entry->symfile_addr; + elf_section = (ir_elf_sectheader*)(entry->symfile_addr + elf_header->shofs); + elf_section_end = (ir_elf_sectheader*)((char*)elf_section + (elf_header->shentsize * elf_header->shnum)); + + while (elf_section < elf_section_end) { + if ((elf_section->flags & ELFSECT_FLAGS_ALLOC) && elf_section->addr == 0) { + elf_section->addr = (uintptr_t)(entry->symfile_addr + elf_section->ofs); + } + elf_section = (ir_elf_sectheader*)((char*)elf_section + elf_header->shentsize); + } + entry->prev_entry = NULL; entry->next_entry = __jit_debug_descriptor.first_entry; diff --git a/ext/opcache/jit/ir/ir_perf.c b/ext/opcache/jit/ir/ir_perf.c index dbb689b091f2..c0561ff86ac1 100644 --- a/ext/opcache/jit/ir/ir_perf.c +++ b/ext/opcache/jit/ir/ir_perf.c @@ -14,6 +14,10 @@ * perf report -i perf.data.jitted */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include #include @@ -26,7 +30,7 @@ #if defined(__linux__) #include -#elif defined(__darwin__) +#elif defined(__APPLE__) # include #elif defined(__FreeBSD__) # include @@ -211,7 +215,7 @@ int ir_perf_jitdump_register(const char *name, const void *start, size_t size) uint32_t thread_id = 0; #if defined(__linux__) thread_id = syscall(SYS_gettid); -#elif defined(__darwin__) +#elif defined(__APPLE__) uint64_t thread_id_u64; pthread_threadid_np(NULL, &thread_id_u64); thread_id = (uint32_t) thread_id_u64; diff --git a/ext/opcache/jit/ir/ir_private.h b/ext/opcache/jit/ir/ir_private.h index 69a0101d24ee..3e1051ca3379 100644 --- a/ext/opcache/jit/ir/ir_private.h +++ b/ext/opcache/jit/ir/ir_private.h @@ -9,6 +9,7 @@ #define IR_PRIVATE_H #include #include +#include #ifdef IR_DEBUG # include @@ -62,7 +63,7 @@ #define IR_MAX(a, b) (((a) > (b)) ? (a) : (b)) #define IR_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define IR_IS_POWER_OF_TWO(x) (!((x) & ((x) - 1))) +#define IR_IS_POWER_OF_TWO(x) ((x) && (!((x) & ((x) - 1)))) #define IR_LOG2(x) ir_ntzl(x) @@ -237,6 +238,7 @@ IR_ALWAYS_INLINE ir_arena* ir_arena_create(size_t size) IR_ASSERT(size >= IR_ALIGNED_SIZE(sizeof(ir_arena), 8)); arena = (ir_arena*)ir_mem_malloc(size); + if (UNEXPECTED(!arena))return NULL; arena->ptr = (char*) arena + IR_ALIGNED_SIZE(sizeof(ir_arena), 8); arena->end = (char*) arena + size; arena->prev = NULL; @@ -257,7 +259,7 @@ IR_ALWAYS_INLINE void* ir_arena_alloc(ir_arena **arena_ptr, size_t size) ir_arena *arena = *arena_ptr; char *ptr = (char*)IR_ALIGNED_SIZE((uintptr_t)arena->ptr, 8); - if (EXPECTED(size <= (size_t)(arena->end - ptr))) { + if (EXPECTED((ptrdiff_t)size <= (ptrdiff_t)(arena->end - ptr))) { arena->ptr = ptr + size; } else { size_t arena_size = @@ -266,6 +268,7 @@ IR_ALWAYS_INLINE void* ir_arena_alloc(ir_arena **arena_ptr, size_t size) (size_t)(arena->end - (char*) arena); ir_arena *new_arena = (ir_arena*)ir_mem_malloc(arena_size); + if (UNEXPECTED(!new_arena)) return NULL; ptr = (char*) new_arena + IR_ALIGNED_SIZE(sizeof(ir_arena), 8); new_arena->ptr = (char*) new_arena + IR_ALIGNED_SIZE(sizeof(ir_arena), 8) + size; new_arena->end = (char*) new_arena + arena_size; @@ -884,7 +887,7 @@ void ir_print_escaped_str(const char *s, size_t len, FILE *f); #define IR_IS_CONST_OP(op) ((op) > IR_NOP && (op) <= IR_C_FLOAT) #define IR_IS_FOLDABLE_OP(op) ((op) <= IR_LAST_FOLDABLE_OP) -#define IR_IS_SYM_CONST(op) ((op) == IR_STR || (op) == IR_SYM || (op) == IR_FUNC) +#define IR_IS_SYM_CONST(op) ((op) == IR_STR || (op) == IR_SYM || (op) == IR_FUNC || (op) == IR_LABEL) ir_ref ir_const_ex(ir_ctx *ctx, ir_val val, uint8_t type, uint32_t optx); @@ -905,7 +908,7 @@ IR_ALWAYS_INLINE bool ir_const_is_true(const ir_insn *v) return 0; } -IR_ALWAYS_INLINE bool ir_ref_is_true(ir_ctx *ctx, ir_ref ref) +IR_ALWAYS_INLINE bool ir_ref_is_true(const ir_ctx *ctx, ir_ref ref) { if (ref == IR_TRUE) { return 1; @@ -943,12 +946,14 @@ IR_ALWAYS_INLINE bool ir_ref_is_true(ir_ctx *ctx, ir_ref ref) #define IR_OPND_UNUSED 0x0 #define IR_OPND_DATA 0x1 #define IR_OPND_CONTROL 0x2 -#define IR_OPND_CONTROL_DEP 0x3 -#define IR_OPND_CONTROL_REF 0x4 -#define IR_OPND_STR 0x5 -#define IR_OPND_NUM 0x6 -#define IR_OPND_PROB 0x7 -#define IR_OPND_PROTO 0x8 +#define IR_OPND_LABEL_REF 0x3 +#define IR_OPND_CONTROL_DEP 0x4 +#define IR_OPND_CONTROL_REF 0x5 +#define IR_OPND_CONTROL_GUARD 0x6 +#define IR_OPND_STR 0x7 +#define IR_OPND_NUM 0x8 +#define IR_OPND_PROB 0x9 +#define IR_OPND_PROTO 0xa #define IR_OP_FLAGS(op_flags, op1_flags, op2_flags, op3_flags) \ ((op_flags) | ((op1_flags) << 20) | ((op2_flags) << 24) | ((op3_flags) << 28)) @@ -962,7 +967,7 @@ IR_ALWAYS_INLINE bool ir_ref_is_true(ir_ctx *ctx, ir_ref ref) (((flags) >> (16 + (4 * (((i) > 3) ? 3 : (i))))) & 0xf) #define IR_IS_REF_OPND_KIND(kind) \ - ((kind) >= IR_OPND_DATA && (kind) <= IR_OPND_CONTROL_REF) + ((kind) >= IR_OPND_DATA && (kind) <= IR_OPND_CONTROL_GUARD) IR_ALWAYS_INLINE ir_ref ir_operands_count(const ir_ctx *ctx, const ir_insn *insn) { @@ -1010,6 +1015,9 @@ IR_ALWAYS_INLINE uint32_t ir_insn_len(const ir_insn *insn) #define IR_HAS_VA_ARG_FP (1<<9) #define IR_HAS_FP_RET_SLOT (1<<10) #define IR_16B_FRAME_ALIGNMENT (1<<11) +#define IR_HAS_BLOCK_ADDR (1<<12) +#define IR_PREALLOCATED_STACK (1<<13) + /* Temporary: MEM2SSA -> SCCP */ #define IR_MEM2SSA_VARS (1<<25) @@ -1040,7 +1048,6 @@ void ir_use_list_remove_one(ir_ctx *ctx, ir_ref def, ir_ref use); void ir_use_list_replace_all(ir_ctx *ctx, ir_ref def, ir_ref use, ir_ref new_use); void ir_use_list_replace_one(ir_ctx *ctx, ir_ref def, ir_ref use, ir_ref new_use); bool ir_use_list_add(ir_ctx *ctx, ir_ref def, ir_ref use); -void ir_use_list_sort(ir_ctx *ctx, ir_ref def); IR_ALWAYS_INLINE ir_ref ir_next_control(const ir_ctx *ctx, ir_ref ref) { @@ -1089,9 +1096,11 @@ void ir_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref); void ir_update_op(ir_ctx *ctx, ir_ref ref, uint32_t idx, ir_ref new_val); /*** Iterative Optimization ***/ +void ir_iter_add_uses(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist); void ir_iter_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bitqueue *worklist); void ir_iter_update_op(ir_ctx *ctx, ir_ref ref, uint32_t idx, ir_ref new_val, ir_bitqueue *worklist); void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist); +void ir_iter_cleanup(ir_ctx *ctx); /*** IR Basic Blocks info ***/ #define IR_IS_BB_START(op) \ @@ -1137,12 +1146,15 @@ struct _ir_block { }; union { uint32_t dom_depth; /* depth from the root of the dominators tree */ - uint32_t postnum; /* used temporary during tree constructon */ + uint32_t postnum; /* used temporary for iterative Post Ordering */ }; uint32_t dom_child; /* first dominated blocks */ uint32_t dom_next_child; /* next dominated block (linked list) */ uint32_t loop_header; - uint32_t loop_depth; + union { + uint32_t loop_depth; + uint32_t next_succ; /* used temporary for iterative Post Ordering */ + }; }; void ir_build_prev_refs(ir_ctx *ctx); @@ -1172,16 +1184,17 @@ typedef enum _ir_fold_action { IR_FOLD_DO_CONST } ir_fold_action; -ir_ref ir_folding(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3, ir_insn *op1_insn, ir_insn *op2_insn, ir_insn *op3_insn); +ir_ref ir_folding(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3, + const ir_insn *op1_insn, const ir_insn *op2_insn, const ir_insn *op3_insn); /*** Alias Analyzes (see ir.c) ***/ -ir_ref ir_find_aliasing_load(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref addr); -ir_ref ir_find_aliasing_vload(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref var); +ir_ref ir_find_aliasing_load(const ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref addr); +ir_ref ir_find_aliasing_vload(const ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref var); ir_ref ir_find_aliasing_store(ir_ctx *ctx, ir_ref ref, ir_ref addr, ir_ref val); ir_ref ir_find_aliasing_vstore(ir_ctx *ctx, ir_ref ref, ir_ref addr, ir_ref val); /*** Predicates (see ir.c) ***/ -ir_ref ir_check_dominating_predicates(ir_ctx *ctx, ir_ref ref, ir_ref condition); +ir_ref ir_check_dominating_predicates(const ir_ctx *ctx, ir_ref ref, ir_ref condition); /*** IR Live Info ***/ typedef ir_ref ir_live_pos; @@ -1211,6 +1224,7 @@ typedef struct _ir_use_pos ir_use_pos; #define IR_USE_SHOULD_BE_IN_REG (1<<1) #define IR_DEF_REUSES_OP1_REG (1<<2) #define IR_DEF_CONFLICTS_WITH_INPUT_REGS (1<<3) +#define IR_EXTEND_INPUTS_TO_NEXT (1<<4) /* used for SNAPSHOT followed by GUARD */ #define IR_FUSED_USE (1<<6) #define IR_PHI_USE (1<<7) @@ -1245,11 +1259,10 @@ struct _ir_live_range { #define IR_LIVE_INTERVAL_HAS_HINT_REGS (1<<2) #define IR_LIVE_INTERVAL_HAS_HINT_REFS (1<<3) #define IR_LIVE_INTERVAL_MEM_PARAM (1<<4) -#define IR_LIVE_INTERVAL_MEM_LOAD (1<<5) -#define IR_LIVE_INTERVAL_COALESCED (1<<6) -#define IR_LIVE_INTERVAL_SPILL_SPECIAL (1<<7) /* spill slot is pre-allocated in a special area (see ir_ctx.spill_reserved_base) */ -#define IR_LIVE_INTERVAL_SPILLED (1<<8) -#define IR_LIVE_INTERVAL_SPLIT_CHILD (1<<9) +#define IR_LIVE_INTERVAL_COALESCED (1<<5) +#define IR_LIVE_INTERVAL_SPILL_SPECIAL (1<<6) /* spill slot is pre-allocated in a special area (see ir_ctx.spill_reserved_base) */ +#define IR_LIVE_INTERVAL_SPILLED (1<<7) +#define IR_LIVE_INTERVAL_SPLIT_CHILD (1<<8) struct _ir_live_interval { uint8_t type; @@ -1271,9 +1284,9 @@ struct _ir_live_interval { ir_live_interval *list_next; /* linked list of active, inactive or unhandled intervals */ }; -typedef int (*emit_copy_t)(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to); +typedef int (*emit_copy_t)(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to, void *data); -int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy); +int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy, void *data); #if defined(IR_REGSET_64BIT) @@ -1359,16 +1372,44 @@ IR_ALWAYS_INLINE ir_reg ir_regset_pop_first(ir_regset *set) #endif /* defined(IR_REGSET_64BIT) */ +/*** Calling Conventions ***/ +#if defined(IR_REGSET_64BIT) +struct _ir_call_conv_dsc { + bool cleanup_stack_by_callee: 1; /* use "retn $size" to return */ + bool pass_struct_by_val: 1; /* pass aggreagate by value, otherwise their copies are passed by ref */ + bool sysv_varargs: 1; /* Use SysV varargs ABI */ + bool shadow_param_regs: 1; /* registers for INT and FP parametrs shadow each other */ + /* (WIN64: 1-st arg is passed in %rcx/%xmm0, 2-nd in %rdx/%xmm1) */ + uint8_t shadow_store_size; /* reserved stack space to keep arguemnts passed in registers (WIN64) */ + uint8_t int_param_regs_count; /* number of registers for INT parameters */ + uint8_t fp_param_regs_count; /* number of registers for FP parameters */ + int8_t int_ret_reg; /* register to return INT value */ + int8_t fp_ret_reg; /* register to return FP value */ + int8_t fp_varargs_reg; /* register to pass number of fp register arguments into vararg func */ + int8_t scratch_reg; /* pseudo register to reffer srcatch regset (clobbered by call) */ + const int8_t *int_param_regs; /* registers for INT parameters */ + const int8_t *fp_param_regs; /* registers for FP parameters */ + ir_regset preserved_regs; /* preserved or callee-saved registers */ +}; + +extern const ir_regset ir_scratch_regset[]; +#endif + +typedef struct _ir_call_conv_dsc ir_call_conv_dsc; + +const ir_call_conv_dsc *ir_get_call_conv_dsc(uint32_t flags); + /*** IR Register Allocation ***/ /* Flags for ctx->regs[][] (low bits are used for register number itself) */ typedef struct _ir_reg_alloc_data { + const ir_call_conv_dsc *cc; int32_t unused_slot_4; int32_t unused_slot_2; int32_t unused_slot_1; ir_live_interval **handled; } ir_reg_alloc_data; -int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type, ir_reg_alloc_data *data); +int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type); IR_ALWAYS_INLINE void ir_set_alocated_reg(ir_ctx *ctx, ir_ref ref, int op_num, int8_t reg) { @@ -1402,9 +1443,27 @@ IR_ALWAYS_INLINE int8_t ir_get_alocated_reg(const ir_ctx *ctx, ir_ref ref, int o #define IR_RULE_MASK 0xff +#define IR_MAX_REG_ARGS 64 + extern const char *ir_rule_name[]; -typedef struct _ir_target_constraints ir_target_constraints; +typedef struct _ir_tmp_reg { + union { + uint8_t num; + int8_t reg; + }; + uint8_t type; + int8_t start; + int8_t end; +} ir_tmp_reg; + +typedef struct { + int8_t def_reg; + uint8_t tmps_count; + uint8_t hints_count; + ir_tmp_reg tmp_regs[3]; + int8_t hints[IR_MAX_REG_ARGS + 3]; +} ir_target_constraints; #define IR_TMP_REG(_num, _type, _start, _end) \ (ir_tmp_reg){.num=(_num), .type=(_type), .start=(_start), .end=(_end)} @@ -1416,9 +1475,7 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co void ir_fix_stack_frame(ir_ctx *ctx); /* Utility */ -ir_type ir_get_return_type(ir_ctx *ctx); -bool ir_is_fastcall(const ir_ctx *ctx, const ir_insn *insn); -bool ir_is_vararg(const ir_ctx *ctx, ir_insn *insn); +const ir_proto_t *ir_call_proto(const ir_ctx *ctx, const ir_insn *insn); //#define IR_BITSET_LIVENESS diff --git a/ext/opcache/jit/ir/ir_ra.c b/ext/opcache/jit/ir/ir_ra.c index 0c0e8dec3b47..f22e06083786 100644 --- a/ext/opcache/jit/ir/ir_ra.c +++ b/ext/opcache/jit/ir/ir_ra.c @@ -610,8 +610,8 @@ int ir_compute_live_ranges(ir_ctx *ctx) len = ir_bitset_len(ctx->vregs_count + 1); bb_live = ir_mem_malloc((ctx->cfg_blocks_count + 1) * len * sizeof(ir_bitset_base_t)); - /* vregs + tmp + fixed + SRATCH + ALL */ - ctx->live_intervals = ir_mem_calloc(ctx->vregs_count + 1 + IR_REG_NUM + 2, sizeof(ir_live_interval*)); + /* vregs + tmp + fixed + ALL + SCRATCH_N */ + ctx->live_intervals = ir_mem_calloc(ctx->vregs_count + 1 + IR_REG_SET_NUM, sizeof(ir_live_interval*)); #ifdef IR_DEBUG visited = ir_bitset_malloc(ctx->cfg_blocks_count + 1); @@ -776,9 +776,6 @@ int ir_compute_live_ranges(ir_ctx *ctx) if (insn->op == IR_PARAM) { /* We may reuse parameter stack slot for spilling */ ctx->live_intervals[v]->flags |= IR_LIVE_INTERVAL_MEM_PARAM; - } else if (insn->op == IR_VLOAD) { - /* Load may be fused into the usage instruction */ - ctx->live_intervals[v]->flags |= IR_LIVE_INTERVAL_MEM_LOAD; } def_pos = IR_DEF_LIVE_POS_FROM_REF(ref); } @@ -802,6 +799,34 @@ int ir_compute_live_ranges(ir_ctx *ctx) ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), IR_REG_NONE, IR_USE_SHOULD_BE_IN_REG, 0); continue; } + } else if (def_flags & IR_EXTEND_INPUTS_TO_NEXT) { + ir_ref next = ir_next_control(ctx, ref); + ir_live_pos use_pos; + + IR_ASSERT(insn->op == IR_SNAPSHOT); + j = 2; + p = insn->ops + 2; + for (; j <= insn->inputs_count; j++, p++) { + ir_ref input = *p; + uint32_t v; + + if (input > 0) { + v = ctx->vregs[input]; + IR_ASSERT(v); + use_pos = IR_USE_LIVE_POS_FROM_REF(next); + if (!ir_bitset_in(live, v)) { + /* live.add(opd) */ + ir_bitset_incl(live, v); + /* intervals[opd].addRange(b.from, op.id) */ + ival = ir_add_live_range(ctx, v, IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); + } else { + ival = ctx->live_intervals[v]; + } + use_pos = IR_USE_LIVE_POS_FROM_REF(ref); + ir_add_use(ctx, ival, j, use_pos, IR_REG_NONE, 0, IR_UNUSED); + } + } + continue; } IR_ASSERT(insn->op != IR_PHI && (!ctx->rules || !(ctx->rules[ref] & (IR_FUSED|IR_SKIPPED)))); @@ -845,11 +870,17 @@ int ir_compute_live_ranges(ir_ctx *ctx) ival = ctx->live_intervals[v]; } ir_add_use(ctx, ival, j, use_pos, reg, IR_USE_FLAGS(def_flags, j), hint_ref); - } else if (ctx->rules) { - if (ctx->rules[input] & IR_FUSED) { - ir_add_fusion_ranges(ctx, ref, input, bb, live); - } else if (ctx->rules[input] == (IR_SKIPPED|IR_RLOAD)) { - ir_set_alocated_reg(ctx, ref, j, ctx->ir_base[input].op2); + } else { + if (ctx->rules) { + if ((ctx->rules[input] & (IR_FUSED|IR_SKIPPED)) == IR_FUSED) { + ir_add_fusion_ranges(ctx, ref, input, bb, live); + } else if (ctx->rules[input] == (IR_SKIPPED|IR_RLOAD)) { + ir_set_alocated_reg(ctx, ref, j, ctx->ir_base[input].op2); + } + } + if (reg != IR_REG_NONE) { + use_pos = IR_LOAD_LIVE_POS_FROM_REF(ref); + ir_add_fixed_live_range(ctx, reg, use_pos, use_pos + IR_USE_SUB_REF); } } } else if (reg != IR_REG_NONE) { @@ -1193,7 +1224,7 @@ static void ir_add_fusion_ranges(ir_ctx *ctx, ir_ref ref, ir_ref input, ir_block n = IR_INPUT_EDGES_COUNT(flags); j = 1; p = insn->ops + j; - if (flags & IR_OP_FLAG_CONTROL) { + if (flags & (IR_OP_FLAG_CONTROL|IR_OP_FLAG_PINNED)) { j++; p++; } @@ -1262,8 +1293,8 @@ int ir_compute_live_ranges(ir_ctx *ctx) /* Compute Live Ranges */ ctx->flags2 &= ~IR_LR_HAVE_DESSA_MOVES; - /* vregs + tmp + fixed + SRATCH + ALL */ - ctx->live_intervals = ir_mem_calloc(ctx->vregs_count + 1 + IR_REG_NUM + 2, sizeof(ir_live_interval*)); + /* vregs + tmp + fixed + ALL + SCRATCH_N */ + ctx->live_intervals = ir_mem_calloc(ctx->vregs_count + 1 + IR_REG_SET_NUM, sizeof(ir_live_interval*)); if (!ctx->arena) { ctx->arena = ir_arena_create(16 * 1024); @@ -1340,7 +1371,7 @@ int ir_compute_live_ranges(ir_ctx *ctx) || (ctx->rules[ref] & IR_RULE_MASK) == IR_ALLOCA) && ctx->use_lists[ref].count > 0) { insn = &ctx->ir_base[ref]; - if (insn->op != IR_VADDR) { + if (insn->op != IR_VADDR && insn->op != IR_PARAM) { insn->op3 = ctx->vars; ctx->vars = ref; } @@ -1396,9 +1427,6 @@ int ir_compute_live_ranges(ir_ctx *ctx) if (insn->op == IR_PARAM) { /* We may reuse parameter stack slot for spilling */ ctx->live_intervals[v]->flags |= IR_LIVE_INTERVAL_MEM_PARAM; - } else if (insn->op == IR_VLOAD) { - /* Load may be fused into the usage instruction */ - ctx->live_intervals[v]->flags |= IR_LIVE_INTERVAL_MEM_LOAD; } def_pos = IR_DEF_LIVE_POS_FROM_REF(ref); } @@ -1418,6 +1446,34 @@ int ir_compute_live_ranges(ir_ctx *ctx) ir_add_use(ctx, ival, 0, IR_DEF_LIVE_POS_FROM_REF(ref), IR_REG_NONE, IR_USE_SHOULD_BE_IN_REG, 0); continue; } + } else if (def_flags & IR_EXTEND_INPUTS_TO_NEXT) { + ir_ref next = ir_next_control(ctx, ref); + ir_live_pos use_pos; + + IR_ASSERT(insn->op == IR_SNAPSHOT); + j = 2; + p = insn->ops + 2; + for (; j <= insn->inputs_count; j++, p++) { + ir_ref input = *p; + uint32_t v; + + if (input > 0) { + v = ctx->vregs[input]; + IR_ASSERT(v); + use_pos = IR_USE_LIVE_POS_FROM_REF(next); + if (!IS_LIVE_IN_BLOCK(v, b)) { + /* live.add(opd) */ + SET_LIVE_IN_BLOCK(v, b); + /* intervals[opd].addRange(b.from, op.id) */ + ival = ir_add_live_range(ctx, v, IR_START_LIVE_POS_FROM_REF(bb->start), use_pos); + } else { + ival = ctx->live_intervals[v]; + } + use_pos = IR_USE_LIVE_POS_FROM_REF(ref); + ir_add_use(ctx, ival, j, use_pos, IR_REG_NONE, 0, IR_UNUSED); + } + } + continue; } IR_ASSERT(insn->op != IR_PHI && (!ctx->rules || !(ctx->rules[ref] & (IR_FUSED|IR_SKIPPED)))); @@ -1465,17 +1521,17 @@ int ir_compute_live_ranges(ir_ctx *ctx) ival = ctx->live_intervals[v]; } ir_add_use(ctx, ival, j, use_pos, reg, IR_USE_FLAGS(def_flags, j), hint_ref); - } else if (ctx->rules) { - if (ctx->rules[input] & IR_FUSED) { - ir_add_fusion_ranges(ctx, ref, input, bb, live_in_block, b); - } else { - if (ctx->rules[input] == (IR_SKIPPED|IR_RLOAD)) { + } else { + if (ctx->rules) { + if ((ctx->rules[input] & (IR_FUSED|IR_SKIPPED)) == IR_FUSED) { + ir_add_fusion_ranges(ctx, ref, input, bb, live_in_block, b); + } else if (ctx->rules[input] == (IR_SKIPPED|IR_RLOAD)) { ir_set_alocated_reg(ctx, ref, j, ctx->ir_base[input].op2); } - if (reg != IR_REG_NONE) { - use_pos = IR_LOAD_LIVE_POS_FROM_REF(ref); - ir_add_fixed_live_range(ctx, reg, use_pos, use_pos + IR_USE_SUB_REF); - } + } + if (reg != IR_REG_NONE) { + use_pos = IR_LOAD_LIVE_POS_FROM_REF(ref); + ir_add_fixed_live_range(ctx, reg, use_pos, use_pos + IR_USE_SUB_REF); } } } else if (reg != IR_REG_NONE) { @@ -1605,7 +1661,7 @@ static void ir_vregs_join(ir_ctx *ctx, uint32_t r1, uint32_t r2) } while (*prev && ((*prev)->pos < use_pos->pos || ((*prev)->pos == use_pos->pos && - (use_pos->op_num == 0 || (*prev)->op_num < use_pos->op_num)))) { + (use_pos->op_num == 0 || ((*prev)->op_num != 0 && (*prev)->op_num < use_pos->op_num))))) { if ((*prev)->hint_ref > 0 && ctx->vregs[(*prev)->hint_ref] == r2) { (*prev)->hint_ref = 0; } @@ -1627,8 +1683,9 @@ static void ir_vregs_join(ir_ctx *ctx, uint32_t r1, uint32_t r2) ctx->live_intervals[r1]->flags |= IR_LIVE_INTERVAL_COALESCED | (ival->flags & (IR_LIVE_INTERVAL_HAS_HINT_REGS|IR_LIVE_INTERVAL_HAS_HINT_REFS)); - if (ctx->ir_base[IR_LIVE_POS_TO_REF(ctx->live_intervals[r1]->use_pos->pos)].op != IR_VLOAD) { - ctx->live_intervals[r1]->flags &= ~IR_LIVE_INTERVAL_MEM_LOAD; + if (ival->flags & IR_LIVE_INTERVAL_MEM_PARAM) { + IR_ASSERT(!(ctx->live_intervals[r1]->flags & IR_LIVE_INTERVAL_MEM_PARAM)); + ctx->live_intervals[r1]->flags |= IR_LIVE_INTERVAL_MEM_PARAM; } ctx->live_intervals[r2] = NULL; @@ -2036,8 +2093,8 @@ int ir_coalesce(ir_ctx *ctx) n--; if (n != ctx->vregs_count) { j = ctx->vregs_count - n; - /* vregs + tmp + fixed + SRATCH + ALL */ - for (i = n + 1; i <= n + IR_REG_NUM + 2; i++) { + /* vregs + tmp + fixed + ALL + SCRATCH_N */ + for (i = n + 1; i <= n + IR_REG_SET_NUM; i++) { ctx->live_intervals[i] = ctx->live_intervals[i + j]; if (ctx->live_intervals[i]) { ctx->live_intervals[i]->vreg = i; @@ -2104,7 +2161,7 @@ int ir_compute_dessa_moves(ir_ctx *ctx) * 2009 International Symposium on Code Generation and Optimization, Seattle, WA, USA, 2009, * pp. 114-125, doi: 10.1109/CGO.2009.19. */ -int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) +int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy, void *data) { uint32_t succ, k, n = 0; ir_block *bb, *succ_bb; @@ -2179,7 +2236,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) while ((b = ir_bitset_pop_first(ready, len)) >= 0) { a = pred[b]; c = loc[a]; - emit_copy(ctx, ctx->ir_base[dst[b]].type, src[c], dst[b]); + emit_copy(ctx, ctx->ir_base[dst[b]].type, src[c], dst[b], data); ir_bitset_excl(todo, b); loc[a] = b; src[b] = dst[b]; @@ -2192,7 +2249,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) break; } IR_ASSERT(b != loc[pred[b]]); - emit_copy(ctx, ctx->ir_base[src[b]].type, src[b], 0); + emit_copy(ctx, ctx->ir_base[src[b]].type, src[b], 0, data); loc[b] = 0; ir_bitset_incl(ready, b); } @@ -2210,7 +2267,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) if (insn->op == IR_PHI) { input = ir_insn_op(insn, k); if (IR_IS_CONST_REF(input) || !ctx->vregs[input]) { - emit_copy(ctx, insn->type, input, ref); + emit_copy(ctx, insn->type, input, ref, data); } } } @@ -2339,16 +2396,6 @@ static ir_live_pos ir_first_use_pos_after(ir_live_interval *ival, ir_live_pos po return p ? p->pos : 0x7fffffff; } -static ir_live_pos ir_first_use_pos(ir_live_interval *ival, uint8_t flags) -{ - ir_use_pos *p = ival->use_pos; - - while (p && !(p->flags & flags)) { - p = p->next; - } - return p ? p->pos : 0x7fffffff; -} - static ir_block *ir_block_from_live_pos(ir_ctx *ctx, ir_live_pos pos) { ir_ref ref = IR_LIVE_POS_TO_REF(pos); @@ -2510,8 +2557,9 @@ static ir_live_interval *ir_split_interval_at(ir_ctx *ctx, ir_live_interval *iva return child; } -static int32_t ir_allocate_small_spill_slot(ir_ctx *ctx, size_t size, ir_reg_alloc_data *data) +static int32_t ir_allocate_small_spill_slot(ir_ctx *ctx, size_t size) { + ir_reg_alloc_data *data = ctx->data; int32_t ret; IR_ASSERT(size == 0 || size == 1 || size == 2 || size == 4 || size == 8); @@ -2610,12 +2658,12 @@ static int32_t ir_allocate_small_spill_slot(ir_ctx *ctx, size_t size, ir_reg_all return ret; } -int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type, ir_reg_alloc_data *data) +int32_t ir_allocate_spill_slot(ir_ctx *ctx, ir_type type) { - return ir_allocate_small_spill_slot(ctx, ir_type_size[type], data); + return ir_allocate_small_spill_slot(ctx, ir_type_size[type]); } -static int32_t ir_allocate_big_spill_slot(ir_ctx *ctx, int32_t size, ir_reg_alloc_data *data) +static int32_t ir_allocate_big_spill_slot(ir_ctx *ctx, int32_t size) { int32_t ret; @@ -2625,7 +2673,7 @@ static int32_t ir_allocate_big_spill_slot(ir_ctx *ctx, int32_t size, ir_reg_allo } else if (size > 4 && size < 8) { size = 8; } - return ir_allocate_small_spill_slot(ctx, size, data); + return ir_allocate_small_spill_slot(ctx, size); } /* Align stack allocated data to 16 byte */ @@ -2845,13 +2893,8 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l /* freeUntilPos[it.reg] = 0 */ reg = other->reg; IR_ASSERT(reg >= 0); - if (reg >= IR_REG_SCRATCH) { - if (reg == IR_REG_SCRATCH) { - available = IR_REGSET_DIFFERENCE(available, IR_REGSET_SCRATCH); - } else { - IR_ASSERT(reg == IR_REG_ALL); - available = IR_REGSET_EMPTY; - } + if (reg >= IR_REG_NUM) { + available = IR_REGSET_DIFFERENCE(available, ir_scratch_regset[reg - IR_REG_NUM]); } else { IR_REGSET_EXCL(available, reg); } @@ -2873,15 +2916,8 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l if (next) { reg = other->reg; IR_ASSERT(reg >= 0); - if (reg >= IR_REG_SCRATCH) { - ir_regset regset; - - if (reg == IR_REG_SCRATCH) { - regset = IR_REGSET_INTERSECTION(available, IR_REGSET_SCRATCH); - } else { - IR_ASSERT(reg == IR_REG_ALL); - regset = available; - } + if (reg >= IR_REG_NUM) { + ir_regset regset = IR_REGSET_INTERSECTION(available, ir_scratch_regset[reg - IR_REG_NUM]); overlapped = IR_REGSET_UNION(overlapped, regset); IR_REGSET_FOREACH(regset, reg) { if (next < freeUntilPos[reg]) { @@ -2931,7 +2967,8 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l } /* prefer caller-saved registers to avoid save/restore in prologue/epilogue */ - scratch = IR_REGSET_INTERSECTION(available, IR_REGSET_SCRATCH); + scratch = IR_REGSET_INTERSECTION(available, + ir_scratch_regset[((ir_reg_alloc_data*)(ctx->data))->cc->scratch_reg - IR_REG_NUM]); if (scratch != IR_REGSET_EMPTY) { /* prefer registers that don't conflict with the hints for the following unhandled intervals */ if (1) { @@ -2979,8 +3016,8 @@ static ir_reg ir_try_allocate_free_reg(ir_ctx *ctx, ir_live_interval *ival, ir_l pos = freeUntilPos[i]; reg = i; } else if (freeUntilPos[i] == pos - && !IR_REGSET_IN(IR_REGSET_SCRATCH, reg) - && IR_REGSET_IN(IR_REGSET_SCRATCH, i)) { + && !IR_REGSET_IN(ir_scratch_regset[((ir_reg_alloc_data*)(ctx->data))->cc->scratch_reg - IR_REG_NUM], reg) + && IR_REGSET_IN(ir_scratch_regset[((ir_reg_alloc_data*)(ctx->data))->cc->scratch_reg - IR_REG_NUM], i)) { /* prefer caller-saved registers to avoid save/restore in prologue/epilogue */ pos = freeUntilPos[i]; reg = i; @@ -3023,6 +3060,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li { ir_live_pos nextUsePos[IR_REG_NUM]; ir_live_pos blockPos[IR_REG_NUM]; + int score, best_score, scores[IR_REG_NUM]; int i, reg; ir_live_pos pos, next_use_pos; ir_live_interval *other, *prev; @@ -3051,6 +3089,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li for (i = IR_REG_FP_FIRST; i <= IR_REG_FP_LAST; i++) { nextUsePos[i] = 0x7fffffff; blockPos[i] = 0x7fffffff; + scores[i] = 0; } } else { available = IR_REGSET_GP; @@ -3069,6 +3108,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li for (i = IR_REG_GP_FIRST; i <= IR_REG_GP_LAST; i++) { nextUsePos[i] = 0x7fffffff; blockPos[i] = 0x7fffffff; + scores[i] = 0; } } @@ -3086,15 +3126,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li /* nextUsePos[it.reg] = next use of it after start of current */ reg = other->reg; IR_ASSERT(reg >= 0); - if (reg >= IR_REG_SCRATCH) { - ir_regset regset; - - if (reg == IR_REG_SCRATCH) { - regset = IR_REGSET_INTERSECTION(available, IR_REGSET_SCRATCH); - } else { - IR_ASSERT(reg == IR_REG_ALL); - regset = available; - } + if (reg >= IR_REG_NUM) { + ir_regset regset = IR_REGSET_INTERSECTION(available, ir_scratch_regset[reg - IR_REG_NUM]); IR_REGSET_FOREACH(regset, reg) { blockPos[reg] = nextUsePos[reg] = 0; } IR_REGSET_FOREACH_END(); @@ -3106,6 +3139,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG); if (pos < nextUsePos[reg]) { nextUsePos[reg] = pos; + /* Prefer splitting interval that was already splitted before */ + scores[reg] = (other->flags & IR_LIVE_INTERVAL_SPLIT_CHILD) ? 1 : 0; } } } @@ -3118,21 +3153,15 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li /* freeUntilPos[it.reg] = next intersection of it with current */ reg = other->reg; IR_ASSERT(reg >= 0); - if (reg >= IR_REG_SCRATCH) { + if (reg >= IR_REG_NUM) { ir_live_pos overlap = ir_ivals_overlap(&ival->range, other->current_range); if (overlap) { - ir_regset regset; - - if (reg == IR_REG_SCRATCH) { - regset = IR_REGSET_INTERSECTION(available, IR_REGSET_SCRATCH); - } else { - IR_ASSERT(reg == IR_REG_ALL); - regset = available; - } + ir_regset regset = IR_REGSET_INTERSECTION(available, ir_scratch_regset[reg - IR_REG_NUM]); IR_REGSET_FOREACH(regset, reg) { if (overlap < nextUsePos[reg]) { nextUsePos[reg] = overlap; + scores[reg] = 0; } if (overlap < blockPos[reg]) { blockPos[reg] = overlap; @@ -3146,6 +3175,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li if (other->flags & (IR_LIVE_INTERVAL_FIXED|IR_LIVE_INTERVAL_TEMP)) { if (overlap < nextUsePos[reg]) { nextUsePos[reg] = overlap; + scores[reg] = 0; } if (overlap < blockPos[reg]) { blockPos[reg] = overlap; @@ -3155,6 +3185,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG); if (pos < nextUsePos[reg]) { nextUsePos[reg] = pos; + /* Prefer splitting interval that was already splitted before */ + scores[reg] = (other->flags & IR_LIVE_INTERVAL_SPLIT_CHILD) ? 1 : 0; } } } @@ -3174,12 +3206,17 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li /* reg = register with highest nextUsePos */ pos = nextUsePos[reg]; + best_score = (scores[reg] << 28) + nextUsePos[reg]; tmp_regset = available; IR_REGSET_EXCL(tmp_regset, reg); IR_REGSET_FOREACH(tmp_regset, i) { if (nextUsePos[i] > pos) { pos = nextUsePos[i]; + } + score = (scores[i] << 28) + nextUsePos[i]; + if (score > best_score) { reg = i; + best_score = score; } } IR_REGSET_FOREACH_END(); @@ -3190,7 +3227,6 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li /* split current before its first use position that requires a register */ ir_live_pos split_pos; -spill_current: if (next_use_pos == ival->range.start) { IR_ASSERT(ival->use_pos && ival->use_pos->op_num == 0); /* split right after definition */ @@ -3257,48 +3293,33 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li IR_LOG_LSRA_CONFLICT(" ---- Conflict with active", other, overlap); split_pos = ir_last_use_pos_before(other, ival->range.start, IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG); - if (split_pos == 0) { - split_pos = ival->range.start; - } - split_pos = ir_find_optimal_split_position(ctx, other, split_pos, ival->range.start, 1); - if (split_pos > other->range.start) { - child = ir_split_interval_at(ctx, other, split_pos); - if (prev) { - prev->list_next = other->list_next; - } else { - *active = other->list_next; - } - IR_LOG_LSRA(" ---- Finish", other, ""); - } else { - if (ir_first_use_pos(other, IR_USE_MUST_BE_IN_REG) <= other->end) { - if (!(ival->flags & IR_LIVE_INTERVAL_TEMP)) { - next_use_pos = ir_first_use_pos(ival, IR_USE_MUST_BE_IN_REG); - if (next_use_pos == ival->range.start) { - IR_ASSERT(ival->use_pos && ival->use_pos->op_num == 0); - /* split right after definition */ - split_pos = next_use_pos + 1; - } else { - split_pos = ir_find_optimal_split_position(ctx, ival, ival->range.start, next_use_pos - 1, 1); - } - - if (split_pos > ival->range.start) { - goto spill_current; - } + if (split_pos) { + split_pos = ir_find_optimal_split_position(ctx, other, split_pos, ival->range.start, 1); + if (split_pos > other->range.start) { + child = ir_split_interval_at(ctx, other, split_pos); + if (prev) { + prev->list_next = other->list_next; + } else { + *active = other->list_next; } + IR_LOG_LSRA(" ---- Finish", other, ""); + } else { goto try_next_available_register; } + } else { child = other; - other->reg = IR_REG_NONE; - if (prev) { - prev->list_next = other->list_next; - } else { - *active = other->list_next; - } - IR_LOG_LSRA(" ---- Spill and Finish", other, " (it must not be in reg)"); } split_pos = ir_first_use_pos_after(child, ival->range.start, IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG) - 1; // TODO: ??? if (split_pos > child->range.start && split_pos < child->end) { + if (child == other) { + other->reg = IR_REG_NONE; + if (prev) { + prev->list_next = other->list_next; + } else { + *active = other->list_next; + } + } ir_live_pos opt_split_pos = ir_find_optimal_split_position(ctx, child, ival->range.start, split_pos, 1); if (opt_split_pos > child->range.start) { split_pos = opt_split_pos; @@ -3311,6 +3332,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li // TODO: this may cause endless loop ir_add_to_unhandled(unhandled, child); IR_LOG_LSRA(" ---- Queue", child, ""); + } else { + goto try_next_available_register; } } break; @@ -3353,9 +3376,9 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li return reg; } -static int ir_fix_dessa_tmps(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to) +static int ir_fix_dessa_tmps(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to, void *data) { - ir_block *bb = ctx->data; + ir_block *bb = data; ir_tmp_reg tmp_reg; if (to == 0) { @@ -3393,15 +3416,16 @@ static int ir_fix_dessa_tmps(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to) return 1; } -static bool ir_ival_spill_for_fuse_load(ir_ctx *ctx, ir_live_interval *ival, ir_reg_alloc_data *data) +static bool ir_ival_spill_for_fuse_load(ir_ctx *ctx, ir_live_interval *ival) { ir_use_pos *use_pos = ival->use_pos; - ir_insn *insn; if (ival->flags & IR_LIVE_INTERVAL_MEM_PARAM) { IR_ASSERT(!ival->next && use_pos && use_pos->op_num == 0); - insn = &ctx->ir_base[IR_LIVE_POS_TO_REF(use_pos->pos)]; +#if IR_DEBUG + ir_insn *insn = &ctx->ir_base[IR_LIVE_POS_TO_REF(use_pos->pos)]; IR_ASSERT(insn->op == IR_PARAM); +#endif use_pos = use_pos->next; if (use_pos && (use_pos->next || (use_pos->flags & IR_USE_MUST_BE_IN_REG))) { return 0; @@ -3414,38 +3438,6 @@ static bool ir_ival_spill_for_fuse_load(ir_ctx *ctx, ir_live_interval *ival, ir_ } } - return 1; - } else if (ival->flags & IR_LIVE_INTERVAL_MEM_LOAD) { - insn = &ctx->ir_base[IR_LIVE_POS_TO_REF(use_pos->pos)]; - IR_ASSERT(insn->op == IR_VLOAD); - IR_ASSERT(ctx->ir_base[insn->op2].op == IR_VAR); - use_pos = use_pos->next; - if (use_pos && (use_pos->next || (use_pos->flags & IR_USE_MUST_BE_IN_REG))) { - return 0; - } - - if (use_pos) { - ir_block *bb = ir_block_from_live_pos(ctx, use_pos->pos); - if (bb->loop_depth && bb != ir_block_from_live_pos(ctx, ival->use_pos->pos)) { - return 0; - } - /* check if VAR may be clobbered between VLOAD and use */ - ir_use_list *use_list = &ctx->use_lists[insn->op2]; - ir_ref n = use_list->count; - ir_ref *p = &ctx->use_edges[use_list->refs]; - for (; n > 0; p++, n--) { - ir_ref use = *p; - if (ctx->ir_base[use].op == IR_VSTORE) { - if (use > IR_LIVE_POS_TO_REF(ival->use_pos->pos) && use < IR_LIVE_POS_TO_REF(use_pos->pos)) { - return 0; - } - } else if (ctx->ir_base[use].op == IR_VADDR) { - return 0; - } - } - } - ival->stack_spill_pos = ctx->ir_base[insn->op2].op3; - return 1; } return 0; @@ -3476,7 +3468,7 @@ static void ir_assign_bound_spill_slots(ir_ctx *ctx) } } -static int ir_linear_scan(ir_ctx *ctx) +static int ir_linear_scan(ir_ctx *ctx, ir_ref vars) { uint32_t b; ir_block *bb; @@ -3487,8 +3479,6 @@ static int ir_linear_scan(ir_ctx *ctx) int j; ir_live_pos position; ir_reg reg; - ir_reg_alloc_data data; - ir_ref vars = ctx->vars; if (!ctx->live_intervals) { return 0; @@ -3499,19 +3489,11 @@ static int ir_linear_scan(ir_ctx *ctx) for (b = 1, bb = &ctx->cfg_blocks[1]; b <= ctx->cfg_blocks_count; b++, bb++) { IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); if (bb->flags & IR_BB_DESSA_MOVES) { - ctx->data = bb; - ir_gen_dessa_moves(ctx, b, ir_fix_dessa_tmps); + ir_gen_dessa_moves(ctx, b, ir_fix_dessa_tmps, bb); } } } - ctx->data = &data; - ctx->stack_frame_size = 0; - data.unused_slot_4 = 0; - data.unused_slot_2 = 0; - data.unused_slot_1 = 0; - data.handled = NULL; - while (vars) { ir_ref var = vars; ir_insn *insn = &ctx->ir_base[var]; @@ -3520,7 +3502,7 @@ static int ir_linear_scan(ir_ctx *ctx) vars = insn->op3; /* list next */ if (insn->op == IR_VAR) { - ir_ref slot = ir_allocate_spill_slot(ctx, insn->type, &data);; + ir_ref slot = ir_allocate_spill_slot(ctx, insn->type); ir_use_list *use_list; ir_ref n, *p; @@ -3543,15 +3525,15 @@ static int ir_linear_scan(ir_ctx *ctx) IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 >= 0); IR_ASSERT(val->val.i64 < 0x7fffffff); - insn->op3 = ir_allocate_big_spill_slot(ctx, val->val.i32, &data); + insn->op3 = ir_allocate_big_spill_slot(ctx, val->val.i32); } } for (j = ctx->vregs_count; j != 0; j--) { ival = ctx->live_intervals[j]; if (ival) { - if (!(ival->flags & (IR_LIVE_INTERVAL_MEM_PARAM|IR_LIVE_INTERVAL_MEM_LOAD)) - || !ir_ival_spill_for_fuse_load(ctx, ival, &data)) { + if (!(ival->flags & IR_LIVE_INTERVAL_MEM_PARAM) + || !ir_ival_spill_for_fuse_load(ctx, ival)) { ir_add_to_unhandled(&unhandled, ival); } } @@ -3562,8 +3544,8 @@ static int ir_linear_scan(ir_ctx *ctx) ir_merge_to_unhandled(&unhandled, ival); } - /* vregs + tmp + fixed + SRATCH + ALL */ - for (j = ctx->vregs_count + 1; j <= ctx->vregs_count + IR_REG_NUM + 2; j++) { + /* vregs + tmp + fixed + ALL + SCRATCH_N */ + for (j = ctx->vregs_count + 1; j <= ctx->vregs_count + IR_REG_SET_NUM; j++) { ival = ctx->live_intervals[j]; if (ival) { ival->current_range = &ival->range; @@ -3722,7 +3704,7 @@ static int ir_linear_scan(ir_ctx *ctx) ir_live_interval *handled[9] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; ir_live_interval *old; - data.handled = handled; + ((ir_reg_alloc_data*)(ctx->data))->handled = handled; active = NULL; while (unhandled) { ival = unhandled; @@ -3760,7 +3742,7 @@ static int ir_linear_scan(ir_ctx *ctx) other = prev ? prev->list_next : active; } - ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type, &data); + ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type); if (unhandled && ival->end > unhandled->range.start) { ival->list_next = active; active = ival; @@ -3780,15 +3762,16 @@ static int ir_linear_scan(ir_ctx *ctx) } } } - data.handled = NULL; + ((ir_reg_alloc_data*)(ctx->data))->handled = NULL; } } #ifdef IR_TARGET_X86 if (ctx->flags2 & IR_HAS_FP_RET_SLOT) { - ctx->ret_slot = ir_allocate_spill_slot(ctx, IR_DOUBLE, &data); - } else if (ctx->ret_type == IR_FLOAT || ctx->ret_type == IR_DOUBLE) { - ctx->ret_slot = ir_allocate_spill_slot(ctx, ctx->ret_type, &data); + ctx->ret_slot = ir_allocate_spill_slot(ctx, IR_DOUBLE); + } else if ((ctx->ret_type == IR_FLOAT || ctx->ret_type == IR_DOUBLE) + && ((ir_reg_alloc_data*)(ctx->data))->cc->fp_ret_reg == IR_REG_NONE) { + ctx->ret_slot = ir_allocate_spill_slot(ctx, ctx->ret_type); } else { ctx->ret_slot = -1; } @@ -3853,14 +3836,13 @@ static void ir_set_fused_reg(ir_ctx *ctx, ir_ref root, ir_ref ref_and_op, int8_t { char key[10]; - IR_ASSERT(reg != IR_REG_NONE); if (!ctx->fused_regs) { ctx->fused_regs = ir_mem_malloc(sizeof(ir_strtab)); ir_strtab_init(ctx->fused_regs, 8, 128); } memcpy(key, &root, sizeof(ir_ref)); memcpy(key + 4, &ref_and_op, sizeof(ir_ref)); - ir_strtab_lookup(ctx->fused_regs, key, 8, 0x10000000 | reg); + ir_strtab_lookup(ctx->fused_regs, key, 8, 0x10000000 | (uint8_t)reg); } static void assign_regs(ir_ctx *ctx) @@ -3966,93 +3948,88 @@ static void assign_regs(ir_ctx *ctx) } prev_use_ref = ref; } - } else if ((!prev_use_ref || ctx->cfg_map[prev_use_ref] != ctx->cfg_map[ref]) - && needs_spill_reload(ctx, ival, ctx->cfg_map[ref], available)) { - if (!(use_pos->flags & IR_USE_MUST_BE_IN_REG) - && use_pos->hint != reg -// && ctx->ir_base[ref].op != IR_CALL -// && ctx->ir_base[ref].op != IR_TAILCALL) { - && ctx->ir_base[ref].op != IR_SNAPSHOT - && !needs_spill_load(ctx, ival, use_pos)) { - /* fuse spill load (valid only when register is not reused) */ - reg = IR_REG_NONE; - if (use_pos->next - && use_pos->op_num == 1 - && use_pos->next->pos == use_pos->pos - && !(use_pos->next->flags & IR_USE_MUST_BE_IN_REG)) { - /* Support for R2 = BINOP(R1, R1) */ - if (use_pos->hint_ref < 0) { - ref = -use_pos->hint_ref; + } else { + if ((!prev_use_ref || ctx->cfg_map[prev_use_ref] != ctx->cfg_map[ref]) + && needs_spill_reload(ctx, ival, ctx->cfg_map[ref], available)) { + if (!(use_pos->flags & IR_USE_MUST_BE_IN_REG) + && use_pos->hint != reg +// && ctx->ir_base[ref].op != IR_CALL +// && ctx->ir_base[ref].op != IR_TAILCALL) { + && ctx->ir_base[ref].op != IR_SNAPSHOT + && !needs_spill_load(ctx, ival, use_pos)) { + /* fuse spill load (valid only when register is not reused) */ + reg = IR_REG_NONE; + if (use_pos->next + && use_pos->op_num == 1 + && use_pos->next->pos == use_pos->pos + && !(use_pos->next->flags & IR_USE_MUST_BE_IN_REG)) { + /* Support for R2 = BINOP(R1, R1) */ + if (use_pos->hint_ref < 0) { + ref = -use_pos->hint_ref; + } + ir_set_alocated_reg(ctx, ref, use_pos->op_num, reg); + use_pos = use_pos->next; } - ir_set_alocated_reg(ctx, ref, use_pos->op_num, reg); - use_pos = use_pos->next; - } - } else { - if (top_ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL) { - reg |= IR_REG_SPILL_SPECIAL; } else { - reg |= IR_REG_SPILL_LOAD; - } - if (ctx->ir_base[ref].op != IR_SNAPSHOT && !(use_pos->flags & IR_PHI_USE)) { - uint32_t use_b = ctx->cfg_map[ref]; + if (top_ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL) { + reg |= IR_REG_SPILL_SPECIAL; + } else { + reg |= IR_REG_SPILL_LOAD; + } + if (ctx->ir_base[ref].op != IR_SNAPSHOT && !(use_pos->flags & IR_PHI_USE)) { + uint32_t use_b = ctx->cfg_map[ref]; - if (ir_ival_covers(ival, IR_SAVE_LIVE_POS_FROM_REF(ctx->cfg_blocks[use_b].end))) { - ir_bitset_incl(available, use_b); + if (ir_ival_covers(ival, IR_SAVE_LIVE_POS_FROM_REF(ctx->cfg_blocks[use_b].end))) { + ir_bitset_incl(available, use_b); + } + prev_use_ref = ref; } - prev_use_ref = ref; } + } else { + /* reuse register without spill load */ } - if (use_pos->hint_ref < 0 - && (old_reg = ir_get_alocated_reg(ctx, -use_pos->hint_ref, use_pos->op_num)) != IR_REG_NONE) { - if (top_ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL) { - reg |= IR_REG_SPILL_SPECIAL; + + if (use_pos->hint_ref < 0) { + if (use_pos->flags & IR_PHI_USE) { + IR_ASSERT(use_pos->hint_ref < 0); + IR_ASSERT(ctx->vregs[-use_pos->hint_ref]); + IR_ASSERT(ctx->live_intervals[ctx->vregs[-use_pos->hint_ref]]); + if (ctx->live_intervals[ctx->vregs[-use_pos->hint_ref]]->flags & IR_LIVE_INTERVAL_SPILLED) { + /* Spilled PHI var is passed through memory */ + reg = IR_REG_NONE; + } } else { - reg |= IR_REG_SPILL_LOAD; - } - if (reg != old_reg) { IR_ASSERT(ctx->rules[-use_pos->hint_ref] & IR_FUSED); - ctx->rules[-use_pos->hint_ref] |= IR_FUSED_REG; - ir_set_fused_reg(ctx, ref, -use_pos->hint_ref * sizeof(ir_ref) + use_pos->op_num, reg); - use_pos = use_pos->next; - continue; + old_reg = ir_get_alocated_reg(ctx, -use_pos->hint_ref, use_pos->op_num); + if ((old_reg != IR_REG_NONE && reg != old_reg) || reg == IR_REG_NONE) { + ctx->rules[-use_pos->hint_ref] |= IR_FUSED_REG; + ir_set_fused_reg(ctx, ref, -use_pos->hint_ref * sizeof(ir_ref) + use_pos->op_num, reg); + use_pos = use_pos->next; + continue; + } } + ref = -use_pos->hint_ref; } - } else if (use_pos->flags & IR_PHI_USE) { - IR_ASSERT(use_pos->hint_ref < 0); - IR_ASSERT(ctx->vregs[-use_pos->hint_ref]); - IR_ASSERT(ctx->live_intervals[ctx->vregs[-use_pos->hint_ref]]); - if (ctx->live_intervals[ctx->vregs[-use_pos->hint_ref]]->flags & IR_LIVE_INTERVAL_SPILLED) { - /* Spilled PHI var is passed through memory */ - reg = IR_REG_NONE; - } - } else if (use_pos->hint_ref < 0 - && (old_reg = ir_get_alocated_reg(ctx, -use_pos->hint_ref, use_pos->op_num)) != IR_REG_NONE) { - if (reg != old_reg) { - IR_ASSERT(ctx->rules[-use_pos->hint_ref] & IR_FUSED); - ctx->rules[-use_pos->hint_ref] |= IR_FUSED_REG; - ir_set_fused_reg(ctx, ref, -use_pos->hint_ref * sizeof(ir_ref) + use_pos->op_num, reg); - use_pos = use_pos->next; - continue; - } - } else { - /* reuse register without spill load */ - } - if (use_pos->hint_ref < 0) { - ref = -use_pos->hint_ref; } + ir_set_alocated_reg(ctx, ref, use_pos->op_num, reg); use_pos = use_pos->next; } - } else if (!(top_ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL)) { + } else { use_pos = ival->use_pos; while (use_pos) { ref = IR_LIVE_POS_TO_REF(use_pos->pos); - if (ctx->ir_base[ref].op == IR_SNAPSHOT) { + if (ctx->ir_base[ref].op == IR_SNAPSHOT + && !(top_ival->flags & IR_LIVE_INTERVAL_SPILL_SPECIAL)) { IR_ASSERT(use_pos->hint_ref >= 0); /* A reference to a CPU spill slot */ reg = IR_REG_SPILL_STORE | IR_REG_STACK_POINTER; ir_set_alocated_reg(ctx, ref, use_pos->op_num, reg); + } else if (use_pos->hint_ref < 0 && !(use_pos->flags & IR_PHI_USE)) { + IR_ASSERT(ctx->rules[-use_pos->hint_ref] & IR_FUSED); + ctx->rules[-use_pos->hint_ref] |= IR_FUSED_REG; + ir_set_fused_reg(ctx, ref, -use_pos->hint_ref * sizeof(ir_ref) + use_pos->op_num, IR_REG_NONE); } use_pos = use_pos->next; } @@ -4092,17 +4069,18 @@ static void assign_regs(ir_ctx *ctx) } while (ival); } + const ir_call_conv_dsc *cc = ((ir_reg_alloc_data*)(ctx->data))->cc; if (ctx->fixed_stack_frame_size != -1) { ctx->used_preserved_regs = (ir_regset)ctx->fixed_save_regset; - if (IR_REGSET_DIFFERENCE(IR_REGSET_INTERSECTION(used_regs, IR_REGSET_PRESERVED), + if (IR_REGSET_DIFFERENCE(IR_REGSET_INTERSECTION(used_regs, cc->preserved_regs), ctx->used_preserved_regs)) { // TODO: Preserved reg and fixed frame conflict ??? // IR_ASSERT(0 && "Preserved reg and fixed frame conflict"); } } else { ctx->used_preserved_regs = IR_REGSET_UNION((ir_regset)ctx->fixed_save_regset, - IR_REGSET_DIFFERENCE(IR_REGSET_INTERSECTION(used_regs, IR_REGSET_PRESERVED), - (ctx->flags & IR_FUNCTION) ? (ir_regset)ctx->fixed_regset : IR_REGSET_PRESERVED)); + IR_REGSET_DIFFERENCE(IR_REGSET_INTERSECTION(used_regs, cc->preserved_regs), + (ctx->flags & IR_FUNCTION) ? (ir_regset)ctx->fixed_regset : cc->preserved_regs)); } ir_fix_stack_frame(ctx); @@ -4110,9 +4088,24 @@ static void assign_regs(ir_ctx *ctx) int ir_reg_alloc(ir_ctx *ctx) { - if (ir_linear_scan(ctx)) { + ir_reg_alloc_data data; + ir_ref vars = ctx->vars; + + data.cc = ir_get_call_conv_dsc(ctx->flags); + data.unused_slot_4 = 0; + data.unused_slot_2 = 0; + data.unused_slot_1 = 0; + data.handled = NULL; + + ctx->data = &data; + ctx->stack_frame_size = 0; + + if (ir_linear_scan(ctx, vars)) { assign_regs(ctx); + ctx->data = NULL; return 1; } + + ctx->data = NULL; return 0; } diff --git a/ext/opcache/jit/ir/ir_save.c b/ext/opcache/jit/ir/ir_save.c index b12cc267af60..8b3f3b5c6b5d 100644 --- a/ext/opcache/jit/ir/ir_save.c +++ b/ext/opcache/jit/ir/ir_save.c @@ -10,31 +10,100 @@ void ir_print_proto(const ir_ctx *ctx, ir_ref func_proto, FILE *f) { - ir_ref j; - if (func_proto) { const ir_proto_t *proto = (const ir_proto_t *)ir_get_str(ctx, func_proto); + ir_print_proto_ex(proto->flags, proto->ret_type, proto->params_count, proto->param_types, f); + } else { + fprintf(f, "(): int32_t"); + } +} - fprintf(f, "("); - if (proto->params_count > 0) { - fprintf(f, "%s", ir_type_cname[proto->param_types[0]]); - for (j = 1; j < proto->params_count; j++) { - fprintf(f, ", %s", ir_type_cname[proto->param_types[j]]); - } - if (proto->flags & IR_VARARG_FUNC) { - fprintf(f, ", ..."); - } - } else if (proto->flags & IR_VARARG_FUNC) { - fprintf(f, "..."); - } - fprintf(f, "): %s", ir_type_cname[proto->ret_type]); - if (proto->flags & IR_FASTCALL_FUNC) { - fprintf(f, " __fastcall"); - } else if (proto->flags & IR_BUILTIN_FUNC) { +static void ir_print_call_conv(uint32_t flags, FILE *f) +{ + switch (flags & IR_CALL_CONV_MASK) { + case IR_CC_BUILTIN: fprintf(f, " __builtin"); + break; + case IR_CC_FASTCALL: + fprintf(f, " __fastcall"); + break; + case IR_CC_PRESERVE_NONE: + fprintf(f, " __preserve_none"); + break; +#if defined(IR_TARGET_X64) + case IR_CC_X86_64_SYSV: + fprintf(f, " __sysv"); + break; + case IR_CC_X86_64_MS: + fprintf(f, " __win64"); + break; +#elif defined(IR_TARGET_AARCH64) + case IR_CC_AARCH64_SYSV: + fprintf(f, " __sysv"); + break; + case IR_CC_AARCH64_DARWIN: + fprintf(f, " __darwin"); + break; +#endif + default: + IR_ASSERT((flags & IR_CALL_CONV_MASK) == IR_CC_DEFAULT); + } +} + +void ir_print_proto_ex(uint8_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types, FILE *f) +{ + uint32_t j; + + fprintf(f, "("); + if (params_count > 0) { + fprintf(f, "%s", ir_type_cname[param_types[0]]); + for (j = 1; j < params_count; j++) { + fprintf(f, ", %s", ir_type_cname[param_types[j]]); } - } else { - fprintf(f, "(): int32_t"); + if (flags & IR_VARARG_FUNC) { + fprintf(f, ", ..."); + } + } else if (flags & IR_VARARG_FUNC) { + fprintf(f, "..."); + } + fprintf(f, "): %s", ir_type_cname[ret_type]); + ir_print_call_conv(flags, f); + if (flags & IR_CONST_FUNC) { + fprintf(f, " __const"); + } else if (flags & IR_PURE_FUNC) { + fprintf(f, " __pure"); + } +} + +void ir_print_func_proto(const ir_ctx *ctx, const char *name, bool prefix, FILE *f) +{ + if (ctx->flags & IR_STATIC) { + fprintf(f, "static "); + } + fprintf(f, "func %s%s(", + prefix ? "@" : "", + name); + if (ctx->ir_base[2].op == IR_PARAM) { + ir_insn *insn = &ctx->ir_base[2]; + + fprintf(f, "%s", ir_type_cname[insn->type]); + insn++; + while (insn->op == IR_PARAM) { + fprintf(f, ", %s", ir_type_cname[insn->type]); + insn++;; + } + if (ctx->flags & IR_VARARG_FUNC) { + fprintf(f, ", ..."); + } + } else if (ctx->flags & IR_VARARG_FUNC) { + fprintf(f, "..."); + } + fprintf(f, "): %s", ir_type_cname[ctx->ret_type != (ir_type)-1 ? ctx->ret_type : IR_VOID]); + ir_print_call_conv(ctx->flags, f); + if (ctx->flags & IR_CONST_FUNC) { + fprintf(f, " __const"); + } else if (ctx->flags & IR_PURE_FUNC) { + fprintf(f, " __pure"); } } @@ -97,10 +166,18 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) for (i = IR_UNUSED + 1, insn = ctx->ir_base - i; i < ctx->consts_count; i++, insn--) { fprintf(f, "\t%s c_%d = ", ir_type_cname[insn->type], i); if (insn->op == IR_FUNC) { - fprintf(f, "func %s", ir_get_str(ctx, insn->val.name)); + fprintf(f, "func %s%s", + (save_flags & IR_SAVE_SAFE_NAMES) ? "@" : "", + ir_get_str(ctx, insn->val.name)); ir_print_proto(ctx, insn->proto, f); } else if (insn->op == IR_SYM) { - fprintf(f, "sym(%s)", ir_get_str(ctx, insn->val.name)); + fprintf(f, "sym(%s%s)", + (save_flags & IR_SAVE_SAFE_NAMES) ? "@" : "", + ir_get_str(ctx, insn->val.name)); + } else if (insn->op == IR_LABEL) { + fprintf(f, "label(%s%s)", + (save_flags & IR_SAVE_SAFE_NAMES) ? "@" : "", + ir_get_str(ctx, insn->val.name)); } else if (insn->op == IR_FUNC_ADDR) { fprintf(f, "func *"); ir_print_const(ctx, insn, f, true); @@ -140,6 +217,9 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) fprintf(f, ", loop=BB%d(%d)", bb->loop_header, bb->loop_depth); } } + if (bb->flags & IR_BB_IRREDUCIBLE_LOOP) { + fprintf(f, ", IRREDUCIBLE"); + } if (bb->predecessors_count) { uint32_t i; @@ -203,7 +283,7 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) n = ir_operands_count(ctx, insn); if ((insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN) && n != 2) { fprintf(f, "/%d", n); - } else if ((insn->op == IR_CALL || insn->op == IR_TAILCALL) && n != 2) { + } else if ((insn->op == IR_CALL || insn->op == IR_TAILCALL || insn->op == IR_ASM) && n != 2) { fprintf(f, "/%d", n - 2); } else if (insn->op == IR_PHI && n != 3) { fprintf(f, "/%d", n - 1); @@ -241,6 +321,7 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) case IR_OPND_CONTROL: case IR_OPND_CONTROL_DEP: case IR_OPND_CONTROL_REF: + case IR_OPND_CONTROL_GUARD: fprintf(f, "%sl_%d", first ? "(" : ", ", ref); first = 0; break; @@ -261,10 +342,19 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) fprintf(f, "%s%d", first ? "(" : ", ", ref); first = 0; break; + case IR_OPND_LABEL_REF: + if (ref) { + IR_ASSERT(IR_IS_CONST_REF(ref)); + fprintf(f, "%sc_%d", first ? "(" : ", ", -ref); + first = 0; + } + break; } } else if (opnd_kind == IR_OPND_NUM) { fprintf(f, "%s%d", first ? "(" : ", ", ref); first = 0; + } else if (opnd_kind == IR_OPND_CONTROL_GUARD) { + /* skip */ } else if (j != n && (IR_IS_REF_OPND_KIND(opnd_kind) || (opnd_kind == IR_OPND_UNUSED && p[n-j]))) { fprintf(f, "%snull", first ? "(" : ", "); @@ -273,6 +363,12 @@ void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f) } if (first) { fprintf(f, ";"); + } else if (ctx->value_params + && insn->op == IR_PARAM + && ctx->value_params[insn->op3 - 1].align) { + fprintf(f, ") ByVal(%d, %d);", + ctx->value_params[insn->op3 - 1].size, + ctx->value_params[insn->op3 - 1].align); } else { fprintf(f, ");"); } diff --git a/ext/opcache/jit/ir/ir_sccp.c b/ext/opcache/jit/ir/ir_sccp.c index 2e006516df81..f2b8616e2afa 100644 --- a/ext/opcache/jit/ir/ir_sccp.c +++ b/ext/opcache/jit/ir/ir_sccp.c @@ -12,12 +12,13 @@ #include "ir.h" #include "ir_private.h" +#include + #define IR_COMBO_COPY_PROPAGATION 1 #define IR_TOP IR_UNUSED #define IR_BOTTOM IR_LAST_OP -#define IR_MAKE_TOP(ref) do {IR_ASSERT(ref > 0); _values[ref].optx = IR_TOP;} while (0) #define IR_MAKE_BOTTOM(ref) do {IR_ASSERT(ref > 0); _values[ref].optx = IR_BOTTOM;} while (0) #define IR_IS_TOP(ref) (ref >= 0 && _values[ref].op == IR_TOP) @@ -25,17 +26,57 @@ #define IR_IS_REACHABLE(ref) _ir_is_reachable_ctrl(ctx, _values, ref) #define IR_IS_CONST(ref) (IR_IS_CONST_REF(ref) || IR_IS_CONST_OP(_values[ref].op)) -IR_ALWAYS_INLINE bool _ir_is_reachable_ctrl(ir_ctx *ctx, ir_insn *_values, ir_ref ref) +typedef struct { + union { + struct { + IR_STRUCT_LOHI( + union { + IR_STRUCT_LOHI( + union { + IR_STRUCT_LOHI( + uint8_t op, /* [IR_TOP - unreachable, IR_BOTTOM - reachable} for control */ + /* {IR_TOP | IR_COPY() | IR_CONST() | IR_BOTTOM} for data */ + /* {IR_TOP | IR_MERGE() | IR_BOTTOM} for IR_MERGE */ + /* {IR_TOP | IR_IF() | IR_BOTTOM} for IR_IF and IR_SWITCH */ + uint8_t type + ); + uint16_t opt; + }, + uint16_t _space_1 + ); + uint32_t optx; + }, + union { + ir_ref copy; /* identity for IR_COPY */ + ir_ref unfeasible_inputs; /* number of unfeasible inputs for IR_MERGE */ + ir_ref single_output; /* reachable output for IR_IF */ + ir_ref visited; /* for IR_TOP */ + } + ); + union { + struct { + ir_ref next; /* double-linked identities list for IR_COPY */ + ir_ref prev; /* double-linked identities list for IR_COPY */ + }; + ir_val val; /* constant value for IR_CONST */ + }; + }; + ir_insn insn; /* constant insn for IR_CONST */ + }; +} ir_sccp_val; + +IR_ALWAYS_INLINE bool _ir_is_reachable_ctrl(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref ref) { IR_ASSERT(!IR_IS_CONST_REF(ref)); IR_ASSERT(ir_op_flags[ctx->ir_base[ref].op] & IR_OP_FLAG_CONTROL); return _values[ref].op != IR_TOP; /* BOTTOM, IF or MERGE */ } -IR_ALWAYS_INLINE void ir_sccp_add_uses(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref) +IR_ALWAYS_INLINE void ir_sccp_add_uses(const ir_ctx *ctx, const ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref) { - ir_use_list *use_list; - ir_ref n, *p, use; + const ir_use_list *use_list; + const ir_ref *p; + ir_ref n, use; IR_ASSERT(!IR_IS_CONST_REF(ref)); use_list = &ctx->use_lists[ref]; @@ -48,23 +89,23 @@ IR_ALWAYS_INLINE void ir_sccp_add_uses(ir_ctx *ctx, ir_insn *_values, ir_bitqueu } } -IR_ALWAYS_INLINE void ir_sccp_add_input(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref) +IR_ALWAYS_INLINE void ir_sccp_add_input(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref) { IR_ASSERT(!IR_IS_CONST_REF(ref)); IR_ASSERT(_values[ref].op == IR_TOP); /* do backward propagaton only once */ - if (!_values[ref].op1) { - _values[ref].op1 = 1; + if (!_values[ref].visited) { + _values[ref].visited = 1; ir_bitqueue_add(worklist, ref); } } #if IR_COMBO_COPY_PROPAGATION -IR_ALWAYS_INLINE ir_ref ir_sccp_identity(ir_ctx *ctx, ir_insn *_values, ir_ref a) +IR_ALWAYS_INLINE ir_ref ir_sccp_identity(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref a) { if (a > 0 && _values[a].op == IR_COPY) { do { - a = _values[a].op1; + a = _values[a].copy; IR_ASSERT(a > 0); } while (_values[a].op == IR_COPY); IR_ASSERT(_values[a].op == IR_BOTTOM); @@ -73,7 +114,7 @@ IR_ALWAYS_INLINE ir_ref ir_sccp_identity(ir_ctx *ctx, ir_insn *_values, ir_ref a } #if 0 -static void CHECK_LIST(ir_insn *_values, ir_ref ref) +static void CHECK_LIST(ir_sccp_val *_values, ir_ref ref) { ir_ref member = _values[ref].op2; while (member != ref) { @@ -86,44 +127,44 @@ static void CHECK_LIST(ir_insn *_values, ir_ref ref) # define CHECK_LIST(_values, ref) #endif -static void ir_sccp_add_identity(ir_ctx *ctx, ir_insn *_values, ir_ref src, ir_ref dst) +static void ir_sccp_add_identity(const ir_ctx *ctx, ir_sccp_val *_values, ir_ref src, ir_ref dst) { IR_ASSERT(dst > 0 && _values[dst].op != IR_BOTTOM && _values[dst].op != IR_COPY); IR_ASSERT((src > 0 && (_values[src].op == IR_BOTTOM || _values[src].op == IR_COPY))); IR_ASSERT(ir_sccp_identity(ctx, _values, src) != dst); _values[dst].optx = IR_COPY; - _values[dst].op1 = src; + _values[dst].copy = src; if (_values[src].op == IR_BOTTOM) { /* initialize empty double-linked list */ - if (_values[src].op1 != src) { - _values[src].op1 = src; - _values[src].op2 = src; - _values[src].op3 = src; + if (_values[src].copy != src) { + _values[src].copy = src; + _values[src].next = src; + _values[src].prev = src; } } else { src = ir_sccp_identity(ctx, _values, src); } /* insert into circular double-linked list */ - ir_ref prev = _values[src].op3; - _values[dst].op2 = src; - _values[dst].op3 = prev; - _values[src].op3 = dst; - _values[prev].op2 = dst; + ir_ref prev = _values[src].prev; + _values[dst].next = src; + _values[dst].prev = prev; + _values[src].prev = dst; + _values[prev].next = dst; CHECK_LIST(_values, dst); } -static void ir_sccp_split_partition(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref) +static void ir_sccp_split_partition(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref) { ir_ref member, head, tail, next, prev; CHECK_LIST(_values, ref); IR_MAKE_BOTTOM(ref); - _values[ref].op1 = ref; + _values[ref].copy = ref; - member = _values[ref].op2; + member = _values[ref].next; head = tail = IR_UNUSED; while (member != ref) { if (_values[member].op != IR_BOTTOM) { @@ -131,19 +172,19 @@ static void ir_sccp_split_partition(ir_ctx *ctx, ir_insn *_values, ir_bitqueue * } ir_sccp_add_uses(ctx, _values, worklist, member); - next = _values[member].op2; + next = _values[member].next; if (ir_sccp_identity(ctx, _values, member) == ref) { /* remove "member" from the old circular double-linked list */ - prev = _values[member].op3; - _values[prev].op2 = next; - _values[next].op3 = prev; + prev = _values[member].prev; + _values[prev].next = next; + _values[next].prev = prev; /* insert "member" into the new double-linked list */ if (!head) { head = tail = member; } else { - _values[tail].op2 = member; - _values[member].op3 = tail; + _values[tail].next = member; + _values[member].prev = tail; tail = member; } } @@ -151,26 +192,26 @@ static void ir_sccp_split_partition(ir_ctx *ctx, ir_insn *_values, ir_bitqueue * } /* remove "ref" from the old circular double-linked list */ - next = _values[ref].op2; - prev = _values[ref].op3; - _values[prev].op2 = next; - _values[next].op3 = prev; + next = _values[ref].next; + prev = _values[ref].prev; + _values[prev].next = next; + _values[next].prev = prev; CHECK_LIST(_values, next); /* close the new circle */ if (head) { - _values[ref].op2 = head; - _values[ref].op3 = tail; - _values[tail].op2 = ref; - _values[head].op3 = ref; + _values[ref].next = head; + _values[ref].prev = tail; + _values[tail].next = ref; + _values[head].prev = ref; } else { - _values[ref].op2 = ref; - _values[ref].op3 = ref; + _values[ref].next = ref; + _values[ref].prev = ref; } CHECK_LIST(_values, ref); } -IR_ALWAYS_INLINE void ir_sccp_make_bottom_ex(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref) +IR_ALWAYS_INLINE void ir_sccp_make_bottom_ex(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref) { if (_values[ref].op == IR_COPY) { ir_sccp_split_partition(ctx, _values, worklist, ref); @@ -185,7 +226,7 @@ IR_ALWAYS_INLINE void ir_sccp_make_bottom_ex(ir_ctx *ctx, ir_insn *_values, ir_b # define IR_MAKE_BOTTOM_EX(ref) IR_MAKE_BOTTOM(ref) #endif -IR_ALWAYS_INLINE bool ir_sccp_meet_const(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref, ir_insn *val_insn) +IR_ALWAYS_INLINE bool ir_sccp_meet_const(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref, const ir_insn *val_insn) { IR_ASSERT(IR_IS_CONST_OP(val_insn->op) || IR_IS_SYM_CONST(val_insn->op)); @@ -205,46 +246,51 @@ IR_ALWAYS_INLINE bool ir_sccp_meet_const(ir_ctx *ctx, ir_insn *_values, ir_bitqu return 1; } -IR_ALWAYS_INLINE bool ir_sccp_meet(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref, ir_ref val) +IR_ALWAYS_INLINE bool ir_sccp_meet_copy(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref, ir_ref val) +{ +#if IR_COMBO_COPY_PROPAGATION + if (_values[ref].op == IR_COPY) { + /* COPY(OLD_VAL) meet COPY(NEW_VAL) => + * (IDENTITY(OLD_VAL) == IDENTITY(NEW_VAL) ? COPY(OLD_VAL) ? BOTTOM */ + if (ir_sccp_identity(ctx, _values, ref) == ir_sccp_identity(ctx, _values, val)) { + return 0; /* not changed */ + } + ir_sccp_split_partition(ctx, _values, worklist, ref); + return 1; + } else { + IR_ASSERT(_values[ref].op != IR_BOTTOM); + /* TOP meet COPY(NEW_VAL) -> COPY(NEW_VAL) */ + /* OLD_CONST meet COPY(NEW_VAL) -> COPY(NEW_VAL) */ + ir_sccp_add_identity(ctx, _values, val, ref); + return 1; + } +#endif + IR_MAKE_BOTTOM(ref); + return 1; +} + +#if 0 +IR_ALWAYS_INLINE bool ir_sccp_meet(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref, ir_ref val) { - ir_ref val_identity = ir_sccp_identity(ctx, _values, val); - ir_insn *val_insn; + const ir_insn *val_insn; - if (IR_IS_CONST_REF(val_identity)) { - val_insn = &ctx->ir_base[val_identity]; + if (IR_IS_CONST_REF(val)) { + val_insn = &ctx->ir_base[val]; } else { - val_insn = &_values[val_identity]; + val_insn = &_values[val].insn; if (!IR_IS_CONST_OP(val_insn->op) && !IR_IS_SYM_CONST(val_insn->op)) { -#if IR_COMBO_COPY_PROPAGATION - if (_values[ref].op == IR_COPY) { - /* COPY(OLD_VAL) meet COPY(NEW_VAL) => - * (IDENTITY(OLD_VAL) == IDENTITY(NEW_VAL) ? COPY(OLD_VAL) ? BOTTOM */ - if (ir_sccp_identity(ctx, _values, ref) == val_identity) { - return 0; /* not changed */ - } - ir_sccp_split_partition(ctx, _values, worklist, ref); - return 1; - } else { - IR_ASSERT(_values[ref].op != IR_BOTTOM); - /* TOP meet COPY(NEW_VAL) -> COPY(NEW_VAL) */ - /* OLD_CONST meet COPY(NEW_VAL) -> COPY(NEW_VAL) */ - ir_sccp_add_identity(ctx, _values, val, ref); - return 1; - } -#endif - - IR_MAKE_BOTTOM(ref); - return 1; + return ir_sccp_meet_copy(ctx, _values, worklist, ref, val); } } return ir_sccp_meet_const(ctx, _values, worklist, ref, val_insn); } +#endif -static ir_ref ir_sccp_fold(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref, ir_insn *insn) +static ir_ref ir_sccp_fold(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref ref, const ir_insn *insn) { - ir_insn *op1_insn, *op2_insn, *op3_insn; + const ir_insn *op1_insn, *op2_insn, *op3_insn; ir_ref op1, op2, op3, copy; uint32_t opt = insn->opt; @@ -253,11 +299,11 @@ static ir_ref ir_sccp_fold(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, op3 = ir_sccp_identity(ctx, _values, insn->op3); restart: - op1_insn = (op1 > 0 && IR_IS_CONST_OP(_values[op1].op)) ? _values + op1 : ctx->ir_base + op1; - op2_insn = (op2 > 0 && IR_IS_CONST_OP(_values[op2].op)) ? _values + op2 : ctx->ir_base + op2; - op3_insn = (op3 > 0 && IR_IS_CONST_OP(_values[op3].op)) ? _values + op3 : ctx->ir_base + op3; + op1_insn = (op1 > 0 && IR_IS_CONST_OP(_values[op1].op)) ? &_values[op1].insn : ctx->ir_base + op1; + op2_insn = (op2 > 0 && IR_IS_CONST_OP(_values[op2].op)) ? &_values[op2].insn : ctx->ir_base + op2; + op3_insn = (op3 > 0 && IR_IS_CONST_OP(_values[op3].op)) ? &_values[op3].insn : ctx->ir_base + op3; - switch (ir_folding(ctx, opt, op1, op2, op3, op1_insn, op2_insn, op3_insn)) { + switch (ir_folding((ir_ctx*)ctx, opt, op1, op2, op3, op1_insn, op2_insn, op3_insn)) { case IR_FOLD_DO_RESTART: opt = ctx->fold_insn.optx; op1 = ctx->fold_insn.op1; @@ -270,19 +316,30 @@ static ir_ref ir_sccp_fold(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, return 1; case IR_FOLD_DO_COPY: copy = ctx->fold_insn.op1; - return ir_sccp_meet(ctx, _values, worklist, ref, copy); + if (IR_IS_CONST_REF(copy)) { + insn = &ctx->ir_base[copy]; + } else { + insn = &_values[copy].insn; + if (!IR_IS_CONST_OP(insn->op) && !IR_IS_SYM_CONST(insn->op)) { + return ir_sccp_meet_copy(ctx, _values, worklist, ref, copy); + } + } + goto meet_const; case IR_FOLD_DO_CONST: - return ir_sccp_meet_const(ctx, _values, worklist, ref, &ctx->fold_insn); + insn = &ctx->fold_insn; +meet_const: + return ir_sccp_meet_const(ctx, _values, worklist, ref, insn); default: IR_ASSERT(0); return 0; } } -static bool ir_sccp_analyze_phi(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref i, ir_insn *insn) +static bool ir_sccp_analyze_phi(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_ref i, const ir_insn *insn) { - ir_ref j, n, input, *merge_input, *p; - ir_insn *v, *new_const = NULL; + ir_ref j, n, input; + const ir_ref *merge_input, *p; + const ir_insn *v, *new_const = NULL; #if IR_COMBO_COPY_PROPAGATION ir_ref new_copy = IR_UNUSED; ir_ref new_copy_identity = IR_UNUSED; @@ -313,7 +370,7 @@ static bool ir_sccp_analyze_phi(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *work } else if (input == i) { continue; } else { - v = &_values[input]; + v = &_values[input].insn; if (v->op == IR_TOP) { ir_sccp_add_input(ctx, _values, worklist, input); continue; @@ -367,7 +424,7 @@ static bool ir_sccp_analyze_phi(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *work } else if (input == i) { continue; } else { - v = &_values[input]; + v = &_values[input].insn; if (v->op == IR_TOP) { ir_sccp_add_input(ctx, _values, worklist, input); continue; @@ -396,7 +453,9 @@ static bool ir_sccp_analyze_phi(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *work #if IR_COMBO_COPY_PROPAGATION if (new_copy) { - return ir_sccp_meet(ctx, _values, worklist, i, new_copy); + IR_ASSERT(!IR_IS_CONST_REF(new_copy)); + IR_ASSERT(!IR_IS_CONST_OP(_values[new_copy].op) && !IR_IS_SYM_CONST(_values[new_copy].op)); + return ir_sccp_meet_copy(ctx, _values, worklist, i, new_copy); } #endif @@ -407,7 +466,7 @@ static bool ir_sccp_analyze_phi(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *work return 1; } -static bool ir_is_dead_load_ex(ir_ctx *ctx, ir_ref ref, uint32_t flags, ir_insn *insn) +static bool ir_is_dead_load_ex(const ir_ctx *ctx, ir_ref ref, uint32_t flags, const ir_insn *insn) { if ((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) { return ctx->use_lists[ref].count == 1; @@ -417,21 +476,22 @@ static bool ir_is_dead_load_ex(ir_ctx *ctx, ir_ref ref, uint32_t flags, ir_insn return 0; } -static bool ir_is_dead_load(ir_ctx *ctx, ir_ref ref) +static bool ir_is_dead_load(const ir_ctx *ctx, ir_ref ref) { if (ctx->use_lists[ref].count == 1) { - uint32_t flags = ir_op_flags[ctx->ir_base[ref].op]; + const ir_insn *insn = &ctx->ir_base[ref]; + uint32_t flags = ir_op_flags[insn->op]; if ((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) { return 1; - } else if (ctx->ir_base[ref].op == IR_ALLOCA) { + } else if (insn->op == IR_ALLOCA || insn->op == IR_BLOCK_BEGIN) { return 1; } } return 0; } -static bool ir_is_dead(ir_ctx *ctx, ir_ref ref) +static bool ir_is_dead(const ir_ctx *ctx, ir_ref ref) { if (ctx->use_lists[ref].count == 0) { return IR_IS_FOLDABLE_OP(ctx->ir_base[ref].op); @@ -441,31 +501,47 @@ static bool ir_is_dead(ir_ctx *ctx, ir_ref ref) return 0; } -static bool ir_sccp_is_true(ir_ctx *ctx, ir_insn *_values, ir_ref a) +static bool ir_sccp_is_true(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref a) { - ir_insn *v = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a]; + const ir_insn *v = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a].insn; return ir_const_is_true(v); } -static bool ir_sccp_is_equal(ir_ctx *ctx, ir_insn *_values, ir_ref a, ir_ref b) +static bool ir_sccp_is_equal(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref a, ir_ref b) { - ir_insn *v1 = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a]; - ir_insn *v2 = IR_IS_CONST_REF(b) ? &ctx->ir_base[b] : &_values[b]; + const ir_insn *v1 = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a].insn; + const ir_insn *v2 = IR_IS_CONST_REF(b) ? &ctx->ir_base[b] : &_values[b].insn; IR_ASSERT(!IR_IS_SYM_CONST(v1->op)); IR_ASSERT(!IR_IS_SYM_CONST(v2->op)); return v1->val.u64 == v2->val.u64; } +static bool ir_sccp_in_range(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref a, ir_ref b, ir_ref c) +{ + const ir_insn *v1 = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a].insn; + const ir_insn *v2 = IR_IS_CONST_REF(b) ? &ctx->ir_base[b] : &_values[b].insn; + const ir_insn *v3 = IR_IS_CONST_REF(c) ? &ctx->ir_base[c] : &_values[c].insn; + + IR_ASSERT(!IR_IS_SYM_CONST(v1->op)); + IR_ASSERT(!IR_IS_SYM_CONST(v2->op)); + IR_ASSERT(!IR_IS_SYM_CONST(v3->op)); + if (IR_IS_TYPE_SIGNED(v1->type)) { + return v1->val.i64 >= v2->val.i64 && v1->val.i64 <= v3->val.i64; + } else { + return v1->val.u64 >= v2->val.u64 && v1->val.u64 <= v3->val.u64; + } +} + #ifdef IR_SCCP_TRACE -static void ir_sccp_trace_val(ir_ctx *ctx, ir_insn *_values, ir_ref i) +static void ir_sccp_trace_val(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref i) { if (IR_IS_BOTTOM(i)) { fprintf(stderr, "BOTTOM"); } else if (IR_IS_CONST_OP(_values[i].op) || IR_IS_SYM_CONST(_values[i].op)) { fprintf(stderr, "CONST("); - ir_print_const(ctx, &_values[i], stderr, true); + ir_print_const(ctx, &_values[i].insn, stderr, true); fprintf(stderr, ")"); #if IR_COMBO_COPY_PROPAGATION } else if (_values[i].op == IR_COPY) { @@ -482,13 +558,13 @@ static void ir_sccp_trace_val(ir_ctx *ctx, ir_insn *_values, ir_ref i) } } -static void ir_sccp_trace_start(ir_ctx *ctx, ir_insn *_values, ir_ref i) +static void ir_sccp_trace_start(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref i) { fprintf(stderr, "%d. ", i); ir_sccp_trace_val(ctx, _values, i); } -static void ir_sccp_trace_end(ir_ctx *ctx, ir_insn *_values, ir_ref i) +static void ir_sccp_trace_end(const ir_ctx *ctx, const ir_sccp_val *_values, ir_ref i) { fprintf(stderr, " -> "); ir_sccp_trace_val(ctx, _values, i); @@ -499,11 +575,12 @@ static void ir_sccp_trace_end(ir_ctx *ctx, ir_insn *_values, ir_ref i) # define ir_sccp_trace_end(c, v, i) #endif -static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_bitqueue *iter_worklist) +static IR_NEVER_INLINE void ir_sccp_analyze(const ir_ctx *ctx, ir_sccp_val *_values, ir_bitqueue *worklist, ir_bitqueue *iter_worklist) { - ir_ref i, j, n, *p, use; - ir_use_list *use_list; - ir_insn *insn, *use_insn; + ir_ref i, j, n, use; + const ir_ref *p; + const ir_use_list *use_list; + const ir_insn *insn, *use_insn; uint32_t flags; /* A bit modified SCCP algorithm of M. N. Wegman and F. K. Zadeck */ @@ -526,12 +603,16 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi bool may_benefit = 0; bool has_top = 0; - if (_values[i].op != IR_TOP) { + if (_values[i].op != IR_TOP || insn->op == IR_COPY) { may_benefit = 1; } IR_ASSERT(!IR_OP_HAS_VAR_INPUTS(flags)); n = IR_INPUT_EDGES_COUNT(flags); + if (insn->op == IR_DIV || insn->op == IR_MOD) { + /* skip data-control guard edge */ + n--; + } for (p = insn->ops + 1; n > 0; p++, n--) { ir_ref input = *p; if (input > 0) { @@ -567,6 +648,15 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi } } else { IR_MAKE_BOTTOM_EX(i); + n = IR_INPUT_EDGES_COUNT(flags); + for (p = insn->ops + 1; n > 0; p++, n--) { + ir_ref input = *p; + if (input > 0) { + if (_values[input].op == IR_TOP) { + ir_sccp_add_input(ctx, _values, worklist, input); + } + } + } } } else if (flags & IR_OP_FLAG_BB_START) { if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_BEGIN) { @@ -582,7 +672,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi } } for (p = insn->ops + 1; n > 0; p++, n--) { - ir_ref input = *p; + const ir_ref input = *p; IR_ASSERT(input > 0); if (!IR_IS_REACHABLE(input)) { unfeasible_inputs++; @@ -590,9 +680,9 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi } if (unfeasible_inputs == 0) { IR_MAKE_BOTTOM(i); - } else if (_values[i].op != IR_MERGE || _values[i].op1 != unfeasible_inputs) { + } else if (_values[i].op != IR_MERGE || _values[i].unfeasible_inputs != unfeasible_inputs) { _values[i].optx = IR_MERGE; - _values[i].op1 = unfeasible_inputs; + _values[i].unfeasible_inputs = unfeasible_inputs; } else { continue; } @@ -646,10 +736,10 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi } if (_values[i].op == IR_TOP) { _values[i].optx = IR_IF; - _values[i].op1 = use; + _values[i].single_output = use; ir_bitqueue_add(worklist, use); continue; - } else if (_values[i].op == IR_IF && _values[i].op1 == use) { + } else if (_values[i].op == IR_IF && _values[i].single_output == use) { continue; } } @@ -676,16 +766,21 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi } } else if (use_insn->op == IR_CASE_DEFAULT) { use_case = use; + } else if (use_insn->op == IR_CASE_RANGE) { + if (ir_sccp_in_range(ctx, _values, insn->op2, use_insn->op2, use_insn->op3)) { + use_case = use; + break; + } } } if (use_case) { use_insn = &ctx->ir_base[use_case]; if (_values[i].op == IR_TOP) { _values[i].optx = IR_IF; - _values[i].op1 = use_case; + _values[i].single_output = use_case; ir_bitqueue_add(worklist, use_case); continue; - } else if (_values[i].op == IR_IF || _values[i].op1 == use_case) { + } else if (_values[i].op == IR_IF || _values[i].single_output == use_case) { continue; } } @@ -696,52 +791,32 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi ir_bitqueue_add(iter_worklist, i); IR_MAKE_BOTTOM(i); } else { - if (_values[i].op == IR_TOP) { - bool has_top = 0; - - /* control, call, load and store instructions may have unprocessed inputs */ - n = IR_INPUT_EDGES_COUNT(flags); - if (IR_OP_HAS_VAR_INPUTS(flags) && (n = insn->inputs_count) > 3) { - for (j = 0; j < (n>>2); j++) { - _values[i+j+1].optx = IR_BOTTOM; /* keep the tail of a long multislot instruction */ - } - for (j = 2, p = insn->ops + j; j <= n; j++, p++) { - IR_ASSERT(IR_OPND_KIND(flags, j) == IR_OPND_DATA); - use = *p; - if (use > 0 && _values[use].op == IR_TOP) { - has_top = 1; - ir_sccp_add_input(ctx, _values, worklist, use); - } - } - } else if (n >= 2) { - IR_ASSERT(IR_OPND_KIND(flags, 2) == IR_OPND_DATA); - use = insn->op2; + /* control, call, load and store instructions may have unprocessed inputs */ + n = IR_INPUT_EDGES_COUNT(flags); + if (IR_OP_HAS_VAR_INPUTS(flags) && (n = insn->inputs_count) > 3) { + for (j = 0; j < (n>>2); j++) { + _values[i+j+1].optx = IR_BOTTOM; /* keep the tail of a long multislot instruction */ + } + for (j = 2, p = insn->ops + j; j <= n; j++, p++) { + IR_ASSERT(IR_OPND_KIND(flags, j) == IR_OPND_DATA); + use = *p; if (use > 0 && _values[use].op == IR_TOP) { - has_top = 1; ir_sccp_add_input(ctx, _values, worklist, use); } - if (n > 2) { - IR_ASSERT(n == 3); - IR_ASSERT(IR_OPND_KIND(flags, 3) == IR_OPND_DATA); - use = insn->op3; - if (use > 0 && _values[use].op == IR_TOP) { - has_top = 1; - ir_sccp_add_input(ctx, _values, worklist, use); - } - } } - - if (has_top && !(flags & IR_OP_FLAG_BB_END)) { - use = ir_next_control(ctx, i); - if (_values[use].op == IR_TOP) { - has_top = 1; - /* do forward control propagaton only once */ - if (!_values[use].op1) { - _values[use].op1 = 1; - ir_bitqueue_add(worklist, use); - } + } else if (n >= 2) { + IR_ASSERT(IR_OPND_KIND(flags, 2) == IR_OPND_DATA); + use = insn->op2; + if (use > 0 && _values[use].op == IR_TOP) { + ir_sccp_add_input(ctx, _values, worklist, use); + } + if (n > 2) { + IR_ASSERT(n == 3); + IR_ASSERT(IR_OPND_KIND(flags, 3) == IR_OPND_DATA); + use = insn->op3; + if (use > 0 && _values[use].op == IR_TOP) { + ir_sccp_add_input(ctx, _values, worklist, use); } - continue; } } IR_MAKE_BOTTOM(i); @@ -755,18 +830,20 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi for (i = 1; i < ctx->insns_count; i++) { if (IR_IS_CONST_OP(_values[i].op) || IR_IS_SYM_CONST(_values[i].op)) { fprintf(stderr, "%d. CONST(", i); - ir_print_const(ctx, &_values[i], stderr, true); + ir_print_const(ctx, &_values[i].insn, stderr, true); fprintf(stderr, ")\n"); #if IR_COMBO_COPY_PROPAGATION } else if (_values[i].op == IR_COPY) { - fprintf(stderr, "%d. COPY(%d)\n", i, _values[i].op1); + fprintf(stderr, "%d. COPY(%d)\n", i, _values[i].copy); #endif } else if (IR_IS_TOP(i)) { - fprintf(stderr, "%d. TOP\n", i); + if (ctx->ir_base[i].op != IR_TOP) { + fprintf(stderr, "%d. TOP\n", i); + } } else if (_values[i].op == IR_IF) { - fprintf(stderr, "%d. IF(%d)\n", i, _values[i].op1); + fprintf(stderr, "%d. IF(%d)\n", i, _values[i].single_output); } else if (_values[i].op == IR_MERGE) { - fprintf(stderr, "%d. MERGE(%d)\n", i, _values[i].op1); + fprintf(stderr, "%d. MERGE(%d)\n", i, _values[i].unfeasible_inputs); } else if (!IR_IS_BOTTOM(i)) { fprintf(stderr, "%d. %d\n", i, _values[i].op); } @@ -793,7 +870,7 @@ static void ir_sccp_make_nop(ir_ctx *ctx, ir_ref ref) } } -static void ir_sccp_remove_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_bitqueue *worklist) +static void ir_sccp_remove_insn(ir_ctx *ctx, const ir_sccp_val *_values, ir_ref ref, ir_bitqueue *worklist) { ir_ref j, n, *p; ir_insn *insn; @@ -807,7 +884,7 @@ static void ir_sccp_remove_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_bi *p = IR_UNUSED; /* we may skip nodes that are going to be removed by SCCP (TOP, CONST and COPY) */ if (input > 0 && _values[input].op > IR_COPY) { - ir_use_list_remove_all(ctx, input, ref); + ir_use_list_remove_one(ctx, input, ref); if (ir_is_dead(ctx, input)) { /* schedule DCE */ ir_bitqueue_add(worklist, input); @@ -816,7 +893,7 @@ static void ir_sccp_remove_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_bi } } -static void ir_sccp_replace_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_ref new_ref, ir_bitqueue *worklist) +static void ir_sccp_replace_insn(ir_ctx *ctx, const ir_sccp_val *_values, ir_ref ref, ir_ref new_ref, ir_bitqueue *worklist) { ir_ref j, n, *p, use, i; ir_insn *insn; @@ -845,7 +922,7 @@ static void ir_sccp_replace_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_r *p = IR_UNUSED; /* we may skip nodes that are going to be removed by SCCP (TOP, CONST and COPY) */ if (input > 0 && _values[input].op > IR_COPY) { - ir_use_list_remove_all(ctx, input, ref); + ir_use_list_remove_one(ctx, input, ref); if (ir_is_dead(ctx, input)) { /* schedule DCE */ ir_bitqueue_add(worklist, input); @@ -894,7 +971,7 @@ static void ir_sccp_replace_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_r CLEAR_USES(ref); } -static void ir_sccp_remove_if(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_ref dst) +static void ir_sccp_remove_if(ir_ctx *ctx, const ir_sccp_val *_values, ir_ref ref, ir_ref dst) { ir_ref next; ir_insn *insn, *next_insn; @@ -914,6 +991,7 @@ static void ir_sccp_remove_if(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_ref insn->optx = IR_OPTX(IR_END, IR_VOID, 1); next_insn = &ctx->ir_base[dst]; next_insn->op = IR_BEGIN; + next_insn->op2 = IR_UNUSED; } } @@ -1041,10 +1119,10 @@ static bool ir_sccp_remove_unfeasible_merge_inputs(ir_ctx *ctx, ir_ref ref, ir_i return 1; } -static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_bitqueue *iter_worklist) +static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, const ir_sccp_val *_values, ir_bitqueue *worklist, ir_bitqueue *iter_worklist) { ir_ref i, j; - ir_insn *value; + const ir_sccp_val *value; for (i = 1, value = _values + i; i < ctx->insns_count; value++, i++) { if (value->op == IR_BOTTOM) { @@ -1059,7 +1137,7 @@ static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_ ir_sccp_replace_insn(ctx, _values, i, j, iter_worklist); #if IR_COMBO_COPY_PROPAGATION } else if (value->op == IR_COPY) { - ir_sccp_replace_insn(ctx, _values, i, ir_sccp_identity(ctx, _values, value->op1), iter_worklist); + ir_sccp_replace_insn(ctx, _values, i, ir_sccp_identity(ctx, _values, value->copy), iter_worklist); #endif } else if (value->op == IR_TOP) { /* remove unreachable instruction */ @@ -1091,7 +1169,7 @@ static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_ } } else if (value->op == IR_IF) { /* remove one way IF/SWITCH */ - ir_sccp_remove_if(ctx, _values, i, value->op1); + ir_sccp_remove_if(ctx, _values, i, value->single_output); } else if (value->op == IR_MERGE) { /* schedule merge to remove unfeasible MERGE inputs */ ir_bitqueue_add(worklist, i); @@ -1108,6 +1186,16 @@ static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_ /* Iterative Optimizations */ /***************************/ +void ir_iter_add_uses(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) +{ + ir_use_list *use_list = &ctx->use_lists[ref]; + ir_ref *p, n = use_list->count; + + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { + ir_bitqueue_add(worklist, *p); + } +} + /* Modification of some instruction may open new optimization oprtunities for other * instructions that use this one. * @@ -1119,16 +1207,16 @@ static IR_NEVER_INLINE void ir_sccp_transform(ir_ctx *ctx, ir_insn *_values, ir_ * * TODO: Think abput a more general solution ??? */ -static void ir_iter_add_related_uses(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) +static void ir_iter_add_related_uses(const ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; if (insn->op == IR_ADD || insn->op == IR_SUB) { - ir_use_list *use_list = &ctx->use_lists[ref]; + const ir_use_list *use_list = &ctx->use_lists[ref]; if (use_list->count == 1) { ir_ref use = ctx->use_edges[use_list->refs]; - ir_insn *use_insn = &ctx->ir_base[ref]; + const ir_insn *use_insn = &ctx->ir_base[ref]; if (use_insn->op == IR_ADD || use_insn->op == IR_SUB) { ir_bitqueue_add(worklist, use); @@ -1150,7 +1238,7 @@ static void ir_iter_remove_insn(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) ir_ref input = *p; *p = IR_UNUSED; if (input > 0) { - ir_use_list_remove_all(ctx, input, ref); + ir_use_list_remove_one(ctx, input, ref); if (ir_is_dead(ctx, input)) { /* schedule DCE */ ir_bitqueue_add(worklist, input); @@ -1218,7 +1306,7 @@ static void ir_iter_replace_insn(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bit ir_ref input = *p; *p = IR_UNUSED; if (input > 0) { - ir_use_list_remove_all(ctx, input, ref); + ir_use_list_remove_one(ctx, input, ref); if (ir_is_dead(ctx, input)) { /* schedule DCE */ ir_bitqueue_add(worklist, input); @@ -1253,16 +1341,17 @@ void ir_iter_update_op(ir_ctx *ctx, ir_ref ref, uint32_t idx, ir_ref new_val, ir } } -static ir_ref ir_iter_find_cse1(ir_ctx *ctx, uint32_t optx, ir_ref op1) +static ir_ref ir_iter_find_cse1(const ir_ctx *ctx, uint32_t optx, ir_ref op1) { IR_ASSERT(!IR_IS_CONST_REF(op1)); - ir_use_list *use_list = &ctx->use_lists[op1]; - ir_ref *p, n = use_list->count; + const ir_use_list *use_list = &ctx->use_lists[op1]; + const ir_ref *p; + ir_ref n = use_list->count; for (p = ctx->use_edges + use_list->refs; n > 0; p++, n--) { ir_ref use = *p; - ir_insn *use_insn = &ctx->ir_base[use]; + const ir_insn *use_insn = &ctx->ir_base[use]; if (use_insn->optx == optx) { IR_ASSERT(use_insn->op1 == op1); @@ -1272,12 +1361,13 @@ static ir_ref ir_iter_find_cse1(ir_ctx *ctx, uint32_t optx, ir_ref op1) return IR_UNUSED; } -static ir_ref ir_iter_find_cse(ir_ctx *ctx, ir_ref ref, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3, ir_bitqueue *worklist) +static ir_ref ir_iter_find_cse(const ir_ctx *ctx, ir_ref ref, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3, ir_bitqueue *worklist) { uint32_t n = IR_INPUT_EDGES_COUNT(ir_op_flags[opt & IR_OPT_OP_MASK]); - ir_use_list *use_list = NULL; - ir_ref *p, use; - ir_insn *use_insn; + const ir_use_list *use_list = NULL; + const ir_ref *p; + ir_ref use; + const ir_insn *use_insn; if (n == 2) { if (!IR_IS_CONST_REF(op1)) { @@ -1304,8 +1394,8 @@ static ir_ref ir_iter_find_cse(ir_ctx *ctx, ir_ref ref, uint32_t opt, ir_ref op1 } } } else if (n < 2) { - IR_ASSERT(n == 1); - if (!IR_IS_CONST_REF(op1)) { + if (op1 > 0) { + IR_ASSERT(n == 1); use_list = &ctx->use_lists[op1]; n = use_list->count; for (p = ctx->use_edges + use_list->refs; n > 0; p++, n--) { @@ -1333,7 +1423,7 @@ static ir_ref ir_iter_find_cse(ir_ctx *ctx, ir_ref ref, uint32_t opt, ir_ref op1 if (!IR_IS_CONST_REF(op2) && (!use_list || use_list->count > ctx->use_lists[op2].count)) { use_list = &ctx->use_lists[op2]; } - if (!IR_IS_CONST_REF(op3) && (!use_list || use_list->count > ctx->use_lists[op3].count)) { + if (op3 > 0 && (!use_list || use_list->count > ctx->use_lists[op3].count)) { use_list = &ctx->use_lists[op3]; } if (use_list) { @@ -1360,7 +1450,8 @@ static void ir_iter_fold(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) { uint32_t opt; ir_ref op1, op2, op3, copy; - ir_insn *op1_insn, *op2_insn, *op3_insn, *insn; + const ir_insn *op1_insn, *op2_insn, *op3_insn; + ir_insn *insn; insn = &ctx->ir_base[ref]; opt = insn->opt; @@ -1395,9 +1486,6 @@ static void ir_iter_fold(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) || insn->op2 != ctx->fold_insn.op2 || insn->op3 != ctx->fold_insn.op3) { - ir_use_list *use_list; - ir_ref n, j, *p, use; - insn->optx = ctx->fold_insn.opt; IR_ASSERT(!IR_OP_HAS_VAR_INPUTS(ir_op_flags[opt & IR_OPT_OP_MASK])); insn->inputs_count = IR_INPUT_EDGES_COUNT(ir_op_flags[opt & IR_OPT_OP_MASK]); @@ -1429,12 +1517,7 @@ static void ir_iter_fold(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) insn->op2 = ctx->fold_insn.op2; insn->op3 = ctx->fold_insn.op3; - use_list = &ctx->use_lists[ref]; - n = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { - use = *p; - ir_bitqueue_add(worklist, use); - } + ir_iter_add_uses(ctx, ref, worklist); } break; case IR_FOLD_DO_COPY: @@ -1451,9 +1534,9 @@ static void ir_iter_fold(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) } } -static bool ir_may_promote_d2f(ir_ctx *ctx, ir_ref ref) +static bool ir_may_promote_d2f(const ir_ctx *ctx, ir_ref ref) { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; IR_ASSERT(insn->type == IR_DOUBLE); if (IR_IS_CONST_REF(ref)) { @@ -1484,9 +1567,9 @@ static bool ir_may_promote_d2f(ir_ctx *ctx, ir_ref ref) return 0; } -static bool ir_may_promote_f2d(ir_ctx *ctx, ir_ref ref) +static bool ir_may_promote_f2d(const ir_ctx *ctx, ir_ref ref) { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; IR_ASSERT(insn->type == IR_FLOAT); if (IR_IS_CONST_REF(ref)) { @@ -1495,8 +1578,8 @@ static bool ir_may_promote_f2d(ir_ctx *ctx, ir_ref ref) switch (insn->op) { case IR_FP2FP: return 1; - case IR_INT2FP: - return ctx->use_lists[ref].count == 1; +// case IR_INT2FP: +// return ctx->use_lists[ref].count == 1; case IR_NEG: case IR_ABS: return ctx->use_lists[ref].count == 1 && @@ -1655,10 +1738,11 @@ static ir_ref ir_promote_f2d(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_bitqueue *w return ref; } -static bool ir_may_promote_trunc(ir_ctx *ctx, ir_type type, ir_ref ref) +static bool ir_may_promote_trunc(const ir_ctx *ctx, ir_type type, ir_ref ref) { - ir_insn *insn = &ctx->ir_base[ref]; - ir_ref *p, n, input; + const ir_insn *insn = &ctx->ir_base[ref]; + const ir_ref *p; + ir_ref n, input; if (IR_IS_CONST_REF(ref)) { return !IR_IS_SYM_CONST(insn->op); @@ -1732,7 +1816,20 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use, ir_ref *p, n, input; if (IR_IS_CONST_REF(ref)) { - return ir_const(ctx, insn->val, type); + ir_val val; + + switch (type) { + case IR_I8: val.i64 = insn->val.i8; break; + case IR_U8: val.u64 = insn->val.u8; break; + case IR_I16: val.i64 = insn->val.i16; break; + case IR_U16: val.u64 = insn->val.u16; break; + case IR_I32: val.i64 = insn->val.i32; break; + case IR_U32: val.u64 = insn->val.u32; break; + case IR_CHAR:val.i64 = insn->val.i8; break; + case IR_BOOL:val.u64 = insn->val.u8 != 0; break; + default: IR_ASSERT(0); val.u64 = 0; + } + return ir_const(ctx, val, type); } else { ir_bitqueue_add(worklist, ref); switch (insn->op) { @@ -1751,6 +1848,7 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use, } } insn->type = type; + ir_iter_add_uses(ctx, ref, worklist); return ref; } @@ -1813,6 +1911,46 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use, insn->op3 = ir_promote_i2i(ctx, type, insn->op3, ref, worklist); } insn->type = type; + if (IR_IS_TYPE_SIGNED(type)) { + ir_insn *cond = &ctx->ir_base[insn->op1]; + if (cond->op == IR_LT || cond->op == IR_LE || cond->op == IR_GT || cond->op == IR_GE) { + if (cond->op1 == insn->op2 && cond->op2 == insn->op3) { + insn->op = (cond->op == IR_LT || cond->op == IR_LE) ? IR_MIN : IR_MAX; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } else if (cond->op1 == insn->op3 && cond->op2 == insn->op1) { + insn->op = (cond->op == IR_LT || cond->op == IR_LE) ? IR_MAX : IR_MIN; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } + } + } else { + IR_ASSERT(IR_IS_TYPE_UNSIGNED(type)); + ir_insn *cond = &ctx->ir_base[insn->op1]; + if (cond->op == IR_ULT || cond->op == IR_ULE || cond->op == IR_UGT || cond->op == IR_UGE) { + if (cond->op1 == insn->op2 && cond->op2 == insn->op3) { + insn->op = (cond->op == IR_ULT || cond->op == IR_ULE) ? IR_MIN : IR_MAX; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } else if (cond->op1 == insn->op3 && cond->op2 == insn->op1) { + insn->op = (cond->op == IR_ULT || cond->op == IR_ULE) ? IR_MAX : IR_MIN; + ir_use_list_remove_one(ctx, insn->op1, ref); + ir_bitqueue_add(worklist, insn->op1); + insn->op1 = insn->op2; + insn->op2 = insn->op3; + insn->op3 = IR_UNUSED; + } + } + } return ref; case IR_PHI: for (p = insn->ops + 2, n = insn->inputs_count - 1; n > 0; p++, n--) { @@ -1831,7 +1969,7 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use, return ref; } -static ir_ref ir_ext_const(ir_ctx *ctx, ir_insn *val_insn, ir_op op, ir_type type) +static ir_ref ir_ext_const(ir_ctx *ctx, const ir_insn *val_insn, ir_op op, ir_type type) { ir_val new_val; @@ -1841,6 +1979,7 @@ static ir_ref ir_ext_const(ir_ctx *ctx, ir_insn *val_insn, ir_op op, ir_type typ case IR_I8: case IR_U8: case IR_BOOL: + case IR_CHAR: if (op == IR_SEXT) { new_val.i64 = (int64_t)val_insn->val.i8; } else { @@ -1894,12 +2033,13 @@ static ir_ref ir_ext_ref(ir_ctx *ctx, ir_ref var_ref, ir_ref src_ref, ir_op op, return ref; } -static uint32_t _ir_estimated_control(ir_ctx *ctx, ir_ref val) +static uint32_t _ir_estimated_control(const ir_ctx *ctx, ir_ref val, ir_ref loop) { - ir_insn *insn; - ir_ref n, *p, input, result, ctrl; + const ir_insn *insn; + const ir_ref *p; + ir_ref n, input, result, ctrl; - if (IR_IS_CONST_REF(val)) { + if (val <= 0) { /* constant or IR_UNUSED */ return 1; /* IR_START */ } @@ -1919,7 +2059,8 @@ static uint32_t _ir_estimated_control(ir_ctx *ctx, ir_ref val) result = 1; for (; n > 0; p++, n--) { input = *p; - ctrl = _ir_estimated_control(ctx, input); + ctrl = _ir_estimated_control(ctx, input, loop); + if (ctrl >= loop) return ctrl; if (ctrl > result) { // TODO: check dominance depth instead of order result = ctrl; } @@ -1927,18 +2068,18 @@ static uint32_t _ir_estimated_control(ir_ctx *ctx, ir_ref val) return result; } -static bool ir_is_loop_invariant(ir_ctx *ctx, ir_ref ref, ir_ref loop) +static bool ir_is_loop_invariant(const ir_ctx *ctx, ir_ref ref, ir_ref loop) { - ref = _ir_estimated_control(ctx, ref); + ref = _ir_estimated_control(ctx, ref, loop); return ref < loop; // TODO: check dominance instead of order } -static bool ir_is_cheaper_ext(ir_ctx *ctx, ir_ref ref, ir_ref loop, ir_ref ext_ref, ir_op op) +static bool ir_is_cheaper_ext(const ir_ctx *ctx, ir_ref ref, ir_ref loop, ir_ref ext_ref, ir_op op) { if (IR_IS_CONST_REF(ref)) { return 1; } else { - ir_insn *insn = &ctx->ir_base[ref]; + const ir_insn *insn = &ctx->ir_base[ref]; if (insn->op == IR_LOAD) { if (ir_is_loop_invariant(ctx, ref, loop)) { @@ -1954,7 +2095,7 @@ static bool ir_is_cheaper_ext(ir_ctx *ctx, ir_ref ref, ir_ref loop, ir_ref ext_r for (p = &ctx->use_edges[use_list->refs], n = use_list->count; n > 0; p++, n--) { use = *p; if (use != ext_ref) { - ir_insn *use_insn = &ctx->ir_base[use]; + const ir_insn *use_insn = &ctx->ir_base[use]; if (use_insn->op != op && (!(ir_op_flags[use_insn->op] & (IR_OP_FLAG_CONTROL|IR_OP_FLAG_MEM)) @@ -1990,7 +2131,7 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref if (use == op_ref || use == ext_ref) { continue; } else { - ir_insn *use_insn = &ctx->ir_base[use]; + const ir_insn *use_insn = &ctx->ir_base[use]; if (use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) { if (use_insn->op1 == phi_ref) { @@ -2029,17 +2170,17 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref if (use == phi_ref || use == ext_ref) { continue; } else { - ir_insn *use_insn = &ctx->ir_base[use]; + const ir_insn *use_insn = &ctx->ir_base[use]; if (use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) { - if (use_insn->op1 == phi_ref) { + if (use_insn->op1 == op_ref) { if (IR_IS_TYPE_SIGNED(type) != IR_IS_TYPE_SIGNED(ctx->ir_base[use_insn->op2].type)) { return 0; } if (ir_is_cheaper_ext(ctx, use_insn->op2, ctx->ir_base[phi_ref].op1, ext_ref, op)) { continue; } - } else if (use_insn->op2 == phi_ref) { + } else if (use_insn->op2 == op_ref) { if (IR_IS_TYPE_SIGNED(type) != IR_IS_TYPE_SIGNED(ctx->ir_base[use_insn->op1].type)) { return 0; } @@ -2082,7 +2223,9 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op1].op)) { ctx->ir_base[use].op1 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op1], op, type); } else { - ctx->ir_base[use].op1 = ir_ext_ref(ctx, use, use_insn->op1, op, type, worklist); + ir_ref tmp = ir_ext_ref(ctx, use, use_insn->op1, op, type, worklist); + use_insn = &ctx->ir_base[use]; + use_insn->op1 = tmp; } ir_bitqueue_add(worklist, use); } @@ -2091,7 +2234,9 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op2].op)) { ctx->ir_base[use].op2 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op2], op, type); } else { - ctx->ir_base[use].op2 = ir_ext_ref(ctx, use, use_insn->op2, op, type, worklist); + ir_ref tmp = ir_ext_ref(ctx, use, use_insn->op2, op, type, worklist); + use_insn = &ctx->ir_base[use]; + use_insn->op2 = tmp; } ir_bitqueue_add(worklist, use); } @@ -2119,7 +2264,9 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op1].op)) { ctx->ir_base[use].op1 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op1], op, type); } else { - ctx->ir_base[use].op1 = ir_ext_ref(ctx, use, use_insn->op1, op, type, worklist); + ir_ref tmp = ir_ext_ref(ctx, use, use_insn->op1, op, type, worklist); + use_insn = &ctx->ir_base[use]; + use_insn->op1 = tmp; } ir_bitqueue_add(worklist, use); } @@ -2128,7 +2275,9 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op2].op)) { ctx->ir_base[use].op2 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op2], op, type); } else { - ctx->ir_base[use].op2 = ir_ext_ref(ctx, use, use_insn->op2, op, type, worklist); + ir_ref tmp = ir_ext_ref(ctx, use, use_insn->op2, op, type, worklist); + use_insn = &ctx->ir_base[use]; + use_insn->op2 = tmp; } ir_bitqueue_add(worklist, use); } @@ -2150,14 +2299,15 @@ static bool ir_try_promote_induction_var_ext(ir_ctx *ctx, ir_ref ext_ref, ir_ref && !IR_IS_SYM_CONST(ctx->ir_base[phi_insn->op2].op)) { ctx->ir_base[phi_ref].op2 = ir_ext_const(ctx, &ctx->ir_base[phi_insn->op2], op, type); } else { - ctx->ir_base[phi_ref].op2 = ir_ext_ref(ctx, phi_ref, phi_insn->op2, op, type, worklist); + ir_ref tmp = ir_ext_ref(ctx, phi_ref, phi_insn->op2, op, type, worklist); + ctx->ir_base[phi_ref].op2 = tmp; } return 1; } static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bitqueue *worklist) - { +{ ir_ref ref = insn->op1; /* Check for simple induction variable in the form: x2 = PHI(loop, x1, x3); x3 = ADD(x2, _); */ @@ -2223,42 +2373,6 @@ static void ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin, ir_bitqueue * ir_ref prev, next; ir_use_list *use_list; - if (ctx->use_lists[begin].count > 1) { - ir_ref *p, n, i, use; - ir_insn *use_insn; - ir_ref region = end; - ir_ref next = IR_UNUSED; - - while (!IR_IS_BB_START(ctx->ir_base[region].op)) { - region = ctx->ir_base[region].op1; - } - - use_list = &ctx->use_lists[begin]; - n = use_list->count; - for (p = &ctx->use_edges[use_list->refs], i = 0; i < n; p++, i++) { - use = *p; - use_insn = &ctx->ir_base[use]; - if (ir_op_flags[use_insn->op] & IR_OP_FLAG_CONTROL) { - IR_ASSERT(!next); - next = use; - } else { - IR_ASSERT(use_insn->op == IR_VAR); - IR_ASSERT(use_insn->op1 == begin); - use_insn->op1 = region; - if (ir_use_list_add(ctx, region, use)) { - /* restore after reallocation */ - use_list = &ctx->use_lists[begin]; - n = use_list->count; - p = &ctx->use_edges[use_list->refs + i]; - } - } - } - - IR_ASSERT(next); - ctx->use_edges[use_list->refs] = next; - use_list->count = 1; - } - IR_ASSERT(ctx->ir_base[begin].op == IR_BEGIN); IR_ASSERT(ctx->ir_base[end].op == IR_END); IR_ASSERT(ctx->ir_base[begin].op1 == end); @@ -2358,7 +2472,7 @@ static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, next->op1 = root->op1; ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); if (!IR_IS_CONST_REF(root->op2)) { - ir_use_list_remove_all(ctx, root->op2, root_ref); + ir_use_list_remove_one(ctx, root->op2, root_ref); if (ir_is_dead(ctx, root->op2)) { ir_bitqueue_add(worklist, root->op2); } @@ -2391,7 +2505,7 @@ static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, } start_ref = end->op1; start = &ctx->ir_base[start_ref]; - if (start->op != IR_CASE_VAL && start->op != IR_CASE_DEFAULT) { + if (start->op != IR_CASE_VAL && start->op != IR_CASE_RANGE && start->op != IR_CASE_DEFAULT) { return 0; } if (ctx->use_lists[start_ref].count != 1) { @@ -2416,7 +2530,7 @@ static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); if (!IR_IS_CONST_REF(root->op2)) { - ir_use_list_remove_all(ctx, root->op2, root_ref); + ir_use_list_remove_one(ctx, root->op2, root_ref); if (ir_is_dead(ctx, root->op2)) { ir_bitqueue_add(worklist, root->op2); } @@ -2444,13 +2558,59 @@ static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, } } -static bool ir_is_zero(ir_ctx *ctx, ir_ref ref) +static bool ir_is_zero(const ir_ctx *ctx, ir_ref ref) { return IR_IS_CONST_REF(ref) && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) && ctx->ir_base[ref].val.u32 == 0; } +static bool ir_fix_min_max_const(ir_ctx *ctx, ir_insn *cond, ir_ref ref) +{ + if (cond->op == IR_ULE) { + /* (x <= 3 ? 4 : x) => (x < 4 ? 4 : x) => max(x, 4) */ + /* (x <= 3 ? x : 4) => (x < 4 ? x : 4) => min(x, 4) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.u64 == ctx->ir_base[ref].val.u64 - 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } else if (cond->op == IR_UGE) { + /* (x >= 3 ? 2 : x) => (x > 2 ? 2 : x) => min(x, 2) */ + /* (x >= 3 ? x : 2) => (x > 2 ? x : 2) => max(x, 2) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.u64 == ctx->ir_base[ref].val.u64 + 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } else if (cond->op == IR_LE) { + /* (x <= 3 ? 4 : x) => (x < 4 ? 4 : x) => max(x, 4) */ + /* (x <= 3 ? x : 4) => (x < 4 ? x : 4) => min(x, 4) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.u64 == ctx->ir_base[ref].val.u64 - 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } else if (cond->op == IR_GE) { + /* (x >= 3 ? 2 : x) => (x > 2 ? 2 : x) => min(x, 2) */ + /* (x >= 3 ? x : 2) => (x > 2 ? x : 2) => max(x, 2) */ + if (!IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) + && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) + && ctx->ir_base[cond->op2].val.i64 == ctx->ir_base[ref].val.i64 + 1 + && ctx->ir_base[cond->op2].type == ctx->ir_base[ref].type) { + cond->op2 = ref; + return 1; + } + } + return 0; +} + static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist) { IR_ASSERT(insn->inputs_count == 3); @@ -2469,7 +2629,7 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re ir_ref root_ref = start1->op1; ir_insn *root = &ctx->ir_base[root_ref]; - if (root->op == IR_IF && !IR_IS_CONST_REF(root->op2) && ctx->use_lists[root->op2].count == 1) { + if (root->op == IR_IF && !IR_IS_CONST_REF(root->op2)) { ir_ref cond_ref = root->op2; ir_insn *cond = &ctx->ir_base[cond_ref]; ir_type type = insn->type; @@ -2490,8 +2650,18 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re } if (is_cmp - && ((insn->op2 == cond->op1 && insn->op3 == cond->op2) - || (insn->op2 == cond->op2 && insn->op3 == cond->op1))) { + && ((insn->op2 == cond->op1 + && (insn->op3 == cond->op2 + || (IR_IS_CONST_REF(cond->op2) + && (IR_IS_CONST_REF(insn->op3) + && IR_IS_TYPE_INT(insn->type) + && ir_fix_min_max_const(ctx, cond, insn->op3))))) + || (insn->op3 == cond->op1 + && (insn->op2 == cond->op2 + || (IR_IS_CONST_REF(cond->op2) + && (IR_IS_CONST_REF(insn->op2) + && IR_IS_TYPE_INT(insn->type) + && ir_fix_min_max_const(ctx, cond, insn->op2))))))) { /* MAX/MIN * * prev prev @@ -2542,14 +2712,18 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re next->op1 = root->op1; ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); - if (!IR_IS_CONST_REF(insn->op1)) { - ir_use_list_remove_all(ctx, insn->op1, cond_ref); - } - if (!IR_IS_CONST_REF(insn->op2)) { - ir_use_list_remove_all(ctx, insn->op2, cond_ref); - } - MAKE_NOP(cond); CLEAR_USES(cond_ref); + if (ctx->use_lists[cond_ref].count == 1) { + if (!IR_IS_CONST_REF(insn->op1)) { + ir_use_list_remove_one(ctx, insn->op1, cond_ref); + } + if (!IR_IS_CONST_REF(insn->op2)) { + ir_use_list_remove_one(ctx, insn->op2, cond_ref); + } + MAKE_NOP(cond); CLEAR_USES(cond_ref); + } else { + ir_use_list_remove_one(ctx, cond_ref, root_ref); + } MAKE_NOP(root); CLEAR_USES(root_ref); MAKE_NOP(start1); CLEAR_USES(start1_ref); MAKE_NOP(start2); CLEAR_USES(start2_ref); @@ -2631,11 +2805,15 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re next->op1 = root->op1; ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); ir_use_list_remove_one(ctx, insn->op1, neg_ref); - if (!IR_IS_CONST_REF(insn->op1)) { - ir_use_list_remove_all(ctx, insn->op1, cond_ref); - } - MAKE_NOP(cond); CLEAR_USES(cond_ref); + if (ctx->use_lists[cond_ref].count == 1) { + if (!IR_IS_CONST_REF(insn->op1)) { + ir_use_list_remove_one(ctx, insn->op1, cond_ref); + } + MAKE_NOP(cond); CLEAR_USES(cond_ref); + } else { + ir_use_list_remove_one(ctx, cond_ref, root_ref); + } MAKE_NOP(root); CLEAR_USES(root_ref); MAKE_NOP(start1); CLEAR_USES(start1_ref); MAKE_NOP(start2); CLEAR_USES(start2_ref); @@ -2649,8 +2827,16 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re } return 1; -#if 0 - } else { + } else if (insn->op2 <= root_ref && insn->op3 <= root_ref + && cond->op != IR_OVERFLOW + // TODO: temporary disable IF-conversion for RLOAD. + // We don't track anti-dependencies in GCM and Local Scheduling. + // As result COND may be scheduled below the following RSTORE. + // See: https://github.com/dstogov/ir/issues/132 + && cond->op != IR_RLOAD + && !((cond->op >= IR_EQ && cond->op <= IR_UNORDERED) + && ((!IR_IS_CONST_REF(cond->op1) && ctx->ir_base[cond->op1].op == IR_RLOAD) + || (!IR_IS_CONST_REF(cond->op2) && ctx->ir_base[cond->op2].op == IR_RLOAD)))) { /* COND * * prev prev @@ -2695,7 +2881,7 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re next->op1 = root->op1; ir_use_list_replace_one(ctx, cond_ref, root_ref, ref); ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); - ir_use_list_remove_all(ctx, root->op2, root_ref); + ir_use_list_remove_one(ctx, root->op2, root_ref); MAKE_NOP(root); CLEAR_USES(root_ref); MAKE_NOP(start1); CLEAR_USES(start1_ref); @@ -2704,12 +2890,12 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re MAKE_NOP(end2); CLEAR_USES(end2_ref); MAKE_NOP(merge); CLEAR_USES(merge_ref); + ir_bitqueue_add(worklist, ref); if (ctx->ir_base[next->op1].op == IR_BEGIN || ctx->ir_base[next->op1].op == IR_MERGE) { ir_bitqueue_add(worklist, next->op1); } return 1; -#endif } } } @@ -2718,7 +2904,7 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re return 0; } -static bool ir_cmp_is_true(ir_op op, ir_insn *op1, ir_insn *op2) +static bool ir_cmp_is_true(ir_op op, const ir_insn *op1, const ir_insn *op2) { IR_ASSERT(op1->type == op2->type); if (IR_IS_TYPE_INT(op1->type)) { @@ -2783,6 +2969,10 @@ static bool ir_cmp_is_true(ir_op op, ir_insn *op1, ir_insn *op2) return !(op1->val.d > op2->val.d); } else if (op == IR_UGT) { return !(op1->val.d <= op2->val.d); + } else if (op == IR_ORDERED) { + return !isnan(op1->val.d) && !isnan(op2->val.d); + } else if (op == IR_UNORDERED) { + return isnan(op1->val.d) || isnan(op2->val.d); } else { IR_ASSERT(0); return 0; @@ -2809,6 +2999,10 @@ static bool ir_cmp_is_true(ir_op op, ir_insn *op1, ir_insn *op2) return !(op1->val.f > op2->val.f); } else if (op == IR_UGT) { return !(op1->val.f <= op2->val.f); + } else if (op == IR_ORDERED) { + return !isnan(op1->val.f) && !isnan(op2->val.f); + } else if (op == IR_UNORDERED) { + return isnan(op1->val.f) || isnan(op2->val.f); } else { IR_ASSERT(0); return 0; @@ -2884,9 +3078,11 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue if_false->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_false->op1 = end1_ref; + if_false->op2 = IR_UNUSED; if_true->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_true->op1 = end2_ref; + if_true->op2 = IR_UNUSED; ir_bitqueue_add(worklist, if_false_ref); ir_bitqueue_add(worklist, if_true_ref); @@ -2924,6 +3120,7 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue if_true->optx = IR_BEGIN; if_true->op1 = IR_UNUSED; + if_true->op2 = IR_UNUSED; ctx->flags2 &= ~IR_CFG_REACHABLE; @@ -2951,8 +3148,8 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue * IF_FALSE | MERGE * | | */ - ir_use_list_remove_all(ctx, merge_ref, cond_ref); - ir_use_list_remove_all(ctx, ref, if_true_ref); + ir_use_list_remove_one(ctx, merge_ref, cond_ref); + ir_use_list_remove_one(ctx, ref, if_true_ref); if (!IR_IS_CONST_REF(cond->op3)) { ir_use_list_replace_one(ctx, cond->op3, cond_ref, end2_ref); } @@ -2961,6 +3158,7 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue end2->optx = IR_OPTX(IR_IF, IR_VOID, 2); end2->op2 = cond->op3; + ir_bitqueue_add(worklist, end2_ref); merge->optx = IR_OPTX(op, IR_VOID, 1); merge->op1 = end2_ref; @@ -3072,9 +3270,11 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu if_false->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_false->op1 = end1_ref; + if_false->op2 = IR_UNUSED; if_true->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1); if_true->op1 = end2_ref; + if_true->op2 = IR_UNUSED; ir_bitqueue_add(worklist, if_false_ref); ir_bitqueue_add(worklist, if_true_ref); @@ -3116,6 +3316,7 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu if_true->optx = IR_BEGIN; if_true->op1 = IR_UNUSED; + if_true->op2 = IR_UNUSED; ctx->flags2 &= ~IR_CFG_REACHABLE; @@ -3145,8 +3346,8 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu * | | */ - ir_use_list_remove_all(ctx, merge_ref, phi_ref); - ir_use_list_remove_all(ctx, ref, if_true_ref); + ir_use_list_remove_one(ctx, merge_ref, phi_ref); + ir_use_list_remove_one(ctx, ref, if_true_ref); if (!IR_IS_CONST_REF(phi->op3)) { ir_use_list_replace_one(ctx, phi->op3, phi_ref, insn->op2); } @@ -3156,6 +3357,7 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu end2->optx = IR_OPTX(IR_IF, IR_VOID, 2); end2->op2 = insn->op2; + ir_bitqueue_add(worklist, end2_ref); merge->optx = IR_OPTX(op, IR_VOID, 1); merge->op1 = end2_ref; @@ -3235,7 +3437,7 @@ static void ir_iter_optimize_merge(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge } } -static ir_ref ir_find_ext_use(ir_ctx *ctx, ir_ref ref) +static ir_ref ir_find_ext_use(const ir_ctx *ctx, ir_ref ref) { ir_use_list *use_list = &ctx->use_lists[ref]; ir_ref *p, n, use; @@ -3335,6 +3537,13 @@ static ir_ref ir_iter_optimize_condition(ir_ctx *ctx, ir_ref control, ir_ref con } } + if (condition_insn->op == IR_SHL && IR_IS_CONST_REF(condition_insn->op1)) { + ir_insn *val_insn = &ctx->ir_base[condition_insn->op1]; + if (!IR_IS_SYM_CONST(val_insn->op) && val_insn->val.u64 == 1) { + return IR_TRUE; + } + } + while ((condition_insn->op == IR_BITCAST || condition_insn->op == IR_ZEXT || condition_insn->op == IR_SEXT) @@ -3401,7 +3610,9 @@ static void ir_iter_optimize_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu if_true = &ctx->ir_base[if_true_ref]; if_false = &ctx->ir_base[if_false_ref]; if_true->op = IR_BEGIN; + if_true->op2 = IR_UNUSED; if_false->op = IR_BEGIN; + if_false->op2 = IR_UNUSED; if (ir_ref_is_true(ctx, condition)) { if_false->op1 = IR_UNUSED; ir_use_list_remove_one(ctx, ref, if_false_ref); @@ -3438,9 +3649,18 @@ static void ir_iter_optimize_guard(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bi remove_guard: prev = insn->op1; next = ir_next_control(ctx, ref); + if (ctx->ir_base[prev].op == IR_SNAPSHOT) { + ir_ref snapshot = prev; + prev = ctx->ir_base[prev].op1; + ir_use_list_remove_one(ctx, snapshot, ref); + ir_use_list_remove_one(ctx, ref, next); + ir_use_list_replace_one(ctx, prev, snapshot, next); + ir_iter_remove_insn(ctx, snapshot, worklist); + } else { + ir_use_list_remove_one(ctx, ref, next); + ir_use_list_replace_one(ctx, prev, ref, next); + } ctx->ir_base[next].op1 = prev; - ir_use_list_remove_one(ctx, ref, next); - ir_use_list_replace_one(ctx, prev, ref, next); insn->op1 = IR_UNUSED; if (!IR_IS_CONST_REF(insn->op2)) { @@ -3451,9 +3671,12 @@ static void ir_iter_optimize_guard(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bi } } - if (insn->op3) { - /* SNAPSHOT */ - ir_iter_remove_insn(ctx, insn->op3, worklist); + if (!IR_IS_CONST_REF(insn->op3)) { + ir_use_list_remove_one(ctx, insn->op3, ref); + if (ir_is_dead(ctx, insn->op3)) { + /* schedule DCE */ + ir_bitqueue_add(worklist, insn->op3); + } } MAKE_NOP(insn); @@ -3545,7 +3768,10 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist) if (!(ctx->flags & IR_OPT_CFG)) { /* pass */ } else if (insn->op == IR_BEGIN) { - if (insn->op1 && ctx->ir_base[insn->op1].op == IR_END) { + if (insn->op1 + && !insn->op2 /* no computed goto label */ + && ctx->use_lists[i].count == 1 + && ctx->ir_base[insn->op1].op == IR_END) { ir_merge_blocks(ctx, insn->op1, i, worklist); } } else if (insn->op == IR_MERGE) { @@ -3602,6 +3828,7 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist) insn->op1 = val; insn->op2 = IR_UNUSED; ir_bitqueue_add(worklist, i); + ir_iter_add_uses(ctx, i, worklist); } } } else if (insn->op == IR_STORE) { @@ -3648,14 +3875,55 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist) } } +void ir_iter_cleanup(ir_ctx *ctx) +{ + ir_bitqueue iter_worklist; + ir_bitqueue cfg_worklist; + ir_ref i, n; + ir_insn *insn; + + ir_bitqueue_init(&cfg_worklist, ctx->insns_count); + ir_bitqueue_init(&iter_worklist, ctx->insns_count); + + /* Remove unused nodes */ + for (i = IR_UNUSED + 1, insn = ctx->ir_base + i; i < ctx->insns_count;) { + if (IR_IS_FOLDABLE_OP(insn->op)) { + if (insn->op != IR_NOP && ctx->use_lists[i].count == 0) { + ir_iter_remove_insn(ctx, i, &iter_worklist); + } + } else if (insn->op == IR_IF || insn->op == IR_MERGE) { + ir_bitqueue_add(&cfg_worklist, i); + } + n = insn->inputs_count; + n = ir_insn_inputs_to_len(n); + i += n; + insn += n; + } + + while ((i = ir_bitqueue_pop(&iter_worklist)) >= 0) { + insn = &ctx->ir_base[i]; + if (IR_IS_FOLDABLE_OP(insn->op)) { + if (ctx->use_lists[i].count == 0) { + ir_iter_remove_insn(ctx, i, &iter_worklist); + } + } + } + + /* Cleanup Control Flow */ + ir_iter_opt(ctx, &cfg_worklist); + + ir_bitqueue_free(&iter_worklist); + ir_bitqueue_free(&cfg_worklist); +} + int ir_sccp(ir_ctx *ctx) { ir_bitqueue sccp_worklist, iter_worklist; - ir_insn *_values; + ir_sccp_val *_values; ir_bitqueue_init(&iter_worklist, ctx->insns_count); ir_bitqueue_init(&sccp_worklist, ctx->insns_count); - _values = ir_mem_calloc(ctx->insns_count, sizeof(ir_insn)); + _values = ir_mem_calloc(ctx->insns_count, sizeof(ir_sccp_val)); ctx->flags2 |= IR_OPT_IN_SCCP; ir_sccp_analyze(ctx, _values, &sccp_worklist, &iter_worklist); diff --git a/ext/opcache/jit/ir/ir_x86.dasc b/ext/opcache/jit/ir/ir_x86.dasc index 76602c2b4bcf..ca42001a8816 100644 --- a/ext/opcache/jit/ir/ir_x86.dasc +++ b/ext/opcache/jit/ir/ir_x86.dasc @@ -66,7 +66,7 @@ IR_ALWAYS_INLINE ir_mem IR_MEM(ir_reg base, int32_t offset, ir_reg index, int32_ #define IR_SPILL_POS_TO_OFFSET(offset) \ ((ctx->flags & IR_USE_FRAME_POINTER) ? \ - ((offset) - (ctx->stack_frame_size - ctx->stack_frame_alignment)) : \ + ((offset) - ctx->stack_frame_size) : \ ((offset) + ctx->call_stack_size)) |.macro ASM_EXPAND_OP_MEM, MACRO, op, type, op1 @@ -882,8 +882,7 @@ IR_ALWAYS_INLINE ir_mem IR_MEM(ir_reg base, int32_t offset, ir_reg index, int32_ |.endmacro typedef struct _ir_backend_data { - ir_reg_alloc_data ra_data; - uint32_t dessa_from_block; + ir_reg_alloc_data ra_data; dasm_State *dasm_state; ir_bitset emit_constants; int rodata_label, jmp_table_label; @@ -892,8 +891,18 @@ typedef struct _ir_backend_data { bool double_abs_const; bool float_abs_const; bool double_zero_const; + bool u2d_const; + bool u2f_const; + bool resolved_label_syms; } ir_backend_data; +typedef struct _ir_x86_64_sysv_va_list { + uint32_t gp_offset; + uint32_t fp_offset; + void *overflow_arg_area; + void *reg_save_area; +} ir_x86_64_sysv_va_list; + #define IR_GP_REG_NAME(code, name64, name32, name16, name8, name8h) \ #name64, #define IR_GP_REG_NAME32(code, name64, name32, name16, name8, name8h) \ @@ -905,9 +914,19 @@ typedef struct _ir_backend_data { #define IR_FP_REG_NAME(code, name) \ #name, -static const char *_ir_reg_name[IR_REG_NUM] = { +static const char *_ir_reg_name[] = { IR_GP_REGS(IR_GP_REG_NAME) IR_FP_REGS(IR_FP_REG_NAME) + "ALL", + "SCRATCH", +#ifdef IR_TARGET_X64 +# ifdef _WIN64 + "SCRATCH_SYSV", +# else + "SCRATCH_MS", +# endif + "SCRATCH_PN", /* preserve none */ +#endif }; static const char *_ir_reg_name32[IR_REG_NUM] = { @@ -922,66 +941,11 @@ static const char *_ir_reg_name8[IR_REG_NUM] = { IR_GP_REGS(IR_GP_REG_NAME8) }; -/* Calling Convention */ -#ifdef _WIN64 - -static const int8_t _ir_int_reg_params[IR_REG_INT_ARGS] = { - IR_REG_INT_ARG1, - IR_REG_INT_ARG2, - IR_REG_INT_ARG3, - IR_REG_INT_ARG4, -}; - -static const int8_t _ir_fp_reg_params[IR_REG_FP_ARGS] = { - IR_REG_FP_ARG1, - IR_REG_FP_ARG2, - IR_REG_FP_ARG3, - IR_REG_FP_ARG4, -}; - -#elif defined(IR_TARGET_X64) - -static const int8_t _ir_int_reg_params[IR_REG_INT_ARGS] = { - IR_REG_INT_ARG1, - IR_REG_INT_ARG2, - IR_REG_INT_ARG3, - IR_REG_INT_ARG4, - IR_REG_INT_ARG5, - IR_REG_INT_ARG6, -}; - -static const int8_t _ir_fp_reg_params[IR_REG_FP_ARGS] = { - IR_REG_FP_ARG1, - IR_REG_FP_ARG2, - IR_REG_FP_ARG3, - IR_REG_FP_ARG4, - IR_REG_FP_ARG5, - IR_REG_FP_ARG6, - IR_REG_FP_ARG7, - IR_REG_FP_ARG8, -}; - -#else - -static const int8_t *_ir_int_reg_params = NULL; -static const int8_t *_ir_fp_reg_params = NULL; -static const int8_t _ir_int_fc_reg_params[IR_REG_INT_FCARGS] = { - IR_REG_INT_FCARG1, - IR_REG_INT_FCARG2, -}; -static const int8_t *_ir_fp_fc_reg_params = NULL; - -#endif - const char *ir_reg_name(int8_t reg, ir_type type) { if (reg >= IR_REG_NUM) { - if (reg == IR_REG_SCRATCH) { - return "SCRATCH"; - } else { - IR_ASSERT(reg == IR_REG_ALL); - return "ALL"; - } + IR_ASSERT((uint8_t)reg < sizeof(_ir_reg_name) / sizeof(_ir_reg_name[0])); + return _ir_reg_name[reg]; } IR_ASSERT(reg >= 0 && reg < IR_REG_NUM); if (type == IR_VOID) { @@ -999,6 +963,159 @@ const char *ir_reg_name(int8_t reg, ir_type type) } } +/* Calling Conventions */ +#ifdef IR_TARGET_X64 + +# ifdef _WIN64 +# define IR_REG_SCRATH_X86_64_MS IR_REG_SET_1 +# define IR_REG_SCRATH_X86_64_SYSV IR_REG_SET_2 +# define IR_REG_SCRATH_X86_64_PN IR_REG_SET_3 +# else +# define IR_REG_SCRATH_X86_64_SYSV IR_REG_SET_1 +# define IR_REG_SCRATH_X86_64_MS IR_REG_SET_2 +# define IR_REG_SCRATH_X86_64_PN IR_REG_SET_3 +# endif + +# define IR_REGSET_SCRATCH_X86_64_SYSV \ + (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) | \ + IR_REGSET_INTERVAL(IR_REG_RSI, IR_REG_RDI) | \ + IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) | \ + IR_REGSET_FP) + +# define IR_REGSET_SCRATCH_X86_64_WIN \ + (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) | \ + IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) | \ + IR_REGSET_INTERVAL(IR_REG_XMM0, IR_REG_XMM5)) + +# define IR_REGSET_SCRATCH_X86_64_PN \ + (IR_REGSET_DIFFERENCE(IR_REGSET_GP, IR_REGSET(IR_REG_RBP)) | IR_REGSET_FP) + +const ir_regset ir_scratch_regset[] = { + IR_REGSET_GP | IR_REGSET_FP, +# ifdef _WIN64 + IR_REGSET_SCRATCH_X86_64_WIN, + IR_REGSET_SCRATCH_X86_64_SYSV, +# else + IR_REGSET_SCRATCH_X86_64_SYSV, + IR_REGSET_SCRATCH_X86_64_WIN, +# endif + IR_REGSET_SCRATCH_X86_64_PN, +}; + +const ir_call_conv_dsc ir_call_conv_x86_64_ms = { + 0, /* cleanup_stack_by_callee */ + 0, /* pass_struct_by_val */ + 0, /* sysv_varargs */ + 1, /* shadow_param_regs */ + 32, /* shadow_store_size */ + 4, /* int_param_regs_count */ + 4, /* fp_param_regs_count */ + IR_REG_RAX, /* int_ret_reg */ + IR_REG_XMM0, /* fp_ret_reg */ + IR_REG_NONE, /* fp_varargs_reg */ + IR_REG_SCRATH_X86_64_MS, + (const int8_t[4]){IR_REG_RCX, IR_REG_RDX, IR_REG_R8, IR_REG_R9}, + (const int8_t[4]){IR_REG_XMM0, IR_REG_XMM1, IR_REG_XMM2, IR_REG_XMM3}, + IR_REGSET(IR_REG_RBX) | IR_REGSET(IR_REG_RBP) | IR_REGSET(IR_REG_RSI) | IR_REGSET(IR_REG_RDI) | + IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15) | IR_REGSET_INTERVAL(IR_REG_XMM6, IR_REG_XMM15), +}; + +const ir_call_conv_dsc ir_call_conv_x86_64_sysv = { + 0, /* cleanup_stack_by_callee */ + 1, /* pass_struct_by_val */ + 1, /* sysv_varargs */ + 0, /* shadow_param_regs */ + 0, /* shadow_store_size */ + 6, /* int_param_regs_count */ + 8, /* fp_param_regs_count */ + IR_REG_RAX, /* int_ret_reg */ + IR_REG_XMM0, /* fp_ret_reg */ + IR_REG_RAX, /* fp_varargs_reg */ + IR_REG_SCRATH_X86_64_SYSV, + (const int8_t[6]){IR_REG_RDI, IR_REG_RSI, IR_REG_RDX, IR_REG_RCX, IR_REG_R8, IR_REG_R9}, + (const int8_t[8]){IR_REG_XMM0, IR_REG_XMM1, IR_REG_XMM2, IR_REG_XMM3, + IR_REG_XMM4, IR_REG_XMM5, IR_REG_XMM6, IR_REG_XMM7}, + IR_REGSET(IR_REG_RBX) | IR_REGSET(IR_REG_RBP) | IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15), + +}; + +const ir_call_conv_dsc ir_call_conv_x86_64_preserve_none = { + 0, /* cleanup_stack_by_callee */ + 1, /* pass_struct_by_val */ + 1, /* sysv_varargs */ + 0, /* shadow_param_regs */ + 0, /* shadow_store_size */ + 12, /* int_param_regs_count */ + 8, /* fp_param_regs_count */ + IR_REG_RAX, /* int_ret_reg */ + IR_REG_XMM0, /* fp_ret_reg */ + IR_REG_RAX, /* fp_varargs_reg */ + IR_REG_SCRATH_X86_64_PN, + (const int8_t[12]){IR_REG_R12, IR_REG_R13, IR_REG_R14, IR_REG_R15, + IR_REG_RDI, IR_REG_RSI, IR_REG_RDX, IR_REG_RCX, IR_REG_R8, IR_REG_R9, + IR_REG_R11, IR_REG_RAX}, + (const int8_t[8]){IR_REG_XMM0, IR_REG_XMM1, IR_REG_XMM2, IR_REG_XMM3, + IR_REG_XMM4, IR_REG_XMM5, IR_REG_XMM6, IR_REG_XMM7}, + IR_REGSET(IR_REG_RBP), + +}; + +# ifdef _WIN64 +# define ir_call_conv_default ir_call_conv_x86_64_ms +# else +# define ir_call_conv_default ir_call_conv_x86_64_sysv +# endif + +#else + +# define IR_REG_SCRATCH_X86 IR_REG_SET_1 + +# define IR_REGSET_SCRATCH_X86 \ + (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) | IR_REGSET_FP) + +const ir_regset ir_scratch_regset[] = { + IR_REGSET_INTERVAL(IR_REG_GP_FIRST, IR_REG_FP_LAST), + IR_REGSET_SCRATCH_X86, +}; + +const ir_call_conv_dsc ir_call_conv_x86_cdecl = { + 0, /* cleanup_stack_by_callee */ + 1, /* pass_struct_by_val */ + 0, /* sysv_varargs */ + 0, /* shadow_param_regs */ + 0, /* shadow_store_size */ + 0, /* int_param_regs_count */ + 0, /* fp_param_regs_count */ + IR_REG_RAX, /* int_ret_reg */ + IR_REG_NONE, /* fp_ret_reg */ + IR_REG_NONE, /* fp_varargs_reg */ + IR_REG_SCRATCH_X86, + NULL, + NULL, + IR_REGSET(IR_REG_RBX) | IR_REGSET(IR_REG_RBP) | IR_REGSET(IR_REG_RSI) | IR_REGSET(IR_REG_RDI), +}; + +const ir_call_conv_dsc ir_call_conv_x86_fastcall = { + 1, /* cleanup_stack_by_callee */ + 1, /* pass_struct_by_val */ + 0, /* sysv_varargs */ + 0, /* shadow_param_regs */ + 0, /* shadow_store_size */ + 2, /* int_param_regs_count */ + 0, /* fp_param_regs_count */ + IR_REG_RAX, /* int_ret_reg */ + IR_REG_NONE, /* fp_ret_reg */ + IR_REG_NONE, /* fp_varargs_reg */ + IR_REG_SCRATCH_X86, + (const int8_t[4]){IR_REG_RCX, IR_REG_RDX}, + NULL, + IR_REGSET(IR_REG_RBX) | IR_REGSET(IR_REG_RBP) | IR_REGSET(IR_REG_RSI) | IR_REGSET(IR_REG_RDI), +}; + +# define ir_call_conv_default ir_call_conv_x86_cdecl + +#endif + #define IR_RULES(_) \ _(CMP_INT) \ _(CMP_FP) \ @@ -1050,6 +1167,7 @@ const char *ir_reg_name(int8_t reg, ir_type type) _(CMP_AND_BRANCH_FP) \ _(TEST_AND_BRANCH_INT) \ _(JCC_INT) \ + _(COND_TEST_INT) \ _(COND_CMP_INT) \ _(COND_CMP_FP) \ _(GUARD_CMP_INT) \ @@ -1087,6 +1205,7 @@ const char *ir_reg_name(int8_t reg, ir_type type) _(SSE_TRUNC) \ _(SSE_NEARBYINT) \ _(BIT_OP) \ + _(IGOTO_DUP) \ #define IR_LEA_FIRST IR_LEA_OB #define IR_LEA_LAST IR_LEA_O_SYM @@ -1110,35 +1229,24 @@ const char *ir_rule_name[IR_LAST_OP] = { static bool ir_may_fuse_addr(ir_ctx *ctx, const ir_insn *addr_insn) { - if (sizeof(void*) == 4) { - return 1; + if (addr_insn->op == IR_LABEL) { + return 0; } else if (IR_IS_SYM_CONST(addr_insn->op)) { void *addr = ir_sym_addr(ctx, addr_insn); if (!addr) { return 0; } - return IR_IS_SIGNED_32BIT((int64_t)(intptr_t)addr); + return (sizeof(void*) == 4) || IR_IS_SIGNED_32BIT((int64_t)(intptr_t)addr); } else { - return IR_IS_SIGNED_32BIT(addr_insn->val.i64); + return (sizeof(void*) == 4) || IR_IS_SIGNED_32BIT(addr_insn->val.i64); } } static bool ir_may_fuse_imm(ir_ctx *ctx, const ir_insn *val_insn) { if (val_insn->type == IR_ADDR) { - if (sizeof(void*) == 4) { - return 1; - } else if (IR_IS_SYM_CONST(val_insn->op)) { - void *addr = ir_sym_addr(ctx, val_insn); - - if (!addr) { - return 0; - } - return IR_IS_SIGNED_32BIT((intptr_t)addr); - } else { - return IR_IS_SIGNED_32BIT(val_insn->val.i64); - } + return ir_may_fuse_addr(ctx, val_insn); } else { return (ir_type_size[val_insn->type] <= 4 || IR_IS_SIGNED_32BIT(val_insn->val.i64)); } @@ -1163,6 +1271,9 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co const ir_insn *insn; int n = 0; int flags = IR_USE_MUST_BE_IN_REG | IR_OP1_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; + const ir_proto_t *proto; + const ir_call_conv_dsc *cc; + ir_ref next; constraints->def_reg = IR_REG_NONE; constraints->hints_count = 0; @@ -1235,9 +1346,14 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co flags = IR_DEF_REUSES_OP1_REG | IR_USE_MUST_BE_IN_REG | IR_OP1_SHOULD_BE_IN_REG | IR_OP2_MUST_BE_IN_REG; op2_const: insn = &ctx->ir_base[ref]; - if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) { - constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); - n++; + if (IR_IS_CONST_REF(insn->op2)) { + if (insn->op1 != insn->op2) { + constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } + } else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { + constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n = 1; } break; case IR_CMP_INT: @@ -1293,6 +1409,7 @@ op2_const: } IR_FALLTHROUGH; case IR_COND_CMP_INT: + case IR_COND_TEST_INT: insn = &ctx->ir_base[ref]; if (IR_IS_TYPE_INT(insn->type)) { if (IR_IS_CONST_REF(insn->op3) || ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA) { @@ -1387,23 +1504,56 @@ op2_const: constraints->tmp_regs[n] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n++; break; + case IR_ARGVAL: + constraints->tmp_regs[0] = IR_SCRATCH_REG(IR_REG_RSI, IR_DEF_SUB_REF - IR_SUB_REFS_COUNT, IR_USE_SUB_REF); + constraints->tmp_regs[1] = IR_SCRATCH_REG(IR_REG_RDI, IR_DEF_SUB_REF - IR_SUB_REFS_COUNT, IR_USE_SUB_REF); + constraints->tmp_regs[2] = IR_SCRATCH_REG(IR_REG_RCX, IR_DEF_SUB_REF - IR_SUB_REFS_COUNT, IR_USE_SUB_REF); + n = 3; + break; case IR_CALL: insn = &ctx->ir_base[ref]; - if (IR_IS_TYPE_INT(insn->type)) { - constraints->def_reg = IR_REG_INT_RET1; -#ifdef IR_REG_FP_RET1 - } else { - constraints->def_reg = IR_REG_FP_RET1; + proto = ir_call_proto(ctx, insn); + cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + if (insn->type != IR_VOID) { + if (IR_IS_TYPE_INT(insn->type)) { + constraints->def_reg = cc->int_ret_reg; + } else { + IR_ASSERT(IR_IS_TYPE_FP(insn->type)); +#ifdef IR_TARGET_X86 + if (cc->fp_ret_reg == IR_REG_NONE) { + ctx->flags2 |= IR_HAS_FP_RET_SLOT; + } else #endif + { + constraints->def_reg = cc->fp_ret_reg; + } + } } - constraints->tmp_regs[0] = IR_SCRATCH_REG(IR_REG_SCRATCH, IR_USE_SUB_REF, IR_DEF_SUB_REF); + constraints->tmp_regs[0] = IR_SCRATCH_REG(cc->scratch_reg, IR_USE_SUB_REF, IR_DEF_SUB_REF); n = 1; - IR_FALLTHROUGH; + if (!IR_IS_CONST_REF(insn->op2) + && proto && (proto->flags & IR_VARARG_FUNC) && cc->fp_varargs_reg != IR_REG_NONE) { + constraints->tmp_regs[n] = IR_SCRATCH_REG(cc->fp_varargs_reg, IR_LOAD_SUB_REF, IR_USE_SUB_REF); + n++; + } + if (insn->inputs_count > 2) { + goto get_arg_hints; + } + flags = IR_USE_SHOULD_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG | IR_OP3_SHOULD_BE_IN_REG; + break; case IR_TAILCALL: insn = &ctx->ir_base[ref]; + proto = ir_call_proto(ctx, insn); + cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + if (!IR_IS_CONST_REF(insn->op2) + && proto && (proto->flags & IR_VARARG_FUNC) && cc->fp_varargs_reg != IR_REG_NONE) { + constraints->tmp_regs[n] = IR_SCRATCH_REG(cc->fp_varargs_reg, IR_LOAD_SUB_REF, IR_USE_SUB_REF); + n++; + } if (insn->inputs_count > 2) { +get_arg_hints: constraints->hints[2] = IR_REG_NONE; - constraints->hints_count = ir_get_args_regs(ctx, insn, constraints->hints); + constraints->hints_count = ir_get_args_regs(ctx, insn, cc, constraints->hints); if (!IR_IS_CONST_REF(insn->op2)) { constraints->tmp_regs[n] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_USE_SUB_REF); n++; @@ -1508,13 +1658,18 @@ op2_const: constraints->tmp_regs[0] = IR_TMP_REG(1, ctx->ir_base[insn->op1].type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; } + if (IR_IS_TYPE_UNSIGNED(ctx->ir_base[insn->op1].type) + && ir_type_size[ctx->ir_base[insn->op1].type] >= sizeof(void*)) { + constraints->tmp_regs[n] = IR_TMP_REG(2, ctx->ir_base[insn->op1].type, IR_USE_SUB_REF, IR_DEF_SUB_REF); + n++; + } break; case IR_ABS_INT: flags = IR_DEF_CONFLICTS_WITH_INPUT_REGS | IR_USE_MUST_BE_IN_REG | IR_OP1_MUST_BE_IN_REG; break; case IR_PARAM: constraints->def_reg = ir_get_param_reg(ctx, ref); - flags = 0; + flags = (constraints->def_reg != IR_REG_NONE) ? IR_USE_SHOULD_BE_IN_REG : 0; break; case IR_PI: case IR_PHI: @@ -1526,13 +1681,15 @@ op2_const: break; case IR_EXITCALL: flags = IR_USE_MUST_BE_IN_REG; - constraints->def_reg = IR_REG_INT_RET1; + cc = ir_get_call_conv_dsc(ctx->flags); + constraints->def_reg = cc->int_ret_reg; break; case IR_IF_INT: case IR_GUARD: case IR_GUARD_NOT: flags = IR_OP2_SHOULD_BE_IN_REG; break; + case IR_IGOTO: case IR_IJMP: flags = IR_OP2_SHOULD_BE_IN_REG; break; @@ -1540,34 +1697,76 @@ op2_const: flags = IR_OP3_SHOULD_BE_IN_REG; break; case IR_RETURN_INT: + cc = ir_get_call_conv_dsc(ctx->flags); flags = IR_OP2_SHOULD_BE_IN_REG; - constraints->hints[2] = IR_REG_INT_RET1; + constraints->hints[2] = cc->int_ret_reg; constraints->hints_count = 3; break; case IR_RETURN_FP: -#ifdef IR_REG_FP_RET1 - flags = IR_OP2_SHOULD_BE_IN_REG; - constraints->hints[2] = IR_REG_FP_RET1; - constraints->hints_count = 3; + cc = ir_get_call_conv_dsc(ctx->flags); +#ifdef IR_TARGET_X86 + if (cc->fp_ret_reg != IR_REG_NONE) #endif + { + flags = IR_OP2_SHOULD_BE_IN_REG; + constraints->hints[2] = cc->fp_ret_reg; + constraints->hints_count = 3; + } break; case IR_SNAPSHOT: flags = 0; + next = ir_next_control(ctx, ref); + if (ctx->ir_base[next].op == IR_GUARD || ctx->ir_base[next].op == IR_GUARD_NOT) { + flags = IR_EXTEND_INPUTS_TO_NEXT; + } break; case IR_VA_START: flags = IR_OP2_MUST_BE_IN_REG; constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; + insn = &ctx->ir_base[ref]; + if (IR_IS_CONST_REF(insn->op2)) { + constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n = 2; + } break; case IR_VA_ARG: - flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG; + flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG | IR_DEF_CONFLICTS_WITH_INPUT_REGS; constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_SAVE_SUB_REF); n = 1; + insn = &ctx->ir_base[ref]; + if (IR_IS_CONST_REF(insn->op2)) { + constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n = 2; + } break; case IR_VA_COPY: flags = IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; constraints->tmp_regs[0] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); n = 1; + insn = &ctx->ir_base[ref]; + if (IR_IS_CONST_REF(insn->op2)) { + constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } + if (IR_IS_CONST_REF(insn->op3)) { + constraints->tmp_regs[n] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n++; + } + break; + case IR_SSE_SQRT: + case IR_SSE_RINT: + case IR_SSE_FLOOR: + case IR_SSE_CEIL: + case IR_SSE_TRUNC: + case IR_SSE_NEARBYINT: + insn = &ctx->ir_base[ref]; + flags = IR_USE_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG; + if (IR_IS_CONST_REF(insn->op3)) { + const ir_insn *val_insn = &ctx->ir_base[insn->op3]; + constraints->tmp_regs[n] = IR_TMP_REG(3, val_insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF); + n = 1; + } break; } constraints->tmps_count = n; @@ -1627,7 +1826,9 @@ static void ir_match_fuse_addr(ir_ctx *ctx, ir_ref addr_ref) do { ir_insn *insn = &ctx->ir_base[*p]; - if (insn->op != IR_LOAD && (insn->op != IR_STORE || insn->op3 == addr_ref)) { + if (insn->op != IR_LOAD + && insn->op != IR_LOAD_v + && ((insn->op != IR_STORE && insn->op != IR_STORE_v) || insn->op3 == addr_ref)) { return; } p++; @@ -1710,7 +1911,7 @@ static bool ir_match_has_mem_deps(ir_ctx *ctx, ir_ref ref, ir_ref root) do { ir_insn *insn = &ctx->ir_base[pos]; - if (insn->op == IR_STORE) { + if (insn->op == IR_STORE || insn->op == IR_STORE_v || insn->op == IR_VSTORE || insn->op == IR_VSTORE_v) { // TODO: check if LOAD and STORE addresses may alias return 1; } else if (insn->op == IR_CALL) { @@ -1724,8 +1925,9 @@ static bool ir_match_has_mem_deps(ir_ctx *ctx, ir_ref ref, ir_ref root) static void ir_match_fuse_load(ir_ctx *ctx, ir_ref ref, ir_ref root) { - if (ir_in_same_block(ctx, ref) - && ctx->ir_base[ref].op == IR_LOAD) { + if (ir_in_same_block(ctx, ref) && + (ctx->ir_base[ref].op == IR_LOAD || ctx->ir_base[ref].op == IR_LOAD_v || + ctx->ir_base[ref].op == IR_VLOAD || ctx->ir_base[ref].op == IR_VLOAD_v)) { if (ctx->use_lists[ref].count == 2 && !ir_match_has_mem_deps(ctx, ref, root)) { ir_ref addr_ref = ctx->ir_base[ref].op2; @@ -1750,7 +1952,7 @@ static bool ir_match_try_fuse_load(ir_ctx *ctx, ir_ref ref, ir_ref root) ir_insn *insn = &ctx->ir_base[ref]; if (ir_in_same_block(ctx, ref) - && insn->op == IR_LOAD) { + && (insn->op == IR_LOAD || insn->op == IR_LOAD_v || insn->op == IR_VLOAD || insn->op == IR_VLOAD_v)) { if (ctx->use_lists[ref].count == 2 && !ir_match_has_mem_deps(ctx, ref, root)) { ir_ref addr_ref = ctx->ir_base[ref].op2; @@ -1772,8 +1974,6 @@ static bool ir_match_try_fuse_load(ir_ctx *ctx, ir_ref ref, ir_ref root) && ir_get_param_reg(ctx, ref) == IR_REG_NONE) { return 1; } - } else if (ctx->ir_base[ref].op == IR_VLOAD) { - return 1; } return 0; } @@ -1839,26 +2039,19 @@ static void ir_match_fuse_load_cmp_fp(ir_ctx *ctx, ir_insn *insn, ir_ref root) /* pass */ } else if ((IR_IS_CONST_REF(insn->op1) && !IR_IS_FP_ZERO(ctx->ir_base[insn->op1])) || ir_match_try_fuse_load(ctx, insn->op1, root)) { ir_swap_ops(insn); - if (insn->op != IR_EQ && insn->op != IR_NE) { + if (insn->op != IR_EQ && insn->op != IR_NE + && insn->op != IR_ORDERED && insn->op != IR_UNORDERED) { insn->op ^= 3; } } } -static void ir_match_fuse_load_cmp_fp_br(ir_ctx *ctx, ir_insn *insn, ir_ref root, bool direct) +static void ir_match_fuse_load_cmp_fp_br(ir_ctx *ctx, ir_insn *insn, ir_ref root) { - if (direct) { - if (insn->op == IR_LT || insn->op == IR_LE) { - /* swap operands to avoid P flag check */ - ir_swap_ops(insn); - insn->op ^= 3; - } - } else { - if (insn->op == IR_GT || insn->op == IR_GE) { - /* swap operands to avoid P flag check */ - ir_swap_ops(insn); - insn->op ^= 3; - } + if (insn->op == IR_LT || insn->op == IR_LE || insn->op == IR_UGT || insn->op == IR_UGE) { + /* swap operands to avoid P flag check */ + ir_swap_ops(insn); + insn->op ^= 3; } if (IR_IS_CONST_REF(insn->op2) && !IR_IS_FP_ZERO(ctx->ir_base[insn->op2])) { /* pass */ @@ -1866,7 +2059,8 @@ static void ir_match_fuse_load_cmp_fp_br(ir_ctx *ctx, ir_insn *insn, ir_ref root /* pass */ } else if ((IR_IS_CONST_REF(insn->op1) && !IR_IS_FP_ZERO(ctx->ir_base[insn->op1])) || ir_match_try_fuse_load(ctx, insn->op1, root)) { ir_swap_ops(insn); - if (insn->op != IR_EQ && insn->op != IR_NE) { + if (insn->op != IR_EQ && insn->op != IR_NE + && insn->op != IR_ORDERED && insn->op != IR_UNORDERED) { insn->op ^= 3; } } @@ -1882,7 +2076,7 @@ static uint32_t ir_match_builtin_call(ir_ctx *ctx, const ir_insn *func) { const ir_proto_t *proto = (const ir_proto_t *)ir_get_str(ctx, func->proto); - if (proto->flags & IR_BUILTIN_FUNC) { + if ((proto->flags & IR_CALL_CONV_MASK) == IR_CC_BUILTIN) { size_t name_len; const char *name = ir_get_strl(ctx, func->val.name, &name_len); @@ -1940,6 +2134,34 @@ static uint32_t ir_match_builtin_call(ir_ctx *ctx, const ir_insn *func) return 0; } +static bool all_usages_are_fusable(ir_ctx *ctx, ir_ref ref) +{ + ir_insn *insn = &ctx->ir_base[ref]; + + if (insn->op >= IR_EQ && insn->op <= IR_UNORDERED) { + ir_use_list *use_list = &ctx->use_lists[ref]; + ir_ref n = use_list->count; + + if (n > 0) { + ir_ref *p = ctx->use_edges + use_list->refs; + + do { + insn = &ctx->ir_base[*p]; + if (insn->op != IR_IF + && insn->op != IR_GUARD + && insn->op != IR_GUARD_NOT + && (insn->op != IR_COND || insn->op2 == ref || insn->op3 == ref)) { + return 0; + } + p++; + n--; + } while (n); + return 1; + } + } + return 0; +} + static uint32_t ir_match_insn(ir_ctx *ctx, ir_ref ref) { ir_insn *op2_insn; @@ -1993,6 +2215,10 @@ static uint32_t ir_match_insn(ir_ctx *ctx, ir_ref ref) return IR_CMP_FP; } break; + case IR_ORDERED: + case IR_UNORDERED: + ir_match_fuse_load_cmp_fp(ctx, insn, ref); + return IR_CMP_FP; case IR_ADD: case IR_SUB: if (IR_IS_TYPE_INT(insn->type)) { @@ -2404,19 +2630,46 @@ binop_fp: } } ctx->flags2 |= IR_HAS_CALLS | IR_16B_FRAME_ALIGNMENT; -#ifndef IR_REG_FP_RET1 - if (IR_IS_TYPE_FP(insn->type)) { - ctx->flags2 |= IR_HAS_FP_RET_SLOT; - } -#endif IR_FALLTHROUGH; case IR_TAILCALL: case IR_IJMP: + if (!IR_IS_CONST_REF(insn->op2)) { + if (ctx->ir_base[insn->op2].op == IR_PROTO) { + if (IR_IS_CONST_REF(ctx->ir_base[insn->op2].op1)) { + ctx->rules[insn->op2] = IR_FUSED | IR_SIMPLE | IR_PROTO; + } else { + ir_match_fuse_load(ctx, ctx->ir_base[insn->op2].op1, ref); + if (ctx->rules[ctx->ir_base[insn->op2].op1] & IR_FUSED) { + ctx->rules[insn->op2] = IR_FUSED | IR_SIMPLE | IR_PROTO; + } + } + } else { + ir_match_fuse_load(ctx, insn->op2, ref); + } + } + return insn->op; + case IR_IGOTO: + if (ctx->ir_base[insn->op1].op == IR_MERGE || ctx->ir_base[insn->op1].op == IR_LOOP_BEGIN) { + ir_insn *merge = &ctx->ir_base[insn->op1]; + ir_ref *p, n = merge->inputs_count; + + for (p = merge->ops + 1; n > 0; p++, n--) { + ir_ref input = *p; + IR_ASSERT(ctx->ir_base[input].op == IR_END || ctx->ir_base[input].op == IR_LOOP_END); + ctx->rules[input] = IR_IGOTO_DUP; + } + } ir_match_fuse_load(ctx, insn->op2, ref); return insn->op; case IR_VAR: - return IR_SKIPPED | IR_VAR; + return IR_STATIC_ALLOCA; case IR_PARAM: + if (ctx->value_params && ctx->value_params[insn->op3 - 1].align) { + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(ctx->flags); + if (cc->pass_struct_by_val) { + return IR_STATIC_ALLOCA; + } + } return ctx->use_lists[ref].count > 0 ? IR_PARAM : IR_SKIPPED | IR_PARAM; case IR_ALLOCA: /* alloca() may be used only in functions */ @@ -2564,7 +2817,15 @@ store_int: return IR_VSTORE_FP; } break; + case IR_VSTORE_v: + if (IR_IS_TYPE_INT(ctx->ir_base[insn->op3].type)) { + return IR_VSTORE_INT; + } else { + return IR_VSTORE_FP; + } + break; case IR_LOAD: + case IR_LOAD_v: ir_match_fuse_addr(ctx, insn->op2); if (IR_IS_TYPE_INT(insn->type)) { return IR_LOAD_INT; @@ -2582,6 +2843,14 @@ store_int: return IR_STORE_FP; } break; + case IR_STORE_v: + ir_match_fuse_addr(ctx, insn->op2); + if (IR_IS_TYPE_INT(ctx->ir_base[insn->op3].type)) { + return IR_STORE_INT; + } else { + return IR_STORE_FP; + } + break; case IR_RLOAD: if (IR_REGSET_IN(IR_REGSET_UNION((ir_regset)ctx->fixed_regset, IR_REGSET_FIXED), insn->op2)) { return IR_SKIPPED | IR_RLOAD; @@ -2630,6 +2899,7 @@ store_int: case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: @@ -2644,9 +2914,9 @@ store_int: return IR_RETURN_FP; } case IR_IF: - if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) { + if (!IR_IS_CONST_REF(insn->op2) && (ctx->use_lists[insn->op2].count == 1 || all_usages_are_fusable(ctx, insn->op2))) { op2_insn = &ctx->ir_base[insn->op2]; - if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT) { + if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) { if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) { if (IR_IS_CONST_REF(op2_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op) @@ -2656,7 +2926,9 @@ store_int: if (op1_insn->op == IR_AND && ctx->use_lists[op2_insn->op1].count == 1) { /* v = AND(_, _); c = CMP(v, 0) ... IF(c) => SKIP_TEST; SKIP ... TEST_AND_BRANCH */ - ir_match_fuse_load_test_int(ctx, op1_insn, ref); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load_test_int(ctx, op1_insn, ref); + } ctx->rules[op2_insn->op1] = IR_FUSED | IR_TEST_INT; ctx->rules[insn->op2] = IR_FUSED | IR_SIMPLE | IR_NOP; return IR_TEST_AND_BRANCH_INT; @@ -2668,10 +2940,14 @@ store_int: op2_insn->op == IR_LT || op2_insn->op == IR_GE)))) { /* v = BINOP(_, _); c = CMP(v, 0) ... IF(c) => BINOP; SKIP_CMP ... JCC */ if (ir_op_flags[op1_insn->op] & IR_OP_FLAG_COMMUTATIVE) { - ir_match_fuse_load_commutative_int(ctx, op1_insn, ref); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load_commutative_int(ctx, op1_insn, ref); + } ctx->rules[op2_insn->op1] = IR_BINOP_INT | IR_MAY_SWAP; } else { - ir_match_fuse_load(ctx, op1_insn->op2, ref); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load(ctx, op1_insn->op2, ref); + } ctx->rules[op2_insn->op1] = IR_BINOP_INT; } ctx->rules[insn->op2] = IR_FUSED | IR_CMP_INT; @@ -2679,12 +2955,16 @@ store_int: } } /* c = CMP(_, _) ... IF(c) => SKIP_CMP ... CMP_AND_BRANCH */ - ir_match_fuse_load_cmp_int(ctx, op2_insn, ref); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load_cmp_int(ctx, op2_insn, ref); + } ctx->rules[insn->op2] = IR_FUSED | IR_CMP_INT; return IR_CMP_AND_BRANCH_INT; } else { /* c = CMP(_, _) ... IF(c) => SKIP_CMP ... CMP_AND_BRANCH */ - ir_match_fuse_load_cmp_fp_br(ctx, op2_insn, ref, 1); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load_cmp_fp_br(ctx, op2_insn, ref); + } ctx->rules[insn->op2] = IR_FUSED | IR_CMP_FP; return IR_CMP_AND_BRANCH_FP; } @@ -2772,31 +3052,39 @@ store_int: break; } case IR_COND: - if (!IR_IS_CONST_REF(insn->op1) && ctx->use_lists[insn->op1].count == 1) { + if (!IR_IS_CONST_REF(insn->op1) && (ctx->use_lists[insn->op1].count == 1 || all_usages_are_fusable(ctx, insn->op1))) { ir_insn *op1_insn = &ctx->ir_base[insn->op1]; - if (op1_insn->op >= IR_EQ && op1_insn->op <= IR_UGT) { + if (op1_insn->op >= IR_EQ && op1_insn->op <= IR_UNORDERED) { if (IR_IS_TYPE_INT(ctx->ir_base[op1_insn->op1].type)) { - ir_match_fuse_load_cmp_int(ctx, op1_insn, ref); + if (ctx->use_lists[insn->op1].count == 1) { + ir_match_fuse_load_cmp_int(ctx, op1_insn, ref); + } ctx->rules[insn->op1] = IR_FUSED | IR_CMP_INT; return IR_COND_CMP_INT; } else { - ir_match_fuse_load_cmp_fp_br(ctx, op1_insn, ref, 1); + if (ctx->use_lists[insn->op1].count == 1) { + ir_match_fuse_load_cmp_fp_br(ctx, op1_insn, ref); + } ctx->rules[insn->op1] = IR_FUSED | IR_CMP_FP; return IR_COND_CMP_FP; } + } else if (op1_insn->op == IR_AND) { + /* c = AND(_, _) ... IF(c) => SKIP_TEST ... TEST_AND_BRANCH */ + ir_match_fuse_load_test_int(ctx, op1_insn, ref); + ctx->rules[insn->op1] = IR_FUSED | IR_TEST_INT; + return IR_COND_TEST_INT; } } + if (IR_IS_TYPE_INT(ctx->ir_base[insn->op1].type)) { + ir_match_fuse_load(ctx, insn->op1, ref); + } return IR_COND; case IR_GUARD: case IR_GUARD_NOT: - if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) { + if (!IR_IS_CONST_REF(insn->op2) && (ctx->use_lists[insn->op2].count == 1 || all_usages_are_fusable(ctx, insn->op2))) { op2_insn = &ctx->ir_base[insn->op2]; - if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT - // TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP - && (insn->op2 == ref - 1 || - (insn->op2 == ctx->prev_ref[ref] - 1 - && ctx->ir_base[ctx->prev_ref[ref]].op == IR_SNAPSHOT))) { + if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) { if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) { if (IR_IS_CONST_REF(op2_insn->op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op) @@ -2810,10 +3098,14 @@ store_int: (op2_insn->op == IR_EQ || op2_insn->op == IR_NE || op2_insn->op == IR_LT || op2_insn->op == IR_GE))) { if (ir_op_flags[op1_insn->op] & IR_OP_FLAG_COMMUTATIVE) { - ir_match_fuse_load_commutative_int(ctx, op1_insn, ref); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load_commutative_int(ctx, op1_insn, ref); + } ctx->rules[op2_insn->op1] = IR_BINOP_INT | IR_MAY_SWAP; } else { - ir_match_fuse_load(ctx, op1_insn->op2, ref); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load(ctx, op1_insn->op2, ref); + } ctx->rules[op2_insn->op1] = IR_BINOP_INT; } /* v = BINOP(_, _); c = CMP(v, 0) ... IF(c) => BINOP; SKIP_CMP ... GUARD_JCC */ @@ -2821,6 +3113,7 @@ store_int: return IR_GUARD_JCC_INT; } } else if ((ctx->flags & IR_OPT_CODEGEN) + && ctx->use_lists[insn->op2].count == 1 && op2_insn->op1 == insn->op2 - 2 /* before previous instruction */ && ir_in_same_block(ctx, op2_insn->op1) && ctx->use_lists[op2_insn->op1].count == 2) { @@ -2868,12 +3161,16 @@ store_int: } } /* c = CMP(_, _) ... GUARD(c) => SKIP_CMP ... GUARD_CMP */ - ir_match_fuse_load_cmp_int(ctx, op2_insn, ref); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load_cmp_int(ctx, op2_insn, ref); + } ctx->rules[insn->op2] = IR_FUSED | IR_CMP_INT; return IR_GUARD_CMP_INT; } else { /* c = CMP(_, _) ... GUARD(c) => SKIP_CMP ... GUARD_CMP */ - ir_match_fuse_load_cmp_fp_br(ctx, op2_insn, ref, insn->op == IR_GUARD_NOT); + if (ctx->use_lists[insn->op2].count == 1) { + ir_match_fuse_load_cmp_fp_br(ctx, op2_insn, ref); + } ctx->rules[insn->op2] = IR_FUSED | IR_CMP_FP; return IR_GUARD_CMP_FP; } @@ -2945,6 +3242,9 @@ store_int: ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP; } } + } else { + /* va_list may escape */ + ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP; } return IR_VA_START; case IR_VA_END: @@ -2961,8 +3261,16 @@ store_int: } } return IR_SKIPPED | IR_NOP; + case IR_ARGVAL: + return IR_FUSED | IR_ARGVAL; case IR_NOP: return IR_SKIPPED | IR_NOP; + case IR_ASM: + case IR_ASM_OUT: + case IR_ASM_GOTO: + fprintf(stderr, "ERROR: IR_ASM is not implemented yet\n"); + exit(1); + return IR_SKIPPED | IR_NOP; default: break; } @@ -3116,7 +3424,7 @@ static void ir_emit_load_imm_fp(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref sr | xorpd xmm(reg-IR_REG_FP_FIRST), xmm(reg-IR_REG_FP_FIRST) } } else { - label = ir_const_label(ctx, src); + label = ir_get_const_label(ctx, src); | ASM_FP_REG_TXT_OP movs, type, reg, [=>label] } } @@ -3138,6 +3446,17 @@ static void ir_emit_load_mem(ir_ctx *ctx, ir_type type, ir_reg reg, ir_mem mem) } } +static int32_t ir_local_offset(ir_ctx *ctx, ir_insn *insn) +{ + if (insn->op != IR_PARAM) { + IR_ASSERT(insn->op == IR_VAR || insn->op == IR_ALLOCA || insn->op == IR_VADDR); + return IR_SPILL_POS_TO_OFFSET(insn->op3); + } else { + IR_ASSERT(ctx->value_params && ctx->value_params[insn->op3 - 1].align); + return IR_SPILL_POS_TO_OFFSET(ctx->value_params[insn->op3 - 1].offset); + } +} + static void ir_load_local_addr(ir_ctx *ctx, ir_reg reg, ir_ref src) { ir_backend_data *data = ctx->data; @@ -3151,8 +3470,7 @@ static void ir_load_local_addr(ir_ctx *ctx, ir_reg reg, ir_ref src) if (var_insn->op == IR_VADDR) { var_insn = &ctx->ir_base[var_insn->op1]; } - IR_ASSERT(var_insn->op == IR_VAR || var_insn->op == IR_ALLOCA); - offset = IR_SPILL_POS_TO_OFFSET(var_insn->op3); + offset = ir_local_offset(ctx, var_insn); if (offset == 0) { | mov Ra(reg), Ra(base) } else { @@ -3160,6 +3478,38 @@ static void ir_load_local_addr(ir_ctx *ctx, ir_reg reg, ir_ref src) } } +static void ir_resolve_label_syms(ir_ctx *ctx) +{ + uint32_t b; + ir_block *bb; + + for (b = 1, bb = &ctx->cfg_blocks[b]; b <= ctx->cfg_blocks_count; bb++, b++) { + ir_insn *insn = &ctx->ir_base[bb->start]; + + if (insn->op == IR_BEGIN && insn->op2) { + IR_ASSERT(ctx->ir_base[insn->op2].op == IR_LABEL); + ctx->ir_base[insn->op2].val.u32_hi = b; + } + } +} + +static void ir_emit_load_label_addr(ir_ctx *ctx, ir_reg reg, ir_insn *label) +{ + ir_backend_data *data = ctx->data; + dasm_State **Dst = &data->dasm_state; + + if (!data->resolved_label_syms) { + data->resolved_label_syms = 1; + ir_resolve_label_syms(ctx); + } + + IR_ASSERT(label->op == IR_LABEL); + int b = label->val.u32_hi; + + b = ir_skip_empty_target_blocks(ctx, b); + | lea Ra(reg), aword [=>b] +} + static void ir_emit_load(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref src) { if (IR_IS_CONST_REF(src)) { @@ -3172,9 +3522,11 @@ static void ir_emit_load(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref src) } else if (insn->op == IR_STR) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - int label = ir_const_label(ctx, src); + int label = ir_get_const_label(ctx, src); | lea Ra(reg), aword [=>label] + } else if (insn->op == IR_LABEL) { + ir_emit_load_label_addr(ctx, reg, insn); } else { ir_emit_load_imm_int(ctx, type, reg, insn->val.i64); } @@ -3220,7 +3572,7 @@ static void ir_emit_store_mem_int_const(ir_ctx *ctx, ir_type type, ir_mem mem, i IR_ASSERT(IR_IS_CONST_REF(src)); if (val_insn->op == IR_STR) { - int label = ir_const_label(ctx, src); + int label = ir_get_const_label(ctx, src); IR_ASSERT(tmp_reg != IR_REG_NONE); |.if X64 @@ -3229,6 +3581,11 @@ static void ir_emit_store_mem_int_const(ir_ctx *ctx, ir_type type, ir_mem mem, i |.else | ASM_TMEM_TXT_OP mov, aword, mem, =>label |.endif + } else if (val_insn->op == IR_LABEL) { + IR_ASSERT(tmp_reg != IR_REG_NONE); + tmp_reg = IR_REG_NUM(tmp_reg); + ir_emit_load_label_addr(ctx, tmp_reg, val_insn); + ir_emit_store_mem_int(ctx, type, mem, tmp_reg); } else { int64_t val = val_insn->val.i64; @@ -3370,7 +3727,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) case IR_LEA_OB: offset_insn = insn; if (ir_rule(ctx, insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; } else { @@ -3392,12 +3749,12 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) break; case IR_LEA_IB: if (ir_rule(ctx, insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = ref * sizeof(ir_ref) + 2; } else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = ref * sizeof(ir_ref) + 1; @@ -3413,12 +3770,12 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) offset_insn = op1_insn; scale = 1; if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = insn->op1 * sizeof(ir_ref) + 1; } else if (ir_rule(ctx, op1_insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op1_insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = ref * sizeof(ir_ref) + 2; @@ -3432,12 +3789,12 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) offset_insn = op2_insn; scale = 1; if (ir_rule(ctx, insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = insn->op2 * sizeof(ir_ref) + 1; } else if (ir_rule(ctx, op2_insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op2_insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[op2_insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = ref * sizeof(ir_ref) + 1; @@ -3464,12 +3821,12 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) offset_insn = insn; scale = 1; if (ir_rule(ctx, op1_insn->op2) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op1_insn->op2].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op2]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = insn->op1 * sizeof(ir_ref) + 1; } else if (ir_rule(ctx, op1_insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op1_insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; index_reg_ref = insn->op1 * sizeof(ir_ref) + 2; @@ -3485,7 +3842,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) op2_insn = &ctx->ir_base[insn->op2]; scale = ctx->ir_base[op2_insn->op2].val.i32; if (ir_rule(ctx, op1_insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op1_insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; } else { @@ -3499,7 +3856,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) op2_insn = &ctx->ir_base[insn->op2]; offset_insn = op2_insn; if (ir_rule(ctx, op2_insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op2_insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[op2_insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; } else { @@ -3508,7 +3865,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) break; case IR_LEA_B_SI: if (ir_rule(ctx, insn->op1) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op1].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op1]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; } else { @@ -3522,7 +3879,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) case IR_LEA_SI_B: index_reg_ref = insn->op1 * sizeof(ir_ref) + 1; if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) { - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = IR_UNUSED; } else { @@ -3535,7 +3892,13 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) case IR_LEA_B_SI_O: offset_insn = insn; op1_insn = &ctx->ir_base[insn->op1]; - base_reg_ref = insn->op1 * sizeof(ir_ref) + 1; + if (ir_rule(ctx, op1_insn->op1) == IR_STATIC_ALLOCA) { + offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op1]); + base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + base_reg_ref = IR_UNUSED; + } else { + base_reg_ref = insn->op1 * sizeof(ir_ref) + 1; + } index_reg_ref = op1_insn->op2 * sizeof(ir_ref) + 1; op2_insn = &ctx->ir_base[op1_insn->op2]; scale = ctx->ir_base[op2_insn->op2].val.i32; @@ -3544,7 +3907,13 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) offset_insn = insn; op1_insn = &ctx->ir_base[insn->op1]; index_reg_ref = op1_insn->op1 * sizeof(ir_ref) + 1; - base_reg_ref = insn->op1 * sizeof(ir_ref) + 2; + if (ir_rule(ctx, op1_insn->op2) == IR_STATIC_ALLOCA) { + offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op2]); + base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + base_reg_ref = IR_UNUSED; + } else { + base_reg_ref = insn->op1 * sizeof(ir_ref) + 2; + } op1_insn = &ctx->ir_base[op1_insn->op1]; scale = ctx->ir_base[op1_insn->op2].val.i32; break; @@ -3565,7 +3934,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) offset_insn = NULL; break; case IR_ALLOCA: - offset = IR_SPILL_POS_TO_OFFSET(insn->op3); + offset = ir_local_offset(ctx, insn); base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; base_reg_ref = index_reg_ref = IR_UNUSED; scale = 1; @@ -3582,7 +3951,7 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref) offset += (int64_t)(intptr_t)(addr); } else { if (offset_insn->op == IR_SUB) { - offset = -addr_insn->val.i32; + offset -= addr_insn->val.i32; } else { offset += addr_insn->val.i32; } @@ -3645,7 +4014,8 @@ static ir_mem ir_fuse_load(ir_ctx *ctx, ir_ref root, ir_ref ref) ir_insn *load_insn = &ctx->ir_base[ref]; ir_reg reg; - IR_ASSERT(load_insn->op == IR_LOAD); + IR_ASSERT(load_insn->op == IR_LOAD || load_insn->op == IR_LOAD_v || + load_insn->op == IR_VLOAD || load_insn->op == IR_VLOAD_v); if (UNEXPECTED(ctx->rules[ref] & IR_FUSED_REG)) { reg = ir_get_fused_reg(ctx, root, ref * sizeof(ir_ref) + 2); } else { @@ -3681,9 +4051,11 @@ static void ir_emit_load_ex(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref src, i } else if (insn->op == IR_STR) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - int label = ir_const_label(ctx, src); + int label = ir_get_const_label(ctx, src); | lea Ra(reg), aword [=>label] + } else if (insn->op == IR_LABEL) { + ir_emit_load_label_addr(ctx, reg, insn); } else { ir_emit_load_imm_int(ctx, type, reg, insn->val.i64); } @@ -3755,59 +4127,68 @@ static void ir_emit_prologue(ir_ctx *ctx) } } if ((ctx->flags & IR_VARARG_FUNC) && (ctx->flags2 & IR_HAS_VA_START)) { -#if defined(_WIN64) - ir_reg fp; - int offset; + const ir_call_conv_dsc *cc = data->ra_data.cc; - if (ctx->flags & IR_USE_FRAME_POINTER) { - fp = IR_REG_FRAME_POINTER; - offset = sizeof(void*) * 2; - } else { - fp = IR_REG_STACK_POINTER; - offset = ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*); + if (cc->shadow_store_size) { + ir_reg fp; + int shadow_store; + int offset = 0; + int n = 0; + + if (ctx->flags & IR_USE_FRAME_POINTER) { + fp = IR_REG_FRAME_POINTER; + shadow_store = sizeof(void*) * 2; + } else { + fp = IR_REG_STACK_POINTER; + shadow_store = ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*); + } + + while (offset < cc->shadow_store_size && n < cc->int_param_regs_count) { + | mov [Ra(fp)+shadow_store+offset], Ra(cc->int_param_regs[n]) + n++; + offset += sizeof(void*); + } } - | mov [Ra(fp)+offset], Ra(IR_REG_INT_ARG1) - | mov [Ra(fp)+offset+8], Ra(IR_REG_INT_ARG2) - | mov [Ra(fp)+offset+16], Ra(IR_REG_INT_ARG3) - | mov [Ra(fp)+offset+24], Ra(IR_REG_INT_ARG4) -#elif defined(IR_TARGET_X64) + + if (cc->sysv_varargs) { + IR_ASSERT(sizeof(void*) == 8); +#ifdef IR_TARGET_X64 |.if X64 - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; - uint32_t i; - ir_reg fp; - int offset; + int32_t i; + ir_reg fp; + int offset; - if (ctx->flags & IR_USE_FRAME_POINTER) { - fp = IR_REG_FRAME_POINTER; + if (ctx->flags & IR_USE_FRAME_POINTER) { + fp = IR_REG_FRAME_POINTER; - offset = -(ctx->stack_frame_size - ctx->stack_frame_alignment - ctx->locals_area_size); - } else { - fp = IR_REG_STACK_POINTER; - offset = ctx->locals_area_size + ctx->call_stack_size; - } + offset = -(ctx->stack_frame_size - ctx->locals_area_size); + } else { + fp = IR_REG_STACK_POINTER; + offset = ctx->locals_area_size + ctx->call_stack_size; + } - if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < IR_REG_INT_ARGS) { - /* skip named args */ - offset += sizeof(void*) * ctx->gp_reg_params; - for (i = ctx->gp_reg_params; i < IR_REG_INT_ARGS; i++) { - | mov qword [Ra(fp)+offset], Rq(int_reg_params[i]) - offset += sizeof(void*); + if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < cc->int_param_regs_count) { + /* skip named args */ + offset += sizeof(void*) * ctx->gp_reg_params; + for (i = ctx->gp_reg_params; i < cc->int_param_regs_count; i++) { + | mov qword [Ra(fp)+offset], Rq(cc->int_param_regs[i]) + offset += sizeof(void*); + } } - } - if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < IR_REG_FP_ARGS) { - | test al, al - | je >1 - /* skip named args */ - offset += 16 * ctx->fp_reg_params; - for (i = ctx->fp_reg_params; i < IR_REG_FP_ARGS; i++) { - | movaps [Ra(fp)+offset], xmm(fp_reg_params[i]-IR_REG_FP_FIRST) - offset += 16; + if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < cc->fp_param_regs_count) { + | test al, al + | je >1 + /* skip named args */ + offset += 16 * ctx->fp_reg_params; + for (i = ctx->fp_reg_params; i < cc->fp_param_regs_count; i++) { + | movaps [Ra(fp)+offset], xmm(cc->fp_param_regs[i]-IR_REG_FP_FIRST) + offset += 16; + } + |1: } - |1: - } |.endif #endif + } } } @@ -5526,7 +5907,7 @@ static void ir_emit_binop_sse2(ir_ctx *ctx, ir_ref def, ir_insn *insn) break; } } else if (IR_IS_CONST_REF(op2)) { - int label = ir_const_label(ctx, op2); + int label = ir_get_const_label(ctx, op2); switch (insn->op) { default: @@ -5633,7 +6014,7 @@ static void ir_emit_binop_avx(ir_ctx *ctx, ir_ref def, ir_insn *insn) break; } } else if (IR_IS_CONST_REF(op2)) { - int label = ir_const_label(ctx, op2); + int label = ir_get_const_label(ctx, op2); switch (insn->op) { default: @@ -5740,8 +6121,15 @@ static void ir_emit_cmp_int_common2(ir_ctx *ctx, ir_ref root, ir_ref ref, ir_ins ir_type type = ctx->ir_base[cmp_insn->op1].type; ir_ref op1 = cmp_insn->op1; ir_ref op2 = cmp_insn->op2; - ir_reg op1_reg = ctx->regs[ref][1]; - ir_reg op2_reg = ctx->regs[ref][2]; + ir_reg op1_reg, op2_reg; + + if (UNEXPECTED(ctx->rules[ref] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, root, ref * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, root, ref * sizeof(ir_ref) + 2); + } else { + op1_reg = ctx->regs[ref][1]; + op2_reg = ctx->regs[ref][2]; + } if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { op1_reg = IR_REG_NUM(op1_reg); @@ -5907,8 +6295,15 @@ static void ir_emit_test_int_common(ir_ctx *ctx, ir_ref root, ir_ref ref, ir_op ir_type type = binop_insn->type; ir_ref op1 = binop_insn->op1; ir_ref op2 = binop_insn->op2; - ir_reg op1_reg = ctx->regs[ref][1]; - ir_reg op2_reg = ctx->regs[ref][2]; + ir_reg op1_reg, op2_reg; + + if (UNEXPECTED(ctx->rules[ref] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, root, ref * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, root, ref * sizeof(ir_ref) + 2); + } else { + op1_reg = ctx->regs[ref][1]; + op2_reg = ctx->regs[ref][2]; + } IR_ASSERT(binop_insn->op == IR_AND); if (op1_reg != IR_REG_NONE) { @@ -6018,8 +6413,13 @@ static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref root, ir_ref cmp_ref, ir_ op1 = cmp_insn->op1; op2 = cmp_insn->op2; - op1_reg = ctx->regs[cmp_ref][1]; - op2_reg = ctx->regs[cmp_ref][2]; + if (UNEXPECTED(ctx->rules[cmp_ref] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, root, cmp_ref * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, root, cmp_ref * sizeof(ir_ref) + 2); + } else { + op1_reg = ctx->regs[cmp_ref][1]; + op2_reg = ctx->regs[cmp_ref][2]; + } if (op1_reg == IR_REG_NONE && op2_reg != IR_REG_NONE && (op == IR_EQ || op == IR_NE)) { ir_reg tmp_reg; @@ -6045,7 +6445,7 @@ static ir_op ir_emit_cmp_fp_common(ir_ctx *ctx, ir_ref root, ir_ref cmp_ref, ir_ } | ASM_FP_REG_REG_OP ucomis, type, op1_reg, op2_reg } else if (IR_IS_CONST_REF(op2)) { - int label = ir_const_label(ctx, op2); + int label = ir_get_const_label(ctx, op2); | ASM_FP_REG_TXT_OP ucomis, type, op1_reg, [=>label] } else { @@ -6115,6 +6515,12 @@ static void ir_emit_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) | mov Rd(tmp_reg), 1 | cmova Rd(def_reg), Rd(tmp_reg) break; + case IR_ORDERED: + | setnp Rb(def_reg) + break; + case IR_UNORDERED: + | setp Rb(def_reg) + break; } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, insn->type, def, def_reg); @@ -6154,7 +6560,7 @@ static void ir_emit_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint ir_get_true_false_blocks(ctx, b, &true_block, &false_block); if (true_block == next_block) { /* swap to avoid unconditional JMP */ - if (int_cmp || op == IR_EQ || op == IR_NE) { + if (int_cmp || op == IR_EQ || op == IR_NE || op == IR_ORDERED || op == IR_UNORDERED) { op ^= 1; // reverse } else { op ^= 5; // reverse @@ -6266,6 +6672,12 @@ static void ir_emit_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn, uint | jp =>true_block | ja =>true_block break; + case IR_ORDERED: + | jnp =>true_block + break; + case IR_UNORDERED: + | jp =>true_block + break; } } if (false_block) { @@ -6280,8 +6692,15 @@ static void ir_emit_cmp_and_branch_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_i ir_type type = ctx->ir_base[cmp_insn->op1].type; ir_ref op1 = cmp_insn->op1; ir_ref op2 = cmp_insn->op2; - ir_reg op1_reg = ctx->regs[insn->op2][1]; - ir_reg op2_reg = ctx->regs[insn->op2][2]; + ir_reg op1_reg, op2_reg; + + if (UNEXPECTED(ctx->rules[insn->op2] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 2); + } else { + op1_reg = ctx->regs[insn->op2][1]; + op2_reg = ctx->regs[insn->op2][2]; + } if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { op1_reg = IR_REG_NUM(op1_reg); @@ -6412,37 +6831,24 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn) IR_ASSERT(def_reg != IR_REG_NONE); - if (op2 != op3) { - if (op2_reg != IR_REG_NONE && IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, type, op2_reg, op2); - if (op1 == op2) { - op1_reg = op2_reg; - } - } - if (op3_reg != IR_REG_NONE && IR_REG_SPILLED(op3_reg)) { - op3_reg = IR_REG_NUM(op3_reg); - ir_emit_load(ctx, type, op3_reg, op3); - if (op1 == op2) { - op1_reg = op3_reg; - } - } - } else if (op2_reg != IR_REG_NONE && IR_REG_SPILLED(op2_reg)) { + if (op2_reg != IR_REG_NONE && IR_REG_SPILLED(op2_reg)) { op2_reg = IR_REG_NUM(op2_reg); ir_emit_load(ctx, type, op2_reg, op2); - op3_reg = op2_reg; if (op1 == op2) { op1_reg = op2_reg; } - } else if (op3_reg != IR_REG_NONE && IR_REG_SPILLED(op3_reg)) { + if (op3 == op2) { + op3_reg = op2_reg; + } + } + if (op3_reg != IR_REG_NONE && IR_REG_SPILLED(op3_reg)) { op3_reg = IR_REG_NUM(op3_reg); ir_emit_load(ctx, type, op3_reg, op3); - op2_reg = op3_reg; if (op1 == op3) { - op1_reg = op3_reg; + op1_reg = op2_reg; } } - if (op1_reg != IR_REG_NONE && op1 != op2 && op1 != op3 && IR_REG_SPILLED(op1_reg)) { + if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { op1_reg = IR_REG_NUM(op1_reg); ir_emit_load(ctx, op1_type, op1_reg, op1); } @@ -6451,7 +6857,13 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn) if (op1_reg != IR_REG_NONE) { | ASM_REG_REG_OP test, op1_type, op1_reg, op1_reg } else { - ir_mem mem = ir_ref_spill_slot(ctx, op1); + ir_mem mem; + + if (ir_rule(ctx, insn->op1) & IR_FUSED) { + mem = ir_fuse_load(ctx, def, insn->op1); + } else { + mem = ir_ref_spill_slot(ctx, insn->op1); + } | ASM_MEM_IMM_OP cmp, op1_type, mem, 0 } @@ -6541,6 +6953,115 @@ static void ir_emit_cond(ir_ctx *ctx, ir_ref def, ir_insn *insn) } } +static void ir_emit_cond_test_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) +{ + ir_backend_data *data = ctx->data; + dasm_State **Dst = &data->dasm_state; + ir_type type = insn->type; + ir_ref op2 = insn->op2; + ir_ref op3 = insn->op3; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg op3_reg = ctx->regs[def][3]; + + if (op2 != op3) { + if (op2_reg != IR_REG_NONE && IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, type, op2_reg, op2); + } + if (op3_reg != IR_REG_NONE && IR_REG_SPILLED(op3_reg)) { + op3_reg = IR_REG_NUM(op3_reg); + ir_emit_load(ctx, type, op3_reg, op3); + } + } else if (op2_reg != IR_REG_NONE && IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, type, op2_reg, op2); + op3_reg = op2_reg; + } else if (op3_reg != IR_REG_NONE && IR_REG_SPILLED(op3_reg)) { + op3_reg = IR_REG_NUM(op3_reg); + ir_emit_load(ctx, type, op3_reg, op3); + op2_reg = op3_reg; + } + + ir_emit_test_int_common(ctx, def, insn->op1, IR_NE); + + if (IR_IS_TYPE_INT(type)) { + bool eq = 0; + + if (op3_reg != IR_REG_NONE) { + if (op3_reg == def_reg) { + IR_ASSERT(op2_reg != IR_REG_NONE); + op3_reg = op2_reg; + eq = 1; // reverse + } else { + if (op2_reg != IR_REG_NONE) { + if (def_reg != op2_reg) { +// if (IR_IS_TYPE_INT(type)) { + ir_emit_mov(ctx, type, def_reg, op2_reg); +// } else { +// ir_emit_fp_mov(ctx, type, def_reg, op2_reg); +// } + } + } else if (IR_IS_CONST_REF(op2) && !IR_IS_SYM_CONST(ctx->ir_base[op2].op)) { + /* prevent "xor" and flags clobbering */ + ir_emit_mov_imm_int(ctx, type, def_reg, ctx->ir_base[op2].val.i64); + } else { + ir_emit_load_ex(ctx, type, def_reg, op2, def); + } + } + } else { + IR_ASSERT(op2_reg != IR_REG_NONE && op2_reg != def_reg); + if (IR_IS_CONST_REF(op3) && !IR_IS_SYM_CONST(ctx->ir_base[op3].op)) { + /* prevent "xor" and flags clobbering */ + ir_emit_mov_imm_int(ctx, type, def_reg, ctx->ir_base[op3].val.i64); + } else { + ir_emit_load_ex(ctx, type, def_reg, op3, def); + } + op3_reg = op2_reg; + eq = 1; // reverse + } + + if (eq) { + | ASM_REG_REG_OP2 cmovne, type, def_reg, op3_reg + } else { + | ASM_REG_REG_OP2 cmove, type, def_reg, op3_reg + } + } else { + | jne >2 + |1: + + if (op2_reg != IR_REG_NONE) { + if (def_reg != op2_reg) { + if (IR_IS_TYPE_INT(type)) { + ir_emit_mov(ctx, type, def_reg, op2_reg); + } else { + ir_emit_fp_mov(ctx, type, def_reg, op2_reg); + } + } + } else { + ir_emit_load_ex(ctx, type, def_reg, op2, def); + } + | jmp >3 + |2: + if (op3_reg != IR_REG_NONE) { + if (def_reg != op3_reg) { + if (IR_IS_TYPE_INT(type)) { + ir_emit_mov(ctx, type, def_reg, op3_reg); + } else { + ir_emit_fp_mov(ctx, type, def_reg, op3_reg); + } + } + } else { + ir_emit_load_ex(ctx, type, def_reg, op3, def); + } + |3: + } + + if (IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, type, def, def_reg); + } +} + static void ir_emit_cond_cmp_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; @@ -6784,6 +7305,12 @@ static void ir_emit_cond_cmp_fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) | jp >1 | jbe >2 break; + case IR_ORDERED: + | jp >2 + break; + case IR_UNORDERED: + | jnp >2 + break; } |1: @@ -6825,27 +7352,26 @@ static void ir_emit_return_void(ir_ctx *ctx) ir_emit_epilogue(ctx); -#ifdef IR_TARGET_X86 - if (sizeof(void*) == 4 && (ctx->flags & IR_FASTCALL_FUNC) && ctx->param_stack_size) { + if (data->ra_data.cc->cleanup_stack_by_callee && ctx->param_stack_size) { | ret ctx->param_stack_size - return; + } else { + | ret } -#endif - - | ret } static void ir_emit_return_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn) { + ir_backend_data *data = ctx->data; + ir_reg ret_reg = data->ra_data.cc->int_ret_reg; ir_reg op2_reg = ctx->regs[ref][2]; - if (op2_reg != IR_REG_INT_RET1) { + if (op2_reg != ret_reg) { ir_type type = ctx->ir_base[insn->op2].type; if (op2_reg != IR_REG_NONE && !IR_REG_SPILLED(op2_reg)) { - ir_emit_mov(ctx, type, IR_REG_INT_RET1, op2_reg); + ir_emit_mov(ctx, type, ret_reg, op2_reg); } else { - ir_emit_load(ctx, type, IR_REG_INT_RET1, insn->op2); + ir_emit_load(ctx, type, ret_reg, insn->op2); } } ir_emit_return_void(ctx); @@ -6853,47 +7379,68 @@ static void ir_emit_return_int(ir_ctx *ctx, ir_ref ref, ir_insn *insn) static void ir_emit_return_fp(ir_ctx *ctx, ir_ref ref, ir_insn *insn) { + ir_backend_data *data = ctx->data; ir_reg op2_reg = ctx->regs[ref][2]; ir_type type = ctx->ir_base[insn->op2].type; + ir_reg ret_reg = data->ra_data.cc->fp_ret_reg; -#ifdef IR_REG_FP_RET1 - if (op2_reg != IR_REG_FP_RET1) { + if (op2_reg != ret_reg && ret_reg != IR_REG_NONE) { if (op2_reg != IR_REG_NONE && !IR_REG_SPILLED(op2_reg)) { - ir_emit_fp_mov(ctx, type, IR_REG_FP_RET1, op2_reg); + ir_emit_fp_mov(ctx, type, ret_reg, op2_reg); } else { - ir_emit_load(ctx, type, IR_REG_FP_RET1, insn->op2); + ir_emit_load(ctx, type, ret_reg, insn->op2); } } -#else - ir_backend_data *data = ctx->data; - dasm_State **Dst = &data->dasm_state; - if (op2_reg == IR_REG_NONE || IR_REG_SPILLED(op2_reg)) { - ir_reg fp; - int32_t offset = ir_ref_spill_slot_offset(ctx, insn->op2, &fp); +#ifdef IR_TARGET_X86 + if (ret_reg == IR_REG_NONE) { + dasm_State **Dst = &data->dasm_state; - if (type == IR_DOUBLE) { - | fld qword [Ra(fp)+offset] - } else { - IR_ASSERT(type == IR_FLOAT); - | fld dword [Ra(fp)+offset] - } - } else { - int32_t offset = ctx->ret_slot; - ir_reg fp; + if (IR_IS_CONST_REF(insn->op2)) { + ir_insn *value = &ctx->ir_base[insn->op2]; + + if ((type == IR_FLOAT && value->val.f == 0.0) || (type == IR_DOUBLE && value->val.d == 0.0)) { + | fldz + } else if ((type == IR_FLOAT && value->val.f == 1.0) || (type == IR_DOUBLE && value->val.d == 1.0)) { + | fld1 + } else { + int label = ir_get_const_label(ctx, insn->op2); + + if (type == IR_DOUBLE) { + | fld qword [=>label] + } else { + IR_ASSERT(type == IR_FLOAT); + | fld dword [=>label] + } + } + } else if (op2_reg == IR_REG_NONE || IR_REG_SPILLED(op2_reg)) { + ir_reg fp; + int32_t offset = ir_ref_spill_slot_offset(ctx, insn->op2, &fp); - IR_ASSERT(offset != -1); - offset = IR_SPILL_POS_TO_OFFSET(offset); - fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - ir_emit_store_mem_fp(ctx, type, IR_MEM_BO(fp, offset), op2_reg); - if (type == IR_DOUBLE) { - | fld qword [Ra(fp)+offset] + if (type == IR_DOUBLE) { + | fld qword [Ra(fp)+offset] + } else { + IR_ASSERT(type == IR_FLOAT); + | fld dword [Ra(fp)+offset] + } } else { - IR_ASSERT(type == IR_FLOAT); - | fld dword [Ra(fp)+offset] + int32_t offset = ctx->ret_slot; + ir_reg fp; + + IR_ASSERT(offset != -1); + offset = IR_SPILL_POS_TO_OFFSET(offset); + fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + ir_emit_store_mem_fp(ctx, type, IR_MEM_BO(fp, offset), op2_reg); + if (type == IR_DOUBLE) { + | fld qword [Ra(fp)+offset] + } else { + IR_ASSERT(type == IR_FLOAT); + | fld dword [Ra(fp)+offset] + } } } #endif + ir_emit_return_void(ctx); } @@ -7144,7 +7691,20 @@ static void ir_emit_trunc(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_emit_load(ctx, src_type, op1_reg, insn->op1); } if (op1_reg != def_reg) { +#ifdef IR_TARGET_X86 + if (ir_type_size[dst_type] == 1 + && (op1_reg == IR_REG_RBP || op1_reg == IR_REG_RSI || op1_reg == IR_REG_RDI)) { + ir_backend_data *data = ctx->data; + dasm_State **Dst = &data->dasm_state; + + ir_emit_mov(ctx, src_type, def_reg, op1_reg); + | and Rb(def_reg), 0xff + } else { + ir_emit_mov(ctx, dst_type, def_reg, op1_reg); + } +#else ir_emit_mov(ctx, dst_type, def_reg, op1_reg); +#endif } } else { ir_emit_load_ex(ctx, dst_type, def_reg, insn->op1, def); @@ -7269,7 +7829,7 @@ static void ir_emit_bitcast(ir_ctx *ctx, ir_ref def, ir_insn *insn) } } } else if (IR_IS_CONST_REF(insn->op1)) { - int label = ir_const_label(ctx, insn->op1); + int label = ir_get_const_label(ctx, insn->op1); | ASM_FP_REG_TXT_OP movs, dst_type, def_reg, [=>label] } else { @@ -7301,13 +7861,80 @@ static void ir_emit_int2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) IR_ASSERT(IR_IS_TYPE_INT(src_type)); IR_ASSERT(IR_IS_TYPE_FP(dst_type)); IR_ASSERT(def_reg != IR_REG_NONE); + + if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { + op1_reg = IR_REG_NUM(op1_reg); + ir_emit_load(ctx, src_type, op1_reg, insn->op1); + } + + if (IR_IS_TYPE_UNSIGNED(src_type) && ir_type_size[src_type] >= sizeof(void*)) { + ir_reg tmp_reg = ctx->regs[def][2]; + + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op1_reg == IR_REG_NONE) { + if (IR_IS_CONST_REF(insn->op1)) { + IR_ASSERT(0); + } else { + ir_mem mem; + + if (ir_rule(ctx, insn->op1) & IR_FUSED) { + mem = ir_fuse_load(ctx, def, insn->op1); + } else { + mem = ir_ref_spill_slot(ctx, insn->op1); + } + ir_emit_load_mem_int(ctx, src_type, tmp_reg, mem); + op1_reg = tmp_reg; + } + } + if (sizeof(void*) == 4) { + if (tmp_reg == op1_reg) { + | add Rd(op1_reg), 0x80000000 + } else { + | lea Rd(tmp_reg), dword [Rd(op1_reg)+0x80000000] + op1_reg = tmp_reg; + } + } else { +|.if X64 + | test Rq(op1_reg), Rq(op1_reg) + | js >1 + |.cold_code + |1: + if (tmp_reg != op1_reg) { + | mov Rq(tmp_reg), Rq(op1_reg) + } + | shr Rq(tmp_reg), 1 + | adc Rq(tmp_reg), 0 + if (dst_type == IR_DOUBLE) { + if (ctx->mflags & IR_X86_AVX) { + | vxorps xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + | vcvtsi2sd xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), Rq(tmp_reg) + | vaddsd xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + } else { + | pxor xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + | cvtsi2sd xmm(def_reg-IR_REG_FP_FIRST), Rq(tmp_reg) + | addsd xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + } + } else { + IR_ASSERT(dst_type == IR_FLOAT); + if (ctx->mflags & IR_X86_AVX) { + | vxorps xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + | vcvtsi2ss xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), Rq(tmp_reg) + | vaddss xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + } else { + | pxor xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + | cvtsi2ss xmm(def_reg-IR_REG_FP_FIRST), Rq(tmp_reg) + | addss xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST) + } + } + | jmp >2 + |.code +|.endif + } + } + if (op1_reg != IR_REG_NONE) { bool src64 = 0; - if (IR_REG_SPILLED(op1_reg)) { - op1_reg = IR_REG_NUM(op1_reg); - ir_emit_load(ctx, src_type, op1_reg, insn->op1); - } if (IR_IS_TYPE_SIGNED(src_type)) { if (ir_type_size[src_type] < 4) { |.if X64 @@ -7346,7 +7973,6 @@ static void ir_emit_int2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) || } |.endif } else { - // TODO: uint64_t -> double src64 = 1; } } @@ -7392,6 +8018,40 @@ static void ir_emit_int2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) } |.endif } + |2: + if (sizeof(void*) == 4 && IR_IS_TYPE_UNSIGNED(src_type) && ir_type_size[src_type] >= sizeof(void*)) { + if (dst_type == IR_DOUBLE) { + uint32_t c = (sizeof(void*) == 4) ? 0x41e00000 : 0x43e00000; + if (!data->u2d_const) { + data->u2d_const = 1; + ir_rodata(ctx); + |.align 8 + |->u2d_const: + |.dword 0, c + |.code + } + if (ctx->mflags & IR_X86_AVX) { + | vaddsd xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), qword [->u2d_const] + } else { + | addsd xmm(def_reg-IR_REG_FP_FIRST), qword [->u2d_const] + } + } else { + uint32_t c = (sizeof(void*) == 4) ? 0x4f000000 : 0x5f000000; + if (!data->u2f_const) { + data->u2f_const = 1; + ir_rodata(ctx); + |.align 4 + |->u2f_const: + |.dword c + |.code + } + if (ctx->mflags & IR_X86_AVX) { + | vaddss xmm(def_reg-IR_REG_FP_FIRST), xmm(def_reg-IR_REG_FP_FIRST), dword [->u2f_const] + } else { + | addss xmm(def_reg-IR_REG_FP_FIRST), dword [->u2f_const] + } + } + } } else if (IR_IS_CONST_REF(insn->op1)) { IR_ASSERT(0); } else { @@ -7509,7 +8169,7 @@ static void ir_emit_fp2int(ir_ctx *ctx, ir_ref def, ir_insn *insn) |.endif } } else if (IR_IS_CONST_REF(insn->op1)) { - int label = ir_const_label(ctx, insn->op1); + int label = ir_get_const_label(ctx, insn->op1); if (!dst64) { if (src_type == IR_DOUBLE) { @@ -7630,7 +8290,7 @@ static void ir_emit_fp2fp(ir_ctx *ctx, ir_ref def, ir_insn *insn) } } } else if (IR_IS_CONST_REF(insn->op1)) { - int label = ir_const_label(ctx, insn->op1); + int label = ir_get_const_label(ctx, insn->op1); if (src_type == IR_DOUBLE) { if (ctx->mflags & IR_X86_AVX) { @@ -8255,276 +8915,323 @@ static void ir_emit_frame_addr(ir_ctx *ctx, ir_ref def) static void ir_emit_va_start(ir_ctx *ctx, ir_ref def, ir_insn *insn) { -#if defined(_WIN64) || defined(IR_TARGET_X86) ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; dasm_State **Dst = &data->dasm_state; - ir_reg fp; - int arg_area_offset; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - int32_t offset; - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + if (!cc->sysv_varargs) { + ir_reg fp; + int arg_area_offset; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + int32_t offset; + + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); } - offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - if (ctx->flags & IR_USE_FRAME_POINTER) { - fp = IR_REG_FRAME_POINTER; - arg_area_offset = sizeof(void*) * 2 + ctx->param_stack_size; + if (ctx->flags & IR_USE_FRAME_POINTER) { + fp = IR_REG_FRAME_POINTER; + arg_area_offset = sizeof(void*) * 2 + ctx->param_stack_size; + } else { + fp = IR_REG_STACK_POINTER; + arg_area_offset = ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*) + ctx->param_stack_size; + } + | lea Ra(tmp_reg), aword [Ra(fp)+arg_area_offset] + | mov aword [Ra(op2_reg)+offset], Ra(tmp_reg) } else { - fp = IR_REG_STACK_POINTER; - arg_area_offset = ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*) + ctx->param_stack_size; - } - | lea Ra(tmp_reg), aword [Ra(fp)+arg_area_offset] - | mov aword [Ra(op2_reg)+offset], Ra(tmp_reg) -#elif defined(IR_TARGET_X64) + IR_ASSERT(sizeof(void*) == 8); +#ifdef IR_TARGET_X64 |.if X64 - ir_backend_data *data = ctx->data; - dasm_State **Dst = &data->dasm_state; - ir_reg fp; - int reg_save_area_offset; - int overflow_arg_area_offset; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - bool have_reg_save_area = 0; - int32_t offset; + ir_reg fp; + int reg_save_area_offset; + int overflow_arg_area_offset; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + bool have_reg_save_area = 0; + int32_t offset; - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); } - offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - if (ctx->flags & IR_USE_FRAME_POINTER) { - fp = IR_REG_FRAME_POINTER; - reg_save_area_offset = -(ctx->stack_frame_size - ctx->stack_frame_alignment - ctx->locals_area_size); - overflow_arg_area_offset = sizeof(void*) * 2 + ctx->param_stack_size; - } else { - fp = IR_REG_STACK_POINTER; - reg_save_area_offset = ctx->locals_area_size + ctx->call_stack_size; - overflow_arg_area_offset = ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*) + ctx->param_stack_size; - } + if (ctx->flags & IR_USE_FRAME_POINTER) { + fp = IR_REG_FRAME_POINTER; + reg_save_area_offset = -(ctx->stack_frame_size - ctx->locals_area_size); + overflow_arg_area_offset = sizeof(void*) * 2 + ctx->param_stack_size; + } else { + fp = IR_REG_STACK_POINTER; + reg_save_area_offset = ctx->locals_area_size + ctx->call_stack_size; + overflow_arg_area_offset = ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*) + ctx->param_stack_size; + } - if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < IR_REG_INT_ARGS) { - | lea Ra(tmp_reg), aword [Ra(fp)+reg_save_area_offset] - have_reg_save_area = 1; - /* Set va_list.gp_offset */ - | mov dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, gp_offset))], sizeof(void*) * ctx->gp_reg_params - } else { - reg_save_area_offset -= sizeof(void*) * IR_REG_INT_ARGS; - /* Set va_list.gp_offset */ - | mov dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, gp_offset))], sizeof(void*) * IR_REG_INT_ARGS - } - if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < IR_REG_FP_ARGS) { - if (!have_reg_save_area) { + if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < cc->int_param_regs_count) { | lea Ra(tmp_reg), aword [Ra(fp)+reg_save_area_offset] have_reg_save_area = 1; + /* Set va_list.gp_offset */ + | mov dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, gp_offset))], sizeof(void*) * ctx->gp_reg_params + } else { + reg_save_area_offset -= sizeof(void*) * cc->int_param_regs_count; + /* Set va_list.gp_offset */ + | mov dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, gp_offset))], sizeof(void*) * cc->int_param_regs_count } - /* Set va_list.fp_offset */ - | mov dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, fp_offset))], sizeof(void*) * IR_REG_INT_ARGS + 16 * ctx->fp_reg_params - } else { - /* Set va_list.fp_offset */ - | mov dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, fp_offset))], sizeof(void*) * IR_REG_INT_ARGS + 16 * IR_REG_FP_ARGS - } - if (have_reg_save_area) { - /* Set va_list.reg_save_area */ - | mov qword [Ra(op2_reg)+(offset+offsetof(ir_va_list, reg_save_area))], Ra(tmp_reg) - } - | lea Ra(tmp_reg), aword [Ra(fp)+overflow_arg_area_offset] - /* Set va_list.overflow_arg_area */ - | mov qword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))], Ra(tmp_reg) + if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < cc->fp_param_regs_count) { + if (!have_reg_save_area) { + | lea Ra(tmp_reg), aword [Ra(fp)+reg_save_area_offset] + have_reg_save_area = 1; + } + /* Set va_list.fp_offset */ + | mov dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, fp_offset))], sizeof(void*) * cc->int_param_regs_count + 16 * ctx->fp_reg_params + } else { + /* Set va_list.fp_offset */ + | mov dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, fp_offset))], sizeof(void*) * cc->int_param_regs_count + 16 * cc->fp_param_regs_count + } + if (have_reg_save_area) { + /* Set va_list.reg_save_area */ + | mov qword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, reg_save_area))], Ra(tmp_reg) + } + | lea Ra(tmp_reg), aword [Ra(fp)+overflow_arg_area_offset] + /* Set va_list.overflow_arg_area */ + | mov qword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))], Ra(tmp_reg) |.endif -#else - IR_ASSERT(0 && "NIY va_start"); #endif + } } static void ir_emit_va_copy(ir_ctx *ctx, ir_ref def, ir_insn *insn) { -#if defined(_WIN64) || defined(IR_TARGET_X86) ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; dasm_State **Dst = &data->dasm_state; - ir_reg tmp_reg = ctx->regs[def][1]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg op3_reg = ctx->regs[def][3]; - int32_t op2_offset, op3_offset; - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + if (!cc->sysv_varargs) { + ir_reg tmp_reg = ctx->regs[def][1]; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg op3_reg = ctx->regs[def][3]; + int32_t op2_offset, op3_offset; + + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + op2_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op2_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); } - op2_offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op2_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - if (op3_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op3_reg)) { - op3_reg = IR_REG_NUM(op3_reg); - ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); + if (op3_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op3_reg)) { + op3_reg = IR_REG_NUM(op3_reg); + ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); + } + op3_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); + op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op3_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op3]); } - op3_offset = 0; + | mov Ra(tmp_reg), aword [Ra(op3_reg)+op3_offset] + | mov aword [Ra(op2_reg)+op2_offset], Ra(tmp_reg) } else { - IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); - op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op3_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op3].op3); - } - | mov Ra(tmp_reg), aword [Ra(op3_reg)+op3_offset] - | mov aword [Ra(op2_reg)+op2_offset], Ra(tmp_reg) -#elif defined(IR_TARGET_X64) + IR_ASSERT(sizeof(void*) == 8); +#ifdef IR_TARGET_X64 |.if X64 - ir_backend_data *data = ctx->data; - dasm_State **Dst = &data->dasm_state; - ir_reg tmp_reg = ctx->regs[def][1]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg op3_reg = ctx->regs[def][3]; - int32_t op2_offset, op3_offset; + ir_reg tmp_reg = ctx->regs[def][1]; + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg op3_reg = ctx->regs[def][3]; + int32_t op2_offset, op3_offset; - IR_ASSERT(tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); - } - op2_offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op2_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - if (op3_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op3_reg)) { - op3_reg = IR_REG_NUM(op3_reg); - ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); + IR_ASSERT(tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + op2_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op2_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); } - op3_offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); - op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - op3_offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op3].op3); - } - | mov Rd(tmp_reg), dword [Ra(op3_reg)+(op3_offset+offsetof(ir_va_list, gp_offset))] - | mov dword [Ra(op2_reg)+(op2_offset+offsetof(ir_va_list, gp_offset))], Rd(tmp_reg) - | mov Rd(tmp_reg), dword [Ra(op3_reg)+(op3_offset+offsetof(ir_va_list, fp_offset))] - | mov aword [Ra(op2_reg)+(op2_offset+offsetof(ir_va_list, fp_offset))], Ra(tmp_reg) - | mov Ra(tmp_reg), aword [Ra(op3_reg)+(op3_offset+offsetof(ir_va_list, overflow_arg_area))] - | mov aword [Ra(op2_reg)+(op2_offset+offsetof(ir_va_list, overflow_arg_area))], Ra(tmp_reg) - | mov Ra(tmp_reg), aword [Ra(op3_reg)+(op3_offset+offsetof(ir_va_list, reg_save_area))] - | mov aword [Ra(op2_reg)+(op2_offset+offsetof(ir_va_list, reg_save_area))], Ra(tmp_reg) + if (op3_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op3_reg)) { + op3_reg = IR_REG_NUM(op3_reg); + ir_emit_load(ctx, IR_ADDR, op3_reg, insn->op3); + } + op3_offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA); + op3_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + op3_offset = ir_local_offset(ctx, &ctx->ir_base[insn->op3]); + } + | mov Rd(tmp_reg), dword [Ra(op3_reg)+(op3_offset+offsetof(ir_x86_64_sysv_va_list, gp_offset))] + | mov dword [Ra(op2_reg)+(op2_offset+offsetof(ir_x86_64_sysv_va_list, gp_offset))], Rd(tmp_reg) + | mov Rd(tmp_reg), dword [Ra(op3_reg)+(op3_offset+offsetof(ir_x86_64_sysv_va_list, fp_offset))] + | mov aword [Ra(op2_reg)+(op2_offset+offsetof(ir_x86_64_sysv_va_list, fp_offset))], Ra(tmp_reg) + | mov Ra(tmp_reg), aword [Ra(op3_reg)+(op3_offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))] + | mov aword [Ra(op2_reg)+(op2_offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))], Ra(tmp_reg) + | mov Ra(tmp_reg), aword [Ra(op3_reg)+(op3_offset+offsetof(ir_x86_64_sysv_va_list, reg_save_area))] + | mov aword [Ra(op2_reg)+(op2_offset+offsetof(ir_x86_64_sysv_va_list, reg_save_area))], Ra(tmp_reg) |.endif -#else - IR_ASSERT(0 && "NIY va_copy"); #endif + } } static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn) { -#if defined(_WIN64) || defined(IR_TARGET_X86) ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; dasm_State **Dst = &data->dasm_state; - ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - int32_t offset; - IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + if (!cc->sysv_varargs) { + ir_type type = insn->type; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + int32_t offset; + + IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); + } + | mov Ra(tmp_reg), aword [Ra(op2_reg)+offset] + if (!cc->pass_struct_by_val || !insn->op3) { + if (def_reg != IR_REG_NONE) { + ir_emit_load_mem(ctx, type, def_reg, IR_MEM_B(tmp_reg)); + } + | add Ra(tmp_reg), IR_MAX(ir_type_size[type], sizeof(void*)) + } else { + int size = IR_VA_ARG_SIZE(insn->op3); + + if (def_reg != IR_REG_NONE) { + IR_ASSERT(type == IR_ADDR); + int align = IR_VA_ARG_ALIGN(insn->op3); + + if (align > (int)sizeof(void*)) { + | add Ra(tmp_reg), (align-1) + | and Ra(tmp_reg), ~(align-1) + } + | mov Ra(def_reg), Ra(tmp_reg) + } + | add Ra(tmp_reg), IR_ALIGNED_SIZE(size, sizeof(void*)) + } + | mov aword [Ra(op2_reg)+offset], Ra(tmp_reg) + if (def_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, type, def, def_reg); } - offset = 0; } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - | mov Ra(tmp_reg), aword [Ra(op2_reg)+offset] - ir_emit_load_mem(ctx, type, def_reg, IR_MEM_B(tmp_reg)); - | add Ra(tmp_reg), IR_MAX(ir_type_size[type], sizeof(void*)) - | mov aword [Ra(op2_reg)+offset], Ra(tmp_reg) - if (IR_REG_SPILLED(ctx->regs[def][0])) { - ir_emit_store(ctx, type, def, def_reg); - } -#elif defined(IR_TARGET_X64) + IR_ASSERT(sizeof(void*) == 8); +#ifdef IR_TARGET_X64 |.if X64 - ir_backend_data *data = ctx->data; - dasm_State **Dst = &data->dasm_state; - ir_type type = insn->type; - ir_reg def_reg = ctx->regs[def][0]; - ir_reg op2_reg = ctx->regs[def][2]; - ir_reg tmp_reg = ctx->regs[def][3]; - int32_t offset; + ir_type type = insn->type; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); + ir_reg op2_reg = ctx->regs[def][2]; + ir_reg tmp_reg = ctx->regs[def][3]; + int32_t offset; - IR_ASSERT(def_reg != IR_REG_NONE&& tmp_reg != IR_REG_NONE); - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE); + if (op2_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(op2_reg)) { + op2_reg = IR_REG_NUM(op2_reg); + ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + } + offset = 0; + } else { + IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); + op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]); + } + if (insn->op3) { + /* long struct arguemnt */ + IR_ASSERT(type == IR_ADDR); + int align = IR_VA_ARG_ALIGN(insn->op3); + int size = IR_VA_ARG_SIZE(insn->op3); + + | mov Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))] + if (align > (int)sizeof(void*)) { + | add Ra(tmp_reg), (align-1) + | and Ra(tmp_reg), ~(align-1) + } + if (def_reg != IR_REG_NONE) { + | mov Ra(def_reg), Ra(tmp_reg) + } + | add Ra(tmp_reg), IR_ALIGNED_SIZE(size, sizeof(void*)) + | mov aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))], Ra(tmp_reg) + } else if (IR_IS_TYPE_INT(type)) { + | mov Rd(tmp_reg), dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, gp_offset))] + | cmp Rd(tmp_reg), sizeof(void*) * cc->int_param_regs_count + | jge >1 + | add Rd(tmp_reg), sizeof(void*) + | mov dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, gp_offset))], Rd(tmp_reg) + | add Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, reg_save_area))] + | jmp >2 + |1: + | mov Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))] + | add Ra(tmp_reg), sizeof(void*) + | mov aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))], Ra(tmp_reg) + |2: + if (def_reg != IR_REG_NONE) { + if (ir_type_size[type] == 8) { + | mov Rq(def_reg), qword [Ra(tmp_reg)-sizeof(void*)] + } else { + | mov Rd(def_reg), dword [Ra(tmp_reg)-sizeof(void*)] + } + } + } else { + | mov Rd(tmp_reg), dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, fp_offset))] + | cmp Rd(tmp_reg), sizeof(void*) * cc->int_param_regs_count + 16 * cc->fp_param_regs_count + | jge >1 + | add Rd(tmp_reg), 16 + | mov dword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, fp_offset))], Rd(tmp_reg) + | add Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, reg_save_area))] + if (def_reg != IR_REG_NONE) { + ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, -16)); + } + | jmp >2 + |1: + | mov Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))] + if (def_reg != IR_REG_NONE) { + ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0)); + } + | add Ra(tmp_reg), 8 + | mov aword [Ra(op2_reg)+(offset+offsetof(ir_x86_64_sysv_va_list, overflow_arg_area))], Ra(tmp_reg) + |2: + } + if (def_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, type, def, def_reg); } - offset = 0; - } else { - IR_ASSERT(ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA); - op2_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; - offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[insn->op2].op3); - } - if (IR_IS_TYPE_INT(type)) { - | mov Rd(tmp_reg), dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, gp_offset))] - | cmp Rd(tmp_reg), sizeof(void*)*IR_REG_INT_ARGS - | jge >1 - | add Rd(tmp_reg), sizeof(void*) - | mov dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, gp_offset))], Rd(tmp_reg) - | add Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, reg_save_area))] - | jmp >2 - |1: - | mov Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))] - | add Ra(tmp_reg), sizeof(void*) - | mov aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))], Ra(tmp_reg) - |2: - | mov Ra(def_reg), aword [Ra(tmp_reg)-sizeof(void*)] - } else { - | mov Rd(tmp_reg), dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, fp_offset))] - | cmp Rd(tmp_reg), sizeof(void*) * IR_REG_INT_ARGS + 16 * IR_REG_FP_ARGS - | jge >1 - | add Rd(tmp_reg), 16 - | mov dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, fp_offset))], Rd(tmp_reg) - | add Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, reg_save_area))] - ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, -16)); - | jmp >2 - |1: - | mov Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))] - ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0)); - | add Ra(tmp_reg), 8 - | mov aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))], Ra(tmp_reg) - |2: - } - if (IR_REG_SPILLED(ctx->regs[def][0])) { - ir_emit_store(ctx, type, def, def_reg); - } |.endif -#else - IR_ASSERT(0 && "NIY va_arg"); #endif + } } static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) @@ -8541,6 +9248,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) ir_val min, max; ir_reg op2_reg = ctx->regs[def][2]; ir_reg tmp_reg = ctx->regs[def][3]; + bool has_case_range = 0; type = ctx->ir_base[insn->op2].type; IR_ASSERT(tmp_reg != IR_REG_NONE); @@ -8570,6 +9278,21 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) max.u64 = (int64_t)IR_MAX(max.u64, val->val.u64); } count++; + } else if (use_insn->op == IR_CASE_RANGE) { + has_case_range = 1; + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + ir_insn *val2 = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val2->op)); + if (IR_IS_TYPE_SIGNED(type)) { + IR_ASSERT(IR_IS_TYPE_SIGNED(val->type)); + min.i64 = IR_MIN(min.i64, val->val.i64); + max.i64 = IR_MAX(max.i64, val2->val.i64); + } else { + IR_ASSERT(!IR_IS_TYPE_SIGNED(val->type)); + min.u64 = (int64_t)IR_MIN(min.u64, val->val.u64); + max.u64 = (int64_t)IR_MAX(max.u64, val2->val.u64); + } } else { IR_ASSERT(use_insn->op == IR_CASE_DEFAULT); default_label = ir_skip_empty_target_blocks(ctx, use_block); @@ -8583,7 +9306,7 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } /* Generate a table jmp or a seqence of calls */ - if (count > 2 && (max.i64-min.i64) < count * 8) { + if (!has_case_range && count > 2 && (max.i64-min.i64) < count * 8) { int *labels = ir_mem_malloc(sizeof(int) * (size_t)(max.i64 - min.i64 + 1)); for (i = 0; i <= (max.i64 - min.i64); i++) { @@ -8715,7 +9438,8 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]); | .aword &addr - if (ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { + if (ctx->ir_base[bb->start].op1 == def + && ctx->ir_base[bb->start].op != IR_CASE_DEFAULT) { bb->flags |= IR_BB_EMPTY; } continue; @@ -8737,7 +9461,9 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) val = &ctx->ir_base[use_insn->op2]; IR_ASSERT(!IR_IS_SYM_CONST(val->op)); label = ir_skip_empty_target_blocks(ctx, use_block); - if (IR_IS_32BIT(type, val->val)) { + if (val->val.u64 == 0) { + | ASM_REG_REG_OP test, type, op2_reg, op2_reg + } else if (IR_IS_32BIT(type, val->val)) { | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i32 } else { IR_ASSERT(sizeof(void*) == 8); @@ -8747,6 +9473,42 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) |.endif } | je =>label + } else if (use_insn->op == IR_CASE_RANGE) { + val = &ctx->ir_base[use_insn->op2]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (IR_IS_32BIT(type, val->val)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i32 + } else { + IR_ASSERT(sizeof(void*) == 8); +|.if X64 + | mov64 Ra(tmp_reg), val->val.i64 + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg +|.endif + } + if (IR_IS_TYPE_SIGNED(type)) { + | jl >1 + } else { + | jb >1 + } + val = &ctx->ir_base[use_insn->op3]; + IR_ASSERT(!IR_IS_SYM_CONST(val->op3)); + label = ir_skip_empty_target_blocks(ctx, use_block); + if (IR_IS_32BIT(type, val->val)) { + | ASM_REG_IMM_OP cmp, type, op2_reg, val->val.i32 + } else { + IR_ASSERT(sizeof(void*) == 8); +|.if X64 + | mov64 Ra(tmp_reg), val->val.i64 + | ASM_REG_REG_OP cmp, type, op2_reg, tmp_reg +|.endif + } + if (IR_IS_TYPE_SIGNED(type)) { + | jle =>label + } else { + | jbe =>label + } + |1: } } if (default_label) { @@ -8755,55 +9517,67 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn) } } -static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn) +static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn, const ir_call_conv_dsc *cc, int *copy_stack_ptr) { int j, n; ir_type type; int int_param = 0; int fp_param = 0; - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; int32_t used_stack = 0; - -#ifdef IR_HAVE_FASTCALL - if (sizeof(void*) == 4 && ir_is_fastcall(ctx, insn)) { - int_reg_params_count = IR_REG_INT_FCARGS; - fp_reg_params_count = IR_REG_FP_FCARGS; - } -#endif + int32_t copy_stack = 0; n = insn->inputs_count; for (j = 3; j <= n; j++) { - type = ctx->ir_base[ir_insn_op(insn, j)].type; + ir_insn *arg = &ctx->ir_base[ir_insn_op(insn, j)]; + type = arg->type; if (IR_IS_TYPE_INT(type)) { - if (int_param >= int_reg_params_count) { + if (arg->op == IR_ARGVAL) { + int size = arg->op2; + int align = arg->op3; + + if (!cc->pass_struct_by_val) { + copy_stack += size; + align = IR_MAX((int)sizeof(void*), align); + copy_stack = IR_ALIGNED_SIZE(copy_stack, align); + type = IR_ADDR; + } else { + align = IR_MAX((int)sizeof(void*), align); + used_stack = IR_ALIGNED_SIZE(used_stack, align); + used_stack += size; + used_stack = IR_ALIGNED_SIZE(used_stack, sizeof(void*)); + continue; + } + } + if (int_param >= cc->int_param_regs_count) { used_stack += IR_MAX(sizeof(void*), ir_type_size[type]); } int_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - fp_param++; -#endif + if (cc->shadow_param_regs) { + fp_param++; + } } else { IR_ASSERT(IR_IS_TYPE_FP(type)); - if (fp_param >= fp_reg_params_count) { + if (fp_param >= cc->fp_param_regs_count) { used_stack += IR_MAX(sizeof(void*), ir_type_size[type]); } fp_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - int_param++; -#endif + if (cc->shadow_param_regs) { + int_param++; + } } } /* Reserved "home space" or "shadow store" for register arguments (used in Windows64 ABI) */ - used_stack += IR_SHADOW_ARGS; + used_stack += cc->shadow_store_size; + + copy_stack = IR_ALIGNED_SIZE(copy_stack, 16); + used_stack += copy_stack; + *copy_stack_ptr = copy_stack; return used_stack; } -static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg) +static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, const ir_proto_t *proto, const ir_call_conv_dsc *cc, ir_reg tmp_reg) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; @@ -8815,11 +9589,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg int int_param = 0; int fp_param = 0; int count = 0; - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; - int32_t used_stack, stack_offset = IR_SHADOW_ARGS; + int32_t used_stack, copy_stack = 0, stack_offset = cc->shadow_store_size; ir_copy *copies; bool do_pass3 = 0; /* For temporaries we may use any scratch registers except for registers used for parameters */ @@ -8834,36 +9604,24 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg tmp_reg = IR_REG_RAX; } -#ifdef IR_HAVE_FASTCALL - if (sizeof(void*) == 4 && ir_is_fastcall(ctx, insn)) { - int_reg_params_count = IR_REG_INT_FCARGS; - fp_reg_params_count = IR_REG_FP_FCARGS; - int_reg_params = _ir_int_fc_reg_params; - fp_reg_params = _ir_fp_fc_reg_params; - } -#endif - if (insn->op == IR_CALL - && (ctx->flags & IR_PREALLOCATED_STACK) -#ifdef IR_HAVE_FASTCALL - && !ir_is_fastcall(ctx, insn) /* fast call functions restore stack pointer */ -#endif - ) { - // TODO: support for preallocated stack - used_stack = 0; + && (ctx->flags2 & IR_PREALLOCATED_STACK) + && !cc->cleanup_stack_by_callee) { + if (!cc->pass_struct_by_val) { + used_stack = ir_call_used_stack(ctx, insn, cc, ©_stack); + } else { + used_stack = 0; + } } else { - used_stack = ir_call_used_stack(ctx, insn); - if (IR_SHADOW_ARGS + used_stack = ir_call_used_stack(ctx, insn, cc, ©_stack); + if (cc->shadow_store_size && insn->op == IR_TAILCALL - && used_stack == IR_SHADOW_ARGS) { + && used_stack == cc->shadow_store_size) { used_stack = 0; } if (ctx->fixed_call_stack_size && used_stack <= ctx->fixed_call_stack_size -#ifdef IR_HAVE_FASTCALL - && !ir_is_fastcall(ctx, insn) /* fast call functions restore stack pointer */ -#endif - ) { + && !cc->cleanup_stack_by_callee) { used_stack = 0; } else { /* Stack must be 16 byte aligned */ @@ -8875,6 +9633,45 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg } } + if (copy_stack) { + /* Copy struct arguments */ + IR_ASSERT(sizeof(void*) == 8); +|.if X64 + int copy_stack_offset = 0; + + for (j = 3; j <= n; j++) { + arg = ir_insn_op(insn, j); + src_reg = ir_get_alocated_reg(ctx, def, j); + arg_insn = &ctx->ir_base[arg]; + type = arg_insn->type; + + if (arg_insn->op == IR_ARGVAL) { + /* make a stack copy */ + int size = arg_insn->op2; + int align = arg_insn->op3; + + copy_stack_offset += size; + align = IR_MAX((int)sizeof(void*), align); + copy_stack_offset = IR_ALIGNED_SIZE(copy_stack_offset, align); + src_reg = ctx->regs[arg][1]; + + | lea rdi, [rsp + (used_stack - copy_stack_offset)] + if (src_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(src_reg)) { + src_reg = IR_REG_NUM(src_reg); + ir_emit_load(ctx, IR_ADDR, src_reg, arg_insn->op1); + } + | mov rsi, Ra(src_reg) + } else { + ir_emit_load(ctx, IR_ADDR, IR_REG_RSI, arg_insn->op1); + } + ir_emit_load_imm_int(ctx, IR_ADDR, IR_REG_RCX, size); + | rep; movsb + } + } +|.endif + } + /* 1. move all register arguments that should be passed through stack * and collect arguments that should be passed through registers */ copies = ir_mem_malloc((n - 2) * sizeof(ir_copy)); @@ -8884,31 +9681,82 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg arg_insn = &ctx->ir_base[arg]; type = arg_insn->type; if (IR_IS_TYPE_INT(type)) { - if (int_param < int_reg_params_count) { - dst_reg = int_reg_params[int_param]; + if (arg_insn->op == IR_ARGVAL && cc->pass_struct_by_val) { + int size = arg_insn->op2; + int align = arg_insn->op3; + align = IR_MAX((int)sizeof(void*), align); + stack_offset = IR_ALIGNED_SIZE(stack_offset, align); + if (size) { + src_reg = ctx->regs[arg][1]; + if (src_reg != IR_REG_NONE) { + if (IR_REG_SPILLED(src_reg)) { + src_reg = IR_REG_NUM(src_reg); + ir_emit_load(ctx, IR_ADDR, src_reg, arg_insn->op1); + } + if (src_reg != IR_REG_RSI) { + |.if X64 + | mov rsi, Ra(src_reg) + |.else + | mov esi, Ra(src_reg) + |.endif + } + } else { + ir_emit_load(ctx, IR_ADDR, IR_REG_RSI, arg_insn->op1); + } + if (stack_offset == 0) { + |.if X64 + | mov rdi, rsp + |.else + | mov edi, esp + |.endif + } else { + |.if X64 + | lea rdi, [rsp+stack_offset] + |.else + | lea edi, [esp+stack_offset] + |.endif + } + |.if X64 + | mov rcx, size + | rep; movsb + |.else + | mov ecx, size + | rep; movsb + |.endif + } + stack_offset += size; + stack_offset = IR_ALIGNED_SIZE(stack_offset, sizeof(void*)); + continue; + } + if (int_param < cc->int_param_regs_count) { + dst_reg = cc->int_param_regs[int_param]; } else { dst_reg = IR_REG_NONE; /* pass argument through stack */ } int_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - fp_param++; -#endif + if (cc->shadow_param_regs) { + fp_param++; + } + if (arg_insn->op == IR_ARGVAL && !cc->pass_struct_by_val) { + do_pass3 = 3; + continue; + } } else { IR_ASSERT(IR_IS_TYPE_FP(type)); - if (fp_param < fp_reg_params_count) { - dst_reg = fp_reg_params[fp_param]; + if (fp_param < cc->fp_param_regs_count) { + dst_reg = cc->fp_param_regs[fp_param]; } else { dst_reg = IR_REG_NONE; /* pass argument through stack */ } fp_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - int_param++; -#endif + if (cc->shadow_param_regs) { + int_param++; + } } if (dst_reg != IR_REG_NONE) { - if (src_reg == IR_REG_NONE) { + if (IR_IS_CONST_REF(arg) || + src_reg == IR_REG_NONE || + (IR_REG_SPILLED(src_reg) && !IR_REGSET_IN(cc->preserved_regs, IR_REG_NUM(src_reg)))) { /* delay CONST->REG and MEM->REG moves to third pass */ do_pass3 = 1; } else { @@ -8943,7 +9791,9 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg /* 3. move the remaining memory and immediate values */ if (do_pass3) { - stack_offset = IR_SHADOW_ARGS; + int copy_stack_offset = 0; + + stack_offset = cc->shadow_store_size; int_param = 0; fp_param = 0; for (j = 3; j <= n; j++) { @@ -8952,31 +9802,61 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg arg_insn = &ctx->ir_base[arg]; type = arg_insn->type; if (IR_IS_TYPE_INT(type)) { - if (int_param < int_reg_params_count) { - dst_reg = int_reg_params[int_param]; + if (arg_insn->op == IR_ARGVAL) { + int size = arg_insn->op2; + int align = arg_insn->op3; + + if (cc->pass_struct_by_val) { + align = IR_MAX((int)sizeof(void*), align); + stack_offset = IR_ALIGNED_SIZE(stack_offset, align); + stack_offset += size; + stack_offset = IR_ALIGNED_SIZE(stack_offset, sizeof(void*)); + continue; + } else { + /* pass pointer to the copy on stack */ + copy_stack_offset += size; + align = IR_MAX((int)sizeof(void*), align); + copy_stack_offset = IR_ALIGNED_SIZE(copy_stack_offset, align); + if (int_param < cc->int_param_regs_count) { + dst_reg = cc->int_param_regs[int_param]; + | lea Ra(dst_reg), [r4 + (used_stack - copy_stack_offset)] + } else { + | lea Ra(tmp_reg), [r4 + (used_stack - copy_stack_offset)] + ir_emit_store_mem_int(ctx, IR_ADDR, IR_MEM_BO(IR_REG_STACK_POINTER, stack_offset), tmp_reg); + stack_offset += sizeof(void*); + } + int_param++; + if (cc->shadow_param_regs) { + fp_param++; + } + continue; + } + } + if (int_param < cc->int_param_regs_count) { + dst_reg = cc->int_param_regs[int_param]; } else { dst_reg = IR_REG_NONE; /* argument already passed through stack */ } int_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - fp_param++; -#endif + if (cc->shadow_param_regs) { + fp_param++; + } } else { IR_ASSERT(IR_IS_TYPE_FP(type)); - if (fp_param < fp_reg_params_count) { - dst_reg = fp_reg_params[fp_param]; + if (fp_param < cc->fp_param_regs_count) { + dst_reg = cc->fp_param_regs[fp_param]; } else { dst_reg = IR_REG_NONE; /* argument already passed through stack */ } fp_param++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - int_param++; -#endif + if (cc->shadow_param_regs) { + int_param++; + } } if (dst_reg != IR_REG_NONE) { - if (src_reg == IR_REG_NONE) { + if (IR_IS_CONST_REF(arg) || + src_reg == IR_REG_NONE || + (IR_REG_SPILLED(src_reg) && !IR_REGSET_IN(cc->preserved_regs, IR_REG_NUM(src_reg)))) { if (IR_IS_TYPE_INT(type)) { if (IR_IS_CONST_REF(arg)) { if (type == IR_I8 || type == IR_I16) { @@ -9044,17 +9924,16 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg } } -#ifdef _WIN64 /* WIN64 calling convention requires duplcation of parameters passed in FP register into GP ones */ - if (ir_is_vararg(ctx, insn)) { - n = IR_MIN(n, IR_MAX_REG_ARGS + 2); + if (proto && (proto->flags & IR_VARARG_FUNC) && cc->shadow_param_regs) { + n = IR_MIN(n, IR_MIN(cc->int_param_regs_count, cc->fp_param_regs_count) + 2); for (j = 3; j <= n; j++) { arg = ir_insn_op(insn, j); arg_insn = &ctx->ir_base[arg]; type = arg_insn->type; if (IR_IS_TYPE_FP(type)) { - src_reg = fp_reg_params[j-3]; - dst_reg = int_reg_params[j-3]; + src_reg = cc->fp_param_regs[j-3]; + dst_reg = cc->int_param_regs[j-3]; |.if X64 if (ctx->mflags & IR_X86_AVX) { | vmovd Rq(dst_reg), xmm(src_reg-IR_REG_FP_FIRST) @@ -9065,38 +9944,46 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg } } } -#endif -#ifdef IR_REG_VARARG_FP_REGS - /* set hidden argument to specify the number of vector registers used */ - if (ir_is_vararg(ctx, insn)) { - fp_param = IR_MIN(fp_param, fp_reg_params_count); - | mov Rd(IR_REG_VARARG_FP_REGS), fp_param + + if (insn->op == IR_CALL && (ctx->flags2 & IR_PREALLOCATED_STACK)) { + used_stack = 0; + } + + if (proto && (proto->flags & IR_VARARG_FUNC) && cc->fp_varargs_reg != IR_REG_NONE) { + /* set hidden argument to specify the number of vector registers used */ + fp_param = IR_MIN(fp_param, cc->fp_param_regs_count); + if (fp_param) { + | mov Rd(cc->fp_varargs_reg), fp_param + } else { + | xor Rd(cc->fp_varargs_reg), Rd(cc->fp_varargs_reg) + } } -#endif return used_stack; } -static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used_stack) +static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, const ir_proto_t *proto, const ir_call_conv_dsc *cc, int32_t used_stack) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; ir_reg def_reg; + ir_ref func = insn->op2; - if (IR_IS_CONST_REF(insn->op2)) { - void *addr = ir_call_addr(ctx, insn, &ctx->ir_base[insn->op2]); + if (!IR_IS_CONST_REF(func) && ctx->rules[func] == (IR_FUSED | IR_SIMPLE | IR_PROTO)) { + func = ctx->ir_base[func].op1; + } + if (IR_IS_CONST_REF(func)) { + void *addr = ir_call_addr(ctx, insn, &ctx->ir_base[func]); if (sizeof(void*) == 4 || IR_MAY_USE_32BIT_ADDR(ctx->code_buffer, addr)) { | call aword &addr } else { |.if X64 -|| ir_reg tmp_reg = IR_REG_RAX; - -#ifdef IR_REG_VARARG_FP_REGS -|| if (ir_is_vararg(ctx, insn)) { -|| tmp_reg = IR_REG_R11; +|| ir_reg tmp_reg = cc->int_ret_reg; +|| +|| if (proto && (proto->flags & IR_VARARG_FUNC) && tmp_reg == cc->fp_varargs_reg) { +|| tmp_reg = IR_REG_R11; // TODO: avoid usage of hardcoded temporary register ??? || } -#endif || if (IR_IS_SIGNED_32BIT(addr)) { | mov Rq(tmp_reg), ((ptrdiff_t)addr) // 0x48 0xc7 0xc0 || } else { @@ -9111,16 +9998,16 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used if (op2_reg != IR_REG_NONE) { if (IR_REG_SPILLED(op2_reg)) { op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); + ir_emit_load(ctx, IR_ADDR, op2_reg, func); } | call Ra(op2_reg) } else { ir_mem mem; - if (ir_rule(ctx, insn->op2) & IR_FUSED) { - mem = ir_fuse_load(ctx, def, insn->op2); + if (ir_rule(ctx, func) & IR_FUSED) { + mem = ir_fuse_load(ctx, def, func); } else { - mem = ir_ref_spill_slot(ctx, insn->op2); + mem = ir_ref_spill_slot(ctx, func); } | ASM_TMEM_OP call, aword, mem @@ -9131,7 +10018,7 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used int32_t aligned_stack = IR_ALIGNED_SIZE(used_stack, 16); ctx->call_stack_size -= aligned_stack; - if (ir_is_fastcall(ctx, insn)) { + if (cc->cleanup_stack_by_callee) { aligned_stack -= used_stack; if (aligned_stack) { | add Ra(IR_REG_RSP), aligned_stack @@ -9145,31 +10032,32 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used if (IR_IS_TYPE_INT(insn->type)) { def_reg = IR_REG_NUM(ctx->regs[def][0]); if (def_reg != IR_REG_NONE) { - if (def_reg != IR_REG_INT_RET1) { - ir_emit_mov(ctx, insn->type, def_reg, IR_REG_INT_RET1); + if (def_reg != cc->int_ret_reg) { + ir_emit_mov(ctx, insn->type, def_reg, cc->int_ret_reg); } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, insn->type, def, def_reg); } } else if (ctx->use_lists[def].count > 1) { - ir_emit_store(ctx, insn->type, def, IR_REG_INT_RET1); + ir_emit_store(ctx, insn->type, def, cc->int_ret_reg); } } else { IR_ASSERT(IR_IS_TYPE_FP(insn->type)); def_reg = IR_REG_NUM(ctx->regs[def][0]); -#ifdef IR_REG_FP_RET1 - if (def_reg != IR_REG_NONE) { - if (def_reg != IR_REG_FP_RET1) { - ir_emit_fp_mov(ctx, insn->type, def_reg, IR_REG_FP_RET1); - } - if (IR_REG_SPILLED(ctx->regs[def][0])) { - ir_emit_store(ctx, insn->type, def, def_reg); + if (cc->fp_ret_reg != IR_REG_NONE) { + if (def_reg != IR_REG_NONE) { + if (def_reg != cc->fp_ret_reg) { + ir_emit_fp_mov(ctx, insn->type, def_reg, cc->fp_ret_reg); + } + if (IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, insn->type, def, def_reg); + } + } else if (ctx->use_lists[def].count > 1) { + ir_emit_store(ctx, insn->type, def, cc->fp_ret_reg); } - } else if (ctx->use_lists[def].count > 1) { - ir_emit_store(ctx, insn->type, def, IR_REG_FP_RET1); } -#else - if (ctx->use_lists[def].count > 1) { +#ifdef IR_TARGET_X86 + if (ctx->use_lists[def].count > 1 && cc->fp_ret_reg == IR_REG_NONE) { int32_t offset; ir_reg fp; @@ -9205,38 +10093,96 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used static void ir_emit_call(ir_ctx *ctx, ir_ref def, ir_insn *insn) { - int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); - ir_emit_call_ex(ctx, def, insn, used_stack); + const ir_proto_t *proto = ir_call_proto(ctx, insn); + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + int32_t used_stack = ir_emit_arguments(ctx, def, insn, proto, cc, ctx->regs[def][1]); + ir_emit_call_ex(ctx, def, insn, proto, cc, used_stack); } static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; dasm_State **Dst = &data->dasm_state; - int32_t used_stack = ir_emit_arguments(ctx, def, insn, ctx->regs[def][1]); + const ir_proto_t *proto = ir_call_proto(ctx, insn); + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + int32_t used_stack = ir_emit_arguments(ctx, def, insn, proto, cc, ctx->regs[def][1]); + ir_ref func = insn->op2; if (used_stack != 0) { - ir_emit_call_ex(ctx, def, insn, used_stack); + ir_emit_call_ex(ctx, def, insn, proto, cc, used_stack); ir_emit_return_void(ctx); return; } + /* Move op2 to a tmp register before epilogue if it's in + * used_preserved_regs, because it will be overridden. */ + + ir_reg op2_reg = IR_REG_NONE; + ir_mem mem = IR_MEM_B(IR_REG_NONE); + if (!IR_IS_CONST_REF(func) && ctx->rules[func] == (IR_FUSED | IR_SIMPLE | IR_PROTO)) { + func = ctx->ir_base[func].op1; + } + if (!IR_IS_CONST_REF(func)) { + op2_reg = ctx->regs[def][2]; + + ir_regset preserved_regs = (ir_regset)ctx->used_preserved_regs | IR_REGSET(IR_REG_STACK_POINTER); + if (ctx->flags & IR_USE_FRAME_POINTER) { + preserved_regs |= IR_REGSET(IR_REG_FRAME_POINTER); + } + + bool is_spill_slot = op2_reg != IR_REG_NONE + && IR_REG_SPILLED(op2_reg) + && ctx->vregs[func]; + + if (op2_reg != IR_REG_NONE && !is_spill_slot) { + if (IR_REGSET_IN(preserved_regs, IR_REG_NUM(op2_reg))) { + ir_ref orig_op2_reg = op2_reg; + op2_reg = IR_REG_RAX; + + if (IR_REG_SPILLED(orig_op2_reg)) { + ir_emit_load(ctx, IR_ADDR, op2_reg, func); + } else { + ir_type type = ctx->ir_base[func].type; + | ASM_REG_REG_OP mov, type, op2_reg, IR_REG_NUM(orig_op2_reg) + } + } else { + op2_reg = IR_REG_NUM(op2_reg); + } + } else { + if (ir_rule(ctx, func) & IR_FUSED) { + IR_ASSERT(op2_reg == IR_REG_NONE); + mem = ir_fuse_load(ctx, def, func); + } else { + mem = ir_ref_spill_slot(ctx, func); + } + ir_reg base = IR_MEM_BASE(mem); + ir_reg index = IR_MEM_INDEX(mem); + if ((base != IR_REG_NONE && IR_REGSET_IN(preserved_regs, base)) || + (index != IR_REG_NONE && IR_REGSET_IN(preserved_regs, index))) { + op2_reg = IR_REG_RAX; + + ir_type type = ctx->ir_base[func].type; + ir_emit_load_mem_int(ctx, type, op2_reg, mem); + } else { + op2_reg = IR_REG_NONE; + } + } + } + ir_emit_epilogue(ctx); - if (IR_IS_CONST_REF(insn->op2)) { - void *addr = ir_call_addr(ctx, insn, &ctx->ir_base[insn->op2]); + if (IR_IS_CONST_REF(func)) { + void *addr = ir_call_addr(ctx, insn, &ctx->ir_base[func]); if (sizeof(void*) == 4 || IR_MAY_USE_32BIT_ADDR(ctx->code_buffer, addr)) { | jmp aword &addr } else { |.if X64 -|| ir_reg tmp_reg = IR_REG_RAX; - -#ifdef IR_REG_VARARG_FP_REGS -|| if (ir_is_vararg(ctx, insn)) { -|| tmp_reg = IR_REG_R11; +|| ir_reg tmp_reg = cc->int_ret_reg; +|| +|| if (proto && (proto->flags & IR_VARARG_FUNC) && tmp_reg == cc->fp_varargs_reg) { +|| tmp_reg = IR_REG_R11; // TODO: avoid usage of hardcoded temporary register ??? || } -#endif || if (IR_IS_SIGNED_32BIT(addr)) { | mov Rq(tmp_reg), ((ptrdiff_t)addr) // 0x48 0xc7 0xc0 || } else { @@ -9246,22 +10192,10 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) |.endif } } else { - ir_reg op2_reg = ctx->regs[def][2]; - if (op2_reg != IR_REG_NONE) { - if (IR_REG_SPILLED(op2_reg)) { - op2_reg = IR_REG_NUM(op2_reg); - ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2); - } + IR_ASSERT(!IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, op2_reg)); | jmp Ra(op2_reg) } else { - ir_mem mem; - - if (ir_rule(ctx, insn->op2) & IR_FUSED) { - mem = ir_fuse_load(ctx, def, insn->op2); - } else { - mem = ir_ref_spill_slot(ctx, insn->op2); - } | ASM_TMEM_OP jmp, aword, mem } } @@ -9274,6 +10208,19 @@ static void ir_emit_ijmp(ir_ctx *ctx, ir_ref def, ir_insn *insn) ir_reg op2_reg = ctx->regs[def][2]; if (IR_IS_CONST_REF(insn->op2)) { + if (ctx->ir_base[insn->op2].op == IR_LABEL) { + if (!data->resolved_label_syms) { + data->resolved_label_syms = 1; + ir_resolve_label_syms(ctx); + } + + uint32_t target = ctx->ir_base[insn->op2].val.u32_hi; + target = ir_skip_empty_target_blocks(ctx, target); + + | jmp =>target + return; + } + void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op2]); if (sizeof(void*) == 4 || IR_MAY_USE_32BIT_ADDR(ctx->code_buffer, addr)) { @@ -9396,6 +10343,26 @@ static bool ir_emit_guard_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, uint32_t next | jp &addr | jbe =>target break; + case IR_ULT: + | jp =>target + | jae =>target + break; + case IR_UGE: + | jb =>target + break; + case IR_ULE: + | jp =>target + | ja =>target + break; + case IR_UGT: + | jbe =>target + break; + case IR_ORDERED: + | jnp =>target + break; + case IR_UNORDERED: + | jp =>target + break; } } | jmp &addr @@ -9475,6 +10442,26 @@ static bool ir_emit_guard_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, uint32_t next | jp &addr | jbe &target_addr break; + case IR_ULT: + | jp &target_addr + | jae &target_addr + break; + case IR_UGE: + | jb &target_addr + break; + case IR_ULE: + | jp &target_addr + | ja &target_addr + break; + case IR_UGT: + | jbe &target_addr + break; + case IR_ORDERED: + | jnp &target_addr + break; + case IR_UNORDERED: + | jp &target_addr + break; } } | jmp &addr @@ -9554,10 +10541,26 @@ static bool ir_emit_guard_jcc(ir_ctx *ctx, uint32_t b, ir_ref def, uint32_t next case IR_GT: | ja &addr break; -// case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break; -// case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break; -// case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break; -// case IR_UGT: fprintf(stderr, "\tja .LL%d\n", true_block); break; + case IR_ULT: + | jb &addr + break; + case IR_UGE: + | jp &addr + | jae &addr + break; + case IR_ULE: + | jbe &addr + break; + case IR_UGT: + | jp &addr + | ja &addr + break; + case IR_ORDERED: + | jp &addr + break; + case IR_UNORDERED: + | jnp &addr + break; } } return 0; @@ -9650,9 +10653,16 @@ static bool ir_emit_guard_cmp_int(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn * ir_type type = ctx->ir_base[cmp_insn->op1].type; ir_ref op1 = cmp_insn->op1; ir_ref op2 = cmp_insn->op2; - ir_reg op1_reg = ctx->regs[insn->op2][1]; - ir_reg op2_reg = ctx->regs[insn->op2][2]; void *addr; + ir_reg op1_reg, op2_reg; + + if (UNEXPECTED(ctx->rules[insn->op2] & IR_FUSED_REG)) { + op1_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 1); + op2_reg = ir_get_fused_reg(ctx, def, insn->op2 * sizeof(ir_ref) + 2); + } else { + op1_reg = ctx->regs[insn->op2][1]; + op2_reg = ctx->regs[insn->op2][2]; + } if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { op1_reg = IR_REG_NUM(op1_reg); @@ -9706,7 +10716,11 @@ static bool ir_emit_guard_cmp_fp(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *i void *addr = ir_jmp_addr(ctx, insn, &ctx->ir_base[insn->op3]); if (insn->op == IR_GUARD) { - op ^= 1; // reverse + if (op == IR_EQ || op == IR_NE || op == IR_ORDERED || op == IR_UNORDERED) { + op ^= 1; // reverse + } else { + op ^= 5; // reverse + } } return ir_emit_guard_jcc(ctx, b, def, next_block, op, addr, 0, 0); } @@ -9923,6 +10937,11 @@ static void ir_emit_sse_round(ir_ctx *ctx, ir_ref def, ir_insn *insn, int round_ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; +#ifdef IR_TARGET_X86 + const ir_call_conv_dsc *cc = &ir_call_conv_x86_fastcall; +#else + const ir_call_conv_dsc *cc = &ir_call_conv_default; +#endif dasm_State **Dst = &data->dasm_state; ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); @@ -9962,13 +10981,13 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) | movsd qword [rsp+16*8+14*8], xmm14 | movsd qword [rsp+16*8+15*8], xmm15 | - | mov Ra(IR_REG_INT_ARG2), rsp - | lea Ra(IR_REG_INT_ARG1), [rsp+16*8+16*8+16] - | mov aword [rsp+4*8], Ra(IR_REG_INT_ARG1) - | mov Ra(IR_REG_INT_ARG1), [rsp+16*8+16*8+8] - |.if X64WIN - | sub rsp, 32 /* shadow space */ - |.endif + | mov Ra(cc->int_param_regs[1]), rsp + | lea Ra(cc->int_param_regs[0]), [rsp+16*8+16*8+16] + | mov aword [rsp+4*8], Ra(cc->int_param_regs[0]) + | mov Ra(cc->int_param_regs[0]), [rsp+16*8+16*8+8] + || if (cc->shadow_store_size) { + | sub rsp, cc->shadow_store_size /* shadow space */ + || } |.else | sub esp, 8*4+8*8+12 /* CPU regs + SSE regs */ | mov aword [esp+0*4], eax @@ -9987,10 +11006,10 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) | movsd qword [esp+8*4+6*8], xmm6 | movsd qword [esp+8*4+7*8], xmm7 | - | mov Ra(IR_REG_INT_FCARG2), esp - | lea Ra(IR_REG_INT_FCARG1), [esp+8*4+8*8+16] - | mov aword [esp+4*4], Ra(IR_REG_INT_FCARG1) - | mov Ra(IR_REG_INT_FCARG1), [esp+8*4+8*8+12] + | mov Ra(cc->int_param_regs[1]), esp + | lea Ra(cc->int_param_regs[0]), [esp+8*4+8*8+16] + | mov aword [esp+4*4], Ra(cc->int_param_regs[0]) + | mov Ra(cc->int_param_regs[0]), [esp+8*4+8*8+12] |.endif if (IR_IS_CONST_REF(insn->op2)) { @@ -10013,16 +11032,14 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn) } // restore SP - |.if X64WIN - | add rsp, 32+16*8+16*8+16 /* shadow space + CPU regs + SSE regs */ - |.elif X64 - | add rsp, 16*8+16*8+16 /* CPU regs + SSE regs */ + |.if X64 + | add rsp, cc->shadow_store_size+16*8+16*8+16 /* shadow space + CPU regs + SSE regs */ |.else | add esp, 8*4+8*8+16 /* CPU regs + SSE regs */ |.endif - if (def_reg != IR_REG_INT_RET1) { - ir_emit_mov(ctx, insn->type, def_reg, IR_REG_INT_RET1); + if (def_reg != cc->int_ret_reg) { + ir_emit_mov(ctx, insn->type, def_reg, cc->int_ret_reg); } if (IR_REG_SPILLED(ctx->regs[def][0])) { ir_emit_store(ctx, insn->type, def, def_reg); @@ -10033,6 +11050,7 @@ static void ir_emit_param_move(ir_ctx *ctx, uint8_t type, ir_reg from_reg, ir_re { ir_reg fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER; + offset = IR_SPILL_POS_TO_OFFSET(offset); IR_ASSERT(from_reg != IR_REG_NONE || to_reg != IR_REG_NONE); if (IR_IS_TYPE_INT(type)) { @@ -10067,26 +11085,17 @@ static void ir_emit_load_params(ir_ctx *ctx) int fp_param_num = 0; ir_reg src_reg; ir_reg dst_reg; - // TODO: Calling convention specific - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; int32_t stack_offset = 0; - -#ifdef IR_TARGET_X86 - if (sizeof(void*) == 4 && (ctx->flags & IR_FASTCALL_FUNC)) { - int_reg_params_count = IR_REG_INT_FCARGS; - fp_reg_params_count = IR_REG_FP_FCARGS; - int_reg_params = _ir_int_fc_reg_params; - fp_reg_params = _ir_fp_fc_reg_params; - } -#endif + int32_t stack_start = 0; if (ctx->flags & IR_USE_FRAME_POINTER) { - stack_offset = sizeof(void*) * 2; /* skip old frame pointer and return address */ + /* skip old frame pointer and return address */ + stack_start = sizeof(void*) * 2 + ctx->stack_frame_size; } else { - stack_offset = sizeof(void*) + ctx->stack_frame_size + ctx->call_stack_size; /* skip return address */ + /* skip return address */ + stack_start = sizeof(void*) + ctx->stack_frame_size; } n = use_list->count; for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { @@ -10094,37 +11103,41 @@ static void ir_emit_load_params(ir_ctx *ctx) insn = &ctx->ir_base[use]; if (insn->op == IR_PARAM) { if (IR_IS_TYPE_INT(insn->type)) { - if (int_param_num < int_reg_params_count) { - src_reg = int_reg_params[int_param_num]; + if (ctx->value_params && ctx->value_params[insn->op3 - 1].align) { + /* struct passed by value on stack */ + size_t align = ctx->value_params[insn->op3 - 1].align; + + align = IR_MAX(sizeof(void*), align); + stack_offset = IR_ALIGNED_SIZE(stack_offset, align); + stack_offset += ctx->value_params[insn->op3 - 1].size; + stack_offset = IR_ALIGNED_SIZE(stack_offset, sizeof(void*)); + continue; + } else if (int_param_num < cc->int_param_regs_count) { + src_reg = cc->int_param_regs[int_param_num]; } else { src_reg = IR_REG_NONE; } int_param_num++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - fp_param_num++; -#endif + if (cc->shadow_param_regs) { + fp_param_num++; + } } else { - if (fp_param_num < fp_reg_params_count) { - src_reg = fp_reg_params[fp_param_num]; + if (fp_param_num < cc->fp_param_regs_count) { + src_reg = cc->fp_param_regs[fp_param_num]; } else { src_reg = IR_REG_NONE; } fp_param_num++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - int_param_num++; -#endif + if (cc->shadow_param_regs) { + int_param_num++; + } } if (ctx->vregs[use]) { dst_reg = IR_REG_NUM(ctx->regs[use][0]); IR_ASSERT(src_reg != IR_REG_NONE || dst_reg != IR_REG_NONE || - stack_offset == ctx->live_intervals[ctx->vregs[use]]->stack_spill_pos + - ((ctx->flags & IR_USE_FRAME_POINTER) ? - -(ctx->stack_frame_size - ctx->stack_frame_alignment) : - ctx->call_stack_size)); + stack_start + stack_offset == ctx->live_intervals[ctx->vregs[use]]->stack_spill_pos); if (src_reg != dst_reg) { - ir_emit_param_move(ctx, insn->type, src_reg, dst_reg, use, stack_offset); + ir_emit_param_move(ctx, insn->type, src_reg, dst_reg, use, stack_start + stack_offset); } if (dst_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[use][0])) { ir_emit_store(ctx, insn->type, use, dst_reg); @@ -10153,10 +11166,9 @@ static ir_reg ir_get_free_reg(ir_type type, ir_regset available) return IR_REGSET_FIRST(available); } -static int ir_fix_dessa_tmps(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to) +static int ir_fix_dessa_tmps(ir_ctx *ctx, uint8_t type, ir_ref from, ir_ref to, void *dessa_from_block) { - ir_backend_data *data = ctx->data; - ir_ref ref = ctx->cfg_blocks[data->dessa_from_block].end; + ir_ref ref = ctx->cfg_blocks[(intptr_t)dessa_from_block].end; if (to == 0) { if (IR_IS_TYPE_INT(type)) { @@ -10192,26 +11204,14 @@ static void ir_fix_param_spills(ir_ctx *ctx) int int_param_num = 0; int fp_param_num = 0; ir_reg src_reg; - // TODO: Calling convention specific - int int_reg_params_count = IR_REG_INT_ARGS; - int fp_reg_params_count = IR_REG_FP_ARGS; - const int8_t *int_reg_params = _ir_int_reg_params; - const int8_t *fp_reg_params = _ir_fp_reg_params; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; int32_t stack_start = 0; int32_t stack_offset = 0; -#ifdef IR_TARGET_X86 - if (sizeof(void*) == 4 && (ctx->flags & IR_FASTCALL_FUNC)) { - int_reg_params_count = IR_REG_INT_FCARGS; - fp_reg_params_count = IR_REG_FP_FCARGS; - int_reg_params = _ir_int_fc_reg_params; - fp_reg_params = _ir_fp_fc_reg_params; - } -#endif - if (ctx->flags & IR_USE_FRAME_POINTER) { /* skip old frame pointer and return address */ - stack_start = sizeof(void*) * 2 + (ctx->stack_frame_size - ctx->stack_frame_alignment); + stack_start = sizeof(void*) * 2 + ctx->stack_frame_size; } else { /* skip return address */ stack_start = sizeof(void*) + ctx->stack_frame_size; @@ -10222,27 +11222,36 @@ static void ir_fix_param_spills(ir_ctx *ctx) insn = &ctx->ir_base[use]; if (insn->op == IR_PARAM) { if (IR_IS_TYPE_INT(insn->type)) { - if (int_param_num < int_reg_params_count) { - src_reg = int_reg_params[int_param_num]; + if (ctx->value_params && ctx->value_params[insn->op3 - 1].align && cc->pass_struct_by_val) { + /* struct passed by value on stack */ + size_t align = ctx->value_params[insn->op3 - 1].align; + + align = IR_MAX(sizeof(void*), align); + stack_offset = IR_ALIGNED_SIZE(stack_offset, align); + ctx->value_params[insn->op3 - 1].offset = stack_start + stack_offset; + stack_offset += ctx->value_params[insn->op3 - 1].size; + stack_offset = IR_ALIGNED_SIZE(stack_offset, sizeof(void*)); + continue; + } + if (int_param_num < cc->int_param_regs_count) { + src_reg = cc->int_param_regs[int_param_num]; } else { src_reg = IR_REG_NONE; } int_param_num++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - fp_param_num++; -#endif + if (cc->shadow_param_regs) { + fp_param_num++; + } } else { - if (fp_param_num < fp_reg_params_count) { - src_reg = fp_reg_params[fp_param_num]; + if (fp_param_num < cc->fp_param_regs_count) { + src_reg = cc->fp_param_regs[fp_param_num]; } else { src_reg = IR_REG_NONE; } fp_param_num++; -#ifdef _WIN64 - /* WIN64 calling convention use common couter for int and fp registers */ - int_param_num++; -#endif + if (cc->shadow_param_regs) { + int_param_num++; + } } if (src_reg == IR_REG_NONE) { if (ctx->vregs[use]) { @@ -10262,12 +11271,13 @@ static void ir_fix_param_spills(ir_ctx *ctx) } } -#ifdef _WIN64 - /* WIN64 uses shsow area for registers */ - stack_offset += IR_MIN(int_param_num, int_reg_params_count) * sizeof(void*); -#endif - ctx->gp_reg_params = IR_MIN(int_param_num, int_reg_params_count); - ctx->fp_reg_params = IR_MIN(fp_param_num, fp_reg_params_count); + if (cc->shadow_store_size) { + /* WIN64 uses shadow area for registers */ + stack_offset += IR_MIN(int_param_num, cc->int_param_regs_count) * sizeof(void*); + } + + ctx->gp_reg_params = IR_MIN(int_param_num, cc->int_param_regs_count); + ctx->fp_reg_params = IR_MIN(fp_param_num, cc->fp_param_regs_count); ctx->param_stack_size = stack_offset; } @@ -10278,17 +11288,20 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) ir_insn *insn; ir_ref i, n, j, *p; uint32_t *rule, insn_flags; - ir_backend_data *data = ctx->data; ir_regset available = 0; ir_target_constraints constraints; uint32_t def_flags; ir_reg reg; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; + ir_regset scratch = ir_scratch_regset[cc->scratch_reg - IR_REG_NUM]; -#ifndef IR_REG_FP_RET1 +#ifdef IR_TARGET_X86 if (ctx->flags2 & IR_HAS_FP_RET_SLOT) { - ctx->ret_slot = ir_allocate_spill_slot(ctx, IR_DOUBLE, &data->ra_data); - } else if (ctx->ret_type == IR_FLOAT || ctx->ret_type == IR_DOUBLE) { - ctx->ret_slot = ir_allocate_spill_slot(ctx, ctx->ret_type, &data->ra_data); + ctx->ret_slot = ir_allocate_spill_slot(ctx, IR_DOUBLE); + } else if ((ctx->ret_type == IR_FLOAT || ctx->ret_type == IR_DOUBLE) + && cc->fp_ret_reg == IR_REG_NONE) { + ctx->ret_slot = ir_allocate_spill_slot(ctx, ctx->ret_type); } else { ctx->ret_slot = -1; } @@ -10314,15 +11327,23 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) case IR_IF_TRUE: case IR_IF_FALSE: case IR_CASE_VAL: + case IR_CASE_RANGE: case IR_CASE_DEFAULT: case IR_MERGE: case IR_LOOP_BEGIN: case IR_LOOP_END: + case IR_IGOTO_DUP: break; -#ifndef IR_REG_FP_RET1 +#ifdef IR_TARGET_X86 case IR_CALL: - if (ctx->ret_slot == -1 && (insn->type == IR_FLOAT || insn->type == IR_DOUBLE)) { - ctx->ret_slot = ir_allocate_spill_slot(ctx, IR_DOUBLE, &data->ra_data); + if (ctx->ret_slot == -1 + && (insn->type == IR_FLOAT || insn->type == IR_DOUBLE)) { + const ir_proto_t *proto = ir_call_proto(ctx, insn); + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + + if (cc->fp_ret_reg == IR_REG_NONE) { + ctx->ret_slot = ir_allocate_spill_slot(ctx, IR_DOUBLE); + } } #endif IR_FALLTHROUGH; @@ -10334,7 +11355,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) && *rule != IR_TEST_AND_BRANCH_INT && *rule != IR_GUARD_CMP_INT && *rule != IR_GUARD_CMP_FP) { - available = IR_REGSET_SCRATCH; + available = scratch; } if (ctx->vregs[i]) { reg = constraints.def_reg; @@ -10342,7 +11363,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) IR_REGSET_EXCL(available, reg); ctx->regs[i][0] = reg | IR_REG_SPILL_STORE; } else if (def_flags & IR_USE_MUST_BE_IN_REG) { - if (insn->op == IR_VLOAD + if ((insn->op == IR_VLOAD || insn->op == IR_VLOAD_v) && ctx->live_intervals[ctx->vregs[i]] && ctx->live_intervals[ctx->vregs[i]]->stack_spill_pos != -1 && ir_is_same_mem_var(ctx, i, ctx->ir_base[insn->op2].op3)) { @@ -10364,7 +11385,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) if (insn->op == IR_PARAM && reg == IR_REG_NONE) { ival->flags |= IR_LIVE_INTERVAL_MEM_PARAM; } else { - ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type, &data->ra_data); + ival->stack_spill_pos = ir_allocate_spill_slot(ctx, ival->type); } } else if (insn->op == IR_PARAM) { IR_ASSERT(0 && "unexpected PARAM"); @@ -10375,14 +11396,14 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) ir_ref n = use_list->count; if (n > 0) { - int32_t stack_spill_pos = insn->op3 = ir_allocate_spill_slot(ctx, insn->type, &data->ra_data); + int32_t stack_spill_pos = insn->op3 = ir_allocate_spill_slot(ctx, insn->type); ir_ref i, *p, use; ir_insn *use_insn; for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { use = *p; use_insn = &ctx->ir_base[use]; - if (use_insn->op == IR_VLOAD) { + if (use_insn->op == IR_VLOAD || use_insn->op == IR_VLOAD_v) { if (ctx->vregs[use] && !ctx->live_intervals[ctx->vregs[use]]) { ir_live_interval *ival = ir_arena_alloc(&ctx->arena, sizeof(ir_live_interval)); @@ -10393,7 +11414,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) ival->vreg = ctx->vregs[use]; ival->stack_spill_pos = stack_spill_pos; } - } else if (use_insn->op == IR_VSTORE) { + } else if (use_insn->op == IR_VSTORE || use_insn->op == IR_VSTORE_v) { if (!IR_IS_CONST_REF(use_insn->op3) && ctx->vregs[use_insn->op3] && !ctx->live_intervals[ctx->vregs[use_insn->op3]]) { @@ -10430,10 +11451,14 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) } } ctx->regs[i][constraints.tmp_regs[n].num] = reg; - } else if (constraints.tmp_regs[n].reg == IR_REG_SCRATCH) { - available = IR_REGSET_DIFFERENCE(available, IR_REGSET_SCRATCH); } else { - IR_REGSET_EXCL(available, constraints.tmp_regs[n].reg); + ir_reg reg = constraints.tmp_regs[n].reg; + + if (reg > IR_REG_NUM) { + available = IR_REGSET_DIFFERENCE(available, ir_scratch_regset[reg - IR_REG_NUM]); + } else { + IR_REGSET_EXCL(available, reg); + } } } while (n); } @@ -10469,8 +11494,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) rule += n; } if (bb->flags & IR_BB_DESSA_MOVES) { - data->dessa_from_block = b; - ir_gen_dessa_moves(ctx, b, ir_fix_dessa_tmps); + ir_gen_dessa_moves(ctx, b, ir_fix_dessa_tmps, (void*)(intptr_t)b); } } @@ -10481,18 +11505,18 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) static void ir_preallocate_call_stack(ir_ctx *ctx) { - int call_stack_size, peak_call_stack_size = 0; + int call_stack_size, copy_stack, peak_call_stack_size = 0; ir_ref i, n; ir_insn *insn; for (i = 1, insn = ctx->ir_base + 1; i < ctx->insns_count;) { if (insn->op == IR_CALL) { - call_stack_size = ir_call_used_stack(ctx, insn); + const ir_proto_t *proto = ir_call_proto(ctx, insn); + const ir_call_conv_dsc *cc = ir_get_call_conv_dsc(proto ? proto->flags : IR_CC_DEFAULT); + + call_stack_size = ir_call_used_stack(ctx, insn, cc, ©_stack); if (call_stack_size > peak_call_stack_size -#ifdef IR_HAVE_FASTCALL - && !ir_is_fastcall(ctx, insn) /* fast call functions restore stack pointer */ -#endif - ) { + && !cc->cleanup_stack_by_callee) { peak_call_stack_size = call_stack_size; } } @@ -10502,7 +11526,7 @@ static void ir_preallocate_call_stack(ir_ctx *ctx) } if (peak_call_stack_size) { ctx->call_stack_size = peak_call_stack_size; - ctx->flags |= IR_PREALLOCATED_STACK; + ctx->flags2 |= IR_PREALLOCATED_STACK; } } @@ -10512,19 +11536,22 @@ void ir_fix_stack_frame(ir_ctx *ctx) ctx->locals_area_size = ctx->stack_frame_size; -#if defined(IR_TARGET_X64) && !defined(_WIN64) if ((ctx->flags & IR_VARARG_FUNC) && (ctx->flags2 & IR_HAS_VA_START)) { - ctx->flags2 |= IR_16B_FRAME_ALIGNMENT; - ctx->stack_frame_size = IR_ALIGNED_SIZE(ctx->stack_frame_size, 16); - ctx->locals_area_size = ctx->stack_frame_size; - if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < IR_REG_INT_ARGS) { - additional_size += sizeof(void*) * IR_REG_INT_ARGS; - } - if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < IR_REG_FP_ARGS) { - additional_size += 16 * IR_REG_FP_ARGS; + ir_backend_data *data = ctx->data; + const ir_call_conv_dsc *cc = data->ra_data.cc; + + if (cc->sysv_varargs) { + ctx->flags2 |= IR_16B_FRAME_ALIGNMENT; + ctx->stack_frame_size = IR_ALIGNED_SIZE(ctx->stack_frame_size, 16); + ctx->locals_area_size = ctx->stack_frame_size; + if ((ctx->flags2 & (IR_HAS_VA_ARG_GP|IR_HAS_VA_COPY)) && ctx->gp_reg_params < cc->int_param_regs_count) { + additional_size += sizeof(void*) * cc->int_param_regs_count; + } + if ((ctx->flags2 & (IR_HAS_VA_ARG_FP|IR_HAS_VA_COPY)) && ctx->fp_reg_params < cc->fp_param_regs_count) { + additional_size += 16 * cc->fp_param_regs_count; + } } } -#endif if (ctx->used_preserved_regs) { ir_regset used_preserved_regs = (ir_regset)ctx->used_preserved_regs; @@ -10538,7 +11565,6 @@ void ir_fix_stack_frame(ir_ctx *ctx) ctx->stack_frame_size = IR_ALIGNED_SIZE(ctx->stack_frame_size, sizeof(void*)); ctx->stack_frame_size += additional_size; - ctx->stack_frame_alignment = 0; ctx->call_stack_size = 0; if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) { @@ -10546,12 +11572,10 @@ void ir_fix_stack_frame(ir_ctx *ctx) if (!(ctx->flags & IR_FUNCTION)) { while (IR_ALIGNED_SIZE(ctx->stack_frame_size, 16) != ctx->stack_frame_size) { ctx->stack_frame_size += sizeof(void*); - ctx->stack_frame_alignment += sizeof(void*); } } else if (ctx->flags & IR_USE_FRAME_POINTER) { while (IR_ALIGNED_SIZE(ctx->stack_frame_size + sizeof(void*) * 2, 16) != ctx->stack_frame_size + sizeof(void*) * 2) { ctx->stack_frame_size += sizeof(void*); - ctx->stack_frame_alignment += sizeof(void*); } } else { if (!(ctx->flags & IR_NO_STACK_COMBINE)) { @@ -10560,7 +11584,6 @@ void ir_fix_stack_frame(ir_ctx *ctx) while (IR_ALIGNED_SIZE(ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*), 16) != ctx->stack_frame_size + ctx->call_stack_size + sizeof(void*)) { ctx->stack_frame_size += sizeof(void*); - ctx->stack_frame_alignment += sizeof(void*); } } } @@ -10593,7 +11616,10 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) int ret; void *entry; size_t size; + ir_ref igoto_dup_ref = IR_UNUSED; + uint32_t igoto_dup_block = 0; + data.ra_data.cc = ir_get_call_conv_dsc(ctx->flags); data.ra_data.unused_slot_4 = 0; data.ra_data.unused_slot_2 = 0; data.ra_data.unused_slot_1 = 0; @@ -10605,11 +11631,13 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) data.double_abs_const = 0; data.float_abs_const = 0; data.double_zero_const = 0; + data.u2d_const = 0; + data.u2f_const = 0; + data.resolved_label_syms = 0; ctx->data = &data; if (!ctx->live_intervals) { ctx->stack_frame_size = 0; - ctx->stack_frame_alignment = 0; ctx->call_stack_size = 0; ctx->used_preserved_regs = 0; ir_allocate_unique_spill_slots(ctx); @@ -10631,7 +11659,6 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) } ctx->stack_frame_size = ctx->fixed_stack_frame_size; ctx->call_stack_size = ctx->fixed_call_stack_size; - ctx->stack_frame_alignment = 0; } Dst = &data.dasm_state; @@ -10641,6 +11668,14 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) dasm_setup(&data.dasm_state, dasm_actions); /* labels for each block + for each constant + rodata label + jmp_table label + for each entry */ dasm_growpc(&data.dasm_state, ctx->cfg_blocks_count + 1 + ctx->consts_count + 1 + 1 + 1 + ctx->entries_count); + if (data.dasm_state->status != DASM_S_OK) { + IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM); + dasm_free(&data.dasm_state); + ctx->data = NULL; + ctx->status = IR_ERROR_TOO_LARGE; + return NULL; + } + data.emit_constants = ir_bitset_malloc(ctx->consts_count); if ((ctx->flags & IR_GEN_ENDBR) && (ctx->flags & IR_START_BR_TARGET)) { @@ -10885,6 +11920,9 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) case IR_COND: ir_emit_cond(ctx, i, insn); break; + case IR_COND_TEST_INT: + ir_emit_cond_test_int(ctx, i, insn); + break; case IR_COND_CMP_INT: ir_emit_cond_cmp_int(ctx, i, insn); break; @@ -10944,6 +11982,35 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) case IR_TAILCALL: ir_emit_tailcall(ctx, i, insn); break; + case IR_IGOTO_DUP: + if (bb->flags & IR_BB_DESSA_MOVES) { + ir_emit_dessa_moves(ctx, b, bb); + } + IR_ASSERT(!igoto_dup_ref && !igoto_dup_block); + igoto_dup_ref = i; + igoto_dup_block = b; + b = ctx->cfg_edges[bb->successors]; + bb = &ctx->cfg_blocks[b]; + i = bb->start; + insn = &ctx->ir_base[i]; + rule = &ctx->rules[i]; + break; + case IR_IGOTO: + if ((ctx->ir_base[insn->op1].op == IR_MERGE || ctx->ir_base[insn->op1].op == IR_LOOP_BEGIN) + && (ctx->rules[ctx->ir_base[insn->op1].op1] & IR_RULE_MASK) == IR_IGOTO_DUP + && igoto_dup_ref) { + ir_emit_ijmp(ctx, i, insn); + b = igoto_dup_block; + bb = &ctx->cfg_blocks[b]; + i = igoto_dup_ref; + insn = &ctx->ir_base[i]; + rule = &ctx->rules[i]; + igoto_dup_block= 0; + igoto_dup_ref = 0; + break; + } + IR_ASSERT(!igoto_dup_ref && !igoto_dup_block); + IR_FALLTHROUGH; case IR_IJMP: ir_emit_ijmp(ctx, i, insn); break; @@ -10973,6 +12040,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) ir_emit_vaddr(ctx, i, insn); break; case IR_VLOAD: + case IR_VLOAD_v: ir_emit_vload(ctx, i, insn); break; case IR_VSTORE_INT: @@ -11137,12 +12205,20 @@ next_block:; return NULL; } + if (data.dasm_state->status != DASM_S_OK) { + IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM); + dasm_free(&data.dasm_state); + ctx->data = NULL; + ctx->status = IR_ERROR_TOO_LARGE; + return NULL; + } + ret = dasm_link(&data.dasm_state, size_ptr); if (ret != DASM_S_OK) { - IR_ASSERT(0); + IR_ASSERT(ret == DASM_S_NOMEM); dasm_free(&data.dasm_state); ctx->data = NULL; - ctx->status = IR_ERROR_LINK; + ctx->status = (ret == DASM_S_NOMEM) ? IR_ERROR_TOO_LARGE : IR_ERROR_LINK; return NULL; } size = *size_ptr; @@ -11207,6 +12283,28 @@ next_block:; } while (i != 0); } + if ((ctx->flags2 & IR_HAS_BLOCK_ADDR) && ctx->loader && ctx->loader->add_label) { + for (b = 1, bb = &ctx->cfg_blocks[b]; b <= ctx->cfg_blocks_count; bb++, b++) { + ir_insn *insn = &ctx->ir_base[bb->start]; + + if (insn->op == IR_BEGIN && insn->op2) { + IR_ASSERT(ctx->ir_base[insn->op2].op == IR_LABEL); + ctx->ir_base[insn->op2].val.u32_hi = 0; + ctx->loader->add_label(ctx->loader, ir_get_str(ctx, ctx->ir_base[insn->op2].val.str), + (char*)entry + dasm_getpclabel(&data.dasm_state, ir_skip_empty_target_blocks(ctx, b))); + } + } + } else if (data.resolved_label_syms) { + for (b = 1, bb = &ctx->cfg_blocks[b]; b <= ctx->cfg_blocks_count; bb++, b++) { + ir_insn *insn = &ctx->ir_base[bb->start]; + + if (insn->op == IR_BEGIN && insn->op2) { + IR_ASSERT(ctx->ir_base[insn->op2].op == IR_LABEL); + ctx->ir_base[insn->op2].val.u32_hi = 0; + } + } + } + dasm_free(&data.dasm_state); ir_mem_flush(entry, size); @@ -11218,7 +12316,7 @@ next_block:; do { /* _cldemote(p); */ - asm volatile(".byte 0x0f, 0x1c, 0x06" :: "S" (p)); + __asm__ volatile(".byte 0x0f, 0x1c, 0x06" :: "S" (p)); p += 64; } while (p < start + size); } @@ -11291,7 +12389,7 @@ const void *ir_emit_exitgroup(uint32_t first_exit_point, uint32_t exit_points_pe return entry; } -bool ir_needs_thunk(ir_code_buffer *code_buffer, void *addr) +bool ir_needs_thunk(const ir_code_buffer *code_buffer, void *addr) { return sizeof(void*) == 8 && !IR_MAY_USE_32BIT_ADDR(code_buffer, addr); } diff --git a/ext/opcache/jit/ir/ir_x86.h b/ext/opcache/jit/ir/ir_x86.h index 4b86c291bdfc..6399ca107fdd 100644 --- a/ext/opcache/jit/ir/ir_x86.h +++ b/ext/opcache/jit/ir/ir_x86.h @@ -82,14 +82,17 @@ enum _ir_reg { IR_GP_REGS(IR_GP_REG_ENUM) IR_FP_REGS(IR_FP_REG_ENUM) IR_REG_NUM, + IR_REG_ALL = IR_REG_NUM, /* special name for regset */ + IR_REG_SET_1, /* special name for regset */ + IR_REG_SET_2, /* special name for regset */ + IR_REG_SET_3, /* special name for regset */ + IR_REG_SET_NUM, }; #define IR_REG_GP_FIRST IR_REG_R0 #define IR_REG_FP_FIRST IR_REG_XMM0 #define IR_REG_GP_LAST (IR_REG_FP_FIRST - 1) #define IR_REG_FP_LAST (IR_REG_NUM - 1) -#define IR_REG_SCRATCH (IR_REG_NUM) /* special name for regset */ -#define IR_REG_ALL (IR_REG_NUM + 1) /* special name for regset */ #define IR_REGSET_64BIT 0 @@ -113,121 +116,4 @@ enum _ir_reg { #define IR_REG_RSI IR_REG_R6 #define IR_REG_RDI IR_REG_R7 -/* Calling Convention */ -#ifdef _WIN64 - -# define IR_REG_INT_RET1 IR_REG_RAX -# define IR_REG_FP_RET1 IR_REG_XMM0 -# define IR_REG_INT_ARGS 4 -# define IR_REG_FP_ARGS 4 -# define IR_REG_INT_ARG1 IR_REG_RCX -# define IR_REG_INT_ARG2 IR_REG_RDX -# define IR_REG_INT_ARG3 IR_REG_R8 -# define IR_REG_INT_ARG4 IR_REG_R9 -# define IR_REG_FP_ARG1 IR_REG_XMM0 -# define IR_REG_FP_ARG2 IR_REG_XMM1 -# define IR_REG_FP_ARG3 IR_REG_XMM2 -# define IR_REG_FP_ARG4 IR_REG_XMM3 -# define IR_MAX_REG_ARGS 4 -# define IR_SHADOW_ARGS 32 /* Reserved space in bytes - "home space" or "shadow store" for register arguments */ - -# define IR_REGSET_SCRATCH \ - (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \ - | IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) \ - | IR_REGSET_INTERVAL(IR_REG_XMM0, IR_REG_XMM5)) - -# define IR_REGSET_PRESERVED \ - (IR_REGSET(IR_REG_RBX) \ - | IR_REGSET_INTERVAL(IR_REG_RBP, IR_REG_RDI) \ - | IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15) \ - | IR_REGSET_INTERVAL(IR_REG_XMM6, IR_REG_XMM15)) - -#elif defined(IR_TARGET_X64) - -# define IR_REG_INT_RET1 IR_REG_RAX -# define IR_REG_FP_RET1 IR_REG_XMM0 -# define IR_REG_INT_ARGS 6 -# define IR_REG_FP_ARGS 8 -# define IR_REG_INT_ARG1 IR_REG_RDI -# define IR_REG_INT_ARG2 IR_REG_RSI -# define IR_REG_INT_ARG3 IR_REG_RDX -# define IR_REG_INT_ARG4 IR_REG_RCX -# define IR_REG_INT_ARG5 IR_REG_R8 -# define IR_REG_INT_ARG6 IR_REG_R9 -# define IR_REG_FP_ARG1 IR_REG_XMM0 -# define IR_REG_FP_ARG2 IR_REG_XMM1 -# define IR_REG_FP_ARG3 IR_REG_XMM2 -# define IR_REG_FP_ARG4 IR_REG_XMM3 -# define IR_REG_FP_ARG5 IR_REG_XMM4 -# define IR_REG_FP_ARG6 IR_REG_XMM5 -# define IR_REG_FP_ARG7 IR_REG_XMM6 -# define IR_REG_FP_ARG8 IR_REG_XMM7 -# define IR_MAX_REG_ARGS 14 -# define IR_SHADOW_ARGS 0 - -# define IR_REG_VARARG_FP_REGS IR_REG_RAX /* hidden argument to specify the number of vector registers used */ - -# define IR_REGSET_SCRATCH \ - (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \ - | IR_REGSET_INTERVAL(IR_REG_RSI, IR_REG_RDI) \ - | IR_REGSET_INTERVAL(IR_REG_R8, IR_REG_R11) \ - | IR_REGSET_FP) - -# define IR_REGSET_PRESERVED \ - (IR_REGSET(IR_REG_RBX) \ - | IR_REGSET(IR_REG_RBP) \ - | IR_REGSET_INTERVAL(IR_REG_R12, IR_REG_R15)) - -typedef struct _ir_va_list { - uint32_t gp_offset; - uint32_t fp_offset; - void *overflow_arg_area; - void *reg_save_area; -} ir_va_list; - -#elif defined(IR_TARGET_X86) - -# define IR_REG_INT_RET1 IR_REG_RAX -# define IR_REG_INT_RET2 IR_REG_RDX -# define IR_REG_INT_ARGS 0 -# define IR_REG_FP_ARGS 0 - -# define IR_HAVE_FASTCALL 1 -# define IR_REG_INT_FCARGS 2 -# define IR_REG_FP_FCARGS 0 -# define IR_REG_INT_FCARG1 IR_REG_RCX -# define IR_REG_INT_FCARG2 IR_REG_RDX -# define IR_MAX_REG_ARGS 2 -# define IR_SHADOW_ARGS 0 - -# define IR_REGSET_SCRATCH \ - (IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) | IR_REGSET_FP) - -# define IR_REGSET_PRESERVED \ - (IR_REGSET(IR_REG_RBX) \ - | IR_REGSET(IR_REG_RBP) \ - | IR_REGSET_INTERVAL(IR_REG_RSI, IR_REG_RDI)) - -#else -# error "Unsupported target architecture" -#endif - -typedef struct _ir_tmp_reg { - union { - uint8_t num; - int8_t reg; - }; - uint8_t type; - uint8_t start; - uint8_t end; -} ir_tmp_reg; - -struct _ir_target_constraints { - int8_t def_reg; - uint8_t tmps_count; - uint8_t hints_count; - ir_tmp_reg tmp_regs[3]; - int8_t hints[IR_MAX_REG_ARGS + 3]; -}; - #endif /* IR_X86_H */ diff --git a/ext/opcache/jit/tls/testing/.gitignore b/ext/opcache/jit/tls/testing/.gitignore new file mode 100644 index 000000000000..3873646140f9 --- /dev/null +++ b/ext/opcache/jit/tls/testing/.gitignore @@ -0,0 +1,4 @@ +*.so +*.o +main +main.dSYM diff --git a/ext/opcache/jit/tls/testing/def-vars.h b/ext/opcache/jit/tls/testing/def-vars.h new file mode 100644 index 000000000000..66cdc2442b8c --- /dev/null +++ b/ext/opcache/jit/tls/testing/def-vars.h @@ -0,0 +1,1030 @@ +/* Declare a few additional TLS variables to fill any surplus space, + * so _tsrm_ls_cache is allocated in the dynamic section. */ + +#define DEF_VAR(prefix, num) __thread void* prefix##num +#define DEF_VARS(prefix) \ + DEF_VAR(prefix, 0000); \ + DEF_VAR(prefix, 0001); \ + DEF_VAR(prefix, 0002); \ + DEF_VAR(prefix, 0003); \ + DEF_VAR(prefix, 0004); \ + DEF_VAR(prefix, 0005); \ + DEF_VAR(prefix, 0006); \ + DEF_VAR(prefix, 0007); \ + DEF_VAR(prefix, 0008); \ + DEF_VAR(prefix, 0009); \ + DEF_VAR(prefix, 0010); \ + DEF_VAR(prefix, 0011); \ + DEF_VAR(prefix, 0012); \ + DEF_VAR(prefix, 0013); \ + DEF_VAR(prefix, 0014); \ + DEF_VAR(prefix, 0015); \ + DEF_VAR(prefix, 0016); \ + DEF_VAR(prefix, 0017); \ + DEF_VAR(prefix, 0018); \ + DEF_VAR(prefix, 0019); \ + DEF_VAR(prefix, 0020); \ + DEF_VAR(prefix, 0021); \ + DEF_VAR(prefix, 0022); \ + DEF_VAR(prefix, 0023); \ + DEF_VAR(prefix, 0024); \ + DEF_VAR(prefix, 0025); \ + DEF_VAR(prefix, 0026); \ + DEF_VAR(prefix, 0027); \ + DEF_VAR(prefix, 0028); \ + DEF_VAR(prefix, 0029); \ + DEF_VAR(prefix, 0030); \ + DEF_VAR(prefix, 0031); \ + DEF_VAR(prefix, 0032); \ + DEF_VAR(prefix, 0033); \ + DEF_VAR(prefix, 0034); \ + DEF_VAR(prefix, 0035); \ + DEF_VAR(prefix, 0036); \ + DEF_VAR(prefix, 0037); \ + DEF_VAR(prefix, 0038); \ + DEF_VAR(prefix, 0039); \ + DEF_VAR(prefix, 0040); \ + DEF_VAR(prefix, 0041); \ + DEF_VAR(prefix, 0042); \ + DEF_VAR(prefix, 0043); \ + DEF_VAR(prefix, 0044); \ + DEF_VAR(prefix, 0045); \ + DEF_VAR(prefix, 0046); \ + DEF_VAR(prefix, 0047); \ + DEF_VAR(prefix, 0048); \ + DEF_VAR(prefix, 0049); \ + DEF_VAR(prefix, 0050); \ + DEF_VAR(prefix, 0051); \ + DEF_VAR(prefix, 0052); \ + DEF_VAR(prefix, 0053); \ + DEF_VAR(prefix, 0054); \ + DEF_VAR(prefix, 0055); \ + DEF_VAR(prefix, 0056); \ + DEF_VAR(prefix, 0057); \ + DEF_VAR(prefix, 0058); \ + DEF_VAR(prefix, 0059); \ + DEF_VAR(prefix, 0060); \ + DEF_VAR(prefix, 0061); \ + DEF_VAR(prefix, 0062); \ + DEF_VAR(prefix, 0063); \ + DEF_VAR(prefix, 0064); \ + DEF_VAR(prefix, 0065); \ + DEF_VAR(prefix, 0066); \ + DEF_VAR(prefix, 0067); \ + DEF_VAR(prefix, 0068); \ + DEF_VAR(prefix, 0069); \ + DEF_VAR(prefix, 0070); \ + DEF_VAR(prefix, 0071); \ + DEF_VAR(prefix, 0072); \ + DEF_VAR(prefix, 0073); \ + DEF_VAR(prefix, 0074); \ + DEF_VAR(prefix, 0075); \ + DEF_VAR(prefix, 0076); \ + DEF_VAR(prefix, 0077); \ + DEF_VAR(prefix, 0078); \ + DEF_VAR(prefix, 0079); \ + DEF_VAR(prefix, 0080); \ + DEF_VAR(prefix, 0081); \ + DEF_VAR(prefix, 0082); \ + DEF_VAR(prefix, 0083); \ + DEF_VAR(prefix, 0084); \ + DEF_VAR(prefix, 0085); \ + DEF_VAR(prefix, 0086); \ + DEF_VAR(prefix, 0087); \ + DEF_VAR(prefix, 0088); \ + DEF_VAR(prefix, 0089); \ + DEF_VAR(prefix, 0090); \ + DEF_VAR(prefix, 0091); \ + DEF_VAR(prefix, 0092); \ + DEF_VAR(prefix, 0093); \ + DEF_VAR(prefix, 0094); \ + DEF_VAR(prefix, 0095); \ + DEF_VAR(prefix, 0096); \ + DEF_VAR(prefix, 0097); \ + DEF_VAR(prefix, 0098); \ + DEF_VAR(prefix, 0099); \ + DEF_VAR(prefix, 0100); \ + DEF_VAR(prefix, 0101); \ + DEF_VAR(prefix, 0102); \ + DEF_VAR(prefix, 0103); \ + DEF_VAR(prefix, 0104); \ + DEF_VAR(prefix, 0105); \ + DEF_VAR(prefix, 0106); \ + DEF_VAR(prefix, 0107); \ + DEF_VAR(prefix, 0108); \ + DEF_VAR(prefix, 0109); \ + DEF_VAR(prefix, 0110); \ + DEF_VAR(prefix, 0111); \ + DEF_VAR(prefix, 0112); \ + DEF_VAR(prefix, 0113); \ + DEF_VAR(prefix, 0114); \ + DEF_VAR(prefix, 0115); \ + DEF_VAR(prefix, 0116); \ + DEF_VAR(prefix, 0117); \ + DEF_VAR(prefix, 0118); \ + DEF_VAR(prefix, 0119); \ + DEF_VAR(prefix, 0120); \ + DEF_VAR(prefix, 0121); \ + DEF_VAR(prefix, 0122); \ + DEF_VAR(prefix, 0123); \ + DEF_VAR(prefix, 0124); \ + DEF_VAR(prefix, 0125); \ + DEF_VAR(prefix, 0126); \ + DEF_VAR(prefix, 0127); \ + DEF_VAR(prefix, 0128); \ + DEF_VAR(prefix, 0129); \ + DEF_VAR(prefix, 0130); \ + DEF_VAR(prefix, 0131); \ + DEF_VAR(prefix, 0132); \ + DEF_VAR(prefix, 0133); \ + DEF_VAR(prefix, 0134); \ + DEF_VAR(prefix, 0135); \ + DEF_VAR(prefix, 0136); \ + DEF_VAR(prefix, 0137); \ + DEF_VAR(prefix, 0138); \ + DEF_VAR(prefix, 0139); \ + DEF_VAR(prefix, 0140); \ + DEF_VAR(prefix, 0141); \ + DEF_VAR(prefix, 0142); \ + DEF_VAR(prefix, 0143); \ + DEF_VAR(prefix, 0144); \ + DEF_VAR(prefix, 0145); \ + DEF_VAR(prefix, 0146); \ + DEF_VAR(prefix, 0147); \ + DEF_VAR(prefix, 0148); \ + DEF_VAR(prefix, 0149); \ + DEF_VAR(prefix, 0150); \ + DEF_VAR(prefix, 0151); \ + DEF_VAR(prefix, 0152); \ + DEF_VAR(prefix, 0153); \ + DEF_VAR(prefix, 0154); \ + DEF_VAR(prefix, 0155); \ + DEF_VAR(prefix, 0156); \ + DEF_VAR(prefix, 0157); \ + DEF_VAR(prefix, 0158); \ + DEF_VAR(prefix, 0159); \ + DEF_VAR(prefix, 0160); \ + DEF_VAR(prefix, 0161); \ + DEF_VAR(prefix, 0162); \ + DEF_VAR(prefix, 0163); \ + DEF_VAR(prefix, 0164); \ + DEF_VAR(prefix, 0165); \ + DEF_VAR(prefix, 0166); \ + DEF_VAR(prefix, 0167); \ + DEF_VAR(prefix, 0168); \ + DEF_VAR(prefix, 0169); \ + DEF_VAR(prefix, 0170); \ + DEF_VAR(prefix, 0171); \ + DEF_VAR(prefix, 0172); \ + DEF_VAR(prefix, 0173); \ + DEF_VAR(prefix, 0174); \ + DEF_VAR(prefix, 0175); \ + DEF_VAR(prefix, 0176); \ + DEF_VAR(prefix, 0177); \ + DEF_VAR(prefix, 0178); \ + DEF_VAR(prefix, 0179); \ + DEF_VAR(prefix, 0180); \ + DEF_VAR(prefix, 0181); \ + DEF_VAR(prefix, 0182); \ + DEF_VAR(prefix, 0183); \ + DEF_VAR(prefix, 0184); \ + DEF_VAR(prefix, 0185); \ + DEF_VAR(prefix, 0186); \ + DEF_VAR(prefix, 0187); \ + DEF_VAR(prefix, 0188); \ + DEF_VAR(prefix, 0189); \ + DEF_VAR(prefix, 0190); \ + DEF_VAR(prefix, 0191); \ + DEF_VAR(prefix, 0192); \ + DEF_VAR(prefix, 0193); \ + DEF_VAR(prefix, 0194); \ + DEF_VAR(prefix, 0195); \ + DEF_VAR(prefix, 0196); \ + DEF_VAR(prefix, 0197); \ + DEF_VAR(prefix, 0198); \ + DEF_VAR(prefix, 0199); \ + DEF_VAR(prefix, 0200); \ + DEF_VAR(prefix, 0201); \ + DEF_VAR(prefix, 0202); \ + DEF_VAR(prefix, 0203); \ + DEF_VAR(prefix, 0204); \ + DEF_VAR(prefix, 0205); \ + DEF_VAR(prefix, 0206); \ + DEF_VAR(prefix, 0207); \ + DEF_VAR(prefix, 0208); \ + DEF_VAR(prefix, 0209); \ + DEF_VAR(prefix, 0210); \ + DEF_VAR(prefix, 0211); \ + DEF_VAR(prefix, 0212); \ + DEF_VAR(prefix, 0213); \ + DEF_VAR(prefix, 0214); \ + DEF_VAR(prefix, 0215); \ + DEF_VAR(prefix, 0216); \ + DEF_VAR(prefix, 0217); \ + DEF_VAR(prefix, 0218); \ + DEF_VAR(prefix, 0219); \ + DEF_VAR(prefix, 0220); \ + DEF_VAR(prefix, 0221); \ + DEF_VAR(prefix, 0222); \ + DEF_VAR(prefix, 0223); \ + DEF_VAR(prefix, 0224); \ + DEF_VAR(prefix, 0225); \ + DEF_VAR(prefix, 0226); \ + DEF_VAR(prefix, 0227); \ + DEF_VAR(prefix, 0228); \ + DEF_VAR(prefix, 0229); \ + DEF_VAR(prefix, 0230); \ + DEF_VAR(prefix, 0231); \ + DEF_VAR(prefix, 0232); \ + DEF_VAR(prefix, 0233); \ + DEF_VAR(prefix, 0234); \ + DEF_VAR(prefix, 0235); \ + DEF_VAR(prefix, 0236); \ + DEF_VAR(prefix, 0237); \ + DEF_VAR(prefix, 0238); \ + DEF_VAR(prefix, 0239); \ + DEF_VAR(prefix, 0240); \ + DEF_VAR(prefix, 0241); \ + DEF_VAR(prefix, 0242); \ + DEF_VAR(prefix, 0243); \ + DEF_VAR(prefix, 0244); \ + DEF_VAR(prefix, 0245); \ + DEF_VAR(prefix, 0246); \ + DEF_VAR(prefix, 0247); \ + DEF_VAR(prefix, 0248); \ + DEF_VAR(prefix, 0249); \ + DEF_VAR(prefix, 0250); \ + DEF_VAR(prefix, 0251); \ + DEF_VAR(prefix, 0252); \ + DEF_VAR(prefix, 0253); \ + DEF_VAR(prefix, 0254); \ + DEF_VAR(prefix, 0255); \ + DEF_VAR(prefix, 0256); \ + DEF_VAR(prefix, 0257); \ + DEF_VAR(prefix, 0258); \ + DEF_VAR(prefix, 0259); \ + DEF_VAR(prefix, 0260); \ + DEF_VAR(prefix, 0261); \ + DEF_VAR(prefix, 0262); \ + DEF_VAR(prefix, 0263); \ + DEF_VAR(prefix, 0264); \ + DEF_VAR(prefix, 0265); \ + DEF_VAR(prefix, 0266); \ + DEF_VAR(prefix, 0267); \ + DEF_VAR(prefix, 0268); \ + DEF_VAR(prefix, 0269); \ + DEF_VAR(prefix, 0270); \ + DEF_VAR(prefix, 0271); \ + DEF_VAR(prefix, 0272); \ + DEF_VAR(prefix, 0273); \ + DEF_VAR(prefix, 0274); \ + DEF_VAR(prefix, 0275); \ + DEF_VAR(prefix, 0276); \ + DEF_VAR(prefix, 0277); \ + DEF_VAR(prefix, 0278); \ + DEF_VAR(prefix, 0279); \ + DEF_VAR(prefix, 0280); \ + DEF_VAR(prefix, 0281); \ + DEF_VAR(prefix, 0282); \ + DEF_VAR(prefix, 0283); \ + DEF_VAR(prefix, 0284); \ + DEF_VAR(prefix, 0285); \ + DEF_VAR(prefix, 0286); \ + DEF_VAR(prefix, 0287); \ + DEF_VAR(prefix, 0288); \ + DEF_VAR(prefix, 0289); \ + DEF_VAR(prefix, 0290); \ + DEF_VAR(prefix, 0291); \ + DEF_VAR(prefix, 0292); \ + DEF_VAR(prefix, 0293); \ + DEF_VAR(prefix, 0294); \ + DEF_VAR(prefix, 0295); \ + DEF_VAR(prefix, 0296); \ + DEF_VAR(prefix, 0297); \ + DEF_VAR(prefix, 0298); \ + DEF_VAR(prefix, 0299); \ + DEF_VAR(prefix, 0300); \ + DEF_VAR(prefix, 0301); \ + DEF_VAR(prefix, 0302); \ + DEF_VAR(prefix, 0303); \ + DEF_VAR(prefix, 0304); \ + DEF_VAR(prefix, 0305); \ + DEF_VAR(prefix, 0306); \ + DEF_VAR(prefix, 0307); \ + DEF_VAR(prefix, 0308); \ + DEF_VAR(prefix, 0309); \ + DEF_VAR(prefix, 0310); \ + DEF_VAR(prefix, 0311); \ + DEF_VAR(prefix, 0312); \ + DEF_VAR(prefix, 0313); \ + DEF_VAR(prefix, 0314); \ + DEF_VAR(prefix, 0315); \ + DEF_VAR(prefix, 0316); \ + DEF_VAR(prefix, 0317); \ + DEF_VAR(prefix, 0318); \ + DEF_VAR(prefix, 0319); \ + DEF_VAR(prefix, 0320); \ + DEF_VAR(prefix, 0321); \ + DEF_VAR(prefix, 0322); \ + DEF_VAR(prefix, 0323); \ + DEF_VAR(prefix, 0324); \ + DEF_VAR(prefix, 0325); \ + DEF_VAR(prefix, 0326); \ + DEF_VAR(prefix, 0327); \ + DEF_VAR(prefix, 0328); \ + DEF_VAR(prefix, 0329); \ + DEF_VAR(prefix, 0330); \ + DEF_VAR(prefix, 0331); \ + DEF_VAR(prefix, 0332); \ + DEF_VAR(prefix, 0333); \ + DEF_VAR(prefix, 0334); \ + DEF_VAR(prefix, 0335); \ + DEF_VAR(prefix, 0336); \ + DEF_VAR(prefix, 0337); \ + DEF_VAR(prefix, 0338); \ + DEF_VAR(prefix, 0339); \ + DEF_VAR(prefix, 0340); \ + DEF_VAR(prefix, 0341); \ + DEF_VAR(prefix, 0342); \ + DEF_VAR(prefix, 0343); \ + DEF_VAR(prefix, 0344); \ + DEF_VAR(prefix, 0345); \ + DEF_VAR(prefix, 0346); \ + DEF_VAR(prefix, 0347); \ + DEF_VAR(prefix, 0348); \ + DEF_VAR(prefix, 0349); \ + DEF_VAR(prefix, 0350); \ + DEF_VAR(prefix, 0351); \ + DEF_VAR(prefix, 0352); \ + DEF_VAR(prefix, 0353); \ + DEF_VAR(prefix, 0354); \ + DEF_VAR(prefix, 0355); \ + DEF_VAR(prefix, 0356); \ + DEF_VAR(prefix, 0357); \ + DEF_VAR(prefix, 0358); \ + DEF_VAR(prefix, 0359); \ + DEF_VAR(prefix, 0360); \ + DEF_VAR(prefix, 0361); \ + DEF_VAR(prefix, 0362); \ + DEF_VAR(prefix, 0363); \ + DEF_VAR(prefix, 0364); \ + DEF_VAR(prefix, 0365); \ + DEF_VAR(prefix, 0366); \ + DEF_VAR(prefix, 0367); \ + DEF_VAR(prefix, 0368); \ + DEF_VAR(prefix, 0369); \ + DEF_VAR(prefix, 0370); \ + DEF_VAR(prefix, 0371); \ + DEF_VAR(prefix, 0372); \ + DEF_VAR(prefix, 0373); \ + DEF_VAR(prefix, 0374); \ + DEF_VAR(prefix, 0375); \ + DEF_VAR(prefix, 0376); \ + DEF_VAR(prefix, 0377); \ + DEF_VAR(prefix, 0378); \ + DEF_VAR(prefix, 0379); \ + DEF_VAR(prefix, 0380); \ + DEF_VAR(prefix, 0381); \ + DEF_VAR(prefix, 0382); \ + DEF_VAR(prefix, 0383); \ + DEF_VAR(prefix, 0384); \ + DEF_VAR(prefix, 0385); \ + DEF_VAR(prefix, 0386); \ + DEF_VAR(prefix, 0387); \ + DEF_VAR(prefix, 0388); \ + DEF_VAR(prefix, 0389); \ + DEF_VAR(prefix, 0390); \ + DEF_VAR(prefix, 0391); \ + DEF_VAR(prefix, 0392); \ + DEF_VAR(prefix, 0393); \ + DEF_VAR(prefix, 0394); \ + DEF_VAR(prefix, 0395); \ + DEF_VAR(prefix, 0396); \ + DEF_VAR(prefix, 0397); \ + DEF_VAR(prefix, 0398); \ + DEF_VAR(prefix, 0399); \ + DEF_VAR(prefix, 0400); \ + DEF_VAR(prefix, 0401); \ + DEF_VAR(prefix, 0402); \ + DEF_VAR(prefix, 0403); \ + DEF_VAR(prefix, 0404); \ + DEF_VAR(prefix, 0405); \ + DEF_VAR(prefix, 0406); \ + DEF_VAR(prefix, 0407); \ + DEF_VAR(prefix, 0408); \ + DEF_VAR(prefix, 0409); \ + DEF_VAR(prefix, 0410); \ + DEF_VAR(prefix, 0411); \ + DEF_VAR(prefix, 0412); \ + DEF_VAR(prefix, 0413); \ + DEF_VAR(prefix, 0414); \ + DEF_VAR(prefix, 0415); \ + DEF_VAR(prefix, 0416); \ + DEF_VAR(prefix, 0417); \ + DEF_VAR(prefix, 0418); \ + DEF_VAR(prefix, 0419); \ + DEF_VAR(prefix, 0420); \ + DEF_VAR(prefix, 0421); \ + DEF_VAR(prefix, 0422); \ + DEF_VAR(prefix, 0423); \ + DEF_VAR(prefix, 0424); \ + DEF_VAR(prefix, 0425); \ + DEF_VAR(prefix, 0426); \ + DEF_VAR(prefix, 0427); \ + DEF_VAR(prefix, 0428); \ + DEF_VAR(prefix, 0429); \ + DEF_VAR(prefix, 0430); \ + DEF_VAR(prefix, 0431); \ + DEF_VAR(prefix, 0432); \ + DEF_VAR(prefix, 0433); \ + DEF_VAR(prefix, 0434); \ + DEF_VAR(prefix, 0435); \ + DEF_VAR(prefix, 0436); \ + DEF_VAR(prefix, 0437); \ + DEF_VAR(prefix, 0438); \ + DEF_VAR(prefix, 0439); \ + DEF_VAR(prefix, 0440); \ + DEF_VAR(prefix, 0441); \ + DEF_VAR(prefix, 0442); \ + DEF_VAR(prefix, 0443); \ + DEF_VAR(prefix, 0444); \ + DEF_VAR(prefix, 0445); \ + DEF_VAR(prefix, 0446); \ + DEF_VAR(prefix, 0447); \ + DEF_VAR(prefix, 0448); \ + DEF_VAR(prefix, 0449); \ + DEF_VAR(prefix, 0450); \ + DEF_VAR(prefix, 0451); \ + DEF_VAR(prefix, 0452); \ + DEF_VAR(prefix, 0453); \ + DEF_VAR(prefix, 0454); \ + DEF_VAR(prefix, 0455); \ + DEF_VAR(prefix, 0456); \ + DEF_VAR(prefix, 0457); \ + DEF_VAR(prefix, 0458); \ + DEF_VAR(prefix, 0459); \ + DEF_VAR(prefix, 0460); \ + DEF_VAR(prefix, 0461); \ + DEF_VAR(prefix, 0462); \ + DEF_VAR(prefix, 0463); \ + DEF_VAR(prefix, 0464); \ + DEF_VAR(prefix, 0465); \ + DEF_VAR(prefix, 0466); \ + DEF_VAR(prefix, 0467); \ + DEF_VAR(prefix, 0468); \ + DEF_VAR(prefix, 0469); \ + DEF_VAR(prefix, 0470); \ + DEF_VAR(prefix, 0471); \ + DEF_VAR(prefix, 0472); \ + DEF_VAR(prefix, 0473); \ + DEF_VAR(prefix, 0474); \ + DEF_VAR(prefix, 0475); \ + DEF_VAR(prefix, 0476); \ + DEF_VAR(prefix, 0477); \ + DEF_VAR(prefix, 0478); \ + DEF_VAR(prefix, 0479); \ + DEF_VAR(prefix, 0480); \ + DEF_VAR(prefix, 0481); \ + DEF_VAR(prefix, 0482); \ + DEF_VAR(prefix, 0483); \ + DEF_VAR(prefix, 0484); \ + DEF_VAR(prefix, 0485); \ + DEF_VAR(prefix, 0486); \ + DEF_VAR(prefix, 0487); \ + DEF_VAR(prefix, 0488); \ + DEF_VAR(prefix, 0489); \ + DEF_VAR(prefix, 0490); \ + DEF_VAR(prefix, 0491); \ + DEF_VAR(prefix, 0492); \ + DEF_VAR(prefix, 0493); \ + DEF_VAR(prefix, 0494); \ + DEF_VAR(prefix, 0495); \ + DEF_VAR(prefix, 0496); \ + DEF_VAR(prefix, 0497); \ + DEF_VAR(prefix, 0498); \ + DEF_VAR(prefix, 0499); \ + DEF_VAR(prefix, 0500); \ + DEF_VAR(prefix, 0501); \ + DEF_VAR(prefix, 0502); \ + DEF_VAR(prefix, 0503); \ + DEF_VAR(prefix, 0504); \ + DEF_VAR(prefix, 0505); \ + DEF_VAR(prefix, 0506); \ + DEF_VAR(prefix, 0507); \ + DEF_VAR(prefix, 0508); \ + DEF_VAR(prefix, 0509); \ + DEF_VAR(prefix, 0510); \ + DEF_VAR(prefix, 0511); \ + DEF_VAR(prefix, 0512); \ + DEF_VAR(prefix, 0513); \ + DEF_VAR(prefix, 0514); \ + DEF_VAR(prefix, 0515); \ + DEF_VAR(prefix, 0516); \ + DEF_VAR(prefix, 0517); \ + DEF_VAR(prefix, 0518); \ + DEF_VAR(prefix, 0519); \ + DEF_VAR(prefix, 0520); \ + DEF_VAR(prefix, 0521); \ + DEF_VAR(prefix, 0522); \ + DEF_VAR(prefix, 0523); \ + DEF_VAR(prefix, 0524); \ + DEF_VAR(prefix, 0525); \ + DEF_VAR(prefix, 0526); \ + DEF_VAR(prefix, 0527); \ + DEF_VAR(prefix, 0528); \ + DEF_VAR(prefix, 0529); \ + DEF_VAR(prefix, 0530); \ + DEF_VAR(prefix, 0531); \ + DEF_VAR(prefix, 0532); \ + DEF_VAR(prefix, 0533); \ + DEF_VAR(prefix, 0534); \ + DEF_VAR(prefix, 0535); \ + DEF_VAR(prefix, 0536); \ + DEF_VAR(prefix, 0537); \ + DEF_VAR(prefix, 0538); \ + DEF_VAR(prefix, 0539); \ + DEF_VAR(prefix, 0540); \ + DEF_VAR(prefix, 0541); \ + DEF_VAR(prefix, 0542); \ + DEF_VAR(prefix, 0543); \ + DEF_VAR(prefix, 0544); \ + DEF_VAR(prefix, 0545); \ + DEF_VAR(prefix, 0546); \ + DEF_VAR(prefix, 0547); \ + DEF_VAR(prefix, 0548); \ + DEF_VAR(prefix, 0549); \ + DEF_VAR(prefix, 0550); \ + DEF_VAR(prefix, 0551); \ + DEF_VAR(prefix, 0552); \ + DEF_VAR(prefix, 0553); \ + DEF_VAR(prefix, 0554); \ + DEF_VAR(prefix, 0555); \ + DEF_VAR(prefix, 0556); \ + DEF_VAR(prefix, 0557); \ + DEF_VAR(prefix, 0558); \ + DEF_VAR(prefix, 0559); \ + DEF_VAR(prefix, 0560); \ + DEF_VAR(prefix, 0561); \ + DEF_VAR(prefix, 0562); \ + DEF_VAR(prefix, 0563); \ + DEF_VAR(prefix, 0564); \ + DEF_VAR(prefix, 0565); \ + DEF_VAR(prefix, 0566); \ + DEF_VAR(prefix, 0567); \ + DEF_VAR(prefix, 0568); \ + DEF_VAR(prefix, 0569); \ + DEF_VAR(prefix, 0570); \ + DEF_VAR(prefix, 0571); \ + DEF_VAR(prefix, 0572); \ + DEF_VAR(prefix, 0573); \ + DEF_VAR(prefix, 0574); \ + DEF_VAR(prefix, 0575); \ + DEF_VAR(prefix, 0576); \ + DEF_VAR(prefix, 0577); \ + DEF_VAR(prefix, 0578); \ + DEF_VAR(prefix, 0579); \ + DEF_VAR(prefix, 0580); \ + DEF_VAR(prefix, 0581); \ + DEF_VAR(prefix, 0582); \ + DEF_VAR(prefix, 0583); \ + DEF_VAR(prefix, 0584); \ + DEF_VAR(prefix, 0585); \ + DEF_VAR(prefix, 0586); \ + DEF_VAR(prefix, 0587); \ + DEF_VAR(prefix, 0588); \ + DEF_VAR(prefix, 0589); \ + DEF_VAR(prefix, 0590); \ + DEF_VAR(prefix, 0591); \ + DEF_VAR(prefix, 0592); \ + DEF_VAR(prefix, 0593); \ + DEF_VAR(prefix, 0594); \ + DEF_VAR(prefix, 0595); \ + DEF_VAR(prefix, 0596); \ + DEF_VAR(prefix, 0597); \ + DEF_VAR(prefix, 0598); \ + DEF_VAR(prefix, 0599); \ + DEF_VAR(prefix, 0600); \ + DEF_VAR(prefix, 0601); \ + DEF_VAR(prefix, 0602); \ + DEF_VAR(prefix, 0603); \ + DEF_VAR(prefix, 0604); \ + DEF_VAR(prefix, 0605); \ + DEF_VAR(prefix, 0606); \ + DEF_VAR(prefix, 0607); \ + DEF_VAR(prefix, 0608); \ + DEF_VAR(prefix, 0609); \ + DEF_VAR(prefix, 0610); \ + DEF_VAR(prefix, 0611); \ + DEF_VAR(prefix, 0612); \ + DEF_VAR(prefix, 0613); \ + DEF_VAR(prefix, 0614); \ + DEF_VAR(prefix, 0615); \ + DEF_VAR(prefix, 0616); \ + DEF_VAR(prefix, 0617); \ + DEF_VAR(prefix, 0618); \ + DEF_VAR(prefix, 0619); \ + DEF_VAR(prefix, 0620); \ + DEF_VAR(prefix, 0621); \ + DEF_VAR(prefix, 0622); \ + DEF_VAR(prefix, 0623); \ + DEF_VAR(prefix, 0624); \ + DEF_VAR(prefix, 0625); \ + DEF_VAR(prefix, 0626); \ + DEF_VAR(prefix, 0627); \ + DEF_VAR(prefix, 0628); \ + DEF_VAR(prefix, 0629); \ + DEF_VAR(prefix, 0630); \ + DEF_VAR(prefix, 0631); \ + DEF_VAR(prefix, 0632); \ + DEF_VAR(prefix, 0633); \ + DEF_VAR(prefix, 0634); \ + DEF_VAR(prefix, 0635); \ + DEF_VAR(prefix, 0636); \ + DEF_VAR(prefix, 0637); \ + DEF_VAR(prefix, 0638); \ + DEF_VAR(prefix, 0639); \ + DEF_VAR(prefix, 0640); \ + DEF_VAR(prefix, 0641); \ + DEF_VAR(prefix, 0642); \ + DEF_VAR(prefix, 0643); \ + DEF_VAR(prefix, 0644); \ + DEF_VAR(prefix, 0645); \ + DEF_VAR(prefix, 0646); \ + DEF_VAR(prefix, 0647); \ + DEF_VAR(prefix, 0648); \ + DEF_VAR(prefix, 0649); \ + DEF_VAR(prefix, 0650); \ + DEF_VAR(prefix, 0651); \ + DEF_VAR(prefix, 0652); \ + DEF_VAR(prefix, 0653); \ + DEF_VAR(prefix, 0654); \ + DEF_VAR(prefix, 0655); \ + DEF_VAR(prefix, 0656); \ + DEF_VAR(prefix, 0657); \ + DEF_VAR(prefix, 0658); \ + DEF_VAR(prefix, 0659); \ + DEF_VAR(prefix, 0660); \ + DEF_VAR(prefix, 0661); \ + DEF_VAR(prefix, 0662); \ + DEF_VAR(prefix, 0663); \ + DEF_VAR(prefix, 0664); \ + DEF_VAR(prefix, 0665); \ + DEF_VAR(prefix, 0666); \ + DEF_VAR(prefix, 0667); \ + DEF_VAR(prefix, 0668); \ + DEF_VAR(prefix, 0669); \ + DEF_VAR(prefix, 0670); \ + DEF_VAR(prefix, 0671); \ + DEF_VAR(prefix, 0672); \ + DEF_VAR(prefix, 0673); \ + DEF_VAR(prefix, 0674); \ + DEF_VAR(prefix, 0675); \ + DEF_VAR(prefix, 0676); \ + DEF_VAR(prefix, 0677); \ + DEF_VAR(prefix, 0678); \ + DEF_VAR(prefix, 0679); \ + DEF_VAR(prefix, 0680); \ + DEF_VAR(prefix, 0681); \ + DEF_VAR(prefix, 0682); \ + DEF_VAR(prefix, 0683); \ + DEF_VAR(prefix, 0684); \ + DEF_VAR(prefix, 0685); \ + DEF_VAR(prefix, 0686); \ + DEF_VAR(prefix, 0687); \ + DEF_VAR(prefix, 0688); \ + DEF_VAR(prefix, 0689); \ + DEF_VAR(prefix, 0690); \ + DEF_VAR(prefix, 0691); \ + DEF_VAR(prefix, 0692); \ + DEF_VAR(prefix, 0693); \ + DEF_VAR(prefix, 0694); \ + DEF_VAR(prefix, 0695); \ + DEF_VAR(prefix, 0696); \ + DEF_VAR(prefix, 0697); \ + DEF_VAR(prefix, 0698); \ + DEF_VAR(prefix, 0699); \ + DEF_VAR(prefix, 0700); \ + DEF_VAR(prefix, 0701); \ + DEF_VAR(prefix, 0702); \ + DEF_VAR(prefix, 0703); \ + DEF_VAR(prefix, 0704); \ + DEF_VAR(prefix, 0705); \ + DEF_VAR(prefix, 0706); \ + DEF_VAR(prefix, 0707); \ + DEF_VAR(prefix, 0708); \ + DEF_VAR(prefix, 0709); \ + DEF_VAR(prefix, 0710); \ + DEF_VAR(prefix, 0711); \ + DEF_VAR(prefix, 0712); \ + DEF_VAR(prefix, 0713); \ + DEF_VAR(prefix, 0714); \ + DEF_VAR(prefix, 0715); \ + DEF_VAR(prefix, 0716); \ + DEF_VAR(prefix, 0717); \ + DEF_VAR(prefix, 0718); \ + DEF_VAR(prefix, 0719); \ + DEF_VAR(prefix, 0720); \ + DEF_VAR(prefix, 0721); \ + DEF_VAR(prefix, 0722); \ + DEF_VAR(prefix, 0723); \ + DEF_VAR(prefix, 0724); \ + DEF_VAR(prefix, 0725); \ + DEF_VAR(prefix, 0726); \ + DEF_VAR(prefix, 0727); \ + DEF_VAR(prefix, 0728); \ + DEF_VAR(prefix, 0729); \ + DEF_VAR(prefix, 0730); \ + DEF_VAR(prefix, 0731); \ + DEF_VAR(prefix, 0732); \ + DEF_VAR(prefix, 0733); \ + DEF_VAR(prefix, 0734); \ + DEF_VAR(prefix, 0735); \ + DEF_VAR(prefix, 0736); \ + DEF_VAR(prefix, 0737); \ + DEF_VAR(prefix, 0738); \ + DEF_VAR(prefix, 0739); \ + DEF_VAR(prefix, 0740); \ + DEF_VAR(prefix, 0741); \ + DEF_VAR(prefix, 0742); \ + DEF_VAR(prefix, 0743); \ + DEF_VAR(prefix, 0744); \ + DEF_VAR(prefix, 0745); \ + DEF_VAR(prefix, 0746); \ + DEF_VAR(prefix, 0747); \ + DEF_VAR(prefix, 0748); \ + DEF_VAR(prefix, 0749); \ + DEF_VAR(prefix, 0750); \ + DEF_VAR(prefix, 0751); \ + DEF_VAR(prefix, 0752); \ + DEF_VAR(prefix, 0753); \ + DEF_VAR(prefix, 0754); \ + DEF_VAR(prefix, 0755); \ + DEF_VAR(prefix, 0756); \ + DEF_VAR(prefix, 0757); \ + DEF_VAR(prefix, 0758); \ + DEF_VAR(prefix, 0759); \ + DEF_VAR(prefix, 0760); \ + DEF_VAR(prefix, 0761); \ + DEF_VAR(prefix, 0762); \ + DEF_VAR(prefix, 0763); \ + DEF_VAR(prefix, 0764); \ + DEF_VAR(prefix, 0765); \ + DEF_VAR(prefix, 0766); \ + DEF_VAR(prefix, 0767); \ + DEF_VAR(prefix, 0768); \ + DEF_VAR(prefix, 0769); \ + DEF_VAR(prefix, 0770); \ + DEF_VAR(prefix, 0771); \ + DEF_VAR(prefix, 0772); \ + DEF_VAR(prefix, 0773); \ + DEF_VAR(prefix, 0774); \ + DEF_VAR(prefix, 0775); \ + DEF_VAR(prefix, 0776); \ + DEF_VAR(prefix, 0777); \ + DEF_VAR(prefix, 0778); \ + DEF_VAR(prefix, 0779); \ + DEF_VAR(prefix, 0780); \ + DEF_VAR(prefix, 0781); \ + DEF_VAR(prefix, 0782); \ + DEF_VAR(prefix, 0783); \ + DEF_VAR(prefix, 0784); \ + DEF_VAR(prefix, 0785); \ + DEF_VAR(prefix, 0786); \ + DEF_VAR(prefix, 0787); \ + DEF_VAR(prefix, 0788); \ + DEF_VAR(prefix, 0789); \ + DEF_VAR(prefix, 0790); \ + DEF_VAR(prefix, 0791); \ + DEF_VAR(prefix, 0792); \ + DEF_VAR(prefix, 0793); \ + DEF_VAR(prefix, 0794); \ + DEF_VAR(prefix, 0795); \ + DEF_VAR(prefix, 0796); \ + DEF_VAR(prefix, 0797); \ + DEF_VAR(prefix, 0798); \ + DEF_VAR(prefix, 0799); \ + DEF_VAR(prefix, 0800); \ + DEF_VAR(prefix, 0801); \ + DEF_VAR(prefix, 0802); \ + DEF_VAR(prefix, 0803); \ + DEF_VAR(prefix, 0804); \ + DEF_VAR(prefix, 0805); \ + DEF_VAR(prefix, 0806); \ + DEF_VAR(prefix, 0807); \ + DEF_VAR(prefix, 0808); \ + DEF_VAR(prefix, 0809); \ + DEF_VAR(prefix, 0810); \ + DEF_VAR(prefix, 0811); \ + DEF_VAR(prefix, 0812); \ + DEF_VAR(prefix, 0813); \ + DEF_VAR(prefix, 0814); \ + DEF_VAR(prefix, 0815); \ + DEF_VAR(prefix, 0816); \ + DEF_VAR(prefix, 0817); \ + DEF_VAR(prefix, 0818); \ + DEF_VAR(prefix, 0819); \ + DEF_VAR(prefix, 0820); \ + DEF_VAR(prefix, 0821); \ + DEF_VAR(prefix, 0822); \ + DEF_VAR(prefix, 0823); \ + DEF_VAR(prefix, 0824); \ + DEF_VAR(prefix, 0825); \ + DEF_VAR(prefix, 0826); \ + DEF_VAR(prefix, 0827); \ + DEF_VAR(prefix, 0828); \ + DEF_VAR(prefix, 0829); \ + DEF_VAR(prefix, 0830); \ + DEF_VAR(prefix, 0831); \ + DEF_VAR(prefix, 0832); \ + DEF_VAR(prefix, 0833); \ + DEF_VAR(prefix, 0834); \ + DEF_VAR(prefix, 0835); \ + DEF_VAR(prefix, 0836); \ + DEF_VAR(prefix, 0837); \ + DEF_VAR(prefix, 0838); \ + DEF_VAR(prefix, 0839); \ + DEF_VAR(prefix, 0840); \ + DEF_VAR(prefix, 0841); \ + DEF_VAR(prefix, 0842); \ + DEF_VAR(prefix, 0843); \ + DEF_VAR(prefix, 0844); \ + DEF_VAR(prefix, 0845); \ + DEF_VAR(prefix, 0846); \ + DEF_VAR(prefix, 0847); \ + DEF_VAR(prefix, 0848); \ + DEF_VAR(prefix, 0849); \ + DEF_VAR(prefix, 0850); \ + DEF_VAR(prefix, 0851); \ + DEF_VAR(prefix, 0852); \ + DEF_VAR(prefix, 0853); \ + DEF_VAR(prefix, 0854); \ + DEF_VAR(prefix, 0855); \ + DEF_VAR(prefix, 0856); \ + DEF_VAR(prefix, 0857); \ + DEF_VAR(prefix, 0858); \ + DEF_VAR(prefix, 0859); \ + DEF_VAR(prefix, 0860); \ + DEF_VAR(prefix, 0861); \ + DEF_VAR(prefix, 0862); \ + DEF_VAR(prefix, 0863); \ + DEF_VAR(prefix, 0864); \ + DEF_VAR(prefix, 0865); \ + DEF_VAR(prefix, 0866); \ + DEF_VAR(prefix, 0867); \ + DEF_VAR(prefix, 0868); \ + DEF_VAR(prefix, 0869); \ + DEF_VAR(prefix, 0870); \ + DEF_VAR(prefix, 0871); \ + DEF_VAR(prefix, 0872); \ + DEF_VAR(prefix, 0873); \ + DEF_VAR(prefix, 0874); \ + DEF_VAR(prefix, 0875); \ + DEF_VAR(prefix, 0876); \ + DEF_VAR(prefix, 0877); \ + DEF_VAR(prefix, 0878); \ + DEF_VAR(prefix, 0879); \ + DEF_VAR(prefix, 0880); \ + DEF_VAR(prefix, 0881); \ + DEF_VAR(prefix, 0882); \ + DEF_VAR(prefix, 0883); \ + DEF_VAR(prefix, 0884); \ + DEF_VAR(prefix, 0885); \ + DEF_VAR(prefix, 0886); \ + DEF_VAR(prefix, 0887); \ + DEF_VAR(prefix, 0888); \ + DEF_VAR(prefix, 0889); \ + DEF_VAR(prefix, 0890); \ + DEF_VAR(prefix, 0891); \ + DEF_VAR(prefix, 0892); \ + DEF_VAR(prefix, 0893); \ + DEF_VAR(prefix, 0894); \ + DEF_VAR(prefix, 0895); \ + DEF_VAR(prefix, 0896); \ + DEF_VAR(prefix, 0897); \ + DEF_VAR(prefix, 0898); \ + DEF_VAR(prefix, 0899); \ + DEF_VAR(prefix, 0900); \ + DEF_VAR(prefix, 0901); \ + DEF_VAR(prefix, 0902); \ + DEF_VAR(prefix, 0903); \ + DEF_VAR(prefix, 0904); \ + DEF_VAR(prefix, 0905); \ + DEF_VAR(prefix, 0906); \ + DEF_VAR(prefix, 0907); \ + DEF_VAR(prefix, 0908); \ + DEF_VAR(prefix, 0909); \ + DEF_VAR(prefix, 0910); \ + DEF_VAR(prefix, 0911); \ + DEF_VAR(prefix, 0912); \ + DEF_VAR(prefix, 0913); \ + DEF_VAR(prefix, 0914); \ + DEF_VAR(prefix, 0915); \ + DEF_VAR(prefix, 0916); \ + DEF_VAR(prefix, 0917); \ + DEF_VAR(prefix, 0918); \ + DEF_VAR(prefix, 0919); \ + DEF_VAR(prefix, 0920); \ + DEF_VAR(prefix, 0921); \ + DEF_VAR(prefix, 0922); \ + DEF_VAR(prefix, 0923); \ + DEF_VAR(prefix, 0924); \ + DEF_VAR(prefix, 0925); \ + DEF_VAR(prefix, 0926); \ + DEF_VAR(prefix, 0927); \ + DEF_VAR(prefix, 0928); \ + DEF_VAR(prefix, 0929); \ + DEF_VAR(prefix, 0930); \ + DEF_VAR(prefix, 0931); \ + DEF_VAR(prefix, 0932); \ + DEF_VAR(prefix, 0933); \ + DEF_VAR(prefix, 0934); \ + DEF_VAR(prefix, 0935); \ + DEF_VAR(prefix, 0936); \ + DEF_VAR(prefix, 0937); \ + DEF_VAR(prefix, 0938); \ + DEF_VAR(prefix, 0939); \ + DEF_VAR(prefix, 0940); \ + DEF_VAR(prefix, 0941); \ + DEF_VAR(prefix, 0942); \ + DEF_VAR(prefix, 0943); \ + DEF_VAR(prefix, 0944); \ + DEF_VAR(prefix, 0945); \ + DEF_VAR(prefix, 0946); \ + DEF_VAR(prefix, 0947); \ + DEF_VAR(prefix, 0948); \ + DEF_VAR(prefix, 0949); \ + DEF_VAR(prefix, 0950); \ + DEF_VAR(prefix, 0951); \ + DEF_VAR(prefix, 0952); \ + DEF_VAR(prefix, 0953); \ + DEF_VAR(prefix, 0954); \ + DEF_VAR(prefix, 0955); \ + DEF_VAR(prefix, 0956); \ + DEF_VAR(prefix, 0957); \ + DEF_VAR(prefix, 0958); \ + DEF_VAR(prefix, 0959); \ + DEF_VAR(prefix, 0960); \ + DEF_VAR(prefix, 0961); \ + DEF_VAR(prefix, 0962); \ + DEF_VAR(prefix, 0963); \ + DEF_VAR(prefix, 0964); \ + DEF_VAR(prefix, 0965); \ + DEF_VAR(prefix, 0966); \ + DEF_VAR(prefix, 0967); \ + DEF_VAR(prefix, 0968); \ + DEF_VAR(prefix, 0969); \ + DEF_VAR(prefix, 0970); \ + DEF_VAR(prefix, 0971); \ + DEF_VAR(prefix, 0972); \ + DEF_VAR(prefix, 0973); \ + DEF_VAR(prefix, 0974); \ + DEF_VAR(prefix, 0975); \ + DEF_VAR(prefix, 0976); \ + DEF_VAR(prefix, 0977); \ + DEF_VAR(prefix, 0978); \ + DEF_VAR(prefix, 0979); \ + DEF_VAR(prefix, 0980); \ + DEF_VAR(prefix, 0981); \ + DEF_VAR(prefix, 0982); \ + DEF_VAR(prefix, 0983); \ + DEF_VAR(prefix, 0984); \ + DEF_VAR(prefix, 0985); \ + DEF_VAR(prefix, 0986); \ + DEF_VAR(prefix, 0987); \ + DEF_VAR(prefix, 0988); \ + DEF_VAR(prefix, 0989); \ + DEF_VAR(prefix, 0990); \ + DEF_VAR(prefix, 0991); \ + DEF_VAR(prefix, 0992); \ + DEF_VAR(prefix, 0993); \ + DEF_VAR(prefix, 0994); \ + DEF_VAR(prefix, 0995); \ + DEF_VAR(prefix, 0996); \ + DEF_VAR(prefix, 0997); \ + DEF_VAR(prefix, 0998); \ + DEF_VAR(prefix, 0999); \ + DEF_VAR(prefix, 1000); \ + DEF_VAR(prefix, 1001); \ + DEF_VAR(prefix, 1002); \ + DEF_VAR(prefix, 1003); \ + DEF_VAR(prefix, 1004); \ + DEF_VAR(prefix, 1005); \ + DEF_VAR(prefix, 1006); \ + DEF_VAR(prefix, 1007); \ + DEF_VAR(prefix, 1008); \ + DEF_VAR(prefix, 1009); \ + DEF_VAR(prefix, 1010); \ + DEF_VAR(prefix, 1011); \ + DEF_VAR(prefix, 1012); \ + DEF_VAR(prefix, 1013); \ + DEF_VAR(prefix, 1014); \ + DEF_VAR(prefix, 1015); \ + DEF_VAR(prefix, 1016); \ + DEF_VAR(prefix, 1017); \ + DEF_VAR(prefix, 1018); \ + DEF_VAR(prefix, 1019); \ + DEF_VAR(prefix, 1020); \ + DEF_VAR(prefix, 1021); \ + DEF_VAR(prefix, 1022); \ + DEF_VAR(prefix, 1023); \ + DEF_VAR(prefix, 1024); diff --git a/ext/opcache/jit/tls/testing/def.c b/ext/opcache/jit/tls/testing/def.c new file mode 100644 index 000000000000..f18d577e278a --- /dev/null +++ b/ext/opcache/jit/tls/testing/def.c @@ -0,0 +1,33 @@ + +/* _tsrm_ls_cache is defined here */ + +#include +#include +#include + +#ifdef NO_SURPLUS +# include "def-vars.h" +DEF_VARS(def); +#endif + +__thread void* _tsrm_ls_cache; + +size_t tsrm_get_ls_cache_tcb_offset(void) { + return 0; +} + +void zend_accel_error(int type, const char *format, ...) { + if (type < 4) { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + } +} + +int test(void); + +int decl(void) { + return test(); +} + diff --git a/ext/opcache/jit/tls/testing/main.c b/ext/opcache/jit/tls/testing/main.c new file mode 100644 index 000000000000..75d40ff7888e --- /dev/null +++ b/ext/opcache/jit/tls/testing/main.c @@ -0,0 +1,48 @@ +#include +#include + +#ifdef NO_SURPLUS +# include "def-vars.h" +DEF_VARS(main); +#endif + +__thread int some_tls_var; + +#ifndef DL_DECL +int decl(void); +#endif + +int main(void) { + /* Ensure TLS vars are allocated */ + some_tls_var = 1; + + int (*decl_p)(void); +#ifdef DL_DECL + int flags = RTLD_LAZY | RTLD_GLOBAL; +# ifdef RTLD_DEEPBIND + flags |= RTLD_DEEPBIND; +# endif + void *handle = dlopen("./libdef.so", flags); + if (!handle) { + fprintf(stderr, "dlopen: %s\n", dlerror()); + return 1; + } + + decl_p = (int (*)(void)) dlsym(handle, "decl"); + if (!decl_p) { + fprintf(stderr, "dlsym: %s\n", dlerror()); + return 1; + } +#else + decl_p = decl; +#endif + + int ret = decl_p(); + if (!ret) { + fprintf(stderr, "FAIL\n"); + } else { + fprintf(stderr, "OK\n"); + } + + return !ret; +} diff --git a/ext/opcache/jit/tls/testing/test.sh b/ext/opcache/jit/tls/testing/test.sh new file mode 100755 index 000000000000..c6b003caafdd --- /dev/null +++ b/ext/opcache/jit/tls/testing/test.sh @@ -0,0 +1,232 @@ +#!/bin/sh + +set -e +cd "$(dirname "$0")" + +print_test() { + echo "Testing: $1 (CC=$CC LD=$LD CFLAGS=$CFLAGS)" +} + +exe_def_static_user() { + print_test "TLS var defined in executable, used in same object" + + rm -f main + + $CC $CFLAGS -ggdb3 -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -o user.o -c user.c + $CC $CFLAGS -ggdb3 -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -ggdb3 -o main main.c def.o user.o tls.o + + ./main +} + +exe_def_shared_user() { + print_test "TLS var defined in executable, used in shared library" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -ggdb3 -fPIC -o main main.c def.o -Wl,-rpath,$(pwd) -L. -luser + + ./main +} + +shared_def_static_user() { + print_test "TLS var defined in shared library, used in same object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o user.o tls.o + + $CC $CFLAGS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +shared_def_shared_user() { + print_test "TLS var defined in shared object, used in other shared object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +shared_def_static_user_no_surplus() { + print_test "TLS var defined in shared library, used in same object. Likely no static TLS surplus." + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o tls.o user.o + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +shared_def_shared_user_no_surplus() { + print_test "TLS var defined in shared object, used in other shared object. Likely no static TLS surplus." + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -ggdb3 -fPIC -o main main.c -Wl,-rpath,$(pwd) -L. -ldef + + ./main +} + +dl_def_static_user() { + print_test "TLS var defined in dl()'ed object, used in same object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o user.o tls.o + + $CC $CFLAGS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +dl_def_shared_user() { + print_test "TLS var defined in dl()'ed object, used in other shared object" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +dl_def_static_user_no_surplus() { + print_test "TLS var defined in dl()'ed object, used in same object. Likely no surplus TLS" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o user.o tls.o + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +dl_def_shared_user_no_surplus() { + print_test "TLS var defined in dl()'ed object, used in other shared object. Likely no surplus TLS" + + rm -f main + + $CC $CFLAGS -ggdb3 -fPIC -o tls.o -c $TLSC + $CC $CFLAGS -ggdb3 -fPIC -o user.o -c user.c + $CC $CFLAGS $LDFLAGS -shared -o libuser.so user.o tls.o + + $CC $CFLAGS -DNO_SURPLUS -ggdb3 -fPIC -o def.o -c def.c + $CC $CFLAGS $LDFLAGS -shared -o libdef.so def.o -Wl,-rpath,$(pwd) -L. -luser + + $CC $CFLAGS -DNO_SURPLUS $LDFLAGS -DDL_DECL -ggdb3 -fPIC -o main main.c + + ./main +} + +if [ -z "$TLSC" ]; then + echo "Variable TLSC is not set" >&2 + exit 1 +fi + +root=$(pwd)/../../../../.. + +# Cheap musl detection +if test -f /etc/alpine-release; then + MUSL="$CFLAGS -D__MUSL__" +else + MUSL= +fi + +if [ "${STATIC_SUPPORT:-yes}" = "yes" ]; then + STATIC=-static +fi + +for CC in clang gcc; do + if [ $CC = gcc ] && [ -f /etc/freebsd-update.conf ]; then + RPATH=-Wl,-rpath,/usr/local/lib/gcc13 + else + RPATH= + fi + case $CC in + gcc) + LDs="" + for l in bdf gold; do + if command -v ld.$l >/dev/null 2>&1; then + LDs="$LDs $l" + fi + done + if [ -z "$LDs" ]; then + LDs=ld + fi + ;; + clang) + LDs="ld" + if command -v ld.lld >/dev/null 2>&1; then + LDs="$LDs lld" + fi + ;; + esac + for LD in $LDs; do + for opt in -O0 -O3; do + CFLAGS="$MACHINE $MUSL $opt -Werror -I$root/ext/opcache -I$root/Zend -I$root" + LDFLAGS="$MACHINE -fuse-ld=$LD $RPATH" + + for pic in "-fPIC" "-fno-PIC $STATIC"; do + CFLAGS="$CFLAGS $pic" exe_def_static_user + done + shared_def_static_user + shared_def_static_user_no_surplus + dl_def_static_user + dl_def_static_user_no_surplus + if [ "$EXTERN_TLS_SUPPORT" = yes ]; then + exe_def_shared_user + shared_def_shared_user + shared_def_shared_user_no_surplus + dl_def_shared_user + dl_def_shared_user_no_surplus + fi + done + done +done + +echo "All OK" >&2 diff --git a/ext/opcache/jit/tls/testing/user.c b/ext/opcache/jit/tls/testing/user.c new file mode 100644 index 000000000000..c27e608f3f4b --- /dev/null +++ b/ext/opcache/jit/tls/testing/user.c @@ -0,0 +1,28 @@ + +/* _tsrm_ls_cache is used / inspected here */ + +#include "../zend_jit_tls.h" + +extern __thread void* _tsrm_ls_cache; + +int test(void) +{ + size_t tcb_offset = 0; + size_t module_index = -1; + size_t module_offset = -1; + + /* Ensure the slot is allocated */ + _tsrm_ls_cache = NULL; + + zend_result result = zend_jit_resolve_tsrm_ls_cache_offsets( + &tcb_offset, &module_index, &module_offset); + + printf("tcb_offset: %zd; module_index: %zd; module_offset: %zd\n", + tcb_offset, module_index, module_offset); + + if (result != SUCCESS) { + return 0; + } + + return zend_jit_tsrm_ls_cache_address(tcb_offset, module_index, module_offset) == &_tsrm_ls_cache; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls.h b/ext/opcache/jit/tls/zend_jit_tls.h new file mode 100644 index 000000000000..7faa76fa6a31 --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls.h @@ -0,0 +1,38 @@ +/* + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ + */ + +#ifndef ZEND_JIT_TLS_H +#define ZEND_JIT_TLS_H + +#include "Zend/zend_types.h" + +#include +#include + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +); + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +); + +#endif /* ZEND_JIT_TLS_H */ diff --git a/ext/opcache/jit/tls/zend_jit_tls_aarch64.c b/ext/opcache/jit/tls/zend_jit_tls_aarch64.c new file mode 100644 index 000000000000..3258a3123ebb --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_aarch64.c @@ -0,0 +1,255 @@ +/* + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ + */ + +#include "Zend/zend_portability.h" +#include "Zend/zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +/* https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/ADRP--Form-PC-relative-address-to-4KB-page- */ +#define AARCH64_ADRP_IMM_MASK 0x60ffffe0 /* bits 30-29, 23-5 */ +#define AARCH64_ADRP_IMMHI_MASK 0x00ffffe0 /* bits 23-5 */ +#define AARCH64_ADRP_IMMLO_MASK 0x60000000 /* bits 30-29 */ +#define AARCH64_ADRP_IMMHI_START 5 +#define AARCH64_ADRP_IMMLO_START 29 +#define AARCH64_ADRP_IMMLO_WIDTH 2 + +#define AARCH64_LDR_UNSIGNED_IMM_MASK 0x003ffc00 /* bits 21-10 */ +#define AARCH64_ADD_IMM_MASK 0x003ffc00 /* bits 21-10 */ +#define AARCH64_MOVZ_IMM_MASK 0x001fffe0 /* bits 20-5 */ +#define AARCH64_MOVZ_HW_MASK 0x00600000 /* bits 22-21 */ +#define AARCH64_MOVK_IMM_MASK 0x001fffe0 /* bits 20-5 */ +#define AARCH64_MOVK_HW_MASK 0x00600000 /* bits 22-21 */ +#define AARCH64_NOP 0xd503201f + +#undef USE_FALLBACK + +#ifdef __MUSL__ + +# define DTV_OFFSET -8 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#elif defined(__FreeBSD__) + +# define DTV_OFFSET 0 +/* Index is offset by 1 on FreeBSD (https://github.com/freebsd/freebsd-src/blob/22ca6db50f4e6bd75a141f57cf953d8de6531a06/lib/libc/gen/tls.c#L88) */ +# define DTV_INDEX_GAP 1 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +/* https://github.com/freebsd/freebsd-src/blob/c52ca7dd09066648b1cc40f758289404d68ab886/libexec/rtld-elf/aarch64/reloc.c#L180-L184 */ +typedef struct _tls_descriptor { + void* thunk; + int index; + size_t offset; +} tls_descriptor; + +#elif defined(__GLIBC__) + +# define DTV_OFFSET 0 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; + uintptr_t _; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#else +# define USE_FALLBACK 1 +#endif + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { +#ifdef USE_FALLBACK + return FAILURE; +#else + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + + void *addr; + uint32_t *insn; + void *thread_pointer; + + __asm__ __volatile__( + /* Load thread pointer address */ + "mrs %0, tpidr_el0\n" + /* Load next instruction address */ + "adr %1, .+4\n\t" + /* General Dynamic code sequence as expected by linkers */ + "adrp x0, :tlsdesc:_tsrm_ls_cache\n" + "ldr x1, [x0, #:tlsdesc_lo12:_tsrm_ls_cache]\n" + "add x0, x0, :tlsdesc_lo12:_tsrm_ls_cache\n" + ".tlsdesccall _tsrm_ls_cache\n" + "blr x1\n" + "mrs x8, tpidr_el0\n" + "add %2, x8, x0\n" + : "=r" (thread_pointer), "=r" (insn), "=r" (addr) + : + : "x0", "x1", "x8"); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); + + /* Check if the general dynamic code was relaxed by the linker */ + + // adrp x0, #any + if ((insn[0] & ~AARCH64_ADRP_IMM_MASK) != 0x90000000) { + zend_accel_error(ACCEL_LOG_DEBUG, "adrp insn does not match: 0x%08" PRIx32 "\n", insn[0]); + goto code_changed; + } + + // ldr x1, [x0, #any] + if ((insn[1] & ~AARCH64_LDR_UNSIGNED_IMM_MASK) != 0xf9400001) { + zend_accel_error(ACCEL_LOG_DEBUG, "ldr insn does not match: 0x%08" PRIx32 "\n", insn[1]); + goto code_changed; + } + + // add x0, x0, any + if ((insn[2] & ~AARCH64_ADD_IMM_MASK) != 0x91000000) { + zend_accel_error(ACCEL_LOG_DEBUG, "add insn does not match: 0x%08" PRIx32 "x\n", insn[2]); + goto code_changed; + } + + /* Code is intact, we can extract immediate values */ + + uint64_t adrp_immhi = (uint64_t)((insn[0] & AARCH64_ADRP_IMMHI_MASK) >> AARCH64_ADRP_IMMHI_START); + uint64_t adrp_immlo = (uint64_t)((insn[0] & AARCH64_ADRP_IMMLO_MASK) >> AARCH64_ADRP_IMMLO_START); + uint64_t adrp_imm = ((adrp_immhi << AARCH64_ADRP_IMMLO_WIDTH) | adrp_immlo) << 12; + uint64_t add_imm = (uint64_t)(insn[2] & AARCH64_ADD_IMM_MASK) >> 10; + uint64_t pc = (uint64_t)insn; + uintptr_t **where = (uintptr_t**)((pc & ~(4096-1)) + adrp_imm + add_imm); + + /* See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst + * section "Relocations for thread-local storage". + * The first entry holds a pointer to the variable's TLS descriptor resolver + * function and the second entry holds a platform-specific offset or + * pointer. */ + tls_descriptor *tlsdesc = (tls_descriptor*)(where[1]); + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == (uintptr_t)tlsdesc) { + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %p from thread pointer (inferred from tlsdesc)\n", tlsdesc); + *tcb_offset = (uintptr_t)tlsdesc; + return SUCCESS; + } + + *module_index = (tlsdesc->index + DTV_INDEX_GAP) * sizeof(dtv_pointer_t); + *module_offset = tlsdesc->offset; + +# if ZEND_DEBUG + /* We've got the TLS descriptor. Double check: */ + + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + addr = (void*)(((dtv_pointer_t*)((char*)dtv + *module_index))->val + *module_offset); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); +# endif + + zend_accel_error(ACCEL_LOG_DEBUG, "dynamic tls module idx %zu offset %zu (inferred from code)\n", (size_t)tlsdesc->index, tlsdesc->offset); + + return SUCCESS; + +code_changed: + + /* Code was changed by the linker. Check if we recognize the updated code */ + + // movz x0, #0, lsl #16 + if ((insn[0] & ~AARCH64_MOVZ_IMM_MASK) != 0xd2a00000) { + zend_accel_error(ACCEL_LOG_DEBUG, "movz insn does not match: 0x%08" PRIx32 "\n", insn[0]); + return FAILURE; + } + + // movk x0, #0x10 + if ((insn[1] & ~AARCH64_MOVK_IMM_MASK) != 0xf2800000) { + zend_accel_error(ACCEL_LOG_DEBUG, "movk insn does not match: 0x%08" PRIx32 "\n", insn[1]); + return FAILURE; + } + + // nop + for (int i = 0; i < 2; i++) { + if (insn[2+i] != AARCH64_NOP) { + zend_accel_error(ACCEL_LOG_DEBUG, "nop(%d) insn does not match: 0x%08" PRIx32 "\n", i, insn[2+i]); + return FAILURE; + } + } + + /* Extract immediate values */ + + uint64_t movz_imm = (insn[0] & AARCH64_MOVZ_IMM_MASK) >> 5; + uint64_t movz_shift = (((insn[0] & AARCH64_MOVZ_HW_MASK) >> 21) << 4); + uint64_t movk_imm = (insn[1] & AARCH64_MOVK_IMM_MASK) >> 5; + uint64_t offset = (movz_imm << movz_shift) | movk_imm; + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == offset) { + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %" PRIxPTR " from thread pointer (inferred from code)\n", offset); + *tcb_offset = offset; + return SUCCESS; + } + + zend_accel_error(ACCEL_LOG_DEBUG, "static tls offset does not match: %" PRIxPTR " (expected %" PRIxPTR ")\n", + offset, ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer)); + + return FAILURE; +#endif +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { +#ifndef USE_FALLBACK + char *thread_pointer; + __asm__ __volatile__( + "mrs %0, tpidr_el0\n" + : "=r" (thread_pointer) + ); + + if (tcb_offset) { + return thread_pointer + tcb_offset; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset); + } +#endif + return NULL; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_darwin.c b/ext/opcache/jit/tls/zend_jit_tls_darwin.c new file mode 100644 index 000000000000..8857ef5e738c --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_darwin.c @@ -0,0 +1,120 @@ +/* + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov | + +----------------------------------------------------------------------+ + */ + +#include "Zend/zend_portability.h" +#include "Zend/zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" + +#include +#include +#include + +TSRMLS_CACHE_EXTERN(); + +/* Thunk format used since dydl 1284 (approx. MacOS 15) + * https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/ThreadLocalVariables.h#L146 */ +#if defined(__x86_64__) || defined(__aarch64__) +struct TLV_Thunkv2 +{ + void* func; + uint32_t key; + uint32_t offset; +}; +#else +struct TLV_Thunkv2 +{ + void* func; + uint16_t key; + uint16_t offset; +}; +#endif + +/* Thunk format used in earlier versions */ +struct TLV_Thunkv1 +{ + void* func; + size_t key; + size_t offset; +}; + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + +#if defined(__x86_64__) + struct TLV_Thunkv2 *thunk; + __asm__ __volatile__( + "leaq __tsrm_ls_cache(%%rip),%0" + : "=r" (thunk)); + + /* Detect dyld 1284: With dyld 1284, thunk->func will be _tlv_get_addr. + * Unfortunately this symbol is private, but we can find it + * as _tlv_bootstrap+8: https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/threadLocalHelpers.s#L54 + * In earlier versions, thunk->func will be tlv_get_addr, which is not + * _tlv_bootstrap+8. + */ + if (thunk->func == (void*)((char*)_tlv_bootstrap + 8)) { + *module_offset = thunk->offset; + *module_index = (size_t)thunk->key * 8; + } else { + struct TLV_Thunkv1 *thunkv1 = (struct TLV_Thunkv1*) thunk; + *module_offset = thunkv1->offset; + *module_index = thunkv1->key * 8; + } + + return SUCCESS; +#endif + + return FAILURE; +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { + +#if defined(__x86_64__) + if (tcb_offset) { + char *addr; + __asm__ __volatile__( + "movq %%gs:(%1), %0\n" + : "=r" (addr) + : "r" (tcb_offset) + ); + return addr; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + char *base; + __asm__ __volatile__( + "movq %%gs:(%1), %0\n" + : "=r" (base) + : "r" (module_index) + ); + return base + module_offset; + } +#endif + + return NULL; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_win.c b/ext/opcache/jit/tls/zend_jit_tls_win.c new file mode 100644 index 000000000000..5646f3dcba0b --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_win.c @@ -0,0 +1,62 @@ +/* + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov | + +----------------------------------------------------------------------+ + */ + +#include "Zend/zend_portability.h" +#include "Zend/zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +extern uint32_t _tls_index; +extern char *_tls_start; +extern char *_tls_end; + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { + /* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */ + /* Probably, it might be better solution */ +#ifdef _WIN64 + void ***tls_mem = ((void****)__readgsqword(0x58))[_tls_index]; +#else + void ***tls_mem = ((void****)__readfsdword(0x2c))[_tls_index]; +#endif + void *val = _tsrm_ls_cache; + size_t offset = 0; + size_t size = (char*)&_tls_end - (char*)&_tls_start; + + while (offset < size) { + if (*tls_mem == val) { + *module_index = _tls_index * sizeof(void*); + *module_offset = offset; + return SUCCESS; + } + tls_mem++; + offset += sizeof(void*); + } + + if (offset >= size) { + zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: offset >= size"); + } + + return FAILURE; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_x86.c b/ext/opcache/jit/tls/zend_jit_tls_x86.c new file mode 100644 index 000000000000..362dffb47785 --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_x86.c @@ -0,0 +1,239 @@ +/* + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ + */ + +#include "zend_portability.h" +#include "zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" +#include "zend_jit_tls.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +#undef USE_FALLBACK + +#ifdef __MUSL__ + +# define DTV_OFFSET 4 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#elif defined(__FreeBSD__) + +# define DTV_OFFSET 4 +# define DTV_INDEX_GAP 1 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +/* https://github.com/freebsd/freebsd-src/blob/6b94546a7ea2dc593f5765bd5465a8b7bb80c325/libexec/rtld-elf/i386/rtld_machdep.h#L65 */ +typedef struct _tls_descriptor { + unsigned long index; + unsigned long offset; +} tls_descriptor; + +#elif defined(__GLIBC__) + +# define DTV_OFFSET 4 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; + uintptr_t _; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#else +# define USE_FALLBACK 1 +#endif + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { +#ifdef USE_FALLBACK + return FAILURE; +#else + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + + void *t_addr; + unsigned char *code; + void *thread_pointer; + + __asm__ __volatile__( + /* Load next instruction address */ + "call 1f\n" + ".subsection 1\n" + "1:\n" + "movl (%%esp), %%ebx\n" + "movl %%ebx, %%esi\n" + "ret\n" + ".previous\n" + /* General Dynamic code sequence as expected by linkers */ + "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n" + "leal _tsrm_ls_cache@TLSGD(,%%ebx,1), %%eax\n" + "call ___tls_get_addr@PLT\n" + /* Load thread pointer address */ + "movl %%gs:0, %%ebx\n" + : "=a" (t_addr), "=S" (code), "=b" (thread_pointer) + ); + + ZEND_ASSERT(t_addr == &_tsrm_ls_cache); + + /* Check if the general dynamic code was relaxed by the linker */ + + // addl any,%ebx + if (memcmp(&code[0], "\x81\xc3", 2) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[0], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "addl insn does not match: 0x%16" PRIx64 "\n", bytes); + goto code_changed; + } + + // leal any(,%ebx,1),%eax + if (memcmp(&code[6], "\x8d\x04\x1d", 3) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[6], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "leal insn does not match: 0x%16" PRIx64 "\n", bytes); + goto code_changed; + } + + // call any + if (memcmp(&code[13], "\xe8", 1) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[13], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "call insn does not match: 0x%16" PRIx64 "\n", bytes); + goto code_changed; + } + + /* Code is intact, we can extract immediate values */ + + uint32_t addl_imm = ((uint32_t)code[5] << 24) + | ((uint32_t)code[4] << 16) + | ((uint32_t)code[3] << 8) + | ((uint32_t)code[2]); + uint32_t leal_imm = ((uint32_t)code[12] << 24) + | ((uint32_t)code[11] << 16) + | ((uint32_t)code[10] << 8) + | ((uint32_t)code[9]); + + tls_descriptor *tlsdesc = (tls_descriptor*)(leal_imm + addl_imm + (uintptr_t)code); + + *module_index = (tlsdesc->index + DTV_INDEX_GAP) * sizeof(dtv_pointer_t); + *module_offset = tlsdesc->offset; + +# if ZEND_DEBUG + /* We've got the TLS descriptor. Double check: */ + + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + void *addr = (void*)(((dtv_pointer_t*)((char*)dtv + *module_index))->val + *module_offset); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); +# endif + + zend_accel_error(ACCEL_LOG_DEBUG, "dynamic tls module idx %zu offset %zu (inferred from code)\n", + (size_t)tlsdesc->index, (size_t)tlsdesc->offset); + + return SUCCESS; + +code_changed: + + /* Code was changed by the linker. Check if we recognize the updated code */ + + /* + * 81 c3 98 2d 00 00 addl $0x2d98,%ebx + * 65 a1 00 00 00 00 movl %gs:0x0,%eax + * 81 e8 04 00 00 00 subl $0x4,%eax + */ + + // movl %gs:0x0,%eax + if (memcmp(&code[6], "\x65\xa1\x00\x00\x00\x00", 6) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[6], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "movl insn does not match: 0x%16" PRIx64 "\n", bytes); + return FAILURE; + } + + // subl $any,%eax + if (memcmp(&code[12], "\x81\xe8", 2) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[6], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "subl insn does not match: 0x%16" PRIx64 "\n", bytes); + return FAILURE; + } + + /* Extract immediate values */ + + uint32_t offset = -(((uint32_t)code[17] << 24) + | ((uint32_t)code[16] << 16) + | ((uint32_t)code[15] << 8) + | ((uint32_t)code[14])); + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == offset) { + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %" PRIx32 " from thread pointer (inferred from code)\n", offset); + *tcb_offset = offset; + return SUCCESS; + } + + zend_accel_error(ACCEL_LOG_DEBUG, "static tls offset does not match: 0x%" PRIx32 " (expected 0x%" PRIx32 ")\n", + offset, (uint32_t)((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer)); + + return FAILURE; +#endif +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { +#ifndef USE_FALLBACK + char *thread_pointer; + __asm__ __volatile__( + "movl %%gs:0, %0\n" + : "=r" (thread_pointer) + ); + + if (tcb_offset) { + return thread_pointer + tcb_offset; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset); + } +#endif + return NULL; +} diff --git a/ext/opcache/jit/tls/zend_jit_tls_x86_64.c b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c new file mode 100644 index 000000000000..1b2730c4be92 --- /dev/null +++ b/ext/opcache/jit/tls/zend_jit_tls_x86_64.c @@ -0,0 +1,222 @@ +/* + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Arnaud Le Blanc | + +----------------------------------------------------------------------+ + */ + +#include "zend_portability.h" +#include "zend_types.h" +#include "TSRM/TSRM.h" +#include "zend_accelerator_debug.h" +#include "zend_jit_tls.h" + +#include +#include + +TSRMLS_CACHE_EXTERN(); + +#undef USE_FALLBACK + +#ifdef __MUSL__ + +# define DTV_OFFSET 8 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#elif defined(__FreeBSD__) + +# define DTV_OFFSET 8 +# define DTV_INDEX_GAP 1 + +typedef struct _dtv_pointer_t { + uintptr_t val; +} dtv_pointer_t; + +/* https://github.com/freebsd/freebsd-src/blob/6b94546a7ea2dc593f5765bd5465a8b7bb80c325/libexec/rtld-elf/amd64/rtld_machdep.h#L65 */ +typedef struct _tls_descriptor { + unsigned long index; + unsigned long offset; +} tls_descriptor; + +#elif defined(__GLIBC__) + +# define DTV_OFFSET 8 +# define DTV_INDEX_GAP 0 + +typedef struct _dtv_pointer_t { + uintptr_t val; + uintptr_t _; +} dtv_pointer_t; + +typedef struct _tls_descriptor { + size_t index; + size_t offset; +} tls_descriptor; + +#else +# define USE_FALLBACK 1 +#endif + +zend_result zend_jit_resolve_tsrm_ls_cache_offsets( + size_t *tcb_offset, + size_t *module_index, + size_t *module_offset +) { +#ifdef USE_FALLBACK + return FAILURE; +#else + *tcb_offset = tsrm_get_ls_cache_tcb_offset(); + if (*tcb_offset != 0) { + return SUCCESS; + } + + void *addr; + unsigned char *code; + void *thread_pointer; + + __asm__ __volatile__( + /* Load next instruction address */ + "leaq (%%rip), %%rbx\n" + /* General Dynamic code sequence as expected by linkers */ + ".byte 0x66\n" + "leaq _tsrm_ls_cache@tlsgd(%%rip), %%rdi\n" + ".word 0x6666\n" + "rex64\n" + "call __tls_get_addr\n" + /* Load thread pointer address */ + "movq %%fs:0, %%rsi\n" + : "=a" (addr), "=b" (code), "=S" (thread_pointer) + ); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); + + /* Check if the general dynamic code was relaxed by the linker */ + + // data16 leaq any(%rip),%rdi + if (memcmp(&code[0], "\x66\x48\x8d\x3d", 4) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[0], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "leaq insn does not match: 0x%016" PRIx64 "\n", bytes); + goto code_changed; + } + + // data16 data16 rex.W call any + if (memcmp(&code[8], "\x66\x66\x48\xe8", 4) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[8], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "call insn does not match: 0x%016" PRIx64 "\n", bytes); + goto code_changed; + } + + /* Code is intact, we can extract immediate values */ + + uintptr_t leaq_imm = (uintptr_t)(int32_t)((uint32_t)code[7] << 24) + | ((uint32_t)code[6] << 16) + | ((uint32_t)code[5] << 8) + | ((uint32_t)code[4]); + + tls_descriptor *tlsdesc = (tls_descriptor*)(leaq_imm + (uintptr_t)code + 8 /* leaq */); + + *module_index = ((size_t)tlsdesc->index + DTV_INDEX_GAP) * sizeof(dtv_pointer_t); + *module_offset = (size_t)tlsdesc->offset; + +# if ZEND_DEBUG + /* We've got the TLS descriptor. Double check: */ + + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + addr = (void*)(((dtv_pointer_t*)((char*)dtv + *module_index))->val + *module_offset); + + ZEND_ASSERT(addr == &_tsrm_ls_cache); +# endif + + zend_accel_error(ACCEL_LOG_DEBUG, "dynamic tls module idx %zu offset %zu (inferred from code)\n", + (size_t)tlsdesc->index, (size_t)tlsdesc->offset); + + return SUCCESS; + +code_changed: + + /* Code was changed by the linker. Check if we recognize the updated code */ + + /* + * 64 48 8b 04 25 00 00 00 00 movq %fs:0x0,%rax + * 48 8d 80 f8 ff ff ff leaq -0x8(%rax),%rax + */ + + // movq %fs:0x0,%rax + if (memcmp(&code[0], "\x64\x48\x8b\x04\x25\x00\x00\x00\x00", 9) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[0], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "movq insn does not match: 0x%016" PRIx64 "\n", bytes); + return FAILURE; + } + + // leaq any(%rax),$rax + if (memcmp(&code[9], "\x48\x8d\x80", 3) != 0) { + uint64_t bytes; + memcpy(&bytes, &code[10], 8); + zend_accel_error(ACCEL_LOG_DEBUG, "leaq insn does not match: 0x%016" PRIx64 "\n", bytes); + return FAILURE; + } + + /* Extract immediate values */ + + uintptr_t offset = (uintptr_t)(int32_t)(((uint32_t)code[15] << 24) + | ((uint32_t)code[14] << 16) + | ((uint32_t)code[13] << 8) + | ((uint32_t)code[12])); + + if ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer == offset) { + *tcb_offset = offset; + zend_accel_error(ACCEL_LOG_DEBUG, "static tls at offset %" PRIxPTR " from thread pointer (inferred from code)\n", offset); + return SUCCESS; + } + + zend_accel_error(ACCEL_LOG_DEBUG, "static tls offset does not match: %" PRIxPTR " (expected %" PRIxPTR ")\n", + offset, ((uintptr_t)&_tsrm_ls_cache - (uintptr_t)thread_pointer)); + + return FAILURE; +#endif +} + +/* Used for testing */ +void *zend_jit_tsrm_ls_cache_address( + size_t tcb_offset, + size_t module_index, + size_t module_offset +) { +#ifndef USE_FALLBACK + char *thread_pointer; + __asm__ __volatile__( + "movq %%fs:0, %0\n" + : "=r" (thread_pointer) + ); + + if (tcb_offset) { + return thread_pointer + tcb_offset; + } + if (module_index != (size_t)-1 && module_offset != (size_t)-1) { + dtv_pointer_t *dtv = *(dtv_pointer_t**)((uintptr_t)thread_pointer + DTV_OFFSET); + return (void*)(((dtv_pointer_t*)((char*)dtv + module_index))->val + module_offset); + } +#endif + return NULL; +} diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index bdf8ce2b007f..8db1b17943c2 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -48,6 +46,7 @@ #ifdef ZTS int jit_globals_id; +size_t jit_globals_offset; #else zend_jit_globals jit_globals; #endif @@ -77,7 +76,7 @@ int zend_jit_profile_counter_rid = -1; int16_t zend_jit_hot_counters[ZEND_HOT_COUNTERS_COUNT]; const zend_op *zend_jit_halt_op = NULL; -static int zend_jit_vm_kind = 0; +const zend_op *zend_jit_interrupt_op = NULL; #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP static int zend_write_protect = 1; #endif @@ -90,19 +89,24 @@ static size_t dasm_size = 0; static zend_long jit_bisect_pos = 0; -static const void *zend_jit_runtime_jit_handler = NULL; -static const void *zend_jit_profile_jit_handler = NULL; -static const void *zend_jit_func_hot_counter_handler = NULL; -static const void *zend_jit_loop_hot_counter_handler = NULL; -static const void *zend_jit_func_trace_counter_handler = NULL; -static const void *zend_jit_ret_trace_counter_handler = NULL; -static const void *zend_jit_loop_trace_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_runtime_jit_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_profile_jit_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_func_hot_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_loop_hot_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_func_trace_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_ret_trace_counter_handler = NULL; +static zend_vm_opcode_handler_t zend_jit_loop_trace_counter_handler = NULL; -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS); +#if ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS); +#else +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS); +#endif static int zend_jit_trace_op_len(const zend_op *opline); static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline); -static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags); +static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags ZEND_FILE_LINE_DC); +#define zend_jit_trace_get_exit_point(to_opline, flags) _zend_jit_trace_get_exit_point(to_opline, flags ZEND_FILE_LINE_CC) static const void *zend_jit_trace_get_exit_addr(uint32_t n); static void zend_jit_trace_add_code(const void *start, uint32_t size); static zend_string *zend_jit_func_name(const zend_op_array *op_array); @@ -110,7 +114,7 @@ static zend_string *zend_jit_func_name(const zend_op_array *op_array); static bool zend_jit_needs_arg_dtor(const zend_function *func, uint32_t arg_num, zend_call_info *call_info); static bool zend_jit_supported_binary_op(uint8_t op, uint32_t op1_info, uint32_t op2_info); -static bool dominates(const zend_basic_block *blocks, int a, int b) { +static bool dominates(const zend_basic_block *blocks, uint32_t a, uint32_t b) { while (blocks[b].level > blocks[a].level) { b = blocks[b].idom; } @@ -133,9 +137,9 @@ static bool zend_ssa_is_last_use(const zend_op_array *op_array, const zend_ssa * if (ssa->cfg.blocks[ssa->cfg.map[use]].loop_header > 0 || (ssa->cfg.blocks[ssa->cfg.map[use]].flags & ZEND_BB_LOOP_HEADER)) { - int b = ssa->cfg.map[use]; + uint32_t b = ssa->cfg.map[use]; int prev_use = ssa->vars[var].use_chain; - int def_block; + uint32_t def_block; if (ssa->vars[var].definition >= 0) { def_block =ssa->cfg.map[ssa->vars[var].definition]; @@ -205,38 +209,38 @@ static int zend_jit_is_constant_cmp_long_long(const zend_op *opline, case ZEND_CASE: case ZEND_CASE_STRICT: if (op1_min == op1_max && op2_min == op2_max && op1_min == op2_min) { - *result = 1; + *result = true; return 1; } else if (op1_max < op2_min || op1_min > op2_max) { - *result = 0; + *result = false; return 1; } return 0; case ZEND_IS_NOT_EQUAL: case ZEND_IS_NOT_IDENTICAL: if (op1_min == op1_max && op2_min == op2_max && op1_min == op2_min) { - *result = 0; + *result = false; return 1; } else if (op1_max < op2_min || op1_min > op2_max) { - *result = 1; + *result = true; return 1; } return 0; case ZEND_IS_SMALLER: if (op1_max < op2_min) { - *result = 1; + *result = true; return 1; } else if (op1_min >= op2_max) { - *result = 0; + *result = false; return 1; } return 0; case ZEND_IS_SMALLER_OR_EQUAL: if (op1_max <= op2_min) { - *result = 1; + *result = true; return 1; } else if (op1_min > op2_max) { - *result = 0; + *result = false; return 1; } return 0; @@ -875,13 +879,13 @@ static zend_string *zend_jit_func_name(const zend_op_array *op_array) if (op_array->function_name) { smart_str_appends(&buf, JIT_PREFIX); if (op_array->scope) { - smart_str_appendl(&buf, ZSTR_VAL(op_array->scope->name), ZSTR_LEN(op_array->scope->name)); + smart_str_append(&buf, op_array->scope->name); smart_str_appends(&buf, "::"); } - smart_str_appendl(&buf, ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)); + smart_str_append(&buf, op_array->function_name); if (op_array->fn_flags & ZEND_ACC_CLOSURE) { smart_str_appends(&buf, ":"); - smart_str_appendl(&buf, ZSTR_VAL(op_array->filename), ZSTR_LEN(op_array->filename)); + smart_str_append(&buf, op_array->filename); smart_str_appends(&buf, ":"); smart_str_append_long(&buf, op_array->line_start); } @@ -889,7 +893,7 @@ static zend_string *zend_jit_func_name(const zend_op_array *op_array) return buf.s; } else if (op_array->filename) { smart_str_appends(&buf, JIT_PREFIX); - smart_str_appendl(&buf, ZSTR_VAL(op_array->filename), ZSTR_LEN(op_array->filename)); + smart_str_append(&buf, op_array->filename); smart_str_0(&buf); return buf.s; } else { @@ -1168,7 +1172,7 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * for (i = 0; i < ssa->vars_count; i++) { if (ssa->vars[i].definition_phi && !ssa->vars[i].no_val) { zend_ssa_phi *phi = ssa->vars[i].definition_phi; - int k, src; + int src; if (phi->pi >= 0) { src = phi->sources[0]; @@ -1183,6 +1187,7 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * } } else { int need_move = 0; + uint32_t k; for (k = 0; k < ssa->cfg.blocks[phi->block].predecessors_count; k++) { src = phi->sources[k]; @@ -1233,13 +1238,13 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * ((ra[i].flags & ZREG_LOAD) || ((ra[i].flags & ZREG_STORE) && ssa->vars[i].definition >= 0)) && ssa->vars[i].use_chain < 0) { - bool may_remove = 1; + bool may_remove = true; zend_ssa_phi *phi = ssa->vars[i].phi_use_chain; while (phi) { if (ra[phi->ssa_var].ref && !(ra[phi->ssa_var].flags & ZREG_LOAD)) { - may_remove = 0; + may_remove = false; break; } phi = zend_ssa_next_use_phi(ssa, i, phi); @@ -1263,13 +1268,12 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * && ssa->vars[i].definition >= 0 && ssa->ops[op_num].result_def == i) { const zend_live_range *range = op_array->live_range; - int j; op_num++; if (op_array->opcodes[op_num].opcode == ZEND_OP_DATA) { op_num++; } - for (j = 0; j < op_array->last_live_range; range++, j++) { + for (uint32_t j = 0; j < op_array->last_live_range; range++, j++) { if (range->start > op_num) { /* further blocks will not be relevant... */ break; @@ -1294,13 +1298,13 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * && (ra[i].flags & ZREG_STORE) && (ssa->vars[i].use_chain < 0 || zend_ssa_next_use(ssa->ops, i, ssa->vars[i].use_chain) < 0)) { - bool may_remove = 1; + bool may_remove = true; zend_ssa_phi *phi = ssa->vars[i].phi_use_chain; while (phi) { if (ra[phi->ssa_var].ref && !(ra[phi->ssa_var].flags & ZREG_LOAD)) { - may_remove = 0; + may_remove = false; break; } phi = zend_ssa_next_use_phi(ssa, i, phi); @@ -1338,7 +1342,7 @@ static void zend_jit_allocate_registers(zend_jit_ctx *ctx, const zend_op_array * static int zend_jit_compute_post_order(zend_cfg *cfg, int start, int *post_order) { int count = 0; - int b, n, *p; + int b, *p; zend_basic_block *bb; zend_worklist worklist; ALLOCA_FLAG(use_heap) @@ -1350,7 +1354,7 @@ static int zend_jit_compute_post_order(zend_cfg *cfg, int start, int *post_order next: b = zend_worklist_peek(&worklist); bb = &cfg->blocks[b]; - n = bb->successors_count; + uint32_t n = bb->successors_count; if (n > 0) { p = bb->successors; do { @@ -1406,7 +1410,7 @@ static bool zend_jit_supported_binary_op(uint8_t op, uint32_t op1_info, uint32_t return (op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG); case ZEND_CONCAT: return (op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -1417,10 +1421,10 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op zend_jit_ctx ctx; zend_jit_ctx *jit = &ctx; zend_jit_reg_var *ra = NULL; - void *handler; + zend_vm_opcode_handler_t handler; int call_level = 0; void *checkpoint = NULL; - bool recv_emitted = 0; /* emitted at least one RECV opcode */ + bool recv_emitted = false; /* emitted at least one RECV opcode */ uint8_t smart_branch_opcode; uint32_t target_label, target_label2; uint32_t op1_info, op1_def_info, op2_info, res_info, res_use_info, op1_mem_info; @@ -1485,7 +1489,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op zend_jit_recv_entry(&ctx, b); } } - recv_emitted = 1; + recv_emitted = true; } else if (opline->opcode == ZEND_RECV) { if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) { /* skip */ @@ -1495,7 +1499,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } else if (recv_emitted) { zend_jit_recv_entry(&ctx, b); } else { - recv_emitted = 1; + recv_emitted = true; } } else { if (recv_emitted) { @@ -1878,8 +1882,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op break; } ce = NULL; - ce_is_instanceof = 0; - on_this = 0; + ce_is_instanceof = false; + on_this = false; if (opline->op1_type == IS_UNUSED) { op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; ce = op_array->scope; @@ -1888,7 +1892,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op ce_is_instanceof = !(ce->ce_flags & ZEND_ACC_FINAL); } op1_addr = 0; - on_this = 1; + on_this = true; } else { op1_info = OP1_INFO(); if (!(op1_info & MAY_BE_OBJECT)) { @@ -1929,8 +1933,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op break; } ce = NULL; - ce_is_instanceof = 0; - on_this = 0; + ce_is_instanceof = false; + on_this = false; if (opline->op1_type == IS_UNUSED) { op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; ce = op_array->scope; @@ -1939,7 +1943,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op ce_is_instanceof = !(ce->ce_flags & ZEND_ACC_FINAL); } op1_addr = 0; - on_this = 1; + on_this = true; } else { op1_info = OP1_INFO(); if (!(op1_info & MAY_BE_OBJECT)) { @@ -1973,8 +1977,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op break; } ce = NULL; - ce_is_instanceof = 0; - on_this = 0; + ce_is_instanceof = false; + on_this = false; if (opline->op1_type == IS_UNUSED) { op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; ce = op_array->scope; @@ -1983,7 +1987,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op ce_is_instanceof = !(ce->ce_flags & ZEND_ACC_FINAL); } op1_addr = 0; - on_this = 1; + on_this = true; } else { op1_info = OP1_INFO(); if (!(op1_info & MAY_BE_OBJECT)) { @@ -2445,8 +2449,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op case ZEND_FETCH_OBJ_IS: case ZEND_FETCH_OBJ_W: ce = NULL; - ce_is_instanceof = 0; - on_this = 0; + ce_is_instanceof = false; + on_this = false; if (opline->op1_type == IS_UNUSED) { op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; op1_addr = 0; @@ -2455,7 +2459,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if (ce) { ce_is_instanceof = !(ce->ce_flags & ZEND_ACC_FINAL); } - on_this = 1; + on_this = true; } else { op1_info = OP1_INFO(); if (!(op1_info & MAY_BE_OBJECT)) { @@ -2625,8 +2629,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op break; } ce = NULL; - ce_is_instanceof = 0; - on_this = 0; + ce_is_instanceof = false; + on_this = false; if (opline->op1_type == IS_UNUSED) { op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; op1_addr = 0; @@ -2635,7 +2639,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if (ce) { ce_is_instanceof = !(ce->ce_flags & ZEND_ACC_FINAL); } - on_this = 1; + on_this = true; } else { op1_info = OP1_INFO(); if (!(op1_info & MAY_BE_OBJECT)) { @@ -2886,7 +2890,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if (i == end && (opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) { /* smart branch split across basic blocks */ - if (!zend_jit_set_cond(&ctx, opline + 2, opline->result.var)) { + if (!zend_jit_set_cond(&ctx, opline, opline + 2, opline->result.var)) { goto jit_failure; } } @@ -2902,13 +2906,13 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if (jit->return_inputs) { zend_jit_common_return(jit); - bool left_frame = 0; + bool left_frame = false; if (op_array->last_var > 100) { /* To many CVs to unroll */ if (!zend_jit_free_cvs(&ctx)) { goto jit_failure; } - left_frame = 1; + left_frame = true; } if (!left_frame) { int j; @@ -2918,7 +2922,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { if (!left_frame) { - left_frame = 1; + left_frame = true; if (!zend_jit_leave_frame(&ctx)) { goto jit_failure; } @@ -2929,6 +2933,18 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } } } + /* Same teardown gap as in the tracing path: the inline CV loop + * skips zend_free_compiled_variables, so a generic-call frame's + * EX(type_args) needs an explicit destroy here. */ + if (!left_frame) { + if (!zend_jit_leave_frame(&ctx)) { + goto jit_failure; + } + left_frame = true; + } + if (!zend_jit_free_type_args(&ctx)) { + goto jit_failure; + } if (!zend_jit_leave_func(&ctx, op_array, NULL, MAY_BE_ANY, left_frame, NULL, NULL, (ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0, 1)) { goto jit_failure; @@ -3074,7 +3090,11 @@ static int zend_real_jit_func(zend_op_array *op_array, zend_script *script, cons } /* Run-time JIT handler */ -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS) +#if ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS) +#else +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS) +#endif { #if GCC_GLOBAL_REGS zend_execute_data *execute_data; @@ -3090,8 +3110,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLE bool do_bailout = 0; zend_shared_alloc_lock(); + jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); - if (ZEND_FUNC_INFO(op_array)) { + if (jit_extension && !(jit_extension->func_info.flags & ZEND_FUNC_JITED)) { SHM_UNPROTECT(); zend_jit_unprotect(); @@ -3103,11 +3124,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLE opline++; } } - jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); ((zend_op*)opline)->handler = jit_extension->orig_handler; /* perform real JIT for this function */ zend_real_jit_func(op_array, NULL, NULL, ZEND_JIT_ON_FIRST_EXEC); + + jit_extension->func_info.flags |= ZEND_FUNC_JITED; } zend_catch { do_bailout = true; } zend_end_try(); @@ -3126,7 +3148,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLE #if GCC_GLOBAL_REGS return; // ZEND_VM_CONTINUE #else - return orig_opline; // ZEND_VM_CONTINUE + opline = orig_opline; + ZEND_OPCODE_RETURN(); #endif } @@ -3173,7 +3196,7 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend zend_shared_alloc_lock(); jit_extension = (zend_jit_op_array_hot_extension*)ZEND_FUNC_INFO(op_array); - if (jit_extension) { + if (jit_extension && !(jit_extension->func_info.flags & ZEND_FUNC_JITED)) { SHM_UNPROTECT(); zend_jit_unprotect(); @@ -3186,6 +3209,8 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend /* perform real JIT for this function */ zend_real_jit_func(op_array, NULL, opline, ZEND_JIT_ON_HOT_COUNTERS); + + jit_extension->func_info.flags |= ZEND_FUNC_JITED; } zend_catch { do_bailout = 1; } zend_end_try(); @@ -3213,7 +3238,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf } } - opline->handler = (const void*)zend_jit_func_hot_counter_handler; + opline->handler = zend_jit_func_hot_counter_handler; } if (JIT_G(hot_loop)) { @@ -3223,7 +3248,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf if ((cfg->blocks[i].flags & ZEND_BB_REACHABLE) && (cfg->blocks[i].flags & ZEND_BB_LOOP_HEADER)) { op_array->opcodes[cfg->blocks[i].start].handler = - (const void*)zend_jit_loop_hot_counter_handler; + zend_jit_loop_hot_counter_handler; } } } @@ -3314,9 +3339,9 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script) memset(&jit_extension->func_info, 0, sizeof(zend_func_info)); jit_extension->func_info.flags = ZEND_FUNC_JIT_ON_FIRST_EXEC; jit_extension->op_array = op_array; - jit_extension->orig_handler = (void*)opline->handler; + jit_extension->orig_handler = opline->handler; ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension); - opline->handler = (const void*)zend_jit_runtime_jit_handler; + opline->handler = zend_jit_runtime_jit_handler; zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension); return SUCCESS; @@ -3344,9 +3369,9 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script) memset(&jit_extension->func_info, 0, sizeof(zend_func_info)); jit_extension->func_info.flags = ZEND_FUNC_JIT_ON_PROF_REQUEST; jit_extension->op_array = op_array; - jit_extension->orig_handler = (void*)opline->handler; + jit_extension->orig_handler = opline->handler; ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension); - opline->handler = (const void*)zend_jit_profile_jit_handler; + opline->handler = zend_jit_profile_jit_handler; zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension); } @@ -3363,6 +3388,17 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script) return FAILURE; } +static void zend_jit_link_func_info(zend_op_array *op_array) +{ + if (!ZEND_FUNC_INFO(op_array)) { + void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + + if (jit_extension) { + ZEND_SET_FUNC_INFO(op_array, jit_extension); + } + } +} + int zend_jit_script(zend_script *script) { void *checkpoint; @@ -3450,6 +3486,7 @@ int zend_jit_script(zend_script *script) zend_class_entry *ce; zend_op_array *op_array; zval *zv; + zend_property_info *prop; ZEND_HASH_MAP_FOREACH_VAL(&script->class_table, zv) { if (Z_TYPE_P(zv) == IS_ALIAS_PTR) { @@ -3460,14 +3497,21 @@ int zend_jit_script(zend_script *script) ZEND_ASSERT(ce->type == ZEND_USER_CLASS); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (!ZEND_FUNC_INFO(op_array)) { - void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + zend_jit_link_func_info(op_array); + } ZEND_HASH_FOREACH_END(); - if (jit_extension) { - ZEND_SET_FUNC_INFO(op_array, jit_extension); + if (ce->num_hooked_props > 0) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + if (prop->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + op_array = &prop->hooks[i]->op_array; + zend_jit_link_func_info(op_array); + } + } } - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } } ZEND_HASH_FOREACH_END(); } @@ -3547,23 +3591,23 @@ void zend_jit_protect(void) static void zend_jit_init_handlers(void) { - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { - zend_jit_runtime_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit]; - zend_jit_profile_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_profile_jit]; - zend_jit_func_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter]; - zend_jit_loop_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter]; - zend_jit_func_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter]; - zend_jit_ret_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter]; - zend_jit_loop_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter]; - } else { - zend_jit_runtime_jit_handler = (const void*)zend_runtime_jit; - zend_jit_profile_jit_handler = (const void*)zend_jit_profile_helper; - zend_jit_func_hot_counter_handler = (const void*)zend_jit_func_counter_helper; - zend_jit_loop_hot_counter_handler = (const void*)zend_jit_loop_counter_helper; - zend_jit_func_trace_counter_handler = (const void*)zend_jit_func_trace_helper; - zend_jit_ret_trace_counter_handler = (const void*)zend_jit_ret_trace_helper; - zend_jit_loop_trace_counter_handler = (const void*)zend_jit_loop_trace_helper; - } +#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID + zend_jit_runtime_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit]; + zend_jit_profile_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_profile_jit]; + zend_jit_func_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter]; + zend_jit_loop_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter]; + zend_jit_func_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter]; + zend_jit_ret_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter]; + zend_jit_loop_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter]; +#else + zend_jit_runtime_jit_handler = zend_runtime_jit; + zend_jit_profile_jit_handler = zend_jit_profile_helper; + zend_jit_func_hot_counter_handler = zend_jit_func_counter_helper; + zend_jit_loop_hot_counter_handler = zend_jit_loop_counter_helper; + zend_jit_func_trace_counter_handler = zend_jit_func_trace_helper; + zend_jit_ret_trace_counter_handler = zend_jit_ret_trace_helper; + zend_jit_loop_trace_counter_handler = zend_jit_loop_trace_helper; +#endif } static void zend_jit_globals_ctor(zend_jit_globals *jit_globals) @@ -3682,25 +3726,20 @@ int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage) void zend_jit_init(void) { #ifdef ZTS - jit_globals_id = ts_allocate_id(&jit_globals_id, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); + jit_globals_id = ts_allocate_fast_id(&jit_globals_id, &jit_globals_offset, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); #else zend_jit_globals_ctor(&jit_globals); #endif } +#if ZEND_VM_KIND != ZEND_VM_KIND_CALL && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL && ZEND_VM_KIND != ZEND_VM_KIND_HYBRID +# error JIT is compatible only with CALL and HYBRID VM +#endif + int zend_jit_check_support(void) { int i; - zend_jit_vm_kind = zend_vm_kind(); - if (zend_jit_vm_kind != ZEND_VM_KIND_CALL && - zend_jit_vm_kind != ZEND_VM_KIND_HYBRID) { - zend_error(E_WARNING, "JIT is compatible only with CALL and HYBRID VM. JIT disabled."); - JIT_G(enabled) = 0; - JIT_G(on) = 0; - return FAILURE; - } - if (zend_execute_ex != execute_ex) { if (zend_dtrace_enabled) { zend_error(E_WARNING, "JIT is incompatible with DTrace. JIT disabled."); @@ -3750,6 +3789,7 @@ int zend_jit_check_support(void) void zend_jit_startup(void *buf, size_t size, bool reattached) { zend_jit_halt_op = zend_get_halt_op(); + zend_jit_interrupt_op = zend_get_interrupt_op(); zend_jit_profile_counter_rid = zend_get_op_array_extension_handle(ACCELERATOR_PRODUCT_NAME); #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP @@ -3845,6 +3885,14 @@ void zend_jit_shutdown(void) #else zend_jit_trace_free_caches(&jit_globals); #endif + + /* Reset global pointers to prevent use-after-free in `zend_jit_status()` + * after gracefully restarting Apache with mod_php, see: + * https://github.com/php/php-src/pull/19212 */ + dasm_ptr = NULL; + dasm_buf = NULL; + dasm_end = NULL; + dasm_size = 0; } static void zend_jit_reset_counters(void) @@ -3885,12 +3933,12 @@ void zend_jit_deactivate(void) SHM_UNPROTECT(); zend_jit_unprotect(); - zend_jit_check_funcs(EG(function_table), 0); + zend_jit_check_funcs(EG(function_table), false); ZEND_HASH_MAP_REVERSE_FOREACH_PTR(EG(class_table), ce) { if (ce->type == ZEND_INTERNAL_CLASS) { break; } - zend_jit_check_funcs(&ce->function_table, 1); + zend_jit_check_funcs(&ce->function_table, true); } ZEND_HASH_FOREACH_END(); zend_jit_protect(); @@ -3901,8 +3949,10 @@ void zend_jit_deactivate(void) zend_jit_profile_counter = 0; } -static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array) +static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array, void *context) { + ZEND_IGNORE_VALUE(context); + zend_func_info *func_info = ZEND_FUNC_INFO(op_array); if (!func_info) { @@ -3926,37 +3976,17 @@ static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array) } } if (func_info->flags & ZEND_FUNC_JIT_ON_FIRST_EXEC) { - opline->handler = (const void*)zend_jit_runtime_jit_handler; + opline->handler = zend_jit_runtime_jit_handler; } else { - opline->handler = (const void*)zend_jit_profile_jit_handler; + opline->handler = zend_jit_profile_jit_handler; } #endif } - if (op_array->num_dynamic_func_defs) { - for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { - zend_jit_restart_preloaded_op_array(op_array->dynamic_func_defs[i]); - } - } } static void zend_jit_restart_preloaded_script(zend_persistent_script *script) { - zend_class_entry *ce; - zend_op_array *op_array; - - zend_jit_restart_preloaded_op_array(&script->script.main_op_array); - - ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) { - zend_jit_restart_preloaded_op_array(op_array); - } ZEND_HASH_FOREACH_END(); - - ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) { - ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION) { - zend_jit_restart_preloaded_op_array(op_array); - } - } ZEND_HASH_FOREACH_END(); - } ZEND_HASH_FOREACH_END(); + zend_foreach_op_array(&script->script, zend_jit_restart_preloaded_op_array, NULL); } void zend_jit_restart(void) diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 9178d340a0ed..2671ddd23e2d 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -64,15 +62,16 @@ #define ZEND_JIT_DEBUG_SIZE (1<<9) #define ZEND_JIT_DEBUG_ASM_ADDR (1<<10) -#define ZEND_JIT_DEBUG_TRACE_START (1<<12) -#define ZEND_JIT_DEBUG_TRACE_STOP (1<<13) -#define ZEND_JIT_DEBUG_TRACE_COMPILED (1<<14) -#define ZEND_JIT_DEBUG_TRACE_EXIT (1<<15) -#define ZEND_JIT_DEBUG_TRACE_ABORT (1<<16) -#define ZEND_JIT_DEBUG_TRACE_BLACKLIST (1<<17) -#define ZEND_JIT_DEBUG_TRACE_BYTECODE (1<<18) -#define ZEND_JIT_DEBUG_TRACE_TSSA (1<<19) -#define ZEND_JIT_DEBUG_TRACE_EXIT_INFO (1<<20) +#define ZEND_JIT_DEBUG_TRACE_START (1<<12) +#define ZEND_JIT_DEBUG_TRACE_STOP (1<<13) +#define ZEND_JIT_DEBUG_TRACE_COMPILED (1<<14) +#define ZEND_JIT_DEBUG_TRACE_EXIT (1<<15) +#define ZEND_JIT_DEBUG_TRACE_ABORT (1<<16) +#define ZEND_JIT_DEBUG_TRACE_BLACKLIST (1<<17) +#define ZEND_JIT_DEBUG_TRACE_BYTECODE (1<<18) +#define ZEND_JIT_DEBUG_TRACE_TSSA (1<<19) +#define ZEND_JIT_DEBUG_TRACE_EXIT_INFO (1<<20) +#define ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC (1<<21) #define ZEND_JIT_DEBUG_IR_SRC (1<<24) #define ZEND_JIT_DEBUG_IR_FINAL (1<<25) @@ -145,8 +144,9 @@ typedef struct _zend_jit_globals { } zend_jit_globals; #ifdef ZTS -# define JIT_G(v) ZEND_TSRMG(jit_globals_id, zend_jit_globals *, v) +# define JIT_G(v) ZEND_TSRMG_FAST(jit_globals_offset, zend_jit_globals *, v) extern int jit_globals_id; +extern size_t jit_globals_offset; #else # define JIT_G(v) (jit_globals.v) extern zend_jit_globals jit_globals; diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index b20afffa47df..64a48068f378 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2,20 +2,20 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ */ +#include "Zend/zend_portability.h" +#include "Zend/zend_types.h" #include "Zend/zend_API.h" static ZEND_COLD void undef_result_after_exception(void) { @@ -500,36 +500,42 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim, } ZEND_FALLTHROUGH; case IS_NULL: - offset_key = ZSTR_EMPTY_ALLOC(); - goto str_index; + retval = zend_hash_find(ht, ZSTR_EMPTY_ALLOC()); + if (!retval) { + ZVAL_NULL(result); + } else { + ZVAL_COPY_DEREF(result, retval); + } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (!retval) { + zend_error(E_WARNING, "Undefined array key \"\""); + } + return; case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(dim)); - if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { - /* The array may be destroyed while throwing the notice. - * Temporarily increase the refcount to detect this situation. */ - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - execute_data = EG(current_execute_data); - opline = EX(opline); - zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } else { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - return; - } - if (EG(exception)) { - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); + hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); } - return; } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; } goto num_index; case IS_RESOURCE: @@ -642,36 +648,41 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim } ZEND_FALLTHROUGH; case IS_NULL: - offset_key = ZSTR_EMPTY_ALLOC(); - goto str_index; + retval = zend_hash_find(ht, ZSTR_EMPTY_ALLOC()); + if (!retval) { + ZVAL_NULL(result); + } else { + ZVAL_COPY_DEREF(result, retval); + } + + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + + return; case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(dim)); - if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { - /* The array may be destroyed while throwing the notice. - * Temporarily increase the refcount to detect this situation. */ - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - execute_data = EG(current_execute_data); - opline = EX(opline); - zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } else { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - return; - } - if (EG(exception)) { - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); + hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); } - return; } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; } goto num_index; case IS_RESOURCE: @@ -769,25 +780,30 @@ static int ZEND_FASTCALL zend_jit_fetch_dim_isset_helper(zend_array *ht, zval *d return 0; } ZEND_FALLTHROUGH; - case IS_NULL: - offset_key = ZSTR_EMPTY_ALLOC(); - goto str_index; + case IS_NULL: { + int result = 0; + retval = zend_hash_find(ht, ZSTR_EMPTY_ALLOC()); + if (retval) { + result = Z_TYPE_P(retval) > IS_NULL; + } + + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + + return result; + } case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(dim)); - if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { - /* The array may be destroyed while throwing the notice. - * Temporarily increase the refcount to detect this situation. */ - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - return 0; - } - if (EG(exception)) { - return 0; - } + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return 0; + } + if (EG(exception)) { + return 0; } goto num_index; case IS_RESOURCE: @@ -878,38 +894,61 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di } ZEND_FALLTHROUGH; case IS_NULL: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + + execute_data = EG(current_execute_data); + opline = EX(opline); + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return NULL; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return NULL; + } offset_key = ZSTR_EMPTY_ALLOC(); goto str_index; case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(dim)); - if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { - /* The array may be destroyed while throwing the notice. - * Temporarily increase the refcount to detect this situation. */ - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - execute_data = EG(current_execute_data); - opline = EX(opline); - zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { - if (!GC_REFCOUNT(ht)) { - zend_array_destroy(ht); - } - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } else { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - return NULL; + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); + hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); } - if (EG(exception)) { - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); } - return NULL; } + return NULL; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return NULL; } goto num_index; case IS_RESOURCE: @@ -1011,38 +1050,65 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim } ZEND_FALLTHROUGH; case IS_NULL: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + + execute_data = EG(current_execute_data); + opline = EX(opline); + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); + } + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + if (opline->opcode == ZEND_ASSIGN_DIM + && ((opline+1)->op1_type & (IS_VAR | IS_TMP_VAR))) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } + return NULL; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return NULL; + } offset_key = ZSTR_EMPTY_ALLOC(); goto str_index; case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(dim)); - if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { - /* The array may be destroyed while throwing the notice. - * Temporarily increase the refcount to detect this situation. */ - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - execute_data = EG(current_execute_data); - opline = EX(opline); - zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { - if (!GC_REFCOUNT(ht)) { - zend_array_destroy(ht); - } - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } else { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - return NULL; + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); + hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && GC_DELREF(ht) != 1) { + if (!GC_REFCOUNT(ht)) { + zend_array_destroy(ht); } - if (EG(exception)) { - if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); } - return NULL; } + return NULL; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return NULL; } goto num_index; case IS_RESOURCE: @@ -1129,10 +1195,13 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type) zend_illegal_container_offset(ZSTR_KNOWN(ZEND_STR_STRING), dim, BP_VAR_R); return 0; } + case IS_DOUBLE: + /* Suppress potential double warning */ + zend_error(E_WARNING, "String offset cast occurred"); + return zend_dval_to_lval_silent(Z_DVAL_P(dim)); case IS_UNDEF: zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); ZEND_FALLTHROUGH; - case IS_DOUBLE: case IS_NULL: case IS_FALSE: case IS_TRUE: @@ -1204,14 +1273,17 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_str_is_helper(zend_string *str, zva switch (Z_TYPE_P(dim)) { /* case IS_LONG: */ case IS_STRING: - if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, false)) { - break; + if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, false)) { + goto out; } ZVAL_NULL(result); return; + case IS_DOUBLE: + offset = zend_dval_to_lval_silent(Z_DVAL_P(dim)); + goto out; case IS_UNDEF: zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); - case IS_DOUBLE: + ZEND_FALLTHROUGH; case IS_NULL: case IS_FALSE: case IS_TRUE: @@ -1232,6 +1304,7 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_str_is_helper(zend_string *str, zva offset = Z_LVAL_P(dim); } +out: if ((zend_ulong)offset >= (zend_ulong)ZSTR_LEN(str)) { if (offset < 0) { /* Handle negative offset */ @@ -1904,7 +1977,7 @@ static bool ZEND_FASTCALL zend_jit_verify_arg_slow(zval *arg, zend_arg_info *arg &arg_info->type, arg, /* ref */ NULL, /* is_return_type */ false); if (UNEXPECTED(!ret)) { zend_verify_arg_error(EX(func), arg_info, opline->op1.num, arg); - return 0; + return false; } return ret; } @@ -2045,8 +2118,13 @@ static zval* ZEND_FASTCALL zend_jit_fetch_obj_r_slow_ex(zend_object *zobj) void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS); retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, result); - if (retval == result && UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + if (UNEXPECTED(Z_ISREF_P(retval))) { + if (retval == result) { + zend_unwrap_reference(retval); + } else { + retval = Z_REFVAL_P(retval); + } + ZEND_ASSERT(!Z_REFCOUNTED_P(retval)); } return retval; } @@ -2205,7 +2283,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( } } break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } return 1; } @@ -2561,11 +2639,24 @@ static void ZEND_FASTCALL zend_jit_only_vars_by_reference(zval *arg) zend_error(E_NOTICE, "Only variables should be passed by reference"); } +static void ZEND_FASTCALL zend_jit_invalid_array_use(const zval *container) +{ + /* Warning should not occur on null */ + if (Z_TYPE_P(container) != IS_NULL) { + zend_error(E_WARNING, "Cannot use %s as array", zend_zval_type_name(container)); + } +} + static void ZEND_FASTCALL zend_jit_invalid_array_access(zval *container) { zend_error(E_WARNING, "Trying to access array offset on %s", zend_zval_value_name(container)); } +static void ZEND_FASTCALL zend_jit_nan_coerced_to_type_warning(void) +{ + zend_nan_coerced_to_type_warning(_IS_BOOL); +} + static void ZEND_FASTCALL zend_jit_invalid_property_read(zval *container, const char *property_name) { zend_error(E_WARNING, "Attempt to read property \"%s\" on %s", property_name, zend_zval_value_name(container)); @@ -2851,7 +2942,7 @@ static void ZEND_FASTCALL zend_jit_assign_obj_op_helper(zend_object *zobj, zend_ //??? } else { //??? prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); //??? } - if (prop_info) { + if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { /* special case for typed properties */ zend_jit_assign_op_to_typed_prop(zptr, prop_info, value, binary_op); } else { @@ -3047,6 +3138,9 @@ static void ZEND_FASTCALL zend_jit_pre_inc_obj_helper(zend_object *zobj, zend_st } } else { zend_property_info *prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + if (prop_info && !ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { fast_long_increment_function(prop); @@ -3117,6 +3211,9 @@ static void ZEND_FASTCALL zend_jit_pre_dec_obj_helper(zend_object *zobj, zend_st } } else { zend_property_info *prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + if (prop_info && !ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { fast_long_decrement_function(prop); @@ -3185,6 +3282,9 @@ static void ZEND_FASTCALL zend_jit_post_inc_obj_helper(zend_object *zobj, zend_s ZVAL_NULL(result); } else { zend_property_info *prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info && !ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { ZVAL_LONG(result, Z_LVAL_P(prop)); @@ -3246,6 +3346,9 @@ static void ZEND_FASTCALL zend_jit_post_dec_obj_helper(zend_object *zobj, zend_s ZVAL_NULL(result); } else { zend_property_info *prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info && !ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { ZVAL_LONG(result, Z_LVAL_P(prop)); diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 3623689f05aa..7b5f93f70db7 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -26,6 +24,7 @@ #include "Zend/zend_constants.h" #include "Zend/Optimizer/zend_func_info.h" #include "Zend/Optimizer/zend_call_graph.h" +#include "zend_vm_opcodes.h" /* Address Encoding */ typedef uintptr_t zend_jit_addr; @@ -118,19 +117,19 @@ typedef uintptr_t zend_jit_addr; static zend_always_inline bool zend_jit_same_addr(zend_jit_addr addr1, zend_jit_addr addr2) { if (addr1 == addr2) { - return 1; + return true; } else if (Z_MODE(addr1) == IS_REG && Z_MODE(addr2) == IS_REG) { return Z_SSA_VAR(addr1) == Z_SSA_VAR(addr2); } else if (Z_MODE(addr1) == IS_REF_ZVAL && Z_MODE(addr2) == IS_REF_ZVAL) { return Z_IR_REF(addr1) == Z_IR_REF(addr2); } - return 0; + return false; } typedef struct _zend_jit_op_array_extension { zend_func_info func_info; const zend_op_array *op_array; - const void *orig_handler; + zend_vm_opcode_handler_t orig_handler; } zend_jit_op_array_extension; /* Profiler */ @@ -169,13 +168,14 @@ typedef struct _zend_jit_op_array_hot_extension { zend_func_info func_info; const zend_op_array *op_array; int16_t *counter; - const void *orig_handlers[1]; + zend_vm_opcode_handler_t orig_handlers[1]; } zend_jit_op_array_hot_extension; #define zend_jit_op_array_hash(op_array) \ zend_jit_hash((op_array)->opcodes) extern const zend_op *zend_jit_halt_op; +extern const zend_op *zend_jit_interrupt_op; #ifdef HAVE_GCC_GLOBAL_REGS # define EXECUTE_DATA_D void @@ -196,10 +196,6 @@ extern const zend_op *zend_jit_halt_op; handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \ return; \ } while(0) -# define ZEND_OPCODE_TAIL_CALL_EX(handler, arg) do { \ - handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg); \ - return; \ - } while(0) # define ZEND_VM_ENTER_BIT 0 #else # define EXECUTE_DATA_D zend_execute_data* execute_data @@ -211,32 +207,38 @@ extern const zend_op *zend_jit_halt_op; # define OPLINE_DC , OPLINE_D # define OPLINE_CC , OPLINE_C # define ZEND_OPCODE_HANDLER_RET const zend_op * +# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +# define ZEND_OPCODE_TAIL_CALL(handler) do { \ + ZEND_MUSTTAIL return (handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \ + } while(0) +# define ZEND_OPCODE_RETURN() ZEND_OPCODE_TAIL_CALL((zend_vm_opcode_handler_t)opline->handler) +# else +# define ZEND_OPCODE_TAIL_CALL(handler) do { \ + return handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \ + } while(0) +# define ZEND_OPCODE_RETURN() return opline +# endif # define ZEND_OPCODE_HANDLER_ARGS EXECUTE_DATA_D OPLINE_DC # define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU EXECUTE_DATA_C OPLINE_CC # define ZEND_OPCODE_HANDLER_ARGS_EX EXECUTE_DATA_D OPLINE_DC, # define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX EXECUTE_DATA_C OPLINE_CC, -# define ZEND_OPCODE_RETURN() return opline -# define ZEND_OPCODE_TAIL_CALL(handler) do { \ - return handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \ - } while(0) -# define ZEND_OPCODE_TAIL_CALL_EX(handler, arg) do { \ - return handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg); \ - } while(0) # define ZEND_VM_ENTER_BIT 1ULL #endif -/* VM handlers */ -typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *zend_vm_opcode_handler_t)(ZEND_OPCODE_HANDLER_ARGS); - /* VM helpers */ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info); ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_top_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info); ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_func_helper(ZEND_OPCODE_HANDLER_ARGS); +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_leave_func_helper_tailcall(ZEND_OPCODE_HANDLER_ARGS); +#endif -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS); +#if ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS); -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_counter_helper(ZEND_OPCODE_HANDLER_ARGS); -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_HANDLER_ARGS); +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_func_counter_helper(ZEND_OPCODE_HANDLER_ARGS); +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_loop_counter_helper(ZEND_OPCODE_HANDLER_ARGS); +#endif ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_copy_extra_args_helper(ZEND_OPCODE_HANDLER_ARGS); ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_copy_extra_args_helper_no_skip_recv(ZEND_OPCODE_HANDLER_ARGS); @@ -339,8 +341,8 @@ typedef enum _zend_jit_trace_stop { typedef union _zend_op_trace_info { zend_op dummy; /* the size of this structure must be the same as zend_op */ struct { - const void *orig_handler; - const void *call_handler; + zend_vm_opcode_handler_t orig_handler; + zend_vm_opcode_handler_func_t call_handler; int16_t *counter; uint8_t trace_flags; }; @@ -453,6 +455,10 @@ typedef struct _zend_jit_trace_exit_info { uint32_t stack_offset; zend_jit_ref_snapshot poly_func; zend_jit_ref_snapshot poly_this; +#if ZEND_DEBUG + const char *filename; + int lineno; +#endif } zend_jit_trace_exit_info; typedef struct _zend_jit_trace_stack { @@ -668,9 +674,11 @@ struct _zend_jit_trace_stack_frame { (frame)->_info |= TRACE_FRAME_MASK_ALWAYS_RELEASE_THIS; \ } while (0) -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_trace_helper(ZEND_OPCODE_HANDLER_ARGS); -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_ret_trace_helper(ZEND_OPCODE_HANDLER_ARGS); -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS); +#if ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_func_trace_helper(ZEND_OPCODE_HANDLER_ARGS); +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_ret_trace_helper(ZEND_OPCODE_HANDLER_ARGS); +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS); +#endif int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const zend_op *opline); zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *execute_data, @@ -697,7 +705,7 @@ static zend_always_inline const zend_op* zend_jit_trace_get_exit_opline(zend_jit } else { ZEND_UNREACHABLE(); } - *exit_if_true = 0; + *exit_if_true = false; return NULL; } diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 6aa789655492..0e214a7350e3 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -1,23 +1,25 @@ /* - * +----------------------------------------------------------------------+ - * | Zend JIT | - * +----------------------------------------------------------------------+ - * | Copyright (c) The PHP Group | - * +----------------------------------------------------------------------+ - * | This source file is subject to version 3.01 of the PHP license, | - * | that is bundled with this package in the file LICENSE, and is | - * | available through the world-wide-web at the following url: | - * | https://www.php.net/license/3_01.txt | - * | If you did not receive a copy of the PHP license and are unable to | - * | obtain it through the world-wide-web, please send a note to | - * | license@php.net so we can mail you a copy immediately. | - * +----------------------------------------------------------------------+ - * | Authors: Dmitry Stogov | - * +----------------------------------------------------------------------+ - */ + +----------------------------------------------------------------------+ + | Zend JIT | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov | + +----------------------------------------------------------------------+ +*/ +#include "Zend/zend_cpuinfo.h" +#include "Zend/zend_types.h" +#include "Zend/zend_type_info.h" #include "jit/ir/ir.h" #include "jit/ir/ir_builder.h" +#include "jit/tls/zend_jit_tls.h" #if defined(IR_TARGET_X86) # define IR_REG_SP 4 /* IR_REG_RSP */ @@ -26,11 +28,21 @@ # define ZREG_IP 7 /* IR_REG_RDI */ # define ZREG_FIRST_FPR 8 # define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7)) /* all preserved registers */ +# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +# error +# endif #elif defined(IR_TARGET_X64) # define IR_REG_SP 4 /* IR_REG_RSP */ # define IR_REG_FP 5 /* IR_REG_RBP */ -# define ZREG_FP 14 /* IR_REG_R14 */ -# define ZREG_IP 15 /* IR_REG_R15 */ +# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +/* Use the first two arg registers of the preserve_none calling convention for FP/IP + * https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/X86/X86CallingConv.td#L1029 */ +# define ZREG_FP 12 /* IR_REG_R12 */ +# define ZREG_IP 13 /* IR_REG_R13 */ +# else +# define ZREG_FP 14 /* IR_REG_R14 */ +# define ZREG_IP 15 /* IR_REG_R15 */ +# endif # define ZREG_FIRST_FPR 16 # if defined(_WIN64) # define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7) | (1<<12) | (1<<13) | (1<<14) | (1<<15)) @@ -45,9 +57,17 @@ # endif #elif defined(IR_TARGET_AARCH64) # define IR_REG_SP 31 /* IR_REG_RSP */ +# define IR_REG_LR 30 /* IR_REG_X30 */ # define IR_REG_FP 29 /* IR_REG_X29 */ -# define ZREG_FP 27 /* IR_REG_X27 */ -# define ZREG_IP 28 /* IR_REG_X28 */ +# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +/* Use the first two arg registers of the preserve_none calling convention for FP/IP + * https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/AArch64/AArch64CallingConvention.td#L541 */ +# define ZREG_FP 20 /* IR_REG_X20 */ +# define ZREG_IP 21 /* IR_REG_X21 */ +# else +# define ZREG_FP 27 /* IR_REG_X27 */ +# define ZREG_IP 28 /* IR_REG_X28 */ +# endif # define ZREG_FIRST_FPR 32 # define IR_REGSET_PRESERVED ((1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23) | \ (1<<24) | (1<<25) | (1<<26) | (1<<27) | (1<<28)) /* all preserved registers */ @@ -63,12 +83,22 @@ #undef _ir_CTX #define _ir_CTX (&jit->ctx) +#if GCC_GLOBAL_REGS +# define IR_OPCODE_HANDLER_RET IR_VOID +#else +# define IR_OPCODE_HANDLER_RET IR_ADDR +#endif + #undef ir_CONST_ADDR #define ir_CONST_ADDR(_addr) jit_CONST_ADDR(jit, (uintptr_t)(_addr)) #define ir_CONST_FUNC(_addr) jit_CONST_FUNC(jit, (uintptr_t)(_addr), 0) #define ir_CONST_FC_FUNC(_addr) jit_CONST_FUNC(jit, (uintptr_t)(_addr), IR_FASTCALL_FUNC) #define ir_CAST_FC_FUNC(_addr) ir_fold2(_ir_CTX, IR_OPT(IR_PROTO, IR_ADDR), (_addr), \ ir_proto_0(_ir_CTX, IR_FASTCALL_FUNC, IR_I32)) +# define ir_CONST_OPCODE_HANDLER_FUNC(_addr) \ + jit_CONST_OPCODE_HANDLER_FUNC(jit, _addr) +# define ir_CAST_OPCODE_HANDLER_FUNC(_addr) ir_fold2(_ir_CTX, IR_OPT(IR_PROTO, IR_ADDR), (_addr), \ + ir_proto_0(_ir_CTX, IR_FASTCALL_FUNC, IR_OPCODE_HANDLER_RET)) #define ir_CONST_FUNC_PROTO(_addr, _proto) \ jit_CONST_FUNC_PROTO(jit, (uintptr_t)(_addr), (_proto)) @@ -168,18 +198,12 @@ static size_t zend_jit_trace_prologue_size = (size_t)-1; static uint32_t allowed_opt_flags = 0; static uint32_t default_mflags = 0; #endif -static bool delayed_call_chain = 0; // TODO: remove this var (use jit->delayed_call_level) ??? +static bool delayed_call_chain = false; // TODO: remove this var (use jit->delayed_call_level) ??? #ifdef ZTS -# ifdef _WIN32 -extern uint32_t _tls_index; -extern char *_tls_start; -extern char *_tls_end; -# endif - static size_t tsrm_ls_cache_tcb_offset = 0; -static size_t tsrm_tls_index = 0; -static size_t tsrm_tls_offset = 0; +static size_t tsrm_tls_index = -1; +static size_t tsrm_tls_offset = -1; # define EG_TLS_OFFSET(field) \ (executor_globals_offset + offsetof(zend_executor_globals, field)) @@ -334,6 +358,8 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit, zend_jit_addr ref_addr, bool check_exception); +static ir_ref jit_CONST_FUNC(zend_jit_ctx *jit, uintptr_t addr, uint16_t flags); + typedef struct _zend_jit_stub { const char *name; int (*stub)(zend_jit_ctx *jit); @@ -397,7 +423,7 @@ static bool zend_jit_set_veneer(ir_ctx *ctx, const void *addr, const void *venee uint32_t exit_point = zend_jit_exit_point_by_addr(addr); if (exit_point != (uint32_t)-1) { - return 1; + return true; } for (i = 0; i < count; i++) { if (zend_jit_stub_handlers[i] == addr) { @@ -422,11 +448,11 @@ static bool zend_jit_set_veneer(ir_ctx *ctx, const void *addr, const void *venee } } #endif - return 1; + return true; } } - return 0; + return false; } static void zend_jit_commit_veneers(void) @@ -445,7 +471,7 @@ static void zend_jit_commit_veneers(void) static bool zend_jit_prefer_const_addr_load(zend_jit_ctx *jit, uintptr_t addr) { #if defined(IR_TARGET_X86) - return 0; /* always use immediate value */ + return false; /* always use immediate value */ #elif defined(IR_TARGET_X64) return addr > 0xffffffff; /* prefer loading long constant from memery */ #elif defined(IR_TARGET_AARCH64) @@ -463,6 +489,11 @@ static const char* zend_reg_name(int8_t reg) /* IR helpers */ #ifdef ZTS +static void * ZEND_FASTCALL zend_jit_get_tsrm_ls_cache(void) +{ + return _tsrm_ls_cache; +} + static ir_ref jit_TLS(zend_jit_ctx *jit) { ZEND_ASSERT(jit->ctx.control); @@ -482,9 +513,15 @@ static ir_ref jit_TLS(zend_jit_ctx *jit) ref = insn->op1; } } - jit->tls = ir_TLS( - tsrm_ls_cache_tcb_offset ? tsrm_ls_cache_tcb_offset : tsrm_tls_index, - tsrm_ls_cache_tcb_offset ? IR_NULL : tsrm_tls_offset); + + if (tsrm_ls_cache_tcb_offset == 0 && tsrm_tls_index == -1) { + jit->tls = ir_CALL(IR_ADDR, ir_CONST_FC_FUNC(zend_jit_get_tsrm_ls_cache)); + } else { + jit->tls = ir_TLS( + tsrm_ls_cache_tcb_offset ? tsrm_ls_cache_tcb_offset : tsrm_tls_index, + tsrm_ls_cache_tcb_offset ? IR_NULL : tsrm_tls_offset); + } + return jit->tls; } #endif @@ -541,6 +578,11 @@ static ir_ref jit_CONST_FUNC(zend_jit_ctx *jit, uintptr_t addr, uint16_t flags) return jit_CONST_FUNC_PROTO(jit, addr, proto); } +static ir_ref jit_CONST_OPCODE_HANDLER_FUNC(zend_jit_ctx *jit, zend_vm_opcode_handler_t handler) +{ + return jit_CONST_FUNC(jit, (uintptr_t)handler, IR_FASTCALL_FUNC); +} + static ir_ref jit_ADD_OFFSET(zend_jit_ctx *jit, ir_ref addr, uintptr_t offset) { if (offset) { @@ -831,6 +873,7 @@ void *zend_jit_snapshot_handler(ir_ctx *ctx, ir_ref snapshot_ref, ir_insn *snaps addr = (void*)zend_jit_trace_get_exit_addr(exit_point); exit_flags &= ~ZEND_JIT_EXIT_FIXED; } + t->stack_map[t->exit_info[exit_point].stack_offset + var].reg = ZREG_NONE; t->stack_map[t->exit_info[exit_point].stack_offset + var].flags = ZREG_TYPE_ONLY; } } else if (!(exit_flags & ZEND_JIT_EXIT_FIXED)) { @@ -946,15 +989,15 @@ static void jit_LOAD_IP_ADDR(zend_jit_ctx *jit, const zend_op *target) static void zend_jit_track_last_valid_opline(zend_jit_ctx *jit) { - jit->use_last_valid_opline = 0; - jit->track_last_valid_opline = 1; + jit->use_last_valid_opline = false; + jit->track_last_valid_opline = true; } static void zend_jit_use_last_valid_opline(zend_jit_ctx *jit) { if (jit->track_last_valid_opline) { - jit->use_last_valid_opline = 1; - jit->track_last_valid_opline = 0; + jit->use_last_valid_opline = true; + jit->track_last_valid_opline = false; } } @@ -966,21 +1009,21 @@ static bool zend_jit_trace_uses_initial_ip(zend_jit_ctx *jit) static void zend_jit_set_last_valid_opline(zend_jit_ctx *jit, const zend_op *opline) { if (!jit->reuse_ip) { - jit->track_last_valid_opline = 1; + jit->track_last_valid_opline = true; jit->last_valid_opline = opline; } } static void zend_jit_reset_last_valid_opline(zend_jit_ctx *jit) { - jit->track_last_valid_opline = 0; + jit->track_last_valid_opline = false; jit->last_valid_opline = NULL; } static void zend_jit_start_reuse_ip(zend_jit_ctx *jit) { zend_jit_reset_last_valid_opline(jit); - jit->reuse_ip = 1; + jit->reuse_ip = true; } static int zend_jit_reuse_ip(zend_jit_ctx *jit) @@ -995,7 +1038,7 @@ static int zend_jit_reuse_ip(zend_jit_ctx *jit) static void zend_jit_stop_reuse_ip(zend_jit_ctx *jit) { - jit->reuse_ip = 0; + jit->reuse_ip = false; } static int zend_jit_save_call_chain(zend_jit_ctx *jit, uint32_t call_level) @@ -1019,7 +1062,7 @@ static int zend_jit_save_call_chain(zend_jit_ctx *jit, uint32_t call_level) ir_STORE(jit_EX(call), rx); jit->delayed_call_level = 0; - delayed_call_chain = 0; + delayed_call_chain = false; return 1; } @@ -1048,7 +1091,7 @@ static int zend_jit_set_ip(zend_jit_ctx *jit, const zend_op *target) } else { jit_STORE_IP(jit, ir_CONST_ADDR(target)); } - jit->reuse_ip = 0; + jit->reuse_ip = false; zend_jit_set_last_valid_opline(jit, target); return 1; } @@ -1266,7 +1309,7 @@ static bool zend_jit_spilling_may_cause_conflict(zend_jit_ctx *jit, int var, ir_ { if (jit->ctx.ir_base[val].op == IR_RLOAD) { /* Deoptimization */ - return 0; + return false; } // if (jit->ctx.ir_base[val].op == IR_LOAD // && jit->ctx.ir_base[jit->ctx.ir_base[val].op2].op == IR_ADD @@ -1288,7 +1331,7 @@ static bool zend_jit_spilling_may_cause_conflict(zend_jit_ctx *jit, int var, ir_ && jit->ctx.ir_base[jit->ctx.ir_base[jit->ctx.ir_base[val].op2].op2].val.addr != (uintptr_t)EX_NUM_TO_VAR(jit->ssa->vars[var].var) && EX_VAR_TO_NUM(jit->ctx.ir_base[jit->ctx.ir_base[jit->ctx.ir_base[val].op2].op2].val.addr) < jit->current_op_array->last_var) { /* binding between different CVs may cause spill conflict */ - return 1; + return true; } else if (jit->ssa->vars[var].definition >= 0 && jit->ssa->ops[jit->ssa->vars[var].definition].op1_def == var && jit->ssa->ops[jit->ssa->vars[var].definition].op1_use >= 0 @@ -1296,18 +1339,18 @@ static bool zend_jit_spilling_may_cause_conflict(zend_jit_ctx *jit, int var, ir_ && jit->ssa->vars[jit->ssa->ops[jit->ssa->vars[var].definition].op1_use].definition_phi && (jit->ssa->cfg.blocks[jit->ssa->vars[jit->ssa->ops[jit->ssa->vars[var].definition].op1_use].definition_phi->block].flags & ZEND_BB_LOOP_HEADER)) { /* Avoid moving spill store out of loop */ - return 1; + return true; } else if (jit->ssa->vars[var].definition >= 0 && jit->ssa->ops[jit->ssa->vars[var].definition].op1_def == var && jit->ssa->ops[jit->ssa->vars[var].definition].op1_use >= 0 && jit->ssa->ops[jit->ssa->vars[var].definition].op2_use >= 0 && jit->ra[jit->ssa->ops[jit->ssa->vars[var].definition].op2_use].ref == val) { /* Avoid spill conflict between of ASSIGN.op1_def and ASSIGN.op1_use */ - return 1; + return true; } - return 0; + return false; } - return 1; + return true; } static void zend_jit_def_reg(zend_jit_ctx *jit, zend_jit_addr addr, ir_ref val) @@ -1435,14 +1478,13 @@ static void zend_jit_gen_phi(zend_jit_ctx *jit, zend_ssa_phi *phi) { int dst_var = phi->ssa_var; zend_basic_block *bb = &jit->ssa->cfg.blocks[phi->block]; - int n = bb->predecessors_count; - int i; + uint32_t n = bb->predecessors_count; ir_type type = (jit->ssa->var_info[phi->ssa_var].type & MAY_BE_LONG) ? IR_LONG : IR_DOUBLE; ir_ref merge = jit->bb_start_ref[phi->block]; ir_ref ref; ir_ref old_insns_count = jit->ctx.insns_count; ir_ref same_src_ref = IR_UNUSED; - bool phi_inputs_are_the_same = 1; + bool phi_inputs_are_the_same = true; ZEND_ASSERT(phi->pi < 0); ZEND_ASSERT(!(jit->ra[dst_var].flags & ZREG_LOAD)); @@ -1453,19 +1495,19 @@ static void zend_jit_gen_phi(zend_jit_ctx *jit, zend_ssa_phi *phi) ref = ir_emit_N(&jit->ctx, IR_OPT(IR_PHI, type), n + 1); ir_set_op(&jit->ctx, ref, 1, merge); - for (i = 0; i < n; i++) { + for (uint32_t i = 0; i < n; i++) { int src_var = phi->sources[i]; ZEND_ASSERT(jit->ra[src_var].ref); if (jit->ra[src_var].ref == IR_NULL) { jit->ra[src_var].flags |= ZREG_FORWARD; - phi_inputs_are_the_same = 0; + phi_inputs_are_the_same = false; } else { ir_ref src_ref = zend_jit_use_reg(jit, ZEND_ADDR_REG(src_var)); if (i == 0) { same_src_ref = src_ref; } else if (same_src_ref != src_ref) { - phi_inputs_are_the_same = 0; + phi_inputs_are_the_same = false; } ir_set_op(&jit->ctx, ref, i + 2, src_ref); } @@ -1854,7 +1896,7 @@ static void jit_FREE_OP(zend_jit_ctx *jit, if (op_type & (IS_VAR|IS_TMP_VAR)) { jit_ZVAL_PTR_DTOR(jit, ZEND_ADDR_MEM_ZVAL(ZREG_FP, op.var), - op_info, 0, opline); + op_info, false, opline); } } @@ -1914,24 +1956,36 @@ static void zend_jit_vm_leave(zend_jit_ctx *jit, ir_ref to_opline) ir_RETURN(ir_OR_A(to_opline, ir_CONST_ADDR(ZEND_VM_ENTER_BIT))); } +static void zend_jit_tailcall_handler(zend_jit_ctx *jit, ir_ref handler) +{ +#if defined(IR_TARGET_X86) + if (!IR_IS_CONST_REF(handler)) { + handler = ir_CAST_OPCODE_HANDLER_FUNC(handler); + } +#endif + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + ir_TAILCALL(IR_OPCODE_HANDLER_RET, handler); + } else { + ir_TAILCALL_2(IR_ADDR, handler, jit_FP(jit), jit_IP(jit)); + } +} + /* stubs */ static int zend_jit_exception_handler_stub(zend_jit_ctx *jit) { - const void *handler; - - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { - handler = zend_get_opcode_handler_func(EG(exception_op)); + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { + zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(EG(exception_op)); ir_CALL(IR_VOID, ir_CONST_FUNC(handler)); ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); } else { - handler = EG(exception_op)->handler; + zend_vm_opcode_handler_t handler = EG(exception_op)->handler; - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler)); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, ir_CONST_OPCODE_HANDLER_FUNC(handler)); } else { - ir_ref ref = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit)); + ir_ref ref = ir_CALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC(handler), jit_FP(jit), jit_IP(jit)); zend_jit_vm_enter(jit, ref); } } @@ -1975,7 +2029,7 @@ static int zend_jit_exception_handler_free_op1_op2_stub(zend_jit_ctx *jit) } ref = ir_ADD_A(jit_FP(jit), ref); var_addr = ZEND_ADDR_REF_ZVAL(ref); - jit_ZVAL_PTR_DTOR(jit, var_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, NULL); + jit_ZVAL_PTR_DTOR(jit, var_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, false, NULL); ir_MERGE_WITH_EMPTY_FALSE(if_dtor); ir_IJMP(jit_STUB_ADDR(jit, jit_stub_exception_handler_free_op2)); @@ -1998,7 +2052,7 @@ static int zend_jit_exception_handler_free_op2_stub(zend_jit_ctx *jit) } ref = ir_ADD_A(jit_FP(jit), ref); var_addr = ZEND_ADDR_REF_ZVAL(ref); - jit_ZVAL_PTR_DTOR(jit, var_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, NULL); + jit_ZVAL_PTR_DTOR(jit, var_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, false, NULL); ir_MERGE_WITH_EMPTY_FALSE(if_dtor); ir_IJMP(jit_STUB_ADDR(jit, jit_stub_exception_handler_undef)); @@ -2030,8 +2084,8 @@ static int zend_jit_interrupt_handler_stub(zend_jit_ctx *jit) jit_STORE_IP(jit, ir_LOAD_A(jit_EX(opline))); } - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, ir_LOAD_A(jit_IP(jit))); } else { zend_jit_vm_enter(jit, jit_IP(jit)); } @@ -2040,12 +2094,16 @@ static int zend_jit_interrupt_handler_stub(zend_jit_ctx *jit) static int zend_jit_leave_function_handler_stub(zend_jit_ctx *jit) { +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + ir_TAILCALL(IR_OPCODE_HANDLER_RET, ir_CONST_OPCODE_HANDLER_FUNC(zend_jit_leave_func_helper_tailcall)); + return 1; +#else ir_ref call_info = ir_LOAD_U32(jit_EX(This.u1.type_info)); ir_ref if_top = ir_IF(ir_AND_U32(call_info, ir_CONST_U32(ZEND_CALL_TOP))); ir_IF_FALSE(if_top); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_leave_nested_func_helper), call_info); jit_STORE_IP(jit, ir_LOAD_A(jit_EX(opline))); @@ -2058,7 +2116,7 @@ static int zend_jit_leave_function_handler_stub(zend_jit_ctx *jit) ir_IF_TRUE(if_top); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_leave_top_func_helper), call_info); ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); } else if (GCC_GLOBAL_REGS) { @@ -2068,6 +2126,7 @@ static int zend_jit_leave_function_handler_stub(zend_jit_ctx *jit) } return 1; +#endif /* ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL */ } static int zend_jit_negative_shift_stub(zend_jit_ctx *jit) @@ -2176,7 +2235,7 @@ static int zend_jit_throw_cannot_pass_by_ref_stub(zend_jit_ctx *jit) ref = ir_ADD_A(jit_FP(jit), ref); jit_ZVAL_PTR_DTOR(jit, ZEND_ADDR_REF_ZVAL(ref), - MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, 0, NULL); + MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF, false, NULL); ir_MERGE_WITH_EMPTY_FALSE(if_tmp); ir_IJMP(jit_STUB_ADDR(jit, jit_stub_exception_handler)); @@ -2228,7 +2287,7 @@ static int zend_jit_leave_throw_stub(zend_jit_ctx *jit) // JIT: opline = EG(exception_op); jit_STORE_IP(jit, jit_EG(exception_op)); - if (GCC_GLOBAL_REGS) { + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { ir_STORE(jit_EX(opline), jit_IP(jit)); // JIT: HANDLE_EXCEPTION() @@ -2242,11 +2301,11 @@ static int zend_jit_leave_throw_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_runtime_jit_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) { return 0; } - ir_CALL(IR_VOID, ir_CONST_FC_FUNC(zend_runtime_jit)); + ir_CALL(IR_VOID, ir_CONST_OPCODE_HANDLER_FUNC(zend_runtime_jit)); ir_IJMP(ir_LOAD_A(jit_IP(jit))); return 1; } @@ -2255,7 +2314,7 @@ static int zend_jit_hybrid_profile_jit_stub(zend_jit_ctx *jit) { ir_ref addr, func, run_time_cache, jit_extension; - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) { return 0; } @@ -2311,7 +2370,7 @@ static int _zend_jit_hybrid_hot_counter_stub(zend_jit_ctx *jit, uint32_t cost) static int zend_jit_hybrid_func_hot_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { return 0; } @@ -2321,7 +2380,7 @@ static int zend_jit_hybrid_func_hot_counter_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_loop_hot_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { return 0; } @@ -2376,14 +2435,14 @@ static int _zend_jit_hybrid_trace_counter_stub(zend_jit_ctx *jit, uint32_t cost) ir_IJMP(_zend_jit_orig_opline_handler(jit, offset)); ir_IF_TRUE(if_halt); - ir_IJMP(ir_CONST_FC_FUNC(zend_jit_halt_op->handler)); + ir_IJMP(ir_CONST_OPCODE_HANDLER_FUNC(zend_jit_halt_op->handler)); return 1; } static int zend_jit_hybrid_func_trace_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_func)) { return 0; } @@ -2393,7 +2452,7 @@ static int zend_jit_hybrid_func_trace_counter_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_ret_trace_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_return)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_return)) { return 0; } @@ -2403,7 +2462,7 @@ static int zend_jit_hybrid_ret_trace_counter_stub(zend_jit_ctx *jit) static int zend_jit_hybrid_loop_trace_counter_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { + if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID || !JIT_G(hot_loop)) { return 0; } @@ -2413,8 +2472,8 @@ static int zend_jit_hybrid_loop_trace_counter_stub(zend_jit_ctx *jit) static int zend_jit_trace_halt_stub(zend_jit_ctx *jit) { - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { - ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_halt_op->handler)); + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { + ir_TAILCALL(IR_VOID, ir_CONST_OPCODE_HANDLER_FUNC(zend_jit_halt_op->handler)); } else if (GCC_GLOBAL_REGS) { jit_STORE_IP(jit, IR_NULL); ir_RETURN(IR_VOID); @@ -2426,8 +2485,8 @@ static int zend_jit_trace_halt_stub(zend_jit_ctx *jit) static int zend_jit_trace_escape_stub(zend_jit_ctx *jit) { - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, ir_LOAD_A(jit_IP(jit))); } else { zend_jit_vm_enter(jit, jit_IP(jit)); } @@ -2453,8 +2512,8 @@ static int zend_jit_trace_exit_stub(zend_jit_ctx *jit) ref = ir_LOAD_A(jit_EX(opline)); jit_STORE_IP(jit, ref); - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, ir_LOAD_A(jit_IP(jit))); } else { zend_jit_vm_enter(jit, ref); } @@ -2473,11 +2532,11 @@ static int zend_jit_trace_exit_stub(zend_jit_ctx *jit) zend_jit_check_timeout(jit, NULL, NULL); addr = zend_jit_orig_opline_handler(jit); - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, addr); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, addr); } else { #if defined(IR_TARGET_X86) - addr = ir_CAST_FC_FUNC(addr); + addr = ir_CAST_OPCODE_HANDLER_FUNC(addr); #endif ref = ir_CALL_2(IR_ADDR, addr, jit_FP(jit), jit_IP(jit)); zend_jit_vm_enter(jit, ref); @@ -2491,7 +2550,7 @@ static int zend_jit_undefined_offset_stub(zend_jit_ctx *jit) if (GCC_GLOBAL_REGS) { ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key)); } else { - ir_TAILCALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key), jit_FP(jit), jit_IP(jit)); + ir_TAILCALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key), jit_FP(jit)); } return 1; @@ -2502,7 +2561,7 @@ static int zend_jit_undefined_key_stub(zend_jit_ctx *jit) if (GCC_GLOBAL_REGS) { ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_string_key)); } else { - ir_TAILCALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_string_key), jit_FP(jit), jit_IP(jit)); + ir_TAILCALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_string_key), jit_FP(jit)); } return 1; @@ -2548,7 +2607,7 @@ static int zend_jit_assign_const_stub(zend_jit_ctx *jit) jit, NULL, var_addr, var_addr, -1, -1, IS_CONST, val_addr, val_info, - 0, 0, 0)) { + 0, 0, false)) { return 0; } ir_RETURN(IR_VOID); @@ -2568,7 +2627,7 @@ static int zend_jit_assign_tmp_stub(zend_jit_ctx *jit) jit, NULL, var_addr, var_addr, -1, -1, IS_TMP_VAR, val_addr, val_info, - 0, 0, 0)) { + 0, 0, false)) { return 0; } ir_RETURN(IR_VOID); @@ -2588,7 +2647,7 @@ static int zend_jit_assign_var_stub(zend_jit_ctx *jit) jit, NULL, var_addr, var_addr, -1, -1, IS_VAR, val_addr, val_info, - 0, 0, 0)) { + 0, 0, false)) { return 0; } ir_RETURN(IR_VOID); @@ -2608,7 +2667,7 @@ static int zend_jit_assign_cv_noref_stub(zend_jit_ctx *jit) jit, NULL, var_addr, var_addr, -1, -1, IS_CV, val_addr, val_info, - 0, 0, 0)) { + 0, 0, false)) { return 0; } ir_RETURN(IR_VOID); @@ -2640,7 +2699,7 @@ static int zend_jit_assign_cv_stub(zend_jit_ctx *jit) jit, NULL, var_addr, var_addr, -1, -1, IS_CV, val_addr, val_info, - 0, 0, 0)) { + 0, 0, false)) { return 0; } ir_RETURN(IR_VOID); @@ -2670,11 +2729,21 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags) jit->ctx.fixed_regset = (1<ctx.flags |= IR_NO_STACK_COMBINE; - if (zend_jit_vm_kind == ZEND_VM_KIND_CALL) { + if (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { jit->ctx.flags |= IR_FUNCTION; /* Stack must be 16 byte aligned */ /* TODO: select stack size ??? */ -#if defined(IR_TARGET_AARCH64) +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +# if defined(IR_TARGET_AARCH64) + /* Must save LR */ + jit->ctx.flags |= IR_USE_FRAME_POINTER; + /* Same as HYBRID VM */ + jit->ctx.fixed_stack_frame_size = sizeof(void*) * 4; /* 4 spill slots */ +# else + /* Same as HYBRID VM, plus 1 slot for re-alignment (caller pushes return address, frame is not aligned on entry) */ + jit->ctx.fixed_stack_frame_size = sizeof(void*) * 5; /* 5 spill slots (8 bytes) or 10 spill slots (4 bytes) */ +# endif +#elif defined(IR_TARGET_AARCH64) jit->ctx.flags |= IR_USE_FRAME_POINTER; jit->ctx.fixed_stack_frame_size = sizeof(void*) * 16; /* 10 saved registers and 6 spill slots (8 bytes) */ #elif defined(_WIN64) @@ -2690,6 +2759,23 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags) */ if (GCC_GLOBAL_REGS) { jit->ctx.fixed_save_regset = IR_REGSET_PRESERVED & ~((1<ctx.fixed_regset |= (1<ctx.fixed_regset |= (1<ctx.fixed_save_regset = IR_REGSET_PRESERVED; //#ifdef _WIN64 @@ -2727,11 +2813,11 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags) jit->ssa = NULL; jit->name = NULL; jit->last_valid_opline = NULL; - jit->use_last_valid_opline = 0; - jit->track_last_valid_opline = 0; - jit->reuse_ip = 0; + jit->use_last_valid_opline = false; + jit->track_last_valid_opline = false; + jit->reuse_ip = false; jit->delayed_call_level = 0; - delayed_call_chain = 0; + delayed_call_chain = false; jit->b = -1; #ifdef ZTS jit->tls = IR_UNUSED; @@ -3127,6 +3213,8 @@ static void zend_jit_setup_disasm(void) REGISTER_DATA(EG(symbol_table)); REGISTER_DATA(CG(map_ptr_base)); +#else /* ZTS */ + REGISTER_HELPER(zend_jit_get_tsrm_ls_cache); #endif #endif } @@ -3138,13 +3226,15 @@ static void zend_jit_calc_trace_prologue_size(void) void *entry; size_t size; - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) ? 0 : IR_START_BR_TARGET); if (!GCC_GLOBAL_REGS) { - ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1); - ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2); - jit_STORE_FP(jit, execute_data_ref); - jit_STORE_IP(jit, opline_ref); + if (ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) { + ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1); + ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2); + jit_STORE_FP(jit, execute_data_ref); + jit_STORE_IP(jit, opline_ref); + } jit->ctx.flags |= IR_FASTCALL_FUNC; } @@ -3224,6 +3314,27 @@ static PRUNTIME_FUNCTION zend_jit_unwind_callback(DWORD64 pc, PVOID context) static void zend_jit_setup_unwinder(void) { +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + /* TAILCALL VM: fixed_save_regset=0, no registers pushed in prologue. + * fixed_stack_frame_size=40, fixed_call_stack_size=48 (16+IR_SHADOW_ARGS). + * Prologue is: sub rsp, 0x58 (88 bytes = 40+48). */ + static const unsigned char uw_data[] = { + 0x01, // Version=1, Flags=0 + 0x04, // Size of prolog (sub rsp,imm8 = 4 bytes: 48 83 ec 58) + 0x01, // Count of unwind codes + 0x00, // Frame Register=none + 0x04, 0xa2, // offset 4: UWOP_ALLOC_SMALL info=10, alloc=(10+1)*8=88 + 0x00, 0x00, // padding + }; + /* Exit call variant: base 88 + 304 (shadow+GP+FP+padding) = 392 (0x188) */ + static const unsigned char uw_data_exitcall[] = { + 0x01, // Version=1, Flags=0 + 0x07, // Size of prolog (sub rsp,imm32 = 7 bytes: 48 81 ec 88 01 00 00) + 0x02, // Count of unwind codes + 0x00, // Frame Register=none + 0x07, 0x01, 0x31, 0x00, // offset 7: UWOP_ALLOC_LARGE info=0, size/8=49, alloc=392 + }; +#else /* Hardcoded SEH unwind data for JIT-ed PHP functions with "fixed stack frame" */ static const unsigned char uw_data[] = { 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags @@ -3258,6 +3369,7 @@ static void zend_jit_setup_unwinder(void) 0x02, 0x50, // 1: pushq %rbp 0x01, 0x30, // 0: pushq %rbx }; +#endif zend_jit_uw_func = (PRUNTIME_FUNCTION)*dasm_ptr; *dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) * 4 + @@ -3293,7 +3405,6 @@ static void zend_jit_setup_unwinder(void) } #endif - static void zend_jit_setup(bool reattached) { #if defined(IR_TARGET_X86) @@ -3306,176 +3417,27 @@ static void zend_jit_setup(bool reattached) if (zend_cpu_supports_avx()) { allowed_opt_flags |= ZEND_JIT_CPU_AVX; } -# if defined(PHP_HAVE_BUILTIN_CPU_SUPPORTS) && defined(__GNUC__) && (ZEND_GCC_VERSION >= 11000) +# ifdef HAVE_ZEND_CPU_SUPPORTS_CLDEMOTE if (zend_cpu_supports_cldemote()) { default_mflags |= IR_X86_CLDEMOTE; } # endif #endif -#ifdef ZTS -#if defined(IR_TARGET_AARCH64) - tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); - -# ifdef __FreeBSD__ - if (tsrm_ls_cache_tcb_offset == 0) { - TLSDescriptor **where; - - __asm__( - "adrp %0, :tlsdesc:_tsrm_ls_cache\n" - "add %0, %0, :tlsdesc_lo12:_tsrm_ls_cache\n" - : "=r" (where)); - /* See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst - * section "Relocations for thread-local storage". - * The first entry holds a pointer to the variable's TLS descriptor resolver function and the second entry holds - * a platform-specific offset or pointer. */ - TLSDescriptor *tlsdesc = where[1]; - - tsrm_tls_offset = tlsdesc->offset; - /* Index is offset by 1 on FreeBSD (https://github.com/freebsd/freebsd-src/blob/22ca6db50f4e6bd75a141f57cf953d8de6531a06/lib/libc/gen/tls.c#L88) */ - tsrm_tls_index = (tlsdesc->index + 1) * 8; - } -# elif defined(__MUSL__) - if (tsrm_ls_cache_tcb_offset == 0) { - size_t **where; - - __asm__( - "adrp %0, :tlsdesc:_tsrm_ls_cache\n" - "add %0, %0, :tlsdesc_lo12:_tsrm_ls_cache\n" - : "=r" (where)); - /* See https://github.com/ARM-software/abi-aa/blob/2a70c42d62e9c3eb5887fa50b71257f20daca6f9/aaelf64/aaelf64.rst */ - size_t *tlsdesc = where[1]; - - tsrm_tls_offset = tlsdesc[1]; - tsrm_tls_index = tlsdesc[0] * 8; - } -# else - ZEND_ASSERT(tsrm_ls_cache_tcb_offset != 0); -# endif -# elif defined(_WIN64) - tsrm_tls_index = _tls_index * sizeof(void*); - - /* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */ - /* Probably, it might be better solution */ - do { - void ***tls_mem = ((void****)__readgsqword(0x58))[_tls_index]; - void *val = _tsrm_ls_cache; - size_t offset = 0; - size_t size = (char*)&_tls_end - (char*)&_tls_start; - - while (offset < size) { - if (*tls_mem == val) { - tsrm_tls_offset = offset; - break; - } - tls_mem++; - offset += sizeof(void*); - } - if (offset >= size) { - zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: offset >= size"); - } - } while(0); -# elif defined(ZEND_WIN32) - tsrm_tls_index = _tls_index * sizeof(void*); - - /* To find offset of "_tsrm_ls_cache" in TLS segment we perform a linear scan of local TLS memory */ - /* Probably, it might be better solution */ - do { - void ***tls_mem = ((void****)__readfsdword(0x2c))[_tls_index]; - void *val = _tsrm_ls_cache; - size_t offset = 0; - size_t size = (char*)&_tls_end - (char*)&_tls_start; - - while (offset < size) { - if (*tls_mem == val) { - tsrm_tls_offset = offset; - break; - } - tls_mem++; - offset += sizeof(void*); - } - if (offset >= size) { - zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: offset >= size"); - } - } while(0); -# elif defined(__APPLE__) && defined(__x86_64__) - tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); - if (tsrm_ls_cache_tcb_offset == 0) { - size_t *ti; - __asm__( - "leaq __tsrm_ls_cache(%%rip),%0" - : "=r" (ti)); - tsrm_tls_offset = ti[2]; - tsrm_tls_index = ti[1] * 8; - } -# elif defined(__GNUC__) && defined(__x86_64__) - tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); - if (tsrm_ls_cache_tcb_offset == 0) { -#if defined(__has_attribute) && __has_attribute(tls_model) && !defined(__FreeBSD__) && \ - !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) - size_t ret; - - asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0" - : "=r" (ret)); - tsrm_ls_cache_tcb_offset = ret; -#elif defined(__MUSL__) - size_t *ti; - - __asm__( - "leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n" - : "=D" (ti)); - tsrm_tls_offset = ti[1]; - tsrm_tls_index = ti[0] * 8; -#elif defined(__FreeBSD__) - size_t *ti; - - __asm__( - "leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n" - : "=D" (ti)); - tsrm_tls_offset = ti[1]; - /* Index is offset by 1 on FreeBSD (https://github.com/freebsd/freebsd-src/blob/bf56e8b9c8639ac4447d223b83cdc128107cc3cd/libexec/rtld-elf/rtld.c#L5260) */ - tsrm_tls_index = (ti[0] + 1) * 8; -#else - size_t *ti; - - __asm__( - "leaq _tsrm_ls_cache@tlsgd(%%rip), %0\n" - : "=D" (ti)); - tsrm_tls_offset = ti[1]; - tsrm_tls_index = ti[0] * 16; -#endif - } -# elif defined(__GNUC__) && defined(__i386__) - tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset(); - if (tsrm_ls_cache_tcb_offset == 0) { -#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) - size_t ret; - asm ("leal _tsrm_ls_cache@ntpoff,%0\n" - : "=a" (ret)); - tsrm_ls_cache_tcb_offset = ret; -#else - size_t *ti, _ebx, _ecx, _edx; - - __asm__( - "call 1f\n" - ".subsection 1\n" - "1:\tmovl (%%esp), %%ebx\n\t" - "ret\n" - ".previous\n\t" - "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" - "leal _tsrm_ls_cache@tlsldm(%%ebx), %0\n\t" - "call ___tls_get_addr@plt\n\t" - "leal _tsrm_ls_cache@tlsldm(%%ebx), %0\n" - : "=a" (ti), "=&b" (_ebx), "=&c" (_ecx), "=&d" (_edx)); - tsrm_tls_offset = ti[1]; - tsrm_tls_index = ti[0] * 8; -#endif +#ifdef ZTS + zend_result result = zend_jit_resolve_tsrm_ls_cache_offsets( + &tsrm_ls_cache_tcb_offset, + &tsrm_tls_index, + &tsrm_tls_offset + ); + if (result == FAILURE) { + zend_accel_error(ACCEL_LOG_INFO, + "Could not get _tsrm_ls_cache offsets, will fallback to runtime resolution"); } -# endif #endif #if !defined(ZEND_WIN32) && !defined(IR_TARGET_AARCH64) - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { zend_jit_set_sp_adj_vm(); // set zend_jit_hybrid_vm_sp_adj } #endif @@ -3556,7 +3518,7 @@ static void zend_jit_case_start(zend_jit_ctx *jit, int switch_b, int case_b, ir_ static void _zend_jit_add_predecessor_ref(zend_jit_ctx *jit, int b, int pred, ir_ref ref) { - int i, *p; + int *p; zend_basic_block *bb; ir_ref *r, header; @@ -3564,7 +3526,7 @@ static void _zend_jit_add_predecessor_ref(zend_jit_ctx *jit, int b, int pred, ir bb = &jit->ssa->cfg.blocks[b]; p = &jit->ssa->cfg.predecessors[bb->predecessor_offset]; r = &jit->bb_edges[jit->bb_predecessors[b]]; - for (i = 0; i < bb->predecessors_count; i++, p++, r++) { + for (uint32_t i = 0; i < bb->predecessors_count; i++, p++, r++) { if (*p == pred) { ZEND_ASSERT(*r == IR_UNUSED || *r == ref); header = jit->bb_start_ref[b]; @@ -3729,7 +3691,7 @@ static void zend_jit_case_start(zend_jit_ctx *jit, int switch_b, int case_b, ir_ int default_b = jit->ssa->cfg.map[default_opline - jit->op_array->opcodes]; zval *zv; ir_ref list = IR_UNUSED, idx; - bool first = 1; + bool first = true; ZEND_HASH_FOREACH_VAL(jumptable, zv) { const zend_op *target = ZEND_OFFSET_TO_OPLINE(opline, Z_LVAL_P(zv)); @@ -3745,7 +3707,7 @@ static void zend_jit_case_start(zend_jit_ctx *jit, int switch_b, int case_b, ir_ idx = ir_CONST_LONG((Bucket*)zv - jumptable->arData); } ir_CASE_VAL(switch_ref, idx); - first = 0; + first = false; } } ZEND_HASH_FOREACH_END(); if (default_b == case_b) { @@ -3779,14 +3741,14 @@ static void zend_jit_case_start(zend_jit_ctx *jit, int switch_b, int case_b, ir_ static int zend_jit_bb_start(zend_jit_ctx *jit, int b) { zend_basic_block *bb; - int i, n, *p, pred; + int *p, pred; ir_ref ref, bb_start; ZEND_ASSERT(JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE); ZEND_ASSERT(b < jit->ssa->cfg.blocks_count); bb = &jit->ssa->cfg.blocks[b]; ZEND_ASSERT((bb->flags & ZEND_BB_REACHABLE) != 0); - n = bb->predecessors_count; + uint32_t n = bb->predecessors_count; if (n == 0) { /* pass */ @@ -3856,6 +3818,7 @@ static int zend_jit_bb_start(zend_jit_ctx *jit, int b) entry_path = ir_END(); } pred_refs = (ir_ref *)do_alloca(sizeof(ir_ref) * n, use_heap); + uint32_t i; for (i = 0, p = jit->ssa->cfg.predecessors + bb->predecessor_offset; i < n; p++, i++) { pred = *p; if (jit->bb_start_ref[pred]) { @@ -4025,11 +3988,12 @@ static int zend_jit_cond_jmp(zend_jit_ctx *jit, const zend_op *next_opline, int return 1; } -static int zend_jit_set_cond(zend_jit_ctx *jit, const zend_op *next_opline, uint32_t var) +static int zend_jit_set_cond(zend_jit_ctx *jit, const zend_op *opline, const zend_op *next_opline, uint32_t var) { ir_ref ref; - ref = ir_ADD_U32(ir_ZEXT_U32(jit_CMP_IP(jit, IR_EQ, next_opline)), ir_CONST_U32(IS_FALSE)); + ir_op op = (opline->result_type & IS_SMART_BRANCH_JMPZ) ? IR_EQ : IR_NE; + ref = ir_ADD_U32(ir_ZEXT_U32(jit_CMP_IP(jit, op, next_opline)), ir_CONST_U32(IS_FALSE)); // EX_VAR(var) = ... ir_STORE(ir_ADD_OFFSET(jit_FP(jit), var + offsetof(zval, u1.type_info)), ref); @@ -4125,7 +4089,7 @@ static void zend_jit_recv_entry(zend_jit_ctx *jit, int b) /* Insert a MERGE block with additional ENTRY input between predecessor and this one */ ir_ENTRY(ref, bb->start); - if (!GCC_GLOBAL_REGS) { + if (!GCC_GLOBAL_REGS && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) { /* 2 and 3 are hardcoded reference to IR_PARAMs */ ZEND_ASSERT(jit->ctx.ir_base[2].op == IR_PARAM); ZEND_ASSERT(jit->ctx.ir_base[2].op3 == 1); @@ -4146,7 +4110,7 @@ static void zend_jit_osr_entry(zend_jit_ctx *jit, int b) /* Insert a MERGE block with additional ENTRY input between predecessor and this one */ ir_ENTRY(ref, bb->start); - if (!GCC_GLOBAL_REGS) { + if (!GCC_GLOBAL_REGS && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) { /* 2 and 3 are hardcoded reference to IR_PARAMs */ ZEND_ASSERT(jit->ctx.ir_base[2].op == IR_PARAM); ZEND_ASSERT(jit->ctx.ir_base[2].op3 == 1); @@ -4162,7 +4126,7 @@ static void zend_jit_osr_entry(zend_jit_ctx *jit, int b) static ir_ref zend_jit_continue_entry(zend_jit_ctx *jit, ir_ref src, unsigned int label) { ir_ENTRY(src, label); - if (!GCC_GLOBAL_REGS) { + if (!GCC_GLOBAL_REGS && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) { /* 2 and 3 are hardcoded reference to IR_PARAMs */ ZEND_ASSERT(jit->ctx.ir_base[2].op == IR_PARAM); ZEND_ASSERT(jit->ctx.ir_base[2].op3 == 1); @@ -4176,17 +4140,16 @@ static ir_ref zend_jit_continue_entry(zend_jit_ctx *jit, ir_ref src, unsigned in static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_throw) { - const void *handler; - zend_jit_set_ip(jit, opline); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { - handler = zend_get_opcode_handler_func(opline); - } else { - handler = opline->handler; - } if (GCC_GLOBAL_REGS) { + zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(opline); ir_CALL(IR_VOID, ir_CONST_FUNC(handler)); + } else if (ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(opline); + ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit)); + jit_STORE_IP(jit, ip); } else { + zend_vm_opcode_handler_t handler = opline->handler; ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit)); jit_STORE_IP(jit, ip); } @@ -4216,30 +4179,29 @@ static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_th static int zend_jit_tail_handler(zend_jit_ctx *jit, const zend_op *opline) { - const void *handler; ir_ref ref; zend_basic_block *bb; zend_jit_set_ip(jit, opline); - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { if (opline->opcode == ZEND_DO_UCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME || opline->opcode == ZEND_DO_FCALL || opline->opcode == ZEND_RETURN) { /* Use inlined HYBRID VM handler */ - handler = opline->handler; + zend_vm_opcode_handler_t handler = opline->handler; ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler)); } else { - handler = zend_get_opcode_handler_func(opline); + zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(opline); ir_CALL(IR_VOID, ir_CONST_FUNC(handler)); ref = ir_LOAD_A(jit_IP(jit)); ir_TAILCALL(IR_VOID, ref); } } else { - handler = opline->handler; - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler)); + zend_vm_opcode_handler_t handler = opline->handler; + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, ir_CONST_OPCODE_HANDLER_FUNC(handler)); } else if ((jit->ssa->cfg.flags & ZEND_FUNC_RECURSIVE_DIRECTLY) && (opline->opcode == ZEND_CATCH || opline->opcode == ZEND_FAST_CALL @@ -4247,10 +4209,10 @@ static int zend_jit_tail_handler(zend_jit_ctx *jit, const zend_op *opline) || opline->opcode == ZEND_MATCH_ERROR || opline->opcode == ZEND_THROW || opline->opcode == ZEND_VERIFY_NEVER_TYPE)) { - ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit)); + ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC(handler), jit_FP(jit), jit_IP(jit)); zend_jit_vm_enter(jit, ip); } else { - ir_TAILCALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit)); + ir_TAILCALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC(handler), jit_FP(jit), jit_IP(jit)); } } if (jit->b >= 0) { @@ -4325,6 +4287,11 @@ static int zend_jit_spill_store_inv(zend_jit_ctx *jit, zend_jit_addr src, zend_j ZEND_ASSERT(Z_MODE(src) == IS_REG); ZEND_ASSERT(Z_MODE(dst) == IS_MEM_ZVAL); + if (Z_LOAD(src) || Z_STORE(src)) { + /* it's not necessary to store register if it was previously loaded or already stored */ + return 1; + } + if ((info & MAY_BE_ANY) == MAY_BE_LONG) { jit_set_Z_LVAL(jit, dst, zend_jit_use_reg(jit, src)); if (Z_REG(dst) != ZREG_FP || !JIT_G(current_frame)) { @@ -4565,7 +4532,7 @@ static int zend_jit_store_var_if_necessary(zend_jit_ctx *jit, int var, zend_jit_ { if (Z_MODE(src) == IS_REG && Z_STORE(src)) { zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); - return zend_jit_spill_store(jit, src, dst, info, 1); + return zend_jit_spill_store(jit, src, dst, info, true); } return 1; } @@ -4574,7 +4541,7 @@ static int zend_jit_store_var_if_necessary_ex(zend_jit_ctx *jit, int var, zend_j { if (Z_MODE(src) == IS_REG && Z_STORE(src)) { zend_jit_addr dst = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); - bool set_type = 1; + bool set_type = true; if ((info & (MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF)) == (old_info & (MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF))) { @@ -4584,10 +4551,10 @@ static int zend_jit_store_var_if_necessary_ex(zend_jit_ctx *jit, int var, zend_j if (mem_type != IS_UNKNOWN && (info & (MAY_BE_ANY|MAY_BE_REF|MAY_BE_UNDEF)) == (1 << mem_type)) { - set_type = 0; + set_type = false; } } else { - set_type = 0; + set_type = false; } } } @@ -4865,33 +4832,30 @@ static int zend_jit_inc_dec(zend_jit_ctx *jit, const zend_op *opline, uint32_t o int32_t exit_point; const void *exit_addr; zend_jit_trace_stack *stack; - uint32_t old_res_info = 0; + uint32_t old_res_info = 0, old_op1_info = 0; stack = JIT_G(current_frame)->stack; if (opline->result_type != IS_UNUSED) { old_res_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var)); + SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_LONG, 0); if (opline->opcode == ZEND_PRE_INC || opline->opcode == ZEND_PRE_DEC) { - SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_LONG, 0); + SET_STACK_REF(stack, EX_VAR_TO_NUM(opline->result.var), ref); + } else { + SET_STACK_REF(stack, EX_VAR_TO_NUM(opline->result.var), op1_lval_ref); } } + old_op1_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var)); + SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var), IS_LONG, 0); + SET_STACK_REF(stack, EX_VAR_TO_NUM(opline->op1.var), ref); + exit_point = zend_jit_trace_get_exit_point(opline + 1, 0); exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if ((opline->opcode == ZEND_PRE_INC || opline->opcode == ZEND_PRE_DEC) && - opline->result_type != IS_UNUSED) { - if_overflow = ir_IF(ir_OVERFLOW(ref)); - ir_IF_FALSE_cold(if_overflow); - jit_set_Z_LVAL(jit, res_addr, ref); - if (Z_MODE(res_addr) != IS_REG) { - jit_set_Z_TYPE_INFO(jit, res_addr, IS_LONG); - } - jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr)); - ir_IF_TRUE(if_overflow); - } else { - ir_GUARD(ir_OVERFLOW(ref), ir_CONST_ADDR(exit_addr)); - } + ir_GUARD(ir_OVERFLOW(ref), ir_CONST_ADDR(exit_addr)); + if (opline->result_type != IS_UNUSED) { SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var), old_res_info); } + SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var), old_op1_info); } else { if_overflow = ir_IF(ir_OVERFLOW(ref)); ir_IF_FALSE(if_overflow); @@ -5041,7 +5005,7 @@ static int zend_jit_inc_dec(zend_jit_ctx *jit, const zend_op *opline, uint32_t o jit_ZVAL_COPY(jit, res_addr, res_use_info, - ZEND_ADDR_REF_ZVAL(ref), op1_info, 1); + ZEND_ADDR_REF_ZVAL(ref), op1_info, true); } if (opline->opcode == ZEND_PRE_INC || opline->opcode == ZEND_POST_INC) { if (opline->opcode == ZEND_PRE_INC && opline->result_type != IS_UNUSED) { @@ -6332,16 +6296,16 @@ static int zend_jit_simple_assign(zend_jit_ctx *jit, jit_ZVAL_COPY_CONST(jit, var_addr, var_info, var_def_info, - zv, 1); + zv, true); } else { jit_ZVAL_COPY_CONST(jit, var_addr, var_info, var_def_info, - zv, 1); + zv, true); jit_ZVAL_COPY_CONST(jit, res_addr, -1, var_def_info, - zv, 1); + zv, true); } } else { if (val_info & MAY_BE_UNDEF) { @@ -6386,7 +6350,7 @@ static int zend_jit_simple_assign(zend_jit_ctx *jit, jit_ZVAL_COPY(jit, var_addr, var_info, - ZEND_ADDR_REF_ZVAL(ref2), val_info, 1); + ZEND_ADDR_REF_ZVAL(ref2), val_info, true); } else { jit_ZVAL_COPY_2(jit, res_addr, @@ -6527,7 +6491,7 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit, { ir_ref if_refcounted = IR_UNUSED; ir_ref simple_inputs = IR_UNUSED; - bool done = 0; + bool done = false; zend_jit_addr real_res_addr = 0; ir_refs *end_inputs; ir_refs *res_inputs; @@ -6637,11 +6601,11 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit, ir_END_list(simple_inputs); ir_IF_TRUE_cold(if_refcounted); } else if (RC_MAY_BE_1(var_info)) { - done = 1; + done = true; } ref = jit_Z_PTR(jit, var_use_addr); if (RC_MAY_BE_1(var_info)) { - if (!zend_jit_simple_assign(jit, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0)) { + if (!zend_jit_simple_assign(jit, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, false)) { return 0; } counter = jit_GC_DELREF(jit, ref); @@ -6759,7 +6723,7 @@ static int zend_jit_qm_assign(zend_jit_ctx *jit, const zend_op *opline, uint32_t } } - if (!zend_jit_simple_assign(jit, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 1)) { + if (!zend_jit_simple_assign(jit, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, true)) { return 0; } if (!zend_jit_store_var_if_necessary(jit, opline->result.var, res_addr, res_info)) { @@ -7265,11 +7229,11 @@ static int zend_jit_cmp(zend_jit_ctx *jit, op1 = jit_ZVAL_ADDR(jit, op1_addr); if (opline->op1_type == IS_CV && (op1_info & MAY_BE_UNDEF)) { - op1 = zend_jit_zval_check_undef(jit, op1, opline->op1.var, NULL, 0); + op1 = zend_jit_zval_check_undef(jit, op1, opline->op1.var, NULL, false); } op2 = jit_ZVAL_ADDR(jit, op2_addr); if (opline->op2_type == IS_CV && (op2_info & MAY_BE_UNDEF)) { - op2 = zend_jit_zval_check_undef(jit, op2, opline->op2.var, NULL, 0); + op2 = zend_jit_zval_check_undef(jit, op2, opline->op2.var, NULL, false); } ref = ir_CALL_2(IR_I32, ir_CONST_FC_FUNC(zend_compare), op1, op2); if (opline->opcode != ZEND_CASE) { @@ -7362,34 +7326,34 @@ static int zend_jit_identical(zend_jit_ctx *jit, const void *exit_addr, bool skip_comparison) { - bool always_false = 0, always_true = 0; + bool always_false = false, always_true = false; ir_ref ref = IR_UNUSED; if (opline->op1_type == IS_CV && (op1_info & MAY_BE_UNDEF)) { ir_ref op1 = jit_ZVAL_ADDR(jit, op1_addr); - op1 = zend_jit_zval_check_undef(jit, op1, opline->op1.var, opline, 0); + op1 = zend_jit_zval_check_undef(jit, op1, opline->op1.var, opline, false); op1_info |= MAY_BE_NULL; op1_addr = ZEND_ADDR_REF_ZVAL(op1); } if (opline->op2_type == IS_CV && (op2_info & MAY_BE_UNDEF)) { ir_ref op2 = jit_ZVAL_ADDR(jit, op2_addr); - op2 = zend_jit_zval_check_undef(jit, op2, opline->op2.var, opline, 0); + op2 = zend_jit_zval_check_undef(jit, op2, opline->op2.var, opline, false); op2_info |= MAY_BE_NULL; op2_addr = ZEND_ADDR_REF_ZVAL(op2); } if ((op1_info & op2_info & MAY_BE_ANY) == 0) { - always_false = 1; + always_false = true; } else if (has_concrete_type(op1_info) && has_concrete_type(op2_info) && concrete_type(op1_info) == concrete_type(op2_info) && concrete_type(op1_info) <= IS_TRUE) { - always_true = 1; + always_true = true; } else if (Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_MODE(op2_addr) == IS_CONST_ZVAL) { if (zend_is_identical(Z_ZV(op1_addr), Z_ZV(op2_addr))) { - always_true = 1; + always_true = true; } else { - always_false = 1; + always_false = true; } } @@ -7591,17 +7555,17 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 { uint32_t true_label = -1; uint32_t false_label = -1; - bool set_bool = 0; - bool set_bool_not = 0; - bool always_true = 0, always_false = 0; + bool set_bool = false; + bool set_bool_not = false; + bool always_true = false, always_false = false; ir_ref ref, end_inputs = IR_UNUSED, true_inputs = IR_UNUSED, false_inputs = IR_UNUSED; ir_type type = IR_UNUSED; if (branch_opcode == ZEND_BOOL) { - set_bool = 1; + set_bool = true; } else if (branch_opcode == ZEND_BOOL_NOT) { - set_bool = 1; - set_bool_not = 1; + set_bool = true; + set_bool_not = true; } else if (branch_opcode == ZEND_JMPZ) { true_label = target_label2; false_label = target_label; @@ -7609,11 +7573,11 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 true_label = target_label; false_label = target_label2; } else if (branch_opcode == ZEND_JMPZ_EX) { - set_bool = 1; + set_bool = true; true_label = target_label2; false_label = target_label; } else if (branch_opcode == ZEND_JMPNZ_EX) { - set_bool = 1; + set_bool = true; true_label = target_label; false_label = target_label2; } else { @@ -7626,21 +7590,23 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 op1_addr = ZEND_ADDR_REF_ZVAL(ref); } - if (Z_MODE(op1_addr) == IS_CONST_ZVAL) { + if (Z_MODE(op1_addr) == IS_CONST_ZVAL + /* NAN Value must cause a warning to be emitted */ + && (Z_TYPE_P(Z_ZV(op1_addr)) != IS_DOUBLE || !zend_isnan(Z_DVAL_P(Z_ZV(op1_addr))))) { if (zend_is_true(Z_ZV(op1_addr))) { - always_true = 1; + always_true = true; } else { - always_false = 1; + always_false = true; } } else if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE)) { if (!(op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)-MAY_BE_TRUE))) { - always_true = 1; + always_true = true; } else if (!(op1_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE)))) { if (opline->op1_type == IS_CV && (op1_info & MAY_BE_UNDEF)) { ref = jit_ZVAL_ADDR(jit, op1_addr); - zend_jit_zval_check_undef(jit, ref, opline->op1.var, opline, 0); + zend_jit_zval_check_undef(jit, ref, opline->op1.var, opline, false); } - always_false = 1; + always_false = true; } } @@ -7685,7 +7651,7 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 zend_jit_type_check_undef(jit, type, opline->op1.var, - opline, 1, 0, 1); + opline, true, false, true); } if (set_bool) { jit_set_Z_TYPE_INFO(jit, res_addr, set_bool_not ? IS_TRUE : IS_FALSE); @@ -7794,7 +7760,16 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 if_double = ir_IF(ir_EQ(type, ir_CONST_U8(IS_DOUBLE))); ir_IF_TRUE(if_double); } - ref = ir_NE(jit_Z_DVAL(jit, op1_addr), ir_CONST_DOUBLE(0.0)); + + ir_ref dval = jit_Z_DVAL(jit, op1_addr); + ir_ref is_nan = ir_NE(dval, dval); + ir_ref if_val = ir_IF(is_nan); + ir_IF_TRUE_cold(if_val); + jit_SET_EX_OPLINE(jit, opline); + ir_CALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_nan_coerced_to_type_warning)); + ir_MERGE_WITH_EMPTY_FALSE(if_val); + + ref = ir_NE(dval, ir_CONST_DOUBLE(0.0)); if (branch_opcode == ZEND_BOOL || branch_opcode == ZEND_BOOL_NOT) { if (set_bool_not) { jit_set_Z_TYPE_INFO_ref(jit, jit_ZVAL_ADDR(jit, res_addr), @@ -7997,7 +7972,7 @@ static int zend_jit_defined(zend_jit_ctx *jit, const zend_op *opline, uint8_t sm return 1; } -static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, const zend_op *opline, int8_t reg) +static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, const zend_op *opline, const zend_op_array *op_array, int8_t reg) { zend_jit_addr reg_addr = ZEND_ADDR_REF_ZVAL(zend_jit_deopt_rload(jit, IR_ADDR, reg)); ir_ref if_def = ir_IF(jit_Z_TYPE(jit, reg_addr)); @@ -8020,7 +7995,18 @@ static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, } jit_LOAD_IP_ADDR(jit, opline - 1); - ir_IJMP(jit_STUB_ADDR(jit, jit_stub_trace_escape)); + + /* We can't use trace_escape() because opcode handler may be overridden by JIT */ + zend_jit_op_array_trace_extension *jit_extension = + (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array); + size_t offset = jit_extension->offset; + ir_ref ref = ir_CONST_FC_FUNC(ZEND_OP_TRACE_INFO((opline - 1), offset)->orig_handler); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + ir_TAILCALL(IR_OPCODE_HANDLER_RET, ref); + } else { + ir_ref opline_ref = ir_CALL_2(IR_OPCODE_HANDLER_RET, ref, jit_FP(jit), jit_IP(jit)); + zend_jit_vm_enter(jit, opline_ref); + } ir_IF_TRUE(if_def); @@ -8033,7 +8019,7 @@ static int zend_jit_restore_zval(zend_jit_ctx *jit, int var, int8_t reg) zend_jit_addr reg_addr = ZEND_ADDR_REF_ZVAL(zend_jit_deopt_rload(jit, IR_ADDR, reg)); // JIT: ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); (no dup) - jit_ZVAL_COPY(jit, var_addr, MAY_BE_ANY, reg_addr, MAY_BE_ANY, 1); + jit_ZVAL_COPY(jit, var_addr, MAY_BE_ANY, reg_addr, MAY_BE_ANY, true); return 1; } @@ -8170,7 +8156,7 @@ static int zend_jit_fetch_constant(zend_jit_ctx *jit, uint8_t type = concrete_type(res_info); zend_jit_addr const_addr = ZEND_ADDR_REF_ZVAL(ref); - const_addr = zend_jit_guard_fetch_result_type(jit, opline, const_addr, type, 0, 0, 0); + const_addr = zend_jit_guard_fetch_result_type(jit, opline, const_addr, type, false, 0, false); if (!const_addr) { return 0; } @@ -8179,7 +8165,7 @@ static int zend_jit_fetch_constant(zend_jit_ctx *jit, ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD; // JIT: ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); (no dup) - jit_ZVAL_COPY(jit, res_addr, MAY_BE_ANY, const_addr, res_info, 1); + jit_ZVAL_COPY(jit, res_addr, MAY_BE_ANY, const_addr, res_info, true); if (!zend_jit_store_var_if_necessary(jit, opline->result.var, res_addr, res_info)) { return 0; } @@ -8187,7 +8173,7 @@ static int zend_jit_fetch_constant(zend_jit_ctx *jit, ir_ref const_addr = ZEND_ADDR_REF_ZVAL(ref); // JIT: ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); (no dup) - jit_ZVAL_COPY(jit, res_addr, MAY_BE_ANY, const_addr, MAY_BE_ANY, 1); + jit_ZVAL_COPY(jit, res_addr, MAY_BE_ANY, const_addr, MAY_BE_ANY, true); } @@ -8298,7 +8284,7 @@ static int zend_jit_type_check(zend_jit_ctx *jit, const zend_op *opline, uint32_ } } else { ir_ref ref; - bool invert = 0; + bool invert = false; uint8_t type; switch (mask) { @@ -8310,15 +8296,15 @@ static int zend_jit_type_check(zend_jit_ctx *jit, const zend_op *opline, uint32_ case MAY_BE_STRING: type = IS_STRING; break; case MAY_BE_ARRAY: type = IS_ARRAY; break; case MAY_BE_OBJECT: type = IS_OBJECT; break; - case MAY_BE_ANY - MAY_BE_NULL: type = IS_NULL; invert = 1; break; - case MAY_BE_ANY - MAY_BE_FALSE: type = IS_FALSE; invert = 1; break; - case MAY_BE_ANY - MAY_BE_TRUE: type = IS_TRUE; invert = 1; break; - case MAY_BE_ANY - MAY_BE_LONG: type = IS_LONG; invert = 1; break; - case MAY_BE_ANY - MAY_BE_DOUBLE: type = IS_DOUBLE; invert = 1; break; - case MAY_BE_ANY - MAY_BE_STRING: type = IS_STRING; invert = 1; break; - case MAY_BE_ANY - MAY_BE_ARRAY: type = IS_ARRAY; invert = 1; break; - case MAY_BE_ANY - MAY_BE_OBJECT: type = IS_OBJECT; invert = 1; break; - case MAY_BE_ANY - MAY_BE_RESOURCE: type = IS_OBJECT; invert = 1; break; + case MAY_BE_ANY - MAY_BE_NULL: type = IS_NULL; invert = true; break; + case MAY_BE_ANY - MAY_BE_FALSE: type = IS_FALSE; invert = true; break; + case MAY_BE_ANY - MAY_BE_TRUE: type = IS_TRUE; invert = true; break; + case MAY_BE_ANY - MAY_BE_LONG: type = IS_LONG; invert = true; break; + case MAY_BE_ANY - MAY_BE_DOUBLE: type = IS_DOUBLE; invert = true; break; + case MAY_BE_ANY - MAY_BE_STRING: type = IS_STRING; invert = true; break; + case MAY_BE_ANY - MAY_BE_ARRAY: type = IS_ARRAY; invert = true; break; + case MAY_BE_ANY - MAY_BE_OBJECT: type = IS_OBJECT; invert = true; break; + case MAY_BE_ANY - MAY_BE_RESOURCE: type = IS_OBJECT; invert = true; break; default: type = 0; } @@ -8456,14 +8442,7 @@ static int zend_jit_isset_isempty_cv(zend_jit_ctx *jit, const zend_op *opline, u return 1; } -/* copy of hidden zend_closure */ -typedef struct _zend_closure { - zend_object std; - zend_function func; - zval this_ptr; - zend_class_entry *called_scope; - zif_handler orig_internal_handler; -} zend_closure; +/* zend_closure struct now exposed in zend_closures.h */ static int zend_jit_stack_check(zend_jit_ctx *jit, const zend_op *opline, uint32_t used_stack) { @@ -8502,14 +8481,14 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co { uint32_t used_stack; ir_ref used_stack_ref = IR_UNUSED; - bool stack_check = 1; + bool stack_check = true; ir_ref rx, ref, top, if_enough_stack, cold_path = IR_UNUSED; ZEND_ASSERT(func_ref != IR_NULL); if (func) { used_stack = zend_vm_calc_used_stack(opline->extended_value, func); if ((int)used_stack <= checked_stack) { - stack_check = 0; + stack_check = false; } used_stack_ref = ir_CONST_ADDR(used_stack); } else { @@ -8758,6 +8737,12 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co // JIT: ZEND_CALL_NUM_ARGS(call) = num_args; ir_STORE(jit_CALL(rx, This.u2.num_args), ir_CONST_U32(opline->extended_value)); + // JIT: call->type_args = NULL; + // Mirrors zend_vm_init_call_frame; without this the field is stack + // garbage and zend_vm_stack_free_call_frame_ex dereferences it on + // frame teardown (segfault on the exception / undef-prop path). + ir_STORE(jit_CALL(rx, type_args), IR_NULL); + return 1; } @@ -8938,7 +8923,7 @@ jit_SET_EX_OPLINE(jit, opline); func_ref = ir_PHI_2(IR_ADDR, ref, func_ref); } - if (!zend_jit_push_call_frame(jit, opline, op_array, func, 0, 0, checked_stack, func_ref, IR_UNUSED)) { + if (!zend_jit_push_call_frame(jit, opline, op_array, func, false, false, checked_stack, func_ref, IR_UNUSED)) { return 0; } @@ -8949,7 +8934,7 @@ jit_SET_EX_OPLINE(jit, opline); } else { ZEND_ASSERT(call_level > 0); jit->delayed_call_level = call_level; - delayed_call_chain = 1; + delayed_call_chain = true; } if (trace @@ -9197,7 +9182,7 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit, } if (!func || (func->common.fn_flags & ZEND_ACC_STATIC) == 0) { - if (!zend_jit_push_call_frame(jit, opline, NULL, func, 0, delayed_fetch_this, checked_stack, func_ref, this_ref)) { + if (!zend_jit_push_call_frame(jit, opline, NULL, func, false, delayed_fetch_this, checked_stack, func_ref, this_ref)) { return 0; } } @@ -9213,7 +9198,7 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit, } } else { ZEND_ASSERT(call_level > 0); - delayed_call_chain = 1; + delayed_call_chain = true; jit->delayed_call_level = call_level; } @@ -9375,7 +9360,7 @@ static int zend_jit_init_static_method_call(zend_jit_ctx *jit, scope_ref = ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(jit_EX(This.value.ref)), offsetof(zend_object, ce))); } } - if (!zend_jit_push_call_frame(jit, opline, op_array, func, 0, 0, checked_stack, func_ref, scope_ref)) { + if (!zend_jit_push_call_frame(jit, opline, op_array, func, false, false, checked_stack, func_ref, scope_ref)) { return 0; } @@ -9392,7 +9377,7 @@ static int zend_jit_init_static_method_call(zend_jit_ctx *jit, } else { ZEND_ASSERT(call_level > 0); jit->delayed_call_level = call_level; - delayed_call_chain = 1; + delayed_call_chain = true; } if (trace @@ -9473,7 +9458,7 @@ static int zend_jit_init_closure_call(zend_jit_ctx *jit, } } - if (!zend_jit_push_call_frame(jit, opline, NULL, func, 1, 0, checked_stack, ref, IR_UNUSED)) { + if (!zend_jit_push_call_frame(jit, opline, NULL, func, true, false, checked_stack, ref, IR_UNUSED)) { return 0; } @@ -9483,7 +9468,7 @@ static int zend_jit_init_closure_call(zend_jit_ctx *jit, } } else { ZEND_ASSERT(call_level > 0); - delayed_call_chain = 1; + delayed_call_chain = true; jit->delayed_call_level = call_level; } @@ -9561,12 +9546,12 @@ static int zend_jit_send_val(zend_jit_ctx *jit, const zend_op *opline, uint32_t jit_ZVAL_COPY_CONST(jit, arg_addr, MAY_BE_ANY, MAY_BE_ANY, - zv, 1); + zv, true); } else { jit_ZVAL_COPY(jit, arg_addr, MAY_BE_ANY, - op1_addr, op1_info, 0); + op1_addr, op1_info, false); } return 1; @@ -9640,7 +9625,7 @@ static int zend_jit_send_ref(zend_jit_ctx *jit, const zend_op *opline, const zen jit_ZVAL_COPY(jit, ref_addr, MAY_BE_ANY, - op1_addr, op1_info, 0); + op1_addr, op1_info, false); // JIT: ZVAL_REFERENCE(arg, ref) jit_set_Z_PTR(jit, op1_addr, ref); @@ -9714,7 +9699,7 @@ static int zend_jit_send_var(zend_jit_ctx *jit, const zend_op *opline, const zen jit_ZVAL_COPY(jit, arg_addr, MAY_BE_ANY, - op1_addr, op1_info, 0); + op1_addr, op1_info, false); if (!ARG_MAY_BE_SENT_BY_REF(JIT_G(current_frame)->call->func, arg_num)) { if (!(op1_info & MAY_BE_REF)) { @@ -9751,7 +9736,7 @@ static int zend_jit_send_var(zend_jit_ctx *jit, const zend_op *opline, const zen jit_ZVAL_COPY(jit, arg_addr, MAY_BE_ANY, - op1_addr, op1_info, 0); + op1_addr, op1_info, false); if (op1_info & MAY_BE_REF) { ir_ref if_ref = jit_if_Z_TYPE(jit, arg_addr, IS_REFERENCE); @@ -9848,7 +9833,7 @@ static int zend_jit_send_var(zend_jit_ctx *jit, const zend_op *opline, const zen jit_ZVAL_COPY(jit, arg_addr, MAY_BE_ANY, - op1_addr, op1_info, 0); + op1_addr, op1_info, false); if (op1_info & MAY_BE_REF) { // JIT: if (Z_TYPE_P(arg) == IS_REFERENCE) ir_ref if_ref = jit_if_Z_TYPE(jit, arg_addr, IS_REFERENCE); @@ -9883,7 +9868,7 @@ static int zend_jit_send_var(zend_jit_ctx *jit, const zend_op *opline, const zen jit_ZVAL_COPY(jit, arg_addr, MAY_BE_ANY, - op1_addr, op1_info, 1); + op1_addr, op1_info, true); } else { ir_ref if_ref, ref, ref2, refcount, if_not_zero, if_refcounted; zend_jit_addr ref_addr; @@ -9901,7 +9886,7 @@ static int zend_jit_send_var(zend_jit_ctx *jit, const zend_op *opline, const zen jit_ZVAL_COPY(jit, arg_addr, MAY_BE_ANY, - ref_addr, op1_info, 0); + ref_addr, op1_info, false); // JIT: if (GC_DELREF(ref) != 0) refcount = jit_GC_DELREF(jit, ref); @@ -9929,7 +9914,7 @@ static int zend_jit_send_var(zend_jit_ctx *jit, const zend_op *opline, const zen jit_ZVAL_COPY(jit, arg_addr, MAY_BE_ANY, - op1_addr, op1_info, 0); + op1_addr, op1_info, false); } } else { if (op1_addr != op1_def_addr) { @@ -10055,7 +10040,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen const zend_function *func = NULL; uint32_t i; uint32_t call_num_args = 0; - bool unknown_num_args = 0; + bool unknown_num_args = false; const void *exit_addr = NULL; const zend_op *prev_opline; ir_ref rx, func_ref = IR_UNUSED, if_user = IR_UNUSED, user_path = IR_UNUSED; @@ -10066,7 +10051,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen } if (prev_opline->opcode == ZEND_SEND_UNPACK || prev_opline->opcode == ZEND_SEND_ARRAY || prev_opline->opcode == ZEND_CHECK_UNDEF_ARGS) { - unknown_num_args = 1; + unknown_num_args = true; } if (info) { @@ -10107,7 +10092,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call) >= 0) { call_num_args = TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call); } else { - unknown_num_args = 1; + unknown_num_args = true; } #endif } else if (trace->op == ZEND_JIT_TRACE_ENTER) { @@ -10119,7 +10104,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call) >= 0) { call_num_args = TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call); } else { - unknown_num_args = 1; + unknown_num_args = true; } } } @@ -10164,7 +10149,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen ir_STORE(jit_EX(call), (call_level == 1) ? IR_NULL : ir_LOAD_A(jit_CALL(rx, prev_execute_data))); } - delayed_call_chain = 0; + delayed_call_chain = false; jit->delayed_call_level = 0; // JIT: call->prev_execute_data = execute_data; @@ -10232,7 +10217,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen if ((!func || func->type == ZEND_USER_FUNCTION) && opline->opcode != ZEND_DO_ICALL) { - bool recursive_call_through_jmp = 0; + bool recursive_call_through_jmp = false; uint32_t num_args = 0; // JIT: EX(call) = NULL; @@ -10324,7 +10309,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen if (!trace && op_array == &func->op_array && call_num_args >= op_array->required_num_args) { /* recursive call */ - recursive_call_through_jmp = 1; + recursive_call_through_jmp = true; } } } else { @@ -10348,6 +10333,8 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen } if (GCC_GLOBAL_REGS) { ir_CALL(IR_VOID, helper); + } else if (ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + ir_CALL_2(IR_ADDR, helper, jit_FP(jit), jit_IP(jit)); } else { ir_ref ref = ir_CALL_2(IR_ADDR, helper, jit_FP(jit), jit_IP(jit)); jit_STORE_IP(jit, ref); @@ -10454,28 +10441,19 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen if (ZEND_OBSERVER_ENABLED && (!func || (func->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE | ZEND_ACC_GENERATOR)) == 0)) { ir_ref observer_handler; ir_ref rx = jit_FP(jit); + const zend_op *observer_opline = NULL; struct jit_observer_fcall_is_unobserved_data unobserved_data = jit_observer_fcall_is_unobserved_start(jit, func, &observer_handler, rx, func_ref); if (trace && (trace->op != ZEND_JIT_TRACE_END || trace->stop < ZEND_JIT_TRACE_STOP_INTERPRETER)) { ZEND_ASSERT(trace[1].op == ZEND_JIT_TRACE_VM || trace[1].op == ZEND_JIT_TRACE_END); - jit_SET_EX_OPLINE(jit, trace[1].opline); + observer_opline = trace[1].opline; + jit_SET_EX_OPLINE(jit, observer_opline); } else { // EX(opline) = opline ir_STORE(jit_EX(opline), jit_IP(jit)); } jit_observer_fcall_begin(jit, rx, observer_handler); - if (trace) { - int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); - - exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!exit_addr) { - return 0; - } - } else { - exit_addr = NULL; - } - - zend_jit_check_timeout(jit, NULL /* we're inside the called function */, exit_addr); + zend_jit_check_timeout(jit, observer_opline, NULL); jit_observer_fcall_is_unobserved_end(jit, &unobserved_data); } @@ -10522,8 +10500,8 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen } } /* fallback to indirect JMP or RETURN */ - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, ir_LOAD_A(jit_IP(jit))); } else { zend_jit_vm_enter(jit, jit_IP(jit)); } @@ -10639,7 +10617,8 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen uint32_t offset = EX_NUM_TO_VAR(i); zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, offset); - jit_ZVAL_PTR_DTOR(jit, var_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, 0, opline); + jit_ZVAL_PTR_DTOR(jit, var_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, false, + opline); } } } else { @@ -10726,7 +10705,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen #endif } res_addr = ZEND_ADDR_REF_ZVAL(sp); - jit_ZVAL_PTR_DTOR(jit, res_addr, func_info, 1, opline); + jit_ZVAL_PTR_DTOR(jit, res_addr, func_info, true, opline); } if (!jit->ctx.fixed_call_stack_size) { // JIT: revert alloca @@ -10909,7 +10888,7 @@ static int zend_jit_recv(zend_jit_ctx *jit, const zend_op *opline, const zend_op } if (arg_info) { - if (!zend_jit_verify_arg_type(jit, opline, arg_info, 1)) { + if (!zend_jit_verify_arg_type(jit, opline, arg_info, true)) { return 0; } } @@ -10931,7 +10910,7 @@ static int zend_jit_recv_init(zend_jit_ctx *jit, const zend_op *opline, const ze jit_ZVAL_COPY_CONST(jit, res_addr, -1, -1, - zv, 1); + zv, true); } } else { if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || @@ -10944,7 +10923,7 @@ static int zend_jit_recv_init(zend_jit_ctx *jit, const zend_op *opline, const ze jit_ZVAL_COPY_CONST(jit, res_addr, -1, -1, - zv, 1); + zv, true); } if (Z_CONSTANT_P(zv)) { @@ -10955,7 +10934,7 @@ static int zend_jit_recv_init(zend_jit_ctx *jit, const zend_op *opline, const ze if_fail = ir_IF(ref); ir_IF_TRUE_cold(if_fail); - jit_ZVAL_PTR_DTOR(jit, res_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, 1, opline); + jit_ZVAL_PTR_DTOR(jit, res_addr, MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, true, opline); ir_IJMP(jit_STUB_ADDR(jit, jit_stub_exception_handler)); ir_IF_FALSE(if_fail); } @@ -10992,7 +10971,7 @@ static bool zend_jit_verify_return_type(zend_jit_ctx *jit, const zend_op *opline zend_arg_info *arg_info = &op_array->arg_info[-1]; ZEND_ASSERT(ZEND_TYPE_IS_SET(arg_info->type)); zend_jit_addr op1_addr = OP1_ADDR(); - bool needs_slow_check = 1; + bool needs_slow_check = true; uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type) & MAY_BE_ANY; ir_ref fast_path = IR_UNUSED; @@ -11000,7 +10979,7 @@ static bool zend_jit_verify_return_type(zend_jit_ctx *jit, const zend_op *opline if (((op1_info & MAY_BE_ANY) & type_mask) == 0) { /* pass */ } else if (((op1_info & MAY_BE_ANY) | type_mask) == type_mask) { - needs_slow_check = 0; + needs_slow_check = false; } else if (is_power_of_two(type_mask)) { uint32_t type_code = concrete_type(type_mask); ir_ref if_ok = jit_if_Z_TYPE(jit, op1_addr, type_code); @@ -11024,7 +11003,7 @@ static bool zend_jit_verify_return_type(zend_jit_ctx *jit, const zend_op *opline jit_SET_EX_OPLINE(jit, opline); ref = jit_ZVAL_ADDR(jit, op1_addr); if (op1_info & MAY_BE_UNDEF) { - ref = zend_jit_zval_check_undef(jit, ref, opline->op1.var, NULL, 1); + ref = zend_jit_zval_check_undef(jit, ref, opline->op1.var, NULL, true); } ir_CALL_3(IR_VOID, ir_CONST_FC_FUNC(zend_jit_verify_return_slow), @@ -11039,7 +11018,7 @@ static bool zend_jit_verify_return_type(zend_jit_ctx *jit, const zend_op *opline } } - return 1; + return true; } static int zend_jit_leave_frame(zend_jit_ctx *jit) @@ -11059,12 +11038,29 @@ static int zend_jit_free_cvs(zend_jit_ctx *jit) return 1; } +/* The inline CV-free fast path that callers use when last_var <= 100 frees + * each CV individually and bypasses zend_free_compiled_variables, which is + * where the interpreter teardown destroys EX(type_args). Without this helper + * the table allocated by VERIFY_GENERIC_ARGUMENTS / INSTALL_GENERIC_ARGS + * leaks on every JIT'd generic call return — and for inference calls each + * leaked table also carries refcounted owned_type fragments, so the rate is + * fast enough to OOM tight loops in seconds. */ +static int zend_jit_free_type_args(zend_jit_ctx *jit) +{ + ir_ref ta = ir_LOAD_A(jit_EX(type_args)); + ir_ref if_ta = ir_IF(ta); + ir_IF_TRUE_cold(if_ta); + ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_type_arg_table_destroy), ta); + ir_MERGE_WITH_EMPTY_FALSE(if_ta); + return 1; +} + static int zend_jit_free_cv(zend_jit_ctx *jit, uint32_t info, uint32_t var) { if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, EX_NUM_TO_VAR(var)); - jit_ZVAL_PTR_DTOR(jit, var_addr, info, 1, NULL); + jit_ZVAL_PTR_DTOR(jit, var_addr, info, true, NULL); } return 1; } @@ -11072,7 +11068,7 @@ static int zend_jit_free_cv(zend_jit_ctx *jit, uint32_t info, uint32_t var) static int zend_jit_free_op(zend_jit_ctx *jit, const zend_op *opline, uint32_t info, uint32_t var_offset) { if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { - jit_ZVAL_PTR_DTOR(jit, ZEND_ADDR_MEM_ZVAL(ZREG_FP, var_offset), info, 0, opline); + jit_ZVAL_PTR_DTOR(jit, ZEND_ADDR_MEM_ZVAL(ZREG_FP, var_offset), info, false, opline); } return 1; } @@ -11111,7 +11107,7 @@ static int zend_jit_leave_func(zend_jit_ctx *jit, if (may_need_call_helper) { if (!left_frame) { - left_frame = 1; + left_frame = true; if (!zend_jit_leave_frame(jit)) { return 0; } @@ -11132,7 +11128,7 @@ static int zend_jit_leave_func(zend_jit_ctx *jit, if (may_be_top_frame) { // TODO: try to avoid this check ??? - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { #if 0 /* this check should be handled by the following OPLINE guard */ | cmp IP, zend_jit_halt_op @@ -11159,7 +11155,7 @@ static int zend_jit_leave_func(zend_jit_ctx *jit, if ((op_array->fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE)) == ZEND_ACC_CLOSURE) { if (!left_frame) { - left_frame = 1; + left_frame = true; if (!zend_jit_leave_frame(jit)) { return 0; } @@ -11170,7 +11166,7 @@ static int zend_jit_leave_func(zend_jit_ctx *jit, ir_ref if_release, fast_path = IR_UNUSED; if (!left_frame) { - left_frame = 1; + left_frame = true; if (!zend_jit_leave_frame(jit)) { return 0; } @@ -11290,8 +11286,8 @@ static int zend_jit_leave_func(zend_jit_ctx *jit, jit_STORE_IP(jit, ir_ADD_OFFSET(jit_IP(jit), sizeof(zend_op))); } - if (GCC_GLOBAL_REGS) { - ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { + zend_jit_tailcall_handler(jit, ir_LOAD_A(jit_IP(jit))); } else { zend_jit_vm_leave(jit, jit_IP(jit)); } @@ -11396,9 +11392,9 @@ static int zend_jit_return(zend_jit_ctx *jit, const zend_op *opline, const zend_ if (opline->op1_type == IS_CONST) { zval *zv = RT_CONSTANT(opline, opline->op1); - jit_ZVAL_COPY_CONST(jit, ret_addr, MAY_BE_ANY, MAY_BE_ANY, zv, 1); + jit_ZVAL_COPY_CONST(jit, ret_addr, MAY_BE_ANY, MAY_BE_ANY, zv, true); } else if (opline->op1_type == IS_TMP_VAR) { - jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, 0); + jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, false); } else if (opline->op1_type == IS_CV) { if (op1_info & MAY_BE_REF) { ref = jit_ZVAL_ADDR(jit, op1_addr); @@ -11410,16 +11406,16 @@ static int zend_jit_return(zend_jit_ctx *jit, const zend_op *opline, const zend_ if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || (op1_info & (MAY_BE_REF|MAY_BE_OBJECT)) || !op_array->function_name) { - jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, 1); + jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, true); } else if (return_value_used != 1) { - jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, 0); + jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, false); // JIT: if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) ZVAL_NULL(retval_ptr); jit_set_Z_TYPE_INFO(jit, op1_addr, IS_NULL); } else { - jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, 0); + jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, false); } } else { - jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, 0); + jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, false); } } else { if (op1_info & MAY_BE_REF) { @@ -11435,7 +11431,7 @@ static int zend_jit_return(zend_jit_ctx *jit, const zend_op *opline, const zend_ // JIT: ZVAL_COPY_VALUE(return_value, &ref->value) ref2 = ir_ADD_OFFSET(ref, offsetof(zend_reference, val)); ref_addr = ZEND_ADDR_REF_ZVAL(ref2); - jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, ref_addr, op1_info, 0); + jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, ref_addr, op1_info, false); ref2 = jit_GC_DELREF(jit, ref); if_non_zero = ir_IF(ref2); ir_IF_TRUE(if_non_zero); @@ -11458,7 +11454,7 @@ static int zend_jit_return(zend_jit_ctx *jit, const zend_op *opline, const zend_ ir_IF_FALSE(if_ref); } - jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, 0); + jit_ZVAL_COPY(jit, ret_addr, MAY_BE_ANY, op1_addr, op1_info, false); } if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { @@ -11614,7 +11610,7 @@ static int zend_jit_free(zend_jit_ctx *jit, const zend_op *opline, uint32_t op1_ ir_MERGE_list(end_inputs); } - jit_ZVAL_PTR_DTOR(jit, op1_addr, op1_info, 0, opline); + jit_ZVAL_PTR_DTOR(jit, op1_addr, op1_info, false, opline); if (may_throw) { zend_jit_check_exception(jit); @@ -11657,7 +11653,7 @@ static int zend_jit_echo(zend_jit_ctx *jit, const zend_op *opline, uint32_t op1_ ir_LOAD_A(ir_ADD_OFFSET(ref, offsetof(zend_string, len)))); if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - jit_ZVAL_PTR_DTOR(jit, op1_addr, op1_info, 0, opline); + jit_ZVAL_PTR_DTOR(jit, op1_addr, op1_info, false, opline); } zend_jit_check_exception(jit); @@ -11996,9 +11992,9 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, } if (op2_info & MAY_BE_LONG) { - bool op2_loaded = 0; - bool packed_loaded = 0; - bool bad_packed_key = 0; + bool op2_loaded = false; + bool packed_loaded = false; + bool bad_packed_key = false; ir_ref if_packed = IS_UNDEF; ir_ref h = IR_UNUSED; ir_ref idx_not_found_inputs = IR_UNUSED; @@ -12027,7 +12023,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, if (type == BP_VAR_W) { // JIT: hval = Z_LVAL_P(dim); h = jit_Z_LVAL(jit, op2_addr); - op2_loaded = 1; + op2_loaded = true; } if (op1_info & MAY_BE_ARRAY_PACKED) { zend_long val = -1; @@ -12035,23 +12031,23 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, if (Z_MODE(op2_addr) == IS_CONST_ZVAL) { val = Z_LVAL_P(Z_ZV(op2_addr)); if (val >= 0 && val < HT_MAX_SIZE) { - packed_loaded = 1; + packed_loaded = true; } else { - bad_packed_key = 1; + bad_packed_key = true; } h = ir_CONST_LONG(val); } else { if (!op2_loaded) { // JIT: hval = Z_LVAL_P(dim); h = jit_Z_LVAL(jit, op2_addr); - op2_loaded = 1; + op2_loaded = true; } - packed_loaded = 1; + packed_loaded = true; } if (dim_type == IS_UNDEF && type == BP_VAR_W && packed_loaded) { /* don't generate "fast" code for packed array */ - packed_loaded = 0; + packed_loaded = false; } if (packed_loaded) { @@ -12122,7 +12118,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, if (!op2_loaded) { // JIT: hval = Z_LVAL_P(dim); h = jit_Z_LVAL(jit, op2_addr); - op2_loaded = 1; + op2_loaded = true; } if (packed_loaded) { ref = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(_zend_hash_index_find), ht_ref, h); @@ -12172,7 +12168,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, if (!op2_loaded) { // JIT: hval = Z_LVAL_P(dim); h = jit_Z_LVAL(jit, op2_addr); - op2_loaded = 1; + op2_loaded = true; } if (packed_loaded) { ref = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(_zend_hash_index_find), ht_ref, h); @@ -12572,8 +12568,8 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit, zend_jit_addr orig_op1_addr; const void *exit_addr = NULL; const void *not_found_exit_addr = NULL; - bool result_type_guard = 0; - bool result_avoid_refcounting = 0; + bool result_type_guard = false; + bool result_avoid_refcounting = false; uint32_t may_be_string = (opline->opcode != ZEND_FETCH_LIST_R) ? MAY_BE_STRING : 0; int may_throw = 0; ir_ref if_type = IR_UNUSED; @@ -12597,7 +12593,7 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit, && (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) { if (!(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))) { - result_type_guard = 1; + result_type_guard = true; res_info &= ~MAY_BE_GUARD; ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD; } @@ -12610,7 +12606,7 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit, && (ssa_op+1)->op1_use == ssa_op->result_def && !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG))) && zend_jit_may_avoid_refcounting(opline+1, res_info)) { - result_avoid_refcounting = 1; + result_avoid_refcounting = true; ssa->var_info[ssa_op->result_def].avoid_refcounting = 1; } @@ -12734,7 +12730,7 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit, } } else { // ZVAL_COPY - jit_ZVAL_COPY(jit, res_addr, -1, val_addr, res_info, 1); + jit_ZVAL_COPY(jit, res_addr, -1, val_addr, res_info, true); } ir_END_list(end_inputs); @@ -12841,16 +12837,18 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit, jit_SET_EX_OPLINE(jit, opline); if (opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) { may_throw = 1; - zend_jit_type_check_undef(jit, jit_Z_TYPE(jit, op1_addr), opline->op1.var, NULL, 0, 1, 0); + zend_jit_type_check_undef(jit, jit_Z_TYPE(jit, op1_addr), opline->op1.var, NULL, + false, true, false); } if (op2_info & MAY_BE_UNDEF) { may_throw = 1; - zend_jit_type_check_undef(jit, jit_Z_TYPE(jit, op2_addr), opline->op2.var, NULL, 0, 1, 0); + zend_jit_type_check_undef(jit, jit_Z_TYPE(jit, op2_addr), opline->op2.var, NULL, + false, true, false); } } - if (opline->opcode != ZEND_FETCH_DIM_IS && opline->opcode != ZEND_FETCH_LIST_R) { + if (opline->opcode != ZEND_FETCH_DIM_IS) { ir_ref ref; may_throw = 1; @@ -12860,7 +12858,11 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit, jit_SET_EX_OPLINE(jit, opline); ref = jit_ZVAL_ADDR(jit, op1_addr); } - ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_invalid_array_access), ref); + if (opline->opcode == ZEND_FETCH_LIST_R) { + ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_invalid_array_use), ref); + } else { + ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_invalid_array_access), ref); + } } jit_set_Z_TYPE_INFO(jit, res_addr, IS_NULL); @@ -13092,7 +13094,7 @@ static int zend_jit_fetch_dim(zend_jit_ctx *jit, } if (!zend_jit_fetch_dimension_address_inner(jit, opline, type, op1_info, op2_info, op2_addr, op2_range, dim_type, NULL, NULL, NULL, - 0, ht_ref, found_inputs, found_vals, &end_inputs, NULL)) { + false, ht_ref, found_inputs, found_vals, &end_inputs, NULL)) { return 0; } @@ -13253,7 +13255,7 @@ static int zend_jit_isset_isempty_dim(zend_jit_ctx *jit, } if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_JIT_IS, op1_info, op2_info, op2_addr, op2_range, dim_type, found_exit_addr, not_found_exit_addr, NULL, - 0, ht_ref, true_inputs, NULL, &false_inputs, NULL)) { + false, ht_ref, true_inputs, NULL, &false_inputs, NULL)) { return 0; } @@ -13454,7 +13456,7 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit, ir_IF_TRUE(if_ok); var_addr = ZEND_ADDR_REF_ZVAL(ref); - if (!zend_jit_simple_assign(jit, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0)) { + if (!zend_jit_simple_assign(jit, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, false)) { return 0; } } else { @@ -13468,7 +13470,7 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit, if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_W, op1_info, op2_info, op2_addr, op2_range, dim_type, NULL, NULL, NULL, - 0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) { + false, ht_ref, found_inputs, found_values, &end_inputs, NULL)) { return 0; } @@ -13489,11 +13491,11 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit, && Z_MODE(op3_addr) != IS_REG && opline->result_type == IS_UNUSED && (res_addr == 0 || Z_MODE(res_addr) != IS_REG)) { - if (!zend_jit_assign_to_variable_call(jit, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0)) { + if (!zend_jit_assign_to_variable_call(jit, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, false)) { return 0; } } else { - if (!zend_jit_assign_to_variable(jit, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0)) { + if (!zend_jit_assign_to_variable(jit, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, false)) { return 0; } } @@ -13586,7 +13588,7 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit, uint32_t var_info = MAY_BE_NULL; ir_ref if_type = IS_UNUSED; ir_ref end_inputs = IR_UNUSED, ht_ref; - bool emit_fast_path = 1; + bool emit_fast_path = true; ZEND_ASSERT(opline->result_type == IS_UNUSED); @@ -13654,7 +13656,7 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit, if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_RW, op1_info, op2_info, op2_addr, op2_range, dim_type, NULL, not_found_exit_addr, NULL, - 0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) { + false, ht_ref, found_inputs, found_values, &end_inputs, NULL)) { return 0; } @@ -13702,7 +13704,7 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit, var_addr = ZEND_ADDR_REF_ZVAL(ref); } } else { - emit_fast_path = 0; + emit_fast_path = false; } } @@ -13802,7 +13804,7 @@ static int zend_jit_fe_reset(zend_jit_ctx *jit, const zend_op *opline, uint32_t if (opline->op1_type == IS_CONST) { zval *zv = RT_CONSTANT(opline, opline->op1); - jit_ZVAL_COPY_CONST(jit, res_addr, MAY_BE_ANY, MAY_BE_ANY, zv, 1); + jit_ZVAL_COPY_CONST(jit, res_addr, MAY_BE_ANY, MAY_BE_ANY, zv, true); } else { zend_jit_addr op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var); @@ -14140,12 +14142,19 @@ static int zend_jit_fe_fetch(zend_jit_ctx *jit, const zend_op *opline, uint32_t val_addr = ZEND_ADDR_REF_ZVAL(p_ref); if (opline->op2_type == IS_CV) { // JIT: zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - if (!zend_jit_assign_to_variable(jit, opline, var_addr, var_addr, op2_info, -1, IS_CV, val_addr, val_info, 0, 0, 1)) { + if (!zend_jit_assign_to_variable(jit, opline, var_addr, var_addr, op2_info, -1, IS_CV, val_addr, val_info, 0, 0, true)) { return 0; } } else { + // JIT: ZVAL_DEREF(value); + if (val_info & MAY_BE_REF) { + ir_ref ref = jit_ZVAL_ADDR(jit, val_addr); + ref = jit_ZVAL_DEREF_ref(jit, ref); + val_addr = ZEND_ADDR_REF_ZVAL(ref); + val_info &= ~MAY_BE_REF; + } // JIT: ZVAL_COPY(res, value); - jit_ZVAL_COPY(jit, var_addr, -1, val_addr, val_info, 1); + jit_ZVAL_COPY(jit, var_addr, -1, val_addr, val_info, true); } if (!exit_addr) { @@ -14264,7 +14273,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, { zval *member; zend_property_info *prop_info; - bool may_be_dynamic = 1; + bool may_be_dynamic = true; zend_jit_addr prop_addr; uint32_t res_info = RES_INFO(); ir_ref prop_type_ref = IR_UNUSED; @@ -14355,7 +14364,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, prop_info = zend_get_known_property_info(op_array, trace_ce, Z_STR_P(member), on_this, op_array->filename); if (prop_info) { ce = trace_ce; - ce_is_instanceof = 0; + ce_is_instanceof = false; if (!(op1_info & MAY_BE_CLASS_GUARD)) { if (on_this && JIT_G(current_frame) && TRACE_FRAME_IS_THIS_CLASS_CHECKED(JIT_G(current_frame))) { @@ -14680,7 +14689,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, if (end_values) { ir_ref val_ref = ir_PHI_list(end_values); zend_jit_addr val_addr = ZEND_ADDR_REF_ZVAL(val_ref); - bool result_avoid_refcounting = 0; + bool result_avoid_refcounting = false; ZEND_ASSERT(opline->opcode == ZEND_FETCH_OBJ_R || opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG @@ -14701,12 +14710,12 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit, && (res_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) && (ssa_op+1)->op1_use == ssa_op->result_def && zend_jit_may_avoid_refcounting(opline+1, res_info)) { - result_avoid_refcounting = 1; + result_avoid_refcounting = true; ssa->var_info[ssa_op->result_def].avoid_refcounting = 1; } val_addr = zend_jit_guard_fetch_result_type(jit, opline, val_addr, type, - 1, flags, op1_avoid_refcounting); + true, flags, op1_avoid_refcounting); if (!val_addr) { return 0; } @@ -14806,6 +14815,13 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, ir_ref slow_inputs = IR_UNUSED; uint32_t res_info = RES_INFO(); + if (Z_MODE(val_addr) == IS_REG + && Z_LOAD(val_addr) + && jit->ra[Z_SSA_VAR(val_addr)].ref == IR_NULL) { + /* Force load */ + zend_jit_use_reg(jit, val_addr); + } + if (val_addr != val_def_addr && val_def_addr) { if (!zend_jit_update_regs(jit, (opline+1)->op1.var, val_addr, val_def_addr, val_info)) { return 0; @@ -14870,7 +14886,7 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, prop_info = zend_get_known_property_info(op_array, trace_ce, name, on_this, op_array->filename); if (prop_info) { ce = trace_ce; - ce_is_instanceof = 0; + ce_is_instanceof = false; if (!(op1_info & MAY_BE_CLASS_GUARD)) { if (on_this && JIT_G(current_frame) && TRACE_FRAME_IS_THIS_CLASS_CHECKED(JIT_G(current_frame))) { @@ -15035,7 +15051,7 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, if (Z_MODE(val_addr) != IS_REG && (res_addr == 0 || Z_MODE(res_addr) != IS_REG) && opline->result_type == IS_UNUSED) { - if (!zend_jit_assign_to_variable_call(jit, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, res_addr, 0)) { + if (!zend_jit_assign_to_variable_call(jit, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, res_addr, false)) { return 0; } } else { @@ -15046,7 +15062,7 @@ static int zend_jit_assign_obj(zend_jit_ctx *jit, } else { real_res_addr = res_addr; } - if (!zend_jit_assign_to_variable(jit, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, real_res_addr, 0, 0)) { + if (!zend_jit_assign_to_variable(jit, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, real_res_addr, 0, false)) { return 0; } } @@ -15152,8 +15168,8 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, zend_string *name; zend_property_info *prop_info; zend_jit_addr prop_addr; - bool use_prop_guard = 0; - bool may_throw = 0; + bool use_prop_guard = false; + bool may_throw = false; binary_op_type binary_op = get_binary_op(opline->extended_value); ir_ref obj_ref = IR_UNUSED; ir_ref prop_ref = IR_UNUSED; @@ -15202,7 +15218,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, jit_ZVAL_ADDR(jit, op1_addr), ir_CONST_ADDR(ZSTR_VAL(name))); - may_throw = 1; + may_throw = true; ir_END_list(end_inputs); ir_IF_TRUE(if_obj); @@ -15216,7 +15232,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, prop_info = zend_get_known_property_info(op_array, trace_ce, name, on_this, op_array->filename); if (prop_info) { ce = trace_ce; - ce_is_instanceof = 0; + ce_is_instanceof = false; if (!(op1_info & MAY_BE_CLASS_GUARD)) { if (on_this && JIT_G(current_frame) && TRACE_FRAME_IS_THIS_CLASS_CHECKED(JIT_G(current_frame))) { @@ -15314,7 +15330,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, if (ZEND_TYPE_IS_SET(prop_info->type)) { ir_ref if_ref, if_typed, noref_path, ref_path, reference, ref, arg2; - may_throw = 1; + may_throw = true; jit_SET_EX_OPLINE(jit, opline); @@ -15392,7 +15408,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, if (var_info & MAY_BE_REF) { ir_ref if_ref, if_typed, noref_path, ref_path, reference, ref, arg2; - may_throw = 1; + may_throw = true; if_ref = jit_if_Z_TYPE(jit, prop_addr, IS_REFERENCE); ir_IF_FALSE(if_ref); @@ -15446,7 +15462,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, if (opline->extended_value != ZEND_ADD || (var_info & MAY_BE_ANY) != MAY_BE_ARRAY || (val_info & MAY_BE_ANY) == MAY_BE_ARRAY) { - may_throw = 1; + may_throw = true; } } if (!zend_jit_math_helper(jit, opline, opline->extended_value, IS_CV, opline->op1, var_addr, var_info, val_op_type, (opline+1)->op1, val_addr, val_info, 0, var_addr, var_def_info, var_info, @@ -15461,7 +15477,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, (val_info & (MAY_BE_STRING|MAY_BE_DOUBLE|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { if ((var_info & MAY_BE_ANY) != MAY_BE_STRING || (val_info & MAY_BE_ANY) != MAY_BE_STRING) { - may_throw = 1; + may_throw = true; } } goto long_math; @@ -15469,23 +15485,23 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, case ZEND_SR: if ((var_info & (MAY_BE_STRING|MAY_BE_DOUBLE|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) || (val_info & (MAY_BE_STRING|MAY_BE_DOUBLE|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { - may_throw = 1; + may_throw = true; } if (val_op_type != IS_CONST || Z_TYPE_P(RT_CONSTANT((opline+1), (opline+1)->op1)) != IS_LONG || Z_LVAL_P(RT_CONSTANT((opline+1), (opline+1)->op1)) < 0) { - may_throw = 1; + may_throw = true; } goto long_math; case ZEND_MOD: if ((var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) || (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { - may_throw = 1; + may_throw = true; } if (val_op_type != IS_CONST || Z_TYPE_P(RT_CONSTANT((opline+1), (opline+1)->op1)) != IS_LONG || Z_LVAL_P(RT_CONSTANT((opline+1), (opline+1)->op1)) == 0) { - may_throw = 1; + may_throw = true; } long_math: if (!zend_jit_long_math_helper(jit, opline, opline->extended_value, @@ -15497,7 +15513,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, } break; case ZEND_CONCAT: - may_throw = 1; + may_throw = true; if (!zend_jit_concat_helper(jit, opline, IS_CV, opline->op1, var_addr, var_info, val_op_type, (opline+1)->op1, val_addr, val_info, var_addr, 0)) { return 0; @@ -15516,7 +15532,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, ir_MERGE_list(slow_inputs); - may_throw = 1; + may_throw = true; if (Z_MODE(val_addr) == IS_REG) { zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, (opline+1)->op1.var); @@ -15552,7 +15568,7 @@ static int zend_jit_assign_obj_op(zend_jit_ctx *jit, if (opline->op1_type != IS_UNUSED && !delayed_fetch_this && !op1_indirect) { if ((op1_info & MAY_HAVE_DTOR) && (op1_info & MAY_BE_RC1)) { - may_throw = 1; + may_throw = true; } jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline); } @@ -15584,8 +15600,8 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, zend_property_info *prop_info; zend_jit_addr res_addr = 0; zend_jit_addr prop_addr; - bool use_prop_guard = 0; - bool may_throw = 0; + bool use_prop_guard = false; + bool may_throw = false; uint32_t res_info = (opline->result_type != IS_UNDEF) ? RES_INFO() : 0; ir_ref obj_ref = IR_UNUSED; ir_ref prop_ref = IR_UNUSED; @@ -15646,7 +15662,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, prop_info = zend_get_known_property_info(op_array, trace_ce, name, on_this, op_array->filename); if (prop_info) { ce = trace_ce; - ce_is_instanceof = 0; + ce_is_instanceof = false; if (!(op1_info & MAY_BE_CLASS_GUARD)) { if (on_this && JIT_G(current_frame) && TRACE_FRAME_IS_THIS_CLASS_CHECKED(JIT_G(current_frame))) { @@ -15739,7 +15755,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, const void *func; ir_ref ref; - may_throw = 1; + may_throw = true; jit_SET_EX_OPLINE(jit, opline); if (ce && ce->ce_flags & ZEND_ACC_IMMUTABLE) { @@ -15844,7 +15860,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, ZEND_UNREACHABLE(); } - may_throw = 1; + may_throw = true; jit_SET_EX_OPLINE(jit, opline); ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(func), reference, @@ -15896,13 +15912,13 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, if (var_info & (MAY_BE_ANY - MAY_BE_LONG)) { if (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) { - may_throw = 1; + may_throw = true; } if (if_long) { ir_IF_FALSE_cold(if_long); } if (opline->opcode == ZEND_POST_INC_OBJ || opline->opcode == ZEND_POST_DEC_OBJ) { - jit_ZVAL_COPY(jit, res_addr, -1, var_addr, var_info, 1); + jit_ZVAL_COPY(jit, res_addr, -1, var_addr, var_info, true); } if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_POST_INC_OBJ) { if (opline->opcode == ZEND_PRE_INC_OBJ && opline->result_type != IS_UNUSED) { @@ -16012,7 +16028,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, ZEND_UNREACHABLE(); } - may_throw = 1; + may_throw = true; jit_SET_EX_OPLINE(jit, opline); ir_ref run_time_cache = ir_LOAD_A(jit_EX(run_time_cache)); ir_CALL_4(IR_VOID, ir_CONST_FC_FUNC(func), @@ -16030,7 +16046,7 @@ static int zend_jit_incdec_obj(zend_jit_ctx *jit, if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && !delayed_fetch_this && !op1_indirect) { if ((op1_info & MAY_HAVE_DTOR) && (op1_info & MAY_BE_RC1)) { - may_throw = 1; + may_throw = true; } jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline); } @@ -16092,7 +16108,7 @@ static int zend_jit_fetch_static_prop(zend_jit_ctx *jit, const zend_op *opline, case ZEND_FETCH_STATIC_PROP_UNSET: fetch_type = BP_VAR_UNSET; break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } // JIT: result = CACHED_PTR(cache_slot + sizeof(void *)); @@ -16711,10 +16727,10 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_ static int zend_jit_start(zend_jit_ctx *jit, const zend_op_array *op_array, zend_ssa *ssa) { - int i, count; + uint32_t i, count; zend_basic_block *bb; - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : (IR_START_BR_TARGET|IR_ENTRY_BR_TARGET)); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) ? 0 : (IR_START_BR_TARGET|IR_ENTRY_BR_TARGET)); jit->ctx.spill_base = ZREG_FP; @@ -16731,17 +16747,19 @@ static int zend_jit_start(zend_jit_ctx *jit, const zend_op_array *op_array, zend jit->bb_edges = zend_arena_calloc(&CG(arena), count, sizeof(ir_ref)); if (!GCC_GLOBAL_REGS) { - ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1); - ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2); - jit_STORE_FP(jit, execute_data_ref); - jit_STORE_IP(jit, opline_ref); + if (ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) { + ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1); + ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2); + jit_STORE_FP(jit, execute_data_ref); + jit_STORE_IP(jit, opline_ref); + } jit->ctx.flags |= IR_FASTCALL_FUNC; } return 1; } -static void *zend_jit_finish(zend_jit_ctx *jit) +static zend_vm_opcode_handler_t zend_jit_finish(zend_jit_ctx *jit) { void *entry; size_t size; @@ -16792,7 +16810,7 @@ static void *zend_jit_finish(zend_jit_ctx *jit) // ir_mem_unprotect(entry, size); if (!(jit->ctx.flags & IR_FUNCTION) - && zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + && ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { #if !defined(ZEND_WIN32) && !defined(IR_TARGET_AARCH64) sp_offset = zend_jit_hybrid_vm_sp_adj; #else @@ -16825,14 +16843,14 @@ static void *zend_jit_finish(zend_jit_ctx *jit) opline++; } } - opline->handler = entry; + opline->handler = (zend_vm_opcode_handler_t)entry; if (jit->ctx.entries_count) { /* For all entries */ int i = jit->ctx.entries_count; do { ir_insn *insn = &jit->ctx.ir_base[jit->ctx.entries[--i]]; - op_array->opcodes[insn->op2].handler = (char*)entry + insn->op3; + op_array->opcodes[insn->op2].handler = (zend_vm_opcode_handler_t)((char*)entry + insn->op3); } while (i != 0); } } else { @@ -16859,7 +16877,7 @@ static void *zend_jit_finish(zend_jit_ctx *jit) zend_string_release(str); } - return entry; + return (zend_vm_opcode_handler_t)entry; } static const void *zend_jit_trace_allocate_exit_group(uint32_t n) @@ -16928,11 +16946,11 @@ static bool zend_jit_noref_guard(zend_jit_ctx *jit, const zend_op *opline, zend_ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!exit_addr) { - return 0; + return false; } ir_GUARD(ir_NE(jit_Z_TYPE(jit, var_addr), ir_CONST_U8(IS_REFERENCE)), ir_CONST_ADDR(exit_addr)); - return 1; + return true; } static int zend_jit_trace_opline_guard(zend_jit_ctx *jit, const zend_op *opline) @@ -16965,7 +16983,7 @@ static bool zend_jit_guard_reference(zend_jit_ctx *jit, exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!exit_addr) { - return 0; + return false; } ref = jit_Z_TYPE(jit, var_addr); @@ -16978,7 +16996,7 @@ static bool zend_jit_guard_reference(zend_jit_ctx *jit, var_addr = ZEND_ADDR_REF_ZVAL(ref); *var_addr_ptr = var_addr; - return 1; + return true; } static bool zend_jit_fetch_reference(zend_jit_ctx *jit, @@ -16999,7 +17017,7 @@ static bool zend_jit_fetch_reference(zend_jit_ctx *jit, exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!exit_addr) { - return 0; + return false; } } @@ -17044,7 +17062,7 @@ static bool zend_jit_fetch_reference(zend_jit_ctx *jit, } *var_info_ptr |= MAY_BE_GUARD; /* prevent generation of specialized zval dtor */ - return 1; + return true; } static bool zend_jit_fetch_indirect_var(zend_jit_ctx *jit, const zend_op *opline, uint8_t var_type, uint32_t *var_info_ptr, zend_jit_addr *var_addr_ptr, bool add_indirect_guard) @@ -17060,7 +17078,7 @@ static bool zend_jit_fetch_indirect_var(zend_jit_ctx *jit, const zend_op *opline const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!exit_addr) { - return 0; + return false; } jit_guard_Z_TYPE(jit, var_addr, IS_INDIRECT, exit_addr); ref = jit_Z_PTR(jit, var_addr); @@ -17083,7 +17101,7 @@ static bool zend_jit_fetch_indirect_var(zend_jit_ctx *jit, const zend_op *opline exit_addr = zend_jit_trace_get_exit_addr(exit_point); if (!exit_addr) { - return 0; + return false; } jit_guard_Z_TYPE(jit, var_addr, var_type, exit_addr); @@ -17101,7 +17119,7 @@ static bool zend_jit_fetch_indirect_var(zend_jit_ctx *jit, const zend_op *opline *var_info_ptr = var_info; } - return 1; + return true; } static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_array, const zend_op *opline, int may_throw, zend_jit_trace_rec *trace) @@ -17109,8 +17127,8 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr zend_jit_op_array_trace_extension *jit_extension = (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array); size_t offset = jit_extension->offset; - const void *handler = - (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->call_handler; + zend_vm_opcode_handler_func_t handler = + ZEND_OP_TRACE_INFO(opline, offset)->call_handler; ir_ref ref; zend_jit_set_ip(jit, opline); @@ -17123,7 +17141,8 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr opline->opcode == ZEND_DO_UCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME || opline->opcode == ZEND_DO_FCALL || - opline->opcode == ZEND_GENERATOR_CREATE) { + opline->opcode == ZEND_GENERATOR_CREATE || + opline->opcode == ZEND_INCLUDE_OR_EVAL) { jit_STORE_IP(jit, ir_AND_A(ref, ir_CONST_ADDR(~ZEND_VM_ENTER_BIT))); } else { @@ -17140,14 +17159,16 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr trace++; } - if (!GCC_GLOBAL_REGS - && (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN)) { + if ((!GCC_GLOBAL_REGS + && (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN)) + || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF || opline->opcode == ZEND_DO_UCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME || opline->opcode == ZEND_DO_FCALL || - opline->opcode == ZEND_GENERATOR_CREATE) { + opline->opcode == ZEND_GENERATOR_CREATE || + opline->opcode == ZEND_INCLUDE_OR_EVAL) { ir_ref addr = jit_EG(current_execute_data); @@ -17160,7 +17181,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr opline->opcode == ZEND_RETURN_BY_REF || opline->opcode == ZEND_GENERATOR_CREATE) { - if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) { if (trace->op != ZEND_JIT_TRACE_END || (trace->stop != ZEND_JIT_TRACE_STOP_RETURN && trace->stop < ZEND_JIT_TRACE_STOP_INTERPRETER)) { @@ -17191,7 +17212,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr zend_jit_trace_stack *stack = JIT_G(current_frame)->stack; if (zend_is_smart_branch(opline)) { - bool exit_if_true = 0; + bool exit_if_true = false; exit_opline = zend_jit_trace_get_exit_opline(trace, opline + 1, &exit_if_true); } else { switch (opline->opcode) { @@ -17226,6 +17247,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var), IS_UNKNOWN, 1); } break; + case ZEND_FE_RESET_RW: case ZEND_BIND_INIT_STATIC_OR_JMP: if (opline->op1_type == IS_CV) { old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var)); @@ -17250,6 +17272,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->op2.var), old_info); } break; + case ZEND_FE_RESET_RW: case ZEND_BIND_INIT_STATIC_OR_JMP: if (opline->op1_type == IS_CV) { SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var), old_info); @@ -17274,7 +17297,7 @@ static int zend_jit_deoptimizer_start(zend_jit_ctx *jit, uint32_t trace_num, uint32_t exit_num) { - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) ? 0 : IR_START_BR_TARGET); jit->ctx.spill_base = ZREG_FP; @@ -17295,7 +17318,7 @@ static int zend_jit_trace_start(zend_jit_ctx *jit, zend_jit_trace_info *parent, uint32_t exit_num) { - zend_jit_init_ctx(jit, (zend_jit_vm_kind == ZEND_VM_KIND_CALL) ? 0 : IR_START_BR_TARGET); + zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) ? 0 : IR_START_BR_TARGET); jit->ctx.spill_base = ZREG_FP; @@ -17306,10 +17329,12 @@ static int zend_jit_trace_start(zend_jit_ctx *jit, if (!GCC_GLOBAL_REGS) { if (!parent) { - ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1); - ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2); - jit_STORE_FP(jit, execute_data_ref); - jit_STORE_IP(jit, opline_ref); + if (ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) { + ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1); + ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2); + jit_STORE_FP(jit, execute_data_ref); + jit_STORE_IP(jit, opline_ref); + } jit->ctx.flags |= IR_FASTCALL_FUNC; } } @@ -17412,11 +17437,11 @@ static int zend_jit_trace_end_loop(zend_jit_ctx *jit, int loop_ref, const void * static int zend_jit_trace_return(zend_jit_ctx *jit, bool original_handler, const zend_op *opline) { - if (GCC_GLOBAL_REGS) { + if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) { if (!original_handler) { - ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit))); + zend_jit_tailcall_handler(jit, ir_LOAD_A(jit_IP(jit))); } else { - ir_TAILCALL(IR_VOID, zend_jit_orig_opline_handler(jit)); + zend_jit_tailcall_handler(jit, zend_jit_orig_opline_handler(jit)); } } else { if (original_handler) { @@ -17427,16 +17452,8 @@ static int zend_jit_trace_return(zend_jit_ctx *jit, bool original_handler, const addr = ir_CAST_FC_FUNC(addr); #endif ref = ir_CALL_2(IR_ADDR, addr, jit_FP(jit), jit_IP(jit)); - if (opline && - (opline->opcode == ZEND_RETURN - || opline->opcode == ZEND_RETURN_BY_REF - || opline->opcode == ZEND_GENERATOR_RETURN - || opline->opcode == ZEND_GENERATOR_CREATE - || opline->opcode == ZEND_YIELD - || opline->opcode == ZEND_YIELD_FROM)) { - zend_jit_vm_enter(jit, ref); - return 1; - } + zend_jit_vm_enter(jit, ref); + return 1; } zend_jit_vm_enter(jit, jit_IP(jit)); } @@ -17481,14 +17498,14 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: case ZEND_CASE: - return 1; + return true; case ZEND_RETURN: return (op_array->type != ZEND_EVAL_CODE && op_array->function_name); case ZEND_ASSIGN: return (opline->op1_type == IS_CV); case ZEND_ASSIGN_OP: if (opline->op1_type != IS_CV || opline->result_type != IS_UNUSED) { - return 0; + return false; } op1_info = OP1_INFO(); op2_info = OP2_INFO(); @@ -17499,7 +17516,7 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa op1_info = OP1_INFO(); op2_info = OP2_INFO(); if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) { - return 0; + return false; } if (trace && trace->op1_type != IS_UNKNOWN) { op1_info &= 1U << (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED)); @@ -17547,11 +17564,11 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa case ZEND_JMPNZ: if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) { if (!ssa->cfg.map) { - return 0; + return false; } if (opline > op_array->opcodes + ssa->cfg.blocks[ssa->cfg.map[opline-op_array->opcodes]].start && ((opline-1)->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) { - return 0; + return false; } } ZEND_FALLTHROUGH; @@ -17559,12 +17576,12 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa case ZEND_BOOL_NOT: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: - return 1; + return true; case ZEND_FETCH_CONSTANT: - return 1; + return true; case ZEND_ISSET_ISEMPTY_DIM_OBJ: if ((opline->extended_value & ZEND_ISEMPTY)) { - return 0; + return false; } ZEND_FALLTHROUGH; case ZEND_FETCH_DIM_R: @@ -17582,10 +17599,10 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa ((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING)); case ZEND_ASSIGN_DIM_OP: if (opline->result_type != IS_UNUSED) { - return 0; + return false; } if (!zend_jit_supported_binary_op(opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) { - return 0; + return false; } ZEND_FALLTHROUGH; case ZEND_ASSIGN_DIM: @@ -17601,13 +17618,13 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa && (opline+1)->op1_type == IS_CV && (opline+1)->op1.var == opline->op1.var) { /* skip $a[x] = $a; */ - return 0; + return false; } } else if (opline->op1_type == IS_VAR) { if (trace->op1_type == IS_UNKNOWN || !(trace->op1_type & IS_TRACE_INDIRECT) || opline->result_type != IS_UNUSED) { - return 0; + return false; } } if (trace->op1_type != IS_UNKNOWN @@ -17616,7 +17633,7 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa } } else { if (opline->op1_type != IS_CV) { - return 0; + return false; } } return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) && @@ -17624,10 +17641,10 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa ((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING)); case ZEND_ASSIGN_OBJ_OP: if (opline->result_type != IS_UNUSED) { - return 0; + return false; } if (!zend_jit_supported_binary_op(opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) { - return 0; + return false; } ZEND_FALLTHROUGH; case ZEND_FETCH_OBJ_R: @@ -17635,19 +17652,19 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa if (opline->op2_type != IS_CONST || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { - return 0; + return false; } op1_info = OP1_INFO(); return opline->op1_type == IS_UNUSED || (op1_info & MAY_BE_OBJECT); } - return 0; + return false; } static bool zend_jit_var_supports_reg(zend_ssa *ssa, int var) { if (ssa->vars[var].no_val) { /* we don't need the value */ - return 0; + return false; } if (!(JIT_G(opt_flags) & ZEND_JIT_REG_ALLOC_GLOBAL)) { @@ -17655,13 +17672,13 @@ static bool zend_jit_var_supports_reg(zend_ssa *ssa, int var) * register allocation for SSA variables connected through Phi functions */ if (ssa->vars[var].definition_phi) { - return 0; + return false; } if (ssa->vars[var].phi_use_chain) { zend_ssa_phi *phi = ssa->vars[var].phi_use_chain; do { if (!ssa->vars[phi->ssa_var].no_val) { - return 0; + return false; } phi = zend_ssa_next_use_phi(ssa, var, phi); } while (phi); @@ -17671,22 +17688,22 @@ static bool zend_jit_var_supports_reg(zend_ssa *ssa, int var) if (((ssa->var_info[var].type & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_DOUBLE) && ((ssa->var_info[var].type & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_LONG)) { /* bad type */ - return 0; + return false; } - return 1; + return true; } static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa, int var) { if (!zend_jit_var_supports_reg(ssa, var)) { - return 0; + return false; } if (ssa->vars[var].definition >= 0) { uint32_t def = ssa->vars[var].definition; if (!zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + def, ssa->ops + def, NULL)) { - return 0; + return false; } } @@ -17696,17 +17713,19 @@ static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa, do { if (!zend_ssa_is_no_val_use(op_array->opcodes + use, ssa->ops + use, var) && !zend_jit_opline_supports_reg(op_array, ssa, op_array->opcodes + use, ssa->ops + use, NULL)) { - return 0; + return false; } use = zend_ssa_next_use(ssa->ops, var, use); } while (use >= 0); } if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) { - int def_block, use_block, b, use, j; + uint32_t def_block, use_block; + int b, use; + uint32_t j; zend_basic_block *bb; zend_ssa_phi *p; - bool ret = 1; + bool ret = true; zend_worklist worklist; ALLOCA_FLAG(use_heap) @@ -17752,7 +17771,7 @@ static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa, b = zend_worklist_pop(&worklist); bb = &ssa->cfg.blocks[b]; if (bb->flags & (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY)) { - ret = 0; + ret = false; break; } for (j = 0; j < bb->predecessors_count; j++) { @@ -17768,7 +17787,7 @@ static bool zend_jit_may_be_in_reg(const zend_op_array *op_array, zend_ssa *ssa, return ret; } - return 1; + return true; } static ir_ref jit_frameless_observer(zend_jit_ctx *jit, const zend_op *opline) { @@ -17825,7 +17844,7 @@ static void jit_frameless_icall1(zend_jit_ctx *jit, const zend_op *opline, uint3 ir_ref op1_ref = jit_ZVAL_ADDR(jit, op1_addr); jit_set_Z_TYPE_INFO(jit, res_addr, IS_NULL); if (opline->op1_type == IS_CV && (op1_info & MAY_BE_UNDEF)) { - op1_ref = zend_jit_zval_check_undef(jit, op1_ref, opline->op1.var, opline, 1); + op1_ref = zend_jit_zval_check_undef(jit, op1_ref, opline->op1.var, opline, true); op1_info &= ~MAY_BE_UNDEF; op1_info |= MAY_BE_NULL; op1_addr = ZEND_ADDR_REF_ZVAL(op1_ref); @@ -17870,13 +17889,13 @@ static void jit_frameless_icall2(zend_jit_ctx *jit, const zend_op *opline, uint3 ir_ref op2_ref = jit_ZVAL_ADDR(jit, op2_addr); jit_set_Z_TYPE_INFO(jit, res_addr, IS_NULL); if (opline->op1_type == IS_CV && (op1_info & MAY_BE_UNDEF)) { - op1_ref = zend_jit_zval_check_undef(jit, op1_ref, opline->op1.var, opline, 1); + op1_ref = zend_jit_zval_check_undef(jit, op1_ref, opline->op1.var, opline, true); op1_info &= ~MAY_BE_UNDEF; op1_info |= MAY_BE_NULL; op1_addr = ZEND_ADDR_REF_ZVAL(op1_ref); } if (opline->op2_type == IS_CV && (op2_info & MAY_BE_UNDEF)) { - op2_ref = zend_jit_zval_check_undef(jit, op2_ref, opline->op2.var, opline, 1); + op2_ref = zend_jit_zval_check_undef(jit, op2_ref, opline->op2.var, opline, true); op2_info &= ~MAY_BE_UNDEF; op2_info |= MAY_BE_NULL; op2_addr = ZEND_ADDR_REF_ZVAL(op2_ref); @@ -17942,19 +17961,19 @@ static void jit_frameless_icall3(zend_jit_ctx *jit, const zend_op *opline, uint3 ir_ref op3_ref = jit_ZVAL_ADDR(jit, op3_addr); jit_set_Z_TYPE_INFO(jit, res_addr, IS_NULL); if (opline->op1_type == IS_CV && (op1_info & MAY_BE_UNDEF)) { - op1_ref = zend_jit_zval_check_undef(jit, op1_ref, opline->op1.var, opline, 1); + op1_ref = zend_jit_zval_check_undef(jit, op1_ref, opline->op1.var, opline, true); op1_info &= ~MAY_BE_UNDEF; op1_info |= MAY_BE_NULL; op1_addr = ZEND_ADDR_REF_ZVAL(op1_ref); } if (opline->op2_type == IS_CV && (op2_info & MAY_BE_UNDEF)) { - op2_ref = zend_jit_zval_check_undef(jit, op2_ref, opline->op2.var, opline, 1); + op2_ref = zend_jit_zval_check_undef(jit, op2_ref, opline->op2.var, opline, true); op2_info &= ~MAY_BE_UNDEF; op2_info |= MAY_BE_NULL; op2_addr = ZEND_ADDR_REF_ZVAL(op2_ref); } if ((opline+1)->op1_type == IS_CV && (op1_data_info & MAY_BE_UNDEF)) { - op3_ref = zend_jit_zval_check_undef(jit, op3_ref, (opline+1)->op1.var, opline, 1); + op3_ref = zend_jit_zval_check_undef(jit, op3_ref, (opline+1)->op1.var, opline, true); op1_data_info &= ~MAY_BE_UNDEF; op1_data_info |= MAY_BE_NULL; op3_addr = ZEND_ADDR_REF_ZVAL(op3_ref); diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index aeec674d60f3..d5d1f5b4238b 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -20,6 +18,7 @@ #include "zend_jit_internal.h" #include "zend_shared_alloc.h" #include "ir/ir.h" +#include "zend_vm_opcodes.h" static zend_jit_trace_info *zend_jit_traces = NULL; static const void **zend_jit_exit_groups = NULL; @@ -131,7 +130,7 @@ static uint32_t zend_jit_exit_point_by_addr(const void *addr) return (uint32_t)-1; } -static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags) +static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags ZEND_FILE_LINE_DC) { zend_jit_trace_info *t = &zend_jit_traces[ZEND_JIT_TRACE_NUM]; uint32_t exit_point; @@ -177,7 +176,13 @@ static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t && memcmp(t->stack_map + t->exit_info[i].stack_offset, stack, stack_size * sizeof(zend_jit_trace_stack)) == 0)) { if (t->exit_info[i].opline == to_opline && t->exit_info[i].flags == flags - && t->exit_info[i].stack_size == stack_size) { + && t->exit_info[i].stack_size == stack_size +#if ZEND_DEBUG + && (((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC) == 0) + || (strcmp(t->exit_info[i].filename, __zend_filename) == 0 + && t->exit_info[i].lineno == __zend_lineno)) +#endif + ) { return i; } } @@ -201,6 +206,15 @@ static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t t->exit_info[exit_point].stack_offset = stack_offset; t->exit_info[exit_point].poly_func = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; t->exit_info[exit_point].poly_this = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; +#if ZEND_DEBUG + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC) != 0) { + t->exit_info[exit_point].filename = __zend_filename; + t->exit_info[exit_point].lineno = __zend_lineno; + } else { + t->exit_info[exit_point].filename = NULL; + t->exit_info[exit_point].lineno = 0; + } +#endif } return exit_point; @@ -242,14 +256,14 @@ static zend_string *zend_jit_trace_name(const zend_op_array *op_array, uint32_t smart_str_appendc(&buf, '$'); if (op_array->function_name) { if (op_array->scope) { - smart_str_appendl(&buf, ZSTR_VAL(op_array->scope->name), ZSTR_LEN(op_array->scope->name)); + smart_str_append(&buf, op_array->scope->name); smart_str_appends(&buf, "::"); - smart_str_appendl(&buf, ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)); + smart_str_append(&buf, op_array->function_name); } else { - smart_str_appendl(&buf, ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)); + smart_str_append(&buf, op_array->function_name); } } else if (op_array->filename) { - smart_str_appendl(&buf, ZSTR_VAL(op_array->filename), ZSTR_LEN(op_array->filename)); + smart_str_append(&buf, op_array->filename); } smart_str_appendc(&buf, '$'); smart_str_append_long(&buf, (zend_long)lineno); @@ -477,7 +491,7 @@ static bool zend_jit_needs_arg_dtor(const zend_function *func, uint32_t arg_num, && func->type == ZEND_INTERNAL_FUNCTION && (func->internal_function.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0 && arg_num < func->internal_function.num_args) { - const zend_internal_arg_info *arg_info = &func->internal_function.arg_info[arg_num]; + const zend_arg_info *arg_info = &func->internal_function.arg_info[arg_num]; if (ZEND_ARG_SEND_MODE(arg_info) == ZEND_SEND_BY_VAL && ZEND_TYPE_IS_SET(arg_info->type) @@ -491,7 +505,7 @@ static bool zend_jit_needs_arg_dtor(const zend_function *func, uint32_t arg_num, if (type != IS_UNKNOWN && type < IS_STRING && ZEND_TYPE_FULL_MASK(arg_info->type) & (1u << type)) { - return 0; + return false; } } if (call_info && arg_num < call_info->num_args && call_info->arg_info[arg_num].opline) { @@ -506,7 +520,7 @@ static bool zend_jit_needs_arg_dtor(const zend_function *func, uint32_t arg_num, // TODO: few functions (e.g. pcntl_exec) modify arrays in-place ??? if (type != IS_ARRAY && (ZEND_TYPE_FULL_MASK(arg_info->type) & (1u << type))) { - return 0; + return false; } } } @@ -514,7 +528,7 @@ static bool zend_jit_needs_arg_dtor(const zend_function *func, uint32_t arg_num, } } - return 1; + return true; } static zend_ssa *zend_jit_trace_build_ssa(const zend_op_array *op_array, zend_script *script) @@ -801,7 +815,7 @@ static bool zend_jit_trace_is_false_loop(const zend_op_array *op_array, const ze bb = ssa->cfg.blocks + ssa->cfg.map[opline - op_array->opcodes]; return bb->loop_header != b; } else { - return 0; + return false; } } @@ -2345,6 +2359,9 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin if (ssa_ops[idx].op2_use >= 0 && ssa_ops[idx].op2_def >= 0) { ssa_var_info[ssa_ops[idx].op2_def] = ssa_var_info[ssa_ops[idx].op2_use]; } + if (ssa_ops[idx].result_use >= 0 && ssa_ops[idx].result_def >= 0) { + ssa_var_info[ssa_ops[idx].result_def] = ssa_var_info[ssa_ops[idx].result_use]; + } } else { if (zend_update_type_info(op_array, tssa, script, (zend_op*)opline, ssa_ops + idx, ssa_opcodes, optimization_level) == FAILURE) { // TODO: @@ -2949,7 +2966,7 @@ static zend_jit_reg_var* zend_jit_trace_allocate_registers(zend_jit_trace_rec *t && ssa_op->op1_def >= 0 && ssa->vars[ssa_op->op1_def].alias != NO_ALIAS) { /* avoid register allocation in case of possibility of indirect modification*/ - support_opline = 0; + support_opline = false; } if (ssa_op->op1_use >= 0 @@ -3409,7 +3426,7 @@ static void zend_jit_trace_setup_ret_counter(const zend_op *opline, size_t offse ZEND_JIT_COUNTER_NUM = (ZEND_JIT_COUNTER_NUM + 1) % ZEND_HOT_COUNTERS_COUNT; } ZEND_OP_TRACE_INFO(next_opline, offset)->trace_flags = ZEND_JIT_TRACE_START_RETURN; - next_opline->handler = (const void*)zend_jit_ret_trace_counter_handler; + next_opline->handler = zend_jit_ret_trace_counter_handler; } } @@ -3424,7 +3441,7 @@ static bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ss || ssa->vars[var].phi_use_chain || ssa->ops[use].op1_use != var || ssa->ops[use].op1_use_chain != -1) { - return 0; + return false; } opline = ssa_opcodes[use]; @@ -3436,7 +3453,7 @@ static bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ss || !JIT_G(current_frame)->call || !JIT_G(current_frame)->call->func || !TRACE_FRAME_IS_LAST_SEND_BY_VAL(JIT_G(current_frame)->call)) { - return 0; + return false; } } else if (opline->opcode != ZEND_FETCH_OBJ_R && opline->opcode != ZEND_FETCH_OBJ_IS @@ -3447,13 +3464,13 @@ static bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ss && opline->opcode != ZEND_PRE_DEC_OBJ && opline->opcode != ZEND_POST_INC_OBJ && opline->opcode != ZEND_POST_DEC_OBJ) { - return 0; + return false; } if (opline->op2_type != IS_CONST || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { - return 0; + return false; } if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { @@ -3461,11 +3478,11 @@ static bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ss && (opline+1)->op1_type == IS_CV && (opline+1)->op1.var == opline->op1.var) { /* skip $a->prop += $a; */ - return 0; + return false; } if (!zend_jit_supported_binary_op( opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) { - return 0; + return false; } } @@ -3474,11 +3491,11 @@ static bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ss || ssa_opcodes[i]->opcode == ZEND_DO_FCALL_BY_NAME || ssa_opcodes[i]->opcode == ZEND_DO_FCALL || ssa_opcodes[i]->opcode == ZEND_INCLUDE_OR_EVAL) { - return 0; + return false; } } - return 1; + return true; } static int zend_jit_trace_stack_needs_deoptimization(zend_jit_trace_stack *stack, uint32_t stack_size) @@ -3633,7 +3650,7 @@ static int zend_jit_trace_deoptimization( ZEND_ASSERT(STACK_FLAGS(parent_stack, check2) == ZREG_ZVAL_COPY); ZEND_ASSERT(reg != ZREG_NONE); - if (!zend_jit_escape_if_undef(jit, check2, flags, opline, reg)) { + if (!zend_jit_escape_if_undef(jit, check2, flags, opline, exit_info->op_array, reg)) { return 0; } if (!zend_jit_restore_zval(jit, EX_NUM_TO_VAR(check2), reg)) { @@ -3888,19 +3905,19 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o || prev_opcode == ZEND_CASE_STRICT) { if (ssa_op->op1_use < 0) { if (RT_CONSTANT(opline, opline->op1) != RT_CONSTANT(&ssa_opcodes[prev_ssa_op - ssa->ops], ssa_opcodes[prev_ssa_op - ssa->ops]->op1)) { - return 0; + return false; } } if (ssa_op->op2_use < 0) { if (RT_CONSTANT(opline, opline->op2) != RT_CONSTANT(&ssa_opcodes[prev_ssa_op - ssa->ops], ssa_opcodes[prev_ssa_op - ssa->ops]->op2)) { - return 0; + return false; } } - return 1; + return true; } } } - return 0; + return false; } static bool zend_jit_trace_next_is_send_result(const zend_op *opline, @@ -3927,9 +3944,9 @@ static bool zend_jit_trace_next_is_send_result(const zend_op *oplin zend_jit_trace_send_type(opline+1, frame->call, res_type); } } - return 1; + return true; } - return 0; + return false; } static int zend_jit_find_ssa_var(const zend_op_array *op_array, @@ -3937,7 +3954,7 @@ static int zend_jit_find_ssa_var(const zend_op_array *op_array, uint32_t opline_num, uint32_t var_num) { - int ssa_var, j, b = ssa->cfg.map[opline_num]; + int ssa_var, b = ssa->cfg.map[opline_num]; const zend_basic_block *bb = ssa->cfg.blocks + b; const zend_ssa_phi *phi; const zend_ssa_op *ssa_op; @@ -3981,7 +3998,7 @@ static int zend_jit_find_ssa_var(const zend_op_array *op_array, ZEND_WORKLIST_ALLOCA(&worklist, ssa->cfg.blocks_count, use_heap); - for (j = 0; j < bb->predecessors_count; j++) { + for (uint32_t j = 0; j < bb->predecessors_count; j++) { b = ssa->cfg.predecessors[bb->predecessor_offset + j]; zend_worklist_push(&worklist, b); } @@ -4022,7 +4039,7 @@ static int zend_jit_find_ssa_var(const zend_op_array *op_array, if (ssa_var >= 0) { goto found; } - for (j = 0; j < bb->predecessors_count; j++) { + for (uint32_t j = 0; j < bb->predecessors_count; j++) { b = ssa->cfg.predecessors[bb->predecessor_offset + j]; zend_worklist_push(&worklist, b); } @@ -4045,11 +4062,11 @@ static bool zend_jit_trace_must_store_type(const zend_op_array *op_array, if (ssa_var >= 0) { if ((ssa->var_info[ssa_var].type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1U << type)) { - return 0; + return false; } } } - return 1; + return true; } static bool zend_jit_trace_may_throw(const zend_op *opline, @@ -4070,7 +4087,7 @@ static bool zend_jit_trace_may_throw(const zend_op *opline, && !(t1 & MAY_BE_ARRAY_OF_REF) && (t2 & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_LONG && (t3 & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_LONG) { - return 0; + return false; } break; default: @@ -4079,9 +4096,9 @@ static bool zend_jit_trace_may_throw(const zend_op *opline, return zend_may_throw_ex(opline, ssa_op, op_array, ssa, t1, t2); } -static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num) +static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num) { - const void *handler = NULL; + zend_vm_opcode_handler_t handler = NULL; zend_jit_ctx ctx; zend_jit_ctx *jit = &ctx; zend_jit_reg_var *ra = NULL; @@ -4094,6 +4111,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par zend_jit_trace_rec *p; zend_jit_op_array_trace_extension *jit_extension; int num_op_arrays = 0; + bool do_bailout = 0; zend_jit_trace_info *t; const zend_op_array *op_arrays[ZEND_JIT_TRACE_MAX_FUNCS]; uint8_t smart_branch_opcode; @@ -4124,6 +4142,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par checkpoint = zend_arena_checkpoint(CG(arena)); + zend_try { + ssa = zend_jit_trace_build_tssa(trace_buffer, parent_trace, exit_num, script, op_arrays, &num_op_arrays); if (!ssa) { @@ -4537,6 +4557,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op2_info = OP2_INFO(); op2_addr = OP2_REG_ADDR(); if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) { + if (op1_type == IS_LONG || op1_type == IS_DOUBLE) { + CHECK_OP1_TRACE_TYPE(); + } + if (op2_type == IS_LONG || op2_type == IS_DOUBLE) { + CHECK_OP2_TRACE_TYPE(); + } break; } if (opline->opcode == ZEND_ADD && @@ -4545,6 +4571,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par /* pass */ } else if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) || !(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) { + if (op1_type == IS_LONG || op1_type == IS_DOUBLE) { + CHECK_OP1_TRACE_TYPE(); + } + if (op2_type == IS_LONG || op2_type == IS_DOUBLE) { + CHECK_OP2_TRACE_TYPE(); + } break; } if (orig_op1_type != IS_UNKNOWN @@ -5187,7 +5219,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par && ssa->vars[ssa_op->op2_def].use_chain < 0 && !ssa->vars[ssa_op->op2_def].phi_use_chain) { if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -5240,7 +5272,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par && ssa->vars[ssa_op->op1_def].use_chain < 0 && !ssa->vars[ssa_op->op1_def].phi_use_chain) { if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -5337,7 +5369,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par && ssa->vars[ssa_op->op1_def].use_chain < 0 && !ssa->vars[ssa_op->op1_def].phi_use_chain) { if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -5614,6 +5646,20 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } } } + /* The inline CV-free loop above bypasses the + * zend_free_compiled_variables path that destroys + * EX(type_args), so a generic-call frame with a + * non-cached (frame-owned) type-arg table would + * leak it on every return. Mirror the slow path. */ + if (!left_frame) { + if (!zend_jit_leave_frame(&ctx)) { + goto jit_failure; + } + left_frame = 1; + } + if (!zend_jit_free_type_args(&ctx)) { + goto jit_failure; + } if (!zend_jit_leave_func(&ctx, op_array, opline, op1_info, left_frame, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM], (op_array_ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0, may_throw)) { @@ -6564,10 +6610,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par uint32_t var_num = opline->result.var; uint32_t op_num = opline - op_array->opcodes; const zend_live_range *range = op_array->live_range; - int j; op_num += zend_jit_trace_op_len(opline); - for (j = 0; j < op_array->last_live_range; range++, j++) { + for (uint32_t j = 0; j < op_array->last_live_range; range++, j++) { if (range->start > op_num) { /* further blocks will not be relevant... */ break; @@ -6597,7 +6642,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par var_num = EX_VAR_TO_NUM(var_num); if (!zend_jit_store_type(&ctx, var_num, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, var_num, type, 1); } @@ -7236,7 +7281,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par && type != STACK_MEM_TYPE(stack, i) && zend_jit_trace_must_store_type(op_array, op_array_ssa, opline - op_array->opcodes, i, type)) { if (!zend_jit_store_type(jit, i, type)) { - return 0; + goto jit_failure; } SET_STACK_TYPE(stack, i, type, 1); } @@ -7357,7 +7402,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par zend_string_release(name); } -jit_cleanup: +jit_cleanup:; + } zend_catch { + do_bailout = 1; + } zend_end_try(); + /* Clean up used op_arrays */ while (num_op_arrays > 0) { op_array = op_arrays[--num_op_arrays]; @@ -7377,6 +7426,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par JIT_G(current_frame) = NULL; JIT_G(current_trace) = NULL; + if (do_bailout) { + zend_bailout(); + } + return handler; } @@ -7392,16 +7445,16 @@ static zend_string *zend_jit_trace_escape_name(uint32_t trace_num, uint32_t exit return buf.s; } -static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_num) +static zend_vm_opcode_handler_t zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_num) { - const void *handler = NULL; + zend_vm_opcode_handler_t handler = NULL; zend_jit_ctx ctx; zend_string *name; void *checkpoint; const zend_op *opline; uint32_t stack_size; zend_jit_trace_stack *stack; - bool original_handler = 0; + bool original_handler = false; if (!zend_jit_trace_exit_needs_deoptimization(trace_num, exit_num)) { return zend_jit_stub_handlers[jit_stub_trace_escape]; @@ -7426,7 +7479,7 @@ static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_n &zend_jit_traces[trace_num].exit_info[exit_num], stack, stack_size, NULL, NULL, zend_jit_traces[trace_num].constants, - 0)) { + false)) { goto jit_failure; } @@ -7438,7 +7491,7 @@ static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_n if (ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->orig_handler != opline->handler) { /* prevent endless loop */ - original_handler = 1; + original_handler = true; } } zend_jit_set_ip(&ctx, opline); @@ -7458,7 +7511,7 @@ static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_n static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace_buffer, const zend_op *opline, size_t offset) { zend_jit_trace_stop ret; - const void *handler; + zend_vm_opcode_handler_t handler; uint8_t orig_trigger; zend_jit_trace_info *t = NULL; zend_jit_trace_exit_info exit_info[ZEND_JIT_TRACE_MAX_EXITS]; @@ -7747,7 +7800,7 @@ static bool zend_jit_trace_is_bad_root(const zend_op *opline, zend_jit_trace_sto if (cache_opline[i] == opline) { if (cache_count[i] >= JIT_G(blacklist_root_trace) - 1) { cache_opline[i] = NULL; - return 1; + return true; } else { #if 0 if (ZEND_OP_TRACE_INFO(opline, offset)->counter) { @@ -7757,7 +7810,7 @@ static bool zend_jit_trace_is_bad_root(const zend_op *opline, zend_jit_trace_sto #endif cache_count[i]++; cache_stop[i] = stop; - return 0; + return false; } } } @@ -7767,7 +7820,7 @@ static bool zend_jit_trace_is_bad_root(const zend_op *opline, zend_jit_trace_sto cache_stop[i] = stop; cache_slot = (i + 1) % ZEND_JIT_TRACE_BAD_ROOT_SLOTS; JIT_G(bad_root_slot) = cache_slot; - return 0; + return false; } static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa) @@ -8084,6 +8137,11 @@ static void zend_jit_dump_exit_info(zend_jit_trace_info *t) fprintf(stderr, ":unknown(zval_copy(%s))", zend_reg_name(STACK_REG(stack, j))); } } +#if ZEND_DEBUG + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC) != 0) { + fprintf(stderr, " %s:%d", t->exit_info[i].filename, t->exit_info[i].lineno); + } +#endif fprintf(stderr, "\n"); } } @@ -8275,10 +8333,10 @@ static bool zend_jit_trace_exit_is_bad(uint32_t trace_num, uint32_t exit_num) zend_jit_traces[trace_num].exit_counters + exit_num; if (*counter + 1 >= JIT_G(hot_side_exit) + JIT_G(blacklist_side_trace)) { - return 1; + return true; } (*counter)++; - return 0; + return false; } static bool zend_jit_trace_exit_is_hot(uint32_t trace_num, uint32_t exit_num) @@ -8287,10 +8345,10 @@ static bool zend_jit_trace_exit_is_hot(uint32_t trace_num, uint32_t exit_num) zend_jit_traces[trace_num].exit_counters + exit_num; if (*counter + 1 >= JIT_G(hot_side_exit)) { - return 1; + return true; } (*counter)++; - return 0; + return false; } static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_num, uint32_t exit_num, uint32_t polymorphism) @@ -8527,7 +8585,7 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3 do { ex = ex->prev_execute_data; n++; - } while (ex && zend_jit_traces[root].op_array != &ex->func->op_array); + } while (ex && (!ex->func || zend_jit_traces[root].op_array != &ex->func->op_array)); if (ex && n <= ZEND_JIT_TRACE_MAX_RET_DEPTH) { ret_depth = n; } @@ -8832,11 +8890,11 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf zend_jit_unprotect(); if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_LOOP) { - ((zend_op*)(t->opline))->handler = (const void*)zend_jit_loop_trace_counter_handler; + ((zend_op*)(t->opline))->handler = zend_jit_loop_trace_counter_handler; } else if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_ENTER) { - ((zend_op*)(t->opline))->handler = (const void*)zend_jit_func_trace_counter_handler; + ((zend_op*)(t->opline))->handler = zend_jit_func_trace_counter_handler; } else if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_RETURN) { - ((zend_op*)(t->opline))->handler = (const void*)zend_jit_ret_trace_counter_handler; + ((zend_op*)(t->opline))->handler = zend_jit_ret_trace_counter_handler; } ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags &= ZEND_JIT_TRACE_START_LOOP|ZEND_JIT_TRACE_START_ENTER|ZEND_JIT_TRACE_START_RETURN; @@ -8889,9 +8947,9 @@ static int zend_jit_restart_hot_trace_counters(zend_op_array *op_array) jit_extension->trace_info[i].trace_flags &= ZEND_JIT_TRACE_START_LOOP | ZEND_JIT_TRACE_START_ENTER | ZEND_JIT_TRACE_UNSUPPORTED; if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_LOOP) { - op_array->opcodes[i].handler = (const void*)zend_jit_loop_trace_counter_handler; + op_array->opcodes[i].handler = zend_jit_loop_trace_counter_handler; } else if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_ENTER) { - op_array->opcodes[i].handler = (const void*)zend_jit_func_trace_counter_handler; + op_array->opcodes[i].handler = zend_jit_func_trace_counter_handler; } else { op_array->opcodes[i].handler = jit_extension->trace_info[i].orig_handler; } @@ -8917,7 +8975,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array) jit_extension->offset = (char*)jit_extension->trace_info - (char*)op_array->opcodes; for (i = 0; i < op_array->last; i++) { jit_extension->trace_info[i].orig_handler = op_array->opcodes[i].handler; - jit_extension->trace_info[i].call_handler = zend_get_opcode_handler_func(&op_array->opcodes[i]); + jit_extension->trace_info[i].call_handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(&op_array->opcodes[i]); jit_extension->trace_info[i].counter = NULL; jit_extension->trace_info[i].trace_flags = zend_jit_trace_supported(&op_array->opcodes[i]); @@ -8939,7 +8997,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array) /* loop header */ opline = op_array->opcodes + cfg.blocks[i].start; if (!(ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_UNSUPPORTED)) { - opline->handler = (const void*)zend_jit_loop_trace_counter_handler; + opline->handler = zend_jit_loop_trace_counter_handler; if (!ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter) { ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter = &zend_jit_hot_counters[ZEND_JIT_COUNTER_NUM]; @@ -8964,7 +9022,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array) if (!ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags) { /* function entry */ - opline->handler = (const void*)zend_jit_func_trace_counter_handler; + opline->handler = zend_jit_func_trace_counter_handler; ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter = &zend_jit_hot_counters[ZEND_JIT_COUNTER_NUM]; ZEND_JIT_COUNTER_NUM = (ZEND_JIT_COUNTER_NUM + 1) % ZEND_HOT_COUNTERS_COUNT; diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 4348fbd53ad4..271d923598d9 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend JIT | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Xinchen Hui | @@ -46,6 +44,60 @@ register const zend_op* volatile opline __asm__("x28"); # pragma GCC diagnostic warning "-Wvolatile-register-var" #endif +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_leave_func_helper_tailcall(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_execute_data *old_execute_data; + uint32_t call_info = EX_CALL_INFO(); + + if (!(call_info & ZEND_CALL_TOP)) { + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { + zend_clean_and_cache_symbol_table(EX(symbol_table)); + } + + zend_vm_stack_free_extra_args_ex(call_info, execute_data); + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(execute_data->This)); + } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(EX(extra_named_params)); + } + + old_execute_data = execute_data; + execute_data = EX(prev_execute_data); + zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); + + if (UNEXPECTED(EG(exception) != NULL)) { + const zend_op *old_opline = EX(opline); + zend_throw_exception_internal(NULL); + if (old_opline->result_type != IS_UNDEF) { + zval_ptr_dtor(EX_VAR(old_opline->result.var)); + } + opline = EG(current_execute_data)->opline; + } else { + opline = ++EX(opline); + } + ZEND_OPCODE_TAIL_CALL(opline->handler); + } else { + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { + zend_clean_and_cache_symbol_table(EX(symbol_table)); + } + zend_vm_stack_free_extra_args_ex(call_info, execute_data); + } + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(EX(extra_named_params)); + } + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + return (zend_op*)ZEND_VM_ENTER_BIT; + } +} +#endif + ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info) { zend_execute_data *old_execute_data; @@ -75,14 +127,16 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(ZEND_OPC zval_ptr_dtor(EX_VAR(old_opline->result.var)); } #ifndef HAVE_GCC_GLOBAL_REGS - return (zend_op*)((uintptr_t)EG(current_execute_data)->opline | ZEND_VM_ENTER_BIT); + return EG(current_execute_data)->opline; #endif } else { EX(opline)++; #ifdef HAVE_GCC_GLOBAL_REGS opline = EX(opline); +#elif ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + return EX(opline); #else - return (zend_op*)((uintptr_t)EX(opline) | ZEND_VM_ENTER_BIT); + return (const zend_op*)((uintptr_t)EX(opline) | ZEND_VM_ENTER_BIT); #endif } } @@ -101,11 +155,11 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_top_func_helper(ZEND_OPCODE if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } - execute_data = EG(current_execute_data); #ifdef HAVE_GCC_GLOBAL_REGS + execute_data = EG(current_execute_data); opline = zend_jit_halt_op; #else - return (const zend_op*)ZEND_VM_ENTER_BIT; // ZEND_VM_RETURN + return (const zend_op*)ZEND_VM_ENTER_BIT; #endif } @@ -114,9 +168,9 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_func_helper(ZEND_OPCODE_HAN uint32_t call_info = EX_CALL_INFO(); if (call_info & ZEND_CALL_TOP) { - ZEND_OPCODE_TAIL_CALL_EX(zend_jit_leave_top_func_helper, call_info); + return zend_jit_leave_top_func_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX call_info); } else { - ZEND_OPCODE_TAIL_CALL_EX(zend_jit_leave_nested_func_helper, call_info); + return zend_jit_leave_nested_func_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX call_info); } } @@ -199,9 +253,9 @@ bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D) } zend_vm_stack_free_call_frame(call); - return 0; + return false; } - return 1; + return true; } bool ZEND_FASTCALL zend_jit_nodiscard_helper(OPLINE_D) @@ -227,9 +281,9 @@ bool ZEND_FASTCALL zend_jit_nodiscard_helper(OPLINE_D) } zend_vm_stack_free_call_frame(call); - return 0; + return false; } - return 1; + return true; } bool ZEND_FASTCALL zend_jit_deprecated_nodiscard_helper(OPLINE_D) @@ -239,17 +293,17 @@ bool ZEND_FASTCALL zend_jit_deprecated_nodiscard_helper(OPLINE_D) if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { if (zend_jit_deprecated_helper(OPLINE_C) == 0) { - return 0; + return false; } } if (fbc->common.fn_flags & ZEND_ACC_NODISCARD) { if (zend_jit_nodiscard_helper(OPLINE_C) == 0) { - return 0; + return false; } } - return 1; + return true; } void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D) @@ -298,17 +352,18 @@ void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D) ZVAL_NULL(result); } -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS) +#if ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS) { zend_op_array *op_array = (zend_op_array*)EX(func); zend_jit_op_array_extension *jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); - zend_vm_opcode_handler_t handler = (zend_vm_opcode_handler_t) jit_extension->orig_handler; + zend_vm_opcode_handler_t handler = jit_extension->orig_handler; ++*(uintptr_t*)(EX(run_time_cache) + zend_jit_profile_counter_rid); ++zend_jit_profile_counter; ZEND_OPCODE_TAIL_CALL(handler); } -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_counter_helper(ZEND_OPCODE_HANDLER_ARGS) +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_func_counter_helper(ZEND_OPCODE_HANDLER_ARGS) { zend_jit_op_array_hot_extension *jit_extension = (zend_jit_op_array_hot_extension*)ZEND_FUNC_INFO(&EX(func)->op_array); @@ -325,7 +380,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_counter_helper(ZEND_OPCODE_H } } -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_HANDLER_ARGS) +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_loop_counter_helper(ZEND_OPCODE_HANDLER_ARGS) { zend_jit_op_array_hot_extension *jit_extension = (zend_jit_op_array_hot_extension*)ZEND_FUNC_INFO(&EX(func)->op_array); @@ -337,10 +392,11 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H zend_jit_hot_func(execute_data, opline); ZEND_OPCODE_RETURN(); } else { - zend_vm_opcode_handler_t handler = (zend_vm_opcode_handler_t)jit_extension->orig_handlers[opline - EX(func)->op_array.opcodes]; + zend_vm_opcode_handler_t handler = jit_extension->orig_handlers[opline - EX(func)->op_array.opcodes]; ZEND_OPCODE_TAIL_CALL(handler); } } +#endif static zend_always_inline zend_constant* _zend_quick_get_constant( const zval *key, uint32_t flags, int check_defined_only) @@ -402,14 +458,13 @@ zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key) return _zend_quick_get_constant(key, 0, 1); } -static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_trace_counter_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t cost) +#if ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL +static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_trace_counter_helper(ZEND_OPCODE_HANDLER_ARGS) { zend_jit_op_array_trace_extension *jit_extension = (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&EX(func)->op_array); size_t offset = jit_extension->offset; - *(ZEND_OP_TRACE_INFO(opline, offset)->counter) -= cost; - if (UNEXPECTED(*(ZEND_OP_TRACE_INFO(opline, offset)->counter) <= 0)) { *(ZEND_OP_TRACE_INFO(opline, offset)->counter) = ZEND_JIT_COUNTER_INIT; if (UNEXPECTED(zend_jit_trace_hot_root(execute_data, opline) < 0)) { @@ -424,32 +479,57 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_trace_c opline = execute_data ? EX(opline) : NULL; #ifdef HAVE_GCC_GLOBAL_REGS return; +#elif ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + if (EXPECTED(opline)) { + ZEND_OPCODE_TAIL_CALL((zend_vm_opcode_handler_t)opline->handler); + } else { + return (const zend_op*)ZEND_VM_ENTER_BIT; + } #else return (const zend_op*)((uintptr_t)opline | ZEND_VM_ENTER_BIT); // ZEND_VM_ENTER() / ZEND_VM_RETURN() #endif } else { - zend_vm_opcode_handler_t handler = (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->orig_handler; + zend_vm_opcode_handler_t handler = ZEND_OP_TRACE_INFO(opline, offset)->orig_handler; ZEND_OPCODE_TAIL_CALL(handler); } } -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_trace_helper(ZEND_OPCODE_HANDLER_ARGS) +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_func_trace_helper(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_OPCODE_TAIL_CALL_EX(zend_jit_trace_counter_helper, - ((ZEND_JIT_COUNTER_INIT + JIT_G(hot_func) - 1) / JIT_G(hot_func))); + zend_jit_op_array_trace_extension *jit_extension = + (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&EX(func)->op_array); + size_t offset = jit_extension->offset; + uint32_t cost = ((ZEND_JIT_COUNTER_INIT + JIT_G(hot_func) - 1) / JIT_G(hot_func)); + + *(ZEND_OP_TRACE_INFO(opline, offset)->counter) -= cost; + + ZEND_OPCODE_TAIL_CALL(zend_jit_trace_counter_helper); } -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_ret_trace_helper(ZEND_OPCODE_HANDLER_ARGS) +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_ret_trace_helper(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_OPCODE_TAIL_CALL_EX(zend_jit_trace_counter_helper, - ((ZEND_JIT_COUNTER_INIT + JIT_G(hot_return) - 1) / JIT_G(hot_return))); + zend_jit_op_array_trace_extension *jit_extension = + (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&EX(func)->op_array); + size_t offset = jit_extension->offset; + uint32_t cost = ((ZEND_JIT_COUNTER_INIT + JIT_G(hot_return) - 1) / JIT_G(hot_return)); + + *(ZEND_OP_TRACE_INFO(opline, offset)->counter) -= cost; + + ZEND_OPCODE_TAIL_CALL(zend_jit_trace_counter_helper); } -ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS) +ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_OPCODE_TAIL_CALL_EX(zend_jit_trace_counter_helper, - ((ZEND_JIT_COUNTER_INIT + JIT_G(hot_loop) - 1) / JIT_G(hot_loop))); + zend_jit_op_array_trace_extension *jit_extension = + (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&EX(func)->op_array); + size_t offset = jit_extension->offset; + uint32_t cost = ((ZEND_JIT_COUNTER_INIT + JIT_G(hot_loop) - 1) / JIT_G(hot_loop)); + + *(ZEND_OP_TRACE_INFO(opline, offset)->counter) -= cost; + + ZEND_OPCODE_TAIL_CALL(zend_jit_trace_counter_helper); } +#endif #define TRACE_RECORD(_op, _info, _ptr) \ trace_buffer[idx].info = _op | (_info); \ @@ -657,7 +737,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, zend_jit_trace_stop halt = 0; int level = 0; int ret_level = 0; - zend_vm_opcode_handler_t handler; + zend_vm_opcode_handler_func_t handler; const zend_op_array *op_array; zend_jit_op_array_trace_extension *jit_extension; size_t offset; @@ -983,15 +1063,25 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, break; } - handler = (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->call_handler; + const zend_op *prev_opline = opline; + handler = ZEND_OP_TRACE_INFO(opline, offset)->call_handler; #ifdef HAVE_GCC_GLOBAL_REGS handler(); if (UNEXPECTED(opline == zend_jit_halt_op)) { #else opline = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +# if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + while (UNEXPECTED(opline == zend_jit_interrupt_op)) { + opline = zend_vm_handle_interrupt(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } +# endif if (UNEXPECTED(((uintptr_t)opline & ~ZEND_VM_ENTER_BIT) == 0)) { #endif - stop = ZEND_JIT_TRACE_STOP_RETURN; + if (prev_opline->opcode == ZEND_YIELD || prev_opline->opcode == ZEND_YIELD_FROM) { + stop = ZEND_JIT_TRACE_STOP_INTERPRETER; + } else { + stop = ZEND_JIT_TRACE_STOP_RETURN; + } opline = NULL; halt = ZEND_JIT_TRACE_HALT; break; @@ -1010,6 +1100,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (UNEXPECTED(!jit_extension) || UNEXPECTED(!(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE))) { if (execute_data->prev_execute_data != prev_execute_data) { + stop = ZEND_JIT_TRACE_STOP_RETURN; + } else { stop = ZEND_JIT_TRACE_STOP_INTERPRETER; } break; diff --git a/ext/opcache/opcache.stub.php b/ext/opcache/opcache.stub.php index 526da238219a..32673bb1dcee 100644 --- a/ext/opcache/opcache.stub.php +++ b/ext/opcache/opcache.stub.php @@ -23,3 +23,5 @@ function opcache_jit_blacklist(Closure $closure): void {} function opcache_get_configuration(): array|false {} function opcache_is_script_cached(string $filename): bool {} + +function opcache_is_script_cached_in_file_cache(string $filename): bool {} diff --git a/ext/opcache/opcache_arginfo.h b/ext/opcache/opcache_arginfo.h index b4dc1f33a5fd..60a1633154c9 100644 --- a/ext/opcache/opcache_arginfo.h +++ b/ext/opcache/opcache_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: c416c231c5d1270b7e5961f84cc3ca3e29db4959 */ +/* This is a generated file, edit opcache.stub.php instead. + * Stub hash: a8de025fa96a78db3a26d53a18bb2b365d094eca */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_opcache_reset, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -26,6 +26,8 @@ ZEND_END_ARG_INFO() #define arginfo_opcache_is_script_cached arginfo_opcache_compile_file +#define arginfo_opcache_is_script_cached_in_file_cache arginfo_opcache_compile_file + ZEND_FUNCTION(opcache_reset); ZEND_FUNCTION(opcache_get_status); ZEND_FUNCTION(opcache_compile_file); @@ -33,6 +35,7 @@ ZEND_FUNCTION(opcache_invalidate); ZEND_FUNCTION(opcache_jit_blacklist); ZEND_FUNCTION(opcache_get_configuration); ZEND_FUNCTION(opcache_is_script_cached); +ZEND_FUNCTION(opcache_is_script_cached_in_file_cache); static const zend_function_entry ext_functions[] = { ZEND_FE(opcache_reset, arginfo_opcache_reset) @@ -42,5 +45,6 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(opcache_jit_blacklist, arginfo_opcache_jit_blacklist) ZEND_FE(opcache_get_configuration, arginfo_opcache_get_configuration) ZEND_FE(opcache_is_script_cached, arginfo_opcache_is_script_cached) + ZEND_FE(opcache_is_script_cached_in_file_cache, arginfo_opcache_is_script_cached_in_file_cache) ZEND_FE_END }; diff --git a/ext/opcache/shared_alloc_mmap.c b/ext/opcache/shared_alloc_mmap.c index 18c7532478f4..a805912d0d75 100644 --- a/ext/opcache/shared_alloc_mmap.c +++ b/ext/opcache/shared_alloc_mmap.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -52,7 +50,7 @@ #endif #if defined(HAVE_JIT) && (defined(__linux__) || defined(__FreeBSD__)) && (defined(__x86_64__) || defined (__aarch64__)) && !defined(__SANITIZE_ADDRESS__) -static void *find_prefered_mmap_base(size_t requested_size) +static void *find_preferred_mmap_base(size_t requested_size) { size_t huge_page_size = 2 * 1024 * 1024; uintptr_t last_free_addr = huge_page_size; @@ -204,7 +202,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ void *hint; if (JIT_G(enabled) && JIT_G(buffer_size) && zend_jit_check_support() == SUCCESS) { - hint = find_prefered_mmap_base(requested_size); + hint = find_preferred_mmap_base(requested_size); } else { /* Do not use a hint if JIT is not enabled, as this profits only JIT and * this is potentially unsafe when the only suitable candidate is just diff --git a/ext/opcache/shared_alloc_posix.c b/ext/opcache/shared_alloc_posix.c index 3f1e097fe97c..36ed7950044f 100644 --- a/ext/opcache/shared_alloc_posix.c +++ b/ext/opcache/shared_alloc_posix.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/shared_alloc_shm.c b/ext/opcache/shared_alloc_shm.c index 09a357d189ed..e98ac615f860 100644 --- a/ext/opcache/shared_alloc_shm.c +++ b/ext/opcache/shared_alloc_shm.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -42,7 +40,6 @@ # define MIN(x, y) ((x) > (y)? (y) : (x)) #endif -#define SEG_ALLOC_SIZE_MAX 32*1024*1024 #define SEG_ALLOC_SIZE_MIN 2*1024*1024 typedef struct { @@ -53,36 +50,38 @@ typedef struct { static int create_segments(size_t requested_size, zend_shared_segment_shm ***shared_segments_p, int *shared_segments_count, const char **error_in) { int i; - size_t allocate_size = 0, remaining_bytes = requested_size, seg_allocate_size; + size_t allocate_size = 0, remaining_bytes, seg_allocate_size; int first_segment_id = -1; key_t first_segment_key = -1; struct shmid_ds sds; int shmget_flags; zend_shared_segment_shm *shared_segments; - seg_allocate_size = SEG_ALLOC_SIZE_MAX; - /* determine segment size we _really_ need: - * no more than to include requested_size - */ - while (requested_size * 2 <= seg_allocate_size && seg_allocate_size > SEG_ALLOC_SIZE_MIN) { - seg_allocate_size >>= 1; - } - shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL; - /* try allocating this much, if not - try shrinking */ - while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) { - allocate_size = MIN(requested_size, seg_allocate_size); - first_segment_id = shmget(first_segment_key, allocate_size, shmget_flags); - if (first_segment_id != -1) { - break; + /* Try contiguous allocation first. */ + seg_allocate_size = requested_size; + first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags); + if (UNEXPECTED(first_segment_id == -1)) { + /* Search for biggest n^2 < requested_size. */ + seg_allocate_size = SEG_ALLOC_SIZE_MIN; + while (seg_allocate_size < requested_size / 2) { + seg_allocate_size *= 2; } - seg_allocate_size >>= 1; /* shrink the allocated block */ - } - if (first_segment_id == -1) { - *error_in = "shmget"; - return ALLOC_FAILURE; + /* try allocating this much, if not - try shrinking */ + while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) { + first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags); + if (first_segment_id != -1) { + break; + } + seg_allocate_size >>= 1; /* shrink the allocated block */ + } + + if (first_segment_id == -1) { + *error_in = "shmget"; + return ALLOC_FAILURE; + } } *shared_segments_count = ((requested_size - 1) / seg_allocate_size) + 1; diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index c51c459ed553..84bd32e9cbad 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/tests/api/opcache_preloading.inc b/ext/opcache/tests/api/opcache_preloading.inc new file mode 100644 index 000000000000..0466028a3709 --- /dev/null +++ b/ext/opcache/tests/api/opcache_preloading.inc @@ -0,0 +1,3 @@ + diff --git a/ext/opcache/tests/api/opcache_preloading_001.phpt b/ext/opcache/tests/api/opcache_preloading_001.phpt new file mode 100644 index 000000000000..e30cbbd7d159 --- /dev/null +++ b/ext/opcache/tests/api/opcache_preloading_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +opcache_preloading() api 001 +--EXTENSIONS-- +zend_test +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.preload={PWD}/opcache_preloading.inc +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +%sopcache_preloading.inc: 1 +%sopcache_preloading_001.php: 0 diff --git a/ext/opcache/tests/api/opcache_preloading_002.phpt b/ext/opcache/tests/api/opcache_preloading_002.phpt new file mode 100644 index 000000000000..30bf5a5bc03b --- /dev/null +++ b/ext/opcache/tests/api/opcache_preloading_002.phpt @@ -0,0 +1,24 @@ +--TEST-- +opcache_preloading() api 002 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.preload={PWD}/opcache_preloading.inc +opcache.preload_user={ENV:TEST_NON_ROOT_USER} +--EXTENSIONS-- +posix +zend_test +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +%sopcache_preloading.inc: 1 +%sopcache_preloading_002.php: 0 diff --git a/ext/opcache/tests/array_map_foreach_optimization_001.phpt b/ext/opcache/tests/array_map_foreach_optimization_001.phpt new file mode 100644 index 000000000000..c38265f35ebd --- /dev/null +++ b/ext/opcache/tests/array_map_foreach_optimization_001.phpt @@ -0,0 +1,82 @@ +--TEST-- +array_map(): foreach optimization +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_FCALL 2 %d string("range") +0001 SEND_VAL int(1) 1 +0002 SEND_VAL int(10) 2 +0003 T2 = DO_ICALL +0004 ASSIGN CV0($array) T2 +0005 TYPE_ASSERT 131079 string("array_map") CV0($array) +0006 T2 = INIT_ARRAY 0 (packed) NEXT +0007 V3 = FE_RESET_R CV0($array) 0014 +0008 T5 = FE_FETCH_R V3 T4 0014 +0009 INIT_FCALL 1 %d string("plus1") +0010 SEND_VAL T4 1 +0011 T4 = DO_UCALL +0012 T2 = ADD_ARRAY_ELEMENT T4 T5 +0013 JMP 0008 +0014 FE_FREE V3 +0015 ASSIGN CV1($foo) T2 +0016 INIT_FCALL 1 %d string("var_dump") +0017 SEND_VAR CV1($foo) 1 +0018 DO_ICALL +0019 RETURN int(1) +LIVE RANGES: + 2: 0007 - 0015 (tmp/var) + 3: 0008 - 0014 (loop) + 4: 0009 - 0010 (tmp/var) + 5: 0009 - 0012 (tmp/var) + +plus1: + ; (lines=3, args=1, vars=1, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($x) = RECV 1 +0001 T1 = ADD CV0($x) int(1) +0002 RETURN T1 +array(10) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) + [5]=> + int(7) + [6]=> + int(8) + [7]=> + int(9) + [8]=> + int(10) + [9]=> + int(11) +} diff --git a/ext/opcache/tests/array_map_foreach_optimization_002.phpt b/ext/opcache/tests/array_map_foreach_optimization_002.phpt new file mode 100644 index 000000000000..03fb221d7ed0 --- /dev/null +++ b/ext/opcache/tests/array_map_foreach_optimization_002.phpt @@ -0,0 +1,73 @@ +--TEST-- +array_map(): foreach optimization - Error +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_FCALL 2 %d string("range") +0001 SEND_VAL int(1) 1 +0002 SEND_VAL int(10) 2 +0003 T2 = DO_ICALL +0004 ASSIGN CV0($array) T2 +0005 T5 = NEW 1 string("ArrayIterator") +0006 SEND_VAR%S CV0($array) 1 +0007 DO_FCALL +0008 TYPE_ASSERT 131079 string("array_map") T5 +0009 T2 = INIT_ARRAY 0 (packed) NEXT +0010 V3 = FE_RESET_R T5 0017 +0011 T5 = FE_FETCH_R V3 T4 0017 +0012 INIT_FCALL 1 %d string("plus1") +0013 SEND_VAL T4 1 +0014 T4 = DO_UCALL +0015 T2 = ADD_ARRAY_ELEMENT T4 T5 +0016 JMP 0011 +0017 FE_FREE V3 +0018 ASSIGN CV1($foo) T2 +0019 INIT_FCALL 1 %d string("var_dump") +0020 SEND_VAR CV1($foo) 1 +0021 DO_ICALL +0022 RETURN int(1) +LIVE RANGES: + 5: 0006 - 0008 (new) + 5: 0008 - 0010 (tmp/var) + 2: 0010 - 0018 (tmp/var) + 3: 0011 - 0017 (loop) + 4: 0012 - 0013 (tmp/var) + 5: 0012 - 0015 (tmp/var) + +plus1: + ; (lines=3, args=1, vars=1, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($x) = RECV 1 +0001 T1 = ADD CV0($x) int(1) +0002 RETURN T1 + +Fatal error: Uncaught TypeError: array_map(): Argument #2 ($array) must be of type array, ArrayIterator given in %s:9 +Stack trace: +#0 {main} + thrown in %s on line 9 diff --git a/ext/opcache/tests/array_map_foreach_optimization_003.phpt b/ext/opcache/tests/array_map_foreach_optimization_003.phpt new file mode 100644 index 000000000000..e3a9972c1244 --- /dev/null +++ b/ext/opcache/tests/array_map_foreach_optimization_003.phpt @@ -0,0 +1,73 @@ +--TEST-- +array_map(): foreach optimization - const array +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 TYPE_ASSERT 131079 string("array_map") array(...) +0001 T1 = INIT_ARRAY 0 (packed) NEXT +0002 V2 = FE_RESET_R array(...) 0009 +0003 T4 = FE_FETCH_R V2 T3 0009 +0004 INIT_FCALL 1 %d string("plus1") +0005 SEND_VAL T3 1 +0006 T3 = DO_UCALL +0007 T1 = ADD_ARRAY_ELEMENT T3 T4 +0008 JMP 0003 +0009 FE_FREE V2 +0010 ASSIGN CV0($foo) T1 +0011 INIT_FCALL 1 %d string("var_dump") +0012 SEND_VAR CV0($foo) 1 +0013 DO_ICALL +0014 RETURN int(1) +LIVE RANGES: + 1: 0002 - 0010 (tmp/var) + 2: 0003 - 0009 (loop) + +plus1: + ; (lines=3, args=1, vars=1, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($x) = RECV 1 +0001 T1 = ADD CV0($x) int(1) +0002 RETURN T1 +array(10) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) + [5]=> + int(7) + [6]=> + int(8) + [7]=> + int(9) + [8]=> + int(10) + [9]=> + int(11) +} diff --git a/ext/opcache/tests/array_map_foreach_optimization_004.phpt b/ext/opcache/tests/array_map_foreach_optimization_004.phpt new file mode 100644 index 000000000000..d4ead73983ba --- /dev/null +++ b/ext/opcache/tests/array_map_foreach_optimization_004.phpt @@ -0,0 +1,57 @@ +--TEST-- +array_map(): foreach optimization - unused refcounted result +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_FCALL 2 %d string("range") +0001 SEND_VAL int(1) 1 +0002 SEND_VAL int(10) 2 +0003 T1 = DO_ICALL +0004 ASSIGN CV0($array) T1 +0005 TYPE_ASSERT 131079 string("array_map") CV0($array) +0006 T1 = INIT_ARRAY 0 (packed) NEXT +0007 V2 = FE_RESET_R CV0($array) 0014 +0008 T4 = FE_FETCH_R V2 T3 0014 +0009 INIT_FCALL 1 %d string("stdclass") +0010 SEND_VAL T3 1 +0011 T3 = DO_UCALL +0012 T1 = ADD_ARRAY_ELEMENT T3 T4 +0013 JMP 0008 +0014 FE_FREE V2 +0015 FREE T1 +0016 RETURN int(1) +LIVE RANGES: + 1: 0007 - 0015 (tmp/var) + 2: 0008 - 0014 (loop) + 3: 0009 - 0010 (tmp/var) + 4: 0009 - 0012 (tmp/var) + +stdClass: + ; (lines=3, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %s +0000 T0 = NEW 0 string("stdClass") +0001 DO_FCALL +0002 RETURN T0 +LIVE RANGES: + 0: 0001 - 0002 (new) diff --git a/ext/opcache/tests/array_map_foreach_optimization_005.phpt b/ext/opcache/tests/array_map_foreach_optimization_005.phpt new file mode 100644 index 000000000000..33197e2c8d58 --- /dev/null +++ b/ext/opcache/tests/array_map_foreach_optimization_005.phpt @@ -0,0 +1,84 @@ +--TEST-- +array_map(): foreach optimization - static call +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_FCALL 2 %d string("range") +0001 SEND_VAL int(1) 1 +0002 SEND_VAL int(10) 2 +0003 T2 = DO_ICALL +0004 ASSIGN CV0($array) T2 +0005 TYPE_ASSERT 131079 string("array_map") CV0($array) +0006 T2 = INIT_ARRAY 0 (packed) NEXT +0007 V3 = FE_RESET_R CV0($array) 0014 +0008 T5 = FE_FETCH_R V3 T4 0014 +0009 INIT_STATIC_METHOD_CALL 1 string("Adder") string("plus1") +0010 SEND_VAL T4 1 +0011 T4 = DO_UCALL +0012 T2 = ADD_ARRAY_ELEMENT T4 T5 +0013 JMP 0008 +0014 FE_FREE V3 +0015 ASSIGN CV1($foo) T2 +0016 INIT_FCALL 1 %d string("var_dump") +0017 SEND_VAR CV1($foo) 1 +0018 DO_ICALL +0019 RETURN int(1) +LIVE RANGES: + 2: 0007 - 0015 (tmp/var) + 3: 0008 - 0014 (loop) + 4: 0009 - 0010 (tmp/var) + 5: 0009 - 0012 (tmp/var) + +Adder::plus1: + ; (lines=3, args=1, vars=1, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($x) = RECV 1 +0001 T1 = ADD CV0($x) int(1) +0002 RETURN T1 +array(10) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) + [5]=> + int(7) + [6]=> + int(8) + [7]=> + int(9) + [8]=> + int(10) + [9]=> + int(11) +} diff --git a/ext/opcache/tests/array_map_foreach_optimization_006.phpt b/ext/opcache/tests/array_map_foreach_optimization_006.phpt new file mode 100644 index 000000000000..889fee27b8a2 --- /dev/null +++ b/ext/opcache/tests/array_map_foreach_optimization_006.phpt @@ -0,0 +1,84 @@ +--TEST-- +array_map(): foreach optimization - dynamic name +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.opt_debug_level=0x20000 +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_FCALL 2 %d string("range") +0001 SEND_VAL int(1) 1 +0002 SEND_VAL int(10) 2 +0003 T3 = DO_ICALL +0004 ASSIGN CV0($array) T3 +0005 ASSIGN CV1($plus1) string("plus1") +0006 TYPE_ASSERT 131079 string("array_map") CV0($array) +0007 T3 = INIT_ARRAY 0 (packed) NEXT +0008 V4 = FE_RESET_R CV0($array) 0015 +0009 T6 = FE_FETCH_R V4 T5 0015 +0010 INIT_DYNAMIC_CALL 1 CV1($plus1) +0011 SEND_VAL_EX T5 1 +0012 T5 = DO_FCALL +0013 T3 = ADD_ARRAY_ELEMENT T5 T6 +0014 JMP 0009 +0015 FE_FREE V4 +0016 ASSIGN CV2($foo) T3 +0017 INIT_FCALL 1 %d string("var_dump") +0018 SEND_VAR CV2($foo) 1 +0019 DO_ICALL +0020 RETURN int(1) +LIVE RANGES: + 3: 0008 - 0016 (tmp/var) + 4: 0009 - 0015 (loop) + 5: 0010 - 0011 (tmp/var) + 6: 0010 - 0013 (tmp/var) + +plus1: + ; (lines=3, args=1, vars=1, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($x) = RECV 1 +0001 T1 = ADD CV0($x) int(1) +0002 RETURN T1 +array(10) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) + [5]=> + int(7) + [6]=> + int(8) + [7]=> + int(9) + [8]=> + int(10) + [9]=> + int(11) +} diff --git a/ext/opcache/tests/bug71127.phpt b/ext/opcache/tests/bug71127.phpt index a417f0d3120a..68f6d36895d0 100644 --- a/ext/opcache/tests/bug71127.phpt +++ b/ext/opcache/tests/bug71127.phpt @@ -21,5 +21,5 @@ include($file); @unlink(__DIR__ . "/bug71127.inc"); ?> --EXPECTF-- -Warning: Constant FOO already defined in %sbug71127.inc on line %d +Warning: Constant FOO already defined, this will be an error in PHP 9 in %sbug71127.inc on line %d okey diff --git a/ext/opcache/tests/dump_property_hooks.phpt b/ext/opcache/tests/dump_property_hooks.phpt index 5083ad385f31..3073ca89ff98 100644 --- a/ext/opcache/tests/dump_property_hooks.phpt +++ b/ext/opcache/tests/dump_property_hooks.phpt @@ -39,9 +39,9 @@ $_main: ; (lines=10, args=0, vars=1, tmps=%d) ; (after optimizer) ; %sdump_property_hooks.php:1-22 -0000 V1 = NEW 0 string("A") +0000 T1 = NEW 0 string("A") 0001 DO_FCALL -0002 ASSIGN CV0($a) V1 +0002 ASSIGN CV0($a) T1 0003 INIT_FCALL 1 %d string("var_dump") 0004 T1 = FETCH_OBJ_R CV0($a) string("prop") 0005 SEND_VAL T1 1 diff --git a/ext/opcache/tests/func_info.phpt b/ext/opcache/tests/func_info.phpt index 8b1f9ef436c4..9596aa23199d 100644 --- a/ext/opcache/tests/func_info.phpt +++ b/ext/opcache/tests/func_info.phpt @@ -16,7 +16,7 @@ foreach (get_defined_functions()["internal"] as $function) { if (in_array($function, ["extract", "compact", "get_defined_vars"])) { continue; } - $contents .= " \$result = {$function}();\n"; + $contents .= " \$result = \\{$function}();\n"; } $contents .= "}\n"; diff --git a/ext/opcache/tests/gh16979_check_file_cache_function.inc b/ext/opcache/tests/gh16979_check_file_cache_function.inc new file mode 100644 index 000000000000..6e4c482985fb --- /dev/null +++ b/ext/opcache/tests/gh16979_check_file_cache_function.inc @@ -0,0 +1,3 @@ + +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=disable +opcache.file_cache="{PWD}/gh16979_cache" +opcache.file_update_protection=0 +--EXTENSIONS-- +opcache +--FILE-- + +--CLEAN-- +isDir()) { + @rmdir($fileinfo->getRealPath()); + } else { + @unlink($fileinfo->getRealPath()); + } + } + @rmdir($dir); +} +removeDirRecursive(__DIR__ . '/gh16979_cache'); +?> +--EXPECT-- +bool(false) +bool(true) +bool(false) diff --git a/ext/opcache/tests/gh17422/001.phpt b/ext/opcache/tests/gh17422/001.phpt new file mode 100644 index 000000000000..04a8bc38a9ef --- /dev/null +++ b/ext/opcache/tests/gh17422/001.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) +--FILE-- + +--EXPECT-- +set_error_handler: "continue" targeting switch is equivalent to "break" +OK: warning diff --git a/ext/opcache/tests/gh17422/002.phpt b/ext/opcache/tests/gh17422/002.phpt new file mode 100644 index 000000000000..6145f71a8e58 --- /dev/null +++ b/ext/opcache/tests/gh17422/002.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Throwing error handler +--FILE-- +getMessage(), PHP_EOL; +} + +warning(); + +?> +--EXPECT-- +Caught: "continue" targeting switch is equivalent to "break" +OK: warning diff --git a/ext/opcache/tests/gh17422/003.phpt b/ext/opcache/tests/gh17422/003.phpt new file mode 100644 index 000000000000..a1330eb88afa --- /dev/null +++ b/ext/opcache/tests/gh17422/003.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Fatal Error +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redeclare function fatal_error() (previously declared in %s:%d) in %s on line %d diff --git a/ext/opcache/tests/gh17422/004.phpt b/ext/opcache/tests/gh17422/004.phpt new file mode 100644 index 000000000000..4fa659a763e8 --- /dev/null +++ b/ext/opcache/tests/gh17422/004.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - eval +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redeclare function warning() %s diff --git a/ext/opcache/tests/gh17422/005.phpt b/ext/opcache/tests/gh17422/005.phpt new file mode 100644 index 000000000000..1b4818d91cc9 --- /dev/null +++ b/ext/opcache/tests/gh17422/005.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - require +--FILE-- + +--EXPECT-- +OK: dummy diff --git a/ext/opcache/tests/gh17422/006.phpt b/ext/opcache/tests/gh17422/006.phpt new file mode 100644 index 000000000000..3c1303dfa844 --- /dev/null +++ b/ext/opcache/tests/gh17422/006.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - File cache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache="{TMP}" +opcache.file_cache_only=1 +opcache.record_warnings=1 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECT-- +set_error_handler: "continue" targeting switch is equivalent to "break" +OK: warning diff --git a/ext/opcache/tests/gh17422/007.phpt b/ext/opcache/tests/gh17422/007.phpt new file mode 100644 index 000000000000..59b2306f52d8 --- /dev/null +++ b/ext/opcache/tests/gh17422/007.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Fatal after warning +--FILE-- + +--EXPECTF-- +Warning: "continue" targeting switch is equivalent to "break" in %s on line %d + +Fatal error: Cannot redeclare function warning() (previously declared in %s:%d) in %s on line %d diff --git a/ext/opcache/tests/gh17422/008.phpt b/ext/opcache/tests/gh17422/008.phpt new file mode 100644 index 000000000000..bcabb071e650 --- /dev/null +++ b/ext/opcache/tests/gh17422/008.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Early binding warning +--FILE-- + +--EXPECTF-- +set_error_handler: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice diff --git a/ext/opcache/tests/gh17422/009.phpt b/ext/opcache/tests/gh17422/009.phpt new file mode 100644 index 000000000000..b071ad9478de --- /dev/null +++ b/ext/opcache/tests/gh17422/009.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Early binding error after warning +--FILE-- + +--EXPECTF-- +Deprecated: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s on line %d + +Fatal error: Declaration of C::getTimestamp(C $arg): int must be compatible with DateTime::getTimestamp(): int in %s on line %d diff --git a/ext/opcache/tests/gh17422/010.phpt b/ext/opcache/tests/gh17422/010.phpt new file mode 100644 index 000000000000..4e94b5e77941 --- /dev/null +++ b/ext/opcache/tests/gh17422/010.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Inheritance warning +--FILE-- + +--EXPECTF-- +set_error_handler: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice diff --git a/ext/opcache/tests/gh17422/011.phpt b/ext/opcache/tests/gh17422/011.phpt new file mode 100644 index 000000000000..7034e5b2a461 --- /dev/null +++ b/ext/opcache/tests/gh17422/011.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-17422 (OPcache bypasses the user-defined error handler for deprecations) - Inheritance error after warning +--FILE-- + +--EXPECTF-- +Deprecated: Return type of C::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s on line %d + +Fatal error: Declaration of C::getTimestamp(C $arg): int must be compatible with DateTime::getTimestamp(): int %s on line %d diff --git a/ext/opcache/tests/gh17422/dummy.inc b/ext/opcache/tests/gh17422/dummy.inc new file mode 100644 index 000000000000..0bb253556124 --- /dev/null +++ b/ext/opcache/tests/gh17422/dummy.inc @@ -0,0 +1,4 @@ + fn($a, $b) => $a + $b; +?> +--EXPECTF-- +$_main: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 T0 = DECLARE_LAMBDA_FUNCTION 0 +0001 FREE T0 +0002 RETURN int(1) + +{closure:%s:%d}: + ; (lines=%d, args=0, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 T0 = DECLARE_LAMBDA_FUNCTION 0 +0001 RETURN T0 + +{closure:%s:%d}: + ; (lines=%d, args=2, vars=%d, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($a) = RECV 1 +0001 CV1($b) = RECV 2 +0002 T2 = ADD CV0($a) CV1($b) +0003 RETURN T2 diff --git a/ext/opcache/tests/gh19984.phpt b/ext/opcache/tests/gh19984.phpt new file mode 100644 index 000000000000..cb49869f5cf0 --- /dev/null +++ b/ext/opcache/tests/gh19984.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-19984: Double-free of EG(errors)/persistent_script->warnings on persist of already persisted file +--EXTENSIONS-- +opcache +pcntl +--INI-- +opcache.enable_cli=1 +opcache.record_warnings=1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: Unsupported declare 'unknown' in %s on line %d + +Warning: Unsupported declare 'unknown' in %s on line %d diff --git a/ext/opcache/tests/gh20628_borked_live_range_calc.phpt b/ext/opcache/tests/gh20628_borked_live_range_calc.phpt new file mode 100644 index 000000000000..f0b6ccfc92c8 --- /dev/null +++ b/ext/opcache/tests/gh20628_borked_live_range_calc.phpt @@ -0,0 +1,23 @@ +--TEST-- +Broken live-range calculation with QM_ASSIGN optimization +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +ReflectionExceptionClass "non" does not exist diff --git a/ext/opcache/tests/gh21052.phpt b/ext/opcache/tests/gh21052.phpt new file mode 100644 index 000000000000..d9d0430b9eef --- /dev/null +++ b/ext/opcache/tests/gh21052.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21052: Preloaded constant erroneously propagated to file-cached script +--CREDITS-- +Grummfy +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache="{TMP}" +opcache.preload={PWD}/gh21052_a.inc +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(3) "foo" +} +array(1) { + [0]=> + string(3) "foo" +} +array(1) { + [0]=> + string(3) "foo" +} diff --git a/ext/opcache/tests/gh21052_a.inc b/ext/opcache/tests/gh21052_a.inc new file mode 100644 index 000000000000..f9614369798b --- /dev/null +++ b/ext/opcache/tests/gh21052_a.inc @@ -0,0 +1,13 @@ +a = 3; + $objs = []; + $obj = new stdClass; + $objs[] = $obj; +} + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/opcache/tests/gh22071.phpt b/ext/opcache/tests/gh22071.phpt new file mode 100644 index 000000000000..148ca461be21 --- /dev/null +++ b/ext/opcache/tests/gh22071.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-22071: Assertion failure jit_CONST_FUNC_PROTO on abstract static method call +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1205 +opcache.jit_buffer_size=16M +--FILE-- + +--EXPECT-- +ok diff --git a/ext/opcache/tests/issue0057.phpt b/ext/opcache/tests/issue0057.phpt index 20c2f2a10558..ac73859b0d36 100644 --- a/ext/opcache/tests/issue0057.phpt +++ b/ext/opcache/tests/issue0057.phpt @@ -15,9 +15,9 @@ class ZException extends Exception { function dummy($query) { try { switch ($query) { - case 1; + case 1: break; - case 2; + case 2: break; default: throw new Exception('exception'); diff --git a/ext/opcache/tests/jit/add_011.phpt b/ext/opcache/tests/jit/add_011.phpt index 28c598c5540a..17bd7be99d15 100644 --- a/ext/opcache/tests/jit/add_011.phpt +++ b/ext/opcache/tests/jit/add_011.phpt @@ -195,5 +195,6 @@ int(-9223371969208523780) Warning: Undefined variable $u in %sadd_011.php on line 5 -Deprecated: Implicit conversion from float %f to int loses precision in %sadd_011.php on line 5 -int(66572500992) \ No newline at end of file +Warning: The float %f is not representable as an int, cast occurred in %sadd_011.php on line 5 +int(66572500992) + diff --git a/ext/opcache/tests/jit/array_elem_002.phpt b/ext/opcache/tests/jit/array_elem_002.phpt index 250f54349051..01de92acfccf 100644 --- a/ext/opcache/tests/jit/array_elem_002.phpt +++ b/ext/opcache/tests/jit/array_elem_002.phpt @@ -11,7 +11,7 @@ $string_float= PHP_INT_MAX; $a = [$float => 'a', $string_float => 'b', 'c', 'd']; ?> --EXPECTF-- -Deprecated: Implicit conversion from float 1.0E+38 to int loses precision in %sarray_elem_002.php on line 4 +Warning: The float 1.0E+38 is not representable as an int, cast occurred in %sarray_elem_002.php on line 4 Fatal error: Uncaught Error: Cannot add element to the array as the next element is already occupied in %sarray_elem_002.php:4 Stack trace: diff --git a/ext/opcache/tests/jit/assign_obj_006.phpt b/ext/opcache/tests/jit/assign_obj_006.phpt new file mode 100644 index 000000000000..a48299f04015 --- /dev/null +++ b/ext/opcache/tests/jit/assign_obj_006.phpt @@ -0,0 +1,37 @@ +--TEST-- +JIT ASSIGN_OBJ: violation of dominance +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +value = $value['value']; + } + return $item; + }, + null, + CacheItem::class); + return $test($value); +} + +$values = [['value'=>'str'], ['value'=>'str'], ['value'=>42]]; +$n = count($values); + +for ($i = 0; $i < $n; $i++) { + test($values[$i]); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/copy_tmp_001.phpt b/ext/opcache/tests/jit/copy_tmp_001.phpt index fa92b6ba21ee..8e3a2a96bd4f 100644 --- a/ext/opcache/tests/jit/copy_tmp_001.phpt +++ b/ext/opcache/tests/jit/copy_tmp_001.phpt @@ -15,7 +15,10 @@ $a = []; $a[test()] ??= 1; var_dump($a); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d array(1) { [""]=> int(1) diff --git a/ext/opcache/tests/jit/fetch_dim_r_001.phpt b/ext/opcache/tests/jit/fetch_dim_r_001.phpt index 3ff56263db68..819ec7edca65 100644 --- a/ext/opcache/tests/jit/fetch_dim_r_001.phpt +++ b/ext/opcache/tests/jit/fetch_dim_r_001.phpt @@ -30,7 +30,7 @@ function foo() { } foo(); ?> ---EXPECT-- +--EXPECTF-- int(1) int(3) int(2) @@ -38,6 +38,8 @@ int(1) int(3) int(1) int(2) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d int(4) int(5) int(5) diff --git a/ext/opcache/tests/jit/fetch_dim_r_002.phpt b/ext/opcache/tests/jit/fetch_dim_r_002.phpt index fb7471d7a292..324cc688c222 100644 --- a/ext/opcache/tests/jit/fetch_dim_r_002.phpt +++ b/ext/opcache/tests/jit/fetch_dim_r_002.phpt @@ -30,7 +30,7 @@ $x=2; $y="x"; foo($x.$y); ?> ---EXPECT-- +--EXPECTF-- int(1) int(3) int(2) @@ -38,6 +38,8 @@ int(1) int(3) int(1) int(2) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d int(4) int(5) int(5) diff --git a/ext/opcache/tests/jit/fetch_list_r_001.phpt b/ext/opcache/tests/jit/fetch_list_r_001.phpt index ec93b305ffaf..f5f0fee4084e 100644 --- a/ext/opcache/tests/jit/fetch_list_r_001.phpt +++ b/ext/opcache/tests/jit/fetch_list_r_001.phpt @@ -13,5 +13,6 @@ function test() { } test(); ?> ---EXPECT-- +--EXPECTF-- +Warning: Cannot use string as array in %s on line %d NULL diff --git a/ext/opcache/tests/jit/gh14082.phpt b/ext/opcache/tests/jit/gh14082.phpt new file mode 100644 index 000000000000..eba67a096b82 --- /dev/null +++ b/ext/opcache/tests/jit/gh14082.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-14082 (Segmentation fault on unknown address 0x600000000018 in ext/opcache/jit/zend_jit.c) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1235 +opcache.jit_buffer_size=16M +opcache.preload={PWD}/preload_gh14082.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(1) +int(1) +ok diff --git a/ext/opcache/tests/jit/gh18898_1.phpt b/ext/opcache/tests/jit/gh18898_1.phpt new file mode 100644 index 000000000000..6038f006f5e5 --- /dev/null +++ b/ext/opcache/tests/jit/gh18898_1.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-18898 (SEGV zend_jit_op_array_hot with property hooks and preloading) - jit 1235 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1235 +opcache.jit_buffer_size=16M +opcache.preload={PWD}/../gh18534_preload.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- +dummyProperty2); +echo "ok"; +?> +--EXPECT-- +NULL +ok diff --git a/ext/opcache/tests/jit/gh18898_2.phpt b/ext/opcache/tests/jit/gh18898_2.phpt new file mode 100644 index 000000000000..0ce79b859a97 --- /dev/null +++ b/ext/opcache/tests/jit/gh18898_2.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-18898 (SEGV zend_jit_op_array_hot with property hooks and preloading) - jit 1233 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=1233 +opcache.jit_buffer_size=16M +opcache.preload={PWD}/../gh18534_preload.inc +--EXTENSIONS-- +opcache +--SKIPIF-- + +--FILE-- +dummyProperty2); +echo "ok"; +?> +--EXPECT-- +NULL +ok diff --git a/ext/opcache/tests/jit/gh19486.phpt b/ext/opcache/tests/jit/gh19486.phpt new file mode 100644 index 000000000000..8a0c610ed200 --- /dev/null +++ b/ext/opcache/tests/jit/gh19486.phpt @@ -0,0 +1,42 @@ +--TEST-- +GH-19486: incorrect opline after deoptimization +--INI-- +opcache.jit_blacklist_root_trace=1 +opcache.jit_blacklist_side_trace=1 +--FILE-- +getLakeArea(0, 0); + +class GameMap +{ + public $lakeID = []; + + public function getLakeArea(int $x, int $y): int + { + $this->floodFill(0, 0, 0); + } + + public function floodFill(int $x, int $y, int $id): void + { + if (($x < 0) or ($x >= 50) or ($y < 0) or ($y >= 50)) { + return; + } + if (isset($this->lakeID[$y][$x]) and ($this->lakeID[$y][$x] == $id)) { + return; + } + $this->lakeID[$y][$x] = $id; + $this->floodFill($x - 1, $y, $id); + $this->floodFill($x + 1, $y, $id); + $this->floodFill($x, $y - 1, $id); + $this->floodFill($x, $y + 1, $id); + } +} + +?> +--EXPECTF-- +Fatal error: Uncaught TypeError: GameMap::getLakeArea(): Return value must be of type int, none returned in %s:%d +Stack trace: +#0 %s(%d): GameMap->getLakeArea(0, 0) +#1 {main} + thrown in %s on line %d diff --git a/ext/opcache/tests/jit/gh19493-001.phpt b/ext/opcache/tests/jit/gh19493-001.phpt new file mode 100644 index 000000000000..68e5d6e24019 --- /dev/null +++ b/ext/opcache/tests/jit/gh19493-001.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19493 001: Var not stored before YIELD +--FILE-- +getReturn()); + +?> +--EXPECT-- +int(99) diff --git a/ext/opcache/tests/jit/gh19493-002.phpt b/ext/opcache/tests/jit/gh19493-002.phpt new file mode 100644 index 000000000000..57f2a9826730 --- /dev/null +++ b/ext/opcache/tests/jit/gh19493-002.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19493 002: Var not stored before YIELD_FROM +--FILE-- +getReturn()); + +?> +--EXPECT-- +int(99) diff --git a/ext/opcache/tests/jit/gh19669-001.phpt b/ext/opcache/tests/jit/gh19669-001.phpt new file mode 100644 index 000000000000..e8c54c542c83 --- /dev/null +++ b/ext/opcache/tests/jit/gh19669-001.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-19669: assertion failure zend_jit_trace_type_to_info_ex +--CREDITS-- +YuanchengJiang +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: The float -1.8446744073709552E+19 is not representable as an int, cast occurred in %s on line %d +int(-3) diff --git a/ext/opcache/tests/jit/gh19669-002.phpt b/ext/opcache/tests/jit/gh19669-002.phpt new file mode 100644 index 000000000000..3a1aa0aa958c --- /dev/null +++ b/ext/opcache/tests/jit/gh19669-002.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-19669 002: assertion failure zend_jit_trace_type_to_info_ex +--CREDITS-- +YuanchengJiang +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: The float -1.8446744073709552E+19 is not representable as an int, cast occurred in %s on line %d +int(-10) diff --git a/ext/opcache/tests/jit/gh19831_001.phpt b/ext/opcache/tests/jit/gh19831_001.phpt new file mode 100644 index 000000000000..c83ca6daa50d --- /dev/null +++ b/ext/opcache/tests/jit/gh19831_001.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-19831 001: fetch obj slow R REG + reference +--CREDITS-- +dktapps +--ENV-- +RT_COND=1 +--INI-- +opcache.jit=1203 +--FILE-- +layers; + } +} + +$t = new Test(); +$a = &$t->layers; +var_dump($t->getLayers()); + +?> +--EXPECT-- +int(1) diff --git a/ext/opcache/tests/jit/gh19831_002.phpt b/ext/opcache/tests/jit/gh19831_002.phpt new file mode 100644 index 000000000000..25b596a3decb --- /dev/null +++ b/ext/opcache/tests/jit/gh19831_002.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-19831 002: fetch obj slow R REG + __get + reference +--CREDITS-- +dktapps +--ENV-- +RT_COND=1 +--INI-- +opcache.jit=1203 +--FILE-- +layers; + } +} + +$t = new Test(); +unset($t->layers); +var_dump($t->getLayers()); + +?> +--EXPECT-- +int(1) diff --git a/ext/opcache/tests/jit/gh20818.phpt b/ext/opcache/tests/jit/gh20818.phpt new file mode 100644 index 000000000000..9423856b66be --- /dev/null +++ b/ext/opcache/tests/jit/gh20818.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-20818 (Segfault in Tracing JIT with Object Reference) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=1M +--FILE-- + 1], + (object) ["" => 1], + (object) [], +]; + +for ($i = 0; $i < 200; $i += 1) { + foreach ($data as $entry) { + process($entry); + } +} + +echo "Done\n"; +?> +--EXPECT-- +Done diff --git a/ext/opcache/tests/jit/gh20838.inc b/ext/opcache/tests/jit/gh20838.inc new file mode 100644 index 000000000000..997cc23b8fee --- /dev/null +++ b/ext/opcache/tests/jit/gh20838.inc @@ -0,0 +1,53 @@ + $value) { + if ($k[$key]['st'] == 'correction') $s += $value; + else { + if ($k[$key]['st'] == 'caa') $value = $value / $avc[$key]; + $s += $value / 5 * $k[$key]['tp'] * (1 + 50 / $k[$key]['tp'] * $pav / (100 * $c)); + } + } + } + + echo("$id $s\n"); + + return $s; +} diff --git a/ext/opcache/tests/jit/gh20838.phpt b/ext/opcache/tests/jit/gh20838.phpt new file mode 100644 index 000000000000..bccf0a0ed8c3 --- /dev/null +++ b/ext/opcache/tests/jit/gh20838.phpt @@ -0,0 +1,66 @@ +--TEST-- +GH-20838 (JIT compiler produces wrong arithmetic results) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=64M +opcache.jit_hot_loop=61 +opcache.jit_hot_func=127 +opcache.jit_hot_return=8 +opcache.jit_hot_side_exit=8 +--EXTENSIONS-- +opcache +--FILE_EXTERNAL-- +gh20838.inc +--EXPECT-- +49 0 +1080 18 +4415 31.25 +4763 75 +4926 75 +4933 60 +4935 75 +4938 75 +4939 75 +4947 60 +4952 45 +4953 75 +4962 60 +8558 45 +14888 45 +16879 13 +100003 0 +100007 60 +100013 0 +100017 13 +100019 15 +100027 45 +100031 30 +106427 -37.5 +217955 -9 +240000 30 +240010 60 +240021 45 +240079 112.66666666667 +240210 45 +240227 45 +240249 75 +240273 75 +240333 30 +240335 60 +300024 96.5 +310001 45 +310025 45 +310034 60 +310042 30 +310111 75 +310191 45 +310219 75 +310236 15 +310322 45 +310356 30 +310360 21.25 +310394 29.5 +310405 75 +310411 60 diff --git a/ext/opcache/tests/jit/gh20880.phpt b/ext/opcache/tests/jit/gh20880.phpt new file mode 100644 index 000000000000..e8d0388fe66b --- /dev/null +++ b/ext/opcache/tests/jit/gh20880.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-20880 (JIT (tracing): NAN float comparisons incorrectly return true) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--FILE-- + $max) { + return $value; + } + return $max; +} + + +$max = 0.0; +for ($i = 0; $i < 100000; $i++) { + $max = observe(1.0, $max); + $max = observe(3.0, $max); +} + +$max = observe(4.0, $max); +$max = observe(NAN, $max); +var_dump($max); +?> +--EXPECT-- +float(4) diff --git a/ext/opcache/tests/jit/gh21158.phpt b/ext/opcache/tests/jit/gh21158.phpt new file mode 100644 index 000000000000..89afd058c665 --- /dev/null +++ b/ext/opcache/tests/jit/gh21158.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-21158: Assertion jit->ra[var].flags & (1<<0) failed in zend_jit_use_reg +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=1254 +--FILE-- += 0 && $col - 1 >= 0 && $board[$row - 1][$col - 1] == 1) $live_neighbors++; + if ($row >= 1 && $col + 1 < COL && $board[$row - 1][$col + 1] == 1) $live_neighbors++; + return $live_neighbors; +} +$board = [ + [1,1,0,0,1,1,1,1,1,0], + [0,1,0,1,1,0,0,1,0,0], + [0,1,0,0,1,0,0,0,1,0], + [0,0,1,1,1,1,1,0,0,0], + [1,1,1,1,1,1,0,1,1,0], + [0,1,0,0,1,1,1,0,1,0], + [0,1,1,0,1,1,1,1,0,0], + [1,1,0,0,0,0,1,1,1,0], + [1,0,0,1,1,0,1,1,0,1], + [0,0,1,1,1,0,1,1,0,1], +]; +for ($i = 0; $i < ROW; $i++) { + for ($j = 0; $j < COL; $j++) { + echo count_live_neighbors($board, $i, $j), ","; + } + echo "\n"; +} +?> +--EXPECT-- +1,0,0,1,1,1,1,1,0,0, +2,1,2,2,1,2,3,2,1,1, +2,0,2,2,1,1,1,1,1,0, +1,1,2,2,1,2,0,1,0,1, +1,2,2,3,3,2,2,2,0,0, +2,2,2,3,3,2,2,2,1,1, +2,1,1,2,2,3,2,2,0,1, +2,1,1,2,1,3,3,2,1,0, +1,1,2,1,0,2,2,2,2,1, +0,2,2,2,1,3,2,1,3,0, diff --git a/ext/opcache/tests/jit/gh21264-1.phpt b/ext/opcache/tests/jit/gh21264-1.phpt new file mode 100644 index 000000000000..ec6cf407fa3b --- /dev/null +++ b/ext/opcache/tests/jit/gh21264-1.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-21264: Missing reference unwrap for FE_FETCH_R in JIT +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=function +--FILE-- +array); + } +} + +function test() { + $c = new C; + $element = 'qux'; + $c->array = [&$element, &$element]; + var_dump($c->test()); +} + +test(); +test(); + +?> +--EXPECT-- +array(2) { + [0]=> + string(3) "qux" + [1]=> + string(3) "qux" +} +array(2) { + [0]=> + string(3) "qux" + [1]=> + string(3) "qux" +} diff --git a/ext/opcache/tests/jit/gh21264-2.phpt b/ext/opcache/tests/jit/gh21264-2.phpt new file mode 100644 index 000000000000..0729546a959d --- /dev/null +++ b/ext/opcache/tests/jit/gh21264-2.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21264: Missing reference unwrap for FE_FETCH_R in JIT +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +--FILE-- +prop) { + $c->prop++; + } +} + +$element = 0; +$array = [&$element, &$element]; +test($array); +test($array); +var_dump($element); + +?> +--EXPECT-- +int(0) diff --git a/ext/opcache/tests/jit/gh21267.phpt b/ext/opcache/tests/jit/gh21267.phpt new file mode 100644 index 000000000000..91c8de29c2bf --- /dev/null +++ b/ext/opcache/tests/jit/gh21267.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-21267 (JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property in polymorphic context) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=64M +opcache.jit_hot_loop=0 +opcache.jit_hot_func=2 +opcache.jit_hot_return=0 +opcache.jit_hot_side_exit=1 +--FILE-- +x; } +} + +$o1 = new C; +$o2 = new C; +$o2->x = false; +$o3 = new C; +unset($o3->x); +$a = [$o1, $o2, $o3]; + +for ($i = 0; $i < 8; $i++) { + $m = $a[$i % 3]; + $m->getX(); + $m->getX(); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/gh21267_blacklist.phpt b/ext/opcache/tests/jit/gh21267_blacklist.phpt new file mode 100644 index 000000000000..3ec222dc4250 --- /dev/null +++ b/ext/opcache/tests/jit/gh21267_blacklist.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-21267 (JIT infinite loop on FETCH_OBJ_R with IS_UNDEF via blacklisted trace exit) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=tracing +opcache.jit_buffer_size=64M +opcache.jit_hot_loop=0 +opcache.jit_hot_func=2 +opcache.jit_hot_return=0 +opcache.jit_hot_side_exit=1 +opcache.jit_max_side_traces=0 +--FILE-- +x; } +} + +$o1 = new C; +$o2 = new C; +$o2->x = false; +$o3 = new C; +unset($o3->x); +$a = [$o1, $o2, $o3]; + +for ($i = 0; $i < 8; $i++) { + $m = $a[$i % 3]; + $m->getX(); + $m->getX(); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/gh21368_call_vm.phpt b/ext/opcache/tests/jit/gh21368_call_vm.phpt new file mode 100644 index 000000000000..cc64e62a610e --- /dev/null +++ b/ext/opcache/tests/jit/gh21368_call_vm.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-21368 (JIT escape_if_undef SEGV on CALL VM with aggressive trace counters) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=64M +opcache.jit=tracing +opcache.protect_memory=1 +opcache.jit_hot_loop=1 +opcache.jit_hot_func=1 +opcache.jit_hot_return=1 +opcache.jit_hot_side_exit=1 +--FILE-- +x; } +} + +$o1 = new C; +$o2 = new C; +$o2->x = false; +$o3 = new C; +unset($o3->x); +$a = [$o1, $o2, $o3]; + +for ($i = 0; $i < 8; $i++) { + $m = $a[$i % 3]; + $m->getX(); + $m->getX(); +} +?> +OK +--EXPECT-- +OK diff --git a/ext/opcache/tests/jit/gh21593.phpt b/ext/opcache/tests/jit/gh21593.phpt new file mode 100644 index 000000000000..d37500195737 --- /dev/null +++ b/ext/opcache/tests/jit/gh21593.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-21593: Function JIT JMPNZ smart branch +--CREDITS-- +paulmhh +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit=function +--FILE-- +a)) { + echo "1\n"; + } +} + +function test2($a) { + if (!isset($a?->a)) { + echo "2\n"; + } +} + +function test3($a) { + if (empty($a?->a)) { + echo "3\n"; + } +} + +function test4($a) { + if (!empty($a?->a)) { + echo "4\n"; + } +} + +$a = new stdClass; +$a->a = 'a'; + +test1($a); +test2($a); +test3($a); +test4($a); + +?> +--EXPECT-- +1 +4 diff --git a/ext/opcache/tests/jit/gh21746.inc b/ext/opcache/tests/jit/gh21746.inc new file mode 100644 index 000000000000..b118625484d0 --- /dev/null +++ b/ext/opcache/tests/jit/gh21746.inc @@ -0,0 +1,16 @@ + ''; + $e = fn() => ''; + $f = fn() => ''; + $g = fn() => ''; + return '' + .LR::p(null, '', null, [], '') + .LR::hbbch([null], $d) + .LR::hbbch([null], $e) + .LR::hbbch([null], $f) + .LR::hbbch([null], $g); +}; diff --git a/ext/opcache/tests/jit/gh21746.phpt b/ext/opcache/tests/jit/gh21746.phpt new file mode 100644 index 000000000000..29b3be778be7 --- /dev/null +++ b/ext/opcache/tests/jit/gh21746.phpt @@ -0,0 +1,112 @@ +--TEST-- +GH-21746: Segfault with tracing JIT on 2nd call of eval'd closure +--CREDITS-- +theodorejb +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=tracing +--FILE-- + $_) { if ($i === 0) break; } + return $result; + } + public static function hbbch(array $positional, ?\Closure $cb): string { + if ($cb && is_array($positional[0] ?? null)) foreach ($positional[0] as $v) $cb($v); + return ''; + } +} + +$renderFile = __DIR__ . '/gh21746.inc'; + +// prevent JITing $renderFile +ini_set('opcache.file_update_protection', 100); +touch($renderFile); + +$renderer = require $renderFile; + +for ($r = 0; $r < 70; $r++) { + echo "Render $r..."; + $renderer(); + echo "OK\n"; +} + +?> +==DONE== +--EXPECT-- +Render 0...OK +Render 1...OK +Render 2...OK +Render 3...OK +Render 4...OK +Render 5...OK +Render 6...OK +Render 7...OK +Render 8...OK +Render 9...OK +Render 10...OK +Render 11...OK +Render 12...OK +Render 13...OK +Render 14...OK +Render 15...OK +Render 16...OK +Render 17...OK +Render 18...OK +Render 19...OK +Render 20...OK +Render 21...OK +Render 22...OK +Render 23...OK +Render 24...OK +Render 25...OK +Render 26...OK +Render 27...OK +Render 28...OK +Render 29...OK +Render 30...OK +Render 31...OK +Render 32...OK +Render 33...OK +Render 34...OK +Render 35...OK +Render 36...OK +Render 37...OK +Render 38...OK +Render 39...OK +Render 40...OK +Render 41...OK +Render 42...OK +Render 43...OK +Render 44...OK +Render 45...OK +Render 46...OK +Render 47...OK +Render 48...OK +Render 49...OK +Render 50...OK +Render 51...OK +Render 52...OK +Render 53...OK +Render 54...OK +Render 55...OK +Render 56...OK +Render 57...OK +Render 58...OK +Render 59...OK +Render 60...OK +Render 61...OK +Render 62...OK +Render 63...OK +Render 64...OK +Render 65...OK +Render 66...OK +Render 67...OK +Render 68...OK +Render 69...OK +==DONE== diff --git a/ext/opcache/tests/jit/gh22004.phpt b/ext/opcache/tests/jit/gh22004.phpt new file mode 100644 index 000000000000..bb60868a269f --- /dev/null +++ b/ext/opcache/tests/jit/gh22004.phpt @@ -0,0 +1,63 @@ +--TEST-- +GH-22004: ZEND_FE_FETCH_R with key operand +--CREDITS-- +YuanchengJiang +--FILE-- + $line) { + } + } +} +$iter = 20; +doRandom($iter); + +?> +==DONE== +--EXPECTF-- +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d + +Warning: Undefined variable $nLines in %s on line %d +==DONE== diff --git a/ext/opcache/tests/jit/inc_022.phpt b/ext/opcache/tests/jit/inc_022.phpt index 9b13f51dc23d..2c091d98d408 100644 --- a/ext/opcache/tests/jit/inc_022.phpt +++ b/ext/opcache/tests/jit/inc_022.phpt @@ -22,7 +22,8 @@ var_dump(inc(1.1)); var_dump(dec("5")); var_dump(dec(1.1)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(3) "abd" int(6) float(2.1) diff --git a/ext/opcache/tests/jit/inc_023.phpt b/ext/opcache/tests/jit/inc_023.phpt index ef832c096ae7..516e5a45aa7d 100644 --- a/ext/opcache/tests/jit/inc_023.phpt +++ b/ext/opcache/tests/jit/inc_023.phpt @@ -19,7 +19,11 @@ var_dump(++$test->prop); var_dump(--$test->prop); ?> --EXPECTF-- +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d + Deprecated: Decrement on non-numeric string has no effect and is deprecated in %s on line %d + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(1) "c" Deprecated: Decrement on non-numeric string has no effect and is deprecated in %s on line %d diff --git a/ext/opcache/tests/jit/inc_024.phpt b/ext/opcache/tests/jit/inc_024.phpt index e125f9b084df..5e6e2bbfe75f 100644 --- a/ext/opcache/tests/jit/inc_024.phpt +++ b/ext/opcache/tests/jit/inc_024.phpt @@ -23,52 +23,52 @@ function test($b) { test("0"); ?> --EXPECTF-- -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d Deprecated: Decrement on non-numeric string has no effect and is deprecated in %s on line %d -Deprecated: Increment on non-alphanumeric string is deprecated in %s on line %d +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d string(5) "-INF0" string(260) "0-2-12-112-1112-11112-111112-1111112-11111112-111111112-1111111112-11111111112-111111111112-1111111111112-11111111111112-111111111111112-1111111111111112-11111111111111112-111111111111111112-1111111111111111112-1.1111111111111E+20-1.1111111111111E+191-ING-INF1" diff --git a/ext/opcache/tests/jit/nan_001.phpt b/ext/opcache/tests/jit/nan_001.phpt index 3ff102745414..5765adcf5f78 100644 --- a/ext/opcache/tests/jit/nan_001.phpt +++ b/ext/opcache/tests/jit/nan_001.phpt @@ -13,7 +13,12 @@ for ($i = 0; $i < 3; $i++) { else { echo "nan is false\n"; } } ?> ---EXPECT-- +--EXPECTF-- +Warning: unexpected NAN value was coerced to bool in %s on line 4 nan is true + +Warning: unexpected NAN value was coerced to bool in %s on line 4 nan is true + +Warning: unexpected NAN value was coerced to bool in %s on line 4 nan is true diff --git a/ext/opcache/tests/jit/nan_002.phpt b/ext/opcache/tests/jit/nan_002.phpt index 01cb1ebb40d4..8d6ac8e11111 100644 --- a/ext/opcache/tests/jit/nan_002.phpt +++ b/ext/opcache/tests/jit/nan_002.phpt @@ -9,13 +9,13 @@ opcache.protect_memory=1 ---EXPECT-- +--EXPECTF-- +Warning: unexpected NAN value was coerced to bool in %s on line 3 string(1) "1" + +Warning: unexpected NAN value was coerced to bool in %s on line 4 + +Warning: unexpected NAN value was coerced to bool in %s on line 5 bool(true) + +Warning: unexpected NAN value was coerced to bool in %s on line 6 bool(false) string(1) "1" @@ -46,10 +53,14 @@ string(1) "2" bool(false) bool(true) + +Warning: unexpected NAN value was coerced to bool in %s on line 10 bool(true) bool(true) bool(false) + +Warning: unexpected NAN value was coerced to bool in %s on line 13 bool(true) bool(true) bool(false) diff --git a/ext/opcache/tests/jit/nan_bool_cast.phpt b/ext/opcache/tests/jit/nan_bool_cast.phpt new file mode 100644 index 000000000000..0a68a682412f --- /dev/null +++ b/ext/opcache/tests/jit/nan_bool_cast.phpt @@ -0,0 +1,15 @@ +--TEST-- +Const NAN with bool cast should emit 1 warning +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECTF-- +Warning: unexpected NAN value was coerced to bool in %s on line 2 +1 diff --git a/ext/opcache/tests/jit/preload_gh14082.inc b/ext/opcache/tests/jit/preload_gh14082.inc new file mode 100644 index 000000000000..f5b11ac621eb --- /dev/null +++ b/ext/opcache/tests/jit/preload_gh14082.inc @@ -0,0 +1,9 @@ + --EXPECTF-- -Deprecated: Implicit conversion from float 4294967168 to int loses precision in %s on line %d +Warning: The float 4294967168 is not representable as an int, cast occurred in %s on line %d correct diff --git a/ext/opcache/tests/match/001.phpt b/ext/opcache/tests/match/001.phpt index 502400681cf1..9d9ad2ac9e32 100644 --- a/ext/opcache/tests/match/001.phpt +++ b/ext/opcache/tests/match/001.phpt @@ -34,17 +34,17 @@ $_main: 0000 INIT_FCALL 2 %d string("range") 0001 SEND_VAL string("a") 1 0002 SEND_VAL string("i") 2 -0003 V2 = DO_ICALL -0004 V1 = FE_RESET_R V2 0013 -0005 FE_FETCH_R V1 CV0($char) 0013 +0003 T2 = DO_ICALL +0004 T1 = FE_RESET_R T2 0013 +0005 FE_FETCH_R T1 CV0($char) 0013 0006 INIT_FCALL 1 %d string("var_dump") 0007 INIT_FCALL 1 %d string("test") 0008 SEND_VAR CV0($char) 1 -0009 V2 = DO_UCALL -0010 SEND_VAR V2 1 +0009 T2 = DO_UCALL +0010 SEND_VAL T2 1 0011 DO_ICALL 0012 JMP 0005 -0013 FE_FREE V1 +0013 FE_FREE T1 0014 RETURN int(1) LIVE RANGES: 1: 0005 - 0013 (loop) diff --git a/ext/opcache/tests/match/003.phpt b/ext/opcache/tests/match/003.phpt index 24f3cd261210..8bed84717883 100644 --- a/ext/opcache/tests/match/003.phpt +++ b/ext/opcache/tests/match/003.phpt @@ -35,17 +35,17 @@ $_main: 0000 INIT_FCALL 2 %d string("range") 0001 SEND_VAL int(0) 1 0002 SEND_VAL int(10) 2 -0003 V2 = DO_ICALL -0004 V1 = FE_RESET_R V2 0013 -0005 FE_FETCH_R V1 CV0($char) 0013 +0003 T2 = DO_ICALL +0004 T1 = FE_RESET_R T2 0013 +0005 FE_FETCH_R T1 CV0($char) 0013 0006 INIT_FCALL 1 %d string("var_dump") 0007 INIT_FCALL 1 %d string("test") 0008 SEND_VAR CV0($char) 1 -0009 V2 = DO_UCALL -0010 SEND_VAR V2 1 +0009 T2 = DO_UCALL +0010 SEND_VAL T2 1 0011 DO_ICALL 0012 JMP 0005 -0013 FE_FREE V1 +0013 FE_FREE T1 0014 RETURN int(1) LIVE RANGES: 1: 0005 - 0013 (loop) diff --git a/ext/opcache/tests/match/004.phpt b/ext/opcache/tests/match/004.phpt index d9d4149b9451..ae7b40f20f58 100644 --- a/ext/opcache/tests/match/004.phpt +++ b/ext/opcache/tests/match/004.phpt @@ -40,24 +40,24 @@ $_main: 0000 INIT_FCALL 2 %d string("range") 0001 SEND_VAL int(0) 1 0002 SEND_VAL int(6) 2 -0003 V2 = DO_ICALL -0004 V1 = FE_RESET_R V2 0020 -0005 FE_FETCH_R V1 CV0($number) 0020 +0003 T2 = DO_ICALL +0004 T1 = FE_RESET_R T2 0020 +0005 FE_FETCH_R T1 CV0($number) 0020 0006 INIT_FCALL 1 %d string("var_dump") 0007 INIT_FCALL 1 %d string("test") 0008 SEND_VAR CV0($number) 1 -0009 V2 = DO_UCALL -0010 SEND_VAR V2 1 +0009 T2 = DO_UCALL +0010 SEND_VAL T2 1 0011 DO_ICALL 0012 INIT_FCALL 1 %d string("var_dump") 0013 INIT_FCALL 1 %d string("test") 0014 T2 = CAST (string) CV0($number) 0015 SEND_VAL T2 1 -0016 V2 = DO_UCALL -0017 SEND_VAR V2 1 +0016 T2 = DO_UCALL +0017 SEND_VAL T2 1 0018 DO_ICALL 0019 JMP 0005 -0020 FE_FREE V1 +0020 FE_FREE T1 0021 RETURN int(1) LIVE RANGES: 1: 0005 - 0020 (loop) diff --git a/ext/opcache/tests/named_parameter_new.phpt b/ext/opcache/tests/named_parameter_new.phpt new file mode 100644 index 000000000000..f8979766421c --- /dev/null +++ b/ext/opcache/tests/named_parameter_new.phpt @@ -0,0 +1,72 @@ +--TEST-- +Named Parameters are optimized for known constructors +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.opt_debug_level=0x20000 +--SKIPIF-- + +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECTF-- +$_main: + ; (lines=4, args=0, vars=0, tmps=%d) + ; (after optimizer) + ; %s +0000 INIT_STATIC_METHOD_CALL 1 string("MyClass") string("new") +0001 SEND_VAL int(1) 1 +0002 DO_UCALL +0003 RETURN int(1) + +MyClass::__construct: + ; (lines=7, args=2, vars=2, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($foo) = RECV 1 +0001 CV1($bar) = RECV_INIT 2 int(0) +0002 ASSIGN_OBJ THIS string("foo") +0003 OP_DATA CV0($foo) +0004 ASSIGN_OBJ THIS string("bar") +0005 OP_DATA CV1($bar) +0006 RETURN null + +MyClass::new: + ; (lines=10, args=1, vars=2, tmps=%d) + ; (after optimizer) + ; %s +0000 CV0($bar) = RECV 1 +0001 T2 = NEW 1 string("Random\\Engine\\Xoshiro256StarStar") +0002 SEND_VAL int(123) 1 +0003 DO_FCALL +0004 CV1($engine) = QM_ASSIGN T2 +0005 T2 = NEW 2 (self) (exception) +0006 SEND_VAR CV1($engine) 1 +0007 SEND_VAR CV0($bar) 2 +0008 DO_FCALL +0009 RETURN T2 +LIVE RANGES: + 2: 0002 - 0004 (new) + 2: 0006 - 0009 (new) diff --git a/ext/opcache/tests/nodiscard_001.phpt b/ext/opcache/tests/nodiscard_001.phpt index 7e232f8f44e4..8f87e7877bcf 100644 --- a/ext/opcache/tests/nodiscard_001.phpt +++ b/ext/opcache/tests/nodiscard_001.phpt @@ -33,28 +33,28 @@ $_main: 0000 INIT_FCALL 0 %d string("zend_test_nodiscard") 0001 DO_FCALL_BY_NAME 0002 INIT_FCALL 0 %d string("zend_test_nodiscard") -0003 V2 = DO_ICALL -0004 FREE V2 +0003 T2 = DO_ICALL +0004 FREE T2 0005 INIT_FCALL 0 %d string("zend_test_nodiscard") -0006 V2 = DO_ICALL -0007 ASSIGN CV0($success) V2 +0006 T2 = DO_ICALL +0007 ASSIGN CV0($success) T2 0008 INIT_FCALL 0 %d string("test") 0009 DO_FCALL_BY_NAME 0010 INIT_FCALL 0 %d string("test") -0011 V2 = DO_UCALL -0012 FREE V2 +0011 T2 = DO_UCALL +0012 FREE T2 0013 INIT_FCALL 0 %d string("test") -0014 V2 = DO_UCALL -0015 ASSIGN CV1($obj) V2 +0014 T2 = DO_UCALL +0015 ASSIGN CV1($obj) T2 0016 RETURN int(1) test: ; (lines=3, args=0, vars=0, tmps=%d) ; (after optimizer) ; %s -0000 V0 = NEW 0 string("stdClass") +0000 T0 = NEW 0 string("stdClass") 0001 DO_FCALL -0002 RETURN V0 +0002 RETURN T0 LIVE RANGES: 0: 0001 - 0002 (new) diff --git a/ext/opcache/tests/opcache_enable_noop_001.phpt b/ext/opcache/tests/opcache_enable_noop_001.phpt new file mode 100644 index 000000000000..0e7f5bbc9879 --- /dev/null +++ b/ext/opcache/tests/opcache_enable_noop_001.phpt @@ -0,0 +1,24 @@ +--TEST-- +Dynamically setting opcache.enable does not warn when noop +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECTF-- +Should not warn: +Disabling: +Should warn: + +Warning: Zend OPcache can't be temporarily enabled (it may be only disabled until the end of request) in %s on line %d diff --git a/ext/opcache/tests/opcache_enable_noop_002.phpt b/ext/opcache/tests/opcache_enable_noop_002.phpt new file mode 100644 index 000000000000..994f2d22f4e4 --- /dev/null +++ b/ext/opcache/tests/opcache_enable_noop_002.phpt @@ -0,0 +1,18 @@ +--TEST-- +Dynamically setting opcache.enable warns when not a noop +--INI-- +opcache.enable=0 +opcache.enable_cli=1 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECTF-- +Should warn, since the INI was initialized to 0: + +Warning: Zend OPcache can't be temporarily enabled (it may be only disabled until the end of request) in %s on line %d diff --git a/ext/opcache/tests/opt/block_pass_003.phpt b/ext/opcache/tests/opt/block_pass_003.phpt index 25d32e1e4d70..c8690add9b83 100644 --- a/ext/opcache/tests/opt/block_pass_003.phpt +++ b/ext/opcache/tests/opt/block_pass_003.phpt @@ -1,5 +1,5 @@ --TEST-- -Block Pass 003: Inorrect constant substitution in FETCH_LIST_R +Block Pass 003: Incorrect constant substitution in FETCH_LIST_R --INI-- opcache.enable=1 opcache.enable_cli=1 @@ -16,5 +16,44 @@ function test() { test(); ?> DONE ---EXPECT-- +--EXPECTF-- +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d + +Warning: Cannot use int as array in %s on line %d DONE diff --git a/ext/opcache/tests/opt/block_pass_007.phpt b/ext/opcache/tests/opt/block_pass_007.phpt index b2dca320d9b7..1afecfc3e171 100644 --- a/ext/opcache/tests/opt/block_pass_007.phpt +++ b/ext/opcache/tests/opt/block_pass_007.phpt @@ -24,8 +24,8 @@ $_main: 0000 INIT_FCALL 2 %d string("random_int") 0001 SEND_VAL int(1) 1 0002 SEND_VAL int(2) 2 -0003 V1 = DO_ICALL -0004 ASSIGN CV0($f) V1 +0003 T1 = DO_ICALL +0004 ASSIGN CV0($f) T1 0005 INIT_FCALL 1 %d string("var_dump") 0006 T1 = BOOL_NOT CV0($f) 0007 SEND_VAL T1 1 diff --git a/ext/opcache/tests/opt/dce_006.phpt b/ext/opcache/tests/opt/dce_006.phpt index 2596651ed3e9..2c1fe749ae98 100644 --- a/ext/opcache/tests/opt/dce_006.phpt +++ b/ext/opcache/tests/opt/dce_006.phpt @@ -31,9 +31,9 @@ foo: ; (after optimizer) ; %sdce_006.php:5-8 0000 CV0($x) = RECV 1 -0001 V2 = NEW 0 string("A") +0001 T2 = NEW 0 string("A") 0002 DO_FCALL -0003 CV1($a) = QM_ASSIGN V2 +0003 CV1($a) = QM_ASSIGN T2 0004 ASSIGN_OBJ CV1($a) string("foo") 0005 OP_DATA CV0($x) 0006 RETURN null diff --git a/ext/opcache/tests/opt/gh11170.phpt b/ext/opcache/tests/opt/gh11170.phpt index 9ea733f92b10..ae26cb4081f4 100644 --- a/ext/opcache/tests/opt/gh11170.phpt +++ b/ext/opcache/tests/opt/gh11170.phpt @@ -65,8 +65,8 @@ BB0: ; level=0 ; children=(BB1, BB2, BB3) 0000 INIT_FCALL 0 %d string("rand") -0001 #2.V2 [long] = DO_ICALL -0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10) +0001 #2.T2 [long] = DO_ICALL +0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.T2 [long] int(10) 0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2 BB1: @@ -111,8 +111,8 @@ BB0: ; level=0 ; children=(BB1, BB2, BB3) 0000 INIT_FCALL 0 %d string("rand") -0001 #2.V2 [long] = DO_ICALL -0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10) +0001 #2.T2 [long] = DO_ICALL +0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.T2 [long] int(10) 0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2 BB1: diff --git a/ext/opcache/tests/opt/gh11245_2.phpt b/ext/opcache/tests/opt/gh11245_2.phpt index f42da12c5274..74aec8d7f8a8 100644 --- a/ext/opcache/tests/opt/gh11245_2.phpt +++ b/ext/opcache/tests/opt/gh11245_2.phpt @@ -28,9 +28,11 @@ $_main: 0000 T1 = PRE_INC_STATIC_PROP string("prop") string("X") 0001 T2 = ISSET_ISEMPTY_CV (empty) CV0($xx) 0002 JMPZ T2 0005 -0003 FREE T1 +0003 FREE T1 loop-end(+2) 0004 RETURN null 0005 FREE T1 0006 RETURN int(1) LIVE RANGES: - 1: 0001 - 0005 (tmp/var) + 1: 0001 - 0003 (tmp/var) + +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %s on line %d diff --git a/ext/opcache/tests/opt/gh14873.phpt b/ext/opcache/tests/opt/gh14873.phpt index d442128d023c..20428b5bcd2b 100644 --- a/ext/opcache/tests/opt/gh14873.phpt +++ b/ext/opcache/tests/opt/gh14873.phpt @@ -62,44 +62,44 @@ $_main: 0000 INIT_FCALL 1 %d string("var_dump") 0001 INIT_FCALL 1 %d string("testtrim1") 0002 SEND_VAL string(" boo ") 1 -0003 V0 = DO_UCALL -0004 SEND_VAR V0 1 +0003 T0 = DO_UCALL +0004 SEND_VAL T0 1 0005 DO_ICALL 0006 INIT_FCALL 1 %d string("var_dump") 0007 INIT_FCALL 1 %d string("testmin2first") 0008 SEND_VAL int(5) 1 -0009 V0 = DO_UCALL -0010 SEND_VAR V0 1 +0009 T0 = DO_UCALL +0010 SEND_VAL T0 1 0011 DO_ICALL 0012 INIT_FCALL 1 %d string("var_dump") 0013 INIT_FCALL 1 %d string("testmin2second") 0014 SEND_VAL int(5) 1 -0015 V0 = DO_UCALL -0016 SEND_VAR V0 1 +0015 T0 = DO_UCALL +0016 SEND_VAL T0 1 0017 DO_ICALL 0018 INIT_FCALL 1 %d string("var_dump") 0019 INIT_FCALL 1 %d string("testmin2_tmp") 0020 SEND_VAL int(5) 1 -0021 V0 = DO_UCALL -0022 SEND_VAR V0 1 +0021 T0 = DO_UCALL +0022 SEND_VAL T0 1 0023 DO_ICALL 0024 INIT_FCALL 1 %d string("var_dump") 0025 INIT_FCALL 1 %d string("teststrstr3first") 0026 SEND_VAL string("needles") 1 -0027 V0 = DO_UCALL -0028 SEND_VAR V0 1 +0027 T0 = DO_UCALL +0028 SEND_VAL T0 1 0029 DO_ICALL 0030 INIT_FCALL 1 %d string("var_dump") 0031 INIT_FCALL 1 %d string("teststrstr3second") 0032 SEND_VAL string("needle") 1 -0033 V0 = DO_UCALL -0034 SEND_VAR V0 1 +0033 T0 = DO_UCALL +0034 SEND_VAL T0 1 0035 DO_ICALL 0036 INIT_FCALL 1 %d string("var_dump") 0037 INIT_FCALL 1 %d string("teststrstr3third") 0038 SEND_VAL bool(false) 1 -0039 V0 = DO_UCALL -0040 SEND_VAR V0 1 +0039 T0 = DO_UCALL +0040 SEND_VAL T0 1 0041 DO_ICALL 0042 RETURN int(1) diff --git a/ext/opcache/tests/opt/gh18107_1.phpt b/ext/opcache/tests/opt/gh18107_1.phpt index c99fa7efa40d..a2cf3162090c 100644 --- a/ext/opcache/tests/opt/gh18107_1.phpt +++ b/ext/opcache/tests/opt/gh18107_1.phpt @@ -29,18 +29,19 @@ $_main: ; %s 0000 T1 = ISSET_ISEMPTY_CV (isset) CV0($badvar) 0001 JMPNZ T1 0006 -0002 V3 = NEW 1 string("Exception") -0003 SEND_VAL_EX string("Should happen") 1 +0002 T3 = NEW 1 string("Exception") +0003 SEND_VAL%S string("Should happen") 1 0004 DO_FCALL -0005 THROW V3 +0005 THROW T3 0006 JMP 0006 -0007 V6 = NEW 1 string("Exception") -0008 SEND_VAL_EX string("Should not happen") 1 +0007 T6 = NEW 1 string("Exception") +0008 SEND_VAL%S string("Should not happen") 1 0009 DO_FCALL -0010 THROW V6 +0010 THROW T6 0011 FAST_RET T5 EXCEPTION TABLE: 0006, -, 0007, 0011 + Fatal error: Uncaught Exception: Should happen in %s:%d Stack trace: #0 {main} diff --git a/ext/opcache/tests/opt/gh18107_2.phpt b/ext/opcache/tests/opt/gh18107_2.phpt index 573bcd5ae4a6..74a709223e5a 100644 --- a/ext/opcache/tests/opt/gh18107_2.phpt +++ b/ext/opcache/tests/opt/gh18107_2.phpt @@ -32,22 +32,23 @@ $_main: ; %s 0000 T2 = ISSET_ISEMPTY_CV (isset) CV0($badvar) 0001 JMPNZ T2 0008 -0002 V4 = NEW 1 string("Exception") -0003 SEND_VAL_EX string("Should happen") 1 +0002 T4 = NEW 1 string("Exception") +0003 SEND_VAL%S string("Should happen") 1 0004 DO_FCALL -0005 THROW V4 +0005 THROW T4 0006 CV1($e) = CATCH string("Throwable") 0007 ECHO string("foo") 0008 T6 = FAST_CALL 0010 0009 JMP 0015 -0010 V7 = NEW 1 string("Exception") -0011 SEND_VAL_EX string("Should not happen") 1 +0010 T7 = NEW 1 string("Exception") +0011 SEND_VAL%S string("Should not happen") 1 0012 DO_FCALL -0013 THROW V7 +0013 THROW T7 0014 FAST_RET T6 0015 RETURN int(1) EXCEPTION TABLE: 0006, 0006, 0010, 0014 + Fatal error: Uncaught Exception: Should happen in %s:%d Stack trace: #0 {main} diff --git a/ext/opcache/tests/opt/gh19792.phpt b/ext/opcache/tests/opt/gh19792.phpt new file mode 100644 index 000000000000..edd805ca57a1 --- /dev/null +++ b/ext/opcache/tests/opt/gh19792.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-19792 (SCCP causes UAF for return value if both warning and exception are triggered) +--EXTENSIONS-- +opcache +zend_test +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECTF-- +Warning: a warning in %s on line %d +an exception diff --git a/ext/opcache/tests/opt/jmp_001.phpt b/ext/opcache/tests/opt/jmp_001.phpt index 71ff73671e81..c061d336c4b0 100644 --- a/ext/opcache/tests/opt/jmp_001.phpt +++ b/ext/opcache/tests/opt/jmp_001.phpt @@ -24,10 +24,11 @@ $_main: 0000 RETURN int(1) test: - ; (lines=4, args=0, vars=1, tmps=1) + ; (lines=5, args=0, vars=1, tmps=1) ; (after optimizer) ; %s:2-6 0000 INIT_FCALL_BY_NAME 0 string("test2") -0001 V1 = DO_FCALL_BY_NAME -0002 CV0($var) = QM_ASSIGN V1 -0003 RETURN CV0($var) +0001 VERIFY_GENERIC_ARGUMENTS +0002 T1 = DO_FCALL_BY_NAME +0003 CV0($var) = QM_ASSIGN T1 +0004 RETURN CV0($var) diff --git a/ext/opcache/tests/opt/sccp_022.phpt b/ext/opcache/tests/opt/sccp_022.phpt index ffcc48b0dccd..27d7b6d71928 100644 --- a/ext/opcache/tests/opt/sccp_022.phpt +++ b/ext/opcache/tests/opt/sccp_022.phpt @@ -51,14 +51,14 @@ bar: ; (lines=9, args=0, vars=3, tmps=2) ; (after optimizer) ; %s -0000 V3 = FE_RESET_R CV0($a) 0007 -0001 FE_FETCH_R V3 CV1($v) 0007 -0002 V4 = FE_RESET_R CV1($v) 0005 -0003 FE_FETCH_R V4 CV2($v2) 0005 +0000 T3 = FE_RESET_R CV0($a) 0007 +0001 FE_FETCH_R T3 CV1($v) 0007 +0002 T4 = FE_RESET_R CV1($v) 0005 +0003 FE_FETCH_R T4 CV2($v2) 0005 0004 JMP 0003 -0005 FE_FREE V4 +0005 FE_FREE T4 0006 JMP 0001 -0007 FE_FREE V3 +0007 FE_FREE T3 0008 RETURN null LIVE RANGES: 3: 0001 - 0007 (loop) diff --git a/ext/opcache/tests/opt/sccp_032.phpt b/ext/opcache/tests/opt/sccp_032.phpt index 6ee4a837ecd3..3db224845f30 100644 --- a/ext/opcache/tests/opt/sccp_032.phpt +++ b/ext/opcache/tests/opt/sccp_032.phpt @@ -30,27 +30,26 @@ $_main: ; (after optimizer) ; %ssccp_032.php:1-15 0000 INIT_FCALL 0 %d string("test") -0001 V2 = DO_UCALL -0002 V1 = FE_RESET_R V2 0009 -0003 FE_FETCH_R V1 CV0($x) 0009 +0001 T2 = DO_UCALL +0002 T1 = FE_RESET_R T2 0009 +0003 FE_FETCH_R T1 CV0($x) 0009 0004 INIT_FCALL 1 %d string("var_export") 0005 SEND_VAR CV0($x) 1 0006 DO_ICALL 0007 ECHO string("\n") 0008 JMP 0003 -0009 FE_FREE V1 +0009 FE_FREE T1 0010 RETURN int(1) LIVE RANGES: 1: 0003 - 0009 (loop) test: - ; (lines=5, args=0, vars=0, tmps=1) + ; (lines=4, args=0, vars=0, tmps=0) ; (after optimizer) ; %ssccp_032.php:2-9 0000 GENERATOR_CREATE 0001 YIELD null -0002 T0 = YIELD_FROM array(...) -0003 FREE T0 -0004 GENERATOR_RETURN null +0002 YIELD_FROM array(...) +0003 GENERATOR_RETURN null NULL 3 diff --git a/ext/opcache/tests/opt/sccp_038.phpt b/ext/opcache/tests/opt/sccp_038.phpt index 165206056c6e..b2d7e79c5fe0 100644 --- a/ext/opcache/tests/opt/sccp_038.phpt +++ b/ext/opcache/tests/opt/sccp_038.phpt @@ -15,5 +15,5 @@ foo(); ?> DONE --EXPECTF-- -Deprecated: Increment on non-alphanumeric string is deprecated in %ssccp_038.php on line 5 +Deprecated: Increment on non-numeric string is deprecated, use str_increment() instead in %ssccp_038.php on line 5 DONE diff --git a/ext/opcache/tests/opt/type_inference_final_class.phpt b/ext/opcache/tests/opt/type_inference_final_class.phpt index 3c4aa03d8cb4..be3b584b3c61 100644 --- a/ext/opcache/tests/opt/type_inference_final_class.phpt +++ b/ext/opcache/tests/opt/type_inference_final_class.phpt @@ -39,5 +39,5 @@ Test::getInt2: ; (lines=2, args=0, vars=0, tmps=1) ; (after optimizer) ; %s -0000 V0 = QM_ASSIGN int(42) -0001 RETURN V0 +0000 T0 = VERIFY_RETURN_TYPE int(42) +0001 RETURN T0 diff --git a/ext/opcache/tests/oss-fuzz-472563272.phpt b/ext/opcache/tests/oss-fuzz-472563272.phpt new file mode 100644 index 000000000000..39519abe9ae0 --- /dev/null +++ b/ext/opcache/tests/oss-fuzz-472563272.phpt @@ -0,0 +1,14 @@ +--TEST-- +OSS-Fuzz #472563272: Borked block_pass JMP[N]Z optimization +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/opcache/tests/oss-fuzz-481014628.phpt b/ext/opcache/tests/oss-fuzz-481014628.phpt new file mode 100644 index 000000000000..8aa6cf3fe1fd --- /dev/null +++ b/ext/opcache/tests/oss-fuzz-481014628.phpt @@ -0,0 +1,27 @@ +--TEST-- +OSS-Fuzz #481014628: Borked FETCH_W+ZEND_FETCH_GLOBAL_LOCK optimization +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--FILE-- + +--EXPECT-- +NULL +int(42) diff --git a/ext/opcache/tests/pipe_optimizations.phpt b/ext/opcache/tests/pipe_optimizations.phpt index 5a8750845ddc..018fbe79f42a 100644 --- a/ext/opcache/tests/pipe_optimizations.phpt +++ b/ext/opcache/tests/pipe_optimizations.phpt @@ -35,30 +35,28 @@ var_dump($res1); ?> --EXPECTF-- $_main: - ; (lines=18, args=0, vars=2, tmps=%d) + ; (lines=17, args=0, vars=2, tmps=%d) ; (after optimizer) ; %s:1-27 -0000 V2 = NEW 0 string("Other") +0000 T2 = NEW 0 string("Other") 0001 DO_FCALL -0002 ASSIGN CV0($o) V2 +0002 ASSIGN CV0($o) T2 0003 INIT_FCALL 1 %d string("_test1") 0004 SEND_VAL int(5) 1 0005 T2 = DO_UCALL 0006 INIT_METHOD_CALL 1 CV0($o) string("foo") -0007 SEND_VAL_EX T2 1 -0008 V3 = DO_FCALL -0009 T2 = QM_ASSIGN V3 -0010 INIT_STATIC_METHOD_CALL 1 string("Other") string("bar") -0011 SEND_VAL T2 1 -0012 V2 = DO_UCALL -0013 ASSIGN CV1($res1) V2 -0014 INIT_FCALL 1 %d string("var_dump") -0015 SEND_VAR CV1($res1) 1 -0016 DO_ICALL -0017 RETURN int(1) +0007 SEND_VAL T2 1 +0008 T2 = DO_UCALL +0009 INIT_STATIC_METHOD_CALL 1 string("Other") string("bar") +0010 SEND_VAL T2 1 +0011 T2 = DO_UCALL +0012 ASSIGN CV1($res1) T2 +0013 INIT_FCALL 1 %d string("var_dump") +0014 SEND_VAR CV1($res1) 1 +0015 DO_ICALL +0016 RETURN int(1) LIVE RANGES: 2: 0001 - 0002 (new) - 2: 0010 - 0011 (tmp/var) _test1: ; (lines=4, args=1, vars=1, tmps=%d) diff --git a/ext/opcache/tests/preload_dynamic_def_removal.inc b/ext/opcache/tests/preload_dynamic_def_removal.inc index 27ec69120eac..2a6a44ef509a 100644 --- a/ext/opcache/tests/preload_dynamic_def_removal.inc +++ b/ext/opcache/tests/preload_dynamic_def_removal.inc @@ -5,6 +5,15 @@ class Test { echo "dynamic\n"; } } + + public int $hook { + get { + function dynamic_in_hook() { + echo "dynamic in hook\n"; + } + return 1; + } + } } function func() { @@ -16,3 +25,4 @@ function func() { $test = new Test; $test->method(); func(); +$test->hook; diff --git a/ext/opcache/tests/preload_dynamic_def_removal.phpt b/ext/opcache/tests/preload_dynamic_def_removal.phpt index d4f2bb070ccd..acc26873e186 100644 --- a/ext/opcache/tests/preload_dynamic_def_removal.phpt +++ b/ext/opcache/tests/preload_dynamic_def_removal.phpt @@ -15,7 +15,9 @@ if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows --EXPECT-- dynamic dynamic2 +dynamic in hook diff --git a/ext/opcache/tests/preload_gh21059.inc b/ext/opcache/tests/preload_gh21059.inc new file mode 100644 index 000000000000..8f93bb45020b --- /dev/null +++ b/ext/opcache/tests/preload_gh21059.inc @@ -0,0 +1,7 @@ + +--FILE-- + +--EXPECT-- +Hello world diff --git a/ext/opcache/tests/revalidate_path_01.phpt b/ext/opcache/tests/revalidate_path_01.phpt index ff87e73b5544..c8cd1ea493a6 100644 --- a/ext/opcache/tests/revalidate_path_01.phpt +++ b/ext/opcache/tests/revalidate_path_01.phpt @@ -30,7 +30,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { @rmdir($link); $ln = str_replace('/', '\\', $link); $d1 = realpath($dir1); - `mklink /j $ln $d1`; + shell_exec("mklink /j $ln $d1"); } else { @unlink($link); @symlink($dir1, $link); @@ -45,7 +45,7 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { @rmdir($link); $ln = str_replace('/', '\\', $link); $d2 = realpath($dir2); - `mklink /j $ln $d2`; + shell_exec("mklink /j $ln $d2"); } else { @unlink($link); @symlink($dir2, $link); diff --git a/ext/opcache/tests/zzz_basic_logging.phpt b/ext/opcache/tests/zzz_basic_logging.phpt index a53c6a8db9de..88290f6a169d 100644 --- a/ext/opcache/tests/zzz_basic_logging.phpt +++ b/ext/opcache/tests/zzz_basic_logging.phpt @@ -13,12 +13,14 @@ opcache.log_verbosity_level=4 opcache.huge_code_pages=0 opcache.preload= opcache.interned_strings_buffer=8 +opcache.blacklist_filename= --EXTENSIONS-- opcache --SKIPIF-- --FILE-- . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ +*/ + +#include "zend_accelerator_api.h" +#include "ZendAccelerator.h" + +ZEND_API bool opcache_preloading(void) +{ + return ZCG(preloading); +} diff --git a/ext/opcache/zend_accelerator_api.h b/ext/opcache/zend_accelerator_api.h new file mode 100644 index 000000000000..002a69eee9f3 --- /dev/null +++ b/ext/opcache/zend_accelerator_api.h @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | Zend OPcache | + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_ACCELERATOR_API_H +#define ZEND_ACCELERATOR_API_H + +#include "Zend/zend_portability.h" + +BEGIN_EXTERN_C() + +/* Returns true during preloading */ +ZEND_API bool opcache_preloading(void); + +END_EXTERN_C() + +#endif /* ZEND_ACCELERATOR_API_H */ diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c index b7ffb164cdd2..ed03a82e9f3f 100644 --- a/ext/opcache/zend_accelerator_blacklist.c +++ b/ext/opcache/zend_accelerator_blacklist.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -205,7 +203,7 @@ void zend_accel_blacklist_shutdown(zend_blacklist *blacklist) return; } - zend_blacklist_entry *p = blacklist->entries, *end = blacklist->entries + blacklist->pos; + const zend_blacklist_entry *p = blacklist->entries, *end = blacklist->entries + blacklist->pos; while (ppath); p++; @@ -227,7 +225,7 @@ static inline void zend_accel_blacklist_allocate(zend_blacklist *blacklist) { if (blacklist->pos == blacklist->size) { blacklist->size += ZEND_BLACKLIST_BLOCK_SIZE; - blacklist->entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry)*blacklist->size); + blacklist->entries = (zend_blacklist_entry *) perealloc(blacklist->entries, sizeof(zend_blacklist_entry)*blacklist->size, true); } } @@ -336,14 +334,14 @@ void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename) zend_accel_blacklist_update_regexp(blacklist); } -bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *verify_path, size_t verify_path_len) +bool zend_accel_blacklist_is_blacklisted(const zend_blacklist *blacklist, const char *verify_path, size_t verify_path_len) { int ret = 0; - zend_regexp_list *regexp_list_it = blacklist->regexp_list; + const zend_regexp_list *regexp_list_it = blacklist->regexp_list; pcre2_match_context *mctx = php_pcre_mctx(); if (regexp_list_it == NULL) { - return 0; + return false; } while (regexp_list_it != NULL) { pcre2_match_data *match_data = php_pcre_create_match_data(0, regexp_list_it->re); @@ -363,7 +361,7 @@ bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *verify return ret; } -void zend_accel_blacklist_apply(zend_blacklist *blacklist, blacklist_apply_func_arg_t func, void *argument) +void zend_accel_blacklist_apply(const zend_blacklist *blacklist, blacklist_apply_func_arg_t func, void *argument) { int i; diff --git a/ext/opcache/zend_accelerator_blacklist.h b/ext/opcache/zend_accelerator_blacklist.h index 2a7921f63d94..4a337dd9814b 100644 --- a/ext/opcache/zend_accelerator_blacklist.h +++ b/ext/opcache/zend_accelerator_blacklist.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -45,7 +43,7 @@ void zend_accel_blacklist_init(zend_blacklist *blacklist); void zend_accel_blacklist_shutdown(zend_blacklist *blacklist); void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename); -bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *verify_path, size_t verify_path_len); -void zend_accel_blacklist_apply(zend_blacklist *blacklist, blacklist_apply_func_arg_t func, void *argument); +bool zend_accel_blacklist_is_blacklisted(const zend_blacklist *blacklist, const char *verify_path, size_t verify_path_len); +void zend_accel_blacklist_apply(const zend_blacklist *blacklist, blacklist_apply_func_arg_t func, void *argument); #endif /* ZEND_ACCELERATOR_BLACKLIST_H */ diff --git a/ext/opcache/zend_accelerator_debug.c b/ext/opcache/zend_accelerator_debug.c index b2a3105dc627..418ef805d633 100644 --- a/ext/opcache/zend_accelerator_debug.c +++ b/ext/opcache/zend_accelerator_debug.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_debug.h b/ext/opcache/zend_accelerator_debug.h index 4a19da57b5e6..d71a48893871 100644 --- a/ext/opcache/zend_accelerator_debug.h +++ b/ext/opcache/zend_accelerator_debug.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/opcache/zend_accelerator_hash.c b/ext/opcache/zend_accelerator_hash.c index 2fd3dfb5ed56..e35528f7f414 100644 --- a/ext/opcache/zend_accelerator_hash.c +++ b/ext/opcache/zend_accelerator_hash.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -138,7 +136,7 @@ zend_accel_hash_entry* zend_accel_hash_update(zend_accel_hash *accel_hash, zend_ return entry; } -static zend_always_inline void* zend_accel_hash_find_ex(zend_accel_hash *accel_hash, zend_string *key, int data) +static zend_always_inline void* zend_accel_hash_find_ex(const zend_accel_hash *accel_hash, zend_string *key, bool data) { zend_ulong index; zend_accel_hash_entry *entry; @@ -176,20 +174,20 @@ static zend_always_inline void* zend_accel_hash_find_ex(zend_accel_hash *accel_h /* Returns the data associated with key on success * Returns NULL if data doesn't exist */ -void* zend_accel_hash_find(zend_accel_hash *accel_hash, zend_string *key) +void* zend_accel_hash_find(const zend_accel_hash *accel_hash, zend_string *key) { - return zend_accel_hash_find_ex(accel_hash, key, 1); + return zend_accel_hash_find_ex(accel_hash, key, true); } /* Returns the hash entry associated with key on success * Returns NULL if it doesn't exist */ -zend_accel_hash_entry* zend_accel_hash_find_entry(zend_accel_hash *accel_hash, zend_string *key) +zend_accel_hash_entry* zend_accel_hash_find_entry(const zend_accel_hash *accel_hash, zend_string *key) { - return (zend_accel_hash_entry *)zend_accel_hash_find_ex(accel_hash, key, 0); + return (zend_accel_hash_entry *)zend_accel_hash_find_ex(accel_hash, key, false); } -int zend_accel_hash_unlink(zend_accel_hash *accel_hash, zend_string *key) +zend_result zend_accel_hash_unlink(zend_accel_hash *accel_hash, zend_string *key) { zend_ulong hash_value; zend_ulong index; diff --git a/ext/opcache/zend_accelerator_hash.h b/ext/opcache/zend_accelerator_hash.h index 755d3f13ec51..6091361a68c8 100644 --- a/ext/opcache/zend_accelerator_hash.h +++ b/ext/opcache/zend_accelerator_hash.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -72,23 +70,23 @@ zend_accel_hash_entry* zend_accel_hash_update( void *data); void* zend_accel_hash_find( - zend_accel_hash *accel_hash, + const zend_accel_hash *accel_hash, zend_string *key); zend_accel_hash_entry* zend_accel_hash_find_entry( - zend_accel_hash *accel_hash, + const zend_accel_hash *accel_hash, zend_string *key); -int zend_accel_hash_unlink( +zend_result zend_accel_hash_unlink( zend_accel_hash *accel_hash, zend_string *key); -static inline bool zend_accel_hash_is_full(zend_accel_hash *accel_hash) +static inline bool zend_accel_hash_is_full(const zend_accel_hash *accel_hash) { if (accel_hash->num_entries == accel_hash->max_num_entries) { - return 1; + return true; } else { - return 0; + return false; } } diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 203a41d93b40..465b15cd9576 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -25,13 +23,15 @@ #include "ZendAccelerator.h" #include "zend_API.h" #include "zend_closures.h" +#include "zend_extensions.h" +#include "zend_modules.h" #include "zend_shared_alloc.h" #include "zend_accelerator_blacklist.h" +#include "zend_file_cache.h" #include "php_ini.h" #include "SAPI.h" #include "zend_virtual_cwd.h" #include "ext/standard/info.h" -#include "ext/standard/php_filestat.h" #include "ext/date/php_date.h" #include "opcache_arginfo.h" @@ -59,7 +59,7 @@ static zif_handler orig_file_exists = NULL; static zif_handler orig_is_file = NULL; static zif_handler orig_is_readable = NULL; -static int validate_api_restriction(void) +static bool validate_api_restriction(void) { if (ZCG(accel_directives).restrict_api && *ZCG(accel_directives).restrict_api) { size_t len = strlen(ZCG(accel_directives).restrict_api); @@ -68,15 +68,24 @@ static int validate_api_restriction(void) strlen(SG(request_info).path_translated) < len || memcmp(SG(request_info).path_translated, ZCG(accel_directives).restrict_api, len) != 0) { zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " API is restricted by \"restrict_api\" configuration directive"); - return 0; + return false; } } - return 1; + return true; } static ZEND_INI_MH(OnUpdateMemoryConsumption) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + if (accel_startup_ok) { + if (strcmp(sapi_module.name, "fpm-fcgi") == 0) { + zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption cannot be changed when OPcache is already set up. Are you using php_admin_value[opcache.memory_consumption] in an individual pool's configuration?\n"); + } else { + zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption cannot be changed when OPcache is already set up.\n"); + } + return FAILURE; + } + + zend_long *p = ZEND_INI_GET_ADDR(); zend_long memsize = atoi(ZSTR_VAL(new_value)); /* sanity check we must use at least 8 MB */ if (memsize < 8) { @@ -93,7 +102,7 @@ static ZEND_INI_MH(OnUpdateMemoryConsumption) static ZEND_INI_MH(OnUpdateInternedStringsBuffer) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); zend_long size = zend_ini_parse_quantity_warn(new_value, entry->name); if (size < 0) { @@ -112,7 +121,7 @@ static ZEND_INI_MH(OnUpdateInternedStringsBuffer) static ZEND_INI_MH(OnUpdateMaxAcceleratedFiles) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); zend_long size = atoi(ZSTR_VAL(new_value)); /* sanity check we must use a value between MIN_ACCEL_FILES and MAX_ACCEL_FILES */ if (size < MIN_ACCEL_FILES) { @@ -129,7 +138,7 @@ static ZEND_INI_MH(OnUpdateMaxAcceleratedFiles) static ZEND_INI_MH(OnUpdateMaxWastedPercentage) { - double *p = (double *) ZEND_INI_GET_ADDR(); + double *p = ZEND_INI_GET_ADDR(); zend_long percentage = atoi(ZSTR_VAL(new_value)); if (percentage <= 0 || percentage > 50) { @@ -147,14 +156,27 @@ static ZEND_INI_MH(OnEnable) stage == ZEND_INI_STAGE_DEACTIVATE) { return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } else { - /* It may be only temporary disabled */ - bool *p = (bool *) ZEND_INI_GET_ADDR(); + /* It may be only temporarily disabled */ + bool *p = ZEND_INI_GET_ADDR(); if (zend_ini_parse_bool(new_value)) { - zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " can't be temporary enabled (it may be only disabled till the end of request)"); + if (*p) { + /* Do not warn if OPcache is enabled, as the update would be a noop anyways. */ + return SUCCESS; + } + + if (stage == ZEND_INI_STAGE_ACTIVATE) { + if (strcmp(sapi_module.name, "fpm-fcgi") == 0) { + zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " can't be temporarily enabled. Are you using php_admin_value[opcache.enable]=1 in an individual pool's configuration?"); + } else { + zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " can't be temporarily enabled (it may be only disabled until the end of request)"); + } + } else { + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " can't be temporarily enabled (it may be only disabled until the end of request)"); + } return FAILURE; } else { - *p = 0; - ZCG(accelerator_enabled) = 0; + *p = false; + ZCG(accelerator_enabled) = false; return SUCCESS; } } @@ -182,7 +204,7 @@ static ZEND_INI_MH(OnUpdateJit) static ZEND_INI_MH(OnUpdateJitDebug) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); if (zend_jit_debug_config(*p, val, stage) == SUCCESS) { @@ -196,7 +218,7 @@ static ZEND_INI_MH(OnUpdateCounter) { zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); if (val >= 0 && val < 256) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); *p = val; return SUCCESS; } @@ -208,7 +230,7 @@ static ZEND_INI_MH(OnUpdateUnrollC) { zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); if (val > 0 && val < ZEND_JIT_TRACE_MAX_CALL_DEPTH) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); *p = val; return SUCCESS; } @@ -221,7 +243,7 @@ static ZEND_INI_MH(OnUpdateUnrollR) { zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); if (val >= 0 && val < ZEND_JIT_TRACE_MAX_RET_DEPTH) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); *p = val; return SUCCESS; } @@ -234,7 +256,7 @@ static ZEND_INI_MH(OnUpdateUnrollL) { zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); if (val > 0 && val < ZEND_JIT_TRACE_MAX_LOOPS_UNROLL) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); *p = val; return SUCCESS; } @@ -247,7 +269,7 @@ static ZEND_INI_MH(OnUpdateMaxTraceLength) { zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); if (val > 3 && val <= ZEND_JIT_TRACE_MAX_LENGTH) { - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + zend_long *p = ZEND_INI_GET_ADDR(); *p = val; return SUCCESS; } @@ -323,7 +345,7 @@ ZEND_INI_BEGIN() STD_PHP_INI_ENTRY("opcache.jit_max_root_traces" , "1024", PHP_INI_SYSTEM, OnUpdateLong, max_root_traces, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_max_side_traces" , "128", PHP_INI_SYSTEM, OnUpdateLong, max_side_traces, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_max_exit_counters" , "8192", PHP_INI_SYSTEM, OnUpdateLong, max_exit_counters, zend_jit_globals, jit_globals) - /* Defautl value should be a prime number, to reduce the chances of loop iterations being a factor of opcache.jit_hot_loop */ + /* Default value should be a prime number, to reduce the chances of loop iterations being a factor of opcache.jit_hot_loop */ STD_PHP_INI_ENTRY("opcache.jit_hot_loop" , "61", PHP_INI_SYSTEM, OnUpdateCounter, hot_loop, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_hot_func" , "127", PHP_INI_SYSTEM, OnUpdateCounter, hot_func, zend_jit_globals, jit_globals) STD_PHP_INI_ENTRY("opcache.jit_hot_return" , "8", PHP_INI_SYSTEM, OnUpdateCounter, hot_return, zend_jit_globals, jit_globals) @@ -338,7 +360,7 @@ ZEND_INI_BEGIN() #endif ZEND_INI_END() -static int filename_is_in_cache(zend_string *filename) +static bool filename_is_in_cache(zend_string *filename) { zend_string *key; @@ -348,23 +370,39 @@ static int filename_is_in_cache(zend_string *filename) if (persistent_script && !persistent_script->corrupted) { if (ZCG(accel_directives).validate_timestamps) { zend_file_handle handle; - int ret; + bool ret; zend_stream_init_filename_ex(&handle, filename); - ret = validate_timestamp_and_record_ex(persistent_script, &handle) == SUCCESS - ? 1 : 0; + ret = validate_timestamp_and_record_ex(persistent_script, &handle) == SUCCESS; zend_destroy_file_handle(&handle); return ret; } - return 1; + return true; } } - return 0; + return false; +} + +static bool filename_is_in_file_cache(zend_string *filename) +{ + zend_string *realpath = zend_resolve_path(filename); + if (!realpath) { + return false; + } + + zend_file_handle handle; + zend_stream_init_filename_ex(&handle, filename); + handle.opened_path = realpath; + + zend_persistent_script *result = zend_file_cache_script_load_ex(&handle, true); + zend_destroy_file_handle(&handle); + + return result != NULL; } -static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) +static bool accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) { if (ZEND_NUM_ARGS() == 1) { zval *zv = ZEND_CALL_ARG(execute_data , 1); @@ -373,7 +411,7 @@ static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS) return filename_is_in_cache(Z_STR_P(zv)); } } - return 0; + return false; } static ZEND_NAMED_FUNCTION(accel_file_exists) @@ -405,13 +443,19 @@ static ZEND_NAMED_FUNCTION(accel_is_readable) static ZEND_MINIT_FUNCTION(zend_accelerator) { - (void)type; /* keep the compiler happy */ - - REGISTER_INI_ENTRIES(); + start_accel_extension(); return SUCCESS; } +void zend_accel_register_ini_entries(void) +{ + zend_module_entry *module = zend_hash_str_find_ptr_lc(&module_registry, + ACCELERATOR_PRODUCT_NAME, strlen(ACCELERATOR_PRODUCT_NAME)); + + zend_register_ini_entries_ex(ini_entries, module->module_number, module->type); +} + void zend_accel_override_file_functions(void) { zend_function *old_function; @@ -442,6 +486,7 @@ static ZEND_MSHUTDOWN_FUNCTION(zend_accelerator) UNREGISTER_INI_ENTRIES(); accel_shutdown(); + return SUCCESS; } @@ -554,7 +599,7 @@ void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS) DISPLAY_INI_ENTRIES(); } -static zend_module_entry accel_module_entry = { +zend_module_entry opcache_module_entry = { STANDARD_MODULE_HEADER, ACCELERATOR_PRODUCT_NAME, ext_functions, @@ -569,11 +614,6 @@ static zend_module_entry accel_module_entry = { STANDARD_MODULE_PROPERTIES_EX }; -int start_accel_module(void) -{ - return zend_startup_module(&accel_module_entry); -} - /* {{{ Get the scripts which are accelerated by ZendAccelerator */ static int accelerator_get_scripts(zval *return_value) { @@ -581,8 +621,6 @@ static int accelerator_get_scripts(zval *return_value) zval persistent_script_report; zend_accel_hash_entry *cache_entry; struct tm *ta; - struct timeval exec_time; - struct timeval fetch_time; if (!ZCG(accelerator_enabled) || accelerator_shm_read_lock() != SUCCESS) { return 0; @@ -612,8 +650,6 @@ static int accelerator_get_scripts(zval *return_value) if (ZCG(accel_directives).validate_timestamps) { add_assoc_long(&persistent_script_report, "timestamp", (zend_long)script->timestamp); } - timerclear(&exec_time); - timerclear(&fetch_time); add_assoc_long(&persistent_script_report, "revalidate", (zend_long)script->dynamic_members.revalidate); @@ -630,7 +666,7 @@ ZEND_FUNCTION(opcache_get_status) { zend_long reqs; zval memory_usage, statistics, scripts; - bool fetch_scripts = 1; + bool fetch_scripts = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &fetch_scripts) == FAILURE) { RETURN_THROWS(); @@ -763,9 +799,7 @@ ZEND_FUNCTION(opcache_get_configuration) { zval directives, version, blacklist; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!validate_api_restriction()) { RETURN_FALSE; @@ -870,9 +904,7 @@ ZEND_FUNCTION(opcache_get_configuration) /* {{{ Request that the contents of the opcode cache to be reset */ ZEND_FUNCTION(opcache_reset) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!validate_api_restriction()) { RETURN_FALSE; @@ -897,7 +929,7 @@ ZEND_FUNCTION(opcache_reset) ZEND_FUNCTION(opcache_invalidate) { zend_string *script_name; - bool force = 0; + bool force = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &script_name, &force) == FAILURE) { RETURN_THROWS(); @@ -907,11 +939,7 @@ ZEND_FUNCTION(opcache_invalidate) RETURN_FALSE; } - if (zend_accel_invalidate(script_name, force) == SUCCESS) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_accel_invalidate(script_name, force) == SUCCESS); } /* {{{ Prevents JIT on function. Call it before the first invocation of the given function. */ @@ -999,3 +1027,27 @@ ZEND_FUNCTION(opcache_is_script_cached) RETURN_BOOL(filename_is_in_cache(script_name)); } + +/* {{{ Return true if the script is cached in OPCache file cache, false if it is not cached or if OPCache is not running. */ +ZEND_FUNCTION(opcache_is_script_cached_in_file_cache) +{ + zend_string *script_name; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(script_name) + ZEND_PARSE_PARAMETERS_END(); + + if (!validate_api_restriction()) { + RETURN_FALSE; + } + + if (!(ZCG(accelerator_enabled) || ZCG(accel_directives).file_cache_only)) { + RETURN_FALSE; + } + + if (!ZCG(accel_directives).file_cache) { + RETURN_FALSE; + } + + RETURN_BOOL(filename_is_in_file_cache(script_name)); +} diff --git a/ext/opcache/zend_accelerator_module.h b/ext/opcache/zend_accelerator_module.h index 656336eeba76..cd46e07d1d27 100644 --- a/ext/opcache/zend_accelerator_module.h +++ b/ext/opcache/zend_accelerator_module.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -22,7 +20,12 @@ #ifndef ZEND_ACCELERATOR_MODULE_H #define ZEND_ACCELERATOR_MODULE_H -int start_accel_module(void); +#include "Zend/zend_modules.h" + +#define phpext_opcache_ptr &opcache_module_entry +extern zend_module_entry opcache_module_entry; + +void zend_accel_register_ini_entries(void); void zend_accel_override_file_functions(void); diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 21f056901fd1..90496e456593 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -47,7 +45,7 @@ zend_persistent_script* create_persistent_script(void) return persistent_script; } -void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements) +void free_persistent_script(zend_persistent_script *persistent_script, bool destroy_elements) { if (!destroy_elements) { /* Both the keys and values have been transferred into the global tables. @@ -65,16 +63,6 @@ void free_persistent_script(zend_persistent_script *persistent_script, int destr zend_string_release_ex(persistent_script->script.filename, 0); } - if (persistent_script->warnings) { - for (uint32_t i = 0; i < persistent_script->num_warnings; i++) { - zend_error_info *info = persistent_script->warnings[i]; - zend_string_release(info->filename); - zend_string_release(info->message); - efree(info); - } - efree(persistent_script->warnings); - } - zend_accel_free_delayed_early_binding_list(persistent_script); efree(persistent_script); @@ -115,7 +103,7 @@ void zend_accel_move_user_classes(HashTable *src, uint32_t count, zend_script *s { Bucket *p, *end; HashTable *dst; - zend_string *filename; + const zend_string *filename; dtor_func_t orig_dtor; zend_class_entry *ce; @@ -142,10 +130,10 @@ void zend_accel_move_user_classes(HashTable *src, uint32_t count, zend_script *s src->pDestructor = orig_dtor; } -static zend_always_inline void _zend_accel_function_hash_copy(HashTable *target, HashTable *source, bool call_observers) +static zend_always_inline void _zend_accel_function_hash_copy(HashTable *target, const HashTable *source, bool call_observers) { zend_function *function1, *function2; - Bucket *p, *end; + const Bucket *p, *end; zval *t; zend_hash_extend(target, target->nNumUsed + source->nNumUsed, 0); @@ -184,20 +172,20 @@ static zend_always_inline void _zend_accel_function_hash_copy(HashTable *target, } } -static zend_always_inline void zend_accel_function_hash_copy(HashTable *target, HashTable *source) +static zend_always_inline void zend_accel_function_hash_copy(HashTable *target, const HashTable *source) { - _zend_accel_function_hash_copy(target, source, 0); + _zend_accel_function_hash_copy(target, source, false); } -static zend_never_inline void zend_accel_function_hash_copy_notify(HashTable *target, HashTable *source) +static zend_never_inline void zend_accel_function_hash_copy_notify(HashTable *target, const HashTable *source) { - _zend_accel_function_hash_copy(target, source, 1); + _zend_accel_function_hash_copy(target, source, true); } -static zend_always_inline void _zend_accel_class_hash_copy(HashTable *target, HashTable *source, bool call_observers) +static zend_always_inline void _zend_accel_class_hash_copy(HashTable *target, const HashTable *source, bool call_observers) { - Bucket *p, *end; - zval *t; + const Bucket *p, *end; + const zval *t; zend_hash_extend(target, target->nNumUsed + source->nNumUsed, 0); p = source->arData; @@ -219,7 +207,7 @@ static zend_always_inline void _zend_accel_class_hash_copy(HashTable *target, Ha * value. */ continue; } else if (UNEXPECTED(!ZCG(accel_directives).ignore_dups)) { - zend_class_entry *ce1 = Z_PTR(p->val); + const zend_class_entry *ce1 = Z_PTR(p->val); if (!(ce1->ce_flags & ZEND_ACC_ANON_CLASS)) { CG(in_compilation) = 1; zend_set_compiled_filename(ce1->info.user.filename); @@ -245,25 +233,25 @@ static zend_always_inline void _zend_accel_class_hash_copy(HashTable *target, Ha target->nInternalPointer = 0; } -static zend_always_inline void zend_accel_class_hash_copy(HashTable *target, HashTable *source) +static zend_always_inline void zend_accel_class_hash_copy(HashTable *target, const HashTable *source) { - _zend_accel_class_hash_copy(target, source, 0); + _zend_accel_class_hash_copy(target, source, false); } -static zend_never_inline void zend_accel_class_hash_copy_notify(HashTable *target, HashTable *source) +static zend_never_inline void zend_accel_class_hash_copy_notify(HashTable *target, const HashTable *source) { - _zend_accel_class_hash_copy(target, source, 1); + _zend_accel_class_hash_copy(target, source, true); } void zend_accel_build_delayed_early_binding_list(zend_persistent_script *persistent_script) { - zend_op_array *op_array = &persistent_script->script.main_op_array; + const zend_op_array *op_array = &persistent_script->script.main_op_array; if (!(op_array->fn_flags & ZEND_ACC_EARLY_BINDING)) { return; } - zend_op *end = op_array->opcodes + op_array->last; - for (zend_op *opline = op_array->opcodes; opline < end; opline++) { + const zend_op *end = op_array->opcodes + op_array->last; + for (const zend_op *opline = op_array->opcodes; opline < end; opline++) { if (opline->opcode == ZEND_DECLARE_CLASS_DELAYED) { persistent_script->num_early_bindings++; } @@ -274,7 +262,7 @@ void zend_accel_build_delayed_early_binding_list(zend_persistent_script *persist for (zend_op *opline = op_array->opcodes; opline < end; opline++) { if (opline->opcode == ZEND_DECLARE_CLASS_DELAYED) { - zval *lcname = RT_CONSTANT(opline, opline->op1); + const zval *lcname = RT_CONSTANT(opline, opline->op1); early_binding->lcname = zend_string_copy(Z_STR_P(lcname)); early_binding->rtd_key = zend_string_copy(Z_STR_P(lcname + 1)); early_binding->lc_parent_name = @@ -285,19 +273,19 @@ void zend_accel_build_delayed_early_binding_list(zend_persistent_script *persist } } -void zend_accel_finalize_delayed_early_binding_list(zend_persistent_script *persistent_script) +void zend_accel_finalize_delayed_early_binding_list(const zend_persistent_script *persistent_script) { if (!persistent_script->num_early_bindings) { return; } zend_early_binding *early_binding = persistent_script->early_bindings; - zend_early_binding *early_binding_end = early_binding + persistent_script->num_early_bindings; - zend_op_array *op_array = &persistent_script->script.main_op_array; - zend_op *opline_end = op_array->opcodes + op_array->last; + const zend_early_binding *early_binding_end = early_binding + persistent_script->num_early_bindings; + const zend_op_array *op_array = &persistent_script->script.main_op_array; + const zend_op *opline_end = op_array->opcodes + op_array->last; for (zend_op *opline = op_array->opcodes; opline < opline_end; opline++) { if (opline->opcode == ZEND_DECLARE_CLASS_DELAYED) { - zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1); + const zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1); /* Skip early_binding entries that don't match, maybe their DECLARE_CLASS_DELAYED * was optimized away. */ while (!zend_string_equals(early_binding->rtd_key, rtd_key)) { @@ -320,7 +308,7 @@ void zend_accel_free_delayed_early_binding_list(zend_persistent_script *persiste { if (persistent_script->num_early_bindings) { for (uint32_t i = 0; i < persistent_script->num_early_bindings; i++) { - zend_early_binding *early_binding = &persistent_script->early_bindings[i]; + const zend_early_binding *early_binding = &persistent_script->early_bindings[i]; zend_string_release(early_binding->lcname); zend_string_release(early_binding->rtd_key); zend_string_release(early_binding->lc_parent_name); @@ -332,7 +320,7 @@ void zend_accel_free_delayed_early_binding_list(zend_persistent_script *persiste } static void zend_accel_do_delayed_early_binding( - zend_persistent_script *persistent_script, zend_op_array *op_array) + const zend_persistent_script *persistent_script, zend_op_array *op_array) { ZEND_ASSERT(!ZEND_MAP_PTR(op_array->run_time_cache)); ZEND_ASSERT(op_array->fn_flags & ZEND_ACC_HEAP_RT_CACHE); @@ -346,7 +334,7 @@ static void zend_accel_do_delayed_early_binding( CG(compiled_filename) = persistent_script->script.filename; CG(in_compilation) = 1; for (uint32_t i = 0; i < persistent_script->num_early_bindings; i++) { - zend_early_binding *early_binding = &persistent_script->early_bindings[i]; + const zend_early_binding *early_binding = &persistent_script->early_bindings[i]; zend_class_entry *ce = zend_hash_find_ex_ptr(EG(class_table), early_binding->lcname, 1); if (!ce) { zval *zv = zend_hash_find_known_hash(EG(class_table), early_binding->rtd_key); @@ -357,6 +345,12 @@ static void zend_accel_do_delayed_early_binding( : NULL; if (parent_ce || (orig_ce->ce_flags & ZEND_ACC_LINKED)) { ce = zend_try_early_bind(orig_ce, parent_ce, early_binding->lcname, zv); + } else if (ZSTR_LEN(early_binding->lc_parent_name) == 0) { + /* Parentless class: use the same binding path as the VM handler */ + zval lcname_zv[2]; + ZVAL_STR(&lcname_zv[0], early_binding->lcname); + ZVAL_STR(&lcname_zv[1], early_binding->rtd_key); + ce = zend_bind_class_in_slot(zv, lcname_zv, early_binding->lc_parent_name); } } if (ce && early_binding->cache_slot != (uint32_t) -1) { @@ -368,7 +362,7 @@ static void zend_accel_do_delayed_early_binding( CG(in_compilation) = orig_in_compilation; } -zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory) +zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, bool from_shared_memory) { zend_op_array *op_array; @@ -458,7 +452,7 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, #define ADLER32_SCALAR_DO8(buf, i) ADLER32_SCALAR_DO4(buf, i); ADLER32_SCALAR_DO4(buf, i + 4); #define ADLER32_SCALAR_DO16(buf) ADLER32_SCALAR_DO8(buf, 0); ADLER32_SCALAR_DO8(buf, 8); -static zend_always_inline void adler32_do16_loop(unsigned char *buf, unsigned char *end, unsigned int *s1_out, unsigned int *s2_out) +static zend_always_inline void adler32_do16_loop(unsigned char *buf, const unsigned char *end, unsigned int *s1_out, unsigned int *s2_out) { unsigned int s1 = *s1_out; unsigned int s2 = *s2_out; diff --git a/ext/opcache/zend_accelerator_util_funcs.h b/ext/opcache/zend_accelerator_util_funcs.h index 53cc1de9effa..a95b2095ebbd 100644 --- a/ext/opcache/zend_accelerator_util_funcs.h +++ b/ext/opcache/zend_accelerator_util_funcs.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -28,15 +26,15 @@ BEGIN_EXTERN_C() zend_persistent_script* create_persistent_script(void); -void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements); +void free_persistent_script(zend_persistent_script *persistent_script, bool destroy_elements); void zend_accel_move_user_functions(HashTable *str, uint32_t count, zend_script *script); void zend_accel_move_user_classes(HashTable *str, uint32_t count, zend_script *script); void zend_accel_build_delayed_early_binding_list(zend_persistent_script *persistent_script); -void zend_accel_finalize_delayed_early_binding_list(zend_persistent_script *persistent_script); +void zend_accel_finalize_delayed_early_binding_list(const zend_persistent_script *persistent_script); void zend_accel_free_delayed_early_binding_list(zend_persistent_script *persistent_script); -zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory); +zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, bool from_shared_memory); #define ADLER32_INIT 1 /* initial Adler-32 value */ diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index fee90e42b574..a6cd2379c2a1 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -135,17 +133,13 @@ static int zend_file_cache_flock(int fd, int type) (ptr) = (void*)((char*)buf + (size_t)(ptr)); \ } \ } while (0) + #define SERIALIZE_STR(ptr) do { \ if (ptr) { \ if (IS_ACCEL_INTERNED(ptr)) { \ (ptr) = zend_file_cache_serialize_interned((zend_string*)(ptr), info); \ } else { \ ZEND_ASSERT(IS_UNSERIALIZED(ptr)); \ - /* script->corrupted shows if the script in SHM or not */ \ - if (EXPECTED(script->corrupted)) { \ - GC_ADD_FLAGS(ptr, IS_STR_INTERNED); \ - GC_DEL_FLAGS(ptr, IS_STR_PERMANENT); \ - } \ (ptr) = (void*)((char*)(ptr) - (char*)script->mem); \ } \ } \ @@ -164,6 +158,7 @@ static int zend_file_cache_flock(int fd, int type) GC_ADD_FLAGS(ptr, IS_STR_INTERNED); \ GC_DEL_FLAGS(ptr, IS_STR_PERMANENT); \ } \ + GC_DEL_FLAGS(ptr, IS_STR_CLASS_NAME_MAP_PTR); \ } \ } \ } while (0) @@ -258,6 +253,12 @@ static void zend_file_cache_serialize_attribute(zval *zv, static void zend_file_cache_unserialize_attribute(zval *zv, zend_persistent_script *script, void *buf); +static void zend_file_cache_serialize_type( + zend_type *type, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf); + +static void zend_file_cache_unserialize_type( + zend_type *type, zend_class_entry *scope, zend_persistent_script *script, void *buf); + static void *zend_file_cache_serialize_interned(zend_string *str, zend_file_cache_metainfo *info) { @@ -387,6 +388,12 @@ static void zend_file_cache_serialize_ast(zend_ast *ast, } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { zend_ast_fcc *fcc = (zend_ast_fcc*)ast; ZEND_MAP_PTR_INIT(fcc->fptr, NULL); + if (!IS_SERIALIZED(fcc->args)) { + SERIALIZE_PTR(fcc->args); + tmp = fcc->args; + UNSERIALIZE_PTR(tmp); + zend_file_cache_serialize_ast(tmp, script, info, buf); + } } else if (zend_ast_is_decl(ast)) { /* Not implemented. */ ZEND_UNREACHABLE(); @@ -461,16 +468,46 @@ static void zend_file_cache_serialize_attribute(zval *zv, SERIALIZE_STR(attr->name); SERIALIZE_STR(attr->lcname); + SERIALIZE_STR(attr->validation_error); for (i = 0; i < attr->argc; i++) { SERIALIZE_STR(attr->args[i].name); zend_file_cache_serialize_zval(&attr->args[i].value, script, info, buf); } + + if (attr->generic_args) { + SERIALIZE_PTR(attr->generic_args); + zend_type *t = attr->generic_args; + UNSERIALIZE_PTR(t); + zend_file_cache_serialize_type(t, script, info, buf); + } } static void zend_file_cache_serialize_type( zend_type *type, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) { + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*type)) { + zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*type); + SERIALIZE_PTR(ref); + ZEND_TYPE_SET_PTR(*type, ref); + UNSERIALIZE_PTR(ref); + SERIALIZE_STR(ref->name); + return; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*type)) { + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*type); + SERIALIZE_PTR(named); + ZEND_TYPE_SET_PTR(*type, named); + UNSERIALIZE_PTR(named); + SERIALIZE_STR(named->name); + for (uint32_t i = 0; i < named->count; i++) { + zend_file_cache_serialize_type(&named->args[i], script, info, buf); + } + + return; + } + if (ZEND_TYPE_HAS_LIST(*type)) { zend_type_list *list = ZEND_TYPE_LIST(*type); SERIALIZE_PTR(list); @@ -488,6 +525,128 @@ static void zend_file_cache_serialize_type( } } +static void zend_file_cache_serialize_generic_type_entry( + zval *zv, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) +{ + SERIALIZE_PTR(Z_PTR_P(zv)); + zend_type *boxed = Z_PTR_P(zv); + UNSERIALIZE_PTR(boxed); + zend_file_cache_serialize_type(boxed, script, info, buf); +} + +/* Serialise a turbofish_args entry — same shape as a boxed type from the + * file's perspective but the buffer slot is the entry struct (currently a + * single args_box; the per-call-site runtime cache that pairs with it lives + * in the caller op_array's runtime cache slot, not here). */ +static void zend_file_cache_serialize_turbofish_args_entry( + zval *zv, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) +{ + SERIALIZE_PTR(Z_PTR_P(zv)); + zend_turbofish_args_entry *entry = Z_PTR_P(zv); + UNSERIALIZE_PTR(entry); + zend_file_cache_serialize_type(&entry->args_box, script, info, buf); + /* concrete_table is a non-portable SHM address; the load path rebuilds it. */ + entry->concrete_table = NULL; +} + +static void zend_file_cache_serialize_generic_type_table_ht( + HashTable **ht_ptr, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) +{ + HashTable *ht; + SERIALIZE_PTR(*ht_ptr); + ht = *ht_ptr; + UNSERIALIZE_PTR(ht); + zend_file_cache_serialize_hash(ht, script, info, buf, zend_file_cache_serialize_generic_type_entry); +} + +static void zend_file_cache_serialize_turbofish_args_ht( + HashTable **ht_ptr, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) +{ + HashTable *ht; + SERIALIZE_PTR(*ht_ptr); + ht = *ht_ptr; + UNSERIALIZE_PTR(ht); + zend_file_cache_serialize_hash(ht, script, info, buf, zend_file_cache_serialize_turbofish_args_entry); +} + +static void zend_file_cache_serialize_generic_parameter_list( + zend_generic_parameter_list **list_ptr, zend_persistent_script *script, + zend_file_cache_metainfo *info, void *buf) +{ + zend_generic_parameter_list *list; + SERIALIZE_PTR(*list_ptr); + list = *list_ptr; + UNSERIALIZE_PTR(list); + for (uint32_t i = 0; i < list->count; i++) { + SERIALIZE_STR(list->parameters[i].name); + zend_file_cache_serialize_type(&list->parameters[i].bound, script, info, buf); + zend_file_cache_serialize_type(&list->parameters[i].bound_pre_erasure, script, info, buf); + zend_file_cache_serialize_type(&list->parameters[i].default_type, script, info, buf); + zend_file_cache_serialize_type(&list->parameters[i].default_pre_erasure, script, info, buf); + } +} + +static void zend_file_cache_serialize_generic_type_table( + zend_generic_type_table **table_ptr, zend_persistent_script *script, + zend_file_cache_metainfo *info, void *buf) +{ + zend_generic_type_table *table; + SERIALIZE_PTR(*table_ptr); + table = *table_ptr; + UNSERIALIZE_PTR(table); + if (table->return_type) { + SERIALIZE_PTR(table->return_type); + zend_type *t = table->return_type; + UNSERIALIZE_PTR(t); + zend_file_cache_serialize_type(t, script, info, buf); + } + if (table->extends) { + SERIALIZE_PTR(table->extends); + zend_type *t = table->extends; + UNSERIALIZE_PTR(t); + zend_file_cache_serialize_type(t, script, info, buf); + } + if (table->parameters) { + zend_file_cache_serialize_generic_type_table_ht(&table->parameters, script, info, buf); + } + if (table->properties) { + zend_file_cache_serialize_generic_type_table_ht(&table->properties, script, info, buf); + } + if (table->class_constants) { + zend_file_cache_serialize_generic_type_table_ht(&table->class_constants, script, info, buf); + } + if (table->implements) { + zend_file_cache_serialize_generic_type_table_ht(&table->implements, script, info, buf); + } + if (table->trait_uses) { + zend_file_cache_serialize_generic_type_table_ht(&table->trait_uses, script, info, buf); + } + if (table->turbofish_args) { + zend_file_cache_serialize_turbofish_args_ht(&table->turbofish_args, script, info, buf); + } +} + +/* Serialise a monomorph's generic_type_args. The owned strings (names) and + * owned_type payloads are inline within the table — type_ref is a borrowed + * pointer that we rebuild from ce->generic_types on the unserialise side, so + * we just NULL it out here. */ +static void zend_file_cache_serialize_type_arg_table( + zend_type_arg_table **table_ptr, zend_persistent_script *script, + zend_file_cache_metainfo *info, void *buf) +{ + zend_type_arg_table *table; + SERIALIZE_PTR(*table_ptr); + table = *table_ptr; + UNSERIALIZE_PTR(table); + for (uint32_t i = 0; i < table->count; i++) { + SERIALIZE_STR(table->entries[i].name); + table->entries[i].type_ref = NULL; + if (ZEND_TYPE_IS_SET(table->entries[i].owned_type)) { + zend_file_cache_serialize_type(&table->entries[i].owned_type, script, info, buf); + } + } +} + static void zend_file_cache_serialize_op_array(zend_op_array *op_array, zend_persistent_script *script, zend_file_cache_metainfo *info, @@ -572,13 +731,32 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra } if (opline->op2_type == IS_CONST) { SERIALIZE_PTR(opline->op2.zv); + + /* See GH-17733. Reset Z_EXTRA_P(op2) of ZEND_INIT_FCALL, which + * is an offset into the global function table, to avoid calling + * incorrect functions when environment changes. This, and the + * equivalent code below, can be removed once proper system ID + * validation is implemented. */ + if (opline->opcode == ZEND_INIT_FCALL) { + zval *op2 = opline->op2.zv; + UNSERIALIZE_PTR(op2); + Z_EXTRA_P(op2) = 0; + ZEND_VM_SET_OPCODE_HANDLER(opline); + } } #else if (opline->op1_type == IS_CONST) { opline->op1.constant = RT_CONSTANT(opline, opline->op1) - literals; } if (opline->op2_type == IS_CONST) { - opline->op2.constant = RT_CONSTANT(opline, opline->op2) - literals; + zval *op2 = RT_CONSTANT(opline, opline->op2); + opline->op2.constant = op2 - literals; + + /* See GH-17733 and comment above. */ + if (opline->opcode == ZEND_INIT_FCALL) { + Z_EXTRA_P(op2) = 0; + ZEND_VM_SET_OPCODE_HANDLER(opline); + } } #endif #if ZEND_USE_ABS_JMP_ADDR @@ -636,6 +814,7 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra SERIALIZE_STR(p->name); } zend_file_cache_serialize_type(&p->type, script, info, buf); + SERIALIZE_STR(p->doc_comment); p++; } } @@ -678,6 +857,14 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra SERIALIZE_PTR(op_array->try_catch_array); SERIALIZE_PTR(op_array->prototype); SERIALIZE_PTR(op_array->prop_info); + + if (op_array->generic_parameters) { + zend_file_cache_serialize_generic_parameter_list(&op_array->generic_parameters, script, info, buf); + } + + if (op_array->generic_types) { + zend_file_cache_serialize_generic_type_table(&op_array->generic_types, script, info, buf); + } } } @@ -809,6 +996,18 @@ static void zend_file_cache_serialize_class(zval *zv, SERIALIZE_STR(ce->info.user.filename); SERIALIZE_STR(ce->doc_comment); SERIALIZE_ATTRIBUTES(ce->attributes); + if (ce->generic_parameters) { + zend_file_cache_serialize_generic_parameter_list(&ce->generic_parameters, script, info, buf); + } + + if (ce->generic_types) { + zend_file_cache_serialize_generic_type_table(&ce->generic_types, script, info, buf); + } + + if (ce->generic_type_args) { + zend_file_cache_serialize_type_arg_table(&ce->generic_type_args, script, info, buf); + } + zend_file_cache_serialize_hash(&ce->properties_info, script, info, buf, zend_file_cache_serialize_prop_info); if (ce->properties_info_table) { @@ -1287,6 +1486,10 @@ static void zend_file_cache_unserialize_ast(zend_ast *ast, } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { zend_ast_fcc *fcc = (zend_ast_fcc*)ast; ZEND_MAP_PTR_NEW(fcc->fptr); + if (!IS_UNSERIALIZED(fcc->args)) { + UNSERIALIZE_PTR(fcc->args); + zend_file_cache_unserialize_ast(fcc->args, script, buf); + } } else if (zend_ast_is_decl(ast)) { /* Not implemented. */ ZEND_UNREACHABLE(); @@ -1352,16 +1555,42 @@ static void zend_file_cache_unserialize_attribute(zval *zv, zend_persistent_scri UNSERIALIZE_STR(attr->name); UNSERIALIZE_STR(attr->lcname); + UNSERIALIZE_STR(attr->validation_error); for (i = 0; i < attr->argc; i++) { UNSERIALIZE_STR(attr->args[i].name); zend_file_cache_unserialize_zval(&attr->args[i].value, script, buf); } + + if (attr->generic_args) { + UNSERIALIZE_PTR(attr->generic_args); + zend_file_cache_unserialize_type(attr->generic_args, NULL, script, buf); + } } static void zend_file_cache_unserialize_type( zend_type *type, zend_class_entry *scope, zend_persistent_script *script, void *buf) { + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*type)) { + zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*type); + UNSERIALIZE_PTR(ref); + ZEND_TYPE_SET_PTR(*type, ref); + UNSERIALIZE_STR(ref->name); + return; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*type)) { + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*type); + UNSERIALIZE_PTR(named); + ZEND_TYPE_SET_PTR(*type, named); + UNSERIALIZE_STR(named->name); + for (uint32_t i = 0; i < named->count; i++) { + zend_file_cache_unserialize_type(&named->args[i], scope, script, buf); + } + + return; + } + if (ZEND_TYPE_HAS_LIST(*type)) { zend_type_list *list = ZEND_TYPE_LIST(*type); UNSERIALIZE_PTR(list); @@ -1383,6 +1612,149 @@ static void zend_file_cache_unserialize_type( } } +static zend_class_entry *zend_file_cache_generic_unserialize_scope = NULL; + +static void zend_file_cache_unserialize_generic_type_entry( + zval *zv, zend_persistent_script *script, void *buf) +{ + UNSERIALIZE_PTR(Z_PTR_P(zv)); + zend_file_cache_unserialize_type( + (zend_type *) Z_PTR_P(zv), zend_file_cache_generic_unserialize_scope, script, buf); +} + +static void zend_file_cache_unserialize_turbofish_args_entry( + zval *zv, zend_persistent_script *script, void *buf) +{ + UNSERIALIZE_PTR(Z_PTR_P(zv)); + zend_turbofish_args_entry *entry = Z_PTR_P(zv); + zend_file_cache_unserialize_type( + &entry->args_box, zend_file_cache_generic_unserialize_scope, script, buf); + entry->concrete_table = NULL; + entry->concrete_skip_value_check = false; +} + +static void zend_file_cache_unserialize_generic_type_table_ht( + HashTable **ht_ptr, zend_class_entry *scope, zend_persistent_script *script, void *buf) +{ + UNSERIALIZE_PTR(*ht_ptr); + HashTable *ht = *ht_ptr; + zend_class_entry *prev = zend_file_cache_generic_unserialize_scope; + zend_file_cache_generic_unserialize_scope = scope; + zend_file_cache_unserialize_hash(ht, script, buf, zend_file_cache_unserialize_generic_type_entry, NULL); + zend_file_cache_generic_unserialize_scope = prev; +} + +static void zend_file_cache_unserialize_turbofish_args_ht( + HashTable **ht_ptr, zend_class_entry *scope, zend_persistent_script *script, void *buf) +{ + UNSERIALIZE_PTR(*ht_ptr); + HashTable *ht = *ht_ptr; + zend_class_entry *prev = zend_file_cache_generic_unserialize_scope; + zend_file_cache_generic_unserialize_scope = scope; + zend_file_cache_unserialize_hash(ht, script, buf, zend_file_cache_unserialize_turbofish_args_entry, NULL); + zend_file_cache_generic_unserialize_scope = prev; +} + +static void zend_file_cache_unserialize_generic_parameter_list( + zend_generic_parameter_list **list_ptr, zend_class_entry *scope, + zend_persistent_script *script, void *buf) +{ + UNSERIALIZE_PTR(*list_ptr); + zend_generic_parameter_list *list = *list_ptr; + for (uint32_t i = 0; i < list->count; i++) { + UNSERIALIZE_STR(list->parameters[i].name); + zend_file_cache_unserialize_type(&list->parameters[i].bound, scope, script, buf); + zend_file_cache_unserialize_type(&list->parameters[i].bound_pre_erasure, scope, script, buf); + zend_file_cache_unserialize_type(&list->parameters[i].default_type, scope, script, buf); + zend_file_cache_unserialize_type(&list->parameters[i].default_pre_erasure, scope, script, buf); + } +} + +static void zend_file_cache_unserialize_generic_type_table( + zend_generic_type_table **table_ptr, zend_class_entry *scope, + zend_persistent_script *script, void *buf) +{ + UNSERIALIZE_PTR(*table_ptr); + zend_generic_type_table *table = *table_ptr; + if (table->return_type) { + UNSERIALIZE_PTR(table->return_type); + zend_file_cache_unserialize_type(table->return_type, scope, script, buf); + } + + if (table->extends) { + UNSERIALIZE_PTR(table->extends); + zend_file_cache_unserialize_type(table->extends, scope, script, buf); + } + + if (table->parameters) { + zend_file_cache_unserialize_generic_type_table_ht(&table->parameters, scope, script, buf); + } + + if (table->properties) { + zend_file_cache_unserialize_generic_type_table_ht(&table->properties, scope, script, buf); + } + + if (table->class_constants) { + zend_file_cache_unserialize_generic_type_table_ht(&table->class_constants, scope, script, buf); + } + + if (table->implements) { + zend_file_cache_unserialize_generic_type_table_ht(&table->implements, scope, script, buf); + } + + if (table->trait_uses) { + zend_file_cache_unserialize_generic_type_table_ht(&table->trait_uses, scope, script, buf); + } + + if (table->turbofish_args) { + zend_file_cache_unserialize_turbofish_args_ht(&table->turbofish_args, scope, script, buf); + } + + /* value_check_plan is not file-serialized; the verify path rebuilds it. */ + table->value_check_plan = NULL; +} + +/* Mirror of zend_file_cache_serialize_type_arg_table. Rebuilds `type_ref` + * to point into the now-unserialized ce->generic_types side table — same + * logic as zend_persist_mono_binding_nwa in zend_persist.c. */ +static void zend_file_cache_unserialize_type_arg_table( + zend_type_arg_table **table_ptr, zend_class_entry *scope, + zend_persistent_script *script, void *buf) +{ + UNSERIALIZE_PTR(*table_ptr); + zend_type_arg_table *table = *table_ptr; + const zend_type_named_with_args *new_nwa = NULL; + if (scope && scope->generic_types) { + if (scope->generic_types->extends + && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*scope->generic_types->extends)) { + new_nwa = ZEND_TYPE_NAMED_WITH_ARGS(*scope->generic_types->extends); + } else { + HashTable *tables[] = { scope->generic_types->implements, + scope->generic_types->trait_uses }; + for (size_t k = 0; k < sizeof(tables) / sizeof(tables[0]); k++) { + if (!tables[k] || zend_hash_num_elements(tables[k]) == 0) continue; + zval *zv; + ZEND_HASH_FOREACH_VAL(tables[k], zv) { + zend_type *boxed = (zend_type *) Z_PTR_P(zv); + if (boxed && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) { + new_nwa = ZEND_TYPE_NAMED_WITH_ARGS(*boxed); + } + break; + } ZEND_HASH_FOREACH_END(); + if (new_nwa) break; + } + } + } + for (uint32_t i = 0; i < table->count; i++) { + UNSERIALIZE_STR(table->entries[i].name); + table->entries[i].type_ref = + (new_nwa && i < new_nwa->count) ? &new_nwa->args[i] : NULL; + if (ZEND_TYPE_IS_SET(table->entries[i].owned_type)) { + zend_file_cache_unserialize_type(&table->entries[i].owned_type, scope, script, buf); + } + } +} + static void zend_file_cache_unserialize_op_array(zend_op_array *op_array, zend_persistent_script *script, void *buf) @@ -1534,6 +1906,7 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr UNSERIALIZE_STR(p->name); } zend_file_cache_unserialize_type(&p->type, (op_array->fn_flags & ZEND_ACC_CLOSURE) ? NULL : op_array->scope, script, buf); + UNSERIALIZE_STR(p->doc_comment); p++; } } @@ -1568,6 +1941,16 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr UNSERIALIZE_PTR(op_array->try_catch_array); UNSERIALIZE_PTR(op_array->prototype); UNSERIALIZE_PTR(op_array->prop_info); + + if (op_array->generic_parameters) { + zend_file_cache_unserialize_generic_parameter_list(&op_array->generic_parameters, + (op_array->fn_flags & ZEND_ACC_CLOSURE) ? NULL : op_array->scope, script, buf); + } + + if (op_array->generic_types) { + zend_file_cache_unserialize_generic_type_table(&op_array->generic_types, + (op_array->fn_flags & ZEND_ACC_CLOSURE) ? NULL : op_array->scope, script, buf); + } } } @@ -1692,6 +2075,18 @@ static void zend_file_cache_unserialize_class(zval *zv, UNSERIALIZE_STR(ce->info.user.filename); UNSERIALIZE_STR(ce->doc_comment); UNSERIALIZE_ATTRIBUTES(ce->attributes); + if (ce->generic_parameters) { + zend_file_cache_unserialize_generic_parameter_list(&ce->generic_parameters, ce, script, buf); + } + + if (ce->generic_types) { + zend_file_cache_unserialize_generic_type_table(&ce->generic_types, ce, script, buf); + } + + if (ce->generic_type_args) { + zend_file_cache_unserialize_type_arg_table(&ce->generic_type_args, ce, script, buf); + } + zend_file_cache_unserialize_hash(&ce->properties_info, script, buf, zend_file_cache_unserialize_prop_info, NULL); @@ -1871,7 +2266,14 @@ static void zend_file_cache_unserialize(zend_persistent_script *script, zend_file_cache_unserialize_early_bindings(script, buf); } +static zend_persistent_script file_cache_validate_success_script; + zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle) +{ + return zend_file_cache_script_load_ex(file_handle, false); +} + +zend_persistent_script *zend_file_cache_script_load_ex(zend_file_handle *file_handle, bool validate_only) { zend_string *full_path = file_handle->opened_path; int fd; @@ -1948,6 +2350,16 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl return NULL; } + /* return here if validating */ + if (validate_only) { + if (zend_file_cache_flock(fd, LOCK_UN) != 0) { + zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename); + } + close(fd); + efree(filename); + return &file_cache_validate_success_script; + } + checkpoint = zend_arena_checkpoint(CG(arena)); #if defined(__AVX__) || defined(__SSE2__) /* Align to 64-byte boundary */ @@ -2074,7 +2486,7 @@ void zend_file_cache_invalidate(zend_string *full_path) if (ZCG(accel_directives).file_cache_read_only) { return; } - + char *filename; filename = zend_file_cache_get_bin_file_path(full_path); diff --git a/ext/opcache/zend_file_cache.h b/ext/opcache/zend_file_cache.h index 8f067f5f37ab..37868285b0da 100644 --- a/ext/opcache/zend_file_cache.h +++ b/ext/opcache/zend_file_cache.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ @@ -21,6 +19,7 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm); zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle); +zend_persistent_script *zend_file_cache_script_load_ex(zend_file_handle *file_handle, bool validate_only); void zend_file_cache_invalidate(zend_string *full_path); #endif /* ZEND_FILE_CACHE_H */ diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 202cd73c9042..5b68782c6ebb 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -87,6 +85,7 @@ typedef void (*zend_persist_func_t)(zval*); static void zend_persist_zval(zval *z); static void zend_persist_op_array(zval *zv); +static void zend_persist_type(zend_type *type); static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = {HT_INVALID_IDX, HT_INVALID_IDX}; @@ -197,6 +196,7 @@ static zend_ast *zend_persist_ast(zend_ast *ast) node = (zend_ast *) copy; } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { zend_ast_fcc *copy = zend_shared_memdup(ast, sizeof(zend_ast_fcc)); + copy->args = zend_persist_ast(copy->args); node = (zend_ast *) copy; } else if (zend_ast_is_decl(ast)) { /* Not implemented. */ @@ -311,6 +311,9 @@ static HashTable *zend_persist_attributes(HashTable *attributes) zend_accel_store_interned_string(copy->name); zend_accel_store_interned_string(copy->lcname); + if (copy->validation_error) { + zend_accel_store_interned_string(copy->validation_error); + } for (i = 0; i < copy->argc; i++) { if (copy->args[i].name) { @@ -319,6 +322,11 @@ static HashTable *zend_persist_attributes(HashTable *attributes) zend_persist_zval(©->args[i].value); } + if (copy->generic_args) { + copy->generic_args = zend_shared_memdup_put_free(copy->generic_args, sizeof(zend_type)); + zend_persist_type(copy->generic_args); + } + ZVAL_PTR(v, copy); } ZEND_HASH_FOREACH_END(); @@ -357,6 +365,38 @@ uint32_t zend_accel_get_class_name_map_ptr(zend_string *type_name) } static void zend_persist_type(zend_type *type) { + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*type)) { + zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*type); + ref = zend_shared_memdup_put_free(ref, sizeof(*ref)); + zend_accel_store_interned_string(ref->name); + ZEND_TYPE_SET_PTR(*type, ref); + return; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*type)) { + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*type); + /* Compile-time NWAs can be structurally shared across the script + * (e.g. two `extends Foo, ...>` clauses end up referencing + * the same `Box` payload). Use the xlat-aware variant so the + * second visit short-circuits to the already-persisted SHM copy + * instead of memdup'ing from the now-freed heap source. */ + zend_type_named_with_args *prev = zend_shared_alloc_get_xlat_entry(named); + if (prev) { + ZEND_TYPE_SET_PTR(*type, prev); + return; + } + named = zend_shared_memdup_put_free(named, ZEND_TYPE_NAMED_WITH_ARGS_SIZE(named->count)); + if (named->name) { + zend_accel_store_interned_string(named->name); + } + for (uint32_t i = 0; i < named->count; i++) { + zend_persist_type(&named->args[i]); + } + + ZEND_TYPE_SET_PTR(*type, named); + return; + } + if (ZEND_TYPE_HAS_LIST(*type)) { zend_type_list *list = ZEND_TYPE_LIST(*type); if (ZEND_TYPE_USES_ARENA(*type) || zend_accel_in_shm(list)) { @@ -374,6 +414,17 @@ static void zend_persist_type(zend_type *type) { zend_persist_type(single_type); continue; } + + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*single_type)) { + zend_persist_type(single_type); + continue; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*single_type)) { + zend_persist_type(single_type); + continue; + } + if (ZEND_TYPE_HAS_NAME(*single_type)) { zend_string *type_name = ZEND_TYPE_NAME(*single_type); zend_accel_store_interned_string(type_name); @@ -385,6 +436,246 @@ static void zend_persist_type(zend_type *type) { } ZEND_TYPE_FOREACH_END(); } +static zend_generic_parameter_list *zend_persist_generic_parameter_list(zend_generic_parameter_list *list) +{ + if (!list) { + return NULL; + } + + zend_generic_parameter_list *persisted = zend_shared_memdup_put_free( + list, + ZEND_GENERIC_PARAMETER_LIST_SIZE(list->count) + ); + + for (uint32_t i = 0; i < persisted->count; i++) { + zend_generic_parameter *param = &persisted->parameters[i]; + zend_accel_store_interned_string(param->name); + zend_persist_type(¶m->bound); + zend_persist_type(¶m->bound_pre_erasure); + zend_persist_type(¶m->default_type); + zend_persist_type(¶m->default_pre_erasure); + } + + return persisted; +} + +static HashTable *zend_persist_generic_type_table_ht(HashTable *ht) +{ + zend_hash_persist(ht); + if (HT_IS_PACKED(ht)) { + zval *v; + ZEND_HASH_PACKED_FOREACH_VAL(ht, v) { + zend_type *boxed = Z_PTR_P(v); + zend_type *copy = zend_shared_memdup_put_free(boxed, sizeof(zend_type)); + zend_persist_type(copy); + Z_PTR_P(v) = copy; + } ZEND_HASH_FOREACH_END(); + } else { + Bucket *p; + ZEND_HASH_MAP_FOREACH_BUCKET(ht, p) { + if (p->key) { + zend_accel_store_interned_string(p->key); + } + zend_type *boxed = Z_PTR(p->val); + zend_type *copy = zend_shared_memdup_put_free(boxed, sizeof(zend_type)); + zend_persist_type(copy); + Z_PTR(p->val) = copy; + } ZEND_HASH_FOREACH_END(); + } + HashTable *ptr = zend_shared_memdup_put_free(ht, sizeof(HashTable)); + GC_SET_REFCOUNT(ptr, 2); + GC_TYPE_INFO(ptr) = GC_ARRAY | ((IS_ARRAY_IMMUTABLE|GC_NOT_COLLECTABLE) << GC_FLAGS_SHIFT); + return ptr; +} + +/* Relocate a turbofish entry's concrete_table into SHM, rebinding each type_ref + * against the just-persisted copy->args_box NWA. Bails to the runtime rebuild + * path (copy->concrete_table = NULL) for any populated default slot. */ +static void zend_persist_concrete_call_table(zend_turbofish_args_entry *copy) +{ + zend_type_arg_table *src = copy->concrete_table; + if (!src) { + return; + } + + const zend_type_named_with_args *new_nwa = + ZEND_TYPE_HAS_NAMED_WITH_ARGS(copy->args_box) + ? ZEND_TYPE_NAMED_WITH_ARGS(copy->args_box) : NULL; + uint32_t passed = new_nwa ? new_nwa->count : 0; + + for (uint32_t i = 0; i < src->count; i++) { + if (i >= passed && (src->entries[i].name || src->entries[i].type_ref)) { + zend_type_arg_table_destroy(src); + copy->concrete_table = NULL; + return; + } + } + + for (uint32_t i = 0; i < src->count; i++) { + if (src->entries[i].name) { + zend_accel_store_interned_string(src->entries[i].name); + } + if (ZEND_TYPE_IS_SET(src->entries[i].owned_type)) { + zend_persist_type(&src->entries[i].owned_type); + } + src->entries[i].type_ref = + (new_nwa && src->entries[i].name && i < new_nwa->count) + ? &new_nwa->args[i] : NULL; + } + + zend_type_arg_table *persisted = zend_shared_memdup_put_free( + src, ZEND_TYPE_ARG_TABLE_SIZE(src->count)); + persisted->persisted = true; + copy->concrete_table = persisted; +} + +/* Persist the turbofish_args HT. Each entry is a zend_turbofish_args_entry + * which now stores only args_box — the per-call-site runtime cache that + * pairs with it lives in the caller op_array's runtime cache slot, not + * here, so the persisted SHM copy carries no per-process state. */ +static HashTable *zend_persist_turbofish_args_ht(HashTable *ht) +{ + zend_hash_persist(ht); + if (HT_IS_PACKED(ht)) { + zval *v; + ZEND_HASH_PACKED_FOREACH_VAL(ht, v) { + zend_turbofish_args_entry *entry = Z_PTR_P(v); + zend_turbofish_args_entry *copy = zend_shared_memdup_put_free(entry, sizeof(*entry)); + zend_persist_type(©->args_box); + zend_persist_concrete_call_table(copy); + Z_PTR_P(v) = copy; + } ZEND_HASH_FOREACH_END(); + } else { + Bucket *p; + ZEND_HASH_MAP_FOREACH_BUCKET(ht, p) { + if (p->key) { + zend_accel_store_interned_string(p->key); + } + zend_turbofish_args_entry *entry = Z_PTR(p->val); + zend_turbofish_args_entry *copy = zend_shared_memdup_put_free(entry, sizeof(*entry)); + zend_persist_type(©->args_box); + zend_persist_concrete_call_table(copy); + Z_PTR(p->val) = copy; + } ZEND_HASH_FOREACH_END(); + } + HashTable *ptr = zend_shared_memdup_put_free(ht, sizeof(HashTable)); + GC_SET_REFCOUNT(ptr, 2); + GC_TYPE_INFO(ptr) = GC_ARRAY | ((IS_ARRAY_IMMUTABLE|GC_NOT_COLLECTABLE) << GC_FLAGS_SHIFT); + return ptr; +} + +/* Locate the post-persistence NWA payload that holds this monomorph's + * bindings — `extends` for class monos, the first `implements` entry for + * interface monos, the first `trait_uses` entry for trait monos. Returns + * NULL when the ce isn't a monomorph (no generic_types side table). */ +static const zend_type_named_with_args *zend_persist_mono_binding_nwa(const zend_class_entry *ce) +{ + if (!ce->generic_types) { + return NULL; + } + if (ce->generic_types->extends && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)) { + return ZEND_TYPE_NAMED_WITH_ARGS(*ce->generic_types->extends); + } + HashTable *tables[] = { ce->generic_types->implements, ce->generic_types->trait_uses }; + for (size_t k = 0; k < sizeof(tables) / sizeof(tables[0]); k++) { + if (!tables[k] || zend_hash_num_elements(tables[k]) == 0) continue; + zval *zv; + ZEND_HASH_FOREACH_VAL(tables[k], zv) { + zend_type *boxed = (zend_type *) Z_PTR_P(zv); + if (boxed && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) { + return ZEND_TYPE_NAMED_WITH_ARGS(*boxed); + } + break; + } ZEND_HASH_FOREACH_END(); + } + return NULL; +} + +/* Persist a monomorph's generic_type_args. Each entry's `type_ref` was + * borrowed from a heap NWA payload that has just been relocated into SHM + * as part of the surrounding ce->generic_types; rebuild type_ref against + * the SHM payload so it stays valid after the heap source is freed. */ +static zend_type_arg_table *zend_persist_type_arg_table( + zend_type_arg_table *table, const zend_class_entry *ce) +{ + if (!table) { + return NULL; + } + const zend_type_named_with_args *new_nwa = zend_persist_mono_binding_nwa(ce); + for (uint32_t i = 0; i < table->count; i++) { + if (table->entries[i].name) { + zend_accel_store_interned_string(table->entries[i].name); + } + table->entries[i].type_ref = + (new_nwa && i < new_nwa->count) ? &new_nwa->args[i] : NULL; + if (ZEND_TYPE_IS_SET(table->entries[i].owned_type)) { + zend_persist_type(&table->entries[i].owned_type); + } + } + zend_type_arg_table *persisted = zend_shared_memdup_put_free( + table, ZEND_TYPE_ARG_TABLE_SIZE(table->count)); + persisted->persisted = true; + return persisted; +} + +static zend_generic_type_table *zend_persist_generic_type_table(zend_generic_type_table *table) +{ + if (!table) { + return NULL; + } + + zend_generic_type_table *persisted = zend_shared_memdup_put_free(table, sizeof(*table)); + persisted->persisted = true; + if (persisted->return_type) { + persisted->return_type = zend_shared_memdup_put_free(persisted->return_type, sizeof(zend_type)); + zend_persist_type(persisted->return_type); + } + + if (persisted->extends) { + persisted->extends = zend_shared_memdup_put_free(persisted->extends, sizeof(zend_type)); + zend_persist_type(persisted->extends); + } + + if (persisted->parameters) { + persisted->parameters = zend_persist_generic_type_table_ht(persisted->parameters); + } + + if (persisted->properties) { + persisted->properties = zend_persist_generic_type_table_ht(persisted->properties); + } + + if (persisted->class_constants) { + persisted->class_constants = zend_persist_generic_type_table_ht(persisted->class_constants); + } + + if (persisted->implements) { + persisted->implements = zend_persist_generic_type_table_ht(persisted->implements); + } + + if (persisted->trait_uses) { + persisted->trait_uses = zend_persist_generic_type_table_ht(persisted->trait_uses); + } + + if (persisted->turbofish_args) { + persisted->turbofish_args = zend_persist_turbofish_args_ht(persisted->turbofish_args); + } + + /* Precompute the value-check plan into SHM (relocated via the persist arena, + * which also works in file_cache mode where no SHM segment is locked). */ + if (persisted->parameters) { + uint32_t cnt = zend_count_generic_value_checks(persisted->parameters); + size_t sz = offsetof(zend_generic_value_check_plan, checks) + + cnt * sizeof(zend_generic_value_check); + zend_generic_value_check_plan *tmp = emalloc(sz); + zend_fill_generic_value_check_plan(tmp, persisted->parameters); + persisted->value_check_plan = zend_shared_memdup_free(tmp, sz); + } else { + persisted->value_check_plan = NULL; + } + + return persisted; +} + static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_script* main_persistent_script) { zend_op *persist_ptr; @@ -454,8 +745,31 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { arg_info--; } - arg_info = zend_shared_alloc_get_xlat_entry(arg_info); - ZEND_ASSERT(arg_info != NULL); + zend_arg_info *xlat_arg_info = zend_shared_alloc_get_xlat_entry(arg_info); + if (xlat_arg_info) { + arg_info = xlat_arg_info; + } else { + uint32_t num_args = op_array->num_args; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + num_args++; + } + + if (op_array->fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + + arg_info = zend_shared_memdup_put(arg_info, sizeof(zend_arg_info) * num_args); + for (uint32_t i = 0; i < num_args; i++) { + if (arg_info[i].name) { + zend_accel_store_interned_string(arg_info[i].name); + } + + zend_persist_type(&arg_info[i].type); + if (arg_info[i].doc_comment) { + zend_accel_store_interned_string(arg_info[i].doc_comment); + } + } + } if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { arg_info++; } @@ -490,6 +804,16 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc op_array->dynamic_func_defs = zend_shared_alloc_get_xlat_entry(op_array->dynamic_func_defs); ZEND_ASSERT(op_array->dynamic_func_defs != NULL); } + if (op_array->generic_parameters) { + zend_generic_parameter_list *xlat_params = zend_shared_alloc_get_xlat_entry(op_array->generic_parameters); + ZEND_ASSERT(xlat_params != NULL); + op_array->generic_parameters = xlat_params; + } + if (op_array->generic_types) { + zend_generic_type_table *xlat_types = zend_shared_alloc_get_xlat_entry(op_array->generic_types); + ZEND_ASSERT(xlat_types != NULL); + op_array->generic_types = xlat_types; + } ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem)))); return; } @@ -501,6 +825,47 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc if (op_array->scope && !(op_array->fn_flags & ZEND_ACC_CLOSURE) && (op_array->scope->ce_flags & ZEND_ACC_CACHED)) { + if (op_array->arg_info) { + zend_arg_info *arg_info = op_array->arg_info; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + arg_info--; + } + + if (!zend_accel_in_shm(arg_info)) { + uint32_t num_args = op_array->num_args; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + num_args++; + } + + if (op_array->fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + + zend_arg_info *xlat_arg_info = zend_shared_alloc_get_xlat_entry(arg_info); + if (xlat_arg_info) { + arg_info = xlat_arg_info; + } else { + arg_info = zend_shared_memdup_put(arg_info, sizeof(zend_arg_info) * num_args); + for (uint32_t i = 0; i < num_args; i++) { + if (arg_info[i].name) { + zend_accel_store_interned_string(arg_info[i].name); + } + + zend_persist_type(&arg_info[i].type); + if (arg_info[i].doc_comment) { + zend_accel_store_interned_string(arg_info[i].doc_comment); + } + } + } + + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + arg_info++; + } + + op_array->arg_info = arg_info; + } + } + return; } @@ -540,9 +905,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc zend_op *new_opcodes = zend_shared_memdup_put(op_array->opcodes, sizeof(zend_op) * op_array->last); zend_op *opline = new_opcodes; zend_op *end = new_opcodes + op_array->last; - int offset = 0; - for (; opline < end ; opline++, offset++) { + for (; opline < end ; opline++) { #if ZEND_USE_ABS_CONST_ADDR if (opline->op1_type == IS_CONST) { opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals)); @@ -648,6 +1012,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc zend_accel_store_interned_string(arg_info[i].name); } zend_persist_type(&arg_info[i].type); + if (arg_info[i].doc_comment) { + zend_accel_store_interned_string(arg_info[i].doc_comment); + } } if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { arg_info++; @@ -695,6 +1062,14 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } } + if (op_array->generic_parameters) { + op_array->generic_parameters = zend_persist_generic_parameter_list(op_array->generic_parameters); + } + + if (op_array->generic_types) { + op_array->generic_types = zend_persist_generic_type_table(op_array->generic_types); + } + ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem)))); } @@ -729,7 +1104,7 @@ static void zend_persist_op_array(zval *zv) } } -static zend_op_array *zend_persist_class_method(zend_op_array *op_array, zend_class_entry *ce) +static zend_op_array *zend_persist_class_method(zend_op_array *op_array, const zend_class_entry *ce) { zend_op_array *old_op_array; @@ -831,7 +1206,7 @@ static zend_property_info *zend_persist_property_info(zend_property_info *prop) prop->attributes = zend_persist_attributes(prop->attributes); } if (prop->prototype) { - zend_property_info *new_prototype = (zend_property_info *) zend_shared_alloc_get_xlat_entry(prop->prototype); + const zend_property_info *new_prototype = (const zend_property_info *) zend_shared_alloc_get_xlat_entry(prop->prototype); if (new_prototype) { prop->prototype = new_prototype; } @@ -851,7 +1226,7 @@ static zend_property_info *zend_persist_property_info(zend_property_info *prop) } } #endif - zend_property_info *new_prop_info = (zend_property_info *) zend_shared_alloc_get_xlat_entry(hook->prop_info); + const zend_property_info *new_prop_info = (const zend_property_info *) zend_shared_alloc_get_xlat_entry(hook->prop_info); if (new_prop_info) { hook->prop_info = new_prop_info; } @@ -863,9 +1238,65 @@ static zend_property_info *zend_persist_property_info(zend_property_info *prop) return prop; } +static zend_property_info *zend_persist_substituted_property_info(zend_property_info *prop) +{ + zend_class_entry *ce; + prop = zend_shared_memdup_put(prop, sizeof(zend_property_info)); + ce = zend_shared_alloc_get_xlat_entry(prop->ce); + if (ce) { + prop->ce = ce; + } + + if (prop->name) { + zend_string *xlat_name = zend_shared_alloc_get_xlat_entry(prop->name); + if (xlat_name) { + prop->name = xlat_name; + } + } + + if (prop->doc_comment) { + zend_string *xlat_doc = zend_shared_alloc_get_xlat_entry(prop->doc_comment); + if (xlat_doc) { + prop->doc_comment = xlat_doc; + } + } + + if (prop->attributes) { + HashTable *xlat_attrs = zend_shared_alloc_get_xlat_entry(prop->attributes); + if (xlat_attrs) { + prop->attributes = xlat_attrs; + } + } + + if (prop->prototype) { + const zend_property_info *xlat_proto = zend_shared_alloc_get_xlat_entry(prop->prototype); + if (xlat_proto) { + prop->prototype = xlat_proto; + } + } + + zend_persist_type(&prop->type); + if (prop->hooks) { + prop->hooks = zend_shared_memdup_put(prop->hooks, ZEND_PROPERTY_HOOK_STRUCT_SIZE); + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + zend_op_array *hook = zend_persist_class_method(&prop->hooks[i]->op_array, prop->ce); + const zend_property_info *new_prop_info = zend_shared_alloc_get_xlat_entry(hook->prop_info); + if (new_prop_info) { + hook->prop_info = new_prop_info; + } + + prop->hooks[i] = (zend_function *) hook; + } + } + } + + return prop; +} + static void zend_persist_class_constant(zval *zv) { - zend_class_constant *orig_c = Z_PTR_P(zv); + const zend_class_constant *orig_c = Z_PTR_P(zv); zend_class_constant *c = zend_shared_alloc_get_xlat_entry(orig_c); zend_class_entry *ce; @@ -964,12 +1395,11 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce) } } if (ce->default_static_members_table) { - int i; ce->default_static_members_table = zend_shared_memdup_free(ce->default_static_members_table, sizeof(zval) * ce->default_static_members_count); /* Persist only static properties in this class. * Static properties from parent classes will be handled in class_copy_ctor and are marked with IS_INDIRECT */ - for (i = 0; i < ce->default_static_members_count; i++) { + for (uint32_t i = 0; i < ce->default_static_members_count; i++) { if (Z_TYPE(ce->default_static_members_table[i]) != IS_INDIRECT) { zend_persist_zval(&ce->default_static_members_table[i]); } @@ -999,9 +1429,11 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce) if (prop->ce == orig_ce) { Z_PTR(p->val) = zend_persist_property_info(prop); } else { - prop = zend_shared_alloc_get_xlat_entry(prop); - if (prop) { - Z_PTR(p->val) = prop; + zend_property_info *xlat_prop = zend_shared_alloc_get_xlat_entry(prop); + if (xlat_prop) { + Z_PTR(p->val) = xlat_prop; + } else if (prop->flags & ZEND_ACC_GENERIC_CLONE) { + Z_PTR(p->val) = zend_persist_substituted_property_info(prop); } else { /* This can happen if preloading is used and we inherit a property from an * internal class. In that case we should keep pointing to the internal @@ -1063,6 +1495,18 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce) ce->attributes = zend_persist_attributes(ce->attributes); } + if (ce->generic_parameters) { + ce->generic_parameters = zend_persist_generic_parameter_list(ce->generic_parameters); + } + + if (ce->generic_types) { + ce->generic_types = zend_persist_generic_type_table(ce->generic_types); + } + + if (ce->generic_type_args) { + ce->generic_type_args = zend_persist_type_arg_table(ce->generic_type_args, ce); + } + if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_LINKED)) { uint32_t i = 0; @@ -1283,6 +1727,41 @@ void zend_update_parent_ce(zend_class_entry *ce) } } +#ifdef HAVE_JIT +static void zend_accel_persist_jit_op_array(zend_op_array *op_array, const zend_class_entry *ce) +{ + if (op_array->type == ZEND_USER_FUNCTION) { + if (op_array->scope == ce + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) + && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { + zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); + for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { + zend_jit_op_array(op_array->dynamic_func_defs[i], ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); + } + } + } +} + +static void zend_accel_persist_link_func_info(zend_op_array *op_array, const zend_class_entry *ce) +{ + if (op_array->type == ZEND_USER_FUNCTION + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) { + if ((op_array->scope != ce + || (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) + && (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC + || JIT_G(trigger) == ZEND_JIT_ON_PROF_REQUEST + || JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS + || JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE)) { + void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + + if (jit_extension) { + ZEND_SET_FUNC_INFO(op_array, jit_extension); + } + } + } +} +#endif + static void zend_accel_persist_class_table(HashTable *class_table) { Bucket *p; @@ -1309,44 +1788,48 @@ static void zend_accel_persist_class_table(HashTable *class_table) if (JIT_G(on) && JIT_G(opt_level) <= ZEND_JIT_LEVEL_OPT_FUNCS && !ZCG(current_persistent_script)->corrupted) { zend_op_array *op_array; + zend_property_info *prop; ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) { if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) { ce = Z_PTR(p->val); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION) { - if (op_array->scope == ce - && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) - && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { - zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); - for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { - zend_jit_op_array(op_array->dynamic_func_defs[i], ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL); + zend_accel_persist_jit_op_array(op_array, ce); + } ZEND_HASH_FOREACH_END(); + + if (ce->num_hooked_props > 0) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + if (prop->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + op_array = &prop->hooks[i]->op_array; + zend_accel_persist_jit_op_array(op_array, ce); + } } } - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } } } ZEND_HASH_FOREACH_END(); ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) { if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) { ce = Z_PTR(p->val); ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { - if (op_array->type == ZEND_USER_FUNCTION - && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) { - if ((op_array->scope != ce - || (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) - && (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC - || JIT_G(trigger) == ZEND_JIT_ON_PROF_REQUEST - || JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS - || JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE)) { - void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes); - - if (jit_extension) { - ZEND_SET_FUNC_INFO(op_array, jit_extension); + zend_accel_persist_link_func_info(op_array, ce); + } ZEND_HASH_FOREACH_END(); + + if (ce->num_hooked_props > 0) { + ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) { + if (prop->hooks) { + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + op_array = &prop->hooks[i]->op_array; + zend_accel_persist_link_func_info(op_array, ce); + } } } - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } } } ZEND_HASH_FOREACH_END(); } @@ -1355,11 +1838,11 @@ static void zend_accel_persist_class_table(HashTable *class_table) zend_error_info **zend_persist_warnings(uint32_t num_warnings, zend_error_info **warnings) { if (warnings) { - warnings = zend_shared_memdup_free(warnings, num_warnings * sizeof(zend_error_info *)); + warnings = zend_shared_memdup(warnings, num_warnings * sizeof(zend_error_info *)); for (uint32_t i = 0; i < num_warnings; i++) { - warnings[i] = zend_shared_memdup_free(warnings[i], sizeof(zend_error_info)); zend_accel_store_string(warnings[i]->filename); zend_accel_store_string(warnings[i]->message); + warnings[i] = zend_shared_memdup(warnings[i], sizeof(zend_error_info)); } } return warnings; @@ -1379,7 +1862,7 @@ static zend_early_binding *zend_persist_early_bindings( return early_bindings; } -zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, int for_shm) +zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, bool for_shm) { Bucket *p; diff --git a/ext/opcache/zend_persist.h b/ext/opcache/zend_persist.h index 930430c9589b..453ae0811c17 100644 --- a/ext/opcache/zend_persist.h +++ b/ext/opcache/zend_persist.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -24,8 +22,8 @@ BEGIN_EXTERN_C() -uint32_t zend_accel_script_persist_calc(zend_persistent_script *script, int for_shm); -zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, int for_shm); +uint32_t zend_accel_script_persist_calc(zend_persistent_script *script, bool for_shm); +zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, bool for_shm); void zend_persist_class_entry_calc(zend_class_entry *ce); zend_class_entry *zend_persist_class_entry(zend_class_entry *ce); diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 639d7d544670..be1deda11ca7 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -47,9 +45,10 @@ } while (0) static void zend_persist_zval_calc(zval *z); -static void zend_persist_op_array_calc(zval *zv); +static void zend_persist_op_array_calc(const zval *zv); +static void zend_persist_type_calc(zend_type *type); -static void zend_hash_persist_calc(HashTable *ht) +static void zend_hash_persist_calc(const HashTable *ht) { if ((HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) || ht->nNumUsed == 0) { return; @@ -79,7 +78,7 @@ static void zend_persist_ast_calc(zend_ast *ast) ADD_SIZE(sizeof(zend_ast_zval)); zend_persist_zval_calc(&((zend_ast_zval*)(ast))->val); } else if (zend_ast_is_list(ast)) { - zend_ast_list *list = zend_ast_get_list(ast); + const zend_ast_list *list = zend_ast_get_list(ast); ADD_SIZE(sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children); for (i = 0; i < list->children; i++) { if (list->child[i]) { @@ -92,7 +91,9 @@ static void zend_persist_ast_calc(zend_ast *ast) ZVAL_PTR(&z, zend_ast_get_op_array(ast)->op_array); zend_persist_op_array_calc(&z); } else if (ast->kind == ZEND_AST_CALLABLE_CONVERT) { + zend_ast_fcc *fcc_ast = (zend_ast_fcc*)ast; ADD_SIZE(sizeof(zend_ast_fcc)); + zend_persist_ast_calc(fcc_ast->args); } else if (zend_ast_is_decl(ast)) { /* Not implemented. */ ZEND_UNREACHABLE(); @@ -125,7 +126,7 @@ static void zend_persist_zval_calc(zval *z) } size = zend_shared_memdup_size(Z_ARR_P(z), sizeof(zend_array)); if (size) { - HashTable *ht = Z_ARRVAL_P(z); + const HashTable *ht = Z_ARRVAL_P(z); ADD_SIZE(size); zend_hash_persist_calc(ht); @@ -181,6 +182,9 @@ static void zend_persist_attributes_calc(HashTable *attributes) ADD_SIZE(ZEND_ATTRIBUTE_SIZE(attr->argc)); ADD_INTERNED_STRING(attr->name); ADD_INTERNED_STRING(attr->lcname); + if (attr->validation_error != NULL) { + ADD_INTERNED_STRING(attr->validation_error); + } for (i = 0; i < attr->argc; i++) { if (attr->args[i].name) { @@ -188,12 +192,37 @@ static void zend_persist_attributes_calc(HashTable *attributes) } zend_persist_zval_calc(&attr->args[i].value); } + + if (attr->generic_args) { + ADD_SIZE(sizeof(zend_type)); + zend_persist_type_calc(attr->generic_args); + } } ZEND_HASH_FOREACH_END(); } } static void zend_persist_type_calc(zend_type *type) { + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*type)) { + zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(*type); + ADD_SIZE(sizeof(*ref)); + ADD_INTERNED_STRING(ref->name); + return; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*type)) { + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*type); + ADD_SIZE(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(named->count)); + if (named->name) { + ADD_INTERNED_STRING(named->name); + } + for (uint32_t i = 0; i < named->count; i++) { + zend_persist_type_calc(&named->args[i]); + } + + return; + } + if (ZEND_TYPE_HAS_LIST(*type)) { ADD_SIZE(ZEND_TYPE_LIST_SIZE(ZEND_TYPE_LIST(*type)->num_types)); } @@ -204,6 +233,17 @@ static void zend_persist_type_calc(zend_type *type) zend_persist_type_calc(single_type); continue; } + + if (ZEND_TYPE_HAS_TYPE_PARAMETER(*single_type)) { + zend_persist_type_calc(single_type); + continue; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(*single_type)) { + zend_persist_type_calc(single_type); + continue; + } + if (ZEND_TYPE_HAS_NAME(*single_type)) { zend_string *type_name = ZEND_TYPE_NAME(*single_type); ADD_INTERNED_STRING(type_name); @@ -212,10 +252,170 @@ static void zend_persist_type_calc(zend_type *type) } ZEND_TYPE_FOREACH_END(); } +static void zend_persist_generic_parameter_list_calc(zend_generic_parameter_list *list) +{ + if (!list) { + return; + } + + ADD_SIZE(ZEND_GENERIC_PARAMETER_LIST_SIZE(list->count)); + for (uint32_t i = 0; i < list->count; i++) { + ADD_INTERNED_STRING(list->parameters[i].name); + zend_persist_type_calc(&list->parameters[i].bound); + zend_persist_type_calc(&list->parameters[i].bound_pre_erasure); + zend_persist_type_calc(&list->parameters[i].default_type); + zend_persist_type_calc(&list->parameters[i].default_pre_erasure); + } +} + +static void zend_persist_generic_type_table_ht_calc(HashTable *ht) +{ + zend_hash_persist_calc(ht); + if (HT_IS_PACKED(ht)) { + zval *v; + ZEND_HASH_PACKED_FOREACH_VAL(ht, v) { + ADD_SIZE(sizeof(zend_type)); + zend_persist_type_calc((zend_type *) Z_PTR_P(v)); + } ZEND_HASH_FOREACH_END(); + } else { + Bucket *p; + ZEND_HASH_MAP_FOREACH_BUCKET(ht, p) { + if (p->key) { + ADD_INTERNED_STRING(p->key); + } + ADD_SIZE(sizeof(zend_type)); + zend_persist_type_calc((zend_type *) Z_PTR(p->val)); + } ZEND_HASH_FOREACH_END(); + } + ADD_SIZE(sizeof(HashTable)); +} + +/* Mirror zend_persist_concrete_call_table's SHM reservation; the eligibility + * predicate must stay byte-identical to persist or SHM is corrupted. */ +static void zend_persist_concrete_call_table_calc(zend_turbofish_args_entry *entry) +{ + zend_type_arg_table *src = entry->concrete_table; + if (!src) { + return; + } + const zend_type_named_with_args *nwa = + ZEND_TYPE_HAS_NAMED_WITH_ARGS(entry->args_box) + ? ZEND_TYPE_NAMED_WITH_ARGS(entry->args_box) : NULL; + uint32_t passed = nwa ? nwa->count : 0; + for (uint32_t i = 0; i < src->count; i++) { + if (i >= passed && (src->entries[i].name || src->entries[i].type_ref)) { + return; /* NULL-fallback: persist reserves nothing for this site. */ + } + } + ADD_SIZE(ZEND_TYPE_ARG_TABLE_SIZE(src->count)); + for (uint32_t i = 0; i < src->count; i++) { + if (src->entries[i].name) { + ADD_INTERNED_STRING(src->entries[i].name); + } + if (ZEND_TYPE_IS_SET(src->entries[i].owned_type)) { + zend_persist_type_calc(&src->entries[i].owned_type); + } + } +} + +/* The turbofish_args HT entries are zend_turbofish_args_entry — same as a + * boxed type for size accounting purposes, but the entry struct itself is + * what we shared-memdup, not a bare zend_type. */ +static void zend_persist_turbofish_args_ht_calc(HashTable *ht) +{ + zend_hash_persist_calc(ht); + if (HT_IS_PACKED(ht)) { + zval *v; + ZEND_HASH_PACKED_FOREACH_VAL(ht, v) { + ADD_SIZE(sizeof(zend_turbofish_args_entry)); + zend_turbofish_args_entry *e = (zend_turbofish_args_entry *) Z_PTR_P(v); + zend_persist_type_calc(&e->args_box); + zend_persist_concrete_call_table_calc(e); + } ZEND_HASH_FOREACH_END(); + } else { + Bucket *p; + ZEND_HASH_MAP_FOREACH_BUCKET(ht, p) { + if (p->key) { + ADD_INTERNED_STRING(p->key); + } + ADD_SIZE(sizeof(zend_turbofish_args_entry)); + zend_turbofish_args_entry *e = (zend_turbofish_args_entry *) Z_PTR(p->val); + zend_persist_type_calc(&e->args_box); + zend_persist_concrete_call_table_calc(e); + } ZEND_HASH_FOREACH_END(); + } + ADD_SIZE(sizeof(HashTable)); +} + +static void zend_persist_generic_type_table_calc(zend_generic_type_table *table) +{ + if (!table) { + return; + } + + ADD_SIZE(sizeof(*table)); + if (table->return_type) { + ADD_SIZE(sizeof(zend_type)); + zend_persist_type_calc(table->return_type); + } + + if (table->extends) { + ADD_SIZE(sizeof(zend_type)); + zend_persist_type_calc(table->extends); + } + + if (table->parameters) { + zend_persist_generic_type_table_ht_calc(table->parameters); + } + + if (table->properties) { + zend_persist_generic_type_table_ht_calc(table->properties); + } + + if (table->class_constants) { + zend_persist_generic_type_table_ht_calc(table->class_constants); + } + + if (table->implements) { + zend_persist_generic_type_table_ht_calc(table->implements); + } + + if (table->trait_uses) { + zend_persist_generic_type_table_ht_calc(table->trait_uses); + } + + if (table->turbofish_args) { + zend_persist_turbofish_args_ht_calc(table->turbofish_args); + } + + /* Mirror the value-check plan reservation in zend_persist_generic_type_table. */ + if (table->parameters) { + uint32_t cnt = zend_count_generic_value_checks(table->parameters); + ADD_SIZE(offsetof(zend_generic_value_check_plan, checks) + + cnt * sizeof(zend_generic_value_check)); + } +} + +static void zend_persist_type_arg_table_calc(zend_type_arg_table *table) +{ + if (!table) { + return; + } + ADD_SIZE(ZEND_TYPE_ARG_TABLE_SIZE(table->count)); + for (uint32_t i = 0; i < table->count; i++) { + if (table->entries[i].name) { + ADD_INTERNED_STRING(table->entries[i].name); + } + if (ZEND_TYPE_IS_SET(table->entries[i].owned_type)) { + zend_persist_type_calc(&table->entries[i].owned_type); + } + } +} + static void zend_persist_op_array_calc_ex(zend_op_array *op_array) { if (op_array->function_name) { - zend_string *old_name = op_array->function_name; + const zend_string *old_name = op_array->function_name; ADD_INTERNED_STRING(op_array->function_name); /* Remember old function name, so it can be released multiple times if shared. */ if (op_array->function_name != old_name @@ -228,6 +428,36 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { /* already stored */ ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array))); + if (op_array->arg_info) { + zend_arg_info *arg_info = op_array->arg_info; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + arg_info--; + } + + if (!zend_shared_alloc_get_xlat_entry(arg_info)) { + uint32_t num_args = op_array->num_args; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + num_args++; + } + + if (op_array->fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + + ADD_SIZE(sizeof(zend_arg_info) * num_args); + for (uint32_t i = 0; i < num_args; i++) { + if (arg_info[i].name) { + ADD_INTERNED_STRING(arg_info[i].name); + } + + zend_persist_type_calc(&arg_info[i].type); + if (arg_info[i].doc_comment) { + ADD_INTERNED_STRING(arg_info[i].doc_comment); + } + } + } + } + return; } } @@ -235,6 +465,36 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) if (op_array->scope && !(op_array->fn_flags & ZEND_ACC_CLOSURE) && (op_array->scope->ce_flags & ZEND_ACC_CACHED)) { + if (op_array->arg_info) { + zend_arg_info *arg_info = op_array->arg_info; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + arg_info--; + } + + if (!zend_accel_in_shm(arg_info) && !zend_shared_alloc_get_xlat_entry(arg_info)) { + uint32_t num_args = op_array->num_args; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + num_args++; + } + + if (op_array->fn_flags & ZEND_ACC_VARIADIC) { + num_args++; + } + + ADD_SIZE(sizeof(zend_arg_info) * num_args); + for (uint32_t i = 0; i < num_args; i++) { + if (arg_info[i].name) { + ADD_INTERNED_STRING(arg_info[i].name); + } + + zend_persist_type_calc(&arg_info[i].type); + if (arg_info[i].doc_comment) { + ADD_INTERNED_STRING(arg_info[i].doc_comment); + } + } + } + } + return; } @@ -255,7 +515,7 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) if (op_array->literals) { zval *p = op_array->literals; - zval *end = p + op_array->last_literal; + const zval *end = p + op_array->last_literal; ADD_SIZE(sizeof(zval) * op_array->last_literal); while (p < end) { zend_persist_zval_calc(p); @@ -269,7 +529,7 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) /* ZEND_ACC_PTR_OPS and ZEND_ACC_OVERRIDE use the same value */ if ((op_array->fn_flags & ZEND_ACC_PTR_OPS) && !op_array->function_name) { zend_op *op = op_array->opcodes; - zend_op *end = op + op_array->last; + const zend_op *end = op + op_array->last; while (op < end) { if (op->opcode == ZEND_DECLARE_ATTRIBUTED_CONST) { HashTable *attributes = Z_PTR_P(RT_CONSTANT(op+1, (op+1)->op1)); @@ -301,6 +561,9 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) ADD_INTERNED_STRING(arg_info[i].name); } zend_persist_type_calc(&arg_info[i].type); + if (arg_info[i].doc_comment) { + ADD_INTERNED_STRING(arg_info[i].doc_comment); + } } } @@ -338,10 +601,13 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) } } + zend_persist_generic_parameter_list_calc(op_array->generic_parameters); + zend_persist_generic_type_table_calc(op_array->generic_types); + ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array))); } -static void zend_persist_op_array_calc(zval *zv) +static void zend_persist_op_array_calc(const zval *zv) { zend_op_array *op_array = Z_PTR_P(zv); ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION); @@ -414,7 +680,21 @@ static void zend_persist_property_info_calc(zend_property_info *prop) } } -static void zend_persist_class_constant_calc(zval *zv) +static void zend_persist_substituted_property_info_calc(zend_property_info *prop) +{ + ADD_SIZE(sizeof(zend_property_info)); + zend_persist_type_calc(&prop->type); + if (prop->hooks) { + ADD_SIZE(ZEND_PROPERTY_HOOK_STRUCT_SIZE); + for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) { + if (prop->hooks[i]) { + zend_persist_class_method_calc(&prop->hooks[i]->op_array); + } + } + } +} + +static void zend_persist_class_constant_calc(const zval *zv) { zend_class_constant *c = Z_PTR_P(zv); @@ -476,10 +756,8 @@ void zend_persist_class_entry_calc(zend_class_entry *ce) } } if (ce->default_static_members_table) { - int i; - ADD_SIZE(sizeof(zval) * ce->default_static_members_count); - for (i = 0; i < ce->default_static_members_count; i++) { + for (uint32_t i = 0; i < ce->default_static_members_count; i++) { if (Z_TYPE(ce->default_static_members_table[i]) != IS_INDIRECT) { zend_persist_zval_calc(&ce->default_static_members_table[i]); } @@ -499,6 +777,9 @@ void zend_persist_class_entry_calc(zend_class_entry *ce) ADD_INTERNED_STRING(p->key); if (prop->ce == ce) { zend_persist_property_info_calc(prop); + } else if ((prop->flags & ZEND_ACC_GENERIC_CLONE) && !zend_shared_alloc_get_xlat_entry(prop)) { + zend_shared_alloc_register_xlat_entry(prop, prop); + zend_persist_substituted_property_info_calc(prop); } } ZEND_HASH_FOREACH_END(); @@ -533,6 +814,10 @@ void zend_persist_class_entry_calc(zend_class_entry *ce) zend_persist_attributes_calc(ce->attributes); } + zend_persist_generic_parameter_list_calc(ce->generic_parameters); + zend_persist_generic_type_table_calc(ce->generic_types); + zend_persist_type_arg_table_calc(ce->generic_type_args); + if (ce->num_interfaces) { uint32_t i; @@ -593,7 +878,7 @@ void zend_persist_class_entry_calc(zend_class_entry *ce) } } -static void zend_accel_persist_class_table_calc(HashTable *class_table) +static void zend_accel_persist_class_table_calc(const HashTable *class_table) { Bucket *p; @@ -626,7 +911,7 @@ static void zend_persist_early_bindings_calc( } } -uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, int for_shm) +uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, bool for_shm) { Bucket *p; diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index 37dbe59f3d55..b264f98a02b7 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -229,6 +227,9 @@ int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size) if (!g_shared_alloc_handler) { /* try memory handlers in order */ + if (handler_table->name == NULL) { + return NO_SHM_BACKEND; + } for (he = handler_table; he->name; he++) { res = zend_shared_alloc_try(he, requested_size, &ZSMMG(shared_segments), &ZSMMG(shared_segments_count), &error_in); if (res) { diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 41cba0bb3519..cf0bb10d8932 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | Zend OPcache | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -72,6 +70,7 @@ #define SUCCESSFULLY_REATTACHED 4 #define ALLOC_FAIL_MAPPING 8 #define ALLOC_FALLBACK 9 +#define NO_SHM_BACKEND 10 typedef struct _zend_shared_segment { size_t size; @@ -165,7 +164,11 @@ typedef union _align_test { zend_long lng; } align_test; -#if ZEND_GCC_VERSION >= 2000 +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +# define PLATFORM_ALIGNMENT (alignof(align_test) < 8 ? 8 : alignof(align_test)) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +# define PLATFORM_ALIGNMENT (_Alignof(align_test) < 8 ? 8 : _Alignof(align_test)) +#elif ZEND_GCC_VERSION >= 2000 || defined(__clang__) # define PLATFORM_ALIGNMENT (__alignof__(align_test) < 8 ? 8 : __alignof__(align_test)) #else # define PLATFORM_ALIGNMENT (sizeof(align_test)) diff --git a/ext/openssl/config.w32 b/ext/openssl/config.w32 index 714f93a0176f..4b7f4b8b8565 100644 --- a/ext/openssl/config.w32 +++ b/ext/openssl/config.w32 @@ -16,9 +16,7 @@ if (PHP_OPENSSL != "no") { AC_DEFINE("LOAD_OPENSSL_LEGACY_PROVIDER", 1, "Define to 1 to load the OpenSSL legacy algorithm provider in addition to the default provider."); } if (PHP_OPENSSL_ARGON2 != "no") { - if (PHP_ZTS != "no") { - WARNING("OpenSSL argon2 hashing not supported in ZTS mode for now"); - } else if (!CHECK_FUNC_IN_HEADER("openssl/thread.h", "OSSL_set_max_threads", PHP_PHP_BUILD + "\\include")) { + if (!GREP_HEADER("openssl/thread.h", "OSSL_set_max_threads", PHP_PHP_BUILD + "\\include")) { WARNING("OpenSSL argon2 hashing requires OpenSSL >= 3.2"); } else { AC_DEFINE("HAVE_OPENSSL_ARGON2", 1, "Define to 1 to enable OpenSSL argon2 password hashing."); diff --git a/ext/openssl/config0.m4 b/ext/openssl/config0.m4 index 774213336b6e..15d1feb96eea 100644 --- a/ext/openssl/config0.m4 +++ b/ext/openssl/config0.m4 @@ -49,9 +49,6 @@ if test "$PHP_OPENSSL" != "no"; then the default provider.])]) AS_VAR_IF([PHP_OPENSSL_ARGON2], [no],, [ - AS_VAR_IF([PHP_THREAD_SAFETY], [yes], - [AC_MSG_ERROR([Not supported in ZTS mode for now])]) - PHP_CHECK_LIBRARY([crypto], [OSSL_set_max_threads], [AC_DEFINE([HAVE_OPENSSL_ARGON2], [1], [Define to 1 to enable OpenSSL argon2 password hashing.])], diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 4d1567f56d8c..65e63265dfc6 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Venaas | | Wez Furlong | @@ -53,16 +51,15 @@ #include #include #include -#if PHP_OPENSSL_API_VERSION >= 0x30000 -#include -#include -#include -#endif ZEND_DECLARE_MODULE_GLOBALS(openssl) #include "openssl_arginfo.h" +/* OpenSSLException class */ + +zend_class_entry *php_openssl_exception_ce; + /* OpenSSLCertificate class */ zend_class_entry *php_openssl_certificate_ce; @@ -172,6 +169,371 @@ static void php_openssl_pkey_free_obj(zend_object *object) zend_object_std_dtor(&key_object->std); } +/* Openssl\Psk class */ + +zend_class_entry *php_openssl_psk_ce; + +static zend_object_handlers php_openssl_psk_object_handlers; + +bool php_openssl_is_psk_ce(zval *val) +{ + return Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_psk_ce; +} + +zend_string *php_openssl_psk_get_psk(zval *psk_zv) +{ + zval rv; + zval *prop = zend_read_property(php_openssl_psk_ce, Z_OBJ_P(psk_zv), ZEND_STRL("psk"), 0, &rv); + if (UNEXPECTED(Z_TYPE_P(prop) != IS_STRING)) { + return NULL; + } + return Z_STR_P(prop); +} + +zend_string *php_openssl_psk_get_identity(zval *psk_zv) +{ + zval rv; + zval *prop = zend_read_property(php_openssl_psk_ce, Z_OBJ_P(psk_zv), + ZEND_STRL("identity"), 0, &rv); + if (Z_TYPE_P(prop) == IS_NULL) { + return NULL; + } + if (UNEXPECTED(Z_TYPE_P(prop) != IS_STRING)) { + return NULL; + } + return Z_STR_P(prop); +} + +PHP_METHOD(Openssl_Psk, __construct) +{ + zend_string *psk; + zend_string *identity = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(psk) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_NULL(identity) + ZEND_PARSE_PARAMETERS_END(); + + if (ZSTR_LEN(psk) == 0) { + zend_argument_value_error(1, "must not be empty"); + RETURN_THROWS(); + } + if (ZSTR_LEN(psk) > PHP_OPENSSL_PSK_MAX_PSK_LEN) { + zend_argument_value_error(1, "must not exceed %d bytes", PHP_OPENSSL_PSK_MAX_PSK_LEN); + RETURN_THROWS(); + } + if (identity != NULL && ZSTR_LEN(identity) > PHP_OPENSSL_PSK_MAX_IDENTITY_LEN) { + zend_argument_value_error(2, "must not exceed %d bytes", PHP_OPENSSL_PSK_MAX_IDENTITY_LEN); + RETURN_THROWS(); + } + + zend_update_property_str(php_openssl_psk_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("psk"), psk); + + if (identity != NULL) { + zend_update_property_str(php_openssl_psk_ce, Z_OBJ_P(ZEND_THIS), + ZEND_STRL("identity"), identity); + } else { + zend_update_property_null(php_openssl_psk_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("identity")); + } +} + +/* Openssl\Session class */ + +zend_class_entry *php_openssl_session_ce; + +static zend_object_handlers php_openssl_session_object_handlers; + +bool php_openssl_is_session_ce(zval *val) +{ + return Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == php_openssl_session_ce; +} + +SSL_SESSION *php_openssl_session_from_zval(zval *zv) +{ + if (!php_openssl_is_session_ce(zv)) { + return NULL; + } + return Z_OPENSSL_SESSION_P(zv)->session; +} + +void php_openssl_session_object_init(zval *zv, SSL_SESSION *session) +{ + object_init_ex(zv, php_openssl_session_ce); + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(zv); + obj->session = session; + + unsigned int id_len = 0; + const unsigned char *id = SSL_SESSION_get_id(session, &id_len); + zend_update_property_stringl(php_openssl_session_ce, Z_OBJ_P(zv), + ZEND_STRL("id"), (char *)id, id_len); +} + +static zend_object *php_openssl_session_create_object(zend_class_entry *class_type) +{ + php_openssl_session_object *intern = zend_object_alloc(sizeof(php_openssl_session_object), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + + return &intern->std; +} + +static zend_function *php_openssl_session_get_constructor(zend_object *object) +{ + zend_throw_error(NULL, + "Cannot directly construct OpenSSLSession, use OpenSSLSession::import() or TLS session callbacks"); + return NULL; +} + +static void php_openssl_session_free_obj(zend_object *object) +{ + php_openssl_session_object *session_object = php_openssl_session_from_obj(object); + + if (session_object->session) { + SSL_SESSION_free(session_object->session); + session_object->session = NULL; + } + zend_object_std_dtor(&session_object->std); +} + +#define PHP_OPENSSL_SESSION_CHECK() \ + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(ZEND_THIS); \ + if (!obj->session) { \ + zend_throw_exception(php_openssl_exception_ce, "Session is not valid", 0); \ + RETURN_THROWS(); \ + } + +PHP_METHOD(Openssl_Session, export) +{ + zend_long format = ENCODING_PEM; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(format) + ZEND_PARSE_PARAMETERS_END(); + + PHP_OPENSSL_SESSION_CHECK(); + + if (format == ENCODING_DER) { + int len = i2d_SSL_SESSION(obj->session, NULL); + if (len <= 0) { + zend_throw_exception(php_openssl_exception_ce, "Failed to export session", 0); + RETURN_THROWS(); + } + + zend_string *result = zend_string_alloc(len, 0); + unsigned char *p = (unsigned char *)ZSTR_VAL(result); + i2d_SSL_SESSION(obj->session, &p); + ZSTR_VAL(result)[len] = '\0'; + + RETURN_NEW_STR(result); + } + + if (format == ENCODING_PEM) { + BIO *bio = BIO_new(BIO_s_mem()); + if (!bio) { + zend_throw_exception(php_openssl_exception_ce, "Failed to create BIO", 0); + RETURN_THROWS(); + } + + if (!PEM_write_bio_SSL_SESSION(bio, obj->session)) { + BIO_free(bio); + zend_throw_exception(php_openssl_exception_ce, "Failed to export session as PEM", 0); + RETURN_THROWS(); + } + + char *data; + long len = BIO_get_mem_data(bio, &data); + zend_string *result = zend_string_init(data, len, 0); + BIO_free(bio); + + RETURN_NEW_STR(result); + } + + zend_argument_value_error(1, "must be OPENSSL_ENCODING_DER or OPENSSL_ENCODING_PEM"); + RETURN_THROWS(); +} + +PHP_METHOD(Openssl_Session, import) +{ + zend_string *data; + zend_long format = ENCODING_PEM; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(data) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(format) + ZEND_PARSE_PARAMETERS_END(); + + SSL_SESSION *session = NULL; + + if (format == ENCODING_DER) { + const unsigned char *p = (const unsigned char *)ZSTR_VAL(data); + session = d2i_SSL_SESSION(NULL, &p, ZSTR_LEN(data)); + } else if (format == ENCODING_PEM) { + BIO *bio = BIO_new_mem_buf(ZSTR_VAL(data), ZSTR_LEN(data)); + if (bio) { + session = PEM_read_bio_SSL_SESSION(bio, NULL, NULL, NULL); + BIO_free(bio); + } + } else { + zend_argument_value_error(2, "must be OPENSSL_ENCODING_DER or OPENSSL_ENCODING_PEM"); + RETURN_THROWS(); + } + + if (!session) { + zend_throw_exception(php_openssl_exception_ce, "Failed to import session data", 0); + RETURN_THROWS(); + } + + php_openssl_session_object_init(return_value, session); +} + +PHP_METHOD(Openssl_Session, isResumable) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + RETURN_BOOL(SSL_SESSION_is_resumable(obj->session)); +} + +PHP_METHOD(Openssl_Session, getTimeout) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + RETURN_LONG((zend_long)SSL_SESSION_get_timeout(obj->session)); +} + +PHP_METHOD(Openssl_Session, getCreatedAt) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); +#if PHP_OPENSSL_API_VERSION >= 0x30300 + RETURN_LONG((zend_long)SSL_SESSION_get_time_ex(obj->session)); +#else + RETURN_LONG((zend_long)SSL_SESSION_get_time(obj->session)); +#endif +} + +PHP_METHOD(Openssl_Session, getProtocol) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + int version = SSL_SESSION_get_protocol_version(obj->session); + + switch (version) { + case TLS1_3_VERSION: + RETURN_STRING("TLSv1.3"); + case TLS1_2_VERSION: + RETURN_STRING("TLSv1.2"); + case TLS1_1_VERSION: + RETURN_STRING("TLSv1.1"); + case TLS1_VERSION: + RETURN_STRING("TLSv1.0"); + default: + RETURN_NULL(); + } +} + +PHP_METHOD(Openssl_Session, getCipher) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + const SSL_CIPHER *cipher = SSL_SESSION_get0_cipher(obj->session); + if (!cipher) { + RETURN_NULL(); + } + + RETURN_STRING(SSL_CIPHER_get_name(cipher)); +} + +PHP_METHOD(Openssl_Session, hasTicket) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + RETURN_BOOL(SSL_SESSION_has_ticket(obj->session)); +} + +PHP_METHOD(Openssl_Session, getTicketLifetimeHint) +{ + ZEND_PARSE_PARAMETERS_NONE(); + PHP_OPENSSL_SESSION_CHECK(); + + if (!SSL_SESSION_has_ticket(obj->session)) { + RETURN_NULL(); + } + + RETURN_LONG((zend_long)SSL_SESSION_get_ticket_lifetime_hint(obj->session)); +} +PHP_METHOD(Openssl_Session, __serialize) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + PHP_OPENSSL_SESSION_CHECK(); + + BIO *bio = BIO_new(BIO_s_mem()); + if (!bio) { + zend_throw_exception(php_openssl_exception_ce, "Failed to serialize session", 0); + RETURN_THROWS(); + } + + if (!PEM_write_bio_SSL_SESSION(bio, obj->session)) { + BIO_free(bio); + zend_throw_exception(php_openssl_exception_ce, "Failed to serialize session", 0); + RETURN_THROWS(); + } + + char *data; + long len = BIO_get_mem_data(bio, &data); + zend_string *pem = zend_string_init(data, len, 0); + BIO_free(bio); + + array_init(return_value); + add_assoc_str(return_value, "pem", pem); +} + +PHP_METHOD(Openssl_Session, __unserialize) +{ + HashTable *data; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(data) + ZEND_PARSE_PARAMETERS_END(); + + zval *pem_zv = zend_hash_str_find(data, ZEND_STRL("pem")); + if (!pem_zv || Z_TYPE_P(pem_zv) != IS_STRING) { + zend_throw_exception(php_openssl_exception_ce, "Invalid serialization data", 0); + RETURN_THROWS(); + } + + BIO *bio = BIO_new_mem_buf(Z_STRVAL_P(pem_zv), Z_STRLEN_P(pem_zv)); + if (!bio) { + zend_throw_exception(php_openssl_exception_ce, "Failed to unserialize session", 0); + RETURN_THROWS(); + } + + SSL_SESSION *session = PEM_read_bio_SSL_SESSION(bio, NULL, NULL, NULL); + BIO_free(bio); + + if (!session) { + zend_throw_exception(php_openssl_exception_ce, "Failed to unserialize session", 0); + RETURN_THROWS(); + } + + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(ZEND_THIS); + obj->session = session; + + /* Populate id property */ + unsigned int id_len = 0; + const unsigned char *id = SSL_SESSION_get_id(session, &id_len); + zend_update_property_stringl(php_openssl_session_ce, Z_OBJ_P(ZEND_THIS), + ZEND_STRL("id"), (char *)id, id_len); +} + #if defined(HAVE_OPENSSL_ARGON2) static const zend_module_dep openssl_deps[] = { ZEND_MOD_REQUIRED("standard") @@ -223,9 +585,9 @@ void php_openssl_store_errors(void) errors = OPENSSL_G(errors); do { - errors->top = (errors->top + 1) % ERR_NUM_ERRORS; + errors->top = (errors->top + 1) % PHP_OPENSSL_ERR_BUFFER_SIZE; if (errors->top == errors->bottom) { - errors->bottom = (errors->bottom + 1) % ERR_NUM_ERRORS; + errors->bottom = (errors->bottom + 1) % PHP_OPENSSL_ERR_BUFFER_SIZE; } errors->buffer[errors->top] = error_code; } while ((error_code = ERR_get_error())); @@ -308,7 +670,7 @@ bool php_openssl_check_path_ex( fs_file_path_len = file_path_len; } - if (CHECK_NULL_PATH(fs_file_path, fs_file_path_len)) { + if (zend_char_has_nul_byte(fs_file_path, fs_file_path_len)) { error_msg = "must not contain any null bytes"; error_type = E_ERROR; } else if (expand_filepath(fs_file_path, real_path) == NULL) { @@ -351,22 +713,51 @@ int php_openssl_get_ssl_stream_data_index(void) return ssl_stream_data_index; } -/* {{{ INI Settings */ +static PHP_INI_MH(OnUpdateLibCtx) +{ +#if PHP_OPENSSL_API_VERSION >= 0x30000 + if (zend_string_equals_literal(new_value, "default")) { +#if defined(ZTS) && defined(HAVE_OPENSSL_ARGON2) + if (stage != ZEND_INI_STAGE_DEACTIVATE) { + int err_type = stage == ZEND_INI_STAGE_RUNTIME ? E_WARNING : E_ERROR; + php_error_docref(NULL, err_type, "OpenSSL libctx \"default\" cannot be used in this configuration"); + } + return FAILURE; +#else + OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).default_libctx; +#endif + } else if (zend_string_equals_literal(new_value, "custom")) { + OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).custom_libctx; + } else { + /* Do not output error when restoring ini options. */ + if (stage != ZEND_INI_STAGE_DEACTIVATE) { + int err_type = stage == ZEND_INI_STAGE_RUNTIME ? E_WARNING : E_ERROR; + php_error_docref(NULL, err_type, "OpenSSL libctx \"%s\" cannot be found", ZSTR_VAL(new_value)); + } + return FAILURE; + } +#endif + + return SUCCESS; +} + PHP_INI_BEGIN() PHP_INI_ENTRY("openssl.cafile", NULL, PHP_INI_PERDIR, NULL) PHP_INI_ENTRY("openssl.capath", NULL, PHP_INI_PERDIR, NULL) + PHP_INI_ENTRY("openssl.libctx", "custom", PHP_INI_PERDIR, OnUpdateLibCtx) PHP_INI_END() -/* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(openssl) { + php_openssl_exception_ce = register_class_Openssl_OpensslException(zend_ce_exception); + php_openssl_certificate_ce = register_class_OpenSSLCertificate(); php_openssl_certificate_ce->create_object = php_openssl_certificate_create_object; php_openssl_certificate_ce->default_object_handlers = &php_openssl_certificate_object_handlers; memcpy(&php_openssl_certificate_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_openssl_certificate_object_handlers.offset = XtOffsetOf(php_openssl_certificate_object, std); + php_openssl_certificate_object_handlers.offset = offsetof(php_openssl_certificate_object, std); php_openssl_certificate_object_handlers.free_obj = php_openssl_certificate_free_obj; php_openssl_certificate_object_handlers.get_constructor = php_openssl_certificate_get_constructor; php_openssl_certificate_object_handlers.clone_obj = NULL; @@ -377,7 +768,7 @@ PHP_MINIT_FUNCTION(openssl) php_openssl_request_ce->default_object_handlers = &php_openssl_request_object_handlers; memcpy(&php_openssl_request_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_openssl_request_object_handlers.offset = XtOffsetOf(php_openssl_request_object, std); + php_openssl_request_object_handlers.offset = offsetof(php_openssl_request_object, std); php_openssl_request_object_handlers.free_obj = php_openssl_request_free_obj; php_openssl_request_object_handlers.get_constructor = php_openssl_request_get_constructor; php_openssl_request_object_handlers.clone_obj = NULL; @@ -388,12 +779,28 @@ PHP_MINIT_FUNCTION(openssl) php_openssl_pkey_ce->default_object_handlers = &php_openssl_pkey_object_handlers; memcpy(&php_openssl_pkey_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - php_openssl_pkey_object_handlers.offset = XtOffsetOf(php_openssl_pkey_object, std); + php_openssl_pkey_object_handlers.offset = offsetof(php_openssl_pkey_object, std); php_openssl_pkey_object_handlers.free_obj = php_openssl_pkey_free_obj; php_openssl_pkey_object_handlers.get_constructor = php_openssl_pkey_get_constructor; php_openssl_pkey_object_handlers.clone_obj = NULL; php_openssl_pkey_object_handlers.compare = zend_objects_not_comparable; + php_openssl_psk_ce = register_class_Openssl_Psk(); + php_openssl_psk_ce->default_object_handlers = &php_openssl_psk_object_handlers; + + memcpy(&php_openssl_psk_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + + php_openssl_session_ce = register_class_Openssl_Session(); + php_openssl_session_ce->create_object = php_openssl_session_create_object; + php_openssl_session_ce->default_object_handlers = &php_openssl_session_object_handlers; + + memcpy(&php_openssl_session_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + php_openssl_session_object_handlers.offset = offsetof(php_openssl_session_object, std); + php_openssl_session_object_handlers.free_obj = php_openssl_session_free_obj; + php_openssl_session_object_handlers.get_constructor = php_openssl_session_get_constructor; + php_openssl_session_object_handlers.clone_obj = NULL; + php_openssl_session_object_handlers.compare = zend_objects_not_comparable; + register_openssl_symbols(module_number); php_openssl_backend_init(); @@ -438,9 +845,7 @@ PHP_GINIT_FUNCTION(openssl) #endif openssl_globals->errors = NULL; openssl_globals->errors_mark = NULL; -#if PHP_OPENSSL_API_VERSION >= 0x30000 - php_openssl_backend_init_libctx(&openssl_globals->libctx, &openssl_globals->propq); -#endif + php_openssl_backend_init_libctx(&openssl_globals->ctx); } /* }}} */ @@ -453,9 +858,7 @@ PHP_GSHUTDOWN_FUNCTION(openssl) if (openssl_globals->errors_mark) { pefree(openssl_globals->errors_mark, 1); } -#if PHP_OPENSSL_API_VERSION >= 0x30000 - php_openssl_backend_destroy_libctx(openssl_globals->libctx, openssl_globals->propq); -#endif + php_openssl_backend_destroy_libctx(&openssl_globals->ctx); } /* }}} */ @@ -504,9 +907,7 @@ PHP_MSHUTDOWN_FUNCTION(openssl) /* {{{ Retrieve an array mapping available certificate locations */ PHP_FUNCTION(openssl_get_cert_locations) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); php_openssl_set_cert_locations(return_value); @@ -546,14 +947,11 @@ PHP_FUNCTION(openssl_x509_export_to_file) bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out) { - if (!notext && !X509_print(bio_out, cert)) { - php_openssl_store_errors(); - } - if (!PEM_write_bio_X509(bio_out, cert)) { + if ((notext || X509_print(bio_out, cert)) && PEM_write_bio_X509(bio_out, cert)) { + RETVAL_TRUE; + } else { php_openssl_store_errors(); } - - RETVAL_TRUE; } else { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening file %s", file_path); @@ -848,8 +1246,7 @@ PHP_FUNCTION(openssl_x509_export) } if (!notext && !X509_print(bio_out, cert)) { php_openssl_store_errors(); - } - if (PEM_write_bio_X509(bio_out, cert)) { + } else if (PEM_write_bio_X509(bio_out, cert)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -985,6 +1382,8 @@ PHP_FUNCTION(openssl_x509_parse) bool useshortnames = 1; char * tmpstr; zval subitem; + zval critext; + int critcount = 0; X509_EXTENSION *extension; X509_NAME *subject_name; char *cert_name; @@ -1012,6 +1411,11 @@ PHP_FUNCTION(openssl_x509_parse) subject_name = X509_get_subject_name(cert); cert_name = X509_NAME_oneline(subject_name, NULL, 0); + if (cert_name == NULL) { + php_openssl_store_errors(); + goto err; + } + add_assoc_string(return_value, "name", cert_name); OPENSSL_free(cert_name); @@ -1044,6 +1448,12 @@ PHP_FUNCTION(openssl_x509_parse) } str_serial = i2s_ASN1_INTEGER(NULL, asn1_serial); + /* Can return NULL on error or memory allocation failure */ + if (!str_serial) { + php_openssl_store_errors(); + goto err; + } + add_assoc_string(return_value, "serialNumber", str_serial); OPENSSL_free(str_serial); @@ -1073,7 +1483,7 @@ PHP_FUNCTION(openssl_x509_parse) for (i = 0; i < X509_PURPOSE_get_count(); i++) { int id, purpset; char * pname; - X509_PURPOSE * purp; + const X509_PURPOSE * purp; zval subsub; array_init(&subsub); @@ -1097,18 +1507,22 @@ PHP_FUNCTION(openssl_x509_parse) add_assoc_zval(return_value, "purposes", &subitem); array_init(&subitem); - + array_init(&critext); for (i = 0; i < X509_get_ext_count(cert); i++) { int nid; extension = X509_get_ext(cert, i); nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); if (nid != NID_undef) { - extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension))); + extname = (char *)OBJ_nid2sn(nid); } else { OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1); extname = buf; } + if (X509_EXTENSION_get_critical(extension)) { + add_next_index_string(&critext, extname); + critcount++; + } bio_out = BIO_new(BIO_s_mem()); if (bio_out == NULL) { php_openssl_store_errors(); @@ -1123,7 +1537,7 @@ PHP_FUNCTION(openssl_x509_parse) goto err_subitem; } } - else if (X509V3_EXT_print(bio_out, extension, 0, 0)) { + else if (X509V3_EXT_print(bio_out, extension, 0, 0) > 0) { BIO_get_mem_ptr(bio_out, &bio_buf); add_assoc_stringl(&subitem, extname, bio_buf->data, bio_buf->length); } else { @@ -1132,6 +1546,11 @@ PHP_FUNCTION(openssl_x509_parse) BIO_free(bio_out); } add_assoc_zval(return_value, "extensions", &subitem); + if (critcount > 0) { + add_assoc_zval(return_value, "criticalExtensions", &critext); + } else { + zval_ptr_dtor(&critext); + } if (cert_str) { X509_free(cert); } @@ -1139,6 +1558,7 @@ PHP_FUNCTION(openssl_x509_parse) err_subitem: zval_ptr_dtor(&subitem); + zval_ptr_dtor(&critext); err: zend_array_destroy(Z_ARR_P(return_value)); if (cert_str) { @@ -1243,8 +1663,6 @@ PHP_FUNCTION(openssl_x509_free) } /* }}} */ -/* }}} */ - /* {{{ Creates and exports a PKCS to file */ PHP_FUNCTION(openssl_pkcs12_export_to_file) { @@ -1310,6 +1728,9 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file) if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL) { ca = php_openssl_array_to_X509_sk(item, 5, "extracerts"); + if (!ca) { + goto cleanup; + } } /* end parse extra config */ @@ -1403,6 +1824,9 @@ PHP_FUNCTION(openssl_pkcs12_export) if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL) { ca = php_openssl_array_to_X509_sk(item, 5, "extracerts"); + if (!ca) { + goto cleanup; + } } /* end parse extra config */ @@ -1410,7 +1834,7 @@ PHP_FUNCTION(openssl_pkcs12_export) if (p12 != NULL) { bio_out = BIO_new(BIO_s_mem()); - if (i2d_PKCS12_bio(bio_out, p12)) { + if (bio_out && i2d_PKCS12_bio(bio_out, p12)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1475,7 +1899,7 @@ PHP_FUNCTION(openssl_pkcs12_read) if (cert) { bio_out = BIO_new(BIO_s_mem()); - if (PEM_write_bio_X509(bio_out, cert)) { + if (bio_out && PEM_write_bio_X509(bio_out, cert)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); @@ -1488,6 +1912,10 @@ PHP_FUNCTION(openssl_pkcs12_read) if (pkey) { bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto cleanup; + } + if (PEM_write_bio_PrivateKey(bio_out, pkey, NULL, NULL, 0, 0, NULL)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1502,13 +1930,16 @@ PHP_FUNCTION(openssl_pkcs12_read) cert_num = sk_X509_num(ca); if (ca && cert_num) { array_init(&zextracerts); + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto cleanup; + } for (i = 0; i < cert_num; i++) { zval zextracert; X509* aCA = sk_X509_pop(ca); if (!aCA) break; - bio_out = BIO_new(BIO_s_mem()); if (PEM_write_bio_X509(bio_out, aCA)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1516,9 +1947,10 @@ PHP_FUNCTION(openssl_pkcs12_read) add_index_zval(&zextracerts, i, &zextracert); } + (void)BIO_reset(bio_out); X509_free(aCA); - BIO_free(bio_out); } + BIO_free(bio_out); sk_X509_free(ca); add_assoc_zval(zout, "extracerts", &zextracerts); @@ -1577,9 +2009,9 @@ PHP_FUNCTION(openssl_csr_export_to_file) bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY)); if (bio_out != NULL) { if (!notext && !X509_REQ_print(bio_out, csr)) { + /* TODO: warn? */ php_openssl_store_errors(); - } - if (!PEM_write_bio_X509_REQ(bio_out, csr)) { + } else if (!PEM_write_bio_X509_REQ(bio_out, csr)) { php_error_docref(NULL, E_WARNING, "Error writing PEM to file %s", file_path); php_openssl_store_errors(); } else { @@ -1628,9 +2060,7 @@ PHP_FUNCTION(openssl_csr_export) bio_out = BIO_new(BIO_s_mem()); if (!notext && !X509_REQ_print(bio_out, csr)) { php_openssl_store_errors(); - } - - if (PEM_write_bio_X509_REQ(bio_out, csr)) { + } else if (PEM_write_bio_X509_REQ(bio_out, csr)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); @@ -1770,10 +2200,17 @@ PHP_FUNCTION(openssl_csr_sign) goto cleanup; } } else { - PHP_OPENSSL_ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial); + if (!PHP_OPENSSL_ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial)) { + php_openssl_store_errors(); + php_error_docref(NULL, E_WARNING, "Error setting serial number"); + goto cleanup; + } } - X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr)); + if (!X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr))) { + php_openssl_store_errors(); + goto cleanup; + } if (cert == NULL) { cert = new_cert; @@ -1782,8 +2219,11 @@ PHP_FUNCTION(openssl_csr_sign) php_openssl_store_errors(); goto cleanup; } - X509_gmtime_adj(X509_getm_notBefore(new_cert), 0); - X509_gmtime_adj(X509_getm_notAfter(new_cert), 60*60*24*num_days); + if (!X509_gmtime_adj(X509_getm_notBefore(new_cert), 0) + || !X509_gmtime_adj(X509_getm_notAfter(new_cert), 60*60*24*num_days)) { + php_openssl_store_errors(); + goto cleanup; + } i = X509_set_pubkey(new_cert, key); if (!i) { php_openssl_store_errors(); @@ -2173,6 +2613,10 @@ PHP_FUNCTION(openssl_pkey_export) if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) { bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + php_openssl_store_errors(); + goto cleanup; + } if (passphrase && req.priv_key_encrypt) { if (req.priv_key_encrypt_cipher) { @@ -2201,6 +2645,7 @@ PHP_FUNCTION(openssl_pkey_export) php_openssl_store_errors(); } } +cleanup: EVP_PKEY_free(key); BIO_free(bio_out); PHP_SSL_REQ_DISPOSE(&req); @@ -2276,7 +2721,7 @@ PHP_FUNCTION(openssl_pkey_get_details) EVP_PKEY *pkey = Z_OPENSSL_PKEY_P(key)->pkey; BIO *out = BIO_new(BIO_s_mem()); - if (!PEM_write_bio_PUBKEY(out, pkey)) { + if (!out || !PEM_write_bio_PUBKEY(out, pkey)) { BIO_free(out); php_openssl_store_errors(); RETURN_FALSE; @@ -2333,6 +2778,14 @@ PHP_FUNCTION(openssl_pkey_derive) RETURN_THROWS(); } + if (ZEND_NUM_ARGS() == 3) { + php_error_docref(NULL, E_DEPRECATED, + "the $key_length parameter is deprecated as it is either ignored or truncates the key"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + if (key_len < 0) { zend_argument_value_error(3, "must be greater than or equal to 0"); RETURN_THROWS(); @@ -2395,9 +2848,9 @@ PHP_FUNCTION(openssl_pbkdf2) } if (method_len) { - digest = EVP_get_digestbyname(method); + digest = php_openssl_get_evp_md_by_name(method); } else { - digest = EVP_sha1(); + digest = php_openssl_get_evp_md_by_name("SHA1"); } if (!digest) { @@ -2409,12 +2862,14 @@ PHP_FUNCTION(openssl_pbkdf2) if (PKCS5_PBKDF2_HMAC(password, (int)password_len, (unsigned char *)salt, (int)salt_len, (int)iterations, digest, (int)key_length, (unsigned char*)ZSTR_VAL(out_buffer)) == 1) { ZSTR_VAL(out_buffer)[key_length] = 0; - RETURN_NEW_STR(out_buffer); + RETVAL_NEW_STR(out_buffer); } else { php_openssl_store_errors(); zend_string_release_ex(out_buffer, 0); - RETURN_FALSE; + RETVAL_FALSE; } + + php_openssl_release_evp_md(digest); } /* }}} */ @@ -2590,6 +3045,9 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) } recipcerts = sk_X509_new_null(); + if (recipcerts == NULL) { + goto clean_exit; + } /* get certs */ if (Z_TYPE_P(zrecipcerts) == IS_ARRAY) { @@ -2611,7 +3069,10 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) goto clean_exit; } } - sk_X509_push(recipcerts, cert); + if (sk_X509_push(recipcerts, cert) <= 0) { + X509_free(cert); + goto clean_exit; + } } ZEND_HASH_FOREACH_END(); } else { /* a single certificate */ @@ -2632,7 +3093,10 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) goto clean_exit; } } - sk_X509_push(recipcerts, cert); + if (sk_X509_push(recipcerts, cert) <= 0) { + X509_free(cert); + goto clean_exit; + } } /* sanity check the cipher */ @@ -2653,16 +3117,21 @@ PHP_FUNCTION(openssl_pkcs7_encrypt) /* tack on extra headers */ if (zheaders) { ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, zcertval) { + int ret; zend_string *str = zval_try_get_string(zcertval); if (UNEXPECTED(!str)) { goto clean_exit; } if (strindex) { - BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); } else { - BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); } zend_string_release(str); + if (ret < 0) { + php_openssl_store_errors(); + goto clean_exit; + } } ZEND_HASH_FOREACH_END(); } @@ -2718,7 +3187,7 @@ PHP_FUNCTION(openssl_pkcs7_read) goto clean_exit; } - p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL); + p7 = php_openssl_pem_read_bio_pkcs7(bio_in); if (p7 == NULL) { php_openssl_store_errors(); goto clean_exit; @@ -2747,33 +3216,41 @@ PHP_FUNCTION(openssl_pkcs7_read) } if (certs != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } for (i = 0; i < sk_X509_num(certs); i++) { X509* ca = sk_X509_value(certs, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509(bio_out, ca)) { + if (PEM_write_bio_X509(bio_out, ca)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } if (crls != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } for (i = 0; i < sk_X509_CRL_num(crls); i++) { X509_CRL* crl = sk_X509_CRL_value(crls, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) { + if (PEM_write_bio_X509_CRL(bio_out, crl)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } RETVAL_TRUE; @@ -2882,6 +3359,7 @@ PHP_FUNCTION(openssl_pkcs7_sign) zend_string_release(str); if (ret < 0) { php_openssl_store_errors(); + goto clean_exit; } } ZEND_HASH_FOREACH_END(); } @@ -3040,19 +3518,19 @@ PHP_FUNCTION(openssl_cms_verify) switch (encoding) { case ENCODING_PEM: - cms = PEM_read_bio_CMS(sigbio, NULL, 0, NULL); - datain = in; - break; - case ENCODING_DER: - cms = d2i_CMS_bio(sigbio, NULL); - datain = in; - break; - case ENCODING_SMIME: - cms = SMIME_read_CMS(sigbio, &datain); - break; - default: - php_error_docref(NULL, E_WARNING, "Unknown encoding"); - goto clean_exit; + cms = php_openssl_pem_read_bio_cms(sigbio); + datain = in; + break; + case ENCODING_DER: + cms = php_openssl_d2i_bio_cms(sigbio); + datain = in; + break; + case ENCODING_SMIME: + cms = php_openssl_smime_read_cms(sigbio, &datain); + break; + default: + php_error_docref(NULL, E_WARNING, "Unknown encoding"); + goto clean_exit; } if (cms == NULL) { php_openssl_store_errors(); @@ -3170,6 +3648,7 @@ PHP_FUNCTION(openssl_cms_encrypt) X509 * cert; const EVP_CIPHER *cipher = NULL; zend_long cipherid = PHP_OPENSSL_CIPHER_DEFAULT; + zend_string *cipher_str = NULL; zend_string * strindex; char * infilename = NULL; size_t infilename_len; @@ -3179,11 +3658,16 @@ PHP_FUNCTION(openssl_cms_encrypt) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppza!|lll", &infilename, &infilename_len, - &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &encoding, &cipherid) == FAILURE) { - RETURN_THROWS(); - } - + ZEND_PARSE_PARAMETERS_START(4, 7) + Z_PARAM_PATH(infilename, infilename_len) + Z_PARAM_PATH(outfilename, outfilename_len) + Z_PARAM_ZVAL(zrecipcerts) + Z_PARAM_ARRAY_OR_NULL(zheaders) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + Z_PARAM_LONG(encoding) + Z_PARAM_STR_OR_LONG(cipher_str, cipherid) + ZEND_PARSE_PARAMETERS_END(); infile = php_openssl_bio_new_file( infilename, infilename_len, 1, PHP_OPENSSL_BIO_MODE_R(flags)); @@ -3198,6 +3682,9 @@ PHP_FUNCTION(openssl_cms_encrypt) } recipcerts = sk_X509_new_null(); + if (recipcerts == NULL) { + goto clean_exit; + } /* get certs */ if (Z_TYPE_P(zrecipcerts) == IS_ARRAY) { @@ -3218,7 +3705,10 @@ PHP_FUNCTION(openssl_cms_encrypt) goto clean_exit; } } - sk_X509_push(recipcerts, cert); + if (sk_X509_push(recipcerts, cert) <= 0) { + php_openssl_store_errors(); + goto clean_exit; + } } ZEND_HASH_FOREACH_END(); } else { /* a single certificate */ @@ -3238,11 +3728,18 @@ PHP_FUNCTION(openssl_cms_encrypt) goto clean_exit; } } - sk_X509_push(recipcerts, cert); + if (sk_X509_push(recipcerts, cert) <= 0) { + php_openssl_store_errors(); + goto clean_exit; + } } /* sanity check the cipher */ - cipher = php_openssl_get_evp_cipher_from_algo(cipherid); + if (cipher_str) { + cipher = php_openssl_get_evp_cipher_by_name(ZSTR_VAL(cipher_str)); + } else { + cipher = php_openssl_get_evp_cipher_from_algo(cipherid); + } if (cipher == NULL) { /* shouldn't happen */ php_error_docref(NULL, E_WARNING, "Failed to get cipher"); @@ -3263,16 +3760,21 @@ PHP_FUNCTION(openssl_cms_encrypt) /* tack on extra headers */ if (zheaders && encoding == ENCODING_SMIME) { ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zheaders), strindex, zcertval) { + int ret; zend_string *str = zval_try_get_string(zcertval); if (UNEXPECTED(!str)) { goto clean_exit; } if (strindex) { - BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s: %s\n", ZSTR_VAL(strindex), ZSTR_VAL(str)); } else { - BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); + ret = BIO_printf(outfile, "%s\n", ZSTR_VAL(str)); } zend_string_release(str); + if (ret < 0) { + php_openssl_store_errors(); + goto clean_exit; + } } ZEND_HASH_FOREACH_END(); } @@ -3367,7 +3869,7 @@ PHP_FUNCTION(openssl_cms_read) goto clean_exit; } - cms = PEM_read_bio_CMS(bio_in, NULL, NULL, NULL); + cms = php_openssl_pem_read_bio_cms(bio_in); if (cms == NULL) { php_openssl_store_errors(); goto clean_exit; @@ -3389,33 +3891,43 @@ PHP_FUNCTION(openssl_cms_read) } if (certs != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } + for (i = 0; i < sk_X509_num(certs); i++) { X509* ca = sk_X509_value(certs, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509(bio_out, ca)) { + if (PEM_write_bio_X509(bio_out, ca)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } if (crls != NULL) { + bio_out = BIO_new(BIO_s_mem()); + if (!bio_out) { + goto clean_exit; + } + for (i = 0; i < sk_X509_CRL_num(crls); i++) { X509_CRL* crl = sk_X509_CRL_value(crls, i); - bio_out = BIO_new(BIO_s_mem()); - if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) { + if (PEM_write_bio_X509_CRL(bio_out, crl)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length); add_index_zval(zout, i, &zcert); } - BIO_free(bio_out); + (void)BIO_reset(bio_out); } + BIO_free(bio_out); } RETVAL_TRUE; @@ -3553,6 +4065,7 @@ PHP_FUNCTION(openssl_cms_sign) zend_string_release(str); if (ret < 0) { php_openssl_store_errors(); + goto clean_exit; } } ZEND_HASH_FOREACH_END(); } @@ -3672,13 +4185,13 @@ PHP_FUNCTION(openssl_cms_decrypt) switch (encoding) { case ENCODING_DER: - cms = d2i_CMS_bio(in, NULL); + cms = php_openssl_d2i_bio_cms(in); break; case ENCODING_PEM: - cms = PEM_read_bio_CMS(in, NULL, 0, NULL); + cms = php_openssl_pem_read_bio_cms(in); break; case ENCODING_SMIME: - cms = SMIME_read_CMS(in, &datain); + cms = php_openssl_smime_read_cms(in, &datain); break; default: zend_argument_value_error(5, "must be an OPENSSL_ENCODING_* constant"); @@ -3710,6 +4223,29 @@ PHP_FUNCTION(openssl_cms_decrypt) /* }}} */ +/* Helper to set RSA padding and digest for OAEP */ +static int php_openssl_set_rsa_padding_and_digest(EVP_PKEY_CTX *ctx, zend_long padding, const char *digest_algo, const EVP_MD **pmd) +{ + if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0) { + return 0; + } + + if (digest_algo != NULL) { + const EVP_MD *md = php_openssl_get_evp_md_by_name(digest_algo); + if (md == NULL) { + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm: %s", digest_algo); + return 0; + } + *pmd = md; + if (padding == RSA_PKCS1_OAEP_PADDING) { + if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0) { + return 0; + } + } + } + + return 1; +} /* {{{ Encrypts data with private key */ PHP_FUNCTION(openssl_private_encrypt) @@ -3765,10 +4301,12 @@ PHP_FUNCTION(openssl_private_decrypt) { zval *key, *crypted; zend_long padding = RSA_PKCS1_PADDING; - char * data; - size_t data_len; + char *data; + char *digest_algo = NULL; + size_t data_len, digest_algo_len = 0; + const EVP_MD *md = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|lp!", &data, &data_len, &crypted, &key, &padding, &digest_algo, &digest_algo_len) == FAILURE) { RETURN_THROWS(); } @@ -3783,7 +4321,7 @@ PHP_FUNCTION(openssl_private_decrypt) size_t out_len = 0; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ctx || EVP_PKEY_decrypt_init(ctx) <= 0 || - EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || + !php_openssl_set_rsa_padding_and_digest(ctx, padding, digest_algo, &md) || EVP_PKEY_decrypt(ctx, NULL, &out_len, (unsigned char *) data, data_len) <= 0) { php_openssl_store_errors(); RETVAL_FALSE; @@ -3805,6 +4343,7 @@ PHP_FUNCTION(openssl_private_decrypt) RETVAL_TRUE; cleanup: + php_openssl_release_evp_md(md); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); } @@ -3816,9 +4355,11 @@ PHP_FUNCTION(openssl_public_encrypt) zval *key, *crypted; zend_long padding = RSA_PKCS1_PADDING; char * data; - size_t data_len; + char *digest_algo = NULL; + size_t data_len, digest_algo_len = 0; + const EVP_MD *md = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|lp!", &data, &data_len, &crypted, &key, &padding, &digest_algo, &digest_algo_len) == FAILURE) { RETURN_THROWS(); } @@ -3833,7 +4374,7 @@ PHP_FUNCTION(openssl_public_encrypt) size_t out_len = 0; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ctx || EVP_PKEY_encrypt_init(ctx) <= 0 || - EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 || + !php_openssl_set_rsa_padding_and_digest(ctx, padding, digest_algo, &md) || EVP_PKEY_encrypt(ctx, NULL, &out_len, (unsigned char *) data, data_len) <= 0) { php_openssl_store_errors(); RETVAL_FALSE; @@ -3854,6 +4395,7 @@ PHP_FUNCTION(openssl_public_encrypt) RETVAL_TRUE; cleanup: + php_openssl_release_evp_md(md); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); } @@ -3864,7 +4406,7 @@ PHP_FUNCTION(openssl_public_decrypt) { zval *key, *crypted; zend_long padding = RSA_PKCS1_PADDING; - char * data; + char *data; size_t data_len; if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) { @@ -3915,9 +4457,7 @@ PHP_FUNCTION(openssl_error_string) char buf[256]; unsigned long val; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); php_openssl_store_errors(); @@ -3925,7 +4465,7 @@ PHP_FUNCTION(openssl_error_string) RETURN_FALSE; } - OPENSSL_G(errors)->bottom = (OPENSSL_G(errors)->bottom + 1) % ERR_NUM_ERRORS; + OPENSSL_G(errors)->bottom = (OPENSSL_G(errors)->bottom + 1) % PHP_OPENSSL_ERR_BUFFER_SIZE; val = OPENSSL_G(errors)->buffer[OPENSSL_G(errors)->bottom]; if (val) { @@ -3937,6 +4477,30 @@ PHP_FUNCTION(openssl_error_string) } /* }}} */ +static zend_result php_openssl_setup_rsa_padding(EVP_PKEY_CTX *pctx, EVP_PKEY *pkey, zend_long padding) +{ + int key_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); + + if (padding != 0) { // 0 = default/unspecified + if (key_type != EVP_PKEY_RSA) { + php_error_docref(NULL, E_WARNING, "Padding parameter is only supported for RSA keys"); + return FAILURE; + } + + if (padding == RSA_PKCS1_PSS_PADDING) { + if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0) { + php_openssl_store_errors(); + return FAILURE; + } + } else if (padding != RSA_PKCS1_PADDING) { + php_error_docref(NULL, E_WARNING, "Unknown padding type"); + return FAILURE; + } + } + + return SUCCESS; +} + /* {{{ Signs data */ PHP_FUNCTION(openssl_sign) { @@ -3949,14 +4513,17 @@ PHP_FUNCTION(openssl_sign) zend_string *method_str = NULL; zend_long method_long = OPENSSL_ALGO_SHA1; const EVP_MD *mdtype; + zend_long padding = 0; + EVP_PKEY_CTX *pctx; bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0; - ZEND_PARSE_PARAMETERS_START(3, 4) + ZEND_PARSE_PARAMETERS_START(3, 5) Z_PARAM_STRING(data, data_len) Z_PARAM_ZVAL(signature) Z_PARAM_ZVAL(key) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_LONG(method_str, method_long) + Z_PARAM_LONG(padding) ZEND_PARSE_PARAMETERS_END(); pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3); @@ -3981,7 +4548,8 @@ PHP_FUNCTION(openssl_sign) md_ctx = EVP_MD_CTX_create(); size_t siglen; if (md_ctx != NULL && - EVP_DigestSignInit(md_ctx, NULL, mdtype, NULL, pkey) && + EVP_DigestSignInit(md_ctx, &pctx, mdtype, NULL, pkey) && + php_openssl_setup_rsa_padding(pctx, pkey, padding) == SUCCESS && EVP_DigestSign(md_ctx, NULL, &siglen, (unsigned char*)data, data_len) && (sigbuf = zend_string_alloc(siglen, 0)) != NULL && EVP_DigestSign(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), &siglen, (unsigned char*)data, data_len)) { @@ -4014,14 +4582,17 @@ PHP_FUNCTION(openssl_verify) size_t signature_len; zend_string *method_str = NULL; zend_long method_long = OPENSSL_ALGO_SHA1; + zend_long padding = 0; + EVP_PKEY_CTX *pctx; bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0; - ZEND_PARSE_PARAMETERS_START(3, 4) + ZEND_PARSE_PARAMETERS_START(3, 5) Z_PARAM_STRING(data, data_len) Z_PARAM_STRING(signature, signature_len) Z_PARAM_ZVAL(key) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_LONG(method_str, method_long) + Z_PARAM_LONG(padding) ZEND_PARSE_PARAMETERS_END(); PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(signature_len, signature, 2); @@ -4046,11 +4617,25 @@ PHP_FUNCTION(openssl_verify) } md_ctx = EVP_MD_CTX_create(); - if (md_ctx == NULL || - !EVP_DigestVerifyInit(md_ctx, NULL, mdtype, NULL, pkey) || - (err = EVP_DigestVerify(md_ctx, (unsigned char *)signature, signature_len, (unsigned char*)data, data_len)) < 0) { + if (md_ctx == NULL) { + php_openssl_store_errors(); + err = -1; + goto cleanup; + } + + if (!EVP_DigestVerifyInit(md_ctx, &pctx, mdtype, NULL, pkey) || + php_openssl_setup_rsa_padding(pctx, pkey, padding) == FAILURE) { + php_openssl_store_errors(); + err = -1; + goto cleanup; + } + + err = EVP_DigestVerify(md_ctx, (unsigned char *)signature, signature_len, (unsigned char*)data, data_len); + if (err < 0) { php_openssl_store_errors(); } + +cleanup: EVP_MD_CTX_destroy(md_ctx); php_openssl_release_evp_md(mdtype); EVP_PKEY_free(pkey); @@ -4087,7 +4672,7 @@ PHP_FUNCTION(openssl_seal) RETURN_THROWS(); } - cipher = EVP_get_cipherbyname(method); + cipher = php_openssl_get_evp_cipher_by_name(method); if (!cipher) { php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); RETURN_FALSE; @@ -4216,21 +4801,23 @@ PHP_FUNCTION(openssl_open) RETURN_FALSE; } - cipher = EVP_get_cipherbyname(method); + cipher = php_openssl_get_evp_cipher_by_name(method); if (!cipher) { php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); - RETURN_FALSE; + RETVAL_FALSE; + goto out_pkey; } cipher_iv_len = EVP_CIPHER_iv_length(cipher); if (cipher_iv_len > 0) { if (!iv) { zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm"); - RETURN_THROWS(); + goto out_pkey; } if ((size_t)cipher_iv_len != iv_len) { php_error_docref(NULL, E_WARNING, "IV length is invalid"); - RETURN_FALSE; + RETVAL_FALSE; + goto out_pkey; } iv_buf = (unsigned char *)iv; } else { @@ -4252,15 +4839,16 @@ PHP_FUNCTION(openssl_open) } efree(buf); - EVP_PKEY_free(pkey); EVP_CIPHER_CTX_free(ctx); +out_pkey: + EVP_PKEY_free(pkey); } /* }}} */ /* {{{ Return array of available digest algorithms */ PHP_FUNCTION(openssl_get_md_methods) { - bool aliases = 0; + bool aliases = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &aliases) == FAILURE) { RETURN_THROWS(); @@ -4272,7 +4860,7 @@ PHP_FUNCTION(openssl_get_md_methods) /* {{{ Return array of available cipher algorithms */ PHP_FUNCTION(openssl_get_cipher_methods) { - bool aliases = 0; + bool aliases = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &aliases) == FAILURE) { RETURN_THROWS(); @@ -4290,9 +4878,7 @@ PHP_FUNCTION(openssl_get_curve_names) size_t i; size_t len = EC_get_builtin_curves(NULL, 0); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); curves = emalloc(sizeof(EC_builtin_curve) * len); if (!EC_get_builtin_curves(curves, len)) { @@ -4314,7 +4900,7 @@ PHP_FUNCTION(openssl_get_curve_names) /* {{{ Computes digest hash value for given data using given method, returns raw or binhex encoded string */ PHP_FUNCTION(openssl_digest) { - bool raw_output = 0; + bool raw_output = false; char *data, *method; size_t data_len, method_len; const EVP_MD *mdtype; @@ -4335,7 +4921,8 @@ PHP_FUNCTION(openssl_digest) sigbuf = zend_string_alloc(siglen, 0); md_ctx = EVP_MD_CTX_create(); - if (EVP_DigestInit(md_ctx, mdtype) && + if (md_ctx && + EVP_DigestInit(md_ctx, mdtype) && EVP_DigestUpdate(md_ctx, (unsigned char *)data, data_len) && EVP_DigestFinal (md_ctx, (unsigned char *)ZSTR_VAL(sigbuf), &siglen)) { if (raw_output) { @@ -4371,7 +4958,7 @@ PHP_FUNCTION(openssl_encrypt) zend_string *ret; zval *tag = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lszsl", &data, &data_len, &method, &method_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lszs!l", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len, &tag, &aad, &aad_len, &tag_len) == FAILURE) { RETURN_THROWS(); } @@ -4393,7 +4980,7 @@ PHP_FUNCTION(openssl_decrypt) size_t data_len, method_len, password_len, iv_len = 0, tag_len = 0, aad_len = 0; zend_string *ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lss!s", &data, &data_len, &method, &method_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lss!s!", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len, &tag, &tag_len, &aad, &aad_len) == FAILURE) { RETURN_THROWS(); } diff --git a/ext/openssl/openssl.stub.php b/ext/openssl/openssl.stub.php index 1fe3a9fc168e..6080ac323903 100644 --- a/ext/openssl/openssl.stub.php +++ b/ext/openssl/openssl.stub.php @@ -2,6 +2,67 @@ /** @generate-class-entries */ +namespace Openssl { + + class OpensslException extends Exception + { + } + + /** + * @strict-properties + */ + final class Psk + { + /** + * @cvalue PHP_OPENSSL_PSK_MAX_PSK_LEN + */ + public const int MAX_PSK_LEN = UNKNOWN; + + /** + * @cvalue PHP_OPENSSL_PSK_MAX_IDENTITY_LEN + */ + public const int MAX_IDENTITY_LEN = UNKNOWN; + + public readonly string $psk; + public readonly ?string $identity; + + public function __construct(string $psk, ?string $identity = null) {} + } + + /** + * @strict-properties + */ + final class Session + { + public readonly string $id; + + public function export(int $format = OPENSSL_ENCODING_PEM): string {} + + public static function import(string $data, int $format = OPENSSL_ENCODING_PEM): Session {} + + public function isResumable(): bool {} + + public function getTimeout(): int {} + + public function getCreatedAt(): int {} + + public function getProtocol(): ?string {} + + public function getCipher(): ?string {} + + public function hasTicket(): bool {} + + public function getTicketLifetimeHint(): ?int {} + + public function __serialize(): array {} + + public function __unserialize(array $data): void {} + } + +} + +namespace { + /** * @var string * @cvalue OPENSSL_VERSION_TEXT @@ -166,6 +227,26 @@ * @cvalue PKCS7_NOOLDMIMETYPE */ const PKCS7_NOOLDMIMETYPE = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_NOSMIMECAP + */ +const PKCS7_NOSMIMECAP = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_CRLFEOL + */ +const PKCS7_CRLFEOL = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_NOCRL + */ +const PKCS7_NOCRL = UNKNOWN; +/** + * @var int + * @cvalue PKCS7_NO_DUAL_CONTENT + */ +const PKCS7_NO_DUAL_CONTENT = UNKNOWN; /** * @var int @@ -236,6 +317,11 @@ * @cvalue RSA_PKCS1_OAEP_PADDING */ const OPENSSL_PKCS1_OAEP_PADDING = UNKNOWN; +/** + * @var int + * @cvalue RSA_PKCS1_PSS_PADDING + */ +const OPENSSL_PKCS1_PSS_PADDING = UNKNOWN; /* Informational stream wrapper constants */ @@ -363,7 +449,6 @@ const OPENSSL_DONT_ZERO_PAD_KEY = UNKNOWN; #ifndef OPENSSL_NO_TLSEXT -/** @var int */ const OPENSSL_TLSEXT_SERVER_NAME = 1; #endif @@ -385,7 +470,6 @@ */ const OPENSSL_ENCODING_PEM = UNKNOWN; - /** * @strict-properties * @not-serializable @@ -549,7 +633,7 @@ function openssl_pkcs7_read(string $data, &$certificates): bool {} function openssl_cms_verify(string $input_filename, int $flags = 0, ?string $certificates = null, array $ca_info = [], ?string $untrusted_certificates_filename = null, ?string $content = null, ?string $pk7 = null, ?string $sigfile = null, int $encoding = OPENSSL_ENCODING_SMIME): bool {} /** @param OpenSSLCertificate|array|string $certificate */ -function openssl_cms_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, int $cipher_algo = OPENSSL_CIPHER_AES_128_CBC): bool {} +function openssl_cms_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, string|int $cipher_algo = OPENSSL_CIPHER_AES_128_CBC): bool {} /** * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key @@ -575,13 +659,13 @@ function openssl_private_encrypt(#[\SensitiveParameter] string $data, &$encrypte * @param string $decrypted_data * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_private_decrypt(string $data, #[\SensitiveParameter] &$decrypted_data, #[\SensitiveParameter] $private_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_private_decrypt(string $data, #[\SensitiveParameter] &$decrypted_data, #[\SensitiveParameter] $private_key, int $padding = OPENSSL_PKCS1_PADDING, ?string $digest_algo = null): bool {} /** * @param string $encrypted_data * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ -function openssl_public_encrypt(#[\SensitiveParameter] string $data, &$encrypted_data, $public_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_public_encrypt(#[\SensitiveParameter] string $data, &$encrypted_data, $public_key, int $padding = OPENSSL_PKCS1_PADDING, ?string $digest_algo = null): bool {} /** * @param string $decrypted_data @@ -595,10 +679,10 @@ function openssl_error_string(): string|false {} * @param string $signature * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1): bool {} +function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): bool {} /** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ -function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1): int|false {} +function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): int|false {} /** * @param string $sealed_data @@ -638,9 +722,9 @@ function openssl_digest(string $data, string $digest_algo, bool $binary = false) /** * @param string $tag */ -function openssl_encrypt(#[\SensitiveParameter] string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", &$tag = null, string $aad = "", int $tag_length = 16): string|false {} +function openssl_encrypt(#[\SensitiveParameter] string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", &$tag = null, ?string $aad = "", int $tag_length = 16): string|false {} -function openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", ?string $tag = null, string $aad = ""): string|false {} +function openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", ?string $tag = null, ?string $aad = ""): string|false {} function openssl_cipher_iv_length(string $cipher_algo): int|false {} @@ -675,3 +759,5 @@ function openssl_get_cert_locations(): array {} function openssl_password_hash(string $algo, #[\SensitiveParameter] string $password, array $options = []): string {} function openssl_password_verify(string $algo, #[\SensitiveParameter] string $password, string $hash): bool {} #endif + +} diff --git a/ext/openssl/openssl_arginfo.h b/ext/openssl/openssl_arginfo.h index fb53dcae903e..caf47a256e78 100644 --- a/ext/openssl/openssl_arginfo.h +++ b/ext/openssl/openssl_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: a42bd7dec0a5e011983ce08b5e31cd8718247501 */ +/* This is a generated file, edit openssl.stub.php instead. + * Stub hash: 4d38e81a2f73bb6dd4bbe7a3e0b8ba86600654e2 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_export_to_file, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) @@ -219,7 +219,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_encrypt, 0, 4, _IS_B ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cipher_algo, IS_LONG, 0, "OPENSSL_CIPHER_AES_128_CBC") + ZEND_ARG_TYPE_MASK(0, cipher_algo, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_CIPHER_AES_128_CBC") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_sign, 0, 5, _IS_BOOL, 0) @@ -258,6 +258,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_private_decrypt, 0, 3, _ ZEND_ARG_INFO(1, decrypted_data) ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algo, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_encrypt, 0, 3, _IS_BOOL, 0) @@ -265,6 +266,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_encrypt, 0, 3, _I ZEND_ARG_INFO(1, encrypted_data) ZEND_ARG_INFO(0, public_key) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algo, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_decrypt, 0, 3, _IS_BOOL, 0) @@ -282,6 +284,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_sign, 0, 3, _IS_BOOL, 0) ZEND_ARG_INFO(1, signature) ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_verify, 0, 3, MAY_BE_LONG|MAY_BE_FALSE) @@ -289,6 +292,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_verify, 0, 3, MAY_BE_LON ZEND_ARG_TYPE_INFO(0, signature, IS_STRING, 0) ZEND_ARG_INFO(0, public_key) ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_seal, 0, 5, MAY_BE_LONG|MAY_BE_FALSE) @@ -333,7 +337,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_encrypt, 0, 3, MAY_BE_ST ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\"\"") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, tag, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 1, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tag_length, IS_LONG, 0, "16") ZEND_END_ARG_INFO() @@ -344,7 +348,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_decrypt, 0, 3, MAY_BE_ST ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tag, IS_STRING, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 1, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_cipher_iv_length, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) @@ -402,6 +406,44 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_password_verify, 0, 3, _ ZEND_END_ARG_INFO() #endif +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Openssl_Psk___construct, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, psk, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, identity, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_export, 0, 0, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_LONG, 0, "OPENSSL_ENCODING_PEM") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Openssl_Session_import, 0, 1, Openssl\\Session, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_LONG, 0, "OPENSSL_ENCODING_PEM") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_isResumable, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_getTimeout, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_Openssl_Session_getCreatedAt arginfo_class_Openssl_Session_getTimeout + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_getProtocol, 0, 0, IS_STRING, 1) +ZEND_END_ARG_INFO() + +#define arginfo_class_Openssl_Session_getCipher arginfo_class_Openssl_Session_getProtocol + +#define arginfo_class_Openssl_Session_hasTicket arginfo_class_Openssl_Session_isResumable + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session_getTicketLifetimeHint, 0, 0, IS_LONG, 1) +ZEND_END_ARG_INFO() + +#define arginfo_class_Openssl_Session___serialize arginfo_openssl_get_cert_locations + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Openssl_Session___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + ZEND_FUNCTION(openssl_x509_export_to_file); ZEND_FUNCTION(openssl_x509_export); ZEND_FUNCTION(openssl_x509_fingerprint); @@ -469,6 +511,18 @@ ZEND_FUNCTION(openssl_get_cert_locations); ZEND_FUNCTION(openssl_password_hash); ZEND_FUNCTION(openssl_password_verify); #endif +ZEND_METHOD(Openssl_Psk, __construct); +ZEND_METHOD(Openssl_Session, export); +ZEND_METHOD(Openssl_Session, import); +ZEND_METHOD(Openssl_Session, isResumable); +ZEND_METHOD(Openssl_Session, getTimeout); +ZEND_METHOD(Openssl_Session, getCreatedAt); +ZEND_METHOD(Openssl_Session, getProtocol); +ZEND_METHOD(Openssl_Session, getCipher); +ZEND_METHOD(Openssl_Session, hasTicket); +ZEND_METHOD(Openssl_Session, getTicketLifetimeHint); +ZEND_METHOD(Openssl_Session, __serialize); +ZEND_METHOD(Openssl_Session, __unserialize); static const zend_function_entry ext_functions[] = { ZEND_FE(openssl_x509_export_to_file, arginfo_openssl_x509_export_to_file) @@ -544,6 +598,26 @@ static const zend_function_entry ext_functions[] = { ZEND_FE_END }; +static const zend_function_entry class_Openssl_Psk_methods[] = { + ZEND_ME(Openssl_Psk, __construct, arginfo_class_Openssl_Psk___construct, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_Openssl_Session_methods[] = { + ZEND_ME(Openssl_Session, export, arginfo_class_Openssl_Session_export, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, import, arginfo_class_Openssl_Session_import, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(Openssl_Session, isResumable, arginfo_class_Openssl_Session_isResumable, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getTimeout, arginfo_class_Openssl_Session_getTimeout, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getCreatedAt, arginfo_class_Openssl_Session_getCreatedAt, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getProtocol, arginfo_class_Openssl_Session_getProtocol, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getCipher, arginfo_class_Openssl_Session_getCipher, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, hasTicket, arginfo_class_Openssl_Session_hasTicket, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, getTicketLifetimeHint, arginfo_class_Openssl_Session_getTicketLifetimeHint, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, __serialize, arginfo_class_Openssl_Session___serialize, ZEND_ACC_PUBLIC) + ZEND_ME(Openssl_Session, __unserialize, arginfo_class_Openssl_Session___unserialize, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + static void register_openssl_symbols(int module_number) { REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_PERSISTENT); @@ -582,6 +656,10 @@ static void register_openssl_symbols(int module_number) REGISTER_LONG_CONSTANT("PKCS7_BINARY", PKCS7_BINARY, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOSIGS", PKCS7_NOSIGS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PKCS7_NOOLDMIMETYPE", PKCS7_NOOLDMIMETYPE, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_NOSMIMECAP", PKCS7_NOSMIMECAP, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_CRLFEOL", PKCS7_CRLFEOL, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_NOCRL", PKCS7_NOCRL, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PKCS7_NO_DUAL_CONTENT", PKCS7_NO_DUAL_CONTENT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_CMS_DETACHED", CMS_DETACHED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_CMS_TEXT", CMS_TEXT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_CMS_NOINTERN", CMS_NOINTERN, CONST_PERSISTENT); @@ -597,6 +675,7 @@ static void register_openssl_symbols(int module_number) #endif REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_PSS_PADDING", RSA_PKCS1_PSS_PADDING, CONST_PERSISTENT); REGISTER_STRING_CONSTANT("OPENSSL_DEFAULT_STREAM_CIPHERS", OPENSSL_DEFAULT_STREAM_CIPHERS, CONST_PERSISTENT); #if !defined(OPENSSL_NO_RC2) REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_RC2_40", PHP_OPENSSL_CIPHER_RC2_40, CONST_PERSISTENT); @@ -640,15 +719,10 @@ static void register_openssl_symbols(int module_number) zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_x509_check_private_key", sizeof("openssl_x509_check_private_key") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_attribute *attribute_Deprecated_func_openssl_x509_free_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_x509_free", sizeof("openssl_x509_free") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_openssl_x509_free_0_arg0; - zend_string *attribute_Deprecated_func_openssl_x509_free_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_x509_free_0_arg0, attribute_Deprecated_func_openssl_x509_free_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_x509_free_0->args[0].value, &attribute_Deprecated_func_openssl_x509_free_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_openssl_x509_free_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_openssl_x509_free_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_openssl_x509_free_0_arg1; zend_string *attribute_Deprecated_func_openssl_x509_free_0_arg1_str = zend_string_init("as OpenSSLCertificate objects are freed automatically", strlen("as OpenSSLCertificate objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_x509_free_0_arg1, attribute_Deprecated_func_openssl_x509_free_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_x509_free_0->args[1].value, &attribute_Deprecated_func_openssl_x509_free_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_openssl_x509_free_0->args[1].value, attribute_Deprecated_func_openssl_x509_free_0_arg1_str); attribute_Deprecated_func_openssl_x509_free_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_pkcs12_export_to_file", sizeof("openssl_pkcs12_export_to_file") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); @@ -674,27 +748,16 @@ static void register_openssl_symbols(int module_number) zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_pkey_export", sizeof("openssl_pkey_export") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_attribute *attribute_Deprecated_func_openssl_pkey_free_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_pkey_free", sizeof("openssl_pkey_free") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_openssl_pkey_free_0_arg0; - zend_string *attribute_Deprecated_func_openssl_pkey_free_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_pkey_free_0_arg0, attribute_Deprecated_func_openssl_pkey_free_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_pkey_free_0->args[0].value, &attribute_Deprecated_func_openssl_pkey_free_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_openssl_pkey_free_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_openssl_pkey_free_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_openssl_pkey_free_0_arg1; zend_string *attribute_Deprecated_func_openssl_pkey_free_0_arg1_str = zend_string_init("as OpenSSLAsymmetricKey objects are freed automatically", strlen("as OpenSSLAsymmetricKey objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_pkey_free_0_arg1, attribute_Deprecated_func_openssl_pkey_free_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_pkey_free_0->args[1].value, &attribute_Deprecated_func_openssl_pkey_free_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_openssl_pkey_free_0->args[1].value, attribute_Deprecated_func_openssl_pkey_free_0_arg1_str); attribute_Deprecated_func_openssl_pkey_free_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_openssl_free_key_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_free_key", sizeof("openssl_free_key") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_openssl_free_key_0_arg0; - zend_string *attribute_Deprecated_func_openssl_free_key_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_free_key_0_arg0, attribute_Deprecated_func_openssl_free_key_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_free_key_0->args[0].value, &attribute_Deprecated_func_openssl_free_key_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_openssl_free_key_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_openssl_free_key_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_openssl_free_key_0_arg1; - zend_string *attribute_Deprecated_func_openssl_free_key_0_arg1_str = zend_string_init("as OpenSSLAsymmetricKey objects are freed automatically", strlen("as OpenSSLAsymmetricKey objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_openssl_free_key_0_arg1, attribute_Deprecated_func_openssl_free_key_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_openssl_free_key_0->args[1].value, &attribute_Deprecated_func_openssl_free_key_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_openssl_free_key_0->args[1].value, attribute_Deprecated_func_openssl_pkey_free_0_arg1_str); attribute_Deprecated_func_openssl_free_key_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "openssl_pkey_get_private", sizeof("openssl_pkey_get_private") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); @@ -758,6 +821,66 @@ static void register_openssl_symbols(int module_number) #endif } +static zend_class_entry *register_class_Openssl_OpensslException(zend_class_entry *class_entry_Openssl_Exception) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Openssl", "OpensslException", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Openssl_Exception, 0); + + return class_entry; +} + +static zend_class_entry *register_class_Openssl_Psk(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Openssl", "Psk", class_Openssl_Psk_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + zval const_MAX_PSK_LEN_value; + ZVAL_LONG(&const_MAX_PSK_LEN_value, PHP_OPENSSL_PSK_MAX_PSK_LEN); + zend_string *const_MAX_PSK_LEN_name = zend_string_init_interned("MAX_PSK_LEN", sizeof("MAX_PSK_LEN") - 1, true); + zend_declare_typed_class_constant(class_entry, const_MAX_PSK_LEN_name, &const_MAX_PSK_LEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_MAX_PSK_LEN_name, true); + + zval const_MAX_IDENTITY_LEN_value; + ZVAL_LONG(&const_MAX_IDENTITY_LEN_value, PHP_OPENSSL_PSK_MAX_IDENTITY_LEN); + zend_string *const_MAX_IDENTITY_LEN_name = zend_string_init_interned("MAX_IDENTITY_LEN", sizeof("MAX_IDENTITY_LEN") - 1, true); + zend_declare_typed_class_constant(class_entry, const_MAX_IDENTITY_LEN_name, &const_MAX_IDENTITY_LEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_MAX_IDENTITY_LEN_name, true); + + zval property_psk_default_value; + ZVAL_UNDEF(&property_psk_default_value); + zend_string *property_psk_name = zend_string_init("psk", sizeof("psk") - 1, true); + zend_declare_typed_property(class_entry, property_psk_name, &property_psk_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_psk_name, true); + + zval property_identity_default_value; + ZVAL_UNDEF(&property_identity_default_value); + zend_string *property_identity_name = zend_string_init("identity", sizeof("identity") - 1, true); + zend_declare_typed_property(class_entry, property_identity_name, &property_identity_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); + zend_string_release_ex(property_identity_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_Openssl_Session(void) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Openssl", "Session", class_Openssl_Session_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + zval property_id_default_value; + ZVAL_UNDEF(&property_id_default_value); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); + zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release_ex(property_id_name, true); + + return class_entry; +} + static zend_class_entry *register_class_OpenSSLCertificate(void) { zend_class_entry ce, *class_entry; diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 42b70c72a9cd..5aa8d246177e 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -110,7 +108,7 @@ void php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, void php_openssl_add_assoc_asn1_string(zval * val, char * key, ASN1_STRING * str) { - add_assoc_stringl(val, key, (char *)str->data, str->length); + add_assoc_stringl(val, key, (const char *)ASN1_STRING_get0_data(str), ASN1_STRING_length(str)); } time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr) @@ -142,12 +140,12 @@ time_t php_openssl_asn1_time_to_time_t(ASN1_UTCTIME * timestr) } if (timestr_len < 13) { - php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", timestr->data); + php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", ASN1_STRING_get0_data(timestr)); return (time_t)-1; } if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && timestr_len < 15) { - php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", timestr->data); + php_error_docref(NULL, E_WARNING, "Unable to parse time string %s correctly", ASN1_STRING_get0_data(timestr)); return (time_t)-1; } @@ -297,12 +295,12 @@ int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args SET_OPTIONAL_STRING_ARG("config", req->config_filename, default_ssl_conf_filename); SET_OPTIONAL_STRING_ARG("config_section_name", req->section_name, "req"); - req->global_config = NCONF_new(NULL); + req->global_config = php_openssl_nconf_new(); if (!NCONF_load(req->global_config, default_ssl_conf_filename, NULL)) { php_openssl_store_errors(); } - req->req_config = NCONF_new(NULL); + req->req_config = php_openssl_nconf_new(); if (!NCONF_load(req->req_config, req->config_filename, NULL)) { return FAILURE; } @@ -440,7 +438,7 @@ zend_result php_openssl_load_rand_file(const char * file, int *egdsocket, int *s return SUCCESS; #endif } - if (file == NULL || !RAND_load_file(file, -1)) { + if (file == NULL || RAND_load_file(file, -1) < 0) { if (RAND_status() == 0) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Unable to load random state; not enough random data!"); @@ -465,7 +463,7 @@ zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int se if (file == NULL) { file = RAND_file_name(buffer, sizeof(buffer)); } - if (file == NULL || !RAND_write_file(file)) { + if (file == NULL || RAND_write_file(file) < 0) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Unable to write random state"); return FAILURE; @@ -473,23 +471,8 @@ zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int se return SUCCESS; } -void php_openssl_backend_init(void) +void php_openssl_backend_init_common(void) { -#ifdef LIBRESSL_VERSION_NUMBER - OPENSSL_config(NULL); - SSL_library_init(); - OpenSSL_add_all_ciphers(); - OpenSSL_add_all_digests(); - OpenSSL_add_all_algorithms(); - SSL_load_error_strings(); -#else -#if PHP_OPENSSL_API_VERSION >= 0x30000 && defined(LOAD_OPENSSL_LEGACY_PROVIDER) - OSSL_PROVIDER_load(NULL, "legacy"); - OSSL_PROVIDER_load(NULL, "default"); -#endif - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); -#endif - /* Determine default SSL configuration file */ char *config_filename = getenv("OPENSSL_CONF"); if (config_filename == NULL) { @@ -519,10 +502,8 @@ void php_openssl_set_cert_locations(zval *return_value) add_assoc_string(return_value, "default_cert_dir_env", (char *) X509_get_default_cert_dir_env()); add_assoc_string(return_value, "default_private_dir", (char *) X509_get_default_private_dir()); add_assoc_string(return_value, "default_default_cert_area", (char *) X509_get_default_cert_area()); - add_assoc_string(return_value, "ini_cafile", - zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0)); - add_assoc_string(return_value, "ini_capath", - zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0)); + add_assoc_str(return_value, "ini_cafile", zend_string_copy(zend_ini_str_literal("openssl.cafile"))); + add_assoc_str(return_value, "ini_capath", zend_string_copy(zend_ini_str_literal("openssl.capath"))); } X509 *php_openssl_x509_from_str( @@ -541,18 +522,14 @@ X509 *php_openssl_x509_from_str( php_openssl_store_errors(); return NULL; } - cert = PEM_read_bio_X509(in, NULL, NULL, NULL); + cert = php_openssl_pem_read_bio_x509(in); } else { in = BIO_new_mem_buf(ZSTR_VAL(cert_str), (int) ZSTR_LEN(cert_str)); if (in == NULL) { php_openssl_store_errors(); return NULL; } -#ifdef TYPEDEF_D2I_OF - cert = (X509 *) PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); -#else - cert = (X509 *) PEM_ASN1_read_bio((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); -#endif + cert = php_openssl_pem_read_asn1_bio_x509(in); } if (!BIO_free(in)) { @@ -589,12 +566,12 @@ X509 *php_openssl_x509_from_zval( zval *val, bool *free_cert, uint32_t arg_num, bool is_from_array, const char *option_name) { if (php_openssl_is_certificate_ce(val)) { - *free_cert = 0; + *free_cert = false; return php_openssl_certificate_from_obj(Z_OBJ_P(val))->x509; } - *free_cert = 1; + *free_cert = true; zend_string *str = zval_try_get_string(val); if (str == NULL) { @@ -612,7 +589,7 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool r unsigned int n; zend_string *ret; - if (!(mdtype = EVP_get_digestbyname(method))) { + if (!(mdtype = php_openssl_get_evp_md_by_name(method))) { php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); return NULL; } else if (!X509_digest(peer, mdtype, md, &n)) { @@ -649,8 +626,8 @@ int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension) } extension_data = X509_EXTENSION_get_data(extension); - p = extension_data->data; - length = extension_data->length; + p = ASN1_STRING_get0_data(extension_data); + length = ASN1_STRING_length(extension_data); if (method->it) { names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, &p, length, ASN1_ITEM_ptr(method->it))); @@ -711,29 +688,25 @@ STACK_OF(X509) *php_openssl_load_all_certs_from_file( X509_INFO *xi; char cert_path[MAXPATHLEN]; - if(!(stack = sk_X509_new_null())) { - php_openssl_store_errors(); - php_error_docref(NULL, E_ERROR, "Memory allocation failure"); - goto end; - } - if (!php_openssl_check_path(cert_file, cert_file_len, cert_path, arg_num)) { - sk_X509_free(stack); goto end; } if (!(in = BIO_new_file(cert_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY)))) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error opening the file, %s", cert_path); - sk_X509_free(stack); goto end; } /* This loads from a file, a stack of x509/crl/pkey sets */ - if (!(sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL))) { + if (!(sk = php_openssl_pem_read_bio_x509_info(in))) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Error reading the file, %s", cert_path); - sk_X509_free(stack); + goto end; + } + + if(!(stack = sk_X509_new_reserve(NULL, sk_X509_INFO_num(sk)))) { + php_openssl_store_errors(); goto end; } @@ -771,6 +744,7 @@ int php_openssl_check_cert(X509_STORE *ctx, X509 *x, STACK_OF(X509) *untrustedch return 0; } if (!X509_STORE_CTX_init(csc, ctx, x, untrustedchain)) { + X509_STORE_CTX_free(csc); php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Certificate store initialization failed"); return 0; @@ -883,6 +857,9 @@ STACK_OF(X509) *php_openssl_array_to_X509_sk(zval * zcerts, uint32_t arg_num, co bool free_cert; sk = sk_X509_new_null(); + if (sk == NULL) { + goto clean_exit; + } /* get certs */ if (Z_TYPE_P(zcerts) == IS_ARRAY) { @@ -902,7 +879,10 @@ STACK_OF(X509) *php_openssl_array_to_X509_sk(zval * zcerts, uint32_t arg_num, co } } - sk_X509_push(sk, cert); + if (sk_X509_push(sk, cert) <= 0) { + X509_free(cert); + goto push_fail_exit; + } } ZEND_HASH_FOREACH_END(); } else { /* a single certificate */ @@ -920,11 +900,20 @@ STACK_OF(X509) *php_openssl_array_to_X509_sk(zval * zcerts, uint32_t arg_num, co goto clean_exit; } } - sk_X509_push(sk, cert); + if (sk_X509_push(sk, cert) <= 0) { + X509_free(cert); + goto push_fail_exit; + } } clean_exit: return sk; + +push_fail_exit: + php_openssl_store_errors(); + php_openssl_sk_X509_free(sk); + sk = NULL; + goto clean_exit; } zend_result php_openssl_csr_add_subj_entry(zval *item, X509_NAME *subj, int nid) @@ -1097,13 +1086,15 @@ zend_result php_openssl_csr_make(struct php_x509_request * req, X509_REQ * csr, } } } + + if (!X509_REQ_set_pubkey(csr, req->priv_key)) { + php_openssl_store_errors(); + } } else { php_openssl_store_errors(); + return FAILURE; } - if (!X509_REQ_set_pubkey(csr, req->priv_key)) { - php_openssl_store_errors(); - } return SUCCESS; } @@ -1127,7 +1118,7 @@ X509_REQ *php_openssl_csr_from_str(zend_string *csr_str, uint32_t arg_num) return NULL; } - csr = PEM_read_bio_X509_REQ(in, NULL,NULL,NULL); + csr = php_openssl_pem_read_bio_x509_req(in); if (csr == NULL) { php_openssl_store_errors(); } @@ -1158,7 +1149,7 @@ EVP_PKEY *php_openssl_extract_public_key(EVP_PKEY *priv_key) return NULL; } - EVP_PKEY *pub_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + EVP_PKEY *pub_key = php_openssl_pem_read_bio_public_key(bio); BIO_free(bio); return pub_key; } @@ -1275,7 +1266,7 @@ EVP_PKEY *php_openssl_pkey_from_zval( cert = php_openssl_x509_from_str(val_str, arg_num, false, NULL); if (cert) { - free_cert = 1; + free_cert = true; } else { /* not a X509 certificate, try to retrieve public key */ php_openssl_errors_restore_mark(); @@ -1290,7 +1281,7 @@ EVP_PKEY *php_openssl_pkey_from_zval( zend_string_release_ex(val_str, false); TMP_CLEAN; } - key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL); + key = php_openssl_pem_read_bio_public_key(in); BIO_free(in); } } else { @@ -1308,12 +1299,12 @@ EVP_PKEY *php_openssl_pkey_from_zval( TMP_CLEAN; } if (passphrase == NULL) { - key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); + key = php_openssl_pem_read_bio_private_key(in, NULL, NULL); } else { struct php_openssl_pem_password password; password.key = passphrase; password.len = passphrase_len; - key = PEM_read_bio_PrivateKey(in, NULL, php_openssl_pem_password_cb, &password); + key = php_openssl_pem_read_bio_private_key(in, php_openssl_pem_password_cb, &password); } BIO_free(in); } @@ -1344,13 +1335,20 @@ EVP_PKEY *php_openssl_pkey_from_zval( return key; } -zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t key_size) -{ - EVP_PKEY_CTX *ctx = php_openssl_pkey_new_from_pkey(key); +zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t requested_key_size) { + size_t key_size = requested_key_size; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(key, NULL); if (!ctx) { return NULL; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* OpenSSL 1.1 does not respect key_size for DH, so force size discovery so it can be compared later. */ + if (EVP_PKEY_base_id(key) == EVP_PKEY_DH && key_size != 0) { + key_size = 0; + } +#endif + if (EVP_PKEY_derive_init(ctx) <= 0 || EVP_PKEY_derive_set_peer(ctx, peer_key) <= 0 || (key_size == 0 && EVP_PKEY_derive(ctx, NULL, &key_size) <= 0)) { @@ -1359,6 +1357,14 @@ zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t k return NULL; } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* Now compare the computed size for DH to mirror OpenSSL 3.0+ behavior. */ + if (EVP_PKEY_base_id(key) == EVP_PKEY_DH && requested_key_size > 0 && requested_key_size < key_size) { + EVP_PKEY_CTX_free(ctx); + return NULL; + } +#endif + zend_string *result = zend_string_alloc(key_size, 0); if (EVP_PKEY_derive(ctx, (unsigned char *)ZSTR_VAL(result), &key_size) <= 0) { php_openssl_store_errors(); @@ -1437,7 +1443,10 @@ static const char *php_openssl_get_evp_pkey_name(int key_type) { EVP_PKEY *php_openssl_generate_private_key(struct php_x509_request * req) { - if (req->priv_key_bits < MIN_KEY_LENGTH) { + if ((req->priv_key_type == OPENSSL_KEYTYPE_RSA || + req->priv_key_type == OPENSSL_KEYTYPE_DH || + req->priv_key_type == OPENSSL_KEYTYPE_DSA) && + req->priv_key_bits < MIN_KEY_LENGTH) { php_error_docref(NULL, E_WARNING, "Private key length must be at least %d bits, configured to %d", MIN_KEY_LENGTH, req->priv_key_bits); return NULL; @@ -1509,7 +1518,7 @@ EVP_PKEY *php_openssl_generate_private_key(struct php_x509_request * req) case EVP_PKEY_ED448: break; #endif - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (EVP_PKEY_paramgen(ctx, ¶ms) <= 0) { @@ -1641,10 +1650,14 @@ void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EV { int cipher_mode = EVP_CIPHER_mode(cipher_type); memset(mode, 0, sizeof(struct php_openssl_cipher_mode)); + switch (cipher_mode) { case EVP_CIPH_GCM_MODE: case EVP_CIPH_CCM_MODE: - /* We check for EVP_CIPH_OCB_MODE, because LibreSSL does not support it. */ + /* We check for EVP_CIPH_SIV_MODE and EVP_CIPH_SIV_MODE, because older OpenSSL and LibreSSL do not support them. */ +#ifdef EVP_CIPH_SIV_MODE + case EVP_CIPH_SIV_MODE: +#endif #ifdef EVP_CIPH_OCB_MODE case EVP_CIPH_OCB_MODE: /* For OCB mode, explicitly set the tag length even when decrypting, @@ -1654,6 +1667,9 @@ void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EV php_openssl_set_aead_flags(mode); mode->set_tag_length_when_encrypting = cipher_mode == EVP_CIPH_CCM_MODE; mode->is_single_run_aead = cipher_mode == EVP_CIPH_CCM_MODE; +#ifdef EVP_CIPH_SIV_MODE + mode->aad_supports_vector = cipher_mode == EVP_CIPH_SIV_MODE; +#endif break; #ifdef NID_chacha20_poly1305 default: @@ -1671,7 +1687,7 @@ zend_result php_openssl_validate_iv(const char **piv, size_t *piv_len, size_t iv char *iv_new; if (mode->is_aead) { - if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_ivlen_flag, *piv_len, NULL) != 1) { + if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_ivlen_flag, *piv_len, NULL) <= 0) { php_error_docref(NULL, E_WARNING, "Setting of IV length for AEAD mode failed"); return FAILURE; } @@ -1689,7 +1705,7 @@ zend_result php_openssl_validate_iv(const char **piv, size_t *piv_len, size_t iv /* BC behavior */ *piv_len = iv_required_len; *piv = iv_new; - *free_iv = 1; + *free_iv = true; return SUCCESS; } @@ -1701,7 +1717,7 @@ zend_result php_openssl_validate_iv(const char **piv, size_t *piv_len, size_t iv memcpy(iv_new, *piv, *piv_len); *piv_len = iv_required_len; *piv = iv_new; - *free_iv = 1; + *free_iv = true; return SUCCESS; } @@ -1711,7 +1727,7 @@ zend_result php_openssl_validate_iv(const char **piv, size_t *piv_len, size_t iv memcpy(iv_new, *piv, iv_required_len); *piv_len = iv_required_len; *piv = iv_new; - *free_iv = 1; + *free_iv = true; return SUCCESS; } @@ -1726,7 +1742,7 @@ zend_result php_openssl_cipher_init(const EVP_CIPHER *cipher_type, int key_len, password_len; size_t max_iv_len; - *free_password = 0; + *free_password = false; max_iv_len = EVP_CIPHER_iv_length(cipher_type); if (enc && *piv_len == 0 && max_iv_len > 0 && !mode->is_aead) { @@ -1742,7 +1758,7 @@ zend_result php_openssl_cipher_init(const EVP_CIPHER *cipher_type, return FAILURE; } if (mode->set_tag_length_always || (enc && mode->set_tag_length_when_encrypting)) { - if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL)) { + if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, NULL) <= 0) { php_error_docref(NULL, E_WARNING, "Setting tag length for AEAD cipher failed"); return FAILURE; } @@ -1750,7 +1766,7 @@ zend_result php_openssl_cipher_init(const EVP_CIPHER *cipher_type, if (!enc && tag && tag_len > 0) { if (!mode->is_aead) { php_error_docref(NULL, E_WARNING, "The tag cannot be used because the cipher algorithm does not support AEAD"); - } else if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, (unsigned char *) tag)) { + } else if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, (unsigned char *) tag) <= 0) { php_error_docref(NULL, E_WARNING, "Setting tag for AEAD cipher decryption failed"); return FAILURE; } @@ -1769,7 +1785,7 @@ zend_result php_openssl_cipher_init(const EVP_CIPHER *cipher_type, memcpy(key, *ppassword, password_len); *ppassword = (char *) key; *ppassword_len = key_len; - *free_password = 1; + *free_password = true; } else { if (password_len > key_len && !EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len)) { php_openssl_store_errors(); @@ -1795,13 +1811,21 @@ zend_result php_openssl_cipher_update(const EVP_CIPHER *cipher_type, { int i = 0; + /* For AEAD modes that do not support vector AAD, treat NULL AAD as zero-length AAD */ + if (!mode->aad_supports_vector && aad == NULL) { + aad_len = 0; + aad = ""; + } + if (mode->is_single_run_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, NULL, (int)data_len)) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Setting of data length failed"); return FAILURE; } - if (mode->is_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, (const unsigned char *) aad, (int) aad_len)) { + /* Only pass AAD to OpenSSL if caller provided it. + This makes NULL mean zero AAD items, while "" with len 0 means one empty AAD item. */ + if (mode->is_aead && aad != NULL && !EVP_CipherUpdate(cipher_ctx, NULL, &i, (const unsigned char *)aad, (int)aad_len)) { php_openssl_store_errors(); php_error_docref(NULL, E_WARNING, "Setting of additional application data failed"); return FAILURE; @@ -1841,7 +1865,7 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt( EVP_CIPHER_CTX *cipher_ctx; struct php_openssl_cipher_mode mode; int i = 0, outlen; - bool free_iv = 0, free_password = 0; + bool free_iv = false, free_password = false; zend_string *outbuf = NULL; PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(data_len, data); @@ -1886,7 +1910,7 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt( if (mode.is_aead && tag) { zend_string *tag_str = zend_string_alloc(tag_len, 0); - if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode.aead_get_tag_flag, tag_len, ZSTR_VAL(tag_str)) == 1) { + if (EVP_CIPHER_CTX_ctrl(cipher_ctx, mode.aead_get_tag_flag, tag_len, ZSTR_VAL(tag_str)) > 0) { ZSTR_VAL(tag_str)[tag_len] = '\0'; ZSTR_LEN(tag_str) = tag_len; ZEND_TRY_ASSIGN_REF_NEW_STR(tag, tag_str); @@ -1935,7 +1959,7 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt( struct php_openssl_cipher_mode mode; int i = 0, outlen; zend_string *base64_str = NULL; - bool free_iv = 0, free_password = 0; + bool free_iv = false, free_password = false; zend_string *outbuf = NULL; PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(data_len, data); diff --git a/ext/openssl/openssl_backend_v1.c b/ext/openssl/openssl_backend_v1.c index 8b9ede38437d..0c1ac6b955f6 100644 --- a/ext/openssl/openssl_backend_v1.c +++ b/ext/openssl/openssl_backend_v1.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -27,6 +25,22 @@ #include #endif +void php_openssl_backend_init(void) +{ +#ifdef LIBRESSL_VERSION_NUMBER + OPENSSL_config(NULL); + SSL_library_init(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); + OpenSSL_add_all_algorithms(); + SSL_load_error_strings(); +#else + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + + php_openssl_backend_init_common(); +} + void php_openssl_backend_shutdown(void) { #ifdef LIBRESSL_VERSION_NUMBER @@ -44,6 +58,16 @@ void php_openssl_backend_shutdown(void) #endif } +void php_openssl_backend_init_libctx(struct php_openssl_libctx *ctx) +{ + // Do nothing as there is no libctx +} + +void php_openssl_backend_destroy_libctx(struct php_openssl_libctx *ctx) +{ + // Do nothing as there is no libctx +} + EVP_PKEY_CTX *php_openssl_pkey_new_from_name(const char *name, int id) { return EVP_PKEY_CTX_new_id(id, NULL); @@ -62,23 +86,23 @@ static bool php_openssl_pkey_init_rsa_data(RSA *rsa, zval *data) OPENSSL_PKEY_SET_BN(data, e); OPENSSL_PKEY_SET_BN(data, d); if (!n || !d || !RSA_set0_key(rsa, n, e, d)) { - return 0; + return false; } OPENSSL_PKEY_SET_BN(data, p); OPENSSL_PKEY_SET_BN(data, q); if ((p || q) && !RSA_set0_factors(rsa, p, q)) { - return 0; + return false; } OPENSSL_PKEY_SET_BN(data, dmp1); OPENSSL_PKEY_SET_BN(data, dmq1); OPENSSL_PKEY_SET_BN(data, iqmp); if ((dmp1 || dmq1 || iqmp) && !RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) { - return 0; + return false; } - return 1; + return true; } EVP_PKEY *php_openssl_pkey_init_rsa(zval *data) @@ -114,8 +138,15 @@ static bool php_openssl_pkey_init_dsa_data(DSA *dsa, zval *data, bool *is_privat OPENSSL_PKEY_SET_BN(data, p); OPENSSL_PKEY_SET_BN(data, q); OPENSSL_PKEY_SET_BN(data, g); - if (!p || !q || !g || !DSA_set0_pqg(dsa, p, q, g)) { - return 0; + if (!p || !q || !g) { + BN_free(p); + BN_free(q); + BN_free(g); + return false; + } + + if (!DSA_set0_pqg(dsa, p, q, g)) { + return false; } OPENSSL_PKEY_SET_BN(data, pub_key); @@ -128,18 +159,18 @@ static bool php_openssl_pkey_init_dsa_data(DSA *dsa, zval *data, bool *is_privat /* generate key */ if (!DSA_generate_key(dsa)) { php_openssl_store_errors(); - return 0; + return false; } /* if BN_mod_exp return -1, then DSA_generate_key succeed for failed key * so we need to double check that public key is created */ DSA_get0_key(dsa, &pub_key_const, &priv_key_const); if (!pub_key_const || BN_is_zero(pub_key_const)) { - return 0; + return false; } /* all good */ *is_private = true; - return 1; + return true; } EVP_PKEY *php_openssl_pkey_init_dsa(zval *data, bool *is_private) @@ -175,8 +206,13 @@ static bool php_openssl_pkey_init_dh_data(DH *dh, zval *data, bool *is_private) OPENSSL_PKEY_SET_BN(data, p); OPENSSL_PKEY_SET_BN(data, q); OPENSSL_PKEY_SET_BN(data, g); - if (!p || !g || !DH_set0_pqg(dh, p, q, g)) { - return 0; + if (!p || !q) { + BN_free(p); + return false; + } + + if (!DH_set0_pqg(dh, p, q, g)) { + return false; } OPENSSL_PKEY_SET_BN(data, priv_key); @@ -188,7 +224,11 @@ static bool php_openssl_pkey_init_dh_data(DH *dh, zval *data, bool *is_private) if (priv_key) { pub_key = php_openssl_dh_pub_from_priv(priv_key, g, p); if (pub_key == NULL) { - return 0; + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(priv_key); + return false; } return DH_set0_key(dh, pub_key, priv_key); } @@ -196,11 +236,11 @@ static bool php_openssl_pkey_init_dh_data(DH *dh, zval *data, bool *is_private) /* generate key */ if (!DH_generate_key(dh)) { php_openssl_store_errors(); - return 0; + return false; } /* all good */ *is_private = true; - return 1; + return true; } EVP_PKEY *php_openssl_pkey_init_dh(zval *data, bool *is_private) @@ -235,6 +275,9 @@ static bool php_openssl_pkey_init_ec_data(EC_KEY *eckey, zval *data, bool *is_pr EC_POINT *point_q = NULL; EC_GROUP *group = NULL; BN_CTX *bctx = BN_CTX_new(); + if (!bctx) { + goto clean_exit; + } *is_private = false; @@ -606,7 +649,6 @@ const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo) #endif default: return NULL; - break; } return mdtype; } @@ -627,40 +669,31 @@ const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo) #ifndef OPENSSL_NO_RC2 case PHP_OPENSSL_CIPHER_RC2_40: return EVP_rc2_40_cbc(); - break; case PHP_OPENSSL_CIPHER_RC2_64: return EVP_rc2_64_cbc(); - break; case PHP_OPENSSL_CIPHER_RC2_128: return EVP_rc2_cbc(); - break; #endif #ifndef OPENSSL_NO_DES case PHP_OPENSSL_CIPHER_DES: return EVP_des_cbc(); - break; case PHP_OPENSSL_CIPHER_3DES: return EVP_des_ede3_cbc(); - break; #endif #ifndef OPENSSL_NO_AES case PHP_OPENSSL_CIPHER_AES_128_CBC: return EVP_aes_128_cbc(); - break; case PHP_OPENSSL_CIPHER_AES_192_CBC: return EVP_aes_192_cbc(); - break; case PHP_OPENSSL_CIPHER_AES_256_CBC: return EVP_aes_256_cbc(); - break; #endif default: return NULL; - break; } } @@ -677,4 +710,59 @@ void php_openssl_get_cipher_methods(zval *return_value, bool aliases) return_value); } +CONF *php_openssl_nconf_new(void) +{ + return NCONF_new(NULL); +} + +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); +} + +X509 *php_openssl_pem_read_bio_x509(BIO *in) +{ + return PEM_read_bio_X509(in, NULL, NULL, NULL); +} + +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in) +{ + return PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); +} + +STACK_OF(X509_INFO) *php_openssl_pem_read_bio_x509_info(BIO *in) +{ + return PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); +} + +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in) +{ + return PEM_read_bio_PUBKEY(in, NULL, NULL, NULL); +} + +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u) +{ + return PEM_read_bio_PrivateKey(in, NULL, cb, u); +} + +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in) +{ + return PEM_read_bio_PKCS7(in, NULL, NULL, NULL); +} + +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in) +{ + return PEM_read_bio_CMS(in, NULL, NULL, NULL); +} + +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in) +{ + return d2i_CMS_bio(in, NULL); +} + +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont) +{ + return SMIME_read_CMS(bio, bcont); +} + #endif diff --git a/ext/openssl/openssl_backend_v3.c b/ext/openssl/openssl_backend_v3.c index e3c80cf659ba..339ff53f7b62 100644 --- a/ext/openssl/openssl_backend_v3.c +++ b/ext/openssl/openssl_backend_v3.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -24,37 +22,64 @@ ZEND_EXTERN_MODULE_GLOBALS(openssl) +void php_openssl_backend_init(void) +{ +#if PHP_OPENSSL_API_VERSION >= 0x30000 && defined(LOAD_OPENSSL_LEGACY_PROVIDER) + OSSL_PROVIDER_load(NULL, "legacy"); + OSSL_PROVIDER_load(NULL, "default"); +#endif + + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); + + php_openssl_backend_init_common(); +} + void php_openssl_backend_shutdown(void) { (void) 0; } -void php_openssl_backend_init_libctx(OSSL_LIB_CTX **plibctx, char **ppropq) +#define PHP_OPENSSL_DEFAULT_CONF_MFLAGS \ + (CONF_MFLAGS_DEFAULT_SECTION | CONF_MFLAGS_IGNORE_MISSING_FILE | CONF_MFLAGS_IGNORE_RETURN_CODES) + +void php_openssl_backend_init_libctx(struct php_openssl_libctx *ctx) { - /* The return value is not checked because we cannot reasonable fail in GINIT so using NULL - * (default context) is probably better. */ - *plibctx = OSSL_LIB_CTX_new(); - *ppropq = NULL; + ctx->default_libctx = OSSL_LIB_CTX_get0_global_default(); + ctx->custom_libctx = OSSL_LIB_CTX_new(); + if (ctx->custom_libctx != NULL) { + /* This is not being checked because there is not much that can be done. */ + CONF_modules_load_file_ex(ctx->custom_libctx, NULL, NULL, + PHP_OPENSSL_DEFAULT_CONF_MFLAGS); +#ifdef LOAD_OPENSSL_LEGACY_PROVIDER + OSSL_PROVIDER_load(ctx->custom_libctx, "legacy"); + OSSL_PROVIDER_load(ctx->custom_libctx, "default"); +#endif + ctx->libctx = ctx->custom_libctx; + } else { + /* If creation fails, just fallback to default */ + ctx->libctx = ctx->default_libctx; + } + ctx->propq = NULL; } -void php_openssl_backend_destroy_libctx(OSSL_LIB_CTX *libctx, char *propq) +void php_openssl_backend_destroy_libctx(struct php_openssl_libctx *ctx) { - if (libctx != NULL) { - OSSL_LIB_CTX_free(libctx); + if (ctx->custom_libctx != NULL) { + OSSL_LIB_CTX_free(ctx->custom_libctx); } - if (propq != NULL) { - free(propq); + if (ctx->propq != NULL) { + free(ctx->propq); } } EVP_PKEY_CTX *php_openssl_pkey_new_from_name(const char *name, int id) { - return EVP_PKEY_CTX_new_from_name(OPENSSL_G(libctx), name, OPENSSL_G(propq)); + return EVP_PKEY_CTX_new_from_name(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ); } EVP_PKEY_CTX *php_openssl_pkey_new_from_pkey(EVP_PKEY *pkey) { - return EVP_PKEY_CTX_new_from_pkey(OPENSSL_G(libctx), pkey, OPENSSL_G(propq)); + return EVP_PKEY_CTX_new_from_pkey(PHP_OPENSSL_LIBCTX, pkey, PHP_OPENSSL_PROPQ); } EVP_PKEY *php_openssl_pkey_init_rsa(zval *data) @@ -299,7 +324,7 @@ EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) { goto cleanup; } - if (!(group = EC_GROUP_new_by_curve_name_ex(OPENSSL_G(libctx), OPENSSL_G(propq), nid))) { + if (!(group = EC_GROUP_new_by_curve_name_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ, nid))) { goto cleanup; } @@ -427,6 +452,9 @@ EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) { } EVP_PKEY_CTX_free(ctx); ctx = EVP_PKEY_CTX_new(param_key, NULL); + if (!ctx) { + goto cleanup; + } } if (EVP_PKEY_check(ctx) || EVP_PKEY_public_check_quick(ctx)) { @@ -540,10 +568,7 @@ static zend_string *php_openssl_get_utf8_param( char buf[64]; size_t len; if (EVP_PKEY_get_utf8_string_param(pkey, param, buf, sizeof(buf), &len) > 0) { - zend_string *str = zend_string_alloc(len, 0); - memcpy(ZSTR_VAL(str), buf, len); - ZSTR_VAL(str)[len] = '\0'; - return str; + return zend_string_init(buf, len, 0); } return NULL; } @@ -698,7 +723,13 @@ zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey, char *pub_str, size_t pu const EVP_MD *php_openssl_get_evp_md_by_name(const char *name) { - return EVP_MD_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq)); + const EVP_MD *dp = (const EVP_MD *) OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); + + if (dp != NULL) { + return dp; + } + + return EVP_MD_fetch(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ); } static const char *php_openssl_digest_names[] = { @@ -754,7 +785,13 @@ static const char *php_openssl_cipher_names[] = { const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name) { - return EVP_CIPHER_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq)); + const EVP_CIPHER *cp = (const EVP_CIPHER *) OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); + + if (cp != NULL) { + return cp; + } + + return EVP_CIPHER_fetch(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ); } const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo) @@ -805,10 +842,142 @@ static int php_openssl_compare_func(Bucket *a, Bucket *b) void php_openssl_get_cipher_methods(zval *return_value, bool aliases) { array_init(return_value); - EVP_CIPHER_do_all_provided(OPENSSL_G(libctx), + EVP_CIPHER_do_all_provided(PHP_OPENSSL_LIBCTX, aliases ? php_openssl_add_cipher_or_alias : php_openssl_add_cipher, return_value); zend_hash_sort(Z_ARRVAL_P(return_value), php_openssl_compare_func, 1); } +CONF *php_openssl_nconf_new(void) +{ + return NCONF_new_ex(PHP_OPENSSL_LIBCTX, NULL); +} + +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in) +{ + X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (x == NULL) { + return NULL; + } + + if (PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, (void **) &x, NULL, NULL) == NULL) { + X509_free(x); + return NULL; + } + + return x; +} + +X509 *php_openssl_pem_read_bio_x509(BIO *in) +{ + X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (x == NULL) { + return NULL; + } + + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { + X509_free(x); + return NULL; + } + + return x; +} + +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in) +{ + X509_REQ *xr = X509_REQ_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (xr == NULL) { + return NULL; + } + + if (PEM_read_bio_X509_REQ(in, &xr, NULL, NULL) == NULL) { + X509_REQ_free(xr); + return NULL; + } + + return xr; +} + +STACK_OF(X509_INFO) *php_openssl_pem_read_bio_x509_info(BIO *in) +{ + return PEM_X509_INFO_read_bio_ex(in, NULL, NULL, NULL, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); +} + +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in) +{ + return PEM_read_bio_PUBKEY_ex(in, NULL, NULL, NULL, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); +} + +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u) +{ + return PEM_read_bio_PrivateKey_ex(in, NULL, cb, u, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); +} + +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in) +{ + PKCS7 *p = PKCS7_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (p == NULL) { + return NULL; + } + + if (PEM_read_bio_PKCS7(in, &p, NULL, NULL) == NULL) { + PKCS7_free(p); + return NULL; + } + + return p; +} + +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (PEM_read_bio_CMS(in, &ci, NULL, NULL) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (d2i_CMS_bio(in, &ci) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (SMIME_read_CMS_ex(bio, 0, bcont, &ci) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + #endif diff --git a/ext/openssl/openssl_pwhash.c b/ext/openssl/openssl_pwhash.c index 5fe5bb5cf1bb..0b439a731d1c 100644 --- a/ext/openssl/openssl_pwhash.c +++ b/ext/openssl/openssl_pwhash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Remi Collet | +----------------------------------------------------------------------+ @@ -22,7 +20,7 @@ #include "ext/standard/php_password.h" #include "php_openssl.h" -#if defined(HAVE_OPENSSL_ARGON2) +#ifdef HAVE_OPENSSL_ARGON2 #include "Zend/zend_attributes.h" #include "openssl_pwhash_arginfo.h" #include @@ -46,9 +44,12 @@ #define PHP_OPENSSL_HASH_SIZE 32 #define PHP_OPENSSL_DIGEST_SIZE 128 +ZEND_EXTERN_MODULE_GLOBALS(openssl) + static inline zend_result get_options(zend_array *options, uint32_t *memlimit, uint32_t *iterlimit, uint32_t *threads) { zval *opt; + zend_long sthreads; *iterlimit = PHP_OPENSSL_PWHASH_ITERLIMIT; *memlimit = PHP_OPENSSL_PWHASH_MEMLIMIT; @@ -74,8 +75,7 @@ static inline zend_result get_options(zend_array *options, uint32_t *memlimit, u } *iterlimit = siterlimit; } - if ((opt = zend_hash_str_find(options, "threads", strlen("threads"))) && (zval_get_long(opt) != 1)) { - zend_long sthreads = zval_get_long(opt); + if ((opt = zend_hash_str_find(options, "threads", strlen("threads"))) && ((sthreads = zval_get_long(opt)) != 1)) { if ((sthreads < PHP_OPENSSL_THREADS_MIN) || (sthreads > PHP_OPENSSL_THREADS_MAX)) { zend_value_error("Invalid number of threads"); return FAILURE; @@ -98,8 +98,8 @@ static bool php_openssl_argon2_compute_hash( uint32_t oldthreads; bool ret = false; - oldthreads = OSSL_get_max_threads(NULL); - if (OSSL_set_max_threads(NULL, threads) != 1) { + oldthreads = OSSL_get_max_threads(PHP_OPENSSL_LIBCTX); + if (OSSL_set_max_threads(PHP_OPENSSL_LIBCTX, threads) != 1) { goto fail; } p = params; @@ -111,7 +111,7 @@ static bool php_openssl_argon2_compute_hash( *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, (void *)pass, pass_len); *p++ = OSSL_PARAM_construct_end(); - if ((kdf = EVP_KDF_fetch(NULL, algo, NULL)) == NULL) { + if ((kdf = EVP_KDF_fetch(PHP_OPENSSL_LIBCTX, algo, PHP_OPENSSL_PROPQ)) == NULL) { goto fail; } if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) { @@ -127,7 +127,7 @@ static bool php_openssl_argon2_compute_hash( fail: EVP_KDF_free(kdf); EVP_KDF_CTX_free(kctx); - OSSL_set_max_threads(NULL, oldthreads); + OSSL_set_max_threads(PHP_OPENSSL_LIBCTX, oldthreads); return ret; } @@ -385,4 +385,5 @@ PHP_MINIT_FUNCTION(openssl_pwhash) return SUCCESS; } + #endif /* HAVE_OPENSSL_ARGON2 */ diff --git a/ext/openssl/openssl_pwhash.stub.php b/ext/openssl/openssl_pwhash.stub.php index c6e3a363c522..49e2663557dc 100644 --- a/ext/openssl/openssl_pwhash.stub.php +++ b/ext/openssl/openssl_pwhash.stub.php @@ -3,13 +3,7 @@ /** @generate-class-entries */ #if defined(HAVE_OPENSSL_ARGON2) -/** - * @var string - */ const PASSWORD_ARGON2I = "argon2i"; -/** - * @var string - */ const PASSWORD_ARGON2ID = "argon2id"; /** * @var int @@ -26,9 +20,6 @@ * @cvalue PHP_OPENSSL_PWHASH_THREADS */ const PASSWORD_ARGON2_DEFAULT_THREADS = UNKNOWN; -/** - * @var string - */ const PASSWORD_ARGON2_PROVIDER = "openssl"; #endif diff --git a/ext/openssl/openssl_pwhash_arginfo.h b/ext/openssl/openssl_pwhash_arginfo.h index b4213158a169..2e78aec41afb 100644 --- a/ext/openssl/openssl_pwhash_arginfo.h +++ b/ext/openssl/openssl_pwhash_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: b6056170a5c8f1a9582c5eef9261a0bd02f7a7e1 */ +/* This is a generated file, edit openssl_pwhash.stub.php instead. + * Stub hash: 23ee957ba4945be3a21db58051e548729c3ff44e */ static void register_openssl_pwhash_symbols(int module_number) { diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h index 67522f3d3471..8b597e6ec8f9 100644 --- a/ext/openssl/php_openssl.h +++ b/ext/openssl/php_openssl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Venaas | | Wez Furlong = 0x30000 OSSL_LIB_CTX *libctx; - char *propq; + OSSL_LIB_CTX *default_libctx; + OSSL_LIB_CTX *custom_libctx; #endif + char *propq; +}; + +ZEND_BEGIN_MODULE_GLOBALS(openssl) + struct php_openssl_errors *errors; + struct php_openssl_errors *errors_mark; + struct php_openssl_libctx ctx; ZEND_END_MODULE_GLOBALS(openssl) +#define PHP_OPENSSL_LIBCTX OPENSSL_G(ctx).libctx +#define PHP_OPENSSL_PROPQ OPENSSL_G(ctx).propq + #define OPENSSL_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(openssl, v) #if defined(ZTS) && defined(COMPILE_DL_OPENSSL) @@ -153,7 +164,7 @@ typedef struct _php_openssl_certificate_object { extern zend_class_entry *php_openssl_certificate_ce; static inline php_openssl_certificate_object *php_openssl_certificate_from_obj(zend_object *obj) { - return (php_openssl_certificate_object *)((char *)(obj) - XtOffsetOf(php_openssl_certificate_object, std)); + return ZEND_CONTAINER_OF(obj, php_openssl_certificate_object, std); } #define Z_OPENSSL_CERTIFICATE_P(zv) php_openssl_certificate_from_obj(Z_OBJ_P(zv)) @@ -168,7 +179,7 @@ typedef struct _php_openssl_x509_request_object { } php_openssl_request_object; static inline php_openssl_request_object *php_openssl_request_from_obj(zend_object *obj) { - return (php_openssl_request_object *)((char *)(obj) - XtOffsetOf(php_openssl_request_object, std)); + return ZEND_CONTAINER_OF(obj, php_openssl_request_object, std); } #define Z_OPENSSL_REQUEST_P(zv) php_openssl_request_from_obj(Z_OBJ_P(zv)) @@ -184,7 +195,7 @@ typedef struct _php_openssl_pkey_object { } php_openssl_pkey_object; static inline php_openssl_pkey_object *php_openssl_pkey_from_obj(zend_object *obj) { - return (php_openssl_pkey_object *)((char *)(obj) - XtOffsetOf(php_openssl_pkey_object, std)); + return ZEND_CONTAINER_OF(obj, php_openssl_pkey_object, std); } #define Z_OPENSSL_PKEY_P(zv) php_openssl_pkey_from_obj(Z_OBJ_P(zv)) @@ -192,6 +203,40 @@ static inline php_openssl_pkey_object *php_openssl_pkey_from_obj(zend_object *ob bool php_openssl_is_pkey_ce(zval *val); void php_openssl_pkey_object_init(zval *zv, EVP_PKEY *pkey, bool is_private); +/* Openssl\Psk class */ + +/* Matches OpenSSL's PSK_MAX_PSK_LEN and PSK_MAX_IDENTITY_LEN */ +#define PHP_OPENSSL_PSK_MAX_PSK_LEN 256 +#define PHP_OPENSSL_PSK_MAX_IDENTITY_LEN 128 + +extern zend_class_entry *php_openssl_psk_ce; + +bool php_openssl_is_psk_ce(zval *val); +zend_string *php_openssl_psk_get_psk(zval *psk_zv); +zend_string *php_openssl_psk_get_identity(zval *psk_zv); + +/* Openssl\Session class */ + +#include + +typedef struct _php_openssl_session_object { + SSL_SESSION *session; + zend_object std; +} php_openssl_session_object; + +static inline php_openssl_session_object *php_openssl_session_from_obj(zend_object *obj) { + return (php_openssl_session_object *)((char *)(obj) - offsetof(php_openssl_session_object, std)); +} + +#define Z_OPENSSL_SESSION_P(zv) php_openssl_session_from_obj(Z_OBJ_P(zv)) + +/* Extern declarations for xp_ssl.c */ +extern zend_class_entry *php_openssl_session_ce; + +void php_openssl_session_object_init(zval *zv, SSL_SESSION *session); +bool php_openssl_is_session_ce(zval *val); +SSL_SESSION *php_openssl_session_from_zval(zval *zv); + #if defined(HAVE_OPENSSL_ARGON2) /** diff --git a/ext/openssl/php_openssl_backend.h b/ext/openssl/php_openssl_backend.h index 69317e3c7833..2d37e594ea57 100644 --- a/ext/openssl/php_openssl_backend.h +++ b/ext/openssl/php_openssl_backend.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jakub Zelenka | +----------------------------------------------------------------------+ @@ -190,7 +188,18 @@ X509_STORE * php_openssl_setup_verify(zval * calist, uint32_t arg_num); STACK_OF(X509) * php_openssl_load_all_certs_from_file( char *cert_file, size_t cert_file_len, uint32_t arg_num); EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req); -zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t key_size); +zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t requested_key_size); + +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in); +X509 *php_openssl_pem_read_bio_x509(BIO *in); +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in); +STACK_OF(X509_INFO) *php_openssl_pem_read_bio_x509_info(BIO *in); +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in); +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u); +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in); +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in); +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in); +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont); #define PHP_SSL_REQ_INIT(req) memset(req, 0, sizeof(*req)) #define PHP_SSL_REQ_DISPOSE(req) php_openssl_dispose_config(req) @@ -237,10 +246,8 @@ void php_openssl_backend_init_common(void); void php_openssl_backend_gshutdown(void); void php_openssl_backend_shutdown(void); -#if PHP_OPENSSL_API_VERSION >= 0x30000 -void php_openssl_backend_init_libctx(OSSL_LIB_CTX **plibctx, char **ppropq); -void php_openssl_backend_destroy_libctx(OSSL_LIB_CTX *libctx, char *propq); -#endif +void php_openssl_backend_init_libctx(struct php_openssl_libctx *ctx); +void php_openssl_backend_destroy_libctx(struct php_openssl_libctx *ctx); const char *php_openssl_get_conf_filename(void); @@ -339,6 +346,7 @@ struct php_openssl_cipher_mode { bool is_single_run_aead; bool set_tag_length_always; bool set_tag_length_when_encrypting; + bool aad_supports_vector; int aead_get_tag_flag; int aead_set_tag_flag; int aead_ivlen_flag; @@ -368,4 +376,6 @@ zend_result php_openssl_cipher_update(const EVP_CIPHER *cipher_type, const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method); +CONF *php_openssl_nconf_new(void); + #endif diff --git a/ext/openssl/tests/ServerClientTestCase.inc b/ext/openssl/tests/ServerClientTestCase.inc index 8eedbfdebee8..f0336fdd3921 100644 --- a/ext/openssl/tests/ServerClientTestCase.inc +++ b/ext/openssl/tests/ServerClientTestCase.inc @@ -179,6 +179,9 @@ class ServerClientTestCase if (empty($addr)) { throw new \Exception("Failed server start"); } + if (strpos($addr, 'SERVER_EXCEPTION') !== false) { + echo $addr; + } if ($code === false) { $clientCode = preg_replace('/{{\s*ADDR\s*}}/', $addr, $clientCode); } else { diff --git a/ext/openssl/tests/bug74796.phpt b/ext/openssl/tests/bug74796.phpt index b3f594d5e60f..8ec5590c064f 100644 --- a/ext/openssl/tests/bug74796.phpt +++ b/ext/openssl/tests/bug74796.phpt @@ -12,13 +12,24 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { --FILE-- saveCaCert($caFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $csFile); +$certificateGenerator->saveNewCertAsFileWithKey('uk.php.net', $ukFile); +$certificateGenerator->saveNewCertAsFileWithKey('us.php.net', $usFile); + $serverCode = <<<'CODE' $serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ - "cs.php.net" => __DIR__ . "/sni_server_cs.pem", - "uk.php.net" => __DIR__ . "/sni_server_uk.pem", - "us.php.net" => __DIR__ . "/sni_server_us.pem" + "cs.php.net" => '%s', + "uk.php.net" => '%s', + "us.php.net" => '%s', ] ]]); @@ -33,6 +44,7 @@ $serverCode = <<<'CODE' phpt_wait(); CODE; +$serverCode = sprintf($serverCode, $csFile, $ukFile, $usFile); $proxyCode = <<<'CODE' function parse_sni_from_client_hello($data) { @@ -134,7 +146,7 @@ CODE; $clientCode = <<<'CODE' $clientCtx = stream_context_create([ 'ssl' => [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', 'verify_peer' => true, 'verify_peer_name' => true, ], @@ -155,16 +167,21 @@ $clientCode = <<<'CODE' phpt_notify('server'); CODE; +$clientCode = sprintf($clientCode, $caFile); include 'ServerClientTestCase.inc'; ServerClientTestCase::getInstance()->run($clientCode, [ - 'server' => $serverCode, - 'proxy' => $proxyCode, + 'server' => $serverCode, + 'proxy' => $proxyCode, ]); ?> --CLEAN-- --EXPECT-- string(19) "Hello from server 0" diff --git a/ext/openssl/tests/bug80770.phpt b/ext/openssl/tests/bug80770.phpt new file mode 100644 index 000000000000..21860dc78eb7 --- /dev/null +++ b/ext/openssl/tests/bug80770.phpt @@ -0,0 +1,88 @@ +--TEST-- +Bug #80770: SNI_server_certs does not inherit peer verification options +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- +saveCaCert($caCertFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $csFile); +$certificateGenerator->saveNewCertAsFileWithKey('uk.php.net', $ukFile); +$certificateGenerator->saveNewCertAsFileWithKey('us.php.net', $usFile); +$certificateGenerator->saveNewCertAsFileWithKey('Bug80770 Test Client', $clientCertFile); + +$serverCode = <<<'CODE' + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $ctx = stream_context_create(['ssl' => [ + 'SNI_server_certs' => [ + "cs.php.net" => '%s', + "uk.php.net" => '%s', + "us.php.net" => '%s', + ], + 'verify_peer' => true, + 'cafile' => '%s', + 'capture_peer_cert' => true, + 'verify_peer_name' => false, + 'security_level' => 0, + ]]); + $server = stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + $client = stream_socket_accept($server, 30); + if ($client) { + $success = stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_SERVER); + if ($success) { + $options = stream_context_get_options($client); + $hasCert = isset($options['ssl']['peer_certificate']); + phpt_notify(message: $hasCert ? "CLIENT_CERT_CAPTURED" : "NO_CLIENT_CERT"); + } else { + phpt_notify(message: "TLS_HANDSHAKE_FAILED"); + } + } else { + phpt_notify(message: "ACCEPT_FAILED"); + } +CODE; +$serverCode = sprintf($serverCode, $csFile, $ukFile, $usFile, $caCertFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'local_cert' => '%s', + 'peer_name' => 'cs.php.net', + 'security_level' => 0, + ]]); + $client = stream_socket_client("tcp://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client) { + stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + } + $result = phpt_wait(); + echo trim($result); +CODE; +$clientCode = sprintf($clientCode, $clientCertFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +CLIENT_CERT_CAPTURED diff --git a/ext/openssl/tests/check_default_conf_path.phpt b/ext/openssl/tests/check_default_conf_path.phpt index 4590ef7804da..267bebe16c1f 100644 --- a/ext/openssl/tests/check_default_conf_path.phpt +++ b/ext/openssl/tests/check_default_conf_path.phpt @@ -21,7 +21,7 @@ ob_end_clean(); preg_match(",Openssl default config [^ ]* (.*),", $info, $m); if (isset($m[1])) { - var_dump(str_replace('/', '\\', strtolower($m[1]))); + var_dump(str_replace('\\/', '\\', strtolower($m[1]))); } else { echo $info; } diff --git a/ext/openssl/tests/cipher_tests.inc b/ext/openssl/tests/cipher_tests.inc index f543a42c9f45..9d17e847bfa2 100644 --- a/ext/openssl/tests/cipher_tests.inc +++ b/ext/openssl/tests/cipher_tests.inc @@ -160,6 +160,59 @@ $php_openssl_cipher_tests = array( 'ct' => '1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1A0124B0A55BAE884ED93481529C76B6A', ), ), + 'aes-128-siv' => array( + array( + 'key' => 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0' . + '0f0e0d0c0b0a09080706050403020100', + 'iv' => '', + 'aad' => '', + 'tag' => 'baba5b99dfc42fa9810fb2eb71ac2e9c', + 'pt' => 'b1677d933fa706f7ef349f9dd569c028' . + '279a5e2219728e77cfe916d5db979942' . + '5d8fb93b0e26dbc85ed14c050dc9f054' . + 'd9153c2be1e9b99ae7a109aba1e5a7f1' . + 'f2131786da90fe998d3571c144d066c3', + 'ct' => '91416054151e844965ad20a2057e2baa' . + '0e785269b152ba9d4dc834777e0d5376' . + 'db611856ae0d5d826f446c8eef47acb4' . + '83dccb37da9481648a4907fd3d65335b' . + 'd9585361c0c1834ac2b975f3238ea7c6', + ), + array( + 'key' => 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0' . + '0f0e0d0c0b0a09080706050403020100', + 'iv' => '', + 'aad' => null, + 'tag' => '606ac96568128a278b02e3e04de97b7e', + 'pt' => 'ea597a2f9fb0b5c4d5a6f215047b58a3' . + '3d2c885bf67cbb09239239f5aecafd6f' . + 'd2401391154b024b05cd938b40fdc749' . + 'ebccb3f48a3156c0bad69cfc5035360d' . + '21ad626dc866cc539f2d0e34b6824fc3', + 'ct' => '9c75fa0345b35e2d6cbcc91ed3fc7feb' . + '84fea50c35766db0c847fb627385107b' . + '4f257548d8b80ccd04261fa651fb89cc' . + 'e6815ecf0c8c4586ce68544ddce4c3af' . + '01e9587282256569194b1dca788fd987', + ), + array( + 'key' => 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0' . + '0f0e0d0c0b0a09080706050403020100', + 'iv' => '', + 'aad' => 'c0ef488e684e6fc95e0bd1da59861259', + 'tag' => 'a24cd6dcc0791bd7719a7f4fcb16de81', + 'pt' => 'b1677d933fa706f7ef349f9dd569c028' . + '279a5e2219728e77cfe916d5db979942' . + '5d8fb93b0e26dbc85ed14c050dc9f054' . + 'd9153c2be1e9b99ae7a109aba1e5a7f1' . + 'f2131786da90fe998d3571c144d066c3', + 'ct' => 'ea597a2f9fb0b5c4d5a6f215047b58a3' . + '3d2c885bf67cbb09239239f5aecafd6f' . + 'd2401391154b024b05cd938b40fdc749' . + 'ebccb3f48a3156c0bad69cfc5035360d' . + '21ad626dc866cc539f2d0e34b6824fc3', + ), + ), 'chacha20-poly1305' => array( array( 'key' => '808182838485868788898a8b8c8d8e8f' . diff --git a/ext/openssl/tests/crit.crt b/ext/openssl/tests/crit.crt new file mode 100644 index 000000000000..b56df4051d1e --- /dev/null +++ b/ext/openssl/tests/crit.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAkmgAwIBAgIUXulKXzpxr33sV/2LwI0+yhpUAZgwDQYJKoZIhvcNAQEF +BQAwgYExHjAcBgNVBAMMFUhlbnJpcXVlIGRvIE4uIEFuZ2VsbzELMAkGA1UEBhMC +QlIxGjAYBgNVBAgMEVJpbyBHcmFuZGUgZG8gU3VsMRUwEwYDVQQHDAxQb3J0byBB +bGVncmUxHzAdBgkqhkiG9w0BCQEWEGhuYW5nZWxvQHBocC5uZXQwHhcNMjUxMDAy +MTgwNjMwWhcNMjYxMDAyMTgwNjMwWjCBgTEeMBwGA1UEAwwVSGVucmlxdWUgZG8g +Ti4gQW5nZWxvMQswCQYDVQQGEwJCUjEaMBgGA1UECAwRUmlvIEdyYW5kZSBkbyBT +dWwxFTATBgNVBAcMDFBvcnRvIEFsZWdyZTEfMB0GCSqGSIb3DQEJARYQaG5hbmdl +bG9AcGhwLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy16ej5ArW6Vf +j9YMBUFh+hM9FPN7hJkvCBp6XiPBZPK2P7xzmc2WWsUQsPpaMnN+NqggyEIXjDgj +ZuRZHr89Oqu+e/6KKIi0d8q8mBioihtSGSIqZZrbAveaCq81EipOtMLiNZm4KTFD ++Syov078XrOT5pFLV34ps9qoJHlHD6UCAwEAAaNTMFEwHQYDVR0OBBYEFNt+QHK9 +XDWF7CkpgRLoYmhqtz99MB8GA1UdIwQYMBaAFNt+QHK9XDWF7CkpgRLoYmhqtz99 +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAc6jR36JD6xkzq2r0 +uIEjhiieDfFXcAVgisqymPHt6DDMSajRskfWPO58ayBKmT2J1yPxx2vdjAZxIRcg +2a06ef2OxE62X4+WNm6skIKLCXmc3AgkT//cqCjOs54EQMpdCJ/mkkYo9gZMB1aQ +jgozP+80FNIaioaDWVZsTsg3q0Q= +-----END CERTIFICATE----- diff --git a/ext/openssl/tests/gh19245.phpt b/ext/openssl/tests/gh19245.phpt new file mode 100644 index 000000000000..13433cc42a32 --- /dev/null +++ b/ext/openssl/tests/gh19245.phpt @@ -0,0 +1,53 @@ +--TEST-- +GH-19245: Success error message on TLS stream accept failure +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'local_pk' => '%s', + ]]); + + $sock = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx); + phpt_notify_server_start($sock); + + $link = stream_socket_accept($sock); +CODE; + +$clientCode = <<<'CODE' + $serverUri = "ssl://{{ ADDR }}"; + $clientFlags = STREAM_CLIENT_CONNECT; + + $clientCtx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false + ]]); + + @stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx); +CODE; + +$serverCode = sprintf($serverCodeTemplate, $baseDirCertFile . "\0test", $baseDirPkFile); +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); + +?> +--EXPECTF-- +PHP Warning: stream_socket_accept(): Path for local_cert in ssl stream context option must not contain any null bytes in %s +PHP Warning: stream_socket_accept(): Unable to get real path of certificate file `%scert.crt' in %s +PHP Warning: stream_socket_accept(): Failed to enable crypto in %s +PHP Warning: stream_socket_accept(): Accept failed: Cannot enable crypto in %s diff --git a/ext/openssl/tests/gh19369.phpt b/ext/openssl/tests/gh19369.phpt new file mode 100644 index 000000000000..3568bbbfeaff --- /dev/null +++ b/ext/openssl/tests/gh19369.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-19369: openssl_sign with alias algorithms +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/ext/openssl/tests/gh19428.phpt b/ext/openssl/tests/gh19428.phpt new file mode 100644 index 000000000000..373b49b52531 --- /dev/null +++ b/ext/openssl/tests/gh19428.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-19428: openssl_pkey_derive() DH with low key_length +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECTF-- +Deprecated: openssl_pkey_derive(): the $key_length parameter is deprecated as it is either ignored or truncates the key in %s on line %d +bool(false) diff --git a/ext/openssl/tests/gh19994.phpt b/ext/openssl/tests/gh19994.phpt new file mode 100644 index 000000000000..3aa32cfb4d2b --- /dev/null +++ b/ext/openssl/tests/gh19994.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-19994: openssl_get_cipher_methods inconsistent with fetched methods +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECT-- diff --git a/ext/openssl/tests/gh20802.phpt b/ext/openssl/tests/gh20802.phpt new file mode 100644 index 000000000000..786679c41c6a --- /dev/null +++ b/ext/openssl/tests/gh20802.phpt @@ -0,0 +1,62 @@ +--TEST-- +GH-20802: undefined behavior with invalid SNI_server_certs option values +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'allow_self_signed' => true, + 'verify_peer_name' => false, + 'verify_peer' => false, + 'SNI_enabled' => true, + 'SNI_server_certs' => [ + 'localhost' => &$localhost, + ] + ] + ]); + $server = stream_socket_server('tls://127.0.0.1:12443', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + stream_socket_accept($server, 3); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + +$ctx = stream_context_create([ + 'ssl' => [ + 'SNI_enabled' => true, + 'verify_peer_name' => false, + 'verify_peer' => false + ] + ]); + @stream_socket_client("tls://127.0.0.1:12443", $errno, $errstr, 1, $flags, $ctx); +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('gh20802-snioptions', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +%a +PHP Warning: stream_socket_accept(): Failed to enable crypto in %s(%d) : eval()'d code on line %d +PHP Warning: stream_socket_accept(): Accept failed: Cannot enable crypto in %s(%d) : eval()'d code on line %d diff --git a/ext/openssl/tests/gh21031.phpt b/ext/openssl/tests/gh21031.phpt new file mode 100644 index 000000000000..25bdb385a791 --- /dev/null +++ b/ext/openssl/tests/gh21031.phpt @@ -0,0 +1,55 @@ +--TEST-- +GH-21031 (Fix NULL deref when enabling TLS fails and the peer name needs to be reset) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'SNI_server_certs' => [ + "cs.php.net" => __DIR__ . "/sni_server_cs_expired.pem", + ] + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $serverFlags, $ctx); + phpt_notify_server_start($server); + + $conn = stream_socket_accept($server, 10); + if ($conn) { + fclose($conn); + } + + phpt_wait(); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create([ + 'ssl' => [ + 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'verify_peer' => true, + 'verify_peer_name' => true, + ], + "http" => [ + "proxy" => "tcp://{{ ADDR }}" + ], + ]); + + var_dump(@file_get_contents("https://cs.php.net/", false, $clientCtx)); + + phpt_notify(); +CODE; + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) diff --git a/ext/openssl/tests/gh21083.phpt b/ext/openssl/tests/gh21083.phpt new file mode 100644 index 000000000000..31afb7ca084d --- /dev/null +++ b/ext/openssl/tests/gh21083.phpt @@ -0,0 +1,61 @@ +--TEST-- +GH-21083 (openssl_pkey_new() fails for EC keys when private_key_bits is not set) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--ENV-- +OPENSSL_CONF= +--FILE-- + $conf, + 'private_key_type' => OPENSSL_KEYTYPE_EC, + 'curve_name' => 'prime256v1', +]); +var_dump($key !== false); +$details = openssl_pkey_get_details($key); +var_dump($details['bits']); +var_dump($details['type'] === OPENSSL_KEYTYPE_EC); +echo "EC OK\n"; + +// X25519 - fixed size key, private_key_bits should not be required +if (defined('OPENSSL_KEYTYPE_X25519')) { + $key = openssl_pkey_new([ + 'config' => $conf, + 'private_key_type' => OPENSSL_KEYTYPE_X25519, + ]); + var_dump($key !== false); + echo "X25519 OK\n"; +} else { + echo "bool(true)\nX25519 OK\n"; +} + +// Ed25519 - fixed size key, private_key_bits should not be required +if (defined('OPENSSL_KEYTYPE_ED25519')) { + $key = openssl_pkey_new([ + 'config' => $conf, + 'private_key_type' => OPENSSL_KEYTYPE_ED25519, + ]); + var_dump($key !== false); + echo "Ed25519 OK\n"; +} else { + echo "bool(true)\nEd25519 OK\n"; +} + +unlink($conf); +?> +--EXPECT-- +bool(true) +int(256) +bool(true) +EC OK +bool(true) +X25519 OK +bool(true) +Ed25519 OK diff --git a/ext/openssl/tests/gh9310.phpt b/ext/openssl/tests/gh9310.phpt index 07a7d442cec8..874ed4c781d3 100644 --- a/ext/openssl/tests/gh9310.phpt +++ b/ext/openssl/tests/gh9310.phpt @@ -23,7 +23,21 @@ $certificateGenerator->saveNewCertAndKey('gh9310', $certFile, $pkFile); copy($certFile, $baseDirCertFile); copy($pkFile, $baseDirPkFile); -copy(__DIR__ . '/sni_server_uk_cert.pem', $baseDir . '/sni_server_uk_cert.pem'); + +$sniCaFile = __DIR__ . '/gh9310_sni_ca.pem.tmp'; +$sniCsFile = __DIR__ . '/gh9310_sni_cs.pem.tmp'; +$sniUkCertFile = __DIR__ . '/gh9310_sni_uk_cert.pem.tmp'; +$sniUkKeyFile = __DIR__ . '/gh9310_sni_uk_key.pem.tmp'; +$sniUsCertFile = __DIR__ . '/gh9310_sni_us_cert.pem.tmp'; +$sniUsKeyFile = __DIR__ . '/gh9310_sni_us_key.pem.tmp'; +$baseDirSniUkCertFile = $baseDir . '/sni_uk_cert.pem'; + +$certificateGenerator->saveCaCert($sniCaFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $sniCsFile); +$certificateGenerator->saveNewCertAndKey('uk.php.net', $sniUkCertFile, $sniUkKeyFile); +$certificateGenerator->saveNewCertAndKey('us.php.net', $sniUsCertFile, $sniUsKeyFile); + +copy($sniUkCertFile, $baseDirSniUkCertFile); $serverCodeTemplate = <<<'CODE' @@ -60,7 +74,7 @@ $sniServerCodeV1 = <<<'CODE' $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ - "cs.php.net" => __DIR__ . "/sni_server_cs.pem", + "cs.php.net" => '%s', ] ]]); @@ -69,6 +83,7 @@ $sniServerCodeV1 = <<<'CODE' stream_socket_accept($server); CODE; +$sniServerCodeV1 = sprintf($sniServerCodeV1, $sniCsFile); $sniServerCodeV2 = <<<'CODE' ini_set('log_errors', 'On'); @@ -77,8 +92,8 @@ $sniServerCodeV2 = <<<'CODE' $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ "uk.php.net" => [ - 'local_cert' => __DIR__ . '/gh9310/sni_server_uk_cert.pem', - 'local_pk' => __DIR__ . '/sni_server_uk_key.pem', + 'local_cert' => '%s', + 'local_pk' => '%s', ] ] ]]); @@ -88,6 +103,7 @@ $sniServerCodeV2 = <<<'CODE' stream_socket_accept($server); CODE; +$sniServerCodeV2 = sprintf($sniServerCodeV2, $baseDirSniUkCertFile, $sniUkKeyFile); $sniServerCodeV3 = <<<'CODE' ini_set('log_errors', 'On'); @@ -96,8 +112,8 @@ $sniServerCodeV3 = <<<'CODE' $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ "us.php.net" => [ - 'local_cert' => __DIR__ . '/sni_server_us_cert.pem', - 'local_pk' => __DIR__ . '/sni_server_us_key.pem', + 'local_cert' => '%s', + 'local_pk' => '%s', ] ] ]]); @@ -107,14 +123,15 @@ $sniServerCodeV3 = <<<'CODE' stream_socket_accept($server); CODE; +$sniServerCodeV3 = sprintf($sniServerCodeV3, $sniUsCertFile, $sniUsKeyFile); $sniClientCodeTemplate = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctxArr = [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', + 'peer_name' => '%s', ]; - $ctxArr['peer_name'] = '%s'; $ctx = stream_context_create(['ssl' => $ctxArr]); @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 1, $flags, $ctx); CODE; @@ -131,13 +148,13 @@ ServerClientTestCase::getInstance()->run($clientCode, $serverCode); $serverCode = sprintf($serverCodeTemplate, $baseDirCertFile, $pkFile); ServerClientTestCase::getInstance()->run($clientCode, $serverCode); -$sniClientCode = sprintf($sniClientCodeTemplate, 'cs.php.net'); +$sniClientCode = sprintf($sniClientCodeTemplate, $sniCaFile, 'cs.php.net'); ServerClientTestCase::getInstance()->run($sniClientCode, $sniServerCodeV1); -$sniClientCode = sprintf($sniClientCodeTemplate, 'uk.php.net'); +$sniClientCode = sprintf($sniClientCodeTemplate, $sniCaFile, 'uk.php.net'); ServerClientTestCase::getInstance()->run($sniClientCode, $sniServerCodeV2); -$sniClientCode = sprintf($sniClientCodeTemplate, 'us.php.net'); +$sniClientCode = sprintf($sniClientCodeTemplate, $sniCaFile, 'us.php.net'); ServerClientTestCase::getInstance()->run($sniClientCode, $sniServerCodeV3); ?> @@ -149,7 +166,13 @@ $baseDir = __DIR__ . '/gh9310'; @unlink(__DIR__ . '/gh9310.key'); @unlink($baseDir . '/cert.crt'); @unlink($baseDir . '/private.key'); -@unlink($baseDir . '/sni_server_uk_cert.pem'); +@unlink($baseDir . '/sni_uk_cert.pem'); +@unlink(__DIR__ . '/gh9310_sni_ca.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_cs.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_uk_cert.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_uk_key.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_us_cert.pem.tmp'); +@unlink(__DIR__ . '/gh9310_sni_us_key.pem.tmp'); @rmdir($baseDir); ?> --EXPECTF-- @@ -169,15 +192,15 @@ PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(% PHP Warning: stream_socket_accept(): Unable to get real path of private key file `%sgh9310.key' in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s -PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%ssni_server_cs.pem) is not within the allowed path(s): (%sgh9310) in %s -PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%ssni_server_cs.pem'; file not found in %s +PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%sgh9310_sni_cs.pem.tmp) is not within the allowed path(s): (%sgh9310) in %s +PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%sgh9310_sni_cs.pem.tmp'; file not found in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s -PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%ssni_server_uk_key.pem) is not within the allowed path(s): (%sgh9310) in %s -PHP Warning: stream_socket_accept(): Failed setting local private key file `%ssni_server_uk_key.pem'; could not open file in %s +PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%sgh9310_sni_uk_key.pem.tmp) is not within the allowed path(s): (%sgh9310) in %s +PHP Warning: stream_socket_accept(): Failed setting local private key file `%sgh9310_sni_uk_key.pem.tmp'; could not open file in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s -PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%ssni_server_us_cert.pem) is not within the allowed path(s): (%sgh9310) in %s -PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%ssni_server_us_cert.pem'; could not open file in %s +PHP Warning: stream_socket_accept(): open_basedir restriction in effect. File(%sgh9310_sni_us_cert.pem.tmp) is not within the allowed path(s): (%sgh9310) in %s +PHP Warning: stream_socket_accept(): Failed setting local cert chain file `%sgh9310_sni_us_cert.pem.tmp'; could not open file in %s PHP Warning: stream_socket_accept(): Failed to enable crypto in %s PHP Warning: stream_socket_accept(): Accept failed: %s diff --git a/ext/openssl/tests/openssl_cms_encrypt_auth_env.phpt b/ext/openssl/tests/openssl_cms_encrypt_auth_env.phpt new file mode 100644 index 000000000000..9b2086c78acf --- /dev/null +++ b/ext/openssl/tests/openssl_cms_encrypt_auth_env.phpt @@ -0,0 +1,34 @@ +--TEST-- +openssl_cms_encrypt() auth enveloped data tests +--EXTENSIONS-- +openssl +--SKIPIF-- += 3.0'); +?> +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +Now is the winter of our discontent. diff --git a/ext/openssl/tests/openssl_cms_encrypt_basic.phpt b/ext/openssl/tests/openssl_cms_encrypt_basic.phpt index 14b5231fdd32..0ddda76d83a6 100644 --- a/ext/openssl/tests/openssl_cms_encrypt_basic.phpt +++ b/ext/openssl/tests/openssl_cms_encrypt_basic.phpt @@ -5,13 +5,9 @@ openssl --FILE-- +--CLEAN-- + --EXPECT-- bool(true) bool(true) diff --git a/ext/openssl/tests/openssl_decrypt_basic.phpt b/ext/openssl/tests/openssl_decrypt_basic.phpt index 6cb2297a979b..0f674dbc1e34 100644 --- a/ext/openssl/tests/openssl_decrypt_basic.phpt +++ b/ext/openssl/tests/openssl_decrypt_basic.phpt @@ -10,8 +10,7 @@ $password = "openssl"; $ivlen = openssl_cipher_iv_length($method); $iv = ''; -srand(time() + ((int)(microtime(true) * 1000000) % 1000000)); -while(strlen($iv) < $ivlen) $iv .= chr(rand(0,255)); +while(strlen($iv) < $ivlen) $iv .= random_bytes(1); $encrypted = openssl_encrypt($data, $method, $password, 0, $iv); $output = openssl_decrypt($encrypted, $method, $password, 0, $iv); diff --git a/ext/openssl/tests/openssl_decrypt_siv.phpt b/ext/openssl/tests/openssl_decrypt_siv.phpt new file mode 100644 index 000000000000..6fc299546e20 --- /dev/null +++ b/ext/openssl/tests/openssl_decrypt_siv.phpt @@ -0,0 +1,43 @@ +--TEST-- +openssl_decrypt() with SIV cipher algorithm tests +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + $test) { + echo "TEST $idx\n"; + $pt = openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], $test['tag'], $test['aad']); + var_dump($test['pt'] === $pt); +} + +// failed because no AAD +echo "TEST AAD\n"; +var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], $test['tag'])); +// failed because wrong tag +echo "TEST WRONGTAG\n"; +var_dump(openssl_decrypt($test['ct'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], str_repeat('x', 16), $test['aad'])); + +?> +--EXPECTF-- +TEST 0 +bool(true) +TEST 1 +bool(true) +TEST 2 +bool(true) +TEST AAD +bool(false) +TEST WRONGTAG +bool(false) diff --git a/ext/openssl/tests/openssl_encrypt_cbc.phpt b/ext/openssl/tests/openssl_encrypt_cbc.phpt new file mode 100644 index 000000000000..5ac526afaa09 --- /dev/null +++ b/ext/openssl/tests/openssl_encrypt_cbc.phpt @@ -0,0 +1,12 @@ +--TEST-- +openssl_encrypt() CBC and its alias +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECTF-- +string(48) "7a654459353452676f6c6b6a446b75455a6c4c6b4f513d3d" +string(48) "7a654459353452676f6c6b6a446b75455a6c4c6b4f513d3d" diff --git a/ext/openssl/tests/openssl_encrypt_siv.phpt b/ext/openssl/tests/openssl_encrypt_siv.phpt new file mode 100644 index 000000000000..43a5c5b34b5a --- /dev/null +++ b/ext/openssl/tests/openssl_encrypt_siv.phpt @@ -0,0 +1,51 @@ +--TEST-- +openssl_encrypt() with SIV cipher algorithm tests +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + $test) { + echo "TEST $idx\n"; + $ct = openssl_encrypt($test['pt'], $method, $test['key'], OPENSSL_RAW_DATA, + $test['iv'], $tag, $test['aad'], strlen($test['tag'])); + var_dump($test['ct'] === $ct); + var_dump($test['tag'] === $tag); +} + +// Empty tag should not be equivalent to null tag +echo "TEST AAD\n"; +var_dump(openssl_encrypt('data', $method, 'password', 0, '', $tag, '') !== openssl_encrypt('data', $method, 'password', 0, '', $tag, null)); + +// Failing to retrieve tag (max is 16 bytes) +var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 32), $tag, '', 20)); + +// Failing when no tag supplied +var_dump(openssl_encrypt('data', $method, 'password', 0, str_repeat('x', 32))); +?> +--EXPECTF-- +TEST 0 +bool(true) +bool(true) +TEST 1 +bool(true) +bool(true) +TEST 2 +bool(true) +bool(true) +TEST AAD +bool(true) + +Warning: openssl_encrypt(): Retrieving verification tag failed in %s on line %d +bool(false) + +Warning: openssl_encrypt(): A tag should be provided when using AEAD mode in %s on line %d +bool(false) diff --git a/ext/openssl/tests/openssl_libctx_with_zts_argon.phpt b/ext/openssl/tests/openssl_libctx_with_zts_argon.phpt new file mode 100644 index 000000000000..13efcaa26b60 --- /dev/null +++ b/ext/openssl/tests/openssl_libctx_with_zts_argon.phpt @@ -0,0 +1,22 @@ +--TEST-- +openssl.libctx INI setting when Argon2 enabled and ZTS used +--EXTENSIONS-- +openssl +--INI-- +openssl.libctx = default +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Fatal error: PHP Startup: OpenSSL libctx "default" cannot be used in this configuration in Unknown on line 0 +string(6) "custom" diff --git a/ext/openssl/tests/openssl_libctx_without_zts_argon.phpt b/ext/openssl/tests/openssl_libctx_without_zts_argon.phpt new file mode 100644 index 000000000000..f2fd64b7469d --- /dev/null +++ b/ext/openssl/tests/openssl_libctx_without_zts_argon.phpt @@ -0,0 +1,18 @@ +--TEST-- +openssl.libctx INI setting when Argon2 disable or ZTS not used +--EXTENSIONS-- +openssl +--INI-- +openssl.libctx = default +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(7) "default" diff --git a/ext/openssl/tests/openssl_password.phpt b/ext/openssl/tests/openssl_password.phpt index 0dbc1ae42a3f..ca0d20f9bcc3 100644 --- a/ext/openssl/tests/openssl_password.phpt +++ b/ext/openssl/tests/openssl_password.phpt @@ -5,7 +5,10 @@ openssl --SKIPIF-- --FILE-- diff --git a/ext/openssl/tests/openssl_pbkdf2_basic.phpt b/ext/openssl/tests/openssl_pbkdf2_basic.phpt index fd253ac78bb2..ba79f9415ba8 100644 --- a/ext/openssl/tests/openssl_pbkdf2_basic.phpt +++ b/ext/openssl/tests/openssl_pbkdf2_basic.phpt @@ -19,6 +19,8 @@ var_dump(bin2hex(openssl_pbkdf2('password', 'salt', 20, 16777216))); var_dump(bin2hex(openssl_pbkdf2('passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 25, 4096))); var_dump(bin2hex(openssl_pbkdf2("pass\0word", "sa\0lt", 16, 4096))); +var_dump(bin2hex(openssl_pbkdf2("password", "salt", 16, 4096, "sha-256"))); + ?> --EXPECT-- string(40) "0c60c80f961f0e71f3a9b524af6012062fe037a6" @@ -26,3 +28,4 @@ string(40) "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957" string(40) "4b007901b765489abead49d926f721d065a429c1" string(50) "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038" string(32) "56fa6aa75548099dcc37d7f03425e0c3" +string(32) "c5e478d59288c841aa530db6845c4c8d" diff --git a/ext/openssl/tests/openssl_pkey_derive_deprecated_key_length_param.phpt b/ext/openssl/tests/openssl_pkey_derive_deprecated_key_length_param.phpt new file mode 100644 index 000000000000..b6a4c9167535 --- /dev/null +++ b/ext/openssl/tests/openssl_pkey_derive_deprecated_key_length_param.phpt @@ -0,0 +1,45 @@ +--TEST-- +openssl_pkey_derive() DH +--EXTENSIONS-- +openssl +--FILE-- + +--EXPECTF-- +Deprecated: openssl_pkey_derive(): the $key_length parameter is deprecated as it is either ignored or truncates the key in %s on line %d +string(512) "10aed66ad96a65f50543aa9adbc18ea169bf98521c682c49fb8b7daeb9e8fbe6b9a800199ffe1123cc36fc358829cbbc5d21bf1eb8ce3cf644538b357f478361a284c27fbe31fc94d431562786dd7314613cd70e6d76ca1ab3c1f31556ed07162f243dcc1a43ea98c454fb6e891eaec7a14158d54cd33d3fbbbc75f1ea8ff5deaab25d5deb657c7c43004252df301b195207d01614e7cb833e0e8d785ba2ecfe16ad7a9634784fdb8db8afe049476b58743575725ee99c761a59a7d7b9e709fff84c8d427e2bc07953a7c2408eb3f8f7e0ebc2f901c6889955874ae79a3de19921757d69424145a35dbe5af778b080dada55bdfce8fb0319f2de39110f58e05d" diff --git a/ext/openssl/tests/openssl_private_decrypt_digest.phpt b/ext/openssl/tests/openssl_private_decrypt_digest.phpt new file mode 100644 index 000000000000..9bb07ba71eac --- /dev/null +++ b/ext/openssl/tests/openssl_private_decrypt_digest.phpt @@ -0,0 +1,57 @@ +--TEST-- +openssl_private_decrypt() with digest algorithm tests +--EXTENSIONS-- +openssl +--FILE-- +getMessage()); +} + +openssl_public_encrypt($data, $encrypted_pkcs1, $pubkey, OPENSSL_PKCS1_PADDING); +var_dump(openssl_private_decrypt($encrypted_pkcs1, $output_pkcs1, $privkey, OPENSSL_PKCS1_PADDING, "sha256")); +var_dump($output_pkcs1); +?> +--EXPECTF-- +bool(true) +string(56) "Testing openssl_private_decrypt() with digest algorithms" +bool(true) +string(56) "Testing openssl_private_decrypt() with digest algorithms" +bool(false) +NULL + +Warning: openssl_private_decrypt(): Unknown digest algorithm: invalid_hash in %s on line %d +bool(false) +NULL +string(85) "openssl_private_decrypt(): Argument #5 ($digest_algo) must not contain any null bytes" +bool(true) +string(56) "Testing openssl_private_decrypt() with digest algorithms" diff --git a/ext/openssl/tests/openssl_sign_basic.phpt b/ext/openssl/tests/openssl_sign_basic.phpt index 047028101893..9d2edbec59f7 100644 --- a/ext/openssl/tests/openssl_sign_basic.phpt +++ b/ext/openssl/tests/openssl_sign_basic.phpt @@ -8,11 +8,27 @@ $data = "Testing openssl_sign()"; $privkey = "file://" . __DIR__ . "/private_rsa_1024.key"; $wrong = "wrong"; -var_dump(openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256)); // no output +var_dump(openssl_sign($data, $sign1, $privkey, OPENSSL_ALGO_SHA256)); +var_dump(bin2hex($sign1)); +var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256)); +var_dump($sign1 === $sign2); +var_dump(openssl_sign($data, $sign1, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); +var_dump(strlen($sign1)); +var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); +var_dump(strlen($sign2)); +var_dump($sign1 === $sign2); var_dump(openssl_sign($data, $sign, $wrong)); ?> --EXPECTF-- bool(true) +string(256) "5eff033d92208fcbf52edc9cbf6c9d4bd7c06b7b5a6a22c7d641d1494a09d6b0898d321c0a8fdb55c10b9bf25c2bb777c2b4660f867001f79879d089de7321a28df5f037cc02b68c47d1eb28d98a9199876961adb02524a489872a12fd3675db6a957d623ff04b9f715b565f516806cea247264c82a7569871dbd0b86cfe4689" +bool(true) +bool(true) +bool(true) +int(128) +bool(true) +int(128) +bool(false) Warning: openssl_sign(): Supplied key param cannot be coerced into a private key in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_verify_basic.phpt b/ext/openssl/tests/openssl_verify_basic.phpt index 674a3c58a9ea..1b28c1371083 100644 --- a/ext/openssl/tests/openssl_verify_basic.phpt +++ b/ext/openssl/tests/openssl_verify_basic.phpt @@ -9,6 +9,10 @@ $privkey = "file://" . __DIR__ . "/private_rsa_1024.key"; $pubkey = "file://" . __DIR__ . "/public.key"; $wrong = "wrong"; + +openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING); +var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING)); +var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256)); openssl_sign($data, $sign, $privkey, OPENSSL_ALGO_SHA256); var_dump(openssl_verify($data, $sign, $pubkey, OPENSSL_ALGO_SHA256)); var_dump(openssl_verify($data, $sign, $privkey, OPENSSL_ALGO_SHA256)); @@ -18,6 +22,8 @@ var_dump(openssl_verify($wrong, $sign, $pubkey, OPENSSL_ALGO_SHA256)); ?> --EXPECTF-- int(1) +int(0) +int(1) Warning: openssl_verify(): Supplied key param cannot be coerced into a public key in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt b/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt index 7c06881c9be7..99c1150b0e85 100644 --- a/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt +++ b/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt @@ -14,7 +14,7 @@ $cert = "file://" . __DIR__ . "/cert.crt"; $bert = "file://" . __DIR__ . "/bug41033.pem"; $sert = "file://" . __DIR__ . "/san-cert.pem"; $cpca = __DIR__ . "/san-cert.pem"; -$utfl = __DIR__ . "/sni_server_uk.pem"; +$utfl = __DIR__ . "/sni_server.pem"; $rcrt = openssl_x509_read($cert); /* int openssl_x509_checkpurpose ( mixed $x509cert , int $purpose); */ diff --git a/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt b/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt index 5775c2597c3e..59a942d6a67e 100644 --- a/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt +++ b/ext/openssl/tests/openssl_x509_export_to_file_leak.phpt @@ -5,7 +5,7 @@ openssl --FILE-- diff --git a/ext/openssl/tests/openssl_x509_parse_basic.phpt b/ext/openssl/tests/openssl_x509_parse_basic.phpt index ef63f0f85f49..7170b1a08aca 100644 --- a/ext/openssl/tests/openssl_x509_parse_basic.phpt +++ b/ext/openssl/tests/openssl_x509_parse_basic.phpt @@ -8,7 +8,7 @@ if (OPENSSL_VERSION_NUMBER >= 0x30200000) die('skip For OpenSSL < 3.2'); ?> --FILE-- --EXPECTF-- bool(true) -array(16) { +array(17) { ["name"]=> - string(96) "/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net" + string(96) "/CN=Henrique do N. Angelo/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/emailAddress=hnangelo@php.net" ["subject"]=> array(5) { + ["CN"]=> + string(21) "Henrique do N. Angelo" ["C"]=> string(2) "BR" ["ST"]=> string(17) "Rio Grande do Sul" ["L"]=> string(12) "Porto Alegre" - ["CN"]=> - string(21) "Henrique do N. Angelo" ["emailAddress"]=> string(16) "hnangelo@php.net" } @@ -37,31 +37,31 @@ array(16) { string(8) "%s" ["issuer"]=> array(5) { + ["CN"]=> + string(21) "Henrique do N. Angelo" ["C"]=> string(2) "BR" ["ST"]=> string(17) "Rio Grande do Sul" ["L"]=> string(12) "Porto Alegre" - ["CN"]=> - string(21) "Henrique do N. Angelo" ["emailAddress"]=> string(16) "hnangelo@php.net" } ["version"]=> int(2) ["serialNumber"]=> - string(20) "12593567369101004962" + string(42) "0x5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198" ["serialNumberHex"]=> - string(16) "AEC556CC723750A2" + string(40) "5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198" ["validFrom"]=> - string(13) "080630102843Z" + string(13) "251002180630Z" ["validTo"]=> - string(13) "080730102843Z" + string(13) "261002180630Z" ["validFrom_time_t"]=> - int(1214821723) + int(1759428390) ["validTo_time_t"]=> - int(1217413723) + int(1790964390) ["signatureTypeSN"]=> string(8) "RSA-SHA1" ["signatureTypeLN"]=> @@ -157,26 +157,29 @@ array(16) { ["subjectKeyIdentifier"]=> string(59) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D" ["authorityKeyIdentifier"]=> - string(%d) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D -DirName:/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net -serial:AE:C5:56:CC:72:37:50:A2%A" + string(%d) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D" ["basicConstraints"]=> string(7) "CA:TRUE" } + ["criticalExtensions"]=> + array(1) { + [0]=> + string(16) "basicConstraints" + } } -array(16) { +array(17) { ["name"]=> - string(96) "/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net" + string(96) "/CN=Henrique do N. Angelo/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/emailAddress=hnangelo@php.net" ["subject"]=> array(5) { + ["commonName"]=> + string(21) "Henrique do N. Angelo" ["countryName"]=> string(2) "BR" ["stateOrProvinceName"]=> string(17) "Rio Grande do Sul" ["localityName"]=> string(12) "Porto Alegre" - ["commonName"]=> - string(21) "Henrique do N. Angelo" ["emailAddress"]=> string(16) "hnangelo@php.net" } @@ -184,31 +187,31 @@ array(16) { string(8) "%s" ["issuer"]=> array(5) { + ["commonName"]=> + string(21) "Henrique do N. Angelo" ["countryName"]=> string(2) "BR" ["stateOrProvinceName"]=> string(17) "Rio Grande do Sul" ["localityName"]=> string(12) "Porto Alegre" - ["commonName"]=> - string(21) "Henrique do N. Angelo" ["emailAddress"]=> string(16) "hnangelo@php.net" } ["version"]=> int(2) ["serialNumber"]=> - string(20) "12593567369101004962" + string(42) "0x5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198" ["serialNumberHex"]=> - string(16) "AEC556CC723750A2" + string(40) "5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198" ["validFrom"]=> - string(13) "080630102843Z" + string(13) "251002180630Z" ["validTo"]=> - string(13) "080730102843Z" + string(13) "261002180630Z" ["validFrom_time_t"]=> - int(1214821723) + int(1759428390) ["validTo_time_t"]=> - int(1217413723) + int(1790964390) ["signatureTypeSN"]=> string(8) "RSA-SHA1" ["signatureTypeLN"]=> @@ -304,10 +307,13 @@ array(16) { ["subjectKeyIdentifier"]=> string(59) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D" ["authorityKeyIdentifier"]=> - string(%d) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D -DirName:/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net -serial:AE:C5:56:CC:72:37:50:A2%A" + string(%d) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D" ["basicConstraints"]=> string(7) "CA:TRUE" } + ["criticalExtensions"]=> + array(1) { + [0]=> + string(16) "basicConstraints" + } } diff --git a/ext/openssl/tests/session_resumption_cache_disabled.phpt b/ext/openssl/tests/session_resumption_cache_disabled.phpt new file mode 100644 index 000000000000..9e0e8a82f399 --- /dev/null +++ b/ext/openssl/tests/session_resumption_cache_disabled.phpt @@ -0,0 +1,86 @@ +--TEST-- +TLS session resumption - server with cache disabled +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => false, /* Disable session caching */ + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "No cache connection " . ($i + 1) . "\n"); + fclose($client); + } + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $globalSession = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$globalSession) { + $globalSession = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + fclose($client1); + } + + /* Second connection - server won't use cached session */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $globalSession, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + echo trim(fgets($client2)) . "\n"; + $meta2 = stream_get_meta_data($client2); + echo "Second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + fclose($client2); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_disabled_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +No cache connection 1 +First connection resumed: no +No cache connection 2 +Second connection resumed: no diff --git a/ext/openssl/tests/session_resumption_client_basic.phpt b/ext/openssl/tests/session_resumption_client_basic.phpt new file mode 100644 index 000000000000..ee1d126a6d9f --- /dev/null +++ b/ext/openssl/tests/session_resumption_client_basic.phpt @@ -0,0 +1,89 @@ +--TEST-- +TLS session resumption - client basic resumption +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => true, + 'session_id_context' => 'test-basic', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Hello from server\n"); + fclose($client); + } + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = ''; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection - full handshake */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo "Session data received: " . (!empty($sessionData) ? "yes" : "no") . "\n"; + fclose($client1); + } + + /* Second connection - resumed session */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + echo trim(fgets($client2)) . "\n"; + $meta2 = stream_get_meta_data($client2); + echo "Second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + fclose($client2); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_resumption_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +Hello from server +First connection resumed: no +Session data received: yes +Hello from server +Second connection resumed: yes diff --git a/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt b/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt new file mode 100644 index 000000000000..f87f831a7859 --- /dev/null +++ b/ext/openssl/tests/session_resumption_get_cb_no_ticket.phpt @@ -0,0 +1,79 @@ +--TEST-- +TLS session resumption - warning when trying to enable tickets with session_get_cb +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-app', + 'no_ticket' => false, // Explicitly trying to enable tickets + 'session_new_cb' => function($stream, $sessionData) { + // Store session + }, + 'session_get_cb' => function($stream, $sessionId) { + return null; + } + ]]); + + try { + $server = @stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client === false) { + phpt_notify(message: "SERVER_FAILED_UNEXPECTEDLY"); + } else { + phpt_notify(message: "SERVER_CREATED_UNEXPECTEDLY"); + fclose($server); + } + } catch (\Throwable $e) { + phpt_notify(message: "SERVER_EXCEPTION: " . $e->getMessage()); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => 'this_is_invalid_session_data', + ]]); + + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed as expected\n"; + } + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_no_ticket_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +SERVER_EXCEPTION: Session tickets cannot be enabled when session_get_cb is setConnection failed as expected + diff --git a/ext/openssl/tests/session_resumption_get_cb_num_tickets_positive.phpt b/ext/openssl/tests/session_resumption_get_cb_num_tickets_positive.phpt new file mode 100644 index 000000000000..5563b0c22cf8 --- /dev/null +++ b/ext/openssl/tests/session_resumption_get_cb_num_tickets_positive.phpt @@ -0,0 +1,82 @@ +--TEST-- +TLS session resumption - num_tickets controls ticket generation (TLS 1.3) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, + 'num_tickets' => 3, // Issue 3 tickets per connection + ]]); + + $server = stream_socket_server('tlsv1.3://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + // Accept one connection + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Ticket test\n"); + // Keep connection open briefly to allow tickets to be sent + usleep(100000); // 100ms + fclose($client); + } + + phpt_notify(message: "SERVER_DONE"); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $ticketCount = 0; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, + 'session_new_cb' => function($stream, $session) use (&$ticketCount) { + $ticketCount++; + } + ]]); + + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client) { + $response = fgets($client); + echo trim($response) . "\n"; + + // Keep connection open briefly to receive all tickets + usleep(150000); // 150ms + fclose($client); + } + + echo "Tickets received: $ticketCount\n"; + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_num_tickets_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Ticket test +Tickets received: 3 +SERVER_DONE diff --git a/ext/openssl/tests/session_resumption_get_cb_num_tickets_zero.phpt b/ext/openssl/tests/session_resumption_get_cb_num_tickets_zero.phpt new file mode 100644 index 000000000000..13654cd451e9 --- /dev/null +++ b/ext/openssl/tests/session_resumption_get_cb_num_tickets_zero.phpt @@ -0,0 +1,112 @@ +--TEST-- +TLS session resumption - num_tickets = 0 disables tickets, forces session IDs +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-no-tickets', + 'num_tickets' => 0, // Disable ticket issuance + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled++; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore) { + $key = bin2hex($sessionId); + return $sessionStore[$key] ?? null; + }, + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + // Accept two connections + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + usleep(50000); // Allow session storage + fclose($client); + } + } + + phpt_notify(message: "NEW_CB_CALLS:$newCbCalled"); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + $clientTickets = 0; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData, &$clientTickets) { + $sessionData = $session; + $clientTickets++; + } + ]]); + + // First connection + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + usleep(100000); // Wait for session storage + fclose($client1); + } + + echo "Client received tickets on first connection: $clientTickets\n"; + + // Second connection with resumption + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + $result = phpt_wait(); + echo "Server: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_no_tickets_zero_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +Client first connection resumed: no +Response 1 +Client received tickets on first connection: 0 +Client second connection resumed: no +Response 2 +Server: NEW_CB_CALLS:0 diff --git a/ext/openssl/tests/session_resumption_import_export_session.phpt b/ext/openssl/tests/session_resumption_import_export_session.phpt new file mode 100644 index 000000000000..0d9a3274b113 --- /dev/null +++ b/ext/openssl/tests/session_resumption_import_export_session.phpt @@ -0,0 +1,98 @@ +--TEST-- +TLS session resumption - import and export session +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => true, + 'session_id_context' => 'test-basic', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept single connections */ + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Hello from server\n"); + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = ''; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + if (empty($sessionData)) { + // default should be pem + $pemSessionData = $session->export(); + var_dump($pemSessionData); + $session = Openssl\Session::import($pemSessionData); + $pemSessionData = $session->export(OPENSSL_ENCODING_PEM); + var_dump($pemSessionData); + $session = Openssl\Session::import($pemSessionData, OPENSSL_ENCODING_PEM); + $derSessionData = $session->export(OPENSSL_ENCODING_DER); + var_dump(strlen($derSessionData) > 0); + var_dump(strpos($derSessionData, 'BEGIN SSL SESSION PARAMETERS') === false); + $session = Openssl\Session::import($derSessionData, OPENSSL_ENCODING_DER); + var_dump($session); + } + $sessionData = $session; + } + ]]); + + /* First connection - full handshake */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo "Session data received: " . (!empty($sessionData) ? "yes" : "no") . "\n"; + fclose($client1); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_resumption_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +string(%d) "-----BEGIN SSL SESSION PARAMETERS----- +%a +-----END SSL SESSION PARAMETERS----- +" +string(%d) "-----BEGIN SSL SESSION PARAMETERS----- +%a +-----END SSL SESSION PARAMETERS----- +" +bool(true) +bool(true) +object(Openssl\Session)#%d (1) { + ["id"]=> + string(32) "%a" +} +Hello from server +First connection resumed: no +Session data received: yes diff --git a/ext/openssl/tests/session_resumption_invalid_callback.phpt b/ext/openssl/tests/session_resumption_invalid_callback.phpt new file mode 100644 index 000000000000..b6cfc90a0554 --- /dev/null +++ b/ext/openssl/tests/session_resumption_invalid_callback.phpt @@ -0,0 +1,60 @@ +--TEST-- +TLS session resumption - invalid callback throws TypeError +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client) { + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use invalid callback */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => 'not_a_valid_function', + ]]); + + try { + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + echo "Should not reach here\n"; + } catch (TypeError $e) { + echo "TypeError caught: " . (strpos($e->getMessage(), 'session_new_cb must be a valid callback') !== false ? "YES" : "NO"); + echo "\n"; + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_invalid_cb_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +TypeError caught: YES diff --git a/ext/openssl/tests/session_resumption_invalid_data.phpt b/ext/openssl/tests/session_resumption_invalid_data.phpt new file mode 100644 index 000000000000..7e50b9235a2b --- /dev/null +++ b/ext/openssl/tests/session_resumption_invalid_data.phpt @@ -0,0 +1,66 @@ +--TEST-- +TLS session resumption - invalid session data is fatal +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client) { + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => 'this_is_invalid_session_data', + ]]); + + try { + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed unexpectedlyd\n"; + } + } catch (\Throwable $e) { + echo "Type error thrown: " . $e->getMessage() . "\n"; + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_invalid_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): Unable to connect to %s in %s on line %d +Type error thrown: session_data must be an OpenSSLSession instance diff --git a/ext/openssl/tests/session_resumption_invalid_session_import.phpt b/ext/openssl/tests/session_resumption_invalid_session_import.phpt new file mode 100644 index 000000000000..a9c5b65f2051 --- /dev/null +++ b/ext/openssl/tests/session_resumption_invalid_session_import.phpt @@ -0,0 +1,23 @@ +--TEST-- +TLS session resumption - invalid session import +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--CLEAN-- + +--EXPECT-- +Failed to import session data diff --git a/ext/openssl/tests/session_resumption_new_cb_no_context.phpt b/ext/openssl/tests/session_resumption_new_cb_no_context.phpt new file mode 100644 index 000000000000..ee2852c54ad7 --- /dev/null +++ b/ext/openssl/tests/session_resumption_new_cb_no_context.phpt @@ -0,0 +1,78 @@ +--TEST-- +TLS session resumption - warning when session_new_cb without session_id_context and verify_peer enabled +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'verify_peer' => true, + 'cafile' => '%s', + 'session_new_cb' => function($stream, $session) { + echo "not called new_cb\n"; + }, + 'session_get_cb' => function($stream, $sessionId) { + echo "not called new_cb\n"; + return null; + } + /* Missing: 'session_id_context' => 'myapp' */ + ]]); + + try { + $server = @stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client === false) { + phpt_notify(message: "SERVER_FAILED_UNEXPECTEDLY"); + } else { + phpt_notify(message: "SERVER_CREATED_UNEXPECTEDLY"); + fclose($server); + } + } catch (\Throwable $e) { + phpt_notify(message: "SERVER_EXCEPTION: " . $e->getMessage()); + } +CODE; +$serverCode = sprintf($serverCode, $certFile, $caCertFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false + ]]); + + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveCaCert($caCertFile); +$certificateGenerator->saveNewCertAsFileWithKey('session_verify_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +SERVER_EXCEPTION: session_id_context must be set if session_new_cb is set diff --git a/ext/openssl/tests/session_resumption_persistent_reject.phpt b/ext/openssl/tests/session_resumption_persistent_reject.phpt new file mode 100644 index 000000000000..835e9bb51648 --- /dev/null +++ b/ext/openssl/tests/session_resumption_persistent_reject.phpt @@ -0,0 +1,66 @@ +--TEST-- +TLS session resumption - callbacks rejected on persistent streams +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client) { + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT; + + /* Try to use callback with persistent stream */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) { + echo "This should never be called\n"; + } + ]]); + + $client = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed as expected with persistent stream\n"; + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_persistent_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- + +Warning: stream_socket_client(): session_new_cb is not supported for persistent streams in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): Unable to connect to %s in %s on line %d +Connection failed as expected with persistent stream diff --git a/ext/openssl/tests/session_resumption_require_new_cb.phpt b/ext/openssl/tests/session_resumption_require_new_cb.phpt new file mode 100644 index 000000000000..a08408e2d90b --- /dev/null +++ b/ext/openssl/tests/session_resumption_require_new_cb.phpt @@ -0,0 +1,73 @@ +--TEST-- +TLS session resumption - server requires session_new_cb with session_get_cb +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_get_cb' => function($stream, $sessionId) { + return null; + } + ]]); + + try { + $server = @stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + $client = @stream_socket_accept($server, 30); + if ($client === false) { + phpt_notify(message: "SERVER_FAILED_UNEXPECTEDLY"); + } else { + phpt_notify(message: "SERVER_CREATED_UNEXPECTEDLY"); + fclose($server); + } + } catch (\Throwable $e) { + phpt_notify(message: "SERVER_EXCEPTION: " . $e->getMessage()); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + + /* Try to use corrupted session data */ + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => 'this_is_invalid_session_data', + ]]); + + $client = @stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + + if ($client === false) { + echo "Connection failed as expected\n"; + } + + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_require_cb_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECT-- +SERVER_EXCEPTION: session_new_cb is required when session_get_cb is providedConnection failed as expected diff --git a/ext/openssl/tests/session_resumption_serialize_session.phpt b/ext/openssl/tests/session_resumption_serialize_session.phpt new file mode 100644 index 000000000000..f2f3c98e5e5b --- /dev/null +++ b/ext/openssl/tests/session_resumption_serialize_session.phpt @@ -0,0 +1,84 @@ +--TEST-- +TLS session resumption - serialize session +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_cache' => true, + 'session_id_context' => 'test-basic', + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept single connections */ + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Hello from server\n"); + fclose($client); + } +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = ''; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + if (empty($sessionData)) { + $serializedSessionData = serialize($session); + var_dump($serializedSessionData); + $session = unserialize($serializedSessionData); + var_dump($session); + } + $sessionData = $session; + } + ]]); + + /* First connection - full handshake */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + echo trim(fgets($client1)) . "\n"; + $meta1 = stream_get_meta_data($client1); + echo "First connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo "Session data received: " . (!empty($sessionData) ? "yes" : "no") . "\n"; + fclose($client1); + } +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_resumption_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +string(%d) "O:15:"Openssl\Session":1:{s:3:"pem";s:%d:"-----BEGIN SSL SESSION PARAMETERS----- +%a +-----END SSL SESSION PARAMETERS----- +";}" +object(Openssl\Session)#9 (1) { + ["id"]=> +%a +} +Hello from server +First connection resumed: no +Session data received: yes diff --git a/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt b/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt new file mode 100644 index 000000000000..02c6a7dcfdc7 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_external_with_context_id.phpt @@ -0,0 +1,116 @@ +--TEST-- +TLS session resumption - server external cache callbacks with context id +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-server', + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled = true; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore, &$getCbCalled) { + $key = bin2hex($sessionId); + $getCbCalled = true; + return $sessionStore[$key] ?? null; + }, + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + fclose($client); + } + } + + /* Report results */ + $result = []; + if ($newCbCalled) $result[] = "NEW_CB_CALLED"; + if ($getCbCalled) $result[] = "GET_CB_CALLED"; + $result[] = "SESSIONS:" . count($sessionStore); + + phpt_notify(message: implode(",", $result)); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + echo "Session captured: " . ($sessionData !== null ? "YES" : "NO") . "\n"; + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Get server callback results */ + $result = phpt_wait(); + echo "Server: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_external_proper_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Response 1 +Session captured: YES +Client second connection resumed: yes +Response 2 +Server: NEW_CB_CALLED,GET_CB_CALLED,SESSIONS:3 diff --git a/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt b/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt new file mode 100644 index 000000000000..bdc3d2ce1bf6 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_external_with_context_id_tls12.phpt @@ -0,0 +1,116 @@ +--TEST-- +TLS session resumption - server external cache callbacks with context id for TLS 1.2 +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-server', // Proper configuration + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled = true; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore, &$getCbCalled) { + $key = bin2hex($sessionId); + $getCbCalled = true; + return $sessionStore[$key] ?? null; + }, + ]]); + + $server = stream_socket_server('tlsv1.2://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + fclose($client); + } + } + + /* Report results */ + $result = []; + if ($newCbCalled) $result[] = "NEW_CB_CALLED"; + if ($getCbCalled) $result[] = "GET_CB_CALLED"; + $result[] = "SESSIONS:" . count($sessionStore); + + phpt_notify(message: implode(",", $result)); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + echo "Session captured: " . ($sessionData !== null ? "YES" : "NO") . "\n"; + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Get server callback results */ + $result = phpt_wait(); + echo "Server: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_external_proper_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Response 1 +Session captured: YES +Client second connection resumed: yes +Response 2 +Server: NEW_CB_CALLED,GET_CB_CALLED,SESSIONS:1 diff --git a/ext/openssl/tests/session_resumption_server_external_with_no_verify.phpt b/ext/openssl/tests/session_resumption_server_external_with_no_verify.phpt new file mode 100644 index 000000000000..28bb97faff28 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_external_with_no_verify.phpt @@ -0,0 +1,121 @@ +--TEST-- +TLS session resumption - server external cache callbacks with no verify +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'verify_peer' => false, + 'no_ticket' => true, + 'session_cache' => true, + 'session_new_cb' => function($stream, $session) use (&$sessionStore, &$newCbCalled) { + $key = bin2hex($session->id); + $sessionStore[$key] = $session; + $newCbCalled = true; + }, + 'session_get_cb' => function($stream, $sessionId) use (&$sessionStore, &$getCbCalled) { + $key = bin2hex($sessionId); + $getCbCalled = true; + return $sessionStore[$key] ?? null; + }, + 'session_remove_cb' => function($stream, $sessionId) use (&$sessionStore, &$removeCbCalled) { + $key = bin2hex($sessionId); + unset($sessionStore[$key]); + $removeCbCalled = true; + } + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Response " . ($i + 1) . "\n"); + fclose($client); + } + } + + /* Notify client about callback invocations */ + $result = []; + if ($newCbCalled) $result[] = "NEW_CB_CALLED"; + if ($getCbCalled) $result[] = "GET_CB_CALLED"; + if ($removeCbCalled) $result[] = "REMOVE_CB_CALLED"; + + phpt_notify(message: implode(",", $result)); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Get server callback results */ + $result = phpt_wait(); + echo "Server callbacks: " . trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_server_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Response 1 +Client second connection resumed: yes +Response 2 +Server callbacks: NEW_CB_CALLED,GET_CB_CALLED diff --git a/ext/openssl/tests/session_resumption_server_internal.phpt b/ext/openssl/tests/session_resumption_server_internal.phpt new file mode 100644 index 000000000000..d7c2633601e8 --- /dev/null +++ b/ext/openssl/tests/session_resumption_server_internal.phpt @@ -0,0 +1,99 @@ +--TEST-- +TLS session resumption - server internal cache +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'local_cert' => '%s', + 'session_id_context' => 'test-server', + 'session_cache' => true, + 'session_cache_size' => 1024, + 'session_timeout' => 300, + ]]); + + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, $flags, $ctx); + phpt_notify_server_start($server); + + /* Accept two connections */ + for ($i = 0; $i < 2; $i++) { + $client = @stream_socket_accept($server, 30); + if ($client) { + fwrite($client, "Connection " . ($i + 1) . "\n"); + fclose($client); + } + } + + phpt_notify(message: "SERVER_DONE"); +CODE; +$serverCode = sprintf($serverCode, $certFile); + +$clientCode = <<<'CODE' + $sessionData = null; + + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_new_cb' => function($stream, $session) use (&$sessionData) { + $sessionData = $session; + } + ]]); + + /* First connection */ + $client1 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx); + if ($client1) { + $meta1 = stream_get_meta_data($client1); + echo "Client first connection resumed: " . ($meta1['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client1)) . "\n"; + fclose($client1); + } + + echo "Session data received: " . ($sessionData !== null ? "YES" : "NO") . "\n"; + + /* Second connection with session resumption */ + $ctx2 = stream_context_create(['ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false, + 'session_data' => $sessionData, + ]]); + + $client2 = stream_socket_client("tls://{{ ADDR }}", $errno, $errstr, 30, $flags, $ctx2); + if ($client2) { + $meta2 = stream_get_meta_data($client2); + echo "Client second connection resumed: " . ($meta2['crypto']['session_reused'] ? "yes" : "no") . "\n"; + echo trim(fgets($client2)) . "\n"; + fclose($client2); + } + + /* Wait for server */ + $result = phpt_wait(); + echo trim($result) . "\n"; +CODE; + +include 'CertificateGenerator.inc'; +$certificateGenerator = new CertificateGenerator(); +$certificateGenerator->saveNewCertAsFileWithKey('session_internal_cache_test', $certFile); + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--CLEAN-- + +--EXPECTF-- +Client first connection resumed: no +Connection 1 +Session data received: YES +Client second connection resumed: yes +Connection 2 +SERVER_DONE diff --git a/ext/openssl/tests/sni_server_uk.pem b/ext/openssl/tests/sni_server.pem similarity index 100% rename from ext/openssl/tests/sni_server_uk.pem rename to ext/openssl/tests/sni_server.pem diff --git a/ext/openssl/tests/sni_server.phpt b/ext/openssl/tests/sni_server.phpt index 7f9a4e82872b..db0b0190dab3 100644 --- a/ext/openssl/tests/sni_server.phpt +++ b/ext/openssl/tests/sni_server.phpt @@ -8,13 +8,25 @@ if (!function_exists("proc_open")) die("skip no proc_open"); ?> --FILE-- saveCaCert($caFile); +$certificateGenerator->saveNewCertAsFileWithKey('cs.php.net', $csFile); +$certificateGenerator->saveNewCertAsFileWithKey('uk.php.net', $ukFile); +$certificateGenerator->saveNewCertAsFileWithKey('us.php.net', $usFile); + $serverCode = <<<'CODE' $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ - "cs.php.net" => __DIR__ . "/sni_server_cs.pem", - "uk.php.net" => __DIR__ . "/sni_server_uk.pem", - "us.php.net" => __DIR__ . "/sni_server_us.pem" + "cs.php.net" => '%s', + "uk.php.net" => '%s', + "us.php.net" => '%s', ] ]]); @@ -25,11 +37,12 @@ $serverCode = <<<'CODE' @stream_socket_accept($server, 3); } CODE; +$serverCode = sprintf($serverCode, $csFile, $ukFile, $usFile); $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctxArr = [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', 'capture_peer_cert' => true ]; @@ -51,10 +64,18 @@ $clientCode = <<<'CODE' $cert = stream_context_get_options($ctx)['ssl']['peer_certificate']; var_dump(openssl_x509_parse($cert)['subject']['CN']); CODE; +$clientCode = sprintf($clientCode, $caFile); include 'ServerClientTestCase.inc'; ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> +--CLEAN-- + --EXPECTF-- string(%d) "cs.php.net" string(%d) "uk.php.net" diff --git a/ext/openssl/tests/sni_server_cs_cert.pem b/ext/openssl/tests/sni_server_cs_cert.pem deleted file mode 100644 index b77c7b83e2ad..000000000000 --- a/ext/openssl/tests/sni_server_cs_cert.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjEyWhcNMjYwNDAy -MTgzNjEyWjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKY3MucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAL8uTYc5LcxHbB02xger6mADZrOa59c1xZkyaxpVgsKC -LDZk32ob2ZKwtXAl02e32zwfF0G6QLc9mUlOznMAVvQfKJGFD6Pc4v6bcHK4LELD -dIa3A/DAUVHHHr8IpnuXy74PBPUSf+vMvctwZ0XFVmDtrACvY7k34nTYxE1NwW9O -aF7/A0g/+qJ10LuLlw4LEN3EV3pXfVAdMWs5kF8soiKl3P3KUwJ2hFWM59vGo+zZ -VG8zauddVFzF2OOMfRHF1qT1We4XjXCTc2OQwjc5rVyq7fcojKVkHD1xM7BElcQD -Kom/bkxTpb1V9eyyD8QRuuej40w/SdYepAWzAlMc7O8CAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFHPfd8dK -Lz1R0Ck4WV1B9AWXd5DSMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQB6WSIHEyDXLZxH -hZjqSNQOA7Wc9Z2FCAiD29xYkGTL8WuPVGGP1mu4B92ytj+PMWwqSReDa7eTGLE7 -O7ozw9l+c+gNmHFNikSsGjlV2E8CToQOFMny+jAQYMSXf8UbTp9xDfgG02t/71hv -SLWqdeHMLcR0xi0nBQH0vDOkwUbuWYqFa3jejHieGhykHM6CkIk6lqnyOEO+ooIF -ZsLprrg1ss/mXCPI6niP0hze55ERKdxI7Rk8sZ4pVkf2SUWqZrUS0aJ+Ymmwi6Xd -2V7izq5N30PkJS8MtqII4FAjRBIkwPh0sy8PmW/DzkYU+lYQnDfYLKDFKcj8xJK/ -o8oZUBsQltrSj0KlM9QuqxCTCBCy1nXZ9WHOhq+jdLiTc1Oi60uEHcUMrLK8aYc4 -HqIvZS6C2iwMI0d1OP3VxmAbMQ9yqRi+FbLYavJ3H40jrU9SYqdxa0BrTaz8MJNE -6AEwgQDPChczSghvHME+Fs4mtGCY3TesbNZKVahQRjaFIhMZIZ4RP4CRc0bJOBG+ -8Me4+KHNsD2ki5b03wAN6C1P2QrMzI+gH9fXLZYp761ciDAsX6YIzrhHHYLxYpJH -BkQKKs8dCQWE5IzgVrdlvC3Z1/l9om66wHqqx7nKnPfYs/Sfnwe9MpCD6xJrXiTm -WS7NM6fbQpO9APNr7o0ZOjbbWFzlNw== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_cs.pem b/ext/openssl/tests/sni_server_cs_expired.pem similarity index 100% rename from ext/openssl/tests/sni_server_cs.pem rename to ext/openssl/tests/sni_server_cs_expired.pem diff --git a/ext/openssl/tests/sni_server_cs_key.pem b/ext/openssl/tests/sni_server_cs_key.pem deleted file mode 100644 index bf1e9f25193b..000000000000 --- a/ext/openssl/tests/sni_server_cs_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEAvy5NhzktzEdsHTbGB6vqYANms5rn1zXFmTJrGlWCwoIsNmTf -ahvZkrC1cCXTZ7fbPB8XQbpAtz2ZSU7OcwBW9B8okYUPo9zi/ptwcrgsQsN0hrcD -8MBRUccevwime5fLvg8E9RJ/68y9y3BnRcVWYO2sAK9juTfidNjETU3Bb05oXv8D -SD/6onXQu4uXDgsQ3cRXeld9UB0xazmQXyyiIqXc/cpTAnaEVYzn28aj7NlUbzNq -511UXMXY44x9EcXWpPVZ7heNcJNzY5DCNzmtXKrt9yiMpWQcPXEzsESVxAMqib9u -TFOlvVX17LIPxBG656PjTD9J1h6kBbMCUxzs7wIDAQABAoIBAQC85lBeY0X4ST3v -I7bJz7kWQ2YP4uhfAdeLhoDDFWjNLffniwYhfwEc6xNri0R2f/jUT9gX7qORKwEx -qPdeNCC2t67LElGg1FlJv2Z9Q7MgCKYzkdQH5s6y4e9kTHTLO/JpiceZKz1QTQ3f -XOH9032E6nIAf0wmr6xHTgOwajrN8VI5BuPEMVmEwIw3AtYeqVuPCNKyGR4HUVkC -2bAydnGngbRJRnNzmKcWJancxpHDGBSFqPyuXMFC7Jgo3ZmyCbGp99vuXVk/sW9x -5aj94M9nRE0guk05ivH2/JZao2uLYkIgjFWlhNxKdWgWRk8DEuN4djC8mKS9YH1q -crYRToMhAoGBAOspUTtKP54mpZmyhxuDqj02JaJRzNTskPHsiF1UhtXuw7uT+ryV -ekUFLNXoFmn9mbx1WVaUvGH4qjilvQOxz7u++lz0ApqJEfyM3jc/cC40Y5zcuGSu -Etbg+SyDoytlgMCIydJyrS7NNALSo5p5oG6XY2f8yd/DCAmo8LzypaHRAoGBANAf -R1SlBMc/bOsi6GrJxcBVSCFMiKYiO5woL5aUKa9yM+UQuQ/6xbQ7Q+sOlt0FH3xo -AJ2L60qTdjyXVtjOdtXs5ZC4l+C6AfnCx6yLr+fNc4SOYXEfqS4LZylgwKd9KyVB -asspIW9Idbgebmi6vPyt9LDkIp0h1VuFGjkvQJK/AoGBAI4pbS0dprXyARyYW6sb -fpgAmuG099IkrT9DUfCx/81myTclr2fAKal+BmvOIXaz0/OlMXvw8K19iVIzh7+r -B70lJ+93p/dKM/BsLI5TsHqOO0YB/QsIXOVAHgJ2FfdPJnW+e9vYba+kZ/Po6PSi -4ITaykJ8BIJcQgis89QWEGFxAoGBAJhQO+jzuDKF9ZWEf6ofrw0anOZZ16wWY5/e -PS2rk3JmVxpuibHrKqPDt+ogTELHDAsFJmYmz3VNxHuFmrajK49Wh4/JuMVr/CQo -6+8YcA1qa/94IFIlBLDBAafjujsZvOjQHnM+z8xcsGKmStF00Pjv6qNG4xoyd646 -FD4DmfOLAoGAWXehpopZKXE9gRAni881ucK6WqxPPBoofbozi09D0MmfarIVaSkv -jNVVHBfLWd7IEXTjiipPBeUqq6Jc3pscN1Vp4rrl8jTmVTdazEv0LuzpdUFqmNo2 -M+xw17uz9D9Q32/aW1Lar0PdIaL/wGEDEyzEBFwrGppcENLilPz8gzU= ------END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/sni_server_key_cert.phpt b/ext/openssl/tests/sni_server_key_cert.phpt index 49ed6aa5328c..878f97c1e359 100644 --- a/ext/openssl/tests/sni_server_key_cert.phpt +++ b/ext/openssl/tests/sni_server_key_cert.phpt @@ -8,21 +8,36 @@ if (!function_exists("proc_open")) die("skip no proc_open"); ?> --FILE-- saveCaCert($caFile); +$certificateGenerator->saveNewCertAndKey('cs.php.net', $csCertFile, $csKeyFile); +$certificateGenerator->saveNewCertAndKey('uk.php.net', $ukCertFile, $ukKeyFile); +$certificateGenerator->saveNewCertAndKey('us.php.net', $usCertFile, $usKeyFile); + $serverCode = <<<'CODE' $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; $ctx = stream_context_create(['ssl' => [ 'SNI_server_certs' => [ "cs.php.net" => [ - 'local_cert' => __DIR__ . "/sni_server_cs_cert.pem", - 'local_pk' => __DIR__ . "/sni_server_cs_key.pem" + 'local_cert' => '%s', + 'local_pk' => '%s', ], "uk.php.net" => [ - 'local_cert' => __DIR__ . "/sni_server_uk_cert.pem", - 'local_pk' => __DIR__ . "/sni_server_uk_key.pem" + 'local_cert' => '%s', + 'local_pk' => '%s', ], "us.php.net" => [ - 'local_cert' => __DIR__ . "/sni_server_us_cert.pem", - 'local_pk' => __DIR__ . "/sni_server_us_key.pem" + 'local_cert' => '%s', + 'local_pk' => '%s', ], ] ]]); @@ -34,11 +49,16 @@ $serverCode = <<<'CODE' @stream_socket_accept($server, 3); } CODE; +$serverCode = sprintf($serverCode, + $csCertFile, $csKeyFile, + $ukCertFile, $ukKeyFile, + $usCertFile, $usKeyFile +); $clientCode = <<<'CODE' $flags = STREAM_CLIENT_CONNECT; $ctxArr = [ - 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'cafile' => '%s', 'capture_peer_cert' => true ]; @@ -60,10 +80,21 @@ $clientCode = <<<'CODE' $cert = stream_context_get_options($ctx)['ssl']['peer_certificate']; var_dump(openssl_x509_parse($cert)['subject']['CN']); CODE; +$clientCode = sprintf($clientCode, $caFile); include 'ServerClientTestCase.inc'; ServerClientTestCase::getInstance()->run($clientCode, $serverCode); ?> +--CLEAN-- + --EXPECTF-- string(%d) "cs.php.net" string(%d) "uk.php.net" diff --git a/ext/openssl/tests/sni_server_uk_cert.pem b/ext/openssl/tests/sni_server_uk_cert.pem deleted file mode 100644 index 57663855e590..000000000000 --- a/ext/openssl/tests/sni_server_uk_cert.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjMyWhcNMjYwNDAy -MTgzNjMyWjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKdWsucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKzKRXj0jVBzRwolFn7Ej0MR2kE6Q36IBCEiDLhquSYR -Lh1spR0XudSVmRot/Wvz2PawApX4P6qj57scBQ6KL4ULKvSndCZ7F1tdQjEqogYp -n/L8oBhP1dgyDonsewG/PucxC+3Aqzcl3w5Pg7qE+zad42khP7t9TjFAMxc+PxC+ -2as5ZCDJBwfxksCyCQfFWx7eB7p39vGy63k3Izv+UKTZEhbSdT721kb91oXkecpE -EFhihfVYMGMEtC7u2JLSxdkRhWYSMqVCvI2syYsLAUUNH2kgqQF00j2Iddhg3oMA -IiqhpC/n2slHVhp56WE1TsrGC/JgqIvQK9AT4LRxFb8CAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFJK58uJe -Lv8WDOR8TTLUcSxO1zCyMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQDHayU795hFnQNj -fuYV21sEmkSjgtp6X4rV9JfoCp8U2gieL4mizoCPx9Q8HYaAf98hPYTofGUaCSd+ -Xlzd8lhLt9GCU+BsCxGtJocrjOQDhyhkioN8iirQRTtJpRVC6a4RCBGpenOD7Z7C -Z32uGXohzFuigP/J8/SXBdHrlpNSa03iEkkisPR46mbGj06lFVOFHJDNKA3CnQwM -3VfqvZt0ksZi/gAOol8dtrAd3k5JBfJ2BtqsPbycEGAhsGrTK/MeqiFcO8QZiXpN -qf0wZzOMFZJ4HqTiHs4TMMQaDK8c4qfR0l1OE224ijcB5NlqMjGAZabMfHgNZcl7 -fYPX+POsOMaqubv98uoC0PCK8NCTyfB4V/el72EEoVfwKYOxm3eYXBEE2ZNyIci6 -YKYhNa9e2k+cFueYMztV06HTGgkcHcSJATP+3ISTRx3tj1BPmc4O4WAMEMx1E0gg -PaVrBVAylGzt8kaMaOQMBImpsALSfutq6+KtQiu0OTGS3yVUGamV4AyRjuwF1/ZA -kZbjmNEGsf9d2rzS89ckds24QUx0zrfJ56p7lRvyVK/pML7iadv8dUH3fKDDDerD -oocLjOjNxFGN9Woz+kfidA8Siu0zsfQ6CLPlaQrVAVQH4iMuCZraqMc3TqAiUKRj -iHKp6FFrRZmY8W8HEKHv98uGofn+3g== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_uk_key.pem b/ext/openssl/tests/sni_server_uk_key.pem deleted file mode 100644 index 3baa6efd776e..000000000000 --- a/ext/openssl/tests/sni_server_uk_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEArMpFePSNUHNHCiUWfsSPQxHaQTpDfogEISIMuGq5JhEuHWyl -HRe51JWZGi39a/PY9rAClfg/qqPnuxwFDoovhQsq9Kd0JnsXW11CMSqiBimf8vyg -GE/V2DIOiex7Ab8+5zEL7cCrNyXfDk+DuoT7Np3jaSE/u31OMUAzFz4/EL7Zqzlk -IMkHB/GSwLIJB8VbHt4Hunf28bLreTcjO/5QpNkSFtJ1PvbWRv3WheR5ykQQWGKF -9VgwYwS0Lu7YktLF2RGFZhIypUK8jazJiwsBRQ0faSCpAXTSPYh12GDegwAiKqGk -L+fayUdWGnnpYTVOysYL8mCoi9Ar0BPgtHEVvwIDAQABAoIBAGpg7XyWMxpAno/k -XYEWSo0kRJa75CnWW5R6fhJbwjlpglajONQ8czAqGeRARDFeI0lc+3qRJ8FKv7Q2 -f/Z/pNnoEj4liiDWz350X/gdIztgDRVv6rCNFj7QMps/eEuPDo8PZySs5bxCGJ2a -3qLKlE7/za4/xhkMAEPaHppEvFb15dpomqP2Fjqei9afp8tD+xJv9BGtkFIy9acw -94AWQi974kgW7ZzfEf8RqHM0ExKiESCc26knbcBu0tQ892YHggMccUMk/UrVgR5d -vuGOBurlYGLBstSDSKCCe6la4N/FX3FiC3WhVNescnuTZPXcX3zebh7roGjgrTdd -6UJYBIECgYEA09XYihdwW66G9Y09OatzlzBh1Rvzjv2Vl5NmWHHb6vh38H4PcOof -S1pT0JvRzpt8uEs4i+Eda5PyQyp4iGtD+DQ07Dxh2jiixsE3PRFRG2wg2QCgDHnS -6vgV1VOqA/A4on4nhxLZXxhX4YvHaJYlm1bZ+amG+j5XiI/NtHJm9k8CgYEA0NB9 -bAoaZnc06+T8rMaO45boX5SvYsCZbtY3VRl75SrbMal0IKfnXHELVHuei12LmlMs -LuFgG8jGO3+ncxUqMytoGvrmk/cM9tCNbDKVHtFbqz0qt9lkDAwLsBougKnVsNDW -Aae/tz/wYXJct86unfLh0xtvkx5Iz1we4cS1fZECgYA8YR+vfK7R8xUUuIVTAsOX -vHqmO6lYgH87DRCG9S0x9FB7g/LyxEjXOY/aTg+nTDpobUhY1nmESE8tRdXFTI27 -GWZcT3m0sZ/z9u6/wUfVAST7tWnpJHAx+TR/8bDsHnSGHF836O98Y3vpFeZosSNW -+5J1zxRiD5LzocmIPXOLkQKBgEgHApxXx898YwbTj8zRGMysay89DFpV8RboUWHL -To83/y/cMbBp+kZKwAu+MGwGMndjJSRunUY4NRik6c+qh0nrORfFX+++Efy4529g -60scEDC7Apc0J2x4Yze1cED1VD6PaqJbiKffKD2UwyKr6lOVSgwVtKDcm2Tbc9OQ -lMHhAoGBAIPwYVxzWM6I6pr8x2TucpBZZReLytz7uzybMNvbKCrwlETbNNXubnfp -nPuPKzpeRI0y26pIIAbijzFW0MXq+kIu3H7we8TaImsJ1AaQCTYeoLWBVcr6RISk -3d4i7iT35aWCuhPVve0FNIv/u3jrqX2H2C2MXMiLOsw1GFxPvpi4 ------END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/sni_server_us.pem b/ext/openssl/tests/sni_server_us.pem deleted file mode 100644 index 170a8a96e75d..000000000000 --- a/ext/openssl/tests/sni_server_us.pem +++ /dev/null @@ -1,57 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEA1QkC3tiNYDY+ZxMmPbagYUbMpzuXo9mVBvYh86bYZaeB7bts -QCBK+6VD4D2LjR3RszpzmOzhJXjm8j0t+GeRS3OMIM75/BKAnixXicRSIb8zdIPz -JP992vvMq8p46/XftAfBhAMOaCqcD85zpyX4PhfC9733nOyN4yqx58O4UhVTKih6 -W9/ldp3uwSYAW+HyoINnHls/bFO8vv60K5VIhkxK30LHnC5PvByGfuHOgrscEThs -jW0ESqO0+9l88KhGdmLgzvbBlGxNziCMfn0LcFH6p2ITc3foD4LSzGEFtJ92OZi3 -buCOfbFsN7vWHTsEi89fRcCnWGtMwLUx0TCluQIDAQABAoIBAQCnsUQ1Lrl6trhA -Yu6DPbLZX+XQ7jPbonaQ2Ea5iOhmfIjmHdaEU+cyV1EqvseO+Z4MO0KraiuAV79T -h50cIEpa3kW7vbFCHz5nQ/hUVdlg/yT93rASu5rSOctOnz64Xv8Ms948kDtS+9eF -Cbo4JMdX+VRbt4mmWP8HhqAsFACPexEoWxJcIxwFcI24GTGzySjemNjQzbmcVhzM -a4k6n8DolCL1cRS54C5Aaf5g4+IFDgyydcgZXp1lnX3MnqivSNkejnPnY55NcmrH -X3ZWPlAi9GHOJE33uy8bGWnip7Tn4iTt6tJvjz/yP82TGACDg1B8XsKrqsuQLsoU -cNBVGcQBAoGBAPteCgNmuNOpo4SRA1UVRw1WgnE8YtnNA6vYyVcTLSpqabq33UaD -03L9CQsbHtj88U+E8OH24Iqj3U9x7QJfH8DVmWuBrlwez80JsKGnLdViHydjKcAz -H2Cbv+SiWeaWXkFCkN4Jf7k3q0Ew4SG2LOq5PVUy/NB4bilbJD2ExKpZAoGBANj2 -Hpwo35IQ4XfSSsGaCdn+8ajMcNUMMGZ6YkZqmVO4kogqobyrPL/2KE9ol/hlacw6 -U/6Digox5/wqruYfqyM8lqGOq2/0Xf7c4XfiOTS9Na4JN3OGzlyqPvcn2zdqhYFY -iHPu2RqpA+LhCHW9Zs8C1Bp/KAEPdRP6OabqVaphAoGACLrHVj7nBFLL3vq6RuYq -RYhPl2cld7LrAbjRpTiBRQvVCCsCgERrv36SJdSXSanfJ4fSZcaRHb97HBs0w/RR -wfypC1bBm2lmhhRkEfkgWlzCADgtZwNff5dpHqOUw7FNLK8HIO7rhJ8uT2FHMEiH -Xs94FdFjfknwaXdE1u4ZdmECgYEAgxfbkQHFbO2UPqErGGXp0/WOsS6ucpyF1jXW -kbOxZ3vb1jjkNyrEbzzeSHTrdmRYk9UekWeLjfNvt9dWjKfP8V+XqJCbF+9wqCFw -fs6LQEmfWMQq5DwtDqKznwVPGOHdPzVuZZaJSemb9oeAZBwINccAv+3bDyD23hZQ -pYFsN6ECgYEA33QYDNG/spki4D8rlxyxZ+1MdB/efnrGBhO8FsJpG5+AtmYhWgD9 -sl29+3aiRkmDznoy36z+hoeZePILEAKMcbHyXOymixOHPuaZJ95hbvq6sqd6WMAe -w5tHnxlfEuu11zatolk6WiAmTmG3sZpN5Tqloq0Ye4dvlhVKNV3Bn3E= ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjQ0WhcNMjYwNDAy -MTgzNjQ0WjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKdXMucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANUJAt7YjWA2PmcTJj22oGFGzKc7l6PZlQb2IfOm2GWn -ge27bEAgSvulQ+A9i40d0bM6c5js4SV45vI9LfhnkUtzjCDO+fwSgJ4sV4nEUiG/ -M3SD8yT/fdr7zKvKeOv137QHwYQDDmgqnA/Oc6cl+D4Xwve995zsjeMqsefDuFIV -Uyooelvf5Xad7sEmAFvh8qCDZx5bP2xTvL7+tCuVSIZMSt9Cx5wuT7wchn7hzoK7 -HBE4bI1tBEqjtPvZfPCoRnZi4M72wZRsTc4gjH59C3BR+qdiE3N36A+C0sxhBbSf -djmYt27gjn2xbDe71h07BIvPX0XAp1hrTMC1MdEwpbkCAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOXnUeNs -grKQb+EvG36DXjjDDmsFMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQBDLwuLbx75ACSU -5cF2L/D17JEnhlna62MgKNdpNLJSpaofK2Lk2BqsmnQf5JdkrXWMUN/DsmXZc9pq -25XmprfABUP9Cx18KPVqLQ43Z9o+R9xI1Ospt5mrpxGp6l2BHSs/4G69nuPFpcIJ -iabnLYdUk2Z+64lPe4EMBrZH+pj4xn3JA59BACJYNYn0nLaw45DIAyzyLJ0vVSwc -0JtjsztXQov4UqdWXxLRFfe2nEGoK8ZkTJ8ELcCYu6sNSBjw9Ech78uXN1BQOBTK -lhAgN3FKqOp3hqf0umqf35gDvmWwLB/eptUYZ96gBYT0tbPA0P+YsW+iZmamxXma -Odgg8iRcPxKl9bVPt57NLaDy/RQhOxTGXQs1Q2jp7UhzqoZDClwVSDxd6DEppAFA -OZAY+Rsrm7VoCwVQ/1KbcJHmJ/79tArvaWJk3KHLGMpdZq4KwrC3hM8/QxYtyX/6 -cfnXvShBYCdfTGgNlj3t/mNAgp1ZB3s9ClGqRBR/P0Db+ryv5DuxYM6nzEB3Od0y -kT5tHbXDQY+1HCExjOMi7Al0cmC2r3+oxDA4UjGv+npgcfeoxQhXmm/SQRiPdKlb -vT0D594sLoB23jqA9bMehpxEyI7eGjfFUmXwMeu0tJhipvpJI3ogJoM+SCFTyLkc -12cPiz/sR/ALhvhUJXTeUH8wxPjzbA== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_us_cert.pem b/ext/openssl/tests/sni_server_us_cert.pem deleted file mode 100644 index 4452e3c6cfbf..000000000000 --- a/ext/openssl/tests/sni_server_us_cert.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFIjCCAwqgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UEBhMCR0Ix -EDAOBgNVBAgMB0VuZ2xhbmQxEDAOBgNVBAoMB1BIUC5uZXQxEDAOBgNVBAsMB29w -ZW5zc2wxEDAOBgNVBAMMB3BocC5uZXQwHhcNMTgwMTE0MTgzNjQ0WhcNMjYwNDAy -MTgzNjQ0WjBGMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UE -CgwHUEhQLm5ldDETMBEGA1UEAwwKdXMucGhwLm5ldDCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANUJAt7YjWA2PmcTJj22oGFGzKc7l6PZlQb2IfOm2GWn -ge27bEAgSvulQ+A9i40d0bM6c5js4SV45vI9LfhnkUtzjCDO+fwSgJ4sV4nEUiG/ -M3SD8yT/fdr7zKvKeOv137QHwYQDDmgqnA/Oc6cl+D4Xwve995zsjeMqsefDuFIV -Uyooelvf5Xad7sEmAFvh8qCDZx5bP2xTvL7+tCuVSIZMSt9Cx5wuT7wchn7hzoK7 -HBE4bI1tBEqjtPvZfPCoRnZi4M72wZRsTc4gjH59C3BR+qdiE3N36A+C0sxhBbSf -djmYt27gjn2xbDe71h07BIvPX0XAp1hrTMC1MdEwpbkCAwEAAaOCAQkwggEFMAkG -A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVu -U1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOXnUeNs -grKQb+EvG36DXjjDDmsFMGwGA1UdIwRlMGOAFOPK44Eacedv7HbR2Igcbew+4kUa -oUekRTBDMQswCQYDVQQGEwJHQjEQMA4GA1UECAwHRW5nbGFuZDEQMA4GA1UECgwH -UEhQLm5ldDEQMA4GA1UEAwwHcGhwLm5ldIICEAAwDgYDVR0PAQH/BAQDAgWgMBMG -A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQBDLwuLbx75ACSU -5cF2L/D17JEnhlna62MgKNdpNLJSpaofK2Lk2BqsmnQf5JdkrXWMUN/DsmXZc9pq -25XmprfABUP9Cx18KPVqLQ43Z9o+R9xI1Ospt5mrpxGp6l2BHSs/4G69nuPFpcIJ -iabnLYdUk2Z+64lPe4EMBrZH+pj4xn3JA59BACJYNYn0nLaw45DIAyzyLJ0vVSwc -0JtjsztXQov4UqdWXxLRFfe2nEGoK8ZkTJ8ELcCYu6sNSBjw9Ech78uXN1BQOBTK -lhAgN3FKqOp3hqf0umqf35gDvmWwLB/eptUYZ96gBYT0tbPA0P+YsW+iZmamxXma -Odgg8iRcPxKl9bVPt57NLaDy/RQhOxTGXQs1Q2jp7UhzqoZDClwVSDxd6DEppAFA -OZAY+Rsrm7VoCwVQ/1KbcJHmJ/79tArvaWJk3KHLGMpdZq4KwrC3hM8/QxYtyX/6 -cfnXvShBYCdfTGgNlj3t/mNAgp1ZB3s9ClGqRBR/P0Db+ryv5DuxYM6nzEB3Od0y -kT5tHbXDQY+1HCExjOMi7Al0cmC2r3+oxDA4UjGv+npgcfeoxQhXmm/SQRiPdKlb -vT0D594sLoB23jqA9bMehpxEyI7eGjfFUmXwMeu0tJhipvpJI3ogJoM+SCFTyLkc -12cPiz/sR/ALhvhUJXTeUH8wxPjzbA== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_us_key.pem b/ext/openssl/tests/sni_server_us_key.pem deleted file mode 100644 index 8b0d73d7d63e..000000000000 --- a/ext/openssl/tests/sni_server_us_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEA1QkC3tiNYDY+ZxMmPbagYUbMpzuXo9mVBvYh86bYZaeB7bts -QCBK+6VD4D2LjR3RszpzmOzhJXjm8j0t+GeRS3OMIM75/BKAnixXicRSIb8zdIPz -JP992vvMq8p46/XftAfBhAMOaCqcD85zpyX4PhfC9733nOyN4yqx58O4UhVTKih6 -W9/ldp3uwSYAW+HyoINnHls/bFO8vv60K5VIhkxK30LHnC5PvByGfuHOgrscEThs -jW0ESqO0+9l88KhGdmLgzvbBlGxNziCMfn0LcFH6p2ITc3foD4LSzGEFtJ92OZi3 -buCOfbFsN7vWHTsEi89fRcCnWGtMwLUx0TCluQIDAQABAoIBAQCnsUQ1Lrl6trhA -Yu6DPbLZX+XQ7jPbonaQ2Ea5iOhmfIjmHdaEU+cyV1EqvseO+Z4MO0KraiuAV79T -h50cIEpa3kW7vbFCHz5nQ/hUVdlg/yT93rASu5rSOctOnz64Xv8Ms948kDtS+9eF -Cbo4JMdX+VRbt4mmWP8HhqAsFACPexEoWxJcIxwFcI24GTGzySjemNjQzbmcVhzM -a4k6n8DolCL1cRS54C5Aaf5g4+IFDgyydcgZXp1lnX3MnqivSNkejnPnY55NcmrH -X3ZWPlAi9GHOJE33uy8bGWnip7Tn4iTt6tJvjz/yP82TGACDg1B8XsKrqsuQLsoU -cNBVGcQBAoGBAPteCgNmuNOpo4SRA1UVRw1WgnE8YtnNA6vYyVcTLSpqabq33UaD -03L9CQsbHtj88U+E8OH24Iqj3U9x7QJfH8DVmWuBrlwez80JsKGnLdViHydjKcAz -H2Cbv+SiWeaWXkFCkN4Jf7k3q0Ew4SG2LOq5PVUy/NB4bilbJD2ExKpZAoGBANj2 -Hpwo35IQ4XfSSsGaCdn+8ajMcNUMMGZ6YkZqmVO4kogqobyrPL/2KE9ol/hlacw6 -U/6Digox5/wqruYfqyM8lqGOq2/0Xf7c4XfiOTS9Na4JN3OGzlyqPvcn2zdqhYFY -iHPu2RqpA+LhCHW9Zs8C1Bp/KAEPdRP6OabqVaphAoGACLrHVj7nBFLL3vq6RuYq -RYhPl2cld7LrAbjRpTiBRQvVCCsCgERrv36SJdSXSanfJ4fSZcaRHb97HBs0w/RR -wfypC1bBm2lmhhRkEfkgWlzCADgtZwNff5dpHqOUw7FNLK8HIO7rhJ8uT2FHMEiH -Xs94FdFjfknwaXdE1u4ZdmECgYEAgxfbkQHFbO2UPqErGGXp0/WOsS6ucpyF1jXW -kbOxZ3vb1jjkNyrEbzzeSHTrdmRYk9UekWeLjfNvt9dWjKfP8V+XqJCbF+9wqCFw -fs6LQEmfWMQq5DwtDqKznwVPGOHdPzVuZZaJSemb9oeAZBwINccAv+3bDyD23hZQ -pYFsN6ECgYEA33QYDNG/spki4D8rlxyxZ+1MdB/efnrGBhO8FsJpG5+AtmYhWgD9 -sl29+3aiRkmDznoy36z+hoeZePILEAKMcbHyXOymixOHPuaZJ95hbvq6sqd6WMAe -w5tHnxlfEuu11zatolk6WiAmTmG3sZpN5Tqloq0Ye4dvlhVKNV3Bn3E= ------END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/tls_psk_callback_not_callable.phpt b/ext/openssl/tests/tls_psk_callback_not_callable.phpt new file mode 100644 index 000000000000..29382e2a13ab --- /dev/null +++ b/ext/openssl/tests/tls_psk_callback_not_callable.phpt @@ -0,0 +1,46 @@ +--TEST-- +TLS PSK callback option must be a valid callable +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => 'php_openssl_no_such_function', + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECTF-- +caught: psk_client_cb must be a valid callback, %s + diff --git a/ext/openssl/tests/tls_psk_callback_wrong_type.phpt b/ext/openssl/tests/tls_psk_callback_wrong_type.phpt new file mode 100644 index 000000000000..78d950f19974 --- /dev/null +++ b/ext/openssl/tests/tls_psk_callback_wrong_type.phpt @@ -0,0 +1,48 @@ +--TEST-- +TLS PSK client callback returning wrong type raises TypeError +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream) { + /* Returning a string instead of Openssl\Psk|null. */ + return "not a Psk object"; + }, + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (TypeError $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +caught: PSK callback must return Openssl\Psk or null diff --git a/ext/openssl/tests/tls_psk_client_callback_null.phpt b/ext/openssl/tests/tls_psk_client_callback_null.phpt new file mode 100644 index 000000000000..92d970908c8e --- /dev/null +++ b/ext/openssl/tests/tls_psk_client_callback_null.phpt @@ -0,0 +1,45 @@ +--TEST-- +TLS 1.2 PSK: client callback returning null aborts handshake (no shared cipher) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("doesnotmatter", null); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + /* Reject: no PSK to use, no other ciphers offered. */ + return null; + }, + ]]); + $client = @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) + diff --git a/ext/openssl/tests/tls_psk_client_callback_throws.phpt b/ext/openssl/tests/tls_psk_client_callback_throws.phpt new file mode 100644 index 000000000000..13b2d71476c2 --- /dev/null +++ b/ext/openssl/tests/tls_psk_client_callback_throws.phpt @@ -0,0 +1,48 @@ +--TEST-- +TLS PSK client callback throwing exception propagates to stream_socket_client caller +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + throw new RuntimeException('callback boom'); + }, + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (RuntimeException $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +caught: callback boom + diff --git a/ext/openssl/tests/tls_psk_client_no_identity.phpt b/ext/openssl/tests/tls_psk_client_no_identity.phpt new file mode 100644 index 000000000000..bfc8d078ceff --- /dev/null +++ b/ext/openssl/tests/tls_psk_client_no_identity.phpt @@ -0,0 +1,49 @@ +--TEST-- +TLS PSK client callback must return Openssl\Psk with a non-null identity +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk("k", "id"); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + /* No identity supplied. */ + return new Openssl\Psk(str_repeat("\x42", 16)); + }, + ]]); + try { + @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + echo "no exception\n"; + } catch (ValueError $e) { + echo "caught: ", $e->getMessage(), "\n"; + } +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +caught: Client PSK callback must return Openssl\Psk with a non-null identity + diff --git a/ext/openssl/tests/tls_psk_mismatch.phpt b/ext/openssl/tests/tls_psk_mismatch.phpt new file mode 100644 index 000000000000..8fa90d115c5a --- /dev/null +++ b/ext/openssl/tests/tls_psk_mismatch.phpt @@ -0,0 +1,44 @@ +--TEST-- +TLS 1.2 PSK: mismatching key material aborts handshake +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x11", 16), $identity); + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x22", 16), 'id'); + }, + ]]); + $client = @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) + diff --git a/ext/openssl/tests/tls_psk_tls12_basic.phpt b/ext/openssl/tests/tls_psk_tls12_basic.phpt new file mode 100644 index 000000000000..2f2a558c4b40 --- /dev/null +++ b/ext/openssl/tests/tls_psk_tls12_basic.phpt @@ -0,0 +1,62 @@ +--TEST-- +TLS 1.2 PSK basic client/server round-trip +--EXTENSIONS-- +openssl +--SKIPIF-- += 1.1.1 required"); +?> +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, + 'ciphers' => 'PSK', + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + if ($identity === 'client_id') { + return new Openssl\Psk("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"); + } + return null; + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + $client = stream_socket_accept($server, 30); + fwrite($client, "hello-from-server"); + fread($client, 1024); + fclose($client); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, + 'ciphers' => 'PSK', + 'verify_peer' => false, + 'verify_peer_name' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk( + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff", + 'client_id' + ); + }, + ]]); + $client = stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 30, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client !== false); + var_dump(fread($client, 1024)); + fwrite($client, "hello-from-client"); + /* Verify PSK was used (no peer cert) */ + $params = stream_context_get_params($client); + var_dump(isset($params['options']['ssl']['peer_certificate'])); + fclose($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(true) +string(17) "hello-from-server" +bool(false) diff --git a/ext/openssl/tests/tls_psk_tls13_basic.phpt b/ext/openssl/tests/tls_psk_tls13_basic.phpt new file mode 100644 index 000000000000..a7642624252a --- /dev/null +++ b/ext/openssl/tests/tls_psk_tls13_basic.phpt @@ -0,0 +1,55 @@ +--TEST-- +TLS 1.3 PSK basic client/server round-trip +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + if ($identity === 'tls13-client') { + return new Openssl\Psk(str_repeat("\x42", 32)); + } + return null; + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + $client = stream_socket_accept($server, 30); + fwrite($client, "tls13-psk-ok"); + fclose($client); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, + 'verify_peer' => false, + 'verify_peer_name' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x42", 32), 'tls13-client'); + }, + ]]); + $client = stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 30, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client !== false); + var_dump(fread($client, 1024)); + /* TLS 1.3 PSK: no peer cert */ + $params = stream_context_get_params($client); + var_dump(isset($params['options']['ssl']['peer_certificate'])); + fclose($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(true) +string(12) "tls13-psk-ok" +bool(false) diff --git a/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt b/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt new file mode 100644 index 000000000000..830c02449dc9 --- /dev/null +++ b/ext/openssl/tests/tls_psk_tls13_unknown_identity.phpt @@ -0,0 +1,44 @@ +--TEST-- +TLS 1.3 PSK: server rejects unknown identity (no cert fallback) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- + [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_SERVER, + 'psk_server_cb' => function ($stream, string $identity): ?Openssl\Psk { + return null; + }, + ]]); + $server = stream_socket_server('tls://127.0.0.1:0', $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $serverCtx); + phpt_notify_server_start($server); + @stream_socket_accept($server, 3); +CODE; + +$clientCode = <<<'CODE' + $clientCtx = stream_context_create(['ssl' => [ + 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, + 'verify_peer' => false, + 'verify_peer_name' => false, + 'psk_client_cb' => function ($stream): ?Openssl\Psk { + return new Openssl\Psk(str_repeat("\x42", 32), 'unknown-id'); + }, + ]]); + $client = @stream_socket_client('tls://{{ ADDR }}', $errno, $errstr, + 5, STREAM_CLIENT_CONNECT, $clientCtx); + var_dump($client); +CODE; + +include __DIR__ . '/ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +bool(false) + diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index e728f647a352..4d0dad20a439 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Daniel Lowrey | @@ -23,10 +21,12 @@ #include "php.h" #include "ext/standard/file.h" -#include "ext/standard/url.h" +#include "ext/uri/php_uri.h" #include "streams/php_streams_int.h" #include "zend_smart_str.h" +#include "zend_exceptions.h" #include "php_openssl.h" +#include "php_openssl_backend.h" #include "php_network.h" #include #include @@ -126,10 +126,6 @@ #define GET_VER_OPT_LONG(_name, _num) \ if (GET_VER_OPT(_name)) _num = zval_get_long(val) -/* Used for peer verification in windows */ -#define PHP_X509_NAME_ENTRY_TO_UTF8(ne, i, out) \ - ASN1_STRING_to_UTF8(&out, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(ne, i))) - #ifdef HAVE_IPV6 /* Used for IPv6 Address peer verification */ #define EXPAND_IPV6_ADDRESS(_str, _bytes) \ @@ -180,6 +176,25 @@ typedef struct _php_openssl_alpn_ctx_t { } php_openssl_alpn_ctx; #endif +/* TLS 1.3 PSK ciphersuite IDs */ +static const unsigned char php_openssl_tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; +static const unsigned char php_openssl_tls13_aes256gcmsha384_id[] = { 0x13, 0x02 }; + +/* Holds PSK callbacks */ +typedef struct _php_openssl_psk_callbacks_t { + int refcount; + zval client_cb; + zval server_cb; +} php_openssl_psk_callbacks_t; + +/* Holds session callback */ +typedef struct _php_openssl_session_callbacks_t { + int refcount; + zval new_cb; + zval get_cb; + zval remove_cb; +} php_openssl_session_callbacks_t; + /* This implementation is very closely tied to the that of the native * sockets implemented in the core. * Don't try this technique in other extensions! @@ -199,6 +214,12 @@ typedef struct _php_openssl_netstream_data_t { #ifdef HAVE_TLS_ALPN php_openssl_alpn_ctx alpn_ctx; #endif + php_openssl_session_callbacks_t *session_callbacks; + php_openssl_psk_callbacks_t *psk_callbacks; + /* Identity buffer for TLS 1.3 client PSK whose lifetime outlives the + * psk_use_session_cb call but OpenSSL doesn't free it, so we own it. */ + unsigned char *psk_identity_buf; + size_t psk_identity_len; char *url_name; unsigned state_set:1; unsigned _spare:31; @@ -237,19 +258,19 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i char esbuf[512]; smart_str ebuf = {0}; unsigned long ecode; - int retry = 1; + bool retry = true; switch(err) { case SSL_ERROR_ZERO_RETURN: /* SSL terminated (but socket may still be active) */ - retry = 0; + retry = false; break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: /* re-negotiation, or perhaps the SSL layer needs more * packets: retry in next iteration */ errno = EAGAIN; - retry = is_init ? 1 : sslsock->s.is_blocked; + retry = is_init ? true : sslsock->s.is_blocked; break; case SSL_ERROR_SYSCALL: if (ERR_peek_error() == 0) { @@ -259,7 +280,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i } SSL_set_shutdown(sslsock->ssl_handle, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); stream->eof = 1; - retry = 0; + retry = false; } else { char *estr = php_socket_strerror(php_socket_errno(), NULL, 0); @@ -267,7 +288,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i "SSL: %s", estr); efree(estr); - retry = 0; + retry = false; } break; } @@ -283,7 +304,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i "SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used. " "This could be because the server is missing an SSL certificate " "(local_cert context option)"); - retry = 0; + retry = false; break; default: @@ -308,7 +329,7 @@ static int php_openssl_handle_ssl_error(php_stream *stream, int nr_bytes, bool i } } - retry = 0; + retry = false; errno = 0; } return retry; @@ -358,7 +379,7 @@ static int php_openssl_x509_fingerprint_cmp(X509 *peer, const char *method, cons zend_string *fingerprint; int result = -1; - fingerprint = php_openssl_x509_fingerprint(peer, method, 0); + fingerprint = php_openssl_x509_fingerprint(peer, method, false); if (fingerprint) { result = strcasecmp(expected, ZSTR_VAL(fingerprint)); zend_string_release_ex(fingerprint, 0); @@ -389,47 +410,47 @@ static bool php_openssl_x509_fingerprint_match(X509 *peer, zval *val) if (!zend_hash_num_elements(Z_ARRVAL_P(val))) { php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required"); - return 0; + return false; } ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), key, current) { if (key == NULL || Z_TYPE_P(current) != IS_STRING) { php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint array; [algo => fingerprint] form required"); - return 0; + return false; } if (php_openssl_x509_fingerprint_cmp(peer, ZSTR_VAL(key), Z_STRVAL_P(current)) != 0) { - return 0; + return false; } } ZEND_HASH_FOREACH_END(); - return 1; + return true; } else { php_error_docref(NULL, E_WARNING, "Invalid peer_fingerprint value; fingerprint string or array of the form [algo => fingerprint] required"); } - return 0; + return false; } static bool php_openssl_matches_wildcard_name(const char *subjectname, const char *certname) /* {{{ */ { - char *wildcard = NULL; + const char *wildcard = NULL; ptrdiff_t prefix_len; size_t suffix_len, subject_len; if (strcasecmp(subjectname, certname) == 0) { - return 1; + return true; } /* wildcard, if present, must only be present in the left-most component */ if (!(wildcard = strchr(certname, '*')) || memchr(certname, '.', wildcard - certname)) { - return 0; + return false; } /* 1) prefix, if not empty, must match subject */ prefix_len = wildcard - certname; if (prefix_len && strncasecmp(subjectname, certname, prefix_len) != 0) { - return 0; + return false; } suffix_len = strlen(wildcard + 1); @@ -442,7 +463,7 @@ static bool php_openssl_matches_wildcard_name(const char *subjectname, const cha memchr(subjectname + prefix_len, '.', subject_len - suffix_len - prefix_len) == NULL; } - return 0; + return false; } /* }}} */ @@ -472,7 +493,10 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i); if (san->type == GEN_DNS) { - ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName); + if (ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName) < 0) { + /* TODO: warn ? */ + continue; + } if ((size_t)ASN1_STRING_length(san->d.dNSName) != strlen((const char*)cert_name)) { OPENSSL_free(cert_name); /* prevent null-byte poisoning*/ @@ -489,31 +513,31 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / OPENSSL_free(cert_name); sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); - return 1; + return true; } OPENSSL_free(cert_name); } else if (san->type == GEN_IPADD) { - if (san->d.iPAddress->length == 4) { + if (ASN1_STRING_length(san->d.iPAddress) == 4) { snprintf(ipbuffer, sizeof(ipbuffer), "%d.%d.%d.%d", - san->d.iPAddress->data[0], - san->d.iPAddress->data[1], - san->d.iPAddress->data[2], - san->d.iPAddress->data[3] + ASN1_STRING_get0_data(san->d.iPAddress)[0], + ASN1_STRING_get0_data(san->d.iPAddress)[1], + ASN1_STRING_get0_data(san->d.iPAddress)[2], + ASN1_STRING_get0_data(san->d.iPAddress)[3] ); if (strcasecmp(subject_name, (const char*)ipbuffer) == 0) { sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); - return 1; + return true; } } #ifdef HAVE_IPV6_SAN - else if (san->d.ip->length == 16 && subject_name_is_ipv6) { + else if (ASN1_STRING_length(san->d.ip) == 16 && subject_name_is_ipv6) { ipbuffer[0] = 0; - EXPAND_IPV6_ADDRESS(ipbuffer, san->d.iPAddress->data); + EXPAND_IPV6_ADDRESS(ipbuffer, ASN1_STRING_get0_data(san->d.iPAddress)); if (strcasecmp((const char*)subject_name_ipv6_expanded, (const char*)ipbuffer) == 0) { sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); - return 1; + return true; } } #endif @@ -522,7 +546,7 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) / sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); - return 0; + return false; } /* }}} */ @@ -530,7 +554,7 @@ static bool php_openssl_matches_common_name(X509 *peer, const char *subject_name { char buf[1024]; X509_NAME *cert_name; - bool is_match = 0; + bool is_match = false; int cert_name_len; cert_name = X509_get_subject_name(peer); @@ -541,7 +565,7 @@ static bool php_openssl_matches_common_name(X509 *peer, const char *subject_name } else if ((size_t)cert_name_len != strlen(buf)) { php_error_docref(NULL, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf); } else if (php_openssl_matches_wildcard_name(subject_name, buf)) { - is_match = 1; + is_match = true; } else { php_error_docref(NULL, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", @@ -677,7 +701,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, php_stream *stream; php_openssl_netstream_data_t *sslsock; zval *val; - bool is_self_signed = 0; + bool is_self_signed = false; stream = (php_stream*)arg; @@ -738,7 +762,7 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, /* check if the cert is self-signed */ if (cert_chain_ctx->cChain > 0 && cert_chain_ctx->rgpChain[0]->cElement > 0 && (cert_chain_ctx->rgpChain[0]->rgpElement[0]->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) != 0) { - is_self_signed = 1; + is_self_signed = true; } /* check the depth */ @@ -850,13 +874,14 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c add_cert: { BIO_puts(buffer, line); efree(line); - cert = PEM_read_bio_X509(buffer, NULL, 0, NULL); + cert = php_openssl_pem_read_bio_x509(buffer); BIO_free(buffer); buffer_active = 0; if (cert && X509_STORE_add_cert(cert_store, cert)) { ++certs_added; - X509_free(cert); } + /* TODO: notify user when adding certificate failed? */ + X509_free(cert); goto cert_start; } @@ -878,16 +903,16 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c static zend_result php_openssl_enable_peer_verification(SSL_CTX *ctx, php_stream *stream) /* {{{ */ { zval *val = NULL; - char *cafile = NULL; - char *capath = NULL; + const char *cafile = NULL; + const char *capath = NULL; php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract; GET_VER_OPT_STRING("cafile", cafile); GET_VER_OPT_STRING("capath", capath); if (cafile == NULL) { - cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0); - cafile = strlen(cafile) ? cafile : NULL; + const zend_string *cafile_str = zend_ini_str_literal("openssl.cafile"); + cafile = ZSTR_LEN(cafile_str) ? ZSTR_VAL(cafile_str) : NULL; } else if (!sslsock->is_client) { /* Servers need to load and assign CA names from the cafile */ STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(cafile); @@ -900,8 +925,8 @@ static zend_result php_openssl_enable_peer_verification(SSL_CTX *ctx, php_stream } if (capath == NULL) { - capath = zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0); - capath = strlen(capath) ? capath : NULL; + const zend_string *capath_str = zend_ini_str_literal("openssl.capath"); + capath = ZSTR_LEN(capath_str) ? ZSTR_VAL(capath_str) : NULL; } if (cafile || capath) { @@ -1301,6 +1326,10 @@ static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_pat /* The hello method is not inherited by SSL structs when assigning a new context * inside the SNI callback, so the just use SSLv23 */ SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); + if (!ctx) { + php_error_docref(NULL, E_WARNING, "Failed to create the SSL context"); + return NULL; + } if (SSL_CTX_use_certificate_chain_file(ctx, cert_path) != 1) { php_error_docref(NULL, E_WARNING, @@ -1324,7 +1353,8 @@ static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_pat } /* }}} */ -static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */ +static zend_result php_openssl_enable_server_sni( + php_stream *stream, php_openssl_netstream_data_t *sslsock, bool verify_peer) { zval *val; zval *current; @@ -1332,7 +1362,7 @@ static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl zend_ulong key_index; int i = 0; char resolved_path_buff[MAXPATHLEN]; - SSL_CTX *ctx; + SSL_CTX *ctx = NULL; /* If the stream ctx disables SNI we're finished here */ if (GET_VER_OPT("SNI_enabled") && !zend_is_true(val)) { @@ -1374,6 +1404,8 @@ static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl return FAILURE; } + ZVAL_DEREF(current); + if (Z_TYPE_P(current) == IS_ARRAY) { zval *local_pk, *local_cert; zend_string *local_pk_str, *local_cert_str; @@ -1428,23 +1460,29 @@ static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl zend_string_release(local_pk_str); ctx = php_openssl_create_sni_server_ctx(resolved_cert_path_buff, resolved_pk_path_buff); - - } else if (php_openssl_check_path_str_ex( - Z_STR_P(current), resolved_path_buff, 0, false, false, - "SNI_server_certs in ssl stream context")) { - ctx = php_openssl_create_sni_server_ctx(resolved_path_buff, resolved_path_buff); + } else if (Z_TYPE_P(current) == IS_STRING) { + if (php_openssl_check_path_str_ex(Z_STR_P(current), resolved_path_buff, 0, false, false, "SNI_server_certs in ssl stream context")) { + ctx = php_openssl_create_sni_server_ctx(resolved_path_buff, resolved_path_buff); + } else { + php_error_docref(NULL, E_WARNING, + "Failed setting local cert chain file `%s'; file not found", + Z_STRVAL_P(current) + ); + } } else { - php_error_docref(NULL, E_WARNING, - "Failed setting local cert chain file `%s'; file not found", - Z_STRVAL_P(current) - ); - return FAILURE; + php_error_docref(NULL, E_WARNING, "SNI_server_certs options values must be of type array|string"); } if (ctx == NULL) { return FAILURE; } + if (!verify_peer) { + php_openssl_disable_peer_verification(ctx, stream); + } else if (FAILURE == php_openssl_enable_peer_verification(ctx, stream)) { + return FAILURE; + } + sslsock->sni_certs[i].name = pestrdup(ZSTR_VAL(key), php_stream_is_persistent(stream)); sslsock->sni_certs[i].ctx = ctx; ++i; @@ -1455,7 +1493,6 @@ static zend_result php_openssl_enable_server_sni(php_stream *stream, php_openssl return SUCCESS; } -/* }}} */ static void php_openssl_enable_client_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */ { @@ -1498,7 +1535,7 @@ static unsigned char *php_openssl_alpn_protos_parse(unsigned short *outlen, cons return NULL; } - out = emalloc(strlen(in) + 1); + out = emalloc(len + 1); for (i = 0; i <= len; ++i) { if (i == len || in[i] == ',') { @@ -1535,251 +1572,1104 @@ static int php_openssl_server_alpn_callback(SSL *ssl_handle, #endif -static zend_result php_openssl_setup_crypto(php_stream *stream, - php_openssl_netstream_data_t *sslsock, - php_stream_xport_crypto_param *cparam) /* {{{ */ +static int php_openssl_get_ctx_stream_data_index(void) { - const SSL_METHOD *method; - int ssl_ctx_options; - int method_flags; - zend_long min_version = 0; - zend_long max_version = 0; - char *cipherlist = NULL; - char *alpn_protocols = NULL; - zval *val; + static int ctx_data_index = -1; + if (ctx_data_index < 0) { + ctx_data_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); + } + return ctx_data_index; +} - if (sslsock->ssl_handle) { - if (sslsock->s.is_blocked) { - php_error_docref(NULL, E_WARNING, "SSL/TLS already set-up for this stream"); - return FAILURE; - } else { - return SUCCESS; +/** + * Build a SSL_SESSION suitable for use as an external PSK in TLS 1.3. + */ +static SSL_SESSION *php_openssl_psk_build_session(SSL *ssl, + const unsigned char *psk, size_t psk_len, const EVP_MD *md) +{ + const SSL_CIPHER *cipher; + + cipher = SSL_CIPHER_find(ssl, php_openssl_tls13_aes128gcmsha256_id); + if (cipher == NULL) { + return NULL; + } + + if (md != NULL && SSL_CIPHER_get_handshake_digest(cipher) != md) { + /* Fallback to SHA384 if SHA256 doesn't match */ + cipher = SSL_CIPHER_find(ssl, php_openssl_tls13_aes256gcmsha384_id); + if (cipher == NULL || SSL_CIPHER_get_handshake_digest(cipher) != md) { + return NULL; } } - ERR_clear_error(); + SSL_SESSION *sess = SSL_SESSION_new(); + if (sess == NULL) { + return NULL; + } - /* We need to do slightly different things based on client/server method - * so let's remember which method was selected */ - sslsock->is_client = cparam->inputs.method & STREAM_CRYPTO_IS_CLIENT; - method_flags = cparam->inputs.method & ~STREAM_CRYPTO_IS_CLIENT; + if (!SSL_SESSION_set1_master_key(sess, psk, psk_len) + || !SSL_SESSION_set_cipher(sess, cipher) + || !SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION)) { + SSL_SESSION_free(sess); + return NULL; + } - method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method(); - sslsock->ctx = SSL_CTX_new(method); + return sess; +} - if (sslsock->ctx == NULL) { - php_error_docref(NULL, E_WARNING, "SSL context creation failure"); - return FAILURE; - } - GET_VER_OPT_LONG("min_proto_version", min_version); - GET_VER_OPT_LONG("max_proto_version", max_version); - method_flags = php_openssl_get_proto_version_flags(method_flags, min_version, max_version); - ssl_ctx_options = SSL_OP_ALL; +/** + * Invoke a user PHP callback (psk_client_cb or psk_server_cb). + */ +static zend_result php_openssl_call_psk_cb(php_stream *stream, zval *cb, + const unsigned char *identity, size_t identity_len, + zval *result) +{ + zval args[2]; + zval retval; + int argc; - if (GET_VER_OPT("no_ticket") && zend_is_true(val)) { - ssl_ctx_options |= SSL_OP_NO_TICKET; - } + ZVAL_RES(&args[0], stream->res); - ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + if (identity != NULL) { + ZVAL_STRINGL(&args[1], (const char *)identity, identity_len); + argc = 2; + } else { + argc = 1; + } -#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF - /* Only for OpenSSL 3+ to keep OpenSSL 1.1.1 behavior */ - ssl_ctx_options |= SSL_OP_IGNORE_UNEXPECTED_EOF; -#endif + ZVAL_UNDEF(&retval); + call_user_function(NULL, NULL, cb, &retval, argc, args); - if (!GET_VER_OPT("disable_compression") || zend_is_true(val)) { - ssl_ctx_options |= SSL_OP_NO_COMPRESSION; + if (identity != NULL) { + zval_ptr_dtor(&args[1]); } - if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) { - php_openssl_disable_peer_verification(sslsock->ctx, stream); - } else if (FAILURE == php_openssl_enable_peer_verification(sslsock->ctx, stream)) { + if (EG(exception)) { + ZVAL_UNDEF(result); return FAILURE; } - /* callback for the passphrase (for localcert) */ - if (GET_VER_OPT("passphrase")) { - SSL_CTX_set_default_passwd_cb_userdata(sslsock->ctx, stream); - SSL_CTX_set_default_passwd_cb(sslsock->ctx, php_openssl_passwd_callback); + if (Z_TYPE(retval) == IS_NULL) { + ZVAL_NULL(result); + return SUCCESS; } - GET_VER_OPT_STRING("ciphers", cipherlist); -#ifndef USE_OPENSSL_SYSTEM_CIPHERS - if (!cipherlist) { - cipherlist = OPENSSL_DEFAULT_STREAM_CIPHERS; + if (!php_openssl_is_psk_ce(&retval)) { + zval_ptr_dtor(&retval); + zend_type_error("PSK callback must return Openssl\\Psk or null"); + ZVAL_UNDEF(result); + return FAILURE; } -#endif - if (cipherlist) { - if (SSL_CTX_set_cipher_list(sslsock->ctx, cipherlist) != 1) { - return FAILURE; - } + + ZVAL_COPY_VALUE(result, &retval); + return SUCCESS; +} + +#ifndef OPENSSL_NO_PSK +/* TLS 1.2 (and below) PSK callbacks. */ + +static unsigned int php_openssl_psk_client_cb(SSL *ssl, const char *hint, + char *identity_out, unsigned int max_identity_len, + unsigned char *psk_out, unsigned int max_psk_len) +{ + (void)hint; /* identity hint deliberately not exposed as it is useless */ + (void)max_identity_len; + (void)max_psk_len; + + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 0; } - if (GET_VER_OPT("security_level")) { - zend_long lval = zval_get_long(val); - if (lval < 0 || lval > 5) { - php_error_docref(NULL, E_WARNING, "Security level must be between 0 and 5"); - } -#ifdef HAVE_SEC_LEVEL - SSL_CTX_set_security_level(sslsock->ctx, lval); -#endif + php_openssl_netstream_data_t *sslsock = + (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || Z_ISUNDEF(sslsock->psk_callbacks->client_cb)) { + return 0; } - GET_VER_OPT_STRING("alpn_protocols", alpn_protocols); - if (alpn_protocols) { -#ifdef HAVE_TLS_ALPN - { - unsigned short alpn_len; - unsigned char *alpn = php_openssl_alpn_protos_parse(&alpn_len, alpn_protocols); + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->client_cb, + NULL, 0, &result) != SUCCESS) { + return 0; + } - if (alpn == NULL) { - php_error_docref(NULL, E_WARNING, "Failed parsing comma-separated TLS ALPN protocol string"); - SSL_CTX_free(sslsock->ctx); - sslsock->ctx = NULL; - return FAILURE; - } - if (sslsock->is_client) { - SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len); - } else { - sslsock->alpn_ctx.data = (unsigned char *) pestrndup((const char*)alpn, alpn_len, php_stream_is_persistent(stream)); - sslsock->alpn_ctx.len = alpn_len; - SSL_CTX_set_alpn_select_cb(sslsock->ctx, php_openssl_server_alpn_callback, sslsock); - } + if (Z_TYPE(result) == IS_NULL) { + return 0; + } - efree(alpn); - } -#else - php_error_docref(NULL, E_WARNING, - "alpn_protocols support is not compiled into the OpenSSL library against which PHP is linked"); -#endif + zend_string *psk_str = php_openssl_psk_get_psk(&result); + zend_string *identity_str = php_openssl_psk_get_identity(&result); + + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; } - if (FAILURE == php_openssl_set_local_cert(sslsock->ctx, stream)) { - return FAILURE; + if (identity_str == NULL) { + zval_ptr_dtor(&result); + zend_value_error("Client PSK callback must return Openssl\\Psk with a non-null identity"); + return 0; } - SSL_CTX_set_options(sslsock->ctx, ssl_ctx_options); + memcpy(identity_out, ZSTR_VAL(identity_str), ZSTR_LEN(identity_str)); + identity_out[ZSTR_LEN(identity_str)] = '\0'; + memcpy(psk_out, ZSTR_VAL(psk_str), ZSTR_LEN(psk_str)); - SSL_CTX_set_min_proto_version(sslsock->ctx, php_openssl_get_min_proto_version(method_flags)); - SSL_CTX_set_max_proto_version(sslsock->ctx, php_openssl_get_max_proto_version(method_flags)); + unsigned int psk_len = (unsigned int)ZSTR_LEN(psk_str); + zval_ptr_dtor(&result); + return psk_len; +} - if (sslsock->is_client == 0 && - PHP_STREAM_CONTEXT(stream) && - FAILURE == php_openssl_set_server_specific_opts(stream, sslsock->ctx) - ) { - return FAILURE; - } +static unsigned int php_openssl_psk_server_cb(SSL *ssl, const char *identity, + unsigned char *psk_out, unsigned int max_psk_len) +{ + (void)max_psk_len; - sslsock->ssl_handle = SSL_new(sslsock->ctx); + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 0; + } - if (sslsock->ssl_handle == NULL) { - php_error_docref(NULL, E_WARNING, "SSL handle creation failure"); - SSL_CTX_free(sslsock->ctx); - sslsock->ctx = NULL; -#ifdef HAVE_TLS_ALPN - if (sslsock->alpn_ctx.data) { - pefree(sslsock->alpn_ctx.data, php_stream_is_persistent(stream)); - sslsock->alpn_ctx.data = NULL; - } -#endif - return FAILURE; - } else { - SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream); + php_openssl_netstream_data_t *sslsock = + (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || Z_ISUNDEF(sslsock->psk_callbacks->server_cb)) { + return 0; } - if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) { - php_openssl_handle_ssl_error(stream, 0, 1); + if (SSL_version(ssl) >= TLS1_3_VERSION) { + return 0; } -#ifdef HAVE_TLS_SNI - /* Enable server-side SNI */ - if (!sslsock->is_client && php_openssl_enable_server_sni(stream, sslsock) == FAILURE) { - return FAILURE; + if (identity == NULL) { + return 0; } -#endif - /* Enable server-side handshake renegotiation rate-limiting */ - if (!sslsock->is_client) { - php_openssl_init_server_reneg_limit(stream, sslsock); + size_t identity_len = strlen(identity); + + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->server_cb, + (const unsigned char *)identity, identity_len, &result) != SUCCESS) { + return 0; } -#ifdef SSL_MODE_RELEASE_BUFFERS - SSL_set_mode(sslsock->ssl_handle, SSL_MODE_RELEASE_BUFFERS); -#endif + if (Z_TYPE(result) == IS_NULL) { + return 0; + } - if (cparam->inputs.session) { - if (cparam->inputs.session->ops != &php_openssl_socket_ops) { - php_error_docref(NULL, E_WARNING, "Supplied session stream must be an SSL enabled stream"); - } else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) { - php_error_docref(NULL, E_WARNING, "Supplied SSL session stream is not initialized"); - } else { - SSL_copy_session_id(sslsock->ssl_handle, ((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle); - } + zend_string *psk_str = php_openssl_psk_get_psk(&result); + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; } - return SUCCESS; + memcpy(psk_out, ZSTR_VAL(psk_str), ZSTR_LEN(psk_str)); + unsigned int psk_len = (unsigned int)ZSTR_LEN(psk_str); + + zval_ptr_dtor(&result); + return psk_len; } -/* }}} */ +#endif /* OPENSSL_NO_PSK */ -static int php_openssl_capture_peer_certs(php_stream *stream, - php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */ +/* TLS 1.3 PSK callbacks */ + +static int php_openssl_psk_use_session_cb(SSL *ssl, const EVP_MD *md, + const unsigned char **id, size_t *idlen, SSL_SESSION **sess) { - zval *val, zcert; - php_openssl_certificate_object *cert_object; - int cert_captured = 0; + *id = NULL; + *idlen = 0; + *sess = NULL; - if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), - "ssl", "capture_peer_cert")) && - zend_is_true(val) - ) { - object_init_ex(&zcert, php_openssl_certificate_ce); - cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); - cert_object->x509 = peer_cert; + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 1; + } - php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert); - zval_ptr_dtor(&zcert); - cert_captured = 1; + php_openssl_netstream_data_t *sslsock = + (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || Z_ISUNDEF(sslsock->psk_callbacks->client_cb)) { + return 1; } - if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), - "ssl", "capture_peer_cert_chain")) && - zend_is_true(val) - ) { - zval arr; - STACK_OF(X509) *chain; + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->client_cb, + NULL, 0, &result) != SUCCESS) { + return 0; + } - chain = SSL_get_peer_cert_chain(sslsock->ssl_handle); + if (Z_TYPE(result) == IS_NULL) { + return 1; /* user rejected, continue without PSK */ + } - if (chain && sk_X509_num(chain) > 0) { - int i; - array_init(&arr); + zend_string *psk_str = php_openssl_psk_get_psk(&result); + zend_string *identity_str = php_openssl_psk_get_identity(&result); - for (i = 0; i < sk_X509_num(chain); i++) { - X509 *mycert = X509_dup(sk_X509_value(chain, i)); + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; + } - object_init_ex(&zcert, php_openssl_certificate_ce); - cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); - cert_object->x509 = mycert; - add_next_index_zval(&arr, &zcert); - } + if (identity_str == NULL) { + zval_ptr_dtor(&result); + zend_value_error("Client PSK callback must return Openssl\\Psk with a non-null identity"); + return 0; + } - } else { - ZVAL_NULL(&arr); + SSL_SESSION *session = php_openssl_psk_build_session(ssl, + (const unsigned char *)ZSTR_VAL(psk_str), ZSTR_LEN(psk_str), md); + if (session == NULL) { + zval_ptr_dtor(&result); + if (md != NULL) { + /* Could not satisfy the server's chosen digest */ + return 1; } + return 0; + } - php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate_chain", &arr); - zval_ptr_dtor(&arr); + /* Identity buffer must outlive this callback. */ + if (sslsock->psk_identity_buf == NULL) { + sslsock->psk_identity_buf = emalloc(PHP_OPENSSL_PSK_MAX_IDENTITY_LEN); } + memcpy(sslsock->psk_identity_buf, ZSTR_VAL(identity_str), ZSTR_LEN(identity_str)); + sslsock->psk_identity_len = ZSTR_LEN(identity_str); - return cert_captured; + *id = sslsock->psk_identity_buf; + *idlen = sslsock->psk_identity_len; + *sess = session; + + zval_ptr_dtor(&result); + return 1; } -/* }}} */ -static zend_result php_openssl_set_blocking(php_openssl_netstream_data_t *sslsock, int block) +static int php_openssl_psk_find_session_cb(SSL *ssl, const unsigned char *identity, + size_t identity_len, SSL_SESSION **sess) { - zend_result result = php_set_sock_blocking(sslsock->s.socket, block); - if (EXPECTED(SUCCESS == result)) { + *sess = NULL; + + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, + php_openssl_get_ssl_stream_data_index()); + if (stream == NULL) { + return 1; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (sslsock == NULL || sslsock->psk_callbacks == NULL + || Z_ISUNDEF(sslsock->psk_callbacks->server_cb)) { + return 1; + } + + zval result; + if (php_openssl_call_psk_cb(stream, &sslsock->psk_callbacks->server_cb, + identity, identity_len, &result) != SUCCESS) { + return 0; + } + + if (Z_TYPE(result) == IS_NULL) { + return 1; /* identity unknown - let handshake fall through */ + } + + zend_string *psk_str = php_openssl_psk_get_psk(&result); + if (psk_str == NULL) { + zval_ptr_dtor(&result); + return 0; + } + + SSL_SESSION *session = php_openssl_psk_build_session(ssl, + (const unsigned char *)ZSTR_VAL(psk_str), ZSTR_LEN(psk_str), NULL); + + zval_ptr_dtor(&result); + + if (session == NULL) { + return 0; + } + + *sess = session; + return 1; +} + +/* PSK setup */ + +static zend_result php_openssl_validate_and_allocate_psk_callback( + php_openssl_netstream_data_t *sslsock, zval *callable, + const char *callback_name, bool is_persistent) +{ + if (is_persistent) { + php_error_docref(NULL, E_WARNING, + "%s is not supported for persistent streams", callback_name); + return FAILURE; + } + + char *is_callable_error = NULL; + if (!zend_is_callable_ex(callable, NULL, 0, NULL, NULL, &is_callable_error)) { + if (is_callable_error) { + zend_type_error("%s must be a valid callback, %s", + callback_name, is_callable_error); + efree(is_callable_error); + } else { + zend_type_error("%s must be a valid callback", callback_name); + } + return FAILURE; + } + + if (!sslsock->psk_callbacks) { + sslsock->psk_callbacks = (php_openssl_psk_callbacks_t *)pemalloc( + sizeof(php_openssl_psk_callbacks_t), is_persistent); + ZVAL_UNDEF(&sslsock->psk_callbacks->client_cb); + ZVAL_UNDEF(&sslsock->psk_callbacks->server_cb); + sslsock->psk_callbacks->refcount = 1; + } + + return SUCCESS; +} + +static zend_result php_openssl_setup_client_psk(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + + if (!GET_VER_OPT("psk_client_cb")) { + return SUCCESS; + } + + if (FAILURE == php_openssl_validate_and_allocate_psk_callback( + sslsock, val, "psk_client_cb", php_stream_is_persistent(stream))) { + return FAILURE; + } + + ZVAL_COPY(&sslsock->psk_callbacks->client_cb, val); + +#ifndef OPENSSL_NO_PSK + SSL_CTX_set_psk_client_callback(sslsock->ctx, php_openssl_psk_client_cb); +#endif + SSL_CTX_set_psk_use_session_callback(sslsock->ctx, php_openssl_psk_use_session_cb); + + return SUCCESS; +} + +static zend_result php_openssl_setup_server_psk(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + + if (!GET_VER_OPT("psk_server_cb")) { + return SUCCESS; + } + + if (FAILURE == php_openssl_validate_and_allocate_psk_callback( + sslsock, val, "psk_server_cb", php_stream_is_persistent(stream))) { + return FAILURE; + } + + ZVAL_COPY(&sslsock->psk_callbacks->server_cb, val); + +#ifndef OPENSSL_NO_PSK + SSL_CTX_set_psk_server_callback(sslsock->ctx, php_openssl_psk_server_cb); +#endif + SSL_CTX_set_psk_find_session_callback(sslsock->ctx, php_openssl_psk_find_session_cb); + + if (!GET_VER_OPT("session_id_context")) { + static const unsigned char default_psk_sid_ctx[] = "PHP_PSK"; + SSL_CTX_set_session_id_context(sslsock->ctx, default_psk_sid_ctx, + sizeof(default_psk_sid_ctx) - 1); + } + + return SUCCESS; +} + +/** + * OpenSSL new session callback - called when a new session is established + */ +static int php_openssl_session_new_cb(SSL *ssl, SSL_SESSION *session) +{ + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, php_openssl_get_ssl_stream_data_index()); + if (!stream) { + return 0; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (!sslsock || !sslsock->session_callbacks) { + return 0; + } + + /* Increment reference - we're giving ownership to the PHP object */ + SSL_SESSION_up_ref(session); + + zval args[2]; + zval retval; + + ZVAL_RES(&args[0], stream->res); + php_openssl_session_object_init(&args[1], session); + + if (call_user_function(EG(function_table), NULL, &sslsock->session_callbacks->new_cb, + &retval, 2, args) == SUCCESS) { + zval_ptr_dtor(&retval); + } + + zval_ptr_dtor(&args[1]); + + return 0; +} + +/** + * OpenSSL get session callback - called when server needs to retrieve a session + */ +static SSL_SESSION *php_openssl_session_get_cb(SSL *ssl, const unsigned char *session_id, + int session_id_len, int *copy) +{ + php_stream *stream = (php_stream *)SSL_get_ex_data(ssl, php_openssl_get_ssl_stream_data_index()); + if (!stream) { + *copy = 0; + return NULL; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (!sslsock || !sslsock->session_callbacks) { + *copy = 0; + return NULL; + } + + zval args[2]; + zval retval; + + ZVAL_RES(&args[0], stream->res); + ZVAL_STRINGL(&args[1], (char *)session_id, session_id_len); + + SSL_SESSION *session = NULL; + + if (call_user_function(EG(function_table), NULL, &sslsock->session_callbacks->get_cb, + &retval, 2, args) == SUCCESS) { + if (php_openssl_is_session_ce(&retval)) { + /* Get session from object and increment ref since OpenSSL will own it */ + php_openssl_session_object *obj = Z_OPENSSL_SESSION_P(&retval); + if (obj->session) { + SSL_SESSION_up_ref(obj->session); + session = obj->session; + } + zval_ptr_dtor(&retval); + } else if (Z_TYPE(retval) != IS_NULL) { + zend_type_error("session_get_cb return type must be null or OpenSSLSession"); + return NULL; + } + } + + zval_ptr_dtor(&args[1]); + + *copy = 0; + return session; +} + +/** + * OpenSSL remove session callback - called when a session is evicted from cache + */ +static void php_openssl_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *session) +{ + php_stream *stream = (php_stream *)SSL_CTX_get_ex_data(ctx, php_openssl_get_ctx_stream_data_index()); + if (!stream) { + return; + } + + php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract; + if (!sslsock || !sslsock->session_callbacks) { + return; + } + + unsigned int session_id_len = 0; + const unsigned char *session_id = SSL_SESSION_get_id(session, &session_id_len); + + zval args[2]; + zval retval; + + ZVAL_RES(&args[0], stream->res); + ZVAL_STRINGL(&args[1], (char *)session_id, session_id_len); + + if (call_user_function(EG(function_table), NULL, &sslsock->session_callbacks->remove_cb, + &retval, 2, args) == SUCCESS) { + zval_ptr_dtor(&retval); + } + + zval_ptr_dtor(&args[1]); +} + +/** + * Validate callable and allocate callback structure if needed. + */ +static zend_result php_openssl_validate_and_allocate_callback( + php_openssl_netstream_data_t *sslsock, zval *callable, + const char *callback_name, bool is_persistent) +{ + zend_fcall_info_cache fcc; + char *is_callable_error = NULL; + + /* Callbacks not supported for persistent streams */ + if (is_persistent) { + php_error_docref(NULL, E_WARNING, + "%s is not supported for persistent streams", callback_name); + return FAILURE; + } + + /* Validate callable */ + if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, &is_callable_error)) { + if (is_callable_error) { + zend_type_error("%s must be a valid callback, %s", callback_name, is_callable_error); + efree(is_callable_error); + } else { + zend_type_error("%s must be a valid callback", callback_name); + } + return FAILURE; + } + + /* Allocate callback structure if not already allocated */ + if (!sslsock->session_callbacks) { + sslsock->session_callbacks = (php_openssl_session_callbacks_t *)pemalloc( + sizeof(php_openssl_session_callbacks_t), is_persistent); + ZVAL_UNDEF(&sslsock->session_callbacks->new_cb); + ZVAL_UNDEF(&sslsock->session_callbacks->get_cb); + ZVAL_UNDEF(&sslsock->session_callbacks->remove_cb); + sslsock->session_callbacks->refcount = 1; + } + + return SUCCESS; +} + +/** + * Configure session resumption options for client connections + */ +static zend_result php_openssl_setup_client_session(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + bool enable_client_cache = false; + bool is_persistent = php_stream_is_persistent(stream); + + if (GET_VER_OPT("session_data")) { + if (php_openssl_is_session_ce(val)) { + enable_client_cache = true; + } else if (Z_TYPE_P(val) != IS_NULL) { + zend_type_error("session_data must be an OpenSSLSession instance"); + return FAILURE; + } + } + + if (GET_VER_OPT("session_new_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_callback( + sslsock, val, "session_new_cb", is_persistent)) { + return FAILURE; + } + + ZVAL_COPY(&sslsock->session_callbacks->new_cb, val); + SSL_CTX_sess_set_new_cb(sslsock->ctx, php_openssl_session_new_cb); + enable_client_cache = true; + } + + if (enable_client_cache) { + SSL_CTX_set_session_cache_mode(sslsock->ctx, + SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL); + } + + return SUCCESS; +} + +static bool php_openssl_is_session_cache_enabled(php_stream *stream, bool internal_only) +{ + zval *val; + + if (GET_VER_OPT("session_cache")) { + return zend_is_true(val); + } + + if (internal_only) { + return false; + } + + return GET_VER_OPT("session_get_cb"); +} + +/** + * Configure session resumption options for server connections + */ +static zend_result php_openssl_setup_server_session(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + bool has_get_cb = false; + bool has_new_cb = false; + bool has_remove_cb = false; + bool has_session_id_context = false; + bool is_persistent = php_stream_is_persistent(stream); + + /* Check for session_get_cb first (determines cache mode) */ + if (GET_VER_OPT("session_get_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_callback( + sslsock, val, "session_new_cb", is_persistent)) { + return FAILURE; + } + ZVAL_COPY(&sslsock->session_callbacks->get_cb, val); + has_get_cb = true; + } + + if (GET_VER_OPT("session_id_context")) { + if (Z_TYPE_P(val) != IS_STRING || Z_STRLEN_P(val) == 0) { + zend_type_error("session_id_context must be a non empty string"); + return FAILURE; + } + SSL_CTX_set_session_id_context(sslsock->ctx, (const unsigned char *) Z_STRVAL_P(val), + Z_STRLEN_P(val)); + has_session_id_context = true; + } + + /* Check for session_new_cb */ + if (GET_VER_OPT("session_new_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_callback( + sslsock, val, "session_new_cb", is_persistent)) { + return FAILURE; + } + ZVAL_COPY(&sslsock->session_callbacks->new_cb, val); + has_new_cb = true; + + if (!has_session_id_context && + (SSL_CTX_get_verify_mode(sslsock->ctx) & SSL_VERIFY_PEER) != 0) { + zend_value_error("session_id_context must be set if session_new_cb is set"); + return FAILURE; + } + } + + /* Validate: if session_get_cb is provided, session_new_cb is required */ + if (has_get_cb && !has_new_cb) { + zend_value_error("session_new_cb is required when session_get_cb is provided"); + return FAILURE; + } + + /* Check for session_remove_cb (optional) */ + if (GET_VER_OPT("session_remove_cb")) { + if (FAILURE == php_openssl_validate_and_allocate_callback( + sslsock, val, "session_remove_cb", is_persistent)) { + return FAILURE; + } + + ZVAL_COPY(&sslsock->session_callbacks->remove_cb, val); + has_remove_cb = true; + } + + /* Configure cache mode based on whether external callbacks are provided */ + if (has_get_cb) { + /* External cache mode - disable internal cache */ + SSL_CTX_set_session_cache_mode(sslsock->ctx, + SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL); + + /* Set callbacks */ + SSL_CTX_sess_set_new_cb(sslsock->ctx, php_openssl_session_new_cb); + SSL_CTX_sess_set_get_cb(sslsock->ctx, php_openssl_session_get_cb); + + if (has_remove_cb) { + SSL_CTX_sess_set_remove_cb(sslsock->ctx, php_openssl_session_remove_cb); + } + + // Disable tickets (they won't work anyway) and warn if explicity enabled + SSL_CTX_set_options(sslsock->ctx, SSL_OP_NO_TICKET); + if (GET_VER_OPT("no_ticket") && !zend_is_true(val)) { + zend_value_error("Session tickets cannot be enabled when session_get_cb is set"); + } + } else if (php_openssl_is_session_cache_enabled(stream, true)) { + if (!has_session_id_context && + (SSL_CTX_get_verify_mode(sslsock->ctx) & SSL_VERIFY_PEER) != 0) { + zend_value_error("session_id_context must be set for internal session cache"); + } + + /* Internal cache mode */ + SSL_CTX_set_session_cache_mode(sslsock->ctx, SSL_SESS_CACHE_SERVER); + + /* Handle session_cache_size */ + if (GET_VER_OPT("session_cache_size")) { + zend_long cache_size = zval_get_long(val); + if (cache_size > 0) { + SSL_CTX_sess_set_cache_size(sslsock->ctx, cache_size); + } else { + zend_value_error("session_cache_size must be positive"); + } + } else { + /* Default cache size from RFC */ + SSL_CTX_sess_set_cache_size(sslsock->ctx, 20480); + } + + /* Handle session_timeout */ + if (GET_VER_OPT("session_timeout")) { + zend_long timeout = zval_get_long(val); + if (timeout > 0) { + SSL_CTX_set_timeout(sslsock->ctx, timeout); + } else { + zend_value_error("session_timeout must be positive"); + } + } else { + /* Default timeout from RFC */ + SSL_CTX_set_timeout(sslsock->ctx, 300); + } + + /* Optional notification callback for internal cache */ + if (has_new_cb) { + SSL_CTX_sess_set_new_cb(sslsock->ctx, php_openssl_session_new_cb); + } + } else { + /* Session caching disabled */ + SSL_CTX_set_session_cache_mode(sslsock->ctx, SSL_SESS_CACHE_OFF); + } + + return SUCCESS; +} + +static zend_result php_openssl_apply_client_session_data(php_stream *stream, + php_openssl_netstream_data_t *sslsock) +{ + zval *val; + + if (GET_VER_OPT("session_data")) { + SSL_SESSION *session = NULL; + bool needs_free = false; + + if (php_openssl_is_session_ce(val)) { + session = php_openssl_session_from_zval(val); + if (!session) { + php_error_docref(NULL, E_WARNING, + "Invalid OpenSSLSession object, falling back to full handshake"); + return FAILURE; + } + /* Object owns the session, we just borrow it */ + needs_free = false; + } else if (Z_TYPE_P(val) != IS_NULL) { + zend_type_error("session_data must be an OpenSSLSession instance"); + return FAILURE; + } + + if (session) { + if (SSL_set_session(sslsock->ssl_handle, session) != 1) { + php_error_docref(NULL, E_WARNING, + "Failed to set session for resumption, falling back to full handshake"); + if (needs_free) { + SSL_SESSION_free(session); + } + ERR_clear_error(); + return FAILURE; + } + + if (needs_free) { + SSL_SESSION_free(session); + } + } + } + + return SUCCESS; +} + +static zend_result php_openssl_create_server_ctx(php_stream *stream, + php_openssl_netstream_data_t *sslsock, int method_flags) +{ + zval *val; + + const SSL_METHOD *method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method(); + sslsock->ctx = SSL_CTX_new(method); + + if (sslsock->ctx == NULL) { + php_error_docref(NULL, E_WARNING, "SSL context creation failure"); + return FAILURE; + } + + SSL_CTX_set_ex_data(sslsock->ctx, php_openssl_get_ctx_stream_data_index(), stream); + + zend_long min_version = 0; + zend_long max_version = 0; + GET_VER_OPT_LONG("min_proto_version", min_version); + GET_VER_OPT_LONG("max_proto_version", max_version); + method_flags = php_openssl_get_proto_version_flags(method_flags, min_version, max_version); + int ssl_ctx_options = SSL_OP_ALL; + + if (GET_VER_OPT("no_ticket") && zend_is_true(val)) { + ssl_ctx_options |= SSL_OP_NO_TICKET; + } + if (GET_VER_OPT("num_tickets")) { + zend_long num_tickets = zval_get_long(val); + if (num_tickets >= 0) { + SSL_CTX_set_num_tickets(sslsock->ctx, num_tickets); + } + } + + ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + +#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF + /* Only for OpenSSL 3+ to keep OpenSSL 1.1.1 behavior */ + ssl_ctx_options |= SSL_OP_IGNORE_UNEXPECTED_EOF; +#endif + + if (!GET_VER_OPT("disable_compression") || zend_is_true(val)) { + ssl_ctx_options |= SSL_OP_NO_COMPRESSION; + } + + bool verify_peer = false; + if (GET_VER_OPT("verify_peer") && !zend_is_true(val)) { + php_openssl_disable_peer_verification(sslsock->ctx, stream); + } else { + verify_peer = true; + if (FAILURE == php_openssl_enable_peer_verification(sslsock->ctx, stream)) { + return FAILURE; + } + } + + /* callback for the passphrase (for localcert) */ + if (GET_VER_OPT("passphrase")) { + SSL_CTX_set_default_passwd_cb_userdata(sslsock->ctx, stream); + SSL_CTX_set_default_passwd_cb(sslsock->ctx, php_openssl_passwd_callback); + } + + char *cipherlist = NULL; + GET_VER_OPT_STRING("ciphers", cipherlist); +#ifndef USE_OPENSSL_SYSTEM_CIPHERS + if (!cipherlist) { + cipherlist = OPENSSL_DEFAULT_STREAM_CIPHERS; + } +#endif + if (cipherlist) { + if (SSL_CTX_set_cipher_list(sslsock->ctx, cipherlist) != 1) { + return FAILURE; + } + } + + if (GET_VER_OPT("security_level")) { + zend_long lval = zval_get_long(val); + if (lval < 0 || lval > 5) { + php_error_docref(NULL, E_WARNING, "Security level must be between 0 and 5"); + } +#ifdef HAVE_SEC_LEVEL + SSL_CTX_set_security_level(sslsock->ctx, lval); +#endif + } + + char *alpn_protocols = NULL; + GET_VER_OPT_STRING("alpn_protocols", alpn_protocols); + if (alpn_protocols) { +#ifdef HAVE_TLS_ALPN + { + unsigned short alpn_len; + unsigned char *alpn = php_openssl_alpn_protos_parse(&alpn_len, alpn_protocols); + + if (alpn == NULL) { + php_error_docref(NULL, E_WARNING, "Failed parsing comma-separated TLS ALPN protocol string"); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; + return FAILURE; + } + if (sslsock->is_client) { + SSL_CTX_set_alpn_protos(sslsock->ctx, alpn, alpn_len); + } else { + sslsock->alpn_ctx.data = (unsigned char *) pestrndup((const char*)alpn, alpn_len, php_stream_is_persistent(stream)); + sslsock->alpn_ctx.len = alpn_len; + SSL_CTX_set_alpn_select_cb(sslsock->ctx, php_openssl_server_alpn_callback, sslsock); + } + + efree(alpn); + } +#else + php_error_docref(NULL, E_WARNING, + "alpn_protocols support is not compiled into the OpenSSL library against which PHP is linked"); +#endif + } + + if (FAILURE == php_openssl_set_local_cert(sslsock->ctx, stream)) { + return FAILURE; + } + + SSL_CTX_set_options(sslsock->ctx, ssl_ctx_options); + + SSL_CTX_set_min_proto_version(sslsock->ctx, php_openssl_get_min_proto_version(method_flags)); + SSL_CTX_set_max_proto_version(sslsock->ctx, php_openssl_get_max_proto_version(method_flags)); + + + if (sslsock->is_client) { + if (FAILURE == php_openssl_setup_client_session(stream, sslsock)) { + return FAILURE; + } + if (FAILURE == php_openssl_setup_client_psk(stream, sslsock)) { + return FAILURE; + } + } else if (PHP_STREAM_CONTEXT(stream)) { + if (FAILURE == php_openssl_setup_server_session(stream, sslsock)) { + return FAILURE; + } + if (FAILURE == php_openssl_setup_server_psk(stream, sslsock)) { + return FAILURE; + } + if (FAILURE == php_openssl_set_server_specific_opts(stream, sslsock->ctx)) { + return FAILURE; + } + } + +#ifdef HAVE_TLS_SNI + /* Enable server-side SNI */ + if (!sslsock->is_client && php_openssl_enable_server_sni(stream, sslsock, verify_peer) == FAILURE) { + return FAILURE; + } +#endif + + return SUCCESS; +} + +static zend_result php_openssl_setup_crypto(php_stream *stream, + php_openssl_netstream_data_t *sslsock, + php_stream_xport_crypto_param *cparam) /* {{{ */ +{ + if (sslsock->ssl_handle) { + if (sslsock->s.is_blocked) { + php_error_docref(NULL, E_WARNING, "SSL/TLS already set-up for this stream"); + return FAILURE; + } else { + return SUCCESS; + } + } + + ERR_clear_error(); + + /* We need to do slightly different things based on client/server method + * so let's remember which method was selected */ + sslsock->is_client = cparam->inputs.method & STREAM_CRYPTO_IS_CLIENT; + int method_flags = cparam->inputs.method & ~STREAM_CRYPTO_IS_CLIENT; + + /* Re-use SSL_CTX if session is set */ + if (cparam->inputs.session) { + php_openssl_netstream_data_t *parent_sslsock; + + if (cparam->inputs.session->ops != &php_openssl_socket_ops) { + php_error_docref(NULL, E_WARNING, "Supplied session stream must be an SSL enabled stream"); + } else if ((parent_sslsock = cparam->inputs.session->abstract)->ctx == NULL) { + php_error_docref(NULL, E_WARNING, "Supplied SSL session stream is not set up"); + } else if (sslsock->is_client && parent_sslsock->ssl_handle == NULL) { + php_error_docref(NULL, E_WARNING, "Supplied SSL session stream is not initialized"); + } else { + SSL_CTX_up_ref(parent_sslsock->ctx); + sslsock->ctx = parent_sslsock->ctx; + if (parent_sslsock->session_callbacks) { + parent_sslsock->session_callbacks->refcount++; + sslsock->session_callbacks = parent_sslsock->session_callbacks; + } + if (parent_sslsock->psk_callbacks) { + parent_sslsock->psk_callbacks->refcount++; + sslsock->psk_callbacks = parent_sslsock->psk_callbacks; + } + + sslsock->ssl_handle = SSL_new(sslsock->ctx); + if (!sslsock->ssl_handle) { + php_error_docref(NULL, E_WARNING, "SSL handle creation failure"); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; + return FAILURE; + } + + SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream); + + if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) { + php_openssl_handle_ssl_error(stream, 0, true); + } + + if (sslsock->is_client) { + if (SSL_copy_session_id(sslsock->ssl_handle, parent_sslsock->ssl_handle)) { + SSL_CTX_set_session_cache_mode(sslsock->ctx, SSL_SESS_CACHE_CLIENT); + } else { + php_error_docref(NULL, E_WARNING, "SSL session copying failed creation failure"); + } + } + + return SUCCESS; + } + } + + if (php_openssl_create_server_ctx(stream, sslsock, method_flags) == FAILURE) { + return FAILURE; + } + + sslsock->ssl_handle = SSL_new(sslsock->ctx); + + if (sslsock->ssl_handle == NULL + || !SSL_set_ex_data(sslsock->ssl_handle, php_openssl_get_ssl_stream_data_index(), stream)) { + php_error_docref(NULL, E_WARNING, "SSL handle creation failure"); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; +#ifdef HAVE_TLS_ALPN + if (sslsock->alpn_ctx.data) { + pefree(sslsock->alpn_ctx.data, php_stream_is_persistent(stream)); + sslsock->alpn_ctx.data = NULL; + } +#endif + return FAILURE; + } + + if (!SSL_set_fd(sslsock->ssl_handle, sslsock->s.socket)) { + php_openssl_handle_ssl_error(stream, 0, true); + } + + return SUCCESS; +} +/* }}} */ + +static int php_openssl_capture_peer_certs(php_stream *stream, + php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */ +{ + zval *val, zcert; + php_openssl_certificate_object *cert_object; + int cert_captured = 0; + + if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), + "ssl", "capture_peer_cert")) && + zend_is_true(val) + ) { + object_init_ex(&zcert, php_openssl_certificate_ce); + cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); + cert_object->x509 = peer_cert; + + php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert); + zval_ptr_dtor(&zcert); + cert_captured = 1; + } + + if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), + "ssl", "capture_peer_cert_chain")) && + zend_is_true(val) + ) { + zval arr; + STACK_OF(X509) *chain; + + chain = SSL_get_peer_cert_chain(sslsock->ssl_handle); + + if (chain && sk_X509_num(chain) > 0) { + int i; + array_init(&arr); + + for (i = 0; i < sk_X509_num(chain); i++) { + X509 *mycert = X509_dup(sk_X509_value(chain, i)); + + object_init_ex(&zcert, php_openssl_certificate_ce); + cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); + cert_object->x509 = mycert; + add_next_index_zval(&arr, &zcert); + } + + } else { + ZVAL_NULL(&arr); + } + + php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate_chain", &arr); + zval_ptr_dtor(&arr); + } + + return cert_captured; +} +/* }}} */ + +static zend_result php_openssl_set_blocking(php_openssl_netstream_data_t *sslsock, int block) +{ + zend_result result = php_set_sock_blocking(sslsock->s.socket, block); + if (EXPECTED(SUCCESS == result)) { sslsock->s.is_blocked = block; } return result; @@ -1796,12 +2686,24 @@ static int php_openssl_enable_crypto(php_stream *stream, if (cparam->inputs.activate && !sslsock->ssl_active) { struct timeval start_time, *timeout; - int blocked = sslsock->s.is_blocked, has_timeout = 0; + bool blocked = sslsock->s.is_blocked, has_timeout = false; -#ifdef HAVE_TLS_SNI if (sslsock->is_client) { + /* Set session data for client */ + if ( php_openssl_apply_client_session_data(stream, sslsock)) { + return FAILURE; + } +#ifdef HAVE_TLS_SNI php_openssl_enable_client_sni(stream, sslsock); +#endif + } else { + php_openssl_init_server_reneg_limit(stream, sslsock); } + +#ifdef PHP_OPENSSL_TLS_DEBUG + BIO *b_out = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); + SSL_set_msg_callback(sslsock->ssl_handle, SSL_trace); + SSL_set_msg_callback_arg(sslsock->ssl_handle, b_out); #endif if (!sslsock->state_set) { @@ -1813,6 +2715,8 @@ static int php_openssl_enable_crypto(php_stream *stream, sslsock->state_set = 1; } + SSL_set_mode(sslsock->ssl_handle, SSL_MODE_RELEASE_BUFFERS); + if (SUCCESS == php_openssl_set_blocking(sslsock, 0)) { /* The following mode are added only if we are able to change socket * to non blocking mode which is also used for read and write */ @@ -1936,8 +2840,8 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si int retry = 1; struct timeval start_time; struct timeval *timeout = NULL; - int began_blocked = sslsock->s.is_blocked; - int has_timeout = 0; + bool began_blocked = sslsock->s.is_blocked; + bool has_timeout = false; int nr_bytes = 0; /* prevent overflow in openssl */ @@ -1955,7 +2859,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si } if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { - has_timeout = 1; + has_timeout = true; /* gettimeofday is not monotonic; using it here is not strictly correct */ gettimeofday(&start_time, NULL); } @@ -1977,7 +2881,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si if (began_blocked) { php_openssl_set_blocking(sslsock, 1); } - sslsock->s.timeout_event = 1; + sslsock->s.timeout_event = true; return -1; } } @@ -2008,7 +2912,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si /* Get the error code from SSL, and check to see if it's an error or not. */ int err = SSL_get_error(sslsock->ssl_handle, nr_bytes ); - retry = php_openssl_handle_ssl_error(stream, nr_bytes, 0); + retry = php_openssl_handle_ssl_error(stream, nr_bytes, false); /* If we get this (the above doesn't check) then we'll retry as well. */ if (errno == EAGAIN && err == SSL_ERROR_WANT_READ && read) { @@ -2186,6 +3090,23 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle) /* {{{ pefree(sslsock->reneg, php_stream_is_persistent(stream)); } + if (sslsock->session_callbacks && --sslsock->session_callbacks->refcount == 0) { + zval_ptr_dtor(&sslsock->session_callbacks->new_cb); + zval_ptr_dtor(&sslsock->session_callbacks->get_cb); + zval_ptr_dtor(&sslsock->session_callbacks->remove_cb); + pefree(sslsock->session_callbacks, php_stream_is_persistent(stream)); + } + + if (sslsock->psk_callbacks && --sslsock->psk_callbacks->refcount == 0) { + zval_ptr_dtor(&sslsock->psk_callbacks->client_cb); + zval_ptr_dtor(&sslsock->psk_callbacks->server_cb); + pefree(sslsock->psk_callbacks, php_stream_is_persistent(stream)); + } + + if (sslsock->psk_identity_buf) { + efree(sslsock->psk_identity_buf); + } + pefree(sslsock, php_stream_is_persistent(stream)); return 0; @@ -2207,28 +3128,34 @@ static int php_openssl_sockop_stat(php_stream *stream, php_stream_statbuf *ssb) static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_netstream_data_t *sock, php_stream_xport_param *xparam STREAMS_DC) /* {{{ */ { - int clisock; - bool nodelay = 0; + php_sockvals sockvals = {0}; zval *tmpzval = NULL; xparam->outputs.client = NULL; - if (PHP_STREAM_CONTEXT(stream) && - (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "tcp_nodelay")) != NULL && - zend_is_true(tmpzval)) { - nodelay = 1; + if (PHP_STREAM_CONTEXT(stream)) { + tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "tcp_nodelay"); + if (tmpzval != NULL && zend_is_true(tmpzval)) { + sockvals.mask |= PHP_SOCKVAL_TCP_NODELAY; + sockvals.tcp_nodelay = 1; + } + tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "tcp_keepidle"); + if (tmpzval != NULL) { + sockvals.mask |= PHP_SOCKVAL_TCP_KEEPIDLE; + sockvals.keepalive.keepidle = (int)zval_get_long(tmpzval); + } } - clisock = php_network_accept_incoming(sock->s.socket, + php_socket_t clisock = php_network_accept_incoming_ex(sock->s.socket, xparam->want_textaddr ? &xparam->outputs.textaddr : NULL, xparam->want_addr ? &xparam->outputs.addr : NULL, xparam->want_addr ? &xparam->outputs.addrlen : NULL, xparam->inputs.timeout, xparam->want_errortext ? &xparam->outputs.error_text : NULL, &xparam->outputs.error_code, - nodelay); + &sockvals); - if (clisock >= 0) { + if (clisock != SOCK_ERR) { php_openssl_netstream_data_t *clisockdata = (php_openssl_netstream_data_t*) emalloc(sizeof(*clisockdata)); /* copy underlying tcp fields */ @@ -2238,7 +3165,7 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ clisockdata->s.socket = clisock; #ifdef __linux__ /* O_NONBLOCK is not inherited on Linux */ - clisockdata->s.is_blocked = 1; + clisockdata->s.is_blocked = true; #endif xparam->outputs.client = php_stream_alloc_rel(stream->ops, clisockdata, NULL, "r+"); @@ -2256,13 +3183,19 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ clisockdata->method = sock->method; if (php_stream_xport_crypto_setup(xparam->outputs.client, clisockdata->method, - NULL) < 0 || php_stream_xport_crypto_enable( + sock->ctx ? stream : NULL) < 0 || php_stream_xport_crypto_enable( xparam->outputs.client, 1) < 0) { php_error_docref(NULL, E_WARNING, "Failed to enable crypto"); php_stream_close(xparam->outputs.client); xparam->outputs.client = NULL; xparam->outputs.returncode = -1; + if (xparam->want_errortext) { + if (xparam->outputs.error_text) { + zend_string_free(xparam->outputs.error_text); + } + xparam->outputs.error_text = ZSTR_INIT_LITERAL("Cannot enable crypto", 0); + } } } } @@ -2309,6 +3242,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val add_assoc_string(&tmp, "cipher_name", (char *) SSL_CIPHER_get_name(cipher)); add_assoc_long(&tmp, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL)); add_assoc_string(&tmp, "cipher_version", SSL_CIPHER_get_version(cipher)); + add_assoc_bool(&tmp, "session_reused", SSL_session_reused(sslsock->ssl_handle)); #ifdef HAVE_TLS_ALPN { @@ -2369,8 +3303,8 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val int retry = 1; struct timeval start_time; struct timeval *timeout = NULL; - int began_blocked = sslsock->s.is_blocked; - int has_timeout = 0; + bool began_blocked = sslsock->s.is_blocked; + bool has_timeout = false; /* never use a timeout with non-blocking sockets */ if (began_blocked) { @@ -2382,7 +3316,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val } if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { - has_timeout = 1; + has_timeout = true; /* gettimeofday is not monotonic; using it here is not strictly correct */ gettimeofday(&start_time, NULL); } @@ -2404,7 +3338,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val if (began_blocked) { php_openssl_set_blocking(sslsock, 1); } - sslsock->s.timeout_event = 1; + sslsock->s.timeout_event = true; return PHP_STREAM_OPTION_RETURN_ERR; } } @@ -2428,7 +3362,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val } /* Don't loop indefinitely in non-blocking mode if no data is available */ - if (began_blocked == 0 || !has_timeout) { + if (!began_blocked || !has_timeout) { alive = retry; break; } @@ -2485,11 +3419,9 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val case STREAM_XPORT_CRYPTO_OP_SETUP: cparam->outputs.returncode = php_openssl_setup_crypto(stream, sslsock, cparam); return PHP_STREAM_OPTION_RETURN_OK; - break; case STREAM_XPORT_CRYPTO_OP_ENABLE: cparam->outputs.returncode = php_openssl_enable_crypto(stream, sslsock, cparam); return PHP_STREAM_OPTION_RETURN_OK; - break; default: /* fall through */ break; @@ -2511,7 +3443,14 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val (xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC && xparam->outputs.returncode == 1 && xparam->outputs.error_code == EINPROGRESS))) { - if (php_stream_xport_crypto_setup(stream, sslsock->method, NULL) < 0 || + zval *val; + php_stream *session_stream = NULL; + + if (GET_VER_OPT("session_stream")) { + php_stream_from_zval_no_verify(session_stream, val); + } + + if (php_stream_xport_crypto_setup(stream, sslsock->method, session_stream) < 0 || php_stream_xport_crypto_enable(stream, 1) < 0) { php_error_docref(NULL, E_WARNING, "Failed to enable crypto"); xparam->outputs.returncode = -1; @@ -2519,6 +3458,21 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val } return PHP_STREAM_OPTION_RETURN_OK; + case STREAM_XPORT_OP_LISTEN: + /* Do normal listen first */ + xparam->outputs.returncode = php_stream_socket_ops.set_option( + stream, option, value, ptrparam); + + if (xparam->outputs.returncode == 0 && sslsock->enable_on_connect) { + /* Check if we should create SSL_CTX early for session resumption */ + if (php_openssl_is_session_cache_enabled(stream, false)) { + if (FAILURE == php_openssl_create_server_ctx(stream, sslsock, sslsock->method)) { + xparam->outputs.returncode = -1; + } + } + } + return PHP_STREAM_OPTION_RETURN_OK; + case STREAM_XPORT_OP_ACCEPT: /* we need to copy the additional fields that the underlying tcp transport * doesn't know about */ @@ -2610,23 +3564,29 @@ static zend_long php_openssl_get_crypto_method( /* }}} */ static char *php_openssl_get_url_name(const char *resourcename, - size_t resourcenamelen, int is_persistent) /* {{{ */ + size_t resourcenamelen, int is_persistent, php_stream_context *context) /* {{{ */ { - php_url *url; - if (!resourcename) { return NULL; } - url = php_url_parse_ex(resourcename, resourcenamelen); - if (!url) { + const php_uri_parser *uri_parser = php_stream_context_get_uri_parser("ssl", context); + if (uri_parser == NULL) { + zend_value_error("%s(): Provided stream context has invalid value for the \"uri_parser_class\" option", get_active_function_name()); + return NULL; + } + + php_uri_internal *internal_uri = php_uri_parse(uri_parser, resourcename, resourcenamelen, true); + if (internal_uri == NULL) { return NULL; } - if (url->host) { - const char * host = ZSTR_VAL(url->host); - char * url_name = NULL; - size_t len = ZSTR_LEN(url->host); + char * url_name = NULL; + zval host_zv; + zend_result result = php_uri_get_host(internal_uri, PHP_URI_COMPONENT_READ_MODE_RAW, &host_zv); + if (result == SUCCESS && Z_TYPE(host_zv) == IS_STRING) { + const char * host = Z_STRVAL(host_zv); + size_t len = Z_STRLEN(host_zv); /* skip trailing dots */ while (len && host[len-1] == '.') { @@ -2636,13 +3596,12 @@ static char *php_openssl_get_url_name(const char *resourcename, if (len) { url_name = pestrndup(host, len, is_persistent); } - - php_url_free(url); - return url_name; } - php_url_free(url); - return NULL; + php_uri_free(internal_uri); + zval_ptr_dtor(&host_zv); + + return url_name; } /* }}} */ @@ -2658,7 +3617,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, sslsock = pemalloc(sizeof(php_openssl_netstream_data_t), persistent_id ? 1 : 0); memset(sslsock, 0, sizeof(*sslsock)); - sslsock->s.is_blocked = 1; + sslsock->s.is_blocked = true; /* this timeout is used by standard stream funcs, therefore it should use the default value */ #ifdef _WIN32 sslsock->s.timeout.tv_sec = (long)FG(default_socket_timeout); @@ -2740,7 +3699,7 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, #endif } - sslsock->url_name = php_openssl_get_url_name(resourcename, resourcenamelen, !!persistent_id); + sslsock->url_name = php_openssl_get_url_name(resourcename, resourcenamelen, !!persistent_id, context); return stream; } diff --git a/ext/pcntl/config.m4 b/ext/pcntl/config.m4 index ce26a6efd2ea..553419114fd2 100644 --- a/ext/pcntl/config.m4 +++ b/ext/pcntl/config.m4 @@ -13,7 +13,6 @@ if test "$PHP_PCNTL" != "no"; then forkx getcpuid getpriority - pidfd_open pset_bind pthread_set_qos_class_self_np rfork @@ -25,6 +24,8 @@ if test "$PHP_PCNTL" != "no"; then wait3 wait4 waitid + wait6 + syscall ])) AC_CHECK_FUNCS([WIFCONTINUED],, @@ -43,6 +44,12 @@ if test "$PHP_PCNTL" != "no"; then ]),,, [#include ]) + AC_CHECK_DECLS([SYS_waitid],,, + [#include ]) + + AC_CHECK_DECLS([SYS_pidfd_open],,, + [#include ]) + dnl if unsupported, -1 means automatically ENOSYS in this context AC_CACHE_CHECK([if sched_getcpu is supported], [php_cv_func_sched_getcpu], [AC_RUN_IFELSE([AC_LANG_SOURCE([ @@ -61,9 +68,6 @@ int main(void) { [AC_DEFINE([HAVE_SCHED_GETCPU], [1], [Define to 1 if the 'sched_getcpu' function is properly supported.])]) - AC_CHECK_TYPE([siginfo_t], [PCNTL_CFLAGS="-DHAVE_STRUCT_SIGINFO_T"],, - [#include ]) - PHP_NEW_EXTENSION([pcntl], [pcntl.c php_signal.c], [$ext_shared], diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 0481c0966c87..2ba732c4540e 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -32,6 +30,7 @@ #include "php_signal.h" #include "php_ticks.h" #include "zend_fibers.h" +#include "main/php_main.h" #if defined(HAVE_GETPRIORITY) || defined(HAVE_SETPRIORITY) || defined(HAVE_WAIT3) #include @@ -93,7 +92,7 @@ typedef cpuset_t *cpu_set_t; #elif defined(HAVE_PSET_BIND) #include typedef psetid_t cpu_set_t; - #define sched_getaffinity(p, c, m) pset_bind(PS_QUERY, P_PID, (p <= 0 ? getpid() : p), &m) + #define sched_getaffinity(p, c, m) pset_bind(PS_QUERY, P_PID, p, &m) #define sched_setaffinity(p, c, m) pset_bind(m, P_PID, (p <= 0 ? getpid() : p), NULL) #define PCNTL_CPUSET(mask) mask #define PCNTL_CPU_ISSET(i, mask) (pset_assign(PS_QUERY, (processorid_t)i, &query) == 0 && query == mask) @@ -125,8 +124,18 @@ typedef psetid_t cpu_set_t; #include #endif -#ifdef HAVE_PIDFD_OPEN -#include +#if defined(__linux__) && defined(HAVE_SYSCALL) +# include +# if defined(HAVE_DECL_SYS_WAITID) && HAVE_DECL_SYS_WAITID == 1 +# define HAVE_LINUX_RAW_SYSCALL_WAITID 1 +# endif +# if defined(HAVE_DECL_SYS_PIDFD_OPEN) && HAVE_DECL_SYS_PIDFD_OPEN == 1 +# define HAVE_LINUX_RAW_SYSCALL_PIDFD_OPEN 1 +# endif +#endif + +#if defined(HAVE_LINUX_RAW_SYSCALL_WAITID) +#include #endif #ifdef HAVE_FORKX @@ -174,12 +183,8 @@ ZEND_GET_MODULE(pcntl) static void (*orig_interrupt_function)(zend_execute_data *execute_data); -#ifdef HAVE_STRUCT_SIGINFO_T static void pcntl_signal_handler(int, siginfo_t*, void*); static void pcntl_siginfo_to_zval(int, siginfo_t*, zval*); -#else -static void pcntl_signal_handler(int); -#endif static void pcntl_signal_dispatch(void); static void pcntl_signal_dispatch_tick_function(int dummy_int, void *dummy_pointer); static void pcntl_interrupt_function(zend_execute_data *execute_data); @@ -201,7 +206,7 @@ PHP_RINIT_FUNCTION(pcntl) PCNTL_G(last_error) = 0; PCNTL_G(num_signals) = NSIG; #ifdef SIGRTMAX - /* At least FreeBSD reports an incorrecrt NSIG that does not include realtime signals. + /* At least FreeBSD reports an incorrect NSIG that does not include realtime signals. * As SIGRTMAX may be a dynamic value, adjust the value in INIT. */ if (NSIG < SIGRTMAX + 1) { PCNTL_G(num_signals) = SIGRTMAX + 1; @@ -229,7 +234,7 @@ PHP_RSHUTDOWN_FUNCTION(pcntl) /* Reset all signals to their default disposition */ ZEND_HASH_FOREACH_NUM_KEY_VAL(&PCNTL_G(php_signal_table), signo, handle) { if (Z_TYPE_P(handle) != IS_LONG || Z_LVAL_P(handle) != (zend_long)SIG_DFL) { - php_signal(signo, (Sigfunc *)(zend_long)SIG_DFL, 0); + php_signal(signo, (Sigfunc *)(zend_long)SIG_DFL, false); } } ZEND_HASH_FOREACH_END(); @@ -287,7 +292,7 @@ PHP_FUNCTION(pcntl_fork) } } else if (id == 0) { - zend_max_execution_timer_init(); + php_child_init(); } RETURN_LONG((zend_long) id); @@ -303,6 +308,11 @@ PHP_FUNCTION(pcntl_alarm) Z_PARAM_LONG(seconds); ZEND_PARSE_PARAMETERS_END(); + if (seconds < 0 || seconds > UINT_MAX) { + zend_argument_value_error(1, "must be between 0 and %u", UINT_MAX); + RETURN_THROWS(); + } + RETURN_LONG((zend_long) alarm(seconds)); } /* }}} */ @@ -401,19 +411,49 @@ PHP_FUNCTION(pcntl_waitid) bool id_is_null = 1; zval *user_siginfo = NULL; zend_long options = WEXITED; + zval *z_rusage = NULL; - ZEND_PARSE_PARAMETERS_START(0, 4) + siginfo_t siginfo; + int status; + + ZEND_PARSE_PARAMETERS_START(0, 5) Z_PARAM_OPTIONAL Z_PARAM_LONG(idtype) Z_PARAM_LONG_OR_NULL(id, id_is_null) Z_PARAM_ZVAL(user_siginfo) Z_PARAM_LONG(options) + Z_PARAM_ZVAL(z_rusage) ZEND_PARSE_PARAMETERS_END(); errno = 0; - siginfo_t siginfo; + memset(&siginfo, 0, sizeof(siginfo_t)); - int status = waitid((idtype_t) idtype, (id_t) id, &siginfo, (int) options); +#if defined(HAVE_WAIT6) || defined(HAVE_LINUX_RAW_SYSCALL_WAITID) + if (z_rusage) { + z_rusage = zend_try_array_init(z_rusage); + if (!z_rusage) { + RETURN_THROWS(); + } + struct rusage rusage; +# if defined(HAVE_WAIT6) /* FreeBSD */ + struct __wrusage wrusage; + memset(&wrusage, 0, sizeof(struct __wrusage)); + pid_t pid = wait6((idtype_t) idtype, (id_t) id, &status, (int) options, &wrusage, &siginfo); + status = pid > 0 ? 0 : pid; + memcpy(&rusage, &wrusage.wru_self, sizeof(struct rusage)); +# else /* Linux */ + memset(&rusage, 0, sizeof(struct rusage)); + status = syscall(SYS_waitid, (idtype_t) idtype, (id_t) id, &siginfo, (int) options, &rusage); +# endif + if (status == 0) { + PHP_RUSAGE_TO_ARRAY(rusage, z_rusage); + } + } else { /* POSIX */ + status = waitid((idtype_t) idtype, (id_t) id, &siginfo, (int) options); + } +#else /* POSIX */ + status = waitid((idtype_t) idtype, (id_t) id, &siginfo, (int) options); +#endif if (status == -1) { PCNTL_G(last_error) = errno; @@ -635,7 +675,11 @@ PHP_FUNCTION(pcntl_exec) ZEND_PARSE_PARAMETERS_END(); if (args != NULL) { - // TODO Check array is a list? + if (!zend_array_is_list(Z_ARRVAL_P(args))) { + zend_argument_value_error(2, "must be a list array"); + RETURN_THROWS(); + } + /* Build argument list */ SEPARATE_ARRAY(args); const HashTable *args_ht = Z_ARRVAL_P(args); @@ -789,7 +833,7 @@ PHP_FUNCTION(pcntl_signal) zend_argument_value_error(2, "must be either SIG_DFL or SIG_IGN when an integer value is given"); RETURN_THROWS(); } - if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), (int) restart_syscalls) == (void *)SIG_ERR) { + if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), restart_syscalls) == (void *)SIG_ERR) { PCNTL_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Error assigning signal"); RETURN_FALSE; @@ -805,15 +849,16 @@ PHP_FUNCTION(pcntl_signal) RETURN_THROWS(); } - /* Add the function name to our signal table */ - handle = zend_hash_index_update(&PCNTL_G(php_signal_table), signo, handle); - Z_TRY_ADDREF_P(handle); - + /* Register with the OS first so that on failure we don't record a handler that was never installed */ if (php_signal4(signo, pcntl_signal_handler, (int) restart_syscalls, 1) == (void *)SIG_ERR) { PCNTL_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Error assigning signal"); RETURN_FALSE; } + + /* Add the function name to our signal table */ + handle = zend_hash_index_update(&PCNTL_G(php_signal_table), signo, handle); + Z_TRY_ADDREF_P(handle); RETURN_TRUE; } /* }}} */ @@ -828,17 +873,8 @@ PHP_FUNCTION(pcntl_signal_get_handler) Z_PARAM_LONG(signo) ZEND_PARSE_PARAMETERS_END(); - // note: max signal on mac is SIGUSR2 (31), no real time signals. - int sigmax = NSIG - 1; -#if defined(SIGRTMAX) - // oddily enough, NSIG on freebsd reports only 32 whereas SIGRTMIN starts at 65. - if (sigmax < SIGRTMAX) { - sigmax = SIGRTMAX; - } -#endif - - if (signo < 1 || signo > sigmax) { - zend_argument_value_error(1, "must be between 1 and %d", sigmax); + if (signo < 1 || signo >= PCNTL_G(num_signals)) { + zend_argument_value_error(1, "must be between 1 and %d", PCNTL_G(num_signals) - 1); RETURN_THROWS(); } @@ -969,8 +1005,7 @@ PHP_FUNCTION(pcntl_sigprocmask) /* }}} */ #endif -#ifdef HAVE_STRUCT_SIGINFO_T -# ifdef HAVE_SIGWAITINFO +#ifdef HAVE_SIGWAITINFO /* {{{ Synchronously wait for queued signals */ PHP_FUNCTION(pcntl_sigwaitinfo) @@ -1012,8 +1047,9 @@ PHP_FUNCTION(pcntl_sigwaitinfo) RETURN_LONG(signal_no); } /* }}} */ -# endif -# ifdef HAVE_SIGTIMEDWAIT +#endif + +#ifdef HAVE_SIGTIMEDWAIT /* {{{ Wait for queued signals */ PHP_FUNCTION(pcntl_sigtimedwait) { @@ -1075,7 +1111,7 @@ PHP_FUNCTION(pcntl_sigtimedwait) RETURN_LONG(signal_no); } /* }}} */ -# endif +#endif static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_siginfo) /* {{{ */ { @@ -1111,7 +1147,7 @@ static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_sigi case SIGFPE: case SIGSEGV: case SIGBUS: - add_assoc_double_ex(user_siginfo, "addr", sizeof("addr")-1, (zend_long)siginfo->si_addr); + add_assoc_long_ex(user_siginfo, "addr", sizeof("addr")-1, (zend_long)siginfo->si_addr); break; #if defined(SIGPOLL) && !defined(__CYGWIN__) case SIGPOLL: @@ -1145,7 +1181,6 @@ static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_sigi } } /* }}} */ -#endif #ifdef HAVE_GETPRIORITY /* {{{ Get the priority of any process */ @@ -1287,11 +1322,7 @@ PHP_FUNCTION(pcntl_strerror) /* }}} */ /* Our custom signal handler that calls the appropriate php_function */ -#ifdef HAVE_STRUCT_SIGINFO_T static void pcntl_signal_handler(int signo, siginfo_t *siginfo, void *context) -#else -static void pcntl_signal_handler(int signo) -#endif { struct php_pcntl_pending_signal *psig = PCNTL_G(spares); if (!psig) { @@ -1303,9 +1334,7 @@ static void pcntl_signal_handler(int signo) psig->signo = signo; psig->next = NULL; -#ifdef HAVE_STRUCT_SIGINFO_T psig->siginfo = *siginfo; -#endif /* the head check is important, as the tick handler cannot atomically clear both * the head and tail */ @@ -1315,7 +1344,7 @@ static void pcntl_signal_handler(int signo) PCNTL_G(head) = psig; } PCNTL_G(tail) = psig; - PCNTL_G(pending_signals) = 1; + PCNTL_G(pending_signals) = true; if (PCNTL_G(async_signals)) { zend_atomic_bool_store_ex(&EG(vm_interrupt), true); } @@ -1346,29 +1375,28 @@ void pcntl_signal_dispatch(void) zend_fiber_switch_block(); /* Prevent reentrant handler calls */ - PCNTL_G(processing_signal_queue) = 1; + PCNTL_G(processing_signal_queue) = true; queue = PCNTL_G(head); PCNTL_G(head) = NULL; /* simple stores are atomic */ + PCNTL_G(tail) = NULL; /* Allocate */ while (queue) { if ((handle = zend_hash_index_find(&PCNTL_G(php_signal_table), queue->signo)) != NULL) { if (Z_TYPE_P(handle) != IS_LONG) { ZVAL_LONG(¶ms[0], queue->signo); -#ifdef HAVE_STRUCT_SIGINFO_T array_init(¶ms[1]); pcntl_siginfo_to_zval(queue->signo, &queue->siginfo, ¶ms[1]); -#else - ZVAL_NULL(¶ms[1]); -#endif /* Call php signal handler - Note that we do not report errors, and we ignore the return value */ call_user_function(NULL, NULL, handle, &retval, 2, params); zval_ptr_dtor(&retval); -#ifdef HAVE_STRUCT_SIGINFO_T zval_ptr_dtor(¶ms[1]); -#endif + + if (EG(exception)) { + break; + } } } @@ -1378,10 +1406,18 @@ void pcntl_signal_dispatch(void) queue = next; } - PCNTL_G(pending_signals) = 0; + /* drain the remaining in case of exception thrown */ + while (queue) { + next = queue->next; + queue->next = PCNTL_G(spares); + PCNTL_G(spares) = queue; + queue = next; + } + + PCNTL_G(pending_signals) = false; /* Re-enable queue */ - PCNTL_G(processing_signal_queue) = 0; + PCNTL_G(processing_signal_queue) = false; /* Re-enable fiber switching */ zend_fiber_switch_unblock(); @@ -1431,7 +1467,6 @@ PHP_FUNCTION(pcntl_unshare) case EINVAL: zend_argument_value_error(1, "must be a combination of CLONE_* flags, or at least one flag is unsupported by the kernel"); RETURN_THROWS(); - break; #endif #ifdef ENOMEM case ENOMEM: @@ -1519,6 +1554,8 @@ PHP_FUNCTION(pcntl_rfork) default: php_error_docref(NULL, E_WARNING, "Error %d", errno); } + } else if (pid == 0) { + php_child_init(); } RETURN_LONG((zend_long) pid); @@ -1562,6 +1599,8 @@ PHP_FUNCTION(pcntl_forkx) default: php_error_docref(NULL, E_WARNING, "Error %d", errno); } + } else if (pid == 0) { + php_child_init(); } RETURN_LONG((zend_long) pid); @@ -1569,7 +1608,7 @@ PHP_FUNCTION(pcntl_forkx) #endif /* }}} */ -#ifdef HAVE_PIDFD_OPEN +#ifdef HAVE_LINUX_RAW_SYSCALL_PIDFD_OPEN // The `pidfd_open` syscall is available since 5.3 // and `setns` since 3.0. PHP_FUNCTION(pcntl_setns) @@ -1586,7 +1625,7 @@ PHP_FUNCTION(pcntl_setns) pid = pid_is_null ? getpid() : pid; fd = syscall(SYS_pidfd_open, pid, 0); - if (errno) { + if (fd == -1) { PCNTL_G(last_error) = errno; switch (errno) { case EINVAL: @@ -1612,11 +1651,12 @@ PHP_FUNCTION(pcntl_setns) RETURN_FALSE; } ret = setns(fd, (int)nstype); + int setns_errno = errno; close(fd); if (ret == -1) { - PCNTL_G(last_error) = errno; - switch (errno) { + PCNTL_G(last_error) = setns_errno; + switch (setns_errno) { case ESRCH: zend_argument_value_error(1, "process no longer available (" ZEND_LONG_FMT ")", pid); RETURN_THROWS(); @@ -1626,11 +1666,11 @@ PHP_FUNCTION(pcntl_setns) RETURN_THROWS(); case EPERM: - php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", errno); + php_error_docref(NULL, E_WARNING, "Error %d: No required capability for this process", setns_errno); break; default: - php_error_docref(NULL, E_WARNING, "Error %d", errno); + php_error_docref(NULL, E_WARNING, "Error %d", setns_errno); } RETURN_FALSE; } else { @@ -1736,6 +1776,7 @@ PHP_FUNCTION(pcntl_setcpuaffinity) if (cpu < 0 || cpu >= maxcpus) { zend_argument_value_error(2, "cpu id must be between 0 and " ZEND_ULONG_FMT " (" ZEND_LONG_FMT ")", maxcpus, cpu); + PCNTL_CPU_DESTROY(mask); RETURN_THROWS(); } @@ -1778,22 +1819,22 @@ PHP_FUNCTION(pcntl_getcpu) #endif #if defined(HAVE_PTHREAD_SET_QOS_CLASS_SELF_NP) -static qos_class_t qos_zval_to_lval(const zval *qos_obj) +static qos_class_t qos_enum_to_pthread(zend_enum_Pcntl_QosClass entry) { - qos_class_t qos_class = QOS_CLASS_DEFAULT; - zend_string *entry = Z_STR_P(zend_enum_fetch_case_name(Z_OBJ_P(qos_obj))); - - if (zend_string_equals_literal(entry, "UserInteractive")) { - qos_class = QOS_CLASS_USER_INTERACTIVE; - } else if (zend_string_equals_literal(entry, "UserInitiated")) { - qos_class = QOS_CLASS_USER_INITIATED; - } else if (zend_string_equals_literal(entry, "Utility")) { - qos_class = QOS_CLASS_UTILITY; - } else if (zend_string_equals_literal(entry, "Background")) { - qos_class = QOS_CLASS_BACKGROUND; - } - - return qos_class; + switch (entry) { + case ZEND_ENUM_Pcntl_QosClass_UserInteractive: + return QOS_CLASS_USER_INTERACTIVE; + case ZEND_ENUM_Pcntl_QosClass_UserInitiated: + return QOS_CLASS_USER_INITIATED; + case ZEND_ENUM_Pcntl_QosClass_Utility: + return QOS_CLASS_UTILITY; + case ZEND_ENUM_Pcntl_QosClass_Background: + return QOS_CLASS_BACKGROUND; + case ZEND_ENUM_Pcntl_QosClass_Default: + return QOS_CLASS_DEFAULT; + } + + ZEND_UNREACHABLE(); } static zend_object *qos_lval_to_zval(qos_class_t qos_class) @@ -1841,13 +1882,13 @@ PHP_FUNCTION(pcntl_getqos_class) PHP_FUNCTION(pcntl_setqos_class) { - zval *qos_obj; + zend_enum_Pcntl_QosClass qos; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT_OF_CLASS(qos_obj, QosClass_ce) + Z_PARAM_ENUM(qos, QosClass_ce) ZEND_PARSE_PARAMETERS_END(); - qos_class_t qos_class = qos_zval_to_lval(qos_obj); + qos_class_t qos_class = qos_enum_to_pthread(qos); if (UNEXPECTED(pthread_set_qos_class_self_np((qos_class_t)qos_class, 0) != 0)) { diff --git a/ext/pcntl/pcntl.stub.php b/ext/pcntl/pcntl.stub.php index c62a40139d9e..4a4b8fe86931 100644 --- a/ext/pcntl/pcntl.stub.php +++ b/ext/pcntl/pcntl.stub.php @@ -1,6 +1,9 @@ . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -17,6 +15,8 @@ #ifndef PHP_PCNTL_H #define PHP_PCNTL_H +#include "pcntl_decl.h" + #if defined(HAVE_DECL_WCONTINUED) && HAVE_DECL_WCONTINUED == 1 && defined(HAVE_WIFCONTINUED) && HAVE_WIFCONTINUED == 1 #define HAVE_WCONTINUED 1 #endif @@ -36,19 +36,18 @@ PHP_MINFO_FUNCTION(pcntl); struct php_pcntl_pending_signal { struct php_pcntl_pending_signal *next; zend_long signo; -#ifdef HAVE_STRUCT_SIGINFO_T siginfo_t siginfo; -#endif }; ZEND_BEGIN_MODULE_GLOBALS(pcntl) HashTable php_signal_table; - int processing_signal_queue; - struct php_pcntl_pending_signal *head, *tail, *spares; - int last_error; - volatile char pending_signals; + bool processing_signal_queue; + volatile bool pending_signals; bool async_signals; - unsigned num_signals; + /* some OSes define NSIG to be > UINT8_MAX */ + uint16_t num_signals; + int last_error; + struct php_pcntl_pending_signal *head, *tail, *spares; ZEND_END_MODULE_GLOBALS(pcntl) #if defined(ZTS) && defined(COMPILE_DL_PCNTL) diff --git a/ext/pcntl/php_signal.c b/ext/pcntl/php_signal.c index 14c169310e60..b0357d86f02b 100644 --- a/ext/pcntl/php_signal.c +++ b/ext/pcntl/php_signal.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -21,24 +19,18 @@ /* php_signal using sigaction is derived from Advanced Programming * in the Unix Environment by W. Richard Stevens p 298. */ -Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all) +Sigfunc *php_signal4(int signo, Sigfunc *func, bool restart, bool mask_all) { struct sigaction act,oact; -#ifdef HAVE_STRUCT_SIGINFO_T act.sa_sigaction = func; -#else - act.sa_handler = func; -#endif if (mask_all) { sigfillset(&act.sa_mask); } else { sigemptyset(&act.sa_mask); } act.sa_flags = SA_ONSTACK; -#ifdef HAVE_STRUCT_SIGINFO_T act.sa_flags |= SA_SIGINFO; -#endif if (!restart) { #ifdef SA_INTERRUPT act.sa_flags |= SA_INTERRUPT; /* SunOS */ @@ -50,14 +42,10 @@ Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all) } zend_sigaction(signo, &act, &oact); -#ifdef HAVE_STRUCT_SIGINFO_T return oact.sa_sigaction; -#else - return oact.sa_handler; -#endif } -Sigfunc *php_signal(int signo, Sigfunc *func, int restart) +Sigfunc *php_signal(int signo, Sigfunc *func, bool restart) { - return php_signal4(signo, func, restart, 0); + return php_signal4(signo, func, restart, false); } diff --git a/ext/pcntl/php_signal.h b/ext/pcntl/php_signal.h index 256898e70acb..7b103793e544 100644 --- a/ext/pcntl/php_signal.h +++ b/ext/pcntl/php_signal.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jason Greene | +----------------------------------------------------------------------+ @@ -18,12 +16,9 @@ #ifndef PHP_SIGNAL_H #define PHP_SIGNAL_H -#ifdef HAVE_STRUCT_SIGINFO_T typedef void Sigfunc(int, siginfo_t*, void*); -#else -typedef void Sigfunc(int); -#endif -Sigfunc *php_signal(int signo, Sigfunc *func, int restart); -Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all); + +Sigfunc *php_signal(int signo, Sigfunc *func, bool restart); +Sigfunc *php_signal4(int signo, Sigfunc *func, bool restart, bool mask_all); #endif diff --git a/ext/pcntl/tests/pcntl_alarm_invalid_value.phpt b/ext/pcntl/tests/pcntl_alarm_invalid_value.phpt new file mode 100644 index 000000000000..59e74662f6f7 --- /dev/null +++ b/ext/pcntl/tests/pcntl_alarm_invalid_value.phpt @@ -0,0 +1,35 @@ +--TEST-- +pcntl_alarm() rejects invalid values +--EXTENSIONS-- +pcntl +--SKIPIF-- + +--FILE-- +getMessage() . \PHP_EOL; +} + +try { + pcntl_alarm(PHP_INT_MIN); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +try { + pcntl_alarm(PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +var_dump(pcntl_alarm(0)); + +?> +--EXPECTF-- +pcntl_alarm(): Argument #1 ($seconds) must be between 0 and %d +pcntl_alarm(): Argument #1 ($seconds) must be between 0 and %d +pcntl_alarm(): Argument #1 ($seconds) must be between 0 and %d +int(0) diff --git a/ext/pcntl/tests/pcntl_cpuaffinity.phpt b/ext/pcntl/tests/pcntl_cpuaffinity.phpt index 1e3809f928c7..91c71d1ebdad 100644 --- a/ext/pcntl/tests/pcntl_cpuaffinity.phpt +++ b/ext/pcntl/tests/pcntl_cpuaffinity.phpt @@ -4,6 +4,9 @@ pcntl_getcpuaffinity() and pcntl_setcpuaffinity() pcntl --SKIPIF-- --FILE-- diff --git a/ext/pcntl/tests/pcntl_exec_list_args.phpt b/ext/pcntl/tests/pcntl_exec_list_args.phpt new file mode 100644 index 000000000000..5cd8c0fbe228 --- /dev/null +++ b/ext/pcntl/tests/pcntl_exec_list_args.phpt @@ -0,0 +1,14 @@ +--TEST-- +pcntl_exec(): Argument array must be a list +--EXTENSIONS-- +pcntl +--FILE-- + '-n']); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +?> +--EXPECT-- +ValueError: pcntl_exec(): Argument #2 ($args) must be a list array diff --git a/ext/pcntl/tests/pcntl_getcpu.phpt b/ext/pcntl/tests/pcntl_getcpu.phpt index b7e84a291d91..2250fde3a1b1 100644 --- a/ext/pcntl/tests/pcntl_getcpu.phpt +++ b/ext/pcntl/tests/pcntl_getcpu.phpt @@ -7,6 +7,7 @@ pcntl if (!function_exists("pcntl_getcpu")) die("skip pcntl_getcpu() is not available"); if (!function_exists("pcntl_setcpuaffinity")) die("skip pcntl_setcpuaffinity() is not available"); if (getenv('SKIP_REPEAT')) die("skip Not repeatable"); +if (PHP_OS_FAMILY === 'Solaris') die("skip doesn't work on Solaris"); ?> --FILE-- getMessage() . "\n"; +} + +echo "Handlers called: " . implode(', ', $called) . "\n"; + +?> +--EXPECT-- +Exception in signal handler +Handlers called: SIGUSR1 diff --git a/ext/pcntl/tests/pcntl_signal_functions_invalid_signals.phpt b/ext/pcntl/tests/pcntl_signal_functions_invalid_signals.phpt new file mode 100644 index 000000000000..e61b17bf3fbd --- /dev/null +++ b/ext/pcntl/tests/pcntl_signal_functions_invalid_signals.phpt @@ -0,0 +1,80 @@ +--TEST-- +pcntl_sigprocmask(), pcntl_sigwaitinfo(), and pcntl_sigtimedwait() properly throw on invalid signals +--EXTENSIONS-- +pcntl +--SKIPIF-- + +--INI-- +max_execution_time=0 +--FILE-- +getMessage() . PHP_EOL; +} + +try { + pcntl_sigprocmask(SIG_BLOCK, [0]); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + pcntl_sigprocmask(SIG_BLOCK, []); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + pcntl_sigwaitinfo(["not_a_signal"]); +} catch (TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + pcntl_sigwaitinfo([0]); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + pcntl_sigwaitinfo([]); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + pcntl_sigtimedwait(["not_a_signal"], $info, 1); +} catch (TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + pcntl_sigtimedwait([0], $info, 1); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + pcntl_sigtimedwait([], $info, 1); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +?> +--EXPECTF-- +pcntl_sigprocmask(): Argument #2 ($signals) signals must be of type int, string given +pcntl_sigprocmask(): Argument #2 ($signals) signals must be between 1 and %d +pcntl_sigprocmask(): Argument #2 ($signals) must not be empty +pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be of type int, string given +pcntl_sigwaitinfo(): Argument #1 ($signals) signals must be between 1 and %d +pcntl_sigwaitinfo(): Argument #1 ($signals) must not be empty +pcntl_sigtimedwait(): Argument #1 ($signals) signals must be of type int, string given +pcntl_sigtimedwait(): Argument #1 ($signals) signals must be between 1 and %d +pcntl_sigtimedwait(): Argument #1 ($signals) must not be empty diff --git a/ext/pcntl/tests/pcntl_waitid.phpt b/ext/pcntl/tests/pcntl_waitid.phpt index b00f26f81fa2..e297cd107a47 100644 --- a/ext/pcntl/tests/pcntl_waitid.phpt +++ b/ext/pcntl/tests/pcntl_waitid.phpt @@ -26,10 +26,12 @@ if ($pid == -1) { } else { pcntl_signal(SIGUSR1, function ($_signo, $_siginfo) { exit(42); }); posix_kill(posix_getpid(), SIGSTOP); - pcntl_signal_dispatch(); - sleep(42); - pcntl_signal_dispatch(); - exit(6); + $nanoseconds = 100; + while (true) { + pcntl_signal_dispatch(); + time_nanosleep(0, $nanoseconds); + $nanoseconds *= 2; + } } ?> --EXPECTF-- diff --git a/ext/pcntl/tests/pcntl_waitid_rusage.phpt b/ext/pcntl/tests/pcntl_waitid_rusage.phpt new file mode 100644 index 000000000000..8df148357d1c --- /dev/null +++ b/ext/pcntl/tests/pcntl_waitid_rusage.phpt @@ -0,0 +1,72 @@ +--TEST-- +pcntl_waitid() and rusage +--EXTENSIONS-- +pcntl +posix +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) +int(%d) +int(%d) +bool(true) +int(%d) +int(%d) +bool(true) +int(%d) +int(42) +bool(false) +string(5) "array" +int(0) +bool(false) +string(5) "array" +int(0) +END diff --git a/ext/pcre/config.w32 b/ext/pcre/config.w32 index d3c15160d0b0..7c09456b8961 100644 --- a/ext/pcre/config.w32 +++ b/ext/pcre/config.w32 @@ -2,7 +2,7 @@ EXTENSION("pcre", "php_pcre.c", false /* never shared */, "-Iext/pcre/pcre2lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); -ADD_SOURCES("ext/pcre/pcre2lib", "pcre2_auto_possess.c pcre2_chartables.c pcre2_compile.c pcre2_compile_class.c pcre2_config.c pcre2_context.c pcre2_chkdint.c pcre2_dfa_match.c pcre2_error.c pcre2_jit_compile.c pcre2_maketables.c pcre2_match.c pcre2_match_data.c pcre2_newline.c pcre2_ord2utf.c pcre2_pattern_info.c pcre2_serialize.c pcre2_string_utils.c pcre2_study.c pcre2_substitute.c pcre2_substring.c pcre2_tables.c pcre2_ucd.c pcre2_valid_utf.c pcre2_xclass.c pcre2_find_bracket.c pcre2_convert.c pcre2_extuni.c pcre2_script_run.c", "pcre"); +ADD_SOURCES("ext/pcre/pcre2lib", "pcre2_auto_possess.c pcre2_chartables.c pcre2_compile.c pcre2_config.c pcre2_context.c pcre2_chkdint.c pcre2_dfa_match.c pcre2_error.c pcre2_jit_compile.c pcre2_maketables.c pcre2_match.c pcre2_match_data.c pcre2_newline.c pcre2_ord2utf.c pcre2_pattern_info.c pcre2_serialize.c pcre2_string_utils.c pcre2_study.c pcre2_substitute.c pcre2_substring.c pcre2_tables.c pcre2_ucd.c pcre2_valid_utf.c pcre2_xclass.c pcre2_find_bracket.c pcre2_convert.c pcre2_extuni.c pcre2_script_run.c", "pcre"); ADD_DEF_FILE("ext\\pcre\\php_pcre.def"); AC_DEFINE('HAVE_BUNDLED_PCRE', 1, 'Define to 1 if PHP uses the bundled PCRE library.'); diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index d049cc538c0f..e71d9a795574 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -68,7 +68,6 @@ else pcre2lib/pcre2_chartables.c pcre2lib/pcre2_chkdint.c pcre2lib/pcre2_compile.c - pcre2lib/pcre2_compile_class.c pcre2lib/pcre2_config.c pcre2lib/pcre2_context.c pcre2lib/pcre2_convert.c @@ -96,8 +95,7 @@ else "]) AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough], - [PHP_PCRE_CFLAGS="$PHP_PCRE_CFLAGS -Wno-implicit-fallthrough"],, - [-Werror]) + [PHP_PCRE_CFLAGS="$PHP_PCRE_CFLAGS -Wno-implicit-fallthrough"]) PHP_PCRE_CFLAGS=m4_normalize([" $PHP_PCRE_CFLAGS diff --git a/ext/pcre/pcre2lib/config.h b/ext/pcre/pcre2lib/config.h index 368c6f986595..859d76f24419 100644 --- a/ext/pcre/pcre2lib/config.h +++ b/ext/pcre/pcre2lib/config.h @@ -104,32 +104,6 @@ #define MAX_VARLOOKBEHIND 255 #endif -/* The value of NEWLINE_DEFAULT determines the default newline character - sequence. PCRE2 client programs can override this by selecting other values - at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5 - (ANYCRLF), and 6 (NUL). */ -#ifndef NEWLINE_DEFAULT -#define NEWLINE_DEFAULT 2 -#endif - -/* The value of PCRE2GREP_BUFSIZE is the starting size of the buffer used by - pcre2grep to hold parts of the file it is searching. The buffer will be - expanded up to PCRE2GREP_MAX_BUFSIZE if necessary, for files containing - very long lines. The actual amount of memory used by pcre2grep is three - times this number, because it allows for the buffering of "before" and - "after" lines. */ -#ifndef PCRE2GREP_BUFSIZE -#define PCRE2GREP_BUFSIZE 20480 -#endif - -/* The value of PCRE2GREP_MAX_BUFSIZE specifies the maximum size of the buffer - used by pcre2grep to hold parts of the file it is searching. The actual - amount of memory used by pcre2grep is three times this number, because it - allows for the buffering of "before" and "after" lines. */ -#ifndef PCRE2GREP_MAX_BUFSIZE -#define PCRE2GREP_MAX_BUFSIZE 1048576 -#endif - /* to make a symbol visible */ #ifndef PCRE2_EXPORT #define PCRE2_EXPORT diff --git a/ext/pcre/pcre2lib/pcre2.h b/ext/pcre/pcre2lib/pcre2.h index 6d1a8758ba96..a322d9f2d56f 100644 --- a/ext/pcre/pcre2lib/pcre2.h +++ b/ext/pcre/pcre2lib/pcre2.h @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 45 +#define PCRE2_MINOR 44 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2025-02-05 +#define PCRE2_DATE 2024-06-07 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -143,7 +143,6 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_EXTENDED_MORE 0x01000000u /* C */ #define PCRE2_LITERAL 0x02000000u /* C */ #define PCRE2_MATCH_INVALID_UTF 0x04000000u /* J M D */ -#define PCRE2_ALT_EXTENDED_CLASS 0x08000000u /* C */ /* An additional compile options word is available in the compile context. */ @@ -160,10 +159,6 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_EXTRA_ASCII_BSW 0x00000400u /* C */ #define PCRE2_EXTRA_ASCII_POSIX 0x00000800u /* C */ #define PCRE2_EXTRA_ASCII_DIGIT 0x00001000u /* C */ -#define PCRE2_EXTRA_PYTHON_OCTAL 0x00002000u /* C */ -#define PCRE2_EXTRA_NO_BS0 0x00004000u /* C */ -#define PCRE2_EXTRA_NEVER_CALLOUT 0x00008000u /* C */ -#define PCRE2_EXTRA_TURKISH_CASING 0x00010000u /* C */ /* These are for pcre2_jit_compile(). */ @@ -171,7 +166,6 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_JIT_PARTIAL_SOFT 0x00000002u #define PCRE2_JIT_PARTIAL_HARD 0x00000004u #define PCRE2_JIT_INVALID_UTF 0x00000100u -#define PCRE2_JIT_TEST_ALLOC 0x00000200u /* These are for pcre2_match(), pcre2_dfa_match(), pcre2_jit_match(), and pcre2_substitute(). Some are allowed only for one of the functions, and in @@ -326,23 +320,7 @@ pcre2_pattern_convert(). */ #define PCRE2_ERROR_TOO_MANY_CAPTURES 197 #define PCRE2_ERROR_CONDITION_ATOMIC_ASSERTION_EXPECTED 198 #define PCRE2_ERROR_BACKSLASH_K_IN_LOOKAROUND 199 -#define PCRE2_ERROR_MAX_VAR_LOOKBEHIND_EXCEEDED 200 -#define PCRE2_ERROR_PATTERN_COMPILED_SIZE_TOO_BIG 201 -#define PCRE2_ERROR_OVERSIZE_PYTHON_OCTAL 202 -#define PCRE2_ERROR_CALLOUT_CALLER_DISABLED 203 -#define PCRE2_ERROR_EXTRA_CASING_REQUIRES_UNICODE 204 -#define PCRE2_ERROR_TURKISH_CASING_REQUIRES_UTF 205 -#define PCRE2_ERROR_EXTRA_CASING_INCOMPATIBLE 206 -#define PCRE2_ERROR_ECLASS_NEST_TOO_DEEP 207 -#define PCRE2_ERROR_ECLASS_INVALID_OPERATOR 208 -#define PCRE2_ERROR_ECLASS_UNEXPECTED_OPERATOR 209 -#define PCRE2_ERROR_ECLASS_EXPECTED_OPERAND 210 -#define PCRE2_ERROR_ECLASS_MIXED_OPERATORS 211 -#define PCRE2_ERROR_ECLASS_HINT_SQUARE_BRACKET 212 -#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_EXPR 213 -#define PCRE2_ERROR_PERL_ECLASS_EMPTY_EXPR 214 -#define PCRE2_ERROR_PERL_ECLASS_MISSING_CLOSE 215 -#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_CHAR 216 + /* "Expected" matching error codes: no match and partial match. */ @@ -429,9 +407,6 @@ released, the numbers must not be changed. */ #define PCRE2_ERROR_INTERNAL_DUPMATCH (-65) #define PCRE2_ERROR_DFA_UINVALID_UTF (-66) #define PCRE2_ERROR_INVALIDOFFSET (-67) -#define PCRE2_ERROR_JIT_UNSUPPORTED (-68) -#define PCRE2_ERROR_REPLACECASE (-69) -#define PCRE2_ERROR_TOOLARGEREPLACE (-70) /* Request types for pcre2_pattern_info() */ @@ -485,30 +460,6 @@ released, the numbers must not be changed. */ #define PCRE2_CONFIG_COMPILED_WIDTHS 14 #define PCRE2_CONFIG_TABLES_LENGTH 15 -/* Optimization directives for pcre2_set_optimize(). -For binary compatibility, only add to this list; do not renumber. */ - -#define PCRE2_OPTIMIZATION_NONE 0 -#define PCRE2_OPTIMIZATION_FULL 1 - -#define PCRE2_AUTO_POSSESS 64 -#define PCRE2_AUTO_POSSESS_OFF 65 -#define PCRE2_DOTSTAR_ANCHOR 66 -#define PCRE2_DOTSTAR_ANCHOR_OFF 67 -#define PCRE2_START_OPTIMIZE 68 -#define PCRE2_START_OPTIMIZE_OFF 69 - -/* Types used in pcre2_set_substitute_case_callout(). - -PCRE2_SUBSTITUTE_CASE_LOWER and PCRE2_SUBSTITUTE_CASE_UPPER are passed to the -callout to indicate that the case of the entire callout input should be -case-transformed. PCRE2_SUBSTITUTE_CASE_TITLE_FIRST is passed to indicate that -only the first character or glyph should be transformed to Unicode titlecase, -and the rest to lowercase. */ - -#define PCRE2_SUBSTITUTE_CASE_LOWER 1 -#define PCRE2_SUBSTITUTE_CASE_UPPER 2 -#define PCRE2_SUBSTITUTE_CASE_TITLE_FIRST 3 /* Types for code units in patterns and subject strings. */ @@ -662,9 +613,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_parens_nest_limit(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_compile_recursion_guard(pcre2_compile_context *, \ - int (*)(uint32_t, void *), void *); \ -PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ - pcre2_set_optimize(pcre2_compile_context *, uint32_t); + int (*)(uint32_t, void *), void *); #define PCRE2_MATCH_CONTEXT_FUNCTIONS \ PCRE2_EXP_DECL pcre2_match_context *PCRE2_CALL_CONVENTION \ @@ -679,11 +628,6 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_substitute_callout(pcre2_match_context *, \ int (*)(pcre2_substitute_callout_block *, void *), void *); \ -PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ - pcre2_set_substitute_case_callout(pcre2_match_context *, \ - PCRE2_SIZE (*)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, PCRE2_SIZE, int, \ - void *), \ - void *); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ @@ -796,7 +740,6 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **); - /* Functions for serializing / deserializing compiled patterns. */ #define PCRE2_SERIALIZE_FUNCTIONS \ @@ -964,9 +907,7 @@ pcre2_compile are called by application code. */ #define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) #define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) #define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) -#define pcre2_set_optimize PCRE2_SUFFIX(pcre2_set_optimize_) #define pcre2_set_substitute_callout PCRE2_SUFFIX(pcre2_set_substitute_callout_) -#define pcre2_set_substitute_case_callout PCRE2_SUFFIX(pcre2_set_substitute_case_callout_) #define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) #define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) #define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) diff --git a/ext/pcre/pcre2lib/pcre2_auto_possess.c b/ext/pcre/pcre2lib/pcre2_auto_possess.c index 6d7f27b6904c..210d13d37aa8 100644 --- a/ext/pcre/pcre2lib/pcre2_auto_possess.c +++ b/ext/pcre/pcre2lib/pcre2_auto_possess.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2022 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -49,10 +49,6 @@ repeats into possessive repeats where possible. */ #include "pcre2_internal.h" -/* This macro represents the max size of list[] and that is used to keep -track of UCD info in several places, it should be kept on sync with the -value used by GenerateUcd.py */ -#define MAX_LIST 8 /************************************************* * Tables for auto-possessification * @@ -68,7 +64,7 @@ The Unicode property types (\P and \p) have to be present to fill out the table because of what their opcode values are, but the table values should always be zero because property types are handled separately in the code. The last four columns apply to items that cannot be repeated, so there is no need to have -rows for them. Note that OP_DIGIT etc. are generated only when PCRE2_UCP is +rows for them. Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ #define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1) @@ -127,21 +123,21 @@ opcode is used to select the column. The values are as follows: */ static const uint8_t propposstab[PT_TABSIZE][PT_TABSIZE] = { -/* LAMP GC PC SC SCX ALNUM SPACE PXSPACE WORD CLIST UCNC BIDICL BOOL */ - { 3, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_LAMP */ - { 0, 2, 4, 0, 0, 9, 10, 10, 11, 0, 0, 0, 0 }, /* PT_GC */ - { 0, 5, 2, 0, 0, 15, 16, 16, 17, 0, 0, 0, 0 }, /* PT_PC */ - { 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SC */ - { 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SCX */ - { 3, 6, 12, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_ALNUM */ - { 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_SPACE */ - { 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_PXSPACE */ - { 0, 8, 14, 0, 0, 0, 1, 1, 3, 0, 0, 0, 0 }, /* PT_WORD */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, /* PT_UCNC */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_BIDICL */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* PT_BOOL */ - /* PT_ANY does not need a record. */ +/* ANY LAMP GC PC SC SCX ALNUM SPACE PXSPACE WORD CLIST UCNC BIDICL BOOL */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */ + { 0, 3, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_LAMP */ + { 0, 0, 2, 4, 0, 0, 9, 10, 10, 11, 0, 0, 0, 0 }, /* PT_GC */ + { 0, 0, 5, 2, 0, 0, 15, 16, 16, 17, 0, 0, 0, 0 }, /* PT_PC */ + { 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SC */ + { 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_SCX */ + { 0, 3, 6, 12, 0, 0, 3, 1, 1, 0, 0, 0, 0, 0 }, /* PT_ALNUM */ + { 0, 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_SPACE */ + { 0, 1, 7, 13, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0 }, /* PT_PXSPACE */ + { 0, 0, 8, 14, 0, 0, 0, 1, 1, 3, 0, 0, 0, 0 }, /* PT_WORD */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, /* PT_UCNC */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_BIDICL */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* PT_BOOL */ }; /* This table is used to check whether auto-possessification is possible @@ -203,7 +199,7 @@ static BOOL check_char_prop(uint32_t c, unsigned int ptype, unsigned int pdata, BOOL negated) { -BOOL ok, rc; +BOOL ok; const uint32_t *p; const ucd_record *prop = GET_UCD(c); @@ -244,13 +240,12 @@ switch(ptype) { HSPACE_CASES: VSPACE_CASES: - rc = negated; - break; + return negated; default: - rc = (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated; + return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated; } - return rc; + break; /* Control never reaches here */ case PT_WORD: return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || @@ -264,8 +259,7 @@ switch(ptype) if (c < *p) return !negated; if (c == *p++) return negated; } - PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ - break; + break; /* Control never reaches here */ /* Haven't yet thought these through. */ @@ -334,7 +328,6 @@ get_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc, PCRE2_UCHAR c = *code; PCRE2_UCHAR base; PCRE2_SPTR end; -PCRE2_SPTR class_end; uint32_t chr; #ifdef SUPPORT_UNICODE @@ -457,12 +450,10 @@ switch(c) code += 2; do { - if (clist_dest >= list + MAX_LIST) + if (clist_dest >= list + 8) { - /* Early return if there is not enough space. GenerateUcd.py - generated a list with more than 5 characters and something - must be done about that going forward. */ - PCRE2_DEBUG_UNREACHABLE(); /* Remove if it ever triggers */ + /* Early return if there is not enough space. This should never + happen, since all clists are shorter than 5 character now. */ list[2] = code[0]; list[3] = code[1]; return code; @@ -482,13 +473,11 @@ switch(c) case OP_CLASS: #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - case OP_ECLASS: - if (c == OP_XCLASS || c == OP_ECLASS) + if (c == OP_XCLASS) end = code + GET(code, 0) - 1; else #endif end = code + 32 / sizeof(PCRE2_UCHAR); - class_end = end; switch(*end) { @@ -516,7 +505,6 @@ switch(c) break; } list[2] = (uint32_t)(end - code); - list[3] = (uint32_t)(end - class_end); return end; } @@ -549,7 +537,7 @@ compare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb, const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit) { PCRE2_UCHAR c; -uint32_t list[MAX_LIST]; +uint32_t list[8]; const uint32_t *chr_ptr; const uint32_t *ochr_ptr; const uint32_t *list_ptr; @@ -593,7 +581,7 @@ for(;;) continue; } - /* At the end of a branch, skip to the end of the group and process it. */ + /* At the end of a branch, skip to the end of the group. */ if (c == OP_ALT) { @@ -650,29 +638,19 @@ for(;;) return FALSE; break; - /* Atomic sub-patterns and forward assertions can always auto-possessify - their last iterator. However, if the group was entered as a result of - checking a previous iterator, this is not possible. */ + /* Atomic sub-patterns and assertions can always auto-possessify their + last iterator except for variable length lookbehinds. However, if the + group was entered as a result of checking a previous iterator, this is + not possible. */ case OP_ASSERT: case OP_ASSERT_NOT: case OP_ONCE: return !entered_a_group; - /* Fixed-length lookbehinds can be treated the same way, but variable - length lookbehinds must not auto-possessify their last iterator. Note - that in order to identify a variable length lookbehind we must check - through all branches, because some may be of fixed length. */ - case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: - do - { - if (bracode[1+LINK_SIZE] == OP_VREVERSE) return FALSE; /* Variable */ - bracode += GET(bracode, 1); - } - while (*bracode == OP_ALT); - return !entered_a_group; /* Not variable length */ + return (bracode[1+LINK_SIZE] == OP_VREVERSE)? FALSE : !entered_a_group; /* Non-atomic assertions - don't possessify last iterator. This needs more thought. */ @@ -770,12 +748,12 @@ for(;;) if (base_list[0] == OP_CLASS) #endif { - set1 = (const uint8_t *)(base_end - base_list[2]); + set1 = (uint8_t *)(base_end - base_list[2]); list_ptr = list; } else { - set1 = (const uint8_t *)(code - list[2]); + set1 = (uint8_t *)(code - list[2]); list_ptr = base_list; } @@ -784,14 +762,13 @@ for(;;) { case OP_CLASS: case OP_NCLASS: - set2 = (const uint8_t *) + set2 = (uint8_t *) ((list_ptr == list ? code : base_end) - list_ptr[2]); break; #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - xclass_flags = (list_ptr == list ? code : base_end) - - list_ptr[2] + LINK_SIZE; + xclass_flags = (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE; if ((*xclass_flags & XCL_HASPROP) != 0) return FALSE; if ((*xclass_flags & XCL_MAP) == 0) { @@ -800,7 +777,7 @@ for(;;) /* Might be an empty repeat. */ continue; } - set2 = (const uint8_t *)(xclass_flags + 1); + set2 = (uint8_t *)(xclass_flags + 1); break; #endif @@ -808,21 +785,21 @@ for(;;) invert_bits = TRUE; /* Fall through */ case OP_DIGIT: - set2 = (const uint8_t *)(cb->cbits + cbit_digit); + set2 = (uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; /* Fall through */ case OP_WHITESPACE: - set2 = (const uint8_t *)(cb->cbits + cbit_space); + set2 = (uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; /* Fall through */ case OP_WORDCHAR: - set2 = (const uint8_t *)(cb->cbits + cbit_word); + set2 = (uint8_t *)(cb->cbits + cbit_word); break; default: @@ -1107,7 +1084,7 @@ for(;;) case OP_CLASS: if (chr > 255) break; - class_bitset = (const uint8_t *) + class_bitset = (uint8_t *) ((list_ptr == list ? code : base_end) - list_ptr[2]); if ((class_bitset[chr >> 3] & (1u << (chr & 7))) != 0) return FALSE; break; @@ -1115,18 +1092,9 @@ for(;;) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) - - list_ptr[2] + LINK_SIZE, (const uint8_t*)cb->start_code, utf)) - return FALSE; - break; - - case OP_ECLASS: - if (PRIV(eclass)(chr, - (list_ptr == list ? code : base_end) - list_ptr[2] + LINK_SIZE, - (list_ptr == list ? code : base_end) - list_ptr[3], - (const uint8_t*)cb->start_code, utf)) - return FALSE; + list_ptr[2] + LINK_SIZE, utf)) return FALSE; break; -#endif /* SUPPORT_WIDE_CHARS */ +#endif default: return FALSE; @@ -1141,8 +1109,8 @@ for(;;) if (list[1] == 0) return TRUE; } -PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ -return FALSE; /* Avoid compiler warnings */ +/* Control never reaches here. There used to be a fail-save return FALSE; here, +but some compilers complain about an unreachable statement. */ } @@ -1172,7 +1140,7 @@ PRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb) PCRE2_UCHAR c; PCRE2_SPTR end; PCRE2_UCHAR *repeat_opcode; -uint32_t list[MAX_LIST]; +uint32_t list[8]; int rec_limit = 1000; /* Was 10,000 but clang+ASAN uses a lot of stack. */ BOOL utf = (cb->external_options & PCRE2_UTF) != 0; BOOL ucp = (cb->external_options & PCRE2_UCP) != 0; @@ -1181,11 +1149,7 @@ for (;;) { c = *code; - if (c >= OP_TABLE_LENGTH) - { - PCRE2_DEBUG_UNREACHABLE(); - return -1; /* Something gone wrong */ - } + if (c >= OP_TABLE_LENGTH) return -1; /* Something gone wrong */ if (c >= OP_STAR && c <= OP_TYPEPOSUPTO) { @@ -1234,14 +1198,10 @@ for (;;) } c = *code; } - else if (c == OP_CLASS || c == OP_NCLASS -#ifdef SUPPORT_WIDE_CHARS - || c == OP_XCLASS || c == OP_ECLASS -#endif - ) + else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS) { #ifdef SUPPORT_WIDE_CHARS - if (c == OP_XCLASS || c == OP_ECLASS) + if (c == OP_XCLASS) repeat_opcode = code + GET(code, 1); else #endif @@ -1251,7 +1211,7 @@ for (;;) if (c >= OP_CRSTAR && c <= OP_CRMINRANGE) { /* The return from get_chr_property_list() will never be NULL when - *code (aka c) is one of the four class opcodes. However, gcc with + *code (aka c) is one of the three class opcodes. However, gcc with -fanalyzer notes that a NULL return is possible, and grumbles. Hence we put in a check. */ @@ -1319,7 +1279,6 @@ for (;;) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - case OP_ECLASS: code += GET(code, 1); break; #endif diff --git a/ext/pcre/pcre2lib/pcre2_chartables.c b/ext/pcre/pcre2lib/pcre2_chartables.c index 861914d1ac3a..7362c3f2345a 100644 --- a/ext/pcre/pcre2lib/pcre2_chartables.c +++ b/ext/pcre/pcre2lib/pcre2_chartables.c @@ -5,7 +5,8 @@ /* This file was automatically written by the pcre2_dftables auxiliary program. It contains character tables that are used when no external tables are passed to PCRE2 by the application that calls it. The tables -are used only for characters whose code values are less than 256. */ +are used only for characters whose code values are less than 256, and +only relevant if not in UCP mode. */ /* This set of tables was written in the C locale. */ @@ -18,13 +19,6 @@ PCRE2 is configured with --enable-rebuild-chartables. However, you can run pcre2_dftables manually with the -L option to build tables using the LC_ALL locale. */ -/* The following #include is present because without it gcc 4.x may remove -the array definition from the final binary if PCRE2 is built into a static -library and dead code stripping is activated. This leads to link errors. -Pulling in the header ensures that the array gets flagged as "someone -outside this compilation unit might reference this" and so it will always -be supplied to the linker. */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -163,7 +157,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x02 letter 0x04 lower case letter 0x08 decimal digit - 0x10 alphanumeric or '_' + 0x10 word (alphanumeric or '_') */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ diff --git a/ext/pcre/pcre2lib/pcre2_chkdint.c b/ext/pcre/pcre2lib/pcre2_chkdint.c index 70830236999d..d04f6f8cf1af 100644 --- a/ext/pcre/pcre2lib/pcre2_chkdint.c +++ b/ext/pcre/pcre2lib/pcre2_chkdint.c @@ -74,7 +74,9 @@ if (__builtin_mul_overflow(a, b, &m)) return TRUE; #else INT64_OR_DOUBLE m; -PCRE2_ASSERT(a >= 0 && b >= 0); +#ifdef PCRE2_DEBUG +if (a < 0 || b < 0) abort(); +#endif m = (INT64_OR_DOUBLE)a * (INT64_OR_DOUBLE)b; @@ -91,4 +93,4 @@ if (m > PCRE2_SIZE_MAX) return TRUE; return FALSE; } -/* End of pcre2_chkdint.c */ +/* End of pcre_chkdint.c */ diff --git a/ext/pcre/pcre2lib/pcre2_compile.c b/ext/pcre/pcre2lib/pcre2_compile.c index 0ffac8939cb6..8e6787aba38e 100644 --- a/ext/pcre/pcre2lib/pcre2_compile.c +++ b/ext/pcre/pcre2lib/pcre2_compile.c @@ -47,7 +47,7 @@ POSSIBILITY OF SUCH DAMAGE. #define PSSTART start_pattern /* Field containing processed string start */ #define PSEND end_pattern /* Field containing processed string end */ -#include "pcre2_compile.h" +#include "pcre2_internal.h" /* In rare error cases debugging might require calling pcre2_printint(). */ @@ -108,8 +108,20 @@ them will be able to (i.e. assume a 64-bit world). */ #define SIZEOFFSET 2 #endif +/* Macros for manipulating elements of the parsed pattern vector. */ + +#define META_CODE(x) (x & 0xffff0000u) +#define META_DATA(x) (x & 0x0000ffffu) +#define META_DIFF(x,y) ((x-y)>>16) + /* Function definitions to allow mutual recursion */ +#ifdef SUPPORT_UNICODE +static unsigned int + add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t, uint32_t, + compile_block *, const uint32_t *, unsigned int); +#endif + static int compile_regex(uint32_t, uint32_t, PCRE2_UCHAR **, uint32_t **, int *, uint32_t, uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *, @@ -187,6 +199,106 @@ don't have to check them every time. */ #define OFLOW_MAX (INT_MAX - 20) +/* Code values for parsed patterns, which are stored in a vector of 32-bit +unsigned ints. Values less than META_END are literal data values. The coding +for identifying the item is in the top 16-bits, leaving 16 bits for the +additional data that some of them need. The META_CODE, META_DATA, and META_DIFF +macros are used to manipulate parsed pattern elements. + +NOTE: When these definitions are changed, the table of extra lengths for each +code (meta_extra_lengths, just below) must be updated to remain in step. */ + +#define META_END 0x80000000u /* End of pattern */ + +#define META_ALT 0x80010000u /* alternation */ +#define META_ATOMIC 0x80020000u /* atomic group */ +#define META_BACKREF 0x80030000u /* Back ref */ +#define META_BACKREF_BYNAME 0x80040000u /* \k'name' */ +#define META_BIGVALUE 0x80050000u /* Next is a literal > META_END */ +#define META_CALLOUT_NUMBER 0x80060000u /* (?C with numerical argument */ +#define META_CALLOUT_STRING 0x80070000u /* (?C with string argument */ +#define META_CAPTURE 0x80080000u /* Capturing parenthesis */ +#define META_CIRCUMFLEX 0x80090000u /* ^ metacharacter */ +#define META_CLASS 0x800a0000u /* start non-empty class */ +#define META_CLASS_EMPTY 0x800b0000u /* empty class */ +#define META_CLASS_EMPTY_NOT 0x800c0000u /* negative empty class */ +#define META_CLASS_END 0x800d0000u /* end of non-empty class */ +#define META_CLASS_NOT 0x800e0000u /* start non-empty negative class */ +#define META_COND_ASSERT 0x800f0000u /* (?(?assertion)... */ +#define META_COND_DEFINE 0x80100000u /* (?(DEFINE)... */ +#define META_COND_NAME 0x80110000u /* (?()... */ +#define META_COND_NUMBER 0x80120000u /* (?(digits)... */ +#define META_COND_RNAME 0x80130000u /* (?(R&name)... */ +#define META_COND_RNUMBER 0x80140000u /* (?(Rdigits)... */ +#define META_COND_VERSION 0x80150000u /* (?(VERSIONx.y)... */ +#define META_DOLLAR 0x80160000u /* $ metacharacter */ +#define META_DOT 0x80170000u /* . metacharacter */ +#define META_ESCAPE 0x80180000u /* \d and friends */ +#define META_KET 0x80190000u /* closing parenthesis */ +#define META_NOCAPTURE 0x801a0000u /* no capture parens */ +#define META_OPTIONS 0x801b0000u /* (?i) and friends */ +#define META_POSIX 0x801c0000u /* POSIX class item */ +#define META_POSIX_NEG 0x801d0000u /* negative POSIX class item */ +#define META_RANGE_ESCAPED 0x801e0000u /* range with at least one escape */ +#define META_RANGE_LITERAL 0x801f0000u /* range defined literally */ +#define META_RECURSE 0x80200000u /* Recursion */ +#define META_RECURSE_BYNAME 0x80210000u /* (?&name) */ +#define META_SCRIPT_RUN 0x80220000u /* (*script_run:...) */ + +/* These must be kept together to make it easy to check that an assertion +is present where expected in a conditional group. */ + +#define META_LOOKAHEAD 0x80230000u /* (?= */ +#define META_LOOKAHEADNOT 0x80240000u /* (?! */ +#define META_LOOKBEHIND 0x80250000u /* (?<= */ +#define META_LOOKBEHINDNOT 0x80260000u /* (? */ CHAR_GREATER_THAN_SIGN, /* ? */ CHAR_QUESTION_MARK, - /* @ */ CHAR_COMMERCIAL_AT, /* A */ -ESC_A, - /* B */ -ESC_B, /* C */ -ESC_C, - /* D */ -ESC_D, /* E */ -ESC_E, - /* F */ 0, /* G */ -ESC_G, - /* H */ -ESC_H, /* I */ 0, - /* J */ 0, /* K */ -ESC_K, - /* L */ 0, /* M */ 0, - /* N */ -ESC_N, /* O */ 0, - /* P */ -ESC_P, /* Q */ -ESC_Q, - /* R */ -ESC_R, /* S */ -ESC_S, - /* T */ 0, /* U */ 0, - /* V */ -ESC_V, /* W */ -ESC_W, - /* X */ -ESC_X, /* Y */ 0, - /* Z */ -ESC_Z, /* [ */ CHAR_LEFT_SQUARE_BRACKET, - /* \ */ CHAR_BACKSLASH, /* ] */ CHAR_RIGHT_SQUARE_BRACKET, - /* ^ */ CHAR_CIRCUMFLEX_ACCENT, /* _ */ CHAR_UNDERSCORE, - /* ` */ CHAR_GRAVE_ACCENT, /* a */ CHAR_BEL, - /* b */ -ESC_b, /* c */ 0, - /* d */ -ESC_d, /* e */ CHAR_ESC, - /* f */ CHAR_FF, /* g */ 0, - /* h */ -ESC_h, /* i */ 0, - /* j */ 0, /* k */ -ESC_k, - /* l */ 0, /* m */ 0, - /* n */ CHAR_LF, /* o */ 0, - /* p */ -ESC_p, /* q */ 0, - /* r */ CHAR_CR, /* s */ -ESC_s, - /* t */ CHAR_HT, /* u */ 0, - /* v */ -ESC_v, /* w */ -ESC_w, - /* x */ 0, /* y */ 0, - /* z */ -ESC_z + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + CHAR_COLON, CHAR_SEMICOLON, + CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, + CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK, + CHAR_COMMERCIAL_AT, -ESC_A, + -ESC_B, -ESC_C, + -ESC_D, -ESC_E, + 0, -ESC_G, + -ESC_H, 0, + 0, -ESC_K, + 0, 0, + -ESC_N, 0, + -ESC_P, -ESC_Q, + -ESC_R, -ESC_S, + 0, 0, + -ESC_V, -ESC_W, + -ESC_X, 0, + -ESC_Z, CHAR_LEFT_SQUARE_BRACKET, + CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET, + CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE, + CHAR_GRAVE_ACCENT, CHAR_BEL, + -ESC_b, 0, + -ESC_d, CHAR_ESC, + CHAR_FF, 0, + -ESC_h, 0, + 0, -ESC_k, + 0, 0, + CHAR_LF, 0, + -ESC_p, 0, + CHAR_CR, -ESC_s, + CHAR_HT, 0, + -ESC_v, -ESC_w, + 0, 0, + -ESC_z }; #else @@ -542,8 +656,6 @@ static const char alasnames[] = STRING_non_atomic_positive_lookbehind0 STRING_negative_lookahead0 STRING_negative_lookbehind0 - STRING_scs0 - STRING_scan_substring0 STRING_atomic0 STRING_sr0 STRING_asr0 @@ -563,8 +675,6 @@ static const alasitem alasmeta[] = { { 30, META_LOOKBEHIND_NA }, { 18, META_LOOKAHEADNOT }, { 19, META_LOOKBEHINDNOT }, - { 3, META_SCS }, - { 14, META_SCS }, { 6, META_ATOMIC }, { 2, META_SCRIPT_RUN }, /* sr = script run */ { 3, META_ATOMIC_SCRIPT_RUN }, /* asr = atomic script run */ @@ -584,11 +694,8 @@ static uint32_t chartypeoffset[] = { now all in a single string, to reduce the number of relocations when a shared library is dynamically loaded. The list of lengths is terminated by a zero length entry. The first three must be alpha, lower, upper, as this is assumed -for handling case independence. - -The indices for several classes are stored in pcre2_compile.h - these must -be kept in sync with posix_names, posix_name_lengths, posix_class_maps, -and posix_substitutes. */ +for handling case independence. The indices for several classes are needed, so +identify them. */ static const char posix_names[] = STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 @@ -599,6 +706,12 @@ static const char posix_names[] = static const uint8_t posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; +#define PC_DIGIT 7 +#define PC_GRAPH 8 +#define PC_PRINT 9 +#define PC_PUNCT 10 +#define PC_XDIGIT 13 + /* Table of class bit maps for each POSIX class. Each class is formed from a base map, with an optional addition or removal of another map. Then, for some classes, there is some additional tweaking: for [:blank:] the vertical space @@ -609,7 +722,7 @@ addition or a negative value for map subtraction (if there are two maps). The absolute value of the third field has these meanings: 0 => no tweaking, 1 => remove vertical space characters, 2 => remove underscore. */ -const int PRIV(posix_class_maps)[] = { +static const int posix_class_maps[] = { cbit_word, cbit_digit, -2, /* alpha */ cbit_lower, -1, 0, /* lower */ cbit_upper, -1, 0, /* upper */ @@ -647,6 +760,7 @@ static int posix_substitutes[] = { PT_WORD, 0, /* word */ /* Perl and POSIX space are the same */ PT_PXXDIGIT, 0 /* xdigit */ /* Perl has additional hex digits */ }; +#define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t))) #endif /* SUPPORT_UNICODE */ /* Masks for checking option settings. When PCRE2_LITERAL is set, only a subset @@ -664,11 +778,10 @@ are allowed. */ PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MATCH_UNSET_BACKREF| \ PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C|PCRE2_NEVER_UCP| \ PCRE2_NEVER_UTF|PCRE2_NO_AUTO_CAPTURE|PCRE2_NO_AUTO_POSSESS| \ - PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY|PCRE2_ALT_EXTENDED_CLASS) + PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY) #define PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS \ - (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD| \ - PCRE2_EXTRA_CASELESS_RESTRICT|PCRE2_EXTRA_TURKISH_CASING) + (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_CASELESS_RESTRICT) #define PUBLIC_COMPILE_EXTRA_OPTIONS \ (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \ @@ -676,8 +789,27 @@ are allowed. */ PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX| \ PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK|PCRE2_EXTRA_ASCII_BSD| \ PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW|PCRE2_EXTRA_ASCII_POSIX| \ - PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_PYTHON_OCTAL|PCRE2_EXTRA_NO_BS0| \ - PCRE2_EXTRA_NEVER_CALLOUT) + PCRE2_EXTRA_ASCII_DIGIT) + +/* Compile time error code numbers. They are given names so that they can more +easily be tracked. When a new number is added, the tables called eint1 and +eint2 in pcre2posix.c may need to be updated, and a new error text must be +added to compile_error_texts in pcre2_error.c. Also, the error codes in +pcre2.h.in must be updated - their values are exactly 100 greater than these +values. */ + +enum { ERR0 = COMPILE_ERROR_BASE, + ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, + ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, + ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, + ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, + ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, + ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, + ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, + ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, + ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, + ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100, + ERR101 }; /* This is a table of start-of-pattern options such as (*UTF) and settings such as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward @@ -685,18 +817,16 @@ compatibility, (*UTFn) is supported in the relevant libraries, but (*UTF) is generic and always supported. */ enum { PSO_OPT, /* Value is an option bit */ - PSO_XOPT, /* Value is an xoption bit */ PSO_FLG, /* Value is a flag bit */ PSO_NL, /* Value is a newline type */ PSO_BSR, /* Value is a \R type */ PSO_LIMH, /* Read integer value for heap limit */ PSO_LIMM, /* Read integer value for match limit */ - PSO_LIMD, /* Read integer value for depth limit */ - PSO_OPTMZ /* Value is an optimization bit */ + PSO_LIMD /* Read integer value for depth limit */ }; typedef struct pso { - const char *name; + const uint8_t *name; uint16_t length; uint16_t type; uint32_t value; @@ -705,29 +835,27 @@ typedef struct pso { /* NB: STRING_UTFn_RIGHTPAR contains the length as well */ static const pso pso_list[] = { - { STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, - { STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, - { STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, - { STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET }, - { STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET }, - { STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPTMZ, PCRE2_OPTIM_AUTO_POSSESS }, - { STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPTMZ, PCRE2_OPTIM_DOTSTAR_ANCHOR }, - { STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT }, - { STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPTMZ, PCRE2_OPTIM_START_OPTIMIZE }, - { STRING_CASELESS_RESTRICT_RIGHTPAR, 18, PSO_XOPT, PCRE2_EXTRA_CASELESS_RESTRICT }, - { STRING_TURKISH_CASING_RIGHTPAR, 15, PSO_XOPT, PCRE2_EXTRA_TURKISH_CASING }, - { STRING_LIMIT_HEAP_EQ, 11, PSO_LIMH, 0 }, - { STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 }, - { STRING_LIMIT_DEPTH_EQ, 12, PSO_LIMD, 0 }, - { STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMD, 0 }, - { STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR }, - { STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF }, - { STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF }, - { STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY }, - { STRING_NUL_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_NUL }, - { STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF }, - { STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF }, - { STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE } + { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, + { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, + { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, + { (uint8_t *)STRING_NOTEMPTY_RIGHTPAR, 9, PSO_FLG, PCRE2_NOTEMPTY_SET }, + { (uint8_t *)STRING_NOTEMPTY_ATSTART_RIGHTPAR, 17, PSO_FLG, PCRE2_NE_ATST_SET }, + { (uint8_t *)STRING_NO_AUTO_POSSESS_RIGHTPAR, 16, PSO_OPT, PCRE2_NO_AUTO_POSSESS }, + { (uint8_t *)STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR, 18, PSO_OPT, PCRE2_NO_DOTSTAR_ANCHOR }, + { (uint8_t *)STRING_NO_JIT_RIGHTPAR, 7, PSO_FLG, PCRE2_NOJIT }, + { (uint8_t *)STRING_NO_START_OPT_RIGHTPAR, 13, PSO_OPT, PCRE2_NO_START_OPTIMIZE }, + { (uint8_t *)STRING_LIMIT_HEAP_EQ, 11, PSO_LIMH, 0 }, + { (uint8_t *)STRING_LIMIT_MATCH_EQ, 12, PSO_LIMM, 0 }, + { (uint8_t *)STRING_LIMIT_DEPTH_EQ, 12, PSO_LIMD, 0 }, + { (uint8_t *)STRING_LIMIT_RECURSION_EQ, 16, PSO_LIMD, 0 }, + { (uint8_t *)STRING_CR_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_CR }, + { (uint8_t *)STRING_LF_RIGHTPAR, 3, PSO_NL, PCRE2_NEWLINE_LF }, + { (uint8_t *)STRING_CRLF_RIGHTPAR, 5, PSO_NL, PCRE2_NEWLINE_CRLF }, + { (uint8_t *)STRING_ANY_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_ANY }, + { (uint8_t *)STRING_NUL_RIGHTPAR, 4, PSO_NL, PCRE2_NEWLINE_NUL }, + { (uint8_t *)STRING_ANYCRLF_RIGHTPAR, 8, PSO_NL, PCRE2_NEWLINE_ANYCRLF }, + { (uint8_t *)STRING_BSR_ANYCRLF_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_ANYCRLF }, + { (uint8_t *)STRING_BSR_UNICODE_RIGHTPAR, 12, PSO_BSR, PCRE2_BSR_UNICODE } }; /* This table is used when converting repeating opcodes into possessified @@ -782,15 +910,12 @@ static const uint8_t opcode_possessify[] = { OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */ 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */ - 0, 0, 0, 0, /* CLASS, NCLASS, XCLASS, ECLASS */ + 0, 0, 0, /* CLASS, NCLASS, XCLASS */ 0, 0, /* REF, REFI */ 0, 0, /* DNREF, DNREFI */ - 0, 0, /* RECURSE, CALLOUT */ + 0, 0 /* RECURSE, CALLOUT */ }; -/* Compile-time check that the table has the correct size. */ -STATIC_ASSERT(sizeof(opcode_possessify) == OP_CALLOUT+1, opcode_possessify); - #ifdef DEBUG_SHOW_PARSED /************************************************* @@ -852,7 +977,7 @@ for (;;) { uint32_t ptype = *pptr >> 16; uint32_t pvalue = *pptr++ & 0xffff; - fprintf(stderr, "META \\%c %d %d", (meta_arg == ESC_P)? CHAR_P:CHAR_p, + fprintf(stderr, "META \\%c %d %d", (meta_arg == ESC_P)? 'P':'p', ptype, pvalue); } else @@ -1027,24 +1152,6 @@ for (;;) fprintf(stderr, "%zd", offset); break; - case META_OFFSET: - fprintf(stderr, "META_OFFSET offset="); - GETOFFSET(offset, pptr); - fprintf(stderr, "%zd", offset); - break; - - case META_SCS: - fprintf(stderr, "META (*scan_substring:"); - break; - - case META_SCS_NAME: - fprintf(stderr, "META_SCS_NAME length=%d relative_offset=%d", *pptr++, (int)meta_arg); - break; - - case META_SCS_NUMBER: - fprintf(stderr, "META_SCS_NUMBER %d relative_offset=%d", *pptr++, (int)meta_arg); - break; - case META_MARK: fprintf(stderr, "META (*MARK:"); goto SHOWARG; @@ -1073,12 +1180,6 @@ for (;;) } fprintf(stderr, ") length=%u", length); break; - - case META_ECLASS_AND: fprintf(stderr, "META_ECLASS_AND"); break; - case META_ECLASS_OR: fprintf(stderr, "META_ECLASS_OR"); break; - case META_ECLASS_SUB: fprintf(stderr, "META_ECLASS_SUB"); break; - case META_ECLASS_XOR: fprintf(stderr, "META_ECLASS_XOR"); break; - case META_ECLASS_NOT: fprintf(stderr, "META_ECLASS_NOT"); break; } fprintf(stderr, "\n"); } @@ -1098,7 +1199,7 @@ associated JIT data. */ PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION pcre2_code_copy(const pcre2_code *code) { -PCRE2_SIZE *ref_count; +PCRE2_SIZE* ref_count; pcre2_code *newcode; if (code == NULL) return NULL; @@ -1210,10 +1311,7 @@ result must be greater than zero. ptrptr points to the character pointer variable ptrend points to the end of the input string allow_sign if < 0, sign not allowed; if >= 0, sign is relative to this - max_value the largest number allowed; - you must not pass a value for max_value larger than - INT_MAX/10 - 1 because this function relies on max_value to - avoid integer overflow + max_value the largest number allowed max_error the error to give for an over-large number intptr where to put the result errcodeptr where to put an error code @@ -1232,8 +1330,6 @@ uint32_t n = 0; PCRE2_SPTR ptr = *ptrptr; BOOL yield = FALSE; -PCRE2_ASSERT(max_value <= INT_MAX/10 - 1); - *errorcodeptr = 0; if (allow_sign >= 0 && ptr < ptrend) @@ -1254,11 +1350,10 @@ if (allow_sign >= 0 && ptr < ptrend) if (ptr >= ptrend || !IS_DIGIT(*ptr)) return FALSE; while (ptr < ptrend && IS_DIGIT(*ptr)) { - n = n * 10 + (*ptr++ - CHAR_0); + n = n * 10 + *ptr++ - CHAR_0; if (n > max_value) { *errorcodeptr = max_error; - while (ptr < ptrend && IS_DIGIT(*ptr)) ptr++; goto EXIT; } } @@ -1272,7 +1367,7 @@ if (allow_sign >= 0 && sign != 0) } if (sign > 0) n += allow_sign; - else if (n > (uint32_t)allow_sign) + else if ((int)n > allow_sign) { *errorcodeptr = ERR15; /* Non-existent subpattern */ goto EXIT; @@ -1359,7 +1454,7 @@ else if (pp >= ptrend || *pp != CHAR_RIGHT_CURLY_BRACKET) return FALSE; } -/* Now process the quantifier for real. We know it must be {n} or {n,} or {,m} +/* Now process the quantifier for real. We know it must be {n} or (n,} or {,m} or {n,m}. The only error that read_number() can return is for a number that is too big. If *errorcodeptr is returned as zero it means no number was found. */ @@ -1426,15 +1521,15 @@ return yield; /* This function is called when a \ has been encountered. It either returns a positive value for a simple escape such as \d, or 0 for a data character, which -is placed in chptr. A backreference to group n is returned as -(n+1). On +is placed in chptr. A backreference to group n is returned as negative n. On entry, ptr is pointing at the character after \. On exit, it points after the final code unit of the escape sequence. This function is also called from pcre2_substitute() to handle escape sequences in replacement strings. In this case, the cb argument is NULL, and in the case of escapes that have further processing, only sequences that define a data -character are recognised. The options argument is the final value of the -compiled pattern's options. +character are recognised. The isclass argument is not relevant; the options +argument is the final value of the compiled pattern's options. Arguments: ptrptr points to the input position pointer @@ -1443,8 +1538,7 @@ compiled pattern's options. errorcodeptr points to the errorcode variable (containing zero) options the current options bits xoptions the current extra options bits - bracount the number of capturing parentheses encountered so far - isclass TRUE if in a character class + isclass TRUE if inside a character class cb compile data block or NULL when called from pcre2_substitute() Returns: zero => a data character @@ -1455,8 +1549,8 @@ Returns: zero => a data character int PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr, - int *errorcodeptr, uint32_t options, uint32_t xoptions, uint32_t bracount, - BOOL isclass, compile_block *cb) + int *errorcodeptr, uint32_t options, uint32_t xoptions, BOOL isclass, + compile_block *cb) { BOOL utf = (options & PCRE2_UTF) != 0; BOOL alt_bsux = @@ -1525,23 +1619,17 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) if (ptrend - p > 1 && *p == CHAR_U && p[1] == CHAR_PLUS) { -#ifndef EBCDIC +#ifdef EBCDIC + *errorcodeptr = ERR93; +#else if (utf) { ptr = p + 2; escape = 0; /* Not a fancy escape after all */ goto COME_FROM_NU; } + else *errorcodeptr = ERR93; #endif - *errorcodeptr = ERR93; - } - - /* Give an error in contexts where quantifiers are not allowed - (character classes; substitution strings). */ - - else if (isclass || cb == NULL) - { - *errorcodeptr = ERR37; } /* Give an error if what follows is not a quantifier, but don't override @@ -1572,8 +1660,7 @@ else if (cb == NULL) { - if (c < CHAR_0 || - (c > CHAR_9 && (c != CHAR_c && c != CHAR_o && c != CHAR_x && c != CHAR_g))) + if (c != CHAR_c && c != CHAR_o && c != CHAR_x) { *errorcodeptr = ERR3; return 0; @@ -1628,7 +1715,6 @@ else hptr >= ptrend || /* Hit end of input */ *hptr != CHAR_RIGHT_CURLY_BRACKET) /* No } terminator */ { - if (isclass) break; /* In a class, just treat as '\u' literal */ escape = ESC_ub; /* Special return */ ptr++; /* Skip { */ break; /* Hex escape not recognized */ @@ -1687,14 +1773,8 @@ else (possibly recursive) subroutine calls, _not_ backreferences. We return the ESC_g code. - Summary: Return a negative number for a numerical back reference (offset - by 1), ESC_k for a named back reference, and ESC_g for a named or - numbered subroutine call. - - The above describes the \g behaviour inside patterns. Inside replacement - strings (pcre2_substitute) we support only \g for Python - compatibility. Return ESG_g for the named case, and -(num+1) for the - numbered case. + Summary: Return a negative number for a numerical back reference, ESC_k for + a named back reference, and ESC_g for a named or numbered subroutine call. */ case CHAR_g: @@ -1706,40 +1786,6 @@ else break; } - if (cb == NULL) - { - PCRE2_SPTR p; - /* Substitution strings */ - if (*ptr != CHAR_LESS_THAN_SIGN) - { - *errorcodeptr = ERR57; - break; - } - - p = ptr + 1; - - if (!read_number(&p, ptrend, -1, MAX_GROUP_NUMBER, ERR61, &s, - errorcodeptr)) - { - if (*errorcodeptr == 0) escape = ESC_g; /* No number found */ - break; - } - - if (p >= ptrend || *p != CHAR_GREATER_THAN_SIGN) - { - /* not advancing ptr; report error at the \g character */ - *errorcodeptr = ERR57; - break; - } - - /* This is the reason that back references are returned as -(s+1) rather - than just -s. In a pattern, \0 is not a back reference, but \g<0> is - valid in a substitution string, so this must be representable. */ - ptr = p + 1; - escape = -(s+1); - break; - } - if (*ptr == CHAR_LESS_THAN_SIGN || *ptr == CHAR_APOSTROPHE) { escape = ESC_g; @@ -1754,7 +1800,7 @@ else PCRE2_SPTR p = ptr + 1; while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; - if (!read_number(&p, ptrend, bracount, MAX_GROUP_NUMBER, ERR61, &s, + if (!read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s, errorcodeptr)) { if (*errorcodeptr == 0) escape = ESC_k; /* No number found */ @@ -1764,7 +1810,6 @@ else if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET) { - /* not advancing ptr; report error at the \g character */ *errorcodeptr = ERR57; break; } @@ -1775,7 +1820,7 @@ else else { - if (!read_number(&ptr, ptrend, bracount, MAX_GROUP_NUMBER, ERR61, &s, + if (!read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s, errorcodeptr)) { if (*errorcodeptr == 0) *errorcodeptr = ERR57; /* No number found */ @@ -1789,7 +1834,7 @@ else break; } - escape = -(s+1); + escape = -s; break; /* The handling of escape sequences consisting of a string of digits @@ -1801,16 +1846,7 @@ else number is less than 10, or if there are that many previous extracting left brackets, it is a back reference. Otherwise, up to three octal digits are read to form an escaped character code. Thus \123 is likely to be octal 123 - (cf \0123, which is octal 012 followed by the literal 3). This is the "Perl - style" of handling ambiguous octal/backrefences such as \12. - - There is an alternative disambiguation strategy, selected by - PCRE2_EXTRA_PYTHON_OCTAL, which follows Python's behaviour. An octal must - have either a leading zero, or exactly three octal digits; otherwise it's - a backreference. The disambiguation is stable, and does not depend on how - many capture groups are defined (it's simply an invalid backreference if - there is no corresponding capture group). Additionally, octal values above - \377 (\xff) are rejected. + (cf \0123, which is octal 012 followed by the literal 3). Inside a character class, \ followed by a digit is always either a literal 8 or 9 or an octal number. */ @@ -1818,65 +1854,24 @@ else case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: - if (isclass) - { - /* Fall through to octal handling; never a backreference inside a class. */ - } - else if ((xoptions & PCRE2_EXTRA_PYTHON_OCTAL) != 0) - { - /* Python-style disambiguation. */ - if (ptr[-1] <= CHAR_7 && ptr + 1 < ptrend && ptr[0] >= CHAR_0 && - ptr[0] <= CHAR_7 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7) - { - /* We peeked a three-digit octal, so fall through */ - } - else - { - /* We are at a digit, so the only possible error from read_number() is - a number that is too large. */ - ptr--; /* Back to the digit */ - - if (!read_number(&ptr, ptrend, -1, MAX_GROUP_NUMBER, 0, &s, errorcodeptr)) - { - *errorcodeptr = ERR61; - break; - } - - escape = -(s+1); - break; - } - } - else + if (!isclass) { - /* Perl-style disambiguation. */ oldptr = ptr; ptr--; /* Back to the digit */ /* As we know we are at a digit, the only possible error from - read_number() is a number that is too large to be a group number. Because - that number might be still valid if read as an octal, errorcodeptr is not - set on failure and therefore a sentinel value of INT_MAX is used instead - of the original value, and will be used later to properly set the error, - if not falling through. */ - - if (!read_number(&ptr, ptrend, -1, MAX_GROUP_NUMBER, 0, &s, errorcodeptr)) - s = INT_MAX; + read_number() is a number that is too large to be a group number. In this + case we fall through handle this as not a group reference. If we have + read a small enough number, check for a back reference. - /* \1 to \9 are always back references. \8x and \9x are too; \1x to \7x + \1 to \9 are always back references. \8x and \9x are too; \1x to \7x are octal escapes if there are not that many previous captures. */ - if (s < 10 || c >= CHAR_8 || (unsigned)s <= bracount) + if (read_number(&ptr, ptrend, -1, INT_MAX/10 - 1, 0, &s, errorcodeptr) && + (s < 10 || oldptr[-1] >= CHAR_8 || s <= (int)cb->bracount)) { - /* s > MAX_GROUP_NUMBER should not be possible because of read_number(), - but we keep it just to be safe and because it will also catch the - sentinel value that was set on failure by that function. */ - - if ((unsigned)s > MAX_GROUP_NUMBER) - { - PCRE2_ASSERT(s == INT_MAX); - *errorcodeptr = ERR61; - } - else escape = -(s+1); /* Indicates a back reference */ + if (s > (int)MAX_GROUP_NUMBER) *errorcodeptr = ERR61; + else escape = -s; /* Indicates a back reference */ break; } @@ -1895,26 +1890,16 @@ else /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least significant 8 bits of octal numbers (I think this is what early Perls used - to do). Nowadays we allow for larger numbers in UTF-8 mode and 16/32-bit mode, + to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode, but no more than 3 octal digits. */ case CHAR_0: c -= CHAR_0; while(i++ < 2 && ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) c = c * 8 + *ptr++ - CHAR_0; - if (c > 0xff) - { - if ((xoptions & PCRE2_EXTRA_PYTHON_OCTAL) != 0) *errorcodeptr = ERR102; #if PCRE2_CODE_UNIT_WIDTH == 8 - else if (!utf) *errorcodeptr = ERR51; + if (!utf && c > 0xff) *errorcodeptr = ERR51; #endif - } - - /* PCRE2_EXTRA_NO_BS0 disables the NUL escape '\0' but doesn't affect - two- or three-character octal escapes \00 and \000, nor \x00. */ - - if ((xoptions & PCRE2_EXTRA_NO_BS0) != 0 && c == 0 && i == 1) - *errorcodeptr = ERR98; break; /* \o is a relatively new Perl feature, supporting a more general way of @@ -1943,7 +1928,7 @@ else cc = *ptr++; if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ #if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x20000000u) { overflow = TRUE; break; } + if (c >= 0x20000000l) { overflow = TRUE; break; } #endif c = (c << 3) + (cc - CHAR_0); #if PCRE2_CODE_UNIT_WIDTH == 8 @@ -2069,29 +2054,10 @@ else else { - /* Perl has the surprising/broken behaviour that \x without following - hex digits is treated as an escape for NUL. Their source code laments - this but keeps it for backwards compatibility. A warning is printed - when "use warnings" is enabled. Because we don't have warnings, we - simply forbid it. */ - if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) - { - /* Not a hex digit */ - *errorcodeptr = ERR78; - break; - } + c = 0; + if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */ ptr++; c = cc; - - /* With "use re 'strict'" Perl actually requires exactly two digits (error - for \x, \xA and \xAAA). While \x was already rejected, this seems overly - strict, and there seems little incentive to align with that, given the - backwards-compatibility cost. - - For comparison, note that other engines disagree. For example: - - Java allows 1 or 2 hex digits. Error if 0 digits. No error if >2 digits - - .NET requires 2 hex digits. Error if 0, 1 digits. No error if >2 digits. - */ if (ptr >= ptrend || (cc = XDIGIT(*ptr)) == 0xff) break; /* Not a hex digit */ ptr++; c = (c << 4) | cc; @@ -2213,65 +2179,37 @@ c = *ptr++; *negptr = FALSE; /* \P or \p can be followed by a name in {}, optionally preceded by ^ for -negation. We must be handling Unicode encoding here, though we may be compiling -for UTF-8 input in an EBCDIC environment. (PCRE2 does not support both EBCDIC -input and Unicode input in the same build.) In accordance with Unicode's "loose -matching" rules, ASCII white space, hyphens, and underscores are ignored. We -don't use isspace() or tolower() because (a) code points may be greater than -255, and (b) they wouldn't work when compiling for Unicode in an EBCDIC -environment. */ +negation. */ if (c == CHAR_LEFT_CURLY_BRACKET) { if (ptr >= cb->end_pattern) goto ERROR_RETURN; - for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++) + if (*ptr == CHAR_CIRCUMFLEX_ACCENT) { - REDO: + *negptr = TRUE; + ptr++; + } + for (i = 0; i < (int)(sizeof(name) / sizeof(PCRE2_UCHAR)) - 1; i++) + { if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; - - /* Skip ignorable Unicode characters. */ - - while (c == CHAR_UNDERSCORE || c == CHAR_MINUS || c == CHAR_SPACE || - (c >= CHAR_HT && c <= CHAR_CR)) +#if PCRE2_CODE_UNIT_WIDTH != 8 + while (c == '_' || c == '-' || (c <= 0xff && isspace(c))) +#else + while (c == '_' || c == '-' || isspace(c)) +#endif { if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; } - - /* The first significant character being circumflex negates the meaning of - the item. */ - - if (i == 0 && !*negptr && c == CHAR_CIRCUMFLEX_ACCENT) - { - *negptr = TRUE; - goto REDO; - } - + if (c == CHAR_NUL) goto ERROR_RETURN; if (c == CHAR_RIGHT_CURLY_BRACKET) break; - - /* Names consist of ASCII letters and digits, but equals and colon may also - occur as a name/value separator. We must also allow for \p{L&}. A simple - check for a value between '&' and 'z' suffices because anything else in a - name or value will cause an "unknown property" error anyway. */ - - if (c < CHAR_AMPERSAND || c > CHAR_z) goto ERROR_RETURN; - - /* Lower case a capital letter or remember where the name/value separator - is. */ - - if (c >= CHAR_A && c <= CHAR_Z) c |= 0x20; - else if ((c == CHAR_COLON || c == CHAR_EQUALS_SIGN) && vptr == NULL) - vptr = name + i; - - name[i] = c; + name[i] = tolower(c); + if ((c == ':' || c == '=') && vptr == NULL) vptr = name + i; } - /* Error if the loop didn't end with '}' - either we hit the end of the - pattern or the name was longer than any legal property name. */ - if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN; name[i] = 0; } @@ -2279,19 +2217,14 @@ if (c == CHAR_LEFT_CURLY_BRACKET) /* If { doesn't follow \p or \P there is just one following character, which must be an ASCII letter. */ -else if (c >= CHAR_A && c <= CHAR_Z) - { - name[0] = c | 0x20; /* Lower case */ - name[1] = 0; - } -else if (c >= CHAR_a && c <= CHAR_z) +else if (MAX_255(c) && (cb->ctypes[c] & ctype_letter) != 0) { - name[0] = c; + name[0] = tolower(c); name[1] = 0; } else goto ERROR_RETURN; -*ptrptr = ptr; /* Update pattern pointer */ +*ptrptr = ptr; /* If the property contains ':' or '=' we have class name and value separately specified. The following are supported: @@ -2549,9 +2482,6 @@ if (ptr >= ptrend) /* No characters in name */ *nameptr = ptr; *offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern); -/* If this logic were ever to change, the matching function in pcre2_substitute.c -ought to be updated to match. */ - /* In UTF mode, a group name may contain letters and decimal digits as defined by Unicode properties, and underscores, but must not start with a digit. */ @@ -2770,60 +2700,6 @@ return parsed_pattern; -/************************************************* -* Maximum size of parsed_pattern for given input * -*************************************************/ - -/* This function is called from parse_regex() below, to determine the amount -of memory to allocate for parsed_pattern. It is also called to check whether -the amount of data written respects the amount of memory allocated. - -Arguments: - ptr points to the start of the pattern - ptrend points to the end of the pattern - utf TRUE in UTF mode - options the options bits - -Returns: the number of uint32_t units for parsed_pattern -*/ -static ptrdiff_t -max_parsed_pattern(PCRE2_SPTR ptr, PCRE2_SPTR ptrend, BOOL utf, - uint32_t options) -{ -PCRE2_SIZE big32count = 0; -ptrdiff_t parsed_size_needed; - -/* When PCRE2_AUTO_CALLOUT is not set, in all but one case the number of -unsigned 32-bit ints written out to the parsed pattern is bounded by the length -of the pattern. The exceptional case is when running in 32-bit, non-UTF mode, -when literal characters greater than META_END (0x80000000) have to be coded as -two units. In this case, therefore, we scan the pattern to check for such -values. */ - -#if PCRE2_CODE_UNIT_WIDTH == 32 -if (!utf) - { - PCRE2_SPTR p; - for (p = ptr; p < ptrend; p++) if (*p >= META_END) big32count++; - } -#else -(void)utf; /* Avoid compiler warning */ -#endif - -parsed_size_needed = (ptrend - ptr) + big32count; - -/* When PCRE2_AUTO_CALLOUT is set we have to assume a numerical callout (4 -elements) for each character. This is overkill, but memory is plentiful these -days. */ - -if ((options & PCRE2_AUTO_CALLOUT) != 0) - parsed_size_needed += (ptrend - ptr) * 4; - -return parsed_size_needed; -} - - - /************************************************* * Parse regex and identify named groups * *************************************************/ @@ -2875,33 +2751,7 @@ the main compiling phase. */ /* States used for analyzing ranges in character classes. The two OK values must be last. */ -enum { - RANGE_NO, /* State after '[' (initial), or '[a-z'; hyphen is literal */ - RANGE_STARTED, /* State after '[1-'; last-emitted code is META_RANGE_XYZ */ - RANGE_FORBID_NO, /* State after '[\d'; '-]' is allowed but not '-1]' */ - RANGE_FORBID_STARTED, /* State after '[\d-'*/ - RANGE_OK_ESCAPED, /* State after '[\1'; hyphen may be a range */ - RANGE_OK_LITERAL /* State after '[1'; hyphen may be a range */ -}; - -/* States used for analyzing operators and operands in extended character -classes. */ - -enum { - CLASS_OP_EMPTY, /* At start of an expression; empty previous contents */ - CLASS_OP_OPERAND, /* Have preceding operand; after "z" a "--" can follow */ - CLASS_OP_OPERATOR /* Have preceding operator; after "--" operand must follow */ -}; - -/* States used for determining the parse mode in character classes. The two -PERL_EXT values must be last. */ - -enum { - CLASS_MODE_NORMAL, /* Ordinary PCRE2 '[...]' class. */ - CLASS_MODE_ALT_EXT, /* UTS#18-style extended '[...]' class. */ - CLASS_MODE_PERL_EXT, /* Perl extended '(?[...])' class. */ - CLASS_MODE_PERL_EXT_LEAF /* Leaf within extended '(?[ [...] ])' class. */ -}; +enum { RANGE_NO, RANGE_STARTED, RANGE_OK_ESCAPED, RANGE_OK_LITERAL }; /* Only in 32-bit mode can there be literals > META_END. A macro encapsulates the storing of literal values in the main parsed pattern, where they can always @@ -2920,16 +2770,13 @@ be quantified. */ /* Here's the actual function. */ -static int parse_regex(PCRE2_SPTR ptr, uint32_t options, uint32_t xoptions, - BOOL *has_lookbehind, compile_block *cb) +static int parse_regex(PCRE2_SPTR ptr, uint32_t options, BOOL *has_lookbehind, + compile_block *cb) { uint32_t c; uint32_t delimiter; uint32_t namelen; uint32_t class_range_state; -uint32_t class_op_state; -uint32_t class_mode_state; -uint32_t *class_start; uint32_t *verblengthptr = NULL; /* Value avoids compiler warning */ uint32_t *verbstartptr = NULL; uint32_t *previous_callout = NULL; @@ -2939,9 +2786,8 @@ uint32_t *this_parsed_item = NULL; uint32_t *prev_parsed_item = NULL; uint32_t meta_quantifier = 0; uint32_t add_after_mark = 0; +uint32_t xoptions = cb->cx->extra_options; uint16_t nest_depth = 0; -int16_t class_depth_m1 = -1; /* The m1 means minus 1. */ -int16_t class_maxdepth_m1 = -1; int after_manual_callout = 0; int expect_cond_assert = 0; int errorcode = 0; @@ -2958,17 +2804,8 @@ PCRE2_SPTR thisptr; PCRE2_SPTR name; PCRE2_SPTR ptrend = cb->end_pattern; PCRE2_SPTR verbnamestart = NULL; /* Value avoids compiler warning */ -PCRE2_SPTR class_range_forbid_ptr = NULL; named_group *ng; nest_save *top_nest, *end_nests; -#ifdef PCRE2_DEBUG -uint32_t *parsed_pattern_check; -ptrdiff_t parsed_pattern_extra = 0; -ptrdiff_t parsed_pattern_extra_check = 0; -PCRE2_SPTR ptr_check; -#endif - -PCRE2_ASSERT(parsed_pattern != NULL); /* Insert leading items for word and line matching (features provided for the benefit of pcre2grep). */ @@ -2984,11 +2821,6 @@ else if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0) *parsed_pattern++ = META_NOCAPTURE; } -#ifdef PCRE2_DEBUG -parsed_pattern_check = parsed_pattern; -ptr_check = ptr; -#endif - /* If the pattern is actually a literal string, process it separately to avoid cluttering up the main loop. */ @@ -2998,7 +2830,6 @@ if ((options & PCRE2_LITERAL) != 0) { if (parsed_pattern >= parsed_pattern_end) { - PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR63; /* Internal error (parsed pattern overflow) */ goto FAILED; } @@ -3042,40 +2873,18 @@ while (ptr < ptrend) PCRE2_SPTR tempptr; PCRE2_SIZE offset; - if (nest_depth > cb->cx->parens_nest_limit) - { - errorcode = ERR19; - goto FAILED; /* Parentheses too deeply nested */ - } - - /* Check that we haven't emitted too much into parsed_pattern. We allocate - a suitably-sized buffer upfront, then do unchecked writes to it. If we only - write a little bit too much, everything will appear to be OK, because the - upfront size is an overestimate... but a malicious pattern could end up - forcing a write past the buffer end. We must catch this during - development. */ - -#ifdef PCRE2_DEBUG - /* Strong post-write check. Won't help in release builds - at this point - the write has already occurred so it's too late. However, should stop us - committing unsafe code. */ - PCRE2_ASSERT((parsed_pattern - parsed_pattern_check) + - (parsed_pattern_extra - parsed_pattern_extra_check) <= - max_parsed_pattern(ptr_check, ptr, utf, options)); - parsed_pattern_check = parsed_pattern; - parsed_pattern_extra_check = parsed_pattern_extra; - ptr_check = ptr; -#endif - if (parsed_pattern >= parsed_pattern_end) { - /* Weak pre-write check; only ensures parsed_pattern[0] is writeable - (but the code below can write many chars). Better than nothing. */ - PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR63; /* Internal error (parsed pattern overflow) */ goto FAILED; } + if (nest_depth > cb->cx->parens_nest_limit) + { + errorcode = ERR19; + goto FAILED; /* Parentheses too deeply nested */ + } + /* If the last time round this loop something was added, parsed_pattern will no longer be equal to this_parsed_item. Remember where the previous item started and reset for the next item. Note that sometimes round the loop, @@ -3195,7 +3004,7 @@ while (ptr < ptrend) if ((options & PCRE2_ALT_VERBNAMES) != 0) { escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - xoptions, cb->bracount, FALSE, cb); + xoptions, FALSE, cb); if (errorcode != 0) goto FAILED; } else escape = 0; /* Treat all as literal */ @@ -3395,7 +3204,7 @@ while (ptr < ptrend) case CHAR_BACKSLASH: tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - xoptions, cb->bracount, FALSE, cb); + xoptions, FALSE, cb); if (errorcode != 0) { ESCAPE_FAILED: @@ -3426,7 +3235,7 @@ while (ptr < ptrend) else if (escape < 0) { offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 1); - escape = -escape - 1; + escape = -escape; *parsed_pattern++ = META_BACKREF | (uint32_t)escape; if (escape < 10) { @@ -3538,7 +3347,7 @@ while (ptr < ptrend) /* When \g is used with quotes or angle brackets as delimiters, it is a numerical or named subroutine call, and control comes here. When used - with brace delimiters it is a numerical back reference and does not come + with brace delimiters it is a numberical back reference and does not come here because check_escape() returns it directly as a reference. \k is always a named back reference. */ @@ -3649,7 +3458,7 @@ while (ptr < ptrend) if (!prev_okquantifier) { errorcode = ERR9; - goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549 + goto FAILED_BACK; } /* Most (*VERB)s are not allowed to be quantified, but an ungreedy @@ -3665,11 +3474,6 @@ while (ptr < ptrend) *verbstartptr = META_NOCAPTURE; parsed_pattern[1] = META_KET; parsed_pattern += 2; - -#ifdef PCRE2_DEBUG - PCRE2_ASSERT(parsed_pattern_extra >= 2); - parsed_pattern_extra -= 2; -#endif } /* Now we can put the quantifier into the parsed pattern vector. At this @@ -3689,6 +3493,7 @@ while (ptr < ptrend) /* ---- Character class ---- */ case CHAR_LEFT_SQUARE_BRACKET: + okquantifier = TRUE; /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is used for "start of word" and "end of word". As these are otherwise illegal @@ -3726,7 +3531,6 @@ while (ptr < ptrend) } *parsed_pattern++ = META_KET; ptr += 6; - okquantifier = TRUE; break; } @@ -3741,14 +3545,46 @@ while (ptr < ptrend) goto FAILED; } - class_mode_state = ((options & PCRE2_ALT_EXTENDED_CLASS) != 0)? - CLASS_MODE_ALT_EXT : CLASS_MODE_NORMAL; + /* Process a regular character class. If the first character is '^', set + the negation flag. If the first few characters (either before or after ^) + are \Q\E or \E or space or tab in extended-more mode, we skip them too. + This makes for compatibility with Perl. */ + + negate_class = FALSE; + while (ptr < ptrend) + { + GETCHARINCTEST(c, ptr); + if (c == CHAR_BACKSLASH) + { + if (ptr < ptrend && *ptr == CHAR_E) ptr++; + else if (ptrend - ptr >= 3 && + PRIV(strncmp_c8)(ptr, STR_Q STR_BACKSLASH STR_E, 3) == 0) + ptr += 3; + else + break; + } + else if ((options & PCRE2_EXTENDED_MORE) != 0 && + (c == CHAR_SPACE || c == CHAR_HT)) /* Note: just these two */ + continue; + else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) + negate_class = TRUE; + else break; + } + + /* Now the real contents of the class; c has the first "real" character. + Empty classes are permitted only if the option is set. */ + + if (c == CHAR_RIGHT_SQUARE_BRACKET && + (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0) + { + *parsed_pattern++ = negate_class? META_CLASS_EMPTY_NOT : META_CLASS_EMPTY; + break; /* End of class processing */ + } - /* Jump here from '(?[...])'. That jump must initialize class_mode_state, - set c to the '[' character, and ptr to just after the '['. */ + /* Process a non-empty class. */ - FROM_PERL_EXTENDED_CLASS: - okquantifier = TRUE; + *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS; + class_range_state = RANGE_NO; /* In an EBCDIC environment, Perl treats alphabetic ranges specially because there are holes in the encoding, and simply using the range A-Z @@ -3758,16 +3594,7 @@ while (ptr < ptrend) character values are literal or not, and a state variable for handling ranges. */ - /* Loop for the contents of the class. Classes may be nested, if - PCRE2_ALT_EXTENDED_CLASS is set, or the class is of the form (?[...]). */ - - /* c is still set to '[' so the loop will handle the start of the class. */ - - class_depth_m1 = -1; - class_maxdepth_m1 = -1; - class_range_state = RANGE_NO; - class_op_state = CLASS_OP_EMPTY; - class_start = NULL; + /* Loop for the contents of the class */ for (;;) { @@ -3783,26 +3610,13 @@ while (ptr < ptrend) ptr++; /* Skip the 'E' */ goto CLASS_CONTINUE; } - - /* Surprisingly, you cannot use \Q..\E to escape a character inside a - Perl extended class. However, empty \Q\E sequences are allowed, so here - were're only giving an error if the \Q..\E is non-empty. */ - - if (class_mode_state == CLASS_MODE_PERL_EXT) - { - errorcode = ERR116; - goto FAILED; - } - goto CLASS_LITERAL; } - /* Skip over space and tab (only) in extended-more mode, or anywhere - inside a Perl extended class (which implies /xx). */ + /* Skip over space and tab (only) in extended-more mode. */ - if ((c == CHAR_SPACE || c == CHAR_HT) && - ((options & PCRE2_EXTENDED_MORE) != 0 || - class_mode_state >= CLASS_MODE_PERL_EXT)) + if ((options & PCRE2_EXTENDED_MORE) != 0 && + (c == CHAR_SPACE || c == CHAR_HT)) goto CLASS_CONTINUE; /* Handle POSIX class names. Perl allows a negation extension of the @@ -3811,8 +3625,7 @@ while (ptr < ptrend) [.ch.] and [=ch=] ("collating elements") and fault them, as Perl 5.6 and 5.8 do. */ - if (class_depth_m1 >= 0 && - c == CHAR_LEFT_SQUARE_BRACKET && + if (c == CHAR_LEFT_SQUARE_BRACKET && ptrend - ptr >= 3 && (*ptr == CHAR_COLON || *ptr == CHAR_DOT || *ptr == CHAR_EQUALS_SIGN) && @@ -3828,41 +3641,14 @@ while (ptr < ptrend) if (class_range_state == RANGE_STARTED) { - ptr = tempptr + 2; - errorcode = ERR50; - goto FAILED; - } - - /* Perl treats a hyphen after a POSIX class as a literal, not the - start of a range. However, it gives a warning in its warning mode - unless the hyphen is the last character in the class. PCRE does not - have a warning mode, so we give an error, because this is likely an - error on the user's part. - - Roll back to the hyphen for the error position. */ - - if (class_range_state == RANGE_FORBID_STARTED) - { - ptr = class_range_forbid_ptr; errorcode = ERR50; goto FAILED; } - /* Disallow implicit union in Perl extended classes. */ - - if (class_op_state == CLASS_OP_OPERAND && - class_mode_state == CLASS_MODE_PERL_EXT) - { - ptr = tempptr + 2; - errorcode = ERR113; - goto FAILED; - } - if (*ptr != CHAR_COLON) { - ptr = tempptr + 2; errorcode = ERR13; - goto FAILED; + goto FAILED_BACK; } if (*(++ptr) == CHAR_CIRCUMFLEX_ACCENT) @@ -3872,19 +3658,33 @@ while (ptr < ptrend) } posix_class = check_posix_name(ptr, (int)(tempptr - ptr)); - ptr = tempptr + 2; if (posix_class < 0) { errorcode = ERR30; goto FAILED; } + ptr = tempptr + 2; + + /* Perl treats a hyphen after a POSIX class as a literal, not the + start of a range. However, it gives a warning in its warning mode + unless the hyphen is the last character in the class. PCRE does not + have a warning mode, so we give an error, because this is likely an + error on the user's part. */ + + if (ptr < ptrend - 1 && *ptr == CHAR_MINUS && + ptr[1] != CHAR_RIGHT_SQUARE_BRACKET) + { + errorcode = ERR50; + goto FAILED; + } - /* Set "a hyphen is forbidden to be the start of a range". For the '-]' - case, the hyphen is treated as a literal, but for '-1' it is disallowed - (because it would be interpreted as range). */ + /* Set "a hyphen is not the start of a range" for the -] case, and also + in case the POSIX class is followed by \E or \Q\E (possibly repeated - + fuzzers do that kind of thing) and *then* a hyphen. This causes that + hyphen to be treated as a literal. I don't think it's worth setting up + special apparatus to do otherwise. */ - class_range_state = RANGE_FORBID_NO; - class_op_state = CLASS_OP_OPERAND; + class_range_state = RANGE_NO; /* When PCRE2_UCP is set, unless PCRE2_EXTRA_ASCII_POSIX is set, some of the POSIX classes are converted to use Unicode properties \p or \P @@ -3927,344 +3727,56 @@ while (ptr < ptrend) *parsed_pattern++ = posix_class; } - /* Check for the start of the outermost class, or the start of a nested class. */ + /* Handle potential start of range */ - else if ((c == CHAR_LEFT_SQUARE_BRACKET && - (class_depth_m1 < 0 || class_mode_state == CLASS_MODE_ALT_EXT || - class_mode_state == CLASS_MODE_PERL_EXT)) || - (c == CHAR_LEFT_PARENTHESIS && - class_mode_state == CLASS_MODE_PERL_EXT)) + else if (c == CHAR_MINUS && class_range_state >= RANGE_OK_ESCAPED) { - uint32_t start_c = c; - uint32_t new_class_mode_state; - - /* Update the class mode, if moving into a 'leaf' inside a Perl extended - class. */ - - if (start_c == CHAR_LEFT_SQUARE_BRACKET && - class_mode_state == CLASS_MODE_PERL_EXT && class_depth_m1 >= 0) - new_class_mode_state = CLASS_MODE_PERL_EXT_LEAF; - else - new_class_mode_state = class_mode_state; + *parsed_pattern++ = (class_range_state == RANGE_OK_LITERAL)? + META_RANGE_LITERAL : META_RANGE_ESCAPED; + class_range_state = RANGE_STARTED; + } - /* Tidy up the other class before starting the nested class. */ - /* -[ beginning a nested class is a literal '-' */ + /* Handle a literal character */ + else if (c != CHAR_BACKSLASH) + { + CLASS_LITERAL: if (class_range_state == RANGE_STARTED) - parsed_pattern[-1] = CHAR_MINUS; - - /* Disallow implicit union in Perl extended classes. */ - - if (class_op_state == CLASS_OP_OPERAND && - class_mode_state == CLASS_MODE_PERL_EXT) - { - errorcode = ERR113; - goto FAILED; - } - - /* Validate nesting depth */ - if (class_depth_m1 >= ECLASS_NEST_LIMIT - 1) { - errorcode = ERR107; - goto FAILED; /* Classes too deeply nested */ - } - - /* Process the character class start. If the first character is '^', set - the negation flag. If the first few characters (either before or after ^) - are \Q\E or \E or space or tab in extended-more mode, we skip them too. - This makes for compatibility with Perl. */ - - negate_class = FALSE; - for (;;) - { - if (ptr >= ptrend) + if (c == parsed_pattern[-2]) /* Optimize one-char range */ + parsed_pattern--; + else if (parsed_pattern[-2] > c) /* Check range is in order */ { - if (start_c == CHAR_LEFT_PARENTHESIS) - errorcode = ERR14; /* Missing terminating ')' */ - else - errorcode = ERR6; /* Missing terminating ']' */ - goto FAILED; - } - - GETCHARINCTEST(c, ptr); - if (new_class_mode_state == CLASS_MODE_PERL_EXT) break; - else if (c == CHAR_BACKSLASH) - { - if (ptr < ptrend && *ptr == CHAR_E) ptr++; - else if (ptrend - ptr >= 3 && - PRIV(strncmp_c8)(ptr, STR_Q STR_BACKSLASH STR_E, 3) == 0) - ptr += 3; - else - break; - } - else if ((c == CHAR_SPACE || c == CHAR_HT) && /* Note: just these two */ - ((options & PCRE2_EXTENDED_MORE) != 0 || - new_class_mode_state >= CLASS_MODE_PERL_EXT)) - continue; - else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT) - negate_class = TRUE; - else break; - } - - /* Now the real contents of the class; c has the first "real" character. - Empty classes are permitted only if the option is set, and if it's not - a Perl-extended class. */ - - if (c == CHAR_RIGHT_SQUARE_BRACKET && - (cb->external_options & PCRE2_ALLOW_EMPTY_CLASS) != 0 && - new_class_mode_state < CLASS_MODE_PERL_EXT) - { - PCRE2_ASSERT(start_c == CHAR_LEFT_SQUARE_BRACKET); - - if (class_start != NULL) - { - PCRE2_ASSERT(class_depth_m1 >= 0); - /* Represents that the class is an extended class. */ - *class_start |= CLASS_IS_ECLASS; - class_start = NULL; - } - - *parsed_pattern++ = negate_class? META_CLASS_EMPTY_NOT : META_CLASS_EMPTY; - - /* Leave nesting depth unchanged; but check for zero depth to handle the - very first (top-level) class being empty. */ - if (class_depth_m1 < 0) break; - - class_range_state = RANGE_NO; /* for processing the containing class */ - class_op_state = CLASS_OP_OPERAND; - goto CLASS_CONTINUE; - } - - /* Enter a non-empty class. */ - - if (class_start != NULL) - { - PCRE2_ASSERT(class_depth_m1 >= 0); - /* Represents that the class is an extended class. */ - *class_start |= CLASS_IS_ECLASS; - class_start = NULL; - } - - class_start = parsed_pattern; - *parsed_pattern++ = negate_class? META_CLASS_NOT : META_CLASS; - class_range_state = RANGE_NO; - class_op_state = CLASS_OP_EMPTY; - class_mode_state = new_class_mode_state; - ++class_depth_m1; - if (class_maxdepth_m1 < class_depth_m1) - class_maxdepth_m1 = class_depth_m1; - /* Reset; no op seen yet at new depth. */ - cb->class_op_used[class_depth_m1] = 0; - - /* Implement the special start-of-class literal meaning of ']'. */ - if (c == CHAR_RIGHT_SQUARE_BRACKET && - new_class_mode_state != CLASS_MODE_PERL_EXT) - { - class_range_state = RANGE_OK_LITERAL; - class_op_state = CLASS_OP_OPERAND; - PARSED_LITERAL(c, parsed_pattern); - goto CLASS_CONTINUE; - } - - continue; /* We have already loaded c with the next character */ - } - - /* Check for the end of the class. */ - - else if (c == CHAR_RIGHT_SQUARE_BRACKET || - (c == CHAR_RIGHT_PARENTHESIS && class_mode_state == CLASS_MODE_PERL_EXT)) - { - /* In Perl extended mode, the ']' can only be used to match the - opening '[', and ')' must match an opening parenthesis. */ - if (class_mode_state == CLASS_MODE_PERL_EXT) - { - if (c == CHAR_RIGHT_SQUARE_BRACKET && class_depth_m1 != 0) - { - errorcode = ERR14; + errorcode = ERR8; goto FAILED_BACK; } - if (c == CHAR_RIGHT_PARENTHESIS && class_depth_m1 < 1) - { - errorcode = ERR22; - goto FAILED; - } - } - - /* Check no trailing operator. */ - if (class_op_state == CLASS_OP_OPERATOR) - { - errorcode = ERR110; - goto FAILED; - } - - /* Check no empty expression for Perl extended expressions. */ - if (class_mode_state == CLASS_MODE_PERL_EXT && - class_op_state == CLASS_OP_EMPTY) - { - errorcode = ERR114; - goto FAILED; - } - - /* -] at the end of a class is a literal '-' */ - if (class_range_state == RANGE_STARTED) - parsed_pattern[-1] = CHAR_MINUS; - - *parsed_pattern++ = META_CLASS_END; - - if (--class_depth_m1 < 0) - { - /* Check for and consume ')' after '(?[...]'. */ - PCRE2_ASSERT(class_mode_state != CLASS_MODE_PERL_EXT_LEAF); - if (class_mode_state == CLASS_MODE_PERL_EXT) + else { - if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS) - { - errorcode = ERR115; - goto FAILED; - } - - ptr++; + if (!char_is_literal && parsed_pattern[-1] == META_RANGE_LITERAL) + parsed_pattern[-1] = META_RANGE_ESCAPED; + PARSED_LITERAL(c, parsed_pattern); } - - break; - } - - class_range_state = RANGE_NO; /* for processing the containing class */ - class_op_state = CLASS_OP_OPERAND; - if (class_mode_state == CLASS_MODE_PERL_EXT_LEAF) - class_mode_state = CLASS_MODE_PERL_EXT; - /* The extended class flag has already - been set for the parent class. */ - class_start = NULL; - } - - /* Handle a Perl set binary operator */ - - else if (class_mode_state == CLASS_MODE_PERL_EXT && - (c == CHAR_PLUS || c == CHAR_VERTICAL_LINE || c == CHAR_MINUS || - c == CHAR_AMPERSAND || c == CHAR_CIRCUMFLEX_ACCENT)) - { - /* Check that there was a preceding operand. */ - if (class_op_state != CLASS_OP_OPERAND) - { - errorcode = ERR109; - goto FAILED; - } - - if (class_start != NULL) - { - PCRE2_ASSERT(class_depth_m1 >= 0); - /* Represents that the class is an extended class. */ - *class_start |= CLASS_IS_ECLASS; - class_start = NULL; - } - - PCRE2_ASSERT(class_range_state != RANGE_STARTED && - class_range_state != RANGE_FORBID_STARTED); - - *parsed_pattern++ = c == CHAR_PLUS? META_ECLASS_OR : - c == CHAR_VERTICAL_LINE? META_ECLASS_OR : - c == CHAR_MINUS? META_ECLASS_SUB : - c == CHAR_AMPERSAND? META_ECLASS_AND : - META_ECLASS_XOR; - class_range_state = RANGE_NO; - class_op_state = CLASS_OP_OPERATOR; - } - - /* Handle a Perl set unary operator */ - - else if (class_mode_state == CLASS_MODE_PERL_EXT && - c == CHAR_EXCLAMATION_MARK) - { - /* Check that the "!" has not got a preceding operand (i.e. it's the - start of the class, or follows an operator). */ - if (class_op_state == CLASS_OP_OPERAND) - { - errorcode = ERR113; - goto FAILED; - } - - if (class_start != NULL) - { - PCRE2_ASSERT(class_depth_m1 >= 0); - /* Represents that the class is an extended class. */ - *class_start |= CLASS_IS_ECLASS; - class_start = NULL; - } - - PCRE2_ASSERT(class_range_state != RANGE_STARTED && - class_range_state != RANGE_FORBID_STARTED); - - *parsed_pattern++ = META_ECLASS_NOT; - class_range_state = RANGE_NO; - class_op_state = CLASS_OP_OPERATOR; - } - - /* Handle a UTS#18 set operator */ - - else if (class_mode_state == CLASS_MODE_ALT_EXT && - (c == CHAR_VERTICAL_LINE || c == CHAR_MINUS || - c == CHAR_AMPERSAND || c == CHAR_TILDE) && - ptr < ptrend && *ptr == c) - { - ++ptr; - - /* Check there isn't a triple-repetition. */ - if (ptr < ptrend && *ptr == c) - { - while (ptr < ptrend && *ptr == c) ++ptr; /* Improve error offset. */ - errorcode = ERR108; - goto FAILED; - } - - /* Check for a preceding operand. */ - if (class_op_state != CLASS_OP_OPERAND) - { - errorcode = ERR109; - goto FAILED; - } - - /* Check for mixed precedence. Forbid [A--B&&C]. */ - if (cb->class_op_used[class_depth_m1] != 0 && - cb->class_op_used[class_depth_m1] != (uint8_t)c) - { - errorcode = ERR111; - goto FAILED; + class_range_state = RANGE_NO; } - - if (class_start != NULL) + else /* Potential start of range */ { - PCRE2_ASSERT(class_depth_m1 >= 0); - /* Represents that the class is an extended class. */ - *class_start |= CLASS_IS_ECLASS; - class_start = NULL; + class_range_state = char_is_literal? + RANGE_OK_LITERAL : RANGE_OK_ESCAPED; + PARSED_LITERAL(c, parsed_pattern); } - - /* Dangling '-' before an operator is a literal */ - if (class_range_state == RANGE_STARTED) - parsed_pattern[-1] = CHAR_MINUS; - - *parsed_pattern++ = c == CHAR_VERTICAL_LINE? META_ECLASS_OR : - c == CHAR_MINUS? META_ECLASS_SUB : - c == CHAR_AMPERSAND? META_ECLASS_AND : - META_ECLASS_XOR; - class_range_state = RANGE_NO; - class_op_state = CLASS_OP_OPERATOR; - cb->class_op_used[class_depth_m1] = (uint8_t)c; } /* Handle escapes in a class */ - else if (c == CHAR_BACKSLASH) + else { tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - xoptions, cb->bracount, TRUE, cb); + xoptions, TRUE, cb); if (errorcode != 0) { - if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0 || - class_mode_state >= CLASS_MODE_PERL_EXT) + if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -4285,11 +3797,6 @@ while (ptr < ptrend) char_is_literal = FALSE; goto CLASS_LITERAL; - case ESC_k: - c = CHAR_k; /* \k is not special in a class, just like \g */ - char_is_literal = FALSE; - goto CLASS_LITERAL; - case ESC_Q: inescq = TRUE; /* Enter literal mode */ goto CLASS_CONTINUE; @@ -4301,10 +3808,29 @@ while (ptr < ptrend) case ESC_R: case ESC_X: errorcode = ERR7; - ptr--; // TODO https://github.com/PCRE2Project/pcre2/issues/549 + ptr--; goto FAILED; + } - case ESC_N: /* Not permitted by Perl either */ + /* The second part of a range can be a single-character escape + sequence (detected above), but not any of the other escapes. Perl + treats a hyphen as a literal in such circumstances. However, in Perl's + warning mode, a warning is given, so PCRE now faults it, as it is + almost certainly a mistake on the user's part. */ + + if (class_range_state == RANGE_STARTED) + { + errorcode = ERR50; + goto FAILED; /* Not CLASS_ESCAPE_FAILED; always an error */ + } + + /* Of the remaining escapes, only those that define characters are + allowed in a class. None may start a range. */ + + class_range_state = RANGE_NO; + switch(escape) + { + case ESC_N: errorcode = ERR71; goto FAILED; @@ -4338,18 +3864,6 @@ while (ptr < ptrend) uint16_t ptype = 0, pdata = 0; if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb)) goto FAILED; - - /* In caseless matching, particular characteristics Lu, Ll, and Lt - get converted to the general characteristic L&. That is, upper, - lower, and title case letters are all conflated. */ - - if ((options & PCRE2_CASELESS) != 0 && ptype == PT_PC && - (pdata == ucp_Lu || pdata == ucp_Ll || pdata == ucp_Lt)) - { - ptype = PT_LAMP; - pdata = 0; - } - if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P; *parsed_pattern++ = META_ESCAPE + escape; *parsed_pattern++ = (ptype << 16) | pdata; @@ -4360,134 +3874,21 @@ while (ptr < ptrend) #endif break; /* End \P and \p */ - /* All others are not allowed in a class */ - - default: - PCRE2_DEBUG_UNREACHABLE(); - /* Fall through */ - - case ESC_A: - case ESC_Z: - case ESC_z: - case ESC_G: - case ESC_K: - case ESC_C: + default: /* All others are not allowed in a class */ errorcode = ERR7; - ptr--; // TODO https://github.com/PCRE2Project/pcre2/issues/549 - goto FAILED; - } - - /* All the switch-cases above which end in "break" describe a set - of characters. None may start a range. */ - - /* The second part of a range can be a single-character escape - sequence (detected above), but not any of the other escapes. Perl - treats a hyphen as a literal in such circumstances. However, in Perl's - warning mode, a warning is given, so PCRE now faults it, as it is - almost certainly a mistake on the user's part. */ - - if (class_range_state == RANGE_STARTED) - { - errorcode = ERR50; - goto FAILED; - } - - /* Perl gives a warning unless the hyphen following a multi-character - escape is the last character in the class. PCRE throws an error. */ - - if (class_range_state == RANGE_FORBID_STARTED) - { - ptr = class_range_forbid_ptr; - errorcode = ERR50; - goto FAILED; - } - - /* Disallow implicit union in Perl extended classes. */ - - if (class_op_state == CLASS_OP_OPERAND && - class_mode_state == CLASS_MODE_PERL_EXT) - { - errorcode = ERR113; + ptr--; goto FAILED; } - class_range_state = RANGE_FORBID_NO; - class_op_state = CLASS_OP_OPERAND; - } + /* Perl gives a warning unless a following hyphen is the last character + in the class. PCRE throws an error. */ - /* Forbid unescaped literals, and the special meaning of '-', inside a - Perl extended class. */ - - else if (class_mode_state == CLASS_MODE_PERL_EXT) - { - errorcode = ERR116; - goto FAILED; - } - - /* Handle potential start of range */ - - else if (c == CHAR_MINUS && class_range_state >= RANGE_OK_ESCAPED) - { - *parsed_pattern++ = (class_range_state == RANGE_OK_LITERAL)? - META_RANGE_LITERAL : META_RANGE_ESCAPED; - class_range_state = RANGE_STARTED; - } - - /* Handle forbidden start of range */ - - else if (c == CHAR_MINUS && class_range_state == RANGE_FORBID_NO) - { - *parsed_pattern++ = CHAR_MINUS; - class_range_state = RANGE_FORBID_STARTED; - class_range_forbid_ptr = ptr; - } - - /* Handle a literal character */ - - else - { - CLASS_LITERAL: - - /* Disallow implicit union in Perl extended classes. */ - - if (class_op_state == CLASS_OP_OPERAND && - class_mode_state == CLASS_MODE_PERL_EXT) - { - errorcode = ERR113; - goto FAILED; - } - - if (class_range_state == RANGE_STARTED) - { - if (c == parsed_pattern[-2]) /* Optimize one-char range */ - parsed_pattern--; - else if (parsed_pattern[-2] > c) /* Check range is in order */ - { - errorcode = ERR8; - goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549 - } - else - { - if (!char_is_literal && parsed_pattern[-1] == META_RANGE_LITERAL) - parsed_pattern[-1] = META_RANGE_ESCAPED; - PARSED_LITERAL(c, parsed_pattern); - } - class_range_state = RANGE_NO; - class_op_state = CLASS_OP_OPERAND; - } - else if (class_range_state == RANGE_FORBID_STARTED) + if (ptr < ptrend - 1 && *ptr == CHAR_MINUS && + ptr[1] != CHAR_RIGHT_SQUARE_BRACKET) { - ptr = class_range_forbid_ptr; errorcode = ERR50; goto FAILED; } - else /* Potential start of range */ - { - class_range_state = char_is_literal? - RANGE_OK_LITERAL : RANGE_OK_ESCAPED; - class_op_state = CLASS_OP_OPERAND; - PARSED_LITERAL(c, parsed_pattern); - } } /* Proceed to next thing in the class. */ @@ -4495,18 +3896,22 @@ while (ptr < ptrend) CLASS_CONTINUE: if (ptr >= ptrend) { - if (class_mode_state == CLASS_MODE_PERL_EXT && class_depth_m1 > 0) - errorcode = ERR14; /* Missing terminating ')' */ - if (class_mode_state == CLASS_MODE_ALT_EXT && - class_depth_m1 == 0 && class_maxdepth_m1 == 1) - errorcode = ERR112; /* Missing terminating ']', but we saw '[ [ ]...' */ - else - errorcode = ERR6; /* Missing terminating ']' */ + errorcode = ERR6; /* Missing terminating ']' */ goto FAILED; } GETCHARINCTEST(c, ptr); + if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break; } /* End of class-processing loop */ + /* -] at the end of a class is a literal '-' */ + + if (class_range_state == RANGE_STARTED) + { + parsed_pattern[-1] = CHAR_MINUS; + class_range_state = RANGE_NO; + } + + *parsed_pattern++ = META_CLASS_END; break; /* End of character class */ @@ -4589,7 +3994,8 @@ while (ptr < ptrend) if (prev_expect_cond_assert > 0 && (meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT)) { - errorcode = ERR28; /* Atomic assertion expected */ + errorcode = (meta == META_LOOKAHEAD_NA || meta == META_LOOKBEHIND_NA)? + ERR98 : ERR28; /* (Atomic) assertion expected */ goto FAILED; } @@ -4599,7 +4005,6 @@ while (ptr < ptrend) switch(meta) { default: - PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR89; /* Unknown code; should never occur because */ goto FAILED; /* the meta values come from a table above. */ @@ -4615,90 +4020,6 @@ while (ptr < ptrend) case META_LOOKAHEADNOT: goto NEGATIVE_LOOK_AHEAD; - case META_SCS: - if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS; - - if (*ptr != CHAR_LEFT_PARENTHESIS) - { - errorcode = ERR15; - goto FAILED; - } - - ptr++; - *parsed_pattern++ = META_SCS; - /* Temporary variable, zero in the first iteration. */ - offset = 0; - - for (;;) - { - PCRE2_SIZE next_offset = (PCRE2_SIZE)(ptr - cb->start_pattern); - - /* Handle (scan_substring:([+-]number)... */ - if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, - &i, &errorcode)) - { - PCRE2_ASSERT(i >= 0); - if (i <= 0) - { - errorcode = ERR15; - goto FAILED; - } - meta = META_SCS_NUMBER; - namelen = (uint32_t)i; - } - else if (errorcode != 0) goto FAILED; /* Number too big */ - else - { - if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS; - - /* Handle (*scan_substring:('name') or (*scan_substring:() */ - if (*ptr == CHAR_LESS_THAN_SIGN) - terminator = CHAR_GREATER_THAN_SIGN; - else if (*ptr == CHAR_APOSTROPHE) - terminator = CHAR_APOSTROPHE; - else - { - errorcode = ERR15; - goto FAILED; - } - - if (!read_name(&ptr, ptrend, utf, terminator, &next_offset, - &name, &namelen, &errorcode, cb)) goto FAILED; - - meta = META_SCS_NAME; - } - - PCRE2_ASSERT(next_offset > 0); - if (offset == 0 || (next_offset - offset) >= 0x10000) - { - *parsed_pattern++ = META_OFFSET; - PUTOFFSET(next_offset, parsed_pattern); - offset = next_offset; - } - - /* The offset is encoded as a relative offset, because for some - inputs such as ",2" in (*scs:(1,2,3)...), we only have space for - two uint32_t values, and an opcode and absolute offset may require - three uint32_t values. */ - *parsed_pattern++ = meta | (uint32_t)(next_offset - offset); - *parsed_pattern++ = namelen; - offset = next_offset; - - if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS; - - if (*ptr == CHAR_RIGHT_PARENTHESIS) break; - - if (*ptr != CHAR_COMMA) - { - errorcode = ERR24; - goto FAILED; - } - - ptr++; - } - ptr++; - goto POST_ASSERTION; - case META_LOOKBEHIND: case META_LOOKBEHINDNOT: case META_LOOKBEHIND_NA: @@ -4730,12 +4051,6 @@ while (ptr < ptrend) top_nest->flags = NSF_ATOMICSR; top_nest->options = options & PARSE_TRACKED_OPTIONS; top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; - -#ifdef PCRE2_DEBUG - /* We'll write out two META_KETs for a single ")" in the input - pattern, so we reserve space for that in our bounds check. */ - parsed_pattern_extra++; -#endif } break; #else /* SUPPORT_UNICODE */ @@ -4795,11 +4110,6 @@ while (ptr < ptrend) verbstartptr = parsed_pattern; okquantifier = (verbs[i].meta == META_ACCEPT); -#ifdef PCRE2_DEBUG - /* Reserve space in our bounds check for optionally wrapping the (*ACCEPT) - with a non-capturing bracket, if there is a following quantifier. */ - if (okquantifier) parsed_pattern_extra += 2; -#endif /* It appears that Perl allows any characters whatsoever, other than a closing parenthesis, to appear in arguments ("names"), so we no longer @@ -5107,7 +4417,11 @@ while (ptr < ptrend) (IS_DIGIT(*ptr))? -1:(int)(cb->bracount), /* + and - are relative */ MAX_GROUP_NUMBER, ERR61, &i, &errorcode)) goto FAILED; - PCRE2_ASSERT(i >= 0); /* NB (?0) is permitted, represented by i=0 */ + if (i < 0) /* NB (?0) is permitted */ + { + errorcode = ERR15; /* Unknown group */ + goto FAILED_BACK; + } if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS) goto UNCLOSED_PARENTHESIS; @@ -5135,12 +4449,6 @@ while (ptr < ptrend) /* ---- Callout with numerical or string argument ---- */ case CHAR_C: - if ((xoptions & PCRE2_EXTRA_NEVER_CALLOUT) != 0) - { - errorcode = ERR103; - goto FAILED; - } - if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS; /* If the previous item was a condition starting (?(? an assertion, @@ -5228,7 +4536,7 @@ while (ptr < ptrend) parsed_pattern += 3; /* Skip pattern info */ while (ptr < ptrend && IS_DIGIT(*ptr)) { - n = n * 10 + (*ptr++ - CHAR_0); + n = n * 10 + *ptr++ - CHAR_0; if (n > 255) { errorcode = ERR38; @@ -5299,7 +4607,6 @@ while (ptr < ptrend) if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &i, &errorcode)) { - PCRE2_ASSERT(i >= 0); if (i <= 0) { errorcode = ERR15; @@ -5450,7 +4757,7 @@ while (ptr < ptrend) goto POST_ASSERTION; case CHAR_ASTERISK: - POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (*napla: */ + POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (?* */ *parsed_pattern++ = META_LOOKAHEAD_NA; ptr++; goto POST_ASSERTION; @@ -5615,18 +4922,6 @@ while (ptr < ptrend) cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname; cb->names_found++; break; - - - /* ---- Perl extended character class ---- */ - - /* These are of the form '(?[...])'. We handle these via the same parser - that consumes ordinary '[...]' classes, but with a flag set to activate - the extended behaviour. */ - - case CHAR_LEFT_SQUARE_BRACKET: - class_mode_state = CLASS_MODE_PERL_EXT; - c = *ptr++; - goto FROM_PERL_EXTENDED_CLASS; } /* End of (? switch */ break; /* End of ( handling */ @@ -5665,11 +4960,6 @@ while (ptr < ptrend) if ((top_nest->flags & NSF_ATOMICSR) != 0) { *parsed_pattern++ = META_KET; - -#ifdef PCRE2_DEBUG - PCRE2_ASSERT(parsed_pattern_extra > 0); - parsed_pattern_extra--; -#endif } if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL; @@ -5678,7 +4968,7 @@ while (ptr < ptrend) if (nest_depth == 0) /* Unmatched closing parenthesis */ { errorcode = ERR22; - goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549 + goto FAILED_BACK; } nest_depth--; *parsed_pattern++ = META_KET; @@ -5694,15 +4984,9 @@ if (inverbname && ptr >= ptrend) goto FAILED; } - -PARSED_END: - -PCRE2_ASSERT((parsed_pattern - parsed_pattern_check) + - (parsed_pattern_extra - parsed_pattern_extra_check) <= - max_parsed_pattern(ptr_check, ptr, utf, options)); - /* Manage callout for the final item */ +PARSED_END: parsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout, parsed_pattern, cb); @@ -5725,7 +5009,6 @@ Otherwise we have unclosed parentheses. */ if (parsed_pattern >= parsed_pattern_end) { - PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR63; /* Internal error (parsed pattern overflow) */ goto FAILED; } @@ -5831,12 +5114,419 @@ for (;;) code += code[1] + PRIV(OP_lengths)[*code]; break; - default: - return code; + default: + return code; + } + } +/* Control never reaches here */ +} + + + +#ifdef SUPPORT_UNICODE +/************************************************* +* Get othercase range * +*************************************************/ + +/* This function is passed the start and end of a class range in UCP mode. For +single characters the range may be just one character long. The function +searches up the characters, looking for ranges of characters in the "other" +case. Each call returns the next one, updating the start address. A character +with multiple other cases is returned on its own with a special return value. + +Arguments: + cptr points to starting character value; updated + d end value + ocptr where to put start of othercase range + odptr where to put end of othercase range + restricted TRUE if caseless restriction applies + +Yield: -1 when no more + 0 when a range is returned + >0 the CASESET offset for char with multiple other cases; + for this return, *ocptr contains the original +*/ + +static int +get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr, + uint32_t *odptr, BOOL restricted) +{ +uint32_t c, othercase, next; +unsigned int co; + +/* Find the first character that has an other case. If it has multiple other +cases, return its case offset value. When CASELESS_RESTRICT is set, ignore the +multi-case entries that begin with ASCII values. In 32-bit mode, a value +greater than the Unicode maximum ends the range. */ + +for (c = *cptr; c <= d; c++) + { +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) return -1; +#endif + if ((co = UCD_CASESET(c)) != 0 && + (!restricted || PRIV(ucd_caseless_sets)[co] > 127)) + { + *ocptr = c++; /* Character that has the set */ + *cptr = c; /* Rest of input range */ + return (int)co; + } + + /* This is not a valid multiple-case character. Check that the single other + case is different to the original. We don't need to check "restricted" here + because the non-ASCII characters with multiple cases that include an ASCII + character don't have a different "othercase". */ + + if ((othercase = UCD_OTHERCASE(c)) != c) break; + } + +if (c > d) return -1; /* Reached end of range */ + +/* Found a character that has a single other case. Search for the end of the +range, which is either the end of the input range, or a character that has zero +or more than one other cases. */ + +*ocptr = othercase; +next = othercase + 1; + +for (++c; c <= d; c++) + { + if ((co = UCD_CASESET(c)) != 0 || UCD_OTHERCASE(c) != next) break; + next++; + } + +*odptr = next - 1; /* End of othercase range */ +*cptr = c; /* Rest of input range */ +return 0; +} +#endif /* SUPPORT_UNICODE */ + + + +/************************************************* +* Add a character or range to a class (internal) * +*************************************************/ + +/* This function packages up the logic of adding a character or range of +characters to a class. The character values in the arguments will be within the +valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is +called only from within the "add to class" group of functions, some of which +are recursive and mutually recursive. The external entry point is +add_to_class(). + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options bits + xoptions the extra options bits + cb compile data + start start of range character + end end of range character + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static unsigned int +add_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, + uint32_t options, uint32_t xoptions, compile_block *cb, uint32_t start, + uint32_t end) +{ +uint32_t c; +uint32_t classbits_end = (end <= 0xff ? end : 0xff); +unsigned int n8 = 0; + +/* If caseless matching is required, scan the range and process alternate +cases. In Unicode, there are 8-bit characters that have alternate cases that +are greater than 255 and vice-versa (though these may be ignored if caseless +restriction is in force). Sometimes we can just extend the original range. */ + +if ((options & PCRE2_CASELESS) != 0) + { +#ifdef SUPPORT_UNICODE + if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0) + { + int rc; + uint32_t oc, od; + + options &= ~PCRE2_CASELESS; /* Remove for recursive calls */ + c = start; + + while ((rc = get_othercase_range(&c, end, &oc, &od, + (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)) >= 0) + { + /* Handle a single character that has more than one other case. */ + + if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, + options, xoptions, cb, PRIV(ucd_caseless_sets) + rc, oc); + + /* Do nothing if the other case range is within the original range. */ + + else if (oc >= cb->class_range_start && od <= cb->class_range_end) + continue; + + /* Extend the original range if there is overlap, noting that if oc < c, + we can't have od > end because a subrange is always shorter than the + basic range. Otherwise, use a recursive call to add the additional range. + */ + + else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ + else if (od > end && oc <= end + 1) + { + end = od; /* Extend upwards */ + if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff); + } + else n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, + cb, oc, od); + } + } + else +#else + (void)xoptions; /* Avoid compiler warning */ +#endif /* SUPPORT_UNICODE */ + + /* Not UTF mode */ + + for (c = start; c <= classbits_end; c++) + { + SETBIT(classbits, cb->fcc[c]); + n8++; + } + } + +/* Now handle the originally supplied range. Adjust the final value according +to the bit length - this means that the same lists of (e.g.) horizontal spaces +can be used in all cases. */ + +if ((options & PCRE2_UTF) == 0 && end > MAX_NON_UTF_CHAR) + end = MAX_NON_UTF_CHAR; + +if (start > cb->class_range_start && end < cb->class_range_end) return n8; + +/* Use the bitmap for characters < 256. Otherwise use extra data.*/ + +for (c = start; c <= classbits_end; c++) + { + /* Regardless of start, c will always be <= 255. */ + SETBIT(classbits, c); + n8++; + } + +#ifdef SUPPORT_WIDE_CHARS +if (start <= 0xff) start = 0xff + 1; + +if (end >= start) + { + PCRE2_UCHAR *uchardata = *uchardptr; + +#ifdef SUPPORT_UNICODE + if ((options & PCRE2_UTF) != 0) + { + if (start < end) + { + *uchardata++ = XCL_RANGE; + uchardata += PRIV(ord2utf)(start, uchardata); + uchardata += PRIV(ord2utf)(end, uchardata); + } + else if (start == end) + { + *uchardata++ = XCL_SINGLE; + uchardata += PRIV(ord2utf)(start, uchardata); + } + } + else +#endif /* SUPPORT_UNICODE */ + + /* Without UTF support, character values are constrained by the bit length, + and can only be > 256 for 16-bit and 32-bit libraries. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 + {} +#else + if (start < end) + { + *uchardata++ = XCL_RANGE; + *uchardata++ = start; + *uchardata++ = end; + } + else if (start == end) + { + *uchardata++ = XCL_SINGLE; + *uchardata++ = start; + } +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + *uchardptr = uchardata; /* Updata extra data pointer */ + } +#else /* SUPPORT_WIDE_CHARS */ + (void)uchardptr; /* Avoid compiler warning */ +#endif /* SUPPORT_WIDE_CHARS */ + +return n8; /* Number of 8-bit characters */ +} + + + +#ifdef SUPPORT_UNICODE +/************************************************* +* Add a list of characters to a class (internal) * +*************************************************/ + +/* This function is used for adding a list of case-equivalent characters to a +class when in UTF mode. This function is called only from within +add_to_class_internal(), with which it is mutually recursive. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options bits + xoptions the extra options bits + cb contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + except character to omit; this is used when adding lists of + case-equivalent characters to avoid including the one we + already know about + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static unsigned int +add_list_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, + uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p, + unsigned int except) +{ +unsigned int n8 = 0; +while (p[0] < NOTACHAR) + { + unsigned int n = 0; + if (p[0] != except) + { + while(p[n+1] == p[0] + n + 1) n++; + n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + p[0], p[n]); + } + p += n + 1; + } +return n8; +} +#endif + + + +/************************************************* +* External entry point for add range to class * +*************************************************/ + +/* This function sets the overall range so that the internal functions can try +to avoid duplication when handling case-independence. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options bits + xoptions the extra options bits + cb compile data + start start of range character + end end of range character + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static unsigned int +add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, + uint32_t xoptions, compile_block *cb, uint32_t start, uint32_t end) +{ +cb->class_range_start = start; +cb->class_range_end = end; +return add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + start, end); +} + + +/************************************************* +* External entry point for add list to class * +*************************************************/ + +/* This function is used for adding a list of horizontal or vertical whitespace +characters to a class. The list must be in order so that ranges of characters +can be detected and handled appropriately. This function sets the overall range +so that the internal functions can try to avoid duplication when handling +case-independence. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options bits + xoptions the extra options bits + cb contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + except character to omit; this is used when adding lists of + case-equivalent characters to avoid including the one we + already know about + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static unsigned int +add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, + uint32_t xoptions, compile_block *cb, const uint32_t *p, unsigned int except) +{ +unsigned int n8 = 0; +while (p[0] < NOTACHAR) + { + unsigned int n = 0; + if (p[0] != except) + { + while(p[n+1] == p[0] + n + 1) n++; + cb->class_range_start = p[0]; + cb->class_range_end = p[n]; + n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + p[0], p[n]); } + p += n + 1; } +return n8; +} + + -PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ +/************************************************* +* Add characters not in a list to a class * +*************************************************/ + +/* This function is used for adding the complement of a list of horizontal or +vertical whitespace to a class. The list must be in order. + +Arguments: + classbits the bit map for characters < 256 + uchardptr points to the pointer for extra data + options the options bits + xoptions the extra options bits + cb contains pointers to tables etc. + p points to row of 32-bit values, terminated by NOTACHAR + +Returns: the number of < 256 characters added + the pointer to extra data is updated +*/ + +static unsigned int +add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, + uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p) +{ +BOOL utf = (options & PCRE2_UTF) != 0; +unsigned int n8 = 0; +if (p[0] > 0) + n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, 0, p[0] - 1); +while (p[0] < NOTACHAR) + { + while (p[1] == p[0] + 1) p++; + n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, p[0] + 1, + (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); + p++; + } +return n8; } @@ -5882,7 +5572,6 @@ have duplicate names. Give an internal error. */ if (i >= cb->names_found) { - PCRE2_DEBUG_UNREACHABLE(); *errorcodeptr = ERR53; cb->erroroffset = name - cb->start_pattern; return FALSE; @@ -5960,13 +5649,12 @@ uint32_t options = *optionsptr; /* May change dynamically */ uint32_t xoptions = *xoptionsptr; /* May change dynamically */ uint32_t firstcu, reqcu; uint32_t zeroreqcu, zerofirstcu; +uint32_t escape; uint32_t *pptr = *pptrptr; uint32_t meta, meta_arg; uint32_t firstcuflags, reqcuflags; uint32_t zeroreqcuflags, zerofirstcuflags; uint32_t req_caseopt, reqvary, tempreqvary; -/* Some opcodes, such as META_SCS_NUMBER or META_SCS_NAME, -depends on the previous value of offset. */ PCRE2_SIZE offset = 0; PCRE2_SIZE length_prevgroup = 0; PCRE2_UCHAR *code = *codeptr; @@ -5980,6 +5668,8 @@ BOOL had_accept = FALSE; BOOL matched_char = FALSE; BOOL previous_matched_char = FALSE; BOOL reset_caseful = FALSE; +const uint8_t *cbits = cb->cbits; +uint8_t classbits[32]; /* We can fish out the UTF setting once and for all into a BOOL, but we must not do this for other options (e.g. PCRE2_EXTENDED) that may change dynamically @@ -5992,6 +5682,17 @@ BOOL ucp = (options & PCRE2_UCP) != 0; BOOL utf = FALSE; #endif +/* Helper variables for OP_XCLASS opcode (for characters > 255). We define +class_uchardata always so that it can be passed to add_to_class() always, +though it will not be used in non-UTF 8-bit cases. This avoids having to supply +alternative calls for the different cases. */ + +PCRE2_UCHAR *class_uchardata; +#ifdef SUPPORT_WIDE_CHARS +BOOL xclass; +PCRE2_UCHAR *class_uchardata_base; +#endif + /* Set up the default and non-default settings for greediness */ greedy_default = ((options & PCRE2_UNGREEDY) != 0); @@ -6021,8 +5722,15 @@ req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0; for (;; pptr++) { +#ifdef SUPPORT_WIDE_CHARS + BOOL xclass_has_prop; +#endif + BOOL negate_class; + BOOL should_flip_negation; + BOOL match_all_or_no_wide_chars; BOOL possessive_quantifier; BOOL note_group_empty; + int class_has_8bitchar; uint32_t mclength; uint32_t skipunits; uint32_t subreqcu, subfirstcu; @@ -6045,13 +5753,8 @@ for (;; pptr++) if (code > cb->start_workspace + cb->workspace_size - WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ { - if (code >= cb->start_workspace + cb->workspace_size) - { - PCRE2_DEBUG_UNREACHABLE(); - *errorcodeptr = ERR52; /* Over-ran workspace - internal error */ - } - else - *errorcodeptr = ERR86; + *errorcodeptr = (code >= cb->start_workspace + cb->workspace_size)? + ERR52 : ERR86; return 0; } @@ -6157,24 +5860,13 @@ for (;; pptr++) /* ===================================================================*/ /* Empty character classes are allowed if PCRE2_ALLOW_EMPTY_CLASS is set. Otherwise, an initial ']' is taken as a data character. When empty classes - are allowed, [] must generate an empty class - we have no dedicated opcode - to optimise the representation, but it's a rare case (the '(*FAIL)' - construct would be a clearer way for a pattern author to represent a - non-matching branch, but it does have different semantics to '[]' if both - are followed by a quantifier). The empty-negated [^] matches any character, - so is useful: generate OP_ALLANY for this. */ + are allowed, [] must always fail, so generate OP_FAIL, whereas [^] must + match any character, so generate OP_ALLANY. */ case META_CLASS_EMPTY: case META_CLASS_EMPTY_NOT: matched_char = TRUE; - if (meta == META_CLASS_EMPTY_NOT) *code++ = OP_ALLANY; - else - { - *code++ = OP_CLASS; - memset(code, 0, 32); - code += 32 / sizeof(PCRE2_UCHAR); - } - + *code++ = (meta == META_CLASS_EMPTY_NOT)? OP_ALLANY : OP_FAIL; if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; zerofirstcu = firstcu; zerofirstcuflags = firstcuflags; @@ -6197,16 +5889,7 @@ for (;; pptr++) case META_CLASS_NOT: case META_CLASS: matched_char = TRUE; - - /* Check for complex extended classes and handle them separately. */ - - if ((*pptr & CLASS_IS_ECLASS) != 0) - { - if (!PRIV(compile_class_nested)(options, xoptions, &pptr, &code, - errorcodeptr, cb, lengthptr)) - return 0; - goto CLASS_END_PROCESSING; - } + negate_class = meta == META_CLASS_NOT; /* We can optimize the case of a single character in a class by generating OP_CHAR or OP_CHARI if it's positive, or OP_NOT or OP_NOTI if it's @@ -6219,6 +5902,9 @@ for (;; pptr++) if (pptr[1] < META_END && pptr[2] == META_CLASS_END) { +#ifdef SUPPORT_UNICODE + uint32_t d; +#endif uint32_t c = pptr[1]; pptr += 2; /* Move on to class end */ @@ -6228,123 +5914,573 @@ for (;; pptr++) goto NORMAL_CHAR_SET; } - /* Handle a negative one-character class */ + /* Handle a negative one-character class */ + + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + + /* For caseless UTF or UCP mode, check whether this character has more + than one other case. If so, generate a special OP_NOTPROP item instead of + OP_NOTI. When restricted by PCRE2_EXTRA_CASELESS_RESTRICT, ignore any + caseless set that starts with an ASCII character. */ + +#ifdef SUPPORT_UNICODE + if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 && + (d = UCD_CASESET(c)) != 0 && + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || + PRIV(ucd_caseless_sets)[d] > 127)) + { + *code++ = OP_NOTPROP; + *code++ = PT_CLIST; + *code++ = d; + break; /* We are finished with this class */ + } +#endif + /* Char has only one other (usable) case, or UCP not available */ + + *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; + code += PUTCHAR(c, code); + break; /* We are finished with this class */ + } /* End of 1-char optimization */ + + /* Handle character classes that contain more than just one literal + character. If there are exactly two characters in a positive class, see if + they are case partners. This can be optimized to generate a caseless single + character match (which also sets first/required code units if relevant). + When casing restrictions apply, ignore a caseless set if both characters + are ASCII. */ + + if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END && + pptr[3] == META_CLASS_END) + { + uint32_t c = pptr[1]; + +#ifdef SUPPORT_UNICODE + if (UCD_CASESET(c) == 0 || + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && + c < 128 && pptr[2] < 128)) +#endif + { + uint32_t d; + +#ifdef SUPPORT_UNICODE + if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else +#endif + { +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) d = c; else +#endif + d = TABLE_GET(c, cb->fcc, c); + } + + if (c != d && pptr[2] == d) + { + pptr += 3; /* Move on to class end */ + meta = c; + if ((options & PCRE2_CASELESS) == 0) + { + reset_caseful = TRUE; + options |= PCRE2_CASELESS; + req_caseopt = REQ_CASELESS; + } + goto CLASS_CASELESS_CHAR; + } + } + } + + /* If a non-extended class contains a negative special such as \S, we need + to flip the negation flag at the end, so that support for characters > 255 + works correctly (they are all included in the class). An extended class may + need to insert specific matching or non-matching code for wide characters. + */ + + should_flip_negation = match_all_or_no_wide_chars = FALSE; + + /* Extended class (xclass) will be used when characters > 255 + might match. */ + +#ifdef SUPPORT_WIDE_CHARS + xclass = FALSE; + class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ + class_uchardata_base = class_uchardata; /* Save the start */ +#endif + + /* For optimization purposes, we track some properties of the class: + class_has_8bitchar will be non-zero if the class contains at least one + character with a code point less than 256; xclass_has_prop will be TRUE if + Unicode property checks are present in the class. */ + + class_has_8bitchar = 0; +#ifdef SUPPORT_WIDE_CHARS + xclass_has_prop = FALSE; +#endif + + /* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map + in a temporary bit of memory, in case the class contains fewer than two + 8-bit characters because in that case the compiled code doesn't use the bit + map. */ + + memset(classbits, 0, 32 * sizeof(uint8_t)); + + /* Process items until META_CLASS_END is reached. */ + + while ((meta = *(++pptr)) != META_CLASS_END) + { + /* Handle POSIX classes such as [:alpha:] etc. */ + + if (meta == META_POSIX || meta == META_POSIX_NEG) + { + BOOL local_negate = (meta == META_POSIX_NEG); + int posix_class = *(++pptr); + int taboffset, tabopt; + uint8_t pbits[32]; + + should_flip_negation = local_negate; /* Note negative special */ + + /* If matching is caseless, upper and lower are converted to alpha. + This relies on the fact that the class table starts with alpha, + lower, upper as the first 3 entries. */ + + if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2) + posix_class = 0; + + /* When PCRE2_UCP is set, some of the POSIX classes are converted to + different escape sequences that use Unicode properties \p or \P. + Others that are not available via \p or \P have to generate + XCL_PROP/XCL_NOTPROP directly, which is done here. */ + +#ifdef SUPPORT_UNICODE + if ((options & PCRE2_UCP) != 0 && + (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0) + { + switch(posix_class) + { + case PC_GRAPH: + case PC_PRINT: + case PC_PUNCT: + *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; + *class_uchardata++ = (PCRE2_UCHAR) + ((posix_class == PC_GRAPH)? PT_PXGRAPH : + (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT); + *class_uchardata++ = 0; + xclass_has_prop = TRUE; + goto CONTINUE_CLASS; + + /* For the other POSIX classes (ex: ascii) we are going to + fall through to the non-UCP case and build a bit map for + characters with code points less than 256. However, if we are in + a negated POSIX class, characters with code points greater than + 255 must either all match or all not match, depending on whether + the whole class is not or is negated. For example, for + [[:^ascii:]... they must all match, whereas for [^[:^ascii:]... + they must not. + + In the special case where there are no xclass items, this is + automatically handled by the use of OP_CLASS or OP_NCLASS, but an + explicit range is needed for OP_XCLASS. Setting a flag here + causes the range to be generated later when it is known that + OP_XCLASS is required. In the 8-bit library this is relevant only in + utf mode, since no wide characters can exist otherwise. */ + + default: +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (utf) +#endif + match_all_or_no_wide_chars |= local_negate; + break; + } + } +#endif /* SUPPORT_UNICODE */ + + /* In the non-UCP case, or when UCP makes no difference, we build the + bit map for the POSIX class in a chunk of local store because we may + be adding and subtracting from it, and we don't want to subtract bits + that may be in the main map already. At the end we or the result into + the bit map that is being built. */ + + posix_class *= 3; + + /* Copy in the first table (always present) */ + + memcpy(pbits, cbits + posix_class_maps[posix_class], + 32 * sizeof(uint8_t)); + + /* If there is a second table, add or remove it as required. */ + + taboffset = posix_class_maps[posix_class + 1]; + tabopt = posix_class_maps[posix_class + 2]; + + if (taboffset >= 0) + { + if (tabopt >= 0) + for (int i = 0; i < 32; i++) pbits[i] |= cbits[(int)i + taboffset]; + else + for (int i = 0; i < 32; i++) pbits[i] &= ~cbits[(int)i + taboffset]; + } + + /* Now see if we need to remove any special characters. An option + value of 1 removes vertical space and 2 removes underscore. */ + + if (tabopt < 0) tabopt = -tabopt; + if (tabopt == 1) pbits[1] &= ~0x3c; + else if (tabopt == 2) pbits[11] &= 0x7f; + + /* Add the POSIX table or its complement into the main table that is + being built and we are done. */ + + if (local_negate) + for (int i = 0; i < 32; i++) classbits[i] |= (uint8_t)(~pbits[i]); + else + for (int i = 0; i < 32; i++) classbits[i] |= pbits[i]; + + /* Every class contains at least one < 256 character. */ + + class_has_8bitchar = 1; + goto CONTINUE_CLASS; /* End of POSIX handling */ + } + + /* Other than POSIX classes, the only items we should encounter are + \d-type escapes and literal characters (possibly as ranges). */ + + if (meta == META_BIGVALUE) + { + meta = *(++pptr); + goto CLASS_LITERAL; + } + + /* Any other non-literal must be an escape */ + + if (meta >= META_END) + { + if (META_CODE(meta) != META_ESCAPE) + { +#ifdef DEBUG_SHOW_PARSED + fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x " + "in character class\n", meta); +#endif + *errorcodeptr = ERR89; /* Internal error - unrecognized. */ + return 0; + } + escape = META_DATA(meta); + + /* Every class contains at least one < 256 character. */ + + class_has_8bitchar++; + + switch(escape) + { + case ESC_d: + for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit]; + break; + + case ESC_D: + should_flip_negation = TRUE; + for (int i = 0; i < 32; i++) + classbits[i] |= (uint8_t)(~cbits[i+cbit_digit]); + break; + + case ESC_w: + for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word]; + break; + + case ESC_W: + should_flip_negation = TRUE; + for (int i = 0; i < 32; i++) + classbits[i] |= (uint8_t)(~cbits[i+cbit_word]); + break; + + /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl + 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was + previously set by something earlier in the character class. + Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so + we could just adjust the appropriate bit. From PCRE 8.34 we no + longer treat \s and \S specially. */ + + case ESC_s: + for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space]; + break; + + case ESC_S: + should_flip_negation = TRUE; + for (int i = 0; i < 32; i++) + classbits[i] |= (uint8_t)(~cbits[i+cbit_space]); + break; + + /* When adding the horizontal or vertical space lists to a class, or + their complements, disable PCRE2_CASELESS, because it justs wastes + time, and in the "not-x" UTF cases can create unwanted duplicates in + the XCLASS list (provoked by characters that have more than one other + case and by both cases being in the same "not-x" sublist). */ + + case ESC_h: + (void)add_list_to_class(classbits, &class_uchardata, + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list), + NOTACHAR); + break; + + case ESC_H: + (void)add_not_list_to_class(classbits, &class_uchardata, + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list)); + break; + + case ESC_v: + (void)add_list_to_class(classbits, &class_uchardata, + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list), + NOTACHAR); + break; + + case ESC_V: + (void)add_not_list_to_class(classbits, &class_uchardata, + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list)); + break; + + /* If Unicode is not supported, \P and \p are not allowed and are + faulted at parse time, so will never appear here. */ + +#ifdef SUPPORT_UNICODE + case ESC_p: + case ESC_P: + { + uint32_t ptype = *(++pptr) >> 16; + uint32_t pdata = *pptr & 0xffff; + *class_uchardata++ = (escape == ESC_p)? XCL_PROP : XCL_NOTPROP; + *class_uchardata++ = ptype; + *class_uchardata++ = pdata; + xclass_has_prop = TRUE; + class_has_8bitchar--; /* Undo! */ + } + break; +#endif + } + + goto CONTINUE_CLASS; + } /* End handling \d-type escapes */ + + /* A literal character may be followed by a range meta. At parse time + there are checks for out-of-order characters, for ranges where the two + characters are equal, and for hyphens that cannot indicate a range. At + this point, therefore, no checking is needed. */ + + else + { + uint32_t c, d; + + CLASS_LITERAL: + c = d = meta; + + /* Remember if \r or \n were explicitly used */ + + if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; + + /* Process a character range */ + + if (pptr[1] == META_RANGE_LITERAL || pptr[1] == META_RANGE_ESCAPED) + { +#ifdef EBCDIC + BOOL range_is_literal = (pptr[1] == META_RANGE_LITERAL); +#endif + pptr += 2; + d = *pptr; + if (d == META_BIGVALUE) d = *(++pptr); + + /* Remember an explicit \r or \n, and add the range to the class. */ + + if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; + + /* In an EBCDIC environment, Perl treats alphabetic ranges specially + because there are holes in the encoding, and simply using the range + A-Z (for example) would include the characters in the holes. This + applies only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */ + +#ifdef EBCDIC + if (range_is_literal && + (cb->ctypes[c] & ctype_letter) != 0 && + (cb->ctypes[d] & ctype_letter) != 0 && + (c <= CHAR_z) == (d <= CHAR_z)) + { + uint32_t uc = (d <= CHAR_z)? 0 : 64; + uint32_t C = c - uc; + uint32_t D = d - uc; + + if (C <= CHAR_i) + { + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, ((D < CHAR_i)? D : CHAR_i) + uc); + C = CHAR_j; + } + + if (C <= D && C <= CHAR_r) + { + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, ((D < CHAR_r)? D : CHAR_r) + uc); + C = CHAR_s; + } + + if (C <= D) + { + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, D + uc); + } + } + else +#endif + /* Not an EBCDIC special range */ + + class_has_8bitchar += add_to_class(classbits, &class_uchardata, + options, xoptions, cb, c, d); + goto CONTINUE_CLASS; /* Go get the next char in the class */ + } /* End of range handling */ - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - /* For caseless UTF or UCP mode, check whether this character has more - than one other case. If so, generate a special OP_NOTPROP item instead of - OP_NOTI. When restricted by PCRE2_EXTRA_CASELESS_RESTRICT, ignore any - caseless set that starts with an ASCII character. If the character is - affected by the special Turkish rules, hardcode the not-matching - characters using a caseset. */ + /* Handle a single character. */ -#ifdef SUPPORT_UNICODE - if ((utf||ucp) && (options & PCRE2_CASELESS) != 0) - { - uint32_t caseset; + class_has_8bitchar += + add_to_class(classbits, &class_uchardata, options, xoptions, cb, + meta, meta); + } - if ((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == - PCRE2_EXTRA_TURKISH_CASING && - UCD_ANY_I(c)) - { - caseset = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(c)? 0 : 3); - } - else if ((caseset = UCD_CASESET(c)) != 0 && - (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && - PRIV(ucd_caseless_sets)[caseset] < 128) - { - caseset = 0; /* Ignore the caseless set if it's restricted. */ - } + /* Continue to the next item in the class. */ - if (caseset != 0) + CONTINUE_CLASS: + +#ifdef SUPPORT_WIDE_CHARS + /* If any wide characters or Unicode properties have been encountered, + set xclass = TRUE. Then, in the pre-compile phase, accumulate the length + of the extra data and reset the pointer. This is so that very large + classes that contain a zillion wide characters or Unicode property tests + do not overwrite the workspace (which is on the stack). */ + + if (class_uchardata > class_uchardata_base) + { + xclass = TRUE; + if (lengthptr != NULL) { - *code++ = OP_NOTPROP; - *code++ = PT_CLIST; - *code++ = caseset; - break; /* We are finished with this class */ + *lengthptr += class_uchardata - class_uchardata_base; + class_uchardata = class_uchardata_base; } } #endif - /* Char has only one other (usable) case, or UCP not available */ - *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; - code += PUTCHAR(c, code); - break; /* We are finished with this class */ - } /* End of 1-char optimization */ + continue; /* Needed to avoid error when not supporting wide chars */ + } /* End of main class-processing loop */ - /* Handle character classes that contain more than just one literal - character. If there are exactly two characters in a positive class, see if - they are case partners. This can be optimized to generate a caseless single - character match (which also sets first/required code units if relevant). - When casing restrictions apply, ignore a caseless set if both characters - are ASCII. When Turkish casing applies, an 'i' does not match its normal - Unicode "othercase". */ + /* If this class is the first thing in the branch, there can be no first + char setting, whatever the repeat count. Any reqcu setting must remain + unchanged after any kind of repeat. */ - if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END && - pptr[3] == META_CLASS_END) - { - uint32_t c = pptr[1]; + if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; + zeroreqcu = reqcu; + zeroreqcuflags = reqcuflags; + /* If there are characters with values > 255, or Unicode property settings + (\p or \P), we have to compile an extended class, with its own opcode, + unless there were no property settings and there was a negated special such + as \S in the class, and PCRE2_UCP is not set, because in that case all + characters > 255 are in or not in the class, so any that were explicitly + given as well can be ignored. + + In the UCP case, if certain negated POSIX classes (ex: [:^ascii:]) were + were present in a class, we either have to match or not match all wide + characters (depending on whether the whole class is or is not negated). + This requirement is indicated by match_all_or_no_wide_chars being true. + We do this by including an explicit range, which works in both cases. + This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there + cannot be any wide characters in 8-bit non-UTF mode. + + When there *are* properties in a positive UTF-8 or any 16-bit or 32_bit + class where \S etc is present without PCRE2_UCP, causing an extended class + to be compiled, we make sure that all characters > 255 are included by + forcing match_all_or_no_wide_chars to be true. + + If, when generating an xclass, there are no characters < 256, we can omit + the bitmap in the actual compiled code. */ + +#ifdef SUPPORT_WIDE_CHARS /* Defined for 16/32 bits, or 8-bit with Unicode */ + if (xclass && ( #ifdef SUPPORT_UNICODE - if ((UCD_CASESET(c) == 0 || - ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && - c < 128 && pptr[2] < 128)) && - !((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == - PCRE2_EXTRA_TURKISH_CASING && - UCD_ANY_I(c))) + (options & PCRE2_UCP) != 0 || #endif - { - uint32_t d; - -#ifdef SUPPORT_UNICODE - if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else + xclass_has_prop || !should_flip_negation)) + { + if (match_all_or_no_wide_chars || ( +#if PCRE2_CODE_UNIT_WIDTH == 8 + utf && #endif + should_flip_negation && !negate_class && (options & PCRE2_UCP) == 0)) + { + *class_uchardata++ = XCL_RANGE; + if (utf) /* Will always be utf in the 8-bit library */ { -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (c > 255) d = c; else + class_uchardata += PRIV(ord2utf)(0x100, class_uchardata); + class_uchardata += PRIV(ord2utf)(MAX_UTF_CODE_POINT, class_uchardata); + } + else /* Can only happen for the 16-bit & 32-bit libraries */ + { +#if PCRE2_CODE_UNIT_WIDTH == 16 + *class_uchardata++ = 0x100; + *class_uchardata++ = 0xffffu; +#elif PCRE2_CODE_UNIT_WIDTH == 32 + *class_uchardata++ = 0x100; + *class_uchardata++ = 0xffffffffu; #endif - d = TABLE_GET(c, cb->fcc, c); } + } + *class_uchardata++ = XCL_END; /* Marks the end of extra data */ + *code++ = OP_XCLASS; + code += LINK_SIZE; + *code = negate_class? XCL_NOT:0; + if (xclass_has_prop) *code |= XCL_HASPROP; - if (c != d && pptr[2] == d) + /* If the map is required, move up the extra data to make room for it; + otherwise just move the code pointer to the end of the extra data. */ + + if (class_has_8bitchar > 0) + { + *code++ |= XCL_MAP; + (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, + CU2BYTES(class_uchardata - code)); + if (negate_class && !xclass_has_prop) { - pptr += 3; /* Move on to class end */ - meta = c; - if ((options & PCRE2_CASELESS) == 0) - { - reset_caseful = TRUE; - options |= PCRE2_CASELESS; - req_caseopt = REQ_CASELESS; - } - goto CLASS_CASELESS_CHAR; + /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ + for (int i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i]; } + memcpy(code, classbits, 32); + code = class_uchardata + (32 / sizeof(PCRE2_UCHAR)); } - } + else code = class_uchardata; - /* Now emit the OP_CLASS/OP_NCLASS/OP_XCLASS/OP_ALLANY opcode. */ + /* Now fill in the complete length of the item */ - pptr = PRIV(compile_class_not_nested)(options, xoptions, pptr + 1, - &code, meta == META_CLASS_NOT, NULL, - errorcodeptr, cb, lengthptr); - if (pptr == NULL) return 0; - PCRE2_ASSERT(*pptr == META_CLASS_END); - - CLASS_END_PROCESSING: + PUT(previous, 1, (int)(code - previous)); + break; /* End of class handling */ + } +#endif /* SUPPORT_WIDE_CHARS */ - /* If this class is the first thing in the branch, there can be no first - char setting, whatever the repeat count. Any reqcu setting must remain - unchanged after any kind of repeat. */ + /* If there are no characters > 255, or they are all to be included or + excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the + whole class was negated and whether there were negative specials such as \S + (non-UCP) in the class. Then copy the 32-byte map into the code vector, + negating it if necessary. */ - if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; - zerofirstcu = firstcu; - zerofirstcuflags = firstcuflags; - zeroreqcu = reqcu; - zeroreqcuflags = reqcuflags; + *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; + if (lengthptr == NULL) /* Save time in the pre-compile phase */ + { + if (negate_class) + { + /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ + for (int i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i]; + } + memcpy(code, classbits, 32); + } + code += 32 / sizeof(PCRE2_UCHAR); break; /* End of class processing */ @@ -6450,15 +6586,6 @@ for (;; pptr++) req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0; break; - case META_OFFSET: - GETPLUSOFFSET(offset, pptr); - break; - - case META_SCS: - bravalue = OP_ASSERT_SCS; - cb->assert_depth += 1; - goto GROUP_PROCESS; - /* ===================================================================*/ /* Handle conditional subpatterns. The case of (?(Rdigits) is ambiguous @@ -6470,7 +6597,6 @@ for (;; pptr++) case META_COND_RNUMBER: /* (?(Rdigits) */ case META_COND_NAME: /* (?(name) or (?'name') or ?() */ case META_COND_RNAME: /* (?(R&name) - test for recursion */ - case META_SCS_NAME: /* Name of scan substring */ bravalue = OP_COND; { int count, index; @@ -6479,10 +6605,7 @@ for (;; pptr++) named_group *ng = cb->named_groups; uint32_t length = *(++pptr); - if (meta == META_SCS_NAME) - offset += meta_arg; - else - GETPLUSOFFSET(offset, pptr); + GETPLUSOFFSET(offset, pptr); name = cb->start_pattern + offset; /* In the first pass, the names generated in the pre-pass are available, @@ -6492,21 +6615,34 @@ for (;; pptr++) numerical group. */ for (i = 0; i < cb->names_found; i++, ng++) + { if (length == ng->length && - PRIV(strncmp)(name, ng->name, length) == 0) break; + PRIV(strncmp)(name, ng->name, length) == 0) + { + if (!ng->isdup) + { + code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF; + PUT2(code, 2+LINK_SIZE, ng->number); + if (ng->number > cb->top_backref) cb->top_backref = ng->number; + skipunits = 1+IMM2_SIZE; + goto GROUP_PROCESS_NOTE_EMPTY; + } + break; /* Found a duplicated name */ + } + } + + /* If the name was not found we have a bad reference, unless we are + dealing with R, which is treated as a recursion test by number. + */ if (i >= cb->names_found) { - /* If the name was not found we have a bad reference, unless we are - dealing with R, which is treated as a recursion test by - number. */ - groupnumber = 0; if (meta == META_COND_RNUMBER) { for (i = 1; i < length; i++) { - groupnumber = groupnumber * 10 + (name[i] - CHAR_0); + groupnumber = groupnumber * 10 + name[i] - CHAR_0; if (groupnumber > MAX_GROUP_NUMBER) { *errorcodeptr = ERR61; @@ -6533,26 +6669,11 @@ for (;; pptr++) skipunits = 1+IMM2_SIZE; goto GROUP_PROCESS_NOTE_EMPTY; } - else if (!ng->isdup) - { - /* Otherwise found a duplicated name */ - if (ng->number > cb->top_backref) cb->top_backref = ng->number; - if (meta == META_SCS_NAME) - { - code[0] = OP_CREF; - PUT2(code, 1, ng->number); - code += 1+IMM2_SIZE; - break; - } + /* A duplicated name was found. Note that if an R name is found + (META_COND_RNUMBER), it is a reference test, not a recursion test. */ - code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF; - PUT2(code, 2+LINK_SIZE, ng->number); - skipunits = 1+IMM2_SIZE; - if (meta != META_SCS_NAME) goto GROUP_PROCESS_NOTE_EMPTY; - cb->assert_depth += 1; - goto GROUP_PROCESS; - } + code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF; /* We have a duplicated name. In the compile pass we have to search the main table in order to get the index and count values. */ @@ -6562,27 +6683,14 @@ for (;; pptr++) if (lengthptr == NULL && !find_dupname_details(name, length, &index, &count, errorcodeptr, cb)) return 0; - if (meta == META_SCS_NAME) - { - code[0] = OP_DNCREF; - PUT2(code, 1, index); - PUT2(code, 1+IMM2_SIZE, count); - code += 1+2*IMM2_SIZE; - break; - } - - /* A duplicated name was found. Note that if an R name is found - (META_COND_RNUMBER), it is a reference test, not a recursion test. */ - - code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_DNRREF : OP_DNCREF; + /* Add one to the opcode to change CREF/RREF into DNCREF/DNRREF and + insert appropriate data values. */ - /* Insert appropriate data values. */ + code[1+LINK_SIZE]++; skipunits = 1+2*IMM2_SIZE; PUT2(code, 2+LINK_SIZE, index); PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count); } - - PCRE2_ASSERT(meta != META_SCS_NAME); goto GROUP_PROCESS_NOTE_EMPTY; /* The DEFINE condition is always false. Its internal groups may never @@ -6599,13 +6707,8 @@ for (;; pptr++) /* Conditional test of a group's being set. */ case META_COND_NUMBER: - case META_SCS_NUMBER: bravalue = OP_COND; - if (meta == META_SCS_NUMBER) - offset += meta_arg; - else - GETPLUSOFFSET(offset, pptr); - + GETPLUSOFFSET(offset, pptr); groupnumber = *(++pptr); if (groupnumber > cb->bracount) { @@ -6614,17 +6717,7 @@ for (;; pptr++) return 0; } if (groupnumber > cb->top_backref) cb->top_backref = groupnumber; - - if (meta == META_SCS_NUMBER) - { - code[0] = OP_CREF; - PUT2(code, 1, groupnumber); - code += 1+IMM2_SIZE; - break; - } - - /* Point at initial ( for too many branches error */ - offset -= 2; + offset -= 2; /* Point at initial ( for too many branches error */ code[1+LINK_SIZE] = OP_CREF; skipunits = 1+IMM2_SIZE; PUT2(code, 2+LINK_SIZE, groupnumber); @@ -6762,7 +6855,7 @@ for (;; pptr++) /* If we've just compiled an assertion, pop the assert depth. */ - if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERT_SCS) + if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NA) cb->assert_depth -= 1; /* At the end of compiling, code is still pointing to the start of the @@ -7001,11 +7094,6 @@ for (;; pptr++) *code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF; PUT2INC(code, 0, index); PUT2INC(code, 0, count); - if ((options & PCRE2_CASELESS) != 0) - *code++ = (((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)? - REFI_FLAG_CASELESS_RESTRICT : 0) | - (((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0)? - REFI_FLAG_TURKISH_CASING : 0); } break; @@ -7125,6 +7213,7 @@ for (;; pptr++) single-char opcodes. */ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; + op_type = 0; /* Adjust first and required code units for a zero repeat. */ @@ -7165,7 +7254,6 @@ for (;; pptr++) /* Save start of previous item, in case we have to move it up in order to insert something before it, and remember what it was. */ - PCRE2_ASSERT(previous != NULL); tempcode = previous; op_previous = *previous; @@ -7225,7 +7313,6 @@ for (;; pptr++) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - case OP_ECLASS: #endif case OP_CLASS: case OP_NCLASS: @@ -7256,6 +7343,14 @@ for (;; pptr++) } break; + /* If previous is OP_FAIL, it was generated by an empty class [] + (PCRE2_ALLOW_EMPTY_CLASS is set). The other ways in which OP_FAIL can be + generated, that is by (*FAIL) or (?!), disallow a quantifier at parse + time. We can just ignore this repeat. */ + + case OP_FAIL: + goto END_REPEAT; + /* Prior to 10.30, repeated recursions were wrapped in OP_ONCE brackets because pcre2_match() could not handle backtracking into recursively called groups. Now that this backtracking is available, we no longer need @@ -7339,7 +7434,6 @@ for (;; pptr++) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -7664,10 +7758,9 @@ for (;; pptr++) here because it just makes it horribly messy. */ default: - if (op_previous >= OP_EODN || op_previous <= OP_WORD_BOUNDARY) + if (op_previous >= OP_EODN) /* Not a character type - internal error */ { - PCRE2_DEBUG_UNREACHABLE(); - *errorcodeptr = ERR10; /* Not a character type - internal error */ + *errorcodeptr = ERR10; return 0; } else @@ -7687,8 +7780,7 @@ for (;; pptr++) } else { - /* Come here from just above with a character in mcbuffer/mclength. - You must also set op_type before the jump. */ + /* Come here from just above with a character in mcbuffer/mclength. */ OUTPUT_SINGLE_REPEAT: prop_type = prop_value = -1; } @@ -7871,7 +7963,6 @@ for (;; pptr++) #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - case OP_ECLASS: tempcode += GET(tempcode, 1); break; #endif @@ -7956,11 +8047,6 @@ for (;; pptr++) if (firstcuflags == REQ_UNSET) zerofirstcuflags = firstcuflags = REQ_NONE; *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF; PUT2INC(code, 0, meta_arg); - if ((options & PCRE2_CASELESS) != 0) - *code++ = (((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)? - REFI_FLAG_CASELESS_RESTRICT : 0) | - (((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0)? - REFI_FLAG_TURKISH_CASING : 0); /* Update the map of back references, and keep the highest one. We could do this in parse_regex() for numerical back references, but not @@ -8053,30 +8139,12 @@ for (;; pptr++) uint32_t ptype = *(++pptr) >> 16; uint32_t pdata = *pptr & 0xffff; - /* In caseless matching, particular characteristics Lu, Ll, and Lt get - converted to the general characteristic L&. That is, upper, lower, and - title case letters are all conflated. */ - - if ((options & PCRE2_CASELESS) != 0 && ptype == PT_PC && - (pdata == ucp_Lu || pdata == ucp_Ll || pdata == ucp_Lt)) - { - ptype = PT_LAMP; - pdata = 0; - } - - /* The special case of \p{Any} is compiled to OP_ALLANY and \P{Any} - is compiled to [] so as to benefit from the auto-anchoring code. */ + /* The special case of \p{Any} is compiled to OP_ALLANY so as to benefit + from the auto-anchoring code. */ - if (ptype == PT_ANY) + if (meta_arg == ESC_p && ptype == PT_ANY) { - if (meta_arg == ESC_P) - { - *code++ = OP_CLASS; - memset(code, 0, 32); - code += 32 / sizeof(PCRE2_UCHAR); - } - else - *code++ = OP_ALLANY; + *code++ = OP_ALLANY; } else { @@ -8145,7 +8213,9 @@ for (;; pptr++) default: if (meta >= META_END) { - PCRE2_DEBUG_UNREACHABLE(); +#ifdef DEBUG_SHOW_PARSED + fprintf(stderr, "** Unrecognized parsed pattern item 0x%.8x\n", *pptr); +#endif *errorcodeptr = ERR89; /* Internal error - unrecognized. */ return 0; } @@ -8161,28 +8231,15 @@ for (;; pptr++) /* For caseless UTF or UCP mode, check whether this character has more than one other case. If so, generate a special OP_PROP item instead of OP_CHARI. When casing restrictions apply, ignore caseless sets that start with an - ASCII character. If the character is affected by the special Turkish rules, - hardcode the matching characters using a caseset. */ + ASCII character. */ #ifdef SUPPORT_UNICODE if ((utf||ucp) && (options & PCRE2_CASELESS) != 0) { - uint32_t caseset; - - if ((xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == - PCRE2_EXTRA_TURKISH_CASING && - UCD_ANY_I(meta)) - { - caseset = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(meta)? 0 : 3); - } - else if ((caseset = UCD_CASESET(meta)) != 0 && - (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && - PRIV(ucd_caseless_sets)[caseset] < 128) - { - caseset = 0; /* Ignore the caseless set if it's restricted. */ - } - - if (caseset != 0) + uint32_t caseset = UCD_CASESET(meta); + if (caseset != 0 && + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || + PRIV(ucd_caseless_sets)[caseset] > 127)) { *code++ = OP_PROP; *code++ = PT_CLIST; @@ -8280,8 +8337,7 @@ for (;; pptr++) } /* End of big switch */ } /* End of big loop */ -PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ -return 0; /* Avoid compiler warnings */ +/* Control never reaches here. */ } @@ -8337,6 +8393,8 @@ uint32_t firstcu, reqcu; uint32_t lookbehindlength; uint32_t lookbehindminlength; uint32_t firstcuflags, reqcuflags; +uint32_t branchfirstcu, branchreqcu; +uint32_t branchfirstcuflags, branchreqcuflags; PCRE2_SIZE length; branch_chain bc; @@ -8405,11 +8463,9 @@ code += 1 + LINK_SIZE + skipunits; for (;;) { int branch_return; - uint32_t branchfirstcu = 0, branchreqcu = 0; - uint32_t branchfirstcuflags = REQ_UNSET, branchreqcuflags = REQ_UNSET; /* Insert OP_REVERSE or OP_VREVERSE if this is a lookbehind assertion. There - is only a single minimum length for the whole assertion. When the minimum + is only a single mimimum length for the whole assertion. When the mimimum length is LOOKBEHIND_MAX it means that all branches are of fixed length, though not necessarily the same length. In this case, the original OP_REVERSE can be used. It can also be used if a branch in a variable length lookbehind @@ -8521,10 +8577,10 @@ for (;;) { if (lengthptr == NULL) { - uint32_t branch_length = (uint32_t)(code - last_branch); + PCRE2_SIZE branch_length = code - last_branch; do { - uint32_t prev_length = GET(last_branch, 1); + PCRE2_SIZE prev_length = GET(last_branch, 1); PUT(last_branch, 1, branch_length); branch_length = prev_length; last_branch -= branch_length; @@ -8535,7 +8591,7 @@ for (;;) /* Fill in the ket */ *code = OP_KET; - PUT(code, 1, (uint32_t)(code - start_bracket)); + PUT(code, 1, (int)(code - start_bracket)); code += 1 + LINK_SIZE; /* Set values to pass back */ @@ -8586,9 +8642,7 @@ for (;;) lookbehindlength = META_DATA(*pptr); pptr++; } - -PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ -return 0; /* Avoid compiler warnings */ +/* Control never reaches here */ } @@ -8631,14 +8685,13 @@ this prevents the number of characters it matches from being adjusted. cb points to the compile data block atomcount atomic group level inassert TRUE if in an assertion - dotstar_anchor TRUE if automatic anchoring optimization is enabled Returns: TRUE or FALSE */ static BOOL is_anchored(PCRE2_SPTR code, uint32_t bracket_map, compile_block *cb, - int atomcount, BOOL inassert, BOOL dotstar_anchor) + int atomcount, BOOL inassert) { do { PCRE2_SPTR scode = first_significant_code( @@ -8650,7 +8703,7 @@ do { if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_anchored(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor)) + if (!is_anchored(scode, bracket_map, cb, atomcount, inassert)) return FALSE; } @@ -8661,14 +8714,14 @@ do { { int n = GET2(scode, 1+LINK_SIZE); uint32_t new_map = bracket_map | ((n < 32)? (1u << n) : 1); - if (!is_anchored(scode, new_map, cb, atomcount, inassert, dotstar_anchor)) return FALSE; + if (!is_anchored(scode, new_map, cb, atomcount, inassert)) return FALSE; } /* Positive forward assertion */ else if (op == OP_ASSERT || op == OP_ASSERT_NA) { - if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor)) return FALSE; + if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; } /* Condition. If there is no second branch, it can't be anchored. */ @@ -8676,7 +8729,7 @@ do { else if (op == OP_COND || op == OP_SCOND) { if (scode[GET(scode,1)] != OP_ALT) return FALSE; - if (!is_anchored(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor)) + if (!is_anchored(scode, bracket_map, cb, atomcount, inassert)) return FALSE; } @@ -8684,7 +8737,7 @@ do { else if (op == OP_ONCE) { - if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert, dotstar_anchor)) + if (!is_anchored(scode, bracket_map, cb, atomcount + 1, inassert)) return FALSE; } @@ -8699,7 +8752,8 @@ do { op == OP_TYPEPOSSTAR)) { if (scode[1] != OP_ALLANY || (bracket_map & cb->backref_map) != 0 || - atomcount > 0 || cb->had_pruneorskip || inassert || !dotstar_anchor) + atomcount > 0 || cb->had_pruneorskip || inassert || + (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) return FALSE; } @@ -8736,14 +8790,13 @@ or *SKIP does not count, because once again the assumption no longer holds. cb points to the compile data atomcount atomic group level inassert TRUE if in an assertion - dotstar_anchor TRUE if automatic anchoring optimization is enabled Returns: TRUE or FALSE */ static BOOL is_startline(PCRE2_SPTR code, unsigned int bracket_map, compile_block *cb, - int atomcount, BOOL inassert, BOOL dotstar_anchor) + int atomcount, BOOL inassert) { do { PCRE2_SPTR scode = first_significant_code( @@ -8774,8 +8827,7 @@ do { return FALSE; default: /* Assertion */ - if (!is_startline(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor)) - return FALSE; + if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; do scode += GET(scode, 1); while (*scode == OP_ALT); scode += 1 + LINK_SIZE; break; @@ -8789,7 +8841,7 @@ do { if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_startline(scode, bracket_map, cb, atomcount, inassert, dotstar_anchor)) + if (!is_startline(scode, bracket_map, cb, atomcount, inassert)) return FALSE; } @@ -8800,15 +8852,14 @@ do { { int n = GET2(scode, 1+LINK_SIZE); unsigned int new_map = bracket_map | ((n < 32)? (1u << n) : 1); - if (!is_startline(scode, new_map, cb, atomcount, inassert, dotstar_anchor)) - return FALSE; + if (!is_startline(scode, new_map, cb, atomcount, inassert)) return FALSE; } /* Positive forward assertions */ else if (op == OP_ASSERT || op == OP_ASSERT_NA) { - if (!is_startline(scode, bracket_map, cb, atomcount, TRUE, dotstar_anchor)) + if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; } @@ -8816,7 +8867,7 @@ do { else if (op == OP_ONCE) { - if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert, dotstar_anchor)) + if (!is_startline(scode, bracket_map, cb, atomcount + 1, inassert)) return FALSE; } @@ -8830,7 +8881,8 @@ do { else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) { if (scode[1] != OP_ANY || (bracket_map & cb->backref_map) != 0 || - atomcount > 0 || cb->had_pruneorskip || inassert || !dotstar_anchor) + atomcount > 0 || cb->had_pruneorskip || inassert || + (cb->external_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) return FALSE; } @@ -8864,8 +8916,8 @@ OP_RECURSE. Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ -static PCRE2_UCHAR * -find_recurse(PCRE2_UCHAR *code, BOOL utf) +static PCRE2_SPTR +find_recurse(PCRE2_SPTR code, BOOL utf) { for (;;) { @@ -8874,13 +8926,12 @@ for (;;) if (c == OP_RECURSE) return code; /* XCLASS is used for classes that cannot be represented just by a bit map. - This includes negated single high-valued characters. ECLASS is used for - classes that use set operations internally. CALLOUT_STR is used for - callouts with string arguments. In each case the length in the table is + This includes negated single high-valued characters. CALLOUT_STR is used for + callouts with string arguments. In both cases the length in the table is zero; the actual length is stored in the compiled code. */ - if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1); - else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); + if (c == OP_XCLASS) code += GET(code, 1); + else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); /* Otherwise, we can get the item's length from the table, except that for repeated character types, we have to test for \p and \P, which have an extra @@ -9210,12 +9261,9 @@ for (;; pptr++) if (meta < META_END) continue; /* Literal */ break; - case META_END: - - /* The parsed regex is malformed; we have reached the end and did - not find the end of the construct which we are skipping over. */ + /* This should never occur. */ - PCRE2_DEBUG_UNREACHABLE(); + case META_END: return NULL; /* The data for these items is variable in length. */ @@ -9224,9 +9272,19 @@ for (;; pptr++) if (META_DATA(*pptr) >= 10) pptr += SIZEOFFSET; break; - case META_ESCAPE: - if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p) - pptr += 1; /* Skip prop data */ + case META_ESCAPE: /* A few escapes are followed by data items. */ + switch (META_DATA(*pptr)) + { + case ESC_P: + case ESC_p: + pptr += 1; + break; + + case ESC_g: + case ESC_k: + pptr += 1 + SIZEOFFSET; + break; + } break; case META_MARK: /* Add the length of the name. */ @@ -9252,7 +9310,6 @@ for (;; pptr++) case META_COND_RNAME: case META_COND_RNUMBER: case META_COND_VERSION: - case META_SCS: case META_LOOKAHEAD: case META_LOOKAHEADNOT: case META_LOOKAHEAD_NA: @@ -9280,8 +9337,8 @@ for (;; pptr++) if (meta >= sizeof(meta_extra_lengths)) return NULL; pptr += meta_extra_lengths[meta]; } - -PCRE2_UNREACHABLE(); /* Control never reaches here */ +/* Control never reaches here */ +return pptr; } @@ -9412,10 +9469,10 @@ for (;; pptr++) parsed_recurse_check *r; uint32_t *gptr, *gptrend; uint32_t escape; - uint32_t min, max; uint32_t group = 0; uint32_t itemlength = 0; uint32_t itemminlength = 0; + uint32_t min, max; if (*pptr < META_END) { @@ -9514,7 +9571,6 @@ for (;; pptr++) case META_LOOKAHEAD: case META_LOOKAHEADNOT: case META_LOOKAHEAD_NA: - case META_SCS: *errcodeptr = check_lookbehinds(pptr + 1, &pptr, recurses, cb, lcptr); if (*errcodeptr != 0) return -1; @@ -9546,9 +9602,7 @@ for (;; pptr++) break; /* A nested lookbehind does not contribute any length to this lookbehind, - but must itself be checked and have its lengths set. Note that - set_lookbehind_lengths() updates pptr, leaving it pointing to the final ket - of the group, so no need to update it here. */ + but must itself be checked and have its lengths set. */ case META_LOOKBEHIND: case META_LOOKBEHINDNOT: @@ -9784,8 +9838,7 @@ for (;; pptr++) return branchlength; PARSED_SKIP_FAILED: -PCRE2_DEBUG_UNREACHABLE(); -*errcodeptr = ERR90; /* Unhandled META code - internal error */ +*errcodeptr = ERR90; return -1; } @@ -9869,7 +9922,7 @@ possibly different) length. */ if (variable) { gbptr[1] = minlength; - if ((PCRE2_SIZE)maxlength > cb->max_varlookbehind) + if ((uint32_t)maxlength > cb->max_varlookbehind) { *errcodeptr = ERR100; cb->erroroffset = offset; @@ -9878,6 +9931,8 @@ if (variable) } else gbptr[1] = LOOKBEHIND_MAX; + +gbptr[1] = variable? minlength : LOOKBEHIND_MAX; return TRUE; } @@ -9923,18 +9978,11 @@ for (; *pptr != META_END; pptr++) switch (META_CODE(*pptr)) { default: - - /* The following erroroffset is a bogus but safe value. This branch should - be avoided by providing a proper implementation for all supported cases - below. */ - - PCRE2_DEBUG_UNREACHABLE(); - cb->erroroffset = 0; return ERR70; /* Unrecognized meta code */ case META_ESCAPE: if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p) - pptr += 1; /* Skip prop data */ + pptr += 1; break; case META_KET: @@ -9948,7 +9996,6 @@ for (; *pptr != META_END; pptr++) case META_ATOMIC: case META_CAPTURE: case META_COND_ASSERT: - case META_SCS: case META_LOOKAHEAD: case META_LOOKAHEADNOT: case META_LOOKAHEAD_NA: @@ -9986,7 +10033,6 @@ for (; *pptr != META_END; pptr++) case META_THEN: break; - case META_OFFSET: case META_RECURSE: pptr += SIZEOFFSET; break; @@ -10021,8 +10067,6 @@ for (; *pptr != META_END; pptr++) case META_BIGVALUE: case META_POSIX: case META_POSIX_NEG: - case META_SCS_NAME: - case META_SCS_NUMBER: pptr += 1; break; @@ -10045,9 +10089,6 @@ for (; *pptr != META_END; pptr++) pptr += 1 + pptr[1]; break; - /* Note that set_lookbehind_lengths() updates pptr, leaving it pointing to - the final ket of the group, so no need to update it here. */ - case META_LOOKBEHIND: case META_LOOKBEHINDNOT: case META_LOOKBEHIND_NA: @@ -10094,19 +10135,19 @@ compile_block cb; /* "Static" compile-time data */ const uint8_t *tables; /* Char tables base pointer */ PCRE2_UCHAR *code; /* Current pointer in compiled code */ -PCRE2_UCHAR * codestart; /* Start of compiled code */ +PCRE2_SPTR codestart; /* Start of compiled code */ PCRE2_SPTR ptr; /* Current pointer in pattern */ uint32_t *pptr; /* Current pointer in parsed pattern */ PCRE2_SIZE length = 1; /* Allow for final END opcode */ PCRE2_SIZE usedlength; /* Actual length used */ PCRE2_SIZE re_blocksize; /* Size of memory block */ +PCRE2_SIZE big32count = 0; /* 32-bit literals >= 0x80000000 */ PCRE2_SIZE parsed_size_needed; /* Needed for parsed pattern */ uint32_t firstcuflags, reqcuflags; /* Type of first/req code unit */ uint32_t firstcu, reqcu; /* Value of first/req code unit */ uint32_t setflags = 0; /* NL and BSR set flags */ -uint32_t xoptions; /* Flags from context, modified */ uint32_t skipatstart; /* When checking (*UTF) etc */ uint32_t limit_heap = UINT32_MAX; @@ -10120,10 +10161,6 @@ int regexrc; /* Return from compile */ uint32_t i; /* Local loop counter */ -/* Enable all optimizations by default. */ -uint32_t optim_flags = ccontext != NULL ? ccontext->optimization_flags : - PCRE2_OPTIMIZATION_ALL; - /* Comments at the head of this file explain about these variables. */ uint32_t stack_groupinfo[GROUPINFO_DEFAULT_SIZE]; @@ -10187,7 +10224,6 @@ PCRE2_ZERO_TERMINATED. Check for an overlong pattern. */ if ((zero_terminated = (patlen == PCRE2_ZERO_TERMINATED))) patlen = PRIV(strlen)(pattern); -(void)zero_terminated; /* Silence compiler; only used if Valgrind enabled */ if (patlen > ccontext->max_pattern_length) { @@ -10195,18 +10231,6 @@ if (patlen > ccontext->max_pattern_length) return NULL; } -/* Optimization flags in 'options' can override those in the compile context. -This is because some options to disable optimizations were added before the -optimization flags word existed, and we need to continue supporting them -for backwards compatibility. */ - -if ((options & PCRE2_NO_AUTO_POSSESS) != 0) - optim_flags &= ~PCRE2_OPTIM_AUTO_POSSESS; -if ((options & PCRE2_NO_DOTSTAR_ANCHOR) != 0) - optim_flags &= ~PCRE2_OPTIM_DOTSTAR_ANCHOR; -if ((options & PCRE2_NO_START_OPTIMIZE) != 0) - optim_flags &= ~PCRE2_OPTIM_START_OPTIMIZE; - /* From here on, all returns from this function should end up going via the EXIT label. */ @@ -10245,11 +10269,6 @@ cb.start_code = cworkspace; cb.start_pattern = pattern; cb.start_workspace = cworkspace; cb.workspace_size = COMPILE_WORK_SIZE; -#ifdef SUPPORT_WIDE_CHARS -cb.cranges = NULL; -cb.next_cranges = NULL; -cb.char_lists_size = 0; -#endif /* Maximum back reference and backref bitmap. The bitmap records up to 31 back references to help in deciding whether (.*) can be treated as anchored or not. @@ -10283,7 +10302,6 @@ non-zero-terminated patterns. */ if (zero_terminated) VALGRIND_MAKE_MEM_NOACCESS(pattern + patlen, CU2BYTES(1)); #endif -xoptions = ccontext->extra_options; ptr = pattern; skipatstart = 0; @@ -10295,13 +10313,13 @@ if ((options & PCRE2_LITERAL) == 0) { for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++) { + uint32_t c, pp; const pso *p = pso_list + i; if (patlen - skipatstart - 2 >= p->length && - PRIV(strncmp_c8)(ptr + skipatstart + 2, p->name, p->length) == 0) + PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name), + p->length) == 0) { - uint32_t c, pp; - skipatstart += p->length + 2; switch(p->type) { @@ -10309,10 +10327,6 @@ if ((options & PCRE2_LITERAL) == 0) cb.external_options |= p->value; break; - case PSO_XOPT: - xoptions |= p->value; - break; - case PSO_FLG: setflags |= p->value; break; @@ -10332,12 +10346,18 @@ if ((options & PCRE2_LITERAL) == 0) case PSO_LIMH: c = 0; pp = skipatstart; - while (pp < patlen && IS_DIGIT(ptr[pp])) + if (!IS_DIGIT(ptr[pp])) + { + errorcode = ERR60; + ptr += pp; + goto HAD_EARLY_ERROR; + } + while (IS_DIGIT(ptr[pp])) { if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */ c = c*10 + (ptr[pp++] - CHAR_0); } - if (pp >= patlen || pp == skipatstart || ptr[pp] != CHAR_RIGHT_PARENTHESIS) + if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS) { errorcode = ERR60; ptr += pp; @@ -10346,45 +10366,14 @@ if ((options & PCRE2_LITERAL) == 0) if (p->type == PSO_LIMH) limit_heap = c; else if (p->type == PSO_LIMM) limit_match = c; else limit_depth = c; - skipatstart = ++pp; - break; - - case PSO_OPTMZ: - optim_flags &= ~(p->value); - - /* For backward compatibility the three original VERBs to disable - optimizations need to also update the corresponding bit in the - external options. */ - - switch(p->value) - { - case PCRE2_OPTIM_AUTO_POSSESS: - cb.external_options |= PCRE2_NO_AUTO_POSSESS; - break; - - case PCRE2_OPTIM_DOTSTAR_ANCHOR: - cb.external_options |= PCRE2_NO_DOTSTAR_ANCHOR; - break; - - case PCRE2_OPTIM_START_OPTIMIZE: - cb.external_options |= PCRE2_NO_START_OPTIMIZE; - break; - } - + skipatstart += pp - skipatstart; break; - - default: - /* All values in the enum need an explicit entry for this switch - but until a better way to prevent coding mistakes is invented keep - a catch all that triggers a debug build assert as a failsafe */ - PCRE2_DEBUG_UNREACHABLE(); } break; /* Out of the table scan loop */ } } if (i >= sizeof(pso_list)/sizeof(pso)) break; /* Out of pso loop */ } - PCRE2_ASSERT(skipatstart <= patlen); } /* End of pattern-start options; advance to start of real regex. */ @@ -10436,31 +10425,6 @@ if (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0) goto HAD_EARLY_ERROR; } -/* PCRE2_EXTRA_TURKISH_CASING checks */ - -if ((xoptions & PCRE2_EXTRA_TURKISH_CASING) != 0) - { - if (!utf && !ucp) - { - errorcode = ERR104; - goto HAD_EARLY_ERROR; - } - -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (!utf) - { - errorcode = ERR105; - goto HAD_EARLY_ERROR; - } -#endif - - if ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0) - { - errorcode = ERR106; - goto HAD_EARLY_ERROR; - } - } - /* Process the BSR setting. */ if (bsr == 0) bsr = ccontext->bsr_convention; @@ -10501,7 +10465,6 @@ switch(newline) break; default: - PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR56; goto HAD_EARLY_ERROR; } @@ -10510,31 +10473,42 @@ switch(newline) their numerical equivalents, so that this information is always available for the remaining processing. (2) At the same time, parse the pattern and put a processed version into the parsed_pattern vector. This has escapes interpreted -and comments removed (amongst other things). */ +and comments removed (amongst other things). -/* Ensure that the parsed pattern buffer is big enough. For many smaller -patterns the vector on the stack (which was set up above) can be used. */ +In all but one case, when PCRE2_AUTO_CALLOUT is not set, the number of unsigned +32-bit ints in the parsed pattern is bounded by the length of the pattern plus +one (for the terminator) plus four if PCRE2_EXTRA_WORD or PCRE2_EXTRA_LINE is +set. The exceptional case is when running in 32-bit, non-UTF mode, when literal +characters greater than META_END (0x80000000) have to be coded as two units. In +this case, therefore, we scan the pattern to check for such values. */ + +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (!utf) + { + PCRE2_SPTR p; + for (p = ptr; p < cb.end_pattern; p++) if (*p >= META_END) big32count++; + } +#endif -parsed_size_needed = max_parsed_pattern(ptr, cb.end_pattern, utf, options); +/* Ensure that the parsed pattern buffer is big enough. When PCRE2_AUTO_CALLOUT +is set we have to assume a numerical callout (4 elements) for each character +plus one at the end. This is overkill, but memory is plentiful these days. For +many smaller patterns the vector on the stack (which was set up above) can be +used. */ -/* Allow for 2x uint32_t at the start and 2 at the end, for -PCRE2_EXTRA_MATCH_WORD or PCRE2_EXTRA_MATCH_LINE (which are exclusive). */ +parsed_size_needed = patlen - skipatstart + big32count; if ((ccontext->extra_options & (PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_MATCH_LINE)) != 0) parsed_size_needed += 4; -/* When PCRE2_AUTO_CALLOUT is set we allow for one callout at the end. */ - if ((options & PCRE2_AUTO_CALLOUT) != 0) - parsed_size_needed += 4; - -parsed_size_needed += 1; /* For the final META_END */ + parsed_size_needed = (parsed_size_needed + 1) * 5; -if (parsed_size_needed > PARSED_PATTERN_DEFAULT_SIZE) +if (parsed_size_needed >= PARSED_PATTERN_DEFAULT_SIZE) { uint32_t *heap_parsed_pattern = ccontext->memctl.malloc( - parsed_size_needed * sizeof(uint32_t), ccontext->memctl.memory_data); + (parsed_size_needed + 1) * sizeof(uint32_t), ccontext->memctl.memory_data); if (heap_parsed_pattern == NULL) { *errorptr = ERR21; @@ -10542,11 +10516,11 @@ if (parsed_size_needed > PARSED_PATTERN_DEFAULT_SIZE) } cb.parsed_pattern = heap_parsed_pattern; } -cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed; +cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1; /* Do the parsing scan. */ -errorcode = parse_regex(ptr, cb.external_options, xoptions, &has_lookbehind, &cb); +errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb); if (errorcode != 0) goto HAD_CB_ERROR; /* If there are any lookbehinds, scan the parsed pattern to figure out their @@ -10615,7 +10589,7 @@ pptr = cb.parsed_pattern; code = cworkspace; *code = OP_BRA; -(void)compile_regex(cb.external_options, xoptions, &code, &pptr, +(void)compile_regex(cb.external_options, ccontext->extra_options, &code, &pptr, &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, NULL, &cb, &length); @@ -10623,13 +10597,7 @@ if (errorcode != 0) goto HAD_CB_ERROR; /* Offset is in cb.erroroffset */ /* This should be caught in compile_regex(), but just in case... */ -#if defined SUPPORT_WIDE_CHARS -PCRE2_ASSERT((cb.char_lists_size & 0x3) == 0); -if (length > MAX_PATTERN_SIZE || - MAX_PATTERN_SIZE - length < (cb.char_lists_size / sizeof(PCRE2_UCHAR))) -#else if (length > MAX_PATTERN_SIZE) -#endif { errorcode = ERR20; goto HAD_CB_ERROR; @@ -10640,22 +10608,9 @@ block for storing the compiled pattern and names table. Integer overflow should no longer be possible because nowadays we limit the maximum value of cb.names_found and cb.name_entry_size. */ -re_blocksize = - CU2BYTES((PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size); - -#if defined SUPPORT_WIDE_CHARS -if (cb.char_lists_size != 0) - { -#if PCRE2_CODE_UNIT_WIDTH != 32 - /* Align to 32 bit first. This ensures the - allocated area will also be 32 bit aligned. */ - re_blocksize = (PCRE2_SIZE)CLIST_ALIGN_TO(re_blocksize, sizeof(uint32_t)); -#endif - re_blocksize += cb.char_lists_size; - } -#endif - -re_blocksize += CU2BYTES(length); +re_blocksize = sizeof(pcre2_real_code) + + CU2BYTES(length + + (PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size); if (re_blocksize > ccontext->max_pattern_compiled_length) { @@ -10663,7 +10618,6 @@ if (re_blocksize > ccontext->max_pattern_compiled_length) goto HAD_CB_ERROR; } -re_blocksize += sizeof(pcre2_real_code); re = (pcre2_real_code *) ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data); if (re == NULL) @@ -10684,11 +10638,10 @@ re->tables = tables; re->executable_jit = NULL; memset(re->start_bitmap, 0, 32 * sizeof(uint8_t)); re->blocksize = re_blocksize; -re->code_start = re_blocksize - CU2BYTES(length); re->magic_number = MAGIC_NUMBER; re->compile_options = options; re->overall_options = cb.external_options; -re->extra_options = xoptions; +re->extra_options = ccontext->extra_options; re->flags = PCRE2_CODE_UNIT_WIDTH/8 | cb.external_flags | setflags; re->limit_heap = limit_heap; re->limit_match = limit_match; @@ -10703,12 +10656,12 @@ re->top_bracket = 0; re->top_backref = 0; re->name_entry_size = cb.name_entry_size; re->name_count = cb.names_found; -re->optimization_flags = optim_flags; /* The basic block is immediately followed by the name table, and the compiled code follows after that. */ -codestart = (PCRE2_UCHAR *)((uint8_t *)re + re->code_start); +codestart = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) + + re->name_entry_size * re->name_count; /* Update the compile data block for the actual compile. The starting points of the name/number translation table and of the code are passed around in the @@ -10723,10 +10676,6 @@ cb.start_code = codestart; cb.req_varyopt = 0; cb.had_accept = FALSE; cb.had_pruneorskip = FALSE; -#ifdef SUPPORT_WIDE_CHARS -cb.char_lists_size = 0; -#endif - /* If any named groups were found, create the name/number table from the list created in the pre-pass. */ @@ -10745,7 +10694,7 @@ of the function here. */ pptr = cb.parsed_pattern; code = (PCRE2_UCHAR *)codestart; *code = OP_BRA; -regexrc = compile_regex(re->overall_options, re->extra_options, &code, +regexrc = compile_regex(re->overall_options, ccontext->extra_options, &code, &pptr, &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, NULL, &cb, NULL); if (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY; @@ -10767,12 +10716,7 @@ memory as unaddressable, so that any out-of-bound reads can be detected. */ *code++ = OP_END; usedlength = code - codestart; -if (usedlength > length) - { - PCRE2_DEBUG_UNREACHABLE(); - errorcode = ERR23; /* Overflow of code block - internal error */ - } -else +if (usedlength > length) errorcode = ERR23; else { re->blocksize -= CU2BYTES(length - usedlength); #ifdef SUPPORT_VALGRIND @@ -10794,9 +10738,9 @@ if (errorcode == 0 && cb.had_recurse) int start = RSCAN_CACHE_SIZE; recurse_cache rc[RSCAN_CACHE_SIZE]; - for (rcode = find_recurse(codestart, utf); + for (rcode = (PCRE2_UCHAR *)find_recurse(codestart, utf); rcode != NULL; - rcode = find_recurse(rcode + 1 + LINK_SIZE, utf)) + rcode = (PCRE2_UCHAR *)find_recurse(rcode + 1 + LINK_SIZE, utf)) { int p, groupnumber; @@ -10825,7 +10769,6 @@ if (errorcode == 0 && cb.had_recurse) rgroup = PRIV(find_bracket)(search_from, utf, groupnumber); if (rgroup == NULL) { - PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR53; break; } @@ -10836,7 +10779,7 @@ if (errorcode == 0 && cb.had_recurse) } } - PUT(rcode, 1, (uint32_t)(rgroup - codestart)); + PUT(rcode, 1, rgroup - codestart); } } @@ -10855,14 +10798,10 @@ used in this code because at least one compiler gives a warning about loss of "const" attribute if the cast (PCRE2_UCHAR *)codestart is used directly in the function call. */ -if (errorcode == 0 && (optim_flags & PCRE2_OPTIM_AUTO_POSSESS) != 0) +if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0) { PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart; - if (PRIV(auto_possessify)(temp, &cb) != 0) - { - PCRE2_DEBUG_UNREACHABLE(); - errorcode = ERR80; - } + if (PRIV(auto_possessify)(temp, &cb) != 0) errorcode = ERR80; } /* Failed to compile, or error while post-processing. */ @@ -10875,21 +10814,18 @@ or anything else, such as starting with non-atomic .* when DOTALL is set and there are no occurrences of *PRUNE or *SKIP (though there is an option to disable this case). */ -if ((re->overall_options & PCRE2_ANCHORED) == 0) - { - BOOL dotstar_anchor = ((optim_flags & PCRE2_OPTIM_DOTSTAR_ANCHOR) != 0); - if (is_anchored(codestart, 0, &cb, 0, FALSE, dotstar_anchor)) - re->overall_options |= PCRE2_ANCHORED; - } +if ((re->overall_options & PCRE2_ANCHORED) == 0 && + is_anchored(codestart, 0, &cb, 0, FALSE)) + re->overall_options |= PCRE2_ANCHORED; /* Set up the first code unit or startline flag, the required code unit, and -then study the pattern. This code need not be obeyed if PCRE2_OPTIM_START_OPTIMIZE -is disabled, as the data it would create will not be used. Note that a first code +then study the pattern. This code need not be obeyed if PCRE2_NO_START_OPTIMIZE +is set, as the data it would create will not be used. Note that a first code unit (but not the startline flag) is useful for anchored patterns because it can still give a quick "no match" and also avoid searching for a last code unit. */ -if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) +if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) { int minminlength = 0; /* For minimal minlength from first/required CU */ @@ -10897,19 +10833,8 @@ if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) (these are not saved during the compile because they can cause conflicts with actual literals that follow). */ - if (firstcuflags >= REQ_NONE) { - uint32_t assertedcuflags = 0; - uint32_t assertedcu = find_firstassertedcu(codestart, &assertedcuflags, 0); - /* It would be wrong to use the asserted first code unit as `firstcu` for - * regexes which are able to match a 1-character string (e.g. /(?=a)b?a/) - * For that example, if we set both firstcu and reqcu to 'a', it would mean - * the subject string needs to be at least 2 characters long, which is wrong. - * With more analysis, we would be able to set firstcu in more cases. */ - if (assertedcuflags < REQ_NONE && assertedcu != reqcu) { - firstcu = assertedcu; - firstcuflags = assertedcuflags; - } - } + if (firstcuflags >= REQ_NONE) + firstcu = find_firstassertedcu(codestart, &firstcuflags, 0); /* Save the data for a first code unit. The existence of one means the minimum length must be at least 1. */ @@ -10930,8 +10855,8 @@ if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) } /* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise. - In 8-bit UTF mode, code units in the range 128-255 are introductory code - units and cannot have another case, but if UCP is set they may do. */ + In 8-bit UTF mode, codepoints in the range 128-255 are introductory code + points and cannot have another case, but if UCP is set they may do. */ #ifdef SUPPORT_UNICODE #if PCRE2_CODE_UNIT_WIDTH == 8 @@ -10952,12 +10877,9 @@ if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) non-DOTALL matches when *PRUNE and SKIP are not present. (There is an option that disables this case.) */ - else if ((re->overall_options & PCRE2_ANCHORED) == 0) - { - BOOL dotstar_anchor = ((optim_flags & PCRE2_OPTIM_DOTSTAR_ANCHOR) != 0); - if (is_startline(codestart, 0, &cb, 0, FALSE, dotstar_anchor)) - re->flags |= PCRE2_STARTLINE; - } + else if ((re->overall_options & PCRE2_ANCHORED) == 0 && + is_startline(codestart, 0, &cb, 0, FALSE)) + re->flags |= PCRE2_STARTLINE; /* Handle the "required code unit", if one is set. In the UTF case we can increment the minimum minimum length only if we are sure this really is a @@ -11017,7 +10939,6 @@ if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) if (PRIV(study)(re) != 0) { - PCRE2_DEBUG_UNREACHABLE(); errorcode = ERR31; goto HAD_CB_ERROR; } @@ -11040,10 +10961,6 @@ version of the pattern, free it before returning. Also free the list of named groups if a larger one had to be obtained, and likewise the group information vector. */ -#ifdef SUPPORT_UNICODE -PCRE2_ASSERT(cb.cranges == NULL); -#endif - EXIT: #ifdef SUPPORT_VALGRIND if (zero_terminated) VALGRIND_MAKE_MEM_DEFINED(pattern + patlen, CU2BYTES(1)); @@ -11054,7 +10971,6 @@ if (cb.named_group_list_size > NAMED_GROUP_LIST_SIZE) ccontext->memctl.free((void *)cb.named_groups, ccontext->memctl.memory_data); if (cb.groupinfo != stack_groupinfo) ccontext->memctl.free((void *)cb.groupinfo, ccontext->memctl.memory_data); - return re; /* Will be NULL after an error */ /* Errors discovered in parse_regex() set the offset value in the compile @@ -11067,28 +10983,12 @@ an offset is available in the parsed pattern. */ ptr = pattern + cb.erroroffset; HAD_EARLY_ERROR: -PCRE2_ASSERT(ptr >= pattern); /* Ensure we don't return invalid erroroffset */ -PCRE2_ASSERT(ptr <= (pattern + patlen)); *erroroffset = ptr - pattern; HAD_ERROR: *errorptr = errorcode; pcre2_code_free(re); re = NULL; - -#ifdef SUPPORT_WIDE_CHARS -if (cb.cranges != NULL) - { - class_ranges* cranges = cb.cranges; - do - { - class_ranges* next_cranges = cranges->next; - cb.cx->memctl.free(cranges, cb.cx->memctl.memory_data); - cranges = next_cranges; - } - while (cranges != NULL); - } -#endif goto EXIT; } diff --git a/ext/pcre/pcre2lib/pcre2_compile.h b/ext/pcre/pcre2lib/pcre2_compile.h deleted file mode 100644 index c8bf610bed54..000000000000 --- a/ext/pcre/pcre2lib/pcre2_compile.h +++ /dev/null @@ -1,280 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE2 is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifndef PCRE2_COMPILE_H_IDEMPOTENT_GUARD -#define PCRE2_COMPILE_H_IDEMPOTENT_GUARD - -#include "pcre2_internal.h" - -/* Compile time error code numbers. They are given names so that they can more -easily be tracked. When a new number is added, the tables called eint1 and -eint2 in pcre2posix.c may need to be updated, and a new error text must be -added to compile_error_texts in pcre2_error.c. Also, the error codes in -pcre2.h.in must be updated - their values are exactly 100 greater than these -values. */ - -enum { ERR0 = COMPILE_ERROR_BASE, - ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, - ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, - ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30, - ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, - ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, - ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, - ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, - ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, - ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, - ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100, - ERR101,ERR102,ERR103,ERR104,ERR105,ERR106,ERR107,ERR108,ERR109,ERR110, - ERR111,ERR112,ERR113,ERR114,ERR115,ERR116 }; - -/* Code values for parsed patterns, which are stored in a vector of 32-bit -unsigned ints. Values less than META_END are literal data values. The coding -for identifying the item is in the top 16-bits, leaving 16 bits for the -additional data that some of them need. The META_CODE, META_DATA, and META_DIFF -macros are used to manipulate parsed pattern elements. - -NOTE: When these definitions are changed, the table of extra lengths for each -code (meta_extra_lengths) must be updated to remain in step. */ - -#define META_END 0x80000000u /* End of pattern */ - -#define META_ALT 0x80010000u /* alternation */ -#define META_ATOMIC 0x80020000u /* atomic group */ -#define META_BACKREF 0x80030000u /* Back ref */ -#define META_BACKREF_BYNAME 0x80040000u /* \k'name' */ -#define META_BIGVALUE 0x80050000u /* Next is a literal > META_END */ -#define META_CALLOUT_NUMBER 0x80060000u /* (?C with numerical argument */ -#define META_CALLOUT_STRING 0x80070000u /* (?C with string argument */ -#define META_CAPTURE 0x80080000u /* Capturing parenthesis */ -#define META_CIRCUMFLEX 0x80090000u /* ^ metacharacter */ -#define META_CLASS 0x800a0000u /* start non-empty class */ -#define META_CLASS_EMPTY 0x800b0000u /* empty class */ -#define META_CLASS_EMPTY_NOT 0x800c0000u /* negative empty class */ -#define META_CLASS_END 0x800d0000u /* end of non-empty class */ -#define META_CLASS_NOT 0x800e0000u /* start non-empty negative class */ -#define META_COND_ASSERT 0x800f0000u /* (?(?assertion)... */ -#define META_COND_DEFINE 0x80100000u /* (?(DEFINE)... */ -#define META_COND_NAME 0x80110000u /* (?()... */ -#define META_COND_NUMBER 0x80120000u /* (?(digits)... */ -#define META_COND_RNAME 0x80130000u /* (?(R&name)... */ -#define META_COND_RNUMBER 0x80140000u /* (?(Rdigits)... */ -#define META_COND_VERSION 0x80150000u /* (?(VERSIONx.y)... */ -#define META_OFFSET 0x80160000u /* Setting offset for various - META codes (e.g. META_SCS_NAME) */ -#define META_SCS 0x80170000u /* (*scan_substring:... */ -#define META_SCS_NAME 0x80180000u /* Next of scan_substring */ -#define META_SCS_NUMBER 0x80190000u /* Next digits of scan_substring */ -#define META_DOLLAR 0x801a0000u /* $ metacharacter */ -#define META_DOT 0x801b0000u /* . metacharacter */ -#define META_ESCAPE 0x801c0000u /* \d and friends */ -#define META_KET 0x801d0000u /* closing parenthesis */ -#define META_NOCAPTURE 0x801e0000u /* no capture parens */ -#define META_OPTIONS 0x801f0000u /* (?i) and friends */ -#define META_POSIX 0x80200000u /* POSIX class item */ -#define META_POSIX_NEG 0x80210000u /* negative POSIX class item */ -#define META_RANGE_ESCAPED 0x80220000u /* range with at least one escape */ -#define META_RANGE_LITERAL 0x80230000u /* range defined literally */ -#define META_RECURSE 0x80240000u /* Recursion */ -#define META_RECURSE_BYNAME 0x80250000u /* (?&name) */ -#define META_SCRIPT_RUN 0x80260000u /* (*script_run:...) */ - -/* These must be kept together to make it easy to check that an assertion -is present where expected in a conditional group. */ - -#define META_LOOKAHEAD 0x80270000u /* (?= */ -#define META_LOOKAHEADNOT 0x80280000u /* (?! */ -#define META_LOOKBEHIND 0x80290000u /* (?<= */ -#define META_LOOKBEHINDNOT 0x802a0000u /* (?>16) - -/* Extended class management flags. */ - -#define CLASS_IS_ECLASS 0x1 - -/* Macro for the highest character value. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define MAX_UCHAR_VALUE 0xffu -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#define MAX_UCHAR_VALUE 0xffffu -#else -#define MAX_UCHAR_VALUE 0xffffffffu -#endif - -#define GET_MAX_CHAR_VALUE(utf) \ - ((utf) ? MAX_UTF_CODE_POINT : MAX_UCHAR_VALUE) - -/* Macro for setting individual bits in class bitmaps. */ - -#define SETBIT(a,b) a[(b) >> 3] |= (uint8_t)(1u << ((b) & 0x7)) - -/* Macro for 8 bit specific checks. */ -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define SELECT_VALUE8(value8, value) (value8) -#else -#define SELECT_VALUE8(value8, value) (value) -#endif - -/* Macro for aligning data. */ -#define CLIST_ALIGN_TO(base, align) \ - ((base + ((size_t)(align) - 1)) & ~((size_t)(align) - 1)) - -/* Structure for holding information about an OP_ECLASS internal operand. -An "operand" here could be just a single OP_[X]CLASS, or it could be some -complex expression; but it's some sequence of ECL_* codes which pushes one -value to the stack. */ -typedef struct { - /* The position of the operand - or NULL if (lengthptr != NULL). */ - PCRE2_UCHAR *code_start; - PCRE2_SIZE length; - /* The operand's type if it is a single code (ECL_XCLASS, ECL_ANY, ECL_NONE); - otherwise zero if the operand is not atomic. */ - uint8_t op_single_type; - /* Regardless of whether it's a single code or not, we fully constant-fold - the bitmap for code points < 256. */ - class_bits_storage bits; -} eclass_op_info; - -/* Macros for the definitions below, to prevent name collisions. */ - -#define _pcre2_posix_class_maps PCRE2_SUFFIX(_pcre2_posix_class_maps) -#define _pcre2_update_classbits PCRE2_SUFFIX(_pcre2_update_classbits_) -#define _pcre2_compile_class_nested PCRE2_SUFFIX(_pcre2_compile_class_nested_) -#define _pcre2_compile_class_not_nested PCRE2_SUFFIX(_pcre2_compile_class_not_nested_) - - -/* Indices of the POSIX classes in posix_names, posix_name_lengths, -posix_class_maps, and posix_substitutes. They must be kept in sync. */ - -#define PC_DIGIT 7 -#define PC_GRAPH 8 -#define PC_PRINT 9 -#define PC_PUNCT 10 -#define PC_XDIGIT 13 - -extern const int PRIV(posix_class_maps)[]; - - -/* Set bits in classbits according to the property type */ - -void PRIV(update_classbits)(uint32_t ptype, uint32_t pdata, BOOL negated, - uint8_t *classbits); - -/* Compile the META codes from start_ptr...end_ptr, writing a single OP_CLASS -OP_CLASS, OP_NCLASS, OP_XCLASS, or OP_ALLANY into pcode. */ - -uint32_t *PRIV(compile_class_not_nested)(uint32_t options, uint32_t xoptions, - uint32_t *start_ptr, PCRE2_UCHAR **pcode, BOOL negate_class, BOOL* has_bitmap, - int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr); - -/* Compile the META codes in pptr into opcodes written to pcode. The pptr must -start at a META_CLASS or META_CLASS_NOT. - -The pptr will be left pointing at the matching META_CLASS_END. */ - -BOOL PRIV(compile_class_nested)(uint32_t options, uint32_t xoptions, - uint32_t **pptr, PCRE2_UCHAR **pcode, int *errorcodeptr, - compile_block *cb, PCRE2_SIZE *lengthptr); - -#endif /* PCRE2_COMPILE_H_IDEMPOTENT_GUARD */ - -/* End of pcre2_compile.h */ diff --git a/ext/pcre/pcre2lib/pcre2_compile_class.c b/ext/pcre/pcre2lib/pcre2_compile_class.c deleted file mode 100644 index 6a73bb9a71b9..000000000000 --- a/ext/pcre/pcre2lib/pcre2_compile_class.c +++ /dev/null @@ -1,2737 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pcre2_compile.h" - -typedef struct { - /* Option bits for eclass. */ - uint32_t options; - uint32_t xoptions; - /* Rarely used members. */ - int *errorcodeptr; - compile_block *cb; - /* Bitmap is needed. */ - BOOL needs_bitmap; -} eclass_context; - -/* Checks the allowed tokens at the end of a class structure in debug mode. -When a new token is not processed by all loops, and the token is equals to -a) one of the cases here: - the compiler will complain about a duplicated case value. -b) none of the cases here: - the loop without the handler will stop with an assertion failure. */ - -#ifdef PCRE2_DEBUG -#define CLASS_END_CASES(meta) \ - default: \ - PCRE2_ASSERT((meta) <= META_END); \ - /* Fall through */ \ - case META_CLASS: \ - case META_CLASS_NOT: \ - case META_CLASS_EMPTY: \ - case META_CLASS_EMPTY_NOT: \ - case META_CLASS_END: \ - case META_ECLASS_AND: \ - case META_ECLASS_OR: \ - case META_ECLASS_SUB: \ - case META_ECLASS_XOR: \ - case META_ECLASS_NOT: -#else -#define CLASS_END_CASES(meta) \ - default: -#endif - -#ifdef SUPPORT_WIDE_CHARS - -/* Heapsort algorithm. */ - -static void do_heapify(uint32_t *buffer, size_t size, size_t i) -{ -size_t max; -size_t left; -size_t right; -uint32_t tmp1, tmp2; - -while (TRUE) - { - max = i; - left = (i << 1) + 2; - right = left + 2; - - if (left < size && buffer[left] > buffer[max]) max = left; - if (right < size && buffer[right] > buffer[max]) max = right; - if (i == max) return; - - /* Swap items. */ - tmp1 = buffer[i]; - tmp2 = buffer[i + 1]; - buffer[i] = buffer[max]; - buffer[i + 1] = buffer[max + 1]; - buffer[max] = tmp1; - buffer[max + 1] = tmp2; - i = max; - } -} - -#ifdef SUPPORT_UNICODE - -#define PARSE_CLASS_UTF 0x1 -#define PARSE_CLASS_CASELESS_UTF 0x2 -#define PARSE_CLASS_RESTRICTED_UTF 0x4 -#define PARSE_CLASS_TURKISH_UTF 0x8 - -/* Get the range of nocase characters which includes the -'c' character passed as argument, or directly follows 'c'. */ - -static const uint32_t* -get_nocase_range(uint32_t c) -{ -uint32_t left = 0; -uint32_t right = PRIV(ucd_nocase_ranges_size); -uint32_t middle; - -if (c > MAX_UTF_CODE_POINT) return PRIV(ucd_nocase_ranges) + right; - -while (TRUE) - { - /* Range end of the middle element. */ - middle = ((left + right) >> 1) | 0x1; - - if (PRIV(ucd_nocase_ranges)[middle] <= c) - left = middle + 1; - else if (middle > 1 && PRIV(ucd_nocase_ranges)[middle - 2] > c) - right = middle - 1; - else - return PRIV(ucd_nocase_ranges) + (middle - 1); - } -} - -/* Get the list of othercase characters, which belongs to the passed range. -Create ranges from these characters, and append them to the buffer argument. */ - -static size_t -utf_caseless_extend(uint32_t start, uint32_t end, uint32_t options, - uint32_t *buffer) -{ -uint32_t new_start = start; -uint32_t new_end = end; -uint32_t c = start; -const uint32_t *list; -uint32_t tmp[3]; -size_t result = 2; -const uint32_t *skip_range = get_nocase_range(c); -uint32_t skip_start = skip_range[0]; - -#if PCRE2_CODE_UNIT_WIDTH == 8 -PCRE2_ASSERT(options & PARSE_CLASS_UTF); -#endif - -#if PCRE2_CODE_UNIT_WIDTH == 32 -if (end > MAX_UTF_CODE_POINT) end = MAX_UTF_CODE_POINT; -#endif - -while (c <= end) - { - uint32_t co; - - if (c > skip_start) - { - c = skip_range[1]; - skip_range += 2; - skip_start = skip_range[0]; - continue; - } - - /* Compute caseless set. */ - - if ((options & (PARSE_CLASS_TURKISH_UTF|PARSE_CLASS_RESTRICTED_UTF)) == - PARSE_CLASS_TURKISH_UTF && - UCD_ANY_I(c)) - { - co = PRIV(ucd_turkish_dotted_i_caseset) + (UCD_DOTTED_I(c)? 0 : 3); - } - else if ((co = UCD_CASESET(c)) != 0 && - (options & PARSE_CLASS_RESTRICTED_UTF) != 0 && - PRIV(ucd_caseless_sets)[co] < 128) - { - co = 0; /* Ignore the caseless set if it's restricted. */ - } - - if (co != 0) - list = PRIV(ucd_caseless_sets) + co; - else - { - co = UCD_OTHERCASE(c); - list = tmp; - tmp[0] = c; - tmp[1] = NOTACHAR; - - if (co != c) - { - tmp[1] = co; - tmp[2] = NOTACHAR; - } - } - c++; - - /* Add characters. */ - do - { -#if PCRE2_CODE_UNIT_WIDTH == 16 - if (!(options & PARSE_CLASS_UTF) && *list > 0xffff) continue; -#endif - - if (*list < new_start) - { - if (*list + 1 == new_start) - { - new_start--; - continue; - } - } - else if (*list > new_end) - { - if (*list - 1 == new_end) - { - new_end++; - continue; - } - } - else continue; - - result += 2; - if (buffer != NULL) - { - buffer[0] = *list; - buffer[1] = *list; - buffer += 2; - } - } - while (*(++list) != NOTACHAR); - } - - if (buffer != NULL) - { - buffer[0] = new_start; - buffer[1] = new_end; - buffer += 2; - (void)buffer; - } - return result; -} - -#endif - -/* Add a character list to a buffer. */ - -static size_t -append_char_list(const uint32_t *p, uint32_t *buffer) -{ -const uint32_t *n; -size_t result = 0; - -while (*p != NOTACHAR) - { - n = p; - while (n[0] == n[1] - 1) n++; - - PCRE2_ASSERT(*p < 0xffff); - - if (buffer != NULL) - { - buffer[0] = *p; - buffer[1] = *n; - buffer += 2; - } - - result += 2; - p = n + 1; - } - - return result; -} - -static uint32_t -get_highest_char(uint32_t options) -{ -(void)options; /* Avoid compiler warning. */ - -#if PCRE2_CODE_UNIT_WIDTH == 8 -return MAX_UTF_CODE_POINT; -#else -#ifdef SUPPORT_UNICODE -return GET_MAX_CHAR_VALUE((options & PARSE_CLASS_UTF) != 0); -#else -return MAX_UCHAR_VALUE; -#endif -#endif -} - -/* Add a negated character list to a buffer. */ -static size_t -append_negated_char_list(const uint32_t *p, uint32_t options, uint32_t *buffer) -{ -const uint32_t *n; -uint32_t start = 0; -size_t result = 2; - -PCRE2_ASSERT(*p > 0); - -while (*p != NOTACHAR) - { - n = p; - while (n[0] == n[1] - 1) n++; - - PCRE2_ASSERT(*p < 0xffff); - - if (buffer != NULL) - { - buffer[0] = start; - buffer[1] = *p - 1; - buffer += 2; - } - - result += 2; - start = *n + 1; - p = n + 1; - } - - if (buffer != NULL) - { - buffer[0] = start; - buffer[1] = get_highest_char(options); - buffer += 2; - (void)buffer; - } - - return result; -} - -static uint32_t * -append_non_ascii_range(uint32_t options, uint32_t *buffer) -{ - if (buffer == NULL) return NULL; - - buffer[0] = 0x100; - buffer[1] = get_highest_char(options); - return buffer + 2; -} - -static size_t -parse_class(uint32_t *ptr, uint32_t options, uint32_t *buffer) -{ -size_t total_size = 0; -size_t size; -uint32_t meta_arg; -uint32_t start_char; - -while (TRUE) - { - switch (META_CODE(*ptr)) - { - case META_ESCAPE: - meta_arg = META_DATA(*ptr); - switch (meta_arg) - { - case ESC_D: - case ESC_W: - case ESC_S: - buffer = append_non_ascii_range(options, buffer); - total_size += 2; - break; - - case ESC_h: - size = append_char_list(PRIV(hspace_list), buffer); - total_size += size; - if (buffer != NULL) buffer += size; - break; - - case ESC_H: - size = append_negated_char_list(PRIV(hspace_list), options, buffer); - total_size += size; - if (buffer != NULL) buffer += size; - break; - - case ESC_v: - size = append_char_list(PRIV(vspace_list), buffer); - total_size += size; - if (buffer != NULL) buffer += size; - break; - - case ESC_V: - size = append_negated_char_list(PRIV(vspace_list), options, buffer); - total_size += size; - if (buffer != NULL) buffer += size; - break; - - case ESC_p: - case ESC_P: - ptr++; - if (meta_arg == ESC_p && (*ptr >> 16) == PT_ANY) - { - if (buffer != NULL) - { - buffer[0] = 0; - buffer[1] = get_highest_char(options); - buffer += 2; - } - total_size += 2; - } - break; - } - ptr++; - continue; - case META_POSIX_NEG: - buffer = append_non_ascii_range(options, buffer); - total_size += 2; - ptr += 2; - continue; - case META_POSIX: - ptr += 2; - continue; - case META_BIGVALUE: - /* Character literal */ - ptr++; - break; - CLASS_END_CASES(*ptr) - if (*ptr >= META_END) return total_size; - break; - } - - start_char = *ptr; - - if (ptr[1] == META_RANGE_LITERAL || ptr[1] == META_RANGE_ESCAPED) - { - ptr += 2; - PCRE2_ASSERT(*ptr < META_END || *ptr == META_BIGVALUE); - - if (*ptr == META_BIGVALUE) ptr++; - -#ifdef EBCDIC -#error "Missing EBCDIC support" -#endif - } - -#ifdef SUPPORT_UNICODE - if (options & PARSE_CLASS_CASELESS_UTF) - { - size = utf_caseless_extend(start_char, *ptr++, options, buffer); - if (buffer != NULL) buffer += size; - total_size += size; - continue; - } -#endif - - if (buffer != NULL) - { - buffer[0] = start_char; - buffer[1] = *ptr; - buffer += 2; - } - - ptr++; - total_size += 2; - } - - return total_size; -} - -/* Extra uint32_t values for storing the lengths of range lists in -the worst case. Two uint32_t lengths and a range end for a range -starting before 255 */ -#define CHAR_LIST_EXTRA_SIZE 3 - -/* Starting character values for each character list. */ - -static const uint32_t char_list_starts[] = { -#if PCRE2_CODE_UNIT_WIDTH == 32 - XCL_CHAR_LIST_HIGH_32_START, -#endif -#if PCRE2_CODE_UNIT_WIDTH == 32 || defined SUPPORT_UNICODE - XCL_CHAR_LIST_LOW_32_START, -#endif - XCL_CHAR_LIST_HIGH_16_START, - /* Must be terminated by XCL_CHAR_LIST_LOW_16_START, - which also represents the end of the bitset. */ - XCL_CHAR_LIST_LOW_16_START, -}; - -static class_ranges * -compile_optimize_class(uint32_t *start_ptr, uint32_t options, - uint32_t xoptions, compile_block *cb) -{ -class_ranges* cranges; -uint32_t *ptr; -uint32_t *buffer; -uint32_t *dst; -uint32_t class_options = 0; -size_t range_list_size = 0, total_size, i; -uint32_t tmp1, tmp2; -const uint32_t *char_list_next; -uint16_t *next_char; -uint32_t char_list_start, char_list_end; -uint32_t range_start, range_end; - -#ifdef SUPPORT_UNICODE -if (options & PCRE2_UTF) - class_options |= PARSE_CLASS_UTF; - -if ((options & PCRE2_CASELESS) && (options & (PCRE2_UTF|PCRE2_UCP))) - class_options |= PARSE_CLASS_CASELESS_UTF; - -if (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) - class_options |= PARSE_CLASS_RESTRICTED_UTF; - -if (xoptions & PCRE2_EXTRA_TURKISH_CASING) - class_options |= PARSE_CLASS_TURKISH_UTF; -#endif - -/* Compute required space for the range. */ - -range_list_size = parse_class(start_ptr, class_options, NULL); -PCRE2_ASSERT((range_list_size & 0x1) == 0); - -/* Allocate buffer. The total_size also represents the end of the buffer. */ - -total_size = range_list_size + - ((range_list_size >= 2) ? CHAR_LIST_EXTRA_SIZE : 0); - -cranges = cb->cx->memctl.malloc( - sizeof(class_ranges) + total_size * sizeof(uint32_t), - cb->cx->memctl.memory_data); - -if (cranges == NULL) return NULL; - -cranges->next = NULL; -cranges->range_list_size = (uint16_t)range_list_size; -cranges->char_lists_types = 0; -cranges->char_lists_size = 0; -cranges->char_lists_start = 0; - -if (range_list_size == 0) return cranges; - -buffer = (uint32_t*)(cranges + 1); -parse_class(start_ptr, class_options, buffer); - -/* Using <= instead of == to help static analysis. */ -if (range_list_size <= 2) return cranges; - -/* In-place sorting of ranges. */ - -i = (((range_list_size >> 2) - 1) << 1); -while (TRUE) - { - do_heapify(buffer, range_list_size, i); - if (i == 0) break; - i -= 2; - } - -i = range_list_size - 2; -while (TRUE) - { - tmp1 = buffer[i]; - tmp2 = buffer[i + 1]; - buffer[i] = buffer[0]; - buffer[i + 1] = buffer[1]; - buffer[0] = tmp1; - buffer[1] = tmp2; - - do_heapify(buffer, i, 0); - if (i == 0) break; - i -= 2; - } - -/* Merge ranges whenever possible. */ -dst = buffer; -ptr = buffer + 2; -range_list_size -= 2; - -/* The second condition is a very rare corner case, where the end of the last -range is the maximum character. This range cannot be extended further. */ - -while (range_list_size > 0 && dst[1] != ~(uint32_t)0) - { - if (dst[1] + 1 < ptr[0]) - { - dst += 2; - dst[0] = ptr[0]; - dst[1] = ptr[1]; - } - else if (dst[1] < ptr[1]) dst[1] = ptr[1]; - - ptr += 2; - range_list_size -= 2; - } - -PCRE2_ASSERT(dst[1] <= get_highest_char(class_options)); - -/* When the number of ranges are less than six, -they are not converted to range lists. */ - -ptr = buffer; -while (ptr < dst && ptr[1] < 0x100) ptr += 2; -if (dst - ptr < (2 * (6 - 1))) - { - cranges->range_list_size = (uint16_t)(dst + 2 - buffer); - return cranges; - } - -/* Compute character lists structures. */ - -char_list_next = char_list_starts; -char_list_start = *char_list_next++; -#if PCRE2_CODE_UNIT_WIDTH == 32 -char_list_end = XCL_CHAR_LIST_HIGH_32_END; -#elif defined SUPPORT_UNICODE -char_list_end = XCL_CHAR_LIST_LOW_32_END; -#else -char_list_end = XCL_CHAR_LIST_HIGH_16_END; -#endif -next_char = (uint16_t*)(buffer + total_size); - -tmp1 = 0; -tmp2 = ((sizeof(char_list_starts) / sizeof(uint32_t)) - 1) * XCL_TYPE_BIT_LEN; -PCRE2_ASSERT(tmp2 <= 3 * XCL_TYPE_BIT_LEN && tmp2 >= XCL_TYPE_BIT_LEN); -range_start = dst[0]; -range_end = dst[1]; - -while (TRUE) - { - if (range_start >= char_list_start) - { - if (range_start == range_end || range_end < char_list_end) - { - tmp1++; - next_char--; - - if (char_list_start < XCL_CHAR_LIST_LOW_32_START) - *next_char = (uint16_t)((range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END); - else - *(uint32_t*)(--next_char) = - (range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END; - } - - if (range_start < range_end) - { - if (range_start > char_list_start) - { - tmp1++; - next_char--; - - if (char_list_start < XCL_CHAR_LIST_LOW_32_START) - *next_char = (uint16_t)(range_start << XCL_CHAR_SHIFT); - else - *(uint32_t*)(--next_char) = (range_start << XCL_CHAR_SHIFT); - } - else - cranges->char_lists_types |= XCL_BEGIN_WITH_RANGE << tmp2; - } - - PCRE2_ASSERT((uint32_t*)next_char >= dst + 2); - - if (dst > buffer) - { - dst -= 2; - range_start = dst[0]; - range_end = dst[1]; - continue; - } - - range_start = 0; - range_end = 0; - } - - if (range_end >= char_list_start) - { - PCRE2_ASSERT(range_start < char_list_start); - - if (range_end < char_list_end) - { - tmp1++; - next_char--; - - if (char_list_start < XCL_CHAR_LIST_LOW_32_START) - *next_char = (uint16_t)((range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END); - else - *(uint32_t*)(--next_char) = - (range_end << XCL_CHAR_SHIFT) | XCL_CHAR_END; - - PCRE2_ASSERT((uint32_t*)next_char >= dst + 2); - } - - cranges->char_lists_types |= XCL_BEGIN_WITH_RANGE << tmp2; - } - - if (tmp1 >= XCL_ITEM_COUNT_MASK) - { - cranges->char_lists_types |= XCL_ITEM_COUNT_MASK << tmp2; - next_char--; - - if (char_list_start < XCL_CHAR_LIST_LOW_32_START) - *next_char = (uint16_t)tmp1; - else - *(uint32_t*)(--next_char) = tmp1; - } - else - cranges->char_lists_types |= tmp1 << tmp2; - - if (range_start < XCL_CHAR_LIST_LOW_16_START) break; - - PCRE2_ASSERT(tmp2 >= XCL_TYPE_BIT_LEN); - char_list_end = char_list_start - 1; - char_list_start = *char_list_next++; - tmp1 = 0; - tmp2 -= XCL_TYPE_BIT_LEN; - } - -if (dst[0] < XCL_CHAR_LIST_LOW_16_START) dst += 2; -PCRE2_ASSERT((uint16_t*)dst <= next_char); - -cranges->char_lists_size = - (size_t)((uint8_t*)(buffer + total_size) - (uint8_t*)next_char); -cranges->char_lists_start = (size_t)((uint8_t*)next_char - (uint8_t*)buffer); -cranges->range_list_size = (uint16_t)(dst - buffer); -return cranges; -} - -#endif /* SUPPORT_WIDE_CHARS */ - -#ifdef SUPPORT_UNICODE - -void PRIV(update_classbits)(uint32_t ptype, uint32_t pdata, BOOL negated, - uint8_t *classbits) -{ -/* Update PRIV(xclass) when this function is changed. */ -int c, chartype; -const ucd_record *prop; -uint32_t gentype; -BOOL set_bit; - -if (ptype == PT_ANY) - { - if (!negated) memset(classbits, 0xff, 32); - return; - } - -for (c = 0; c < 256; c++) - { - prop = GET_UCD(c); - set_bit = FALSE; - (void)set_bit; - - switch (ptype) - { - case PT_LAMP: - chartype = prop->chartype; - set_bit = (chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt); - break; - - case PT_GC: - set_bit = (PRIV(ucp_gentype)[prop->chartype] == pdata); - break; - - case PT_PC: - set_bit = (prop->chartype == pdata); - break; - - case PT_SC: - set_bit = (prop->script == pdata); - break; - - case PT_SCX: - set_bit = (prop->script == pdata || - MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), pdata) != 0); - break; - - case PT_ALNUM: - gentype = PRIV(ucp_gentype)[prop->chartype]; - set_bit = (gentype == ucp_L || gentype == ucp_N); - break; - - case PT_SPACE: /* Perl space */ - case PT_PXSPACE: /* POSIX space */ - switch(c) - { - HSPACE_BYTE_CASES: - VSPACE_BYTE_CASES: - set_bit = TRUE; - break; - - default: - set_bit = (PRIV(ucp_gentype)[prop->chartype] == ucp_Z); - break; - } - break; - - case PT_WORD: - chartype = prop->chartype; - gentype = PRIV(ucp_gentype)[chartype]; - set_bit = (gentype == ucp_L || gentype == ucp_N || - chartype == ucp_Mn || chartype == ucp_Pc); - break; - - case PT_UCNC: - set_bit = (c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || - c == CHAR_GRAVE_ACCENT || c >= 0xa0); - break; - - case PT_BIDICL: - set_bit = (UCD_BIDICLASS_PROP(prop) == pdata); - break; - - case PT_BOOL: - set_bit = MAPBIT(PRIV(ucd_boolprop_sets) + - UCD_BPROPS_PROP(prop), pdata) != 0; - break; - - case PT_PXGRAPH: - chartype = prop->chartype; - gentype = PRIV(ucp_gentype)[chartype]; - set_bit = (gentype != ucp_Z && (gentype != ucp_C || chartype == ucp_Cf)); - break; - - case PT_PXPRINT: - chartype = prop->chartype; - set_bit = (chartype != ucp_Zl && chartype != ucp_Zp && - (PRIV(ucp_gentype)[chartype] != ucp_C || chartype == ucp_Cf)); - break; - - case PT_PXPUNCT: - gentype = PRIV(ucp_gentype)[prop->chartype]; - set_bit = (gentype == ucp_P || (c < 128 && gentype == ucp_S)); - break; - - default: - PCRE2_ASSERT(ptype == PT_PXXDIGIT); - set_bit = (c >= CHAR_0 && c <= CHAR_9) || - (c >= CHAR_A && c <= CHAR_F) || - (c >= CHAR_a && c <= CHAR_f); - break; - } - - if (negated) set_bit = !set_bit; - if (set_bit) *classbits |= (uint8_t)(1 << (c & 0x7)); - if ((c & 0x7) == 0x7) classbits++; - } -} - -#endif /* SUPPORT_UNICODE */ - - - -#ifdef SUPPORT_WIDE_CHARS - -/************************************************* -* XClass related properties * -*************************************************/ - -/* XClass needs to be generated. */ -#define XCLASS_REQUIRED 0x1 -/* XClass has 8 bit character. */ -#define XCLASS_HAS_8BIT_CHARS 0x2 -/* XClass has properties. */ -#define XCLASS_HAS_PROPS 0x4 -/* XClass has character lists. */ -#define XCLASS_HAS_CHAR_LISTS 0x8 -/* XClass matches to all >= 256 characters. */ -#define XCLASS_HIGH_ANY 0x10 - -#endif - - -/************************************************* -* Internal entry point for add range to class * -*************************************************/ - -/* This function sets the overall range for characters < 256. -It also handles non-utf case folding. - -Arguments: - options the options bits - xoptions the extra options bits - cb compile data - start start of range character - end end of range character - -Returns: cb->classbits is updated -*/ - -static void -add_to_class(uint32_t options, uint32_t xoptions, compile_block *cb, - uint32_t start, uint32_t end) -{ -uint8_t *classbits = cb->classbits.classbits; -uint32_t c, byte_start, byte_end; -uint32_t classbits_end = (end <= 0xff ? end : 0xff); - -/* If caseless matching is required, scan the range and process alternate -cases. In Unicode, there are 8-bit characters that have alternate cases that -are greater than 255 and vice-versa (though these may be ignored if caseless -restriction is in force). Sometimes we can just extend the original range. */ - -if ((options & PCRE2_CASELESS) != 0) - { -#ifdef SUPPORT_UNICODE - /* UTF mode. This branch is taken if we don't support wide characters (e.g. - 8-bit library, without UTF), but we do treat those characters as Unicode - (if UCP flag is set). In this case, we only need to expand the character class - set to include the case pairs which are in the 0-255 codepoint range. */ - if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0) - { - BOOL turkish_i = (xoptions & (PCRE2_EXTRA_TURKISH_CASING|PCRE2_EXTRA_CASELESS_RESTRICT)) == - PCRE2_EXTRA_TURKISH_CASING; - if (start < 128) - { - uint32_t lo_end = (classbits_end < 127 ? classbits_end : 127); - for (c = start; c <= lo_end; c++) - { - if (turkish_i && UCD_ANY_I(c)) continue; - SETBIT(classbits, cb->fcc[c]); - } - } - if (classbits_end >= 128) - { - uint32_t hi_start = (start > 128 ? start : 128); - for (c = hi_start; c <= classbits_end; c++) - { - uint32_t co = UCD_OTHERCASE(c); - if (co <= 0xff) SETBIT(classbits, co); - } - } - } - - else -#endif /* SUPPORT_UNICODE */ - - /* Not UTF mode */ - { - for (c = start; c <= classbits_end; c++) - SETBIT(classbits, cb->fcc[c]); - } - } - -/* Use the bitmap for characters < 256. Otherwise use extra data. */ - -byte_start = (start + 7) >> 3; -byte_end = (classbits_end + 1) >> 3; - -if (byte_start >= byte_end) - { - for (c = start; c <= classbits_end; c++) - /* Regardless of start, c will always be <= 255. */ - SETBIT(classbits, c); - return; - } - -for (c = byte_start; c < byte_end; c++) - classbits[c] = 0xff; - -byte_start <<= 3; -byte_end <<= 3; - -for (c = start; c < byte_start; c++) - SETBIT(classbits, c); - -for (c = byte_end; c <= classbits_end; c++) - SETBIT(classbits, c); -} - - -#if PCRE2_CODE_UNIT_WIDTH == 8 -/************************************************* -* Internal entry point for add list to class * -*************************************************/ - -/* This function is used for adding a list of horizontal or vertical whitespace -characters to a class. The list must be in order so that ranges of characters -can be detected and handled appropriately. This function sets the overall range -so that the internal functions can try to avoid duplication when handling -case-independence. - -Arguments: - options the options bits - xoptions the extra options bits - cb contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - -Returns: cb->classbits is updated -*/ - -static void -add_list_to_class(uint32_t options, uint32_t xoptions, compile_block *cb, - const uint32_t *p) -{ -while (p[0] < 256) - { - unsigned int n = 0; - - while(p[n+1] == p[0] + n + 1) n++; - add_to_class(options, xoptions, cb, p[0], p[n]); - - p += n + 1; - } -} - - - -/************************************************* -* Add characters not in a list to a class * -*************************************************/ - -/* This function is used for adding the complement of a list of horizontal or -vertical whitespace to a class. The list must be in order. - -Arguments: - options the options bits - xoptions the extra options bits - cb contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - -Returns: cb->classbits is updated -*/ - -static void -add_not_list_to_class(uint32_t options, uint32_t xoptions, compile_block *cb, - const uint32_t *p) -{ -if (p[0] > 0) - add_to_class(options, xoptions, cb, 0, p[0] - 1); -while (p[0] < 256) - { - while (p[1] == p[0] + 1) p++; - add_to_class(options, xoptions, cb, p[0] + 1, (p[1] > 255) ? 255 : p[1] - 1); - p++; - } -} -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - - - -/************************************************* -* Main entry-point to compile a character class * -*************************************************/ - -/* This function consumes a "leaf", which is a set of characters that will -become a single OP_CLASS OP_NCLASS, OP_XCLASS, or OP_ALLANY. */ - -uint32_t * -PRIV(compile_class_not_nested)(uint32_t options, uint32_t xoptions, - uint32_t *start_ptr, PCRE2_UCHAR **pcode, BOOL negate_class, BOOL* has_bitmap, - int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr) -{ -uint32_t *pptr = start_ptr; -PCRE2_UCHAR *code = *pcode; -BOOL should_flip_negation; -const uint8_t *cbits = cb->cbits; -/* Some functions such as add_to_class() or eclass processing -expects that the bitset is stored in cb->classbits.classbits. */ -uint8_t *const classbits = cb->classbits.classbits; - -#ifdef SUPPORT_UNICODE -BOOL utf = (options & PCRE2_UTF) != 0; -#else /* No Unicode support */ -BOOL utf = FALSE; -#endif - -/* Helper variables for OP_XCLASS opcode (for characters > 255). */ - -#ifdef SUPPORT_WIDE_CHARS -uint32_t xclass_props; -PCRE2_UCHAR *class_uchardata; -class_ranges* cranges; -#endif - -/* If an XClass contains a negative special such as \S, we need to flip the -negation flag at the end, so that support for characters > 255 works correctly -(they are all included in the class). An XClass may need to insert specific -matching or non-matching code for wide characters. -*/ - -should_flip_negation = FALSE; - -/* XClass will be used when characters > 255 might match. */ - -#ifdef SUPPORT_WIDE_CHARS -xclass_props = 0; - -#if PCRE2_CODE_UNIT_WIDTH == 8 -cranges = NULL; - -if (utf) -#endif - { - if (lengthptr != NULL) - { - cranges = compile_optimize_class(pptr, options, xoptions, cb); - - if (cranges == NULL) - { - *errorcodeptr = ERR21; - return NULL; - } - - /* Caching the pre-processed character ranges. */ - if (cb->next_cranges != NULL) - cb->next_cranges->next = cranges; - else - cb->cranges = cranges; - - cb->next_cranges = cranges; - } - else - { - /* Reuse the pre-processed character ranges. */ - cranges = cb->cranges; - PCRE2_ASSERT(cranges != NULL); - cb->cranges = cranges->next; - } - - if (cranges->range_list_size > 0) - { - const uint32_t *ranges = (const uint32_t*)(cranges + 1); - - if (ranges[0] <= 255) - xclass_props |= XCLASS_HAS_8BIT_CHARS; - - if (ranges[cranges->range_list_size - 1] == GET_MAX_CHAR_VALUE(utf) && - ranges[cranges->range_list_size - 2] <= 256) - xclass_props |= XCLASS_HIGH_ANY; - } - } - -class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ -#endif /* SUPPORT_WIDE_CHARS */ - -/* Initialize the 256-bit (32-byte) bit map to all zeros. We build the map -in a temporary bit of memory, in case the class contains fewer than two -8-bit characters because in that case the compiled code doesn't use the bit -map. */ - -memset(classbits, 0, 32); - -/* Process items until end_ptr is reached. */ - -while (TRUE) - { - uint32_t meta = *(pptr++); - BOOL local_negate; - int posix_class; - int taboffset, tabopt; - class_bits_storage pbits; - uint32_t escape, c; - - /* Handle POSIX classes such as [:alpha:] etc. */ - switch (META_CODE(meta)) - { - case META_POSIX: - case META_POSIX_NEG: - - local_negate = (meta == META_POSIX_NEG); - posix_class = *(pptr++); - - if (local_negate) should_flip_negation = TRUE; /* Note negative special */ - - /* If matching is caseless, upper and lower are converted to alpha. - This relies on the fact that the class table starts with alpha, - lower, upper as the first 3 entries. */ - - if ((options & PCRE2_CASELESS) != 0 && posix_class <= 2) - posix_class = 0; - - /* When PCRE2_UCP is set, some of the POSIX classes are converted to - different escape sequences that use Unicode properties \p or \P. - Others that are not available via \p or \P have to generate - XCL_PROP/XCL_NOTPROP directly, which is done here. */ - -#ifdef SUPPORT_UNICODE - /* TODO This entire block of code here appears to be unreachable!? I simply - can't see how it can be hit, given that the frontend parser doesn't emit - META_POSIX for GRAPH/PRINT/PUNCT when UCP is set. */ - if ((options & PCRE2_UCP) != 0 && - (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0) - { - uint32_t ptype; - - switch(posix_class) - { - case PC_GRAPH: - case PC_PRINT: - case PC_PUNCT: - ptype = (posix_class == PC_GRAPH)? PT_PXGRAPH : - (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT; - - PRIV(update_classbits)(ptype, 0, local_negate, classbits); - - if ((xclass_props & XCLASS_HIGH_ANY) == 0) - { - if (lengthptr != NULL) - *lengthptr += 3; - else - { - *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; - *class_uchardata++ = (PCRE2_UCHAR)ptype; - *class_uchardata++ = 0; - } - xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_PROPS; - } - continue; - - /* For the other POSIX classes (ex: ascii) we are going to - fall through to the non-UCP case and build a bit map for - characters with code points less than 256. However, if we are in - a negated POSIX class, characters with code points greater than - 255 must either all match or all not match, depending on whether - the whole class is not or is negated. For example, for - [[:^ascii:]... they must all match, whereas for [^[:^ascii:]... - they must not. - - In the special case where there are no xclass items, this is - automatically handled by the use of OP_CLASS or OP_NCLASS, but an - explicit range is needed for OP_XCLASS. Setting a flag here - causes the range to be generated later when it is known that - OP_XCLASS is required. In the 8-bit library this is relevant only in - utf mode, since no wide characters can exist otherwise. */ - - default: - break; - } - } -#endif /* SUPPORT_UNICODE */ - - /* In the non-UCP case, or when UCP makes no difference, we build the - bit map for the POSIX class in a chunk of local store because we may - be adding and subtracting from it, and we don't want to subtract bits - that may be in the main map already. At the end we or the result into - the bit map that is being built. */ - - posix_class *= 3; - - /* Copy in the first table (always present) */ - - memcpy(pbits.classbits, cbits + PRIV(posix_class_maps)[posix_class], 32); - - /* If there is a second table, add or remove it as required. */ - - taboffset = PRIV(posix_class_maps)[posix_class + 1]; - tabopt = PRIV(posix_class_maps)[posix_class + 2]; - - if (taboffset >= 0) - { - if (tabopt >= 0) - for (int i = 0; i < 32; i++) - pbits.classbits[i] |= cbits[i + taboffset]; - else - for (int i = 0; i < 32; i++) - pbits.classbits[i] &= (uint8_t)(~cbits[i + taboffset]); - } - - /* Now see if we need to remove any special characters. An option - value of 1 removes vertical space and 2 removes underscore. */ - - if (tabopt < 0) tabopt = -tabopt; - if (tabopt == 1) pbits.classbits[1] &= ~0x3c; - else if (tabopt == 2) pbits.classbits[11] &= 0x7f; - - /* Add the POSIX table or its complement into the main table that is - being built and we are done. */ - - { - uint32_t *classwords = cb->classbits.classwords; - - if (local_negate) - for (int i = 0; i < 8; i++) - classwords[i] |= (uint32_t)(~pbits.classwords[i]); - else - for (int i = 0; i < 8; i++) - classwords[i] |= pbits.classwords[i]; - } - -#ifdef SUPPORT_WIDE_CHARS - /* Every class contains at least one < 256 character. */ - xclass_props |= XCLASS_HAS_8BIT_CHARS; -#endif - continue; /* End of POSIX handling */ - - /* Other than POSIX classes, the only items we should encounter are - \d-type escapes and literal characters (possibly as ranges). */ - case META_BIGVALUE: - meta = *(pptr++); - break; - - case META_ESCAPE: - escape = META_DATA(meta); - - switch(escape) - { - case ESC_d: - for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_digit]; - break; - - case ESC_D: - should_flip_negation = TRUE; - for (int i = 0; i < 32; i++) - classbits[i] |= (uint8_t)(~cbits[i+cbit_digit]); - break; - - case ESC_w: - for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_word]; - break; - - case ESC_W: - should_flip_negation = TRUE; - for (int i = 0; i < 32; i++) - classbits[i] |= (uint8_t)(~cbits[i+cbit_word]); - break; - - /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl - 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was - previously set by something earlier in the character class. - Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so - we could just adjust the appropriate bit. From PCRE 8.34 we no - longer treat \s and \S specially. */ - - case ESC_s: - for (int i = 0; i < 32; i++) classbits[i] |= cbits[i+cbit_space]; - break; - - case ESC_S: - should_flip_negation = TRUE; - for (int i = 0; i < 32; i++) - classbits[i] |= (uint8_t)(~cbits[i+cbit_space]); - break; - - /* When adding the horizontal or vertical space lists to a class, or - their complements, disable PCRE2_CASELESS, because it justs wastes - time, and in the "not-x" UTF cases can create unwanted duplicates in - the XCLASS list (provoked by characters that have more than one other - case and by both cases being in the same "not-x" sublist). */ - - case ESC_h: -#if PCRE2_CODE_UNIT_WIDTH == 8 -#ifdef SUPPORT_UNICODE - if (cranges != NULL) break; -#endif - add_list_to_class(options & ~PCRE2_CASELESS, xoptions, - cb, PRIV(hspace_list)); -#else - PCRE2_ASSERT(cranges != NULL); -#endif - break; - - case ESC_H: -#if PCRE2_CODE_UNIT_WIDTH == 8 -#ifdef SUPPORT_UNICODE - if (cranges != NULL) break; -#endif - add_not_list_to_class(options & ~PCRE2_CASELESS, xoptions, - cb, PRIV(hspace_list)); -#else - PCRE2_ASSERT(cranges != NULL); -#endif - break; - - case ESC_v: -#if PCRE2_CODE_UNIT_WIDTH == 8 -#ifdef SUPPORT_UNICODE - if (cranges != NULL) break; -#endif - add_list_to_class(options & ~PCRE2_CASELESS, xoptions, - cb, PRIV(vspace_list)); -#else - PCRE2_ASSERT(cranges != NULL); -#endif - break; - - case ESC_V: -#if PCRE2_CODE_UNIT_WIDTH == 8 -#ifdef SUPPORT_UNICODE - if (cranges != NULL) break; -#endif - add_not_list_to_class(options & ~PCRE2_CASELESS, xoptions, - cb, PRIV(vspace_list)); -#else - PCRE2_ASSERT(cranges != NULL); -#endif - break; - - /* If Unicode is not supported, \P and \p are not allowed and are - faulted at parse time, so will never appear here. */ - -#ifdef SUPPORT_UNICODE - case ESC_p: - case ESC_P: - { - uint32_t ptype = *pptr >> 16; - uint32_t pdata = *(pptr++) & 0xffff; - - /* The "Any" is processed by PRIV(update_classbits)(). */ - if (ptype == PT_ANY) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (!utf && escape == ESC_p) memset(classbits, 0xff, 32); -#endif - continue; - } - - PRIV(update_classbits)(ptype, pdata, (escape == ESC_P), classbits); - - if ((xclass_props & XCLASS_HIGH_ANY) == 0) - { - if (lengthptr != NULL) - *lengthptr += 3; - else - { - *class_uchardata++ = (escape == ESC_p)? XCL_PROP : XCL_NOTPROP; - *class_uchardata++ = ptype; - *class_uchardata++ = pdata; - } - xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_PROPS; - } - } - continue; -#endif - } - -#ifdef SUPPORT_WIDE_CHARS - /* Every non-property class contains at least one < 256 character. */ - xclass_props |= XCLASS_HAS_8BIT_CHARS; -#endif - /* End handling \d-type escapes */ - continue; - - CLASS_END_CASES(meta) - /* Literals. */ - if (meta < META_END) break; - /* Non-literals: end of class contents. */ - goto END_PROCESSING; - } - - /* A literal character may be followed by a range meta. At parse time - there are checks for out-of-order characters, for ranges where the two - characters are equal, and for hyphens that cannot indicate a range. At - this point, therefore, no checking is needed. */ - - c = meta; - - /* Remember if \r or \n were explicitly used */ - - if (c == CHAR_CR || c == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; - - /* Process a character range */ - - if (*pptr == META_RANGE_LITERAL || *pptr == META_RANGE_ESCAPED) - { - uint32_t d; - -#ifdef EBCDIC - BOOL range_is_literal = (*pptr == META_RANGE_LITERAL); -#endif - ++pptr; - d = *(pptr++); - if (d == META_BIGVALUE) d = *(pptr++); - - /* Remember an explicit \r or \n, and add the range to the class. */ - - if (d == CHAR_CR || d == CHAR_NL) cb->external_flags |= PCRE2_HASCRORLF; - -#if PCRE2_CODE_UNIT_WIDTH == 8 -#ifdef SUPPORT_UNICODE - if (cranges != NULL) continue; - xclass_props |= XCLASS_HAS_8BIT_CHARS; -#endif - - /* In an EBCDIC environment, Perl treats alphabetic ranges specially - because there are holes in the encoding, and simply using the range - A-Z (for example) would include the characters in the holes. This - applies only to literal ranges; [\xC1-\xE9] is different to [A-Z]. */ - -#ifdef EBCDIC - if (range_is_literal && - (cb->ctypes[c] & ctype_letter) != 0 && - (cb->ctypes[d] & ctype_letter) != 0 && - (c <= CHAR_z) == (d <= CHAR_z)) - { - uint32_t uc = (d <= CHAR_z)? 0 : 64; - uint32_t C = c - uc; - uint32_t D = d - uc; - - if (C <= CHAR_i) - { - add_to_class(options, xoptions, cb, C + uc, - ((D < CHAR_i)? D : CHAR_i) + uc); - C = CHAR_j; - } - - if (C <= D && C <= CHAR_r) - { - add_to_class(options, xoptions, cb, C + uc, - ((D < CHAR_r)? D : CHAR_r) + uc); - C = CHAR_s; - } - - if (C <= D) - add_to_class(options, xoptions, cb, C + uc, D + uc); - } - else -#endif - /* Not an EBCDIC special range */ - - add_to_class(options, xoptions, cb, c, d); -#else - PCRE2_ASSERT(cranges != NULL); -#endif - continue; - } /* End of range handling */ - - /* Character ranges are ignored when class_ranges is present. */ -#if PCRE2_CODE_UNIT_WIDTH == 8 -#ifdef SUPPORT_UNICODE - if (cranges != NULL) continue; - xclass_props |= XCLASS_HAS_8BIT_CHARS; -#endif - /* Handle a single character. */ - - add_to_class(options, xoptions, cb, meta, meta); -#else - PCRE2_ASSERT(cranges != NULL); -#endif - } /* End of main class-processing loop */ - -END_PROCESSING: - -#ifdef SUPPORT_WIDE_CHARS -PCRE2_ASSERT((xclass_props & XCLASS_HAS_PROPS) == 0 || - (xclass_props & XCLASS_HIGH_ANY) == 0); - -if (cranges != NULL) - { - uint32_t *range = (uint32_t*)(cranges + 1); - uint32_t *end = range + cranges->range_list_size; - - while (range < end && range[0] < 256) - { - PCRE2_ASSERT((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0); - /* Add range to bitset. If we are in UTF or UCP mode, then clear the - caseless bit, because the cranges handle caselessness (only) in this - condition; see the condition for PARSE_CLASS_CASELESS_UTF in - compile_optimize_class(). */ - add_to_class(((options & (PCRE2_UTF|PCRE2_UCP)) != 0)? - (options & ~PCRE2_CASELESS) : options, xoptions, cb, range[0], range[1]); - - if (range[1] > 255) break; - range += 2; - } - - if (cranges->char_lists_size > 0) - { - /* The cranges structure is still used and freed later. */ - PCRE2_ASSERT((xclass_props & XCLASS_HIGH_ANY) == 0); - xclass_props |= XCLASS_REQUIRED | XCLASS_HAS_CHAR_LISTS; - } - else - { - if ((xclass_props & XCLASS_HIGH_ANY) != 0) - { - PCRE2_ASSERT(range + 2 == end && range[0] <= 256 && - range[1] >= GET_MAX_CHAR_VALUE(utf)); - should_flip_negation = TRUE; - range = end; - } - - while (range < end) - { - uint32_t range_start = range[0]; - uint32_t range_end = range[1]; - - range += 2; - xclass_props |= XCLASS_REQUIRED; - - if (range_start < 256) range_start = 256; - - if (lengthptr != NULL) - { -#ifdef SUPPORT_UNICODE - if (utf) - { - *lengthptr += 1; - - if (range_start < range_end) - *lengthptr += PRIV(ord2utf)(range_start, class_uchardata); - - *lengthptr += PRIV(ord2utf)(range_end, class_uchardata); - continue; - } -#endif /* SUPPORT_UNICODE */ - - *lengthptr += range_start < range_end ? 3 : 2; - continue; - } - -#ifdef SUPPORT_UNICODE - if (utf) - { - if (range_start < range_end) - { - *class_uchardata++ = XCL_RANGE; - class_uchardata += PRIV(ord2utf)(range_start, class_uchardata); - } - else - *class_uchardata++ = XCL_SINGLE; - - class_uchardata += PRIV(ord2utf)(range_end, class_uchardata); - continue; - } -#endif /* SUPPORT_UNICODE */ - - /* Without UTF support, character values are constrained - by the bit length, and can only be > 256 for 16-bit and - 32-bit libraries. */ -#if PCRE2_CODE_UNIT_WIDTH != 8 - if (range_start < range_end) - { - *class_uchardata++ = XCL_RANGE; - *class_uchardata++ = range_start; - } - else - *class_uchardata++ = XCL_SINGLE; - - *class_uchardata++ = range_end; -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - } - - if (lengthptr == NULL) - cb->cx->memctl.free(cranges, cb->cx->memctl.memory_data); - } - } -#endif /* SUPPORT_WIDE_CHARS */ - -/* If there are characters with values > 255, or Unicode property settings -(\p or \P), we have to compile an extended class, with its own opcode, -unless there were no property settings and there was a negated special such -as \S in the class, and PCRE2_UCP is not set, because in that case all -characters > 255 are in or not in the class, so any that were explicitly -given as well can be ignored. - -In the UCP case, if certain negated POSIX classes (ex: [:^ascii:]) were -were present in a class, we either have to match or not match all wide -characters (depending on whether the whole class is or is not negated). -This requirement is indicated by match_all_or_no_wide_chars being true. -We do this by including an explicit range, which works in both cases. -This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there -cannot be any wide characters in 8-bit non-UTF mode. - -When there *are* properties in a positive UTF-8 or any 16-bit or 32_bit -class where \S etc is present without PCRE2_UCP, causing an extended class -to be compiled, we make sure that all characters > 255 are included by -forcing match_all_or_no_wide_chars to be true. - -If, when generating an xclass, there are no characters < 256, we can omit -the bitmap in the actual compiled code. */ - -#ifdef SUPPORT_WIDE_CHARS /* Defined for 16/32 bits, or 8-bit with Unicode */ -if ((xclass_props & XCLASS_REQUIRED) != 0) - { - PCRE2_UCHAR *previous = code; - - if ((xclass_props & XCLASS_HAS_CHAR_LISTS) == 0) - *class_uchardata++ = XCL_END; /* Marks the end of extra data */ - *code++ = OP_XCLASS; - code += LINK_SIZE; - *code = negate_class? XCL_NOT:0; - if ((xclass_props & XCLASS_HAS_PROPS) != 0) *code |= XCL_HASPROP; - - /* If the map is required, move up the extra data to make room for it; - otherwise just move the code pointer to the end of the extra data. */ - - if ((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0 || has_bitmap != NULL) - { - if (negate_class) - { - uint32_t *classwords = cb->classbits.classwords; - for (int i = 0; i < 8; i++) classwords[i] = ~classwords[i]; - } - - if (has_bitmap == NULL) - { - *code++ |= XCL_MAP; - (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, - CU2BYTES(class_uchardata - code)); - memcpy(code, classbits, 32); - code = class_uchardata + (32 / sizeof(PCRE2_UCHAR)); - } - else - { - code = class_uchardata; - if ((xclass_props & XCLASS_HAS_8BIT_CHARS) != 0) - *has_bitmap = TRUE; - } - } - else code = class_uchardata; - - if ((xclass_props & XCLASS_HAS_CHAR_LISTS) != 0) - { - /* Char lists size is an even number, because all items are 16 or 32 - bit values. The character list data is always aligned to 32 bits. */ - size_t char_lists_size = cranges->char_lists_size; - PCRE2_ASSERT((char_lists_size & 0x1) == 0 && - (cb->char_lists_size & 0x3) == 0); - - if (lengthptr != NULL) - { - char_lists_size = CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t)); - -#if PCRE2_CODE_UNIT_WIDTH == 8 - *lengthptr += 2 + LINK_SIZE; -#else - *lengthptr += 1 + LINK_SIZE; -#endif - - cb->char_lists_size += char_lists_size; - - char_lists_size /= sizeof(PCRE2_UCHAR); - - /* Storage space for character lists is included - in the maximum pattern size. */ - if (*lengthptr > MAX_PATTERN_SIZE || - MAX_PATTERN_SIZE - *lengthptr < char_lists_size) - { - *errorcodeptr = ERR20; /* Pattern is too large */ - return NULL; - } - } - else - { - uint8_t *data; - - PCRE2_ASSERT(cranges->char_lists_types <= XCL_TYPE_MASK); -#if PCRE2_CODE_UNIT_WIDTH == 8 - /* Encode as high / low bytes. */ - code[0] = (uint8_t)(XCL_LIST | - (cranges->char_lists_types >> 8)); - code[1] = (uint8_t)cranges->char_lists_types; - code += 2; -#else - *code++ = (PCRE2_UCHAR)(XCL_LIST | cranges->char_lists_types); -#endif - - /* Character lists are stored in backwards direction from - byte code start. The non-dfa/dfa matchers can access these - lists using the byte code start stored in match blocks. - Each list is aligned to 32 bit with an optional unused - 16 bit value at the beginning of the character list. */ - - cb->char_lists_size += char_lists_size; - data = (uint8_t*)cb->start_code - cb->char_lists_size; - - memcpy(data, (uint8_t*)(cranges + 1) + cranges->char_lists_start, - char_lists_size); - - /* Since character lists total size is less than MAX_PATTERN_SIZE, - their starting offset fits into a value which size is LINK_SIZE. */ - - char_lists_size = cb->char_lists_size; - PUT(code, 0, (uint32_t)(char_lists_size >> 1)); - code += LINK_SIZE; - -#if defined PCRE2_DEBUG || defined SUPPORT_VALGRIND - if ((char_lists_size & 0x2) != 0) - { - /* In debug the unused 16 bit value is set - to a fixed value and marked unused. */ - ((uint16_t*)data)[-1] = 0x5555; -#ifdef SUPPORT_VALGRIND - VALGRIND_MAKE_MEM_NOACCESS(data - 2, 2); -#endif - } -#endif - - cb->char_lists_size = - CLIST_ALIGN_TO(char_lists_size, sizeof(uint32_t)); - - cb->cx->memctl.free(cranges, cb->cx->memctl.memory_data); - } - } - - /* Now fill in the complete length of the item */ - - PUT(previous, 1, (int)(code - previous)); - goto DONE; /* End of class handling */ - } -#endif /* SUPPORT_WIDE_CHARS */ - -/* If there are no characters > 255, or they are all to be included or -excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the -whole class was negated and whether there were negative specials such as \S -(non-UCP) in the class. Then copy the 32-byte map into the code vector, -negating it if necessary. */ - -if (negate_class) - { - uint32_t *classwords = cb->classbits.classwords; - - for (int i = 0; i < 8; i++) classwords[i] = ~classwords[i]; - } - -if ((SELECT_VALUE8(!utf, 0) || negate_class != should_flip_negation) && - cb->classbits.classwords[0] == ~(uint32_t)0) - { - const uint32_t *classwords = cb->classbits.classwords; - int i; - - for (i = 0; i < 8; i++) - if (classwords[i] != ~(uint32_t)0) break; - - if (i == 8) - { - *code++ = OP_ALLANY; - goto DONE; /* End of class handling */ - } - } - -*code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS; -memcpy(code, classbits, 32); -code += 32 / sizeof(PCRE2_UCHAR); - -DONE: -*pcode = code; -return pptr - 1; -} - - - -/* ===================================================================*/ -/* Here follows a block of ECLASS-compiling functions. You may well want to -read them from top to bottom; they are ordered from leafmost (at the top) to -outermost parser (at the bottom of the file). */ - -/* This function folds one operand using the negation operator. -The new, combined chunk of stack code is written out to *pop_info. */ - -static void -fold_negation(eclass_op_info *pop_info, PCRE2_SIZE *lengthptr, - BOOL preserve_classbits) -{ -/* If the chunk of stack code is already composed of multiple ops, we won't -descend in and try and propagate the negation down the tree. (That would lead -to O(n^2) compile-time, which could be exploitable with a malicious regex - -although maybe that's not really too much of a worry in a library that offers -an exponential-time matching function!) */ - -if (pop_info->op_single_type == 0) - { - if (lengthptr != NULL) - *lengthptr += 1; - else - pop_info->code_start[pop_info->length] = ECL_NOT; - pop_info->length += 1; - } - -/* Otherwise, it's a nice single-op item, so we can easily fold in the negation -without needing to produce an ECL_NOT. */ - -else if (pop_info->op_single_type == ECL_ANY || - pop_info->op_single_type == ECL_NONE) - { - pop_info->op_single_type = (pop_info->op_single_type == ECL_NONE)? - ECL_ANY : ECL_NONE; - if (lengthptr == NULL) - *(pop_info->code_start) = pop_info->op_single_type; - } -else - { - PCRE2_ASSERT(pop_info->op_single_type == ECL_XCLASS && - pop_info->length >= 1 + LINK_SIZE + 1); - if (lengthptr == NULL) - pop_info->code_start[1 + LINK_SIZE] ^= XCL_NOT; - } - -if (!preserve_classbits) - { - for (int i = 0; i < 8; i++) - pop_info->bits.classwords[i] = ~pop_info->bits.classwords[i]; - } -} - - - -/* This function folds together two operands using a binary operator. -The new, combined chunk of stack code is written out to *lhs_op_info. */ - -static void -fold_binary(int op, eclass_op_info *lhs_op_info, eclass_op_info *rhs_op_info, - PCRE2_SIZE *lengthptr) -{ -switch (op) - { - /* ECL_AND truth table: - - LHS RHS RESULT - ---------------- - ANY * RHS - * ANY LHS - NONE * NONE - * NONE NONE - X Y X & Y - */ - - case ECL_AND: - if (rhs_op_info->op_single_type == ECL_ANY) - { - /* no-op: drop the RHS */ - } - else if (lhs_op_info->op_single_type == ECL_ANY) - { - /* no-op: drop the LHS, and memmove the RHS into its place */ - if (lengthptr == NULL) - memmove(lhs_op_info->code_start, rhs_op_info->code_start, - CU2BYTES(rhs_op_info->length)); - lhs_op_info->length = rhs_op_info->length; - lhs_op_info->op_single_type = rhs_op_info->op_single_type; - } - else if (rhs_op_info->op_single_type == ECL_NONE) - { - /* the result is ECL_NONE: write into the LHS */ - if (lengthptr == NULL) - lhs_op_info->code_start[0] = ECL_NONE; - lhs_op_info->length = 1; - lhs_op_info->op_single_type = ECL_NONE; - } - else if (lhs_op_info->op_single_type == ECL_NONE) - { - /* the result is ECL_NONE: drop the RHS */ - } - else - { - /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */ - if (lengthptr != NULL) - *lengthptr += 1; - else - { - PCRE2_ASSERT(rhs_op_info->code_start == - lhs_op_info->code_start + lhs_op_info->length); - rhs_op_info->code_start[rhs_op_info->length] = ECL_AND; - } - lhs_op_info->length += rhs_op_info->length + 1; - lhs_op_info->op_single_type = 0; - } - - for (int i = 0; i < 8; i++) - lhs_op_info->bits.classwords[i] &= rhs_op_info->bits.classwords[i]; - break; - - /* ECL_OR truth table: - - LHS RHS RESULT - ---------------- - ANY * ANY - * ANY ANY - NONE * RHS - * NONE LHS - X Y X | Y - */ - - case ECL_OR: - if (rhs_op_info->op_single_type == ECL_NONE) - { - /* no-op: drop the RHS */ - } - else if (lhs_op_info->op_single_type == ECL_NONE) - { - /* no-op: drop the LHS, and memmove the RHS into its place */ - if (lengthptr == NULL) - memmove(lhs_op_info->code_start, rhs_op_info->code_start, - CU2BYTES(rhs_op_info->length)); - lhs_op_info->length = rhs_op_info->length; - lhs_op_info->op_single_type = rhs_op_info->op_single_type; - } - else if (rhs_op_info->op_single_type == ECL_ANY) - { - /* the result is ECL_ANY: write into the LHS */ - if (lengthptr == NULL) - lhs_op_info->code_start[0] = ECL_ANY; - lhs_op_info->length = 1; - lhs_op_info->op_single_type = ECL_ANY; - } - else if (lhs_op_info->op_single_type == ECL_ANY) - { - /* the result is ECL_ANY: drop the RHS */ - } - else - { - /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */ - if (lengthptr != NULL) - *lengthptr += 1; - else - { - PCRE2_ASSERT(rhs_op_info->code_start == - lhs_op_info->code_start + lhs_op_info->length); - rhs_op_info->code_start[rhs_op_info->length] = ECL_OR; - } - lhs_op_info->length += rhs_op_info->length + 1; - lhs_op_info->op_single_type = 0; - } - - for (int i = 0; i < 8; i++) - lhs_op_info->bits.classwords[i] |= rhs_op_info->bits.classwords[i]; - break; - - /* ECL_XOR truth table: - - LHS RHS RESULT - ---------------- - ANY * !RHS - * ANY !LHS - NONE * RHS - * NONE LHS - X Y X ^ Y - */ - - case ECL_XOR: - if (rhs_op_info->op_single_type == ECL_NONE) - { - /* no-op: drop the RHS */ - } - else if (lhs_op_info->op_single_type == ECL_NONE) - { - /* no-op: drop the LHS, and memmove the RHS into its place */ - if (lengthptr == NULL) - memmove(lhs_op_info->code_start, rhs_op_info->code_start, - CU2BYTES(rhs_op_info->length)); - lhs_op_info->length = rhs_op_info->length; - lhs_op_info->op_single_type = rhs_op_info->op_single_type; - } - else if (rhs_op_info->op_single_type == ECL_ANY) - { - /* the result is !LHS: fold in the negation, and drop the RHS */ - /* Preserve the classbits, because we promise to deal with them later. */ - fold_negation(lhs_op_info, lengthptr, TRUE); - } - else if (lhs_op_info->op_single_type == ECL_ANY) - { - /* the result is !RHS: drop the LHS, memmove the RHS into its place, and - fold in the negation */ - if (lengthptr == NULL) - memmove(lhs_op_info->code_start, rhs_op_info->code_start, - CU2BYTES(rhs_op_info->length)); - lhs_op_info->length = rhs_op_info->length; - lhs_op_info->op_single_type = rhs_op_info->op_single_type; - - /* Preserve the classbits, because we promise to deal with them later. */ - fold_negation(lhs_op_info, lengthptr, TRUE); - } - else - { - /* Both of LHS & RHS are either ECL_XCLASS, or compound operations. */ - if (lengthptr != NULL) - *lengthptr += 1; - else - { - PCRE2_ASSERT(rhs_op_info->code_start == - lhs_op_info->code_start + lhs_op_info->length); - rhs_op_info->code_start[rhs_op_info->length] = ECL_XOR; - } - lhs_op_info->length += rhs_op_info->length + 1; - lhs_op_info->op_single_type = 0; - } - - for (int i = 0; i < 8; i++) - lhs_op_info->bits.classwords[i] ^= rhs_op_info->bits.classwords[i]; - break; - - default: - PCRE2_DEBUG_UNREACHABLE(); - break; - } -} - - - -static BOOL -compile_eclass_nested(eclass_context *context, BOOL negated, - uint32_t **pptr, PCRE2_UCHAR **pcode, - eclass_op_info *pop_info, PCRE2_SIZE *lengthptr); - -/* This function consumes a group of implicitly-unioned class elements. -These can be characters, ranges, properties, or nested classes, as long -as they are all joined by being placed adjacently. */ - -static BOOL -compile_class_operand(eclass_context *context, BOOL negated, - uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, - PCRE2_SIZE *lengthptr) -{ -uint32_t *ptr = *pptr; -uint32_t *prev_ptr; -PCRE2_UCHAR *code = *pcode; -PCRE2_UCHAR *code_start = code; -PCRE2_SIZE prev_length = (lengthptr != NULL)? *lengthptr : 0; -PCRE2_SIZE extra_length; -uint32_t meta = META_CODE(*ptr); - -switch (meta) - { - case META_CLASS_EMPTY_NOT: - case META_CLASS_EMPTY: - ++ptr; - pop_info->length = 1; - if ((meta == META_CLASS_EMPTY) == negated) - { - *code++ = pop_info->op_single_type = ECL_ANY; - memset(pop_info->bits.classbits, 0xff, 32); - } - else - { - *code++ = pop_info->op_single_type = ECL_NONE; - memset(pop_info->bits.classbits, 0, 32); - } - break; - - case META_CLASS: - case META_CLASS_NOT: - if ((*ptr & CLASS_IS_ECLASS) != 0) - { - if (!compile_eclass_nested(context, negated, &ptr, &code, - pop_info, lengthptr)) - return FALSE; - - PCRE2_ASSERT(*ptr == META_CLASS_END); - ptr++; - goto DONE; - } - - ptr++; - /* Fall through */ - - default: - /* Scan forward characters, ranges, and properties. - For example: inside [a-z_ -- m] we don't have brackets around "a-z_" but - we still need to collect that fragment up into a "leaf" OP_CLASS. */ - - prev_ptr = ptr; - ptr = PRIV(compile_class_not_nested)( - context->options, context->xoptions, ptr, &code, - (meta != META_CLASS_NOT) == negated, &context->needs_bitmap, - context->errorcodeptr, context->cb, lengthptr); - if (ptr == NULL) return FALSE; - - /* We must have a 100% guarantee that ptr increases when - compile_class_operand() returns, even on Release builds, so that we can - statically prove our loops terminate. */ - if (ptr <= prev_ptr) - { - PCRE2_DEBUG_UNREACHABLE(); - return FALSE; - } - - /* If we fell through above, consume the closing ']'. */ - if (meta == META_CLASS || meta == META_CLASS_NOT) - { - PCRE2_ASSERT(*ptr == META_CLASS_END); - ptr++; - } - - /* Regardless of whether (lengthptr == NULL), some data will still be written - out to *pcode, which we need: we have to peek at it, to transform the opcode - into the ECLASS version (since we need to hoist up the bitmaps). */ - PCRE2_ASSERT(code > code_start); - extra_length = (lengthptr != NULL)? *lengthptr - prev_length : 0; - - /* Easiest case: convert OP_ALLANY to ECL_ANY */ - - if (*code_start == OP_ALLANY) - { - PCRE2_ASSERT(code - code_start == 1 && extra_length == 0); - pop_info->length = 1; - *code_start = pop_info->op_single_type = ECL_ANY; - memset(pop_info->bits.classbits, 0xff, 32); - } - - /* For OP_CLASS and OP_NCLASS, we hoist out the bitmap and convert to - ECL_NONE / ECL_ANY respectively. */ - - else if (*code_start == OP_CLASS || *code_start == OP_NCLASS) - { - PCRE2_ASSERT(code - code_start == 1 + 32 / sizeof(PCRE2_UCHAR) && - extra_length == 0); - pop_info->length = 1; - *code_start = pop_info->op_single_type = - (*code_start == OP_CLASS)? ECL_NONE : ECL_ANY; - memcpy(pop_info->bits.classbits, code_start + 1, 32); - /* Rewind the code pointer, but make sure we adjust *lengthptr, because we - do need to reserve that space (even though we only use it temporarily). */ - if (lengthptr != NULL) - *lengthptr += code - (code_start + 1); - code = code_start + 1; - - if (!context->needs_bitmap && *code_start == ECL_NONE) - { - uint32_t *classwords = pop_info->bits.classwords; - - for (int i = 0; i < 8; i++) - if (classwords[i] != 0) - { - context->needs_bitmap = TRUE; - break; - } - } - else - context->needs_bitmap = TRUE; - } - - /* Finally, for OP_XCLASS we hoist out the bitmap (if any), and convert to - ECL_XCLASS. */ - - else - { - PCRE2_ASSERT(*code_start == OP_XCLASS); - *code_start = pop_info->op_single_type = ECL_XCLASS; - - PCRE2_ASSERT(code - code_start >= 1 + LINK_SIZE + 1); - - memcpy(pop_info->bits.classbits, context->cb->classbits.classbits, 32); - pop_info->length = (code - code_start) + extra_length; - } - - break; - } /* End of switch(meta) */ - -pop_info->code_start = (lengthptr == NULL)? code_start : NULL; - -if (lengthptr != NULL) - { - *lengthptr += code - code_start; - code = code_start; - } - -DONE: -PCRE2_ASSERT(lengthptr == NULL || (code == code_start)); - -*pptr = ptr; -*pcode = code; -return TRUE; -} - - - -/* This function consumes a group of implicitly-unioned class elements. -These can be characters, ranges, properties, or nested classes, as long -as they are all joined by being placed adjacently. */ - -static BOOL -compile_class_juxtaposition(eclass_context *context, BOOL negated, - uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, - PCRE2_SIZE *lengthptr) -{ -uint32_t *ptr = *pptr; -PCRE2_UCHAR *code = *pcode; -#ifdef PCRE2_DEBUG -PCRE2_UCHAR *start_code = *pcode; -#endif - -/* See compile_class_binary_loose() for comments on compile-time folding of -the "negated" flag. */ - -/* Because it's a non-empty class, there must be an operand at the start. */ -if (!compile_class_operand(context, negated, &ptr, &code, pop_info, lengthptr)) - return FALSE; - -while (*ptr != META_CLASS_END && - !(*ptr >= META_ECLASS_AND && *ptr <= META_ECLASS_NOT)) - { - uint32_t op; - BOOL rhs_negated; - eclass_op_info rhs_op_info; - - if (negated) - { - /* !(A juxtapose B) -> !A && !B */ - op = ECL_AND; - rhs_negated = TRUE; - } - else - { - /* A juxtapose B -> A || B */ - op = ECL_OR; - rhs_negated = FALSE; - } - - /* An operand must follow the operator. */ - if (!compile_class_operand(context, rhs_negated, &ptr, &code, - &rhs_op_info, lengthptr)) - return FALSE; - - /* Convert infix to postfix (RPN). */ - fold_binary(op, pop_info, &rhs_op_info, lengthptr); - if (lengthptr == NULL) - code = pop_info->code_start + pop_info->length; - } - -PCRE2_ASSERT(lengthptr == NULL || code == start_code); - -*pptr = ptr; -*pcode = code; -return TRUE; -} - - - -/* This function consumes unary prefix operators. */ - -static BOOL -compile_class_unary(eclass_context *context, BOOL negated, - uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, - PCRE2_SIZE *lengthptr) -{ -uint32_t *ptr = *pptr; -#ifdef PCRE2_DEBUG -PCRE2_UCHAR *start_code = *pcode; -#endif - -while (*ptr == META_ECLASS_NOT) - { - ++ptr; - negated = !negated; - } - -*pptr = ptr; -/* Because it's a non-empty class, there must be an operand. */ -if (!compile_class_juxtaposition(context, negated, pptr, pcode, - pop_info, lengthptr)) - return FALSE; - -PCRE2_ASSERT(lengthptr == NULL || *pcode == start_code); -return TRUE; -} - - - -/* This function consumes tightly-binding binary operators. */ - -static BOOL -compile_class_binary_tight(eclass_context *context, BOOL negated, - uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, - PCRE2_SIZE *lengthptr) -{ -uint32_t *ptr = *pptr; -PCRE2_UCHAR *code = *pcode; -#ifdef PCRE2_DEBUG -PCRE2_UCHAR *start_code = *pcode; -#endif - -/* See compile_class_binary_loose() for comments on compile-time folding of -the "negated" flag. */ - -/* Because it's a non-empty class, there must be an operand at the start. */ -if (!compile_class_unary(context, negated, &ptr, &code, pop_info, lengthptr)) - return FALSE; - -while (*ptr == META_ECLASS_AND) - { - uint32_t op; - BOOL rhs_negated; - eclass_op_info rhs_op_info; - - if (negated) - { - /* !(A && B) -> !A || !B */ - op = ECL_OR; - rhs_negated = TRUE; - } - else - { - /* A && B -> A && B */ - op = ECL_AND; - rhs_negated = FALSE; - } - - ++ptr; - - /* An operand must follow the operator. */ - if (!compile_class_unary(context, rhs_negated, &ptr, &code, - &rhs_op_info, lengthptr)) - return FALSE; - - /* Convert infix to postfix (RPN). */ - fold_binary(op, pop_info, &rhs_op_info, lengthptr); - if (lengthptr == NULL) - code = pop_info->code_start + pop_info->length; - } - -PCRE2_ASSERT(lengthptr == NULL || code == start_code); - -*pptr = ptr; -*pcode = code; -return TRUE; -} - - - -/* This function consumes loosely-binding binary operators. */ - -static BOOL -compile_class_binary_loose(eclass_context *context, BOOL negated, - uint32_t **pptr, PCRE2_UCHAR **pcode, eclass_op_info *pop_info, - PCRE2_SIZE *lengthptr) -{ -uint32_t *ptr = *pptr; -PCRE2_UCHAR *code = *pcode; -#ifdef PCRE2_DEBUG -PCRE2_UCHAR *start_code = *pcode; -#endif - -/* We really want to fold the negation operator, if at all possible, so that -simple cases can be reduced down. In particular, in 8-bit no-UTF mode, we want -to produce a fully-folded expression, so that we can guarantee not to emit any -OP_ECLASS codes (in the same way that we never emit OP_XCLASS in this mode). - -This has the consequence that with a little ingenuity, we can in fact avoid -emitting (nearly...) all cases of the "NOT" operator. Imagine that we have: - !(A ... -We have parsed the preceding "!", and we are about to parse the "A" operand. We -don't know yet whether there will even be a following binary operand! Both of -these are possibilities for what follows: - !(A && B) - !(A) -However, we can still fold the "!" into the "A" operand, because no matter what -the following binary operator will be, we can produce an expression which is -equivalent. */ - -/* Because it's a non-empty class, there must be an operand at the start. */ -if (!compile_class_binary_tight(context, negated, &ptr, &code, - pop_info, lengthptr)) - return FALSE; - -while (*ptr >= META_ECLASS_OR && *ptr <= META_ECLASS_XOR) - { - uint32_t op; - BOOL op_neg; - BOOL rhs_negated; - eclass_op_info rhs_op_info; - - if (negated) - { - /* The whole expression is being negated; we respond by unconditionally - negating the LHS A, before seeing what follows. And hooray! We can recover, - no matter what follows. */ - /* !(A || B) -> !A && !B */ - /* !(A -- B) -> !(A && !B) -> !A || B */ - /* !(A XOR B) -> !(!A XOR !B) -> !A XNOR !B */ - op = (*ptr == META_ECLASS_OR )? ECL_AND : - (*ptr == META_ECLASS_SUB)? ECL_OR : - /*ptr == META_ECLASS_XOR*/ ECL_XOR; - op_neg = (*ptr == META_ECLASS_XOR); - rhs_negated = *ptr != META_ECLASS_SUB; - } - else - { - /* A || B -> A || B */ - /* A -- B -> A && !B */ - /* A XOR B -> A XOR B */ - op = (*ptr == META_ECLASS_OR )? ECL_OR : - (*ptr == META_ECLASS_SUB)? ECL_AND : - /*ptr == META_ECLASS_XOR*/ ECL_XOR; - op_neg = FALSE; - rhs_negated = *ptr == META_ECLASS_SUB; - } - - ++ptr; - - /* An operand must follow the operator. */ - if (!compile_class_binary_tight(context, rhs_negated, &ptr, &code, - &rhs_op_info, lengthptr)) - return FALSE; - - /* Convert infix to postfix (RPN). */ - fold_binary(op, pop_info, &rhs_op_info, lengthptr); - if (op_neg) fold_negation(pop_info, lengthptr, FALSE); - if (lengthptr == NULL) - code = pop_info->code_start + pop_info->length; - } - -PCRE2_ASSERT(lengthptr == NULL || code == start_code); - -*pptr = ptr; -*pcode = code; -return TRUE; -} - - - -/* This function converts the META codes in pptr into opcodes written to -pcode. The pptr must start at a META_CLASS or META_CLASS_NOT. - -The class is compiled as a left-associative sequence of operator -applications. - -The pptr will be left pointing at the matching META_CLASS_END. */ - -static BOOL -compile_eclass_nested(eclass_context *context, BOOL negated, - uint32_t **pptr, PCRE2_UCHAR **pcode, - eclass_op_info *pop_info, PCRE2_SIZE *lengthptr) -{ -uint32_t *ptr = *pptr; -#ifdef PCRE2_DEBUG -PCRE2_UCHAR *start_code = *pcode; -#endif - -/* The CLASS_IS_ECLASS bit must be set since it is a nested class. */ -PCRE2_ASSERT(*ptr == (META_CLASS | CLASS_IS_ECLASS) || - *ptr == (META_CLASS_NOT | CLASS_IS_ECLASS)); - -if (*ptr++ == (META_CLASS_NOT | CLASS_IS_ECLASS)) - negated = !negated; - -(*pptr)++; - -/* Because it's a non-empty class, there must be an operand at the start. */ -if (!compile_class_binary_loose(context, negated, pptr, pcode, - pop_info, lengthptr)) - return FALSE; - -PCRE2_ASSERT(**pptr == META_CLASS_END); -PCRE2_ASSERT(lengthptr == NULL || *pcode == start_code); -return TRUE; -} - -BOOL -PRIV(compile_class_nested)(uint32_t options, uint32_t xoptions, - uint32_t **pptr, PCRE2_UCHAR **pcode, int *errorcodeptr, - compile_block *cb, PCRE2_SIZE *lengthptr) -{ -eclass_context context; -eclass_op_info op_info; -PCRE2_SIZE previous_length = (lengthptr != NULL)? *lengthptr : 0; -PCRE2_UCHAR *code = *pcode; -PCRE2_UCHAR *previous; -BOOL allbitsone = TRUE; - -context.needs_bitmap = FALSE; -context.options = options; -context.xoptions = xoptions; -context.errorcodeptr = errorcodeptr; -context.cb = cb; - -previous = code; -*code++ = OP_ECLASS; -code += LINK_SIZE; -*code++ = 0; /* Flags, currently zero. */ -if (!compile_eclass_nested(&context, FALSE, pptr, &code, &op_info, lengthptr)) - return FALSE; - -if (lengthptr != NULL) - { - *lengthptr += code - previous; - code = previous; - /* (*lengthptr - previous_length) now holds the amount of buffer that - we require to make the call to compile_class_nested() with - lengthptr = NULL, and including the (1+LINK_SIZE+1) that we write out - before that call. */ - } - -/* Do some useful counting of what's in the bitmap. */ -for (int i = 0; i < 8; i++) - if (op_info.bits.classwords[i] != 0xffffffff) - { - allbitsone = FALSE; - break; - } - -/* After constant-folding the extended class syntax, it may turn out to be -a simple class after all. In that case, we can unwrap it from the -OP_ECLASS container - and in fact, we must do so, because in 8-bit -no-Unicode mode the matcher is compiled without support for OP_ECLASS. */ - -#ifndef SUPPORT_WIDE_CHARS -PCRE2_ASSERT(op_info.op_single_type != 0); -#else -if (op_info.op_single_type != 0) -#endif - { - /* Rewind back over the OP_ECLASS. */ - code = previous; - - /* If the bits are all ones, and the "high characters" are all matched - too, we use a special-cased encoding of OP_ALLANY. */ - - if (op_info.op_single_type == ECL_ANY && allbitsone) - { - /* Advancing code means rewinding lengthptr, at this point. */ - if (lengthptr != NULL) *lengthptr -= 1; - *code++ = OP_ALLANY; - } - - /* If the high bits are all matched / all not-matched, then we emit an - OP_NCLASS/OP_CLASS respectively. */ - - else if (op_info.op_single_type == ECL_ANY || - op_info.op_single_type == ECL_NONE) - { - PCRE2_SIZE required_len = 1 + (32 / sizeof(PCRE2_UCHAR)); - - if (lengthptr != NULL) - { - if (required_len > (*lengthptr - previous_length)) - *lengthptr = previous_length + required_len; - } - - /* Advancing code means rewinding lengthptr, at this point. */ - if (lengthptr != NULL) *lengthptr -= required_len; - *code++ = (op_info.op_single_type == ECL_ANY)? OP_NCLASS : OP_CLASS; - memcpy(code, op_info.bits.classbits, 32); - code += 32 / sizeof(PCRE2_UCHAR); - } - - /* Otherwise, we have an ECL_XCLASS, so we have the OP_XCLASS data - there, but, we pulled out its bitmap into op_info, so now we have to - put that back into the OP_XCLASS. */ - - else - { -#ifndef SUPPORT_WIDE_CHARS - PCRE2_DEBUG_UNREACHABLE(); -#else - BOOL need_map = context.needs_bitmap; - PCRE2_SIZE required_len; - - PCRE2_ASSERT(op_info.op_single_type == ECL_XCLASS); - required_len = op_info.length + (need_map? 32/sizeof(PCRE2_UCHAR) : 0); - - if (lengthptr != NULL) - { - /* Don't unconditionally request all the space we need - we may - already have asked for more during processing of the ECLASS. */ - if (required_len > (*lengthptr - previous_length)) - *lengthptr = previous_length + required_len; - - /* The code we write out here won't be ignored, even during the - (lengthptr != NULL) phase, because if there's a following quantifier - it will peek backwards. So we do have to write out a (truncated) - OP_XCLASS, even on this branch. */ - *lengthptr -= 1 + LINK_SIZE + 1; - *code++ = OP_XCLASS; - PUT(code, 0, 1 + LINK_SIZE + 1); - code += LINK_SIZE; - *code++ = 0; - } - else - { - PCRE2_UCHAR *rest; - PCRE2_SIZE rest_len; - PCRE2_UCHAR flags; - - /* 1 unit: OP_XCLASS | LINK_SIZE units | 1 unit: flags | ...rest */ - PCRE2_ASSERT(op_info.length >= 1 + LINK_SIZE + 1); - rest = op_info.code_start + 1 + LINK_SIZE + 1; - rest_len = (op_info.code_start + op_info.length) - rest; - - /* First read any data we use, before memmove splats it. */ - flags = op_info.code_start[1 + LINK_SIZE]; - PCRE2_ASSERT((flags & XCL_MAP) == 0); - - /* Next do the memmove before any writes. */ - memmove(code + 1 + LINK_SIZE + 1 + (need_map? 32/sizeof(PCRE2_UCHAR) : 0), - rest, CU2BYTES(rest_len)); - - /* Finally write the header data. */ - *code++ = OP_XCLASS; - PUT(code, 0, (int)required_len); - code += LINK_SIZE; - *code++ = flags | (need_map? XCL_MAP : 0); - if (need_map) - { - memcpy(code, op_info.bits.classbits, 32); - code += 32 / sizeof(PCRE2_UCHAR); - } - code += rest_len; - } -#endif /* SUPPORT_WIDE_CHARS */ - } - } - -/* Otherwise, we're going to keep the OP_ECLASS. However, again we need -to do some adjustment to insert the bitmap if we have one. */ - -#ifdef SUPPORT_WIDE_CHARS -else - { - BOOL need_map = context.needs_bitmap; - PCRE2_SIZE required_len = - 1 + LINK_SIZE + 1 + (need_map? 32/sizeof(PCRE2_UCHAR) : 0) + op_info.length; - - if (lengthptr != NULL) - { - if (required_len > (*lengthptr - previous_length)) - *lengthptr = previous_length + required_len; - - /* As for the XCLASS branch above, we do have to write out a dummy - OP_ECLASS, because of the backwards peek by the quantifier code. Write - out a (truncated) OP_ECLASS, even on this branch. */ - *lengthptr -= 1 + LINK_SIZE + 1; - *code++ = OP_ECLASS; - PUT(code, 0, 1 + LINK_SIZE + 1); - code += LINK_SIZE; - *code++ = 0; - } - else - { - if (need_map) - { - PCRE2_UCHAR *map_start = previous + 1 + LINK_SIZE + 1; - previous[1 + LINK_SIZE] |= ECL_MAP; - memmove(map_start + 32/sizeof(PCRE2_UCHAR), map_start, - CU2BYTES(code - map_start)); - memcpy(map_start, op_info.bits.classbits, 32); - code += 32 / sizeof(PCRE2_UCHAR); - } - PUT(previous, 1, (int)(code - previous)); - } - } -#endif /* SUPPORT_WIDE_CHARS */ - -*pcode = code; -return TRUE; -} - -/* End of pcre2_compile_class.c */ diff --git a/ext/pcre/pcre2lib/pcre2_config.c b/ext/pcre/pcre2lib/pcre2_config.c index 031981b09bfe..5ef103caf792 100644 --- a/ext/pcre/pcre2lib/pcre2_config.c +++ b/ext/pcre/pcre2lib/pcre2_config.c @@ -224,8 +224,8 @@ switch (what) XSTRING when PCRE2_PRERELEASE is not empty, an unwanted space is inserted. There are problems using an "obvious" approach like this: - XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE2_MINOR) - XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE2_DATE) + XSTRING(PCRE2_MAJOR) "." XSTRING(PCRE_MINOR) + XSTRING(PCRE2_PRERELEASE) " " XSTRING(PCRE_DATE) because, when PCRE2_PRERELEASE is empty, this leads to an attempted expansion of STRING(). The C standard states: "If (before argument substitution) any diff --git a/ext/pcre/pcre2lib/pcre2_context.c b/ext/pcre/pcre2lib/pcre2_context.c index 2345145d3f55..9edbd1b2ae86 100644 --- a/ext/pcre/pcre2lib/pcre2_context.c +++ b/ext/pcre/pcre2lib/pcre2_context.c @@ -130,7 +130,7 @@ return gcontext; /* A default compile context is set up to save having to initialize at run time when no context is supplied to the compile function. */ -pcre2_compile_context PRIV(default_compile_context) = { +const pcre2_compile_context PRIV(default_compile_context) = { { default_malloc, default_free, NULL }, /* Default memory handling */ NULL, /* Stack guard */ NULL, /* Stack guard data */ @@ -141,8 +141,7 @@ pcre2_compile_context PRIV(default_compile_context) = { NEWLINE_DEFAULT, /* Newline convention */ PARENS_NEST_LIMIT, /* As it says */ 0, /* Extra options */ - MAX_VARLOOKBEHIND, /* As it says */ - PCRE2_OPTIMIZATION_ALL /* All optimizations enabled */ + MAX_VARLOOKBEHIND /* As it says */ }; /* The create function copies the default into the new memory, but must @@ -164,7 +163,7 @@ return ccontext; /* A default match context is set up to save having to initialize at run time when no context is supplied to a match function. */ -pcre2_match_context PRIV(default_match_context) = { +const pcre2_match_context PRIV(default_match_context) = { { default_malloc, default_free, NULL }, #ifdef SUPPORT_JIT NULL, /* JIT callback */ @@ -174,8 +173,6 @@ pcre2_match_context PRIV(default_match_context) = { NULL, /* Callout data */ NULL, /* Substitute callout function */ NULL, /* Substitute callout data */ - NULL, /* Substitute case callout function */ - NULL, /* Substitute case callout data */ PCRE2_UNSET, /* Offset limit */ HEAP_LIMIT, MATCH_LIMIT, @@ -200,7 +197,7 @@ return mcontext; /* A default convert context is set up to save having to initialize at run time when no context is supplied to the convert function. */ -pcre2_convert_context PRIV(default_convert_context) = { +const pcre2_convert_context PRIV(default_convert_context) = { { default_malloc, default_free, NULL }, /* Default memory handling */ #ifdef _WIN32 CHAR_BACKSLASH, /* Default path separator */ @@ -412,38 +409,6 @@ ccontext->stack_guard_data = user_data; return 0; } -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_optimize(pcre2_compile_context *ccontext, uint32_t directive) -{ -if (ccontext == NULL) - return PCRE2_ERROR_NULL; - -switch (directive) - { - case PCRE2_OPTIMIZATION_NONE: - ccontext->optimization_flags = 0; - break; - - case PCRE2_OPTIMIZATION_FULL: - ccontext->optimization_flags = PCRE2_OPTIMIZATION_ALL; - break; - - default: - if (directive >= PCRE2_AUTO_POSSESS && directive <= PCRE2_START_OPTIMIZE_OFF) - { - /* Even directive numbers starting from 64 switch a bit on; - * Odd directive numbers starting from 65 switch a bit off */ - if ((directive & 1) != 0) - ccontext->optimization_flags &= ~(1u << ((directive >> 1) - 32)); - else - ccontext->optimization_flags |= 1u << ((directive >> 1) - 32); - return 0; - } - return PCRE2_ERROR_BADOPTION; - } - -return 0; -} /* ------------ Match context ------------ */ @@ -459,24 +424,13 @@ return 0; PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_substitute_callout(pcre2_match_context *mcontext, int (*substitute_callout)(pcre2_substitute_callout_block *, void *), - void *substitute_callout_data) + void *substitute_callout_data) { mcontext->substitute_callout = substitute_callout; mcontext->substitute_callout_data = substitute_callout_data; return 0; } -PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION -pcre2_set_substitute_case_callout(pcre2_match_context *mcontext, - PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, - PCRE2_SIZE, int, void *), - void *substitute_case_callout_data) -{ -mcontext->substitute_case_callout = substitute_case_callout; -mcontext->substitute_case_callout_data = substitute_case_callout_data; -return 0; -} - PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit) { diff --git a/ext/pcre/pcre2lib/pcre2_convert.c b/ext/pcre/pcre2lib/pcre2_convert.c index d2b238ca4afb..fe396ae4f9c5 100644 --- a/ext/pcre/pcre2lib/pcre2_convert.c +++ b/ext/pcre/pcre2lib/pcre2_convert.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2022 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -74,7 +74,7 @@ enum { POSIX_START_REGEX, POSIX_ANCHORED, POSIX_NOT_BRACKET, #define PUTCHARS(string) \ { \ - for (const char *s = string; *s != 0; s++) \ + for (s = (char *)(string); *s != 0; s++) \ { \ if (p >= endp) return PCRE2_ERROR_NOMEMORY; \ *p++ = *s; \ @@ -125,6 +125,7 @@ convert_posix(uint32_t pattype, PCRE2_SPTR pattern, PCRE2_SIZE plength, BOOL utf, PCRE2_UCHAR *use_buffer, PCRE2_SIZE use_length, PCRE2_SIZE *bufflenptr, BOOL dummyrun, pcre2_convert_context *ccontext) { +char *s; PCRE2_SPTR posix = pattern; PCRE2_UCHAR *p = use_buffer; PCRE2_UCHAR *pp = p; @@ -1064,7 +1065,7 @@ pcre2_pattern_convert(PCRE2_SPTR pattern, PCRE2_SIZE plength, uint32_t options, PCRE2_UCHAR **buffptr, PCRE2_SIZE *bufflenptr, pcre2_convert_context *ccontext) { -int rc; +int i, rc; PCRE2_UCHAR dummy_buffer[DUMMY_BUFFER_SIZE]; PCRE2_UCHAR *use_buffer = dummy_buffer; PCRE2_SIZE use_length = DUMMY_BUFFER_SIZE; @@ -1118,7 +1119,7 @@ if (buffptr != NULL && *buffptr != NULL) /* Call an individual converter, either just once (if a buffer was provided or just the length is needed), or twice (if a memory allocation is required). */ -for (int i = 0; i < 2; i++) +for (i = 0; i < 2; i++) { PCRE2_UCHAR *allocated; BOOL dummyrun = buffptr == NULL || *buffptr == NULL; @@ -1137,7 +1138,8 @@ for (int i = 0; i < 2; i++) break; default: - goto EXIT; + *bufflenptr = 0; /* Error offset */ + return PCRE2_ERROR_INTERNAL; } if (rc != 0 || /* Error */ @@ -1157,12 +1159,8 @@ for (int i = 0; i < 2; i++) use_length = *bufflenptr + 1; } -/* Something went terribly wrong. Trigger an assert and return an error */ -PCRE2_DEBUG_UNREACHABLE(); +/* Control should never get here. */ -EXIT: - -*bufflenptr = 0; /* Error offset */ return PCRE2_ERROR_INTERNAL; } diff --git a/ext/pcre/pcre2lib/pcre2_dfa_match.c b/ext/pcre/pcre2lib/pcre2_dfa_match.c index ebf31d284d27..caae65248ff7 100644 --- a/ext/pcre/pcre2lib/pcre2_dfa_match.c +++ b/ext/pcre/pcre2lib/pcre2_dfa_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -156,7 +156,6 @@ static const uint8_t coptable[] = { 0, /* CLASS */ 0, /* NCLASS */ 0, /* XCLASS - variable length */ - 0, /* ECLASS - variable length */ 0, /* REF */ 0, /* REFI */ 0, /* DNREF */ @@ -176,7 +175,6 @@ static const uint8_t coptable[] = { 0, /* Assert behind not */ 0, /* NA assert */ 0, /* NA assert behind */ - 0, /* Assert scan substring */ 0, /* ONCE */ 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ @@ -190,7 +188,7 @@ static const uint8_t coptable[] = { 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ - 0, 0, /* \B and \b in UCP mode */ + 0, 0 /* \B and \b in UCP mode */ }; /* This table identifies those opcodes that inspect a character. It is used to @@ -236,7 +234,6 @@ static const uint8_t poptable[] = { 1, /* CLASS */ 1, /* NCLASS */ 1, /* XCLASS - variable length */ - 1, /* ECLASS - variable length */ 0, /* REF */ 0, /* REFI */ 0, /* DNREF */ @@ -256,7 +253,6 @@ static const uint8_t poptable[] = { 0, /* Assert behind not */ 0, /* NA assert */ 0, /* NA assert behind */ - 0, /* Assert scan substring */ 0, /* ONCE */ 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ @@ -270,13 +266,9 @@ static const uint8_t poptable[] = { 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ - 1, 1, /* \B and \b in UCP mode */ + 1, 1 /* \B and \b in UCP mode */ }; -/* Compile-time check that these tables have the correct size. */ -STATIC_ASSERT(sizeof(coptable) == OP_TABLE_LENGTH, coptable); -STATIC_ASSERT(sizeof(poptable) == OP_TABLE_LENGTH, poptable); - /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, and \w */ @@ -703,6 +695,7 @@ for (;;) int i, j; int clen, dlen; uint32_t c, d; + int forced_fail = 0; BOOL partial_newline = FALSE; BOOL could_continue = reset_could_continue; reset_could_continue = FALSE; @@ -848,6 +841,19 @@ for (;;) switch (codevalue) { +/* ========================================================================== */ + /* These cases are never obeyed. This is a fudge that causes a compile- + time error if the vectors coptable or poptable, which are indexed by + opcode, are not the correct length. It seems to be the only way to do + such a check at compile time, as the sizeof() operator does not work + in the C preprocessor. */ + + case OP_TABLE_LENGTH: + case OP_TABLE_LENGTH + + ((sizeof(coptable) == OP_TABLE_LENGTH) && + (sizeof(poptable) == OP_TABLE_LENGTH)): + return 0; + /* ========================================================================== */ /* Reached a closing bracket. If not at the end of the pattern, carry on with the next opcode. For repeating opcodes, also add the repeat @@ -1173,6 +1179,10 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[1]) { + case PT_ANY: + OK = TRUE; + break; + case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || @@ -1452,6 +1462,10 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[2]) { + case PT_ANY: + OK = TRUE; + break; + case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; @@ -1713,6 +1727,10 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[2]) { + case PT_ANY: + OK = TRUE; + break; + case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; @@ -1999,6 +2017,10 @@ for (;;) const ucd_record * prop = GET_UCD(c); switch(code[1 + IMM2_SIZE + 1]) { + case PT_ANY: + OK = TRUE; + break; + case PT_LAMP: chartype = prop->chartype; OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; @@ -2641,54 +2663,35 @@ for (;;) case OP_CLASS: case OP_NCLASS: -#ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - case OP_ECLASS: -#endif { BOOL isinclass = FALSE; int next_state_offset; PCRE2_SPTR ecode; -#ifdef SUPPORT_WIDE_CHARS - /* An extended class may have a table or a list of single characters, - ranges, or both, and it may be positive or negative. There's a - function that sorts all this out. */ - - if (codevalue == OP_XCLASS) - { - ecode = code + GET(code, 1); - if (clen > 0) - isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, - (const uint8_t*)mb->start_code, utf); - } - - /* A nested set-based class has internal opcodes for performing - set operations. */ - - else if (codevalue == OP_ECLASS) - { - ecode = code + GET(code, 1); - if (clen > 0) - isinclass = PRIV(eclass)(c, code + 1 + LINK_SIZE, ecode, - (const uint8_t*)mb->start_code, utf); - } - - else -#endif /* SUPPORT_WIDE_CHARS */ - /* For a simple class, there is always just a 32-byte table, and we can set isinclass from it. */ + if (codevalue != OP_XCLASS) { ecode = code + 1 + (32 / sizeof(PCRE2_UCHAR)); if (clen > 0) { isinclass = (c > 255)? (codevalue == OP_NCLASS) : - ((((const uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0); + ((((uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0); } } + /* An extended class may have a table or a list of single characters, + ranges, or both, and it may be positive or negative. There's a + function that sorts all this out. */ + + else + { + ecode = code + GET(code, 1); + if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf); + } + /* At this point, isinclass is set for all kinds of class, and ecode points to the byte after the end of the class. If there is a quantifier, this is where it will be. */ @@ -2781,6 +2784,7 @@ for (;;) though the other "backtracking verbs" are not supported. */ case OP_FAIL: + forced_fail++; /* Count FAILs for multiple states */ break; case OP_ASSERT: @@ -3054,7 +3058,7 @@ for (;;) if (codevalue == OP_BRAPOSZERO) { allow_zero = TRUE; - ++code; /* The following opcode will be one of the above BRAs */ + codevalue = *(++code); /* Codevalue will be one of above BRAs */ } else allow_zero = FALSE; @@ -3267,12 +3271,18 @@ for (;;) matches that we are going to find. If partial matching has been requested, check for appropriate conditions. + The "forced_ fail" variable counts the number of (*F) encountered for the + character. If it is equal to the original active_count (saved in + workspace[1]) it means that (*F) was found on every active state. In this + case we don't want to give a partial match. + The "could_continue" variable is true if a state could have continued but for the fact that the end of the subject was reached. */ if (new_count <= 0) { if (could_continue && /* Some could go on, and */ + forced_fail != workspace[1] && /* Not all forced fail & */ ( /* either... */ (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */ || /* or... */ @@ -3428,7 +3438,7 @@ if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) /* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the options variable for this function. Users of PCRE2 who are not calling the function directly would like to have a way of setting these flags, in the same -way that they can set pcre2_compile() flags like PCRE2_NO_AUTO_POSSESS with +way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and (*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which can now be transferred to the options for this function. The bits are guaranteed to be @@ -3518,7 +3528,8 @@ if (mb->match_limit_depth > re->limit_depth) if (mb->heap_limit > re->limit_heap) mb->heap_limit = re->limit_heap; -mb->start_code = (PCRE2_SPTR)((const uint8_t *)re + re->code_start); +mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + + re->name_count * re->name_entry_size; mb->tables = re->tables; mb->start_subject = subject; mb->end_subject = end_subject; @@ -3565,9 +3576,7 @@ switch(re->newline_convention) mb->nltype = NLTYPE_ANYCRLF; break; - default: - PCRE2_DEBUG_UNREACHABLE(); - return PCRE2_ERROR_INTERNAL; + default: return PCRE2_ERROR_INTERNAL; } /* Check a UTF string for validity if required. For 8-bit and 16-bit strings, @@ -3696,7 +3705,7 @@ for (;;) these, for testing and for ensuring that all callouts do actually occur. The optimizations must also be avoided when restarting a DFA match. */ - if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0 && + if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && (options & PCRE2_DFA_RESTART) == 0) { /* If firstline is TRUE, the start of the match is constrained to the first diff --git a/ext/pcre/pcre2lib/pcre2_error.c b/ext/pcre/pcre2lib/pcre2_error.c index 8b7423c6c640..7fa997aa9510 100644 --- a/ext/pcre/pcre2lib/pcre2_error.c +++ b/ext/pcre/pcre2lib/pcre2_error.c @@ -96,7 +96,7 @@ static const unsigned char compile_error_texts[] = "length of lookbehind assertion is not limited\0" "a relative value of zero is not allowed\0" "conditional subpattern contains more than two branches\0" - "atomic assertion expected after (?( or (?(?C)\0" + "assertion expected after (?( or (?(?C)\0" "digit expected after (?+ or (?-\0" /* 30 */ "unknown POSIX class name\0" @@ -161,7 +161,7 @@ static const unsigned char compile_error_texts[] = "using UCP is disabled by the application\0" "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" "character code point value in \\u.... sequence is too large\0" - "digits missing after \\x or in \\x{} or \\o{} or \\N{U+}\0" + "digits missing in \\x{} or \\o{} or \\N{U+}\0" "syntax error or number too big in (?(VERSION condition\0" /* 80 */ "internal error: unknown opcode in auto_possessify()\0" @@ -185,29 +185,11 @@ static const unsigned char compile_error_texts[] = "(*alpha_assertion) not recognized\0" "script runs require Unicode support, which this version of PCRE2 does not have\0" "too many capturing groups (maximum 65535)\0" - "octal digit missing after \\0 (PCRE2_EXTRA_NO_BS0 is set)\0" + "atomic assertion expected after (?( or (?(?C)\0" "\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\0" /* 100 */ "branch too long in variable-length lookbehind assertion\0" "compiled pattern would be longer than the limit set by the application\0" - "octal value given by \\ddd is greater than \\377 (forbidden by PCRE2_EXTRA_PYTHON_OCTAL)\0" - "using callouts is disabled by the application\0" - "PCRE2_EXTRA_TURKISH_CASING require Unicode (UTF or UCP) mode\0" - /* 105 */ - "PCRE2_EXTRA_TURKISH_CASING requires UTF in 8-bit mode\0" - "PCRE2_EXTRA_TURKISH_CASING and PCRE2_EXTRA_CASELESS_RESTRICT are not compatible\0" - "extended character class nesting is too deep\0" - "invalid operator in extended character class\0" - "unexpected operator in extended character class (no preceding operand)\0" - /* 110 */ - "expected operand after operator in extended character class\0" - "square brackets needed to clarify operator precedence in extended character class\0" - "missing terminating ] for extended character class (note '[' must be escaped under PCRE2_ALT_EXTENDED_CLASS)\0" - "unexpected expression in extended character class (no preceding operator)\0" - "empty expression in extended character class\0" - /* 115 */ - "terminating ] with no following closing parenthesis in (?[...]\0" - "unexpected character in (?[...]) extended character class\0" ; /* Match-time and UTF error texts are in the same format. */ @@ -294,10 +276,6 @@ static const unsigned char match_error_texts[] = "internal error - duplicate substitution match\0" "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0" "INTERNAL ERROR: invalid substring offset\0" - "feature is not supported by the JIT compiler\0" - "error performing replacement case transformation\0" - /* 70 */ - "replacement too large (longer than PCRE2_SIZE)\0" ; @@ -340,7 +318,7 @@ else if (enumber < 0) /* Match or UTF error */ } else /* Invalid error number */ { - message = (const unsigned char *)"\0"; /* Empty message list */ + message = (unsigned char *)"\0"; /* Empty message list */ n = 1; } diff --git a/ext/pcre/pcre2lib/pcre2_extuni.c b/ext/pcre/pcre2lib/pcre2_extuni.c index 91d839e2970c..4ed9f00c55a1 100644 --- a/ext/pcre/pcre2lib/pcre2_extuni.c +++ b/ext/pcre/pcre2lib/pcre2_extuni.c @@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. /* This module contains an internal function that is used to match a Unicode extended grapheme sequence. It is used by both pcre2_match() and -pcre2_dfa_match(). However, it is called only when Unicode support is being +pcre2_def_match(). However, it is called only when Unicode support is being compiled. Nevertheless, we provide a dummy function when there is no Unicode support, because some compilers do not like functionless source files. */ diff --git a/ext/pcre/pcre2lib/pcre2_find_bracket.c b/ext/pcre/pcre2lib/pcre2_find_bracket.c index 486f4539d89e..1290c5e9de11 100644 --- a/ext/pcre/pcre2lib/pcre2_find_bracket.c +++ b/ext/pcre/pcre2lib/pcre2_find_bracket.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -76,19 +76,18 @@ for (;;) if (c == OP_END) return NULL; /* XCLASS is used for classes that cannot be represented just by a bit map. - This includes negated single high-valued characters. ECLASS is used for - classes that use set operations internally. CALLOUT_STR is used for - callouts with string arguments. In each case the length in the table is + This includes negated single high-valued characters. CALLOUT_STR is used for + callouts with string arguments. In both cases the length in the table is zero; the actual length is stored in the compiled code. */ - if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1); - else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); + if (c == OP_XCLASS) code += GET(code, 1); + else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); /* Handle lookbehind */ else if (c == OP_REVERSE || c == OP_VREVERSE) { - if (number < 0) return code; + if (number < 0) return (PCRE2_UCHAR *)code; code += PRIV(OP_lengths)[c]; } @@ -98,7 +97,7 @@ for (;;) c == OP_CBRAPOS || c == OP_SCBRAPOS) { int n = (int)GET2(code, 1+LINK_SIZE); - if (n == number) return code; + if (n == number) return (PCRE2_UCHAR *)code; code += PRIV(OP_lengths)[c]; } diff --git a/ext/pcre/pcre2lib/pcre2_internal.h b/ext/pcre/pcre2lib/pcre2_internal.h index 6e0a5e05d03f..e5808182e676 100644 --- a/ext/pcre/pcre2lib/pcre2_internal.h +++ b/ext/pcre/pcre2lib/pcre2_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -88,12 +88,6 @@ typedef int BOOL; #define TRUE 1 #endif -/* Helper macro for static (compile-time) assertions. Can be used inside -functions, or at the top-level of a file. */ -#define STATIC_ASSERT_JOIN(a,b) a ## b -#define STATIC_ASSERT(cond, msg) \ - typedef int STATIC_ASSERT_JOIN(static_assertion_,msg)[(cond)?1:-1] - /* Valgrind (memcheck) support */ #ifdef SUPPORT_VALGRIND @@ -529,29 +523,29 @@ start/end of string field names are. */ three must not be changed, because whichever is set is actually the number of bytes in a code unit in that mode. */ -#define PCRE2_MODE8 0x00000001u /* compiled in 8 bit mode */ -#define PCRE2_MODE16 0x00000002u /* compiled in 16 bit mode */ -#define PCRE2_MODE32 0x00000004u /* compiled in 32 bit mode */ -#define PCRE2_FIRSTSET 0x00000010u /* first_code unit is set */ -#define PCRE2_FIRSTCASELESS 0x00000020u /* caseless first code unit */ -#define PCRE2_FIRSTMAPSET 0x00000040u /* bitmap of first code units is set */ -#define PCRE2_LASTSET 0x00000080u /* last code unit is set */ -#define PCRE2_LASTCASELESS 0x00000100u /* caseless last code unit */ -#define PCRE2_STARTLINE 0x00000200u /* start after \n for multiline */ -#define PCRE2_JCHANGED 0x00000400u /* j option used in pattern */ -#define PCRE2_HASCRORLF 0x00000800u /* explicit \r or \n in pattern */ -#define PCRE2_HASTHEN 0x00001000u /* pattern contains (*THEN) */ -#define PCRE2_MATCH_EMPTY 0x00002000u /* pattern can match empty string */ -#define PCRE2_BSR_SET 0x00004000u /* BSR was set in the pattern */ -#define PCRE2_NL_SET 0x00008000u /* newline was set in the pattern */ -#define PCRE2_NOTEMPTY_SET 0x00010000u /* (*NOTEMPTY) used ) keep */ -#define PCRE2_NE_ATST_SET 0x00020000u /* (*NOTEMPTY_ATSTART) used) together */ -#define PCRE2_DEREF_TABLES 0x00040000u /* release character tables */ -#define PCRE2_NOJIT 0x00080000u /* (*NOJIT) used */ -#define PCRE2_HASBKPORX 0x00100000u /* contains \P, \p, or \X */ -#define PCRE2_DUPCAPUSED 0x00200000u /* contains (?| */ -#define PCRE2_HASBKC 0x00400000u /* contains \C */ -#define PCRE2_HASACCEPT 0x00800000u /* contains (*ACCEPT) */ +#define PCRE2_MODE8 0x00000001 /* compiled in 8 bit mode */ +#define PCRE2_MODE16 0x00000002 /* compiled in 16 bit mode */ +#define PCRE2_MODE32 0x00000004 /* compiled in 32 bit mode */ +#define PCRE2_FIRSTSET 0x00000010 /* first_code unit is set */ +#define PCRE2_FIRSTCASELESS 0x00000020 /* caseless first code unit */ +#define PCRE2_FIRSTMAPSET 0x00000040 /* bitmap of first code units is set */ +#define PCRE2_LASTSET 0x00000080 /* last code unit is set */ +#define PCRE2_LASTCASELESS 0x00000100 /* caseless last code unit */ +#define PCRE2_STARTLINE 0x00000200 /* start after \n for multiline */ +#define PCRE2_JCHANGED 0x00000400 /* j option used in pattern */ +#define PCRE2_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */ +#define PCRE2_HASTHEN 0x00001000 /* pattern contains (*THEN) */ +#define PCRE2_MATCH_EMPTY 0x00002000 /* pattern can match empty string */ +#define PCRE2_BSR_SET 0x00004000 /* BSR was set in the pattern */ +#define PCRE2_NL_SET 0x00008000 /* newline was set in the pattern */ +#define PCRE2_NOTEMPTY_SET 0x00010000 /* (*NOTEMPTY) used ) keep */ +#define PCRE2_NE_ATST_SET 0x00020000 /* (*NOTEMPTY_ATSTART) used) together */ +#define PCRE2_DEREF_TABLES 0x00040000 /* release character tables */ +#define PCRE2_NOJIT 0x00080000 /* (*NOJIT) used */ +#define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */ +#define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */ +#define PCRE2_HASBKC 0x00400000 /* contains \C */ +#define PCRE2_HASACCEPT 0x00800000 /* contains (*ACCEPT) */ #define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32) @@ -580,16 +574,6 @@ modes. */ #define REQ_CU_MAX 2000 #endif -/* The maximum nesting depth for Unicode character class sets. -Currently fixed. Warning: the interpreter relies on this so it can encode -the operand stack in a uint32_t. A nesting limit of 15 implies (15*2+1)=31 -stack operands required, due to the fact that we have two (and only two) -levels of operator precedence. In the UTS#18 syntax, you can write 'x&&y[z]' -and in Perl syntax you can write '(?[ x - y & (z) ])', both of which imply -pushing the match results for x & y to the stack. */ - -#define ECLASS_NEST_LIMIT 15 - /* Offsets for the bitmap tables in the cbits set of tables. Each table contains a set of bits for a class map. Some classes are built by combining these tables. */ @@ -625,13 +609,6 @@ total length of the tables. */ #define ctypes_offset (cbits_offset + cbit_length) /* Character types */ #define TABLES_LENGTH (ctypes_offset + 256) -/* Private flags used in compile_context.optimization_flags */ - -#define PCRE2_OPTIM_AUTO_POSSESS 0x00000001u -#define PCRE2_OPTIM_DOTSTAR_ANCHOR 0x00000002u -#define PCRE2_OPTIM_START_OPTIMIZE 0x00000004u - -#define PCRE2_OPTIMIZATION_ALL 0x00000007u /* -------------------- Character and string names ------------------------ */ @@ -938,7 +915,6 @@ a positive value. */ #define STRING_naplb0 "naplb\0" #define STRING_nla0 "nla\0" #define STRING_nlb0 "nlb\0" -#define STRING_scs0 "scs\0" #define STRING_sr0 "sr\0" #define STRING_asr0 "asr\0" #define STRING_positive_lookahead0 "positive_lookahead\0" @@ -949,7 +925,6 @@ a positive value. */ #define STRING_negative_lookbehind0 "negative_lookbehind\0" #define STRING_script_run0 "script_run\0" #define STRING_atomic_script_run "atomic_script_run" -#define STRING_scan_substring0 "scan_substring\0" #define STRING_alpha0 "alpha\0" #define STRING_lower0 "lower\0" @@ -990,8 +965,6 @@ a positive value. */ #define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" #define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)" #define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)" -#define STRING_CASELESS_RESTRICT_RIGHTPAR "CASELESS_RESTRICT)" -#define STRING_TURKISH_CASING_RIGHTPAR "TURKISH_CASING)" #define STRING_LIMIT_HEAP_EQ "LIMIT_HEAP=" #define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH=" #define STRING_LIMIT_DEPTH_EQ "LIMIT_DEPTH=" @@ -1243,7 +1216,6 @@ only. */ #define STRING_naplb0 STR_n STR_a STR_p STR_l STR_b "\0" #define STRING_nla0 STR_n STR_l STR_a "\0" #define STRING_nlb0 STR_n STR_l STR_b "\0" -#define STRING_scs0 STR_s STR_c STR_s "\0" #define STRING_sr0 STR_s STR_r "\0" #define STRING_asr0 STR_a STR_s STR_r "\0" #define STRING_positive_lookahead0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0" @@ -1254,7 +1226,6 @@ only. */ #define STRING_negative_lookbehind0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0" #define STRING_script_run0 STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n "\0" #define STRING_atomic_script_run STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n -#define STRING_scan_substring0 STR_s STR_c STR_a STR_n STR_UNDERSCORE STR_s STR_u STR_b STR_s STR_t STR_r STR_i STR_n STR_g "\0" #define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" #define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" @@ -1295,8 +1266,6 @@ only. */ #define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS #define STRING_NOTEMPTY_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_RIGHT_PARENTHESIS #define STRING_NOTEMPTY_ATSTART_RIGHTPAR STR_N STR_O STR_T STR_E STR_M STR_P STR_T STR_Y STR_UNDERSCORE STR_A STR_T STR_S STR_T STR_A STR_R STR_T STR_RIGHT_PARENTHESIS -#define STRING_CASELESS_RESTRICT_RIGHTPAR STR_C STR_A STR_S STR_E STR_L STR_E STR_S STR_S STR_UNDERSCORE STR_R STR_E STR_S STR_T STR_R STR_I STR_C STR_T STR_RIGHT_PARENTHESIS -#define STRING_TURKISH_CASING_RIGHTPAR STR_T STR_U STR_R STR_K STR_I STR_S STR_H STR_UNDERSCORE STR_C STR_A STR_S STR_I STR_N STR_G STR_RIGHT_PARENTHESIS #define STRING_LIMIT_HEAP_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_H STR_E STR_A STR_P STR_EQUALS_SIGN #define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN #define STRING_LIMIT_DEPTH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_D STR_E STR_P STR_T STR_H STR_EQUALS_SIGN @@ -1321,22 +1290,21 @@ only. */ changed, the autopossessifying table in pcre2_auto_possess.c must be updated to match. */ -#define PT_LAMP 0 /* L& - the union of Lu, Ll, Lt */ -#define PT_GC 1 /* Specified general characteristic (e.g. L) */ -#define PT_PC 2 /* Specified particular characteristic (e.g. Lu) */ -#define PT_SC 3 /* Script only (e.g. Han) */ -#define PT_SCX 4 /* Script extensions (includes SC) */ -#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */ -#define PT_SPACE 6 /* Perl space - general category Z plus 9,10,12,13 */ -#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ -#define PT_WORD 8 /* Word - L, N, Mn, or Pc */ -#define PT_CLIST 9 /* Pseudo-property: match character list */ -#define PT_UCNC 10 /* Universal Character nameable character */ -#define PT_BIDICL 11 /* Specified bidi class */ -#define PT_BOOL 12 /* Boolean property */ -#define PT_ANY 13 /* Must be the last entry! - Any property - matches all chars */ -#define PT_TABSIZE PT_ANY /* Size of square table for autopossessify tests */ +#define PT_ANY 0 /* Any property - matches all chars */ +#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */ +#define PT_GC 2 /* Specified general characteristic (e.g. L) */ +#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */ +#define PT_SC 4 /* Script only (e.g. Han) */ +#define PT_SCX 5 /* Script extensions (includes SC) */ +#define PT_ALNUM 6 /* Alphanumeric - the union of L and N */ +#define PT_SPACE 7 /* Perl space - general category Z plus 9,10,12,13 */ +#define PT_PXSPACE 8 /* POSIX space - Z plus 9,10,11,12,13 */ +#define PT_WORD 9 /* Word - L, N, Mn, or Pc */ +#define PT_CLIST 10 /* Pseudo-property: match character list */ +#define PT_UCNC 11 /* Universal Character nameable character */ +#define PT_BIDICL 12 /* Specified bidi class */ +#define PT_BOOL 13 /* Boolean property */ +#define PT_TABSIZE 14 /* Size of square table for autopossessify tests */ /* The following special properties are used only in XCLASS items, when POSIX classes are specified and PCRE2_UCP is set - in other words, for Unicode @@ -1366,94 +1334,6 @@ contain characters with values greater than 255. */ #define XCL_RANGE 2 /* A range (two multibyte chars) follows */ #define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ #define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ -/* This value represents the beginning of character lists. The value -is 16 bit long, and stored as a high and low byte pair in 8 bit mode. -The lower 12 bit contains information about character lists (see later). */ -#define XCL_LIST (sizeof(PCRE2_UCHAR) == 1 ? 0x10 : 0x1000) - -/* When a character class contains many characters/ranges, -they are stored in character lists. There are four character -lists which contain characters/ranges within a given range. - -The name, character range and item size for each list: -Low16 [0x100 - 0x7fff] 16 bit items -High16 [0x8000 - 0xffff] 16 bit items -Low32 [0x10000 - 0x7fffffff] 32 bit items -High32 [0x80000000 - 0xffffffff] 32 bit items - -The Low32 character list is used only when utf encoding or 32 bit -character width is enabled, and the High32 character is used only -when 32 bit character width is enabled. - -Each character list contain items. The lowest bit represents that -an item is the beginning of a range (bit is cleared), or not (bit -is set). The other bits represent the character shifted left by -one, so its highest bit is discarded. Due to the layout of character -lists, the highest bit of a character is always known: - -Low16 and Low32: the highest bit is always zero -High16 and High32: the highest bit is always one - -The items are ordered in increasing order, so binary search can be -used to find the lower bound of an input character. The lower bound -is the highest item, which value is less or equal than the input -character. If the lower bit of the item is cleard, or the character -stored in the item equals to the input character, the input -character is in the character list. */ - -/* Character list constants. */ -#define XCL_CHAR_LIST_LOW_16_START 0x100 -#define XCL_CHAR_LIST_LOW_16_END 0x7fff -#define XCL_CHAR_LIST_LOW_16_ADD 0x0 - -#define XCL_CHAR_LIST_HIGH_16_START 0x8000 -#define XCL_CHAR_LIST_HIGH_16_END 0xffff -#define XCL_CHAR_LIST_HIGH_16_ADD 0x8000 - -#define XCL_CHAR_LIST_LOW_32_START 0x10000 -#define XCL_CHAR_LIST_LOW_32_END 0x7fffffff -#define XCL_CHAR_LIST_LOW_32_ADD 0x0 - -#define XCL_CHAR_LIST_HIGH_32_START 0x80000000 -#define XCL_CHAR_LIST_HIGH_32_END 0xffffffff -#define XCL_CHAR_LIST_HIGH_32_ADD 0x80000000 - -/* Mask for getting the descriptors of character list ranges. -Each descriptor has XCL_TYPE_BIT_LEN bits, and can be processed -by XCL_BEGIN_WITH_RANGE and XCL_ITEM_COUNT_MASK macros. */ -#define XCL_TYPE_MASK 0xfff -#define XCL_TYPE_BIT_LEN 3 -/* If this bit is set, the first item of the character list is the -end of a range, which started before the starting character of the -character list. */ -#define XCL_BEGIN_WITH_RANGE 0x4 -/* Number of items in the character list: 0, 1, or 2. The value 3 -represents that the item count is stored at the begining of the -character list. The item count has the same width as the items -in the character list (e.g. 16 bit for Low16 and High16 lists). */ -#define XCL_ITEM_COUNT_MASK 0x3 -/* Shift and flag for constructing character list items. The XCL_CHAR_END -is set, when the item is not the beginning of a range. The XCL_CHAR_SHIFT -can be used to encode / decode the character value stored in an item. */ -#define XCL_CHAR_END 0x1 -#define XCL_CHAR_SHIFT 1 - -/* Flag bits for an extended class (OP_ECLASS), which is used for complex -character matches such as [\p{Greek} && \p{Ll}]. */ - -#define ECL_MAP 0x01 /* Flag: a 32-byte map is present */ - -/* Type tags for the items stored in an extended class (OP_ECLASS). These items -follow the OP_ECLASS's flag char and bitmap, and represent a Reverse Polish -Notation list of operands and operators manipulating a stack of bits. */ - -#define ECL_AND 1 /* Pop two from the stack, AND, and push result. */ -#define ECL_OR 2 /* Pop two from the stack, OR, and push result. */ -#define ECL_XOR 3 /* Pop two from the stack, XOR, and push result. */ -#define ECL_NOT 4 /* Pop one from the stack, NOT, and push result. */ -#define ECL_XCLASS 5 /* XCLASS nested within ECLASS; match and push result. */ -#define ECL_ANY 6 /* Temporary, only used during compilation. */ -#define ECL_NONE 7 /* Temporary, only used during compilation. */ /* These are escaped items that aren't just an encoding of a particular data value such as \n. They must have non-zero values, as check_escape() returns 0 @@ -1675,105 +1555,102 @@ enum { character > 255 is encountered. */ OP_XCLASS, /* 112 Extended class for handling > 255 chars within the class. This does both positive and negative. */ - OP_ECLASS, /* 113 Really-extended class, for handling logical - expressions computed over characters. */ - OP_REF, /* 114 Match a back reference, casefully */ - OP_REFI, /* 115 Match a back reference, caselessly */ - OP_DNREF, /* 116 Match a duplicate name backref, casefully */ - OP_DNREFI, /* 117 Match a duplicate name backref, caselessly */ - OP_RECURSE, /* 118 Match a numbered subpattern (possibly recursive) */ - OP_CALLOUT, /* 119 Call out to external function if provided */ - OP_CALLOUT_STR, /* 120 Call out with string argument */ - - OP_ALT, /* 121 Start of alternation */ - OP_KET, /* 122 End of group that doesn't have an unbounded repeat */ - OP_KETRMAX, /* 123 These two must remain together and in this */ - OP_KETRMIN, /* 124 order. They are for groups the repeat for ever. */ - OP_KETRPOS, /* 125 Possessive unlimited repeat. */ + OP_REF, /* 113 Match a back reference, casefully */ + OP_REFI, /* 114 Match a back reference, caselessly */ + OP_DNREF, /* 115 Match a duplicate name backref, casefully */ + OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */ + OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */ + OP_CALLOUT, /* 118 Call out to external function if provided */ + OP_CALLOUT_STR, /* 119 Call out with string argument */ + + OP_ALT, /* 120 Start of alternation */ + OP_KET, /* 121 End of group that doesn't have an unbounded repeat */ + OP_KETRMAX, /* 122 These two must remain together and in this */ + OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */ + OP_KETRPOS, /* 124 Possessive unlimited repeat. */ /* The assertions must come before BRA, CBRA, ONCE, and COND. */ - OP_REVERSE, /* 126 Move pointer back - used in lookbehind assertions */ - OP_VREVERSE, /* 127 Move pointer back - variable */ - OP_ASSERT, /* 128 Positive lookahead */ - OP_ASSERT_NOT, /* 129 Negative lookahead */ - OP_ASSERTBACK, /* 130 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 131 Negative lookbehind */ - OP_ASSERT_NA, /* 132 Positive non-atomic lookahead */ - OP_ASSERTBACK_NA, /* 133 Positive non-atomic lookbehind */ - OP_ASSERT_SCS, /* 134 Scan substring */ + OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */ + OP_VREVERSE, /* 126 Move pointer back - variable */ + OP_ASSERT, /* 127 Positive lookahead */ + OP_ASSERT_NOT, /* 128 Negative lookahead */ + OP_ASSERTBACK, /* 129 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 130 Negative lookbehind */ + OP_ASSERT_NA, /* 131 Positive non-atomic lookahead */ + OP_ASSERTBACK_NA, /* 132 Positive non-atomic lookbehind */ /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. The POS versions must immediately follow the non-POS versions in each case. */ - OP_ONCE, /* 135 Atomic group, contains captures */ - OP_SCRIPT_RUN, /* 136 Non-capture, but check characters' scripts */ - OP_BRA, /* 137 Start of non-capturing bracket */ - OP_BRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 139 Start of capturing bracket */ - OP_CBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 141 Conditional group */ + OP_ONCE, /* 133 Atomic group, contains captures */ + OP_SCRIPT_RUN, /* 134 Non-capture, but check characters' scripts */ + OP_BRA, /* 135 Start of non-capturing bracket */ + OP_BRAPOS, /* 136 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 137 Start of capturing bracket */ + OP_CBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 139 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 142 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 143 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 144 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 145 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 146 Conditional group, check empty */ + OP_SBRA, /* 140 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 141 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 142 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 143 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 144 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 147 Used to hold a capture number as condition */ - OP_DNCREF, /* 148 Used to point to duplicate names as a condition */ - OP_RREF, /* 149 Used to hold a recursion number as condition */ - OP_DNRREF, /* 150 Used to point to duplicate names as a condition */ - OP_FALSE, /* 151 Always false (used by DEFINE and VERSION) */ - OP_TRUE, /* 152 Always true (used by VERSION) */ + OP_CREF, /* 145 Used to hold a capture number as condition */ + OP_DNCREF, /* 146 Used to point to duplicate names as a condition */ + OP_RREF, /* 147 Used to hold a recursion number as condition */ + OP_DNRREF, /* 148 Used to point to duplicate names as a condition */ + OP_FALSE, /* 149 Always false (used by DEFINE and VERSION) */ + OP_TRUE, /* 150 Always true (used by VERSION) */ - OP_BRAZERO, /* 153 These two must remain together and in this */ - OP_BRAMINZERO, /* 154 order. */ - OP_BRAPOSZERO, /* 155 */ + OP_BRAZERO, /* 151 These two must remain together and in this */ + OP_BRAMINZERO, /* 152 order. */ + OP_BRAPOSZERO, /* 153 */ /* These are backtracking control verbs */ - OP_MARK, /* 156 always has an argument */ - OP_PRUNE, /* 157 */ - OP_PRUNE_ARG, /* 158 same, but with argument */ - OP_SKIP, /* 159 */ - OP_SKIP_ARG, /* 160 same, but with argument */ - OP_THEN, /* 161 */ - OP_THEN_ARG, /* 162 same, but with argument */ - OP_COMMIT, /* 163 */ - OP_COMMIT_ARG, /* 164 same, but with argument */ + OP_MARK, /* 154 always has an argument */ + OP_PRUNE, /* 155 */ + OP_PRUNE_ARG, /* 156 same, but with argument */ + OP_SKIP, /* 157 */ + OP_SKIP_ARG, /* 158 same, but with argument */ + OP_THEN, /* 159 */ + OP_THEN_ARG, /* 160 same, but with argument */ + OP_COMMIT, /* 161 */ + OP_COMMIT_ARG, /* 162 same, but with argument */ /* These are forced failure and success verbs. FAIL and ACCEPT do accept an argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL) without the need for a special opcode. */ - OP_FAIL, /* 165 */ - OP_ACCEPT, /* 166 */ - OP_ASSERT_ACCEPT, /* 167 Used inside assertions */ - OP_CLOSE, /* 168 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 163 */ + OP_ACCEPT, /* 164 */ + OP_ASSERT_ACCEPT, /* 165 Used inside assertions */ + OP_CLOSE, /* 166 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 169 */ + OP_SKIPZERO, /* 167 */ /* This is used to identify a DEFINE group during compilation so that it can be checked for having only one branch. It is changed to OP_FALSE before compilation finishes. */ - OP_DEFINE, /* 170 */ + OP_DEFINE, /* 168 */ /* These opcodes replace their normal counterparts in UCP mode when PCRE2_EXTRA_ASCII_BSW is not set. */ - OP_NOT_UCP_WORD_BOUNDARY, /* 171 */ - OP_UCP_WORD_BOUNDARY, /* 172 */ + OP_NOT_UCP_WORD_BOUNDARY, /* 169 */ + OP_UCP_WORD_BOUNDARY, /* 170 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1816,21 +1693,19 @@ some cases doesn't actually use these names at all). */ "*+","++", "?+", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ "*+","++", "?+", "{", \ - "class", "nclass", "xclass", "eclass", \ - "Ref", "Refi", "DnRef", "DnRefi", \ + "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ "Recurse", "Callout", "CalloutStr", \ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ "Reverse", "VReverse", "Assert", "Assert not", \ "Assert back", "Assert back not", \ "Non-atomic assert", "Non-atomic assert back", \ - "Scan substring", \ "Once", \ "Script run", \ "Bra", "BraPos", "CBra", "CBraPos", \ "Cond", \ "SBra", "SBraPos", "SCBra", "SCBraPos", \ "SCond", \ - "Capture ref", "Capture dnref", "Cond rec", "Cond dnrec", \ + "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", \ "Cond false", "Cond true", \ "Brazero", "Braminzero", "Braposzero", \ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ @@ -1891,11 +1766,10 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+(32/sizeof(PCRE2_UCHAR)), /* CLASS */ \ 1+(32/sizeof(PCRE2_UCHAR)), /* NCLASS */ \ 0, /* XCLASS - variable length */ \ - 0, /* ECLASS - variable length */ \ 1+IMM2_SIZE, /* REF */ \ - 1+IMM2_SIZE+1, /* REFI */ \ + 1+IMM2_SIZE, /* REFI */ \ 1+2*IMM2_SIZE, /* DNREF */ \ - 1+2*IMM2_SIZE+1, /* DNREFI */ \ + 1+2*IMM2_SIZE, /* DNREFI */ \ 1+LINK_SIZE, /* RECURSE */ \ 1+2*LINK_SIZE+1, /* CALLOUT */ \ 0, /* CALLOUT_STR - variable length */ \ @@ -1912,7 +1786,6 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+LINK_SIZE, /* Assert behind not */ \ 1+LINK_SIZE, /* NA Assert */ \ 1+LINK_SIZE, /* NA Assert behind */ \ - 1+LINK_SIZE, /* Scan substring */ \ 1+LINK_SIZE, /* ONCE */ \ 1+LINK_SIZE, /* SCRIPT_RUN */ \ 1+LINK_SIZE, /* BRA */ \ @@ -1942,11 +1815,6 @@ in UTF-8 mode. The code that uses this table must know about such things. */ #define RREF_ANY 0xffff -/* Constants used by OP_REFI and OP_DNREFI to control matching behaviour. */ - -#define REFI_FLAG_CASELESS_RESTRICT 0x1 -#define REFI_FLAG_TURKISH_CASING 0x2 - /* ---------- Private structures that are mode-independent. ---------- */ @@ -2022,14 +1890,6 @@ typedef struct { #define UCD_SCRIPTX(ch) UCD_SCRIPTX_PROP(GET_UCD(ch)) #define UCD_BPROPS(ch) UCD_BPROPS_PROP(GET_UCD(ch)) #define UCD_BIDICLASS(ch) UCD_BIDICLASS_PROP(GET_UCD(ch)) -#define UCD_ANY_I(ch) \ - /* match any of the four characters 'i', 'I', U+0130, U+0131 */ \ - (((uint32_t)(ch) | 0x20u) == 0x69u || ((uint32_t)(ch) | 1u) == 0x0131u) -#define UCD_DOTTED_I(ch) \ - ((uint32_t)(ch) == 0x69u || (uint32_t)(ch) == 0x0130u) -#define UCD_FOLD_I_TURKISH(ch) \ - ((uint32_t)(ch) == 0x0130u ? 0x69u : \ - (uint32_t)(ch) == 0x49u ? 0x0131u : (uint32_t)(ch)) /* The "scriptx" and bprops fields contain offsets into vectors of 32-bit words that form a bitmap representing a list of scripts or boolean properties. These @@ -2095,9 +1955,6 @@ extern const uint8_t PRIV(utf8_table4)[]; #define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_) #define _pcre2_ucd_boolprop_sets PCRE2_SUFFIX(_pcre2_ucd_boolprop_sets_) #define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_) -#define _pcre2_ucd_turkish_dotted_i_caseset PCRE2_SUFFIX(_pcre2_ucd_turkish_dotted_i_caseset_) -#define _pcre2_ucd_nocase_ranges PCRE2_SUFFIX(_pcre2_ucd_nocase_ranges_) -#define _pcre2_ucd_nocase_ranges_size PCRE2_SUFFIX(_pcre2_ucd_nocase_ranges_size_) #define _pcre2_ucd_digit_sets PCRE2_SUFFIX(_pcre2_ucd_digit_sets_) #define _pcre2_ucd_script_sets PCRE2_SUFFIX(_pcre2_ucd_script_sets_) #define _pcre2_ucd_records PCRE2_SUFFIX(_pcre2_ucd_records_) @@ -2114,17 +1971,14 @@ extern const uint8_t PRIV(utf8_table4)[]; extern const uint8_t PRIV(OP_lengths)[]; extern const uint32_t PRIV(callout_end_delims)[]; extern const uint32_t PRIV(callout_start_delims)[]; -extern pcre2_compile_context PRIV(default_compile_context); -extern pcre2_convert_context PRIV(default_convert_context); -extern pcre2_match_context PRIV(default_match_context); +extern const pcre2_compile_context PRIV(default_compile_context); +extern const pcre2_convert_context PRIV(default_convert_context); +extern const pcre2_match_context PRIV(default_match_context); extern const uint8_t PRIV(default_tables)[]; extern const uint32_t PRIV(hspace_list)[]; extern const uint32_t PRIV(vspace_list)[]; extern const uint32_t PRIV(ucd_boolprop_sets)[]; extern const uint32_t PRIV(ucd_caseless_sets)[]; -extern const uint32_t PRIV(ucd_turkish_dotted_i_caseset); -extern const uint32_t PRIV(ucd_nocase_ranges)[]; -extern const uint32_t PRIV(ucd_nocase_ranges_size); extern const uint32_t PRIV(ucd_digit_sets)[]; extern const uint32_t PRIV(ucd_script_sets)[]; extern const ucd_record PRIV(ucd_records)[]; @@ -2185,12 +2039,11 @@ is available. */ #define _pcre2_valid_utf PCRE2_SUFFIX(_pcre2_valid_utf_) #define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_) #define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_) -#define _pcre2_eclass PCRE2_SUFFIX(_pcre2_eclass_) extern int _pcre2_auto_possessify(PCRE2_UCHAR *, const compile_block *); extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *, - int *, uint32_t, uint32_t, uint32_t, BOOL, compile_block *); + int *, uint32_t, uint32_t, BOOL, compile_block *); extern PCRE2_SPTR _pcre2_extuni(uint32_t, PCRE2_SPTR, PCRE2_SPTR, PCRE2_SPTR, BOOL, int *); extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int); @@ -2213,9 +2066,7 @@ extern int _pcre2_study(pcre2_real_code *); extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *); extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR, uint32_t *, BOOL); -extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, const uint8_t *, BOOL); -extern BOOL _pcre2_eclass(uint32_t, PCRE2_SPTR, PCRE2_SPTR, - const uint8_t *, BOOL); +extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL); /* This function is needed only when memmove() is not available. */ @@ -2228,8 +2079,6 @@ extern void * _pcre2_memmove(void *, const void *, size_t); extern BOOL PRIV(ckd_smul)(PCRE2_SIZE *, int, int); -#include "pcre2_util.h" - #endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */ /* End of pcre2_internal.h */ diff --git a/ext/pcre/pcre2lib/pcre2_intmodedep.h b/ext/pcre/pcre2lib/pcre2_intmodedep.h index 6b858139f577..9bd9e694a496 100644 --- a/ext/pcre/pcre2lib/pcre2_intmodedep.h +++ b/ext/pcre/pcre2lib/pcre2_intmodedep.h @@ -47,7 +47,7 @@ to have access to the hidden structures at all supported widths. Some of the mode-dependent macros are required at different widths for different parts of the pcre2test code (in particular, the included -pcre2_printint.c file). We undefine them here so that they can be re-defined for +pcre_printint.c file). We undefine them here so that they can be re-defined for multiple inclusions. Not all of these are used in pcre2test, but it's easier just to undefine them all. */ @@ -435,7 +435,7 @@ UTF-16 mode. */ c = *eptr; \ if ((c & 0xfc00u) == 0xd800u) GETUTF16LEN(c, eptr, len); -/* Get the next UTF-16 character, testing for UTF-16 mode, not advancing the +/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the pointer, incrementing length if there is a low surrogate. This is called when we do not know if we are in UTF-16 mode. */ @@ -556,11 +556,6 @@ code that uses them is simpler because it assumes this. */ /* The real general context structure. At present it holds only data for custom memory control. */ -/* WARNING: if this is ever changed, code in pcre2_substitute.c will have to be -changed because it builds a general context "by hand" in order to avoid the -malloc() call in pcre2_general_context)_create(). There is also code in -pcre2_match.c that makes the same assumption. */ - typedef struct pcre2_real_general_context { pcre2_memctl memctl; } pcre2_real_general_context; @@ -579,7 +574,6 @@ typedef struct pcre2_real_compile_context { uint32_t parens_nest_limit; uint32_t extra_options; uint32_t max_varlookbehind; - uint32_t optimization_flags; } pcre2_real_compile_context; /* The real match context structure. */ @@ -590,13 +584,10 @@ typedef struct pcre2_real_match_context { pcre2_jit_callback jit_callback; void *jit_callback_data; #endif - int (*callout)(pcre2_callout_block *, void *); - void *callout_data; - int (*substitute_callout)(pcre2_substitute_callout_block *, void *); - void *substitute_callout_data; - PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, - PCRE2_SIZE, int, void *); - void *substitute_case_callout_data; + int (*callout)(pcre2_callout_block *, void *); + void *callout_data; + int (*substitute_callout)(pcre2_substitute_callout_block *, void *); + void *substitute_callout_data; PCRE2_SIZE offset_limit; uint32_t heap_limit; uint32_t match_limit; @@ -632,7 +623,6 @@ typedef struct pcre2_real_code { void *executable_jit; /* Pointer to JIT code */ uint8_t start_bitmap[32]; /* Bitmap for starting code unit < 256 */ CODE_BLOCKSIZE_TYPE blocksize; /* Total (bytes) that was malloc-ed */ - CODE_BLOCKSIZE_TYPE code_start; /* Byte code start offset */ uint32_t magic_number; /* Paranoid and endianness check */ uint32_t compile_options; /* Options passed to pcre2_compile() */ uint32_t overall_options; /* Options after processing the pattern */ @@ -651,7 +641,6 @@ typedef struct pcre2_real_code { uint16_t top_backref; /* Highest numbered back reference */ uint16_t name_entry_size; /* Size (code units) of table entries */ uint16_t name_count; /* Number of name entries in the table */ - uint32_t optimization_flags; /* Optimizations enabled at compile time */ } pcre2_real_code; /* The real match data structure. Define ovector as large as it can ever @@ -727,23 +716,6 @@ typedef struct named_group { uint16_t isdup; /* TRUE if a duplicate */ } named_group; -/* Structure for caching sorted ranges. This improves the performance -of translating META code to byte code. */ - -typedef struct class_ranges { - struct class_ranges *next; /* Next class ranges */ - size_t char_lists_size; /* Total size of encoded char lists */ - size_t char_lists_start; /* Start offset of encoded char lists */ - uint16_t range_list_size; /* Size of ranges array */ - uint16_t char_lists_types; /* The XCL_LIST header of char lists */ - /* Followed by the list of ranges (start/end pairs) */ -} class_ranges; - -typedef union class_bits_storage { - uint8_t classbits[32]; - uint32_t classwords[8]; -} class_bits_storage; - /* Structure for passing "static" information around between the functions doing the compiling, so that they are thread-safe. */ @@ -753,15 +725,14 @@ typedef struct compile_block { const uint8_t *fcc; /* Points to case-flipping table */ const uint8_t *cbits; /* Points to character type table */ const uint8_t *ctypes; /* Points to table of type maps */ - PCRE2_UCHAR *start_workspace; /* The start of working space */ - PCRE2_UCHAR *start_code; /* The start of the compiled code */ + PCRE2_SPTR start_workspace; /* The start of working space */ + PCRE2_SPTR start_code; /* The start of the compiled code */ PCRE2_SPTR start_pattern; /* The start of the pattern */ PCRE2_SPTR end_pattern; /* The end of the pattern */ PCRE2_UCHAR *name_table; /* The name/number table */ PCRE2_SIZE workspace_size; /* Size of workspace */ PCRE2_SIZE small_ref_offset[10]; /* Offsets for \1 to \9 */ PCRE2_SIZE erroroffset; /* Offset of error in pattern */ - class_bits_storage classbits; /* Temporary store for classbits */ uint16_t names_found; /* Number of entries so far */ uint16_t name_entry_size; /* Size of each entry */ uint16_t parens_depth; /* Depth of nested parentheses */ @@ -779,9 +750,9 @@ typedef struct compile_block { uint32_t backref_map; /* Bitmap of low back refs */ uint32_t nltype; /* Newline type */ uint32_t nllen; /* Newline string length */ + uint32_t class_range_start; /* Overall class range start */ + uint32_t class_range_end; /* Overall class range end */ PCRE2_UCHAR nl[4]; /* Newline string when fixed length */ - uint8_t class_op_used[ECLASS_NEST_LIMIT]; /* Operation used for - extended classes */ uint32_t req_varyopt; /* "After variable item" flag for reqbyte */ uint32_t max_varlookbehind; /* Limit for variable lookbehinds */ int max_lookbehind; /* Maximum lookbehind encountered (characters) */ @@ -789,11 +760,6 @@ typedef struct compile_block { BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ BOOL had_recurse; /* Had a pattern recursion or subroutine call */ BOOL dupnames; /* Duplicate names exist */ -#ifdef SUPPORT_WIDE_CHARS - class_ranges *cranges; /* First class range. */ - class_ranges *next_cranges; /* Next class range. */ - size_t char_lists_size; /* Current size of character lists */ -#endif } compile_block; /* Structure for keeping the properties of the in-memory stack used @@ -827,7 +793,7 @@ typedef struct heapframe { to RRMATCH(), but which do not need to be copied to new frames. */ PCRE2_SPTR ecode; /* The current position in the pattern */ - PCRE2_SPTR temp_sptr[2]; /* Used for short-term PCRE2_SPTR values */ + PCRE2_SPTR temp_sptr[2]; /* Used for short-term PCRE_SPTR values */ PCRE2_SIZE length; /* Used for character, string, or code lengths */ PCRE2_SIZE back_frame; /* Amount to subtract on RRETURN */ PCRE2_SIZE temp_size; /* Used for short-term PCRE2_SIZE values */ @@ -875,10 +841,11 @@ typedef struct heapframe { PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ } heapframe; -/* Assert that the size of the heapframe structure is a multiple of PCRE2_SIZE. -See various comments above. */ +/* This typedef is a check that the size of the heapframe structure is a +multiple of PCRE2_SIZE. See various comments above. */ -STATIC_ASSERT((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0, heapframe_size); +typedef char check_heapframe_size[ + ((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0)? (+1):(-1)]; /* Structure for computing the alignment of heapframe. */ diff --git a/ext/pcre/pcre2lib/pcre2_jit_char_inc.h b/ext/pcre/pcre2lib/pcre2_jit_char_inc.h deleted file mode 100644 index 69fe938fc5bc..000000000000 --- a/ext/pcre/pcre2lib/pcre2_jit_char_inc.h +++ /dev/null @@ -1,2280 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - This module by Zoltan Herczeg - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -/* XClass matching code. */ - -#ifdef SUPPORT_WIDE_CHARS - -#define ECLASS_CHAR_DATA STACK_TOP -#define ECLASS_STACK_DATA STACK_LIMIT - -#define SET_CHAR_OFFSET(value) \ - if ((value) != charoffset) \ - { \ - if ((value) < charoffset) \ - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ - else \ - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ - } \ - charoffset = (value); - -#define READ_FROM_CHAR_LIST(destination) \ - if (list_ind <= 1) \ - { \ - destination = *(const uint16_t*)next_char; \ - next_char += 2; \ - } \ - else \ - { \ - destination = *(const uint32_t*)next_char; \ - next_char += 4; \ - } - -#define XCLASS_LOCAL_RANGES_SIZE 32 -#define XCLASS_LOCAL_RANGES_LOG2_SIZE 5 - -typedef struct xclass_stack_item { - sljit_u32 first_item; - sljit_u32 last_item; - struct sljit_jump *jump; -} xclass_stack_item; - -typedef struct xclass_ranges { - size_t range_count; - /* Pointer to ranges. A stack area is provided when a small buffer is enough. */ - uint32_t *ranges; - uint32_t local_ranges[XCLASS_LOCAL_RANGES_SIZE * 2]; - /* Stack size must be log2(ranges / 2). */ - xclass_stack_item *stack; - xclass_stack_item local_stack[XCLASS_LOCAL_RANGES_LOG2_SIZE]; -} xclass_ranges; - -static void xclass_compute_ranges(compiler_common *common, PCRE2_SPTR cc, xclass_ranges *ranges) -{ -DEFINE_COMPILER; -size_t range_count = 0, est_range_count; -size_t est_stack_size, tmp; -uint32_t type, list_ind; -uint32_t est_type; -uint32_t char_list_add, range_start, range_end; -const uint8_t *next_char; -const uint8_t *est_next_char; -#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) -BOOL utf = common->utf; -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ - -if (*cc == XCL_SINGLE || *cc == XCL_RANGE) - { - /* Only a few ranges are present. */ - do - { - type = *cc++; - SLJIT_ASSERT(type == XCL_SINGLE || type == XCL_RANGE); - GETCHARINCTEST(range_end, cc); - ranges->ranges[range_count] = range_end; - - if (type == XCL_RANGE) - { - GETCHARINCTEST(range_end, cc); - } - - ranges->ranges[range_count + 1] = range_end; - range_count += 2; - } - while (*cc != XCL_END); - - SLJIT_ASSERT(range_count <= XCLASS_LOCAL_RANGES_SIZE); - ranges->range_count = range_count; - return; - } - -SLJIT_ASSERT(cc[0] >= XCL_LIST); -#if PCRE2_CODE_UNIT_WIDTH == 8 -type = (uint32_t)(cc[0] << 8) | cc[1]; -cc += 2; -#else -type = cc[0]; -cc++; -#endif /* CODE_UNIT_WIDTH */ - -/* Align characters. */ -next_char = (const uint8_t*)common->start - (GET(cc, 0) << 1); -type &= XCL_TYPE_MASK; - -/* Estimate size. */ -est_next_char = next_char; -est_type = type; -est_range_count = 0; -list_ind = 0; - -while (est_type > 0) - { - uint32_t item_count = est_type & XCL_ITEM_COUNT_MASK; - - if (item_count == XCL_ITEM_COUNT_MASK) - { - if (list_ind <= 1) - { - item_count = *(const uint16_t*)est_next_char; - est_next_char += 2; - } - else - { - item_count = *(const uint32_t*)est_next_char; - est_next_char += 4; - } - } - - est_type >>= XCL_TYPE_BIT_LEN; - est_next_char += (size_t)item_count << (list_ind <= 1 ? 1 : 2); - list_ind++; - est_range_count += item_count + 1; - } - -if (est_range_count > XCLASS_LOCAL_RANGES_SIZE) - { - est_stack_size = 0; - tmp = est_range_count - 1; - - /* Compute log2(est_range_count) */ - while (tmp > 0) - { - est_stack_size++; - tmp >>= 1; - } - - ranges->stack = (xclass_stack_item*)SLJIT_MALLOC((sizeof(xclass_stack_item) * est_stack_size) - + ((sizeof(uint32_t) << 1) * (size_t)est_range_count), compiler->allocator_data); - - if (ranges->stack == NULL) - { - sljit_set_compiler_memory_error(compiler); - ranges->ranges = NULL; - return; - } - - ranges->ranges = (uint32_t*)(ranges->stack + est_stack_size); - } - -char_list_add = XCL_CHAR_LIST_LOW_16_ADD; -range_start = ~(uint32_t)0; -list_ind = 0; - -if ((type & XCL_BEGIN_WITH_RANGE) != 0) - range_start = XCL_CHAR_LIST_LOW_16_START; - -while (type > 0) - { - uint32_t item_count = type & XCL_ITEM_COUNT_MASK; - - if (item_count == XCL_ITEM_COUNT_MASK) - { - READ_FROM_CHAR_LIST(item_count); - SLJIT_ASSERT(item_count >= XCL_ITEM_COUNT_MASK); - } - - while (item_count > 0) - { - READ_FROM_CHAR_LIST(range_end); - - if ((range_end & XCL_CHAR_END) != 0) - { - range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT); - - if (range_start == ~(uint32_t)0) - range_start = range_end; - - ranges->ranges[range_count] = range_start; - ranges->ranges[range_count + 1] = range_end; - range_count += 2; - range_start = ~(uint32_t)0; - } - else - range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT); - - item_count--; - } - - list_ind++; - type >>= XCL_TYPE_BIT_LEN; - - if (range_start == ~(uint32_t)0) - { - if ((type & XCL_BEGIN_WITH_RANGE) != 0) - { - if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START; -#if PCRE2_CODE_UNIT_WIDTH == 32 - else if (list_ind == 2) range_start = XCL_CHAR_LIST_LOW_32_START; - else range_start = XCL_CHAR_LIST_HIGH_32_START; -#else - else range_start = XCL_CHAR_LIST_LOW_32_START; -#endif - } - } - else if ((type & XCL_BEGIN_WITH_RANGE) == 0) - { - if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END; - else if (list_ind == 2) range_end = XCL_CHAR_LIST_HIGH_16_END; -#if PCRE2_CODE_UNIT_WIDTH == 32 - else if (list_ind == 3) range_end = XCL_CHAR_LIST_LOW_32_END; - else range_end = XCL_CHAR_LIST_HIGH_32_END; -#else - else range_end = XCL_CHAR_LIST_LOW_32_END; -#endif - - ranges->ranges[range_count] = range_start; - ranges->ranges[range_count + 1] = range_end; - range_count += 2; - range_start = ~(uint32_t)0; - } - - if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; -#if PCRE2_CODE_UNIT_WIDTH == 32 - else if (list_ind == 2) char_list_add = XCL_CHAR_LIST_LOW_32_ADD; - else char_list_add = XCL_CHAR_LIST_HIGH_32_ADD; -#else - else char_list_add = XCL_CHAR_LIST_LOW_32_ADD; -#endif - } - -SLJIT_ASSERT(range_count > 0 && range_count <= (est_range_count << 1)); -SLJIT_ASSERT(next_char <= (const uint8_t*)common->start); -ranges->range_count = range_count; -} - -static void xclass_check_bitset(compiler_common *common, const sljit_u8 *bitset, jump_list **found, jump_list **backtracks) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; - -jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); -if (!optimize_class(common, bitset, (bitset[31] & 0x80) != 0, TRUE, found)) - { - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)bitset); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); - add_jump(compiler, found, JUMP(SLJIT_NOT_ZERO)); - } - -add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); -JUMPHERE(jump); -} - -#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) - -static void xclass_update_min_max(compiler_common *common, PCRE2_SPTR cc, sljit_u32 *min_ptr, sljit_u32 *max_ptr) -{ -uint32_t type, list_ind, c; -sljit_u32 min = *min_ptr; -sljit_u32 max = *max_ptr; -uint32_t char_list_add; -const uint8_t *next_char; -BOOL utf = TRUE; - -/* This function is pointless without utf 8/16. */ -SLJIT_ASSERT(common->utf); -if (*cc == XCL_SINGLE || *cc == XCL_RANGE) - { - /* Only a few ranges are present. */ - do - { - type = *cc++; - SLJIT_ASSERT(type == XCL_SINGLE || type == XCL_RANGE); - GETCHARINCTEST(c, cc); - - if (c < min) - min = c; - - if (type == XCL_RANGE) - { - GETCHARINCTEST(c, cc); - } - - if (c > max) - max = c; - } - while (*cc != XCL_END); - - SLJIT_ASSERT(min <= MAX_UTF_CODE_POINT && max <= MAX_UTF_CODE_POINT && min <= max); - *min_ptr = min; - *max_ptr = max; - return; - } - -SLJIT_ASSERT(cc[0] >= XCL_LIST); -#if PCRE2_CODE_UNIT_WIDTH == 8 -type = (uint32_t)(cc[0] << 8) | cc[1]; -cc += 2; -#else -type = cc[0]; -cc++; -#endif /* CODE_UNIT_WIDTH */ - -/* Align characters. */ -next_char = (const uint8_t*)common->start - (GET(cc, 0) << 1); -type &= XCL_TYPE_MASK; - -SLJIT_ASSERT(type != 0); - -/* Detect minimum. */ - -/* Skip unused ranges. */ -list_ind = 0; -while ((type & (XCL_BEGIN_WITH_RANGE | XCL_ITEM_COUNT_MASK)) == 0) - { - type >>= XCL_TYPE_BIT_LEN; - list_ind++; - } - -SLJIT_ASSERT(list_ind <= 2); -switch (list_ind) - { - case 0: - char_list_add = XCL_CHAR_LIST_LOW_16_ADD; - c = XCL_CHAR_LIST_LOW_16_START; - break; - - case 1: - char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; - c = XCL_CHAR_LIST_HIGH_16_START; - break; - - default: - char_list_add = XCL_CHAR_LIST_LOW_32_ADD; - c = XCL_CHAR_LIST_LOW_32_START; - break; - } - -if ((type & XCL_BEGIN_WITH_RANGE) != 0) - { - if (c < min) - min = c; - } -else - { - if ((type & XCL_ITEM_COUNT_MASK) == XCL_ITEM_COUNT_MASK) - { - if (list_ind <= 1) - c = *(const uint16_t*)(next_char + 2); - else - c = *(const uint32_t*)(next_char + 4); - } - else - { - if (list_ind <= 1) - c = *(const uint16_t*)next_char; - else - c = *(const uint32_t*)next_char; - } - - c = char_list_add + (c >> XCL_CHAR_SHIFT); - if (c < min) - min = c; - } - -/* Detect maximum. */ - -/* Skip intermediate ranges. */ -while (TRUE) - { - if ((type & XCL_ITEM_COUNT_MASK) == XCL_ITEM_COUNT_MASK) - { - if (list_ind <= 1) - { - c = *(const uint16_t*)next_char; - next_char += (c + 1) << 1; - } - else - { - c = *(const uint32_t*)next_char; - next_char += (c + 1) << 2; - } - } - else - next_char += (type & XCL_ITEM_COUNT_MASK) << (list_ind <= 1 ? 1 : 2); - - if ((type >> XCL_TYPE_BIT_LEN) == 0) - break; - - list_ind++; - type >>= XCL_TYPE_BIT_LEN; - } - -SLJIT_ASSERT(list_ind <= 2 && type != 0); -switch (list_ind) - { - case 0: - char_list_add = XCL_CHAR_LIST_LOW_16_ADD; - c = XCL_CHAR_LIST_LOW_16_END; - break; - - case 1: - char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; - c = XCL_CHAR_LIST_HIGH_16_END; - break; - - default: - char_list_add = XCL_CHAR_LIST_LOW_32_ADD; - c = XCL_CHAR_LIST_LOW_32_END; - break; - } - -if ((type & XCL_ITEM_COUNT_MASK) != 0) - { - /* Type is reused as temporary. */ - if (list_ind <= 1) - type = *(const uint16_t*)(next_char - 2); - else - type = *(const uint32_t*)(next_char - 4); - - if (type & XCL_CHAR_END) - c = char_list_add + (type >> XCL_CHAR_SHIFT); - } - -if (c > max) - max = c; - -SLJIT_ASSERT(min <= MAX_UTF_CODE_POINT && max <= MAX_UTF_CODE_POINT && min <= max); -*min_ptr = min; -*max_ptr = max; -} - -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ - -#define XCLASS_IS_ECLASS 0x001 -#ifdef SUPPORT_UNICODE -#define XCLASS_SAVE_CHAR 0x002 -#define XCLASS_HAS_TYPE 0x004 -#define XCLASS_HAS_SCRIPT 0x008 -#define XCLASS_HAS_SCRIPT_EXTENSION 0x010 -#define XCLASS_HAS_BOOL 0x020 -#define XCLASS_HAS_BIDICL 0x040 -#define XCLASS_NEEDS_UCD (XCLASS_HAS_TYPE | XCLASS_HAS_SCRIPT | XCLASS_HAS_SCRIPT_EXTENSION | XCLASS_HAS_BOOL | XCLASS_HAS_BIDICL) -#define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080 -#define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100 -#define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0 0x200 -#endif /* SUPPORT_UNICODE */ - -static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); - -/* TMP3 must be preserved because it is used by compile_iterator_matchingpath. */ -static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, sljit_u32 status) -{ -DEFINE_COMPILER; -jump_list *found = NULL; -jump_list *check_result = NULL; -jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; -sljit_uw c, charoffset; -sljit_u32 max = READ_CHAR_MAX, min = 0; -struct sljit_jump *jump = NULL; -PCRE2_UCHAR flags; -PCRE2_SPTR ccbegin; -sljit_u32 compares, invertcmp, depth; -sljit_u32 first_item, last_item, mid_item; -sljit_u32 range_start, range_end; -xclass_ranges ranges; -BOOL has_cmov, last_range_set; - -#ifdef SUPPORT_UNICODE -sljit_u32 category_list = 0; -sljit_u32 items; -int typereg = TMP1; -#endif /* SUPPORT_UNICODE */ - -SLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw)); -/* Scanning the necessary info. */ -flags = *cc++; -ccbegin = cc; -compares = 0; - -if (flags & XCL_MAP) - cc += 32 / sizeof(PCRE2_UCHAR); - -#ifdef SUPPORT_UNICODE -while (*cc == XCL_PROP || *cc == XCL_NOTPROP) - { - compares++; - cc++; - - items = 0; - - switch(*cc) - { - case PT_LAMP: - items = UCPCAT3(ucp_Lu, ucp_Ll, ucp_Lt); - break; - - case PT_GC: - items = UCPCAT_RANGE(PRIV(ucp_typerange)[(int)cc[1] * 2], PRIV(ucp_typerange)[(int)cc[1] * 2 + 1]); - break; - - case PT_PC: - items = UCPCAT(cc[1]); - break; - - case PT_WORD: - items = UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N; - break; - - case PT_ALNUM: - items = UCPCAT_L | UCPCAT_N; - break; - - case PT_SCX: - status |= XCLASS_HAS_SCRIPT_EXTENSION; - if (cc[-1] == XCL_NOTPROP) - { - status |= XCLASS_SCRIPT_EXTENSION_NOTPROP; - break; - } - compares++; - /* Fall through */ - - case PT_SC: - status |= XCLASS_HAS_SCRIPT; - break; - - case PT_SPACE: - case PT_PXSPACE: - case PT_PXGRAPH: - case PT_PXPRINT: - case PT_PXPUNCT: - status |= XCLASS_SAVE_CHAR | XCLASS_HAS_TYPE; - break; - - case PT_UCNC: - case PT_PXXDIGIT: - status |= XCLASS_SAVE_CHAR; - break; - - case PT_BOOL: - status |= XCLASS_HAS_BOOL; - break; - - case PT_BIDICL: - status |= XCLASS_HAS_BIDICL; - break; - - default: - SLJIT_UNREACHABLE(); - break; - } - - if (items > 0) - { - if (cc[-1] == XCL_NOTPROP) - items ^= UCPCAT_ALL; - category_list |= items; - status |= XCLASS_HAS_TYPE; - compares--; - } - - cc += 2; - } - -if (category_list == UCPCAT_ALL) - { - /* All or no characters are accepted, same as dotall. */ - if (status & XCLASS_IS_ECLASS) - { - if (list != backtracks) - OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - return; - } - - compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); - if (list == backtracks) - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - return; - } - -if (category_list != 0) - compares++; -#endif - -if (*cc != XCL_END) - { -#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) - if (common->utf && compares == 0 && !(status & XCLASS_IS_ECLASS)) - { - SLJIT_ASSERT(category_list == 0); - max = 0; - min = (flags & XCL_MAP) != 0 ? 0 : READ_CHAR_MAX; - xclass_update_min_max(common, cc, &min, &max); - } -#endif - compares++; -#ifdef SUPPORT_UNICODE - status |= XCLASS_SAVE_CHAR; -#endif /* SUPPORT_UNICODE */ - } - -#ifdef SUPPORT_UNICODE -SLJIT_ASSERT(compares > 0 || category_list != 0); -#else /* !SUPPORT_UNICODE */ -SLJIT_ASSERT(compares > 0); -#endif /* SUPPORT_UNICODE */ - -/* We are not necessary in utf mode even in 8 bit mode. */ -cc = ccbegin; -if (!(status & XCLASS_IS_ECLASS)) - { - if ((flags & XCL_NOT) != 0) - read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - { -#ifdef SUPPORT_UNICODE - read_char(common, min, max, (status & XCLASS_NEEDS_UCD) ? backtracks : NULL, 0); -#else /* !SUPPORT_UNICODE */ - read_char(common, min, max, NULL, 0); -#endif /* SUPPORT_UNICODE */ - } - } - -if ((flags & XCL_MAP) != 0) - { - SLJIT_ASSERT(!(status & XCLASS_IS_ECLASS)); - xclass_check_bitset(common, (const sljit_u8 *)cc, &found, backtracks); - cc += 32 / sizeof(PCRE2_UCHAR); - } - -#ifdef SUPPORT_UNICODE -if (status & XCLASS_NEEDS_UCD) - { - if ((status & (XCLASS_SAVE_CHAR | XCLASS_IS_ECLASS)) == XCLASS_SAVE_CHAR) - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); - -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (!common->utf) - { - OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1); - SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, UNASSIGNED_UTF_CHAR, TMP1); - } -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ - - OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); - OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - - ccbegin = cc; - - if (status & XCLASS_HAS_BIDICL) - { - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BIDICLASS_SHIFT); - - while (*cc == XCL_PROP || *cc == XCL_NOTPROP) - { - cc++; - - if (*cc == PT_BIDICL) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - if (cc[-1] == XCL_NOTPROP) - invertcmp ^= 0x1; - jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]); - add_jump(compiler, compares > 0 ? list : backtracks, jump); - } - cc += 2; - } - - cc = ccbegin; - } - - if (status & XCLASS_HAS_BOOL) - { - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, bprops)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BPROPS_MASK); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); - - while (*cc == XCL_PROP || *cc == XCL_NOTPROP) - { - cc++; - if (*cc == PT_BOOL) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - if (cc[-1] == XCL_NOTPROP) - invertcmp ^= 0x1; - - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); - add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); - } - cc += 2; - } - - cc = ccbegin; - } - - if (status & XCLASS_HAS_SCRIPT) - { - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - - while (*cc == XCL_PROP || *cc == XCL_NOTPROP) - { - cc++; - - switch (*cc) - { - case PT_SCX: - if (cc[-1] == XCL_NOTPROP) - break; - /* Fall through */ - - case PT_SC: - compares--; - invertcmp = (compares == 0 && list != backtracks); - if (cc[-1] == XCL_NOTPROP) - invertcmp ^= 0x1; - - add_jump(compiler, compares > 0 ? list : backtracks, CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1])); - } - cc += 2; - } - - cc = ccbegin; - } - - if (status & XCLASS_HAS_SCRIPT_EXTENSION) - { - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_SCRIPTX_MASK); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); - - if (status & XCLASS_SCRIPT_EXTENSION_NOTPROP) - { - if (status & XCLASS_HAS_TYPE) - { - if ((status & (XCLASS_SAVE_CHAR | XCLASS_IS_ECLASS)) == XCLASS_SAVE_CHAR) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, TMP2, 0); - status |= XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0; - } - else - { - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0); - status |= XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR; - } - } - OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - } - - while (*cc == XCL_PROP || *cc == XCL_NOTPROP) - { - cc++; - - if (*cc == PT_SCX) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - - jump = NULL; - if (cc[-1] == XCL_NOTPROP) - { - jump = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, (int)cc[1]); - if (invertcmp) - { - add_jump(compiler, backtracks, jump); - jump = NULL; - } - invertcmp ^= 0x1; - } - - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); - add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); - - if (jump != NULL) - JUMPHERE(jump); - } - cc += 2; - } - - if (status & XCLASS_SCRIPT_EXTENSION_RESTORE_LOCAL0) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); - else if (status & XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR) - OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0); - cc = ccbegin; - } - - if (status & XCLASS_SAVE_CHAR) - OP1(SLJIT_MOV, TMP1, 0, (status & XCLASS_IS_ECLASS) ? ECLASS_CHAR_DATA : RETURN_ADDR, 0); - - if (status & XCLASS_HAS_TYPE) - { - if (status & XCLASS_SAVE_CHAR) - typereg = RETURN_ADDR; - - OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); - OP2(SLJIT_SHL, typereg, 0, SLJIT_IMM, 1, TMP2, 0); - - if (category_list > 0) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, category_list); - add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); - } - } - } -#endif /* SUPPORT_UNICODE */ - -/* Generating code. */ -charoffset = 0; - -#ifdef SUPPORT_UNICODE -while (*cc == XCL_PROP || *cc == XCL_NOTPROP) - { - compares--; - invertcmp = (compares == 0 && list != backtracks); - jump = NULL; - - if (*cc == XCL_NOTPROP) - invertcmp ^= 0x1; - cc++; - switch(*cc) - { - case PT_LAMP: - case PT_GC: - case PT_PC: - case PT_SC: - case PT_SCX: - case PT_BOOL: - case PT_BIDICL: - case PT_WORD: - case PT_ALNUM: - compares++; - /* Already handled. */ - break; - - case PT_SPACE: - case PT_PXSPACE: - SET_CHAR_OFFSET(9); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xd - 0x9); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Zl, ucp_Zs)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_UCNC: - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - SET_CHAR_OFFSET(0xa0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - SET_CHAR_OFFSET(0); - OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_PXGRAPH: - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT_RANGE(ucp_Zl, ucp_Zs)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); - jump = JUMP(SLJIT_ZERO); - - c = charoffset; - /* In case of ucp_Cf, we overwrite the result. */ - SET_CHAR_OFFSET(0x2066); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - /* Restore charoffset. */ - SET_CHAR_OFFSET(c); - - JUMPHERE(jump); - jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); - break; - - case PT_PXPRINT: - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT2(ucp_Zl, ucp_Zp)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); - jump = JUMP(SLJIT_ZERO); - - c = charoffset; - /* In case of ucp_Cf, we overwrite the result. */ - SET_CHAR_OFFSET(0x2066); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - - /* Restore charoffset. */ - SET_CHAR_OFFSET(c); - - JUMPHERE(jump); - jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); - break; - - case PT_PXPUNCT: - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Sc, ucp_So)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - - SET_CHAR_OFFSET(0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f); - OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL); - - OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Pc, ucp_Ps)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_PXXDIGIT: - SET_CHAR_OFFSET(CHAR_A); - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, ~0x20); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP2, 0, SLJIT_IMM, CHAR_F - CHAR_A); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(CHAR_0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_9 - CHAR_0); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff10); - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff10); - - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff19 - 0xff10); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff21); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff26 - 0xff21); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff41); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff41); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - - SET_CHAR_OFFSET(0xff10); - - JUMPHERE(jump); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - default: - SLJIT_UNREACHABLE(); - break; - } - - cc += 2; - - if (jump != NULL) - add_jump(compiler, compares > 0 ? list : backtracks, jump); - } - -if (compares == 0) - { - if (found != NULL) - set_jumps(found, LABEL()); - - if (status & XCLASS_IS_ECLASS) - OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - return; - } -#endif /* SUPPORT_UNICODE */ - -SLJIT_ASSERT(compares == 1); -ranges.range_count = 0; -ranges.ranges = ranges.local_ranges; -ranges.stack = ranges.local_stack; - -xclass_compute_ranges(common, cc, &ranges); - -/* Memory error is set for the compiler. */ -if (ranges.stack == NULL) - return; - -#if (defined SLJIT_DEBUG && SLJIT_DEBUG) && \ - defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) -if (common->utf) - { - min = READ_CHAR_MAX; - max = 0; - xclass_update_min_max(common, cc, &min, &max); - SLJIT_ASSERT(ranges.ranges[0] == min && ranges.ranges[ranges.range_count - 1] == max); - } -#endif /* SLJIT_DEBUG && SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ - -invertcmp = (list != backtracks); - -if (ranges.range_count == 2) - { - range_start = ranges.ranges[0]; - range_end = ranges.ranges[1]; - - if (range_start < range_end) - { - SET_CHAR_OFFSET(range_start); - jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start)); - } - else - jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset)); - - add_jump(compiler, backtracks, jump); - - SLJIT_ASSERT(ranges.stack == ranges.local_stack); - if (found != NULL) - set_jumps(found, LABEL()); - - if (status & XCLASS_IS_ECLASS) - OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - return; - } - -range_start = ranges.ranges[0]; -SET_CHAR_OFFSET(range_start); -if (ranges.range_count >= 6) - { - /* Early fail. */ - range_end = ranges.ranges[ranges.range_count - 1]; - add_jump(compiler, (flags & XCL_NOT) == 0 ? backtracks : &found, - CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start))); - } - -depth = 0; -first_item = 0; -last_item = ranges.range_count - 2; -has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV) != 0; - -while (TRUE) - { - /* At least two items are present. */ - SLJIT_ASSERT(first_item < last_item && charoffset == ranges.ranges[0]); - last_range_set = FALSE; - - if (first_item + 6 <= last_item) - { - mid_item = ((first_item + last_item) >> 1) & ~(sljit_u32)1; - SLJIT_ASSERT(last_item >= mid_item + 4); - - range_end = ranges.ranges[mid_item + 1]; - if (first_item + 6 > mid_item && ranges.ranges[mid_item] == range_end) - { - OP2U(SLJIT_SUB | SLJIT_SET_GREATER | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - charoffset)); - ranges.stack[depth].jump = JUMP(SLJIT_GREATER); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - last_range_set = TRUE; - } - else - ranges.stack[depth].jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - charoffset)); - - ranges.stack[depth].first_item = (sljit_u32)(mid_item + 2); - ranges.stack[depth].last_item = (sljit_u32)last_item; - - depth++; - SLJIT_ASSERT(ranges.stack == ranges.local_stack ? - depth <= XCLASS_LOCAL_RANGES_LOG2_SIZE : (ranges.stack + depth) <= (xclass_stack_item*)ranges.ranges); - - last_item = mid_item; - if (!last_range_set) - continue; - - last_item -= 2; - } - - if (!last_range_set) - { - range_start = ranges.ranges[first_item]; - range_end = ranges.ranges[first_item + 1]; - - if (range_start < range_end) - { - SET_CHAR_OFFSET(range_start); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - } - else - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - } - first_item += 2; - } - - SLJIT_ASSERT(first_item <= last_item); - - do - { - range_start = ranges.ranges[first_item]; - range_end = ranges.ranges[first_item + 1]; - - if (range_start < range_end) - { - SET_CHAR_OFFSET(range_start); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_end - range_start)); - - if (has_cmov) - SELECT(SLJIT_LESS_EQUAL, TMP2, STR_END, 0, TMP2); - else - OP_FLAGS(SLJIT_OR | ((first_item == last_item) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_LESS_EQUAL); - } - else - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(range_start - charoffset)); - - if (has_cmov) - SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2); - else - OP_FLAGS(SLJIT_OR | ((first_item == last_item) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); - } - - first_item += 2; - } - while (first_item <= last_item); - - if (depth == 0) break; - - add_jump(compiler, &check_result, JUMP(SLJIT_JUMP)); - - /* The charoffset resets after the end of a branch is reached. */ - charoffset = ranges.ranges[0]; - depth--; - first_item = ranges.stack[depth].first_item; - last_item = ranges.stack[depth].last_item; - JUMPHERE(ranges.stack[depth].jump); - } - -if (check_result != NULL) - set_jumps(check_result, LABEL()); - -if (has_cmov) - jump = CMP(SLJIT_NOT_EQUAL ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); -else - { - sljit_set_current_flags(compiler, SLJIT_SET_Z); - jump = JUMP(SLJIT_NOT_EQUAL ^ invertcmp); - } - -add_jump(compiler, backtracks, jump); - -if (found != NULL) - set_jumps(found, LABEL()); - -if (status & XCLASS_IS_ECLASS) - OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - -if (ranges.stack != ranges.local_stack) - SLJIT_FREE(ranges.stack, compiler->allocator_data); -} - -static PCRE2_SPTR compile_eclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) -{ -DEFINE_COMPILER; -PCRE2_SPTR end = cc + GET(cc, 0) - 1; -PCRE2_SPTR begin; -jump_list *not_found; -jump_list *found = NULL; - -cc += LINK_SIZE; - -/* Should be optimized later. */ -read_char(common, 0, READ_CHAR_MAX, backtracks, 0); - -if (((*cc++) & ECL_MAP) != 0) - { - xclass_check_bitset(common, (const sljit_u8 *)cc, &found, backtracks); - cc += 32 / sizeof(PCRE2_UCHAR); - } - -begin = cc; - -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, ECLASS_CHAR_DATA, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, ECLASS_STACK_DATA, 0); -OP1(SLJIT_MOV, ECLASS_STACK_DATA, 0, SLJIT_IMM, 0); -OP1(SLJIT_MOV, ECLASS_CHAR_DATA, 0, TMP1, 0); - -/* All eclass must start with an xclass. */ -SLJIT_ASSERT(*cc == ECL_XCLASS); - -while (cc < end) - { - switch (*cc) - { - case ECL_AND: - ++cc; - OP2(SLJIT_OR, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, ~(sljit_sw)1); - OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - OP2(SLJIT_AND, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0); - break; - - case ECL_OR: - ++cc; - OP2(SLJIT_AND, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - OP2(SLJIT_OR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0); - break; - - case ECL_XOR: - ++cc; - OP2(SLJIT_AND, TMP2, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - OP2(SLJIT_LSHR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - OP2(SLJIT_XOR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, TMP2, 0); - break; - - case ECL_NOT: - ++cc; - OP2(SLJIT_XOR, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - break; - - default: - SLJIT_ASSERT(*cc == ECL_XCLASS); - if (cc != begin) - { - OP1(SLJIT_MOV, TMP1, 0, ECLASS_CHAR_DATA, 0); - OP2(SLJIT_SHL, ECLASS_STACK_DATA, 0, ECLASS_STACK_DATA, 0, SLJIT_IMM, 1); - } - - not_found = NULL; - compile_xclass_matchingpath(common, cc + 1 + LINK_SIZE, ¬_found, XCLASS_IS_ECLASS); - set_jumps(not_found, LABEL()); - - cc += GET(cc, 1); - break; - } - } - -OP2U(SLJIT_SUB | SLJIT_SET_Z, ECLASS_STACK_DATA, 0, SLJIT_IMM, 0); -OP1(SLJIT_MOV, ECLASS_CHAR_DATA, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); -OP1(SLJIT_MOV, ECLASS_STACK_DATA, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); -add_jump(compiler, backtracks, JUMP(SLJIT_EQUAL)); -set_jumps(found, LABEL()); -return end; -} - -/* Generic character matching code. */ - -#undef SET_CHAR_OFFSET -#undef READ_FROM_CHAR_LIST -#undef XCLASS_LOCAL_RANGES_SIZE -#undef XCLASS_LOCAL_RANGES_LOG2_SIZE - -#endif /* SUPPORT_WIDE_CHARS */ - -static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, - compare_context *context, jump_list **backtracks) -{ -DEFINE_COMPILER; -unsigned int othercasebit = 0; -PCRE2_SPTR othercasechar = NULL; -#ifdef SUPPORT_UNICODE -int utflength; -#endif - -if (caseless && char_has_othercase(common, cc)) - { - othercasebit = char_get_othercase_bit(common, cc); - SLJIT_ASSERT(othercasebit); - /* Extracting bit difference info. */ -#if PCRE2_CODE_UNIT_WIDTH == 8 - othercasechar = cc + (othercasebit >> 8); - othercasebit &= 0xff; -#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - /* Note that this code only handles characters in the BMP. If there - ever are characters outside the BMP whose othercase differs in only one - bit from itself (there currently are none), this code will need to be - revised for PCRE2_CODE_UNIT_WIDTH == 32. */ - othercasechar = cc + (othercasebit >> 9); - if ((othercasebit & 0x100) != 0) - othercasebit = (othercasebit & 0xff) << 8; - else - othercasebit &= 0xff; -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ - } - -if (context->sourcereg == -1) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - if (context->length >= 4) - OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else if (context->length >= 2) - OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else -#endif - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - if (context->length >= 4) - OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); - else -#endif - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif PCRE2_CODE_UNIT_WIDTH == 32 - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ - context->sourcereg = TMP2; - } - -#ifdef SUPPORT_UNICODE -utflength = 1; -if (common->utf && HAS_EXTRALEN(*cc)) - utflength += GET_EXTRALEN(*cc); - -do - { -#endif - - context->length -= IN_UCHARS(1); -#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) - - /* Unaligned read is supported. */ - if (othercasebit != 0 && othercasechar == cc) - { - context->c.asuchars[context->ucharptr] = *cc | othercasebit; - context->oc.asuchars[context->ucharptr] = othercasebit; - } - else - { - context->c.asuchars[context->ucharptr] = *cc; - context->oc.asuchars[context->ucharptr] = 0; - } - context->ucharptr++; - -#if PCRE2_CODE_UNIT_WIDTH == 8 - if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) -#else - if (context->ucharptr >= 2 || context->length == 0) -#endif - { - if (context->length >= 4) - OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); - else if (context->length >= 2) - OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#if PCRE2_CODE_UNIT_WIDTH == 8 - else if (context->length >= 1) - OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; - - switch(context->ucharptr) - { - case 4 / sizeof(PCRE2_UCHAR): - if (context->oc.asint != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); - break; - - case 2 / sizeof(PCRE2_UCHAR): - if (context->oc.asushort != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); - break; - -#if PCRE2_CODE_UNIT_WIDTH == 8 - case 1: - if (context->oc.asbyte != 0) - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); - break; -#endif - - default: - SLJIT_UNREACHABLE(); - break; - } - context->ucharptr = 0; - } - -#else - - /* Unaligned read is unsupported or in 32 bit mode. */ - if (context->length >= 1) - OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); - - context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; - - if (othercasebit != 0 && othercasechar == cc) - { - OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); - } - else - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); - -#endif - - cc++; -#ifdef SUPPORT_UNICODE - utflength--; - } -while (utflength > 0); -#endif - -return cc; -} - -#ifdef SUPPORT_UNICODE - -#if PCRE2_CODE_UNIT_WIDTH != 32 - -/* The code in this function copies the logic of the interpreter function that -is defined in the pcre2_extuni.c source. If that code is updated, this -function, and those below it, must be kept in step (note by PH, June 2024). */ - -static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc) -{ -PCRE2_SPTR start_subject = args->begin; -PCRE2_SPTR end_subject = args->end; -int lgb, rgb, ricount; -PCRE2_SPTR prevcc, endcc, bptr; -BOOL first = TRUE; -BOOL was_ep_ZWJ = FALSE; -uint32_t c; - -prevcc = cc; -endcc = NULL; -do - { - GETCHARINC(c, cc); - rgb = UCD_GRAPHBREAK(c); - - if (first) - { - lgb = rgb; - endcc = cc; - first = FALSE; - continue; - } - - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) - break; - - /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was - preceded by Extended Pictographic. */ - - if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) - break; - - /* Not breaking between Regional Indicators is allowed only if there - are an even number of preceding RIs. */ - - if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) - { - ricount = 0; - bptr = prevcc; - - /* bptr is pointing to the left-hand character */ - while (bptr > start_subject) - { - bptr--; - BACKCHAR(bptr); - GETCHAR(c, bptr); - - if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) - break; - - ricount++; - } - - if ((ricount & 1) != 0) break; /* Grapheme break required */ - } - - /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in - between; see next statement). */ - - was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); - - /* If Extend follows Extended_Pictographic, do not update lgb; this allows - any number of them before a following ZWJ. */ - - if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) - lgb = rgb; - - prevcc = endcc; - endcc = cc; - } -while (cc < end_subject); - -return endcc; -} - -#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ - -/* The code in this function copies the logic of the interpreter function that -is defined in the pcre2_extuni.c source. If that code is updated, this -function, and the one below it, must be kept in step (note by PH, June 2024). */ - -static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc) -{ -PCRE2_SPTR start_subject = args->begin; -PCRE2_SPTR end_subject = args->end; -int lgb, rgb, ricount; -PCRE2_SPTR prevcc, endcc, bptr; -BOOL first = TRUE; -BOOL was_ep_ZWJ = FALSE; -uint32_t c; - -prevcc = cc; -endcc = NULL; -do - { - GETCHARINC_INVALID(c, cc, end_subject, break); - rgb = UCD_GRAPHBREAK(c); - - if (first) - { - lgb = rgb; - endcc = cc; - first = FALSE; - continue; - } - - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) - break; - - /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was - preceded by Extended Pictographic. */ - - if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) - break; - - /* Not breaking between Regional Indicators is allowed only if there - are an even number of preceding RIs. */ - - if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) - { - ricount = 0; - bptr = prevcc; - - /* bptr is pointing to the left-hand character */ - while (bptr > start_subject) - { - GETCHARBACK_INVALID(c, bptr, start_subject, break); - - if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) - break; - - ricount++; - } - - if ((ricount & 1) != 0) - break; /* Grapheme break required */ - } - - /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in - between; see next statement). */ - - was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); - - /* If Extend follows Extended_Pictographic, do not update lgb; this allows - any number of them before a following ZWJ. */ - - if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) - lgb = rgb; - - prevcc = endcc; - endcc = cc; - } -while (cc < end_subject); - -return endcc; -} - -/* The code in this function copies the logic of the interpreter function that -is defined in the pcre2_extuni.c source. If that code is updated, this -function must be kept in step (note by PH, June 2024). */ - -static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc) -{ -PCRE2_SPTR start_subject = args->begin; -PCRE2_SPTR end_subject = args->end; -int lgb, rgb, ricount; -PCRE2_SPTR bptr; -uint32_t c; -BOOL was_ep_ZWJ = FALSE; - -/* Patch by PH */ -/* GETCHARINC(c, cc); */ -c = *cc++; - -#if PCRE2_CODE_UNIT_WIDTH == 32 -if (c >= 0x110000) - return cc; -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ -lgb = UCD_GRAPHBREAK(c); - -while (cc < end_subject) - { - c = *cc; -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x110000) - break; -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ - rgb = UCD_GRAPHBREAK(c); - - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) - break; - - /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was - preceded by Extended Pictographic. */ - - if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) - break; - - /* Not breaking between Regional Indicators is allowed only if there - are an even number of preceding RIs. */ - - if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) - { - ricount = 0; - bptr = cc - 1; - - /* bptr is pointing to the left-hand character */ - while (bptr > start_subject) - { - bptr--; - c = *bptr; -#if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x110000) - break; -#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ - - if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; - - ricount++; - } - - if ((ricount & 1) != 0) - break; /* Grapheme break required */ - } - - /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in - between; see next statement). */ - - was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); - - /* If Extend follows Extended_Pictographic, do not update lgb; this allows - any number of them before a following ZWJ. */ - - if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) - lgb = rgb; - - cc++; - } - -return cc; -} - -static void compile_clist(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) -{ -DEFINE_COMPILER; -const sljit_u32 *other_cases; -struct sljit_jump *jump; -sljit_u32 min = 0, max = READ_CHAR_MAX; -BOOL has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV) != 0; - -SLJIT_ASSERT(cc[1] == PT_CLIST); - -if (cc[0] == OP_PROP) - { - other_cases = PRIV(ucd_caseless_sets) + cc[2]; - - min = *other_cases++; - max = min; - - while (*other_cases != NOTACHAR) - { - if (*other_cases > max) max = *other_cases; - if (*other_cases < min) min = *other_cases; - other_cases++; - } - } - -other_cases = PRIV(ucd_caseless_sets) + cc[2]; -SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR); -/* The NOTACHAR is higher than any character. */ -SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); - -read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); - -/* At least two characters are required. - Otherwise this case would be handled by the normal code path. */ -/* NOTACHAR is the unsigned maximum. */ - -/* Optimizing character pairs, if their difference is power of 2. */ -if (is_powerof2(other_cases[1] ^ other_cases[0])) - { - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[1] ^ other_cases[0])); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[1]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - other_cases += 2; - } -else if (is_powerof2(other_cases[2] ^ other_cases[1])) - { - SLJIT_ASSERT(other_cases[2] != NOTACHAR); - - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[2] ^ other_cases[1])); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[2]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)other_cases[0]); - - if (has_cmov) - SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2); - else - OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); - - other_cases += 3; - } -else - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - } - -while (*other_cases != NOTACHAR) - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++)); - - if (has_cmov) - SELECT(SLJIT_EQUAL, TMP2, STR_END, 0, TMP2); - else - OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); - } - -if (has_cmov) - jump = CMP(cc[0] == OP_PROP ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0); -else - jump = JUMP(cc[0] == OP_PROP ? SLJIT_ZERO : SLJIT_NOT_ZERO); - -add_jump(compiler, backtracks, jump); -} - -#endif /* SUPPORT_UNICODE */ - -static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr) -{ -DEFINE_COMPILER; -int length; -unsigned int c, oc, bit; -compare_context context; -struct sljit_jump *jump[3]; -jump_list *end_list; -#ifdef SUPPORT_UNICODE -PCRE2_UCHAR propdata[5]; -#endif /* SUPPORT_UNICODE */ - -switch(type) - { - case OP_NOT_DIGIT: - case OP_DIGIT: - /* Digits are usually 0-9, so it is worth to optimize them. */ - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE)) - read_char7_type(common, backtracks, type == OP_NOT_DIGIT); - else -#endif - read_char8_type(common, backtracks, type == OP_NOT_DIGIT); - /* Flip the starting bit in the negative case. */ - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_digit); - add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE)) - read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE); - else -#endif - read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_space); - add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE)) - read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR); - else -#endif - read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_word); - add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); - return cc; - - case OP_ANY: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - end_list = NULL; - if (common->mode != PCRE2_JIT_PARTIAL_HARD) - add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - else - check_str_end(common, &end_list); - - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); - set_jumps(end_list, LABEL()); - JUMPHERE(jump[0]); - } - else - check_newlinechar(common, common->nltype, backtracks, TRUE); - return cc; - - case OP_ALLANY: - if (check_str_ptr) - detect_partial_match(common, backtracks); -#ifdef SUPPORT_UNICODE - if (common->utf && common->invalid_utf) - { - read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); - return cc; - } -#endif /* SUPPORT_UNICODE */ - - skip_valid_char(common); - return cc; - - case OP_ANYBYTE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - return cc; - -#ifdef SUPPORT_UNICODE - case OP_NOTPROP: - case OP_PROP: - if (check_str_ptr) - detect_partial_match(common, backtracks); - if (cc[0] == PT_CLIST) - { - compile_clist(common, cc - 1, backtracks); - return cc + 2; - } - - propdata[0] = 0; - propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; - propdata[2] = cc[0]; - propdata[3] = cc[1]; - propdata[4] = XCL_END; - compile_xclass_matchingpath(common, propdata, backtracks, 0); - return cc + 2; -#endif - - case OP_ANYNL: - if (check_str_ptr) - detect_partial_match(common, backtracks); - read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0); - jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - /* We don't need to handle soft partial matching case. */ - end_list = NULL; - if (common->mode != PCRE2_JIT_PARTIAL_HARD) - add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - else - check_str_end(common, &end_list); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - jump[1] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[0]); - check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); - set_jumps(end_list, LABEL()); - JUMPHERE(jump[1]); - return cc; - - case OP_NOT_HSPACE: - case OP_HSPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - if (type == OP_NOT_HSPACE) - read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - read_char(common, 0x9, 0x3000, NULL, 0); - - add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); - sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - - case OP_NOT_VSPACE: - case OP_VSPACE: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - if (type == OP_NOT_VSPACE) - read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - read_char(common, 0xa, 0x2029, NULL, 0); - - add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); - sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - -#ifdef SUPPORT_UNICODE - case OP_EXTUNI: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); - OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); - -#if PCRE2_CODE_UNIT_WIDTH != 32 - sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, - common->utf ? (common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_utf)) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); - if (common->invalid_utf) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); -#else - sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, - common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); - if (common->invalid_utf) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); -#endif - - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); - - if (common->mode == PCRE2_JIT_PARTIAL_HARD) - { - jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0); - /* Since we successfully read a char above, partial matching must occur. */ - check_partial(common, TRUE); - JUMPHERE(jump[0]); - } - return cc; -#endif - - case OP_CHAR: - case OP_CHARI: - length = 1; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); -#endif - - if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE) - detect_partial_match(common, backtracks); - - if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) - { - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); - - context.length = IN_UCHARS(length); - context.sourcereg = -1; -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - context.ucharptr = 0; -#endif - return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); - } - -#ifdef SUPPORT_UNICODE - if (common->utf) - { - GETCHAR(c, cc); - } - else -#endif - c = *cc; - - SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc)); - - if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - - oc = char_othercase(common, c); - read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0); - - SLJIT_ASSERT(!is_powerof2(c ^ oc)); - - if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc); - SELECT(SLJIT_EQUAL, TMP1, SLJIT_IMM, c, TMP1); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - } - else - { - jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); - JUMPHERE(jump[0]); - } - return cc + length; - - case OP_NOT: - case OP_NOTI: - if (check_str_ptr) - detect_partial_match(common, backtracks); - - length = 1; -#ifdef SUPPORT_UNICODE - if (common->utf) - { -#if PCRE2_CODE_UNIT_WIDTH == 8 - c = *cc; - if (c < 128 && !common->invalid_utf) - { - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - if (type == OP_NOT || !char_has_othercase(common, cc)) - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - else - { - /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); - } - /* Skip the variable-length character. */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(jump[0]); - return cc + 1; - } - else -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - { - GETCHARLEN(c, cc, length); - } - } - else -#endif /* SUPPORT_UNICODE */ - c = *cc; - - if (type == OP_NOT || !char_has_othercase(common, cc)) - { - read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - } - else - { - oc = char_othercase(common, c); - read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR); - bit = c ^ oc; - if (is_powerof2(bit)) - { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); - } - else - { - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); - } - } - return cc + length; - - case OP_CLASS: - case OP_NCLASS: - if (check_str_ptr) - detect_partial_match(common, backtracks); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255; - if (type == OP_NCLASS) - read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - read_char(common, 0, bit, NULL, 0); -#else - if (type == OP_NCLASS) - read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR); - else - read_char(common, 0, 255, NULL, 0); -#endif - - if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks)) - return cc + 32 / sizeof(PCRE2_UCHAR); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - jump[0] = NULL; - if (common->utf) - { - jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit); - if (type == OP_CLASS) - { - add_jump(compiler, backtracks, jump[0]); - jump[0] = NULL; - } - } -#elif PCRE2_CODE_UNIT_WIDTH != 8 - jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - if (type == OP_CLASS) - { - add_jump(compiler, backtracks, jump[0]); - jump[0] = NULL; - } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ - - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); - add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - if (jump[0] != NULL) - JUMPHERE(jump[0]); -#endif - return cc + 32 / sizeof(PCRE2_UCHAR); - -#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - case OP_XCLASS: - if (check_str_ptr) - detect_partial_match(common, backtracks); - compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks, 0); - return cc + GET(cc, 0) - 1; - - case OP_ECLASS: - if (check_str_ptr) - detect_partial_match(common, backtracks); - return compile_eclass_matchingpath(common, cc, backtracks); -#endif - } -SLJIT_UNREACHABLE(); -return cc; -} - -static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks) -{ -/* This function consumes at least one input character. */ -/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ -DEFINE_COMPILER; -PCRE2_SPTR ccbegin = cc; -compare_context context; -int size; - -context.length = 0; -do - { - if (cc >= ccend) - break; - - if (*cc == OP_CHAR) - { - size = 1; -#ifdef SUPPORT_UNICODE - if (common->utf && HAS_EXTRALEN(cc[1])) - size += GET_EXTRALEN(cc[1]); -#endif - } - else if (*cc == OP_CHARI) - { - size = 1; -#ifdef SUPPORT_UNICODE - if (common->utf) - { - if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) - size = 0; - else if (HAS_EXTRALEN(cc[1])) - size += GET_EXTRALEN(cc[1]); - } - else -#endif - if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) - size = 0; - } - else - size = 0; - - cc += 1 + size; - context.length += IN_UCHARS(size); - } -while (size > 0 && context.length <= 128); - -cc = ccbegin; -if (context.length > 0) - { - /* We have a fixed-length byte sequence. */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); - - context.sourcereg = -1; -#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED - context.ucharptr = 0; -#endif - do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); - return cc; - } - -/* A non-fixed length character will be checked if length == 0. */ -return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); -} - - diff --git a/ext/pcre/pcre2lib/pcre2_jit_compile.c b/ext/pcre/pcre2lib/pcre2_jit_compile.c index 7fd10d5eaf39..92f4fb858b10 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_compile.c +++ b/ext/pcre/pcre2lib/pcre2_jit_compile.c @@ -282,14 +282,14 @@ typedef struct bracket_backtrack { struct sljit_label *zero_matchingpath; /* Contains the branches of a failed condition. */ union { - /* Both for OP_COND, OP_SCOND, OP_ASSERT_SCS. */ - jump_list *no_capture; + /* Both for OP_COND, OP_SCOND. */ + jump_list *condfailed; assert_backtrack *assert; /* For OP_ONCE. Less than 0 if not needed. */ int framesize; + /* For brackets with >3 alternatives. */ + struct sljit_jump *matching_mov_addr; } u; - /* For brackets with >3 alternatives. */ - struct sljit_jump *matching_mov_addr; /* Points to our private memory word on the stack. */ int private_data_ptr; } bracket_backtrack; @@ -313,12 +313,14 @@ typedef struct char_iterator_backtrack { backtrack_common common; /* Next iteration. */ struct sljit_label *matchingpath; - /* Creating a range based on the next character. */ - struct { - unsigned int othercasebit; - PCRE2_UCHAR chr; - BOOL charpos_enabled; - } charpos; + union { + jump_list *backtracks; + struct { + unsigned int othercasebit; + PCRE2_UCHAR chr; + BOOL enabled; + } charpos; + } u; } char_iterator_backtrack; typedef struct ref_iterator_backtrack { @@ -406,10 +408,6 @@ typedef struct compiler_common { then_trap_backtrack *then_trap; /* Starting offset of private data for capturing brackets. */ sljit_s32 cbra_ptr; -#if defined SLJIT_DEBUG && SLJIT_DEBUG - /* End offset of locals for assertions. */ - sljit_s32 locals_size; -#endif /* Output vector starting point. Must be divisible by 2. */ sljit_s32 ovector_start; /* Points to the starting character of the current match. */ @@ -431,11 +429,6 @@ typedef struct compiler_common { Each item must have a previous offset and type (see control_types) values. See do_search_mark. */ sljit_s32 control_head_ptr; - /* The offset of the saved STR_END in the outermost - scan substring block. Since scan substring restores - STR_END after a match, it is enough to restore - STR_END inside a scan substring block. */ - sljit_s32 restore_end_ptr; /* Points to the last matched capture block index. */ sljit_s32 capture_last_ptr; /* Fast forward skipping byte code pointer. */ @@ -520,6 +513,7 @@ typedef struct compiler_common { BOOL invalid_utf; BOOL ucp; /* Points to saving area for iref. */ + sljit_s32 iref_ptr; jump_list *getucd; jump_list *getucdtype; #if PCRE2_CODE_UNIT_WIDTH == 8 @@ -609,14 +603,14 @@ typedef struct compare_context { #endif /* Local space layout. */ +/* These two locals can be used by the current opcode. */ +#define LOCALS0 (0 * sizeof(sljit_sw)) +#define LOCALS1 (1 * sizeof(sljit_sw)) +/* Two local variables for possessive quantifiers (char1 cannot use them). */ +#define POSSESSIVE0 (2 * sizeof(sljit_sw)) +#define POSSESSIVE1 (3 * sizeof(sljit_sw)) /* Max limit of recursions. */ -#define LIMIT_MATCH (0 * sizeof(sljit_sw)) -/* Local variables. Their number is computed by check_opcode_types. */ -#define LOCAL0 (1 * sizeof(sljit_sw)) -#define LOCAL1 (2 * sizeof(sljit_sw)) -#define LOCAL2 (3 * sizeof(sljit_sw)) -#define LOCAL3 (4 * sizeof(sljit_sw)) -#define LOCAL4 (5 * sizeof(sljit_sw)) +#define LIMIT_MATCH (4 * sizeof(sljit_sw)) /* The output vector is stored on the stack, and contains pointers to characters. The vector data is divided into two groups: the first group contains the start / end character pointers, and the second is @@ -673,7 +667,7 @@ the start pointers when the end of the capturing group has not yet reached. */ #define GET_LOCAL_BASE(dst, dstw, offset) \ sljit_get_local_base(compiler, (dst), (dstw), (offset)) -#define READ_CHAR_MAX ((sljit_u32)0xffffffff) +#define READ_CHAR_MAX 0x7fffffff #define INVALID_UTF_CHAR -1 #define UNASSIGNED_UTF_CHAR 888 @@ -868,7 +862,7 @@ the start pointers when the end of the capturing group has not yet reached. */ static PCRE2_SPTR bracketend(PCRE2_SPTR cc) { -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERT_SCS) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); do cc += GET(cc, 1); while (*cc == OP_ALT); SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); cc += 1 + LINK_SIZE; @@ -878,7 +872,7 @@ return cc; static int no_alternatives(PCRE2_SPTR cc) { int count = 0; -SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERT_SCS) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); +SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); do { cc += GET(cc, 1); @@ -981,7 +975,6 @@ switch(*cc) case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -1104,9 +1097,7 @@ switch(*cc) return cc + GET(cc, 1 + 2*LINK_SIZE); #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 - case OP_ECLASS: case OP_XCLASS: - SLJIT_COMPILE_ASSERT(OP_XCLASS + 1 == OP_ECLASS && OP_CLASS + 1 == OP_NCLASS && OP_NCLASS < OP_XCLASS, class_byte_code_order); return cc + GET(cc, 1); #endif @@ -1123,36 +1114,12 @@ switch(*cc) } } -static sljit_s32 ref_update_local_size(compiler_common *common, PCRE2_SPTR cc, sljit_s32 current_locals_size) -{ -/* Depends on do_casefulcmp(), do_caselesscmp(), and compile_ref_matchingpath() */ -int locals_size = 2 * SSIZE_OF(sw); -SLJIT_UNUSED_ARG(common); - -#ifdef SUPPORT_UNICODE -if ((*cc == OP_REFI || *cc == OP_DNREFI) && (common->utf || common->ucp)) - locals_size = 3 * SSIZE_OF(sw); -#endif - -cc += PRIV(OP_lengths)[*cc]; -/* Although do_casefulcmp() uses only one local, the allocate_stack() -calls during the repeat destroys LOCAL1 variables. */ -if (*cc >= OP_CRSTAR && *cc <= OP_CRPOSRANGE) - locals_size += 2 * SSIZE_OF(sw); - -return (current_locals_size >= locals_size) ? current_locals_size : locals_size; -} - static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend) { int count; PCRE2_SPTR slot; PCRE2_SPTR assert_back_end = cc - 1; PCRE2_SPTR assert_na_end = cc - 1; -sljit_s32 locals_size = 2 * SSIZE_OF(sw); -BOOL set_recursive_head = FALSE; -BOOL set_capture_last = FALSE; -BOOL set_mark = FALSE; /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ while (cc < ccend) @@ -1165,41 +1132,22 @@ while (cc < ccend) cc += 1; break; - case OP_TYPEUPTO: - case OP_TYPEEXACT: - if (cc[1 + IMM2_SIZE] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw)) - locals_size = 3 * SSIZE_OF(sw); - cc += (2 + IMM2_SIZE) - 1; - break; - - case OP_TYPEPOSSTAR: - case OP_TYPEPOSPLUS: - case OP_TYPEPOSQUERY: - if (cc[1] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw)) - locals_size = 3 * SSIZE_OF(sw); - cc += 2 - 1; - break; - - case OP_TYPEPOSUPTO: -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf && locals_size <= 3 * SSIZE_OF(sw)) - locals_size = 3 * SSIZE_OF(sw); -#endif - if (cc[1 + IMM2_SIZE] == OP_EXTUNI && locals_size <= 3 * SSIZE_OF(sw)) - locals_size = 3 * SSIZE_OF(sw); - cc += (2 + IMM2_SIZE) - 1; - break; - case OP_REFI: +#ifdef SUPPORT_UNICODE + if (common->iref_ptr == 0) + { + common->iref_ptr = common->ovector_start; + common->ovector_start += 3 * sizeof(sljit_sw); + } +#endif /* SUPPORT_UNICODE */ + /* Fall through. */ case OP_REF: - locals_size = ref_update_local_size(common, cc, locals_size); common->optimized_cbracket[GET2(cc, 1)] = 0; - cc += PRIV(OP_lengths)[*cc]; + cc += 1 + IMM2_SIZE; break; case OP_ASSERT_NA: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: slot = bracketend(cc); if (slot > assert_na_end) assert_na_end = slot; @@ -1226,10 +1174,8 @@ while (cc < ccend) cc += 1 + IMM2_SIZE; break; - case OP_DNREFI: case OP_DNREF: - locals_size = ref_update_local_size(common, cc, locals_size); - /* Fall through */ + case OP_DNREFI: case OP_DNCREF: count = GET2(cc, 1 + IMM2_SIZE); slot = common->name_table + GET2(cc, 1) * common->name_entry_size; @@ -1238,18 +1184,26 @@ while (cc < ccend) common->optimized_cbracket[GET2(slot, 0)] = 0; slot += common->name_entry_size; } - cc += PRIV(OP_lengths)[*cc]; + cc += 1 + 2 * IMM2_SIZE; break; case OP_RECURSE: /* Set its value only once. */ - set_recursive_head = TRUE; + if (common->recursive_head_ptr == 0) + { + common->recursive_head_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } cc += 1 + LINK_SIZE; break; case OP_CALLOUT: case OP_CALLOUT_STR: - set_capture_last = TRUE; + if (common->capture_last_ptr == 0) + { + common->capture_last_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE); break; @@ -1267,8 +1221,15 @@ while (cc < ccend) case OP_COMMIT_ARG: case OP_PRUNE_ARG: + if (cc < assert_na_end) + return FALSE; + /* Fall through */ case OP_MARK: - set_mark = TRUE; + if (common->mark_ptr == 0) + { + common->mark_ptr = common->ovector_start; + common->ovector_start += sizeof(sljit_sw); + } cc += 1 + 2 + cc[1]; break; @@ -1281,6 +1242,8 @@ while (cc < ccend) case OP_SKIP: if (cc < assert_back_end) common->has_skip_in_assert_back = TRUE; + if (cc < assert_na_end) + return FALSE; cc += 1; break; @@ -1289,31 +1252,19 @@ while (cc < ccend) common->has_skip_arg = TRUE; if (cc < assert_back_end) common->has_skip_in_assert_back = TRUE; + if (cc < assert_na_end) + return FALSE; cc += 1 + 2 + cc[1]; break; + case OP_PRUNE: + case OP_COMMIT: case OP_ASSERT_ACCEPT: if (cc < assert_na_end) return FALSE; cc++; break; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - case OP_CRPOSRANGE: - /* The second value can be 0 for infinite repeats. */ - if (common->utf && GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE) && locals_size <= 3 * SSIZE_OF(sw)) - locals_size = 3 * SSIZE_OF(sw); - cc += 1 + 2 * IMM2_SIZE; - break; - - case OP_POSUPTO: - case OP_POSUPTOI: - case OP_NOTPOSUPTO: - case OP_NOTPOSUPTOI: - if (common->utf && locals_size <= 3 * SSIZE_OF(sw)) - locals_size = 3 * SSIZE_OF(sw); -#endif - /* Fall through */ default: cc = next_opcode(common, cc); if (cc == NULL) @@ -1321,36 +1272,6 @@ while (cc < ccend) break; } } - -SLJIT_ASSERT((locals_size & (SSIZE_OF(sw) - 1)) == 0); -#if defined SLJIT_DEBUG && SLJIT_DEBUG -common->locals_size = locals_size; -#endif - -if (locals_size > 0) - common->ovector_start += locals_size; - -if (set_mark) - { - SLJIT_ASSERT(common->mark_ptr == 0); - common->mark_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - -if (set_recursive_head) - { - SLJIT_ASSERT(common->recursive_head_ptr == 0); - common->recursive_head_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - -if (set_capture_last) - { - SLJIT_ASSERT(common->capture_last_ptr == 0); - common->capture_last_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); - } - return TRUE; } @@ -1591,9 +1512,8 @@ do case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - case OP_ECLASS: accelerated_start = cc; - cc += (*cc >= OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR))); + cc += ((*cc == OP_XCLASS) ? GET(cc, 1) : (unsigned int)(1 + (32 / sizeof(PCRE2_UCHAR)))); #else accelerated_start = cc; cc += (1 + (32 / sizeof(PCRE2_UCHAR))); @@ -1767,7 +1687,7 @@ switch(*cc) if (max == 0) return (*cc == OP_CRRANGE) ? 2 : 1; max -= min; - if (max > (sljit_u32)(*cc == OP_CRRANGE ? 0 : 1)) + if (max > 2) max = 2; return max; @@ -1985,12 +1905,6 @@ while (cc < ccend) bracketlen = 1 + LINK_SIZE; break; - case OP_ASSERT_SCS: - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += 2 * sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE; - break; - case OP_CBRAPOS: case OP_SCBRAPOS: common->private_data_ptrs[cc - common->start] = private_data_ptr; @@ -2048,13 +1962,13 @@ while (cc < ccend) CASE_ITERATOR_TYPE_PRIVATE_DATA_2A size = 1; - if (cc[1] != OP_EXTUNI) + if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) space = 2; break; case OP_TYPEUPTO: size = 1 + IMM2_SIZE; - if (cc[1 + IMM2_SIZE] != OP_EXTUNI) + if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) space = 2; break; @@ -2071,7 +1985,6 @@ while (cc < ccend) #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - case OP_ECLASS: size = GET(cc, 1); space = get_class_iterator_size(cc + size); break; @@ -2287,7 +2200,6 @@ while (cc < ccend) case OP_CLASS: case OP_NCLASS: case OP_XCLASS: - case OP_ECLASS: case OP_CALLOUT: case OP_CALLOUT_STR: @@ -2330,7 +2242,6 @@ if (ccend == NULL) cc = next_opcode(common, cc); } -/* The data is restored by do_revertframes(). */ SLJIT_ASSERT(cc != NULL); while (cc < ccend) switch(*cc) @@ -2605,13 +2516,6 @@ while (cc < ccend) cc += 1 + LINK_SIZE; break; - case OP_ASSERT_SCS: - SLJIT_ASSERT(PRIVATE_DATA(cc) != 0); - if (recurse_check_bit(common, PRIVATE_DATA(cc))) - length += 2; - cc += 1 + LINK_SIZE; - break; - case OP_CBRA: case OP_SCBRA: offset = GET2(cc, 1 + LINK_SIZE); @@ -2719,8 +2623,7 @@ while (cc < ccend) case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - case OP_ECLASS: - size = (*cc >= OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); + size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); #else size = 1 + 32 / (int)sizeof(PCRE2_UCHAR); #endif @@ -2962,14 +2865,6 @@ while (cc < ccend) cc += 1 + LINK_SIZE; break; - case OP_ASSERT_SCS: - private_srcw[0] = PRIVATE_DATA(cc); - private_srcw[1] = private_srcw[0] + sizeof(sljit_sw); - if (recurse_check_bit(common, private_srcw[0])) - private_count = 2; - cc += 1 + LINK_SIZE; - break; - case OP_CBRA: case OP_SCBRA: offset = GET2(cc, 1 + LINK_SIZE); @@ -3110,8 +3005,7 @@ while (cc < ccend) case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - case OP_ECLASS: - i = (*cc >= OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); + i = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR); #else i = 1 + 32 / (int)sizeof(PCRE2_UCHAR); #endif @@ -3246,66 +3140,50 @@ static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_S PCRE2_SPTR end = bracketend(cc); BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; -/* Assert captures *THEN verb even if it has no alternatives. */ -if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) +/* Assert captures then. */ +if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) current_offset = NULL; -else if (*cc >= OP_ASSERT_NA && *cc <= OP_ASSERT_SCS) - has_alternatives = TRUE; -/* Conditional block does never capture. */ -else if (*cc == OP_COND || *cc == OP_SCOND) +/* Conditional block does not. */ +if (*cc == OP_COND || *cc == OP_SCOND) has_alternatives = FALSE; cc = next_opcode(common, cc); if (has_alternatives) { - switch (*cc) - { - case OP_REVERSE: - case OP_CREF: - cc += 1 + IMM2_SIZE; - break; - case OP_VREVERSE: - case OP_DNCREF: - cc += 1 + 2 * IMM2_SIZE; - break; - } + if (*cc == OP_REVERSE) + cc += 1 + IMM2_SIZE; + else if (*cc == OP_VREVERSE) + cc += 1 + 2 * IMM2_SIZE; current_offset = common->then_offsets + (cc - common->start); } while (cc < end) { - if (*cc >= OP_ASSERT && *cc <= OP_SCOND) - { + if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NA) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) cc = set_then_offsets(common, cc, current_offset); - continue; - } - - if (*cc == OP_ALT && has_alternatives) + else { - cc += 1 + LINK_SIZE; + if (*cc == OP_ALT && has_alternatives) + { + cc += 1 + LINK_SIZE; - if (*cc == OP_REVERSE) - cc += 1 + IMM2_SIZE; - else if (*cc == OP_VREVERSE) - cc += 1 + 2 * IMM2_SIZE; + if (*cc == OP_REVERSE) + cc += 1 + IMM2_SIZE; + else if (*cc == OP_VREVERSE) + cc += 1 + 2 * IMM2_SIZE; - current_offset = common->then_offsets + (cc - common->start); - continue; - } + current_offset = common->then_offsets + (cc - common->start); + continue; + } - if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) - *current_offset = 1; - cc = next_opcode(common, cc); + if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) + *current_offset = 1; + cc = next_opcode(common, cc); + } } -cc = end - 1 - LINK_SIZE; - -/* Ignore repeats. */ -if (*cc == OP_KET && PRIVATE_DATA(cc) != 0) - end += PRIVATE_DATA(cc + 1); - return end; } @@ -3391,12 +3269,8 @@ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * SSIZE_OF(sw)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); -#if defined SLJIT_DEBUG && SLJIT_DEBUG -SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); -/* These two are also used by the stackalloc calls. */ -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, TMP1, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, TMP1, 0); -#endif +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); #endif add_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0)); } @@ -5715,38 +5589,11 @@ if (last) chars->last_count++; } -/* Value can be increased if needed. Patterns -such as /(a|){33}b/ can exhaust the stack. - -Note: /(a|){29}b/ already stops scan_prefix() -because it reaches the maximum step_count. */ -#define SCAN_PREFIX_STACK_END 32 - -/* -Scan prefix stores the prefix string in the chars array. -The elements of the chars array is either small character -sets or "any" (count is set to 255). - -Examples (the chars array is represented by a simple regex): - -/(abc|xbyd)/ prefix: /[ax]b[cy]/ (length: 3) -/a[a-z]b+c/ prefix: a.b (length: 3) -/ab?cd/ prefix: a[bc][cd] (length: 3) -/(ab|cd)|(ef|gh)/ prefix: [aceg][bdfh] (length: 2) - -The length is returned by scan_prefix(). The length is -less than or equal than the minimum length of the pattern. -*/ - -static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars) +static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars, int max_chars, sljit_u32 *rec_count) { -fast_forward_char_data *chars_start = chars; -fast_forward_char_data *chars_end = chars + MAX_N_CHARS; -PCRE2_SPTR cc_stack[SCAN_PREFIX_STACK_END]; -fast_forward_char_data *chars_stack[SCAN_PREFIX_STACK_END]; -sljit_u8 next_alternative_stack[SCAN_PREFIX_STACK_END]; +/* Recursive function, which scans prefix literals. */ BOOL last, any, class, caseless; -int stack_ptr, step_count, repeat, len, len_save; +int len, repeat, len_save, consumed = 0; sljit_u32 chr; /* Any unicode character. */ sljit_u8 *bytes, *bytes_end, byte; PCRE2_SPTR alternative, cc_save, oc; @@ -5759,44 +5606,11 @@ PCRE2_UCHAR othercase[1]; #endif repeat = 1; -stack_ptr = 0; -step_count = 10000; while (TRUE) { - if (--step_count == 0) + if (*rec_count == 0) return 0; - - SLJIT_ASSERT(chars <= chars_start + MAX_N_CHARS); - - if (chars >= chars_end) - { - if (stack_ptr == 0) - return (int)(chars_end - chars_start); - - --stack_ptr; - cc = cc_stack[stack_ptr]; - chars = chars_stack[stack_ptr]; - - if (chars >= chars_end) - continue; - - if (next_alternative_stack[stack_ptr] != 0) - { - /* When an alternative is processed, the - next alternative is pushed onto the stack. */ - SLJIT_ASSERT(*cc == OP_ALT); - alternative = cc + GET(cc, 1); - if (*alternative == OP_ALT) - { - SLJIT_ASSERT(stack_ptr < SCAN_PREFIX_STACK_END); - SLJIT_ASSERT(chars_stack[stack_ptr] == chars); - SLJIT_ASSERT(next_alternative_stack[stack_ptr] == 1); - cc_stack[stack_ptr] = alternative; - stack_ptr++; - } - cc += 1 + LINK_SIZE; - } - } + (*rec_count)--; last = TRUE; any = FALSE; @@ -5836,7 +5650,6 @@ while (TRUE) case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: cc = bracketend(cc); continue; @@ -5873,17 +5686,9 @@ while (TRUE) #ifdef SUPPORT_UNICODE if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); #endif - if (stack_ptr >= SCAN_PREFIX_STACK_END) - { - chars_end = chars; - continue; - } - - cc_stack[stack_ptr] = cc + len; - chars_stack[stack_ptr] = chars; - next_alternative_stack[stack_ptr] = 0; - stack_ptr++; - + max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count); + if (max_chars == 0) + return consumed; last = FALSE; break; @@ -5901,18 +5706,12 @@ while (TRUE) case OP_CBRA: case OP_CBRAPOS: alternative = cc + GET(cc, 1); - if (*alternative == OP_ALT) + while (*alternative == OP_ALT) { - if (stack_ptr >= SCAN_PREFIX_STACK_END) - { - chars_end = chars; - continue; - } - - cc_stack[stack_ptr] = alternative; - chars_stack[stack_ptr] = chars; - next_alternative_stack[stack_ptr] = 1; - stack_ptr++; + max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count); + if (max_chars == 0) + return consumed; + alternative += GET(alternative, 1); } if (*cc == OP_CBRA || *cc == OP_CBRAPOS) @@ -5923,34 +5722,22 @@ while (TRUE) case OP_CLASS: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE)) - { - chars_end = chars; - continue; - } + return consumed; #endif class = TRUE; break; case OP_NCLASS: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - chars_end = chars; - continue; - } + if (common->utf) return consumed; #endif class = TRUE; break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - case OP_ECLASS: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - chars_end = chars; - continue; - } + if (common->utf) return consumed; #endif any = TRUE; cc += GET(cc, 1); @@ -5960,10 +5747,7 @@ while (TRUE) case OP_DIGIT: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) - { - chars_end = chars; - continue; - } + return consumed; #endif any = TRUE; cc++; @@ -5972,10 +5756,7 @@ while (TRUE) case OP_WHITESPACE: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE)) - { - chars_end = chars; - continue; - } + return consumed; #endif any = TRUE; cc++; @@ -5984,10 +5765,7 @@ while (TRUE) case OP_WORDCHAR: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE)) - { - chars_end = chars; - continue; - } + return consumed; #endif any = TRUE; cc++; @@ -6003,11 +5781,7 @@ while (TRUE) case OP_ANY: case OP_ALLANY: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - chars_end = chars; - continue; - } + if (common->utf) return consumed; #endif any = TRUE; cc++; @@ -6017,11 +5791,7 @@ while (TRUE) case OP_NOTPROP: case OP_PROP: #if PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - chars_end = chars; - continue; - } + if (common->utf) return consumed; #endif any = TRUE; cc += 1 + 2; @@ -6036,11 +5806,7 @@ while (TRUE) case OP_NOTEXACT: case OP_NOTEXACTI: #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { - chars_end = chars; - continue; - } + if (common->utf) return consumed; #endif any = TRUE; repeat = GET2(cc, 1); @@ -6048,20 +5814,21 @@ while (TRUE) break; default: - chars_end = chars; - continue; + return consumed; } - SLJIT_ASSERT(chars < chars_end); - if (any) { do { chars->count = 255; + + consumed++; + if (--max_chars == 0) + return consumed; chars++; } - while (--repeat > 0 && chars < chars_end); + while (--repeat > 0); repeat = 1; continue; @@ -6072,27 +5839,17 @@ while (TRUE) bytes = (sljit_u8*) (cc + 1); cc += 1 + 32 / sizeof(PCRE2_UCHAR); - SLJIT_ASSERT(last == TRUE && repeat == 1); switch (*cc) { - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSQUERY: - last = FALSE; - /* Fall through */ case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPOSSTAR: - if (stack_ptr >= SCAN_PREFIX_STACK_END) - { - chars_end = chars; - continue; - } - - cc_stack[stack_ptr] = ++cc; - chars_stack[stack_ptr] = chars; - next_alternative_stack[stack_ptr] = 0; - stack_ptr++; + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count); + if (max_chars == 0) + return consumed; break; default: @@ -6106,13 +5863,7 @@ while (TRUE) case OP_CRPOSRANGE: repeat = GET2(cc, 1); if (repeat <= 0) - { - chars_end = chars; - continue; - } - - last = (repeat != (int)GET2(cc, 1 + IMM2_SIZE)); - cc += 1 + 2 * IMM2_SIZE; + return consumed; break; } @@ -6147,13 +5898,36 @@ while (TRUE) bytes = bytes_end - 32; } + consumed++; + if (--max_chars == 0) + return consumed; chars++; } - while (--repeat > 0 && chars < chars_end); + while (--repeat > 0); + + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPOSSTAR: + return consumed; + + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + cc++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE)) + return consumed; + cc += 1 + 2 * IMM2_SIZE; + break; + } repeat = 1; - if (last) - chars_end = chars; continue; } @@ -6169,10 +5943,7 @@ while (TRUE) { GETCHAR(chr, cc); if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len) - { - chars_end = chars; - continue; - } + return consumed; } else #endif @@ -6203,6 +5974,7 @@ while (TRUE) do { len--; + consumed++; chr = *cc; add_prefix_char(*cc, chars, len == 0); @@ -6210,13 +5982,15 @@ while (TRUE) if (caseless) add_prefix_char(*oc, chars, len == 0); + if (--max_chars == 0) + return consumed; chars++; cc++; oc++; } - while (len > 0 && chars < chars_end); + while (len > 0); - if (--repeat == 0 || chars >= chars_end) + if (--repeat == 0) break; len = len_save; @@ -6225,7 +5999,7 @@ while (TRUE) repeat = 1; if (last) - chars_end = chars; + return consumed; } } @@ -6395,6 +6169,7 @@ int i, max, from; int range_right = -1, range_len; sljit_u8 *update_table = NULL; BOOL in_range; +sljit_u32 rec_count; for (i = 0; i < MAX_N_CHARS; i++) { @@ -6402,7 +6177,8 @@ for (i = 0; i < MAX_N_CHARS; i++) chars[i].last_count = 0; } -max = scan_prefix(common, common->start, chars); +rec_count = 10000; +max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count); if (max < 1) return FALSE; @@ -6992,7 +6768,8 @@ jump = JUMP(SLJIT_NOT_ZERO /* SIG_LESS */); OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); JUMPHERE(jump); -OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, TMP2, 0); +OP2(SLJIT_SUB, TMP2, 0, SLJIT_IMM, 0, TMP2, 0); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); if (HAS_VIRTUAL_REGISTERS) { OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * SSIZE_OF(sw))); @@ -7034,8 +6811,7 @@ struct sljit_jump *jump; SLJIT_UNUSED_ARG(ucp); SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); -SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); /* Get type of the previous char, and put it to TMP3. */ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); @@ -7104,7 +6880,7 @@ JUMPHERE(skipread); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); check_str_end(common, &skipread_list); -peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCAL1, &invalid_utf2); +peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2); /* Testing char type. This is a code duplication. */ #ifdef SUPPORT_UNICODE @@ -7143,7 +6919,7 @@ else } set_jumps(skipread_list, LABEL()); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_XOR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, TMP3, 0); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); @@ -7152,15 +6928,15 @@ if (common->invalid_utf) { set_jumps(invalid_utf1, LABEL()); - peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCAL1, NULL); + peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, NULL); CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR, valid_utf); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); set_jumps(invalid_utf2, LABEL()); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); } @@ -7541,9 +7317,7 @@ else char2_reg = RETURN_ADDR; } -/* Update ref_update_local_size() when this changes. */ -SLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw)); -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); if (char1_reg == STR_END) @@ -7562,7 +7336,7 @@ if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); } else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS) { @@ -7577,7 +7351,7 @@ else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_ JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } else @@ -7592,7 +7366,7 @@ else JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); } if (char1_reg == STR_END) @@ -7630,12 +7404,10 @@ if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS) opt_type = 2; -/* Update ref_update_local_size() when this changes. */ -SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, char1_reg, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0); if (char2_reg == STACK_TOP) { @@ -7689,7 +7461,7 @@ OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); JUMPTO(SLJIT_NOT_ZERO, label); JUMPHERE(jump); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); if (opt_type == 2) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -7700,253 +7472,1929 @@ if (char2_reg == STACK_TOP) OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0); } -OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); +OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); } -#include "pcre2_jit_char_inc.h" - -static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) +static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, + compare_context *context, jump_list **backtracks) { DEFINE_COMPILER; -struct sljit_jump *jump[4]; +unsigned int othercasebit = 0; +PCRE2_SPTR othercasechar = NULL; +#ifdef SUPPORT_UNICODE +int utflength; +#endif -switch(type) +if (caseless && char_has_othercase(common, cc)) { - case OP_SOD: - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - } + othercasebit = char_get_othercase_bit(common, cc); + SLJIT_ASSERT(othercasebit); + /* Extracting bit difference info. */ +#if PCRE2_CODE_UNIT_WIDTH == 8 + othercasechar = cc + (othercasebit >> 8); + othercasebit &= 0xff; +#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + /* Note that this code only handles characters in the BMP. If there + ever are characters outside the BMP whose othercase differs in only one + bit from itself (there currently are none), this code will need to be + revised for PCRE2_CODE_UNIT_WIDTH == 32. */ + othercasechar = cc + (othercasebit >> 9); + if ((othercasebit & 0x100) != 0) + othercasebit = (othercasebit & 0xff) << 8; else - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); - return cc; + othercasebit &= 0xff; +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ + } - case OP_SOM: - if (HAS_VIRTUAL_REGISTERS) +if (context->sourcereg == -1) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + if (context->length >= 4) + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + else +#endif + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#elif PCRE2_CODE_UNIT_WIDTH == 32 + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ + context->sourcereg = TMP2; + } + +#ifdef SUPPORT_UNICODE +utflength = 1; +if (common->utf && HAS_EXTRALEN(*cc)) + utflength += GET_EXTRALEN(*cc); + +do + { +#endif + + context->length -= IN_UCHARS(1); +#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) + + /* Unaligned read is supported. */ + if (othercasebit != 0 && othercasechar == cc) + { + context->c.asuchars[context->ucharptr] = *cc | othercasebit; + context->oc.asuchars[context->ucharptr] = othercasebit; + } + else + { + context->c.asuchars[context->ucharptr] = *cc; + context->oc.asuchars[context->ucharptr] = 0; + } + context->ucharptr++; + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) +#else + if (context->ucharptr >= 2 || context->length == 0) +#endif + { + if (context->length >= 4) + OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + else if (context->length >= 2) + OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#if PCRE2_CODE_UNIT_WIDTH == 8 + else if (context->length >= 1) + OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + switch(context->ucharptr) + { + case 4 / sizeof(PCRE2_UCHAR): + if (context->oc.asint != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); + break; + + case 2 / sizeof(PCRE2_UCHAR): + if (context->oc.asushort != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); + break; + +#if PCRE2_CODE_UNIT_WIDTH == 8 + case 1: + if (context->oc.asbyte != 0) + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); + break; +#endif + + default: + SLJIT_UNREACHABLE(); + break; + } + context->ucharptr = 0; + } + +#else + + /* Unaligned read is unsupported or in 32 bit mode. */ + if (context->length >= 1) + OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + + context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; + + if (othercasebit != 0 && othercasechar == cc) + { + OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); + } + else + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); + +#endif + + cc++; +#ifdef SUPPORT_UNICODE + utflength--; + } +while (utflength > 0); +#endif + +return cc; +} + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + +#define SET_CHAR_OFFSET(value) \ + if ((value) != charoffset) \ + { \ + if ((value) < charoffset) \ + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \ + else \ + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \ + } \ + charoffset = (value); + +static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr); + +#ifdef SUPPORT_UNICODE +#define XCLASS_SAVE_CHAR 0x001 +#define XCLASS_CHAR_SAVED 0x002 +#define XCLASS_HAS_TYPE 0x004 +#define XCLASS_HAS_SCRIPT 0x008 +#define XCLASS_HAS_SCRIPT_EXTENSION 0x010 +#define XCLASS_HAS_BOOL 0x020 +#define XCLASS_HAS_BIDICL 0x040 +#define XCLASS_NEEDS_UCD (XCLASS_HAS_TYPE | XCLASS_HAS_SCRIPT | XCLASS_HAS_SCRIPT_EXTENSION | XCLASS_HAS_BOOL | XCLASS_HAS_BIDICL) +#define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080 +#define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100 +#define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0 0x200 +#endif /* SUPPORT_UNICODE */ + +static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +jump_list *found = NULL; +jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks; +sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX; +struct sljit_jump *jump = NULL; +PCRE2_SPTR ccbegin; +int compares, invertcmp, numberofcmps; +#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) +BOOL utf = common->utf; +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ + +#ifdef SUPPORT_UNICODE +sljit_u32 unicode_status = 0; +sljit_u32 category_list = 0; +sljit_u32 items; +int typereg = TMP1; +const sljit_u32 *other_cases; +#endif /* SUPPORT_UNICODE */ + +/* Scanning the necessary info. */ +cc++; +ccbegin = cc; +compares = 0; + +if (cc[-1] & XCL_MAP) + { + min = 0; + cc += 32 / sizeof(PCRE2_UCHAR); + } + +while (*cc != XCL_END) + { + compares++; + + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + if (c > max) max = c; + if (c < min) min = c; +#ifdef SUPPORT_UNICODE + unicode_status |= XCLASS_SAVE_CHAR; +#endif /* SUPPORT_UNICODE */ + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + if (c < min) min = c; + GETCHARINCTEST(c, cc); + if (c > max) max = c; +#ifdef SUPPORT_UNICODE + unicode_status |= XCLASS_SAVE_CHAR; +#endif /* SUPPORT_UNICODE */ + } +#ifdef SUPPORT_UNICODE + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + + if (*cc == PT_CLIST && cc[-1] == XCL_PROP) + { + other_cases = PRIV(ucd_caseless_sets) + cc[1]; + while (*other_cases != NOTACHAR) + { + if (*other_cases > max) max = *other_cases; + if (*other_cases < min) min = *other_cases; + other_cases++; + } + } + else + { + max = READ_CHAR_MAX; + min = 0; + } + + items = 0; + + switch(*cc) + { + case PT_ANY: + /* Any either accepts everything or ignored. */ + if (cc[-1] == XCL_PROP) + items = UCPCAT_ALL; + else + compares--; + break; + + case PT_LAMP: + items = UCPCAT3(ucp_Lu, ucp_Ll, ucp_Lt); + break; + + case PT_GC: + items = UCPCAT_RANGE(PRIV(ucp_typerange)[(int)cc[1] * 2], PRIV(ucp_typerange)[(int)cc[1] * 2 + 1]); + break; + + case PT_PC: + items = UCPCAT(cc[1]); + break; + + case PT_WORD: + items = UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N; + break; + + case PT_ALNUM: + items = UCPCAT_L | UCPCAT_N; + break; + + case PT_SCX: + unicode_status |= XCLASS_HAS_SCRIPT_EXTENSION; + if (cc[-1] == XCL_NOTPROP) + { + unicode_status |= XCLASS_SCRIPT_EXTENSION_NOTPROP; + break; + } + compares++; + /* Fall through */ + + case PT_SC: + unicode_status |= XCLASS_HAS_SCRIPT; + break; + + case PT_SPACE: + case PT_PXSPACE: + case PT_PXGRAPH: + case PT_PXPRINT: + case PT_PXPUNCT: + unicode_status |= XCLASS_SAVE_CHAR | XCLASS_HAS_TYPE; + break; + + case PT_CLIST: + case PT_UCNC: + case PT_PXXDIGIT: + unicode_status |= XCLASS_SAVE_CHAR; + break; + + case PT_BOOL: + unicode_status |= XCLASS_HAS_BOOL; + break; + + case PT_BIDICL: + unicode_status |= XCLASS_HAS_BIDICL; + break; + + default: + SLJIT_UNREACHABLE(); + break; + } + + if (items > 0) + { + if (cc[-1] == XCL_NOTPROP) + items ^= UCPCAT_ALL; + category_list |= items; + unicode_status |= XCLASS_HAS_TYPE; + compares--; + } + + cc += 2; + } +#endif /* SUPPORT_UNICODE */ + } + +#ifdef SUPPORT_UNICODE +if (category_list == UCPCAT_ALL) + { + /* All characters are accepted, same as dotall. */ + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list == backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } + +if (compares == 0 && category_list == 0) + { + /* No characters are accepted, same as (*F) or dotall. */ + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list != backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } +#else /* !SUPPORT_UNICODE */ +SLJIT_ASSERT(compares > 0); +#endif /* SUPPORT_UNICODE */ + +/* We are not necessary in utf mode even in 8 bit mode. */ +cc = ccbegin; +if ((cc[-1] & XCL_NOT) != 0) + read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); +else + { +#ifdef SUPPORT_UNICODE + read_char(common, min, max, (unicode_status & XCLASS_NEEDS_UCD) ? backtracks : NULL, 0); +#else /* !SUPPORT_UNICODE */ + read_char(common, min, max, NULL, 0); +#endif /* SUPPORT_UNICODE */ + } + +if ((cc[-1] & XCL_HASPROP) == 0) + { + if ((cc[-1] & XCL_MAP) != 0) + { + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (!optimize_class(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found)) + { + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); + add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO)); + } + + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump); + + cc += 32 / sizeof(PCRE2_UCHAR); + } + else + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); + add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min)); + } + } +else if ((cc[-1] & XCL_MAP) != 0) + { + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); +#ifdef SUPPORT_UNICODE + unicode_status |= XCLASS_CHAR_SAVED; +#endif /* SUPPORT_UNICODE */ + if (!optimize_class(common, (const sljit_u8 *)cc, FALSE, TRUE, list)) + { +#if PCRE2_CODE_UNIT_WIDTH == 8 + jump = NULL; + if (common->utf) +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); + add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf) +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + JUMPHERE(jump); + } + + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + cc += 32 / sizeof(PCRE2_UCHAR); + } + +#ifdef SUPPORT_UNICODE +if (unicode_status & XCLASS_NEEDS_UCD) + { + if ((unicode_status & (XCLASS_SAVE_CHAR | XCLASS_CHAR_SAVED)) == XCLASS_SAVE_CHAR) + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); + +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (!common->utf) + { + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR); + JUMPHERE(jump); + } +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ + + OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); + OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); + OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + + ccbegin = cc; + + if (category_list != 0) + compares++; + + if (unicode_status & XCLASS_HAS_BIDICL) + { + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BIDICLASS_SHIFT); + + while (*cc != XCL_END) + { + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + GETCHARINCTEST(c, cc); + } + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + if (*cc == PT_BIDICL) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]); + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + cc += 2; + } + } + + cc = ccbegin; + } + + if (unicode_status & XCLASS_HAS_BOOL) + { + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, bprops)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BPROPS_MASK); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); + + while (*cc != XCL_END) + { + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + GETCHARINCTEST(c, cc); + } + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + if (*cc == PT_BOOL) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + } + cc += 2; + } + } + + cc = ccbegin; + } + + if (unicode_status & XCLASS_HAS_SCRIPT) + { + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + + while (*cc != XCL_END) + { + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + GETCHARINCTEST(c, cc); + } + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + switch (*cc) + { + case PT_SCX: + if (cc[-1] == XCL_NOTPROP) + break; + /* Fall through */ + + case PT_SC: + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + + add_jump(compiler, compares > 0 ? list : backtracks, CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1])); + } + cc += 2; + } + } + + cc = ccbegin; + } + + if (unicode_status & XCLASS_HAS_SCRIPT_EXTENSION) + { + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_SCRIPTX_MASK); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); + + if (unicode_status & XCLASS_SCRIPT_EXTENSION_NOTPROP) + { + if (unicode_status & XCLASS_HAS_TYPE) + { + if (unicode_status & XCLASS_SAVE_CHAR) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP2, 0); + unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0; + } + else + { + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0); + unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR; + } + } + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + } + + while (*cc != XCL_END) + { + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + GETCHARINCTEST(c, cc); + } + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + if (*cc == PT_SCX) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + + jump = NULL; + if (cc[-1] == XCL_NOTPROP) + { + jump = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, (int)cc[1]); + if (invertcmp) + { + add_jump(compiler, backtracks, jump); + jump = NULL; + } + invertcmp ^= 0x1; + } + + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f))); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + + if (jump != NULL) + JUMPHERE(jump); + } + cc += 2; + } + } + + if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + else if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR) + OP1(SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0); + cc = ccbegin; + } + + if (unicode_status & XCLASS_SAVE_CHAR) + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + + if (unicode_status & XCLASS_HAS_TYPE) + { + if (unicode_status & XCLASS_SAVE_CHAR) + typereg = RETURN_ADDR; + + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP2(SLJIT_SHL, typereg, 0, SLJIT_IMM, 1, TMP2, 0); + + if (category_list > 0) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, category_list); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + } + } + } +#endif /* SUPPORT_UNICODE */ + +/* Generating code. */ +charoffset = 0; +numberofcmps = 0; + +while (*cc != XCL_END) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + jump = NULL; + + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + numberofcmps = 0; + } + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + SET_CHAR_OFFSET(c); + GETCHARINCTEST(c, cc); + + if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) + { + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + numberofcmps++; + } + else if (numberofcmps > 0) + { + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + numberofcmps = 0; + } + else + { + jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); + numberofcmps = 0; + } + } +#ifdef SUPPORT_UNICODE + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + if (*cc == XCL_NOTPROP) + invertcmp ^= 0x1; + cc++; + switch(*cc) + { + case PT_ANY: + case PT_LAMP: + case PT_GC: + case PT_PC: + case PT_SC: + case PT_SCX: + case PT_BOOL: + case PT_BIDICL: + case PT_WORD: + case PT_ALNUM: + compares++; + /* Already handled. */ + break; + + case PT_SPACE: + case PT_PXSPACE: + SET_CHAR_OFFSET(9); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xd - 0x9); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_CLIST: + other_cases = PRIV(ucd_caseless_sets) + cc[1]; + + /* At least three characters are required. + Otherwise this case would be handled by the normal code path. */ + SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR); + SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); + + /* Optimizing character pairs, if their difference is power of 2. */ + if (is_powerof2(other_cases[1] ^ other_cases[0])) + { + if (charoffset == 0) + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + else + { + OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + } + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[1]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + other_cases += 2; + } + else if (is_powerof2(other_cases[2] ^ other_cases[1])) + { + if (charoffset == 0) + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]); + else + { + OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); + OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); + } + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[2]); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); + OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); + + other_cases += 3; + } + else + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + } + + while (*other_cases != NOTACHAR) + { + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); + OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL); + } + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_UCNC: + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + SET_CHAR_OFFSET(0xa0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + SET_CHAR_OFFSET(0); + OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_PXGRAPH: + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + + c = charoffset; + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + + JUMPHERE(jump); + jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPRINT: + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT2(ucp_Zl, ucp_Zp)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + + c = charoffset; + /* In case of ucp_Cf, we overwrite the result. */ + SET_CHAR_OFFSET(0x2066); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + + JUMPHERE(jump); + jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); + break; + + case PT_PXPUNCT: + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Sc, ucp_So)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); + + SET_CHAR_OFFSET(0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f); + OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL); + + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Pc, ucp_Ps)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_PXXDIGIT: + SET_CHAR_OFFSET(CHAR_A); + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, ~0x20); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP2, 0, SLJIT_IMM, CHAR_F - CHAR_A); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(CHAR_0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_9 - CHAR_0); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff10); + + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff19 - 0xff10); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff21); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff26 - 0xff21); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff41); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff41); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + + JUMPHERE(jump); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + default: + SLJIT_UNREACHABLE(); + break; + } + cc += 2; + } +#endif /* SUPPORT_UNICODE */ + + if (jump != NULL) + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + +SLJIT_ASSERT(compares == 0); +if (found != NULL) + set_jumps(found, LABEL()); +} + +#undef SET_TYPE_OFFSET +#undef SET_CHAR_OFFSET + +#endif + +static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +struct sljit_jump *jump[4]; + +switch(type) + { + case OP_SOD: + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } + else + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_SOM: + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + } + else + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + add_jump(compiler, (type == OP_NOT_WORD_BOUNDARY || type == OP_WORD_BOUNDARY) ? &common->wordboundary : &common->ucp_wordboundary, JUMP(SLJIT_FAST_CALL)); +#ifdef SUPPORT_UNICODE + if (common->invalid_utf) + { + add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + return cc; + } +#endif /* SUPPORT_UNICODE */ + sljit_set_current_flags(compiler, SLJIT_SET_Z); + add_jump(compiler, backtracks, JUMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + + case OP_EODN: + /* Requires rather complex checks. */ + jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, STR_END, 0); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else if (common->nltype == NLTYPE_FIXED) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } + else + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, TMP2, 0, STR_END, 0); + jump[2] = JUMP(SLJIT_GREATER); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */); + /* Equal. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[1]); + if (common->nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + sljit_set_current_flags(compiler, SLJIT_SET_Z); + add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + } + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + } + JUMPHERE(jump[0]); + if (common->mode != PCRE2_JIT_COMPLETE) + check_partial(common, TRUE); + return cc; + + case OP_EOD: + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + if (common->mode != PCRE2_JIT_COMPLETE) + check_partial(common, TRUE); + return cc; + + case OP_DOLL: + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + } + else + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + + if (!common->endonly) + compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); + else + { + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); + } + return cc; + + case OP_DOLLM: + jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + } + else + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + check_partial(common, FALSE); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); + /* STR_PTR = STR_END - IN_UCHARS(1) */ + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + peek_char(common, common->nlmax, TMP3, 0, NULL); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + + case OP_CIRC: + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + } + return cc; + + case OP_CIRCM: + /* TMP2 might be used by peek_char_back. */ + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); + OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + } + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (!common->alt_circumflex) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 0)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + peek_char_back(common, common->nlmax, backtracks); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + } +SLJIT_UNREACHABLE(); +return cc; +} + +#ifdef SUPPORT_UNICODE + +#if PCRE2_CODE_UNIT_WIDTH != 32 + +/* The code in this function copies the logic of the interpreter function that +is defined in the pcre2_extuni.c source. If that code is updated, this +function, and those below it, must be kept in step (note by PH, June 2024). */ + +static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc) +{ +PCRE2_SPTR start_subject = args->begin; +PCRE2_SPTR end_subject = args->end; +int lgb, rgb, ricount; +PCRE2_SPTR prevcc, endcc, bptr; +BOOL first = TRUE; +BOOL was_ep_ZWJ = FALSE; +uint32_t c; + +prevcc = cc; +endcc = NULL; +do + { + GETCHARINC(c, cc); + rgb = UCD_GRAPHBREAK(c); + + if (first) + { + lgb = rgb; + endcc = cc; + first = FALSE; + continue; + } + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; + + /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was + preceded by Extended Pictographic. */ + + if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) + break; + + /* Not breaking between Regional Indicators is allowed only if there + are an even number of preceding RIs. */ + + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) + { + ricount = 0; + bptr = prevcc; + + /* bptr is pointing to the left-hand character */ + while (bptr > start_subject) + { + bptr--; + BACKCHAR(bptr); + GETCHAR(c, bptr); + + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) + break; + + ricount++; + } + + if ((ricount & 1) != 0) break; /* Grapheme break required */ + } + + /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in + between; see next statement). */ + + was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); + + /* If Extend follows Extended_Pictographic, do not update lgb; this allows + any number of them before a following ZWJ. */ + + if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) + lgb = rgb; + + prevcc = endcc; + endcc = cc; + } +while (cc < end_subject); + +return endcc; +} + +#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ + +/* The code in this function copies the logic of the interpreter function that +is defined in the pcre2_extuni.c source. If that code is updated, this +function, and the one below it, must be kept in step (note by PH, June 2024). */ + +static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc) +{ +PCRE2_SPTR start_subject = args->begin; +PCRE2_SPTR end_subject = args->end; +int lgb, rgb, ricount; +PCRE2_SPTR prevcc, endcc, bptr; +BOOL first = TRUE; +BOOL was_ep_ZWJ = FALSE; +uint32_t c; + +prevcc = cc; +endcc = NULL; +do + { + GETCHARINC_INVALID(c, cc, end_subject, break); + rgb = UCD_GRAPHBREAK(c); + + if (first) + { + lgb = rgb; + endcc = cc; + first = FALSE; + continue; + } + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; + + /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was + preceded by Extended Pictographic. */ + + if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) + break; + + /* Not breaking between Regional Indicators is allowed only if there + are an even number of preceding RIs. */ + + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) + { + ricount = 0; + bptr = prevcc; + + /* bptr is pointing to the left-hand character */ + while (bptr > start_subject) + { + GETCHARBACK_INVALID(c, bptr, start_subject, break); + + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) + break; + + ricount++; + } + + if ((ricount & 1) != 0) + break; /* Grapheme break required */ + } + + /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in + between; see next statement). */ + + was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); + + /* If Extend follows Extended_Pictographic, do not update lgb; this allows + any number of them before a following ZWJ. */ + + if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) + lgb = rgb; + + prevcc = endcc; + endcc = cc; + } +while (cc < end_subject); + +return endcc; +} + +/* The code in this function copies the logic of the interpreter function that +is defined in the pcre2_extuni.c source. If that code is updated, this +function must be kept in step (note by PH, June 2024). */ + +static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc) +{ +PCRE2_SPTR start_subject = args->begin; +PCRE2_SPTR end_subject = args->end; +int lgb, rgb, ricount; +PCRE2_SPTR bptr; +uint32_t c; +BOOL was_ep_ZWJ = FALSE; + +/* Patch by PH */ +/* GETCHARINC(c, cc); */ +c = *cc++; + +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (c >= 0x110000) + return cc; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ +lgb = UCD_GRAPHBREAK(c); + +while (cc < end_subject) + { + c = *cc; +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x110000) + break; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ + rgb = UCD_GRAPHBREAK(c); + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; + + /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was + preceded by Extended Pictographic. */ + + if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ) + break; + + /* Not breaking between Regional Indicators is allowed only if there + are an even number of preceding RIs. */ + + if (lgb == ucp_gbRegional_Indicator && rgb == ucp_gbRegional_Indicator) + { + ricount = 0; + bptr = cc - 1; + + /* bptr is pointing to the left-hand character */ + while (bptr > start_subject) + { + bptr--; + c = *bptr; +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x110000) + break; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ + + if (UCD_GRAPHBREAK(c) != ucp_gbRegional_Indicator) break; + + ricount++; + } + + if ((ricount & 1) != 0) + break; /* Grapheme break required */ + } + + /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in + between; see next statement). */ + + was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ); + + /* If Extend follows Extended_Pictographic, do not update lgb; this allows + any number of them before a following ZWJ. */ + + if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) + lgb = rgb; + + cc++; + } + +return cc; +} + +#endif /* SUPPORT_UNICODE */ + +static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr) +{ +DEFINE_COMPILER; +int length; +unsigned int c, oc, bit; +compare_context context; +struct sljit_jump *jump[3]; +jump_list *end_list; +#ifdef SUPPORT_UNICODE +PCRE2_UCHAR propdata[5]; +#endif /* SUPPORT_UNICODE */ + +switch(type) + { + case OP_NOT_DIGIT: + case OP_DIGIT: + /* Digits are usually 0-9, so it is worth to optimize them. */ + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE)) + read_char7_type(common, backtracks, type == OP_NOT_DIGIT); + else +#endif + read_char8_type(common, backtracks, type == OP_NOT_DIGIT); + /* Flip the starting bit in the negative case. */ + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_digit); + add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_NOT_WHITESPACE: + case OP_WHITESPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE)) + read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE); + else +#endif + read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_space); + add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_NOT_WORDCHAR: + case OP_WORDCHAR: + if (check_str_ptr) + detect_partial_match(common, backtracks); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE)) + read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR); + else +#endif + read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_word); + add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); + return cc; + + case OP_ANY: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + end_list = NULL; + if (common->mode != PCRE2_JIT_PARTIAL_HARD) + add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + else + check_str_end(common, &end_list); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); + set_jumps(end_list, LABEL()); + JUMPHERE(jump[0]); } else - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + check_newlinechar(common, common->nltype, backtracks, TRUE); return cc; - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_NOT_UCP_WORD_BOUNDARY: - case OP_UCP_WORD_BOUNDARY: - add_jump(compiler, (type == OP_NOT_WORD_BOUNDARY || type == OP_WORD_BOUNDARY) ? &common->wordboundary : &common->ucp_wordboundary, JUMP(SLJIT_FAST_CALL)); + case OP_ALLANY: + if (check_str_ptr) + detect_partial_match(common, backtracks); #ifdef SUPPORT_UNICODE - if (common->invalid_utf) + if (common->utf && common->invalid_utf) { - add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); return cc; } #endif /* SUPPORT_UNICODE */ + + skip_valid_char(common); + return cc; + + case OP_ANYBYTE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + return cc; + +#ifdef SUPPORT_UNICODE + case OP_NOTPROP: + case OP_PROP: + propdata[0] = XCL_HASPROP; + propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; + propdata[2] = cc[0]; + propdata[3] = cc[1]; + propdata[4] = XCL_END; + if (check_str_ptr) + detect_partial_match(common, backtracks); + compile_xclass_matchingpath(common, propdata, backtracks); + return cc + 2; +#endif + + case OP_ANYNL: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0); + jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + /* We don't need to handle soft partial matching case. */ + end_list = NULL; + if (common->mode != PCRE2_JIT_PARTIAL_HARD) + add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + else + check_str_end(common, &end_list); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[2] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[0]); + check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); + set_jumps(end_list, LABEL()); + JUMPHERE(jump[1]); + JUMPHERE(jump[2]); + return cc; + + case OP_NOT_HSPACE: + case OP_HSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + if (type == OP_NOT_HSPACE) + read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0x9, 0x3000, NULL, 0); + + add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); return cc; - case OP_EODN: - /* Requires rather complex checks. */ - jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - else - { - jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); - OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, STR_END, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); - } - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else if (common->nltype == NLTYPE_FIXED) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); - } + case OP_NOT_VSPACE: + case OP_VSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + if (type == OP_NOT_VSPACE) + read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR); else - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, TMP2, 0, STR_END, 0); - jump[2] = JUMP(SLJIT_GREATER); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */); - /* Equal. */ - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + read_char(common, 0xa, 0x2029, NULL, 0); - JUMPHERE(jump[1]); - if (common->nltype == NLTYPE_ANYCRLF) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); - } - else - { - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); - add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); - sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - } - JUMPHERE(jump[2]); - JUMPHERE(jump[3]); - } - JUMPHERE(jump[0]); - if (common->mode != PCRE2_JIT_COMPLETE) - check_partial(common, TRUE); + add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); + sljit_set_current_flags(compiler, SLJIT_SET_Z); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); return cc; - case OP_EOD: - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - if (common->mode != PCRE2_JIT_COMPLETE) +#ifdef SUPPORT_UNICODE + case OP_EXTUNI: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); + OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); + +#if PCRE2_CODE_UNIT_WIDTH != 32 + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, + common->utf ? (common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_utf)) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); +#else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, + common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); +#endif + + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + + if (common->mode == PCRE2_JIT_PARTIAL_HARD) + { + jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0); + /* Since we successfully read a char above, partial matching must occure. */ check_partial(common, TRUE); + JUMPHERE(jump[0]); + } return cc; +#endif - case OP_DOLL: - if (HAS_VIRTUAL_REGISTERS) + case OP_CHAR: + case OP_CHARI: + length = 1; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); +#endif + + if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE) + detect_partial_match(common, backtracks); + + if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) { - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); + if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); + + context.length = IN_UCHARS(length); + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); } - else - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - if (!common->endonly) - compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); - else +#ifdef SUPPORT_UNICODE + if (common->utf) { - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - check_partial(common, FALSE); + GETCHAR(c, cc); } - return cc; + else +#endif + c = *cc; - case OP_DOLLM: - jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - if (HAS_VIRTUAL_REGISTERS) + SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc)); + + if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + + oc = char_othercase(common, c); + read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0); + + SLJIT_ASSERT(!is_powerof2(c ^ oc)); + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) { - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc); + SELECT(SLJIT_EQUAL, TMP1, SLJIT_IMM, c, TMP1); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); } else - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - check_partial(common, FALSE); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); + { + jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + JUMPHERE(jump[0]); + } + return cc + length; - if (common->nltype == NLTYPE_FIXED && common->newline > 255) + case OP_NOT: + case OP_NOTI: + if (check_str_ptr) + detect_partial_match(common, backtracks); + + length = 1; +#ifdef SUPPORT_UNICODE + if (common->utf) { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); - else +#if PCRE2_CODE_UNIT_WIDTH == 8 + c = *cc; + if (c < 128 && !common->invalid_utf) { - jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); - /* STR_PTR = STR_END - IN_UCHARS(1) */ - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + if (type == OP_NOT || !char_has_othercase(common, cc)) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + else + { + /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ + OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); + } + /* Skip the variable-length character. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + JUMPHERE(jump[0]); + return cc + 1; + } + else +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + { + GETCHARLEN(c, cc, length); } - - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else - { - peek_char(common, common->nlmax, TMP3, 0, NULL); - check_newlinechar(common, common->nltype, backtracks, FALSE); } - JUMPHERE(jump[0]); - return cc; + else +#endif /* SUPPORT_UNICODE */ + c = *cc; - case OP_CIRC: - if (HAS_VIRTUAL_REGISTERS) + if (type == OP_NOT || !char_has_othercase(common, cc)) { - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); } else { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); + oc = char_othercase(common, c); + read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR); + bit = c ^ oc; + if (is_powerof2(bit)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); + } + else + { + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + } } - return cc; + return cc + length; - case OP_CIRCM: - /* TMP2 might be used by peek_char_back. */ - if (HAS_VIRTUAL_REGISTERS) + case OP_CLASS: + case OP_NCLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255; + if (type == OP_NCLASS) + read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0, bit, NULL, 0); +#else + if (type == OP_NCLASS) + read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0, 255, NULL, 0); +#endif + + if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks)) + return cc + 32 / sizeof(PCRE2_UCHAR); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + jump[0] = NULL; + if (common->utf) { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit); + if (type == OP_CLASS) + { + add_jump(compiler, backtracks, jump[0]); + jump[0] = NULL; + } } - else +#elif PCRE2_CODE_UNIT_WIDTH != 8 + jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + if (type == OP_CLASS) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); - OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, jump[0]); + jump[0] = NULL; } - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO)); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ - if (!common->alt_circumflex) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0); + add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 + if (jump[0] != NULL) + JUMPHERE(jump[0]); +#endif + return cc + 32 / sizeof(PCRE2_UCHAR); + +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + case OP_XCLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); + compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); + return cc + GET(cc, 0) - 1; +#endif + } +SLJIT_UNREACHABLE(); +return cc; +} + +static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks) +{ +/* This function consumes at least one input character. */ +/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ +DEFINE_COMPILER; +PCRE2_SPTR ccbegin = cc; +compare_context context; +int size; + +context.length = 0; +do + { + if (cc >= ccend) + break; + + if (*cc == OP_CHAR) { - OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 0)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + size = 1; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); +#endif } - else + else if (*cc == OP_CHARI) { - peek_char_back(common, common->nlmax, backtracks); - check_newlinechar(common, common->nltype, backtracks, FALSE); + size = 1; +#ifdef SUPPORT_UNICODE + if (common->utf) + { + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; + else if (HAS_EXTRALEN(cc[1])) + size += GET_EXTRALEN(cc[1]); + } + else +#endif + if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) + size = 0; } - JUMPHERE(jump[0]); + else + size = 0; + + cc += 1 + size; + context.length += IN_UCHARS(size); + } +while (size > 0 && context.length <= 128); + +cc = ccbegin; +if (context.length > 0) + { + /* We have a fixed-length byte sequence. */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); + + context.sourcereg = -1; +#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED + context.ucharptr = 0; +#endif + do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); return cc; } -SLJIT_UNREACHABLE(); -return cc; + +/* A non-fixed length character will be checked if length == 0. */ +return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); } /* Forward definitions. */ @@ -8022,16 +9470,10 @@ struct sljit_jump *nopartial; #if defined SUPPORT_UNICODE struct sljit_label *loop; struct sljit_label *caseless_loop; -struct sljit_jump *turkish_ascii_i = NULL; -struct sljit_jump *turkish_non_ascii_i = NULL; jump_list *no_match = NULL; int source_reg = COUNT_MATCH; int source_end_reg = ARGUMENTS; int char1_reg = STACK_LIMIT; -PCRE2_UCHAR refi_flag = 0; - -if (*cc == OP_REFI || *cc == OP_DNREFI) - refi_flag = cc[PRIV(OP_lengths)[*cc] - 1]; #endif /* SUPPORT_UNICODE */ if (ref) @@ -8046,10 +9488,9 @@ else OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); #if defined SUPPORT_UNICODE -if ((common->utf || common->ucp) && (*cc == OP_REFI || *cc == OP_DNREFI)) +if (common->utf && *cc == OP_REFI) { - /* Update ref_update_local_size() when this changes. */ - SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw)); + SLJIT_ASSERT(common->iref_ptr != 0); if (ref) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); @@ -8059,9 +9500,9 @@ if ((common->utf || common->ucp) && (*cc == OP_REFI || *cc == OP_DNREFI)) if (withchecks && emptyfail) add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, source_reg, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, source_end_reg, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, char1_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr, source_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw), source_end_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2, char1_reg, 0); OP1(SLJIT_MOV, source_reg, 0, TMP1, 0); OP1(SLJIT_MOV, source_end_reg, 0, TMP2, 0); @@ -8085,16 +9526,6 @@ if ((common->utf || common->ucp) && (*cc == OP_REFI || *cc == OP_DNREFI)) CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); - if ((refi_flag & (REFI_FLAG_TURKISH_CASING|REFI_FLAG_CASELESS_RESTRICT)) == - REFI_FLAG_TURKISH_CASING) - { - OP2(SLJIT_OR, SLJIT_TMP_DEST_REG, 0, char1_reg, 0, SLJIT_IMM, 0x20); - turkish_ascii_i = CMP(SLJIT_EQUAL, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 0x69); - - OP2(SLJIT_OR, SLJIT_TMP_DEST_REG, 0, char1_reg, 0, SLJIT_IMM, 0x1); - turkish_non_ascii_i = CMP(SLJIT_EQUAL, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 0x131); - } - OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); @@ -8114,9 +9545,6 @@ if ((common->utf || common->ucp) && (*cc == OP_REFI || *cc == OP_DNREFI)) OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_caseless_sets)); - if (refi_flag & REFI_FLAG_CASELESS_RESTRICT) - add_jump(compiler, &no_match, CMP(SLJIT_LESS | SLJIT_32, SLJIT_MEM1(TMP2), 0, SLJIT_IMM, 128)); - caseless_loop = LABEL(); OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP2), 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(uint32_t)); @@ -8124,52 +9552,30 @@ if ((common->utf || common->ucp) && (*cc == OP_REFI || *cc == OP_DNREFI)) JUMPTO(SLJIT_EQUAL, loop); JUMPTO(SLJIT_LESS, caseless_loop); - if ((refi_flag & (REFI_FLAG_TURKISH_CASING|REFI_FLAG_CASELESS_RESTRICT)) == - REFI_FLAG_TURKISH_CASING) - { - add_jump(compiler, &no_match, JUMP(SLJIT_JUMP)); - JUMPHERE(turkish_ascii_i); - - OP2(SLJIT_LSHR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 5); - OP2(SLJIT_AND, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); - OP2(SLJIT_XOR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); - OP2(SLJIT_ADD, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 0x130); - CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); - - add_jump(compiler, &no_match, JUMP(SLJIT_JUMP)); - JUMPHERE(turkish_non_ascii_i); - - OP2(SLJIT_AND, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); - OP2(SLJIT_XOR, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 1); - OP2(SLJIT_SHL, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 5); - OP2(SLJIT_ADD, char1_reg, 0, char1_reg, 0, SLJIT_IMM, 0x49); - CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); - } - set_jumps(no_match, LABEL()); if (common->mode == PCRE2_JIT_COMPLETE) JUMPHERE(partial); - OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); - OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); - OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); if (common->mode != PCRE2_JIT_COMPLETE) { JUMPHERE(partial); - OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); - OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); - OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); check_partial(common, FALSE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); } JUMPHERE(jump); - OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); - OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); - OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); return; } else @@ -8188,7 +9594,7 @@ else if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, backtracks, partial); - add_jump(compiler, (*cc == OP_REF || *cc == OP_DNREF) ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); if (common->mode != PCRE2_JIT_COMPLETE) @@ -8200,7 +9606,7 @@ else OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); - add_jump(compiler, (*cc == OP_REF || *cc == OP_DNREF) ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); JUMPHERE(partial); check_partial(common, FALSE); @@ -8224,7 +9630,6 @@ DEFINE_COMPILER; BOOL ref = (*cc == OP_REF || *cc == OP_REFI); backtrack_common *backtrack; PCRE2_UCHAR type; -int local_start = LOCAL2; int offset = 0; struct sljit_label *label; struct sljit_jump *zerolength; @@ -8239,21 +9644,9 @@ if (ref) offset = GET2(cc, 1) << 1; else cc += IMM2_SIZE; - -if (*ccbegin == OP_REFI || *ccbegin == OP_DNREFI) - { - cc += 1; -#ifdef SUPPORT_UNICODE - if (common->utf || common->ucp) - local_start = LOCAL3; -#endif - } - type = cc[1 + IMM2_SIZE]; SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even); -/* Update ref_update_local_size() when this changes. */ -SLJIT_ASSERT(local_start + 2 * SSIZE_OF(sw) <= (int)LOCAL0 + common->locals_size); minimize = (type & 0x1) != 0; switch(type) { @@ -8305,7 +9698,7 @@ if (!minimize) { compile_dnref_search(common, ccbegin, NULL); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); } /* Restore if not zero length. */ @@ -8328,24 +9721,24 @@ if (!minimize) { compile_dnref_search(common, ccbegin, &backtrack->own_backtracks); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); } } if (min > 1 || max > 1) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start, SLJIT_IMM, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); label = LABEL(); if (!ref) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), local_start + SSIZE_OF(sw)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, FALSE, FALSE); if (min > 1 || max > 1) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), local_start); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), local_start, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); if (min > 1) CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label); if (max > 1) @@ -8613,13 +10006,12 @@ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_pt SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); /* Needed to save important temporary registers. */ -SLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); /* SLJIT_R0 = arguments */ OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0); GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START); sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS3(32, W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_callout_jit)); -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); free_stack(common, callout_arg_size); /* Check return value. */ @@ -8787,7 +10179,6 @@ jump_list **found; /* Saving previous accept variables. */ BOOL save_local_quit_available = common->local_quit_available; BOOL save_in_positive_assertion = common->in_positive_assertion; -sljit_s32 save_restore_end_ptr = common->restore_end_ptr; then_trap_backtrack *save_then_trap = common->then_trap; struct sljit_label *save_quit_label = common->quit_label; struct sljit_label *save_accept_label = common->accept_label; @@ -8895,7 +10286,6 @@ if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)) { /* Control verbs cannot escape from these asserts. */ local_quit_available = TRUE; - common->restore_end_ptr = 0; common->local_quit_available = TRUE; common->quit_label = NULL; common->quit = NULL; @@ -8931,7 +10321,6 @@ while (1) common->quit = save_quit; } common->in_positive_assertion = save_in_positive_assertion; - common->restore_end_ptr = save_restore_end_ptr; common->then_trap = save_then_trap; common->accept_label = save_accept_label; common->positive_assertion_quit = save_positive_assertion_quit; @@ -9029,7 +10418,6 @@ while (1) common->quit = save_quit; } common->in_positive_assertion = save_in_positive_assertion; - common->restore_end_ptr = save_restore_end_ptr; common->then_trap = save_then_trap; common->accept_label = save_accept_label; common->positive_assertion_quit = save_positive_assertion_quit; @@ -9169,8 +10557,7 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { JUMPTO(SLJIT_JUMP, backtrack->matchingpath); JUMPHERE(brajump); - SLJIT_ASSERT(framesize != 0); - if (framesize > 0) + if (framesize >= 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -9235,9 +10622,7 @@ if (local_quit_available) common->quit_label = save_quit_label; common->quit = save_quit; } - common->in_positive_assertion = save_in_positive_assertion; -common->restore_end_ptr = save_restore_end_ptr; common->then_trap = save_then_trap; common->accept_label = save_accept_label; common->positive_assertion_quit = save_positive_assertion_quit; @@ -9428,7 +10813,6 @@ BOOL needs_control_head = FALSE; BOOL has_vreverse = FALSE; struct sljit_jump *jump; struct sljit_jump *skip; -jump_list *jumplist; struct sljit_label *rmax_label = NULL; struct sljit_jump *braminzero = NULL; @@ -9491,8 +10875,7 @@ if (opcode == OP_CBRA || opcode == OP_SCBRA) BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; matchingpath += IMM2_SIZE; } -else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE - || opcode == OP_ASSERT_SCS || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) +else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_ONCE || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { /* Other brackets simply allocate the next entry. */ private_data_ptr = PRIVATE_DATA(ccbegin); @@ -9703,88 +11086,6 @@ else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SC if (*matchingpath == OP_REVERSE) matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack); } -else if (opcode == OP_ASSERT_SCS) - { - /* Nested scs blocks will not update this variable. */ - if (common->restore_end_ptr == 0) - common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw); - - if (*matchingpath == OP_CREF && (matchingpath[1 + IMM2_SIZE] != OP_CREF && matchingpath[1 + IMM2_SIZE] != OP_DNCREF)) - { - /* Optimized case for a single capture reference. */ - i = OVECTOR(GET2(matchingpath, 1) << 1); - - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), i); - - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); - matchingpath += 1 + IMM2_SIZE; - - allocate_stack(common, has_alternatives ? 3 : 2); - - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), i + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); - } - else - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); - jumplist = NULL; - - while (TRUE) - { - if (*matchingpath == OP_CREF) - { - sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(matchingpath, 1) << 1)); - matchingpath += 1 + IMM2_SIZE; - } - else - { - SLJIT_ASSERT(*matchingpath == OP_DNCREF); - - i = GET2(matchingpath, 1 + IMM2_SIZE); - slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; - - while (i-- > 1) - { - sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(slot, 0) << 1)); - add_jump(compiler, &jumplist, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0)); - slot += common->name_entry_size; - } - - sljit_get_local_base(compiler, TMP2, 0, OVECTOR(GET2(slot, 0) << 1)); - matchingpath += 1 + 2 * IMM2_SIZE; - } - - if (*matchingpath != OP_CREF && *matchingpath != OP_DNCREF) - break; - - add_jump(compiler, &jumplist, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0)); - } - - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), - CMP(SLJIT_EQUAL, SLJIT_MEM1(TMP2), 0, TMP1, 0)); - - set_jumps(jumplist, LABEL()); - - allocate_stack(common, has_alternatives ? 3 : 2); - - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); - } - - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_TMP_DEST_REG, 0); - - if (has_alternatives) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); - } else if (has_alternatives) { /* Pushing the starting string pointer. */ @@ -9798,7 +11099,7 @@ if (opcode == OP_COND || opcode == OP_SCOND) if (*matchingpath == OP_CREF) { SLJIT_ASSERT(has_alternatives); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); matchingpath += 1 + IMM2_SIZE; } @@ -9820,13 +11121,13 @@ if (opcode == OP_COND || opcode == OP_SCOND) slot += common->name_entry_size; } OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.no_capture), JUMP(SLJIT_ZERO)); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO)); matchingpath += 1 + 2 * IMM2_SIZE; } else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) { /* Never has other case. */ - BACKTRACK_AS(bracket_backtrack)->u.no_capture = NULL; + BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; SLJIT_ASSERT(!has_alternatives); if (*matchingpath == OP_TRUE) @@ -9915,6 +11216,9 @@ switch (opcode) if (PRIVATE_DATA(ccbegin + 1)) OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); break; + case OP_ASSERT_NA: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + break; case OP_ONCE: match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); break; @@ -9980,7 +11284,7 @@ if (has_alternatives) if (i <= 3) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); else - BACKTRACK_AS(bracket_backtrack)->matching_mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize)); + BACKTRACK_AS(bracket_backtrack)->u.matching_mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize)); } if (ket != OP_KETRMAX) BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); @@ -9992,22 +11296,6 @@ if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0) SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0); } -else switch (opcode) - { - case OP_ASSERT_NA: - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - break; - case OP_ASSERT_SCS: - OP1(SLJIT_MOV, TMP1, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP1, 0); - - /* Nested scs blocks will not update this variable. */ - if (common->restore_end_ptr == private_data_ptr + SSIZE_OF(sw)) - common->restore_end_ptr = 0; - break; - } if (ket == OP_KETRMAX) { @@ -10071,19 +11359,13 @@ if (bra == OP_BRAMINZERO) /* We need to release the end pointer to perform the backtrack for the zero-length iteration. When framesize is < 0, OP_ONCE will do the release itself. */ - if (opcode == OP_ONCE) + if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) { - int framesize = BACKTRACK_AS(bracket_backtrack)->u.framesize; - - SLJIT_ASSERT(framesize != 0); - if (framesize > 0) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); - } + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw)); } - else if (ket == OP_KETRMIN) + else if (ket == OP_KETRMIN && opcode != OP_ONCE) free_stack(common, 1); } /* Continue to the normal backtrack. */ @@ -10331,7 +11613,12 @@ while (*cc != OP_KETRPOS) add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); if (!zero) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + { + if (framesize < 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + } } JUMPTO(SLJIT_JUMP, loop); @@ -10425,11 +11712,11 @@ else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) } else { - SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS || *opcode == OP_ECLASS); + SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS); *type = *opcode; - class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 1); - *opcode = cc[class_len]; cc++; + class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0); + *opcode = cc[class_len - 1]; if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) { @@ -10441,10 +11728,8 @@ else *exact = 1; *opcode -= OP_PLUS - OP_STAR; } - return cc; } - - if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) + else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) { *opcode -= OP_CRPOSSTAR - OP_POSSTAR; *end = cc + class_len; @@ -10454,40 +11739,41 @@ else *exact = 1; *opcode = OP_POSSTAR; } - return cc; - } - - SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); - *max = GET2(cc, (class_len + IMM2_SIZE)); - *exact = GET2(cc, class_len); - *end = cc + class_len + 2 * IMM2_SIZE; - - if (*max == 0) - { - SLJIT_ASSERT(*exact > 1); - if (*opcode == OP_CRRANGE) - *opcode = OP_UPTO; - else if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSUPTO; - else - *opcode = OP_MINSTAR; - return cc; } - - *max -= *exact; - if (*max == 0) - *opcode = OP_EXACT; else { - SLJIT_ASSERT(*exact > 0 || *max > 1); - if (*opcode == OP_CRRANGE) - *opcode = OP_UPTO; - else if (*opcode == OP_CRPOSRANGE) - *opcode = OP_POSUPTO; - else if (*max == 1) - *opcode = OP_MINQUERY; + SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); + *max = GET2(cc, (class_len + IMM2_SIZE)); + *exact = GET2(cc, class_len); + + if (*max == 0) + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSSTAR; + else + *opcode -= OP_CRRANGE - OP_STAR; + } else - *opcode = OP_MINUPTO; + { + *max -= *exact; + if (*max == 0) + *opcode = OP_EXACT; + else if (*max == 1) + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSQUERY; + else + *opcode -= OP_CRRANGE - OP_QUERY; + } + else + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSUPTO; + else + *opcode -= OP_CRRANGE - OP_UPTO; + } + } + *end = cc + class_len + 2 * IMM2_SIZE; } return cc; } @@ -10533,17 +11819,16 @@ if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); return cc; } -static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent, jump_list **prev_backtracks) +static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) { DEFINE_COMPILER; -backtrack_common *backtrack = NULL; -PCRE2_SPTR begin = cc; +backtrack_common *backtrack; PCRE2_UCHAR opcode; PCRE2_UCHAR type; sljit_u32 max = 0, exact; sljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1); sljit_s32 early_fail_type; -BOOL charpos_enabled, use_tmp; +BOOL charpos_enabled; PCRE2_UCHAR charpos_char; unsigned int charpos_othercasebit; PCRE2_SPTR end; @@ -10556,6 +11841,11 @@ int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw); int tmp_base, tmp_offset; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +BOOL use_tmp; +#endif + +PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL); early_fail_type = (early_fail_ptr & 0x7); early_fail_ptr >>= 3; @@ -10571,7 +11861,7 @@ SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0 || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr)); if (early_fail_type == type_fail) - add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); @@ -10583,47 +11873,39 @@ if (type != OP_EXTUNI) else { tmp_base = SLJIT_MEM1(SLJIT_SP); - tmp_offset = LOCAL2; + tmp_offset = POSSESSIVE0; } -if (opcode == OP_EXACT) +/* Handle fixed part first. */ +if (exact > 1) { - SLJIT_ASSERT(early_fail_ptr == 0 && exact >= 2); + SLJIT_ASSERT(early_fail_ptr == 0); if (common->mode == PCRE2_JIT_COMPLETE -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +#ifdef SUPPORT_UNICODE && !common->utf #endif && type != OP_ANYNL && type != OP_EXTUNI) { - OP2(SLJIT_SUB, TMP1, 0, STR_END, 0, STR_PTR, 0); - add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, IN_UCHARS(exact))); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32 - if (type == OP_ALLANY && !common->invalid_utf) -#else - if (type == OP_ALLANY) -#endif - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); - else - { - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, prev_backtracks, FALSE); - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); } else { - SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw)); OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); label = LABEL(); - compile_char1_matchingpath(common, type, cc, prev_backtracks, TRUE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } } +else if (exact == 1) + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); if (early_fail_type == type_fail_range) { @@ -10632,57 +11914,38 @@ if (early_fail_type == type_fail_range) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0); OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0); - add_jump(compiler, prev_backtracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw), STR_PTR, 0); } -if (opcode < OP_EXACT) - PUSH_BACKTRACK(sizeof(char_iterator_backtrack), begin, NULL); - switch(opcode) { case OP_STAR: case OP_UPTO: - SLJIT_ASSERT(backtrack != NULL && (early_fail_ptr == 0 || opcode == OP_STAR)); - max += exact; - - if (type == OP_EXTUNI) - { - SLJIT_ASSERT(private_data_ptr == 0); - SLJIT_ASSERT(early_fail_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0 || opcode == OP_STAR); - if (exact == 1) - { - SLJIT_ASSERT(opcode == OP_STAR); - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } - else - { - /* If OP_EXTUNI is present, it has a separate EXACT opcode. */ - SLJIT_ASSERT(exact == 0); + if (type == OP_ANYNL || type == OP_EXTUNI) + { + SLJIT_ASSERT(private_data_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); - allocate_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); - } + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); if (opcode == OP_UPTO) - { - SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, SLJIT_IMM, max); - } + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); + compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); if (opcode == OP_UPTO) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); jump = JUMP(SLJIT_ZERO); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); } /* We cannot use TMP3 because of allocate_stack. */ @@ -10702,9 +11965,6 @@ switch(opcode) { if (opcode == OP_STAR) { - if (exact == 1) - detect_partial_match(common, prev_backtracks); - if (private_data_ptr == 0) allocate_stack(common, 2); @@ -10725,9 +11985,6 @@ switch(opcode) else #endif { - /* If OP_ALLANY is present, it has a separate EXACT opcode. */ - SLJIT_ASSERT(exact == 0); - if (private_data_ptr == 0) allocate_stack(common, 2); @@ -10759,7 +12016,6 @@ switch(opcode) charpos_char = 0; charpos_othercasebit = 0; - SLJIT_ASSERT(tmp_base == TMP3); if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI)) { #ifdef SUPPORT_UNICODE @@ -10789,320 +12045,176 @@ switch(opcode) if (charpos_othercasebit != 0) charpos_char |= charpos_othercasebit; - BACKTRACK_AS(char_iterator_backtrack)->charpos.charpos_enabled = TRUE; - BACKTRACK_AS(char_iterator_backtrack)->charpos.chr = charpos_char; - BACKTRACK_AS(char_iterator_backtrack)->charpos.othercasebit = charpos_othercasebit; - - if (private_data_ptr == 0) - allocate_stack(common, 2); - - use_tmp = (opcode == OP_STAR); - - if (use_tmp) - { - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); - OP1(SLJIT_MOV, base, offset0, TMP3, 0); - } - else - { - OP1(SLJIT_MOV, base, offset1, COUNT_MATCH, 0); - OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_IMM, 0); - OP1(SLJIT_MOV, base, offset0, COUNT_MATCH, 0); - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? 0 : (max + 1)); - } - - /* Search the first instance of charpos_char. */ - if (exact > 0) - detect_partial_match(common, &no_match); - else - jump = JUMP(SLJIT_JUMP); - - label = LABEL(); - - if (opcode == OP_UPTO) - { - if (exact == max) - OP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - else - { - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); - } - } - - compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - - if (early_fail_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); - - if (exact == 0) - JUMPHERE(jump); - - detect_partial_match(common, &no_match); - - if (opcode == OP_UPTO && exact > 0) - { - if (exact == max) - CMPTO(SLJIT_LESS, TMP3, 0, SLJIT_IMM, exact, label); - else - CMPTO(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, (max + 1) - exact, label); - } - - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (charpos_othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); - - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (use_tmp) - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, SLJIT_IMM, 0); - SELECT(SLJIT_EQUAL, TMP3, STR_PTR, 0, TMP3); - } - else - { - OP2U(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, SLJIT_IMM, 0); - SELECT(SLJIT_EQUAL, COUNT_MATCH, STR_PTR, 0, COUNT_MATCH); - } - JUMPTO(SLJIT_JUMP, label); - - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - if (use_tmp) - OP1(SLJIT_MOV, base, offset1, TMP3, 0); - else - { - OP1(SLJIT_MOV, TMP1, 0, base, offset1); - OP1(SLJIT_MOV, base, offset1, COUNT_MATCH, 0); - OP1(SLJIT_MOV, COUNT_MATCH, 0, TMP1, 0); - } - - add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0)); - - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - break; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit; } } - if (private_data_ptr == 0) - allocate_stack(common, 2); + if (charpos_enabled) + { + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - use_tmp = (opcode == OP_STAR); + /* Search the first instance of charpos_char. */ + jump = JUMP(SLJIT_JUMP); + label = LABEL(); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_ZERO)); + } + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); + JUMPHERE(jump); - if (common->utf) - { - if (!use_tmp) - OP1(SLJIT_MOV, base, offset0, COUNT_MATCH, 0); + detect_partial_match(common, &backtrack->own_backtracks); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); - OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0); - } -#endif + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? -(sljit_sw)exact : (sljit_sw)max); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + } - if (opcode == OP_UPTO && exact > 0) - { + /* Search the last instance of charpos_char. */ label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); detect_partial_match(common, &no_match); - compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0); -#endif + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); - if (exact == max) + if (opcode == OP_STAR) { - OP2(SLJIT_ADD | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); } else { - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); - CMPTO(SLJIT_NOT_EQUAL, TMP3, 0, SLJIT_IMM, max - exact, label); + jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPHERE(jump); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); } - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, label); + set_jumps(no_match, LABEL()); + OP2(SLJIT_ADD, STR_PTR, 0, base, offset0, SLJIT_IMM, IN_UCHARS(1)); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); } else { + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR); + SLJIT_ASSERT(!use_tmp || tmp_base == TMP3); + + if (common->utf) + OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0); +#endif + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); detect_partial_match(common, &no_match); label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 if (common->utf) - OP1(SLJIT_MOV, use_tmp ? TMP3 : COUNT_MATCH, 0, STR_PTR, 0); + OP1(SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0); #endif if (opcode == OP_UPTO) { - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); } detect_partial_match_to(common, label); - } + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) - { set_jumps(no_char1_match, LABEL()); - set_jumps(no_match, LABEL()); - if (use_tmp) +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) { - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - OP1(SLJIT_MOV, base, offset0, TMP3, 0); + set_jumps(no_match, LABEL()); + if (use_tmp) + { + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + OP1(SLJIT_MOV, base, offset0, TMP3, 0); + } + else + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); } else +#endif { - OP1(SLJIT_MOV, STR_PTR, 0, COUNT_MATCH, 0); - OP1(SLJIT_MOV, COUNT_MATCH, 0, base, offset0); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); } - } - else -#endif - { - if (opcode != OP_UPTO || exact == 0) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_char1_match, LABEL()); - - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - } - if (opcode == OP_UPTO) - { - if (exact > 0) - { - if (max == exact) - jump = CMP(SLJIT_GREATER_EQUAL, TMP3, 0, SLJIT_IMM, -(sljit_sw)exact); - else - jump = CMP(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, max - exact); - - add_jump(compiler, &backtrack->own_backtracks, jump); - } + if (early_fail_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); } - else if (exact == 1) - add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, base, offset1, STR_PTR, 0)); - - if (early_fail_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; - case OP_QUERY: - SLJIT_ASSERT(backtrack != NULL && early_fail_ptr == 0); + case OP_MINSTAR: if (private_data_ptr == 0) allocate_stack(common, 1); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - break; - - case OP_MINSTAR: - case OP_MINQUERY: - SLJIT_ASSERT(backtrack != NULL && (opcode == OP_MINSTAR || early_fail_ptr == 0)); - if (private_data_ptr == 0) - allocate_stack(common, 1); - - if (exact >= 1) - { - if (exact >= 2) - { - /* Extuni has a separate exact opcode. */ - SLJIT_ASSERT(tmp_base == TMP3 && early_fail_ptr == 0); - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact); - } - - if (opcode == OP_MINQUERY) - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, -1); - - label = LABEL(); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = label; - - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); - - if (exact >= 2) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - - if (opcode == OP_MINQUERY) - OP2(SLJIT_AND, base, offset0, base, offset0, STR_PTR, 0); - else - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - } - else - { - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - } - if (early_fail_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); break; case OP_MINUPTO: - SLJIT_ASSERT(backtrack != NULL && early_fail_ptr == 0); + SLJIT_ASSERT(early_fail_ptr == 0); if (private_data_ptr == 0) allocate_stack(common, 2); - + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; - if (exact == 0) - { - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); - break; - } - - if (exact >= 2) - { - /* Extuni has a separate exact opcode. */ - SLJIT_ASSERT(tmp_base == TMP3); - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact); - } - - label = LABEL(); - BACKTRACK_AS(char_iterator_backtrack)->matchingpath = label; - - compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); - - if (exact >= 2) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - + case OP_QUERY: + case OP_MINQUERY: + SLJIT_ASSERT(early_fail_ptr == 0); + if (private_data_ptr == 0) + allocate_stack(common, 1); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (opcode == OP_QUERY) + compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; case OP_EXACT: - SLJIT_ASSERT(backtrack == NULL); break; case OP_POSSTAR: - SLJIT_ASSERT(backtrack == NULL); #if defined SUPPORT_UNICODE if (type == OP_ALLANY && !common->invalid_utf) #else if (type == OP_ALLANY) #endif { - if (exact == 1) - detect_partial_match(common, prev_backtracks); - OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); process_partial_match(common); if (early_fail_ptr != 0) @@ -11111,150 +12223,98 @@ switch(opcode) } #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) + if (type == OP_EXTUNI || common->utf) { - SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw)); - - if (tmp_base != TMP3) - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, COUNT_MATCH, 0); - tmp_base = COUNT_MATCH; - } - - OP1(SLJIT_MOV, tmp_base, 0, exact == 1 ? SLJIT_IMM : STR_PTR, 0); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); detect_partial_match(common, &no_match); label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - OP1(SLJIT_MOV, tmp_base, 0, STR_PTR, 0); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); detect_partial_match_to(common, label); set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, 0); - - if (tmp_base != TMP3) - OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); - - if (exact == 1) - add_jump(compiler, prev_backtracks, CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0)); - + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); if (early_fail_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); + { + if (!HAS_VIRTUAL_REGISTERS && tmp_base == TMP3) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, TMP3, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); + } break; } #endif - if (exact == 1) - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - detect_partial_match(common, &no_match); label = LABEL(); - /* Extuni never fails, so no_char1_match is not used in that case. - Anynl optionally reads an extra character on success. */ compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); detect_partial_match_to(common, label); - if (type != OP_EXTUNI) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_char1_match, LABEL()); - if (type != OP_EXTUNI) - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_match, LABEL()); - - if (exact == 1) - add_jump(compiler, prev_backtracks, CMP(SLJIT_EQUAL, tmp_base, tmp_offset, STR_PTR, 0)); - if (early_fail_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); break; case OP_POSUPTO: - SLJIT_ASSERT(backtrack == NULL && early_fail_ptr == 0); - max += exact; - + SLJIT_ASSERT(early_fail_ptr == 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (type == OP_EXTUNI || common->utf) -#else - if (type == OP_EXTUNI) -#endif + if (common->utf) { - SLJIT_ASSERT(common->locals_size >= 3 * SSIZE_OF(sw)); - - /* Count match is not modified by compile_char1_matchingpath. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL2, COUNT_MATCH, 0); - OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_IMM, exact == max ? 0 : max); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + detect_partial_match(common, &no_match); label = LABEL(); - /* Extuni only modifies TMP3 on successful match. */ - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + detect_partial_match_to(common, label); + + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); + break; + } +#endif - if (exact == max) + if (type == OP_ALLANY) + { + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max)); + + if (common->mode == PCRE2_JIT_COMPLETE) { - OP2(SLJIT_ADD, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_JUMP, label); + OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else { - OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - } - - set_jumps(no_match, LABEL()); - - if (exact > 0) - { - if (exact == max) - OP2U(SLJIT_SUB | SLJIT_SET_LESS, COUNT_MATCH, 0, SLJIT_IMM, exact); - else - OP2U(SLJIT_SUB | SLJIT_SET_GREATER, COUNT_MATCH, 0, SLJIT_IMM, max - exact); + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0); + process_partial_match(common); + JUMPHERE(jump); } - - OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LOCAL2); - - if (exact > 0) - add_jump(compiler, prev_backtracks, JUMP(exact == max ? SLJIT_LESS : SLJIT_GREATER)); - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); break; } - SLJIT_ASSERT(tmp_base == TMP3); - - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, exact == max ? 0 : max); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); detect_partial_match(common, &no_match); label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - - if (exact == max) - OP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - else - { - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); - } + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); detect_partial_match_to(common, label); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_char1_match, LABEL()); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_match, LABEL()); - - if (exact > 0) - { - if (exact == max) - jump = CMP(SLJIT_LESS, TMP3, 0, SLJIT_IMM, exact); - else - jump = CMP(SLJIT_GREATER, TMP3, 0, SLJIT_IMM, max - exact); - - add_jump(compiler, prev_backtracks, jump); - } break; case OP_POSQUERY: - SLJIT_ASSERT(backtrack == NULL && early_fail_ptr == 0); - SLJIT_ASSERT(tmp_base == TMP3 || common->locals_size >= 3 * SSIZE_OF(sw)); + SLJIT_ASSERT(early_fail_ptr == 0); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); compile_char1_matchingpath(common, type, cc, &no_match, TRUE); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); @@ -11417,7 +12477,6 @@ DEFINE_COMPILER; backtrack_common *backtrack; BOOL has_then_trap = FALSE; then_trap_backtrack *save_then_trap = NULL; -size_t op_len; SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); @@ -11553,23 +12612,21 @@ while (cc < ccend) case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSUPTO: - cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); + cc = compile_iterator_matchingpath(common, cc, parent); break; case OP_CLASS: case OP_NCLASS: if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE) - cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); + cc = compile_iterator_matchingpath(common, cc, parent); else cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 case OP_XCLASS: - case OP_ECLASS: - op_len = GET(cc, 1); - if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE) - cc = compile_iterator_matchingpath(common, cc, parent, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); + if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) + cc = compile_iterator_matchingpath(common, cc, parent); else cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; @@ -11577,26 +12634,24 @@ while (cc < ccend) case OP_REF: case OP_REFI: - op_len = PRIV(OP_lengths)[*cc]; - if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE) + if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); - cc += op_len; + cc += 1 + IMM2_SIZE; } break; case OP_DNREF: case OP_DNREFI: - op_len = PRIV(OP_lengths)[*cc]; - if (cc[op_len] >= OP_CRSTAR && cc[op_len] <= OP_CRPOSRANGE) + if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); - cc += op_len; + cc += 1 + 2 * IMM2_SIZE; } break; @@ -11637,7 +12692,6 @@ while (cc < ccend) case OP_ASSERT_NA: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -11749,28 +12803,6 @@ SLJIT_ASSERT(cc == ccend); #define CURRENT_AS(type) ((type *)current) -static void compile_newline_move_back(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; - -OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, TMP2, 0); -/* All newlines are single byte, or their last byte -is not equal to CHAR_NL/CHAR_CR even if UTF is enabled. */ -OP1(MOV_UCHAR, SLJIT_TMP_DEST_REG, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); -OP2(SLJIT_SHL, SLJIT_TMP_DEST_REG, 0, SLJIT_TMP_DEST_REG, 0, SLJIT_IMM, 8); -OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_TMP_DEST_REG, 0); -OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_CR << 8 | CHAR_NL); -OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); -#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 -OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -JUMPHERE(jump); -} - static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; @@ -11793,104 +12825,52 @@ switch(opcode) { case OP_STAR: case OP_UPTO: - if (type == OP_EXTUNI) + if (type == OP_ANYNL || type == OP_EXTUNI) { SLJIT_ASSERT(private_data_ptr == 0); - set_jumps(current->own_backtracks, LABEL()); + set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); } else { - if (CURRENT_AS(char_iterator_backtrack)->charpos.charpos_enabled) + if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled) { OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP1(SLJIT_MOV, TMP2, 0, base, offset1); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); label = LABEL(); - if (type == OP_ANYNL) - compile_newline_move_back(common); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); move_back(common, NULL, TRUE); - - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (CURRENT_AS(char_iterator_backtrack)->charpos.othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->charpos.othercasebit); - CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); - /* The range beginning must match, no need to compare. */ - JUMPTO(SLJIT_JUMP, label); - - set_jumps(current->own_backtracks, LABEL()); - current->own_backtracks = NULL; + CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label); } else { OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - - if (opcode == OP_STAR && exact == 1) - { - if (type == OP_ANYNL) - { - OP1(SLJIT_MOV, TMP2, 0, base, offset1); - compile_newline_move_back(common); - } - - move_back(common, NULL, TRUE); - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); - } - else - { - if (type == OP_ANYNL) - { - OP1(SLJIT_MOV, TMP2, 0, base, offset1); - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); - compile_newline_move_back(common); - } - else - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); - - move_back(common, NULL, TRUE); - } - + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); + move_back(common, NULL, TRUE); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - - set_jumps(current->own_backtracks, LABEL()); } - JUMPHERE(jump); if (private_data_ptr == 0) free_stack(common, 2); } break; - case OP_QUERY: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); - jump = JUMP(SLJIT_JUMP); - set_jumps(current->own_backtracks, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - JUMPHERE(jump); - if (private_data_ptr == 0) - free_stack(common, 1); - break; - case OP_MINSTAR: OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - if (exact == 0) - { - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - } - else if (exact > 1) - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); - + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - set_jumps(exact > 0 ? current->own_backtracks : jumplist, LABEL()); + set_jumps(jumplist, LABEL()); if (private_data_ptr == 0) free_stack(common, 1); break; @@ -11899,60 +12879,56 @@ switch(opcode) OP1(SLJIT_MOV, TMP1, 0, base, offset1); OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO)); - if (exact == 0) - { - add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO)); - - OP1(SLJIT_MOV, base, offset1, TMP1, 0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - - set_jumps(jumplist, LABEL()); - } - else - { - if (exact > 1) - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, base, offset1, TMP1, 0); - JUMPTO(SLJIT_NOT_ZERO, CURRENT_AS(char_iterator_backtrack)->matchingpath); - - set_jumps(current->own_backtracks, LABEL()); - } + OP1(SLJIT_MOV, base, offset1, TMP1, 0); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + set_jumps(jumplist, LABEL()); if (private_data_ptr == 0) free_stack(common, 2); break; - case OP_MINQUERY: + case OP_QUERY: OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); + jump = JUMP(SLJIT_JUMP); + set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + JUMPHERE(jump); + if (private_data_ptr == 0) + free_stack(common, 1); + break; - if (exact >= 1) - { - if (exact >= 2) - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); - set_jumps(current->own_backtracks, LABEL()); - } - else - { - jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); - JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); - set_jumps(jumplist, LABEL()); - JUMPHERE(jump); - } - + case OP_MINQUERY: + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); + set_jumps(jumplist, LABEL()); + JUMPHERE(jump); if (private_data_ptr == 0) free_stack(common, 1); break; + case OP_EXACT: + case OP_POSSTAR: + case OP_POSQUERY: + case OP_POSUPTO: + break; + default: SLJIT_UNREACHABLE(); break; } + +set_jumps(current->own_backtracks, LABEL()); } static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -11962,7 +12938,7 @@ PCRE2_SPTR cc = current->cc; BOOL ref = (*cc == OP_REF || *cc == OP_REFI); PCRE2_UCHAR type; -type = cc[PRIV(OP_lengths)[*cc]]; +type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; if ((type & 0x1) == 0) { @@ -12081,7 +13057,7 @@ PCRE2_SPTR ccbegin; PCRE2_SPTR ccprev; PCRE2_UCHAR bra = OP_BRA; PCRE2_UCHAR ket; -const assert_backtrack *assert; +assert_backtrack *assert; BOOL has_alternatives; BOOL needs_control_head = FALSE; BOOL has_vreverse; @@ -12117,7 +13093,7 @@ ccbegin = cc; cc += GET(cc, 1); has_alternatives = *cc == OP_ALT; if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) - has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.no_capture != NULL; + has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; if (opcode == OP_CBRA || opcode == OP_SCBRA) offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) @@ -12220,27 +13196,14 @@ if (offset != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0); } } -else if (SLJIT_UNLIKELY(opcode == OP_ASSERT_SCS)) - { - OP1(SLJIT_MOV, TMP1, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP1, 0); - - /* Nested scs blocks will not update this variable. */ - if (common->restore_end_ptr == 0) - common->restore_end_ptr = private_data_ptr + sizeof(sljit_sw); - } if (SLJIT_UNLIKELY(opcode == OP_ONCE)) { - int framesize = CURRENT_AS(bracket_backtrack)->u.framesize; - - SLJIT_ASSERT(framesize != 0); - if (framesize > 0) + if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw)); } once = JUMP(SLJIT_JUMP); } @@ -12265,8 +13228,8 @@ else if (has_alternatives) { sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0); - SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->matching_mov_addr != NULL); - sljit_set_label(CURRENT_AS(bracket_backtrack)->matching_mov_addr, LABEL()); + SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_mov_addr); + sljit_set_label(CURRENT_AS(bracket_backtrack)->u.matching_mov_addr, LABEL()); sljit_emit_op0(compiler, SLJIT_ENDBR); } else @@ -12284,8 +13247,7 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { SLJIT_ASSERT(has_alternatives); assert = CURRENT_AS(bracket_backtrack)->u.assert; - SLJIT_ASSERT(assert->framesize != 0); - if (assert->framesize > 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) + if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -12296,11 +13258,11 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) cond = JUMP(SLJIT_JUMP); set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); } - else if (CURRENT_AS(bracket_backtrack)->u.no_capture != NULL) + else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) { SLJIT_ASSERT(has_alternatives); cond = JUMP(SLJIT_JUMP); - set_jumps(CURRENT_AS(bracket_backtrack)->u.no_capture, LABEL()); + set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); } else SLJIT_ASSERT(!has_alternatives); @@ -12321,33 +13283,26 @@ if (has_alternatives) cc += GET(cc, 1); has_vreverse = FALSE; - - switch (opcode) + if (opcode == OP_ASSERTBACK || opcode == OP_ASSERTBACK_NA) { - case OP_ASSERTBACK: - case OP_ASSERTBACK_NA: - SLJIT_ASSERT(private_data_ptr != 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + SLJIT_ASSERT(private_data_ptr != 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - has_vreverse = (*ccprev == OP_VREVERSE); - if (*ccprev == OP_REVERSE || has_vreverse) - ccprev = compile_reverse_matchingpath(common, ccprev, current); - break; - case OP_ASSERT_SCS: - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); - break; - case OP_ONCE: - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); - break; - case OP_COND: - case OP_SCOND: - break; - default: + has_vreverse = (*ccprev == OP_VREVERSE); + if (*ccprev == OP_REVERSE || has_vreverse) + ccprev = compile_reverse_matchingpath(common, ccprev, current); + } + else if (opcode != OP_COND && opcode != OP_SCOND) + { + if (opcode != OP_ONCE) + { if (private_data_ptr != 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); else OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - break; + } + else + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); } compile_matchingpath(common, ccprev, cc, current); @@ -12468,18 +13423,14 @@ if (has_alternatives) if (cond != NULL) { SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); - if (ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) + assert = CURRENT_AS(bracket_backtrack)->u.assert; + if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) { - assert = CURRENT_AS(bracket_backtrack)->u.assert; - SLJIT_ASSERT(assert->framesize != 0); - if (assert->framesize > 0) - { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); - add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0); - } + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr); + add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0); } JUMPHERE(cond); } @@ -12521,21 +13472,6 @@ else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SC OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); } -else if (opcode == OP_ASSERT_SCS) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP2, 0); - free_stack(common, has_alternatives ? 3 : 2); - - set_jumps(CURRENT_AS(bracket_backtrack)->u.no_capture, LABEL()); - - /* Nested scs blocks will not update this variable. */ - if (common->restore_end_ptr == private_data_ptr + SSIZE_OF(sw)) - common->restore_end_ptr = 0; - } else if (opcode == OP_ONCE) { cc = ccbegin + GET(ccbegin, 1); @@ -12716,9 +13652,6 @@ if (opcode == OP_THEN || opcode == OP_THEN_ARG) } } -if (common->restore_end_ptr != 0 && opcode != OP_SKIP_ARG) - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr); - if (common->local_quit_available) { /* Abort match with a fail. */ @@ -12736,18 +13669,8 @@ if (opcode == OP_SKIP_ARG) OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2)); sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_search_mark)); - if (common->restore_end_ptr == 0) - { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0); - add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0)); - return; - } - - jump = CMP(SLJIT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr); - add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); - JUMPHERE(jump); + add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0)); return; } @@ -12779,7 +13702,6 @@ static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *com { DEFINE_COMPILER; struct sljit_jump *jump; -int framesize; int size; if (CURRENT_AS(then_trap_backtrack)->then_trap) @@ -12796,15 +13718,11 @@ free_stack(common, size); jump = JUMP(SLJIT_JUMP); set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); - -framesize = CURRENT_AS(then_trap_backtrack)->framesize; -SLJIT_ASSERT(framesize != 0); - /* STACK_TOP is set by THEN. */ -if (framesize > 0) +if (CURRENT_AS(then_trap_backtrack)->framesize >= 0) { add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(then_trap_backtrack)->framesize - 1) * sizeof(sljit_sw)); } OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 3); @@ -12895,13 +13813,10 @@ while (current) case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSUPTO: - /* Since classes has no backtracking path, this - backtrackingpath was pushed by an iterator. */ case OP_CLASS: case OP_NCLASS: #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - case OP_ECLASS: #endif compile_iterator_backtrackingpath(common, current); break; @@ -12926,7 +13841,6 @@ while (current) case OP_ASSERT_NA: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -12978,12 +13892,8 @@ while (current) case OP_COMMIT: case OP_COMMIT_ARG: - if (common->restore_end_ptr != 0) - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->restore_end_ptr); - if (!common->local_quit_available) OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); - if (common->quit_label == NULL) add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); else @@ -13244,7 +14154,8 @@ int private_data_size; PCRE2_SPTR ccend; executable_functions *functions; void *executable_func; -sljit_uw executable_size, private_data_length, total_length; +sljit_uw executable_size; +sljit_uw total_length; struct sljit_label *mainloop_label = NULL; struct sljit_label *continue_match_label; struct sljit_label *empty_match_found_label = NULL; @@ -13271,7 +14182,7 @@ memset(&rootbacktrack, 0, sizeof(backtrack_common)); memset(common, 0, sizeof(compiler_common)); common->re = re; common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); -rootbacktrack.cc = (PCRE2_SPTR)((uint8_t *)re + re->code_start); +rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size; #ifdef SUPPORT_UNICODE common->invalid_utf = (mode & PCRE2_JIT_INVALID_UTF) != 0; @@ -13319,7 +14230,7 @@ common->name_entry_size = re->name_entry_size; common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0; common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0; #ifdef SUPPORT_UNICODE -/* PCRE2_UTF[16|32] have the same value as PCRE2_UTF8. */ +/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ common->utf = (re->overall_options & PCRE2_UTF) != 0; common->ucp = (re->overall_options & PCRE2_UCP) != 0; if (common->utf) @@ -13351,26 +14262,10 @@ else ccend = bracketend(common->start); /* Calculate the local space size on the stack. */ -common->ovector_start = LOCAL0; -/* Allocate space for temporary data structures. */ -private_data_length = ccend - common->start; -/* The chance of overflow is very low, but might happen on 32 bit. */ -if (private_data_length > ~(sljit_uw)0 / sizeof(sljit_s32)) +common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); +common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data); +if (!common->optimized_cbracket) return PCRE2_ERROR_NOMEMORY; - -private_data_length *= sizeof(sljit_s32); -/* Align to 32 bit. */ -total_length = ((re->top_bracket + 1) + (sljit_uw)(sizeof(sljit_s32) - 1)) & ~(sljit_uw)(sizeof(sljit_s32) - 1); -if (~(sljit_uw)0 - private_data_length < total_length) - return PCRE2_ERROR_NOMEMORY; - -total_length += private_data_length; -common->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length, allocator_data); -if (!common->private_data_ptrs) - return PCRE2_ERROR_NOMEMORY; - -memset(common->private_data_ptrs, 0, private_data_length); -common->optimized_cbracket = ((sljit_u8 *)common->private_data_ptrs) + private_data_length; #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 memset(common->optimized_cbracket, 0, re->top_bracket + 1); #else @@ -13384,19 +14279,16 @@ common->ovector_start += sizeof(sljit_sw); #endif if (!check_opcode_types(common, common->start, ccend)) { - SLJIT_FREE(common->private_data_ptrs, allocator_data); - return PCRE2_ERROR_JIT_UNSUPPORTED; + SLJIT_FREE(common->optimized_cbracket, allocator_data); + return PCRE2_ERROR_NOMEMORY; } /* Checking flags and updating ovector_start. */ -if (mode == PCRE2_JIT_COMPLETE && - (re->flags & PCRE2_LASTSET) != 0 && - (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) +if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) { common->req_char_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } - if (mode != PCRE2_JIT_COMPLETE) { common->start_used_ptr = common->ovector_start; @@ -13407,23 +14299,19 @@ if (mode != PCRE2_JIT_COMPLETE) common->ovector_start += sizeof(sljit_sw); } } - if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0) { common->match_end_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } - #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD common->control_head_ptr = 1; #endif - if (common->control_head_ptr != 0) { common->control_head_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } - if (common->has_set_som) { /* Saving the real start pointer is necessary. */ @@ -13444,11 +14332,19 @@ if (common->capture_last_ptr != 0) SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); + +total_length = ccend - common->start; +common->private_data_ptrs = (sljit_s32*)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data); +if (!common->private_data_ptrs) + { + SLJIT_FREE(common->optimized_cbracket, allocator_data); + return PCRE2_ERROR_NOMEMORY; + } +memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32)); + private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); -if ((re->overall_options & PCRE2_ANCHORED) == 0 && - (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0 && - !common->has_skip_in_assert_back) +if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back) detect_early_fail(common, common->start, &private_data_size, 0, 0); set_private_data_ptrs(common, &private_data_size, ccend); @@ -13458,18 +14354,13 @@ SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr); if (private_data_size > 65536) { SLJIT_FREE(common->private_data_ptrs, allocator_data); - return PCRE2_ERROR_JIT_UNSUPPORTED; + SLJIT_FREE(common->optimized_cbracket, allocator_data); + return PCRE2_ERROR_NOMEMORY; } if (common->has_then) { - total_length = ccend - common->start; - common->then_offsets = (sljit_u8 *)SLJIT_MALLOC(total_length, allocator_data); - if (!common->then_offsets) - { - SLJIT_FREE(common->private_data_ptrs, allocator_data); - return PCRE2_ERROR_NOMEMORY; - } + common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length); memset(common->then_offsets, 0, total_length); set_then_offsets(common, common->start, NULL); } @@ -13477,16 +14368,15 @@ if (common->has_then) compiler = sljit_create_compiler(allocator_data); if (!compiler) { + SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); - if (common->has_then) - SLJIT_FREE(common->then_offsets, allocator_data); return PCRE2_ERROR_NOMEMORY; } common->compiler = compiler; /* Main pcre2_jit_exec entry. */ SLJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0); -sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5 | SLJIT_ENTER_VECTOR(SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS), 5, private_data_size); +sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS, 0, private_data_size); /* Register init. */ reset_ovector(common, (re->top_bracket + 1) * 2); @@ -13520,7 +14410,7 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0) mainloop_label = mainloop_entry(common); continue_match_label = LABEL(); /* Forward search if possible. */ - if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) + if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) { if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common)) ; @@ -13535,8 +14425,7 @@ if ((re->overall_options & PCRE2_ANCHORED) == 0) else continue_match_label = LABEL(); -if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && - (re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) +if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) { OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength)); @@ -13571,9 +14460,8 @@ compile_matchingpath(common, common->start, ccend, &rootbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); - if (common->has_then) - SLJIT_FREE(common->then_offsets, allocator_data); PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); return PCRE2_ERROR_NOMEMORY; } @@ -13628,9 +14516,8 @@ compile_backtrackingpath(common, rootbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); - if (common->has_then) - SLJIT_FREE(common->then_offsets, allocator_data); PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); return PCRE2_ERROR_NOMEMORY; } @@ -13711,8 +14598,6 @@ common->early_fail_end_ptr = 0; common->currententry = common->entries; common->local_quit_available = TRUE; quit_label = common->quit_label; -SLJIT_ASSERT(common->restore_end_ptr == 0); - if (common->currententry != NULL) { /* A free bit for each private data. */ @@ -13742,28 +14627,24 @@ if (common->currententry != NULL) SLJIT_ASSERT(sljit_get_compiler_error(compiler) || common->recurse_bitset == NULL); sljit_free_compiler(compiler); + SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); - if (common->has_then) - SLJIT_FREE(common->then_offsets, allocator_data); PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); return PCRE2_ERROR_NOMEMORY; } } - common->local_quit_available = FALSE; common->quit_label = quit_label; -SLJIT_ASSERT(common->restore_end_ptr == 0); -/* Allocating stack, returns with PCRE2_ERROR_JIT_STACKLIMIT if fails. */ +/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ /* This is a (really) rare case. */ set_jumps(common->stackalloc, LABEL()); /* RETURN_ADDR is not a saved register. */ -SLJIT_ASSERT(common->locals_size >= 2 * SSIZE_OF(sw)); -sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCAL0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE); OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack)); @@ -13774,8 +14655,8 @@ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FU jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); OP_SRC(SLJIT_FAST_RETURN, TMP1, 0); /* Allocation failed. */ @@ -13896,9 +14777,8 @@ if (common->getucdtype != NULL) } #endif /* SUPPORT_UNICODE */ +SLJIT_FREE(common->optimized_cbracket, allocator_data); SLJIT_FREE(common->private_data_ptrs, allocator_data); -if (common->has_then) - SLJIT_FREE(common->then_offsets, allocator_data); executable_func = sljit_generate_code(compiler, 0, NULL); executable_size = sljit_get_generated_code_size(compiler); @@ -13968,36 +14848,9 @@ pcre2_jit_compile(pcre2_code *code, uint32_t options) { pcre2_real_code *re = (pcre2_real_code *)code; #ifdef SUPPORT_JIT -void *exec_memory; executable_functions *functions; static int executable_allocator_is_working = -1; - -if (executable_allocator_is_working == -1) - { - /* Checks whether the executable allocator is working. This check - might run multiple times in multi-threaded environments, but the - result should not be affected by it. */ - exec_memory = SLJIT_MALLOC_EXEC(32, NULL); - if (exec_memory != NULL) - { - SLJIT_FREE_EXEC(((sljit_u8*)(exec_memory)) + SLJIT_EXEC_OFFSET(exec_memory), NULL); - executable_allocator_is_working = 1; - } - else executable_allocator_is_working = 0; - } -#endif - -if (options & PCRE2_JIT_TEST_ALLOC) - { - if (options != PCRE2_JIT_TEST_ALLOC) - return PCRE2_ERROR_JIT_BADOPTION; - -#ifdef SUPPORT_JIT - return executable_allocator_is_working ? 0 : PCRE2_ERROR_NOMEMORY; -#else - return PCRE2_ERROR_JIT_UNSUPPORTED; #endif - } if (code == NULL) return PCRE2_ERROR_NULL; @@ -14059,6 +14912,20 @@ return PCRE2_ERROR_JIT_BADOPTION; if ((re->flags & PCRE2_NOJIT) != 0) return 0; +if (executable_allocator_is_working == -1) + { + /* Checks whether the executable allocator is working. This check + might run multiple times in multi-threaded environments, but the + result should not be affected by it. */ + void *ptr = SLJIT_MALLOC_EXEC(32, NULL); + if (ptr != NULL) + { + SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr), NULL); + executable_allocator_is_working = 1; + } + else executable_allocator_is_working = 0; + } + if (!executable_allocator_is_working) return PCRE2_ERROR_NOMEMORY; diff --git a/ext/pcre/pcre2lib/pcre2_jit_match.c b/ext/pcre/pcre2lib/pcre2_jit_match.c index 8867f768df15..ae5903e202b5 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_match.c +++ b/ext/pcre/pcre2lib/pcre2_jit_match.c @@ -83,7 +83,7 @@ return executable_func(arguments); Returns: > 0 => success; value is the number of ovector pairs filled = 0 => success, but ovector is not big enough - -1 => failed to match (PCRE2_ERROR_NOMATCH) + -1 => failed to match (PCRE_ERROR_NOMATCH) < -1 => some kind of unexpected problem */ diff --git a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h index 1389a16573d5..4a718b67b7eb 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h +++ b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h @@ -82,7 +82,7 @@ POSSIBILITY OF SUCH DAMAGE. # endif # endif -#if (defined(__GNUC__) && defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__ ) \ +#if (defined(__GNUC__) && __SANITIZE_ADDRESS__) \ || (defined(__clang__) \ && ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3))) __attribute__((no_sanitize_address)) @@ -198,14 +198,14 @@ vect_t data = VLD1Q(*str_ptr); #if PCRE2_CODE_UNIT_WIDTH != 8 data = VANDQ(data, char_mask); #endif - + #if defined(FFCS) vect_t eq = VCEQQ(data, vc1); #elif defined(FFCS_2) vect_t eq1 = VCEQQ(data, vc1); vect_t eq2 = VCEQQ(data, vc2); -vect_t eq = VORRQ(eq1, eq2); +vect_t eq = VORRQ(eq1, eq2); #elif defined(FFCS_MASK) vect_t eq = VORRQ(data, vmask); @@ -226,7 +226,7 @@ if (p1 < *str_ptr) } else data2 = shift_left_n_lanes(data, offs1 - offs2); - + if (compare1_type == compare_match1) data = VCEQQ(data, cmp1a); else @@ -281,7 +281,7 @@ while (*str_ptr < str_end) #elif defined(FFCS_2) eq1 = VCEQQ(data, vc1); eq2 = VCEQQ(data, vc2); - eq = VORRQ(eq1, eq2); + eq = VORRQ(eq1, eq2); #elif defined(FFCS_MASK) eq = VORRQ(data, vmask); diff --git a/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h b/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h index 66e93cd5996f..502977fc3204 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h +++ b/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h @@ -246,10 +246,10 @@ struct sljit_jump *quit; struct sljit_jump *partial_quit[2]; vector_compare_type compare_type = vector_compare_match1; sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); -sljit_s32 data_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0); -sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1); -sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2); -sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); sljit_u32 bit = 0; int i; @@ -273,17 +273,17 @@ if (common->mode == PCRE2_JIT_COMPLETE) /* First part (unaligned start) */ value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; -sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR1, SLJIT_VR1, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); if (char1 != char2) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); @@ -294,12 +294,12 @@ OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -318,11 +318,11 @@ if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, &common->failed_match, partial_quit[1]); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); @@ -380,10 +380,10 @@ struct sljit_jump *quit; jump_list *not_found = NULL; vector_compare_type compare_type = vector_compare_match1; sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); -sljit_s32 data_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0); -sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1); -sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2); -sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); sljit_u32 bit = 0; int i; @@ -406,29 +406,29 @@ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); /* First part (unaligned start) */ value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; -sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR1, SLJIT_VR1, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); if (char1 != char2) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -445,12 +445,12 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); @@ -488,14 +488,14 @@ sljit_u32 bit1 = 0; sljit_u32 bit2 = 0; sljit_u32 diff = IN_UCHARS(offs1 - offs2); sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); -sljit_s32 data1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0); -sljit_s32 data2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1); -sljit_s32 cmp1a_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2); -sljit_s32 cmp2a_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3); -sljit_s32 cmp1b_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR4); -sljit_s32 cmp2b_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR5); -sljit_s32 tmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR6); -sljit_s32 tmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_TMP_DEST_VREG); +sljit_s32 data1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 data2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp1a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 cmp2a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); +sljit_s32 cmp1b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR4); +sljit_s32 cmp2b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR5); +sljit_s32 tmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR6); +sljit_s32 tmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_TMP_FR0); struct sljit_label *start; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 struct sljit_label *restart; @@ -541,10 +541,10 @@ else } value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; -sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR2, 0, TMP1, 0); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, TMP1, 0); if (char1a != char1b) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR4, 0, TMP2, 0); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR4, 0, TMP2, 0); if (char2a == char2b) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); @@ -566,18 +566,18 @@ else } } -sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR3, 0, TMP1, 0); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR3, 0, TMP1, 0); if (char2a != char2b) - sljit_emit_simd_lane_mov(compiler, value, SLJIT_VR5, 0, TMP2, 0); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR5, 0, TMP2, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR2, SLJIT_VR2, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); if (char1a != char1b) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR4, SLJIT_VR4, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR4, SLJIT_FR4, 0); -sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR3, SLJIT_VR3, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR3, SLJIT_FR3, 0); if (char2a != char2b) - sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_VR5, SLJIT_VR5, 0); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR5, SLJIT_FR5, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); @@ -589,11 +589,11 @@ value = (reg_type == SLJIT_SIMD_REG_256) ? ~0x1f : ~0xf; OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0); -sljit_emit_simd_mov(compiler, reg_type, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); jump[1] = JUMP(SLJIT_JUMP); JUMPHERE(jump[0]); @@ -668,8 +668,8 @@ for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); } -sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); /* Ignore matches before the first STR_PTR. */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); @@ -687,8 +687,8 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; -sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0); -sljit_emit_simd_mov(compiler, reg_type, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); for (i = 0; i < 4; i++) { @@ -696,8 +696,8 @@ for (i = 0; i < 4; i++) fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); } -sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0); -sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_VR0, TMP1, 0); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); @@ -843,13 +843,12 @@ DEFINE_COMPILER; int_char ic; struct sljit_jump *partial_quit, *quit; /* Save temporary registers. */ -SLJIT_ASSERT(common->locals_size >= 2 * (int)sizeof(sljit_sw)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, TMP3, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0); /* Prepare function arguments */ OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0); -GET_LOCAL_BASE(SLJIT_R1, 0, LOCAL0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset); if (char1 == char2) @@ -911,8 +910,8 @@ else } } /* Restore registers. */ -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); -OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); /* Check return value. */ partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); @@ -1039,7 +1038,7 @@ SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); SLJIT_ASSERT(compiler->scratches == 5); /* Save temporary register STR_PTR. */ -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); /* Prepare arguments for the function call. */ if (common->match_end_ptr == 0) @@ -1053,7 +1052,7 @@ else SELECT(SLJIT_LESS, SLJIT_R0, STR_END, 0, SLJIT_R0); } -GET_LOCAL_BASE(SLJIT_R1, 0, LOCAL0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1); OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2); ic.c.c1 = char1a; @@ -1094,7 +1093,7 @@ if (diff == 1) { } /* Restore STR_PTR register. */ -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); /* Check return value. */ partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); diff --git a/ext/pcre/pcre2lib/pcre2_maketables.c b/ext/pcre/pcre2lib/pcre2_maketables.c index 0474cc7dbb41..ac8b63b8097f 100644 --- a/ext/pcre/pcre2lib/pcre2_maketables.c +++ b/ext/pcre/pcre2lib/pcre2_maketables.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -155,10 +155,10 @@ return yield; PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables) { -if (gcontext != NULL) - gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data); -else - free((void *)tables); + if (gcontext) + gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data); + else + free((void *)tables); } #endif diff --git a/ext/pcre/pcre2lib/pcre2_match.c b/ext/pcre/pcre2lib/pcre2_match.c index 5adc03480522..6c422c2e5ef9 100644 --- a/ext/pcre/pcre2lib/pcre2_match.c +++ b/ext/pcre/pcre2lib/pcre2_match.c @@ -155,17 +155,17 @@ changed, the code at RETURN_SWITCH below must be updated in sync. */ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, - RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39 }; + RM31, RM32, RM33, RM34, RM35, RM36, RM37 }; #ifdef SUPPORT_WIDE_CHARS -enum { RM100=100, RM101, RM102, RM103 }; +enum { RM100=100, RM101 }; #endif #ifdef SUPPORT_UNICODE enum { RM200=200, RM201, RM202, RM203, RM204, RM205, RM206, RM207, RM208, RM209, RM210, RM211, RM212, RM213, RM214, RM215, RM216, RM217, RM218, RM219, RM220, RM221, RM222, RM223, - RM224 }; + RM224, RM225 }; #endif /* Define short names for general fields in the current backtrack frame, which @@ -348,7 +348,6 @@ seems unlikely.) Arguments: offset index into the offset vector caseless TRUE if caseless - caseopts bitmask of REFI_FLAG_XYZ values F the current backtracking frame pointer mb points to match block lengthptr pointer for returning the length matched @@ -359,8 +358,8 @@ Returns: = 0 sucessful match; number of code units matched is set */ static int -match_ref(PCRE2_SIZE offset, BOOL caseless, int caseopts, heapframe *F, - match_block *mb, PCRE2_SIZE *lengthptr) +match_ref(PCRE2_SIZE offset, BOOL caseless, heapframe *F, match_block *mb, + PCRE2_SIZE *lengthptr) { PCRE2_SPTR p; PCRE2_SIZE length; @@ -390,8 +389,6 @@ if (caseless) { #if defined SUPPORT_UNICODE BOOL utf = (mb->poptions & PCRE2_UTF) != 0; - BOOL caseless_restrict = (caseopts & REFI_FLAG_CASELESS_RESTRICT) != 0; - BOOL turkish_casing = !caseless_restrict && (caseopts & REFI_FLAG_TURKISH_CASING) != 0; if (utf || (mb->poptions & PCRE2_UCP) != 0) { @@ -423,20 +420,10 @@ if (caseless) d = *p++; } - if (turkish_casing && UCD_ANY_I(d)) - { - c = UCD_FOLD_I_TURKISH(c); - d = UCD_FOLD_I_TURKISH(d); - if (c != d) return -1; /* No match */ - } - else if (c != d && c != (uint32_t)((int)d + (ur = GET_UCD(d))->other_case)) + ur = GET_UCD(d); + if (c != d && c != (uint32_t)((int)d + ur->other_case)) { const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset; - - /* When PCRE2_EXTRA_CASELESS_RESTRICT is set, ignore any caseless sets - that start with an ASCII character. */ - if (caseless_restrict && *pp < 128) return -1; /* No match */ - for (;;) { if (c < *pp) return -1; /* No match */ @@ -541,46 +528,38 @@ For hard partial matching, we immediately return a partial match. Otherwise, carrying on means that a complete match on the current subject will be sought. A partial match is returned only if no complete match can be found. */ -#define CHECK_PARTIAL() \ - do { \ - if (Feptr >= mb->end_subject) \ - { \ - SCHECK_PARTIAL(); \ - } \ - } \ - while (0) - -#define SCHECK_PARTIAL() \ - do { \ - if (mb->partial != 0 && \ - (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \ - { \ - mb->hitend = TRUE; \ - if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \ - } \ - } \ - while (0) +#define CHECK_PARTIAL()\ + if (Feptr >= mb->end_subject) \ + { \ + SCHECK_PARTIAL(); \ + } + +#define SCHECK_PARTIAL()\ + if (mb->partial != 0 && \ + (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \ + { \ + mb->hitend = TRUE; \ + if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \ + } /* These macros are used to implement backtracking. They simulate a recursive call to the match() function by means of a local vector of frames which remember the backtracking points. */ -#define RMATCH(ra,rb) \ - do { \ - start_ecode = ra; \ - Freturn_id = rb; \ - goto MATCH_RECURSE; \ - L_##rb:; \ - } \ - while (0) +#define RMATCH(ra,rb)\ + {\ + start_ecode = ra;\ + Freturn_id = rb;\ + goto MATCH_RECURSE;\ + L_##rb:;\ + } -#define RRETURN(ra) \ - do { \ - rrc = ra; \ - goto RETURN_SWITCH; \ - } \ - while (0) +#define RRETURN(ra)\ + {\ + rrc = ra;\ + goto RETURN_SWITCH;\ + } @@ -834,10 +813,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, offset = Flast_group_offset; for(;;) { - /* Corrupted heapframes?. Trigger an assert and return an error */ - PCRE2_ASSERT(offset != PCRE2_UNSET); if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; - N = (heapframe *)((char *)match_data->heapframes + offset); P = (heapframe *)((char *)N - frame_size); if (N->group_frame_type == (GF_CAPTURE | number)) break; @@ -876,10 +852,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, offset = Flast_group_offset; for(;;) { - /* Corrupted heapframes?. Trigger an assert and return an error */ - PCRE2_ASSERT(offset != PCRE2_UNSET); if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; - N = (heapframe *)((char *)match_data->heapframes + offset); P = (heapframe *)((char *)N - frame_size); if (GF_IDMASK(N->group_frame_type) == GF_RECURSE) break; @@ -1356,7 +1329,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } else /* Maximize */ @@ -1457,7 +1430,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH); Feptr++; } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } else /* Maximize */ @@ -1515,7 +1488,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } else /* Maximize */ { @@ -1733,7 +1706,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Feptr++; } } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } /* Maximize case */ @@ -1871,7 +1844,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH); } } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } /* Maximize case */ @@ -1955,7 +1928,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #define Lmax F->temp_32[1] #define Lstart_eptr F->temp_sptr[0] #define Lbyte_map_address F->temp_sptr[1] -#define Lbyte_map ((const unsigned char *)Lbyte_map_address) +#define Lbyte_map ((unsigned char *)Lbyte_map_address) case OP_NCLASS: case OP_CLASS: @@ -2098,7 +2071,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); } } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ @@ -2178,8 +2151,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } } - - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ #undef Lbyte_map_address #undef Lbyte_map @@ -2247,9 +2219,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - if (!PRIV(xclass)(fc, Lxclass_data, - (const uint8_t*)mb->start_code, utf)) - RRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH); } /* If Lmax == Lmin we can just continue with the main loop. */ @@ -2272,11 +2242,9 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - if (!PRIV(xclass)(fc, Lxclass_data, - (const uint8_t*)mb->start_code, utf)) - RRETURN(MATCH_NOMATCH); + if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ @@ -2297,8 +2265,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #else fc = *Feptr; #endif - if (!PRIV(xclass)(fc, Lxclass_data, - (const uint8_t*)mb->start_code, utf)) break; + if (!PRIV(xclass)(fc, Lxclass_data, utf)) break; Feptr += len; } @@ -2320,7 +2287,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } #endif /* SUPPORT_WIDE_CHARS: end of XCLASS */ @@ -2330,151 +2297,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #undef Lmax - /* ===================================================================== */ - /* Match a complex, set-based character class. This opcodes are used when - there is complex nesting or logical operations within the character - class. */ - -#define Lstart_eptr F->temp_sptr[0] -#define Leclass_data F->temp_sptr[1] -#define Leclass_len F->temp_size -#define Lmin F->temp_32[0] -#define Lmax F->temp_32[1] - -#ifdef SUPPORT_WIDE_CHARS - case OP_ECLASS: - { - Leclass_data = Fecode + 1 + LINK_SIZE; /* Save for matching */ - Fecode += GET(Fecode, 1); /* Advance past the item */ - Leclass_len = (PCRE2_SIZE)(Fecode - Leclass_data); - - switch (*Fecode) - { - case OP_CRSTAR: - case OP_CRMINSTAR: - case OP_CRPLUS: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - case OP_CRPOSSTAR: - case OP_CRPOSPLUS: - case OP_CRPOSQUERY: - fc = *Fecode++ - OP_CRSTAR; - Lmin = rep_min[fc]; - Lmax = rep_max[fc]; - reptype = rep_typ[fc]; - break; - - case OP_CRRANGE: - case OP_CRMINRANGE: - case OP_CRPOSRANGE: - Lmin = GET2(Fecode, 1); - Lmax = GET2(Fecode, 1 + IMM2_SIZE); - if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */ - reptype = rep_typ[*Fecode - OP_CRSTAR]; - Fecode += 1 + 2 * IMM2_SIZE; - break; - - default: /* No repeat follows */ - Lmin = Lmax = 1; - break; - } - - /* First, ensure the minimum number of matches are present. */ - - for (i = 1; i <= Lmin; i++) - { - if (Feptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(fc, Feptr); - if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len, - (const uint8_t*)mb->start_code, utf)) - RRETURN(MATCH_NOMATCH); - } - - /* If Lmax == Lmin we can just continue with the main loop. */ - - if (Lmin == Lmax) continue; - - /* If minimizing, keep testing the rest of the expression and advancing - the pointer while it matches the class. */ - - if (reptype == REPTYPE_MIN) - { - for (;;) - { - RMATCH(Fecode, RM102); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); - if (Feptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(fc, Feptr); - if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len, - (const uint8_t*)mb->start_code, utf)) - RRETURN(MATCH_NOMATCH); - } - PCRE2_UNREACHABLE(); /* Control never reaches here */ - } - - /* If maximizing, find the longest possible run, then work backwards. */ - - else - { - Lstart_eptr = Feptr; - for (i = Lmin; i < Lmax; i++) - { - int len = 1; - if (Feptr >= mb->end_subject) - { - SCHECK_PARTIAL(); - break; - } -#ifdef SUPPORT_UNICODE - GETCHARLENTEST(fc, Feptr, len); -#else - fc = *Feptr; -#endif - if (!PRIV(eclass)(fc, Leclass_data, Leclass_data + Leclass_len, - (const uint8_t*)mb->start_code, utf)) - break; - Feptr += len; - } - - if (reptype == REPTYPE_POS) continue; /* No backtracking */ - - /* After \C in UTF mode, Lstart_eptr might be in the middle of a - Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't - go too far. */ - - for(;;) - { - RMATCH(Fecode, RM103); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */ -#ifdef SUPPORT_UNICODE - if (utf) BACKCHAR(Feptr); -#endif - } - RRETURN(MATCH_NOMATCH); - } - - PCRE2_UNREACHABLE(); /* Control never reaches here */ - } -#endif /* SUPPORT_WIDE_CHARS: end of ECLASS */ - -#undef Lstart_eptr -#undef Leclass_data -#undef Leclass_len -#undef Lmin -#undef Lmax - - /* ===================================================================== */ /* Match various character types when PCRE2_UCP is not set. These opcodes are not generated when PCRE2_UCP is set - instead appropriate property @@ -2670,6 +2492,10 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, switch(Fecode[1]) { + case PT_ANY: + if (notmatch) RRETURN(MATCH_NOMATCH); + break; + case PT_LAMP: chartype = prop->chartype; if ((chartype == ucp_Lu || @@ -2780,7 +2606,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, /* This should never occur */ default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -2903,6 +2728,19 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, BOOL notmatch = Lctype == OP_NOTPROP; switch(proptype) { + case PT_ANY: + if (notmatch) RRETURN(MATCH_NOMATCH); + for (i = 1; i <= Lmin; i++) + { + if (Feptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(fc, Feptr); + } + break; + case PT_LAMP: for (i = 1; i <= Lmin; i++) { @@ -3131,7 +2969,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, /* This should not occur */ default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -3407,7 +3244,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } /* End switch(Lctype) */ @@ -3660,7 +3496,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -3681,11 +3516,27 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, { switch(proptype) { + case PT_ANY: + for (;;) + { + RMATCH(Fecode, RM208); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); + if (Feptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + RRETURN(MATCH_NOMATCH); + } + GETCHARINCTEST(fc, Feptr); + if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH); + } + /* Control never gets here */ + case PT_LAMP: for (;;) { int chartype; - RMATCH(Fecode, RM208); + RMATCH(Fecode, RM209); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3700,12 +3551,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, chartype == ucp_Lt) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_GC: for (;;) { - RMATCH(Fecode, RM209); + RMATCH(Fecode, RM210); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3717,12 +3568,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_PC: for (;;) { - RMATCH(Fecode, RM210); + RMATCH(Fecode, RM211); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3734,12 +3585,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_SC: for (;;) { - RMATCH(Fecode, RM211); + RMATCH(Fecode, RM212); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3751,14 +3602,14 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_SCX: for (;;) { BOOL ok; const ucd_record *prop; - RMATCH(Fecode, RM224); + RMATCH(Fecode, RM225); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3773,13 +3624,13 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (ok == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_ALNUM: for (;;) { int category; - RMATCH(Fecode, RM212); + RMATCH(Fecode, RM213); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3792,7 +3643,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((category == ucp_L || category == ucp_N) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ /* Perl space used to exclude VT, but from Perl 5.18 it is included, which means that Perl space and POSIX space are now identical. PCRE @@ -3802,7 +3653,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case PT_PXSPACE: /* POSIX space */ for (;;) { - RMATCH(Fecode, RM213); + RMATCH(Fecode, RM214); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3824,13 +3675,13 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; } } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_WORD: for (;;) { int chartype, category; - RMATCH(Fecode, RM214); + RMATCH(Fecode, RM215); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3847,13 +3698,13 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, chartype == ucp_Pc) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_CLIST: for (;;) { const uint32_t *cp; - RMATCH(Fecode, RM215); + RMATCH(Fecode, RM216); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3884,12 +3735,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } } } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_UCNC: for (;;) { - RMATCH(Fecode, RM216); + RMATCH(Fecode, RM217); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3903,12 +3754,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, fc >= 0xe000) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_BIDICL: for (;;) { - RMATCH(Fecode, RM223); + RMATCH(Fecode, RM224); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3920,14 +3771,14 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((UCD_BIDICLASS(fc) == Lpropvalue) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ case PT_BOOL: for (;;) { BOOL ok; const ucd_record *prop; - RMATCH(Fecode, RM222); + RMATCH(Fecode, RM223); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3942,11 +3793,10 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (ok == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ /* This should never occur */ default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -3958,7 +3808,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, { for (;;) { - RMATCH(Fecode, RM217); + RMATCH(Fecode, RM218); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -3985,7 +3835,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, { for (;;) { - RMATCH(Fecode, RM218); + RMATCH(Fecode, RM219); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); if (Feptr >= mb->end_subject) @@ -4101,7 +3951,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } @@ -4246,13 +4095,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } } } - - PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ + /* Control never gets here */ } /* If maximizing, it is worth using inline code for speed, doing the type @@ -4270,6 +4117,21 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, BOOL notmatch = Lctype == OP_NOTPROP; switch(proptype) { + case PT_ANY: + for (i = Lmin; i < Lmax; i++) + { + int len = 1; + if (Feptr >= mb->end_subject) + { + SCHECK_PARTIAL(); + break; + } + GETCHARLENTEST(fc, Feptr, len); + if (notmatch) break; + Feptr+= len; + } + break; + case PT_LAMP: for (i = Lmin; i < Lmax; i++) { @@ -4515,7 +4377,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -4530,7 +4391,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for(;;) { if (Feptr <= Lstart_eptr) break; - RMATCH(Fecode, RM221); + RMATCH(Fecode, RM222); if (rrc != MATCH_NOMATCH) RRETURN(rrc); Feptr--; if (utf) BACKCHAR(Feptr); @@ -4573,7 +4434,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, PCRE2_SPTR fptr; if (Feptr <= Lstart_eptr) break; /* At start of char run */ - RMATCH(Fecode, RM219); + RMATCH(Fecode, RM220); if (rrc != MATCH_NOMATCH) RRETURN(rrc); /* Backtracking over an extended grapheme cluster involves inspecting @@ -4834,7 +4695,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -4847,7 +4707,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for(;;) { if (Feptr <= Lstart_eptr) break; - RMATCH(Fecode, RM220); + RMATCH(Fecode, RM221); if (rrc != MATCH_NOMATCH) RRETURN(rrc); Feptr--; BACKCHAR(Feptr); @@ -5092,7 +4952,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, break; default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -5129,18 +4988,16 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #define Lmin F->temp_32[0] #define Lmax F->temp_32[1] #define Lcaseless F->temp_32[2] -#define Lcaseopts F->temp_32[3] #define Lstart F->temp_sptr[0] #define Loffset F->temp_size case OP_DNREF: case OP_DNREFI: Lcaseless = (Fop == OP_DNREFI); - Lcaseopts = (Fop == OP_DNREFI)? Fecode[1 + 2*IMM2_SIZE] : 0; { int count = GET2(Fecode, 1+IMM2_SIZE); PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size; - Fecode += 1 + 2*IMM2_SIZE + (Fop == OP_DNREFI? 1 : 0); + Fecode += 1 + 2*IMM2_SIZE; while (count-- > 0) { @@ -5154,9 +5011,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_REF: case OP_REFI: Lcaseless = (Fop == OP_REFI); - Lcaseopts = (Fop == OP_REFI)? Fecode[1 + IMM2_SIZE] : 0; Loffset = (GET2(Fecode, 1) << 1) - 2; - Fecode += 1 + IMM2_SIZE + (Fop == OP_REFI? 1 : 0); + Fecode += 1 + IMM2_SIZE; /* Set up for repetition, or handle the non-repeated case. The maximum and minimum must be in the heap frame, but as they are short-term values, we @@ -5188,7 +5044,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, default: /* No repeat follows */ { - rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &length); + rrc = match_ref(Loffset, Lcaseless, F, mb, &length); if (rrc != 0) { if (rrc > 0) Feptr = mb->end_subject; /* Partial match */ @@ -5222,7 +5078,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for (i = 1; i <= Lmin; i++) { PCRE2_SIZE slength; - rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); + rrc = match_ref(Loffset, Lcaseless, F, mb, &slength); if (rrc != 0) { if (rrc > 0) Feptr = mb->end_subject; /* Partial match */ @@ -5246,7 +5102,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RMATCH(Fecode, RM20); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); - rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); + rrc = match_ref(Loffset, Lcaseless, F, mb, &slength); if (rrc != 0) { if (rrc > 0) Feptr = mb->end_subject; /* Partial match */ @@ -5255,8 +5111,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } Feptr += slength; } - - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never gets here */ } /* If maximizing, find the longest string and work backwards, as long as @@ -5271,7 +5126,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for (i = Lmin; i < Lmax; i++) { PCRE2_SIZE slength; - rrc = match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); + rrc = match_ref(Loffset, Lcaseless, F, mb, &slength); if (rrc != 0) { /* Can't use CHECK_PARTIAL because we don't want to update Feptr in @@ -5322,7 +5177,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, for (i = Lmin; i < Lmax; i++) { PCRE2_SIZE slength; - (void)match_ref(Loffset, Lcaseless, Lcaseopts, F, mb, &slength); + (void)match_ref(Loffset, Lcaseless, F, mb, &slength); Feptr += slength; } } @@ -5330,8 +5185,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, RRETURN(MATCH_NOMATCH); } - - PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ + /* Control never gets here */ #undef Lcaseless #undef Lmin @@ -5555,7 +5409,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += GET(Fecode, 1); if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never reaches here. */ #undef Lframe_type @@ -5640,7 +5494,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Lstart_branch = next_ecode; if (*Lstart_branch != OP_ALT) RRETURN(MATCH_NOMATCH); } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never reaches here. */ #undef Lframe_type #undef Lstart_branch @@ -5731,132 +5585,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #undef Lframe_type - /* ===================================================================== */ - /* Handle scan substring operation. */ - -#define Lframe_type F->temp_32[0] -#define Lextra_size F->temp_32[1] -#define Lsaved_moptions F->temp_32[2] -#define Lsaved_end_subject F->temp_sptr[0] -#define Lsaved_eptr F->temp_sptr[1] -#define Ltrue_end_extra F->temp_size - - case OP_ASSERT_SCS: - { - PCRE2_SPTR ecode = Fecode + 1 + LINK_SIZE; - uint32_t extra_size = 0; - int count; - PCRE2_SPTR slot; - - /* Disable compiler warning. */ - offset = 0; - (void)offset; - - for (;;) - { - if (*ecode == OP_CREF) - { - extra_size += 1+IMM2_SIZE; - offset = (GET2(ecode, 1) << 1) - 2; - ecode += 1+IMM2_SIZE; - if (offset < Foffset_top && Fovector[offset] != PCRE2_UNSET) - goto SCS_OFFSET_FOUND; - continue; - } - - if (*ecode != OP_DNCREF) RRETURN(MATCH_NOMATCH); - - count = GET2(ecode, 1 + IMM2_SIZE); - slot = mb->name_table + GET2(ecode, 1) * mb->name_entry_size; - extra_size += 1+2*IMM2_SIZE; - ecode += 1+2*IMM2_SIZE; - - while (count > 0) - { - offset = (GET2(slot, 0) << 1) - 2; - if (offset < Foffset_top && Fovector[offset] != PCRE2_UNSET) - goto SCS_OFFSET_FOUND; - slot += mb->name_entry_size; - count--; - } - } - - SCS_OFFSET_FOUND: - - /* Skip remaining options. */ - for (;;) - { - if (*ecode == OP_CREF) - { - extra_size += 1+IMM2_SIZE; - ecode += 1+IMM2_SIZE; - } - else if (*ecode == OP_DNCREF) - { - extra_size += 1+2*IMM2_SIZE; - ecode += 1+2*IMM2_SIZE; - } - else break; - } - - Lextra_size = extra_size; - } - - Lsaved_end_subject = mb->end_subject; - Ltrue_end_extra = mb->true_end_subject - mb->end_subject; - Lsaved_eptr = Feptr; - Lsaved_moptions = mb->moptions; - - Feptr = mb->start_subject + Fovector[offset]; - mb->true_end_subject = mb->end_subject = - mb->start_subject + Fovector[offset + 1]; - mb->moptions &= ~PCRE2_NOTEOL; - - Lframe_type = GF_NOCAPTURE | Fop; - for (;;) - { - group_frame_type = Lframe_type; - RMATCH(Fecode + 1 + LINK_SIZE + Lextra_size, RM38); - if (rrc == MATCH_ACCEPT) - { - memcpy(Fovector, - (char *)assert_accept_frame + offsetof(heapframe, ovector), - assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); - Foffset_top = assert_accept_frame->offset_top; - Fmark = assert_accept_frame->mark; - break; - } - - if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) - { - mb->end_subject = Lsaved_end_subject; - mb->true_end_subject = mb->end_subject + Ltrue_end_extra; - mb->moptions = Lsaved_moptions; - RRETURN(rrc); - } - - Fecode += GET(Fecode, 1); - if (*Fecode != OP_ALT) - { - mb->end_subject = Lsaved_end_subject; - mb->true_end_subject = mb->end_subject + Ltrue_end_extra; - mb->moptions = Lsaved_moptions; - RRETURN(MATCH_NOMATCH); - } - Lextra_size = 0; - } - - do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT); - Fecode += 1 + LINK_SIZE; - Feptr = Lsaved_eptr; - break; - -#undef Lframe_type -#undef Lextra_size -#undef Lsaved_end_subject -#undef Lsaved_eptr -#undef Ltrue_end_extra -#undef Lsave_moptions /* ===================================================================== */ /* The callout item calls an external function, if one is provided, passing @@ -6067,11 +5795,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, #ifdef SUPPORT_UNICODE if (utf) { - /* We used to do a simpler `while (number-- > 0)` but that triggers - clang's unsigned integer overflow sanitizer. */ - while (number > 0) + while (number-- > 0) { - --number; if (Feptr <= mb->check_subject) RRETURN(MATCH_NOMATCH); Feptr--; BACKCHAR(Feptr); @@ -6144,7 +5869,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, } /* Now try matching, moving forward one character on failure, until we - reach the minimum back length. */ + reach the mimimum back length. */ for (;;) { @@ -6156,7 +5881,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if (utf) { FORWARDCHARTEST(Feptr, mb->end_subject); } #endif } - PCRE2_UNREACHABLE(); /* Control never reaches here */ + /* Control never reaches here */ #undef Lmin #undef Lmax @@ -6206,20 +5931,14 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, (char *)P->eptr - (char *)mb->start_subject); #endif - /* If we are at the end of an assertion that is a condition, first check - to see if we are at the end of a variable-length branch in a lookbehind. - If this is the case and we have not landed on the current character, - return no match. Compare code below for non-condition lookbehinds. In - other cases, return a match, discarding any intermediate backtracking - points. Copy back the mark setting and the captures into the frame before - N so that they are set on return. Doing this for all assertions, both - positive and negative, seems to match what Perl does. */ + /* If we are at the end of an assertion that is a condition, return a + match, discarding any intermediate backtracking points. Copy back the + mark setting and the captures into the frame before N so that they are + set on return. Doing this for all assertions, both positive and negative, + seems to match what Perl does. */ if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT) { - if ((*bracode == OP_ASSERTBACK || *bracode == OP_ASSERTBACK_NOT) && - branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) - RRETURN(MATCH_NOMATCH); memcpy((char *)P + offsetof(heapframe, ovector), Fovector, Foffset_top * sizeof(PCRE2_SIZE)); P->offset_top = Foffset_top; @@ -6248,11 +5967,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, /* It is the end of whole-pattern recursion. */ offset = Flast_group_offset; - - /* Corrupted heapframes?. Trigger an assert and return an error */ - PCRE2_ASSERT(offset != PCRE2_UNSET); if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; - N = (heapframe *)((char *)match_data->heapframes + offset); P = (heapframe *)((char *)N - frame_size); Flast_group_offset = P->last_group_offset; @@ -6327,23 +6042,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); - /* A scan substring group must preserve the current end_subject, - and restore it before the backtracking is performed into its sub - pattern. */ - - case OP_ASSERT_SCS: - F->temp_sptr[0] = mb->end_subject; - mb->end_subject = P->temp_sptr[0]; - mb->true_end_subject = mb->end_subject + P->temp_size; - Feptr = P->temp_sptr[1]; - - RMATCH(Fecode + 1 + LINK_SIZE, RM39); - - mb->end_subject = F->temp_sptr[0]; - mb->true_end_subject = mb->end_subject; - RRETURN(rrc); - break; - /* At the end of a script run, apply the script-checking rules. This code will never by exercised if Unicode support it not compiled, because in that environment script runs cause an error at compile time. */ @@ -6467,8 +6165,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_EODN: ASSERT_NL_OR_EOS: - if (Feptr < mb->true_end_subject && - (!IS_NEWLINE(Feptr) || Feptr != mb->true_end_subject - mb->nllen)) + if (Feptr < mb->end_subject && + (!IS_NEWLINE(Feptr) || Feptr != mb->end_subject - mb->nllen)) { if (mb->partial != 0 && Feptr + 1 >= mb->end_subject && @@ -6749,7 +6447,6 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, something seriously wrong in the code above or the OP_xxx definitions. */ default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } @@ -6758,8 +6455,8 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, loop. */ } /* End of main loop */ +/* Control never reaches here */ -PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ /* ========================================================================= */ /* The RRETURN() macro jumps here. The number that is saved in Freturn_id @@ -6785,21 +6482,20 @@ switch (Freturn_id) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16) LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24) LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32) - LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) LBL(38) LBL(39) + LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) #ifdef SUPPORT_WIDE_CHARS - LBL(100) LBL(101) LBL(102) LBL(103) + LBL(100) LBL(101) #endif #ifdef SUPPORT_UNICODE LBL(200) LBL(201) LBL(202) LBL(203) LBL(204) LBL(205) LBL(206) LBL(207) LBL(208) LBL(209) LBL(210) LBL(211) LBL(212) LBL(213) LBL(214) LBL(215) LBL(216) LBL(217) LBL(218) LBL(219) LBL(220) - LBL(221) LBL(222) LBL(223) LBL(224) + LBL(221) LBL(222) LBL(223) LBL(224) LBL(225) #endif default: - PCRE2_DEBUG_UNREACHABLE(); return PCRE2_ERROR_INTERNAL; } #undef LBL @@ -6925,7 +6621,7 @@ if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8) /* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the options variable for this function. Users of PCRE2 who are not calling the function directly would like to have a way of setting these flags, in the same -way that they can set pcre2_compile() flags like PCRE2_NO_AUTO_POSSESS with +way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and (*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which we now transfer to the options for this function. The bits are guaranteed to be @@ -7007,6 +6703,9 @@ if (use_jit) #ifdef SUPPORT_UNICODE if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid) { +#if PCRE2_CODE_UNIT_WIDTH != 32 + unsigned int i; +#endif /* For 8-bit and 16-bit UTF, check that the first code unit is a valid character start. */ @@ -7027,7 +6726,7 @@ if (use_jit) start of matching. */ #if PCRE2_CODE_UNIT_WIDTH != 32 - for (unsigned int i = re->max_lookbehind; i > 0 && start_match > subject; i--) + for (i = re->max_lookbehind; i > 0 && start_match > subject; i--) { start_match--; while (start_match > subject && @@ -7274,10 +6973,10 @@ mb->mark = mb->nomatch_mark = NULL; /* In case never set */ /* The name table is needed for finding all the numbers associated with a given name, for condition testing. The code follows the name table. */ -mb->name_table = (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code)); +mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)); mb->name_count = re->name_count; mb->name_entry_size = re->name_entry_size; -mb->start_code = (PCRE2_SPTR)((const uint8_t *)re + re->code_start); +mb->start_code = mb->name_table + re->name_count * re->name_entry_size; /* Process the \R and newline settings. */ @@ -7314,9 +7013,7 @@ switch(re->newline_convention) mb->nltype = NLTYPE_ANYCRLF; break; - default: - PCRE2_DEBUG_UNREACHABLE(); - return PCRE2_ERROR_INTERNAL; + default: return PCRE2_ERROR_INTERNAL; } /* The backtracking frames have fixed data at the front, and a PCRE2_SIZE @@ -7462,7 +7159,7 @@ for(;;) However, there is an option (settable at compile time) that disables these, for testing and for ensuring that all callouts do actually occur. */ - if ((re->optimization_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0) + if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) { /* If firstline is TRUE, the start of the match is constrained to the first line of a multiline string. That is, the match must be before or at the diff --git a/ext/pcre/pcre2lib/pcre2_match_data.c b/ext/pcre/pcre2lib/pcre2_match_data.c index 100e7c9d944c..757dab9df51d 100644 --- a/ext/pcre/pcre2lib/pcre2_match_data.c +++ b/ext/pcre/pcre2lib/pcre2_match_data.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2022 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -77,16 +77,14 @@ return yield; * Create a match data block using pattern data * *************************************************/ -/* If no context is supplied, use the memory allocator from the code. This code -assumes that a general context contains nothing other than a memory allocator. -If that ever changes, this code will need fixing. */ +/* If no context is supplied, use the memory allocator from the code. */ PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION pcre2_match_data_create_from_pattern(const pcre2_code *code, pcre2_general_context *gcontext) { if (gcontext == NULL) gcontext = (pcre2_general_context *)code; -return pcre2_match_data_create(((const pcre2_real_code *)code)->top_bracket + 1, +return pcre2_match_data_create(((pcre2_real_code *)code)->top_bracket + 1, gcontext); } diff --git a/ext/pcre/pcre2lib/pcre2_ord2utf.c b/ext/pcre/pcre2lib/pcre2_ord2utf.c index a1e9e08803bc..1403730996d6 100644 --- a/ext/pcre/pcre2lib/pcre2_ord2utf.c +++ b/ext/pcre/pcre2lib/pcre2_ord2utf.c @@ -117,4 +117,4 @@ return 1; } #endif /* SUPPORT_UNICODE */ -/* End of pcre2_ord2utf.c */ +/* End of pcre_ord2utf.c */ diff --git a/ext/pcre/pcre2lib/pcre2_pattern_info.c b/ext/pcre/pcre2lib/pcre2_pattern_info.c index fe4d3c661a01..a29f5eff673b 100644 --- a/ext/pcre/pcre2lib/pcre2_pattern_info.c +++ b/ext/pcre/pcre2lib/pcre2_pattern_info.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ Returns: 0 when data returned PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where) { -const pcre2_real_code *re = (const pcre2_real_code *)code; +const pcre2_real_code *re = (pcre2_real_code *)code; if (where == NULL) /* Requests field length */ { @@ -230,8 +230,7 @@ switch(what) break; case PCRE2_INFO_NAMETABLE: - *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((const char *)re + - sizeof(pcre2_real_code)); + *((PCRE2_SPTR *)where) = (PCRE2_SPTR)((char *)re + sizeof(pcre2_real_code)); break; case PCRE2_INFO_NEWLINE: @@ -269,7 +268,7 @@ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_callout_enumerate(const pcre2_code *code, int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data) { -const pcre2_real_code *re = (const pcre2_real_code *)code; +pcre2_real_code *re = (pcre2_real_code *)code; pcre2_callout_enumerate_block cb; PCRE2_SPTR cc; #ifdef SUPPORT_UNICODE @@ -292,7 +291,7 @@ if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC; if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE; cb.version = 0; -cc = (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code)) +cc = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)) + re->name_count * re->name_entry_size; while (TRUE) @@ -384,9 +383,8 @@ while (TRUE) #endif break; -#ifdef SUPPORT_WIDE_CHARS +#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 case OP_XCLASS: - case OP_ECLASS: cc += GET(cc, 1); break; #endif diff --git a/ext/pcre/pcre2lib/pcre2_printint.c b/ext/pcre/pcre2lib/pcre2_printint.c index 84f84f82f733..870e283b7456 100644 --- a/ext/pcre/pcre2lib/pcre2_printint.c +++ b/ext/pcre/pcre2lib/pcre2_printint.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -53,7 +53,6 @@ pcre2_internal.h, which is #included by pcre2test before this file. */ #ifndef OP_LISTS_DEFINED static const char *OP_names[] = { OP_NAME_LIST }; -STATIC_ASSERT(sizeof(OP_names)/sizeof(*OP_names) == OP_TABLE_LENGTH, OP_names); #define OP_LISTS_DEFINED #endif @@ -66,17 +65,13 @@ STATIC_ASSERT(sizeof(OP_names)/sizeof(*OP_names) == OP_TABLE_LENGTH, OP_names); #define print_custring PCRE2_SUFFIX(print_custring_) #define print_custring_bylen PCRE2_SUFFIX(print_custring_bylen_) #define print_prop PCRE2_SUFFIX(print_prop_) -#define print_char_list PCRE2_SUFFIX(print_char_list_) -#define print_map PCRE2_SUFFIX(print_map_) -#define print_class PCRE2_SUFFIX(print_class_) /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that the definition is next to the definition of the opcodes in pcre2_internal.h. The contents of the table are, however, mode-dependent. */ static const uint8_t OP_lengths[] = { OP_LENGTHS }; -STATIC_ASSERT(sizeof(OP_lengths)/sizeof(*OP_lengths) == OP_TABLE_LENGTH, - PCRE2_SUFFIX(OP_lengths_)); + /************************************************* @@ -250,7 +245,7 @@ const char *yield = "??"; size_t len = 0; unsigned int ptypex = (ptype == PT_SC)? PT_SCX : ptype; -for (ptrdiff_t i = PRIV(utt_size) - 1; i >= 0; i--) +for (int i = PRIV(utt_size) - 1; i >= 0; i--) { const ucp_type_table *u = PRIV(utt) + i; @@ -323,298 +318,6 @@ else -/************************************************* -* Print character list * -*************************************************/ - -/* Prints the characters and character ranges in a character list. - -Arguments: - f file to write to - code pointer in the compiled code -*/ - -static PCRE2_SPTR -print_char_list(FILE *f, PCRE2_SPTR code, const uint8_t *char_lists_end) -{ -uint32_t type, list_ind; -uint32_t char_list_add = XCL_CHAR_LIST_LOW_16_ADD; -uint32_t range_start = ~(uint32_t)0, range_end = 0; -const uint8_t *next_char; - -#if PCRE2_CODE_UNIT_WIDTH == 8 -type = (uint32_t)(code[0] << 8) | code[1]; -code += 2; -#else -type = code[0]; -code++; -#endif /* CODE_UNIT_WIDTH */ - -/* Align characters. */ -next_char = char_lists_end - (GET(code, 0) << 1); -type &= XCL_TYPE_MASK; -list_ind = 0; - -if ((type & XCL_BEGIN_WITH_RANGE) != 0) - range_start = XCL_CHAR_LIST_LOW_16_START; - -while (type > 0) - { - uint32_t item_count = type & XCL_ITEM_COUNT_MASK; - - if (item_count == XCL_ITEM_COUNT_MASK) - { - if (list_ind <= 1) - { - item_count = *(const uint16_t*)next_char; - next_char += 2; - } - else - { - item_count = *(const uint32_t*)next_char; - next_char += 4; - } - } - - while (item_count > 0) - { - if (list_ind <= 1) - { - range_end = *(const uint16_t*)next_char; - next_char += 2; - } - else - { - range_end = *(const uint32_t*)next_char; - next_char += 4; - } - - if ((range_end & XCL_CHAR_END) != 0) - { - range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT); - - if (range_start < range_end) - fprintf(f, "\\x{%x}-", range_start); - - fprintf(f, "\\x{%x}", range_end); - range_start = ~(uint32_t)0; - } - else - range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT); - - item_count--; - } - - list_ind++; - type >>= XCL_TYPE_BIT_LEN; - - /* The following code could be optimized to 8/16/32 bit, - but it is not worth it for a debugging function. */ - - if (range_start == ~(uint32_t)0) - { - if ((type & XCL_BEGIN_WITH_RANGE) != 0) - { - if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START; - else if (list_ind == 2) range_start = XCL_CHAR_LIST_LOW_32_START; - else range_start = XCL_CHAR_LIST_HIGH_32_START; - } - } - else if ((type & XCL_BEGIN_WITH_RANGE) == 0) - { - fprintf(f, "\\x{%x}-", range_start); - - if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END; - else if (list_ind == 2) range_end = XCL_CHAR_LIST_HIGH_16_END; - else if (list_ind == 3) range_end = XCL_CHAR_LIST_LOW_32_END; - else range_end = XCL_CHAR_LIST_HIGH_32_END; - - fprintf(f, "\\x{%x}", range_end); - range_start = ~(uint32_t)0; - } - - if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; - else if (list_ind == 2) char_list_add = XCL_CHAR_LIST_LOW_32_ADD; - else char_list_add = XCL_CHAR_LIST_HIGH_32_ADD; - } - -return code + LINK_SIZE; -} - - - -/************************************************* -* Print a character bitmap * -*************************************************/ - -/* Prints a 32-byte bitmap, which occurs within a character class opcode. - -Arguments: - f file to write to - map pointer to the bitmap - negated TRUE if the bitmap will be printed as negated - -Returns: nothing -*/ - -static void -print_map(FILE *f, const uint8_t *map, BOOL negated) -{ -BOOL first = TRUE; -uint8_t inverted_map[32]; -int i; - -if (negated) - { - /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ - for (i = 0; i < 32; i++) inverted_map[i] = 255 ^ map[i]; - map = inverted_map; - } - -for (i = 0; i < 256; i++) - { - if ((map[i/8] & (1u << (i&7))) != 0) - { - int j; - for (j = i+1; j < 256; j++) - if ((map[j/8] & (1u << (j&7))) == 0) break; - if (i == '-' || i == '\\' || i == ']' || (first && i == '^')) - fprintf(f, "\\"); - if (PRINTABLE(i)) fprintf(f, "%c", i); - else fprintf(f, "\\x%02x", i); - first = FALSE; - if (--j > i) - { - if (j != i + 1) fprintf(f, "-"); - if (j == '-' || j == '\\' || j == ']') fprintf(f, "\\"); - if (PRINTABLE(j)) fprintf(f, "%c", j); - else fprintf(f, "\\x%02x", j); - } - i = j; - } - } -} - - - -/************************************************* -* Print character class * -*************************************************/ - -/* Prints a character class, which must be either an OP_CLASS, OP_NCLASS, or -OP_XCLASS. - -Arguments: - f file to write to - type OP_CLASS, OP_NCLASS, or OP_XCLASS - code pointer in the compiled code (after the OP tag) - utf TRUE if re is UTF (will be FALSE if UTF is not supported) - before text to print before - after text to print after - -Returns: nothing -*/ - -static void -print_class(FILE *f, int type, PCRE2_SPTR code, const uint8_t *char_lists_end, - BOOL utf, const char *before, const char *after) -{ -BOOL printmap, negated; -PCRE2_SPTR ccode; - -/* Negative XCLASS and NCLASS both have a bitmap indicating which characters -are accepted. For clarity we print this inverted and prefixed by "^". */ -if (type == OP_XCLASS) - { - ccode = code + LINK_SIZE; - printmap = (*ccode & XCL_MAP) != 0; - negated = (*ccode & XCL_NOT) != 0; - ccode++; - } -else /* CLASS or NCLASS */ - { - printmap = TRUE; - negated = type == OP_NCLASS; - ccode = code; - } - -fprintf(f, "%s[%s", before, negated? "^" : ""); - -/* Print a bit map */ -if (printmap) - { - print_map(f, (const uint8_t *)ccode, negated); - ccode += 32 / sizeof(PCRE2_UCHAR); - } - -/* For an XCLASS there is always some additional data */ -if (type == OP_XCLASS) - { - PCRE2_UCHAR ch; - - while ((ch = *ccode++) != XCL_END) - { - const char *notch = ""; - - if (ch >= XCL_LIST) - { - ccode = print_char_list(f, ccode - 1, char_lists_end); - break; - } - - switch(ch) - { - case XCL_NOTPROP: - notch = "^"; - /* Fall through */ - case XCL_PROP: - { - unsigned int ptype = *ccode++; - unsigned int pvalue = *ccode++; - const char *s; - switch(ptype) - { - case PT_PXGRAPH: - fprintf(f, "[:%sgraph:]", notch); - break; - case PT_PXPRINT: - fprintf(f, "[:%sprint:]", notch); - break; - case PT_PXPUNCT: - fprintf(f, "[:%spunct:]", notch); - break; - case PT_PXXDIGIT: - fprintf(f, "[:%sxdigit:]", notch); - break; - default: - s = get_ucpname(ptype, pvalue); - fprintf(f, "\\%c{%c%s}", ((notch[0] == '^')? 'P':'p'), - toupper(s[0]), s+1); - break; - } - } - break; - - default: - ccode += 1 + print_char(f, ccode, utf); - if (ch == XCL_RANGE) - { - fprintf(f, "-"); - ccode += 1 + print_char(f, ccode, utf); - } - break; - } - } - - PCRE2_ASSERT(ccode == code + (GET(code, 0) - 1)); - } - -/* Indicate a non-UTF class which was created by negation */ -fprintf(f, "]%s", after); -} - - - /************************************************* * Print compiled pattern * *************************************************/ @@ -639,7 +342,7 @@ uint32_t nesize = re->name_entry_size; BOOL utf = (re->overall_options & PCRE2_UTF) != 0; nametable = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); -code = codestart = (PCRE2_SPTR)((uint8_t *)re + re->code_start); +code = codestart = nametable + re->name_count * re->name_entry_size; for(;;) { @@ -656,6 +359,20 @@ for(;;) switch(*code) { +/* ========================================================================== */ + /* These cases are never obeyed. This is a fudge that causes a compile- + time error if the vectors OP_names or OP_lengths, which are indexed + by opcode, are not the correct length. It seems to be the only way to do + such a check at compile time, as the sizeof() operator does not work in + the C preprocessor. */ + + case OP_TABLE_LENGTH: + case OP_TABLE_LENGTH + + ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) && + (sizeof(OP_lengths) == OP_TABLE_LENGTH)): + return; +/* ========================================================================== */ + case OP_END: fprintf(f, " %s\n", OP_names[*code]); fprintf(f, "------------------------------------------------------------------\n"); @@ -707,7 +424,6 @@ for(;;) case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: case OP_ONCE: case OP_SCRIPT_RUN: case OP_COND: @@ -741,7 +457,7 @@ for(;;) case OP_DNCREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; - fprintf(f, " %s Capture ref <", flag); + fprintf(f, " %s Cond ref <", flag); print_custring(f, entry); fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); } @@ -858,7 +574,7 @@ for(;;) case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); - fprintf(f, "] (not)"); + fprintf(f, "]"); break; case OP_NOTSTARI: @@ -884,7 +600,7 @@ for(;;) case OP_NOTPOSQUERY: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); - fprintf(f, "]%s (not)", OP_names[*code]); + fprintf(f, "]%s", OP_names[*code]); break; case OP_NOTEXACTI: @@ -906,7 +622,6 @@ for(;;) if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?"); else if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+"); - fprintf(f, " (not)"); break; case OP_RECURSE: @@ -917,17 +632,14 @@ for(;;) case OP_REFI: flag = "/i"; - extra = code[1 + IMM2_SIZE]; /* Fall through */ case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); - if (extra != 0) fprintf(f, " 0x%02x", extra); ccode = code + OP_lengths[*code]; goto CLASS_REF_REPEAT; case OP_DNREFI: flag = "/i"; - extra = code[1 + 2*IMM2_SIZE]; /* Fall through */ case OP_DNREF: { @@ -935,7 +647,6 @@ for(;;) fprintf(f, " %s \\k<", flag); print_custring(f, entry); fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE)); - if (extra != 0) fprintf(f, " 0x%02x", extra); } ccode = code + OP_lengths[*code]; goto CLASS_REF_REPEAT; @@ -965,77 +676,141 @@ for(;;) print_prop(f, code, " ", ""); break; -#ifdef SUPPORT_WIDE_CHARS - case OP_ECLASS: - extra = GET(code, 1); - fprintf(f, " eclass[\n"); - /* We print the opcodes contained inside as well. */ - ccode = code + 1 + LINK_SIZE + 1; - if ((ccode[-1] & ECL_MAP) != 0) - { - const uint8_t *map = (const uint8_t *)ccode; - /* The first 6 ASCII characters (SOH...ACK) are totally, utterly useless. - If they're set in the bitmap, then it's clearly been formed by negation.*/ - BOOL print_negated = (map[0] & 0x7e) == 0x7e; - - fprintf(f, " bitmap: [%s", print_negated? "^" : ""); - print_map(f, map, print_negated); - fprintf(f, "]\n"); - ccode += 32 / sizeof(PCRE2_UCHAR); - } - else - fprintf(f, " no bitmap\n"); - while (ccode < code + extra) + /* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm + in having this code always here, and it makes it less messy without all + those #ifdefs. */ + + case OP_CLASS: + case OP_NCLASS: + case OP_XCLASS: { - if (print_lengths) - fprintf(f, "%3d ", (int)(ccode - codestart)); - else - fprintf(f, " "); + BOOL printmap, invertmap; - switch (*ccode) + fprintf(f, " ["); + + /* Negative XCLASS has an inverted map whereas the original opcodes have + already done the inversion. */ + + invertmap = FALSE; + if (*code == OP_XCLASS) { - case ECL_AND: - fprintf(f, " AND\n"); - ccode += 1; - break; - case ECL_OR: - fprintf(f, " OR\n"); - ccode += 1; - break; - case ECL_XOR: - fprintf(f, " XOR\n"); - ccode += 1; - break; - case ECL_NOT: - fprintf(f, " NOT\n"); - ccode += 1; - break; + extra = GET(code, 1); + ccode = code + LINK_SIZE + 1; + printmap = (*ccode & XCL_MAP) != 0; + if ((*ccode & XCL_NOT) != 0) + { + invertmap = (*ccode & XCL_HASPROP) == 0; + fprintf(f, "^"); + } + ccode++; + } + else /* CLASS or NCLASS */ + { + printmap = TRUE; + ccode = code + 1; + } - case ECL_XCLASS: - print_class(f, OP_XCLASS, ccode+1, (uint8_t*)codestart, utf, - " xclass: ", "\n"); - ccode += GET(ccode, 1); - break; + /* Print a bit map */ - default: - fprintf(f, " UNEXPECTED\n"); - ccode += 1; - break; + if (printmap) + { + uint8_t inverted_map[32]; + uint8_t *map = (uint8_t *)ccode; + + if (invertmap) + { + /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ + for (i = 0; i < 32; i++) inverted_map[i] = 255 ^ map[i]; + map = inverted_map; + } + + for (i = 0; i < 256; i++) + { + if ((map[i/8] & (1u << (i&7))) != 0) + { + int j; + for (j = i+1; j < 256; j++) + if ((map[j/8] & (1u << (j&7))) == 0) break; + if (i == '-' || i == ']') fprintf(f, "\\"); + if (PRINTABLE(i)) fprintf(f, "%c", i); + else fprintf(f, "\\x%02x", i); + if (--j > i) + { + if (j != i + 1) fprintf(f, "-"); + if (j == '-' || j == ']') fprintf(f, "\\"); + if (PRINTABLE(j)) fprintf(f, "%c", j); + else fprintf(f, "\\x%02x", j); + } + i = j; + } + } + ccode += 32 / sizeof(PCRE2_UCHAR); } } - fprintf(f, " ]"); - goto CLASS_REF_REPEAT; -#endif /* SUPPORT_WIDE_CHARS */ - case OP_CLASS: - case OP_NCLASS: -#ifdef SUPPORT_WIDE_CHARS - case OP_XCLASS: + /* For an XCLASS there is always some additional data */ + if (*code == OP_XCLASS) - extra = GET(code, 1); -#endif - print_class(f, *code, code+1, (uint8_t*)codestart, utf, " ", ""); - ccode = code + OP_lengths[*code] + extra; + { + PCRE2_UCHAR ch; + while ((ch = *ccode++) != XCL_END) + { + const char *notch = ""; + + switch(ch) + { + case XCL_NOTPROP: + notch = "^"; + /* Fall through */ + + case XCL_PROP: + { + unsigned int ptype = *ccode++; + unsigned int pvalue = *ccode++; + const char *s; + + switch(ptype) + { + case PT_PXGRAPH: + fprintf(f, "[:%sgraph:]", notch); + break; + + case PT_PXPRINT: + fprintf(f, "[:%sprint:]", notch); + break; + + case PT_PXPUNCT: + fprintf(f, "[:%spunct:]", notch); + break; + + case PT_PXXDIGIT: + fprintf(f, "[:%sxdigit:]", notch); + break; + + default: + s = get_ucpname(ptype, pvalue); + fprintf(f, "\\%c{%c%s}", ((notch[0] == '^')? 'P':'p'), + toupper(s[0]), s+1); + break; + } + } + break; + + default: + ccode += 1 + print_char(f, ccode, utf); + if (ch == XCL_RANGE) + { + fprintf(f, "-"); + ccode += 1 + print_char(f, ccode, utf); + } + break; + } + } + } + + /* Indicate a non-UTF class which was created by negation */ + + fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); /* Handle repeats after a class or a back reference */ diff --git a/ext/pcre/pcre2lib/pcre2_serialize.c b/ext/pcre/pcre2lib/pcre2_serialize.c index a10e3020bbe9..ba17a26d2eeb 100644 --- a/ext/pcre/pcre2lib/pcre2_serialize.c +++ b/ext/pcre/pcre2lib/pcre2_serialize.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2020 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -127,25 +127,25 @@ dst_bytes += TABLES_LENGTH; for (i = 0; i < number_of_codes; i++) { re = (const pcre2_real_code *)(codes[i]); - (void)memcpy(dst_bytes, (const char *)re, re->blocksize); - - /* Certain fields in the compiled code block are re-set during - deserialization. In order to ensure that the serialized data stream is always - the same for the same pattern, set them to zero here. We can't assume the - copy of the pattern is correctly aligned for accessing the fields as part of + (void)memcpy(dst_bytes, (char *)re, re->blocksize); + + /* Certain fields in the compiled code block are re-set during + deserialization. In order to ensure that the serialized data stream is always + the same for the same pattern, set them to zero here. We can't assume the + copy of the pattern is correctly aligned for accessing the fields as part of a structure. Note the use of sizeof(void *) in the second of these, to - specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a - pointer to uint8_t), gcc gives a warning because the first argument is also a - pointer to uint8_t. Casting the first argument to (void *) can stop this, but + specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a + pointer to uint8_t), gcc gives a warning because the first argument is also a + pointer to uint8_t. Casting the first argument to (void *) can stop this, but it didn't stop Coverity giving the same complaint. */ - - (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0, + + (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0, sizeof(pcre2_memctl)); - (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0, + (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0, sizeof(void *)); (void)memset(dst_bytes + offsetof(pcre2_real_code, executable_jit), 0, - sizeof(void *)); - + sizeof(void *)); + dst_bytes += re->blocksize; } @@ -232,10 +232,10 @@ for (i = 0; i < number_of_codes; i++) if (dst_re->magic_number != MAGIC_NUMBER || dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 || dst_re->name_count > MAX_NAME_COUNT) - { - memctl->free(dst_re, memctl->memory_data); + { + memctl->free(dst_re, memctl->memory_data); return PCRE2_ERROR_BADSERIALIZEDDATA; - } + } /* At the moment only one table is supported. */ diff --git a/ext/pcre/pcre2lib/pcre2_study.c b/ext/pcre/pcre2lib/pcre2_study.c index 85764cea5653..792e696dad74 100644 --- a/ext/pcre/pcre2lib/pcre2_study.c +++ b/ext/pcre/pcre2lib/pcre2_study.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -114,7 +114,7 @@ uint32_t once_fudge = 0; BOOL had_recurse = FALSE; BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0; PCRE2_SPTR nextbranch = code + GET(code, 1); -PCRE2_SPTR cc = code + 1 + LINK_SIZE; +PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE; recurse_check this_recurse; /* If this is a "could be empty" group, its minimum length is 0. */ @@ -136,13 +136,12 @@ passes 16-bits, reset to that value and skip the rest of the branch. */ for (;;) { int d, min, recno; - PCRE2_UCHAR op; - PCRE2_SPTR cs, ce; + PCRE2_UCHAR op, *cs, *ce; if (branchlength >= UINT16_MAX) { branchlength = UINT16_MAX; - cc = nextbranch; + cc = (PCRE2_UCHAR *)nextbranch; } op = *cc; @@ -250,7 +249,6 @@ for (;;) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: - case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); /* Fall through */ @@ -419,14 +417,15 @@ for (;;) case OP_NCLASS: #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - case OP_ECLASS: /* The original code caused an unsigned overflow in 64 bit systems, so now we use a conditional statement. */ - if (op == OP_XCLASS || op == OP_ECLASS) + if (op == OP_XCLASS) cc += GET(cc, 1); else -#endif cc += PRIV(OP_lengths)[OP_CLASS]; +#else + cc += PRIV(OP_lengths)[OP_CLASS]; +#endif switch (*cc) { @@ -480,8 +479,8 @@ for (;;) if (!dupcapused && (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) { int count = GET2(cc, 1+IMM2_SIZE); - PCRE2_SPTR slot = - (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code)) + + PCRE2_UCHAR *slot = + (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + GET2(cc, 1) * re->name_entry_size; d = INT_MAX; @@ -497,12 +496,13 @@ for (;;) dd = backref_cache[recno]; else { - ce = cs = PRIV(find_bracket)(startcode, utf, recno); + ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); dd = 0; - if (!dupcapused || PRIV(find_bracket)(ce, utf, recno) == NULL) + if (!dupcapused || + (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL) { if (cc > cs && cc < ce) /* Simple recursion */ { @@ -539,7 +539,7 @@ for (;;) } } else d = 0; - cc += PRIV(OP_lengths)[*cc]; + cc += 1 + 2*IMM2_SIZE; goto REPEAT_BACK_REFERENCE; /* Single back reference by number. References by name are converted to by @@ -557,11 +557,12 @@ for (;;) if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) { - ce = cs = PRIV(find_bracket)(startcode, utf, recno); + ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); - if (!dupcapused || PRIV(find_bracket)(ce, utf, recno) == NULL) + if (!dupcapused || + (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL) { if (cc > cs && cc < ce) /* Simple recursion */ { @@ -592,7 +593,7 @@ for (;;) backref_cache[0] = recno; } - cc += PRIV(OP_lengths)[*cc]; + cc += 1 + IMM2_SIZE; /* Handle repeated back references */ @@ -642,7 +643,7 @@ for (;;) pattern contains multiple subpatterns with the same number. */ case OP_RECURSE: - cs = ce = startcode + GET(cc, 1); + cs = ce = (PCRE2_UCHAR *)startcode + GET(cc, 1); recno = GET2(cs, 1+LINK_SIZE); if (recno == prev_recurse_recno) { @@ -754,13 +755,10 @@ for (;;) new ones get added they are properly considered. */ default: - PCRE2_DEBUG_UNREACHABLE(); return -3; } } - -PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */ -return -3; /* Avoid compiler warnings */ +/* Control never gets here */ } @@ -921,138 +919,6 @@ if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 -/************************************************* -* Set starting bits for a character list. * -*************************************************/ - -/* This function sets starting bits for a character list. It enumerates -all characters and character ranges in the character list, and sets -the starting bits accordingly. - -Arguments: - code pointer to the code - start_bitmap pointer to the starting bitmap - -Returns: nothing -*/ -static void -study_char_list(PCRE2_SPTR code, uint8_t *start_bitmap, - const uint8_t *char_lists_end) -{ -uint32_t type, list_ind; -uint32_t char_list_add = XCL_CHAR_LIST_LOW_16_ADD; -uint32_t range_start = ~(uint32_t)0, range_end = 0; -const uint8_t *next_char; -PCRE2_UCHAR start_buffer[6], end_buffer[6]; -PCRE2_UCHAR start, end; - -/* Only needed in 8-bit mode at the moment. */ -type = (uint32_t)(code[0] << 8) | code[1]; -code += 2; - -/* Align characters. */ -next_char = char_lists_end - (GET(code, 0) << 1); -type &= XCL_TYPE_MASK; -list_ind = 0; - -if ((type & XCL_BEGIN_WITH_RANGE) != 0) - range_start = XCL_CHAR_LIST_LOW_16_START; - -while (type > 0) - { - uint32_t item_count = type & XCL_ITEM_COUNT_MASK; - - if (item_count == XCL_ITEM_COUNT_MASK) - { - if (list_ind <= 1) - { - item_count = *(const uint16_t*)next_char; - next_char += 2; - } - else - { - item_count = *(const uint32_t*)next_char; - next_char += 4; - } - } - - while (item_count > 0) - { - if (list_ind <= 1) - { - range_end = *(const uint16_t*)next_char; - next_char += 2; - } - else - { - range_end = *(const uint32_t*)next_char; - next_char += 4; - } - - if ((range_end & XCL_CHAR_END) != 0) - { - range_end = char_list_add + (range_end >> XCL_CHAR_SHIFT); - - PRIV(ord2utf)(range_end, end_buffer); - end = end_buffer[0]; - - if (range_start < range_end) - { - PRIV(ord2utf)(range_start, start_buffer); - for (start = start_buffer[0]; start <= end; start++) - start_bitmap[start / 8] |= (1u << (start & 7)); - } - else - start_bitmap[end / 8] |= (1u << (end & 7)); - - range_start = ~(uint32_t)0; - } - else - range_start = char_list_add + (range_end >> XCL_CHAR_SHIFT); - - item_count--; - } - - list_ind++; - type >>= XCL_TYPE_BIT_LEN; - - if (range_start == ~(uint32_t)0) - { - if ((type & XCL_BEGIN_WITH_RANGE) != 0) - { - /* In 8 bit mode XCL_CHAR_LIST_HIGH_32_START is not possible. */ - if (list_ind == 1) range_start = XCL_CHAR_LIST_HIGH_16_START; - else range_start = XCL_CHAR_LIST_LOW_32_START; - } - } - else if ((type & XCL_BEGIN_WITH_RANGE) == 0) - { - PRIV(ord2utf)(range_start, start_buffer); - - /* In 8 bit mode XCL_CHAR_LIST_LOW_32_END and - XCL_CHAR_LIST_HIGH_32_END are not possible. */ - if (list_ind == 1) range_end = XCL_CHAR_LIST_LOW_16_END; - else range_end = XCL_CHAR_LIST_HIGH_16_END; - - PRIV(ord2utf)(range_end, end_buffer); - end = end_buffer[0]; - - for (start = start_buffer[0]; start <= end; start++) - start_bitmap[start / 8] |= (1u << (start & 7)); - - range_start = ~(uint32_t)0; - } - - /* In 8 bit mode XCL_CHAR_LIST_HIGH_32_ADD is not possible. */ - if (list_ind == 1) char_list_add = XCL_CHAR_LIST_HIGH_16_ADD; - else char_list_add = XCL_CHAR_LIST_LOW_32_ADD; - } -} -#endif - - - /************************************************* * Create bitmap of starting code units * *************************************************/ @@ -1114,7 +980,7 @@ do { int rc; PCRE2_SPTR ncode; - const uint8_t *classmap = NULL; + uint8_t *classmap = NULL; #ifdef SUPPORT_WIDE_CHARS PCRE2_UCHAR xclassflags; #endif @@ -1268,7 +1134,6 @@ do case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: ncode += GET(ncode, 1); while (*ncode == OP_ALT) ncode += GET(ncode, 1); ncode += 1 + LINK_SIZE; @@ -1387,14 +1252,12 @@ do tcode += GET(tcode, 1 + 2*LINK_SIZE); break; - /* Skip over lookbehind, negative lookahead, and scan substring - assertions */ + /* Skip over lookbehind and negative lookahead assertions */ case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERTBACK_NA: - case OP_ASSERT_SCS: do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; @@ -1715,13 +1578,6 @@ do tcode += 2; break; - /* Set-based ECLASS: treat it the same as a "complex" XCLASS; give up. */ - -#ifdef SUPPORT_WIDE_CHARS - case OP_ECLASS: - return SSB_FAIL; -#endif - /* Extended class: if there are any property checks, or if this is a negative XCLASS without a map, give up. If there are no property checks, there must be wide characters on the XCLASS list, because otherwise an @@ -1740,7 +1596,7 @@ do map pointer if there is one, and fall through. */ classmap = ((xclassflags & XCL_MAP) == 0)? NULL : - (const uint8_t *)(tcode + 1 + LINK_SIZE + 1); + (uint8_t *)(tcode + 1 + LINK_SIZE + 1); /* In UTF-8 mode, scan the character list and set bits for leading bytes, then jump to handle the map. */ @@ -1752,13 +1608,6 @@ do PCRE2_SPTR p = tcode + 1 + LINK_SIZE + 1 + ((classmap == NULL)? 0:32); tcode += GET(tcode, 1); - if (*p >= XCL_LIST) - { - study_char_list(p, re->start_bitmap, - ((const uint8_t *)re + re->code_start)); - goto HANDLE_CLASSMAP; - } - for (;;) switch (*p++) { case XCL_SINGLE: @@ -1780,7 +1629,6 @@ do goto HANDLE_CLASSMAP; default: - PCRE2_DEBUG_UNREACHABLE(); return SSB_UNKNOWN; /* Internal error, should not occur */ } } @@ -1817,7 +1665,7 @@ do case OP_CLASS: if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else { - classmap = (const uint8_t *)(++tcode); + classmap = (uint8_t *)(++tcode); tcode += 32 / sizeof(PCRE2_UCHAR); } @@ -1920,7 +1768,8 @@ BOOL ucp = (re->overall_options & PCRE2_UCP) != 0; /* Find start of compiled code */ -code = (PCRE2_UCHAR *)((uint8_t *)re + re->code_start); +code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + + re->name_entry_size * re->name_count; /* For a pattern that has a first code unit, or a multiline pattern that matches only at "line start", there is no point in seeking a list of starting @@ -1930,11 +1779,7 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) { int depth = 0; int rc = set_start_bits(re, code, utf, ucp, &depth); - if (rc == SSB_UNKNOWN) - { - PCRE2_DEBUG_UNREACHABLE(); - return 1; - } + if (rc == SSB_UNKNOWN) return 1; /* If a list of starting code units was set up, scan the list to see if only one or two were listed. Having only one listed is rare because usually a @@ -2007,22 +1852,25 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) } } - /* Replace the start code unit bits with a first code unit. If it is the - same as a required later code unit, then clear the required later code - unit. This is because a search for a required code unit starts after an - explicit first code unit, but at a code unit found from the bitmap. - Patterns such as /a*a/ don't work if both the start unit and required - unit are the same. */ - - if (a >= 0) { - if ((re->flags & PCRE2_LASTSET) && (re->last_codeunit == (uint32_t)a || (b >= 0 && re->last_codeunit == (uint32_t)b))) { - re->flags &= ~(PCRE2_LASTSET | PCRE2_LASTCASELESS); - re->last_codeunit = 0; - } + /* Replace the start code unit bits with a first code unit, but only if it + is not the same as a required later code unit. This is because a search for + a required code unit starts after an explicit first code unit, but at a + code unit found from the bitmap. Patterns such as /a*a/ don't work + if both the start unit and required unit are the same. */ + + if (a >= 0 && + ( + (re->flags & PCRE2_LASTSET) == 0 || + ( + re->last_codeunit != (uint32_t)a && + (b < 0 || re->last_codeunit != (uint32_t)b) + ) + )) + { re->first_codeunit = a; flags = PCRE2_FIRSTSET; if (b >= 0) flags |= PCRE2_FIRSTCASELESS; - } + } DONE: re->flags |= flags; @@ -2050,11 +1898,9 @@ if ((re->flags & (PCRE2_MATCH_EMPTY|PCRE2_HASACCEPT)) == 0 && break; /* Leave minlength unchanged (will be zero) */ case -2: - PCRE2_DEBUG_UNREACHABLE(); return 2; /* missing capturing bracket */ case -3: - PCRE2_DEBUG_UNREACHABLE(); return 3; /* unrecognized opcode */ default: diff --git a/ext/pcre/pcre2lib/pcre2_substitute.c b/ext/pcre/pcre2lib/pcre2_substitute.c index 17040ce5fd4c..edbb78c6d786 100644 --- a/ext/pcre/pcre2lib/pcre2_substitute.c +++ b/ext/pcre/pcre2lib/pcre2_substitute.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2022 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -130,21 +130,17 @@ for (; ptr < ptrend; ptr++) ptr += 1; /* Must point after \ */ erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode, - code->overall_options, code->extra_options, code->top_bracket, FALSE, NULL); + code->overall_options, code->extra_options, FALSE, NULL); ptr -= 1; /* Back to last code unit of escape */ if (errorcode != 0) { - /* errorcode from check_escape is positive, so must not be returned by - pcre2_substitute(). */ - rc = PCRE2_ERROR_BADREPESCAPE; + rc = errorcode; goto EXIT; } switch(erc) { case 0: /* Data character */ - case ESC_b: /* Data character */ - case ESC_v: /* Data character */ case ESC_E: /* Isolated \E is ignored */ break; @@ -152,18 +148,7 @@ for (; ptr < ptrend; ptr++) literal = TRUE; break; - case ESC_g: - /* The \g form (\g already handled by check_escape) - - Don't worry about finding the matching ">". We are super, super lenient - about validating ${} replacements inside find_text_end(), so we certainly - don't need to worry about other syntax. Importantly, a \g<..> or $<...> - sequence can't contain a '}' character. */ - break; - default: - if (erc < 0) - break; /* capture group reference */ rc = PCRE2_ERROR_BADREPESCAPE; goto EXIT; } @@ -178,426 +163,6 @@ return rc; } -/************************************************* -* Validate group name * -*************************************************/ - -/* This function scans for a capture group name, validating it -consists of legal characters, is not empty, and does not exceed -MAX_NAME_SIZE. - -Arguments: - ptrptr points to the pointer to the start of the text (updated) - ptrend end of the whole string - utf true if the input is UTF-encoded - ctypes pointer to the character types table - -Returns: TRUE if a name was read - FALSE otherwise -*/ - -static BOOL -read_name_subst(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf, - const uint8_t* ctypes) -{ -PCRE2_SPTR ptr = *ptrptr; -PCRE2_SPTR nameptr = ptr; - -if (ptr >= ptrend) /* No characters in name */ - goto FAILED; - -/* We do not need to check whether the name starts with a non-digit. -We are simply referencing names here, not defining them. */ - -/* See read_name in the pcre2_compile.c for the corresponding logic -restricting group names inside the pattern itself. */ - -#ifdef SUPPORT_UNICODE -if (utf) - { - uint32_t c, type; - - while (ptr < ptrend) - { - GETCHAR(c, ptr); - type = UCD_CHARTYPE(c); - if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L && - c != CHAR_UNDERSCORE) break; - ptr++; - FORWARDCHARTEST(ptr, ptrend); - } - } -else -#else -(void)utf; /* Avoid compiler warning */ -#endif /* SUPPORT_UNICODE */ - -/* Handle group names in non-UTF modes. */ - - { - while (ptr < ptrend && MAX_255(*ptr) && (ctypes[*ptr] & ctype_word) != 0) - { - ptr++; - } - } - -/* Check name length */ - -if (ptr - nameptr > MAX_NAME_SIZE) - goto FAILED; - -/* Subpattern names must not be empty */ -if (ptr == nameptr) - goto FAILED; - -*ptrptr = ptr; -return TRUE; - -FAILED: -*ptrptr = ptr; -return FALSE; -} - - -/************************************************* -* Case transformations * -*************************************************/ - -#define PCRE2_SUBSTITUTE_CASE_NONE 0 -// 1, 2, 3 are PCRE2_SUBSTITUTE_CASE_LOWER, UPPER, TITLE_FIRST. -#define PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST 4 - -typedef struct { - int to_case; /* One of PCRE2_SUBSTITUTE_CASE_xyz */ - BOOL single_char; -} case_state; - -/* Helper to guess how much a string is likely to increase in size when -case-transformed. Usually, strings don't change size at all, but some rare -characters do grow. Estimate +10%, plus another few characters. - -Performing this estimation is unfortunate, but inevitable, since we can't call -the callout if we ran out of buffer space to prepare its input. - -Because this estimate is inexact (and in pathological cases, underestimates the -required buffer size) we must document that when you have a -substitute_case_callout, and you are using PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, you -may need more than two calls to determine the final buffer size. */ - -static PCRE2_SIZE -pessimistic_case_inflation(PCRE2_SIZE len) -{ -return (len >> 3u) + 10; -} - -/* Case transformation behaviour if no callout is passed. */ - -static PCRE2_SIZE -default_substitute_case_callout( - PCRE2_SPTR input, PCRE2_SIZE input_len, - PCRE2_UCHAR *output, PCRE2_SIZE output_cap, - case_state *state, const pcre2_code *code) -{ -PCRE2_SPTR input_end = input + input_len; -#ifdef SUPPORT_UNICODE -BOOL utf; -BOOL ucp; -#endif -PCRE2_UCHAR temp[6]; -BOOL next_to_upper; -BOOL rest_to_upper; -BOOL single_char; -BOOL overflow = FALSE; -PCRE2_SIZE written = 0; - -/* Helpful simplifying invariant: input and output are disjoint buffers. -I believe that this code is technically undefined behaviour, because the two -pointers input/output are "unrelated" pointers and hence not comparable. Casting -via char* bypasses some but not all of those technical rules. It is not included -in release builds, in any case. */ -PCRE2_ASSERT((char *)(input + input_len) <= (char *)output || - (char *)(output + output_cap) <= (char *)input); - -#ifdef SUPPORT_UNICODE -utf = (code->overall_options & PCRE2_UTF) != 0; -ucp = (code->overall_options & PCRE2_UCP) != 0; -#endif - -if (input_len == 0) return 0; - -switch (state->to_case) - { - default: - PCRE2_DEBUG_UNREACHABLE(); - return 0; - - case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE - case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE - next_to_upper = rest_to_upper = (state->to_case == PCRE2_SUBSTITUTE_CASE_UPPER); - break; - - case PCRE2_SUBSTITUTE_CASE_TITLE_FIRST: // Can be single_char TRUE or FALSE - next_to_upper = TRUE; - rest_to_upper = FALSE; - state->to_case = PCRE2_SUBSTITUTE_CASE_LOWER; - break; - - case PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST: // Can only be single_char FALSE - next_to_upper = FALSE; - rest_to_upper = TRUE; - state->to_case = PCRE2_SUBSTITUTE_CASE_UPPER; - break; - } - -single_char = state->single_char; -if (single_char) - state->to_case = PCRE2_SUBSTITUTE_CASE_NONE; - -while (input < input_end) - { - uint32_t ch; - unsigned int chlen; - - GETCHARINCTEST(ch, input); - -#ifdef SUPPORT_UNICODE - if ((utf || ucp) && ch >= 128) - { - uint32_t type = UCD_CHARTYPE(ch); - if (PRIV(ucp_gentype)[type] == ucp_L && - type != (next_to_upper? ucp_Lu : ucp_Ll)) - ch = UCD_OTHERCASE(ch); - - /* TODO This is far from correct... it doesn't support the SpecialCasing.txt - mappings, but worse, it's not even correct for all the ordinary case - mappings. We should add support for those (at least), and then add the - SpecialCasing.txt mappings for Esszet and ligatures, and finally use the - Turkish casing flag on the match context. */ - } - else -#endif - if (MAX_255(ch)) - { - if (((code->tables + cbits_offset + - (next_to_upper? cbit_upper:cbit_lower) - )[ch/8] & (1u << (ch%8))) == 0) - ch = (code->tables + fcc_offset)[ch]; - } - -#ifdef SUPPORT_UNICODE - if (utf) chlen = PRIV(ord2utf)(ch, temp); else -#endif - { - temp[0] = ch; - chlen = 1; - } - - if (!overflow && chlen <= output_cap) - { - memcpy(output, temp, CU2BYTES(chlen)); - output += chlen; - output_cap -= chlen; - } - else - { - overflow = TRUE; - } - - if (chlen > ~(PCRE2_SIZE)0 - written) /* Integer overflow */ - return ~(PCRE2_SIZE)0; - written += chlen; - - next_to_upper = rest_to_upper; - - /* memcpy the remainder, if only transforming a single character. */ - - if (single_char) - { - PCRE2_SIZE rest_len = input_end - input; - - if (!overflow && rest_len <= output_cap) - memcpy(output, input, CU2BYTES(rest_len)); - - if (rest_len > ~(PCRE2_SIZE)0 - written) /* Integer overflow */ - return ~(PCRE2_SIZE)0; - written += rest_len; - - return written; - } - } - -return written; -} - -/* Helper to perform the call to the substitute_case_callout. We wrap the -user-provided callout because our internal arguments are slightly extended. We -don't want the user callout to handle the case of "\l" (first character only to -lowercase) or "\l\U" (first character to lowercase, rest to uppercase) because -those are not operations defined by Unicode. Instead the user callout simply -needs to provide the three Unicode primitives: lower, upper, titlecase. */ - -static PCRE2_SIZE -do_case_copy( - PCRE2_UCHAR *input_output, PCRE2_SIZE input_len, PCRE2_SIZE output_cap, - case_state *state, BOOL utf, - PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, - PCRE2_SIZE, int, void *), - void *substitute_case_callout_data) -{ -PCRE2_SPTR input = input_output; -PCRE2_UCHAR *output = input_output; -PCRE2_SIZE rc; -PCRE2_SIZE rc2; -int ch1_to_case; -int rest_to_case; -PCRE2_UCHAR ch1[6]; -PCRE2_SIZE ch1_len; -PCRE2_SPTR rest; -PCRE2_SIZE rest_len; -BOOL ch1_overflow = FALSE; -BOOL rest_overflow = FALSE; - -#if PCRE2_CODE_UNIT_WIDTH == 32 || !defined(SUPPORT_UNICODE) -(void)utf; /* Avoid compiler warning. */ -#endif - -PCRE2_ASSERT(input_len != 0); - -switch (state->to_case) - { - default: - PCRE2_DEBUG_UNREACHABLE(); - return 0; - - case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE - case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE - case PCRE2_SUBSTITUTE_CASE_TITLE_FIRST: // Can be single_char TRUE or FALSE - - /* The easy case, where our internal casing operations align with those of - the callout. */ - - if (state->single_char == FALSE) - { - rc = substitute_case_callout(input, input_len, output, output_cap, - state->to_case, substitute_case_callout_data); - - if (state->to_case == PCRE2_SUBSTITUTE_CASE_TITLE_FIRST) - state->to_case = PCRE2_SUBSTITUTE_CASE_LOWER; - - return rc; - } - - ch1_to_case = state->to_case; - rest_to_case = PCRE2_SUBSTITUTE_CASE_NONE; - break; - - case PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST: // Can only be single_char FALSE - ch1_to_case = PCRE2_SUBSTITUTE_CASE_LOWER; - rest_to_case = PCRE2_SUBSTITUTE_CASE_UPPER; - break; - } - -/* Identify the leading character. Take copy, because its storage overlaps with -`output`, and hence may be scrambled by the callout. */ - - { - PCRE2_SPTR ch_end = input; - uint32_t ch; - - GETCHARINCTEST(ch, ch_end); - (void) ch; - PCRE2_ASSERT(ch_end <= input + input_len && ch_end - input <= 6); - ch1_len = ch_end - input; - memcpy(ch1, input, CU2BYTES(ch1_len)); - } - -rest = input + ch1_len; -rest_len = input_len - ch1_len; - -/* Transform just ch1. The buffers are always in-place (input == output). With a -custom callout, we need a loop to discover its required buffer size. The loop -wouldn't be required if the callout were well-behaved, but it might be naughty -and return "5" the first time, then "10" the next time we call it using the -exact same input! */ - - { - PCRE2_SIZE ch1_cap; - PCRE2_SIZE max_ch1_cap; - - ch1_cap = ch1_len; /* First attempt uses the space vacated by ch1. */ - PCRE2_ASSERT(output_cap >= input_len && input_len >= rest_len); - max_ch1_cap = output_cap - rest_len; - - while (TRUE) - { - rc = substitute_case_callout(ch1, ch1_len, output, ch1_cap, ch1_to_case, - substitute_case_callout_data); - if (rc == ~(PCRE2_SIZE)0) return rc; - - if (rc <= ch1_cap) break; - - if (rc > max_ch1_cap) - { - ch1_overflow = TRUE; - break; - } - - /* Move the rest to the right, to make room for expanding ch1. */ - - memmove(input_output + rc, rest, CU2BYTES(rest_len)); - rest = input + rc; - - ch1_cap = rc; - - /* Proof of loop termination: `ch1_cap` is growing on each iteration, but - the loop ends if `rc` reaches the (unchanging) upper bound of output_cap. */ - } - } - -if (rest_to_case == PCRE2_SUBSTITUTE_CASE_NONE) - { - if (!ch1_overflow) - { - PCRE2_ASSERT(rest_len <= output_cap - rc); - memmove(output + rc, rest, CU2BYTES(rest_len)); - } - rc2 = rest_len; - - state->to_case = PCRE2_SUBSTITUTE_CASE_NONE; - } -else - { - PCRE2_UCHAR dummy[1]; - - rc2 = substitute_case_callout(rest, rest_len, - ch1_overflow? dummy : output + rc, - ch1_overflow? 0u : output_cap - rc, - rest_to_case, substitute_case_callout_data); - if (rc2 == ~(PCRE2_SIZE)0) return rc2; - - if (!ch1_overflow && rc2 > output_cap - rc) rest_overflow = TRUE; - - /* If ch1 grows so that `xform(ch1)+rest` can't fit in the buffer, but then - `rest` shrinks, it's actually possible for the total calculated length of - `xform(ch1)+xform(rest)` to come out at less than output_cap. But we can't - report that, because it would make it seem that the operation succeeded. - If either of xform(ch1) or xform(rest) won't fit in the buffer, our final - result must be > output_cap. */ - if (ch1_overflow && rc2 < rest_len) - rc2 = rest_len; - - state->to_case = PCRE2_SUBSTITUTE_CASE_UPPER; - } - -if (rc2 > ~(PCRE2_SIZE)0 - rc) /* Integer overflow */ - return ~(PCRE2_SIZE)0; - -PCRE2_ASSERT(!(ch1_overflow || rest_overflow) || rc + rc2 > output_cap); -(void)rest_overflow; - -return rc + rc2; -} - /************************************************* * Match and substitute * @@ -629,107 +194,25 @@ Returns: >= 0 number of substitutions made overflow, either give an error immediately, or keep on, accumulating the length. */ -#define CHECKMEMCPY(from, length_) \ - do { \ - PCRE2_SIZE chkmc_length = length_; \ - if (overflowed) \ - { \ - if (chkmc_length > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ \ - goto TOOLARGEREPLACE; \ - extra_needed += chkmc_length; \ - } \ - else if (lengthleft < chkmc_length) \ - { \ - if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ - overflowed = TRUE; \ - extra_needed = chkmc_length - lengthleft; \ - } \ - else \ - { \ - memcpy(buffer + buff_offset, from, CU2BYTES(chkmc_length)); \ - buff_offset += chkmc_length; \ - lengthleft -= chkmc_length; \ - } \ - } \ - while (0) - -/* This macro checks for space and copies characters with casing modifications. -On overflow, it behaves as for CHECKMEMCPY(). - -When substitute_case_callout is NULL, the source and destination buffers must -not overlap, because our default handler does not support this. */ - -#define CHECKCASECPY_BASE(length_, do_call) \ - do { \ - PCRE2_SIZE chkcc_length = (PCRE2_SIZE)(length_); \ - PCRE2_SIZE chkcc_rc; \ - do_call \ - if (lengthleft < chkcc_rc) \ - { \ - if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ - overflowed = TRUE; \ - extra_needed = chkcc_rc - lengthleft; \ - } \ - else \ - { \ - buff_offset += chkcc_rc; \ - lengthleft -= chkcc_rc; \ - } \ - } \ - while (0) - -#define CHECKCASECPY_DEFAULT(from, length_) \ - CHECKCASECPY_BASE(length_, { \ - chkcc_rc = default_substitute_case_callout(from, chkcc_length, \ - buffer + buff_offset, \ - overflowed? 0 : lengthleft, \ - &forcecase, code); \ - if (overflowed) \ - { \ - if (chkcc_rc > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ \ - goto TOOLARGEREPLACE; \ - extra_needed += chkcc_rc; \ - break; \ - } \ - }) - -#define CHECKCASECPY_CALLOUT(length_) \ - CHECKCASECPY_BASE(length_, { \ - chkcc_rc = do_case_copy(buffer + buff_offset, chkcc_length, \ - lengthleft, &forcecase, utf, \ - substitute_case_callout, \ - substitute_case_callout_data); \ - if (chkcc_rc == ~(PCRE2_SIZE)0) goto CASEERROR; \ - }) - -/* This macro does a delayed case transformation, for the situation when we have -a case-forcing callout. */ - -#define DELAYEDFORCECASE() \ - do { \ - PCRE2_SIZE chars_outstanding = (buff_offset - casestart_offset) + \ - (extra_needed - casestart_extra_needed); \ - if (chars_outstanding > 0) \ - { \ - if (overflowed) \ - { \ - PCRE2_SIZE guess = pessimistic_case_inflation(chars_outstanding); \ - if (guess > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ \ - goto TOOLARGEREPLACE; \ - extra_needed += guess; \ - } \ - else \ - { \ - /* Rewind the buffer */ \ - lengthleft += (buff_offset - casestart_offset); \ - buff_offset = casestart_offset; \ - /* Care! In-place case transformation */ \ - CHECKCASECPY_CALLOUT(chars_outstanding); \ - } \ - } \ - } \ - while (0) - +#define CHECKMEMCPY(from,length) \ + { \ + if (!overflowed && lengthleft < length) \ + { \ + if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \ + overflowed = TRUE; \ + extra_needed = length - lengthleft; \ + } \ + else if (overflowed) \ + { \ + extra_needed += length; \ + } \ + else \ + { \ + memcpy(buffer + buff_offset, from, CU2BYTES(length)); \ + buff_offset += length; \ + lengthleft -= length; \ + } \ + } /* Here's the function */ @@ -741,6 +224,8 @@ pcre2_substitute(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, { int rc; int subs; +int forcecase = 0; +int forcecasereset = 0; uint32_t ovector_count; uint32_t goptions = 0; uint32_t suboptions; @@ -749,19 +234,18 @@ BOOL escaped_literal = FALSE; BOOL overflowed = FALSE; BOOL use_existing_match; BOOL replacement_only; +#ifdef SUPPORT_UNICODE BOOL utf = (code->overall_options & PCRE2_UTF) != 0; +BOOL ucp = (code->overall_options & PCRE2_UCP) != 0; +#endif PCRE2_UCHAR temp[6]; PCRE2_SPTR ptr; -PCRE2_SPTR repend = NULL; +PCRE2_SPTR repend; PCRE2_SIZE extra_needed = 0; PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength; PCRE2_SIZE *ovector; PCRE2_SIZE ovecsave[3]; pcre2_substitute_callout_block scb; -PCRE2_SIZE sub_start_extra_needed; -PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *, - PCRE2_SIZE, int, void *) = NULL; -void *substitute_case_callout_data = NULL; /* General initialization */ @@ -770,12 +254,6 @@ lengthleft = buff_length = *blength; *blength = PCRE2_UNSET; ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET; -if (mcontext != NULL) - { - substitute_case_callout = mcontext->substitute_case_callout; - substitute_case_callout_data = mcontext->substitute_case_callout_data; - } - /* Partial matching is not valid. This must come after setting *blength to PCRE2_UNSET, so as not to imply an offset in the replacement. */ @@ -808,34 +286,27 @@ case, we copy the existing match into the internal block, except for any cached heap frame size and pointer. This ensures that no changes are made to the external match data block. */ -/* WARNING: In both cases below a general context is constructed "by hand" -because calling pcre2_general_context_create() involves a memory allocation. If -the contents of a general context control block are ever changed there will -have to be changes below. */ - if (match_data == NULL) { - pcre2_general_context gcontext; + pcre2_general_context *gcontext; if (use_existing_match) return PCRE2_ERROR_NULL; - gcontext.memctl = (mcontext == NULL)? - ((const pcre2_real_code *)code)->memctl : - ((pcre2_real_match_context *)mcontext)->memctl; + gcontext = (mcontext == NULL)? + (pcre2_general_context *)code : + (pcre2_general_context *)mcontext; match_data = internal_match_data = - pcre2_match_data_create_from_pattern(code, &gcontext); + pcre2_match_data_create_from_pattern(code, gcontext); if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; } else if (use_existing_match) { - int pairs; - pcre2_general_context gcontext; - gcontext.memctl = (mcontext == NULL)? - ((const pcre2_real_code *)code)->memctl : - ((pcre2_real_match_context *)mcontext)->memctl; - pairs = (code->top_bracket + 1 < match_data->oveccount)? + pcre2_general_context *gcontext = (mcontext == NULL)? + (pcre2_general_context *)code : + (pcre2_general_context *)mcontext; + int pairs = (code->top_bracket + 1 < match_data->oveccount)? code->top_bracket + 1 : match_data->oveccount; internal_match_data = pcre2_match_data_create(match_data->oveccount, - &gcontext); + gcontext); if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY; memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector) + 2*pairs*sizeof(PCRE2_SIZE)); @@ -909,9 +380,6 @@ do { PCRE2_SPTR ptrstack[PTR_STACK_SIZE]; uint32_t ptrstackptr = 0; - case_state forcecase = { PCRE2_SUBSTITUTE_CASE_NONE, FALSE }; - PCRE2_SIZE casestart_offset = 0; - PCRE2_SIZE casestart_extra_needed = 0; if (use_existing_match) { @@ -944,9 +412,8 @@ do save_start = start_offset++; if (subject[start_offset-1] == CHAR_CR && - (code->newline_convention == PCRE2_NEWLINE_CRLF || - code->newline_convention == PCRE2_NEWLINE_ANY || - code->newline_convention == PCRE2_NEWLINE_ANYCRLF) && + code->newline_convention != PCRE2_NEWLINE_CR && + code->newline_convention != PCRE2_NEWLINE_LF && start_offset < length && subject[start_offset] == CHAR_LF) start_offset++; @@ -1013,16 +480,14 @@ do } subs++; - /* Copy the text leading up to the match (unless not required); remember - where the insert begins and how many ovector pairs are set; and remember how - much space we have requested in extra_needed. */ + /* Copy the text leading up to the match (unless not required), and remember + where the insert begins and how many ovector pairs are set. */ if (rc == 0) rc = ovector_count; fraglength = ovector[0] - start_offset; if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength); scb.output_offsets[0] = buff_offset; scb.oveccount = rc; - sub_start_extra_needed = extra_needed; /* Process the replacement string. If the entire replacement is literal, just copy it with length check. */ @@ -1042,13 +507,6 @@ do { uint32_t ch; unsigned int chlen; - int group; - uint32_t special; - PCRE2_SPTR text1_start = NULL; - PCRE2_SPTR text1_end = NULL; - PCRE2_SPTR text2_start = NULL; - PCRE2_SPTR text2_end = NULL; - PCRE2_UCHAR name[MAX_NAME_SIZE + 1]; /* If at the end of a nested substring, pop the stack. */ @@ -1077,62 +535,25 @@ do if (*ptr == CHAR_DOLLAR_SIGN) { + int group, n; + uint32_t special = 0; BOOL inparens; - BOOL inangle; BOOL star; PCRE2_SIZE sublength; + PCRE2_SPTR text1_start = NULL; + PCRE2_SPTR text1_end = NULL; + PCRE2_SPTR text2_start = NULL; + PCRE2_SPTR text2_end = NULL; PCRE2_UCHAR next; - PCRE2_SPTR subptr, subptrend; + PCRE2_UCHAR name[33]; if (++ptr >= repend) goto BAD; if ((next = *ptr) == CHAR_DOLLAR_SIGN) goto LOADLITERAL; - special = 0; - text1_start = NULL; - text1_end = NULL; - text2_start = NULL; - text2_end = NULL; group = -1; + n = 0; inparens = FALSE; - inangle = FALSE; star = FALSE; - subptr = NULL; - subptrend = NULL; - - /* Special $ sequences, as supported by Perl, JavaScript, .NET and others. */ - if (next == CHAR_AMPERSAND) - { - ++ptr; - group = 0; - goto GROUP_SUBSTITUTE; - } - if (next == CHAR_GRAVE_ACCENT || next == CHAR_APOSTROPHE) - { - ++ptr; - rc = pcre2_substring_length_bynumber(match_data, 0, &sublength); - if (rc < 0) goto PTREXIT; /* (Sanity-check ovector before reading from it.) */ - - if (next == CHAR_GRAVE_ACCENT) - { - subptr = subject; - subptrend = subject + ovector[0]; - } - else - { - subptr = subject + ovector[1]; - subptrend = subject + length; - } - - goto SUBPTR_SUBSTITUTE; - } - if (next == CHAR_UNDERSCORE) - { - /* Java, .NET support $_ for "entire input string". */ - ++ptr; - subptr = subject; - subptrend = subject + length; - goto SUBPTR_SUBSTITUTE; - } if (next == CHAR_LEFT_CURLY_BRACKET) { @@ -1140,31 +561,22 @@ do next = *ptr; inparens = TRUE; } - else if (next == CHAR_LESS_THAN_SIGN) - { - /* JavaScript compatibility syntax, $. Processes only named - groups (not numbered) and does not support extensions such as star - (you can do ${name} and ${*name}, but not $<*name>). */ - if (++ptr >= repend) goto BAD; - next = *ptr; - inangle = TRUE; - } - if (!inangle && next == CHAR_ASTERISK) + if (next == CHAR_ASTERISK) { if (++ptr >= repend) goto BAD; next = *ptr; star = TRUE; } - if (!star && !inangle && next >= CHAR_0 && next <= CHAR_9) + if (!star && next >= CHAR_0 && next <= CHAR_9) { group = next - CHAR_0; while (++ptr < repend) { next = *ptr; if (next < CHAR_0 || next > CHAR_9) break; - group = group * 10 + (next - CHAR_0); + group = group * 10 + next - CHAR_0; /* A check for a number greater than the hightest captured group is sufficient here; no need for a separate overflow check. If unknown @@ -1188,25 +600,25 @@ do } else { - PCRE2_SIZE name_len; - PCRE2_SPTR name_start = ptr; - if (!read_name_subst(&ptr, repend, utf, code->tables + ctypes_offset)) - goto BAD; - name_len = ptr - name_start; - memcpy(name, name_start, CU2BYTES(name_len)); - name[name_len] = 0; + const uint8_t *ctypes = code->tables + ctypes_offset; + while (MAX_255(next) && (ctypes[next] & ctype_word) != 0) + { + name[n++] = next; + if (n > 32) goto BAD; + if (++ptr >= repend) break; + next = *ptr; + } + if (n == 0) goto BAD; + name[n] = 0; } - next = 0; /* not used or updated after this point */ - (void)next; - /* In extended mode we recognize ${name:+set text:unset text} and ${name:-default text}. */ if (inparens) { if ((suboptions & PCRE2_SUBSTITUTE_EXTENDED) != 0 && - !star && ptr < repend - 2 && *ptr == CHAR_COLON) + !star && ptr < repend - 2 && next == CHAR_COLON) { special = *(++ptr); if (special != CHAR_PLUS && special != CHAR_MINUS) @@ -1241,13 +653,6 @@ do ptr++; } - if (inangle) - { - if (ptr >= repend || *ptr != CHAR_GREATER_THAN_SIGN) - goto BAD; - ptr++; - } - /* Have found a syntactically correct group number or name, or *name. Only *MARK is currently recognized. */ @@ -1258,14 +663,10 @@ do PCRE2_SPTR mark = pcre2_get_mark(match_data); if (mark != NULL) { - /* Peek backwards one code unit to obtain the length of the mark. - It can (theoretically) contain an embedded NUL. */ - fraglength = mark[-1]; - if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && - substitute_case_callout == NULL) - CHECKCASECPY_DEFAULT(mark, fraglength); - else - CHECKMEMCPY(mark, fraglength); + PCRE2_SPTR mark_start = mark; + while (*mark != 0) mark++; + fraglength = mark - mark_start; + CHECKMEMCPY(mark_start, fraglength); } } else goto BAD; @@ -1276,7 +677,8 @@ do else { - GROUP_SUBSTITUTE: + PCRE2_SPTR subptr, subptrend; + /* Find a number for a named group. In case there are duplicate names, search for the first one that is set. If the name is not found when PCRE2_SUBSTITUTE_UNKNOWN_EMPTY is set, set the group number to a @@ -1373,14 +775,41 @@ do /* Substitute a literal string, possibly forcing alphabetic case. */ - SUBPTR_SUBSTITUTE: - if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && - substitute_case_callout == NULL) - CHECKCASECPY_DEFAULT(subptr, subptrend - subptr); - else - CHECKMEMCPY(subptr, subptrend - subptr); + while (subptr < subptrend) + { + GETCHARINCTEST(ch, subptr); + if (forcecase != 0) + { +#ifdef SUPPORT_UNICODE + if (utf || ucp) + { + uint32_t type = UCD_CHARTYPE(ch); + if (PRIV(ucp_gentype)[type] == ucp_L && + type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) + ch = UCD_OTHERCASE(ch); + } + else +#endif + { + if (((code->tables + cbits_offset + + ((forcecase > 0)? cbit_upper:cbit_lower) + )[ch/8] & (1u << (ch%8))) == 0) + ch = (code->tables + fcc_offset)[ch]; + } + forcecase = forcecasereset; + } + +#ifdef SUPPORT_UNICODE + if (utf) chlen = PRIV(ord2utf)(ch, temp); else +#endif + { + temp[0] = ch; + chlen = 1; + } + CHECKMEMCPY(temp, chlen); + } } - } /* End of $ processing */ + } /* Handle an escape sequence in extended mode. We can use check_escape() to process \Q, \E, \c, \o, \x and \ followed by non-alphanumerics, but @@ -1391,239 +820,123 @@ do *ptr == CHAR_BACKSLASH) { int errorcode; - case_state new_forcecase = { PCRE2_SUBSTITUTE_CASE_NONE, FALSE }; if (ptr < repend - 1) switch (ptr[1]) { case CHAR_L: - new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_LOWER; - new_forcecase.single_char = FALSE; + forcecase = forcecasereset = -1; ptr += 2; - break; + continue; case CHAR_l: - new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_LOWER; - new_forcecase.single_char = TRUE; + forcecase = -1; + forcecasereset = 0; ptr += 2; - if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_U) - { - /* Perl reverse-title-casing feature for \l\U */ - new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_REVERSE_TITLE_FIRST; - new_forcecase.single_char = FALSE; - ptr += 2; - } - break; + continue; case CHAR_U: - new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_UPPER; - new_forcecase.single_char = FALSE; + forcecase = forcecasereset = 1; ptr += 2; - break; + continue; case CHAR_u: - new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_TITLE_FIRST; - new_forcecase.single_char = TRUE; + forcecase = 1; + forcecasereset = 0; ptr += 2; - if (ptr + 2 < repend && ptr[0] == CHAR_BACKSLASH && ptr[1] == CHAR_L) - { - /* Perl title-casing feature for \u\L */ - new_forcecase.to_case = PCRE2_SUBSTITUTE_CASE_TITLE_FIRST; - new_forcecase.single_char = FALSE; - ptr += 2; - } - break; + continue; default: break; } - if (new_forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE) - { - SETFORCECASE: - - /* If the substitute_case_callout is unset, our case-forcing is done - immediately. If there is a callout however, then its action is delayed - until all the characters have been collected. - - Apply the callout now, before we set the new casing mode. */ - - if (substitute_case_callout != NULL && - forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE) - DELAYEDFORCECASE(); - - forcecase = new_forcecase; - casestart_offset = buff_offset; - casestart_extra_needed = extra_needed; - continue; - } - ptr++; /* Point after \ */ rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode, - code->overall_options, code->extra_options, code->top_bracket, FALSE, NULL); + code->overall_options, code->extra_options, FALSE, NULL); if (errorcode != 0) goto BADESCAPE; switch(rc) { case ESC_E: - goto SETFORCECASE; + forcecase = forcecasereset = 0; + continue; case ESC_Q: escaped_literal = TRUE; continue; case 0: /* Data character */ - case ESC_b: /* \b is backspace in a substitution */ - case ESC_v: /* \v is vertical tab in a substitution */ - - if (rc == ESC_b) ch = CHAR_BS; - if (rc == ESC_v) ch = CHAR_VT; - -#ifdef SUPPORT_UNICODE - if (utf) chlen = PRIV(ord2utf)(ch, temp); else -#endif - { - temp[0] = ch; - chlen = 1; - } - - if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && - substitute_case_callout == NULL) - CHECKCASECPY_DEFAULT(temp, chlen); - else - CHECKMEMCPY(temp, chlen); - continue; - - case ESC_g: - { - PCRE2_SIZE name_len; - PCRE2_SPTR name_start; - - /* Parse the \g form (\g already handled by check_escape) */ - if (ptr >= repend || *ptr != CHAR_LESS_THAN_SIGN) - goto BADESCAPE; - ++ptr; - - name_start = ptr; - if (!read_name_subst(&ptr, repend, utf, code->tables + ctypes_offset)) - goto BADESCAPE; - name_len = ptr - name_start; - - if (ptr >= repend || *ptr != CHAR_GREATER_THAN_SIGN) - goto BADESCAPE; - ++ptr; - - special = 0; - group = -1; - memcpy(name, name_start, CU2BYTES(name_len)); - name[name_len] = 0; - goto GROUP_SUBSTITUTE; - } + goto LITERAL; default: - if (rc < 0) - { - special = 0; - group = -rc - 1; - goto GROUP_SUBSTITUTE; - } goto BADESCAPE; } - } /* End of backslash processing */ + } /* Handle a literal code unit */ else { - PCRE2_SPTR ch_start; - LOADLITERAL: - ch_start = ptr; GETCHARINCTEST(ch, ptr); /* Get character value, increment pointer */ - (void) ch; - if (forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE && - substitute_case_callout == NULL) - CHECKCASECPY_DEFAULT(ch_start, ptr - ch_start); - else - CHECKMEMCPY(ch_start, ptr - ch_start); + LITERAL: + if (forcecase != 0) + { +#ifdef SUPPORT_UNICODE + if (utf || ucp) + { + uint32_t type = UCD_CHARTYPE(ch); + if (PRIV(ucp_gentype)[type] == ucp_L && + type != ((forcecase > 0)? ucp_Lu : ucp_Ll)) + ch = UCD_OTHERCASE(ch); + } + else +#endif + { + if (((code->tables + cbits_offset + + ((forcecase > 0)? cbit_upper:cbit_lower) + )[ch/8] & (1u << (ch%8))) == 0) + ch = (code->tables + fcc_offset)[ch]; + } + forcecase = forcecasereset; + } + +#ifdef SUPPORT_UNICODE + if (utf) chlen = PRIV(ord2utf)(ch, temp); else +#endif + { + temp[0] = ch; + chlen = 1; + } + CHECKMEMCPY(temp, chlen); } /* End handling a literal code unit */ } /* End of loop for scanning the replacement. */ - /* If the substitute_case_callout is unset, our case-forcing is done - immediately. If there is a callout however, then its action is delayed - until all the characters have been collected. - - We now clean up any trailing section of the replacement for which we deferred - the case-forcing. */ - - if (substitute_case_callout != NULL && - forcecase.to_case != PCRE2_SUBSTITUTE_CASE_NONE) - DELAYEDFORCECASE(); - /* The replacement has been copied to the output, or its size has been - remembered. Handle the callout if there is one. */ + remembered. Do the callout if there is one and we have done an actual + replacement. */ - if (mcontext != NULL && mcontext->substitute_callout != NULL) + if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL) { - /* If we an actual (non-simulated) replacement, do the callout. */ + scb.subscount = subs; + scb.output_offsets[1] = buff_offset; + rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data); - if (!overflowed) - { - scb.subscount = subs; - scb.output_offsets[1] = buff_offset; - rc = mcontext->substitute_callout(&scb, - mcontext->substitute_callout_data); + /* A non-zero return means cancel this substitution. Instead, copy the + matched string fragment. */ - /* A non-zero return means cancel this substitution. Instead, copy the - matched string fragment. */ - - if (rc != 0) - { - PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0]; - PCRE2_SIZE oldlength = ovector[1] - ovector[0]; - - buff_offset -= newlength; - lengthleft += newlength; - if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength); - - /* A negative return means do not do any more. */ - - if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL); - } - } - - /* In this interesting case, we cannot do the callout, so it's hard to - estimate the required buffer size. What callers want is to be able to make - two calls to pcre2_substitute(), once with PCRE2_SUBSTITUTE_OVERFLOW_LENGTH - to discover the buffer size, and then a second and final call. Older - versions of PCRE2 violated this assumption, by proceding as if the callout - had returned zero - but on the second call to pcre2_substitute() it could - return non-zero and then overflow the buffer again. Callers probably don't - want to keep on looping to incrementally discover the buffer size. */ - - else + if (rc != 0) { - PCRE2_SIZE newlength_buf = buff_offset - scb.output_offsets[0]; - PCRE2_SIZE newlength_extra = extra_needed - sub_start_extra_needed; - PCRE2_SIZE newlength = - (newlength_extra > ~(PCRE2_SIZE)0 - newlength_buf)? /* Integer overflow */ - ~(PCRE2_SIZE)0 : newlength_buf + newlength_extra; /* Cap the addition */ + PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0]; PCRE2_SIZE oldlength = ovector[1] - ovector[0]; - /* Be pessimistic: request whichever buffer size is larger out of - accepting or rejecting the substitution. */ + buff_offset -= newlength; + lengthleft += newlength; + if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength); - if (oldlength > newlength) - { - PCRE2_SIZE additional = oldlength - newlength; - if (additional > ~(PCRE2_SIZE)0 - extra_needed) /* Integer overflow */ - goto TOOLARGEREPLACE; - extra_needed += additional; - } + /* A negative return means do not do any more. */ - /* Proceed as if the callout did not return a negative. A negative - effectively rejects all future substitutions, but we want to examine them - pessimistically. */ + if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL); } } @@ -1660,9 +973,6 @@ needed. Otherwise, an overflow generates an immediate error return. */ if (overflowed) { rc = PCRE2_ERROR_NOMEMORY; - - if (extra_needed > ~(PCRE2_SIZE)0 - buff_length) /* Integer overflow */ - goto TOOLARGEREPLACE; *blength = buff_length + extra_needed; } @@ -1684,14 +994,6 @@ return rc; rc = PCRE2_ERROR_NOMEMORY; goto EXIT; -CASEERROR: -rc = PCRE2_ERROR_REPLACECASE; -goto EXIT; - -TOOLARGEREPLACE: -rc = PCRE2_ERROR_TOOLARGEREPLACE; -goto EXIT; - BAD: rc = PCRE2_ERROR_BADREPLACEMENT; goto PTREXIT; diff --git a/ext/pcre/pcre2lib/pcre2_substring.c b/ext/pcre/pcre2lib/pcre2_substring.c index 88afd2348bb3..14e919dce930 100644 --- a/ext/pcre/pcre2lib/pcre2_substring.c +++ b/ext/pcre/pcre2lib/pcre2_substring.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -486,7 +486,7 @@ pcre2_substring_nametable_scan(const pcre2_code *code, PCRE2_SPTR stringname, uint16_t bot = 0; uint16_t top = code->name_count; uint16_t entrysize = code->name_entry_size; -PCRE2_SPTR nametable = (PCRE2_SPTR)((const char *)code + sizeof(pcre2_real_code)); +PCRE2_SPTR nametable = (PCRE2_SPTR)((char *)code + sizeof(pcre2_real_code)); while (top > bot) { diff --git a/ext/pcre/pcre2lib/pcre2_ucd.c b/ext/pcre/pcre2lib/pcre2_ucd.c index 4c5e5163b3a9..97dbc8b26f36 100644 --- a/ext/pcre/pcre2lib/pcre2_ucd.c +++ b/ext/pcre/pcre2lib/pcre2_ucd.c @@ -72,13 +72,11 @@ const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0}}; const uint16_t PRIV(ucd_stage1)[] = {0}; const uint16_t PRIV(ucd_stage2)[] = {0}; const uint32_t PRIV(ucd_caseless_sets)[] = {0}; -const uint32_t PRIV(ucd_nocase_ranges)[] = {0}; -const uint32_t PRIV(ucd_nocase_ranges_size) = 0; #else -/* Total size: 116564 bytes, block size: 128. */ +/* Total size: 112564 bytes, block size: 128. */ -const char *PRIV(unicode_version) = "16.0.0"; +const char *PRIV(unicode_version) = "15.0.0"; /* When recompiling tables with a new Unicode version, please check the types in this structure definition with those in pcre2_internal.h (the actual field @@ -142,87 +140,28 @@ const uint32_t PRIV(ucd_caseless_sets)[] = { 0x004b, 0x006b, 0x212a, NOTACHAR, 0x00c5, 0x00e5, 0x212b, NOTACHAR, 0x1c88, 0xa64a, 0xa64b, NOTACHAR, - 0x0069, 0x0130, NOTACHAR, - 0x0049, 0x0131, NOTACHAR, }; -/* This is the index, within ucd_caseless_sets, of the additional -Turkish case-equivalences. The dotted I ones are this offset; the -dotless I are +3 from here. */ - -const uint32_t PRIV(ucd_turkish_dotted_i_caseset) = 112; - /* When #included in pcre2test, we don't need the table of digit sets, nor the the large main UCD tables. */ #ifndef PCRE2_PCRE2TEST -/* This table contains character ranges, where the characters in the range have -no other case. Both start and end values are excluded from the range. */ - -const uint32_t PRIV(ucd_nocase_ranges)[] = { - 0x0000, 0x0041, /* 64 */ - 0x007a, 0x00b5, /* 58 */ - 0x00b5, 0x00c0, /* 10 */ - 0x0292, 0x029d, /* 10 */ - 0x029e, 0x0345, /* 166 */ - 0x0345, 0x0370, /* 42 */ - 0x0481, 0x048a, /* 8 */ - 0x0556, 0x0561, /* 10 */ - 0x0586, 0x10a0, /* 2841 */ - 0x10ff, 0x13a0, /* 672 */ - 0x13fd, 0x1c80, /* 2178 */ - 0x1cbf, 0x1d79, /* 185 */ - 0x1d7d, 0x1d8e, /* 16 */ - 0x1d8e, 0x1e00, /* 113 */ - 0x1ffc, 0x2126, /* 297 */ - 0x2132, 0x214e, /* 27 */ - 0x214e, 0x2160, /* 17 */ - 0x2184, 0x24b6, /* 817 */ - 0x24e9, 0x2c00, /* 1814 */ - 0x2cf3, 0x2d00, /* 12 */ - 0x2d2d, 0xa640, /* 30994 */ - 0xa66d, 0xa680, /* 18 */ - 0xa69b, 0xa722, /* 134 */ - 0xa76f, 0xa779, /* 9 */ - 0xa7dc, 0xa7f5, /* 24 */ - 0xa7f6, 0xab53, /* 860 */ - 0xab53, 0xab70, /* 28 */ - 0xabbf, 0xfb05, /* 20293 */ - 0xfb06, 0xff21, /* 1050 */ - 0xff5a, 0x10400, /* 1189 */ - 0x1044f, 0x104b0, /* 96 */ - 0x104fb, 0x10570, /* 116 */ - 0x105bc, 0x10c80, /* 1731 */ - 0x10cb2, 0x10cc0, /* 13 */ - 0x10cf2, 0x10d50, /* 93 */ - 0x10d65, 0x10d70, /* 10 */ - 0x10d85, 0x118a0, /* 2842 */ - 0x118df, 0x16e40, /* 21856 */ - 0x16e7f, 0x1e900, /* 31360 */ - 0x1e943, 0x110000, /* 988860 */ - 0xffffffff, 0xffffffff /* terminator */ -}; - -/* Total: 1110933 characters. */ -const uint32_t PRIV(ucd_nocase_ranges_size) = 80; - /* This table lists the code points for the '9' characters in each set of decimal digits. It is used to ensure that all the digits in a script run come from the same set. */ const uint32_t PRIV(ucd_digit_sets)[] = { - 76, /* Number of subsequent values */ + 68, /* Number of subsequent values */ 0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef, 0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9, 0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89, 0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909, - 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x10d49, - 0x1106f, 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, - 0x116c9, 0x116d9, 0x116e3, 0x11739, 0x118e9, 0x11959, 0x11bf9, 0x11c59, - 0x11d59, 0x11da9, 0x11f59, 0x16139, 0x16a69, 0x16ac9, 0x16b59, 0x16d79, - 0x1ccf9, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, - 0x1e4f9, 0x1e5fa, 0x1e959, 0x1fbf9, + 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f, + 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9, + 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x11f59, 0x16a69, + 0x16ac9, 0x16b59, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, + 0x1e2f9, 0x1e4f9, 0x1e959, 0x1fbf9, }; /* This vector is a list of script bitsets for the Script Extension property. @@ -230,117 +169,69 @@ The number of 32-bit words in each bitset is #defined in pcre2_ucp.h as ucd_script_sets_item_size. */ const uint32_t PRIV(ucd_script_sets)[] = { - 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x40200003u, 0x00381901u, 0x00100246u, 0x00000000u, - 0x00040305u, 0x00800000u, 0x08000000u, 0x00000000u, - 0x20000001u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000001u, 0x00800000u, 0x00000000u, 0x00000000u, - 0x00040001u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x01000007u, 0x00000840u, 0x80000200u, 0x00000000u, - 0x01000007u, 0x00000040u, 0x80010000u, 0x00000001u, - 0x01000005u, 0x00002000u, 0x00000000u, 0x00000000u, - 0x00040041u, 0x00001000u, 0x80000000u, 0x00000000u, - 0x01000047u, 0x00002801u, 0x00010001u, 0x00000001u, - 0x10000001u, 0x00001801u, 0x00000004u, 0x00000000u, - 0x00000007u, 0x00000000u, 0x00000200u, 0x00000000u, - 0x00000051u, 0x00002840u, 0x00000202u, 0x00000001u, - 0x0000005fu, 0x00000041u, 0x00000202u, 0x00000000u, - 0x00000001u, 0x00002000u, 0x00000000u, 0x00000000u, - 0x00000041u, 0x00000000u, 0x00000002u, 0x00000000u, - 0x01000005u, 0x00000000u, 0x00010000u, 0x00000000u, - 0x01000001u, 0x00000040u, 0x00000000u, 0x00000000u, - 0x00000001u, 0x00000000u, 0x80000000u, 0x00000000u, - 0x00800001u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000005u, 0x00000000u, 0x00000000u, 0x00000001u, - 0x00000003u, 0x00000000u, 0x00000200u, 0x00000001u, - 0x00000041u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x11000041u, 0x00000000u, 0x00000002u, 0x00000000u, - 0x01000041u, 0x00000000u, 0x00000002u, 0x00000000u, - 0x00000041u, 0x00000000u, 0x80000000u, 0x00000000u, - 0x01000041u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x01040001u, 0x00000001u, 0x80000001u, 0x00000000u, - 0x00000002u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000001u, 0x00000000u, 0x00010000u, 0x00000000u, - 0x00000001u, 0x00000000u, 0x00000001u, 0x00000001u, - 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000002u, 0x00000800u, 0x00000000u, 0x00000000u, - 0x00000004u, 0x00000000u, 0x00000200u, 0x00000000u, - 0x00000004u, 0x00001000u, 0x00000000u, 0x00000000u, - 0x00000005u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00200008u, 0x00001000u, 0x00000000u, 0x00000000u, - 0x000000e0u, 0x00010000u, 0x11200000u, 0x00000000u, - 0x000000e0u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x000000e0u, 0x00010000u, 0x11208000u, 0x00000000u, - 0x00000060u, 0x08000000u, 0x04608480u, 0x00000000u, - 0x00000060u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x000000a0u, 0x00000000u, 0x01000000u, 0x00000000u, - 0x00000020u, 0x00000000u, 0x00200000u, 0x00000000u, - 0x0001ff01u, 0x40000000u, 0x00001008u, 0x00000000u, - 0x0001ff01u, 0x00000000u, 0x00001008u, 0x00000000u, - 0x0003ff00u, 0x80004000u, 0x409c1848u, 0x00000000u, - 0x0003ff00u, 0x80004020u, 0x609c1848u, 0x00000000u, - 0x00000100u, 0x04000000u, 0x00080040u, 0x00000000u, - 0x00000200u, 0x10004000u, 0x00000000u, 0x00000000u, - 0x00000400u, 0x00000000u, 0x00002000u, 0x00000000u, - 0x00000800u, 0x00000000u, 0x00000010u, 0x00000000u, - 0x00002000u, 0x00000000u, 0x00000008u, 0x00000000u, - 0x00008000u, 0x00000000u, 0x00800000u, 0x00000002u, - 0x00100000u, 0x10000040u, 0x00000000u, 0x00000000u, - 0x00200001u, 0x00001000u, 0x00000000u, 0x00000000u, - 0x02000000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x0000001eu, 0x00000000u, 0x00000000u, - 0x04000000u, 0x00008000u, 0x00000000u, 0x00000000u, - 0x00008300u, 0x00000000u, 0x00000008u, 0x00000000u, - 0x00000100u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00008100u, 0x00000000u, 0x00000008u, 0x00000000u, - 0x00000300u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000100u, 0x40000000u, 0x00000000u, 0x00000000u, - 0x0001f100u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000100u, 0x00000000u, 0x00800000u, 0x00000000u, - 0x0003d300u, 0x00000000u, 0x00801008u, 0x00000002u, - 0x00000100u, 0x00000000u, 0x00000008u, 0x00000000u, - 0x00008100u, 0x00000000u, 0x00000008u, 0x00000002u, - 0x00000200u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00000000u, 0x00800000u, 0x00000000u, - 0x00000045u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000040u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x04000001u, 0x00008000u, 0x00000000u, 0x00000000u, - 0x00000020u, 0x00000000u, 0x00008000u, 0x00000000u, - 0x00200000u, 0x020c1000u, 0x00004000u, 0x00000000u, - 0x00000002u, 0x20080000u, 0x00004000u, 0x00000000u, - 0x00000101u, 0x00000000u, 0x00000008u, 0x00000000u, - 0x00000001u, 0x00000800u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x02200000u, 0x00000000u, 0x00000000u, - 0x00200000u, 0x04780000u, 0x00004000u, 0x00000000u, - 0x00000000u, 0x00000000u, 0x00000002u, 0x00000000u, - 0x00000020u, 0x00000000u, 0x0000c000u, 0x00000000u, - 0x40000000u, 0x00000000u, 0x00020000u, 0x00000000u, - 0xfc400000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0xfc400000u, 0x00008000u, 0x00000000u, 0x00000000u, - 0x78400000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x40000000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0xfc480000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0xfc480000u, 0x00800000u, 0x00000000u, 0x00000000u, - 0xf8400000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x60000000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x18000000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x58000000u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x40000001u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00018d00u, 0xc4000000u, 0x00881950u, 0x00000002u, - 0x00008d00u, 0xc4000000u, 0x00881950u, 0x00000002u, - 0x00000d00u, 0x84000000u, 0x00081950u, 0x00000000u, - 0x00000d00u, 0xc4000000u, 0x00081950u, 0x00000000u, - 0x00000300u, 0x00000000u, 0x00000000u, 0x00000002u, - 0x00002100u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00100001u, 0x00020000u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x01000400u, 0x00000000u, 0x00000000u, - 0x00000020u, 0x00010000u, 0x00000000u, 0x00000000u, - 0x000000a0u, 0x00000000u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00000280u, 0x02000000u, 0x00000000u, - 0x00000000u, 0x00000280u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00000280u, 0x00000020u, 0x00000000u, - 0x00000020u, 0x00000800u, 0x00000000u, 0x00000000u, - 0x00000000u, 0x00000000u, 0x04000080u, 0x00000000u, + 0x00000000u, 0x00000000u, 0x00000000u, + 0x00000080u, 0x00000000u, 0x00000000u, + 0x00000040u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00004000u, 0x00000000u, + 0x00000002u, 0x00000000u, 0x00000000u, + 0x00800000u, 0x00000000u, 0x00000000u, + 0x00000001u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000000u, 0x00000001u, + 0x00000010u, 0x00000000u, 0x00000000u, + 0x00000008u, 0x00000004u, 0x00000000u, + 0x00000008u, 0x40000000u, 0x00000000u, + 0x00000008u, 0x00000040u, 0x00000000u, + 0x00000018u, 0x00000000u, 0x00000000u, + 0x00000028u, 0x00000000u, 0x00000000u, + 0x000000c0u, 0x00000000u, 0x00000000u, + 0x00c00000u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00000102u, 0x00000000u, + 0x80000000u, 0x00000001u, 0x00000000u, + 0x00000004u, 0x00000008u, 0x00000000u, + 0x00000005u, 0x00000000u, 0x00000000u, + 0x00000004u, 0x00200000u, 0x00000000u, + 0x00000014u, 0x00000000u, 0x00000000u, + 0x00000040u, 0x00008000u, 0x00000000u, + 0x00000040u, 0x00000000u, 0x00000001u, + 0x00000040u, 0x00001000u, 0x00000000u, + 0x00000840u, 0x00000000u, 0x00000000u, + 0x00020001u, 0x00000000u, 0x00000000u, + 0x00000800u, 0x00008000u, 0x00000000u, + 0x00000200u, 0x00010000u, 0x00000000u, + 0x00000100u, 0x02000000u, 0x00000000u, + 0x00800001u, 0x00000000u, 0x00000000u, + 0x00300000u, 0x00000000u, 0x00000000u, + 0x00002000u, 0x00000000u, 0x00000001u, + 0x00080001u, 0x00000000u, 0x00000000u, + 0x00000000u, 0x00080000u, 0x00000008u, + 0x00080000u, 0x00000020u, 0x00000000u, + 0x00000038u, 0x00000000u, 0x00000000u, + 0x00000028u, 0x00000000u, 0x00000002u, + 0x00000080u, 0x00000810u, 0x00000000u, + 0x40010000u, 0x00000800u, 0x00000000u, + 0x80000000u, 0x00000001u, 0x00000004u, + 0x80000000u, 0x00020001u, 0x00000000u, + 0x00002040u, 0x00008000u, 0x00000000u, + 0x00000041u, 0x00008000u, 0x00000000u, + 0x00b00000u, 0x00000000u, 0x00000000u, + 0x00010001u, 0x00000080u, 0x00000000u, + 0x000020c0u, 0x00008000u, 0x00000000u, + 0x1e000000u, 0x00000000u, 0x00000000u, + 0x00000040u, 0x10040200u, 0x00000000u, + 0x00f40000u, 0x00000000u, 0x00000000u, + 0x00000038u, 0x40000040u, 0x00000002u, + 0x01f40000u, 0x00000000u, 0x00000000u, + 0x00007c40u, 0x00000000u, 0x00000000u, + 0x00000038u, 0x44000040u, 0x00000002u, + 0x000034c0u, 0x01008000u, 0x00000001u, + 0x00000018u, 0xc4480400u, 0x00000008u, + 0x00000340u, 0x11952200u, 0x00000000u, + 0x00007fc1u, 0x01008000u, 0x00000000u, + 0x00007fc1u, 0x01009000u, 0x00000000u, + 0x00002340u, 0x11952200u, 0x00000001u, + 0x00006340u, 0x11952200u, 0x00000001u, + 0x0000ffc0u, 0x3984a010u, 0x00000001u, + 0x2000ffc0u, 0x3984a010u, 0x00000001u, }; /* This vector is a list of bitsets for Boolean properties. The number of @@ -350,196 +241,181 @@ pcre2_ucp.h. */ const uint32_t PRIV(ucd_boolprop_sets)[] = { 0x00000000u, 0x00000000u, 0x00000001u, 0x00000000u, - 0x00000001u, 0x00400800u, - 0x00800001u, 0x00400800u, - 0x00800001u, 0x00050400u, - 0x00800001u, 0x00002400u, - 0x00830001u, 0x00000400u, - 0x00800001u, 0x00000400u, - 0x00800021u, 0x00002400u, - 0x00800011u, 0x00000400u, - 0x00800001u, 0x00000480u, - 0x00800001u, 0x00040400u, - 0x00801001u, 0x00000400u, - 0x00800021u, 0x00050400u, - 0x04830003u, 0x00800001u, - 0x00800021u, 0x00040400u, - 0x00800011u, 0x00000480u, - 0x048003c7u, 0x01900003u, - 0x008003c5u, 0x01900003u, - 0x00808021u, 0x00000480u, - 0x00800001u, 0x00800001u, - 0x00808021u, 0x00000400u, - 0x04800d47u, 0x01800043u, - 0x00800d45u, 0x01800043u, - 0x00800d45u, 0x01820043u, - 0x00000000u, 0x00400800u, - 0x00800000u, 0x00400000u, - 0x00800000u, 0x00000400u, + 0x00000001u, 0x00020040u, + 0x00800001u, 0x00020040u, + 0x00800001u, 0x00002820u, + 0x00800001u, 0x00000120u, + 0x00830001u, 0x00000020u, + 0x00800001u, 0x00000020u, + 0x00800021u, 0x00000120u, + 0x00800011u, 0x00000020u, + 0x00800001u, 0x00000028u, + 0x00800001u, 0x00002020u, + 0x00801001u, 0x00000020u, + 0x00800021u, 0x00002820u, + 0x24830003u, 0x00040000u, + 0x00800021u, 0x00002020u, + 0x00800011u, 0x00000028u, + 0x648003c7u, 0x000c8000u, + 0x608003c5u, 0x000c8000u, + 0x00808021u, 0x00000028u, + 0x20800001u, 0x00040000u, + 0x00808021u, 0x00000020u, + 0x64800d47u, 0x000c0004u, + 0x60800d45u, 0x000c0004u, + 0x60800d45u, 0x000c1004u, + 0x00000000u, 0x00020040u, + 0x00800000u, 0x00020000u, + 0x00800000u, 0x00000020u, 0x00808020u, 0x00000000u, - 0x00a10000u, 0x00000400u, - 0x00800044u, 0x01800043u, - 0x00800010u, 0x00002400u, - 0x00800000u, 0x00000480u, + 0x00a10000u, 0x00000020u, + 0x60800044u, 0x000c0004u, + 0x00800010u, 0x00000120u, + 0x00800000u, 0x00000028u, 0x00002020u, 0x00000000u, - 0x40800000u, 0x00000000u, - 0x00800dc4u, 0x01800043u, - 0x00c08020u, 0x00800001u, 0x00800000u, 0x00000000u, - 0x008003c4u, 0x01900003u, - 0x00800d44u, 0x01800043u, - 0x00800d44u, 0x01820043u, - 0x00804dc4u, 0x01800043u, - 0x00800004u, 0x01800003u, - 0x008007c4u, 0x01900003u, - 0x00800bc4u, 0x01800003u, - 0x00808064u, 0x01800043u, - 0x00808064u, 0x01820043u, - 0x00808024u, 0x01800003u, - 0x00c08024u, 0x01800003u, - 0x01008020u, 0x00800009u, - 0x01008de4u, 0x00800049u, - 0x01002020u, 0x00800009u, - 0x01000020u, 0x00800009u, - 0x01000024u, 0x00800009u, - 0x00808064u, 0x00000043u, - 0x00800000u, 0x00040000u, - 0x00800020u, 0x00840001u, - 0x00800dc4u, 0x018000c3u, - 0x00800044u, 0x01900083u, - 0x00800044u, 0x01900003u, - 0x008003c4u, 0x01900083u, - 0x00800000u, 0x00000080u, - 0x01000020u, 0x00000008u, + 0x60800dc4u, 0x000c0004u, + 0x20c08020u, 0x00040000u, + 0x608003c4u, 0x000c8000u, + 0x60800d44u, 0x000c0004u, + 0x60800d44u, 0x000c1004u, + 0x60804dc4u, 0x000c0004u, + 0x60800004u, 0x000c0000u, + 0x608007c4u, 0x000c8000u, + 0x60800bc4u, 0x000c0000u, + 0x60808064u, 0x000c0004u, + 0x60808064u, 0x000c1004u, + 0x60808024u, 0x000c0000u, + 0x60c08024u, 0x000c0000u, + 0x21008020u, 0x00040000u, + 0x21008de4u, 0x00040004u, + 0x21002020u, 0x00040000u, + 0x21000020u, 0x00040000u, + 0x60808064u, 0x00000004u, + 0x00800000u, 0x00002000u, + 0x20800020u, 0x00042000u, + 0x60800dc4u, 0x000c000cu, + 0x60800044u, 0x000c8008u, + 0x60800044u, 0x000c8000u, + 0x608003c4u, 0x000c8008u, + 0x00800000u, 0x00000008u, + 0x01000020u, 0x00000000u, 0x00800020u, 0x00000000u, - 0x00800000u, 0x00050000u, + 0x00800000u, 0x00002800u, 0x00801000u, 0x00000000u, - 0x01008024u, 0x00800009u, - 0x00000020u, 0x00001000u, + 0x21008024u, 0x00040000u, + 0x21000024u, 0x00040000u, + 0x00000020u, 0x00000080u, 0x00002028u, 0x00000000u, - 0x00c00024u, 0x01800003u, - 0x01000024u, 0x00800109u, - 0x01008020u, 0x00800109u, - 0x00800000u, 0x00800001u, - 0x00804004u, 0x01800003u, - 0x00800024u, 0x01800003u, - 0x01000020u, 0x00800109u, - 0x01008024u, 0x00800109u, - 0x00800004u, 0x00800001u, - 0x00800004u, 0x0180000bu, - 0x03008020u, 0x00800009u, - 0x01000004u, 0x00800009u, - 0x01400024u, 0x00800009u, - 0x01408020u, 0x00800009u, - 0x00800004u, 0x00800003u, - 0x03008024u, 0x00800009u, - 0x00800004u, 0x01800023u, + 0x60c00024u, 0x000c0000u, + 0x20800000u, 0x00040000u, + 0x60804004u, 0x000c0000u, + 0x60800024u, 0x000c0000u, + 0x20800004u, 0x00040000u, + 0x23008020u, 0x00040000u, + 0x21000004u, 0x00040000u, + 0x21408020u, 0x00040000u, + 0x60800004u, 0x00040000u, + 0x23000024u, 0x00040000u, + 0x60800004u, 0x000c0002u, 0x00800010u, 0x00000000u, - 0x00808000u, 0x00800001u, - 0x01004024u, 0x00800009u, - 0x00808004u, 0x00800001u, - 0x00800944u, 0x01800043u, - 0x00800064u, 0x01800043u, - 0x00802004u, 0x01800003u, - 0x00800344u, 0x01900003u, - 0x03008000u, 0x00800009u, + 0x20808000u, 0x00040000u, + 0x21004024u, 0x00040000u, + 0x20808004u, 0x00040000u, + 0x60800944u, 0x000c0004u, + 0x60800064u, 0x000c0004u, + 0x60802004u, 0x000c0000u, + 0x60800344u, 0x000c8000u, + 0x22808000u, 0x00040000u, + 0x22800000u, 0x00040000u, 0x00c00000u, 0x00000000u, - 0x01002020u, 0x00a00009u, - 0x01000024u, 0x0180000bu, - 0x01008020u, 0x00000008u, - 0x01408024u, 0x00800009u, + 0x21002020u, 0x00050000u, + 0x61000024u, 0x000c0000u, + 0x23000020u, 0x00040000u, + 0x01008020u, 0x00000000u, + 0x21408024u, 0x00040000u, 0x00808000u, 0x00000000u, - 0x00800044u, 0x01820043u, - 0x00800064u, 0x01820043u, - 0x01002020u, 0x00800011u, - 0x00022020u, 0x00800019u, - 0x00002028u, 0x00000800u, - 0x00801000u, 0x00000400u, - 0x00800020u, 0x00002400u, - 0x00800000u, 0x00002400u, - 0x00800020u, 0x00050400u, - 0x00800020u, 0x00000400u, - 0x00a10000u, 0x00050400u, - 0x00800000u, 0x00050400u, - 0x00800000u, 0x00800081u, - 0x00800010u, 0x00000400u, - 0x00002020u, 0x00000080u, + 0x60800044u, 0x000c1004u, + 0x60800064u, 0x000c1004u, + 0x01002020u, 0x00000001u, + 0x00022020u, 0x00000001u, + 0x00002028u, 0x00000040u, + 0x00801000u, 0x00000020u, + 0x00800020u, 0x00000120u, + 0x00800000u, 0x00000120u, + 0x00800020u, 0x00000020u, + 0x00a10000u, 0x00002820u, + 0x00800000u, 0x00002820u, + 0x20800000u, 0x00040008u, + 0x00800010u, 0x00000020u, + 0x00002020u, 0x00000008u, 0x00002000u, 0x00000000u, 0x00006020u, 0x00000000u, - 0x40800000u, 0x00000080u, - 0x40801000u, 0x00000080u, - 0x40800010u, 0x00000080u, - 0x01000020u, 0x00800089u, - 0x01020020u, 0x00000008u, - 0x00800044u, 0x018000c3u, - 0x00800000u, 0x01800083u, + 0x00801000u, 0x00000008u, + 0x00800010u, 0x00000008u, + 0x21000020u, 0x00040008u, + 0x01020020u, 0x00000000u, + 0x60800044u, 0x000c000cu, + 0x60800000u, 0x000c0008u, 0x00a10000u, 0x00000000u, - 0x00800000u, 0x01800003u, - 0x00800004u, 0x01800083u, - 0x00a10044u, 0x01800043u, - 0x00800044u, 0x018200c3u, - 0x00a10000u, 0x00000480u, - 0xc0800000u, 0x00000480u, - 0x00800010u, 0x00000480u, - 0x00801000u, 0x00000480u, - 0x00b10000u, 0x00000400u, - 0x00804010u, 0x00000400u, - 0x00a00000u, 0x00000400u, - 0x00000000u, 0x00000400u, - 0x008003c4u, 0x00100000u, - 0x00a103c4u, 0x00100000u, - 0x00800d44u, 0x00000040u, - 0x00b10000u, 0x00000480u, - 0x00a00000u, 0x00000480u, - 0x00a90000u, 0x00000400u, - 0x00b90000u, 0x00000400u, - 0x03000020u, 0x00800009u, - 0x00808024u, 0x00000400u, - 0x00800000u, 0x00040400u, - 0x00800000u, 0x00004000u, + 0x60800000u, 0x000c0000u, + 0x60800004u, 0x000c0008u, + 0x60a10044u, 0x000c0004u, + 0x60800044u, 0x000c100cu, + 0x00a10000u, 0x00000028u, + 0x00800010u, 0x00000028u, + 0x00801000u, 0x00000028u, + 0x00b10000u, 0x00000020u, + 0x00804010u, 0x00000020u, + 0x00a00000u, 0x00000020u, + 0x00000000u, 0x00000020u, + 0x008003c4u, 0x00008000u, + 0x00a103c4u, 0x00008000u, + 0x00800d44u, 0x00000004u, + 0x00b10000u, 0x00000028u, + 0x00a00000u, 0x00000028u, + 0x00a90000u, 0x00000020u, + 0x00b90000u, 0x00000020u, + 0x00808024u, 0x00000020u, + 0x00800000u, 0x00002020u, + 0x00800000u, 0x00000200u, 0x08800000u, 0x00000000u, 0x10800000u, 0x00000000u, - 0x20800000u, 0x00000000u, - 0x00800004u, 0x01800007u, - 0x01008000u, 0x00800009u, - 0x00a11000u, 0x00000400u, - 0x00808020u, 0x00000003u, - 0x00800004u, 0x01880007u, - 0x00808004u, 0x01800003u, - 0x00800004u, 0x00000003u, - 0x00000000u, 0x00000200u, - 0x01022020u, 0x00a00009u, - 0x00800000u, 0x00002000u, - 0x00800020u, 0x00050000u, - 0x00800020u, 0x00040000u, - 0x00801000u, 0x00000080u, - 0x00800010u, 0x00000080u, + 0xe0800004u, 0x000c0000u, + 0x21008000u, 0x00040000u, + 0x00a11000u, 0x00000020u, + 0x60808020u, 0x00000000u, + 0xe0800004u, 0x000c4000u, + 0x60808004u, 0x000c0000u, + 0x60800004u, 0x00000000u, + 0x00000000u, 0x00000010u, + 0x21022020u, 0x00050000u, + 0x00800000u, 0x00000100u, + 0x00800020u, 0x00002800u, 0x00800020u, 0x00002000u, - 0x04800000u, 0x00800001u, - 0x048003c4u, 0x01900003u, - 0x00808020u, 0x00000080u, - 0x04800d44u, 0x01800043u, - 0x00800010u, 0x00002000u, - 0x01008024u, 0x0080000bu, + 0x00800020u, 0x00000100u, + 0x24800000u, 0x00040000u, + 0x648003c4u, 0x000c8000u, + 0x00808020u, 0x00000008u, + 0x64800d44u, 0x000c0004u, + 0x00800010u, 0x00000100u, + 0x61008024u, 0x00040000u, 0x00000020u, 0x00000000u, - 0x00c00004u, 0x01800003u, - 0x00c08004u, 0x01800003u, - 0x01400020u, 0x00800009u, - 0x01000020u, 0x0080000du, - 0x01008004u, 0x00800009u, - 0x01000000u, 0x00800009u, - 0xc0800000u, 0x00000080u, + 0x60c00004u, 0x000c0000u, + 0x21400020u, 0x00040000u, + 0xa1000020u, 0x00040000u, + 0x21000000u, 0x00040000u, 0x00a00000u, 0x00000000u, 0x00b10000u, 0x00000000u, 0x00200000u, 0x00000000u, - 0x00800044u, 0x00100000u, - 0x00a10044u, 0x00100000u, - 0x00930000u, 0x00008000u, + 0x00800044u, 0x00008000u, + 0x00a10044u, 0x00008000u, + 0x00930000u, 0x00000400u, 0x00b90000u, 0x00000000u, 0x00a90000u, 0x00000000u, - 0x00970020u, 0x00000008u, + 0x00970020u, 0x00000000u, 0x00b30000u, 0x00000000u, - 0x01022020u, 0x00000008u, + 0x01022020u, 0x00000000u, }; /* These are the main two-stage UCD tables. The fields in each record are: @@ -548,1550 +424,1430 @@ offset to multichar other cases or zero (8 bits), offset to other case or zero (32 bits, signed), bidi class (5 bits) and script extension (11 bits) packed into a 16-bit field, and offset in binary properties table (16 bits). */ -const ucd_record PRIV(ucd_records)[] = { /* 18516 bytes, record size 12 */ - { 99, 0, 2, 0, 0, 6144, 2, }, /* 0 */ - { 99, 0, 2, 0, 0, 43008, 4, }, /* 1 */ - { 99, 0, 1, 0, 0, 4096, 4, }, /* 2 */ - { 99, 0, 2, 0, 0, 45056, 4, }, /* 3 */ - { 99, 0, 0, 0, 0, 4096, 4, }, /* 4 */ - { 99, 0, 2, 0, 0, 4096, 2, }, /* 5 */ - { 99, 0, 2, 0, 0, 43008, 2, }, /* 6 */ - { 99, 29, 12, 0, 0, 45056, 6, }, /* 7 */ - { 99, 21, 12, 0, 0, 28672, 8, }, /* 8 */ - { 99, 21, 12, 0, 0, 28672, 10, }, /* 9 */ - { 99, 21, 12, 0, 0, 14336, 12, }, /* 10 */ - { 99, 23, 12, 0, 0, 14336, 14, }, /* 11 */ - { 99, 21, 12, 0, 0, 14336, 14, }, /* 12 */ - { 99, 21, 12, 0, 0, 28672, 14, }, /* 13 */ - { 99, 21, 12, 0, 0, 28672, 16, }, /* 14 */ - { 99, 22, 12, 0, 0, 28672, 18, }, /* 15 */ - { 99, 18, 12, 0, 0, 28672, 18, }, /* 16 */ - { 99, 21, 12, 0, 0, 28672, 12, }, /* 17 */ - { 99, 25, 12, 0, 0, 12288, 20, }, /* 18 */ - { 99, 21, 12, 0, 0, 8192, 22, }, /* 19 */ - { 99, 17, 12, 0, 0, 12288, 24, }, /* 20 */ - { 99, 21, 12, 0, 0, 8192, 26, }, /* 21 */ - { 99, 21, 12, 0, 0, 8192, 14, }, /* 22 */ - { 99, 13, 12, 0, 0, 10240, 28, }, /* 23 */ - { 99, 21, 12, 0, 0, 8192, 30, }, /* 24 */ - { 99, 21, 12, 0, 0, 28672, 22, }, /* 25 */ - { 99, 25, 12, 0, 0, 28672, 32, }, /* 26 */ - { 99, 25, 12, 0, 0, 28672, 20, }, /* 27 */ +const ucd_record PRIV(ucd_records)[] = { /* 17076 bytes, record size 12 */ + { 69, 0, 2, 0, 0, 6144, 2, }, /* 0 */ + { 69, 0, 2, 0, 0, 43008, 4, }, /* 1 */ + { 69, 0, 1, 0, 0, 4096, 4, }, /* 2 */ + { 69, 0, 2, 0, 0, 45056, 4, }, /* 3 */ + { 69, 0, 0, 0, 0, 4096, 4, }, /* 4 */ + { 69, 0, 2, 0, 0, 4096, 2, }, /* 5 */ + { 69, 0, 2, 0, 0, 43008, 2, }, /* 6 */ + { 69, 29, 12, 0, 0, 45056, 6, }, /* 7 */ + { 69, 21, 12, 0, 0, 28672, 8, }, /* 8 */ + { 69, 21, 12, 0, 0, 28672, 10, }, /* 9 */ + { 69, 21, 12, 0, 0, 14336, 12, }, /* 10 */ + { 69, 23, 12, 0, 0, 14336, 14, }, /* 11 */ + { 69, 21, 12, 0, 0, 14336, 14, }, /* 12 */ + { 69, 21, 12, 0, 0, 28672, 14, }, /* 13 */ + { 69, 21, 12, 0, 0, 28672, 16, }, /* 14 */ + { 69, 22, 12, 0, 0, 28672, 18, }, /* 15 */ + { 69, 18, 12, 0, 0, 28672, 18, }, /* 16 */ + { 69, 21, 12, 0, 0, 28672, 12, }, /* 17 */ + { 69, 25, 12, 0, 0, 12288, 20, }, /* 18 */ + { 69, 21, 12, 0, 0, 8192, 22, }, /* 19 */ + { 69, 17, 12, 0, 0, 12288, 24, }, /* 20 */ + { 69, 21, 12, 0, 0, 8192, 26, }, /* 21 */ + { 69, 21, 12, 0, 0, 8192, 14, }, /* 22 */ + { 69, 13, 12, 0, 0, 10240, 28, }, /* 23 */ + { 69, 21, 12, 0, 0, 8192, 30, }, /* 24 */ + { 69, 21, 12, 0, 0, 28672, 22, }, /* 25 */ + { 69, 25, 12, 0, 0, 28672, 32, }, /* 26 */ + { 69, 25, 12, 0, 0, 28672, 20, }, /* 27 */ { 0, 9, 12, 0, 32, 18432, 34, }, /* 28 */ { 0, 9, 12, 0, 32, 18432, 36, }, /* 29 */ { 0, 9, 12, 100, 32, 18432, 36, }, /* 30 */ { 0, 9, 12, 1, 32, 18432, 36, }, /* 31 */ - { 99, 24, 12, 0, 0, 28672, 38, }, /* 32 */ - { 99, 16, 12, 0, 0, 28672, 40, }, /* 33 */ - { 99, 24, 12, 0, 0, 28672, 42, }, /* 34 */ + { 69, 24, 12, 0, 0, 28672, 38, }, /* 32 */ + { 69, 16, 12, 0, 0, 28672, 40, }, /* 33 */ + { 69, 24, 12, 0, 0, 28672, 42, }, /* 34 */ { 0, 5, 12, 0, -32, 18432, 44, }, /* 35 */ { 0, 5, 12, 0, -32, 18432, 46, }, /* 36 */ { 0, 5, 12, 0, -32, 18432, 48, }, /* 37 */ { 0, 5, 12, 100, -32, 18432, 46, }, /* 38 */ { 0, 5, 12, 1, -32, 18432, 46, }, /* 39 */ - { 99, 0, 2, 0, 0, 6144, 0, }, /* 40 */ - { 99, 0, 2, 0, 0, 4096, 50, }, /* 41 */ - { 99, 29, 12, 0, 0, 8192, 52, }, /* 42 */ - { 99, 21, 12, 0, 0, 28672, 54, }, /* 43 */ - { 99, 23, 12, 0, 0, 14336, 54, }, /* 44 */ - { 99, 26, 12, 0, 0, 28672, 54, }, /* 45 */ - { 99, 24, 12, 0, 0, 28672, 56, }, /* 46 */ - { 99, 26, 14, 0, 0, 28672, 58, }, /* 47 */ + { 69, 0, 2, 0, 0, 6144, 0, }, /* 40 */ + { 69, 0, 2, 0, 0, 4096, 50, }, /* 41 */ + { 69, 29, 12, 0, 0, 8192, 52, }, /* 42 */ + { 69, 21, 12, 0, 0, 28672, 54, }, /* 43 */ + { 69, 23, 12, 0, 0, 14336, 54, }, /* 44 */ + { 69, 26, 12, 0, 0, 28672, 54, }, /* 45 */ + { 69, 24, 12, 0, 0, 28672, 56, }, /* 46 */ + { 69, 26, 14, 0, 0, 28672, 58, }, /* 47 */ { 0, 7, 12, 0, 0, 18432, 60, }, /* 48 */ - { 99, 20, 12, 0, 0, 28672, 62, }, /* 49 */ - { 99, 25, 12, 0, 0, 28672, 64, }, /* 50 */ - { 99, 1, 2, 0, 0, 6144, 66, }, /* 51 */ - { 99, 26, 12, 0, 0, 14336, 54, }, /* 52 */ - { 99, 25, 12, 0, 0, 14336, 64, }, /* 53 */ - { 99, 15, 12, 0, 0, 10240, 68, }, /* 54 */ - { 99, 5, 12, 26, 775, 18432, 70, }, /* 55 */ - { 99, 21, 12, 0, 0, 28676, 72, }, /* 56 */ - { 99, 19, 12, 0, 0, 28672, 62, }, /* 57 */ - { 99, 15, 12, 0, 0, 28672, 74, }, /* 58 */ - { 0, 9, 12, 0, 32, 18432, 76, }, /* 59 */ - { 0, 9, 12, 104, 32, 18432, 76, }, /* 60 */ + { 69, 20, 12, 0, 0, 28672, 62, }, /* 49 */ + { 69, 25, 12, 0, 0, 28672, 64, }, /* 50 */ + { 69, 1, 2, 0, 0, 6144, 66, }, /* 51 */ + { 69, 26, 12, 0, 0, 14336, 54, }, /* 52 */ + { 69, 25, 12, 0, 0, 14336, 64, }, /* 53 */ + { 69, 15, 12, 0, 0, 10240, 68, }, /* 54 */ + { 69, 5, 12, 26, 775, 18432, 70, }, /* 55 */ + { 69, 21, 12, 0, 0, 28672, 72, }, /* 56 */ + { 69, 19, 12, 0, 0, 28672, 62, }, /* 57 */ + { 69, 15, 12, 0, 0, 28672, 68, }, /* 58 */ + { 0, 9, 12, 0, 32, 18432, 74, }, /* 59 */ + { 0, 9, 12, 104, 32, 18432, 74, }, /* 60 */ { 0, 5, 12, 0, 7615, 18432, 70, }, /* 61 */ - { 0, 5, 12, 0, -32, 18432, 78, }, /* 62 */ - { 0, 5, 12, 104, -32, 18432, 78, }, /* 63 */ - { 0, 5, 12, 0, 121, 18432, 78, }, /* 64 */ - { 0, 9, 12, 0, 1, 18432, 76, }, /* 65 */ - { 0, 5, 12, 0, -1, 18432, 78, }, /* 66 */ - { 0, 5, 12, 0, -1, 18432, 80, }, /* 67 */ - { 0, 9, 12, 0, 0, 18432, 76, }, /* 68 */ - { 0, 5, 12, 0, 0, 18432, 78, }, /* 69 */ + { 0, 5, 12, 0, -32, 18432, 76, }, /* 62 */ + { 0, 5, 12, 104, -32, 18432, 76, }, /* 63 */ + { 0, 5, 12, 0, 121, 18432, 76, }, /* 64 */ + { 0, 9, 12, 0, 1, 18432, 74, }, /* 65 */ + { 0, 5, 12, 0, -1, 18432, 76, }, /* 66 */ + { 0, 5, 12, 0, -1, 18432, 78, }, /* 67 */ + { 0, 9, 12, 0, 0, 18432, 74, }, /* 68 */ + { 0, 5, 12, 0, 0, 18432, 76, }, /* 69 */ { 0, 5, 12, 0, 0, 18432, 60, }, /* 70 */ - { 0, 5, 12, 0, 0, 18432, 82, }, /* 71 */ - { 0, 9, 12, 0, -121, 18432, 76, }, /* 72 */ + { 0, 5, 12, 0, 0, 18432, 80, }, /* 71 */ + { 0, 9, 12, 0, -121, 18432, 74, }, /* 72 */ { 0, 5, 12, 1, 0, 18432, 70, }, /* 73 */ - { 0, 5, 12, 0, 195, 18432, 78, }, /* 74 */ - { 0, 9, 12, 0, 210, 18432, 76, }, /* 75 */ - { 0, 9, 12, 0, 206, 18432, 76, }, /* 76 */ - { 0, 9, 12, 0, 205, 18432, 76, }, /* 77 */ - { 0, 9, 12, 0, 79, 18432, 76, }, /* 78 */ - { 0, 9, 12, 0, 202, 18432, 76, }, /* 79 */ - { 0, 9, 12, 0, 203, 18432, 76, }, /* 80 */ - { 0, 9, 12, 0, 207, 18432, 76, }, /* 81 */ - { 0, 5, 12, 0, 97, 18432, 78, }, /* 82 */ - { 0, 9, 12, 0, 211, 18432, 76, }, /* 83 */ - { 0, 9, 12, 0, 209, 18432, 76, }, /* 84 */ - { 0, 5, 12, 0, 163, 18432, 78, }, /* 85 */ - { 0, 5, 12, 0, 42561, 18432, 78, }, /* 86 */ - { 0, 9, 12, 0, 213, 18432, 76, }, /* 87 */ - { 0, 5, 12, 0, 130, 18432, 78, }, /* 88 */ - { 0, 9, 12, 0, 214, 18432, 76, }, /* 89 */ - { 0, 9, 12, 0, 218, 18432, 76, }, /* 90 */ - { 0, 9, 12, 0, 217, 18432, 76, }, /* 91 */ - { 0, 9, 12, 0, 219, 18432, 76, }, /* 92 */ - { 0, 7, 12, 0, 0, 18432, 84, }, /* 93 */ - { 0, 5, 12, 0, 56, 18432, 78, }, /* 94 */ - { 0, 9, 12, 5, 2, 18432, 86, }, /* 95 */ - { 0, 8, 12, 5, 1, 18432, 88, }, /* 96 */ - { 0, 5, 12, 5, -2, 18432, 78, }, /* 97 */ - { 0, 9, 12, 9, 2, 18432, 86, }, /* 98 */ - { 0, 8, 12, 9, 1, 18432, 88, }, /* 99 */ - { 0, 5, 12, 9, -2, 18432, 78, }, /* 100 */ - { 0, 9, 12, 13, 2, 18432, 86, }, /* 101 */ - { 0, 8, 12, 13, 1, 18432, 88, }, /* 102 */ - { 0, 5, 12, 13, -2, 18432, 78, }, /* 103 */ - { 0, 5, 12, 0, -79, 18432, 78, }, /* 104 */ - { 0, 9, 12, 17, 2, 18432, 86, }, /* 105 */ - { 0, 8, 12, 17, 1, 18432, 88, }, /* 106 */ - { 0, 5, 12, 17, -2, 18432, 78, }, /* 107 */ - { 0, 9, 12, 0, -97, 18432, 76, }, /* 108 */ - { 0, 9, 12, 0, -56, 18432, 76, }, /* 109 */ - { 0, 9, 12, 0, -130, 18432, 76, }, /* 110 */ - { 0, 9, 12, 0, 10795, 18432, 76, }, /* 111 */ - { 0, 9, 12, 0, -163, 18432, 76, }, /* 112 */ - { 0, 9, 12, 0, 10792, 18432, 76, }, /* 113 */ - { 0, 5, 12, 0, 10815, 18432, 78, }, /* 114 */ - { 0, 9, 12, 0, -195, 18432, 76, }, /* 115 */ - { 0, 9, 12, 0, 69, 18432, 76, }, /* 116 */ - { 0, 9, 12, 0, 71, 18432, 76, }, /* 117 */ - { 0, 5, 12, 0, 10783, 18432, 78, }, /* 118 */ - { 0, 5, 12, 0, 10780, 18432, 78, }, /* 119 */ - { 0, 5, 12, 0, 10782, 18432, 78, }, /* 120 */ - { 0, 5, 12, 0, -210, 18432, 78, }, /* 121 */ - { 0, 5, 12, 0, -206, 18432, 78, }, /* 122 */ - { 0, 5, 12, 0, -205, 18432, 78, }, /* 123 */ - { 0, 5, 12, 0, -202, 18432, 78, }, /* 124 */ - { 0, 5, 12, 0, -203, 18432, 78, }, /* 125 */ - { 0, 5, 12, 0, 42319, 18432, 78, }, /* 126 */ - { 0, 5, 12, 0, 42315, 18432, 78, }, /* 127 */ - { 0, 5, 12, 0, -207, 18432, 78, }, /* 128 */ - { 0, 5, 12, 0, 42343, 18432, 78, }, /* 129 */ - { 0, 5, 12, 0, 42280, 18432, 78, }, /* 130 */ - { 0, 5, 12, 0, 42308, 18432, 78, }, /* 131 */ - { 0, 5, 12, 0, -209, 18432, 80, }, /* 132 */ - { 0, 5, 12, 0, -211, 18432, 78, }, /* 133 */ - { 0, 5, 12, 0, 10743, 18432, 78, }, /* 134 */ - { 0, 5, 12, 0, 42305, 18432, 78, }, /* 135 */ - { 0, 5, 12, 0, 10749, 18432, 78, }, /* 136 */ - { 0, 5, 12, 0, -213, 18432, 78, }, /* 137 */ - { 0, 5, 12, 0, -214, 18432, 78, }, /* 138 */ - { 0, 5, 12, 0, 10727, 18432, 78, }, /* 139 */ - { 0, 5, 12, 0, -218, 18432, 78, }, /* 140 */ - { 0, 5, 12, 0, 42307, 18432, 78, }, /* 141 */ - { 0, 5, 12, 0, 42282, 18432, 78, }, /* 142 */ - { 0, 5, 12, 0, -69, 18432, 78, }, /* 143 */ - { 0, 5, 12, 0, -217, 18432, 78, }, /* 144 */ - { 0, 5, 12, 0, -71, 18432, 78, }, /* 145 */ - { 0, 5, 12, 0, -219, 18432, 78, }, /* 146 */ - { 0, 5, 12, 0, 42261, 18432, 80, }, /* 147 */ - { 0, 5, 12, 0, 42258, 18432, 78, }, /* 148 */ - { 0, 6, 12, 0, 0, 18432, 90, }, /* 149 */ - { 0, 6, 12, 0, 0, 18432, 92, }, /* 150 */ - { 99, 6, 12, 0, 0, 28672, 94, }, /* 151 */ - { 99, 6, 12, 0, 0, 18432, 94, }, /* 152 */ - { 99, 6, 12, 0, 0, 18440, 94, }, /* 153 */ - { 99, 6, 12, 0, 0, 18432, 90, }, /* 154 */ - { 99, 6, 12, 0, 0, 28684, 94, }, /* 155 */ - { 99, 6, 12, 0, 0, 28688, 94, }, /* 156 */ - { 99, 6, 12, 0, 0, 18432, 96, }, /* 157 */ - { 99, 24, 12, 0, 0, 28692, 56, }, /* 158 */ - { 99, 24, 12, 0, 0, 28684, 56, }, /* 159 */ - { 29, 24, 12, 0, 0, 28672, 56, }, /* 160 */ - { 106, 12, 3, 0, 0, 26648, 98, }, /* 161 */ - { 106, 12, 3, 0, 0, 26652, 98, }, /* 162 */ - { 106, 12, 3, 0, 0, 26656, 98, }, /* 163 */ - { 106, 12, 3, 0, 0, 26660, 98, }, /* 164 */ - { 106, 12, 3, 0, 0, 26664, 98, }, /* 165 */ - { 106, 12, 3, 0, 0, 26668, 98, }, /* 166 */ - { 106, 12, 3, 0, 0, 26672, 98, }, /* 167 */ - { 106, 12, 3, 0, 0, 26676, 98, }, /* 168 */ - { 106, 12, 3, 0, 0, 26680, 98, }, /* 169 */ - { 106, 12, 3, 0, 0, 26684, 98, }, /* 170 */ - { 106, 12, 3, 0, 0, 26688, 98, }, /* 171 */ - { 106, 12, 3, 0, 0, 26692, 98, }, /* 172 */ - { 106, 12, 3, 0, 0, 26696, 98, }, /* 173 */ - { 106, 12, 3, 0, 0, 26700, 98, }, /* 174 */ - { 106, 12, 3, 0, 0, 26704, 98, }, /* 175 */ - { 106, 12, 3, 0, 0, 26624, 98, }, /* 176 */ - { 106, 12, 3, 0, 0, 26708, 98, }, /* 177 */ - { 106, 12, 3, 0, 0, 26712, 98, }, /* 178 */ - { 106, 12, 3, 0, 0, 26716, 98, }, /* 179 */ - { 106, 12, 3, 0, 0, 26720, 98, }, /* 180 */ - { 106, 12, 3, 0, 0, 26724, 98, }, /* 181 */ - { 106, 12, 3, 0, 0, 26728, 98, }, /* 182 */ - { 106, 12, 3, 0, 0, 26732, 98, }, /* 183 */ - { 106, 12, 3, 0, 0, 26736, 98, }, /* 184 */ - { 106, 12, 3, 0, 0, 26740, 98, }, /* 185 */ - { 106, 12, 3, 21, 116, 26740, 100, }, /* 186 */ - { 106, 12, 3, 0, 0, 26624, 102, }, /* 187 */ - { 106, 12, 3, 0, 0, 26744, 104, }, /* 188 */ - { 106, 12, 3, 0, 0, 26624, 104, }, /* 189 */ - { 106, 12, 3, 0, 0, 26748, 98, }, /* 190 */ - { 106, 12, 3, 0, 0, 26752, 106, }, /* 191 */ - { 1, 9, 12, 0, 1, 18432, 76, }, /* 192 */ - { 1, 5, 12, 0, -1, 18432, 78, }, /* 193 */ - { 99, 6, 12, 0, 0, 28804, 94, }, /* 194 */ - { 1, 24, 12, 0, 0, 28804, 56, }, /* 195 */ - { 98, 2, 12, 0, 0, 18432, 0, }, /* 196 */ - { 1, 6, 12, 0, 0, 18432, 108, }, /* 197 */ - { 1, 5, 12, 0, 130, 18432, 78, }, /* 198 */ - { 99, 21, 12, 0, 0, 28672, 110, }, /* 199 */ - { 1, 9, 12, 0, 116, 18432, 76, }, /* 200 */ - { 1, 24, 12, 0, 0, 28672, 56, }, /* 201 */ - { 1, 9, 12, 0, 38, 18432, 76, }, /* 202 */ - { 99, 21, 12, 0, 0, 28672, 112, }, /* 203 */ - { 1, 9, 12, 0, 37, 18432, 76, }, /* 204 */ - { 1, 9, 12, 0, 64, 18432, 76, }, /* 205 */ - { 1, 9, 12, 0, 63, 18432, 76, }, /* 206 */ - { 1, 5, 12, 0, 7235, 18432, 78, }, /* 207 */ - { 1, 9, 12, 0, 32, 18432, 76, }, /* 208 */ - { 1, 9, 12, 34, 32, 18432, 76, }, /* 209 */ - { 1, 9, 12, 59, 32, 18432, 76, }, /* 210 */ - { 1, 9, 12, 38, 32, 18432, 76, }, /* 211 */ - { 1, 9, 12, 21, 32, 18432, 76, }, /* 212 */ - { 1, 9, 12, 51, 32, 18432, 76, }, /* 213 */ - { 1, 9, 12, 26, 32, 18432, 76, }, /* 214 */ - { 1, 9, 12, 47, 32, 18432, 76, }, /* 215 */ - { 1, 9, 12, 55, 32, 18432, 76, }, /* 216 */ - { 1, 9, 12, 30, 32, 18432, 76, }, /* 217 */ - { 1, 9, 12, 43, 32, 18432, 76, }, /* 218 */ - { 1, 9, 12, 96, 32, 18432, 76, }, /* 219 */ - { 1, 5, 12, 0, -38, 18432, 78, }, /* 220 */ - { 1, 5, 12, 0, -37, 18432, 78, }, /* 221 */ - { 1, 5, 12, 0, 7219, 18432, 78, }, /* 222 */ - { 1, 5, 12, 0, -32, 18432, 78, }, /* 223 */ - { 1, 5, 12, 34, -32, 18432, 78, }, /* 224 */ - { 1, 5, 12, 59, -32, 18432, 78, }, /* 225 */ - { 1, 5, 12, 38, -32, 18432, 78, }, /* 226 */ - { 1, 5, 12, 21, -116, 18432, 78, }, /* 227 */ - { 1, 5, 12, 51, -32, 18432, 78, }, /* 228 */ - { 1, 5, 12, 26, -775, 18432, 78, }, /* 229 */ - { 1, 5, 12, 47, -32, 18432, 78, }, /* 230 */ - { 1, 5, 12, 55, -32, 18432, 78, }, /* 231 */ - { 1, 5, 12, 30, 1, 18432, 70, }, /* 232 */ - { 1, 5, 12, 30, -32, 18432, 78, }, /* 233 */ - { 1, 5, 12, 43, -32, 18432, 78, }, /* 234 */ - { 1, 5, 12, 96, -32, 18432, 78, }, /* 235 */ - { 1, 5, 12, 0, -64, 18432, 78, }, /* 236 */ - { 1, 5, 12, 0, -63, 18432, 78, }, /* 237 */ - { 1, 9, 12, 0, 8, 18432, 76, }, /* 238 */ - { 1, 5, 12, 34, -30, 18432, 114, }, /* 239 */ - { 1, 5, 12, 38, -25, 18432, 114, }, /* 240 */ - { 1, 9, 12, 0, 0, 18432, 116, }, /* 241 */ - { 1, 9, 12, 0, 0, 18432, 118, }, /* 242 */ - { 1, 5, 12, 43, -15, 18432, 114, }, /* 243 */ - { 1, 5, 12, 47, -22, 18432, 70, }, /* 244 */ - { 1, 5, 12, 0, -8, 18432, 78, }, /* 245 */ - { 43, 9, 12, 0, 1, 18432, 76, }, /* 246 */ - { 43, 5, 12, 0, -1, 18432, 78, }, /* 247 */ - { 1, 5, 12, 51, -54, 18432, 114, }, /* 248 */ - { 1, 5, 12, 55, -48, 18432, 114, }, /* 249 */ - { 1, 5, 12, 0, 7, 18432, 78, }, /* 250 */ - { 1, 5, 12, 0, -116, 18432, 80, }, /* 251 */ - { 1, 9, 12, 38, -60, 18432, 120, }, /* 252 */ - { 1, 5, 12, 59, -64, 18432, 114, }, /* 253 */ - { 1, 25, 12, 0, 0, 28672, 122, }, /* 254 */ - { 1, 9, 12, 0, -7, 18432, 76, }, /* 255 */ - { 1, 5, 12, 0, 0, 18432, 60, }, /* 256 */ - { 1, 9, 12, 0, -130, 18432, 76, }, /* 257 */ - { 2, 9, 12, 0, 80, 18432, 76, }, /* 258 */ - { 2, 9, 12, 0, 32, 18432, 76, }, /* 259 */ - { 2, 9, 12, 63, 32, 18432, 76, }, /* 260 */ - { 2, 9, 12, 67, 32, 18432, 76, }, /* 261 */ - { 2, 9, 12, 71, 32, 18432, 76, }, /* 262 */ - { 2, 9, 12, 75, 32, 18432, 76, }, /* 263 */ - { 2, 9, 12, 79, 32, 18432, 76, }, /* 264 */ - { 2, 9, 12, 84, 32, 18432, 76, }, /* 265 */ - { 2, 5, 12, 0, -32, 18432, 78, }, /* 266 */ - { 2, 5, 12, 63, -32, 18432, 78, }, /* 267 */ - { 2, 5, 12, 67, -32, 18432, 78, }, /* 268 */ - { 2, 5, 12, 71, -32, 18432, 78, }, /* 269 */ - { 2, 5, 12, 75, -32, 18432, 78, }, /* 270 */ - { 2, 5, 12, 79, -32, 18432, 78, }, /* 271 */ - { 2, 5, 12, 84, -32, 18432, 78, }, /* 272 */ - { 2, 5, 12, 0, -80, 18432, 78, }, /* 273 */ - { 2, 5, 12, 0, -80, 18432, 80, }, /* 274 */ - { 2, 9, 12, 0, 1, 18432, 76, }, /* 275 */ - { 2, 5, 12, 0, -1, 18432, 78, }, /* 276 */ - { 2, 9, 12, 88, 1, 18432, 76, }, /* 277 */ - { 2, 5, 12, 88, -1, 18432, 78, }, /* 278 */ - { 2, 26, 12, 0, 0, 18432, 74, }, /* 279 */ - { 2, 12, 3, 0, 0, 26760, 98, }, /* 280 */ - { 2, 12, 3, 0, 0, 26764, 98, }, /* 281 */ - { 106, 12, 3, 0, 0, 26768, 98, }, /* 282 */ - { 2, 11, 3, 0, 0, 26624, 124, }, /* 283 */ - { 2, 9, 12, 0, 15, 18432, 76, }, /* 284 */ - { 2, 5, 12, 0, -15, 18432, 78, }, /* 285 */ - { 3, 9, 12, 0, 48, 18432, 76, }, /* 286 */ - { 3, 6, 12, 0, 0, 18432, 94, }, /* 287 */ - { 3, 21, 12, 0, 0, 18432, 74, }, /* 288 */ - { 3, 21, 12, 0, 0, 18432, 126, }, /* 289 */ - { 3, 5, 12, 0, 0, 18432, 60, }, /* 290 */ - { 3, 5, 12, 0, -48, 18432, 78, }, /* 291 */ - { 3, 5, 12, 0, 0, 18432, 70, }, /* 292 */ - { 3, 21, 12, 0, 0, 18580, 128, }, /* 293 */ - { 3, 17, 12, 0, 0, 28672, 130, }, /* 294 */ - { 3, 26, 12, 0, 0, 28672, 74, }, /* 295 */ - { 3, 23, 12, 0, 0, 14336, 74, }, /* 296 */ - { 98, 2, 12, 0, 0, 34816, 0, }, /* 297 */ - { 4, 12, 3, 0, 0, 26624, 98, }, /* 298 */ - { 4, 12, 3, 0, 0, 26624, 104, }, /* 299 */ - { 4, 12, 3, 0, 0, 26624, 132, }, /* 300 */ - { 4, 17, 12, 0, 0, 34816, 130, }, /* 301 */ - { 4, 21, 12, 0, 0, 34816, 74, }, /* 302 */ - { 4, 21, 12, 0, 0, 34816, 110, }, /* 303 */ - { 4, 12, 3, 0, 0, 26624, 106, }, /* 304 */ - { 4, 7, 12, 0, 0, 34816, 84, }, /* 305 */ - { 4, 21, 12, 0, 0, 34816, 126, }, /* 306 */ - { 5, 1, 4, 0, 0, 2048, 134, }, /* 307 */ - { 99, 1, 4, 0, 0, 2048, 134, }, /* 308 */ - { 5, 25, 12, 0, 0, 28672, 122, }, /* 309 */ - { 5, 25, 12, 0, 0, 0, 122, }, /* 310 */ - { 5, 21, 12, 0, 0, 14336, 74, }, /* 311 */ - { 5, 23, 12, 0, 0, 0, 74, }, /* 312 */ - { 99, 21, 12, 0, 0, 8344, 110, }, /* 313 */ - { 5, 21, 12, 0, 0, 0, 74, }, /* 314 */ - { 5, 26, 12, 0, 0, 28672, 74, }, /* 315 */ - { 5, 12, 3, 0, 0, 26624, 106, }, /* 316 */ - { 99, 21, 12, 0, 0, 152, 110, }, /* 317 */ - { 5, 1, 2, 0, 0, 156, 136, }, /* 318 */ - { 5, 21, 12, 0, 0, 0, 128, }, /* 319 */ - { 99, 21, 12, 0, 0, 160, 128, }, /* 320 */ - { 5, 7, 12, 0, 0, 0, 84, }, /* 321 */ - { 99, 6, 12, 0, 0, 164, 138, }, /* 322 */ - { 106, 12, 3, 0, 0, 26792, 132, }, /* 323 */ - { 106, 12, 3, 0, 0, 26792, 106, }, /* 324 */ - { 106, 12, 3, 0, 0, 26792, 140, }, /* 325 */ - { 5, 12, 3, 0, 0, 26624, 132, }, /* 326 */ - { 5, 12, 3, 0, 0, 26624, 142, }, /* 327 */ - { 5, 13, 12, 0, 0, 2220, 144, }, /* 328 */ - { 5, 21, 12, 0, 0, 2048, 74, }, /* 329 */ - { 5, 7, 12, 0, 0, 0, 146, }, /* 330 */ - { 5, 21, 12, 0, 0, 176, 128, }, /* 331 */ - { 5, 12, 3, 0, 0, 26624, 140, }, /* 332 */ - { 5, 12, 3, 0, 0, 26624, 98, }, /* 333 */ - { 5, 6, 12, 0, 0, 0, 94, }, /* 334 */ - { 5, 13, 12, 0, 0, 10240, 144, }, /* 335 */ - { 5, 26, 12, 0, 0, 0, 74, }, /* 336 */ - { 6, 21, 12, 0, 0, 0, 128, }, /* 337 */ - { 6, 21, 12, 0, 0, 0, 110, }, /* 338 */ - { 6, 21, 12, 0, 0, 0, 74, }, /* 339 */ - { 98, 2, 12, 0, 0, 0, 0, }, /* 340 */ - { 6, 1, 4, 0, 0, 0, 134, }, /* 341 */ - { 6, 7, 12, 0, 0, 0, 84, }, /* 342 */ - { 6, 12, 3, 0, 0, 26624, 106, }, /* 343 */ - { 6, 12, 3, 0, 0, 26624, 132, }, /* 344 */ - { 6, 12, 3, 0, 0, 26624, 98, }, /* 345 */ - { 7, 7, 12, 0, 0, 0, 84, }, /* 346 */ - { 7, 12, 3, 0, 0, 26624, 132, }, /* 347 */ - { 48, 13, 12, 0, 0, 34816, 144, }, /* 348 */ - { 48, 7, 12, 0, 0, 34816, 84, }, /* 349 */ - { 48, 12, 3, 0, 0, 26624, 98, }, /* 350 */ - { 48, 6, 12, 0, 0, 34816, 94, }, /* 351 */ - { 48, 26, 12, 0, 0, 28672, 74, }, /* 352 */ - { 48, 21, 12, 0, 0, 28672, 74, }, /* 353 */ - { 48, 21, 12, 0, 0, 28672, 110, }, /* 354 */ - { 48, 21, 12, 0, 0, 28672, 128, }, /* 355 */ - { 48, 6, 12, 0, 0, 34816, 138, }, /* 356 */ - { 48, 12, 3, 0, 0, 26624, 104, }, /* 357 */ - { 48, 23, 12, 0, 0, 34816, 74, }, /* 358 */ - { 54, 7, 12, 0, 0, 34816, 84, }, /* 359 */ - { 54, 12, 3, 0, 0, 26624, 106, }, /* 360 */ - { 54, 12, 3, 0, 0, 26624, 98, }, /* 361 */ - { 54, 6, 12, 0, 0, 34816, 148, }, /* 362 */ - { 54, 12, 3, 0, 0, 26624, 104, }, /* 363 */ - { 54, 21, 12, 0, 0, 34816, 110, }, /* 364 */ - { 54, 21, 12, 0, 0, 34816, 74, }, /* 365 */ - { 54, 21, 12, 0, 0, 34816, 128, }, /* 366 */ - { 59, 7, 12, 0, 0, 34816, 84, }, /* 367 */ - { 59, 12, 3, 0, 0, 26624, 104, }, /* 368 */ - { 59, 21, 12, 0, 0, 34816, 110, }, /* 369 */ - { 5, 24, 12, 0, 0, 0, 126, }, /* 370 */ - { 5, 12, 3, 0, 0, 26624, 150, }, /* 371 */ - { 5, 12, 3, 0, 0, 26624, 104, }, /* 372 */ - { 5, 12, 3, 0, 0, 26624, 152, }, /* 373 */ - { 8, 12, 3, 0, 0, 26624, 106, }, /* 374 */ - { 8, 10, 5, 0, 0, 18432, 154, }, /* 375 */ - { 8, 7, 12, 0, 0, 18432, 84, }, /* 376 */ - { 8, 7, 12, 0, 0, 18432, 156, }, /* 377 */ - { 8, 12, 3, 0, 0, 26624, 98, }, /* 378 */ - { 8, 12, 3, 0, 0, 26624, 158, }, /* 379 */ - { 106, 12, 3, 0, 0, 26804, 98, }, /* 380 */ - { 106, 12, 3, 0, 0, 26808, 98, }, /* 381 */ - { 99, 21, 12, 0, 0, 18620, 128, }, /* 382 */ - { 99, 21, 12, 0, 0, 18624, 128, }, /* 383 */ - { 8, 13, 12, 0, 0, 18628, 144, }, /* 384 */ - { 8, 21, 12, 0, 0, 18432, 74, }, /* 385 */ - { 8, 6, 12, 0, 0, 18432, 94, }, /* 386 */ - { 9, 7, 12, 0, 0, 18432, 84, }, /* 387 */ - { 9, 12, 3, 0, 0, 26624, 106, }, /* 388 */ - { 9, 10, 5, 0, 0, 18432, 154, }, /* 389 */ - { 9, 7, 12, 0, 0, 18432, 156, }, /* 390 */ - { 9, 12, 3, 0, 0, 26624, 98, }, /* 391 */ - { 9, 10, 3, 0, 0, 18432, 160, }, /* 392 */ - { 9, 12, 3, 0, 0, 26624, 158, }, /* 393 */ - { 9, 13, 12, 0, 0, 18632, 144, }, /* 394 */ - { 9, 23, 12, 0, 0, 14336, 74, }, /* 395 */ - { 9, 15, 12, 0, 0, 18432, 74, }, /* 396 */ - { 9, 26, 12, 0, 0, 18432, 74, }, /* 397 */ - { 9, 21, 12, 0, 0, 18432, 74, }, /* 398 */ - { 9, 12, 3, 0, 0, 26624, 104, }, /* 399 */ - { 10, 12, 3, 0, 0, 26624, 106, }, /* 400 */ - { 10, 10, 5, 0, 0, 18432, 154, }, /* 401 */ - { 10, 7, 12, 0, 0, 18432, 84, }, /* 402 */ - { 10, 12, 3, 0, 0, 26624, 98, }, /* 403 */ - { 10, 12, 3, 0, 0, 26624, 158, }, /* 404 */ - { 10, 13, 12, 0, 0, 18636, 144, }, /* 405 */ - { 10, 12, 3, 0, 0, 26624, 162, }, /* 406 */ - { 10, 21, 12, 0, 0, 18432, 74, }, /* 407 */ - { 11, 12, 3, 0, 0, 26624, 106, }, /* 408 */ - { 11, 10, 5, 0, 0, 18432, 154, }, /* 409 */ - { 11, 7, 12, 0, 0, 18432, 84, }, /* 410 */ - { 11, 7, 12, 0, 0, 18432, 156, }, /* 411 */ - { 11, 12, 3, 0, 0, 26624, 98, }, /* 412 */ - { 11, 12, 3, 0, 0, 26624, 158, }, /* 413 */ - { 11, 13, 12, 0, 0, 18640, 144, }, /* 414 */ - { 11, 21, 12, 0, 0, 18432, 74, }, /* 415 */ - { 11, 23, 12, 0, 0, 14336, 74, }, /* 416 */ - { 11, 12, 3, 0, 0, 26624, 162, }, /* 417 */ - { 12, 12, 3, 0, 0, 26624, 106, }, /* 418 */ - { 12, 10, 5, 0, 0, 18432, 154, }, /* 419 */ - { 12, 7, 12, 0, 0, 18432, 84, }, /* 420 */ - { 12, 7, 12, 0, 0, 18432, 156, }, /* 421 */ - { 12, 12, 3, 0, 0, 26624, 98, }, /* 422 */ - { 12, 10, 3, 0, 0, 18432, 160, }, /* 423 */ - { 12, 12, 3, 0, 0, 26624, 158, }, /* 424 */ - { 12, 12, 3, 0, 0, 26624, 164, }, /* 425 */ - { 12, 13, 12, 0, 0, 18432, 144, }, /* 426 */ - { 12, 26, 12, 0, 0, 18432, 74, }, /* 427 */ - { 12, 15, 12, 0, 0, 18432, 74, }, /* 428 */ - { 13, 12, 3, 0, 0, 26624, 106, }, /* 429 */ - { 13, 7, 12, 0, 0, 18432, 84, }, /* 430 */ - { 13, 10, 3, 0, 0, 18432, 160, }, /* 431 */ - { 13, 10, 5, 0, 0, 18432, 154, }, /* 432 */ - { 13, 12, 3, 0, 0, 26624, 158, }, /* 433 */ - { 13, 13, 12, 0, 0, 18644, 144, }, /* 434 */ - { 13, 15, 12, 0, 0, 18644, 74, }, /* 435 */ - { 13, 26, 12, 0, 0, 28884, 74, }, /* 436 */ - { 13, 26, 12, 0, 0, 28672, 74, }, /* 437 */ - { 13, 23, 12, 0, 0, 14336, 74, }, /* 438 */ - { 14, 12, 3, 0, 0, 26624, 106, }, /* 439 */ - { 14, 10, 5, 0, 0, 18432, 154, }, /* 440 */ - { 14, 7, 12, 0, 0, 18432, 84, }, /* 441 */ - { 14, 7, 12, 0, 0, 18432, 156, }, /* 442 */ - { 14, 12, 3, 0, 0, 26624, 98, }, /* 443 */ - { 14, 12, 3, 0, 0, 26624, 158, }, /* 444 */ - { 14, 13, 12, 0, 0, 18432, 144, }, /* 445 */ - { 14, 21, 12, 0, 0, 18432, 74, }, /* 446 */ - { 14, 15, 12, 0, 0, 28672, 74, }, /* 447 */ - { 14, 26, 12, 0, 0, 18432, 74, }, /* 448 */ - { 15, 7, 12, 0, 0, 18432, 84, }, /* 449 */ - { 15, 12, 3, 0, 0, 26624, 106, }, /* 450 */ - { 15, 10, 5, 0, 0, 18432, 154, }, /* 451 */ - { 15, 21, 12, 0, 0, 18432, 74, }, /* 452 */ - { 15, 12, 3, 0, 0, 26624, 98, }, /* 453 */ - { 15, 12, 3, 0, 0, 18432, 106, }, /* 454 */ - { 15, 10, 3, 0, 0, 18432, 160, }, /* 455 */ - { 15, 12, 3, 0, 0, 26624, 158, }, /* 456 */ - { 15, 13, 12, 0, 0, 18648, 144, }, /* 457 */ - { 16, 12, 3, 0, 0, 26624, 106, }, /* 458 */ - { 16, 10, 5, 0, 0, 18432, 154, }, /* 459 */ - { 16, 7, 12, 0, 0, 18432, 84, }, /* 460 */ - { 16, 7, 12, 0, 0, 18432, 156, }, /* 461 */ - { 16, 12, 3, 0, 0, 26624, 158, }, /* 462 */ - { 16, 10, 3, 0, 0, 18432, 160, }, /* 463 */ - { 16, 7, 4, 0, 0, 18432, 84, }, /* 464 */ - { 16, 26, 12, 0, 0, 18432, 74, }, /* 465 */ - { 16, 15, 12, 0, 0, 18432, 74, }, /* 466 */ - { 16, 13, 12, 0, 0, 18432, 144, }, /* 467 */ - { 17, 12, 3, 0, 0, 26624, 106, }, /* 468 */ - { 17, 10, 5, 0, 0, 18432, 154, }, /* 469 */ - { 17, 7, 12, 0, 0, 18432, 84, }, /* 470 */ - { 17, 12, 3, 0, 0, 26624, 158, }, /* 471 */ - { 17, 10, 3, 0, 0, 18432, 160, }, /* 472 */ - { 17, 13, 12, 0, 0, 18432, 144, }, /* 473 */ - { 17, 21, 12, 0, 0, 18432, 74, }, /* 474 */ - { 18, 7, 12, 0, 0, 18432, 84, }, /* 475 */ - { 18, 12, 3, 0, 0, 26624, 106, }, /* 476 */ - { 18, 7, 5, 0, 0, 18432, 166, }, /* 477 */ - { 18, 12, 3, 0, 0, 26624, 168, }, /* 478 */ - { 99, 23, 12, 0, 0, 14336, 74, }, /* 479 */ - { 18, 7, 12, 0, 0, 18432, 170, }, /* 480 */ - { 18, 6, 12, 0, 0, 18432, 138, }, /* 481 */ - { 18, 12, 3, 0, 0, 26624, 98, }, /* 482 */ - { 18, 21, 12, 0, 0, 18432, 74, }, /* 483 */ - { 18, 13, 12, 0, 0, 18432, 144, }, /* 484 */ - { 18, 21, 12, 0, 0, 18432, 110, }, /* 485 */ - { 100, 7, 12, 0, 0, 18432, 84, }, /* 486 */ - { 100, 12, 3, 0, 0, 26624, 106, }, /* 487 */ - { 100, 7, 5, 0, 0, 18432, 166, }, /* 488 */ - { 100, 12, 3, 0, 0, 26624, 158, }, /* 489 */ - { 100, 7, 12, 0, 0, 18432, 170, }, /* 490 */ - { 100, 6, 12, 0, 0, 18432, 138, }, /* 491 */ - { 100, 12, 3, 0, 0, 26624, 98, }, /* 492 */ - { 100, 12, 3, 0, 0, 26624, 104, }, /* 493 */ - { 100, 13, 12, 0, 0, 18432, 144, }, /* 494 */ - { 19, 7, 12, 0, 0, 18432, 84, }, /* 495 */ - { 19, 26, 12, 0, 0, 18432, 74, }, /* 496 */ - { 19, 21, 12, 0, 0, 18432, 74, }, /* 497 */ - { 19, 21, 12, 0, 0, 18432, 110, }, /* 498 */ - { 19, 12, 3, 0, 0, 26624, 98, }, /* 499 */ - { 19, 13, 12, 0, 0, 18432, 144, }, /* 500 */ - { 19, 15, 12, 0, 0, 18432, 74, }, /* 501 */ - { 19, 22, 12, 0, 0, 28672, 172, }, /* 502 */ - { 19, 18, 12, 0, 0, 28672, 172, }, /* 503 */ - { 19, 10, 5, 0, 0, 18432, 174, }, /* 504 */ - { 19, 12, 3, 0, 0, 26624, 106, }, /* 505 */ - { 19, 12, 3, 0, 0, 26624, 176, }, /* 506 */ - { 19, 10, 5, 0, 0, 18432, 154, }, /* 507 */ - { 19, 12, 3, 0, 0, 26624, 132, }, /* 508 */ - { 19, 12, 3, 0, 0, 26624, 158, }, /* 509 */ - { 99, 26, 12, 0, 0, 18432, 74, }, /* 510 */ - { 20, 7, 12, 0, 0, 18432, 84, }, /* 511 */ - { 20, 10, 12, 0, 0, 18432, 154, }, /* 512 */ - { 20, 12, 3, 0, 0, 26624, 106, }, /* 513 */ - { 20, 10, 5, 0, 0, 18432, 154, }, /* 514 */ - { 20, 12, 3, 0, 0, 26624, 98, }, /* 515 */ - { 20, 12, 3, 0, 0, 26624, 158, }, /* 516 */ - { 20, 13, 12, 0, 0, 18652, 144, }, /* 517 */ - { 20, 21, 12, 0, 0, 18432, 128, }, /* 518 */ - { 20, 21, 12, 0, 0, 18432, 74, }, /* 519 */ - { 20, 10, 12, 0, 0, 18432, 178, }, /* 520 */ - { 20, 12, 3, 0, 0, 26624, 132, }, /* 521 */ - { 20, 13, 12, 0, 0, 18432, 144, }, /* 522 */ - { 20, 26, 12, 0, 0, 18432, 74, }, /* 523 */ - { 21, 9, 12, 0, 7264, 18432, 76, }, /* 524 */ - { 21, 5, 12, 0, 3008, 18432, 180, }, /* 525 */ - { 99, 21, 12, 0, 0, 18656, 74, }, /* 526 */ - { 21, 6, 12, 0, 0, 18432, 182, }, /* 527 */ - { 22, 7, 6, 0, 0, 18432, 84, }, /* 528 */ - { 22, 7, 6, 0, 0, 18432, 184, }, /* 529 */ - { 22, 7, 7, 0, 0, 18432, 184, }, /* 530 */ - { 22, 7, 7, 0, 0, 18432, 84, }, /* 531 */ - { 22, 7, 8, 0, 0, 18432, 84, }, /* 532 */ - { 23, 7, 12, 0, 0, 18432, 84, }, /* 533 */ - { 23, 12, 3, 0, 0, 26624, 98, }, /* 534 */ - { 23, 21, 12, 0, 0, 18432, 74, }, /* 535 */ - { 23, 21, 12, 0, 0, 18432, 110, }, /* 536 */ - { 23, 21, 12, 0, 0, 18432, 128, }, /* 537 */ - { 23, 15, 12, 0, 0, 18432, 144, }, /* 538 */ - { 23, 15, 12, 0, 0, 18432, 74, }, /* 539 */ - { 23, 26, 12, 0, 0, 28672, 74, }, /* 540 */ - { 24, 9, 12, 0, 38864, 18432, 186, }, /* 541 */ - { 24, 9, 12, 0, 8, 18432, 186, }, /* 542 */ - { 24, 5, 12, 0, -8, 18432, 70, }, /* 543 */ - { 101, 17, 12, 0, 0, 28672, 130, }, /* 544 */ - { 101, 7, 12, 0, 0, 18432, 84, }, /* 545 */ - { 101, 26, 12, 0, 0, 18432, 74, }, /* 546 */ - { 101, 21, 12, 0, 0, 18432, 128, }, /* 547 */ - { 102, 29, 12, 0, 0, 45056, 52, }, /* 548 */ - { 102, 7, 12, 0, 0, 18432, 84, }, /* 549 */ - { 102, 22, 12, 0, 0, 28672, 172, }, /* 550 */ - { 102, 18, 12, 0, 0, 28672, 172, }, /* 551 */ - { 25, 7, 12, 0, 0, 18432, 84, }, /* 552 */ - { 99, 21, 12, 0, 0, 18660, 110, }, /* 553 */ - { 25, 14, 12, 0, 0, 18432, 84, }, /* 554 */ - { 33, 7, 12, 0, 0, 18432, 84, }, /* 555 */ - { 33, 12, 3, 0, 0, 26624, 106, }, /* 556 */ - { 33, 12, 3, 0, 0, 26624, 158, }, /* 557 */ - { 33, 10, 3, 0, 0, 18432, 188, }, /* 558 */ - { 34, 7, 12, 0, 0, 18432, 84, }, /* 559 */ - { 34, 12, 3, 0, 0, 26624, 106, }, /* 560 */ - { 34, 10, 3, 0, 0, 18432, 188, }, /* 561 */ - { 99, 21, 12, 0, 0, 18664, 128, }, /* 562 */ - { 35, 7, 12, 0, 0, 18432, 84, }, /* 563 */ - { 35, 12, 3, 0, 0, 26624, 106, }, /* 564 */ - { 36, 7, 12, 0, 0, 18432, 84, }, /* 565 */ - { 36, 12, 3, 0, 0, 26624, 106, }, /* 566 */ - { 103, 7, 12, 0, 0, 18432, 84, }, /* 567 */ - { 103, 7, 12, 0, 0, 18432, 146, }, /* 568 */ - { 103, 12, 3, 0, 0, 26624, 102, }, /* 569 */ - { 103, 10, 5, 0, 0, 18432, 154, }, /* 570 */ - { 103, 12, 3, 0, 0, 26624, 106, }, /* 571 */ - { 103, 12, 3, 0, 0, 26624, 98, }, /* 572 */ - { 103, 12, 3, 0, 0, 26624, 158, }, /* 573 */ - { 103, 21, 12, 0, 0, 18432, 128, }, /* 574 */ - { 103, 21, 12, 0, 0, 18432, 110, }, /* 575 */ - { 103, 6, 12, 0, 0, 18432, 148, }, /* 576 */ - { 103, 21, 12, 0, 0, 18432, 74, }, /* 577 */ - { 103, 23, 12, 0, 0, 14336, 74, }, /* 578 */ - { 103, 13, 12, 0, 0, 18432, 144, }, /* 579 */ - { 103, 15, 12, 0, 0, 28672, 74, }, /* 580 */ - { 26, 21, 12, 0, 0, 28672, 74, }, /* 581 */ - { 99, 21, 12, 0, 0, 28908, 110, }, /* 582 */ - { 99, 21, 12, 0, 0, 28908, 128, }, /* 583 */ - { 26, 21, 12, 0, 0, 28672, 110, }, /* 584 */ - { 26, 17, 12, 0, 0, 28672, 130, }, /* 585 */ - { 26, 21, 12, 0, 0, 28672, 128, }, /* 586 */ - { 26, 21, 12, 0, 0, 28672, 190, }, /* 587 */ - { 26, 12, 3, 0, 0, 26624, 192, }, /* 588 */ - { 26, 1, 2, 0, 0, 6144, 66, }, /* 589 */ - { 26, 13, 12, 0, 0, 18432, 144, }, /* 590 */ - { 26, 7, 12, 0, 0, 18432, 84, }, /* 591 */ - { 26, 6, 12, 0, 0, 18432, 138, }, /* 592 */ - { 26, 12, 3, 0, 0, 26624, 194, }, /* 593 */ - { 26, 12, 3, 0, 0, 26624, 106, }, /* 594 */ - { 37, 7, 12, 0, 0, 18432, 84, }, /* 595 */ - { 37, 12, 3, 0, 0, 26624, 106, }, /* 596 */ - { 37, 10, 5, 0, 0, 18432, 154, }, /* 597 */ - { 37, 12, 3, 0, 0, 26624, 98, }, /* 598 */ - { 37, 26, 12, 0, 0, 28672, 74, }, /* 599 */ - { 37, 21, 12, 0, 0, 28672, 128, }, /* 600 */ - { 37, 13, 12, 0, 0, 18432, 144, }, /* 601 */ - { 38, 7, 12, 0, 0, 18432, 84, }, /* 602 */ - { 110, 7, 12, 0, 0, 18432, 84, }, /* 603 */ - { 110, 7, 12, 0, 0, 18432, 170, }, /* 604 */ - { 110, 13, 12, 0, 0, 18432, 144, }, /* 605 */ - { 110, 15, 12, 0, 0, 18432, 144, }, /* 606 */ - { 110, 26, 12, 0, 0, 28672, 74, }, /* 607 */ - { 103, 26, 12, 0, 0, 28672, 74, }, /* 608 */ - { 42, 7, 12, 0, 0, 18432, 84, }, /* 609 */ - { 42, 12, 3, 0, 0, 26624, 106, }, /* 610 */ - { 42, 10, 5, 0, 0, 18432, 154, }, /* 611 */ - { 42, 21, 12, 0, 0, 18432, 74, }, /* 612 */ - { 123, 7, 12, 0, 0, 18432, 84, }, /* 613 */ - { 123, 10, 5, 0, 0, 18432, 154, }, /* 614 */ - { 123, 12, 3, 0, 0, 26624, 106, }, /* 615 */ - { 123, 12, 3, 0, 0, 26624, 158, }, /* 616 */ - { 123, 10, 12, 0, 0, 18432, 154, }, /* 617 */ - { 123, 12, 3, 0, 0, 26624, 98, }, /* 618 */ - { 123, 13, 12, 0, 0, 18432, 144, }, /* 619 */ - { 123, 21, 12, 0, 0, 18432, 74, }, /* 620 */ - { 123, 6, 12, 0, 0, 18432, 138, }, /* 621 */ - { 123, 21, 12, 0, 0, 18432, 128, }, /* 622 */ - { 106, 11, 3, 0, 0, 26624, 196, }, /* 623 */ - { 106, 12, 3, 0, 0, 26624, 106, }, /* 624 */ - { 113, 12, 3, 0, 0, 26624, 106, }, /* 625 */ - { 113, 10, 5, 0, 0, 18432, 154, }, /* 626 */ - { 113, 7, 12, 0, 0, 18432, 84, }, /* 627 */ - { 113, 12, 3, 0, 0, 26624, 98, }, /* 628 */ - { 113, 10, 3, 0, 0, 18432, 160, }, /* 629 */ - { 113, 10, 3, 0, 0, 18432, 188, }, /* 630 */ - { 113, 21, 12, 0, 0, 18432, 128, }, /* 631 */ - { 113, 13, 12, 0, 0, 18432, 144, }, /* 632 */ - { 113, 21, 12, 0, 0, 18432, 74, }, /* 633 */ - { 113, 21, 12, 0, 0, 18432, 110, }, /* 634 */ - { 113, 26, 12, 0, 0, 18432, 74, }, /* 635 */ - { 116, 12, 3, 0, 0, 26624, 106, }, /* 636 */ - { 116, 10, 5, 0, 0, 18432, 154, }, /* 637 */ - { 116, 7, 12, 0, 0, 18432, 84, }, /* 638 */ - { 116, 10, 3, 0, 0, 18432, 188, }, /* 639 */ - { 116, 12, 3, 0, 0, 26624, 158, }, /* 640 */ - { 116, 13, 12, 0, 0, 18432, 144, }, /* 641 */ - { 132, 7, 12, 0, 0, 18432, 84, }, /* 642 */ - { 132, 12, 3, 0, 0, 26624, 98, }, /* 643 */ - { 132, 10, 5, 0, 0, 18432, 154, }, /* 644 */ - { 132, 12, 3, 0, 0, 26624, 106, }, /* 645 */ - { 132, 10, 3, 0, 0, 18432, 188, }, /* 646 */ - { 132, 21, 12, 0, 0, 18432, 74, }, /* 647 */ - { 117, 7, 12, 0, 0, 18432, 84, }, /* 648 */ - { 117, 10, 5, 0, 0, 18432, 154, }, /* 649 */ - { 117, 12, 3, 0, 0, 26624, 106, }, /* 650 */ - { 117, 12, 3, 0, 0, 26624, 198, }, /* 651 */ - { 117, 12, 3, 0, 0, 26624, 98, }, /* 652 */ - { 117, 21, 12, 0, 0, 18432, 128, }, /* 653 */ - { 117, 21, 12, 0, 0, 18432, 110, }, /* 654 */ - { 117, 13, 12, 0, 0, 18432, 144, }, /* 655 */ - { 118, 13, 12, 0, 0, 18432, 144, }, /* 656 */ - { 118, 7, 12, 0, 0, 18432, 84, }, /* 657 */ - { 118, 6, 12, 0, 0, 18432, 94, }, /* 658 */ - { 118, 6, 12, 0, 0, 18432, 96, }, /* 659 */ - { 118, 21, 12, 0, 0, 18432, 128, }, /* 660 */ - { 2, 5, 12, 63, -6222, 18432, 70, }, /* 661 */ - { 2, 5, 12, 67, -6221, 18432, 70, }, /* 662 */ - { 2, 5, 12, 71, -6212, 18432, 70, }, /* 663 */ - { 2, 5, 12, 75, -6210, 18432, 70, }, /* 664 */ - { 2, 5, 12, 79, -6210, 18432, 70, }, /* 665 */ - { 2, 5, 12, 79, -6211, 18432, 70, }, /* 666 */ - { 2, 5, 12, 84, -6204, 18432, 70, }, /* 667 */ - { 2, 5, 12, 88, -6180, 18432, 70, }, /* 668 */ - { 2, 5, 12, 108, 35267, 18432, 70, }, /* 669 */ - { 21, 9, 12, 0, -3008, 18432, 76, }, /* 670 */ - { 116, 21, 12, 0, 0, 18432, 74, }, /* 671 */ - { 106, 12, 3, 0, 0, 26864, 98, }, /* 672 */ - { 106, 12, 3, 0, 0, 26868, 98, }, /* 673 */ - { 99, 21, 12, 0, 0, 18680, 200, }, /* 674 */ - { 106, 12, 3, 0, 0, 26876, 98, }, /* 675 */ - { 106, 12, 3, 0, 0, 26880, 98, }, /* 676 */ - { 106, 12, 3, 0, 0, 26884, 98, }, /* 677 */ - { 99, 10, 5, 0, 0, 18684, 174, }, /* 678 */ - { 99, 7, 12, 0, 0, 18696, 84, }, /* 679 */ - { 99, 7, 12, 0, 0, 18684, 84, }, /* 680 */ - { 99, 7, 12, 0, 0, 18676, 84, }, /* 681 */ - { 99, 7, 12, 0, 0, 18700, 84, }, /* 682 */ - { 99, 7, 12, 0, 0, 18704, 84, }, /* 683 */ - { 106, 12, 3, 0, 0, 26900, 98, }, /* 684 */ - { 99, 10, 5, 0, 0, 18712, 174, }, /* 685 */ - { 106, 12, 3, 0, 0, 26896, 98, }, /* 686 */ - { 99, 7, 12, 0, 0, 18716, 84, }, /* 687 */ - { 2, 5, 12, 0, 0, 18432, 60, }, /* 688 */ - { 1, 6, 12, 0, 0, 18432, 90, }, /* 689 */ - { 2, 6, 12, 0, 0, 18432, 182, }, /* 690 */ - { 0, 5, 12, 0, 35332, 18432, 78, }, /* 691 */ - { 0, 5, 12, 0, 3814, 18432, 78, }, /* 692 */ - { 0, 5, 12, 0, 35384, 18432, 78, }, /* 693 */ - { 0, 5, 12, 0, 0, 18432, 202, }, /* 694 */ - { 0, 6, 12, 0, 0, 18432, 182, }, /* 695 */ - { 0, 6, 12, 0, 0, 18432, 204, }, /* 696 */ - { 1, 6, 12, 0, 0, 18432, 182, }, /* 697 */ - { 106, 12, 3, 0, 0, 26740, 104, }, /* 698 */ - { 106, 12, 3, 0, 0, 26912, 98, }, /* 699 */ - { 106, 12, 3, 0, 0, 26916, 98, }, /* 700 */ - { 0, 9, 12, 92, 1, 18432, 76, }, /* 701 */ - { 0, 5, 12, 92, -1, 18432, 78, }, /* 702 */ - { 0, 5, 12, 0, 0, 18432, 70, }, /* 703 */ - { 0, 5, 12, 92, -58, 18432, 70, }, /* 704 */ - { 0, 9, 12, 0, -7615, 18432, 76, }, /* 705 */ - { 1, 5, 12, 0, 8, 18432, 78, }, /* 706 */ - { 1, 9, 12, 0, -8, 18432, 76, }, /* 707 */ - { 1, 5, 12, 0, 0, 18432, 78, }, /* 708 */ - { 1, 5, 12, 0, 74, 18432, 78, }, /* 709 */ - { 1, 5, 12, 0, 86, 18432, 78, }, /* 710 */ - { 1, 5, 12, 0, 100, 18432, 78, }, /* 711 */ - { 1, 5, 12, 0, 128, 18432, 78, }, /* 712 */ - { 1, 5, 12, 0, 112, 18432, 78, }, /* 713 */ - { 1, 5, 12, 0, 126, 18432, 78, }, /* 714 */ - { 1, 5, 12, 0, 8, 18432, 70, }, /* 715 */ - { 1, 8, 12, 0, -8, 18432, 88, }, /* 716 */ - { 1, 5, 12, 0, 0, 18432, 70, }, /* 717 */ - { 1, 5, 12, 0, 9, 18432, 70, }, /* 718 */ - { 1, 9, 12, 0, -74, 18432, 76, }, /* 719 */ - { 1, 8, 12, 0, -9, 18432, 88, }, /* 720 */ - { 1, 5, 12, 21, -7173, 18432, 78, }, /* 721 */ - { 1, 9, 12, 0, -86, 18432, 76, }, /* 722 */ - { 1, 5, 12, 0, -7235, 18432, 78, }, /* 723 */ - { 1, 9, 12, 0, -100, 18432, 76, }, /* 724 */ - { 1, 5, 12, 0, -7219, 18432, 78, }, /* 725 */ - { 1, 9, 12, 0, -112, 18432, 76, }, /* 726 */ - { 1, 9, 12, 0, -128, 18432, 76, }, /* 727 */ - { 1, 9, 12, 0, -126, 18432, 76, }, /* 728 */ - { 99, 29, 12, 0, 0, 45056, 52, }, /* 729 */ - { 106, 1, 3, 0, 0, 6144, 206, }, /* 730 */ - { 106, 1, 13, 0, 0, 6144, 208, }, /* 731 */ - { 99, 1, 2, 0, 0, 18432, 210, }, /* 732 */ - { 99, 1, 2, 0, 0, 34816, 210, }, /* 733 */ - { 99, 17, 12, 0, 0, 28672, 212, }, /* 734 */ - { 99, 21, 12, 0, 0, 28672, 64, }, /* 735 */ - { 99, 20, 12, 0, 0, 28672, 214, }, /* 736 */ - { 99, 19, 12, 0, 0, 28672, 214, }, /* 737 */ - { 99, 22, 12, 0, 0, 28672, 216, }, /* 738 */ - { 99, 20, 12, 0, 0, 28672, 216, }, /* 739 */ - { 99, 19, 12, 0, 0, 28672, 216, }, /* 740 */ - { 99, 21, 12, 0, 0, 28672, 218, }, /* 741 */ - { 99, 21, 12, 0, 0, 28672, 220, }, /* 742 */ - { 99, 27, 2, 0, 0, 45056, 50, }, /* 743 */ - { 99, 28, 2, 0, 0, 4096, 50, }, /* 744 */ - { 99, 1, 2, 0, 0, 20480, 136, }, /* 745 */ - { 99, 1, 2, 0, 0, 36864, 136, }, /* 746 */ - { 99, 1, 2, 0, 0, 30720, 136, }, /* 747 */ - { 99, 1, 2, 0, 0, 24576, 136, }, /* 748 */ - { 99, 1, 2, 0, 0, 40960, 136, }, /* 749 */ - { 99, 29, 12, 0, 0, 8488, 52, }, /* 750 */ - { 99, 21, 12, 0, 0, 14336, 54, }, /* 751 */ - { 99, 21, 12, 0, 0, 14336, 64, }, /* 752 */ - { 99, 21, 14, 0, 0, 28672, 222, }, /* 753 */ - { 99, 21, 12, 0, 0, 28672, 224, }, /* 754 */ - { 99, 16, 12, 0, 0, 28672, 144, }, /* 755 */ - { 99, 16, 12, 0, 0, 28672, 226, }, /* 756 */ - { 99, 25, 12, 0, 0, 8192, 64, }, /* 757 */ - { 99, 22, 12, 0, 0, 28672, 228, }, /* 758 */ - { 99, 18, 12, 0, 0, 28672, 228, }, /* 759 */ - { 99, 21, 12, 0, 0, 28972, 54, }, /* 760 */ - { 99, 21, 12, 0, 0, 28672, 212, }, /* 761 */ - { 99, 21, 12, 0, 0, 28976, 54, }, /* 762 */ - { 99, 21, 12, 0, 0, 28980, 54, }, /* 763 */ - { 99, 1, 2, 0, 0, 6144, 230, }, /* 764 */ - { 98, 2, 2, 0, 0, 6144, 232, }, /* 765 */ - { 99, 1, 2, 0, 0, 22528, 136, }, /* 766 */ - { 99, 1, 2, 0, 0, 38912, 136, }, /* 767 */ - { 99, 1, 2, 0, 0, 16384, 136, }, /* 768 */ - { 99, 1, 2, 0, 0, 32768, 136, }, /* 769 */ - { 99, 1, 2, 0, 0, 6144, 234, }, /* 770 */ - { 99, 25, 12, 0, 0, 12288, 236, }, /* 771 */ - { 99, 25, 12, 0, 0, 12288, 238, }, /* 772 */ - { 99, 25, 12, 0, 0, 28672, 236, }, /* 773 */ - { 99, 22, 12, 0, 0, 28672, 240, }, /* 774 */ - { 99, 18, 12, 0, 0, 28672, 240, }, /* 775 */ - { 98, 2, 12, 0, 0, 14336, 0, }, /* 776 */ - { 106, 12, 3, 0, 0, 26624, 242, }, /* 777 */ - { 106, 11, 3, 0, 0, 26624, 124, }, /* 778 */ - { 106, 11, 3, 0, 0, 26624, 244, }, /* 779 */ - { 106, 12, 3, 0, 0, 26936, 104, }, /* 780 */ - { 99, 26, 12, 0, 0, 28672, 74, }, /* 781 */ - { 99, 9, 12, 0, 0, 18432, 116, }, /* 782 */ - { 99, 5, 12, 0, 0, 18432, 246, }, /* 783 */ - { 99, 25, 12, 0, 0, 28672, 248, }, /* 784 */ - { 99, 26, 14, 0, 0, 28672, 250, }, /* 785 */ - { 1, 9, 12, 96, -7517, 18432, 76, }, /* 786 */ - { 99, 26, 12, 0, 0, 28672, 122, }, /* 787 */ - { 0, 9, 12, 100, 0, 18432, 76, }, /* 788 */ - { 0, 9, 12, 104, -8262, 18432, 76, }, /* 789 */ - { 99, 26, 12, 0, 0, 14336, 252, }, /* 790 */ - { 0, 9, 12, 0, 28, 18432, 76, }, /* 791 */ - { 99, 7, 12, 0, 0, 18432, 254, }, /* 792 */ - { 99, 5, 14, 0, 0, 18432, 256, }, /* 793 */ - { 99, 25, 12, 0, 0, 28672, 122, }, /* 794 */ - { 99, 5, 12, 0, 0, 18432, 258, }, /* 795 */ - { 0, 5, 12, 0, -28, 18432, 78, }, /* 796 */ - { 0, 14, 12, 0, 16, 18432, 76, }, /* 797 */ - { 0, 14, 12, 0, -16, 18432, 78, }, /* 798 */ - { 0, 14, 12, 0, 0, 18432, 84, }, /* 799 */ - { 99, 25, 14, 0, 0, 28672, 260, }, /* 800 */ - { 99, 26, 14, 0, 0, 28672, 260, }, /* 801 */ - { 99, 26, 12, 0, 0, 28672, 64, }, /* 802 */ - { 99, 25, 12, 0, 0, 28672, 262, }, /* 803 */ - { 99, 25, 12, 0, 0, 28672, 264, }, /* 804 */ - { 99, 25, 12, 0, 0, 12288, 266, }, /* 805 */ - { 99, 22, 12, 0, 0, 28672, 264, }, /* 806 */ - { 99, 18, 12, 0, 0, 28672, 264, }, /* 807 */ - { 99, 26, 14, 0, 0, 28672, 268, }, /* 808 */ - { 99, 22, 12, 0, 0, 28672, 270, }, /* 809 */ - { 99, 18, 12, 0, 0, 28672, 270, }, /* 810 */ - { 99, 26, 12, 0, 0, 18432, 54, }, /* 811 */ - { 99, 26, 14, 0, 0, 28672, 272, }, /* 812 */ - { 98, 2, 12, 0, 0, 18432, 274, }, /* 813 */ - { 99, 15, 12, 0, 0, 10240, 74, }, /* 814 */ - { 99, 26, 12, 0, 26, 18432, 276, }, /* 815 */ - { 99, 26, 14, 0, 26, 18432, 278, }, /* 816 */ - { 99, 26, 12, 0, -26, 18432, 280, }, /* 817 */ - { 99, 25, 14, 0, 0, 28672, 282, }, /* 818 */ - { 99, 26, 14, 0, 0, 28672, 284, }, /* 819 */ - { 99, 26, 14, 0, 0, 28672, 286, }, /* 820 */ - { 99, 25, 14, 0, 0, 28672, 284, }, /* 821 */ - { 99, 26, 14, 0, 0, 18432, 272, }, /* 822 */ - { 99, 26, 14, 0, 0, 28672, 288, }, /* 823 */ - { 109, 26, 12, 0, 0, 18432, 54, }, /* 824 */ - { 99, 26, 12, 0, 0, 28672, 228, }, /* 825 */ - { 44, 9, 12, 0, 48, 18432, 76, }, /* 826 */ - { 44, 5, 12, 0, -48, 18432, 78, }, /* 827 */ - { 0, 9, 12, 0, -10743, 18432, 76, }, /* 828 */ - { 0, 9, 12, 0, -3814, 18432, 76, }, /* 829 */ - { 0, 9, 12, 0, -10727, 18432, 76, }, /* 830 */ - { 0, 5, 12, 0, -10795, 18432, 78, }, /* 831 */ - { 0, 5, 12, 0, -10792, 18432, 78, }, /* 832 */ - { 0, 9, 12, 0, -10780, 18432, 76, }, /* 833 */ - { 0, 9, 12, 0, -10749, 18432, 76, }, /* 834 */ - { 0, 9, 12, 0, -10783, 18432, 76, }, /* 835 */ - { 0, 9, 12, 0, -10782, 18432, 76, }, /* 836 */ - { 0, 9, 12, 0, -10815, 18432, 76, }, /* 837 */ - { 43, 5, 12, 0, 0, 18432, 60, }, /* 838 */ - { 43, 26, 12, 0, 0, 28672, 74, }, /* 839 */ - { 43, 12, 3, 0, 0, 26624, 98, }, /* 840 */ - { 43, 21, 12, 0, 0, 28672, 128, }, /* 841 */ - { 43, 21, 12, 0, 0, 28672, 74, }, /* 842 */ - { 43, 15, 12, 0, 0, 28672, 74, }, /* 843 */ - { 21, 5, 12, 0, -7264, 18432, 78, }, /* 844 */ - { 45, 7, 12, 0, 0, 18432, 84, }, /* 845 */ - { 45, 6, 12, 0, 0, 18432, 148, }, /* 846 */ - { 45, 21, 12, 0, 0, 18432, 74, }, /* 847 */ - { 45, 12, 3, 0, 0, 26624, 290, }, /* 848 */ - { 2, 12, 3, 0, 0, 26624, 106, }, /* 849 */ - { 99, 20, 12, 0, 0, 28672, 228, }, /* 850 */ - { 99, 19, 12, 0, 0, 28672, 228, }, /* 851 */ - { 99, 17, 12, 0, 0, 28988, 212, }, /* 852 */ - { 99, 6, 12, 0, 0, 28672, 292, }, /* 853 */ - { 99, 21, 12, 0, 0, 28992, 54, }, /* 854 */ - { 99, 21, 12, 0, 0, 28996, 54, }, /* 855 */ - { 99, 21, 12, 0, 0, 29000, 224, }, /* 856 */ - { 99, 21, 12, 0, 0, 29004, 294, }, /* 857 */ - { 99, 21, 12, 0, 0, 28812, 54, }, /* 858 */ - { 99, 21, 12, 0, 0, 28672, 294, }, /* 859 */ - { 30, 26, 12, 0, 0, 28672, 296, }, /* 860 */ - { 99, 26, 12, 0, 0, 29008, 298, }, /* 861 */ - { 99, 26, 12, 0, 0, 29008, 300, }, /* 862 */ - { 99, 26, 12, 0, 0, 29008, 302, }, /* 863 */ - { 99, 21, 12, 0, 0, 29012, 294, }, /* 864 */ - { 99, 21, 12, 0, 0, 29016, 224, }, /* 865 */ - { 99, 21, 12, 0, 0, 29020, 54, }, /* 866 */ - { 30, 6, 12, 0, 0, 18432, 138, }, /* 867 */ - { 99, 7, 12, 0, 0, 18784, 304, }, /* 868 */ - { 30, 14, 12, 0, 0, 18432, 304, }, /* 869 */ - { 99, 22, 12, 0, 0, 29028, 228, }, /* 870 */ - { 99, 18, 12, 0, 0, 29028, 228, }, /* 871 */ - { 99, 22, 12, 0, 0, 29032, 228, }, /* 872 */ - { 99, 18, 12, 0, 0, 29032, 228, }, /* 873 */ - { 99, 22, 12, 0, 0, 29036, 62, }, /* 874 */ - { 99, 18, 12, 0, 0, 29036, 62, }, /* 875 */ - { 99, 22, 12, 0, 0, 29036, 228, }, /* 876 */ - { 99, 18, 12, 0, 0, 29036, 228, }, /* 877 */ - { 99, 26, 12, 0, 0, 29020, 54, }, /* 878 */ - { 99, 17, 12, 0, 0, 29020, 212, }, /* 879 */ - { 99, 22, 12, 0, 0, 29020, 216, }, /* 880 */ - { 99, 18, 12, 0, 0, 29020, 216, }, /* 881 */ - { 106, 12, 3, 0, 0, 26992, 98, }, /* 882 */ - { 22, 10, 3, 0, 0, 18432, 306, }, /* 883 */ - { 99, 17, 14, 0, 0, 29020, 308, }, /* 884 */ - { 99, 6, 12, 0, 0, 18804, 138, }, /* 885 */ - { 99, 26, 12, 0, 0, 29020, 74, }, /* 886 */ - { 30, 6, 12, 0, 0, 18432, 148, }, /* 887 */ - { 99, 7, 12, 0, 0, 18808, 84, }, /* 888 */ - { 99, 21, 14, 0, 0, 29048, 250, }, /* 889 */ - { 99, 26, 12, 0, 0, 29024, 74, }, /* 890 */ - { 27, 7, 12, 0, 0, 18432, 84, }, /* 891 */ - { 106, 12, 3, 0, 0, 26996, 98, }, /* 892 */ - { 99, 24, 12, 0, 0, 29044, 310, }, /* 893 */ - { 27, 6, 12, 0, 0, 18432, 138, }, /* 894 */ - { 99, 17, 12, 0, 0, 29044, 130, }, /* 895 */ - { 28, 7, 12, 0, 0, 18432, 84, }, /* 896 */ - { 99, 21, 12, 0, 0, 29036, 144, }, /* 897 */ - { 99, 6, 12, 0, 0, 18804, 96, }, /* 898 */ - { 28, 6, 12, 0, 0, 18432, 138, }, /* 899 */ - { 29, 7, 12, 0, 0, 18432, 84, }, /* 900 */ - { 22, 7, 12, 0, 0, 18432, 84, }, /* 901 */ - { 22, 7, 12, 0, 0, 18432, 184, }, /* 902 */ - { 99, 26, 12, 0, 0, 18784, 74, }, /* 903 */ - { 99, 15, 12, 0, 0, 18784, 74, }, /* 904 */ - { 22, 26, 12, 0, 0, 18432, 74, }, /* 905 */ - { 22, 26, 12, 0, 0, 28672, 74, }, /* 906 */ - { 99, 15, 12, 0, 0, 18432, 74, }, /* 907 */ - { 99, 26, 14, 0, 0, 18784, 250, }, /* 908 */ - { 28, 26, 12, 0, 0, 18432, 74, }, /* 909 */ - { 30, 7, 12, 0, 0, 18432, 312, }, /* 910 */ - { 31, 7, 12, 0, 0, 18432, 84, }, /* 911 */ - { 31, 6, 12, 0, 0, 18432, 138, }, /* 912 */ - { 31, 26, 12, 0, 0, 28672, 74, }, /* 913 */ - { 55, 7, 12, 0, 0, 18432, 84, }, /* 914 */ - { 55, 6, 12, 0, 0, 18432, 148, }, /* 915 */ - { 55, 21, 12, 0, 0, 18432, 110, }, /* 916 */ - { 55, 21, 12, 0, 0, 18432, 128, }, /* 917 */ - { 119, 7, 12, 0, 0, 18432, 84, }, /* 918 */ - { 119, 6, 12, 0, 0, 18432, 138, }, /* 919 */ - { 119, 21, 12, 0, 0, 28672, 110, }, /* 920 */ - { 119, 21, 12, 0, 0, 28672, 128, }, /* 921 */ - { 119, 13, 12, 0, 0, 18432, 144, }, /* 922 */ - { 2, 9, 12, 108, 1, 18432, 76, }, /* 923 */ - { 2, 5, 12, 108, -35267, 18432, 78, }, /* 924 */ - { 2, 7, 12, 0, 0, 18432, 84, }, /* 925 */ - { 2, 21, 12, 0, 0, 28672, 74, }, /* 926 */ - { 2, 12, 3, 0, 0, 26624, 98, }, /* 927 */ - { 2, 6, 12, 0, 0, 28672, 94, }, /* 928 */ - { 2, 6, 12, 0, 0, 18432, 90, }, /* 929 */ - { 126, 7, 12, 0, 0, 18432, 84, }, /* 930 */ - { 126, 14, 12, 0, 0, 18432, 84, }, /* 931 */ - { 126, 12, 3, 0, 0, 26624, 98, }, /* 932 */ - { 126, 21, 12, 0, 0, 18432, 74, }, /* 933 */ - { 126, 21, 12, 0, 0, 18432, 128, }, /* 934 */ - { 126, 21, 12, 0, 0, 18432, 110, }, /* 935 */ - { 99, 24, 12, 0, 0, 29052, 56, }, /* 936 */ - { 0, 9, 12, 0, -35332, 18432, 76, }, /* 937 */ - { 99, 24, 12, 0, 0, 18432, 56, }, /* 938 */ - { 0, 9, 12, 0, -42280, 18432, 76, }, /* 939 */ - { 0, 5, 12, 0, 48, 18432, 78, }, /* 940 */ - { 0, 9, 12, 0, -42308, 18432, 76, }, /* 941 */ - { 0, 9, 12, 0, -42319, 18432, 76, }, /* 942 */ - { 0, 9, 12, 0, -42315, 18432, 76, }, /* 943 */ - { 0, 9, 12, 0, -42305, 18432, 76, }, /* 944 */ - { 0, 9, 12, 0, -42258, 18432, 76, }, /* 945 */ - { 0, 9, 12, 0, -42282, 18432, 76, }, /* 946 */ - { 0, 9, 12, 0, -42261, 18432, 76, }, /* 947 */ - { 0, 9, 12, 0, 928, 18432, 76, }, /* 948 */ - { 0, 9, 12, 0, -48, 18432, 76, }, /* 949 */ - { 0, 9, 12, 0, -42307, 18432, 76, }, /* 950 */ - { 0, 9, 12, 0, -35384, 18432, 76, }, /* 951 */ - { 0, 9, 12, 0, -42343, 18432, 76, }, /* 952 */ - { 0, 9, 12, 0, -42561, 18432, 76, }, /* 953 */ - { 46, 7, 12, 0, 0, 18432, 84, }, /* 954 */ - { 46, 12, 3, 0, 0, 26624, 106, }, /* 955 */ - { 46, 12, 3, 0, 0, 26624, 158, }, /* 956 */ - { 46, 10, 5, 0, 0, 18432, 154, }, /* 957 */ - { 46, 26, 12, 0, 0, 28672, 74, }, /* 958 */ - { 99, 15, 12, 0, 0, 18816, 74, }, /* 959 */ - { 99, 15, 12, 0, 0, 18820, 74, }, /* 960 */ - { 99, 26, 12, 0, 0, 18824, 74, }, /* 961 */ - { 99, 23, 12, 0, 0, 14732, 74, }, /* 962 */ - { 99, 26, 12, 0, 0, 14728, 74, }, /* 963 */ - { 47, 7, 12, 0, 0, 18432, 84, }, /* 964 */ - { 47, 21, 12, 0, 0, 28672, 74, }, /* 965 */ - { 47, 21, 12, 0, 0, 28672, 128, }, /* 966 */ - { 120, 10, 5, 0, 0, 18432, 154, }, /* 967 */ - { 120, 7, 12, 0, 0, 18432, 84, }, /* 968 */ - { 120, 12, 3, 0, 0, 26624, 158, }, /* 969 */ - { 120, 12, 3, 0, 0, 26624, 106, }, /* 970 */ - { 120, 21, 12, 0, 0, 18432, 128, }, /* 971 */ - { 120, 13, 12, 0, 0, 18432, 144, }, /* 972 */ - { 8, 12, 3, 0, 0, 27024, 98, }, /* 973 */ - { 8, 7, 12, 0, 0, 18836, 84, }, /* 974 */ - { 49, 13, 12, 0, 0, 18432, 144, }, /* 975 */ - { 49, 7, 12, 0, 0, 18432, 84, }, /* 976 */ - { 49, 12, 3, 0, 0, 26624, 106, }, /* 977 */ - { 49, 12, 3, 0, 0, 26624, 98, }, /* 978 */ - { 99, 21, 12, 0, 0, 18840, 200, }, /* 979 */ - { 49, 21, 12, 0, 0, 18432, 128, }, /* 980 */ - { 121, 7, 12, 0, 0, 18432, 84, }, /* 981 */ - { 121, 12, 3, 0, 0, 26624, 106, }, /* 982 */ - { 121, 10, 5, 0, 0, 18432, 154, }, /* 983 */ - { 121, 10, 3, 0, 0, 18432, 188, }, /* 984 */ - { 121, 21, 12, 0, 0, 18432, 74, }, /* 985 */ - { 56, 12, 3, 0, 0, 26624, 106, }, /* 986 */ - { 56, 10, 5, 0, 0, 18432, 154, }, /* 987 */ - { 56, 7, 12, 0, 0, 18432, 84, }, /* 988 */ - { 56, 12, 3, 0, 0, 26624, 98, }, /* 989 */ - { 56, 10, 3, 0, 0, 18432, 188, }, /* 990 */ - { 56, 21, 12, 0, 0, 18432, 74, }, /* 991 */ - { 56, 21, 12, 0, 0, 18432, 110, }, /* 992 */ - { 56, 21, 12, 0, 0, 18432, 128, }, /* 993 */ - { 99, 6, 12, 0, 0, 18844, 138, }, /* 994 */ - { 56, 13, 12, 0, 0, 18432, 144, }, /* 995 */ - { 20, 6, 12, 0, 0, 18432, 138, }, /* 996 */ - { 122, 7, 12, 0, 0, 18432, 84, }, /* 997 */ - { 122, 12, 3, 0, 0, 26624, 106, }, /* 998 */ - { 122, 10, 5, 0, 0, 18432, 154, }, /* 999 */ - { 122, 13, 12, 0, 0, 18432, 144, }, /* 1000 */ - { 122, 21, 12, 0, 0, 18432, 74, }, /* 1001 */ - { 122, 21, 12, 0, 0, 18432, 128, }, /* 1002 */ - { 124, 7, 12, 0, 0, 18432, 84, }, /* 1003 */ - { 124, 12, 3, 0, 0, 26624, 106, }, /* 1004 */ - { 124, 7, 12, 0, 0, 18432, 170, }, /* 1005 */ - { 124, 12, 3, 0, 0, 26624, 98, }, /* 1006 */ - { 124, 7, 12, 0, 0, 18432, 314, }, /* 1007 */ - { 124, 6, 12, 0, 0, 18432, 138, }, /* 1008 */ - { 124, 21, 12, 0, 0, 18432, 74, }, /* 1009 */ - { 124, 21, 12, 0, 0, 18432, 110, }, /* 1010 */ - { 127, 7, 12, 0, 0, 18432, 84, }, /* 1011 */ - { 127, 10, 5, 0, 0, 18432, 154, }, /* 1012 */ - { 127, 12, 3, 0, 0, 26624, 106, }, /* 1013 */ - { 127, 21, 12, 0, 0, 18432, 128, }, /* 1014 */ - { 127, 6, 12, 0, 0, 18432, 138, }, /* 1015 */ - { 127, 12, 3, 0, 0, 26624, 158, }, /* 1016 */ - { 0, 5, 12, 0, -928, 18432, 78, }, /* 1017 */ - { 24, 5, 12, 0, -38864, 18432, 70, }, /* 1018 */ - { 127, 10, 5, 0, 0, 18432, 174, }, /* 1019 */ - { 127, 13, 12, 0, 0, 18432, 144, }, /* 1020 */ - { 22, 7, 9, 0, 0, 18432, 84, }, /* 1021 */ - { 22, 7, 10, 0, 0, 18432, 84, }, /* 1022 */ - { 98, 4, 12, 0, 0, 18432, 0, }, /* 1023 */ - { 98, 3, 12, 0, 0, 18432, 0, }, /* 1024 */ - { 30, 7, 12, 0, 0, 18432, 304, }, /* 1025 */ - { 0, 5, 12, 0, 1, 18432, 70, }, /* 1026 */ - { 0, 5, 12, 0, -1, 18432, 70, }, /* 1027 */ - { 4, 25, 12, 0, 0, 12288, 122, }, /* 1028 */ - { 5, 7, 12, 0, 0, 0, 316, }, /* 1029 */ - { 99, 18, 12, 0, 0, 29088, 54, }, /* 1030 */ - { 99, 22, 12, 0, 0, 29088, 54, }, /* 1031 */ - { 98, 2, 12, 0, 0, 6144, 318, }, /* 1032 */ - { 5, 7, 12, 0, 0, 420, 84, }, /* 1033 */ - { 5, 26, 12, 0, 0, 29092, 74, }, /* 1034 */ - { 106, 12, 3, 0, 0, 26624, 192, }, /* 1035 */ - { 106, 12, 3, 0, 0, 26624, 320, }, /* 1036 */ - { 99, 21, 12, 0, 0, 28672, 74, }, /* 1037 */ - { 99, 21, 12, 0, 0, 28672, 128, }, /* 1038 */ - { 99, 21, 12, 0, 0, 28672, 126, }, /* 1039 */ - { 99, 22, 12, 0, 0, 28672, 74, }, /* 1040 */ - { 99, 18, 12, 0, 0, 28672, 74, }, /* 1041 */ - { 99, 17, 12, 0, 0, 28672, 130, }, /* 1042 */ - { 99, 22, 12, 0, 0, 28672, 322, }, /* 1043 */ - { 99, 18, 12, 0, 0, 28672, 322, }, /* 1044 */ - { 99, 21, 12, 0, 0, 8192, 110, }, /* 1045 */ - { 99, 21, 12, 0, 0, 8192, 324, }, /* 1046 */ - { 99, 21, 12, 0, 0, 8192, 326, }, /* 1047 */ - { 99, 22, 12, 0, 0, 28672, 172, }, /* 1048 */ - { 99, 18, 12, 0, 0, 28672, 172, }, /* 1049 */ - { 99, 21, 12, 0, 0, 14336, 74, }, /* 1050 */ - { 99, 21, 12, 0, 0, 28672, 122, }, /* 1051 */ - { 99, 25, 12, 0, 0, 12288, 122, }, /* 1052 */ - { 99, 17, 12, 0, 0, 12288, 328, }, /* 1053 */ - { 99, 25, 12, 0, 0, 28672, 330, }, /* 1054 */ - { 99, 21, 12, 0, 0, 28672, 322, }, /* 1055 */ - { 99, 21, 12, 0, 0, 28672, 332, }, /* 1056 */ - { 99, 17, 12, 0, 0, 12288, 130, }, /* 1057 */ - { 99, 21, 12, 0, 0, 8192, 74, }, /* 1058 */ - { 99, 13, 12, 0, 0, 10240, 334, }, /* 1059 */ - { 0, 9, 12, 0, 32, 18432, 336, }, /* 1060 */ - { 99, 24, 12, 0, 0, 28672, 338, }, /* 1061 */ - { 0, 5, 12, 0, -32, 18432, 340, }, /* 1062 */ - { 99, 21, 12, 0, 0, 29036, 128, }, /* 1063 */ - { 99, 22, 12, 0, 0, 29036, 342, }, /* 1064 */ - { 99, 18, 12, 0, 0, 29036, 342, }, /* 1065 */ - { 99, 21, 12, 0, 0, 29036, 110, }, /* 1066 */ - { 99, 6, 3, 0, 0, 18804, 344, }, /* 1067 */ - { 99, 1, 2, 0, 0, 28672, 346, }, /* 1068 */ - { 39, 7, 12, 0, 0, 18432, 84, }, /* 1069 */ - { 99, 21, 12, 0, 0, 18856, 74, }, /* 1070 */ - { 99, 21, 12, 0, 0, 29096, 74, }, /* 1071 */ - { 99, 21, 12, 0, 0, 18860, 74, }, /* 1072 */ - { 99, 15, 12, 0, 0, 18864, 74, }, /* 1073 */ - { 99, 26, 12, 0, 0, 18860, 74, }, /* 1074 */ - { 1, 14, 12, 0, 0, 28672, 84, }, /* 1075 */ - { 1, 15, 12, 0, 0, 28672, 74, }, /* 1076 */ - { 1, 26, 12, 0, 0, 28672, 74, }, /* 1077 */ - { 1, 26, 12, 0, 0, 18432, 74, }, /* 1078 */ - { 50, 7, 12, 0, 0, 18432, 84, }, /* 1079 */ - { 51, 7, 12, 0, 0, 18432, 84, }, /* 1080 */ - { 106, 12, 3, 0, 0, 27060, 98, }, /* 1081 */ - { 99, 15, 12, 0, 0, 10676, 74, }, /* 1082 */ - { 104, 7, 12, 0, 0, 18432, 84, }, /* 1083 */ - { 104, 15, 12, 0, 0, 18432, 74, }, /* 1084 */ - { 32, 7, 12, 0, 0, 18432, 84, }, /* 1085 */ - { 32, 14, 12, 0, 0, 18432, 84, }, /* 1086 */ - { 73, 7, 12, 0, 0, 18432, 84, }, /* 1087 */ - { 73, 12, 3, 0, 0, 26624, 106, }, /* 1088 */ - { 107, 7, 12, 0, 0, 18432, 84, }, /* 1089 */ - { 107, 21, 12, 0, 0, 18432, 110, }, /* 1090 */ - { 111, 7, 12, 0, 0, 18432, 84, }, /* 1091 */ - { 111, 21, 12, 0, 0, 18432, 110, }, /* 1092 */ - { 111, 14, 12, 0, 0, 18432, 84, }, /* 1093 */ - { 105, 9, 12, 0, 40, 18432, 76, }, /* 1094 */ - { 105, 5, 12, 0, -40, 18432, 78, }, /* 1095 */ - { 40, 7, 12, 0, 0, 18432, 84, }, /* 1096 */ - { 108, 7, 12, 0, 0, 18432, 84, }, /* 1097 */ - { 108, 13, 12, 0, 0, 18432, 144, }, /* 1098 */ - { 80, 9, 12, 0, 40, 18432, 76, }, /* 1099 */ - { 80, 5, 12, 0, -40, 18432, 78, }, /* 1100 */ - { 66, 7, 12, 0, 0, 18432, 84, }, /* 1101 */ - { 64, 7, 12, 0, 0, 18432, 84, }, /* 1102 */ - { 64, 21, 12, 0, 0, 18432, 74, }, /* 1103 */ - { 167, 9, 12, 0, 39, 18432, 76, }, /* 1104 */ - { 167, 5, 12, 0, -39, 18432, 78, }, /* 1105 */ - { 96, 7, 12, 0, 0, 18432, 84, }, /* 1106 */ - { 69, 7, 12, 0, 0, 18432, 84, }, /* 1107 */ - { 0, 6, 12, 0, 0, 18432, 96, }, /* 1108 */ - { 41, 7, 12, 0, 0, 34816, 84, }, /* 1109 */ - { 128, 7, 12, 0, 0, 34816, 84, }, /* 1110 */ - { 128, 21, 12, 0, 0, 34816, 110, }, /* 1111 */ - { 128, 15, 12, 0, 0, 34816, 74, }, /* 1112 */ - { 143, 7, 12, 0, 0, 34816, 84, }, /* 1113 */ - { 143, 26, 12, 0, 0, 34816, 74, }, /* 1114 */ - { 143, 15, 12, 0, 0, 34816, 74, }, /* 1115 */ - { 142, 7, 12, 0, 0, 34816, 84, }, /* 1116 */ - { 142, 15, 12, 0, 0, 34816, 74, }, /* 1117 */ - { 149, 7, 12, 0, 0, 34816, 84, }, /* 1118 */ - { 149, 15, 12, 0, 0, 34816, 74, }, /* 1119 */ - { 115, 7, 12, 0, 0, 34816, 84, }, /* 1120 */ - { 115, 15, 12, 0, 0, 34816, 74, }, /* 1121 */ - { 115, 21, 12, 0, 0, 28672, 110, }, /* 1122 */ - { 52, 7, 12, 0, 0, 34816, 84, }, /* 1123 */ - { 52, 21, 12, 0, 0, 34816, 74, }, /* 1124 */ - { 61, 7, 12, 0, 0, 34816, 84, }, /* 1125 */ - { 134, 7, 12, 0, 0, 34816, 84, }, /* 1126 */ - { 134, 15, 12, 0, 0, 34816, 74, }, /* 1127 */ - { 112, 7, 12, 0, 0, 34816, 84, }, /* 1128 */ - { 112, 12, 3, 0, 0, 26624, 106, }, /* 1129 */ - { 112, 12, 3, 0, 0, 26624, 98, }, /* 1130 */ - { 112, 12, 3, 0, 0, 26624, 158, }, /* 1131 */ - { 112, 15, 12, 0, 0, 34816, 74, }, /* 1132 */ - { 112, 21, 12, 0, 0, 34816, 74, }, /* 1133 */ - { 112, 21, 12, 0, 0, 34816, 128, }, /* 1134 */ - { 129, 7, 12, 0, 0, 34816, 84, }, /* 1135 */ - { 129, 15, 12, 0, 0, 34816, 74, }, /* 1136 */ - { 129, 21, 12, 0, 0, 34816, 74, }, /* 1137 */ - { 141, 7, 12, 0, 0, 34816, 84, }, /* 1138 */ - { 141, 15, 12, 0, 0, 34816, 74, }, /* 1139 */ - { 71, 7, 12, 0, 0, 34816, 84, }, /* 1140 */ - { 71, 26, 12, 0, 0, 34816, 74, }, /* 1141 */ - { 71, 12, 3, 0, 0, 26624, 98, }, /* 1142 */ - { 71, 15, 12, 0, 0, 34816, 74, }, /* 1143 */ - { 71, 21, 12, 0, 0, 34816, 110, }, /* 1144 */ - { 71, 21, 12, 0, 0, 35256, 110, }, /* 1145 */ - { 71, 21, 12, 0, 0, 34816, 74, }, /* 1146 */ - { 53, 7, 12, 0, 0, 34816, 84, }, /* 1147 */ - { 53, 21, 12, 0, 0, 28672, 74, }, /* 1148 */ - { 53, 21, 12, 0, 0, 28672, 110, }, /* 1149 */ - { 130, 7, 12, 0, 0, 34816, 84, }, /* 1150 */ - { 130, 15, 12, 0, 0, 34816, 74, }, /* 1151 */ - { 131, 7, 12, 0, 0, 34816, 84, }, /* 1152 */ - { 131, 15, 12, 0, 0, 34816, 74, }, /* 1153 */ - { 74, 7, 12, 0, 0, 34816, 84, }, /* 1154 */ - { 74, 21, 12, 0, 0, 34816, 110, }, /* 1155 */ - { 74, 15, 12, 0, 0, 34816, 74, }, /* 1156 */ - { 57, 7, 12, 0, 0, 34816, 84, }, /* 1157 */ - { 78, 9, 12, 0, 64, 34816, 76, }, /* 1158 */ - { 78, 5, 12, 0, -64, 34816, 78, }, /* 1159 */ - { 78, 15, 12, 0, 0, 34816, 74, }, /* 1160 */ - { 85, 7, 12, 0, 0, 0, 84, }, /* 1161 */ - { 85, 7, 12, 0, 0, 0, 314, }, /* 1162 */ - { 85, 12, 3, 0, 0, 26624, 132, }, /* 1163 */ - { 85, 13, 12, 0, 0, 2048, 144, }, /* 1164 */ - { 92, 13, 12, 0, 0, 2048, 144, }, /* 1165 */ - { 92, 7, 12, 0, 0, 34816, 84, }, /* 1166 */ - { 92, 6, 12, 0, 0, 34816, 96, }, /* 1167 */ - { 92, 9, 12, 0, 32, 34816, 76, }, /* 1168 */ - { 92, 12, 3, 0, 0, 26624, 132, }, /* 1169 */ - { 92, 12, 3, 0, 0, 26624, 164, }, /* 1170 */ - { 92, 12, 3, 0, 0, 26624, 98, }, /* 1171 */ - { 92, 17, 12, 0, 0, 28672, 130, }, /* 1172 */ - { 92, 6, 12, 0, 0, 34816, 138, }, /* 1173 */ - { 92, 5, 12, 0, -32, 34816, 78, }, /* 1174 */ - { 92, 25, 12, 0, 0, 34816, 122, }, /* 1175 */ - { 5, 15, 12, 0, 0, 2048, 74, }, /* 1176 */ - { 88, 7, 12, 0, 0, 34816, 84, }, /* 1177 */ - { 88, 12, 3, 0, 0, 26624, 106, }, /* 1178 */ - { 88, 17, 12, 0, 0, 34816, 130, }, /* 1179 */ - { 159, 7, 12, 0, 0, 34816, 84, }, /* 1180 */ - { 159, 15, 12, 0, 0, 34816, 74, }, /* 1181 */ - { 86, 7, 12, 0, 0, 0, 84, }, /* 1182 */ - { 86, 12, 3, 0, 0, 26624, 98, }, /* 1183 */ - { 86, 15, 12, 0, 0, 0, 74, }, /* 1184 */ - { 86, 21, 12, 0, 0, 0, 128, }, /* 1185 */ - { 90, 7, 12, 0, 0, 34816, 84, }, /* 1186 */ - { 90, 12, 3, 0, 0, 26624, 98, }, /* 1187 */ - { 90, 21, 12, 0, 0, 34816, 128, }, /* 1188 */ - { 163, 7, 12, 0, 0, 34816, 84, }, /* 1189 */ - { 163, 15, 12, 0, 0, 34816, 74, }, /* 1190 */ - { 160, 7, 12, 0, 0, 34816, 84, }, /* 1191 */ - { 133, 10, 5, 0, 0, 18432, 154, }, /* 1192 */ - { 133, 12, 3, 0, 0, 26624, 106, }, /* 1193 */ - { 133, 7, 12, 0, 0, 18432, 84, }, /* 1194 */ - { 133, 12, 3, 0, 0, 26624, 158, }, /* 1195 */ - { 133, 21, 12, 0, 0, 18432, 128, }, /* 1196 */ - { 133, 21, 12, 0, 0, 18432, 110, }, /* 1197 */ - { 133, 15, 12, 0, 0, 28672, 74, }, /* 1198 */ - { 133, 13, 12, 0, 0, 18432, 144, }, /* 1199 */ - { 133, 12, 3, 0, 0, 26624, 290, }, /* 1200 */ - { 58, 12, 3, 0, 0, 26624, 106, }, /* 1201 */ - { 58, 10, 5, 0, 0, 18432, 154, }, /* 1202 */ - { 58, 7, 12, 0, 0, 18432, 84, }, /* 1203 */ - { 58, 12, 3, 0, 0, 26624, 158, }, /* 1204 */ - { 58, 12, 3, 0, 0, 26624, 98, }, /* 1205 */ - { 58, 21, 12, 0, 0, 18432, 74, }, /* 1206 */ - { 58, 1, 4, 0, 0, 18432, 134, }, /* 1207 */ - { 58, 21, 12, 0, 0, 18432, 128, }, /* 1208 */ - { 136, 7, 12, 0, 0, 18432, 84, }, /* 1209 */ - { 136, 13, 12, 0, 0, 18432, 144, }, /* 1210 */ - { 60, 12, 3, 0, 0, 26624, 106, }, /* 1211 */ - { 60, 7, 12, 0, 0, 18432, 84, }, /* 1212 */ - { 60, 10, 5, 0, 0, 18432, 154, }, /* 1213 */ - { 60, 12, 3, 0, 0, 26624, 158, }, /* 1214 */ - { 60, 13, 12, 0, 0, 18432, 144, }, /* 1215 */ - { 60, 21, 12, 0, 0, 18432, 74, }, /* 1216 */ - { 60, 21, 12, 0, 0, 18432, 128, }, /* 1217 */ - { 70, 7, 12, 0, 0, 18432, 84, }, /* 1218 */ - { 70, 12, 3, 0, 0, 26624, 98, }, /* 1219 */ - { 70, 21, 12, 0, 0, 18432, 74, }, /* 1220 */ - { 62, 12, 3, 0, 0, 26624, 106, }, /* 1221 */ - { 62, 10, 5, 0, 0, 18432, 154, }, /* 1222 */ - { 62, 7, 12, 0, 0, 18432, 84, }, /* 1223 */ - { 62, 10, 3, 0, 0, 18432, 188, }, /* 1224 */ - { 62, 7, 4, 0, 0, 18432, 84, }, /* 1225 */ - { 62, 21, 12, 0, 0, 18432, 128, }, /* 1226 */ - { 62, 21, 12, 0, 0, 18432, 74, }, /* 1227 */ - { 62, 12, 3, 0, 0, 26624, 104, }, /* 1228 */ - { 62, 12, 3, 0, 0, 26624, 98, }, /* 1229 */ - { 62, 13, 12, 0, 0, 18432, 144, }, /* 1230 */ - { 17, 15, 12, 0, 0, 18432, 74, }, /* 1231 */ - { 68, 7, 12, 0, 0, 18432, 84, }, /* 1232 */ - { 68, 10, 5, 0, 0, 18432, 154, }, /* 1233 */ - { 68, 12, 3, 0, 0, 26624, 106, }, /* 1234 */ - { 68, 10, 3, 0, 0, 18432, 188, }, /* 1235 */ - { 68, 12, 3, 0, 0, 26624, 98, }, /* 1236 */ - { 68, 12, 3, 0, 0, 26624, 162, }, /* 1237 */ - { 68, 21, 12, 0, 0, 18432, 128, }, /* 1238 */ - { 68, 21, 12, 0, 0, 18432, 110, }, /* 1239 */ - { 68, 21, 12, 0, 0, 18432, 74, }, /* 1240 */ - { 77, 7, 12, 0, 0, 18432, 84, }, /* 1241 */ - { 77, 21, 12, 0, 0, 18432, 128, }, /* 1242 */ - { 75, 7, 12, 0, 0, 18432, 84, }, /* 1243 */ - { 75, 12, 3, 0, 0, 26624, 106, }, /* 1244 */ - { 75, 10, 5, 0, 0, 18432, 154, }, /* 1245 */ - { 75, 12, 3, 0, 0, 26624, 98, }, /* 1246 */ - { 75, 12, 3, 0, 0, 26624, 158, }, /* 1247 */ - { 75, 13, 12, 0, 0, 18432, 144, }, /* 1248 */ - { 67, 12, 3, 0, 0, 26624, 106, }, /* 1249 */ - { 67, 12, 3, 0, 0, 26836, 106, }, /* 1250 */ - { 67, 10, 5, 0, 0, 18432, 154, }, /* 1251 */ - { 67, 10, 5, 0, 0, 18644, 154, }, /* 1252 */ - { 67, 7, 12, 0, 0, 18432, 84, }, /* 1253 */ - { 106, 12, 3, 0, 0, 26836, 98, }, /* 1254 */ - { 67, 12, 3, 0, 0, 26836, 98, }, /* 1255 */ - { 67, 10, 3, 0, 0, 18432, 160, }, /* 1256 */ - { 67, 10, 3, 0, 0, 18432, 188, }, /* 1257 */ - { 67, 7, 12, 0, 0, 18432, 348, }, /* 1258 */ - { 67, 12, 3, 0, 0, 26624, 98, }, /* 1259 */ - { 97, 7, 12, 0, 0, 18432, 84, }, /* 1260 */ - { 97, 10, 3, 0, 0, 18432, 160, }, /* 1261 */ - { 97, 10, 5, 0, 0, 18432, 154, }, /* 1262 */ - { 97, 12, 3, 0, 0, 26624, 106, }, /* 1263 */ - { 97, 12, 3, 0, 0, 26624, 158, }, /* 1264 */ - { 97, 10, 3, 0, 0, 18432, 188, }, /* 1265 */ - { 97, 7, 4, 0, 0, 18432, 84, }, /* 1266 */ - { 97, 12, 3, 0, 0, 26624, 164, }, /* 1267 */ - { 97, 7, 12, 0, 0, 18432, 350, }, /* 1268 */ - { 97, 21, 12, 0, 0, 18432, 128, }, /* 1269 */ - { 97, 21, 12, 0, 0, 18432, 74, }, /* 1270 */ - { 97, 12, 3, 0, 0, 26624, 98, }, /* 1271 */ - { 153, 7, 12, 0, 0, 18432, 84, }, /* 1272 */ - { 153, 10, 5, 0, 0, 18432, 154, }, /* 1273 */ - { 153, 12, 3, 0, 0, 26624, 106, }, /* 1274 */ - { 153, 12, 3, 0, 0, 26624, 158, }, /* 1275 */ - { 153, 12, 3, 0, 0, 26624, 98, }, /* 1276 */ - { 153, 21, 12, 0, 0, 18432, 128, }, /* 1277 */ - { 153, 21, 12, 0, 0, 18432, 110, }, /* 1278 */ - { 153, 21, 12, 0, 0, 18432, 74, }, /* 1279 */ - { 153, 13, 12, 0, 0, 18432, 144, }, /* 1280 */ - { 153, 12, 3, 0, 0, 26624, 104, }, /* 1281 */ - { 76, 7, 12, 0, 0, 18432, 84, }, /* 1282 */ - { 76, 10, 3, 0, 0, 18432, 160, }, /* 1283 */ - { 76, 10, 5, 0, 0, 18432, 154, }, /* 1284 */ - { 76, 12, 3, 0, 0, 26624, 106, }, /* 1285 */ - { 76, 12, 3, 0, 0, 26624, 158, }, /* 1286 */ - { 76, 12, 3, 0, 0, 26624, 98, }, /* 1287 */ - { 76, 21, 12, 0, 0, 18432, 74, }, /* 1288 */ - { 76, 13, 12, 0, 0, 18432, 144, }, /* 1289 */ - { 145, 7, 12, 0, 0, 18432, 84, }, /* 1290 */ - { 145, 10, 3, 0, 0, 18432, 160, }, /* 1291 */ - { 145, 10, 5, 0, 0, 18432, 154, }, /* 1292 */ - { 145, 12, 3, 0, 0, 26624, 106, }, /* 1293 */ - { 145, 12, 3, 0, 0, 26624, 158, }, /* 1294 */ - { 145, 12, 3, 0, 0, 26624, 98, }, /* 1295 */ - { 145, 21, 12, 0, 0, 18432, 74, }, /* 1296 */ - { 145, 21, 12, 0, 0, 18432, 128, }, /* 1297 */ - { 145, 21, 12, 0, 0, 18432, 110, }, /* 1298 */ - { 145, 21, 12, 0, 0, 18432, 190, }, /* 1299 */ - { 72, 7, 12, 0, 0, 18432, 84, }, /* 1300 */ - { 72, 10, 5, 0, 0, 18432, 154, }, /* 1301 */ - { 72, 12, 3, 0, 0, 26624, 106, }, /* 1302 */ - { 72, 12, 3, 0, 0, 26624, 158, }, /* 1303 */ - { 72, 21, 12, 0, 0, 18432, 128, }, /* 1304 */ - { 72, 21, 12, 0, 0, 18432, 74, }, /* 1305 */ - { 72, 13, 12, 0, 0, 18432, 144, }, /* 1306 */ - { 63, 7, 12, 0, 0, 18432, 84, }, /* 1307 */ - { 63, 12, 3, 0, 0, 26624, 106, }, /* 1308 */ - { 63, 10, 5, 0, 0, 18432, 154, }, /* 1309 */ - { 63, 10, 3, 0, 0, 18432, 188, }, /* 1310 */ - { 63, 12, 3, 0, 0, 26624, 98, }, /* 1311 */ - { 63, 21, 12, 0, 0, 18432, 74, }, /* 1312 */ - { 63, 13, 12, 0, 0, 18432, 144, }, /* 1313 */ - { 147, 7, 12, 0, 0, 18432, 84, }, /* 1314 */ - { 147, 12, 3, 0, 0, 26624, 106, }, /* 1315 */ - { 147, 10, 5, 0, 0, 18432, 154, }, /* 1316 */ - { 147, 10, 12, 0, 0, 18432, 154, }, /* 1317 */ - { 147, 12, 3, 0, 0, 26624, 158, }, /* 1318 */ - { 147, 13, 12, 0, 0, 18432, 144, }, /* 1319 */ - { 147, 15, 12, 0, 0, 18432, 74, }, /* 1320 */ - { 147, 21, 12, 0, 0, 18432, 128, }, /* 1321 */ - { 147, 26, 12, 0, 0, 18432, 74, }, /* 1322 */ - { 83, 7, 12, 0, 0, 18432, 84, }, /* 1323 */ - { 83, 10, 5, 0, 0, 18432, 154, }, /* 1324 */ - { 83, 12, 3, 0, 0, 26624, 106, }, /* 1325 */ - { 83, 12, 3, 0, 0, 26624, 158, }, /* 1326 */ - { 83, 12, 3, 0, 0, 26624, 98, }, /* 1327 */ - { 83, 21, 12, 0, 0, 18432, 74, }, /* 1328 */ - { 146, 9, 12, 0, 32, 18432, 76, }, /* 1329 */ - { 146, 5, 12, 0, -32, 18432, 78, }, /* 1330 */ - { 146, 13, 12, 0, 0, 18432, 144, }, /* 1331 */ - { 146, 15, 12, 0, 0, 18432, 74, }, /* 1332 */ - { 146, 7, 12, 0, 0, 18432, 84, }, /* 1333 */ - { 164, 7, 12, 0, 0, 18432, 84, }, /* 1334 */ - { 164, 10, 3, 0, 0, 18432, 160, }, /* 1335 */ - { 164, 10, 5, 0, 0, 18432, 154, }, /* 1336 */ - { 164, 12, 3, 0, 0, 26624, 106, }, /* 1337 */ - { 164, 10, 3, 0, 0, 18432, 188, }, /* 1338 */ - { 164, 12, 3, 0, 0, 26624, 158, }, /* 1339 */ - { 164, 7, 4, 0, 0, 18432, 84, }, /* 1340 */ - { 164, 12, 3, 0, 0, 26624, 98, }, /* 1341 */ - { 164, 21, 12, 0, 0, 18432, 128, }, /* 1342 */ - { 164, 21, 12, 0, 0, 18432, 74, }, /* 1343 */ - { 164, 13, 12, 0, 0, 18432, 144, }, /* 1344 */ - { 87, 7, 12, 0, 0, 18432, 84, }, /* 1345 */ - { 87, 10, 5, 0, 0, 18432, 154, }, /* 1346 */ - { 87, 12, 3, 0, 0, 26624, 106, }, /* 1347 */ - { 87, 12, 3, 0, 0, 26624, 158, }, /* 1348 */ - { 87, 21, 12, 0, 0, 18432, 74, }, /* 1349 */ - { 156, 7, 12, 0, 0, 18432, 84, }, /* 1350 */ - { 156, 12, 3, 0, 0, 26624, 106, }, /* 1351 */ - { 156, 12, 3, 0, 0, 18432, 106, }, /* 1352 */ - { 156, 12, 3, 0, 0, 26624, 104, }, /* 1353 */ - { 156, 12, 3, 0, 0, 26624, 158, }, /* 1354 */ - { 156, 10, 5, 0, 0, 18432, 154, }, /* 1355 */ - { 156, 7, 4, 0, 0, 18432, 84, }, /* 1356 */ - { 156, 21, 12, 0, 0, 18432, 74, }, /* 1357 */ - { 156, 21, 12, 0, 0, 18432, 128, }, /* 1358 */ - { 155, 7, 12, 0, 0, 18432, 84, }, /* 1359 */ - { 155, 12, 3, 0, 0, 26624, 106, }, /* 1360 */ - { 155, 10, 5, 0, 0, 18432, 154, }, /* 1361 */ - { 155, 7, 4, 0, 0, 18432, 84, }, /* 1362 */ - { 155, 12, 3, 0, 0, 26624, 352, }, /* 1363 */ - { 155, 12, 3, 0, 0, 26624, 158, }, /* 1364 */ - { 155, 21, 12, 0, 0, 18432, 74, }, /* 1365 */ - { 155, 21, 12, 0, 0, 18432, 128, }, /* 1366 */ - { 155, 21, 12, 0, 0, 18432, 110, }, /* 1367 */ - { 144, 7, 12, 0, 0, 18432, 84, }, /* 1368 */ - { 95, 7, 12, 0, 0, 18432, 84, }, /* 1369 */ - { 95, 21, 12, 0, 0, 18432, 74, }, /* 1370 */ - { 95, 13, 12, 0, 0, 18432, 144, }, /* 1371 */ - { 151, 7, 12, 0, 0, 18432, 84, }, /* 1372 */ - { 151, 10, 5, 0, 0, 18432, 154, }, /* 1373 */ - { 151, 12, 3, 0, 0, 26624, 106, }, /* 1374 */ - { 151, 12, 3, 0, 0, 18432, 158, }, /* 1375 */ - { 151, 21, 12, 0, 0, 18432, 128, }, /* 1376 */ - { 151, 21, 12, 0, 0, 18432, 110, }, /* 1377 */ - { 151, 21, 12, 0, 0, 18432, 74, }, /* 1378 */ - { 151, 13, 12, 0, 0, 18432, 144, }, /* 1379 */ - { 151, 15, 12, 0, 0, 18432, 74, }, /* 1380 */ - { 152, 21, 12, 0, 0, 18432, 74, }, /* 1381 */ - { 152, 21, 12, 0, 0, 18432, 110, }, /* 1382 */ - { 152, 7, 12, 0, 0, 18432, 84, }, /* 1383 */ - { 152, 12, 3, 0, 0, 26624, 106, }, /* 1384 */ - { 152, 10, 5, 0, 0, 18432, 154, }, /* 1385 */ - { 82, 7, 12, 0, 0, 18432, 84, }, /* 1386 */ - { 82, 12, 3, 0, 0, 26624, 106, }, /* 1387 */ - { 82, 12, 3, 0, 0, 26624, 98, }, /* 1388 */ - { 82, 12, 3, 0, 0, 26624, 158, }, /* 1389 */ - { 82, 7, 4, 0, 0, 18432, 84, }, /* 1390 */ - { 82, 13, 12, 0, 0, 18432, 144, }, /* 1391 */ - { 84, 7, 12, 0, 0, 18432, 84, }, /* 1392 */ - { 84, 10, 5, 0, 0, 18432, 154, }, /* 1393 */ - { 84, 12, 3, 0, 0, 26624, 106, }, /* 1394 */ - { 84, 12, 3, 0, 0, 26624, 158, }, /* 1395 */ - { 84, 13, 12, 0, 0, 18432, 144, }, /* 1396 */ - { 157, 7, 12, 0, 0, 18432, 84, }, /* 1397 */ - { 157, 12, 3, 0, 0, 26624, 106, }, /* 1398 */ - { 157, 10, 5, 0, 0, 18432, 154, }, /* 1399 */ - { 157, 21, 12, 0, 0, 18432, 128, }, /* 1400 */ - { 168, 12, 3, 0, 0, 26624, 106, }, /* 1401 */ - { 168, 7, 4, 0, 0, 18432, 84, }, /* 1402 */ - { 168, 10, 5, 0, 0, 18432, 154, }, /* 1403 */ - { 168, 7, 12, 0, 0, 18432, 84, }, /* 1404 */ - { 168, 10, 3, 0, 0, 18432, 188, }, /* 1405 */ - { 168, 12, 3, 0, 0, 26624, 158, }, /* 1406 */ - { 168, 21, 12, 0, 0, 18432, 128, }, /* 1407 */ - { 168, 21, 12, 0, 0, 18432, 74, }, /* 1408 */ - { 168, 13, 12, 0, 0, 18432, 144, }, /* 1409 */ - { 168, 12, 3, 0, 0, 26624, 98, }, /* 1410 */ - { 13, 15, 12, 0, 0, 18432, 74, }, /* 1411 */ - { 13, 21, 12, 0, 0, 18432, 74, }, /* 1412 */ - { 114, 7, 12, 0, 0, 18432, 84, }, /* 1413 */ - { 114, 14, 12, 0, 0, 18432, 84, }, /* 1414 */ - { 114, 21, 12, 0, 0, 18432, 110, }, /* 1415 */ - { 89, 7, 12, 0, 0, 18432, 84, }, /* 1416 */ - { 89, 21, 12, 0, 0, 18432, 74, }, /* 1417 */ - { 125, 7, 12, 0, 0, 18432, 84, }, /* 1418 */ - { 125, 1, 2, 0, 0, 18432, 346, }, /* 1419 */ - { 125, 12, 3, 0, 0, 26624, 104, }, /* 1420 */ - { 125, 12, 3, 0, 0, 26624, 98, }, /* 1421 */ - { 148, 7, 12, 0, 0, 18432, 84, }, /* 1422 */ - { 93, 7, 12, 0, 0, 18432, 84, }, /* 1423 */ - { 93, 12, 3, 0, 0, 26624, 106, }, /* 1424 */ - { 93, 10, 5, 0, 0, 18432, 154, }, /* 1425 */ - { 93, 12, 3, 0, 0, 26624, 158, }, /* 1426 */ - { 93, 13, 12, 0, 0, 18432, 144, }, /* 1427 */ - { 140, 7, 12, 0, 0, 18432, 84, }, /* 1428 */ - { 140, 13, 12, 0, 0, 18432, 144, }, /* 1429 */ - { 140, 21, 12, 0, 0, 18432, 128, }, /* 1430 */ - { 166, 7, 12, 0, 0, 18432, 84, }, /* 1431 */ - { 166, 13, 12, 0, 0, 18432, 144, }, /* 1432 */ - { 137, 7, 12, 0, 0, 18432, 84, }, /* 1433 */ - { 137, 12, 3, 0, 0, 26624, 98, }, /* 1434 */ - { 137, 21, 12, 0, 0, 18432, 128, }, /* 1435 */ - { 138, 7, 12, 0, 0, 18432, 84, }, /* 1436 */ - { 138, 12, 3, 0, 0, 26624, 98, }, /* 1437 */ - { 138, 21, 12, 0, 0, 18432, 128, }, /* 1438 */ - { 138, 21, 12, 0, 0, 18432, 110, }, /* 1439 */ - { 138, 21, 12, 0, 0, 18432, 74, }, /* 1440 */ - { 138, 26, 12, 0, 0, 18432, 74, }, /* 1441 */ - { 138, 6, 12, 0, 0, 18432, 148, }, /* 1442 */ - { 138, 6, 12, 0, 0, 18432, 138, }, /* 1443 */ - { 138, 13, 12, 0, 0, 18432, 144, }, /* 1444 */ - { 138, 15, 12, 0, 0, 18432, 74, }, /* 1445 */ - { 170, 6, 12, 0, 0, 18432, 148, }, /* 1446 */ - { 170, 7, 12, 0, 0, 18432, 84, }, /* 1447 */ - { 170, 7, 7, 0, 0, 18432, 84, }, /* 1448 */ - { 170, 6, 12, 0, 0, 18432, 94, }, /* 1449 */ - { 170, 21, 12, 0, 0, 18432, 74, }, /* 1450 */ - { 170, 21, 12, 0, 0, 18432, 128, }, /* 1451 */ - { 170, 13, 12, 0, 0, 18432, 144, }, /* 1452 */ - { 158, 9, 12, 0, 32, 18432, 76, }, /* 1453 */ - { 158, 5, 12, 0, -32, 18432, 78, }, /* 1454 */ - { 158, 15, 12, 0, 0, 18432, 74, }, /* 1455 */ - { 158, 21, 12, 0, 0, 18432, 110, }, /* 1456 */ - { 158, 21, 12, 0, 0, 18432, 128, }, /* 1457 */ - { 158, 21, 12, 0, 0, 18432, 74, }, /* 1458 */ - { 135, 7, 12, 0, 0, 18432, 84, }, /* 1459 */ - { 135, 12, 3, 0, 0, 26624, 106, }, /* 1460 */ - { 135, 10, 5, 0, 0, 18432, 154, }, /* 1461 */ - { 135, 12, 3, 0, 0, 26624, 132, }, /* 1462 */ - { 135, 6, 12, 0, 0, 18432, 94, }, /* 1463 */ - { 81, 6, 12, 0, 0, 18432, 138, }, /* 1464 */ - { 154, 6, 12, 0, 0, 18432, 138, }, /* 1465 */ - { 30, 21, 12, 0, 0, 28672, 74, }, /* 1466 */ - { 165, 12, 3, 0, 0, 26624, 354, }, /* 1467 */ - { 30, 10, 3, 0, 0, 18432, 356, }, /* 1468 */ - { 81, 7, 12, 0, 0, 18432, 304, }, /* 1469 */ - { 165, 7, 12, 0, 0, 18432, 304, }, /* 1470 */ - { 28, 6, 12, 0, 0, 18432, 94, }, /* 1471 */ - { 154, 7, 12, 0, 0, 18432, 304, }, /* 1472 */ - { 65, 7, 12, 0, 0, 18432, 84, }, /* 1473 */ - { 65, 26, 12, 0, 0, 18432, 74, }, /* 1474 */ - { 65, 12, 3, 0, 0, 26624, 104, }, /* 1475 */ - { 65, 12, 3, 0, 0, 26624, 106, }, /* 1476 */ - { 65, 21, 12, 0, 0, 18432, 128, }, /* 1477 */ - { 99, 1, 2, 0, 0, 6472, 66, }, /* 1478 */ - { 99, 13, 12, 0, 0, 10240, 144, }, /* 1479 */ - { 99, 10, 3, 0, 0, 18432, 358, }, /* 1480 */ - { 99, 10, 3, 0, 0, 18432, 306, }, /* 1481 */ - { 1, 12, 3, 0, 0, 26624, 104, }, /* 1482 */ - { 99, 25, 12, 0, 0, 28672, 360, }, /* 1483 */ - { 99, 13, 12, 0, 0, 10240, 226, }, /* 1484 */ - { 150, 26, 12, 0, 0, 18432, 74, }, /* 1485 */ - { 150, 12, 3, 0, 0, 26624, 104, }, /* 1486 */ - { 150, 21, 12, 0, 0, 18432, 110, }, /* 1487 */ - { 150, 21, 12, 0, 0, 18432, 128, }, /* 1488 */ - { 150, 21, 12, 0, 0, 18432, 74, }, /* 1489 */ - { 44, 12, 3, 0, 0, 26624, 106, }, /* 1490 */ - { 2, 6, 12, 0, 0, 18432, 92, }, /* 1491 */ - { 161, 7, 12, 0, 0, 18432, 84, }, /* 1492 */ - { 161, 12, 3, 0, 0, 26624, 98, }, /* 1493 */ - { 161, 6, 12, 0, 0, 18432, 148, }, /* 1494 */ - { 161, 6, 12, 0, 0, 18432, 138, }, /* 1495 */ - { 161, 13, 12, 0, 0, 18432, 144, }, /* 1496 */ - { 161, 26, 12, 0, 0, 18432, 74, }, /* 1497 */ - { 91, 7, 12, 0, 0, 18432, 84, }, /* 1498 */ - { 91, 12, 3, 0, 0, 26624, 98, }, /* 1499 */ - { 162, 7, 12, 0, 0, 18432, 84, }, /* 1500 */ - { 162, 12, 3, 0, 0, 26624, 98, }, /* 1501 */ - { 162, 13, 12, 0, 0, 18432, 144, }, /* 1502 */ - { 162, 23, 12, 0, 0, 14336, 74, }, /* 1503 */ - { 169, 7, 12, 0, 0, 18432, 84, }, /* 1504 */ - { 169, 6, 12, 0, 0, 18432, 148, }, /* 1505 */ - { 169, 12, 3, 0, 0, 26624, 104, }, /* 1506 */ - { 169, 13, 12, 0, 0, 18432, 144, }, /* 1507 */ - { 94, 7, 12, 0, 0, 18432, 84, }, /* 1508 */ - { 94, 12, 3, 0, 0, 26624, 98, }, /* 1509 */ - { 94, 12, 3, 0, 0, 26624, 164, }, /* 1510 */ - { 94, 13, 12, 0, 0, 18432, 144, }, /* 1511 */ - { 94, 21, 12, 0, 0, 18432, 74, }, /* 1512 */ - { 139, 7, 12, 0, 0, 34816, 84, }, /* 1513 */ - { 139, 15, 12, 0, 0, 34816, 74, }, /* 1514 */ - { 139, 12, 3, 0, 0, 26624, 98, }, /* 1515 */ - { 79, 9, 12, 0, 34, 34816, 76, }, /* 1516 */ - { 79, 5, 12, 0, -34, 34816, 78, }, /* 1517 */ - { 79, 12, 3, 0, 0, 26624, 164, }, /* 1518 */ - { 79, 12, 3, 0, 0, 26624, 106, }, /* 1519 */ - { 79, 12, 3, 0, 0, 26624, 98, }, /* 1520 */ - { 79, 6, 12, 0, 0, 34816, 148, }, /* 1521 */ - { 79, 13, 12, 0, 0, 34816, 144, }, /* 1522 */ - { 79, 21, 12, 0, 0, 34816, 74, }, /* 1523 */ - { 99, 15, 12, 0, 0, 0, 74, }, /* 1524 */ - { 99, 26, 12, 0, 0, 0, 74, }, /* 1525 */ - { 99, 23, 12, 0, 0, 0, 74, }, /* 1526 */ - { 5, 7, 12, 0, 0, 0, 254, }, /* 1527 */ - { 99, 26, 14, 0, 0, 28672, 362, }, /* 1528 */ - { 99, 26, 14, 0, 0, 28672, 364, }, /* 1529 */ - { 98, 2, 14, 0, 0, 18432, 366, }, /* 1530 */ - { 99, 26, 12, 0, 0, 18432, 368, }, /* 1531 */ - { 99, 26, 14, 0, 0, 18432, 370, }, /* 1532 */ - { 99, 26, 14, 0, 0, 18432, 364, }, /* 1533 */ - { 99, 26, 11, 0, 0, 18432, 372, }, /* 1534 */ - { 27, 26, 12, 0, 0, 18432, 74, }, /* 1535 */ - { 99, 26, 14, 0, 0, 18432, 250, }, /* 1536 */ - { 99, 26, 14, 0, 0, 18784, 364, }, /* 1537 */ - { 99, 26, 14, 0, 0, 28672, 374, }, /* 1538 */ - { 99, 26, 14, 0, 0, 28672, 376, }, /* 1539 */ - { 99, 24, 3, 0, 0, 28672, 378, }, /* 1540 */ - { 99, 26, 14, 0, 0, 28672, 380, }, /* 1541 */ - { 99, 1, 3, 0, 0, 6144, 382, }, /* 1542 */ + { 0, 5, 12, 0, 195, 18432, 76, }, /* 74 */ + { 0, 9, 12, 0, 210, 18432, 74, }, /* 75 */ + { 0, 9, 12, 0, 206, 18432, 74, }, /* 76 */ + { 0, 9, 12, 0, 205, 18432, 74, }, /* 77 */ + { 0, 9, 12, 0, 79, 18432, 74, }, /* 78 */ + { 0, 9, 12, 0, 202, 18432, 74, }, /* 79 */ + { 0, 9, 12, 0, 203, 18432, 74, }, /* 80 */ + { 0, 9, 12, 0, 207, 18432, 74, }, /* 81 */ + { 0, 5, 12, 0, 97, 18432, 76, }, /* 82 */ + { 0, 9, 12, 0, 211, 18432, 74, }, /* 83 */ + { 0, 9, 12, 0, 209, 18432, 74, }, /* 84 */ + { 0, 5, 12, 0, 163, 18432, 76, }, /* 85 */ + { 0, 9, 12, 0, 213, 18432, 74, }, /* 86 */ + { 0, 5, 12, 0, 130, 18432, 76, }, /* 87 */ + { 0, 9, 12, 0, 214, 18432, 74, }, /* 88 */ + { 0, 9, 12, 0, 218, 18432, 74, }, /* 89 */ + { 0, 9, 12, 0, 217, 18432, 74, }, /* 90 */ + { 0, 9, 12, 0, 219, 18432, 74, }, /* 91 */ + { 0, 7, 12, 0, 0, 18432, 82, }, /* 92 */ + { 0, 5, 12, 0, 56, 18432, 76, }, /* 93 */ + { 0, 9, 12, 5, 2, 18432, 84, }, /* 94 */ + { 0, 8, 12, 5, 1, 18432, 86, }, /* 95 */ + { 0, 5, 12, 5, -2, 18432, 76, }, /* 96 */ + { 0, 9, 12, 9, 2, 18432, 84, }, /* 97 */ + { 0, 8, 12, 9, 1, 18432, 86, }, /* 98 */ + { 0, 5, 12, 9, -2, 18432, 76, }, /* 99 */ + { 0, 9, 12, 13, 2, 18432, 84, }, /* 100 */ + { 0, 8, 12, 13, 1, 18432, 86, }, /* 101 */ + { 0, 5, 12, 13, -2, 18432, 76, }, /* 102 */ + { 0, 5, 12, 0, -79, 18432, 76, }, /* 103 */ + { 0, 9, 12, 17, 2, 18432, 84, }, /* 104 */ + { 0, 8, 12, 17, 1, 18432, 86, }, /* 105 */ + { 0, 5, 12, 17, -2, 18432, 76, }, /* 106 */ + { 0, 9, 12, 0, -97, 18432, 74, }, /* 107 */ + { 0, 9, 12, 0, -56, 18432, 74, }, /* 108 */ + { 0, 9, 12, 0, -130, 18432, 74, }, /* 109 */ + { 0, 9, 12, 0, 10795, 18432, 74, }, /* 110 */ + { 0, 9, 12, 0, -163, 18432, 74, }, /* 111 */ + { 0, 9, 12, 0, 10792, 18432, 74, }, /* 112 */ + { 0, 5, 12, 0, 10815, 18432, 76, }, /* 113 */ + { 0, 9, 12, 0, -195, 18432, 74, }, /* 114 */ + { 0, 9, 12, 0, 69, 18432, 74, }, /* 115 */ + { 0, 9, 12, 0, 71, 18432, 74, }, /* 116 */ + { 0, 5, 12, 0, 10783, 18432, 76, }, /* 117 */ + { 0, 5, 12, 0, 10780, 18432, 76, }, /* 118 */ + { 0, 5, 12, 0, 10782, 18432, 76, }, /* 119 */ + { 0, 5, 12, 0, -210, 18432, 76, }, /* 120 */ + { 0, 5, 12, 0, -206, 18432, 76, }, /* 121 */ + { 0, 5, 12, 0, -205, 18432, 76, }, /* 122 */ + { 0, 5, 12, 0, -202, 18432, 76, }, /* 123 */ + { 0, 5, 12, 0, -203, 18432, 76, }, /* 124 */ + { 0, 5, 12, 0, 42319, 18432, 76, }, /* 125 */ + { 0, 5, 12, 0, 42315, 18432, 76, }, /* 126 */ + { 0, 5, 12, 0, -207, 18432, 76, }, /* 127 */ + { 0, 5, 12, 0, 42280, 18432, 76, }, /* 128 */ + { 0, 5, 12, 0, 42308, 18432, 76, }, /* 129 */ + { 0, 5, 12, 0, -209, 18432, 78, }, /* 130 */ + { 0, 5, 12, 0, -211, 18432, 76, }, /* 131 */ + { 0, 5, 12, 0, 10743, 18432, 76, }, /* 132 */ + { 0, 5, 12, 0, 42305, 18432, 76, }, /* 133 */ + { 0, 5, 12, 0, 10749, 18432, 76, }, /* 134 */ + { 0, 5, 12, 0, -213, 18432, 76, }, /* 135 */ + { 0, 5, 12, 0, -214, 18432, 76, }, /* 136 */ + { 0, 5, 12, 0, 10727, 18432, 76, }, /* 137 */ + { 0, 5, 12, 0, -218, 18432, 76, }, /* 138 */ + { 0, 5, 12, 0, 42307, 18432, 76, }, /* 139 */ + { 0, 5, 12, 0, 42282, 18432, 76, }, /* 140 */ + { 0, 5, 12, 0, -69, 18432, 76, }, /* 141 */ + { 0, 5, 12, 0, -217, 18432, 76, }, /* 142 */ + { 0, 5, 12, 0, -71, 18432, 76, }, /* 143 */ + { 0, 5, 12, 0, -219, 18432, 76, }, /* 144 */ + { 0, 5, 12, 0, 42261, 18432, 78, }, /* 145 */ + { 0, 5, 12, 0, 42258, 18432, 76, }, /* 146 */ + { 0, 6, 12, 0, 0, 18432, 88, }, /* 147 */ + { 0, 6, 12, 0, 0, 18432, 90, }, /* 148 */ + { 69, 6, 12, 0, 0, 28672, 92, }, /* 149 */ + { 69, 6, 12, 0, 0, 18432, 92, }, /* 150 */ + { 69, 6, 12, 0, 0, 18432, 88, }, /* 151 */ + { 69, 6, 12, 0, 0, 18432, 94, }, /* 152 */ + { 22, 24, 12, 0, 0, 28672, 56, }, /* 153 */ + { 84, 12, 3, 0, 0, 26624, 96, }, /* 154 */ + { 84, 12, 3, 0, 0, 26636, 96, }, /* 155 */ + { 84, 12, 3, 21, 116, 26636, 98, }, /* 156 */ + { 84, 12, 3, 0, 0, 26624, 100, }, /* 157 */ + { 84, 12, 3, 0, 0, 26624, 102, }, /* 158 */ + { 84, 12, 3, 0, 0, 26642, 102, }, /* 159 */ + { 1, 9, 12, 0, 1, 18432, 74, }, /* 160 */ + { 1, 5, 12, 0, -1, 18432, 76, }, /* 161 */ + { 1, 24, 12, 0, 0, 28672, 56, }, /* 162 */ + { 68, 2, 12, 0, 0, 18432, 0, }, /* 163 */ + { 1, 6, 12, 0, 0, 18432, 104, }, /* 164 */ + { 1, 5, 12, 0, 130, 18432, 76, }, /* 165 */ + { 69, 21, 12, 0, 0, 28672, 106, }, /* 166 */ + { 1, 9, 12, 0, 116, 18432, 74, }, /* 167 */ + { 1, 9, 12, 0, 38, 18432, 74, }, /* 168 */ + { 69, 21, 12, 0, 0, 28672, 108, }, /* 169 */ + { 1, 9, 12, 0, 37, 18432, 74, }, /* 170 */ + { 1, 9, 12, 0, 64, 18432, 74, }, /* 171 */ + { 1, 9, 12, 0, 63, 18432, 74, }, /* 172 */ + { 1, 5, 12, 0, 0, 18432, 76, }, /* 173 */ + { 1, 9, 12, 0, 32, 18432, 74, }, /* 174 */ + { 1, 9, 12, 34, 32, 18432, 74, }, /* 175 */ + { 1, 9, 12, 59, 32, 18432, 74, }, /* 176 */ + { 1, 9, 12, 38, 32, 18432, 74, }, /* 177 */ + { 1, 9, 12, 21, 32, 18432, 74, }, /* 178 */ + { 1, 9, 12, 51, 32, 18432, 74, }, /* 179 */ + { 1, 9, 12, 26, 32, 18432, 74, }, /* 180 */ + { 1, 9, 12, 47, 32, 18432, 74, }, /* 181 */ + { 1, 9, 12, 55, 32, 18432, 74, }, /* 182 */ + { 1, 9, 12, 30, 32, 18432, 74, }, /* 183 */ + { 1, 9, 12, 43, 32, 18432, 74, }, /* 184 */ + { 1, 9, 12, 96, 32, 18432, 74, }, /* 185 */ + { 1, 5, 12, 0, -38, 18432, 76, }, /* 186 */ + { 1, 5, 12, 0, -37, 18432, 76, }, /* 187 */ + { 1, 5, 12, 0, -32, 18432, 76, }, /* 188 */ + { 1, 5, 12, 34, -32, 18432, 76, }, /* 189 */ + { 1, 5, 12, 59, -32, 18432, 76, }, /* 190 */ + { 1, 5, 12, 38, -32, 18432, 76, }, /* 191 */ + { 1, 5, 12, 21, -116, 18432, 76, }, /* 192 */ + { 1, 5, 12, 51, -32, 18432, 76, }, /* 193 */ + { 1, 5, 12, 26, -775, 18432, 76, }, /* 194 */ + { 1, 5, 12, 47, -32, 18432, 76, }, /* 195 */ + { 1, 5, 12, 55, -32, 18432, 76, }, /* 196 */ + { 1, 5, 12, 30, 1, 18432, 70, }, /* 197 */ + { 1, 5, 12, 30, -32, 18432, 76, }, /* 198 */ + { 1, 5, 12, 43, -32, 18432, 76, }, /* 199 */ + { 1, 5, 12, 96, -32, 18432, 76, }, /* 200 */ + { 1, 5, 12, 0, -64, 18432, 76, }, /* 201 */ + { 1, 5, 12, 0, -63, 18432, 76, }, /* 202 */ + { 1, 9, 12, 0, 8, 18432, 74, }, /* 203 */ + { 1, 5, 12, 34, -30, 18432, 110, }, /* 204 */ + { 1, 5, 12, 38, -25, 18432, 110, }, /* 205 */ + { 1, 9, 12, 0, 0, 18432, 112, }, /* 206 */ + { 1, 9, 12, 0, 0, 18432, 114, }, /* 207 */ + { 1, 5, 12, 43, -15, 18432, 110, }, /* 208 */ + { 1, 5, 12, 47, -22, 18432, 70, }, /* 209 */ + { 1, 5, 12, 0, -8, 18432, 76, }, /* 210 */ + { 34, 9, 12, 0, 1, 18432, 74, }, /* 211 */ + { 34, 5, 12, 0, -1, 18432, 76, }, /* 212 */ + { 1, 5, 12, 51, -54, 18432, 110, }, /* 213 */ + { 1, 5, 12, 55, -48, 18432, 110, }, /* 214 */ + { 1, 5, 12, 0, 7, 18432, 76, }, /* 215 */ + { 1, 5, 12, 0, -116, 18432, 78, }, /* 216 */ + { 1, 9, 12, 38, -60, 18432, 116, }, /* 217 */ + { 1, 5, 12, 59, -64, 18432, 110, }, /* 218 */ + { 1, 25, 12, 0, 0, 28672, 118, }, /* 219 */ + { 1, 9, 12, 0, -7, 18432, 74, }, /* 220 */ + { 1, 5, 12, 0, 0, 18432, 60, }, /* 221 */ + { 1, 9, 12, 0, -130, 18432, 74, }, /* 222 */ + { 2, 9, 12, 0, 80, 18432, 74, }, /* 223 */ + { 2, 9, 12, 0, 32, 18432, 74, }, /* 224 */ + { 2, 9, 12, 63, 32, 18432, 74, }, /* 225 */ + { 2, 9, 12, 67, 32, 18432, 74, }, /* 226 */ + { 2, 9, 12, 71, 32, 18432, 74, }, /* 227 */ + { 2, 9, 12, 75, 32, 18432, 74, }, /* 228 */ + { 2, 9, 12, 79, 32, 18432, 74, }, /* 229 */ + { 2, 9, 12, 84, 32, 18432, 74, }, /* 230 */ + { 2, 5, 12, 0, -32, 18432, 76, }, /* 231 */ + { 2, 5, 12, 63, -32, 18432, 76, }, /* 232 */ + { 2, 5, 12, 67, -32, 18432, 76, }, /* 233 */ + { 2, 5, 12, 71, -32, 18432, 76, }, /* 234 */ + { 2, 5, 12, 75, -32, 18432, 76, }, /* 235 */ + { 2, 5, 12, 79, -32, 18432, 76, }, /* 236 */ + { 2, 5, 12, 84, -32, 18432, 76, }, /* 237 */ + { 2, 5, 12, 0, -80, 18432, 76, }, /* 238 */ + { 2, 5, 12, 0, -80, 18432, 78, }, /* 239 */ + { 2, 9, 12, 0, 1, 18432, 74, }, /* 240 */ + { 2, 5, 12, 0, -1, 18432, 76, }, /* 241 */ + { 2, 9, 12, 88, 1, 18432, 74, }, /* 242 */ + { 2, 5, 12, 88, -1, 18432, 76, }, /* 243 */ + { 2, 26, 12, 0, 0, 18432, 68, }, /* 244 */ + { 2, 12, 3, 0, 0, 26684, 96, }, /* 245 */ + { 2, 12, 3, 0, 0, 26678, 96, }, /* 246 */ + { 84, 12, 3, 0, 0, 26681, 96, }, /* 247 */ + { 2, 11, 3, 0, 0, 26624, 120, }, /* 248 */ + { 2, 9, 12, 0, 15, 18432, 74, }, /* 249 */ + { 2, 5, 12, 0, -15, 18432, 76, }, /* 250 */ + { 70, 9, 12, 0, 48, 18432, 74, }, /* 251 */ + { 70, 6, 12, 0, 0, 18432, 92, }, /* 252 */ + { 70, 21, 12, 0, 0, 18432, 68, }, /* 253 */ + { 70, 21, 12, 0, 0, 18432, 122, }, /* 254 */ + { 70, 5, 12, 0, 0, 18432, 60, }, /* 255 */ + { 70, 5, 12, 0, -48, 18432, 76, }, /* 256 */ + { 70, 5, 12, 0, 0, 18432, 70, }, /* 257 */ + { 70, 21, 12, 0, 0, 18432, 124, }, /* 258 */ + { 70, 17, 12, 0, 0, 28672, 126, }, /* 259 */ + { 70, 26, 12, 0, 0, 28672, 68, }, /* 260 */ + { 70, 23, 12, 0, 0, 14336, 68, }, /* 261 */ + { 68, 2, 12, 0, 0, 34816, 0, }, /* 262 */ + { 71, 12, 3, 0, 0, 26624, 96, }, /* 263 */ + { 71, 12, 3, 0, 0, 26624, 102, }, /* 264 */ + { 71, 12, 3, 0, 0, 26624, 128, }, /* 265 */ + { 71, 17, 12, 0, 0, 34816, 126, }, /* 266 */ + { 71, 21, 12, 0, 0, 34816, 68, }, /* 267 */ + { 71, 21, 12, 0, 0, 34816, 106, }, /* 268 */ + { 71, 12, 3, 0, 0, 26624, 130, }, /* 269 */ + { 71, 7, 12, 0, 0, 34816, 82, }, /* 270 */ + { 71, 21, 12, 0, 0, 34816, 122, }, /* 271 */ + { 3, 1, 4, 0, 0, 2048, 132, }, /* 272 */ + { 69, 1, 4, 0, 0, 2048, 132, }, /* 273 */ + { 3, 25, 12, 0, 0, 28672, 118, }, /* 274 */ + { 3, 25, 12, 0, 0, 0, 118, }, /* 275 */ + { 3, 21, 12, 0, 0, 14336, 68, }, /* 276 */ + { 3, 23, 12, 0, 0, 0, 68, }, /* 277 */ + { 69, 21, 12, 0, 0, 8342, 106, }, /* 278 */ + { 3, 21, 12, 0, 0, 0, 68, }, /* 279 */ + { 3, 26, 12, 0, 0, 28672, 68, }, /* 280 */ + { 3, 12, 3, 0, 0, 26624, 130, }, /* 281 */ + { 69, 21, 12, 0, 0, 150, 106, }, /* 282 */ + { 3, 1, 2, 0, 0, 108, 134, }, /* 283 */ + { 3, 21, 12, 0, 0, 0, 124, }, /* 284 */ + { 69, 21, 12, 0, 0, 159, 124, }, /* 285 */ + { 3, 7, 12, 0, 0, 0, 82, }, /* 286 */ + { 69, 6, 12, 0, 0, 165, 136, }, /* 287 */ + { 84, 12, 3, 0, 0, 26660, 128, }, /* 288 */ + { 84, 12, 3, 0, 0, 26660, 130, }, /* 289 */ + { 3, 12, 3, 0, 0, 26624, 128, }, /* 290 */ + { 3, 12, 3, 0, 0, 26624, 96, }, /* 291 */ + { 3, 13, 12, 0, 0, 2159, 138, }, /* 292 */ + { 3, 21, 12, 0, 0, 2048, 68, }, /* 293 */ + { 3, 7, 12, 0, 0, 0, 140, }, /* 294 */ + { 3, 21, 12, 0, 0, 30, 124, }, /* 295 */ + { 3, 6, 12, 0, 0, 0, 92, }, /* 296 */ + { 3, 13, 12, 0, 0, 10240, 138, }, /* 297 */ + { 3, 26, 12, 0, 0, 0, 68, }, /* 298 */ + { 4, 21, 12, 0, 0, 0, 124, }, /* 299 */ + { 4, 21, 12, 0, 0, 0, 106, }, /* 300 */ + { 4, 21, 12, 0, 0, 0, 68, }, /* 301 */ + { 68, 2, 12, 0, 0, 0, 0, }, /* 302 */ + { 4, 1, 4, 0, 0, 0, 132, }, /* 303 */ + { 4, 7, 12, 0, 0, 0, 82, }, /* 304 */ + { 4, 12, 3, 0, 0, 26624, 130, }, /* 305 */ + { 4, 12, 3, 0, 0, 26624, 128, }, /* 306 */ + { 4, 12, 3, 0, 0, 26624, 96, }, /* 307 */ + { 5, 7, 12, 0, 0, 0, 82, }, /* 308 */ + { 5, 12, 3, 0, 0, 26624, 128, }, /* 309 */ + { 38, 13, 12, 0, 0, 34816, 138, }, /* 310 */ + { 38, 7, 12, 0, 0, 34816, 82, }, /* 311 */ + { 38, 12, 3, 0, 0, 26624, 96, }, /* 312 */ + { 38, 6, 12, 0, 0, 34816, 92, }, /* 313 */ + { 38, 26, 12, 0, 0, 28672, 68, }, /* 314 */ + { 38, 21, 12, 0, 0, 28672, 68, }, /* 315 */ + { 38, 21, 12, 0, 0, 28672, 106, }, /* 316 */ + { 38, 21, 12, 0, 0, 28672, 124, }, /* 317 */ + { 38, 6, 12, 0, 0, 34816, 136, }, /* 318 */ + { 38, 12, 3, 0, 0, 26624, 102, }, /* 319 */ + { 38, 23, 12, 0, 0, 34816, 68, }, /* 320 */ + { 110, 7, 12, 0, 0, 34816, 82, }, /* 321 */ + { 110, 12, 3, 0, 0, 26624, 130, }, /* 322 */ + { 110, 12, 3, 0, 0, 26624, 96, }, /* 323 */ + { 110, 6, 12, 0, 0, 34816, 142, }, /* 324 */ + { 110, 12, 3, 0, 0, 26624, 102, }, /* 325 */ + { 110, 21, 12, 0, 0, 34816, 106, }, /* 326 */ + { 110, 21, 12, 0, 0, 34816, 124, }, /* 327 */ + { 42, 7, 12, 0, 0, 34816, 82, }, /* 328 */ + { 42, 12, 3, 0, 0, 26624, 102, }, /* 329 */ + { 42, 21, 12, 0, 0, 34816, 106, }, /* 330 */ + { 3, 24, 12, 0, 0, 0, 122, }, /* 331 */ + { 3, 12, 3, 0, 0, 26624, 102, }, /* 332 */ + { 6, 12, 3, 0, 0, 26624, 130, }, /* 333 */ + { 6, 10, 5, 0, 0, 18432, 144, }, /* 334 */ + { 6, 7, 12, 0, 0, 18432, 82, }, /* 335 */ + { 6, 12, 3, 0, 0, 26624, 96, }, /* 336 */ + { 6, 12, 3, 0, 0, 26624, 146, }, /* 337 */ + { 84, 12, 3, 0, 0, 26798, 96, }, /* 338 */ + { 84, 12, 3, 0, 0, 26795, 96, }, /* 339 */ + { 69, 21, 12, 0, 0, 18615, 124, }, /* 340 */ + { 69, 21, 12, 0, 0, 18618, 124, }, /* 341 */ + { 6, 13, 12, 0, 0, 18576, 138, }, /* 342 */ + { 6, 21, 12, 0, 0, 18432, 68, }, /* 343 */ + { 6, 6, 12, 0, 0, 18432, 92, }, /* 344 */ + { 7, 7, 12, 0, 0, 18432, 82, }, /* 345 */ + { 7, 12, 3, 0, 0, 26624, 130, }, /* 346 */ + { 7, 10, 5, 0, 0, 18432, 144, }, /* 347 */ + { 7, 12, 3, 0, 0, 26624, 96, }, /* 348 */ + { 7, 10, 3, 0, 0, 18432, 148, }, /* 349 */ + { 7, 12, 3, 0, 0, 26624, 146, }, /* 350 */ + { 7, 13, 12, 0, 0, 18546, 138, }, /* 351 */ + { 7, 23, 12, 0, 0, 14336, 68, }, /* 352 */ + { 7, 15, 12, 0, 0, 18432, 68, }, /* 353 */ + { 7, 26, 12, 0, 0, 18432, 68, }, /* 354 */ + { 7, 21, 12, 0, 0, 18432, 68, }, /* 355 */ + { 7, 12, 3, 0, 0, 26624, 102, }, /* 356 */ + { 8, 12, 3, 0, 0, 26624, 130, }, /* 357 */ + { 8, 10, 5, 0, 0, 18432, 144, }, /* 358 */ + { 8, 7, 12, 0, 0, 18432, 82, }, /* 359 */ + { 8, 12, 3, 0, 0, 26624, 96, }, /* 360 */ + { 8, 12, 3, 0, 0, 26624, 146, }, /* 361 */ + { 8, 13, 12, 0, 0, 18519, 138, }, /* 362 */ + { 8, 21, 12, 0, 0, 18432, 68, }, /* 363 */ + { 9, 12, 3, 0, 0, 26624, 130, }, /* 364 */ + { 9, 10, 5, 0, 0, 18432, 144, }, /* 365 */ + { 9, 7, 12, 0, 0, 18432, 82, }, /* 366 */ + { 9, 12, 3, 0, 0, 26624, 96, }, /* 367 */ + { 9, 12, 3, 0, 0, 26624, 146, }, /* 368 */ + { 9, 13, 12, 0, 0, 18516, 138, }, /* 369 */ + { 9, 21, 12, 0, 0, 18432, 68, }, /* 370 */ + { 9, 23, 12, 0, 0, 14336, 68, }, /* 371 */ + { 10, 12, 3, 0, 0, 26624, 130, }, /* 372 */ + { 10, 10, 5, 0, 0, 18432, 144, }, /* 373 */ + { 10, 7, 12, 0, 0, 18432, 82, }, /* 374 */ + { 10, 12, 3, 0, 0, 26624, 96, }, /* 375 */ + { 10, 10, 3, 0, 0, 18432, 148, }, /* 376 */ + { 10, 12, 3, 0, 0, 26624, 146, }, /* 377 */ + { 10, 12, 3, 0, 0, 26624, 150, }, /* 378 */ + { 10, 13, 12, 0, 0, 18432, 138, }, /* 379 */ + { 10, 26, 12, 0, 0, 18432, 68, }, /* 380 */ + { 10, 15, 12, 0, 0, 18432, 68, }, /* 381 */ + { 11, 12, 3, 0, 0, 26624, 130, }, /* 382 */ + { 11, 7, 12, 0, 0, 18432, 82, }, /* 383 */ + { 11, 10, 3, 0, 0, 18432, 148, }, /* 384 */ + { 11, 10, 5, 0, 0, 18432, 144, }, /* 385 */ + { 11, 12, 3, 0, 0, 26624, 146, }, /* 386 */ + { 11, 13, 12, 0, 0, 18513, 138, }, /* 387 */ + { 11, 15, 12, 0, 0, 18513, 68, }, /* 388 */ + { 11, 26, 12, 0, 0, 28753, 68, }, /* 389 */ + { 11, 26, 12, 0, 0, 28672, 68, }, /* 390 */ + { 11, 23, 12, 0, 0, 14336, 68, }, /* 391 */ + { 12, 12, 3, 0, 0, 26624, 130, }, /* 392 */ + { 12, 10, 5, 0, 0, 18432, 144, }, /* 393 */ + { 12, 7, 12, 0, 0, 18432, 82, }, /* 394 */ + { 12, 12, 3, 0, 0, 26624, 96, }, /* 395 */ + { 12, 12, 3, 0, 0, 26624, 146, }, /* 396 */ + { 12, 13, 12, 0, 0, 18432, 138, }, /* 397 */ + { 12, 21, 12, 0, 0, 18432, 68, }, /* 398 */ + { 12, 15, 12, 0, 0, 28672, 68, }, /* 399 */ + { 12, 26, 12, 0, 0, 18432, 68, }, /* 400 */ + { 13, 7, 12, 0, 0, 18432, 82, }, /* 401 */ + { 13, 12, 3, 0, 0, 26624, 130, }, /* 402 */ + { 13, 10, 5, 0, 0, 18432, 144, }, /* 403 */ + { 13, 21, 12, 0, 0, 18432, 68, }, /* 404 */ + { 13, 12, 3, 0, 0, 26624, 96, }, /* 405 */ + { 13, 12, 3, 0, 0, 18432, 130, }, /* 406 */ + { 13, 10, 3, 0, 0, 18432, 148, }, /* 407 */ + { 13, 12, 3, 0, 0, 26624, 146, }, /* 408 */ + { 13, 13, 12, 0, 0, 18528, 138, }, /* 409 */ + { 14, 12, 3, 0, 0, 26624, 130, }, /* 410 */ + { 14, 10, 5, 0, 0, 18432, 144, }, /* 411 */ + { 14, 7, 12, 0, 0, 18432, 82, }, /* 412 */ + { 14, 12, 3, 0, 0, 26624, 146, }, /* 413 */ + { 14, 10, 3, 0, 0, 18432, 148, }, /* 414 */ + { 14, 7, 4, 0, 0, 18432, 82, }, /* 415 */ + { 14, 26, 12, 0, 0, 18432, 68, }, /* 416 */ + { 14, 15, 12, 0, 0, 18432, 68, }, /* 417 */ + { 14, 13, 12, 0, 0, 18432, 138, }, /* 418 */ + { 15, 12, 3, 0, 0, 26624, 130, }, /* 419 */ + { 15, 10, 5, 0, 0, 18432, 144, }, /* 420 */ + { 15, 7, 12, 0, 0, 18432, 82, }, /* 421 */ + { 15, 12, 3, 0, 0, 26624, 146, }, /* 422 */ + { 15, 10, 3, 0, 0, 18432, 148, }, /* 423 */ + { 15, 13, 12, 0, 0, 18432, 138, }, /* 424 */ + { 15, 21, 12, 0, 0, 18432, 68, }, /* 425 */ + { 72, 7, 12, 0, 0, 18432, 82, }, /* 426 */ + { 72, 12, 3, 0, 0, 26624, 130, }, /* 427 */ + { 72, 7, 5, 0, 0, 18432, 152, }, /* 428 */ + { 72, 12, 3, 0, 0, 26624, 154, }, /* 429 */ + { 69, 23, 12, 0, 0, 14336, 68, }, /* 430 */ + { 72, 7, 12, 0, 0, 18432, 156, }, /* 431 */ + { 72, 6, 12, 0, 0, 18432, 136, }, /* 432 */ + { 72, 12, 3, 0, 0, 26624, 96, }, /* 433 */ + { 72, 21, 12, 0, 0, 18432, 68, }, /* 434 */ + { 72, 13, 12, 0, 0, 18432, 138, }, /* 435 */ + { 72, 21, 12, 0, 0, 18432, 106, }, /* 436 */ + { 73, 7, 12, 0, 0, 18432, 82, }, /* 437 */ + { 73, 12, 3, 0, 0, 26624, 130, }, /* 438 */ + { 73, 7, 5, 0, 0, 18432, 152, }, /* 439 */ + { 73, 12, 3, 0, 0, 26624, 146, }, /* 440 */ + { 73, 7, 12, 0, 0, 18432, 156, }, /* 441 */ + { 73, 6, 12, 0, 0, 18432, 136, }, /* 442 */ + { 73, 12, 3, 0, 0, 26624, 96, }, /* 443 */ + { 73, 12, 3, 0, 0, 26624, 102, }, /* 444 */ + { 73, 13, 12, 0, 0, 18432, 138, }, /* 445 */ + { 74, 7, 12, 0, 0, 18432, 82, }, /* 446 */ + { 74, 26, 12, 0, 0, 18432, 68, }, /* 447 */ + { 74, 21, 12, 0, 0, 18432, 68, }, /* 448 */ + { 74, 21, 12, 0, 0, 18432, 106, }, /* 449 */ + { 74, 12, 3, 0, 0, 26624, 96, }, /* 450 */ + { 74, 13, 12, 0, 0, 18432, 138, }, /* 451 */ + { 74, 15, 12, 0, 0, 18432, 68, }, /* 452 */ + { 74, 22, 12, 0, 0, 28672, 158, }, /* 453 */ + { 74, 18, 12, 0, 0, 28672, 158, }, /* 454 */ + { 74, 10, 5, 0, 0, 18432, 160, }, /* 455 */ + { 74, 12, 3, 0, 0, 26624, 130, }, /* 456 */ + { 74, 12, 3, 0, 0, 26624, 162, }, /* 457 */ + { 74, 10, 5, 0, 0, 18432, 144, }, /* 458 */ + { 74, 12, 3, 0, 0, 26624, 128, }, /* 459 */ + { 74, 12, 3, 0, 0, 26624, 146, }, /* 460 */ + { 69, 26, 12, 0, 0, 18432, 68, }, /* 461 */ + { 16, 7, 12, 0, 0, 18432, 82, }, /* 462 */ + { 16, 10, 12, 0, 0, 18432, 144, }, /* 463 */ + { 16, 12, 3, 0, 0, 26624, 130, }, /* 464 */ + { 16, 10, 5, 0, 0, 18432, 144, }, /* 465 */ + { 16, 12, 3, 0, 0, 26624, 96, }, /* 466 */ + { 16, 12, 3, 0, 0, 26624, 146, }, /* 467 */ + { 16, 13, 12, 0, 0, 18549, 138, }, /* 468 */ + { 16, 21, 12, 0, 0, 18432, 124, }, /* 469 */ + { 16, 21, 12, 0, 0, 18432, 68, }, /* 470 */ + { 16, 10, 12, 0, 0, 18432, 164, }, /* 471 */ + { 16, 12, 3, 0, 0, 26624, 128, }, /* 472 */ + { 16, 13, 12, 0, 0, 18432, 138, }, /* 473 */ + { 16, 26, 12, 0, 0, 18432, 68, }, /* 474 */ + { 17, 9, 12, 0, 7264, 18432, 74, }, /* 475 */ + { 17, 5, 12, 0, 3008, 18432, 166, }, /* 476 */ + { 69, 21, 12, 0, 0, 18510, 68, }, /* 477 */ + { 17, 6, 12, 0, 0, 18432, 168, }, /* 478 */ + { 18, 7, 6, 0, 0, 18432, 82, }, /* 479 */ + { 18, 7, 6, 0, 0, 18432, 170, }, /* 480 */ + { 18, 7, 7, 0, 0, 18432, 170, }, /* 481 */ + { 18, 7, 7, 0, 0, 18432, 82, }, /* 482 */ + { 18, 7, 8, 0, 0, 18432, 82, }, /* 483 */ + { 75, 7, 12, 0, 0, 18432, 82, }, /* 484 */ + { 75, 12, 3, 0, 0, 26624, 96, }, /* 485 */ + { 75, 21, 12, 0, 0, 18432, 68, }, /* 486 */ + { 75, 21, 12, 0, 0, 18432, 106, }, /* 487 */ + { 75, 21, 12, 0, 0, 18432, 124, }, /* 488 */ + { 75, 15, 12, 0, 0, 18432, 138, }, /* 489 */ + { 75, 15, 12, 0, 0, 18432, 68, }, /* 490 */ + { 75, 26, 12, 0, 0, 28672, 68, }, /* 491 */ + { 76, 9, 12, 0, 38864, 18432, 172, }, /* 492 */ + { 76, 9, 12, 0, 8, 18432, 172, }, /* 493 */ + { 76, 5, 12, 0, -8, 18432, 70, }, /* 494 */ + { 77, 17, 12, 0, 0, 28672, 126, }, /* 495 */ + { 77, 7, 12, 0, 0, 18432, 82, }, /* 496 */ + { 77, 26, 12, 0, 0, 18432, 68, }, /* 497 */ + { 77, 21, 12, 0, 0, 18432, 124, }, /* 498 */ + { 78, 29, 12, 0, 0, 45056, 52, }, /* 499 */ + { 78, 7, 12, 0, 0, 18432, 82, }, /* 500 */ + { 78, 22, 12, 0, 0, 28672, 158, }, /* 501 */ + { 78, 18, 12, 0, 0, 28672, 158, }, /* 502 */ + { 79, 7, 12, 0, 0, 18432, 82, }, /* 503 */ + { 69, 21, 12, 0, 0, 18432, 106, }, /* 504 */ + { 79, 14, 12, 0, 0, 18432, 82, }, /* 505 */ + { 25, 7, 12, 0, 0, 18432, 82, }, /* 506 */ + { 25, 12, 3, 0, 0, 26624, 130, }, /* 507 */ + { 25, 12, 3, 0, 0, 26624, 146, }, /* 508 */ + { 25, 10, 5, 0, 0, 18432, 174, }, /* 509 */ + { 26, 7, 12, 0, 0, 18432, 82, }, /* 510 */ + { 26, 12, 3, 0, 0, 26624, 130, }, /* 511 */ + { 26, 10, 5, 0, 0, 18432, 176, }, /* 512 */ + { 69, 21, 12, 0, 0, 18573, 124, }, /* 513 */ + { 27, 7, 12, 0, 0, 18432, 82, }, /* 514 */ + { 27, 12, 3, 0, 0, 26624, 130, }, /* 515 */ + { 28, 7, 12, 0, 0, 18432, 82, }, /* 516 */ + { 28, 12, 3, 0, 0, 26624, 130, }, /* 517 */ + { 80, 7, 12, 0, 0, 18432, 82, }, /* 518 */ + { 80, 7, 12, 0, 0, 18432, 140, }, /* 519 */ + { 80, 12, 3, 0, 0, 26624, 100, }, /* 520 */ + { 80, 10, 5, 0, 0, 18432, 144, }, /* 521 */ + { 80, 12, 3, 0, 0, 26624, 130, }, /* 522 */ + { 80, 12, 3, 0, 0, 26624, 96, }, /* 523 */ + { 80, 12, 3, 0, 0, 26624, 146, }, /* 524 */ + { 80, 21, 12, 0, 0, 18432, 106, }, /* 525 */ + { 80, 6, 12, 0, 0, 18432, 142, }, /* 526 */ + { 80, 21, 12, 0, 0, 18432, 68, }, /* 527 */ + { 80, 23, 12, 0, 0, 14336, 68, }, /* 528 */ + { 80, 13, 12, 0, 0, 18432, 138, }, /* 529 */ + { 80, 15, 12, 0, 0, 28672, 68, }, /* 530 */ + { 19, 21, 12, 0, 0, 28672, 68, }, /* 531 */ + { 69, 21, 12, 0, 0, 28777, 106, }, /* 532 */ + { 69, 21, 12, 0, 0, 28777, 124, }, /* 533 */ + { 19, 21, 12, 0, 0, 28672, 106, }, /* 534 */ + { 19, 17, 12, 0, 0, 28672, 126, }, /* 535 */ + { 19, 21, 12, 0, 0, 28672, 124, }, /* 536 */ + { 19, 21, 12, 0, 0, 28672, 178, }, /* 537 */ + { 19, 12, 3, 0, 0, 26624, 180, }, /* 538 */ + { 19, 1, 2, 0, 0, 6144, 66, }, /* 539 */ + { 19, 13, 12, 0, 0, 18432, 138, }, /* 540 */ + { 19, 7, 12, 0, 0, 18432, 82, }, /* 541 */ + { 19, 6, 12, 0, 0, 18432, 136, }, /* 542 */ + { 19, 12, 3, 0, 0, 26624, 182, }, /* 543 */ + { 19, 12, 3, 0, 0, 26624, 130, }, /* 544 */ + { 29, 7, 12, 0, 0, 18432, 82, }, /* 545 */ + { 29, 12, 3, 0, 0, 26624, 130, }, /* 546 */ + { 29, 10, 5, 0, 0, 18432, 144, }, /* 547 */ + { 29, 12, 3, 0, 0, 26624, 96, }, /* 548 */ + { 29, 26, 12, 0, 0, 28672, 68, }, /* 549 */ + { 29, 21, 12, 0, 0, 28672, 124, }, /* 550 */ + { 29, 13, 12, 0, 0, 18432, 138, }, /* 551 */ + { 30, 7, 12, 0, 0, 18432, 82, }, /* 552 */ + { 89, 7, 12, 0, 0, 18432, 82, }, /* 553 */ + { 89, 7, 12, 0, 0, 18432, 156, }, /* 554 */ + { 89, 13, 12, 0, 0, 18432, 138, }, /* 555 */ + { 89, 15, 12, 0, 0, 18432, 138, }, /* 556 */ + { 89, 26, 12, 0, 0, 28672, 68, }, /* 557 */ + { 80, 26, 12, 0, 0, 28672, 68, }, /* 558 */ + { 33, 7, 12, 0, 0, 18432, 82, }, /* 559 */ + { 33, 12, 3, 0, 0, 26624, 130, }, /* 560 */ + { 33, 10, 5, 0, 0, 18432, 144, }, /* 561 */ + { 33, 21, 12, 0, 0, 18432, 68, }, /* 562 */ + { 106, 7, 12, 0, 0, 18432, 82, }, /* 563 */ + { 106, 10, 5, 0, 0, 18432, 144, }, /* 564 */ + { 106, 12, 3, 0, 0, 26624, 130, }, /* 565 */ + { 106, 12, 3, 0, 0, 26624, 184, }, /* 566 */ + { 106, 10, 12, 0, 0, 18432, 144, }, /* 567 */ + { 106, 12, 3, 0, 0, 26624, 96, }, /* 568 */ + { 106, 13, 12, 0, 0, 18432, 138, }, /* 569 */ + { 106, 21, 12, 0, 0, 18432, 68, }, /* 570 */ + { 106, 6, 12, 0, 0, 18432, 136, }, /* 571 */ + { 106, 21, 12, 0, 0, 18432, 124, }, /* 572 */ + { 84, 11, 3, 0, 0, 26624, 186, }, /* 573 */ + { 84, 12, 3, 0, 0, 26624, 130, }, /* 574 */ + { 93, 12, 3, 0, 0, 26624, 130, }, /* 575 */ + { 93, 10, 5, 0, 0, 18432, 144, }, /* 576 */ + { 93, 7, 12, 0, 0, 18432, 82, }, /* 577 */ + { 93, 12, 3, 0, 0, 26624, 96, }, /* 578 */ + { 93, 10, 3, 0, 0, 18432, 148, }, /* 579 */ + { 93, 10, 5, 0, 0, 18432, 174, }, /* 580 */ + { 93, 13, 12, 0, 0, 18432, 138, }, /* 581 */ + { 93, 21, 12, 0, 0, 18432, 124, }, /* 582 */ + { 93, 21, 12, 0, 0, 18432, 68, }, /* 583 */ + { 93, 21, 12, 0, 0, 18432, 106, }, /* 584 */ + { 93, 26, 12, 0, 0, 18432, 68, }, /* 585 */ + { 96, 12, 3, 0, 0, 26624, 130, }, /* 586 */ + { 96, 10, 5, 0, 0, 18432, 144, }, /* 587 */ + { 96, 7, 12, 0, 0, 18432, 82, }, /* 588 */ + { 96, 10, 5, 0, 0, 18432, 174, }, /* 589 */ + { 96, 12, 3, 0, 0, 26624, 146, }, /* 590 */ + { 96, 13, 12, 0, 0, 18432, 138, }, /* 591 */ + { 119, 7, 12, 0, 0, 18432, 82, }, /* 592 */ + { 119, 12, 3, 0, 0, 26624, 102, }, /* 593 */ + { 119, 10, 5, 0, 0, 18432, 144, }, /* 594 */ + { 119, 12, 3, 0, 0, 26624, 130, }, /* 595 */ + { 119, 10, 5, 0, 0, 18432, 176, }, /* 596 */ + { 119, 21, 12, 0, 0, 18432, 68, }, /* 597 */ + { 97, 7, 12, 0, 0, 18432, 82, }, /* 598 */ + { 97, 10, 5, 0, 0, 18432, 144, }, /* 599 */ + { 97, 12, 3, 0, 0, 26624, 130, }, /* 600 */ + { 97, 12, 3, 0, 0, 26624, 188, }, /* 601 */ + { 97, 12, 3, 0, 0, 26624, 96, }, /* 602 */ + { 97, 21, 12, 0, 0, 18432, 124, }, /* 603 */ + { 97, 21, 12, 0, 0, 18432, 106, }, /* 604 */ + { 97, 13, 12, 0, 0, 18432, 138, }, /* 605 */ + { 98, 13, 12, 0, 0, 18432, 138, }, /* 606 */ + { 98, 7, 12, 0, 0, 18432, 82, }, /* 607 */ + { 98, 6, 12, 0, 0, 18432, 92, }, /* 608 */ + { 98, 6, 12, 0, 0, 18432, 94, }, /* 609 */ + { 98, 21, 12, 0, 0, 18432, 124, }, /* 610 */ + { 2, 5, 12, 63, -6222, 18432, 70, }, /* 611 */ + { 2, 5, 12, 67, -6221, 18432, 70, }, /* 612 */ + { 2, 5, 12, 71, -6212, 18432, 70, }, /* 613 */ + { 2, 5, 12, 75, -6210, 18432, 70, }, /* 614 */ + { 2, 5, 12, 79, -6210, 18432, 70, }, /* 615 */ + { 2, 5, 12, 79, -6211, 18432, 70, }, /* 616 */ + { 2, 5, 12, 84, -6204, 18432, 70, }, /* 617 */ + { 2, 5, 12, 88, -6180, 18432, 70, }, /* 618 */ + { 2, 5, 12, 108, 35267, 18432, 70, }, /* 619 */ + { 17, 9, 12, 0, -3008, 18432, 74, }, /* 620 */ + { 96, 21, 12, 0, 0, 18432, 68, }, /* 621 */ + { 84, 12, 3, 0, 0, 26762, 96, }, /* 622 */ + { 84, 12, 3, 0, 0, 26630, 96, }, /* 623 */ + { 69, 21, 12, 0, 0, 18498, 190, }, /* 624 */ + { 84, 12, 3, 0, 0, 26666, 96, }, /* 625 */ + { 84, 12, 3, 0, 0, 26696, 96, }, /* 626 */ + { 84, 12, 3, 0, 0, 26780, 96, }, /* 627 */ + { 69, 10, 5, 0, 0, 18474, 160, }, /* 628 */ + { 69, 7, 12, 0, 0, 18501, 82, }, /* 629 */ + { 69, 7, 12, 0, 0, 18474, 82, }, /* 630 */ + { 69, 7, 12, 0, 0, 18438, 82, }, /* 631 */ + { 69, 7, 12, 0, 0, 18594, 82, }, /* 632 */ + { 69, 7, 12, 0, 0, 18498, 82, }, /* 633 */ + { 84, 12, 3, 0, 0, 26750, 96, }, /* 634 */ + { 69, 10, 5, 0, 0, 18435, 160, }, /* 635 */ + { 84, 12, 3, 0, 0, 26690, 96, }, /* 636 */ + { 69, 7, 12, 0, 0, 18453, 82, }, /* 637 */ + { 2, 5, 12, 0, 0, 18432, 60, }, /* 638 */ + { 1, 6, 12, 0, 0, 18432, 88, }, /* 639 */ + { 2, 6, 12, 0, 0, 18432, 168, }, /* 640 */ + { 0, 5, 12, 0, 35332, 18432, 76, }, /* 641 */ + { 0, 5, 12, 0, 3814, 18432, 76, }, /* 642 */ + { 0, 5, 12, 0, 35384, 18432, 76, }, /* 643 */ + { 0, 5, 12, 0, 0, 18432, 192, }, /* 644 */ + { 0, 6, 12, 0, 0, 18432, 168, }, /* 645 */ + { 0, 6, 12, 0, 0, 18432, 194, }, /* 646 */ + { 1, 6, 12, 0, 0, 18432, 168, }, /* 647 */ + { 84, 12, 3, 0, 0, 26636, 102, }, /* 648 */ + { 84, 12, 3, 0, 0, 26687, 96, }, /* 649 */ + { 84, 12, 3, 0, 0, 26648, 96, }, /* 650 */ + { 0, 9, 12, 92, 1, 18432, 74, }, /* 651 */ + { 0, 5, 12, 92, -1, 18432, 76, }, /* 652 */ + { 0, 5, 12, 0, 0, 18432, 70, }, /* 653 */ + { 0, 5, 12, 92, -58, 18432, 70, }, /* 654 */ + { 0, 9, 12, 0, -7615, 18432, 74, }, /* 655 */ + { 1, 5, 12, 0, 8, 18432, 76, }, /* 656 */ + { 1, 9, 12, 0, -8, 18432, 74, }, /* 657 */ + { 1, 5, 12, 0, 74, 18432, 76, }, /* 658 */ + { 1, 5, 12, 0, 86, 18432, 76, }, /* 659 */ + { 1, 5, 12, 0, 100, 18432, 76, }, /* 660 */ + { 1, 5, 12, 0, 128, 18432, 76, }, /* 661 */ + { 1, 5, 12, 0, 112, 18432, 76, }, /* 662 */ + { 1, 5, 12, 0, 126, 18432, 76, }, /* 663 */ + { 1, 5, 12, 0, 8, 18432, 70, }, /* 664 */ + { 1, 8, 12, 0, -8, 18432, 86, }, /* 665 */ + { 1, 5, 12, 0, 0, 18432, 70, }, /* 666 */ + { 1, 5, 12, 0, 9, 18432, 70, }, /* 667 */ + { 1, 9, 12, 0, -74, 18432, 74, }, /* 668 */ + { 1, 8, 12, 0, -9, 18432, 86, }, /* 669 */ + { 1, 5, 12, 21, -7173, 18432, 76, }, /* 670 */ + { 1, 9, 12, 0, -86, 18432, 74, }, /* 671 */ + { 1, 9, 12, 0, -100, 18432, 74, }, /* 672 */ + { 1, 9, 12, 0, -112, 18432, 74, }, /* 673 */ + { 1, 9, 12, 0, -128, 18432, 74, }, /* 674 */ + { 1, 9, 12, 0, -126, 18432, 74, }, /* 675 */ + { 69, 29, 12, 0, 0, 45056, 52, }, /* 676 */ + { 84, 1, 3, 0, 0, 6144, 196, }, /* 677 */ + { 84, 1, 13, 0, 0, 6144, 198, }, /* 678 */ + { 69, 1, 2, 0, 0, 18432, 200, }, /* 679 */ + { 69, 1, 2, 0, 0, 34816, 200, }, /* 680 */ + { 69, 17, 12, 0, 0, 28672, 202, }, /* 681 */ + { 69, 21, 12, 0, 0, 28672, 64, }, /* 682 */ + { 69, 20, 12, 0, 0, 28672, 204, }, /* 683 */ + { 69, 19, 12, 0, 0, 28672, 204, }, /* 684 */ + { 69, 22, 12, 0, 0, 28672, 206, }, /* 685 */ + { 69, 20, 12, 0, 0, 28672, 206, }, /* 686 */ + { 69, 19, 12, 0, 0, 28672, 206, }, /* 687 */ + { 69, 21, 12, 0, 0, 28672, 208, }, /* 688 */ + { 69, 27, 2, 0, 0, 45056, 50, }, /* 689 */ + { 69, 28, 2, 0, 0, 4096, 50, }, /* 690 */ + { 69, 1, 2, 0, 0, 20480, 134, }, /* 691 */ + { 69, 1, 2, 0, 0, 36864, 134, }, /* 692 */ + { 69, 1, 2, 0, 0, 30720, 134, }, /* 693 */ + { 69, 1, 2, 0, 0, 24576, 134, }, /* 694 */ + { 69, 1, 2, 0, 0, 40960, 134, }, /* 695 */ + { 69, 29, 12, 0, 0, 8291, 52, }, /* 696 */ + { 69, 21, 12, 0, 0, 14336, 54, }, /* 697 */ + { 69, 21, 12, 0, 0, 14336, 64, }, /* 698 */ + { 69, 21, 14, 0, 0, 28672, 210, }, /* 699 */ + { 69, 21, 12, 0, 0, 28672, 212, }, /* 700 */ + { 69, 16, 12, 0, 0, 28672, 138, }, /* 701 */ + { 69, 16, 12, 0, 0, 28672, 214, }, /* 702 */ + { 69, 25, 12, 0, 0, 8192, 64, }, /* 703 */ + { 69, 22, 12, 0, 0, 28672, 216, }, /* 704 */ + { 69, 18, 12, 0, 0, 28672, 216, }, /* 705 */ + { 69, 21, 12, 0, 0, 28672, 202, }, /* 706 */ + { 69, 1, 2, 0, 0, 6144, 218, }, /* 707 */ + { 68, 2, 2, 0, 0, 6144, 220, }, /* 708 */ + { 69, 1, 2, 0, 0, 22528, 134, }, /* 709 */ + { 69, 1, 2, 0, 0, 38912, 134, }, /* 710 */ + { 69, 1, 2, 0, 0, 16384, 134, }, /* 711 */ + { 69, 1, 2, 0, 0, 32768, 134, }, /* 712 */ + { 69, 1, 2, 0, 0, 6144, 222, }, /* 713 */ + { 69, 25, 12, 0, 0, 12288, 118, }, /* 714 */ + { 69, 25, 12, 0, 0, 12288, 224, }, /* 715 */ + { 69, 25, 12, 0, 0, 28672, 118, }, /* 716 */ + { 69, 22, 12, 0, 0, 28672, 226, }, /* 717 */ + { 69, 18, 12, 0, 0, 28672, 226, }, /* 718 */ + { 68, 2, 12, 0, 0, 14336, 0, }, /* 719 */ + { 84, 12, 3, 0, 0, 26624, 228, }, /* 720 */ + { 84, 11, 3, 0, 0, 26624, 120, }, /* 721 */ + { 84, 11, 3, 0, 0, 26624, 230, }, /* 722 */ + { 84, 12, 3, 0, 0, 26753, 102, }, /* 723 */ + { 69, 26, 12, 0, 0, 28672, 68, }, /* 724 */ + { 69, 9, 12, 0, 0, 18432, 112, }, /* 725 */ + { 69, 5, 12, 0, 0, 18432, 232, }, /* 726 */ + { 69, 25, 12, 0, 0, 28672, 234, }, /* 727 */ + { 69, 26, 14, 0, 0, 28672, 236, }, /* 728 */ + { 1, 9, 12, 96, -7517, 18432, 74, }, /* 729 */ + { 69, 26, 12, 0, 0, 28672, 118, }, /* 730 */ + { 0, 9, 12, 100, 0, 18432, 74, }, /* 731 */ + { 0, 9, 12, 104, -8262, 18432, 74, }, /* 732 */ + { 69, 26, 12, 0, 0, 14336, 238, }, /* 733 */ + { 0, 9, 12, 0, 28, 18432, 74, }, /* 734 */ + { 69, 7, 12, 0, 0, 18432, 240, }, /* 735 */ + { 69, 5, 14, 0, 0, 18432, 242, }, /* 736 */ + { 69, 5, 12, 0, 0, 18432, 244, }, /* 737 */ + { 0, 5, 12, 0, -28, 18432, 76, }, /* 738 */ + { 0, 14, 12, 0, 16, 18432, 74, }, /* 739 */ + { 0, 14, 12, 0, -16, 18432, 76, }, /* 740 */ + { 0, 14, 12, 0, 0, 18432, 82, }, /* 741 */ + { 69, 25, 14, 0, 0, 28672, 246, }, /* 742 */ + { 69, 26, 14, 0, 0, 28672, 246, }, /* 743 */ + { 69, 26, 12, 0, 0, 28672, 64, }, /* 744 */ + { 69, 25, 12, 0, 0, 28672, 248, }, /* 745 */ + { 69, 25, 12, 0, 0, 12288, 250, }, /* 746 */ + { 69, 22, 12, 0, 0, 28672, 248, }, /* 747 */ + { 69, 18, 12, 0, 0, 28672, 248, }, /* 748 */ + { 69, 26, 14, 0, 0, 28672, 252, }, /* 749 */ + { 69, 22, 12, 0, 0, 28672, 254, }, /* 750 */ + { 69, 18, 12, 0, 0, 28672, 254, }, /* 751 */ + { 69, 26, 12, 0, 0, 18432, 54, }, /* 752 */ + { 69, 26, 14, 0, 0, 28672, 256, }, /* 753 */ + { 68, 2, 12, 0, 0, 18432, 258, }, /* 754 */ + { 69, 26, 12, 0, 26, 18432, 260, }, /* 755 */ + { 69, 26, 14, 0, 26, 18432, 262, }, /* 756 */ + { 69, 26, 12, 0, -26, 18432, 264, }, /* 757 */ + { 69, 25, 14, 0, 0, 28672, 266, }, /* 758 */ + { 69, 26, 14, 0, 0, 28672, 268, }, /* 759 */ + { 69, 26, 14, 0, 0, 28672, 270, }, /* 760 */ + { 69, 25, 14, 0, 0, 28672, 268, }, /* 761 */ + { 69, 26, 14, 0, 0, 18432, 256, }, /* 762 */ + { 69, 26, 14, 0, 0, 28672, 272, }, /* 763 */ + { 88, 26, 12, 0, 0, 18432, 54, }, /* 764 */ + { 69, 26, 12, 0, 0, 28672, 216, }, /* 765 */ + { 35, 9, 12, 0, 48, 18432, 74, }, /* 766 */ + { 35, 5, 12, 0, -48, 18432, 76, }, /* 767 */ + { 0, 9, 12, 0, -10743, 18432, 74, }, /* 768 */ + { 0, 9, 12, 0, -3814, 18432, 74, }, /* 769 */ + { 0, 9, 12, 0, -10727, 18432, 74, }, /* 770 */ + { 0, 5, 12, 0, -10795, 18432, 76, }, /* 771 */ + { 0, 5, 12, 0, -10792, 18432, 76, }, /* 772 */ + { 0, 9, 12, 0, -10780, 18432, 74, }, /* 773 */ + { 0, 9, 12, 0, -10749, 18432, 74, }, /* 774 */ + { 0, 9, 12, 0, -10783, 18432, 74, }, /* 775 */ + { 0, 9, 12, 0, -10782, 18432, 74, }, /* 776 */ + { 0, 9, 12, 0, -10815, 18432, 74, }, /* 777 */ + { 34, 5, 12, 0, 0, 18432, 60, }, /* 778 */ + { 34, 26, 12, 0, 0, 28672, 68, }, /* 779 */ + { 34, 12, 3, 0, 0, 26624, 96, }, /* 780 */ + { 34, 21, 12, 0, 0, 28672, 68, }, /* 781 */ + { 34, 15, 12, 0, 0, 28672, 68, }, /* 782 */ + { 17, 5, 12, 0, -7264, 18432, 76, }, /* 783 */ + { 90, 7, 12, 0, 0, 18432, 82, }, /* 784 */ + { 90, 6, 12, 0, 0, 18432, 142, }, /* 785 */ + { 90, 21, 12, 0, 0, 18432, 68, }, /* 786 */ + { 90, 12, 3, 0, 0, 26624, 184, }, /* 787 */ + { 2, 12, 3, 0, 0, 26624, 130, }, /* 788 */ + { 69, 20, 12, 0, 0, 28672, 216, }, /* 789 */ + { 69, 19, 12, 0, 0, 28672, 216, }, /* 790 */ + { 69, 6, 12, 0, 0, 28672, 274, }, /* 791 */ + { 69, 21, 12, 0, 0, 28672, 276, }, /* 792 */ + { 69, 21, 12, 0, 0, 28726, 54, }, /* 793 */ + { 23, 26, 12, 0, 0, 28672, 278, }, /* 794 */ + { 69, 26, 12, 0, 0, 28672, 280, }, /* 795 */ + { 69, 26, 12, 0, 0, 28672, 282, }, /* 796 */ + { 69, 21, 12, 0, 0, 28825, 276, }, /* 797 */ + { 69, 21, 12, 0, 0, 28825, 212, }, /* 798 */ + { 69, 21, 12, 0, 0, 28819, 54, }, /* 799 */ + { 23, 6, 12, 0, 0, 18432, 136, }, /* 800 */ + { 69, 7, 12, 0, 0, 18447, 284, }, /* 801 */ + { 23, 14, 12, 0, 0, 18432, 284, }, /* 802 */ + { 69, 22, 12, 0, 0, 28825, 216, }, /* 803 */ + { 69, 18, 12, 0, 0, 28825, 216, }, /* 804 */ + { 69, 22, 12, 0, 0, 28825, 62, }, /* 805 */ + { 69, 18, 12, 0, 0, 28825, 62, }, /* 806 */ + { 69, 26, 12, 0, 0, 28819, 54, }, /* 807 */ + { 69, 17, 12, 0, 0, 28819, 202, }, /* 808 */ + { 69, 22, 12, 0, 0, 28819, 206, }, /* 809 */ + { 69, 18, 12, 0, 0, 28819, 206, }, /* 810 */ + { 84, 12, 3, 0, 0, 26669, 96, }, /* 811 */ + { 18, 10, 3, 0, 0, 18432, 286, }, /* 812 */ + { 69, 17, 14, 0, 0, 28819, 288, }, /* 813 */ + { 69, 6, 12, 0, 0, 18525, 136, }, /* 814 */ + { 69, 26, 12, 0, 0, 28819, 68, }, /* 815 */ + { 23, 6, 12, 0, 0, 18432, 142, }, /* 816 */ + { 69, 7, 12, 0, 0, 18564, 82, }, /* 817 */ + { 69, 21, 14, 0, 0, 28804, 236, }, /* 818 */ + { 69, 26, 12, 0, 0, 28687, 68, }, /* 819 */ + { 20, 7, 12, 0, 0, 18432, 82, }, /* 820 */ + { 84, 12, 3, 0, 0, 26717, 96, }, /* 821 */ + { 69, 24, 12, 0, 0, 28765, 290, }, /* 822 */ + { 20, 6, 12, 0, 0, 18432, 136, }, /* 823 */ + { 69, 17, 12, 0, 0, 28765, 126, }, /* 824 */ + { 21, 7, 12, 0, 0, 18432, 82, }, /* 825 */ + { 69, 21, 12, 0, 0, 28825, 68, }, /* 826 */ + { 69, 6, 12, 0, 0, 18525, 94, }, /* 827 */ + { 21, 6, 12, 0, 0, 18432, 136, }, /* 828 */ + { 22, 7, 12, 0, 0, 18432, 82, }, /* 829 */ + { 18, 7, 12, 0, 0, 18432, 82, }, /* 830 */ + { 18, 7, 12, 0, 0, 18432, 170, }, /* 831 */ + { 69, 26, 12, 0, 0, 18447, 68, }, /* 832 */ + { 69, 15, 12, 0, 0, 18447, 68, }, /* 833 */ + { 18, 26, 12, 0, 0, 18432, 68, }, /* 834 */ + { 18, 26, 12, 0, 0, 28672, 68, }, /* 835 */ + { 69, 15, 12, 0, 0, 18432, 68, }, /* 836 */ + { 69, 26, 14, 0, 0, 18447, 236, }, /* 837 */ + { 21, 26, 12, 0, 0, 18432, 68, }, /* 838 */ + { 23, 7, 12, 0, 0, 18432, 292, }, /* 839 */ + { 24, 7, 12, 0, 0, 18432, 82, }, /* 840 */ + { 24, 6, 12, 0, 0, 18432, 136, }, /* 841 */ + { 24, 26, 12, 0, 0, 28672, 68, }, /* 842 */ + { 111, 7, 12, 0, 0, 18432, 82, }, /* 843 */ + { 111, 6, 12, 0, 0, 18432, 142, }, /* 844 */ + { 111, 21, 12, 0, 0, 18432, 106, }, /* 845 */ + { 111, 21, 12, 0, 0, 18432, 124, }, /* 846 */ + { 99, 7, 12, 0, 0, 18432, 82, }, /* 847 */ + { 99, 6, 12, 0, 0, 18432, 136, }, /* 848 */ + { 99, 21, 12, 0, 0, 28672, 106, }, /* 849 */ + { 99, 21, 12, 0, 0, 28672, 124, }, /* 850 */ + { 99, 13, 12, 0, 0, 18432, 138, }, /* 851 */ + { 2, 9, 12, 108, 1, 18432, 74, }, /* 852 */ + { 2, 5, 12, 108, -35267, 18432, 76, }, /* 853 */ + { 2, 7, 12, 0, 0, 18432, 82, }, /* 854 */ + { 2, 21, 12, 0, 0, 28672, 68, }, /* 855 */ + { 2, 12, 3, 0, 0, 26624, 96, }, /* 856 */ + { 2, 6, 12, 0, 0, 28672, 92, }, /* 857 */ + { 2, 6, 12, 0, 0, 18432, 88, }, /* 858 */ + { 112, 7, 12, 0, 0, 18432, 82, }, /* 859 */ + { 112, 14, 12, 0, 0, 18432, 82, }, /* 860 */ + { 112, 12, 3, 0, 0, 26624, 96, }, /* 861 */ + { 112, 21, 12, 0, 0, 18432, 68, }, /* 862 */ + { 112, 21, 12, 0, 0, 18432, 124, }, /* 863 */ + { 112, 21, 12, 0, 0, 18432, 106, }, /* 864 */ + { 69, 24, 12, 0, 0, 28762, 56, }, /* 865 */ + { 0, 9, 12, 0, -35332, 18432, 74, }, /* 866 */ + { 69, 24, 12, 0, 0, 18432, 56, }, /* 867 */ + { 0, 9, 12, 0, -42280, 18432, 74, }, /* 868 */ + { 0, 5, 12, 0, 48, 18432, 76, }, /* 869 */ + { 0, 9, 12, 0, -42308, 18432, 74, }, /* 870 */ + { 0, 9, 12, 0, -42319, 18432, 74, }, /* 871 */ + { 0, 9, 12, 0, -42315, 18432, 74, }, /* 872 */ + { 0, 9, 12, 0, -42305, 18432, 74, }, /* 873 */ + { 0, 9, 12, 0, -42258, 18432, 74, }, /* 874 */ + { 0, 9, 12, 0, -42282, 18432, 74, }, /* 875 */ + { 0, 9, 12, 0, -42261, 18432, 74, }, /* 876 */ + { 0, 9, 12, 0, 928, 18432, 74, }, /* 877 */ + { 0, 9, 12, 0, -48, 18432, 74, }, /* 878 */ + { 0, 9, 12, 0, -42307, 18432, 74, }, /* 879 */ + { 0, 9, 12, 0, -35384, 18432, 74, }, /* 880 */ + { 36, 7, 12, 0, 0, 18432, 82, }, /* 881 */ + { 36, 12, 3, 0, 0, 26624, 130, }, /* 882 */ + { 36, 12, 3, 0, 0, 26624, 184, }, /* 883 */ + { 36, 10, 5, 0, 0, 18432, 144, }, /* 884 */ + { 36, 26, 12, 0, 0, 28672, 68, }, /* 885 */ + { 69, 15, 12, 0, 0, 18612, 68, }, /* 886 */ + { 69, 15, 12, 0, 0, 18609, 68, }, /* 887 */ + { 69, 26, 12, 0, 0, 18600, 68, }, /* 888 */ + { 69, 23, 12, 0, 0, 14504, 68, }, /* 889 */ + { 69, 26, 12, 0, 0, 14504, 68, }, /* 890 */ + { 37, 7, 12, 0, 0, 18432, 82, }, /* 891 */ + { 37, 21, 12, 0, 0, 28672, 68, }, /* 892 */ + { 37, 21, 12, 0, 0, 28672, 124, }, /* 893 */ + { 100, 10, 5, 0, 0, 18432, 144, }, /* 894 */ + { 100, 7, 12, 0, 0, 18432, 82, }, /* 895 */ + { 100, 12, 3, 0, 0, 26624, 146, }, /* 896 */ + { 100, 12, 3, 0, 0, 26624, 130, }, /* 897 */ + { 100, 21, 12, 0, 0, 18432, 124, }, /* 898 */ + { 100, 13, 12, 0, 0, 18432, 138, }, /* 899 */ + { 6, 12, 3, 0, 0, 26666, 96, }, /* 900 */ + { 6, 7, 12, 0, 0, 18507, 82, }, /* 901 */ + { 39, 13, 12, 0, 0, 18432, 138, }, /* 902 */ + { 39, 7, 12, 0, 0, 18432, 82, }, /* 903 */ + { 39, 12, 3, 0, 0, 26624, 130, }, /* 904 */ + { 39, 12, 3, 0, 0, 26624, 96, }, /* 905 */ + { 69, 21, 12, 0, 0, 18567, 190, }, /* 906 */ + { 39, 21, 12, 0, 0, 18432, 124, }, /* 907 */ + { 101, 7, 12, 0, 0, 18432, 82, }, /* 908 */ + { 101, 12, 3, 0, 0, 26624, 130, }, /* 909 */ + { 101, 10, 5, 0, 0, 18432, 144, }, /* 910 */ + { 101, 10, 5, 0, 0, 18432, 174, }, /* 911 */ + { 101, 21, 12, 0, 0, 18432, 68, }, /* 912 */ + { 40, 12, 3, 0, 0, 26624, 130, }, /* 913 */ + { 40, 10, 5, 0, 0, 18432, 144, }, /* 914 */ + { 40, 7, 12, 0, 0, 18432, 82, }, /* 915 */ + { 40, 12, 3, 0, 0, 26624, 96, }, /* 916 */ + { 40, 10, 5, 0, 0, 18432, 174, }, /* 917 */ + { 40, 21, 12, 0, 0, 18432, 68, }, /* 918 */ + { 40, 21, 12, 0, 0, 18432, 106, }, /* 919 */ + { 40, 21, 12, 0, 0, 18432, 124, }, /* 920 */ + { 69, 6, 12, 0, 0, 18480, 136, }, /* 921 */ + { 40, 13, 12, 0, 0, 18432, 138, }, /* 922 */ + { 16, 6, 12, 0, 0, 18432, 136, }, /* 923 */ + { 105, 7, 12, 0, 0, 18432, 82, }, /* 924 */ + { 105, 12, 3, 0, 0, 26624, 130, }, /* 925 */ + { 105, 10, 5, 0, 0, 18432, 144, }, /* 926 */ + { 105, 13, 12, 0, 0, 18432, 138, }, /* 927 */ + { 105, 21, 12, 0, 0, 18432, 68, }, /* 928 */ + { 105, 21, 12, 0, 0, 18432, 124, }, /* 929 */ + { 107, 7, 12, 0, 0, 18432, 82, }, /* 930 */ + { 107, 12, 3, 0, 0, 26624, 130, }, /* 931 */ + { 107, 7, 12, 0, 0, 18432, 156, }, /* 932 */ + { 107, 12, 3, 0, 0, 26624, 96, }, /* 933 */ + { 107, 7, 12, 0, 0, 18432, 294, }, /* 934 */ + { 107, 6, 12, 0, 0, 18432, 136, }, /* 935 */ + { 107, 21, 12, 0, 0, 18432, 68, }, /* 936 */ + { 107, 21, 12, 0, 0, 18432, 106, }, /* 937 */ + { 113, 7, 12, 0, 0, 18432, 82, }, /* 938 */ + { 113, 10, 5, 0, 0, 18432, 144, }, /* 939 */ + { 113, 12, 3, 0, 0, 26624, 130, }, /* 940 */ + { 113, 21, 12, 0, 0, 18432, 124, }, /* 941 */ + { 113, 6, 12, 0, 0, 18432, 136, }, /* 942 */ + { 113, 12, 3, 0, 0, 26624, 146, }, /* 943 */ + { 0, 5, 12, 0, -928, 18432, 76, }, /* 944 */ + { 76, 5, 12, 0, -38864, 18432, 70, }, /* 945 */ + { 113, 10, 5, 0, 0, 18432, 160, }, /* 946 */ + { 113, 13, 12, 0, 0, 18432, 138, }, /* 947 */ + { 18, 7, 9, 0, 0, 18432, 82, }, /* 948 */ + { 18, 7, 10, 0, 0, 18432, 82, }, /* 949 */ + { 68, 4, 12, 0, 0, 18432, 0, }, /* 950 */ + { 68, 3, 12, 0, 0, 18432, 0, }, /* 951 */ + { 23, 7, 12, 0, 0, 18432, 284, }, /* 952 */ + { 71, 25, 12, 0, 0, 12288, 118, }, /* 953 */ + { 3, 7, 12, 0, 0, 0, 296, }, /* 954 */ + { 69, 18, 12, 0, 0, 28705, 54, }, /* 955 */ + { 69, 22, 12, 0, 0, 28705, 54, }, /* 956 */ + { 68, 2, 12, 0, 0, 6144, 298, }, /* 957 */ + { 3, 7, 12, 0, 0, 39, 82, }, /* 958 */ + { 3, 26, 12, 0, 0, 28711, 68, }, /* 959 */ + { 84, 12, 3, 0, 0, 26624, 180, }, /* 960 */ + { 84, 12, 3, 0, 0, 26624, 300, }, /* 961 */ + { 69, 21, 12, 0, 0, 28672, 68, }, /* 962 */ + { 69, 21, 12, 0, 0, 28672, 122, }, /* 963 */ + { 69, 22, 12, 0, 0, 28672, 68, }, /* 964 */ + { 69, 18, 12, 0, 0, 28672, 68, }, /* 965 */ + { 69, 17, 12, 0, 0, 28672, 126, }, /* 966 */ + { 69, 22, 12, 0, 0, 28672, 302, }, /* 967 */ + { 69, 18, 12, 0, 0, 28672, 302, }, /* 968 */ + { 69, 21, 12, 0, 0, 8192, 106, }, /* 969 */ + { 69, 21, 12, 0, 0, 8192, 304, }, /* 970 */ + { 69, 21, 12, 0, 0, 8192, 306, }, /* 971 */ + { 69, 21, 12, 0, 0, 28672, 124, }, /* 972 */ + { 69, 22, 12, 0, 0, 28672, 158, }, /* 973 */ + { 69, 18, 12, 0, 0, 28672, 158, }, /* 974 */ + { 69, 21, 12, 0, 0, 14336, 68, }, /* 975 */ + { 69, 21, 12, 0, 0, 28672, 118, }, /* 976 */ + { 69, 17, 12, 0, 0, 12288, 224, }, /* 977 */ + { 69, 25, 12, 0, 0, 28672, 226, }, /* 978 */ + { 69, 21, 12, 0, 0, 28672, 302, }, /* 979 */ + { 69, 21, 12, 0, 0, 28672, 308, }, /* 980 */ + { 69, 17, 12, 0, 0, 12288, 126, }, /* 981 */ + { 69, 21, 12, 0, 0, 8192, 68, }, /* 982 */ + { 69, 13, 12, 0, 0, 10240, 310, }, /* 983 */ + { 0, 9, 12, 0, 32, 18432, 312, }, /* 984 */ + { 69, 24, 12, 0, 0, 28672, 314, }, /* 985 */ + { 0, 5, 12, 0, -32, 18432, 316, }, /* 986 */ + { 69, 21, 12, 0, 0, 28825, 124, }, /* 987 */ + { 69, 22, 12, 0, 0, 28825, 318, }, /* 988 */ + { 69, 18, 12, 0, 0, 28825, 318, }, /* 989 */ + { 69, 21, 12, 0, 0, 28825, 106, }, /* 990 */ + { 69, 6, 3, 0, 0, 18525, 320, }, /* 991 */ + { 69, 1, 2, 0, 0, 28672, 322, }, /* 992 */ + { 31, 7, 12, 0, 0, 18432, 82, }, /* 993 */ + { 69, 21, 12, 0, 0, 18552, 68, }, /* 994 */ + { 69, 21, 12, 0, 0, 28792, 68, }, /* 995 */ + { 69, 21, 12, 0, 0, 18483, 68, }, /* 996 */ + { 69, 15, 12, 0, 0, 18555, 68, }, /* 997 */ + { 69, 26, 12, 0, 0, 18483, 68, }, /* 998 */ + { 1, 14, 12, 0, 0, 28672, 82, }, /* 999 */ + { 1, 15, 12, 0, 0, 28672, 68, }, /* 1000 */ + { 1, 26, 12, 0, 0, 28672, 68, }, /* 1001 */ + { 1, 26, 12, 0, 0, 18432, 68, }, /* 1002 */ + { 102, 7, 12, 0, 0, 18432, 82, }, /* 1003 */ + { 103, 7, 12, 0, 0, 18432, 82, }, /* 1004 */ + { 84, 12, 3, 0, 0, 26651, 96, }, /* 1005 */ + { 69, 15, 12, 0, 0, 10267, 68, }, /* 1006 */ + { 81, 7, 12, 0, 0, 18432, 82, }, /* 1007 */ + { 81, 15, 12, 0, 0, 18432, 68, }, /* 1008 */ + { 82, 7, 12, 0, 0, 18432, 82, }, /* 1009 */ + { 82, 14, 12, 0, 0, 18432, 82, }, /* 1010 */ + { 53, 7, 12, 0, 0, 18432, 82, }, /* 1011 */ + { 53, 12, 3, 0, 0, 26624, 130, }, /* 1012 */ + { 85, 7, 12, 0, 0, 18432, 82, }, /* 1013 */ + { 85, 21, 12, 0, 0, 18432, 106, }, /* 1014 */ + { 91, 7, 12, 0, 0, 18432, 82, }, /* 1015 */ + { 91, 21, 12, 0, 0, 18432, 106, }, /* 1016 */ + { 91, 14, 12, 0, 0, 18432, 82, }, /* 1017 */ + { 83, 9, 12, 0, 40, 18432, 74, }, /* 1018 */ + { 83, 5, 12, 0, -40, 18432, 76, }, /* 1019 */ + { 86, 7, 12, 0, 0, 18432, 82, }, /* 1020 */ + { 87, 7, 12, 0, 0, 18432, 82, }, /* 1021 */ + { 87, 13, 12, 0, 0, 18432, 138, }, /* 1022 */ + { 145, 9, 12, 0, 40, 18432, 74, }, /* 1023 */ + { 145, 5, 12, 0, -40, 18432, 76, }, /* 1024 */ + { 127, 7, 12, 0, 0, 18432, 82, }, /* 1025 */ + { 125, 7, 12, 0, 0, 18432, 82, }, /* 1026 */ + { 125, 21, 12, 0, 0, 18432, 68, }, /* 1027 */ + { 161, 9, 12, 0, 39, 18432, 74, }, /* 1028 */ + { 161, 5, 12, 0, -39, 18432, 76, }, /* 1029 */ + { 49, 7, 12, 0, 0, 18432, 82, }, /* 1030 */ + { 0, 6, 12, 0, 0, 18432, 94, }, /* 1031 */ + { 32, 7, 12, 0, 0, 34816, 82, }, /* 1032 */ + { 114, 7, 12, 0, 0, 34816, 82, }, /* 1033 */ + { 114, 21, 12, 0, 0, 34816, 106, }, /* 1034 */ + { 114, 15, 12, 0, 0, 34816, 68, }, /* 1035 */ + { 133, 7, 12, 0, 0, 34816, 82, }, /* 1036 */ + { 133, 26, 12, 0, 0, 34816, 68, }, /* 1037 */ + { 133, 15, 12, 0, 0, 34816, 68, }, /* 1038 */ + { 132, 7, 12, 0, 0, 34816, 82, }, /* 1039 */ + { 132, 15, 12, 0, 0, 34816, 68, }, /* 1040 */ + { 139, 7, 12, 0, 0, 34816, 82, }, /* 1041 */ + { 139, 15, 12, 0, 0, 34816, 68, }, /* 1042 */ + { 95, 7, 12, 0, 0, 34816, 82, }, /* 1043 */ + { 95, 15, 12, 0, 0, 34816, 68, }, /* 1044 */ + { 95, 21, 12, 0, 0, 28672, 106, }, /* 1045 */ + { 104, 7, 12, 0, 0, 34816, 82, }, /* 1046 */ + { 104, 21, 12, 0, 0, 34816, 68, }, /* 1047 */ + { 122, 7, 12, 0, 0, 34816, 82, }, /* 1048 */ + { 121, 7, 12, 0, 0, 34816, 82, }, /* 1049 */ + { 121, 15, 12, 0, 0, 34816, 68, }, /* 1050 */ + { 92, 7, 12, 0, 0, 34816, 82, }, /* 1051 */ + { 92, 12, 3, 0, 0, 26624, 130, }, /* 1052 */ + { 92, 12, 3, 0, 0, 26624, 102, }, /* 1053 */ + { 92, 12, 3, 0, 0, 26624, 184, }, /* 1054 */ + { 92, 15, 12, 0, 0, 34816, 68, }, /* 1055 */ + { 92, 21, 12, 0, 0, 34816, 68, }, /* 1056 */ + { 92, 21, 12, 0, 0, 34816, 124, }, /* 1057 */ + { 115, 7, 12, 0, 0, 34816, 82, }, /* 1058 */ + { 115, 15, 12, 0, 0, 34816, 68, }, /* 1059 */ + { 115, 21, 12, 0, 0, 34816, 68, }, /* 1060 */ + { 131, 7, 12, 0, 0, 34816, 82, }, /* 1061 */ + { 131, 15, 12, 0, 0, 34816, 68, }, /* 1062 */ + { 51, 7, 12, 0, 0, 34816, 82, }, /* 1063 */ + { 51, 26, 12, 0, 0, 34816, 68, }, /* 1064 */ + { 51, 12, 3, 0, 0, 26624, 96, }, /* 1065 */ + { 51, 15, 12, 0, 0, 34816, 68, }, /* 1066 */ + { 51, 21, 12, 0, 0, 34816, 106, }, /* 1067 */ + { 51, 21, 12, 0, 0, 34918, 106, }, /* 1068 */ + { 51, 21, 12, 0, 0, 34816, 68, }, /* 1069 */ + { 108, 7, 12, 0, 0, 34816, 82, }, /* 1070 */ + { 108, 21, 12, 0, 0, 28672, 68, }, /* 1071 */ + { 108, 21, 12, 0, 0, 28672, 106, }, /* 1072 */ + { 116, 7, 12, 0, 0, 34816, 82, }, /* 1073 */ + { 116, 15, 12, 0, 0, 34816, 68, }, /* 1074 */ + { 117, 7, 12, 0, 0, 34816, 82, }, /* 1075 */ + { 117, 15, 12, 0, 0, 34816, 68, }, /* 1076 */ + { 54, 7, 12, 0, 0, 34816, 82, }, /* 1077 */ + { 54, 21, 12, 0, 0, 34816, 106, }, /* 1078 */ + { 54, 15, 12, 0, 0, 34816, 68, }, /* 1079 */ + { 118, 7, 12, 0, 0, 34816, 82, }, /* 1080 */ + { 140, 9, 12, 0, 64, 34816, 74, }, /* 1081 */ + { 140, 5, 12, 0, -64, 34816, 76, }, /* 1082 */ + { 140, 15, 12, 0, 0, 34816, 68, }, /* 1083 */ + { 62, 7, 12, 0, 0, 0, 82, }, /* 1084 */ + { 62, 7, 12, 0, 0, 0, 294, }, /* 1085 */ + { 62, 12, 3, 0, 0, 26624, 128, }, /* 1086 */ + { 62, 13, 12, 0, 0, 2048, 138, }, /* 1087 */ + { 3, 15, 12, 0, 0, 2048, 68, }, /* 1088 */ + { 65, 7, 12, 0, 0, 34816, 82, }, /* 1089 */ + { 65, 12, 3, 0, 0, 26624, 130, }, /* 1090 */ + { 65, 17, 12, 0, 0, 34816, 126, }, /* 1091 */ + { 152, 7, 12, 0, 0, 34816, 82, }, /* 1092 */ + { 152, 15, 12, 0, 0, 34816, 68, }, /* 1093 */ + { 63, 7, 12, 0, 0, 0, 82, }, /* 1094 */ + { 63, 12, 3, 0, 0, 26624, 96, }, /* 1095 */ + { 63, 15, 12, 0, 0, 0, 68, }, /* 1096 */ + { 63, 21, 12, 0, 0, 0, 124, }, /* 1097 */ + { 67, 7, 12, 0, 0, 34816, 82, }, /* 1098 */ + { 67, 12, 3, 0, 0, 26624, 96, }, /* 1099 */ + { 67, 21, 12, 0, 0, 34816, 124, }, /* 1100 */ + { 156, 7, 12, 0, 0, 34816, 82, }, /* 1101 */ + { 156, 15, 12, 0, 0, 34816, 68, }, /* 1102 */ + { 153, 7, 12, 0, 0, 34816, 82, }, /* 1103 */ + { 120, 10, 5, 0, 0, 18432, 144, }, /* 1104 */ + { 120, 12, 3, 0, 0, 26624, 130, }, /* 1105 */ + { 120, 7, 12, 0, 0, 18432, 82, }, /* 1106 */ + { 120, 12, 3, 0, 0, 26624, 146, }, /* 1107 */ + { 120, 21, 12, 0, 0, 18432, 124, }, /* 1108 */ + { 120, 21, 12, 0, 0, 18432, 106, }, /* 1109 */ + { 120, 15, 12, 0, 0, 28672, 68, }, /* 1110 */ + { 120, 13, 12, 0, 0, 18432, 138, }, /* 1111 */ + { 120, 12, 3, 0, 0, 26624, 184, }, /* 1112 */ + { 41, 12, 3, 0, 0, 26624, 130, }, /* 1113 */ + { 41, 10, 5, 0, 0, 18432, 144, }, /* 1114 */ + { 41, 7, 12, 0, 0, 18432, 82, }, /* 1115 */ + { 41, 12, 3, 0, 0, 26624, 146, }, /* 1116 */ + { 41, 12, 3, 0, 0, 26624, 96, }, /* 1117 */ + { 41, 21, 12, 0, 0, 18432, 68, }, /* 1118 */ + { 41, 1, 4, 0, 0, 18432, 132, }, /* 1119 */ + { 41, 21, 12, 0, 0, 18432, 124, }, /* 1120 */ + { 124, 7, 12, 0, 0, 18432, 82, }, /* 1121 */ + { 124, 13, 12, 0, 0, 18432, 138, }, /* 1122 */ + { 43, 12, 3, 0, 0, 26624, 130, }, /* 1123 */ + { 43, 7, 12, 0, 0, 18432, 82, }, /* 1124 */ + { 43, 10, 5, 0, 0, 18432, 144, }, /* 1125 */ + { 43, 12, 3, 0, 0, 26624, 146, }, /* 1126 */ + { 43, 13, 12, 0, 0, 18432, 138, }, /* 1127 */ + { 43, 21, 12, 0, 0, 18432, 68, }, /* 1128 */ + { 43, 21, 12, 0, 0, 18432, 124, }, /* 1129 */ + { 50, 7, 12, 0, 0, 18432, 82, }, /* 1130 */ + { 50, 12, 3, 0, 0, 26624, 96, }, /* 1131 */ + { 50, 21, 12, 0, 0, 18432, 68, }, /* 1132 */ + { 44, 12, 3, 0, 0, 26624, 130, }, /* 1133 */ + { 44, 10, 5, 0, 0, 18432, 144, }, /* 1134 */ + { 44, 7, 12, 0, 0, 18432, 82, }, /* 1135 */ + { 44, 10, 5, 0, 0, 18432, 174, }, /* 1136 */ + { 44, 7, 4, 0, 0, 18432, 82, }, /* 1137 */ + { 44, 21, 12, 0, 0, 18432, 124, }, /* 1138 */ + { 44, 21, 12, 0, 0, 18432, 68, }, /* 1139 */ + { 44, 12, 3, 0, 0, 26624, 102, }, /* 1140 */ + { 44, 12, 3, 0, 0, 26624, 96, }, /* 1141 */ + { 44, 13, 12, 0, 0, 18432, 138, }, /* 1142 */ + { 15, 15, 12, 0, 0, 18432, 68, }, /* 1143 */ + { 48, 7, 12, 0, 0, 18432, 82, }, /* 1144 */ + { 48, 10, 5, 0, 0, 18432, 144, }, /* 1145 */ + { 48, 12, 3, 0, 0, 26624, 130, }, /* 1146 */ + { 48, 10, 5, 0, 0, 18432, 174, }, /* 1147 */ + { 48, 12, 3, 0, 0, 26624, 96, }, /* 1148 */ + { 48, 21, 12, 0, 0, 18432, 124, }, /* 1149 */ + { 48, 21, 12, 0, 0, 18432, 106, }, /* 1150 */ + { 48, 21, 12, 0, 0, 18432, 68, }, /* 1151 */ + { 57, 7, 12, 0, 0, 18432, 82, }, /* 1152 */ + { 57, 21, 12, 0, 0, 18432, 124, }, /* 1153 */ + { 55, 7, 12, 0, 0, 18432, 82, }, /* 1154 */ + { 55, 12, 3, 0, 0, 26624, 130, }, /* 1155 */ + { 55, 10, 5, 0, 0, 18432, 144, }, /* 1156 */ + { 55, 12, 3, 0, 0, 26624, 96, }, /* 1157 */ + { 55, 12, 3, 0, 0, 26624, 146, }, /* 1158 */ + { 55, 13, 12, 0, 0, 18432, 138, }, /* 1159 */ + { 47, 12, 3, 0, 0, 26624, 130, }, /* 1160 */ + { 47, 12, 3, 0, 0, 26705, 130, }, /* 1161 */ + { 47, 10, 5, 0, 0, 18432, 144, }, /* 1162 */ + { 47, 10, 5, 0, 0, 18513, 144, }, /* 1163 */ + { 47, 7, 12, 0, 0, 18432, 82, }, /* 1164 */ + { 84, 12, 3, 0, 0, 26705, 102, }, /* 1165 */ + { 47, 12, 3, 0, 0, 26705, 96, }, /* 1166 */ + { 47, 10, 3, 0, 0, 18432, 148, }, /* 1167 */ + { 47, 10, 5, 0, 0, 18432, 174, }, /* 1168 */ + { 47, 7, 12, 0, 0, 18432, 324, }, /* 1169 */ + { 47, 12, 3, 0, 0, 26624, 96, }, /* 1170 */ + { 144, 7, 12, 0, 0, 18432, 82, }, /* 1171 */ + { 144, 10, 5, 0, 0, 18432, 144, }, /* 1172 */ + { 144, 12, 3, 0, 0, 26624, 130, }, /* 1173 */ + { 144, 12, 3, 0, 0, 26624, 146, }, /* 1174 */ + { 144, 12, 3, 0, 0, 26624, 96, }, /* 1175 */ + { 144, 21, 12, 0, 0, 18432, 124, }, /* 1176 */ + { 144, 21, 12, 0, 0, 18432, 106, }, /* 1177 */ + { 144, 21, 12, 0, 0, 18432, 68, }, /* 1178 */ + { 144, 13, 12, 0, 0, 18432, 138, }, /* 1179 */ + { 144, 12, 3, 0, 0, 26624, 102, }, /* 1180 */ + { 56, 7, 12, 0, 0, 18432, 82, }, /* 1181 */ + { 56, 10, 3, 0, 0, 18432, 148, }, /* 1182 */ + { 56, 10, 5, 0, 0, 18432, 144, }, /* 1183 */ + { 56, 12, 3, 0, 0, 26624, 130, }, /* 1184 */ + { 56, 12, 3, 0, 0, 26624, 146, }, /* 1185 */ + { 56, 12, 3, 0, 0, 26624, 96, }, /* 1186 */ + { 56, 21, 12, 0, 0, 18432, 68, }, /* 1187 */ + { 56, 13, 12, 0, 0, 18432, 138, }, /* 1188 */ + { 135, 7, 12, 0, 0, 18432, 82, }, /* 1189 */ + { 135, 10, 3, 0, 0, 18432, 148, }, /* 1190 */ + { 135, 10, 5, 0, 0, 18432, 144, }, /* 1191 */ + { 135, 12, 3, 0, 0, 26624, 130, }, /* 1192 */ + { 135, 12, 3, 0, 0, 26624, 146, }, /* 1193 */ + { 135, 12, 3, 0, 0, 26624, 96, }, /* 1194 */ + { 135, 21, 12, 0, 0, 18432, 68, }, /* 1195 */ + { 135, 21, 12, 0, 0, 18432, 124, }, /* 1196 */ + { 135, 21, 12, 0, 0, 18432, 106, }, /* 1197 */ + { 135, 21, 12, 0, 0, 18432, 178, }, /* 1198 */ + { 52, 7, 12, 0, 0, 18432, 82, }, /* 1199 */ + { 52, 10, 5, 0, 0, 18432, 144, }, /* 1200 */ + { 52, 12, 3, 0, 0, 26624, 130, }, /* 1201 */ + { 52, 12, 3, 0, 0, 26624, 146, }, /* 1202 */ + { 52, 21, 12, 0, 0, 18432, 124, }, /* 1203 */ + { 52, 21, 12, 0, 0, 18432, 68, }, /* 1204 */ + { 52, 13, 12, 0, 0, 18432, 138, }, /* 1205 */ + { 45, 7, 12, 0, 0, 18432, 82, }, /* 1206 */ + { 45, 12, 3, 0, 0, 26624, 130, }, /* 1207 */ + { 45, 10, 5, 0, 0, 18432, 144, }, /* 1208 */ + { 45, 10, 5, 0, 0, 18432, 174, }, /* 1209 */ + { 45, 12, 3, 0, 0, 26624, 96, }, /* 1210 */ + { 45, 21, 12, 0, 0, 18432, 68, }, /* 1211 */ + { 45, 13, 12, 0, 0, 18432, 138, }, /* 1212 */ + { 137, 7, 12, 0, 0, 18432, 82, }, /* 1213 */ + { 137, 12, 3, 0, 0, 26624, 130, }, /* 1214 */ + { 137, 10, 12, 0, 0, 18432, 144, }, /* 1215 */ + { 137, 10, 5, 0, 0, 18432, 144, }, /* 1216 */ + { 137, 12, 3, 0, 0, 26624, 146, }, /* 1217 */ + { 137, 13, 12, 0, 0, 18432, 138, }, /* 1218 */ + { 137, 15, 12, 0, 0, 18432, 68, }, /* 1219 */ + { 137, 21, 12, 0, 0, 18432, 124, }, /* 1220 */ + { 137, 26, 12, 0, 0, 18432, 68, }, /* 1221 */ + { 60, 7, 12, 0, 0, 18432, 82, }, /* 1222 */ + { 60, 10, 5, 0, 0, 18432, 144, }, /* 1223 */ + { 60, 12, 3, 0, 0, 26624, 130, }, /* 1224 */ + { 60, 12, 3, 0, 0, 26624, 146, }, /* 1225 */ + { 60, 12, 3, 0, 0, 26624, 96, }, /* 1226 */ + { 60, 21, 12, 0, 0, 18432, 68, }, /* 1227 */ + { 136, 9, 12, 0, 32, 18432, 74, }, /* 1228 */ + { 136, 5, 12, 0, -32, 18432, 76, }, /* 1229 */ + { 136, 13, 12, 0, 0, 18432, 138, }, /* 1230 */ + { 136, 15, 12, 0, 0, 18432, 68, }, /* 1231 */ + { 136, 7, 12, 0, 0, 18432, 82, }, /* 1232 */ + { 157, 7, 12, 0, 0, 18432, 82, }, /* 1233 */ + { 157, 10, 3, 0, 0, 18432, 148, }, /* 1234 */ + { 157, 10, 5, 0, 0, 18432, 144, }, /* 1235 */ + { 157, 12, 3, 0, 0, 26624, 130, }, /* 1236 */ + { 157, 10, 5, 0, 0, 18432, 174, }, /* 1237 */ + { 157, 12, 3, 0, 0, 26624, 146, }, /* 1238 */ + { 157, 7, 4, 0, 0, 18432, 82, }, /* 1239 */ + { 157, 12, 3, 0, 0, 26624, 96, }, /* 1240 */ + { 157, 21, 12, 0, 0, 18432, 124, }, /* 1241 */ + { 157, 21, 12, 0, 0, 18432, 68, }, /* 1242 */ + { 157, 13, 12, 0, 0, 18432, 138, }, /* 1243 */ + { 64, 7, 12, 0, 0, 18432, 82, }, /* 1244 */ + { 64, 10, 5, 0, 0, 18432, 144, }, /* 1245 */ + { 64, 12, 3, 0, 0, 26624, 130, }, /* 1246 */ + { 64, 12, 3, 0, 0, 26624, 146, }, /* 1247 */ + { 64, 21, 12, 0, 0, 18432, 68, }, /* 1248 */ + { 149, 7, 12, 0, 0, 18432, 82, }, /* 1249 */ + { 149, 12, 3, 0, 0, 26624, 130, }, /* 1250 */ + { 149, 12, 3, 0, 0, 18432, 130, }, /* 1251 */ + { 149, 12, 3, 0, 0, 26624, 102, }, /* 1252 */ + { 149, 12, 3, 0, 0, 26624, 146, }, /* 1253 */ + { 149, 10, 5, 0, 0, 18432, 144, }, /* 1254 */ + { 149, 7, 4, 0, 0, 18432, 82, }, /* 1255 */ + { 149, 21, 12, 0, 0, 18432, 68, }, /* 1256 */ + { 149, 21, 12, 0, 0, 18432, 124, }, /* 1257 */ + { 148, 7, 12, 0, 0, 18432, 82, }, /* 1258 */ + { 148, 12, 3, 0, 0, 26624, 130, }, /* 1259 */ + { 148, 10, 5, 0, 0, 18432, 144, }, /* 1260 */ + { 148, 7, 4, 0, 0, 18432, 82, }, /* 1261 */ + { 148, 12, 3, 0, 0, 26624, 326, }, /* 1262 */ + { 148, 12, 3, 0, 0, 26624, 146, }, /* 1263 */ + { 148, 21, 12, 0, 0, 18432, 68, }, /* 1264 */ + { 148, 21, 12, 0, 0, 18432, 124, }, /* 1265 */ + { 148, 21, 12, 0, 0, 18432, 106, }, /* 1266 */ + { 134, 7, 12, 0, 0, 18432, 82, }, /* 1267 */ + { 142, 7, 12, 0, 0, 18432, 82, }, /* 1268 */ + { 142, 10, 5, 0, 0, 18432, 144, }, /* 1269 */ + { 142, 12, 3, 0, 0, 26624, 130, }, /* 1270 */ + { 142, 12, 3, 0, 0, 18432, 146, }, /* 1271 */ + { 142, 21, 12, 0, 0, 18432, 124, }, /* 1272 */ + { 142, 21, 12, 0, 0, 18432, 106, }, /* 1273 */ + { 142, 21, 12, 0, 0, 18432, 68, }, /* 1274 */ + { 142, 13, 12, 0, 0, 18432, 138, }, /* 1275 */ + { 142, 15, 12, 0, 0, 18432, 68, }, /* 1276 */ + { 143, 21, 12, 0, 0, 18432, 68, }, /* 1277 */ + { 143, 21, 12, 0, 0, 18432, 106, }, /* 1278 */ + { 143, 7, 12, 0, 0, 18432, 82, }, /* 1279 */ + { 143, 12, 3, 0, 0, 26624, 130, }, /* 1280 */ + { 143, 10, 5, 0, 0, 18432, 144, }, /* 1281 */ + { 59, 7, 12, 0, 0, 18432, 82, }, /* 1282 */ + { 59, 12, 3, 0, 0, 26624, 130, }, /* 1283 */ + { 59, 12, 3, 0, 0, 26624, 96, }, /* 1284 */ + { 59, 12, 3, 0, 0, 26624, 146, }, /* 1285 */ + { 59, 7, 4, 0, 0, 18432, 82, }, /* 1286 */ + { 59, 13, 12, 0, 0, 18432, 138, }, /* 1287 */ + { 61, 7, 12, 0, 0, 18432, 82, }, /* 1288 */ + { 61, 10, 5, 0, 0, 18432, 144, }, /* 1289 */ + { 61, 12, 3, 0, 0, 26624, 130, }, /* 1290 */ + { 61, 12, 3, 0, 0, 26624, 146, }, /* 1291 */ + { 61, 13, 12, 0, 0, 18432, 138, }, /* 1292 */ + { 150, 7, 12, 0, 0, 18432, 82, }, /* 1293 */ + { 150, 12, 3, 0, 0, 26624, 130, }, /* 1294 */ + { 150, 10, 5, 0, 0, 18432, 144, }, /* 1295 */ + { 150, 21, 12, 0, 0, 18432, 124, }, /* 1296 */ + { 162, 12, 3, 0, 0, 26624, 130, }, /* 1297 */ + { 162, 7, 4, 0, 0, 18432, 82, }, /* 1298 */ + { 162, 10, 5, 0, 0, 18432, 144, }, /* 1299 */ + { 162, 7, 12, 0, 0, 18432, 82, }, /* 1300 */ + { 162, 10, 5, 0, 0, 18432, 176, }, /* 1301 */ + { 162, 12, 3, 0, 0, 26624, 184, }, /* 1302 */ + { 162, 21, 12, 0, 0, 18432, 124, }, /* 1303 */ + { 162, 21, 12, 0, 0, 18432, 68, }, /* 1304 */ + { 162, 13, 12, 0, 0, 18432, 138, }, /* 1305 */ + { 11, 15, 12, 0, 0, 18432, 68, }, /* 1306 */ + { 11, 21, 12, 0, 0, 18432, 68, }, /* 1307 */ + { 94, 7, 12, 0, 0, 18432, 82, }, /* 1308 */ + { 94, 14, 12, 0, 0, 18432, 82, }, /* 1309 */ + { 94, 21, 12, 0, 0, 18432, 106, }, /* 1310 */ + { 66, 7, 12, 0, 0, 18432, 82, }, /* 1311 */ + { 66, 21, 12, 0, 0, 18432, 68, }, /* 1312 */ + { 109, 7, 12, 0, 0, 18432, 82, }, /* 1313 */ + { 109, 1, 2, 0, 0, 18432, 322, }, /* 1314 */ + { 109, 12, 3, 0, 0, 26624, 102, }, /* 1315 */ + { 109, 12, 3, 0, 0, 26624, 96, }, /* 1316 */ + { 138, 7, 12, 0, 0, 18432, 82, }, /* 1317 */ + { 130, 7, 12, 0, 0, 18432, 82, }, /* 1318 */ + { 130, 13, 12, 0, 0, 18432, 138, }, /* 1319 */ + { 130, 21, 12, 0, 0, 18432, 124, }, /* 1320 */ + { 159, 7, 12, 0, 0, 18432, 82, }, /* 1321 */ + { 159, 13, 12, 0, 0, 18432, 138, }, /* 1322 */ + { 126, 7, 12, 0, 0, 18432, 82, }, /* 1323 */ + { 126, 12, 3, 0, 0, 26624, 96, }, /* 1324 */ + { 126, 21, 12, 0, 0, 18432, 124, }, /* 1325 */ + { 128, 7, 12, 0, 0, 18432, 82, }, /* 1326 */ + { 128, 12, 3, 0, 0, 26624, 96, }, /* 1327 */ + { 128, 21, 12, 0, 0, 18432, 124, }, /* 1328 */ + { 128, 21, 12, 0, 0, 18432, 106, }, /* 1329 */ + { 128, 21, 12, 0, 0, 18432, 68, }, /* 1330 */ + { 128, 26, 12, 0, 0, 18432, 68, }, /* 1331 */ + { 128, 6, 12, 0, 0, 18432, 142, }, /* 1332 */ + { 128, 6, 12, 0, 0, 18432, 136, }, /* 1333 */ + { 128, 13, 12, 0, 0, 18432, 138, }, /* 1334 */ + { 128, 15, 12, 0, 0, 18432, 68, }, /* 1335 */ + { 151, 9, 12, 0, 32, 18432, 74, }, /* 1336 */ + { 151, 5, 12, 0, -32, 18432, 76, }, /* 1337 */ + { 151, 15, 12, 0, 0, 18432, 68, }, /* 1338 */ + { 151, 21, 12, 0, 0, 18432, 106, }, /* 1339 */ + { 151, 21, 12, 0, 0, 18432, 124, }, /* 1340 */ + { 151, 21, 12, 0, 0, 18432, 68, }, /* 1341 */ + { 123, 7, 12, 0, 0, 18432, 82, }, /* 1342 */ + { 123, 12, 3, 0, 0, 26624, 130, }, /* 1343 */ + { 123, 10, 5, 0, 0, 18432, 144, }, /* 1344 */ + { 123, 12, 3, 0, 0, 26624, 128, }, /* 1345 */ + { 123, 6, 12, 0, 0, 18432, 92, }, /* 1346 */ + { 146, 6, 12, 0, 0, 18432, 136, }, /* 1347 */ + { 147, 6, 12, 0, 0, 18432, 136, }, /* 1348 */ + { 23, 21, 12, 0, 0, 28672, 68, }, /* 1349 */ + { 158, 12, 3, 0, 0, 26624, 328, }, /* 1350 */ + { 23, 10, 5, 0, 0, 18432, 164, }, /* 1351 */ + { 146, 7, 12, 0, 0, 18432, 284, }, /* 1352 */ + { 158, 7, 12, 0, 0, 18432, 284, }, /* 1353 */ + { 21, 6, 12, 0, 0, 18432, 92, }, /* 1354 */ + { 147, 7, 12, 0, 0, 18432, 284, }, /* 1355 */ + { 46, 7, 12, 0, 0, 18432, 82, }, /* 1356 */ + { 46, 26, 12, 0, 0, 18432, 68, }, /* 1357 */ + { 46, 12, 3, 0, 0, 26624, 102, }, /* 1358 */ + { 46, 12, 3, 0, 0, 26624, 130, }, /* 1359 */ + { 46, 21, 12, 0, 0, 18432, 124, }, /* 1360 */ + { 69, 1, 2, 0, 0, 6153, 66, }, /* 1361 */ + { 69, 10, 3, 0, 0, 18432, 330, }, /* 1362 */ + { 69, 10, 5, 0, 0, 18432, 138, }, /* 1363 */ + { 69, 10, 5, 0, 0, 18432, 160, }, /* 1364 */ + { 69, 10, 3, 0, 0, 18432, 286, }, /* 1365 */ + { 1, 12, 3, 0, 0, 26624, 102, }, /* 1366 */ + { 69, 25, 12, 0, 0, 18432, 118, }, /* 1367 */ + { 69, 13, 12, 0, 0, 10240, 214, }, /* 1368 */ + { 141, 26, 12, 0, 0, 18432, 68, }, /* 1369 */ + { 141, 12, 3, 0, 0, 26624, 102, }, /* 1370 */ + { 141, 21, 12, 0, 0, 18432, 106, }, /* 1371 */ + { 141, 21, 12, 0, 0, 18432, 124, }, /* 1372 */ + { 141, 21, 12, 0, 0, 18432, 68, }, /* 1373 */ + { 35, 12, 3, 0, 0, 26624, 130, }, /* 1374 */ + { 2, 6, 12, 0, 0, 18432, 90, }, /* 1375 */ + { 154, 7, 12, 0, 0, 18432, 82, }, /* 1376 */ + { 154, 12, 3, 0, 0, 26624, 96, }, /* 1377 */ + { 154, 6, 12, 0, 0, 18432, 142, }, /* 1378 */ + { 154, 6, 12, 0, 0, 18432, 136, }, /* 1379 */ + { 154, 13, 12, 0, 0, 18432, 138, }, /* 1380 */ + { 154, 26, 12, 0, 0, 18432, 68, }, /* 1381 */ + { 160, 7, 12, 0, 0, 18432, 82, }, /* 1382 */ + { 160, 12, 3, 0, 0, 26624, 96, }, /* 1383 */ + { 155, 7, 12, 0, 0, 18432, 82, }, /* 1384 */ + { 155, 12, 3, 0, 0, 26624, 96, }, /* 1385 */ + { 155, 13, 12, 0, 0, 18432, 138, }, /* 1386 */ + { 155, 23, 12, 0, 0, 14336, 68, }, /* 1387 */ + { 163, 7, 12, 0, 0, 18432, 82, }, /* 1388 */ + { 163, 6, 12, 0, 0, 18432, 142, }, /* 1389 */ + { 163, 12, 3, 0, 0, 26624, 102, }, /* 1390 */ + { 163, 13, 12, 0, 0, 18432, 138, }, /* 1391 */ + { 129, 7, 12, 0, 0, 34816, 82, }, /* 1392 */ + { 129, 15, 12, 0, 0, 34816, 68, }, /* 1393 */ + { 129, 12, 3, 0, 0, 26624, 96, }, /* 1394 */ + { 58, 9, 12, 0, 34, 34816, 74, }, /* 1395 */ + { 58, 5, 12, 0, -34, 34816, 76, }, /* 1396 */ + { 58, 12, 3, 0, 0, 26624, 150, }, /* 1397 */ + { 58, 12, 3, 0, 0, 26624, 130, }, /* 1398 */ + { 58, 12, 3, 0, 0, 26624, 96, }, /* 1399 */ + { 58, 6, 12, 0, 0, 34816, 142, }, /* 1400 */ + { 58, 13, 12, 0, 0, 34816, 138, }, /* 1401 */ + { 58, 21, 12, 0, 0, 34816, 68, }, /* 1402 */ + { 69, 15, 12, 0, 0, 0, 68, }, /* 1403 */ + { 69, 26, 12, 0, 0, 0, 68, }, /* 1404 */ + { 69, 23, 12, 0, 0, 0, 68, }, /* 1405 */ + { 3, 7, 12, 0, 0, 0, 240, }, /* 1406 */ + { 69, 26, 14, 0, 0, 28672, 332, }, /* 1407 */ + { 69, 26, 14, 0, 0, 28672, 334, }, /* 1408 */ + { 68, 2, 14, 0, 0, 18432, 336, }, /* 1409 */ + { 69, 26, 12, 0, 0, 18432, 338, }, /* 1410 */ + { 69, 26, 14, 0, 0, 18432, 340, }, /* 1411 */ + { 69, 26, 14, 0, 0, 18432, 334, }, /* 1412 */ + { 69, 26, 11, 0, 0, 18432, 342, }, /* 1413 */ + { 20, 26, 12, 0, 0, 18432, 68, }, /* 1414 */ + { 69, 26, 14, 0, 0, 18432, 236, }, /* 1415 */ + { 69, 26, 14, 0, 0, 18447, 334, }, /* 1416 */ + { 69, 26, 14, 0, 0, 28672, 344, }, /* 1417 */ + { 69, 26, 14, 0, 0, 28672, 346, }, /* 1418 */ + { 69, 24, 3, 0, 0, 28672, 348, }, /* 1419 */ + { 69, 26, 14, 0, 0, 28672, 350, }, /* 1420 */ + { 69, 13, 12, 0, 0, 10240, 138, }, /* 1421 */ + { 69, 1, 3, 0, 0, 6144, 352, }, /* 1422 */ }; const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ @@ -2129,36 +1885,36 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,129,129,130,131,132,133,134,135,136,137,138,139,140,141, /* U+F800 */ 142,143,144,145,146,147,148,149,150,151,152,153,154,154,155,156, /* U+10000 */ 157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172, /* U+10800 */ -173,174,175,176,177,178,179,180,181,182,146,183,184,185,186,146, /* U+11000 */ -187,188,189,190,191,192,193,194,195,196,197,198,146,199,200,201, /* U+11800 */ -202,202,202,202,202,202,202,203,204,202,205,146,146,146,146,146, /* U+12000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,206, /* U+12800 */ -207,207,207,207,207,207,207,207,208,207,207,207,207,207,207,207, /* U+13000 */ -207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, /* U+13800 */ -207,207,207,207,207,207,207,209,210,210,210,210,211,146,146,146, /* U+14000 */ +173,174,175,176,177,178,179,146,180,181,146,182,183,184,185,146, /* U+11000 */ +186,187,188,189,190,191,192,146,193,194,195,196,146,197,198,199, /* U+11800 */ +200,200,200,200,200,200,200,201,202,200,203,146,146,146,146,146, /* U+12000 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,204, /* U+12800 */ +205,205,205,205,205,205,205,205,206,146,146,146,146,146,146,146, /* U+13000 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+13800 */ +146,146,146,146,146,146,146,146,207,207,207,207,208,146,146,146, /* U+14000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+14800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15800 */ -146,146,212,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */ -213,213,213,213,214,215,216,217,146,146,218,146,219,220,221,222, /* U+16800 */ -223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, /* U+17000 */ -223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, /* U+17800 */ -223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,224, /* U+18000 */ -223,223,223,223,223,223,225,225,225,226,227,146,146,146,146,146, /* U+18800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */ +209,209,209,209,210,211,212,213,146,146,146,146,214,215,216,217, /* U+16800 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17000 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17800 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,219, /* U+18000 */ +218,218,218,218,218,218,220,220,220,221,222,146,146,146,146,146, /* U+18800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1A000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,228, /* U+1A800 */ -229,230,231,232,232,233,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ -146,146,146,146,146,146,146,146,234,235,146,146,146,146,146,146, /* U+1B800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,223, /* U+1A800 */ +224,225,226,227,227,228,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ +146,146,146,146,146,146,146,146,229,230,146,146,146,146,146,146, /* U+1B800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1C000 */ -146,146,146,146,146,146,146,146,236,237,236,236,236,238,239,240, /* U+1C800 */ -241,242,243,244,245,246,247,146,248,249,250,251,252,253,254,255, /* U+1D000 */ -256,256,256,256,257,258,146,146,146,146,146,146,146,146,259,146, /* U+1D800 */ -260,261,262,146,146,263,146,146,146,264,146,265,146,146,146,266, /* U+1E000 */ -267,268,269,270,270,270,270,270,271,272,273,270,274,275,270,270, /* U+1E800 */ -276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291, /* U+1F000 */ -292,293,294,295,296,297,236,298,281,281,281,281,281,281,281,299, /* U+1F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,231,232, /* U+1C800 */ +233,234,235,236,237,238,239,146,240,241,242,243,244,245,246,247, /* U+1D000 */ +248,248,248,248,249,250,146,146,146,146,146,146,146,146,251,146, /* U+1D800 */ +252,253,254,146,146,255,146,146,146,256,146,146,146,146,146,257, /* U+1E000 */ +258,259,260,168,168,168,168,168,261,262,263,168,264,265,168,168, /* U+1E800 */ +266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281, /* U+1F000 */ +282,283,284,285,286,287,288,289,271,271,271,271,271,271,271,290, /* U+1F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21000 */ @@ -2179,23 +1935,23 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,300,101,101, /* U+2A000 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,291,101,101, /* U+2A000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2A800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,101,301,101, /* U+2B000 */ -302,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,101,292,101, /* U+2B000 */ +293,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2C000 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,303,101,101, /* U+2C800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,294,101,101, /* U+2C800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2E000 */ -101,101,101,101,101,101,101,304,101,101,101,101,305,146,146,146, /* U+2E800 */ +101,101,101,101,101,101,101,295,146,146,146,146,146,146,146,146, /* U+2E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+2F000 */ -129,129,129,129,306,146,146,146,146,146,146,146,146,146,146,307, /* U+2F800 */ +129,129,129,129,296,146,146,146,146,146,146,146,146,146,146,297, /* U+2F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30800 */ -101,101,101,101,101,101,308,101,101,101,101,101,101,101,101,101, /* U+31000 */ +101,101,101,101,101,101,298,101,101,101,101,101,101,101,101,101, /* U+31000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+31800 */ -101,101,101,101,101,101,101,309,146,146,146,146,146,146,146,146, /* U+32000 */ +101,101,101,101,101,101,101,299,146,146,146,146,146,146,146,146, /* U+32000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33800 */ @@ -2222,7 +1978,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+3F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+3F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41000 */ @@ -2254,7 +2010,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+4F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+4F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51000 */ @@ -2286,7 +2042,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+5F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+5F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61000 */ @@ -2318,7 +2074,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+6F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+6F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71000 */ @@ -2350,7 +2106,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+7F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+7F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81000 */ @@ -2382,7 +2138,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+8F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+8F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91000 */ @@ -2414,7 +2170,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+9F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+9F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1000 */ @@ -2446,7 +2202,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+AF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+AF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1000 */ @@ -2478,7 +2234,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+BF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+BF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1000 */ @@ -2510,7 +2266,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+CF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+CF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1000 */ @@ -2542,9 +2298,9 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+DF800 */ -310,311,312,313,311,311,311,311,311,311,311,311,311,311,311,311, /* U+E0000 */ -311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, /* U+E0800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+DF800 */ +300,301,302,303,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0000 */ +301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2000 */ @@ -2574,7 +2330,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,307, /* U+EF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+EF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1000 */ @@ -2606,7 +2362,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FF000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,314, /* U+FF800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+FF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101000 */ @@ -2638,10 +2394,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10F000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,314, /* U+10F800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+10F800 */ }; -const uint16_t PRIV(ucd_stage2)[] = { /* 80640 bytes, block = 128 */ +const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ /* block 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 3, 4, 0, 0, @@ -2675,553 +2431,553 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 80640 bytes, block = 128 */ /* block 3 */ 74, 75, 65, 66, 65, 66, 76, 65, 66, 77, 77, 65, 66, 70, 78, 79, - 80, 65, 66, 77, 81, 82, 83, 84, 65, 66, 85, 86, 83, 87, 88, 89, - 65, 66, 65, 66, 65, 66, 90, 65, 66, 90, 70, 70, 65, 66, 90, 65, - 66, 91, 91, 65, 66, 65, 66, 92, 65, 66, 70, 93, 65, 66, 70, 94, - 93, 93, 93, 93, 95, 96, 97, 98, 99,100,101,102,103, 65, 66, 65, - 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,104, 65, 66, + 80, 65, 66, 77, 81, 82, 83, 84, 65, 66, 85, 70, 83, 86, 87, 88, + 65, 66, 65, 66, 65, 66, 89, 65, 66, 89, 70, 70, 65, 66, 89, 65, + 66, 90, 90, 65, 66, 65, 66, 91, 65, 66, 70, 92, 65, 66, 70, 93, + 92, 92, 92, 92, 94, 95, 96, 97, 98, 99,100,101,102, 65, 66, 65, + 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,103, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 69,105,106,107, 65, 66,108,109, 65, 66, 65, 66, 65, 66, 65, 66, + 69,104,105,106, 65, 66,107,108, 65, 66, 65, 66, 65, 66, 65, 66, /* block 4 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -110, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 70, 70, 70, 70, 70, 70,111, 65, 66,112,113,114, -114, 65, 66,115,116,117, 65, 66, 65, 67, 65, 66, 65, 66, 65, 66, -118,119,120,121,122, 70,123,123, 70,124, 70,125,126, 70, 70, 70, -123,127, 70,128,129,130,131, 70,132,133,131,134,135, 70, 70,133, - 70,136,137, 70, 70,138, 70, 70, 70, 70, 70, 70, 70,139, 70, 70, +109, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 70, 70, 70, 70, 70, 70,110, 65, 66,111,112,113, +113, 65, 66,114,115,116, 65, 66, 65, 67, 65, 66, 65, 66, 65, 66, +117,118,119,120,121, 70,122,122, 70,123, 70,124,125, 70, 70, 70, +122,126, 70,127, 70,128,129, 70,130,131,129,132,133, 70, 70,131, + 70,134,135, 70, 70,136, 70, 70, 70, 70, 70, 70, 70,137, 70, 70, /* block 5 */ -140, 70,141,140, 70, 70, 70,142,140,143,144,144,145, 70, 70, 70, - 70, 70,146, 70, 93, 70, 70, 70, 70, 70, 70, 70, 70,147,148, 70, +138, 70,139,138, 70, 70, 70,140,138,141,142,142,143, 70, 70, 70, + 70, 70,144, 70, 92, 70, 70, 70, 70, 70, 70, 70, 70,145,146, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, -149,149,150,149,149,149,149,149,149,151,151,152,153,152,152,152, -154,154, 46, 46, 46, 46,151,155,151,155,155,155,151,156,151,151, -157,157, 46, 46, 46, 46, 46,158, 46,159, 46, 46, 46, 46, 46, 46, -149,149,149,149,149, 46, 46, 46, 46, 46,160,160,151, 46,152, 46, +147,147,148,147,147,147,147,147,147,149,149,150,150,150,150,150, +151,151, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149,149, +152,152, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, +147,147,147,147,147, 46, 46, 46, 46, 46,153,153,149, 46,150, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, /* block 6 */ -161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, -174,177,176,178,176,176,176,176,176,176,176,176,176,176,176,176, -179,176,176,180,181,179,176,176,176,176,176,176,176,182,179,176, -183,184,176,176,176,176,176,176,176,176,176,176,176,176,176,176, -176,176,185,176,176,186,176,176,176,176,176,176,176,176,176,187, -176,176,176,176,176,176,176,176,188,189,189,189,189,176,190,176, -176,176,176,191,191,191,191,191,191,191,191,191,191,191,191,191, -192,193,192,193,194,195,192,193,196,196,197,198,198,198,199,200, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,155,154,154,156,154,154,154,154,154,154,154,154,154,157, +154,154,154,154,154,154,154,154,158,158,158,158,158,154,154,154, +154,154,154,159,159,159,159,159,159,159,159,159,159,159,159,159, +160,161,160,161,149,162,160,161,163,163,164,165,165,165,166,167, /* block 7 */ -196,196,196,196,201, 46,202,203,204,204,204,196,205,196,206,206, -207,208,209,208,208,210,208,208,211,212,213,208,214,208,208,208, -215,216,196,217,208,208,218,208,208,219,208,208,220,221,221,221, -222,223,224,223,223,225,223,223,226,227,228,223,229,223,223,223, -230,231,232,233,223,223,234,223,223,235,223,223,236,237,237,238, -239,240,241,242,242,243,244,245,192,193,192,193,192,193,192,193, -192,193,246,247,246,247,246,247,246,247,246,247,246,247,246,247, -248,249,250,251,252,253,254,192,193,255,192,193,256,257,257,257, +163,163,163,163,162, 46,168,169,170,170,170,163,171,163,172,172, +173,174,175,174,174,176,174,174,177,178,179,174,180,174,174,174, +181,182,163,183,174,174,184,174,174,185,174,174,186,187,187,187, +173,188,189,188,188,190,188,188,191,192,193,188,194,188,188,188, +195,196,197,198,188,188,199,188,188,200,188,188,201,202,202,203, +204,205,206,207,207,208,209,210,160,161,160,161,160,161,160,161, +160,161,211,212,211,212,211,212,211,212,211,212,211,212,211,212, +213,214,215,216,217,218,219,160,161,220,160,161,221,222,222,222, /* block 8 */ -258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258, -259,259,260,259,261,259,259,259,259,259,259,259,259,259,262,259, -259,263,264,259,259,259,259,259,259,259,265,259,259,259,259,259, -266,266,267,266,268,266,266,266,266,266,266,266,266,266,269,266, -266,270,271,266,266,266,266,266,266,266,272,266,266,266,266,266, -273,273,273,273,273,273,274,273,274,273,273,273,273,273,273,273, -275,276,277,278,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +224,224,225,224,226,224,224,224,224,224,224,224,224,224,227,224, +224,228,229,224,224,224,224,224,224,224,230,224,224,224,224,224, +231,231,232,231,233,231,231,231,231,231,231,231,231,231,234,231, +231,235,236,231,231,231,231,231,231,231,237,231,231,231,231,231, +238,238,238,238,238,238,239,238,239,238,238,238,238,238,238,238, +240,241,242,243,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, /* block 9 */ -275,276,279,280,281,282,282,281,283,283,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -284,275,276,275,276,275,276,275,276,275,276,275,276,275,276,285, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, +240,241,244,245,246,247,247,246,248,248,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +249,240,241,240,241,240,241,240,241,240,241,240,241,240,241,250, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, /* block 10 */ -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -196,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,196,196,287,288,288,288,288,288,289, -290,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, -291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +163,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,163,163,252,253,253,253,253,253,254, +255,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, +256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, /* block 11 */ -291,291,291,291,291,291,291,292,290,293,294,196,196,295,295,296, -297,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298, -298,298,299,298,298,298,298,298,298,298,298,298,298,298,298,298, -300,300,300,300,300,300,300,300,300,300,300,300,300,300,301,300, -302,300,300,303,300,304,302,304,297,297,297,297,297,297,297,297, -305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305, -305,305,305,305,305,305,305,305,305,305,305,297,297,297,297,305, -305,305,305,302,306,297,297,297,297,297,297,297,297,297,297,297, +256,256,256,256,256,256,256,257,255,258,259,163,163,260,260,261, +262,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, +263,263,264,263,263,263,263,263,263,263,263,263,263,263,263,263, +265,265,265,265,265,265,265,265,265,265,265,265,265,265,266,265, +267,265,265,268,265,269,267,269,262,262,262,262,262,262,262,262, +270,270,270,270,270,270,270,270,270,270,270,270,270,270,270,270, +270,270,270,270,270,270,270,270,270,270,270,262,262,262,262,270, +270,270,270,267,271,262,262,262,262,262,262,262,262,262,262,262, /* block 12 */ -307,307,307,307,307,308,309,309,310,311,311,312,313,314,315,315, -316,316,316,316,316,316,316,316,316,316,316,317,318,319,319,320, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -322,321,321,321,321,321,321,321,321,321,321,323,323,323,323,323, -323,323,323,324,325,325,316,326,327,316,316,316,316,316,316,316, -328,328,328,328,328,328,328,328,328,328,311,329,329,314,321,321, -324,321,321,330,321,321,321,321,321,321,321,321,321,321,321,321, +272,272,272,272,272,273,274,274,275,276,276,277,278,279,280,280, +281,281,281,281,281,281,281,281,281,281,281,282,283,284,284,285, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +287,286,286,286,286,286,286,286,286,286,286,288,288,288,288,288, +288,288,288,289,289,289,281,290,291,281,281,281,281,281,281,281, +292,292,292,292,292,292,292,292,292,292,276,293,293,279,286,286, +289,286,286,294,286,286,286,286,286,286,286,286,286,286,286,286, /* block 13 */ -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,331,321,316,316,316,316,316,316,332,308,315,333, -333,316,316,332,316,334,334,332,332,315,333,333,333,316,321,321, -335,335,335,335,335,335,335,335,335,335,321,321,321,336,336,321, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,295,286,281,281,281,281,281,281,281,273,280,291, +291,281,281,281,281,296,296,281,281,280,291,291,291,281,286,286, +297,297,297,297,297,297,297,297,297,297,286,286,286,298,298,286, /* block 14 */ -337,337,337,338,338,338,338,338,338,338,338,339,338,339,340,341, -342,343,342,342,342,342,342,342,342,342,342,342,342,342,342,342, -342,342,342,342,342,342,342,342,342,342,342,342,342,342,342,342, -344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344, -345,345,345,345,345,345,345,345,345,345,345,340,340,342,342,342, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +299,299,299,300,300,300,300,300,300,300,300,301,300,301,302,303, +304,305,304,304,304,304,304,304,304,304,304,304,304,304,304,304, +304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304, +306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306, +307,307,307,307,307,307,307,307,307,307,307,302,302,304,304,304, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 15 */ -346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346, -346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346, -346,346,346,346,346,346,347,347,347,347,347,347,347,347,347,347, -347,346,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -348,348,348,348,348,348,348,348,348,348,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,350,350,350,350,350, -350,350,350,350,351,351,352,353,354,355,356,297,297,357,358,358, +308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, +308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308, +308,308,308,308,308,308,309,309,309,309,309,309,309,309,309,309, +309,308,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +310,310,310,310,310,310,310,310,310,310,311,311,311,311,311,311, +311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, +311,311,311,311,311,311,311,311,311,311,311,312,312,312,312,312, +312,312,312,312,313,313,314,315,316,317,318,262,262,319,320,320, /* block 16 */ -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,359,359,359,359,360,360,361,361,362,360,360,360,360,360, -360,360,360,360,362,360,360,360,362,360,360,360,360,363,297,297, -364,364,364,364,364,364,365,366,364,366,364,364,364,366,366,297, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,368,368,368,297,297,369,297, -342,342,342,342,342,342,342,342,342,342,342,340,340,340,340,340, 321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +321,321,321,321,321,321,322,322,323,323,324,322,322,322,322,322, +322,322,322,322,324,322,322,322,324,322,322,322,322,325,262,262, +326,326,326,326,326,326,326,327,326,327,326,326,326,327,327,262, +328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328, +328,328,328,328,328,328,328,328,328,329,329,329,262,262,330,262, +304,304,304,304,304,304,304,304,304,304,304,302,302,302,302,302, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 17 */ -321,321,321,321,321,321,321,321,370,321,321,321,321,321,321,340, -307,307,340,340,340,340,340,316,333,333,333,333,333,333,333,333, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,334,327,327,333,327,327,327, -333,333,333,371,316,316,316,316,316,316,316,316,316,316,316,316, -372,372,308,326,326,326,326,326,326,326,333,333,333,333,333,333, -326,326,326,373,326,326,326,326,326,326,326,326,326,326,326,316, +286,286,286,286,286,286,286,286,331,286,286,286,286,286,286,302, +272,272,302,302,302,302,302,302,291,291,291,291,291,291,291,291, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,296,291,291,291,291,291,291, +291,291,291,332,281,281,281,281,281,281,281,281,281,281,281,281, +332,332,273,290,290,290,290,290,290,290,291,291,291,291,291,291, +290,290,290,290,290,290,290,290,290,290,290,290,290,290,290,281, /* block 18 */ -374,374,374,375,376,376,376,376,376,376,376,376,376,376,376,376, -376,376,376,376,376,377,377,377,377,377,377,377,377,377,377,377, -377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377, -377,377,377,377,377,377,377,377,377,377,374,375,378,376,375,375, -375,374,374,374,374,374,374,374,374,375,375,375,375,379,375,375, -376,380,381,176,176,374,374,374,377,377,377,377,377,377,377,377, -376,376,374,374,382,383,384,384,384,384,384,384,384,384,384,384, -385,386,376,376,376,376,376,376,377,377,377,377,377,377,377,377, +333,333,333,334,335,335,335,335,335,335,335,335,335,335,335,335, +335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335, +335,335,335,335,335,335,335,335,335,335,335,335,335,335,335,335, +335,335,335,335,335,335,335,335,335,335,333,334,336,335,334,334, +334,333,333,333,333,333,333,333,333,334,334,334,334,337,334,334, +335,338,339,154,154,333,333,333,335,335,335,335,335,335,335,335, +335,335,333,333,340,341,342,342,342,342,342,342,342,342,342,342, +343,344,335,335,335,335,335,335,335,335,335,335,335,335,335,335, /* block 19 */ -387,388,389,389,196,387,387,387,387,387,387,387,387,196,196,387, -387,196,196,387,387,390,390,390,390,390,390,390,390,390,390,390, -390,390,390,390,390,390,390,390,390,196,390,390,390,390,390,390, -390,196,390,196,196,196,390,390,390,390,196,196,391,387,392,389, -389,388,388,388,388,196,196,389,389,196,196,389,389,393,387,196, -196,196,196,196,196,196,196,392,196,196,196,196,390,390,196,390, -387,387,388,388,196,196,394,394,394,394,394,394,394,394,394,394, -390,390,395,395,396,396,396,396,396,396,397,395,387,398,399,196, +345,346,347,347,163,345,345,345,345,345,345,345,345,163,163,345, +345,163,163,345,345,345,345,345,345,345,345,345,345,345,345,345, +345,345,345,345,345,345,345,345,345,163,345,345,345,345,345,345, +345,163,345,163,163,163,345,345,345,345,163,163,348,345,349,347, +347,346,346,346,346,163,163,347,347,163,163,347,347,350,345,163, +163,163,163,163,163,163,163,349,163,163,163,163,345,345,163,345, +345,345,346,346,163,163,351,351,351,351,351,351,351,351,351,351, +345,345,352,352,353,353,353,353,353,353,354,352,345,355,356,163, /* block 20 */ -196,400,400,401,196,402,402,402,402,402,402,196,196,196,196,402, -402,196,196,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,196,402,402,402,402,402,402, -402,196,402,402,196,402,402,196,402,402,196,196,403,196,401,401, -401,400,400,196,196,196,196,400,400,196,196,400,400,404,196,196, -196,400,196,196,196,196,196,196,196,402,402,402,402,196,402,196, -196,196,196,196,196,196,405,405,405,405,405,405,405,405,405,405, -400,406,402,402,402,400,407,196,196,196,196,196,196,196,196,196, +163,357,357,358,163,359,359,359,359,359,359,163,163,163,163,359, +359,163,163,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,163,359,359,359,359,359,359, +359,163,359,359,163,359,359,163,359,359,163,163,360,163,358,358, +358,357,357,163,163,163,163,357,357,163,163,357,357,361,163,163, +163,357,163,163,163,163,163,163,163,359,359,359,359,163,359,163, +163,163,163,163,163,163,362,362,362,362,362,362,362,362,362,362, +357,357,359,359,359,357,363,163,163,163,163,163,163,163,163,163, /* block 21 */ -196,408,408,409,196,410,410,410,410,410,410,410,410,410,196,410, -410,410,196,410,410,411,411,411,411,411,411,411,411,411,411,411, -411,411,411,411,411,411,411,411,411,196,411,411,411,411,411,411, -411,196,411,411,196,411,411,411,411,411,196,196,412,410,409,409, -409,408,408,408,408,408,196,408,408,409,196,409,409,413,196,196, -410,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -410,410,408,408,196,196,414,414,414,414,414,414,414,414,414,414, -415,416,196,196,196,196,196,196,196,411,408,417,408,412,412,412, +163,364,364,365,163,366,366,366,366,366,366,366,366,366,163,366, +366,366,163,366,366,366,366,366,366,366,366,366,366,366,366,366, +366,366,366,366,366,366,366,366,366,163,366,366,366,366,366,366, +366,163,366,366,163,366,366,366,366,366,163,163,367,366,365,365, +365,364,364,364,364,364,163,364,364,365,163,365,365,368,163,163, +366,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +366,366,364,364,163,163,369,369,369,369,369,369,369,369,369,369, +370,371,163,163,163,163,163,163,163,366,364,364,364,367,367,367, /* block 22 */ -196,418,419,419,196,420,420,420,420,420,420,420,420,196,196,420, -420,196,196,420,420,421,421,421,421,421,421,421,421,421,421,421, -421,421,421,421,421,421,421,421,421,196,421,421,421,421,421,421, -421,196,421,421,196,421,421,421,421,421,196,196,422,420,423,418, -419,418,418,418,418,196,196,419,419,196,196,419,419,424,196,196, -196,196,196,196,196,425,418,423,196,196,196,196,421,421,196,421, -420,420,418,418,196,196,426,426,426,426,426,426,426,426,426,426, -427,421,428,428,428,428,428,428,196,196,196,196,196,196,196,196, +163,372,373,373,163,374,374,374,374,374,374,374,374,163,163,374, +374,163,163,374,374,374,374,374,374,374,374,374,374,374,374,374, +374,374,374,374,374,374,374,374,374,163,374,374,374,374,374,374, +374,163,374,374,163,374,374,374,374,374,163,163,375,374,376,372, +373,372,372,372,372,163,163,373,373,163,163,373,373,377,163,163, +163,163,163,163,163,378,372,376,163,163,163,163,374,374,163,374, +374,374,372,372,163,163,379,379,379,379,379,379,379,379,379,379, +380,374,381,381,381,381,381,381,163,163,163,163,163,163,163,163, /* block 23 */ -196,196,429,430,196,430,430,430,430,430,430,196,196,196,430,430, -430,196,430,430,430,430,196,196,196,430,430,196,430,196,430,430, -196,196,196,430,430,196,196,196,430,430,430,196,196,196,430,430, -430,430,430,430,430,430,430,430,430,430,196,196,196,196,431,432, -429,432,432,196,196,196,432,432,432,196,432,432,432,433,196,196, -430,196,196,196,196,196,196,431,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,434,434,434,434,434,434,434,434,434,434, -435,435,435,436,437,437,437,437,437,438,437,196,196,196,196,196, +163,163,382,383,163,383,383,383,383,383,383,163,163,163,383,383, +383,163,383,383,383,383,163,163,163,383,383,163,383,163,383,383, +163,163,163,383,383,163,163,163,383,383,383,163,163,163,383,383, +383,383,383,383,383,383,383,383,383,383,163,163,163,163,384,385, +382,385,385,163,163,163,385,385,385,163,385,385,385,386,163,163, +383,163,163,163,163,163,163,384,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,387,387,387,387,387,387,387,387,387,387, +388,388,388,389,390,390,390,390,390,391,390,163,163,163,163,163, /* block 24 */ -439,440,440,440,439,441,441,441,441,441,441,441,441,196,441,441, -441,196,441,441,441,442,442,442,442,442,442,442,442,442,442,442, -442,442,442,442,442,442,442,442,442,196,442,442,442,442,442,442, -442,442,442,442,442,442,442,442,442,442,196,196,443,441,439,439, -439,440,440,440,440,196,439,439,439,196,439,439,439,444,196,196, -196,196,196,196,196,439,439,196,442,442,442,196,196,441,196,196, -441,441,439,439,196,196,445,445,445,445,445,445,445,445,445,445, -196,196,196,196,196,196,196,446,447,447,447,447,447,447,447,448, +392,393,393,393,392,394,394,394,394,394,394,394,394,163,394,394, +394,163,394,394,394,394,394,394,394,394,394,394,394,394,394,394, +394,394,394,394,394,394,394,394,394,163,394,394,394,394,394,394, +394,394,394,394,394,394,394,394,394,394,163,163,395,394,392,392, +392,393,393,393,393,163,392,392,392,163,392,392,392,396,163,163, +163,163,163,163,163,392,392,163,394,394,394,163,163,394,163,163, +394,394,392,392,163,163,397,397,397,397,397,397,397,397,397,397, +163,163,163,163,163,163,163,398,399,399,399,399,399,399,399,400, /* block 25 */ -449,450,451,451,452,449,449,449,449,449,449,449,449,196,449,449, -449,196,449,449,449,449,449,449,449,449,449,449,449,449,449,449, -449,449,449,449,449,449,449,449,449,196,449,449,449,449,449,449, -449,449,449,449,196,449,449,449,449,449,196,196,453,449,451,454, -455,451,455,451,451,196,454,455,455,196,455,455,450,456,196,196, -196,196,196,196,196,455,455,196,196,196,196,196,196,449,449,196, -449,449,450,450,196,196,457,457,457,457,457,457,457,457,457,457, -196,449,449,451,196,196,196,196,196,196,196,196,196,196,196,196, +401,402,403,403,404,401,401,401,401,401,401,401,401,163,401,401, +401,163,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,163,401,401,401,401,401,401, +401,401,401,401,163,401,401,401,401,401,163,163,405,401,403,406, +403,403,407,403,403,163,406,403,403,163,403,403,402,408,163,163, +163,163,163,163,163,407,407,163,163,163,163,163,163,401,401,163, +401,401,402,402,163,163,409,409,409,409,409,409,409,409,409,409, +163,401,401,403,163,163,163,163,163,163,163,163,163,163,163,163, /* block 26 */ -458,458,459,459,460,460,460,460,460,460,460,460,460,196,460,460, -460,196,460,460,460,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,462,462,460,463,459, -459,458,458,458,458,196,459,459,459,196,459,459,459,462,464,465, -196,196,196,196,460,460,460,463,466,466,466,466,466,466,466,460, -460,460,458,458,196,196,467,467,467,467,467,467,467,467,467,467, -466,466,466,466,466,466,466,466,466,465,460,460,460,460,460,460, +410,410,411,411,412,412,412,412,412,412,412,412,412,163,412,412, +412,163,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,413,413,412,414,411, +411,410,410,410,410,163,411,411,411,163,411,411,411,413,415,416, +163,163,163,163,412,412,412,414,417,417,417,417,417,417,417,412, +412,412,410,410,163,163,418,418,418,418,418,418,418,418,418,418, +417,417,417,417,417,417,417,417,417,416,412,412,412,412,412,412, /* block 27 */ -196,468,469,469,196,470,470,470,470,470,470,470,470,470,470,470, -470,470,470,470,470,470,470,196,196,196,470,470,470,470,470,470, -470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470, -470,470,196,470,470,470,470,470,470,470,470,470,196,470,196,196, -470,470,470,470,470,470,470,196,196,196,471,196,196,196,196,472, -469,469,468,468,468,196,468,196,469,469,469,469,469,469,469,472, -196,196,196,196,196,196,473,473,473,473,473,473,473,473,473,473, -196,196,469,469,474,196,196,196,196,196,196,196,196,196,196,196, +163,419,420,420,163,421,421,421,421,421,421,421,421,421,421,421, +421,421,421,421,421,421,421,163,163,163,421,421,421,421,421,421, +421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421, +421,421,163,421,421,421,421,421,421,421,421,421,163,421,163,163, +421,421,421,421,421,421,421,163,163,163,422,163,163,163,163,423, +420,420,419,419,419,163,419,163,420,420,420,420,420,420,420,423, +163,163,163,163,163,163,424,424,424,424,424,424,424,424,424,424, +163,163,420,420,425,163,163,163,163,163,163,163,163,163,163,163, /* block 28 */ -196,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,476,475,477,476,476,476,476,476,476,478,196,196,196,196,479, -480,480,480,480,480,475,481,482,482,482,482,482,482,476,482,483, -484,484,484,484,484,484,484,484,484,484,485,485,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +163,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,427,426,428,427,427,427,427,427,427,429,163,163,163,163,430, +431,431,431,431,431,426,432,433,433,433,433,433,433,427,433,434, +435,435,435,435,435,435,435,435,435,435,436,436,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 29 */ -196,486,486,196,486,196,486,486,486,486,486,196,486,486,486,486, -486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486, -486,486,486,486,196,486,196,486,486,486,486,486,486,486,486,486, -486,487,486,488,487,487,487,487,487,487,489,487,487,486,196,196, -490,490,490,490,490,196,491,196,492,492,492,492,492,487,493,196, -494,494,494,494,494,494,494,494,494,494,196,196,486,486,486,486, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +163,437,437,163,437,163,437,437,437,437,437,163,437,437,437,437, +437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, +437,437,437,437,163,437,163,437,437,437,437,437,437,437,437,437, +437,438,437,439,438,438,438,438,438,438,440,438,438,437,163,163, +441,441,441,441,441,163,442,163,443,443,443,443,443,438,444,163, +445,445,445,445,445,445,445,445,445,445,163,163,437,437,437,437, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 30 */ -495,496,496,496,497,497,497,497,498,497,497,497,497,498,498,498, -498,498,498,496,497,496,496,496,499,499,496,496,496,496,496,496, -500,500,500,500,500,500,500,500,500,500,501,501,501,501,501,501, -501,501,501,501,496,499,496,499,496,499,502,503,502,503,504,504, -495,495,495,495,495,495,495,495,196,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,196,196,196, -196,505,505,505,505,505,505,506,505,506,505,505,505,505,505,507, +446,447,447,447,448,448,448,448,449,448,448,448,448,449,449,449, +449,449,449,447,448,447,447,447,450,450,447,447,447,447,447,447, +451,451,451,451,451,451,451,451,451,451,452,452,452,452,452,452, +452,452,452,452,447,450,447,450,447,450,453,454,453,454,455,455, +446,446,446,446,446,446,446,446,163,446,446,446,446,446,446,446, +446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446, +446,446,446,446,446,446,446,446,446,446,446,446,446,163,163,163, +163,456,456,456,456,456,456,457,456,457,456,456,456,456,456,458, /* block 31 */ -505,505,508,508,509,497,499,499,495,495,495,495,495,505,505,505, -505,505,505,505,505,505,505,505,196,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,196,496,496, -496,496,496,496,496,496,499,496,496,496,496,496,496,196,496,496, -497,497,497,497,497,510,510,510,510,497,497,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +456,456,459,459,460,448,450,450,446,446,446,446,446,456,456,456, +456,456,456,456,456,456,456,456,163,456,456,456,456,456,456,456, +456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, +456,456,456,456,456,456,456,456,456,456,456,456,456,163,447,447, +447,447,447,447,447,447,450,447,447,447,447,447,447,163,447,447, +448,448,448,448,448,461,461,461,461,448,448,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 32 */ -511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, -511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, -511,511,511,511,511,511,511,511,511,511,511,512,512,513,513,513, -513,514,513,513,513,513,513,515,512,516,516,514,514,513,513,511, -517,517,517,517,517,517,517,517,517,517,518,518,519,519,519,519, -511,511,511,511,511,511,514,514,513,513,511,511,511,511,513,513, -513,511,512,520,520,511,511,512,512,520,520,520,520,520,511,511, -511,513,513,513,513,511,511,511,511,511,511,511,511,511,511,511, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +462,462,462,462,462,462,462,462,462,462,462,463,463,464,464,464, +464,465,464,464,464,464,464,466,463,467,467,465,465,464,464,462, +468,468,468,468,468,468,468,468,468,468,469,469,470,470,470,470, +462,462,462,462,462,462,465,465,464,464,462,462,462,462,464,464, +464,462,463,471,471,462,462,463,463,471,471,471,471,471,462,462, +462,464,464,464,464,462,462,462,462,462,462,462,462,462,462,462, /* block 33 */ -511,511,513,512,514,513,513,520,520,520,520,520,520,521,511,520, -522,522,522,522,522,522,522,522,522,522,520,520,512,513,523,523, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,196,524,196,196,196,196,196,524,196,196, -525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, -525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525, -525,525,525,525,525,525,525,525,525,525,525,526,527,525,525,525, +462,462,464,463,465,464,464,471,471,471,471,471,471,472,462,471, +473,473,473,473,473,473,473,473,473,473,471,471,463,464,474,474, +475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, +475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, +475,475,475,475,475,475,163,475,163,163,163,163,163,475,163,163, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,477,478,476,476,476, /* block 34 */ -528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, -528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, -528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, -528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, -528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, -528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,529, -530,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, -531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,480, +481,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, /* block 35 */ -531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, -531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, -531,531,531,531,531,531,531,531,532,532,532,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, /* block 36 */ -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,196,533,533,533,533,196,196, -533,533,533,533,533,533,533,196,533,196,533,533,533,533,196,196, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,163,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, /* block 37 */ -533,533,533,533,533,533,533,533,533,196,533,533,533,533,196,196, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,196, -533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, +484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,163, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, /* block 38 */ -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,196,533,533,533,533,196,196,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,533,533,533,533,196,196,534,534,534, -535,536,537,536,536,536,536,537,537,538,538,538,538,538,538,538, -538,538,539,539,539,539,539,539,539,539,539,539,539,196,196,196, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,163,163,485,485,485, +486,487,488,487,487,487,487,488,488,489,489,489,489,489,489,489, +489,489,490,490,490,490,490,490,490,490,490,490,490,163,163,163, /* block 39 */ -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -540,540,540,540,540,540,540,540,540,540,196,196,196,196,196,196, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, -542,542,542,542,542,542,196,196,543,543,543,543,543,543,196,196, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +491,491,491,491,491,491,491,491,491,491,163,163,163,163,163,163, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +493,493,493,493,493,493,163,163,494,494,494,494,494,494,163,163, /* block 40 */ -544,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +495,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 41 */ -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 42 */ -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,546,547,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,497,498,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 43 */ -548,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549, -549,549,549,549,549,549,549,549,549,549,549,550,551,196,196,196, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,553,553,553,554,554, -554,552,552,552,552,552,552,552,552,196,196,196,196,196,196,196, +499,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +500,500,500,500,500,500,500,500,500,500,500,501,502,163,163,163, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,504,504,504,505,505, +505,503,503,503,503,503,503,503,503,163,163,163,163,163,163,163, /* block 44 */ -555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555, -555,555,556,556,557,558,196,196,196,196,196,196,196,196,196,555, -559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, -559,559,560,560,561,562,562,196,196,196,196,196,196,196,196,196, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,564,564,196,196,196,196,196,196,196,196,196,196,196,196, -565,565,565,565,565,565,565,565,565,565,565,565,565,196,565,565, -565,196,566,566,196,196,196,196,196,196,196,196,196,196,196,196, +506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, +506,506,507,507,508,509,163,163,163,163,163,163,163,163,163,506, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,511,511,512,513,513,163,163,163,163,163,163,163,163,163, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,515,515,163,163,163,163,163,163,163,163,163,163,163,163, +516,516,516,516,516,516,516,516,516,516,516,516,516,163,516,516, +516,163,517,517,163,163,163,163,163,163,163,163,163,163,163,163, /* block 45 */ -567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567, -567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567, -567,567,567,568,568,567,567,567,567,567,567,567,567,567,567,567, -567,567,567,567,569,569,570,571,571,571,571,571,571,571,570,570, -570,570,570,570,570,570,571,570,570,572,572,572,572,572,572,572, -572,572,573,572,574,574,575,576,577,577,575,578,567,572,196,196, -579,579,579,579,579,579,579,579,579,579,196,196,196,196,196,196, -580,580,580,580,580,580,580,580,580,580,196,196,196,196,196,196, +518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,519,519,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,518,520,520,521,522,522,522,522,522,522,522,521,521, +521,521,521,521,521,521,522,521,521,523,523,523,523,523,523,523, +523,523,524,523,525,525,525,526,527,527,525,528,518,523,163,163, +529,529,529,529,529,529,529,529,529,529,163,163,163,163,163,163, +530,530,530,530,530,530,530,530,530,530,163,163,163,163,163,163, /* block 46 */ -581,581,582,583,584,582,585,581,584,586,587,588,588,588,589,588, -590,590,590,590,590,590,590,590,590,590,196,196,196,196,196,196, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,592,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,196,196,196,196,196,196,196, +531,531,532,533,534,532,535,531,534,536,537,538,538,538,539,538, +540,540,540,540,540,540,540,540,540,540,163,163,163,163,163,163, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,542,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,163,163,163,163,163,163,163, /* block 47 */ -591,591,591,591,591,593,593,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,594,591,196,196,196,196,196, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,196,196,196,196,196,196,196,196,196,196, +541,541,541,541,541,543,543,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,544,541,163,163,163,163,163, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,163,163,163,163,163,163,163,163,163,163, /* block 48 */ -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,196, -596,596,596,597,597,597,597,596,596,597,597,597,196,196,196,196, -597,597,596,597,597,597,597,597,597,598,598,598,196,196,196,196, -599,196,196,196,600,600,601,601,601,601,601,601,601,601,601,601, -602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602, -602,602,602,602,602,602,602,602,602,602,602,602,602,602,196,196, -602,602,602,602,602,196,196,196,196,196,196,196,196,196,196,196, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,163, +546,546,546,547,547,547,547,546,546,547,547,547,163,163,163,163, +547,547,546,547,547,547,547,547,547,548,548,548,163,163,163,163, +549,163,163,163,550,550,551,551,551,551,551,551,551,551,551,551, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,163,163, +552,552,552,552,552,163,163,163,163,163,163,163,163,163,163,163, /* block 49 */ -603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603, -603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603, -603,603,603,603,603,603,603,603,603,603,603,603,196,196,196,196, -603,603,603,603,603,604,604,604,603,603,604,603,603,603,603,603, -603,603,603,603,603,603,603,603,603,603,196,196,196,196,196,196, -605,605,605,605,605,605,605,605,605,605,606,196,196,196,607,607, -608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608, -608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,163,163,163,163, +553,553,553,553,553,554,554,554,553,553,554,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,163,163,163,163,163,163, +555,555,555,555,555,555,555,555,555,555,556,163,163,163,557,557, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, /* block 50 */ -609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609, -609,609,609,609,609,609,609,610,610,611,611,610,196,196,612,612, -613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613, -613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613, -613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613, -613,613,613,613,613,614,615,614,615,615,615,615,615,615,615,196, -616,617,615,617,617,615,615,615,615,615,615,615,615,614,614,614, -614,614,614,615,615,618,618,618,618,618,618,618,618,196,196,618, +559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, +559,559,559,559,559,559,559,560,560,561,561,560,163,163,562,562, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,564,565,564,565,565,565,565,565,565,565,163, +566,567,565,567,567,565,565,565,565,565,565,565,565,564,564,564, +564,564,564,565,565,568,568,568,568,568,568,568,568,163,163,568, /* block 51 */ -619,619,619,619,619,619,619,619,619,619,196,196,196,196,196,196, -619,619,619,619,619,619,619,619,619,619,196,196,196,196,196,196, -620,620,620,620,620,620,620,621,622,622,622,622,620,620,196,196, -176,176,176,176,176,176,176,176,176,176,176,176,176,176,623,624, -624,176,176,176,176,176,176,176,176,176,176,176,624,624,624,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, +569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, +570,570,570,570,570,570,570,571,572,572,572,572,570,570,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,573,574, +574,154,154,154,154,154,154,154,154,154,154,154,574,574,574,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 52 */ -625,625,625,625,626,627,627,627,627,627,627,627,627,627,627,627, -627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, -627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, -627,627,627,627,628,629,625,625,625,625,625,629,625,629,626,626, -626,626,625,629,630,627,627,627,627,627,627,627,627,196,631,631, -632,632,632,632,632,632,632,632,632,632,631,631,633,634,631,631, -633,635,635,635,635,635,635,635,635,635,635,628,628,628,628,628, -628,628,628,628,635,635,635,635,635,635,635,635,635,631,631,631, +575,575,575,575,576,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,578,579,575,575,575,575,575,576,575,576,576,576, +576,576,575,576,580,577,577,577,577,577,577,577,577,163,163,163, +581,581,581,581,581,581,581,581,581,581,582,582,583,584,582,582, +583,585,585,585,585,585,585,585,585,585,585,578,578,578,578,578, +578,578,578,578,585,585,585,585,585,585,585,585,585,582,582,163, /* block 53 */ -636,636,637,638,638,638,638,638,638,638,638,638,638,638,638,638, -638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638, -638,637,636,636,636,636,637,637,636,636,639,640,636,636,638,638, -641,641,641,641,641,641,641,641,641,641,638,638,638,638,638,638, -642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642, -642,642,642,642,642,642,642,642,642,642,642,642,642,642,642,642, -642,642,642,642,642,642,643,644,645,645,644,644,644,645,644,645, -645,645,646,646,196,196,196,196,196,196,196,196,647,647,647,647, +586,586,587,588,588,588,588,588,588,588,588,588,588,588,588,588, +588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588, +588,587,586,586,586,586,587,587,586,586,589,590,586,586,588,588, +591,591,591,591,591,591,591,591,591,591,588,588,588,588,588,588, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,593,594,595,595,594,594,594,595,594,595, +595,595,596,596,163,163,163,163,163,163,163,163,597,597,597,597, /* block 54 */ -648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, -648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, -648,648,648,648,649,649,649,649,649,649,649,649,650,650,650,650, -650,650,650,650,649,649,651,652,196,196,196,653,653,654,654,654, -655,655,655,655,655,655,655,655,655,655,196,196,196,648,648,648, -656,656,656,656,656,656,656,656,656,656,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,658,658,658,659,658,658,660,660, +598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, +598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, +598,598,598,598,599,599,599,599,599,599,599,599,600,600,600,600, +600,600,600,600,599,599,601,602,163,163,163,603,603,604,604,604, +605,605,605,605,605,605,605,605,605,605,163,163,163,598,598,598, +606,606,606,606,606,606,606,606,606,606,607,607,607,607,607,607, +607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607, +607,607,607,607,607,607,607,607,608,608,608,609,608,608,610,610, /* block 55 */ -661,662,663,664,665,666,667,668,669,275,276,196,196,196,196,196, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, -670,670,670,670,670,670,670,670,670,670,670,196,196,670,670,670, -671,671,671,671,671,671,671,671,196,196,196,196,196,196,196,196, -672,673,672,674,673,675,675,676,675,676,677,673,676,676,673,673, -676,678,673,673,673,673,673,673,673,679,680,681,681,675,681,681, -681,681,682,683,684,680,680,685,686,686,687,196,196,196,196,196, +611,612,613,614,615,616,617,618,619,163,163,163,163,163,163,163, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +620,620,620,620,620,620,620,620,620,620,620,163,163,620,620,620, +621,621,621,621,621,621,621,621,163,163,163,163,163,163,163,163, +622,623,622,624,623,625,625,626,625,626,627,623,626,626,623,623, +626,628,623,623,623,623,623,623,623,629,630,631,631,625,631,631, +631,631,632,633,634,630,630,635,636,636,637,163,163,163,163,163, /* block 56 */ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70,256,256,256,256,256,688,149,149,149,149, -149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, -149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, -149,149,149,149,149,149,149,149,149,149,149,149,149,689,689,689, -689,689,150,149,149,149,689,689,689,689,689, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70,690,691, 70, 70, 70,692, 70, 70, + 70, 70, 70, 70, 70, 70,221,221,221,221,221,638,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,639,639,639, +639,639,148,147,147,147,639,639,639,639,639, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70,640,641, 70, 70, 70,642, 70, 70, /* block 57 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,693, 70, - 70, 70, 70, 70, 70, 70,694, 70, 70, 70, 70,695,695,695,695,695, -695,695,695,695,696,695,695,695,696,695,695,695,695,695,695,695, -695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,697, -698,698,189,189,176,176,176,176,176,176,176,176,176,176,176,176, -189,189,189,624,624,624,624,624,624,624,624,624,624,624,624,624, -624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624, -624,624,624,624,624,176,176,176,699,176,700,176,176,176,176,176, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,643, 70, + 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,645,645,645,645,645, +645,645,645,645,646,645,645,645,646,645,645,645,645,645,645,645, +645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,647, +648,648,158,158,154,154,154,154,154,154,154,154,154,154,154,154, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,574,574,574,574,574,574,574,574,574, +574,574,574,574,574,154,154,154,649,154,650,154,154,154,154,154, /* block 58 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, @@ -3230,12 +2986,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 80640 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -701,702, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, +651,652, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 59 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,703,704, 70, 70,705, 70, + 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,653,654, 70, 70,655, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66, 65, 66, @@ -3244,123 +3000,123 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 80640 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 60 */ -706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, -706,706,706,706,706,706,196,196,707,707,707,707,707,707,196,196, -706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, -706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, -706,706,706,706,706,706,196,196,707,707,707,707,707,707,196,196, -708,706,708,706,708,706,708,706,196,707,196,707,196,707,196,707, -706,706,706,706,706,706,706,706,707,707,707,707,707,707,707,707, -709,709,710,710,710,710,711,711,712,712,713,713,714,714,196,196, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, +173,656,173,656,173,656,173,656,163,657,163,657,163,657,163,657, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +658,658,659,659,659,659,660,660,661,661,662,662,663,663,163,163, /* block 61 */ -715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716, -715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716, -715,715,715,715,715,715,715,715,716,716,716,716,716,716,716,716, -706,706,717,718,717,196,708,717,707,707,719,719,720,201,721,201, -201,201,717,718,717,196,708,717,722,722,722,722,720,201,201,201, -706,706,708,723,196,196,708,708,707,707,724,724,196,201,201,201, -706,706,708,725,708,250,708,708,707,707,726,726,255,201,201,201, -196,196,717,718,717,196,708,717,727,727,728,728,720,201,201,196, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +656,656,666,667,666,163,173,666,657,657,668,668,669,162,670,162, +162,162,666,667,666,163,173,666,671,671,671,671,669,162,162,162, +656,656,173,173,163,163,173,173,657,657,672,672,163,162,162,162, +656,656,173,173,173,215,173,173,657,657,673,673,220,162,162,162, +163,163,666,667,666,163,173,666,674,674,675,675,669,162,162,163, /* block 62 */ -729,729,729,729,729,729,729,729,729,729,729, 51,730,731,732,733, -734,734,734,734,734,734,735, 43,736,737,738,739,739,740,738,739, - 43, 43, 43, 43,741, 43, 43,742,743,744,745,746,747,748,749,750, -751,751,752,752,752, 43, 43, 43, 43, 49, 57, 43,753,754, 43,755, -756, 43, 43, 43,757,758,759,754,754,753, 43, 43, 43, 43, 43,760, - 43, 43, 50,761,755, 43, 43, 43, 43, 43,762, 43, 43,763, 43,729, - 51,764,764,764,764,765,766,767,768,769,770,770,770,770,770,770, - 54,696,196,196, 54, 54, 54, 54, 54, 54,771,772,773,774,775,695, +676,676,676,676,676,676,676,676,676,676,676, 51,677,678,679,680, +681,681,681,681,681,681,682, 43,683,684,685,686,686,687,685,686, + 43, 43, 43, 43,688, 43, 43,688,689,690,691,692,693,694,695,696, +697,697,698,698,698, 43, 43, 43, 43, 49, 57, 43,699,700, 43,701, +702, 43, 43, 43,703,704,705,700,700,699, 43, 43, 43, 43, 43, 43, + 43, 43, 50,706,701, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,676, + 51,707,707,707,707,708,709,710,711,712,713,713,713,713,713,713, + 54,646,163,163, 54, 54, 54, 54, 54, 54,714,715,716,717,718,645, /* block 63 */ - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,771,772,773,774,775,196, -695,695,695,695,695,695,695,695,695,695,695,695,695,196,196,196, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, -479,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776, -777,777,777,777,777,777,777,777,777,777,777,777,777,778,778,778, -778,777,778,779,778,777,777,189,189,189,189,777,777,777,777,777, -780,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,714,715,716,717,718,163, +645,645,645,645,645,645,645,645,645,645,645,645,645,163,163,163, +430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, +430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, +430,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719, +720,720,720,720,720,720,720,720,720,720,720,720,720,721,721,721, +721,720,721,722,721,720,720,158,158,158,158,720,720,720,720,720, +723,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 64 */ -781,781,782,781,781,781,781,782,781,781,783,782,782,782,783,783, -782,782,782,783,781,782,781,781,784,782,782,782,782,782,781,781, -781,781,785,781,782,781,786,781,782,787,788,789,782,782,790,783, -782,782,791,782,783,792,792,792,792,793,781,781,783,783,782,782, -794,794,794,794,794,782,783,783,795,795,781,794,781,781,796,510, +724,724,725,724,724,724,724,725,724,724,726,725,725,725,726,726, +725,725,725,726,724,725,724,724,727,725,725,725,725,725,724,724, +724,724,728,724,725,724,729,724,725,730,731,732,725,725,733,726, +725,725,734,725,726,735,735,735,735,736,724,724,726,726,725,725, +716,716,716,716,716,725,726,726,737,737,724,716,724,724,738,461, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797, -798,798,798,798,798,798,798,798,798,798,798,798,798,798,798,798, +739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739, +740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, /* block 65 */ -799,799,799, 65, 66,799,799,799,799, 58,781,781,196,196,196,196, - 50, 50, 50, 50,800,801,801,801,801,801, 50, 50,802,802,802,802, - 50,802,802, 50,802,802, 50,802, 45,801,801,802,802,802, 50, 45, -802,802, 45, 45, 45, 45,802,802, 45, 45, 45, 45,802,802,802,802, -802,802,802,802,802,802,802,802,802,802,802,802,802,802, 50, 50, -802,802, 50,802, 50,802,802,802,802,802,802,802, 45,802, 45, 45, - 45, 45, 45, 45,802,802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +741,741,741, 65, 66,741,741,741,741, 58,724,724,163,163,163,163, + 50, 50, 50, 50,742,743,743,743,743,743, 50, 50,744,744,744,744, + 50,744,744, 50,744,744, 50,744, 45,743,743,744,744,744, 50, 45, +744,744, 45, 45, 45, 45,744,744, 45, 45, 45, 45,744,744,744,744, +744,744,744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, +744,744, 50,744, 50,744,744,744,744,744,744,744, 45,744, 45, 45, + 45, 45, 45, 45,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 66 */ - 50, 50,803, 50, 50, 50, 50,803,804,804,804,804,804,804, 50, 50, - 50, 50,805, 53, 50,804, 50, 50, 50, 50, 50, 50, 50, 50,803,804, -804,804,804, 50,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804, 50, 50, - 50, 50, 50,804, 50,804, 50, 50, 50, 50, 50, 50,804, 50, 50, 50, - 50, 50,804,804,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,804,804,804,804,804,804,804,804, 50, 50,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, + 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745, 50, 50, + 50, 50,746, 53, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, +745,745,745, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, + 50, 50, 50,745, 50,745, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, + 50, 50,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,745,745,745,745,745,745,745,745, 50, 50,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, /* block 67 */ -804,804,804,804,804,804,804,804,804,804,804,804, 50, 50, 50,804, -804,804,804, 50, 50, 50, 50, 50,804, 50, 50, 50, 50, 50, 50, 50, - 50, 50,804,804, 50, 50,804, 50,804,804, 50,804, 50, 50, 50, 50, -804,804,804,804,804,804,804,804,804, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804,804, 50, 50, -804,804, 50, 50, 50, 50,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804, 50, 50, -804,804,804,804,804, 50,804,804, 50, 50,804,804,804,804,804, 50, +745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, 50,745, +745,745,745, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, + 50, 50,745,745, 50, 50,745, 50,745,745, 50,745, 50, 50, 50, 50, +745,745,745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745, 50, 50, +745,745, 50, 50, 50, 50,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, +745,745,745,745,745, 50,745,745, 50, 50,745,745,745,745,745, 50, /* block 68 */ - 45, 45, 45, 45, 45, 45, 45, 45,806,807,806,807, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808,808, 45, 45, 45, 45, - 50, 50, 45, 45, 45, 45, 45, 45, 47,809,810, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,811,811,811,811,811,811,811,811,811,811, -811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811, -811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811, -811,811,811,811,811,811,811,811,811,811,811,811,811,811,811,811, -811,811,811,811,811,811,811,811,811,811,811, 45, 50, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45,747,748,747,748, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, 45, + 50, 50, 45, 45, 45, 45, 45, 45, 47,750,751, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752, 45, 50, 45, 45, 45, /* block 69 */ - 45, 45, 45, 45, 45, 45, 45, 45,812, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45,811, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, + 45, 45, 45, 45, 45, 45, 45, 45,753, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45,752, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,802,802, 45,802, 45, 45, 45, 45, 45, 45, 45, 45, + 50, 50, 50, 50,744,744, 45,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, -802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, - 50, 50,802, 45, 45, 45, 45, 45, 45,808,808,808,808, 47, 47, 47, -808, 47, 47,808, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, +744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, + 50, 50,744, 45, 45, 45, 45, 45, 45,749,749,749,749, 47, 47, 47, +749, 47, 47,749, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, /* block 70 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,813,813,813,813,813,813, -813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,813,813,813,813,813, -813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, + 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 71 */ - 58, 58, 58, 58, 58, 58, 58, 58,814,814,814,814,814,814,814,814, -814,814,814,814,814,814,814,814,814,814,814,814,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,815,815,815,815,815,815,815,815,815,815, -815,815,816,815,815,815,815,815,815,815,815,815,815,815,815,815, -817,817,817,817,817,817,817,817,817,817,817,817,817,817,817,817, -817,817,817,817,817,817,817,817,817,817, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,755,755,755,755,755,755,755,755,755,755, +755,755,756,755,755,755,755,755,755,755,755,755,755,755,755,755, +757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, +757,757,757,757,757,757,757,757,757,757, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 72 */ @@ -3376,2422 +3132,2322 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 80640 bytes, block = 128 */ /* block 73 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -802,802, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,802,802, -802,802,802,802,802,802,801, 50, 45, 45, 45, 45,802,802,802,802, -801, 50, 45, 45, 45, 45,802,802, 45, 45,802,802, 45, 45, 45,802, -802,802,802,802, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45,802, 45,802, 45, 45,802,802,802,802,802,802, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,800,800,818,818, 50, +744,744, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,744,744, +744,744,744,744,744,744,743, 50, 45, 45, 45, 45,744,744,744,744, +743, 50, 45, 45, 45, 45,744,744, 45, 45,744,744, 45, 45, 45,744, +744,744,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45,744, 45,744, 45, 45,744,744,744,744,744,744, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,742,742,758,758, 50, /* block 74 */ - 47, 47, 47, 47, 47,819,802,812,812,812,812,812,812,812, 47,812, -812, 47,812, 45,808,808,812,812, 47,812,812,812,812,820,812,812, - 47,812, 47, 47,812,812, 47,812,812,812, 47,812,812,812, 47, 47, -812,812,812,812,812,812,812,812, 47, 47, 47,812,812,812,812,812, -801,812,801,812,812,812,812,812,808,808,808,808,808,808,808,808, -808,808,808,808,812,812,812,812,812,812,812,812,812,812,812, 47, -801,819,819,801,812, 47, 47,812, 47,812,812,812,812,819,819,821, -812,812,812,812,812,812,812,812,812,812,812, 47,812,812, 47,808, + 47, 47, 47, 47, 47,759,744,753,753,753,753,753,753,753, 47,753, +753, 47,753, 45,749,749,753,753, 47,753,753,753,753,760,753,753, + 47,753, 47, 47,753,753, 47,753,753,753, 47,753,753,753, 47, 47, +753,753,753,753,753,753,753,753, 47, 47, 47,753,753,753,753,753, +743,753,743,753,753,753,753,753,749,749,749,749,749,749,749,749, +749,749,749,749,753,753,753,753,753,753,753,753,753,753,753, 47, +743,759,759,743,753, 47, 47,753, 47,753,753,753,753,759,759,761, +753,753,753,753,753,753,753,753,753,753,753, 47,753,753, 47,749, /* block 75 */ -812,812,812,812,812,812, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -812,812, 47,808, 47, 47, 47, 47,812, 47,812, 47, 47,812,812,812, - 47,808,812,812,812,812,812, 47,812,812,808,808,822,812,812,812, - 47, 47,812,812,812,812,812,812,812,812,812,812,812,808,808,812, -812,812,812,812,808,808,812,812, 47,812,812,812,812,812,808, 47, -812, 47,812, 47,808,812,812,812,812,812,812,812,812,812,812,812, -812,812,812,812,812,812,812,812,812, 47,808,812,812,812,812,812, - 47, 47,808,808, 47,808,812, 47, 47,820,808,812,812,808,812,812, +753,753,753,753,753,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +753,753, 47,749, 47, 47, 47, 47,753, 47,753, 47, 47,753,753,753, + 47,749,753,753,753,753,753, 47,753,753,749,749,762,753,753,753, + 47, 47,753,753,753,753,753,753,753,753,753,753,753,749,749,753, +753,753,753,753,749,749,753,753, 47,753,753,753,753,753,749, 47, +753, 47,753, 47,749,753,753,753,753,753,753,753,753,753,753,753, +753,753,753,753,753,753,753,753,753, 47,749,753,753,753,753,753, + 47, 47,749,749, 47,749,753, 47, 47,760,749,753,753,749,753,753, /* block 76 */ -812,812, 47,812,812,808, 45, 45, 47, 47,823,823,820,820,812, 47, -812,812, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, - 45, 47, 45, 45, 45, 45, 45, 45,808, 45, 45, 45, 45, 45, 45, 45, +753,753, 47,753,753,749, 45, 45, 47, 47,763,763,760,760,753, 47, +753,753, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, + 45, 47, 45, 45, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,808, 45,808, 45, - 45, 45, 45,808,808,808, 45,808, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 47, 47,812,812,812,758,759,758,759,758,759,758,759, -758,759,758,759,758,759, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,749, 45,749, 45, + 45, 45, 45,749,749,749, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 47, 47,753,753,753,704,705,704,705,704,705,704,705, +704,705,704,705,704,705, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 77 */ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 45,808,808,808, 45, 45, 45, 45, 45, 45, 45, 45, + 58, 58, 58, 58, 45,749,749,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808, - 50, 50, 50,804,804,806,807, 50,804,804, 50,804, 50,804, 50, 50, - 50, 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50,804,804,804, 50, - 50, 50,804,804,804,804,806,807,806,807,806,807,806,807,806,807, +749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749, + 50, 50, 50,745,745,747,748, 50,745,745, 50,745, 50,745, 50, 50, + 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50,745,745,745, 50, + 50, 50,745,745,745,745,747,748,747,748,747,748,747,748,747,748, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 78 */ -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, /* block 79 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,800,800, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,742,742, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 80 */ - 50, 50, 50,806,807,806,807,806,807,806,807,806,807,806,807,806, -807,806,807,806,807,806,807,806,807, 50, 50,804, 50, 50, 50, 50, -804, 50, 50,804,804,804, 50, 50,804,804,804,804,804,804,804,804, - 50, 50, 50, 50, 50, 50, 50, 50,804, 50, 50, 50, 50, 50, 50, 50, -804,804, 50, 50,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50,804, -804,804,804, 50,804,804, 50, 50,806,807,806,807, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50,804, 50, 50,804,804, 50, 50,806,807, 50, 50, + 50, 50, 50,747,748,747,748,747,748,747,748,747,748,747,748,747, +748,747,748,747,748,747,748,747,748, 50, 50,745, 50, 50, 50, 50, +745, 50, 50,745,745,745, 50, 50,745,745,745,745,745,745,745,745, + 50, 50, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, +745,745, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, +745,745,745, 50,745,745, 50, 50,747,748,747,748, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50,745, 50, 50,745,745, 50, 50,747,748, 50, 50, /* block 81 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804, 50, - 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50,804,804, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, + 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,804,804, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,804,804,804,804,804,804,804, + 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745,745, /* block 82 */ -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804, 50, 50, 50,804,804,804,804,804,804,804,804, 50,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804, 50, 50, 50, 50, 50, 50, 50,804, 50, - 50, 50, 50,804,804,804, 50, 50, 50, 50, 50, 50,804,804,804, 50, - 50, 50, 50, 50, 50, 50, 50,804,804,804,804, 50, 50, 50, 50, 50, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745, 50, 50, 50,745,745,745,745,745,745,745,745, 50,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50,745, 50, + 50, 50, 50,745,745,745, 50, 50, 50, 50, 50, 50,745,745,745, 50, + 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, 50, 50, 50, 50, /* block 83 */ 45, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,808,808, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 45, 45, 50, 50, 50, 50, 50, 50, 45, 45, 45, -808, 45, 45, 45, 45,808, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +749, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45,813,813, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45,754,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, /* block 84 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,813, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,825, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,765, 45, /* block 85 */ -826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826, -826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826, -826,826,826,826,826,826,826,826,826,826,826,826,826,826,826,826, -827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827, -827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827, -827,827,827,827,827,827,827,827,827,827,827,827,827,827,827,827, - 65, 66,828,829,830,831,832, 65, 66, 65, 66, 65, 66,833,834,835, -836, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,696,695,837,837, +766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, +766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, +766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, + 65, 66,768,769,770,771,772, 65, 66, 65, 66, 65, 66,773,774,775, +776, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,646,645,777,777, /* block 86 */ -246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, -246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, -246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, -246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, -246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, -246,247,246,247,246,247,246,247,246,247,246,247,246,247,246,247, -246,247,246,247,838,839,839,839,839,839,839,246,247,246,247,840, -840,840,246,247,196,196,196,196,196,841,841,841,842,843,842,842, +211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, +211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, +211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, +211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, +211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, +211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, +211,212,211,212,778,779,779,779,779,779,779,211,212,211,212,780, +780,780,211,212,163,163,163,163,163,781,781,781,781,782,781,781, /* block 87 */ -844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844, -844,844,844,844,844,844,844,844,844,844,844,844,844,844,844,844, -844,844,844,844,844,844,196,844,196,196,196,196,196,844,196,196, -845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, -845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, -845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, -845,845,845,845,845,845,845,845,196,196,196,196,196,196,196,846, -847,196,196,196,196,196,196,196,196,196,196,196,196,196,196,848, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +783,783,783,783,783,783,163,783,163,163,163,163,163,783,163,163, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,163,163,163,163,163,163,163,785, +786,163,163,163,163,163,163,163,163,163,163,163,163,163,163,787, /* block 88 */ -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,533, -533,533,533,533,533,533,533,196,196,196,196,196,196,196,196,196, -533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, -533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, -533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, -533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, -849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, -849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, +788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, /* block 89 */ - 43, 43,850,851,850,851, 43, 43, 43,850,851, 43,850,851, 43, 43, - 43, 43, 43, 43, 43, 43, 43,852, 43, 43,734, 43,850,851, 43, 43, -850,851,758,759,758,759,758,759,758,759, 43, 43, 43, 43,754,853, -854,855, 43, 43, 43, 43, 43, 43, 43, 43,734,734,856, 43, 43, 43, -734,857,738,858, 43, 43, 43, 43, 43, 43, 43, 43,859, 43,859,859, - 45, 45, 43,754,754,758,759,758,759,758,759,758,759,734,813,813, -813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, -813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, + 43, 43,789,790,789,790, 43, 43, 43,789,790, 43,789,790, 43, 43, + 43, 43, 43, 43, 43, 43, 43,681, 43, 43,681, 43,789,790, 43, 43, +789,790,704,705,704,705,704,705,704,705, 43, 43, 43, 43,700,791, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,681,681,700, 43, 43, 43, +681,792,685,793, 43, 43, 43, 43, 43, 43, 43, 43,792, 43,792,792, + 45, 45, 43,700,700,704,705,704,705,704,705,704,705,681,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, /* block 90 */ -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,196,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,196,196,196,196,196,196,196,196,196,196,196,196, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,163,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,163,163,163,163,163,163,163,163,163,163,163,163, /* block 91 */ -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, /* block 92 */ -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,860,860,860,860,860,860,860,860,860,860, -860,860,860,860,860,860,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -861,861,862,862,861,861,861,861,861,861,861,861,861,861,863,863, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +795,795,796,796,795,795,795,795,795,795,795,795,163,163,163,163, /* block 93 */ -729,864,865,866,781,867,868,869,870,871,872,873,874,875,874,875, -876,877, 45,878,876,877,876,877,876,877,876,877,879,880,881,881, - 45,869,869,869,869,869,869,869,869,869,882,882,882,882,883,883, -884,885,885,885,885,885,781,886,869,869,869,887,888,889,890,890, -196,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +676,797,798,799,724,800,801,802,803,804,803,804,805,806,805,806, +803,804, 45,807,803,804,803,804,803,804,803,804,808,809,810,810, + 45,802,802,802,802,802,802,802,802,802,811,811,811,811,812,812, +813,814,814,814,814,814,724,815,802,802,802,816,817,818,819,819, +163,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 94 */ -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,196,196,892,892,893,893,894,894,891, -895,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,897,898,899,899,896, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,163,163,821,821,822,822,823,823,820, +824,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,826,827,828,828,825, /* block 95 */ -196,196,196,196,196,900,900,900,900,900,900,900,900,900,900,900, -900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, -900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, -196,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,902,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +163,163,163,163,163,829,829,829,829,829,829,829,829,829,829,829, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +163,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,831,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, /* block 96 */ -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,196, -903,903,904,904,904,904,903,903,903,903,903,903,903,903,903,903, -900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, -900,900,900,900,900,900,900,900,900,900,900,900,900,900,900,900, -890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,890, -890,890,890,890,890,890,890,890,890,890,890,890,890,890,890,890, -890,890,890,890,890,890,196,196,196,196,196,196,196,196,196,861, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, +832,832,833,833,833,833,832,832,832,832,832,832,832,832,832,832, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,163,163,163,163,163,163,163,163,163,163,163,163, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, /* block 97 */ -905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, -905,905,905,905,905,905,905,905,905,905,905,905,905,906,906,196, -904,904,904,904,904,904,904,904,904,904,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,907,907,907,907,907,907,907,907, -781, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, -905,905,905,905,905,905,905,905,905,905,905,905,906,906,906,510, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,834,834,835,835,163, +833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,836,836,836,836,836,836,836,836, +724, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,834,835,835,835,461, /* block 98 */ -904,904,904,904,904,904,904,904,904,904,903,903,903,903,903,903, -903,903,903,903,903,903,903,908,903,908,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -903,903,903,903,903,903,903,903,903,903,903,903,781,781,781,781, -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,903, +833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, +832,832,832,832,832,832,832,837,832,837,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +832,832,832,832,832,832,832,832,832,832,832,832,724,724,724,724, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,832, /* block 99 */ -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, -909,909,909,909,909,909,909,909,909,909,909,909,909,909,909,909, -909,909,909,909,909,909,909,909,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,510,510,510,510,510,510,781,781,781,781,903,903,903,903,903, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,461,461,461,461,461,461,724,724,724,724,832,832,832,832,832, /* block 100 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,781,781, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,781, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,724,724, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,724, /* block 101 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 102 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 103 */ -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,912,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,841,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, /* block 104 */ -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, /* block 105 */ -911,911,911,911,911,911,911,911,911,911,911,911,911,196,196,196, -913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, -913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, -913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, -913,913,913,913,913,913,913,196,196,196,196,196,196,196,196,196, -914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914, -914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914, -914,914,914,914,914,914,914,914,915,915,915,915,915,915,916,917, +840,840,840,840,840,840,840,840,840,840,840,840,840,163,163,163, +842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, +842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, +842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, +842,842,842,842,842,842,842,163,163,163,163,163,163,163,163,163, +843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, +843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, +843,843,843,843,843,843,843,843,844,844,844,844,844,844,845,846, /* block 106 */ -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, /* block 107 */ -918,918,918,918,918,918,918,918,918,918,918,918,919,920,921,921, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -922,922,922,922,922,922,922,922,922,922,918,918,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -275,276,275,276,275,276,275,276,275,276,923,924,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,275,276,925,281, -283,283,283,926,849,849,849,849,849,849,849,849,927,927,926,928, +847,847,847,847,847,847,847,847,847,847,847,847,848,849,850,850, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +851,851,851,851,851,851,851,851,851,851,847,847,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +240,241,240,241,240,241,240,241,240,241,852,853,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,854,246, +248,248,248,855,788,788,788,788,788,788,788,788,856,856,855,857, /* block 108 */ -275,276,275,276,275,276,275,276,275,276,275,276,275,276,275,276, -275,276,275,276,275,276,275,276,275,276,275,276,929,929,849,849, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,931,931,931,931,931,931,931,931,931,931, -932,932,933,934,935,935,935,934,196,196,196,196,196,196,196,196, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,240,241,858,858,788,788, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,860,860,860,860,860,860,860,860,860,860, +861,861,862,863,864,864,864,863,163,163,163,163,163,163,163,163, /* block 109 */ -936,936,936,936,936,936,936,936, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46,151,151,151,151,151,151,151,151,151, +865,865,865,865,865,865,865,865, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149, 46, 46, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 70, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -695, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,937, 65, 66, +645, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,866, 65, 66, /* block 110 */ - 65, 66, 65, 66, 65, 66, 65, 66,151,938,938, 65, 66,939, 70, 93, - 65, 66, 65, 66,940, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,941,942,943,944,941, 70, -945,946,947,948, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66,949,950,951, 65, 66, 65, 66,952, 65, 66,196,196, - 65, 66,196, 70,196, 70, 65, 66, 65, 66, 65, 66,953,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,695,695,695, 65, 66, 93,149,149, 70, 93, 93, 93, 93, 93, + 65, 66, 65, 66, 65, 66, 65, 66,149,867,867, 65, 66,868, 70, 92, + 65, 66, 65, 66,869, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,870,871,872,873,870, 70, +874,875,876,877, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66,878,879,880, 65, 66, 65, 66,163,163,163,163,163, + 65, 66,163, 70,163, 70, 65, 66, 65, 66,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,645,645,645, 65, 66, 92,147,147, 70, 92, 92, 92, 92, 92, /* block 111 */ -954,954,955,954,954,954,956,954,954,954,954,955,954,954,954,954, -954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -954,954,954,957,957,955,955,957,958,958,958,958,956,196,196,196, -959,959,959,960,960,960,961,961,962,963,196,196,196,196,196,196, -964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, -964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, -964,964,964,964,964,964,964,964,964,964,964,964,964,964,964,964, -964,964,964,964,965,965,966,966,196,196,196,196,196,196,196,196, +881,881,882,881,881,881,883,881,881,881,881,882,881,881,881,881, +881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881, +881,881,881,884,884,882,882,884,885,885,885,885,883,163,163,163, +886,886,886,887,887,887,888,888,889,890,163,163,163,163,163,163, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,892,892,893,893,163,163,163,163,163,163,163,163, /* block 112 */ -967,967,968,968,968,968,968,968,968,968,968,968,968,968,968,968, -968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,968, -968,968,968,968,968,968,968,968,968,968,968,968,968,968,968,968, -968,968,968,968,967,967,967,967,967,967,967,967,967,967,967,967, -967,967,967,967,969,970,196,196,196,196,196,196,196,196,971,971, -972,972,972,972,972,972,972,972,972,972,196,196,196,196,196,196, -378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, -378,973,376,974,376,376,376,376,385,385,385,376,385,376,376,374, +894,894,895,895,895,895,895,895,895,895,895,895,895,895,895,895, +895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, +895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, +895,895,895,895,894,894,894,894,894,894,894,894,894,894,894,894, +894,894,894,894,896,897,163,163,163,163,163,163,163,163,898,898, +899,899,899,899,899,899,899,899,899,899,163,163,163,163,163,163, +336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336, +336,900,335,901,335,335,335,335,343,343,343,335,343,335,335,333, /* block 113 */ -975,975,975,975,975,975,975,975,975,975,976,976,976,976,976,976, -976,976,976,976,976,976,976,976,976,976,976,976,976,976,976,976, -976,976,976,976,976,976,977,977,977,977,977,978,978,978,979,980, -981,981,981,981,981,981,981,981,981,981,981,981,981,981,981,981, -981,981,981,981,981,981,981,982,982,982,982,982,982,982,982,982, -982,982,983,984,196,196,196,196,196,196,196,196,196,196,196,985, -528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, -528,528,528,528,528,528,528,528,528,528,528,528,528,196,196,196, +902,902,902,902,902,902,902,902,902,902,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,904,904,904,904,904,905,905,905,906,907, +908,908,908,908,908,908,908,908,908,908,908,908,908,908,908,908, +908,908,908,908,908,908,908,909,909,909,909,909,909,909,909,909, +909,909,910,911,163,163,163,163,163,163,163,163,163,163,163,912, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,163,163,163, /* block 114 */ -986,986,986,987,988,988,988,988,988,988,988,988,988,988,988,988, -988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,988, -988,988,988,988,988,988,988,988,988,988,988,988,988,988,988,988, -988,988,988,989,987,987,986,986,986,986,987,987,986,986,987,987, -990,991,991,991,991,991,991,992,993,993,991,991,991,991,196,994, -995,995,995,995,995,995,995,995,995,995,196,196,196,196,991,991, -511,511,511,511,511,521,996,511,511,511,511,511,511,511,511,511, -522,522,522,522,522,522,522,522,522,522,511,511,511,511,511,196, +913,913,913,914,915,915,915,915,915,915,915,915,915,915,915,915, +915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, +915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, +915,915,915,916,914,914,913,913,913,913,914,914,913,913,914,914, +917,918,918,918,918,918,918,919,920,920,918,918,918,918,163,921, +922,922,922,922,922,922,922,922,922,922,163,163,163,163,918,918, +462,462,462,462,462,472,923,462,462,462,462,462,462,462,462,462, +473,473,473,473,473,473,473,473,473,473,462,462,462,462,462,163, /* block 115 */ -997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, -997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, -997,997,997,997,997,997,997,997,997,998,998,998,998,998,998,999, -999,998,998,999,999,998,998,196,196,196,196,196,196,196,196,196, -997,997,997,998,997,997,997,997,997,997,997,997,998,999,196,196, -1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,196,196,1001,1002,1002,1002, -511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, -996,511,511,511,511,511,511,523,523,523,511,520,521,520,511,511, +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,925,925,925,925,925,925,926, +926,925,925,926,926,925,925,163,163,163,163,163,163,163,163,163, +924,924,924,925,924,924,924,924,924,924,924,924,925,926,163,163, +927,927,927,927,927,927,927,927,927,927,163,163,928,929,929,929, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +923,462,462,462,462,462,462,474,474,474,462,471,472,471,462,462, /* block 116 */ -1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, -1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, -1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, -1004,1003,1004,1004,1004,1005,1005,1004,1004,1005,1003,1005,1005,1003,1004,1006, -1007,1006,1007,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,1003,1003,1008,1009,1010, -1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1012,1013,1013,1012,1012, -1014,1014,1011,1015,1015,1012,1016,196,196,196,196,196,196,196,196,196, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +931,930,931,931,931,932,932,931,931,932,930,932,932,930,931,933, +934,933,934,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,930,930,935,936,937, +938,938,938,938,938,938,938,938,938,938,938,939,940,940,939,939, +941,941,938,942,942,939,943,163,163,163,163,163,163,163,163,163, /* block 117 */ -196,533,533,533,533,533,533,196,196,533,533,533,533,533,533,196, -196,533,533,533,533,533,533,196,196,196,196,196,196,196,196,196, -533,533,533,533,533,533,533,196,533,533,533,533,533,533,533,196, +163,484,484,484,484,484,484,163,163,484,484,484,484,484,484,163, +163,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,1017, 70, 70, 70, 70, 70, 70, 70,938,149,149,149,149, - 70, 70, 70, 70, 70,256, 70, 70, 70,149, 46, 46,196,196,196,196, -1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, + 70, 70, 70,944, 70, 70, 70, 70, 70, 70, 70,867,147,147,147,147, + 70, 70, 70, 70, 70,221, 70, 70, 70,147, 46, 46,163,163,163,163, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, /* block 118 */ -1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, -1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, -1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, -1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, -1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, -1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, -1011,1011,1011,1012,1012,1013,1012,1012,1013,1012,1012,1014,1019,1016,196,196, -1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,196,196,196,196,196,196, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, +938,938,938,939,939,940,939,939,940,939,939,941,946,943,163,163, +947,947,947,947,947,947,947,947,947,947,163,163,163,163,163,163, /* block 119 */ -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 120 */ -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, /* block 121 */ -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 122 */ -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, /* block 123 */ -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 124 */ -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, /* block 125 */ -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 126 */ -1022,1022,1022,1022,1022,1022,1022,1022,1021,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,196,196,196,196,196,196,196,196,196,196,196,196, -531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, -531,531,531,531,531,531,531,196,196,196,196,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532, -532,532,532,532,532,532,532,532,532,532,532,532,196,196,196,196, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,163,163,163,163,163,163,163,163,163,163,163,163, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,163,163,163,163,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,163,163,163,163, /* block 127 */ -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, /* block 128 */ -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, /* block 129 */ -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, /* block 130 */ -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,910,910, -1025,910,1025,910,910,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,910, -1025,910,1025,910,910,1025,1025,910,910,910,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,839,839, +952,839,952,839,839,952,952,952,952,952,952,952,952,952,952,839, +952,839,952,839,839,952,952,839,839,839,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, /* block 131 */ -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 132 */ -703,703,703,703,703,1026,1027,196,196,196,196,196,196,196,196,196, -196,196,196,292,292,292,292,292,196,196,196,196,196,305,300,305, -305,305,305,305,305,305,305,305,305,1028,305,305,305,305,305,305, -305,305,305,305,305,305,305,297,305,305,305,305,305,297,305,297, -305,305,297,305,305,297,305,305,305,305,305,305,305,305,305,305, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +653,653,653,653,653,653,653,163,163,163,163,163,163,163,163,163, +163,163,163,257,257,257,257,257,163,163,163,163,163,270,265,270, +270,270,270,270,270,270,270,270,270,953,270,270,270,270,270,270, +270,270,270,270,270,270,270,262,270,270,270,270,270,262,270,262, +270,270,262,270,270,262,270,270,270,270,270,270,270,270,270,270, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 133 */ -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,331,331,331,331,331,331,331,331,331,331,331,331,331,331, +331,331,331,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 134 */ -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,1029,1029, -1029,1029,1029,1029,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,954,954, +954,954,954,954,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 135 */ -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 136 */ -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,1030,1031, -315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,955,956, +280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 137 */ -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -340,340,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,340,340,340,340,340,340,340,315, -1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, -1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, -321,321,1033,321,321,321,321,321,321,321,1029,1029,312,1034,315,315, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +302,302,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,302,302,302,302,302,302,302,280, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +286,286,958,286,286,286,286,286,286,286,954,954,277,959,280,280, /* block 138 */ -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1036, -1037,1037,1038,1039,1037,1038,1038,1040,1041,1037,196,196,196,196,196,196, -176,176,176,176,176,176,176,176,176,176,176,176,176,176,927,927, -1037,1042,1042,755,755,1040,1041,1040,1041,1040,1041,1040,1041,1040,1041,1040, -1041,1043,1044,1043,1044,866,866,1040,1041,1037,1037,1037,1037,755,755,755, -1045,199,1046,196,199,1047,1038,1038,1042,1048,1049,1048,1049,1048,1049,1050, -1037,1051,1052,1053,1054,1054,794,196,1051,479,1050,1037,196,196,196,196, -1029,321,1029,321,1029,340,1029,321,1029,321,1029,321,1029,321,1029,321, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,961, +962,962,962,963,962,962,962,964,965,962,163,163,163,163,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,856,856, +962,966,966,701,701,964,965,964,965,964,965,964,965,964,965,964, +965,967,968,967,968,799,799,964,965,962,962,962,962,701,701,701, +969,166,970,163,166,971,972,972,966,973,974,973,974,973,974,975, +962,976,714,977,978,978,716,163,976,430,975,962,163,163,163,163, +954,286,954,286,954,302,954,286,954,286,954,286,954,286,954,286, /* block 139 */ -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,340,340, 51, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,302,302, 51, /* block 140 */ -196,1038,1055,1050,479,1050,1037,1056,1048,1049,1037,1052,1045,1057,1046,1058, -1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1047,199,1054,794,1054,1038, -1037,1060,1060,1060,1060,1060,1060, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,1048,1051,1049,1061,755, - 46,1062,1062,1062,1062,1062,1062, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,1048,794,1049,794,1048, -1049,1063,1064,1065,1066,897,896,896,896,896,896,896,896,896,896,896, -898,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +163,972,979,975,430,975,962,980,973,974,962,714,969,981,970,982, +983,983,983,983,983,983,983,983,983,983,971,166,978,716,978,972, +962,984,984,984,984,984,984, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,973,976,974,985,701, + 46,986,986,986,986,986,986, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,973,716,974,716,973, +974,987,988,989,990,826,825,825,825,825,825,825,825,825,825,825, +827,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, /* block 141 */ -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,1067,1067, -902,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,196, -196,196,901,901,901,901,901,901,196,196,901,901,901,901,901,901, -196,196,901,901,901,901,901,901,196,196,901,901,901,196,196,196, -479,479,794, 46,781,479,479,196,781,794,794,794,794,781,781,196, -765,765,765,765,765,765,765,765,765,1068,1068,1068,781,781,1032,1032, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,991,991, +831,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, +163,163,830,830,830,830,830,830,163,163,830,830,830,830,830,830, +163,163,830,830,830,830,830,830,163,163,830,830,830,163,163,163, +430,430,716, 46,724,430,430,163,724,716,716,716,716,724,724,163, +708,708,708,708,708,708,708,708,708,992,992,992,724,724,957,957, /* block 142 */ -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,196,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,1069,1069,196,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +993,993,993,993,993,993,993,993,993,993,993,993,163,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,163,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,163,993,993,163,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 143 */ -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069, -1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,1069,196,196,196,196,196, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,163,163,163,163,163, /* block 144 */ -1070,1071,1072,196,196,196,196,1073,1073,1073,1073,1073,1073,1073,1073,1073, -1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, -1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, -1073,1073,1073,1073,196,196,196,1074,1074,1074,1074,1074,1074,1074,1074,1074, -1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, -1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, -1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, -1075,1075,1075,1075,1075,1076,1076,1076,1076,1077,1077,1077,1077,1077,1077,1077, +994,995,996,163,163,163,163,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,163,163,163,998,998,998,998,998,998,998,998,998, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,1000,1000,1000,1000,1001,1001,1001,1001,1001,1001,1001, /* block 145 */ -1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1076,1076,1077,1078,1078,196, -781,781,781,781,781,781,781,781,781,781,781,781,781,196,196,196, -1077,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,189,196,196, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1000,1000,1001,1002,1002,163, +724,724,724,724,724,724,724,724,724,724,724,724,724,163,163,163, +1001,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,158,163,163, /* block 146 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 147 */ -1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079, -1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,1079,196,196,196, -1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, -1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, -1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, -1080,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1081,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, -1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,196,196,196,196, +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,163,163,163, +1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, +1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, +1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, +1004,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1005,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006, +1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,163,163,163,163, /* block 148 */ -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1084,1084,1084,1084,196,196,196,196,196,196,196,196,196,1083,1083,1083, -1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085, -1085,1086,1085,1085,1085,1085,1085,1085,1085,1085,1086,196,196,196,196,196, -1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087, -1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,1087, -1087,1087,1087,1087,1087,1087,1088,1088,1088,1088,1088,196,196,196,196,196, +1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, +1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, +1008,1008,1008,1008,163,163,163,163,163,163,163,163,163,1007,1007,1007, +1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009, +1009,1010,1009,1009,1009,1009,1009,1009,1009,1009,1010,163,163,163,163,163, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1011,1011,1011,1012,1012,1012,1012,1012,163,163,163,163,163, /* block 149 */ -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,196,1090, -1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091, -1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091,1091, -1091,1091,1091,1091,196,196,196,196,1091,1091,1091,1091,1091,1091,1091,1091, -1092,1093,1093,1093,1093,1093,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013, +1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,163,1014, +1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, +1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, +1015,1015,1015,1015,163,163,163,163,1015,1015,1015,1015,1015,1015,1015,1015, +1016,1017,1017,1017,1017,1017,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 150 */ -1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, -1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, -1094,1094,1094,1094,1094,1094,1094,1094,1095,1095,1095,1095,1095,1095,1095,1095, -1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, -1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, -1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, -1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, -1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1019,1019,1019,1019,1019,1019,1019,1019, +1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, +1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, +1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, +1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, +1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, /* block 151 */ -1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097, -1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,1097,196,196, -1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,196,196,196,196,196,196, -1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099, -1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099, -1099,1099,1099,1099,196,196,196,196,1100,1100,1100,1100,1100,1100,1100,1100, -1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100, -1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,196,196,196,196, +1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, +1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,163,163, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,163,163,163,163,163,163, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,163,163,163,163,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,163,163,163,163, /* block 152 */ -1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, -1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, -1101,1101,1101,1101,1101,1101,1101,1101,196,196,196,196,196,196,196,196, -1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, -1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, -1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, -1102,1102,1102,1102,196,196,196,196,196,196,196,196,196,196,196,1103, -1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,196,1104,1104,1104,1104, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,163,163,163,163,163,163,163,163, +1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, +1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, +1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, +1026,1026,1026,1026,163,163,163,163,163,163,163,163,163,163,163,1027, +1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, /* block 153 */ -1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,196,1104,1104,1104,1104, -1104,1104,1104,196,1104,1104,196,1105,1105,1105,1105,1105,1105,1105,1105,1105, -1105,1105,196,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105,1105, -1105,1105,196,1105,1105,1105,1105,1105,1105,1105,196,1105,1105,196,196,196, -1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,196,196,196,196,196,196,196,196,196,196,196,196, +1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, +1028,1028,1028,163,1028,1028,163,1029,1029,1029,1029,1029,1029,1029,1029,1029, +1029,1029,163,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029, +1029,1029,163,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 154 */ -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, /* block 155 */ -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196,196, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196,196,196, -1107,1107,1107,1107,1107,1107,1107,1107,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 156 */ -149,1108,1108,149,149,149,196,149,149,149,149,149,149,149,149,149, -149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, -149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, -149,196,149,149,149,149,149,149,149,149,149,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +147,1031,1031,147,147,147,163,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,163,147,147,147,147,147,147,147,147,147,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 157 */ -1109,1109,1109,1109,1109,1109,297,297,1109,297,1109,1109,1109,1109,1109,1109, -1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109, -1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109,1109, -1109,1109,1109,1109,1109,1109,297,1109,1109,297,297,297,1109,297,297,1109, -1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110, -1110,1110,1110,1110,1110,1110,297,1111,1112,1112,1112,1112,1112,1112,1112,1112, -1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113,1113, -1113,1113,1113,1113,1113,1113,1113,1114,1114,1115,1115,1115,1115,1115,1115,1115, +1032,1032,1032,1032,1032,1032,262,262,1032,262,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,262,1032,1032,262,262,262,1032,262,262,1032, +1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033, +1033,1033,1033,1033,1033,1033,262,1034,1035,1035,1035,1035,1035,1035,1035,1035, +1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036, +1036,1036,1036,1036,1036,1036,1036,1037,1037,1038,1038,1038,1038,1038,1038,1038, /* block 158 */ -1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, -1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,297, -297,297,297,297,297,297,297,1117,1117,1117,1117,1117,1117,1117,1117,1117, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118,1118, -1118,1118,1118,297,1118,1118,297,297,297,297,297,1119,1119,1119,1119,1119, +1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039, +1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,262, +262,262,262,262,262,262,262,1040,1040,1040,1040,1040,1040,1040,1040,1040, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041, +1041,1041,1041,262,1041,1041,262,262,262,262,262,1042,1042,1042,1042,1042, /* block 159 */ -1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120,1120, -1120,1120,1120,1120,1120,1120,1121,1121,1121,1121,1121,1121,297,297,297,1122, -1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123, -1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,297,297,297,297,297,1124, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043, +1043,1043,1043,1043,1043,1043,1044,1044,1044,1044,1044,1044,262,262,262,1045, +1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046, +1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,262,262,262,262,262,1047, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 160 */ -1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125, -1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125,1125, -1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126, -1126,1126,1126,1126,1126,1126,1126,1126,297,297,297,297,1127,1127,1126,1126, -1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, -297,297,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, -1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, -1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, +1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, +1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, +1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049, +1049,1049,1049,1049,1049,1049,1049,1049,262,262,262,262,1050,1050,1049,1049, +1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +262,262,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, /* block 161 */ -1128,1129,1129,1129,297,1129,1129,297,297,297,297,297,1129,1129,1129,1129, -1128,1128,1128,1128,297,1128,1128,1128,297,1128,1128,1128,1128,1128,1128,1128, -1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128,1128, -1128,1128,1128,1128,1128,1128,297,297,1130,1130,1130,297,297,297,297,1131, -1132,1132,1132,1132,1132,1132,1132,1132,1132,297,297,297,297,297,297,297, -1133,1133,1133,1133,1133,1133,1134,1134,1133,297,297,297,297,297,297,297, -1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, -1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1136,1136,1137, +1051,1052,1052,1052,262,1052,1052,262,262,262,262,262,1052,1052,1052,1052, +1051,1051,1051,1051,262,1051,1051,1051,262,1051,1051,1051,1051,1051,1051,1051, +1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, +1051,1051,1051,1051,1051,1051,262,262,1053,1053,1053,262,262,262,262,1054, +1055,1055,1055,1055,1055,1055,1055,1055,1055,262,262,262,262,262,262,262, +1056,1056,1056,1056,1056,1056,1057,1057,1056,262,262,262,262,262,262,262, +1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058, +1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1059,1059,1060, /* block 162 */ -1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138, -1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1138,1139,1139,1139, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -1140,1140,1140,1140,1140,1140,1140,1140,1141,1140,1140,1140,1140,1140,1140,1140, -1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140,1140, -1140,1140,1140,1140,1140,1142,1142,297,297,297,297,1143,1143,1143,1143,1143, -1144,1144,1145,1144,1144,1144,1146,297,297,297,297,297,297,297,297,297, +1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061, +1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1062,1062,1062, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1063,1063,1063,1063,1063,1063,1063,1063,1064,1063,1063,1063,1063,1063,1063,1063, +1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063, +1063,1063,1063,1063,1063,1065,1065,262,262,262,262,1066,1066,1066,1066,1066, +1067,1067,1068,1067,1067,1067,1069,262,262,262,262,262,262,262,262,262, /* block 163 */ -1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147, -1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147, -1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147,1147, -1147,1147,1147,1147,1147,1147,297,297,297,1148,1149,1149,1149,1149,1149,1149, -1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150,1150, -1150,1150,1150,1150,1150,1150,297,297,1151,1151,1151,1151,1151,1151,1151,1151, -1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152, -1152,1152,1152,297,297,297,297,297,1153,1153,1153,1153,1153,1153,1153,1153, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,262,262,262,1071,1072,1072,1072,1072,1072,1072, +1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, +1073,1073,1073,1073,1073,1073,262,262,1074,1074,1074,1074,1074,1074,1074,1074, +1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, +1075,1075,1075,262,262,262,262,262,1076,1076,1076,1076,1076,1076,1076,1076, /* block 164 */ -1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, -1154,1154,297,297,297,297,297,297,297,1155,1155,1155,1155,297,297,297, -297,297,297,297,297,297,297,297,297,1156,1156,1156,1156,1156,1156,1156, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, +1077,1077,262,262,262,262,262,262,262,1078,1078,1078,1078,262,262,262, +262,262,262,262,262,262,262,262,262,1079,1079,1079,1079,1079,1079,1079, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 165 */ -1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, -1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, -1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, -1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157,1157, -1157,1157,1157,1157,1157,1157,1157,1157,1157,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 166 */ -1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158, -1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158, -1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158,1158, -1158,1158,1158,297,297,297,297,297,297,297,297,297,297,297,297,297, -1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159, -1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159, -1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,1159, -1159,1159,1159,297,297,297,297,297,297,297,1160,1160,1160,1160,1160,1160, +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,262,262,262,262,262,262,262,262,262,262,262,262,262, +1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, +1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, +1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, +1082,1082,1082,262,262,262,262,262,262,262,1083,1083,1083,1083,1083,1083, /* block 167 */ -1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161, -1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,1161, -1161,1161,1162,1162,1163,1163,1163,1163,340,340,340,340,340,340,340,340, -1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,340,340,340,340,340,340, -1165,1165,1165,1165,1165,1165,1165,1165,1165,1165,1166,1166,1166,1166,1167,1166, -1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168,1168, -1168,1168,1168,1168,1168,1168,297,297,297,1169,1170,1171,1171,1171,1172,1173, -1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174,1174, +1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, +1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, +1084,1084,1085,1085,1086,1086,1086,1086,302,302,302,302,302,302,302,302, +1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,302,302,302,302,302,302, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 168 */ -1174,1174,1174,1174,1174,1174,297,297,297,297,297,297,297,297,1175,1175, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 169 */ -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176, -1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,1176,297, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088, +1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,262, /* block 170 */ -1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177, -1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,1177, -1177,1177,1177,1177,1177,1177,1177,1177,1177,1177,297,1178,1178,1179,297,297, -1177,1177,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -340,340,321,321,321,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,316,333,333,333, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,262,1090,1090,1091,262,262, +1089,1089,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,291,291,291, /* block 171 */ -1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180, -1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1180,1181,1181,1181, -1181,1181,1181,1181,1181,1181,1181,1180,297,297,297,297,297,297,297,297, -1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182,1182, -1182,1182,1182,1182,1182,1182,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, -1183,1184,1184,1184,1184,1185,1185,1185,1185,1185,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186,1186, +1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092, +1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1093,1093,1093, +1093,1093,1093,1093,1093,1093,1093,1092,262,262,262,262,262,262,262,262, +1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, +1094,1094,1094,1094,1094,1094,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, +1095,1096,1096,1096,1096,1097,1097,1097,1097,1097,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098, /* block 172 */ -1186,1186,1187,1187,1187,1187,1188,1188,1188,1188,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, -1189,1189,1189,1189,1189,1190,1190,1190,1190,1190,1190,1190,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191, -1191,1191,1191,1191,1191,1191,1191,297,297,297,297,297,297,297,297,297, +1098,1098,1099,1099,1099,1099,1100,1100,1100,1100,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, +1101,1101,1101,1101,1101,1102,1102,1102,1102,1102,1102,1102,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103, +1103,1103,1103,1103,1103,1103,1103,262,262,262,262,262,262,262,262,262, /* block 173 */ -1192,1193,1192,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194, -1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194, -1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194,1194, -1194,1194,1194,1194,1194,1194,1194,1194,1193,1193,1193,1193,1193,1193,1193,1193, -1193,1193,1193,1193,1193,1193,1195,1196,1196,1197,1197,1197,1197,1197,196,196, -196,196,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198,1198, -1198,1198,1198,1198,1198,1198,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, -1195,1194,1194,1193,1193,1194,196,196,196,196,196,196,196,196,196,1200, +1104,1105,1104,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1105,1105,1105,1105,1105,1105,1105,1105, +1105,1105,1105,1105,1105,1105,1107,1108,1108,1109,1109,1109,1109,1109,163,163, +163,163,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110, +1110,1110,1110,1110,1110,1110,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111, +1107,1106,1106,1105,1105,1106,163,163,163,163,163,163,163,163,163,1112, /* block 174 */ -1201,1201,1202,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203, -1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203, -1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203,1203, -1202,1202,1202,1201,1201,1201,1201,1202,1202,1204,1205,1206,1206,1207,1208,1208, -1208,1208,1201,196,196,196,196,196,196,196,196,196,196,1207,196,196, -1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209,1209, -1209,1209,1209,1209,1209,1209,1209,1209,1209,196,196,196,196,196,196,196, -1210,1210,1210,1210,1210,1210,1210,1210,1210,1210,196,196,196,196,196,196, +1113,1113,1114,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1114,1114,1114,1113,1113,1113,1113,1114,1114,1116,1117,1118,1118,1119,1120,1120, +1120,1120,1113,163,163,163,163,163,163,163,163,163,163,1119,163,163, +1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121, +1121,1121,1121,1121,1121,1121,1121,1121,1121,163,163,163,163,163,163,163, +1122,1122,1122,1122,1122,1122,1122,1122,1122,1122,163,163,163,163,163,163, /* block 175 */ -1211,1211,1211,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212, -1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,1212, -1212,1212,1212,1212,1212,1212,1212,1211,1211,1211,1211,1211,1213,1211,1211,1211, -1211,1211,1211,1214,1214,196,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215, -1216,1217,1217,1217,1212,1213,1213,1212,196,196,196,196,196,196,196,196, -1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218, -1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1218, -1218,1218,1218,1219,1220,1220,1218,196,196,196,196,196,196,196,196,196, +1123,1123,1123,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, +1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, +1124,1124,1124,1124,1124,1124,1124,1123,1123,1123,1123,1123,1125,1123,1123,1123, +1123,1123,1123,1126,1126,163,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, +1128,1129,1129,1129,1124,1125,1125,1124,163,163,163,163,163,163,163,163, +1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, +1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, +1130,1130,1130,1131,1132,1132,1130,163,163,163,163,163,163,163,163,163, /* block 176 */ -1221,1221,1222,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223, -1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223, -1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223,1223, -1223,1223,1223,1222,1222,1222,1221,1221,1221,1221,1221,1221,1221,1221,1221,1222, -1224,1223,1225,1225,1223,1226,1226,1227,1227,1228,1229,1229,1229,1226,1222,1221, -1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1223,1227,1223,1227,1226,1226, -196,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231, -1231,1231,1231,1231,1231,196,196,196,196,196,196,196,196,196,196,196, +1133,1133,1134,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1134,1134,1134,1133,1133,1133,1133,1133,1133,1133,1133,1133,1134, +1136,1135,1137,1137,1135,1138,1138,1139,1139,1140,1141,1141,1141,1138,1134,1133, +1142,1142,1142,1142,1142,1142,1142,1142,1142,1142,1135,1139,1135,1139,1138,1138, +163,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143, +1143,1143,1143,1143,1143,163,163,163,163,163,163,163,163,163,163,163, /* block 177 */ -1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232, -1232,1232,196,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232, -1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1233,1233,1233,1234, -1234,1234,1233,1233,1234,1235,1236,1237,1238,1238,1239,1238,1238,1240,1234,1232, -1232,1234,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, +1144,1144,163,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, +1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1145,1145,1145,1146, +1146,1146,1145,1145,1146,1147,1148,1146,1149,1149,1150,1149,1149,1151,1146,1144, +1144,1146,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 178 */ -1241,1241,1241,1241,1241,1241,1241,196,1241,196,1241,1241,1241,1241,196,1241, -1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,1241,196,1241, -1241,1241,1241,1241,1241,1241,1241,1241,1241,1242,196,196,196,196,196,196, -1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243, -1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243, -1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,1244, -1245,1245,1245,1244,1244,1244,1244,1244,1244,1246,1247,196,196,196,196,196, -1248,1248,1248,1248,1248,1248,1248,1248,1248,1248,196,196,196,196,196,196, +1152,1152,1152,1152,1152,1152,1152,163,1152,163,1152,1152,1152,1152,163,1152, +1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,163,1152, +1152,1152,1152,1152,1152,1152,1152,1152,1152,1153,163,163,163,163,163,163, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1155, +1156,1156,1156,1155,1155,1155,1155,1155,1155,1157,1158,163,163,163,163,163, +1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,163,163,163,163,163,163, /* block 179 */ -1249,1250,1251,1252,196,1253,1253,1253,1253,1253,1253,1253,1253,196,196,1253, -1253,196,196,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253,1253, -1253,1253,1253,1253,1253,1253,1253,1253,1253,196,1253,1253,1253,1253,1253,1253, -1253,196,1253,1253,196,1253,1253,1253,1253,1253,196,1254,1255,1253,1256,1251, -1249,1251,1251,1251,1251,196,196,1251,1251,196,196,1251,1251,1257,196,196, -1253,196,196,196,196,196,196,1256,196,196,196,196,196,1258,1253,1253, -1253,1253,1251,1251,196,196,1259,1259,1259,1259,1259,1259,1259,196,196,196, -1259,1259,1259,1259,1259,196,196,196,196,196,196,196,196,196,196,196, +1160,1161,1162,1163,163,1164,1164,1164,1164,1164,1164,1164,1164,163,163,1164, +1164,163,163,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164, +1164,1164,1164,1164,1164,1164,1164,1164,1164,163,1164,1164,1164,1164,1164,1164, +1164,163,1164,1164,163,1164,1164,1164,1164,1164,163,1165,1166,1164,1167,1162, +1160,1162,1162,1162,1162,163,163,1162,1162,163,163,1162,1162,1168,163,163, +1164,163,163,163,163,163,163,1167,163,163,163,163,163,1169,1164,1164, +1164,1164,1162,1162,163,163,1170,1170,1170,1170,1170,1170,1170,163,163,163, +1170,1170,1170,1170,1170,163,163,163,163,163,163,163,163,163,163,163, /* block 180 */ -1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,196,1260,196,196,1260,196, -1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, -1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, -1260,1260,1260,1260,1260,1260,196,1260,1261,1262,1262,1263,1263,1263,1263,1263, -1263,196,1261,196,196,1261,196,1261,1261,1261,1262,196,1262,1262,1264,1265, -1264,1266,1267,1268,1269,1269,196,1270,1270,196,196,196,196,196,196,196, -196,1271,1271,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1172,1172,1172,1173,1173,1173,1173,1173,1173,1173,1173, +1172,1172,1174,1173,1173,1172,1175,1171,1171,1171,1171,1176,1176,1177,1178,1178, +1179,1179,1179,1179,1179,1179,1179,1179,1179,1179,1177,1177,163,1178,1180,1171, +1171,1171,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 181 */ -1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272, -1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272, -1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272,1272, -1272,1272,1272,1272,1272,1273,1273,1273,1274,1274,1274,1274,1274,1274,1274,1274, -1273,1273,1275,1274,1274,1273,1276,1272,1272,1272,1272,1277,1277,1278,1279,1279, -1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1278,1278,196,1279,1281,1272, -1272,1272,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1182,1183,1183,1184,1184,1184,1184,1184,1184,1183,1184,1183,1183,1182,1183,1184, +1184,1183,1185,1186,1181,1181,1187,1181,163,163,163,163,163,163,163,163, +1188,1188,1188,1188,1188,1188,1188,1188,1188,1188,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 182 */ -1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, -1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, -1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, -1283,1284,1284,1285,1285,1285,1285,1285,1285,1284,1285,1284,1284,1283,1284,1285, -1285,1284,1286,1287,1282,1282,1288,1282,196,196,196,196,196,196,196,196, -1289,1289,1289,1289,1289,1289,1289,1289,1289,1289,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1190, +1191,1191,1192,1192,1192,1192,163,163,1191,1191,1191,1191,1192,1192,1191,1193, +1194,1195,1196,1196,1197,1197,1198,1198,1198,1196,1196,1196,1196,1196,1196,1196, +1196,1196,1196,1196,1196,1196,1196,1196,1189,1189,1189,1189,1192,1192,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 183 */ -1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290, -1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290, -1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1291, -1292,1292,1293,1293,1293,1293,196,196,1292,1292,1292,1292,1293,1293,1292,1294, -1295,1296,1297,1297,1298,1298,1299,1299,1299,1297,1297,1297,1297,1297,1297,1297, -1297,1297,1297,1297,1297,1297,1297,1297,1290,1290,1290,1290,1293,1293,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1200,1200,1200,1201,1201,1201,1201,1201,1201,1201,1201,1200,1200,1201,1200,1202, +1201,1203,1203,1204,1199,163,163,163,163,163,163,163,163,163,163,163, +1205,1205,1205,1205,1205,1205,1205,1205,1205,1205,163,163,163,163,163,163, +531,531,531,531,531,531,531,531,531,531,531,531,531,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 184 */ -1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, -1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, -1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, -1301,1301,1301,1302,1302,1302,1302,1302,1302,1302,1302,1301,1301,1302,1301,1303, -1302,1304,1304,1305,1300,196,196,196,196,196,196,196,196,196,196,196, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,196,196,196,196,196,196, -581,581,581,581,581,581,581,581,581,581,581,581,581,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1207,1208,1207,1208,1208, +1207,1207,1207,1207,1207,1207,1209,1210,1206,1211,163,163,163,163,163,163, +1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 185 */ -1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307, -1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307, -1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1307,1308,1309,1308,1309,1309, -1308,1308,1308,1308,1308,1308,1310,1311,1307,1312,196,196,196,196,196,196, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,196,196,196,196,196,196, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213, +1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,163,163,1214,1214,1214, +1215,1215,1214,1214,1214,1214,1216,1214,1214,1214,1214,1217,163,163,163,163, +1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1219,1219,1220,1220,1220,1221, +1213,1213,1213,1213,1213,1213,1213,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 186 */ -1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, -1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,196,196,1315,1316,1315, -1317,1317,1315,1315,1315,1315,1316,1315,1315,1315,1315,1318,196,196,196,196, -1319,1319,1319,1319,1319,1319,1319,1319,1319,1319,1320,1320,1321,1321,1321,1322, -1314,1314,1314,1314,1314,1314,1314,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1223,1223,1223,1224, +1224,1224,1224,1224,1224,1224,1224,1224,1223,1225,1226,1227,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 187 */ -1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, -1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, -1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1324,1324,1324,1325, -1325,1325,1325,1325,1325,1325,1325,1325,1324,1326,1327,1328,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, +1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, +1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, +1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, +1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1231,1231,1231,1231,1231,1231, +1231,1231,1231,163,163,163,163,163,163,163,163,163,163,163,163,1232, /* block 188 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329, -1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329, -1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330, -1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330,1330, -1331,1331,1331,1331,1331,1331,1331,1331,1331,1331,1332,1332,1332,1332,1332,1332, -1332,1332,1332,196,196,196,196,196,196,196,196,196,196,196,196,1333, +1233,1233,1233,1233,1233,1233,1233,163,163,1233,163,163,1233,1233,1233,1233, +1233,1233,1233,1233,163,1233,1233,163,1233,1233,1233,1233,1233,1233,1233,1233, +1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233, +1234,1235,1235,1235,1235,1235,163,1235,1235,163,163,1236,1236,1237,1238,1239, +1235,1239,1235,1240,1241,1242,1241,163,163,163,163,163,163,163,163,163, +1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 189 */ -1334,1334,1334,1334,1334,1334,1334,196,196,1334,196,196,1334,1334,1334,1334, -1334,1334,1334,1334,196,1334,1334,196,1334,1334,1334,1334,1334,1334,1334,1334, -1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,1334, -1335,1336,1336,1336,1336,1336,196,1336,1336,196,196,1337,1337,1338,1339,1340, -1336,1340,1336,1341,1342,1343,1342,196,196,196,196,196,196,196,196,196, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1244,1244,1244,1244,1244,1244,1244,1244,163,163,1244,1244,1244,1244,1244,1244, +1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, +1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, +1244,1245,1245,1245,1246,1246,1246,1246,163,163,1246,1246,1245,1245,1245,1245, +1247,1244,1248,1244,1245,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 190 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1345,1345,1345,1345,1345,1345,1345,1345,196,196,1345,1345,1345,1345,1345,1345, -1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345, -1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345,1345, -1345,1346,1346,1346,1347,1347,1347,1347,196,196,1347,1347,1346,1346,1346,1346, -1348,1345,1349,1345,1346,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1249,1250,1250,1250,1250,1250,1250,1251,1251,1250,1250,1249,1249,1249,1249,1249, +1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, +1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, +1249,1249,1249,1252,1253,1250,1250,1250,1250,1254,1255,1250,1250,1250,1250,1256, +1256,1256,1257,1257,1256,1256,1256,1253,163,163,163,163,163,163,163,163, +1258,1259,1259,1259,1259,1259,1259,1260,1260,1259,1259,1259,1258,1258,1258,1258, +1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, +1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, /* block 191 */ -1350,1351,1351,1351,1351,1351,1351,1352,1352,1351,1351,1350,1350,1350,1350,1350, -1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350, -1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350,1350, -1350,1350,1350,1353,1354,1351,1351,1351,1351,1355,1356,1351,1351,1351,1351,1357, -1357,1357,1358,1358,1357,1357,1357,1354,196,196,196,196,196,196,196,196, -1359,1360,1360,1360,1360,1360,1360,1361,1361,1360,1360,1360,1359,1359,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, +1258,1258,1258,1258,1261,1261,1261,1261,1261,1261,1259,1259,1259,1259,1259,1259, +1259,1259,1259,1259,1259,1259,1259,1260,1262,1263,1264,1265,1265,1258,1264,1264, +1264,1266,1266,163,163,163,163,163,163,163,163,163,163,163,163,163, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,163,163,163,163,163,163,163, /* block 192 */ -1359,1359,1359,1359,1362,1362,1362,1362,1362,1362,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1361,1363,1364,1365,1366,1366,1359,1365,1365, -1365,1367,1367,196,196,196,196,196,196,196,196,196,196,196,196,196, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, -1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, -1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, -1368,1368,1368,1368,1368,1368,1368,1368,1368,196,196,196,196,196,196,196, +343,343,343,343,343,343,343,343,343,343,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 193 */ -385,385,385,385,385,385,385,385,385,385,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1268,1268,1268,1268,1268,1268,1268,1268,1268,163,1268,1268,1268,1268,1268,1268, +1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268, +1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1269, +1270,1270,1270,1270,1270,1270,1270,163,1270,1270,1270,1270,1270,1270,1269,1271, +1268,1272,1272,1273,1274,1274,163,163,163,163,163,163,163,163,163,163, +1275,1275,1275,1275,1275,1275,1275,1275,1275,1275,1276,1276,1276,1276,1276,1276, +1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,163,163,163, +1277,1278,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, /* block 194 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, -1369,1370,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1371,1371,1371,1371,1371,1371,1371,1371,1371,1371,196,196,196,196,196,196, +1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, +163,163,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280, +1280,1280,1280,1280,1280,1280,1280,1280,163,1281,1280,1280,1280,1280,1280,1280, +1280,1281,1280,1280,1281,1280,1280,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 195 */ -1372,1372,1372,1372,1372,1372,1372,1372,1372,196,1372,1372,1372,1372,1372,1372, -1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372, -1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1373, -1374,1374,1374,1374,1374,1374,1374,196,1374,1374,1374,1374,1374,1374,1373,1375, -1372,1376,1376,1377,1378,1378,196,196,196,196,196,196,196,196,196,196, -1379,1379,1379,1379,1379,1379,1379,1379,1379,1379,1380,1380,1380,1380,1380,1380, -1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,196,196,196, -1381,1382,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383, +1282,1282,1282,1282,1282,1282,1282,163,1282,1282,163,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1283,1283,1283,1283,1283,1283,163,163,163,1283,163,1283,1283,163,1283, +1283,1283,1284,1283,1285,1285,1286,1283,163,163,163,163,163,163,163,163, +1287,1287,1287,1287,1287,1287,1287,1287,1287,1287,163,163,163,163,163,163, +1288,1288,1288,1288,1288,1288,163,1288,1288,163,1288,1288,1288,1288,1288,1288, +1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288, /* block 196 */ -1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383,1383, -196,196,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, -1384,1384,1384,1384,1384,1384,1384,1384,196,1385,1384,1384,1384,1384,1384,1384, -1384,1385,1384,1384,1385,1384,1384,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1289,1289,1289,1289,1289,163, +1290,1290,163,1289,1289,1290,1289,1291,1288,163,163,163,163,163,163,163, +1292,1292,1292,1292,1292,1292,1292,1292,1292,1292,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 197 */ -1386,1386,1386,1386,1386,1386,1386,196,1386,1386,196,1386,1386,1386,1386,1386, -1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386, -1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,1386, -1386,1387,1387,1387,1387,1387,1387,196,196,196,1387,196,1387,1387,196,1387, -1387,1387,1388,1387,1389,1389,1390,1387,196,196,196,196,196,196,196,196, -1391,1391,1391,1391,1391,1391,1391,1391,1391,1391,196,196,196,196,196,196, -1392,1392,1392,1392,1392,1392,196,1392,1392,196,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293, +1293,1293,1293,1294,1294,1295,1295,1296,1296,163,163,163,163,163,163,163, /* block 198 */ -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1393,1393,1393,1393,1393,196, -1394,1394,196,1393,1393,1394,1393,1395,1392,196,196,196,196,196,196,196, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1297,1297,1298,1299,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,163,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1299,1299,1297,1297,1297,1297,1297,163,163,163,1299,1299, +1297,1301,1302,1303,1303,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, +1305,1305,1305,1305,1305,1305,1305,1305,1305,1305,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 199 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397,1397, -1397,1397,1397,1398,1398,1399,1399,1400,1400,196,196,196,196,196,196,196, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +843,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, +388,388,1306,388,1306,390,390,390,390,390,390,390,390,391,391,391, +391,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390, +390,390,163,163,163,163,163,163,163,163,163,163,163,163,163,1307, /* block 200 */ -1401,1401,1402,1403,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404, -1404,196,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404, -1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404,1404, -1404,1404,1404,1404,1403,1403,1401,1401,1401,1401,1401,196,196,196,1403,1403, -1401,1405,1406,1407,1407,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1410,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, /* block 201 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -914,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411,1411, -435,435,1411,435,1411,437,437,437,437,437,437,437,437,438,438,438, -438,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, -437,437,196,196,196,196,196,196,196,196,196,196,196,196,196,1412, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 202 */ -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,163, +1310,1310,1310,1310,1310,163,163,163,163,163,163,163,163,163,163,163, /* block 203 */ -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 204 */ -1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, -1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, -1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, -1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, -1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, -1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414, -1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,1414,196, -1415,1415,1415,1415,1415,196,196,196,196,196,196,196,196,196,196,196, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1312,1312,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 205 */ -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, -1413,1413,1413,1413,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, /* block 206 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, -1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, -1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, -1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, -1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, -1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416,1416, -1416,1417,1417,196,196,196,196,196,196,196,196,196,196,196,196,196, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, +1315,1313,1313,1313,1313,1313,1313,1316,1316,1316,1316,1316,1316,1316,1316,1316, +1316,1316,1316,1316,1316,1316,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 207 */ -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, /* block 208 */ -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419,1419, -1420,1418,1418,1418,1418,1418,1418,1421,1421,1421,1421,1421,1421,1421,1421,1421, -1421,1421,1421,1421,1421,1421,196,196,196,196,196,196,196,196,196,196, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 209 */ -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418, -1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,1418,196,196,196,196,196, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, /* block 210 */ -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,163,163,163,163,163,163,163, +1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318, +1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,163, +1319,1319,1319,1319,1319,1319,1319,1319,1319,1319,163,163,163,163,1320,1320, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, /* block 211 */ -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, -1422,1422,1422,1422,1422,1422,1422,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,163, +1322,1322,1322,1322,1322,1322,1322,1322,1322,1322,163,163,163,163,163,163, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,163,163, +1324,1324,1324,1324,1324,1325,163,163,163,163,163,163,163,163,163,163, /* block 212 */ -1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423, -1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1423,1424,1424, -1424,1424,1424,1424,1424,1424,1424,1424,1424,1424,1425,1425,1425,1424,1424,1426, -1427,1427,1427,1427,1427,1427,1427,1427,1427,1427,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1327,1327,1327,1327,1327,1327,1327,1328,1328,1329,1330,1330,1331,1331,1331,1331, +1332,1332,1333,1333,1328,1331,163,163,163,163,163,163,163,163,163,163, +1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,163,1335,1335,1335,1335,1335, +1335,1335,163,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,163,163,163,163,163,1326,1326,1326, /* block 213 */ -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 214 */ -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, -930,930,930,930,930,930,930,930,930,196,196,196,196,196,196,196, -1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428, -1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,1428,196, -1429,1429,1429,1429,1429,1429,1429,1429,1429,1429,196,196,196,196,1430,1430, -1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, +1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, +1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, +1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, /* block 215 */ -1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, -1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, -1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431, -1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,1431,196, -1432,1432,1432,1432,1432,1432,1432,1432,1432,1432,196,196,196,196,196,196, -1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433, -1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,1433,196,196, -1434,1434,1434,1434,1434,1435,196,196,196,196,196,196,196,196,196,196, +1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338, +1338,1338,1338,1338,1338,1338,1338,1339,1340,1341,1341,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 216 */ -1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, -1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, -1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, -1437,1437,1437,1437,1437,1437,1437,1438,1438,1439,1440,1440,1441,1441,1441,1441, -1442,1442,1443,1443,1438,1441,196,196,196,196,196,196,196,196,196,196, -1444,1444,1444,1444,1444,1444,1444,1444,1444,1444,196,1445,1445,1445,1445,1445, -1445,1445,196,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, -1436,1436,1436,1436,1436,1436,1436,1436,196,196,196,196,196,1436,1436,1436, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,163,163,163,163,1343, +1342,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, /* block 217 */ -1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436,1436, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1344,1344,1344,1344,1344,1344,1344,1344,163,163,163,163,163,163,163,1345, +1345,1345,1345,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1347,1348,1349,800,1350,163,163,163,163,163,163,163,163,163,163,163, +1351,1351,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 218 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1446,1446,1446,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447, -1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447,1447, -1447,1447,1447,1448,1447,1447,1447,1448,1448,1448,1448,1449,1449,1450,1451,1451, -1452,1452,1452,1452,1452,1452,1452,1452,1452,1452,196,196,196,196,196,196, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, /* block 219 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453, -1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453,1453, -1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454, -1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454,1454, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163,163, /* block 220 */ -1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455,1455, -1455,1455,1455,1455,1455,1455,1455,1456,1457,1458,1458,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, /* block 221 */ -1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, -1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, -1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, -1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459, -1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,1459,196,196,196,196,1460, -1459,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461, -1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461, -1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461,1461, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 222 */ -1461,1461,1461,1461,1461,1461,1461,1461,196,196,196,196,196,196,196,1462, -1462,1462,1462,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463,1463, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1464,1465,1466,867,1467,196,196,196,196,196,196,196,196,196,196,196, -1468,1468,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1352,1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 223 */ -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1354,1354,1354,1354,163,1354,1354,1354,1354,1354,1354,1354,163,1354,1354,163, /* block 224 */ -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469,1469, -1469,1469,1469,1469,1469,1469,1469,1469,196,196,196,196,196,196,196,196, +825,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 225 */ -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 226 */ -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470, -1470,1470,1470,1470,1470,1470,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,1470, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +825,825,825,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,820,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +820,820,820,163,163,825,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,825,825,825,825,163,163,163,163,163,163,163,163, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, /* block 227 */ -1469,1469,1469,1469,1469,1469,1469,1469,1469,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, /* block 228 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1471,1471,1471,1471,196,1471,1471,1471,1471,1471,1471,1471,196,1471,1471,196, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,163,163,163,163, /* block 229 */ -896,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163, /* block 230 */ -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,1357,1358,1359,1360, +1361,1361,1361,1361,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 231 */ -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -896,896,896,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,891,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -891,891,891,196,196,896,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,896,896,896,896,196,196,196,196,196,196,196,196, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, /* block 232 */ -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 233 */ -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472, -1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,1472,196,196,196,196, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, /* block 234 */ -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196,196,196, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,163,163,163,163,163,163,163,163,163,163, /* block 235 */ -1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,196,196,196,196,196, -1473,1473,1473,1473,1473,1473,1473,1473,1473,1473,196,196,1474,1475,1476,1477, -1478,1478,1478,1478,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,163,163,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,1362,1363,154,154,154,461,461,461,1364,1365,1365, +1365,1365,1365, 51, 51, 51, 51, 51, 51, 51, 51,154,154,154,154,154, /* block 236 */ -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +154,154,154,461,461,154,154,154,154,154,154,154,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,154,154,154,154,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,724,724,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 237 */ -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -1479,1479,1479,1479,1479,1479,1479,1479,1479,1479,196,196,196,196,196,196, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1366,1366,1366,1001,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 238 */ -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, +836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, +836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, +836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, /* block 239 */ -176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, -176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, -176,176,176,176,176,176,176,176,176,176,176,176,176,176,196,196, -176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, -176,176,176,176,176,176,176,196,196,196,196,196,196,196,196,196, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,163,163,163,163,163,163,163,163,163, +833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, +833,833,836,836,836,836,836,836,836,163,163,163,163,163,163,163, /* block 240 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, +726,726,726,726,726,163,737,737,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, /* block 241 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,163,725,725, +163,163,725,163,163,725,725,163,163,725,725,725,725,163,725,725, +725,725,725,725,725,725,726,726,726,726,163,726,163,726,737,737, +726,726,726,726,163,726,726,726,726,726,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, /* block 242 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,196,196,196,196,196,196,196,196,196,196, +726,726,726,726,725,725,163,725,725,725,725,163,163,725,725,725, +725,725,725,725,725,163,725,725,725,725,725,725,725,163,726,726, +726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,725,725,163,725,725,725,725,163, +725,725,725,725,725,163,725,163,163,163,725,725,725,725,725,725, +725,163,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, /* block 243 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,196,196,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,1480,1480,176,176,176,510,510,510,1481,1481,1481, -1481,1481,1481, 51, 51, 51, 51, 51, 51, 51, 51,176,176,176,176,176, +725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, +726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, /* block 244 */ -176,176,176,510,510,176,176,176,176,176,176,176,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,176,176,176,176,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,781,781,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, /* block 245 */ -1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, -1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, -1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, -1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, -1077,1077,1482,1482,1482,1077,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,163,163,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,1367,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,716,726,726,726,726, +726,726,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,1367,726,726,726,726, /* block 246 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, -907,907,907,907,196,196,196,196,196,196,196,196,196,196,196,196, -907,907,907,907,907,907,907,907,907,907,907,907,907,907,907,907, -907,907,907,907,196,196,196,196,196,196,196,196,196,196,196,196, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,716,726,726,726,726,726,726,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,1367,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,716, +726,726,726,726,726,726,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,1367, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, /* block 247 */ -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,196,196,196,196,196,196,196,196,196, -904,904,904,904,904,904,904,904,904,904,904,904,904,904,904,904, -904,904,907,907,907,907,907,907,907,196,196,196,196,196,196,196, +726,726,726,726,726,726,726,726,726,716,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,1367,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,716,726,726,726,726,726,726,725,726,163,163,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, /* block 248 */ -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, -783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,783,783, -783,783,783,783,783,196,795,795,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, /* block 249 */ -782,782,783,783,783,783,783,783,783,783,795,795,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,782,196,782,782, -196,196,782,196,196,782,782,196,196,782,782,782,782,196,782,782, -782,782,782,782,782,782,783,783,783,783,196,783,196,783,795,795, -783,783,783,783,196,783,783,783,783,783,783,783,783,783,783,783, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, -783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1369,1369,1369,1369,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1369,1369,1369, +1369,1369,1369,1369,1369,1370,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, /* block 250 */ -783,783,783,783,782,782,196,782,782,782,782,196,196,782,782,782, -782,782,782,782,782,196,782,782,782,782,782,782,782,196,783,783, -783,783,783,783,783,783,795,795,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,782,782,196,782,782,782,782,196, -782,782,782,782,782,196,782,196,196,196,782,782,782,782,782,782, -782,196,783,783,783,783,783,783,783,783,795,795,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +1369,1369,1369,1369,1370,1369,1369,1371,1372,1371,1371,1373,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,1370,1370,1370,1370,1370, +163,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 251 */ -782,782,782,782,782,782,783,783,783,783,783,783,783,783,795,795, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, -783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,783,783, -783,783,783,783,783,783,795,795,783,783,783,783,783,783,783,783, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 92, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,163, +163,163,163,163,163, 70, 70, 70, 70, 70, 70,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 252 */ -783,783,783,783,783,783,783,783,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,783,783,783,783,783,783,783,783,795,795,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,783,783,783,783,783,783,783,783,795,795, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +1374,1374,1374,1374,1374,1374,1374,163,1374,1374,1374,1374,1374,1374,1374,1374, +1374,1374,1374,1374,1374,1374,1374,1374,1374,163,163,1374,1374,1374,1374,1374, +1374,1374,163,1374,1374,163,1374,1374,1374,1374,1374,163,163,163,163,163, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,1375,1375,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,858,858,858,858,858,1375,858,858,858,858,858,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 253 */ -782,782,782,782,782,782,782,782,782,782,783,783,783,783,783,783, -783,783,795,795,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,196,196,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,1483,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,1483,783,783,783,783, -783,783,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,1483,783,783,783,783, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,788, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 254 */ -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,1483,783,783,783,783,783,783,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,1483,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,1483, -783,783,783,783,783,783,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,1483, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,163,163,163, +1377,1377,1377,1377,1377,1377,1377,1378,1378,1378,1378,1378,1379,1379,163,163, +1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,163,163,163,163,1376,1381, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 255 */ -783,783,783,783,783,783,783,783,783,1483,783,783,783,783,783,783, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,1483,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,1483,783,783,783,783,783,783,782,783,196,196,1484,1484, -1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484, -1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484, -1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484,1484, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, +1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1383,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1385,1385,1385,1385, +1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,163,163,163,163,163,1387, /* block 256 */ -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, -1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388, +1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1389,1390,1390,1390,1390, +1391,1391,1391,1391,1391,1391,1391,1391,1391,1391,163,163,163,163,163,163, /* block 257 */ -1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, -1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, -1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, -1486,1486,1486,1486,1486,1486,1486,1485,1485,1485,1485,1486,1486,1486,1486,1486, -1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, -1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, -1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1485,1485,1485, -1485,1485,1485,1485,1485,1486,1485,1485,1485,1485,1485,1485,1485,1485,1485,1485, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,163,484,484,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,163, /* block 258 */ -1485,1485,1485,1485,1486,1485,1485,1487,1488,1487,1487,1489,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,1486,1486,1486,1486,1486, -196,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486,1486, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, /* block 259 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 93, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,694, 70, 70, 70, 70,196, -196,196,196,196,196, 70, 70, 70, 70, 70, 70,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,262,262,1393,1393,1393,1393,1393,1393,1393,1393,1393, +1394,1394,1394,1394,1394,1394,1394,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 260 */ -1490,1490,1490,1490,1490,1490,1490,196,1490,1490,1490,1490,1490,1490,1490,1490, -1490,1490,1490,1490,1490,1490,1490,1490,1490,196,196,1490,1490,1490,1490,1490, -1490,1490,196,1490,1490,196,1490,1490,1490,1490,1490,196,196,196,196,196, -929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, -929,929,929,929,929,929,929,929,929,929,929,929,1491,1491,929,929, -929,929,929,929,929,929,929,929,929,929,929,929,929,929,929,929, -929,929,929,929,929,929,929,929,1491,929,929,929,929,929,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1395,1395,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, +1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, +1396,1396,1396,1396,1397,1397,1397,1398,1399,1399,1399,1400,262,262,262,262, +1401,1401,1401,1401,1401,1401,1401,1401,1401,1401,262,262,262,262,1402,1402, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 261 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,849, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, /* block 262 */ -1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492, -1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492, -1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,1492,196,196,196, -1493,1493,1493,1493,1493,1493,1493,1494,1494,1494,1494,1494,1495,1495,196,196, -1496,1496,1496,1496,1496,1496,1496,1496,1496,1496,196,196,196,196,1492,1497, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403,1403,1403, +1405,1403,1403,1403,1403,302,302,302,302,302,302,302,302,302,302,302, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 263 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498, -1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1498,1499,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500, -1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500, -1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1501,1501,1501,1501, -1502,1502,1502,1502,1502,1502,1502,1502,1502,1502,196,196,196,196,196,1503, +302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 264 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504, -1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1504,1505,1506,1506,1506,1506, -1507,1507,1507,1507,1507,1507,1507,1507,1507,1507,196,196,196,196,196,196, +1406,1406,1406,1406,302,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, +302,1406,1406,302,1406,302,302,1406,302,1406,1406,1406,1406,1406,1406,1406, +1406,1406,1406,302,1406,1406,1406,1406,302,1406,302,1406,302,302,302,302, +302,302,1406,302,302,302,302,1406,302,1406,302,1406,302,1406,1406,1406, +302,1406,1406,302,1406,302,302,1406,302,1406,302,1406,302,1406,302,1406, +302,1406,1406,302,1406,302,302,1406,1406,1406,1406,302,1406,1406,1406,1406, +1406,1406,1406,302,1406,1406,1406,1406,302,1406,1406,1406,1406,302,1406,302, /* block 265 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508, -1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1508,1509,1510, -1508,1511,1511,1511,1511,1511,1511,1511,1511,1511,1511,196,196,196,196,1512, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, +302,1406,1406,1406,302,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +274,274,302,302,302,302,302,302,302,302,302,302,302,302,302,302, /* block 266 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -533,533,533,533,533,533,533,196,533,533,533,533,196,533,533,196, -533,533,533,533,533,533,533,533,533,533,533,533,533,533,533,196, +1407,1407,1407,1407,1408,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, /* block 267 */ -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1408, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 268 */ -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513,1513, -1513,1513,1513,1513,1513,297,297,1514,1514,1514,1514,1514,1514,1514,1514,1514, -1515,1515,1515,1515,1515,1515,1515,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 58, 58,1407,1407,1407, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1407, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,461,461, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,724,724,1407,1407,1407,1407, +1411,1411,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1411,1411, /* block 269 */ -1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516, -1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516,1516, -1516,1516,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517, -1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517,1517, -1517,1517,1517,1517,1518,1518,1518,1519,1520,1520,1520,1521,297,297,297,297, -1522,1522,1522,1522,1522,1522,1522,1522,1522,1522,297,297,297,297,1523,1523, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,1412,461, +461,1412,1412,1412,1412,1412,1412,1412,1412,1412,1412,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,1407,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, /* block 270 */ -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1414,1412,1415,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +461,461,461,461,461,461,461,461,461,461,1412,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1412, +461,461,1412,1412,1412,1412,1412,1415,1412,1412,1412,461,1409,1409,1409,1409, +461,461,461,461,461,461,461,461,461,1409,1409,1409,1409,1409,1409,1409, +1416,1416,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 271 */ -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -340,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 272 */ -1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, -1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, -1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1525,1524,1524,1524, -1526,1524,1524,1524,1524,340,340,340,340,340,340,340,340,340,340,340, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,728,1407,1407,728,728,728,728,728,728,728,728,728,1408,1408,1408, +1408,1408,1408,1408,1408,1408,728,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1408,1408, /* block 273 */ -340,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, -1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524, -1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1525,1524, -1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,1524,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, -297,297,297,297,297,297,297,297,297,297,297,297,297,297,297,297, +1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1407,1407,728,728,1407,728,728,728,1407,1407,728,728, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1417,1417,1417,1408,1408,1417,1408,1408,1417,1418,1418,728,728,1408, +1408,1408,1408,1408,728,728,728,728,728,728,728,728,728,728,728,728, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1407,1407,728,1408,728,1407,728,1408,1408,1408,1419,1419,1419,1419,1419, /* block 274 */ -1527,1527,1527,1527,340,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527, -1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527, -340,1527,1527,340,1527,340,340,1527,340,1527,1527,1527,1527,1527,1527,1527, -1527,1527,1527,340,1527,1527,1527,1527,340,1527,340,1527,340,340,340,340, -340,340,1527,340,340,340,340,1527,340,1527,340,1527,340,1527,1527,1527, -340,1527,1527,340,1527,340,340,1527,340,1527,340,1527,340,1527,340,1527, -340,1527,1527,340,1527,340,340,1527,1527,1527,1527,340,1527,1527,1527,1527, -1527,1527,1527,340,1527,1527,1527,1527,340,1527,1527,1527,1527,340,1527,340, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728, +1408,728,1417,1417,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, +1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408,1408,1417,1408,1408,1408, /* block 275 */ -1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,1527,1527,1527,1527,1527, -1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,340,340,340, -340,1527,1527,1527,340,1527,1527,1527,1527,1527,340,1527,1527,1527,1527,1527, -1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,1527,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -309,309,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +1408,1417,1417,1417,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1417, +1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1407,1408, /* block 276 */ -1528,1528,1528,1528,1529,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530,1530,1530, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,724,724, +724,724,724,724,724,724,1407,1407,1407,728,728,1408,1408,1408,1408,1407, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,1407,1407,728, +728,1407,1407,728,1418,1418,728,728,728,728,1417,1407,1407,1407,1407,1407, /* block 277 */ -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530, -1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1529, -1530,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +1407,1407,1407,1407,1407,1407,1407,728,1407,1407,728,728,728,728,1407,1407, +1418,1407,1407,1407,1407,1417,1417,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1408,728,1407,1407,728,1407,1407,1407,1407,1407,1407,1407, +1407,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,728,1407,1407,1407, +1407,1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,728,728,728,1407, +1407,728,1407,728,1407,1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728, +1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728,1408,1408,1408,1408,1408, /* block 278 */ -814,814,814,814,814,814,814,814,814,814,814, 58, 58,1528,1528,1528, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,1528, -1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531, -1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,510,510,510,510,510,510, -1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531, -1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,781,781,1528,1528,1528,1528, -1532,1532,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,1532,1532, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1417,1417,1417,1417,1417, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 279 */ -1531,1531,1531,1531,1531,1531,1531,1531,1531,1531,510,510,510,510,1533,510, -510,1533,1533,1533,1533,1533,1533,1533,1533,1533,1533,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,1528,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534, -1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534,1534, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1417,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,728,1417,728,728,728, +1408,1408,1408,1407,1407,1408,1408,1408,1409,1409,1409,1409,1408,1408,1408,1408, +728,728,728,728,728,728,1407,1407,1407,728,1407,1408,1408,1409,1409,1409, +728,1407,1407,728,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, /* block 280 */ -1535,1533,1536,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -510,510,510,510,510,510,510,510,510,510,1533,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,1533, -510,510,1533,1533,1533,1533,1533,1536,1533,1533,1533,510,1530,1530,1530,1530, -510,510,510,510,510,510,510,510,510,1530,1530,1530,1530,1530,1530,1530, -1537,1537,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1528,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,1407,1407,1407,1409,1409,1409,1409,1407,1407,1407,1407,1407, /* block 281 */ -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, +1408,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 282 */ -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,785,1528,1528,785,785,785,785,785,785,785,785,785,1529,1529,1529, -1529,1529,1529,1529,1529,1529,785,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785,1529,1529, +724,724,724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 283 */ -1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1528,1528,785,785,1528,785,785,785,1528,1528,785,785, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1538,1538,1538,1529,1529,1538,1529,1529,1538,1539,1539,785,785,1529, -1529,1529,1529,1529,785,785,785,785,785,785,785,785,785,785,785,785, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1528,1528,785,1529,785,1528,785,1529,1529,1529,1540,1540,1540,1540,1540, +724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,1409,1409, +1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 284 */ -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785, -1529,785,1538,1538,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538, -1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538, -1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,1529,1529,1538,1529,1529,1529, +724,724,724,724,724,724,724,724,724,724,724,724,1417,1408,1408,1417, +1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417, +1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,724,1417,1417,1417,1408, +1408,1408,1408,1408,1408,1408,724,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408, /* block 285 */ -1529,1538,1538,1538,1529,1538,1538,1538,1529,1529,1529,1529,1529,1529,1529,1538, -1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,785,1528,1529, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1420,1420,1420,1420,1408,1417,1417,1408,1417,1417,1408,1417,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417, +1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, /* block 286 */ -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,781,781, -781,781,781,781,781,781,1528,1528,1528,785,785,1529,1529,1529,1529,1528, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1528,1528,1528,1528,1528,1528,1528,785, -785,1528,1528,785,1539,1539,785,785,785,785,1538,1528,1528,1528,1528,1528, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, /* block 287 */ -1528,1528,1528,1528,1528,1528,1528,785,1528,1528,785,785,785,785,1528,1528, -1539,1528,1528,1528,1528,1538,1538,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1529,785,1528,1528,785,1528,1528,1528,1528,1528,1528,1528, -1528,785,785,1528,1528,1528,1528,1528,1528,1528,1528,1528,785,1528,1528,1528, -1528,1528,785,785,785,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,785,785,785,1528,1528,1528,1528,1528,1528,1528,1528,785,785,785,1528, -1528,785,1528,785,1528,1528,1528,1528,785,1528,1528,1528,1528,1528,1528,785, -1528,1528,1528,785,1528,1528,1528,1528,1528,1528,785,1529,1529,1529,1529,1529, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1408, +1408,1408,1408,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409,1409,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409, /* block 288 */ -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1538,1538,1538,1529,1529,1529,1538,1538,1538,1538,1538, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 289 */ -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1538,1538,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1538,1529,1529,1529,1529,1529,1528,1528,1528,1528,1528,785,1538,785,785,785, -1529,1529,1529,1528,1528,1529,1529,1529,1530,1530,1530,1530,1529,1529,1529,1529, -785,785,785,785,785,785,1528,1528,1528,785,1528,1529,1529,1530,1530,1530, -785,1528,1528,785,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,163,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1421,1421,1421,1421,1421,1421,1421,1421,1421,1421,163,163,163,163,163,163, /* block 290 */ -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,1528,1528,1528,1530,1530,1530,1530,1528,1528,1528,1528,1528, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,957,957, /* block 291 */ -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,1528,1528,1528,1528,1528,1530,1530,1530,1530,1530,1530, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530, -1529,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 292 */ -781,781,781,781,781,781,781,781,781,781,781,781,1530,1530,1530,1530, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530,1530,1530, -781,781,781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 293 */ -781,781,781,781,781,781,781,781,1530,1530,1530,1530,1530,1530,1530,1530, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,1530,1530, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530,1530,1530, -1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 294 */ -781,781,781,781,781,781,781,781,781,781,781,781,1538,1529,1529,1538, -1529,1529,1529,1529,1529,1529,1529,1529,1538,1538,1538,1538,1538,1538,1538,1538, -1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,781,1538,1538,1538,1529, -1529,1529,1529,1529,1529,1529,781,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1538,1529,1529,1529,1529,1529,1529,1529,1529, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 295 */ -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1541,1541,1541,1541,1529,1538,1538,1529,1538,1538,1529,1538,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1538,1538,1538, -1529,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1538,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 296 */ -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528, -1528,1528,1528,1528,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1528,1530,1530, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 297 */ -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530,1530,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529, -1529,1529,1529,1538,1538,1538,1529,1530,1530,1530,1530,1530,1530,1530,1529,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1529, -1529,1529,1529,1529,1529,1529,1529,1529,1529,1529,1530,1530,1530,1530,1530,1530, -1538,1538,1538,1538,1538,1538,1538,1538,1538,1530,1530,1530,1530,1530,1530,1530, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,957,957, /* block 298 */ -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,196,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -1479,1479,1479,1479,1479,1479,1479,1479,1479,1479,196,196,196,196,196,196, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 299 */ -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530, -1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1530,1032,1032, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 300 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +708,713,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, /* block 301 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,196,196,196,196,196,196, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, /* block 302 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,196,196, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, /* block 303 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, /* block 304 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, - -/* block 305 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, - -/* block 306 */ -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, - -/* block 307 */ -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,1032,1032, - -/* block 308 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,196,196,196,196,196, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, - -/* block 309 */ -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -910,910,910,910,910,910,910,910,910,910,910,910,910,910,910,910, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, -196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, - -/* block 310 */ -765,770,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, -1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, -1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, -1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, -1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, -1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542,1542, - -/* block 311 */ -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, - -/* block 312 */ -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, - -/* block 313 */ -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035,1035, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, - -/* block 314 */ -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1032,1032, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,957,957, }; #if UCD_BLOCK_SIZE != 128 diff --git a/ext/pcre/pcre2lib/pcre2_ucp.h b/ext/pcre/pcre2lib/pcre2_ucp.h index 513c54e29e6b..9ccc82975080 100644 --- a/ext/pcre/pcre2lib/pcre2_ucp.h +++ b/ext/pcre/pcre2lib/pcre2_ucp.h @@ -132,18 +132,13 @@ enum { ucp_Hex_Digit, ucp_IDS_Binary_Operator, ucp_IDS_Trinary_Operator, - ucp_IDS_Unary_Operator, - ucp_ID_Compat_Math_Continue, - ucp_ID_Compat_Math_Start, ucp_ID_Continue, ucp_ID_Start, ucp_Ideographic, - ucp_InCB, ucp_Join_Control, ucp_Logical_Order_Exception, ucp_Lowercase, ucp_Math, - ucp_Modifier_Combining_Mark, ucp_Noncharacter_Code_Point, ucp_Pattern_Syntax, ucp_Pattern_White_Space, @@ -224,8 +219,6 @@ enum { ucp_Latin, ucp_Greek, ucp_Cyrillic, - ucp_Armenian, - ucp_Hebrew, ucp_Arabic, ucp_Syriac, ucp_Thaana, @@ -239,21 +232,15 @@ enum { ucp_Kannada, ucp_Malayalam, ucp_Sinhala, - ucp_Thai, - ucp_Tibetan, ucp_Myanmar, ucp_Georgian, ucp_Hangul, - ucp_Ethiopic, - ucp_Cherokee, - ucp_Runic, ucp_Mongolian, ucp_Hiragana, ucp_Katakana, ucp_Bopomofo, ucp_Han, ucp_Yi, - ucp_Gothic, ucp_Tagalog, ucp_Hanunoo, ucp_Buhid, @@ -261,33 +248,21 @@ enum { ucp_Limbu, ucp_Tai_Le, ucp_Linear_B, - ucp_Shavian, ucp_Cypriot, ucp_Buginese, ucp_Coptic, ucp_Glagolitic, - ucp_Tifinagh, ucp_Syloti_Nagri, ucp_Phags_Pa, ucp_Nko, ucp_Kayah_Li, - ucp_Lycian, - ucp_Carian, - ucp_Lydian, - ucp_Avestan, - ucp_Samaritan, - ucp_Lisu, ucp_Javanese, - ucp_Old_Turkic, ucp_Kaithi, ucp_Mandaic, ucp_Chakma, - ucp_Meroitic_Hieroglyphs, ucp_Sharada, ucp_Takri, - ucp_Caucasian_Albanian, ucp_Duployan, - ucp_Elbasan, ucp_Grantha, ucp_Khojki, ucp_Linear_A, @@ -299,10 +274,7 @@ enum { ucp_Khudawadi, ucp_Tirhuta, ucp_Multani, - ucp_Old_Hungarian, ucp_Adlam, - ucp_Osage, - ucp_Tangut, ucp_Masaram_Gondi, ucp_Dogra, ucp_Gunjala_Gondi, @@ -312,28 +284,31 @@ enum { ucp_Yezidi, ucp_Cypro_Minoan, ucp_Old_Uyghur, - ucp_Toto, - ucp_Garay, - ucp_Gurung_Khema, - ucp_Ol_Onal, - ucp_Sunuwar, - ucp_Todhri, - ucp_Tulu_Tigalari, /* Scripts which has no characters in other scripts. */ ucp_Unknown, ucp_Common, + ucp_Armenian, + ucp_Hebrew, + ucp_Thai, ucp_Lao, + ucp_Tibetan, + ucp_Ethiopic, + ucp_Cherokee, ucp_Canadian_Aboriginal, ucp_Ogham, + ucp_Runic, ucp_Khmer, ucp_Old_Italic, + ucp_Gothic, ucp_Deseret, ucp_Inherited, ucp_Ugaritic, + ucp_Shavian, ucp_Osmanya, ucp_Braille, ucp_New_Tai_Lue, + ucp_Tifinagh, ucp_Old_Persian, ucp_Kharoshthi, ucp_Balinese, @@ -345,22 +320,32 @@ enum { ucp_Vai, ucp_Saurashtra, ucp_Rejang, + ucp_Lycian, + ucp_Carian, + ucp_Lydian, ucp_Cham, ucp_Tai_Tham, ucp_Tai_Viet, + ucp_Avestan, ucp_Egyptian_Hieroglyphs, + ucp_Samaritan, + ucp_Lisu, ucp_Bamum, ucp_Meetei_Mayek, ucp_Imperial_Aramaic, ucp_Old_South_Arabian, ucp_Inscriptional_Parthian, ucp_Inscriptional_Pahlavi, + ucp_Old_Turkic, ucp_Batak, ucp_Brahmi, ucp_Meroitic_Cursive, + ucp_Meroitic_Hieroglyphs, ucp_Miao, ucp_Sora_Sompeng, + ucp_Caucasian_Albanian, ucp_Bassa_Vah, + ucp_Elbasan, ucp_Pahawh_Hmong, ucp_Mende_Kikakui, ucp_Mro, @@ -373,10 +358,13 @@ enum { ucp_Ahom, ucp_Anatolian_Hieroglyphs, ucp_Hatran, + ucp_Old_Hungarian, ucp_SignWriting, ucp_Bhaiksuki, ucp_Marchen, ucp_Newa, + ucp_Osage, + ucp_Tangut, ucp_Nushu, ucp_Soyombo, ucp_Zanabazar_Square, @@ -390,10 +378,10 @@ enum { ucp_Dives_Akuru, ucp_Khitan_Small_Script, ucp_Tangsa, + ucp_Toto, ucp_Vithkuqi, ucp_Kawi, ucp_Nag_Mundari, - ucp_Kirat_Rai, /* This must be last */ ucp_Script_Count @@ -401,7 +389,7 @@ enum { /* Size of entries in ucd_script_sets[] */ -#define ucd_script_sets_item_size 4 +#define ucd_script_sets_item_size 3 #endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */ diff --git a/ext/pcre/pcre2lib/pcre2_ucptables.c b/ext/pcre/pcre2lib/pcre2_ucptables.c index d2b34037bea6..2110014c29ed 100644 --- a/ext/pcre/pcre2lib/pcre2_ucptables.c +++ b/ext/pcre/pcre2lib/pcre2_ucptables.c @@ -199,8 +199,6 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_extendedpictographic0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_d STR_p STR_i STR_c STR_t STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c "\0" #define STRING_extender0 STR_e STR_x STR_t STR_e STR_n STR_d STR_e STR_r "\0" #define STRING_extpict0 STR_e STR_x STR_t STR_p STR_i STR_c STR_t "\0" -#define STRING_gara0 STR_g STR_a STR_r STR_a "\0" -#define STRING_garay0 STR_g STR_a STR_r STR_a STR_y "\0" #define STRING_geor0 STR_g STR_e STR_o STR_r "\0" #define STRING_georgian0 STR_g STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0" #define STRING_glag0 STR_g STR_l STR_a STR_g "\0" @@ -221,11 +219,9 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_grlink0 STR_g STR_r STR_l STR_i STR_n STR_k "\0" #define STRING_gujarati0 STR_g STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0" #define STRING_gujr0 STR_g STR_u STR_j STR_r "\0" -#define STRING_gukh0 STR_g STR_u STR_k STR_h "\0" #define STRING_gunjalagondi0 STR_g STR_u STR_n STR_j STR_a STR_l STR_a STR_g STR_o STR_n STR_d STR_i "\0" #define STRING_gurmukhi0 STR_g STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0" #define STRING_guru0 STR_g STR_u STR_r STR_u "\0" -#define STRING_gurungkhema0 STR_g STR_u STR_r STR_u STR_n STR_g STR_k STR_h STR_e STR_m STR_a "\0" #define STRING_han0 STR_h STR_a STR_n "\0" #define STRING_hang0 STR_h STR_a STR_n STR_g "\0" #define STRING_hangul0 STR_h STR_a STR_n STR_g STR_u STR_l "\0" @@ -246,8 +242,6 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_hmnp0 STR_h STR_m STR_n STR_p "\0" #define STRING_hung0 STR_h STR_u STR_n STR_g "\0" #define STRING_idc0 STR_i STR_d STR_c "\0" -#define STRING_idcompatmathcontinue0 STR_i STR_d STR_c STR_o STR_m STR_p STR_a STR_t STR_m STR_a STR_t STR_h STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e "\0" -#define STRING_idcompatmathstart0 STR_i STR_d STR_c STR_o STR_m STR_p STR_a STR_t STR_m STR_a STR_t STR_h STR_s STR_t STR_a STR_r STR_t "\0" #define STRING_idcontinue0 STR_i STR_d STR_c STR_o STR_n STR_t STR_i STR_n STR_u STR_e "\0" #define STRING_ideo0 STR_i STR_d STR_e STR_o "\0" #define STRING_ideographic0 STR_i STR_d STR_e STR_o STR_g STR_r STR_a STR_p STR_h STR_i STR_c "\0" @@ -257,10 +251,7 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_idst0 STR_i STR_d STR_s STR_t "\0" #define STRING_idstart0 STR_i STR_d STR_s STR_t STR_a STR_r STR_t "\0" #define STRING_idstrinaryoperator0 STR_i STR_d STR_s STR_t STR_r STR_i STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r "\0" -#define STRING_idsu0 STR_i STR_d STR_s STR_u "\0" -#define STRING_idsunaryoperator0 STR_i STR_d STR_s STR_u STR_n STR_a STR_r STR_y STR_o STR_p STR_e STR_r STR_a STR_t STR_o STR_r "\0" #define STRING_imperialaramaic0 STR_i STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_a STR_r STR_a STR_m STR_a STR_i STR_c "\0" -#define STRING_incb0 STR_i STR_n STR_c STR_b "\0" #define STRING_inherited0 STR_i STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0" #define STRING_inscriptionalpahlavi0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_h STR_l STR_a STR_v STR_i "\0" #define STRING_inscriptionalparthian0 STR_i STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_p STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0" @@ -284,10 +275,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_khoj0 STR_k STR_h STR_o STR_j "\0" #define STRING_khojki0 STR_k STR_h STR_o STR_j STR_k STR_i "\0" #define STRING_khudawadi0 STR_k STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0" -#define STRING_kiratrai0 STR_k STR_i STR_r STR_a STR_t STR_r STR_a STR_i "\0" #define STRING_kits0 STR_k STR_i STR_t STR_s "\0" #define STRING_knda0 STR_k STR_n STR_d STR_a "\0" -#define STRING_krai0 STR_k STR_r STR_a STR_i "\0" #define STRING_kthi0 STR_k STR_t STR_h STR_i "\0" #define STRING_l0 STR_l "\0" #define STRING_l_AMPERSAND0 STR_l STR_AMPERSAND "\0" @@ -334,7 +323,6 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_masaramgondi0 STR_m STR_a STR_s STR_a STR_r STR_a STR_m STR_g STR_o STR_n STR_d STR_i "\0" #define STRING_math0 STR_m STR_a STR_t STR_h "\0" #define STRING_mc0 STR_m STR_c "\0" -#define STRING_mcm0 STR_m STR_c STR_m "\0" #define STRING_me0 STR_m STR_e "\0" #define STRING_medefaidrin0 STR_m STR_e STR_d STR_e STR_f STR_a STR_i STR_d STR_r STR_i STR_n "\0" #define STRING_medf0 STR_m STR_e STR_d STR_f "\0" @@ -349,7 +337,6 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_mlym0 STR_m STR_l STR_y STR_m "\0" #define STRING_mn0 STR_m STR_n "\0" #define STRING_modi0 STR_m STR_o STR_d STR_i "\0" -#define STRING_modifiercombiningmark0 STR_m STR_o STR_d STR_i STR_f STR_i STR_e STR_r STR_c STR_o STR_m STR_b STR_i STR_n STR_i STR_n STR_g STR_m STR_a STR_r STR_k "\0" #define STRING_mong0 STR_m STR_o STR_n STR_g "\0" #define STRING_mongolian0 STR_m STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0" #define STRING_mro0 STR_m STR_r STR_o "\0" @@ -392,8 +379,6 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_oldsoutharabian0 STR_o STR_l STR_d STR_s STR_o STR_u STR_t STR_h STR_a STR_r STR_a STR_b STR_i STR_a STR_n "\0" #define STRING_oldturkic0 STR_o STR_l STR_d STR_t STR_u STR_r STR_k STR_i STR_c "\0" #define STRING_olduyghur0 STR_o STR_l STR_d STR_u STR_y STR_g STR_h STR_u STR_r "\0" -#define STRING_olonal0 STR_o STR_l STR_o STR_n STR_a STR_l "\0" -#define STRING_onao0 STR_o STR_n STR_a STR_o "\0" #define STRING_oriya0 STR_o STR_r STR_i STR_y STR_a "\0" #define STRING_orkh0 STR_o STR_r STR_k STR_h "\0" #define STRING_orya0 STR_o STR_r STR_y STR_a "\0" @@ -478,8 +463,6 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_sterm0 STR_s STR_t STR_e STR_r STR_m "\0" #define STRING_sund0 STR_s STR_u STR_n STR_d "\0" #define STRING_sundanese0 STR_s STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0" -#define STRING_sunu0 STR_s STR_u STR_n STR_u "\0" -#define STRING_sunuwar0 STR_s STR_u STR_n STR_u STR_w STR_a STR_r "\0" #define STRING_sylo0 STR_s STR_y STR_l STR_o "\0" #define STRING_sylotinagri0 STR_s STR_y STR_l STR_o STR_t STR_i STR_n STR_a STR_g STR_r STR_i "\0" #define STRING_syrc0 STR_s STR_y STR_r STR_c "\0" @@ -515,11 +498,7 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_tirh0 STR_t STR_i STR_r STR_h "\0" #define STRING_tirhuta0 STR_t STR_i STR_r STR_h STR_u STR_t STR_a "\0" #define STRING_tnsa0 STR_t STR_n STR_s STR_a "\0" -#define STRING_todhri0 STR_t STR_o STR_d STR_h STR_r STR_i "\0" -#define STRING_todr0 STR_t STR_o STR_d STR_r "\0" #define STRING_toto0 STR_t STR_o STR_t STR_o "\0" -#define STRING_tulutigalari0 STR_t STR_u STR_l STR_u STR_t STR_i STR_g STR_a STR_l STR_a STR_r STR_i "\0" -#define STRING_tutg0 STR_t STR_u STR_t STR_g "\0" #define STRING_ugar0 STR_u STR_g STR_a STR_r "\0" #define STRING_ugaritic0 STR_u STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0" #define STRING_uideo0 STR_u STR_i STR_d STR_e STR_o "\0" @@ -711,8 +690,6 @@ const char PRIV(utt_names)[] = STRING_extendedpictographic0 STRING_extender0 STRING_extpict0 - STRING_gara0 - STRING_garay0 STRING_geor0 STRING_georgian0 STRING_glag0 @@ -733,11 +710,9 @@ const char PRIV(utt_names)[] = STRING_grlink0 STRING_gujarati0 STRING_gujr0 - STRING_gukh0 STRING_gunjalagondi0 STRING_gurmukhi0 STRING_guru0 - STRING_gurungkhema0 STRING_han0 STRING_hang0 STRING_hangul0 @@ -758,8 +733,6 @@ const char PRIV(utt_names)[] = STRING_hmnp0 STRING_hung0 STRING_idc0 - STRING_idcompatmathcontinue0 - STRING_idcompatmathstart0 STRING_idcontinue0 STRING_ideo0 STRING_ideographic0 @@ -769,10 +742,7 @@ const char PRIV(utt_names)[] = STRING_idst0 STRING_idstart0 STRING_idstrinaryoperator0 - STRING_idsu0 - STRING_idsunaryoperator0 STRING_imperialaramaic0 - STRING_incb0 STRING_inherited0 STRING_inscriptionalpahlavi0 STRING_inscriptionalparthian0 @@ -796,10 +766,8 @@ const char PRIV(utt_names)[] = STRING_khoj0 STRING_khojki0 STRING_khudawadi0 - STRING_kiratrai0 STRING_kits0 STRING_knda0 - STRING_krai0 STRING_kthi0 STRING_l0 STRING_l_AMPERSAND0 @@ -846,7 +814,6 @@ const char PRIV(utt_names)[] = STRING_masaramgondi0 STRING_math0 STRING_mc0 - STRING_mcm0 STRING_me0 STRING_medefaidrin0 STRING_medf0 @@ -861,7 +828,6 @@ const char PRIV(utt_names)[] = STRING_mlym0 STRING_mn0 STRING_modi0 - STRING_modifiercombiningmark0 STRING_mong0 STRING_mongolian0 STRING_mro0 @@ -904,8 +870,6 @@ const char PRIV(utt_names)[] = STRING_oldsoutharabian0 STRING_oldturkic0 STRING_olduyghur0 - STRING_olonal0 - STRING_onao0 STRING_oriya0 STRING_orkh0 STRING_orya0 @@ -990,8 +954,6 @@ const char PRIV(utt_names)[] = STRING_sterm0 STRING_sund0 STRING_sundanese0 - STRING_sunu0 - STRING_sunuwar0 STRING_sylo0 STRING_sylotinagri0 STRING_syrc0 @@ -1027,11 +989,7 @@ const char PRIV(utt_names)[] = STRING_tirh0 STRING_tirhuta0 STRING_tnsa0 - STRING_todhri0 - STRING_todr0 STRING_toto0 - STRING_tulutigalari0 - STRING_tutg0 STRING_ugar0 STRING_ugaritic0 STRING_uideo0 @@ -1079,7 +1037,7 @@ const char PRIV(utt_names)[] = const ucp_type_table PRIV(utt)[] = { { 0, PT_SCX, ucp_Adlam }, { 6, PT_SCX, ucp_Adlam }, - { 11, PT_SCX, ucp_Caucasian_Albanian }, + { 11, PT_SC, ucp_Caucasian_Albanian }, { 16, PT_BOOL, ucp_ASCII_Hex_Digit }, { 21, PT_SC, ucp_Ahom }, { 26, PT_BOOL, ucp_Alphabetic }, @@ -1088,13 +1046,13 @@ const ucp_type_table PRIV(utt)[] = { { 64, PT_ANY, 0 }, { 68, PT_SCX, ucp_Arabic }, { 73, PT_SCX, ucp_Arabic }, - { 80, PT_SCX, ucp_Armenian }, + { 80, PT_SC, ucp_Armenian }, { 89, PT_SC, ucp_Imperial_Aramaic }, - { 94, PT_SCX, ucp_Armenian }, + { 94, PT_SC, ucp_Armenian }, { 99, PT_BOOL, ucp_ASCII }, { 105, PT_BOOL, ucp_ASCII_Hex_Digit }, - { 119, PT_SCX, ucp_Avestan }, - { 127, PT_SCX, ucp_Avestan }, + { 119, PT_SC, ucp_Avestan }, + { 127, PT_SC, ucp_Avestan }, { 132, PT_SC, ucp_Balinese }, { 137, PT_SC, ucp_Balinese }, { 146, PT_SC, ucp_Bamum }, @@ -1148,11 +1106,11 @@ const ucp_type_table PRIV(utt)[] = { { 480, PT_SCX, ucp_Chakma }, { 485, PT_SC, ucp_Canadian_Aboriginal }, { 504, PT_SC, ucp_Canadian_Aboriginal }, - { 509, PT_SCX, ucp_Carian }, - { 514, PT_SCX, ucp_Carian }, + { 509, PT_SC, ucp_Carian }, + { 514, PT_SC, ucp_Carian }, { 521, PT_BOOL, ucp_Cased }, { 527, PT_BOOL, ucp_Case_Ignorable }, - { 541, PT_SCX, ucp_Caucasian_Albanian }, + { 541, PT_SC, ucp_Caucasian_Albanian }, { 559, PT_PC, ucp_Cc }, { 562, PT_PC, ucp_Cf }, { 565, PT_SCX, ucp_Chakma }, @@ -1162,8 +1120,8 @@ const ucp_type_table PRIV(utt)[] = { { 621, PT_BOOL, ucp_Changes_When_Lowercased }, { 643, PT_BOOL, ucp_Changes_When_Titlecased }, { 665, PT_BOOL, ucp_Changes_When_Uppercased }, - { 687, PT_SCX, ucp_Cherokee }, - { 692, PT_SCX, ucp_Cherokee }, + { 687, PT_SC, ucp_Cherokee }, + { 692, PT_SC, ucp_Cherokee }, { 701, PT_SC, ucp_Chorasmian }, { 712, PT_SC, ucp_Chorasmian }, { 717, PT_BOOL, ucp_Case_Ignorable }, @@ -1206,8 +1164,8 @@ const ucp_type_table PRIV(utt)[] = { { 963, PT_BOOL, ucp_Emoji_Component }, { 969, PT_SC, ucp_Egyptian_Hieroglyphs }, { 974, PT_SC, ucp_Egyptian_Hieroglyphs }, - { 994, PT_SCX, ucp_Elbasan }, - { 999, PT_SCX, ucp_Elbasan }, + { 994, PT_SC, ucp_Elbasan }, + { 999, PT_SC, ucp_Elbasan }, { 1007, PT_SC, ucp_Elymaic }, { 1012, PT_SC, ucp_Elymaic }, { 1020, PT_BOOL, ucp_Emoji_Modifier }, @@ -1217,376 +1175,355 @@ const ucp_type_table PRIV(utt)[] = { { 1060, PT_BOOL, ucp_Emoji_Modifier_Base }, { 1078, PT_BOOL, ucp_Emoji_Presentation }, { 1096, PT_BOOL, ucp_Emoji_Presentation }, - { 1102, PT_SCX, ucp_Ethiopic }, - { 1107, PT_SCX, ucp_Ethiopic }, + { 1102, PT_SC, ucp_Ethiopic }, + { 1107, PT_SC, ucp_Ethiopic }, { 1116, PT_BOOL, ucp_Extender }, { 1120, PT_BOOL, ucp_Extended_Pictographic }, { 1141, PT_BOOL, ucp_Extender }, { 1150, PT_BOOL, ucp_Extended_Pictographic }, - { 1158, PT_SCX, ucp_Garay }, - { 1163, PT_SCX, ucp_Garay }, - { 1169, PT_SCX, ucp_Georgian }, - { 1174, PT_SCX, ucp_Georgian }, - { 1183, PT_SCX, ucp_Glagolitic }, - { 1188, PT_SCX, ucp_Glagolitic }, - { 1199, PT_SCX, ucp_Gunjala_Gondi }, - { 1204, PT_SCX, ucp_Masaram_Gondi }, - { 1209, PT_SCX, ucp_Gothic }, - { 1214, PT_SCX, ucp_Gothic }, - { 1221, PT_SCX, ucp_Grantha }, - { 1226, PT_SCX, ucp_Grantha }, - { 1234, PT_BOOL, ucp_Grapheme_Base }, - { 1247, PT_BOOL, ucp_Grapheme_Extend }, - { 1262, PT_BOOL, ucp_Grapheme_Link }, - { 1275, PT_BOOL, ucp_Grapheme_Base }, - { 1282, PT_SCX, ucp_Greek }, - { 1288, PT_SCX, ucp_Greek }, - { 1293, PT_BOOL, ucp_Grapheme_Extend }, - { 1299, PT_BOOL, ucp_Grapheme_Link }, - { 1306, PT_SCX, ucp_Gujarati }, - { 1315, PT_SCX, ucp_Gujarati }, - { 1320, PT_SCX, ucp_Gurung_Khema }, - { 1325, PT_SCX, ucp_Gunjala_Gondi }, - { 1338, PT_SCX, ucp_Gurmukhi }, - { 1347, PT_SCX, ucp_Gurmukhi }, - { 1352, PT_SCX, ucp_Gurung_Khema }, - { 1364, PT_SCX, ucp_Han }, - { 1368, PT_SCX, ucp_Hangul }, - { 1373, PT_SCX, ucp_Hangul }, - { 1380, PT_SCX, ucp_Han }, - { 1385, PT_SCX, ucp_Hanifi_Rohingya }, - { 1400, PT_SCX, ucp_Hanunoo }, - { 1405, PT_SCX, ucp_Hanunoo }, - { 1413, PT_SC, ucp_Hatran }, - { 1418, PT_SC, ucp_Hatran }, - { 1425, PT_SCX, ucp_Hebrew }, - { 1430, PT_SCX, ucp_Hebrew }, - { 1437, PT_BOOL, ucp_Hex_Digit }, - { 1441, PT_BOOL, ucp_Hex_Digit }, - { 1450, PT_SCX, ucp_Hiragana }, - { 1455, PT_SCX, ucp_Hiragana }, - { 1464, PT_SC, ucp_Anatolian_Hieroglyphs }, - { 1469, PT_SC, ucp_Pahawh_Hmong }, - { 1474, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, - { 1479, PT_SCX, ucp_Old_Hungarian }, - { 1484, PT_BOOL, ucp_ID_Continue }, - { 1488, PT_BOOL, ucp_ID_Compat_Math_Continue }, - { 1509, PT_BOOL, ucp_ID_Compat_Math_Start }, - { 1527, PT_BOOL, ucp_ID_Continue }, - { 1538, PT_BOOL, ucp_Ideographic }, - { 1543, PT_BOOL, ucp_Ideographic }, - { 1555, PT_BOOL, ucp_ID_Start }, - { 1559, PT_BOOL, ucp_IDS_Binary_Operator }, - { 1564, PT_BOOL, ucp_IDS_Binary_Operator }, - { 1582, PT_BOOL, ucp_IDS_Trinary_Operator }, - { 1587, PT_BOOL, ucp_ID_Start }, - { 1595, PT_BOOL, ucp_IDS_Trinary_Operator }, - { 1614, PT_BOOL, ucp_IDS_Unary_Operator }, - { 1619, PT_BOOL, ucp_IDS_Unary_Operator }, - { 1636, PT_SC, ucp_Imperial_Aramaic }, - { 1652, PT_BOOL, ucp_InCB }, - { 1657, PT_SC, ucp_Inherited }, - { 1667, PT_SC, ucp_Inscriptional_Pahlavi }, - { 1688, PT_SC, ucp_Inscriptional_Parthian }, - { 1710, PT_SC, ucp_Old_Italic }, - { 1715, PT_SCX, ucp_Javanese }, - { 1720, PT_SCX, ucp_Javanese }, - { 1729, PT_BOOL, ucp_Join_Control }, - { 1735, PT_BOOL, ucp_Join_Control }, - { 1747, PT_SCX, ucp_Kaithi }, - { 1754, PT_SCX, ucp_Kayah_Li }, - { 1759, PT_SCX, ucp_Katakana }, - { 1764, PT_SCX, ucp_Kannada }, - { 1772, PT_SCX, ucp_Katakana }, - { 1781, PT_SC, ucp_Kawi }, - { 1786, PT_SCX, ucp_Kayah_Li }, - { 1794, PT_SC, ucp_Kharoshthi }, - { 1799, PT_SC, ucp_Kharoshthi }, - { 1810, PT_SC, ucp_Khitan_Small_Script }, - { 1828, PT_SC, ucp_Khmer }, - { 1834, PT_SC, ucp_Khmer }, - { 1839, PT_SCX, ucp_Khojki }, - { 1844, PT_SCX, ucp_Khojki }, - { 1851, PT_SCX, ucp_Khudawadi }, - { 1861, PT_SC, ucp_Kirat_Rai }, - { 1870, PT_SC, ucp_Khitan_Small_Script }, - { 1875, PT_SCX, ucp_Kannada }, - { 1880, PT_SC, ucp_Kirat_Rai }, - { 1885, PT_SCX, ucp_Kaithi }, - { 1890, PT_GC, ucp_L }, - { 1892, PT_LAMP, 0 }, - { 1895, PT_SC, ucp_Tai_Tham }, - { 1900, PT_SC, ucp_Lao }, - { 1904, PT_SC, ucp_Lao }, - { 1909, PT_SCX, ucp_Latin }, - { 1915, PT_SCX, ucp_Latin }, - { 1920, PT_LAMP, 0 }, - { 1923, PT_SC, ucp_Lepcha }, - { 1928, PT_SC, ucp_Lepcha }, - { 1935, PT_SCX, ucp_Limbu }, - { 1940, PT_SCX, ucp_Limbu }, - { 1946, PT_SCX, ucp_Linear_A }, - { 1951, PT_SCX, ucp_Linear_B }, - { 1956, PT_SCX, ucp_Linear_A }, - { 1964, PT_SCX, ucp_Linear_B }, - { 1972, PT_SCX, ucp_Lisu }, - { 1977, PT_PC, ucp_Ll }, - { 1980, PT_PC, ucp_Lm }, - { 1983, PT_PC, ucp_Lo }, - { 1986, PT_BOOL, ucp_Logical_Order_Exception }, - { 1990, PT_BOOL, ucp_Logical_Order_Exception }, - { 2012, PT_BOOL, ucp_Lowercase }, - { 2018, PT_BOOL, ucp_Lowercase }, - { 2028, PT_PC, ucp_Lt }, - { 2031, PT_PC, ucp_Lu }, - { 2034, PT_SCX, ucp_Lycian }, - { 2039, PT_SCX, ucp_Lycian }, - { 2046, PT_SCX, ucp_Lydian }, - { 2051, PT_SCX, ucp_Lydian }, - { 2058, PT_GC, ucp_M }, - { 2060, PT_SCX, ucp_Mahajani }, - { 2069, PT_SCX, ucp_Mahajani }, - { 2074, PT_SC, ucp_Makasar }, - { 2079, PT_SC, ucp_Makasar }, - { 2087, PT_SCX, ucp_Malayalam }, - { 2097, PT_SCX, ucp_Mandaic }, - { 2102, PT_SCX, ucp_Mandaic }, - { 2110, PT_SCX, ucp_Manichaean }, - { 2115, PT_SCX, ucp_Manichaean }, - { 2126, PT_SC, ucp_Marchen }, - { 2131, PT_SC, ucp_Marchen }, - { 2139, PT_SCX, ucp_Masaram_Gondi }, - { 2152, PT_BOOL, ucp_Math }, - { 2157, PT_PC, ucp_Mc }, - { 2160, PT_BOOL, ucp_Modifier_Combining_Mark }, - { 2164, PT_PC, ucp_Me }, - { 2167, PT_SC, ucp_Medefaidrin }, - { 2179, PT_SC, ucp_Medefaidrin }, - { 2184, PT_SC, ucp_Meetei_Mayek }, - { 2196, PT_SC, ucp_Mende_Kikakui }, - { 2201, PT_SC, ucp_Mende_Kikakui }, - { 2214, PT_SC, ucp_Meroitic_Cursive }, - { 2219, PT_SCX, ucp_Meroitic_Hieroglyphs }, - { 2224, PT_SC, ucp_Meroitic_Cursive }, - { 2240, PT_SCX, ucp_Meroitic_Hieroglyphs }, - { 2260, PT_SC, ucp_Miao }, - { 2265, PT_SCX, ucp_Malayalam }, - { 2270, PT_PC, ucp_Mn }, - { 2273, PT_SCX, ucp_Modi }, - { 2278, PT_BOOL, ucp_Modifier_Combining_Mark }, - { 2300, PT_SCX, ucp_Mongolian }, - { 2305, PT_SCX, ucp_Mongolian }, - { 2315, PT_SC, ucp_Mro }, - { 2319, PT_SC, ucp_Mro }, - { 2324, PT_SC, ucp_Meetei_Mayek }, - { 2329, PT_SCX, ucp_Multani }, - { 2334, PT_SCX, ucp_Multani }, - { 2342, PT_SCX, ucp_Myanmar }, - { 2350, PT_SCX, ucp_Myanmar }, - { 2355, PT_GC, ucp_N }, - { 2357, PT_SC, ucp_Nabataean }, - { 2367, PT_SC, ucp_Nag_Mundari }, - { 2372, PT_SC, ucp_Nag_Mundari }, - { 2383, PT_SCX, ucp_Nandinagari }, - { 2388, PT_SCX, ucp_Nandinagari }, - { 2400, PT_SC, ucp_Old_North_Arabian }, - { 2405, PT_SC, ucp_Nabataean }, - { 2410, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2416, PT_PC, ucp_Nd }, - { 2419, PT_SC, ucp_Newa }, - { 2424, PT_SC, ucp_New_Tai_Lue }, - { 2434, PT_SCX, ucp_Nko }, - { 2438, PT_SCX, ucp_Nko }, - { 2443, PT_PC, ucp_Nl }, - { 2446, PT_PC, ucp_No }, - { 2449, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2471, PT_SC, ucp_Nushu }, - { 2476, PT_SC, ucp_Nushu }, - { 2482, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, - { 2503, PT_SC, ucp_Ogham }, - { 2508, PT_SC, ucp_Ogham }, - { 2514, PT_SC, ucp_Ol_Chiki }, - { 2522, PT_SC, ucp_Ol_Chiki }, - { 2527, PT_SCX, ucp_Old_Hungarian }, - { 2540, PT_SC, ucp_Old_Italic }, - { 2550, PT_SC, ucp_Old_North_Arabian }, - { 2566, PT_SCX, ucp_Old_Permic }, - { 2576, PT_SC, ucp_Old_Persian }, - { 2587, PT_SC, ucp_Old_Sogdian }, - { 2598, PT_SC, ucp_Old_South_Arabian }, - { 2614, PT_SCX, ucp_Old_Turkic }, - { 2624, PT_SCX, ucp_Old_Uyghur }, - { 2634, PT_SCX, ucp_Ol_Onal }, - { 2641, PT_SCX, ucp_Ol_Onal }, - { 2646, PT_SCX, ucp_Oriya }, - { 2652, PT_SCX, ucp_Old_Turkic }, - { 2657, PT_SCX, ucp_Oriya }, - { 2662, PT_SCX, ucp_Osage }, - { 2668, PT_SCX, ucp_Osage }, - { 2673, PT_SC, ucp_Osmanya }, - { 2678, PT_SC, ucp_Osmanya }, - { 2686, PT_SCX, ucp_Old_Uyghur }, - { 2691, PT_GC, ucp_P }, - { 2693, PT_SC, ucp_Pahawh_Hmong }, - { 2705, PT_SC, ucp_Palmyrene }, - { 2710, PT_SC, ucp_Palmyrene }, - { 2720, PT_BOOL, ucp_Pattern_Syntax }, - { 2727, PT_BOOL, ucp_Pattern_Syntax }, - { 2741, PT_BOOL, ucp_Pattern_White_Space }, - { 2759, PT_BOOL, ucp_Pattern_White_Space }, - { 2765, PT_SC, ucp_Pau_Cin_Hau }, - { 2770, PT_SC, ucp_Pau_Cin_Hau }, - { 2780, PT_PC, ucp_Pc }, - { 2783, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2787, PT_PC, ucp_Pd }, - { 2790, PT_PC, ucp_Pe }, - { 2793, PT_SCX, ucp_Old_Permic }, - { 2798, PT_PC, ucp_Pf }, - { 2801, PT_SCX, ucp_Phags_Pa }, - { 2806, PT_SCX, ucp_Phags_Pa }, - { 2814, PT_SC, ucp_Inscriptional_Pahlavi }, - { 2819, PT_SCX, ucp_Psalter_Pahlavi }, - { 2824, PT_SC, ucp_Phoenician }, - { 2829, PT_SC, ucp_Phoenician }, - { 2840, PT_PC, ucp_Pi }, - { 2843, PT_SC, ucp_Miao }, - { 2848, PT_PC, ucp_Po }, - { 2851, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2878, PT_SC, ucp_Inscriptional_Parthian }, - { 2883, PT_PC, ucp_Ps }, - { 2886, PT_SCX, ucp_Psalter_Pahlavi }, - { 2901, PT_SCX, ucp_Coptic }, - { 2906, PT_SC, ucp_Inherited }, - { 2911, PT_BOOL, ucp_Quotation_Mark }, - { 2917, PT_BOOL, ucp_Quotation_Mark }, - { 2931, PT_BOOL, ucp_Radical }, - { 2939, PT_BOOL, ucp_Regional_Indicator }, - { 2957, PT_SC, ucp_Rejang }, - { 2964, PT_BOOL, ucp_Regional_Indicator }, - { 2967, PT_SC, ucp_Rejang }, - { 2972, PT_SCX, ucp_Hanifi_Rohingya }, - { 2977, PT_SCX, ucp_Runic }, - { 2983, PT_SCX, ucp_Runic }, - { 2988, PT_GC, ucp_S }, - { 2990, PT_SCX, ucp_Samaritan }, - { 3000, PT_SCX, ucp_Samaritan }, - { 3005, PT_SC, ucp_Old_South_Arabian }, - { 3010, PT_SC, ucp_Saurashtra }, - { 3015, PT_SC, ucp_Saurashtra }, - { 3026, PT_PC, ucp_Sc }, - { 3029, PT_BOOL, ucp_Soft_Dotted }, - { 3032, PT_BOOL, ucp_Sentence_Terminal }, - { 3049, PT_SC, ucp_SignWriting }, - { 3054, PT_SCX, ucp_Sharada }, - { 3062, PT_SCX, ucp_Shavian }, - { 3070, PT_SCX, ucp_Shavian }, - { 3075, PT_SCX, ucp_Sharada }, - { 3080, PT_SC, ucp_Siddham }, - { 3085, PT_SC, ucp_Siddham }, - { 3093, PT_SC, ucp_SignWriting }, - { 3105, PT_SCX, ucp_Khudawadi }, - { 3110, PT_SCX, ucp_Sinhala }, - { 3115, PT_SCX, ucp_Sinhala }, - { 3123, PT_PC, ucp_Sk }, - { 3126, PT_PC, ucp_Sm }, - { 3129, PT_PC, ucp_So }, - { 3132, PT_BOOL, ucp_Soft_Dotted }, - { 3143, PT_SCX, ucp_Sogdian }, - { 3148, PT_SCX, ucp_Sogdian }, - { 3156, PT_SC, ucp_Old_Sogdian }, - { 3161, PT_SC, ucp_Sora_Sompeng }, - { 3166, PT_SC, ucp_Sora_Sompeng }, - { 3178, PT_SC, ucp_Soyombo }, - { 3183, PT_SC, ucp_Soyombo }, - { 3191, PT_BOOL, ucp_White_Space }, - { 3197, PT_BOOL, ucp_Sentence_Terminal }, - { 3203, PT_SC, ucp_Sundanese }, - { 3208, PT_SC, ucp_Sundanese }, - { 3218, PT_SCX, ucp_Sunuwar }, - { 3223, PT_SCX, ucp_Sunuwar }, - { 3231, PT_SCX, ucp_Syloti_Nagri }, - { 3236, PT_SCX, ucp_Syloti_Nagri }, - { 3248, PT_SCX, ucp_Syriac }, - { 3253, PT_SCX, ucp_Syriac }, - { 3260, PT_SCX, ucp_Tagalog }, - { 3268, PT_SCX, ucp_Tagbanwa }, - { 3273, PT_SCX, ucp_Tagbanwa }, - { 3282, PT_SCX, ucp_Tai_Le }, - { 3288, PT_SC, ucp_Tai_Tham }, - { 3296, PT_SC, ucp_Tai_Viet }, - { 3304, PT_SCX, ucp_Takri }, - { 3309, PT_SCX, ucp_Takri }, - { 3315, PT_SCX, ucp_Tai_Le }, - { 3320, PT_SC, ucp_New_Tai_Lue }, - { 3325, PT_SCX, ucp_Tamil }, - { 3331, PT_SCX, ucp_Tamil }, - { 3336, PT_SCX, ucp_Tangut }, - { 3341, PT_SC, ucp_Tangsa }, - { 3348, PT_SCX, ucp_Tangut }, - { 3355, PT_SC, ucp_Tai_Viet }, - { 3360, PT_SCX, ucp_Telugu }, - { 3365, PT_SCX, ucp_Telugu }, - { 3372, PT_BOOL, ucp_Terminal_Punctuation }, - { 3377, PT_BOOL, ucp_Terminal_Punctuation }, - { 3397, PT_SCX, ucp_Tifinagh }, - { 3402, PT_SCX, ucp_Tagalog }, - { 3407, PT_SCX, ucp_Thaana }, - { 3412, PT_SCX, ucp_Thaana }, - { 3419, PT_SCX, ucp_Thai }, - { 3424, PT_SCX, ucp_Tibetan }, - { 3432, PT_SCX, ucp_Tibetan }, - { 3437, PT_SCX, ucp_Tifinagh }, - { 3446, PT_SCX, ucp_Tirhuta }, - { 3451, PT_SCX, ucp_Tirhuta }, - { 3459, PT_SC, ucp_Tangsa }, - { 3464, PT_SCX, ucp_Todhri }, - { 3471, PT_SCX, ucp_Todhri }, - { 3476, PT_SCX, ucp_Toto }, - { 3481, PT_SCX, ucp_Tulu_Tigalari }, - { 3494, PT_SCX, ucp_Tulu_Tigalari }, - { 3499, PT_SC, ucp_Ugaritic }, - { 3504, PT_SC, ucp_Ugaritic }, - { 3513, PT_BOOL, ucp_Unified_Ideograph }, - { 3519, PT_BOOL, ucp_Unified_Ideograph }, - { 3536, PT_SC, ucp_Unknown }, - { 3544, PT_BOOL, ucp_Uppercase }, - { 3550, PT_BOOL, ucp_Uppercase }, - { 3560, PT_SC, ucp_Vai }, - { 3564, PT_SC, ucp_Vai }, - { 3569, PT_BOOL, ucp_Variation_Selector }, - { 3587, PT_SC, ucp_Vithkuqi }, - { 3592, PT_SC, ucp_Vithkuqi }, - { 3601, PT_BOOL, ucp_Variation_Selector }, - { 3604, PT_SC, ucp_Wancho }, - { 3611, PT_SC, ucp_Warang_Citi }, - { 3616, PT_SC, ucp_Warang_Citi }, - { 3627, PT_SC, ucp_Wancho }, - { 3632, PT_BOOL, ucp_White_Space }, - { 3643, PT_BOOL, ucp_White_Space }, - { 3650, PT_ALNUM, 0 }, - { 3654, PT_BOOL, ucp_XID_Continue }, - { 3659, PT_BOOL, ucp_XID_Continue }, - { 3671, PT_BOOL, ucp_XID_Start }, - { 3676, PT_BOOL, ucp_XID_Start }, - { 3685, PT_SC, ucp_Old_Persian }, - { 3690, PT_PXSPACE, 0 }, - { 3694, PT_SPACE, 0 }, - { 3698, PT_SC, ucp_Cuneiform }, - { 3703, PT_UCNC, 0 }, - { 3707, PT_WORD, 0 }, - { 3711, PT_SCX, ucp_Yezidi }, - { 3716, PT_SCX, ucp_Yezidi }, - { 3723, PT_SCX, ucp_Yi }, - { 3726, PT_SCX, ucp_Yi }, - { 3731, PT_GC, ucp_Z }, - { 3733, PT_SC, ucp_Zanabazar_Square }, - { 3749, PT_SC, ucp_Zanabazar_Square }, - { 3754, PT_SC, ucp_Inherited }, - { 3759, PT_PC, ucp_Zl }, - { 3762, PT_PC, ucp_Zp }, - { 3765, PT_PC, ucp_Zs }, - { 3768, PT_SC, ucp_Common }, - { 3773, PT_SC, ucp_Unknown } + { 1158, PT_SCX, ucp_Georgian }, + { 1163, PT_SCX, ucp_Georgian }, + { 1172, PT_SCX, ucp_Glagolitic }, + { 1177, PT_SCX, ucp_Glagolitic }, + { 1188, PT_SCX, ucp_Gunjala_Gondi }, + { 1193, PT_SCX, ucp_Masaram_Gondi }, + { 1198, PT_SC, ucp_Gothic }, + { 1203, PT_SC, ucp_Gothic }, + { 1210, PT_SCX, ucp_Grantha }, + { 1215, PT_SCX, ucp_Grantha }, + { 1223, PT_BOOL, ucp_Grapheme_Base }, + { 1236, PT_BOOL, ucp_Grapheme_Extend }, + { 1251, PT_BOOL, ucp_Grapheme_Link }, + { 1264, PT_BOOL, ucp_Grapheme_Base }, + { 1271, PT_SCX, ucp_Greek }, + { 1277, PT_SCX, ucp_Greek }, + { 1282, PT_BOOL, ucp_Grapheme_Extend }, + { 1288, PT_BOOL, ucp_Grapheme_Link }, + { 1295, PT_SCX, ucp_Gujarati }, + { 1304, PT_SCX, ucp_Gujarati }, + { 1309, PT_SCX, ucp_Gunjala_Gondi }, + { 1322, PT_SCX, ucp_Gurmukhi }, + { 1331, PT_SCX, ucp_Gurmukhi }, + { 1336, PT_SCX, ucp_Han }, + { 1340, PT_SCX, ucp_Hangul }, + { 1345, PT_SCX, ucp_Hangul }, + { 1352, PT_SCX, ucp_Han }, + { 1357, PT_SCX, ucp_Hanifi_Rohingya }, + { 1372, PT_SCX, ucp_Hanunoo }, + { 1377, PT_SCX, ucp_Hanunoo }, + { 1385, PT_SC, ucp_Hatran }, + { 1390, PT_SC, ucp_Hatran }, + { 1397, PT_SC, ucp_Hebrew }, + { 1402, PT_SC, ucp_Hebrew }, + { 1409, PT_BOOL, ucp_Hex_Digit }, + { 1413, PT_BOOL, ucp_Hex_Digit }, + { 1422, PT_SCX, ucp_Hiragana }, + { 1427, PT_SCX, ucp_Hiragana }, + { 1436, PT_SC, ucp_Anatolian_Hieroglyphs }, + { 1441, PT_SC, ucp_Pahawh_Hmong }, + { 1446, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 1451, PT_SC, ucp_Old_Hungarian }, + { 1456, PT_BOOL, ucp_ID_Continue }, + { 1460, PT_BOOL, ucp_ID_Continue }, + { 1471, PT_BOOL, ucp_Ideographic }, + { 1476, PT_BOOL, ucp_Ideographic }, + { 1488, PT_BOOL, ucp_ID_Start }, + { 1492, PT_BOOL, ucp_IDS_Binary_Operator }, + { 1497, PT_BOOL, ucp_IDS_Binary_Operator }, + { 1515, PT_BOOL, ucp_IDS_Trinary_Operator }, + { 1520, PT_BOOL, ucp_ID_Start }, + { 1528, PT_BOOL, ucp_IDS_Trinary_Operator }, + { 1547, PT_SC, ucp_Imperial_Aramaic }, + { 1563, PT_SC, ucp_Inherited }, + { 1573, PT_SC, ucp_Inscriptional_Pahlavi }, + { 1594, PT_SC, ucp_Inscriptional_Parthian }, + { 1616, PT_SC, ucp_Old_Italic }, + { 1621, PT_SCX, ucp_Javanese }, + { 1626, PT_SCX, ucp_Javanese }, + { 1635, PT_BOOL, ucp_Join_Control }, + { 1641, PT_BOOL, ucp_Join_Control }, + { 1653, PT_SCX, ucp_Kaithi }, + { 1660, PT_SCX, ucp_Kayah_Li }, + { 1665, PT_SCX, ucp_Katakana }, + { 1670, PT_SCX, ucp_Kannada }, + { 1678, PT_SCX, ucp_Katakana }, + { 1687, PT_SC, ucp_Kawi }, + { 1692, PT_SCX, ucp_Kayah_Li }, + { 1700, PT_SC, ucp_Kharoshthi }, + { 1705, PT_SC, ucp_Kharoshthi }, + { 1716, PT_SC, ucp_Khitan_Small_Script }, + { 1734, PT_SC, ucp_Khmer }, + { 1740, PT_SC, ucp_Khmer }, + { 1745, PT_SCX, ucp_Khojki }, + { 1750, PT_SCX, ucp_Khojki }, + { 1757, PT_SCX, ucp_Khudawadi }, + { 1767, PT_SC, ucp_Khitan_Small_Script }, + { 1772, PT_SCX, ucp_Kannada }, + { 1777, PT_SCX, ucp_Kaithi }, + { 1782, PT_GC, ucp_L }, + { 1784, PT_LAMP, 0 }, + { 1787, PT_SC, ucp_Tai_Tham }, + { 1792, PT_SC, ucp_Lao }, + { 1796, PT_SC, ucp_Lao }, + { 1801, PT_SCX, ucp_Latin }, + { 1807, PT_SCX, ucp_Latin }, + { 1812, PT_LAMP, 0 }, + { 1815, PT_SC, ucp_Lepcha }, + { 1820, PT_SC, ucp_Lepcha }, + { 1827, PT_SCX, ucp_Limbu }, + { 1832, PT_SCX, ucp_Limbu }, + { 1838, PT_SCX, ucp_Linear_A }, + { 1843, PT_SCX, ucp_Linear_B }, + { 1848, PT_SCX, ucp_Linear_A }, + { 1856, PT_SCX, ucp_Linear_B }, + { 1864, PT_SC, ucp_Lisu }, + { 1869, PT_PC, ucp_Ll }, + { 1872, PT_PC, ucp_Lm }, + { 1875, PT_PC, ucp_Lo }, + { 1878, PT_BOOL, ucp_Logical_Order_Exception }, + { 1882, PT_BOOL, ucp_Logical_Order_Exception }, + { 1904, PT_BOOL, ucp_Lowercase }, + { 1910, PT_BOOL, ucp_Lowercase }, + { 1920, PT_PC, ucp_Lt }, + { 1923, PT_PC, ucp_Lu }, + { 1926, PT_SC, ucp_Lycian }, + { 1931, PT_SC, ucp_Lycian }, + { 1938, PT_SC, ucp_Lydian }, + { 1943, PT_SC, ucp_Lydian }, + { 1950, PT_GC, ucp_M }, + { 1952, PT_SCX, ucp_Mahajani }, + { 1961, PT_SCX, ucp_Mahajani }, + { 1966, PT_SC, ucp_Makasar }, + { 1971, PT_SC, ucp_Makasar }, + { 1979, PT_SCX, ucp_Malayalam }, + { 1989, PT_SCX, ucp_Mandaic }, + { 1994, PT_SCX, ucp_Mandaic }, + { 2002, PT_SCX, ucp_Manichaean }, + { 2007, PT_SCX, ucp_Manichaean }, + { 2018, PT_SC, ucp_Marchen }, + { 2023, PT_SC, ucp_Marchen }, + { 2031, PT_SCX, ucp_Masaram_Gondi }, + { 2044, PT_BOOL, ucp_Math }, + { 2049, PT_PC, ucp_Mc }, + { 2052, PT_PC, ucp_Me }, + { 2055, PT_SC, ucp_Medefaidrin }, + { 2067, PT_SC, ucp_Medefaidrin }, + { 2072, PT_SC, ucp_Meetei_Mayek }, + { 2084, PT_SC, ucp_Mende_Kikakui }, + { 2089, PT_SC, ucp_Mende_Kikakui }, + { 2102, PT_SC, ucp_Meroitic_Cursive }, + { 2107, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 2112, PT_SC, ucp_Meroitic_Cursive }, + { 2128, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 2148, PT_SC, ucp_Miao }, + { 2153, PT_SCX, ucp_Malayalam }, + { 2158, PT_PC, ucp_Mn }, + { 2161, PT_SCX, ucp_Modi }, + { 2166, PT_SCX, ucp_Mongolian }, + { 2171, PT_SCX, ucp_Mongolian }, + { 2181, PT_SC, ucp_Mro }, + { 2185, PT_SC, ucp_Mro }, + { 2190, PT_SC, ucp_Meetei_Mayek }, + { 2195, PT_SCX, ucp_Multani }, + { 2200, PT_SCX, ucp_Multani }, + { 2208, PT_SCX, ucp_Myanmar }, + { 2216, PT_SCX, ucp_Myanmar }, + { 2221, PT_GC, ucp_N }, + { 2223, PT_SC, ucp_Nabataean }, + { 2233, PT_SC, ucp_Nag_Mundari }, + { 2238, PT_SC, ucp_Nag_Mundari }, + { 2249, PT_SCX, ucp_Nandinagari }, + { 2254, PT_SCX, ucp_Nandinagari }, + { 2266, PT_SC, ucp_Old_North_Arabian }, + { 2271, PT_SC, ucp_Nabataean }, + { 2276, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2282, PT_PC, ucp_Nd }, + { 2285, PT_SC, ucp_Newa }, + { 2290, PT_SC, ucp_New_Tai_Lue }, + { 2300, PT_SCX, ucp_Nko }, + { 2304, PT_SCX, ucp_Nko }, + { 2309, PT_PC, ucp_Nl }, + { 2312, PT_PC, ucp_No }, + { 2315, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2337, PT_SC, ucp_Nushu }, + { 2342, PT_SC, ucp_Nushu }, + { 2348, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 2369, PT_SC, ucp_Ogham }, + { 2374, PT_SC, ucp_Ogham }, + { 2380, PT_SC, ucp_Ol_Chiki }, + { 2388, PT_SC, ucp_Ol_Chiki }, + { 2393, PT_SC, ucp_Old_Hungarian }, + { 2406, PT_SC, ucp_Old_Italic }, + { 2416, PT_SC, ucp_Old_North_Arabian }, + { 2432, PT_SCX, ucp_Old_Permic }, + { 2442, PT_SC, ucp_Old_Persian }, + { 2453, PT_SC, ucp_Old_Sogdian }, + { 2464, PT_SC, ucp_Old_South_Arabian }, + { 2480, PT_SC, ucp_Old_Turkic }, + { 2490, PT_SCX, ucp_Old_Uyghur }, + { 2500, PT_SCX, ucp_Oriya }, + { 2506, PT_SC, ucp_Old_Turkic }, + { 2511, PT_SCX, ucp_Oriya }, + { 2516, PT_SC, ucp_Osage }, + { 2522, PT_SC, ucp_Osage }, + { 2527, PT_SC, ucp_Osmanya }, + { 2532, PT_SC, ucp_Osmanya }, + { 2540, PT_SCX, ucp_Old_Uyghur }, + { 2545, PT_GC, ucp_P }, + { 2547, PT_SC, ucp_Pahawh_Hmong }, + { 2559, PT_SC, ucp_Palmyrene }, + { 2564, PT_SC, ucp_Palmyrene }, + { 2574, PT_BOOL, ucp_Pattern_Syntax }, + { 2581, PT_BOOL, ucp_Pattern_Syntax }, + { 2595, PT_BOOL, ucp_Pattern_White_Space }, + { 2613, PT_BOOL, ucp_Pattern_White_Space }, + { 2619, PT_SC, ucp_Pau_Cin_Hau }, + { 2624, PT_SC, ucp_Pau_Cin_Hau }, + { 2634, PT_PC, ucp_Pc }, + { 2637, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2641, PT_PC, ucp_Pd }, + { 2644, PT_PC, ucp_Pe }, + { 2647, PT_SCX, ucp_Old_Permic }, + { 2652, PT_PC, ucp_Pf }, + { 2655, PT_SCX, ucp_Phags_Pa }, + { 2660, PT_SCX, ucp_Phags_Pa }, + { 2668, PT_SC, ucp_Inscriptional_Pahlavi }, + { 2673, PT_SCX, ucp_Psalter_Pahlavi }, + { 2678, PT_SC, ucp_Phoenician }, + { 2683, PT_SC, ucp_Phoenician }, + { 2694, PT_PC, ucp_Pi }, + { 2697, PT_SC, ucp_Miao }, + { 2702, PT_PC, ucp_Po }, + { 2705, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2732, PT_SC, ucp_Inscriptional_Parthian }, + { 2737, PT_PC, ucp_Ps }, + { 2740, PT_SCX, ucp_Psalter_Pahlavi }, + { 2755, PT_SCX, ucp_Coptic }, + { 2760, PT_SC, ucp_Inherited }, + { 2765, PT_BOOL, ucp_Quotation_Mark }, + { 2771, PT_BOOL, ucp_Quotation_Mark }, + { 2785, PT_BOOL, ucp_Radical }, + { 2793, PT_BOOL, ucp_Regional_Indicator }, + { 2811, PT_SC, ucp_Rejang }, + { 2818, PT_BOOL, ucp_Regional_Indicator }, + { 2821, PT_SC, ucp_Rejang }, + { 2826, PT_SCX, ucp_Hanifi_Rohingya }, + { 2831, PT_SC, ucp_Runic }, + { 2837, PT_SC, ucp_Runic }, + { 2842, PT_GC, ucp_S }, + { 2844, PT_SC, ucp_Samaritan }, + { 2854, PT_SC, ucp_Samaritan }, + { 2859, PT_SC, ucp_Old_South_Arabian }, + { 2864, PT_SC, ucp_Saurashtra }, + { 2869, PT_SC, ucp_Saurashtra }, + { 2880, PT_PC, ucp_Sc }, + { 2883, PT_BOOL, ucp_Soft_Dotted }, + { 2886, PT_BOOL, ucp_Sentence_Terminal }, + { 2903, PT_SC, ucp_SignWriting }, + { 2908, PT_SCX, ucp_Sharada }, + { 2916, PT_SC, ucp_Shavian }, + { 2924, PT_SC, ucp_Shavian }, + { 2929, PT_SCX, ucp_Sharada }, + { 2934, PT_SC, ucp_Siddham }, + { 2939, PT_SC, ucp_Siddham }, + { 2947, PT_SC, ucp_SignWriting }, + { 2959, PT_SCX, ucp_Khudawadi }, + { 2964, PT_SCX, ucp_Sinhala }, + { 2969, PT_SCX, ucp_Sinhala }, + { 2977, PT_PC, ucp_Sk }, + { 2980, PT_PC, ucp_Sm }, + { 2983, PT_PC, ucp_So }, + { 2986, PT_BOOL, ucp_Soft_Dotted }, + { 2997, PT_SCX, ucp_Sogdian }, + { 3002, PT_SCX, ucp_Sogdian }, + { 3010, PT_SC, ucp_Old_Sogdian }, + { 3015, PT_SC, ucp_Sora_Sompeng }, + { 3020, PT_SC, ucp_Sora_Sompeng }, + { 3032, PT_SC, ucp_Soyombo }, + { 3037, PT_SC, ucp_Soyombo }, + { 3045, PT_BOOL, ucp_White_Space }, + { 3051, PT_BOOL, ucp_Sentence_Terminal }, + { 3057, PT_SC, ucp_Sundanese }, + { 3062, PT_SC, ucp_Sundanese }, + { 3072, PT_SCX, ucp_Syloti_Nagri }, + { 3077, PT_SCX, ucp_Syloti_Nagri }, + { 3089, PT_SCX, ucp_Syriac }, + { 3094, PT_SCX, ucp_Syriac }, + { 3101, PT_SCX, ucp_Tagalog }, + { 3109, PT_SCX, ucp_Tagbanwa }, + { 3114, PT_SCX, ucp_Tagbanwa }, + { 3123, PT_SCX, ucp_Tai_Le }, + { 3129, PT_SC, ucp_Tai_Tham }, + { 3137, PT_SC, ucp_Tai_Viet }, + { 3145, PT_SCX, ucp_Takri }, + { 3150, PT_SCX, ucp_Takri }, + { 3156, PT_SCX, ucp_Tai_Le }, + { 3161, PT_SC, ucp_New_Tai_Lue }, + { 3166, PT_SCX, ucp_Tamil }, + { 3172, PT_SCX, ucp_Tamil }, + { 3177, PT_SC, ucp_Tangut }, + { 3182, PT_SC, ucp_Tangsa }, + { 3189, PT_SC, ucp_Tangut }, + { 3196, PT_SC, ucp_Tai_Viet }, + { 3201, PT_SCX, ucp_Telugu }, + { 3206, PT_SCX, ucp_Telugu }, + { 3213, PT_BOOL, ucp_Terminal_Punctuation }, + { 3218, PT_BOOL, ucp_Terminal_Punctuation }, + { 3238, PT_SC, ucp_Tifinagh }, + { 3243, PT_SCX, ucp_Tagalog }, + { 3248, PT_SCX, ucp_Thaana }, + { 3253, PT_SCX, ucp_Thaana }, + { 3260, PT_SC, ucp_Thai }, + { 3265, PT_SC, ucp_Tibetan }, + { 3273, PT_SC, ucp_Tibetan }, + { 3278, PT_SC, ucp_Tifinagh }, + { 3287, PT_SCX, ucp_Tirhuta }, + { 3292, PT_SCX, ucp_Tirhuta }, + { 3300, PT_SC, ucp_Tangsa }, + { 3305, PT_SC, ucp_Toto }, + { 3310, PT_SC, ucp_Ugaritic }, + { 3315, PT_SC, ucp_Ugaritic }, + { 3324, PT_BOOL, ucp_Unified_Ideograph }, + { 3330, PT_BOOL, ucp_Unified_Ideograph }, + { 3347, PT_SC, ucp_Unknown }, + { 3355, PT_BOOL, ucp_Uppercase }, + { 3361, PT_BOOL, ucp_Uppercase }, + { 3371, PT_SC, ucp_Vai }, + { 3375, PT_SC, ucp_Vai }, + { 3380, PT_BOOL, ucp_Variation_Selector }, + { 3398, PT_SC, ucp_Vithkuqi }, + { 3403, PT_SC, ucp_Vithkuqi }, + { 3412, PT_BOOL, ucp_Variation_Selector }, + { 3415, PT_SC, ucp_Wancho }, + { 3422, PT_SC, ucp_Warang_Citi }, + { 3427, PT_SC, ucp_Warang_Citi }, + { 3438, PT_SC, ucp_Wancho }, + { 3443, PT_BOOL, ucp_White_Space }, + { 3454, PT_BOOL, ucp_White_Space }, + { 3461, PT_ALNUM, 0 }, + { 3465, PT_BOOL, ucp_XID_Continue }, + { 3470, PT_BOOL, ucp_XID_Continue }, + { 3482, PT_BOOL, ucp_XID_Start }, + { 3487, PT_BOOL, ucp_XID_Start }, + { 3496, PT_SC, ucp_Old_Persian }, + { 3501, PT_PXSPACE, 0 }, + { 3505, PT_SPACE, 0 }, + { 3509, PT_SC, ucp_Cuneiform }, + { 3514, PT_UCNC, 0 }, + { 3518, PT_WORD, 0 }, + { 3522, PT_SCX, ucp_Yezidi }, + { 3527, PT_SCX, ucp_Yezidi }, + { 3534, PT_SCX, ucp_Yi }, + { 3537, PT_SCX, ucp_Yi }, + { 3542, PT_GC, ucp_Z }, + { 3544, PT_SC, ucp_Zanabazar_Square }, + { 3560, PT_SC, ucp_Zanabazar_Square }, + { 3565, PT_SC, ucp_Inherited }, + { 3570, PT_PC, ucp_Zl }, + { 3573, PT_PC, ucp_Zp }, + { 3576, PT_PC, ucp_Zs }, + { 3579, PT_SC, ucp_Common }, + { 3584, PT_SC, ucp_Unknown } }; const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); diff --git a/ext/pcre/pcre2lib/pcre2_util.h b/ext/pcre/pcre2lib/pcre2_util.h deleted file mode 100644 index ea8635552a15..000000000000 --- a/ext/pcre/pcre2lib/pcre2_util.h +++ /dev/null @@ -1,132 +0,0 @@ -/************************************************* -* Perl-Compatible Regular Expressions * -*************************************************/ - -/* PCRE2 is a library of functions to support regular expressions whose syntax -and semantics are as close as possible to those of the Perl 5 language. - - Written by Philip Hazel - Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge - ------------------------------------------------------------------------------ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name of the University of Cambridge nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ -*/ - -#ifndef PCRE2_UTIL_H_IDEMPOTENT_GUARD -#define PCRE2_UTIL_H_IDEMPOTENT_GUARD - -/* Assertion macros */ - -#ifdef PCRE2_DEBUG - -#if defined(HAVE_ASSERT_H) && !defined(NDEBUG) -#include -#endif - -/* PCRE2_ASSERT(x) can be used to inject an assert() for conditions -that the code below doesn't support. It is a NOP for non debug builds -but in debug builds will print information about the location of the -code where it triggered and crash. - -It is meant to work like assert(), and therefore the expression used -should indicate what the expected state is, and shouldn't have any -side-effects. */ - -#if defined(HAVE_ASSERT_H) && !defined(NDEBUG) -#define PCRE2_ASSERT(x) assert(x) -#else -#define PCRE2_ASSERT(x) do \ -{ \ - if (!(x)) \ - { \ - fprintf(stderr, "Assertion failed at " __FILE__ ":%d\n", __LINE__); \ - abort(); \ - } \ -} while(0) -#endif - -/* PCRE2_UNREACHABLE() can be used to mark locations on the code that -shouldn't be reached. In non debug builds is defined as a hint for -the compiler to eliminate any code after it, so it is useful also for -performance reasons, but should be used with care because if it is -ever reached will trigger Undefined Behaviour and if you are lucky a -crash. In debug builds it will report the location where it was triggered -and crash. One important point to consider when using this macro, is -that it is only implemented for a few compilers, and therefore can't -be relied on to always be active either, so if it is followed by some -code it is important to make sure that the whole thing is safe to -use even if the macro is not there (ex: make sure there is a `break` -after it if used at the end of a `case`) and to test your code also -with a configuration where the macro will be a NOP. */ - -#if defined(HAVE_ASSERT_H) && !defined(NDEBUG) -#define PCRE2_UNREACHABLE() \ -assert(((void)"Execution reached unexpected point", 0)) -#else -#define PCRE2_UNREACHABLE() do \ -{ \ -fprintf(stderr, "Execution reached unexpected point at " __FILE__ \ - ":%d\n", __LINE__); \ -abort(); \ -} while(0) -#endif - -/* PCRE2_DEBUG_UNREACHABLE() is a debug only version of the previous -macro. It is meant to be used in places where the code is handling -an error situation in code that shouldn't be reached, but that has -some sort of fallback code to normally handle the error. When in -doubt you should use this instead of the previous macro. Like in -the previous case, it is a good idea to document as much as possible -the reason and the actions that should be taken if it ever triggers. */ - -#define PCRE2_DEBUG_UNREACHABLE() PCRE2_UNREACHABLE() - -#endif /* PCRE2_DEBUG */ - -#ifndef PCRE2_DEBUG_UNREACHABLE -#define PCRE2_DEBUG_UNREACHABLE() do {} while(0) -#endif - -#ifndef PCRE2_UNREACHABLE -#ifdef HAVE_BUILTIN_UNREACHABLE -#define PCRE2_UNREACHABLE() __builtin_unreachable() -#elif defined(HAVE_BUILTIN_ASSUME) -#define PCRE2_UNREACHABLE() __assume(0) -#else -#define PCRE2_UNREACHABLE() do {} while(0) -#endif -#endif /* !PCRE2_UNREACHABLE */ - -#ifndef PCRE2_ASSERT -#define PCRE2_ASSERT(x) do {} while(0) -#endif - -#endif /* PCRE2_UTIL_H_IDEMPOTENT_GUARD */ - -/* End of pcre2_util.h */ diff --git a/ext/pcre/pcre2lib/pcre2_xclass.c b/ext/pcre/pcre2lib/pcre2_xclass.c index 25de7cbf38b6..5df25d2c8dfa 100644 --- a/ext/pcre/pcre2lib/pcre2_xclass.c +++ b/ext/pcre/pcre2lib/pcre2_xclass.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2024 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -38,9 +38,9 @@ POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------------- */ -/* This module contains two internal functions that are used to match -OP_XCLASS and OP_ECLASS. It is used by pcre2_auto_possessify() and by both -pcre2_match() and pcre2_dfa_match(). */ +/* This module contains an internal function that is used to match an extended +class. It is used by pcre2_auto_possessify() and by both pcre2_match() and +pcre2_def_match(). */ #ifdef HAVE_CONFIG_H @@ -66,75 +66,114 @@ Returns: TRUE if character matches, else FALSE */ BOOL -PRIV(xclass)(uint32_t c, PCRE2_SPTR data, const uint8_t *char_lists_end, BOOL utf) +PRIV(xclass)(uint32_t c, PCRE2_SPTR data, BOOL utf) { -/* Update PRIV(update_classbits) when this function is changed. */ PCRE2_UCHAR t; -BOOL not_negated = (*data & XCL_NOT) == 0; -uint32_t type, max_index, min_index, value; -const uint8_t *next_char; +BOOL negated = (*data & XCL_NOT) != 0; #if PCRE2_CODE_UNIT_WIDTH == 8 /* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */ utf = TRUE; #endif -/* Code points < 256 are matched against a bitmap, if one is present. */ +/* Code points < 256 are matched against a bitmap, if one is present. If not, +we still carry on, because there may be ranges that start below 256 in the +additional data. */ -if ((*data++ & XCL_MAP) != 0) +if (c < 256) { - if (c < 256) - return (((const uint8_t *)data)[c/8] & (1u << (c&7))) != 0; - /* Skip bitmap. */ - data += 32 / sizeof(PCRE2_UCHAR); + if ((*data & XCL_HASPROP) == 0) + { + if ((*data & XCL_MAP) == 0) return negated; + return (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0; + } + if ((*data & XCL_MAP) != 0 && + (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0) + return !negated; /* char found */ } -/* Match against the list of Unicode properties. We won't ever +/* First skip the bit map if present. Then match against the list of Unicode +properties or large chars or ranges that end with a large char. We won't ever encounter XCL_PROP or XCL_NOTPROP when UTF support is not compiled. */ -#ifdef SUPPORT_UNICODE -if (*data == XCL_PROP || *data == XCL_NOTPROP) + +if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(PCRE2_UCHAR); + +while ((t = *data++) != XCL_END) { - /* The UCD record is the same for all properties. */ - const ucd_record *prop = GET_UCD(c); + uint32_t x, y; + if (t == XCL_SINGLE) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + } + else +#endif + x = *data++; + if (c == x) return !negated; + } + else if (t == XCL_RANGE) + { +#ifdef SUPPORT_UNICODE + if (utf) + { + GETCHARINC(x, data); /* macro generates multiple statements */ + GETCHARINC(y, data); /* macro generates multiple statements */ + } + else +#endif + { + x = *data++; + y = *data++; + } + if (c >= x && c <= y) return !negated; + } - do +#ifdef SUPPORT_UNICODE + else /* XCL_PROP & XCL_NOTPROP */ { int chartype; - BOOL isprop = (*data++) == XCL_PROP; + const ucd_record *prop = GET_UCD(c); + BOOL isprop = t == XCL_PROP; BOOL ok; switch(*data) { + case PT_ANY: + if (isprop) return !negated; + break; + case PT_LAMP: chartype = prop->chartype; if ((chartype == ucp_Lu || chartype == ucp_Ll || - chartype == ucp_Lt) == isprop) return not_negated; + chartype == ucp_Lt) == isprop) return !negated; break; case PT_GC: if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop) - return not_negated; + return !negated; break; case PT_PC: - if ((data[1] == prop->chartype) == isprop) return not_negated; + if ((data[1] == prop->chartype) == isprop) return !negated; break; case PT_SC: - if ((data[1] == prop->script) == isprop) return not_negated; + if ((data[1] == prop->script) == isprop) return !negated; break; case PT_SCX: ok = (data[1] == prop->script || MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), data[1]) != 0); - if (ok == isprop) return not_negated; + if (ok == isprop) return !negated; break; case PT_ALNUM: chartype = prop->chartype; if ((PRIV(ucp_gentype)[chartype] == ucp_L || PRIV(ucp_gentype)[chartype] == ucp_N) == isprop) - return not_negated; + return !negated; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -147,12 +186,12 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP) { HSPACE_CASES: VSPACE_CASES: - if (isprop) return not_negated; + if (isprop) return !negated; break; default: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop) - return not_negated; + return !negated; break; } break; @@ -162,7 +201,7 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP) if ((PRIV(ucp_gentype)[chartype] == ucp_L || PRIV(ucp_gentype)[chartype] == ucp_N || chartype == ucp_Mn || chartype == ucp_Pc) == isprop) - return not_negated; + return !negated; break; case PT_UCNC: @@ -170,24 +209,24 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP) { if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT || c == CHAR_GRAVE_ACCENT) == isprop) - return not_negated; + return !negated; } else { if ((c < 0xd800 || c > 0xdfff) == isprop) - return not_negated; + return !negated; } break; case PT_BIDICL: if ((UCD_BIDICLASS_PROP(prop) == data[1]) == isprop) - return not_negated; + return !negated; break; case PT_BOOL: ok = MAPBIT(PRIV(ucd_boolprop_sets) + UCD_BPROPS_PROP(prop), data[1]) != 0; - if (ok == isprop) return not_negated; + if (ok == isprop) return !negated; break; /* The following three properties can occur only in an XCLASS, as there @@ -209,7 +248,7 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP) (chartype == ucp_Cf && c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) )) == isprop) - return not_negated; + return !negated; break; /* Printable character: same as graphic, with the addition of Zs, i.e. @@ -223,7 +262,7 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP) (chartype == ucp_Cf && c != 0x061c && (c < 0x2066 || c > 0x2069)) )) == isprop) - return not_negated; + return !negated; break; /* Punctuation: all Unicode punctuation, plus ASCII characters that @@ -234,7 +273,7 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP) chartype = prop->chartype; if ((PRIV(ucp_gentype)[chartype] == ucp_P || (c < 128 && PRIV(ucp_gentype)[chartype] == ucp_S)) == isprop) - return not_negated; + return !negated; break; /* Perl has two sets of hex digits */ @@ -246,300 +285,24 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP) (c >= 0xff10 && c <= 0xff19) || /* Fullwidth digits */ (c >= 0xff21 && c <= 0xff26) || /* Fullwidth letters */ (c >= 0xff41 && c <= 0xff46)) == isprop) - return not_negated; + return !negated; break; /* This should never occur, but compilers may mutter if there is no default. */ default: - PCRE2_DEBUG_UNREACHABLE(); return FALSE; } data += 2; } - while (*data == XCL_PROP || *data == XCL_NOTPROP); - } #else (void)utf; /* Avoid compiler warning */ #endif /* SUPPORT_UNICODE */ - -/* Match against large chars or ranges that end with a large char. */ -if (*data < XCL_LIST) - { - while ((t = *data++) != XCL_END) - { - uint32_t x, y; - -#ifdef SUPPORT_UNICODE - if (utf) - { - GETCHARINC(x, data); /* macro generates multiple statements */ - } - else -#endif - x = *data++; - - if (t == XCL_SINGLE) - { - /* Since character ranges follow the properties, and they are - sorted, early return is possible for all characters <= x. */ - if (c <= x) return (c == x) ? not_negated : !not_negated; - continue; - } - - PCRE2_ASSERT(t == XCL_RANGE); -#ifdef SUPPORT_UNICODE - if (utf) - { - GETCHARINC(y, data); /* macro generates multiple statements */ - } - else -#endif - y = *data++; - - /* Since character ranges follow the properties, and they are - sorted, early return is possible for all characters <= y. */ - if (c <= y) return (c >= x) ? not_negated : !not_negated; - } - - return !not_negated; /* char did not match */ - } - -#if PCRE2_CODE_UNIT_WIDTH == 8 -type = (uint32_t)(data[0] << 8) | data[1]; -data += 2; -#else -type = data[0]; -data++; -#endif /* CODE_UNIT_WIDTH */ - -/* Align characters. */ -next_char = char_lists_end - (GET(data, 0) << 1); -type &= XCL_TYPE_MASK; - -/* Alignment check. */ -PCRE2_ASSERT(((uintptr_t)next_char & 0x1) == 0); - -if (c >= XCL_CHAR_LIST_HIGH_16_START) - { - max_index = type & XCL_ITEM_COUNT_MASK; - if (max_index == XCL_ITEM_COUNT_MASK) - { - max_index = *(const uint16_t*)next_char; - PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); - next_char += 2; - } - - next_char += max_index << 1; - type >>= XCL_TYPE_BIT_LEN; } -if (c < XCL_CHAR_LIST_LOW_32_START) - { - max_index = type & XCL_ITEM_COUNT_MASK; - - c = (uint16_t)((c << XCL_CHAR_SHIFT) | XCL_CHAR_END); - - if (max_index == XCL_ITEM_COUNT_MASK) - { - max_index = *(const uint16_t*)next_char; - PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); - next_char += 2; - } - - if (max_index == 0 || c < *(const uint16_t*)next_char) - return ((type & XCL_BEGIN_WITH_RANGE) != 0) == not_negated; - - min_index = 0; - value = ((const uint16_t*)next_char)[--max_index]; - if (c >= value) - return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; - - max_index--; - - /* Binary search of a range. */ - while (TRUE) - { - uint32_t mid_index = (min_index + max_index) >> 1; - value = ((const uint16_t*)next_char)[mid_index]; - - if (c < value) - max_index = mid_index - 1; - else if (((const uint16_t*)next_char)[mid_index + 1] <= c) - min_index = mid_index + 1; - else - return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; - } - } - -/* Skip the 16 bit ranges. */ -max_index = type & XCL_ITEM_COUNT_MASK; -if (max_index == XCL_ITEM_COUNT_MASK) - { - max_index = *(const uint16_t*)next_char; - PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); - next_char += 2; - } - -next_char += (max_index << 1); -type >>= XCL_TYPE_BIT_LEN; - -/* Alignment check. */ -PCRE2_ASSERT(((uintptr_t)next_char & 0x3) == 0); - -max_index = type & XCL_ITEM_COUNT_MASK; - -#if PCRE2_CODE_UNIT_WIDTH == 32 -if (c >= XCL_CHAR_LIST_HIGH_32_START) - { - if (max_index == XCL_ITEM_COUNT_MASK) - { - max_index = *(const uint32_t*)next_char; - PCRE2_ASSERT(max_index >= XCL_ITEM_COUNT_MASK); - next_char += 4; - } - - next_char += max_index << 2; - type >>= XCL_TYPE_BIT_LEN; - max_index = type & XCL_ITEM_COUNT_MASK; - } -#endif - -c = (uint32_t)((c << XCL_CHAR_SHIFT) | XCL_CHAR_END); - -if (max_index == XCL_ITEM_COUNT_MASK) - { - max_index = *(const uint32_t*)next_char; - next_char += 4; - } - -if (max_index == 0 || c < *(const uint32_t*)next_char) - return ((type & XCL_BEGIN_WITH_RANGE) != 0) == not_negated; - -min_index = 0; -value = ((const uint32_t*)next_char)[--max_index]; -if (c >= value) - return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; - -max_index--; - -/* Binary search of a range. */ -while (TRUE) - { - uint32_t mid_index = (min_index + max_index) >> 1; - value = ((const uint32_t*)next_char)[mid_index]; - - if (c < value) - max_index = mid_index - 1; - else if (((const uint32_t*)next_char)[mid_index + 1] <= c) - min_index = mid_index + 1; - else - return (value == c || (value & XCL_CHAR_END) == 0) == not_negated; - } -} - - - -/************************************************* -* Match character against an ECLASS * -*************************************************/ - -/* This function is called to match a character against an extended class -used for describing characters using boolean operations on sets. - -Arguments: - c the character - data_start points to the start of the ECLASS data - data_end points one-past-the-last of the ECLASS data - utf TRUE if in UTF mode - -Returns: TRUE if character matches, else FALSE -*/ - -BOOL -PRIV(eclass)(uint32_t c, PCRE2_SPTR data_start, PCRE2_SPTR data_end, - const uint8_t *char_lists_end, BOOL utf) -{ -PCRE2_SPTR ptr = data_start; -PCRE2_UCHAR flags; -uint32_t stack = 0; -int stack_depth = 0; - -PCRE2_ASSERT(data_start < data_end); -flags = *ptr++; -PCRE2_ASSERT((flags & ECL_MAP) == 0 || - (data_end - ptr) >= 32 / (int)sizeof(PCRE2_UCHAR)); - -/* Code points < 256 are matched against a bitmap, if one is present. -Otherwise all codepoints are checked later. */ - -if ((flags & ECL_MAP) != 0) - { - if (c < 256) - return (((const uint8_t *)ptr)[c/8] & (1u << (c&7))) != 0; - - /* Skip the bitmap. */ - ptr += 32 / sizeof(PCRE2_UCHAR); - } - -/* Do a little loop, until we reach the end of the ECLASS. */ -while (ptr < data_end) - { - switch (*ptr) - { - case ECL_AND: - ++ptr; - stack = (stack >> 1) & (stack | ~(uint32_t)1u); - PCRE2_ASSERT(stack_depth >= 2); - --stack_depth; - break; - - case ECL_OR: - ++ptr; - stack = (stack >> 1) | (stack & (uint32_t)1u); - PCRE2_ASSERT(stack_depth >= 2); - --stack_depth; - break; - - case ECL_XOR: - ++ptr; - stack = (stack >> 1) ^ (stack & (uint32_t)1u); - PCRE2_ASSERT(stack_depth >= 2); - --stack_depth; - break; - - case ECL_NOT: - ++ptr; - stack ^= (uint32_t)1u; - PCRE2_ASSERT(stack_depth >= 1); - break; - - case ECL_XCLASS: - { - uint32_t matched = PRIV(xclass)(c, ptr + 1 + LINK_SIZE, char_lists_end, utf); - - ptr += GET(ptr, 1); - stack = (stack << 1) | matched; - ++stack_depth; - break; - } - - /* This should never occur, but compilers may mutter if there is no - default. */ - - default: - PCRE2_DEBUG_UNREACHABLE(); - return FALSE; - } - } - -PCRE2_ASSERT(stack_depth == 1); -(void)stack_depth; /* Ignore unused variable, if assertions are disabled. */ - -/* The final bit left on the stack now holds the match result. */ -return (stack & 1u) != 0; +return negated; /* char did not match */ } /* End of pcre2_xclass.c */ diff --git a/ext/pcre/pcre2lib/sljit/sljitConfig.h b/ext/pcre/pcre2lib/sljit/sljitConfig.h index 993f4fe2fa16..364c8bb7884a 100644 --- a/ext/pcre/pcre2lib/sljit/sljitConfig.h +++ b/ext/pcre/pcre2lib/sljit/sljitConfig.h @@ -29,7 +29,7 @@ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* This file contains the basic configuration options for the SLJIT compiler @@ -47,19 +47,19 @@ extern "C" { #ifndef SLJIT_UTIL_STACK /* Enabled by default */ #define SLJIT_UTIL_STACK 1 -#endif /* SLJIT_UTIL_STACK */ +#endif /* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */ #ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION /* Disabled by default */ #define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0 -#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */ +#endif /* Single threaded application. Does not require any locks. */ #ifndef SLJIT_SINGLE_THREADED /* Disabled by default. */ #define SLJIT_SINGLE_THREADED 0 -#endif /* SLJIT_SINGLE_THREADED */ +#endif /* --------------------------------------------------------------------- */ /* Configuration */ @@ -70,7 +70,7 @@ extern "C" { #ifndef SLJIT_STD_MACROS_DEFINED /* Disabled by default. */ #define SLJIT_STD_MACROS_DEFINED 0 -#endif /* SLJIT_STD_MACROS_DEFINED */ +#endif /* Executable code allocation: If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should @@ -93,7 +93,7 @@ extern "C" { #ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR /* Disabled by default. */ #define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0 -#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */ +#endif /* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an allocator which does not set writable and executable permission @@ -104,7 +104,7 @@ extern "C" { #ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR /* Disabled by default. */ #define SLJIT_WX_EXECUTABLE_ALLOCATOR 0 -#endif /* SLJIT_WX_EXECUTABLE_ALLOCATOR */ +#endif #endif /* !SLJIT_EXECUTABLE_ALLOCATOR */ @@ -112,19 +112,19 @@ extern "C" { #ifndef SLJIT_ARGUMENT_CHECKS /* Disabled by default */ #define SLJIT_ARGUMENT_CHECKS 0 -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif /* Debug checks (assertions, etc.). */ #ifndef SLJIT_DEBUG /* Enabled by default */ #define SLJIT_DEBUG 1 -#endif /* SLJIT_DEBUG */ +#endif /* Verbose operations. */ #ifndef SLJIT_VERBOSE /* Enabled by default */ #define SLJIT_VERBOSE 1 -#endif /* SLJIT_VERBOSE */ +#endif /* SLJIT_IS_FPU_AVAILABLE @@ -137,6 +137,6 @@ extern "C" { #ifdef __cplusplus } /* extern "C" */ -#endif /* __cplusplus */ +#endif #endif /* SLJIT_CONFIG_H_ */ diff --git a/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h b/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h index dcf88efbd437..2720bdab0bd1 100644 --- a/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h +++ b/ext/pcre/pcre2lib/sljit/sljitConfigCPU.h @@ -169,7 +169,7 @@ #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) #define SLJIT_CONFIG_ARM_32 1 -#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 || SLJIT_CONFIG_ARM_THUMB2 */ +#endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define SLJIT_CONFIG_X86 1 diff --git a/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h b/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h index 3ae944efb810..de06dd8e0c02 100644 --- a/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h +++ b/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h @@ -27,6 +27,20 @@ #ifndef SLJIT_CONFIG_INTERNAL_H_ #define SLJIT_CONFIG_INTERNAL_H_ +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ + || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE))) +#include +#endif + +#if (defined SLJIT_DEBUG && SLJIT_DEBUG \ + && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS))) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + /* SLJIT defines the following architecture dependent types and macros: @@ -50,26 +64,16 @@ SLJIT_MASKED_SHIFT : all word shifts are always masked SLJIT_MASKED_SHIFT32 : all 32 bit shifts are always masked SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information - SLJIT_UPPER_BITS_IGNORED : 32 bit operations ignores the upper bits of source registers - SLJIT_UPPER_BITS_ZERO_EXTENDED : 32 bit operations clears the upper bits of destination registers - SLJIT_UPPER_BITS_SIGN_EXTENDED : 32 bit operations replicates the sign bit in the upper bits of destination registers - SLJIT_UPPER_BITS_PRESERVED : 32 bit operations preserves the upper bits of destination registers Constants: SLJIT_NUMBER_OF_REGISTERS : number of available registers SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available scratch floating point registers - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available saved floating point registers - SLJIT_NUMBER_OF_VECTOR_REGISTERS : number of available vector registers - SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS : number of available scratch vector registers - SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS : number of available saved vector registers + SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers + SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers SLJIT_NUMBER_OF_TEMPORARY_REGISTERS : number of available temporary registers SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS : number of available temporary floating point registers - SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS : number of available temporary vector registers - SLJIT_SEPARATE_VECTOR_REGISTERS : if this macro is defined, the vector registers do not - overlap with floating point registers SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index SLJIT_F32_SHIFT : the shift required to apply when accessing a single precision floating point array by index @@ -94,33 +98,16 @@ SLJIT_TMP_R(i) : accessing temporary registers SLJIT_TMP_FR0 .. FR9 : accessing temporary floating point registers SLJIT_TMP_FR(i) : accessing temporary floating point registers - SLJIT_TMP_VR0 .. VR9 : accessing temporary vector registers - SLJIT_TMP_VR(i) : accessing temporary vector registers SLJIT_TMP_DEST_REG : a temporary register for results SLJIT_TMP_MEM_REG : a temporary base register for accessing memory (can be the same as SLJIT_TMP_DEST_REG) SLJIT_TMP_DEST_FREG : a temporary register for float results - SLJIT_TMP_DEST_VREG : a temporary register for vector results SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper) SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero */ -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE))) -#include -#endif - -#if (defined SLJIT_DEBUG && SLJIT_DEBUG \ - && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS))) -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - /***********************************************************/ /* Intel Control-flow Enforcement Technology (CET) spport. */ /***********************************************************/ @@ -298,7 +285,7 @@ extern "C" { #elif defined(_WIN32) #define SLJIT_CACHE_FLUSH(from, to) \ - FlushInstructionCache(GetCurrentProcess(), (void*)(from), (size_t)((char*)(to) - (char*)(from))) + FlushInstructionCache(GetCurrentProcess(), (void*)(from), (char*)(to) - (char*)(from)) #elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || defined(__clang__) @@ -566,7 +553,7 @@ determine the next executed instruction after return. */ #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); -/* Note: sljitLir.h also defines sljit_free_unused_memory_exec() function. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); #define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size) #define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr) @@ -604,12 +591,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_DEST_REG SLJIT_TMP_R0 #define SLJIT_TMP_MEM_REG SLJIT_TMP_R0 #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 -#define SLJIT_LOCALS_OFFSET_BASE (8 * (sljit_s32)sizeof(sljit_sw)) +#define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw)) #define SLJIT_PREF_SHIFT_REG SLJIT_R2 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 -#define SLJIT_UPPER_BITS_IGNORED 1 -#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1 #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -624,7 +609,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #else /* _WIN64 */ #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 10 -#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw)) +#define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw)) #endif /* !_WIN64 */ #define SLJIT_TMP_DEST_REG SLJIT_TMP_R0 #define SLJIT_TMP_MEM_REG SLJIT_TMP_R0 @@ -632,8 +617,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_PREF_SHIFT_REG SLJIT_R3 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 -#define SLJIT_UPPER_BITS_IGNORED 1 -#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1 #elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) @@ -662,8 +645,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw)) #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 -#define SLJIT_UPPER_BITS_IGNORED 1 -#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) @@ -684,7 +665,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #else #define SLJIT_LOCALS_OFFSET_BASE (3 * (sljit_s32)sizeof(sljit_sw)) #endif /* SLJIT_CONFIG_PPC_64 || _AIX */ -#define SLJIT_UPPER_BITS_IGNORED 1 #elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) @@ -706,7 +686,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 -#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1 #elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) @@ -716,19 +695,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12 #define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 -#define SLJIT_SEPARATE_VECTOR_REGISTERS 1 -#define SLJIT_NUMBER_OF_VECTOR_REGISTERS 30 -#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS 0 -#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS 2 #define SLJIT_TMP_DEST_REG SLJIT_TMP_R1 #define SLJIT_TMP_MEM_REG SLJIT_TMP_R1 #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 -#define SLJIT_TMP_DEST_VREG SLJIT_TMP_VR0 #define SLJIT_LOCALS_OFFSET_BASE 0 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 -#define SLJIT_UPPER_BITS_IGNORED 1 -#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) @@ -764,8 +736,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0 #define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE #define SLJIT_MASKED_SHIFT 1 -#define SLJIT_UPPER_BITS_IGNORED 1 -#define SLJIT_UPPER_BITS_PRESERVED 1 #elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) @@ -781,7 +751,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_LOCALS_OFFSET_BASE 0 #define SLJIT_MASKED_SHIFT 1 #define SLJIT_MASKED_SHIFT32 1 -#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1 #elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) @@ -799,13 +768,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #endif -#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) -#define SLJIT_NUMBER_OF_VECTOR_REGISTERS (SLJIT_NUMBER_OF_FLOAT_REGISTERS) -#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS (SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) -#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS (SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS) -#define SLJIT_TMP_DEST_VREG (SLJIT_TMP_DEST_FREG) -#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ - #define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE) #define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \ @@ -814,27 +776,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \ (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) -#define SLJIT_NUMBER_OF_SCRATCH_VECTOR_REGISTERS \ - (SLJIT_NUMBER_OF_VECTOR_REGISTERS - SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS) - -#if (defined SLJIT_UPPER_BITS_ZERO_EXTENDED && SLJIT_UPPER_BITS_ZERO_EXTENDED) \ - + (defined SLJIT_UPPER_BITS_SIGN_EXTENDED && SLJIT_UPPER_BITS_SIGN_EXTENDED) \ - + (defined SLJIT_UPPER_BITS_PRESERVED && SLJIT_UPPER_BITS_PRESERVED) > 1 -#error "Invalid upper bits defintion" -#endif - -#if (defined SLJIT_UPPER_BITS_PRESERVED && SLJIT_UPPER_BITS_PRESERVED) \ - && !(defined SLJIT_UPPER_BITS_IGNORED && SLJIT_UPPER_BITS_IGNORED) -#error "Upper bits preserved requires bits ignored" -#endif - /**********************************/ /* Temporary register management. */ /**********************************/ #define SLJIT_TMP_REGISTER_BASE (SLJIT_NUMBER_OF_REGISTERS + 2) #define SLJIT_TMP_FREGISTER_BASE (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) -#define SLJIT_TMP_VREGISTER_BASE (SLJIT_NUMBER_OF_VECTOR_REGISTERS + 1) /* WARNING: Accessing temporary registers is not recommended, because they are also used by the JIT compiler for various computations. Using them @@ -868,18 +815,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code); #define SLJIT_TMP_FR9 (SLJIT_TMP_FREGISTER_BASE + 9) #define SLJIT_TMP_FR(i) (SLJIT_TMP_FREGISTER_BASE + (i)) -#define SLJIT_TMP_VR0 (SLJIT_TMP_VREGISTER_BASE + 0) -#define SLJIT_TMP_VR1 (SLJIT_TMP_VREGISTER_BASE + 1) -#define SLJIT_TMP_VR2 (SLJIT_TMP_VREGISTER_BASE + 2) -#define SLJIT_TMP_VR3 (SLJIT_TMP_VREGISTER_BASE + 3) -#define SLJIT_TMP_VR4 (SLJIT_TMP_VREGISTER_BASE + 4) -#define SLJIT_TMP_VR5 (SLJIT_TMP_VREGISTER_BASE + 5) -#define SLJIT_TMP_VR6 (SLJIT_TMP_VREGISTER_BASE + 6) -#define SLJIT_TMP_VR7 (SLJIT_TMP_VREGISTER_BASE + 7) -#define SLJIT_TMP_VR8 (SLJIT_TMP_VREGISTER_BASE + 8) -#define SLJIT_TMP_VR9 (SLJIT_TMP_VREGISTER_BASE + 9) -#define SLJIT_TMP_VR(i) (SLJIT_TMP_VREGISTER_BASE + (i)) - /********************************/ /* CPU status flags management. */ /********************************/ diff --git a/ext/pcre/pcre2lib/sljit/sljitLir.c b/ext/pcre/pcre2lib/sljit/sljitLir.c index 6b2d5564c758..2dca17cd6f07 100644 --- a/ext/pcre/pcre2lib/sljit/sljitLir.c +++ b/ext/pcre/pcre2lib/sljit/sljitLir.c @@ -96,10 +96,9 @@ /* All variable flags are even. */ #define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT) #define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT) -#define GET_FLAG_TYPE_MASK(op) (((op) >> VARIABLE_FLAG_SHIFT) & 0x3e) #define GET_OPCODE(op) \ - ((op) & 0xff) + ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) #define HAS_FLAGS(op) \ ((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) @@ -119,9 +118,9 @@ #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) #define ABUF_SIZE 2048 -#else /* !SLJIT_32BIT_ARCHITECTURE */ +#else #define ABUF_SIZE 4096 -#endif /* SLJIT_32BIT_ARCHITECTURE */ +#endif /* Parameter parsing. */ #define REG_MASK 0x7f @@ -140,10 +139,7 @@ #define REG_PAIR_SECOND(reg) ((reg) >> 8) /* Mask for sljit_emit_enter. */ -#define ENTER_GET_REGS(regs) ((regs) & 0xff) -#define ENTER_GET_FLOAT_REGS(regs) (((regs) >> 8) & 0xff) -#define ENTER_GET_VECTOR_REGS(regs) (((regs) >> 16) & 0xff) -#define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3) +#define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3) /* Getters for simd operations, which returns with log2(size). */ #define SLJIT_SIMD_GET_OPCODE(type) ((type) & 0xff) @@ -338,19 +334,19 @@ #if defined(__NetBSD__) #include "allocator_src/sljitProtExecAllocatorNetBSD.c" -#else /* !__NetBSD__ */ +#else #include "allocator_src/sljitProtExecAllocatorPosix.c" -#endif /* __NetBSD__ */ +#endif #elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) #if defined(_WIN32) #include "allocator_src/sljitWXExecAllocatorWindows.c" -#else /* !_WIN32 */ +#else #include "allocator_src/sljitWXExecAllocatorPosix.c" -#endif /* _WIN32 */ +#endif -#else /* !SLJIT_PROT_EXECUTABLAE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */ +#else #if defined(_WIN32) #include "allocator_src/sljitExecAllocatorWindows.c" @@ -358,25 +354,25 @@ #include "allocator_src/sljitExecAllocatorApple.c" #elif defined(__FreeBSD__) #include "allocator_src/sljitExecAllocatorFreeBSD.c" -#else /* !_WIN32 && !__APPLE__ && !__FreeBSD__ */ +#else #include "allocator_src/sljitExecAllocatorPosix.c" -#endif /* _WIN32 */ +#endif -#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */ +#endif #else /* !SLJIT_EXECUTABLE_ALLOCATOR */ #ifndef SLJIT_UPDATE_WX_FLAGS #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) -#endif /* SLJIT_UPDATE_WX_FLAGS */ +#endif #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset)) -#else /* !SLJIT_PROT_EXECUTABLE_ALLOCATOR */ +#else #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr)) -#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */ +#endif /* Argument checking features. */ @@ -438,7 +434,7 @@ #define CHECK_PTR(x) x #define CHECK_REG_INDEX(x) x -#else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_DEBUG && !SLJIT_VERBOSE */ +#else /* Arguments are not checked. */ #define CHECK(x) @@ -456,7 +452,7 @@ static sljit_s32 compiler_initialized = 0; /* A thread safe initialization. */ static void init_compiler(void); -#endif /* SLJIT_CONFIG_X86 */ +#endif SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data) { @@ -505,12 +501,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo compiler->saveds = -1; compiler->fscratches = -1; compiler->fsaveds = -1; -#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - compiler->vscratches = -1; - compiler->vsaveds = -1; -#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ compiler->local_size = -1; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -536,25 +526,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) - SLJIT_ASSERT(compiler->last_flags == 0 && compiler->logical_local_size == 0); + compiler->last_flags = 0; compiler->last_return = -1; + compiler->logical_local_size = 0; #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) - compiler->real_fscratches = -1; - compiler->real_fsaveds = -1; -#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ - SLJIT_ASSERT(compiler->skip_checks == 0); -#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ - #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) if (!compiler_initialized) { init_compiler(); compiler_initialized = 1; } -#endif /* SLJIT_NEEDS_COMPILER_INIT */ +#endif return compiler; } @@ -582,7 +564,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_FREE(compiler->cpool, allocator_data); -#endif /* SLJIT_CONFIG_ARM_V6 */ +#endif SLJIT_FREE(compiler, allocator_data); } @@ -625,14 +607,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *com #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) compiler->status_flags_state = current_flags; -#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ +#endif #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_flags = 0; if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) { compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z)); } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif } /* --------------------------------------------------------------------- */ @@ -685,11 +667,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compile if (size <= 0 || size > 128) return NULL; size = (size + 7) & ~7; -#else /* !SLJIT_64BIT_ARCHITECTURE */ +#else if (size <= 0 || size > 64) return NULL; size = (size + 3) & ~3; -#endif /* SLJIT_64BIT_ARCHITECTURE */ +#endif return ensure_abuf(compiler, (sljit_uw)size); } @@ -770,55 +752,40 @@ static SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size, #endif /* !SLJIT_CONFIG_X86 */ -#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) - -static void update_float_register_count(struct sljit_compiler *compiler, sljit_s32 scratches, sljit_s32 saveds) +static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 vscratches = ENTER_GET_VECTOR_REGS(scratches); - sljit_s32 vsaveds = ENTER_GET_VECTOR_REGS(saveds); - - if (compiler->fscratches < vscratches) - compiler->fscratches = vscratches; - - if (compiler->fsaveds < vsaveds) - compiler->fsaveds = vsaveds; + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(local_size); - if (compiler->fsaveds + compiler->fscratches > SLJIT_NUMBER_OF_FLOAT_REGISTERS) - compiler->fscratches = SLJIT_NUMBER_OF_FLOAT_REGISTERS - compiler->fsaveds; + compiler->options = options; + compiler->scratches = scratches; + compiler->saveds = saveds; + compiler->fscratches = fscratches; + compiler->fsaveds = fsaveds; +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + compiler->last_return = args & SLJIT_ARG_MASK; + compiler->logical_local_size = local_size; +#endif } -#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ - -static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 args, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) +static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(local_size); compiler->options = options; - compiler->scratches = ENTER_GET_REGS(scratches); - compiler->saveds = ENTER_GET_REGS(saveds); - /* These members may be copied to real_* members below. */ - compiler->fscratches = ENTER_GET_FLOAT_REGS(scratches); - compiler->fsaveds = ENTER_GET_FLOAT_REGS(saveds); -#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) - compiler->vscratches = ENTER_GET_VECTOR_REGS(scratches); - compiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds); -#else /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - compiler->real_fscratches = compiler->fscratches; - compiler->real_fsaveds = compiler->fsaveds; - compiler->vscratches = ENTER_GET_VECTOR_REGS(scratches); - compiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds); -#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ - update_float_register_count(compiler, scratches, saveds); -#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */ + compiler->scratches = scratches; + compiler->saveds = saveds; + compiler->fscratches = fscratches; + compiler->fsaveds = fsaveds; #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_return = args & SLJIT_ARG_MASK; compiler->logical_local_size = local_size; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif } static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler) @@ -933,9 +900,9 @@ static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratch #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8) -#else /* !SLJIT_CONFIG_X86_32 */ +#else #define CHECK_IF_VIRTUAL_REGISTER(p) 0 -#endif /* SLJIT_CONFIG_X86_32 */ +#endif static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { @@ -1027,47 +994,17 @@ static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, s return function_check_src_mem(compiler, p, i); } -static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type); - -#define FUNCTION_CHECK_IS_VREG(vr, type) \ - function_check_is_vreg(compiler, (vr), (type)) - -#define FUNCTION_VCHECK(p, i, type) \ - CHECK_ARGUMENT(function_vcheck(compiler, (p), (i), (type))) - -static sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 type) -{ - if (compiler->scratches == -1) - return 0; - - if (FUNCTION_CHECK_IS_VREG(p, type)) - return (i == 0); - - return function_check_src_mem(compiler, p, i); -} - #else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */ - #define FUNCTION_CHECK_IS_FREG(fr, is_32) \ function_check_is_freg(compiler, (fr)) static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr) { - sljit_s32 fscratches, fsaveds; - if (compiler->scratches == -1) return 0; -#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; -#else /* SLJIT_SEPARATE_VECTOR_REGISTERS */ - fscratches = compiler->real_fscratches; - fsaveds = compiler->real_fsaveds; -#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ - - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + fscratches)) - || (fr > (SLJIT_FS0 - fsaveds) && fr <= SLJIT_FS0) + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } @@ -1079,34 +1016,9 @@ static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, s if (compiler->scratches == -1) return 0; - if (function_check_is_freg(compiler, p)) - return (i == 0); - - return function_check_src_mem(compiler, p, i); -} - -#define FUNCTION_CHECK_IS_VREG(vr, type) \ - function_check_is_vreg(compiler, (vr)) - -static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr) -{ - if (compiler->scratches == -1) - return 0; - - return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches)) - || (vr > (SLJIT_VS0 - compiler->vsaveds) && vr <= SLJIT_VS0) - || (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)); -} - -#define FUNCTION_VCHECK(p, i, type) \ - CHECK_ARGUMENT(function_vcheck(compiler, (p), (i))) - -static sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) -{ - if (compiler->scratches == -1) - return 0; - - if (function_check_is_vreg(compiler, p)) + if ((p >= SLJIT_FR0 && p < (SLJIT_FR0 + compiler->fscratches)) + || (p > (SLJIT_FS0 - compiler->fsaveds) && p <= SLJIT_FS0) + || (p >= SLJIT_TMP_FREGISTER_BASE && p < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))) return (i == 0); return function_check_src_mem(compiler, p, i); @@ -1127,15 +1039,15 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp #ifdef _WIN64 #ifdef __GNUC__ # define SLJIT_PRINT_D "ll" -#else /* !__GNUC__ */ +#else # define SLJIT_PRINT_D "I64" -#endif /* __GNUC__ */ -#else /* !_WIN64 */ +#endif +#else # define SLJIT_PRINT_D "l" -#endif /* _WIN64 */ -#else /* !SLJIT_64BIT_ARCHITECTURE */ +#endif +#else # define SLJIT_PRINT_D "" -#endif /* SLJIT_64BIT_ARCHITECTURE */ +#endif static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r) { @@ -1167,73 +1079,57 @@ static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r) fprintf(compiler->verbose, "ft%d", r - SLJIT_TMP_FREGISTER_BASE); } -static void sljit_verbose_vreg(struct sljit_compiler *compiler, sljit_s32 r) -{ -#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ - || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - if (r >= SLJIT_F64_SECOND(SLJIT_VR0)) { - fprintf(compiler->verbose, "^"); - r -= SLJIT_F64_SECOND(0); - } -#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ - - if (r < (SLJIT_VR0 + compiler->vscratches)) - fprintf(compiler->verbose, "vr%d", r - SLJIT_VR0); - else if (r < SLJIT_TMP_VREGISTER_BASE) - fprintf(compiler->verbose, "vs%d", SLJIT_NUMBER_OF_VECTOR_REGISTERS - r); - else - fprintf(compiler->verbose, "vt%d", r - SLJIT_TMP_VREGISTER_BASE); -} - -static void sljit_verbose_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) -{ - if (!(p & REG_MASK)) { - fprintf(compiler->verbose, "[%" SLJIT_PRINT_D "d]", i); - return; - } - - fputc('[', compiler->verbose); - sljit_verbose_reg(compiler, (p) & REG_MASK); - if (p & OFFS_REG_MASK) { - fprintf(compiler->verbose, " + "); - sljit_verbose_reg(compiler, OFFS_REG(p)); - if (i) - fprintf(compiler->verbose, " * %d", 1 << (i)); - } else if (i) - fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); - fputc(']', compiler->verbose); -} - static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (p == SLJIT_IMM) - fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", i); - else if (p & SLJIT_MEM) - sljit_verbose_mem(compiler, p, i); - else + if ((p) == SLJIT_IMM) + fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); + else if ((p) & SLJIT_MEM) { + if ((p) & REG_MASK) { + fputc('[', compiler->verbose); + sljit_verbose_reg(compiler, (p) & REG_MASK); + if ((p) & OFFS_REG_MASK) { + fprintf(compiler->verbose, " + "); + sljit_verbose_reg(compiler, OFFS_REG(p)); + if (i) + fprintf(compiler->verbose, " * %d", 1 << (i)); + } + else if (i) + fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); + fputc(']', compiler->verbose); + } + else + fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); + } else sljit_verbose_reg(compiler, p); } static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (p & SLJIT_MEM) - sljit_verbose_mem(compiler, p, i); + if ((p) & SLJIT_MEM) { + if ((p) & REG_MASK) { + fputc('[', compiler->verbose); + sljit_verbose_reg(compiler, (p) & REG_MASK); + if ((p) & OFFS_REG_MASK) { + fprintf(compiler->verbose, " + "); + sljit_verbose_reg(compiler, OFFS_REG(p)); + if (i) + fprintf(compiler->verbose, "%d", 1 << (i)); + } + else if (i) + fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); + fputc(']', compiler->verbose); + } + else + fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); + } else sljit_verbose_freg(compiler, p); } -static void sljit_verbose_vparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) -{ - if (p & SLJIT_MEM) - sljit_verbose_mem(compiler, p, i); - else - sljit_verbose_vreg(compiler, p); -} - static const char* op0_names[] = { "breakpoint", "nop", "lmul.uw", "lmul.sw", "divmod.u", "divmod.s", "div.u", "div.s", - "memory_barrier", "endbr", "skip_frames_before_return" + "endbr", "skip_frames_before_return" }; static const char* op1_names[] = { @@ -1288,7 +1184,7 @@ static const char* fop2r_names[] = { }; static const char* simd_op2_names[] = { - "and", "or", "xor", "shuffle" + "and", "or", "xor" }; static const char* jump_names[] = { @@ -1328,13 +1224,12 @@ static const char* call_arg_names[] = { || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) #define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1 -#define SLJIT_CHECK_OPCODE(op, flags) ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK | (flags))) static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) struct sljit_jump *jump; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif SLJIT_UNUSED_ARG(compiler); @@ -1346,7 +1241,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com CHECK_ARGUMENT((jump->flags & JUMP_ADDR) || jump->u.label != NULL); jump = jump->next; } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif CHECK_RETURN_OK; } @@ -1357,17 +1252,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com #endif /* !SLJIT_CONFIG_X86 */ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - sljit_s32 real_scratches = ENTER_GET_REGS(scratches); - sljit_s32 real_saveds = ENTER_GET_REGS(saveds); - sljit_s32 real_fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 real_fsaveds = ENTER_GET_FLOAT_REGS(saveds); - sljit_s32 real_vscratches = ENTER_GET_VECTOR_REGS(scratches); - sljit_s32 real_vsaveds = ENTER_GET_VECTOR_REGS(saveds); -#endif /* SLJIT_ARGUMENT_CHECKS */ SLJIT_UNUSED_ARG(compiler); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1377,23 +1264,18 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0); } CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds); - CHECK_ARGUMENT((scratches & ~0xffffff) == 0 && (saveds & ~0xffffff) == 0); - CHECK_ARGUMENT(real_scratches >= 0 && real_scratches <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(real_saveds >= 0 && real_saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); - CHECK_ARGUMENT(real_scratches + real_saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(real_fscratches >= 0 && real_fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(real_fsaveds >= 0 && real_fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); - CHECK_ARGUMENT(real_fscratches + real_fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(real_vscratches >= 0 && real_vscratches <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); - CHECK_ARGUMENT(real_vsaveds >= 0 && real_vsaveds <= SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS); - CHECK_ARGUMENT(real_vscratches + real_vsaveds <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); + CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); + CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); + CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) <= SLJIT_ARG_TYPE_F32); - CHECK_ARGUMENT(function_check_arguments(arg_types, real_scratches, - (options & SLJIT_ENTER_REG_ARG) ? 0 : real_saveds, real_fscratches)); + CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches)); compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " enter ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]); @@ -1425,26 +1307,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil } #endif /* !SLJIT_CONFIG_X86 */ - fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, vscratches:%d, vsaveds:%d, local_size:%d\n", - ENTER_GET_REGS(scratches), ENTER_GET_REGS(saveds), ENTER_GET_FLOAT_REGS(scratches), ENTER_GET_FLOAT_REGS(saveds), - ENTER_GET_VECTOR_REGS(scratches), ENTER_GET_VECTOR_REGS(saveds), local_size); + fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", + scratches, saveds, fscratches, fsaveds, local_size); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - sljit_s32 real_scratches = ENTER_GET_REGS(scratches); - sljit_s32 real_saveds = ENTER_GET_REGS(saveds); - sljit_s32 real_fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 real_fsaveds = ENTER_GET_FLOAT_REGS(saveds); - sljit_s32 real_vscratches = ENTER_GET_VECTOR_REGS(scratches); - sljit_s32 real_vsaveds = ENTER_GET_VECTOR_REGS(saveds); -#endif /* SLJIT_ARGUMENT_CHECKS */ SLJIT_UNUSED_ARG(compiler); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1454,23 +1327,18 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0); } CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds); - CHECK_ARGUMENT((scratches & ~0xffffff) == 0 && (saveds & ~0xffffff) == 0); - CHECK_ARGUMENT(real_scratches >= 0 && real_scratches <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(real_saveds >= 0 && real_saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); - CHECK_ARGUMENT(real_scratches + real_saveds <= SLJIT_NUMBER_OF_REGISTERS); - CHECK_ARGUMENT(real_fscratches >= 0 && real_fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(real_fsaveds >= 0 && real_fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); - CHECK_ARGUMENT(real_fscratches + real_fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); - CHECK_ARGUMENT(real_vscratches >= 0 && real_vscratches <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); - CHECK_ARGUMENT(real_vsaveds >= 0 && real_vsaveds <= SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS); - CHECK_ARGUMENT(real_vscratches + real_vsaveds <= SLJIT_NUMBER_OF_VECTOR_REGISTERS); + CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS); + CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS); + CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64); - CHECK_ARGUMENT(function_check_arguments(arg_types, real_scratches, - (options & SLJIT_ENTER_REG_ARG) ? 0 : real_saveds, real_fscratches)); + CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches)); compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " set_context ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]); @@ -1502,11 +1370,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi } #endif /* !SLJIT_CONFIG_X86 */ - fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, vscratches:%d, vsaveds:%d, local_size:%d\n", - ENTER_GET_REGS(scratches), ENTER_GET_REGS(saveds), ENTER_GET_FLOAT_REGS(scratches), ENTER_GET_FLOAT_REGS(saveds), - ENTER_GET_VECTOR_REGS(scratches), ENTER_GET_VECTOR_REGS(saveds), local_size); + fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", + scratches, saveds, fscratches, fsaveds, local_size); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1521,13 +1388,13 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_RET_VOID); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " return_void\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1560,13 +1427,13 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi break; } - if (SLJIT_CHECK_OPCODE(op, 0) < SLJIT_MOV_F64) { + if (GET_OPCODE(op) < SLJIT_MOV_F64) { FUNCTION_CHECK_SRC(src, srcw); } else { FUNCTION_FCHECK(src, srcw, op & SLJIT_32); } compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (GET_OPCODE(op) < SLJIT_MOV_F64) { @@ -1579,7 +1446,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi } fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1588,14 +1455,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_co { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_SRC(src, srcw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " return_to "); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1604,11 +1471,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW) || ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW) - || (op >= SLJIT_MEMORY_BARRIER && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) < SLJIT_LMUL_UW || SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MEMORY_BARRIER || compiler->scratches >= 2); - if ((SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_LMUL_UW && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN) + || (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN)); + CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2); + if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN) compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1618,7 +1485,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler } fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1632,7 +1499,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MOV && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_REV_S32); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_REV_S32); switch (GET_OPCODE(op)) { case SLJIT_MOV: @@ -1653,7 +1520,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler FUNCTION_CHECK_DST(dst, dstw); FUNCTION_CHECK_SRC(src, srcw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], @@ -1664,7 +1531,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1679,37 +1546,26 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z | VARIABLE_FLAG_MASK) >= SLJIT_MOV - && SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z | VARIABLE_FLAG_MASK) <= SLJIT_MOV_P); - CHECK_ARGUMENT((op & (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)) != (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); + CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); /* All arguments must be valid registers. */ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); - if (GET_OPCODE(op) < SLJIT_MOV_U8 || GET_OPCODE(op) > SLJIT_MOV_S16) { + if (op == SLJIT_MOV32_U8 || op == SLJIT_MOV32_U16) { + /* Only SLJIT_32 is allowed. */ + CHECK_ARGUMENT(!(op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z))); + } else { /* Nothing allowed. */ - CHECK_ARGUMENT(!(op & SLJIT_32)); + CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))); } compiler->last_flags = 0; #endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (op & SLJIT_ATOMIC_TEST) - CHECK_RETURN_OK; - if (sljit_emit_atomic_load(compiler, op | SLJIT_ATOMIC_TEST, dst_reg, mem_reg)) { - fprintf(compiler->verbose, " # atomic_load: unsupported form, no instructions are emitted\n"); - CHECK_RETURN_OK; - } - - fprintf(compiler->verbose, " atomic_load"); - if (op & SLJIT_ATOMIC_USE_CAS) - fprintf(compiler->verbose, "_cas"); - if (op & SLJIT_ATOMIC_USE_LS) - fprintf(compiler->verbose, "_ls"); - - fprintf(compiler->verbose, "%s%s ", !(op & SLJIT_32) ? "" : "32", + fprintf(compiler->verbose, " atomic_load%s%s ", !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); sljit_verbose_reg(compiler, dst_reg); fprintf(compiler->verbose, ", ["); @@ -1732,40 +1588,29 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z) >= SLJIT_MOV - && SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z) <= SLJIT_MOV_P); - CHECK_ARGUMENT((op & (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)) != (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); + CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); /* All arguments must be valid registers. */ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && (src_reg != temp_reg || (op & SLJIT_ATOMIC_USE_LS))); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && src_reg != temp_reg); - CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE_MASK(op) == SLJIT_ATOMIC_STORED); + CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_ATOMIC_STORED); - if (GET_OPCODE(op) < SLJIT_MOV_U8 || GET_OPCODE(op) > SLJIT_MOV_S16) { - /* Nothing allowed. */ - CHECK_ARGUMENT(!(op & SLJIT_32)); + if (GET_OPCODE(op) == SLJIT_MOV_U8 || GET_OPCODE(op) == SLJIT_MOV_U16) { + /* Only SLJIT_32, SLJIT_ATOMIC_STORED are allowed. */ + CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); + } else { + /* Only SLJIT_ATOMIC_STORED is allowed. */ + CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z))); } - compiler->last_flags = GET_FLAG_TYPE_MASK(op) | (op & SLJIT_32); + compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32); #endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (op & SLJIT_ATOMIC_TEST) - CHECK_RETURN_OK; - if (sljit_emit_atomic_store(compiler, op | SLJIT_ATOMIC_TEST, src_reg, mem_reg, temp_reg)) { - fprintf(compiler->verbose, " # atomic_store: unsupported form, no instructions are emitted\n"); - CHECK_RETURN_OK; - } - - fprintf(compiler->verbose, " atomic_store"); - if (op & SLJIT_ATOMIC_USE_CAS) - fprintf(compiler->verbose, "_cas"); - if (op & SLJIT_ATOMIC_USE_LS) - fprintf(compiler->verbose, "_ls"); - - fprintf(compiler->verbose, "%s%s%s ", !(op & SLJIT_32) ? "" : "32", + fprintf(compiler->verbose, " atomic_store%s%s%s ", !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & VARIABLE_FLAG_MASK) ? "" : ".stored"); sljit_verbose_reg(compiler, src_reg); fprintf(compiler->verbose, ", ["); @@ -1789,7 +1634,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ROTR); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ROTR); switch (GET_OPCODE(op)) { case SLJIT_AND: @@ -1842,7 +1687,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32", @@ -1858,7 +1703,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler sljit_verbose_param(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1873,7 +1718,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compile FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s ", op2r_names[GET_OPCODE(op) - SLJIT_OP2R_BASE], !(op & SLJIT_32) ? "" : "32"); @@ -1885,7 +1730,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compile sljit_verbose_param(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1896,15 +1741,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_c sljit_s32 src3, sljit_sw src3w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_SHL || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_LSHR - || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_MSHL || SLJIT_CHECK_OPCODE(op, 0) == SLJIT_MLSHR); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR + || GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR); CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src1_reg)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg)); FUNCTION_CHECK_SRC(src3, src3w); CHECK_ARGUMENT(dst_reg != src2_reg); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32", @@ -1919,7 +1764,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_c sljit_verbose_param(compiler, src3, src3w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1936,14 +1781,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compi } else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) { CHECK_ARGUMENT(src & SLJIT_MEM); } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1956,14 +1801,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_dst(struct sljit_compi if (op == SLJIT_FAST_ENTER) compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -1975,19 +1820,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 t if (type == SLJIT_GP_REGISTER) { CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS) || (reg >= SLJIT_TMP_REGISTER_BASE && reg < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS))); - } -#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) - else if (((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6))) { - CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_VECTOR_REGISTERS) - || (reg >= SLJIT_TMP_VREGISTER_BASE && reg < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS))); - } -#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */ - else { - CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6) || (type & (3 << 12)) || (type & (4 << 12)) || (type & (5 << 12)) || (type & (6 << 12)))); + } else { + CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6))); CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS) || (reg >= SLJIT_TMP_FREGISTER_BASE && reg < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))); } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif CHECK_RETURN_OK; } @@ -1996,7 +1834,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) sljit_u32 i; -#endif /* SLJIT_VERBOSE */ +#endif SLJIT_UNUSED_ARG(compiler); @@ -2010,12 +1848,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co || (size == 4 && (((sljit_sw)instruction) & 0x3) == 0)); #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) CHECK_ARGUMENT(size == 2 || size == 4 || size == 6); -#else /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_CONFIG_S390X */ +#else CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0); -#endif /* SLJIT_CONFIG_X86 */ +#endif compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " op_custom"); @@ -2023,7 +1861,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2038,11 +1876,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MOV_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ABS_F64); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_FCHECK(src, srcw, op & SLJIT_32); FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) @@ -2057,7 +1895,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile sljit_verbose_fparam(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2067,7 +1905,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -2076,13 +1914,13 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_CMP_F64); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64); CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK) || (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL)); FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); @@ -2095,7 +1933,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2113,7 +1951,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_FCHECK(src, srcw, op & SLJIT_32); FUNCTION_CHECK_DST(dst, dstw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], @@ -2124,7 +1962,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str sljit_verbose_fparam(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2142,7 +1980,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(stru CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_CHECK_SRC(src, srcw); FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from.%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], @@ -2153,7 +1991,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(stru sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2169,12 +2007,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_DIV_F64); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); @@ -2185,7 +2023,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2196,11 +2034,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compil { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) == SLJIT_COPYSIGN_F64); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_COPYSIGN_F64); FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, op & SLJIT_32)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s ", fop2r_names[GET_OPCODE(op) - SLJIT_FOP2R_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); @@ -2211,7 +2049,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compil sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2228,14 +2066,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset32(struct sljit_compi #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 1)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fset32 "); sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", %f\n", value); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2252,14 +2090,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset64(struct sljit_compi #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fset64 "); sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", %f\n", value); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2268,7 +2106,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compil { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_COPY_TO_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_COPY_FROM_F64); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_COPY_TO_F64 && GET_OPCODE(op) <= SLJIT_COPY_FROM_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32)); @@ -2297,7 +2135,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compil break; } #endif /* SLJIT_64BIT_ARCHITECTURE */ -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " copy%s_%s_f%s ", (op & SLJIT_32) ? "32" : "", @@ -2317,7 +2155,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compil fprintf(compiler->verbose, "\n"); } } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2332,12 +2170,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, "label:\n"); -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2347,9 +2185,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil #define CHECK_UNORDERED(type, last_flags) \ ((((type) & 0xfe) == SLJIT_ORDERED) && \ ((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL) -#else /* !SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM */ +#else #define CHECK_UNORDERED(type, last_flags) 0 -#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM */ +#endif #endif /* SLJIT_ARGUMENT_CHECKS */ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) @@ -2373,12 +2211,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(type, compiler->last_flags)); } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) fprintf(compiler->verbose, " jump%s %s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2399,7 +2237,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compile CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG); } } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s ret[%s", jump_names[type & 0xff], @@ -2419,7 +2257,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compile } fprintf(compiler->verbose, "]\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2433,7 +2271,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " cmp%s%s %s, ", (type & SLJIT_32) ? "32" : "", @@ -2443,7 +2281,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler sljit_verbose_param(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2458,7 +2296,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile FUNCTION_FCHECK(src1, src1w, type & SLJIT_32); FUNCTION_FCHECK(src2, src2w, type & SLJIT_32); compiler->last_flags = 0; -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fcmp%s%s %s, ", (type & SLJIT_32) ? ".f32" : ".f64", @@ -2468,7 +2306,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile sljit_verbose_fparam(compiler, src2, src2w); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2483,14 +2321,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compil #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL); FUNCTION_CHECK_SRC(src, srcw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " ijump.%s ", jump_names[type]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2513,7 +2351,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compil CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG); } } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " i%s%s ret[%s", jump_names[type & 0xff], @@ -2534,7 +2372,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compil sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2545,7 +2383,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32 - || (SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_AND && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_XOR)); + || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)); if (type <= SLJIT_NOT_ZERO) @@ -2558,7 +2396,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com if (GET_OPCODE(op) >= SLJIT_ADD) compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " flags.%s%s%s ", @@ -2568,7 +2406,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", %s\n", jump_names[type]); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2595,7 +2433,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compi } else CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(cond, compiler->last_flags)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " select%s %s, ", @@ -2608,7 +2446,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compi sljit_verbose_reg(compiler, src2_reg); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2635,7 +2473,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_comp } else CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(cond, compiler->last_flags)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " fselect%s %s, ", @@ -2648,7 +2486,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_comp sljit_verbose_freg(compiler, src2_freg); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2702,7 +2540,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler } FUNCTION_CHECK_SRC_MEM(mem, memw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if ((type & 0xff) == SLJIT_MOV32) @@ -2734,7 +2572,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2753,7 +2591,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_c CHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg); FUNCTION_CHECK_SRC_MEM(mem, memw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_MEM_SUPP) @@ -2779,7 +2617,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_c sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2803,7 +2641,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); FUNCTION_CHECK_SRC_MEM(mem, memw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s.%s", @@ -2823,7 +2661,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -2837,7 +2675,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0); FUNCTION_CHECK_SRC_MEM(mem, memw); CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_MEM_SUPP) @@ -2857,12 +2695,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ sljit_verbose_param(compiler, mem, memw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2871,14 +2709,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_com CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); - FUNCTION_VCHECK(srcdst, srcdstw, type); -#endif /* SLJIT_ARGUMENT_CHECKS */ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_FCHECK(srcdst, srcdstw, 0); +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, vreg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, freg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_mem: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2894,17 +2732,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_com else fprintf(compiler->verbose, ".al%d ", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type))); - sljit_verbose_vreg(compiler, vreg); + sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", "); - sljit_verbose_vparam(compiler, srcdst, srcdstw); + sljit_verbose_fparam(compiler, srcdst, srcdstw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2912,7 +2750,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) { @@ -2923,12 +2761,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj } else if (src != SLJIT_IMM) { FUNCTION_CHECK_DST(src, srcw); } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, vreg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_dup: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2938,7 +2776,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_vreg(compiler, vreg); + sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", "); if (type & SLJIT_SIMD_FLOAT) sljit_verbose_fparam(compiler, src, srcw); @@ -2946,12 +2784,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -2963,7 +2801,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); CHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); CHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); if (type & SLJIT_SIMD_FLOAT) { @@ -2971,12 +2809,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji } else if ((type & SLJIT_SIMD_STORE) || srcdst != SLJIT_IMM) { FUNCTION_CHECK_DST(srcdst, srcdstw); } -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, vreg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, freg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_move_lane: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -2990,7 +2828,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_vreg(compiler, vreg); + sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, "[%d], ", lane_index); if (type & SLJIT_SIMD_FLOAT) sljit_verbose_fparam(compiler, srcdst, srcdstw); @@ -2998,12 +2836,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji sljit_verbose_param(compiler, srcdst, srcdstw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -3011,15 +2849,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struc CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src, type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src, 0)); CHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, vreg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_lane_replicate: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -3029,17 +2867,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struc (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_vreg(compiler, vreg); + sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", "); - sljit_verbose_vreg(compiler, src); + sljit_verbose_freg(compiler, src); fprintf(compiler->verbose, "[%d]\n", src_lane_index); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -3049,14 +2887,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_ CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); - FUNCTION_VCHECK(src, srcw, type); -#endif /* SLJIT_ARGUMENT_CHECKS */ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, vreg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_extend: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -3069,17 +2907,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_ (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_vreg(compiler, vreg); + sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", "); - sljit_verbose_vparam(compiler, src, srcw); + sljit_verbose_fparam(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -3087,14 +2925,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_co CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); FUNCTION_CHECK_DST(dst, dstw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, vreg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, freg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_sign: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } @@ -3105,56 +2943,50 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_co (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - sljit_verbose_vreg(compiler, vreg); + sljit_verbose_freg(compiler, freg); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); - CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK2(0)) <= SLJIT_SIMD_OP2_SHUFFLE); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK(0)) <= SLJIT_SIMD_OP2_XOR); CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); - CHECK_ARGUMENT(SLJIT_SIMD_GET_OPCODE(type) != SLJIT_SIMD_OP2_SHUFFLE || (SLJIT_SIMD_GET_ELEM_SIZE(type) == 0 && !(type & SLJIT_SIMD_FLOAT))); - CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (src2 & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(dst_vreg, type)); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src1_vreg, type)); - FUNCTION_VCHECK(src2, src2w, type); -#endif /* SLJIT_ARGUMENT_CHECKS */ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src1_freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, 0)); +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (type & SLJIT_SIMD_TEST) CHECK_RETURN_OK; - if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_vreg, src1_vreg, src2, src2w) == SLJIT_ERR_UNSUPPORTED) { + if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_freg, src1_freg, src2_freg) == SLJIT_ERR_UNSUPPORTED) { fprintf(compiler->verbose, " # simd_op2: unsupported form, no instructions are emitted\n"); CHECK_RETURN_OK; } - fprintf(compiler->verbose, " simd_%s.%d.%s%d", + fprintf(compiler->verbose, " simd_%s.%d.%s%d ", simd_op2_names[SLJIT_SIMD_GET_OPCODE(type) - 1], (8 << SLJIT_SIMD_GET_REG_SIZE(type)), (type & SLJIT_SIMD_FLOAT) ? "f" : "", (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); - if ((type & 0x3f000000) != SLJIT_SIMD_MEM_UNALIGNED) - fprintf(compiler->verbose, ".al%d", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type))); - - fprintf(compiler->verbose, " "); - sljit_verbose_vreg(compiler, dst_vreg); + sljit_verbose_freg(compiler, dst_freg); fprintf(compiler->verbose, ", "); - sljit_verbose_vreg(compiler, src1_vreg); + sljit_verbose_freg(compiler, src1_freg); fprintf(compiler->verbose, ", "); - sljit_verbose_vparam(compiler, src2, src2w); + sljit_verbose_freg(compiler, src2_freg); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -3165,14 +2997,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " local_base "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -3182,14 +3014,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " const "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -3197,14 +3029,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mov_addr(struct sljit_com { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); -#endif /* SLJIT_ARGUMENT_CHECKS */ +#endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " mov_addr "); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, "\n"); } -#endif /* SLJIT_VERBOSE */ +#endif CHECK_RETURN_OK; } @@ -3282,23 +3114,23 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji #define SLJIT_CPUINFO_PART1 " 32bit (" #elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) #define SLJIT_CPUINFO_PART1 " 64bit (" -#else /* !SLJIT_32BIT_ARCHITECTURE && !SLJIT_64BIT_ARCHITECTURE */ +#else #error "Internal error: CPU type info missing" -#endif /* SLJIT_32BIT_ARCHITECTURE */ +#endif #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) #define SLJIT_CPUINFO_PART2 "little endian + " #elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) #define SLJIT_CPUINFO_PART2 "big endian + " -#else /* !SLJIT_LITTLE_ENDIAN && !SLJIT_BIG_ENDIAN */ +#else #error "Internal error: CPU type info missing" -#endif /* SLJIT_LITTLE_ENDIAN */ +#endif #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) #define SLJIT_CPUINFO_PART3 "unaligned)" -#else /* !SLJIT_UNALIGNED */ +#else #define SLJIT_CPUINFO_PART3 "aligned)" -#endif /* SLJIT_UNALIGNED */ +#endif #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 @@ -3322,7 +3154,7 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji # include "sljitNativeS390X.c" #elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) # include "sljitNativeLOONGARCH_64.c" -#endif /* SLJIT_CONFIG_X86 */ +#endif #include "sljitSerialize.c" @@ -3332,10 +3164,10 @@ static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *comp /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; -#else /* !SLJIT_64BIT_ARCHITECTURE */ +#else if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; -#endif /* SLJIT_64BIT_ARCHITECTURE */ +#endif SLJIT_SKIP_CHECKS(compiler); return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw); @@ -3417,7 +3249,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler if (src2 == SLJIT_IMM && !src2w) return emit_cmp_to0(compiler, type, src1, src1w); } -#endif /* SLJIT_CONFIG_ARM_64 */ +#endif if (SLJIT_UNLIKELY(src1 == SLJIT_IMM && src2 != SLJIT_IMM)) { /* Immediate is preferred as second argument by most architectures. */ @@ -3557,18 +3389,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ && !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ - && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(vreg); + SLJIT_UNUSED_ARG(freg); SLJIT_UNUSED_ARG(srcdst); SLJIT_UNUSED_ARG(srcdstw); @@ -3576,14 +3407,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(vreg); + SLJIT_UNUSED_ARG(freg); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); @@ -3591,14 +3422,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(vreg); + SLJIT_UNUSED_ARG(freg); SLJIT_UNUSED_ARG(lane_index); SLJIT_UNUSED_ARG(srcdst); SLJIT_UNUSED_ARG(srcdstw); @@ -3607,14 +3438,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(vreg); + SLJIT_UNUSED_ARG(freg); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(src_lane_index); @@ -3622,14 +3453,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(vreg); + SLJIT_UNUSED_ARG(freg); SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); @@ -3637,14 +3468,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(vreg); + SLJIT_UNUSED_ARG(freg); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); @@ -3652,16 +3483,56 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(dst_vreg); - SLJIT_UNUSED_ARG(src1_vreg); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); + SLJIT_UNUSED_ARG(dst_freg); + SLJIT_UNUSED_ARG(src1_freg); + SLJIT_UNUSED_ARG(src2_freg); + + return SLJIT_ERR_UNSUPPORTED; +} + +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM */ + +#if !(defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86) \ + && !(defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM) \ + && !(defined(SLJIT_CONFIG_S390X) && SLJIT_CONFIG_S390X) \ + && !(defined(SLJIT_CONFIG_LOONGARCH) && SLJIT_CONFIG_LOONGARCH) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst_reg); + SLJIT_UNUSED_ARG(mem_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(src_reg); + SLJIT_UNUSED_ARG(mem_reg); + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); return SLJIT_ERR_UNSUPPORTED; } diff --git a/ext/pcre/pcre2lib/sljit/sljitLir.h b/ext/pcre/pcre2lib/sljit/sljitLir.h index 60d34f154305..8b6fa69a0a29 100644 --- a/ext/pcre/pcre2lib/sljit/sljitLir.h +++ b/ext/pcre/pcre2lib/sljit/sljitLir.h @@ -87,7 +87,7 @@ of sljitConfigInternal.h */ #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ +#endif /* Version numbers. */ #define SLJIT_MAJOR_VERSION 0 @@ -251,7 +251,7 @@ extern "C" { #define SLJIT_FS7 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 7) #define SLJIT_FS8 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 8) #define SLJIT_FS9 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 9) -/* All FS registers provided by the architecture can be accessed by SLJIT_FS(i) +/* All S registers provided by the architecture can be accessed by SLJIT_FS(i) The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */ #define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i)) @@ -262,52 +262,6 @@ extern "C" { #define SLJIT_RETURN_FREG SLJIT_FR0 -/* --------------------------------------------------------------------- */ -/* Vector registers */ -/* --------------------------------------------------------------------- */ - -/* Vector registers are storage areas, which are used for Single Instruction - Multiple Data (SIMD) computations. The VR and VS register sets overlap - in the same way as R and S register sets. See above. - - The storage space of vector registers often overlap with floating point - registers. In this case setting the value of SLJIT_VR(i) destroys the - value of SLJIT_FR(i) and vice versa. See SLJIT_SEPARATE_VECTOR_REGISTERS - macro. */ - -/* Vector scratch registers. */ -#define SLJIT_VR0 1 -#define SLJIT_VR1 2 -#define SLJIT_VR2 3 -#define SLJIT_VR3 4 -#define SLJIT_VR4 5 -#define SLJIT_VR5 6 -#define SLJIT_VR6 7 -#define SLJIT_VR7 8 -#define SLJIT_VR8 9 -#define SLJIT_VR9 10 -/* All VR registers provided by the architecture can be accessed by SLJIT_VR(i) - The i parameter must be >= 0 and < SLJIT_NUMBER_OF_VECTOR_REGISTERS. */ -#define SLJIT_VR(i) (1 + (i)) - -/* Vector saved registers. */ -#define SLJIT_VS0 (SLJIT_NUMBER_OF_VECTOR_REGISTERS) -#define SLJIT_VS1 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 1) -#define SLJIT_VS2 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 2) -#define SLJIT_VS3 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 3) -#define SLJIT_VS4 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 4) -#define SLJIT_VS5 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 5) -#define SLJIT_VS6 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 6) -#define SLJIT_VS7 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 7) -#define SLJIT_VS8 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 8) -#define SLJIT_VS9 (SLJIT_NUMBER_OF_VECTOR_REGISTERS - 9) -/* All VS registers provided by the architecture can be accessed by SLJIT_VS(i) - The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS. */ -#define SLJIT_VS(i) (SLJIT_NUMBER_OF_VECTOR_REGISTERS - (i)) - -/* Vector registers >= SLJIT_FIRST_SAVED_VECTOR_REG are saved registers. */ -#define SLJIT_FIRST_SAVED_VECTOR_REG (SLJIT_VS0 - SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS + 1) - /* --------------------------------------------------------------------- */ /* Argument type definitions */ /* --------------------------------------------------------------------- */ @@ -529,15 +483,6 @@ struct sljit_compiler { sljit_s32 fscratches; /* Available float saved registers. */ sljit_s32 fsaveds; -#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ - || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ - || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - /* Available vector scratch registers. */ - sljit_s32 vscratches; - /* Available vector saved registers. */ - sljit_s32 vsaveds; -#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG || SLJIT_VERBOSE */ /* Local stack size. */ sljit_s32 local_size; /* Maximum code size. */ @@ -618,7 +563,6 @@ struct sljit_compiler { FILE* verbose; #endif /* SLJIT_VERBOSE */ - /* Note: SLJIT_DEBUG enables SLJIT_ARGUMENT_CHECKS. */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Flags specified by the last arithmetic instruction. @@ -633,13 +577,6 @@ struct sljit_compiler { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) - /* Available float scratch registers. */ - sljit_s32 real_fscratches; - /* Available float saved registers. */ - sljit_s32 real_fsaveds; -#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */ - /* Trust arguments when an API function is called. Used internally for calling API functions. */ sljit_s32 skip_checks; @@ -697,7 +634,7 @@ static SLJIT_INLINE void* sljit_compiler_get_user_data(struct sljit_compiler *co #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); -#endif /* SLJIT_VERBOSE */ +#endif /* Option bits for sljit_generate_code. */ @@ -743,9 +680,7 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler support while others (e.g. move with update) are emulated if not available. However, even when a feature is emulated, specialized code paths may be faster than the emulation. Some limitations are emulated as well so their - general case is supported but it has extra performance costs. - - Note: sljitConfigInternal.h also provides several feature detection macros. */ + general case is supported but it has extra performance costs. */ /* [Not emulated] Floating-point support is available. */ #define SLJIT_HAS_FPU 0 @@ -780,22 +715,20 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler a simd operation represents the same 128 bit register, and both SLJIT_FR0 and SLJIT_FR1 are overwritten. */ #define SLJIT_SIMD_REGS_ARE_PAIRS 13 -/* [Not emulated] Atomic support is available. */ -#define SLJIT_HAS_ATOMIC 14 -/* [Not emulated] Memory barrier support is available. */ -#define SLJIT_HAS_MEMORY_BARRIER 15 +/* [Not emulated] Atomic support is available (fine-grained). */ +#define SLJIT_HAS_ATOMIC 14 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* [Not emulated] AVX support is available on x86. */ #define SLJIT_HAS_AVX 100 /* [Not emulated] AVX2 support is available on x86. */ #define SLJIT_HAS_AVX2 101 -#endif /* SLJIT_CONFIG_X86 */ +#endif #if (defined SLJIT_CONFIG_LOONGARCH) /* [Not emulated] LASX support is available on LoongArch */ #define SLJIT_HAS_LASX 201 -#endif /* SLJIT_CONFIG_LOONGARCH */ +#endif SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type); @@ -816,65 +749,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); with an error code. */ /* - The executable code is a callable function from the viewpoint - of the C language. Function calls must conform with the ABI - (Application Binary Interface) of the target platform, which - specify the purpose of machine registers and stack handling - among other things. The sljit_emit_enter function emits the - necessary instructions for setting up an entry point for the - executable code. This is often called as function prologue. - - The "options" argument can be used to pass configuration options - to the sljit compiler which affects the generated code, until - another sljit_emit_enter or sljit_set_context is called. The + The executable code is a function from the viewpoint of the C + language. The function calls must conform to the ABI (Application + Binary Interface) of the platform, which specify the purpose of + machine registers and stack handling among other things. The + sljit_emit_enter function emits the necessary instructions for + setting up a new context for the executable code. This is often + called as function prologue. Furthermore the options argument + can be used to pass configuration options to the compiler. The available options are listed before sljit_emit_enter. The function argument list is specified by the SLJIT_ARGSx (SLJIT_ARGS0 .. SLJIT_ARGS4) macros. Currently maximum four arguments are supported. See the description of SLJIT_ARGSx - macros about argument passing. - - The register set used by the function must be declared as well. - The number of scratch and saved registers available to the - function must be passed to sljit_emit_enter. Only R registers - between R0 and "scratches" argument can be used later. E.g. - if "scratches" is set to two, the scratch register set will - be limited to SLJIT_R0 and SLJIT_R1. The S registers are - declared in a similar manner, but their count is specified - by "saveds" argument. The floating point scratch and saved - registers can be set by using "scratches" and "saveds" argument - as well, but their value must be passed to the SLJIT_ENTER_FLOAT - macro, see below. - - The sljit_emit_enter is also capable of allocating a stack - space for local data. The "local_size" argument contains the - size in bytes of this local area, and it can be accessed using - SLJIT_MEM1(SLJIT_SP). The memory area between SLJIT_SP (inclusive) - and SLJIT_SP + local_size (exclusive) can be modified freely - until the function returns. The alocated stack space is an - uninitialized memory area. - - Floating point scratch and saved registers must be specified - by the SLJIT_ENTER_FLOAT macro, which result value should be - combined with scratches / saveds argument. - - Examples: - To use three scratch and four floating point scratch - registers, the "scratches" argument must be set to: - 3 | SLJIT_ENTER_FLOAT(4) - - To use six saved and five floating point saved - registers, the "saveds" argument must be set to: - 6 | SLJIT_ENTER_FLOAT(5) + macros about argument passing. Furthermore the register set + used by the function must be declared as well. The number of + scratch and saved registers available to the function must + be passed to sljit_emit_enter. Only R registers between R0 + and "scratches" argument can be used later. E.g. if "scratches" + is set to two, the scratch register set will be limited to + SLJIT_R0 and SLJIT_R1. The S registers and the floating point + registers ("fscratches" and "fsaveds") are specified in a + similar manner. The sljit_emit_enter is also capable of + allocating a stack space for local data. The "local_size" + argument contains the size in bytes of this local area, and + it can be accessed using SLJIT_MEM1(SLJIT_SP). The memory + area between SLJIT_SP (inclusive) and SLJIT_SP + local_size + (exclusive) can be modified freely until the function returns. + The stack space is not initialized to zero. Note: the following conditions must met: 0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS 0 <= saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS - - 0 <= float scratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS - 0 <= float saveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS - float scratches + float saveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS + 0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS + 0 <= fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS Note: the compiler can use saved registers as scratch registers, but the opposite is not supported @@ -883,8 +793,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); overwrites the previous context. */ -/* The following options are available for sljit_emit_enter. */ - /* Saved registers between SLJIT_S0 and SLJIT_S(n - 1) (inclusive) are not saved / restored on function enter / return. Instead, these registers can be used to pass / return data (such as @@ -900,27 +808,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); and all arguments must be stored in scratch registers. */ #define SLJIT_ENTER_REG_ARG 0x00000004 +/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ +#define SLJIT_MAX_LOCAL_SIZE 1048576 + #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* Use VEX prefix for all SIMD operations on x86. */ #define SLJIT_ENTER_USE_VEX 0x00010000 #endif /* !SLJIT_CONFIG_X86 */ -/* Macros for other sljit_emit_enter arguments. */ - -/* Floating point scratch and saved registers can be - specified by SLJIT_ENTER_FLOAT. */ -#define SLJIT_ENTER_FLOAT(regs) ((regs) << 8) - -/* Vector scratch and saved registers can be specified - by SLJIT_ENTER_VECTOR. */ -#define SLJIT_ENTER_VECTOR(regs) ((regs) << 16) - -/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ -#define SLJIT_MAX_LOCAL_SIZE 1048576 - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size); + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); /* The SLJIT compiler has a current context (which contains the local stack space size, number of used registers, etc.) which is initialized @@ -936,8 +834,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi the previous context. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size); + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); /* Return to the caller function. The sljit_emit_return_void function does not return with any value. The sljit_emit_return function returns @@ -1194,21 +1092,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c the behaviour is undefined. */ #define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7) #define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_32) -/* Flags: - (does not modify flags) - May return with SLJIT_ERR_UNSUPPORTED if SLJIT_HAS_MEMORY_BARRIER - feature is not supported (calling sljit_has_cpu_feature() with - this feature option returns with 0). */ -#define SLJIT_MEMORY_BARRIER (SLJIT_OP0_BASE + 8) /* Flags: - (does not modify flags) ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64 when Intel Control-flow Enforcement Technology (CET) is enabled. No instructions are emitted for other architectures. */ -#define SLJIT_ENDBR (SLJIT_OP0_BASE + 9) +#define SLJIT_ENDBR (SLJIT_OP0_BASE + 8) /* Flags: - (may destroy flags) Skip stack frames before return when Intel Control-flow Enforcement Technology (CET) is enabled. No instructions are emitted for other architectures. */ -#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 10) +#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 9) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op); @@ -1997,21 +1890,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler /* The following options are used by several simd operations. */ -/* Load data into a vector register, this is the default */ +/* Load data into a simd register, this is the default */ #define SLJIT_SIMD_LOAD 0x000000 -/* Store data from a vector register */ +/* Store data from a simd register */ #define SLJIT_SIMD_STORE 0x000001 -/* The vector register contains floating point values */ +/* The simd register contains floating point values */ #define SLJIT_SIMD_FLOAT 0x000400 /* Tests whether the operation is available */ #define SLJIT_SIMD_TEST 0x000800 -/* Move data to/from a 64 bit (8 byte) long vector register */ +/* Move data to/from a 64 bit (8 byte) long SIMD register */ #define SLJIT_SIMD_REG_64 (3 << 12) -/* Move data to/from a 128 bit (16 byte) long vector register */ +/* Move data to/from a 128 bit (16 byte) long SIMD register */ #define SLJIT_SIMD_REG_128 (4 << 12) -/* Move data to/from a 256 bit (32 byte) long vector register */ +/* Move data to/from a 256 bit (32 byte) long SIMD register */ #define SLJIT_SIMD_REG_256 (5 << 12) -/* Move data to/from a 512 bit (64 byte) long vector register */ +/* Move data to/from a 512 bit (64 byte) long SIMD register */ #define SLJIT_SIMD_REG_512 (6 << 12) /* Element size is 8 bit long (this is the default), usually cannot be combined with SLJIT_SIMD_FLOAT */ #define SLJIT_SIMD_ELEM_8 (0 << 18) @@ -2026,8 +1919,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler /* Element size is 256 bit long */ #define SLJIT_SIMD_ELEM_256 (5 << 18) -/* The following options are used by sljit_emit_simd_mov() - and sljit_emit_simd_op2(). */ +/* The following options are used by sljit_emit_simd_mov(). */ /* Memory address is unaligned (this is the default) */ #define SLJIT_SIMD_MEM_UNALIGNED (0 << 24) @@ -2044,7 +1936,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler /* Memory address is 512 bit aligned */ #define SLJIT_SIMD_MEM_ALIGNED_512 (6 << 24) -/* Moves data between a vector register and memory. +/* Moves data between a simd register and memory. If the operation is not supported, it returns with SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, @@ -2052,21 +1944,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler type must be a combination of SLJIT_SIMD_* and SLJIT_SIMD_MEM_* options - vreg is the source or destination vector register + freg is the source or destination simd register of the operation - srcdst must be a memory operand or a vector register + srcdst must be a memory operand or a simd register Note: The alignment and element size must be - less or equal than vector register size. + less or equal than simd register size. Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw); -/* Replicates a scalar value to all lanes of a vector +/* Replicates a scalar value to all lanes of a simd register. If the operation is not supported, it returns with @@ -2075,7 +1967,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co type must be a combination of SLJIT_SIMD_* options except SLJIT_SIMD_STORE. - vreg is the destination vector register of the operation + freg is the destination simd register of the operation src is the value which is replicated Note: @@ -2085,7 +1977,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw); /* The following options are used by sljit_emit_simd_lane_mov(). */ @@ -2095,7 +1987,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil /* Sign extend the integer value stored from the lane. */ #define SLJIT_SIMD_LANE_SIGNED 0x000004 -/* Moves data between a vector register lane and a register or +/* Moves data between a simd register lane and a register or memory. If the srcdst argument is a register, it must be a floating point register when SLJIT_SIMD_FLOAT is specified, or a general purpose register otherwise. @@ -2111,7 +2003,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil is set and SLJIT_SIMD_FLOAT is not set SLJIT_SIMD_LANE_ZERO - when SLJIT_SIMD_LOAD is specified - vreg is the source or destination vector register + freg is the source or destination simd register of the operation lane_index is the index of the lane srcdst is the destination operand for loads, and @@ -2123,11 +2015,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw); /* Replicates a scalar value from a lane to all lanes - of a vector register. + of a simd register. If the operation is not supported, it returns with SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, @@ -2135,14 +2027,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile type must be a combination of SLJIT_SIMD_* options except SLJIT_SIMD_STORE. - vreg is the destination vector register of the operation - src is the vector register which lane is replicated + freg is the destination simd register of the operation + src is the simd register which lane is replicated src_lane_index is the lane index of the src register Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index); /* The following options are used by sljit_emit_simd_load_extend(). */ @@ -2156,7 +2048,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c /* Extend data to 64 bit */ #define SLJIT_SIMD_EXTEND_64 (3 << 24) -/* Extend elements and stores them in a vector register. +/* Extend elements and stores them in a simd register. The extension operation increases the size of the elements (e.g. from 16 bit to 64 bit). For integer values, the extension can be signed or unsigned. @@ -2167,15 +2059,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c type must be a combination of SLJIT_SIMD_*, and SLJIT_SIMD_EXTEND_* options except SLJIT_SIMD_STORE - vreg is the destination vector register of the operation - src must be a memory operand or a vector register. + freg is the destination simd register of the operation + src must be a memory operand or a simd register. In the latter case, the source elements are stored in the lower half of the register. Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw); /* Extract the highest bit (usually the sign bit) from @@ -2187,16 +2079,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler type must be a combination of SLJIT_SIMD_* and SLJIT_32 options except SLJIT_SIMD_LOAD - vreg is the source vector register of the operation + freg is the source simd register of the operation dst is the destination operand Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw); -/* The following operations are used by sljit_emit_simd_op2(). */ +/* The following options are used by sljit_emit_simd_op2(). */ /* Binary 'and' operation */ #define SLJIT_SIMD_OP2_AND 0x000001 @@ -2204,40 +2096,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c #define SLJIT_SIMD_OP2_OR 0x000002 /* Binary 'xor' operation */ #define SLJIT_SIMD_OP2_XOR 0x000003 -/* Shuffle bytes of src1 using the indicies in src2 */ -#define SLJIT_SIMD_OP2_SHUFFLE 0x000004 -/* Perform simd operations using vector registers. +/* Perform simd operations using simd registers. If the operation is not supported, it returns with SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, it does not emit any instructions. - type must be a combination of SLJIT_SIMD_*, SLJIT_SIMD_MEM_* - and SLJIT_SIMD_OP2_* options except SLJIT_SIMD_LOAD - and SLJIT_SIMD_STORE - dst_vreg is the destination register of the operation - src1_vreg is the first source register of the operation - src2 is the second source operand of the operation + type must be a combination of SLJIT_SIMD_* and SLJIT_SIMD_OP2_ + options except SLJIT_SIMD_LOAD and SLJIT_SIMD_STORE + dst_freg is the destination register of the operation + src1_freg is the first source register of the operation + src1_freg is the second source register of the operation Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w); - -/* The following operations are used by sljit_emit_atomic_load() and - sljit_emit_atomic_store() operations. */ - -/* Tests whether the atomic operation is available (does not generate - any instructions). When a load from is allowed, its corresponding - store form is allowed and vice versa. */ -#define SLJIT_ATOMIC_TEST 0x10000 -/* The compiler must generate compare and swap instruction. - When this bit is set, calling sljit_emit_atomic_load() is optional. */ -#define SLJIT_ATOMIC_USE_CAS 0x20000 -/* The compiler must generate load-acquire and store-release instructions. - When this bit is set, the temp_reg for sljit_emit_atomic_store is not used. */ -#define SLJIT_ATOMIC_USE_LS 0x40000 + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg); /* The sljit_emit_atomic_load and sljit_emit_atomic_store operation pair can perform an atomic read-modify-write operation. First, an unsigned @@ -2246,17 +2121,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co sljit_emit_atomic_store. A thread can only perform a single atomic operation at a time. + Note: atomic operations are experimental, and not implemented + for all cpus. + The following conditions must be satisfied, or the operation is undefined: - the address provided in mem_reg must be divisible by the size of the value (only naturally aligned updates are supported) - - no memory operations are allowed between the load and store operations + - no memory writes are allowed between the load and store operations + regardless of its target address (currently read operations are + allowed, but this might change in the future) - the memory operation (op) and the base address (stored in mem_reg) passed to the load/store operations must be the same (the mem_reg can be a different register, only its value must be the same) - - a store must always follow a load for the same transaction. + - an store must always follow a load for the same transaction. - op must be between SLJIT_MOV and SLJIT_MOV_P + op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all + signed loads such as SLJIT_MOV32_S16 dst_reg is the register where the data will be loaded into mem_reg is the base address of the memory load (it cannot be SLJIT_SP or a virtual register on x86-32) @@ -2270,19 +2151,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler allows performing an atomic read-modify-write operation. See the description of sljit_emit_atomic_load. - op must be between SLJIT_MOV and SLJIT_MOV_P + op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all signed + loads such as SLJIT_MOV32_S16 src_reg is the register which value is stored into the memory mem_reg is the base address of the memory store (it cannot be SLJIT_SP or a virtual register on x86-32) - temp_reg is a scratch register, which must be initialized with - the value loaded into the dst_reg during the corresponding - sljit_emit_atomic_load operation, or the operation is undefined. - The temp_reg register preserves its value, if the memory store - is successful. Otherwise, its value is undefined. - - Flags: ATOMIC_STORED - if ATOMIC_STORED flag is set, it represents that the memory - is updated with a new value. Otherwise the memory is unchanged. */ + temp_reg is a not preserved scratch register, which must be + initialized with the value loaded into the dst_reg during the + corresponding sljit_emit_atomic_load operation, or the operation + is undefined + + Flags: ATOMIC_STORED is set if the operation is successful, + otherwise the memory remains unchanged. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src_reg, sljit_s32 mem_reg, @@ -2577,10 +2457,10 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct it is sometimes desired to free all unused memory regions, e.g. before the application terminates. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); -#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ +#endif #ifdef __cplusplus } /* extern "C" */ -#endif /* __cplusplus */ +#endif #endif /* SLJIT_LIR_H_ */ diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c index 327dc824efc6..a253c06f0100 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c @@ -114,7 +114,6 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define CLZ 0xe16f0f10 #define CMN 0xe1600000 #define CMP 0xe1400000 -#define DMB_SY 0xf57ff05f #define EOR 0xe0200000 #define LDR 0xe5100000 #define LDR_POST 0xe4100000 @@ -181,7 +180,6 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define VST1_s 0xf4800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 -#define VTBL 0xf3b00800 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Arm v7 specific instructions. */ @@ -200,28 +198,11 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) fr -= SLJIT_F64_SECOND(0); - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches)) - || (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0) + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } -static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type) -{ - sljit_s32 vr_low = vr; - - if (compiler->scratches == -1) - return 0; - - if (SLJIT_SIMD_GET_REG_SIZE(type) == 4) { - vr += (vr & 0x1); - vr_low = vr - 1; - } - - return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches)) - || (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0) - || (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)); -} - #endif /* SLJIT_ARGUMENT_CHECKS */ #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) @@ -383,7 +364,7 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ while (last_pc_patch < code_ptr) { /* Data transfer instruction with Rn == r15. */ - if ((*last_pc_patch & 0x0e4f0000) == 0x040f0000) { + if ((*last_pc_patch & 0x0e0f0000) == 0x040f0000) { diff = (sljit_uw)(const_pool - last_pc_patch); ind = (*last_pc_patch) & 0xfff; @@ -495,14 +476,6 @@ static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s3 static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code, sljit_sw executable_offset) { sljit_sw diff; - sljit_uw target_addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; - sljit_uw orig_addr = jump->addr; - SLJIT_UNUSED_ARG(executable_offset); - -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - jump->addr = jump_addr; -#endif if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; @@ -513,17 +486,12 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw #endif /* SLJIT_CONFIG_ARM_V6 */ if (jump->flags & JUMP_ADDR) - target_addr = jump->u.target; + diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset); else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - - if (jump->u.label->size > orig_addr) - jump_addr = (sljit_uw)(code + orig_addr); + diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)); } - diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr + 8, executable_offset); - /* Branch to Thumb code has not been optimized yet. */ if (diff & 0x3) return 0; @@ -535,9 +503,12 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw jump->flags |= PATCH_B; return 1; } - } else if (diff <= 0x01ffffff && diff >= -0x02000000) { - *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); - jump->flags |= PATCH_B; + } + else { + if (diff <= 0x01ffffff && diff >= -0x02000000) { + *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK); + jump->flags |= PATCH_B; + } } #else /* !SLJIT_CONFIG_ARM_V6 */ if (diff <= 0x01ffffff && diff >= -0x02000000) { @@ -743,21 +714,16 @@ static void set_const_value(sljit_uw addr, sljit_sw executable_offset, sljit_uw static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else { + else addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - if (jump->u.label->size > jump->addr) - jump_addr = (sljit_uw)(code + jump->addr); - } - /* The pc+8 offset is represented by the 2 * SSIZE_OF(ins) below. */ - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); if ((diff & 0x3) == 0 && diff <= (0x3fc + 2 * SSIZE_OF(ins)) && diff >= (-0x3fc + 2 * SSIZE_OF(ins))) { jump->flags |= PATCH_B; @@ -818,10 +784,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if (diff <= (0x01ffffff / SSIZE_OF(ins)) && diff >= (-0x02000000 / SSIZE_OF(ins))) total_size = 1 - 1; @@ -834,11 +796,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } - if (diff <= 0xff + 2 && diff >= -0xff + 2) total_size = 0; } @@ -960,6 +917,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump->addr = (sljit_uw)code_ptr; #else /* !SLJIT_CONFIG_ARM_V6 */ word_count += jump->flags >> JUMP_SIZE_SHIFT; + jump->addr = (sljit_uw)code_ptr; if (!detect_jump_type(jump, code_ptr, code, executable_offset)) { code_ptr[2] = code_ptr[0]; addr = ((code_ptr[0] & 0xf) << 12); @@ -1173,9 +1131,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - case SLJIT_HAS_MEMORY_BARRIER: -#endif /* SLJIT_CONFIG_ARM_V7 */ return 1; case SLJIT_HAS_CTZ: @@ -1270,11 +1225,9 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 sljit_s32 src2, sljit_sw src2w); SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_uw imm, offset; sljit_s32 i, tmp, size, word_arg_count; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); @@ -1287,15 +1240,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); imm = 0; + tmp = SLJIT_S0 - saveds; for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) imm |= (sljit_uw)1 << reg_map[i]; @@ -1442,21 +1391,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); /* Doubles are saved, so alignment is unaffected. */ @@ -2421,12 +2364,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); } return SLJIT_SUCCESS; - case SLJIT_MEMORY_BARRIER: -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - return push_inst(compiler, DMB_SY); -#else /* !SLJIT_CONFIG_ARM_V7 */ - return SLJIT_ERR_UNSUPPORTED; -#endif /* SLJIT_CONFIG_ARM_V7 */ case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2693,7 +2630,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) return freg_map[reg]; - if (type == SLJIT_SIMD_REG_128) + if (type != SLJIT_SIMD_REG_128) return freg_map[reg] & ~0x1; return -1; @@ -3168,9 +3105,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile if (type >= SLJIT_FAST_CALL) PTR_FAIL_IF(prepare_blx(compiler)); + jump->addr = compiler->size; PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(compiler, type), 0)); - jump->addr = compiler->size - 1; if (jump->flags & SLJIT_REWRITABLE_JUMP) compiler->patches++; @@ -3970,7 +3907,7 @@ static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) #define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3979,7 +3916,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3993,16 +3930,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (!(srcdst & SLJIT_MEM)) { if (reg_size == 4) srcdst = simd_get_quad_reg_index(srcdst); if (type & SLJIT_SIMD_STORE) - ins = VD(srcdst) | VN(vreg) | VM(vreg); + ins = VD(srcdst) | VN(freg) | VM(freg); else - ins = VD(vreg) | VN(srcdst) | VM(srcdst); + ins = VD(freg) | VN(srcdst) | VM(srcdst); if (reg_size == 4) ins |= (sljit_ins)1 << 6; @@ -4015,7 +3952,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (elem_size > 3) elem_size = 3; - ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD(vreg) + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD(freg) | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); SLJIT_ASSERT(reg_size >= alignment); @@ -4123,7 +4060,7 @@ static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4131,7 +4068,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins, imm; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4145,24 +4082,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (src == SLJIT_IMM && srcw == 0) - return push_inst(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD(vreg)); + return push_inst(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD(freg)); if (SLJIT_UNLIKELY(elem_size == 3)) { SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, vreg, src, srcw)); - src = vreg; - } else if (vreg != src) - FAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src))); + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); + src = freg; + } else if (freg != src) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); - if (vreg != src) - return push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src)); + if (freg != src) + return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); return SLJIT_SUCCESS; } @@ -4174,7 +4111,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 5; - return push_inst(compiler, VLD1_r | ins | VD(vreg) | RN(src) | 0xf); + return push_inst(compiler, VLD1_r | ins | VD(freg) | RN(src) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { @@ -4184,7 +4121,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst(compiler, VDUP_s | ins | VD(vreg) | (sljit_ins)freg_map[src]); + return push_inst(compiler, VDUP_s | ins | VD(freg) | (sljit_ins)freg_map[src]); } if (src == SLJIT_IMM) { @@ -4197,7 +4134,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) imm |= (sljit_ins)1 << 6; - return push_inst(compiler, VMOV_i | imm | VD(vreg)); + return push_inst(compiler, VMOV_i | imm | VD(freg)); } FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); @@ -4219,11 +4156,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 21; - return push_inst(compiler, VDUP | ins | VN(vreg) | RD(src)); + return push_inst(compiler, VDUP | ins | VN(freg) | RD(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4231,7 +4168,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -4245,7 +4182,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); @@ -4253,62 +4190,62 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { if (lane_index == 1) - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); - if (srcdst != vreg) - FAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(srcdst) | VM(srcdst))); + if (srcdst != freg) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(srcdst) | VM(srcdst))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - return push_inst(compiler, VMOV_i | VD(vreg)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VMOV_i | VD(freg)); } - if (srcdst == vreg || (elem_size == 3 && srcdst == (vreg + SLJIT_QUAD_OTHER_HALF(vreg)))) { - FAIL_IF(push_inst(compiler, VORR | ins | VD(TMP_FREG2) | VN(vreg) | VM(vreg))); + if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { + FAIL_IF(push_inst(compiler, VORR | ins | VD(TMP_FREG2) | VN(freg) | VM(freg))); srcdst = TMP_FREG2; srcdstw = 0; } } - FAIL_IF(push_inst(compiler, VMOV_i | ins | VD(vreg))); + FAIL_IF(push_inst(compiler, VMOV_i | ins | VD(freg))); } if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { lane_index -= (0x8 >> elem_size); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); } if (srcdst & SLJIT_MEM) { if (elem_size == 3) - return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, vreg, srcdst, srcdstw); + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); lane_index = lane_index << elem_size; ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); - return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD(vreg) | RN(srcdst) | 0xf); + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD(freg) | RN(srcdst) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3) { if (type & SLJIT_SIMD_STORE) - return push_inst(compiler, VORR | VD(srcdst) | VN(vreg) | VM(vreg)); - return push_inst(compiler, VMOV_F32 | SLJIT_32 | VD(vreg) | VM(srcdst)); + return push_inst(compiler, VORR | VD(srcdst) | VN(freg) | VM(freg)); + return push_inst(compiler, VMOV_F32 | SLJIT_32 | VD(freg) | VM(srcdst)); } if (type & SLJIT_SIMD_STORE) { - if (freg_ebit_map[vreg] == 0) { + if (freg_ebit_map[freg] == 0) { if (lane_index == 1) - vreg = SLJIT_F64_SECOND(vreg); + freg = SLJIT_F64_SECOND(freg); - return push_inst(compiler, VMOV_F32 | VD(srcdst) | VM(vreg)); + return push_inst(compiler, VMOV_F32 | VD(srcdst) | VM(freg)); } - FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN(vreg) | RD(TMP_REG1))); + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1))); return push_inst(compiler, VMOV | VN(srcdst) | RD(TMP_REG1)); } FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(srcdst) | RD(TMP_REG1))); - return push_inst(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN(vreg) | RD(TMP_REG1)); + return push_inst(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1)); } if (srcdst == SLJIT_IMM) { @@ -4336,11 +4273,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins |= (1 << 23); } - return push_inst(compiler, VMOV_s | ins | VN(vreg) | RD(srcdst)); + return push_inst(compiler, VMOV_s | ins | VN(freg) | RD(srcdst)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4348,7 +4285,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4360,7 +4297,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c return SLJIT_SUCCESS; if (reg_size == 4) { - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); src = simd_get_quad_reg_index(src); if (src_lane_index >= (0x8 >> elem_size)) { @@ -4370,13 +4307,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } if (elem_size == 3) { - if (vreg != src) - FAIL_IF(push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src))); + if (freg != src) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); - if (vreg != src) - return push_inst(compiler, VORR | VD(vreg) | VN(src) | VM(src)); + if (freg != src) + return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); return SLJIT_SUCCESS; } @@ -4385,11 +4322,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst(compiler, VDUP_s | ins | VD(vreg) | VM(src)); + return push_inst(compiler, VDUP_s | ins | VD(freg) | VM(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4398,7 +4335,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_s32 dst_reg; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4412,20 +4349,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (src & SLJIT_MEM) { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); if (reg_size == 4 && elem2_size - elem_size == 1) - FAIL_IF(push_inst(compiler, VLD1 | (0x7 << 8) | VD(vreg) | RN(src) | 0xf)); + FAIL_IF(push_inst(compiler, VLD1 | (0x7 << 8) | VD(freg) | RN(src) | 0xf)); else - FAIL_IF(push_inst(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD(vreg) | RN(src) | 0xf)); - src = vreg; + FAIL_IF(push_inst(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD(freg) | RN(src) | 0xf)); + src = freg; } else if (reg_size == 4) src = simd_get_quad_reg_index(src); if (!(type & SLJIT_SIMD_FLOAT)) { - dst_reg = (reg_size == 4) ? vreg : TMP_FREG2; + dst_reg = (reg_size == 4) ? freg : TMP_FREG2; do { FAIL_IF(push_inst(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 24)) @@ -4434,27 +4371,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } while (++elem_size < elem2_size); if (dst_reg == TMP_FREG2) - return push_inst(compiler, VORR | VD(vreg) | VN(TMP_FREG2) | VM(TMP_FREG2)); + return push_inst(compiler, VORR | VD(freg) | VN(TMP_FREG2) | VM(TMP_FREG2)); return SLJIT_SUCCESS; } /* No SIMD variant, must use VFP instead. */ SLJIT_ASSERT(reg_size == 4); - if (vreg == src) { - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src) | 0x20)); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - return push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src)); + if (freg == src) { + freg += SLJIT_QUAD_OTHER_HALF(freg); + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src)); } - FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - return push_inst(compiler, VCVT_F64_F32 | VD(vreg) | VM(src) | 0x20); + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src))); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4463,7 +4400,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4496,12 +4433,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } if (reg_size == 4) { - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); ins |= (sljit_ins)1 << 6; } SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); - FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG2) | VM(vreg))); + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG2) | VM(freg))); if (reg_size == 4 && elem_size > 0) FAIL_IF(push_inst(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD(TMP_FREG2) | VM(TMP_FREG2))); @@ -4531,16 +4468,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 alignment; - sljit_ins ins = 0, load_ins; + sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4548,9 +4483,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) return SLJIT_ERR_UNSUPPORTED; - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = VAND; @@ -4561,51 +4493,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = VEOR; break; - case SLJIT_SIMD_OP2_SHUFFLE: - ins = VTBL; - break; } - if (src2 & SLJIT_MEM) { - if (elem_size > 3) - elem_size = 3; - - load_ins = VLD1 | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); - alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); - - SLJIT_ASSERT(reg_size >= alignment); - - if (alignment == 3) - load_ins |= 0x10; - else if (alignment >= 4) - load_ins |= 0x20; - - FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); - FAIL_IF(push_inst(compiler, load_ins | VD(TMP_FREG2) | RN(src2) | ((sljit_ins)elem_size) << 6 | 0xf)); - src2 = TMP_FREG2; - } + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; if (reg_size == 4) { - dst_vreg = simd_get_quad_reg_index(dst_vreg); - src1_vreg = simd_get_quad_reg_index(src1_vreg); - src2 = simd_get_quad_reg_index(src2); - - if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) { - ins |= (sljit_ins)1 << 8; - - FAIL_IF(push_inst(compiler, ins | VD(dst_vreg != src1_vreg ? dst_vreg : TMP_FREG2) | VN(src1_vreg) | VM(src2))); - src2 += SLJIT_QUAD_OTHER_HALF(src2); - FAIL_IF(push_inst(compiler, ins | VD(dst_vreg + SLJIT_QUAD_OTHER_HALF(dst_vreg)) | VN(src1_vreg) | VM(src2))); - - if (dst_vreg == src1_vreg) - return push_inst(compiler, VORR | VD(dst_vreg) | VN(TMP_FREG2) | VM(TMP_FREG2)); - return SLJIT_SUCCESS; - } - + dst_freg = simd_get_quad_reg_index(dst_freg); + src1_freg = simd_get_quad_reg_index(src1_freg); + src2_freg = simd_get_quad_reg_index(src2_freg); ins |= (sljit_ins)1 << 6; } - return push_inst(compiler, ins | VD(dst_vreg) | VN(src1_vreg) | VM(src2)); + return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); } #undef FPU_LOAD @@ -4619,15 +4519,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - case SLJIT_MOV_S16: - case SLJIT_MOV_S32: - return SLJIT_ERR_UNSUPPORTED; - case SLJIT_MOV_U8: ins = LDREXB; break; @@ -4639,9 +4531,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler break; } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - return push_inst(compiler, ins | RN(mem_reg) | RD(dst_reg)); } @@ -4658,15 +4547,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - case SLJIT_MOV_S16: - case SLJIT_MOV_S32: - return SLJIT_ERR_UNSUPPORTED; - case SLJIT_MOV_U8: ins = STREXB; break; @@ -4678,9 +4559,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - FAIL_IF(push_inst(compiler, ins | RN(mem_reg) | RD(TMP_REG1) | RM(src_reg))); if (op & SLJIT_SET_ATOMIC_STORED) return push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(TMP_REG1)); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c index d80c9e546ee7..5331ebdf4296 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c @@ -91,7 +91,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define CLZ 0xdac01000 #define CSEL 0x9a800000 #define CSINC 0x9a800400 -#define DMB_SY 0xd5033fbf #define DUP_e 0x0e000400 #define DUP_g 0x0e000c00 #define EOR 0xca000000 @@ -172,7 +171,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SUBI 0xd1000000 #define SUBS 0xeb000000 #define TBZ 0x36000000 -#define TBL_v 0x0e000000 #define UBFM 0xd3400000 #define UCVTF 0x9e630000 #define UDIV 0x9ac00800 @@ -210,11 +208,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i { sljit_sw diff; sljit_uw target_addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; - sljit_uw orig_addr = jump->addr; - SLJIT_UNUSED_ARG(executable_offset); - jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -222,13 +216,10 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - - if (jump->u.label->size > orig_addr) - jump_addr = (sljit_uw)(code + orig_addr); + target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } - diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)target_addr - (sljit_sw)code_ptr - executable_offset; if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); @@ -280,21 +271,16 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT(jump->flags < ((sljit_uw)4 << JUMP_SIZE_SHIFT)); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else { + else addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - if (jump->u.label->size > jump->addr) - jump_addr = (sljit_uw)(code + jump->addr); - } - - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); if (diff <= 0xfffff && diff >= -0x100000) { jump->flags |= PATCH_B; @@ -436,10 +422,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if ((jump->flags & IS_COND) && (diff + 1) <= (0xfffff / SSIZE_OF(ins)) && (diff + 1) >= (-0x100000 / SSIZE_OF(ins))) total_size = 0; @@ -457,10 +439,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if (diff <= (0xfffff / SSIZE_OF(ins)) && diff >= (-0x100000 / SSIZE_OF(ins))) total_size = 0; @@ -538,6 +516,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); + jump->addr = (sljit_uw)code_ptr; code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); SLJIT_ASSERT((jump->flags & PATCH_COND) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { @@ -614,7 +593,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: return 1; default: @@ -1230,23 +1208,16 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 prev, fprev, saved_regs_size, i, tmp; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_ins offs; CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 2); saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1412,21 +1383,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 saved_regs_size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 2); saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1572,7 +1537,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile op = GET_OPCODE(op); switch (op) { case SLJIT_BREAKPOINT: - return push_inst(compiler, BRK | (0xf000 << 5)); + return push_inst(compiler, BRK); case SLJIT_NOP: return push_inst(compiler, NOP); case SLJIT_LMUL_UW: @@ -1589,8 +1554,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile case SLJIT_DIV_UW: case SLJIT_DIV_SW: return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); - case SLJIT_MEMORY_BARRIER: - return push_inst(compiler, DMB_SY); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2812,7 +2775,7 @@ static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, slj } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -2820,7 +2783,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -2835,9 +2798,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (!(srcdst & SLJIT_MEM)) { if (type & SLJIT_SIMD_STORE) - ins = VD(srcdst) | VN(vreg) | VM(vreg); + ins = VD(srcdst) | VN(freg) | VM(freg); else - ins = VD(vreg) | VN(srcdst) | VM(srcdst); + ins = VD(freg) | VN(srcdst) | VM(srcdst); if (reg_size == 4) ins |= (1 << 30); @@ -2855,7 +2818,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (reg_size == 4) ins |= (1 << 30); - return push_inst(compiler, ins | ((sljit_ins)elem_size << 10) | RN(srcdst) | VT(vreg)); + return push_inst(compiler, ins | ((sljit_ins)elem_size << 10) | RN(srcdst) | VT(freg)); } static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) @@ -2960,7 +2923,7 @@ static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -2968,7 +2931,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins, imm; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -2989,7 +2952,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 30; - return push_inst(compiler, LD1R | ins | RN(src) | VT(vreg)); + return push_inst(compiler, LD1R | ins | RN(src) | VT(freg)); } ins = (sljit_ins)1 << (16 + elem_size); @@ -2999,9 +2962,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) - return push_inst(compiler, MOVI | (ins & ((sljit_ins)1 << 30)) | VD(vreg)); + return push_inst(compiler, MOVI | (ins & ((sljit_ins)1 << 30)) | VD(freg)); - return push_inst(compiler, DUP_e | ins | VD(vreg) | VN(src)); + return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); } if (src == SLJIT_IMM) { @@ -3013,18 +2976,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (imm != ~(sljit_ins)0) { imm |= ins & ((sljit_ins)1 << 30); - return push_inst(compiler, MOVI | imm | VD(vreg)); + return push_inst(compiler, MOVI | imm | VD(freg)); } FAIL_IF(load_immediate(compiler, TMP_REG2, srcw)); src = TMP_REG2; } - return push_inst(compiler, DUP_g | ins | VD(vreg) | RN(src)); + return push_inst(compiler, DUP_g | ins | VD(freg) | RN(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3032,7 +2995,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3048,13 +3011,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 30); - if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { - FAIL_IF(push_inst(compiler, ORR_v | ins | VD(TMP_FREG1) | VN(vreg) | VM(vreg))); + if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(push_inst(compiler, ORR_v | ins | VD(TMP_FREG1) | VN(freg) | VM(freg))); srcdst = TMP_FREG1; srcdstw = 0; } - FAIL_IF(push_inst(compiler, MOVI | ins | VD(vreg))); + FAIL_IF(push_inst(compiler, MOVI | ins | VD(freg))); } if (srcdst & SLJIT_MEM) { @@ -3070,14 +3033,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile lane_index = lane_index << elem_size; ins |= (sljit_ins)(((lane_index & 0x8) << 27) | ((lane_index & 0x7) << 10)); - return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? ST1_s : LD1_s) | ins | RN(srcdst) | VT(vreg)); + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? ST1_s : LD1_s) | ins | RN(srcdst) | VT(freg)); } if (type & SLJIT_SIMD_FLOAT) { if (type & SLJIT_SIMD_STORE) - ins = INS_e | ((sljit_ins)1 << (16 + elem_size)) | ((sljit_ins)lane_index << (11 + elem_size)) | VD(srcdst) | VN(vreg); + ins = INS_e | ((sljit_ins)1 << (16 + elem_size)) | ((sljit_ins)lane_index << (11 + elem_size)) | VD(srcdst) | VN(freg); else - ins = INS_e | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)) | VD(vreg) | VN(srcdst); + ins = INS_e | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)) | VD(freg) | VN(srcdst); return push_inst(compiler, ins); } @@ -3091,7 +3054,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } if (type & SLJIT_SIMD_STORE) { - ins = RD(srcdst) | VN(vreg); + ins = RD(srcdst) | VN(freg); if ((type & SLJIT_SIMD_LANE_SIGNED) && (elem_size < 2 || (elem_size == 2 && !(type & SLJIT_32)))) { ins |= SMOV; @@ -3101,7 +3064,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } else ins |= UMOV; } else - ins = INS | VD(vreg) | RN(srcdst); + ins = INS | VD(freg) | RN(srcdst); if (elem_size == 3) ins |= (sljit_ins)1 << 30; @@ -3110,7 +3073,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3118,7 +3081,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3134,11 +3097,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 4) ins |= (sljit_ins)1 << 30; - return push_inst(compiler, DUP_e | ins | VD(vreg) | VN(src)); + return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3146,7 +3109,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3163,28 +3126,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); if (reg_size == 4 && elem2_size - elem_size == 1) - FAIL_IF(push_inst(compiler, LD1 | ((sljit_ins)elem_size << 10) | RN(src) | VT(vreg))); + FAIL_IF(push_inst(compiler, LD1 | ((sljit_ins)elem_size << 10) | RN(src) | VT(freg))); else - FAIL_IF(push_inst(compiler, LD1_s | ((sljit_ins)0x2000 << (reg_size - elem2_size + elem_size)) | RN(src) | VT(vreg))); - src = vreg; + FAIL_IF(push_inst(compiler, LD1_s | ((sljit_ins)0x2000 << (reg_size - elem2_size + elem_size)) | RN(src) | VT(freg))); + src = freg; } if (type & SLJIT_SIMD_FLOAT) { SLJIT_ASSERT(reg_size == 4); - return push_inst(compiler, FCVTL | (1 << 22) | VD(vreg) | VN(src)); + return push_inst(compiler, FCVTL | (1 << 22) | VD(freg) | VN(src)); } do { FAIL_IF(push_inst(compiler, ((type & SLJIT_SIMD_EXTEND_SIGNED) ? SSHLL : USHLL) - | ((sljit_ins)1 << (19 + elem_size)) | VD(vreg) | VN(src))); - src = vreg; + | ((sljit_ins)1 << (19 + elem_size)) | VD(freg) | VN(src))); + src = freg; } while (++elem_size < elem2_size); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3193,7 +3156,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -3228,7 +3191,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c if (reg_size == 4) ins |= (1 << 30); - FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG1) | VN(vreg))); + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG1) | VN(freg))); if (reg_size == 4 && elem_size > 0) FAIL_IF(push_inst(compiler, XTN | ((sljit_ins)(elem_size - 1) << 22) | VD(TMP_FREG1) | VN(TMP_FREG1))); @@ -3261,15 +3224,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3277,9 +3239,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) return SLJIT_ERR_UNSUPPORTED; - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = AND_v; @@ -3290,24 +3249,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = EOR_v; break; - case SLJIT_SIMD_OP2_SHUFFLE: - ins = TBL_v; - break; } - if (src2 & SLJIT_MEM) { - if (elem_size > 3) - elem_size = 3; - - FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); - push_inst(compiler, LD1 | (reg_size == 4 ? (1 << 30) : 0) | ((sljit_ins)elem_size << 10) | RN(src2) | VT(TMP_FREG1)); - src2 = TMP_FREG1; - } + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; if (reg_size == 4) ins |= (sljit_ins)1 << 30; - return push_inst(compiler, ins | VD(dst_vreg) | VN(src1_vreg) | VM(src2)); + return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, @@ -3319,55 +3269,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); -#ifndef __ARM_FEATURE_ATOMICS - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; -#endif /* ARM_FEATURE_ATOMICS */ - +#ifdef __ARM_FEATURE_ATOMICS switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - case SLJIT_MOV_S16: - case SLJIT_MOV_S32: - return SLJIT_ERR_UNSUPPORTED; - case SLJIT_MOV32: case SLJIT_MOV_U32: -#ifdef __ARM_FEATURE_ATOMICS - if (!(op & SLJIT_ATOMIC_USE_LS)) - ins = LDR ^ (1 << 30); - else -#endif /* ARM_FEATURE_ATOMICS */ - ins = LDXR ^ (1 << 30); + ins = LDR ^ (1 << 30); + break; + case SLJIT_MOV_U16: + ins = LDRH; break; case SLJIT_MOV_U8: -#ifdef __ARM_FEATURE_ATOMICS - if (!(op & SLJIT_ATOMIC_USE_LS)) - ins = LDRB; - else -#endif /* ARM_FEATURE_ATOMICS */ - ins = LDXRB; + ins = LDRB; + break; + default: + ins = LDR; + break; + } +#else /* !__ARM_FEATURE_ATOMICS */ + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = LDXR ^ (1 << 30); + break; + case SLJIT_MOV_U8: + ins = LDXRB; break; case SLJIT_MOV_U16: -#ifdef __ARM_FEATURE_ATOMICS - if (!(op & SLJIT_ATOMIC_USE_LS)) - ins = LDRH; - else -#endif /* ARM_FEATURE_ATOMICS */ - ins = LDXRH; + ins = LDXRH; break; default: -#ifdef __ARM_FEATURE_ATOMICS - if (!(op & SLJIT_ATOMIC_USE_LS)) - ins = LDR; - else -#endif /* ARM_FEATURE_ATOMICS */ - ins = LDXR; + ins = LDXR; break; } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - +#endif /* ARM_FEATURE_ATOMICS */ return push_inst(compiler, ins | RN(mem_reg) | RT(dst_reg)); } @@ -3377,65 +3311,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler sljit_s32 temp_reg) { sljit_ins ins; + sljit_s32 tmp = temp_reg; sljit_ins cmp = 0; + sljit_ins inv_bits = W_OP; CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); #ifdef __ARM_FEATURE_ATOMICS - if (!(op & SLJIT_ATOMIC_USE_LS)) { - if (op & SLJIT_SET_ATOMIC_STORED) - cmp = (SUBS ^ W_OP) | RD(TMP_ZERO); - - switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - case SLJIT_MOV_S16: - case SLJIT_MOV_S32: - return SLJIT_ERR_UNSUPPORTED; - - case SLJIT_MOV32: - case SLJIT_MOV_U32: - ins = CAS ^ (1 << 30); - break; - case SLJIT_MOV_U16: - ins = CASH; - break; - case SLJIT_MOV_U8: - ins = CASB; - break; - default: - ins = CAS; - if (cmp) - cmp ^= W_OP; - break; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; + if (op & SLJIT_SET_ATOMIC_STORED) + cmp = (SUBS ^ W_OP) | RD(TMP_ZERO); + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = CAS ^ (1 << 30); + break; + case SLJIT_MOV_U16: + ins = CASH; + break; + case SLJIT_MOV_U8: + ins = CASB; + break; + default: + ins = CAS; + inv_bits = 0; if (cmp) - FAIL_IF(push_inst(compiler, ((MOV ^ W_OP) ^ (cmp & W_OP)) | RM(temp_reg) | RD(TMP_REG2))); - - FAIL_IF(push_inst(compiler, ins | RM(temp_reg) | RN(mem_reg) | RD(src_reg))); - if (!cmp) - return SLJIT_SUCCESS; + cmp ^= W_OP; + break; + } - return push_inst(compiler, cmp | RM(TMP_REG2) | RN(temp_reg)); + if (cmp) { + FAIL_IF(push_inst(compiler, (MOV ^ inv_bits) | RM(temp_reg) | RD(TMP_REG1))); + tmp = TMP_REG1; } + FAIL_IF(push_inst(compiler, ins | RM(tmp) | RN(mem_reg) | RD(src_reg))); + if (!cmp) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, cmp | RM(tmp) | RN(temp_reg))); + FAIL_IF(push_inst(compiler, (CSET ^ inv_bits) | RD(tmp))); + return push_inst(compiler, cmp | RM(tmp) | RN(TMP_ZERO)); #else /* !__ARM_FEATURE_ATOMICS */ - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; -#endif /* __ARM_FEATURE_ATOMICS */ + SLJIT_UNUSED_ARG(tmp); + SLJIT_UNUSED_ARG(inv_bits); if (op & SLJIT_SET_ATOMIC_STORED) cmp = (SUBI ^ W_OP) | (1 << 29); switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - case SLJIT_MOV_S16: - case SLJIT_MOV_S32: - return SLJIT_ERR_UNSUPPORTED; - case SLJIT_MOV32: case SLJIT_MOV_U32: ins = STXR ^ (1 << 30); @@ -3451,13 +3375,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - FAIL_IF(push_inst(compiler, ins | RM(TMP_REG2) | RN(mem_reg) | RT(src_reg))); - if (!cmp) - return SLJIT_SUCCESS; - return push_inst(compiler, cmp | RD(TMP_ZERO) | RN(TMP_REG2)); + FAIL_IF(push_inst(compiler, ins | RM(TMP_REG1) | RN(mem_reg) | RT(src_reg))); + return cmp ? push_inst(compiler, cmp | RD(TMP_ZERO) | RN(TMP_REG1)) : SLJIT_SUCCESS; +#endif /* __ARM_FEATURE_ATOMICS */ } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c index d8058ab6ea4b..799954a85996 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c @@ -138,7 +138,6 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define CMPI_W 0xf1b00f00 #define CMP_X 0x4500 #define CMP_W 0xebb00f00 -#define DMB_SY 0xf3bf8f5f #define EORI 0xf0800000 #define EORS 0x4040 #define EOR_W 0xea800000 @@ -254,7 +253,6 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) #define VST1_s 0xf9800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 -#define VTBL 0xffb00800 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -266,28 +264,11 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) fr -= SLJIT_F64_SECOND(0); - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches)) - || (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0) + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } -static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type) -{ - sljit_s32 vr_low = vr; - - if (compiler->scratches == -1) - return 0; - - if (SLJIT_SIMD_GET_REG_SIZE(type) == 4) { - vr += (vr & 0x1); - vr_low = vr - 1; - } - - return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches)) - || (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0) - || (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)); -} - #endif /* SLJIT_ARGUMENT_CHECKS */ static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst) @@ -339,12 +320,7 @@ static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm) static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset) { sljit_sw diff; - sljit_uw target_addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; - sljit_uw orig_addr = jump->addr; - SLJIT_UNUSED_ARG(executable_offset); - jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -352,17 +328,12 @@ static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u /* Branch to ARM code is not optimized yet. */ if (!(jump->u.target & 0x1)) goto exit; - target_addr = jump->u.target; + diff = (sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset; } else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - - if (jump->u.label->size > orig_addr) - jump_addr = (sljit_uw)(code + orig_addr); + diff = (sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2); } - diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr + 4, executable_offset); - if (jump->flags & IS_COND) { SLJIT_ASSERT(!(jump->flags & IS_BL)); /* Size of the prefix IT instruction. */ @@ -409,21 +380,16 @@ static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset) { sljit_uw addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else { + else addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - if (jump->u.label->size > jump->addr) - jump_addr = (sljit_uw)(code + jump->addr); - } - /* The pc+4 offset is represented by the 2 * SSIZE_OF(sljit_u16) below. */ - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); /* Note: ADR with imm8 does not set the last bit (Thumb2 flag). */ @@ -551,10 +517,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if (jump->flags & IS_COND) { diff++; @@ -578,10 +540,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if (diff <= (0xffd / SSIZE_OF(u16)) && diff >= (-0xfff / SSIZE_OF(u16))) total_size = 1; @@ -654,6 +612,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { half_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); + jump->addr = (sljit_uw)code_ptr; code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); SLJIT_ASSERT((sljit_uw)code_ptr - jump->addr < ((jump->flags >> JUMP_SIZE_SHIFT) + ((jump->flags & 0xf0) <= PATCH_TYPE2)) * sizeof(sljit_u16)); @@ -735,7 +694,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: return 1; default: @@ -1409,11 +1367,9 @@ static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 size, i, tmp, word_arg_count; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_uw offset; @@ -1427,13 +1383,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); tmp = SLJIT_S0 - saveds; for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) @@ -1626,21 +1577,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); /* Doubles are saved, so alignment is unaffected. */ @@ -1959,8 +1904,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile } return SLJIT_SUCCESS; #endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */ - case SLJIT_MEMORY_BARRIER: - return push_inst32(compiler, DMB_SY); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2261,7 +2204,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) return freg_map[reg]; - if (type == SLJIT_SIMD_REG_128) + if (type != SLJIT_SIMD_REG_128) return freg_map[reg] & ~0x1; return -1; @@ -3639,7 +3582,7 @@ static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) #define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3648,7 +3591,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3662,16 +3605,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (!(srcdst & SLJIT_MEM)) { if (reg_size == 4) srcdst = simd_get_quad_reg_index(srcdst); if (type & SLJIT_SIMD_STORE) - ins = VD4(srcdst) | VN4(vreg) | VM4(vreg); + ins = VD4(srcdst) | VN4(freg) | VM4(freg); else - ins = VD4(vreg) | VN4(srcdst) | VM4(srcdst); + ins = VD4(freg) | VN4(srcdst) | VM4(srcdst); if (reg_size == 4) ins |= (sljit_ins)1 << 6; @@ -3684,7 +3627,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (elem_size > 3) elem_size = 3; - ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD4(vreg) + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD4(freg) | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); SLJIT_ASSERT(reg_size >= alignment); @@ -3792,7 +3735,7 @@ static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3800,7 +3743,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins, imm; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3814,24 +3757,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (src == SLJIT_IMM && srcw == 0) - return push_inst32(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD4(vreg)); + return push_inst32(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD4(freg)); if (SLJIT_UNLIKELY(elem_size == 3)) { SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, vreg, src, srcw)); - src = vreg; - } else if (vreg != src) - FAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src))); + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); + src = freg; + } else if (freg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); - if (vreg != src) - return push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src)); + if (freg != src) + return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); return SLJIT_SUCCESS; } @@ -3843,7 +3786,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= 1 << 5; - return push_inst32(compiler, VLD1_r | ins | VD4(vreg) | RN4(src) | 0xf); + return push_inst32(compiler, VLD1_r | ins | VD4(freg) | RN4(src) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { @@ -3853,7 +3796,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst32(compiler, VDUP_s | ins | VD4(vreg) | (sljit_ins)freg_map[src]); + return push_inst32(compiler, VDUP_s | ins | VD4(freg) | (sljit_ins)freg_map[src]); } if (src == SLJIT_IMM) { @@ -3866,7 +3809,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) imm |= (sljit_ins)1 << 6; - return push_inst32(compiler, VMOV_i | imm | VD4(vreg)); + return push_inst32(compiler, VMOV_i | imm | VD4(freg)); } FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); @@ -3888,11 +3831,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 4) ins |= (sljit_ins)1 << 21; - return push_inst32(compiler, VDUP | ins | VN4(vreg) | RT4(src)); + return push_inst32(compiler, VDUP | ins | VN4(freg) | RT4(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3900,7 +3843,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3914,7 +3857,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); @@ -3922,62 +3865,62 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { if (lane_index == 1) - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); - if (srcdst != vreg) - FAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(srcdst) | VM4(srcdst))); + if (srcdst != freg) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(srcdst) | VM4(srcdst))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - return push_inst32(compiler, VMOV_i | VD4(vreg)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VMOV_i | VD4(freg)); } - if (srcdst == vreg || (elem_size == 3 && srcdst == (vreg + SLJIT_QUAD_OTHER_HALF(vreg)))) { - FAIL_IF(push_inst32(compiler, VORR | ins | VD4(TMP_FREG2) | VN4(vreg) | VM4(vreg))); + if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { + FAIL_IF(push_inst32(compiler, VORR | ins | VD4(TMP_FREG2) | VN4(freg) | VM4(freg))); srcdst = TMP_FREG2; srcdstw = 0; } } - FAIL_IF(push_inst32(compiler, VMOV_i | ins | VD4(vreg))); + FAIL_IF(push_inst32(compiler, VMOV_i | ins | VD4(freg))); } if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { lane_index -= (0x8 >> elem_size); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); } if (srcdst & SLJIT_MEM) { if (elem_size == 3) - return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, vreg, srcdst, srcdstw); + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); lane_index = lane_index << elem_size; ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); - return push_inst32(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD4(vreg) | RN4(srcdst) | 0xf); + return push_inst32(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD4(freg) | RN4(srcdst) | 0xf); } if (type & SLJIT_SIMD_FLOAT) { if (elem_size == 3) { if (type & SLJIT_SIMD_STORE) - return push_inst32(compiler, VORR | VD4(srcdst) | VN4(vreg) | VM4(vreg)); - return push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(vreg) | VM4(srcdst)); + return push_inst32(compiler, VORR | VD4(srcdst) | VN4(freg) | VM4(freg)); + return push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(freg) | VM4(srcdst)); } if (type & SLJIT_SIMD_STORE) { - if (freg_ebit_map[vreg] == 0) { + if (freg_ebit_map[freg] == 0) { if (lane_index == 1) - vreg = SLJIT_F64_SECOND(vreg); + freg = SLJIT_F64_SECOND(freg); - return push_inst32(compiler, VMOV_F32 | VD4(srcdst) | VM4(vreg)); + return push_inst32(compiler, VMOV_F32 | VD4(srcdst) | VM4(freg)); } - FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN4(vreg) | RT4(TMP_REG1))); + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1))); return push_inst32(compiler, VMOV | VN4(srcdst) | RT4(TMP_REG1)); } FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(srcdst) | RT4(TMP_REG1))); - return push_inst32(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN4(vreg) | RT4(TMP_REG1)); + return push_inst32(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1)); } if (srcdst == SLJIT_IMM) { @@ -4005,11 +3948,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins |= (1 << 23); } - return push_inst32(compiler, VMOV_s | ins | VN4(vreg) | RT4(srcdst)); + return push_inst32(compiler, VMOV_s | ins | VN4(freg) | RT4(srcdst)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4017,7 +3960,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4029,7 +3972,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c return SLJIT_SUCCESS; if (reg_size == 4) { - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); src = simd_get_quad_reg_index(src); if (src_lane_index >= (0x8 >> elem_size)) { @@ -4039,13 +3982,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } if (elem_size == 3) { - if (vreg != src) - FAIL_IF(push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src))); + if (freg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); + freg += SLJIT_QUAD_OTHER_HALF(freg); - if (vreg != src) - return push_inst32(compiler, VORR | VD4(vreg) | VN4(src) | VM4(src)); + if (freg != src) + return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); return SLJIT_SUCCESS; } @@ -4054,11 +3997,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 4) ins |= (sljit_ins)1 << 6; - return push_inst32(compiler, VDUP_s | ins | VD4(vreg) | VM4(src)); + return push_inst32(compiler, VDUP_s | ins | VD4(freg) | VM4(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4067,7 +4010,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_s32 dst_reg; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4081,20 +4024,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (reg_size == 4) - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); if (src & SLJIT_MEM) { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); if (reg_size == 4 && elem2_size - elem_size == 1) - FAIL_IF(push_inst32(compiler, VLD1 | (0x7 << 8) | VD4(vreg) | RN4(src) | 0xf)); + FAIL_IF(push_inst32(compiler, VLD1 | (0x7 << 8) | VD4(freg) | RN4(src) | 0xf)); else - FAIL_IF(push_inst32(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD4(vreg) | RN4(src) | 0xf)); - src = vreg; + FAIL_IF(push_inst32(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD4(freg) | RN4(src) | 0xf)); + src = freg; } else if (reg_size == 4) src = simd_get_quad_reg_index(src); if (!(type & SLJIT_SIMD_FLOAT)) { - dst_reg = (reg_size == 4) ? vreg : TMP_FREG2; + dst_reg = (reg_size == 4) ? freg : TMP_FREG2; do { FAIL_IF(push_inst32(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 28)) @@ -4103,27 +4046,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } while (++elem_size < elem2_size); if (dst_reg == TMP_FREG2) - return push_inst32(compiler, VORR | VD4(vreg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); + return push_inst32(compiler, VORR | VD4(freg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); return SLJIT_SUCCESS; } /* No SIMD variant, must use VFP instead. */ SLJIT_ASSERT(reg_size == 4); - if (vreg == src) { - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src) | 0x20)); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - return push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src)); + if (freg == src) { + freg += SLJIT_QUAD_OTHER_HALF(freg); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src)); } - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src))); - vreg += SLJIT_QUAD_OTHER_HALF(vreg); - return push_inst32(compiler, VCVT_F64_F32 | VD4(vreg) | VM4(src) | 0x20); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src))); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4132,7 +4075,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4165,12 +4108,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } if (reg_size == 4) { - vreg = simd_get_quad_reg_index(vreg); + freg = simd_get_quad_reg_index(freg); ins |= (sljit_ins)1 << 6; } SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); - FAIL_IF(push_inst32(compiler, ins | VD4(TMP_FREG2) | VM4(vreg))); + FAIL_IF(push_inst32(compiler, ins | VD4(TMP_FREG2) | VM4(freg))); if (reg_size == 4 && elem_size > 0) FAIL_IF(push_inst32(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); @@ -4200,16 +4143,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 alignment; - sljit_ins ins = 0, load_ins; + sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); if (reg_size != 3 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4217,9 +4158,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) return SLJIT_ERR_UNSUPPORTED; - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = VAND; @@ -4230,51 +4168,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = VEOR; break; - case SLJIT_SIMD_OP2_SHUFFLE: - ins = VTBL; - break; } - if (src2 & SLJIT_MEM) { - if (elem_size > 3) - elem_size = 3; - - load_ins = VLD1 | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); - alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); - - SLJIT_ASSERT(reg_size >= alignment); - - if (alignment == 3) - load_ins |= 0x10; - else if (alignment >= 4) - load_ins |= 0x20; - - FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); - FAIL_IF(push_inst32(compiler, load_ins | VD4(TMP_FREG2) | RN4(src2) | ((sljit_ins)elem_size) << 6 | 0xf)); - src2 = TMP_FREG2; - } + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; if (reg_size == 4) { - dst_vreg = simd_get_quad_reg_index(dst_vreg); - src1_vreg = simd_get_quad_reg_index(src1_vreg); - src2 = simd_get_quad_reg_index(src2); - - if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) { - ins |= (sljit_ins)1 << 8; - - FAIL_IF(push_inst32(compiler, ins | VD4(dst_vreg != src1_vreg ? dst_vreg : TMP_FREG2) | VN4(src1_vreg) | VM4(src2))); - src2 += SLJIT_QUAD_OTHER_HALF(src2); - FAIL_IF(push_inst32(compiler, ins | VD4(dst_vreg + SLJIT_QUAD_OTHER_HALF(dst_vreg)) | VN4(src1_vreg) | VM4(src2))); - - if (dst_vreg == src1_vreg) - return push_inst32(compiler, VORR | VD4(dst_vreg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); - return SLJIT_SUCCESS; - } - + dst_freg = simd_get_quad_reg_index(dst_freg); + src1_freg = simd_get_quad_reg_index(src1_freg); + src2_freg = simd_get_quad_reg_index(src2_freg); ins |= (sljit_ins)1 << 6; } - return push_inst32(compiler, ins | VD4(dst_vreg) | VN4(src1_vreg) | VM4(src2)); + return push_inst32(compiler, ins | VD4(dst_freg) | VN4(src1_freg) | VM4(src2_freg)); } #undef FPU_LOAD @@ -4288,15 +4194,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - case SLJIT_MOV_S16: - case SLJIT_MOV_S32: - return SLJIT_ERR_UNSUPPORTED; - case SLJIT_MOV_U8: ins = LDREXB; break; @@ -4308,9 +4206,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler break; } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - return push_inst32(compiler, ins | RN4(mem_reg) | RT4(dst_reg)); } @@ -4327,15 +4222,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - case SLJIT_MOV_S16: - case SLJIT_MOV_S32: - return SLJIT_ERR_UNSUPPORTED; - case SLJIT_MOV_U8: ins = STREXB | RM4(TMP_REG1); break; @@ -4347,9 +4234,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - FAIL_IF(push_inst32(compiler, ins | RN4(mem_reg) | RT4(src_reg))); if (op & SLJIT_SET_ATOMIC_STORED) return push_inst32(compiler, CMPI_W | RN4(TMP_REG1)); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c index 73868ca186a4..2e1d742aee74 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeLOONGARCH_64.c @@ -250,9 +250,6 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes #define AMCAS_W OPC_3R(0x70B2) #define AMCAS_D OPC_3R(0x70B3) -/* Memory barrier instructions */ -#define DBAR OPC_3R(0x70e4) - /* Other instructions */ #define BREAK OPC_3R(0x54) #define DBGCALL OPC_3R(0x55) @@ -351,7 +348,6 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes #define VREPLGR2VR OPC_2R(0x1ca7c0) #define VREPLVE OPC_3R(0xe244) #define VREPLVEI OPC_2R(0x1cbde0) -#define VSHUF_B OPC_4R(0xd5) #define XVPERMI OPC_2RI8(0x1dfa) #define I12_MAX (0x7ff) @@ -390,8 +386,6 @@ static sljit_u32 hwcap_feature_list = 0; #define GET_CFG2 0 #define GET_HWCAP 1 -#define LOONGARCH_SUPPORT_AMCAS (LOONGARCH_CFG2_LAMCAS & get_cpu_features(GET_CFG2)) - static SLJIT_INLINE sljit_u32 get_cpu_features(sljit_u32 feature_type) { if (cfg2_feature_list == 0) @@ -411,15 +405,14 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; - sljit_uw orig_addr = jump->addr; - SLJIT_UNUSED_ARG(executable_offset); + sljit_ins *inst; + + inst = (sljit_ins *)jump->addr; - jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -427,23 +420,20 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - - if (jump->u.label->size > orig_addr) - jump_addr = (sljit_uw)(code + orig_addr); + target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } - diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)target_addr - (sljit_sw)inst - executable_offset; if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); if (diff >= BRANCH16_MIN && diff <= BRANCH16_MAX) { - code_ptr--; - code_ptr[0] = (code_ptr[0] & 0xfc0003ff) ^ 0x4000000; + inst--; + inst[0] = (inst[0] & 0xfc0003ff) ^ 0x4000000; jump->flags |= PATCH_B; - jump->addr = (sljit_uw)code_ptr; - return code_ptr; + jump->addr = (sljit_uw)inst; + return inst; } diff -= SSIZE_OF(ins); @@ -451,65 +441,60 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i if (diff >= JUMP_MIN && diff <= JUMP_MAX) { if (jump->flags & IS_COND) { - code_ptr[-1] |= (sljit_ins)IMM_I16(2); + inst[-1] |= (sljit_ins)IMM_I16(2); } jump->flags |= PATCH_J; - return code_ptr; + return inst; } if (diff >= S32_MIN && diff <= S32_MAX) { if (jump->flags & IS_COND) - code_ptr[-1] |= (sljit_ins)IMM_I16(3); + inst[-1] |= (sljit_ins)IMM_I16(3); jump->flags |= PATCH_REL32; - code_ptr[1] = code_ptr[0]; - return code_ptr + 1; + inst[1] = inst[0]; + return inst + 1; } if (target_addr <= (sljit_uw)S32_MAX) { if (jump->flags & IS_COND) - code_ptr[-1] |= (sljit_ins)IMM_I16(3); + inst[-1] |= (sljit_ins)IMM_I16(3); jump->flags |= PATCH_ABS32; - code_ptr[1] = code_ptr[0]; - return code_ptr + 1; + inst[1] = inst[0]; + return inst + 1; } if (target_addr <= S52_MAX) { if (jump->flags & IS_COND) - code_ptr[-1] |= (sljit_ins)IMM_I16(4); + inst[-1] |= (sljit_ins)IMM_I16(4); jump->flags |= PATCH_ABS52; - code_ptr[2] = code_ptr[0]; - return code_ptr + 2; + inst[2] = inst[0]; + return inst + 2; } exit: if (jump->flags & IS_COND) - code_ptr[-1] |= (sljit_ins)IMM_I16(5); - code_ptr[3] = code_ptr[0]; - return code_ptr + 3; + inst[-1] |= (sljit_ins)IMM_I16(5); + inst[3] = inst[0]; + return inst + 3; } static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT)); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else { + else addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - if (jump->u.label->size > jump->addr) - jump_addr = (sljit_uw)(code + jump->addr); - } - - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); if (diff >= S32_MIN && diff <= S32_MAX) { SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT)); @@ -632,10 +617,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH16_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH16_MIN / SSIZE_OF(ins))) total_size = 0; @@ -654,10 +635,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { /* Real size minus 1. Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins))) total_size = 1; @@ -733,7 +710,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); + jump->addr = (sljit_uw)code_ptr; + code_ptr = detect_jump_type(jump, code, executable_offset); SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { word_count += jump->flags >> JUMP_SIZE_SHIFT; @@ -826,6 +804,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_SIMD: return (LOONGARCH_HWCAP_LSX & get_cpu_features(GET_HWCAP)); + case SLJIT_HAS_ATOMIC: + return (LOONGARCH_CFG2_LAMCAS & get_cpu_features(GET_CFG2)); + case SLJIT_HAS_CLZ: case SLJIT_HAS_CTZ: case SLJIT_HAS_REV: @@ -833,8 +814,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_PREFETCH: case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: - case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: return 1; default: @@ -910,22 +889,16 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw); SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 i, tmp, offset; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1000,20 +973,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #undef STACK_MAX_DISTANCE SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1918,8 +1884,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, ((op & SLJIT_32)? DIV_WU: DIV_DU) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1)); case SLJIT_DIV_SW: return push_inst(compiler, INST(DIV, op) | RD(SLJIT_R0) | RJ(SLJIT_R0) | RK(SLJIT_R1)); - case SLJIT_MEMORY_BARRIER: - return push_inst(compiler, DBAR); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2680,8 +2644,10 @@ static sljit_ins get_jump_instruction(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: return BNE | RJ(EQUAL_FLAG) | RD(TMP_ZERO); case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_STORED: return BEQ | RJ(EQUAL_FLAG) | RD(TMP_ZERO); case SLJIT_LESS: case SLJIT_GREATER: @@ -2689,7 +2655,6 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: case SLJIT_CARRY: - case SLJIT_ATOMIC_STORED: return BEQ | RJ(OTHER_FLAG) | RD(TMP_ZERO); case SLJIT_GREATER_EQUAL: case SLJIT_LESS_EQUAL: @@ -2697,7 +2662,6 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: case SLJIT_NOT_CARRY: - case SLJIT_ATOMIC_NOT_STORED: return BNE | RJ(OTHER_FLAG) | RD(TMP_ZERO); case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: @@ -2969,7 +2933,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co break; case SLJIT_ATOMIC_STORED: case SLJIT_ATOMIC_NOT_STORED: - FAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RJ(OTHER_FLAG) | IMM_I12(1))); + FAIL_IF(push_inst(compiler, SLTUI | RD(dst_r) | RJ(EQUAL_FLAG) | IMM_I12(1))); src_r = dst_r; invert ^= 0x1; break; @@ -3198,14 +3162,14 @@ static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, slj } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3220,9 +3184,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (!(srcdst & SLJIT_MEM)) { if (type & SLJIT_SIMD_STORE) - ins = FRD(srcdst) | FRJ(vreg) | FRK(vreg); + ins = FRD(srcdst) | FRJ(freg) | FRK(freg); else - ins = FRD(vreg) | FRJ(srcdst) | FRK(srcdst); + ins = FRD(freg) | FRJ(srcdst) | FRK(srcdst); if (reg_size == 5) ins |= VOR_V | (sljit_ins)1 << 26; @@ -3238,15 +3202,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co ins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD; if (FAST_IS_REG(srcdst) && srcdst >= 0 && (srcdstw >= I12_MIN && srcdstw <= I12_MAX)) - return push_inst(compiler, ins | FRD(vreg) | RJ((sljit_u8)srcdst) | IMM_I12(srcdstw)); + return push_inst(compiler, ins | FRD(freg) | RJ((sljit_u8)srcdst) | IMM_I12(srcdstw)); else { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); - return push_inst(compiler, ins | FRD(vreg) | RJ(srcdst) | IMM_I12(0)); + return push_inst(compiler, ins | FRD(freg) | RJ(srcdst) | IMM_I12(0)); } } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3254,7 +3218,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3273,7 +3237,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (reg_size == 5) ins = (sljit_ins)1 << 25; - return push_inst(compiler, VLDREPL | ins | FRD(vreg) | RJ(src) | (sljit_ins)1 << (23 - elem_size)); + return push_inst(compiler, VLDREPL | ins | FRD(freg) | RJ(src) | (sljit_ins)1 << (23 - elem_size)); } if (reg_size == 5) @@ -3281,13 +3245,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) - return push_inst(compiler, VREPLGR2VR | ins | FRD(vreg) | RJ(TMP_ZERO) | (sljit_ins)elem_size << 10); + return push_inst(compiler, VREPLGR2VR | ins | FRD(freg) | RJ(TMP_ZERO) | (sljit_ins)elem_size << 10); - FAIL_IF(push_inst(compiler, VREPLVE | ins | FRD(vreg) | FRJ(src) | RK(TMP_ZERO) | (sljit_ins)elem_size << 15)); + FAIL_IF(push_inst(compiler, VREPLVE | ins | FRD(freg) | FRJ(src) | RK(TMP_ZERO) | (sljit_ins)elem_size << 15)); if (reg_size == 5) { ins = (sljit_ins)(0x44 << 10); - return push_inst(compiler, XVPERMI | ins | FRD(vreg) | FRJ(vreg)); + return push_inst(compiler, XVPERMI | ins | FRD(freg) | FRJ(freg)); } return SLJIT_SUCCESS; @@ -3300,11 +3264,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil src = TMP_REG2; } - return push_inst(compiler, ins | FRD(vreg) | RJ(src)); + return push_inst(compiler, ins | FRD(freg) | RJ(src)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3312,7 +3276,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3334,13 +3298,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_LANE_ZERO) { ins = (reg_size == 5) ? ((sljit_ins)1 << 26) : 0; - if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { - FAIL_IF(push_inst(compiler, VOR_V | ins | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); + if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(push_inst(compiler, VOR_V | ins | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); srcdst = TMP_FREG1; srcdstw = 0; } - FAIL_IF(push_inst(compiler, VXOR_V | ins | FRD(vreg) | FRJ(vreg) | FRK(vreg))); + FAIL_IF(push_inst(compiler, VXOR_V | ins | FRD(freg) | FRJ(freg) | FRK(freg))); } if (srcdst & SLJIT_MEM) { @@ -3351,7 +3315,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_STORE) { ins |= (sljit_ins)lane_index << 18 | (sljit_ins)(1 << (23 - elem_size)); - return push_inst(compiler, VSTELM | ins | FRD(vreg) | RJ(srcdst)); + return push_inst(compiler, VSTELM | ins | FRD(freg) | RJ(srcdst)); } else { emit_op_mem(compiler, (elem_size == 3 ? WORD_DATA : (elem_size == 2 ? INT_DATA : (elem_size == 1 ? HALF_DATA : BYTE_DATA))) | LOAD_DATA, TMP_REG1, srcdst | SLJIT_MEM, 0); srcdst = TMP_REG1; @@ -3359,20 +3323,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (reg_size == 5) { if (elem_size < 2) { - FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); + FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); if (lane_index >= (2 << (3 - elem_size))) { - FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1))); + FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1))); FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size))))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(2)); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(2)); } else { - FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(18)); + FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index))); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(18)); } } else ins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26; } - return push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index)); + return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index)); } } @@ -3380,11 +3344,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins = (reg_size == 5) ? (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26 : (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10; if (type & SLJIT_SIMD_STORE) { - FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(vreg) | IMM_V(lane_index))); + FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(freg) | IMM_V(lane_index))); return push_inst(compiler, VINSGR2VR | ins | FRD(srcdst) | RJ(TMP_REG1) | IMM_V(0)); } else { FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(srcdst) | IMM_V(0))); - return push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(TMP_REG1) | IMM_V(lane_index)); + return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(TMP_REG1) | IMM_V(lane_index)); } } @@ -3409,8 +3373,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile else ins |= VPICKVE2GR_U; - FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); - FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1))); + FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); + FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1))); return push_inst(compiler, ins | RD(srcdst) | FRJ(TMP_FREG1) | IMM_V(lane_index % (2 << (3 - elem_size)))); } } else { @@ -3419,33 +3383,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } } - return push_inst(compiler, ins | RD(srcdst) | FRJ(vreg) | IMM_V(lane_index)); + return push_inst(compiler, ins | RD(srcdst) | FRJ(freg) | IMM_V(lane_index)); } else { ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10; if (reg_size == 5) { if (elem_size < 2) { - FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(vreg) | FRK(vreg))); + FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg))); if (lane_index >= (2 << (3 - elem_size))) { - FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(vreg) | IMM_I8(1))); + FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1))); FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size))))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(2)); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(2)); } else { - FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index))); - return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(vreg) | FRJ(TMP_FREG1) | IMM_I8(18)); + FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index))); + return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(18)); } } else ins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26; } - return push_inst(compiler, VINSGR2VR | ins | FRD(vreg) | RJ(srcdst) | IMM_V(lane_index)); + return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index)); } return SLJIT_ERR_UNSUPPORTED; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3453,7 +3417,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); if (reg_size != 5 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3467,18 +3431,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10; if (reg_size == 5) { - FAIL_IF(push_inst(compiler, VREPLVEI | (sljit_ins)1 << 26 | ins | FRD(vreg) | FRJ(src) | IMM_V(src_lane_index % (2 << (3 - elem_size))))); + FAIL_IF(push_inst(compiler, VREPLVEI | (sljit_ins)1 << 26 | ins | FRD(freg) | FRJ(src) | IMM_V(src_lane_index % (2 << (3 - elem_size))))); ins = (src_lane_index < (2 << (3 - elem_size))) ? (sljit_ins)(0x44 << 10) : (sljit_ins)(0xee << 10); - return push_inst(compiler, XVPERMI | ins | FRD(vreg) | FRJ(vreg)); + return push_inst(compiler, XVPERMI | ins | FRD(freg) | FRJ(freg)); } - return push_inst(compiler, VREPLVEI | ins | FRD(vreg) | FRJ(src) | IMM_V(src_lane_index)); + return push_inst(compiler, VREPLVEI | ins | FRD(freg) | FRJ(src) | IMM_V(src_lane_index)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3487,7 +3451,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3507,12 +3471,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler ins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD; if (FAST_IS_REG(src) && src >= 0 && (srcw >= I12_MIN && srcw <= I12_MAX)) - FAIL_IF(push_inst(compiler, ins | FRD(vreg) | RJ(src) | IMM_I12(srcw))); + FAIL_IF(push_inst(compiler, ins | FRD(freg) | RJ(src) | IMM_I12(srcw))); else { FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); - FAIL_IF(push_inst(compiler, ins | FRD(vreg) | RJ(src) | IMM_I12(0))); + FAIL_IF(push_inst(compiler, ins | FRD(freg) | RJ(src) | IMM_I12(0))); } - src = vreg; + src = freg; } if (type & SLJIT_SIMD_FLOAT) { @@ -3525,7 +3489,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler FAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16))); } - return push_inst(compiler, VFCVTL_D_S | ins | FRD(vreg) | FRJ(src)); + return push_inst(compiler, VFCVTL_D_S | ins | FRD(freg) | FRJ(src)); } ins = (type & SLJIT_SIMD_EXTEND_SIGNED) ? VSLLWIL : (VSLLWIL | (sljit_ins)1 << 18); @@ -3537,15 +3501,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler if (reg_size == 5) FAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16))); - FAIL_IF(push_inst(compiler, ins | ((sljit_ins)1 << (13 + elem_size)) | FRD(vreg) | FRJ(src))); - src = vreg; + FAIL_IF(push_inst(compiler, ins | ((sljit_ins)1 << (13 + elem_size)) | FRD(freg) | FRJ(src))); + src = freg; } while (++elem_size < elem2_size); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3554,7 +3518,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_s32 dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -3575,7 +3539,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c if (reg_size == 5) ins = (sljit_ins)1 << 26; - FAIL_IF(push_inst(compiler, VMSKLTZ | ins | (sljit_ins)(elem_size << 10) | FRD(TMP_FREG1) | FRJ(vreg))); + FAIL_IF(push_inst(compiler, VMSKLTZ | ins | (sljit_ins)(elem_size << 10) | FRD(TMP_FREG1) | FRJ(freg))); FAIL_IF(push_inst(compiler, VPICKVE2GR_U | (sljit_ins)(0x3c << 10) | RD(dst_r) | FRJ(TMP_FREG1))); @@ -3592,15 +3556,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); if (reg_size != 5 && reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -3614,12 +3577,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if (type & SLJIT_SIMD_TEST) return SLJIT_SUCCESS; - if (src2 & SLJIT_MEM) { - FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src2, src2w)); - FAIL_IF(push_inst(compiler, (reg_size == 4 ? VLD : XVLD) | FRD(TMP_FREG1) | RJ(src2) | IMM_I12(0))); - src2 = TMP_FREG1; - } - switch (SLJIT_SIMD_GET_OPCODE(type)) { case SLJIT_SIMD_OP2_AND: ins = VAND_V; @@ -3630,17 +3587,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = VXOR_V; break; - case SLJIT_SIMD_OP2_SHUFFLE: - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - - return push_inst(compiler, VSHUF_B | FRD(dst_vreg) | FRJ(src1_vreg) | FRK(src1_vreg) | FRA(src2)); } if (reg_size == 5) ins |= (sljit_ins)1 << 26; - return push_inst(compiler, ins | FRD(dst_vreg) | FRJ(src1_vreg) | FRK(src2)); + return push_inst(compiler, ins | FRD(dst_freg) | FRJ(src1_freg) | FRK(src2_freg)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, @@ -3653,45 +3605,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - if ((op & SLJIT_ATOMIC_USE_LS) || !LOONGARCH_SUPPORT_AMCAS) { - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - ins = LL_D; - break; - case SLJIT_MOV_S32: - case SLJIT_MOV32: - ins = LL_W; - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - return push_inst(compiler, ins | RD(dst_reg) | RJ(mem_reg)); - } - switch(GET_OPCODE(op)) { - case SLJIT_MOV_S8: - ins = LD_B; - break; case SLJIT_MOV_U8: ins = LD_BU; break; - case SLJIT_MOV_S16: - ins = LD_H; - break; case SLJIT_MOV_U16: ins = LD_HU; break; case SLJIT_MOV32: - case SLJIT_MOV_S32: ins = LD_W; break; case SLJIT_MOV_U32: @@ -3702,9 +3623,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler break; } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - return push_inst(compiler, ins | RD(dst_reg) | RJ(mem_reg) | IMM_I12(0)); } @@ -3721,48 +3639,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); - if ((op & SLJIT_ATOMIC_USE_LS) || !LOONGARCH_SUPPORT_AMCAS) { - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: - ins = SC_D; - break; - case SLJIT_MOV_S32: - case SLJIT_MOV32: - ins = SC_W; - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - FAIL_IF(push_inst(compiler, ADD_D | RD(OTHER_FLAG) | RJ(src_reg) | RK(TMP_ZERO))); - return push_inst(compiler, ins | RD(OTHER_FLAG) | RJ(mem_reg)); - } - switch (GET_OPCODE(op)) { - case SLJIT_MOV_S8: - ins = AMCAS_B; - break; case SLJIT_MOV_U8: ins = AMCAS_B; unsign = BSTRPICK_D | (7 << 16); break; - case SLJIT_MOV_S16: - ins = AMCAS_H; - break; case SLJIT_MOV_U16: ins = AMCAS_H; unsign = BSTRPICK_D | (15 << 16); break; case SLJIT_MOV32: - case SLJIT_MOV_S32: ins = AMCAS_W; break; case SLJIT_MOV_U32: @@ -3774,12 +3660,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler break; } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - if (op & SLJIT_SET_ATOMIC_STORED) { - FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG3) | RJ(temp_reg) | RK(TMP_ZERO))); - tmp = TMP_REG3; + FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RJ(temp_reg) | RK(TMP_ZERO))); + tmp = TMP_REG1; } FAIL_IF(push_inst(compiler, ins | RD(tmp) | RJ(mem_reg) | RK(src_reg))); if (!(op & SLJIT_SET_ATOMIC_STORED)) @@ -3788,8 +3671,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler if (unsign) FAIL_IF(push_inst(compiler, unsign | RD(tmp) | RJ(tmp))); - FAIL_IF(push_inst(compiler, XOR | RD(OTHER_FLAG) | RJ(tmp) | RK(temp_reg))); - return push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RJ(OTHER_FLAG) | IMM_I12(1)); + FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(tmp) | RK(temp_reg))); + return push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RJ(EQUAL_FLAG) | IMM_I12(1)); } static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c index 1b951fe18348..88eb30b7f163 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c @@ -249,8 +249,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define LDL (HI(26)) #define LDR (HI(27)) #define LDC1 (HI(53)) -#define LL (HI(48)) -#define LLD (HI(52)) #define LUI (HI(15)) #define LW (HI(35)) #define LWL (HI(34)) @@ -290,8 +288,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define ROTR (HI(0) | (1 << 21) | LO(2)) #define ROTRV (HI(0) | (1 << 6) | LO(6)) #endif /* SLJIT_MIPS_REV >= 2 */ -#define SC (HI(56)) -#define SCD (HI(60)) #define SD (HI(63)) #define SDL (HI(44)) #define SDR (HI(45)) @@ -312,7 +308,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define SWL (HI(42)) #define SWR (HI(46)) #define SWC1 (HI(57)) -#define SYNC (HI(0) | LO(15)) #define TRUNC_W_S (HI(17) | FMT_S | LO(13)) #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define WSBH (HI(31) | (2 << 6) | LO(32)) @@ -386,21 +381,11 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) fr -= SLJIT_F64_SECOND(0); - return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches)) - || (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0) + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); } -static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(vr); - SLJIT_UNUSED_ARG(type); - - /* SIMD is not supported. */ - return 0; -} - #endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_ARGUMENT_CHECKS */ static void get_cpu_features(void) @@ -872,8 +857,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_CMOV: case SLJIT_HAS_PREFETCH: - case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: return 1; case SLJIT_HAS_CTZ: @@ -945,22 +928,17 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit #endif SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); sljit_ins base; sljit_s32 i, tmp, offset; sljit_s32 arg_count, word_arg_count, float_arg_count; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -1160,18 +1138,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -2490,12 +2462,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); #endif /* SLJIT_MIPS_REV >= 6 */ - case SLJIT_MEMORY_BARRIER: -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) - return push_inst(compiler, SYNC, UNMOVABLE_INS); -#else /* SLJIT_MIPS_REV < 1 */ - return SLJIT_ERR_UNSUPPORTED; -#endif /* SLJIT_MIPS_REV >= 1 */ case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -3346,7 +3312,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: case SLJIT_CARRY: - case SLJIT_ATOMIC_STORED: BR_Z(OTHER_FLAG); break; case SLJIT_GREATER_EQUAL: @@ -3355,7 +3320,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: case SLJIT_NOT_CARRY: - case SLJIT_ATOMIC_NOT_STORED: BR_NZ(OTHER_FLAG); break; case SLJIT_F_NOT_EQUAL: @@ -4245,80 +4209,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil #undef TO_ARGW_HI -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst_reg, - sljit_s32 mem_reg) -{ - sljit_ins ins; - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - ins = LLD; - break; -#endif /* SLJIT_CONFIG_MIPS_64 */ - case SLJIT_MOV_S32: - case SLJIT_MOV32: - ins = LL; - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - return push_inst(compiler, ins | T(dst_reg) | S(mem_reg), DR(dst_reg)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_reg, - sljit_s32 mem_reg, - sljit_s32 temp_reg) -{ - sljit_ins ins; - - /* temp_reg == mem_reg is undefined so use another temp register */ - SLJIT_UNUSED_ARG(temp_reg); - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); - - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - ins = SCD; - break; -#endif /* SLJIT_CONFIG_RISCV_64 */ - case SLJIT_MOV_S32: - case SLJIT_MOV32: - op |= SLJIT_32; - ins = SC; - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src_reg) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG)); - return push_inst(compiler, ins | TA(OTHER_FLAG) | S(mem_reg), OTHER_FLAG); -} - SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c b/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c index 3d2268e896bf..1f17d90423eb 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c @@ -187,12 +187,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define LD (HI(58) | 0) #define LFD (HI(50)) #define LFS (HI(48)) -#define LDARX (HI(31) | LO(84)) #if defined(_ARCH_PWR7) && _ARCH_PWR7 #define LDBRX (HI(31) | LO(532)) #endif /* POWER7 */ #define LHBRX (HI(31) | LO(790)) -#define LWARX (HI(31) | LO(20)) #define LWBRX (HI(31) | LO(534)) #define LWZ (HI(32)) #define MFCR (HI(31) | LO(19)) @@ -233,7 +231,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #if defined(_ARCH_PWR7) && _ARCH_PWR7 #define STDBRX (HI(31) | LO(660)) #endif /* POWER7 */ -#define STDCX (HI(31) | LO(214)) #define STDU (HI(62) | 1) #define STDUX (HI(31) | LO(181)) #define STFD (HI(54)) @@ -242,14 +239,12 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define STHBRX (HI(31) | LO(918)) #define STW (HI(36)) #define STWBRX (HI(31) | LO(662)) -#define STWCX (HI(31) | LO(150)) #define STWU (HI(37)) #define STWUX (HI(31) | LO(183)) #define SUBF (HI(31) | LO(40)) #define SUBFC (HI(31) | LO(8)) #define SUBFE (HI(31) | LO(136)) #define SUBFIC (HI(8)) -#define SYNC (HI(31) | LO(598)) #define XOR (HI(31) | LO(316)) #define XORI (HI(26)) #define XORIS (HI(27)) @@ -319,11 +314,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i { sljit_sw diff; sljit_uw target_addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; - sljit_uw orig_addr = jump->addr; - SLJIT_UNUSED_ARG(executable_offset); - jump->addr = jump_addr; #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL)) goto exit; @@ -337,9 +328,6 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i else { SLJIT_ASSERT(jump->u.label != NULL); target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; - - if (jump->u.label->size > orig_addr) - jump_addr = (sljit_uw)(code + orig_addr); } #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -347,7 +335,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i goto keep_address; #endif - diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)target_addr - (sljit_sw)code_ptr - executable_offset; if (jump->flags & IS_COND) { if (diff <= 0x7fff && diff >= -0x8000) { @@ -559,10 +547,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if (jump->flags & IS_COND) { if (diff <= (0x7fff / SSIZE_OF(ins)) && diff >= (-0x8000 / SSIZE_OF(ins))) @@ -608,9 +592,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; -#if (defined SLJIT_DEBUG && SLJIT_DEBUG) - sljit_uw jump_addr; -#endif SLJIT_NEXT_DEFINE_TYPES; sljit_sw executable_offset; @@ -667,11 +648,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count += jump->flags >> JUMP_SIZE_SHIFT; -#if (defined SLJIT_DEBUG && SLJIT_DEBUG) - jump_addr = (sljit_uw)code_ptr; -#endif + jump->addr = (sljit_uw)code_ptr; code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); - SLJIT_ASSERT(((sljit_uw)code_ptr - jump_addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); + SLJIT_ASSERT(((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { jump->addr = (sljit_uw)code_ptr; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -769,8 +748,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_ROT: case SLJIT_HAS_PREFETCH: - case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: return 1; case SLJIT_HAS_CTZ: @@ -868,11 +845,9 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flag #define STACK_MAX_DISTANCE (0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); sljit_s32 i, tmp, base, offset; sljit_s32 word_arg_count = 0; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); @@ -881,11 +856,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 0) + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -989,18 +962,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 0) + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); @@ -1431,8 +1399,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #else return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); #endif - case SLJIT_MEMORY_BARRIER: - return push_inst(compiler, SYNC); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2456,7 +2422,6 @@ static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type /* fallthrough */ case SLJIT_EQUAL: - case SLJIT_ATOMIC_STORED: return (12 << 21) | (2 << 16); case SLJIT_CARRY: @@ -2465,7 +2430,6 @@ static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type /* fallthrough */ case SLJIT_NOT_EQUAL: - case SLJIT_ATOMIC_NOT_STORED: return (4 << 21) | (2 << 16); case SLJIT_LESS: @@ -2722,12 +2686,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co break; case SLJIT_EQUAL: - case SLJIT_ATOMIC_STORED: bit = 2; break; case SLJIT_NOT_EQUAL: - case SLJIT_ATOMIC_NOT_STORED: bit = 2; invert = 1; break; @@ -3144,78 +3106,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler return push_inst(compiler, INST_CODE_AND_DST(inst, DOUBLE_DATA, freg) | A(mem & REG_MASK) | IMM(memw)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst_reg, - sljit_s32 mem_reg) -{ - sljit_ins ins; - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - ins = LDARX; - break; -#endif /* SLJIT_CONFIG_RISCV_64 */ - case SLJIT_MOV_U32: - case SLJIT_MOV32: - ins = LWARX; - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - return push_inst(compiler, ins | D(dst_reg) | B(mem_reg)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_reg, - sljit_s32 mem_reg, - sljit_s32 temp_reg) -{ - sljit_ins ins; - - /* temp_reg == mem_reg is undefined so use another temp register */ - SLJIT_UNUSED_ARG(temp_reg); - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); - - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - ins = STDCX | 0x1; - break; -#endif /* SLJIT_CONFIG_RISCV_64 */ - case SLJIT_MOV_U32: - case SLJIT_MOV32: - ins = STWCX | 0x1; - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - return push_inst(compiler, ins | D(src_reg) | B(mem_reg)); -} - SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c index d3ba46dba8b3..d86100a80cef 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeRISCV_common.c @@ -50,9 +50,6 @@ typedef sljit_u32 sljit_ins; #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) -#define TMP_VREG1 (SLJIT_NUMBER_OF_VECTOR_REGISTERS + 1) -#define TMP_VREG2 (SLJIT_NUMBER_OF_VECTOR_REGISTERS + 2) - static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { 0, 10, 11, 12, 13, 14, 15, 16, 17, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 2, 6, 1, 7, 5, 28 }; @@ -61,10 +58,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { 0, 10, 11, 12, 13, 14, 15, 16, 17, 2, 3, 4, 5, 6, 7, 28, 29, 30, 31, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 9, 8, 0, 1, }; -static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 -}; - /* --------------------------------------------------------------------- */ /* Instrucion forms */ /* --------------------------------------------------------------------- */ @@ -75,9 +68,6 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define FRD(rd) ((sljit_ins)freg_map[rd] << 7) #define FRS1(rs1) ((sljit_ins)freg_map[rs1] << 15) #define FRS2(rs2) ((sljit_ins)freg_map[rs2] << 20) -#define VRD(rd) ((sljit_ins)vreg_map[rd] << 7) -#define VRS1(rs1) ((sljit_ins)vreg_map[rs1] << 15) -#define VRS2(rs2) ((sljit_ins)vreg_map[rs2] << 20) #define IMM_I(imm) ((sljit_ins)(imm) << 20) #define IMM_S(imm) ((((sljit_ins)(imm) & 0xfe0) << 20) | (((sljit_ins)(imm) & 0x1f) << 7)) @@ -87,15 +77,6 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define F12(f) ((sljit_ins)(f) << 20) #define F7(f) ((sljit_ins)(f) << 25) -/* Vector instruction types. */ -#define OPFVF (F3(0x5) | OPC(0x57)) -#define OPFVV (F3(0x1) | OPC(0x57)) -#define OPIVI (F3(0x3) | OPC(0x57)) -#define OPIVV (F3(0x0) | OPC(0x57)) -#define OPIVX (F3(0x4) | OPC(0x57)) -#define OPMVV (F3(0x2) | OPC(0x57)) -#define OPMVX (F3(0x6) | OPC(0x57)) - #define ADD (F7(0x0) | F3(0x0) | OPC(0x33)) #define ADDI (F3(0x0) | OPC(0x13)) #define AND (F7(0x0) | F3(0x7) | OPC(0x33)) @@ -107,16 +88,11 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define BGE (F3(0x5) | OPC(0x63)) #define BLTU (F3(0x6) | OPC(0x63)) #define BGEU (F3(0x7) | OPC(0x63)) -#if defined __riscv_zbb -#define CLZ (F7(0x30) | F3(0x1) | OPC(0x13)) -#define CTZ (F7(0x30) | F12(0x1) | F3(0x1) | OPC(0x13)) -#endif /* __riscv_zbb */ #define DIV (F7(0x1) | F3(0x4) | OPC(0x33)) #define DIVU (F7(0x1) | F3(0x5) | OPC(0x33)) #define EBREAK (F12(0x1) | F3(0x0) | OPC(0x73)) #define FADD_S (F7(0x0) | F3(0x7) | OPC(0x53)) #define FDIV_S (F7(0xc) | F3(0x7) | OPC(0x53)) -#define FENCE (F3(0x0) | OPC(0xf)) #define FEQ_S (F7(0x50) | F3(0x2) | OPC(0x53)) #define FLD (F3(0x3) | OPC(0x7)) #define FLE_S (F7(0x50) | F3(0x0) | OPC(0x53)) @@ -140,7 +116,6 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define LD (F3(0x3) | OPC(0x3)) #define LUI (OPC(0x37)) #define LW (F3(0x2) | OPC(0x3)) -#define LR (F7(0x8) | OPC(0x2f)) #define MUL (F7(0x1) | F3(0x0) | OPC(0x33)) #define MULH (F7(0x1) | F3(0x1) | OPC(0x33)) #define MULHU (F7(0x1) | F3(0x3) | OPC(0x33)) @@ -148,73 +123,21 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define ORI (F3(0x6) | OPC(0x13)) #define REM (F7(0x1) | F3(0x6) | OPC(0x33)) #define REMU (F7(0x1) | F3(0x7) | OPC(0x33)) -#if defined __riscv_zbb -#if defined SLJIT_CONFIG_RISCV_32 -#define REV8 (F12(0x698) | F3(0x5) | OPC(0x13)) -#elif defined SLJIT_CONFIG_RISCV_64 -#define REV8 (F12(0x6b8) | F3(0x5) | OPC(0x13)) -#endif /* SLJIT_CONFIG_RISCV_32 */ -#define ROL (F7(0x30) | F3(0x1) | OPC(0x33)) -#define ROR (F7(0x30) | F3(0x5) | OPC(0x33)) -#define RORI (F7(0x30) | F3(0x5) | OPC(0x13)) -#endif /* __riscv_zbb */ -#define SC (F7(0xc) | OPC(0x2f)) #define SD (F3(0x3) | OPC(0x23)) -#if defined __riscv_zbb -#define SEXTB (F7(0x30) | F12(0x4) | F3(0x1) | OPC(0x13)) -#define SEXTH (F7(0x30) | F12(0x5) | F3(0x1) | OPC(0x13)) -#endif /* __riscv_zbb */ -#if defined __riscv_zba -#define SH1ADD (F7(0x10) | F3(0x2) | OPC(0x33)) -#define SH2ADD (F7(0x10) | F3(0x4) | OPC(0x33)) -#define SH3ADD (F7(0x10) | F3(0x6) | OPC(0x33)) -#endif /* __riscv_zba */ #define SLL (F7(0x0) | F3(0x1) | OPC(0x33)) -#define SLLI (F3(0x1) | OPC(0x13)) +#define SLLI (IMM_I(0x0) | F3(0x1) | OPC(0x13)) #define SLT (F7(0x0) | F3(0x2) | OPC(0x33)) #define SLTI (F3(0x2) | OPC(0x13)) #define SLTU (F7(0x0) | F3(0x3) | OPC(0x33)) #define SLTUI (F3(0x3) | OPC(0x13)) #define SRL (F7(0x0) | F3(0x5) | OPC(0x33)) -#define SRLI (F3(0x5) | OPC(0x13)) +#define SRLI (IMM_I(0x0) | F3(0x5) | OPC(0x13)) #define SRA (F7(0x20) | F3(0x5) | OPC(0x33)) -#define SRAI (F7(0x20) | F3(0x5) | OPC(0x13)) +#define SRAI (IMM_I(0x400) | F3(0x5) | OPC(0x13)) #define SUB (F7(0x20) | F3(0x0) | OPC(0x33)) #define SW (F3(0x2) | OPC(0x23)) -#define VAND_VV (F7(0x13) | OPIVV) -#define VFMV_FS (F7(0x21) | OPFVV) -#define VFMV_SF (F7(0x21) | OPFVF) -#define VFMV_VF (F7(0x2f) | OPFVF) -#define VFWCVT_FFV (F7(0x25) | (0xc << 15) | OPFVV) -#define VL (F7(0x1) | OPC(0x7)) -#define VMSLE_VI (F7(0x3b) | OPIVI) -#define VMV_SX (F7(0x21) | OPMVX) -#define VMV_VI (F7(0x2f) | OPIVI) -#define VMV_VV (F7(0x2f) | OPIVV) -#define VMV_VX (F7(0x2f) | OPIVX) -#define VMV_XS (F7(0x21) | OPMVV) -#define VOR_VV (F7(0x15) | OPIVV) -#define VSETIVLI (F7(0x60) | F3(0x7) | OPC(0x57)) -#define VS (F7(0x1) | OPC(0x27)) -#define VSLIDEDOWN_VX (F7(0x1f) | OPIVX) -#define VSLIDEDOWN_VI (F7(0x1f) | OPIVI) -#define VSLIDEUP_VX (F7(0x1d) | OPIVX) -#define VSLIDEUP_VI (F7(0x1d) | OPIVI) -#define VRGATHER_VI (F7(0x19) | OPIVI) -#define VRGATHER_VV (F7(0x19) | OPIVV) -#define VXOR_VV (F7(0x17) | OPIVV) -#define VZEXT_VF2 (F7(0x25) | (0x6 << 15) | OPMVV) -#define VZEXT_VF4 (F7(0x25) | (0x4 << 15) | OPMVV) -#define VZEXT_VF8 (F7(0x25) | (0x2 << 15) | OPMVV) #define XOR (F7(0x0) | F3(0x4) | OPC(0x33)) #define XORI (F3(0x4) | OPC(0x13)) -#if defined __riscv_zbb -#if defined SLJIT_CONFIG_RISCV_32 -#define ZEXTH (F7(0x4) | F3(0x4) | OPC(0x33)) -#elif defined SLJIT_CONFIG_RISCV_64 -#define ZEXTH (F7(0x4) | F3(0x4) | OPC(0x3B)) -#endif /* SLJIT_CONFIG_RISCV_32 */ -#endif /* __riscv_zbb */ #define SIMM_MAX (0x7ff) #define SIMM_MIN (-0x800) @@ -228,7 +151,7 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define S32_MIN (-0x80000000l) #define S44_MAX (0x7fffffff7ffl) #define S52_MAX (0x7ffffffffffffl) -#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { @@ -244,15 +167,14 @@ static sljit_s32 push_imm_s_inst(struct sljit_compiler *compiler, sljit_ins ins, return push_inst(compiler, ins | IMM_S(imm)); } -static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) +static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; - sljit_uw orig_addr = jump->addr; - SLJIT_UNUSED_ARG(executable_offset); + sljit_ins *inst; + + inst = (sljit_ins *)jump->addr; - jump->addr = jump_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) goto exit; @@ -260,23 +182,20 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i target_addr = jump->u.target; else { SLJIT_ASSERT(jump->u.label != NULL); - target_addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - - if (jump->u.label->size > orig_addr) - jump_addr = (sljit_uw)(code + orig_addr); + target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } - diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)target_addr - (sljit_sw)inst - executable_offset; if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); if (diff >= BRANCH_MIN && diff <= BRANCH_MAX) { - code_ptr--; - code_ptr[0] = (code_ptr[0] & 0x1fff07f) ^ 0x1000; + inst--; + inst[0] = (inst[0] & 0x1fff07f) ^ 0x1000; jump->flags |= PATCH_B; - jump->addr = (sljit_uw)code_ptr; - return code_ptr; + jump->addr = (sljit_uw)inst; + return inst; } diff -= SSIZE_OF(ins); @@ -285,62 +204,62 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i if (diff >= JUMP_MIN && diff <= JUMP_MAX) { if (jump->flags & IS_COND) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - code_ptr[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; -#else /* !SLJIT_CONFIG_RISCV_32 */ - code_ptr[-1] -= (sljit_ins)(5 * sizeof(sljit_ins)) << 7; -#endif /* SLJIT_CONFIG_RISCV_32 */ + inst[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; +#else + inst[-1] -= (sljit_ins)(5 * sizeof(sljit_ins)) << 7; +#endif } jump->flags |= PATCH_J; - return code_ptr; + return inst; } #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) if (diff >= S32_MIN && diff <= S32_MAX) { if (jump->flags & IS_COND) - code_ptr[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; + inst[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_REL32; - code_ptr[1] = code_ptr[0]; - return code_ptr + 1; + inst[1] = inst[0]; + return inst + 1; } if (target_addr <= (sljit_uw)S32_MAX) { if (jump->flags & IS_COND) - code_ptr[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; + inst[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_ABS32; - code_ptr[1] = code_ptr[0]; - return code_ptr + 1; + inst[1] = inst[0]; + return inst + 1; } if (target_addr <= S44_MAX) { if (jump->flags & IS_COND) - code_ptr[-1] -= (sljit_ins)(2 * sizeof(sljit_ins)) << 7; + inst[-1] -= (sljit_ins)(2 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_ABS44; - code_ptr[3] = code_ptr[0]; - return code_ptr + 3; + inst[3] = inst[0]; + return inst + 3; } if (target_addr <= S52_MAX) { if (jump->flags & IS_COND) - code_ptr[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; + inst[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7; jump->flags |= PATCH_ABS52; - code_ptr[4] = code_ptr[0]; - return code_ptr + 4; + inst[4] = inst[0]; + return inst + 4; } -#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif exit: #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - code_ptr[1] = code_ptr[0]; - return code_ptr + 1; -#else /* !SLJIT_CONFIG_RISCV_32 */ - code_ptr[5] = code_ptr[0]; - return code_ptr + 5; -#endif /* SLJIT_CONFIG_RISCV_32 */ + inst[1] = inst[0]; + return inst + 1; +#else + inst[5] = inst[0]; + return inst + 5; +#endif } #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) @@ -348,21 +267,16 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_uw addr; - sljit_uw jump_addr = (sljit_uw)code_ptr; sljit_sw diff; SLJIT_UNUSED_ARG(executable_offset); SLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT)); if (jump->flags & JUMP_ADDR) addr = jump->u.target; - else { + else addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset); - if (jump->u.label->size > jump->addr) - jump_addr = (sljit_uw)(code + jump->addr); - } - - diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset); + diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); if (diff >= S32_MIN && diff <= S32_MAX) { SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT)); @@ -402,7 +316,7 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : TMP_REG1; #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) sljit_sw high; -#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif SLJIT_UNUSED_ARG(executable_offset); #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) @@ -423,7 +337,7 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr); return; } -#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif if ((addr & 0x800) != 0) addr += 0x1000; @@ -539,10 +453,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) } else { /* Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH_MIN / SSIZE_OF(ins))) total_size = 0; @@ -564,10 +474,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (!(jump->flags & JUMP_ADDR)) { /* Real size minus 1. Unit size: instruction. */ diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins))) total_size = 1; @@ -646,7 +552,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (next_min_addr == next_jump_addr) { if (!(jump->flags & JUMP_MOV_ADDR)) { word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT); - code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); + jump->addr = (sljit_uw)code_ptr; + code_ptr = detect_jump_type(jump, code, executable_offset); SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins))); } else { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) @@ -735,7 +642,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) return (SLJIT_IS_FPU_AVAILABLE) != 0; #elif defined(__riscv_float_abi_soft) return 0; -#else /* !SLJIT_IS_FPU_AVAILABLE && !__riscv_float_abi_soft */ +#else return 1; #endif /* SLJIT_IS_FPU_AVAILABLE */ case SLJIT_HAS_ZERO_REGISTER: @@ -743,19 +650,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) case SLJIT_HAS_COPY_F64: #endif /* !SLJIT_CONFIG_RISCV_64 */ - case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: -#ifdef __riscv_vector - case SLJIT_HAS_SIMD: -#endif /* __riscv_vector */ - return 1; -#ifdef __riscv_zbb - case SLJIT_HAS_CLZ: - case SLJIT_HAS_CTZ: - case SLJIT_HAS_REV: - case SLJIT_HAS_ROT: return 1; -#endif /* __riscv_zbb */ default: return 0; } @@ -813,36 +708,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define STACK_STORE SW #define STACK_LOAD LW -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else #define STACK_STORE SD #define STACK_LOAD LD -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #include "sljitNativeRISCV_32.c" -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else #include "sljitNativeRISCV_64.c" -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif #define STACK_MAX_DISTANCE (-SIMM_MIN) static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw); SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); sljit_s32 i, tmp, offset; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1); #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { @@ -850,9 +741,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi local_size += SSIZE_OF(sw); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; compiler->local_size = local_size; @@ -887,7 +778,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi /* This alignment is valid because offset is not used after storing FPU regs. */ if ((offset & SSIZE_OF(sw)) != 0) offset -= SSIZE_OF(sw); -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif tmp = SLJIT_FS0 - fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { @@ -930,18 +821,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #undef STACK_MAX_DISTANCE SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches = ENTER_GET_FLOAT_REGS(scratches); - sljit_s32 fsaveds = ENTER_GET_FLOAT_REGS(saveds); - CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { @@ -949,9 +835,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp local_size += SSIZE_OF(sw); local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; return SLJIT_SUCCESS; @@ -997,7 +883,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit /* This alignment is valid because offset is not used after storing FPU regs. */ if ((offset & SSIZE_OF(sw)) != 0) offset -= SSIZE_OF(sw); -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif tmp = SLJIT_FS0 - compiler->fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { @@ -1053,9 +939,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define ARCH_32_64(a, b) a -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else #define ARCH_32_64(a, b) b -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif static const sljit_ins data_transfer_insts[16 + 4] = { /* u w s */ ARCH_32_64(F3(0x2) | OPC(0x23) /* sw */, F3(0x3) | OPC(0x23) /* sd */), @@ -1148,9 +1034,6 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl sljit_s32 base = arg & REG_MASK; sljit_s32 tmp_r = (flags & MEM_USE_TMP2) ? TMP_REG2 : TMP_REG1; sljit_sw offset, argw_hi; -#if defined __riscv_zba - sljit_ins ins = ADD; -#endif /* __riscv_zba */ SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -1161,20 +1044,6 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { argw &= 0x3; -#if defined __riscv_zba - switch (argw) { - case 1: - ins = SH1ADD; - break; - case 2: - ins = SH2ADD; - break; - case 3: - ins = SH3ADD; - break; - } - FAIL_IF(push_inst(compiler, ins | RD(tmp_r) | RS1(OFFS_REG(arg)) | RS2(base))); -#else /* !__riscv_zba */ /* Using the cache. */ if (argw == compiler->cache_argw) { if (arg == compiler->cache_arg) @@ -1206,8 +1075,6 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl } else FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(!argw ? OFFS_REG(arg) : TMP_REG3))); -#endif /* __riscv_zba */ - return push_mem_inst(compiler, flags, reg, tmp_r, 0); } @@ -1294,7 +1161,7 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji #define WORD_32 0x08 #define IMM_EXTEND(v) (IMM_I((op & SLJIT_32) ? (v) : (32 + (v)))) #endif /* SLJIT_CONFIG_RISCV_32 */ -#ifndef __riscv_zbb + static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) { sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ); @@ -1397,7 +1264,6 @@ static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | WORD | RD(dst) | RS1(dst) | IMM_I(word_size - 16))); return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); } -#endif /* !__riscv_zbb */ #define EMIT_LOGICAL(op_imm, op_reg) \ if (flags & SRC2_IMM) { \ @@ -1443,9 +1309,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; case SLJIT_MOV_S8: -#if defined __riscv_zbb - return push_inst(compiler, SEXTB | RD(dst) | RS1(src2)); -#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(24))); @@ -1453,12 +1316,8 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } SLJIT_ASSERT(dst == src2); return SLJIT_SUCCESS; -#endif /* __riscv_zbb */ case SLJIT_MOV_U16: -#if defined __riscv_zbb - return push_inst(compiler, ZEXTH | RD(dst) | RS1(src2)); -#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16))); @@ -1466,12 +1325,8 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } SLJIT_ASSERT(dst == src2); return SLJIT_SUCCESS; -#endif /* __riscv_zbb */ case SLJIT_MOV_S16: -#if defined __riscv_zbb - return push_inst(compiler, SEXTH | RD(dst) | RS1(src2)); -#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16))); @@ -1479,7 +1334,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } SLJIT_ASSERT(dst == src2); return SLJIT_SUCCESS; -#endif /* !__riscv_zbb */ #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) case SLJIT_MOV_U32: @@ -1500,59 +1354,24 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl #endif /* SLJIT_CONFIG_RISCV_64 */ case SLJIT_CLZ: -#if defined __riscv_zbb - return push_inst(compiler, CLZ | WORD | RD(dst) | RS1(src2)); -#endif /* __riscv_zbb */ case SLJIT_CTZ: -#if defined __riscv_zbb - return push_inst(compiler, CTZ | WORD | RD(dst) | RS1(src2)); -#else /* !__riscv_zbb */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); return emit_clz_ctz(compiler, op, dst, src2); -#endif /* __riscv_zbb */ case SLJIT_REV: -#if defined __riscv_zbb - SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); - FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2))); -#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64 - if (op & SLJIT_32) - return push_inst(compiler, SRAI | RD(dst) | RS1(dst) | IMM_I(32)); - return SLJIT_SUCCESS; -#else /* !SLJIT_CONFIG_RISCV_64 */ - return SLJIT_SUCCESS; -#endif /* SLJIT_CONFIG_RISCV_64 */ -#endif /* __riscv_zbb */ case SLJIT_REV_S32: -#if ((defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || defined __riscv_zbb) +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) case SLJIT_REV_U32: -#endif /* SLJIT_CONFIG_RISCV_32 || __riscv_zbb */ +#endif /* SLJIT_CONFIG_RISCV_32 */ SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); -#if defined __riscv_zbb - FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2))); -#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64 - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U32 ? SRLI : SRAI )| RD(dst) | RS1(dst) | IMM_I(32)); -#else /* !SLJIT_CONFIG_RISCV_64 */ - return SLJIT_SUCCESS; -#endif /* SLJIT_CONFIG_RISCV_64 */ -#else /* !__riscv_zbb */ return emit_rev(compiler, op, dst, src2); -#endif /* __riscv_zbb */ + case SLJIT_REV_U16: case SLJIT_REV_S16: SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM)); -#if defined __riscv_zbb - FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2))); -#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64 - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI )| RD(dst) | RS1(dst) | IMM_I(48)); -#else /* !SLJIT_CONFIG_RISCV_64 */ - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | RD(dst) | RS1(dst) | IMM_I(16)); -#endif /* SLJIT_CONFIG_RISCV_64 */ -#else /* !__riscv_zbb */ return emit_rev16(compiler, op, dst, src2); -#endif /* __riscv_zbb */ -#if ((defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) && !defined __riscv_zbb) +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) case SLJIT_REV_U32: SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1); FAIL_IF(emit_rev(compiler, op, dst, src2)); @@ -1560,7 +1379,8 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(32))); return push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32)); -#endif /* SLJIT_CONFIG_RISCV_64 && !__riscv_zbb */ +#endif /* SLJIT_CONFIG_RISCV_32 */ + case SLJIT_ADD: /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; @@ -1848,16 +1668,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_ROTR: if (flags & SRC2_IMM) { SLJIT_ASSERT(src2 != 0); -#if defined __riscv_zbb - if (GET_OPCODE(op) == SLJIT_ROTL) { -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - src2 = ((op & SLJIT_32) ? 32 : 64) - src2; -#else /* !SLJIT_CONFIG_RISCV_64 */ - src2 = 32 - src2; -#endif /* SLJIT_CONFIG_RISCV_64 */ - } - return push_inst(compiler, RORI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)); -#else /* !__riscv_zbb */ + op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLI : SRLI; FAIL_IF(push_inst(compiler, op_imm | WORD | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2))); @@ -1869,12 +1680,8 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLI : SLLI; FAIL_IF(push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)); -#endif /* !__riscv_zbb */ } -#if defined __riscv_zbb - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_ROTL ? ROL : ROR) | WORD | RD(dst) | RS1(src1) | RS2(src2)); -#else /* !__riscv_zbb */ if (src2 == TMP_ZERO) { if (dst != src1) return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(0)); @@ -1887,7 +1694,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl op_reg = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL; FAIL_IF(push_inst(compiler, op_reg | WORD | RD(dst) | RS1(src1) | RS2(EQUAL_FLAG))); return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)); -#endif /* !riscv_zbb */ + default: SLJIT_UNREACHABLE(); return SLJIT_SUCCESS; @@ -2074,8 +1881,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, DIVU | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)); case SLJIT_DIV_SW: return push_inst(compiler, DIV | WORD | RD(SLJIT_R0) | RS1(SLJIT_R0) | RS2(SLJIT_R1)); - case SLJIT_MEMORY_BARRIER: - return push_inst(compiler, FENCE | 0x0ff00000); case SLJIT_ENDBR: case SLJIT_SKIP_FRAMES_BEFORE_RETURN: return SLJIT_SUCCESS; @@ -2098,7 +1903,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) if (op & SLJIT_32) flags = INT_DATA | SIGNED_DATA; -#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif switch (GET_OPCODE(op)) { case SLJIT_MOV: @@ -2106,7 +1911,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_U32: case SLJIT_MOV_S32: case SLJIT_MOV32: -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, srcw); @@ -2118,7 +1923,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile /* Logical operators have no W variant, so sign extended input is necessary for them. */ case SLJIT_MOV32: return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw); -#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif case SLJIT_MOV_U8: return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); @@ -2171,7 +1976,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (src2 == SLJIT_IMM) src2w = (sljit_s32)src2w; } -#endif /* SLJIT_CONFIG_RISCV_64 */ +#endif switch (GET_OPCODE(op)) { case SLJIT_ADD: @@ -2399,10 +2204,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_GP_REGISTER) return reg_map[reg]; - if (type == SLJIT_FLOAT_REGISTER) - return freg_map[reg]; + if (type != SLJIT_FLOAT_REGISTER) + return -1; - return vreg_map[reg]; + return freg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -2429,9 +2234,9 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) # define flags (sljit_u32)0 -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21; -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; if (src & SLJIT_MEM) { @@ -2445,15 +2250,15 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (dst & SLJIT_MEM) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) return emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else return emit_op_mem2(compiler, flags ? WORD_DATA : INT_DATA, TMP_REG2, dst, dstw, 0, 0); -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) # undef flags -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif } static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, @@ -2751,9 +2556,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define BRANCH_LENGTH ((sljit_ins)(3 * sizeof(sljit_ins)) << 7) -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else #define BRANCH_LENGTH ((sljit_ins)(7 * sizeof(sljit_ins)) << 7) -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif static sljit_ins get_jump_instruction(sljit_s32 type) { @@ -2768,7 +2573,6 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: case SLJIT_CARRY: - case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: case SLJIT_ORDERED_NOT_EQUAL: @@ -2787,7 +2591,6 @@ static sljit_ins get_jump_instruction(sljit_s32 type) case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: case SLJIT_NOT_CARRY: - case SLJIT_ATOMIC_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: case SLJIT_UNORDERED_OR_EQUAL: @@ -2884,7 +2687,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler } if (src2 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, flags | (src1 == TMP_REG1 ? MEM_USE_TMP2 : 0), src2_tmp_reg, src2, src2w, 0, 0)); + PTR_FAIL_IF(emit_op_mem2(compiler, flags, src2_tmp_reg, src2, src2w, 0, 0)); src2 = src2_tmp_reg; } @@ -3022,9 +2825,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 saved_op = op; #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) sljit_s32 mem_type = WORD_DATA; -#else /* !SLJIT_CONFIG_RISCV_32 */ +#else sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; -#endif /* SLJIT_CONFIG_RISCV_32 */ +#endif CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type)); @@ -3059,10 +2862,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co src_r = dst_r; invert ^= 0x1; break; - case SLJIT_ATOMIC_STORED: - case SLJIT_ATOMIC_NOT_STORED: - invert ^= 0x1; - break; } } else { invert = 0; @@ -3267,561 +3066,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile #undef TO_ARGW_HI -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst_reg, - sljit_s32 mem_reg) -{ - sljit_ins ins; - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - ins = LR | (3 << 12); - break; -#endif /* SLJIT_CONFIG_RISCV_64 */ - case SLJIT_MOV_S32: - case SLJIT_MOV32: - ins = LR | (2 << 12); - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - return push_inst(compiler, ins | RD(dst_reg) | RS1(mem_reg)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_reg, - sljit_s32 mem_reg, - sljit_s32 temp_reg) -{ - sljit_ins ins; - - /* temp_reg == mem_reg is undefined so use another temp register */ - SLJIT_UNUSED_ARG(temp_reg); - - CHECK_ERROR(); - CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); - - if (op & SLJIT_ATOMIC_USE_CAS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - ins = SC | (3 << 12); - break; -#endif /* SLJIT_CONFIG_RISCV_64 */ - case SLJIT_MOV_S32: - case SLJIT_MOV32: - ins = SC | (2 << 12); - break; - - default: - return SLJIT_ERR_UNSUPPORTED; - } - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - return push_inst(compiler, ins | RD(OTHER_FLAG) | RS1(mem_reg) | RS2(src_reg)); -} - -/* - SEW = Selected element width - LMUL = Vector register group multiplier - - VLMUL values (in binary): - 100 : reserved - 101 : 1/8 - 110 : 1/4 - 111 : 1/2 - 000 : 1 - 001 : 2 - 010 : 4 - 011 : 8 -*/ - -static SLJIT_INLINE sljit_s32 sljit_emit_vsetivli(struct sljit_compiler *compiler, sljit_s32 type, sljit_ins vlmul) -{ - sljit_ins elem_size = (sljit_ins)SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_ins avl = (sljit_ins)1 << (SLJIT_SIMD_GET_REG_SIZE(type) - elem_size); - - return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | (elem_size << 23) | (vlmul << 20) | (avl << 15)); -} - -static SLJIT_INLINE sljit_s32 sljit_emit_vsetivli_size(struct sljit_compiler *compiler, sljit_s32 reg_size, sljit_s32 elem_size) -{ - sljit_ins avl = (sljit_ins)1 << (reg_size - elem_size); - return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (avl << 15)); -} - -static sljit_s32 sljit_emit_vmem(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 elem_size, sljit_s32 mem, sljit_sw memw) -{ - sljit_s32 base = mem & REG_MASK; - - if (elem_size > 0) - ins |= (1 << 14) | ((sljit_ins)elem_size << 12); - - if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { - memw &= 0x3; - - if (SLJIT_UNLIKELY(memw)) { - FAIL_IF(push_inst(compiler, SLLI | RD(TMP_REG1) | RS1(OFFS_REG(mem)) | IMM_I(memw))); - } - - FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(base) | RS2(!memw ? OFFS_REG(mem) : TMP_REG1))); - return push_inst(compiler, ins | RS1(TMP_REG1)); - } - - if (memw == 0) - return push_inst(compiler, ins | RS1(base)); - - if (memw <= SIMM_MAX && memw >= SIMM_MIN) { - FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(base) | IMM_I(memw))); - return push_inst(compiler, ins | RS1(TMP_REG1)); - } - - FAIL_IF(load_immediate(compiler, TMP_REG1, memw, TMP_REG3)); - - if (base != 0) - FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(base))); - - return push_inst(compiler, ins | RS1(TMP_REG1)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, - sljit_s32 srcdst, sljit_sw srcdstw) -{ - sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); - sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_ins ins; - - CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); - - ADJUST_LOCAL_OFFSET(srcdst, srcdstw); - - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - - if (elem_size > 3) - elem_size = 3; - - FAIL_IF(sljit_emit_vsetivli_size(compiler, reg_size, elem_size)); - - if (srcdst & SLJIT_MEM) { - ins = (type & SLJIT_SIMD_STORE) ? VS : VL; - return sljit_emit_vmem(compiler, ins | VRD(vreg), elem_size, srcdst, srcdstw); - } - - if (type & SLJIT_SIMD_STORE) - ins = VRD(srcdst) | VRS1(vreg); - else - ins = VRD(vreg) | VRS1(srcdst); - - return push_inst(compiler, VMV_VV | ins); -} - -static sljit_s32 sljit_simd_get_mem_flags(sljit_s32 elem_size) -{ - switch (elem_size) { - case 0: - return BYTE_DATA; - case 1: - return HALF_DATA; -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - case 2: - return INT_DATA; -#endif /* SLJIT_CONFIG_RISCV_64 */ - default: - return WORD_DATA; - } -} - -static sljit_sw sljit_simd_get_imm(sljit_s32 elem_size, sljit_sw imm) -{ - switch (elem_size) { - case 0: - return (sljit_s8)imm; - case 1: - return (sljit_s16)imm; -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - case 2: - return (sljit_s32)imm; -#endif /* SLJIT_CONFIG_RISCV_64 */ - default: - return imm; - } -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, - sljit_s32 src, sljit_sw srcw) -{ - sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); - sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 flags; - - CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); - - ADJUST_LOCAL_OFFSET(src, srcw); - - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - -#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) - return SLJIT_ERR_UNSUPPORTED; -#else /* !SLJIT_CONFIG_RISCV_32 */ - if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) - return SLJIT_ERR_UNSUPPORTED; -#endif /* SLJIT_CONFIG_RISCV_32 */ - - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - - FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); - - if (type & SLJIT_SIMD_FLOAT) { - if (src == SLJIT_IMM) - return push_inst(compiler, VMV_VI | VRD(vreg) | ((sljit_ins)(srcw & 0x1f) << 15)); - - if (src & SLJIT_MEM) { - flags = (elem_size == 2) ? SINGLE_DATA : DOUBLE_DATA; - FAIL_IF(emit_op_mem(compiler, flags | LOAD_DATA, TMP_FREG1, src, srcw)); - src = TMP_FREG1; - } - - return push_inst(compiler, VFMV_VF | VRD(vreg) | FRS1(src)); - } - - if (src == SLJIT_IMM) { - srcw = sljit_simd_get_imm(elem_size, srcw); - - if (srcw >= -0x10 && srcw <= 0xf) - return push_inst(compiler, VMV_VI | VRD(vreg) | ((sljit_ins)(srcw & 0x1f) << 15)); - - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw, TMP_REG3)); - src = TMP_REG1; - } else if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, sljit_simd_get_mem_flags(elem_size) | LOAD_DATA, TMP_REG1, src, srcw)); - src = TMP_REG1; - } - - return push_inst(compiler, VMV_VX | VRD(vreg) | RS1(src)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, - sljit_s32 srcdst, sljit_sw srcdstw) -{ - sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); - sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 flags; - - CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); - - ADJUST_LOCAL_OFFSET(srcdst, srcdstw); - - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - -#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) - return SLJIT_ERR_UNSUPPORTED; -#else /* !SLJIT_CONFIG_RISCV_32 */ - if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) - return SLJIT_ERR_UNSUPPORTED; -#endif /* SLJIT_CONFIG_RISCV_32 */ - - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - - if (type & SLJIT_SIMD_STORE) { - FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (1 << 15))); - - if (lane_index > 0) { - FAIL_IF(push_inst(compiler, VSLIDEDOWN_VI | VRD(TMP_VREG1) | ((sljit_ins)lane_index << 15) | VRS2(vreg))); - vreg = TMP_VREG1; - } - - if (srcdst & SLJIT_MEM) - return sljit_emit_vmem(compiler, VS | VRD(vreg), elem_size, srcdst, srcdstw); - - if (type & SLJIT_SIMD_FLOAT) - return push_inst(compiler, VFMV_FS | FRD(srcdst) | VRS2(vreg)); - - FAIL_IF(push_inst(compiler, VMV_XS | RD(srcdst) | VRS2(vreg))); - -#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - if ((type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 2) - return SLJIT_SUCCESS; -#else /* !SLJIT_CONFIG_RISCV_32 */ - if ((type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3 || (elem_size == 2 && (type & SLJIT_32))) - return SLJIT_SUCCESS; -#endif /* SLJIT_CONFIG_RISCV_32 */ - - if (elem_size == 0) - return push_inst(compiler, ANDI | RD(srcdst) | RS1(srcdst) | IMM_I(0xff)); - -#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - flags = 16; -#else /* !SLJIT_CONFIG_RISCV_32 */ - flags = (elem_size == 1) ? 48 : 32; -#endif /* SLJIT_CONFIG_RISCV_32 */ - - FAIL_IF(push_inst(compiler, SLLI | RD(srcdst) | RS1(srcdst) | IMM_I(flags))); - return push_inst(compiler, SRLI | RD(srcdst) | RS1(srcdst) | IMM_I(flags)); - } - - if (type & SLJIT_SIMD_LANE_ZERO) { - FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); - FAIL_IF(push_inst(compiler, VMV_VI | VRD(vreg))); - } - - if (srcdst & SLJIT_MEM) { - FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (1 << 15))); - FAIL_IF(sljit_emit_vmem(compiler, VL | VRD(lane_index > 0 ? TMP_VREG1 : vreg), elem_size, srcdst, srcdstw)); - - if (lane_index == 0) - return SLJIT_SUCCESS; - - FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | ((sljit_ins)(lane_index + 1) << 15))); - return push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1)); - } - - if (!(type & SLJIT_SIMD_LANE_ZERO) || lane_index > 0) - FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | ((sljit_ins)(lane_index + 1) << 15))); - - if (type & SLJIT_SIMD_FLOAT) { - FAIL_IF(push_inst(compiler, VFMV_SF | VRD(lane_index > 0 ? TMP_VREG1 : vreg) | FRS1(srcdst))); - - if (lane_index == 0) - return SLJIT_SUCCESS; - - return push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1)); - } - - if (srcdst == SLJIT_IMM) { - srcdstw = sljit_simd_get_imm(elem_size, srcdstw); - FAIL_IF(load_immediate(compiler, TMP_REG1, srcdstw, TMP_REG3)); - srcdst = TMP_REG1; - } - - FAIL_IF(push_inst(compiler, VMV_SX | VRD(lane_index > 0 ? TMP_VREG1 : vreg) | RS1(srcdst))); - - if (lane_index == 0) - return SLJIT_SUCCESS; - - return push_inst(compiler, VSLIDEUP_VI | VRD(vreg) | ((sljit_ins)lane_index << 15) | VRS2(TMP_VREG1)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, - sljit_s32 src, sljit_s32 src_lane_index) -{ - sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); - sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - - CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); - - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - - if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) - return SLJIT_ERR_UNSUPPORTED; - - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - - FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); - - FAIL_IF(push_inst(compiler, VRGATHER_VI | VRD(vreg != src ? vreg : TMP_VREG1) | ((sljit_ins)src_lane_index << 15) | VRS2(src))); - if (vreg == src) - return push_inst(compiler, VMV_VV | VRD(vreg) | VRS1(TMP_VREG1)); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, - sljit_s32 src, sljit_sw srcw) -{ - sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); - sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); - sljit_ins ins; - - CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); - - ADJUST_LOCAL_OFFSET(src, srcw); - - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - -#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) - if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) - return SLJIT_ERR_UNSUPPORTED; -#else /* !SLJIT_CONFIG_RISCV_32 */ - if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) - return SLJIT_ERR_UNSUPPORTED; -#endif /* SLJIT_CONFIG_RISCV_32 */ - - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - - if ((src & SLJIT_MEM) || vreg == src) { - ins = (sljit_ins)1 << (reg_size - elem2_size); - FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (ins << 15))); - - if (src & SLJIT_MEM) - FAIL_IF(sljit_emit_vmem(compiler, VL | VRD(TMP_VREG1), elem_size, src, srcw)); - else - FAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG1) | VRS1(src))); - - src = TMP_VREG1; - } - - if (type & SLJIT_SIMD_FLOAT) { - FAIL_IF(sljit_emit_vsetivli(compiler, type, 0x7)); - return push_inst(compiler, VFWCVT_FFV | VRD(vreg) | VRS2(src)); - } - - ins = (sljit_ins)1 << (reg_size - elem2_size); - FAIL_IF(push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem2_size << 23) | (ins << 15))); - - switch (elem2_size - elem_size) { - case 1: - ins = VZEXT_VF2; - break; - case 2: - ins = VZEXT_VF4; - break; - default: - ins = VZEXT_VF8; - break; - } - - if (type & SLJIT_SIMD_EXTEND_SIGNED) - ins |= 1 << 15; - - return push_inst(compiler, ins | VRD(vreg) | VRS2(src)); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, - sljit_s32 dst, sljit_sw dstw) -{ - sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); - sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; - - CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); - - ADJUST_LOCAL_OFFSET(dst, dstw); - - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - - if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3) - return SLJIT_ERR_UNSUPPORTED; - - FAIL_IF(sljit_emit_vsetivli(compiler, type, 0)); - FAIL_IF(push_inst(compiler, VMV_VI | VRD(TMP_VREG1) | (0x0 << 15))); - FAIL_IF(push_inst(compiler, VMSLE_VI | VRD(TMP_VREG1) | (0x0 << 15) | VRS2(vreg))); - - FAIL_IF(sljit_emit_vsetivli_size(compiler, 2, 2)); - FAIL_IF(push_inst(compiler, VMV_XS | RD(dst_r) | VRS2(TMP_VREG1))); - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, (type & SLJIT_32) ? INT_DATA : WORD_DATA, dst_r, dst, dstw); - return SLJIT_SUCCESS; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) -{ - sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); - sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_ins ins = 0; - - CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); - - ADJUST_LOCAL_OFFSET(src2, src2w); - - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - - if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) - return SLJIT_ERR_UNSUPPORTED; - - if (type & SLJIT_SIMD_TEST) - return SLJIT_SUCCESS; - - switch (SLJIT_SIMD_GET_OPCODE(type)) { - case SLJIT_SIMD_OP2_AND: - ins = VAND_VV; - break; - case SLJIT_SIMD_OP2_OR: - ins = VOR_VV; - break; - case SLJIT_SIMD_OP2_XOR: - ins = VXOR_VV; - break; - case SLJIT_SIMD_OP2_SHUFFLE: - ins = VRGATHER_VV; - elem_size = 0; - break; - } - - if (elem_size > 3) - elem_size = 3; - - FAIL_IF(sljit_emit_vsetivli_size(compiler, reg_size, elem_size)); - - if (src2 & SLJIT_MEM) { - FAIL_IF(sljit_emit_vmem(compiler, VL | VRD(TMP_VREG1), elem_size, src2, src2w)); - src2 = TMP_VREG1; - } - - if (SLJIT_SIMD_GET_OPCODE(type) != SLJIT_SIMD_OP2_SHUFFLE) - return push_inst(compiler, ins | VRD(dst_vreg) | VRS1(src1_vreg) | VRS2(src2)); - - if (dst_vreg == src2) { - FAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG1) | VRS1(src2))); - src2 = TMP_VREG1; - } - - if (dst_vreg == src1_vreg) { - FAIL_IF(push_inst(compiler, VMV_VV | VRD(TMP_VREG2) | VRS1(src1_vreg))); - src1_vreg = TMP_VREG2; - } - - return push_inst(compiler, ins | VRD(dst_vreg) | VRS1(src2) | VRS2(src1_vreg)); -} - SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c b/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c index 7ce9f9fcdcc5..99e846350fdd 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeS390X.c @@ -1638,7 +1638,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F64: case SLJIT_HAS_SIMD: case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: return 1; case SLJIT_HAS_CTZ: @@ -1661,26 +1660,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) /* --------------------------------------------------------------------- */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_s32 offset, i, tmp; CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); /* Saved registers are stored in callee allocated save area. */ SLJIT_ASSERT(gpr(SLJIT_FIRST_SAVED_REG) == r6 && gpr(SLJIT_S0) == r13); - scratches = ENTER_GET_REGS(scratches); - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; - offset = 2 * SSIZE_OF(sw); if (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) { if (saved_arg_count == 0) { @@ -1764,12 +1756,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); compiler->local_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf; return SLJIT_SUCCESS; @@ -1931,7 +1923,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return SLJIT_SUCCESS; case SLJIT_DIV_S32: case SLJIT_DIVMOD_S32: - FAIL_IF(push_inst(compiler, 0xeb00000000dc /* srak */ | R36A(tmp0) | R32A(arg0) | (31 << 16))); + FAIL_IF(push_inst(compiler, lhi(tmp0, 0))); FAIL_IF(push_inst(compiler, lr(tmp1, arg0))); FAIL_IF(push_inst(compiler, dr(tmp0, arg1))); FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */ @@ -1958,8 +1950,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */ return SLJIT_SUCCESS; - case SLJIT_MEMORY_BARRIER: - return push_inst(compiler, 0x0700 /* bcr */ | (0xe << 4) | 0); case SLJIT_ENDBR: return SLJIT_SUCCESS; case SLJIT_SKIP_FRAMES_BEFORE_RETURN: @@ -2485,9 +2475,14 @@ static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op, ins = (op & SLJIT_32) ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */; return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); } - } else if ((op & SLJIT_32) || is_u32(src2w)) { - ins = (op & SLJIT_32) ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */; - return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); + } + else { + if ((op & SLJIT_32) || is_u32(src2w)) { + ins = (op & SLJIT_32) ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */; + return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); + } + if (is_s16(src2w)) + return emit_rie_d(compiler, 0xec00000000db /* alghsik */, (sljit_s32)tmp0, src1, src1w, src2w); } } else if (src2 & SLJIT_MEM) { @@ -3187,7 +3182,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji if (type == SLJIT_GP_REGISTER) return (sljit_s32)gpr(reg); - if (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128) + if (type != SLJIT_FLOAT_REGISTER) return -1; return (sljit_s32)freg_map[reg]; @@ -3939,7 +3934,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3949,7 +3944,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3964,15 +3959,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co if (!(srcdst & SLJIT_MEM)) { if (type & SLJIT_SIMD_STORE) - ins = F36(srcdst) | F32(vreg); + ins = F36(srcdst) | F32(freg); else - ins = F36(vreg) | F32(srcdst); + ins = F36(freg) | F32(srcdst); return push_inst(compiler, 0xe70000000056 /* vlr */ | ins); } FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); - ins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); if (alignment >= 4) ins |= 4 << 12; @@ -3983,7 +3978,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3993,7 +3988,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_sw sign_ext; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4008,15 +4003,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (src & SLJIT_MEM) { FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); - return push_inst(compiler, 0xe70000000005 /* vlrep */ | F36(vreg) + return push_inst(compiler, 0xe70000000005 /* vlrep */ | F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset) | ((sljit_ins)elem_size << 12)); } if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) - return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg)); + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg)); - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(src) | ((sljit_ins)elem_size << 12)); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) | ((sljit_ins)elem_size << 12)); } if (src == SLJIT_IMM) { @@ -4048,10 +4043,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (sign_ext != 0x10000) { if (sign_ext == 0 || sign_ext == -1) - return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg) + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg) | (sign_ext == 0 ? 0 : ((sljit_ins)0xffff << 16))); - return push_inst(compiler, 0xe70000000045 /* vrepi */ | F36(vreg) + return push_inst(compiler, 0xe70000000045 /* vrepi */ | F36(freg) | ((sljit_ins)srcw << 16) | ((sljit_ins)elem_size << 12)); } @@ -4060,12 +4055,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil } else reg = gpr(src); - FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(reg) | ((sljit_ins)elem_size << 12))); - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(vreg) | ((sljit_ins)elem_size << 12)); + FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ((sljit_ins)elem_size << 12))); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(freg) | ((sljit_ins)elem_size << 12)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4075,7 +4070,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -4090,20 +4085,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (srcdst & SLJIT_MEM) { FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); - ins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); } if (type & SLJIT_SIMD_LANE_ZERO) { if ((srcdst & SLJIT_MEM) && lane_index == ((1 << (3 - elem_size)) - 1)) return push_inst(compiler, 0xe70000000004 /* vllez */ | ins | ((sljit_ins)elem_size << 12)); - if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { - FAIL_IF(push_inst(compiler, 0xe70000000056 /* vlr */ | F36(TMP_FREG1) | F32(vreg))); + if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(push_inst(compiler, 0xe70000000056 /* vlr */ | F36(TMP_FREG1) | F32(freg))); srcdst = TMP_FREG1; srcdstw = 0; } - FAIL_IF(push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(vreg))); + FAIL_IF(push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg))); } if (srcdst & SLJIT_MEM) { @@ -4131,19 +4126,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (type & SLJIT_SIMD_FLOAT) { if (type & SLJIT_SIMD_STORE) - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(srcdst) | F32(vreg) | ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12)); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(srcdst) | F32(freg) | ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12)); if (elem_size == 3) { if (lane_index == 0) - ins = F32(srcdst) | F28(vreg) | (1 << 12); + ins = F32(srcdst) | F28(freg) | (1 << 12); else - ins = F32(vreg) | F28(srcdst); + ins = F32(freg) | F28(srcdst); - return push_inst(compiler, 0xe70000000084 /* vpdi */ | F36(vreg) | ins); + return push_inst(compiler, 0xe70000000084 /* vpdi */ | F36(freg) | ins); } FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(tmp0) | F32(srcdst) | ((sljit_ins)2 << 12))); - return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(tmp0) | ((sljit_ins)lane_index << 16) | ((sljit_ins)2 << 12)); + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(tmp0) | ((sljit_ins)lane_index << 16) | ((sljit_ins)2 << 12)); } if (srcdst == SLJIT_IMM) { @@ -4172,7 +4167,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } if (ins != 0) - return push_inst(compiler, ins | F36(vreg) | ((sljit_ins)srcdstw << 16) | ((sljit_ins)lane_index << 12)); + return push_inst(compiler, ins | F36(freg) | ((sljit_ins)srcdstw << 16) | ((sljit_ins)lane_index << 12)); push_load_imm_inst(compiler, tmp0, srcdstw); reg = tmp0; @@ -4182,9 +4177,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile ins = ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12); if (!(type & SLJIT_SIMD_STORE)) - return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(vreg) | R32A(reg) | ins); + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ins); - FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(reg) | F32(vreg) | ins)); + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(reg) | F32(freg) | ins)); if (!(type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3) return SLJIT_SUCCESS; @@ -4205,14 +4200,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); if (reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4223,12 +4218,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (type & SLJIT_SIMD_TEST) return SLJIT_SUCCESS; - return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(vreg) | F32(src) + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) | ((sljit_ins)src_lane_index << 16) | ((sljit_ins)elem_size << 12)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4238,7 +4233,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4253,7 +4248,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler if (src & SLJIT_MEM) { FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); - ins = F36(vreg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); switch (elem2_size - elem_size) { case 1: @@ -4268,27 +4263,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler } FAIL_IF(push_inst(compiler, ins)); - src = vreg; + src = freg; } if (type & SLJIT_SIMD_FLOAT) { - FAIL_IF(push_inst(compiler, 0xe700000000d5 /* vuplh */ | F36(vreg) | F32(src) | (2 << 12))); - FAIL_IF(push_inst(compiler, 0xe70000000030 /* vesl */ | F36(vreg) | F32(vreg) | (32 << 16) | (3 << 12))); - return push_inst(compiler, 0xe700000000c4 /* vfll */ | F36(vreg) | F32(vreg) | (2 << 12)); + FAIL_IF(push_inst(compiler, 0xe700000000d5 /* vuplh */ | F36(freg) | F32(src) | (2 << 12))); + FAIL_IF(push_inst(compiler, 0xe70000000030 /* vesl */ | F36(freg) | F32(freg) | (32 << 16) | (3 << 12))); + return push_inst(compiler, 0xe700000000c4 /* vfll */ | F36(freg) | F32(freg) | (2 << 12)); } - ins = ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0xe700000000d7 /* vuph */ : 0xe700000000d5 /* vuplh */) | F36(vreg); + ins = ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0xe700000000d7 /* vuph */ : 0xe700000000d5 /* vuplh */) | F36(freg); do { FAIL_IF(push_inst(compiler, ins | F32(src) | ((sljit_ins)elem_size << 12))); - src = vreg; + src = freg; } while (++elem_size < elem2_size); return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4296,7 +4291,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_gpr dst_r; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4329,7 +4324,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c if (elem_size != 0) FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(TMP_FREG1) | R32A(tmp0) | (1 << 16) | (3 << 12))); - FAIL_IF(push_inst(compiler, 0xe70000000085 /* vbperm */ | F36(TMP_FREG1) | F32(vreg) | F28(TMP_FREG1))); + FAIL_IF(push_inst(compiler, 0xe70000000085 /* vbperm */ | F36(TMP_FREG1) | F32(freg) | F28(TMP_FREG1))); dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(dst_r) | F32(TMP_FREG1) @@ -4342,17 +4337,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 alignment; - struct addr addr; - sljit_ins ins = 0, load_ins; + sljit_ins ins = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); if (reg_size != 4) return SLJIT_ERR_UNSUPPORTED; @@ -4373,29 +4365,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co case SLJIT_SIMD_OP2_XOR: ins = 0xe7000000006d /* vx */; break; - case SLJIT_SIMD_OP2_SHUFFLE: - ins = 0xe7000000008c /* vperm */; - break; } - if (src2 & SLJIT_MEM) { - FAIL_IF(make_addr_bx(compiler, &addr, src2, src2w, tmp1)); - load_ins = 0xe70000000006 /* vl */ | F36(TMP_FREG1) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); - alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); - - if (alignment >= 4) - load_ins |= 4 << 12; - else if (alignment == 3) - load_ins |= 3 << 12; - - FAIL_IF(push_inst(compiler, load_ins)); - src2 = TMP_FREG1; - } - - if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) - return push_inst(compiler, ins | F36(dst_vreg) | F32(src1_vreg) | F28(src1_vreg) | F12(src2)); + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; - return push_inst(compiler, ins | F36(dst_vreg) | F32(src1_vreg) | F28(src2)); + return push_inst(compiler, ins | F36(dst_freg) | F32(src1_freg) | F28(src2_freg)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, @@ -4405,22 +4380,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - if (op & SLJIT_ATOMIC_USE_LS) - return SLJIT_ERR_UNSUPPORTED; - - switch (GET_OPCODE(op)) { - case SLJIT_MOV32: - case SLJIT_MOV_U32: - case SLJIT_MOV: - case SLJIT_MOV_P: - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - - SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op1(compiler, op & ~SLJIT_ATOMIC_USE_CAS, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); - default: - return SLJIT_ERR_UNSUPPORTED; - } + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, @@ -4428,33 +4389,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler sljit_s32 mem_reg, sljit_s32 temp_reg) { - sljit_ins ins; + sljit_ins mask; sljit_gpr tmp_r = gpr(temp_reg); sljit_gpr mem_r = gpr(mem_reg); CHECK_ERROR(); CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); - if (op & SLJIT_ATOMIC_USE_LS) - return SLJIT_ERR_UNSUPPORTED; - switch (GET_OPCODE(op)) { case SLJIT_MOV32: case SLJIT_MOV_U32: - ins = 0xba000000 /* cs */ | R20A(tmp_r) | R16A(gpr(src_reg)) | R12A(mem_r); + return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp_r) | R16A(gpr(src_reg)) | R12A(mem_r)); + case SLJIT_MOV_U8: + mask = 0xff; break; - case SLJIT_MOV: - case SLJIT_MOV_P: - ins = 0xeb0000000030 /* csg */ | R36A(tmp_r) | R32A(gpr(src_reg)) | R28A(mem_r); + case SLJIT_MOV_U16: + mask = 0xffff; break; default: - return SLJIT_ERR_UNSUPPORTED; + return push_inst(compiler, 0xeb0000000030 /* csg */ | R36A(tmp_r) | R32A(gpr(src_reg)) | R28A(mem_r)); } - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; + /* tmp0 = (src_reg ^ tmp_r) & mask */ + FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | mask)); + FAIL_IF(push_inst(compiler, 0xb9e70000 /* xgrk */ | R4A(tmp0) | R0A(gpr(src_reg)) | R12A(tmp_r))); + FAIL_IF(push_inst(compiler, 0xa7090000 /* lghi */ | R20A(tmp_r) | 0xfffc)); + FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp0) | R0A(tmp1))); - return push_inst(compiler, ins); + /* tmp0 = tmp0 << (((mem_r ^ 0x3) & 0x3) << 3) */ + FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | (sljit_ins)((mask == 0xff) ? 0x18 : 0x10))); + FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp_r) | R0A(mem_r))); + FAIL_IF(push_inst(compiler, 0xec0000000057 /* rxsbg */ | R36A(tmp1) | R32A(mem_r) | (59 << 24) | (60 << 16) | (3 << 8))); + FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp0) | R32A(tmp0) | R28A(tmp1))); + + /* Already computed: tmp_r = mem_r & ~0x3 */ + + FAIL_IF(push_inst(compiler, 0x58000000 /* l */ | R20A(tmp1) | R12A(tmp_r))); + FAIL_IF(push_inst(compiler, 0x1700 /* x */ | R4A(tmp0) | R0A(tmp1))); + return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp1) | R16A(tmp0) | R12A(tmp_r)); } /* --------------------------------------------------------------------- */ diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c index 217a1498abe1..59ea04a5c81b 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c @@ -311,8 +311,8 @@ static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_pt #define ENTER_TMP_TO_S 0x00002 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_s32 word_arg_count, saved_arg_count, float_arg_count; sljit_s32 size, args_size, types, status; @@ -323,10 +323,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); /* Emit ENDBR32 at function entry if needed. */ FAIL_IF(emit_endbranch(compiler)); @@ -538,16 +536,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_s32 args_size; CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); arg_types >>= SLJIT_ARG_SHIFT; args_size = 0; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c index e4d3db828fa0..1ab79293c7ef 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c @@ -454,16 +454,14 @@ typedef struct { #endif /* _WIN64 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_uw size; sljit_s32 word_arg_count = 0; sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options); sljit_s32 saved_regs_size, tmp, i; #ifdef _WIN64 - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 saved_float_regs_size; sljit_s32 saved_float_regs_offset = 0; sljit_s32 float_arg_count = 0; @@ -471,15 +469,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi sljit_u8 *inst; CHECK_ERROR(); - CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); -#ifdef _WIN64 - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; -#endif /* _WIN64 */ + CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); if (options & SLJIT_ENTER_REG_ARG) arg_types = 0; @@ -639,27 +630,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, - sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size) + sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_s32 saved_regs_size; #ifdef _WIN64 - sljit_s32 fscratches; - sljit_s32 fsaveds; sljit_s32 saved_float_regs_size; #endif /* _WIN64 */ CHECK_ERROR(); - CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size)); - set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size); - - scratches = ENTER_GET_REGS(scratches); + CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); + set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); #ifdef _WIN64 - saveds = ENTER_GET_REGS(saveds); - fscratches = compiler->fscratches; - fsaveds = compiler->fsaveds; - local_size += SLJIT_LOCALS_OFFSET; saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c index 9f599d5fb089..ecb7e9be3b0e 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c @@ -239,7 +239,6 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { #define MOVDDUP_x_xm 0x12 #define MOVDQA_x_xm 0x6f #define MOVDQA_xm_x 0x7f -#define MOVDQU_x_xm 0x6f #define MOVHLPS_x_x 0x12 #define MOVHPD_m_x 0x17 #define MOVHPD_x_m 0x16 @@ -399,13 +398,6 @@ static sljit_u32 cpu_feature_list = 0; #include #elif defined(_MSC_VER) && _MSC_VER >= 1400 #include -#elif defined(__INTEL_COMPILER) -#include -#endif - -#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__INTEL_COMPILER) \ - || (defined(__INTEL_LLVM_COMPILER) && defined(__XSAVE__)) -#include #endif /******************************************************/ @@ -433,20 +425,49 @@ static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value) static void execute_cpu_id(sljit_u32 info[4]) { -#if (defined(_MSC_VER) && _MSC_VER >= 1400) \ - || (defined(__INTEL_COMPILER) && __INTEL_COMPILER == 2021 && __INTEL_COMPILER_UPDATE >= 7) +#if defined(_MSC_VER) && _MSC_VER >= 1400 __cpuidex((int*)info, (int)info[0], (int)info[2]); -#elif (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900) +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__TINYC__) - __get_cpuid_count(info[0], info[2], info, info + 1, info + 2, info + 3); + /* AT&T syntax. */ + __asm__ ( +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + "movl %0, %%esi\n" + "movl (%%esi), %%eax\n" + "movl 8(%%esi), %%ecx\n" + "pushl %%ebx\n" + "cpuid\n" + "movl %%eax, (%%esi)\n" + "movl %%ebx, 4(%%esi)\n" + "popl %%ebx\n" + "movl %%ecx, 8(%%esi)\n" + "movl %%edx, 12(%%esi)\n" +#else /* !SLJIT_CONFIG_X86_32 */ + "movq %0, %%rsi\n" + "movl (%%rsi), %%eax\n" + "movl 8(%%rsi), %%ecx\n" + "cpuid\n" + "movl %%eax, (%%rsi)\n" + "movl %%ebx, 4(%%rsi)\n" + "movl %%ecx, 8(%%rsi)\n" + "movl %%edx, 12(%%rsi)\n" +#endif /* SLJIT_CONFIG_X86_32 */ + : + : "r" (info) +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + : "memory", "eax", "ecx", "edx", "esi" +#else /* !SLJIT_CONFIG_X86_32 */ + : "memory", "rax", "rbx", "rcx", "rdx", "rsi" +#endif /* SLJIT_CONFIG_X86_32 */ + ); -#elif (defined(_MSC_VER) || defined(__INTEL_COMPILER)) \ - && (defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32) +#else /* _MSC_VER < 1400 */ /* Intel syntax. */ __asm { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) mov esi, info mov eax, [esi] mov ecx, [esi + 8] @@ -455,48 +476,30 @@ static void execute_cpu_id(sljit_u32 info[4]) mov [esi + 4], ebx mov [esi + 8], ecx mov [esi + 12], edx +#else /* !SLJIT_CONFIG_X86_32 */ + mov rsi, info + mov eax, [rsi] + mov ecx, [rsi + 8] + cpuid + mov [rsi], eax + mov [rsi + 4], ebx + mov [rsi + 8], ecx + mov [rsi + 12], edx +#endif /* SLJIT_CONFIG_X86_32 */ } -#else - - __asm__ __volatile__ ( - "cpuid\n" - : "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3]) - : "0" (info[0]), "2" (info[2]) - ); - -#endif +#endif /* _MSC_VER && _MSC_VER >= 1400 */ } static sljit_u32 execute_get_xcr0_low(void) { sljit_u32 xcr0; -#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__INTEL_COMPILER) \ - || (defined(__INTEL_LLVM_COMPILER) && defined(__XSAVE__)) +#if defined(_MSC_VER) && _MSC_VER >= 1400 xcr0 = (sljit_u32)_xgetbv(0); -#elif defined(__TINYC__) - - __asm__ ( - "xorl %%ecx, %%ecx\n" - ".byte 0x0f\n" - ".byte 0x01\n" - ".byte 0xd0\n" - : "=a" (xcr0) - : -#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 - : "ecx", "edx" -#else /* !SLJIT_CONFIG_X86_32 */ - : "rcx", "rdx" -#endif /* SLJIT_CONFIG_X86_32 */ - ); - -#elif (defined(__INTEL_LLVM_COMPILER) && __INTEL_LLVM_COMPILER < 20220100) \ - || (defined(__clang__) && __clang_major__ < 14) \ - || (defined(__GNUC__) && __GNUC__ < 3) \ - || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__TINYC__) /* AT&T syntax. */ __asm__ ( @@ -504,37 +507,23 @@ static sljit_u32 execute_get_xcr0_low(void) "xgetbv\n" : "=a" (xcr0) : -#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) : "ecx", "edx" #else /* !SLJIT_CONFIG_X86_32 */ : "rcx", "rdx" #endif /* SLJIT_CONFIG_X86_32 */ ); -#elif defined(_MSC_VER) +#else /* _MSC_VER < 1400 */ /* Intel syntax. */ __asm { - xor ecx, ecx + mov ecx, 0 xgetbv mov xcr0, eax } -#else - - __asm__ ( - "xor{l %%ecx, %%ecx | ecx, ecx}\n" - "xgetbv\n" - : "=a" (xcr0) - : -#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 - : "ecx", "edx" -#else /* !SLJIT_CONFIG_X86_32 */ - : "rcx", "rdx" -#endif /* SLJIT_CONFIG_X86_32 */ - ); - -#endif +#endif /* _MSC_VER && _MSC_VER >= 1400 */ return xcr0; } @@ -560,10 +549,6 @@ static void get_cpu_features(void) if (max_id >= 1) { info[0] = 1; -#if defined(SLJIT_CONFIG_X86_32) && SLJIT_CONFIG_X86_32 - /* Winchip 2 and Cyrix MII bugs */ - info[1] = info[2] = 0; -#endif execute_cpu_id(info); if (info[2] & 0x80000) @@ -580,17 +565,11 @@ static void get_cpu_features(void) feature_list |= CPU_FEATURE_CMOV; } - info[0] = 0x80000000; + info[0] = 0x80000001; execute_cpu_id(info); - max_id = info[0]; - - if (max_id >= 0x80000001) { - info[0] = 0x80000001; - execute_cpu_id(info); - if (info[2] & 0x20) - feature_list |= CPU_FEATURE_LZCNT; - } + if (info[2] & 0x20) + feature_list |= CPU_FEATURE_LZCNT; if ((feature_list & CPU_FEATURE_OSXSAVE) && (execute_get_xcr0_low() & 0x4) == 0) feature_list &= ~(sljit_u32)(CPU_FEATURE_AVX | CPU_FEATURE_AVX2); @@ -680,23 +659,18 @@ static sljit_u8* detect_near_jump_type(struct sljit_jump *jump, sljit_u8 *code_p sljit_uw type = jump->flags >> TYPE_SHIFT; sljit_s32 short_jump; sljit_uw label_addr; - sljit_uw jump_addr; - - jump_addr = (sljit_uw)code_ptr; - if (!(jump->flags & JUMP_ADDR)) { - label_addr = (sljit_uw)(code + jump->u.label->size); - if (jump->u.label->size > jump->addr) - jump_addr = (sljit_uw)(code + jump->addr); - } else + if (jump->flags & JUMP_ADDR) label_addr = jump->u.target - (sljit_uw)executable_offset; + else + label_addr = (sljit_uw)(code + jump->u.label->size); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((sljit_sw)(label_addr - (jump_addr + 6)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump_addr + 5)) < HALFWORD_MIN) + if ((sljit_sw)(label_addr - (sljit_uw)(code_ptr + 6)) > HALFWORD_MAX || (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 5)) < HALFWORD_MIN) return detect_far_jump_type(jump, code_ptr); #endif /* SLJIT_CONFIG_X86_64 */ - short_jump = (sljit_sw)(label_addr - (jump_addr + 2)) >= -0x80 && (sljit_sw)(label_addr - (jump_addr + 2)) <= 0x7f; + short_jump = (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 2)) >= -0x80 && (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 2)) <= 0x7f; if (type == SLJIT_JUMP) { if (short_jump) @@ -818,7 +792,6 @@ static void reduce_code_size(struct sljit_compiler *compiler) if (next_min_addr != next_jump_addr) continue; - jump->addr -= size_reduce; if (!(jump->flags & JUMP_MOV_ADDR)) { #if (defined SLJIT_DEBUG && SLJIT_DEBUG) size_reduce_max = size_reduce + (((jump->flags >> TYPE_SHIFT) < SLJIT_JUMP) ? CJUMP_MAX_SIZE : JUMP_MAX_SIZE); @@ -832,11 +805,7 @@ static void reduce_code_size(struct sljit_compiler *compiler) #endif /* SLJIT_CONFIG_X86_64 */ } else { /* Unit size: instruction. */ - diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr; - if (jump->u.label->size > jump->addr) { - SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr); - diff -= (sljit_sw)size_reduce; - } + diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - size_reduce); type = jump->flags >> TYPE_SHIFT; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -876,7 +845,7 @@ static void reduce_code_size(struct sljit_compiler *compiler) #endif /* SLJIT_DEBUG */ if (!(jump->flags & JUMP_ADDR)) { - diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - 3); + diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - size_reduce - 3); if (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN) size_reduce += 3; @@ -1048,7 +1017,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_COPY_F32: case SLJIT_HAS_COPY_F64: case SLJIT_HAS_ATOMIC: - case SLJIT_HAS_MEMORY_BARRIER: return 1; #if !(defined SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE @@ -1508,14 +1476,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); #endif break; - case SLJIT_MEMORY_BARRIER: - inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); - INC_SIZE(3); - inst[0] = GROUP_0F; - inst[1] = 0xae; - inst[2] = 0xf0; - return SLJIT_SUCCESS; case SLJIT_ENDBR: return emit_endbranch(compiler); case SLJIT_SKIP_FRAMES_BEFORE_RETURN: @@ -3506,7 +3466,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_u8 cond_set; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) sljit_s32 reg; - sljit_uw size; #endif /* !SLJIT_CONFIG_X86_64 */ /* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */ sljit_s32 dst_save = dst; @@ -3523,52 +3482,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst)) { - size = 3 + 2; - if (reg_map[TMP_REG1] >= 4) - size += 1 + 1; - else if (reg_map[dst] >= 4) - size++; - - inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3); FAIL_IF(!inst); - INC_SIZE(size); + INC_SIZE(4 + 3); /* Set low register to conditional flag. */ - if (reg_map[TMP_REG1] >= 4) - *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; - - inst[0] = GROUP_0F; - inst[1] = cond_set; - inst[2] = MOD_REG | reg_lmap[TMP_REG1]; - inst += 3; - - if (reg_map[TMP_REG1] >= 4 || reg_map[dst] >= 4) - *inst++ = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); - - inst[0] = OR_rm8_r8; - inst[1] = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); + inst[0] = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; + inst[1] = GROUP_0F; + inst[2] = cond_set; + inst[3] = MOD_REG | reg_lmap[TMP_REG1]; + inst[4] = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); + inst[5] = OR_rm8_r8; + inst[6] = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); return SLJIT_SUCCESS; } reg = (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG1; - size = 3 + (reg_map[reg] >= 4) + 4; - inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4); FAIL_IF(!inst); - INC_SIZE(size); + INC_SIZE(4 + 4); /* Set low register to conditional flag. */ - - if (reg_map[reg] >= 4) - *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; - - inst[0] = GROUP_0F; - inst[1] = cond_set; - inst[2] = MOD_REG | reg_lmap[reg]; - - inst[3] = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + inst[0] = (reg_map[reg] <= 7) ? REX : REX_B; + inst[1] = GROUP_0F; + inst[2] = cond_set; + inst[3] = MOD_REG | reg_lmap[reg]; + inst[4] = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); /* The movzx instruction does not affect flags. */ - inst[4] = GROUP_0F; - inst[5] = MOVZX_r_rm8; - inst[6] = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); + inst[5] = GROUP_0F; + inst[6] = MOVZX_r_rm8; + inst[7] = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); if (reg != TMP_REG1) return SLJIT_SUCCESS; @@ -3675,7 +3617,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3684,7 +3626,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co sljit_uw op; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_mov(compiler, type, vreg, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -3728,13 +3670,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co return SLJIT_SUCCESS; if ((op & VEX_256) || ((cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX))) - return emit_vex_instruction(compiler, op, vreg, 0, srcdst, srcdstw); + return emit_vex_instruction(compiler, op, freg, 0, srcdst, srcdstw); - return emit_groupf(compiler, op, vreg, srcdst, srcdstw); + return emit_groupf(compiler, op, freg, srcdst, srcdstw); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3745,7 +3687,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil sljit_uw op; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_replicate(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -3811,48 +3753,48 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (elem_size >= 3) compiler->mode32 = 0; #endif /* SLJIT_CONFIG_X86_64 */ - FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw)); + FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; #endif /* SLJIT_CONFIG_X86_64 */ - src = vreg; + src = freg; srcw = 0; } if (reg_size == 5) op |= VEX_256; - return emit_vex_instruction(compiler, op, vreg, 0, src, srcw); + return emit_vex_instruction(compiler, op, freg, 0, src, srcw); } } if (type & SLJIT_SIMD_FLOAT) { if (src == SLJIT_IMM) { if (use_vex) - return emit_vex_instruction(compiler, XORPD_x_xm | (reg_size == 5 ? VEX_256 : 0) | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0); + return emit_vex_instruction(compiler, XORPD_x_xm | (reg_size == 5 ? VEX_256 : 0) | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); - return emit_groupf(compiler, XORPD_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2, vreg, vreg, 0); + return emit_groupf(compiler, XORPD_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2, freg, freg, 0); } SLJIT_ASSERT(reg_size == 4); if (use_vex) { if (elem_size == 3) - return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, src, srcw); + return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, src, srcw); SLJIT_ASSERT(!(src & SLJIT_MEM)); - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, vreg, src, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0)); return emit_byte(compiler, 0); } - if (elem_size == 2 && vreg != src) { - FAIL_IF(emit_sse2_load(compiler, 1, vreg, src, srcw)); - src = vreg; + if (elem_size == 2 && freg != src) { + FAIL_IF(emit_sse2_load(compiler, 1, freg, src, srcw)); + src = freg; srcw = 0; } op = (elem_size == 2 ? SHUFPS_x_xm : MOVDDUP_x_xm) | (elem_size == 2 ? 0 : EX86_PREF_F2) | EX86_SSE2; - FAIL_IF(emit_groupf(compiler, op, vreg, src, srcw)); + FAIL_IF(emit_groupf(compiler, op, freg, src, srcw)); if (elem_size == 2) return emit_byte(compiler, 0); @@ -3878,9 +3820,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (srcw == 0 || srcw == -1) { if (use_vex) - return emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0); + return emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); - return emit_groupf(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0); + return emit_groupf(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | EX86_PREF_66 | EX86_SSE2, freg, freg, 0); } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -3922,11 +3864,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil if (use_vex) { if (opcode != MOVD_x_rm) { op = (opcode == 0x3a) ? (PINSRB_x_rm_i8 | VEX_OP_0F3A) : opcode; - FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1 | VEX_SSE2_OPV, vreg, vreg, src, srcw)); + FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1 | VEX_SSE2_OPV, freg, freg, src, srcw)); } else - FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw)); + FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw)); } else { - inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, src, srcw); + inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw); FAIL_IF(!inst); inst[0] = GROUP_0F; inst[1] = opcode; @@ -3937,13 +3879,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil } } - if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && elem_size >= 2) { + if (use_vex && elem_size >= 2) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) op = VPBROADCASTD_x_xm; #else /* !SLJIT_CONFIG_X86_32 */ op = (elem_size == 3) ? VPBROADCASTQ_x_xm : VPBROADCASTD_x_xm; #endif /* SLJIT_CONFIG_X86_32 */ - return emit_vex_instruction(compiler, op | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0); + return emit_vex_instruction(compiler, op | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); } SLJIT_ASSERT(reg_size == 4); @@ -3955,37 +3897,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil case 0: if (use_vex) { FAIL_IF(emit_vex_instruction(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0)); - return emit_vex_instruction(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, TMP_FREG, 0); + return emit_vex_instruction(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, TMP_FREG, 0); } FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); - return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, TMP_FREG, 0); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); case 1: if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, freg, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, vreg, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, freg, 0)); FAIL_IF(emit_byte(compiler, 0)); /* fallthrough */ default: if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, freg, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); return emit_byte(compiler, 0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) case 3: compiler->mode32 = 1; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, freg, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, vreg, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); return emit_byte(compiler, 0x44); #endif /* SLJIT_CONFIG_X86_64 */ } } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, sljit_s32 lane_index, + sljit_s32 freg, sljit_s32 lane_index, sljit_s32 srcdst, sljit_sw srcdstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -3994,7 +3936,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile sljit_u8 *inst; sljit_u8 opcode = 0; sljit_uw op; - sljit_s32 vreg_orig = vreg; + sljit_s32 freg_orig = freg; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) sljit_s32 srcdst_is_ereg = 0; sljit_s32 srcdst_orig = 0; @@ -4002,7 +3944,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile #endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_mov(compiler, type, vreg, lane_index, srcdst, srcdstw)); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); ADJUST_LOCAL_OFFSET(srcdst, srcdstw); @@ -4062,29 +4004,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (elem_size == 2) { if (use_vex) - return emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, srcdst, srcdstw); - return emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, vreg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); + return emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, srcdst, srcdstw); } } else if (srcdst & SLJIT_MEM) { SLJIT_ASSERT(elem_size == 2 || elem_size == 3); if (use_vex) - return emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, vreg, 0, srcdst, srcdstw); - return emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, vreg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, 0, srcdst, srcdstw); + return emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, srcdst, srcdstw); } else if (elem_size == 3) { if (use_vex) - return emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, vreg, 0, srcdst, 0); - return emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, vreg, srcdst, 0); + return emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, 0, srcdst, 0); + return emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, srcdst, 0); } else if (use_vex) { FAIL_IF(emit_vex_instruction(compiler, XORPD_x_xm | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0)); - return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F3 | EX86_SSE2 | VEX_SSE2_OPV, vreg, TMP_FREG, srcdst, 0); + return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F3 | EX86_SSE2 | VEX_SSE2_OPV, freg, TMP_FREG, srcdst, 0); } } if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { - vreg = TMP_FREG; + freg = TMP_FREG; lane_index -= (1 << (4 - elem_size)); - } else if ((type & SLJIT_SIMD_FLOAT) && vreg == srcdst) { + } else if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { if (use_vex) FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, srcdst, srcdstw)); else @@ -4097,14 +4039,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile | ((type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm) | EX86_SSE2; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, op | (reg_size == 5 ? VEX_256 : 0) | VEX_SSE2_OPV, vreg, vreg, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, op | (reg_size == 5 ? VEX_256 : 0) | VEX_SSE2_OPV, freg, freg, freg, 0)); else - FAIL_IF(emit_groupf(compiler, op, vreg, vreg, 0)); + FAIL_IF(emit_groupf(compiler, op, freg, freg, 0)); } else if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { - FAIL_IF(emit_vex_instruction(compiler, ((type & SLJIT_SIMD_FLOAT) ? VEXTRACTF128_x_ym : VEXTRACTI128_x_ym) | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, ((type & SLJIT_SIMD_FLOAT) ? VEXTRACTF128_x_ym : VEXTRACTI128_x_ym) | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); FAIL_IF(emit_byte(compiler, 1)); - vreg = TMP_FREG; + freg = TMP_FREG; lane_index -= (1 << (4 - elem_size)); } @@ -4117,55 +4059,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile op = lane_index == 0 ? MOVLPD_x_m : MOVHPD_x_m; /* VEX prefix clears upper bits of the target register. */ - if (use_vex && ((type & SLJIT_SIMD_STORE) || reg_size == 4 || vreg == TMP_FREG)) + if (use_vex && ((type & SLJIT_SIMD_STORE) || reg_size == 4 || freg == TMP_FREG)) FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2 - | ((type & SLJIT_SIMD_STORE) ? 0 : VEX_SSE2_OPV), vreg, (type & SLJIT_SIMD_STORE) ? 0 : vreg, srcdst, srcdstw)); + | ((type & SLJIT_SIMD_STORE) ? 0 : VEX_SSE2_OPV), freg, (type & SLJIT_SIMD_STORE) ? 0 : freg, srcdst, srcdstw)); else - FAIL_IF(emit_groupf(compiler, op | EX86_PREF_66 | EX86_SSE2, vreg, srcdst, srcdstw)); + FAIL_IF(emit_groupf(compiler, op | EX86_PREF_66 | EX86_SSE2, freg, srcdst, srcdstw)); - /* In case of store, vreg is not TMP_FREG. */ + /* In case of store, freg is not TMP_FREG. */ } else if (type & SLJIT_SIMD_STORE) { if (lane_index == 1) { if (use_vex) - return emit_vex_instruction(compiler, MOVHLPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, vreg, 0); - return emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, vreg, 0); + return emit_vex_instruction(compiler, MOVHLPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, freg, 0); + return emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, freg, 0); } if (use_vex) - return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, vreg, 0); - return emit_sse2_load(compiler, 0, srcdst, vreg, 0); - } else if (use_vex && (reg_size == 4 || vreg == TMP_FREG)) { + return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, freg, 0); + return emit_sse2_load(compiler, 0, srcdst, freg, 0); + } else if (use_vex && (reg_size == 4 || freg == TMP_FREG)) { if (lane_index == 1) - FAIL_IF(emit_vex_instruction(compiler, MOVLHPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, srcdst, 0)); + FAIL_IF(emit_vex_instruction(compiler, MOVLHPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, srcdst, 0)); else - FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, srcdst, 0)); + FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, srcdst, 0)); } else { if (lane_index == 1) - FAIL_IF(emit_groupf(compiler, MOVLHPS_x_x | EX86_SSE2, vreg, srcdst, 0)); + FAIL_IF(emit_groupf(compiler, MOVLHPS_x_x | EX86_SSE2, freg, srcdst, 0)); else - FAIL_IF(emit_sse2_load(compiler, 0, vreg, srcdst, 0)); + FAIL_IF(emit_sse2_load(compiler, 0, freg, srcdst, 0)); } } else if (type & SLJIT_SIMD_STORE) { if (lane_index == 0) { if (use_vex) - return emit_vex_instruction(compiler, MOVSD_xm_x | EX86_PREF_F3 | EX86_SSE2 | ((srcdst & SLJIT_MEM) ? 0 : VEX_SSE2_OPV), - vreg, ((srcdst & SLJIT_MEM) ? 0 : srcdst), srcdst, srcdstw); - return emit_sse2_store(compiler, 1, srcdst, srcdstw, vreg); + return emit_vex_instruction(compiler, ((srcdst & SLJIT_MEM) ? MOVSD_xm_x : MOVSD_x_xm) | EX86_PREF_F3 | EX86_SSE2 + | ((srcdst & SLJIT_MEM) ? 0 : VEX_SSE2_OPV), freg, ((srcdst & SLJIT_MEM) ? 0 : freg), srcdst, srcdstw); + return emit_sse2_store(compiler, 1, srcdst, srcdstw, freg); } if (srcdst & SLJIT_MEM) { if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, srcdst, srcdstw)); + FAIL_IF(emit_vex_instruction(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, srcdst, srcdstw)); else - FAIL_IF(emit_groupf_ext(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, srcdst, srcdstw)); + FAIL_IF(emit_groupf_ext(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); return emit_byte(compiler, U8(lane_index)); } if (use_vex) { - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, srcdst, vreg, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, srcdst, freg, freg, 0)); return emit_byte(compiler, U8(lane_index)); } - if (srcdst == vreg) + if (srcdst == freg) op = SHUFPS_x_xm | EX86_SSE2; else { switch (lane_index) { @@ -4182,7 +4124,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } } - FAIL_IF(emit_groupf(compiler, op, srcdst, vreg, 0)); + FAIL_IF(emit_groupf(compiler, op, srcdst, freg, 0)); op &= 0xff; if (op == SHUFPS_x_xm || op == PSHUFD_x_xm) @@ -4191,23 +4133,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile return SLJIT_SUCCESS; } else { if (lane_index != 0 || (srcdst & SLJIT_MEM)) { - FAIL_IF(emit_groupf_ext(compiler, INSERTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, srcdst, srcdstw)); + FAIL_IF(emit_groupf_ext(compiler, INSERTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); FAIL_IF(emit_byte(compiler, U8(lane_index << 4))); } else - FAIL_IF(emit_sse2_store(compiler, 1, vreg, 0, srcdst)); + FAIL_IF(emit_sse2_store(compiler, 1, freg, 0, srcdst)); } - if (vreg != TMP_FREG || (type & SLJIT_SIMD_STORE)) + if (freg != TMP_FREG || (type & SLJIT_SIMD_STORE)) return SLJIT_SUCCESS; SLJIT_ASSERT(reg_size == 5); if (type & SLJIT_SIMD_LANE_ZERO) { - FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg_orig, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); return emit_byte(compiler, 0x4e); } - FAIL_IF(emit_vex_instruction(compiler, VINSERTF128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, vreg_orig, vreg_orig, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VINSERTF128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); return emit_byte(compiler, 1); } @@ -4244,9 +4186,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile if (use_vex && (type & SLJIT_SIMD_STORE)) { op = opcode | ((op == 3) ? VEX_OP_0F3A : 0); - FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | VEX_AUTO_W | EX86_SSE2_OP1 | VEX_SSE2_OPV, vreg, 0, srcdst, srcdstw)); + FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | VEX_AUTO_W | EX86_SSE2_OP1 | VEX_SSE2_OPV, freg, 0, srcdst, srcdstw)); } else { - inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, vreg, 0, srcdst, srcdstw); + inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); FAIL_IF(!inst); inst[0] = GROUP_0F; @@ -4260,15 +4202,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile FAIL_IF(emit_byte(compiler, U8(lane_index))); if (!(type & SLJIT_SIMD_LANE_SIGNED) || (srcdst & SLJIT_MEM)) { - if (vreg == TMP_FREG && !(type & SLJIT_SIMD_STORE)) { + if (freg == TMP_FREG && !(type & SLJIT_SIMD_STORE)) { SLJIT_ASSERT(reg_size == 5); if (type & SLJIT_SIMD_LANE_ZERO) { - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg_orig, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); return emit_byte(compiler, 0x4e); } - FAIL_IF(emit_vex_instruction(compiler, VINSERTI128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, vreg_orig, vreg_orig, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VINSERTI128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); return emit_byte(compiler, 1); } @@ -4320,7 +4262,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_s32 src_lane_index) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4335,7 +4277,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c #endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); - CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index)); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -4359,9 +4301,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 5) { if (src_lane_index == 0) - return emit_vex_instruction(compiler, VBROADCASTSD_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0); + return emit_vex_instruction(compiler, VBROADCASTSD_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); - FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); byte = U8(byte | (byte << 2)); return emit_byte(compiler, U8(byte | (byte << 4))); @@ -4369,8 +4311,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (src_lane_index == 0) { if (use_vex) - return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, 0, src, 0); - return emit_groupf(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, src, 0); + return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, src, 0); + return emit_groupf(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, src, 0); } /* Changes it to SHUFPD_x_xm. */ @@ -4384,9 +4326,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c SLJIT_ASSERT(elem_size == 2); if (src_lane_index == 0) - return emit_vex_instruction(compiler, VBROADCASTSS_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0); + return emit_vex_instruction(compiler, VBROADCASTSS_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); - FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); byte = 0x44; if (src_lane_index >= 4) { @@ -4395,15 +4337,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } FAIL_IF(emit_byte(compiler, byte)); - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | VEX_256 | pref | EX86_SSE2 | VEX_SSE2_OPV, vreg, vreg, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | VEX_256 | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0)); byte = U8(src_lane_index); } else if (use_vex) { - FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, vreg, src, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0)); } else { - if (vreg != src) - FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | pref | EX86_SSE2, vreg, src, 0)); + if (freg != src) + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | pref | EX86_SSE2, freg, src, 0)); - FAIL_IF(emit_groupf(compiler, SHUFPS_x_xm | pref | EX86_SSE2, vreg, vreg, 0)); + FAIL_IF(emit_groupf(compiler, SHUFPS_x_xm | pref | EX86_SSE2, freg, freg, 0)); } if (elem_size == 2) { @@ -4420,13 +4362,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (elem_size == 0) { if (reg_size == 5 && src_lane_index >= 16) { - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); FAIL_IF(emit_byte(compiler, src_lane_index >= 24 ? 0xff : 0xaa)); src_lane_index &= 0x7; - src = vreg; + src = freg; } - if (src_lane_index != 0 || (vreg != src && (!(cpu_feature_list & CPU_FEATURE_AVX2) || !use_vex))) { + if (src_lane_index != 0 || (freg != src && (!(cpu_feature_list & CPU_FEATURE_AVX2) || !use_vex))) { pref = 0; if ((src_lane_index & 0x3) == 0) { @@ -4437,33 +4379,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c byte = U8(src_lane_index >> 1); } else { if (!use_vex) { - if (vreg != src) - FAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, src, 0)); + if (freg != src) + FAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); - FAIL_IF(emit_groupf(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2, opcode3, vreg, 0)); + FAIL_IF(emit_groupf(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2, opcode3, freg, 0)); } else - FAIL_IF(emit_vex_instruction(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2 | VEX_SSE2_OPV, opcode3, vreg, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2 | VEX_SSE2_OPV, opcode3, freg, src, 0)); FAIL_IF(emit_byte(compiler, U8(src_lane_index))); } if (pref != 0) { if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, 0, src, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, src, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); FAIL_IF(emit_byte(compiler, byte)); } - src = vreg; + src = freg; } if (use_vex && (cpu_feature_list & CPU_FEATURE_AVX2)) - return emit_vex_instruction(compiler, VPBROADCASTB_x_xm | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, 0); + return emit_vex_instruction(compiler, VPBROADCASTB_x_xm | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); SLJIT_ASSERT(reg_size == 4); FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); - return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, TMP_FREG, 0); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); } if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && src_lane_index == 0 && elem_size <= 3) { @@ -4482,7 +4424,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c if (reg_size == 5) pref |= VEX_256; - return emit_vex_instruction(compiler, pref, vreg, 0, src, 0); + return emit_vex_instruction(compiler, pref, freg, 0, src, 0); } if (reg_size == 5) { @@ -4501,22 +4443,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c pref = 0; break; default: - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); return emit_byte(compiler, U8(src_lane_index == 0 ? 0x44 : 0xee)); } if (pref != 0) { - FAIL_IF(emit_vex_instruction(compiler, pref, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, pref, freg, 0, src, 0)); byte = U8(byte | (byte << 2)); FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); if (src_lane_index == 0) - return emit_vex_instruction(compiler, VPBROADCASTQ_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0); + return emit_vex_instruction(compiler, VPBROADCASTQ_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); - src = vreg; + src = freg; } - FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); byte = U8(src_lane_index); byte = U8(byte | (byte << 2)); return emit_byte(compiler, U8(byte | (byte << 4))); @@ -4529,16 +4471,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c pref = (src_lane_index & 2) == 0 ? EX86_PREF_F2 : EX86_PREF_F3; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, 0, src, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, vreg, src, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); byte = U8(byte | (byte << 2)); FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && pref == EX86_PREF_F2) - return emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0); + return emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); - src = vreg; + src = freg; /* fallthrough */ case 2: byte = U8(src_lane_index); @@ -4551,14 +4493,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c } if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, src, 0)); + FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, src, 0)); else - FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, src, 0)); + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); return emit_byte(compiler, U8(byte | (byte << 4))); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 src, sljit_sw srcw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4568,7 +4510,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler sljit_u8 opcode; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_extend(compiler, type, vreg, src, srcw)); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); ADJUST_LOCAL_OFFSET(src, srcw); @@ -4591,8 +4533,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (use_vex) - return emit_vex_instruction(compiler, CVTPS2PD_x_xm | ((reg_size == 5) ? VEX_256 : 0) | EX86_SSE2, vreg, 0, src, srcw); - return emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, vreg, src, srcw); + return emit_vex_instruction(compiler, CVTPS2PD_x_xm | ((reg_size == 5) ? VEX_256 : 0) | EX86_SSE2, freg, 0, src, srcw); + return emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, freg, src, srcw); } switch (elem_size) { @@ -4628,12 +4570,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler return SLJIT_SUCCESS; if (use_vex) - return emit_vex_instruction(compiler, opcode | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, src, srcw); - return emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, src, srcw); + return emit_vex_instruction(compiler, opcode | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, srcw); + return emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, src, srcw); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 vreg, + sljit_s32 freg, sljit_s32 dst, sljit_sw dstw) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); @@ -4644,7 +4586,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c sljit_u8 *inst; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_sign(compiler, type, vreg, dst, dstw)); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -4665,10 +4607,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c switch (elem_size) { case 1: if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, vreg, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, freg, freg, 0)); else - FAIL_IF(emit_groupf(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, vreg, 0)); - vreg = TMP_FREG; + FAIL_IF(emit_groupf(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, freg, 0)); + freg = TMP_FREG; break; case 2: op = EX86_SSE2_OP2; @@ -4679,9 +4621,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c op |= (elem_size < 2) ? PMOVMSKB_r_x : MOVMSKPS_r_x; if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, freg, 0)); else - FAIL_IF(emit_groupf(compiler, op, dst_r, vreg, 0)); + FAIL_IF(emit_groupf(compiler, op, dst_r, freg, 0)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = type & SLJIT_32; @@ -4708,9 +4650,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; if (elem_size == 1) { - FAIL_IF(emit_vex_instruction(compiler, VEXTRACTI128_x_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, vreg, 0, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, VEXTRACTI128_x_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); FAIL_IF(emit_byte(compiler, 1)); - FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, vreg, TMP_FREG, 0)); + FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, freg, TMP_FREG, 0)); FAIL_IF(emit_groupf(compiler, PMOVMSKB_r_x | EX86_PREF_66 | EX86_SSE2_OP2, dst_r, TMP_FREG, 0)); } else { op = MOVMSKPS_r_x | VEX_256 | EX86_SSE2_OP2; @@ -4720,7 +4662,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c else if (elem_size == 3) op |= EX86_PREF_66; - FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, vreg, 0)); + FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, freg, 0)); } if (dst_r == TMP_REG1) { @@ -4734,7 +4676,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c } static sljit_s32 emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src_vreg) + sljit_s32 dst_freg, sljit_s32 src_freg) { sljit_uw op = ((type & SLJIT_SIMD_FLOAT) ? MOVAPS_x_xm : MOVDQA_x_xm) | EX86_SSE2; @@ -4743,21 +4685,18 @@ static sljit_s32 emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, if (!(type & SLJIT_SIMD_FLOAT) || SLJIT_SIMD_GET_ELEM_SIZE(type) == 3) op |= EX86_PREF_66; - return emit_groupf(compiler, op, dst_vreg, src_vreg, 0); + return emit_groupf(compiler, op, dst_freg, src_freg, 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_vreg, sljit_s32 src1_vreg, sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) { sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); - sljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX); sljit_uw op = 0; - sljit_uw mov_op = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_simd_op2(compiler, type, dst_vreg, src1_vreg, src2, src2w)); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -4791,52 +4730,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) op |= EX86_PREF_66; break; - - case SLJIT_SIMD_OP2_SHUFFLE: - if (reg_size != 4) - return SLJIT_ERR_UNSUPPORTED; - - op = PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38; - break; } if (type & SLJIT_SIMD_TEST) return SLJIT_SUCCESS; - if ((src2 & SLJIT_MEM) && SLJIT_SIMD_GET_ELEM2_SIZE(type) < reg_size) { - mov_op = ((type & SLJIT_SIMD_FLOAT) ? (MOVUPS_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0)) : (MOVDQU_x_xm | EX86_PREF_F3)) | EX86_SSE2; - if (use_vex) - FAIL_IF(emit_vex_instruction(compiler, mov_op, TMP_FREG, 0, src2, src2w)); - else - FAIL_IF(emit_groupf(compiler, mov_op, TMP_FREG, src2, src2w)); - - src2 = TMP_FREG; - src2w = 0; - } - - if (reg_size == 5 || use_vex) { + if (reg_size == 5 || ((cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX))) { if (reg_size == 5) op |= VEX_256; - return emit_vex_instruction(compiler, op | EX86_SSE2 | VEX_SSE2_OPV, dst_vreg, src1_vreg, src2, src2w); + return emit_vex_instruction(compiler, op | EX86_SSE2 | VEX_SSE2_OPV, dst_freg, src1_freg, src2_freg, 0); } - if (dst_vreg != src1_vreg) { - if (dst_vreg == src2) { - if (SLJIT_SIMD_GET_OPCODE(type) == SLJIT_SIMD_OP2_SHUFFLE) { - FAIL_IF(emit_simd_mov(compiler, type, TMP_FREG, src2)); - FAIL_IF(emit_simd_mov(compiler, type, dst_vreg, src1_vreg)); - src2 = TMP_FREG; - src2w = 0; - } else - src2 = src1_vreg; - } else - FAIL_IF(emit_simd_mov(compiler, type, dst_vreg, src1_vreg)); + if (dst_freg != src1_freg) { + if (dst_freg == src2_freg) + src2_freg = src1_freg; + else + FAIL_IF(emit_simd_mov(compiler, type, dst_freg, src1_freg)); } - if (op & (VEX_OP_0F38 | VEX_OP_0F3A)) - return emit_groupf_ext(compiler, op | EX86_SSE2, dst_vreg, src2, src2w); - return emit_groupf(compiler, op | EX86_SSE2, dst_vreg, src2, src2w); + FAIL_IF(emit_groupf(compiler, op | EX86_SSE2, dst_freg, src2_freg, 0)); + return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, @@ -4846,14 +4760,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler CHECK_ERROR(); CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); - if ((op & SLJIT_ATOMIC_USE_LS) || GET_OPCODE(op) == SLJIT_MOV_S8 || GET_OPCODE(op) == SLJIT_MOV_S16 || GET_OPCODE(op) == SLJIT_MOV_S32) - return SLJIT_ERR_UNSUPPORTED; - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op1(compiler, op & ~SLJIT_ATOMIC_USE_CAS, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); + return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, @@ -4862,9 +4770,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler sljit_s32 temp_reg) { sljit_uw pref; + sljit_s32 free_reg = TMP_REG1; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_s32 saved_reg = TMP_REG1; - sljit_s32 swap_tmp = 0; sljit_sw srcw = 0; sljit_sw tempw = 0; #endif /* SLJIT_CONFIG_X86_32 */ @@ -4877,43 +4784,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler SLJIT_ASSERT(FAST_IS_REG(src_reg) || src_reg == SLJIT_MEM1(SLJIT_SP)); SLJIT_ASSERT(FAST_IS_REG(temp_reg) || temp_reg == SLJIT_MEM1(SLJIT_SP)); - if ((op & SLJIT_ATOMIC_USE_LS) || GET_OPCODE(op) == SLJIT_MOV_S8 || GET_OPCODE(op) == SLJIT_MOV_S16 || GET_OPCODE(op) == SLJIT_MOV_S32) - return SLJIT_ERR_UNSUPPORTED; - - if (op & SLJIT_ATOMIC_TEST) - return SLJIT_SUCCESS; - op = GET_OPCODE(op); - #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (temp_reg == SLJIT_TMP_DEST_REG) { - FAIL_IF(emit_byte(compiler, XCHG_EAX_r | reg_map[TMP_REG1])); - - if (src_reg == SLJIT_R0) - src_reg = TMP_REG1; - if (mem_reg == SLJIT_R0) - mem_reg = TMP_REG1; - - temp_reg = SLJIT_R0; - swap_tmp = 1; - } - - /* Src is virtual register or its low byte is not accessible. */ if ((src_reg & SLJIT_MEM) || (op == SLJIT_MOV_U8 && reg_map[src_reg] >= 4)) { - SLJIT_ASSERT(src_reg != SLJIT_R1 && temp_reg != SLJIT_TMP_DEST_REG); - - if (swap_tmp) { - saved_reg = (mem_reg != SLJIT_R1) ? SLJIT_R1 : SLJIT_R2; - - EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, saved_reg, 0); - EMIT_MOV(compiler, saved_reg, 0, src_reg, srcw); - } else - EMIT_MOV(compiler, TMP_REG1, 0, src_reg, srcw); + /* Src is virtual register or its low byte is not accessible. */ + SLJIT_ASSERT(src_reg != SLJIT_R1); + free_reg = src_reg; - src_reg = saved_reg; + EMIT_MOV(compiler, TMP_REG1, 0, src_reg, srcw); + src_reg = TMP_REG1; if (mem_reg == src_reg) - mem_reg = saved_reg; + mem_reg = TMP_REG1; } #endif /* SLJIT_CONFIG_X86_32 */ @@ -4921,37 +4803,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; - EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, 0); if (src_reg == SLJIT_R0) - src_reg = TMP_REG2; + src_reg = free_reg; if (mem_reg == SLJIT_R0) - mem_reg = TMP_REG2; + mem_reg = free_reg; #else /* !SLJIT_CONFIG_X86_64 */ - SLJIT_ASSERT(!swap_tmp); - - if (src_reg == TMP_REG1) { - if (mem_reg == SLJIT_R0) { - EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R1, 0); - EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_R0, 0); - EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + if (src_reg == TMP_REG1 && mem_reg == SLJIT_R0 && (free_reg & SLJIT_MEM)) { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R1, 0); + EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); - mem_reg = SLJIT_R1; - saved_reg = SLJIT_R1; - } else { - EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0); - EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); - saved_reg = SLJIT_R0; - } + mem_reg = SLJIT_R1; + free_reg = SLJIT_R1; } else { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); if (src_reg == SLJIT_R0) - src_reg = TMP_REG1; + src_reg = free_reg; if (mem_reg == SLJIT_R0) - mem_reg = TMP_REG1; + mem_reg = free_reg; } #endif /* SLJIT_CONFIG_X86_64 */ } @@ -4973,25 +4847,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler FAIL_IF(emit_groupf(compiler, (op == SLJIT_MOV_U8 ? CMPXCHG_rm8_r : CMPXCHG_rm_r) | pref, src_reg, SLJIT_MEM1(mem_reg), 0)); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (swap_tmp) { - SLJIT_ASSERT(temp_reg == SLJIT_R0); - FAIL_IF(emit_byte(compiler, XCHG_EAX_r | reg_map[TMP_REG1])); - - if (saved_reg != TMP_REG1) - return emit_mov(compiler, saved_reg, 0, SLJIT_MEM1(SLJIT_SP), 0); - return SLJIT_SUCCESS; - } -#endif /* SLJIT_CONFIG_X86_32 */ - if (temp_reg != SLJIT_R0) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; - return emit_mov(compiler, SLJIT_R0, 0, TMP_REG2, 0); + return emit_mov(compiler, SLJIT_R0, 0, TMP_REG1, 0); #else /* !SLJIT_CONFIG_X86_64 */ - EMIT_MOV(compiler, SLJIT_R0, 0, (saved_reg == SLJIT_R0) ? SLJIT_MEM1(SLJIT_SP) : saved_reg, 0); - if (saved_reg == SLJIT_R1) - return emit_mov(compiler, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_SP), 0); + EMIT_MOV(compiler, SLJIT_R0, 0, free_reg, 0); + if (free_reg != TMP_REG1) + return emit_mov(compiler, free_reg, 0, (free_reg == SLJIT_R1) ? SLJIT_MEM1(SLJIT_SP) : TMP_REG1, 0); #endif /* SLJIT_CONFIG_X86_64 */ } return SLJIT_SUCCESS; diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 8e0fb2cce5f9..6a62d9717e7b 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ @@ -622,7 +620,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo /* Parse through the leading whitespace, and display a warning if we get to the end without encountering a delimiter. */ - while (isspace((int)*(unsigned char *)p)) p++; + while (isspace((unsigned char)*p)) p++; if (p >= end_p) { if (key != regex) { zend_string_release_ex(key, 0); @@ -635,7 +633,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo /* Get the delimiter and display a warning if it is alphanumeric or a backslash. */ delimiter = *p++; - if (isalnum((int)*(unsigned char *)&delimiter) || delimiter == '\\' || delimiter == '\0') { + if (isalnum((unsigned char)delimiter) || delimiter == '\\' || delimiter == '\0') { if (key != regex) { zend_string_release_ex(key, 0); } @@ -750,21 +748,23 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo } if (key != regex) { - tables = (uint8_t *)zend_hash_find_ptr(&char_tables, BG(ctype_string)); - if (!tables) { - zend_string *_k; + zv = zend_hash_str_lookup(&char_tables, ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string))); + if (Z_ISNULL_P(zv)) { tables = pcre2_maketables(gctx); if (UNEXPECTED(!tables)) { + /* Remove the placeholder entry created by zend_hash_str_lookup(), + * set ptr to NULL first so the destructor (pefree) is safe. */ + ZVAL_PTR(zv, NULL); + zend_hash_str_del(&char_tables, ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string))); php_error_docref(NULL,E_WARNING, "Failed to generate locale character tables"); pcre_handle_exec_error(PCRE2_ERROR_NOMEMORY); zend_string_release_ex(key, 0); efree(pattern); return NULL; } - _k = zend_string_init(ZSTR_VAL(BG(ctype_string)), ZSTR_LEN(BG(ctype_string)), 1); - GC_MAKE_PERSISTENT_LOCAL(_k); - zend_hash_add_ptr(&char_tables, _k, (void *)tables); - zend_string_release(_k); + ZVAL_PTR(zv, (void *)tables); + } else { + tables = Z_PTR_P(zv); } } pcre2_set_character_tables(cctx, tables); @@ -826,21 +826,12 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo new_entry.refcount = 0; new_entry.subpats_table = NULL; - rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &new_entry.capture_count); - if (rc < 0) { - if (key != regex) { - zend_string_release_ex(key, 0); - } - php_error_docref(NULL, E_WARNING, "Internal pcre2_pattern_info() error %d", rc); - pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); - return NULL; - } - - rc = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &new_entry.name_count); - if (rc < 0) { + if ((rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &new_entry.capture_count)) < 0 || + (rc = pcre2_pattern_info(re, PCRE2_INFO_NAMECOUNT, &new_entry.name_count)) < 0) { if (key != regex) { zend_string_release_ex(key, 0); } + pcre2_code_free(new_entry.re); php_error_docref(NULL, E_WARNING, "Internal pcre_pattern_info() error %d", rc); pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); return NULL; @@ -1088,7 +1079,7 @@ static void populate_subpat_array( /* Add MARK, if available */ if (mark) { ZVAL_STRING(&val, (char *)mark); - zend_hash_str_add_new(subpats_ht, ZEND_STRL("MARK"), &val); + zend_hash_str_update(subpats_ht, ZEND_STRL("MARK"), &val); } } @@ -1132,12 +1123,12 @@ static zend_always_inline bool is_known_valid_utf8( zend_string *subject_str, PCRE2_SIZE start_offset) { if (!ZSTR_IS_VALID_UTF8(subject_str)) { /* We don't know whether the string is valid UTF-8 or not. */ - return 0; + return false; } if (start_offset == ZSTR_LEN(subject_str)) { /* Degenerate case: Offset points to end of string. */ - return 1; + return true; } /* Check that the offset does not point to an UTF-8 continuation byte. */ @@ -1165,6 +1156,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, HashTable *marks = NULL; /* Array of marks for PREG_PATTERN_ORDER */ pcre2_match_data *match_data; PCRE2_SIZE start_offset2, orig_start_offset; + bool old_mdata_used; char *subject = ZSTR_VAL(subject_str); size_t subject_len = ZSTR_LEN(subject_str); @@ -1234,7 +1226,9 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, matched = 0; PCRE_G(error_code) = PHP_PCRE_NO_ERROR; - if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + old_mdata_used = mdata_used; + if (!old_mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + mdata_used = true; match_data = mdata; } else { match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); @@ -1286,7 +1280,18 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, if (subpats != NULL) { /* Try to get the list of substrings and display a warning if failed. */ if (UNEXPECTED(offsets[1] < offsets[0])) { - if (match_sets) efree(match_sets); + if (match_sets) { + for (i = 0; i < num_subpats; i++) { + zend_array_destroy(match_sets[i]); + } + efree(match_sets); + } + if (marks) { + zend_array_destroy(marks); + } + if (match_data != mdata) { + pcre2_match_data_free(match_data); + } php_error_docref(NULL, E_WARNING, "Get subpatterns list failed"); RETURN_FALSE; } @@ -1420,6 +1425,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, if (match_data != mdata) { pcre2_match_data_free(match_data); } + mdata_used = old_mdata_used; /* Add the match sets to the output array and clean up */ if (match_sets) { @@ -1481,7 +1487,8 @@ ZEND_FRAMELESS_FUNCTION(preg_match, 2) /* Compile regex or get it from cache. */ pcre_cache_entry *pce; if ((pce = pcre_get_compiled_regex_cache(regex)) == NULL) { - RETURN_FALSE; + RETVAL_FALSE; + goto flf_clean; } pce->refcount++; @@ -1552,6 +1559,7 @@ static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cach fci->retval = &retval; fci->param_count = 1; fci->params = &arg; + fci->consumed_args = zend_fci_consumed_arg(0); zend_call_function(fci, fcc); zval_ptr_dtor(&arg); if (EXPECTED(Z_TYPE(retval) == IS_STRING)) { @@ -1615,6 +1623,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su size_t result_len; /* Length of result */ zend_string *result; /* Result of replacement */ pcre2_match_data *match_data; + bool old_mdata_used; /* Calculate the size of the offsets array, and allocate memory for it. */ num_subpats = pce->capture_count + 1; @@ -1628,7 +1637,9 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su result_len = 0; PCRE_G(error_code) = PHP_PCRE_NO_ERROR; - if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + old_mdata_used = mdata_used; + if (!old_mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + mdata_used = true; match_data = mdata; } else { match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); @@ -1687,10 +1698,10 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su walk = ZSTR_VAL(replace_str); replace_end = walk + ZSTR_LEN(replace_str); walk_last = 0; - simple_string = 1; + simple_string = true; while (walk < replace_end) { if ('\\' == *walk || '$' == *walk) { - simple_string = 0; + simple_string = false; if (walk_last == '\\') { walk++; walk_last = 0; @@ -1830,6 +1841,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su if (match_data != mdata) { pcre2_match_data_free(match_data); } + mdata_used = old_mdata_used; return result; } @@ -2473,7 +2485,7 @@ PHP_FUNCTION(preg_replace_callback_array) case IS_NULL: RETVAL_NULL(); goto error; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (EG(exception)) { @@ -2555,6 +2567,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str, uint32_t num_subpats; /* Number of captured subpatterns */ zval tmp; pcre2_match_data *match_data; + bool old_mdata_used; char *subject = ZSTR_VAL(subject_str); no_empty = flags & PREG_SPLIT_NO_EMPTY; @@ -2581,7 +2594,9 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str, goto last; } - if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + old_mdata_used = mdata_used; + if (!old_mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + mdata_used = true; match_data = mdata; } else { match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); @@ -2710,6 +2725,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str, if (match_data != mdata) { pcre2_match_data_free(match_data); } + mdata_used = old_mdata_used; if (PCRE_G(error_code) != PHP_PCRE_NO_ERROR) { zval_ptr_dtor(return_value); @@ -2909,6 +2925,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return zend_ulong num_key; bool invert; /* Whether to return non-matching entries */ + bool old_mdata_used; pcre2_match_data *match_data; invert = flags & PREG_GREP_INVERT ? 1 : 0; @@ -2921,7 +2938,9 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return PCRE_G(error_code) = PHP_PCRE_NO_ERROR; - if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + old_mdata_used = mdata_used; + if (!old_mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { + mdata_used = true; match_data = mdata; } else { match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); @@ -2986,6 +3005,13 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return if (match_data != mdata) { pcre2_match_data_free(match_data); } + + mdata_used = old_mdata_used; + + if (PCRE_G(error_code) != PHP_PCRE_NO_ERROR) { + zend_array_destroy(Z_ARR_P(return_value)); + RETURN_FALSE; + } } /* }}} */ diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h index e180d68a3d48..ebaa686a31c3 100644 --- a/ext/pcre/php_pcre.h +++ b/ext/pcre/php_pcre.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ diff --git a/ext/pcre/php_pcre_arginfo.h b/ext/pcre/php_pcre_arginfo.h index 86eaf0d8d60f..0d22c2414fb8 100644 --- a/ext/pcre/php_pcre_arginfo.h +++ b/ext/pcre/php_pcre_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit php_pcre.stub.php instead. * Stub hash: 63de1d37ab303e1d6af7c96eaeeba09d7f35d116 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_match, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) diff --git a/ext/pcre/tests/grep2.phpt b/ext/pcre/tests/grep2.phpt index 9721dfbd9eec..a953b13c49d5 100644 --- a/ext/pcre/tests/grep2.phpt +++ b/ext/pcre/tests/grep2.phpt @@ -21,7 +21,7 @@ var_dump(preg_last_error() == PREG_RECURSION_LIMIT_ERROR); ?> --EXPECTF-- -Warning: preg_grep(): Compilation failed: quantifier does not follow a repeatable item at offset 0 in %sgrep2.php on line %d +Warning: preg_grep(): Compilation failed: quantifier does not follow a repeatable item at offset %r(0|1)%r in %sgrep2.php on line %d bool(false) array(3) { [5]=> diff --git a/ext/pcre/tests/mark_named_collision.phpt b/ext/pcre/tests/mark_named_collision.phpt new file mode 100644 index 000000000000..b644c4d44023 --- /dev/null +++ b/ext/pcre/tests/mark_named_collision.phpt @@ -0,0 +1,15 @@ +--TEST-- +preg_match: (*MARK:name) directive does not collide with named group called MARK +--FILE-- +[abc])(*MARK:value)/', "abc", $m); +echo "count: ", count($m), "\n"; +echo "MARK: ", $m['MARK'], "\n"; +echo "json: ", json_encode($m), "\n"; +echo "keys: ", implode(',', array_keys($m)), "\n"; +?> +--EXPECT-- +count: 3 +MARK: value +json: {"0":"a","MARK":"value","1":"a"} +keys: 0,MARK,1 diff --git a/ext/pcre/tests/pcre_extra.phpt b/ext/pcre/tests/pcre_extra.phpt index 730c7299390c..660e0a1488a1 100644 --- a/ext/pcre/tests/pcre_extra.phpt +++ b/ext/pcre/tests/pcre_extra.phpt @@ -8,8 +8,8 @@ var_dump(preg_match('/\y/X', '\y')); ?> --EXPECTF-- -Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in %spcre_extra.php on line 3 +Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset %r(1|2)%r in %spcre_extra.php on line 3 bool(false) -Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset 1 in %spcre_extra.php on line 4 +Warning: preg_match(): Compilation failed: unrecognized character follows \ at offset %r(1|2)%r in %spcre_extra.php on line 4 bool(false) diff --git a/ext/pcre/tests/pcre_reentrancy.phpt b/ext/pcre/tests/pcre_reentrancy.phpt new file mode 100644 index 000000000000..5fe4071e4fe1 --- /dev/null +++ b/ext/pcre/tests/pcre_reentrancy.phpt @@ -0,0 +1,58 @@ +--TEST-- +PCRE re-entrancy: nested calls should not corrupt global match data +--EXTENSIONS-- +pcre +--FILE-- + +--EXPECT-- +Testing nested PCRE calls... +Outer match: a +Outer match: b +Outer match: c +string(3) "ABC" + +Testing deep nesting... +string(7) "SUCCESS" diff --git a/ext/pcre/tests/preg_grep_error_utf8.phpt b/ext/pcre/tests/preg_grep_error_utf8.phpt new file mode 100644 index 000000000000..efdd7632ab71 --- /dev/null +++ b/ext/pcre/tests/preg_grep_error_utf8.phpt @@ -0,0 +1,44 @@ +--TEST-- +preg_grep() returns false on match execution error (e.g. malformed UTF-8) +--FILE-- + +--EXPECTF-- +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +array(2) { + [0]=> + string(3) "foo" + [1]=> + string(3) "bar" +} +bool(true) diff --git a/ext/pcre/tests/preg_match_frameless_leak.phpt b/ext/pcre/tests/preg_match_frameless_leak.phpt new file mode 100644 index 000000000000..b97cb86347fb --- /dev/null +++ b/ext/pcre/tests/preg_match_frameless_leak.phpt @@ -0,0 +1,23 @@ +--TEST-- +Memory leak in preg_match() frameless function with invalid regex and object arguments +--FILE-- +val = str_repeat($val, random_int(1, 1)); + } + public function __toString() { + return $this->val; + } +} + +$regex = new Str("invalid regex"); +$subject = new Str("some subject"); + +@preg_match($regex, $subject); + +echo "Done"; +?> +--EXPECT-- +Done diff --git a/ext/pcre/tests/preg_replace_callback_array_error.phpt b/ext/pcre/tests/preg_replace_callback_array_error.phpt index fc531b3b02a1..02f50d048cd0 100644 --- a/ext/pcre/tests/preg_replace_callback_array_error.phpt +++ b/ext/pcre/tests/preg_replace_callback_array_error.phpt @@ -21,18 +21,6 @@ var_dump( ) ); -var_dump( - preg_replace_callback_array( - [ - '/a/' => 'b', - null => function () { - return 'ok'; - }, - ], - 'a' - ) -); - // backslashes var_dump( @@ -92,9 +80,6 @@ var_dump( Warning: preg_replace_callback_array(): Empty regular expression in %spreg_replace_callback_array_error.php on line %d NULL -Warning: preg_replace_callback_array(): Empty regular expression in %spreg_replace_callback_array_error.php on line %d -NULL - Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric, backslash, or NUL byte in %spreg_replace_callback_array_error.php on line %d NULL diff --git a/ext/pcre/tests/preg_replace_callback_matches_refcount.phpt b/ext/pcre/tests/preg_replace_callback_matches_refcount.phpt new file mode 100644 index 000000000000..0ae802654c9a --- /dev/null +++ b/ext/pcre/tests/preg_replace_callback_matches_refcount.phpt @@ -0,0 +1,37 @@ +--TEST-- +preg_replace_callback(): capture match array refcount stays low during callback +--FILE-- + static function ($matches) { + debug_zval_dump($matches); + return ''; +}], 'abc')); +?> +--EXPECTF-- +array(4) packed refcount(2){ + [0]=> + string(3) "abc"%s + [1]=> + string(1) "a" interned + [2]=> + string(1) "b" interned + [3]=> + string(1) "c" interned +} +string(0) "" +array(4) packed refcount(2){ + [0]=> + string(3) "abc"%s + [1]=> + string(1) "a" interned + [2]=> + string(1) "b" interned + [3]=> + string(1) "c" interned +} +string(0) "" diff --git a/ext/pcre/tests/split.phpt b/ext/pcre/tests/split.phpt index df4b9af92f2f..27f1c85b433e 100644 --- a/ext/pcre/tests/split.phpt +++ b/ext/pcre/tests/split.phpt @@ -16,7 +16,7 @@ var_dump(preg_split('/\d*/', 'ab2c3u', -1, PREG_SPLIT_NO_EMPTY)); ?> --EXPECTF-- -Warning: preg_split(): Compilation failed: quantifier does not follow a repeatable item at offset 0 in %ssplit.php on line %d +Warning: preg_split(): Compilation failed: quantifier does not follow a repeatable item at offset %r(0|1)%r in %ssplit.php on line %d bool(false) array(3) { [0]=> diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index a213fa1c8727..5b881b0f56da 100644 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | @@ -115,11 +113,9 @@ PDO_API zend_result php_pdo_register_driver(const pdo_driver_t *driver) /* {{{ * if (driver->api_version != PDO_DRIVER_API) { zend_error_noreturn(E_ERROR, "PDO: driver %s requires PDO API version " ZEND_ULONG_FMT "; this is PDO version %d", driver->driver_name, driver->api_version, PDO_DRIVER_API); - return FAILURE; } if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) { zend_error_noreturn(E_ERROR, "The PDO extension must be loaded first in order to load PDO drivers"); - return FAILURE; /* NOTREACHED */ } return zend_hash_str_add_ptr(&pdo_driver_hash, driver->driver_name, driver->driver_name_len, (void*)driver) != NULL ? SUCCESS : FAILURE; @@ -141,7 +137,6 @@ PDO_API zend_result php_pdo_register_driver_specific_ce(const pdo_driver_t *driv { if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) { zend_error_noreturn(E_ERROR, "The PDO extension must be loaded first in order to load PDO drivers"); - return FAILURE; /* NOTREACHED */ } return zend_hash_str_add_ptr(&pdo_driver_specific_ce_hash, driver->driver_name, @@ -244,7 +239,7 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, zend_ulong data_s } } - while (i < data_source_len && isspace(data_source[i])) { + while (i < data_source_len && isspace((unsigned char)data_source[i])) { i++; } diff --git a/ext/pdo/pdo_arginfo.h b/ext/pdo/pdo_arginfo.h index d2df2f0b0eb2..8327b383a1b9 100644 --- a/ext/pdo/pdo_arginfo.h +++ b/ext/pdo/pdo_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pdo.stub.php instead. * Stub hash: dc41dddeea1ae117c6f2f3447afb29bf6623b757 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pdo_drivers, 0, 0, IS_ARRAY, 0) @@ -24,9 +24,9 @@ static zend_class_entry *register_class_PDOException(zend_class_entry *class_ent zval property_errorInfo_default_value; ZVAL_NULL(&property_errorInfo_default_value); - zend_string *property_errorInfo_name = zend_string_init("errorInfo", sizeof("errorInfo") - 1, 1); + zend_string *property_errorInfo_name = zend_string_init("errorInfo", sizeof("errorInfo") - 1, true); zend_declare_typed_property(class_entry, property_errorInfo_name, &property_errorInfo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release(property_errorInfo_name); + zend_string_release_ex(property_errorInfo_name, true); return class_entry; } diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 9588f23d420c..6a47ec30c862 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | @@ -347,6 +345,11 @@ PDO_API void php_pdo_internal_construct_driver(INTERNAL_FUNCTION_PARAMETERS, zen } if (!strncmp(data_source, "uri:", sizeof("uri:")-1)) { + zend_error(E_DEPRECATED, "Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs"); + if (EG(exception)) { + RETURN_THROWS(); + } + /* the specified URI holds connection details */ data_source = dsn_from_uri(data_source + sizeof("uri:")-1, alt_dsn, sizeof(alt_dsn)); if (!data_source) { @@ -800,7 +803,7 @@ PDO_API bool pdo_get_bool_param(bool *bval, const zval *value) *bval = false; return true; case IS_LONG: - *bval = zval_is_true(value); + *bval = zend_is_true(value); return true; case IS_STRING: /* TODO Should string be allowed? */ default: @@ -1185,7 +1188,7 @@ PHP_METHOD(PDO, query) pdo_stmt_t *stmt; zend_string *statement; zend_long fetch_mode; - bool fetch_mode_is_null = 1; + bool fetch_mode_is_null = true; zval *args = NULL; uint32_t num_args = 0; pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS); @@ -1313,6 +1316,10 @@ static void cls_method_dtor(zval *el) /* {{{ */ { if (ZEND_MAP_PTR(func->common.run_time_cache)) { efree(ZEND_MAP_PTR(func->common.run_time_cache)); } + if (func->common.attributes) { + zend_hash_release(func->common.attributes); + } + zend_free_internal_arg_info(&func->internal_function, false); efree(func); } /* }}} */ @@ -1325,10 +1332,40 @@ static void cls_method_pdtor(zval *el) /* {{{ */ { if (ZEND_MAP_PTR(func->common.run_time_cache)) { pefree(ZEND_MAP_PTR(func->common.run_time_cache), 1); } + if (func->common.attributes) { + zend_hash_release(func->common.attributes); + } + zend_free_internal_arg_info(&func->internal_function, true); pefree(func, 1); } /* }}} */ +/* We cannot add #[Deprecated] attributes in @generate-function-entries stubs, + * and PDO drivers have no way to add them either, so we hard-code deprecation + * info here and add the attribute manually in pdo_hash_methods() */ +struct driver_specific_method_deprecation { + const char *old_name; + const char *new_name; +}; + +/* Methods deprecated in https://wiki.php.net/rfc/deprecations_php_8_5 + * "Deprecate driver specific PDO constants and methods" */ +static const struct driver_specific_method_deprecation driver_specific_method_deprecations[] = { + {"pgsqlCopyFromArray", "Pdo\\Pgsql::copyFromArray"}, + {"pgsqlCopyFromFile", "Pdo\\Pgsql::copyFromFile"}, + {"pgsqlCopyToArray", "Pdo\\Pgsql::copyToArray"}, + {"pgsqlCopyToFile", "Pdo\\Pgsql::copyToFile"}, + {"pgsqlGetNotify", "Pdo\\Pgsql::getNotify"}, + {"pgsqlGetPid", "Pdo\\Pgsql::getPid"}, + {"pgsqlLOBCreate", "Pdo\\Pgsql::lobCreate"}, + {"pgsqlLOBOpen", "Pdo\\Pgsql::lobOpen"}, + {"pgsqlLOBUnlink", "Pdo\\Pgsql::lobUnlink"}, + {"sqliteCreateAggregate", "Pdo\\Sqlite::createAggregate"}, + {"sqliteCreateCollation", "Pdo\\Sqlite::createCollation"}, + {"sqliteCreateFunction", "Pdo\\Sqlite::createFunction"}, + {NULL, NULL}, +}; + /* {{{ overloaded object handlers for PDO class */ bool pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind) { @@ -1357,7 +1394,7 @@ bool pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind) func.type = ZEND_INTERNAL_FUNCTION; func.handler = funcs->handler; func.function_name = zend_string_init(funcs->fname, strlen(funcs->fname), dbh->is_persistent); - func.scope = dbh_obj->std.ce; + func.scope = pdo_dbh_ce; func.prototype = NULL; ZEND_MAP_PTR(func.run_time_cache) = rt_cache_size ? pecalloc(rt_cache_size, 1, dbh->is_persistent) : NULL; func.T = ZEND_OBSERVER_ENABLED; @@ -1366,11 +1403,24 @@ bool pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind) } else { func.fn_flags = ZEND_ACC_PUBLIC | ZEND_ACC_NEVER_CACHE; } + func.fn_flags |= ZEND_ACC_DEPRECATED; func.doc_comment = NULL; if (funcs->arg_info) { zend_internal_function_info *info = (zend_internal_function_info*)funcs->arg_info; - func.arg_info = (zend_internal_arg_info*)funcs->arg_info + 1; + uint32_t num_arg_info = 1 + funcs->num_args; + if (func.fn_flags & ZEND_ACC_VARIADIC) { + num_arg_info++; + } + + zend_arg_info *arg_info = safe_pemalloc(num_arg_info, + sizeof(zend_arg_info), 0, dbh->is_persistent); + for (uint32_t i = 0; i < num_arg_info; i++) { + zend_convert_internal_arg_info(&arg_info[i], + &funcs->arg_info[i], i == 0, dbh->is_persistent); + } + + func.arg_info = arg_info + 1; func.num_args = funcs->num_args; if (info->required_num_args == (uint32_t)-1) { func.required_num_args = funcs->num_args; @@ -1394,8 +1444,36 @@ bool pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind) namelen = strlen(funcs->fname); lc_name = emalloc(namelen+1); zend_str_tolower_copy(lc_name, funcs->fname, namelen); - zend_hash_str_add_mem(dbh->cls_methods[kind], lc_name, namelen, &func, sizeof(func)); + zend_function *func_p = zend_hash_str_add_mem(dbh->cls_methods[kind], lc_name, namelen, &func, sizeof(func)); efree(lc_name); + + const char *new_name = NULL; + for (const struct driver_specific_method_deprecation *d = driver_specific_method_deprecations; + d->old_name; d++) { + if (strcmp(d->old_name, funcs->fname) == 0) { + new_name = d->new_name; + break; + } + } + if (new_name) { + uint32_t flags = dbh->is_persistent ? ZEND_ATTRIBUTE_PERSISTENT : 0; + zend_attribute *attr = zend_add_attribute( + &func_p->common.attributes, + ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), + 2, flags, 0, 0); + + attr->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR(&attr->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + + char *message; + size_t len = zend_spprintf(&message, 0, "use %s() instead", new_name); + zend_string *message_str = zend_string_init(message, len, dbh->is_persistent); + efree(message); + + attr->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + ZVAL_STR(&attr->args[1].value, message_str); + } + funcs++; } @@ -1451,7 +1529,7 @@ void pdo_dbh_init(int module_number) pdo_dbh_ce->default_object_handlers = &pdo_dbh_object_handlers; memcpy(&pdo_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pdo_dbh_object_handlers.offset = XtOffsetOf(pdo_dbh_object_t, std); + pdo_dbh_object_handlers.offset = offsetof(pdo_dbh_object_t, std); pdo_dbh_object_handlers.free_obj = pdo_dbh_free_storage; pdo_dbh_object_handlers.clone_obj = NULL; pdo_dbh_object_handlers.get_method = dbh_method_get; @@ -1528,7 +1606,7 @@ static void pdo_dbh_free_storage(zend_object *std) dbh->methods->persistent_shutdown(dbh); } zend_object_std_dtor(std); - dbh_free(dbh, 0); + dbh_free(dbh, false); } zend_object *pdo_dbh_new(zend_class_entry *ce) @@ -1552,7 +1630,7 @@ ZEND_RSRC_DTOR_FUNC(php_pdo_pdbh_dtor) /* {{{ */ { if (res->ptr) { pdo_dbh_t *dbh = (pdo_dbh_t*)res->ptr; - dbh_free(dbh, 1); + dbh_free(dbh, true); res->ptr = NULL; } } diff --git a/ext/pdo/pdo_dbh_arginfo.h b/ext/pdo/pdo_dbh_arginfo.h index 71df4c519e1a..90da5123a487 100644 --- a/ext/pdo/pdo_dbh_arginfo.h +++ b/ext/pdo/pdo_dbh_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pdo_dbh.stub.php instead. * Stub hash: 006be61b2c519e7d9ca997a7f12135eb3e0f3500 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_PDO___construct, 0, 0, 1) @@ -111,454 +111,454 @@ static zend_class_entry *register_class_PDO(void) zval const_PARAM_NULL_value; ZVAL_LONG(&const_PARAM_NULL_value, LONG_CONST(PDO_PARAM_NULL)); - zend_string *const_PARAM_NULL_name = zend_string_init_interned("PARAM_NULL", sizeof("PARAM_NULL") - 1, 1); + zend_string *const_PARAM_NULL_name = zend_string_init_interned("PARAM_NULL", sizeof("PARAM_NULL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_NULL_name, &const_PARAM_NULL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_NULL_name); + zend_string_release_ex(const_PARAM_NULL_name, true); ZEND_ASSERT(LONG_CONST(PDO_PARAM_NULL) == 0); zval const_PARAM_BOOL_value; ZVAL_LONG(&const_PARAM_BOOL_value, LONG_CONST(PDO_PARAM_BOOL)); - zend_string *const_PARAM_BOOL_name = zend_string_init_interned("PARAM_BOOL", sizeof("PARAM_BOOL") - 1, 1); + zend_string *const_PARAM_BOOL_name = zend_string_init_interned("PARAM_BOOL", sizeof("PARAM_BOOL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_BOOL_name, &const_PARAM_BOOL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_BOOL_name); + zend_string_release_ex(const_PARAM_BOOL_name, true); ZEND_ASSERT(LONG_CONST(PDO_PARAM_BOOL) == 5); zval const_PARAM_INT_value; ZVAL_LONG(&const_PARAM_INT_value, LONG_CONST(PDO_PARAM_INT)); - zend_string *const_PARAM_INT_name = zend_string_init_interned("PARAM_INT", sizeof("PARAM_INT") - 1, 1); + zend_string *const_PARAM_INT_name = zend_string_init_interned("PARAM_INT", sizeof("PARAM_INT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_INT_name, &const_PARAM_INT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_INT_name); + zend_string_release_ex(const_PARAM_INT_name, true); ZEND_ASSERT(LONG_CONST(PDO_PARAM_INT) == 1); zval const_PARAM_STR_value; ZVAL_LONG(&const_PARAM_STR_value, LONG_CONST(PDO_PARAM_STR)); - zend_string *const_PARAM_STR_name = zend_string_init_interned("PARAM_STR", sizeof("PARAM_STR") - 1, 1); + zend_string *const_PARAM_STR_name = zend_string_init_interned("PARAM_STR", sizeof("PARAM_STR") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_STR_name, &const_PARAM_STR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_STR_name); + zend_string_release_ex(const_PARAM_STR_name, true); ZEND_ASSERT(LONG_CONST(PDO_PARAM_STR) == 2); zval const_PARAM_LOB_value; ZVAL_LONG(&const_PARAM_LOB_value, LONG_CONST(PDO_PARAM_LOB)); - zend_string *const_PARAM_LOB_name = zend_string_init_interned("PARAM_LOB", sizeof("PARAM_LOB") - 1, 1); + zend_string *const_PARAM_LOB_name = zend_string_init_interned("PARAM_LOB", sizeof("PARAM_LOB") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_LOB_name, &const_PARAM_LOB_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_LOB_name); + zend_string_release_ex(const_PARAM_LOB_name, true); ZEND_ASSERT(LONG_CONST(PDO_PARAM_LOB) == 3); zval const_PARAM_STMT_value; ZVAL_LONG(&const_PARAM_STMT_value, LONG_CONST(PDO_PARAM_STMT)); - zend_string *const_PARAM_STMT_name = zend_string_init_interned("PARAM_STMT", sizeof("PARAM_STMT") - 1, 1); + zend_string *const_PARAM_STMT_name = zend_string_init_interned("PARAM_STMT", sizeof("PARAM_STMT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_STMT_name, &const_PARAM_STMT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_STMT_name); + zend_string_release_ex(const_PARAM_STMT_name, true); ZEND_ASSERT(LONG_CONST(PDO_PARAM_STMT) == 4); zval const_PARAM_INPUT_OUTPUT_value; ZVAL_LONG(&const_PARAM_INPUT_OUTPUT_value, LONG_CONST(PDO_PARAM_INPUT_OUTPUT)); - zend_string *const_PARAM_INPUT_OUTPUT_name = zend_string_init_interned("PARAM_INPUT_OUTPUT", sizeof("PARAM_INPUT_OUTPUT") - 1, 1); + zend_string *const_PARAM_INPUT_OUTPUT_name = zend_string_init_interned("PARAM_INPUT_OUTPUT", sizeof("PARAM_INPUT_OUTPUT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_INPUT_OUTPUT_name, &const_PARAM_INPUT_OUTPUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_INPUT_OUTPUT_name); + zend_string_release_ex(const_PARAM_INPUT_OUTPUT_name, true); zval const_PARAM_STR_NATL_value; ZVAL_LONG(&const_PARAM_STR_NATL_value, LONG_CONST(PDO_PARAM_STR_NATL)); - zend_string *const_PARAM_STR_NATL_name = zend_string_init_interned("PARAM_STR_NATL", sizeof("PARAM_STR_NATL") - 1, 1); + zend_string *const_PARAM_STR_NATL_name = zend_string_init_interned("PARAM_STR_NATL", sizeof("PARAM_STR_NATL") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_STR_NATL_name, &const_PARAM_STR_NATL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_STR_NATL_name); + zend_string_release_ex(const_PARAM_STR_NATL_name, true); zval const_PARAM_STR_CHAR_value; ZVAL_LONG(&const_PARAM_STR_CHAR_value, LONG_CONST(PDO_PARAM_STR_CHAR)); - zend_string *const_PARAM_STR_CHAR_name = zend_string_init_interned("PARAM_STR_CHAR", sizeof("PARAM_STR_CHAR") - 1, 1); + zend_string *const_PARAM_STR_CHAR_name = zend_string_init_interned("PARAM_STR_CHAR", sizeof("PARAM_STR_CHAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_STR_CHAR_name, &const_PARAM_STR_CHAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_STR_CHAR_name); + zend_string_release_ex(const_PARAM_STR_CHAR_name, true); zval const_PARAM_EVT_ALLOC_value; ZVAL_LONG(&const_PARAM_EVT_ALLOC_value, LONG_CONST(PDO_PARAM_EVT_ALLOC)); - zend_string *const_PARAM_EVT_ALLOC_name = zend_string_init_interned("PARAM_EVT_ALLOC", sizeof("PARAM_EVT_ALLOC") - 1, 1); + zend_string *const_PARAM_EVT_ALLOC_name = zend_string_init_interned("PARAM_EVT_ALLOC", sizeof("PARAM_EVT_ALLOC") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_EVT_ALLOC_name, &const_PARAM_EVT_ALLOC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_EVT_ALLOC_name); + zend_string_release_ex(const_PARAM_EVT_ALLOC_name, true); zval const_PARAM_EVT_FREE_value; ZVAL_LONG(&const_PARAM_EVT_FREE_value, LONG_CONST(PDO_PARAM_EVT_FREE)); - zend_string *const_PARAM_EVT_FREE_name = zend_string_init_interned("PARAM_EVT_FREE", sizeof("PARAM_EVT_FREE") - 1, 1); + zend_string *const_PARAM_EVT_FREE_name = zend_string_init_interned("PARAM_EVT_FREE", sizeof("PARAM_EVT_FREE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_EVT_FREE_name, &const_PARAM_EVT_FREE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_EVT_FREE_name); + zend_string_release_ex(const_PARAM_EVT_FREE_name, true); zval const_PARAM_EVT_EXEC_PRE_value; ZVAL_LONG(&const_PARAM_EVT_EXEC_PRE_value, LONG_CONST(PDO_PARAM_EVT_EXEC_PRE)); - zend_string *const_PARAM_EVT_EXEC_PRE_name = zend_string_init_interned("PARAM_EVT_EXEC_PRE", sizeof("PARAM_EVT_EXEC_PRE") - 1, 1); + zend_string *const_PARAM_EVT_EXEC_PRE_name = zend_string_init_interned("PARAM_EVT_EXEC_PRE", sizeof("PARAM_EVT_EXEC_PRE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_EVT_EXEC_PRE_name, &const_PARAM_EVT_EXEC_PRE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_EVT_EXEC_PRE_name); + zend_string_release_ex(const_PARAM_EVT_EXEC_PRE_name, true); zval const_PARAM_EVT_EXEC_POST_value; ZVAL_LONG(&const_PARAM_EVT_EXEC_POST_value, LONG_CONST(PDO_PARAM_EVT_EXEC_POST)); - zend_string *const_PARAM_EVT_EXEC_POST_name = zend_string_init_interned("PARAM_EVT_EXEC_POST", sizeof("PARAM_EVT_EXEC_POST") - 1, 1); + zend_string *const_PARAM_EVT_EXEC_POST_name = zend_string_init_interned("PARAM_EVT_EXEC_POST", sizeof("PARAM_EVT_EXEC_POST") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_EVT_EXEC_POST_name, &const_PARAM_EVT_EXEC_POST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_EVT_EXEC_POST_name); + zend_string_release_ex(const_PARAM_EVT_EXEC_POST_name, true); zval const_PARAM_EVT_FETCH_PRE_value; ZVAL_LONG(&const_PARAM_EVT_FETCH_PRE_value, LONG_CONST(PDO_PARAM_EVT_FETCH_PRE)); - zend_string *const_PARAM_EVT_FETCH_PRE_name = zend_string_init_interned("PARAM_EVT_FETCH_PRE", sizeof("PARAM_EVT_FETCH_PRE") - 1, 1); + zend_string *const_PARAM_EVT_FETCH_PRE_name = zend_string_init_interned("PARAM_EVT_FETCH_PRE", sizeof("PARAM_EVT_FETCH_PRE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_EVT_FETCH_PRE_name, &const_PARAM_EVT_FETCH_PRE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_EVT_FETCH_PRE_name); + zend_string_release_ex(const_PARAM_EVT_FETCH_PRE_name, true); zval const_PARAM_EVT_FETCH_POST_value; ZVAL_LONG(&const_PARAM_EVT_FETCH_POST_value, LONG_CONST(PDO_PARAM_EVT_FETCH_POST)); - zend_string *const_PARAM_EVT_FETCH_POST_name = zend_string_init_interned("PARAM_EVT_FETCH_POST", sizeof("PARAM_EVT_FETCH_POST") - 1, 1); + zend_string *const_PARAM_EVT_FETCH_POST_name = zend_string_init_interned("PARAM_EVT_FETCH_POST", sizeof("PARAM_EVT_FETCH_POST") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_EVT_FETCH_POST_name, &const_PARAM_EVT_FETCH_POST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_EVT_FETCH_POST_name); + zend_string_release_ex(const_PARAM_EVT_FETCH_POST_name, true); zval const_PARAM_EVT_NORMALIZE_value; ZVAL_LONG(&const_PARAM_EVT_NORMALIZE_value, LONG_CONST(PDO_PARAM_EVT_NORMALIZE)); - zend_string *const_PARAM_EVT_NORMALIZE_name = zend_string_init_interned("PARAM_EVT_NORMALIZE", sizeof("PARAM_EVT_NORMALIZE") - 1, 1); + zend_string *const_PARAM_EVT_NORMALIZE_name = zend_string_init_interned("PARAM_EVT_NORMALIZE", sizeof("PARAM_EVT_NORMALIZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_PARAM_EVT_NORMALIZE_name, &const_PARAM_EVT_NORMALIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PARAM_EVT_NORMALIZE_name); + zend_string_release_ex(const_PARAM_EVT_NORMALIZE_name, true); zval const_FETCH_DEFAULT_value; ZVAL_LONG(&const_FETCH_DEFAULT_value, LONG_CONST(PDO_FETCH_USE_DEFAULT)); - zend_string *const_FETCH_DEFAULT_name = zend_string_init_interned("FETCH_DEFAULT", sizeof("FETCH_DEFAULT") - 1, 1); + zend_string *const_FETCH_DEFAULT_name = zend_string_init_interned("FETCH_DEFAULT", sizeof("FETCH_DEFAULT") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_DEFAULT_name, &const_FETCH_DEFAULT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_DEFAULT_name); + zend_string_release_ex(const_FETCH_DEFAULT_name, true); zval const_FETCH_LAZY_value; ZVAL_LONG(&const_FETCH_LAZY_value, LONG_CONST(PDO_FETCH_LAZY)); - zend_string *const_FETCH_LAZY_name = zend_string_init_interned("FETCH_LAZY", sizeof("FETCH_LAZY") - 1, 1); + zend_string *const_FETCH_LAZY_name = zend_string_init_interned("FETCH_LAZY", sizeof("FETCH_LAZY") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_LAZY_name, &const_FETCH_LAZY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_LAZY_name); + zend_string_release_ex(const_FETCH_LAZY_name, true); zval const_FETCH_ASSOC_value; ZVAL_LONG(&const_FETCH_ASSOC_value, LONG_CONST(PDO_FETCH_ASSOC)); - zend_string *const_FETCH_ASSOC_name = zend_string_init_interned("FETCH_ASSOC", sizeof("FETCH_ASSOC") - 1, 1); + zend_string *const_FETCH_ASSOC_name = zend_string_init_interned("FETCH_ASSOC", sizeof("FETCH_ASSOC") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_ASSOC_name, &const_FETCH_ASSOC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_ASSOC_name); + zend_string_release_ex(const_FETCH_ASSOC_name, true); zval const_FETCH_NUM_value; ZVAL_LONG(&const_FETCH_NUM_value, LONG_CONST(PDO_FETCH_NUM)); - zend_string *const_FETCH_NUM_name = zend_string_init_interned("FETCH_NUM", sizeof("FETCH_NUM") - 1, 1); + zend_string *const_FETCH_NUM_name = zend_string_init_interned("FETCH_NUM", sizeof("FETCH_NUM") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_NUM_name, &const_FETCH_NUM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_NUM_name); + zend_string_release_ex(const_FETCH_NUM_name, true); zval const_FETCH_BOTH_value; ZVAL_LONG(&const_FETCH_BOTH_value, LONG_CONST(PDO_FETCH_BOTH)); - zend_string *const_FETCH_BOTH_name = zend_string_init_interned("FETCH_BOTH", sizeof("FETCH_BOTH") - 1, 1); + zend_string *const_FETCH_BOTH_name = zend_string_init_interned("FETCH_BOTH", sizeof("FETCH_BOTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_BOTH_name, &const_FETCH_BOTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_BOTH_name); + zend_string_release_ex(const_FETCH_BOTH_name, true); zval const_FETCH_OBJ_value; ZVAL_LONG(&const_FETCH_OBJ_value, LONG_CONST(PDO_FETCH_OBJ)); - zend_string *const_FETCH_OBJ_name = zend_string_init_interned("FETCH_OBJ", sizeof("FETCH_OBJ") - 1, 1); + zend_string *const_FETCH_OBJ_name = zend_string_init_interned("FETCH_OBJ", sizeof("FETCH_OBJ") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_OBJ_name, &const_FETCH_OBJ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_OBJ_name); + zend_string_release_ex(const_FETCH_OBJ_name, true); zval const_FETCH_BOUND_value; ZVAL_LONG(&const_FETCH_BOUND_value, LONG_CONST(PDO_FETCH_BOUND)); - zend_string *const_FETCH_BOUND_name = zend_string_init_interned("FETCH_BOUND", sizeof("FETCH_BOUND") - 1, 1); + zend_string *const_FETCH_BOUND_name = zend_string_init_interned("FETCH_BOUND", sizeof("FETCH_BOUND") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_BOUND_name, &const_FETCH_BOUND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_BOUND_name); + zend_string_release_ex(const_FETCH_BOUND_name, true); zval const_FETCH_COLUMN_value; ZVAL_LONG(&const_FETCH_COLUMN_value, LONG_CONST(PDO_FETCH_COLUMN)); - zend_string *const_FETCH_COLUMN_name = zend_string_init_interned("FETCH_COLUMN", sizeof("FETCH_COLUMN") - 1, 1); + zend_string *const_FETCH_COLUMN_name = zend_string_init_interned("FETCH_COLUMN", sizeof("FETCH_COLUMN") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_COLUMN_name, &const_FETCH_COLUMN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_COLUMN_name); + zend_string_release_ex(const_FETCH_COLUMN_name, true); zval const_FETCH_CLASS_value; ZVAL_LONG(&const_FETCH_CLASS_value, LONG_CONST(PDO_FETCH_CLASS)); - zend_string *const_FETCH_CLASS_name = zend_string_init_interned("FETCH_CLASS", sizeof("FETCH_CLASS") - 1, 1); + zend_string *const_FETCH_CLASS_name = zend_string_init_interned("FETCH_CLASS", sizeof("FETCH_CLASS") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_CLASS_name, &const_FETCH_CLASS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_CLASS_name); + zend_string_release_ex(const_FETCH_CLASS_name, true); zval const_FETCH_INTO_value; ZVAL_LONG(&const_FETCH_INTO_value, LONG_CONST(PDO_FETCH_INTO)); - zend_string *const_FETCH_INTO_name = zend_string_init_interned("FETCH_INTO", sizeof("FETCH_INTO") - 1, 1); + zend_string *const_FETCH_INTO_name = zend_string_init_interned("FETCH_INTO", sizeof("FETCH_INTO") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_INTO_name, &const_FETCH_INTO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_INTO_name); + zend_string_release_ex(const_FETCH_INTO_name, true); zval const_FETCH_FUNC_value; ZVAL_LONG(&const_FETCH_FUNC_value, LONG_CONST(PDO_FETCH_FUNC)); - zend_string *const_FETCH_FUNC_name = zend_string_init_interned("FETCH_FUNC", sizeof("FETCH_FUNC") - 1, 1); + zend_string *const_FETCH_FUNC_name = zend_string_init_interned("FETCH_FUNC", sizeof("FETCH_FUNC") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_FUNC_name, &const_FETCH_FUNC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_FUNC_name); + zend_string_release_ex(const_FETCH_FUNC_name, true); zval const_FETCH_GROUP_value; ZVAL_LONG(&const_FETCH_GROUP_value, LONG_CONST(PDO_FETCH_GROUP)); - zend_string *const_FETCH_GROUP_name = zend_string_init_interned("FETCH_GROUP", sizeof("FETCH_GROUP") - 1, 1); + zend_string *const_FETCH_GROUP_name = zend_string_init_interned("FETCH_GROUP", sizeof("FETCH_GROUP") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_GROUP_name, &const_FETCH_GROUP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_GROUP_name); + zend_string_release_ex(const_FETCH_GROUP_name, true); zval const_FETCH_UNIQUE_value; ZVAL_LONG(&const_FETCH_UNIQUE_value, LONG_CONST(PDO_FETCH_UNIQUE)); - zend_string *const_FETCH_UNIQUE_name = zend_string_init_interned("FETCH_UNIQUE", sizeof("FETCH_UNIQUE") - 1, 1); + zend_string *const_FETCH_UNIQUE_name = zend_string_init_interned("FETCH_UNIQUE", sizeof("FETCH_UNIQUE") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_UNIQUE_name, &const_FETCH_UNIQUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_UNIQUE_name); + zend_string_release_ex(const_FETCH_UNIQUE_name, true); zval const_FETCH_KEY_PAIR_value; ZVAL_LONG(&const_FETCH_KEY_PAIR_value, LONG_CONST(PDO_FETCH_KEY_PAIR)); - zend_string *const_FETCH_KEY_PAIR_name = zend_string_init_interned("FETCH_KEY_PAIR", sizeof("FETCH_KEY_PAIR") - 1, 1); + zend_string *const_FETCH_KEY_PAIR_name = zend_string_init_interned("FETCH_KEY_PAIR", sizeof("FETCH_KEY_PAIR") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_KEY_PAIR_name, &const_FETCH_KEY_PAIR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_KEY_PAIR_name); + zend_string_release_ex(const_FETCH_KEY_PAIR_name, true); zval const_FETCH_CLASSTYPE_value; ZVAL_LONG(&const_FETCH_CLASSTYPE_value, LONG_CONST(PDO_FETCH_CLASSTYPE)); - zend_string *const_FETCH_CLASSTYPE_name = zend_string_init_interned("FETCH_CLASSTYPE", sizeof("FETCH_CLASSTYPE") - 1, 1); + zend_string *const_FETCH_CLASSTYPE_name = zend_string_init_interned("FETCH_CLASSTYPE", sizeof("FETCH_CLASSTYPE") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_CLASSTYPE_name, &const_FETCH_CLASSTYPE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_CLASSTYPE_name); + zend_string_release_ex(const_FETCH_CLASSTYPE_name, true); zval const_FETCH_SERIALIZE_value; ZVAL_LONG(&const_FETCH_SERIALIZE_value, LONG_CONST(PDO_FETCH_SERIALIZE)); - zend_string *const_FETCH_SERIALIZE_name = zend_string_init_interned("FETCH_SERIALIZE", sizeof("FETCH_SERIALIZE") - 1, 1); + zend_string *const_FETCH_SERIALIZE_name = zend_string_init_interned("FETCH_SERIALIZE", sizeof("FETCH_SERIALIZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_SERIALIZE_name, &const_FETCH_SERIALIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_SERIALIZE_name); + zend_string_release_ex(const_FETCH_SERIALIZE_name, true); zval const_FETCH_PROPS_LATE_value; ZVAL_LONG(&const_FETCH_PROPS_LATE_value, LONG_CONST(PDO_FETCH_PROPS_LATE)); - zend_string *const_FETCH_PROPS_LATE_name = zend_string_init_interned("FETCH_PROPS_LATE", sizeof("FETCH_PROPS_LATE") - 1, 1); + zend_string *const_FETCH_PROPS_LATE_name = zend_string_init_interned("FETCH_PROPS_LATE", sizeof("FETCH_PROPS_LATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_PROPS_LATE_name, &const_FETCH_PROPS_LATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_PROPS_LATE_name); + zend_string_release_ex(const_FETCH_PROPS_LATE_name, true); zval const_FETCH_NAMED_value; ZVAL_LONG(&const_FETCH_NAMED_value, LONG_CONST(PDO_FETCH_NAMED)); - zend_string *const_FETCH_NAMED_name = zend_string_init_interned("FETCH_NAMED", sizeof("FETCH_NAMED") - 1, 1); + zend_string *const_FETCH_NAMED_name = zend_string_init_interned("FETCH_NAMED", sizeof("FETCH_NAMED") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_NAMED_name, &const_FETCH_NAMED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_NAMED_name); + zend_string_release_ex(const_FETCH_NAMED_name, true); zval const_ATTR_AUTOCOMMIT_value; ZVAL_LONG(&const_ATTR_AUTOCOMMIT_value, LONG_CONST(PDO_ATTR_AUTOCOMMIT)); - zend_string *const_ATTR_AUTOCOMMIT_name = zend_string_init_interned("ATTR_AUTOCOMMIT", sizeof("ATTR_AUTOCOMMIT") - 1, 1); + zend_string *const_ATTR_AUTOCOMMIT_name = zend_string_init_interned("ATTR_AUTOCOMMIT", sizeof("ATTR_AUTOCOMMIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_AUTOCOMMIT_name, &const_ATTR_AUTOCOMMIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_AUTOCOMMIT_name); + zend_string_release_ex(const_ATTR_AUTOCOMMIT_name, true); zval const_ATTR_PREFETCH_value; ZVAL_LONG(&const_ATTR_PREFETCH_value, LONG_CONST(PDO_ATTR_PREFETCH)); - zend_string *const_ATTR_PREFETCH_name = zend_string_init_interned("ATTR_PREFETCH", sizeof("ATTR_PREFETCH") - 1, 1); + zend_string *const_ATTR_PREFETCH_name = zend_string_init_interned("ATTR_PREFETCH", sizeof("ATTR_PREFETCH") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_PREFETCH_name, &const_ATTR_PREFETCH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_PREFETCH_name); + zend_string_release_ex(const_ATTR_PREFETCH_name, true); zval const_ATTR_TIMEOUT_value; ZVAL_LONG(&const_ATTR_TIMEOUT_value, LONG_CONST(PDO_ATTR_TIMEOUT)); - zend_string *const_ATTR_TIMEOUT_name = zend_string_init_interned("ATTR_TIMEOUT", sizeof("ATTR_TIMEOUT") - 1, 1); + zend_string *const_ATTR_TIMEOUT_name = zend_string_init_interned("ATTR_TIMEOUT", sizeof("ATTR_TIMEOUT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_TIMEOUT_name, &const_ATTR_TIMEOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_TIMEOUT_name); + zend_string_release_ex(const_ATTR_TIMEOUT_name, true); zval const_ATTR_ERRMODE_value; ZVAL_LONG(&const_ATTR_ERRMODE_value, LONG_CONST(PDO_ATTR_ERRMODE)); - zend_string *const_ATTR_ERRMODE_name = zend_string_init_interned("ATTR_ERRMODE", sizeof("ATTR_ERRMODE") - 1, 1); + zend_string *const_ATTR_ERRMODE_name = zend_string_init_interned("ATTR_ERRMODE", sizeof("ATTR_ERRMODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_ERRMODE_name, &const_ATTR_ERRMODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_ERRMODE_name); + zend_string_release_ex(const_ATTR_ERRMODE_name, true); zval const_ATTR_SERVER_VERSION_value; ZVAL_LONG(&const_ATTR_SERVER_VERSION_value, LONG_CONST(PDO_ATTR_SERVER_VERSION)); - zend_string *const_ATTR_SERVER_VERSION_name = zend_string_init_interned("ATTR_SERVER_VERSION", sizeof("ATTR_SERVER_VERSION") - 1, 1); + zend_string *const_ATTR_SERVER_VERSION_name = zend_string_init_interned("ATTR_SERVER_VERSION", sizeof("ATTR_SERVER_VERSION") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SERVER_VERSION_name, &const_ATTR_SERVER_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SERVER_VERSION_name); + zend_string_release_ex(const_ATTR_SERVER_VERSION_name, true); zval const_ATTR_CLIENT_VERSION_value; ZVAL_LONG(&const_ATTR_CLIENT_VERSION_value, LONG_CONST(PDO_ATTR_CLIENT_VERSION)); - zend_string *const_ATTR_CLIENT_VERSION_name = zend_string_init_interned("ATTR_CLIENT_VERSION", sizeof("ATTR_CLIENT_VERSION") - 1, 1); + zend_string *const_ATTR_CLIENT_VERSION_name = zend_string_init_interned("ATTR_CLIENT_VERSION", sizeof("ATTR_CLIENT_VERSION") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_CLIENT_VERSION_name, &const_ATTR_CLIENT_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_CLIENT_VERSION_name); + zend_string_release_ex(const_ATTR_CLIENT_VERSION_name, true); zval const_ATTR_SERVER_INFO_value; ZVAL_LONG(&const_ATTR_SERVER_INFO_value, LONG_CONST(PDO_ATTR_SERVER_INFO)); - zend_string *const_ATTR_SERVER_INFO_name = zend_string_init_interned("ATTR_SERVER_INFO", sizeof("ATTR_SERVER_INFO") - 1, 1); + zend_string *const_ATTR_SERVER_INFO_name = zend_string_init_interned("ATTR_SERVER_INFO", sizeof("ATTR_SERVER_INFO") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SERVER_INFO_name, &const_ATTR_SERVER_INFO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SERVER_INFO_name); + zend_string_release_ex(const_ATTR_SERVER_INFO_name, true); zval const_ATTR_CONNECTION_STATUS_value; ZVAL_LONG(&const_ATTR_CONNECTION_STATUS_value, LONG_CONST(PDO_ATTR_CONNECTION_STATUS)); - zend_string *const_ATTR_CONNECTION_STATUS_name = zend_string_init_interned("ATTR_CONNECTION_STATUS", sizeof("ATTR_CONNECTION_STATUS") - 1, 1); + zend_string *const_ATTR_CONNECTION_STATUS_name = zend_string_init_interned("ATTR_CONNECTION_STATUS", sizeof("ATTR_CONNECTION_STATUS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_CONNECTION_STATUS_name, &const_ATTR_CONNECTION_STATUS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_CONNECTION_STATUS_name); + zend_string_release_ex(const_ATTR_CONNECTION_STATUS_name, true); zval const_ATTR_CASE_value; ZVAL_LONG(&const_ATTR_CASE_value, LONG_CONST(PDO_ATTR_CASE)); - zend_string *const_ATTR_CASE_name = zend_string_init_interned("ATTR_CASE", sizeof("ATTR_CASE") - 1, 1); + zend_string *const_ATTR_CASE_name = zend_string_init_interned("ATTR_CASE", sizeof("ATTR_CASE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_CASE_name, &const_ATTR_CASE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_CASE_name); + zend_string_release_ex(const_ATTR_CASE_name, true); zval const_ATTR_CURSOR_NAME_value; ZVAL_LONG(&const_ATTR_CURSOR_NAME_value, LONG_CONST(PDO_ATTR_CURSOR_NAME)); - zend_string *const_ATTR_CURSOR_NAME_name = zend_string_init_interned("ATTR_CURSOR_NAME", sizeof("ATTR_CURSOR_NAME") - 1, 1); + zend_string *const_ATTR_CURSOR_NAME_name = zend_string_init_interned("ATTR_CURSOR_NAME", sizeof("ATTR_CURSOR_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_CURSOR_NAME_name, &const_ATTR_CURSOR_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_CURSOR_NAME_name); + zend_string_release_ex(const_ATTR_CURSOR_NAME_name, true); zval const_ATTR_CURSOR_value; ZVAL_LONG(&const_ATTR_CURSOR_value, LONG_CONST(PDO_ATTR_CURSOR)); - zend_string *const_ATTR_CURSOR_name = zend_string_init_interned("ATTR_CURSOR", sizeof("ATTR_CURSOR") - 1, 1); + zend_string *const_ATTR_CURSOR_name = zend_string_init_interned("ATTR_CURSOR", sizeof("ATTR_CURSOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_CURSOR_name, &const_ATTR_CURSOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_CURSOR_name); + zend_string_release_ex(const_ATTR_CURSOR_name, true); zval const_ATTR_ORACLE_NULLS_value; ZVAL_LONG(&const_ATTR_ORACLE_NULLS_value, LONG_CONST(PDO_ATTR_ORACLE_NULLS)); - zend_string *const_ATTR_ORACLE_NULLS_name = zend_string_init_interned("ATTR_ORACLE_NULLS", sizeof("ATTR_ORACLE_NULLS") - 1, 1); + zend_string *const_ATTR_ORACLE_NULLS_name = zend_string_init_interned("ATTR_ORACLE_NULLS", sizeof("ATTR_ORACLE_NULLS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_ORACLE_NULLS_name, &const_ATTR_ORACLE_NULLS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_ORACLE_NULLS_name); + zend_string_release_ex(const_ATTR_ORACLE_NULLS_name, true); zval const_ATTR_PERSISTENT_value; ZVAL_LONG(&const_ATTR_PERSISTENT_value, LONG_CONST(PDO_ATTR_PERSISTENT)); - zend_string *const_ATTR_PERSISTENT_name = zend_string_init_interned("ATTR_PERSISTENT", sizeof("ATTR_PERSISTENT") - 1, 1); + zend_string *const_ATTR_PERSISTENT_name = zend_string_init_interned("ATTR_PERSISTENT", sizeof("ATTR_PERSISTENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_PERSISTENT_name, &const_ATTR_PERSISTENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_PERSISTENT_name); + zend_string_release_ex(const_ATTR_PERSISTENT_name, true); zval const_ATTR_STATEMENT_CLASS_value; ZVAL_LONG(&const_ATTR_STATEMENT_CLASS_value, LONG_CONST(PDO_ATTR_STATEMENT_CLASS)); - zend_string *const_ATTR_STATEMENT_CLASS_name = zend_string_init_interned("ATTR_STATEMENT_CLASS", sizeof("ATTR_STATEMENT_CLASS") - 1, 1); + zend_string *const_ATTR_STATEMENT_CLASS_name = zend_string_init_interned("ATTR_STATEMENT_CLASS", sizeof("ATTR_STATEMENT_CLASS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_STATEMENT_CLASS_name, &const_ATTR_STATEMENT_CLASS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_STATEMENT_CLASS_name); + zend_string_release_ex(const_ATTR_STATEMENT_CLASS_name, true); zval const_ATTR_FETCH_TABLE_NAMES_value; ZVAL_LONG(&const_ATTR_FETCH_TABLE_NAMES_value, LONG_CONST(PDO_ATTR_FETCH_TABLE_NAMES)); - zend_string *const_ATTR_FETCH_TABLE_NAMES_name = zend_string_init_interned("ATTR_FETCH_TABLE_NAMES", sizeof("ATTR_FETCH_TABLE_NAMES") - 1, 1); + zend_string *const_ATTR_FETCH_TABLE_NAMES_name = zend_string_init_interned("ATTR_FETCH_TABLE_NAMES", sizeof("ATTR_FETCH_TABLE_NAMES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_FETCH_TABLE_NAMES_name, &const_ATTR_FETCH_TABLE_NAMES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_FETCH_TABLE_NAMES_name); + zend_string_release_ex(const_ATTR_FETCH_TABLE_NAMES_name, true); zval const_ATTR_FETCH_CATALOG_NAMES_value; ZVAL_LONG(&const_ATTR_FETCH_CATALOG_NAMES_value, LONG_CONST(PDO_ATTR_FETCH_CATALOG_NAMES)); - zend_string *const_ATTR_FETCH_CATALOG_NAMES_name = zend_string_init_interned("ATTR_FETCH_CATALOG_NAMES", sizeof("ATTR_FETCH_CATALOG_NAMES") - 1, 1); + zend_string *const_ATTR_FETCH_CATALOG_NAMES_name = zend_string_init_interned("ATTR_FETCH_CATALOG_NAMES", sizeof("ATTR_FETCH_CATALOG_NAMES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_FETCH_CATALOG_NAMES_name, &const_ATTR_FETCH_CATALOG_NAMES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_FETCH_CATALOG_NAMES_name); + zend_string_release_ex(const_ATTR_FETCH_CATALOG_NAMES_name, true); zval const_ATTR_DRIVER_NAME_value; ZVAL_LONG(&const_ATTR_DRIVER_NAME_value, LONG_CONST(PDO_ATTR_DRIVER_NAME)); - zend_string *const_ATTR_DRIVER_NAME_name = zend_string_init_interned("ATTR_DRIVER_NAME", sizeof("ATTR_DRIVER_NAME") - 1, 1); + zend_string *const_ATTR_DRIVER_NAME_name = zend_string_init_interned("ATTR_DRIVER_NAME", sizeof("ATTR_DRIVER_NAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_DRIVER_NAME_name, &const_ATTR_DRIVER_NAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_DRIVER_NAME_name); + zend_string_release_ex(const_ATTR_DRIVER_NAME_name, true); zval const_ATTR_STRINGIFY_FETCHES_value; ZVAL_LONG(&const_ATTR_STRINGIFY_FETCHES_value, LONG_CONST(PDO_ATTR_STRINGIFY_FETCHES)); - zend_string *const_ATTR_STRINGIFY_FETCHES_name = zend_string_init_interned("ATTR_STRINGIFY_FETCHES", sizeof("ATTR_STRINGIFY_FETCHES") - 1, 1); + zend_string *const_ATTR_STRINGIFY_FETCHES_name = zend_string_init_interned("ATTR_STRINGIFY_FETCHES", sizeof("ATTR_STRINGIFY_FETCHES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_STRINGIFY_FETCHES_name, &const_ATTR_STRINGIFY_FETCHES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_STRINGIFY_FETCHES_name); + zend_string_release_ex(const_ATTR_STRINGIFY_FETCHES_name, true); zval const_ATTR_MAX_COLUMN_LEN_value; ZVAL_LONG(&const_ATTR_MAX_COLUMN_LEN_value, LONG_CONST(PDO_ATTR_MAX_COLUMN_LEN)); - zend_string *const_ATTR_MAX_COLUMN_LEN_name = zend_string_init_interned("ATTR_MAX_COLUMN_LEN", sizeof("ATTR_MAX_COLUMN_LEN") - 1, 1); + zend_string *const_ATTR_MAX_COLUMN_LEN_name = zend_string_init_interned("ATTR_MAX_COLUMN_LEN", sizeof("ATTR_MAX_COLUMN_LEN") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_MAX_COLUMN_LEN_name, &const_ATTR_MAX_COLUMN_LEN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_MAX_COLUMN_LEN_name); + zend_string_release_ex(const_ATTR_MAX_COLUMN_LEN_name, true); zval const_ATTR_EMULATE_PREPARES_value; ZVAL_LONG(&const_ATTR_EMULATE_PREPARES_value, LONG_CONST(PDO_ATTR_EMULATE_PREPARES)); - zend_string *const_ATTR_EMULATE_PREPARES_name = zend_string_init_interned("ATTR_EMULATE_PREPARES", sizeof("ATTR_EMULATE_PREPARES") - 1, 1); + zend_string *const_ATTR_EMULATE_PREPARES_name = zend_string_init_interned("ATTR_EMULATE_PREPARES", sizeof("ATTR_EMULATE_PREPARES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_EMULATE_PREPARES_name, &const_ATTR_EMULATE_PREPARES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_EMULATE_PREPARES_name); + zend_string_release_ex(const_ATTR_EMULATE_PREPARES_name, true); zval const_ATTR_DEFAULT_FETCH_MODE_value; ZVAL_LONG(&const_ATTR_DEFAULT_FETCH_MODE_value, LONG_CONST(PDO_ATTR_DEFAULT_FETCH_MODE)); - zend_string *const_ATTR_DEFAULT_FETCH_MODE_name = zend_string_init_interned("ATTR_DEFAULT_FETCH_MODE", sizeof("ATTR_DEFAULT_FETCH_MODE") - 1, 1); + zend_string *const_ATTR_DEFAULT_FETCH_MODE_name = zend_string_init_interned("ATTR_DEFAULT_FETCH_MODE", sizeof("ATTR_DEFAULT_FETCH_MODE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_DEFAULT_FETCH_MODE_name, &const_ATTR_DEFAULT_FETCH_MODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_DEFAULT_FETCH_MODE_name); + zend_string_release_ex(const_ATTR_DEFAULT_FETCH_MODE_name, true); zval const_ATTR_DEFAULT_STR_PARAM_value; ZVAL_LONG(&const_ATTR_DEFAULT_STR_PARAM_value, LONG_CONST(PDO_ATTR_DEFAULT_STR_PARAM)); - zend_string *const_ATTR_DEFAULT_STR_PARAM_name = zend_string_init_interned("ATTR_DEFAULT_STR_PARAM", sizeof("ATTR_DEFAULT_STR_PARAM") - 1, 1); + zend_string *const_ATTR_DEFAULT_STR_PARAM_name = zend_string_init_interned("ATTR_DEFAULT_STR_PARAM", sizeof("ATTR_DEFAULT_STR_PARAM") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_DEFAULT_STR_PARAM_name, &const_ATTR_DEFAULT_STR_PARAM_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_DEFAULT_STR_PARAM_name); + zend_string_release_ex(const_ATTR_DEFAULT_STR_PARAM_name, true); zval const_ERRMODE_SILENT_value; ZVAL_LONG(&const_ERRMODE_SILENT_value, LONG_CONST(PDO_ERRMODE_SILENT)); - zend_string *const_ERRMODE_SILENT_name = zend_string_init_interned("ERRMODE_SILENT", sizeof("ERRMODE_SILENT") - 1, 1); + zend_string *const_ERRMODE_SILENT_name = zend_string_init_interned("ERRMODE_SILENT", sizeof("ERRMODE_SILENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRMODE_SILENT_name, &const_ERRMODE_SILENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRMODE_SILENT_name); + zend_string_release_ex(const_ERRMODE_SILENT_name, true); zval const_ERRMODE_WARNING_value; ZVAL_LONG(&const_ERRMODE_WARNING_value, LONG_CONST(PDO_ERRMODE_WARNING)); - zend_string *const_ERRMODE_WARNING_name = zend_string_init_interned("ERRMODE_WARNING", sizeof("ERRMODE_WARNING") - 1, 1); + zend_string *const_ERRMODE_WARNING_name = zend_string_init_interned("ERRMODE_WARNING", sizeof("ERRMODE_WARNING") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRMODE_WARNING_name, &const_ERRMODE_WARNING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRMODE_WARNING_name); + zend_string_release_ex(const_ERRMODE_WARNING_name, true); zval const_ERRMODE_EXCEPTION_value; ZVAL_LONG(&const_ERRMODE_EXCEPTION_value, LONG_CONST(PDO_ERRMODE_EXCEPTION)); - zend_string *const_ERRMODE_EXCEPTION_name = zend_string_init_interned("ERRMODE_EXCEPTION", sizeof("ERRMODE_EXCEPTION") - 1, 1); + zend_string *const_ERRMODE_EXCEPTION_name = zend_string_init_interned("ERRMODE_EXCEPTION", sizeof("ERRMODE_EXCEPTION") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRMODE_EXCEPTION_name, &const_ERRMODE_EXCEPTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRMODE_EXCEPTION_name); + zend_string_release_ex(const_ERRMODE_EXCEPTION_name, true); zval const_CASE_NATURAL_value; ZVAL_LONG(&const_CASE_NATURAL_value, LONG_CONST(PDO_CASE_NATURAL)); - zend_string *const_CASE_NATURAL_name = zend_string_init_interned("CASE_NATURAL", sizeof("CASE_NATURAL") - 1, 1); + zend_string *const_CASE_NATURAL_name = zend_string_init_interned("CASE_NATURAL", sizeof("CASE_NATURAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CASE_NATURAL_name, &const_CASE_NATURAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CASE_NATURAL_name); + zend_string_release_ex(const_CASE_NATURAL_name, true); zval const_CASE_LOWER_value; ZVAL_LONG(&const_CASE_LOWER_value, LONG_CONST(PDO_CASE_LOWER)); - zend_string *const_CASE_LOWER_name = zend_string_init_interned("CASE_LOWER", sizeof("CASE_LOWER") - 1, 1); + zend_string *const_CASE_LOWER_name = zend_string_init_interned("CASE_LOWER", sizeof("CASE_LOWER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CASE_LOWER_name, &const_CASE_LOWER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CASE_LOWER_name); + zend_string_release_ex(const_CASE_LOWER_name, true); zval const_CASE_UPPER_value; ZVAL_LONG(&const_CASE_UPPER_value, LONG_CONST(PDO_CASE_UPPER)); - zend_string *const_CASE_UPPER_name = zend_string_init_interned("CASE_UPPER", sizeof("CASE_UPPER") - 1, 1); + zend_string *const_CASE_UPPER_name = zend_string_init_interned("CASE_UPPER", sizeof("CASE_UPPER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CASE_UPPER_name, &const_CASE_UPPER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CASE_UPPER_name); + zend_string_release_ex(const_CASE_UPPER_name, true); zval const_NULL_NATURAL_value; ZVAL_LONG(&const_NULL_NATURAL_value, LONG_CONST(PDO_NULL_NATURAL)); - zend_string *const_NULL_NATURAL_name = zend_string_init_interned("NULL_NATURAL", sizeof("NULL_NATURAL") - 1, 1); + zend_string *const_NULL_NATURAL_name = zend_string_init_interned("NULL_NATURAL", sizeof("NULL_NATURAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_NULL_NATURAL_name, &const_NULL_NATURAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NULL_NATURAL_name); + zend_string_release_ex(const_NULL_NATURAL_name, true); zval const_NULL_EMPTY_STRING_value; ZVAL_LONG(&const_NULL_EMPTY_STRING_value, LONG_CONST(PDO_NULL_EMPTY_STRING)); - zend_string *const_NULL_EMPTY_STRING_name = zend_string_init_interned("NULL_EMPTY_STRING", sizeof("NULL_EMPTY_STRING") - 1, 1); + zend_string *const_NULL_EMPTY_STRING_name = zend_string_init_interned("NULL_EMPTY_STRING", sizeof("NULL_EMPTY_STRING") - 1, true); zend_declare_typed_class_constant(class_entry, const_NULL_EMPTY_STRING_name, &const_NULL_EMPTY_STRING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NULL_EMPTY_STRING_name); + zend_string_release_ex(const_NULL_EMPTY_STRING_name, true); zval const_NULL_TO_STRING_value; ZVAL_LONG(&const_NULL_TO_STRING_value, LONG_CONST(PDO_NULL_TO_STRING)); - zend_string *const_NULL_TO_STRING_name = zend_string_init_interned("NULL_TO_STRING", sizeof("NULL_TO_STRING") - 1, 1); + zend_string *const_NULL_TO_STRING_name = zend_string_init_interned("NULL_TO_STRING", sizeof("NULL_TO_STRING") - 1, true); zend_declare_typed_class_constant(class_entry, const_NULL_TO_STRING_name, &const_NULL_TO_STRING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NULL_TO_STRING_name); + zend_string_release_ex(const_NULL_TO_STRING_name, true); zval const_ERR_NONE_value; zend_string *const_ERR_NONE_value_str = zend_string_init(PDO_ERR_NONE, strlen(PDO_ERR_NONE), 1); ZVAL_STR(&const_ERR_NONE_value, const_ERR_NONE_value_str); - zend_string *const_ERR_NONE_name = zend_string_init_interned("ERR_NONE", sizeof("ERR_NONE") - 1, 1); + zend_string *const_ERR_NONE_name = zend_string_init_interned("ERR_NONE", sizeof("ERR_NONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERR_NONE_name, &const_ERR_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(const_ERR_NONE_name); + zend_string_release_ex(const_ERR_NONE_name, true); zval const_FETCH_ORI_NEXT_value; ZVAL_LONG(&const_FETCH_ORI_NEXT_value, LONG_CONST(PDO_FETCH_ORI_NEXT)); - zend_string *const_FETCH_ORI_NEXT_name = zend_string_init_interned("FETCH_ORI_NEXT", sizeof("FETCH_ORI_NEXT") - 1, 1); + zend_string *const_FETCH_ORI_NEXT_name = zend_string_init_interned("FETCH_ORI_NEXT", sizeof("FETCH_ORI_NEXT") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_ORI_NEXT_name, &const_FETCH_ORI_NEXT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_ORI_NEXT_name); + zend_string_release_ex(const_FETCH_ORI_NEXT_name, true); zval const_FETCH_ORI_PRIOR_value; ZVAL_LONG(&const_FETCH_ORI_PRIOR_value, LONG_CONST(PDO_FETCH_ORI_PRIOR)); - zend_string *const_FETCH_ORI_PRIOR_name = zend_string_init_interned("FETCH_ORI_PRIOR", sizeof("FETCH_ORI_PRIOR") - 1, 1); + zend_string *const_FETCH_ORI_PRIOR_name = zend_string_init_interned("FETCH_ORI_PRIOR", sizeof("FETCH_ORI_PRIOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_ORI_PRIOR_name, &const_FETCH_ORI_PRIOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_ORI_PRIOR_name); + zend_string_release_ex(const_FETCH_ORI_PRIOR_name, true); zval const_FETCH_ORI_FIRST_value; ZVAL_LONG(&const_FETCH_ORI_FIRST_value, LONG_CONST(PDO_FETCH_ORI_FIRST)); - zend_string *const_FETCH_ORI_FIRST_name = zend_string_init_interned("FETCH_ORI_FIRST", sizeof("FETCH_ORI_FIRST") - 1, 1); + zend_string *const_FETCH_ORI_FIRST_name = zend_string_init_interned("FETCH_ORI_FIRST", sizeof("FETCH_ORI_FIRST") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_ORI_FIRST_name, &const_FETCH_ORI_FIRST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_ORI_FIRST_name); + zend_string_release_ex(const_FETCH_ORI_FIRST_name, true); zval const_FETCH_ORI_LAST_value; ZVAL_LONG(&const_FETCH_ORI_LAST_value, LONG_CONST(PDO_FETCH_ORI_LAST)); - zend_string *const_FETCH_ORI_LAST_name = zend_string_init_interned("FETCH_ORI_LAST", sizeof("FETCH_ORI_LAST") - 1, 1); + zend_string *const_FETCH_ORI_LAST_name = zend_string_init_interned("FETCH_ORI_LAST", sizeof("FETCH_ORI_LAST") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_ORI_LAST_name, &const_FETCH_ORI_LAST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_ORI_LAST_name); + zend_string_release_ex(const_FETCH_ORI_LAST_name, true); zval const_FETCH_ORI_ABS_value; ZVAL_LONG(&const_FETCH_ORI_ABS_value, LONG_CONST(PDO_FETCH_ORI_ABS)); - zend_string *const_FETCH_ORI_ABS_name = zend_string_init_interned("FETCH_ORI_ABS", sizeof("FETCH_ORI_ABS") - 1, 1); + zend_string *const_FETCH_ORI_ABS_name = zend_string_init_interned("FETCH_ORI_ABS", sizeof("FETCH_ORI_ABS") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_ORI_ABS_name, &const_FETCH_ORI_ABS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_ORI_ABS_name); + zend_string_release_ex(const_FETCH_ORI_ABS_name, true); zval const_FETCH_ORI_REL_value; ZVAL_LONG(&const_FETCH_ORI_REL_value, LONG_CONST(PDO_FETCH_ORI_REL)); - zend_string *const_FETCH_ORI_REL_name = zend_string_init_interned("FETCH_ORI_REL", sizeof("FETCH_ORI_REL") - 1, 1); + zend_string *const_FETCH_ORI_REL_name = zend_string_init_interned("FETCH_ORI_REL", sizeof("FETCH_ORI_REL") - 1, true); zend_declare_typed_class_constant(class_entry, const_FETCH_ORI_REL_name, &const_FETCH_ORI_REL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FETCH_ORI_REL_name); + zend_string_release_ex(const_FETCH_ORI_REL_name, true); zval const_CURSOR_FWDONLY_value; ZVAL_LONG(&const_CURSOR_FWDONLY_value, LONG_CONST(PDO_CURSOR_FWDONLY)); - zend_string *const_CURSOR_FWDONLY_name = zend_string_init_interned("CURSOR_FWDONLY", sizeof("CURSOR_FWDONLY") - 1, 1); + zend_string *const_CURSOR_FWDONLY_name = zend_string_init_interned("CURSOR_FWDONLY", sizeof("CURSOR_FWDONLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURSOR_FWDONLY_name, &const_CURSOR_FWDONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURSOR_FWDONLY_name); + zend_string_release_ex(const_CURSOR_FWDONLY_name, true); zval const_CURSOR_SCROLL_value; ZVAL_LONG(&const_CURSOR_SCROLL_value, LONG_CONST(PDO_CURSOR_SCROLL)); - zend_string *const_CURSOR_SCROLL_name = zend_string_init_interned("CURSOR_SCROLL", sizeof("CURSOR_SCROLL") - 1, 1); + zend_string *const_CURSOR_SCROLL_name = zend_string_init_interned("CURSOR_SCROLL", sizeof("CURSOR_SCROLL") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURSOR_SCROLL_name, &const_CURSOR_SCROLL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURSOR_SCROLL_name); + zend_string_release_ex(const_CURSOR_SCROLL_name, true); zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "__construct", sizeof("__construct") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); diff --git a/ext/pdo/pdo_sql_parser.h b/ext/pdo/pdo_sql_parser.h index 0701d984ae64..9baca65e5f90 100644 --- a/ext/pdo/pdo_sql_parser.h +++ b/ext/pdo/pdo_sql_parser.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | +----------------------------------------------------------------------+ diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index a87fd473404e..d77425531cc4 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | +----------------------------------------------------------------------+ @@ -117,7 +115,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string if (t == PDO_PARSER_BIND) { ptrdiff_t len = s.cur - s.tok; - if ((ZSTR_VAL(inquery) < (s.cur - len)) && isalnum(*(s.cur - len - 1))) { + if ((ZSTR_VAL(inquery) < (s.cur - len)) && isalnum((unsigned char)s.cur[-len - 1])) { continue; } query_type |= PDO_PLACEHOLDER_NAMED; @@ -300,6 +298,12 @@ safe: } plc->quoted = stmt->dbh->methods->quoter(stmt->dbh, buf, param_type); + if (plc->quoted == NULL) { + /* bork */ + ret = -1; + strncpy(stmt->error_code, stmt->dbh->error_code, 6); + goto clean_up; + } } } diff --git a/ext/pdo/pdo_sqlstate.c b/ext/pdo/pdo_sqlstate.c index a44b95a9181d..089c1bdd027f 100644 --- a/ext/pdo/pdo_sqlstate.c +++ b/ext/pdo/pdo_sqlstate.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 697940d94260..2b4e5a8f8239 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | @@ -55,17 +53,17 @@ static inline bool rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_p if (stmt->named_rewrite_template) { /* this is not an error here */ - return 1; + return true; } if (!param->name) { /* do the reverse; map the parameter number to the name */ if ((name = zend_hash_index_find_ptr(stmt->bound_param_map, param->paramno)) != NULL) { param->name = zend_string_copy(name); - return 1; + return true; } /* TODO Error? */ pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined"); - return 0; + return false; } ZEND_HASH_FOREACH_PTR(stmt->bound_param_map, name) { @@ -79,29 +77,29 @@ static inline bool rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_p return -1; } param->paramno = position; - return 1; + return true; } ZEND_HASH_FOREACH_END(); /* TODO Error? */ pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined"); - return 0; + return false; } - return 1; + return true; } /* }}} */ /* trigger callback hook for parameters */ static bool dispatch_param_event(pdo_stmt_t *stmt, enum pdo_param_event event_type) /* {{{ */ { - bool ret = 1, is_param = 1; + bool ret = true, is_param = true; struct pdo_bound_param_data *param; HashTable *ht; if (stmt->dbh->skip_param_evt & (1 << event_type)) { - return 1; + return true; } if (!stmt->methods->param_hook) { - return 1; + return true; } ht = stmt->bound_params; @@ -110,14 +108,14 @@ static bool dispatch_param_event(pdo_stmt_t *stmt, enum pdo_param_event event_ty if (ht) { ZEND_HASH_FOREACH_PTR(ht, param) { if (!stmt->methods->param_hook(stmt, param, event_type)) { - ret = 0; + ret = false; break; } } ZEND_HASH_FOREACH_END(); } if (ret && is_param) { ht = stmt->bound_columns; - is_param = 0; + is_param = false; goto iterate; } @@ -148,7 +146,7 @@ bool pdo_stmt_describe_columns(pdo_stmt_t *stmt) /* {{{ */ stmt->columns[col].name = zend_string_toupper(orig_name); zend_string_release(orig_name); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -272,7 +270,7 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_ if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && !Z_ISNULL_P(parameter)) { if (!try_convert_to_string(parameter)) { - return 0; + return false; } } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE)) { convert_to_long(parameter); @@ -326,7 +324,7 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_ zend_string_release_ex(param->name, 0); param->name = NULL; } - return 0; + return false; } /* ask the driver to perform any normalization it needs on the @@ -340,7 +338,7 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_ zend_string_release_ex(param->name, 0); param->name = NULL; } - return 0; + return false; } } @@ -371,10 +369,10 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_ } /* param->parameter is freed by hash dtor */ ZVAL_UNDEF(¶m->parameter); - return 0; + return false; } } - return 1; + return true; } /* }}} */ @@ -563,24 +561,24 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, enum pdo static bool do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, zend_long offset) /* {{{ */ { if (!stmt->executed) { - return 0; + return false; } if (!dispatch_param_event(stmt, PDO_PARAM_EVT_FETCH_PRE)) { - return 0; + return false; } if (!stmt->methods->fetcher(stmt, ori, offset)) { - return 0; + return false; } /* some drivers might need to describe the columns now */ if (!stmt->columns && !pdo_stmt_describe_columns(stmt)) { - return 0; + return false; } if (!dispatch_param_event(stmt, PDO_PARAM_EVT_FETCH_POST)) { - return 0; + return false; } if (stmt->bound_columns) { @@ -607,7 +605,7 @@ static bool do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, ze } ZEND_HASH_FOREACH_END(); } - return 1; + return true; } /* }}} */ @@ -771,9 +769,10 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch class specified"); goto in_fetch_error; } - ctor_arguments = stmt->fetch.cls.ctor_args; } ZEND_ASSERT(ce != NULL); + + ctor_arguments = stmt->fetch.cls.ctor_args; if (flags & PDO_FETCH_SERIALIZE) { if (!ce->unserialize) { /* As this option is deprecated we do not bother to mention the class name. */ @@ -822,7 +821,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h * However, if we fetch a group key we will have over allocated. */ fetch_function_params = safe_emalloc(sizeof(zval), stmt->column_count, 0); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } if (group_key) { @@ -917,7 +916,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h case PDO_FETCH_FUNC: ZVAL_COPY_VALUE(&fetch_function_params[fetch_function_param_num++], &val); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -1052,7 +1051,7 @@ PHP_METHOD(PDOStatement, fetch) array_init_size(return_value, 1); bool success = pdo_do_key_pair_fetch(stmt, ori, off, Z_ARRVAL_P(return_value)); if (!success) { - zval_dtor(return_value); + zval_ptr_dtor_nogc(return_value); PDO_HANDLE_STMT_ERR(); RETURN_FALSE; } @@ -1506,9 +1505,9 @@ static bool generic_stmt_attr_get(pdo_stmt_t *stmt, zval *return_value, zend_lon switch (attr) { case PDO_ATTR_EMULATE_PREPARES: RETVAL_BOOL(stmt->supports_placeholders == PDO_PLACEHOLDER_NONE); - return 1; + return true; } - return 0; + return false; } PHP_METHOD(PDOStatement, getAttribute) @@ -1788,12 +1787,12 @@ static bool pdo_stmt_do_next_rowset(pdo_stmt_t *stmt) if (!stmt->methods->next_rowset(stmt)) { /* Set the executed flag to 0 to reallocate columns on next execute */ stmt->executed = 0; - return 0; + return false; } pdo_stmt_describe_columns(stmt); - return 1; + return true; } PHP_METHOD(PDOStatement, nextRowset) @@ -1915,9 +1914,7 @@ PHP_METHOD(PDOStatement, debugDumpParams) PHP_METHOD(PDOStatement, getIterator) { - if (zend_parse_parameters_none() == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_NONE(); zend_create_internal_iterator_zval(return_value, ZEND_THIS); } @@ -2423,7 +2420,7 @@ void pdo_stmt_init(void) pdo_dbstmt_ce->default_object_handlers = &pdo_dbstmt_object_handlers; memcpy(&pdo_dbstmt_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pdo_dbstmt_object_handlers.offset = XtOffsetOf(pdo_stmt_t, std); + pdo_dbstmt_object_handlers.offset = offsetof(pdo_stmt_t, std); pdo_dbstmt_object_handlers.free_obj = pdo_dbstmt_free_storage; pdo_dbstmt_object_handlers.write_property = dbstmt_prop_write; pdo_dbstmt_object_handlers.unset_property = dbstmt_prop_delete; @@ -2437,7 +2434,7 @@ void pdo_stmt_init(void) pdo_row_ce->default_object_handlers = &pdo_row_object_handlers; memcpy(&pdo_row_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pdo_row_object_handlers.offset = XtOffsetOf(pdo_row_t, std); + pdo_row_object_handlers.offset = offsetof(pdo_row_t, std); pdo_row_object_handlers.free_obj = pdo_row_free_storage; pdo_row_object_handlers.clone_obj = NULL; pdo_row_object_handlers.get_property_ptr_ptr = pdo_row_get_property_ptr_ptr; diff --git a/ext/pdo/pdo_stmt_arginfo.h b/ext/pdo/pdo_stmt_arginfo.h index 0d4131d5be49..080202f897bc 100644 --- a/ext/pdo/pdo_stmt_arginfo.h +++ b/ext/pdo/pdo_stmt_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pdo_stmt.stub.php instead. * Stub hash: 6a5b332ba4bfeceaca6aad734d38dabb66d82c97 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PDOStatement_bindColumn, 0, 2, _IS_BOOL, 0) @@ -142,9 +142,9 @@ static zend_class_entry *register_class_PDOStatement(zend_class_entry *class_ent zval property_queryString_default_value; ZVAL_UNDEF(&property_queryString_default_value); - zend_string *property_queryString_name = zend_string_init("queryString", sizeof("queryString") - 1, 1); + zend_string *property_queryString_name = zend_string_init("queryString", sizeof("queryString") - 1, true); zend_declare_typed_property(class_entry, property_queryString_name, &property_queryString_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_queryString_name); + zend_string_release_ex(property_queryString_name, true); return class_entry; } @@ -158,9 +158,9 @@ static zend_class_entry *register_class_PDORow(void) zval property_queryString_default_value; ZVAL_UNDEF(&property_queryString_default_value); - zend_string *property_queryString_name = zend_string_init("queryString", sizeof("queryString") - 1, 1); + zend_string *property_queryString_name = zend_string_init("queryString", sizeof("queryString") - 1, true); zend_declare_typed_property(class_entry, property_queryString_name, &property_queryString_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_queryString_name); + zend_string_release_ex(property_queryString_name, true); return class_entry; } diff --git a/ext/pdo/php_pdo.h b/ext/pdo/php_pdo.h index 1618c78d6228..39443bb35c89 100644 --- a/ext/pdo/php_pdo.h +++ b/ext/pdo/php_pdo.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -18,6 +16,9 @@ #define PHP_PDO_H #include "zend.h" +#include "Zend/zend_compile.h" +#include "Zend/zend_API.h" +#include "Zend/zend_attributes.h" PHPAPI extern zend_module_entry pdo_module_entry; #define phpext_pdo_ptr &pdo_module_entry @@ -50,8 +51,47 @@ PHP_MINIT_FUNCTION(pdo); PHP_MSHUTDOWN_FUNCTION(pdo); PHP_MINFO_FUNCTION(pdo); -#define REGISTER_PDO_CLASS_CONST_LONG(const_name, value) \ - zend_declare_class_constant_long(php_pdo_get_dbh_ce(), const_name, sizeof(const_name)-1, (zend_long)value); +static inline void pdo_declare_deprecated_class_constant_long( + zend_class_entry *ce, const char *name, zend_long value, + zend_string *since, const char *message) { + + zval zvalue; + ZVAL_LONG(&zvalue, value); + + zend_string *name_str = zend_string_init_interned(name, strlen(name), true); + + zend_class_constant *constant = zend_declare_class_constant_ex( + ce, name_str, &zvalue, + ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL); + + zend_attribute *attr = zend_add_class_constant_attribute(ce, constant, + ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), + 1 + (message != NULL)); + + attr->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR(&attr->args[0].value, since); + + if (message) { + zend_string *message_str = zend_string_init_interned(message, strlen(message), true); + + attr->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + ZVAL_STR(&attr->args[1].value, message_str); + } +} + +/* Declare a constant deprecated in 8.5 */ +#define REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_85(const_name, value) \ + pdo_declare_deprecated_class_constant_long(php_pdo_get_dbh_ce(), \ + const_name, (zend_long)value, \ + ZSTR_KNOWN(ZEND_STR_8_DOT_5), NULL) + +/* Declare one of the constants deprecated in https://wiki.php.net/rfc/deprecations_php_8_5 + * "Deprecate driver specific PDO constants and methods" */ +#define REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(name, old_prefix, new_prefix, value) \ + pdo_declare_deprecated_class_constant_long(php_pdo_get_dbh_ce(), \ + old_prefix name, (zend_long)value, \ + ZSTR_KNOWN(ZEND_STR_8_DOT_5), \ + "use " new_prefix name " instead") #define LONG_CONST(c) (zend_long) c diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 9c5986ff8bce..74449d565901 100644 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -520,11 +518,11 @@ struct _pdo_dbh_object_t { }; static inline pdo_dbh_t *php_pdo_dbh_fetch_inner(zend_object *obj) { - return (pdo_dbh_t *)(((pdo_dbh_object_t *)((char*)(obj) - XtOffsetOf(pdo_dbh_object_t, std)))->inner); + return (pdo_dbh_t *)((ZEND_CONTAINER_OF(obj, pdo_dbh_object_t, std))->inner); } static inline pdo_dbh_object_t *php_pdo_dbh_fetch_object(zend_object *obj) { - return (pdo_dbh_object_t *)((char*)(obj) - XtOffsetOf(pdo_dbh_object_t, std)); + return ZEND_CONTAINER_OF(obj, pdo_dbh_object_t, std); } #define Z_PDO_DBH_P(zv) php_pdo_dbh_fetch_inner(Z_OBJ_P((zv))) @@ -642,7 +640,7 @@ struct _pdo_stmt_t { static inline pdo_stmt_t *php_pdo_stmt_fetch_object(zend_object *obj) { - return (pdo_stmt_t *)((char*)(obj) - XtOffsetOf(pdo_stmt_t, std)); + return ZEND_CONTAINER_OF(obj, pdo_stmt_t, std); } #define Z_PDO_STMT_P(zv) php_pdo_stmt_fetch_object(Z_OBJ_P((zv))) @@ -653,7 +651,7 @@ struct _pdo_row_t { }; static inline pdo_row_t *php_pdo_row_fetch_object(zend_object *obj) { - return (pdo_row_t *)((char*)(obj) - XtOffsetOf(pdo_row_t, std)); + return ZEND_CONTAINER_OF(obj, pdo_row_t, std); } struct _pdo_scanner_t { diff --git a/ext/pdo/php_pdo_error.h b/ext/pdo/php_pdo_error.h index 50c751a0f490..79d1c482d609 100644 --- a/ext/pdo/php_pdo_error.h +++ b/ext/pdo/php_pdo_error.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h index e8befe9f819a..dde79af73aa0 100644 --- a/ext/pdo/php_pdo_int.h +++ b/ext/pdo/php_pdo_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Marcus Boerger | diff --git a/ext/pdo/tests/gh20553.phpt b/ext/pdo/tests/gh20553.phpt new file mode 100644 index 000000000000..fe0b84c27ebb --- /dev/null +++ b/ext/pdo/tests/gh20553.phpt @@ -0,0 +1,97 @@ +--TEST-- +GH-20553: PHP 8.5.0 regression: PDO::FETCH_CLASSTYPE ignores $constructorArgs +--EXTENSIONS-- +pdo +--SKIPIF-- + +--FILE-- + PDO::FETCH_CLASS, + 'PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE' + => PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, + 'PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE' + => PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE, + 'PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_PROPS_LATE' + => PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_PROPS_LATE, +]; + +foreach ($fetchModes as $combinedModes => $fetchMode) { + echo '## ' . $combinedModes . PHP_EOL; + $db->query($sql)->fetchAll( + $fetchMode, + 'dumpy', + ['constructor argument #1'] + ); + echo PHP_EOL; +} +?> +--EXPECT-- +## PDO::FETCH_CLASS +'pdo_fetch_class_type_class' = 'dummy' +'foo' = 'bar' +'abc' = 'dfg' +constructor called, + my class is 'dumpy' + input parameters: array ( + 0 => 'constructor argument #1', +) + +## PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE +constructor called, + my class is 'dumpy' + input parameters: array ( + 0 => 'constructor argument #1', +) +'pdo_fetch_class_type_class' = 'dummy' +'foo' = 'bar' +'abc' = 'dfg' + +## PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE +'foo' = 'bar' +'abc' = 'dfg' +constructor called, + my class is 'dummy' + input parameters: array ( + 0 => 'constructor argument #1', +) + +## PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_PROPS_LATE +constructor called, + my class is 'dummy' + input parameters: array ( + 0 => 'constructor argument #1', +) +'foo' = 'bar' +'abc' = 'dfg' diff --git a/ext/pdo/tests/pdo_016.phpt b/ext/pdo/tests/pdo_016.phpt index 5b99930f2495..2a5fa8d85f51 100644 --- a/ext/pdo/tests/pdo_016.phpt +++ b/ext/pdo/tests/pdo_016.phpt @@ -17,7 +17,7 @@ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $db = PDOTest::factory(); if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); } $db->exec('CREATE TABLE test016(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))'); diff --git a/ext/pdo/tests/pdo_016a.phpt b/ext/pdo/tests/pdo_016a.phpt index d7dcb2c65430..2c0590594a84 100644 --- a/ext/pdo/tests/pdo_016a.phpt +++ b/ext/pdo/tests/pdo_016a.phpt @@ -17,7 +17,7 @@ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $db = PDOTest::factory(); if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); } $db->exec('CREATE TABLE test016a(idx int NOT NULL PRIMARY KEY, txt VARCHAR(20))'); diff --git a/ext/pdo/tests/pdo_021.phpt b/ext/pdo/tests/pdo_021.phpt index 494ad3c39c50..7ca3b075881f 100644 --- a/ext/pdo/tests/pdo_021.phpt +++ b/ext/pdo/tests/pdo_021.phpt @@ -16,7 +16,7 @@ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $db = PDOTest::factory(); if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); } $db->exec('CREATE TABLE test021(id INT NOT NULL PRIMARY KEY, val VARCHAR(10), val2 VARCHAR(16))'); diff --git a/ext/pdo/tests/pdo_fetch_class_change_ctor_args_during_fetch2.phpt b/ext/pdo/tests/pdo_fetch_class_change_ctor_args_during_fetch2.phpt index 23b91210d9da..819b452ad808 100644 --- a/ext/pdo/tests/pdo_fetch_class_change_ctor_args_during_fetch2.phpt +++ b/ext/pdo/tests/pdo_fetch_class_change_ctor_args_during_fetch2.phpt @@ -27,7 +27,6 @@ class Test { } } -// TODO Rename pdo_fetch_class_change_ctor_two table to pdo_fetch_class_change_ctor_two in PHP-8.4 $db->exec('CREATE TABLE pdo_fetch_class_change_ctor_two(id int NOT NULL PRIMARY KEY, val1 VARCHAR(10), val2 VARCHAR(10))'); $db->exec("INSERT INTO pdo_fetch_class_change_ctor_two VALUES(1, 'A', 'alpha')"); $db->exec("INSERT INTO pdo_fetch_class_change_ctor_two VALUES(2, 'B', 'beta')"); diff --git a/ext/pdo_dblib/config.w32 b/ext/pdo_dblib/config.w32 index 4b1c76130f52..07e98d16a4af 100644 --- a/ext/pdo_dblib/config.w32 +++ b/ext/pdo_dblib/config.w32 @@ -7,7 +7,7 @@ if (PHP_PDO_DBLIB != "no") { * otherwise we'll poke around and look for MSSQL libs */ if (CHECK_LIB("sybdb.lib", "pdo_dblib", PHP_PDO_DBLIB) && - CHECK_HEADER_ADD_INCLUDE("sybfront.h", "CFLAGS_PDO_DBLIB", + CHECK_HEADER("sybfront.h", "CFLAGS_PDO_DBLIB", PHP_PDO_DBLIB, null, null, true)) { EXTENSION("pdo_dblib", "pdo_dblib.c dblib_driver.c dblib_stmt.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); @@ -24,7 +24,7 @@ if (PHP_PDO_MSSQL != "no") { PDO_DBLIB_FLAVOUR = 0; if (CHECK_LIB("sybdb.lib", "pdo_mssql", PHP_PDO_MSSQL) && - CHECK_HEADER_ADD_INCLUDE("sybfront.h", "CFLAGS_PDO_MSSQL", + CHECK_HEADER("sybfront.h", "CFLAGS_PDO_MSSQL", PHP_PDO_MSSQL, null, null, true)) { /* smells like FreeTDS (or maybe native sybase dblib) */ PDO_DBLIB_FLAVOUR = "freetds"; diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index 132e5c2e4dee..9f590c9071b6 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | @@ -145,20 +143,20 @@ static zend_long dblib_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) static zend_string* dblib_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; - bool use_national_character_set = 0; + bool use_national_character_set = false; size_t i; char *q; size_t quotedlen = 0, extralen = 0; zend_string *quoted_str; if (H->assume_national_character_set_strings) { - use_national_character_set = 1; + use_national_character_set = true; } if ((paramtype & PDO_PARAM_STR_NATL) == PDO_PARAM_STR_NATL) { - use_national_character_set = 1; + use_national_character_set = true; } if ((paramtype & PDO_PARAM_STR_CHAR) == PDO_PARAM_STR_CHAR) { - use_national_character_set = 0; + use_national_character_set = false; } /* Detect quoted length, adding extra char for doubled single quotes */ @@ -422,6 +420,17 @@ static int dblib_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_valu return 1; } +static zend_result dblib_handle_check_liveness(pdo_dbh_t *dbh) +{ + pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; + + if (dbdead(H->link)) { + return FAILURE; + } + + return SUCCESS; +} + static const struct pdo_dbh_methods dblib_methods = { dblib_handle_closer, dblib_handle_preparer, @@ -434,7 +443,7 @@ static const struct pdo_dbh_methods dblib_methods = { dblib_handle_last_id, /* last insert id */ dblib_fetch_error, /* fetch error */ dblib_get_attribute, /* get attr */ - NULL, /* check liveness */ + dblib_handle_check_liveness, /* check_liveness */ NULL, /* get driver methods */ NULL, /* request shutdown */ NULL, /* in transaction, use PDO's internal tracking mechanism */ diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index e6e91b60fa27..0b97b1dfb076 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c index b16208fbd8e7..47cf1497ef7d 100644 --- a/ext/pdo_dblib/pdo_dblib.c +++ b/ext/pdo_dblib/pdo_dblib.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | @@ -190,15 +188,18 @@ PHP_RSHUTDOWN_FUNCTION(pdo_dblib) return SUCCESS; } +#define REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, value) \ + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, "DBLIB_", "Pdo\\Dblib::", value) + PHP_MINIT_FUNCTION(pdo_dblib) { - REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_CONNECTION_TIMEOUT", (long) PDO_DBLIB_ATTR_CONNECTION_TIMEOUT); - REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT); - REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER", (long) PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER); - REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_VERSION", (long) PDO_DBLIB_ATTR_VERSION); - REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_TDS_VERSION", (long) PDO_DBLIB_ATTR_TDS_VERSION); - REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_SKIP_EMPTY_ROWSETS", (long) PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS); - REGISTER_PDO_CLASS_CONST_LONG("DBLIB_ATTR_DATETIME_CONVERT", (long) PDO_DBLIB_ATTR_DATETIME_CONVERT); + REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_CONNECTION_TIMEOUT", (long) PDO_DBLIB_ATTR_CONNECTION_TIMEOUT); + REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_QUERY_TIMEOUT", (long) PDO_DBLIB_ATTR_QUERY_TIMEOUT); + REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_STRINGIFY_UNIQUEIDENTIFIER", (long) PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER); + REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_VERSION", (long) PDO_DBLIB_ATTR_VERSION); + REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_TDS_VERSION", (long) PDO_DBLIB_ATTR_TDS_VERSION); + REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SKIP_EMPTY_ROWSETS", (long) PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS); + REGISTER_PDO_DBLIB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_DATETIME_CONVERT", (long) PDO_DBLIB_ATTR_DATETIME_CONVERT); if (FAIL == dbinit()) { return FAILURE; diff --git a/ext/pdo_dblib/pdo_dblib_arginfo.h b/ext/pdo_dblib/pdo_dblib_arginfo.h index 1cf6c60d7a3b..330bcde667f2 100644 --- a/ext/pdo_dblib/pdo_dblib_arginfo.h +++ b/ext/pdo_dblib/pdo_dblib_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pdo_dblib.stub.php instead. * Stub hash: 95f297028aee0675523d6984c03a518e4fc431df */ static zend_class_entry *register_class_Pdo_Dblib(zend_class_entry *class_entry_PDO) @@ -10,45 +10,45 @@ static zend_class_entry *register_class_Pdo_Dblib(zend_class_entry *class_entry_ zval const_ATTR_CONNECTION_TIMEOUT_value; ZVAL_LONG(&const_ATTR_CONNECTION_TIMEOUT_value, PDO_DBLIB_ATTR_CONNECTION_TIMEOUT); - zend_string *const_ATTR_CONNECTION_TIMEOUT_name = zend_string_init_interned("ATTR_CONNECTION_TIMEOUT", sizeof("ATTR_CONNECTION_TIMEOUT") - 1, 1); + zend_string *const_ATTR_CONNECTION_TIMEOUT_name = zend_string_init_interned("ATTR_CONNECTION_TIMEOUT", sizeof("ATTR_CONNECTION_TIMEOUT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_CONNECTION_TIMEOUT_name, &const_ATTR_CONNECTION_TIMEOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_CONNECTION_TIMEOUT_name); + zend_string_release_ex(const_ATTR_CONNECTION_TIMEOUT_name, true); zval const_ATTR_QUERY_TIMEOUT_value; ZVAL_LONG(&const_ATTR_QUERY_TIMEOUT_value, PDO_DBLIB_ATTR_QUERY_TIMEOUT); - zend_string *const_ATTR_QUERY_TIMEOUT_name = zend_string_init_interned("ATTR_QUERY_TIMEOUT", sizeof("ATTR_QUERY_TIMEOUT") - 1, 1); + zend_string *const_ATTR_QUERY_TIMEOUT_name = zend_string_init_interned("ATTR_QUERY_TIMEOUT", sizeof("ATTR_QUERY_TIMEOUT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_QUERY_TIMEOUT_name, &const_ATTR_QUERY_TIMEOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_QUERY_TIMEOUT_name); + zend_string_release_ex(const_ATTR_QUERY_TIMEOUT_name, true); zval const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_value; ZVAL_LONG(&const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_value, PDO_DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER); - zend_string *const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name = zend_string_init_interned("ATTR_STRINGIFY_UNIQUEIDENTIFIER", sizeof("ATTR_STRINGIFY_UNIQUEIDENTIFIER") - 1, 1); + zend_string *const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name = zend_string_init_interned("ATTR_STRINGIFY_UNIQUEIDENTIFIER", sizeof("ATTR_STRINGIFY_UNIQUEIDENTIFIER") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name, &const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name); + zend_string_release_ex(const_ATTR_STRINGIFY_UNIQUEIDENTIFIER_name, true); zval const_ATTR_VERSION_value; ZVAL_LONG(&const_ATTR_VERSION_value, PDO_DBLIB_ATTR_VERSION); - zend_string *const_ATTR_VERSION_name = zend_string_init_interned("ATTR_VERSION", sizeof("ATTR_VERSION") - 1, 1); + zend_string *const_ATTR_VERSION_name = zend_string_init_interned("ATTR_VERSION", sizeof("ATTR_VERSION") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_VERSION_name, &const_ATTR_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_VERSION_name); + zend_string_release_ex(const_ATTR_VERSION_name, true); zval const_ATTR_TDS_VERSION_value; ZVAL_LONG(&const_ATTR_TDS_VERSION_value, PDO_DBLIB_ATTR_TDS_VERSION); - zend_string *const_ATTR_TDS_VERSION_name = zend_string_init_interned("ATTR_TDS_VERSION", sizeof("ATTR_TDS_VERSION") - 1, 1); + zend_string *const_ATTR_TDS_VERSION_name = zend_string_init_interned("ATTR_TDS_VERSION", sizeof("ATTR_TDS_VERSION") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_TDS_VERSION_name, &const_ATTR_TDS_VERSION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_TDS_VERSION_name); + zend_string_release_ex(const_ATTR_TDS_VERSION_name, true); zval const_ATTR_SKIP_EMPTY_ROWSETS_value; ZVAL_LONG(&const_ATTR_SKIP_EMPTY_ROWSETS_value, PDO_DBLIB_ATTR_SKIP_EMPTY_ROWSETS); - zend_string *const_ATTR_SKIP_EMPTY_ROWSETS_name = zend_string_init_interned("ATTR_SKIP_EMPTY_ROWSETS", sizeof("ATTR_SKIP_EMPTY_ROWSETS") - 1, 1); + zend_string *const_ATTR_SKIP_EMPTY_ROWSETS_name = zend_string_init_interned("ATTR_SKIP_EMPTY_ROWSETS", sizeof("ATTR_SKIP_EMPTY_ROWSETS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SKIP_EMPTY_ROWSETS_name, &const_ATTR_SKIP_EMPTY_ROWSETS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SKIP_EMPTY_ROWSETS_name); + zend_string_release_ex(const_ATTR_SKIP_EMPTY_ROWSETS_name, true); zval const_ATTR_DATETIME_CONVERT_value; ZVAL_LONG(&const_ATTR_DATETIME_CONVERT_value, PDO_DBLIB_ATTR_DATETIME_CONVERT); - zend_string *const_ATTR_DATETIME_CONVERT_name = zend_string_init_interned("ATTR_DATETIME_CONVERT", sizeof("ATTR_DATETIME_CONVERT") - 1, 1); + zend_string *const_ATTR_DATETIME_CONVERT_name = zend_string_init_interned("ATTR_DATETIME_CONVERT", sizeof("ATTR_DATETIME_CONVERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_DATETIME_CONVERT_name, &const_ATTR_DATETIME_CONVERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_DATETIME_CONVERT_name); + zend_string_release_ex(const_ATTR_DATETIME_CONVERT_name, true); return class_entry; } diff --git a/ext/pdo_dblib/php_pdo_dblib.h b/ext/pdo_dblib/php_pdo_dblib.h index 7cd13d6eb4bb..60e3d8c082a6 100644 --- a/ext/pdo_dblib/php_pdo_dblib.h +++ b/ext/pdo_dblib/php_pdo_dblib.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h index 2067d944c718..21ffa9c86243 100644 --- a/ext/pdo_dblib/php_pdo_dblib_int.h +++ b/ext/pdo_dblib/php_pdo_dblib_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | | Frank M. Kromann | diff --git a/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt b/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt index 431c61951ee2..95b33ddb7f3c 100644 --- a/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt +++ b/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt @@ -4,6 +4,7 @@ GHSA-5hqh-c84r-qjcv (Integer overflow in the dblib quoter causing OOB writes) pdo_dblib --SKIPIF-- getAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS)); +var_dump($db->getAttribute(Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS)); $stmt = $db->query($sql); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -27,15 +27,15 @@ var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); $stmt->closeCursor(); -$db->setAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS, true); -var_dump($db->getAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS)); +$db->setAttribute(Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS, true); +var_dump($db->getAttribute(Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS)); $stmt = $db->query($sql); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); var_dump($stmt->nextRowset()); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); $stmt->closeCursor(); -var_dump($db->getAttribute(PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS)); +var_dump($db->getAttribute(Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS)); ?> --EXPECT-- diff --git a/ext/pdo_dblib/tests/bug_73396.phpt b/ext/pdo_dblib/tests/bug_73396.phpt index b2f96f8ec1c9..93dc66778a16 100644 --- a/ext/pdo_dblib/tests/bug_73396.phpt +++ b/ext/pdo_dblib/tests/bug_73396.phpt @@ -6,7 +6,7 @@ pdo_dblib getAttribute(PDO::DBLIB_ATTR_TDS_VERSION), ['4.2', '4.6', '5.0', '6.0', '7.0'])) die('skip bigint type is unsupported by active TDS version'); +if (in_array($db->getAttribute(Pdo\Dblib::ATTR_TDS_VERSION), ['4.2', '4.6', '5.0', '6.0', '7.0'])) die('skip bigint type is unsupported by active TDS version'); ?> --FILE-- =1.1 function driver_supports_batch_statements_without_select($db) { - $version = $db->getAttribute(PDO::DBLIB_ATTR_VERSION); + $version = $db->getAttribute(Pdo\Dblib::ATTR_VERSION); return !strstartswith($version, 'freetds ') || !strstartswith($version, 'freetds v1.0'); } diff --git a/ext/pdo_dblib/tests/datetime2.phpt b/ext/pdo_dblib/tests/datetime2.phpt index e4f65048dd89..2b54361a30e5 100644 --- a/ext/pdo_dblib/tests/datetime2.phpt +++ b/ext/pdo_dblib/tests/datetime2.phpt @@ -6,7 +6,7 @@ pdo_dblib getAttribute(PDO::DBLIB_ATTR_TDS_VERSION), ['4.2', '4.6', '5.0', '6.0', '7.0', '7.1', '7.2'])) die('skip feature unsupported by this TDS version'); +if (in_array($db->getAttribute(Pdo\Dblib::ATTR_TDS_VERSION), ['4.2', '4.6', '5.0', '6.0', '7.0', '7.1', '7.2'])) die('skip feature unsupported by this TDS version'); ?> --FILE-- getAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT)); +var_dump($db->getAttribute(Pdo\Dblib::ATTR_DATETIME_CONVERT)); $stmt = $db->query($sql); var_dump($stmt->fetch(PDO::FETCH_ASSOC)); -$db->setAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT, 1); -var_dump($db->getAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT)); +$db->setAttribute(Pdo\Dblib::ATTR_DATETIME_CONVERT, 1); +var_dump($db->getAttribute(Pdo\Dblib::ATTR_DATETIME_CONVERT)); $stmt = $db->query($sql); var_dump($stmt->fetch(PDO::FETCH_ASSOC)); diff --git a/ext/pdo_dblib/tests/datetime_convert.phpt b/ext/pdo_dblib/tests/datetime_convert.phpt index ec858cf351c5..0934dd7f83e7 100644 --- a/ext/pdo_dblib/tests/datetime_convert.phpt +++ b/ext/pdo_dblib/tests/datetime_convert.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO_DBLIB: PDO::DBLIB_ATTR_DATETIME_CONVERT +PDO_DBLIB: Pdo\Dblib::ATTR_DATETIME_CONVERT --EXTENSIONS-- pdo_dblib --SKIPIF-- @@ -15,14 +15,14 @@ $db = getDbConnection(); $sql = "SELECT convert(datetime, '20171027 10:22:44.135') AS [d]"; -var_dump($db->getAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT)); +var_dump($db->getAttribute(Pdo\Dblib::ATTR_DATETIME_CONVERT)); $stmt = $db->query($sql); var_dump($stmt->fetch(PDO::FETCH_ASSOC)); // assume default date format: %b %e %Y %I:%M:%S:%z%p -$db->setAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT, 1); -var_dump($db->getAttribute(PDO::DBLIB_ATTR_DATETIME_CONVERT)); +$db->setAttribute(Pdo\Dblib::ATTR_DATETIME_CONVERT, 1); +var_dump($db->getAttribute(Pdo\Dblib::ATTR_DATETIME_CONVERT)); $stmt = $db->query($sql); var_dump($stmt->fetch(PDO::FETCH_ASSOC)); diff --git a/ext/pdo_dblib/tests/dbtds.phpt b/ext/pdo_dblib/tests/dbtds.phpt index aa05606a9326..fb2402eec080 100644 --- a/ext/pdo_dblib/tests/dbtds.phpt +++ b/ext/pdo_dblib/tests/dbtds.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO_DBLIB: \PDO::DBLIB_ATTR_TDS_VERSION exposes a string or false +PDO_DBLIB: \Pdo\Dblib::ATTR_TDS_VERSION exposes a string or false --EXTENSIONS-- pdo_dblib --SKIPIF-- @@ -13,7 +13,7 @@ require __DIR__ . '/config.inc'; $db = getDbConnection(); -$version = $db->getAttribute(PDO::DBLIB_ATTR_TDS_VERSION); +$version = $db->getAttribute(Pdo\Dblib::ATTR_TDS_VERSION); var_dump((is_string($version) && strlen($version)) || $version === false); ?> diff --git a/ext/pdo_dblib/tests/dbversion.phpt b/ext/pdo_dblib/tests/dbversion.phpt index 44dd8f4a86dc..aa61a26beeb2 100644 --- a/ext/pdo_dblib/tests/dbversion.phpt +++ b/ext/pdo_dblib/tests/dbversion.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO_DBLIB: \PDO::DBLIB_ATTR_VERSION exposes a string +PDO_DBLIB: \Pdo\Dblib::ATTR_VERSION exposes a string --EXTENSIONS-- pdo_dblib --SKIPIF-- @@ -13,7 +13,7 @@ require __DIR__ . '/config.inc'; $db = getDbConnection(); -$version = $db->getAttribute(PDO::DBLIB_ATTR_VERSION); +$version = $db->getAttribute(Pdo\Dblib::ATTR_VERSION); var_dump(is_string($version) && strlen($version)); ?> diff --git a/ext/pdo_dblib/tests/php_8.5_deprecations.phpt b/ext/pdo_dblib/tests/php_8.5_deprecations.phpt new file mode 100644 index 000000000000..bf0e84cb4080 --- /dev/null +++ b/ext/pdo_dblib/tests/php_8.5_deprecations.phpt @@ -0,0 +1,39 @@ +--TEST-- +PDO_dblib: PHP 8.5 deprecations +--EXTENSIONS-- +pdo_dblib +--FILE-- + +--EXPECTF-- +Deprecated: Constant PDO::DBLIB_ATTR_CONNECTION_TIMEOUT is deprecated since 8.5, use Pdo\Dblib::ATTR_CONNECTION_TIMEOUT instead in %s on line %d + +Deprecated: Constant PDO::DBLIB_ATTR_QUERY_TIMEOUT is deprecated since 8.5, use Pdo\Dblib::ATTR_QUERY_TIMEOUT instead in %s on line %d + +Deprecated: Constant PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER is deprecated since 8.5, use Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER instead in %s on line %d + +Deprecated: Constant PDO::DBLIB_ATTR_VERSION is deprecated since 8.5, use Pdo\Dblib::ATTR_VERSION instead in %s on line %d + +Deprecated: Constant PDO::DBLIB_ATTR_TDS_VERSION is deprecated since 8.5, use Pdo\Dblib::ATTR_TDS_VERSION instead in %s on line %d + +Deprecated: Constant PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS is deprecated since 8.5, use Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS instead in %s on line %d + +Deprecated: Constant PDO::DBLIB_ATTR_DATETIME_CONVERT is deprecated since 8.5, use Pdo\Dblib::ATTR_DATETIME_CONVERT instead in %s on line %d +int(1000) +int(1001) +int(1002) +int(1003) +int(1004) +int(1005) +int(1006) diff --git a/ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt b/ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt index 86c94877c63c..3e87b4790ca9 100644 --- a/ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt +++ b/ext/pdo_dblib/tests/stringify_uniqueidentifier.phpt @@ -6,7 +6,7 @@ pdo_dblib getAttribute(PDO::DBLIB_ATTR_TDS_VERSION), ['4.2', '4.6'])) die('skip feature unsupported by this TDS version'); +if (in_array($db->getAttribute(Pdo\Dblib::ATTR_TDS_VERSION), ['4.2', '4.6'])) die('skip feature unsupported by this TDS version'); ?> --FILE-- setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true); -var_dump(true === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER)); -$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, false); -var_dump(false === $db->getAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER)); +$db->setAttribute(Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER, true); +var_dump(true === $db->getAttribute(Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER)); +$db->setAttribute(Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER, false); +var_dump(false === $db->getAttribute(Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER)); //-------------------------------------------------------------------------------- @@ -54,7 +54,7 @@ var_dump($row['guid'] === $testGUIDBinary); // TODO: something from PDO::ATTR_SERVER_VERSION, PDO::ATTR_CLIENT_VERSION or PDO::ATTR_SERVER_INFO should be used // to get TDS version and skip this test in this case. //-------------------------------------------------------------------------------- -$db->setAttribute(PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true); +$db->setAttribute(Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER, true); $stmt = $db->query($sql); $row = $stmt->fetch(PDO::FETCH_ASSOC); diff --git a/ext/pdo_dblib/tests/timeout.phpt b/ext/pdo_dblib/tests/timeout.phpt index 08e8ef54ecab..5f935a3d01b8 100644 --- a/ext/pdo_dblib/tests/timeout.phpt +++ b/ext/pdo_dblib/tests/timeout.phpt @@ -33,7 +33,7 @@ if (!$stmt->execute()) { // pdo_dblib-specific timeout attribute, set after instance created, will control query timeout, causing this query to fail $db = getDbConnection(); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); -$db->setAttribute(PDO::DBLIB_ATTR_QUERY_TIMEOUT, 1); +$db->setAttribute(Pdo\Dblib::ATTR_QUERY_TIMEOUT, 1); $stmt = $db->prepare($sql); if (!$stmt->execute()) { echo "OK\n"; @@ -57,7 +57,7 @@ if (!$stmt->execute()) { } // pdo_dblib-specific timeout attribute will control query timeout, causing this query to fail -$db = getDbConnection(PDO::class, [PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT, PDO::DBLIB_ATTR_QUERY_TIMEOUT => 1]); +$db = getDbConnection(PDO::class, [PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT, Pdo\Dblib::ATTR_QUERY_TIMEOUT => 1]); $stmt = $db->prepare($sql); if (!$stmt->execute()) { echo "OK\n"; diff --git a/ext/pdo_dblib/tests/types.phpt b/ext/pdo_dblib/tests/types.phpt index a58a969c6f1b..df04115fee9e 100644 --- a/ext/pdo_dblib/tests/types.phpt +++ b/ext/pdo_dblib/tests/types.phpt @@ -16,7 +16,7 @@ $db = getDbConnection(); function get_expected_float_string() { global $db; - switch ($db->getAttribute(PDO::DBLIB_ATTR_TDS_VERSION)) { + switch ($db->getAttribute(Pdo\Dblib::ATTR_TDS_VERSION)) { case '5.0': case '6.0': case '7.0': diff --git a/ext/pdo_firebird/config.w32 b/ext/pdo_firebird/config.w32 index 003a1a677082..1c5cb4214ad7 100644 --- a/ext/pdo_firebird/config.w32 +++ b/ext/pdo_firebird/config.w32 @@ -5,9 +5,9 @@ ARG_WITH("pdo-firebird", "Firebird support for PDO", "no"); if (PHP_PDO_FIREBIRD != "no") { if (CHECK_LIB("fbclient_ms.lib", "pdo_firebird", PHP_PHP_BUILD + "\\interbase\\lib_ms;" + PHP_PDO_FIREBIRD) - && CHECK_HEADER_ADD_INCLUDE("ibase.h", "CFLAGS_PDO_FIREBIRD", + && CHECK_HEADER("ibase.h", "CFLAGS_PDO_FIREBIRD", PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) - && CHECK_HEADER_ADD_INCLUDE("firebird\\Interface.h", "CFLAGS_PDO_FIREBIRD", + && CHECK_HEADER("firebird\\Interface.h", "CFLAGS_PDO_FIREBIRD", PHP_PHP_BUILD + "\\include\\interbase;" + PHP_PHP_BUILD + "\\interbase\\include;" + PHP_PDO_FIREBIRD) ) { diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index f6d5b1144f38..c20969aac2b0 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ @@ -295,9 +293,9 @@ static FbTokenType php_firebird_get_token(const char** begin, const char* end) return ret; } -static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTable* named_params) +static int php_firebird_preprocess(const zend_string* sql, char* sql_out, size_t* sql_out_len, HashTable* named_params) { - bool passAsIs = 1, execBlock = 0; + bool passAsIs = true, execBlock = false; zend_long pindex = -1; char pname[254], ident[253], ident2[253]; unsigned int l; @@ -326,7 +324,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 252) { return 0; } - strncpy(ident, i, l); + memcpy(ident, i, l); ident[l] = '\0'; if (!strcasecmp(ident, "EXECUTE")) { @@ -351,10 +349,10 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 252) { return 0; } - strncpy(ident2, i2, l); + memcpy(ident2, i2, l); ident2[l] = '\0'; execBlock = !strcasecmp(ident2, "BLOCK"); - passAsIs = 0; + passAsIs = false; } else { @@ -367,11 +365,15 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (passAsIs) { - strcpy(sql_out, ZSTR_VAL(sql)); + memcpy(sql_out, ZSTR_VAL(sql), ZSTR_LEN(sql)); + sql_out[ZSTR_LEN(sql)] = '\0'; + *sql_out_len = ZSTR_LEN(sql); return 1; } - strncat(sql_out, start, p - start); + char *sql_out_p = sql_out; + memcpy(sql_out_p, start, p - start); + sql_out_p += p - start; while (p < end) { @@ -379,10 +381,12 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa tok = php_firebird_get_token(&p, end); switch (tok) { - case ttParamMark: - tok = php_firebird_get_token(&p, end); + case ttParamMark: { + const char* p_peek = p; + tok = php_firebird_get_token(&p_peek, end); if (tok == ttIdent /*|| tok == ttString*/) { + p = p_peek; ++pindex; l = p - start; /* check the length of the identifier */ @@ -391,7 +395,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 253) { return 0; } - strncpy(pname, start, l); + memcpy(pname, start, l); pname[l] = '\0'; if (named_params) { @@ -400,7 +404,7 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa zend_hash_str_update(named_params, pname, l, &tmp); } - strcat(sql_out, "?"); + *sql_out_p++ = '?'; } else { @@ -410,10 +414,11 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa return 0; } ++pindex; - strncat(sql_out, start, p - start); + memcpy(sql_out_p, start, p - start); + sql_out_p += p - start; } break; - + } case ttIdent: if (execBlock) { @@ -425,11 +430,14 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa if (l > 252) { return 0; } - strncpy(ident, start, l); + memcpy(ident, start, l); ident[l] = '\0'; if (!strcasecmp(ident, "AS")) { - strncat(sql_out, start, end - start); + memcpy(sql_out_p, start, end - start); + sql_out_p += end - start; + *sql_out_p = '\0'; + *sql_out_len = sql_out_p - sql_out; return 1; } } @@ -440,7 +448,8 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa case ttComment: case ttString: case ttOther: - strncat(sql_out, start, p - start); + memcpy(sql_out_p, start, p - start); + sql_out_p += p - start; break; case ttBrokenComment: @@ -455,9 +464,10 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa case ttNone: /* Execute statement preprocess SQL error */ return 0; - break; } } + *sql_out_p = '\0'; + *sql_out_len = sql_out_p - sql_out; return 1; } @@ -592,7 +602,7 @@ static void firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */ php_firebird_rollback_transaction(dbh); } } - H->in_manually_txn = 0; + H->in_manually_txn = false; /* isc_detach_database returns 0 on success, 1 on failure. */ if (H->db && isc_detach_database(H->isc_status, &H->db)) { @@ -758,7 +768,7 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /* ret = -1; goto free_statement; } - while (result[i] != isc_info_end && i < result_size) { + while (i < result_size && result[i] != isc_info_end) { short len = (short)isc_vax_integer(&result[i+1],2); /* bail out on bad len */ if (len != 1 && len != 2 && len != 4) { @@ -792,7 +802,7 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const zend_string *sql) /* static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { size_t qcount = 0; - char const *co, *l, *r; + char const *co, *l; char *c; size_t quotedlen; zend_string *quoted_str; @@ -801,9 +811,15 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un return ZSTR_INIT_LITERAL("''", 0); } + const char * const end = ZSTR_VAL(unquoted) + ZSTR_LEN(unquoted); + /* Firebird only requires single quotes to be doubled if string lengths are used */ /* count the number of ' characters */ - for (co = ZSTR_VAL(unquoted); (co = strchr(co,'\'')); qcount++, co++); + for (co = ZSTR_VAL(unquoted); co < end; co++) { + if (*co == '\'') { + qcount++; + } + } if (UNEXPECTED(ZSTR_LEN(unquoted) + 2 > ZSTR_MAX_LEN - qcount)) { return NULL; @@ -815,15 +831,14 @@ static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *un *c++ = '\''; /* foreach (chunk that ends in a quote) */ - for (l = ZSTR_VAL(unquoted); (r = strchr(l,'\'')); l = r+1) { - strncpy(c, l, r-l+1); - c += (r-l+1); - /* add the second quote */ - *c++ = '\''; + for (l = ZSTR_VAL(unquoted); l < end; l++) { + *c++ = *l; + if (*l == '\'') { + /* add the second quote */ + *c++ = '\''; + } } - /* copy the remainder */ - strncpy(c, l, quotedlen-(c-ZSTR_VAL(quoted_str))-1); ZSTR_VAL(quoted_str)[quotedlen-1] = '\''; ZSTR_VAL(quoted_str)[quotedlen] = '\0'; @@ -904,7 +919,7 @@ static bool firebird_handle_manually_begin(pdo_dbh_t *dbh) /* {{{ */ if (!php_firebird_begin_transaction(dbh, /* auto commit mode */ false)) { return false; } - H->in_manually_txn = 1; + H->in_manually_txn = true; return true; } /* }}} */ @@ -954,7 +969,7 @@ static bool firebird_handle_manually_commit(pdo_dbh_t *dbh) /* {{{ */ return false; } } - H->in_manually_txn = 0; + H->in_manually_txn = false; return true; } /* }}} */ @@ -990,7 +1005,7 @@ static bool firebird_handle_manually_rollback(pdo_dbh_t *dbh) /* {{{ */ return false; } } - H->in_manually_txn = 0; + H->in_manually_txn = false; return true; } /* }}} */ @@ -1001,6 +1016,7 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; char *new_sql; + size_t new_sql_len; /* allocate the statement */ if (isc_dsql_allocate_statement(H->isc_status, &H->db, s)) { @@ -1012,14 +1028,14 @@ static int php_firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const zend_string *sq we need to replace :foo by ?, and store the name we just replaced */ new_sql = emalloc(ZSTR_LEN(sql)+1); new_sql[0] = '\0'; - if (!php_firebird_preprocess(sql, new_sql, named_params)) { + if (!php_firebird_preprocess(sql, new_sql, &new_sql_len, named_params)) { php_firebird_error_with_info(dbh, "07000", strlen("07000"), NULL, 0); efree(new_sql); return 0; } /* prepare the statement */ - if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) { + if (isc_dsql_prepare(H->isc_status, &H->tr, s, new_sql_len, new_sql, H->sql_dialect, out_sqlda)) { php_firebird_error(dbh); efree(new_sql); return 0; @@ -1353,7 +1369,7 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* dbh->password = pestrdup(vars[5].optval, dbh->is_persistent); } - H->in_manually_txn = 0; + H->in_manually_txn = false; H->is_writable_txn = pdo_attr_lval(driver_options, PDO_FB_WRITABLE_TRANSACTION, 1); zend_long txn_isolation_level = pdo_attr_lval(driver_options, PDO_FB_TRANSACTION_ISOLATION_LEVEL, PDO_FB_REPEATABLE_READ); if (txn_isolation_level == PDO_FB_READ_COMMITTED || diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 60a5e60e11bd..bdca5af974cf 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ @@ -87,7 +85,6 @@ static int get_formatted_time_tz(pdo_stmt_t *stmt, const ISC_TIME_TZ* timeTz, zv struct tm t; ISC_TIME time; char timeBuf[80] = {0}; - char timeTzBuf[124] = {0}; if (fb_decode_time_tz(S->H->isc_status, timeTz, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) { return 1; } @@ -100,8 +97,8 @@ static int get_formatted_time_tz(pdo_stmt_t *stmt, const ISC_TIME_TZ* timeTz, zv return 1; } - size_t time_tz_len = sprintf(timeTzBuf, "%s %s", timeBuf, timeZoneBuffer); - ZVAL_STRINGL(result, timeTzBuf, time_tz_len); + zend_string *time_tz_str = zend_strpprintf(0, "%s %s", timeBuf, timeZoneBuffer); + ZVAL_NEW_STR(result, time_tz_str); return 0; } @@ -115,7 +112,6 @@ static int get_formatted_timestamp_tz(pdo_stmt_t *stmt, const ISC_TIMESTAMP_TZ* struct tm t; ISC_TIMESTAMP ts; char timestampBuf[80] = {0}; - char timestampTzBuf[124] = {0}; if (fb_decode_timestamp_tz(S->H->isc_status, timestampTz, &year, &month, &day, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) { return 1; } @@ -130,8 +126,8 @@ static int get_formatted_timestamp_tz(pdo_stmt_t *stmt, const ISC_TIMESTAMP_TZ* return 1; } - size_t timestamp_tz_len = sprintf(timestampTzBuf, "%s %s", timestampBuf, timeZoneBuffer); - ZVAL_STRINGL(result, timestampTzBuf, timestamp_tz_len); + zend_string *timestamp_tz_str = zend_strpprintf(0, "%s %s", timestampBuf, timeZoneBuffer); + ZVAL_NEW_STR(result, timestamp_tz_str); return 0; } @@ -237,7 +233,7 @@ static int pdo_firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */ if (result_size > sizeof(result)) { goto error; } - while (result[i] != isc_info_end && i < result_size) { + while (i < result_size && result[i] != isc_info_end) { short len = (short) isc_vax_integer(&result[i + 1], 2); if (len != 1 && len != 2 && len != 4) { goto error; @@ -494,7 +490,7 @@ static int pdo_firebird_stmt_get_col( break; case SQL_DOUBLE: break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if ((var->sqltype & ~1) == SQL_DOUBLE) { diff --git a/ext/pdo_firebird/pdo_firebird.c b/ext/pdo_firebird/pdo_firebird.c index 0fbdb7f8c97c..74ba7f8994ca 100644 --- a/ext/pdo_firebird/pdo_firebird.c +++ b/ext/pdo_firebird/pdo_firebird.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ @@ -55,11 +53,14 @@ zend_module_entry pdo_firebird_module_entry = { /* {{{ */ ZEND_GET_MODULE(pdo_firebird) #endif +#define REGISTER_PDO_FB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, value) \ + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, "FB_", "Pdo\\Firebird::", value) + PHP_MINIT_FUNCTION(pdo_firebird) /* {{{ */ { - REGISTER_PDO_CLASS_CONST_LONG("FB_ATTR_DATE_FORMAT", (zend_long) PDO_FB_ATTR_DATE_FORMAT); - REGISTER_PDO_CLASS_CONST_LONG("FB_ATTR_TIME_FORMAT", (zend_long) PDO_FB_ATTR_TIME_FORMAT); - REGISTER_PDO_CLASS_CONST_LONG("FB_ATTR_TIMESTAMP_FORMAT", (zend_long) PDO_FB_ATTR_TIMESTAMP_FORMAT); + REGISTER_PDO_FB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_DATE_FORMAT", (zend_long) PDO_FB_ATTR_DATE_FORMAT); + REGISTER_PDO_FB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_TIME_FORMAT", (zend_long) PDO_FB_ATTR_TIME_FORMAT); + REGISTER_PDO_FB_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_TIMESTAMP_FORMAT", (zend_long) PDO_FB_ATTR_TIMESTAMP_FORMAT); if (FAILURE == php_pdo_register_driver(&pdo_firebird_driver)) { return FAILURE; @@ -103,9 +104,7 @@ PHP_MINFO_FUNCTION(pdo_firebird) /* {{{ */ PHP_METHOD(Pdo_Firebird, getApiVersion) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(FB_API_VER); } diff --git a/ext/pdo_firebird/pdo_firebird_arginfo.h b/ext/pdo_firebird/pdo_firebird_arginfo.h index a5a9c562c9c1..11b75f920880 100644 --- a/ext/pdo_firebird/pdo_firebird_arginfo.h +++ b/ext/pdo_firebird/pdo_firebird_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pdo_firebird.stub.php instead. * Stub hash: d36b2055abc48ae91c3442dda68fa2a28eb6d25b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Pdo_Firebird_getApiVersion, 0, 0, IS_LONG, 0) @@ -20,51 +20,51 @@ static zend_class_entry *register_class_Pdo_Firebird(zend_class_entry *class_ent zval const_ATTR_DATE_FORMAT_value; ZVAL_LONG(&const_ATTR_DATE_FORMAT_value, PDO_FB_ATTR_DATE_FORMAT); - zend_string *const_ATTR_DATE_FORMAT_name = zend_string_init_interned("ATTR_DATE_FORMAT", sizeof("ATTR_DATE_FORMAT") - 1, 1); + zend_string *const_ATTR_DATE_FORMAT_name = zend_string_init_interned("ATTR_DATE_FORMAT", sizeof("ATTR_DATE_FORMAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_DATE_FORMAT_name, &const_ATTR_DATE_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_DATE_FORMAT_name); + zend_string_release_ex(const_ATTR_DATE_FORMAT_name, true); zval const_ATTR_TIME_FORMAT_value; ZVAL_LONG(&const_ATTR_TIME_FORMAT_value, PDO_FB_ATTR_TIME_FORMAT); - zend_string *const_ATTR_TIME_FORMAT_name = zend_string_init_interned("ATTR_TIME_FORMAT", sizeof("ATTR_TIME_FORMAT") - 1, 1); + zend_string *const_ATTR_TIME_FORMAT_name = zend_string_init_interned("ATTR_TIME_FORMAT", sizeof("ATTR_TIME_FORMAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_TIME_FORMAT_name, &const_ATTR_TIME_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_TIME_FORMAT_name); + zend_string_release_ex(const_ATTR_TIME_FORMAT_name, true); zval const_ATTR_TIMESTAMP_FORMAT_value; ZVAL_LONG(&const_ATTR_TIMESTAMP_FORMAT_value, PDO_FB_ATTR_TIMESTAMP_FORMAT); - zend_string *const_ATTR_TIMESTAMP_FORMAT_name = zend_string_init_interned("ATTR_TIMESTAMP_FORMAT", sizeof("ATTR_TIMESTAMP_FORMAT") - 1, 1); + zend_string *const_ATTR_TIMESTAMP_FORMAT_name = zend_string_init_interned("ATTR_TIMESTAMP_FORMAT", sizeof("ATTR_TIMESTAMP_FORMAT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_TIMESTAMP_FORMAT_name, &const_ATTR_TIMESTAMP_FORMAT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_TIMESTAMP_FORMAT_name); + zend_string_release_ex(const_ATTR_TIMESTAMP_FORMAT_name, true); zval const_TRANSACTION_ISOLATION_LEVEL_value; ZVAL_LONG(&const_TRANSACTION_ISOLATION_LEVEL_value, PDO_FB_TRANSACTION_ISOLATION_LEVEL); - zend_string *const_TRANSACTION_ISOLATION_LEVEL_name = zend_string_init_interned("TRANSACTION_ISOLATION_LEVEL", sizeof("TRANSACTION_ISOLATION_LEVEL") - 1, 1); + zend_string *const_TRANSACTION_ISOLATION_LEVEL_name = zend_string_init_interned("TRANSACTION_ISOLATION_LEVEL", sizeof("TRANSACTION_ISOLATION_LEVEL") - 1, true); zend_declare_typed_class_constant(class_entry, const_TRANSACTION_ISOLATION_LEVEL_name, &const_TRANSACTION_ISOLATION_LEVEL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRANSACTION_ISOLATION_LEVEL_name); + zend_string_release_ex(const_TRANSACTION_ISOLATION_LEVEL_name, true); zval const_READ_COMMITTED_value; ZVAL_LONG(&const_READ_COMMITTED_value, PDO_FB_READ_COMMITTED); - zend_string *const_READ_COMMITTED_name = zend_string_init_interned("READ_COMMITTED", sizeof("READ_COMMITTED") - 1, 1); + zend_string *const_READ_COMMITTED_name = zend_string_init_interned("READ_COMMITTED", sizeof("READ_COMMITTED") - 1, true); zend_declare_typed_class_constant(class_entry, const_READ_COMMITTED_name, &const_READ_COMMITTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_READ_COMMITTED_name); + zend_string_release_ex(const_READ_COMMITTED_name, true); zval const_REPEATABLE_READ_value; ZVAL_LONG(&const_REPEATABLE_READ_value, PDO_FB_REPEATABLE_READ); - zend_string *const_REPEATABLE_READ_name = zend_string_init_interned("REPEATABLE_READ", sizeof("REPEATABLE_READ") - 1, 1); + zend_string *const_REPEATABLE_READ_name = zend_string_init_interned("REPEATABLE_READ", sizeof("REPEATABLE_READ") - 1, true); zend_declare_typed_class_constant(class_entry, const_REPEATABLE_READ_name, &const_REPEATABLE_READ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REPEATABLE_READ_name); + zend_string_release_ex(const_REPEATABLE_READ_name, true); zval const_SERIALIZABLE_value; ZVAL_LONG(&const_SERIALIZABLE_value, PDO_FB_SERIALIZABLE); - zend_string *const_SERIALIZABLE_name = zend_string_init_interned("SERIALIZABLE", sizeof("SERIALIZABLE") - 1, 1); + zend_string *const_SERIALIZABLE_name = zend_string_init_interned("SERIALIZABLE", sizeof("SERIALIZABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SERIALIZABLE_name, &const_SERIALIZABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SERIALIZABLE_name); + zend_string_release_ex(const_SERIALIZABLE_name, true); zval const_WRITABLE_TRANSACTION_value; ZVAL_LONG(&const_WRITABLE_TRANSACTION_value, PDO_FB_WRITABLE_TRANSACTION); - zend_string *const_WRITABLE_TRANSACTION_name = zend_string_init_interned("WRITABLE_TRANSACTION", sizeof("WRITABLE_TRANSACTION") - 1, 1); + zend_string *const_WRITABLE_TRANSACTION_name = zend_string_init_interned("WRITABLE_TRANSACTION", sizeof("WRITABLE_TRANSACTION") - 1, true); zend_declare_typed_class_constant(class_entry, const_WRITABLE_TRANSACTION_name, &const_WRITABLE_TRANSACTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_WRITABLE_TRANSACTION_name); + zend_string_release_ex(const_WRITABLE_TRANSACTION_name, true); return class_entry; } diff --git a/ext/pdo_firebird/pdo_firebird_utils.cpp b/ext/pdo_firebird/pdo_firebird_utils.cpp index 715963eec17c..cd54da8cd9c6 100644 --- a/ext/pdo_firebird/pdo_firebird_utils.cpp +++ b/ext/pdo_firebird/pdo_firebird_utils.cpp @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Simonov Denis | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/pdo_firebird_utils.h b/ext/pdo_firebird/pdo_firebird_utils.h index 19b0d0ab4ba4..3a3ee4ab7c41 100644 --- a/ext/pdo_firebird/pdo_firebird_utils.h +++ b/ext/pdo_firebird/pdo_firebird_utils.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Simonov Denis | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/php_pdo_firebird.h b/ext/pdo_firebird/php_pdo_firebird.h index 19ce061c959f..6d897dfd2933 100644 --- a/ext/pdo_firebird/php_pdo_firebird.h +++ b/ext/pdo_firebird/php_pdo_firebird.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h index a62c152ffab3..7e83b2687a72 100644 --- a/ext/pdo_firebird/php_pdo_firebird_int.h +++ b/ext/pdo_firebird/php_pdo_firebird_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ard Biesheuvel | +----------------------------------------------------------------------+ diff --git a/ext/pdo_firebird/tests/autocommit.phpt b/ext/pdo_firebird/tests/autocommit.phpt index 3f4f7e8f370f..daa91898a8e9 100644 --- a/ext/pdo_firebird/tests/autocommit.phpt +++ b/ext/pdo_firebird/tests/autocommit.phpt @@ -71,9 +71,9 @@ array(1) { ========== not in auto commit mode ========== auto commit mode OFF insert, expect error -SQLSTATE[08003]: Connection does not exist: %s +%r(SQLSTATE\[08003\]: Connection does not exist|SQLSTATE\[HY000\]: General error)%r: %s select, expect error -SQLSTATE[08003]: Connection does not exist: %s +%r(SQLSTATE\[08003\]: Connection does not exist|SQLSTATE\[HY000\]: General error)%r: %s done! diff --git a/ext/pdo_firebird/tests/dialect_1.phpt b/ext/pdo_firebird/tests/dialect_1.phpt index c08b37bf552c..9b934cd40ec0 100644 --- a/ext/pdo_firebird/tests/dialect_1.phpt +++ b/ext/pdo_firebird/tests/dialect_1.phpt @@ -14,7 +14,7 @@ require("testdb.inc"); $dbh = getDbConnection(); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); -$dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S'); +$dbh->setAttribute(Pdo\Firebird::ATTR_TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S'); $sql = 'SELECT diff --git a/ext/pdo_firebird/tests/execute.phpt b/ext/pdo_firebird/tests/execute.phpt index 464c8c29a9c4..cb749956ecfb 100644 --- a/ext/pdo_firebird/tests/execute.phpt +++ b/ext/pdo_firebird/tests/execute.phpt @@ -12,7 +12,7 @@ $dbh = getDbConnection(); var_dump($dbh->getAttribute(PDO::ATTR_CONNECTION_STATUS)); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); -$dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S'); +$dbh->setAttribute(Pdo\Firebird::ATTR_TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S'); $dbh->exec("CREATE TABLE test_execute (id SMALLINT NOT NULL PRIMARY KEY, text VARCHAR(32), datetime TIMESTAMP DEFAULT '2000-02-12' NOT NULL)"); diff --git a/ext/pdo_firebird/tests/gh18276.phpt b/ext/pdo_firebird/tests/gh18276.phpt index 610876166ccf..5a1c4b4de295 100644 --- a/ext/pdo_firebird/tests/gh18276.phpt +++ b/ext/pdo_firebird/tests/gh18276.phpt @@ -23,9 +23,9 @@ for ($i = 0; $i < 2; $i++) { ], ); // Avoid interned - $dbh->setAttribute(PDO::FB_ATTR_DATE_FORMAT, str_repeat('Y----m----d', random_int(1, 1))); - $dbh->setAttribute(PDO::FB_ATTR_TIME_FORMAT, str_repeat('H::::i::::s', random_int(1, 1))); - $dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, str_repeat('Y----m----d....H::::i::::s', random_int(1, 1))); + $dbh->setAttribute(Pdo\Firebird::ATTR_DATE_FORMAT, str_repeat('Y----m----d', random_int(1, 1))); + $dbh->setAttribute(Pdo\Firebird::ATTR_TIME_FORMAT, str_repeat('H::::i::::s', random_int(1, 1))); + $dbh->setAttribute(Pdo\Firebird::ATTR_TIMESTAMP_FORMAT, str_repeat('Y----m----d....H::::i::::s', random_int(1, 1))); unset($dbh); } diff --git a/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt b/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt new file mode 100644 index 000000000000..3046fbc011b7 --- /dev/null +++ b/ext/pdo_firebird/tests/ghsa-w476-322c-wpvm.phpt @@ -0,0 +1,46 @@ +--TEST-- +GHSA-w476-322c-wpvm: SQL injection in pdo_firebird via NUL bytes in quoted strings +--EXTENSIONS-- +pdo_firebird +--SKIPIF-- + +--XLEAK-- +A bug in firebird causes a memory leak when calling `isc_attach_database()`. +See https://github.com/FirebirdSQL/firebird/issues/7849 +--FILE-- +exec('CREATE TABLE ghsa_w476_322c_wpvm (name VARCHAR(255))'); + +$param = $dbh->quote("\0"); +$param2 = $dbh->quote('or 1=1--'); +var_export($param); +echo("\n"); + +echo "prepare: "; +$stmt = $dbh->prepare("SELECT * FROM ghsa_w476_322c_wpvm WHERE name = {$param} AND name = {$param2}"); +$stmt->execute(); +echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)) . "\n"; + +echo "query: "; +$stmt = $dbh->query("SELECT * FROM ghsa_w476_322c_wpvm WHERE name = {$param} AND name = {$param2}"); +echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC)) . "\n"; + +echo "exec: "; +$affectedRows = $dbh->exec("UPDATE ghsa_w476_322c_wpvm SET name = 'updated' WHERE name = {$param} AND name = {$param2}"); +echo $affectedRows . "\n"; +?> +--CLEAN-- +exec("DROP TABLE ghsa_w476_322c_wpvm"); +?> +--EXPECT-- +'\'' . "\0" . '\'' +prepare: [] +query: [] +exec: 0 diff --git a/ext/pdo_firebird/tests/php_8.5_deprecations.phpt b/ext/pdo_firebird/tests/php_8.5_deprecations.phpt new file mode 100644 index 000000000000..6919dda408fd --- /dev/null +++ b/ext/pdo_firebird/tests/php_8.5_deprecations.phpt @@ -0,0 +1,23 @@ +--TEST-- +PDO_firebird: PHP 8.5 deprecations +--EXTENSIONS-- +pdo_firebird +--FILE-- + +--EXPECTF-- +Deprecated: Constant PDO::FB_ATTR_DATE_FORMAT is deprecated since 8.5, use Pdo\Firebird::ATTR_DATE_FORMAT instead in %s on line %d + +Deprecated: Constant PDO::FB_ATTR_TIME_FORMAT is deprecated since 8.5, use Pdo\Firebird::ATTR_TIME_FORMAT instead in %s on line %d + +Deprecated: Constant PDO::FB_ATTR_TIMESTAMP_FORMAT is deprecated since 8.5, use Pdo\Firebird::ATTR_TIMESTAMP_FORMAT instead in %s on line %d +int(1000) +int(1001) +int(1002) diff --git a/ext/pdo_mysql/config.w32 b/ext/pdo_mysql/config.w32 index ece466975c55..95899d2270c8 100644 --- a/ext/pdo_mysql/config.w32 +++ b/ext/pdo_mysql/config.w32 @@ -12,7 +12,7 @@ if (PHP_PDO_MYSQL != "no") { ADD_MAKEFILE_FRAGMENT(); } else { if (CHECK_LIB("libmysql.lib", "pdo_mysql", PHP_PDO_MYSQL) && - CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_PDO_MYSQL", + CHECK_HEADER("mysql.h", "CFLAGS_PDO_MYSQL", PHP_PDO_MYSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\mysql;" + PHP_PDO_MYSQL)) { diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index f0a2a887a5c7..54a8803971ca 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Wez Furlong | @@ -84,7 +82,7 @@ int _pdo_mysql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int lin "Cannot execute queries while other unbuffered queries are active. " "Consider using PDOStatement::fetchAll(). Alternatively, if your code " "is only ever going to run against mysql, you may enable query " - "buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.", + "buffering by setting the Pdo\\Mysql::ATTR_USE_BUFFERED_QUERY attribute.", dbh->is_persistent); } } else if (einfo->errcode == 2057) { @@ -308,21 +306,21 @@ static zend_string *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const zend_string * static zend_string* mysql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype ) { pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; - bool use_national_character_set = 0; - bool use_binary = 0; + bool use_national_character_set = false; + bool use_binary = false; size_t quotedlen; if ((paramtype & PDO_PARAM_LOB) == PDO_PARAM_LOB) { - use_binary = 1; + use_binary = true; } else { if (H->assume_national_character_set_strings) { - use_national_character_set = 1; + use_national_character_set = true; } if ((paramtype & PDO_PARAM_STR_NATL) == PDO_PARAM_STR_NATL) { - use_national_character_set = 1; + use_national_character_set = true; } if ((paramtype & PDO_PARAM_STR_CHAR) == PDO_PARAM_STR_CHAR) { - use_national_character_set = 0; + use_national_character_set = false; } } diff --git a/ext/pdo_mysql/mysql_sql_parser.re b/ext/pdo_mysql/mysql_sql_parser.re index 01afbefaaa8d..9db54063889d 100644 --- a/ext/pdo_mysql/mysql_sql_parser.re +++ b/ext/pdo_mysql/mysql_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Matteo Beccati | +----------------------------------------------------------------------+ diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index cf01791407e2..f6b182fcb9ad 100644 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Wez Furlong | @@ -713,7 +711,7 @@ static int pdo_mysql_stmt_get_col( static char *type_to_name_native(int type) /* {{{ */ { -#define PDO_MYSQL_NATIVE_TYPE_NAME(x) case FIELD_TYPE_##x: return #x; +#define PDO_MYSQL_NATIVE_TYPE_NAME(x) case MYSQL_TYPE_##x: return #x; switch (type) { PDO_MYSQL_NATIVE_TYPE_NAME(STRING) @@ -746,6 +744,13 @@ static char *type_to_name_native(int type) /* {{{ */ PDO_MYSQL_NATIVE_TYPE_NAME(DATE) #ifdef FIELD_TYPE_NEWDATE PDO_MYSQL_NATIVE_TYPE_NAME(NEWDATE) +#endif + /* The following 2 don't have BC FIELD_TYPE_* aliases. */ +#if (MYSQL_VERSION_ID >= 90000 && !defined(MARIADB_BASE_VERSION)) || defined(PDO_USE_MYSQLND) + PDO_MYSQL_NATIVE_TYPE_NAME(VECTOR) +#endif +#if MYSQL_VERSION_ID >= 50708 || defined(PDO_USE_MYSQLND) + PDO_MYSQL_NATIVE_TYPE_NAME(JSON) #endif PDO_MYSQL_NATIVE_TYPE_NAME(TIME) PDO_MYSQL_NATIVE_TYPE_NAME(DATETIME) diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c index 772022cdbe93..fe5ebc7e6ed8 100644 --- a/ext/pdo_mysql/pdo_mysql.c +++ b/ext/pdo_mysql/pdo_mysql.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Johannes Schlueter | @@ -112,37 +110,40 @@ PHP_INI_END() /* true global environment */ +#define REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, value) \ + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, "MYSQL_", "Pdo\\Mysql::", value) + /* {{{ PHP_MINIT_FUNCTION */ static PHP_MINIT_FUNCTION(pdo_mysql) { REGISTER_INI_ENTRIES(); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_USE_BUFFERED_QUERY", (zend_long)PDO_MYSQL_ATTR_USE_BUFFERED_QUERY); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_LOCAL_INFILE", (zend_long)PDO_MYSQL_ATTR_LOCAL_INFILE); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_INIT_COMMAND", (zend_long)PDO_MYSQL_ATTR_INIT_COMMAND); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_USE_BUFFERED_QUERY", (zend_long)PDO_MYSQL_ATTR_USE_BUFFERED_QUERY); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_LOCAL_INFILE", (zend_long)PDO_MYSQL_ATTR_LOCAL_INFILE); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_INIT_COMMAND", (zend_long)PDO_MYSQL_ATTR_INIT_COMMAND); #ifndef PDO_USE_MYSQLND - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_MAX_BUFFER_SIZE", (zend_long)PDO_MYSQL_ATTR_MAX_BUFFER_SIZE); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_FILE", (zend_long)PDO_MYSQL_ATTR_READ_DEFAULT_FILE); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_GROUP", (zend_long)PDO_MYSQL_ATTR_READ_DEFAULT_GROUP); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_MAX_BUFFER_SIZE", (zend_long)PDO_MYSQL_ATTR_MAX_BUFFER_SIZE); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_READ_DEFAULT_FILE", (zend_long)PDO_MYSQL_ATTR_READ_DEFAULT_FILE); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_READ_DEFAULT_GROUP", (zend_long)PDO_MYSQL_ATTR_READ_DEFAULT_GROUP); #endif - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_COMPRESS", (zend_long)PDO_MYSQL_ATTR_COMPRESS); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_DIRECT_QUERY", (zend_long)PDO_ATTR_EMULATE_PREPARES); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_FOUND_ROWS", (zend_long)PDO_MYSQL_ATTR_FOUND_ROWS); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_IGNORE_SPACE", (zend_long)PDO_MYSQL_ATTR_IGNORE_SPACE); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_KEY", (zend_long)PDO_MYSQL_ATTR_SSL_KEY); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CERT", (zend_long)PDO_MYSQL_ATTR_SSL_CERT); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CA", (zend_long)PDO_MYSQL_ATTR_SSL_CA); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CAPATH", (zend_long)PDO_MYSQL_ATTR_SSL_CAPATH); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CIPHER", (zend_long)PDO_MYSQL_ATTR_SSL_CIPHER); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_COMPRESS", (zend_long)PDO_MYSQL_ATTR_COMPRESS); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_DIRECT_QUERY", (zend_long)PDO_ATTR_EMULATE_PREPARES); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_FOUND_ROWS", (zend_long)PDO_MYSQL_ATTR_FOUND_ROWS); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_IGNORE_SPACE", (zend_long)PDO_MYSQL_ATTR_IGNORE_SPACE); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SSL_KEY", (zend_long)PDO_MYSQL_ATTR_SSL_KEY); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SSL_CERT", (zend_long)PDO_MYSQL_ATTR_SSL_CERT); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SSL_CA", (zend_long)PDO_MYSQL_ATTR_SSL_CA); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SSL_CAPATH", (zend_long)PDO_MYSQL_ATTR_SSL_CAPATH); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SSL_CIPHER", (zend_long)PDO_MYSQL_ATTR_SSL_CIPHER); #if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND) - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SERVER_PUBLIC_KEY", (zend_long)PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SERVER_PUBLIC_KEY", (zend_long)PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY); #endif - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_MULTI_STATEMENTS", (zend_long)PDO_MYSQL_ATTR_MULTI_STATEMENTS); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_MULTI_STATEMENTS", (zend_long)PDO_MYSQL_ATTR_MULTI_STATEMENTS); #ifdef PDO_USE_MYSQLND - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_VERIFY_SERVER_CERT", (zend_long)PDO_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_SSL_VERIFY_SERVER_CERT", (zend_long)PDO_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT); #endif #if MYSQL_VERSION_ID >= 80021 || defined(PDO_USE_MYSQLND) - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_LOCAL_INFILE_DIRECTORY", (zend_long)PDO_MYSQL_ATTR_LOCAL_INFILE_DIRECTORY); + REGISTER_PDO_MYSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_LOCAL_INFILE_DIRECTORY", (zend_long)PDO_MYSQL_ATTR_LOCAL_INFILE_DIRECTORY); #endif #ifdef PDO_USE_MYSQLND diff --git a/ext/pdo_mysql/pdo_mysql_arginfo.h b/ext/pdo_mysql/pdo_mysql_arginfo.h index 0e9c04bd3cfd..a3fe8b90c425 100644 --- a/ext/pdo_mysql/pdo_mysql_arginfo.h +++ b/ext/pdo_mysql/pdo_mysql_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pdo_mysql.stub.php instead. * Stub hash: 9d2c0327499693f1ca2825a9ad42ad769f44a24a */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Pdo_Mysql_getWarningCount, 0, 0, IS_LONG, 0) @@ -20,124 +20,124 @@ static zend_class_entry *register_class_Pdo_Mysql(zend_class_entry *class_entry_ zval const_ATTR_USE_BUFFERED_QUERY_value; ZVAL_LONG(&const_ATTR_USE_BUFFERED_QUERY_value, PDO_MYSQL_ATTR_USE_BUFFERED_QUERY); - zend_string *const_ATTR_USE_BUFFERED_QUERY_name = zend_string_init_interned("ATTR_USE_BUFFERED_QUERY", sizeof("ATTR_USE_BUFFERED_QUERY") - 1, 1); + zend_string *const_ATTR_USE_BUFFERED_QUERY_name = zend_string_init_interned("ATTR_USE_BUFFERED_QUERY", sizeof("ATTR_USE_BUFFERED_QUERY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_USE_BUFFERED_QUERY_name, &const_ATTR_USE_BUFFERED_QUERY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_USE_BUFFERED_QUERY_name); + zend_string_release_ex(const_ATTR_USE_BUFFERED_QUERY_name, true); zval const_ATTR_LOCAL_INFILE_value; ZVAL_LONG(&const_ATTR_LOCAL_INFILE_value, PDO_MYSQL_ATTR_LOCAL_INFILE); - zend_string *const_ATTR_LOCAL_INFILE_name = zend_string_init_interned("ATTR_LOCAL_INFILE", sizeof("ATTR_LOCAL_INFILE") - 1, 1); + zend_string *const_ATTR_LOCAL_INFILE_name = zend_string_init_interned("ATTR_LOCAL_INFILE", sizeof("ATTR_LOCAL_INFILE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_LOCAL_INFILE_name, &const_ATTR_LOCAL_INFILE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_LOCAL_INFILE_name); + zend_string_release_ex(const_ATTR_LOCAL_INFILE_name, true); zval const_ATTR_INIT_COMMAND_value; ZVAL_LONG(&const_ATTR_INIT_COMMAND_value, PDO_MYSQL_ATTR_INIT_COMMAND); - zend_string *const_ATTR_INIT_COMMAND_name = zend_string_init_interned("ATTR_INIT_COMMAND", sizeof("ATTR_INIT_COMMAND") - 1, 1); + zend_string *const_ATTR_INIT_COMMAND_name = zend_string_init_interned("ATTR_INIT_COMMAND", sizeof("ATTR_INIT_COMMAND") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_INIT_COMMAND_name, &const_ATTR_INIT_COMMAND_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_INIT_COMMAND_name); + zend_string_release_ex(const_ATTR_INIT_COMMAND_name, true); #if !defined(PDO_USE_MYSQLND) zval const_ATTR_MAX_BUFFER_SIZE_value; ZVAL_LONG(&const_ATTR_MAX_BUFFER_SIZE_value, PDO_MYSQL_ATTR_MAX_BUFFER_SIZE); - zend_string *const_ATTR_MAX_BUFFER_SIZE_name = zend_string_init_interned("ATTR_MAX_BUFFER_SIZE", sizeof("ATTR_MAX_BUFFER_SIZE") - 1, 1); + zend_string *const_ATTR_MAX_BUFFER_SIZE_name = zend_string_init_interned("ATTR_MAX_BUFFER_SIZE", sizeof("ATTR_MAX_BUFFER_SIZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_MAX_BUFFER_SIZE_name, &const_ATTR_MAX_BUFFER_SIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_MAX_BUFFER_SIZE_name); + zend_string_release_ex(const_ATTR_MAX_BUFFER_SIZE_name, true); zval const_ATTR_READ_DEFAULT_FILE_value; ZVAL_LONG(&const_ATTR_READ_DEFAULT_FILE_value, PDO_MYSQL_ATTR_READ_DEFAULT_FILE); - zend_string *const_ATTR_READ_DEFAULT_FILE_name = zend_string_init_interned("ATTR_READ_DEFAULT_FILE", sizeof("ATTR_READ_DEFAULT_FILE") - 1, 1); + zend_string *const_ATTR_READ_DEFAULT_FILE_name = zend_string_init_interned("ATTR_READ_DEFAULT_FILE", sizeof("ATTR_READ_DEFAULT_FILE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_READ_DEFAULT_FILE_name, &const_ATTR_READ_DEFAULT_FILE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_READ_DEFAULT_FILE_name); + zend_string_release_ex(const_ATTR_READ_DEFAULT_FILE_name, true); zval const_ATTR_READ_DEFAULT_GROUP_value; ZVAL_LONG(&const_ATTR_READ_DEFAULT_GROUP_value, PDO_MYSQL_ATTR_READ_DEFAULT_GROUP); - zend_string *const_ATTR_READ_DEFAULT_GROUP_name = zend_string_init_interned("ATTR_READ_DEFAULT_GROUP", sizeof("ATTR_READ_DEFAULT_GROUP") - 1, 1); + zend_string *const_ATTR_READ_DEFAULT_GROUP_name = zend_string_init_interned("ATTR_READ_DEFAULT_GROUP", sizeof("ATTR_READ_DEFAULT_GROUP") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_READ_DEFAULT_GROUP_name, &const_ATTR_READ_DEFAULT_GROUP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_READ_DEFAULT_GROUP_name); + zend_string_release_ex(const_ATTR_READ_DEFAULT_GROUP_name, true); #endif zval const_ATTR_COMPRESS_value; ZVAL_LONG(&const_ATTR_COMPRESS_value, PDO_MYSQL_ATTR_COMPRESS); - zend_string *const_ATTR_COMPRESS_name = zend_string_init_interned("ATTR_COMPRESS", sizeof("ATTR_COMPRESS") - 1, 1); + zend_string *const_ATTR_COMPRESS_name = zend_string_init_interned("ATTR_COMPRESS", sizeof("ATTR_COMPRESS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_COMPRESS_name, &const_ATTR_COMPRESS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_COMPRESS_name); + zend_string_release_ex(const_ATTR_COMPRESS_name, true); zval const_ATTR_DIRECT_QUERY_value; ZVAL_LONG(&const_ATTR_DIRECT_QUERY_value, PDO_ATTR_EMULATE_PREPARES); - zend_string *const_ATTR_DIRECT_QUERY_name = zend_string_init_interned("ATTR_DIRECT_QUERY", sizeof("ATTR_DIRECT_QUERY") - 1, 1); + zend_string *const_ATTR_DIRECT_QUERY_name = zend_string_init_interned("ATTR_DIRECT_QUERY", sizeof("ATTR_DIRECT_QUERY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_DIRECT_QUERY_name, &const_ATTR_DIRECT_QUERY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_DIRECT_QUERY_name); + zend_string_release_ex(const_ATTR_DIRECT_QUERY_name, true); zval const_ATTR_FOUND_ROWS_value; ZVAL_LONG(&const_ATTR_FOUND_ROWS_value, PDO_MYSQL_ATTR_FOUND_ROWS); - zend_string *const_ATTR_FOUND_ROWS_name = zend_string_init_interned("ATTR_FOUND_ROWS", sizeof("ATTR_FOUND_ROWS") - 1, 1); + zend_string *const_ATTR_FOUND_ROWS_name = zend_string_init_interned("ATTR_FOUND_ROWS", sizeof("ATTR_FOUND_ROWS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_FOUND_ROWS_name, &const_ATTR_FOUND_ROWS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_FOUND_ROWS_name); + zend_string_release_ex(const_ATTR_FOUND_ROWS_name, true); zval const_ATTR_IGNORE_SPACE_value; ZVAL_LONG(&const_ATTR_IGNORE_SPACE_value, PDO_MYSQL_ATTR_IGNORE_SPACE); - zend_string *const_ATTR_IGNORE_SPACE_name = zend_string_init_interned("ATTR_IGNORE_SPACE", sizeof("ATTR_IGNORE_SPACE") - 1, 1); + zend_string *const_ATTR_IGNORE_SPACE_name = zend_string_init_interned("ATTR_IGNORE_SPACE", sizeof("ATTR_IGNORE_SPACE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_IGNORE_SPACE_name, &const_ATTR_IGNORE_SPACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_IGNORE_SPACE_name); + zend_string_release_ex(const_ATTR_IGNORE_SPACE_name, true); zval const_ATTR_SSL_KEY_value; ZVAL_LONG(&const_ATTR_SSL_KEY_value, PDO_MYSQL_ATTR_SSL_KEY); - zend_string *const_ATTR_SSL_KEY_name = zend_string_init_interned("ATTR_SSL_KEY", sizeof("ATTR_SSL_KEY") - 1, 1); + zend_string *const_ATTR_SSL_KEY_name = zend_string_init_interned("ATTR_SSL_KEY", sizeof("ATTR_SSL_KEY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_KEY_name, &const_ATTR_SSL_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SSL_KEY_name); + zend_string_release_ex(const_ATTR_SSL_KEY_name, true); zval const_ATTR_SSL_CERT_value; ZVAL_LONG(&const_ATTR_SSL_CERT_value, PDO_MYSQL_ATTR_SSL_CERT); - zend_string *const_ATTR_SSL_CERT_name = zend_string_init_interned("ATTR_SSL_CERT", sizeof("ATTR_SSL_CERT") - 1, 1); + zend_string *const_ATTR_SSL_CERT_name = zend_string_init_interned("ATTR_SSL_CERT", sizeof("ATTR_SSL_CERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CERT_name, &const_ATTR_SSL_CERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SSL_CERT_name); + zend_string_release_ex(const_ATTR_SSL_CERT_name, true); zval const_ATTR_SSL_CA_value; ZVAL_LONG(&const_ATTR_SSL_CA_value, PDO_MYSQL_ATTR_SSL_CA); - zend_string *const_ATTR_SSL_CA_name = zend_string_init_interned("ATTR_SSL_CA", sizeof("ATTR_SSL_CA") - 1, 1); + zend_string *const_ATTR_SSL_CA_name = zend_string_init_interned("ATTR_SSL_CA", sizeof("ATTR_SSL_CA") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CA_name, &const_ATTR_SSL_CA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SSL_CA_name); + zend_string_release_ex(const_ATTR_SSL_CA_name, true); zval const_ATTR_SSL_CAPATH_value; ZVAL_LONG(&const_ATTR_SSL_CAPATH_value, PDO_MYSQL_ATTR_SSL_CAPATH); - zend_string *const_ATTR_SSL_CAPATH_name = zend_string_init_interned("ATTR_SSL_CAPATH", sizeof("ATTR_SSL_CAPATH") - 1, 1); + zend_string *const_ATTR_SSL_CAPATH_name = zend_string_init_interned("ATTR_SSL_CAPATH", sizeof("ATTR_SSL_CAPATH") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CAPATH_name, &const_ATTR_SSL_CAPATH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SSL_CAPATH_name); + zend_string_release_ex(const_ATTR_SSL_CAPATH_name, true); zval const_ATTR_SSL_CIPHER_value; ZVAL_LONG(&const_ATTR_SSL_CIPHER_value, PDO_MYSQL_ATTR_SSL_CIPHER); - zend_string *const_ATTR_SSL_CIPHER_name = zend_string_init_interned("ATTR_SSL_CIPHER", sizeof("ATTR_SSL_CIPHER") - 1, 1); + zend_string *const_ATTR_SSL_CIPHER_name = zend_string_init_interned("ATTR_SSL_CIPHER", sizeof("ATTR_SSL_CIPHER") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_CIPHER_name, &const_ATTR_SSL_CIPHER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SSL_CIPHER_name); + zend_string_release_ex(const_ATTR_SSL_CIPHER_name, true); #if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND) zval const_ATTR_SERVER_PUBLIC_KEY_value; ZVAL_LONG(&const_ATTR_SERVER_PUBLIC_KEY_value, PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY); - zend_string *const_ATTR_SERVER_PUBLIC_KEY_name = zend_string_init_interned("ATTR_SERVER_PUBLIC_KEY", sizeof("ATTR_SERVER_PUBLIC_KEY") - 1, 1); + zend_string *const_ATTR_SERVER_PUBLIC_KEY_name = zend_string_init_interned("ATTR_SERVER_PUBLIC_KEY", sizeof("ATTR_SERVER_PUBLIC_KEY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SERVER_PUBLIC_KEY_name, &const_ATTR_SERVER_PUBLIC_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SERVER_PUBLIC_KEY_name); + zend_string_release_ex(const_ATTR_SERVER_PUBLIC_KEY_name, true); #endif zval const_ATTR_MULTI_STATEMENTS_value; ZVAL_LONG(&const_ATTR_MULTI_STATEMENTS_value, PDO_MYSQL_ATTR_MULTI_STATEMENTS); - zend_string *const_ATTR_MULTI_STATEMENTS_name = zend_string_init_interned("ATTR_MULTI_STATEMENTS", sizeof("ATTR_MULTI_STATEMENTS") - 1, 1); + zend_string *const_ATTR_MULTI_STATEMENTS_name = zend_string_init_interned("ATTR_MULTI_STATEMENTS", sizeof("ATTR_MULTI_STATEMENTS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_MULTI_STATEMENTS_name, &const_ATTR_MULTI_STATEMENTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_MULTI_STATEMENTS_name); + zend_string_release_ex(const_ATTR_MULTI_STATEMENTS_name, true); #if defined(PDO_USE_MYSQLND) zval const_ATTR_SSL_VERIFY_SERVER_CERT_value; ZVAL_LONG(&const_ATTR_SSL_VERIFY_SERVER_CERT_value, PDO_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT); - zend_string *const_ATTR_SSL_VERIFY_SERVER_CERT_name = zend_string_init_interned("ATTR_SSL_VERIFY_SERVER_CERT", sizeof("ATTR_SSL_VERIFY_SERVER_CERT") - 1, 1); + zend_string *const_ATTR_SSL_VERIFY_SERVER_CERT_name = zend_string_init_interned("ATTR_SSL_VERIFY_SERVER_CERT", sizeof("ATTR_SSL_VERIFY_SERVER_CERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_SSL_VERIFY_SERVER_CERT_name, &const_ATTR_SSL_VERIFY_SERVER_CERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_SSL_VERIFY_SERVER_CERT_name); + zend_string_release_ex(const_ATTR_SSL_VERIFY_SERVER_CERT_name, true); #endif #if MYSQL_VERSION_ID >= 80021 || defined(PDO_USE_MYSQLND) zval const_ATTR_LOCAL_INFILE_DIRECTORY_value; ZVAL_LONG(&const_ATTR_LOCAL_INFILE_DIRECTORY_value, PDO_MYSQL_ATTR_LOCAL_INFILE_DIRECTORY); - zend_string *const_ATTR_LOCAL_INFILE_DIRECTORY_name = zend_string_init_interned("ATTR_LOCAL_INFILE_DIRECTORY", sizeof("ATTR_LOCAL_INFILE_DIRECTORY") - 1, 1); + zend_string *const_ATTR_LOCAL_INFILE_DIRECTORY_name = zend_string_init_interned("ATTR_LOCAL_INFILE_DIRECTORY", sizeof("ATTR_LOCAL_INFILE_DIRECTORY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_LOCAL_INFILE_DIRECTORY_name, &const_ATTR_LOCAL_INFILE_DIRECTORY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_LOCAL_INFILE_DIRECTORY_name); + zend_string_release_ex(const_ATTR_LOCAL_INFILE_DIRECTORY_name, true); #endif return class_entry; diff --git a/ext/pdo_mysql/php_pdo_mysql.h b/ext/pdo_mysql/php_pdo_mysql.h index 650c51b497a2..55b2cded0f28 100644 --- a/ext/pdo_mysql/php_pdo_mysql.h +++ b/ext/pdo_mysql/php_pdo_mysql.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | +----------------------------------------------------------------------+ diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h index ae77193afcfa..baba729aa53d 100644 --- a/ext/pdo_mysql/php_pdo_mysql_int.h +++ b/ext/pdo_mysql/php_pdo_mysql_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: George Schlossnagle | | Wez Furlong | @@ -78,7 +76,7 @@ ZEND_BEGIN_MODULE_GLOBALS(pdo_mysql) /* dummy member so we get at least one member in the struct * and avoids build errors. */ - void *dummymemmber; + void *dummymember; #endif ZEND_END_MODULE_GLOBALS(pdo_mysql) diff --git a/ext/pdo_mysql/tests/bug66528.phpt b/ext/pdo_mysql/tests/bug66528.phpt index 31ae2f42e3a9..4bddfc9dfcf1 100644 --- a/ext/pdo_mysql/tests/bug66528.phpt +++ b/ext/pdo_mysql/tests/bug66528.phpt @@ -13,7 +13,7 @@ require_once __DIR__ . '/inc/mysql_pdo_test.inc'; $dbh = MySQLPDOTest::factory(); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); +$dbh->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); $dbh->exec('CREATE TABLE test_66528 (a INT) ENGINE=InnoDB'); $dbh->beginTransaction(); @@ -46,6 +46,6 @@ $db = MySQLPDOTest::factory(); $db->exec('DROP TABLE IF EXISTS test_66528'); ?> --EXPECT-- -SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. -SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. -SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. +SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. +SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. +SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. diff --git a/ext/pdo_mysql/tests/bug67004.phpt b/ext/pdo_mysql/tests/bug67004.phpt index 019be3fec9de..39e19a9ed22c 100644 --- a/ext/pdo_mysql/tests/bug67004.phpt +++ b/ext/pdo_mysql/tests/bug67004.phpt @@ -14,7 +14,7 @@ $dbh = MySQLPDOTest::factory(); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); -$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); +$dbh->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $dbh->prepare("SELECT ?"); diff --git a/ext/pdo_mysql/tests/bug68371.phpt b/ext/pdo_mysql/tests/bug68371.phpt index 146b8e4684d2..5b5152dd054a 100644 --- a/ext/pdo_mysql/tests/bug68371.phpt +++ b/ext/pdo_mysql/tests/bug68371.phpt @@ -16,7 +16,7 @@ $pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $attrs = [ // Extensive test: default value and set+get values PDO::ATTR_EMULATE_PREPARES => array(null, true, false), - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => array(null, false, true), + Pdo\Mysql::ATTR_USE_BUFFERED_QUERY => array(null, false, true), // Just test the default PDO::ATTR_AUTOCOMMIT => [null], diff --git a/ext/pdo_mysql/tests/bug70389.phpt b/ext/pdo_mysql/tests/bug70389.phpt index b4f6bf1afeb4..a8bbab8cc16e 100644 --- a/ext/pdo_mysql/tests/bug70389.phpt +++ b/ext/pdo_mysql/tests/bug70389.phpt @@ -11,8 +11,8 @@ MySQLPDOTest::skip(); true, - PDO::MYSQL_ATTR_LOCAL_INFILE => true, + Pdo\Mysql::ATTR_FOUND_ROWS => true, + Pdo\Mysql::ATTR_LOCAL_INFILE => true, PDO::ATTR_PERSISTENT => true, ]; diff --git a/ext/pdo_mysql/tests/bug71145.phpt b/ext/pdo_mysql/tests/bug71145.phpt index 0c6f1a549dfb..b25207152666 100644 --- a/ext/pdo_mysql/tests/bug71145.phpt +++ b/ext/pdo_mysql/tests/bug71145.phpt @@ -13,7 +13,7 @@ require_once __DIR__ . '/inc/mysql_pdo_test.inc'; $attr = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; SET SESSION sql_mode=traditional', + Pdo\Mysql::ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; SET SESSION sql_mode=traditional', PDO::ATTR_STRINGIFY_FETCHES => true, ]; diff --git a/ext/pdo_mysql/tests/bug71569.phpt b/ext/pdo_mysql/tests/bug71569.phpt index fe50b669d845..975474dd5587 100644 --- a/ext/pdo_mysql/tests/bug71569.phpt +++ b/ext/pdo_mysql/tests/bug71569.phpt @@ -13,7 +13,7 @@ require_once __DIR__ . '/inc/mysql_pdo_test.inc'; try { new PDO(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_USER, PDO_MYSQL_TEST_PASS, [ - PDO::MYSQL_ATTR_INIT_COMMAND => null, + Pdo\Mysql::ATTR_INIT_COMMAND => null, ]); } catch (PDOException $e) { echo $e->getMessage(); diff --git a/ext/pdo_mysql/tests/bug79375.phpt b/ext/pdo_mysql/tests/bug79375.phpt index fb118f1db2d5..07ccd183d45f 100644 --- a/ext/pdo_mysql/tests/bug79375.phpt +++ b/ext/pdo_mysql/tests/bug79375.phpt @@ -52,7 +52,7 @@ function testPrepareExecute(PDO $db, string $name) { } function testUnbuffered(PDO $db, string $name) { - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); $db->exec("SET innodb_lock_wait_timeout = 1"); $db->exec("START TRANSACTION"); $query = "SELECT first FROM test_79375 WHERE first = 1 FOR UPDATE"; diff --git a/ext/pdo_mysql/tests/bug80458.phpt b/ext/pdo_mysql/tests/bug80458.phpt index aecdca6674cc..a425c69658e1 100644 --- a/ext/pdo_mysql/tests/bug80458.phpt +++ b/ext/pdo_mysql/tests/bug80458.phpt @@ -97,7 +97,7 @@ var_dump($stmt5->fetchAll()); $db->exec("DROP PROCEDURE IF EXISTS {$procedure_ret}"); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); -$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); +$db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); $stmt = $db->prepare('DELETE FROM test_80458 WHERE first=15'); $stmt->execute(); diff --git a/ext/pdo_mysql/tests/bug80908.phpt b/ext/pdo_mysql/tests/bug80908.phpt index 52b7a40dbb3c..c00c196d9a66 100644 --- a/ext/pdo_mysql/tests/bug80908.phpt +++ b/ext/pdo_mysql/tests/bug80908.phpt @@ -23,7 +23,7 @@ $db->exec('CREATE TABLE test_80908 (`id` BIGINT(20) UNSIGNED AUTO_INCREMENT, `na function testLastInsertId(PDO $db) { echo "Running test lastInsertId\n"; - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); try { $db->exec("INSERT INTO test_80908 (`name`) VALUES ('bar')"); $id = $db->lastInsertId(); diff --git a/ext/pdo_mysql/tests/bug_42499.phpt b/ext/pdo_mysql/tests/bug_42499.phpt index 6f1534859a0c..b0c009259e00 100644 --- a/ext/pdo_mysql/tests/bug_42499.phpt +++ b/ext/pdo_mysql/tests/bug_42499.phpt @@ -28,13 +28,13 @@ function bug_42499($db) { print "Emulated Prepared Statements...\n"; $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1); -$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); +$db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 1); bug_42499($db); print "Native Prepared Statements...\n"; $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); -$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); +$db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 1); bug_42499($db); print "done!"; @@ -55,7 +55,7 @@ array(1) { } } -Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d +Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d Native Prepared Statements... array(1) { [0]=> @@ -65,5 +65,5 @@ array(1) { } } -Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d +Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d done! diff --git a/ext/pdo_mysql/tests/gh20122.phpt b/ext/pdo_mysql/tests/gh20122.phpt new file mode 100644 index 000000000000..f4abc266335a --- /dev/null +++ b/ext/pdo_mysql/tests/gh20122.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-20122 (getColumnMeta() for JSON-column in MySQL) +--EXTENSIONS-- +pdo +pdo_mysql +--SKIPIF-- + +--FILE-- +exec('CREATE TABLE test_gh20122 (bar JSON)'); +$db->exec('INSERT INTO test_gh20122 VALUES("[]")'); + +$stmt = $db->query('SELECT * from test_gh20122'); +$meta = $stmt->getColumnMeta(0); + +// Note: JSON is an alias for LONGTEXT on MariaDB! +echo $meta['native_type'], "\n"; +?> +--CLEAN-- +query('DROP TABLE IF EXISTS test_gh20122'); +?> +--EXPECTF-- +%r(JSON|LONGTEXT)%r diff --git a/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt b/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt index ba3054247c2b..910afceb27f0 100644 --- a/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql___construct_options.phpt @@ -44,11 +44,11 @@ MySQLPDOTest::skip(); PDO::ATTR_TIMEOUT => 'PDO::ATTR_TIMEOUT', PDO::ATTR_EMULATE_PREPARES => 'PDO::ATTR_EMULATE_PREPARES', - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => 'PDO::MYSQL_ATTR_USE_BUFFERED_QUERY', - PDO::MYSQL_ATTR_LOCAL_INFILE => 'PDO::MYSQL_ATTR_LOCAL_INFILE', - PDO::MYSQL_ATTR_DIRECT_QUERY => 'PDO::MYSQL_ATTR_DIRECT_QUERY', + Pdo\Mysql::ATTR_USE_BUFFERED_QUERY => 'Pdo\Mysql::ATTR_USE_BUFFERED_QUERY', + Pdo\Mysql::ATTR_LOCAL_INFILE => 'Pdo\Mysql::ATTR_LOCAL_INFILE', + Pdo\Mysql::ATTR_DIRECT_QUERY => 'Pdo\Mysql::ATTR_DIRECT_QUERY', - PDO::MYSQL_ATTR_INIT_COMMAND => 'PDO::MYSQL_ATTR_INIT_COMMAND', + Pdo\Mysql::ATTR_INIT_COMMAND => 'Pdo\Mysql::ATTR_INIT_COMMAND', PDO::ATTR_EMULATE_PREPARES => 'PDO::ATTR_EMULATE_PREPARES', ]; @@ -58,12 +58,12 @@ MySQLPDOTest::skip(); /* TODO - why is this a valid option if getAttribute() does not support it?! */ PDO::ATTR_TIMEOUT => false, PDO::ATTR_EMULATE_PREPARES => true, - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, + Pdo\Mysql::ATTR_USE_BUFFERED_QUERY => true, /* TODO getAttribute() does not handle it */ - PDO::MYSQL_ATTR_LOCAL_INFILE => false, + Pdo\Mysql::ATTR_LOCAL_INFILE => false, /* TODO getAttribute() does not handle it */ - PDO::MYSQL_ATTR_DIRECT_QUERY => true, - PDO::MYSQL_ATTR_INIT_COMMAND => '', + Pdo\Mysql::ATTR_DIRECT_QUERY => true, + Pdo\Mysql::ATTR_INIT_COMMAND => '', ]; try { @@ -73,7 +73,7 @@ MySQLPDOTest::skip(); } if (!is_object($db = new PDO($dsn, $user, $pass, array()))) - printf("[002] Expecting object got %s/%s¸\n", gettype($db), $db); + printf("[002] Expecting object got %s/%s\n", gettype($db), $db); $invalid = 999; if (is_object($db = new PDO($dsn, $user, $pass, array($invalid => true)))) @@ -108,56 +108,56 @@ MySQLPDOTest::skip(); if (!is_object($db = new PDO($dsn, $user, $pass, array(PDO::ATTR_TIMEOUT => -PHP_INT_MAX)))) printf("[008] ATTR_TIMEOUT should be accepted\n"); - /* TODO: Its ugly that PDO::ATTR_EMULATE_PREPARES == PDO::MYSQL_ATTR_DIRECT_QUERY */ + /* TODO: Its ugly that PDO::ATTR_EMULATE_PREPARES == Pdo\Mysql::ATTR_DIRECT_QUERY */ $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => true)); if (!is_object($db)) printf("[009] ATTR_EMULATE_PREPARES should be accepted and on\n"); if (!$db->getAttribute(PDO::ATTR_EMULATE_PREPARES)) printf("[010] [TODO][CHANGEREQUEST] ATTR_EMULATE_PREPARES should be on\n"); - if (!$db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) - printf("[011] As PDO::MYSQL_ATTR_DIRECT_QUERY == PDO::ATTR_EMULATE_PREPARES - and PDO::ATTR_EMULATE_PREPARES overrules the other, PDO::MYSQL_ATTR_DIRECT_QUERY should be on\n"); + if (!$db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) + printf("[011] As Pdo\Mysql::ATTR_DIRECT_QUERY == PDO::ATTR_EMULATE_PREPARES + and PDO::ATTR_EMULATE_PREPARES overrules the other, Pdo\Mysql::ATTR_DIRECT_QUERY should be on\n"); $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => false)); if (!is_object($db)) printf("[012] ATTR_EMULATE_PREPARES should be accepted and on\n"); if ($db->getAttribute(PDO::ATTR_EMULATE_PREPARES)) printf("[013] [TODO][CHANGEREQUEST] ATTR_EMULATE_PREPARES should be off\n"); - if ($db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) - printf("[014] As PDO::MYSQL_ATTR_DIRECT_QUERY == PDO::ATTR_EMULATE_PREPARES - and PDO::ATTR_EMULATE_PREPARES overrules the other, PDO::MYSQL_ATTR_DIRECT_QUERY should be off\n"); + if ($db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) + printf("[014] As Pdo\Mysql::ATTR_DIRECT_QUERY == PDO::ATTR_EMULATE_PREPARES + and PDO::ATTR_EMULATE_PREPARES overrules the other, Pdo\Mysql::ATTR_DIRECT_QUERY should be off\n"); - // PDO::ATTR_EMULATE_PREPARES overrules PDO::MYSQL_ATTR_DIRECT_QUERY + // PDO::ATTR_EMULATE_PREPARES overrules Pdo\Mysql::ATTR_DIRECT_QUERY // TODO: is it clever that a generic setting overrules a specific setting? - $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => true, PDO::MYSQL_ATTR_DIRECT_QUERY => false)); + $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => true, Pdo\Mysql::ATTR_DIRECT_QUERY => false)); if (!$db->getAttribute(PDO::ATTR_EMULATE_PREPARES)) printf("[015] PDO::ATTR_EMULATE_PREPARES should be on\n"); - if (!$db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) - printf("[016] PDO::MYSQL_ATTR_DIRECT_QUERY should be on\n"); + if (!$db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) + printf("[016] Pdo\Mysql::ATTR_DIRECT_QUERY should be on\n"); - $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_DIRECT_QUERY => true)); + $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_EMULATE_PREPARES => false, Pdo\Mysql::ATTR_DIRECT_QUERY => true)); if ($db->getAttribute(PDO::ATTR_EMULATE_PREPARES)) printf("[017] PDO::ATTR_EMULATE_PREPARES should be off\n"); - if ($db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) - printf("[018] PDO::MYSQL_ATTR_DIRECT_QUERY should be off\n"); + if ($db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) + printf("[018] Pdo\Mysql::ATTR_DIRECT_QUERY should be off\n"); - set_option_and_check(19, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true, 'PDO::MYSQL_ATTR_USE_BUFFERED_QUERY'); - set_option_and_check(20, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false, 'PDO::MYSQL_ATTR_USE_BUFFERED_QUERY'); + set_option_and_check(19, Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true, 'Pdo\Mysql::ATTR_USE_BUFFERED_QUERY'); + set_option_and_check(20, Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false, 'Pdo\Mysql::ATTR_USE_BUFFERED_QUERY'); - set_option_and_check(21, PDO::MYSQL_ATTR_LOCAL_INFILE, true, 'PDO::MYSQL_ATTR_LOCAL_INFILE'); - set_option_and_check(22, PDO::MYSQL_ATTR_LOCAL_INFILE, false, 'PDO::MYSQL_ATTR_LOCAL_INFILE'); + set_option_and_check(21, Pdo\Mysql::ATTR_LOCAL_INFILE, true, 'Pdo\Mysql::ATTR_LOCAL_INFILE'); + set_option_and_check(22, Pdo\Mysql::ATTR_LOCAL_INFILE, false, 'Pdo\Mysql::ATTR_LOCAL_INFILE'); - set_option_and_check(23, PDO::MYSQL_ATTR_INIT_COMMAND, 'SET @a=1', 'PDO::MYSQL_ATTR_INIT_COMMAND'); - set_option_and_check(24, PDO::MYSQL_ATTR_INIT_COMMAND, '', 'PDO::MYSQL_ATTR_INIT_COMMAND'); - set_option_and_check(25, PDO::MYSQL_ATTR_INIT_COMMAND, 'INSERT INTO nonexistent(invalid) VALUES (1)', 'PDO::MYSQL_ATTR_INIT_COMMAND'); + set_option_and_check(23, Pdo\Mysql::ATTR_INIT_COMMAND, 'SET @a=1', 'Pdo\Mysql::ATTR_INIT_COMMAND'); + set_option_and_check(24, Pdo\Mysql::ATTR_INIT_COMMAND, '', 'Pdo\Mysql::ATTR_INIT_COMMAND'); + set_option_and_check(25, Pdo\Mysql::ATTR_INIT_COMMAND, 'INSERT INTO nonexistent(invalid) VALUES (1)', 'Pdo\Mysql::ATTR_INIT_COMMAND'); - set_option_and_check(33, PDO::MYSQL_ATTR_DIRECT_QUERY, true, 'PDO::MYSQL_ATTR_DIRECT_QUERY'); - set_option_and_check(34, PDO::MYSQL_ATTR_DIRECT_QUERY, false, 'PDO::MYSQL_ATTR_DIRECT_QUERY'); + set_option_and_check(33, Pdo\Mysql::ATTR_DIRECT_QUERY, true, 'Pdo\Mysql::ATTR_DIRECT_QUERY'); + set_option_and_check(34, Pdo\Mysql::ATTR_DIRECT_QUERY, false, 'Pdo\Mysql::ATTR_DIRECT_QUERY'); - if (defined('PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY')) { - set_option_and_check(35, PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY, null, 'PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY'); + if (defined('Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY')) { + set_option_and_check(35, Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY, null, 'Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY'); // libmysqlclient returns the directory with a trailing slash. - // set_option_and_check(36, PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY, __DIR__, 'PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY'); + // set_option_and_check(36, Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY, __DIR__, 'Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY'); } } catch (PDOException $e) { printf("[001] %s, [%s] %s Line: %s\n", @@ -171,12 +171,12 @@ MySQLPDOTest::skip(); ?> --EXPECTF-- [003] [TODO][CHANGEREQUEST] Please, lets not ignore invalid options and bail out! -[003a] Expecting default value for 'PDO::MYSQL_ATTR_INIT_COMMAND' of ''/string, getAttribute() reports setting ''/boolean +[003a] Expecting default value for 'Pdo\Mysql::ATTR_INIT_COMMAND' of ''/string, getAttribute() reports setting ''/boolean [015] PDO::ATTR_EMULATE_PREPARES should be on -[016] PDO::MYSQL_ATTR_DIRECT_QUERY should be on +[016] Pdo\Mysql::ATTR_DIRECT_QUERY should be on [017] PDO::ATTR_EMULATE_PREPARES should be off -[018] PDO::MYSQL_ATTR_DIRECT_QUERY should be off -[023] Expecting 'SET @a=1'/string got ''/boolean' for options 'PDO::MYSQL_ATTR_INIT_COMMAND' +[018] Pdo\Mysql::ATTR_DIRECT_QUERY should be off +[023] Expecting 'SET @a=1'/string got ''/boolean' for options 'Pdo\Mysql::ATTR_INIT_COMMAND' [024] SQLSTATE[42000] [1065] Query was empty [025] SQLSTATE[42S02] [1146] Table '%s.nonexistent' doesn't exist done! diff --git a/ext/pdo_mysql/tests/pdo_mysql___construct_options_libmysql.phpt b/ext/pdo_mysql/tests/pdo_mysql___construct_options_libmysql.phpt index e3d8ee2db658..c56ee9e5d1e9 100644 --- a/ext/pdo_mysql/tests/pdo_mysql___construct_options_libmysql.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql___construct_options_libmysql.phpt @@ -36,16 +36,16 @@ if (MySQLPDOTest::isPDOMySQLnd()) $pass = PDO_MYSQL_TEST_PASS; $valid_options = []; - $valid_options[PDO::MYSQL_ATTR_MAX_BUFFER_SIZE] = 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE'; - $valid_options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'PDO::MYSQL_ATTR_INIT_COMMAND'; - $valid_options[PDO::MYSQL_ATTR_READ_DEFAULT_FILE] = 'PDO::MYSQL_ATTR_READ_DEFAULT_FILE'; - $valid_options[PDO::MYSQL_ATTR_READ_DEFAULT_GROUP] = 'PDO::MYSQL_ATTR_READ_DEFAULT_GROUP'; + $valid_options[Pdo\Mysql::ATTR_MAX_BUFFER_SIZE] = 'Pdo\Mysql::ATTR_MAX_BUFFER_SIZE'; + $valid_options[Pdo\Mysql::ATTR_INIT_COMMAND] = 'Pdo\Mysql::ATTR_INIT_COMMAND'; + $valid_options[Pdo\Mysql::ATTR_READ_DEFAULT_FILE] = 'Pdo\Mysql::ATTR_READ_DEFAULT_FILE'; + $valid_options[Pdo\Mysql::ATTR_READ_DEFAULT_GROUP] = 'Pdo\Mysql::ATTR_READ_DEFAULT_GROUP'; - $defaults[PDO::MYSQL_ATTR_MAX_BUFFER_SIZE] = 1048576; + $defaults[Pdo\Mysql::ATTR_MAX_BUFFER_SIZE] = 1048576; /* TODO getAttribute() does not handle it */ - $defaults[PDO::MYSQL_ATTR_INIT_COMMAND] = ''; - $defaults[PDO::MYSQL_ATTR_READ_DEFAULT_FILE] = false; - $defaults[PDO::MYSQL_ATTR_READ_DEFAULT_GROUP] = false; + $defaults[Pdo\Mysql::ATTR_INIT_COMMAND] = ''; + $defaults[Pdo\Mysql::ATTR_READ_DEFAULT_FILE] = false; + $defaults[Pdo\Mysql::ATTR_READ_DEFAULT_GROUP] = false; $db = new PDO($dsn, $user, $pass); foreach ($valid_options as $option => $name) { @@ -60,19 +60,19 @@ if (MySQLPDOTest::isPDOMySQLnd()) } } - set_option_and_check(26, PDO::MYSQL_ATTR_READ_DEFAULT_FILE, true, 'PDO::MYSQL_ATTR_READ_DEFAULT_FILE'); - set_option_and_check(27, PDO::MYSQL_ATTR_READ_DEFAULT_FILE, false, 'PDO::MYSQL_ATTR_READ_DEFAULT_FILE'); + set_option_and_check(26, Pdo\Mysql::ATTR_READ_DEFAULT_FILE, true, 'Pdo\Mysql::ATTR_READ_DEFAULT_FILE'); + set_option_and_check(27, Pdo\Mysql::ATTR_READ_DEFAULT_FILE, false, 'Pdo\Mysql::ATTR_READ_DEFAULT_FILE'); - set_option_and_check(30, PDO::MYSQL_ATTR_MAX_BUFFER_SIZE, -1, 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE', true); - set_option_and_check(31, PDO::MYSQL_ATTR_MAX_BUFFER_SIZE, PHP_INT_MAX, 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE'); - set_option_and_check(32, PDO::MYSQL_ATTR_MAX_BUFFER_SIZE, 1, 'PDO::MYSQL_ATTR_MAX_BUFFER_SIZE'); + set_option_and_check(30, Pdo\Mysql::ATTR_MAX_BUFFER_SIZE, -1, 'Pdo\Mysql::ATTR_MAX_BUFFER_SIZE', true); + set_option_and_check(31, Pdo\Mysql::ATTR_MAX_BUFFER_SIZE, PHP_INT_MAX, 'Pdo\Mysql::ATTR_MAX_BUFFER_SIZE'); + set_option_and_check(32, Pdo\Mysql::ATTR_MAX_BUFFER_SIZE, 1, 'Pdo\Mysql::ATTR_MAX_BUFFER_SIZE'); print "done!\n"; ?> --EXPECT-- -Failed to getAttribute() for PDO::MYSQL_ATTR_INIT_COMMAND -Failed to getAttribute() for PDO::MYSQL_ATTR_READ_DEFAULT_FILE -Failed to getAttribute() for PDO::MYSQL_ATTR_READ_DEFAULT_GROUP -Failed to getAttribute() for PDO::MYSQL_ATTR_READ_DEFAULT_FILE -Failed to getAttribute() for PDO::MYSQL_ATTR_READ_DEFAULT_FILE +Failed to getAttribute() for Pdo\Mysql::ATTR_INIT_COMMAND +Failed to getAttribute() for Pdo\Mysql::ATTR_READ_DEFAULT_FILE +Failed to getAttribute() for Pdo\Mysql::ATTR_READ_DEFAULT_GROUP +Failed to getAttribute() for Pdo\Mysql::ATTR_READ_DEFAULT_FILE +Failed to getAttribute() for Pdo\Mysql::ATTR_READ_DEFAULT_FILE done! diff --git a/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt b/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt index ec6bce78b7c4..d86f9b3d8773 100644 --- a/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql___construct_uri.phpt @@ -63,5 +63,8 @@ MySQLPDOTest::skip(); print "done!"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs in %s on line %d + +Deprecated: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs in %s on line %d done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt index 94db61e00ded..b9562247af86 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO::MYSQL_ATTR_INIT_COMMAND +Pdo\Mysql::ATTR_INIT_COMMAND --EXTENSIONS-- pdo_mysql --SKIPIF-- @@ -22,7 +22,7 @@ error_reporting=E_ALL $create = sprintf('CREATE TABLE %s(id INT)', $table); var_dump($create); - $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => $create)); + $db = new PDO($dsn, $user, $pass, array(Pdo\Mysql::ATTR_INIT_COMMAND => $create)); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $info = $db->errorInfo(); diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_max_buffer_size.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_max_buffer_size.phpt index 293eb71ca0a0..00a0eb0edc10 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_max_buffer_size.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_max_buffer_size.phpt @@ -1,5 +1,5 @@ --TEST-- -MySQL PDO->__construct(), PDO::MYSQL_ATTR_MAX_BUFFER_SIZE +MySQL PDO->__construct(), Pdo\Mysql::ATTR_MAX_BUFFER_SIZE --EXTENSIONS-- pdo_mysql --SKIPIF-- @@ -7,7 +7,7 @@ pdo_mysql require_once __DIR__ . '/inc/mysql_pdo_test.inc'; MySQLPDOTest::skip(); if (MySQLPDOTest::isPDOMySQLnd()) - die("skip PDO::MYSQL_ATTR_MAX_BUFFER_SIZE not supported with mysqlnd"); + die("skip Pdo\Mysql::ATTR_MAX_BUFFER_SIZE not supported with mysqlnd"); ?> --FILE-- $buffer_size, + Pdo\Mysql::ATTR_MAX_BUFFER_SIZE => $buffer_size, /* buffer is only relevant with native PS */ - PDO::MYSQL_ATTR_DIRECT_QUERY => 0, + Pdo\Mysql::ATTR_DIRECT_QUERY => 0, PDO::ATTR_EMULATE_PREPARES => 0, ]); diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt index 7d0256500f55..16f19da7d1b0 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO::MYSQL_ATTR_MULTI_STATEMENTS +Pdo\Mysql::ATTR_MULTI_STATEMENTS --EXTENSIONS-- pdo_mysql --SKIPIF-- @@ -37,7 +37,7 @@ error_reporting=E_ALL var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); // New connection, does not allow multiple statements. - $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_MULTI_STATEMENTS => false)); + $db = new PDO($dsn, $user, $pass, array(Pdo\Mysql::ATTR_MULTI_STATEMENTS => false)); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $stmt = $db->query(sprintf('SELECT * FROM %s; INSERT INTO %s(id) VALUES (3)', $table, $table)); diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt index f308f3384f85..d116aa701a14 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt @@ -47,7 +47,7 @@ MySQLPDOTest::skip(); $have_procedures = false; $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); if ($have_procedures && (false !== $db->exec("DROP PROCEDURE IF EXISTS {$procedure}")) && (false !== $db->exec("CREATE PROCEDURE {$procedure}() BEGIN SELECT NULL as z, '' AS a, ' ' AS b, TRIM(' ') as c, ' d' AS d, ' e' AS e; END;"))) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_exec_load_data.phpt b/ext/pdo_mysql/tests/pdo_mysql_exec_load_data.phpt index 9876ae0759f3..066843fa71f6 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_exec_load_data.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_exec_load_data.phpt @@ -55,7 +55,7 @@ function exec_and_count($offset, &$db, $sql, $exp) { } require_once __DIR__ . '/inc/mysql_pdo_test.inc'; -$db = MySQLPDOTest::factoryWithAttr([PDO::MYSQL_ATTR_LOCAL_INFILE=>true]); +$db = MySQLPDOTest::factoryWithAttr([Pdo\Mysql::ATTR_LOCAL_INFILE=>true]); /* affected rows related */ diff --git a/ext/pdo_mysql/tests/pdo_mysql_exec_select.phpt b/ext/pdo_mysql/tests/pdo_mysql_exec_select.phpt index fe1550776dc5..fc52a20f2172 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_exec_select.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_exec_select.phpt @@ -38,7 +38,7 @@ MySQLPDOTest::skip(); exec_and_count(4, $db, "INSERT INTO test_mysql_exec_select(id, col1) VALUES (1, 'a')", 1); // question is: will the result set be cleaned up, will it be possible to run more queries on the line? // buffered or unbuffered does not matter! - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); exec_and_count(5, $db, 'SELECT id FROM test_mysql_exec_select', 0); exec_and_count(6, $db, "INSERT INTO test_mysql_exec_select(id, col1) VALUES (2, 'b')", 1); @@ -57,6 +57,6 @@ $db = MySQLPDOTest::factory(); $db->query('DROP TABLE IF EXISTS test_mysql_exec_select'); ?> --EXPECTF-- -Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d -[006] Expecting '1'/integer got ''/boolean when running 'INSERT INTO test_mysql_exec_select(id, col1) VALUES (2, 'b')', [HY000] HY000 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. +Warning: PDO::exec(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d +[006] Expecting '1'/integer got ''/boolean when running 'INSERT INTO test_mysql_exec_select(id, col1) VALUES (2, 'b')', [HY000] HY000 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_get_attribute.phpt b/ext/pdo_mysql/tests/pdo_mysql_get_attribute.phpt index 6e83be8e1a8f..ba4aeb7051ef 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_get_attribute.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_get_attribute.phpt @@ -50,27 +50,27 @@ MySQLPDOTest::skipNotTransactionalEngine(); $obj = new stdClass(); set_and_get(4, $db, PDO::ATTR_AUTOCOMMIT, $obj); - set_and_get(5, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, 1); - set_and_get(6, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, 0); - set_and_get(7, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, -1); + set_and_get(5, $db, Pdo\Mysql::ATTR_LOCAL_INFILE, 1); + set_and_get(6, $db, Pdo\Mysql::ATTR_LOCAL_INFILE, 0); + set_and_get(7, $db, Pdo\Mysql::ATTR_LOCAL_INFILE, -1); $tmp = array(); - set_and_get(8, $db, PDO::MYSQL_ATTR_LOCAL_INFILE, $tmp); + set_and_get(8, $db, Pdo\Mysql::ATTR_LOCAL_INFILE, $tmp); - set_and_get(9, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, ''); - set_and_get(10, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, 'SOME SQL'); - set_and_get(11, $db, PPDO::MYSQL_ATTR_INIT_COMMAND, -1); + set_and_get(9, $db, PPdo\Mysql::ATTR_INIT_COMMAND, ''); + set_and_get(10, $db, PPdo\Mysql::ATTR_INIT_COMMAND, 'SOME SQL'); + set_and_get(11, $db, PPdo\Mysql::ATTR_INIT_COMMAND, -1); */ /* - PDO::MYSQL_ATTR_READ_DEFAULT_FILE (integer) + Pdo\Mysql::ATTR_READ_DEFAULT_FILE (integer) Read options from the named option file instead of from my.cnf. - PDO::MYSQL_ATTR_READ_DEFAULT_GROUP (integer) + Pdo\Mysql::ATTR_READ_DEFAULT_GROUP (integer) Read options from the named group from my.cnf or the file specified with MYSQL_READ_DEFAULT_FILE. - PDO::MYSQL_ATTR_MAX_BUFFER_SIZE (integer) + Pdo\Mysql::ATTR_MAX_BUFFER_SIZE (integer) Maximum buffer size. Defaults to 1 MiB. - PDO::MYSQL_ATTR_DIRECT_QUERY (integer) + Pdo\Mysql::ATTR_DIRECT_QUERY (integer) Perform direct queries, don't use prepared statements. */ diff --git a/ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt b/ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt index 91a67260f039..af065bd7d907 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_local_infile_default_off.phpt @@ -6,7 +6,7 @@ pdo_mysql @@ -19,8 +19,8 @@ $user = PDO_MYSQL_TEST_USER; $pass = PDO_MYSQL_TEST_PASS; $db = new PDO($dsn, $user, $pass); -echo var_export($db->getAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE)), "\n"; -echo var_export($db->getAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY)), "\n"; +echo var_export($db->getAttribute(Pdo\Mysql::ATTR_LOCAL_INFILE)), "\n"; +echo var_export($db->getAttribute(Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY)), "\n"; echo "done!\n"; ?> --EXPECT-- diff --git a/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_allowed.phpt b/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_allowed.phpt index 2b7f4673ddaf..7c910e2ba80c 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_allowed.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_allowed.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY vs access allowed +Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY vs access allowed --EXTENSIONS-- pdo_mysql --SKIPIF-- @@ -7,7 +7,7 @@ pdo_mysql require_once __DIR__ . '/inc/mysql_pdo_test.inc'; MySQLPDOTest::skip(); MySQLPDOTest::skipInfileNotAllowed(); -if (!defined('PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY')) { +if (!defined('Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY')) { die("skip No MYSQL_ATTR_LOCAL_INFILE_DIRECTORY support"); } ?> @@ -33,8 +33,8 @@ if (!defined('PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY')) { require_once __DIR__ . '/inc/mysql_pdo_test.inc'; $db = MySQLPDOTest::factoryWithAttr([ - PDO::MYSQL_ATTR_LOCAL_INFILE=>false, - PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY=>__DIR__."/foo", + Pdo\Mysql::ATTR_LOCAL_INFILE=>false, + Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY=>__DIR__."/foo", ]); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_denied.phpt b/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_denied.phpt index ccf2abd4a86d..58bac57748ea 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_denied.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_local_infile_directory_denied.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY vs access denied +Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY vs access denied --EXTENSIONS-- pdo_mysql --SKIPIF-- @@ -7,7 +7,7 @@ pdo_mysql require_once __DIR__ . '/inc/mysql_pdo_test.inc'; MySQLPDOTest::skip(); MySQLPDOTest::skipInfileNotAllowed(); -if (!defined('PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY')) { +if (!defined('Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY')) { die("skip No MYSQL_ATTR_LOCAL_INFILE_DIRECTORY support"); } ?> @@ -33,8 +33,8 @@ if (!defined('PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY')) { require_once __DIR__ . '/inc/mysql_pdo_test.inc'; $db = MySQLPDOTest::factoryWithAttr([ - PDO::MYSQL_ATTR_LOCAL_INFILE=>false, - PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY=>__DIR__."/foo/bar", + Pdo\Mysql::ATTR_LOCAL_INFILE=>false, + Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY=>__DIR__."/foo/bar", ]); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_local_infile_overrides_local_infile_directory.phpt b/ext/pdo_mysql/tests/pdo_mysql_local_infile_overrides_local_infile_directory.phpt index b99375c37b6e..d454694ef2c3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_local_infile_overrides_local_infile_directory.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_local_infile_overrides_local_infile_directory.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO::MYSQL_ATTR_LOCAL_INFILE overrides PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY +Pdo\Mysql::ATTR_LOCAL_INFILE overrides Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY --EXTENSIONS-- pdo_mysql --SKIPIF-- @@ -7,7 +7,7 @@ pdo_mysql require_once __DIR__ . '/inc/mysql_pdo_test.inc'; MySQLPDOTest::skip(); MySQLPDOTest::skipInfileNotAllowed(); -if (!defined('PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY')) { +if (!defined('Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY')) { die("skip No MYSQL_ATTR_LOCAL_INFILE_DIRECTORY support"); } ?> @@ -33,8 +33,8 @@ if (!defined('PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY')) { require_once __DIR__ . '/inc/mysql_pdo_test.inc'; $db = MySQLPDOTest::factoryWithAttr([ - PDO::MYSQL_ATTR_LOCAL_INFILE=>true, - PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY=>__DIR__."/foo/bar", + Pdo\Mysql::ATTR_LOCAL_INFILE=>true, + Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY=>__DIR__."/foo/bar", ]); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt b/ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt index cbdbc063dd8a..e5176b44f158 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_local_infile_set_on.phpt @@ -15,8 +15,8 @@ $dsn = MySQLPDOTest::getDSN(); $user = PDO_MYSQL_TEST_USER; $pass = PDO_MYSQL_TEST_PASS; -$db = new PDO($dsn, $user, $pass, [PDO::MYSQL_ATTR_LOCAL_INFILE => true]); -echo var_export($db->getAttribute(PDO::MYSQL_ATTR_LOCAL_INFILE)), "\n"; +$db = new PDO($dsn, $user, $pass, [Pdo\Mysql::ATTR_LOCAL_INFILE => true]); +echo var_export($db->getAttribute(Pdo\Mysql::ATTR_LOCAL_INFILE)), "\n"; echo "done!\n"; ?> --EXPECT-- diff --git a/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt b/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt index b699dbdaa571..75abb0ca39d5 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt @@ -1,5 +1,5 @@ --TEST-- -MySQL PDOStatement->nextRowSet() with PDO::MYSQL_ATTR_MULTI_STATEMENTS either true or false +MySQL PDOStatement->nextRowSet() with Pdo\Mysql::ATTR_MULTI_STATEMENTS either true or false --EXTENSIONS-- pdo_mysql --SKIPIF-- @@ -35,21 +35,21 @@ MySQLPDOTest::skip(); printf("Native PS...\n"); foreach (array(false, true) as $multi) { $value = $multi ? 'true' : 'false'; - echo "\nTesting with PDO::MYSQL_ATTR_MULTI_STATEMENTS set to {$value}\n"; + echo "\nTesting with Pdo\Mysql::ATTR_MULTI_STATEMENTS set to {$value}\n"; $dsn = MySQLPDOTest::getDSN(); $user = PDO_MYSQL_TEST_USER; $pass = PDO_MYSQL_TEST_PASS; - $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_MULTI_STATEMENTS => $multi)); + $db = new PDO($dsn, $user, $pass, array(Pdo\Mysql::ATTR_MULTI_STATEMENTS => $multi)); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 1); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); test_proc($db); - $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_MULTI_STATEMENTS => $multi)); + $db = new PDO($dsn, $user, $pass, array(Pdo\Mysql::ATTR_MULTI_STATEMENTS => $multi)); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 0); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 0); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); test_proc($db); @@ -81,7 +81,7 @@ $db->exec('DROP PROCEDURE IF EXISTS pdo_mysql_multi_stmt_nextrowset_p'); --EXPECTF-- Native PS... -Testing with PDO::MYSQL_ATTR_MULTI_STATEMENTS set to false +Testing with Pdo\Mysql::ATTR_MULTI_STATEMENTS set to false array(3) { [0]=> array(1) { @@ -172,7 +172,7 @@ bool(false) Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'INSERT INTO pdo_mysql_multi_stmt_nextrowset (id, label) VALUES (99, 'x')' at line 1 in %s on line %d string(5) "42000" -Testing with PDO::MYSQL_ATTR_MULTI_STATEMENTS set to true +Testing with Pdo\Mysql::ATTR_MULTI_STATEMENTS set to true array(3) { [0]=> array(1) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt index 29074fb5505f..e8ff3781b350 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt @@ -82,8 +82,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to switch to emulated prepared statements, test will fail\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous.phpt index f16f9078758f..f8196bcd61ad 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous.phpt @@ -13,8 +13,8 @@ MySQLPDOTest::skip(); $db = MySQLPDOTest::factory(); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to switch to emulated prepared statements, test will fail\n"); $db->exec(sprintf('CREATE TABLE test_prepare_emulated_anonymous(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE)); @@ -33,8 +33,8 @@ MySQLPDOTest::skip(); // now the same with native PS printf("now the same with native PS\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to switch off emulated prepared statements, test will fail\n"); $db->exec('DELETE FROM test_prepare_emulated_anonymous'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt index ac4f85949bb1..409d9b1f86c0 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_anonymous_placeholders.phpt @@ -83,8 +83,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to switch to emulated prepared statements, test will fail\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt index 8406be4db6d7..fdc82d5ab34b 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam.phpt @@ -82,8 +82,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to switch to emulated prepared statements, test will fail\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt index 1acc055e12a0..a94014a183a5 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_myisam_index.phpt @@ -85,8 +85,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to switch to emulated prepared statements, test will fail\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_placeholder_everywhere.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_placeholder_everywhere.phpt index 92f14a5b2e9b..3b356cad3dfc 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_placeholder_everywhere.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_placeholder_everywhere.phpt @@ -15,8 +15,8 @@ MySQLPDOTest::skip(); try { // native PS - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to switch off emulated prepared statements, test will fail\n"); $db->exec(sprintf('CREATE TABLE test_prepare_emulated_placeholder_everywhere(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE)); @@ -35,8 +35,8 @@ MySQLPDOTest::skip(); // now the same with emulated PS printf("now the same with emulated PS\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to switch on emulated prepared statements, test will fail\n"); $stmt = $db->prepare('SELECT ? FROM test_prepare_emulated_placeholder_everywhere WHERE ? > ?'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt index 02690d4164c6..7db84207f19c 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native.phpt @@ -91,8 +91,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt index db7844b1e6fb..2ac60de4ae62 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_anonymous_placeholder.phpt @@ -91,8 +91,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt index 5d40bc826233..68cfa4203cfe 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt @@ -17,8 +17,8 @@ MySQLPDOTest::skip(); $db->exec(sprintf('CREATE TABLE test_prepare_native_clear_error(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE)); // We need to run the emulated version first. Native version will cause a fatal error - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); // INSERT a single row @@ -40,8 +40,8 @@ MySQLPDOTest::skip(); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); // Native PS - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[005] Unable to turn off emulated prepared statements\n"); $stmt = $db->prepare('SELECT unknown_column FROM test_prepare_native_clear_error WHERE id > :placeholder ORDER BY id ASC'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_column.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_column.phpt index 5786b009500a..ec63d4a4b750 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_column.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_column.phpt @@ -15,8 +15,8 @@ MySQLPDOTest::skip(); $table = 'pdo_mysql_prepare_native_column'; MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); $stmt = $db->prepare("SELECT :param FROM {$table} ORDER BY id ASC LIMIT 1"); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt index 21bbe8728ed8..ef38604c449b 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt @@ -16,8 +16,8 @@ MySQLPDOTest::skip(); try { $db->exec(sprintf('CREATE TABLE test_prepare_native_dup_named(id INT, label1 CHAR(255), label2 CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE)); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); printf("Native...\n"); @@ -36,8 +36,8 @@ MySQLPDOTest::skip(); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); // Now the same with emulated PS. - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to turn on emulated prepared statements\n"); printf("Emulated...\n"); @@ -72,8 +72,8 @@ MySQLPDOTest::skip(); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); // native... - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[007] Unable to turn off emulated prepared statements\n"); printf("Native...\n"); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_mixed_style.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_mixed_style.phpt index 9e5607fa4cef..adca8ecfc233 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_mixed_style.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_mixed_style.phpt @@ -15,8 +15,8 @@ MySQLPDOTest::skip(); $table = 'pdo_mysql_prepare_native_mixed_style'; MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); $stmt = $db->query("DELETE FROM {$table}"); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt index c8ede104016a..c4a4f7c6f383 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam.phpt @@ -91,8 +91,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt index f1547281438e..e84dd18b957c 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_myisam_index.phpt @@ -91,8 +91,8 @@ MySQLPDOTest::skip(); } try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_named_placeholder.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_named_placeholder.phpt index 2e23def16334..93bedbe9de74 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_named_placeholder.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_named_placeholder.phpt @@ -16,8 +16,8 @@ MySQLPDOTest::skip(); $db->exec(sprintf('CREATE TABLE test_prepare_native_named_placeholder(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE)); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); // INSERT a single row @@ -39,8 +39,8 @@ MySQLPDOTest::skip(); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); // Now the same with emulated PS. - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to turn on emulated prepared statements\n"); // Note that the "named placeholder" is enclosed by double quotes. diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt index 575af4a8f2c8..4afccdc9e298 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt @@ -14,8 +14,8 @@ MySQLPDOTest::skip(); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to switch on emulated prepared statements, test will fail\n"); $db->exec(sprintf('CREATE TABLE test_prepare_native_named_placeholder_everywhere(id INT, label CHAR(255)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE)); @@ -31,8 +31,8 @@ MySQLPDOTest::skip(); // now the same with native PS printf("now the same with native PS\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to switch off emulated prepared statements, test_prepare_native_named_placeholder_everywhere will fail\n"); $stmt = $db->prepare('SELECT ?, id, label FROM test_prepare_native_named_placeholder_everywhere WHERE ? = ? ORDER BY id ASC'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindcolumn.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindcolumn.phpt index cce3dc9393a3..8f144b611df7 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindcolumn.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindcolumn.phpt @@ -16,8 +16,8 @@ MySQLPDOTest::skip(); MySQLPDOTest::createTestTable($table, $db); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); $stmt = $db->prepare("SELECT id, label FROM {$table} ORDER BY id ASC LIMIT 2"); @@ -56,8 +56,8 @@ MySQLPDOTest::skip(); $index++; } - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[007] Unable to turn off emulated prepared statements\n"); $stmt = $db->prepare("SELECT id, label FROM {$table} ORDER BY id ASC LIMIT 2, 2"); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam.phpt index b0bbad59d8e9..92e6f446e1b3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam.phpt @@ -84,32 +84,32 @@ MySQLPDOTest::skip(); try { printf("Emulated PS...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); printf("Buffered...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); pdo_mysql_stmt_bindparam($db, 3); printf("Unbuffered...\n"); MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); pdo_mysql_stmt_bindparam($db, 4); printf("Native PS...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to turn off emulated prepared statements\n"); printf("Buffered...\n"); MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); pdo_mysql_stmt_bindparam($db, 5); printf("Unbuffered...\n"); MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); pdo_mysql_stmt_bindparam($db, 6); } catch (PDOException $e) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam_types.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam_types.phpt index b315c97b9120..fde08dfa6932 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam_types.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindparam_types.phpt @@ -14,9 +14,9 @@ MySQLPDOTest::skip(); function pdo_mysql_stmt_bindparam_types_do($db, $offset, $native, $sql_type, $value) { if ($native) - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); else - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); $sql = sprintf('CREATE TABLE test_stmt_bindparam_types(id INT, label %s) ENGINE=%s', $sql_type, MySQLPDOTest::getTableEngine()); if ((!$stmt = $db->prepare($sql)) || (!$stmt->execute())) diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindvalue.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindvalue.phpt index c558eb6f81da..7d214e0c7e23 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_bindvalue.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_bindvalue.phpt @@ -17,8 +17,8 @@ MySQLPDOTest::skip(); printf("Testing native PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); printf("Binding variable...\n"); @@ -157,8 +157,8 @@ MySQLPDOTest::skip(); printf("Testing emulated PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); printf("Binding variable...\n"); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor.phpt index af052a02423f..65dfbb660bc3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor.phpt @@ -21,7 +21,7 @@ MySQLPDOTest::skip(); // This one should fail. I let it fail to prove that closeCursor() makes a difference. // If no error messages gets printed do not know if proper usage of closeCursor() makes any // difference or not. That's why we need to cause an error here. - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); $stmt1 = $db->query("SELECT id, label FROM {$table} ORDER BY id ASC"); // query() shall fail! $stmt2 = $db->query("SELECT id, label FROM {$table} ORDER BY id ASC"); @@ -46,7 +46,7 @@ MySQLPDOTest::skip(); $stmt2->execute(); $stmt2->closeCursor(); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); // check if changing the fetch mode from unbuffered to buffered will // cause any harm to a statement created prior to the change $stmt1->execute(); @@ -110,33 +110,33 @@ MySQLPDOTest::skip(); try { printf("Testing emulated PS...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); printf("Buffered...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); MySQLPDOTest::createTestTable($table, $db); pdo_mysql_stmt_closecursor($db); printf("Unbuffered...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); MySQLPDOTest::createTestTable($table, $db); pdo_mysql_stmt_closecursor($db); printf("Testing native PS...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); printf("Buffered...\n"); MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); pdo_mysql_stmt_closecursor($db); printf("Unbuffered...\n"); MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); pdo_mysql_stmt_closecursor($db); } catch (PDOException $e) { @@ -156,23 +156,23 @@ $db->exec('DROP TABLE IF EXISTS pdo_mysql_stmt_closecursor'); Testing emulated PS... Buffered... -Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d +Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d in = 0 -> id = 1 (integer) / label = 'a' (string) in = 0 -> id = 2 (integer) / label = 'b' (string) Unbuffered... -Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d +Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d in = 0 -> id = 1 (integer) / label = 'a' (string) in = 0 -> id = 2 (integer) / label = 'b' (string) Testing native PS... Buffered... -Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d +Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d in = 0 -> id = 1 (integer) / label = 'a' (string) in = 0 -> id = 2 (integer) / label = 'b' (string) Unbuffered... -Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d +Warning: PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the Pdo\Mysql::ATTR_USE_BUFFERED_QUERY attribute. in %s on line %d in = 0 -> id = 1 (integer) / label = 'a' (string) in = 0 -> id = 2 (integer) / label = 'b' (string) done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor_empty.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor_empty.phpt index 33127f4ee242..b0880f354898 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor_empty.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_closecursor_empty.phpt @@ -16,11 +16,11 @@ MySQLPDOTest::skip(); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); MySQLPDOTest::createTestTable($table, $db); $stmt = $db->prepare("SELECT id, label FROM {$table} WHERE id > ? ORDER BY id ASC LIMIT 2"); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_columncount.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_columncount.phpt index b55725057e23..81d2bd6386e3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_columncount.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_columncount.phpt @@ -20,8 +20,8 @@ MySQLPDOTest::skip(); // Internal data structures should be the same in both cases. printf("Testing emulated PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); $stmt = $db->prepare("SELECT id, label, '?' as foo FROM {$table}"); @@ -38,8 +38,8 @@ MySQLPDOTest::skip(); printf("Testing native PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to turn off emulated prepared statements\n"); $stmt = $db->prepare("SELECT id, label, '?' as foo, 'TODO - Stored Procedure' as bar FROM {$table}"); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_errorcode.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_errorcode.phpt index de4cb8b97bfb..8602fa7b3600 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_errorcode.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_errorcode.phpt @@ -16,8 +16,8 @@ MySQLPDOTest::skip(); printf("Testing emulated PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); $stmt = $db->prepare('SELECT id FROM pdo_mysql_stmt_errorcode_ihopeitdoesnotexist ORDER BY id ASC'); @@ -32,8 +32,8 @@ MySQLPDOTest::skip(); printf("Testing native PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to turn off emulated prepared statements\n"); $stmt = $db->prepare('SELECT id FROM pdo_mysql_stmt_errorcode_ihopeitdoesnotexist ORDER BY id ASC'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt index 6b2a9281d9c2..04fb7d802e62 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt @@ -17,8 +17,8 @@ MySQLPDOTest::skip(); printf("Testing emulated PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); $stmt = $db->prepare('SELECT id FROM pdo_mysql_stmt_errorinfo_ihopeitdoesnotexist ORDER BY id ASC'); @@ -40,8 +40,8 @@ MySQLPDOTest::skip(); printf("Testing native PS...\n"); try { - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to turn off emulated prepared statements\n"); $stmt = $db->prepare('SELECT id FROM pdo_mysql_stmt_errorinfo_ihopeitdoesnotexist ORDER BY id ASC'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_class.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_class.phpt index 4d5db44ea91b..20259b8d4929 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_class.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_class.phpt @@ -75,8 +75,8 @@ MySQLPDOTest::skip(); } - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); $db->exec(sprintf('CREATE TABLE test_stmt_fetch_class(id INT, myobj BLOB) ENGINE=%s', diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_non_select.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_non_select.phpt index 0027d1ea52ff..421276c570d7 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_non_select.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_non_select.phpt @@ -18,8 +18,8 @@ MySQLPDOTest::skip(); try { // Emulated PS first - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); - if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 1); + if (1 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn on emulated prepared statements\n"); if (!is_object($stmt = $db->query("DESCRIBE {$table} id"))) @@ -68,8 +68,8 @@ MySQLPDOTest::skip(); printf("[010] Emulated PS, EXPLAIN returned no results\n"); // And now native PS - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[011] Unable to turn off emulated prepared statements\n"); $native_support = 'no'; diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize.phpt index 8aaf65f52d9e..fd2b6cb5e4a7 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize.phpt @@ -75,8 +75,8 @@ MySQLPDOTest::skip(); } - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); $db->exec(sprintf('CREATE TABLE test_stmt_fetch_serialize(id INT, myobj BLOB) ENGINE=%s', diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize_fetch_class.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize_fetch_class.phpt index f2f6c89ad389..1d3c7f69fab9 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize_fetch_class.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetch_serialize_fetch_class.phpt @@ -75,8 +75,8 @@ MySQLPDOTest::skip(); } - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[002] Unable to turn off emulated prepared statements\n"); $db->exec(sprintf('CREATE TABLE test_stmt_fetchserialize_fetch_class(id INT, myobj BLOB) ENGINE=%s', diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt index 0552a87aa42d..9b09491e0cbf 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt @@ -37,8 +37,8 @@ try { $emulated = $stmt->getColumnMeta(0); printf("Testing native PS...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[007] Unable to turn off emulated prepared statements\n"); $stmt = $db->prepare('SELECT id FROM test_stmt_getcolumnmeta ORDER BY id ASC'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt index df2d3b402d83..0415a04fdab6 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt @@ -63,14 +63,14 @@ MySQLPDOTest::skipNotMySQLnd(); printf("Emulated PS...\n"); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 1); test_proc1($db); test_proc2($db); $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 1); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 0); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 0); test_proc1($db); test_proc2($db); @@ -78,14 +78,14 @@ MySQLPDOTest::skipNotMySQLnd(); printf("Native PS...\n"); $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 1); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); test_proc1($db); test_proc2($db); $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 0); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 0); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); test_proc1($db); diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_unbuffered_2050.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_unbuffered_2050.phpt index aca3e6a084cb..fcba9e44e694 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_unbuffered_2050.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_unbuffered_2050.phpt @@ -18,13 +18,13 @@ if (MYSQLPDOTest::isPDOMySQLnd()) try { printf("Native PS...\n"); - $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 0); - if (0 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) + $db->setAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY, 0); + if (0 != $db->getAttribute(Pdo\Mysql::ATTR_DIRECT_QUERY)) printf("[004] Unable to turn off emulated prepared statements\n"); printf("Buffered...\n"); MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, true); $stmt = $db->query("SELECT id, label FROM {$table} WHERE id = 1"); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); $stmt = $db->query("SELECT id, label FROM {$table} WHERE id = 1"); @@ -32,7 +32,7 @@ if (MYSQLPDOTest::isPDOMySQLnd()) printf("Unbuffered...\n"); MySQLPDOTest::createTestTable($table, $db); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, false); $stmt = $db->query("SELECT id, label FROM {$table} WHERE id = 1"); var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); /* diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt index fb3538176974..48353f4cbdb3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt @@ -57,7 +57,7 @@ MySQLPDOTest::skip(); // Libmysql cannot handle such a stored procedure. You will see leaks with libmysql $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 1); $stmt = $db->prepare("CALL {$procedure}(?)"); $stmt->bindParam(1, $columns); for ($i = 5; $i < 10; $i++) { @@ -88,7 +88,7 @@ MySQLPDOTest::skip(); // Libmysql cannot handle such a stored procedure. You will see leaks with libmysql $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); - $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); + $db->setAttribute(Pdo\Mysql::ATTR_USE_BUFFERED_QUERY, 1); $db->exec('SET @numcols = 1'); $stmt = $db->prepare("CALL {$procedure}()"); $stmt->execute(); diff --git a/ext/pdo_mysql/tests/pdo_mysql_types.phpt b/ext/pdo_mysql/tests/pdo_mysql_types.phpt index 462a542c24c1..7c7926a8cb9f 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_types.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_types.phpt @@ -105,7 +105,7 @@ MySQLPDOTest::skip(); test_type($db, 90, 'MEDIUMINT UNSIGNED', 16777215, ($is_mysqlnd) ? 16777215 : '16777215'); test_type($db, 100, 'INT', -2147483648, - ($is_mysqlnd) ? ((PHP_INT_SIZE > 4) ? (int)-2147483648 : (double)-2147483648) : '-2147483648', + ($is_mysqlnd) ? ((PHP_INT_SIZE > 4) ? (int)-2147483648 : (float)-2147483648) : '-2147483648', NULL, ($is_mysqlnd) ? 'integer' : NULL); test_type($db, 110, 'INT UNSIGNED', 4294967295, ($is_mysqlnd) ? ((PHP_INT_SIZE > 4) ? 4294967295 : '4294967295') : '4294967295'); diff --git a/ext/pdo_mysql/tests/php_8.5_deprecations.phpt b/ext/pdo_mysql/tests/php_8.5_deprecations.phpt new file mode 100644 index 000000000000..4d163c2f48cd --- /dev/null +++ b/ext/pdo_mysql/tests/php_8.5_deprecations.phpt @@ -0,0 +1,81 @@ +--TEST-- +PDO_mysql: PHP 8.5 deprecations +--EXTENSIONS-- +pdo_mysql +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Deprecated: Constant PDO::MYSQL_ATTR_USE_BUFFERED_QUERY is deprecated since 8.5, use Pdo\Mysql::ATTR_USE_BUFFERED_QUERY instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_LOCAL_INFILE is deprecated since 8.5, use Pdo\Mysql::ATTR_LOCAL_INFILE instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY is deprecated since 8.5, use Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_INIT_COMMAND is deprecated since 8.5, use Pdo\Mysql::ATTR_INIT_COMMAND instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_COMPRESS is deprecated since 8.5, use Pdo\Mysql::ATTR_COMPRESS instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_DIRECT_QUERY is deprecated since 8.5, use Pdo\Mysql::ATTR_DIRECT_QUERY instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_FOUND_ROWS is deprecated since 8.5, use Pdo\Mysql::ATTR_FOUND_ROWS instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_IGNORE_SPACE is deprecated since 8.5, use Pdo\Mysql::ATTR_IGNORE_SPACE instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_SSL_KEY is deprecated since 8.5, use Pdo\Mysql::ATTR_SSL_KEY instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_SSL_CERT is deprecated since 8.5, use Pdo\Mysql::ATTR_SSL_CERT instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_SSL_CA is deprecated since 8.5, use Pdo\Mysql::ATTR_SSL_CA instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_SSL_CAPATH is deprecated since 8.5, use Pdo\Mysql::ATTR_SSL_CAPATH instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_SSL_CIPHER is deprecated since 8.5, use Pdo\Mysql::ATTR_SSL_CIPHER instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT is deprecated since 8.5, use Pdo\Mysql::ATTR_SSL_VERIFY_SERVER_CERT instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_SERVER_PUBLIC_KEY is deprecated since 8.5, use Pdo\Mysql::ATTR_SERVER_PUBLIC_KEY instead in %s on line %d + +Deprecated: Constant PDO::MYSQL_ATTR_MULTI_STATEMENTS is deprecated since 8.5, use Pdo\Mysql::ATTR_MULTI_STATEMENTS instead in %s on line %d +int(1000) +int(1001) +int(1014) +int(1002) +int(1003) +int(20) +int(1004) +int(1005) +int(1006) +int(1007) +int(1008) +int(1009) +int(1010) +int(1013) +int(1011) +int(1012) diff --git a/ext/pdo_odbc/config.w32 b/ext/pdo_odbc/config.w32 index 6a94da7f7953..e70516195718 100644 --- a/ext/pdo_odbc/config.w32 +++ b/ext/pdo_odbc/config.w32 @@ -4,11 +4,13 @@ ARG_WITH("pdo-odbc", "ODBC support for PDO", "no"); if (PHP_PDO_ODBC != "no") { if (CHECK_LIB("odbc32.lib", "pdo_odbc") && CHECK_LIB("odbccp32.lib", "pdo_odbc") - && CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_PDO_ODBC') - && CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_PDO_ODBC')) { + && CHECK_HEADER('sql.h', 'CFLAGS_PDO_ODBC') + && CHECK_HEADER('sqlext.h', 'CFLAGS_PDO_ODBC')) { EXTENSION("pdo_odbc", "pdo_odbc.c odbc_driver.c odbc_stmt.c"); ADD_EXTENSION_DEP('pdo_odbc', 'pdo'); + AC_DEFINE('HAVE_SQL_H', 1, 'Define to 1 if you have the header.'); + AC_DEFINE('HAVE_SQLEXT_H', 1, 'Define to 1 if you have the header.'); } else { WARNING("pdo_odbc support can't be enabled, headers or libraries are missing (SDK)") diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 7401023c573c..3c8afe2d4215 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -550,9 +548,9 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ if (use_uid_arg) { should_quote_uid = !php_odbc_connstr_is_quoted(dbh->username) && php_odbc_connstr_should_quote(dbh->username); if (should_quote_uid) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->username); - uid = emalloc(estimated_length); - php_odbc_connstr_quote(uid, dbh->username, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(dbh->username); + uid = emalloc(quoted_length); + php_odbc_connstr_quote(uid, dbh->username, quoted_length); } else { uid = dbh->username; } @@ -567,9 +565,9 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ if (use_pwd_arg) { should_quote_pwd = !php_odbc_connstr_is_quoted(dbh->password) && php_odbc_connstr_should_quote(dbh->password); if (should_quote_pwd) { - size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->password); - pwd = emalloc(estimated_length); - php_odbc_connstr_quote(pwd, dbh->password, estimated_length); + size_t quoted_length = php_odbc_connstr_get_quoted_length(dbh->password); + pwd = emalloc(quoted_length); + php_odbc_connstr_quote(pwd, dbh->password, quoted_length); } else { pwd = dbh->password; } diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 1f5009c746b6..dfc42147c30f 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -26,6 +24,9 @@ #include "php_pdo_odbc.h" #include "php_pdo_odbc_int.h" +/* Buffer size; bigger columns than this become a "long column" */ +#define LONG_COLUMN_BUFFER_SIZE (ZEND_MM_PAGE_SIZE- ZSTR_MAX_OVERHEAD) + enum pdo_odbc_conv_result { PDO_ODBC_CONV_NOT_REQUIRED, PDO_ODBC_CONV_OK, @@ -615,7 +616,7 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno) /* tell ODBC to put it straight into our buffer, but only if it * isn't "long" data, and only if we haven't already bound a long * column. */ - if (colsize < 256 && !S->going_long) { + if (colsize < LONG_COLUMN_BUFFER_SIZE && !S->going_long) { S->cols[colno].data = emalloc(colsize+1); S->cols[colno].is_long = 0; @@ -631,7 +632,7 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno) } else { /* allocate a smaller buffer to keep around for smaller * "long" columns */ - S->cols[colno].data = emalloc(256); + S->cols[colno].data = emalloc(LONG_COLUMN_BUFFER_SIZE); S->going_long = 1; S->cols[colno].is_long = 1; } @@ -657,37 +658,57 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo RETCODE rc; /* fetch it into C->data, which is allocated with a length - * of 256 bytes; if there is more to be had, we then allocate + * of the page size minus zend_string overhead (LONG_COLUMN_BUFFER_SIZE); + * if there is more to be had, we then allocate * bigger buffer for the caller to free */ rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, C->data, - 256, &C->fetched_len); + LONG_COLUMN_BUFFER_SIZE, &C->fetched_len); orig_fetched_len = C->fetched_len; - if (rc == SQL_SUCCESS && C->fetched_len < 256) { + if (rc == SQL_SUCCESS && C->fetched_len < LONG_COLUMN_BUFFER_SIZE) { /* all the data fit into our little buffer; * jump down to the generic bound data case */ goto in_data; } if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS) { - /* this is a 'long column' - - read the column in 255 byte blocks until the end of the column is reached, reassembling those blocks - in order into the output buffer; 255 bytes are an optimistic assumption, since the driver may assert - more or less NUL bytes at the end; we cater to that later, if actual length information is available - - this loop has to work whether or not SQLGetData() provides the total column length. - calling SQLDescribeCol() or other, specifically to get the column length, then doing a single read - for that size would be slower except maybe for extremely long columns.*/ - char *buf2 = emalloc(256); - zend_string *str = zend_string_init(C->data, 256, 0); - size_t used = 255; /* not 256; the driver NUL terminated the buffer */ + /* + * This is a long column. + * + * Try to get as much as we can at once. If the + * driver somehow has more for us, get more. We'll + * assemble it into one big buffer at the end. + * + * N.B. with n and n+1 mentioned in the comments: + * n is the size returned without null terminator. + * + * The extension previously tried getting it in 256 + * byte blocks, but this could have created trouble + * with some drivers. + * + * However, depending on the driver, fetched_len may + * not contain the number of bytes and SQL_NO_TOTAL + * may be passed. + * The behavior in this case is the same as before, + * dividing the data into blocks. However, it has been + * changed from 256 byte to LONG_COLUMN_BUFFER_SIZE. + */ + ssize_t to_fetch_len; + if (orig_fetched_len == SQL_NO_TOTAL) { + to_fetch_len = C->datalen > (LONG_COLUMN_BUFFER_SIZE - 1) ? (LONG_COLUMN_BUFFER_SIZE - 1) : C->datalen; + } else { + to_fetch_len = orig_fetched_len; + } + ssize_t to_fetch_byte = to_fetch_len + 1; + char *buf2 = emalloc(to_fetch_byte); + zend_string *str = zend_string_init(C->data, to_fetch_byte, 0); + size_t used = to_fetch_len; do { C->fetched_len = 0; - /* read block. 256 bytes => 255 bytes are actually read, the last 1 is NULL */ - rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, buf2, 256, &C->fetched_len); + /* read block. n + 1 bytes => n bytes are actually read, the last 1 is NULL */ + rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, buf2, to_fetch_byte, &C->fetched_len); /* adjust `used` in case we have proper length info from the driver */ if (orig_fetched_len >= 0 && C->fetched_len >= 0) { @@ -698,14 +719,14 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo } /* resize output buffer and reassemble block */ - if (rc==SQL_SUCCESS_WITH_INFO || (rc==SQL_SUCCESS && C->fetched_len > 255)) { + if (rc==SQL_SUCCESS_WITH_INFO || (rc==SQL_SUCCESS && C->fetched_len > to_fetch_len)) { /* point 5, in section "Retrieving Data with SQLGetData" in http://msdn.microsoft.com/en-us/library/windows/desktop/ms715441(v=vs.85).aspx - states that if SQL_SUCCESS_WITH_INFO, fetched_len will be > 255 (greater than buf2's size) - (if a driver fails to follow that and wrote less than 255 bytes to buf2, this will AV or read garbage into buf) */ - str = zend_string_realloc(str, used + 256, 0); - memcpy(ZSTR_VAL(str) + used, buf2, 256); - used = used + 255; - } else if (rc==SQL_SUCCESS) { + states that if SQL_SUCCESS_WITH_INFO, fetched_len will be > n (greater than buf2's size) + (if a driver fails to follow that and wrote less than n bytes to buf2, this will AV or read garbage into buf) */ + str = zend_string_realloc(str, used + to_fetch_byte, 0); + memcpy(ZSTR_VAL(str) + used, buf2, to_fetch_byte); + used = used + to_fetch_len; + } else if (rc == SQL_SUCCESS && C->fetched_len != 0) { str = zend_string_realloc(str, used + C->fetched_len, 0); memcpy(ZSTR_VAL(str) + used, buf2, C->fetched_len); used = used + C->fetched_len; @@ -780,7 +801,7 @@ static int odbc_stmt_set_param(pdo_stmt_t *stmt, zend_long attr, zval *val) return 0; case PDO_ODBC_ATTR_ASSUME_UTF8: - S->assume_utf8 = zval_is_true(val); + S->assume_utf8 = zend_is_true(val); return 0; default: strcpy(S->einfo.last_err_msg, "Unknown Attribute"); diff --git a/ext/pdo_odbc/pdo_odbc.c b/ext/pdo_odbc/pdo_odbc.c index 1052322fe8cf..47a19062947c 100644 --- a/ext/pdo_odbc/pdo_odbc.c +++ b/ext/pdo_odbc/pdo_odbc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -61,6 +59,9 @@ zend_ulong pdo_odbc_pool_on = SQL_CP_OFF; zend_ulong pdo_odbc_pool_mode = SQL_CP_ONE_PER_HENV; #endif +#define REGISTER_PDO_ODBC_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, value) \ + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, "ODBC_", "Pdo\\Odbc::", value) + /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(pdo_odbc) { @@ -101,11 +102,11 @@ PHP_MINIT_FUNCTION(pdo_odbc) register_pdo_odbc_symbols(module_number); - REGISTER_PDO_CLASS_CONST_LONG("ODBC_ATTR_USE_CURSOR_LIBRARY", PDO_ODBC_ATTR_USE_CURSOR_LIBRARY); - REGISTER_PDO_CLASS_CONST_LONG("ODBC_ATTR_ASSUME_UTF8", PDO_ODBC_ATTR_ASSUME_UTF8); - REGISTER_PDO_CLASS_CONST_LONG("ODBC_SQL_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED); - REGISTER_PDO_CLASS_CONST_LONG("ODBC_SQL_USE_DRIVER", SQL_CUR_USE_DRIVER); - REGISTER_PDO_CLASS_CONST_LONG("ODBC_SQL_USE_ODBC", SQL_CUR_USE_ODBC); + REGISTER_PDO_ODBC_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_USE_CURSOR_LIBRARY", PDO_ODBC_ATTR_USE_CURSOR_LIBRARY); + REGISTER_PDO_ODBC_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_ASSUME_UTF8", PDO_ODBC_ATTR_ASSUME_UTF8); + REGISTER_PDO_ODBC_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("SQL_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED); + REGISTER_PDO_ODBC_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("SQL_USE_DRIVER", SQL_CUR_USE_DRIVER); + REGISTER_PDO_ODBC_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("SQL_USE_ODBC", SQL_CUR_USE_ODBC); pdo_odbc_ce = register_class_Pdo_Odbc(pdo_dbh_ce); pdo_odbc_ce->create_object = pdo_dbh_new; diff --git a/ext/pdo_odbc/pdo_odbc_arginfo.h b/ext/pdo_odbc/pdo_odbc_arginfo.h index 5b1933d7594a..9492f8c374e0 100644 --- a/ext/pdo_odbc/pdo_odbc_arginfo.h +++ b/ext/pdo_odbc/pdo_odbc_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pdo_odbc.stub.php instead. * Stub hash: 9136c911494c9e3462c49b3e58f4bcc15ebb2a9c */ static void register_pdo_odbc_symbols(int module_number) @@ -15,33 +15,33 @@ static zend_class_entry *register_class_Pdo_Odbc(zend_class_entry *class_entry_P zval const_ATTR_USE_CURSOR_LIBRARY_value; ZVAL_LONG(&const_ATTR_USE_CURSOR_LIBRARY_value, PDO_ODBC_ATTR_USE_CURSOR_LIBRARY); - zend_string *const_ATTR_USE_CURSOR_LIBRARY_name = zend_string_init_interned("ATTR_USE_CURSOR_LIBRARY", sizeof("ATTR_USE_CURSOR_LIBRARY") - 1, 1); + zend_string *const_ATTR_USE_CURSOR_LIBRARY_name = zend_string_init_interned("ATTR_USE_CURSOR_LIBRARY", sizeof("ATTR_USE_CURSOR_LIBRARY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_USE_CURSOR_LIBRARY_name, &const_ATTR_USE_CURSOR_LIBRARY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_USE_CURSOR_LIBRARY_name); + zend_string_release_ex(const_ATTR_USE_CURSOR_LIBRARY_name, true); zval const_ATTR_ASSUME_UTF8_value; ZVAL_LONG(&const_ATTR_ASSUME_UTF8_value, PDO_ODBC_ATTR_ASSUME_UTF8); - zend_string *const_ATTR_ASSUME_UTF8_name = zend_string_init_interned("ATTR_ASSUME_UTF8", sizeof("ATTR_ASSUME_UTF8") - 1, 1); + zend_string *const_ATTR_ASSUME_UTF8_name = zend_string_init_interned("ATTR_ASSUME_UTF8", sizeof("ATTR_ASSUME_UTF8") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_ASSUME_UTF8_name, &const_ATTR_ASSUME_UTF8_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_ASSUME_UTF8_name); + zend_string_release_ex(const_ATTR_ASSUME_UTF8_name, true); zval const_SQL_USE_IF_NEEDED_value; ZVAL_LONG(&const_SQL_USE_IF_NEEDED_value, SQL_CUR_USE_IF_NEEDED); - zend_string *const_SQL_USE_IF_NEEDED_name = zend_string_init_interned("SQL_USE_IF_NEEDED", sizeof("SQL_USE_IF_NEEDED") - 1, 1); + zend_string *const_SQL_USE_IF_NEEDED_name = zend_string_init_interned("SQL_USE_IF_NEEDED", sizeof("SQL_USE_IF_NEEDED") - 1, true); zend_declare_typed_class_constant(class_entry, const_SQL_USE_IF_NEEDED_name, &const_SQL_USE_IF_NEEDED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SQL_USE_IF_NEEDED_name); + zend_string_release_ex(const_SQL_USE_IF_NEEDED_name, true); zval const_SQL_USE_DRIVER_value; ZVAL_LONG(&const_SQL_USE_DRIVER_value, SQL_CUR_USE_DRIVER); - zend_string *const_SQL_USE_DRIVER_name = zend_string_init_interned("SQL_USE_DRIVER", sizeof("SQL_USE_DRIVER") - 1, 1); + zend_string *const_SQL_USE_DRIVER_name = zend_string_init_interned("SQL_USE_DRIVER", sizeof("SQL_USE_DRIVER") - 1, true); zend_declare_typed_class_constant(class_entry, const_SQL_USE_DRIVER_name, &const_SQL_USE_DRIVER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SQL_USE_DRIVER_name); + zend_string_release_ex(const_SQL_USE_DRIVER_name, true); zval const_SQL_USE_ODBC_value; ZVAL_LONG(&const_SQL_USE_ODBC_value, SQL_CUR_USE_ODBC); - zend_string *const_SQL_USE_ODBC_name = zend_string_init_interned("SQL_USE_ODBC", sizeof("SQL_USE_ODBC") - 1, 1); + zend_string *const_SQL_USE_ODBC_name = zend_string_init_interned("SQL_USE_ODBC", sizeof("SQL_USE_ODBC") - 1, true); zend_declare_typed_class_constant(class_entry, const_SQL_USE_ODBC_name, &const_SQL_USE_ODBC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SQL_USE_ODBC_name); + zend_string_release_ex(const_SQL_USE_ODBC_name, true); return class_entry; } diff --git a/ext/pdo_odbc/php_pdo_odbc.h b/ext/pdo_odbc/php_pdo_odbc.h index 3f0417029784..6c72b6f2ebe9 100644 --- a/ext/pdo_odbc/php_pdo_odbc.h +++ b/ext/pdo_odbc/php_pdo_odbc.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo_odbc/php_pdo_odbc_int.h b/ext/pdo_odbc/php_pdo_odbc_int.h index 473d70ff7076..18b45af21a02 100644 --- a/ext/pdo_odbc/php_pdo_odbc_int.h +++ b/ext/pdo_odbc/php_pdo_odbc_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/pdo_odbc/tests/bug80783a.phpt b/ext/pdo_odbc/tests/bug80783a.phpt index ab141588e1b4..d8987cfd0ac3 100644 --- a/ext/pdo_odbc/tests/bug80783a.phpt +++ b/ext/pdo_odbc/tests/bug80783a.phpt @@ -22,7 +22,7 @@ $string = str_repeat("0123456789", 50); $db->exec("INSERT INTO bug80783a VALUES('$string')"); $stmt = $db->prepare("SELECT name FROM bug80783a"); -$stmt->setAttribute(PDO::ODBC_ATTR_ASSUME_UTF8, true); +$stmt->setAttribute(Pdo\Odbc::ATTR_ASSUME_UTF8, true); $stmt->bindColumn(1, $data, PDO::PARAM_STR); $stmt->execute(); $stmt->fetch(PDO::FETCH_BOUND); diff --git a/ext/pdo_odbc/tests/php_8.5_deprecations.phpt b/ext/pdo_odbc/tests/php_8.5_deprecations.phpt new file mode 100644 index 000000000000..54be2339f6cf --- /dev/null +++ b/ext/pdo_odbc/tests/php_8.5_deprecations.phpt @@ -0,0 +1,31 @@ +--TEST-- +PDO_odbc: PHP 8.5 deprecations +--EXTENSIONS-- +pdo_odbc +--FILE-- + +--EXPECTF-- +Deprecated: Constant PDO::ODBC_ATTR_USE_CURSOR_LIBRARY is deprecated since 8.5, use Pdo\Odbc::ATTR_USE_CURSOR_LIBRARY instead in %s on line %d + +Deprecated: Constant PDO::ODBC_ATTR_ASSUME_UTF8 is deprecated since 8.5, use Pdo\Odbc::ATTR_ASSUME_UTF8 instead in %s on line %d + +Deprecated: Constant PDO::ODBC_SQL_USE_IF_NEEDED is deprecated since 8.5, use Pdo\Odbc::SQL_USE_IF_NEEDED instead in %s on line %d + +Deprecated: Constant PDO::ODBC_SQL_USE_DRIVER is deprecated since 8.5, use Pdo\Odbc::SQL_USE_DRIVER instead in %s on line %d + +Deprecated: Constant PDO::ODBC_SQL_USE_ODBC is deprecated since 8.5, use Pdo\Odbc::SQL_USE_ODBC instead in %s on line %d +int(1000) +int(1001) +int(0) +int(2) +int(1) diff --git a/ext/pdo_pgsql/config.w32 b/ext/pdo_pgsql/config.w32 index aec5db508d07..87ad0a661b53 100644 --- a/ext/pdo_pgsql/config.w32 +++ b/ext/pdo_pgsql/config.w32 @@ -4,9 +4,10 @@ ARG_WITH("pdo-pgsql", "PostgreSQL support for PDO", "no"); if (PHP_PDO_PGSQL != "no") { if (CHECK_LIB("libpq.lib", "pdo_pgsql", PHP_PDO_PGSQL) && - CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) { + CHECK_HEADER("libpq-fe.h", "CFLAGS_PDO_PGSQL", PHP_PDO_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;")) { EXTENSION("pdo_pgsql", "pdo_pgsql.c pgsql_driver.c pgsql_statement.c pgsql_sql_parser.c"); + AC_DEFINE('HAVE_PG_RESULT_MEMORY_SIZE', 1, "Define to 1 if libpq has the 'PQresultMemorySize' function (PostgreSQL 12 or later)."); AC_DEFINE('HAVE_PDO_PGSQL', 1, "Define to 1 if the PHP extension 'pdo_pgsql' is available."); ADD_EXTENSION_DEP('pdo_pgsql', 'pdo'); diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c index 49efa0b23848..d552aa5e61dd 100644 --- a/ext/pdo_pgsql/pdo_pgsql.c +++ b/ext/pdo_pgsql/pdo_pgsql.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ @@ -175,15 +173,18 @@ PHP_METHOD(Pdo_Pgsql, setNoticeCallback) /* true global environment */ +#define REGISTER_PDO_PGSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, value) \ + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, "PGSQL_", "Pdo\\Pgsql::", value) + /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(pdo_pgsql) { - REGISTER_PDO_CLASS_CONST_LONG("PGSQL_ATTR_DISABLE_PREPARES", PDO_PGSQL_ATTR_DISABLE_PREPARES); - REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_IDLE", (zend_long)PGSQL_TRANSACTION_IDLE); - REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_ACTIVE", (zend_long)PGSQL_TRANSACTION_ACTIVE); - REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INTRANS", (zend_long)PGSQL_TRANSACTION_INTRANS); - REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_INERROR", (zend_long)PGSQL_TRANSACTION_INERROR); - REGISTER_PDO_CLASS_CONST_LONG("PGSQL_TRANSACTION_UNKNOWN", (zend_long)PGSQL_TRANSACTION_UNKNOWN); + REGISTER_PDO_PGSQL_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_DISABLE_PREPARES", PDO_PGSQL_ATTR_DISABLE_PREPARES); + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_85("PGSQL_TRANSACTION_IDLE", (zend_long)PGSQL_TRANSACTION_IDLE); + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_85("PGSQL_TRANSACTION_ACTIVE", (zend_long)PGSQL_TRANSACTION_ACTIVE); + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_85("PGSQL_TRANSACTION_INTRANS", (zend_long)PGSQL_TRANSACTION_INTRANS); + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_85("PGSQL_TRANSACTION_INERROR", (zend_long)PGSQL_TRANSACTION_INERROR); + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_85("PGSQL_TRANSACTION_UNKNOWN", (zend_long)PGSQL_TRANSACTION_UNKNOWN); PdoPgsql_ce = register_class_Pdo_Pgsql(pdo_dbh_ce); PdoPgsql_ce->create_object = pdo_dbh_new; diff --git a/ext/pdo_pgsql/pdo_pgsql.stub.php b/ext/pdo_pgsql/pdo_pgsql.stub.php index 8e96a5526682..8322b88ca8db 100644 --- a/ext/pdo_pgsql/pdo_pgsql.stub.php +++ b/ext/pdo_pgsql/pdo_pgsql.stub.php @@ -19,18 +19,23 @@ class Pgsql extends \PDO #endif /** @cvalue PGSQL_TRANSACTION_IDLE */ + #[\Deprecated(since: "8.5", message: "as it has no effect")] public const int TRANSACTION_IDLE = UNKNOWN; /** @cvalue PGSQL_TRANSACTION_ACTIVE */ + #[\Deprecated(since: "8.5", message: "as it has no effect")] public const int TRANSACTION_ACTIVE = UNKNOWN; /** @cvalue PGSQL_TRANSACTION_INTRANS */ + #[\Deprecated(since: "8.5", message: "as it has no effect")] public const int TRANSACTION_INTRANS = UNKNOWN; /** @cvalue PGSQL_TRANSACTION_INERROR */ + #[\Deprecated(since: "8.5", message: "as it has no effect")] public const int TRANSACTION_INERROR = UNKNOWN; /** @cvalue PGSQL_TRANSACTION_UNKNOWN */ + #[\Deprecated(since: "8.5", message: "as it has no effect")] public const int TRANSACTION_UNKNOWN = UNKNOWN; public function escapeIdentifier(string $input): string {} diff --git a/ext/pdo_pgsql/pdo_pgsql_arginfo.h b/ext/pdo_pgsql/pdo_pgsql_arginfo.h index f7f54cb600c7..80e87862b08b 100644 --- a/ext/pdo_pgsql/pdo_pgsql_arginfo.h +++ b/ext/pdo_pgsql/pdo_pgsql_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 225cbb077d441f93b7c6bdb9826ab3e8f634b79d */ +/* This is a generated file, edit pdo_pgsql.stub.php instead. + * Stub hash: 0ea21010467d661416f0858f2bda095583ea3a36 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Pdo_Pgsql_escapeIdentifier, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, input, IS_STRING, 0) @@ -90,47 +90,79 @@ static zend_class_entry *register_class_Pdo_Pgsql(zend_class_entry *class_entry_ zval const_ATTR_DISABLE_PREPARES_value; ZVAL_LONG(&const_ATTR_DISABLE_PREPARES_value, PDO_PGSQL_ATTR_DISABLE_PREPARES); - zend_string *const_ATTR_DISABLE_PREPARES_name = zend_string_init_interned("ATTR_DISABLE_PREPARES", sizeof("ATTR_DISABLE_PREPARES") - 1, 1); + zend_string *const_ATTR_DISABLE_PREPARES_name = zend_string_init_interned("ATTR_DISABLE_PREPARES", sizeof("ATTR_DISABLE_PREPARES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_DISABLE_PREPARES_name, &const_ATTR_DISABLE_PREPARES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_DISABLE_PREPARES_name); + zend_string_release_ex(const_ATTR_DISABLE_PREPARES_name, true); #if defined(HAVE_PG_RESULT_MEMORY_SIZE) zval const_ATTR_RESULT_MEMORY_SIZE_value; ZVAL_LONG(&const_ATTR_RESULT_MEMORY_SIZE_value, PDO_PGSQL_ATTR_RESULT_MEMORY_SIZE); - zend_string *const_ATTR_RESULT_MEMORY_SIZE_name = zend_string_init_interned("ATTR_RESULT_MEMORY_SIZE", sizeof("ATTR_RESULT_MEMORY_SIZE") - 1, 1); + zend_string *const_ATTR_RESULT_MEMORY_SIZE_name = zend_string_init_interned("ATTR_RESULT_MEMORY_SIZE", sizeof("ATTR_RESULT_MEMORY_SIZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_RESULT_MEMORY_SIZE_name, &const_ATTR_RESULT_MEMORY_SIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_RESULT_MEMORY_SIZE_name); + zend_string_release_ex(const_ATTR_RESULT_MEMORY_SIZE_name, true); #endif zval const_TRANSACTION_IDLE_value; ZVAL_LONG(&const_TRANSACTION_IDLE_value, PGSQL_TRANSACTION_IDLE); - zend_string *const_TRANSACTION_IDLE_name = zend_string_init_interned("TRANSACTION_IDLE", sizeof("TRANSACTION_IDLE") - 1, 1); - zend_declare_typed_class_constant(class_entry, const_TRANSACTION_IDLE_name, &const_TRANSACTION_IDLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRANSACTION_IDLE_name); + zend_string *const_TRANSACTION_IDLE_name = zend_string_init_interned("TRANSACTION_IDLE", sizeof("TRANSACTION_IDLE") - 1, true); + zend_class_constant *const_TRANSACTION_IDLE = zend_declare_typed_class_constant(class_entry, const_TRANSACTION_IDLE_name, &const_TRANSACTION_IDLE_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_IDLE_name, true); zval const_TRANSACTION_ACTIVE_value; ZVAL_LONG(&const_TRANSACTION_ACTIVE_value, PGSQL_TRANSACTION_ACTIVE); - zend_string *const_TRANSACTION_ACTIVE_name = zend_string_init_interned("TRANSACTION_ACTIVE", sizeof("TRANSACTION_ACTIVE") - 1, 1); - zend_declare_typed_class_constant(class_entry, const_TRANSACTION_ACTIVE_name, &const_TRANSACTION_ACTIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRANSACTION_ACTIVE_name); + zend_string *const_TRANSACTION_ACTIVE_name = zend_string_init_interned("TRANSACTION_ACTIVE", sizeof("TRANSACTION_ACTIVE") - 1, true); + zend_class_constant *const_TRANSACTION_ACTIVE = zend_declare_typed_class_constant(class_entry, const_TRANSACTION_ACTIVE_name, &const_TRANSACTION_ACTIVE_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_ACTIVE_name, true); zval const_TRANSACTION_INTRANS_value; ZVAL_LONG(&const_TRANSACTION_INTRANS_value, PGSQL_TRANSACTION_INTRANS); - zend_string *const_TRANSACTION_INTRANS_name = zend_string_init_interned("TRANSACTION_INTRANS", sizeof("TRANSACTION_INTRANS") - 1, 1); - zend_declare_typed_class_constant(class_entry, const_TRANSACTION_INTRANS_name, &const_TRANSACTION_INTRANS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRANSACTION_INTRANS_name); + zend_string *const_TRANSACTION_INTRANS_name = zend_string_init_interned("TRANSACTION_INTRANS", sizeof("TRANSACTION_INTRANS") - 1, true); + zend_class_constant *const_TRANSACTION_INTRANS = zend_declare_typed_class_constant(class_entry, const_TRANSACTION_INTRANS_name, &const_TRANSACTION_INTRANS_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_INTRANS_name, true); zval const_TRANSACTION_INERROR_value; ZVAL_LONG(&const_TRANSACTION_INERROR_value, PGSQL_TRANSACTION_INERROR); - zend_string *const_TRANSACTION_INERROR_name = zend_string_init_interned("TRANSACTION_INERROR", sizeof("TRANSACTION_INERROR") - 1, 1); - zend_declare_typed_class_constant(class_entry, const_TRANSACTION_INERROR_name, &const_TRANSACTION_INERROR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRANSACTION_INERROR_name); + zend_string *const_TRANSACTION_INERROR_name = zend_string_init_interned("TRANSACTION_INERROR", sizeof("TRANSACTION_INERROR") - 1, true); + zend_class_constant *const_TRANSACTION_INERROR = zend_declare_typed_class_constant(class_entry, const_TRANSACTION_INERROR_name, &const_TRANSACTION_INERROR_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_INERROR_name, true); zval const_TRANSACTION_UNKNOWN_value; ZVAL_LONG(&const_TRANSACTION_UNKNOWN_value, PGSQL_TRANSACTION_UNKNOWN); - zend_string *const_TRANSACTION_UNKNOWN_name = zend_string_init_interned("TRANSACTION_UNKNOWN", sizeof("TRANSACTION_UNKNOWN") - 1, 1); - zend_declare_typed_class_constant(class_entry, const_TRANSACTION_UNKNOWN_name, &const_TRANSACTION_UNKNOWN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRANSACTION_UNKNOWN_name); + zend_string *const_TRANSACTION_UNKNOWN_name = zend_string_init_interned("TRANSACTION_UNKNOWN", sizeof("TRANSACTION_UNKNOWN") - 1, true); + zend_class_constant *const_TRANSACTION_UNKNOWN = zend_declare_typed_class_constant(class_entry, const_TRANSACTION_UNKNOWN_name, &const_TRANSACTION_UNKNOWN_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_UNKNOWN_name, true); + + + zend_attribute *attribute_Deprecated_const_TRANSACTION_IDLE_0 = zend_add_class_constant_attribute(class_entry, const_TRANSACTION_IDLE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_TRANSACTION_IDLE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_TRANSACTION_IDLE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_TRANSACTION_IDLE_0_arg1_str = zend_string_init("as it has no effect", strlen("as it has no effect"), 1); + ZVAL_STR(&attribute_Deprecated_const_TRANSACTION_IDLE_0->args[1].value, attribute_Deprecated_const_TRANSACTION_IDLE_0_arg1_str); + attribute_Deprecated_const_TRANSACTION_IDLE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_TRANSACTION_ACTIVE_0 = zend_add_class_constant_attribute(class_entry, const_TRANSACTION_ACTIVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_TRANSACTION_ACTIVE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_TRANSACTION_ACTIVE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_TRANSACTION_ACTIVE_0->args[1].value, attribute_Deprecated_const_TRANSACTION_IDLE_0_arg1_str); + attribute_Deprecated_const_TRANSACTION_ACTIVE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_TRANSACTION_INTRANS_0 = zend_add_class_constant_attribute(class_entry, const_TRANSACTION_INTRANS, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_TRANSACTION_INTRANS_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_TRANSACTION_INTRANS_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_TRANSACTION_INTRANS_0->args[1].value, attribute_Deprecated_const_TRANSACTION_IDLE_0_arg1_str); + attribute_Deprecated_const_TRANSACTION_INTRANS_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_TRANSACTION_INERROR_0 = zend_add_class_constant_attribute(class_entry, const_TRANSACTION_INERROR, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_TRANSACTION_INERROR_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_TRANSACTION_INERROR_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_TRANSACTION_INERROR_0->args[1].value, attribute_Deprecated_const_TRANSACTION_IDLE_0_arg1_str); + attribute_Deprecated_const_TRANSACTION_INERROR_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_TRANSACTION_UNKNOWN_0 = zend_add_class_constant_attribute(class_entry, const_TRANSACTION_UNKNOWN, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_TRANSACTION_UNKNOWN_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_const_TRANSACTION_UNKNOWN_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_TRANSACTION_UNKNOWN_0->args[1].value, attribute_Deprecated_const_TRANSACTION_IDLE_0_arg1_str); + attribute_Deprecated_const_TRANSACTION_UNKNOWN_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; } diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 4895463db4b0..3cfb7a3fa01a 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Edin Kadribasic | | Ilia Alshanestsky | @@ -39,8 +37,14 @@ static bool pgsql_handle_in_transaction(pdo_dbh_t *dbh); static char * _pdo_pgsql_trim_message(const char *message, int persistent) { - size_t i = strlen(message)-1; + size_t i = strlen(message); char *tmp; + if (UNEXPECTED(i == 0)) { + tmp = pemalloc(1, persistent); + tmp[0] = '\0'; + return tmp; + } + --i; if (i>1 && (message[i-1] == '\r' || message[i-1] == '\n') && message[i] == '.') { --i; @@ -378,11 +382,15 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo zend_string *quoted_str; pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; size_t tmp_len; + int err; switch (paramtype) { case PDO_PARAM_LOB: /* escapedlen returned by PQescapeBytea() accounts for trailing 0 */ escaped = PQescapeByteaConn(H->server, (unsigned char *)ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), &tmp_len); + if (escaped == NULL) { + return NULL; + } quotedlen = tmp_len + 1; quoted = emalloc(quotedlen + 1); memcpy(quoted+1, escaped, quotedlen-2); @@ -394,7 +402,11 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo default: quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3); quoted[0] = '\''; - quotedlen = PQescapeStringConn(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), NULL); + quotedlen = PQescapeStringConn(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), &err); + if (err) { + efree(quoted); + return NULL; + } quoted[quotedlen + 1] = '\''; quoted[quotedlen + 2] = '\0'; quotedlen += 2; @@ -491,22 +503,18 @@ static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_ case CONNECTION_AUTH_OK: ZVAL_STRINGL(return_value, "Received authentication; waiting for backend start-up to finish.", strlen("Received authentication; waiting for backend start-up to finish.")); break; -#ifdef CONNECTION_SSL_STARTUP case CONNECTION_SSL_STARTUP: ZVAL_STRINGL(return_value, "Negotiating SSL encryption.", strlen("Negotiating SSL encryption.")); break; -#endif case CONNECTION_SETENV: ZVAL_STRINGL(return_value, "Negotiating environment-driven parameter settings.", strlen("Negotiating environment-driven parameter settings.")); break; -#ifdef CONNECTION_CONSUME case CONNECTION_CONSUME: ZVAL_STRINGL(return_value, "Flushing send queue/consuming extra data.", strlen("Flushing send queue/consuming extra data.")); break; -#endif #ifdef CONNECTION_GSS_STARTUP - case CONNECTION_SSL_STARTUP: + case CONNECTION_GSS_STARTUP: ZVAL_STRINGL(return_value, "Negotiating GSSAPI.", strlen("Negotiating GSSAPI.")); break; #endif @@ -1326,6 +1334,20 @@ static const zend_function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, i } } +static void pdo_pgsql_request_shutdown(pdo_dbh_t *dbh) +{ + PGresult *res; + pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; + + if(H->server) { + res = PQexec(H->server, "DISCARD ALL"); + + if(res) { + PQclear(res); + } + } +} + static bool pdo_pgsql_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val) { bool bval; @@ -1369,7 +1391,7 @@ static const struct pdo_dbh_methods pgsql_methods = { pdo_pgsql_get_attribute, pdo_pgsql_check_liveness, /* check_liveness */ pdo_pgsql_get_driver_methods, /* get_driver_methods */ - NULL, + pdo_pgsql_request_shutdown, pgsql_handle_in_transaction, NULL, /* get_gc */ pdo_pgsql_scanner diff --git a/ext/pdo_pgsql/pgsql_driver_arginfo.h b/ext/pdo_pgsql/pgsql_driver_arginfo.h index cd01e2e8e716..9e52f3dbfdbc 100644 --- a/ext/pdo_pgsql/pgsql_driver_arginfo.h +++ b/ext/pdo_pgsql/pgsql_driver_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit pgsql_driver.stub.php instead. * Stub hash: 30c01b4d2e7f836b81a31dc0c1a115883eb41568 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PDO_PGSql_Ext_pgsqlCopyFromArray, 0, 2, _IS_BOOL, 0) diff --git a/ext/pdo_pgsql/pgsql_sql_parser.re b/ext/pdo_pgsql/pgsql_sql_parser.re index caea615c4073..011fce56a1a0 100644 --- a/ext/pdo_pgsql/pgsql_sql_parser.re +++ b/ext/pdo_pgsql/pgsql_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Matteo Beccati | +----------------------------------------------------------------------+ diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 3485bd8df002..1620544556b6 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Edin Kadribasic | | Ilia Alshanestsky | @@ -219,7 +217,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt) PQclear(S->result); /* the cursor was declared correctly */ - S->is_prepared = 1; + S->is_prepared = true; /* fetch to be able to get the number of tuples later, but don't advance the cursor pointer */ spprintf(&q, 0, "FETCH FORWARD 0 FROM %s", S->cursor_name); @@ -240,7 +238,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt) case PGRES_COMMAND_OK: case PGRES_TUPLES_OK: /* it worked */ - S->is_prepared = 1; + S->is_prepared = true; PQclear(S->result); S->result = NULL; break; @@ -526,10 +524,10 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt, ExecStatusType status; switch (ori) { - case PDO_FETCH_ORI_NEXT: spprintf(&ori_str, 0, "NEXT"); break; - case PDO_FETCH_ORI_PRIOR: spprintf(&ori_str, 0, "BACKWARD"); break; - case PDO_FETCH_ORI_FIRST: spprintf(&ori_str, 0, "FIRST"); break; - case PDO_FETCH_ORI_LAST: spprintf(&ori_str, 0, "LAST"); break; + case PDO_FETCH_ORI_NEXT: ori_str = "NEXT"; break; + case PDO_FETCH_ORI_PRIOR: ori_str = "BACKWARD"; break; + case PDO_FETCH_ORI_FIRST: ori_str = "FIRST"; break; + case PDO_FETCH_ORI_LAST: ori_str = "LAST"; break; case PDO_FETCH_ORI_ABS: spprintf(&ori_str, 0, "ABSOLUTE " ZEND_LONG_FMT, offset); break; case PDO_FETCH_ORI_REL: spprintf(&ori_str, 0, "RELATIVE " ZEND_LONG_FMT, offset); break; default: @@ -542,7 +540,9 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt, } spprintf(&q, 0, "FETCH %s FROM %s", ori_str, S->cursor_name); - efree(ori_str); + if (ori == PDO_FETCH_ORI_ABS || ori == PDO_FETCH_ORI_REL) { + efree(ori_str); + } S->result = PQexec(S->H->server, q); efree(q); status = PQresultStatus(S->result); @@ -571,6 +571,12 @@ static int pgsql_stmt_fetch(pdo_stmt_t *stmt, } S->result = PQgetResult(S->H->server); + if (!S->result) { + S->is_running_unbuffered = false; + stmt->row_count = 0; + S->current_row = 0; + return 0; + } status = PQresultStatus(S->result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK && status != PGRES_SINGLE_TUPLE) { diff --git a/ext/pdo_pgsql/php_pdo_pgsql.h b/ext/pdo_pgsql/php_pdo_pgsql.h index fa28214f71a7..345535108cb1 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql.h +++ b/ext/pdo_pgsql/php_pdo_pgsql.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index 881b4e704650..47c9223540ad 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Edin Kadribasic | | Ilia Alshanestsky | diff --git a/ext/pdo_pgsql/tests/bug68199.phpt b/ext/pdo_pgsql/tests/bug68199.phpt index 55a83a2bcddf..8ec73634a07e 100644 --- a/ext/pdo_pgsql/tests/bug68199.phpt +++ b/ext/pdo_pgsql/tests/bug68199.phpt @@ -80,26 +80,41 @@ var_dump($notify[2]); var_dump($db->pgsqlGetNotify()); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::pgsqlGetPid() is deprecated since 8.5, use Pdo\Pgsql::getPid() instead in %s on line %d bool(true) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(false) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(false) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(3) string(16) "channel_bug68199" bool(true) string(7) "payload" + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(3) string(16) "channel_bug68199" bool(true) string(7) "payload" + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(3) string(16) "channel_bug68199" bool(true) string(7) "payload" + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(3) string(16) "channel_bug68199" bool(true) string(7) "payload" + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(6) string(16) "channel_bug68199" bool(true) @@ -107,4 +122,6 @@ string(7) "payload" string(16) "channel_bug68199" bool(true) string(7) "payload" + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(false) diff --git a/ext/pdo_pgsql/tests/bug68371.phpt b/ext/pdo_pgsql/tests/bug68371.phpt index 6569abf3071f..13fd1913274d 100644 --- a/ext/pdo_pgsql/tests/bug68371.phpt +++ b/ext/pdo_pgsql/tests/bug68371.phpt @@ -18,7 +18,7 @@ $pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $attrs = array( // Extensive test: default value and set+get values PDO::ATTR_EMULATE_PREPARES => array(null, true, false), - PDO::PGSQL_ATTR_DISABLE_PREPARES => array(null, true, false), + Pdo\Pgsql::ATTR_DISABLE_PREPARES => array(null, true, false), // Just test the default PDO::ATTR_AUTOCOMMIT => array(null), diff --git a/ext/pdo_pgsql/tests/bug73959.phpt b/ext/pdo_pgsql/tests/bug73959.phpt index 34b68f9825c7..918743ff4383 100644 --- a/ext/pdo_pgsql/tests/bug73959.phpt +++ b/ext/pdo_pgsql/tests/bug73959.phpt @@ -15,7 +15,7 @@ require __DIR__ . '/config.inc'; $db = PDOTest::test_factory(__DIR__ . '/common.phpt'); $db->setAttribute(PDO::ATTR_PERSISTENT, false); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$db->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true); +$db->setAttribute(Pdo\Pgsql::ATTR_DISABLE_PREPARES, true); try { $db->lastInsertId('nonexistent_seq'); diff --git a/ext/pdo_pgsql/tests/copy_from.phpt b/ext/pdo_pgsql/tests/copy_from.phpt index 8480c2961a23..ded3efd9cad2 100644 --- a/ext/pdo_pgsql/tests/copy_from.phpt +++ b/ext/pdo_pgsql/tests/copy_from.phpt @@ -134,6 +134,8 @@ $db->query('DROP TABLE IF EXISTS test_copy_from CASCADE'); --EXPECTF-- Preparing test file and array for CopyFrom tests Testing pgsqlCopyFromArray() with default parameters + +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d bool(true) array(6) { ["a"]=> @@ -178,6 +180,8 @@ array(6) { NULL } Testing pgsqlCopyFromArray() with different field separator and not null indicator + +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d bool(true) array(6) { ["a"]=> @@ -222,6 +226,8 @@ array(6) { NULL } Testing pgsqlCopyFromArray() with only selected fields + +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d bool(true) array(6) { ["a"]=> @@ -266,8 +272,12 @@ array(6) { NULL } Testing pgsqlCopyFromArray() with error + +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyFromFile() with default parameters + +Deprecated: Method PDO::pgsqlCopyFromFile() is deprecated since 8.5, use Pdo\Pgsql::copyFromFile() instead in %s on line %d bool(true) array(6) { ["a"]=> @@ -312,6 +322,8 @@ array(6) { NULL } Testing pgsqlCopyFromFile() with different field separator and not null indicator + +Deprecated: Method PDO::pgsqlCopyFromFile() is deprecated since 8.5, use Pdo\Pgsql::copyFromFile() instead in %s on line %d bool(true) array(6) { ["a"]=> @@ -356,6 +368,8 @@ array(6) { NULL } Testing pgsqlCopyFromFile() with only selected fields + +Deprecated: Method PDO::pgsqlCopyFromFile() is deprecated since 8.5, use Pdo\Pgsql::copyFromFile() instead in %s on line %d bool(true) array(6) { ["a"]=> @@ -400,6 +414,10 @@ array(6) { NULL } Testing pgsqlCopyFromFile() with error + +Deprecated: Method PDO::pgsqlCopyFromFile() is deprecated since 8.5, use Pdo\Pgsql::copyFromFile() instead in %s on line %d Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyFromFile() with non existing file + +Deprecated: Method PDO::pgsqlCopyFromFile() is deprecated since 8.5, use Pdo\Pgsql::copyFromFile() instead in %s on line %d Exception: SQLSTATE[HY000]: General error: 7 Unable to open the file diff --git a/ext/pdo_pgsql/tests/copy_from_generator.phpt b/ext/pdo_pgsql/tests/copy_from_generator.phpt index a058cb4ff430..6bfd39a7f238 100644 --- a/ext/pdo_pgsql/tests/copy_from_generator.phpt +++ b/ext/pdo_pgsql/tests/copy_from_generator.phpt @@ -41,7 +41,8 @@ require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; $db = PDOTest::test_factory(__DIR__ . '/common.phpt'); $db->query('DROP TABLE IF EXISTS test_copy_from_generator CASCADE'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d array ( 0 => 1, 1 => 1, diff --git a/ext/pdo_pgsql/tests/copy_from_iterator.phpt b/ext/pdo_pgsql/tests/copy_from_iterator.phpt index b507af891462..bb178d0d66b8 100644 --- a/ext/pdo_pgsql/tests/copy_from_iterator.phpt +++ b/ext/pdo_pgsql/tests/copy_from_iterator.phpt @@ -61,8 +61,11 @@ require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; $db = PDOTest::test_factory(__DIR__ . '/common.phpt'); $db->query('DROP TABLE IF EXISTS test_copy_from_traversable CASCADE'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d PDO::pgsqlCopyFromArray(): Argument #2 ($rows) must be of type Traversable|array, stdClass given + +Deprecated: Method PDO::pgsqlCopyFromArray() is deprecated since 8.5, use Pdo\Pgsql::copyFromArray() instead in %s on line %d array ( 0 => 1, 1 => 1, diff --git a/ext/pdo_pgsql/tests/copy_to.phpt b/ext/pdo_pgsql/tests/copy_to.phpt index 0f2d8cd7e9c7..02707006d2a8 100644 --- a/ext/pdo_pgsql/tests/copy_to.phpt +++ b/ext/pdo_pgsql/tests/copy_to.phpt @@ -87,6 +87,8 @@ $db->exec('DROP TABLE test_copy_to'); --EXPECTF-- Preparing test table for CopyTo tests Testing pgsqlCopyToArray() with default parameters + +Deprecated: Method PDO::pgsqlCopyToArray() is deprecated since 8.5, use Pdo\Pgsql::copyToArray() instead in %s on line %d array(3) { [0]=> string(19) "0 test insert 0 \N @@ -99,6 +101,8 @@ array(3) { " } Testing pgsqlCopyToArray() with different field separator and not null indicator + +Deprecated: Method PDO::pgsqlCopyToArray() is deprecated since 8.5, use Pdo\Pgsql::copyToArray() instead in %s on line %d array(3) { [0]=> string(21) "0;test insert 0;NULL @@ -111,6 +115,8 @@ array(3) { " } Testing pgsqlCopyToArray() with only selected fields + +Deprecated: Method PDO::pgsqlCopyToArray() is deprecated since 8.5, use Pdo\Pgsql::copyToArray() instead in %s on line %d array(3) { [0]=> string(7) "0;NULL @@ -123,23 +129,35 @@ array(3) { " } Testing pgsqlCopyToArray() with error + +Deprecated: Method PDO::pgsqlCopyToArray() is deprecated since 8.5, use Pdo\Pgsql::copyToArray() instead in %s on line %d Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyToFile() with default parameters + +Deprecated: Method PDO::pgsqlCopyToFile() is deprecated since 8.5, use Pdo\Pgsql::copyToFile() instead in %s on line %d bool(true) 0 test insert 0 \N 1 test insert 1 \N 2 test insert 2 \N Testing pgsqlCopyToFile() with different field separator and not null indicator + +Deprecated: Method PDO::pgsqlCopyToFile() is deprecated since 8.5, use Pdo\Pgsql::copyToFile() instead in %s on line %d bool(true) 0;test insert 0;NULL 1;test insert 1;NULL 2;test insert 2;NULL Testing pgsqlCopyToFile() with only selected fields + +Deprecated: Method PDO::pgsqlCopyToFile() is deprecated since 8.5, use Pdo\Pgsql::copyToFile() instead in %s on line %d bool(true) 0;NULL 1;NULL 2;NULL Testing pgsqlCopyToFile() with error + +Deprecated: Method PDO::pgsqlCopyToFile() is deprecated since 8.5, use Pdo\Pgsql::copyToFile() instead in %s on line %d Exception: SQLSTATE[42P01]: Undefined table: 7 %s: %stest_error%s Testing pgsqlCopyToFile() to unwritable file + +Deprecated: Method PDO::pgsqlCopyToFile() is deprecated since 8.5, use Pdo\Pgsql::copyToFile() instead in %s on line %d Exception: SQLSTATE[HY000]: General error: 7 Unable to open the file for writing diff --git a/ext/pdo_pgsql/tests/disable_prepares.phpt b/ext/pdo_pgsql/tests/disable_prepares.phpt index 58f3a4b00c1f..b184e9bc6db6 100644 --- a/ext/pdo_pgsql/tests/disable_prepares.phpt +++ b/ext/pdo_pgsql/tests/disable_prepares.phpt @@ -28,7 +28,7 @@ $stmt->execute(); $first = $stmt->fetchAll(); $stmt3 = $db->prepare("SELECT (?)::int4", array( - PDO::PGSQL_ATTR_DISABLE_PREPARES => true)); + Pdo\Pgsql::ATTR_DISABLE_PREPARES => true)); $stmt3->execute(array(3)); var_dump($stmt3->fetch()); $stmt3->execute(array(4)); diff --git a/ext/pdo_pgsql/tests/getnotify.phpt b/ext/pdo_pgsql/tests/getnotify.phpt index fca15879d19d..fe6a34b7f95e 100644 --- a/ext/pdo_pgsql/tests/getnotify.phpt +++ b/ext/pdo_pgsql/tests/getnotify.phpt @@ -84,29 +84,50 @@ var_dump($diff < 1 || abs(1 - abs($diff)) < .05); var_dump(count($notify)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::pgsqlGetPid() is deprecated since 8.5, use Pdo\Pgsql::getPid() instead in %s on line %d bool(true) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(false) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(false) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(2) string(17) "channel_getnotify" bool(true) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(2) string(17) "channel_getnotify" bool(true) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(2) string(17) "channel_getnotify" bool(true) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(2) string(17) "channel_getnotify" bool(true) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d int(4) string(17) "channel_getnotify" bool(true) string(17) "channel_getnotify" bool(true) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(false) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(true) bool(false) + +Deprecated: Method PDO::pgsqlGetNotify() is deprecated since 8.5, use Pdo\Pgsql::getNotify() instead in %s on line %d bool(true) int(2) diff --git a/ext/pdo_pgsql/tests/gh15287.phpt b/ext/pdo_pgsql/tests/gh15287.phpt index 72bcc44b363b..821c22a8f1c5 100644 --- a/ext/pdo_pgsql/tests/gh15287.phpt +++ b/ext/pdo_pgsql/tests/gh15287.phpt @@ -75,8 +75,8 @@ for ($i = -1; ++$i < 5;) { while (($re = $stmt->fetch())) { $res[] = $re; // Memory introspection relies on an optionally-compiled constant. - if (defined('PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE')) { - $mem = $stmt->getAttribute(PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE); + if (defined('Pdo\Pgsql::ATTR_RESULT_MEMORY_SIZE')) { + $mem = $stmt->getAttribute(Pdo\Pgsql::ATTR_RESULT_MEMORY_SIZE); } else { // If not there emulate a return value which validates our test. $mem = $lazy ? 0 : 1; diff --git a/ext/pdo_pgsql/tests/gh21683.phpt b/ext/pdo_pgsql/tests/gh21683.phpt new file mode 100644 index 000000000000..bd941511767a --- /dev/null +++ b/ext/pdo_pgsql/tests/gh21683.phpt @@ -0,0 +1,48 @@ +--TEST-- +PDO PgSQL single-row mode (ATTR_PREFETCH=0) on empty result set +--EXTENSIONS-- +pdo +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$pdo->setAttribute(PDO::ATTR_PREFETCH, 0); + +$pdo->exec("CREATE TEMP TABLE empty_t (id int, val text)"); + +echo "=== query / fetch ===\n"; +$stmt = $pdo->query("SELECT * FROM empty_t"); +var_dump($stmt->fetch()); + +echo "=== prepare / fetchAll ===\n"; +$stmt = $pdo->prepare("SELECT * FROM empty_t"); +$stmt->execute(); +var_dump($stmt->fetchAll()); + +echo "=== connection still works ===\n"; +$stmt = $pdo->query("SELECT 1 AS alive"); +var_dump($stmt->fetch(PDO::FETCH_ASSOC)); + +echo "Done\n"; +?> +--EXPECT-- +=== query / fetch === +bool(false) +=== prepare / fetchAll === +array(0) { +} +=== connection still works === +array(1) { + ["alive"]=> + string(1) "1" +} +Done diff --git a/ext/pdo_pgsql/tests/gh9411.phpt b/ext/pdo_pgsql/tests/gh9411.phpt index 5fe19c3560d4..2e8eadf8d3e0 100644 --- a/ext/pdo_pgsql/tests/gh9411.phpt +++ b/ext/pdo_pgsql/tests/gh9411.phpt @@ -34,9 +34,18 @@ var_dump($lob = $db->pgsqlLOBOpen($oid, 'wb')); var_dump(fgets($lob)); ?> --EXPECTF-- +Deprecated: Method PDO::pgsqlLOBCreate() is deprecated since 8.5, use Pdo\Pgsql::lobCreate() instead in %s on line %d + +Deprecated: Method PDO::pgsqlLOBOpen() is deprecated since 8.5, use Pdo\Pgsql::lobOpen() instead in %s on line %d resource(%d) of type (stream) resource(%d) of type (Unknown) + +Deprecated: Method PDO::pgsqlLOBCreate() is deprecated since 8.5, use Pdo\Pgsql::lobCreate() instead in %s on line %d + +Deprecated: Method PDO::pgsqlLOBOpen() is deprecated since 8.5, use Pdo\Pgsql::lobOpen() instead in %s on line %d resource(%d) of type (stream) resource(%d) of type (Unknown) + +Deprecated: Method PDO::pgsqlLOBOpen() is deprecated since 8.5, use Pdo\Pgsql::lobOpen() instead in %s on line %d resource(%d) of type (stream) string(4) "test" diff --git a/ext/pdo_pgsql/tests/ghsa-8xr5-qppj-gvwj.phpt b/ext/pdo_pgsql/tests/ghsa-8xr5-qppj-gvwj.phpt new file mode 100644 index 000000000000..736354cab13c --- /dev/null +++ b/ext/pdo_pgsql/tests/ghsa-8xr5-qppj-gvwj.phpt @@ -0,0 +1,28 @@ +--TEST-- +#GHSA-8xr5-qppj-gvwj: NULL Pointer Derefernce for failed user input quoting +--EXTENSIONS-- +pdo +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); + +$sql = "SELECT * FROM users where username = :username"; +$stmt = $db->prepare($sql); + +$p1 = "alice\x99"; +var_dump($stmt->execute(['username' => $p1])); + +?> +--EXPECT-- +bool(false) diff --git a/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt b/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt new file mode 100644 index 000000000000..8566a26753b4 --- /dev/null +++ b/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt @@ -0,0 +1,24 @@ +--TEST-- +#GHSA-hrwm-9436-5mv3: pdo_pgsql extension does not check for errors during escaping +--EXTENSIONS-- +pdo +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$invalid = "ABC\xff\x30';"; +var_dump($db->quote($invalid)); + +?> +--EXPECT-- +bool(false) diff --git a/ext/pdo_pgsql/tests/is_in_transaction.phpt b/ext/pdo_pgsql/tests/is_in_transaction.phpt index 440044f66a57..982357db9210 100644 --- a/ext/pdo_pgsql/tests/is_in_transaction.phpt +++ b/ext/pdo_pgsql/tests/is_in_transaction.phpt @@ -19,7 +19,7 @@ $db->exec('CREATE TABLE test_is_in_transaction (a integer not null primary key, $db->beginTransaction(); try { -echo "Test PDO::PGSQL_TRANSACTION_INTRANS\n"; +echo "Test Pdo\Pgsql::TRANSACTION_INTRANS\n"; var_dump($db->inTransaction()); $stmt = $db->prepare("INSERT INTO test_is_in_transaction (a, b) values (?, ?)"); @@ -29,7 +29,7 @@ $stmt->execute(); $db->commit(); -echo "Test PDO::PGSQL_TRANSACTION_IDLE\n"; +echo "Test Pdo\Pgsql::TRANSACTION_IDLE\n"; var_dump($db->inTransaction()); $db->beginTransaction(); @@ -40,13 +40,13 @@ $stmt->bindValue(1, "error"); $stmt->bindValue(2, "test insert"); $stmt->execute(); } catch (Exception $e) { - /* We catch the exception because the execute will give error and we must test the PDO::PGSQL_TRANSACTION_ERROR */ - echo "Test PDO::PGSQL_TRANSACTION_INERROR\n"; + /* We catch the exception because the execute will give error and we must test the Pdo\Pgsql::TRANSACTION_ERROR */ + echo "Test Pdo\Pgsql::TRANSACTION_INERROR\n"; var_dump($db->inTransaction()); $db->rollBack(); } -echo "Test PDO::PGSQL_TRANSACTION_IDLE\n"; +echo "Test Pdo\Pgsql::TRANSACTION_IDLE\n"; var_dump($db->inTransaction()); } catch (Exception $e) { @@ -62,11 +62,11 @@ $db = PDOTest::test_factory(__DIR__ . '/common.phpt'); $db->exec('DROP TABLE test_is_in_transaction'); ?> --EXPECT-- -Test PDO::PGSQL_TRANSACTION_INTRANS +Test Pdo\Pgsql::TRANSACTION_INTRANS bool(true) -Test PDO::PGSQL_TRANSACTION_IDLE +Test Pdo\Pgsql::TRANSACTION_IDLE bool(false) -Test PDO::PGSQL_TRANSACTION_INERROR +Test Pdo\Pgsql::TRANSACTION_INERROR bool(true) -Test PDO::PGSQL_TRANSACTION_IDLE +Test Pdo\Pgsql::TRANSACTION_IDLE bool(false) diff --git a/ext/pdo_pgsql/tests/large_objects.phpt b/ext/pdo_pgsql/tests/large_objects.phpt index ff3248fbdb34..86149ce1b6a8 100644 --- a/ext/pdo_pgsql/tests/large_objects.phpt +++ b/ext/pdo_pgsql/tests/large_objects.phpt @@ -83,7 +83,10 @@ require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; $db = PDOTest::test_factory(__DIR__ . '/common.phpt'); $db->exec('DROP TABLE test_large_objects'); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::pgsqlLOBCreate() is deprecated since 8.5, use Pdo\Pgsql::lobCreate() instead in %s on line %d + +Deprecated: Method PDO::pgsqlLOBOpen() is deprecated since 8.5, use Pdo\Pgsql::lobOpen() instead in %s on line %d Fetching: int(1) string(11) "Hello dude @@ -97,3 +100,5 @@ Fetching NO bind: int(1) bool(true) Fetched! + +Deprecated: Method PDO::pgsqlLOBUnlink() is deprecated since 8.5, use Pdo\Pgsql::lobUnlink() instead in %s on line %d diff --git a/ext/pdo_pgsql/tests/php_8.5_deprecations.phpt b/ext/pdo_pgsql/tests/php_8.5_deprecations.phpt new file mode 100644 index 000000000000..816850853e14 --- /dev/null +++ b/ext/pdo_pgsql/tests/php_8.5_deprecations.phpt @@ -0,0 +1,15 @@ +--TEST-- +PDO_pgsql: PHP 8.5 deprecations +--EXTENSIONS-- +pdo_pgsql +--FILE-- + +--EXPECTF-- +Deprecated: Constant PDO::PGSQL_ATTR_DISABLE_PREPARES is deprecated since 8.5, use Pdo\Pgsql::ATTR_DISABLE_PREPARES instead in %s on line %d +int(1000) diff --git a/ext/pdo_pgsql/tests/session_state_reset.phpt b/ext/pdo_pgsql/tests/session_state_reset.phpt new file mode 100644 index 000000000000..ad892bb0da52 --- /dev/null +++ b/ext/pdo_pgsql/tests/session_state_reset.phpt @@ -0,0 +1,55 @@ +--TEST-- +Persistent connections: session state reset when performing disconnect-equivalent processing (general case) +--EXTENSIONS-- +pdo_pgsql +--SKIPIF-- + +--FILE-- + true])); + +require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; + +$pdo1 = PDOTest::test_factory(__DIR__ . '/common.phpt'); + +$pid1 = (int)$pdo1 + ->query('select pg_backend_pid()::int;') + ->fetchColumn(0); + +$defaultValue = (int)$pdo1 + ->query('show log_min_duration_statement;') + ->fetchColumn(0); + +$setValue = $defaultValue + 1; + +$pdo1->exec("set log_min_duration_statement = {$setValue};"); + +$pdo1 = null; + +$pdo2 = PDOTest::test_factory(__DIR__ . '/common.phpt'); + +$pid2 = (int)$pdo2 + ->query('select pg_backend_pid()::int;') + ->fetchColumn(0); + +assert($pid1 === $pid2); + +$expectedValue = (int)$pdo2 + ->query('show log_min_duration_statement;') + ->fetchColumn(0); + +echo "defaultValue: {$defaultValue}\n"; +echo "setValue: {$setValue}\n"; +echo "expectedValue: {$expectedValue}\n"; +echo "expected value should be reset to default: " . (($expectedValue === $defaultValue) ? 'success' : 'failure') . "\n"; + +?> +--EXPECTF-- +defaultValue: %i +setValue: %d +expectedValue: %i +expected value should be reset to default: success diff --git a/ext/pdo_pgsql/tests/session_state_reset_advisory_lock.phpt b/ext/pdo_pgsql/tests/session_state_reset_advisory_lock.phpt new file mode 100644 index 000000000000..3435f6b7b402 --- /dev/null +++ b/ext/pdo_pgsql/tests/session_state_reset_advisory_lock.phpt @@ -0,0 +1,51 @@ +--TEST-- +Persistent connections: session state reset when performing disconnect-equivalent processing (advisory lock case) +--EXTENSIONS-- +pdo_pgsql +--SKIPIF-- + +--FILE-- + true])); + +require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; + +$pdo1 = PDOTest::test_factory(__DIR__ . '/common.phpt'); + +$pid1 = (int)$pdo1 + ->query('select pg_backend_pid()::int;') + ->fetchColumn(0); + +$lockResult1 = (bool)$pdo1 + ->query('select pg_try_advisory_lock(42)::int;') + ->fetchColumn(0); + +$pdo1 = null; + +$dsn = getenv('PDO_PGSQL_TEST_DSN'); +$dsn .= ';'; +putenv('PDO_PGSQL_TEST_DSN='.$dsn); + +$pdo2 = PDOTest::test_factory(__DIR__ . '/common.phpt'); + +$pid2 = (int)$pdo2 + ->query('select pg_backend_pid()::int;') + ->fetchColumn(0); + +assert($pid1 !== $pid2); + +$lockResult2 = (bool)$pdo2 + ->query('select pg_try_advisory_lock(42)::int;') + ->fetchColumn(0); + +echo "lock1: " . ($lockResult1 ? 'success' : 'failure') . "\n"; +echo "lock2: " . ($lockResult2 ? 'success' : 'failure') . "\n"; + +?> +--EXPECT-- +lock1: success +lock2: success diff --git a/ext/pdo_pgsql/tests/session_state_reset_after_interrupted.phpt b/ext/pdo_pgsql/tests/session_state_reset_after_interrupted.phpt new file mode 100644 index 000000000000..fdafe8a00fc3 --- /dev/null +++ b/ext/pdo_pgsql/tests/session_state_reset_after_interrupted.phpt @@ -0,0 +1,52 @@ +--TEST-- +Persistent connections: session state reset after backend termination (interrupted case) +--EXTENSIONS-- +pdo_pgsql +--SKIPIF-- + +--FILE-- + true])); + +require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc'; + +$pdo1 = PDOTest::test_factory(__DIR__ . '/common.phpt'); + +$pid1 = (int)$pdo1 + ->query('select pg_backend_pid()::int;') + ->fetchColumn(0); + +$pid1 = (int)$pdo1 + ->query('select pg_backend_pid()::int;') + ->fetchColumn(0); + +$dsn = getenv('PDO_PGSQL_TEST_DSN'); +$dsn .= ';'; +putenv('PDO_PGSQL_TEST_DSN='.$dsn); + +$pdo2 = PDOTest::test_factory(__DIR__ . '/common.phpt'); + +$pid2 = (int)$pdo2 + ->query('select pg_backend_pid()::int;') + ->fetchColumn(0); + +assert($pid1 !== $pid2); + +$terminateResult = (bool)$pdo2 + ->query("select pg_terminate_backend({$pid1})::int") + ->fetchColumn(0); + +// Disconnect after being terminated by another connection +$pdo1 = null; + +echo 'pid of pdo1: ' . $pid1 . "\n"; +echo 'terminate result of pdo1 by pdo2: ' . ($terminateResult ? 'success' : 'failure') . "\n"; + +?> +--EXPECTF-- +pid of pdo1: %d +terminate result of pdo1 by pdo2: success diff --git a/ext/pdo_pgsql/tests/transations_deprecations.phpt b/ext/pdo_pgsql/tests/transations_deprecations.phpt new file mode 100644 index 000000000000..7aa51b47f769 --- /dev/null +++ b/ext/pdo_pgsql/tests/transations_deprecations.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test PDO::PGSQL_TRANSACTION* constants. +--EXTENSIONS-- +pdo +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Deprecated: Constant PDO::PGSQL_TRANSACTION_IDLE is deprecated since 8.5 in %s on line %d +int(0) + +Deprecated: Constant PDO::PGSQL_TRANSACTION_ACTIVE is deprecated since 8.5 in %s on line %d +int(1) + +Deprecated: Constant PDO::PGSQL_TRANSACTION_INTRANS is deprecated since 8.5 in %s on line %d +int(2) + +Deprecated: Constant PDO::PGSQL_TRANSACTION_INERROR is deprecated since 8.5 in %s on line %d +int(3) + +Deprecated: Constant PDO::PGSQL_TRANSACTION_UNKNOWN is deprecated since 8.5 in %s on line %d +int(4) diff --git a/ext/pdo_sqlite/config.m4 b/ext/pdo_sqlite/config.m4 index eaaee6182bfe..7b7700481a30 100644 --- a/ext/pdo_sqlite/config.m4 +++ b/ext/pdo_sqlite/config.m4 @@ -9,12 +9,6 @@ if test "$PHP_PDO_SQLITE" != "no"; then PHP_SETUP_SQLITE([PDO_SQLITE_SHARED_LIBADD]) - PHP_CHECK_LIBRARY([sqlite3], [sqlite3_close_v2], - [AC_DEFINE([HAVE_SQLITE3_CLOSE_V2], [1], - [Define to 1 if SQLite library has the 'sqlite3_close_v2' function.])], - [], - [$PDO_SQLITE_SHARED_LIBADD]) - PHP_CHECK_LIBRARY([sqlite3], [sqlite3_column_table_name], [AC_DEFINE([HAVE_SQLITE3_COLUMN_TABLE_NAME], [1], [Define to 1 if SQLite library was compiled with the diff --git a/ext/pdo_sqlite/config.w32 b/ext/pdo_sqlite/config.w32 index d1f94438925d..d6162278abed 100644 --- a/ext/pdo_sqlite/config.w32 +++ b/ext/pdo_sqlite/config.w32 @@ -8,7 +8,6 @@ if (PHP_PDO_SQLITE != "no") { ADD_EXTENSION_DEP('pdo_sqlite', 'pdo'); AC_DEFINE("HAVE_SQLITE3_COLUMN_TABLE_NAME", 1, "Define to 1 if SQLite library was compiled with the SQLITE_ENABLE_COLUMN_METADATA and has the 'sqlite3_column_table_name' function."); - AC_DEFINE("HAVE_SQLITE3_CLOSE_V2", 1, "Define to 1 if SQLite library has the 'sqlite3_close_v2' function."); ADD_MAKEFILE_FRAGMENT(); } else { WARNING("pdo_sqlite not enabled; libraries and/or headers not found"); diff --git a/ext/pdo_sqlite/pdo_sqlite.c b/ext/pdo_sqlite/pdo_sqlite.c index 023e35a2bc33..0e7e02df46a4 100644 --- a/ext/pdo_sqlite/pdo_sqlite.c +++ b/ext/pdo_sqlite/pdo_sqlite.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -404,19 +402,22 @@ PHP_METHOD(Pdo_Sqlite, createCollation) pdo_sqlite_create_collation_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_sqlite_collation_callback); } +#define REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, value) \ + REGISTER_PDO_CLASS_CONST_LONG_DEPRECATED_ALIAS_85(base_name, "SQLITE_", "Pdo\\Sqlite::", value) + /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(pdo_sqlite) { #ifdef SQLITE_DETERMINISTIC - REGISTER_PDO_CLASS_CONST_LONG("SQLITE_DETERMINISTIC", (zend_long)SQLITE_DETERMINISTIC); + REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("DETERMINISTIC", (zend_long)SQLITE_DETERMINISTIC); #endif - REGISTER_PDO_CLASS_CONST_LONG("SQLITE_ATTR_OPEN_FLAGS", (zend_long)PDO_SQLITE_ATTR_OPEN_FLAGS); - REGISTER_PDO_CLASS_CONST_LONG("SQLITE_OPEN_READONLY", (zend_long)SQLITE_OPEN_READONLY); - REGISTER_PDO_CLASS_CONST_LONG("SQLITE_OPEN_READWRITE", (zend_long)SQLITE_OPEN_READWRITE); - REGISTER_PDO_CLASS_CONST_LONG("SQLITE_OPEN_CREATE", (zend_long)SQLITE_OPEN_CREATE); - REGISTER_PDO_CLASS_CONST_LONG("SQLITE_ATTR_READONLY_STATEMENT", (zend_long)PDO_SQLITE_ATTR_READONLY_STATEMENT); - REGISTER_PDO_CLASS_CONST_LONG("SQLITE_ATTR_EXTENDED_RESULT_CODES", (zend_long)PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES); + REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_OPEN_FLAGS", (zend_long)PDO_SQLITE_ATTR_OPEN_FLAGS); + REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("OPEN_READONLY", (zend_long)SQLITE_OPEN_READONLY); + REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("OPEN_READWRITE", (zend_long)SQLITE_OPEN_READWRITE); + REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("OPEN_CREATE", (zend_long)SQLITE_OPEN_CREATE); + REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_READONLY_STATEMENT", (zend_long)PDO_SQLITE_ATTR_READONLY_STATEMENT); + REGISTER_PDO_SQLITE_CLASS_CONST_LONG_DEPRECATED_ALIAS_85("ATTR_EXTENDED_RESULT_CODES", (zend_long)PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES); pdosqlite_ce = register_class_Pdo_Sqlite(pdo_dbh_ce); pdosqlite_ce->create_object = pdo_dbh_new; diff --git a/ext/pdo_sqlite/pdo_sqlite.stub.php b/ext/pdo_sqlite/pdo_sqlite.stub.php index 4af2d8c55260..53f1ceba427b 100644 --- a/ext/pdo_sqlite/pdo_sqlite.stub.php +++ b/ext/pdo_sqlite/pdo_sqlite.stub.php @@ -39,6 +39,13 @@ class Sqlite extends \PDO /** @cvalue PDO_SQLITE_ATTR_EXPLAIN_STATEMENT */ public const int ATTR_EXPLAIN_STATEMENT = UNKNOWN; + /** @cvalue PDO_SQLITE_ATTR_TRANSACTION_MODE */ + public const int ATTR_TRANSACTION_MODE = UNKNOWN; + + public const int TRANSACTION_MODE_DEFERRED = 0; + public const int TRANSACTION_MODE_IMMEDIATE = 1; + public const int TRANSACTION_MODE_EXCLUSIVE = 2; + #if SQLITE_VERSION_NUMBER >= 3043000 public const int EXPLAIN_MODE_PREPARED = 0; public const int EXPLAIN_MODE_EXPLAIN = 1; diff --git a/ext/pdo_sqlite/pdo_sqlite_arginfo.h b/ext/pdo_sqlite/pdo_sqlite_arginfo.h index e2cd71723706..73a9158301c0 100644 --- a/ext/pdo_sqlite/pdo_sqlite_arginfo.h +++ b/ext/pdo_sqlite/pdo_sqlite_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: c1d4ef325ecb8c8cb312910e8091ca003dc2603a */ +/* This is a generated file, edit pdo_sqlite.stub.php instead. + * Stub hash: 721c46905fa8fb1e18d7196ed85c37f56049ea33 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Pdo_Sqlite_createAggregate, 0, 3, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) @@ -69,96 +69,120 @@ static zend_class_entry *register_class_Pdo_Sqlite(zend_class_entry *class_entry zval const_DETERMINISTIC_value; ZVAL_LONG(&const_DETERMINISTIC_value, SQLITE_DETERMINISTIC); - zend_string *const_DETERMINISTIC_name = zend_string_init_interned("DETERMINISTIC", sizeof("DETERMINISTIC") - 1, 1); + zend_string *const_DETERMINISTIC_name = zend_string_init_interned("DETERMINISTIC", sizeof("DETERMINISTIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_DETERMINISTIC_name, &const_DETERMINISTIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DETERMINISTIC_name); + zend_string_release_ex(const_DETERMINISTIC_name, true); #endif zval const_OPEN_READONLY_value; ZVAL_LONG(&const_OPEN_READONLY_value, SQLITE_OPEN_READONLY); - zend_string *const_OPEN_READONLY_name = zend_string_init_interned("OPEN_READONLY", sizeof("OPEN_READONLY") - 1, 1); + zend_string *const_OPEN_READONLY_name = zend_string_init_interned("OPEN_READONLY", sizeof("OPEN_READONLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_OPEN_READONLY_name, &const_OPEN_READONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OPEN_READONLY_name); + zend_string_release_ex(const_OPEN_READONLY_name, true); zval const_OPEN_READWRITE_value; ZVAL_LONG(&const_OPEN_READWRITE_value, SQLITE_OPEN_READWRITE); - zend_string *const_OPEN_READWRITE_name = zend_string_init_interned("OPEN_READWRITE", sizeof("OPEN_READWRITE") - 1, 1); + zend_string *const_OPEN_READWRITE_name = zend_string_init_interned("OPEN_READWRITE", sizeof("OPEN_READWRITE") - 1, true); zend_declare_typed_class_constant(class_entry, const_OPEN_READWRITE_name, &const_OPEN_READWRITE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OPEN_READWRITE_name); + zend_string_release_ex(const_OPEN_READWRITE_name, true); zval const_OPEN_CREATE_value; ZVAL_LONG(&const_OPEN_CREATE_value, SQLITE_OPEN_CREATE); - zend_string *const_OPEN_CREATE_name = zend_string_init_interned("OPEN_CREATE", sizeof("OPEN_CREATE") - 1, 1); + zend_string *const_OPEN_CREATE_name = zend_string_init_interned("OPEN_CREATE", sizeof("OPEN_CREATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_OPEN_CREATE_name, &const_OPEN_CREATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OPEN_CREATE_name); + zend_string_release_ex(const_OPEN_CREATE_name, true); zval const_ATTR_OPEN_FLAGS_value; ZVAL_LONG(&const_ATTR_OPEN_FLAGS_value, PDO_SQLITE_ATTR_OPEN_FLAGS); - zend_string *const_ATTR_OPEN_FLAGS_name = zend_string_init_interned("ATTR_OPEN_FLAGS", sizeof("ATTR_OPEN_FLAGS") - 1, 1); + zend_string *const_ATTR_OPEN_FLAGS_name = zend_string_init_interned("ATTR_OPEN_FLAGS", sizeof("ATTR_OPEN_FLAGS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_OPEN_FLAGS_name, &const_ATTR_OPEN_FLAGS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_OPEN_FLAGS_name); + zend_string_release_ex(const_ATTR_OPEN_FLAGS_name, true); zval const_ATTR_READONLY_STATEMENT_value; ZVAL_LONG(&const_ATTR_READONLY_STATEMENT_value, PDO_SQLITE_ATTR_READONLY_STATEMENT); - zend_string *const_ATTR_READONLY_STATEMENT_name = zend_string_init_interned("ATTR_READONLY_STATEMENT", sizeof("ATTR_READONLY_STATEMENT") - 1, 1); + zend_string *const_ATTR_READONLY_STATEMENT_name = zend_string_init_interned("ATTR_READONLY_STATEMENT", sizeof("ATTR_READONLY_STATEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_READONLY_STATEMENT_name, &const_ATTR_READONLY_STATEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_READONLY_STATEMENT_name); + zend_string_release_ex(const_ATTR_READONLY_STATEMENT_name, true); zval const_ATTR_EXTENDED_RESULT_CODES_value; ZVAL_LONG(&const_ATTR_EXTENDED_RESULT_CODES_value, PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES); - zend_string *const_ATTR_EXTENDED_RESULT_CODES_name = zend_string_init_interned("ATTR_EXTENDED_RESULT_CODES", sizeof("ATTR_EXTENDED_RESULT_CODES") - 1, 1); + zend_string *const_ATTR_EXTENDED_RESULT_CODES_name = zend_string_init_interned("ATTR_EXTENDED_RESULT_CODES", sizeof("ATTR_EXTENDED_RESULT_CODES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_EXTENDED_RESULT_CODES_name, &const_ATTR_EXTENDED_RESULT_CODES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_EXTENDED_RESULT_CODES_name); + zend_string_release_ex(const_ATTR_EXTENDED_RESULT_CODES_name, true); zval const_ATTR_BUSY_STATEMENT_value; ZVAL_LONG(&const_ATTR_BUSY_STATEMENT_value, PDO_SQLITE_ATTR_BUSY_STATEMENT); - zend_string *const_ATTR_BUSY_STATEMENT_name = zend_string_init_interned("ATTR_BUSY_STATEMENT", sizeof("ATTR_BUSY_STATEMENT") - 1, 1); + zend_string *const_ATTR_BUSY_STATEMENT_name = zend_string_init_interned("ATTR_BUSY_STATEMENT", sizeof("ATTR_BUSY_STATEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_BUSY_STATEMENT_name, &const_ATTR_BUSY_STATEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_BUSY_STATEMENT_name); + zend_string_release_ex(const_ATTR_BUSY_STATEMENT_name, true); zval const_ATTR_EXPLAIN_STATEMENT_value; ZVAL_LONG(&const_ATTR_EXPLAIN_STATEMENT_value, PDO_SQLITE_ATTR_EXPLAIN_STATEMENT); - zend_string *const_ATTR_EXPLAIN_STATEMENT_name = zend_string_init_interned("ATTR_EXPLAIN_STATEMENT", sizeof("ATTR_EXPLAIN_STATEMENT") - 1, 1); + zend_string *const_ATTR_EXPLAIN_STATEMENT_name = zend_string_init_interned("ATTR_EXPLAIN_STATEMENT", sizeof("ATTR_EXPLAIN_STATEMENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTR_EXPLAIN_STATEMENT_name, &const_ATTR_EXPLAIN_STATEMENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTR_EXPLAIN_STATEMENT_name); + zend_string_release_ex(const_ATTR_EXPLAIN_STATEMENT_name, true); + + zval const_ATTR_TRANSACTION_MODE_value; + ZVAL_LONG(&const_ATTR_TRANSACTION_MODE_value, PDO_SQLITE_ATTR_TRANSACTION_MODE); + zend_string *const_ATTR_TRANSACTION_MODE_name = zend_string_init_interned("ATTR_TRANSACTION_MODE", sizeof("ATTR_TRANSACTION_MODE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_ATTR_TRANSACTION_MODE_name, &const_ATTR_TRANSACTION_MODE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_ATTR_TRANSACTION_MODE_name, true); + + zval const_TRANSACTION_MODE_DEFERRED_value; + ZVAL_LONG(&const_TRANSACTION_MODE_DEFERRED_value, 0); + zend_string *const_TRANSACTION_MODE_DEFERRED_name = zend_string_init_interned("TRANSACTION_MODE_DEFERRED", sizeof("TRANSACTION_MODE_DEFERRED") - 1, true); + zend_declare_typed_class_constant(class_entry, const_TRANSACTION_MODE_DEFERRED_name, &const_TRANSACTION_MODE_DEFERRED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_MODE_DEFERRED_name, true); + + zval const_TRANSACTION_MODE_IMMEDIATE_value; + ZVAL_LONG(&const_TRANSACTION_MODE_IMMEDIATE_value, 1); + zend_string *const_TRANSACTION_MODE_IMMEDIATE_name = zend_string_init_interned("TRANSACTION_MODE_IMMEDIATE", sizeof("TRANSACTION_MODE_IMMEDIATE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_TRANSACTION_MODE_IMMEDIATE_name, &const_TRANSACTION_MODE_IMMEDIATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_MODE_IMMEDIATE_name, true); + + zval const_TRANSACTION_MODE_EXCLUSIVE_value; + ZVAL_LONG(&const_TRANSACTION_MODE_EXCLUSIVE_value, 2); + zend_string *const_TRANSACTION_MODE_EXCLUSIVE_name = zend_string_init_interned("TRANSACTION_MODE_EXCLUSIVE", sizeof("TRANSACTION_MODE_EXCLUSIVE") - 1, true); + zend_declare_typed_class_constant(class_entry, const_TRANSACTION_MODE_EXCLUSIVE_name, &const_TRANSACTION_MODE_EXCLUSIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release_ex(const_TRANSACTION_MODE_EXCLUSIVE_name, true); #if SQLITE_VERSION_NUMBER >= 3043000 zval const_EXPLAIN_MODE_PREPARED_value; ZVAL_LONG(&const_EXPLAIN_MODE_PREPARED_value, 0); - zend_string *const_EXPLAIN_MODE_PREPARED_name = zend_string_init_interned("EXPLAIN_MODE_PREPARED", sizeof("EXPLAIN_MODE_PREPARED") - 1, 1); + zend_string *const_EXPLAIN_MODE_PREPARED_name = zend_string_init_interned("EXPLAIN_MODE_PREPARED", sizeof("EXPLAIN_MODE_PREPARED") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXPLAIN_MODE_PREPARED_name, &const_EXPLAIN_MODE_PREPARED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXPLAIN_MODE_PREPARED_name); + zend_string_release_ex(const_EXPLAIN_MODE_PREPARED_name, true); zval const_EXPLAIN_MODE_EXPLAIN_value; ZVAL_LONG(&const_EXPLAIN_MODE_EXPLAIN_value, 1); - zend_string *const_EXPLAIN_MODE_EXPLAIN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN", sizeof("EXPLAIN_MODE_EXPLAIN") - 1, 1); + zend_string *const_EXPLAIN_MODE_EXPLAIN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN", sizeof("EXPLAIN_MODE_EXPLAIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXPLAIN_MODE_EXPLAIN_name, &const_EXPLAIN_MODE_EXPLAIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXPLAIN_MODE_EXPLAIN_name); + zend_string_release_ex(const_EXPLAIN_MODE_EXPLAIN_name, true); zval const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_value; ZVAL_LONG(&const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_value, 2); - zend_string *const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN", sizeof("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN") - 1, 1); + zend_string *const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN", sizeof("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name, &const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name); + zend_string_release_ex(const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name, true); #endif zval const_OK_value; ZVAL_LONG(&const_OK_value, SQLITE_OK); - zend_string *const_OK_name = zend_string_init_interned("OK", sizeof("OK") - 1, 1); + zend_string *const_OK_name = zend_string_init_interned("OK", sizeof("OK") - 1, true); zend_declare_typed_class_constant(class_entry, const_OK_name, &const_OK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OK_name); + zend_string_release_ex(const_OK_name, true); zval const_DENY_value; ZVAL_LONG(&const_DENY_value, SQLITE_DENY); - zend_string *const_DENY_name = zend_string_init_interned("DENY", sizeof("DENY") - 1, 1); + zend_string *const_DENY_name = zend_string_init_interned("DENY", sizeof("DENY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DENY_name, &const_DENY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DENY_name); + zend_string_release_ex(const_DENY_name, true); zval const_IGNORE_value; ZVAL_LONG(&const_IGNORE_value, SQLITE_IGNORE); - zend_string *const_IGNORE_name = zend_string_init_interned("IGNORE", sizeof("IGNORE") - 1, 1); + zend_string *const_IGNORE_name = zend_string_init_interned("IGNORE", sizeof("IGNORE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IGNORE_name, &const_IGNORE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IGNORE_name); + zend_string_release_ex(const_IGNORE_name, true); return class_entry; } diff --git a/ext/pdo_sqlite/php_pdo_sqlite.h b/ext/pdo_sqlite/php_pdo_sqlite.h index 1bba9e3556a7..a567e8c87ee6 100644 --- a/ext/pdo_sqlite/php_pdo_sqlite.h +++ b/ext/pdo_sqlite/php_pdo_sqlite.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -27,6 +25,12 @@ extern zend_module_entry pdo_sqlite_module_entry; #include "TSRM.h" #endif +enum pdo_sqlite_transaction_mode { + PDO_SQLITE_TRANSACTION_MODE_DEFERRED = 0, + PDO_SQLITE_TRANSACTION_MODE_IMMEDIATE = 1, + PDO_SQLITE_TRANSACTION_MODE_EXCLUSIVE = 2 +}; + PHP_MINIT_FUNCTION(pdo_sqlite); PHP_MSHUTDOWN_FUNCTION(pdo_sqlite); PHP_RINIT_FUNCTION(pdo_sqlite); diff --git a/ext/pdo_sqlite/php_pdo_sqlite_int.h b/ext/pdo_sqlite/php_pdo_sqlite_int.h index 69ac003356b8..122f714040de 100644 --- a/ext/pdo_sqlite/php_pdo_sqlite_int.h +++ b/ext/pdo_sqlite/php_pdo_sqlite_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -51,6 +49,7 @@ typedef struct { struct pdo_sqlite_func *funcs; struct pdo_sqlite_collation *collations; zend_fcall_info_cache authorizer_fcc; + enum pdo_sqlite_transaction_mode transaction_mode; } pdo_sqlite_db_handle; typedef struct { @@ -75,7 +74,8 @@ enum { PDO_SQLITE_ATTR_READONLY_STATEMENT, PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES, PDO_SQLITE_ATTR_BUSY_STATEMENT, - PDO_SQLITE_ATTR_EXPLAIN_STATEMENT + PDO_SQLITE_ATTR_EXPLAIN_STATEMENT, + PDO_SQLITE_ATTR_TRANSACTION_MODE }; typedef int pdo_sqlite_create_collation_callback(void*, int, const void*, int, const void*); diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index 2c907a34f489..39efa02dd583 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -159,11 +157,7 @@ static void sqlite_handle_closer(pdo_dbh_t *dbh) /* {{{ */ pdo_sqlite_cleanup_callbacks(H); if (H->db) { -#ifdef HAVE_SQLITE3_CLOSE_V2 sqlite3_close_v2(H->db); -#else - sqlite3_close(H->db); -#endif H->db = NULL; } if (einfo->errmsg) { @@ -255,7 +249,20 @@ static bool sqlite_handle_begin(pdo_dbh_t *dbh) { pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; - if (sqlite3_exec(H->db, "BEGIN", NULL, NULL, NULL) != SQLITE_OK) { + const char *begin_statement = "BEGIN"; + switch (H->transaction_mode) { + case PDO_SQLITE_TRANSACTION_MODE_DEFERRED: + begin_statement = "BEGIN DEFERRED TRANSACTION"; + break; + case PDO_SQLITE_TRANSACTION_MODE_IMMEDIATE: + begin_statement = "BEGIN IMMEDIATE TRANSACTION"; + break; + case PDO_SQLITE_TRANSACTION_MODE_EXCLUSIVE: + begin_statement = "BEGIN EXCLUSIVE TRANSACTION"; + break; + } + + if (sqlite3_exec(H->db, begin_statement, NULL, NULL, NULL) != SQLITE_OK) { pdo_sqlite_error(dbh); return false; } @@ -286,11 +293,16 @@ static bool sqlite_handle_rollback(pdo_dbh_t *dbh) static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value) { + pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; + switch (attr) { case PDO_ATTR_CLIENT_VERSION: case PDO_ATTR_SERVER_VERSION: ZVAL_STRING(return_value, (char *)sqlite3_libversion()); break; + case PDO_SQLITE_ATTR_TRANSACTION_MODE: + ZVAL_LONG(return_value, H->transaction_mode); + break; default: return 0; @@ -326,6 +338,19 @@ static bool pdo_sqlite_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val) } sqlite3_extended_result_codes(H->db, lval); return true; + case PDO_SQLITE_ATTR_TRANSACTION_MODE: + if (!pdo_get_long_param(&lval, val)) { + return false; + } + switch (lval) { + case PDO_SQLITE_TRANSACTION_MODE_DEFERRED: + case PDO_SQLITE_TRANSACTION_MODE_IMMEDIATE: + case PDO_SQLITE_TRANSACTION_MODE_EXCLUSIVE: + H->transaction_mode = lval; + return true; + default: + return false; + } } return false; } diff --git a/ext/pdo_sqlite/sqlite_driver_arginfo.h b/ext/pdo_sqlite/sqlite_driver_arginfo.h index 8785c187a97a..4a31eebb745d 100644 --- a/ext/pdo_sqlite/sqlite_driver_arginfo.h +++ b/ext/pdo_sqlite/sqlite_driver_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit sqlite_driver.stub.php instead. * Stub hash: dc901bd60d17c1a2cdb40a118e2c6cd6eb0396e3 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_PDO_SQLite_Ext_sqliteCreateFunction, 0, 2, _IS_BOOL, 0) diff --git a/ext/pdo_sqlite/sqlite_sql_parser.re b/ext/pdo_sqlite/sqlite_sql_parser.re index 5678e6025577..c836f6b2b499 100644 --- a/ext/pdo_sqlite/sqlite_sql_parser.re +++ b/ext/pdo_sqlite/sqlite_sql_parser.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Matteo Beccati | +----------------------------------------------------------------------+ diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c index e9e7a0cc7860..ca82b1b09322 100644 --- a/ext/pdo_sqlite/sqlite_statement.c +++ b/ext/pdo_sqlite/sqlite_statement.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -335,7 +333,6 @@ static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *ret case SQLITE_BLOB: add_next_index_string(&flags, "blob"); - /* TODO Check this is correct */ ZEND_FALLTHROUGH; case SQLITE_TEXT: add_assoc_str(return_value, "native_type", ZSTR_KNOWN(ZEND_STR_STRING)); diff --git a/ext/pdo_sqlite/tests/bug38334.phpt b/ext/pdo_sqlite/tests/bug38334.phpt index b4e9a378d717..eefd997cc71a 100644 --- a/ext/pdo_sqlite/tests/bug38334.phpt +++ b/ext/pdo_sqlite/tests/bug38334.phpt @@ -7,11 +7,11 @@ pdo_sqlite $db = new PDO('sqlite::memory:'); $db->exec('CREATE TABLE test_38334 (i INTEGER , f DOUBLE, s VARCHAR(255))'); -$db->exec('INSERT INTO test_38334 VALUES (42, 46.7, "test")'); +$db->exec("INSERT INTO test_38334 VALUES (42, 46.7, 'test')"); var_dump($db->query('SELECT * FROM test_38334')->fetch(PDO::FETCH_ASSOC)); // Check handling of integers larger than 32-bit. -$db->exec('INSERT INTO test_38334 VALUES (10000000000, 0.0, "")'); +$db->exec("INSERT INTO test_38334 VALUES (10000000000, 0.0, '')"); $i = $db->query('SELECT i FROM test_38334 WHERE f = 0.0')->fetchColumn(0); if (PHP_INT_SIZE >= 8) { var_dump($i === 10000000000); @@ -20,8 +20,8 @@ if (PHP_INT_SIZE >= 8) { } // Check storing of strings into integer/float columns. -$db->exec('INSERT INTO test_38334 VALUES ("test", "test", "x")'); -var_dump($db->query('SELECT * FROM test_38334 WHERE s = "x"')->fetch(PDO::FETCH_ASSOC)); +$db->exec("INSERT INTO test_38334 VALUES ('test', 'test', 'x')"); +var_dump($db->query("SELECT * FROM test_38334 WHERE s = 'x'")->fetch(PDO::FETCH_ASSOC)); ?> --EXPECT-- diff --git a/ext/pdo_sqlite/tests/bug60104.phpt b/ext/pdo_sqlite/tests/bug60104.phpt index b69be4681ad1..51ff2acf427f 100644 --- a/ext/pdo_sqlite/tests/bug60104.phpt +++ b/ext/pdo_sqlite/tests/bug60104.phpt @@ -15,5 +15,8 @@ setUp(); setUp(); echo "done"; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d done diff --git a/ext/pdo_sqlite/tests/bug70221.phpt b/ext/pdo_sqlite/tests/bug70221.phpt index 5c9d9453048d..b8e0a20a48a7 100644 --- a/ext/pdo_sqlite/tests/bug70221.phpt +++ b/ext/pdo_sqlite/tests/bug70221.phpt @@ -16,5 +16,6 @@ unset($db); $dbfile = __DIR__ . '/test.sqlite'; unlink($dbfile); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d Everything is fine, no exceptions here diff --git a/ext/pdo_sqlite/tests/bug81740.phpt b/ext/pdo_sqlite/tests/bug81740.phpt index 2b8b9447f0fe..2acd865b319b 100644 --- a/ext/pdo_sqlite/tests/bug81740.phpt +++ b/ext/pdo_sqlite/tests/bug81740.phpt @@ -5,6 +5,7 @@ pdo pdo_sqlite --SKIPIF-- diff --git a/ext/pdo_sqlite/tests/bug_42589.phpt b/ext/pdo_sqlite/tests/bug_42589.phpt index 46ded8d027a6..39b87b106521 100644 --- a/ext/pdo_sqlite/tests/bug_42589.phpt +++ b/ext/pdo_sqlite/tests/bug_42589.phpt @@ -15,7 +15,7 @@ if(!in_array('ENABLE_COLUMN_METADATA', $options, true)) $db = new PDO("sqlite::memory:"); $db->exec('CREATE TABLE test_42589 (field1 VARCHAR(10))'); -$db->exec('INSERT INTO test_42589 VALUES("test")'); +$db->exec("INSERT INTO test_42589 VALUES('test')"); $result = $db->query('SELECT * FROM test_42589 t1 LEFT JOIN test_42589 t2 ON t1.field1 = t2.field1'); $meta1 = $result->getColumnMeta(0); diff --git a/ext/pdo_sqlite/tests/gc.phpt b/ext/pdo_sqlite/tests/gc.phpt index b5fbad62dab7..6e60de256f63 100644 --- a/ext/pdo_sqlite/tests/gc.phpt +++ b/ext/pdo_sqlite/tests/gc.phpt @@ -18,5 +18,10 @@ $obj->a->sqliteCreateCollation('col', function() use ($obj) {}); ?> ===DONE=== ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateCollation() is deprecated since 8.5, use Pdo\Sqlite::createCollation() instead in %s on line %d ===DONE=== diff --git a/ext/pdo_sqlite/tests/gh13998.phpt b/ext/pdo_sqlite/tests/gh13998.phpt index c87b4acdd214..80ebedb1ffb2 100644 --- a/ext/pdo_sqlite/tests/gh13998.phpt +++ b/ext/pdo_sqlite/tests/gh13998.phpt @@ -21,5 +21,6 @@ try { echo 'done!'; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d done! diff --git a/ext/pdo_sqlite/tests/gh20095.phpt b/ext/pdo_sqlite/tests/gh20095.phpt new file mode 100644 index 000000000000..8d691f99ee2a --- /dev/null +++ b/ext/pdo_sqlite/tests/gh20095.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-20095: Incorrect class name in deprecation message for PDO mixins +--EXTENSIONS-- +pdo_sqlite +--FILE-- +sqliteCreateFunction('my_test', [$this, "test"]); + } +} + +$pdo = new Foo('sqlite::memory:'); +$pdo->register(); +$pdo->query("SELECT my_test()"); + +?> +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d +foo diff --git a/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt b/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt new file mode 100644 index 000000000000..7fc686b21472 --- /dev/null +++ b/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt @@ -0,0 +1,48 @@ +--TEST-- +PDO_sqlite: PDO->__construct() - URI +--EXTENSIONS-- +pdo_sqlite +--FILE-- +getMessage(), PHP_EOL; +} + +clearstatcache(); +var_dump(file_exists($dbFile)); + +?> +--CLEAN-- + +--EXPECTF-- +bool(false) + +Deprecated: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs in %s on line %d +bool(true) +bool(false) +ErrorException: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs +bool(false) diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt index 3ecc0ccddc99..cba2c49556f7 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate.phpt @@ -9,7 +9,7 @@ $db = new PDO('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createaggregate (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->sqliteCreateAggregate('testing', function(&$a, $b) { $a .= $b; return $a; }, function(&$v) { return $v; }); @@ -19,7 +19,8 @@ foreach ($db->query('SELECT testing(name) FROM test_pdo_sqlite_createaggregate') } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d array(2) { ["testing(name)"]=> string(2) "12" diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt index 4fa3578fef08..192eabbf74fd 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt @@ -19,6 +19,9 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d PDO::sqliteCreateAggregate(): Argument #2 ($step) must be a valid callback, function "a" not found or invalid function name + +Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d PDO::sqliteCreateAggregate(): Argument #3 ($finalize) must be a valid callback, function "" not found or invalid function name diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt index fdfb8dda448f..eb5ea6c97b7d 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt @@ -10,7 +10,7 @@ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->query('CREATE TABLE test_pdo_sqlite_createcollation (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, "1"), (NULL, "2"), (NULL, "10")'); +$db->query("INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, '1'), (NULL, '2'), (NULL, '10')"); $db->sqliteCreateCollation('MYCOLLATE', function($a, $b) { return strnatcmp($a, $b); }); @@ -32,11 +32,14 @@ try { echo $e->getMessage(), PHP_EOL; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateCollation() is deprecated since 8.5, use Pdo\Sqlite::createCollation() instead in %s on line %d 1 2 10 1 10 2 + +Deprecated: Method PDO::sqliteCreateCollation() is deprecated since 8.5, use Pdo\Sqlite::createCollation() instead in %s on line %d PDO::query(): Return value of the collation callback must be of type int, string returned diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt index bda7ab0b4155..49daabf5a7a9 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction.phpt @@ -9,7 +9,7 @@ $db = new PDO('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createfunction (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createfunction VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createfunction VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->sqliteCreateFunction('testing', function($v) { return strtolower($v); }); @@ -20,7 +20,8 @@ foreach ($db->query('SELECT testing(name) FROM test_pdo_sqlite_createfunction') } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d array(2) { ["testing(name)"]=> string(3) "php" diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt index 4ebba65be4a9..ead2f7b6a830 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt @@ -17,5 +17,6 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d PDO::sqliteCreateFunction(): Argument #2 ($callback) must be a valid callback, function "bar" not found or invalid function name diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt index f9312bcee69e..fafa4f6bfa21 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_with_flags.phpt @@ -4,7 +4,7 @@ PDO_sqlite: Testing sqliteCreateFunction() with flags pdo_sqlite --SKIPIF-- = 3.8.3'); ?> --FILE-- query('CREATE TABLE test_pdo_sqlite_createfunction_with_flags (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); -$db->sqliteCreateFunction('testing', function($v) { return strtolower($v); }, 1, PDO::SQLITE_DETERMINISTIC); +$db->sqliteCreateFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); foreach ($db->query('SELECT testing(name) FROM test_pdo_sqlite_createfunction_with_flags') as $row) { @@ -24,7 +24,8 @@ foreach ($db->query('SELECT testing(name) FROM test_pdo_sqlite_createfunction_wi } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d array(2) { ["testing(name)"]=> string(3) "php" diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_dqs.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_dqs.phpt new file mode 100644 index 000000000000..8ae668428484 --- /dev/null +++ b/ext/pdo_sqlite/tests/pdo_sqlite_dqs.phpt @@ -0,0 +1,27 @@ +--TEST-- +PDO_sqlite: Testing DQS support +--EXTENSIONS-- +pdo_sqlite +--SKIPIF-- +exec('SELECT "test"'); +} catch (\PDOException) { + die('skip SQLite is lacking DQS'); +} +?> +--FILE-- +exec('CREATE TABLE test (s1 VARCHAR(255), s2 VARCHAR(255))'); +$db->exec('INSERT INTO test VALUES (\'test\', "test")'); +var_dump($db->query('SELECT * FROM test')->fetch(PDO::FETCH_ASSOC)); +?> +--EXPECT-- +array(2) { + ["s1"]=> + string(4) "test" + ["s2"]=> + string(4) "test" +} diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_extendederror_attr.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_extendederror_attr.phpt index 19f3bc1427bf..bbdc65275558 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_extendederror_attr.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_extendederror_attr.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO_sqlite: Testing PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES +PDO_sqlite: Testing Pdo\Sqlite::ATTR_EXTENDED_RESULT_CODES --EXTENSIONS-- pdo_sqlite --FILE-- @@ -23,7 +23,7 @@ echo sprintf("Second Error Info: SQLSTATE Error Code: (%s), Driver Specific Erro echo "Creating new PDO with Extended Result Codes turned on" . PHP_EOL; -$db = new PDO('sqlite::memory:', '', '', [PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES => TRUE]); +$db = new PDO('sqlite::memory:', '', '', [Pdo\Sqlite::ATTR_EXTENDED_RESULT_CODES => TRUE]); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $db->exec("CREATE TABLE dog ( id INTEGER PRIMARY KEY, name TEXT, annoying INTEGER )"); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt index 7e55ed60d5f1..0f1cba84dcce 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_lastinsertid.phpt @@ -7,7 +7,7 @@ pdo_sqlite $db = new PDO('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_lastinsertid (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_lastinsertid VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_lastinsertid VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); var_dump($db->query('SELECT * FROM test_pdo_sqlite_lastinsertid')); var_dump($db->errorInfo()); var_dump($db->lastInsertId()); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_open_flags.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_open_flags.phpt index 772b1d9a76b0..00e1153fa91a 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_open_flags.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_open_flags.phpt @@ -12,7 +12,7 @@ $db = new PDO('sqlite:' . $filename, null, null, [PDO::ATTR_ERRMODE => PDO::ERRM var_dump($db->exec('CREATE TABLE test_sqlite_open_flags (id INT);')); -$db = new PDO('sqlite:' . $filename, null, null, [PDO::SQLITE_ATTR_OPEN_FLAGS => PDO::SQLITE_OPEN_READONLY, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); +$db = new PDO('sqlite:' . $filename, null, null, [Pdo\Sqlite::ATTR_OPEN_FLAGS => Pdo\Sqlite::OPEN_READONLY, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); var_dump($db->exec('CREATE TABLE test_sqlite_open_flags_2 (id INT);')); ?> diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt index d5eda8d9b827..c1eed6f3adc8 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_parser.phpt @@ -31,9 +31,8 @@ foreach ($queries as $k => $query) { // One parameter $queries = [ "SELECT * FROM {$table} WHERE '1' = ?", - "SELECT * FROM {$table} WHERE \"?\" IN (?, \"?\")", + "SELECT * FROM {$table} WHERE '?' IN (?, '?')", "SELECT * FROM {$table} WHERE `a``?` = ?", - "SELECT * FROM {$table} WHERE \"a`?\" = ?", "SELECT * FROM {$table} WHERE [a`?] = ?", ]; @@ -43,6 +42,22 @@ foreach ($queries as $k => $query) { var_dump($stmt->fetch(PDO::FETCH_NUM) === [0 => 1]); } +// Check if DQS are enabled. +$dqs = true; +try { + $db->exec('SELECT "test"'); +} catch (\PDOException) { + $dqs = false; +} + +if ($dqs) { + $stmt = $db->prepare("SELECT * FROM {$table} WHERE \"a`?\" = ?"); + $stmt->execute([1]); + var_dump($stmt->fetch(PDO::FETCH_NUM) === [0 => 1]); +} else { + var_dump(true); +} + ?> --CLEAN-- prepare('SELECT 1;'); -var_dump($st->getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT)); +var_dump($st->getAttribute(Pdo\Sqlite::ATTR_READONLY_STATEMENT)); $st = $db->prepare('CREATE TABLE test_sqlite_stmt_getattribute (a TEXT);'); -var_dump($st->getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT)); +var_dump($st->getAttribute(Pdo\Sqlite::ATTR_READONLY_STATEMENT)); ?> --EXPECT-- bool(true) diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_transaction.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_transaction.phpt index dc1e4c13a330..c8c39d18f3ac 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_transaction.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_transaction.phpt @@ -14,7 +14,7 @@ $db->query('CREATE TABLE test_pdo_sqlite_transaction (id INT AUTO INCREMENT, nam $db->commit(); $db->beginTransaction(); -$db->query('INSERT INTO test_pdo_sqlite_transaction VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_transaction VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->rollback(); $r = $db->query('SELECT COUNT(*) FROM test_pdo_sqlite_transaction'); diff --git a/ext/pdo_sqlite/tests/php_8.5_deprecations.phpt b/ext/pdo_sqlite/tests/php_8.5_deprecations.phpt new file mode 100644 index 000000000000..f7aa61206f6f --- /dev/null +++ b/ext/pdo_sqlite/tests/php_8.5_deprecations.phpt @@ -0,0 +1,65 @@ +--TEST-- +PDO_sqlite: PHP 8.5 deprecations +--EXTENSIONS-- +pdo_sqlite +--SKIPIF-- += 3.8.3'); +?> +--FILE-- +sqliteCreateFunction('test1', function(){}); +$pdo->sqliteCreateAggregate('test2', function(){}, function(){}); +$pdo->sqliteCreateCollation('test3', function(){}); + +$pdo = new PDO("sqlite::memory:", options: [PDO::ATTR_PERSISTENT => true]); +$pdo->sqliteCreateFunction('test1', function(){}); +$pdo->sqliteCreateAggregate('test2', function(){}, function(){}); +$pdo->sqliteCreateCollation('test3', function(){}); + +?> +--EXPECTF-- +Deprecated: Constant PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES is deprecated since 8.5, use Pdo\Sqlite::ATTR_EXTENDED_RESULT_CODES instead in %s on line %d + +Deprecated: Constant PDO::SQLITE_ATTR_OPEN_FLAGS is deprecated since 8.5, use Pdo\Sqlite::ATTR_OPEN_FLAGS instead in %s on line %d + +Deprecated: Constant PDO::SQLITE_ATTR_READONLY_STATEMENT is deprecated since 8.5, use Pdo\Sqlite::ATTR_READONLY_STATEMENT instead in %s on line %d + +Deprecated: Constant PDO::SQLITE_DETERMINISTIC is deprecated since 8.5, use Pdo\Sqlite::DETERMINISTIC instead in %s on line %d + +Deprecated: Constant PDO::SQLITE_OPEN_READONLY is deprecated since 8.5, use Pdo\Sqlite::OPEN_READONLY instead in %s on line %d + +Deprecated: Constant PDO::SQLITE_OPEN_READWRITE is deprecated since 8.5, use Pdo\Sqlite::OPEN_READWRITE instead in %s on line %d + +Deprecated: Constant PDO::SQLITE_OPEN_CREATE is deprecated since 8.5, use Pdo\Sqlite::OPEN_CREATE instead in %s on line %d +int(1002) +int(1000) +int(1001) +int(2048) +int(1) +int(2) +int(4) + +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateCollation() is deprecated since 8.5, use Pdo\Sqlite::createCollation() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d + +Deprecated: Method PDO::sqliteCreateCollation() is deprecated since 8.5, use Pdo\Sqlite::createCollation() instead in %s on line %d diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_constants.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_constants.phpt index d1db58b1323e..f258dd2a5041 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_constants.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_constants.phpt @@ -2,6 +2,10 @@ PDO_sqlite: Testing constants exist --EXTENSIONS-- pdo_sqlite +--SKIPIF-- += 3.8.3'); +?> --FILE-- createFunction('strtoupper', [new TrampolineTest(), 'strtoupper'])); -foreach ($db->query('SELECT strtoupper("test")') as $row) { +foreach ($db->query("SELECT strtoupper('test')") as $row) { var_dump($row); } -foreach ($db->query('SELECT strtoupper("test")') as $row) { +foreach ($db->query("SELECT strtoupper('test')") as $row) { var_dump($row); } @@ -33,14 +33,14 @@ foreach ($db->query('SELECT strtoupper("test")') as $row) { bool(true) Trampoline for strtoupper array(2) { - ["strtoupper("test")"]=> + ["strtoupper('test')"]=> string(4) "TEST" [0]=> string(4) "TEST" } Trampoline for strtoupper array(2) { - ["strtoupper("test")"]=> + ["strtoupper('test')"]=> string(4) "TEST" [0]=> string(4) "TEST" diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt index 1f96da8e1fa3..af04daaec7fa 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate.phpt @@ -10,7 +10,7 @@ $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createaggregate (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createaggregate VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->createAggregate('testing', function(&$a, $b) { $a .= $b; return $a; }, function(&$v) { return $v; }); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt index d043dda7a526..4ba37ec6aa6e 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation.phpt @@ -11,7 +11,7 @@ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->query('CREATE TABLE test_pdo_sqlite_createcollation (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, "1"), (NULL, "2"), (NULL, "10")'); +$db->query("INSERT INTO test_pdo_sqlite_createcollation VALUES (NULL, '1'), (NULL, '2'), (NULL, '10')"); $db->createCollation('MYCOLLATE', function($a, $b) { return strnatcmp($a, $b); }); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt index 1635fd700771..7f2b309ebf4c 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_trampoline.phpt @@ -9,7 +9,7 @@ $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_pdo_sqlite_createcollation_trampoline (s VARCHAR(4))'); -$stmt = $db->query('INSERT INTO test_pdo_sqlite_createcollation_trampoline VALUES ("a1"), ("a10"), ("a2")'); +$stmt = $db->query("INSERT INTO test_pdo_sqlite_createcollation_trampoline VALUES ('a1'), ('a10'), ('a2')"); class TrampolineTest { public function __call(string $name, array $arguments) { diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt index 838e2b9bd49b..07359a69bc4c 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createfunction_with_flags.phpt @@ -4,14 +4,14 @@ PDO_sqlite: Testing createFunction() with flags pdo_sqlite --SKIPIF-- = 3.8.3'); ?> --FILE-- query('CREATE TABLE test_pdo_sqlite_createfunction_with_flags (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, "PHP"), (NULL, "PHP6")'); +$db->query("INSERT INTO test_pdo_sqlite_createfunction_with_flags VALUES (NULL, 'PHP'), (NULL, 'PHP6')"); $db->createFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt index 230fb7390ae5..c1f82e96c07b 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getattr_busy.phpt @@ -8,7 +8,7 @@ pdo_sqlite $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_busy (a string);'); -$db->query('INSERT INTO test_busy VALUES ("interleaved"), ("statements")'); +$db->query("INSERT INTO test_busy VALUES ('interleaved'), ('statements')"); $st = $db->prepare('SELECT a FROM test_busy'); var_dump($st->getAttribute(Pdo\Sqlite::ATTR_BUSY_STATEMENT)); $st->execute(); diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt index 383457f3a79e..d2a6c2a5f52b 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt @@ -13,7 +13,7 @@ if (!defined('Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN')) die('skip system sqlite does n $db = new Pdo\Sqlite('sqlite::memory:'); $db->query('CREATE TABLE test_explain (a string);'); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN); var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT) == Pdo\Sqlite::EXPLAIN_MODE_EXPLAIN); $r = $stmt->execute(); @@ -24,7 +24,7 @@ var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT) == Pdo\Sqlite:: $r = $stmts->execute(); var_dump($stmts->fetchAll(PDO::FETCH_ASSOC)); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, Pdo\Sqlite::EXPLAIN_MODE_PREPARED); $stmt->execute(); $stmts->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, Pdo\Sqlite::EXPLAIN_MODE_PREPARED); @@ -88,7 +88,7 @@ array(%d) { ["opcode"]=> string(13) "InitCoroutine" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> @@ -109,7 +109,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -126,7 +126,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -147,7 +147,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -164,7 +164,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -183,7 +183,7 @@ array(%d) { ["opcode"]=> string(12) "EndCoroutine" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -221,7 +221,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> @@ -242,7 +242,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(1) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -259,11 +259,11 @@ array(%d) { ["opcode"]=> string(10) "MakeRecord" ["p1"]=> - int(2) + int(%d) ["p2"]=> int(1) ["p3"]=> - int(4) + int(%d) ["p4"]=> string(1) "C" ["p5"]=> @@ -280,9 +280,9 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(4) + int(%d) ["p3"]=> - int(1) + int(%d) ["p4"]=> string(12) "test_explain" ["p5"]=> diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_transaction_mode.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_transaction_mode.phpt new file mode 100644 index 000000000000..b342ece3adeb --- /dev/null +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_transaction_mode.phpt @@ -0,0 +1,88 @@ +--TEST-- +PDO_sqlite: Testing ATTR_TRANSACTION_MODE +--EXTENSIONS-- +pdo_sqlite +--FILE-- +getAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE) === PDO\Sqlite::TRANSACTION_MODE_DEFERRED); + +// Both should return true - setting DEFERRED +var_dump($pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, PDO\Sqlite::TRANSACTION_MODE_DEFERRED)); +var_dump($pdo->getAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE) === PDO\Sqlite::TRANSACTION_MODE_DEFERRED); + +// Both should return true - setting IMMEDIATE +var_dump($pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, PDO\Sqlite::TRANSACTION_MODE_IMMEDIATE)); +var_dump($pdo->getAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE) === PDO\Sqlite::TRANSACTION_MODE_IMMEDIATE); + +// Both should return true - setting EXCLUSIVE +var_dump($pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, PDO\Sqlite::TRANSACTION_MODE_EXCLUSIVE)); +var_dump($pdo->getAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE) === PDO\Sqlite::TRANSACTION_MODE_EXCLUSIVE); + +// Setting the numeric equivalents of the above. All should return true +var_dump($pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, 0)); +var_dump($pdo->getAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE) === PDO\Sqlite::TRANSACTION_MODE_DEFERRED); +var_dump($pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, 1)); +var_dump($pdo->getAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE) === PDO\Sqlite::TRANSACTION_MODE_IMMEDIATE); +var_dump($pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, 2)); +var_dump($pdo->getAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE) === PDO\Sqlite::TRANSACTION_MODE_EXCLUSIVE); + +// Cannot set a random numeric value +var_dump($pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, 4)); + +// Set $pdo to deferred, try to get immediate transaction in $pdo2. There should be no lock contention +$pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, PDO\Sqlite::TRANSACTION_MODE_DEFERRED); +$pdo->beginTransaction(); +try { + $pdo2->exec('begin immediate transaction'); + $pdo2->rollBack(); + printf("Database is not locked\n"); +} catch (PDOException $e) { + printf("Database is locked: %s\n", $e->getMessage()); +} +$pdo->rollBack(); + +// Set $pdo to immediate, try to get immediate transaction in $pdo2. There SHOULD be lock contention +$pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, PDO\Sqlite::TRANSACTION_MODE_IMMEDIATE); +$pdo->beginTransaction(); +try { + $pdo2->exec('begin immediate transaction'); + printf("Database is not locked\n"); +} catch (PDOException $e) { + printf("Database is locked: %s\n", $e->getMessage()); +} +$pdo->rollBack(); + +// Set $pdo to exclusive, try to get immediate transaction in $pdo2. There SHOULD be lock contention +$pdo->setAttribute(PDO\Sqlite::ATTR_TRANSACTION_MODE, PDO\Sqlite::TRANSACTION_MODE_EXCLUSIVE); +$pdo->beginTransaction(); +try { + $pdo2->exec('begin immediate transaction'); + printf("Database is not locked\n"); +} catch (PDOException $e) { + printf("Database is locked: %s\n", $e->getMessage()); +} +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +Database is not locked +Database is locked: SQLSTATE[HY000]: General error: 6 database table is locked +Database is locked: SQLSTATE[HY000]: General error: 6 database schema is locked: main diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt index ea88a6316b64..40ec0a7799f0 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_001.phpt @@ -2,6 +2,10 @@ Pdo\Sqlite basic --EXTENSIONS-- pdo_sqlite +--SKIPIF-- += 3.8.3'); +?> --FILE-- query('CREATE TABLE pdosqlite_001 (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO pdosqlite_001 VALUES (NULL, "PHP")'); -$db->query('INSERT INTO pdosqlite_001 VALUES (NULL, "PHP6")'); +$db->query("INSERT INTO pdosqlite_001 VALUES (NULL, 'PHP')"); +$db->query("INSERT INTO pdosqlite_001 VALUES (NULL, 'PHP6')"); $db->createFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt index 28534f4a2365..fddf2138f84e 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_002.phpt @@ -2,6 +2,10 @@ Pdo\Sqlite create through PDO::connect and function define. --EXTENSIONS-- pdo_sqlite +--SKIPIF-- += 3.8.3'); +?> --FILE-- query('CREATE TABLE pdosqlite_002 (id INT AUTO INCREMENT, name TEXT)'); -$db->query('INSERT INTO pdosqlite_002 VALUES (NULL, "PHP")'); -$db->query('INSERT INTO pdosqlite_002 VALUES (NULL, "PHP6")'); +$db->query("INSERT INTO pdosqlite_002 VALUES (NULL, 'PHP')"); +$db->query("INSERT INTO pdosqlite_002 VALUES (NULL, 'PHP6')"); $db->createFunction('testing', function($v) { return strtolower($v); }, 1, Pdo\Sqlite::DETERMINISTIC); diff --git a/ext/pgsql/config.w32 b/ext/pgsql/config.w32 index 3ca5fc2f1691..4c8d6f3bd715 100644 --- a/ext/pgsql/config.w32 +++ b/ext/pgsql/config.w32 @@ -4,8 +4,9 @@ ARG_WITH("pgsql", "PostgreSQL support", "no"); if (PHP_PGSQL != "no") { if (CHECK_LIB("libpq.lib", "pgsql", PHP_PGSQL) && - CHECK_HEADER_ADD_INCLUDE("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;" + PHP_PGSQL)) { + CHECK_HEADER("libpq-fe.h", "CFLAGS_PGSQL", PHP_PGSQL + "\\include;" + PHP_PHP_BUILD + "\\include\\pgsql;" + PHP_PHP_BUILD + "\\include\\libpq;" + PHP_PGSQL)) { EXTENSION("pgsql", "pgsql.c", PHP_PGSQL_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + AC_DEFINE('HAVE_PG_RESULT_MEMORY_SIZE', 1, "Define to 1 if libpq has the 'PQresultMemorySize' function (PostgreSQL 12 or later)."); AC_DEFINE('HAVE_PGSQL', 1, "Define to 1 if the PHP extension 'pgsql' is available."); ADD_FLAG("CFLAGS_PGSQL", "/D PGSQL_EXPORTS"); ADD_EXTENSION_DEP('pgsql', 'pcre'); diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index ba6d660d0307..8efd43ed3a8b 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Zeev Suraski | | Jouni Ahto | @@ -154,7 +152,7 @@ static zend_class_entry *pgsql_link_ce, *pgsql_result_ce, *pgsql_lob_ce; static zend_object_handlers pgsql_link_object_handlers, pgsql_result_object_handlers, pgsql_lob_object_handlers; static inline pgsql_link_handle *pgsql_link_from_obj(zend_object *obj) { - return (pgsql_link_handle *)((char *)(obj) - XtOffsetOf(pgsql_link_handle, std)); + return ZEND_CONTAINER_OF(obj, pgsql_link_handle, std); } #define Z_PGSQL_LINK_P(zv) pgsql_link_from_obj(Z_OBJ_P(zv)) @@ -210,7 +208,7 @@ static void pgsql_link_free_obj(zend_object *obj) } static inline pgsql_result_handle *pgsql_result_from_obj(zend_object *obj) { - return (pgsql_result_handle *)((char *)(obj) - XtOffsetOf(pgsql_result_handle, std)); + return ZEND_CONTAINER_OF(obj, pgsql_result_handle, std); } #define Z_PGSQL_RESULT_P(zv) pgsql_result_from_obj(Z_OBJ_P(zv)) @@ -247,7 +245,7 @@ static void pgsql_result_free_obj(zend_object *obj) } static inline pgLofp *pgsql_lob_from_obj(zend_object *obj) { - return (pgLofp *)((char *)(obj) - XtOffsetOf(pgLofp, std)); + return ZEND_CONTAINER_OF(obj, pgLofp, std); } #define Z_PGSQL_LOB_P(zv) pgsql_lob_from_obj(Z_OBJ_P(zv)) @@ -321,6 +319,10 @@ static void _close_pgsql_plink(zend_resource *rsrc) static void _php_pgsql_notice_handler(void *l, const char *message) { + if (l == NULL) { + /* This connection does not currently have a valid context, ignore this notice */ + return; + } if (PGG(ignore_notices)) { return; } @@ -353,6 +355,11 @@ static int _rollback_transactions(zval *el) link = (PGconn *) rsrc->ptr; + /* unset notice processor if we initially did set it */ + if (PQsetNoticeProcessor(link, NULL, NULL) == _php_pgsql_notice_handler) { + PQsetNoticeProcessor(link, _php_pgsql_notice_handler, NULL); + } + if (PQsetnonblocking(link, 0)) { php_error_docref("ref.pgsql", E_NOTICE, "Cannot set connection to blocking mode"); return -1; @@ -567,7 +574,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_link_ce->default_object_handlers = &pgsql_link_object_handlers; memcpy(&pgsql_link_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pgsql_link_object_handlers.offset = XtOffsetOf(pgsql_link_handle, std); + pgsql_link_object_handlers.offset = offsetof(pgsql_link_handle, std); pgsql_link_object_handlers.free_obj = pgsql_link_free_obj; pgsql_link_object_handlers.get_constructor = pgsql_link_get_constructor; pgsql_link_object_handlers.clone_obj = NULL; @@ -578,7 +585,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_result_ce->default_object_handlers = &pgsql_result_object_handlers; memcpy(&pgsql_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pgsql_result_object_handlers.offset = XtOffsetOf(pgsql_result_handle, std); + pgsql_result_object_handlers.offset = offsetof(pgsql_result_handle, std); pgsql_result_object_handlers.free_obj = pgsql_result_free_obj; pgsql_result_object_handlers.get_constructor = pgsql_result_get_constructor; pgsql_result_object_handlers.clone_obj = NULL; @@ -589,7 +596,7 @@ PHP_MINIT_FUNCTION(pgsql) pgsql_lob_ce->default_object_handlers = &pgsql_lob_object_handlers; memcpy(&pgsql_lob_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - pgsql_lob_object_handlers.offset = XtOffsetOf(pgLofp, std); + pgsql_lob_object_handlers.offset = offsetof(pgLofp, std); pgsql_lob_object_handlers.free_obj = pgsql_lob_free_obj; pgsql_lob_object_handlers.get_constructor = pgsql_lob_get_constructor; pgsql_lob_object_handlers.clone_obj = NULL; @@ -697,10 +704,12 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* create the link */ pgsql = PQconnectdb(connstring); if (pgsql == NULL || PQstatus(pgsql) == CONNECTION_BAD) { - PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql) + zend_string *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql)); if (pgsql) { PQfinish(pgsql); } + php_error_docref(NULL, E_WARNING, "Unable to connect to PostgreSQL server: %s", ZSTR_VAL(msgbuf)); + zend_string_release(msgbuf); goto err; } @@ -781,19 +790,23 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) if (connect_type & PGSQL_CONNECT_ASYNC) { pgsql = PQconnectStart(connstring); if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { - PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql); + zend_string *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql)); if (pgsql) { PQfinish(pgsql); } + php_error_docref(NULL, E_WARNING, "Unable to connect to PostgreSQL server: %s", ZSTR_VAL(msgbuf)); + zend_string_release(msgbuf); goto err; } } else { pgsql = PQconnectdb(connstring); if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) { - PHP_PQ_ERROR("Unable to connect to PostgreSQL server: %s", pgsql); + zend_string *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql)); if (pgsql) { PQfinish(pgsql); } + php_error_docref(NULL, E_WARNING, "Unable to connect to PostgreSQL server: %s", ZSTR_VAL(msgbuf)); + zend_string_release(msgbuf); goto err; } } @@ -998,7 +1011,7 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type break; } #endif - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (result) { RETURN_STRING(result); @@ -1197,7 +1210,6 @@ PHP_FUNCTION(pg_query) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1214,28 +1226,55 @@ PHP_FUNCTION(pg_query) } } -static void _php_pgsql_free_params(char **params, int num_params) +/* The char pointer MUST refer to the char* of a zend_string struct */ +static void php_pgsql_zend_string_release_from_char_pointer(char *ptr) { + zend_string_release((zend_string*) (ptr - offsetof(zend_string, val))); +} + +static void _php_pgsql_free_params(char **params, uint32_t num_params) { - if (num_params > 0) { - int i; - for (i = 0; i < num_params; i++) { - if (params[i]) { - efree(params[i]); - } + for (uint32_t i = 0; i < num_params; i++) { + if (params[i]) { + php_pgsql_zend_string_release_from_char_pointer(params[i]); } - efree(params); } + efree(params); +} + +static char **php_pgsql_make_arguments(const HashTable *param_arr, int *num_params) +{ + /* This conversion is safe because of the limit of number of elements in a table. */ + *num_params = (int) zend_hash_num_elements(param_arr); + char **params = safe_emalloc(sizeof(char *), *num_params, 0); + uint32_t i = 0; + + ZEND_HASH_FOREACH_VAL(param_arr, zval *tmp) { + ZVAL_DEREF(tmp); + if (Z_TYPE_P(tmp) == IS_NULL) { + params[i] = NULL; + } else { + zend_string *param_str = zval_try_get_string(tmp); + if (!param_str) { + _php_pgsql_free_params(params, i); + return NULL; + } + params[i] = ZSTR_VAL(param_str); + } + i++; + } ZEND_HASH_FOREACH_END(); + + return params; } /* Execute a query */ PHP_FUNCTION(pg_query_params) { zval *pgsql_link = NULL; - zval *pv_param_arr, *tmp; + zval *pv_param_arr; char *query; size_t query_len; bool leftover = false; - int num_params = 0; + int num_params; char **params = NULL; pgsql_link_handle *link; PGconn *pgsql; @@ -1279,26 +1318,9 @@ PHP_FUNCTION(pg_query_params) php_error_docref(NULL, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); } - num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); - if (num_params > 0) { - int i = 0; - params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { - ZVAL_DEREF(tmp); - if (Z_TYPE_P(tmp) == IS_NULL) { - params[i] = NULL; - } else { - zend_string *param_str = zval_try_get_string(tmp); - if (!param_str) { - _php_pgsql_free_params(params, i); - RETURN_THROWS(); - } - params[i] = estrndup(ZSTR_VAL(param_str), ZSTR_LEN(param_str)); - zend_string_release(param_str); - } - i++; - } ZEND_HASH_FOREACH_END(); + params = php_pgsql_make_arguments(Z_ARRVAL_P(pv_param_arr), &num_params); + if (UNEXPECTED(!params)) { + RETURN_THROWS(); } pgsql_result = PQexecParams(pgsql, query, num_params, @@ -1326,7 +1348,6 @@ PHP_FUNCTION(pg_query_params) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1412,7 +1433,6 @@ PHP_FUNCTION(pg_prepare) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1433,11 +1453,11 @@ PHP_FUNCTION(pg_prepare) PHP_FUNCTION(pg_execute) { zval *pgsql_link = NULL; - zval *pv_param_arr, *tmp; + zval *pv_param_arr; char *stmtname; size_t stmtname_len; bool leftover = false; - int num_params = 0; + int num_params; char **params = NULL; PGconn *pgsql; pgsql_link_handle *link; @@ -1481,25 +1501,9 @@ PHP_FUNCTION(pg_execute) php_error_docref(NULL, E_NOTICE, "Found results on this connection. Use pg_get_result() to get these results first"); } - num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); - if (num_params > 0) { - int i = 0; - params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { - ZVAL_DEREF(tmp); - if (Z_TYPE_P(tmp) == IS_NULL) { - params[i] = NULL; - } else { - zend_string *tmp_str; - zend_string *str = zval_get_tmp_string(tmp, &tmp_str); - - params[i] = estrndup(ZSTR_VAL(str), ZSTR_LEN(str)); - zend_tmp_string_release(tmp_str); - } - - i++; - } ZEND_HASH_FOREACH_END(); + params = php_pgsql_make_arguments(Z_ARRVAL_P(pv_param_arr), &num_params); + if (UNEXPECTED(!params)) { + RETURN_THROWS(); } pgsql_result = PQexecPrepared(pgsql, stmtname, num_params, @@ -1527,7 +1531,6 @@ PHP_FUNCTION(pg_execute) PHP_PQ_ERROR("Query failed: %s", pgsql); PQclear(pgsql_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pgsql_result) { @@ -1573,7 +1576,7 @@ static void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_ty case PHP_PG_CMD_TUPLES: RETVAL_LONG(atoi(PQcmdTuples(pgsql_result))); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } @@ -1639,7 +1642,6 @@ PHP_FUNCTION(pg_last_notice) zend_hash_clean(notices); } RETURN_TRUE; - break; default: zend_argument_value_error(2, "must be one of PGSQL_NOTICE_LAST, PGSQL_NOTICE_ALL, or PGSQL_NOTICE_CLEAR"); RETURN_THROWS(); @@ -1805,19 +1807,15 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ switch (entry_type) { case PHP_PG_FIELD_NAME: RETURN_STRING(PQfname(pgsql_result, (int)field)); - break; case PHP_PG_FIELD_SIZE: RETURN_LONG(PQfsize(pgsql_result, (int)field)); - break; case PHP_PG_FIELD_TYPE: RETURN_STR(get_field_name(pg_result->conn, PQftype(pgsql_result, (int)field))); - break; case PHP_PG_FIELD_TYPE_OID: oid = PQftype(pgsql_result, (int)field); PGSQL_RETURN_OID(oid); - break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -1974,60 +1972,37 @@ PHP_FUNCTION(pg_fetch_result) } /* }}} */ -/* {{{ void php_pgsql_fetch_hash */ -static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_type, int into_object) +/* Returns true when the return_value was populated with an array, + * otherwise when an error occurs false is returned, in which case the return_value is NOT initialized */ +static bool php_pgsql_fetch_hash(zval *return_value, const zval *result, zend_long row, bool row_is_null, zend_long result_type) { - zval *result; PGresult *pgsql_result; pgsql_result_handle *pg_result; int i, num_fields, pgsql_row; - zend_long row; - bool row_is_null = true; char *field_name; - HashTable *ctor_params = NULL; - zend_class_entry *ce = NULL; - - if (into_object) { - ZEND_PARSE_PARAMETERS_START(1, 4) - Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) - Z_PARAM_OPTIONAL - Z_PARAM_LONG_OR_NULL(row, row_is_null) - Z_PARAM_CLASS(ce) - Z_PARAM_ARRAY_HT(ctor_params) - ZEND_PARSE_PARAMETERS_END(); - - if (!ce) { - ce = zend_standard_class_def; - } - result_type = PGSQL_ASSOC; - } else { - ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) - Z_PARAM_OPTIONAL - Z_PARAM_LONG_OR_NULL(row, row_is_null) - Z_PARAM_LONG(result_type) - ZEND_PARSE_PARAMETERS_END(); - } if (!row_is_null && row < 0) { zend_argument_value_error(2, "must be greater than or equal to 0"); - RETURN_THROWS(); + return false; } if (!(result_type & PGSQL_BOTH)) { zend_argument_value_error(3, "must be one of PGSQL_ASSOC, PGSQL_NUM, or PGSQL_BOTH"); - RETURN_THROWS(); + return false; } pg_result = Z_PGSQL_RESULT_P(result); - CHECK_PGSQL_RESULT(pg_result); + if (UNEXPECTED(pg_result->result == NULL)) { + zend_throw_error(NULL, "PostgreSQL result has already been closed"); + return false; + } pgsql_result = pg_result->result; if (!row_is_null) { if (row >= PQntuples(pgsql_result)) { php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT, row, Z_LVAL_P(result)); - RETURN_FALSE; + return false; } pgsql_row = (int)row; pg_result->row = pgsql_row; @@ -2035,7 +2010,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ /* If 2nd param is NULL, use internal row counter to access next row */ pgsql_row = pg_result->row; if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) { - RETURN_FALSE; + return false; } pg_result->row++; } @@ -2051,7 +2026,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ add_assoc_null(return_value, field_name); } } else { - char *element = PQgetvalue(pgsql_result, pgsql_row, i); + const char *element = PQgetvalue(pgsql_result, pgsql_row, i); if (element) { const size_t element_len = strlen(element); @@ -2066,63 +2041,139 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ } } } - - if (into_object) { - zval dataset; - - ZVAL_COPY_VALUE(&dataset, return_value); - object_init_ex(return_value, ce); - if (!ce->default_properties_count && !ce->__set) { - Z_OBJ_P(return_value)->properties = Z_ARR(dataset); - } else { - zend_merge_properties(return_value, Z_ARRVAL(dataset)); - zval_ptr_dtor(&dataset); - } - - if (ce->constructor) { - zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), Z_OBJCE_P(return_value), - /* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params); - } else if (ctor_params && zend_hash_num_elements(ctor_params) > 0) { - zend_argument_value_error(3, - "must be empty when the specified class (%s) does not have a constructor", - ZSTR_VAL(ce->name) - ); - } - } + return true; } -/* }}} */ /* {{{ Get a row as an enumerated array */ PHP_FUNCTION(pg_fetch_row) { - php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_NUM, 0); + zval *result; + zend_long row = 0; + bool row_is_null = true; + zend_long result_type = PGSQL_NUM; + + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(row, row_is_null) + Z_PARAM_LONG(result_type) + ZEND_PARSE_PARAMETERS_END(); + + if (UNEXPECTED(!php_pgsql_fetch_hash(return_value, result, row, row_is_null, result_type))) { + /* Either an exception is thrown, or we return false */ + RETURN_FALSE; + } } /* }}} */ /* {{{ Fetch a row as an assoc array */ PHP_FUNCTION(pg_fetch_assoc) { - /* pg_fetch_assoc() is added from PHP 4.3.0. It should raise error, when - there is 3rd parameter */ - if (ZEND_NUM_ARGS() > 2) - WRONG_PARAM_COUNT; - php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 0); + zval *result; + zend_long row = 0; + bool row_is_null = true; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(row, row_is_null) + ZEND_PARSE_PARAMETERS_END(); + + if (UNEXPECTED(!php_pgsql_fetch_hash(return_value, result, row, row_is_null, PGSQL_ASSOC))) { + /* Either an exception is thrown, or we return false */ + RETURN_FALSE; + } } /* }}} */ /* {{{ Fetch a row as an array */ PHP_FUNCTION(pg_fetch_array) { - php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_BOTH, 0); + zval *result; + zend_long row = 0; + bool row_is_null = true; + zend_long result_type = PGSQL_BOTH; + + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(row, row_is_null) + Z_PARAM_LONG(result_type) + ZEND_PARSE_PARAMETERS_END(); + + if (UNEXPECTED(!php_pgsql_fetch_hash(return_value, result, row, row_is_null, result_type))) { + /* Either an exception is thrown, or we return false */ + RETURN_FALSE; + } } /* }}} */ /* {{{ Fetch a row as an object */ PHP_FUNCTION(pg_fetch_object) { - /* pg_fetch_object() allowed result_type used to be. 3rd parameter - must be allowed for compatibility */ - php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 1); + zval *result; + zend_long row = 0; + bool row_is_null = true; + zend_class_entry *ce = NULL; + HashTable *ctor_params = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 4) + Z_PARAM_OBJECT_OF_CLASS(result, pgsql_result_ce) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(row, row_is_null) + Z_PARAM_CLASS(ce) + Z_PARAM_ARRAY_HT(ctor_params) + ZEND_PARSE_PARAMETERS_END(); + + if (!ce) { + ce = zend_standard_class_def; + } + + if (UNEXPECTED(object_init_ex(return_value, ce) == FAILURE)) { + RETURN_THROWS(); + } + + zval dataset; + if (UNEXPECTED(!php_pgsql_fetch_hash(&dataset, result, row, row_is_null, PGSQL_ASSOC))) { + /* Either an exception is thrown, or we return false */ + zval_ptr_dtor(return_value); + RETURN_FALSE; + } + + if (!ce->default_properties_count && !ce->__set) { + Z_OBJ_P(return_value)->properties = Z_ARR(dataset); + } else { + zend_merge_properties(return_value, Z_ARRVAL(dataset)); + zval_ptr_dtor(&dataset); + } + + zend_object *obj = Z_OBJ_P(return_value); + const zend_class_entry *old = EG(fake_scope); + EG(fake_scope) = ce; + zend_function *constructor = obj->handlers->get_constructor(obj); + EG(fake_scope) = old; + + if (UNEXPECTED(EG(exception))) { + /* visibility error or override refused - VM dtors return_value */ + return; + } + + if (UNEXPECTED(!constructor && ctor_params && zend_hash_num_elements(ctor_params) > 0)) { + zend_argument_value_error(4, + "must be empty when the specified class (%s) does not have a constructor", + ZSTR_VAL(ce->name) + ); + RETURN_THROWS(); + } + + if (constructor) { + zend_call_known_function(constructor, obj, ce, + /* retval */ NULL, /* argc */ 0, /* params */ NULL, ctor_params); + if (EG(exception)) { + zend_object_store_ctor_failed(obj); + RETURN_THROWS(); + } + } } /* }}} */ @@ -2308,7 +2359,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type, bo case PHP_PG_DATA_ISNULL: RETVAL_LONG(PQgetisnull(pgsql_result, pgsql_row, field_offset)); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -2856,19 +2907,18 @@ PHP_FUNCTION(pg_lo_import) Oid returned_oid; pgsql_link_handle *link; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "OP|z", &pgsql_link, pgsql_link_ce, &file_in, &oid) == SUCCESS) { + /* Deprecated signature with implicit connection */ + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "P|z", &file_in, &oid) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "OP|z", &pgsql_link, pgsql_link_ce, &file_in, &oid) == FAILURE) { + RETURN_THROWS(); + } link = Z_PGSQL_LINK_P(pgsql_link); CHECK_PGSQL_LINK(link); - } - else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), - "P|z", &file_in, &oid) == SUCCESS) { + } else { + /* Load implicit connection */ link = FETCH_DEFAULT_LINK(); CHECK_DEFAULT_LINK(link); } - else { - WRONG_PARAM_COUNT; - } if (php_check_open_basedir(ZSTR_VAL(file_in))) { RETURN_FALSE; @@ -2981,10 +3031,7 @@ PHP_FUNCTION(pg_lo_export) pgsql = link->conn; - if (lo_export(pgsql, oid, ZSTR_VAL(file_out)) == -1) { - RETURN_FALSE; - } - RETURN_TRUE; + RETURN_BOOL(lo_export(pgsql, oid, ZSTR_VAL(file_out)) != -1); } /* }}} */ @@ -3038,15 +3085,11 @@ PHP_FUNCTION(pg_lo_tell) pgsql = Z_PGSQL_LOB_P(pgsql_id); CHECK_PGSQL_LOB(pgsql); -#ifdef VE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { offset = lo_tell64((PGconn *)pgsql->conn, pgsql->lofd); } else { offset = lo_tell((PGconn *)pgsql->conn, pgsql->lofd); } -#else - offset = lo_tell((PGconn *)pgsql->conn, pgsql->lofd); -#endif RETURN_LONG(offset); } /* }}} */ @@ -3067,15 +3110,11 @@ PHP_FUNCTION(pg_lo_truncate) pgsql = Z_PGSQL_LOB_P(pgsql_id); CHECK_PGSQL_LOB(pgsql); -#ifdef VE_PG_LO64 if (PQserverVersion((PGconn *)pgsql->conn) >= 90300) { result = lo_truncate64((PGconn *)pgsql->conn, pgsql->lofd, size); } else { result = lo_truncate((PGconn *)pgsql->conn, pgsql->lofd, size); } -#else - result = lo_truncate((PGconn *)pgsql->conn, pgsql->lofd, size); -#endif if (!result) { RETURN_TRUE; } else { @@ -3308,9 +3347,8 @@ PHP_FUNCTION(pg_copy_to) pgsql_link_handle *link; zend_string *table_name; zend_string *pg_delimiter = NULL; - char *pg_null_as = NULL; + char *pg_null_as = "\\\\N"; size_t pg_null_as_len = 0; - bool free_pg_null = false; char *query; PGconn *pgsql; PGresult *pgsql_result; @@ -3335,10 +3373,6 @@ PHP_FUNCTION(pg_copy_to) zend_argument_value_error(3, "must be one character"); RETURN_THROWS(); } - if (!pg_null_as) { - pg_null_as = estrdup("\\\\N"); - free_pg_null = true; - } spprintf(&query, 0, "COPY %s TO STDOUT DELIMITER E'%c' NULL AS E'%s'", ZSTR_VAL(table_name), *ZSTR_VAL(pg_delimiter), pg_null_as); @@ -3346,9 +3380,6 @@ PHP_FUNCTION(pg_copy_to) PQclear(pgsql_result); } pgsql_result = PQexec(pgsql, query); - if (free_pg_null) { - efree(pg_null_as); - } efree(query); if (pgsql_result) { @@ -3376,7 +3407,6 @@ PHP_FUNCTION(pg_copy_to) case -2: PHP_PQ_ERROR("getline failed: %s", pgsql); RETURN_FALSE; - break; default: add_next_index_string(return_value, csv); PQfreemem(csv); @@ -3395,33 +3425,33 @@ PHP_FUNCTION(pg_copy_to) PQclear(pgsql_result); PHP_PQ_ERROR("Copy command failed: %s", pgsql); RETURN_FALSE; - break; } } /* }}} */ static zend_result pgsql_copy_from_query(PGconn *pgsql, PGresult *pgsql_result, zval *value) { - zend_string *tmp = zval_try_get_string(value); + zend_string *tmp_tmp; + zend_string *tmp = zval_try_get_tmp_string(value, &tmp_tmp); if (UNEXPECTED(!tmp)) { return FAILURE; } - zend_string *zquery = zend_string_alloc(ZSTR_LEN(tmp) + 2, false); - memcpy(ZSTR_VAL(zquery), ZSTR_VAL(tmp), ZSTR_LEN(tmp) + 1); - ZSTR_LEN(zquery) = ZSTR_LEN(tmp); - if (ZSTR_LEN(tmp) > 0 && ZSTR_VAL(zquery)[ZSTR_LEN(tmp) - 1] != '\n') { - ZSTR_VAL(zquery)[ZSTR_LEN(tmp)] = '\n'; - ZSTR_VAL(zquery)[ZSTR_LEN(tmp) + 1] = '\0'; - ZSTR_LEN(zquery) ++; - } - if (PQputCopyData(pgsql, ZSTR_VAL(zquery), ZSTR_LEN(zquery)) != 1) { - zend_string_release_ex(zquery, false); - zend_string_release(tmp); - return FAILURE; + + int result; + if (ZSTR_LEN(tmp) > 0 && ZSTR_VAL(tmp)[ZSTR_LEN(tmp) - 1] != '\n') { + char *zquery = emalloc(ZSTR_LEN(tmp) + 2); + memcpy(zquery, ZSTR_VAL(tmp), ZSTR_LEN(tmp)); + zquery[ZSTR_LEN(tmp)] = '\n'; + zquery[ZSTR_LEN(tmp) + 1] = '\0'; + result = PQputCopyData(pgsql, zquery, ZSTR_LEN(tmp) + 1); + efree(zquery); + } else { + result = PQputCopyData(pgsql, ZSTR_VAL(tmp), ZSTR_LEN(tmp)); } - zend_string_release_ex(zquery, false); - zend_string_release(tmp); - return SUCCESS; + + zend_tmp_string_release(tmp_tmp); + + return result != 1 ? FAILURE : SUCCESS; } /* {{{ Copy table from array */ @@ -3432,9 +3462,8 @@ PHP_FUNCTION(pg_copy_from) zval *value; zend_string *table_name; zend_string *pg_delimiter = NULL; - char *pg_null_as = NULL; + char *pg_null_as = "\\\\N"; size_t pg_null_as_len; - bool pg_null_as_free = false; char *query; PGconn *pgsql; PGresult *pgsql_result; @@ -3459,10 +3488,6 @@ PHP_FUNCTION(pg_copy_from) zend_argument_value_error(4, "must be one character"); RETURN_THROWS(); } - if (!pg_null_as) { - pg_null_as = estrdup("\\\\N"); - pg_null_as_free = true; - } spprintf(&query, 0, "COPY %s FROM STDIN DELIMITER E'%c' NULL AS E'%s'", ZSTR_VAL(table_name), *ZSTR_VAL(pg_delimiter), pg_null_as); while ((pgsql_result = PQgetResult(pgsql))) { @@ -3470,9 +3495,6 @@ PHP_FUNCTION(pg_copy_from) } pgsql_result = PQexec(pgsql, query); - if (pg_null_as_free) { - efree(pg_null_as); - } efree(query); if (pgsql_result) { @@ -3533,12 +3555,10 @@ PHP_FUNCTION(pg_copy_from) RETURN_FALSE; } RETURN_TRUE; - break; default: PQclear(pgsql_result); PHP_PQ_ERROR("Copy command failed: %s", pgsql); RETURN_FALSE; - break; } } /* }}} */ @@ -3572,8 +3592,14 @@ PHP_FUNCTION(pg_escape_string) to = zend_string_safe_alloc(ZSTR_LEN(from), 2, 0, 0); if (link) { + int err; pgsql = link->conn; - ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), NULL); + ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), &err); + if (err) { + zend_argument_value_error(ZEND_NUM_ARGS(), "Escaping string failed"); + zend_string_efree(to); + RETURN_THROWS(); + } } else { ZSTR_LEN(to) = PQescapeString(ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from)); @@ -3619,6 +3645,10 @@ PHP_FUNCTION(pg_escape_bytea) } else { to = (char *)PQescapeBytea((unsigned char *)ZSTR_VAL(from), ZSTR_LEN(from), &to_len); } + if (to == NULL) { + zend_argument_value_error(ZEND_NUM_ARGS(), "Escape failure"); + RETURN_THROWS(); + } RETVAL_STRINGL(to, to_len-1); /* to_len includes additional '\0' */ PQfreemem(to); @@ -3639,7 +3669,6 @@ PHP_FUNCTION(pg_unescape_bytea) tmp = (char *)PQunescapeBytea((unsigned char*)from, &to_len); if (!tmp) { zend_error_noreturn(E_ERROR, "Out of memory"); - return; } RETVAL_STRINGL(tmp, to_len); @@ -3751,12 +3780,8 @@ PHP_FUNCTION(pg_result_error_field) if (fieldcode & (PG_DIAG_SEVERITY|PG_DIAG_SQLSTATE|PG_DIAG_MESSAGE_PRIMARY|PG_DIAG_MESSAGE_DETAIL |PG_DIAG_MESSAGE_HINT|PG_DIAG_STATEMENT_POSITION -#ifdef PG_DIAG_INTERNAL_POSITION |PG_DIAG_INTERNAL_POSITION -#endif -#ifdef PG_DIAG_INTERNAL_QUERY |PG_DIAG_INTERNAL_QUERY -#endif |PG_DIAG_CONTEXT|PG_DIAG_SOURCE_FILE|PG_DIAG_SOURCE_LINE |PG_DIAG_SOURCE_FUNCTION)) { field = PQresultErrorField(pgsql_result, (int)fieldcode); @@ -3827,10 +3852,8 @@ PHP_FUNCTION(pg_connection_reset) pgsql = link->conn; PQreset(pgsql); - if (PQstatus(pgsql) == CONNECTION_BAD) { - RETURN_FALSE; - } - RETURN_TRUE; + + RETURN_BOOL(PQstatus(pgsql) != CONNECTION_BAD); } /* }}} */ @@ -3909,7 +3932,7 @@ static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) PQfreeCancel(c); break; } - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (PQsetnonblocking(pgsql, 0)) { php_error_docref(NULL, E_NOTICE, "Cannot set connection to blocking mode"); @@ -4016,9 +4039,9 @@ PHP_FUNCTION(pg_send_query) /* {{{ Send asynchronous parameterized query */ PHP_FUNCTION(pg_send_query_params) { - zval *pgsql_link, *pv_param_arr, *tmp; + zval *pgsql_link, *pv_param_arr; pgsql_link_handle *link; - int num_params = 0; + int num_params; char **params = NULL; char *query; size_t query_len; @@ -4048,25 +4071,9 @@ PHP_FUNCTION(pg_send_query_params) "There are results on this connection. Call pg_get_result() until it returns FALSE"); } - num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); - if (num_params > 0) { - int i = 0; - params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { - ZVAL_DEREF(tmp); - if (Z_TYPE_P(tmp) == IS_NULL) { - params[i] = NULL; - } else { - zend_string *tmp_str; - zend_string *str = zval_get_tmp_string(tmp, &tmp_str); - - params[i] = estrndup(ZSTR_VAL(str), ZSTR_LEN(str)); - zend_tmp_string_release(tmp_str); - } - - i++; - } ZEND_HASH_FOREACH_END(); + params = php_pgsql_make_arguments(Z_ARRVAL_P(pv_param_arr), &num_params); + if (UNEXPECTED(!params)) { + RETURN_THROWS(); } if (PQsendQueryParams(pgsql, query, num_params, NULL, (const char * const *)params, NULL, NULL, 0)) { @@ -4188,8 +4195,8 @@ PHP_FUNCTION(pg_send_execute) { zval *pgsql_link; pgsql_link_handle *link; - zval *pv_param_arr, *tmp; - int num_params = 0; + zval *pv_param_arr; + int num_params; char **params = NULL; char *stmtname; size_t stmtname_len; @@ -4219,27 +4226,9 @@ PHP_FUNCTION(pg_send_execute) "There are results on this connection. Call pg_get_result() until it returns FALSE"); } - num_params = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr)); - if (num_params > 0) { - int i = 0; - params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pv_param_arr), tmp) { - ZVAL_DEREF(tmp); - if (Z_TYPE_P(tmp) == IS_NULL) { - params[i] = NULL; - } else { - zend_string *tmp_str = zval_try_get_string(tmp); - if (UNEXPECTED(!tmp_str)) { - _php_pgsql_free_params(params, i); - return; - } - params[i] = estrndup(ZSTR_VAL(tmp_str), ZSTR_LEN(tmp_str)); - zend_string_release(tmp_str); - } - - i++; - } ZEND_HASH_FOREACH_END(); + params = php_pgsql_make_arguments(Z_ARRVAL_P(pv_param_arr), &num_params); + if (UNEXPECTED(!params)) { + RETURN_THROWS(); } if (PQsendQueryPrepared(pgsql, stmtname, num_params, (const char * const *)params, NULL, NULL, 0)) { @@ -4554,8 +4543,8 @@ PHP_FUNCTION(pg_flush) } switch (ret) { - case 0: RETURN_TRUE; break; - case 1: RETURN_LONG(0); break; + case 0: RETURN_TRUE; + case 1: RETURN_LONG(0); default: RETURN_FALSE; } } @@ -4572,7 +4561,7 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string char *escaped; smart_str querystr = {0}; size_t new_len, len; - int i, num_rows; + int i, num_rows, err; zval elem; ZEND_ASSERT(ZSTR_LEN(table_name) != 0); @@ -4611,7 +4600,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string } len = strlen(tmp_name2); escaped = (char *)safe_emalloc(len, 2, 1); - new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, len, NULL); + new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, len, &err); + if (err) { + php_error_docref(NULL, E_WARNING, "Escaping table name '%s' failed", ZSTR_VAL(table_name)); + efree(src); + efree(escaped); + smart_str_free(&querystr); + return FAILURE; + } if (new_len) { smart_str_appendl(&querystr, escaped, new_len); } @@ -4620,7 +4616,14 @@ PHP_PGSQL_API zend_result php_pgsql_meta_data(PGconn *pg_link, const zend_string smart_str_appends(&querystr, "' AND n.nspname = '"); len = strlen(tmp_name); escaped = (char *)safe_emalloc(len, 2, 1); - new_len = PQescapeStringConn(pg_link, escaped, tmp_name, len, NULL); + new_len = PQescapeStringConn(pg_link, escaped, tmp_name, len, &err); + if (err) { + php_error_docref(NULL, E_WARNING, "Escaping table namespace '%s' failed", ZSTR_VAL(table_name)); + efree(src); + efree(escaped); + smart_str_free(&querystr); + return FAILURE; + } if (new_len) { smart_str_appendl(&querystr, escaped, new_len); } @@ -4875,7 +4878,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * { zend_string *field = NULL; zval meta, *def, *type, *not_null, *has_default, *is_enum, *val, new_val; - int err = 0; + int err = 0, escape_err = 0; bool skip_field; php_pgsql_data_type data_type; @@ -4889,7 +4892,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * array_init(&meta); /* table_name is escaped by php_pgsql_meta_data */ - if (php_pgsql_meta_data(pg_link, table_name, &meta, 0) == FAILURE) { + if (php_pgsql_meta_data(pg_link, table_name, &meta, false) == FAILURE) { zval_ptr_dtor(&meta); return FAILURE; } @@ -4934,7 +4937,7 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * break; /* break out for() */ } - if (zval_is_true(is_enum)) { + if (zend_is_true(is_enum)) { /* enums need to be treated like strings */ data_type = PG_TEXT; } else { @@ -5121,8 +5124,13 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * /* PostgreSQL ignores \0 */ str = zend_string_alloc(Z_STRLEN_P(val) * 2, 0); /* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */ - ZSTR_LEN(str) = PQescapeStringConn(pg_link, ZSTR_VAL(str), Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); - ZVAL_STR(&new_val, php_pgsql_add_quotes(str)); + ZSTR_LEN(str) = PQescapeStringConn(pg_link, ZSTR_VAL(str), + Z_STRVAL_P(val), Z_STRLEN_P(val), &escape_err); + if (escape_err) { + err = 1; + } else { + ZVAL_STR(&new_val, php_pgsql_add_quotes(str)); + } zend_string_release_ex(str, false); } break; @@ -5145,7 +5153,14 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * } PGSQL_CONV_CHECK_IGNORE(); if (err) { - zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type)); + if (escape_err) { + php_error_docref(NULL, E_NOTICE, + "String value escaping failed for PostgreSQL '%s' (%s)", + Z_STRVAL_P(type), ZSTR_VAL(field)); + } else { + zend_type_error("%s(): Field \"%s\" must be of type string|null, %s given", + get_active_function_name(), ZSTR_VAL(field), Z_STRVAL_P(type)); + } } break; @@ -5379,6 +5394,11 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * zend_string *tmp_zstr; tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val), &to_len); + if (tmp == NULL) { + php_error_docref(NULL, E_NOTICE, "Escaping value failed for %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field)); + err = 1; + break; + } tmp_zstr = zend_string_init((char *)tmp, to_len - 1, false); /* PQescapeBytea's to_len includes additional '\0' */ PQfreemem(tmp); @@ -5455,6 +5475,12 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * zend_hash_update(Z_ARRVAL_P(result), field, &new_val); } else { char *escaped = PQescapeIdentifier(pg_link, ZSTR_VAL(field), ZSTR_LEN(field)); + if (escaped == NULL) { + /* This cannot fail because of invalid string but only due to failed memory allocation */ + php_error_docref(NULL, E_NOTICE, "Escaping field '%s' failed", ZSTR_VAL(field)); + err = 1; + break; + } add_assoc_zval(result, escaped, &new_val); PQfreemem(escaped); } @@ -5537,7 +5563,7 @@ static bool do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link, } /* }}} */ -static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const zend_string *table) /* {{{ */ +static inline zend_result build_tablename(smart_str *querystr, PGconn *pg_link, const zend_string *table) /* {{{ */ { /* schema.table should be "schema"."table" */ const char *dot = memchr(ZSTR_VAL(table), '.', ZSTR_LEN(table)); @@ -5547,6 +5573,10 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z smart_str_appendl(querystr, ZSTR_VAL(table), len); } else { char *escaped = PQescapeIdentifier(pg_link, ZSTR_VAL(table), len); + if (escaped == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape table name '%s'", ZSTR_VAL(table)); + return FAILURE; + } smart_str_appends(querystr, escaped); PQfreemem(escaped); } @@ -5559,11 +5589,17 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z smart_str_appendl(querystr, after_dot, len); } else { char *escaped = PQescapeIdentifier(pg_link, after_dot, len); + if (escaped == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape table name '%s'", ZSTR_VAL(table)); + return FAILURE; + } smart_str_appendc(querystr, '.'); smart_str_appends(querystr, escaped); PQfreemem(escaped); } } + + return SUCCESS; } /* }}} */ @@ -5571,7 +5607,6 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const z PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *table, zval *var_array, zend_ulong opt, zend_string **sql) { zval *val, converted; - char buf[256]; char *tmp; smart_str querystr = {0}; zend_result ret = FAILURE; @@ -5584,7 +5619,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t ZVAL_UNDEF(&converted); if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0) { smart_str_appends(&querystr, "INSERT INTO "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " DEFAULT VALUES"); goto no_values; @@ -5600,7 +5637,9 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "INSERT INTO "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " ("); ZEND_HASH_FOREACH_STR_KEY(Z_ARRVAL_P(var_array), fld) { @@ -5609,7 +5648,11 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t goto cleanup; } if (opt & PGSQL_DML_ESCAPE) { - tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1); + tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld)); + if (tmp == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s'", ZSTR_VAL(fld)); + goto cleanup; + } smart_str_appends(&querystr, tmp); PQfreemem(tmp); } else { @@ -5621,15 +5664,19 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t smart_str_appends(&querystr, ") VALUES ("); /* make values string */ - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(var_array), val) { + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(var_array), fld, val) { /* we can avoid the key_type check here, because we tested it in the other loop */ switch (Z_TYPE_P(val)) { case IS_STRING: if (opt & PGSQL_DML_ESCAPE) { - size_t new_len; - char *tmp; - tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1); - new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); + int error; + char *tmp = safe_emalloc(Z_STRLEN_P(val), 2, 1); + size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), &error); + if (error) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s' value", ZSTR_VAL(fld)); + efree(tmp); + goto cleanup; + } smart_str_appendc(&querystr, '\''); smart_str_appendl(&querystr, tmp, new_len); smart_str_appendc(&querystr, '\''); @@ -5642,7 +5689,7 @@ PHP_PGSQL_API zend_result php_pgsql_insert(PGconn *pg_link, const zend_string *t smart_str_append_long(&querystr, Z_LVAL_P(val)); break; case IS_DOUBLE: - smart_str_appendl(&querystr, buf, snprintf(buf, sizeof(buf), "%F", Z_DVAL_P(val))); + smart_str_append_double(&querystr, Z_DVAL_P(val), 6, false); break; case IS_NULL: smart_str_appendl(&querystr, "NULL", sizeof("NULL")-1); @@ -5748,7 +5795,6 @@ PHP_FUNCTION(pg_insert) PHP_PQ_ERROR("Query failed: %s", pg_link); PQclear(pg_result); RETURN_FALSE; - break; case PGRES_COMMAND_OK: /* successful command that did not return rows */ default: if (pg_result) { @@ -5786,7 +5832,11 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, return -1; } if (opt & PGSQL_DML_ESCAPE) { - char *tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1); + char *tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld)); + if (tmp == NULL) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s'", ZSTR_VAL(fld)); + return -1; + } smart_str_appends(querystr, tmp); PQfreemem(tmp); } else { @@ -5802,8 +5852,14 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, switch (Z_TYPE_P(val)) { case IS_STRING: if (opt & PGSQL_DML_ESCAPE) { + int error; char *tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1); - size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL); + size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), &error); + if (error) { + php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s' value", ZSTR_VAL(fld)); + efree(tmp); + return -1; + } smart_str_appendc(querystr, '\''); smart_str_appendl(querystr, tmp, new_len); smart_str_appendc(querystr, '\''); @@ -5816,8 +5872,7 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr, smart_str_append_long(querystr, Z_LVAL_P(val)); break; case IS_DOUBLE: { - char buf[256]; - smart_str_appendl(querystr, buf, MIN(snprintf(buf, sizeof(buf), "%F", Z_DVAL_P(val)), sizeof(buf) - 1)); + smart_str_append_double(querystr, Z_DVAL_P(val), 6, false); } break; case IS_NULL: @@ -5871,7 +5926,9 @@ PHP_PGSQL_API zend_result php_pgsql_update(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "UPDATE "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " SET "); if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(var_array), 0, ",", 1, opt)) @@ -5977,7 +6034,9 @@ PHP_PGSQL_API zend_result php_pgsql_delete(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "DELETE FROM "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } smart_str_appends(&querystr, " WHERE "); if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt)) @@ -6121,7 +6180,9 @@ PHP_PGSQL_API zend_result php_pgsql_select(PGconn *pg_link, const zend_string *t } smart_str_appends(&querystr, "SELECT * FROM "); - build_tablename(&querystr, pg_link, table); + if (build_tablename(&querystr, pg_link, table) == FAILURE) { + goto cleanup; + } if (is_valid_ids_array) { smart_str_appends(&querystr, " WHERE "); @@ -6168,7 +6229,6 @@ PHP_FUNCTION(pg_select) PGconn *pg_link; zend_string *sql = NULL; - /* TODO Document result_type param on php.net (apparently it was added in PHP 7.1) */ ZEND_PARSE_PARAMETERS_START(2, 5) Z_PARAM_OBJECT_OF_CLASS(pgsql_link, pgsql_link_ce) Z_PARAM_PATH_STR(table) @@ -6304,7 +6364,7 @@ PHP_FUNCTION(pg_socket_poll) Z_PARAM_LONG(ts) ZEND_PARSE_PARAMETERS_END(); - if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void **)&socket, 0)) { + if (UNEXPECTED(php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void **)&socket, 0) == FAILURE)) { zend_argument_type_error(1, "invalid resource socket"); RETURN_THROWS(); } diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php index 04e648eff8d5..52ddc3b3748a 100644 --- a/ext/pgsql/pgsql.stub.php +++ b/ext/pgsql/pgsql.stub.php @@ -13,8 +13,8 @@ /** * @var string * @cvalue pgsql_libpq_version - * @deprecated */ + #[\Deprecated(since: '8.0', message: 'as it is the same as PGSQL_LIBPQ_VERSION')] const PGSQL_LIBPQ_VERSION_STR = UNKNOWN; /* For connection option */ @@ -98,13 +98,11 @@ * @cvalue CONNECTION_AUTH_OK */ const PGSQL_CONNECTION_AUTH_OK = UNKNOWN; -#ifdef CONNECTION_SSL_STARTUP /** * @var int * @cvalue CONNECTION_SSL_STARTUP */ const PGSQL_CONNECTION_SSL_STARTUP = UNKNOWN; -#endif /** * @var int * @cvalue CONNECTION_SETENV @@ -310,20 +308,16 @@ * @cvalue PG_DIAG_STATEMENT_POSITION */ const PGSQL_DIAG_STATEMENT_POSITION = UNKNOWN; -#ifdef PG_DIAG_INTERNAL_POSITION /** * @var int * @cvalue PG_DIAG_INTERNAL_POSITION */ const PGSQL_DIAG_INTERNAL_POSITION = UNKNOWN; -#endif -#ifdef PG_DIAG_INTERNAL_QUERY /** * @var int * @cvalue PG_DIAG_INTERNAL_QUERY */ const PGSQL_DIAG_INTERNAL_QUERY = UNKNOWN; -#endif /** * @var int * @cvalue PG_DIAG_CONTEXT @@ -344,48 +338,36 @@ * @cvalue PG_DIAG_SOURCE_FUNCTION */ const PGSQL_DIAG_SOURCE_FUNCTION = UNKNOWN; -#ifdef PG_DIAG_SCHEMA_NAME /** * @var int * @cvalue PG_DIAG_SCHEMA_NAME */ const PGSQL_DIAG_SCHEMA_NAME = UNKNOWN; -#endif -#ifdef PG_DIAG_TABLE_NAME /** * @var int * @cvalue PG_DIAG_TABLE_NAME */ const PGSQL_DIAG_TABLE_NAME = UNKNOWN; -#endif -#ifdef PG_DIAG_COLUMN_NAME /** * @var int * @cvalue PG_DIAG_COLUMN_NAME */ const PGSQL_DIAG_COLUMN_NAME = UNKNOWN; -#endif -#ifdef PG_DIAG_DATATYPE_NAME /** * @var int * @cvalue PG_DIAG_DATATYPE_NAME */ const PGSQL_DIAG_DATATYPE_NAME = UNKNOWN; -#endif -#ifdef PG_DIAG_CONSTRAINT_NAME /** * @var int * @cvalue PG_DIAG_CONSTRAINT_NAME */ const PGSQL_DIAG_CONSTRAINT_NAME = UNKNOWN; -#endif -#ifdef PG_DIAG_SEVERITY_NONLOCALIZED /** * @var int * @cvalue PG_DIAG_SEVERITY_NONLOCALIZED */ const PGSQL_DIAG_SEVERITY_NONLOCALIZED = UNKNOWN; -#endif /* pg_convert options */ @@ -432,7 +414,7 @@ * @cvalue PGSQL_DML_STRING */ const PGSQL_DML_STRING = UNKNOWN; -#ifdef PQTRACE_SUPPPRESS_TIMESTAMPS +#ifdef PQTRACE_SUPPRESS_TIMESTAMPS /** * @var int * @cvalue PQTRACE_SUPPRESS_TIMESTAMPS diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index cb58645e5e9f..63a1d185d535 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3cf44ca06d11cad086829d3d04900ade3cacb88b */ +/* This is a generated file, edit pgsql.stub.php instead. + * Stub hash: f25b5a574c96d4bc2f08b8cacab16f499a164a6b */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_pg_connect, 0, 1, PgSql\\Connection, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0) @@ -757,7 +757,7 @@ static const zend_function_entry ext_functions[] = { static void register_pgsql_symbols(int module_number) { REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION", pgsql_libpq_version, CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION_STR", pgsql_libpq_version, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_PGSQL_LIBPQ_VERSION_STR = REGISTER_STRING_CONSTANT("PGSQL_LIBPQ_VERSION_STR", pgsql_libpq_version, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("PGSQL_CONNECT_FORCE_NEW", PGSQL_CONNECT_FORCE_NEW, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECT_ASYNC", PGSQL_CONNECT_ASYNC, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_PERSISTENT); @@ -772,9 +772,7 @@ static void register_pgsql_symbols(int module_number) REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_MADE", CONNECTION_MADE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AWAITING_RESPONSE", CONNECTION_AWAITING_RESPONSE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_AUTH_OK", CONNECTION_AUTH_OK, CONST_PERSISTENT); -#if defined(CONNECTION_SSL_STARTUP) REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SSL_STARTUP", CONNECTION_SSL_STARTUP, CONST_PERSISTENT); -#endif REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_SETENV", CONNECTION_SETENV, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_POLLING_FAILED", PGRES_POLLING_FAILED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_POLLING_READING", PGRES_POLLING_READING, CONST_PERSISTENT); @@ -817,34 +815,18 @@ static void register_pgsql_symbols(int module_number) REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_DETAIL", PG_DIAG_MESSAGE_DETAIL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DIAG_MESSAGE_HINT", PG_DIAG_MESSAGE_HINT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DIAG_STATEMENT_POSITION", PG_DIAG_STATEMENT_POSITION, CONST_PERSISTENT); -#if defined(PG_DIAG_INTERNAL_POSITION) REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_POSITION", PG_DIAG_INTERNAL_POSITION, CONST_PERSISTENT); -#endif -#if defined(PG_DIAG_INTERNAL_QUERY) REGISTER_LONG_CONSTANT("PGSQL_DIAG_INTERNAL_QUERY", PG_DIAG_INTERNAL_QUERY, CONST_PERSISTENT); -#endif REGISTER_LONG_CONSTANT("PGSQL_DIAG_CONTEXT", PG_DIAG_CONTEXT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FILE", PG_DIAG_SOURCE_FILE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_LINE", PG_DIAG_SOURCE_LINE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DIAG_SOURCE_FUNCTION", PG_DIAG_SOURCE_FUNCTION, CONST_PERSISTENT); -#if defined(PG_DIAG_SCHEMA_NAME) REGISTER_LONG_CONSTANT("PGSQL_DIAG_SCHEMA_NAME", PG_DIAG_SCHEMA_NAME, CONST_PERSISTENT); -#endif -#if defined(PG_DIAG_TABLE_NAME) REGISTER_LONG_CONSTANT("PGSQL_DIAG_TABLE_NAME", PG_DIAG_TABLE_NAME, CONST_PERSISTENT); -#endif -#if defined(PG_DIAG_COLUMN_NAME) REGISTER_LONG_CONSTANT("PGSQL_DIAG_COLUMN_NAME", PG_DIAG_COLUMN_NAME, CONST_PERSISTENT); -#endif -#if defined(PG_DIAG_DATATYPE_NAME) REGISTER_LONG_CONSTANT("PGSQL_DIAG_DATATYPE_NAME", PG_DIAG_DATATYPE_NAME, CONST_PERSISTENT); -#endif -#if defined(PG_DIAG_CONSTRAINT_NAME) REGISTER_LONG_CONSTANT("PGSQL_DIAG_CONSTRAINT_NAME", PG_DIAG_CONSTRAINT_NAME, CONST_PERSISTENT); -#endif -#if defined(PG_DIAG_SEVERITY_NONLOCALIZED) REGISTER_LONG_CONSTANT("PGSQL_DIAG_SEVERITY_NONLOCALIZED", PG_DIAG_SEVERITY_NONLOCALIZED, CONST_PERSISTENT); -#endif REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_DEFAULT", PGSQL_CONV_IGNORE_DEFAULT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONV_FORCE_NULL", PGSQL_CONV_FORCE_NULL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_CONV_IGNORE_NOT_NULL", PGSQL_CONV_IGNORE_NOT_NULL, CONST_PERSISTENT); @@ -853,7 +835,7 @@ static void register_pgsql_symbols(int module_number) REGISTER_LONG_CONSTANT("PGSQL_DML_EXEC", PGSQL_DML_EXEC, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DML_ASYNC", PGSQL_DML_ASYNC, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_PERSISTENT); -#if defined(PQTRACE_SUPPPRESS_TIMESTAMPS) +#if defined(PQTRACE_SUPPRESS_TIMESTAMPS) REGISTER_LONG_CONSTANT("PGSQL_TRACE_SUPPRESS_TIMESTAMPS", PQTRACE_SUPPRESS_TIMESTAMPS, CONST_PERSISTENT); #endif #if defined(PQTRACE_REGRESS_MODE) @@ -865,294 +847,181 @@ static void register_pgsql_symbols(int module_number) zend_attribute *attribute_Deprecated_func_pg_errormessage_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_errormessage", sizeof("pg_errormessage") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_errormessage_0_arg0; - zend_string *attribute_Deprecated_func_pg_errormessage_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_errormessage_0_arg0, attribute_Deprecated_func_pg_errormessage_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_errormessage_0->args[0].value, &attribute_Deprecated_func_pg_errormessage_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_errormessage_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_errormessage_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_errormessage_0_arg1; zend_string *attribute_Deprecated_func_pg_errormessage_0_arg1_str = zend_string_init("use pg_last_error() instead", strlen("use pg_last_error() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_errormessage_0_arg1, attribute_Deprecated_func_pg_errormessage_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_errormessage_0->args[1].value, &attribute_Deprecated_func_pg_errormessage_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_errormessage_0->args[1].value, attribute_Deprecated_func_pg_errormessage_0_arg1_str); attribute_Deprecated_func_pg_errormessage_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_numrows_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_numrows", sizeof("pg_numrows") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_numrows_0_arg0; - zend_string *attribute_Deprecated_func_pg_numrows_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_numrows_0_arg0, attribute_Deprecated_func_pg_numrows_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_numrows_0->args[0].value, &attribute_Deprecated_func_pg_numrows_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_numrows_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_numrows_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_numrows_0_arg1; zend_string *attribute_Deprecated_func_pg_numrows_0_arg1_str = zend_string_init("use pg_num_rows() instead", strlen("use pg_num_rows() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_numrows_0_arg1, attribute_Deprecated_func_pg_numrows_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_numrows_0->args[1].value, &attribute_Deprecated_func_pg_numrows_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_numrows_0->args[1].value, attribute_Deprecated_func_pg_numrows_0_arg1_str); attribute_Deprecated_func_pg_numrows_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_numfields_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_numfields", sizeof("pg_numfields") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_numfields_0_arg0; - zend_string *attribute_Deprecated_func_pg_numfields_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_numfields_0_arg0, attribute_Deprecated_func_pg_numfields_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_numfields_0->args[0].value, &attribute_Deprecated_func_pg_numfields_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_numfields_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_numfields_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_numfields_0_arg1; zend_string *attribute_Deprecated_func_pg_numfields_0_arg1_str = zend_string_init("use pg_num_fields() instead", strlen("use pg_num_fields() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_numfields_0_arg1, attribute_Deprecated_func_pg_numfields_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_numfields_0->args[1].value, &attribute_Deprecated_func_pg_numfields_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_numfields_0->args[1].value, attribute_Deprecated_func_pg_numfields_0_arg1_str); attribute_Deprecated_func_pg_numfields_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_cmdtuples_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_cmdtuples", sizeof("pg_cmdtuples") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_cmdtuples_0_arg0; - zend_string *attribute_Deprecated_func_pg_cmdtuples_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_cmdtuples_0_arg0, attribute_Deprecated_func_pg_cmdtuples_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_cmdtuples_0->args[0].value, &attribute_Deprecated_func_pg_cmdtuples_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_cmdtuples_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_cmdtuples_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_cmdtuples_0_arg1; zend_string *attribute_Deprecated_func_pg_cmdtuples_0_arg1_str = zend_string_init("use pg_affected_rows() instead", strlen("use pg_affected_rows() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_cmdtuples_0_arg1, attribute_Deprecated_func_pg_cmdtuples_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_cmdtuples_0->args[1].value, &attribute_Deprecated_func_pg_cmdtuples_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_cmdtuples_0->args[1].value, attribute_Deprecated_func_pg_cmdtuples_0_arg1_str); attribute_Deprecated_func_pg_cmdtuples_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldname_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldname", sizeof("pg_fieldname") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_fieldname_0_arg0; - zend_string *attribute_Deprecated_func_pg_fieldname_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldname_0_arg0, attribute_Deprecated_func_pg_fieldname_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldname_0->args[0].value, &attribute_Deprecated_func_pg_fieldname_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldname_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldname_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldname_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldname_0_arg1_str = zend_string_init("use pg_field_name() instead", strlen("use pg_field_name() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldname_0_arg1, attribute_Deprecated_func_pg_fieldname_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldname_0->args[1].value, &attribute_Deprecated_func_pg_fieldname_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldname_0->args[1].value, attribute_Deprecated_func_pg_fieldname_0_arg1_str); attribute_Deprecated_func_pg_fieldname_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldsize_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldsize", sizeof("pg_fieldsize") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_fieldsize_0_arg0; - zend_string *attribute_Deprecated_func_pg_fieldsize_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldsize_0_arg0, attribute_Deprecated_func_pg_fieldsize_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldsize_0->args[0].value, &attribute_Deprecated_func_pg_fieldsize_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldsize_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldsize_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldsize_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldsize_0_arg1_str = zend_string_init("use pg_field_size() instead", strlen("use pg_field_size() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldsize_0_arg1, attribute_Deprecated_func_pg_fieldsize_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldsize_0->args[1].value, &attribute_Deprecated_func_pg_fieldsize_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldsize_0->args[1].value, attribute_Deprecated_func_pg_fieldsize_0_arg1_str); attribute_Deprecated_func_pg_fieldsize_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldtype_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldtype", sizeof("pg_fieldtype") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_fieldtype_0_arg0; - zend_string *attribute_Deprecated_func_pg_fieldtype_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldtype_0_arg0, attribute_Deprecated_func_pg_fieldtype_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldtype_0->args[0].value, &attribute_Deprecated_func_pg_fieldtype_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldtype_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldtype_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldtype_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldtype_0_arg1_str = zend_string_init("use pg_field_type() instead", strlen("use pg_field_type() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldtype_0_arg1, attribute_Deprecated_func_pg_fieldtype_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldtype_0->args[1].value, &attribute_Deprecated_func_pg_fieldtype_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldtype_0->args[1].value, attribute_Deprecated_func_pg_fieldtype_0_arg1_str); attribute_Deprecated_func_pg_fieldtype_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldnum_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldnum", sizeof("pg_fieldnum") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_fieldnum_0_arg0; - zend_string *attribute_Deprecated_func_pg_fieldnum_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldnum_0_arg0, attribute_Deprecated_func_pg_fieldnum_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldnum_0->args[0].value, &attribute_Deprecated_func_pg_fieldnum_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldnum_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldnum_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldnum_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldnum_0_arg1_str = zend_string_init("use pg_field_num() instead", strlen("use pg_field_num() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldnum_0_arg1, attribute_Deprecated_func_pg_fieldnum_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldnum_0->args[1].value, &attribute_Deprecated_func_pg_fieldnum_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldnum_0->args[1].value, attribute_Deprecated_func_pg_fieldnum_0_arg1_str); attribute_Deprecated_func_pg_fieldnum_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_result_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_result", sizeof("pg_result") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_result_0_arg0; - zend_string *attribute_Deprecated_func_pg_result_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_result_0_arg0, attribute_Deprecated_func_pg_result_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_result_0->args[0].value, &attribute_Deprecated_func_pg_result_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_result_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_result_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_result_0_arg1; zend_string *attribute_Deprecated_func_pg_result_0_arg1_str = zend_string_init("use pg_fetch_result() instead", strlen("use pg_fetch_result() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_result_0_arg1, attribute_Deprecated_func_pg_result_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_result_0->args[1].value, &attribute_Deprecated_func_pg_result_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_result_0->args[1].value, attribute_Deprecated_func_pg_result_0_arg1_str); attribute_Deprecated_func_pg_result_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldprtlen_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldprtlen", sizeof("pg_fieldprtlen") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_fieldprtlen_0_arg0; - zend_string *attribute_Deprecated_func_pg_fieldprtlen_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldprtlen_0_arg0, attribute_Deprecated_func_pg_fieldprtlen_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldprtlen_0->args[0].value, &attribute_Deprecated_func_pg_fieldprtlen_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldprtlen_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldprtlen_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldprtlen_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldprtlen_0_arg1_str = zend_string_init("use pg_field_prtlen() instead", strlen("use pg_field_prtlen() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldprtlen_0_arg1, attribute_Deprecated_func_pg_fieldprtlen_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldprtlen_0->args[1].value, &attribute_Deprecated_func_pg_fieldprtlen_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldprtlen_0->args[1].value, attribute_Deprecated_func_pg_fieldprtlen_0_arg1_str); attribute_Deprecated_func_pg_fieldprtlen_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_fieldisnull_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_fieldisnull", sizeof("pg_fieldisnull") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_fieldisnull_0_arg0; - zend_string *attribute_Deprecated_func_pg_fieldisnull_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldisnull_0_arg0, attribute_Deprecated_func_pg_fieldisnull_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldisnull_0->args[0].value, &attribute_Deprecated_func_pg_fieldisnull_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldisnull_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_fieldisnull_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_fieldisnull_0_arg1; zend_string *attribute_Deprecated_func_pg_fieldisnull_0_arg1_str = zend_string_init("use pg_field_is_null() instead", strlen("use pg_field_is_null() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_fieldisnull_0_arg1, attribute_Deprecated_func_pg_fieldisnull_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_fieldisnull_0->args[1].value, &attribute_Deprecated_func_pg_fieldisnull_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_fieldisnull_0->args[1].value, attribute_Deprecated_func_pg_fieldisnull_0_arg1_str); attribute_Deprecated_func_pg_fieldisnull_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_freeresult_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_freeresult", sizeof("pg_freeresult") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_freeresult_0_arg0; - zend_string *attribute_Deprecated_func_pg_freeresult_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_freeresult_0_arg0, attribute_Deprecated_func_pg_freeresult_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_freeresult_0->args[0].value, &attribute_Deprecated_func_pg_freeresult_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_freeresult_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_freeresult_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_freeresult_0_arg1; zend_string *attribute_Deprecated_func_pg_freeresult_0_arg1_str = zend_string_init("use pg_free_result() instead", strlen("use pg_free_result() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_freeresult_0_arg1, attribute_Deprecated_func_pg_freeresult_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_freeresult_0->args[1].value, &attribute_Deprecated_func_pg_freeresult_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_freeresult_0->args[1].value, attribute_Deprecated_func_pg_freeresult_0_arg1_str); attribute_Deprecated_func_pg_freeresult_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_getlastoid_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_getlastoid", sizeof("pg_getlastoid") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_getlastoid_0_arg0; - zend_string *attribute_Deprecated_func_pg_getlastoid_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_getlastoid_0_arg0, attribute_Deprecated_func_pg_getlastoid_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_getlastoid_0->args[0].value, &attribute_Deprecated_func_pg_getlastoid_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_getlastoid_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_getlastoid_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_getlastoid_0_arg1; zend_string *attribute_Deprecated_func_pg_getlastoid_0_arg1_str = zend_string_init("use pg_last_oid() instead", strlen("use pg_last_oid() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_getlastoid_0_arg1, attribute_Deprecated_func_pg_getlastoid_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_getlastoid_0->args[1].value, &attribute_Deprecated_func_pg_getlastoid_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_getlastoid_0->args[1].value, attribute_Deprecated_func_pg_getlastoid_0_arg1_str); attribute_Deprecated_func_pg_getlastoid_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_locreate_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_locreate", sizeof("pg_locreate") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_locreate_0_arg0; - zend_string *attribute_Deprecated_func_pg_locreate_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_locreate_0_arg0, attribute_Deprecated_func_pg_locreate_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_locreate_0->args[0].value, &attribute_Deprecated_func_pg_locreate_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_locreate_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_locreate_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_locreate_0_arg1; zend_string *attribute_Deprecated_func_pg_locreate_0_arg1_str = zend_string_init("use pg_lo_create() instead", strlen("use pg_lo_create() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_locreate_0_arg1, attribute_Deprecated_func_pg_locreate_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_locreate_0->args[1].value, &attribute_Deprecated_func_pg_locreate_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_locreate_0->args[1].value, attribute_Deprecated_func_pg_locreate_0_arg1_str); attribute_Deprecated_func_pg_locreate_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_lounlink_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_lounlink", sizeof("pg_lounlink") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_lounlink_0_arg0; - zend_string *attribute_Deprecated_func_pg_lounlink_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_lounlink_0_arg0, attribute_Deprecated_func_pg_lounlink_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_lounlink_0->args[0].value, &attribute_Deprecated_func_pg_lounlink_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_lounlink_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_lounlink_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_lounlink_0_arg1; zend_string *attribute_Deprecated_func_pg_lounlink_0_arg1_str = zend_string_init("use pg_lo_unlink() instead", strlen("use pg_lo_unlink() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_lounlink_0_arg1, attribute_Deprecated_func_pg_lounlink_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_lounlink_0->args[1].value, &attribute_Deprecated_func_pg_lounlink_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_lounlink_0->args[1].value, attribute_Deprecated_func_pg_lounlink_0_arg1_str); attribute_Deprecated_func_pg_lounlink_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loopen_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loopen", sizeof("pg_loopen") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_loopen_0_arg0; - zend_string *attribute_Deprecated_func_pg_loopen_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loopen_0_arg0, attribute_Deprecated_func_pg_loopen_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loopen_0->args[0].value, &attribute_Deprecated_func_pg_loopen_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_loopen_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loopen_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loopen_0_arg1; zend_string *attribute_Deprecated_func_pg_loopen_0_arg1_str = zend_string_init("use pg_lo_open() instead", strlen("use pg_lo_open() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loopen_0_arg1, attribute_Deprecated_func_pg_loopen_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loopen_0->args[1].value, &attribute_Deprecated_func_pg_loopen_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loopen_0->args[1].value, attribute_Deprecated_func_pg_loopen_0_arg1_str); attribute_Deprecated_func_pg_loopen_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loclose_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loclose", sizeof("pg_loclose") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_loclose_0_arg0; - zend_string *attribute_Deprecated_func_pg_loclose_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loclose_0_arg0, attribute_Deprecated_func_pg_loclose_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loclose_0->args[0].value, &attribute_Deprecated_func_pg_loclose_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_loclose_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loclose_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loclose_0_arg1; zend_string *attribute_Deprecated_func_pg_loclose_0_arg1_str = zend_string_init("use pg_lo_close() instead", strlen("use pg_lo_close() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loclose_0_arg1, attribute_Deprecated_func_pg_loclose_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loclose_0->args[1].value, &attribute_Deprecated_func_pg_loclose_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loclose_0->args[1].value, attribute_Deprecated_func_pg_loclose_0_arg1_str); attribute_Deprecated_func_pg_loclose_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loread_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loread", sizeof("pg_loread") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_loread_0_arg0; - zend_string *attribute_Deprecated_func_pg_loread_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loread_0_arg0, attribute_Deprecated_func_pg_loread_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loread_0->args[0].value, &attribute_Deprecated_func_pg_loread_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_loread_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loread_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loread_0_arg1; zend_string *attribute_Deprecated_func_pg_loread_0_arg1_str = zend_string_init("use pg_lo_read() instead", strlen("use pg_lo_read() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loread_0_arg1, attribute_Deprecated_func_pg_loread_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loread_0->args[1].value, &attribute_Deprecated_func_pg_loread_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loread_0->args[1].value, attribute_Deprecated_func_pg_loread_0_arg1_str); attribute_Deprecated_func_pg_loread_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_lowrite_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_lowrite", sizeof("pg_lowrite") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_lowrite_0_arg0; - zend_string *attribute_Deprecated_func_pg_lowrite_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_lowrite_0_arg0, attribute_Deprecated_func_pg_lowrite_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_lowrite_0->args[0].value, &attribute_Deprecated_func_pg_lowrite_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_lowrite_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_lowrite_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_lowrite_0_arg1; zend_string *attribute_Deprecated_func_pg_lowrite_0_arg1_str = zend_string_init("use pg_lo_write() instead", strlen("use pg_lo_write() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_lowrite_0_arg1, attribute_Deprecated_func_pg_lowrite_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_lowrite_0->args[1].value, &attribute_Deprecated_func_pg_lowrite_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_lowrite_0->args[1].value, attribute_Deprecated_func_pg_lowrite_0_arg1_str); attribute_Deprecated_func_pg_lowrite_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loreadall_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loreadall", sizeof("pg_loreadall") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_loreadall_0_arg0; - zend_string *attribute_Deprecated_func_pg_loreadall_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loreadall_0_arg0, attribute_Deprecated_func_pg_loreadall_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loreadall_0->args[0].value, &attribute_Deprecated_func_pg_loreadall_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_loreadall_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loreadall_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loreadall_0_arg1; zend_string *attribute_Deprecated_func_pg_loreadall_0_arg1_str = zend_string_init("use pg_lo_read_all() instead", strlen("use pg_lo_read_all() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loreadall_0_arg1, attribute_Deprecated_func_pg_loreadall_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loreadall_0->args[1].value, &attribute_Deprecated_func_pg_loreadall_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loreadall_0->args[1].value, attribute_Deprecated_func_pg_loreadall_0_arg1_str); attribute_Deprecated_func_pg_loreadall_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loimport_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loimport", sizeof("pg_loimport") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_loimport_0_arg0; - zend_string *attribute_Deprecated_func_pg_loimport_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loimport_0_arg0, attribute_Deprecated_func_pg_loimport_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loimport_0->args[0].value, &attribute_Deprecated_func_pg_loimport_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_loimport_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loimport_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loimport_0_arg1; zend_string *attribute_Deprecated_func_pg_loimport_0_arg1_str = zend_string_init("use pg_lo_import() instead", strlen("use pg_lo_import() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loimport_0_arg1, attribute_Deprecated_func_pg_loimport_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loimport_0->args[1].value, &attribute_Deprecated_func_pg_loimport_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loimport_0->args[1].value, attribute_Deprecated_func_pg_loimport_0_arg1_str); attribute_Deprecated_func_pg_loimport_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_loexport_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_loexport", sizeof("pg_loexport") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_loexport_0_arg0; - zend_string *attribute_Deprecated_func_pg_loexport_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loexport_0_arg0, attribute_Deprecated_func_pg_loexport_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loexport_0->args[0].value, &attribute_Deprecated_func_pg_loexport_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_loexport_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_loexport_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_loexport_0_arg1; zend_string *attribute_Deprecated_func_pg_loexport_0_arg1_str = zend_string_init("use pg_lo_export() instead", strlen("use pg_lo_export() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_loexport_0_arg1, attribute_Deprecated_func_pg_loexport_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_loexport_0->args[1].value, &attribute_Deprecated_func_pg_loexport_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_loexport_0->args[1].value, attribute_Deprecated_func_pg_loexport_0_arg1_str); attribute_Deprecated_func_pg_loexport_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_setclientencoding_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_setclientencoding", sizeof("pg_setclientencoding") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_setclientencoding_0_arg0; - zend_string *attribute_Deprecated_func_pg_setclientencoding_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_setclientencoding_0_arg0, attribute_Deprecated_func_pg_setclientencoding_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_setclientencoding_0->args[0].value, &attribute_Deprecated_func_pg_setclientencoding_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_setclientencoding_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_setclientencoding_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_setclientencoding_0_arg1; zend_string *attribute_Deprecated_func_pg_setclientencoding_0_arg1_str = zend_string_init("use pg_set_client_encoding() instead", strlen("use pg_set_client_encoding() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_setclientencoding_0_arg1, attribute_Deprecated_func_pg_setclientencoding_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_setclientencoding_0->args[1].value, &attribute_Deprecated_func_pg_setclientencoding_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_setclientencoding_0->args[1].value, attribute_Deprecated_func_pg_setclientencoding_0_arg1_str); attribute_Deprecated_func_pg_setclientencoding_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_pg_clientencoding_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_clientencoding", sizeof("pg_clientencoding") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_pg_clientencoding_0_arg0; - zend_string *attribute_Deprecated_func_pg_clientencoding_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_clientencoding_0_arg0, attribute_Deprecated_func_pg_clientencoding_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_clientencoding_0->args[0].value, &attribute_Deprecated_func_pg_clientencoding_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_pg_clientencoding_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_pg_clientencoding_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_pg_clientencoding_0_arg1; zend_string *attribute_Deprecated_func_pg_clientencoding_0_arg1_str = zend_string_init("use pg_client_encoding() instead", strlen("use pg_client_encoding() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_pg_clientencoding_0_arg1, attribute_Deprecated_func_pg_clientencoding_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_pg_clientencoding_0->args[1].value, &attribute_Deprecated_func_pg_clientencoding_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_pg_clientencoding_0->args[1].value, attribute_Deprecated_func_pg_clientencoding_0_arg1_str); attribute_Deprecated_func_pg_clientencoding_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "pg_change_password", sizeof("pg_change_password") - 1), 2, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_attribute *attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0 = zend_add_global_constant_attribute(const_PGSQL_LIBPQ_VERSION_STR, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); + attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1_str = zend_string_init("as it is the same as PGSQL_LIBPQ_VERSION", strlen("as it is the same as PGSQL_LIBPQ_VERSION"), 1); + ZVAL_STR(&attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[1].value, attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0_arg1_str); + attribute_Deprecated_const_PGSQL_LIBPQ_VERSION_STR_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_PgSql_Connection(void) diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index 7a5770cb5936..a865a7ce73a4 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Zeev Suraski | | Jouni Ahto | diff --git a/ext/pgsql/tests/03sync_query.phpt b/ext/pgsql/tests/03sync_query.phpt index 36b1230f5f88..3ecee338d22a 100644 --- a/ext/pgsql/tests/03sync_query.phpt +++ b/ext/pgsql/tests/03sync_query.phpt @@ -70,14 +70,8 @@ pg_result_error_field($result, PGSQL_DIAG_MESSAGE_PRIMARY); pg_result_error_field($result, PGSQL_DIAG_MESSAGE_DETAIL); pg_result_error_field($result, PGSQL_DIAG_MESSAGE_HINT); pg_result_error_field($result, PGSQL_DIAG_STATEMENT_POSITION); -if (defined('PGSQL_DIAG_INTERNAL_POSITION')) -{ - pg_result_error_field($result, PGSQL_DIAG_INTERNAL_POSITION); -} -if (defined('PGSQL_DIAG_INTERNAL_QUERY')) -{ - pg_result_error_field($result, PGSQL_DIAG_INTERNAL_QUERY); -} +pg_result_error_field($result, PGSQL_DIAG_INTERNAL_POSITION); +pg_result_error_field($result, PGSQL_DIAG_INTERNAL_QUERY); pg_result_error_field($result, PGSQL_DIAG_CONTEXT); pg_result_error_field($result, PGSQL_DIAG_SOURCE_FILE); pg_result_error_field($result, PGSQL_DIAG_SOURCE_LINE); diff --git a/ext/pgsql/tests/gh21162.phpt b/ext/pgsql/tests/gh21162.phpt new file mode 100644 index 000000000000..6bdfa4291441 --- /dev/null +++ b/ext/pgsql/tests/gh21162.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-21162 (pg_connect() on error memory leak) +--EXTENSIONS-- +pgsql +--FILE-- + +--EXPECT-- +Warning caught +Done diff --git a/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt b/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt new file mode 100644 index 000000000000..6cbfe6d1f585 --- /dev/null +++ b/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt @@ -0,0 +1,64 @@ +--TEST-- +#GHSA-hrwm-9436-5mv3: pgsql extension does not check for errors during escaping +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- + 'test'])); // table name str escape in php_pgsql_meta_data +var_dump(pg_insert($db, "$invalid.tbl", ['bar' => 'test'])); // schema name str escape in php_pgsql_meta_data +var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', ['bar' => $invalid])); // converted value str escape in php_pgsql_convert +var_dump(pg_insert($db, $invalid, [])); // ident escape in build_tablename +var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', [$invalid => 'foo'], $flags)); // ident escape for field php_pgsql_insert +var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', ['bar' => $invalid], $flags)); // str escape for field value in php_pgsql_insert +var_dump(pg_update($db, 'ghsa_hrmw_9436_5mv3', ['bar' => 'val'], [$invalid => 'test'], $flags)); // ident escape in build_assignment_string +var_dump(pg_update($db, 'ghsa_hrmw_9436_5mv3', ['bar' => 'val'], ['bar' => $invalid], $flags)); // invalid str escape in build_assignment_string +var_dump(pg_escape_literal($db, $invalid)); // pg_escape_literal escape +var_dump(pg_escape_identifier($db, $invalid)); // pg_escape_identifier escape + +?> +--EXPECTF-- + +Warning: pg_insert(): Escaping table name 'ABC%s';' failed in %s on line %d +bool(false) + +Warning: pg_insert(): Escaping table namespace 'ABC%s';.tbl' failed in %s on line %d +bool(false) + +Notice: pg_insert(): String value escaping failed for PostgreSQL 'text' (bar) in %s on line %d +bool(false) + +Notice: pg_insert(): Failed to escape table name 'ABC%s';' in %s on line %d +bool(false) + +Notice: pg_insert(): Failed to escape field 'ABC%s';' in %s on line %d +bool(false) + +Notice: pg_insert(): Failed to escape field 'bar' value in %s on line %d +bool(false) + +Notice: pg_update(): Failed to escape field 'ABC%s';' in %s on line %d +bool(false) + +Notice: pg_update(): Failed to escape field 'bar' value in %s on line %d +bool(false) + +Warning: pg_escape_literal(): Failed to escape in %s on line %d +bool(false) + +Warning: pg_escape_identifier(): Failed to escape in %s on line %d +bool(false) diff --git a/ext/pgsql/tests/inc/config.inc b/ext/pgsql/tests/inc/config.inc index b01b120723d9..dc95c9eedab2 100644 --- a/ext/pgsql/tests/inc/config.inc +++ b/ext/pgsql/tests/inc/config.inc @@ -6,4 +6,3 @@ // "test" database must exist. i.e. "createdb test" before testing $conn_str = getenv('PGSQL_TEST_CONNSTR') ?: "host=localhost dbname=test port=5432 user=postgres password=postgres"; // connection string -?> diff --git a/ext/pgsql/tests/inc/lcmess.inc b/ext/pgsql/tests/inc/lcmess.inc index 7c6e0b80ed7b..a1bf61e6851c 100644 --- a/ext/pgsql/tests/inc/lcmess.inc +++ b/ext/pgsql/tests/inc/lcmess.inc @@ -17,5 +17,3 @@ function _set_lc_messages($conn, $lc_messages = 'C') return true; } - -?> diff --git a/ext/pgsql/tests/inc/skipif.inc b/ext/pgsql/tests/inc/skipif.inc index 06c3ff657115..2ce5f46e7787 100644 --- a/ext/pgsql/tests/inc/skipif.inc +++ b/ext/pgsql/tests/inc/skipif.inc @@ -1,4 +1,3 @@ - = 9.0\n"); } } - -?> diff --git a/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt b/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt new file mode 100644 index 000000000000..bd3df73acba4 --- /dev/null +++ b/ext/pgsql/tests/pg_fetch_object_ctor_paths.phpt @@ -0,0 +1,69 @@ +--TEST-- +pg_fetch_object() constructor handling: ctor_params validation, throwing constructor, property visibility +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- +num}, str={$this->str}\n"; + } + public function __destruct() { + echo "SeesProps::__destruct called\n"; + } +} + +$table_name = "pg_fetch_object_ctor_paths"; +$db = pg_connect($conn_str); +pg_query($db, "CREATE TABLE {$table_name} (num int, str text)"); +pg_query($db, "INSERT INTO {$table_name} VALUES(1, 'hello')"); + +$sql = "SELECT * FROM {$table_name} WHERE num = 1"; + +// 1) ctor_params on a class with no constructor must throw ValueError +try { + pg_fetch_object(pg_query($db, $sql), null, 'NoCtor', [1, 2]); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +// 2) Constructor that throws: __destruct must NOT run on the partially constructed object +try { + pg_fetch_object(pg_query($db, $sql), null, 'ThrowingCtor'); +} catch (RuntimeException $e) { + echo "caught: ", $e->getMessage(), "\n"; +} + +// 3) Constructor sees row properties already merged onto $this +$obj = pg_fetch_object(pg_query($db, $sql), null, 'SeesProps'); +unset($obj); + +echo "Ok\n"; +?> +--CLEAN-- + +--EXPECT-- +pg_fetch_object(): Argument #4 ($constructor_args) must be empty when the specified class (NoCtor) does not have a constructor +caught: boom +ctor sees: num=1, str=hello +SeesProps::__destruct called +Ok diff --git a/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt b/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt new file mode 100644 index 000000000000..b3e6ea7f7b36 --- /dev/null +++ b/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt @@ -0,0 +1,59 @@ +--TEST-- +pg_fetch_object() with abstract class name +--EXTENSIONS-- +pgsql +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + $result = pg_query($db, $sql); + var_dump(pg_fetch_object($result, NULL, 'C')); +} catch(Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +try { + $result = pg_query($db, $sql); + var_dump(pg_fetch_object($result, NULL, 'E')); +} catch(Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--CLEAN-- + +--EXPECT-- +Error: Cannot instantiate interface I +Error: Cannot instantiate abstract class C +Error: Cannot instantiate enum E diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index c5aa292200e8..6c356c04e5e1 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar:// stream wrapper support | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -21,8 +19,6 @@ #include "phar_internal.h" #include "dirstream.h" -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, bool is_dir); - static const php_stream_ops phar_dir_ops = { phar_dir_write, /* write */ phar_dir_read, /* read */ @@ -188,8 +184,6 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has entry = safe_emalloc(keylen, 1, 1); memcpy(entry, ZSTR_VAL(str_key), keylen); entry[keylen] = '\0'; - - goto PHAR_ADD_ENTRY; } else { if (0 != memcmp(ZSTR_VAL(str_key), dir, dirlen)) { /* entry in directory not found */ @@ -199,28 +193,28 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has continue; } } - } - const char *save = ZSTR_VAL(str_key); - save += dirlen + 1; /* seek to just past the path separator */ + const char *save = ZSTR_VAL(str_key); + save += dirlen + 1; /* seek to just past the path separator */ - const char *has_slash = memchr(save, '/', keylen - dirlen - 1); - if (has_slash) { - /* is subdirectory */ - save -= dirlen + 1; - entry = safe_emalloc(has_slash - save + dirlen, 1, 1); - memcpy(entry, save + dirlen + 1, has_slash - save - dirlen - 1); - keylen = has_slash - save - dirlen - 1; - entry[keylen] = '\0'; - } else { - /* is file */ - save -= dirlen + 1; - entry = safe_emalloc(keylen - dirlen, 1, 1); - memcpy(entry, save + dirlen + 1, keylen - dirlen - 1); - entry[keylen - dirlen - 1] = '\0'; - keylen = keylen - dirlen - 1; + const char *has_slash = memchr(save, '/', keylen - dirlen - 1); + if (has_slash) { + /* is subdirectory */ + save -= dirlen + 1; + entry = safe_emalloc(has_slash - save + dirlen, 1, 1); + memcpy(entry, save + dirlen + 1, has_slash - save - dirlen - 1); + keylen = has_slash - save - dirlen - 1; + entry[keylen] = '\0'; + } else { + /* is file */ + save -= dirlen + 1; + entry = safe_emalloc(keylen - dirlen, 1, 1); + memcpy(entry, save + dirlen + 1, keylen - dirlen - 1); + entry[keylen - dirlen - 1] = '\0'; + keylen = keylen - dirlen - 1; + } } -PHAR_ADD_ENTRY: + if (keylen) { /** * Add an empty element to avoid duplicates @@ -251,11 +245,10 @@ static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const Has */ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) /* {{{ */ { - php_url *resource = NULL; char *error; - phar_archive_data *phar; - if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { + php_url *resource = phar_parse_url(wrapper, path, mode, options); + if (!resource) { php_stream_wrapper_log_error(wrapper, options, "phar url \"%s\" is unknown", path); return NULL; } @@ -280,7 +273,8 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, phar_request_initialize(); - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + const phar_archive_data *phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error); + if (!phar) { if (error) { php_stream_wrapper_log_error(wrapper, options, "%s", error); efree(error); @@ -291,10 +285,6 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, return NULL; } - if (error) { - efree(error); - } - if (zend_string_equals(resource->path, ZSTR_CHAR('/'))) { /* root directory requested */ php_url_free(resource); @@ -308,7 +298,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ size_t internal_file_len = ZSTR_LEN(resource->path) - 1; - phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); + const phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); php_stream *ret; if (NULL != entry && !entry->is_dir) { @@ -347,24 +337,20 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, */ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mode, int options, php_stream_context *context) /* {{{ */ { - phar_entry_info entry, *e; - phar_archive_data *phar = NULL; - char *error, *arch, *entry2; - size_t arch_len, entry_len; + phar_entry_info entry; + char *error; php_url *resource = NULL; /* pre-readonly check, we need to know if this is a data phar */ - if (FAILURE == phar_split_fname(url_from, strlen(url_from), &arch, &arch_len, &entry2, &entry_len, 2, 2)) { + zend_string *arch = phar_split_fname(url_from, strlen(url_from), NULL, 2, 2); + if (!arch) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", no phar archive specified", url_from); return 0; } - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - phar = NULL; - } + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); - efree(arch); - efree(entry2); + zend_string_release_ex(arch, false); if (PHAR_G(readonly) && (!phar || !phar->is_data)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\", write operations disabled", url_from); @@ -388,14 +374,16 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error); + if (!phar) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path) + 1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); return 0; } - if ((e = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 2, &error, 1))) { + phar_entry_info *e = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 2, &error, true); + if (e) { /* directory exists, or is a subdirectory of an existing file */ if (e->is_temp_dir) { zend_string_efree(e->filename); @@ -413,7 +401,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo return 0; } - if (phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 0, &error, 1)) { + if (phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1, 0, &error, true)) { /* entry exists as a file */ php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", file already exists", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host)); php_url_free(resource); @@ -449,9 +437,9 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo entry.flags = PHAR_ENT_PERM_DEF_DIR; entry.old_flags = PHAR_ENT_PERM_DEF_DIR; - if (NULL == zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info))) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed", ZSTR_VAL(entry.filename), phar->fname); - efree(error); + void *had_been_added = zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info)); + if (!had_been_added) { + php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed", ZSTR_VAL(entry.filename), ZSTR_VAL(phar->fname)); zend_string_efree(entry.filename); return 0; } @@ -459,7 +447,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo phar_flush(phar, &error); if (error) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry.filename), phar->fname, error); + php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry.filename), ZSTR_VAL(phar->fname), error); zend_hash_del(&phar->manifest, entry.filename); efree(error); return 0; @@ -475,31 +463,26 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo */ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) /* {{{ */ { - phar_entry_info *entry; - phar_archive_data *phar = NULL; - char *error, *arch, *entry2; - size_t arch_len, entry_len; - php_url *resource = NULL; + char *error; /* pre-readonly check, we need to know if this is a data phar */ - if (FAILURE == phar_split_fname(url, strlen(url), &arch, &arch_len, &entry2, &entry_len, 2, 2)) { + zend_string *arch = phar_split_fname(url, strlen(url), NULL, 2, 2); + if (!arch) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\", no phar archive specified, or phar archive does not exist", url); return 0; } - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - phar = NULL; - } + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); - efree(arch); - efree(entry2); + zend_string_release_ex(arch, false); if (PHAR_G(readonly) && (!phar || !phar->is_data)) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot rmdir directory \"%s\", write operations disabled", url); return 0; } - if ((resource = phar_parse_url(wrapper, url, "w", options)) == NULL) { + php_url *resource = phar_parse_url(wrapper, url, "w", options); + if (!resource) { return 0; } @@ -516,7 +499,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options return 0; } - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error); + if (!phar) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); efree(error); php_url_free(resource); @@ -525,7 +509,8 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options size_t path_len = ZSTR_LEN(resource->path) - 1; - if (!(entry = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, path_len, 2, &error, 1))) { + phar_entry_info *entry = phar_get_entry_info_dir(phar, ZSTR_VAL(resource->path) + 1, path_len, 2, &error, true); + if (!entry) { if (error) { php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(resource->path)+1, ZSTR_VAL(resource->host), error); efree(error); @@ -581,7 +566,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options phar_flush(phar, &error); if (error) { - php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry->filename), phar->fname, error); + php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname), error); php_url_free(resource); efree(error); return 0; diff --git a/ext/phar/dirstream.h b/ext/phar/dirstream.h index 4debfecde41a..41899f88a992 100644 --- a/ext/phar/dirstream.h +++ b/ext/phar/dirstream.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index f1b2b0eba1e6..f6e69f20035c 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ @@ -40,8 +38,6 @@ PHP_FUNCTION(phar_opendir) /* {{{ */ } if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -50,25 +46,23 @@ PHP_FUNCTION(phar_opendir) /* {{{ */ goto skip_phar; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) { + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { php_stream_context *context = NULL; php_stream *stream; char *name; - efree(entry); - entry = estrndup(filename, filename_len); /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - entry = phar_fix_filepath(entry, &entry_len, 1); + zend_string *entry = phar_fix_filepath(filename, filename_len, true); - if (entry[0] == '/') { - spprintf(&name, 4096, "phar://%s%s", arch, entry); + if (ZSTR_VAL(entry)[0] == '/') { + spprintf(&name, 4096, "phar://%s%s", ZSTR_VAL(arch), ZSTR_VAL(entry)); } else { - spprintf(&name, 4096, "phar://%s/%s", arch, entry); + spprintf(&name, 4096, "phar://%s/%s", ZSTR_VAL(arch), ZSTR_VAL(entry)); } - efree(entry); - efree(arch); + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); if (zcontext) { context = php_stream_context_from_zval(zcontext, 0); } @@ -89,8 +83,6 @@ PHP_FUNCTION(phar_opendir) /* {{{ */ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool using_include_path) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -99,59 +91,56 @@ static zend_string* phar_get_name_for_relative_paths(zend_string *filename, bool return NULL; } - if (FAILURE == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) { + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (!arch) { return NULL; } - efree(entry); - entry = NULL; - entry_len = 0; /* fopen within phar, if :// is not in the url, then prepend phar:/// */ /* retrieving a file defaults to within the current directory, so use this if possible */ - phar_archive_data *phar; - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - efree(arch); + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + if (!phar) { + zend_string_release_ex(arch, false); return NULL; } zend_string *name = NULL; if (using_include_path) { - if (!(name = phar_find_in_include_path(filename, NULL))) { + name = phar_find_in_include_path(filename); + if (!name) { /* this file is not in the phar, use the original path */ - efree(arch); + zend_string_release_ex(arch, false); return NULL; } } else { - entry_len = ZSTR_LEN(filename); - entry = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &entry_len, 1); - if (entry[0] == '/') { - if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) { - /* this file is not in the phar, use the original path */ -notfound: - efree(entry); - efree(arch); - return NULL; - } + zend_string *entry = phar_fix_filepath(ZSTR_VAL(filename), ZSTR_LEN(filename), true); + bool is_in_phar; + if (ZSTR_VAL(entry)[0] == '/') { + is_in_phar = zend_hash_str_exists(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); } else { - if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) { - goto notfound; - } + is_in_phar = zend_hash_exists(&(phar->manifest), entry); + } + /* this file is not in the phar, use the original path */ + if (!is_in_phar) { + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); + return NULL; } /* auto-convert to phar:// */ - if (entry[0] == '/') { - ZEND_ASSERT(strlen("phar://") + arch_len + entry_len < 4096); + if (ZSTR_VAL(entry)[0] == '/') { + ZEND_ASSERT(strlen("phar://") + ZSTR_LEN(arch) + ZSTR_LEN(entry) < 4096); name = zend_string_concat3( "phar://", strlen("phar://"), - arch, arch_len, - entry, entry_len + ZSTR_VAL(arch), ZSTR_LEN(arch), + ZSTR_VAL(entry), ZSTR_LEN(entry) ); } else { - name = strpprintf(4096, "phar://%s/%s", arch, entry); + name = strpprintf(4096, "phar://%s/%s", ZSTR_VAL(arch), ZSTR_VAL(entry)); } - efree(entry); + zend_string_release_ex(entry, false); } - efree(arch); + zend_string_release_ex(arch, false); return name; } @@ -159,10 +148,10 @@ PHP_FUNCTION(phar_file_get_contents) /* {{{ */ { zend_string *filename; zend_string *contents; - bool use_include_path = 0; + bool use_include_path = false; zend_long offset = -1; zend_long maxlen; - bool maxlen_is_null = 1; + bool maxlen_is_null = true; zval *zcontext = NULL; if (!PHAR_G(intercepted)) { @@ -235,7 +224,7 @@ PHP_FUNCTION(phar_file_get_contents) /* {{{ */ PHP_FUNCTION(phar_readfile) /* {{{ */ { zend_string *filename; - bool use_include_path = 0; + bool use_include_path = false; zval *zcontext = NULL; if (!PHAR_G(intercepted)) { @@ -281,7 +270,7 @@ PHP_FUNCTION(phar_fopen) /* {{{ */ zend_string *filename; char *mode; size_t mode_len; - bool use_include_path = 0; + bool use_include_path = false; zval *zcontext = NULL; if (!PHAR_G(intercepted)) { @@ -334,10 +323,6 @@ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value) zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev, stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks; int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */ - char *stat_sb_names[13] = { - "dev", "ino", "mode", "nlink", "uid", "gid", "rdev", - "size", "atime", "mtime", "ctime", "blksize", "blocks" - }; if (type >= FS_IS_W && type <= FS_IS_X) { if(stat_sb->st_uid==getuid()) { @@ -349,15 +334,12 @@ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value) wmask=S_IWGRP; xmask=S_IXGRP; } else { - int groups, n, i; - gid_t *gids; - - groups = getgroups(0, NULL); - if(groups > 0) { - gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0); - n=getgroups(groups, gids); - for(i=0;ist_gid==gids[i]) { + int groups = getgroups(0, NULL); + if (groups > 0) { + gid_t *gids = safe_emalloc(groups, sizeof(gid_t), 0); + int n = getgroups(groups, gids); + for(int i = 0; i < n; ++i){ + if (stat_sb->st_gid==gids[i]) { rmask=S_IRGRP; wmask=S_IWGRP; xmask=S_IXGRP; @@ -457,19 +439,19 @@ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value) zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &stat_blocks); /* Store string indexes referencing the same zval*/ - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[0], strlen(stat_sb_names[0]), &stat_dev); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[1], strlen(stat_sb_names[1]), &stat_ino); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[2], strlen(stat_sb_names[2]), &stat_mode); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[3], strlen(stat_sb_names[3]), &stat_nlink); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[4], strlen(stat_sb_names[4]), &stat_uid); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[5], strlen(stat_sb_names[5]), &stat_gid); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[6], strlen(stat_sb_names[6]), &stat_rdev); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[7], strlen(stat_sb_names[7]), &stat_size); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[8], strlen(stat_sb_names[8]), &stat_atime); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[9], strlen(stat_sb_names[9]), &stat_mtime); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[10], strlen(stat_sb_names[10]), &stat_ctime); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize); - zend_hash_str_update(Z_ARRVAL_P(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("dev"), &stat_dev); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("ino"), &stat_ino); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("mode"), &stat_mode); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("nlink"), &stat_nlink); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("uid"), &stat_uid); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("gid"), &stat_gid); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("rdev"), &stat_rdev); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("size"), &stat_size); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("atime"), &stat_atime); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("mtime"), &stat_mtime); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("ctime"), &stat_ctime); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("blksize"), &stat_blksize); + zend_hash_str_update(Z_ARRVAL_P(return_value), ZEND_STRL("blocks"), &stat_blocks); return; } @@ -485,11 +467,8 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ } if (!IS_ABSOLUTE_PATH(filename, filename_length) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname; zend_stat_t sb = {0}; - phar_entry_info *data = NULL; phar_archive_data *phar; fname = zend_get_executed_filename_ex(); @@ -500,42 +479,38 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ goto skip_phar; } - if (PHAR_G(last_phar) && ZSTR_LEN(fname) - 7 >= PHAR_G(last_phar_name_len) && !memcmp(ZSTR_VAL(fname) + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) { - arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len)); - arch_len = PHAR_G(last_phar_name_len); - entry = estrndup(filename, filename_length); + if (PHAR_G(last_phar) && ZSTR_LEN(fname) - 7 >= ZSTR_LEN(PHAR_G(last_phar_name)) && !memcmp(ZSTR_VAL(fname) + 7, ZSTR_VAL(PHAR_G(last_phar_name)), ZSTR_LEN(PHAR_G(last_phar_name)))) { /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_length; phar = PHAR_G(last_phar); goto splitted; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) { - efree(entry); - entry = estrndup(filename, filename_length); + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_length; - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - efree(arch); - efree(entry); + phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_string_release_ex(arch, false); + if (!phar) { goto skip_phar; } -splitted: - entry = phar_fix_filepath(entry, &entry_len, 1); - if (entry[0] == '/') { - if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { - efree(entry); +splitted:; + zend_string *entry = phar_fix_filepath(filename, filename_length, true); + const phar_entry_info *data = NULL; + if (ZSTR_VAL(entry)[0] == '/') { + data = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); + if (data) { + zend_string_release_ex(entry, false); goto stat_entry; } goto notfound; } - if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) { - efree(entry); + data = zend_hash_find_ptr(&(phar->manifest), entry); + if (data) { + zend_string_release_ex(entry, false); goto stat_entry; } - if (zend_hash_str_exists(&(phar->virtual_dirs), entry, entry_len)) { - efree(entry); - efree(arch); + if (zend_hash_exists(&(phar->virtual_dirs), entry)) { + zend_string_release_ex(entry, false); if (IS_EXISTS_CHECK(type)) { RETURN_TRUE; } @@ -551,31 +526,28 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ size_t save_len; notfound: - efree(entry); + zend_string_release_ex(entry, false); save = PHAR_G(cwd); save_len = PHAR_G(cwd_len); /* this file is not in the current directory, use the original path */ - entry = estrndup(filename, filename_length); - entry_len = filename_length; PHAR_G(cwd) = "/"; PHAR_G(cwd_len) = 0; /* clean path without cwd */ - entry = phar_fix_filepath(entry, &entry_len, 1); - if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { + entry = phar_fix_filepath(filename, filename_length, true); + data = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); + if (data) { PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; - efree(entry); + zend_string_release_ex(entry, false); if (IS_EXISTS_CHECK(type)) { - efree(arch); RETURN_TRUE; } goto stat_entry; } - if (zend_hash_str_exists(&(phar->virtual_dirs), entry + 1, entry_len - 1)) { + if (zend_hash_str_exists(&(phar->virtual_dirs), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1)) { PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; - efree(entry); - efree(arch); + zend_string_release_ex(entry, false); if (IS_EXISTS_CHECK(type)) { RETURN_TRUE; } @@ -589,8 +561,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ } PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; - efree(entry); - efree(arch); + zend_string_release_ex(entry, false); /* Error Occurred */ if (!IS_EXISTS_CHECK(type)) { php_error_docref(NULL, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename); @@ -598,11 +569,10 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ RETURN_FALSE; } stat_entry: - efree(arch); if (!data->is_dir) { sb.st_size = data->uncompressed_filesize; sb.st_mode = data->flags & PHAR_ENT_PERM_MASK; - if (data->link) { + if (data->symlink) { sb.st_mode |= S_IFREG|S_IFLNK; /* regular file */ } else { sb.st_mode |= S_IFREG; /* regular file */ @@ -615,7 +585,7 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ sb.st_size = 0; sb.st_mode = data->flags & PHAR_ENT_PERM_MASK; sb.st_mode |= S_IFDIR; /* regular directory */ - if (data->link) { + if (data->symlink) { sb.st_mode |= S_IFLNK; } /* timestamp is just the timestamp when this was added to the phar */ @@ -637,8 +607,10 @@ static void phar_file_stat(const char *filename, size_t filename_length, int typ if (data) { sb.st_ino = data->inode; } -#ifndef PHP_WIN32 +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE sb.st_blksize = -1; +#endif +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS sb.st_blocks = -1; #endif phar_fancy_stat(&sb, type, return_value); @@ -741,8 +713,6 @@ PHP_FUNCTION(phar_is_file) /* {{{ */ goto skip_phar; } if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -751,36 +721,29 @@ PHP_FUNCTION(phar_is_file) /* {{{ */ goto skip_phar; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) { - phar_archive_data *phar; + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { + ; - efree(entry); - entry = filename; /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_string_release_ex(arch, false); + if (phar) { phar_entry_info *etemp; - entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1); - if (entry[0] == '/') { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { - /* this file is not in the current directory, use the original path */ -found_it: - efree(entry); - efree(arch); - RETURN_BOOL(!etemp->is_dir); - } + zend_string *entry = phar_fix_filepath(filename, filename_len, true); + if (ZSTR_VAL(entry)[0] == '/') { + etemp = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); } else { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) { - goto found_it; - } + etemp = zend_hash_find_ptr(&(phar->manifest), entry); } + zend_string_release_ex(entry, false); + if (etemp) { + RETURN_BOOL(!etemp->is_dir); + } + /* this file is not in the current directory, use the original path */ } - if (entry != filename) { - efree(entry); - } - efree(arch); RETURN_FALSE; } } @@ -807,8 +770,6 @@ PHP_FUNCTION(phar_is_link) /* {{{ */ goto skip_phar; } if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) { - char *arch, *entry; - size_t arch_len, entry_len; zend_string *fname = zend_get_executed_filename_ex(); /* we are checking for existence of a file within the relative path. Chances are good that this is @@ -817,34 +778,26 @@ PHP_FUNCTION(phar_is_link) /* {{{ */ goto skip_phar; } - if (SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0)) { - phar_archive_data *phar; - - efree(entry); - entry = filename; + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { /* fopen within phar, if :// is not in the url, then prepend phar:/// */ - entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + zend_string_release_ex(arch, false); + if (phar) { phar_entry_info *etemp; - entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1); - if (entry[0] == '/') { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) { - /* this file is not in the current directory, use the original path */ -found_it: - efree(entry); - efree(arch); - RETURN_BOOL(etemp->link); - } + zend_string *entry = phar_fix_filepath(filename, filename_len, true); + if (ZSTR_VAL(entry)[0] == '/') { + etemp = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(entry) + 1, ZSTR_LEN(entry) - 1); } else { - if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) { - goto found_it; - } + etemp = zend_hash_find_ptr(&(phar->manifest), entry); + } + zend_string_release_ex(entry, false); + if (etemp) { + RETURN_BOOL(etemp->symlink); } } - efree(entry); - efree(arch); RETURN_FALSE; } } @@ -883,7 +836,8 @@ void phar_release_functions(void) /* {{{ void phar_intercept_functions_init(void) */ #define PHAR_INTERCEPT(func) \ PHAR_G(orig_##func) = NULL; \ - if (NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \ + orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1); \ + if (orig) { \ PHAR_G(orig_##func) = orig->internal_function.handler; \ orig->internal_function.handler = PHP_FN(phar_##func); \ } @@ -932,6 +886,7 @@ void phar_intercept_functions_shutdown(void) PHAR_RELEASE(fopen); PHAR_RELEASE(file_get_contents); PHAR_RELEASE(is_file); + PHAR_RELEASE(is_link); PHAR_RELEASE(is_dir); PHAR_RELEASE(opendir); PHAR_RELEASE(file_exists); diff --git a/ext/phar/func_interceptors.h b/ext/phar/func_interceptors.h index 06906ee79e80..af68b0410d4c 100644 --- a/ext/phar/func_interceptors.h +++ b/ext/phar/func_interceptors.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | diff --git a/ext/phar/makestub.php b/ext/phar/makestub.php old mode 100644 new mode 100755 index 5808f4c38c9a..e5cbe89ff4bd --- a/ext/phar/makestub.php +++ b/ext/phar/makestub.php @@ -1,3 +1,4 @@ +#!/usr/bin/env php . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ */ -static inline void phar_get_stub(const char *index_php, const char *web, size_t *len, char **stub, const int name_len, const int web_len) +static inline zend_string *phar_get_stub(const char *index_php, const char *web, size_t name_len, size_t web_len) { + /* Do NOT modify this file directly! + * Instead modify shortarc.php to change PHP code or makestub.php to change C code and then use makestub.php to generate this file. */ '; $s1split = str_split($s1, 2046); $s3split = str_split($s3, 2046); @@ -88,9 +89,9 @@ $stub .= "\tstatic const char newstub3_" . $i . '[] = "' . $chunk . '"; '; } -$stub .= "\n\tstatic const int newstub_len = " . $slen . "; +$stub .= "\n\tstatic const size_t newstub_len = " . $slen . "; -\t*len = spprintf(stub, name_len + web_len + newstub_len, \"%s%s" . str_repeat('%s', $s1count) . '%s%s%d' +\treturn strpprintf(name_len + web_len + newstub_len, \"%s%s" . str_repeat('%s', $s1count) . '%s%s%zu' . str_repeat('%s', $s3count) . '", newstub0, web'; foreach ($s1split as $i => $unused) { $stub .= ', newstub1_' . $i; diff --git a/ext/phar/phar.1.in b/ext/phar/phar.1.in index db22d40abc3f..8dffd2cf2dd0 100644 --- a/ext/phar/phar.1.in +++ b/ext/phar/phar.1.in @@ -511,17 +511,9 @@ contributors all around the world. .SH VERSION INFORMATION This manpage describes \fBphar\fP, version @PHP_VERSION@. .SH COPYRIGHT -Copyright \(co The PHP Group +Copyright \(co The PHP Group and Contributors .LP -This source file is subject to version 3.01 of the PHP license, -that is bundled with this package in the file LICENSE, and is -available through the world-wide-web at the following url: -.PD 0 -.P -.B https://www.php.net/license/3_01.txt -.PD 1 -.P -If you did not receive a copy of the PHP license and are unable to -obtain it through the world-wide-web, please send a note to -.B license@php.net -so we can mail you a copy immediately. +This source file is subject to the Modified BSD License that is +bundled with this package in the file LICENSE, and is available +through the World Wide Web at +.B https://www.php.net/license/ diff --git a/ext/phar/phar.c b/ext/phar/phar.c index de3b1b4ee199..ee12c5b91feb 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -93,7 +91,7 @@ HashTable cached_alias; static void phar_split_cache_list(void) /* {{{ */ { char *tmp; - char *key, *lasts, *end; + char *key, *lasts; char ds[2]; phar_archive_data *phar; uint32_t i = 0; @@ -126,14 +124,14 @@ static void phar_split_cache_list(void) /* {{{ */ key; key = php_strtok_r(NULL, ds, &lasts)) { size_t len; - end = strchr(key, DEFAULT_DIR_SEPARATOR); + const char *end = strchr(key, DEFAULT_DIR_SEPARATOR); if (end) { len = end - key; } else { len = strlen(key); } - if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(key, len, NULL, 0, &phar, NULL)) { phar->phar_pos = i++; php_stream_close(phar->fp); phar->fp = NULL; @@ -194,13 +192,13 @@ PHP_INI_END() */ void phar_destroy_phar_data(phar_archive_data *phar) /* {{{ */ { - if (phar->alias && phar->alias != phar->fname) { + if (phar->alias) { pefree(phar->alias, phar->is_persistent); phar->alias = NULL; } if (phar->fname) { - pefree(phar->fname, phar->is_persistent); + zend_string_release_ex(phar->fname, phar->is_persistent); phar->fname = NULL; } @@ -246,41 +244,48 @@ void phar_destroy_phar_data(phar_archive_data *phar) /* {{{ */ bool phar_archive_delref(phar_archive_data *phar) /* {{{ */ { if (phar->is_persistent) { - return 0; + return false; } if (--phar->refcount < 0) { if (PHAR_G(request_done) - || zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) { + || zend_hash_del(&(PHAR_G(phar_fname_map)), phar->fname) != SUCCESS) { phar_destroy_phar_data(phar); } - return 1; + return true; } else if (!phar->refcount) { /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + + /* This is a new phar that has perhaps had an alias/metadata set, but has never been flushed. */ + bool remove_fname_cache = !zend_hash_num_elements(&phar->manifest); if (phar->fp && (!(phar->flags & PHAR_FILE_COMPRESSION_MASK) || !phar->alias)) { /* close open file handle - allows removal or rename of the file on windows, which has greedy locking - only close if the archive was not already compressed. If it - was compressed, then the fp does not refer to the original file. - We're also closing compressed files to save resources, - but only if the archive isn't aliased. */ + only close if the archive was not already compressed. + We're also closing compressed files to save resources, but only if the archive isn't aliased. + If it was compressed, then the fp does not refer to the original compressed file: + it refers to the **uncompressed** filtered file stream. + Therefore, upon closing a compressed file we need to invalidate the phar archive such + that the code that reopens the phar will not try to use the **compressed** file as if it was uncompressed. + That would result in treating compressed file data as if it were compressed and using uncompressed file offsets + on the compressed file. */ php_stream_close(phar->fp); phar->fp = NULL; + remove_fname_cache |= phar->flags & PHAR_FILE_COMPRESSION_MASK; } - if (!zend_hash_num_elements(&phar->manifest)) { - /* this is a new phar that has perhaps had an alias/metadata set, but has never - been flushed */ - if (zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) { + if (remove_fname_cache) { + if (zend_hash_del(&(PHAR_G(phar_fname_map)), phar->fname) != SUCCESS) { phar_destroy_phar_data(phar); } - return 1; + return true; } } - return 0; + return false; } /* }}}*/ @@ -369,9 +374,9 @@ void destroy_phar_manifest_entry_int(phar_entry_info *entry) /* {{{ */ zend_string_release_ex(entry->filename, entry->is_persistent); - if (entry->link) { - pefree(entry->link, entry->is_persistent); - entry->link = 0; + if (entry->symlink) { + zend_string_release_ex(entry->symlink, entry->is_persistent); + entry->symlink = NULL; } if (entry->tmp) { @@ -414,13 +419,13 @@ void phar_entry_delref(phar_entry_data *idata) /* {{{ */ /** * Removes an entry, either by actually removing it or by marking it. */ -void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */ { phar_archive_data *phar; phar = idata->phar; - if (idata->internal_file->fp_refcount < 2) { + if (idata->internal_file->fp_refcount < 2 && idata->internal_file->fileinfo_lock_count == 0) { if (idata->fp && idata->fp != idata->phar->fp && idata->fp != idata->phar->ufp && idata->fp != idata->internal_file->fp) { php_stream_close(idata->fp); } @@ -464,17 +469,10 @@ void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */ | ((uint32_t)(((unsigned char*)(buffer))[1]) << 8) \ | ((uint32_t)((unsigned char*)(buffer))[0]); \ (buffer) += 4 -# define PHAR_GET_16(buffer, var) \ - var = ((uint16_t)(((unsigned char*)(buffer))[1]) << 8) \ - | ((uint16_t)((unsigned char*)(buffer))[0]); \ - (buffer) += 2 #else # define PHAR_GET_32(buffer, var) \ memcpy(&var, buffer, sizeof(var)); \ buffer += 4 -# define PHAR_GET_16(buffer, var) \ - var = *(uint16_t*)(buffer); \ - buffer += 2 #endif #define PHAR_ZIP_16(var) ((uint16_t)((((uint16_t)var[0]) & 0xff) | \ (((uint16_t)var[1]) & 0xff) << 8)) @@ -486,9 +484,15 @@ void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */ /** * Open an already loaded phar */ -static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ - phar_archive_data *phar; +static zend_result phar_open_parsed_phar( + char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { #ifdef PHP_WIN32 char *save_fname; ALLOCA_FLAG(fname_use_heap) @@ -506,17 +510,22 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al phar_unixify_path_separators(fname, fname_len); } #endif - if (SUCCESS == phar_get_archive(&phar, fname, fname_len, alias, alias_len, error) - && ((alias && fname_len == phar->fname_len - && !strncmp(fname, phar->fname, fname_len)) || !alias) - ) { - phar_entry_info *stub; + const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; + size_t alias_len = alias ? ZSTR_LEN(alias) : 0; + phar_archive_data *phar = phar_get_archive(fname, fname_len, alias_cstr, alias_len, error); + /* logic is as follows: + - If no alias was passed in, then it can match either and be valid + - If an explicit alias was requested, ensure the filename passed in matches the phar's filename. + */ + bool process_phar = phar && (!alias || zend_string_equals_cstr(phar->fname, fname, fname_len)); #ifdef PHP_WIN32 - if (fname != save_fname) { - free_alloca(fname, fname_use_heap); - fname = save_fname; - } + if (fname != save_fname) { + free_alloca(fname, fname_use_heap); + fname = save_fname; + } #endif + + if (process_phar) { /* logic above is as follows: If an explicit alias was requested, ensure the filename passed in matches the phar's filename. @@ -526,7 +535,7 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al if (!is_data) { /* prevent any ".phar" without a stub getting through */ if (!phar->halt_offset && !phar->is_brandnew && (phar->is_tar || phar->is_zip)) { - if (PHAR_G(readonly) && NULL == (stub = zend_hash_str_find_ptr(&(phar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1))) { + if (PHAR_G(readonly) && !zend_hash_str_exists(&(phar->manifest), ZEND_STRL(".phar/stub.php"))) { if (error) { spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", fname); } @@ -541,12 +550,6 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al return SUCCESS; } else { -#ifdef PHP_WIN32 - if (fname != save_fname) { - free_alloca(fname, fname_use_heap); - fname = save_fname; - } -#endif if (pphar) { *pphar = NULL; } @@ -558,7 +561,6 @@ static zend_result phar_open_parsed_phar(char *fname, size_t fname_len, char *al return FAILURE; } } -/* }}}*/ /** * Attempt to serialize the data. @@ -595,13 +597,9 @@ zend_result phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker *tra const bool has_unserialize_options = unserialize_options != NULL && zend_hash_num_elements(unserialize_options) > 0; /* It should be impossible to create a zval in a persistent phar/entry. */ ZEND_ASSERT(!persistent || Z_ISUNDEF(tracker->val)); + ZEND_ASSERT(!EG(exception)); if (Z_ISUNDEF(tracker->val) || has_unserialize_options) { - if (EG(exception)) { - /* Because other parts of the phar code haven't been updated to check for exceptions after doing something that may throw, - * check for exceptions before potentially serializing/unserializing instead. */ - return FAILURE; - } /* Persistent phars should always be unserialized. */ const char *start; /* Assert it should not be possible to create raw data in a persistent phar (i.e. from cache_list) */ @@ -730,7 +728,7 @@ void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker * This is used by phar_open_from_filename to process the manifest, but can be called * directly. */ -static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ +static zend_result phar_parse_pharfile(php_stream *fp, const char *fname, size_t fname_len, const char *alias, size_t alias_len, zend_long halt_offset, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ { char b32[4], *buffer, *endbuffer, *savebuf; phar_archive_data *mydata = NULL; @@ -740,7 +738,7 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname uint32_t len; zend_long offset; size_t sig_len; - int register_alias = 0, temp_alias = 0; + bool register_alias = false, temp_alias = false; char *signature = NULL; zend_string *str; @@ -1073,15 +1071,15 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname alias_len = tmp_len; alias = buffer; buffer += tmp_len; - register_alias = 1; + register_alias = true; } else if (!alias_len || !alias) { /* if we neither have an explicit nor an implicit alias, we use the filename */ alias = NULL; alias_len = 0; - register_alias = 0; + register_alias = false; } else if (alias_len) { - register_alias = 1; - temp_alias = 1; + register_alias = true; + temp_alias = true; } /* we have 5 32-bit items plus 1 byte at least */ @@ -1113,16 +1111,18 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname /* set up our manifest */ zend_hash_init(&mydata->manifest, manifest_count, - zend_get_hash_value, destroy_phar_manifest_entry, (bool)mydata->is_persistent); + zend_get_hash_value, destroy_phar_manifest_entry, mydata->is_persistent); zend_hash_init(&mydata->mounted_dirs, 5, - zend_get_hash_value, NULL, (bool)mydata->is_persistent); + zend_get_hash_value, NULL, mydata->is_persistent); zend_hash_init(&mydata->virtual_dirs, manifest_count * 2, - zend_get_hash_value, NULL, (bool)mydata->is_persistent); - mydata->fname = pestrndup(fname, fname_len, mydata->is_persistent); + zend_get_hash_value, NULL, mydata->is_persistent); + mydata->fname = zend_string_init(fname, fname_len, mydata->is_persistent); + if (mydata->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(mydata->fname); + } #ifdef PHP_WIN32 - phar_unixify_path_separators(mydata->fname, fname_len); + phar_unixify_path_separators(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname)); #endif - mydata->fname_len = fname_len; offset = halt_offset + manifest_len + 4; memset(&entry, 0, sizeof(phar_entry_info)); entry.phar = mydata; @@ -1161,15 +1161,9 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname PHAR_GET_32(buffer, entry.uncompressed_filesize); PHAR_GET_32(buffer, entry.timestamp); - if (offset == halt_offset + manifest_len + 4) { - mydata->min_timestamp = entry.timestamp; + if (offset == halt_offset + manifest_len + 4 + || mydata->max_timestamp < entry.timestamp) { mydata->max_timestamp = entry.timestamp; - } else { - if (mydata->min_timestamp > entry.timestamp) { - mydata->min_timestamp = entry.timestamp; - } else if (mydata->max_timestamp < entry.timestamp) { - mydata->max_timestamp = entry.timestamp; - } } PHAR_GET_32(buffer, entry.compressed_filesize); @@ -1243,22 +1237,22 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname snprintf(mydata->version, sizeof(mydata->version), "%u.%u.%u", manifest_ver >> 12, (manifest_ver >> 8) & 0xF, (manifest_ver >> 4) & 0xF); mydata->halt_offset = halt_offset; mydata->flags = manifest_flags; - endbuffer = strrchr(mydata->fname, '/'); + endbuffer = strrchr(ZSTR_VAL(mydata->fname), '/'); if (endbuffer) { - mydata->ext = memchr(endbuffer, '.', (mydata->fname + fname_len) - endbuffer); + mydata->ext = memchr(endbuffer, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - endbuffer); if (mydata->ext == endbuffer) { - mydata->ext = memchr(endbuffer + 1, '.', (mydata->fname + fname_len) - endbuffer - 1); + mydata->ext = memchr(endbuffer + 1, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - endbuffer - 1); } if (mydata->ext) { - mydata->ext_len = (mydata->fname + mydata->fname_len) - mydata->ext; + mydata->ext_len = (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - mydata->ext; } } mydata->alias = alias ? pestrndup(alias, alias_len, mydata->is_persistent) : - pestrndup(mydata->fname, fname_len, mydata->is_persistent); - mydata->alias_len = alias ? alias_len : fname_len; + pestrndup(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname), mydata->is_persistent); + mydata->alias_len = alias ? alias_len : ZSTR_LEN(mydata->fname); mydata->sig_flags = sig_flags; mydata->fp = fp; mydata->sig_len = sig_len; @@ -1276,8 +1270,9 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname MAPPHAR_FAIL("Cannot open archive \"%s\", invalid alias"); } - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { + fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { signature = NULL; fp = NULL; MAPPHAR_FAIL("Cannot open archive \"%s\", alias is already in use by existing archive"); @@ -1296,12 +1291,12 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname } if (mydata->is_persistent) { - str = zend_string_init_interned(mydata->fname, fname_len, 1); + str = zend_string_init_interned(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname), true); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), str, mydata); + zend_string_release(str); } else { - str = zend_string_init(mydata->fname, fname_len, 0); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, mydata); } - zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), str, mydata); - zend_string_release(str); efree(savebuf); if (pphar) { @@ -1315,8 +1310,14 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname /** * Create or open a phar for writing */ -zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_filename( + zend_string *fname, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { const char *ext_str, *z; char *my_error; size_t ext_len; @@ -1324,43 +1325,34 @@ zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *al test = &unused; - if (error) { - *error = NULL; - } + *error = NULL; /* first try to open an existing file */ - if (phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, !is_data, 0, 1) == SUCCESS) { + if (phar_detect_phar_fname_ext(ZSTR_VAL(fname), ZSTR_LEN(fname), &ext_str, &ext_len, !is_data, 0, true) == SUCCESS) { goto check_file; } /* next try to create a new file */ - if (FAILURE == phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, !is_data, 1, 1)) { - if (error) { - if (ext_len == -2) { - spprintf(error, 0, "Cannot create a phar archive from a URL like \"%s\". Phar objects can only be created from local files", fname); - } else { - spprintf(error, 0, "Cannot create phar '%s', file extension (or combination) not recognised or the directory does not exist", fname); - } + if (FAILURE == phar_detect_phar_fname_ext(ZSTR_VAL(fname), ZSTR_LEN(fname), &ext_str, &ext_len, !is_data, 1, true)) { + if (ext_len == -2) { + spprintf(error, 0, "Cannot create a phar archive from a URL like \"%s\". Phar objects can only be created from local files", ZSTR_VAL(fname)); + } else { + spprintf(error, 0, "Cannot create phar '%s', file extension (or combination) not recognised or the directory does not exist", ZSTR_VAL(fname)); } return FAILURE; } check_file: - if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, test, &my_error) == SUCCESS) { - if (pphar) { - *pphar = *test; - } + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, is_data, options, test, &my_error) == SUCCESS) { + *pphar = *test; if ((*test)->is_data && !(*test)->is_tar && !(*test)->is_zip) { - if (error) { - spprintf(error, 0, "Cannot open '%s' as a PharData object. Use Phar::__construct() for executable archives", fname); - } + spprintf(error, 0, "Cannot open '%s' as a PharData object. Use Phar::__construct() for executable archives", ZSTR_VAL(fname)); return FAILURE; } if (PHAR_G(readonly) && !(*test)->is_data && ((*test)->is_tar || (*test)->is_zip)) { - phar_entry_info *stub; - if (NULL == (stub = zend_hash_str_find_ptr(&((*test)->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1))) { - spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", fname); + if (!zend_hash_str_exists(&((*test)->manifest), ZEND_STRL(".phar/stub.php"))) { + spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", ZSTR_VAL(fname)); return FAILURE; } } @@ -1370,54 +1362,51 @@ zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *al } return SUCCESS; } else if (my_error) { - if (error) { - *error = my_error; - } else { - efree(my_error); - } + *error = my_error; return FAILURE; } if (ext_len > 3 && (z = memchr(ext_str, 'z', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ip", 2)) { /* assume zip-based phar */ - return phar_open_or_create_zip(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_open_or_create_zip(fname, alias, is_data, options, pphar, error); } if (ext_len > 3 && (z = memchr(ext_str, 't', ext_len)) && ((ext_str + ext_len) - z >= 2) && !memcmp(z + 1, "ar", 2)) { /* assume tar-based phar */ - return phar_open_or_create_tar(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_open_or_create_tar(fname, alias, is_data, options, pphar, error); } - return phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, pphar, error); + return phar_create_or_parse_filename(fname, alias, is_data, options, pphar, error); } -/* }}} */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); +static zend_result phar_open_from_fp(php_stream* fp, const char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error); -zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ - phar_archive_data *mydata; +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_create_or_parse_filename( + zend_string *fname, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { php_stream *fp; zend_string *actual = NULL; + zend_string *save_fname = fname; char *p; - if (!pphar) { - pphar = &mydata; - } - if (php_check_open_basedir(fname)) { + if (php_check_open_basedir(ZSTR_VAL(fname))) { return FAILURE; } /* first open readonly so it won't be created if not present */ - fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, &actual); + fp = php_stream_open_wrapper(ZSTR_VAL(fname), "rb", IGNORE_URL|STREAM_MUST_SEEK|0, &actual); if (actual) { - fname = ZSTR_VAL(actual); - fname_len = ZSTR_LEN(actual); + fname = actual; } if (fp) { - if (phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error) == SUCCESS) { + if (phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, options, pphar, error) == SUCCESS) { if ((*pphar)->is_data || !PHAR_G(readonly)) { (*pphar)->is_writeable = 1; } @@ -1436,110 +1425,97 @@ zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *a if (actual) { zend_string_release_ex(actual, 0); + fname = save_fname; } if (PHAR_G(readonly) && !is_data) { if (options & REPORT_ERRORS) { - if (error) { - spprintf(error, 0, "creating archive \"%s\" disabled by the php.ini setting phar.readonly", fname); - } + spprintf(error, 0, "creating archive \"%s\" disabled by the php.ini setting phar.readonly", ZSTR_VAL(fname)); } return FAILURE; } /* set up our manifest */ - mydata = ecalloc(1, sizeof(phar_archive_data)); - mydata->fname = expand_filepath(fname, NULL); - if (mydata->fname == NULL) { + phar_archive_data *mydata = ecalloc(1, sizeof(phar_archive_data)); + /* TODO: prevent reallocation via a new expand_filepath() API? */ + char *new_fname = expand_filepath(ZSTR_VAL(fname), NULL); + if (new_fname == NULL) { efree(mydata); return FAILURE; } - fname_len = strlen(mydata->fname); + size_t new_fname_len = strlen(new_fname); #ifdef PHP_WIN32 - phar_unixify_path_separators(mydata->fname, fname_len); + phar_unixify_path_separators(new_fname, new_fname_len); #endif - p = strrchr(mydata->fname, '/'); + p = strrchr(new_fname, '/'); if (p) { - mydata->ext = memchr(p, '.', (mydata->fname + fname_len) - p); + mydata->ext = memchr(p, '.', (new_fname + new_fname_len) - p); if (mydata->ext == p) { - mydata->ext = memchr(p + 1, '.', (mydata->fname + fname_len) - p - 1); + mydata->ext = memchr(p + 1, '.', (new_fname + new_fname_len) - p - 1); } if (mydata->ext) { - mydata->ext_len = (mydata->fname + fname_len) - mydata->ext; + mydata->ext_len = (new_fname + new_fname_len) - mydata->ext; } } - if (pphar) { - *pphar = mydata; - } - zend_hash_init(&mydata->manifest, sizeof(phar_entry_info), zend_get_hash_value, destroy_phar_manifest_entry, 0); zend_hash_init(&mydata->mounted_dirs, sizeof(char *), zend_get_hash_value, NULL, 0); zend_hash_init(&mydata->virtual_dirs, sizeof(char *), - zend_get_hash_value, NULL, (bool)mydata->is_persistent); - mydata->fname_len = fname_len; + zend_get_hash_value, NULL, mydata->is_persistent); + mydata->fname = zend_string_init(new_fname, new_fname_len, false); + efree(new_fname); snprintf(mydata->version, sizeof(mydata->version), "%s", PHP_PHAR_API_VERSION); mydata->is_temporary_alias = alias ? 0 : 1; mydata->fp = NULL; mydata->is_writeable = 1; mydata->is_brandnew = 1; phar_request_initialize(); - zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len, mydata); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, mydata); if (is_data) { alias = NULL; - alias_len = 0; mydata->is_data = 1; /* assume tar format, PharData can specify other */ mydata->is_tar = 1; } else { - phar_archive_data *fd_ptr; - - if (alias && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { - if (error) { - spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", mydata->fname, alias); - } + if (alias) { + const phar_archive_data *fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias); + if (fd_ptr && SUCCESS != phar_free_alias(fd_ptr)) { + spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", ZSTR_VAL(mydata->fname), ZSTR_VAL(alias)); - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); - if (pphar) { - *pphar = NULL; - } + *pphar = NULL; return FAILURE; } } ZEND_ASSERT(!mydata->is_persistent); - mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len); - mydata->alias_len = alias ? alias_len : fname_len; + mydata->alias = alias ? estrndup(ZSTR_VAL(alias), ZSTR_LEN(alias)) : estrndup(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname)); + mydata->alias_len = alias ? ZSTR_LEN(alias) : ZSTR_LEN(mydata->fname); } - if (alias_len && alias) { - if (NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, mydata)) { + if (alias) { + if (NULL == zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, mydata)) { if (options & REPORT_ERRORS) { - if (error) { - spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", fname, alias); - } + spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", ZSTR_VAL(fname), ZSTR_VAL(alias)); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); - if (pphar) { - *pphar = NULL; - } + *pphar = NULL; return FAILURE; } } + *pphar = mydata; return SUCCESS; } -/* }}}*/ /** * Return an already opened filename. @@ -1548,8 +1524,14 @@ zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *a * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +zend_result phar_open_from_filename( + char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + uint32_t options, + phar_archive_data** pphar, + char **error +) { php_stream *fp; zend_string *actual; bool is_data = false; @@ -1562,7 +1544,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, is_data = true; } - if (phar_open_parsed_phar(fname, fname_len, alias, alias_len, is_data, options, pphar, error) == SUCCESS) { + if (phar_open_parsed_phar(fname, fname_len, alias, is_data, options, pphar, error) == SUCCESS) { return SUCCESS; } else if (error && *error) { return FAILURE; @@ -1590,7 +1572,7 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, fname_len = ZSTR_LEN(actual); } - zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, alias_len, options, pphar, error); + zend_result ret = phar_open_from_fp(fp, fname, fname_len, alias, options, pphar, error); if (actual) { zend_string_release_ex(actual, 0); @@ -1598,56 +1580,34 @@ zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, return ret; } -/* }}}*/ - -static inline char *phar_strnstr(const char *buf, int buf_len, const char *search, int search_len) /* {{{ */ -{ - const char *c; - ptrdiff_t so_far = 0; - - if (buf_len < search_len) { - return NULL; - } - - c = buf - 1; - - do { - if (!(c = memchr(c + 1, search[0], buf_len - search_len - so_far))) { - return (char *) NULL; - } - - so_far = c - buf; - - if (so_far >= (buf_len - search_len)) { - return (char *) NULL; - } - - if (!memcmp(c, search, search_len)) { - return (char *) c; - } - } while (1); -} -/* }}} */ /** * Scan an open fp for the required __HALT_COMPILER(); ?> token and verify * that the manifest is proper, then pass it to phar_parse_pharfile(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +static zend_result phar_open_from_fp( + php_stream* fp, + const char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + uint32_t options, + phar_archive_data** pphar, + char **error +) { static const char token[] = "__HALT_COMPILER();"; static const char zip_magic[] = "PK\x03\x04"; static const char gz_magic[] = "\x1f\x8b\x08"; static const char bz_magic[] = "BZh"; - char *pos, test = '\0'; + const char *pos; + char test = '\0'; int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion const int window_size = 1024; char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */ const zend_long readsize = sizeof(buffer) - sizeof(token); const zend_long tokenlen = sizeof(token) - 1; zend_long halt_offset; - size_t got; + ssize_t got; uint32_t compression = PHAR_FILE_COMPRESSED_NONE; if (error) { @@ -1665,7 +1625,7 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l /* Maybe it's better to compile the file instead of just searching, */ /* but we only want the offset. So we want a .re scanner to find it. */ while(!php_stream_eof(fp)) { - if ((got = php_stream_read(fp, buffer+tokenlen, readsize)) < (size_t) tokenlen) { + if ((got = php_stream_read(fp, buffer+tokenlen, readsize)) < tokenlen) { MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)") } @@ -1682,6 +1642,12 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l if (!PHAR_G(has_zlib)) { MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\" to temporary file, enable zlib extension in php.ini") } + + /* entire file is gzip-compressed, uncompress to temporary file */ + if (!(temp = php_stream_fopen_tmpfile())) { + MAPPHAR_ALLOC_FAIL("unable to create temporary file for decompression of gzipped phar archive \"%s\"") + } + array_init(&filterparams); /* this is defined in zlib's zconf.h */ #ifndef MAX_WBITS @@ -1689,11 +1655,6 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l #endif add_assoc_long_ex(&filterparams, "window", sizeof("window") - 1, MAX_WBITS + 32); - /* entire file is gzip-compressed, uncompress to temporary file */ - if (!(temp = php_stream_fopen_tmpfile())) { - MAPPHAR_ALLOC_FAIL("unable to create temporary file for decompression of gzipped phar archive \"%s\"") - } - php_stream_rewind(fp); filter = php_stream_filter_create("zlib.inflate", &filterparams, php_stream_is_persistent(fp)); @@ -1739,14 +1700,14 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l continue; } else if (!memcmp(pos, bz_magic, 3)) { php_stream_filter *filter; - php_stream *temp; if (!PHAR_G(has_bz2)) { MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\" to temporary file, enable bz2 extension in php.ini") } /* entire file is bzip-compressed, uncompress to temporary file */ - if (!(temp = php_stream_fopen_tmpfile())) { + php_stream *temp = php_stream_fopen_tmpfile(); + if (!temp) { MAPPHAR_ALLOC_FAIL("unable to create temporary file for decompression of bzipped phar archive \"%s\"") } @@ -1784,20 +1745,22 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l if (!memcmp(pos, zip_magic, 4)) { php_stream_seek(fp, 0, SEEK_END); - return phar_parse_zipfile(fp, fname, fname_len, alias, alias_len, pphar, error); + return phar_parse_zipfile(fp, fname, fname_len, alias, pphar, error); } if (got >= 512) { if (phar_is_tar(pos, fname)) { php_stream_rewind(fp); - return phar_parse_tarfile(fp, fname, fname_len, alias, alias_len, pphar, compression, error); + return phar_parse_tarfile(fp, fname, fname_len, alias, pphar, compression, error); } } } - if (got > 0 && (pos = phar_strnstr(buffer, got + sizeof(token), token, sizeof(token)-1)) != NULL) { + if (got > 0 && (pos = php_memnistr(buffer, token, tokenlen, buffer + got + sizeof(token))) != NULL) { halt_offset += (pos - buffer); /* no -tokenlen+tokenlen here */ - return phar_parse_pharfile(fp, fname, fname_len, alias, alias_len, halt_offset, pphar, compression, error); + const char *alias_cstr = alias ? ZSTR_VAL(alias) : NULL; + size_t alias_len = alias ? ZSTR_LEN(alias) : 0; + return phar_parse_pharfile(fp, fname, fname_len, alias_cstr, alias_len, halt_offset, pphar, compression, error); } halt_offset += got; @@ -1806,7 +1769,6 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (__HALT_COMPILER(); not found)") } -/* }}} */ /* * given the location of the file extension and the start of the file path, @@ -1820,10 +1782,10 @@ static zend_result phar_open_from_fp(php_stream* fp, char *fname, size_t fname_l static zend_result phar_analyze_path(const char *fname, const char *ext, size_t ext_len, int for_create) /* {{{ */ { php_stream_statbuf ssb; - char *realpath; char *filename = estrndup(fname, (ext - fname) + ext_len); - if ((realpath = expand_filepath(filename, NULL))) { + char *realpath = expand_filepath(filename, NULL); + if (realpath) { #ifdef PHP_WIN32 phar_unixify_path_separators(realpath, strlen(realpath)); #endif @@ -1870,7 +1832,8 @@ static zend_result phar_analyze_path(const char *fname, const char *ext, size_t if (SUCCESS != php_stream_stat_path((char *) filename, &ssb)) { if (!slash) { - if (!(realpath = expand_filepath(filename, NULL))) { + realpath = expand_filepath(filename, NULL); + if (!realpath) { efree(filename); return FAILURE; } @@ -1974,7 +1937,7 @@ static zend_result phar_check_str(const char *fname, const char *ext_str, size_t * the last parameter should be set to tell the thing to assume that filename is the full path, and only to check the * extension rules, not to iterate. */ -zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete) /* {{{ */ +zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, bool is_complete) /* {{{ */ { const char *pos, *slash; @@ -2013,7 +1976,8 @@ zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len phar_archive_data *pphar; if (is_complete) { - if (NULL != (pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), (char *) filename, filename_len))) { + pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), filename, filename_len); + if (pphar) { *ext_str = filename + (filename_len - pphar->ext_len); woohoo: *ext_len = pphar->ext_len; @@ -2033,7 +1997,8 @@ zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len return FAILURE; } - if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, (char *) filename, filename_len))) { + pphar = PHAR_G(manifest_cached) ? zend_hash_str_find_ptr(&cached_phars, filename, filename_len) : NULL; + if (pphar) { *ext_str = filename + (filename_len - pphar->ext_len); goto woohoo; } @@ -2068,45 +2033,40 @@ zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len } } - // TODO Use some sort of loop here instead of a goto pos = memchr(filename + 1, '.', filename_len); -next_extension: - if (!pos) { - return FAILURE; - } - - while (pos != filename && (*(pos - 1) == '/' || *(pos - 1) == '\0')) { - pos = memchr(pos + 1, '.', filename_len - (pos - filename) - 1); - if (!pos) { - return FAILURE; + while (pos) { + while (pos != filename && (*(pos - 1) == '/' || *(pos - 1) == '\0')) { + pos = memchr(pos + 1, '.', filename_len - (pos - filename) - 1); + if (!pos) { + return FAILURE; + } } - } - slash = memchr(pos, '/', filename_len - (pos - filename)); + slash = memchr(pos, '/', filename_len - (pos - filename)); - if (!slash) { - /* this is a url like "phar://blah.phar" with no directory */ - *ext_str = pos; - *ext_len = strlen(pos); + if (!slash) { + /* this is a url like "phar://blah.phar" with no directory */ + *ext_str = pos; + *ext_len = strlen(pos); - /* file extension must contain "phar" */ - return phar_check_str(filename, *ext_str, *ext_len, executable, for_create); - } + /* file extension must contain "phar" */ + return phar_check_str(filename, *ext_str, *ext_len, executable, for_create); + } - /* we've found an extension that ends at a directory separator */ - *ext_str = pos; - *ext_len = slash - pos; + /* we've found an extension that ends at a directory separator */ + *ext_str = pos; + *ext_len = slash - pos; - if (phar_check_str(filename, *ext_str, *ext_len, executable, for_create) == SUCCESS) { - return SUCCESS; - } + if (phar_check_str(filename, *ext_str, *ext_len, executable, for_create) == SUCCESS) { + return SUCCESS; + } - /* look for more extensions */ - pos = strchr(pos + 1, '.'); - if (pos) { - *ext_str = NULL; - *ext_len = 0; - goto next_extension; + /* look for more extensions */ + pos = strchr(pos + 1, '.'); + if (pos) { + *ext_str = NULL; + *ext_len = 0; + } } return FAILURE; @@ -2117,10 +2077,10 @@ static bool php_check_dots(const char *element, size_t n) /* {{{ */ { for(n-- ; n != SIZE_MAX; --n) { if (element[n] != '.') { - return 1; + return true; } } - return 0; + return false; } /* }}} */ @@ -2135,31 +2095,29 @@ static bool php_check_dots(const char *element, size_t n) /* {{{ */ /** * Remove .. and . references within a phar filename */ -char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd) /* {{{ */ +zend_string* phar_fix_filepath(const char *path, size_t path_length, bool use_cwd) /* {{{ */ { - char *newpath; - size_t newpath_len; - char *ptr; - char *tok; - size_t ptr_length, path_length = *new_len; - - if (PHAR_G(cwd_len) && use_cwd && path_length > 2 && path[0] == '.' && path[1] == '/') { - newpath_len = PHAR_G(cwd_len); - newpath = emalloc(strlen(path) + newpath_len + 1); - memcpy(newpath, PHAR_G(cwd), newpath_len); + zend_string *new_path; + size_t new_path_len; + size_t ptr_length; + + if (use_cwd && PHAR_G(cwd_len) && path_length > 2 && path[0] == '.' && path[1] == '/') { + new_path = zend_string_alloc(path_length + PHAR_G(cwd_len) + 1, false); + new_path_len = PHAR_G(cwd_len); + memcpy(ZSTR_VAL(new_path), PHAR_G(cwd), PHAR_G(cwd_len)); } else { - newpath = emalloc(strlen(path) + 2); - newpath[0] = '/'; - newpath_len = 1; + new_path = zend_string_alloc(path_length + 2, false); + ZSTR_VAL(new_path)[0] = '/'; + new_path_len = 1; } - ptr = path; + const char *ptr = path; if (*ptr == '/') { ++ptr; } - tok = ptr; + const char *tok = ptr; do { ptr = memchr(ptr, '/', path_length - (ptr - path)); @@ -2169,46 +2127,42 @@ char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd) /* {{{ */ switch (path_length - (tok - path)) { case 1: if (*tok == '.') { - efree(path); - *new_len = 1; - efree(newpath); - return estrndup("/", 1); + zend_string_release_ex(new_path, false); + return ZSTR_CHAR('/'); } break; case 2: if (tok[0] == '.' && tok[1] == '.') { - efree(path); - *new_len = 1; - efree(newpath); - return estrndup("/", 1); + zend_string_release_ex(new_path, false); + return ZSTR_CHAR('/'); } } - efree(newpath); - return path; + zend_string_release_ex(new_path, false); + return zend_string_init(path, path_length, false); } while (ptr) { ptr_length = ptr - tok; last_time: if (IS_DIRECTORY_UP(tok, ptr_length)) { - while (newpath_len > 1 && !IS_BACKSLASH(newpath[newpath_len - 1])) { - newpath_len--; + while (new_path_len > 1 && !IS_BACKSLASH(ZSTR_VAL(new_path)[new_path_len - 1])) { + new_path_len--; } - if (newpath[0] != '/') { - newpath[newpath_len] = '\0'; - } else if (newpath_len > 1) { - --newpath_len; + if (ZSTR_VAL(new_path)[0] != '/') { + ZSTR_VAL(new_path)[new_path_len] = '\0'; + } else if (new_path_len > 1) { + --new_path_len; } } else if (!IS_DIRECTORY_CURRENT(tok, ptr_length)) { - if (newpath_len > 1) { - newpath[newpath_len++] = '/'; - memcpy(newpath + newpath_len, tok, ptr_length+1); + if (new_path_len > 1) { + ZSTR_VAL(new_path)[new_path_len++] = '/'; + memcpy(ZSTR_VAL(new_path) + new_path_len, tok, ptr_length+1); } else { - memcpy(newpath + newpath_len, tok, ptr_length+1); + memcpy(ZSTR_VAL(new_path) + new_path_len, tok, ptr_length+1); } - newpath_len += ptr_length; + new_path_len += ptr_length; } if (ptr == path + path_length) { @@ -2228,10 +2182,8 @@ char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd) /* {{{ */ } } - efree(path); - *new_len = newpath_len; - newpath[newpath_len] = '\0'; - return erealloc(newpath, newpath_len + 1); + ZSTR_VAL(new_path)[new_path_len] = '\0'; + return zend_string_realloc(new_path, new_path_len, false); } /* }}} */ @@ -2247,7 +2199,7 @@ char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd) /* {{{ */ * * This is used by phar_parse_url() */ -zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create) /* {{{ */ +zend_string* phar_split_fname_ex(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create, const char **error) /* {{{ */ { const char *ext_str; #ifdef PHP_WIN32 @@ -2255,8 +2207,11 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a #endif size_t ext_len; - if (CHECK_NULL_PATH(filename, filename_len)) { - return FAILURE; + if (error) { + *error = NULL; + } + if (zend_char_has_nul_byte(filename, filename_len)) { + return NULL; } if (!strncasecmp(filename, "phar://", 7)) { @@ -2272,14 +2227,14 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a phar_unixify_path_separators((char *)filename, filename_len); } #endif - if (phar_detect_phar_fname_ext(filename, filename_len, &ext_str, &ext_len, executable, for_create, 0) == FAILURE) { + if (phar_detect_phar_fname_ext(filename, filename_len, &ext_str, &ext_len, executable, for_create, false) == FAILURE) { if (ext_len != -1) { - if (!ext_str) { + if (!ext_str && error) { /* no / detected, restore arch for error message */ #ifdef PHP_WIN32 - *arch = save; + *error = save; #else - *arch = (char*)filename; + *error = filename; #endif } @@ -2288,26 +2243,25 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a efree((char *)filename); } #endif - return FAILURE; + return NULL; } ext_len = 0; /* no extension detected - instead we are dealing with an alias */ } - *arch_len = ext_str - filename + ext_len; - *arch = estrndup(filename, *arch_len); + size_t arch_len = ext_str - filename + ext_len; + zend_string *arch = zend_string_init(filename, arch_len, false); - if (ext_str[ext_len]) { - *entry_len = filename_len - *arch_len; - *entry = estrndup(ext_str+ext_len, *entry_len); -#ifdef PHP_WIN32 - phar_unixify_path_separators(*entry, *entry_len); -#endif - *entry = phar_fix_filepath(*entry, entry_len, 0); - } else { - *entry_len = 1; - *entry = estrndup("/", 1); + if (entry) { + if (ext_str[ext_len]) { + size_t computed_entry_len = filename_len - arch_len; + /* We don't need to unixify the path on Windows, + * as ext_str is derived from filename that was already unixify */ + *entry = phar_fix_filepath(ext_str+ext_len, computed_entry_len, false); + } else { + *entry = ZSTR_CHAR('/'); + } } #ifdef PHP_WIN32 @@ -2316,37 +2270,35 @@ zend_result phar_split_fname(const char *filename, size_t filename_len, char **a } #endif - return SUCCESS; + return arch; } /* }}} */ +zend_string* phar_split_fname(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create) { + return phar_split_fname_ex(filename, filename_len, entry, executable, for_create, NULL); +} + /** * Invoked when a user calls Phar::mapPhar() from within an executing .phar * to set up its manifest directly */ -zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(/* copyable & hash update */ zend_string *alias, char **error) /* {{{ */ { - if (error) { - *error = NULL; - } + *error = NULL; zend_string *fname = zend_get_executed_filename_ex(); if (!fname) { - if (error) { - spprintf(error, 0, "cannot initialize a phar outside of PHP execution"); - } + *error = estrdup("cannot initialize a phar outside of PHP execution"); return FAILURE; } - if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, 0, REPORT_ERRORS, NULL, 0) == SUCCESS) { + if (phar_open_parsed_phar(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, false, REPORT_ERRORS, NULL, NULL) == SUCCESS) { return SUCCESS; } - if (0 == zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) { - if (error) { - spprintf(error, 0, "__HALT_COMPILER(); must be declared in a phar"); - } + if (NULL == zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) { + *error = estrdup("__HALT_COMPILER(); must be declared in a phar"); return FAILURE; } @@ -2359,9 +2311,7 @@ zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **er fp = php_stream_open_wrapper(ZSTR_VAL(fname), "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, &actual); if (!fp) { - if (error) { - spprintf(error, 0, "unable to open phar for reading \"%s\"", ZSTR_VAL(fname)); - } + spprintf(error, 0, "unable to open phar for reading \"%s\"", ZSTR_VAL(fname)); if (actual) { zend_string_release_ex(actual, 0); } @@ -2372,7 +2322,7 @@ zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **er fname = actual; } - zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, alias_len, REPORT_ERRORS, NULL, error); + zend_result ret = phar_open_from_fp(fp, ZSTR_VAL(fname), ZSTR_LEN(fname), alias, REPORT_ERRORS, NULL, error); if (actual) { zend_string_release_ex(actual, 0); @@ -2385,42 +2335,43 @@ zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **er /** * Validate the CRC32 of a file opened from within the phar */ -zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip) /* {{{ */ { php_stream *fp = idata->fp; phar_entry_info *entry = idata->internal_file; - if (error) { - *error = NULL; - } + *error = NULL; if (entry->is_zip && process_zip > 0) { /* verify local file header */ phar_zip_file_header local; phar_zip_data_desc desc; + php_stream *stream = phar_open_archive_fp(idata->phar); - if (SUCCESS != phar_open_archive_fp(idata->phar)) { - spprintf(error, 0, "phar error: unable to open zip-based phar archive \"%s\" to verify local file header for file \"%s\"", idata->phar->fname, ZSTR_VAL(entry->filename)); + if (!stream) { + spprintf(error, 0, "phar error: unable to open zip-based phar archive \"%s\" to verify local file header for file \"%s\"", + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } - php_stream_seek(phar_get_entrypfp(idata->internal_file), entry->header_offset, SEEK_SET); + php_stream_seek(stream, entry->header_offset, SEEK_SET); - if (sizeof(local) != php_stream_read(phar_get_entrypfp(idata->internal_file), (char *) &local, sizeof(local))) { - - spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (cannot read local file header for file \"%s\")", idata->phar->fname, ZSTR_VAL(entry->filename)); + if (sizeof(local) != php_stream_read(stream, (char *) &local, sizeof(local))) { + spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (cannot read local file header for file \"%s\")", + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } /* check for data descriptor */ if (((PHAR_ZIP_16(local.flags)) & 0x8) == 0x8) { - php_stream_seek(phar_get_entrypfp(idata->internal_file), + php_stream_seek(stream, entry->header_offset + sizeof(local) + PHAR_ZIP_16(local.filename_len) + PHAR_ZIP_16(local.extra_len) + entry->compressed_filesize, SEEK_SET); - if (sizeof(desc) != php_stream_read(phar_get_entrypfp(idata->internal_file), + if (sizeof(desc) != php_stream_read(stream, (char *) &desc, sizeof(desc))) { - spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (cannot read local data descriptor for file \"%s\")", idata->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (cannot read local data descriptor for file \"%s\")", + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } if (desc.signature[0] == 'P' && desc.signature[1] == 'K') { @@ -2432,7 +2383,8 @@ zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char * } /* verify local header */ if (ZSTR_LEN(entry->filename) != PHAR_ZIP_16(local.filename_len) || entry->crc32 != PHAR_ZIP_32(local.crc32) || entry->uncompressed_filesize != PHAR_ZIP_32(local.uncompsize) || entry->compressed_filesize != PHAR_ZIP_32(local.compsize)) { - spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (local header of file \"%s\" does not match central directory)", idata->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (local header of file \"%s\" does not match central directory)", + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } @@ -2460,7 +2412,8 @@ zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char * entry->is_crc_checked = 1; return SUCCESS; } else { - spprintf(error, 0, "phar error: internal corruption of phar \"%s\" (crc32 mismatch on file \"%s\")", idata->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 0, "phar error: internal corruption of phar \"%s\" (crc32 mismatch on file \"%s\")", + ZSTR_VAL(idata->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } } @@ -2482,7 +2435,7 @@ static int phar_flush_clean_deleted_apply(zval *zv) /* {{{ */ { phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv); - if (entry->fp_refcount <= 0 && entry->is_deleted) { + if (entry->is_deleted && phar_entry_can_remove(entry)) { return ZEND_HASH_APPLY_REMOVE; } else { return ZEND_HASH_APPLY_KEEP; @@ -2492,47 +2445,53 @@ static int phar_flush_clean_deleted_apply(zval *zv) /* {{{ */ #include "stub.h" /* Generated phar_get_stub() function from makestub.php script */ -zend_string *phar_create_default_stub(const char *index_php, const char *web_index, char **error) /* {{{ */ +zend_string *phar_create_default_stub(const zend_string *php_index_str, const zend_string *web_index_str, char **error) /* {{{ */ { - size_t index_len, web_len; + const char *php_index; + const char *web_index; + size_t php_len, web_len; if (error) { *error = NULL; } - if (!index_php) { - index_php = "index.php"; - } - - if (!web_index) { - web_index = "index.php"; - } - - index_len = strlen(index_php); - web_len = strlen(web_index); - - if (index_len > 400) { - /* ridiculous size not allowed for index.php startup filename */ - if (error) { - spprintf(error, 0, "Illegal filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", index_len); + if (!php_index_str) { + php_index = "index.php"; + php_len = strlen("index.php"); + } else { + php_index = ZSTR_VAL(php_index_str); + php_len = ZSTR_LEN(php_index_str); + if (php_len > 400) { + /* ridiculous size not allowed for index.php startup filename */ + if (error) { + spprintf(error, 0, "Illegal filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", php_len); + } return NULL; } } - if (web_len > 400) { - /* ridiculous size not allowed for index.php startup filename */ - if (error) { - spprintf(error, 0, "Illegal web filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", web_len); + if (!web_index_str) { + web_index = "index.php"; + web_len = strlen("index.php"); + } else { + web_index = ZSTR_VAL(web_index_str); + web_len = ZSTR_LEN(web_index_str); + + if (web_len > 400) { + /* ridiculous size not allowed for index.php startup filename */ + if (error) { + spprintf(error, 0, "Illegal web filename passed in for stub creation, was %zd characters long, and only 400 or less is allowed", web_len); + } return NULL; } } - return phar_get_stub(index_php, web_index, index_len+1, web_len+1); + return phar_get_stub(php_index, web_index, php_len+1, web_len+1); } /* }}} */ -void phar_flush(phar_archive_data *phar, char **error) { - phar_flush_ex(phar, NULL, false, error); +ZEND_ATTRIBUTE_NONNULL int phar_flush(phar_archive_data *phar, char **error) { + return phar_flush_ex(phar, NULL, false, error); } /** @@ -2540,13 +2499,14 @@ void phar_flush(phar_archive_data *phar, char **error) { * * if user_stub is NULL the default or existing stub should be used */ -void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */ { static const char halt_stub[] = "__HALT_COMPILER();"; phar_entry_info *entry, *newentry; size_t halt_offset; - int restore_alias_len, global_flags = 0; + uint32_t restore_alias_len; + uint32_t global_flags = 0; bool must_close_old_file = false; bool has_dirs = false; char manifest[18], entry_buffer[24]; @@ -2565,34 +2525,28 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream *shared_cfp = NULL; if (phar->is_persistent) { - if (error) { - spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } - if (error) { - *error = NULL; - } + *error = NULL; if (!zend_hash_num_elements(&phar->manifest) && !user_stub) { - return; + return EOF; } zend_hash_clean(&phar->virtual_dirs); if (phar->is_zip) { - phar_zip_flush(phar, user_stub, is_default_stub, error); - return; + return phar_zip_flush(phar, user_stub, is_default_stub, error); } if (phar->is_tar) { - phar_tar_flush(phar, user_stub, is_default_stub, error); - return; + return phar_tar_flush(phar, user_stub, is_default_stub, error); } if (PHAR_G(readonly)) { - return; + return EOF; } if (phar->fp && !phar->is_brandnew) { @@ -2600,18 +2554,16 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa must_close_old_file = false; php_stream_rewind(oldfile); } else { - oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL); + oldfile = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", 0, NULL); must_close_old_file = oldfile != NULL; } newfile = php_stream_fopen_tmpfile(); if (!newfile) { - if (error) { - spprintf(error, 0, "unable to create temporary file"); - } + *error = estrdup("unable to create temporary file"); if (must_close_old_file) { php_stream_close(oldfile); } - return; + return EOF; } if (user_stub) { @@ -2622,10 +2574,8 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - spprintf(error, 0, "illegal stub for phar \"%s\" (__HALT_COMPILER(); is missing)", phar->fname); - } - return; + spprintf(error, 0, "illegal stub for phar \"%s\" (__HALT_COMPILER(); is missing)", ZSTR_VAL(phar->fname)); + return EOF; } size_t len = pos - ZSTR_VAL(user_stub) + strlen(halt_stub); @@ -2640,10 +2590,8 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to create stub from string in new phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "unable to create stub from string in new phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } phar->halt_offset = len + end_sequence_len; } else { @@ -2663,17 +2611,15 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - if (new_stub) { - spprintf(error, 0, "unable to create stub in new phar \"%s\"", phar->fname); - } else { - spprintf(error, 0, "unable to copy stub of old phar to new phar \"%s\"", phar->fname); - } + if (new_stub) { + spprintf(error, 0, "unable to create stub in new phar \"%s\"", ZSTR_VAL(phar->fname)); + } else { + spprintf(error, 0, "unable to copy stub of old phar to new phar \"%s\"", ZSTR_VAL(phar->fname)); } if (new_stub) { zend_string_free(new_stub); } - return; + return EOF; } if (new_stub) { zend_string_free(new_stub); @@ -2690,7 +2636,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa /* compress as necessary, calculate crcs, serialize meta-data, manifest size, and file sizes */ main_metadata_str.s = NULL; if (phar->metadata_tracker.str) { - smart_str_appendl(&main_metadata_str, ZSTR_VAL(phar->metadata_tracker.str), ZSTR_LEN(phar->metadata_tracker.str)); + smart_str_append(&main_metadata_str, phar->metadata_tracker.str); } else if (!Z_ISUNDEF(phar->metadata_tracker.val)) { PHP_VAR_SERIALIZE_INIT(metadata_hash); php_var_serialize(&main_metadata_str, &phar->metadata_tracker.val, &metadata_hash); @@ -2708,7 +2654,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa /* remove this from the new phar */ continue; } - if (!entry->is_modified && entry->fp_refcount) { + if (entry->fp_refcount) { /* open file pointers refer to this fp, do not free the stream */ switch (entry->fp_type) { case PHAR_FP: @@ -2749,7 +2695,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa } continue; } - if (!phar_get_efp(entry, 0)) { + if (!phar_get_efp(entry, false)) { /* re-open internal file pointer just-in-time */ newentry = phar_open_jit(phar, entry, error); if (!newentry) { @@ -2760,16 +2706,14 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa } entry = newentry; } - file = phar_get_efp(entry, 0); - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 1)) { + file = phar_get_efp(entry, false); + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, true)) { if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } - return; + spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); + return EOF; } newcrc32 = php_crc32_bulk_init(); php_crc32_stream_bulk_update(&newcrc32, file, entry->uncompressed_filesize); @@ -2780,22 +2724,17 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa entry->compressed_filesize = entry->uncompressed_filesize; continue; } - filter = php_stream_filter_create(phar_compress_filter(entry, 0), NULL, 0); + filter = php_stream_filter_create(phar_compress_filter(entry, false), NULL, 0); if (!filter) { if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { - if (error) { - spprintf(error, 0, "unable to gzip compress file \"%s\" to new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } - } else { - if (error) { - spprintf(error, 0, "unable to bzip2 compress file \"%s\" to new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } - } - return; + spprintf(error, 0, "unable to %s compress file \"%s\" to new phar \"%s\"", + entry->flags & PHAR_ENT_COMPRESSED_GZ ? "gzip" : "bzip2", + ZSTR_VAL(entry->filename), + ZSTR_VAL(phar->fname)); + return EOF; } /* create new file that holds the compressed versions */ @@ -2807,9 +2746,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa entry->cfp = shared_cfp; if (!entry->cfp) { php_stream_filter_free(filter); - if (error) { - spprintf(error, 0, "unable to create temporary file"); - } + *error = estrdup("unable to create temporary file"); if (must_close_old_file) { php_stream_close(oldfile); } @@ -2820,15 +2757,14 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa ZEND_ASSERT(entry->header_offset == 0); entry->header_offset = php_stream_tell(entry->cfp); php_stream_flush(file); - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { php_stream_filter_free(filter); if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } + spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", + ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } php_stream_filter_append((&entry->cfp->writefilters), filter); @@ -2838,9 +2774,8 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } + spprintf(error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", + ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } php_stream_filter_flush(filter, 1); @@ -2900,9 +2835,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(newfile); phar->alias_len = restore_alias_len; - if (error) { - spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", phar->fname); - } + spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", ZSTR_VAL(phar->fname)); goto cleanup; } @@ -2921,9 +2854,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(newfile); phar->alias_len = restore_alias_len; - if (error) { - spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", phar->fname); - } + spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", ZSTR_VAL(phar->fname)); goto cleanup; } @@ -2954,12 +2885,10 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - if (entry->is_dir) { - spprintf(error, 0, "unable to write filename of directory \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } else { - spprintf(error, 0, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } + if (entry->is_dir) { + spprintf(error, 0, "unable to write filename of directory \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); + } else { + spprintf(error, 0, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); } goto cleanup; } @@ -2991,9 +2920,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } + spprintf(error, 0, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } @@ -3007,9 +2934,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to write manifest padding byte"); - } + *error = estrdup("unable to write manifest padding byte"); goto cleanup; } @@ -3026,15 +2951,13 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa file = entry->cfp; php_stream_seek(file, entry->header_offset, SEEK_SET); } else { - file = phar_get_efp(entry, 0); - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { + file = phar_get_efp(entry, false); + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } + spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } } @@ -3044,9 +2967,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(oldfile); } php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } + spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } @@ -3060,9 +2981,7 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa php_stream_close(newfile); - if (error) { - spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); - } + spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); goto cleanup; } @@ -3105,33 +3024,27 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa switch(phar->sig_flags) { default: { - char *digest = NULL; - size_t digest_len; + char *signature_error = NULL; + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { + spprintf(error, 0, "phar error: unable to write signature: %s", signature_error); + efree(signature_error); - if (FAILURE == phar_create_signature(phar, newfile, &digest, &digest_len, error)) { - if (error) { - char *save = *error; - spprintf(error, 0, "phar error: unable to write signature: %s", save); - efree(save); - } - if (digest) { - efree(digest); - } if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - return; + return EOF; } - php_stream_write(newfile, digest, digest_len); - efree(digest); + php_stream_write(newfile, ZSTR_VAL(signature), ZSTR_LEN(signature)); if (phar->sig_flags == PHAR_SIG_OPENSSL || phar->sig_flags == PHAR_SIG_OPENSSL_SHA256 || phar->sig_flags == PHAR_SIG_OPENSSL_SHA512) { - phar_set_32(sig_buf, digest_len); + phar_set_32(sig_buf, ZSTR_LEN(signature)); php_stream_write(newfile, sig_buf, 4); } + zend_string_release_ex(signature, false); break; } } @@ -3167,13 +3080,11 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa /* deferred flush */ phar->fp = newfile; } else { - phar->fp = php_stream_open_wrapper(phar->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); + phar->fp = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (!phar->fp) { phar->fp = newfile; - if (error) { - spprintf(error, 4096, "unable to open new phar \"%s\" for writing", phar->fname); - } - return; + spprintf(error, 4096, "unable to open new phar \"%s\" for writing", ZSTR_VAL(phar->fname)); + return EOF; } if (phar->flags & PHAR_FILE_COMPRESSED_GZ) { @@ -3186,10 +3097,8 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa zend_array_destroy(Z_ARR(filterparams)); if (!filter) { - if (error) { - spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", phar->fname); - } - return; + spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", ZSTR_VAL(phar->fname)); + return EOF; } php_stream_filter_append(&phar->fp->writefilters, filter); @@ -3216,12 +3125,11 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa } if (-1 == php_stream_seek(phar->fp, phar->halt_offset, SEEK_SET)) { - if (error) { - spprintf(error, 0, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", phar->fname); - } + spprintf(error, 0, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } - return; + return 0; cleanup: if (shared_cfp != NULL) { @@ -3233,6 +3141,8 @@ void phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_defa entry->header_offset = 0; } } ZEND_HASH_FOREACH_END(); + + return EOF; } /* }}} */ @@ -3258,7 +3168,7 @@ zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type static zend_string *phar_resolve_path(zend_string *filename) { - zend_string *ret = phar_find_in_include_path(filename, NULL); + zend_string *ret = phar_find_in_include_path(filename); if (!ret) { ret = phar_save_resolve_path(filename); } @@ -3269,14 +3179,14 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) { zend_op_array *res; zend_string *name = NULL; - int failed; + bool failed; phar_archive_data *phar; if (!file_handle || !file_handle->filename) { return phar_orig_compile_file(file_handle, type); } if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) { - if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, 0, &phar, NULL)) { + if (SUCCESS == phar_open_from_filename(ZSTR_VAL(file_handle->filename), ZSTR_LEN(file_handle->filename), NULL, 0, &phar, NULL)) { if (phar->is_zip || phar->is_tar) { zend_file_handle f; @@ -3320,11 +3230,11 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) } zend_try { - failed = 0; + failed = false; CG(zend_lineno) = 0; res = phar_orig_compile_file(file_handle, type); } zend_catch { - failed = 1; + failed = true; res = NULL; } zend_end_try(); @@ -3461,7 +3371,8 @@ void phar_request_initialize(void) /* {{{ */ if (!PHAR_G(request_init)) { PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; PHAR_G(has_bz2) = zend_hash_str_exists(&module_registry, "bz2", sizeof("bz2")-1); PHAR_G(has_zlib) = zend_hash_str_exists(&module_registry, "zlib", sizeof("zlib")-1); PHAR_G(request_init) = 1; diff --git a/ext/phar/phar/pharcommand.inc b/ext/phar/phar/pharcommand.inc index fee6c069ab08..7d35335a2947 100644 --- a/ext/phar/phar/pharcommand.inc +++ b/ext/phar/phar/pharcommand.inc @@ -225,13 +225,13 @@ class PharCommand extends CLICommand } } if ($pear) { - $apiver = (string) `pear -q info PHP_Archive 2>/dev/null|grep 'API Version'`; + $apiver = (string) shell_exec("pear -q info PHP_Archive 2>/dev/null|grep 'API Version'"); $apiver = trim(substr($apiver, strlen('API Version'))); } if ($apiver) { self::notice("PEAR package PHP_Archive: API Version: $apiver.\n"); - $files = explode("\n", (string) `pear list-files PHP_Archive`); - $phpdir = (string) `pear config-get php_dir 2>/dev/null`; + $files = explode("\n", (string) shell_exec("pear list-files PHP_Archive")); + $phpdir = (string) shell_exec("pear config-get php_dir 2>/dev/null"); $phpdir = trim($phpdir); self::notice("PEAR package PHP_Archive: $phpdir.\n"); if (is_dir($phpdir)) { diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 736226783bef..d75498f9c95a 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -105,8 +103,8 @@ ZEND_BEGIN_MODULE_GLOBALS(phar) /* for cached phars, this is a per-process store of fp/ufp */ phar_entry_fp *cached_fp; HashTable phar_alias_map; - int phar_SERVER_mung_list; char* cache_list; + int phar_SERVER_mung_list; bool readonly; bool manifest_cached; bool persist; @@ -148,10 +146,9 @@ ZEND_BEGIN_MODULE_GLOBALS(phar) char *openssl_privatekey; uint32_t openssl_privatekey_len; /* phar_get_archive cache */ - char* last_phar_name; - uint32_t last_phar_name_len; - char* last_alias; + const zend_string *last_phar_name; uint32_t last_alias_len; + const char* last_alias; phar_archive_data* last_phar; HashTable mime_types; ZEND_END_MODULE_GLOBALS(phar) @@ -196,6 +193,7 @@ typedef struct _phar_metadata_tracker { typedef struct _phar_entry_info { /* first bytes are exactly as in file */ uint32_t uncompressed_filesize; + /* modification time */ uint32_t timestamp; uint32_t compressed_filesize; uint32_t crc32; @@ -205,7 +203,6 @@ typedef struct _phar_entry_info { uint32_t old_flags; phar_metadata_tracker metadata_tracker; zend_string *filename; - enum phar_fp_type fp_type; /* offset within original phar file of the file contents */ zend_long offset_abs; /* offset within fp of the file contents */ @@ -214,42 +211,43 @@ typedef struct _phar_entry_info { zend_long header_offset; php_stream *fp; php_stream *cfp; + enum phar_fp_type fp_type; int fp_refcount; + unsigned int fileinfo_lock_count; char *tmp; phar_archive_data *phar; - char *link; /* symbolic link to another file */ + zend_string *symlink; char tar_type; /* position in the manifest */ uint32_t manifest_pos; /* for stat */ unsigned short inode; - uint32_t is_crc_checked:1; - uint32_t is_modified:1; - uint32_t is_deleted:1; - uint32_t is_dir:1; + bool is_crc_checked:1; + bool is_modified:1; + bool is_deleted:1; + bool is_dir:1; /* this flag is used for mounted entries (external files mapped to location inside a phar */ - uint32_t is_mounted:1; + bool is_mounted:1; /* used when iterating */ - uint32_t is_temp_dir:1; + bool is_temp_dir:1; /* tar-based phar file stuff */ - uint32_t is_tar:1; + bool is_tar:1; /* zip-based phar file stuff */ - uint32_t is_zip:1; + bool is_zip:1; /* for cached phar entries */ - uint32_t is_persistent:1; + bool is_persistent:1; } phar_entry_info; /* information about a phar file (the archive itself) */ struct _phar_archive_data { - char *fname; - uint32_t fname_len; - /* for phar_detect_fname_ext, this stores the location of the file extension within fname */ - char *ext; + zend_string *fname; + /* The ext field stores the location of the file extension from the fname field, and thus should never be freed. */ uint32_t ext_len; + const char *ext; char *alias; - uint32_t alias_len; + uint32_t alias_len; char version[12]; size_t halt_offset; HashTable manifest; @@ -258,32 +256,31 @@ struct _phar_archive_data { /* hash of mounted directory paths */ HashTable mounted_dirs; uint32_t flags; - uint32_t min_timestamp; uint32_t max_timestamp; + int refcount; php_stream *fp; /* decompressed file contents are stored here */ php_stream *ufp; - int refcount; uint32_t sig_flags; uint32_t sig_len; char *signature; phar_metadata_tracker metadata_tracker; uint32_t phar_pos; /* if 1, then this alias was manually specified by the user and is not a permanent alias */ - uint32_t is_temporary_alias:1; - uint32_t is_modified:1; - uint32_t is_writeable:1; - uint32_t is_brandnew:1; + bool is_temporary_alias:1; + bool is_modified:1; + bool is_writeable:1; + bool is_brandnew:1; /* defer phar creation */ - uint32_t donotflush:1; + bool donotflush:1; /* zip-based phar variables */ - uint32_t is_zip:1; + bool is_zip:1; /* tar-based phar variables */ - uint32_t is_tar:1; + bool is_tar:1; /* PharData variables */ - uint32_t is_data:1; + bool is_data:1; /* for cached phar manifests */ - uint32_t is_persistent:1; + bool is_persistent:1; }; typedef struct _phar_entry_fp_info { @@ -381,50 +378,54 @@ static inline bool phar_validate_alias(const char *alias, size_t alias_len) /* { static inline void phar_set_inode(phar_entry_info *entry) /* {{{ */ { - char tmp[MAXPATHLEN]; - size_t tmp_len; - size_t len1, len2; - - tmp_len = MIN(MAXPATHLEN, ZSTR_LEN(entry->filename) + entry->phar->fname_len); - - len1 = MIN(entry->phar->fname_len, tmp_len); if (entry->phar->fname) { - memcpy(tmp, entry->phar->fname, len1); - } + char tmp[MAXPATHLEN]; + size_t tmp_len = MIN(MAXPATHLEN, ZSTR_LEN(entry->filename) + ZSTR_LEN(entry->phar->fname)); - len2 = MIN(tmp_len - len1, ZSTR_LEN(entry->filename)); - memcpy(tmp + len1, entry->filename, len2); + size_t len1 = MIN(ZSTR_LEN(entry->phar->fname), tmp_len); + memcpy(tmp, ZSTR_VAL(entry->phar->fname), len1); - entry->inode = (unsigned short) zend_hash_func(tmp, tmp_len); + size_t len2 = MIN(tmp_len - len1, ZSTR_LEN(entry->filename)); + memcpy(tmp + len1, entry->filename, len2); + + entry->inode = (unsigned short) zend_hash_func(tmp, tmp_len); + } else { + entry->inode = (unsigned short) zend_string_hash_val(entry->filename); + } } /* }}} */ +static inline bool phar_entry_can_remove(const phar_entry_info *entry) +{ + return entry->fp_refcount == 0 && entry->fileinfo_lock_count == 0; +} + void phar_request_initialize(void); void phar_object_init(void); void phar_destroy_phar_data(phar_archive_data *phar); -zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); -zend_result phar_open_from_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, uint32_t options, phar_archive_data** pphar, char **error); -zend_result phar_open_or_create_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -zend_result phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, size_t alias_len, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); -zend_result phar_open_executed_filename(char *alias, size_t alias_len, char **error); -zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len); -zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error); -zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error); -zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); +ZEND_ATTRIBUTE_NONNULL zend_result phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip); +zend_result phar_open_from_filename(char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_filename(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_create_or_parse_filename(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(2) zend_result phar_open_executed_filename(/* copyable & hash update */ zend_string *alias, char **error); +zend_result phar_free_alias(const phar_archive_data *phar); +phar_archive_data* phar_get_archive(const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error); +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, const char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error); +ZEND_ATTRIBUTE_NONNULL zend_string* phar_create_signature(phar_archive_data *phar, php_stream *fp, char **error); /* utility functions */ -zend_string *phar_create_default_stub(const char *index_php, const char *web_index, char **error); -char *phar_decompress_filter(phar_entry_info * entry, int return_unknown); -char *phar_compress_filter(phar_entry_info * entry, int return_unknown); +zend_string *phar_create_default_stub(const zend_string *php_index_str, const zend_string *web_index_str, char **error); +const char *phar_decompress_filter(const phar_entry_info *entry, bool return_unknown); +const char *phar_compress_filter(const phar_entry_info *entry, bool return_unknown); /* void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); */ -void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len); -zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len); -zend_string *phar_find_in_include_path(zend_string *file, phar_archive_data **pphar); -char *phar_fix_filepath(char *path, size_t *new_len, int use_cwd); -phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error); +void phar_add_virtual_dirs(phar_archive_data *phar, const char *filename, size_t filename_len); +zend_result phar_mount_entry(phar_archive_data *phar, const char *filename, size_t filename_len, char *path, size_t path_len); + zend_string *phar_find_in_include_path(const zend_string *file); +zend_string* phar_fix_filepath(const char *path, size_t path_length, bool use_cwd); +ZEND_ATTRIBUTE_NONNULL phar_entry_info * phar_open_jit(const phar_archive_data *phar, phar_entry_info *entry, char **error); void phar_parse_metadata_lazy(const char *buffer, phar_metadata_tracker *tracker, uint32_t zip_metadata_len, bool persistent); bool phar_metadata_tracker_has_data(const phar_metadata_tracker* tracker, bool persistent); /* If this has data, free it and set all values to undefined. */ @@ -434,24 +435,24 @@ void phar_metadata_tracker_clone(phar_metadata_tracker* tracker); void phar_metadata_tracker_try_ensure_has_serialized_data(phar_metadata_tracker* tracker, bool persistent); zend_result phar_metadata_tracker_unserialize_or_copy(phar_metadata_tracker* tracker, zval *value, bool persistent, HashTable *unserialize_options, const char* method_name); void destroy_phar_manifest_entry(zval *zv); -int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links); -php_stream *phar_get_efp(phar_entry_info *entry, int follow_links); -zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error); -zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links); +int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, bool follow_links); +php_stream *phar_get_efp(phar_entry_info *entry, bool follow_links); +ZEND_ATTRIBUTE_NONNULL zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error); +ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, bool follow_links); phar_entry_info *phar_get_link_source(phar_entry_info *entry); -zend_result phar_open_archive_fp(phar_archive_data *phar); +php_stream *phar_open_archive_fp(phar_archive_data *phar); zend_result phar_copy_on_write(phar_archive_data **pphar); /* tar functions in tar.c */ -bool phar_is_tar(char *buf, char *fname); -zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error); -zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error); -void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error); +bool phar_is_tar(const char *buf, const char *fname); +zend_result phar_parse_tarfile(php_stream* fp, const char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, phar_archive_data** pphar, uint32_t compression, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_tar(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error); /* zip functions in zip.c */ -int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, char **error); -int phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error); -void phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); +zend_result phar_parse_zipfile(php_stream *fp, const char *fname, size_t fname_len, /* copyable & hash update */ zend_string *alias, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_zip(zend_string *fname, /* copyable & hash update */ zend_string *alias, bool is_data, uint32_t options, phar_archive_data** pphar, char **error); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); #ifdef PHAR_MAIN extern const php_stream_wrapper php_stream_phar_wrapper; @@ -463,14 +464,15 @@ extern HashTable cached_alias; bool phar_archive_delref(phar_archive_data *phar); void phar_entry_delref(phar_entry_data *idata); -phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security); -phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security); -phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); -zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security); -void phar_flush_ex(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); -void phar_flush(phar_archive_data *archive, char **error); -zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete); -zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create); +phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, bool security); +phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, bool security); +ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security, uint32_t timestamp); +ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, const zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security); +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error); +ZEND_ATTRIBUTE_NONNULL int phar_flush(phar_archive_data *archive, char **error); +zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, bool is_complete); +zend_string* phar_split_fname_ex(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create, const char **error); +zend_string* phar_split_fname(const char *filename, size_t filename_len, zend_string **entry, int executable, int for_create); typedef enum { pcr_use_query, @@ -484,6 +486,6 @@ typedef enum { pcr_err_empty_entry } phar_path_check_result; -phar_path_check_result phar_path_check(char **p, size_t *len, const char **error); +ZEND_ATTRIBUTE_NONNULL phar_path_check_result phar_path_check(char **p, size_t *len, const char **error); END_EXTERN_C() diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 723339a431ee..46db925cfd50 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -27,25 +25,35 @@ #include "main/SAPI.h" #include "zend_exceptions.h" #include "zend_interfaces.h" -#include "zend_exceptions.h" static zend_class_entry *phar_ce_archive; static zend_class_entry *phar_ce_data; static zend_class_entry *phar_ce_PharException; static zend_class_entry *phar_ce_entry; -static int phar_file_type(HashTable *mimes, char *file, char **mime_type) /* {{{ */ +#define PHAR_FETCH_INTERNAL_EX(zv) (void *)((char *) Z_OBJ_P(zv) - Z_OBJ_P(zv)->handlers->offset); +#define PHAR_FETCH_INTERNAL() PHAR_FETCH_INTERNAL_EX(ZEND_THIS) + +#define PHAR_ARCHIVE_OBJECT() \ + phar_archive_object *phar_obj = PHAR_FETCH_INTERNAL(); \ + if (!phar_obj->archive) { \ + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, \ + "Cannot call method on an uninitialized Phar object"); \ + RETURN_THROWS(); \ + } + +static int phar_file_type(const HashTable *mimes, const char *file, char **mime_type) /* {{{ */ { - char *ext; - phar_mime_type *mime; - ext = strrchr(file, '.'); + const char *ext = strrchr(file, '.'); if (!ext) { *mime_type = "text/plain"; /* no file extension = assume text/plain */ return PHAR_MIME_OTHER; } ++ext; - if (NULL == (mime = zend_hash_str_find_ptr(mimes, ext, strlen(ext)))) { + + phar_mime_type *mime = zend_hash_str_find_ptr(mimes, ext, strlen(ext)); + if (!mime) { *mime_type = "application/octet-stream"; return PHAR_MIME_OTHER; } @@ -54,10 +62,9 @@ static int phar_file_type(HashTable *mimes, char *file, char **mime_type) /* {{{ } /* }}} */ -static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, char *basename, size_t request_uri_len) /* {{{ */ +static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, const char *basename, size_t request_uri_len) /* {{{ */ { HashTable *_SERVER; - zval *stuff; char *path_info; size_t basename_len = strlen(basename); size_t code; @@ -71,23 +78,25 @@ static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, ch _SERVER = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]); /* PATH_INFO and PATH_TRANSLATED should always be munged */ - if (NULL != (stuff = zend_hash_str_find(_SERVER, "PATH_INFO", sizeof("PATH_INFO")-1))) { + zval *stuff = zend_hash_str_find(_SERVER, ZEND_STRL("PATH_INFO")); + if (stuff) { path_info = Z_STRVAL_P(stuff); code = Z_STRLEN_P(stuff); if (code > (size_t)entry_len && !memcmp(path_info, entry, entry_len)) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, path_info + entry_len, request_uri_len); - zend_hash_str_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_PATH_INFO"), &temp); } } - if (NULL != (stuff = zend_hash_str_find(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("PATH_TRANSLATED")); + if (stuff) { zend_string *str = strpprintf(4096, "phar://%s%s", fname, entry); ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_NEW_STR(stuff, str); - zend_hash_str_update(_SERVER, "PHAR_PATH_TRANSLATED", sizeof("PHAR_PATH_TRANSLATED")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_PATH_TRANSLATED"), &temp); } if (!PHAR_G(phar_SERVER_mung_list)) { @@ -95,52 +104,61 @@ static void phar_mung_server_vars(char *fname, char *entry, size_t entry_len, ch } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_REQUEST_URI) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("REQUEST_URI")); + if (stuff) { path_info = Z_STRVAL_P(stuff); code = Z_STRLEN_P(stuff); if (code > basename_len && !memcmp(path_info, basename, basename_len)) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, path_info + basename_len, code - basename_len); - zend_hash_str_update(_SERVER, "PHAR_REQUEST_URI", sizeof("PHAR_REQUEST_URI")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_REQUEST_URI"), &temp); } } } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_PHP_SELF) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "PHP_SELF", sizeof("PHP_SELF")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("PHP_SELF")); + if (stuff) { path_info = Z_STRVAL_P(stuff); code = Z_STRLEN_P(stuff); if (code > basename_len && !memcmp(path_info, basename, basename_len)) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, path_info + basename_len, code - basename_len); - zend_hash_str_update(_SERVER, "PHAR_PHP_SELF", sizeof("PHAR_PHP_SELF")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_PHP_SELF"), &temp); } } } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_SCRIPT_NAME) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("SCRIPT_NAME")); + if (stuff) { ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_STRINGL(stuff, entry, entry_len); - zend_hash_str_update(_SERVER, "PHAR_SCRIPT_NAME", sizeof("PHAR_SCRIPT_NAME")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_SCRIPT_NAME"), &temp); } } if (PHAR_G(phar_SERVER_mung_list) & PHAR_MUNG_SCRIPT_FILENAME) { - if (NULL != (stuff = zend_hash_str_find(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1))) { + stuff = zend_hash_str_find(_SERVER, ZEND_STRL("SCRIPT_FILENAME")); + if (stuff) { zend_string *str = strpprintf(4096, "phar://%s%s", fname, entry); ZVAL_STR(&temp, Z_STR_P(stuff)); ZVAL_NEW_STR(stuff, str); - zend_hash_str_update(_SERVER, "PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME")-1, &temp); + zend_hash_str_update(_SERVER, ZEND_STRL("PHAR_SCRIPT_FILENAME"), &temp); } } } /* }}} */ -static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char *mime_type, int code, char *entry, size_t entry_len, char *arch, char *basename, char *ru, size_t ru_len) /* {{{ */ +typedef enum { + PHAR_ACT_DO_EXIT, + PHAR_ACT_GRACEFULLY_RETURN, +} phar_action_status; + +static phar_action_status phar_file_action(phar_archive_data *phar, phar_entry_info *info, char *mime_type, int code, char *entry, size_t entry_len, char *arch, const char *basename, char *ru, size_t ru_len) /* {{{ */ { char *name = NULL, buf[8192]; const char *cwd; @@ -157,7 +175,6 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char switch (code) { case PHAR_MIME_PHPS: - efree(basename); /* highlight source */ if (entry[0] == '/') { spprintf(&name, 4096, "phar://%s%s", arch, entry); @@ -169,13 +186,9 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char highlight_file(name, &syntax_highlighter_ini); efree(name); -#ifdef PHP_WIN32 - efree(arch); -#endif - zend_bailout(); + return PHAR_ACT_DO_EXIT; case PHAR_MIME_OTHER: /* send headers, output file contents */ - efree(basename); ctr.line_len = spprintf((char **) &(ctr.line), 0, "Content-type: %s", mime_type); sapi_header_op(SAPI_HEADER_REPLACE, &ctr); efree((void *) ctr.line); @@ -184,11 +197,11 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char efree((void *) ctr.line); if (FAILURE == sapi_send_headers()) { - zend_bailout(); + return PHAR_ACT_DO_EXIT; } /* prepare to output */ - fp = phar_get_efp(info, 1); + fp = phar_get_efp(info, true); if (!fp) { char *error; @@ -197,12 +210,12 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); efree(error); } - return -1; + return PHAR_ACT_GRACEFULLY_RETURN; } - fp = phar_get_efp(info, 1); + fp = phar_get_efp(info, true); } position = 0; - phar_seek_efp(info, 0, SEEK_SET, 0, 1); + phar_seek_efp(info, 0, SEEK_SET, 0, true); do { got = php_stream_read(fp, buf, MIN(8192, info->uncompressed_filesize - position)); @@ -215,11 +228,10 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char } } while (1); - zend_bailout(); + return PHAR_ACT_DO_EXIT; case PHAR_MIME_PHP: if (basename) { phar_mung_server_vars(arch, entry, entry_len, basename, ru_len); - efree(basename); } if (entry[0] == '/') { @@ -261,9 +273,6 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char } zend_destroy_file_handle(&file_handle); -#ifdef PHP_WIN32 - efree(arch); -#endif if (new_op_array) { ZVAL_UNDEF(&result); @@ -291,16 +300,15 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char efree(name); } zend_end_try(); - zend_bailout(); + return PHAR_ACT_DO_EXIT; } - - return PHAR_MIME_PHP; } - return -1; + + return PHAR_ACT_GRACEFULLY_RETURN; } /* }}} */ -static void phar_do_403(char *entry, size_t entry_len) /* {{{ */ +static void phar_do_403(void) /* {{{ */ { sapi_header_line ctr = {0}; @@ -314,16 +322,16 @@ static void phar_do_403(char *entry, size_t entry_len) /* {{{ */ } /* }}} */ -static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, char *f404, size_t f404_len, char *entry, size_t entry_len) /* {{{ */ +static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, zend_string *f404) /* {{{ */ { sapi_header_line ctr = {0}; - phar_entry_info *info; - if (phar && f404_len) { - info = phar_get_entry_info(phar, f404, f404_len, NULL, 1); + if (phar && f404 && ZSTR_LEN(f404)) { + phar_entry_info *info = phar_get_entry_info(phar, ZSTR_VAL(f404), ZSTR_LEN(f404), NULL, true); if (info) { - phar_file_action(phar, info, "text/html", PHAR_MIME_PHP, f404, f404_len, fname, NULL, NULL, 0); + /* Status doesn't matter, we're exiting anyway. */ + phar_file_action(phar, info, "text/html", PHAR_MIME_PHP, ZSTR_VAL(f404), ZSTR_LEN(f404), fname, NULL, NULL, 0); return; } } @@ -341,9 +349,10 @@ static void phar_do_404(phar_archive_data *phar, char *fname, size_t fname_len, /* post-process REQUEST_URI and retrieve the actual request URI. This is for cases like http://localhost/blah.phar/path/to/file.php/extra/stuff which calls "blah.phar" file "path/to/file.php" with PATH_INFO "/extra/stuff" */ -static void phar_postprocess_ru_web(char *fname, size_t fname_len, char **entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ +static void phar_postprocess_ru_web(const char *fname, size_t fname_len, char *entry, size_t *entry_len, char **ru, size_t *ru_len) /* {{{ */ { - char *e = *entry + 1, *u = NULL, *u1 = NULL, *saveu = NULL; + char *e = entry + 1; + char *u1 = NULL, *u = NULL, *saveu = NULL; size_t e_len = *entry_len - 1, u_len = 0; phar_archive_data *pphar; @@ -400,34 +409,27 @@ static void phar_postprocess_ru_web(char *fname, size_t fname_len, char **entry, */ PHP_METHOD(Phar, running) { - zend_string *fname; - char *arch, *entry; - size_t arch_len, entry_len; - bool retphar = 1; + bool retphar = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &retphar) == FAILURE) { RETURN_THROWS(); } - fname = zend_get_executed_filename_ex(); + const zend_string *fname = zend_get_executed_filename_ex(); if (!fname) { RETURN_EMPTY_STRING(); } - if ( - zend_string_starts_with_literal_ci(fname, "phar://") - && SUCCESS == phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 2, 0) - ) { - efree(entry); - if (retphar) { - RETVAL_STRINGL(ZSTR_VAL(fname), arch_len + 7); - efree(arch); - return; - } else { - // TODO: avoid reallocation ??? - RETVAL_STRINGL(arch, arch_len); - efree(arch); - return; + if (zend_string_starts_with_literal_ci(fname, "phar://")) { + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 2, 0); + if (arch) { + if (retphar) { + RETVAL_STRINGL(ZSTR_VAL(fname), ZSTR_LEN(arch) + 7); + zend_string_release_ex(arch, false); + return; + } else { + RETURN_STR(arch); + } } } @@ -442,8 +444,8 @@ PHP_METHOD(Phar, running) */ PHP_METHOD(Phar, mount) { - char *fname, *arch = NULL, *entry = NULL, *path, *actual; - size_t fname_len, arch_len, entry_len; + char *fname, *path, *actual; + size_t fname_len; size_t path_len, actual_len; phar_archive_data *pphar; #ifdef PHP_WIN32 @@ -474,42 +476,39 @@ PHP_METHOD(Phar, mount) } #endif - if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { - efree(entry); - entry = NULL; - + zend_string *entry = NULL; + zend_string *arch = NULL; + if (fname_len > 7 && !memcmp(fname, "phar://", 7) && (arch = phar_split_fname(fname, fname_len, NULL, 2, 0))) { if (path_len > 7 && !memcmp(path, "phar://", 7)) { zend_throw_exception_ex(phar_ce_PharException, 0, "Can only mount internal paths within a phar archive, use a relative path instead of \"%s\"", path); - efree(arch); + zend_string_release_ex(arch, false); goto finish; } carry_on2: - if (NULL == (pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), arch, arch_len))) { - if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len))) { + pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), arch); + if (!pphar) { + if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_find_ptr(&cached_phars, arch))) { if (SUCCESS == phar_copy_on_write(&pphar)) { goto carry_on; } } - zend_throw_exception_ex(phar_ce_PharException, 0, "%s is not a phar archive, cannot mount", arch); - - if (arch) { - efree(arch); - } + zend_throw_exception_ex(phar_ce_PharException, 0, "%s is not a phar archive, cannot mount", ZSTR_VAL(arch)); + zend_string_release_ex(arch, false); goto finish; } carry_on: if (SUCCESS != phar_mount_entry(pphar, actual, actual_len, path, path_len)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "Mounting of %s to %s within phar %s failed", path, actual, arch); + zend_throw_exception_ex(phar_ce_PharException, 0, "Mounting of %s to %s within phar %s failed", path, actual, ZSTR_VAL(arch)); } - if (entry && path == entry) { - efree(entry); + if (entry && path == ZSTR_VAL(entry)) { + zend_string_release_ex(entry, false); } if (arch) { - efree(arch); + zend_string_release_ex(arch, false); } goto finish; @@ -521,9 +520,9 @@ PHP_METHOD(Phar, mount) } goto carry_on; - } else if (SUCCESS == phar_split_fname(path, path_len, &arch, &arch_len, &entry, &entry_len, 2, 0)) { - path = entry; - path_len = entry_len; + } else if ((arch = phar_split_fname(path, path_len, &entry, 2, 0))) { + path = ZSTR_VAL(entry); + path_len = ZSTR_LEN(entry); goto carry_on2; } @@ -550,8 +549,9 @@ PHP_METHOD(Phar, webPhar) zval *mimeoverride = NULL; zend_fcall_info rewrite_fci = {0}; zend_fcall_info_cache rewrite_fcc; - char *alias = NULL, *error, *index_php = NULL, *f404 = NULL, *ru = NULL; - size_t alias_len = 0, f404_len = 0, free_pathinfo = 0; + char *error, *index_php = NULL, *ru = NULL; + size_t free_pathinfo = 0; + zend_string *f404 = NULL; size_t ru_len = 0; char *fname, *path_info, *mime_type = NULL, *entry, *pt; const char *basename; @@ -561,14 +561,16 @@ PHP_METHOD(Phar, webPhar) phar_archive_data *phar = NULL; phar_entry_info *info = NULL; size_t sapi_mod_name_len = strlen(sapi_module.name); + phar_action_status status = PHAR_ACT_DO_EXIT; + zend_string *alias = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!s!af!", &alias, &alias_len, &index_php, &index_php_len, &f404, &f404_len, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!s!S!af!", &alias, &index_php, &index_php_len, &f404, &mimeoverride, &rewrite_fci, &rewrite_fcc) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - if (phar_open_executed_filename(alias, alias_len, &error) != SUCCESS) { + if (phar_open_executed_filename(alias, &error) != SUCCESS) { if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); efree(error); @@ -601,10 +603,8 @@ PHP_METHOD(Phar, webPhar) fname_len = ZSTR_LEN(zend_file_name); #ifdef PHP_WIN32 - if (memchr(fname, '\\', fname_len)) { - fname = estrndup(fname, fname_len); - phar_unixify_path_separators(fname, fname_len); - } + fname = estrndup(fname, fname_len); + phar_unixify_path_separators(fname, fname_len); #endif basename = zend_memrchr(fname, '/', fname_len); @@ -620,7 +620,7 @@ PHP_METHOD(Phar, webPhar) || (sapi_mod_name_len == sizeof("litespeed") - 1 && !strncmp(sapi_module.name, "litespeed", sizeof("litespeed") - 1))) { if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF) { - HashTable *_server = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]); + const HashTable *_server = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]); zval *z_script_name, *z_path_info; if (NULL == (z_script_name = zend_hash_str_find(_server, "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1)) || @@ -646,10 +646,13 @@ PHP_METHOD(Phar, webPhar) pt = estrndup(Z_STRVAL_P(z_script_name), Z_STRLEN_P(z_script_name)); } else { - char *testit; + char *testit = sapi_getenv("SCRIPT_NAME", sizeof("SCRIPT_NAME")-1); + if (!testit) { + goto finish; + } - testit = sapi_getenv("SCRIPT_NAME", sizeof("SCRIPT_NAME")-1); - if (!(pt = strstr(testit, basename))) { + pt = strstr(testit, basename); + if (!pt) { efree(testit); goto finish; } @@ -669,12 +672,14 @@ PHP_METHOD(Phar, webPhar) } pt = estrndup(testit, (pt - testit) + (fname_len - (basename - fname))); + efree(testit); } not_cgi = 0; } else { path_info = SG(request_info).request_uri; - if (!(pt = strstr(path_info, basename))) { + pt = strstr(path_info, basename); + if (!pt) { /* this can happen with rewrite rules - and we have no idea what to do then, so return */ goto finish; } @@ -691,62 +696,49 @@ PHP_METHOD(Phar, webPhar) zval params, retval; ZVAL_STRINGL(¶ms, entry, entry_len); + efree(entry); rewrite_fci.param_count = 1; rewrite_fci.params = ¶ms; rewrite_fci.retval = &retval; if (FAILURE == zend_call_function(&rewrite_fci, &rewrite_fcc)) { + zval_ptr_dtor_str(¶ms); if (!EG(exception)) { zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: failed to call rewrite callback"); } - goto cleanup_fail; + goto cleanup_skip_entry; } - if (Z_TYPE_P(rewrite_fci.retval) == IS_UNDEF || Z_TYPE(retval) == IS_UNDEF) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: rewrite callback must return a string or false"); - goto cleanup_fail; - } + zval_ptr_dtor_str(¶ms); switch (Z_TYPE(retval)) { case IS_STRING: - efree(entry); + /* TODO: avoid relocation??? */ entry = estrndup(Z_STRVAL_P(rewrite_fci.retval), Z_STRLEN_P(rewrite_fci.retval)); entry_len = Z_STRLEN_P(rewrite_fci.retval); + zval_ptr_dtor_str(&retval); break; case IS_TRUE: case IS_FALSE: - phar_do_403(entry, entry_len); - - if (free_pathinfo) { - efree(path_info); - } - efree(pt); - - zend_bailout(); + phar_do_403(); + goto cleanup_skip_entry; default: + zval_ptr_dtor(&retval); zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: rewrite callback must return a string or false"); - -cleanup_fail: - zval_ptr_dtor(¶ms); - if (free_pathinfo) { - efree(path_info); - } - efree(entry); - efree(pt); -#ifdef PHP_WIN32 - efree(fname); -#endif - RETURN_THROWS(); + goto cleanup_skip_entry; } } if (entry_len) { - phar_postprocess_ru_web(fname, fname_len, &entry, &entry_len, &ru, &ru_len); + phar_postprocess_ru_web(fname, fname_len, entry, &entry_len, &ru, &ru_len); } if (!entry_len || (entry_len == 1 && entry[0] == '/')) { efree(entry); + + bool is_entry_allocated = false; + /* direct request */ if (index_php_len) { entry = index_php; @@ -754,22 +746,17 @@ PHP_METHOD(Phar, webPhar) if (entry[0] != '/') { spprintf(&entry, 0, "/%s", index_php); ++entry_len; + is_entry_allocated = true; } } else { /* assume "index.php" is starting point */ - entry = estrndup("/index.php", sizeof("/index.php")); + entry = "/index.php"; entry_len = sizeof("/index.php")-1; } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || - (info = phar_get_entry_info(phar, entry, entry_len, NULL, 0)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); - - if (free_pathinfo) { - efree(path_info); - } - - zend_bailout(); + phar = phar_get_archive(fname, fname_len, NULL, 0, NULL); + if (!phar || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { + phar_do_404(phar, fname, fname_len, f404); } else { char *tmp = NULL, sa = '\0'; sapi_header_line ctr = {0}; @@ -796,21 +783,22 @@ PHP_METHOD(Phar, webPhar) *tmp = sa; } - if (free_pathinfo) { - efree(path_info); - } - sapi_header_op(SAPI_HEADER_REPLACE, &ctr); sapi_send_headers(); efree((void *) ctr.line); - zend_bailout(); } + + if (is_entry_allocated) { + efree(entry); + } + + goto cleanup_skip_entry; } - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) || - (info = phar_get_entry_info(phar, entry, entry_len, NULL, 0)) == NULL) { - phar_do_404(phar, fname, fname_len, f404, f404_len, entry, entry_len); - zend_bailout(); + phar = phar_get_archive(fname, fname_len, NULL, 0, NULL); + if (!phar || (info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) { + phar_do_404(phar, fname, fname_len, f404); + goto cleanup; } if (mimeoverride && zend_hash_num_elements(Z_ARRVAL_P(mimeoverride))) { @@ -828,15 +816,7 @@ PHP_METHOD(Phar, webPhar) code = Z_LVAL_P(val); } else { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed"); - if (free_pathinfo) { - efree(path_info); - } - efree(pt); - efree(entry); -#ifdef PHP_WIN32 - efree(fname); -#endif - RETURN_THROWS(); + goto cleanup; } break; case IS_STRING: @@ -845,15 +825,7 @@ PHP_METHOD(Phar, webPhar) break; default: zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown mime type specifier used (not a string or int), only Phar::PHP, Phar::PHPS and a mime type string are allowed"); - if (free_pathinfo) { - efree(path_info); - } - efree(pt); - efree(entry); -#ifdef PHP_WIN32 - efree(fname); -#endif - RETURN_THROWS(); + goto cleanup; } } } @@ -862,7 +834,22 @@ PHP_METHOD(Phar, webPhar) if (!mime_type) { code = phar_file_type(&PHAR_G(mime_types), entry, &mime_type); } - phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, pt, ru, ru_len); + status = phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, pt, ru, ru_len); + +cleanup: + efree(entry); +cleanup_skip_entry: + if (free_pathinfo) { + efree(path_info); + } + efree(pt); + efree(ru); + + if (status == PHAR_ACT_DO_EXIT) { + if (!EG(exception)) { + zend_throw_unwind_exit(); + } + } finish: ; #ifdef PHP_WIN32 @@ -897,7 +884,7 @@ PHP_METHOD(Phar, mungServer) phar_request_initialize(); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(mungvalues), data) { - + ZVAL_DEREF(data); if (Z_TYPE_P(data) != IS_STRING) { zend_throw_exception_ex(phar_ce_PharException, 0, "Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME"); RETURN_THROWS(); @@ -911,8 +898,10 @@ PHP_METHOD(Phar, mungServer) PHAR_G(phar_SERVER_mung_list) |= PHAR_MUNG_SCRIPT_NAME; } else if (zend_string_equals_literal(Z_STR_P(data), "SCRIPT_FILENAME")) { PHAR_G(phar_SERVER_mung_list) |= PHAR_MUNG_SCRIPT_FILENAME; + } else { + zend_throw_exception_ex(phar_ce_PharException, 0, "Invalid value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME"); + RETURN_THROWS(); } - // TODO Warning for invalid value? } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -926,9 +915,7 @@ PHP_METHOD(Phar, mungServer) */ PHP_METHOD(Phar, interceptFileFuncs) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); phar_intercept_functions(); } /* }}} */ @@ -939,11 +926,11 @@ PHP_METHOD(Phar, interceptFileFuncs) */ PHP_METHOD(Phar, createDefaultStub) { - char *index = NULL, *webindex = NULL, *error; + zend_string *index = NULL, *webindex = NULL; + char *error; zend_string *stub; - size_t index_len = 0, webindex_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p!p!", &index, &index_len, &webindex, &webindex_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!P!", &index, &webindex) == FAILURE) { RETURN_THROWS(); } @@ -961,17 +948,17 @@ PHP_METHOD(Phar, createDefaultStub) /* {{{ Reads the currently executed file (a phar) and registers its manifest */ PHP_METHOD(Phar, mapPhar) { - char *alias = NULL, *error; - size_t alias_len = 0; + zend_string *alias = NULL; + char *error; zend_long dataoffset = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!l", &alias, &alias_len, &dataoffset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!l", &alias, &dataoffset) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_executed_filename(alias, alias_len, &error) == SUCCESS); + RETVAL_BOOL(phar_open_executed_filename(alias, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -982,16 +969,17 @@ PHP_METHOD(Phar, mapPhar) /* {{{ Loads any phar archive with an alias */ PHP_METHOD(Phar, loadPhar) { - char *fname, *alias = NULL, *error; - size_t fname_len, alias_len = 0; + zend_string *fname; + zend_string *alias = NULL; + char *error; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s!", &fname, &fname_len, &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|S!", &fname, &alias) == FAILURE) { RETURN_THROWS(); } phar_request_initialize(); - RETVAL_BOOL(phar_open_from_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL, &error) == SUCCESS); + RETVAL_BOOL(phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), alias, REPORT_ERRORS, NULL, &error) == SUCCESS); if (error) { zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); @@ -1002,9 +990,7 @@ PHP_METHOD(Phar, loadPhar) /* {{{ Returns the api version */ PHP_METHOD(Phar, apiVersion) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_STRINGL(PHP_PHAR_API_VERSION, sizeof(PHP_PHAR_API_VERSION)-1); } /* }}}*/ @@ -1021,23 +1007,11 @@ PHP_METHOD(Phar, canCompress) phar_request_initialize(); switch (method) { case PHAR_ENT_COMPRESSED_GZ: - if (PHAR_G(has_zlib)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(PHAR_G(has_zlib)); case PHAR_ENT_COMPRESSED_BZ2: - if (PHAR_G(has_bz2)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(PHAR_G(has_bz2)); default: - if (PHAR_G(has_zlib) || PHAR_G(has_bz2)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(PHAR_G(has_zlib) || PHAR_G(has_bz2)); } } /* }}} */ @@ -1045,9 +1019,7 @@ PHP_METHOD(Phar, canCompress) /* {{{ Returns whether phar extension supports writing and creating phars */ PHP_METHOD(Phar, canWrite) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(!PHAR_G(readonly)); } /* }}} */ @@ -1059,15 +1031,13 @@ PHP_METHOD(Phar, isValidPharFilename) const char *ext_str; size_t fname_len; size_t ext_len; - int is_executable; - bool executable = 1; + bool is_executable = true; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|b", &fname, &fname_len, &executable) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|b", &fname, &fname_len, &is_executable) == FAILURE) { RETURN_THROWS(); } - is_executable = executable; - RETVAL_BOOL(phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, is_executable, 2, 1) == SUCCESS); + RETURN_BOOL(phar_detect_phar_fname_ext(fname, fname_len, &ext_str, &ext_len, is_executable, 2, true) == SUCCESS); } /* }}} */ @@ -1114,26 +1084,26 @@ static const spl_other_handler phar_spl_foreign_handler = { */ PHP_METHOD(Phar, __construct) { - char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname; - size_t fname_len, alias_len = 0; - size_t arch_len, entry_len; + zend_string *fname; + zend_string *alias = NULL; + char *error; bool is_data; zend_long flags = SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS; zend_long format = 0; phar_archive_object *phar_obj; phar_archive_data *phar_data; - zval *zobj = ZEND_THIS, arg1, arg2; + zval arg1, arg2; - phar_obj = (phar_archive_object*)((char*)Z_OBJ_P(zobj) - Z_OBJ_P(zobj)->handlers->offset); + phar_obj = PHAR_FETCH_INTERNAL(); - is_data = instanceof_function(Z_OBJCE_P(zobj), phar_ce_data); + is_data = instanceof_function(Z_OBJCE_P(ZEND_THIS), phar_ce_data); if (is_data) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls!l", &fname, &fname_len, &flags, &alias, &alias_len, &format) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|lS!l", &fname, &flags, &alias, &format) == FAILURE) { RETURN_THROWS(); } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls!", &fname, &fname_len, &flags, &alias, &alias_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|lS!", &fname, &flags, &alias) == FAILURE) { RETURN_THROWS(); } } @@ -1143,33 +1113,25 @@ PHP_METHOD(Phar, __construct) RETURN_THROWS(); } - save_fname = fname; - if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, !is_data, 2)) { + zend_string *entry = NULL; + /* phar_split_fname() will unixify the path */ + zend_string *arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &entry, !is_data, 2); + if (arch) { /* use arch (the basename for the archive) for fname instead of fname */ /* this allows support for RecursiveDirectoryIterator of subdirectories */ -#ifdef PHP_WIN32 - phar_unixify_path_separators(arch, arch_len); -#endif fname = arch; - fname_len = arch_len; -#ifdef PHP_WIN32 - } else { - arch = estrndup(fname, fname_len); - arch_len = fname_len; - fname = arch; - phar_unixify_path_separators(arch, arch_len); -#endif } - if (phar_open_or_create_filename(fname, fname_len, alias, alias_len, is_data, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + zend_result phar_status = phar_open_or_create_filename(fname, alias, is_data, REPORT_ERRORS, &phar_data, &error); - if (fname == arch && fname != save_fname) { - efree(arch); - fname = save_fname; - } + if (arch) { + zend_string_release_ex(arch, false); + } + + if (phar_status == FAILURE) { if (entry) { - efree(entry); + zend_string_release_ex(entry, false); } if (error) { @@ -1185,13 +1147,8 @@ PHP_METHOD(Phar, __construct) } if (is_data && phar_data->is_tar && phar_data->is_brandnew && format == PHAR_FORMAT_ZIP) { - phar_data->is_zip = 1; - phar_data->is_tar = 0; - } - - if (fname == arch) { - efree(arch); - fname = save_fname; + phar_data->is_zip = true; + phar_data->is_tar = false; } if ((is_data && !phar_data->is_data) || (!is_data && phar_data->is_data)) { @@ -1202,7 +1159,7 @@ PHP_METHOD(Phar, __construct) zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Phar class can only be used for executable tar and zip archives"); } - efree(entry); + zend_string_release_ex(entry, false); RETURN_THROWS(); } @@ -1215,20 +1172,29 @@ PHP_METHOD(Phar, __construct) phar_obj->archive = phar_data; phar_obj->spl.oth_handler = &phar_spl_foreign_handler; + zend_string *file_name_for_recursive_director_iterator_constructor; if (entry) { - fname_len = spprintf(&fname, 0, "phar://%s%s", phar_data->fname, entry); - efree(entry); + file_name_for_recursive_director_iterator_constructor = zend_string_concat3( + ZEND_STRL("phar://"), + ZSTR_VAL(phar_data->fname), ZSTR_LEN(phar_data->fname), + ZSTR_VAL(entry), ZSTR_LEN(entry) + ); + zend_string_release_ex(entry, false); } else { - fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname); + file_name_for_recursive_director_iterator_constructor = zend_string_concat2( + ZEND_STRL("phar://"), + ZSTR_VAL(phar_data->fname), ZSTR_LEN(phar_data->fname) + ); } - ZVAL_STRINGL(&arg1, fname, fname_len); + ZVAL_STR(&arg1, file_name_for_recursive_director_iterator_constructor); ZVAL_LONG(&arg2, flags); zend_call_known_instance_method_with_2_params(spl_ce_RecursiveDirectoryIterator->constructor, - Z_OBJ_P(zobj), NULL, &arg1, &arg2); + Z_OBJ_P(ZEND_THIS), NULL, &arg1, &arg2); - zval_ptr_dtor(&arg1); + /* Freeing arg1 */ + zend_string_release_ex(file_name_for_recursive_director_iterator_constructor, false); if (!phar_data->is_persistent) { phar_obj->archive->is_data = is_data; @@ -1238,16 +1204,13 @@ PHP_METHOD(Phar, __construct) } phar_obj->spl.info_class = phar_ce_entry; - efree(fname); } /* }}} */ /* {{{ Return array of supported signature types */ PHP_METHOD(Phar, getSupportedSignatures) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -1272,9 +1235,7 @@ PHP_METHOD(Phar, getSupportedSignatures) /* {{{ Return array of supported comparession algorithms */ PHP_METHOD(Phar, getSupportedCompression) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); phar_request_initialize(); @@ -1292,88 +1253,72 @@ PHP_METHOD(Phar, getSupportedCompression) /* {{{ Completely remove a phar archive from memory and disk */ PHP_METHOD(Phar, unlinkArchive) { - char *fname, *error, *arch, *entry; - size_t fname_len; - size_t arch_len, entry_len; + char *error; + zend_string *fname; phar_archive_data *phar; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &fname) == FAILURE) { RETURN_THROWS(); } - if (!fname_len) { + if (ZSTR_LEN(fname) == 0) { zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"\""); RETURN_THROWS(); } - if (FAILURE == phar_open_from_filename(fname, fname_len, NULL, 0, REPORT_ERRORS, &phar, &error)) { + if (FAILURE == phar_open_from_filename(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, REPORT_ERRORS, &phar, &error)) { if (error) { - zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\": %s", fname, error); + zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\": %s", ZSTR_VAL(fname), error); efree(error); } else { - zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\"", fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "Unknown phar archive \"%s\"", ZSTR_VAL(fname)); } RETURN_THROWS(); } - zend_string *zend_file_name = zend_get_executed_filename_ex(); - - if ( - zend_file_name - && zend_string_starts_with_literal_ci(zend_file_name, "phar://") - && SUCCESS == phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), &arch, &arch_len, &entry, &entry_len, 2, 0) - ) { - if (arch_len == fname_len && !memcmp(arch, fname, arch_len)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" cannot be unlinked from within itself", fname); - efree(arch); - efree(entry); - RETURN_THROWS(); + const zend_string *zend_file_name = zend_get_executed_filename_ex(); + if (zend_file_name && zend_string_starts_with_literal_ci(zend_file_name, "phar://")) { + zend_string *arch = phar_split_fname(ZSTR_VAL(zend_file_name), ZSTR_LEN(zend_file_name), NULL, 2, 0); + if (arch) { + if (zend_string_equals(arch, fname)) { + zend_string_release_ex(arch, false); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" cannot be unlinked from within itself", ZSTR_VAL(fname)); + RETURN_THROWS(); + } + zend_string_release_ex(arch, false); } - efree(arch); - efree(entry); } if (phar->is_persistent) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" is in phar.cache_list, cannot unlinkArchive()", fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" is in phar.cache_list, cannot unlinkArchive()", ZSTR_VAL(fname)); RETURN_THROWS(); } if (phar->refcount) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" has open file handles or objects. fclose() all file handles, and unset() all objects prior to calling unlinkArchive()", fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar archive \"%s\" has open file handles or objects. fclose() all file handles, and unset() all objects prior to calling unlinkArchive()", ZSTR_VAL(fname)); RETURN_THROWS(); } - fname = estrndup(phar->fname, phar->fname_len); + fname = zend_string_copy(phar->fname); /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; phar_archive_delref(phar); - unlink(fname); - efree(fname); + unlink(ZSTR_VAL(fname)); + zend_string_release(fname); RETURN_TRUE; } /* }}} */ -#define PHAR_ARCHIVE_OBJECT() \ - zval *zobj = ZEND_THIS; \ - phar_archive_object *phar_obj = (phar_archive_object*)((char*)Z_OBJ_P(zobj) - Z_OBJ_P(zobj)->handlers->offset); \ - if (!phar_obj->archive) { \ - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, \ - "Cannot call method on an uninitialized Phar object"); \ - RETURN_THROWS(); \ - } - /* {{{ if persistent, remove from the cache */ PHP_METHOD(Phar, __destruct) { - zval *zobj = ZEND_THIS; - phar_archive_object *phar_obj = (phar_archive_object*)((char*)Z_OBJ_P(zobj) - Z_OBJ_P(zobj)->handlers->offset); + phar_archive_object *phar_obj = PHAR_FETCH_INTERNAL(); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (phar_obj->archive && phar_obj->archive->is_persistent) { zend_hash_str_del(&PHAR_G(phar_persist_map), (const char *) phar_obj->archive, sizeof(phar_obj->archive)); @@ -1390,17 +1335,55 @@ struct _phar_t { int count; }; +static zend_always_inline void phar_call_method_with_unwrap(zend_object *obj, const char *name, zval *rv) +{ + zend_call_method_with_0_params(obj, obj->ce, NULL, name, rv); + if (Z_ISREF_P(rv)) { + zend_unwrap_reference(rv); + } +} + +/* This is the same as phar_get_or_create_entry_data(), but allows overriding metadata via SplFileInfo. */ +static phar_entry_data *phar_build_entry_data(zend_string *fname, char *path, size_t path_len, char **error, zval *file_info) +{ + uint32_t timestamp; + + /* Expects an instance of SplFileInfo if it is an object, which is verified in phar_build(). */ + if (Z_TYPE_P(file_info) == IS_OBJECT && Z_OBJCE_P(file_info)->type == ZEND_USER_CLASS) { + zval rv; + phar_call_method_with_unwrap(Z_OBJ_P(file_info), "getMTime", &rv); + + if (UNEXPECTED(Z_TYPE(rv) != IS_LONG)) { + /* Either it's a tentative type failure, an exception happened, or the function returned false to indicate failure. */ + *error = estrdup("getMTime() must return an int"); + return NULL; + } + + /* Sanity check bounds. See GH-14141. */ + if (ZEND_LONG_UINT_OVFL(Z_LVAL(rv))) { + *error = estrdup("timestamp is limited to 32-bit"); + return NULL; + } + + timestamp = Z_LVAL(rv); + } else { + timestamp = time(NULL); + } + + return phar_get_or_create_entry_data(fname, path, path_len, "w+b", 0, error, true, timestamp); +} + static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ { zval *value; - bool close_fp = 1; + bool close_fp = true; struct _phar_t *p_obj = (struct _phar_t*) puser; - size_t str_key_len, base_len = ZSTR_LEN(p_obj->base); + size_t str_key_len, base_len = p_obj->base ? ZSTR_LEN(p_obj->base) : 0; phar_entry_data *data; php_stream *fp; size_t fname_len; size_t contents_len; - char *fname, *error = NULL, *base = ZSTR_VAL(p_obj->base), *save = NULL, *temp = NULL; + char *fname = NULL, *error = NULL, *base = p_obj->base ? ZSTR_VAL(p_obj->base) : NULL, *save = NULL, *temp = NULL; zend_string *opened; char *str_key; zend_class_entry *ce = p_obj->c; @@ -1455,56 +1438,71 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } - close_fp = 0; + close_fp = false; opened = ZSTR_INIT_LITERAL("[stream]", 0); goto after_open_fp; case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(value), spl_ce_SplFileInfo)) { - char *test = NULL; - spl_filesystem_object *intern = (spl_filesystem_object*)((char*)Z_OBJ_P(value) - Z_OBJ_P(value)->handlers->offset); + spl_filesystem_object *intern = PHAR_FETCH_INTERNAL_EX(value); if (!base_len) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Iterator %s returns an SplFileInfo object, so base directory must be specified", ZSTR_VAL(ce->name)); return ZEND_HASH_APPLY_STOP; } - switch (intern->type) { - case SPL_FS_DIR: { - zend_string *test_str = spl_filesystem_object_get_path(intern); - fname_len = spprintf(&fname, 0, "%s%c%s", ZSTR_VAL(test_str), DEFAULT_SLASH, intern->u.dir.entry.d_name); - zend_string_release_ex(test_str, /* persistent */ false); - if (php_stream_stat_path(fname, &ssb) == 0 && S_ISDIR(ssb.sb.st_mode)) { - /* ignore directories */ - efree(fname); - return ZEND_HASH_APPLY_KEEP; - } + zend_string *tmp_dir_str = NULL; - test = expand_filepath(fname, NULL); - efree(fname); + /* Take into account that SplFileObject may be overridden. + * The purpose here is to grab the path name of the file to add. */ + if (Z_OBJCE_P(value)->type == ZEND_USER_CLASS) { + zval rv; + phar_call_method_with_unwrap(Z_OBJ_P(value), "getPathname", &rv); - if (test) { - fname = test; - fname_len = strlen(fname); - } else { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Could not resolve file path"); - return ZEND_HASH_APPLY_STOP; + if (UNEXPECTED(Z_TYPE(rv) != IS_STRING)) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "getPathname() must return a string"); + return ZEND_HASH_APPLY_STOP; + } + tmp_dir_str = Z_STR(rv); + } else { + /* Not a user class, so we can grab the data internally quickly. */ + switch (intern->type) { + case SPL_FS_DIR: { + zend_string *test_str = spl_filesystem_object_get_path(intern); + const char slash = DEFAULT_SLASH; + tmp_dir_str = zend_string_concat3( + ZSTR_VAL(test_str), ZSTR_LEN(test_str), + &slash, 1, + intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name) + ); + zend_string_release_ex(test_str, /* persistent */ false); + break; } + case SPL_FS_INFO: + case SPL_FS_FILE: + fname = expand_filepath(ZSTR_VAL(intern->file_name), NULL); + break; + } + } - save = fname; - goto phar_spl_fileinfo; + if (tmp_dir_str) { + if (php_stream_stat_path(ZSTR_VAL(tmp_dir_str), &ssb) == 0 && S_ISDIR(ssb.sb.st_mode)) { + /* ignore directories */ + zend_string_release_ex(tmp_dir_str, /* persistent */ false); + return ZEND_HASH_APPLY_KEEP; } - case SPL_FS_INFO: - case SPL_FS_FILE: - fname = expand_filepath(ZSTR_VAL(intern->file_name), NULL); - if (!fname) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Could not resolve file path"); - return ZEND_HASH_APPLY_STOP; - } - fname_len = strlen(fname); - save = fname; - goto phar_spl_fileinfo; + fname = expand_filepath(ZSTR_VAL(tmp_dir_str), NULL); + zend_string_release_ex(tmp_dir_str, /* persistent */ false); + } + + if (!fname) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Could not resolve file path"); + return ZEND_HASH_APPLY_STOP; } + + fname_len = strlen(fname); + save = fname; + goto phar_spl_fileinfo; } ZEND_FALLTHROUGH; default: @@ -1635,7 +1633,8 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_KEEP; } - if (!(data = phar_get_or_create_entry_data(phar_obj->archive->fname, phar_obj->archive->fname_len, str_key, str_key_len, "w+b", 0, &error, 1))) { + data = phar_build_entry_data(phar_obj->archive->fname, str_key, str_key_len, &error, value); + if (!data) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s cannot be created: %s", str_key, error); efree(error); @@ -1658,9 +1657,6 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } else { - if (error) { - efree(error); - } /* convert to PHAR_UFP */ if (data->internal_file->fp_type == PHAR_MOD) { php_stream_close(data->internal_file->fp); @@ -1671,8 +1667,6 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ data->internal_file->offset_abs = data->internal_file->offset = php_stream_tell(p_obj->fp); data->fp = NULL; php_stream_copy_to_stream_ex(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len); - data->internal_file->uncompressed_filesize = data->internal_file->compressed_filesize = - php_stream_tell(p_obj->fp) - data->internal_file->offset; if (php_stream_stat(fp, &ssb) != -1) { data->internal_file->flags = ssb.sb.st_mode & PHAR_ENT_PERM_MASK ; } else { @@ -1714,8 +1708,8 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ PHP_METHOD(Phar, buildFromDirectory) { char *error; - bool apply_reg = 0; - zval arg, arg2, iter, iteriter, regexiter; + bool apply_reg = false; + zval iter, iteriter, regexiter; struct _phar_t pass; zend_string *dir, *regex = NULL; @@ -1731,54 +1725,31 @@ PHP_METHOD(Phar, buildFromDirectory) RETURN_THROWS(); } - if (SUCCESS != object_init_ex(&iter, spl_ce_RecursiveDirectoryIterator)) { - zval_ptr_dtor(&iter); - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to instantiate directory iterator for %s", phar_obj->archive->fname); - RETURN_THROWS(); - } - - ZVAL_STR(&arg, dir); - ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS); - - zend_call_known_instance_method_with_2_params(spl_ce_RecursiveDirectoryIterator->constructor, - Z_OBJ(iter), NULL, &arg, &arg2); + zval args[2]; + ZVAL_STR(&args[0], dir); + ZVAL_LONG(&args[1], SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS); - if (EG(exception)) { - zval_ptr_dtor(&iter); + if (SUCCESS != object_init_with_constructor(&iter, spl_ce_RecursiveDirectoryIterator, 2, args, NULL)) { RETURN_THROWS(); } - if (SUCCESS != object_init_ex(&iteriter, spl_ce_RecursiveIteratorIterator)) { + if (SUCCESS != object_init_with_constructor(&iteriter, spl_ce_RecursiveIteratorIterator, 1, &iter, NULL)) { zval_ptr_dtor(&iter); - zval_ptr_dtor(&iteriter); - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to instantiate directory iterator for %s", phar_obj->archive->fname); - RETURN_THROWS(); - } - - zend_call_known_instance_method_with_1_params(spl_ce_RecursiveIteratorIterator->constructor, - Z_OBJ(iteriter), NULL, &iter); - - if (EG(exception)) { - zval_ptr_dtor(&iter); - zval_ptr_dtor(&iteriter); RETURN_THROWS(); } zval_ptr_dtor(&iter); if (regex && ZSTR_LEN(regex) > 0) { - apply_reg = 1; + apply_reg = true; - if (SUCCESS != object_init_ex(®exiter, spl_ce_RegexIterator)) { + ZVAL_COPY_VALUE(&args[0], &iteriter); + ZVAL_STR(&args[1], regex); + + if (SUCCESS != object_init_with_constructor(®exiter, spl_ce_RegexIterator, 2, args, NULL)) { zval_ptr_dtor(&iteriter); - zval_ptr_dtor(®exiter); - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to instantiate regex iterator for %s", phar_obj->archive->fname); RETURN_THROWS(); } - - ZVAL_STR(&arg2, regex); - zend_call_known_instance_method_with_2_params(spl_ce_RegexIterator->constructor, - Z_OBJ(regexiter), NULL, &iteriter, &arg2); } array_init(return_value); @@ -1790,7 +1761,11 @@ PHP_METHOD(Phar, buildFromDirectory) pass.ret = return_value; pass.fp = php_stream_fopen_tmpfile(); if (pass.fp == NULL) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" unable to create temporary file", phar_obj->archive->fname); + zval_ptr_dtor(&iteriter); + if (apply_reg) { + zval_ptr_dtor(®exiter); + } + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" unable to create temporary file", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1800,7 +1775,7 @@ PHP_METHOD(Phar, buildFromDirectory) zval_ptr_dtor(®exiter); } php_stream_close(pass.fp); - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1845,7 +1820,7 @@ PHP_METHOD(Phar, buildFromIterator) zend_string *base = ZSTR_EMPTY_ALLOC(); struct _phar_t pass; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|S!", &obj, zend_ce_traversable, &base) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|P!", &obj, zend_ce_traversable, &base) == FAILURE) { RETURN_THROWS(); } @@ -1858,7 +1833,7 @@ PHP_METHOD(Phar, buildFromIterator) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1871,7 +1846,7 @@ PHP_METHOD(Phar, buildFromIterator) pass.count = 0; pass.fp = php_stream_fopen_tmpfile(); if (pass.fp == NULL) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\": unable to create temporary file", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\": unable to create temporary file", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -1934,41 +1909,30 @@ static zend_result phar_copy_file_contents(phar_entry_info *entry, php_stream *f { char *error; zend_off_t offset; - phar_entry_info *link; - if (FAILURE == phar_open_entry_fp(entry, &error, 1)) { + ZEND_ASSERT(!entry->symlink); + + if (FAILURE == phar_open_entry_fp(entry, &error, true)) { if (error) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents: %s", entry->phar->fname, ZSTR_VAL(entry->filename), error); + "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents: %s", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename), error); efree(error); } else { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents", entry->phar->fname, ZSTR_VAL(entry->filename)); + "Cannot convert phar archive \"%s\", unable to open entry \"%s\" contents", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return FAILURE; } /* copy old contents in entirety */ - phar_seek_efp(entry, 0, SEEK_SET, 0, 1); + phar_seek_efp(entry, 0, SEEK_SET, 0, false); offset = php_stream_tell(fp); - link = phar_get_link_source(entry); - - if (!link) { - link = entry; - } - - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, false), fp, entry->uncompressed_filesize, NULL)) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Cannot convert phar archive \"%s\", unable to copy entry \"%s\" contents", entry->phar->fname, ZSTR_VAL(entry->filename)); + "Cannot convert phar archive \"%s\", unable to copy entry \"%s\" contents", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } - if (entry->fp_type == PHAR_MOD) { - /* save for potential restore on error */ - entry->cfp = entry->fp; - entry->fp = NULL; - } - /* set new location of file contents */ entry->fp_type = PHAR_FP; entry->offset = offset; @@ -1978,17 +1942,15 @@ static zend_result phar_copy_file_contents(phar_entry_info *entry, php_stream *f static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* {{{ */ { - const char *oldname = NULL; phar_archive_data *phar = *sphar; - char *oldpath = NULL; char *basename = NULL, *basepath = NULL; - char *newname = NULL, *newpath = NULL; + char *newname = NULL; zval ret, arg1; zend_class_entry *ce; char *error = NULL; const char *pcr_error; size_t ext_len = ext ? strlen(ext) : 0; - size_t new_len, oldname_len, phar_ext_len; + size_t phar_ext_len; phar_archive_data *pphar = NULL; php_stream_statbuf ssb; @@ -2060,34 +2022,38 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* } else if (phar_path_check(&ext, &ext_len, &pcr_error) > pcr_is_ok) { if (phar->is_data) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar converted from \"%s\" has invalid extension %s", phar->fname, ext); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar converted from \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); } else { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar converted from \"%s\" has invalid extension %s", phar->fname, ext); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar converted from \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); } return NULL; } - oldpath = estrndup(phar->fname, phar->fname_len); - if ((oldname = zend_memrchr(phar->fname, '/', phar->fname_len))) { - ++oldname; + zend_string *old_path = zend_string_copy(phar->fname); + + const char *old_name = zend_memrchr(ZSTR_VAL(phar->fname), '/', ZSTR_LEN(phar->fname)); + size_t old_name_len; + if (old_name) { + ++old_name; + old_name_len = strlen(old_name); } else { - oldname = phar->fname; + old_name = ZSTR_VAL(phar->fname); + old_name_len = ZSTR_LEN(phar->fname); } - oldname_len = strlen(oldname); /* Copy the old name to create base for the new name */ - basename = estrndup(oldname, oldname_len); + basename = estrndup(old_name, old_name_len); phar_ext_list_len = sizeof(phar_ext_list)/sizeof(phar_ext_list[0]); /* Remove possible PHAR extensions */ /* phar_ext_list must be in order of longest extension to shortest */ for (i=0; i < phar_ext_list_len; i++) { phar_ext_len = strlen(phar_ext_list[i]); - if (phar_ext_len && oldname_len > phar_ext_len) { + if (phar_ext_len && old_name_len > phar_ext_len) { /* Check if the basename strings ends with the extension */ - if (memcmp(phar_ext_list[i], basename + (oldname_len - phar_ext_len), phar_ext_len) == 0) { - ext_pos = basename + (oldname_len - phar_ext_len); + if (memcmp(phar_ext_list[i], basename + (old_name_len - phar_ext_len), phar_ext_len) == 0) { + ext_pos = basename + (old_name_len - phar_ext_len); ext_pos[0] = '\0'; break; } @@ -2111,21 +2077,21 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* spprintf(&newname, 0, "%s.%s", basename, ext); efree(basename); - basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); - new_len = spprintf(&newpath, 0, "%s%s", basepath, newname); - phar->fname_len = new_len; + basepath = estrndup(ZSTR_VAL(old_path), (ZSTR_LEN(old_path) - old_name_len)); + + zend_string *newpath = strpprintf(0, "%s%s", basepath, newname); + phar->ext = ZSTR_VAL(newpath) + ZSTR_LEN(newpath) - strlen(ext) - 1; phar->fname = newpath; - phar->ext = newpath + phar->fname_len - strlen(ext) - 1; efree(basepath); efree(newname); - if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, newpath, phar->fname_len))) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, new phar name is in phar.cache_list", phar->fname); + if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_find_ptr(&cached_phars, newpath))) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, new phar name is in phar.cache_list", ZSTR_VAL(phar->fname)); goto err_oldpath; } - if (NULL != (pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len))) { - if (pphar->fname_len == phar->fname_len && !memcmp(pphar->fname, phar->fname, phar->fname_len)) { + if (NULL != (pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), newpath))) { + if (zend_string_equals(pphar->fname, phar->fname)) { if (!zend_hash_num_elements(&phar->manifest)) { pphar->is_tar = phar->is_tar; pphar->is_zip = phar->is_zip; @@ -2140,22 +2106,22 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* phar = pphar; /* NOTE: this phar is now reused, so the refcount must be increased. */ phar->refcount++; - newpath = oldpath; + newpath = old_path; goto its_ok; } } - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, a phar with that name already exists", phar->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars, a phar with that name already exists", ZSTR_VAL(phar->fname)); goto err_oldpath; } its_ok: - if (SUCCESS == php_stream_stat_path(newpath, &ssb)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" exists and must be unlinked prior to conversion", newpath); + if (SUCCESS == php_stream_stat_path(ZSTR_VAL(newpath), &ssb)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" exists and must be unlinked prior to conversion", ZSTR_VAL(newpath)); goto err_reused_oldpath; } if (!phar->is_data) { - if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &ext_len, 1, 1, 1)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" has invalid extension %s", phar->fname, ext); + if (SUCCESS != phar_detect_phar_fname_ext(ZSTR_VAL(newpath), ZSTR_LEN(newpath), &(phar->ext), &ext_len, 1, 1, true)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "phar \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); goto err_reused_oldpath; } phar->ext_len = ext_len; @@ -2168,17 +2134,17 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* phar->alias = NULL; phar->alias_len = 0; } else { - phar->alias = pestrndup(newpath, strlen(newpath), phar->is_persistent); - phar->alias_len = strlen(newpath); + phar->alias = pestrndup(ZSTR_VAL(newpath), ZSTR_LEN(newpath), phar->is_persistent); + phar->alias_len = ZSTR_LEN(newpath); phar->is_temporary_alias = 1; - zend_hash_str_update_ptr(&(PHAR_G(phar_alias_map)), newpath, phar->fname_len, phar); + zend_hash_update_ptr(&(PHAR_G(phar_alias_map)), newpath, phar); } } } else { - if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &ext_len, 0, 1, 1)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar \"%s\" has invalid extension %s", phar->fname, ext); + if (SUCCESS != phar_detect_phar_fname_ext(ZSTR_VAL(newpath), ZSTR_LEN(newpath), &(phar->ext), &ext_len, 0, 1, true)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "data phar \"%s\" has invalid extension %s", ZSTR_VAL(phar->fname), ext); goto err_reused_oldpath; } phar->ext_len = ext_len; @@ -2190,22 +2156,22 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* } } - if ((!pphar || phar == pphar) && NULL == zend_hash_str_update_ptr(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len, phar)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars", phar->fname); + if ((!pphar || phar == pphar) && NULL == zend_hash_update_ptr(&(PHAR_G(phar_fname_map)), newpath, phar)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to add newly converted phar \"%s\" to the list of phars", ZSTR_VAL(phar->fname)); goto err_oldpath; } - phar_flush_ex(phar, NULL, 1, &error); + phar_flush_ex(phar, NULL, true, &error); if (error) { - zend_hash_str_del(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), newpath); *sphar = NULL; zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s", error); efree(error); goto err_oldpath; } - efree(oldpath); + zend_string_release(old_path); if (phar->is_data) { ce = phar_ce_data; @@ -2213,17 +2179,11 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* ce = phar_ce_archive; } - ZVAL_NULL(&ret); - if (SUCCESS != object_init_ex(&ret, ce)) { - zval_ptr_dtor(&ret); - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Unable to instantiate phar object when converting archive \"%s\"", phar->fname); + ZVAL_STR(&arg1, phar->fname); + zend_result result = object_init_with_constructor(&ret, ce, 1, &arg1, NULL); + if (SUCCESS != result) { return NULL; } - - ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len); - - zend_call_known_instance_method_with_1_params(ce->constructor, Z_OBJ(ret), NULL, &arg1); - zval_ptr_dtor(&arg1); return Z_OBJ(ret); err_reused_oldpath: @@ -2233,7 +2193,7 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /* } /* fallthrough */ err_oldpath: - efree(oldpath); + zend_string_release(old_path); return NULL; } /* }}} */ @@ -2246,7 +2206,14 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; + + php_stream *tmp_fp = php_stream_fopen_tmpfile(); + if (tmp_fp == NULL) { + zend_throw_exception_ex(phar_ce_PharException, 0, "unable to create temporary file"); + return NULL; + } phar = (phar_archive_data *) ecalloc(1, sizeof(phar_archive_data)); /* set whole-archive compression and type from parameter */ @@ -2255,13 +2222,13 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert switch (convert) { case PHAR_FORMAT_TAR: - phar->is_tar = 1; + phar->is_tar = true; break; case PHAR_FORMAT_ZIP: - phar->is_zip = 1; + phar->is_zip = true; break; default: - phar->is_data = 0; + phar->is_data = false; break; } @@ -2272,13 +2239,8 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert zend_hash_init(&phar->virtual_dirs, sizeof(char *), zend_get_hash_value, NULL, 0); - phar->fp = php_stream_fopen_tmpfile(); - if (phar->fp == NULL) { - zend_throw_exception_ex(phar_ce_PharException, 0, "unable to create temporary file"); - return NULL; - } + phar->fp = tmp_fp; phar->fname = source->fname; - phar->fname_len = source->fname_len; phar->is_temporary_alias = source->is_temporary_alias; phar->alias = source->alias; @@ -2289,8 +2251,8 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert newentry = *entry; - if (newentry.link) { - newentry.link = estrdup(newentry.link); + if (newentry.symlink) { + zend_string_addref(newentry.symlink); goto no_copy; } @@ -2300,6 +2262,7 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert } if (FAILURE == phar_copy_file_contents(&newentry, phar->fp)) { + phar_metadata_tracker_free(&phar->metadata_tracker, phar->is_persistent); zend_hash_destroy(&(phar->manifest)); php_stream_close(phar->fp); efree(phar); @@ -2307,6 +2270,10 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert return NULL; } no_copy: + /* Reset file pointers, they have to be reset here such that if a copy happens the original + * source fp can be accessed. */ + newentry.fp = NULL; + newentry.cfp = NULL; newentry.filename = zend_string_copy(newentry.filename); phar_metadata_tracker_clone(&newentry.metadata_tracker); @@ -2333,13 +2300,18 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert return ret; } else { if(phar != NULL) { + phar_metadata_tracker_free(&phar->metadata_tracker, phar->is_persistent); zend_hash_destroy(&(phar->manifest)); zend_hash_destroy(&(phar->mounted_dirs)); zend_hash_destroy(&(phar->virtual_dirs)); if (phar->fp) { php_stream_close(phar->fp); } - efree(phar->fname); + if (phar->fname != source->fname) { + /* Depending on when phar_rename_archive() errors, the new filename + * may have already been assigned or it may still be the old one. */ + zend_string_release(phar->fname); + } efree(phar); } return NULL; @@ -2354,12 +2326,11 @@ static zend_object *phar_convert_to_other(phar_archive_data *source, int convert PHP_METHOD(Phar, convertToExecutable) { char *ext = NULL; - int is_data; size_t ext_len = 0; uint32_t flags; zend_object *ret; zend_long format, method; - bool format_is_null = 1, method_is_null = 1; + bool format_is_null = true, method_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!l!s!", &format, &format_is_null, &method, &method_is_null, &ext, &ext_len) == FAILURE) { RETURN_THROWS(); @@ -2445,8 +2416,8 @@ PHP_METHOD(Phar, convertToExecutable) } } - is_data = phar_obj->archive->is_data; - phar_obj->archive->is_data = 0; + bool is_data = phar_obj->archive->is_data; + phar_obj->archive->is_data = false; ret = phar_convert_to_other(phar_obj->archive, format, ext, flags); phar_obj->archive->is_data = is_data; @@ -2465,12 +2436,11 @@ PHP_METHOD(Phar, convertToExecutable) PHP_METHOD(Phar, convertToData) { char *ext = NULL; - int is_data; size_t ext_len = 0; uint32_t flags; zend_object *ret; zend_long format, method; - bool format_is_null = 1, method_is_null = 1; + bool format_is_null = true, method_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!l!s!", &format, &format_is_null, &method, &method_is_null, &ext, &ext_len) == FAILURE) { RETURN_THROWS(); @@ -2555,8 +2525,8 @@ PHP_METHOD(Phar, convertToData) } } - is_data = phar_obj->archive->is_data; - phar_obj->archive->is_data = 1; + bool is_data = phar_obj->archive->is_data; + phar_obj->archive->is_data = true; ret = phar_convert_to_other(phar_obj->archive, (int)format, ext, flags); phar_obj->archive->is_data = is_data; @@ -2573,9 +2543,7 @@ PHP_METHOD(Phar, convertToData) */ PHP_METHOD(Phar, isCompressed) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -2596,9 +2564,7 @@ PHP_METHOD(Phar, isWritable) { php_stream_statbuf ssb; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -2606,12 +2572,9 @@ PHP_METHOD(Phar, isWritable) RETURN_FALSE; } - if (SUCCESS != php_stream_stat_path(phar_obj->archive->fname, &ssb)) { - if (phar_obj->archive->is_brandnew) { - /* assume it works if the file doesn't exist yet */ - RETURN_TRUE; - } - RETURN_FALSE; + if (SUCCESS != php_stream_stat_path(ZSTR_VAL(phar_obj->archive->fname), &ssb)) { + /* assume it works if the file doesn't exist yet */ + RETURN_BOOL(phar_obj->archive->is_brandnew); } RETURN_BOOL((ssb.sb.st_mode & (S_IWOTH | S_IWGRP | S_IWUSR)) != 0); @@ -2638,7 +2601,7 @@ PHP_METHOD(Phar, delete) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { @@ -2669,13 +2632,11 @@ PHP_METHOD(Phar, delete) /* {{{ Returns the alias for the Phar or NULL. */ PHP_METHOD(Phar, getAlias) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); - if (phar_obj->archive->alias && phar_obj->archive->alias != phar_obj->archive->fname) { + if (phar_obj->archive->alias) { RETURN_STRINGL(phar_obj->archive->alias, phar_obj->archive->alias_len); } } @@ -2684,13 +2645,11 @@ PHP_METHOD(Phar, getAlias) /* {{{ Returns the real path to the phar archive on disk */ PHP_METHOD(Phar, getPath) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); - RETURN_STRINGL(phar_obj->archive->fname, phar_obj->archive->fname_len); + RETURN_STR_COPY(phar_obj->archive->fname); } /* }}} */ @@ -2703,7 +2662,7 @@ PHP_METHOD(Phar, setAlias) char *error, *oldalias; phar_archive_data *fd_ptr; size_t oldalias_len; - int old_temp, readd = 0; + bool old_temp, readd = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &new_alias) == FAILURE) { RETURN_THROWS(); @@ -2719,7 +2678,8 @@ PHP_METHOD(Phar, setAlias) /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; if (phar_obj->archive->is_data) { if (phar_obj->archive->is_tar) { @@ -2736,37 +2696,33 @@ PHP_METHOD(Phar, setAlias) RETURN_TRUE; } if (NULL != (fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), new_alias))) { - spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", ZSTR_VAL(new_alias), fd_ptr->fname); - if (SUCCESS == phar_free_alias(fd_ptr, ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { - efree(error); - goto valid_alias; + if (SUCCESS != phar_free_alias(fd_ptr)) { + zend_throw_exception_ex(phar_ce_PharException, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", ZSTR_VAL(new_alias), ZSTR_VAL(fd_ptr->fname)); + RETURN_THROWS(); } - zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error); - efree(error); - RETURN_THROWS(); - } - if (!phar_validate_alias(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { + } else if (!phar_validate_alias(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias))) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "Invalid alias \"%s\" specified for phar \"%s\"", ZSTR_VAL(new_alias), phar_obj->archive->fname); + "Invalid alias \"%s\" specified for phar \"%s\"", ZSTR_VAL(new_alias), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } -valid_alias: if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (phar_obj->archive->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias, phar_obj->archive->alias_len))) { zend_hash_str_del(&(PHAR_G(phar_alias_map)), phar_obj->archive->alias, phar_obj->archive->alias_len); - readd = 1; + readd = true; } + ZEND_ASSERT(!phar_obj->archive->is_persistent); + oldalias = phar_obj->archive->alias; oldalias_len = phar_obj->archive->alias_len; old_temp = phar_obj->archive->is_temporary_alias; phar_obj->archive->alias_len = ZSTR_LEN(new_alias); if (phar_obj->archive->alias_len) { - phar_obj->archive->alias = pestrndup(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias), phar_obj->archive->is_persistent); + phar_obj->archive->alias = estrndup(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias)); } else { phar_obj->archive->alias = NULL; } @@ -2775,6 +2731,7 @@ PHP_METHOD(Phar, setAlias) phar_flush(phar_obj->archive, &error); if (error) { + efree(phar_obj->archive->alias); phar_obj->archive->alias = oldalias; phar_obj->archive->alias_len = oldalias_len; phar_obj->archive->is_temporary_alias = old_temp; @@ -2799,9 +2756,7 @@ PHP_METHOD(Phar, setAlias) /* {{{ Return version info of Phar archive */ PHP_METHOD(Phar, getVersion) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -2812,9 +2767,7 @@ PHP_METHOD(Phar, getVersion) /* {{{ Do not flush a writeable phar (save its contents) until explicitly requested */ PHP_METHOD(Phar, startBuffering) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -2825,9 +2778,7 @@ PHP_METHOD(Phar, startBuffering) /* {{{ Returns whether write operations are flushing to disk immediately. */ PHP_METHOD(Phar, isBuffering) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -2840,9 +2791,7 @@ PHP_METHOD(Phar, stopBuffering) { char *error; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -2902,7 +2851,7 @@ PHP_METHOD(Phar, setStub) if ((php_stream_from_zval_no_verify(stream, zstub)) != NULL) { if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -2914,7 +2863,7 @@ PHP_METHOD(Phar, setStub) } if (stub_file_content == NULL) { - zend_throw_exception_ex(phar_ce_PharException, 0, "unable to read resource to copy stub to new phar \"%s\"", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "unable to read resource to copy stub to new phar \"%s\"", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -2932,7 +2881,7 @@ PHP_METHOD(Phar, setStub) } } else if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &stub) == SUCCESS) { if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } phar_flush_ex(phar_obj->archive, stub, /* is_default_stub */ false, &error); @@ -2964,12 +2913,11 @@ PHP_METHOD(Phar, setStub) */ PHP_METHOD(Phar, setDefaultStub) { - char *index = NULL, *webindex = NULL, *error = NULL; + zend_string *index = NULL, *webindex = NULL; zend_string *stub = NULL; - size_t index_len = 0, webindex_len = 0; - int created_stub = 0; + bool created_stub = false; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!", &index, &index_len, &webindex, &webindex_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!P!", &index, &webindex) == FAILURE) { RETURN_THROWS(); } @@ -2997,6 +2945,7 @@ PHP_METHOD(Phar, setDefaultStub) RETURN_THROWS(); } + char *error = NULL; if (!phar_obj->archive->is_tar && !phar_obj->archive->is_zip) { stub = phar_create_default_stub(index, webindex, &error); @@ -3013,7 +2962,7 @@ PHP_METHOD(Phar, setDefaultStub) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } phar_flush_ex(phar_obj->archive, stub, /* is_default_stub */ true, &error); @@ -3064,7 +3013,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm) case PHAR_SIG_OPENSSL_SHA256: case PHAR_SIG_OPENSSL_SHA512: if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } phar_obj->archive->sig_flags = (uint32_t)algo; @@ -3088,9 +3037,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm) /* {{{ Returns a hash signature, or FALSE if the archive is unsigned. */ PHP_METHOD(Phar, getSignature) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -3135,9 +3082,7 @@ PHP_METHOD(Phar, getSignature) /* {{{ Return whether phar was modified */ PHP_METHOD(Phar, getModified) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -3164,7 +3109,7 @@ static int phar_set_compression(zval *zv, void *argument) /* {{{ */ static int phar_test_compression(zval *zv, void *argument) /* {{{ */ { - phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv); + const phar_entry_info *entry = Z_PTR_P(zv); if (entry->is_deleted) { return ZEND_HASH_APPLY_KEEP; @@ -3173,12 +3118,14 @@ static int phar_test_compression(zval *zv, void *argument) /* {{{ */ if (!PHAR_G(has_bz2)) { if (entry->flags & PHAR_ENT_COMPRESSED_BZ2) { *(int *) argument = 0; + return ZEND_HASH_APPLY_STOP; } } if (!PHAR_G(has_zlib)) { if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { *(int *) argument = 0; + return ZEND_HASH_APPLY_STOP; } } @@ -3376,7 +3323,7 @@ PHP_METHOD(Phar, compressFiles) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } pharobj_set_compression(&phar_obj->archive->manifest, flags); @@ -3395,10 +3342,7 @@ PHP_METHOD(Phar, decompressFiles) { char *error; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -3418,7 +3362,7 @@ PHP_METHOD(Phar, decompressFiles) RETURN_TRUE; } else { if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } pharobj_set_compression(&phar_obj->archive->manifest, PHAR_ENT_COMPRESSED_NONE); @@ -3441,7 +3385,7 @@ PHP_METHOD(Phar, copy) { char *error; const char *pcr_error; - phar_entry_info *oldentry, newentry = {0}, *temp; + phar_entry_info newentry = {0}; zend_string *new_file = NULL; zend_string *old_file = NULL; @@ -3460,26 +3404,28 @@ PHP_METHOD(Phar, copy) if (zend_string_starts_with_literal(old_file, ".phar")) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (zend_string_starts_with_literal(new_file, ".phar")) { /* can't copy a meta file */ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", cannot copy to Phar meta-file in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } - if (NULL == (oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file)) || oldentry->is_deleted) { + phar_entry_info *oldentry = zend_hash_find_ptr(&phar_obj->archive->manifest, old_file); + if (!oldentry || oldentry->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } - if (NULL != (temp = zend_hash_find_ptr(&phar_obj->archive->manifest, new_file)) && !temp->is_deleted) { + const phar_entry_info *temp = zend_hash_find_ptr(&phar_obj->archive->manifest, new_file); + if (temp && !temp->is_deleted) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), phar_obj->archive->fname); + "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", ZSTR_VAL(old_file), ZSTR_VAL(new_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -3487,13 +3433,13 @@ PHP_METHOD(Phar, copy) char *tmp_new_file = ZSTR_VAL(new_file); if (phar_path_check(&tmp_new_file, &tmp_len, &pcr_error) > pcr_is_ok) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, - "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", ZSTR_VAL(new_file), pcr_error, ZSTR_VAL(old_file), phar_obj->archive->fname); + "file \"%s\" contains invalid characters %s, cannot be copied from \"%s\" in phar %s", ZSTR_VAL(new_file), pcr_error, ZSTR_VAL(old_file), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (phar_obj->archive->is_persistent) { if (FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } /* re-populate with copied-on-write entry */ @@ -3534,7 +3480,6 @@ PHP_METHOD(Phar, copy) PHP_METHOD(Phar, offsetExists) { zend_string *file_name; - phar_entry_info *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); @@ -3542,19 +3487,15 @@ PHP_METHOD(Phar, offsetExists) PHAR_ARCHIVE_OBJECT(); - if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { - if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { - if (entry->is_deleted) { - /* entry is deleted, but has not been flushed to disk yet */ - RETURN_FALSE; - } - } - - if (zend_string_starts_with_literal(file_name, ".phar")) { - /* none of these are real files, so they don't exist */ + const phar_entry_info *entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); + if (entry != NULL) { + if (entry->is_deleted) { + /* entry is deleted, but has not been flushed to disk yet */ RETURN_FALSE; } - RETURN_TRUE; + + /* none of these are real files, so they don't exist */ + RETURN_BOOL(!zend_string_starts_with_literal(file_name, ".phar")); } else { /* If the info class is not based on PharFileInfo, directories are not directly instantiable */ if (UNEXPECTED(!instanceof_function(phar_obj->spl.info_class, phar_ce_entry))) { @@ -3569,7 +3510,6 @@ PHP_METHOD(Phar, offsetExists) PHP_METHOD(Phar, offsetGet) { char *error; - phar_entry_info *entry; zend_string *file_name = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { @@ -3579,16 +3519,22 @@ PHP_METHOD(Phar, offsetGet) PHAR_ARCHIVE_OBJECT(); /* security is 0 here so that we can get a better error message than "entry doesn't exist" */ - if (!(entry = phar_get_entry_info_dir(phar_obj->archive, ZSTR_VAL(file_name), ZSTR_LEN(file_name), 1, &error, 0))) { + phar_entry_info *entry = phar_get_entry_info_dir(phar_obj->archive, ZSTR_VAL(file_name), ZSTR_LEN(file_name), 1, &error, false); + if (!entry) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist%s%s", ZSTR_VAL(file_name), error?", ":"", error?error:""); } else { + if (entry->is_temp_dir) { + zend_string_efree(entry->filename); + efree(entry); + } + if (zend_string_equals_literal(file_name, ".phar/stub.php")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get stub \".phar/stub.php\" directly in phar \"%s\", use getStub", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get stub \".phar/stub.php\" directly in phar \"%s\", use getStub", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get alias \".phar/alias.txt\" directly in phar \"%s\", use getAlias", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot get alias \".phar/alias.txt\" directly in phar \"%s\", use getAlias", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -3597,12 +3543,7 @@ PHP_METHOD(Phar, offsetGet) RETURN_THROWS(); } - if (entry->is_temp_dir) { - zend_string_efree(entry->filename); - efree(entry); - } - - zend_string *sfname = strpprintf(0, "phar://%s/%s", phar_obj->archive->fname, ZSTR_VAL(file_name)); + zend_string *sfname = strpprintf(0, "phar://%s/%s", ZSTR_VAL(phar_obj->archive->fname), ZSTR_VAL(file_name)); zval zfname; ZVAL_NEW_STR(&zfname, sfname); @@ -3620,7 +3561,6 @@ PHP_METHOD(Phar, offsetGet) static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, const zend_string *content, zval *zresource) { char *error; - phar_entry_data *data; php_stream *contents_file = NULL; php_stream_statbuf ssb; #ifdef PHP_WIN32 @@ -3652,7 +3592,8 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con } #endif - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, filename, filename_len, "w+b", 0, &error, 1))) { + phar_entry_data *data = phar_get_or_create_entry_data((*pphar)->fname, filename, filename_len, "w+b", 0, &error, true, time(NULL)); + if (!data) { if (error) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s does not exist and cannot be created: %s", filename, error); efree(error); @@ -3661,10 +3602,6 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con } goto finish; } else { - if (error) { - efree(error); - } - if (!data->internal_file->is_dir) { size_t contents_len = 0; if (content) { @@ -3672,11 +3609,13 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con size_t written_len = php_stream_write(data->fp, ZSTR_VAL(content), ZSTR_LEN(content)); if (written_len != contents_len) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s could not be written to", filename); + phar_entry_delref(data); goto finish; } } else { if (!(php_stream_from_zval_no_verify(contents_file, zresource))) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Entry %s could not be written to", filename); + phar_entry_delref(data); goto finish; } php_stream_copy_to_stream_ex(contents_file, data->fp, PHP_STREAM_COPY_ALL, &contents_len); @@ -3722,9 +3661,14 @@ finish: ; static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name) { char *error; - phar_entry_data *data; - if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, ZSTR_VAL(dir_name), ZSTR_LEN(dir_name), "w+b", 2, &error, 1))) { + phar_entry_data *data = phar_get_or_create_entry_data( + (*pphar)->fname, + ZSTR_VAL(dir_name), ZSTR_LEN(dir_name), + "w+b", 2, &error, true, + time(NULL) + ); + if (!data) { if (error) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Directory %s does not exist and cannot be created: %s", ZSTR_VAL(dir_name), error); efree(error); @@ -3734,10 +3678,6 @@ static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name) return; } else { - if (error) { - efree(error); - } - /* check for copy on write */ if (data->phar != *pphar) { *pphar = data->phar; @@ -3773,12 +3713,12 @@ PHP_METHOD(Phar, offsetSet) } if (zend_string_equals_literal(file_name, ".phar/stub.php")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set stub \".phar/stub.php\" directly in phar \"%s\", use setStub", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (zend_string_equals_literal(file_name, ".phar/alias.txt")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set alias \".phar/alias.txt\" directly in phar \"%s\", use setAlias", phar_obj->archive->fname); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot set alias \".phar/alias.txt\" directly in phar \"%s\", use setAlias", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -3796,7 +3736,6 @@ PHP_METHOD(Phar, offsetUnset) { char *error; zend_string *file_name; - phar_entry_info *entry; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file_name) == FAILURE) { RETURN_THROWS(); @@ -3810,7 +3749,8 @@ PHP_METHOD(Phar, offsetUnset) } if (zend_hash_exists(&phar_obj->archive->manifest, file_name)) { - if (NULL != (entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name))) { + phar_entry_info *entry = zend_hash_find_ptr(&phar_obj->archive->manifest, file_name); + if (entry) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ return; @@ -3818,7 +3758,7 @@ PHP_METHOD(Phar, offsetUnset) if (phar_obj->archive->is_persistent) { if (FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } /* re-populate entry after copy on write */ @@ -3849,9 +3789,16 @@ PHP_METHOD(Phar, addEmptyDir) PHAR_ARCHIVE_OBJECT(); - if (zend_string_starts_with_literal(dir_name, ".phar")) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); - RETURN_THROWS(); + if ( + zend_string_starts_with_literal(dir_name, ".phar") + || zend_string_starts_with_literal(dir_name, "/.phar") + ) { + size_t prefix_len = (ZSTR_VAL(dir_name)[0] == '/') + sizeof(".phar") - 1; + char next_char = ZSTR_VAL(dir_name)[prefix_len]; + if (next_char == '/' || next_char == '\\' || next_char == '\0') { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory"); + RETURN_THROWS(); + } } phar_mkdir(&phar_obj->archive, dir_name); @@ -3863,7 +3810,6 @@ PHP_METHOD(Phar, addFile) { zend_string *file_name; zend_string *local_name = NULL; - php_stream *resource; zval zresource; if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|S!", &file_name, &local_name) == FAILURE) { @@ -3877,7 +3823,8 @@ PHP_METHOD(Phar, addFile) RETURN_THROWS(); } - if (!(resource = php_stream_open_wrapper(ZSTR_VAL(file_name), "rb", 0, NULL))) { + php_stream *resource = php_stream_open_wrapper(ZSTR_VAL(file_name), "rb", 0, NULL); + if (!resource) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, "phar error: unable to open file \"%s\" to add to phar archive", ZSTR_VAL(file_name)); RETURN_THROWS(); } @@ -3915,34 +3862,33 @@ PHP_METHOD(Phar, getStub) zend_string *buf; php_stream *fp; php_stream_filter *filter = NULL; - phar_entry_info *stub; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); if (phar_obj->archive->is_tar || phar_obj->archive->is_zip) { + const phar_entry_info *stub = zend_hash_str_find_ptr(&(phar_obj->archive->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1); - if (NULL != (stub = zend_hash_str_find_ptr(&(phar_obj->archive->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1))) { + if (stub) { if (phar_obj->archive->fp && !phar_obj->archive->is_brandnew && !(stub->flags & PHAR_ENT_COMPRESSION_MASK)) { fp = phar_obj->archive->fp; } else { - if (!(fp = php_stream_open_wrapper(phar_obj->archive->fname, "rb", 0, NULL))) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to open phar \"%s\"", phar_obj->archive->fname); + fp = php_stream_open_wrapper(ZSTR_VAL(phar_obj->archive->fname), "rb", 0, NULL); + if (!fp) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to open phar \"%s\"", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } if (stub->flags & PHAR_ENT_COMPRESSION_MASK) { - char *filter_name; + const char *filter_name = phar_decompress_filter(stub, false); - if ((filter_name = phar_decompress_filter(stub, 0)) != NULL) { + if (filter_name != NULL) { filter = php_stream_filter_create(filter_name, NULL, php_stream_is_persistent(fp)); } else { filter = NULL; } if (!filter) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to read stub of phar \"%s\" (cannot create %s filter)", phar_obj->archive->fname, phar_decompress_filter(stub, 1)); + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "phar error: unable to read stub of phar \"%s\" (cannot create %s filter)", ZSTR_VAL(phar_obj->archive->fname), phar_decompress_filter(stub, true)); RETURN_THROWS(); } php_stream_filter_append(&fp->readfilters, filter); @@ -3967,7 +3913,7 @@ PHP_METHOD(Phar, getStub) if (phar_obj->archive->fp && !phar_obj->archive->is_brandnew) { fp = phar_obj->archive->fp; } else { - fp = php_stream_open_wrapper(phar_obj->archive->fname, "rb", 0, NULL); + fp = php_stream_open_wrapper(ZSTR_VAL(phar_obj->archive->fname), "rb", 0, NULL); } if (!fp) { @@ -4008,9 +3954,7 @@ PHP_METHOD(Phar, getStub) /* {{{ Returns TRUE if the phar has global metadata, FALSE otherwise. */ PHP_METHOD(Phar, hasMetadata) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -4039,7 +3983,7 @@ PHP_METHOD(Phar, getMetadata) /* }}} */ /* {{{ Modifies the phar metadata or throws */ -static zend_result serialize_metadata_or_throw(phar_metadata_tracker *tracker, int persistent, zval *metadata) +static zend_result serialize_metadata_or_throw(phar_metadata_tracker *tracker, bool persistent, zval *metadata) { php_serialize_data_t metadata_hash; smart_str main_metadata_str = {0}; @@ -4087,7 +4031,7 @@ PHP_METHOD(Phar, setMetadata) } if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } @@ -4111,9 +4055,7 @@ PHP_METHOD(Phar, delMetadata) { char *error; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ARCHIVE_OBJECT(); @@ -4140,7 +4082,7 @@ PHP_METHOD(Phar, delMetadata) } /* }}} */ -static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, char *dest, size_t dest_len, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, const zend_string *path, char **error) /* {{{ */ { php_stream_statbuf ssb; size_t len; @@ -4168,7 +4110,7 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha if (virtual_file_ex(&new_state, ZSTR_VAL(entry->filename), NULL, CWD_EXPAND) != 0 || new_state.cwd_length <= 1) { if (EINVAL == errno && ZSTR_LEN(entry->filename) > 50) { - spprintf(error, 4096, "Cannot extract \"%.50s...\" to \"%s...\", extracted filename is too long for filesystem", ZSTR_VAL(entry->filename), dest); + spprintf(error, 4096, "Cannot extract \"%.50s...\" to \"%s...\", extracted filename is too long for filesystem", ZSTR_VAL(entry->filename), ZSTR_VAL(path)); } else { spprintf(error, 4096, "Cannot extract \"%s\", internal error", ZSTR_VAL(entry->filename)); } @@ -4190,7 +4132,7 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha } #endif - len = spprintf(&fullpath, 0, "%s/%s", dest, filename); + len = spprintf(&fullpath, 0, "%s/%s", ZSTR_VAL(path), filename); if (len >= MAXPATHLEN) { /* truncate for error message */ @@ -4231,9 +4173,9 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha slash = zend_memrchr(filename, '/', filename_len); if (slash) { - fullpath[dest_len + (slash - filename) + 1] = '\0'; + fullpath[ZSTR_LEN(path) + (slash - filename) + 1] = '\0'; } else { - fullpath[dest_len] = '\0'; + fullpath[ZSTR_LEN(path)] = '\0'; } if (FAILURE == php_stream_stat_path(fullpath, &ssb)) { @@ -4255,9 +4197,9 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha } if (slash) { - fullpath[dest_len + (slash - filename) + 1] = '/'; + fullpath[ZSTR_LEN(path) + (slash - filename) + 1] = '/'; } else { - fullpath[dest_len] = '/'; + fullpath[ZSTR_LEN(path)] = '/'; } filename = NULL; @@ -4276,10 +4218,11 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha return FAILURE; } - if ((phar_get_fp_type(entry) == PHAR_FP && (entry->flags & PHAR_ENT_COMPRESSION_MASK)) || !phar_get_efp(entry, 0)) { - if (FAILURE == phar_open_entry_fp(entry, error, 1)) { - if (error) { - spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer: %s", ZSTR_VAL(entry->filename), fullpath, *error); + if ((phar_get_fp_type(entry) == PHAR_FP && (entry->flags & PHAR_ENT_COMPRESSION_MASK)) || !phar_get_efp(entry, false)) { + char *open_entry_error = NULL; + if (FAILURE == phar_open_entry_fp(entry, &open_entry_error, true)) { + if (open_entry_error) { + spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer: %s", ZSTR_VAL(entry->filename), fullpath, open_entry_error); } else { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to open internal file pointer", ZSTR_VAL(entry->filename), fullpath); } @@ -4289,14 +4232,14 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha } } - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", unable to seek internal file pointer", ZSTR_VAL(entry->filename), fullpath); efree(fullpath); php_stream_close(fp); return FAILURE; } - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, 0), fp, entry->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, false), fp, entry->uncompressed_filesize, NULL)) { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", copying contents failed", ZSTR_VAL(entry->filename), fullpath); efree(fullpath); php_stream_close(fp); @@ -4317,28 +4260,28 @@ static zend_result phar_extract_file(bool overwrite, phar_entry_info *entry, cha } /* }}} */ -static int extract_helper(phar_archive_data *archive, zend_string *search, char *pathto, size_t pathto_len, bool overwrite, char **error) { /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 3, 5) static int extract_helper(const phar_archive_data *archive, zend_string *search, const zend_string *path_to, bool overwrite, char **error) { /* {{{ */ int extracted = 0; phar_entry_info *entry; if (!search) { /* nothing to match -- extract all files */ ZEND_HASH_MAP_FOREACH_PTR(&archive->manifest, entry) { - if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, error)) return -1; + if (FAILURE == phar_extract_file(overwrite, entry, path_to, error)) return -1; extracted++; } ZEND_HASH_FOREACH_END(); } else if (ZSTR_LEN(search) > 0 && '/' == ZSTR_VAL(search)[ZSTR_LEN(search) - 1]) { /* ends in "/" -- extract all entries having that prefix */ ZEND_HASH_MAP_FOREACH_PTR(&archive->manifest, entry) { if (!zend_string_starts_with(entry->filename, search)) continue; - if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, error)) return -1; + if (FAILURE == phar_extract_file(overwrite, entry, path_to, error)) return -1; extracted++; } ZEND_HASH_FOREACH_END(); } else { /* otherwise, looking for an exact match */ entry = zend_hash_find_ptr(&archive->manifest, search); if (NULL == entry) return 0; - if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, error)) return -1; + if (FAILURE == phar_extract_file(overwrite, entry, path_to, error)) return -1; return 1; } @@ -4351,9 +4294,8 @@ PHP_METHOD(Phar, extractTo) { php_stream *fp; php_stream_statbuf ssb; - char *pathto; + zend_string *path_to; zend_string *filename = NULL; - size_t pathto_len; int ret; zval *zval_file; HashTable *files_ht = NULL; @@ -4361,7 +4303,7 @@ PHP_METHOD(Phar, extractTo) char *error = NULL; ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_PATH(pathto, pathto_len) + Z_PARAM_PATH_STR(path_to) Z_PARAM_OPTIONAL Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(files_ht, filename) Z_PARAM_BOOL(overwrite) @@ -4369,40 +4311,37 @@ PHP_METHOD(Phar, extractTo) PHAR_ARCHIVE_OBJECT(); - fp = php_stream_open_wrapper(phar_obj->archive->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK, NULL); + fp = php_stream_open_wrapper(ZSTR_VAL(phar_obj->archive->fname), "rb", IGNORE_URL|STREAM_MUST_SEEK, NULL); if (!fp) { zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, - "Invalid argument, %s cannot be found", phar_obj->archive->fname); + "Invalid argument, %s cannot be found", ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } php_stream_close(fp); - if (pathto_len < 1) { + if (ZSTR_LEN(path_to) == 0) { zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid argument, extraction path must be non-zero length"); RETURN_THROWS(); } - if (pathto_len >= MAXPATHLEN) { - char *tmp = estrndup(pathto, 50); - /* truncate for error message */ - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Cannot extract to \"%s...\", destination directory is too long for filesystem", tmp); - efree(tmp); + if (ZSTR_LEN(path_to) >= MAXPATHLEN) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Cannot extract to \"%.50s...\", destination directory is too long for filesystem", ZSTR_VAL(path_to)); RETURN_THROWS(); } - if (php_stream_stat_path(pathto, &ssb) < 0) { - ret = php_stream_mkdir(pathto, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL); + if (php_stream_stat_path(ZSTR_VAL(path_to), &ssb) < 0) { + ret = php_stream_mkdir(ZSTR_VAL(path_to), 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL); if (!ret) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, - "Unable to create path \"%s\" for extraction", pathto); + "Unable to create path \"%s\" for extraction", ZSTR_VAL(path_to)); RETURN_THROWS(); } } else if (!(ssb.sb.st_mode & S_IFDIR)) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, - "Unable to use path \"%s\" for extraction, it is a file, must be a directory", pathto); + "Unable to use path \"%s\" for extraction, it is a file, must be a directory", ZSTR_VAL(path_to)); RETURN_THROWS(); } @@ -4418,31 +4357,31 @@ PHP_METHOD(Phar, extractTo) "Invalid argument, array of filenames to extract contains non-string value"); RETURN_THROWS(); } - switch (extract_helper(phar_obj->archive, Z_STR_P(zval_file), pathto, pathto_len, overwrite, &error)) { + switch (extract_helper(phar_obj->archive, Z_STR_P(zval_file), path_to, overwrite, &error)) { case -1: zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s", - phar_obj->archive->fname, error); + ZSTR_VAL(phar_obj->archive->fname), error); efree(error); RETURN_THROWS(); case 0: zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: attempted to extract non-existent file or directory \"%s\" from phar \"%s\"", - ZSTR_VAL(Z_STR_P(zval_file)), phar_obj->archive->fname); + ZSTR_VAL(Z_STR_P(zval_file)), ZSTR_VAL(phar_obj->archive->fname)); RETURN_THROWS(); } } ZEND_HASH_FOREACH_END(); RETURN_TRUE; } - ret = extract_helper(phar_obj->archive, filename, pathto, pathto_len, overwrite, &error); + ret = extract_helper(phar_obj->archive, filename, path_to, overwrite, &error); if (-1 == ret) { zend_throw_exception_ex(phar_ce_PharException, 0, "Extraction from phar \"%s\" failed: %s", - phar_obj->archive->fname, error); + ZSTR_VAL(phar_obj->archive->fname), error); efree(error); } else if (0 == ret && NULL != filename) { zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: attempted to extract non-existent file or directory \"%s\" from phar \"%s\"", - ZSTR_VAL(filename), phar_obj->archive->fname); + ZSTR_VAL(filename), ZSTR_VAL(phar_obj->archive->fname)); } else { RETURN_TRUE; } @@ -4453,33 +4392,39 @@ PHP_METHOD(Phar, extractTo) /* {{{ Construct a Phar entry object */ PHP_METHOD(PharFileInfo, __construct) { - char *fname, *arch, *entry, *error; + char *fname, *error; size_t fname_len; - size_t arch_len, entry_len; phar_entry_object *entry_obj; - phar_entry_info *entry_info; phar_archive_data *phar_data; - zval *zobj = ZEND_THIS, arg1; + zval arg1; if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &fname, &fname_len) == FAILURE) { RETURN_THROWS(); } - entry_obj = (phar_entry_object*)((char*)Z_OBJ_P(zobj) - Z_OBJ_P(zobj)->handlers->offset); + entry_obj = PHAR_FETCH_INTERNAL(); if (entry_obj->entry) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot call constructor twice"); RETURN_THROWS(); } - if (fname_len < 7 || memcmp(fname, "phar://", 7) || phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0) == FAILURE) { + if (fname_len < 7 || memcmp(fname, "phar://", 7)) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, "'%s' is not a valid phar archive URL (must have at least phar://filename.phar)", fname); RETURN_THROWS(); } - if (phar_open_from_filename(arch, arch_len, NULL, 0, REPORT_ERRORS, &phar_data, &error) == FAILURE) { - efree(arch); + zend_string *entry = NULL; + zend_string *arch = phar_split_fname(fname, fname_len, &entry, 2, 0); + if (!arch) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, + "'%s' is not a valid phar archive URL (must have at least phar://filename.phar)", fname); + RETURN_THROWS(); + } + + if (phar_open_from_filename(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, REPORT_ERRORS, &phar_data, &error) == FAILURE) { + zend_string_release_ex(arch, false); efree(entry); if (error) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, @@ -4492,76 +4437,79 @@ PHP_METHOD(PharFileInfo, __construct) RETURN_THROWS(); } - if ((entry_info = phar_get_entry_info_dir(phar_data, entry, entry_len, 1, &error, 1)) == NULL) { + phar_entry_info *entry_info = phar_get_entry_info_dir(phar_data, ZSTR_VAL(entry), ZSTR_LEN(entry), 1, &error, true); + if (UNEXPECTED(!entry_info)) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, - "Cannot access phar file entry '%s' in archive '%s'%s%s", entry, arch, error ? ", " : "", error ? error : ""); - efree(arch); - efree(entry); + "Cannot access phar file entry '%s' in archive '%s'%s%s", + ZSTR_VAL(entry), ZSTR_VAL(arch), error ? ", " : "", error ? error : ""); + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); RETURN_THROWS(); } - efree(arch); - efree(entry); + zend_string_release_ex(entry, false); + zend_string_release_ex(arch, false); entry_obj->entry = entry_info; if (!entry_info->is_persistent && !entry_info->is_temp_dir) { - ++entry_info->fp_refcount; + ++entry_info->fileinfo_lock_count; + /* The phar data must exist to keep the alias locked. */ + ZEND_ASSERT(!phar_data->is_persistent); + ++phar_data->refcount; } ZVAL_STRINGL(&arg1, fname, fname_len); zend_call_known_instance_method_with_1_params(spl_ce_SplFileInfo->constructor, - Z_OBJ_P(zobj), NULL, &arg1); + Z_OBJ_P(ZEND_THIS), NULL, &arg1); zval_ptr_dtor(&arg1); } /* }}} */ -#define PHAR_ENTRY_OBJECT() \ - zval *zobj = ZEND_THIS; \ - phar_entry_object *entry_obj = (phar_entry_object*)((char*)Z_OBJ_P(zobj) - Z_OBJ_P(zobj)->handlers->offset); \ +#define PHAR_ENTRY_OBJECT_EX(throw) \ + phar_entry_object *entry_obj = PHAR_FETCH_INTERNAL(); \ if (!entry_obj->entry) { \ - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, \ - "Cannot call method on an uninitialized PharFileInfo object"); \ - RETURN_THROWS(); \ + if (throw) { \ + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, \ + "Cannot call method on an uninitialized PharFileInfo object"); \ + } \ + return; \ } +#define PHAR_ENTRY_OBJECT() PHAR_ENTRY_OBJECT_EX(true) + /* {{{ clean up directory-based entry objects */ PHP_METHOD(PharFileInfo, __destruct) { - zval *zobj = ZEND_THIS; - phar_entry_object *entry_obj = (phar_entry_object*)((char*)Z_OBJ_P(zobj) - Z_OBJ_P(zobj)->handlers->offset); + ZEND_PARSE_PARAMETERS_NONE(); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + PHAR_ENTRY_OBJECT_EX(false); - if (!entry_obj->entry) { - return; - } + phar_entry_info *entry = entry_obj->entry; - if (entry_obj->entry->is_temp_dir) { - if (entry_obj->entry->filename) { - zend_string_efree(entry_obj->entry->filename); - entry_obj->entry->filename = NULL; + if (entry->is_temp_dir) { + if (entry->filename) { + zend_string_release_ex(entry->filename, false); + entry->filename = NULL; } - efree(entry_obj->entry); - } else if (!entry_obj->entry->is_persistent) { - --entry_obj->entry->fp_refcount; - /* It is necessarily still in the manifest, which will ultimately free this. */ + efree(entry); + entry_obj->entry = NULL; + } else if (!entry->is_persistent) { + --entry->fileinfo_lock_count; + /* The entry itself still lives in the manifest, + * which will either be freed here if the file info was the last reference; or freed later. */ + entry_obj->entry = NULL; + phar_archive_delref(entry->phar); } - - entry_obj->entry = NULL; } /* }}} */ /* {{{ Returns the compressed size */ PHP_METHOD(PharFileInfo, getCompressedSize) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); @@ -4573,7 +4521,7 @@ PHP_METHOD(PharFileInfo, getCompressedSize) PHP_METHOD(PharFileInfo, isCompressed) { zend_long method; - bool method_is_null = 1; + bool method_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &method, &method_is_null) == FAILURE) { RETURN_THROWS(); @@ -4602,9 +4550,7 @@ PHP_METHOD(PharFileInfo, isCompressed) /* {{{ Returns CRC32 code or throws an exception if not CRC checked */ PHP_METHOD(PharFileInfo, getCRC32) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); @@ -4626,9 +4572,7 @@ PHP_METHOD(PharFileInfo, getCRC32) /* {{{ Returns whether file entry is CRC checked */ PHP_METHOD(PharFileInfo, isCRCChecked) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); @@ -4639,9 +4583,7 @@ PHP_METHOD(PharFileInfo, isCRCChecked) /* {{{ Returns the Phar file entry flags */ PHP_METHOD(PharFileInfo, getPharFlags) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); @@ -4668,7 +4610,7 @@ PHP_METHOD(PharFileInfo, chmod) } if (PHAR_G(readonly) && !entry_obj->entry->phar->is_data) { - zend_throw_exception_ex(phar_ce_PharException, 0, "Cannot modify permissions for file \"%s\" in phar \"%s\", write operations are prohibited", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "Cannot modify permissions for file \"%s\" in phar \"%s\", write operations are prohibited", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname)); RETURN_THROWS(); } @@ -4676,7 +4618,7 @@ PHP_METHOD(PharFileInfo, chmod) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4714,9 +4656,7 @@ PHP_METHOD(PharFileInfo, chmod) /* {{{ Returns the metadata of the entry */ PHP_METHOD(PharFileInfo, hasMetadata) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); @@ -4771,7 +4711,7 @@ PHP_METHOD(PharFileInfo, setMetadata) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4799,9 +4739,7 @@ PHP_METHOD(PharFileInfo, delMetadata) { char *error; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); @@ -4821,7 +4759,7 @@ PHP_METHOD(PharFileInfo, delMetadata) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4852,19 +4790,16 @@ PHP_METHOD(PharFileInfo, delMetadata) PHP_METHOD(PharFileInfo, getContent) { char *error; - php_stream *fp; phar_entry_info *link; zend_string *str; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); if (entry_obj->entry->is_dir) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\" is a directory", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname); + "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\" is a directory", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname)); RETURN_THROWS(); } @@ -4874,20 +4809,21 @@ PHP_METHOD(PharFileInfo, getContent) link = entry_obj->entry; } - if (SUCCESS != phar_open_entry_fp(link, &error, 0)) { + if (SUCCESS != phar_open_entry_fp(link, &error, false)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\": %s", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "phar error: Cannot retrieve contents, \"%s\" in phar \"%s\": %s", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } - if (!(fp = phar_get_efp(link, 0))) { + php_stream *fp = phar_get_efp(link, false); + if (!fp) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot retrieve contents of \"%s\" in phar \"%s\"", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname); + "phar error: Cannot retrieve contents of \"%s\" in phar \"%s\"", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname)); RETURN_THROWS(); } - phar_seek_efp(link, 0, SEEK_SET, 0, 0); + phar_seek_efp(link, 0, SEEK_SET, 0, false); str = php_stream_copy_to_mem(fp, link->uncompressed_filesize, 0); if (str) { RETURN_STR(str); @@ -4937,7 +4873,7 @@ PHP_METHOD(PharFileInfo, compress) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -4957,9 +4893,9 @@ PHP_METHOD(PharFileInfo, compress) } /* decompress this file indirectly */ - if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, 1)) { + if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, true)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot decompress bzip2-compressed file \"%s\" in phar \"%s\" in order to compress with gzip: %s", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "phar error: Cannot decompress bzip2-compressed file \"%s\" in phar \"%s\" in order to compress with gzip: %s", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } @@ -4988,9 +4924,9 @@ PHP_METHOD(PharFileInfo, compress) } /* decompress this file indirectly */ - if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, 1)) { + if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, true)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "phar error: Cannot decompress gzip-compressed file \"%s\" in phar \"%s\" in order to compress with bzip2: %s", ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "phar error: Cannot decompress gzip-compressed file \"%s\" in phar \"%s\" in order to compress with bzip2: %s", ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } @@ -5030,9 +4966,7 @@ PHP_METHOD(PharFileInfo, decompress) char *error; char *compression_type; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHAR_ENTRY_OBJECT(); @@ -5074,7 +5008,7 @@ PHP_METHOD(PharFileInfo, decompress) phar_archive_data *phar = entry_obj->entry->phar; if (FAILURE == phar_copy_on_write(&phar)) { - zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar->fname); + zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", ZSTR_VAL(phar->fname)); RETURN_THROWS(); } /* re-populate after copy-on-write */ @@ -5093,9 +5027,9 @@ PHP_METHOD(PharFileInfo, decompress) RETURN_THROWS(); } /* decompress this file indirectly */ - if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, 1)) { + if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, true)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, - "Phar error: Cannot decompress %s-compressed file \"%s\" in phar \"%s\": %s", compression_type, ZSTR_VAL(entry_obj->entry->filename), entry_obj->entry->phar->fname, error); + "Phar error: Cannot decompress %s-compressed file \"%s\" in phar \"%s\": %s", compression_type, ZSTR_VAL(entry_obj->entry->filename), ZSTR_VAL(entry_obj->entry->phar->fname), error); efree(error); RETURN_THROWS(); } diff --git a/ext/phar/phar_object_arginfo.h b/ext/phar/phar_object_arginfo.h index e6c5ac75e9e7..bca9f0112eaa 100644 --- a/ext/phar/phar_object_arginfo.h +++ b/ext/phar/phar_object_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit phar_object.stub.php instead. * Stub hash: 031dc8f07d2d9bac4a5f82f4ac2c5b3da5995405 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar___construct, 0, 0, 1) @@ -624,99 +624,99 @@ static zend_class_entry *register_class_Phar(zend_class_entry *class_entry_Recur zval const_BZ2_value; ZVAL_LONG(&const_BZ2_value, PHAR_ENT_COMPRESSED_BZ2); - zend_string *const_BZ2_name = zend_string_init_interned("BZ2", sizeof("BZ2") - 1, 1); + zend_string *const_BZ2_name = zend_string_init_interned("BZ2", sizeof("BZ2") - 1, true); zend_declare_typed_class_constant(class_entry, const_BZ2_name, &const_BZ2_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BZ2_name); + zend_string_release_ex(const_BZ2_name, true); zval const_GZ_value; ZVAL_LONG(&const_GZ_value, PHAR_ENT_COMPRESSED_GZ); - zend_string *const_GZ_name = zend_string_init_interned("GZ", sizeof("GZ") - 1, 1); + zend_string *const_GZ_name = zend_string_init_interned("GZ", sizeof("GZ") - 1, true); zend_declare_typed_class_constant(class_entry, const_GZ_name, &const_GZ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GZ_name); + zend_string_release_ex(const_GZ_name, true); zval const_NONE_value; ZVAL_LONG(&const_NONE_value, PHAR_ENT_COMPRESSED_NONE); - zend_string *const_NONE_name = zend_string_init_interned("NONE", sizeof("NONE") - 1, 1); + zend_string *const_NONE_name = zend_string_init_interned("NONE", sizeof("NONE") - 1, true); zend_declare_typed_class_constant(class_entry, const_NONE_name, &const_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NONE_name); + zend_string_release_ex(const_NONE_name, true); zval const_PHAR_value; ZVAL_LONG(&const_PHAR_value, PHAR_FORMAT_PHAR); - zend_string *const_PHAR_name = zend_string_init_interned("PHAR", sizeof("PHAR") - 1, 1); + zend_string *const_PHAR_name = zend_string_init_interned("PHAR", sizeof("PHAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_PHAR_name, &const_PHAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PHAR_name); + zend_string_release_ex(const_PHAR_name, true); zval const_TAR_value; ZVAL_LONG(&const_TAR_value, PHAR_FORMAT_TAR); - zend_string *const_TAR_name = zend_string_init_interned("TAR", sizeof("TAR") - 1, 1); + zend_string *const_TAR_name = zend_string_init_interned("TAR", sizeof("TAR") - 1, true); zend_declare_typed_class_constant(class_entry, const_TAR_name, &const_TAR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TAR_name); + zend_string_release_ex(const_TAR_name, true); zval const_ZIP_value; ZVAL_LONG(&const_ZIP_value, PHAR_FORMAT_ZIP); - zend_string *const_ZIP_name = zend_string_init_interned("ZIP", sizeof("ZIP") - 1, 1); + zend_string *const_ZIP_name = zend_string_init_interned("ZIP", sizeof("ZIP") - 1, true); zend_declare_typed_class_constant(class_entry, const_ZIP_name, &const_ZIP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ZIP_name); + zend_string_release_ex(const_ZIP_name, true); zval const_COMPRESSED_value; ZVAL_LONG(&const_COMPRESSED_value, PHAR_ENT_COMPRESSION_MASK); - zend_string *const_COMPRESSED_name = zend_string_init_interned("COMPRESSED", sizeof("COMPRESSED") - 1, 1); + zend_string *const_COMPRESSED_name = zend_string_init_interned("COMPRESSED", sizeof("COMPRESSED") - 1, true); zend_declare_typed_class_constant(class_entry, const_COMPRESSED_name, &const_COMPRESSED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_COMPRESSED_name); + zend_string_release_ex(const_COMPRESSED_name, true); zval const_PHP_value; ZVAL_LONG(&const_PHP_value, PHAR_MIME_PHP); - zend_string *const_PHP_name = zend_string_init_interned("PHP", sizeof("PHP") - 1, 1); + zend_string *const_PHP_name = zend_string_init_interned("PHP", sizeof("PHP") - 1, true); zend_declare_typed_class_constant(class_entry, const_PHP_name, &const_PHP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PHP_name); + zend_string_release_ex(const_PHP_name, true); zval const_PHPS_value; ZVAL_LONG(&const_PHPS_value, PHAR_MIME_PHPS); - zend_string *const_PHPS_name = zend_string_init_interned("PHPS", sizeof("PHPS") - 1, 1); + zend_string *const_PHPS_name = zend_string_init_interned("PHPS", sizeof("PHPS") - 1, true); zend_declare_typed_class_constant(class_entry, const_PHPS_name, &const_PHPS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PHPS_name); + zend_string_release_ex(const_PHPS_name, true); zval const_MD5_value; ZVAL_LONG(&const_MD5_value, PHAR_SIG_MD5); - zend_string *const_MD5_name = zend_string_init_interned("MD5", sizeof("MD5") - 1, 1); + zend_string *const_MD5_name = zend_string_init_interned("MD5", sizeof("MD5") - 1, true); zend_declare_typed_class_constant(class_entry, const_MD5_name, &const_MD5_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MD5_name); + zend_string_release_ex(const_MD5_name, true); zval const_OPENSSL_value; ZVAL_LONG(&const_OPENSSL_value, PHAR_SIG_OPENSSL); - zend_string *const_OPENSSL_name = zend_string_init_interned("OPENSSL", sizeof("OPENSSL") - 1, 1); + zend_string *const_OPENSSL_name = zend_string_init_interned("OPENSSL", sizeof("OPENSSL") - 1, true); zend_declare_typed_class_constant(class_entry, const_OPENSSL_name, &const_OPENSSL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OPENSSL_name); + zend_string_release_ex(const_OPENSSL_name, true); zval const_OPENSSL_SHA256_value; ZVAL_LONG(&const_OPENSSL_SHA256_value, PHAR_SIG_OPENSSL_SHA256); - zend_string *const_OPENSSL_SHA256_name = zend_string_init_interned("OPENSSL_SHA256", sizeof("OPENSSL_SHA256") - 1, 1); + zend_string *const_OPENSSL_SHA256_name = zend_string_init_interned("OPENSSL_SHA256", sizeof("OPENSSL_SHA256") - 1, true); zend_declare_typed_class_constant(class_entry, const_OPENSSL_SHA256_name, &const_OPENSSL_SHA256_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OPENSSL_SHA256_name); + zend_string_release_ex(const_OPENSSL_SHA256_name, true); zval const_OPENSSL_SHA512_value; ZVAL_LONG(&const_OPENSSL_SHA512_value, PHAR_SIG_OPENSSL_SHA512); - zend_string *const_OPENSSL_SHA512_name = zend_string_init_interned("OPENSSL_SHA512", sizeof("OPENSSL_SHA512") - 1, 1); + zend_string *const_OPENSSL_SHA512_name = zend_string_init_interned("OPENSSL_SHA512", sizeof("OPENSSL_SHA512") - 1, true); zend_declare_typed_class_constant(class_entry, const_OPENSSL_SHA512_name, &const_OPENSSL_SHA512_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OPENSSL_SHA512_name); + zend_string_release_ex(const_OPENSSL_SHA512_name, true); zval const_SHA1_value; ZVAL_LONG(&const_SHA1_value, PHAR_SIG_SHA1); - zend_string *const_SHA1_name = zend_string_init_interned("SHA1", sizeof("SHA1") - 1, 1); + zend_string *const_SHA1_name = zend_string_init_interned("SHA1", sizeof("SHA1") - 1, true); zend_declare_typed_class_constant(class_entry, const_SHA1_name, &const_SHA1_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SHA1_name); + zend_string_release_ex(const_SHA1_name, true); zval const_SHA256_value; ZVAL_LONG(&const_SHA256_value, PHAR_SIG_SHA256); - zend_string *const_SHA256_name = zend_string_init_interned("SHA256", sizeof("SHA256") - 1, 1); + zend_string *const_SHA256_name = zend_string_init_interned("SHA256", sizeof("SHA256") - 1, true); zend_declare_typed_class_constant(class_entry, const_SHA256_name, &const_SHA256_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SHA256_name); + zend_string_release_ex(const_SHA256_name, true); zval const_SHA512_value; ZVAL_LONG(&const_SHA512_value, PHAR_SIG_SHA512); - zend_string *const_SHA512_name = zend_string_init_interned("SHA512", sizeof("SHA512") - 1, 1); + zend_string *const_SHA512_name = zend_string_init_interned("SHA512", sizeof("SHA512") - 1, true); zend_declare_typed_class_constant(class_entry, const_SHA512_name, &const_SHA512_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SHA512_name); + zend_string_release_ex(const_SHA512_name, true); return class_entry; } diff --git a/ext/phar/phar_path_check.re b/ext/phar/phar_path_check.re index 77aa0b1953d3..39b18bfc0b44 100644 --- a/ext/phar/phar_path_check.re +++ b/ext/phar/phar_path_check.re @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -18,7 +16,7 @@ #include "phar_internal.h" -phar_path_check_result phar_path_check(char **s, size_t *len, const char **error) +ZEND_ATTRIBUTE_NONNULL phar_path_check_result phar_path_check(char **s, size_t *len, const char **error) { const unsigned char *p = (const unsigned char*)*s; const unsigned char *m; diff --git a/ext/phar/pharzip.h b/ext/phar/pharzip.h index 5c814747b692..5a827f7a7294 100644 --- a/ext/phar/pharzip.h +++ b/ext/phar/pharzip.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | diff --git a/ext/phar/php_phar.h b/ext/phar/php_phar.h index 18e3485fc3a9..f086f9cfff2d 100644 --- a/ext/phar/php_phar.h +++ b/ext/phar/php_phar.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | diff --git a/ext/phar/shortarc.php b/ext/phar/shortarc.php index 2d0d37d0dcc5..c85e08439e76 100644 --- a/ext/phar/shortarc.php +++ b/ext/phar/shortarc.php @@ -74,7 +74,7 @@ $a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt); if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) { header('HTTP/1.0 404 Not Found'); - echo "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; + echo "<html>\n <head>\n <title>File Not Found\n \n \n

404 - File Not Found

\n \n"; exit; } $b = pathinfo($a); @@ -114,15 +114,15 @@ static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); - $L = unpack('V', $a = (binary)fread($fp, 4)); - $m = (binary)''; + $L = unpack('V', $a = (string)fread($fp, 4)); + $m = ''; do { $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } - $last = (binary)fread($fp, $read); + $last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -268,7 +268,7 @@ static function extractFile($path, $entry, $fp) $entry[0] . ")"); } - if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) { + if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { die("Invalid internal .phar file (checksum error)"); } diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 38c0c3e6f801..772f9c2769a5 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar:// stream wrapper support | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -60,8 +58,7 @@ const php_stream_wrapper php_stream_phar_wrapper = { php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options) /* {{{ */ { php_url *resource; - char *arch = NULL, *entry = NULL, *error; - size_t arch_len, entry_len; + char *error; if (strncasecmp(filename, "phar://", 7)) { return NULL; @@ -72,11 +69,14 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const } return NULL; } - if (phar_split_fname(filename, strlen(filename), &arch, &arch_len, &entry, &entry_len, 2, (mode[0] == 'w' ? 2 : 0)) == FAILURE) { + + zend_string *entry = NULL; + const char *arch_error = NULL; + zend_string *arch = phar_split_fname_ex(filename, strlen(filename), &entry, 2, (mode[0] == 'w' ? 2 : 0), &arch_error); + if (!arch) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { - if (arch && !entry) { - php_stream_wrapper_log_error(wrapper, options, "phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)", filename, arch); - arch = NULL; + if (arch_error && !entry) { + php_stream_wrapper_log_error(wrapper, options, "phar error: no directory in \"%s\", must have at least phar://%s/ for root directory (always use full path to a new phar)", filename, arch_error); } else { php_stream_wrapper_log_error(wrapper, options, "phar error: invalid url or non-existent phar \"%s\"", filename); } @@ -85,10 +85,8 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const } resource = ecalloc(1, sizeof(php_url)); resource->scheme = ZSTR_INIT_LITERAL("phar", 0); - resource->host = zend_string_init(arch, arch_len, 0); - efree(arch); - resource->path = zend_string_init(entry, entry_len, 0); - efree(entry); + resource->host = arch; + resource->path = entry; #ifdef MBO_0 if (resource) { @@ -116,7 +114,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const php_url_free(resource); return NULL; } - if (phar_open_or_create_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, 0, options, &phar, &error) == FAILURE) + if (phar_open_or_create_filename(resource->host, NULL, 0, options, &phar, &error) == FAILURE) { if (error) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { @@ -139,7 +137,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const return NULL; } } else { - if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, options, NULL, &error) == FAILURE) + if (phar_open_from_filename(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, options, NULL, &error) == FAILURE) { if (error) { if (!(options & PHP_STREAM_URL_STAT_QUIET)) { @@ -165,11 +163,11 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha char *internal_file; char *error; HashTable *pharcontext; - php_url *resource = NULL; php_stream *fpf; zval *pzoption, *metadata; - if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) { + php_url *resource = phar_parse_url(wrapper, path, mode, options); + if (!resource) { return NULL; } @@ -191,7 +189,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha /* strip leading "/" */ internal_file = estrndup(ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1); if (mode[0] == 'w' || (mode[0] == 'r' && mode[1] == '+')) { - if (NULL == (idata = phar_get_or_create_entry_data(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), internal_file, strlen(internal_file), mode, 0, &error, 1))) { + if (NULL == (idata = phar_get_or_create_entry_data(resource->host, internal_file, strlen(internal_file), mode, 0, &error, true, time(NULL)))) { if (error) { php_stream_wrapper_log_error(wrapper, options, "%s", error); efree(error); @@ -202,65 +200,63 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha php_url_free(resource); return NULL; } - if (error) { - efree(error); - } fpf = php_stream_alloc(&phar_ops, idata, NULL, mode); php_url_free(resource); efree(internal_file); - if (context && Z_TYPE(context->options) != IS_UNDEF && (pzoption = zend_hash_str_find(HASH_OF(&context->options), "phar", sizeof("phar")-1)) != NULL) { + if (context && Z_TYPE(context->options) != IS_UNDEF && (pzoption = zend_hash_str_find_ind(HASH_OF(&context->options), "phar", sizeof("phar")-1)) != NULL) { pharcontext = HASH_OF(pzoption); if (idata->internal_file->uncompressed_filesize == 0 && idata->internal_file->compressed_filesize == 0 - && (pzoption = zend_hash_str_find(pharcontext, "compress", sizeof("compress")-1)) != NULL + && (pzoption = zend_hash_str_find_ind(pharcontext, "compress", sizeof("compress")-1)) != NULL && Z_TYPE_P(pzoption) == IS_LONG && (Z_LVAL_P(pzoption) & ~PHAR_ENT_COMPRESSION_MASK) == 0 ) { idata->internal_file->flags &= ~PHAR_ENT_COMPRESSION_MASK; idata->internal_file->flags |= Z_LVAL_P(pzoption); } - if ((pzoption = zend_hash_str_find(pharcontext, "metadata", sizeof("metadata")-1)) != NULL) { + if ((pzoption = zend_hash_str_find_ind(pharcontext, "metadata", sizeof("metadata")-1)) != NULL) { phar_metadata_tracker_free(&idata->internal_file->metadata_tracker, idata->internal_file->is_persistent); metadata = pzoption; ZVAL_COPY_DEREF(&idata->internal_file->metadata_tracker.val, metadata); - idata->phar->is_modified = 1; + idata->phar->is_modified = true; } } if (opened_path) { - *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%s/%S", idata->phar->fname, idata->internal_file->filename); + *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%S/%S", idata->phar->fname, idata->internal_file->filename); } return fpf; } else { if (!*internal_file && (options & STREAM_OPEN_FOR_INCLUDE)) { /* retrieve the stub */ - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL)) { + phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL); + if (!phar) { php_stream_wrapper_log_error(wrapper, options, "file %s is not a valid phar archive", ZSTR_VAL(resource->host)); efree(internal_file); php_url_free(resource); return NULL; } if (phar->is_tar || phar->is_zip) { - if ((FAILURE == phar_get_entry_data(&idata, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), ".phar/stub.php", sizeof(".phar/stub.php")-1, "r", 0, &error, 0)) || !idata) { + if ((FAILURE == phar_get_entry_data(&idata, resource->host, ".phar/stub.php", sizeof(".phar/stub.php")-1, "r", 0, &error, false)) || !idata) { goto idata_error; } efree(internal_file); if (opened_path) { - *opened_path = strpprintf(MAXPATHLEN, "%s", phar->fname); + *opened_path = zend_string_copy(phar->fname); } php_url_free(resource); goto phar_stub; } else { php_stream *stream = phar_get_pharfp(phar); if (stream == NULL) { - if (UNEXPECTED(FAILURE == phar_open_archive_fp(phar))) { + stream = phar_open_archive_fp(phar); + if (UNEXPECTED(!stream)) { php_stream_wrapper_log_error(wrapper, options, "phar error: could not reopen phar \"%s\"", ZSTR_VAL(resource->host)); efree(internal_file); php_url_free(resource); return NULL; } - stream = phar_get_pharfp(phar); } phar_entry_info *entry; @@ -283,14 +279,14 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha ++(entry->fp_refcount); php_url_free(resource); if (opened_path) { - *opened_path = strpprintf(MAXPATHLEN, "%s", phar->fname); + *opened_path = zend_string_copy(phar->fname); } efree(internal_file); goto phar_stub; } } /* read-only access is allowed to magic files in .phar directory */ - if ((FAILURE == phar_get_entry_data(&idata, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), internal_file, strlen(internal_file), "r", 0, &error, 0)) || !idata) { + if ((FAILURE == phar_get_entry_data(&idata, resource->host, internal_file, strlen(internal_file), "r", 0, &error, false)) || !idata) { idata_error: if (error) { php_stream_wrapper_log_error(wrapper, options, "%s", error); @@ -305,7 +301,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } php_url_free(resource); #ifdef MBO_0 - fprintf(stderr, "Pharname: %s\n", idata->phar->fname); + fprintf(stderr, "Pharname: %s\n", ZSTR_VAL(idata->phar->fname)); fprintf(stderr, "Filename: %s\n", internal_file); fprintf(stderr, "Entry: %s\n", ZSTR_VAL(idata->internal_file->filename)); fprintf(stderr, "Size: %u\n", idata->internal_file->uncompressed_filesize); @@ -322,7 +318,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } if (!PHAR_G(cwd_init) && (options & STREAM_OPEN_FOR_INCLUDE)) { - char *entry = ZSTR_VAL(idata->internal_file->filename), *cwd; + const char *entry = ZSTR_VAL(idata->internal_file->filename), *cwd; PHAR_G(cwd_init) = 1; if ((idata->phar->is_tar || idata->phar->is_zip) && zend_string_equals_literal(idata->internal_file->filename, ".phar/stub.php")) { @@ -338,7 +334,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha } } if (opened_path) { - *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%s/%S", idata->phar->fname, idata->internal_file->filename); + *opened_path = zend_strpprintf_unchecked(MAXPATHLEN, "phar://%S/%S", idata->phar->fname, idata->internal_file->filename); } efree(internal_file); phar_stub: @@ -353,11 +349,11 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha static int phar_stream_close(php_stream *stream, int close_handle) /* {{{ */ { /* for some reasons phar needs to be flushed even if there is no write going on */ - phar_stream_flush(stream); + int ret = phar_stream_flush(stream); phar_entry_delref((phar_entry_data *)stream->abstract); - return 0; + return ret; } /* }}} */ @@ -368,9 +364,9 @@ static ssize_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* { phar_entry_data *data = (phar_entry_data *)stream->abstract; ssize_t got; - phar_entry_info *entry; + const phar_entry_info *entry; - if (data->internal_file->link) { + if (data->internal_file->symlink) { entry = phar_get_link_source(data->internal_file); } else { entry = data->internal_file; @@ -398,11 +394,11 @@ static ssize_t phar_stream_read(php_stream *stream, char *buf, size_t count) /* static int phar_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) /* {{{ */ { phar_entry_data *data = (phar_entry_data *)stream->abstract; - phar_entry_info *entry; + const phar_entry_info *entry; int res; zend_ulong temp; - if (data->internal_file->link) { + if (data->internal_file->symlink) { entry = phar_get_link_source(data->internal_file); } else { entry = data->internal_file; @@ -424,11 +420,9 @@ static int phar_stream_seek(php_stream *stream, zend_off_t offset, int whence, z zend_off_t temp_signed = (zend_off_t) temp; if (temp_signed > data->zero + (zend_off_t) entry->uncompressed_filesize) { - *newoffset = -1; /* FIXME: this will invalidate the ZEND_ASSERT(stream->position >= 0); assertion in streams.c */ return -1; } if (temp_signed < data->zero) { - *newoffset = -1; /* FIXME: this will invalidate the ZEND_ASSERT(stream->position >= 0); assertion in streams.c */ return -1; } res = php_stream_seek(data->fp, temp_signed, SEEK_SET); @@ -445,18 +439,18 @@ static ssize_t phar_stream_write(php_stream *stream, const char *buf, size_t cou { phar_entry_data *data = (phar_entry_data *) stream->abstract; - php_stream_seek(data->fp, data->position, SEEK_SET); + php_stream_seek(data->fp, data->position + data->zero, SEEK_SET); if (count != php_stream_write(data->fp, buf, count)) { - php_stream_wrapper_log_error(stream->wrapper, stream->flags, "phar error: Could not write %d characters to \"%s\" in phar \"%s\"", (int) count, ZSTR_VAL(data->internal_file->filename), data->phar->fname); + php_stream_wrapper_log_error(stream->wrapper, stream->flags, "phar error: Could not write %zu characters to \"%s\" in phar \"%s\"", count, ZSTR_VAL(data->internal_file->filename), ZSTR_VAL(data->phar->fname)); return -1; } - data->position = php_stream_tell(data->fp); + data->position = php_stream_tell(data->fp) - data->zero; if (data->position > (zend_off_t)data->internal_file->uncompressed_filesize) { data->internal_file->uncompressed_filesize = data->position; } data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize; data->internal_file->old_flags = data->internal_file->flags; - data->internal_file->is_modified = 1; + data->internal_file->is_modified = true; return count; } /* }}} */ @@ -467,16 +461,17 @@ static ssize_t phar_stream_write(php_stream *stream, const char *buf, size_t cou static int phar_stream_flush(php_stream *stream) /* {{{ */ { char *error; - phar_entry_data *data = (phar_entry_data *) stream->abstract; + int ret; + const phar_entry_data *data = stream->abstract; if (data->internal_file->is_modified) { data->internal_file->timestamp = time(0); - phar_flush(data->phar, &error); + ret = phar_flush(data->phar, &error); if (error) { php_stream_wrapper_log_error(stream->wrapper, REPORT_ERRORS, "%s", error); efree(error); } - return EOF; + return ret; } else { return EOF; } @@ -487,7 +482,7 @@ static int phar_stream_flush(php_stream *stream) /* {{{ */ /** * stat an opened phar file handle stream, used by phar_stat() */ -void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_statbuf *ssb, bool is_temp_dir) +static void phar_dostat(const phar_archive_data *phar, const phar_entry_info *data, php_stream_statbuf *ssb, bool is_temp_dir) { memset(ssb, 0, sizeof(php_stream_statbuf)); @@ -527,8 +522,10 @@ void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_stat if (!is_temp_dir) { ssb->sb.st_ino = data->inode; } -#ifndef PHP_WIN32 +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE ssb->sb.st_blksize = -1; +#endif +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS ssb->sb.st_blocks = -1; #endif } @@ -539,14 +536,14 @@ void phar_dostat(phar_archive_data *phar, phar_entry_info *data, php_stream_stat */ static int phar_stream_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */ { - phar_entry_data *data = (phar_entry_data *)stream->abstract; + const phar_entry_data *data = stream->abstract; /* If ssb is NULL then someone is misbehaving */ if (!ssb) { return -1; } - phar_dostat(data->phar, data->internal_file, ssb, 0); + phar_dostat(data->phar, data->internal_file, ssb, false); return 0; } /* }}} */ @@ -557,13 +554,11 @@ static int phar_stream_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context) /* {{{ */ { - php_url *resource = NULL; - char *internal_file, *error; - phar_archive_data *phar; - phar_entry_info *entry; + char *internal_file; size_t internal_file_len; - if ((resource = phar_parse_url(wrapper, url, "r", flags|PHP_STREAM_URL_STAT_QUIET)) == NULL) { + php_url *resource = phar_parse_url(wrapper, url, "r", flags|PHP_STREAM_URL_STAT_QUIET); + if (!resource) { return FAILURE; } @@ -582,19 +577,14 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */ /* find the phar in our trusty global hash indexed by alias (host of phar://blah.phar/file.whatever) */ - if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, NULL); + if (!phar) { php_url_free(resource); - if (error) { - efree(error); - } return FAILURE; } - if (error) { - efree(error); - } if (*internal_file == '\0') { /* root directory requested */ - phar_dostat(phar, NULL, ssb, 1); + phar_dostat(phar, NULL, ssb, true); php_url_free(resource); return SUCCESS; } @@ -604,13 +594,14 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f } internal_file_len = strlen(internal_file); /* search through the manifest of files, and if we have an exact match, it's a file */ - if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len))) { - phar_dostat(phar, entry, ssb, 0); + phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); + if (entry) { + phar_dostat(phar, entry, ssb, false); php_url_free(resource); return SUCCESS; } if (zend_hash_str_exists(&(phar->virtual_dirs), internal_file, internal_file_len)) { - phar_dostat(phar, NULL, ssb, 1); + phar_dostat(phar, NULL, ssb, true); php_url_free(resource); return SUCCESS; } @@ -643,10 +634,12 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f goto free_resource; } efree(test); - if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len))) { + + entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len); + if (!entry) { goto free_resource; } - phar_dostat(phar, entry, ssb, 0); + phar_dostat(phar, entry, ssb, false); php_url_free(resource); return SUCCESS; } @@ -663,13 +656,12 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f */ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) /* {{{ */ { - php_url *resource; char *internal_file, *error; - int internal_file_len; + size_t internal_file_len; phar_entry_data *idata; - phar_archive_data *pphar; - if ((resource = phar_parse_url(wrapper, url, "rb", options)) == NULL) { + php_url *resource = phar_parse_url(wrapper, url, "rb", options); + if (!resource) { php_stream_wrapper_log_error(wrapper, options, "phar error: unlink failed"); return 0; } @@ -689,7 +681,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int phar_request_initialize(); - pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); + const phar_archive_data *pphar = zend_hash_find_ptr(&(PHAR_G(phar_fname_map)), resource->host); if (PHAR_G(readonly) && (!pphar || !pphar->is_data)) { php_url_free(resource); php_stream_wrapper_log_error(wrapper, options, "phar error: write operations disabled by the php.ini setting phar.readonly"); @@ -699,7 +691,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int /* need to copy to strip leading "/", will get touched again */ internal_file = estrndup(ZSTR_VAL(resource->path) + 1, ZSTR_LEN(resource->path) - 1); internal_file_len = ZSTR_LEN(resource->path) - 1; - if (FAILURE == phar_get_entry_data(&idata, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), internal_file, internal_file_len, "r", 0, &error, 1)) { + if (FAILURE == phar_get_entry_data(&idata, resource->host, internal_file, internal_file_len, "r", 0, &error, true)) { /* constraints of fp refcount were not met */ if (error) { php_stream_wrapper_log_error(wrapper, options, "unlink of \"%s\" failed: %s", url, error); @@ -711,9 +703,6 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int php_url_free(resource); return 0; } - if (error) { - efree(error); - } if (idata->internal_file->fp_refcount > 1) { /* more than just our fp resource is open for this file */ php_stream_wrapper_log_error(wrapper, options, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot unlink", internal_file, ZSTR_VAL(resource->host)); @@ -735,42 +724,33 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context) /* {{{ */ { - php_url *resource_from, *resource_to; char *error; - phar_archive_data *phar, *pfrom, *pto; - phar_entry_info *entry; - int is_dir = 0; - int is_modified = 0; + bool is_dir = false; + bool is_modified = false; error = NULL; - if ((resource_from = phar_parse_url(wrapper, url_from, "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) { + php_url *resource_from = phar_parse_url(wrapper, url_from, "wb", options|PHP_STREAM_URL_STAT_QUIET); + if (!resource_from) { php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_from); return 0; } - if (SUCCESS != phar_get_archive(&pfrom, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error)) { - pfrom = NULL; - if (error) { - efree(error); - } - } + + phar_archive_data *pfrom = phar_get_archive(ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, NULL); if (PHAR_G(readonly) && (!pfrom || !pfrom->is_data)) { php_url_free(resource_from); php_error_docref(NULL, E_WARNING, "phar error: Write operations disabled by the php.ini setting phar.readonly"); return 0; } - if ((resource_to = phar_parse_url(wrapper, url_to, "wb", options|PHP_STREAM_URL_STAT_QUIET)) == NULL) { + php_url *resource_to = phar_parse_url(wrapper, url_to, "wb", options|PHP_STREAM_URL_STAT_QUIET); + if (!resource_to) { php_url_free(resource_from); php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": invalid or non-writable url \"%s\"", url_from, url_to, url_to); return 0; } - if (SUCCESS != phar_get_archive(&pto, ZSTR_VAL(resource_to->host), ZSTR_LEN(resource_to->host), NULL, 0, &error)) { - if (error) { - efree(error); - } - pto = NULL; - } + + phar_archive_data *pto = phar_get_archive(ZSTR_VAL(resource_to->host), ZSTR_LEN(resource_to->host), NULL, 0, NULL); if (PHAR_G(readonly) && (!pto || !pto->is_data)) { php_url_free(resource_from); php_url_free(resource_to); @@ -814,7 +794,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from return 0; } - if (SUCCESS != phar_get_archive(&phar, ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(resource_from->host), ZSTR_LEN(resource_from->host), NULL, 0, &error); + if (!phar) { php_url_free(resource_from); php_url_free(resource_to); php_error_docref(NULL, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error); @@ -829,7 +810,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from return 0; } - if (NULL != (entry = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(resource_from->path)+1, ZSTR_LEN(resource_from->path)-1))) { + phar_entry_info *entry = zend_hash_str_find_ptr(&(phar->manifest), ZSTR_VAL(resource_from->path)+1, ZSTR_LEN(resource_from->path)-1); + if (entry) { phar_entry_info new, *source; /* perform rename magic */ @@ -845,7 +827,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from entry->is_deleted = 1; entry->fp = NULL; ZVAL_UNDEF(&entry->metadata_tracker.val); - entry->link = entry->tmp = NULL; + entry->symlink = NULL; + entry->tmp = NULL; source = entry; /* add to the manifest, and then store the pointer to the new guy in entry @@ -861,8 +844,8 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from zend_hash_del(&phar->manifest, entry->filename); return 0; } - is_modified = 1; - entry->is_modified = 1; + is_modified = true; + entry->is_modified = true; is_dir = entry->is_dir; } else { is_dir = zend_hash_str_exists(&(phar->virtual_dirs), ZSTR_VAL(resource_from->path)+1, ZSTR_LEN(resource_from->path)-1); @@ -892,13 +875,13 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from memcmp(ZSTR_VAL(str_key), ZSTR_VAL(resource_from->path)+1, from_len) == 0 && IS_SLASH(ZSTR_VAL(str_key)[from_len])) { - new_str_key = zend_string_alloc(ZSTR_LEN(str_key) + to_len - from_len, 0); - memcpy(ZSTR_VAL(new_str_key), ZSTR_VAL(resource_to->path) + 1, to_len); - memcpy(ZSTR_VAL(new_str_key) + to_len, ZSTR_VAL(str_key) + from_len, ZSTR_LEN(str_key) - from_len); - ZSTR_VAL(new_str_key)[ZSTR_LEN(new_str_key)] = 0; + new_str_key = zend_string_concat2( + ZSTR_VAL(resource_to->path) + 1, to_len, + ZSTR_VAL(str_key) + from_len, ZSTR_LEN(str_key) - from_len + ); - is_modified = 1; - entry->is_modified = 1; + is_modified = true; + entry->is_modified = true; zend_string_release(entry->filename); entry->filename = zend_string_copy(new_str_key); @@ -914,10 +897,10 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from if (zend_string_starts_with_cstr(str_key, ZSTR_VAL(resource_from->path)+1, from_len) && (ZSTR_LEN(str_key) == from_len || IS_SLASH(ZSTR_VAL(str_key)[from_len]))) { - new_str_key = zend_string_alloc(ZSTR_LEN(str_key) + to_len - from_len, 0); - memcpy(ZSTR_VAL(new_str_key), ZSTR_VAL(resource_to->path) + 1, to_len); - memcpy(ZSTR_VAL(new_str_key) + to_len, ZSTR_VAL(str_key) + from_len, ZSTR_LEN(str_key) - from_len); - ZSTR_VAL(new_str_key)[ZSTR_LEN(new_str_key)] = 0; + new_str_key = zend_string_concat2( + ZSTR_VAL(resource_to->path) + 1, to_len, + ZSTR_VAL(str_key) + from_len, ZSTR_LEN(str_key) - from_len + ); zend_string_release_ex(str_key, 0); b->h = zend_string_hash_val(new_str_key); @@ -931,10 +914,10 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from if (zend_string_starts_with_cstr(str_key, ZSTR_VAL(resource_from->path)+1, from_len) && (ZSTR_LEN(str_key) == from_len || IS_SLASH(ZSTR_VAL(str_key)[from_len]))) { - new_str_key = zend_string_alloc(ZSTR_LEN(str_key) + to_len - from_len, 0); - memcpy(ZSTR_VAL(new_str_key), ZSTR_VAL(resource_to->path) + 1, to_len); - memcpy(ZSTR_VAL(new_str_key) + to_len, ZSTR_VAL(str_key) + from_len, ZSTR_LEN(str_key) - from_len); - ZSTR_VAL(new_str_key)[ZSTR_LEN(new_str_key)] = 0; + new_str_key = zend_string_concat2( + ZSTR_VAL(resource_to->path) + 1, to_len, + ZSTR_VAL(str_key) + from_len, ZSTR_LEN(str_key) - from_len + ); zend_string_release_ex(str_key, 0); b->h = zend_string_hash_val(new_str_key); diff --git a/ext/phar/stream.h b/ext/phar/stream.h index ce75b70dcba0..cf40e3129c69 100644 --- a/ext/phar/stream.h +++ b/ext/phar/stream.h @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -21,7 +19,7 @@ BEGIN_EXTERN_C() #include "ext/standard/url.h" php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options); -void phar_entry_remove(phar_entry_data *idata, char **error); +ZEND_ATTRIBUTE_NONNULL void phar_entry_remove(phar_entry_data *idata, char **error); static php_stream* phar_wrapper_open_url(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context); diff --git a/ext/phar/stub.h b/ext/phar/stub.h index aa70e703b79b..79887a62d7b8 100644 --- a/ext/phar/stub.h +++ b/ext/phar/stub.h @@ -2,30 +2,30 @@ +----------------------------------------------------------------------+ | phar php single-file executable PHP extension generated stub | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ */ -static inline zend_string* phar_get_stub(const char *index_php, const char *web, const int name_len, const int web_len) +static inline zend_string *phar_get_stub(const char *index_php, const char *web, size_t name_len, size_t web_len) { + /* Do NOT modify this file directly! + * Instead modify shortarc.php to change PHP code or makestub.php to change C code and then use makestub.php to generate this file. */ static const char newstub0[] = " 2,\n'c' => 'text/plain',\n'cc' => 'text/plain',\n'cpp' => 'text/plain',\n'c++' => 'text/plain',\n'dtd' => 'text/plain',\n'h' => 'text/plain',\n'log' => 'text/plain',\n'rng' => 'text/plain',\n'txt' => 'text/plain',\n'xsd' => 'text/plain',\n'php' => 1,\n'inc' => 1,\n'avi' => 'video/avi',\n'bmp' => 'image/bmp',\n'css' => 'text/css',\n'gif' => 'image/gif',\n'htm' => 'text/html',\n'html' => 'text/html',\n'htmls' => 'text/html',\n'ico' => 'image/x-ico',\n'jpe' => 'image/jpeg',\n'jpg' => 'image/jpeg',\n'jpeg' => 'image/jpeg',\n'js' => 'application/x-javascript',\n'midi' => 'audio/midi',\n'mid' => 'audio/midi',\n'mod' => 'audio/mod',\n'mov' => 'movie/quicktime',\n'mp3' => 'audio/mp3',\n'mpg' => 'video/mpeg',\n'mpeg' => 'video/mpeg',\n'pdf' => 'application/pdf',\n'png' => 'image/png',\n'swf' => 'application/shockwave-flash',\n'tif' => 'image/tiff',\n'tiff' => 'image/tiff',\n'wav' => 'audio/wav',\n'xbm' => 'image/xbm',\n'xml' => 'text/xml',\n);\n\nheader(\"Cache-Control: no-cache, must-revalidate\");\nheader(\"Pragma: no-cache\");\n\n$basename = basename(__FILE__);\nif (!strpos($_SERVER['REQUEST_URI'], $basename)) {\nchdir(Extract_Phar::$temp);\ninclude $web;\nreturn;\n}\n$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));\nif (!$pt || $pt == '/') {\n$pt = $web;\nheader('HTTP/1.1 301 Moved Permanently');\nheader('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);\nexit;\n}\n$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);\nif (!$a || strlen(dirname($a)) < strlen("; - static const char newstub1_1[] = "Extract_Phar::$temp)) {\nheader('HTTP/1.0 404 Not Found');\necho \"\\n \\n File Not Found<title>\\n </head>\\n <body>\\n <h1>404 - File Not Found</h1>\\n </body>\\n</html>\";\nexit;\n}\n$b = pathinfo($a);\nif (!isset($b['extension'])) {\nheader('Content-Type: text/plain');\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\nif (isset($mimes[$b['extension']])) {\nif ($mimes[$b['extension']] === 1) {\ninclude $a;\nexit;\n}\nif ($mimes[$b['extension']] === 2) {\nhighlight_file($a);\nexit;\n}\nheader('Content-Type: ' .$mimes[$b['extension']]);\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\n}\n\nclass Extract_Phar\n{\nstatic $temp;\nstatic $origdir;\nconst GZ = 0x1000;\nconst BZ2 = 0x2000;\nconst MASK = 0x3000;\nconst START = '"; + static const char newstub1_1[] = "Extract_Phar::$temp)) {\nheader('HTTP/1.0 404 Not Found');\necho \"<html>\\n <head>\\n <title>File Not Found\\n \\n \\n

404 - File Not Found

\\n \\n\";\nexit;\n}\n$b = pathinfo($a);\nif (!isset($b['extension'])) {\nheader('Content-Type: text/plain');\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\nif (isset($mimes[$b['extension']])) {\nif ($mimes[$b['extension']] === 1) {\ninclude $a;\nexit;\n}\nif ($mimes[$b['extension']] === 2) {\nhighlight_file($a);\nexit;\n}\nheader('Content-Type: ' .$mimes[$b['extension']]);\nheader('Content-Length: ' . filesize($a));\nreadfile($a);\nexit;\n}\n}\n\nclass Extract_Phar\n{\nstatic $temp;\nstatic $origdir;\nconst GZ = 0x1000;\nconst BZ2 = 0x2000;\nconst MASK = 0x3000;\nconst START = '"; static const char newstub2[] = "';\nconst LEN = "; - static const char newstub3_0[] = ";\n\nstatic function go($return = false)\n{\n$fp = fopen(__FILE__, 'rb');\nfseek($fp, self::LEN);\n$L = unpack('V', $a = fread($fp, 4));\n$m = '';\n\ndo {\n$read = 8192;\nif ($L[1] - strlen($m) < 8192) {\n$read = $L[1] - strlen($m);\n}\n$last = fread($fp, $read);\n$m .= $last;\n} while (strlen($last) && strlen($m) < $L[1]);\n\nif (strlen($m) < $L[1]) {\ndie('ERROR: manifest length read was \"' .\nstrlen($m) .'\" should be \"' .\n$L[1] . '\"');\n}\n\n$info = self::_unpack($m);\n$f = $info['c'];\n\nif ($f & self::GZ) {\nif (!function_exists('gzinflate')) {\ndie('Error: zlib extension is not enabled -' .\n' gzinflate() function needed for zlib-compressed .phars');\n}\n}\n\nif ($f & self::BZ2) {\nif (!function_exists('bzdecompress')) {\ndie('Error: bzip2 extension is not enabled -' .\n' bzdecompress() function needed for bz2-compressed .phars');\n}\n}\n\n$temp = self::tmpdir();\n\nif (!$temp || !is_writable($temp)) {\n$sessionpath = session_save_path();\nif (strpos ($sessionpath, \";\") !== false)\n$sessionpath = substr ($sessionpath, strpos ($sessionpath, \";\")+1);\nif (!file_exists($sessionpath) || !is_dir($sessionpath)) {\ndie('Could not locate temporary directory to extract phar');\n}\n$temp = $sessionpath;\n}\n\n$temp .= '/pharextract/'.basename(__FILE__, '.phar');\nself::$temp = $temp;\nself::$origdir = getcwd();\n@mkdir($temp, 0777, true);\n$temp = realpath($temp);\n\nif (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {\nself::_removeTmpFiles($temp, getcwd());\n@mkdir($temp, 0777, true);\n@file_put_contents($temp . '/' . md5_file(__FILE__), '');\n\nforeach ($info['m'] as $path => $file) {\n$a = !file_exists(dirname($temp . '/' . $path));\n@mkdir(dirname($temp . '/' . $path), 0777, true);\nclearstatcache();\n\nif ($path[strlen($path) - 1] == '/') {\n@mkdir($temp . '/' . $path, 0777);\n} else {\nfile_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));\n@chmod($temp . '/' . $path, 0666);\n}\n}\n}\n\nchdir($temp);\n\nif (!$return) {\ninclude self::START;\n}\n}\n\nstatic fun"; - static const char newstub3_1[] = "ction tmpdir()\n{\nif (strpos(PHP_OS, 'WIN') !== false) {\nif ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {\nreturn $var;\n}\nif (is_dir('/temp') || mkdir('/temp')) {\nreturn realpath('/temp');\n}\nreturn false;\n}\nif ($var = getenv('TMPDIR')) {\nreturn $var;\n}\nreturn realpath('/tmp');\n}\n\nstatic function _unpack($m)\n{\n$info = unpack('V', substr($m, 0, 4));\n $l = unpack('V', substr($m, 10, 4));\n$m = substr($m, 14 + $l[1]);\n$s = unpack('V', substr($m, 0, 4));\n$o = 0;\n$start = 4 + $s[1];\n$ret['c'] = 0;\n\nfor ($i = 0; $i < $info[1]; $i++) {\n $len = unpack('V', substr($m, $start, 4));\n$start += 4;\n $savepath = substr($m, $start, $len[1]);\n$start += $len[1];\n $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));\n$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]\n& 0xffffffff);\n$ret['m'][$savepath][7] = $o;\n$o += $ret['m'][$savepath][2];\n$start += 24 + $ret['m'][$savepath][5];\n$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;\n}\nreturn $ret;\n}\n\nstatic function extractFile($path, $entry, $fp)\n{\n$data = '';\n$c = $entry[2];\n\nwhile ($c) {\nif ($c < 8192) {\n$data .= @fread($fp, $c);\n$c = 0;\n} else {\n$c -= 8192;\n$data .= @fread($fp, 8192);\n}\n}\n\nif ($entry[4] & self::GZ) {\n$data = gzinflate($data);\n} elseif ($entry[4] & self::BZ2) {\n$data = bzdecompress($data);\n}\n\nif (strlen($data) != $entry[0]) {\ndie(\"Invalid internal .phar file (size error \" . strlen($data) . \" != \" .\n$stat[7] . \")\");\n}\n\nif ($entry[3] != sprintf(\"%u\", crc32($data) & 0xffffffff)) {\ndie(\"Invalid internal .phar file (checksum error)\");\n}\n\nreturn $data;\n}\n\nstatic function _removeTmpFiles($temp, $origdir)\n{\nchdir($temp);\n\nforeach (glob('*') as $f) {\nif (file_exists($f)) {\nis_dir($f) ? @rmdir($f) : @unlink($f);\nif (file_exists($f) && is_dir($f)) {\nself::_removeTmpFiles($f, getcwd());\n}\n}\n}\n\n@rmdir($temp);\nclearstatcache();\nchdir($origdir);\n}\n}\n\nExtract_Phar::go();\n__HALT_COMPILER(); ?>"; + static const char newstub3_0[] = ";\n\nstatic function go($return = false)\n{\n$fp = fopen(__FILE__, 'rb');\nfseek($fp, self::LEN);\n$L = unpack('V', $a = (string)fread($fp, 4));\n$m = '';\n\ndo {\n$read = 8192;\nif ($L[1] - strlen($m) < 8192) {\n$read = $L[1] - strlen($m);\n}\n$last = (string)fread($fp, $read);\n$m .= $last;\n} while (strlen($last) && strlen($m) < $L[1]);\n\nif (strlen($m) < $L[1]) {\ndie('ERROR: manifest length read was \"' .\nstrlen($m) .'\" should be \"' .\n$L[1] . '\"');\n}\n\n$info = self::_unpack($m);\n$f = $info['c'];\n\nif ($f & self::GZ) {\nif (!function_exists('gzinflate')) {\ndie('Error: zlib extension is not enabled -' .\n' gzinflate() function needed for zlib-compressed .phars');\n}\n}\n\nif ($f & self::BZ2) {\nif (!function_exists('bzdecompress')) {\ndie('Error: bzip2 extension is not enabled -' .\n' bzdecompress() function needed for bz2-compressed .phars');\n}\n}\n\n$temp = self::tmpdir();\n\nif (!$temp || !is_writable($temp)) {\n$sessionpath = session_save_path();\nif (strpos ($sessionpath, \";\") !== false)\n$sessionpath = substr ($sessionpath, strpos ($sessionpath, \";\")+1);\nif (!file_exists($sessionpath) || !is_dir($sessionpath)) {\ndie('Could not locate temporary directory to extract phar');\n}\n$temp = $sessionpath;\n}\n\n$temp .= '/pharextract/'.basename(__FILE__, '.phar');\nself::$temp = $temp;\nself::$origdir = getcwd();\n@mkdir($temp, 0777, true);\n$temp = realpath($temp);\n\nif (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {\nself::_removeTmpFiles($temp, getcwd());\n@mkdir($temp, 0777, true);\n@file_put_contents($temp . '/' . md5_file(__FILE__), '');\n\nforeach ($info['m'] as $path => $file) {\n$a = !file_exists(dirname($temp . '/' . $path));\n@mkdir(dirname($temp . '/' . $path), 0777, true);\nclearstatcache();\n\nif ($path[strlen($path) - 1] == '/') {\n@mkdir($temp . '/' . $path, 0777);\n} else {\nfile_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));\n@chmod($temp . '/' . $path, 0666);\n}\n}\n}\n\nchdir($temp);\n\nif (!$return) {\ninclude self::START;\n}\n"; + static const char newstub3_1[] = "}\n\nstatic function tmpdir()\n{\nif (strpos(PHP_OS, 'WIN') !== false) {\nif ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {\nreturn $var;\n}\nif (is_dir('/temp') || mkdir('/temp')) {\nreturn realpath('/temp');\n}\nreturn false;\n}\nif ($var = getenv('TMPDIR')) {\nreturn $var;\n}\nreturn realpath('/tmp');\n}\n\nstatic function _unpack($m)\n{\n$info = unpack('V', substr($m, 0, 4));\n\n$l = unpack('V', substr($m, 10, 4));\n$m = substr($m, 14 + $l[1]);\n$s = unpack('V', substr($m, 0, 4));\n$o = 0;\n$start = 4 + $s[1];\n$ret['c'] = 0;\n\nfor ($i = 0; $i < $info[1]; $i++) {\n\n$len = unpack('V', substr($m, $start, 4));\n$start += 4;\n\n$savepath = substr($m, $start, $len[1]);\n$start += $len[1];\n\n\n\n$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));\n$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]\n& 0xffffffff);\n$ret['m'][$savepath][7] = $o;\n$o += $ret['m'][$savepath][2];\n$start += 24 + $ret['m'][$savepath][5];\n$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;\n}\nreturn $ret;\n}\n\nstatic function extractFile($path, $entry, $fp)\n{\n$data = '';\n$c = $entry[2];\n\nwhile ($c) {\nif ($c < 8192) {\n$data .= @fread($fp, $c);\n$c = 0;\n} else {\n$c -= 8192;\n$data .= @fread($fp, 8192);\n}\n}\n\nif ($entry[4] & self::GZ) {\n$data = gzinflate($data);\n} elseif ($entry[4] & self::BZ2) {\n$data = bzdecompress($data);\n}\n\nif (strlen($data) != $entry[0]) {\ndie(\"Invalid internal .phar file (size error \" . strlen($data) . \" != \" .\n$entry[0] . \")\");\n}\n\nif ($entry[3] != sprintf(\"%u\", crc32($data) & 0xffffffff)) {\ndie(\"Invalid internal .phar file (checksum error)\");\n}\n\nreturn $data;\n}\n\nstatic function _removeTmpFiles($temp, $origdir)\n{\nchdir($temp);\n\nforeach (glob('*') as $f) {\nif (file_exists($f)) {\nis_dir($f) ? @rmdir($f) : @unlink($f);\nif (file_exists($f) && is_dir($f)) {\nself::_removeTmpFiles($f, getcwd());\n}\n}\n}\n\n@rmdir($temp);\nclearstatcache();\nchdir($origdir);\n}\n}\n\nExtract_Phar::go();\n__HALT_COMPILER(); ?>"; - static const int newstub_len = 6623; + static const size_t newstub_len = 6641; - return strpprintf(name_len + web_len + newstub_len, "%s%s%s%s%s%s%d%s%s", newstub0, web, newstub1_0, newstub1_1, index_php, newstub2, name_len + web_len + newstub_len, newstub3_0, newstub3_1); + return strpprintf(name_len + web_len + newstub_len, "%s%s%s%s%s%s%zu%s%s", newstub0, web, newstub1_0, newstub1_1, index_php, newstub2, name_len + web_len + newstub_len, newstub3_0, newstub3_1); } diff --git a/ext/phar/tar.c b/ext/phar/tar.c index a91419d84c77..f85241ccc4e5 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | TAR archive support for Phar | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Gregory Beaver | @@ -87,10 +85,10 @@ static zend_result phar_tar_octal(char *buf, uint32_t val, size_t len) /* {{{ */ } /* }}} */ -static uint32_t phar_tar_checksum(char *buf, size_t len) /* {{{ */ +static uint32_t phar_tar_checksum(const char *buf, size_t len) /* {{{ */ { uint32_t sum = 0; - char *end = buf + len; + const char *end = buf + len; while (buf != end) { sum += (unsigned char)*buf; @@ -100,12 +98,13 @@ static uint32_t phar_tar_checksum(char *buf, size_t len) /* {{{ */ } /* }}} */ -bool phar_is_tar(char *buf, char *fname) /* {{{ */ +bool phar_is_tar(const char *buf, const char *fname) /* {{{ */ { tar_header *header = (tar_header *) buf; uint32_t checksum = phar_tar_number(header->checksum, sizeof(header->checksum)); bool is_tar; - char save[sizeof(header->checksum)], *bname; + char save[sizeof(header->checksum)]; + const char *bname; /* assume that the first filename in a tar won't begin with is_data = is_data; @@ -153,12 +156,9 @@ zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, } /* we've reached here - the phar exists and is a regular phar */ - if (error) { - spprintf(error, 4096, "phar tar error: \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a tar-based phar", fname); - } + spprintf(error, 4096, "phar tar error: \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a tar-based phar", ZSTR_VAL(fname)); return FAILURE; } -/* }}} */ static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp) /* {{{ */ { @@ -202,15 +202,22 @@ static zend_result phar_tar_process_metadata(phar_entry_info *entry, php_stream } /* }}} */ -zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error) /* {{{ */ -{ +zend_result phar_parse_tarfile( + php_stream* fp, + const char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + phar_archive_data** pphar, + uint32_t compression, + char **error +) { char buf[512], *actual_alias = NULL, *p; phar_entry_info entry = {0}; size_t pos = 0, read, totalsize; tar_header *hdr; uint32_t sum1, sum2, size, old; phar_archive_data *myphar, *actual; - int last_was_longlink = 0; + bool last_was_longlink = false; size_t linkname_len; if (error) { @@ -237,11 +244,11 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch myphar->is_persistent = PHAR_G(persist); /* estimate number of entries, can't be certain with tar files */ zend_hash_init(&myphar->manifest, 2 + (totalsize >> 12), - zend_get_hash_value, destroy_phar_manifest_entry, (bool)myphar->is_persistent); + zend_get_hash_value, destroy_phar_manifest_entry, myphar->is_persistent); zend_hash_init(&myphar->mounted_dirs, 5, - zend_get_hash_value, NULL, (bool)myphar->is_persistent); + zend_get_hash_value, NULL, myphar->is_persistent); zend_hash_init(&myphar->virtual_dirs, 4 + (totalsize >> 11), - zend_get_hash_value, NULL, (bool)myphar->is_persistent); + zend_get_hash_value, NULL, myphar->is_persistent); myphar->is_tar = 1; /* remember whether this entire phar was compressed with gz/bzip2 */ myphar->flags = compression; @@ -361,7 +368,7 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch } if (!last_was_longlink && hdr->typeflag == 'L') { - last_was_longlink = 1; + last_was_longlink = true; /* support the ././@LongLink system for storing long filenames */ /* Check for overflow - bug 61065 */ @@ -465,7 +472,7 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch GC_MAKE_PERSISTENT_LOCAL(entry.filename); } } - last_was_longlink = 0; + last_was_longlink = false; phar_add_virtual_dirs(myphar, ZSTR_VAL(entry.filename), ZSTR_LEN(entry.filename)); @@ -497,8 +504,8 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch entry.is_dir = 0; } - entry.link = NULL; - /* link field is null-terminated unless it has 100 non-null chars. + entry.symlink = NULL; + /* linkname field is null-terminated unless it has 100 non-null chars. * Thus we cannot use strlen. */ linkname_len = zend_strnlen(hdr->linkname, 100); if (entry.tar_type == TAR_LINK) { @@ -511,9 +518,9 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch phar_destroy_phar_data(myphar); return FAILURE; } - entry.link = estrndup(hdr->linkname, linkname_len); + entry.symlink = zend_string_init(hdr->linkname, linkname_len, false); } else if (entry.tar_type == TAR_SYMLINK) { - entry.link = estrndup(hdr->linkname, linkname_len); + entry.symlink = zend_string_init(hdr->linkname, linkname_len, false); } phar_set_inode(&entry); @@ -631,27 +638,29 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch return FAILURE; } - myphar->fname = pestrndup(fname, fname_len, myphar->is_persistent); + myphar->fname = zend_string_init(fname, fname_len, myphar->is_persistent); + if (myphar->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(myphar->fname); + } #ifdef PHP_WIN32 - phar_unixify_path_separators(myphar->fname, fname_len); + phar_unixify_path_separators(ZSTR_VAL(myphar->fname), ZSTR_LEN(myphar->fname)); #endif - myphar->fname_len = fname_len; myphar->fp = fp; - p = strrchr(myphar->fname, '/'); + p = strrchr(ZSTR_VAL(myphar->fname), '/'); if (p) { - myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p); + myphar->ext = memchr(p, '.', (ZSTR_VAL(myphar->fname) + ZSTR_LEN(myphar->fname)) - p); if (myphar->ext == p) { - myphar->ext = memchr(p + 1, '.', (myphar->fname + fname_len) - p - 1); + myphar->ext = memchr(p + 1, '.', (ZSTR_VAL(myphar->fname) + ZSTR_LEN(myphar->fname)) - p - 1); } if (myphar->ext) { - myphar->ext_len = (myphar->fname + fname_len) - myphar->ext; + myphar->ext_len = (ZSTR_VAL(myphar->fname) + ZSTR_LEN(myphar->fname)) - myphar->ext; } } phar_request_initialize(); - if (NULL == (actual = zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), myphar->fname, fname_len, myphar))) { + if (NULL == (actual = zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), myphar->fname, myphar))) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\" to phar registry", fname); } @@ -663,40 +672,37 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch myphar = actual; if (actual_alias) { - phar_archive_data *fd_ptr; - myphar->is_temporary_alias = 0; - - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, myphar->alias_len)) { + phar_archive_data *fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), myphar->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), myphar->fname); return FAILURE; } } zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, myphar->alias_len, myphar); } else { - phar_archive_data *fd_ptr; - - if (alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { + if (alias) { + phar_archive_data *fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), myphar->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), myphar->fname); return FAILURE; } } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, myphar); - myphar->alias = pestrndup(alias, alias_len, myphar->is_persistent); - myphar->alias_len = alias_len; + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, myphar); + myphar->alias = pestrndup(ZSTR_VAL(alias), ZSTR_LEN(alias), myphar->is_persistent); + myphar->alias_len = ZSTR_LEN(alias); } else { - myphar->alias = pestrndup(myphar->fname, fname_len, myphar->is_persistent); - myphar->alias_len = fname_len; + myphar->alias = pestrndup(ZSTR_VAL(myphar->fname), ZSTR_LEN(myphar->fname), myphar->is_persistent); + myphar->alias_len = ZSTR_LEN(myphar->fname); } myphar->is_temporary_alias = 1; @@ -708,7 +714,6 @@ zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, ch return SUCCESS; } -/* }}} */ struct _phar_pass_tar_info { php_stream *old; @@ -730,7 +735,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* } if (entry->is_deleted) { - if (entry->fp_refcount <= 0) { + if (phar_entry_can_remove(entry)) { return ZEND_HASH_APPLY_REMOVE; } else { /* we can't delete this in-memory until it is closed */ @@ -745,7 +750,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* char *boundary; if (ZSTR_LEN(entry->filename) > 256) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -755,7 +760,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* } if (!*boundary || ((boundary - ZSTR_VAL(entry->filename)) > 155)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -769,14 +774,14 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* if (FAILURE == phar_tar_octal(header.size, entry->uncompressed_filesize, sizeof(header.size)-1)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too large for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too large for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } if (FAILURE == phar_tar_octal(header.mtime, entry->timestamp, sizeof(header.mtime)-1)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, file modification time of file \"%s\" is too large for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, file modification time of file \"%s\" is too large for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -784,10 +789,10 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* /* calc checksum */ header.typeflag = entry->tar_type; - if (entry->link) { - if (strlcpy(header.linkname, entry->link, sizeof(header.linkname)) >= sizeof(header.linkname)) { + if (entry->symlink) { + if (strlcpy(header.linkname, ZSTR_VAL(entry->symlink), sizeof(header.linkname)) >= sizeof(header.linkname)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, link \"%s\" is too long for format", entry->phar->fname, entry->link); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, link \"%s\" is too long for format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->symlink)); } return ZEND_HASH_APPLY_STOP; } @@ -800,7 +805,7 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* if (FAILURE == phar_tar_octal(header.checksum, entry->crc32, sizeof(header.checksum)-1)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, checksum of file \"%s\" is too large for tar file format", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, checksum of file \"%s\" is too large for tar file format", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -808,9 +813,9 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* /* write header */ entry->header_offset = php_stream_tell(fp->new); - if (sizeof(header) != php_stream_write(fp->new, (char *) &header, sizeof(header))) { + if (sizeof(header) != php_stream_write(fp->new, (const char *) &header, sizeof(header))) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, header for file \"%s\" could not be written", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, header for file \"%s\" could not be written", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -819,20 +824,20 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* /* write contents */ if (entry->uncompressed_filesize) { - if (FAILURE == phar_open_entry_fp(entry, fp->error, 0)) { + if (FAILURE == phar_open_entry_fp(entry, fp->error, false)) { return ZEND_HASH_APPLY_STOP; } - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written, seek failed", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written, seek failed", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, 0), fp->new, entry->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, false), fp->new, entry->uncompressed_filesize, NULL)) { if (fp->error) { - spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", entry->phar->fname, ZSTR_VAL(entry->filename)); + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, contents of file \"%s\" could not be written", ZSTR_VAL(entry->phar->fname), ZSTR_VAL(entry->filename)); } return ZEND_HASH_APPLY_STOP; } @@ -841,14 +846,14 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /* php_stream_write(fp->new, padding, ((entry->uncompressed_filesize +511)&~511) - entry->uncompressed_filesize); } - if (!entry->is_modified && entry->fp_refcount) { + if (entry->fp_refcount) { /* open file pointers refer to this fp, do not free the stream */ switch (entry->fp_type) { case PHAR_FP: - fp->free_fp = 0; + fp->free_fp = false; break; case PHAR_UFP: - fp->free_ufp = 0; + fp->free_ufp = false; default: break; } @@ -877,7 +882,7 @@ static int phar_tar_writeheaders(zval *zv, void *argument) /* {{{ */ } /* }}} */ -static int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry_info *entry, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL static int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry_info *entry, char **error) /* {{{ */ { /* Copy the metadata from tracker to the new entry being written out to temporary files */ const zend_string *serialized_str; @@ -897,7 +902,7 @@ static int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry entry->fp = php_stream_fopen_tmpfile(); entry->offset = entry->offset_abs = 0; if (entry->fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); + *error = estrdup("phar error: unable to create temporary file"); return -1; } if (serialized_str && ZSTR_LEN(serialized_str) != php_stream_write(entry->fp, ZSTR_VAL(serialized_str), ZSTR_LEN(serialized_str))) { @@ -910,11 +915,11 @@ static int phar_tar_setmetadata(const phar_metadata_tracker *tracker, phar_entry } /* }}} */ -static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */ { - struct _phar_pass_tar_info *i = (struct _phar_pass_tar_info *)argument; + const struct _phar_pass_tar_info *i = (struct _phar_pass_tar_info *)argument; char **error = i->error; - phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv), *metadata, newentry = {0}; + phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv), newentry = {0}; if (zend_string_starts_with_literal(entry->filename, ".phar/.metadata")) { if (zend_string_equals_literal(entry->filename, ".phar/.metadata.bin")) { @@ -942,7 +947,8 @@ static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */ return ZEND_HASH_APPLY_KEEP; } - if (NULL != (metadata = zend_hash_find_ptr(&entry->phar->manifest, lookfor))) { + phar_entry_info *metadata = zend_hash_find_ptr(&entry->phar->manifest, lookfor); + if (metadata) { int ret; ret = phar_tar_setmetadata(&entry->metadata_tracker, metadata, error); zend_string_efree(lookfor); @@ -954,7 +960,8 @@ static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */ newentry.tar_type = TAR_FILE; newentry.is_tar = 1; - if (NULL == (metadata = zend_hash_add_mem(&entry->phar->manifest, lookfor, &newentry, sizeof(phar_entry_info)))) { + metadata = zend_hash_add_mem(&entry->phar->manifest, lookfor, &newentry, sizeof(phar_entry_info)); + if (!metadata) { zend_string_efree(lookfor); spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for file \"%s\"", ZSTR_VAL(entry->filename)); return ZEND_HASH_APPLY_STOP; @@ -964,7 +971,7 @@ static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */ } /* }}} */ -void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */ { static const char newstub[] = "is_persistent) { - if (error) { - spprintf(error, 0, "internal error: attempt to flush cached tar-based phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "internal error: attempt to flush cached tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } if (phar->is_data) { @@ -1002,15 +1006,13 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def if (!phar->is_temporary_alias && phar->alias_len) { entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return; + *error = estrdup("phar error: unable to create temporary file"); + return EOF; } if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) { - if (error) { - spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname); - } + spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); php_stream_close(entry.fp); - return; + return EOF; } entry.uncompressed_filesize = phar->alias_len; @@ -1028,10 +1030,8 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), sizeof(halt_stub) - 1); if (pos == NULL) { - if (error) { - spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } size_t len = pos - ZSTR_VAL(user_stub) + strlen(halt_stub); @@ -1040,8 +1040,8 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return; + *error = estrdup("phar error: unable to create temporary file"); + return EOF; } entry.uncompressed_filesize = len + end_sequence_len; @@ -1049,11 +1049,9 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def len != php_stream_write(entry.fp, ZSTR_VAL(user_stub), len) || end_sequence_len != php_stream_write(entry.fp, end_sequence, end_sequence_len) ) { - if (error) { - spprintf(error, 0, "unable to create stub from string in new tar-based phar \"%s\"", phar->fname); - } + spprintf(error, 0, "unable to create stub from string in new tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); php_stream_close(entry.fp); - return; + return EOF; } entry.filename = ZSTR_INIT_LITERAL(".phar/stub.php", false); @@ -1062,15 +1060,14 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def /* Either this is a brand new phar (add the stub), or the default stub is required (overwrite the stub) */ entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return; + *error = estrdup("phar error: unable to create temporary file"); + return EOF; } if (sizeof(newstub)-1 != php_stream_write(entry.fp, newstub, sizeof(newstub)-1)) { php_stream_close(entry.fp); - if (error) { - spprintf(error, 0, "unable to %s stub in%star-based phar \"%s\", failed", user_stub ? "overwrite" : "create", user_stub ? " " : " new ", phar->fname); - } - return; + spprintf(error, 0, "unable to %s stub in%star-based phar \"%s\", failed", + user_stub ? "overwrite" : "create", user_stub ? " " : " new ", ZSTR_VAL(phar->fname)); + return EOF; } entry.uncompressed_filesize = entry.compressed_filesize = sizeof(newstub) - 1; @@ -1081,10 +1078,8 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def if (NULL == zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info))) { php_stream_close(entry.fp); zend_string_efree(entry.filename); - if (error) { - spprintf(error, 0, "unable to create stub in tar-based phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "unable to create stub in tar-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } } else { php_stream_close(entry.fp); @@ -1100,35 +1095,33 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def must_close_old_file = false; php_stream_rewind(oldfile); } else { - oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL); + oldfile = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", 0, NULL); must_close_old_file = oldfile != NULL; } newfile = php_stream_fopen_tmpfile(); if (!newfile) { - if (error) { - spprintf(error, 0, "unable to create temporary file"); - } + *error = estrdup("unable to create temporary file"); if (must_close_old_file) { php_stream_close(oldfile); } - return; + return EOF; } pass.old = oldfile; pass.new = newfile; pass.error = error; - pass.free_fp = 1; - pass.free_ufp = 1; + pass.free_fp = true; + pass.free_ufp = true; if (phar_metadata_tracker_has_data(&phar->metadata_tracker, phar->is_persistent)) { - phar_entry_info *mentry; - if (NULL != (mentry = zend_hash_str_find_ptr(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1))) { + phar_entry_info *mentry = zend_hash_str_find_ptr(&(phar->manifest), ZEND_STRL(".phar/.metadata.bin")); + if (mentry) { if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(&phar->metadata_tracker, mentry, error)) { if (must_close_old_file) { php_stream_close(oldfile); } - return; + return EOF; } } else { phar_entry_info newentry = {0}; @@ -1138,13 +1131,14 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def newentry.tar_type = TAR_FILE; newentry.is_tar = 1; - if (NULL == (mentry = zend_hash_add_mem(&phar->manifest, newentry.filename, &newentry, sizeof(phar_entry_info)))) { + mentry = zend_hash_add_mem(&phar->manifest, newentry.filename, &newentry, sizeof(phar_entry_info)); + if (!mentry) { zend_string_efree(newentry.filename); - spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for phar archive \"%s\"", phar->fname); + spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for phar archive \"%s\"", ZSTR_VAL(phar->fname)); if (must_close_old_file) { php_stream_close(oldfile); } - return; + return EOF; } if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(&phar->metadata_tracker, mentry, error)) { @@ -1152,46 +1146,61 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def if (must_close_old_file) { php_stream_close(oldfile); } - return; + return EOF; } } } zend_hash_apply_with_argument(&phar->manifest, phar_tar_setupmetadata, (void *) &pass); - if (error && *error) { + if (*error) { if (must_close_old_file) { php_stream_close(oldfile); } /* on error in the hash iterator above, error is set */ php_stream_close(newfile); - return; + return EOF; } zend_hash_apply_with_argument(&phar->manifest, phar_tar_writeheaders, (void *) &pass); + if (*error) { + if (must_close_old_file) { + php_stream_close(oldfile); + } + + /* on error in the hash iterator above, error is set */ + php_stream_close(newfile); + return EOF; + } + /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */ if (!phar->is_data || phar->sig_flags) { - if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, error)) { - if (error) { - char *save = *error; - spprintf(error, 0, "phar error: unable to write signature to tar-based phar: %s", save); - efree(save); - } + char *signature_error = NULL; + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { + spprintf(error, 0, "phar error: unable to write signature to tar-based phar: %s", signature_error); + efree(signature_error); if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - return; + return EOF; } entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return; + *error = estrdup("phar error: unable to create temporary file"); + + zend_string_release_ex(signature, false); + if (must_close_old_file) { + php_stream_close(oldfile); + } + php_stream_close(newfile); + return EOF; } #ifdef WORDS_BIGENDIAN # define PHAR_SET_32(destination, source) do { \ @@ -1205,36 +1214,34 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def # define PHAR_SET_32(destination, source) memcpy(destination, &source, 4) #endif PHAR_SET_32(sigbuf, phar->sig_flags); - PHAR_SET_32(sigbuf + 4, signature_length); + PHAR_SET_32(sigbuf + 4, ZSTR_LEN(signature)); - if (8 != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) { - efree(signature); - if (error) { - spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", phar->fname); - } + if (8 != php_stream_write(entry.fp, sigbuf, 8) || ZSTR_LEN(signature) != php_stream_write(entry.fp, ZSTR_VAL(signature), ZSTR_LEN(signature))) { + zend_string_release_ex(signature, false); + spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", ZSTR_VAL(phar->fname)); if (must_close_old_file) { php_stream_close(oldfile); } php_stream_close(newfile); - return; + return EOF; } ALLOCA_FLAG(use_heap); ZSTR_ALLOCA_INIT(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1, use_heap); - efree(signature); - entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8; + entry.uncompressed_filesize = entry.compressed_filesize = ZSTR_LEN(signature) + 8; /* throw out return value and write the signature */ phar_tar_writeheaders_int(&entry, &pass); ZSTR_ALLOCA_FREE(entry.filename, use_heap); + zend_string_release_ex(signature, false); - if (error && *error) { + if (*error) { if (must_close_old_file) { php_stream_close(oldfile); } /* error is set by writeheaders */ php_stream_close(newfile); - return; + return EOF; } } /* signature */ @@ -1247,12 +1254,6 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def php_stream_close(oldfile); } - /* on error in the hash iterator above, error is set */ - if (error && *error) { - php_stream_close(newfile); - return; - } - if (phar->fp && pass.free_fp) { php_stream_close(phar->fp); } @@ -1271,13 +1272,11 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def /* deferred flush */ phar->fp = newfile; } else { - phar->fp = php_stream_open_wrapper(phar->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); + phar->fp = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (!phar->fp) { phar->fp = newfile; - if (error) { - spprintf(error, 0, "unable to open new phar \"%s\" for writing", phar->fname); - } - return; + spprintf(error, 0, "unable to open new phar \"%s\" for writing", ZSTR_VAL(phar->fname)); + return EOF; } if (phar->flags & PHAR_FILE_COMPRESSED_GZ) { @@ -1298,10 +1297,8 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def /* copy contents uncompressed rather than lose them */ php_stream_copy_to_stream_ex(newfile, phar->fp, PHP_STREAM_COPY_ALL, NULL); php_stream_close(newfile); - if (error) { - spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", phar->fname); - } - return; + spprintf(error, 4096, "unable to compress all contents of phar \"%s\" using zlib, PHP versions older than 5.2.6 have a buggy zlib", ZSTR_VAL(phar->fname)); + return EOF; } php_stream_filter_append(&phar->fp->writefilters, filter); @@ -1328,5 +1325,6 @@ void phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def php_stream_close(newfile); } } + return 0; } /* }}} */ diff --git a/ext/phar/tar.h b/ext/phar/tar.h index 55ce5501eeb1..80e4586e8db9 100644 --- a/ext/phar/tar.h +++ b/ext/phar/tar.h @@ -4,15 +4,13 @@ +----------------------------------------------------------------------+ | TAR archive support for Phar | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Dmitry Stogov | | Gregory Beaver | diff --git a/ext/phar/tests/022.phpt b/ext/phar/tests/022.phpt index 5363a65be942..c484c4d3c06d 100644 --- a/ext/phar/tests/022.phpt +++ b/ext/phar/tests/022.phpt @@ -80,28 +80,28 @@ int(1) fseek($fp, -1, SEEK_END)int(0) int(6) fseek($fp, -8, SEEK_END)int(-1) -bool(false) +int(6) fseek($fp, -7, SEEK_END)int(0) int(0) fseek($fp, 0, SEEK_END)int(0) int(7) fseek($fp, 1, SEEK_END)int(-1) -bool(false) +int(7) fseek($fp, -8, SEEK_END)int(-1) -bool(false) +int(7) fseek($fp, 6)int(0) int(6) fseek($fp, 8)int(-1) -bool(false) +int(6) fseek($fp, -1)int(-1) -bool(false) +int(6) next int(4) fseek($fp, -5, SEEK_CUR)int(-1) -bool(false) +int(4) int(4) fseek($fp, 5, SEEK_CUR)int(-1) -bool(false) +int(4) int(4) fseek($fp, -4, SEEK_CUR)int(0) int(0) diff --git a/ext/phar/tests/SplFileInfo_openFile_write.phpt b/ext/phar/tests/SplFileInfo_openFile_write.phpt new file mode 100644 index 000000000000..f63baf5c7ad1 --- /dev/null +++ b/ext/phar/tests/SplFileInfo_openFile_write.phpt @@ -0,0 +1,31 @@ +--TEST-- +SplFileInfo::openFile() in write mode +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--FILE-- +addFromString('test', 'contents'); +var_dump($phar['test']->openFile('w')); + +?> +--CLEAN-- + +--EXPECTF-- +object(SplFileObject)#%d (%d) { + ["pathName":"SplFileInfo":private]=> + string(%d) "phar://%stest" + ["fileName":"SplFileInfo":private]=> + string(4) "test" + ["openMode":"SplFileObject":private]=> + string(1) "w" + ["delimiter":"SplFileObject":private]=> + string(1) "," + ["enclosure":"SplFileObject":private]=> + string(1) """ +} diff --git a/ext/phar/tests/bug74154.phpt b/ext/phar/tests/bug74154.phpt new file mode 100644 index 000000000000..ab3836ce87d4 --- /dev/null +++ b/ext/phar/tests/bug74154.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #74154 (Phar extractTo creates empty files) +--EXTENSIONS-- +phar +zlib +--FILE-- +buildFromDirectory($dir); + +$compPhar = $phar->compress(Phar::GZ); +unset($phar); //make sure that test.tar is closed +unlink(__DIR__.'/bug74154.tar'); +unset($compPhar); //make sure that test.tar.gz is closed +$extractingPhar = new PharData(__DIR__.'/bug74154.tar.gz'); +$extractingPhar->extractTo($dir.'_out'); + +var_dump(file_get_contents($dir.'_out/1.txt')); +var_dump(file_get_contents($dir.'_out/2.txt')); + +?> +--CLEAN-- + +--EXPECT-- +string(64) "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" +string(64) "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" diff --git a/ext/phar/tests/bug77432.phpt b/ext/phar/tests/bug77432.phpt index b3b927a5439d..86a07fe99a4e 100644 --- a/ext/phar/tests/bug77432.phpt +++ b/ext/phar/tests/bug77432.phpt @@ -21,8 +21,6 @@ unset($phar); echo "--- Include 1 ---\n"; include("phar://" . $filename); echo "--- Include 2 ---\n"; -// Note: will warn because the halting offset is redefined, but won't display the name because "zend_mangle_property_name" starts the name with \0 -// However, this is just the easiest way to reproduce it, so go with this test. include("phar://" . $filename); echo "--- After unlink ---\n"; unlink($filename); @@ -38,8 +36,6 @@ include("phar://" . $filename); --- Include 1 --- hello world --- Include 2 --- - -Warning: Constant already defined in %s on line %d hello world --- After unlink --- diff --git a/ext/phar/tests/buildFromIterator_user_overrides/getMTime.phpt b/ext/phar/tests/buildFromIterator_user_overrides/getMTime.phpt new file mode 100644 index 000000000000..eefe352a0cbb --- /dev/null +++ b/ext/phar/tests/buildFromIterator_user_overrides/getMTime.phpt @@ -0,0 +1,81 @@ +--TEST-- +buildFromIterator with user overrides - getMTime() +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--CREDITS-- +Arne Blankerts +N. Dossche +--FILE-- +getPathname() . " ]\n"; + return new MySplFileInfo(parent::current()->getPathname()); + } +} + +$workdir = __DIR__.'/getMTime'; +mkdir($workdir . '/content', recursive: true); +file_put_contents($workdir . '/content/hello.txt', "Hello world."); + +$phar = new \Phar($workdir . '/test.phar'); +$phar->startBuffering(); +$phar->buildFromIterator( + new RecursiveIteratorIterator( + new MyIterator($workdir . '/content', FilesystemIterator::SKIP_DOTS) + ), + $workdir +); +$phar->stopBuffering(); + + +$result = new \Phar($workdir . '/test.phar', 0, 'test.phar'); +var_dump($result['content/hello.txt']); +var_dump($result['content/hello.txt']->getATime()); +var_dump($result['content/hello.txt']->getMTime()); +var_dump($result['content/hello.txt']->getCTime()); + +?> +--CLEAN-- + +--EXPECTF-- +[ Found: %shello.txt ] +[MTime] +object(PharFileInfo)#%d (2) { + ["pathName":"SplFileInfo":private]=> + string(%d) "phar://%shello.txt" + ["fileName":"SplFileInfo":private]=> + string(%d) "hello.txt" +} +int(123) +int(123) +int(123) diff --git a/ext/phar/tests/buildFromIterator_user_overrides/getMTime_byRef.phpt b/ext/phar/tests/buildFromIterator_user_overrides/getMTime_byRef.phpt new file mode 100644 index 000000000000..a7f81709a34e --- /dev/null +++ b/ext/phar/tests/buildFromIterator_user_overrides/getMTime_byRef.phpt @@ -0,0 +1,70 @@ +--TEST-- +buildFromIterator with user overrides - getMTime() by ref +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--CREDITS-- +Arne Blankerts +N. Dossche +--FILE-- +getPathname() . " ]\n"; + return new MySplFileInfo(parent::current()->getPathname()); + } +} + +$workdir = __DIR__.'/getMTime_byRef'; +mkdir($workdir . '/content', recursive: true); +file_put_contents($workdir . '/content/hello.txt', "Hello world."); + +$phar = new \Phar($workdir . '/test.phar'); +$phar->startBuffering(); +$phar->buildFromIterator( + new RecursiveIteratorIterator( + new MyIterator($workdir . '/content', FilesystemIterator::SKIP_DOTS) + ), + $workdir +); +$phar->stopBuffering(); + + +$result = new \Phar($workdir . '/test.phar', 0, 'test.phar'); +var_dump($result['content/hello.txt']); +var_dump($result['content/hello.txt']->getATime()); +var_dump($result['content/hello.txt']->getMTime()); +var_dump($result['content/hello.txt']->getCTime()); + +?> +--CLEAN-- + +--EXPECTF-- +[ Found: %shello.txt ] +[MTime] +object(PharFileInfo)#%d (2) { + ["pathName":"SplFileInfo":private]=> + string(%d) "phar://%shello.txt" + ["fileName":"SplFileInfo":private]=> + string(%d) "hello.txt" +} +int(123) +int(123) +int(123) diff --git a/ext/phar/tests/buildFromIterator_user_overrides/getMTime_errors.phpt b/ext/phar/tests/buildFromIterator_user_overrides/getMTime_errors.phpt new file mode 100644 index 000000000000..f43a7a496a76 --- /dev/null +++ b/ext/phar/tests/buildFromIterator_user_overrides/getMTime_errors.phpt @@ -0,0 +1,117 @@ +--TEST-- +buildFromIterator with user overrides - errors in getMTime() +--EXTENSIONS-- +phar +--SKIPIF-- + +--INI-- +phar.readonly=0 +phar.require_hash=0 +--CREDITS-- +Arne Blankerts +N. Dossche +--FILE-- +getPathname() . " ]\n"; + if ($counter === 1) { + return new MySplFileInfo1(parent::current()->getPathname()); + } else if ($counter === 2) { + return new MySplFileInfo2(parent::current()->getPathname()); + } else if ($counter === 3) { + return new MySplFileInfo3(parent::current()->getPathname()); + } else if ($counter === 4) { + return new MySplFileInfo4(parent::current()->getPathname()); + } + } +} + +$workdir = __DIR__.'/getMTime_errors'; +mkdir($workdir . '/content', recursive: true); +file_put_contents($workdir . '/content/hello.txt', "Hello world."); + +for ($i = 0; $i < 4; $i++) { + echo "--- Iteration $i ---\n"; + try { + $phar = new \Phar($workdir . "/test$i.phar"); + $phar->startBuffering(); + $phar->buildFromIterator( + new RecursiveIteratorIterator( + new MyIterator($workdir . '/content', FilesystemIterator::SKIP_DOTS) + ), + $workdir + ); + $phar->stopBuffering(); + } catch (Throwable $e) { + echo $e->getMessage(), "\n"; + if ($previous = $e->getPrevious()) { + echo "Previous: ", $previous->getMessage(), "\n"; + } + } +} + +?> +--CLEAN-- + +--EXPECTF-- +--- Iteration 0 --- +[ Found: %shello.txt ] +[MTime] +Entry content%chello.txt cannot be created: timestamp is limited to 32-bit +--- Iteration 1 --- +[ Found: %shello.txt ] +[MTime] +Entry content%chello.txt cannot be created: getMTime() must return an int +--- Iteration 2 --- +[ Found: %shello.txt ] +[MTime] +Entry content%chello.txt cannot be created: getMTime() must return an int +Previous: Throwing an exception inside getMTime() +--- Iteration 3 --- +[ Found: %shello.txt ] +[MTime] +Entry content%chello.txt cannot be created: getMTime() must return an int diff --git a/ext/phar/tests/buildFromIterator_user_overrides/getPathname.phpt b/ext/phar/tests/buildFromIterator_user_overrides/getPathname.phpt new file mode 100644 index 000000000000..144eed1d874a --- /dev/null +++ b/ext/phar/tests/buildFromIterator_user_overrides/getPathname.phpt @@ -0,0 +1,67 @@ +--TEST-- +buildFromIterator with user overrides - getPathname() +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--CREDITS-- +Arne Blankerts +N. Dossche +--FILE-- +getPathname() . " ]\n"; + return new MyGlobIterator(parent::current()->getPath() . '/*'); + } +} + +$workdir = __DIR__.'/getPathname'; +mkdir($workdir . '/content', recursive: true); +file_put_contents($workdir . '/content/hello1.txt', "Hello world 1."); +file_put_contents($workdir . '/content/hello2.txt', "Hello world 2."); + +$phar = new \Phar($workdir . "/test.phar"); +$phar->startBuffering(); +$phar->buildFromIterator( + new RecursiveIteratorIterator( + new MyIterator($workdir . '/content', FilesystemIterator::SKIP_DOTS) + ), + $workdir +); +$phar->stopBuffering(); + +$result = new \Phar($workdir . '/test.phar', 0, 'test.phar'); +var_dump(isset($result['content/hello1.txt'])); +var_dump(isset($result['content/hello2.txt'])); + +?> +--CLEAN-- + +--EXPECTF-- +[ Found: %shello%d.txt ] +[getPathname] +string(%d) "%shello1.txt" +[ Found: %shello%d.txt ] +[getPathname] +string(%d) "%shello1.txt" +bool(false) +bool(true) diff --git a/ext/phar/tests/buildFromIterator_user_overrides/getPathname_byRef.phpt b/ext/phar/tests/buildFromIterator_user_overrides/getPathname_byRef.phpt new file mode 100644 index 000000000000..0ae2946ce1ad --- /dev/null +++ b/ext/phar/tests/buildFromIterator_user_overrides/getPathname_byRef.phpt @@ -0,0 +1,58 @@ +--TEST-- +buildFromIterator with user overrides - getPathname() by ref +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--CREDITS-- +Arne Blankerts +N. Dossche +--FILE-- +getPathname() . " ]\n"; + return new MyGlobIterator(parent::current()->getPath() . '/*'); + } +} + +$workdir = __DIR__.'/getPathname_byRef'; +mkdir($workdir . '/content', recursive: true); +file_put_contents($workdir . '/content/hello.txt', "Hello world 1."); + +$phar = new \Phar($workdir . "/test.phar"); +$phar->startBuffering(); +$phar->buildFromIterator( + new RecursiveIteratorIterator( + new MyIterator($workdir . '/content', FilesystemIterator::SKIP_DOTS) + ), + $workdir +); +$phar->stopBuffering(); + +$result = new \Phar($workdir . '/test.phar', 0, 'test.phar'); +var_dump(isset($result['content/hello.txt'])); + +?> +--CLEAN-- + +--EXPECTF-- +[ Found: %scontent%chello.txt ] +[getPathname] +bool(true) diff --git a/ext/phar/tests/buildFromIterator_user_overrides/getPathname_exception.phpt b/ext/phar/tests/buildFromIterator_user_overrides/getPathname_exception.phpt new file mode 100644 index 000000000000..86b66050a973 --- /dev/null +++ b/ext/phar/tests/buildFromIterator_user_overrides/getPathname_exception.phpt @@ -0,0 +1,63 @@ +--TEST-- +buildFromIterator with user overrides - exception in getPathname() +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--CREDITS-- +Arne Blankerts +N. Dossche +--FILE-- +getPathname() . " ]\n"; + return new MyGlobIterator(parent::current()->getPath() . '/*'); + } +} + +$workdir = __DIR__.'/getPathname_exception'; +mkdir($workdir . '/content', recursive: true); +file_put_contents($workdir . '/content/hello.txt', "Hello world."); + +$phar = new \Phar($workdir . "/test.phar"); +$phar->startBuffering(); +try { + $phar->buildFromIterator( + new RecursiveIteratorIterator( + new MyIterator($workdir . '/content', FilesystemIterator::SKIP_DOTS) + ), + $workdir + ); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; + if ($previous = $e->getPrevious()) { + echo "Previous: ", $previous->getMessage(), "\n"; + } +} +$phar->stopBuffering(); + +?> +--CLEAN-- + +--EXPECTF-- +[ Found: %shello.txt ] +[getPathname] +string(%d) "%shello.txt" +getPathname() must return a string +Previous: exception in getPathname() diff --git a/ext/phar/tests/buildFromIterator_user_overrides/getPathname_wrong_type.phpt b/ext/phar/tests/buildFromIterator_user_overrides/getPathname_wrong_type.phpt new file mode 100644 index 000000000000..dfb3fb5f2c55 --- /dev/null +++ b/ext/phar/tests/buildFromIterator_user_overrides/getPathname_wrong_type.phpt @@ -0,0 +1,58 @@ +--TEST-- +buildFromIterator with user overrides - wrong return type in getPathname() +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--CREDITS-- +Arne Blankerts +N. Dossche +--FILE-- +getPathname() . " ]\n"; + return new MyGlobIterator(parent::current()->getPath() . '/*'); + } +} + +$workdir = __DIR__.'/getPathname_wrong_type'; +mkdir($workdir . '/content', recursive: true); +file_put_contents($workdir . '/content/hello.txt', "Hello world."); + +$phar = new \Phar($workdir . "/test.phar"); +$phar->startBuffering(); +try { + $phar->buildFromIterator( + new RecursiveIteratorIterator( + new MyIterator($workdir . '/content', FilesystemIterator::SKIP_DOTS) + ), + $workdir + ); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +$phar->stopBuffering(); + +?> +--CLEAN-- + +--EXPECTF-- +[ Found: %scontent%chello.txt ] +[getPathname] +getPathname() must return a string diff --git a/ext/phar/tests/cache_list/copyonwrite11.phar.phpt b/ext/phar/tests/cache_list/copyonwrite11.phar.phpt index a52b8e5fed3f..d51135894494 100644 --- a/ext/phar/tests/cache_list/copyonwrite11.phar.phpt +++ b/ext/phar/tests/cache_list/copyonwrite11.phar.phpt @@ -18,5 +18,5 @@ echo strlen($p2->getStub()),"\n"; echo "ok\n"; __HALT_COMPILER(); ?> " -6643 +6661 ok diff --git a/ext/phar/tests/cache_list/files/phar_test.inc b/ext/phar/tests/cache_list/files/phar_test.inc index bae9415aac4a..b30b2f2fce39 100644 --- a/ext/phar/tests/cache_list/files/phar_test.inc +++ b/ext/phar/tests/cache_list/files/phar_test.inc @@ -2,7 +2,7 @@ date_default_timezone_set('UTC'); -$manifest = (binary)''; +$manifest = ''; $glags = 0; foreach($files as $name => $cont) @@ -34,12 +34,12 @@ foreach($files as $name => $cont) if (empty($comp)) $comp = $cont; if (empty($ulen)) $ulen = strlen($cont); if (empty($clen)) $clen = strlen($comp); - if (empty($crc32))$crc32= crc32((binary)$cont); + if (empty($crc32))$crc32= crc32($cont); if (isset($meta)) $meta = serialize($meta); // write manifest entry - $manifest .= pack('V', strlen($name)) . (binary)$name; - $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . (binary)$meta; + $manifest .= pack('V', strlen($name)) . $name; + $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . $meta; // globals $gflags |= $flags; @@ -50,13 +50,13 @@ if (!isset($alias)) $alias = 'hio'; if (isset($pmeta)) $pmeta = serialize($pmeta); else $pmeta = ''; -$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . (binary)$alias . pack('V', strlen($pmeta)) . (binary)$pmeta . $manifest; -$file = (binary)$file; +$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . $alias . pack('V', strlen($pmeta)) . $pmeta . $manifest; +$file = $file; $file .= pack('V', strlen($manifest)) . $manifest; foreach($files as $cont) { - $file .= (binary)$cont; + $file .= $cont; } file_put_contents($fname, $file); diff --git a/ext/phar/tests/fflush_phar_file_report_success.phpt b/ext/phar/tests/fflush_phar_file_report_success.phpt new file mode 100644 index 000000000000..615f4e58e567 --- /dev/null +++ b/ext/phar/tests/fflush_phar_file_report_success.phpt @@ -0,0 +1,25 @@ +--TEST-- +fflush() on phar file should report success +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--FILE-- +addFromString('test', 'contents'); +unset($phar); + +$f = fopen('phar://' . __DIR__.'/fflush_phar_file_report_success.phar/test', 'w'); +var_dump(fflush($f)); +var_dump(fclose($f)); + +?> +--CLEAN-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/ext/phar/tests/files/gh20442.phar b/ext/phar/tests/files/gh20442.phar new file mode 100644 index 000000000000..26fac67ede58 Binary files /dev/null and b/ext/phar/tests/files/gh20442.phar differ diff --git a/ext/phar/tests/files/phar_oo_test.inc b/ext/phar/tests/files/phar_oo_test.inc index a6f4cee5ee65..b935346bc8ef 100644 --- a/ext/phar/tests/files/phar_oo_test.inc +++ b/ext/phar/tests/files/phar_oo_test.inc @@ -5,7 +5,7 @@ ini_set('date.timezone', 'GMT'); $tname = basename(current(get_included_files()), ".php"); $fname = dirname(__FILE__) . "/$tname.phar.php"; $pname = 'phar://' . $fname; -$file = (binary)''; +$file = ''; $files = array(); diff --git a/ext/phar/tests/files/phar_test.inc b/ext/phar/tests/files/phar_test.inc index 277271ef4c63..caf220d0b37b 100644 --- a/ext/phar/tests/files/phar_test.inc +++ b/ext/phar/tests/files/phar_test.inc @@ -2,7 +2,7 @@ date_default_timezone_set('UTC'); -$manifest = (binary)''; +$manifest = ''; $gflags = 0; foreach($files as $name => $cont) @@ -34,12 +34,12 @@ foreach($files as $name => $cont) if (empty($comp)) $comp = $cont; if (empty($ulen)) $ulen = strlen($cont); if (empty($clen)) $clen = strlen($comp); - if (empty($crc32))$crc32= crc32((binary)$cont); + if (empty($crc32))$crc32= crc32($cont); $meta = isset($meta) ? serialize($meta) : ""; // write manifest entry - $manifest .= pack('V', strlen($name)) . (binary)$name; - $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . (binary)$meta; + $manifest .= pack('V', strlen($name)) . $name; + $manifest .= pack('VVVVVV', $ulen, $time, $clen, $crc32, $flags|$perm, strlen($meta)) . $meta; // globals $gflags |= $flags; @@ -50,13 +50,13 @@ if (!isset($alias)) $alias = 'hio'; if (isset($pmeta)) $pmeta = serialize($pmeta); else $pmeta = ''; -$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . (binary)$alias . pack('V', strlen($pmeta)) . (binary)$pmeta . $manifest; -$file = (binary)$file; +$manifest = pack('VnVV', count($files), isset($hasdir) ? 0x1110 : 0x1000, $gflags, strlen($alias)) . $alias . pack('V', strlen($pmeta)) . $pmeta . $manifest; +$file = $file; $file .= pack('V', strlen($manifest)) . $manifest; foreach($files as $cont) { - $file .= (binary)$cont; + $file .= $cont; } file_put_contents($fname, $file); diff --git a/ext/phar/tests/fseek_outside_bounds.phpt b/ext/phar/tests/fseek_outside_bounds.phpt new file mode 100644 index 000000000000..0a35abb360d5 --- /dev/null +++ b/ext/phar/tests/fseek_outside_bounds.phpt @@ -0,0 +1,26 @@ +--TEST-- +Assertion failure when fseeking outside of bounds of phar file +--EXTENSIONS-- +phar +--INI-- +phar.require_hash=0 +--FILE-- +setInfoClass('SplFileObject'); +$f = $phar['a.php']; +var_dump($f->fseek(1, SEEK_SET)); +var_dump($f->fseek(999999, SEEK_SET)); +var_dump($f->fseek(999999, SEEK_CUR)); +var_dump($f->ftell()); +var_dump($f->fseek(1, SEEK_CUR)); +var_dump($f->fread(3)); +?> +--EXPECT-- +int(0) +int(-1) +int(-1) +int(1) +int(0) +string(3) "php" diff --git a/ext/phar/tests/gh17808.phpt b/ext/phar/tests/gh17808.phpt index 03e54ff264bf..a5c13a5405e2 100644 --- a/ext/phar/tests/gh17808.phpt +++ b/ext/phar/tests/gh17808.phpt @@ -5,18 +5,26 @@ phar zlib --FILE-- getContent())); -unlink("$file"); +unlink($file); var_dump($file->getATime()); ?> +--CLEAN-- + --EXPECTF-- -string(%d) "phar://%spackage.xml" +object(PharFileInfo)#%d (%d) { + ["pathName":"SplFileInfo":private]=> + string(%d) "phar://%spackage.xml" + ["fileName":"SplFileInfo":private]=> + string(11) "package.xml" +} int(6747) - -Warning: unlink(): phar error: "package.xml" in phar %s, has open file pointers, cannot unlink in %s on line %d int(33188) diff --git a/ext/phar/tests/gh18953.phpt b/ext/phar/tests/gh18953.phpt new file mode 100644 index 000000000000..ff48e457cc9f --- /dev/null +++ b/ext/phar/tests/gh18953.phpt @@ -0,0 +1,41 @@ +--TEST-- +GH-18953 (Phar: Stream double free) +--EXTENSIONS-- +phar +zlib +--INI-- +phar.readonly=0 +--FILE-- +addFromString("file", str_repeat("123", random_int(1, 1))); +$phar->addEmptyDir("dir"); +$phar2 = $phar->compress(Phar::GZ); + +var_dump($phar["dir"]); +var_dump($phar2["dir"]); +var_dump($phar["file"]->openFile()->fread(100)); +var_dump($phar2["file"]->openFile()->fread(100)); + +?> +--CLEAN-- + +--EXPECTF-- +object(PharFileInfo)#%d (2) { + ["pathName":"SplFileInfo":private]=> + string(%d) "%sphar%sdir" + ["fileName":"SplFileInfo":private]=> + string(3) "dir" +} +object(PharFileInfo)#%d (2) { + ["pathName":"SplFileInfo":private]=> + string(%d) "%sphar.gz%sdir" + ["fileName":"SplFileInfo":private]=> + string(3) "dir" +} +string(3) "123" +string(3) "123" diff --git a/ext/phar/tests/gh19038.phpt b/ext/phar/tests/gh19038.phpt new file mode 100644 index 000000000000..34eba44c1dcd --- /dev/null +++ b/ext/phar/tests/gh19038.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-19038 (Phar crash and data corruption with SplFileObject) +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--FILE-- +addFromString("file", "123"); +$file = $phar["file"]->openFile(); +$file->fseek(3); +var_dump($file->fwrite("456", 3)); +$file->fseek(0); +echo $file->fread(100); + +?> +--CLEAN-- + +--EXPECT-- +int(3) +123456 diff --git a/ext/phar/tests/gh19752.phpt b/ext/phar/tests/gh19752.phpt new file mode 100644 index 000000000000..94ee8691305e --- /dev/null +++ b/ext/phar/tests/gh19752.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-19752 (Phar decompression with invalid extension can cause UAF) +--EXTENSIONS-- +phar +--FILE-- +decompress("*"); +} catch (BadMethodCallException $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +data phar converted from "%sgh19752.1" has invalid extension * diff --git a/ext/phar/tests/gh20302.phpt b/ext/phar/tests/gh20302.phpt new file mode 100644 index 000000000000..0cbd253d54fc --- /dev/null +++ b/ext/phar/tests/gh20302.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-20302 (Freeing a phar alias may invalidate PharFileInfo objects) +--EXTENSIONS-- +phar +--INI-- +phar.require_hash=0 +--FILE-- +"; +$files = array(); +$files['here'] = 'a'; +include __DIR__.'/files/phar_test.inc'; +$b = new PharFileInfo($pname . '/here'); + +// Create new phar with same alias and open it +@mkdir(__DIR__.'/gh20302'); +$fname = __DIR__.'/gh20302/gh20302.phar'; +$pname = 'phar://' . $fname; +include __DIR__.'/files/phar_test.inc'; +try { + new Phar($fname); +} catch (UnexpectedValueException $e) { + echo $e->getMessage(), "\n"; +} +?> +--CLEAN-- + +--EXPECTF-- +Cannot open archive "%sgh20302.phar", alias is already in use by existing archive diff --git a/ext/phar/tests/gh20442.phpt b/ext/phar/tests/gh20442.phpt new file mode 100644 index 000000000000..e6862f3d33db --- /dev/null +++ b/ext/phar/tests/gh20442.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-20442 (Phar does not respect case-insensitiveness of __halt_compiler() when reading stub) +--EXTENSIONS-- +phar +--FILE-- +count()); +var_dump($phar->getStub()); + +?> +--EXPECT-- +int(1) +string(50) " +" diff --git a/ext/phar/tests/gh20732.phpt b/ext/phar/tests/gh20732.phpt new file mode 100644 index 000000000000..b938d16d42ca --- /dev/null +++ b/ext/phar/tests/gh20732.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-20732 (Phar::LoadPhar undefined behavior when loading directory) +--EXTENSIONS-- +phar +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECTF-- +%r(internal corruption of phar "%s" \(truncated entry\)|unable to open phar for reading ".")%r diff --git a/ext/phar/tests/gh20882.phpt b/ext/phar/tests/gh20882.phpt new file mode 100644 index 000000000000..8928178a22a9 --- /dev/null +++ b/ext/phar/tests/gh20882.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-20882 (phar buildFromIterator breaks with missing base directory) +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +--FILE-- +buildFromIterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator(__DIR__.'/test79082', FilesystemIterator::SKIP_DOTS) + ), + null + ); +} catch (BadMethodCallException $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Iterator RecursiveIteratorIterator returns an SplFileInfo object, so base directory must be specified diff --git a/ext/phar/tests/gh21333.phpt b/ext/phar/tests/gh21333.phpt new file mode 100644 index 000000000000..334986619c32 --- /dev/null +++ b/ext/phar/tests/gh21333.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-21333 (UAF when unlinking entries during iteration of a compressed phar) +--CREDITS-- +YuanchengJiang +--EXTENSIONS-- +phar +zlib +--INI-- +phar.readonly=0 +--FILE-- +addFromString("file", "initial_content"); +$phar->addEmptyDir("dir"); + +$phar2 = $phar->compress(Phar::GZ); + +$tmp_src = __DIR__ . "/gh21333.tmp"; +file_put_contents($tmp_src, str_repeat("A", 100)); + +foreach ($phar2 as $item) { + @copy($tmp_src, $item); + @unlink($item); +} + +$garbage = get_defined_vars(); + +echo "Done\n"; +?> +--CLEAN-- + +--EXPECT-- +Done diff --git a/ext/phar/tests/gh21797.phpt b/ext/phar/tests/gh21797.phpt new file mode 100644 index 000000000000..b24e30b7829a --- /dev/null +++ b/ext/phar/tests/gh21797.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-21797: Phar::webPhar() NULL dereference when SCRIPT_NAME absent from SAPI environment +--CGI-- +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +variables_order=EGPC +register_argc_argv=0 +cgi.fix_pathinfo=0 +--ENV-- +REQUEST_METHOD=GET +PATH_INFO=/gh21797.phar +--FILE-- +addFromString('index.php', ''); +$phar->setStub(''); +unset($phar); +include $fname; +?> +--CLEAN-- + +--EXPECT-- +no crash diff --git a/ext/phar/tests/gh21798-add-file-delref.phpt b/ext/phar/tests/gh21798-add-file-delref.phpt new file mode 100644 index 000000000000..fa893a1975e3 --- /dev/null +++ b/ext/phar/tests/gh21798-add-file-delref.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-21798: phar_add_file must call phar_entry_delref on write error paths +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('hello.txt', 'hello world'); +$phar->addFromString('empty.txt', ''); +unset($phar); + +$phar = new Phar($fname); +echo $phar['hello.txt']->getContent() . "\n"; +echo ($phar->offsetExists('empty.txt') ? 'empty exists' : 'missing') . "\n"; +echo "no crash\n"; +?> +--CLEAN-- + +--EXPECT-- +hello world +empty exists +no crash diff --git a/ext/phar/tests/gh21798-offsetget-temp-entry.phpt b/ext/phar/tests/gh21798-offsetget-temp-entry.phpt new file mode 100644 index 000000000000..b5b11ad43634 --- /dev/null +++ b/ext/phar/tests/gh21798-offsetget-temp-entry.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-21798: Phar::offsetGet() must free is_temp_dir entry before rejecting .phar/* paths +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('index.php', ''); +unset($phar); + +$phar = new Phar($fname); +try { + $phar->offsetGet('.phar/stub.php'); +} catch (BadMethodCallException $e) { + echo $e->getMessage() . "\n"; +} +try { + $phar->offsetGet('.phar/alias.txt'); +} catch (BadMethodCallException $e) { + echo $e->getMessage() . "\n"; +} +try { + $phar->offsetGet('.phar/internal'); +} catch (BadMethodCallException $e) { + echo $e->getMessage() . "\n"; +} +echo "no crash\n"; +?> +--CLEAN-- + +--EXPECT-- +Entry .phar/stub.php does not exist +Entry .phar/alias.txt does not exist +Entry .phar/internal does not exist +no crash diff --git a/ext/phar/tests/gh21799-stream-close-flush.phpt b/ext/phar/tests/gh21799-stream-close-flush.phpt new file mode 100644 index 000000000000..aaa6c17fac38 --- /dev/null +++ b/ext/phar/tests/gh21799-stream-close-flush.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21799: phar_stream_close propagates phar_stream_flush return value +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('hello.txt', 'hello'); +unset($phar); + +$fp = fopen('phar://' . $fname . '/hello.txt', 'rb'); +$content = fread($fp, 1024); +$result = fclose($fp); + +echo $content . "\n"; +var_dump($result); +echo "no crash\n"; +?> +--CLEAN-- + +--EXPECT-- +hello +bool(true) +no crash diff --git a/ext/phar/tests/invalid_string_phar_mungserver.phpt b/ext/phar/tests/invalid_string_phar_mungserver.phpt new file mode 100644 index 000000000000..8128987dacbc --- /dev/null +++ b/ext/phar/tests/invalid_string_phar_mungserver.phpt @@ -0,0 +1,17 @@ +--TEST-- +Passing invalid string to Phar::mungServer() +--EXTENSIONS-- +phar +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +Invalid value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME diff --git a/ext/phar/tests/mkdir.phpt b/ext/phar/tests/mkdir.phpt index 1ffdc7fe252d..2c1586b0de5c 100644 --- a/ext/phar/tests/mkdir.phpt +++ b/ext/phar/tests/mkdir.phpt @@ -24,6 +24,13 @@ $a->addEmptyDir('.phar'); } catch (Exception $e) { echo $e->getMessage(),"\n"; } +try { +$a->addEmptyDir('/.phar'); +} catch (Exception $e) { +echo $e->getMessage(),"\n"; +} +$a->addEmptyDir('/.pharx'); +var_dump(is_dir($pname . '/.pharx')); ?> --CLEAN-- +--INI-- +phar.require_hash=0 +--FILE-- +setSignatureAlgorithm(Phar::OPENSSL, "randomcrap"); +try { + $phar->addEmptyDir('blah'); +} catch (PharException $e) { + echo $e->getMessage(); +} + +?> +--CLEAN-- + +--EXPECTF-- +phar error: unable to write signature to tar-based phar: unable to write phar "%s" with requested openssl signature diff --git a/ext/phar/tests/phar-is-link-intercept.phpt b/ext/phar/tests/phar-is-link-intercept.phpt new file mode 100644 index 000000000000..f81f1ae425d7 --- /dev/null +++ b/ext/phar/tests/phar-is-link-intercept.phpt @@ -0,0 +1,29 @@ +--TEST-- +phar: is_link() intercept correctly delegates for non-symlink phar entries +--EXTENSIONS-- +phar +--INI-- +phar.readonly=0 +phar.require_hash=0 +--FILE-- +addFromString('file.txt', 'hello'); +$phar->setStub(''); +include $fname; +?> +--CLEAN-- + +--EXPECT-- +regular entry (not a symlink): bool(false) +missing entry: bool(false) +absolute phar:// path (bypasses intercept): bool(false) diff --git a/ext/phar/tests/phar_commitwrite.phpt b/ext/phar/tests/phar_commitwrite.phpt index 80c35cb78436..951506aff0f0 100644 --- a/ext/phar/tests/phar_commitwrite.phpt +++ b/ext/phar/tests/phar_commitwrite.phpt @@ -27,7 +27,7 @@ unlink(__DIR__ . '/phar_commitwrite.phar'); __HALT_COMPILER(); ?> --EXPECTF-- -int(6641) +int(6659) string(%d) "setMetadata("foobar"); +$phar['x'] = 'hi'; +try { + $phar->convertToData(Phar::ZIP, Phar::NONE, 'phar.zip'); +} catch (BadMethodCallException $e) { + echo $e->getMessage(),"\n"; +} +?> +--CLEAN-- + +--EXPECTF-- +data phar "%s" has invalid extension phar.zip diff --git a/ext/phar/tests/phar_convert_repeated.phpt b/ext/phar/tests/phar_convert_repeated.phpt index 8f8b6361362f..09026f0d947f 100644 --- a/ext/phar/tests/phar_convert_repeated.phpt +++ b/ext/phar/tests/phar_convert_repeated.phpt @@ -120,7 +120,7 @@ NULL bool(true) bool(false) bool(false) -int(6641) +int(6659) NULL ================= convertToZip() ===================== bool(false) diff --git a/ext/phar/tests/phar_create_in_cwd.phpt b/ext/phar/tests/phar_create_in_cwd.phpt index c6245c295e65..7aed3a5d5903 100644 --- a/ext/phar/tests/phar_create_in_cwd.phpt +++ b/ext/phar/tests/phar_create_in_cwd.phpt @@ -30,7 +30,7 @@ __HALT_COMPILER(); unlink(__DIR__ . '/phar_create_in_cwd.phar'); ?> --EXPECTF-- -int(6641) +int(6659) string(%d) "getMessage() . "\n"; } ?> --EXPECT-- -string(6641) "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; +echo "<html>\n <head>\n <title>File Not Found\n \n \n

404 - File Not Found

\n \n"; exit; } $b = pathinfo($a); @@ -143,13 +143,13 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'index.php'; -const LEN = 6643; +const LEN = 6661; static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); -$L = unpack('V', $a = fread($fp, 4)); +$L = unpack('V', $a = (string)fread($fp, 4)); $m = ''; do { @@ -157,7 +157,7 @@ $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } -$last = fread($fp, $read); +$last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -248,7 +248,8 @@ return realpath('/tmp'); static function _unpack($m) { $info = unpack('V', substr($m, 0, 4)); - $l = unpack('V', substr($m, 10, 4)); + +$l = unpack('V', substr($m, 10, 4)); $m = substr($m, 14 + $l[1]); $s = unpack('V', substr($m, 0, 4)); $o = 0; @@ -256,11 +257,16 @@ $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { - $len = unpack('V', substr($m, $start, 4)); + +$len = unpack('V', substr($m, $start, 4)); $start += 4; - $savepath = substr($m, $start, $len[1]); + +$savepath = substr($m, $start, $len[1]); $start += $len[1]; - $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); + + + +$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; @@ -294,7 +300,7 @@ $data = bzdecompress($data); if (strlen($data) != $entry[0]) { die("Invalid internal .phar file (size error " . strlen($data) . " != " . -$stat[7] . ")"); +$entry[0] . ")"); } if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { @@ -327,7 +333,7 @@ Extract_Phar::go(); __HALT_COMPILER(); ?>" ============================================================================ ============================================================================ -string(6652) "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; +echo "<html>\n <head>\n <title>File Not Found\n \n \n

404 - File Not Found

\n \n"; exit; } $b = pathinfo($a); @@ -437,13 +443,13 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6654; +const LEN = 6672; static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); -$L = unpack('V', $a = fread($fp, 4)); +$L = unpack('V', $a = (string)fread($fp, 4)); $m = ''; do { @@ -451,7 +457,7 @@ $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } -$last = fread($fp, $read); +$last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -542,7 +548,8 @@ return realpath('/tmp'); static function _unpack($m) { $info = unpack('V', substr($m, 0, 4)); - $l = unpack('V', substr($m, 10, 4)); + +$l = unpack('V', substr($m, 10, 4)); $m = substr($m, 14 + $l[1]); $s = unpack('V', substr($m, 0, 4)); $o = 0; @@ -550,11 +557,16 @@ $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { - $len = unpack('V', substr($m, $start, 4)); + +$len = unpack('V', substr($m, $start, 4)); $start += 4; - $savepath = substr($m, $start, $len[1]); + +$savepath = substr($m, $start, $len[1]); $start += $len[1]; - $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); + + + +$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; @@ -588,7 +600,7 @@ $data = bzdecompress($data); if (strlen($data) != $entry[0]) { die("Invalid internal .phar file (size error " . strlen($data) . " != " . -$stat[7] . ")"); +$entry[0] . ")"); } if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { @@ -621,7 +633,7 @@ Extract_Phar::go(); __HALT_COMPILER(); ?>" ============================================================================ ============================================================================ -int(7032) +int(7050) ============================================================================ ============================================================================ Illegal filename passed in for stub creation, was 401 characters long, and only 400 or less is allowed @@ -629,7 +641,7 @@ Illegal filename passed in for stub creation, was 401 characters long, and only ============================================================================ ============================================================================ ============================================================================ -string(6654) "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; +echo "<html>\n <head>\n <title>File Not Found\n \n \n

404 - File Not Found

\n \n"; exit; } $b = pathinfo($a); @@ -739,13 +751,13 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6656; +const LEN = 6674; static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); -$L = unpack('V', $a = fread($fp, 4)); +$L = unpack('V', $a = (string)fread($fp, 4)); $m = ''; do { @@ -753,7 +765,7 @@ $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } -$last = fread($fp, $read); +$last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -844,7 +856,8 @@ return realpath('/tmp'); static function _unpack($m) { $info = unpack('V', substr($m, 0, 4)); - $l = unpack('V', substr($m, 10, 4)); + +$l = unpack('V', substr($m, 10, 4)); $m = substr($m, 14 + $l[1]); $s = unpack('V', substr($m, 0, 4)); $o = 0; @@ -852,11 +865,16 @@ $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { - $len = unpack('V', substr($m, $start, 4)); + +$len = unpack('V', substr($m, $start, 4)); $start += 4; - $savepath = substr($m, $start, $len[1]); + +$savepath = substr($m, $start, $len[1]); $start += $len[1]; - $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); + + + +$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; @@ -890,7 +908,7 @@ $data = bzdecompress($data); if (strlen($data) != $entry[0]) { die("Invalid internal .phar file (size error " . strlen($data) . " != " . -$stat[7] . ")"); +$entry[0] . ")"); } if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { @@ -923,5 +941,5 @@ Extract_Phar::go(); __HALT_COMPILER(); ?>" ============================================================================ ============================================================================ -int(7032) +int(7050) Illegal web filename passed in for stub creation, was 401 characters long, and only 400 or less is allowed diff --git a/ext/phar/tests/phar_extract2.phpt b/ext/phar/tests/phar_extract2.phpt index f57d96ad5e92..b22c00977665 100644 --- a/ext/phar/tests/phar_extract2.phpt +++ b/ext/phar/tests/phar_extract2.phpt @@ -46,8 +46,6 @@ $dir = __DIR__ . '/extract2/'; @rmdir($dir . 'one/level'); @rmdir($dir . 'one'); @rmdir($dir); -$dir = __DIR__ . '/extract1/'; -@rmdir($dir); ?> --EXPECTF-- %sextract2%cfile1.txt diff --git a/ext/phar/tests/phar_offset_check.phpt b/ext/phar/tests/phar_offset_check.phpt index c1a8d201c8bc..5a039d2d8934 100644 --- a/ext/phar/tests/phar_offset_check.phpt +++ b/ext/phar/tests/phar_offset_check.phpt @@ -68,8 +68,8 @@ var_dump($phar->getAlias()); Entry .phar/stub.php does not exist Entry .phar/alias.txt does not exist Cannot set stub ".phar/stub.php" directly in phar "%sphar_offset_check.phar.php", use setStub -int(6643) -int(6643) +int(6661) +int(6661) Cannot set alias ".phar/alias.txt" directly in phar "%sphar_offset_check.phar.php", use setAlias string(5) "susan" string(5) "susan" diff --git a/ext/phar/tests/phar_setdefaultstub.phpt b/ext/phar/tests/phar_setdefaultstub.phpt index c5db64a308e6..ea05a03bc1a7 100644 --- a/ext/phar/tests/phar_setdefaultstub.phpt +++ b/ext/phar/tests/phar_setdefaultstub.phpt @@ -53,7 +53,7 @@ try { unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar'); ?> --EXPECT-- -string(6643) "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; +echo "<html>\n <head>\n <title>File Not Found\n \n \n

404 - File Not Found

\n \n"; exit; } $b = pathinfo($a); @@ -163,13 +163,13 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'index.php'; -const LEN = 6643; +const LEN = 6661; static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); -$L = unpack('V', $a = fread($fp, 4)); +$L = unpack('V', $a = (string)fread($fp, 4)); $m = ''; do { @@ -177,7 +177,7 @@ $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } -$last = fread($fp, $read); +$last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -268,7 +268,8 @@ return realpath('/tmp'); static function _unpack($m) { $info = unpack('V', substr($m, 0, 4)); - $l = unpack('V', substr($m, 10, 4)); + +$l = unpack('V', substr($m, 10, 4)); $m = substr($m, 14 + $l[1]); $s = unpack('V', substr($m, 0, 4)); $o = 0; @@ -276,11 +277,16 @@ $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { - $len = unpack('V', substr($m, $start, 4)); + +$len = unpack('V', substr($m, $start, 4)); $start += 4; - $savepath = substr($m, $start, $len[1]); + +$savepath = substr($m, $start, $len[1]); $start += $len[1]; - $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); + + + +$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; @@ -314,7 +320,7 @@ $data = bzdecompress($data); if (strlen($data) != $entry[0]) { die("Invalid internal .phar file (size error " . strlen($data) . " != " . -$stat[7] . ")"); +$entry[0] . ")"); } if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { @@ -348,7 +354,7 @@ __HALT_COMPILER(); ?> " ============================================================================ ============================================================================ -string(6654) "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; +echo "<html>\n <head>\n <title>File Not Found\n \n \n

404 - File Not Found

\n \n"; exit; } $b = pathinfo($a); @@ -458,13 +464,13 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6654; +const LEN = 6672; static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); -$L = unpack('V', $a = fread($fp, 4)); +$L = unpack('V', $a = (string)fread($fp, 4)); $m = ''; do { @@ -472,7 +478,7 @@ $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } -$last = fread($fp, $read); +$last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -563,7 +569,8 @@ return realpath('/tmp'); static function _unpack($m) { $info = unpack('V', substr($m, 0, 4)); - $l = unpack('V', substr($m, 10, 4)); + +$l = unpack('V', substr($m, 10, 4)); $m = substr($m, 14 + $l[1]); $s = unpack('V', substr($m, 0, 4)); $o = 0; @@ -571,11 +578,16 @@ $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { - $len = unpack('V', substr($m, $start, 4)); + +$len = unpack('V', substr($m, $start, 4)); $start += 4; - $savepath = substr($m, $start, $len[1]); + +$savepath = substr($m, $start, $len[1]); $start += $len[1]; - $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); + + + +$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; @@ -609,7 +621,7 @@ $data = bzdecompress($data); if (strlen($data) != $entry[0]) { die("Invalid internal .phar file (size error " . strlen($data) . " != " . -$stat[7] . ")"); +$entry[0] . ")"); } if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { @@ -643,7 +655,7 @@ __HALT_COMPILER(); ?> " ============================================================================ ============================================================================ -string(6656) "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; +echo "<html>\n <head>\n <title>File Not Found\n \n \n

404 - File Not Found

\n \n"; exit; } $b = pathinfo($a); @@ -753,13 +765,13 @@ const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'my/custom/thingy.php'; -const LEN = 6656; +const LEN = 6674; static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); -$L = unpack('V', $a = fread($fp, 4)); +$L = unpack('V', $a = (string)fread($fp, 4)); $m = ''; do { @@ -767,7 +779,7 @@ $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } -$last = fread($fp, $read); +$last = (string)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); @@ -858,7 +870,8 @@ return realpath('/tmp'); static function _unpack($m) { $info = unpack('V', substr($m, 0, 4)); - $l = unpack('V', substr($m, 10, 4)); + +$l = unpack('V', substr($m, 10, 4)); $m = substr($m, 14 + $l[1]); $s = unpack('V', substr($m, 0, 4)); $o = 0; @@ -866,11 +879,16 @@ $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { - $len = unpack('V', substr($m, $start, 4)); + +$len = unpack('V', substr($m, $start, 4)); $start += 4; - $savepath = substr($m, $start, $len[1]); + +$savepath = substr($m, $start, $len[1]); $start += $len[1]; - $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); + + + +$ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; @@ -904,7 +922,7 @@ $data = bzdecompress($data); if (strlen($data) != $entry[0]) { die("Invalid internal .phar file (size error " . strlen($data) . " != " . -$stat[7] . ")"); +$entry[0] . ")"); } if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { @@ -938,5 +956,5 @@ __HALT_COMPILER(); ?> " ============================================================================ ============================================================================ -int(7034) +int(7052) Illegal filename passed in for stub creation, was 401 characters long, and only 400 or less is allowed diff --git a/ext/phar/tests/phar_setsignaturealgo2.phpt b/ext/phar/tests/phar_setsignaturealgo2.phpt index 4f31836fbbbc..82615a13da47 100644 --- a/ext/phar/tests/phar_setsignaturealgo2.phpt +++ b/ext/phar/tests/phar_setsignaturealgo2.phpt @@ -2,6 +2,7 @@ Phar::setSupportedSignatures() with hash --EXTENSIONS-- phar +openssl --SKIPIF-- getSignature()); + +echo "Set MD5:\n"; $p->setSignatureAlgorithm(Phar::MD5); var_dump($p->getSignature()); + +echo "Set SHA1:\n"; $p->setSignatureAlgorithm(Phar::SHA1); var_dump($p->getSignature()); + +echo "Set SHA256:\n"; try { -$p->setSignatureAlgorithm(Phar::SHA256); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $p->setSignatureAlgorithm(Phar::SHA256); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + +echo "Set SHA512:\n"; try { -$p->setSignatureAlgorithm(Phar::SHA512); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $p->setSignatureAlgorithm(Phar::SHA512); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + +echo "Set OPENSSL:\n"; try { -$config = __DIR__ . '/files/openssl.cnf'; -$config_arg = array('config' => $config); -$private = openssl_get_privatekey(file_get_contents(__DIR__ . '/files/private.pem')); -$pkey = ''; -openssl_pkey_export($private, $pkey, NULL, $config_arg); -$p->setSignatureAlgorithm(Phar::OPENSSL, $pkey); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $config = __DIR__ . '/files/openssl.cnf'; + $config_arg = array('config' => $config); + $private = openssl_get_privatekey(file_get_contents(__DIR__ . '/files/private.pem')); + $pkey = ''; + openssl_pkey_export($private, $pkey, NULL, $config_arg); + $p->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + ?> --CLEAN-- --EXPECTF-- +Default: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-256" } +Set MD5: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(3) "MD5" } +Set SHA1: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(5) "SHA-1" } +Set SHA256: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-256" } +Set SHA512: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-512" } +Set OPENSSL: array(2) { ["hash"]=> string(%d) "%s" diff --git a/ext/phar/tests/tar/bug70417.phpt b/ext/phar/tests/tar/bug70417.phpt index 4d98a18954cc..7bb6bbafbcfa 100644 --- a/ext/phar/tests/tar/bug70417.phpt +++ b/ext/phar/tests/tar/bug70417.phpt @@ -3,32 +3,18 @@ Bug #70417 (PharData::compress() doesn't close temp file) --EXTENSIONS-- phar zlib ---SKIPIF-- - --FILE-- /dev/null', $out); // Note: valgrind can produce false positives for /usr/bin/lsof - return count($out); -} $filename = __DIR__ . '/bug70417.tar'; @unlink("$filename.gz"); -$openFiles1 = countOpenFiles(); +$resBefore = count(get_resources()); $arch = new PharData($filename); $arch->addFromString('foo', 'bar'); +$arch->addFromString('foo2', 'baz'); $arch->compress(Phar::GZ); unset($arch); -$openFiles2 = countOpenFiles(); -var_dump($openFiles1 === $openFiles2); +$resAfter = count(get_resources()); +var_dump($resAfter - $resBefore); ?> --CLEAN-- --EXPECT-- -bool(true) +int(0) diff --git a/ext/phar/tests/tar/files/make.dangerous.tar.php.inc b/ext/phar/tests/tar/files/make.dangerous.tar.php.inc index 641dda56f595..ff9c20ccf9b7 100644 --- a/ext/phar/tests/tar/files/make.dangerous.tar.php.inc +++ b/ext/phar/tests/tar/files/make.dangerous.tar.php.inc @@ -108,16 +108,16 @@ class danger_tarmaker $checksum = pack('a8', sprintf('%6s ', decoct($checksum))); - fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512); + fwrite($this->tmp, $block . $checksum . $blockend, 512); if (is_resource($fileOrStream)) { stream_copy_to_stream($fileOrStream, $this->tmp); if ($stat['size'] % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - $stat['size'] % 512)); } } else { - fwrite($this->tmp, (binary)$fileOrStream); + fwrite($this->tmp, $fileOrStream); if (strlen($fileOrStream) % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - strlen($fileOrStream) % 512)); } } } diff --git a/ext/phar/tests/tar/files/make_invalid_tar.php.inc b/ext/phar/tests/tar/files/make_invalid_tar.php.inc index 2ccdf00201c0..cf9034bc3076 100644 --- a/ext/phar/tests/tar/files/make_invalid_tar.php.inc +++ b/ext/phar/tests/tar/files/make_invalid_tar.php.inc @@ -3,7 +3,7 @@ include dirname(__FILE__) . '/tarmaker.php.inc'; class corrupter extends tarmaker { function close() { - fwrite($this->tmp, (binary)'oopsie'); + fwrite($this->tmp, 'oopsie'); fclose($this->tmp); } } diff --git a/ext/phar/tests/tar/files/tarmaker.php.inc b/ext/phar/tests/tar/files/tarmaker.php.inc index 5860bf84d314..ce0bd249b51d 100644 --- a/ext/phar/tests/tar/files/tarmaker.php.inc +++ b/ext/phar/tests/tar/files/tarmaker.php.inc @@ -107,16 +107,16 @@ class tarmaker $checksum = pack('a8', sprintf('%6s ', decoct($checksum))); - fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512); + fwrite($this->tmp, $block . $checksum . $blockend, 512); if (is_resource($fileOrStream)) { stream_copy_to_stream($fileOrStream, $this->tmp); if ($stat['size'] % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - $stat['size'] % 512)); } } else { - fwrite($this->tmp, (binary)$fileOrStream); + fwrite($this->tmp, $fileOrStream); if (strlen($fileOrStream) % 512) { - fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512)); + fwrite($this->tmp, str_repeat("\0", 512 - strlen($fileOrStream) % 512)); } } } diff --git a/ext/phar/tests/tar/gh21986.phpt b/ext/phar/tests/tar/gh21986.phpt new file mode 100644 index 000000000000..13205d40a65d --- /dev/null +++ b/ext/phar/tests/tar/gh21986.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-21986 (PharData::getContent() crash on circular symlink chain in tar) +--EXTENSIONS-- +phar +--FILE-- +getContent()); +?> +--CLEAN-- + +--EXPECT-- +string(0) "" diff --git a/ext/phar/tests/tar/phar_convert_phar.phpt b/ext/phar/tests/tar/phar_convert_phar.phpt index c25ed7c556bf..3247550431d4 100644 --- a/ext/phar/tests/tar/phar_convert_phar.phpt +++ b/ext/phar/tests/tar/phar_convert_phar.phpt @@ -45,11 +45,11 @@ __HALT_COMPILER(); ?> --EXPECT-- bool(false) -int(6641) +int(6659) bool(true) string(60) " --EXPECT-- bool(false) -int(6641) +int(6659) bool(true) string(60) " --EXPECT-- bool(false) -int(6641) +int(6659) bool(true) string(60) " --EXPECT-- bool(false) -int(6641) +int(6659) string(2) "hi" bool(true) string(60) "getSignature()); + +echo "Set MD5:\n"; $p->setSignatureAlgorithm(Phar::MD5); var_dump($p->getSignature()); + +echo "Set SHA1:\n"; $p->setSignatureAlgorithm(Phar::SHA1); var_dump($p->getSignature()); + +echo "Set SHA256:\n"; try { -$p->setSignatureAlgorithm(Phar::SHA256); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $p->setSignatureAlgorithm(Phar::SHA256); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + +echo "Set SHA512:\n"; try { -$p->setSignatureAlgorithm(Phar::SHA512); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $p->setSignatureAlgorithm(Phar::SHA512); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + +echo "Set OPENSSL:\n"; try { -$config = __DIR__ . '/../files/openssl.cnf'; -$config_arg = array('config' => $config); -$private = openssl_get_privatekey(file_get_contents(dirname(__DIR__) . '/files/private.pem')); -$pkey = ''; -openssl_pkey_export($private, $pkey, NULL, $config_arg); -$p->setSignatureAlgorithm(Phar::OPENSSL, $pkey); -var_dump($p->getSignature()); -$p->setSignatureAlgorithm(Phar::OPENSSL_SHA512, $pkey); -var_dump($p->getSignature()); -$p->setSignatureAlgorithm(Phar::OPENSSL_SHA256, $pkey); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $config = __DIR__ . '/../files/openssl.cnf'; + $config_arg = array('config' => $config); + $private = openssl_get_privatekey(file_get_contents(dirname(__DIR__) . '/files/private.pem')); + $pkey = ''; + openssl_pkey_export($private, $pkey, NULL, $config_arg); + $p->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + var_dump($p->getSignature()); + echo "Set OPENSSL_SHA512:\n"; + $p->setSignatureAlgorithm(Phar::OPENSSL_SHA512, $pkey); + var_dump($p->getSignature()); + echo "Set OPENSSL_SHA256:\n"; + $p->setSignatureAlgorithm(Phar::OPENSSL_SHA256, $pkey); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + ?> --CLEAN-- --EXPECTF-- +Default: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-256" } +Set MD5: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(3) "MD5" } +Set SHA1: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(5) "SHA-1" } +Set SHA256: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-256" } +Set SHA512: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-512" } +Set OPENSSL: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "OpenSSL" } +Set OPENSSL_SHA512: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(14) "OpenSSL_SHA512" } +Set OPENSSL_SHA256: array(2) { ["hash"]=> string(%d) "%s" diff --git a/ext/phar/tests/tar_flush_too_long_filename.phpt b/ext/phar/tests/tar_flush_too_long_filename.phpt new file mode 100644 index 000000000000..be18f5e48168 --- /dev/null +++ b/ext/phar/tests/tar_flush_too_long_filename.phpt @@ -0,0 +1,41 @@ +--TEST-- +Tar flush with too long file name +--EXTENSIONS-- +phar +--SKIPIF-- + +--INI-- +phar.require_hash=0 +--FILE-- +addEmptyDir('blah1/'); +$phar->setSignatureAlgorithm(Phar::OPENSSL, "randomcrap"); +try { + $phar->addEmptyDir('blah2/' . str_repeat('X', 1000)); +} catch (PharException $e) { + echo $e->getMessage(); +} + +?> +--CLEAN-- + +--EXPECTF-- +tar-based phar "%s" cannot be created, filename "%s" is too long for tar file format diff --git a/ext/phar/tests/test77022na49ia3c4t8cefa4Wbt b/ext/phar/tests/test77022na49ia3c4t8cefa4Wbt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ext/phar/tests/zip/notphar.phpt b/ext/phar/tests/zip/notphar.phpt index 10d4d7d8be31..ab4f80e430bb 100644 --- a/ext/phar/tests/zip/notphar.phpt +++ b/ext/phar/tests/zip/notphar.phpt @@ -4,7 +4,6 @@ Phar: a non-executable zip with no stub named .phar.zip phar --INI-- phar.readonly=1 -detect_unicode=0 zend.multibyte=0 --FILE-- --EXPECT-- bool(false) -int(6641) +int(6659) bool(true) string(60) "getSignature()); + +echo "Set MD5:\n"; $p->setSignatureAlgorithm(Phar::MD5); copy($fname, $fname2); $p = new Phar($fname2); var_dump($p->getSignature()); +echo "Set SHA1:\n"; $p->setSignatureAlgorithm(Phar::SHA1); copy($fname2, $fname3); $p = new Phar($fname3); var_dump($p->getSignature()); +echo "Set SHA256:\n"; try { -$p->setSignatureAlgorithm(Phar::SHA256); -copy($fname3, $fname4); -$p = new Phar($fname4); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $p->setSignatureAlgorithm(Phar::SHA256); + copy($fname3, $fname4); + $p = new Phar($fname4); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + +echo "Set SHA512:\n"; try { -$p->setSignatureAlgorithm(Phar::SHA512); -copy($fname4, $fname5); -$p = new Phar($fname5); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + $p->setSignatureAlgorithm(Phar::SHA512); + copy($fname4, $fname5); + $p = new Phar($fname5); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } + +echo "Set OPENSSL:\n"; try { -$config = __DIR__ . '/../files/openssl.cnf'; -$config_arg = array('config' => $config); -$keys=openssl_pkey_new($config_arg); -openssl_pkey_export($keys, $privkey, NULL, $config_arg); -$pubkey=openssl_pkey_get_details($keys); -$p->setSignatureAlgorithm(Phar::OPENSSL, $privkey); + $config = __DIR__ . '/../files/openssl.cnf'; + $config_arg = array('config' => $config); + $keys=openssl_pkey_new($config_arg); + openssl_pkey_export($keys, $privkey, NULL, $config_arg); + $pubkey=openssl_pkey_get_details($keys); + $p->setSignatureAlgorithm(Phar::OPENSSL, $privkey); -copy($fname5, $fname6); -file_put_contents($fname6 . '.pubkey', $pubkey['key']); -$p = new Phar($fname6); -var_dump($p->getSignature()); -} catch (Exception $e) { -echo $e->getMessage(); + copy($fname5, $fname6); + file_put_contents($fname6 . '.pubkey', $pubkey['key']); + $p = new Phar($fname6); + var_dump($p->getSignature()); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; } ?> --CLEAN-- @@ -76,36 +86,42 @@ unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.6.phar.zip'); unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.6.phar.zip.pubkey'); ?> --EXPECTF-- +Default: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-256" } +Set MD5: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(3) "MD5" } +Set SHA1: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(5) "SHA-1" } +Set SHA256: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-256" } +Set SHA512: array(2) { ["hash"]=> string(%d) "%s" ["hash_type"]=> string(7) "SHA-512" } +Set OPENSSL: array(2) { ["hash"]=> string(%d) "%s" diff --git a/ext/phar/util.c b/ext/phar/util.c index 06394813574b..e95b3ab7574b 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -3,15 +3,13 @@ | phar php single-file executable PHP extension | | utility functions | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | | Marcus Boerger | @@ -36,54 +34,62 @@ #include #include #else -static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type); +ZEND_ATTRIBUTE_NONNULL static bool phar_call_openssl_verify(php_stream *fp, zend_off_t end, zend_string *public_key, const char *signature, size_t signature_len, uint32_t sig_type); +static zend_result phar_call_openssl_sign(php_stream *fp, zend_off_t end, const char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type); #endif /* for links to relative location, prepend cwd of the entry */ -static char *phar_get_link_location(phar_entry_info *entry) /* {{{ */ +static zend_string *phar_get_link_location(phar_entry_info *entry) /* {{{ */ { - char *p, *ret = NULL; - if (!entry->link) { - return NULL; - } - if (entry->link[0] == '/') { - return estrdup(entry->link + 1); + ZEND_ASSERT(entry->symlink); + + if (ZSTR_VAL(entry->symlink)[0] == '/') { + return zend_string_init(ZSTR_VAL(entry->symlink) + 1, ZSTR_LEN(entry->symlink) - 1, false); } - p = strrchr(ZSTR_VAL(entry->filename), '/'); + const char *p = strrchr(ZSTR_VAL(entry->filename), '/'); if (p) { /* Important: don't modify the original `p` data because it is a shared string. */ zend_string *new_name = zend_string_init(ZSTR_VAL(entry->filename), p - ZSTR_VAL(entry->filename), false); - spprintf(&ret, 0, "%s/%s", ZSTR_VAL(new_name), entry->link); + zend_string *location = zend_string_concat3( + ZSTR_VAL(new_name), ZSTR_LEN(new_name), + ZEND_STRL("/"), + ZSTR_VAL(entry->symlink), ZSTR_LEN(entry->symlink) + ); zend_string_release(entry->filename); entry->filename = new_name; - return ret; + return location; } - return entry->link; + return zend_string_copy(entry->symlink); } /* }}} */ phar_entry_info *phar_get_link_source(phar_entry_info *entry) /* {{{ */ { phar_entry_info *link_entry; - char *link; + uint32_t depth = 0, max_depth; - if (!entry->link) { + if (!entry->symlink) { return entry; } - link = phar_get_link_location(entry); - if (NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), entry->link, strlen(entry->link))) || - NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), link, strlen(link)))) { - if (link != entry->link) { - efree(link); + max_depth = zend_hash_num_elements(&(entry->phar->manifest)); + + while (entry->symlink) { + if (UNEXPECTED(++depth > max_depth)) { + return NULL; } - return phar_get_link_source(link_entry); - } else { - if (link != entry->link) { - efree(link); + zend_string *link = phar_get_link_location(entry); + + if (NULL != (link_entry = zend_hash_find_ptr(&(entry->phar->manifest), entry->symlink)) || + NULL != (link_entry = zend_hash_find_ptr(&(entry->phar->manifest), link))) { + zend_string_release(link); + entry = link_entry; + } else { + zend_string_release(link); + return NULL; } - return NULL; } + return entry; } /* }}} */ @@ -96,22 +102,23 @@ static php_stream *phar_get_entrypufp(const phar_entry_info *entry) } /* retrieve a phar_entry_info's current file pointer for reading contents */ -php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */ +php_stream *phar_get_efp(phar_entry_info *entry, bool follow_links) /* {{{ */ { - if (follow_links && entry->link) { + if (follow_links && entry->symlink) { phar_entry_info *link_entry = phar_get_link_source(entry); if (link_entry && link_entry != entry) { - return phar_get_efp(link_entry, 1); + return phar_get_efp(link_entry, true); } } if (phar_get_fp_type(entry) == PHAR_FP) { - if (!phar_get_entrypfp(entry)) { + php_stream *stream = phar_get_entrypfp(entry); + if (!stream) { /* re-open just in time for cases where our refcount reached 0 on the phar archive */ - phar_open_archive_fp(entry->phar); + stream = phar_open_archive_fp(entry->phar); } - return phar_get_entrypfp(entry); + return stream; } else if (phar_get_fp_type(entry) == PHAR_UFP) { return phar_get_entrypufp(entry); } else if (entry->fp_type == PHAR_MOD) { @@ -139,7 +146,7 @@ static zend_off_t phar_get_fp_offset(const phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].offset; } -int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links) /* {{{ */ +int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, bool follow_links) /* {{{ */ { php_stream *fp = phar_get_efp(entry, follow_links); zend_off_t temp, eoffset; @@ -189,11 +196,11 @@ int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_of /* }}} */ /* mount an absolute path or uri to a path internal to the phar archive */ -zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ +zend_result phar_mount_entry(phar_archive_data *phar, const char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */ { phar_entry_info entry = {0}; php_stream_statbuf ssb; - int is_phar; + bool is_phar; const char *err; if (phar_path_check(&path, &path_len, &err) > pcr_is_ok) { @@ -225,8 +232,8 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil return FAILURE; } - entry.is_mounted = 1; - entry.is_crc_checked = 1; + entry.is_mounted = true; + entry.is_crc_checked = true; entry.fp_type = PHAR_TMP; if (SUCCESS != php_stream_stat_path(filename, &ssb)) { @@ -240,7 +247,7 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil #endif if (ssb.sb.st_mode & S_IFDIR) { - entry.is_dir = 1; + entry.is_dir = true; if (NULL == zend_hash_add_ptr(&phar->mounted_dirs, entry.filename, entry.filename)) { /* directory already mounted */ efree(entry.tmp); @@ -248,7 +255,7 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil return FAILURE; } } else { - entry.is_dir = 0; + entry.is_dir = false; entry.uncompressed_filesize = entry.compressed_filesize = ssb.sb.st_size; } @@ -264,19 +271,13 @@ zend_result phar_mount_entry(phar_archive_data *phar, char *filename, size_t fil } /* }}} */ -zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar) /* {{{ */ +zend_string *phar_find_in_include_path(const zend_string *filename) /* {{{ */ { zend_string *ret; - char *path, *arch, *entry, *test; - size_t arch_len, entry_len; + char *path; + zend_string *arch; phar_archive_data *phar; - if (pphar) { - *pphar = NULL; - } else { - pphar = &phar; - } - if (!zend_is_executing() || !PHAR_G(cwd)) { return NULL; } @@ -292,81 +293,65 @@ zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data if ( PHAR_G(last_phar) && is_file_a_phar_wrapper - && ZSTR_LEN(fname) - length_phar_protocol >= PHAR_G(last_phar_name_len) - && !memcmp(ZSTR_VAL(fname) + length_phar_protocol, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len)) + && ZSTR_LEN(fname) - length_phar_protocol >= ZSTR_LEN(PHAR_G(last_phar_name)) + && !memcmp(ZSTR_VAL(fname) + length_phar_protocol, ZSTR_VAL(PHAR_G(last_phar_name)), ZSTR_LEN(PHAR_G(last_phar_name))) ) { - arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len)); - arch_len = PHAR_G(last_phar_name_len); + arch = zend_string_init(ZSTR_VAL(PHAR_G(last_phar_name)), ZSTR_LEN(PHAR_G(last_phar_name)), false); phar = PHAR_G(last_phar); goto splitted; } - if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) { + if (!is_file_a_phar_wrapper) { + return NULL; + } + arch = phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 1, 0); + if (!arch) { return NULL; } - - efree(entry); if (*ZSTR_VAL(filename) == '.') { - size_t try_len; - - if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) { - efree(arch); + phar = phar_get_archive(ZSTR_VAL(arch), ZSTR_LEN(arch), NULL, 0, NULL); + if (!phar) { + zend_string_release_ex(arch, false); return NULL; } -splitted: - if (pphar) { - *pphar = phar; - } - - try_len = ZSTR_LEN(filename); - test = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &try_len, 1); - - if (*test == '/') { - if (zend_hash_str_exists(&(phar->manifest), test + 1, try_len - 1)) { - ret = strpprintf(0, "phar://%s%s", arch, test); - efree(arch); - efree(test); +splitted:; + zend_string *test = phar_fix_filepath(ZSTR_VAL(filename), ZSTR_LEN(filename), true); + if (ZSTR_VAL(test)[0] == '/') { + if (zend_hash_str_exists(&(phar->manifest), ZSTR_VAL(test) + 1, ZSTR_LEN(test) - 1)) { + ret = zend_string_concat3( + "phar://", strlen("phar://"), + ZSTR_VAL(arch), ZSTR_LEN(arch), + ZSTR_VAL(test), ZSTR_LEN(test) + ); + zend_string_release_ex(test, false); + zend_string_release_ex(arch, false); return ret; } } else { - if (zend_hash_str_exists(&(phar->manifest), test, try_len)) { - ret = strpprintf(0, "phar://%s/%s", arch, test); - efree(arch); - efree(test); + if (zend_hash_exists(&(phar->manifest), test)) { + ret = strpprintf(0, "phar://%s/%s", ZSTR_VAL(arch), ZSTR_VAL(test)); + zend_string_release_ex(test, false); + zend_string_release_ex(arch, false); return ret; } } - efree(test); + zend_string_release_ex(test, false); } - spprintf(&path, MAXPATHLEN + 1 + strlen(PG(include_path)), "phar://%s/%s%c%s", arch, PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path)); - efree(arch); + spprintf(&path, MAXPATHLEN + 1 + strlen(PG(include_path)), "phar://%s/%s%c%s", ZSTR_VAL(arch), PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path)); + zend_string_release_ex(arch, false); ret = php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), path); efree(path); - if (ret && zend_string_starts_with_literal_ci(ret, "phar://")) { - /* found phar:// */ - if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, &entry, &entry_len, 1, 0)) { - return ret; - } - - *pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), arch, arch_len); - - if (!*pphar && PHAR_G(manifest_cached)) { - *pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len); - } - - efree(arch); - efree(entry); - } - return ret; } /* }}} */ -static zend_result phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ +static ZEND_ATTRIBUTE_NONNULL zend_result phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ { + *error = NULL; + if (entry->fp_type == PHAR_MOD) { /* already newly created, truncate */ php_stream_truncate_set_size(entry->fp, 0); @@ -384,23 +369,17 @@ static zend_result phar_create_writeable_entry(phar_archive_data *phar, phar_ent return SUCCESS; } - if (error) { - *error = NULL; - } - /* open a new temp file for writing */ - if (entry->link) { - efree(entry->link); - entry->link = NULL; + if (entry->symlink) { + zend_string_release(entry->symlink); + entry->symlink = NULL; entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); } entry->fp = php_stream_fopen_tmpfile(); if (!entry->fp) { - if (error) { - spprintf(error, 0, "phar error: unable to create temporary file"); - } + *error = estrdup("phar error: unable to create temporary file"); return FAILURE; } @@ -418,12 +397,12 @@ static zend_result phar_create_writeable_entry(phar_archive_data *phar, phar_ent } /* }}} */ -static zend_result phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL static zend_result phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */ { php_stream *fp; phar_entry_info *link; - if (FAILURE == phar_open_entry_fp(entry, error, 1)) { + if (FAILURE == phar_open_entry_fp(entry, error, true)) { return FAILURE; } @@ -433,26 +412,24 @@ static zend_result phar_separate_entry_fp(phar_entry_info *entry, char **error) fp = php_stream_fopen_tmpfile(); if (fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); + *error = estrdup("phar error: unable to create temporary file"); return FAILURE; } - phar_seek_efp(entry, 0, SEEK_SET, 0, 1); + phar_seek_efp(entry, 0, SEEK_SET, 0, true); link = phar_get_link_source(entry); if (!link) { link = entry; } - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) { - if (error) { - spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", ZSTR_VAL(entry->filename), entry->phar->fname); - } + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, false), fp, link->uncompressed_filesize, NULL)) { + spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return FAILURE; } - if (entry->link) { - efree(entry->link); - entry->link = NULL; + if (entry->symlink) { + zend_string_release(entry->symlink); + entry->symlink = NULL; entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); } @@ -472,52 +449,43 @@ static zend_result phar_separate_entry_fp(phar_entry_info *entry, char **error) * appended, truncated, or read. For read, if the entry is marked unmodified, it is * assumed that the file pointer, if present, is opened for reading */ -zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_result phar_get_entry_data(phar_entry_data **ret, const zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security) /* {{{ */ { - phar_archive_data *phar; phar_entry_info *entry; bool for_write = mode[0] != 'r' || mode[1] == '+'; bool for_append = mode[0] == 'a'; bool for_create = mode[0] != 'r'; bool for_trunc = mode[0] == 'w'; - if (!ret) { - return FAILURE; - } - *ret = NULL; + *error = NULL; - if (error) { - *error = NULL; - } - - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 0, error); + if (!phar) { return FAILURE; } if (for_write && PHAR_G(readonly) && !phar->is_data) { - if (error) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, disabled by ini setting", path, fname); - } + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, disabled by ini setting", path, ZSTR_VAL(fname)); return FAILURE; } if (!path_len) { - if (error) { - spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" must not be empty", fname); - } + spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" must not be empty", ZSTR_VAL(fname)); return FAILURE; } really_get_entry: if (allow_dir) { - if ((entry = phar_get_entry_info_dir(phar, path, path_len, allow_dir, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) { + entry = phar_get_entry_info_dir(phar, path, path_len, allow_dir, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security); + if (!entry) { if (for_create && (!PHAR_G(readonly) || phar->is_data)) { return SUCCESS; } return FAILURE; } } else { - if ((entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) { + entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security); + if (!entry) { if (for_create && (!PHAR_G(readonly) || phar->is_data)) { return SUCCESS; } @@ -527,9 +495,7 @@ zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname if (for_write && phar->is_persistent) { if (FAILURE == phar_copy_on_write(&phar)) { - if (error) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, could not make cached phar writeable", path, fname); - } + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, could not make cached phar writeable", path, ZSTR_VAL(fname)); return FAILURE; } else { goto really_get_entry; @@ -537,16 +503,12 @@ zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname } if (entry->is_modified && !for_write) { - if (error) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for reading, writable file pointers are open", path, fname); - } + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for reading, writable file pointers are open", path, ZSTR_VAL(fname)); return FAILURE; } if (entry->fp_refcount && for_write) { - if (error) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, readable file pointers are open", path, fname); - } + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, readable file pointers are open", path, ZSTR_VAL(fname)); return FAILURE; } @@ -578,13 +540,13 @@ zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname return FAILURE; } } else if (for_append) { - phar_seek_efp(entry, 0, SEEK_END, 0, 0); + phar_seek_efp(entry, 0, SEEK_END, 0, false); } } else { if (for_write) { - if (entry->link) { - efree(entry->link); - entry->link = NULL; + if (entry->symlink) { + zend_string_release(entry->symlink); + entry->symlink = NULL; entry->tar_type = (entry->is_tar ? TAR_FILE : '\0'); } @@ -598,7 +560,7 @@ zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname } } } else { - if (FAILURE == phar_open_entry_fp(entry, error, 1)) { + if (FAILURE == phar_open_entry_fp(entry, error, true)) { return FAILURE; } } @@ -608,8 +570,8 @@ zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname (*ret)->position = 0; (*ret)->phar = phar; (*ret)->internal_file = entry; - (*ret)->fp = phar_get_efp(entry, 1); - if (entry->link) { + (*ret)->fp = phar_get_efp(entry, true); + if (entry->symlink) { phar_entry_info *link = phar_get_link_source(entry); if(!link) { efree(*ret); @@ -632,10 +594,9 @@ zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname /** * Create a new dummy file slot within a writeable phar for a newly created file */ -phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL phar_entry_data *phar_get_or_create_entry_data(zend_string *fname, char *path, size_t path_len, const char *mode, char allow_dir, char **error, bool security, uint32_t timestamp) /* {{{ */ { - phar_archive_data *phar; - phar_entry_info *entry, etemp; + phar_entry_info etemp; phar_entry_data *ret; const char *pcr_error; char is_dir; @@ -646,27 +607,24 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch is_dir = (path_len && path[path_len - 1] == '/') ? 1 : 0; - if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) { + phar_archive_data *phar = phar_get_archive(ZSTR_VAL(fname), ZSTR_LEN(fname), NULL, 0, error); + if (!phar) { return NULL; } - if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, allow_dir, error, security)) { + if (FAILURE == phar_get_entry_data(&ret, fname, path, path_len, mode, allow_dir, error, security)) { return NULL; } else if (ret) { return ret; } if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) { - if (error) { - spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error); - } + spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error); return NULL; } if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar)) { - if (error) { - spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be created, could not make cached phar writeable", path, fname); - } + spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be created, could not make cached phar writeable", path, ZSTR_VAL(fname)); return NULL; } @@ -679,9 +637,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch etemp.fp = php_stream_fopen_tmpfile(); if (!etemp.fp) { - if (error) { - spprintf(error, 0, "phar error: unable to create temporary file"); - } + *error = estrdup("phar error: unable to create temporary file"); efree(ret); return NULL; } @@ -700,7 +656,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch phar_add_virtual_dirs(phar, path, path_len); etemp.is_modified = 1; - etemp.timestamp = time(0); + etemp.timestamp = timestamp; etemp.is_crc_checked = 1; etemp.phar = phar; etemp.filename = zend_string_init(path, path_len, false); @@ -711,11 +667,11 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch etemp.tar_type = etemp.is_dir ? TAR_DIR : TAR_FILE; } - if (NULL == (entry = zend_hash_add_mem(&phar->manifest, etemp.filename, &etemp, sizeof(phar_entry_info)))) { + phar_entry_info *entry = zend_hash_add_mem(&phar->manifest, etemp.filename, &etemp, sizeof(phar_entry_info)); + if (!entry) { php_stream_close(etemp.fp); - if (error) { - spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", ZSTR_VAL(etemp.filename), phar->fname); - } + spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", + ZSTR_VAL(etemp.filename), ZSTR_VAL(phar->fname)); efree(ret); zend_string_efree(etemp.filename); return NULL; @@ -741,39 +697,38 @@ static inline void phar_set_pharfp(phar_archive_data *phar, php_stream *fp) PHAR_G(cached_fp)[phar->phar_pos].fp = fp; } -/* initialize a phar_archive_data's read-only fp for existing phar data */ -zend_result phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ +/* Initialize a phar_archive_data's read-only fp for existing phar data. + * The stream is owned by the `phar` object and must not be closed manually. */ +php_stream *phar_open_archive_fp(phar_archive_data *phar) /* {{{ */ { - if (phar_get_pharfp(phar)) { - return SUCCESS; + php_stream *stream = phar_get_pharfp(phar); + if (stream) { + return stream; } - if (php_check_open_basedir(phar->fname)) { - return FAILURE; + if (php_check_open_basedir(ZSTR_VAL(phar->fname))) { + return NULL; } - phar_set_pharfp(phar, php_stream_open_wrapper(phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, NULL)); - - if (!phar_get_pharfp(phar)) { - return FAILURE; - } + stream = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", IGNORE_URL|STREAM_MUST_SEEK, NULL); + phar_set_pharfp(phar, stream); - return SUCCESS; + return stream; } /* }}} */ /* copy file data from an existing to a new phar_entry_info that is not in the manifest */ -zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */ { phar_entry_info *link; - if (FAILURE == phar_open_entry_fp(source, error, 1)) { + if (FAILURE == phar_open_entry_fp(source, error, true)) { return FAILURE; } - if (dest->link) { - efree(dest->link); - dest->link = NULL; + if (dest->symlink) { + zend_string_release(dest->symlink); + dest->symlink = NULL; dest->tar_type = (dest->is_tar ? TAR_FILE : '\0'); } @@ -782,22 +737,21 @@ zend_result phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, c dest->is_modified = 1; dest->fp = php_stream_fopen_tmpfile(); if (dest->fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); + *error = estrdup("phar error: unable to create temporary file"); return EOF; } - phar_seek_efp(source, 0, SEEK_SET, 0, 1); + phar_seek_efp(source, 0, SEEK_SET, 0, true); link = phar_get_link_source(source); if (!link) { link = source; } - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), dest->fp, link->uncompressed_filesize, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, false), dest->fp, link->uncompressed_filesize, NULL)) { php_stream_close(dest->fp); dest->fp_type = PHAR_FP; - if (error) { - spprintf(error, 4096, "phar error: unable to copy contents of file \"%s\" to \"%s\" in phar archive \"%s\"", ZSTR_VAL(source->filename), ZSTR_VAL(dest->filename), source->phar->fname); - } + spprintf(error, 4096, "phar error: unable to copy contents of file \"%s\" to \"%s\" in phar archive \"%s\"", + ZSTR_VAL(source->filename), ZSTR_VAL(dest->filename), ZSTR_VAL(source->phar->fname)); return FAILURE; } @@ -831,19 +785,18 @@ static void phar_set_fp_type(phar_entry_info *entry, enum phar_fp_type type, zen /* open and decompress a compressed phar entry */ -zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, bool follow_links) /* {{{ */ { php_stream_filter *filter; phar_archive_data *phar = entry->phar; - char *filtername; zend_off_t loc; php_stream *ufp; phar_entry_data dummy; - if (follow_links && entry->link) { + if (follow_links && entry->symlink) { phar_entry_info *link_entry = phar_get_link_source(entry); if (link_entry && link_entry != entry) { - return phar_open_entry_fp(link_entry, error, 1); + return phar_open_entry_fp(link_entry, error, true); } } @@ -864,8 +817,8 @@ zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_ } if (!phar_get_pharfp(phar)) { - if (FAILURE == phar_open_archive_fp(phar)) { - spprintf(error, 4096, "phar error: Cannot open phar archive \"%s\" for reading", phar->fname); + if (!phar_open_archive_fp(phar)) { + spprintf(error, 4096, "phar error: Cannot open phar archive \"%s\" for reading", ZSTR_VAL(phar->fname)); return FAILURE; } } @@ -884,7 +837,7 @@ zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_ if (!phar_get_entrypufp(entry)) { phar_set_entrypufp(entry, php_stream_fopen_tmpfile()); if (!phar_get_entrypufp(entry)) { - spprintf(error, 4096, "phar error: Cannot open temporary file for decompressing phar archive \"%s\" file \"%s\"", phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: Cannot open temporary file for decompressing phar archive \"%s\" file \"%s\"", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } } @@ -899,14 +852,15 @@ zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_ ufp = phar_get_entrypufp(entry); - if ((filtername = phar_decompress_filter(entry, 0)) != NULL) { - filter = php_stream_filter_create(filtername, NULL, 0); + const char *filter_name = phar_decompress_filter(entry, false); + if (filter_name != NULL) { + filter = php_stream_filter_create(filter_name, NULL, 0); } else { filter = NULL; } if (!filter) { - spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->fname, phar_decompress_filter(entry, 1), ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", ZSTR_VAL(phar->fname), phar_decompress_filter(entry, true), ZSTR_VAL(entry->filename)); return FAILURE; } @@ -919,7 +873,7 @@ zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_ if (entry->uncompressed_filesize) { if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_entrypfp(entry), ufp, entry->compressed_filesize, NULL)) { - spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename)); php_stream_filter_remove(filter, 1); return FAILURE; } @@ -930,7 +884,7 @@ zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_ php_stream_filter_remove(filter, 1); if (php_stream_tell(ufp) - loc != (zend_off_t) entry->uncompressed_filesize) { - spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, ZSTR_VAL(entry->filename)); + spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", ZSTR_VAL(phar->fname), ZSTR_VAL(entry->filename)); return FAILURE; } @@ -950,37 +904,36 @@ zend_result phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_ /** * helper function to open an internal file's fp just-in-time */ -phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL phar_entry_info * phar_open_jit(const phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */ { - if (error) { - *error = NULL; - } + *error = NULL; /* seek to start of internal file and read it */ - if (FAILURE == phar_open_entry_fp(entry, error, 1)) { + if (FAILURE == phar_open_entry_fp(entry, error, true)) { return NULL; } - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 1)) { - spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", ZSTR_VAL(entry->filename), phar->fname); + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, true)) { + spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(phar->fname)); return NULL; } return entry; } /* }}} */ -zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */ +zend_result phar_free_alias(const phar_archive_data *phar) /* {{{ */ { if (phar->refcount || phar->is_persistent) { return FAILURE; } /* this archive has no open references, so emit a notice and remove it */ - if (zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) { + if (zend_hash_del(&(PHAR_G(phar_fname_map)), phar->fname) != SUCCESS) { return FAILURE; } /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; return SUCCESS; } @@ -990,11 +943,9 @@ zend_result phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_l * Looks up a phar archive in the filename map, connecting it to the alias * (if any) or returns null */ -zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */ +phar_archive_data* phar_get_archive(const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error) /* {{{ */ { - phar_archive_data *fd, *fd_ptr; - char *my_realpath, *save; - size_t save_len; + phar_archive_data *archive; phar_request_initialize(); @@ -1002,199 +953,169 @@ zend_result phar_get_archive(phar_archive_data **archive, char *fname, size_t fn *error = NULL; } - *archive = NULL; - - if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) { - *archive = PHAR_G(last_phar); + if (PHAR_G(last_phar) && zend_string_equals_cstr(PHAR_G(last_phar_name), fname, fname_len)) { + archive = PHAR_G(last_phar); if (alias && alias_len) { if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(PHAR_G(last_phar)->fname), fname); } - *archive = NULL; - return FAILURE; + return NULL; } - if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) { + if (PHAR_G(last_phar)->alias_len && zend_hash_str_exists(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len)) { zend_hash_str_del(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, *archive); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, archive); PHAR_G(last_alias) = alias; PHAR_G(last_alias_len) = alias_len; } - return SUCCESS; - } - - if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) { - fd = PHAR_G(last_phar); - fd_ptr = fd; - goto alias_success; + return archive; } if (alias && alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { -alias_success: - if (fname && (fname_len != fd_ptr->fname_len || strncmp(fname, fd_ptr->fname, fname_len))) { + /* If the alias stored in the last_phar cache matches, just use it directly */ + if (PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) { + archive = PHAR_G(last_phar); + } else { + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len); + } + + /* If we didn't find the alias, check in the cached manifest to see if we can find it */ + if (!archive && PHAR_G(manifest_cached)) { + archive = zend_hash_str_find_ptr(&cached_alias, alias, alias_len); + } + + if (archive) { + if (!zend_string_equals_cstr(archive->fname, fname, fname_len)) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(archive->fname), fname); } - if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) { + if (SUCCESS == phar_free_alias(archive)) { if (error) { efree(*error); *error = NULL; } } - return FAILURE; + return NULL; } - *archive = fd_ptr; - fd = fd_ptr; - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; PHAR_G(last_alias) = alias; PHAR_G(last_alias_len) = alias_len; - return SUCCESS; - } - - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) { - goto alias_success; + return archive; } } - my_realpath = NULL; - save = fname; - save_len = fname_len; - if (fname && fname_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) { - *archive = fd_ptr; - fd = fd_ptr; - + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len); + if (archive) { if (alias && alias_len) { - if (!fd->is_temporary_alias && (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len))) { + if (!archive->is_temporary_alias && (alias_len != archive->alias_len || memcmp(archive->alias, alias, alias_len))) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(archive->fname), fname); } - return FAILURE; + return NULL; } - if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len))) { - zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len); + if (archive->alias_len && zend_hash_str_exists(&(PHAR_G(phar_alias_map)), archive->alias, archive->alias_len)) { + zend_hash_str_del(&(PHAR_G(phar_alias_map)), archive->alias, archive->alias_len); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, archive); } - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - return SUCCESS; + return archive; } - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) { - *archive = fd_ptr; - fd = fd_ptr; - + if (PHAR_G(manifest_cached) && NULL != (archive = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) { /* this could be problematic - alias should never be different from manifest alias for cached phars */ - if (!fd->is_temporary_alias && alias && alias_len) { - if (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len)) { + if (!archive->is_temporary_alias && alias && alias_len) { + if (alias_len != archive->alias_len || memcmp(archive->alias, alias, alias_len)) { if (error) { - spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname); + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(archive->fname), fname); } - return FAILURE; + return NULL; } } - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - return SUCCESS; + return archive; } - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), save, save_len))) { - fd = *archive = fd_ptr; + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fname, fname_len); - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; - - return SUCCESS; + /* If we didn't find the fname in the alias map, check in the cached manifest to see if we can find it */ + if (!archive && PHAR_G(manifest_cached)) { + archive = zend_hash_str_find_ptr(&cached_alias, fname, fname_len); } - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, save, save_len))) { - fd = *archive = fd_ptr; - - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + if (archive) { + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - return SUCCESS; + return archive; } /* not found, try converting \ to / */ - my_realpath = expand_filepath(fname, my_realpath); + char *my_realpath = expand_filepath(fname, NULL); - if (my_realpath) { - fname_len = strlen(my_realpath); - fname = my_realpath; - } else { - return FAILURE; + if (UNEXPECTED(!my_realpath)) { + return NULL; } + + size_t my_realpath_len = strlen(my_realpath); #ifdef PHP_WIN32 - phar_unixify_path_separators(fname, fname_len); + phar_unixify_path_separators(my_realpath, my_realpath_len); #endif - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) { -realpath_success: - *archive = fd_ptr; - fd = fd_ptr; + archive = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), my_realpath, my_realpath_len); + + /* If we didn't find the path in the fname map, check in the cached manifest to see if we can find it */ + if (!archive && PHAR_G(manifest_cached)) { + archive = zend_hash_str_find_ptr(&cached_phars, my_realpath, my_realpath_len); + } + efree(my_realpath); + if (archive) { if (alias && alias_len) { - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, archive); } - efree(my_realpath); - - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_phar_name_len) = fd->fname_len; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = archive; + PHAR_G(last_phar_name) = archive->fname; + PHAR_G(last_alias) = archive->alias; + PHAR_G(last_alias_len) = archive->alias_len; - return SUCCESS; + return archive; } - - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) { - goto realpath_success; - } - - efree(my_realpath); } - return FAILURE; + return NULL; } /* }}} */ /** * Determine which stream compression filter (if any) we need to read this file */ -char * phar_compress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */ +const char * phar_compress_filter(const phar_entry_info *entry, bool return_unknown) /* {{{ */ { switch (entry->flags & PHAR_ENT_COMPRESSION_MASK) { case PHAR_ENT_COMPRESSED_GZ: @@ -1210,7 +1131,7 @@ char * phar_compress_filter(phar_entry_info * entry, int return_unknown) /* {{{ /** * Determine which stream decompression filter (if any) we need to read this file */ -char * phar_decompress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */ +const char * phar_decompress_filter(const phar_entry_info *entry, bool return_unknown) /* {{{ */ { uint32_t flags; @@ -1234,7 +1155,7 @@ char * phar_decompress_filter(phar_entry_info * entry, int return_unknown) /* {{ /** * retrieve information on a file contained within a phar, or null if it ain't there */ -phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security) /* {{{ */ +phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, bool security) /* {{{ */ { return phar_get_entry_info_dir(phar, path, path_len, 0, error, security); } @@ -1245,17 +1166,16 @@ phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t * valid pre-existing empty directory entries */ // TODO: convert this to use zend_string too -phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security) /* {{{ */ +phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, bool security) /* {{{ */ { const char *pcr_error; - phar_entry_info *entry; - int is_dir; + bool is_dir; #ifdef PHP_WIN32 phar_unixify_path_separators(path, path_len); #endif - is_dir = (path_len && (path[path_len - 1] == '/')) ? 1 : 0; + is_dir = path_len && (path[path_len - 1] == '/'); if (error) { *error = NULL; @@ -1293,7 +1213,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si path_len--; } - if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) { + phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len); + if (entry) { if (entry->is_deleted) { /* entry is deleted, but has not been flushed to disk yet */ return NULL; @@ -1337,7 +1258,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si size_t test_len; php_stream_statbuf ssb; - if (NULL == (entry = zend_hash_find_ptr(&phar->manifest, str_key))) { + entry = zend_hash_find_ptr(&phar->manifest, str_key); + if (!entry) { if (error) { spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", ZSTR_VAL(str_key)); } @@ -1386,7 +1308,8 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, si efree(test); - if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) { + entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len); + if (!entry) { if (error) { spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be retrieved after being mounted", path, test); } @@ -1420,36 +1343,44 @@ static int phar_hex_str(const char *digest, size_t digest_len, char **signature) /* }}} */ #ifndef PHAR_HAVE_OPENSSL -static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type) /* {{{ */ -{ - zval retval, zp[4]; - zend_string *str; - - zend_function *fn = NULL; - if (is_sign) { - fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_sign")); - } else { - fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_verify")); - } +ZEND_ATTRIBUTE_NONNULL static bool phar_call_openssl_verify( + php_stream *fp, + zend_off_t end, + zend_string *public_key, + const char *signature, + size_t signature_len, + uint32_t sig_type +) { + ZEND_ASSERT(signature_len != 0); + zend_function *fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_verify")); /* OpenSSL is not available, even as a shared module */ - if (fn == NULL) { - return FAILURE; + if (UNEXPECTED(fn == NULL)) { + return false; } - if (*signature_len) { - ZVAL_STRINGL(&zp[1], *signature, *signature_len); - } else { - ZVAL_EMPTY_STRING(&zp[1]); - } - ZVAL_STRINGL(&zp[2], key, key_len); + /* Read and copy stream content */ php_stream_rewind(fp); - str = php_stream_copy_to_mem(fp, (size_t) end, 0); - if (str) { - ZVAL_STR(&zp[0], str); - } else { - ZVAL_EMPTY_STRING(&zp[0]); - } + zend_string *str = php_stream_copy_to_mem(fp, (size_t) end, false); + /* No content thus signing must fail */ + if (UNEXPECTED(str == NULL)) { + return false; + } + + /* Set up parameters for call to openssl_verify() + * openssl_verify( + * string $data, + * string $signature, + * OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key, + * string|int $algorithm = OPENSSL_ALGO_SHA1, + * int $padding = 0 + * ): int|false + */ + zval retval, zp[4]; + ZVAL_STR(&zp[0], str); + ZVAL_STRINGL(&zp[1], signature, signature_len); + /* Note we do not own the lifetime of the public key, but it is fine as calling the function will increase the refcount) */ + ZVAL_STR(&zp[2], public_key); if (sig_type == PHAR_SIG_OPENSSL_SHA512) { ZVAL_LONG(&zp[3], 9); /* value from openssl.c #define OPENSSL_ALGO_SHA512 9 */ } else if (sig_type == PHAR_SIG_OPENSSL_SHA256) { @@ -1458,50 +1389,84 @@ static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, ze /* don't rely on default value which may change in the future */ ZVAL_LONG(&zp[3], 1); /* value from openssl.c #define OPENSSL_ALGO_SHA1 1 */ } + zend_call_known_function(fn, NULL, NULL, &retval, /* param_count */ 4, zp, NULL); + /* Free string arguments that we own */ + zval_ptr_dtor_str(&zp[0]); + zval_ptr_dtor_str(&zp[1]); + + /* Returns 1 if the signature is correct, 0 if it is incorrect, and -1 or false on error. */ + switch (Z_TYPE(retval)) { + case IS_LONG: + if (1 == Z_LVAL(retval)) { + return true; + } + ZEND_FALLTHROUGH; + default: + /* Unlikely, but the openssl_verify() function may be disabled and redefined in userland and return bollocks */ + zval_ptr_dtor(&retval); + return false; + } +} - if ((size_t)end != Z_STRLEN(zp[0])) { - zval_ptr_dtor_str(&zp[0]); - zval_ptr_dtor_str(&zp[1]); - zval_ptr_dtor_str(&zp[2]); +static zend_result phar_call_openssl_sign(php_stream *fp, zend_off_t end, const char *key, size_t key_len, char **signature, size_t *signature_len, uint32_t sig_type) /* {{{ */ +{ + ZEND_ASSERT(end != 0); + ZEND_ASSERT(*signature_len == 0); + zval retval, zp[4]; + + zend_function *fn = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("openssl_sign")); + + /* OpenSSL is not available, even as a shared module */ + if (fn == NULL) { + return FAILURE; + } + + /* Read and copy stream content */ + php_stream_rewind(fp); + zend_string *str = php_stream_copy_to_mem(fp, (size_t) end, false); + /* No content thus signing must fail */ + if (!str || (size_t)end != ZSTR_LEN(str)) { return FAILURE; } - Z_ADDREF(zp[0]); - if (is_sign) { - ZVAL_NEW_REF(&zp[1], &zp[1]); + /* Set up parameters for call to openssl_sign() + * openssl_sign( + * string $data, + * string &$signature, + * #[\SensitiveParameter] OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key, + * string|int $algorithm = OPENSSL_ALGO_SHA1, + * int $padding = 0 + * ): bool + */ + ZVAL_STR(&zp[0], str); + ZVAL_EMPTY_STRING(&zp[1]); + ZVAL_NEW_REF(&zp[1], &zp[1]); + ZVAL_STRINGL(&zp[2], key, key_len); + if (sig_type == PHAR_SIG_OPENSSL_SHA512) { + ZVAL_LONG(&zp[3], 9); /* value from openssl.c #define OPENSSL_ALGO_SHA512 9 */ + } else if (sig_type == PHAR_SIG_OPENSSL_SHA256) { + ZVAL_LONG(&zp[3], 7); /* value from openssl.c #define OPENSSL_ALGO_SHA256 7 */ } else { - Z_ADDREF(zp[1]); + /* don't rely on default value which may change in the future */ + ZVAL_LONG(&zp[3], 1); /* value from openssl.c #define OPENSSL_ALGO_SHA1 1 */ } - Z_ADDREF(zp[2]); zend_call_known_function(fn, NULL, NULL, &retval, /* param_count */ 4, zp, NULL); - Z_DELREF(zp[0]); - - if (is_sign) { - ZVAL_UNREF(&zp[1]); - } else { - Z_DELREF(zp[1]); - } - Z_DELREF(zp[2]); + ZVAL_UNREF(&zp[1]); zval_ptr_dtor_str(&zp[0]); zval_ptr_dtor_str(&zp[2]); switch (Z_TYPE(retval)) { - case IS_LONG: - zval_ptr_dtor(&zp[1]); - if (1 == Z_LVAL(retval)) { - return SUCCESS; - } - return FAILURE; case IS_TRUE: *signature = estrndup(Z_STRVAL(zp[1]), Z_STRLEN(zp[1])); *signature_len = Z_STRLEN(zp[1]); zval_ptr_dtor(&zp[1]); return SUCCESS; - case IS_FALSE: default: + /* Unlikely, but the openssl_sign() function may be disabled and redefined in userland and return bollocks */ + zval_ptr_dtor(&retval); zval_ptr_dtor(&zp[1]); return FAILURE; } @@ -1509,7 +1474,7 @@ static zend_result phar_call_openssl_signverify(bool is_sign, php_stream *fp, ze /* }}} */ #endif /* #ifndef PHAR_HAVE_OPENSSL */ -zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ +zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, const char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */ { size_t read_size, len; zend_off_t read_len; @@ -1534,8 +1499,6 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s } else { mdtype = EVP_sha1(); } -#else - size_t tempsig; #endif zend_string *pubkey = NULL; char *pfile; @@ -1543,7 +1506,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s #ifndef PHAR_HAVE_OPENSSL if (!zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) { if (error) { - spprintf(error, 0, "openssl not loaded"); + *error = estrdup("openssl not loaded"); } return FAILURE; } @@ -1553,40 +1516,41 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s pfp = php_stream_open_wrapper(pfile, "rb", 0, NULL); efree(pfile); - if (!pfp || !(pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0)) || !ZSTR_LEN(pubkey)) { - if (pfp) { - php_stream_close(pfp); - } + if (!pfp) { if (error) { - spprintf(error, 0, "openssl public key could not be read"); + *error = estrdup("openssl public key could not be read"); } return FAILURE; } + pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0); php_stream_close(pfp); -#ifndef PHAR_HAVE_OPENSSL - tempsig = sig_len; + if (!pubkey || !ZSTR_LEN(pubkey)) { + if (error) { + *error = estrdup("openssl public key could not be read"); + } + return FAILURE; + } - if (FAILURE == phar_call_openssl_signverify(false, fp, end_of_phar, ZSTR_VAL(pubkey), ZSTR_LEN(pubkey), &sig, &tempsig, sig_type)) { +#ifndef PHAR_HAVE_OPENSSL + if (!phar_call_openssl_verify(fp, end_of_phar, pubkey, sig, sig_len, sig_type)) { zend_string_release_ex(pubkey, 0); if (error) { - spprintf(error, 0, "openssl signature could not be verified"); + *error = estrdup("openssl signature could not be verified"); } return FAILURE; } - zend_string_release_ex(pubkey, 0); - - sig_len = tempsig; + zend_string_release_ex(pubkey, false); #else in = BIO_new_mem_buf(ZSTR_VAL(pubkey), ZSTR_LEN(pubkey)); if (NULL == in) { zend_string_release_ex(pubkey, 0); if (error) { - spprintf(error, 0, "openssl signature could not be processed"); + *error = estrdup("openssl signature could not be processed"); } return FAILURE; } @@ -1597,7 +1561,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (NULL == key) { if (error) { - spprintf(error, 0, "openssl signature could not be processed"); + *error = estrdup("openssl signature could not be processed"); } return FAILURE; } @@ -1607,8 +1571,9 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (md_ctx) { EVP_MD_CTX_destroy(md_ctx); } + EVP_PKEY_free(key); if (error) { - spprintf(error, 0, "openssl signature could not be verified"); + *error = estrdup("openssl signature could not be verified"); } return FAILURE; } @@ -1640,7 +1605,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s EVP_MD_CTX_destroy(md_ctx); if (error) { - spprintf(error, 0, "broken openssl signature"); + *error = estrdup("broken openssl signature"); } return FAILURE; @@ -1650,7 +1615,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s EVP_MD_CTX_destroy(md_ctx); #endif - *signature_len = phar_hex_str((const char*)sig, sig_len, signature); + *signature_len = phar_hex_str(sig, sig_len, signature); } break; case PHAR_SIG_SHA512: { @@ -1659,7 +1624,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (sig_len < sizeof(digest)) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken openssl signature"); } return FAILURE; } @@ -1685,7 +1650,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (memcmp(digest, sig, sizeof(digest))) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken openssl signature"); } return FAILURE; } @@ -1699,7 +1664,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (sig_len < sizeof(digest)) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken openssl signature"); } return FAILURE; } @@ -1725,7 +1690,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (memcmp(digest, sig, sizeof(digest))) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken signature"); } return FAILURE; } @@ -1739,7 +1704,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (sig_len < sizeof(digest)) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken signature"); } return FAILURE; } @@ -1765,7 +1730,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (memcmp(digest, sig, sizeof(digest))) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken signature"); } return FAILURE; } @@ -1779,7 +1744,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (sig_len < sizeof(digest)) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken signature"); } return FAILURE; } @@ -1805,7 +1770,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s if (memcmp(digest, sig, sizeof(digest))) { if (error) { - spprintf(error, 0, "broken signature"); + *error = estrdup("broken signature"); } return FAILURE; } @@ -1815,7 +1780,7 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s } default: if (error) { - spprintf(error, 0, "broken or unsupported signature"); + *error = estrdup("broken or unsupported signature"); } return FAILURE; } @@ -1823,8 +1788,9 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s } /* }}} */ -zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_string* phar_create_signature(phar_archive_data *phar, php_stream *fp, char **error) /* {{{ */ { + zend_string *signature = NULL; unsigned char buf[1024]; size_t sig_len; @@ -1847,8 +1813,7 @@ zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char } PHP_SHA512Final(digest, &context); - *signature = estrndup((char *) digest, 64); - *signature_length = 64; + signature = zend_string_init((const char*)digest, 64, false); break; } default: @@ -1865,8 +1830,7 @@ zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char } PHP_SHA256Final(digest, &context); - *signature = estrndup((char *) digest, 32); - *signature_length = 32; + signature = zend_string_init((const char*)digest, 32, false); break; } case PHAR_SIG_OPENSSL_SHA512: @@ -1891,29 +1855,23 @@ zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len)); if (in == NULL) { - if (error) { - spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", phar->fname); - } - return FAILURE; + spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); + return NULL; } key = PEM_read_bio_PrivateKey(in, NULL,NULL, ""); BIO_free(in); if (!key) { - if (error) { - spprintf(error, 0, "unable to process private key"); - } - return FAILURE; + *error = estrdup("unable to process private key"); + return NULL; } md_ctx = EVP_MD_CTX_create(); if (md_ctx == NULL) { EVP_PKEY_free(key); - if (error) { - spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname); - } - return FAILURE; + spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); + return NULL; } siglen = EVP_PKEY_size(key); @@ -1921,51 +1879,48 @@ zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char if (!EVP_SignInit(md_ctx, mdtype)) { EVP_PKEY_free(key); + EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); - if (error) { - spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname); - } - return FAILURE; + spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); + return NULL; } while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { if (!EVP_SignUpdate(md_ctx, buf, sig_len)) { EVP_PKEY_free(key); + EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); - if (error) { - spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", phar->fname); - } - return FAILURE; + spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); + return NULL; } } if (!EVP_SignFinal (md_ctx, sigbuf, &siglen, key)) { EVP_PKEY_free(key); + EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); - if (error) { - spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); - } - return FAILURE; + spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); + return NULL; } sigbuf[siglen] = '\0'; EVP_PKEY_free(key); EVP_MD_CTX_destroy(md_ctx); + signature = zend_string_init((const char*)sigbuf, siglen, false); + efree(sigbuf); #else size_t siglen; sigbuf = NULL; siglen = 0; php_stream_seek(fp, 0, SEEK_END); - if (FAILURE == phar_call_openssl_signverify(true, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) { - if (error) { - spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname); - } - return FAILURE; + if (FAILURE == phar_call_openssl_sign(fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) { + spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); + return NULL; } + signature = zend_string_init((const char*)sigbuf, siglen, false); + efree(sigbuf); #endif - *signature = (char *) sigbuf; - *signature_length = siglen; } break; case PHAR_SIG_SHA1: { @@ -1979,8 +1934,7 @@ zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char } PHP_SHA1Final(digest, &context); - *signature = estrndup((char *) digest, 20); - *signature_length = 20; + signature = zend_string_init((const char*)digest, 20, false); break; } case PHAR_SIG_MD5: { @@ -1994,19 +1948,18 @@ zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char } PHP_MD5Final(digest, &context); - *signature = estrndup((char *) digest, 16); - *signature_length = 16; + signature = zend_string_init((const char*)digest, 16, false); break; } } - phar->sig_len = phar_hex_str((const char *)*signature, *signature_length, &phar->signature); - return SUCCESS; + phar->sig_len = phar_hex_str(ZSTR_VAL(signature), ZSTR_LEN(signature), &phar->signature); + return signature; } /* }}} */ // TODO: convert this to zend_string too -void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len) /* {{{ */ +void phar_add_virtual_dirs(phar_archive_data *phar, const char *filename, size_t filename_len) /* {{{ */ { const char *s; zend_string *str; @@ -2037,8 +1990,8 @@ static int phar_update_cached_entry(zval *data, void *argument) /* {{{ */ entry->phar = (phar_archive_data *)argument; - if (entry->link) { - entry->link = estrdup(entry->link); + if (entry->symlink) { + zend_string_addref(entry->symlink); } if (entry->tmp) { @@ -2062,19 +2015,15 @@ static void phar_manifest_copy_ctor(zval *zv) /* {{{ */ } /* }}} */ -static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ +static phar_archive_data* phar_copy_cached_phar(const phar_archive_data *persistent_phar) /* {{{ */ { - phar_archive_data *phar; HashTable newmanifest; - char *fname; phar_archive_object *objphar; - phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data)); - *phar = **pphar; + phar_archive_data *phar = emalloc(sizeof(phar_archive_data)); + *phar = *persistent_phar; phar->is_persistent = 0; - fname = phar->fname; - phar->fname = estrndup(phar->fname, phar->fname_len); - phar->ext = phar->fname + (phar->ext - fname); + zend_string_addref(phar->fname); if (phar->alias) { phar->alias = estrndup(phar->alias, phar->alias_len); @@ -2086,45 +2035,40 @@ static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */ phar_metadata_tracker_clone(&phar->metadata_tracker); - zend_hash_init(&newmanifest, sizeof(phar_entry_info), - zend_get_hash_value, destroy_phar_manifest_entry, 0); - zend_hash_copy(&newmanifest, &(*pphar)->manifest, phar_manifest_copy_ctor); + zend_hash_init(&newmanifest, sizeof(phar_entry_info), NULL, destroy_phar_manifest_entry, 0); + zend_hash_copy(&newmanifest, &persistent_phar->manifest, phar_manifest_copy_ctor); zend_hash_apply_with_argument(&newmanifest, phar_update_cached_entry, (void *)phar); phar->manifest = newmanifest; - zend_hash_init(&phar->mounted_dirs, sizeof(char *), - zend_get_hash_value, NULL, 0); - zend_hash_init(&phar->virtual_dirs, sizeof(char *), - zend_get_hash_value, NULL, 0); - zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL); - *pphar = phar; + zend_hash_init(&phar->mounted_dirs, sizeof(char *), NULL, NULL, 0); + zend_hash_init(&phar->virtual_dirs, sizeof(char *), NULL, NULL, 0); + zend_hash_copy(&phar->virtual_dirs, &persistent_phar->virtual_dirs, NULL); /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */ ZEND_HASH_MAP_FOREACH_PTR(&PHAR_G(phar_persist_map), objphar) { - if (objphar->archive->fname_len == phar->fname_len && !memcmp(objphar->archive->fname, phar->fname, phar->fname_len)) { + if (zend_string_equals(objphar->archive->fname, phar->fname)) { objphar->archive = phar; } } ZEND_HASH_FOREACH_END(); + return phar; } /* }}} */ zend_result phar_copy_on_write(phar_archive_data **pphar) /* {{{ */ { - zval zv, *pzv; - phar_archive_data *newpphar; + phar_archive_data *newpphar = phar_copy_cached_phar(*pphar); - ZVAL_PTR(&zv, *pphar); - if (NULL == (pzv = zend_hash_str_add(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len, &zv))) { + zval *pzv = zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), newpphar->fname, newpphar); + if (!pzv) { return FAILURE; } - phar_copy_cached_phar((phar_archive_data **)&Z_PTR_P(pzv)); - newpphar = Z_PTR_P(pzv); /* invalidate phar cache */ PHAR_G(last_phar) = NULL; - PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + PHAR_G(last_alias) = NULL; + PHAR_G(last_phar_name) = NULL; if (newpphar->alias_len && NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), newpphar->alias, newpphar->alias_len, newpphar)) { - zend_hash_str_del(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), newpphar->fname); return FAILURE; } diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 0ee958bda24f..7811865e3e69 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -2,15 +2,13 @@ +----------------------------------------------------------------------+ | ZIP archive support for Phar | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gregory Beaver | +----------------------------------------------------------------------+ @@ -41,7 +39,7 @@ static inline void phar_write_16(char buffer[2], uint32_t value) # define PHAR_SET_32(var, value) phar_write_32(var, (uint32_t) (value)); # define PHAR_SET_16(var, value) phar_write_16(var, (uint16_t) (value)); -static int phar_zip_process_extra(php_stream *fp, phar_entry_info *entry, uint16_t len) /* {{{ */ +static zend_result phar_zip_process_extra(php_stream *fp, phar_entry_info *entry, uint16_t len) /* {{{ */ { union { phar_zip_extra_field_header header; @@ -226,15 +224,21 @@ static char *phar_find_eocd(const char *s, size_t n) * This is used by phar_open_from_fp to process a zip-based phar, but can be called * directly. */ -int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, char **error) /* {{{ */ -{ +zend_result phar_parse_zipfile( + php_stream *fp, + const char *fname, + size_t fname_len, + /* copyable & hash update */ zend_string *alias, + phar_archive_data** pphar, + char **error +) { phar_zip_dir_end locator; char buf[sizeof(locator) + 65536]; zend_off_t size; uint16_t i; phar_archive_data *mydata = NULL; phar_entry_info entry = {0}; - char *p = buf, *ext, *actual_alias = NULL; + char *ext, *actual_alias = NULL; char *metadata = NULL; size = php_stream_tell(fp); @@ -261,73 +265,72 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia return FAILURE; } - if ((p = phar_find_eocd(buf, size)) != NULL) { - memcpy((void *)&locator, (void *) p, sizeof(locator)); - if (PHAR_GET_16(locator.centraldisk) != 0 || PHAR_GET_16(locator.disknumber) != 0) { - /* split archives not handled */ - php_stream_close(fp); - if (error) { - spprintf(error, 4096, "phar error: split archives spanning multiple zips cannot be processed in zip-based phar \"%s\"", fname); - } - return FAILURE; + char *p = phar_find_eocd(buf, size); + if (!p) { + php_stream_close(fp); + if (error) { + spprintf(error, 4096, "phar error: end of central directory not found in zip-based phar \"%s\"", fname); } + return FAILURE; + } - if (PHAR_GET_16(locator.counthere) != PHAR_GET_16(locator.count)) { - if (error) { - spprintf(error, 4096, "phar error: corrupt zip archive, conflicting file count in end of central directory record in zip-based phar \"%s\"", fname); - } - php_stream_close(fp); - return FAILURE; + memcpy((void *)&locator, (void *) p, sizeof(locator)); + if (PHAR_GET_16(locator.centraldisk) != 0 || PHAR_GET_16(locator.disknumber) != 0) { + /* split archives not handled */ + php_stream_close(fp); + if (error) { + spprintf(error, 4096, "phar error: split archives spanning multiple zips cannot be processed in zip-based phar \"%s\"", fname); } + return FAILURE; + } - mydata = pecalloc(1, sizeof(phar_archive_data), PHAR_G(persist)); - mydata->is_persistent = PHAR_G(persist); + if (PHAR_GET_16(locator.counthere) != PHAR_GET_16(locator.count)) { + if (error) { + spprintf(error, 4096, "phar error: corrupt zip archive, conflicting file count in end of central directory record in zip-based phar \"%s\"", fname); + } + php_stream_close(fp); + return FAILURE; + } - /* read in archive comment, if any */ - if (PHAR_GET_16(locator.comment_len)) { + mydata = pecalloc(1, sizeof(phar_archive_data), PHAR_G(persist)); + mydata->is_persistent = PHAR_G(persist); - metadata = p + sizeof(locator); + /* read in archive comment, if any */ + if (PHAR_GET_16(locator.comment_len)) { - if (PHAR_GET_16(locator.comment_len) != size - (metadata - buf)) { - if (error) { - spprintf(error, 4096, "phar error: corrupt zip archive, zip file comment truncated in zip-based phar \"%s\"", fname); - } - php_stream_close(fp); - pefree(mydata, mydata->is_persistent); - return FAILURE; - } + metadata = p + sizeof(locator); - phar_parse_metadata_lazy(metadata, &mydata->metadata_tracker, PHAR_GET_16(locator.comment_len), mydata->is_persistent); - } else { - ZVAL_UNDEF(&mydata->metadata_tracker.val); + if (PHAR_GET_16(locator.comment_len) != size - (metadata - buf)) { + if (error) { + spprintf(error, 4096, "phar error: corrupt zip archive, zip file comment truncated in zip-based phar \"%s\"", fname); + } + php_stream_close(fp); + pefree(mydata, mydata->is_persistent); + return FAILURE; } - goto foundit; + phar_parse_metadata_lazy(metadata, &mydata->metadata_tracker, PHAR_GET_16(locator.comment_len), mydata->is_persistent); + } else { + ZVAL_UNDEF(&mydata->metadata_tracker.val); } - php_stream_close(fp); - - if (error) { - spprintf(error, 4096, "phar error: end of central directory not found in zip-based phar \"%s\"", fname); + mydata->fname = zend_string_init(fname, fname_len, mydata->is_persistent); + if (mydata->is_persistent) { + GC_MAKE_PERSISTENT_LOCAL(mydata->fname); } - - return FAILURE; -foundit: - mydata->fname = pestrndup(fname, fname_len, mydata->is_persistent); #ifdef PHP_WIN32 - phar_unixify_path_separators(mydata->fname, fname_len); + phar_unixify_path_separators(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname)); #endif mydata->is_zip = 1; - mydata->fname_len = fname_len; - ext = strrchr(mydata->fname, '/'); + ext = strrchr(ZSTR_VAL(mydata->fname), '/'); if (ext) { - mydata->ext = memchr(ext, '.', (mydata->fname + fname_len) - ext); + mydata->ext = memchr(ext, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - ext); if (mydata->ext == ext) { - mydata->ext = memchr(ext + 1, '.', (mydata->fname + fname_len) - ext - 1); + mydata->ext = memchr(ext + 1, '.', (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - ext - 1); } if (mydata->ext) { - mydata->ext_len = (mydata->fname + fname_len) - mydata->ext; + mydata->ext_len = (ZSTR_VAL(mydata->fname) + ZSTR_LEN(mydata->fname)) - mydata->ext; } } @@ -336,38 +339,17 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia php_stream_seek(fp, PHAR_GET_32(locator.cdir_offset), SEEK_SET); /* read in central directory */ zend_hash_init(&mydata->manifest, PHAR_GET_16(locator.count), - zend_get_hash_value, destroy_phar_manifest_entry, (bool)mydata->is_persistent); + zend_get_hash_value, destroy_phar_manifest_entry, mydata->is_persistent); zend_hash_init(&mydata->mounted_dirs, 5, - zend_get_hash_value, NULL, (bool)mydata->is_persistent); + zend_get_hash_value, NULL, mydata->is_persistent); zend_hash_init(&mydata->virtual_dirs, PHAR_GET_16(locator.count) * 2, - zend_get_hash_value, NULL, (bool)mydata->is_persistent); + zend_get_hash_value, NULL, mydata->is_persistent); entry.phar = mydata; entry.is_zip = 1; entry.fp_type = PHAR_FP; entry.is_persistent = mydata->is_persistent; -#define PHAR_ZIP_FAIL_FREE(errmsg, save) \ - zend_hash_destroy(&mydata->manifest); \ - HT_INVALIDATE(&mydata->manifest); \ - zend_hash_destroy(&mydata->mounted_dirs); \ - HT_INVALIDATE(&mydata->mounted_dirs); \ - zend_hash_destroy(&mydata->virtual_dirs); \ - HT_INVALIDATE(&mydata->virtual_dirs); \ - php_stream_close(fp); \ - phar_metadata_tracker_free(&mydata->metadata_tracker, mydata->is_persistent); \ - if (mydata->signature) { \ - efree(mydata->signature); \ - } \ - if (error) { \ - spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, mydata->fname); \ - } \ - pefree(mydata->fname, mydata->is_persistent); \ - if (mydata->alias) { \ - pefree(mydata->alias, mydata->is_persistent); \ - } \ - pefree(mydata, mydata->is_persistent); \ - efree(save); \ - return FAILURE; #define PHAR_ZIP_FAIL(errmsg) \ + efree(actual_alias); \ zend_hash_destroy(&mydata->manifest); \ HT_INVALIDATE(&mydata->manifest); \ zend_hash_destroy(&mydata->mounted_dirs); \ @@ -380,9 +362,9 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia efree(mydata->signature); \ } \ if (error) { \ - spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, mydata->fname); \ + spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, ZSTR_VAL(mydata->fname)); \ } \ - pefree(mydata->fname, mydata->is_persistent); \ + zend_string_release_ex(mydata->fname, mydata->is_persistent); \ if (mydata->alias) { \ pefree(mydata->alias, mydata->is_persistent); \ } \ @@ -522,14 +504,13 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia mydata->sig_flags = PHAR_GET_32(sig); if (FAILURE == phar_verify_signature(sigfile, php_stream_tell(sigfile), mydata->sig_flags, sig + 8, entry.uncompressed_filesize - 8, fname, &mydata->signature, &sig_len, error)) { efree(sig); + php_stream_close(sigfile); if (error) { - char *save; - php_stream_close(sigfile); - spprintf(&save, 4096, "signature cannot be verified: %s", *error); + char errmsg[128]; + snprintf(errmsg, sizeof(errmsg), "signature cannot be verified: %s", *error); efree(*error); - PHAR_ZIP_FAIL_FREE(save, save); + PHAR_ZIP_FAIL(errmsg); } else { - php_stream_close(sigfile); PHAR_ZIP_FAIL("signature cannot be verified"); } } @@ -641,13 +622,6 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia zend_off_t restore_pos = php_stream_tell(fp); php_stream_seek(fp, entry.offset, SEEK_SET); - /* these next lines should be for php < 5.2.6 after 5.3 filters are fixed */ - fp->writepos = 0; - fp->readpos = 0; - php_stream_seek(fp, entry.offset, SEEK_SET); - fp->writepos = 0; - fp->readpos = 0; - /* the above lines should be for php < 5.2.6 after 5.3 filters are fixed */ mydata->alias_len = entry.uncompressed_filesize; if (entry.flags & PHAR_ENT_COMPRESSED_GZ) { @@ -674,7 +648,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia } } - if (!entry.uncompressed_filesize || !actual_alias) { + if (!entry.uncompressed_filesize) { php_stream_filter_remove(filter, 1); zend_string_release_ex(entry.filename, entry.is_persistent); PHAR_ZIP_FAIL("unable to read in alias, truncated"); @@ -707,7 +681,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia } } - if (!entry.uncompressed_filesize || !actual_alias) { + if (!entry.uncompressed_filesize) { php_stream_filter_remove(filter, 1); zend_string_release_ex(entry.filename, entry.is_persistent); PHAR_ZIP_FAIL("unable to read in alias, truncated"); @@ -730,7 +704,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia } } - if (!entry.uncompressed_filesize || !actual_alias) { + if (!entry.uncompressed_filesize) { zend_string_release_ex(entry.filename, entry.is_persistent); PHAR_ZIP_FAIL("unable to read in alias, truncated"); } @@ -757,29 +731,29 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia mydata->fp = fp; - zend_hash_str_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len, mydata); + zend_hash_add_ptr(&(PHAR_G(phar_fname_map)), mydata->fname, mydata); if (actual_alias) { - phar_archive_data *fd_ptr; if (!phar_validate_alias(actual_alias, mydata->alias_len)) { if (error) { spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", actual_alias, fname); } efree(actual_alias); - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); return FAILURE; } mydata->is_temporary_alias = 0; - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, mydata->alias_len)) { + phar_archive_data *fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with implicit alias, alias is already in use", fname); } efree(actual_alias); - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); return FAILURE; } } @@ -792,24 +766,23 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata); } else { - phar_archive_data *fd_ptr; - - if (alias_len) { - if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) { - if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len)) { + if (alias) { + phar_archive_data *fd_ptr = zend_hash_find_ptr(&(PHAR_G(phar_alias_map)), alias); + if (fd_ptr) { + if (SUCCESS != phar_free_alias(fd_ptr)) { if (error) { spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with explicit alias, alias is already in use", fname); } - zend_hash_str_del(&(PHAR_G(phar_fname_map)), mydata->fname, fname_len); + zend_hash_del(&(PHAR_G(phar_fname_map)), mydata->fname); return FAILURE; } } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, mydata); - mydata->alias = pestrndup(alias, alias_len, mydata->is_persistent); - mydata->alias_len = alias_len; + zend_hash_add_ptr(&(PHAR_G(phar_alias_map)), alias, mydata); + mydata->alias = pestrndup(ZSTR_VAL(alias), ZSTR_LEN(alias), mydata->is_persistent); + mydata->alias_len = ZSTR_LEN(alias); } else { - mydata->alias = pestrndup(mydata->fname, fname_len, mydata->is_persistent); + mydata->alias = pestrndup(ZSTR_VAL(mydata->fname), ZSTR_LEN(mydata->fname), mydata->is_persistent); mydata->alias_len = fname_len; } @@ -827,18 +800,22 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia /** * Create or open a zip-based phar for writing */ -int phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error) /* {{{ */ -{ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 5, 6) zend_result phar_open_or_create_zip( + zend_string *fname, + /* copyable & hash update */ zend_string *alias, + bool is_data, + uint32_t options, + phar_archive_data** pphar, + char **error +) { phar_archive_data *phar; - int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, is_data, options, &phar, error); + zend_result ret = phar_create_or_parse_filename(fname, alias, is_data, options, &phar, error); if (FAILURE == ret) { return FAILURE; } - if (pphar) { - *pphar = phar; - } + *pphar = phar; phar->is_data = is_data; @@ -853,13 +830,10 @@ int phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t a } /* we've reached here - the phar exists and is a regular phar */ - if (error) { - spprintf(error, 4096, "phar zip error: phar \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a zip-based phar", fname); - } + spprintf(error, 4096, "phar zip error: phar \"%s\" already exists as a regular phar and must be deleted from disk prior to creating as a zip-based phar", ZSTR_VAL(fname)); return FAILURE; } -/* }}} */ struct _phar_zip_pass { php_stream *filefp; @@ -878,7 +852,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ struct _phar_zip_pass *p; uint32_t newcrc32; zend_off_t offset; - int not_really_modified = 0; + bool not_really_modified = false; p = (struct _phar_zip_pass*) arg; uint16_t general_purpose_flags; @@ -887,7 +861,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ } if (entry->is_deleted) { - if (entry->fp_refcount <= 0) { + if (phar_entry_can_remove(entry)) { return ZEND_HASH_APPLY_REMOVE; } else { /* we can't delete this in-memory until it is closed */ @@ -952,23 +926,23 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ goto continue_dir; } - if (FAILURE == phar_open_entry_fp(entry, p->error, 0)) { - spprintf(p->error, 0, "unable to open file contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + if (FAILURE == phar_open_entry_fp(entry, p->error, false)) { + spprintf(p->error, 0, "unable to open file contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } /* we can be modified and already be compressed, such as when chmod() is executed */ if (entry->flags & PHAR_ENT_COMPRESSION_MASK && (entry->old_flags == entry->flags || !entry->old_flags)) { - not_really_modified = 1; + not_really_modified = true; goto is_compressed; } - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { - spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { + spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } - efp = phar_get_efp(entry, 0); + efp = phar_get_efp(entry, false); newcrc32 = php_crc32_bulk_init(); php_crc32_stream_bulk_update(&newcrc32, efp, entry->uncompressed_filesize); @@ -985,13 +959,13 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ goto not_compressed; } - filter = php_stream_filter_create(phar_compress_filter(entry, 0), NULL, 0); + filter = php_stream_filter_create(phar_compress_filter(entry, false), NULL, 0); if (!filter) { if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { - spprintf(p->error, 0, "unable to gzip compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to gzip compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); } else { - spprintf(p->error, 0, "unable to bzip2 compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to bzip2 compress file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); } return ZEND_HASH_APPLY_STOP; } @@ -1003,15 +977,15 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ if (!entry->cfp) { php_stream_filter_free(filter); - spprintf(p->error, 0, "unable to create temporary file for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to create temporary file for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } php_stream_flush(efp); - if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) { + if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, false)) { php_stream_filter_free(filter); - spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to seek to start of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -1019,7 +993,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ if (SUCCESS != php_stream_copy_to_stream_ex(efp, entry->cfp, entry->uncompressed_filesize, NULL)) { php_stream_filter_remove(filter, 1); - spprintf(p->error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } @@ -1042,7 +1016,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ PHAR_SET_32(local.compsize, entry->compressed_filesize); if (p->old) { if (-1 == php_stream_seek(p->old, entry->offset_abs, SEEK_SET)) { - spprintf(p->error, 0, "unable to seek to start of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to seek to start of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1061,75 +1035,75 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ offset = entry->header_offset + sizeof(local) + ZSTR_LEN(entry->filename) + (entry->is_dir ? 1 : 0) + sizeof(perms); if (sizeof(local) != php_stream_write(p->filefp, (char *)&local, sizeof(local))) { - spprintf(p->error, 0, "unable to write local file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write local file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (sizeof(central) != php_stream_write(p->centralfp, (char *)¢ral, sizeof(central))) { - spprintf(p->error, 0, "unable to write central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (entry->is_dir) { if (ZSTR_LEN(entry->filename) != php_stream_write(p->filefp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (1 != php_stream_write(p->filefp, "/", 1)) { - spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to local directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (ZSTR_LEN(entry->filename) != php_stream_write(p->centralfp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (1 != php_stream_write(p->centralfp, "/", 1)) { - spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to central directory entry for directory \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } else { if (ZSTR_LEN(entry->filename) != php_stream_write(p->filefp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to local directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to local directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (ZSTR_LEN(entry->filename) != php_stream_write(p->centralfp, ZSTR_VAL(entry->filename), ZSTR_LEN(entry->filename))) { - spprintf(p->error, 0, "unable to write filename to central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write filename to central directory entry for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } if (sizeof(perms) != php_stream_write(p->filefp, (char *)&perms, sizeof(perms))) { - spprintf(p->error, 0, "unable to write local extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write local extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (sizeof(perms) != php_stream_write(p->centralfp, (char *)&perms, sizeof(perms))) { - spprintf(p->error, 0, "unable to write central extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write central extra permissions file header of file \"%s\" to zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } if (!not_really_modified && entry->is_modified) { if (entry->cfp) { if (SUCCESS != php_stream_copy_to_stream_ex(entry->cfp, p->filefp, entry->compressed_filesize, NULL)) { - spprintf(p->error, 0, "unable to write compressed contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write compressed contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } php_stream_close(entry->cfp); entry->cfp = NULL; } else { - if (FAILURE == phar_open_entry_fp(entry, p->error, 0)) { + if (FAILURE == phar_open_entry_fp(entry, p->error, false)) { return ZEND_HASH_APPLY_STOP; } - phar_seek_efp(entry, 0, SEEK_SET, 0, 0); + phar_seek_efp(entry, 0, SEEK_SET, 0, false); - if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, 0), p->filefp, entry->uncompressed_filesize, NULL)) { - spprintf(p->error, 0, "unable to write contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(entry, false), p->filefp, entry->uncompressed_filesize, NULL)) { + spprintf(p->error, 0, "unable to write contents of file \"%s\" in zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1145,17 +1119,17 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ /* open file pointers refer to this fp, do not free the stream */ switch (entry->fp_type) { case PHAR_FP: - p->free_fp = 0; + p->free_fp = false; break; case PHAR_UFP: - p->free_ufp = 0; + p->free_ufp = false; default: break; } } if (!entry->is_dir && entry->compressed_filesize && SUCCESS != php_stream_copy_to_stream_ex(p->old, p->filefp, entry->compressed_filesize, NULL)) { - spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to copy contents of file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1166,7 +1140,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{ if (entry->metadata_tracker.str) { if (ZSTR_LEN(entry->metadata_tracker.str) != php_stream_write(p->centralfp, ZSTR_VAL(entry->metadata_tracker.str), ZSTR_LEN(entry->metadata_tracker.str))) { - spprintf(p->error, 0, "unable to write metadata as file comment for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), entry->phar->fname); + spprintf(p->error, 0, "unable to write metadata as file comment for file \"%s\" while creating zip-based phar \"%s\"", ZSTR_VAL(entry->filename), ZSTR_VAL(entry->phar->fname)); return ZEND_HASH_APPLY_STOP; } } @@ -1181,12 +1155,11 @@ static int phar_zip_changed_apply(zval *zv, void *arg) /* {{{ */ } /* }}} */ -static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pass *pass) /* {{{ */ +static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pass *pass) /* {{{ */ { /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */ if (!phar->is_data || phar->sig_flags) { - size_t signature_length; - char *signature, sigbuf[8]; + char sigbuf[8]; phar_entry_info entry = {0}; php_stream *newfile; zend_off_t tell; @@ -1207,12 +1180,11 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas php_stream_write(newfile, ZSTR_VAL(phar->metadata_tracker.str), ZSTR_LEN(phar->metadata_tracker.str)); } - if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, pass->error)) { - if (pass->error) { - char *save = *(pass->error); - spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar: %s", save); - efree(save); - } + char *signature_error = NULL; + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { + spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar: %s", signature_error); + efree(signature_error); php_stream_close(newfile); return FAILURE; @@ -1222,17 +1194,19 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas entry.fp_type = PHAR_MOD; entry.is_modified = 1; if (entry.fp == NULL) { + zend_string_release_ex(signature, false); spprintf(pass->error, 0, "phar error: unable to create temporary file for signature"); + php_stream_close(newfile); return FAILURE; } PHAR_SET_32(sigbuf, phar->sig_flags); - PHAR_SET_32(sigbuf + 4, signature_length); + PHAR_SET_32(sigbuf + 4, ZSTR_LEN(signature)); - if (Z_UL(8) != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) { - efree(signature); + if (Z_UL(8) != php_stream_write(entry.fp, sigbuf, 8) || ZSTR_LEN(signature) != php_stream_write(entry.fp, ZSTR_VAL(signature), ZSTR_LEN(signature))) { + zend_string_release_ex(signature, false); if (pass->error) { - spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar %s", phar->fname); + spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar %s", ZSTR_VAL(phar->fname)); } php_stream_close(newfile); @@ -1241,13 +1215,13 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas ALLOCA_FLAG(use_heap); ZSTR_ALLOCA_INIT(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1, use_heap); - efree(signature); - entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8; + entry.uncompressed_filesize = entry.compressed_filesize = ZSTR_LEN(signature) + 8; entry.phar = phar; /* throw out return value and write the signature */ phar_zip_changed_apply_int(&entry, (void *)pass); ZSTR_ALLOCA_FREE(entry.filename, use_heap); php_stream_close(newfile); + zend_string_release_ex(signature, false); if (pass->error && *(pass->error)) { /* error is set by writeheaders */ @@ -1258,7 +1232,7 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas } /* }}} */ -void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */ { static const char newstub[] = "is_persistent) { - if (error) { - spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "internal error: attempt to flush cached zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } if (phar->is_data) { @@ -1294,14 +1263,13 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def if (!phar->is_temporary_alias && phar->alias_len) { entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return; + *error = estrdup("phar error: unable to create temporary file"); + return EOF; } if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) { - if (error) { - spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname); - } - return; + php_stream_close(entry.fp); + spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } entry.uncompressed_filesize = entry.compressed_filesize = phar->alias_len; @@ -1314,20 +1282,19 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def /* register alias */ if (phar->alias_len) { - if (FAILURE == phar_get_archive(&phar, phar->fname, phar->fname_len, phar->alias, phar->alias_len, error)) { - return; + phar = phar_get_archive(ZSTR_VAL(phar->fname), ZSTR_LEN(phar->fname), phar->alias, phar->alias_len, error); + if (!phar) { + return EOF; } } /* set stub */ if (user_stub && !is_default_stub) { - char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), strlen(halt_stub)); + const char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), strlen(halt_stub)); if (pos == NULL) { - if (error) { - spprintf(error, 0, "illegal stub for zip-based phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "illegal stub for zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } size_t len = pos - ZSTR_VAL(user_stub) + strlen(halt_stub); @@ -1336,8 +1303,8 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return; + *error = estrdup("phar error: unable to create temporary file"); + return EOF; } entry.uncompressed_filesize = len + end_sequence_len; @@ -1345,11 +1312,9 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def len != php_stream_write(entry.fp, ZSTR_VAL(user_stub), len) || end_sequence_len != php_stream_write(entry.fp, end_sequence, end_sequence_len) ) { - if (error) { - spprintf(error, 0, "unable to create stub from string in new zip-based phar \"%s\"", phar->fname); - } + spprintf(error, 0, "unable to create stub from string in new zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); php_stream_close(entry.fp); - return; + return EOF; } entry.filename = ZSTR_INIT_LITERAL(".phar/stub.php", false); @@ -1359,15 +1324,13 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def /* Either this is a brand new phar (add the stub), or the default stub is required (overwrite the stub) */ entry.fp = php_stream_fopen_tmpfile(); if (entry.fp == NULL) { - spprintf(error, 0, "phar error: unable to create temporary file"); - return; + *error = estrdup("phar error: unable to create temporary file"); + return EOF; } if (sizeof(newstub)-1 != php_stream_write(entry.fp, newstub, sizeof(newstub)-1)) { php_stream_close(entry.fp); - if (error) { - spprintf(error, 0, "unable to %s stub in%szip-based phar \"%s\", failed", user_stub ? "overwrite" : "create", user_stub ? " " : " new ", phar->fname); - } - return; + spprintf(error, 0, "unable to %s stub in%szip-based phar \"%s\", failed", user_stub ? "overwrite" : "create", user_stub ? " " : " new ", ZSTR_VAL(phar->fname)); + return EOF; } entry.uncompressed_filesize = entry.compressed_filesize = sizeof(newstub) - 1; @@ -1378,10 +1341,8 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def if (NULL == zend_hash_add_mem(&phar->manifest, entry.filename, &entry, sizeof(phar_entry_info))) { php_stream_close(entry.fp); zend_string_efree(entry.filename); - if (error) { - spprintf(error, 0, "unable to create stub in zip-based phar \"%s\"", phar->fname); - } - return; + spprintf(error, 0, "unable to create stub in zip-based phar \"%s\"", ZSTR_VAL(phar->fname)); + return EOF; } } else { php_stream_close(entry.fp); @@ -1397,11 +1358,14 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def must_close_old_file = false; php_stream_rewind(oldfile); } else { - oldfile = php_stream_open_wrapper(phar->fname, "rb", 0, NULL); + oldfile = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "rb", 0, NULL); must_close_old_file = oldfile != NULL; } /* save modified files to the zip */ + char *pass_error = NULL; + struct _phar_zip_pass pass; + pass.error = &pass_error; pass.old = oldfile; pass.filefp = php_stream_fopen_tmpfile(); @@ -1410,19 +1374,18 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def if (must_close_old_file) { php_stream_close(oldfile); } - if (error) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to open temporary file", phar->fname); - } - return; + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to open temporary file", ZSTR_VAL(phar->fname)); + return EOF; } pass.centralfp = php_stream_fopen_tmpfile(); if (!pass.centralfp) { + php_stream_close(pass.filefp); goto fperror; } - pass.free_fp = pass.free_ufp = 1; + pass.free_fp = pass.free_ufp = true; memset(&eocd, 0, sizeof(eocd)); memcpy(eocd.signature, "PK\5\6", 4); @@ -1439,23 +1402,18 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def zend_hash_apply_with_argument(&phar->manifest, phar_zip_changed_apply, (void *) &pass); phar_metadata_tracker_try_ensure_has_serialized_data(&phar->metadata_tracker, phar->is_persistent); - if (temperr) { - if (error) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", phar->fname, temperr); - } - efree(temperr); -temperror: + if (pass_error + || FAILURE == phar_zip_applysignature(phar, &pass)) { + spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", ZSTR_VAL(phar->fname), pass_error); + efree(pass_error); +nopasserror: php_stream_close(pass.centralfp); nocentralerror: php_stream_close(pass.filefp); if (must_close_old_file) { php_stream_close(oldfile); } - return; - } - - if (FAILURE == phar_zip_applysignature(phar, &pass)) { - goto temperror; + return EOF; } /* save zip */ @@ -1467,12 +1425,10 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def { size_t clen; - int ret = php_stream_copy_to_stream_ex(pass.centralfp, pass.filefp, PHP_STREAM_COPY_ALL, &clen); + zend_result ret = php_stream_copy_to_stream_ex(pass.centralfp, pass.filefp, PHP_STREAM_COPY_ALL, &clen); if (SUCCESS != ret || clen != cdir_size) { - if (error) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write central-directory", phar->fname); - } - goto temperror; + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write central-directory", ZSTR_VAL(phar->fname)); + goto nopasserror; } } @@ -1484,23 +1440,17 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def PHAR_SET_16(eocd.comment_len, ZSTR_LEN(phar->metadata_tracker.str)); if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) { - if (error) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", phar->fname); - } + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", ZSTR_VAL(phar->fname)); goto nocentralerror; } if (ZSTR_LEN(phar->metadata_tracker.str) != php_stream_write(pass.filefp, ZSTR_VAL(phar->metadata_tracker.str), ZSTR_LEN(phar->metadata_tracker.str))) { - if (error) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write metadata to zip comment", phar->fname); - } + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write metadata to zip comment", ZSTR_VAL(phar->fname)); goto nocentralerror; } } else { if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) { - if (error) { - spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", phar->fname); - } + spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write end of central-directory", ZSTR_VAL(phar->fname)); goto nocentralerror; } } @@ -1523,16 +1473,14 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def /* deferred flush */ phar->fp = pass.filefp; } else { - phar->fp = php_stream_open_wrapper(phar->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); + phar->fp = php_stream_open_wrapper(ZSTR_VAL(phar->fname), "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (!phar->fp) { if (must_close_old_file) { php_stream_close(oldfile); } phar->fp = pass.filefp; - if (error) { - spprintf(error, 4096, "unable to open new phar \"%s\" for writing", phar->fname); - } - return; + spprintf(error, 4096, "unable to open new phar \"%s\" for writing", ZSTR_VAL(phar->fname)); + return EOF; } php_stream_rewind(pass.filefp); php_stream_copy_to_stream_ex(pass.filefp, phar->fp, PHP_STREAM_COPY_ALL, NULL); @@ -1543,5 +1491,6 @@ void phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_def if (must_close_old_file) { php_stream_close(oldfile); } + return 0; } /* }}} */ diff --git a/ext/posix/config.m4 b/ext/posix/config.m4 index b7a6e4277251..865546356953 100644 --- a/ext/posix/config.m4 +++ b/ext/posix/config.m4 @@ -17,6 +17,7 @@ if test "$PHP_POSIX" = "yes"; then eaccess getgrgid_r getgroups + getlogin getpgid getrlimit getsid @@ -43,7 +44,8 @@ if test "$PHP_POSIX" = "yes"; then dnl Skip pathconf and fpathconf check on musl libc due to limited implementation dnl (first argument is not validated and has different error). - AS_IF([command -v ldd >/dev/null && ldd --version 2>&1 | grep ^musl >/dev/null 2>&1], + PHP_C_STANDARD_LIBRARY + AS_VAR_IF([php_cv_c_standard_library], [musl], [], [AC_CHECK_FUNCS([pathconf fpathconf])]) diff --git a/ext/posix/php_posix.h b/ext/posix/php_posix.h index 79e6fe83ef9e..82208bb63088 100644 --- a/ext/posix/php_posix.h +++ b/ext/posix/php_posix.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kristian Koehntopp | +----------------------------------------------------------------------+ diff --git a/ext/posix/posix.c b/ext/posix/posix.c index 512776d3ced2..b44b73cc8dcf 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kristian Koehntopp | +----------------------------------------------------------------------+ @@ -45,6 +43,14 @@ # include #endif +#if (defined(__sun) && !defined(_LP64)) || defined(_AIX) +#define POSIX_PID_MIN LONG_MIN +#define POSIX_PID_MAX LONG_MAX +#else +#define POSIX_PID_MIN INT_MIN +#define POSIX_PID_MAX INT_MAX +#endif + #include "posix_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(posix) @@ -118,6 +124,12 @@ ZEND_GET_MODULE(posix) } \ RETURN_TRUE; +#define PHP_POSIX_CHECK_PID(pid, arg, lower, upper) \ + if (pid < lower || pid > upper) { \ + zend_argument_value_error(arg, "must be between " ZEND_LONG_FMT " and " ZEND_LONG_FMT, lower, upper); \ + RETURN_THROWS(); \ + } + /* {{{ Send a signal to a process (POSIX.1, 3.3.2) */ PHP_FUNCTION(posix_kill) @@ -129,6 +141,8 @@ PHP_FUNCTION(posix_kill) Z_PARAM_LONG(sig) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(pid, 1, POSIX_PID_MIN, POSIX_PID_MAX) + if (kill(pid, sig) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; @@ -291,6 +305,9 @@ PHP_FUNCTION(posix_setpgid) Z_PARAM_LONG(pgid) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(pid, 1, 0, POSIX_PID_MAX) + PHP_POSIX_CHECK_PID(pgid, 2, 0, POSIX_PID_MAX) + if (setpgid(pid, pgid) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; @@ -329,6 +346,8 @@ PHP_FUNCTION(posix_getsid) Z_PARAM_LONG(val) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(val, 1, 0, POSIX_PID_MAX) + if ((val = getsid(val)) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; @@ -678,7 +697,8 @@ static void php_posix_group_to_array(struct group *g, zval *array_group) /* {{{ for (count = 0;; count++) { /* gr_mem entries may be misaligned on macos. */ char *gr_mem; - memcpy(&gr_mem, &g->gr_mem[count], sizeof(char *)); + char *entry = (char *)g->gr_mem + (count * sizeof (char *)); + memcpy(&gr_mem, entry, sizeof(char *)); if (!gr_mem) { break; } @@ -722,6 +742,15 @@ PHP_FUNCTION(posix_access) RETURN_FALSE; } + if (mode < 0 || (mode & ~(F_OK | R_OK | W_OK | X_OK))) { + zend_argument_value_error( + 2, + "must be a bitmask of POSIX_F_OK, POSIX_R_OK, POSIX_W_OK, and POSIX_X_OK" + ); + efree(path); + RETURN_THROWS(); + } + ret = access(path, mode); efree(path); @@ -1183,6 +1212,21 @@ PHP_FUNCTION(posix_setrlimit) Z_PARAM_LONG(max) ZEND_PARSE_PARAMETERS_END(); + if (cur < -1) { + zend_argument_value_error(2, "must be greater or equal to -1"); + RETURN_THROWS(); + } + + if (max < -1) { + zend_argument_value_error(3, "must be greater or equal to -1"); + RETURN_THROWS(); + } + + if (max > -1 && cur > max) { + zend_argument_value_error(2, "must be lower or equal to " ZEND_LONG_FMT, max); + RETURN_THROWS(); + } + rl.rlim_cur = cur; rl.rlim_max = max; diff --git a/ext/posix/posix_arginfo.h b/ext/posix/posix_arginfo.h index dceac3eabc99..835ad31fa1a8 100644 --- a/ext/posix/posix_arginfo.h +++ b/ext/posix/posix_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit posix.stub.php instead. * Stub hash: 25e0aa769d72988ebca07fff96c8ed1fcb6b7d5e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_posix_kill, 0, 2, _IS_BOOL, 0) diff --git a/ext/posix/tests/posix_access_flags.phpt b/ext/posix/tests/posix_access_flags.phpt new file mode 100644 index 000000000000..0989e2a2bc66 --- /dev/null +++ b/ext/posix/tests/posix_access_flags.phpt @@ -0,0 +1,54 @@ +--TEST-- +posix_access() flag (mode) validation +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +try { + posix_access($testfile, 01000); // S_ISVTX bit (sticky) +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +try { + posix_access($testfile, 02000); // S_ISGID bit +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +if (posix_access($testfile, POSIX_R_OK | POSIX_W_OK)) { + echo "Read/write access OK\n"; +} + +if (posix_access($testfile, POSIX_F_OK)) { + echo "File exists OK\n"; +} + +?> +--CLEAN-- + +--EXPECTF-- +posix_access(): Argument #2 ($flags) must be a bitmask of POSIX_F_OK, POSIX_R_OK, POSIX_W_OK, and POSIX_X_OK +posix_access(): Argument #2 ($flags) must be a bitmask of POSIX_F_OK, POSIX_R_OK, POSIX_W_OK, and POSIX_X_OK +posix_access(): Argument #2 ($flags) must be a bitmask of POSIX_F_OK, POSIX_R_OK, POSIX_W_OK, and POSIX_X_OK +Read/write access OK +File exists OK diff --git a/ext/posix/tests/posix_fpathconf.phpt b/ext/posix/tests/posix_fpathconf.phpt index 4225852c3a03..91918d5901bb 100644 --- a/ext/posix/tests/posix_fpathconf.phpt +++ b/ext/posix/tests/posix_fpathconf.phpt @@ -25,6 +25,6 @@ fclose($fd); Warning: posix_fpathconf(): Argument #1 ($file_descriptor) must be between 0 and %d in %s on line %d bool(false) bool(true) -string(19) "Bad file descriptor" +string(%d) "Bad file %r(descriptor|number)%r" posix_fpathconf(): Argument #1 ($file_descriptor) must be of type int|resource, string given int(%d) diff --git a/ext/posix/tests/posix_getsid_error.phpt b/ext/posix/tests/posix_getsid_error.phpt index c62eca58a840..68f168554997 100644 --- a/ext/posix/tests/posix_getsid_error.phpt +++ b/ext/posix/tests/posix_getsid_error.phpt @@ -9,7 +9,11 @@ PHP Testfest Berlin 2009-05-10 posix --FILE-- getMessage(), PHP_EOL; +} ?> ---EXPECT-- -bool(false) +--EXPECTF-- +posix_getsid(): Argument #1 ($process_id) must be between 0 and %d diff --git a/ext/posix/tests/posix_isatty_value_errors.phpt b/ext/posix/tests/posix_isatty_value_errors.phpt index 599d892de0d3..3e6b715b05fa 100644 --- a/ext/posix/tests/posix_isatty_value_errors.phpt +++ b/ext/posix/tests/posix_isatty_value_errors.phpt @@ -24,10 +24,10 @@ foreach ($values as $value) { Warning: posix_isatty(): Argument #1 ($file_descriptor) must be between 0 and %d in %s on line %d bool(false) -string(19) "Bad file descriptor" +string(%d) "Bad file %r(descriptor|number)%r" bool(false) -string(19) "Bad file descriptor" +string(%d) "Bad file %r(descriptor|number)%r" Warning: posix_isatty(): Argument #1 ($file_descriptor) must be between 0 and %d in %s on line %d bool(false) -string(19) "Bad file descriptor" +string(%d) "Bad file %r(descriptor|number)%r" diff --git a/ext/posix/tests/posix_kill_pidoverflow.phpt b/ext/posix/tests/posix_kill_pidoverflow.phpt new file mode 100644 index 000000000000..0e8b8c7b7df1 --- /dev/null +++ b/ext/posix/tests/posix_kill_pidoverflow.phpt @@ -0,0 +1,25 @@ +--TEST-- +posix_kill() with large pid +--EXTENSIONS-- +posix +pcntl +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + posix_kill(PHP_INT_MIN, SIGTERM); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +posix_kill(): Argument #1 ($process_id) must be between %i and %d +posix_kill(): Argument #1 ($process_id) must be between %i and %d diff --git a/ext/posix/tests/posix_setpgid_error.phpt b/ext/posix/tests/posix_setpgid_error.phpt new file mode 100644 index 000000000000..0d00dd87c60f --- /dev/null +++ b/ext/posix/tests/posix_setpgid_error.phpt @@ -0,0 +1,34 @@ +--TEST-- +posix_setpgid() with wrong pid values +--EXTENSIONS-- +posix +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +try { + posix_setpgid(-2, 1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + posix_setpgid(1, PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + posix_setpgid(1, -2); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +posix_setpgid(): Argument #1 ($process_id) must be between 0 and %d +posix_setpgid(): Argument #1 ($process_id) must be between 0 and %d +posix_setpgid(): Argument #2 ($process_group_id) must be between 0 and %d +posix_setpgid(): Argument #2 ($process_group_id) must be between 0 and %d diff --git a/ext/posix/tests/posix_setrlimit.phpt b/ext/posix/tests/posix_setrlimit.phpt index cc8fadafc047..51638793f9d4 100644 --- a/ext/posix/tests/posix_setrlimit.phpt +++ b/ext/posix/tests/posix_setrlimit.phpt @@ -12,9 +12,25 @@ if (str_contains(PHP_OS, 'FreeBSD')) die('skip different behavior on FreeBSD'); getMessage(), PHP_EOL; +} +try { + posix_setrlimit(POSIX_RLIMIT_NOFILE, -2, -1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + posix_setrlimit(POSIX_RLIMIT_NOFILE, -1, -2); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} ?> --EXPECT-- bool(true) -bool(false) +posix_setrlimit(): Argument #2 ($soft_limit) must be lower or equal to 128 +posix_setrlimit(): Argument #2 ($soft_limit) must be greater or equal to -1 +posix_setrlimit(): Argument #3 ($hard_limit) must be greater or equal to -1 diff --git a/ext/posix/tests/posix_ttyname_value_errors.phpt b/ext/posix/tests/posix_ttyname_value_errors.phpt index 31014fd6f3c6..41cf07876d7e 100644 --- a/ext/posix/tests/posix_ttyname_value_errors.phpt +++ b/ext/posix/tests/posix_ttyname_value_errors.phpt @@ -22,8 +22,8 @@ foreach ($values as $value) { --EXPECTF-- Warning: posix_ttyname(): Argument #1 ($file_descriptor) must be between 0 and %d in %s on line %d bool(false) -string(19) "Bad file descriptor" +string(%d) "Bad file %r(descriptor|number)%r" Warning: posix_ttyname(): Argument #1 ($file_descriptor) must be between 0 and %d in %s on line %d bool(false) -string(19) "Bad file descriptor" +string(%d) "Bad file %r(descriptor|number)%r" diff --git a/ext/random/config.m4 b/ext/random/config.m4 index ff43b856acf0..484f0549e019 100644 --- a/ext/random/config.m4 +++ b/ext/random/config.m4 @@ -38,4 +38,5 @@ PHP_INSTALL_HEADERS([ext/random], m4_normalize([ php_random_csprng.h php_random_uint128.h php_random.h + random_decl.h ])) diff --git a/ext/random/config.w32 b/ext/random/config.w32 index 717055d6fc41..bb0badbd183d 100644 --- a/ext/random/config.w32 +++ b/ext/random/config.w32 @@ -1,4 +1,4 @@ EXTENSION("random", "random.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); PHP_RANDOM="yes"; ADD_SOURCES(configure_module_dirname, "csprng.c engine_mt19937.c engine_pcgoneseq128xslrr64.c engine_xoshiro256starstar.c engine_secure.c engine_user.c gammasection.c randomizer.c zend_utils.c", "random"); -PHP_INSTALL_HEADERS("ext/random", "php_random.h php_random_csprng.h php_random_uint128.h"); +PHP_INSTALL_HEADERS("ext/random", "php_random.h php_random_csprng.h php_random_uint128.h random_decl.h"); diff --git a/ext/random/csprng.c b/ext/random/csprng.c index 73832d7d0685..4c474fb86796 100644 --- a/ext/random/csprng.c +++ b/ext/random/csprng.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | Go Kudo | diff --git a/ext/random/engine_mt19937.c b/ext/random/engine_mt19937.c index 7c9d1741d81f..a84fb9585c80 100644 --- a/ext/random/engine_mt19937.c +++ b/ext/random/engine_mt19937.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -324,17 +322,16 @@ PHP_METHOD(Random_Engine_Mt19937, __serialize) array_init(return_value); /* members */ - ZVAL_ARR(&t, zend_std_get_properties(&engine->std)); - Z_TRY_ADDREF(t); + ZVAL_EMPTY_ARRAY(&t); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &t); /* state */ array_init(&t); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &t); if (!engine->engine.algo->serialize(engine->engine.state, Z_ARRVAL(t))) { zend_throw_exception(NULL, "Engine serialize failed", 0); RETURN_THROWS(); } - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &t); } /* }}} */ @@ -392,11 +389,11 @@ PHP_METHOD(Random_Engine_Mt19937, __debugInfo) if (engine->engine.algo->serialize) { array_init(&t); + zend_hash_str_add(Z_ARR_P(return_value), "__states", strlen("__states"), &t); if (!engine->engine.algo->serialize(engine->engine.state, Z_ARRVAL(t))) { zend_throw_exception(NULL, "Engine serialize failed", 0); RETURN_THROWS(); } - zend_hash_str_add(Z_ARR_P(return_value), "__states", strlen("__states"), &t); } } /* }}} */ diff --git a/ext/random/engine_pcgoneseq128xslrr64.c b/ext/random/engine_pcgoneseq128xslrr64.c index 9ff4f911920b..9472ce918fef 100644 --- a/ext/random/engine_pcgoneseq128xslrr64.c +++ b/ext/random/engine_pcgoneseq128xslrr64.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | | | diff --git a/ext/random/engine_secure.c b/ext/random/engine_secure.c index 0a03a03bdf13..1fd0748e2b81 100644 --- a/ext/random/engine_secure.c +++ b/ext/random/engine_secure.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sammy Kaye Powers | | Go Kudo | diff --git a/ext/random/engine_user.c b/ext/random/engine_user.c index 955ddebdb99a..f759613ea8cf 100644 --- a/ext/random/engine_user.c +++ b/ext/random/engine_user.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ diff --git a/ext/random/engine_xoshiro256starstar.c b/ext/random/engine_xoshiro256starstar.c index 1a054362f065..8dd0156dcb2d 100644 --- a/ext/random/engine_xoshiro256starstar.c +++ b/ext/random/engine_xoshiro256starstar.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | | | @@ -151,6 +149,10 @@ static bool unserialize(void *state, HashTable *data) } } + if (UNEXPECTED(s->state[0] == 0 && s->state[1] == 0 && s->state[2] == 0 && s->state[3] == 0)) { + return false; + } + return true; } diff --git a/ext/random/gammasection.c b/ext/random/gammasection.c index 732f8a2b0d9b..ef0352773a77 100644 --- a/ext/random/gammasection.c +++ b/ext/random/gammasection.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | | diff --git a/ext/random/php_random.h b/ext/random/php_random.h index bc55a3defcc7..6e3df1317a4f 100644 --- a/ext/random/php_random.h +++ b/ext/random/php_random.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -34,19 +32,10 @@ # include "php.h" # include "php_random_csprng.h" # include "php_random_uint128.h" +# include "random_decl.h" PHPAPI double php_combined_lcg(void); -typedef struct _php_random_fallback_seed_state php_random_fallback_seed_state; - -PHPAPI uint64_t php_random_generate_fallback_seed(void); -PHPAPI uint64_t php_random_generate_fallback_seed_ex(php_random_fallback_seed_state *state); - -static inline zend_long GENERATE_SEED(void) -{ - return (zend_long)php_random_generate_fallback_seed(); -} - # define PHP_MT_RAND_MAX ((zend_long) (0x7FFFFFFF)) /* (1<<31) - 1 */ enum php_random_mt19937_mode { @@ -61,31 +50,31 @@ PHPAPI uint32_t php_mt_rand(void); PHPAPI zend_long php_mt_rand_range(zend_long min, zend_long max); PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max); -typedef struct _php_random_status_state_mt19937 { +typedef struct php_random_status_state_mt19937 { uint32_t count; enum php_random_mt19937_mode mode; uint32_t state[624]; } php_random_status_state_mt19937; -typedef struct _php_random_status_state_pcgoneseq128xslrr64 { +typedef struct php_random_status_state_pcgoneseq128xslrr64 { php_random_uint128_t state; } php_random_status_state_pcgoneseq128xslrr64; -typedef struct _php_random_status_state_xoshiro256starstar { +typedef struct php_random_status_state_xoshiro256starstar { uint64_t state[4]; } php_random_status_state_xoshiro256starstar; -typedef struct _php_random_status_state_user { +typedef struct php_random_status_state_user { zend_object *object; zend_function *generate_method; } php_random_status_state_user; -typedef struct _php_random_result { +typedef struct php_random_result { uint64_t result; size_t size; } php_random_result; -typedef struct _php_random_algo { +typedef struct php_random_algo { const size_t state_size; php_random_result (*generate)(void *state); zend_long (*range)(void *state, zend_long min, zend_long max); @@ -93,12 +82,12 @@ typedef struct _php_random_algo { bool (*unserialize)(void *state, HashTable *data); } php_random_algo; -typedef struct _php_random_algo_with_state { +typedef struct php_random_algo_with_state { const php_random_algo *algo; void *state; } php_random_algo_with_state; -typedef struct _php_random_fallback_seed_state { +typedef struct php_random_fallback_seed_state { bool initialized; unsigned char seed[20]; } php_random_fallback_seed_state; @@ -109,12 +98,12 @@ extern PHPAPI const php_random_algo php_random_algo_xoshiro256starstar; extern PHPAPI const php_random_algo php_random_algo_secure; extern PHPAPI const php_random_algo php_random_algo_user; -typedef struct _php_random_engine { +typedef struct php_random_engine { php_random_algo_with_state engine; zend_object std; } php_random_engine; -typedef struct _php_random_randomizer { +typedef struct php_random_randomizer { php_random_algo_with_state engine; bool is_userland_algo; zend_object std; @@ -137,21 +126,29 @@ extern PHPAPI zend_class_entry *random_ce_Random_Randomizer; extern PHPAPI zend_class_entry *random_ce_Random_IntervalBoundary; static inline php_random_engine *php_random_engine_from_obj(zend_object *object) { - return (php_random_engine *)((char *)(object) - XtOffsetOf(php_random_engine, std)); + return ZEND_CONTAINER_OF(object, php_random_engine, std); } static inline php_random_randomizer *php_random_randomizer_from_obj(zend_object *object) { - return (php_random_randomizer *)((char *)(object) - XtOffsetOf(php_random_randomizer, std)); + return ZEND_CONTAINER_OF(object, php_random_randomizer, std); } # define Z_RANDOM_ENGINE_P(zval) php_random_engine_from_obj(Z_OBJ_P(zval)) # define Z_RANDOM_RANDOMIZER_P(zval) php_random_randomizer_from_obj(Z_OBJ_P(zval)); +PHPAPI uint64_t php_random_generate_fallback_seed(void); +PHPAPI uint64_t php_random_generate_fallback_seed_ex(php_random_fallback_seed_state *state); + +static inline zend_long GENERATE_SEED(void) +{ + return (zend_long)php_random_generate_fallback_seed(); +} + PHPAPI void *php_random_status_alloc(const php_random_algo *algo, const bool persistent); PHPAPI void *php_random_status_copy(const php_random_algo *algo, void *old_status, void *new_status); PHPAPI void php_random_status_free(void *status, const bool persistent); -PHPAPI php_random_engine *php_random_engine_common_init(zend_class_entry *ce, zend_object_handlers *handlers, const php_random_algo *algo); +PHPAPI php_random_engine *php_random_engine_common_init(zend_class_entry *ce, const php_random_algo *algo); PHPAPI void php_random_engine_common_free_object(zend_object *object); PHPAPI zend_object *php_random_engine_common_clone_object(zend_object *object); PHPAPI uint32_t php_random_range32(php_random_algo_with_state engine, uint32_t umax); diff --git a/ext/random/php_random_csprng.h b/ext/random/php_random_csprng.h index 7fb0d7357f61..6028bbf62522 100644 --- a/ext/random/php_random_csprng.h +++ b/ext/random/php_random_csprng.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | Go Kudo | diff --git a/ext/random/php_random_uint128.h b/ext/random/php_random_uint128.h index 8c484ce5ba9f..25d2677da436 100644 --- a/ext/random/php_random_uint128.h +++ b/ext/random/php_random_uint128.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tim Düsterhus | | Go Kudo | @@ -23,7 +21,7 @@ # include # if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128) -typedef struct _php_random_uint128_t { +typedef struct php_random_uint128_t { uint64_t hi; uint64_t lo; } php_random_uint128_t; diff --git a/ext/random/php_random_zend_utils.h b/ext/random/php_random_zend_utils.h index db37805904cb..56718e5c214b 100644 --- a/ext/random/php_random_zend_utils.h +++ b/ext/random/php_random_zend_utils.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | | Tim Düsterhus | @@ -22,7 +20,7 @@ # include "php_random.h" # include "zend.h" -typedef struct _php_random_bytes_insecure_state_for_zend { +typedef struct php_random_bytes_insecure_state_for_zend { bool initialized; php_random_status_state_xoshiro256starstar xoshiro256starstar_state; } php_random_bytes_insecure_state_for_zend; diff --git a/ext/random/random.c b/ext/random/random.c index 46a6c4fd44f2..bd6f9f8a9018 100644 --- a/ext/random/random.c +++ b/ext/random/random.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sammy Kaye Powers | | Go Kudo | @@ -197,22 +195,22 @@ PHPAPI uint64_t php_random_range64(php_random_algo_with_state engine, uint64_t u static zend_object *php_random_engine_mt19937_new(zend_class_entry *ce) { - return &php_random_engine_common_init(ce, &random_engine_mt19937_object_handlers, &php_random_algo_mt19937)->std; + return &php_random_engine_common_init(ce, &php_random_algo_mt19937)->std; } static zend_object *php_random_engine_pcgoneseq128xslrr64_new(zend_class_entry *ce) { - return &php_random_engine_common_init(ce, &random_engine_pcgoneseq128xslrr64_object_handlers, &php_random_algo_pcgoneseq128xslrr64)->std; + return &php_random_engine_common_init(ce, &php_random_algo_pcgoneseq128xslrr64)->std; } static zend_object *php_random_engine_xoshiro256starstar_new(zend_class_entry *ce) { - return &php_random_engine_common_init(ce, &random_engine_xoshiro256starstar_object_handlers, &php_random_algo_xoshiro256starstar)->std; + return &php_random_engine_common_init(ce, &php_random_algo_xoshiro256starstar)->std; } static zend_object *php_random_engine_secure_new(zend_class_entry *ce) { - return &php_random_engine_common_init(ce, &random_engine_secure_object_handlers, &php_random_algo_secure)->std; + return &php_random_engine_common_init(ce, &php_random_algo_secure)->std; } static zend_object *php_random_randomizer_new(zend_class_entry *ce) @@ -250,7 +248,7 @@ PHPAPI void php_random_status_free(void *status, const bool persistent) pefree(status, persistent); } -PHPAPI php_random_engine *php_random_engine_common_init(zend_class_entry *ce, zend_object_handlers *handlers, const php_random_algo *algo) +PHPAPI php_random_engine *php_random_engine_common_init(zend_class_entry *ce, const php_random_algo *algo) { php_random_engine *engine = zend_object_alloc(sizeof(php_random_engine), ce); @@ -261,7 +259,6 @@ PHPAPI php_random_engine *php_random_engine_common_init(zend_class_entry *ce, ze .algo = algo, .state = php_random_status_alloc(algo, false) }; - engine->std.handlers = handlers; return engine; } @@ -276,7 +273,7 @@ PHPAPI void php_random_engine_common_free_object(zend_object *object) PHPAPI zend_object *php_random_engine_common_clone_object(zend_object *object) { - php_random_engine *old_engine = php_random_engine_from_obj(object); + const php_random_engine *old_engine = php_random_engine_from_obj(object); php_random_engine *new_engine = php_random_engine_from_obj(old_engine->std.ce->create_object(old_engine->std.ce)); new_engine->engine.algo = old_engine->engine.algo; @@ -746,32 +743,36 @@ PHP_MINIT_FUNCTION(random) /* Random\Engine\Mt19937 */ random_ce_Random_Engine_Mt19937 = register_class_Random_Engine_Mt19937(random_ce_Random_Engine); random_ce_Random_Engine_Mt19937->create_object = php_random_engine_mt19937_new; + random_ce_Random_Engine_Mt19937->default_object_handlers = &random_engine_mt19937_object_handlers; memcpy(&random_engine_mt19937_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_mt19937_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_mt19937_object_handlers.offset = offsetof(php_random_engine, std); random_engine_mt19937_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_mt19937_object_handlers.clone_obj = php_random_engine_common_clone_object; /* Random\Engine\PcgOnseq128XslRr64 */ random_ce_Random_Engine_PcgOneseq128XslRr64 = register_class_Random_Engine_PcgOneseq128XslRr64(random_ce_Random_Engine); random_ce_Random_Engine_PcgOneseq128XslRr64->create_object = php_random_engine_pcgoneseq128xslrr64_new; + random_ce_Random_Engine_PcgOneseq128XslRr64->default_object_handlers = &random_engine_pcgoneseq128xslrr64_object_handlers; memcpy(&random_engine_pcgoneseq128xslrr64_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_pcgoneseq128xslrr64_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_pcgoneseq128xslrr64_object_handlers.offset = offsetof(php_random_engine, std); random_engine_pcgoneseq128xslrr64_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_pcgoneseq128xslrr64_object_handlers.clone_obj = php_random_engine_common_clone_object; /* Random\Engine\Xoshiro256StarStar */ random_ce_Random_Engine_Xoshiro256StarStar = register_class_Random_Engine_Xoshiro256StarStar(random_ce_Random_Engine); random_ce_Random_Engine_Xoshiro256StarStar->create_object = php_random_engine_xoshiro256starstar_new; + random_ce_Random_Engine_Xoshiro256StarStar->default_object_handlers = &random_engine_xoshiro256starstar_object_handlers; memcpy(&random_engine_xoshiro256starstar_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_xoshiro256starstar_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_xoshiro256starstar_object_handlers.offset = offsetof(php_random_engine, std); random_engine_xoshiro256starstar_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_xoshiro256starstar_object_handlers.clone_obj = php_random_engine_common_clone_object; /* Random\Engine\Secure */ random_ce_Random_Engine_Secure = register_class_Random_Engine_Secure(random_ce_Random_CryptoSafeEngine); random_ce_Random_Engine_Secure->create_object = php_random_engine_secure_new; + random_ce_Random_Engine_Secure->default_object_handlers = &random_engine_secure_object_handlers; memcpy(&random_engine_secure_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_engine_secure_object_handlers.offset = XtOffsetOf(php_random_engine, std); + random_engine_secure_object_handlers.offset = offsetof(php_random_engine, std); random_engine_secure_object_handlers.free_obj = php_random_engine_common_free_object; random_engine_secure_object_handlers.clone_obj = NULL; @@ -780,7 +781,7 @@ PHP_MINIT_FUNCTION(random) random_ce_Random_Randomizer->create_object = php_random_randomizer_new; random_ce_Random_Randomizer->default_object_handlers = &random_randomizer_object_handlers; memcpy(&random_randomizer_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - random_randomizer_object_handlers.offset = XtOffsetOf(php_random_randomizer, std); + random_randomizer_object_handlers.offset = offsetof(php_random_randomizer, std); random_randomizer_object_handlers.free_obj = randomizer_free_obj; random_randomizer_object_handlers.clone_obj = NULL; diff --git a/ext/random/random.stub.php b/ext/random/random.stub.php index b59221bf9180..57a80bf645b1 100644 --- a/ext/random/random.stub.php +++ b/ext/random/random.stub.php @@ -1,6 +1,9 @@ args[0].value, &attribute_Deprecated_func_lcg_value_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_lcg_value_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func_lcg_value_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_lcg_value_0_arg1; zend_string *attribute_Deprecated_func_lcg_value_0_arg1_str = zend_string_init("use \\Random\\Randomizer::getFloat() instead", strlen("use \\Random\\Randomizer::getFloat() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_lcg_value_0_arg1, attribute_Deprecated_func_lcg_value_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_lcg_value_0->args[1].value, &attribute_Deprecated_func_lcg_value_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_lcg_value_0->args[1].value, attribute_Deprecated_func_lcg_value_0_arg1_str); attribute_Deprecated_func_lcg_value_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_MT_RAND_PHP_0 = zend_add_global_constant_attribute(const_MT_RAND_PHP, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_MT_RAND_PHP_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); + attribute_Deprecated_const_MT_RAND_PHP_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_MT_RAND_PHP_0_arg1_str = zend_string_init("as it uses a biased non-standard variant of Mt19937", strlen("as it uses a biased non-standard variant of Mt19937"), 1); + ZVAL_STR(&attribute_Deprecated_const_MT_RAND_PHP_0->args[1].value, attribute_Deprecated_const_MT_RAND_PHP_0_arg1_str); + attribute_Deprecated_const_MT_RAND_PHP_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_Random_Engine_Mt19937(zend_class_entry *class_entry_Random_Engine) @@ -316,10 +319,10 @@ static zend_class_entry *register_class_Random_Randomizer(void) zval property_engine_default_value; ZVAL_UNDEF(&property_engine_default_value); - zend_string *property_engine_name = zend_string_init("engine", sizeof("engine") - 1, 1); + zend_string *property_engine_name = zend_string_init("engine", sizeof("engine") - 1, true); zend_string *property_engine_class_Random_Engine = zend_string_init("Random\\Engine", sizeof("Random\\Engine")-1, 1); zend_declare_typed_property(class_entry, property_engine_name, &property_engine_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_engine_class_Random_Engine, 0, 0)); - zend_string_release(property_engine_name); + zend_string_release_ex(property_engine_name, true); return class_entry; } diff --git a/ext/random/random_decl.h b/ext/random/random_decl.h new file mode 100644 index 000000000000..67b27f198247 --- /dev/null +++ b/ext/random/random_decl.h @@ -0,0 +1,14 @@ +/* This is a generated file, edit random.stub.php instead. + * Stub hash: 245fb5b66e540814c8595a06182886aee3e32f2c */ + +#ifndef ZEND_RANDOM_DECL_245fb5b66e540814c8595a06182886aee3e32f2c_H +#define ZEND_RANDOM_DECL_245fb5b66e540814c8595a06182886aee3e32f2c_H + +typedef enum zend_enum_Random_IntervalBoundary { + ZEND_ENUM_Random_IntervalBoundary_ClosedOpen = 1, + ZEND_ENUM_Random_IntervalBoundary_ClosedClosed = 2, + ZEND_ENUM_Random_IntervalBoundary_OpenClosed = 3, + ZEND_ENUM_Random_IntervalBoundary_OpenOpen = 4, +} zend_enum_Random_IntervalBoundary; + +#endif /* ZEND_RANDOM_DECL_245fb5b66e540814c8595a06182886aee3e32f2c_H */ diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c index 4f63388e8f56..0738380ca253 100644 --- a/ext/random/randomizer.c +++ b/ext/random/randomizer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Go Kudo | +----------------------------------------------------------------------+ @@ -43,16 +41,9 @@ static inline void randomizer_common_init(php_random_randomizer *randomizer, zen .state = state, }; - zend_string *mname; - zend_function *generate_method; - - mname = ZSTR_INIT_LITERAL("generate", 0); - generate_method = zend_hash_find_ptr(&engine_object->ce->function_table, mname); - zend_string_release(mname); - /* Create compatible state */ state->object = engine_object; - state->generate_method = generate_method; + state->generate_method = zend_hash_str_find_ptr(&engine_object->ce->function_table, "generate", strlen("generate")); /* Mark self-allocated for memory management */ randomizer->is_userland_algo = true; @@ -138,14 +129,13 @@ PHP_METHOD(Random_Randomizer, getFloat) { php_random_randomizer *randomizer = Z_RANDOM_RANDOMIZER_P(ZEND_THIS); double min, max; - zend_object *bounds = NULL; - int bounds_type = 'C' + sizeof("ClosedOpen") - 1; + zend_enum_Random_IntervalBoundary bounds_type = ZEND_ENUM_Random_IntervalBoundary_ClosedOpen; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_DOUBLE(min) Z_PARAM_DOUBLE(max) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OF_CLASS(bounds, random_ce_Random_IntervalBoundary); + Z_PARAM_ENUM(bounds_type, random_ce_Random_IntervalBoundary); ZEND_PARSE_PARAMETERS_END(); if (!zend_finite(min)) { @@ -158,36 +148,29 @@ PHP_METHOD(Random_Randomizer, getFloat) RETURN_THROWS(); } - if (bounds) { - zval *case_name = zend_enum_fetch_case_name(bounds); - zend_string *bounds_name = Z_STR_P(case_name); - - bounds_type = ZSTR_VAL(bounds_name)[0] + ZSTR_LEN(bounds_name); - } - switch (bounds_type) { - case 'C' + sizeof("ClosedOpen") - 1: + case ZEND_ENUM_Random_IntervalBoundary_ClosedOpen: if (UNEXPECTED(max <= min)) { zend_argument_value_error(2, "must be greater than argument #1 ($min)"); RETURN_THROWS(); } RETURN_DOUBLE(php_random_gammasection_closed_open(randomizer->engine, min, max)); - case 'C' + sizeof("ClosedClosed") - 1: + case ZEND_ENUM_Random_IntervalBoundary_ClosedClosed: if (UNEXPECTED(max < min)) { zend_argument_value_error(2, "must be greater than or equal to argument #1 ($min)"); RETURN_THROWS(); } RETURN_DOUBLE(php_random_gammasection_closed_closed(randomizer->engine, min, max)); - case 'O' + sizeof("OpenClosed") - 1: + case ZEND_ENUM_Random_IntervalBoundary_OpenClosed: if (UNEXPECTED(max <= min)) { zend_argument_value_error(2, "must be greater than argument #1 ($min)"); RETURN_THROWS(); } RETURN_DOUBLE(php_random_gammasection_open_closed(randomizer->engine, min, max)); - case 'O' + sizeof("OpenOpen") - 1: + case ZEND_ENUM_Random_IntervalBoundary_OpenOpen: if (UNEXPECTED(max <= min)) { zend_argument_value_error(2, "must be greater than argument #1 ($min)"); RETURN_THROWS(); @@ -196,13 +179,11 @@ PHP_METHOD(Random_Randomizer, getFloat) RETVAL_DOUBLE(php_random_gammasection_open_open(randomizer->engine, min, max)); if (UNEXPECTED(isnan(Z_DVAL_P(return_value)))) { - zend_value_error("The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max)."); + zend_value_error("The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max)"); RETURN_THROWS(); } return; - default: - ZEND_UNREACHABLE(); } } /* }}} */ @@ -516,8 +497,7 @@ PHP_METHOD(Random_Randomizer, __serialize) ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); - ZVAL_ARR(&t, zend_std_get_properties(&randomizer->std)); - Z_TRY_ADDREF(t); + ZVAL_ARR(&t, zend_array_dup(zend_std_get_properties(&randomizer->std))); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &t); } /* }}} */ diff --git a/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt b/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt index 703460a890f0..ee3e155484dd 100644 --- a/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt +++ b/ext/random/tests/01_functions/array_rand_mt_rand_php.phpt @@ -24,7 +24,7 @@ var_dump( ); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d string(11) "found key 0" diff --git a/ext/random/tests/01_functions/bug75514.phpt b/ext/random/tests/01_functions/bug75514.phpt index 583ac9a209ef..8f9006496698 100644 --- a/ext/random/tests/01_functions/bug75514.phpt +++ b/ext/random/tests/01_functions/bug75514.phpt @@ -6,7 +6,7 @@ mt_srand(0, MT_RAND_PHP); var_dump(mt_rand(0,999999999), mt_rand(0,999)); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d int(448865905) diff --git a/ext/random/tests/01_functions/mt_rand_value.phpt b/ext/random/tests/01_functions/mt_rand_value.phpt index ede620648e16..bf5fdfc2a4e8 100644 --- a/ext/random/tests/01_functions/mt_rand_value.phpt +++ b/ext/random/tests/01_functions/mt_rand_value.phpt @@ -38,7 +38,7 @@ echo $x.PHP_EOL; ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d 1614640687 diff --git a/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt b/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt new file mode 100644 index 000000000000..6ebcd03e8570 --- /dev/null +++ b/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-21731: Xoshiro256StarStar::__unserialize() must reject the all-zero state +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Invalid serialization data for Random\Engine\Xoshiro256StarStar object diff --git a/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt b/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt index 4abb1276f366..50aa7b3efb0d 100644 --- a/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt +++ b/ext/random/tests/03_randomizer/compatibility_mt_rand.phpt @@ -46,11 +46,11 @@ die('success'); --EXPECTF-- MT_RAND_PHP -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d MT_RAND_MT19937 diff --git a/ext/random/tests/03_randomizer/gh_19765_unserialize.phpt b/ext/random/tests/03_randomizer/gh_19765_unserialize.phpt new file mode 100644 index 000000000000..24abfca293fc --- /dev/null +++ b/ext/random/tests/03_randomizer/gh_19765_unserialize.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-19765: object_properties_load() bypasses readonly property checks +--FILE-- +__unserialize([['engine' => new PcgOneseq128XslRr64()]]); +} catch (Exception $error) { + echo $error->getMessage() . "\n"; +} +var_dump($r->engine::class); + +?> +--EXPECT-- +Invalid serialization data for Random\Randomizer object +string(21) "Random\Engine\Mt19937" diff --git a/ext/random/tests/03_randomizer/gh_9186_unserialize.phpt b/ext/random/tests/03_randomizer/gh_9186_unserialize.phpt index fe1acb2f74be..edadb7380bd1 100644 --- a/ext/random/tests/03_randomizer/gh_9186_unserialize.phpt +++ b/ext/random/tests/03_randomizer/gh_9186_unserialize.phpt @@ -1,5 +1,5 @@ --TEST-- -Fix GH-9186 @strict-properties can be bypassed using unserialization +GH-9186: @strict-properties can be bypassed using unserialization --FILE-- __serialize()); + +?> +--EXPECT-- +array(1) { + [0]=> + array(1) { + ["engine"]=> + object(Random\Engine\Secure)#2 (0) { + } + } +} diff --git a/ext/random/tests/03_randomizer/methods/getBytes.phpt b/ext/random/tests/03_randomizer/methods/getBytes.phpt index 70aca6e22f8b..2a163040ac77 100644 --- a/ext/random/tests/03_randomizer/methods/getBytes.phpt +++ b/ext/random/tests/03_randomizer/methods/getBytes.phpt @@ -39,7 +39,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt b/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt index 06d24cc82bd2..8189d061d970 100644 --- a/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt +++ b/ext/random/tests/03_randomizer/methods/getBytesFromString.phpt @@ -43,7 +43,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/getBytesFromString_fast_path.phpt b/ext/random/tests/03_randomizer/methods/getBytesFromString_fast_path.phpt index 84c8ec611db8..7d7b98f1b27a 100644 --- a/ext/random/tests/03_randomizer/methods/getBytesFromString_fast_path.phpt +++ b/ext/random/tests/03_randomizer/methods/getBytesFromString_fast_path.phpt @@ -41,7 +41,7 @@ for ($i = 1; $i <= strlen($allBytes); $i *= 2) { } // We also expect that each possible value appears at least once, if - // not is is very likely that some bits were erroneously masked away. + // not it is very likely that some bits were erroneously masked away. var_dump(count($count)); echo PHP_EOL; @@ -67,7 +67,7 @@ for ($i = 1; ($i + 1) <= strlen($allBytes); $i *= 2) { } // We expect that each possible value appears at least once, if - // not is is very likely that some bits were erroneously masked away. + // not it is very likely that some bits were erroneously masked away. var_dump(count($count)); echo PHP_EOL; @@ -90,7 +90,7 @@ for ($j = 0; $j < strlen($result); $j++) { } // We also expect that each possible value appears at least once, if -// not is is very likely that some bits were erroneously masked away. +// not it is very likely that some bits were erroneously masked away. var_dump(count($count)); ?> diff --git a/ext/random/tests/03_randomizer/methods/getFloat.phpt b/ext/random/tests/03_randomizer/methods/getFloat.phpt index 8655777f89c3..c07fedcc210e 100644 --- a/ext/random/tests/03_randomizer/methods/getFloat.phpt +++ b/ext/random/tests/03_randomizer/methods/getFloat.phpt @@ -42,7 +42,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/getFloat_error.phpt b/ext/random/tests/03_randomizer/methods/getFloat_error.phpt index 286435e1752f..42e933cbefb2 100644 --- a/ext/random/tests/03_randomizer/methods/getFloat_error.phpt +++ b/ext/random/tests/03_randomizer/methods/getFloat_error.phpt @@ -127,4 +127,4 @@ Random\Randomizer::getFloat(): Argument #2 ($max) must be finite Random\Randomizer::getFloat(): Argument #2 ($max) must be greater than argument #1 ($min) Random\Randomizer::getFloat(): Argument #2 ($max) must be greater than argument #1 ($min) Random\Randomizer::getFloat(): Argument #2 ($max) must be greater than argument #1 ($min) -The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max). +The given interval is empty, there are no floats between argument #1 ($min) and argument #2 ($max) diff --git a/ext/random/tests/03_randomizer/methods/getInt.phpt b/ext/random/tests/03_randomizer/methods/getInt.phpt index ba936dcf3bf0..5f1656c615a7 100644 --- a/ext/random/tests/03_randomizer/methods/getInt.phpt +++ b/ext/random/tests/03_randomizer/methods/getInt.phpt @@ -46,7 +46,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/nextFloat.phpt b/ext/random/tests/03_randomizer/methods/nextFloat.phpt index b51524213750..62243faf434a 100644 --- a/ext/random/tests/03_randomizer/methods/nextFloat.phpt +++ b/ext/random/tests/03_randomizer/methods/nextFloat.phpt @@ -41,7 +41,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/nextInt.phpt b/ext/random/tests/03_randomizer/methods/nextInt.phpt index 008e5acb259e..6739ae9f1cf5 100644 --- a/ext/random/tests/03_randomizer/methods/nextInt.phpt +++ b/ext/random/tests/03_randomizer/methods/nextInt.phpt @@ -41,7 +41,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt b/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt index d5b159f2af13..8c799909c874 100644 --- a/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt +++ b/ext/random/tests/03_randomizer/methods/pickArrayKeys.phpt @@ -76,7 +76,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/shuffleArray.phpt b/ext/random/tests/03_randomizer/methods/shuffleArray.phpt index af4ce88b3821..302e683edbf2 100644 --- a/ext/random/tests/03_randomizer/methods/shuffleArray.phpt +++ b/ext/random/tests/03_randomizer/methods/shuffleArray.phpt @@ -45,7 +45,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt b/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt index 404b670e2863..cacf3688bb31 100644 --- a/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt +++ b/ext/random/tests/03_randomizer/methods/shuffleBytes.phpt @@ -52,7 +52,7 @@ die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/tests/03_randomizer/serialize.phpt b/ext/random/tests/03_randomizer/serialize.phpt index 1f56228d3322..4ac8bfe6e682 100644 --- a/ext/random/tests/03_randomizer/serialize.phpt +++ b/ext/random/tests/03_randomizer/serialize.phpt @@ -43,7 +43,7 @@ foreach ($engines as $engine) { die('success'); ?> --EXPECTF-- -Deprecated: Constant MT_RAND_PHP is deprecated in %s on line %d +Deprecated: Constant MT_RAND_PHP is deprecated since 8.3, as it uses a biased non-standard variant of Mt19937 in %s on line %d Deprecated: The MT_RAND_PHP variant of Mt19937 is deprecated in %s on line %d Random\Engine\Mt19937 diff --git a/ext/random/zend_utils.c b/ext/random/zend_utils.c index 64ba2c87ef70..19067f343afb 100644 --- a/ext/random/zend_utils.c +++ b/ext/random/zend_utils.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Arnaud Le Blanc | | Tim Düsterhus | diff --git a/ext/readline/config.w32 b/ext/readline/config.w32 index 8f3a2db61f23..2ff9cc8a2bbc 100644 --- a/ext/readline/config.w32 +++ b/ext/readline/config.w32 @@ -4,7 +4,7 @@ ARG_WITH("readline", "Readline support", "yes"); if (PHP_READLINE != "no") { if (CHECK_LIB("edit_a.lib;edit.lib", "readline", PHP_READLINE) && - CHECK_HEADER_ADD_INCLUDE("editline/readline.h", "CFLAGS_READLINE")) { + CHECK_HEADER("editline/readline.h", "CFLAGS_READLINE")) { EXTENSION("readline", "readline.c readline_cli.c"); ADD_FLAG("CFLAGS_READLINE", "/D HAVE_LIBEDIT"); ADD_FLAG("CFLAGS_READLINE", "/D HAVE_RL_COMPLETION_MATCHES"); diff --git a/ext/readline/php_readline.h b/ext/readline/php_readline.h index f67238db663a..c1a337713069 100644 --- a/ext/readline/php_readline.h +++ b/ext/readline/php_readline.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/readline/readline.c b/ext/readline/readline.c index d29292185690..cbc0ebdd8713 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -47,6 +45,11 @@ static zval _prepped_callback; static zval _readline_completion; static zval _readline_array; +ZEND_TLS char *php_readline_custom_readline_name = NULL; +#if defined(PHP_WIN32) || defined(HAVE_LIBEDIT) +ZEND_TLS char *php_readline_custom_line_buffer = NULL; +#endif + PHP_MINIT_FUNCTION(readline); PHP_MSHUTDOWN_FUNCTION(readline); PHP_RSHUTDOWN_FUNCTION(readline); @@ -146,7 +149,6 @@ PHP_FUNCTION(readline_info) zend_string *what = NULL; zval *value = NULL; size_t oldval; - char *oldstr; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!z!", &what, &value) == FAILURE) { RETURN_THROWS(); @@ -181,35 +183,29 @@ PHP_FUNCTION(readline_info) add_assoc_long(return_value,"attempted_completion_over",rl_attempted_completion_over); } else { if (zend_string_equals_literal_ci(what,"line_buffer")) { - oldstr = strdup(rl_line_buffer ? rl_line_buffer : ""); + RETVAL_STRING(SAFE_STRING(rl_line_buffer)); if (value) { if (!try_convert_to_string(value)) { RETURN_THROWS(); } + /* XXX: These stores would need to be atomic ideally or use a memory barrier */ #if !defined(PHP_WIN32) && !defined(HAVE_LIBEDIT) - if (!rl_line_buffer) { - rl_line_buffer = malloc(Z_STRLEN_P(value) + 1); - } else if (strlen(oldstr) < Z_STRLEN_P(value)) { - rl_extend_line_buffer(Z_STRLEN_P(value) + 1); - free(oldstr); - oldstr = strdup(rl_line_buffer ? rl_line_buffer : ""); + rl_extend_line_buffer(Z_STRLEN_P(value) + 1); + if (EXPECTED(rl_line_buffer)) { + memcpy(rl_line_buffer, Z_STRVAL_P(value), Z_STRLEN_P(value) + 1); } - memcpy(rl_line_buffer, Z_STRVAL_P(value), Z_STRLEN_P(value) + 1); #else - char *tmp = strdup(Z_STRVAL_P(value)); - if (tmp) { - if (rl_line_buffer) { - free(rl_line_buffer); - } - rl_line_buffer = tmp; + char *copy = strdup(Z_STRVAL_P(value)); + rl_line_buffer = copy; + if (php_readline_custom_line_buffer) { + free(php_readline_custom_line_buffer); } + php_readline_custom_line_buffer = copy; #endif #if !defined(PHP_WIN32) rl_end = Z_STRLEN_P(value); #endif } - RETVAL_STRING(SAFE_STRING(oldstr)); - free(oldstr); } else if (zend_string_equals_literal_ci(what, "point")) { RETVAL_LONG(rl_point); #ifndef PHP_WIN32 @@ -268,15 +264,19 @@ PHP_FUNCTION(readline_info) RETVAL_STRING((char *)SAFE_STRING(rl_library_version)); #endif } else if (zend_string_equals_literal_ci(what, "readline_name")) { - oldstr = (char*)rl_readline_name; + RETVAL_STRING(SAFE_STRING(rl_readline_name)); if (value) { - /* XXX if (rl_readline_name) free(rl_readline_name); */ if (!try_convert_to_string(value)) { RETURN_THROWS(); } - rl_readline_name = strdup(Z_STRVAL_P(value)); + char *copy = strdup(Z_STRVAL_P(value)); + /* XXX: This store would need to be atomic ideally or use a memory barrier */ + rl_readline_name = copy; + if (php_readline_custom_readline_name) { + free(php_readline_custom_readline_name); + } + php_readline_custom_readline_name = copy; } - RETVAL_STRING(SAFE_STRING(oldstr)); } else if (zend_string_equals_literal_ci(what, "attempted_completion_over")) { oldval = rl_attempted_completion_over; if (value) { @@ -307,9 +307,7 @@ PHP_FUNCTION(readline_add_history) /* {{{ Clears the history */ PHP_FUNCTION(readline_clear_history) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); #ifdef HAVE_LIBEDIT /* clear_history is the only function where rl_initialize @@ -329,9 +327,7 @@ PHP_FUNCTION(readline_list_history) { HIST_ENTRY **history; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -391,13 +387,9 @@ PHP_FUNCTION(readline_read_history) RETURN_FALSE; } - /* XXX from & to NYI */ - if (read_history(arg)) { - /* If filename is NULL, then read from `~/.history' */ - RETURN_FALSE; - } else { - RETURN_TRUE; - } + /* XXX from & to NYI + If filename is NULL, then read from `~/.history' */ + RETURN_BOOL(!read_history(arg)); } /* }}} */ @@ -415,11 +407,7 @@ PHP_FUNCTION(readline_write_history) RETURN_FALSE; } - if (write_history(arg)) { - RETURN_FALSE; - } else { - RETURN_TRUE; - } + RETURN_BOOL(!write_history(arg)); } /* }}} */ @@ -501,10 +489,8 @@ PHP_FUNCTION(readline_completion_function) /* NOTE: The rl_attempted_completion_function variable (and others) are part of the readline library, not php */ rl_attempted_completion_function = php_readline_completion_cb; - if (rl_attempted_completion_function == NULL) { - RETURN_FALSE; - } - RETURN_TRUE; + + RETURN_BOOL(rl_attempted_completion_function != NULL); } /* }}} */ @@ -554,9 +540,7 @@ PHP_FUNCTION(readline_callback_handler_install) /* {{{ Informs the readline callback interface that a character is ready for input */ PHP_FUNCTION(readline_callback_read_char) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_TYPE(_prepped_callback) != IS_UNDEF) { rl_callback_read_char(); @@ -567,9 +551,7 @@ PHP_FUNCTION(readline_callback_read_char) /* {{{ Removes a previously installed callback handler and restores terminal settings */ PHP_FUNCTION(readline_callback_handler_remove) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_TYPE(_prepped_callback) != IS_UNDEF) { rl_callback_handler_remove(); @@ -584,9 +566,7 @@ PHP_FUNCTION(readline_callback_handler_remove) /* {{{ Ask readline to redraw the display */ PHP_FUNCTION(readline_redisplay) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); #ifdef HAVE_LIBEDIT /* seems libedit doesn't take care of rl_initialize in rl_redisplay @@ -603,9 +583,7 @@ PHP_FUNCTION(readline_redisplay) /* {{{ Inform readline that the cursor has moved to a new line */ PHP_FUNCTION(readline_on_new_line) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); rl_on_new_line(); } diff --git a/ext/readline/readline_arginfo.h b/ext/readline/readline_arginfo.h index c6fa7ee4590f..689d5f762eef 100644 --- a/ext/readline/readline_arginfo.h +++ b/ext/readline/readline_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit readline.stub.php instead. * Stub hash: 7a314f75d9a89a9ea4d525515bb6bacdf7be6746 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_readline, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c index 312129991c70..9f42b33596c0 100644 --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | | Johannes Schlueter | @@ -529,7 +527,8 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ } else if (text[0] == '#' && text[1] != '[') { retval = cli_completion_generator_ini(text, textlen, &cli_completion_state); } else { - char *lc_text, *class_name_end; + char *lc_text; + const char *class_name_end; zend_string *class_name = NULL; zend_class_entry *ce = NULL; diff --git a/ext/readline/readline_cli.h b/ext/readline/readline_cli.h index 6db09ce991ce..31c21d8eedc1 100644 --- a/ext/readline/readline_cli.h +++ b/ext/readline/readline_cli.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | | Johannes Schlueter | diff --git a/ext/readline/tests/gh18139.phpt b/ext/readline/tests/gh18139.phpt new file mode 100644 index 000000000000..a2de1f9720c7 --- /dev/null +++ b/ext/readline/tests/gh18139.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-18139 (Memory leak when overriding some settings via readline_info()) +--EXTENSIONS-- +readline +--FILE-- + +--EXPECTF-- +string(%d) "%S" +string(5) "first" +string(%d) "%S" +string(5) "third" diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 8ef0269481cf..9c4d82affb43 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Timm Friebe | | George Schlossnagle | @@ -47,6 +45,7 @@ #include "zend_closures.h" #include "zend_generators.h" #include "zend_extensions.h" +#include "zend_inheritance.h" #include "zend_builtin_functions.h" #include "zend_smart_str.h" #include "zend_enum.h" @@ -104,12 +103,11 @@ PHPAPI zend_class_entry *reflection_enum_unit_case_ptr; PHPAPI zend_class_entry *reflection_enum_backed_case_ptr; PHPAPI zend_class_entry *reflection_fiber_ptr; PHPAPI zend_class_entry *reflection_constant_ptr; +PHPAPI zend_class_entry *reflection_generic_type_parameter_ptr; +PHPAPI zend_class_entry *reflection_type_parameter_reference_ptr; +PHPAPI zend_class_entry *reflection_generic_variance_ptr; PHPAPI zend_class_entry *reflection_property_hook_type_ptr; -/* Exception throwing macro */ -#define _DO_THROW(msg) \ - zend_throw_exception(reflection_exception_ptr, msg, 0); - #define GET_REFLECTION_OBJECT() do { \ intern = Z_REFLECTION_P(ZEND_THIS); \ if (intern->ptr == NULL) { \ @@ -126,6 +124,19 @@ PHPAPI zend_class_entry *reflection_property_hook_type_ptr; target = intern->ptr; \ } while (0) +/* When reflecting a bare generic class, swap in the defaults monomorph (same + * contract as `new ClassName()`); throws and returns from the caller if any + * type parameter has no default. Reflecting an existing monomorph leaves + * `ce` unchanged. */ +#define REFLECTION_RESOLVE_GENERIC_DEFAULTS(ce) do { \ + if ((ce)->generic_parameters) { \ + (ce) = zend_get_defaults_monomorph(ce); \ + if (UNEXPECTED((ce) == NULL)) { \ + RETURN_THROWS(); \ + } \ + } \ +} while (0) + /* {{{ Object structure */ /* Struct for properties */ @@ -146,10 +157,132 @@ typedef struct _parameter_reference { /* Struct for type hints */ typedef struct _type_reference { zend_type type; + bool owns_type; /* Whether to use backwards compatible null representation */ bool legacy_behavior; + /* Optional pre-erasure form for generic-aware reflection. */ + zend_type pre_erasure; + bool owns_pre_erasure; + /* Declaring entity for type-parameter resolution. */ + zend_class_entry *declaring_class; + zend_function *declaring_fn; } type_reference; +static zend_type reflection_type_copy(zend_type type); + +static zend_type_list *reflection_type_list_copy(const zend_type_list *old_list) +{ + size_t size = ZEND_TYPE_LIST_SIZE(old_list->num_types); + zend_type_list *new_list = emalloc(size); + new_list->num_types = old_list->num_types; + + for (uint32_t i = 0; i < old_list->num_types; i++) { + new_list->types[i] = reflection_type_copy(old_list->types[i]); + } + + return new_list; +} + +static zend_type_named_with_args *reflection_named_with_args_copy( + const zend_type_named_with_args *old_named) +{ + zend_type_named_with_args *new_named = emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(old_named->count)); + new_named->name = old_named->name ? zend_string_copy(old_named->name) : NULL; + new_named->name_attr = old_named->name_attr; + new_named->count = old_named->count; + + for (uint32_t i = 0; i < old_named->count; i++) { + new_named->args[i] = reflection_type_copy(old_named->args[i]); + } + + return new_named; +} + +static zend_type_parameter_ref *reflection_type_parameter_ref_copy( + const zend_type_parameter_ref *old_ref) +{ + zend_type_parameter_ref *new_ref = emalloc(sizeof(zend_type_parameter_ref)); + *new_ref = *old_ref; + if (new_ref->name) { + zend_string_addref(new_ref->name); + } + return new_ref; +} + +static zend_type reflection_type_copy(zend_type type) +{ + zend_type result = type; + + if (ZEND_TYPE_HAS_LIST(type)) { + ZEND_TYPE_SET_LIST(result, reflection_type_list_copy(ZEND_TYPE_LIST(type))); + ZEND_TYPE_FULL_MASK(result) &= ~_ZEND_TYPE_ARENA_BIT; + } else if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) { + ZEND_TYPE_SET_PTR(result, reflection_named_with_args_copy(ZEND_TYPE_NAMED_WITH_ARGS(type))); + } else if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) { + ZEND_TYPE_SET_PTR(result, reflection_type_parameter_ref_copy(ZEND_TYPE_TYPE_PARAMETER(type))); + } else if (ZEND_TYPE_HAS_NAME(type)) { + zend_string_addref(ZEND_TYPE_NAME(type)); + } + + return result; +} + +static zend_type reflection_type_substitute_class_params( + zend_type type, const zend_type *args, uint32_t arity) +{ + if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) { + const zend_type_parameter_ref *ref = ZEND_TYPE_TYPE_PARAMETER(type); + if (ref->origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE && ref->index < arity) { + zend_type result = reflection_type_copy(args[ref->index]); + if (ZEND_TYPE_FULL_MASK(type) & _ZEND_TYPE_NULLABLE_BIT) { + ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NULLABLE_BIT; + } + return result; + } + } + + if (ZEND_TYPE_HAS_LIST(type)) { + zend_type result = type; + const zend_type_list *old_list = ZEND_TYPE_LIST(type); + size_t size = ZEND_TYPE_LIST_SIZE(old_list->num_types); + zend_type_list *new_list = emalloc(size); + new_list->num_types = old_list->num_types; + for (uint32_t i = 0; i < old_list->num_types; i++) { + new_list->types[i] = reflection_type_substitute_class_params( + old_list->types[i], args, arity); + } + ZEND_TYPE_SET_LIST(result, new_list); + ZEND_TYPE_FULL_MASK(result) &= ~_ZEND_TYPE_ARENA_BIT; + return result; + } + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) { + zend_type result = type; + const zend_type_named_with_args *old_named = ZEND_TYPE_NAMED_WITH_ARGS(type); + zend_type_named_with_args *new_named = emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(old_named->count)); + new_named->name = old_named->name ? zend_string_copy(old_named->name) : NULL; + new_named->name_attr = old_named->name_attr; + new_named->count = old_named->count; + for (uint32_t i = 0; i < old_named->count; i++) { + new_named->args[i] = reflection_type_substitute_class_params( + old_named->args[i], args, arity); + } + ZEND_TYPE_SET_PTR(result, new_named); + return result; + } + + return reflection_type_copy(type); +} + +/* Struct for generic type-parameter reflection. Points back at a parameter slot + * inside the declaring entity's zend_generic_parameter_list. Lifetime is bound + * to the declaring class_entry / op_array. */ +typedef struct _generic_parameter_reference { + zend_generic_parameter *param; /* points into a zend_generic_parameter_list */ + uint32_t index; /* position in the list */ + zval declaring; /* zval-wrapped ReflectionClass / ReflectionFunctionAbstract */ +} generic_parameter_reference; + /* Struct for attributes */ typedef struct _attribute_reference { HashTable *attributes; @@ -168,7 +301,8 @@ typedef enum { REF_TYPE_TYPE, REF_TYPE_PROPERTY, REF_TYPE_CLASS_CONSTANT, - REF_TYPE_ATTRIBUTE + REF_TYPE_ATTRIBUTE, + REF_TYPE_GENERIC_PARAMETER } reflection_type_t; /* Struct for reflection objects */ @@ -181,7 +315,7 @@ typedef struct { } reflection_object; static inline reflection_object *reflection_object_from_obj(zend_object *obj) { - return (reflection_object*)((char*)(obj) - XtOffsetOf(reflection_object, zo)); + return ZEND_CONTAINER_OF(obj, reflection_object, zo); } #define Z_REFLECTION_P(zv) reflection_object_from_obj(Z_OBJ_P((zv))) @@ -195,7 +329,7 @@ static zend_always_inline uint32_t prop_get_flags(const property_reference *ref) static inline bool is_closure_invoke(const zend_class_entry *ce, const zend_string *lcname) { return ce == zend_ce_closure - && zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME); + && zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE)); } static zend_function *_copy_function(zend_function *fptr) /* {{{ */ @@ -250,9 +384,14 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ case REF_TYPE_TYPE: { type_reference *type_ref = intern->ptr; - if (ZEND_TYPE_HAS_NAME(type_ref->type)) { + if (type_ref->owns_type) { + zend_type_release(type_ref->type, /* persistent */ false); + } else if (ZEND_TYPE_HAS_NAME(type_ref->type)) { zend_string_release(ZEND_TYPE_NAME(type_ref->type)); } + if (type_ref->owns_pre_erasure) { + zend_type_release(type_ref->pre_erasure, /* persistent */ false); + } efree(type_ref); break; } @@ -270,6 +409,12 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ efree(intern->ptr); break; } + case REF_TYPE_GENERIC_PARAMETER: { + generic_parameter_reference *ref = intern->ptr; + zval_ptr_dtor(&ref->declaring); + efree(ref); + break; + } case REF_TYPE_GENERATOR: case REF_TYPE_FIBER: case REF_TYPE_CLASS_CONSTANT: @@ -616,7 +761,7 @@ static void _const_string(smart_str *str, const char *name, zval *value, const c if (Z_TYPE_P(value) == IS_ARRAY) { smart_str_append(str, ZSTR_KNOWN(ZEND_STR_ARRAY_CAPITALIZED)); } else if (Z_TYPE_P(value) == IS_STRING) { - smart_str_appends(str, Z_STRVAL_P(value)); + smart_str_append(str, Z_STR_P(value)); } else { zend_string *tmp_value_str; zend_string *value_str = zval_get_tmp_string(value, &tmp_value_str); @@ -716,7 +861,7 @@ static zval *get_default_from_recv(zend_op_array *op_array, uint32_t offset) { return RT_CONSTANT(recv, recv->op2); } -static int format_default_value(smart_str *str, zval *value) { +static void format_default_value(smart_str *str, zval *value) { if (smart_str_append_zval(str, value, SIZE_MAX) == SUCCESS) { /* Nothing to do. */ } else if (Z_TYPE_P(value) == IS_ARRAY) { @@ -761,12 +906,6 @@ static int format_default_value(smart_str *str, zval *value) { smart_str_append(str, ast_str); zend_string_release(ast_str); } - return SUCCESS; -} - -static inline bool has_internal_arg_info(const zend_function *fptr) { - return fptr->type == ZEND_INTERNAL_FUNCTION - && !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO); } /* {{{ _parameter_string */ @@ -790,17 +929,15 @@ static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_ if (ZEND_ARG_IS_VARIADIC(arg_info)) { smart_str_appends(str, "..."); } - smart_str_append_printf(str, "$%s", has_internal_arg_info(fptr) - ? ((zend_internal_arg_info*)arg_info)->name : ZSTR_VAL(arg_info->name)); + smart_str_append_printf(str, "$%s", ZSTR_VAL(arg_info->name)); if (!required && !ZEND_ARG_IS_VARIADIC(arg_info)) { if (fptr->type == ZEND_INTERNAL_FUNCTION) { smart_str_appends(str, " = "); /* TODO: We don't have a way to fetch the default value for an internal function * with userland arg info. */ - if (has_internal_arg_info(fptr) - && ((zend_internal_arg_info*)arg_info)->default_value) { - smart_str_appends(str, ((zend_internal_arg_info*)arg_info)->default_value); + if (arg_info->default_value) { + smart_str_append(str, arg_info->default_value); } else { smart_str_appends(str, ""); } @@ -808,9 +945,7 @@ static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_ zval *default_value = get_default_from_recv((zend_op_array*)fptr, offset); if (default_value) { smart_str_appends(str, " = "); - if (format_default_value(str, default_value) == FAILURE) { - return; - } + format_default_value(str, default_value); } } } @@ -889,7 +1024,7 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->internal_function.doc_comment)); } - smart_str_appendl(str, indent, strlen(indent)); + smart_str_appends(str, indent); smart_str_appends(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ ")); smart_str_appends(str, (fptr->type == ZEND_USER_FUNCTION) ? "common.fn_flags & ZEND_ACC_DEPRECATED) { @@ -1040,6 +1175,9 @@ static void _property_string(smart_str *str, zend_property_info *prop, const cha if (prop->flags & ZEND_ACC_READONLY) { smart_str_appends(str, "readonly "); } + if (prop->flags & ZEND_ACC_VIRTUAL) { + smart_str_appends(str, "virtual "); + } if (ZEND_TYPE_IS_SET(prop->type)) { zend_string *type_str = zend_type_to_string(prop->type); smart_str_append(str, type_str); @@ -1055,9 +1193,27 @@ static void _property_string(smart_str *str, zend_property_info *prop, const cha zval *default_value = property_get_default(prop); if (default_value && !Z_ISUNDEF_P(default_value)) { smart_str_appends(str, " = "); - if (format_default_value(str, default_value) == FAILURE) { - return; + format_default_value(str, default_value); + } + if (prop->hooks != NULL) { + smart_str_appends(str, " {"); + const zend_function *get_hooked = prop->hooks[ZEND_PROPERTY_HOOK_GET]; + if (get_hooked != NULL) { + if (get_hooked->common.fn_flags & ZEND_ACC_FINAL) { + smart_str_appends(str, " final get;"); + } else { + smart_str_appends(str, " get;"); + } + } + const zend_function *set_hooked = prop->hooks[ZEND_PROPERTY_HOOK_SET]; + if (set_hooked != NULL) { + if (set_hooked->common.fn_flags & ZEND_ACC_FINAL) { + smart_str_appends(str, " final set;"); + } else { + smart_str_appends(str, " set;"); + } } + smart_str_appends(str, " }"); } } @@ -1255,7 +1411,7 @@ static void reflection_attribute_factory(zval *object, HashTable *attributes, ze } /* }}} */ -static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *scope, +static zend_result read_attributes(zval *ret, HashTable *attributes, zend_class_entry *scope, uint32_t offset, uint32_t target, zend_string *name, zend_class_entry *base, zend_string *filename) /* {{{ */ { ZEND_ASSERT(attributes != NULL); @@ -1414,13 +1570,7 @@ static void reflection_extension_factory_ex(zval *object, zend_module_entry *mod static void reflection_extension_factory(zval *object, const char *name_str) { size_t name_len = strlen(name_str); - zend_string *lcname; - struct _zend_module_entry *module; - - lcname = zend_string_alloc(name_len, 0); - zend_str_tolower_copy(ZSTR_VAL(lcname), name_str, name_len); - module = zend_hash_find_ptr(&module_registry, lcname); - zend_string_efree(lcname); + struct _zend_module_entry *module = zend_hash_str_find_ptr_lc(&module_registry, name_str, name_len); if (!module) { return; } @@ -1451,11 +1601,7 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje } prop_name = reflection_prop_name(object); - if (has_internal_arg_info(fptr)) { - ZVAL_STRING(prop_name, ((zend_internal_arg_info*)arg_info)->name); - } else { - ZVAL_STR_COPY(prop_name, arg_info->name); - } + ZVAL_STR_COPY(prop_name, arg_info->name); } /* }}} */ @@ -1500,11 +1646,69 @@ static reflection_type_kind get_type_kind(zend_type type) { return NAMED_TYPE; } -/* {{{ reflection_type_factory */ -static void reflection_type_factory(zend_type type, zval *object, bool legacy_behavior) +static zend_class_entry *reflection_resolve_declaring_class(zend_class_entry *ce) +{ + return (ce && ce->generic_parameters) ? ce : NULL; +} + +static void reflection_resolve_fn_context( + zend_function *fptr, + zend_class_entry **declaring_class_out, + zend_function **declaring_fn_out) +{ + *declaring_class_out = NULL; + *declaring_fn_out = NULL; + if (fptr->type != ZEND_USER_FUNCTION) { + return; + } + + const zend_op_array *op = &fptr->op_array; + if (op->generic_parameters) { + *declaring_fn_out = fptr; + } + + *declaring_class_out = reflection_resolve_declaring_class(op->scope); +} + +/* {{{ reflection_type_factory_ex */ +static void reflection_type_factory_ex_impl( + zend_type type, zval *object, bool legacy_behavior, + zend_type pre_erasure, + zend_class_entry *declaring_class, + zend_function *declaring_fn, + bool copy_type, + bool copy_pre_erasure) { reflection_object *intern; type_reference *reference; + + if (ZEND_TYPE_HAS_NAMED_WITH_ARGS(type)) { + ZEND_ASSERT(!ZEND_TYPE_HAS_NAMED_WITH_ARGS(pre_erasure)); + pre_erasure = type; + copy_pre_erasure = copy_type; + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(type); + type = (zend_type) ZEND_TYPE_INIT_CLASS(named->name, 0, 0); + copy_type = false; + } + + if (ZEND_TYPE_HAS_TYPE_PARAMETER(type)) { + object_init_ex(object, reflection_type_parameter_reference_ptr); + intern = Z_REFLECTION_P(object); + reference = (type_reference*) emalloc(sizeof(type_reference)); + reference->type = copy_type ? reflection_type_copy(type) : type; + reference->owns_type = copy_type; + reference->legacy_behavior = false; + reference->pre_erasure = (zend_type) ZEND_TYPE_INIT_NONE(0); + reference->owns_pre_erasure = false; + reference->declaring_class = declaring_class; + reference->declaring_fn = declaring_fn; + intern->ptr = reference; + intern->ref_type = REF_TYPE_TYPE; + zend_type_parameter_ref *tp = ZEND_TYPE_TYPE_PARAMETER(type); + ZVAL_STR_COPY(reflection_prop_name(object), tp->name); + return; + } + reflection_type_kind type_kind = get_type_kind(type); bool is_mixed = ZEND_TYPE_PURE_MASK(type) == MAY_BE_ANY; bool is_only_null = (ZEND_TYPE_PURE_MASK(type) == MAY_BE_NULL && !ZEND_TYPE_IS_COMPLEX(type)); @@ -1519,13 +1723,19 @@ static void reflection_type_factory(zend_type type, zval *object, bool legacy_be case NAMED_TYPE: object_init_ex(object, reflection_named_type_ptr); break; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } intern = Z_REFLECTION_P(object); reference = (type_reference*) emalloc(sizeof(type_reference)); - reference->type = type; + reference->type = copy_type ? reflection_type_copy(type) : type; + reference->owns_type = copy_type; reference->legacy_behavior = legacy_behavior && type_kind == NAMED_TYPE && !is_mixed && !is_only_null; + reference->pre_erasure = copy_pre_erasure && ZEND_TYPE_IS_SET(pre_erasure) + ? reflection_type_copy(pre_erasure) : pre_erasure; + reference->owns_pre_erasure = copy_pre_erasure && ZEND_TYPE_IS_SET(pre_erasure); + reference->declaring_class = declaring_class; + reference->declaring_fn = declaring_fn; intern->ptr = reference; intern->ref_type = REF_TYPE_TYPE; @@ -1534,12 +1744,37 @@ static void reflection_type_factory(zend_type type, zval *object, bool legacy_be * do this for the top-level type, as resolutions inside type lists will be * fully visible to us (we'd have to do a fully copy of the type if we wanted * to prevent that). */ - if (ZEND_TYPE_HAS_NAME(type)) { + if (!copy_type && ZEND_TYPE_HAS_NAME(type)) { zend_string_addref(ZEND_TYPE_NAME(type)); } } + +static void reflection_type_factory_ex( + zend_type type, zval *object, bool legacy_behavior, + zend_type pre_erasure, + zend_class_entry *declaring_class, + zend_function *declaring_fn) +{ + reflection_type_factory_ex_impl(type, object, legacy_behavior, pre_erasure, + declaring_class, declaring_fn, false, false); +} + +static void reflection_type_factory_ex_copy( + zend_type type, zval *object, bool legacy_behavior, + zend_type pre_erasure, + zend_class_entry *declaring_class, + zend_function *declaring_fn) +{ + reflection_type_factory_ex_impl(type, object, legacy_behavior, pre_erasure, + declaring_class, declaring_fn, true, ZEND_TYPE_IS_SET(pre_erasure)); +} /* }}} */ +static void reflection_type_factory(zend_type type, zval *object, bool legacy_behavior) +{ + reflection_type_factory_ex(type, object, legacy_behavior, (zend_type) ZEND_TYPE_INIT_NONE(0), NULL, NULL); +} + /* {{{ reflection_function_factory */ static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object) { @@ -1635,14 +1870,13 @@ static void reflection_enum_case_factory(zend_class_entry *ce, zend_string *name ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name); } -static int get_parameter_default(zval *result, parameter_reference *param) { +static zend_result get_parameter_default(zval *result, parameter_reference *param) { if (param->fptr->type == ZEND_INTERNAL_FUNCTION) { if (param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO) { /* We don't have a way to determine the default value for this case right now. */ return FAILURE; } - return zend_get_default_from_internal_arg_info( - result, (zend_internal_arg_info *) param->arg_info); + return zend_get_default_from_internal_arg_info(result, param->arg_info); } else { zval *default_value = get_default_from_recv((zend_op_array *) param->fptr, param->offset); if (!default_value) { @@ -1658,7 +1892,7 @@ static int get_parameter_default(zval *result, parameter_reference *param) { ZEND_METHOD(ReflectionClass, __clone) { /* __clone() is private but this is reachable with reflection */ - _DO_THROW("Cannot clone object using __clone()"); + zend_throw_exception(reflection_exception_ptr, "Cannot clone object using __clone()", 0); } /* }}} */ @@ -1695,6 +1929,15 @@ ZEND_METHOD(Reflection, getModifierNames) add_next_index_stringl(return_value, "protected", sizeof("protected")-1); break; } + /* These are also mutually exclusive */ + switch (modifiers & ZEND_ACC_PPP_SET_MASK) { + case ZEND_ACC_PROTECTED_SET: + add_next_index_stringl(return_value, "protected(set)", sizeof("protected(set)")-1); + break; + case ZEND_ACC_PRIVATE_SET: + add_next_index_stringl(return_value, "private(set)", sizeof("private(set)")-1); + break; + } if (modifiers & ZEND_ACC_STATIC) { add_next_index_str(return_value, ZSTR_KNOWN(ZEND_STR_STATIC)); @@ -2114,16 +2357,10 @@ ZEND_METHOD(ReflectionFunction, invoke) zend_call_known_fcc(&fcc, &retval, num_args, params, named_params); - if (Z_TYPE(retval) == IS_UNDEF && !EG(exception)) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name)); - RETURN_THROWS(); - } - if (Z_ISREF(retval)) { zend_unwrap_reference(&retval); } - ZVAL_COPY_VALUE(return_value, &retval); + RETURN_COPY_VALUE(&retval); } /* }}} */ @@ -2153,16 +2390,10 @@ ZEND_METHOD(ReflectionFunction, invokeArgs) zend_call_known_fcc(&fcc, &retval, /* num_params */ 0, /* params */ NULL, params); - if (Z_TYPE(retval) == IS_UNDEF && !EG(exception)) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name)); - RETURN_THROWS(); - } - if (Z_ISREF(retval)) { zend_unwrap_reference(&retval); } - ZVAL_COPY_VALUE(return_value, &retval); + RETURN_COPY_VALUE(&retval); } /* }}} */ @@ -2328,7 +2559,7 @@ ZEND_METHOD(ReflectionGenerator, __construct) #define REFLECTION_CHECK_VALID_GENERATOR(ex) \ if (!ex) { \ - _DO_THROW("Cannot fetch information from a closed Generator"); \ + zend_throw_exception(reflection_exception_ptr, "Cannot fetch information from a closed Generator", 0); \ RETURN_THROWS(); \ } @@ -2508,7 +2739,7 @@ ZEND_METHOD(ReflectionParameter, __construct) if (((classref = zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL) || ((method = zend_hash_index_find(Z_ARRVAL_P(reference), 1)) == NULL)) { - _DO_THROW("Expected array($object, $method) or array($classname, $method)"); + zend_throw_exception(reflection_exception_ptr, "Expected array($object, $method) or array($classname, $method)", 0); RETURN_THROWS(); } @@ -2581,27 +2812,16 @@ ZEND_METHOD(ReflectionParameter, __construct) uint32_t i; position = -1; - if (has_internal_arg_info(fptr)) { - for (i = 0; i < num_args; i++) { - if (arg_info[i].name) { - if (strcmp(((zend_internal_arg_info*)arg_info)[i].name, ZSTR_VAL(arg_name)) == 0) { - position = i; - break; - } - } - } - } else { - for (i = 0; i < num_args; i++) { - if (arg_info[i].name) { - if (zend_string_equals(arg_name, arg_info[i].name)) { - position = i; - break; - } + for (i = 0; i < num_args; i++) { + if (arg_info[i].name) { + if (zend_string_equals(arg_name, arg_info[i].name)) { + position = i; + break; } } } if (position == -1) { - _DO_THROW("The parameter specified by its name could not be found"); + zend_throw_exception(reflection_exception_ptr, "The parameter specified by its name could not be found", 0); goto failure; } } else { @@ -2610,7 +2830,7 @@ ZEND_METHOD(ReflectionParameter, __construct) goto failure; } if (position >= num_args) { - _DO_THROW("The parameter specified by its offset could not be found"); + zend_throw_exception(reflection_exception_ptr, "The parameter specified by its offset could not be found", 0); goto failure; } } @@ -2637,11 +2857,7 @@ ZEND_METHOD(ReflectionParameter, __construct) prop_name = reflection_prop_name(object); zval_ptr_dtor(prop_name); - if (has_internal_arg_info(fptr)) { - ZVAL_STRING(prop_name, ((zend_internal_arg_info*)arg_info)[position].name); - } else { - ZVAL_STR_COPY(prop_name, arg_info[position].name); - } + ZVAL_STR_COPY(prop_name, arg_info[position].name); return; failure: @@ -2671,6 +2887,22 @@ ZEND_METHOD(ReflectionParameter, __toString) /* }}} */ +/* {{{ Returns the doc comment for this parameter */ +ZEND_METHOD(ReflectionParameter, getDocComment) +{ + reflection_object *intern; + parameter_reference *param; + + ZEND_PARSE_PARAMETERS_NONE(); + + GET_REFLECTION_OBJECT_PTR(param); + if (param->arg_info->doc_comment) { + RETURN_STR_COPY(param->arg_info->doc_comment); + } + RETURN_FALSE; +} +/* }}} */ + /* {{{ Returns this parameter's name */ ZEND_METHOD(ReflectionParameter, getName) { @@ -2680,11 +2912,7 @@ ZEND_METHOD(ReflectionParameter, getName) ZEND_PARSE_PARAMETERS_NONE(); GET_REFLECTION_OBJECT_PTR(param); - if (has_internal_arg_info(param->fptr)) { - RETURN_STRING(((zend_internal_arg_info *) param->arg_info)->name); - } else { - RETURN_STR_COPY(param->arg_info->name); - } + RETURN_STR_COPY(param->arg_info->name); } /* }}} */ @@ -2805,7 +3033,23 @@ ZEND_METHOD(ReflectionParameter, getType) if (!ZEND_TYPE_IS_SET(param->arg_info->type)) { RETURN_NULL(); } - reflection_type_factory(param->arg_info->type, return_value, 1); + + zend_type pre_erasure = (zend_type) ZEND_TYPE_INIT_NONE(0); + zend_class_entry *declaring_class; + zend_function *declaring_fn; + reflection_resolve_fn_context(param->fptr, &declaring_class, &declaring_fn); + if (param->fptr->type == ZEND_USER_FUNCTION) { + zend_op_array *op = ¶m->fptr->op_array; + if (op->generic_types && op->generic_types->parameters) { + zend_type *boxed = zend_hash_index_find_ptr(op->generic_types->parameters, param->offset); + if (boxed) { + pre_erasure = *boxed; + } + } + } + + reflection_type_factory_ex(param->arg_info->type, return_value, true, + pre_erasure, declaring_class, declaring_fn); } /* }}} */ @@ -2844,7 +3088,7 @@ ZEND_METHOD(ReflectionParameter, isCallable) } /* }}} */ -/* {{{ Returns whether NULL is allowed as this parameters's value */ +/* {{{ Returns whether NULL is allowed as this parameter's value */ ZEND_METHOD(ReflectionParameter, allowsNull) { reflection_object *intern; @@ -2938,8 +3182,7 @@ ZEND_METHOD(ReflectionParameter, isDefaultValueAvailable) GET_REFLECTION_OBJECT_PTR(param); if (param->fptr->type == ZEND_INTERNAL_FUNCTION) { - RETURN_BOOL(!(param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO) - && ((zend_internal_arg_info*) (param->arg_info))->default_value); + RETURN_BOOL(param->arg_info->default_value); } else { zval *default_value = get_default_from_recv((zend_op_array *)param->fptr, param->offset); RETURN_BOOL(default_value != NULL); @@ -3150,7 +3393,7 @@ static void append_type(zval *return_value, zend_type type) { ZEND_TYPE_FULL_MASK(type) &= ~_ZEND_TYPE_ITERABLE_BIT; } - reflection_type_factory(type, &reflection_type, 0); + reflection_type_factory(type, &reflection_type, false); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &reflection_type); } @@ -3329,7 +3572,9 @@ static void instantiate_reflection_method(INTERNAL_FUNCTION_PARAMETERS, bool is_ && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 && (mptr = zend_get_closure_invoke_method(orig_obj)) != NULL) { - /* do nothing, mptr already set */ + /* Store the original closure object so we can validate it in invoke/invokeArgs. + * Each closure has a unique __invoke signature, so we must reject different closures. */ + ZVAL_OBJ_COPY(&intern->obj, orig_obj); } else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, method_name_len)) == NULL) { efree(lcname); zend_throw_exception_ex(reflection_exception_ptr, 0, @@ -3391,7 +3636,7 @@ ZEND_METHOD(ReflectionMethod, getClosure) } if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope)) { - _DO_THROW("Given object is not an instance of the class this method was declared in"); + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this method was declared in", 0); RETURN_THROWS(); } @@ -3461,24 +3706,48 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic) if (!variadic) { efree(params); } - _DO_THROW("Given object is not an instance of the class this method was declared in"); + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this method was declared in", 0); RETURN_THROWS(); } + + /* For Closure::__invoke(), closures from different source locations have + * different signatures, so we must reject those. */ + if (obj_ce == zend_ce_closure && !Z_ISUNDEF(intern->obj) + && Z_OBJ_P(object) != Z_OBJ(intern->obj)) { + const zend_function *orig_func = zend_get_closure_method_def(Z_OBJ(intern->obj)); + const zend_function *given_func = zend_get_closure_method_def(Z_OBJ_P(object)); + + bool same_closure = false; + /* Check if they are either both fake closures or they both are not. */ + if ((orig_func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) == (given_func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { + if (orig_func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + /* For fake closures, scope and name must match. */ + same_closure = orig_func->common.scope == given_func->common.scope + && orig_func->common.function_name == given_func->common.function_name; + } else { + /* Otherwise the opcode structure must be identical. */ + ZEND_ASSERT(orig_func->type == ZEND_USER_FUNCTION); + same_closure = orig_func->op_array.opcodes == given_func->op_array.opcodes; + } + } + + if (!same_closure) { + if (!variadic) { + efree(params); + } + zend_throw_exception(reflection_exception_ptr, "Given Closure is not the same as the reflected Closure", 0); + RETURN_THROWS(); + } + } } /* Copy the zend_function when calling via handler (e.g. Closure::__invoke()) */ callback = _copy_function(mptr); zend_call_known_function(callback, (object ? Z_OBJ_P(object) : NULL), intern->ce, &retval, argc, params, named_params); - if (Z_TYPE(retval) == IS_UNDEF && !EG(exception)) { - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Invocation of method %s::%s() failed", ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name)); - RETURN_THROWS(); - } - if (Z_ISREF(retval)) { zend_unwrap_reference(&retval); } - ZVAL_COPY_VALUE(return_value, &retval); + RETURN_COPY_VALUE(&retval); } /* }}} */ @@ -3652,7 +3921,19 @@ ZEND_METHOD(ReflectionFunctionAbstract, getReturnType) RETURN_NULL(); } - reflection_type_factory(fptr->common.arg_info[-1].type, return_value, 1); + zend_type pre_erasure = (zend_type) ZEND_TYPE_INIT_NONE(0); + zend_class_entry *declaring_class; + zend_function *declaring_fn; + reflection_resolve_fn_context(fptr, &declaring_class, &declaring_fn); + if (fptr->type == ZEND_USER_FUNCTION) { + zend_op_array *op = &fptr->op_array; + if (op->generic_types && op->generic_types->return_type) { + pre_erasure = *op->generic_types->return_type; + } + } + + reflection_type_factory_ex(fptr->common.arg_info[-1].type, return_value, true, + pre_erasure, declaring_class, declaring_fn); } /* }}} */ @@ -3684,7 +3965,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getTentativeReturnType) RETURN_NULL(); } - reflection_type_factory(fptr->common.arg_info[-1].type, return_value, 1); + reflection_type_factory(fptr->common.arg_info[-1].type, return_value, true); } /* }}} */ @@ -3887,7 +4168,7 @@ ZEND_METHOD(ReflectionClassConstant, getType) RETURN_NULL(); } - reflection_type_factory(ref->type, return_value, 1); + reflection_type_factory(ref->type, return_value, true); } /* Returns whether class constant has a type */ @@ -4190,7 +4471,7 @@ ZEND_METHOD(ReflectionClass, getStaticProperties) ZEND_METHOD(ReflectionClass, getStaticPropertyValue) { reflection_object *intern; - zend_class_entry *ce, *old_scope; + zend_class_entry *ce; zend_string *name; zval *prop, *def_value = NULL; @@ -4204,7 +4485,7 @@ ZEND_METHOD(ReflectionClass, getStaticPropertyValue) RETURN_THROWS(); } - old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; prop = zend_std_get_static_property(ce, name, BP_VAR_IS); EG(fake_scope) = old_scope; @@ -4231,7 +4512,7 @@ ZEND_METHOD(ReflectionClass, getStaticPropertyValue) ZEND_METHOD(ReflectionClass, setStaticPropertyValue) { reflection_object *intern; - zend_class_entry *ce, *old_scope; + zend_class_entry *ce; zend_property_info *prop_info; zend_string *name; zval *variable_ptr, *value; @@ -4245,7 +4526,7 @@ ZEND_METHOD(ReflectionClass, setStaticPropertyValue) if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { RETURN_THROWS(); } - old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; variable_ptr = zend_std_get_static_property_with_info(ce, name, BP_VAR_W, &prop_info); EG(fake_scope) = old_scope; @@ -4287,8 +4568,8 @@ ZEND_METHOD(ReflectionClass, getDefaultProperties) if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { RETURN_THROWS(); } - add_class_vars(ce, 1, return_value); - add_class_vars(ce, 0, return_value); + add_class_vars(ce, true, return_value); + add_class_vars(ce, false, return_value); } /* }}} */ @@ -4505,16 +4786,16 @@ ZEND_METHOD(ReflectionClass, getMethod) static bool _addmethod(zend_function *mptr, zend_class_entry *ce, HashTable *ht, zend_long filter) { if ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) && mptr->common.scope != ce) { - return 0; + return false; } if (mptr->common.fn_flags & filter) { zval method; reflection_method_factory(ce, mptr, NULL, &method); zend_hash_next_index_insert_new(ht, &method); - return 1; + return true; } - return 0; + return false; } /* }}} */ @@ -4525,7 +4806,7 @@ ZEND_METHOD(ReflectionClass, getMethods) zend_class_entry *ce; zend_function *mptr; zend_long filter; - bool filter_is_null = 1; + bool filter_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &filter, &filter_is_null) == FAILURE) { RETURN_THROWS(); @@ -4703,7 +4984,7 @@ ZEND_METHOD(ReflectionClass, getProperties) zend_string *key; zend_property_info *prop_info; zend_long filter; - bool filter_is_null = 1; + bool filter_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &filter, &filter_is_null) == FAILURE) { RETURN_THROWS(); @@ -4759,7 +5040,7 @@ ZEND_METHOD(ReflectionClass, getConstants) zend_class_constant *constant; zval val; zend_long filter; - bool filter_is_null = 1; + bool filter_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &filter, &filter_is_null) == FAILURE) { RETURN_THROWS(); @@ -4793,7 +5074,7 @@ ZEND_METHOD(ReflectionClass, getReflectionConstants) zend_string *name; zend_class_constant *constant; zend_long filter; - bool filter_is_null = 1; + bool filter_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &filter, &filter_is_null) == FAILURE) { RETURN_THROWS(); @@ -4821,7 +5102,7 @@ ZEND_METHOD(ReflectionClass, getConstant) { reflection_object *intern; zend_class_entry *ce; - HashTable *constants_table; + const HashTable *constants_table; zend_class_constant *c; zend_string *name, *key; @@ -4837,6 +5118,11 @@ ZEND_METHOD(ReflectionClass, getConstant) } } ZEND_HASH_FOREACH_END(); if ((c = zend_hash_find_ptr(constants_table, name)) == NULL) { + zend_error( + E_DEPRECATED, + "ReflectionClass::getConstant() for a non-existent constant is deprecated, " + "use ReflectionClass::hasConstant() to check if the constant exists" + ); RETURN_FALSE; } ZVAL_COPY_OR_DUP(return_value, &c->value); @@ -4998,16 +5284,18 @@ ZEND_METHOD(ReflectionClass, isInstance) ZEND_METHOD(ReflectionClass, newInstance) { reflection_object *intern; - zend_class_entry *ce, *old_scope; + zend_class_entry *ce; zend_function *constructor; GET_REFLECTION_OBJECT_PTR(ce); + REFLECTION_RESOLVE_GENERIC_DEFAULTS(ce); + if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) { return; } - old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); EG(fake_scope) = old_scope; @@ -5057,6 +5345,8 @@ ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor) RETURN_THROWS(); } + REFLECTION_RESOLVE_GENERIC_DEFAULTS(ce); + object_init_ex(return_value, ce); } /* }}} */ @@ -5065,7 +5355,7 @@ ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor) ZEND_METHOD(ReflectionClass, newInstanceArgs) { reflection_object *intern; - zend_class_entry *ce, *old_scope; + zend_class_entry *ce; int argc = 0; HashTable *args = NULL; zend_function *constructor; @@ -5080,11 +5370,13 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs) argc = zend_hash_num_elements(args); } + REFLECTION_RESOLVE_GENERIC_DEFAULTS(ce); + if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) { return; } - old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = ce; constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); EG(fake_scope) = old_scope; @@ -5557,7 +5849,8 @@ ZEND_METHOD(ReflectionClass, isIterable) RETURN_FALSE; } - RETURN_BOOL(ce->get_iterator || instanceof_function(ce, zend_ce_traversable)); + RETURN_BOOL((ce->get_iterator && ce->get_iterator != zend_hooked_object_get_iterator) + || instanceof_function(ce, zend_ce_traversable)); } /* }}} */ @@ -5753,6 +6046,21 @@ ZEND_METHOD(ReflectionProperty, getName) } /* }}} */ +ZEND_METHOD(ReflectionProperty, getMangledName) +{ + reflection_object *intern; + property_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + + GET_REFLECTION_OBJECT_PTR(ref); + if (ref->prop == NULL) { + RETURN_STR_COPY(ref->unmangled_name); + } + + RETURN_STR_COPY(ref->prop->name); +} + static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */ { reflection_object *intern; @@ -5893,7 +6201,7 @@ ZEND_METHOD(ReflectionProperty, getValue) /* TODO: Should this always use intern->ce? */ if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) { - _DO_THROW("Given object is not an instance of the class this property was declared in"); + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); RETURN_THROWS(); } @@ -5908,7 +6216,7 @@ ZEND_METHOD(ReflectionProperty, getValue) } } - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = intern->ce; member_p = Z_OBJ_P(object)->handlers->read_property(Z_OBJ_P(object), ref->unmangled_name, BP_VAR_R, ref->cache_slot, &rv); @@ -5967,7 +6275,7 @@ ZEND_METHOD(ReflectionProperty, setValue) Z_PARAM_ZVAL(value) ZEND_PARSE_PARAMETERS_END(); - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = intern->ce; object->handlers->write_property(object, ref->unmangled_name, value, ref->cache_slot); EG(fake_scope) = old_scope; @@ -6001,7 +6309,7 @@ ZEND_METHOD(ReflectionProperty, getRawValue) GET_REFLECTION_OBJECT_PTR(ref); if (!instanceof_function(Z_OBJCE_P(object), intern->ce)) { - _DO_THROW("Given object is not an instance of the class this property was declared in"); + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); RETURN_THROWS(); } @@ -6020,13 +6328,13 @@ ZEND_METHOD(ReflectionProperty, getRawValue) intern->ce, Z_OBJ_P(object)); if (UNEXPECTED(prop && (prop->flags & ZEND_ACC_STATIC))) { - _DO_THROW("May not use getRawValue on static properties"); + zend_throw_exception(reflection_exception_ptr, "May not use getRawValue on static properties", 0); RETURN_THROWS(); } if (!prop || !prop->hooks || !prop->hooks[ZEND_PROPERTY_HOOK_GET]) { zval rv; - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = intern->ce; zval *member_p = Z_OBJ_P(object)->handlers->read_property( Z_OBJ_P(object), ref->unmangled_name, BP_VAR_R, @@ -6052,7 +6360,7 @@ static void reflection_property_set_raw_value(zend_property_info *prop, zend_object *object, zval *value) { if (!prop || !prop->hooks || !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { - zend_class_entry *old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = intern->ce; object->handlers->write_property(object, unmangled_name, value, cache_slot); EG(fake_scope) = old_scope; @@ -6080,7 +6388,7 @@ ZEND_METHOD(ReflectionProperty, setRawValue) intern->ce, Z_OBJ_P(object)); if (UNEXPECTED(prop && (prop->flags & ZEND_ACC_STATIC))) { - _DO_THROW("May not use setRawValue on static properties"); + zend_throw_exception(reflection_exception_ptr, "May not use setRawValue on static properties", 0); RETURN_THROWS(); } @@ -6275,7 +6583,6 @@ ZEND_METHOD(ReflectionProperty, isInitialized) } RETURN_FALSE; } else { - zend_class_entry *old_scope; int retval; if (!object) { @@ -6285,7 +6592,7 @@ ZEND_METHOD(ReflectionProperty, isInitialized) /* TODO: Should this always use intern->ce? */ if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) { - _DO_THROW("Given object is not an instance of the class this property was declared in"); + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); RETURN_THROWS(); } @@ -6298,7 +6605,7 @@ ZEND_METHOD(ReflectionProperty, isInitialized) } } - old_scope = EG(fake_scope); + const zend_class_entry *old_scope = EG(fake_scope); EG(fake_scope) = intern->ce; retval = Z_OBJ_HT_P(object)->has_property(Z_OBJ_P(object), ref->unmangled_name, ZEND_PROPERTY_EXISTS, ref->cache_slot); @@ -6382,7 +6689,17 @@ ZEND_METHOD(ReflectionProperty, getType) RETURN_NULL(); } - reflection_type_factory(ref->prop->type, return_value, 1); + zend_type pre_erasure = (zend_type) ZEND_TYPE_INIT_NONE(0); + zend_class_entry *ce = ref->prop->ce; + if (ce && ce->generic_types && ce->generic_types->properties) { + zend_type *boxed = zend_hash_find_ptr(ce->generic_types->properties, ref->prop->name); + if (boxed) { + pre_erasure = *boxed; + } + } + + reflection_type_factory_ex(ref->prop->type, return_value, true, + pre_erasure, reflection_resolve_declaring_class(ce), NULL); } /* }}} */ @@ -6404,7 +6721,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) /* Get-only virtual property can never be written to. */ if (prop->hooks && (prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { zend_type never_type = ZEND_TYPE_INIT_CODE(IS_NEVER, 0, 0); - reflection_type_factory(never_type, return_value, 0); + reflection_type_factory(never_type, return_value, true); return; } @@ -6414,7 +6731,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) if (!ZEND_TYPE_IS_SET(arg_info->type)) { RETURN_NULL(); } - reflection_type_factory(arg_info->type, return_value, 0); + reflection_type_factory(arg_info->type, return_value, true); return; } @@ -6422,7 +6739,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) if (!ZEND_TYPE_IS_SET(ref->prop->type)) { RETURN_NULL(); } - reflection_type_factory(ref->prop->type, return_value, 0); + reflection_type_factory(ref->prop->type, return_value, true); } /* {{{ Returns whether property has a type */ @@ -6477,11 +6794,22 @@ ZEND_METHOD(ReflectionProperty, getDefaultValue) prop_info = ref->prop; if (prop_info == NULL) { - return; // throw exception? + // Dynamic property + zend_error( + E_DEPRECATED, + "ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, " + "use ReflectionProperty::hasDefaultValue() to check if the default value exists" + ); + return; } prop = property_get_default(prop_info); if (!prop || Z_ISUNDEF_P(prop)) { + zend_error( + E_DEPRECATED, + "ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, " + "use ReflectionProperty::hasDefaultValue() to check if the default value exists" + ); return; } @@ -6545,16 +6873,16 @@ ZEND_METHOD(ReflectionProperty, hasHook) reflection_object *intern; property_reference *ref; - zend_object *type; + zend_enum_PropertyHookType type; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJ_OF_CLASS(type, reflection_property_hook_type_ptr) + Z_PARAM_ENUM(type, reflection_property_hook_type_ptr) ZEND_PARSE_PARAMETERS_END(); GET_REFLECTION_OBJECT_PTR(ref); zend_property_hook_kind kind; - if (zend_string_equals_literal(Z_STR_P(zend_enum_fetch_case_name(type)), "Get")) { + if (type == ZEND_ENUM_PropertyHookType_Get) { kind = ZEND_PROPERTY_HOOK_GET; } else { kind = ZEND_PROPERTY_HOOK_SET; @@ -6567,10 +6895,10 @@ ZEND_METHOD(ReflectionProperty, getHook) { reflection_object *intern; property_reference *ref; - zend_object *type; + zend_enum_PropertyHookType type; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJ_OF_CLASS(type, reflection_property_hook_type_ptr) + Z_PARAM_ENUM(type, reflection_property_hook_type_ptr) ZEND_PARSE_PARAMETERS_END(); GET_REFLECTION_OBJECT_PTR(ref); @@ -6581,7 +6909,7 @@ ZEND_METHOD(ReflectionProperty, getHook) } zend_function *hook; - if (zend_string_equals_literal(Z_STR_P(zend_enum_fetch_case_name(type)), "Get")) { + if (type == ZEND_ENUM_PropertyHookType_Get) { hook = ref->prop->hooks[ZEND_PROPERTY_HOOK_GET]; } else { hook = ref->prop->hooks[ZEND_PROPERTY_HOOK_SET]; @@ -6599,101 +6927,335 @@ ZEND_METHOD(ReflectionProperty, isFinal) _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL); } -/* {{{ Constructor. Throws an Exception in case the given extension does not exist */ -ZEND_METHOD(ReflectionExtension, __construct) +static zend_result get_ce_from_scope_name(zend_class_entry **scope, zend_string *scope_name, zend_execute_data *execute_data) { - zval *object; - char *lcname; - reflection_object *intern; - zend_module_entry *module; - char *name_str; - size_t name_len; - ALLOCA_FLAG(use_heap) - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) { - RETURN_THROWS(); + if (!scope_name) { + *scope = NULL; + return SUCCESS; } - object = ZEND_THIS; - intern = Z_REFLECTION_P(object); - lcname = do_alloca(name_len + 1, use_heap); - zend_str_tolower_copy(lcname, name_str, name_len); - if ((module = zend_hash_str_find_ptr(&module_registry, lcname, name_len)) == NULL) { - free_alloca(lcname, use_heap); - zend_throw_exception_ex(reflection_exception_ptr, 0, - "Extension \"%s\" does not exist", name_str); - RETURN_THROWS(); + *scope = zend_lookup_class(scope_name); + if (!*scope) { + zend_throw_error(NULL, "Class \"%s\" not found", ZSTR_VAL(scope_name)); + return FAILURE; } - free_alloca(lcname, use_heap); - zval *prop_name = reflection_prop_name(object); - zval_ptr_dtor(prop_name); - ZVAL_STRING(prop_name, module->name); - intern->ptr = module; - intern->ref_type = REF_TYPE_OTHER; - intern->ce = NULL; + return SUCCESS; } -/* }}} */ -/* {{{ Returns a string representation */ -ZEND_METHOD(ReflectionExtension, __toString) +static zend_always_inline uint32_t set_visibility_to_visibility(uint32_t set_visibility) { - reflection_object *intern; - zend_module_entry *module; - smart_str str = {0}; - - ZEND_PARSE_PARAMETERS_NONE(); - GET_REFLECTION_OBJECT_PTR(module); - _extension_string(&str, module, ""); - RETURN_STR(smart_str_extract(&str)); + switch (set_visibility) { + case ZEND_ACC_PUBLIC_SET: + return ZEND_ACC_PUBLIC; + case ZEND_ACC_PROTECTED_SET: + return ZEND_ACC_PROTECTED; + case ZEND_ACC_PRIVATE_SET: + return ZEND_ACC_PRIVATE; + default: ZEND_UNREACHABLE(); + } } -/* }}} */ -/* {{{ Returns this extension's name */ -ZEND_METHOD(ReflectionExtension, getName) +static bool check_visibility(uint32_t visibility, zend_class_entry *ce, zend_class_entry *scope) { - reflection_object *intern; - zend_module_entry *module; - - ZEND_PARSE_PARAMETERS_NONE(); - - GET_REFLECTION_OBJECT_PTR(module); - RETURN_STRING(module->name); + if (!(visibility & ZEND_ACC_PUBLIC) && (scope != ce)) { + if (!scope) { + return false; + } + if (visibility & ZEND_ACC_PRIVATE) { + return false; + } + ZEND_ASSERT(visibility & ZEND_ACC_PROTECTED); + if (!instanceof_function(scope, ce) && !instanceof_function(ce, scope)) { + return false; + } + } + return true; } -/* }}} */ -/* {{{ Returns this extension's version */ -ZEND_METHOD(ReflectionExtension, getVersion) +ZEND_METHOD(ReflectionProperty, isReadable) { reflection_object *intern; - zend_module_entry *module; + property_reference *ref; + zend_string *scope_name; + zend_object *obj = NULL; - ZEND_PARSE_PARAMETERS_NONE(); - GET_REFLECTION_OBJECT_PTR(module); + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_NULL(scope_name) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OR_NULL(obj) + ZEND_PARSE_PARAMETERS_END(); - /* An extension does not necessarily have a version number */ - if (module->version == NO_VERSION_YET) { - RETURN_NULL(); - } else { - RETURN_STRING(module->version); - } -} -/* }}} */ + GET_REFLECTION_OBJECT_PTR(ref); -/* {{{ Returns an array of this extension's functions */ -ZEND_METHOD(ReflectionExtension, getFunctions) -{ - reflection_object *intern; - zend_module_entry *module; - zval function; - zend_function *fptr; + zend_property_info *prop = ref->prop; + if (prop && obj) { + if (prop->flags & ZEND_ACC_STATIC) { + zend_throw_exception(reflection_exception_ptr, "null is expected as object argument for static properties", 0); + RETURN_THROWS(); + } + if (!instanceof_function(obj->ce, prop->ce)) { + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); + RETURN_THROWS(); + } + prop = reflection_property_get_effective_prop(ref, intern->ce, obj); + } - ZEND_PARSE_PARAMETERS_NONE(); - GET_REFLECTION_OBJECT_PTR(module); + zend_class_entry *ce = obj ? obj->ce : intern->ce; + if (!prop) { + if (obj && obj->properties && zend_hash_find(obj->properties, ref->unmangled_name)) { + RETURN_TRUE; + } +handle_magic_get: + if (ce->__get) { + if (obj && ce->__isset) { + uint32_t *guard = zend_get_property_guard(obj, ref->unmangled_name); + if (!((*guard) & ZEND_GUARD_PROPERTY_ISSET)) { + GC_ADDREF(obj); + *guard |= ZEND_GUARD_PROPERTY_ISSET; + zval member; + ZVAL_STR(&member, ref->unmangled_name); + zend_call_known_instance_method_with_1_params(ce->__isset, obj, return_value, &member); + + if (Z_TYPE_P(return_value) == IS_REFERENCE) { + zend_unwrap_reference(return_value); + } - array_init(return_value); - ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), fptr) { - if (fptr->common.type==ZEND_INTERNAL_FUNCTION - && fptr->internal_function.module == module) { + *guard &= ~ZEND_GUARD_PROPERTY_ISSET; + OBJ_RELEASE(obj); + return; + } + } + RETURN_TRUE; + } + if (obj && zend_lazy_object_must_init(obj)) { + obj = zend_lazy_object_init(obj); + if (!obj) { + RETURN_THROWS(); + } + if (obj->properties && zend_hash_find(obj->properties, ref->unmangled_name)) { + RETURN_TRUE; + } + } + RETURN_FALSE; + } + + zend_class_entry *scope; + if (get_ce_from_scope_name(&scope, scope_name, execute_data) == FAILURE) { + RETURN_THROWS(); + } + + if (!check_visibility(prop->flags & ZEND_ACC_PPP_MASK, prop->ce, scope)) { + if (!(prop->flags & ZEND_ACC_STATIC)) { + goto handle_magic_get; + } + RETURN_FALSE; + } + + if (prop->flags & ZEND_ACC_VIRTUAL) { + ZEND_ASSERT(prop->hooks); + if (!prop->hooks[ZEND_PROPERTY_HOOK_GET]) { + RETURN_FALSE; + } + } else if (obj && (!prop->hooks || !prop->hooks[ZEND_PROPERTY_HOOK_GET])) { +retry_declared:; + zval *prop_val = OBJ_PROP(obj, prop->offset); + if (Z_TYPE_P(prop_val) == IS_UNDEF) { + if (zend_lazy_object_must_init(obj) && (Z_PROP_FLAG_P(prop_val) & IS_PROP_LAZY)) { + obj = zend_lazy_object_init(obj); + if (!obj) { + RETURN_THROWS(); + } + goto retry_declared; + } + if (!(Z_PROP_FLAG_P(prop_val) & IS_PROP_UNINIT)) { + goto handle_magic_get; + } + RETURN_FALSE; + } + } else if (prop->flags & ZEND_ACC_STATIC) { + if (ce->default_static_members_count && !CE_STATIC_MEMBERS(ce)) { + zend_class_init_statics(ce); + } + zval *prop_val = CE_STATIC_MEMBERS(ce) + prop->offset; + RETURN_BOOL(!Z_ISUNDEF_P(prop_val)); + } + + RETURN_TRUE; +} + +ZEND_METHOD(ReflectionProperty, isWritable) +{ + reflection_object *intern; + property_reference *ref; + zend_string *scope_name; + zend_object *obj = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR_OR_NULL(scope_name) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OR_NULL(obj) + ZEND_PARSE_PARAMETERS_END(); + + GET_REFLECTION_OBJECT_PTR(ref); + + zend_property_info *prop = ref->prop; + if (prop && obj) { + if (prop->flags & ZEND_ACC_STATIC) { + zend_throw_exception(reflection_exception_ptr, "null is expected as object argument for static properties", 0); + RETURN_THROWS(); + } + if (!instanceof_function(obj->ce, prop->ce)) { + zend_throw_exception(reflection_exception_ptr, "Given object is not an instance of the class this property was declared in", 0); + RETURN_THROWS(); + } + prop = reflection_property_get_effective_prop(ref, intern->ce, obj); + } + + zend_class_entry *ce = obj ? obj->ce : intern->ce; + if (!prop) { + if (!(ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) { + RETURN_TRUE; + } + /* This path is effectively unreachable, but theoretically possible for + * two internal classes where ZEND_ACC_NO_DYNAMIC_PROPERTIES is only + * added to the subclass, in which case a ReflectionProperty can be + * constructed on the parent class, and then tested on the subclass. */ +handle_magic_set: + RETURN_BOOL(ce->__set); + } + + zend_class_entry *scope; + if (get_ce_from_scope_name(&scope, scope_name, execute_data) == FAILURE) { + RETURN_THROWS(); + } + + if (!check_visibility(prop->flags & ZEND_ACC_PPP_MASK, prop->ce, scope)) { + if (!(prop->flags & ZEND_ACC_STATIC)) { + goto handle_magic_set; + } + RETURN_FALSE; + } + uint32_t set_visibility = prop->flags & ZEND_ACC_PPP_SET_MASK; + if (!set_visibility) { + set_visibility = zend_visibility_to_set_visibility(prop->flags & ZEND_ACC_PPP_MASK); + } + if (!check_visibility(set_visibility_to_visibility(set_visibility), prop->ce, scope)) { + RETURN_FALSE; + } + + if (prop->flags & ZEND_ACC_VIRTUAL) { + ZEND_ASSERT(prop->hooks); + if (!prop->hooks[ZEND_PROPERTY_HOOK_SET]) { + RETURN_FALSE; + } + } else if (obj && (prop->flags & ZEND_ACC_READONLY)) { +retry:; + zval *prop_val = OBJ_PROP(obj, prop->offset); + if (Z_TYPE_P(prop_val) == IS_UNDEF + && zend_lazy_object_must_init(obj) + && (Z_PROP_FLAG_P(prop_val) & IS_PROP_LAZY)) { + obj = zend_lazy_object_init(obj); + if (!obj) { + RETURN_THROWS(); + } + goto retry; + } + if (Z_TYPE_P(prop_val) != IS_UNDEF && !(Z_PROP_FLAG_P(prop_val) & IS_PROP_REINITABLE)) { + RETURN_FALSE; + } + } + + RETURN_TRUE; +} + +/* {{{ Constructor. Throws an Exception in case the given extension does not exist */ +ZEND_METHOD(ReflectionExtension, __construct) +{ + zval *object; + reflection_object *intern; + zend_module_entry *module; + zend_string *name_str; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name_str) == FAILURE) { + RETURN_THROWS(); + } + + object = ZEND_THIS; + intern = Z_REFLECTION_P(object); + if ((module = zend_hash_find_ptr_lc(&module_registry, name_str)) == NULL) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Extension \"%s\" does not exist", ZSTR_VAL(name_str)); + RETURN_THROWS(); + } + zval *prop_name = reflection_prop_name(object); + zval_ptr_dtor(prop_name); + ZVAL_STRING(prop_name, module->name); + intern->ptr = module; + intern->ref_type = REF_TYPE_OTHER; + intern->ce = NULL; +} +/* }}} */ + +/* {{{ Returns a string representation */ +ZEND_METHOD(ReflectionExtension, __toString) +{ + reflection_object *intern; + zend_module_entry *module; + smart_str str = {0}; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(module); + _extension_string(&str, module, ""); + RETURN_STR(smart_str_extract(&str)); +} +/* }}} */ + +/* {{{ Returns this extension's name */ +ZEND_METHOD(ReflectionExtension, getName) +{ + reflection_object *intern; + zend_module_entry *module; + + ZEND_PARSE_PARAMETERS_NONE(); + + GET_REFLECTION_OBJECT_PTR(module); + RETURN_STRING(module->name); +} +/* }}} */ + +/* {{{ Returns this extension's version */ +ZEND_METHOD(ReflectionExtension, getVersion) +{ + reflection_object *intern; + zend_module_entry *module; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(module); + + /* An extension does not necessarily have a version number */ + if (module->version == NO_VERSION_YET) { + RETURN_NULL(); + } else { + RETURN_STRING(module->version); + } +} +/* }}} */ + +/* {{{ Returns an array of this extension's functions */ +ZEND_METHOD(ReflectionExtension, getFunctions) +{ + reflection_object *intern; + zend_module_entry *module; + zval function; + zend_function *fptr; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(module); + + array_init(return_value); + ZEND_HASH_MAP_FOREACH_PTR(CG(function_table), fptr) { + if (fptr->common.type==ZEND_INTERNAL_FUNCTION + && fptr->internal_function.module == module) { reflection_function_factory(fptr, NULL, &function); zend_hash_update(Z_ARRVAL_P(return_value), fptr->common.function_name, &function); } @@ -6791,7 +7353,7 @@ ZEND_METHOD(ReflectionExtension, getClasses) array_init(return_value); ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { - add_extension_class(ce, key, return_value, module, 1); + add_extension_class(ce, key, return_value, module, true); } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -6809,7 +7371,7 @@ ZEND_METHOD(ReflectionExtension, getClassNames) array_init(return_value); ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) { - add_extension_class(ce, key, return_value, module, 0); + add_extension_class(ce, key, return_value, module, false); } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -7043,16 +7605,15 @@ ZEND_METHOD(ReflectionZendExtension, getCopyright) /* {{{ Dummy constructor -- always throws ReflectionExceptions. */ ZEND_METHOD(ReflectionReference, __construct) { - _DO_THROW( + zend_throw_exception(reflection_exception_ptr, "Cannot directly instantiate ReflectionReference. " - "Use ReflectionReference::fromArrayElement() instead" - ); + "Use ReflectionReference::fromArrayElement() instead", 0); } /* }}} */ static bool is_ignorable_reference(HashTable *ht, zval *ref) { if (Z_REFCOUNT_P(ref) != 1) { - return 0; + return false; } /* Directly self-referential arrays are treated as proper references @@ -7081,7 +7642,7 @@ ZEND_METHOD(ReflectionReference, fromArrayElement) } if (!item) { - _DO_THROW("Array key not found"); + zend_throw_exception(reflection_exception_ptr, "Array key not found", 0); RETURN_THROWS(); } @@ -7108,7 +7669,7 @@ ZEND_METHOD(ReflectionReference, getId) intern = Z_REFLECTION_P(ZEND_THIS); if (Z_TYPE(intern->obj) != IS_REFERENCE) { - _DO_THROW("Corrupted ReflectionReference object"); + zend_throw_exception(reflection_exception_ptr, "Corrupted ReflectionReference object", 0); RETURN_THROWS(); } @@ -7117,7 +7678,7 @@ ZEND_METHOD(ReflectionReference, getId) RETURN_THROWS(); } - REFLECTION_G(key_initialized) = 1; + REFLECTION_G(key_initialized) = true; } /* SHA1(ref || key) to avoid directly exposing memory addresses. */ @@ -7132,13 +7693,13 @@ ZEND_METHOD(ReflectionReference, getId) ZEND_METHOD(ReflectionAttribute, __construct) { - _DO_THROW("Cannot directly instantiate ReflectionAttribute"); + zend_throw_exception(reflection_exception_ptr, "Cannot directly instantiate ReflectionAttribute", 0); } ZEND_METHOD(ReflectionAttribute, __clone) { /* __clone() is private but this is reachable with reflection */ - _DO_THROW("Cannot clone object using __clone()"); + zend_throw_exception(reflection_exception_ptr, "Cannot clone object using __clone()", 0); } /* {{{ Returns a string representation */ @@ -7167,10 +7728,7 @@ ZEND_METHOD(ReflectionAttribute, __toString) smart_str_appends(&str, " = "); } - if (format_default_value(&str, &attr->data->args[i].value) == FAILURE) { - smart_str_free(&str); - RETURN_THROWS(); - } + format_default_value(&str, &attr->data->args[i].value); smart_str_appends(&str, " ]\n"); } @@ -7276,26 +7834,61 @@ ZEND_METHOD(ReflectionAttribute, newInstance) RETURN_THROWS(); } - if (ce->type == ZEND_USER_CLASS) { - uint32_t flags = zend_attribute_attribute_get_flags(marker, ce); - if (EG(exception)) { - RETURN_THROWS(); - } + /* This code can be reached under one of three possible conditions: + * - the attribute is an internal attribute, and it had the target and + * and repetition validated already + * - the attribute is an internal attribute and repetition was validated + * already, the internal validator might have been run if the target was + * correct, but any error would have been stored in + * `zend_attribute.validation_error` instead of being thrown due to the + * presence of #[DelayedTargetValidation] + * - the attribute is a user attribute, and neither target nor repetition + * have been validated. + */ + uint32_t flags = zend_attribute_attribute_get_flags(marker, ce); + if (EG(exception)) { + RETURN_THROWS(); + } - if (!(attr->target & flags)) { - zend_string *location = zend_get_attribute_target_names(attr->target); - zend_string *allowed = zend_get_attribute_target_names(flags); + /* No harm in always running target validation, for internal attributes + * without #[DelayedTargetValidation] it isn't necessary but will always + * succeed. */ + if (!(attr->target & flags)) { + zend_string *location = zend_get_attribute_target_names(attr->target); + zend_string *allowed = zend_get_attribute_target_names(flags); - zend_throw_error(NULL, "Attribute \"%s\" cannot target %s (allowed targets: %s)", - ZSTR_VAL(attr->data->name), ZSTR_VAL(location), ZSTR_VAL(allowed) - ); + zend_throw_error(NULL, "Attribute \"%s\" cannot target %s (allowed targets: %s)", + ZSTR_VAL(attr->data->name), ZSTR_VAL(location), ZSTR_VAL(allowed) + ); - zend_string_release(location); - zend_string_release(allowed); + zend_string_release(location); + zend_string_release(allowed); - RETURN_THROWS(); - } + RETURN_THROWS(); + } + + if (attr->data->validation_error != NULL) { + /* Delayed validation errors should only be set for internal attributes. */ + ZEND_ASSERT(ce->type == ZEND_INTERNAL_CLASS); + /* Delayed validation errors should only be set when + * #[\DelayedTargetValidation] is used. Searching for the attribute is + * more expensive than just an assertion and so we don't worry about it + * for non-debug builds. See discussion on GH-18817. */ +#if ZEND_DEBUG + zend_attribute *delayed_target_validation = zend_get_attribute_str( + attr->attributes, + "delayedtargetvalidation", + strlen("delayedtargetvalidation") + ); + ZEND_ASSERT(delayed_target_validation != NULL); +#endif + zend_throw_exception(zend_ce_error, ZSTR_VAL(attr->data->validation_error), 0); + RETURN_THROWS(); + } + /* Repetition validation is done even if #[DelayedTargetValidation] is used + * and so can be skipped for internal attributes. */ + if (ce->type == ZEND_USER_CLASS) { if (!(flags & ZEND_ATTRIBUTE_IS_REPEATABLE)) { if (zend_is_attribute_repeated(attr->attributes, attr->data)) { zend_throw_error(NULL, "Attribute \"%s\" must not be repeated", ZSTR_VAL(attr->data->name)); @@ -7304,6 +7897,13 @@ ZEND_METHOD(ReflectionAttribute, newInstance) } } + if (attr->data->generic_arity > 0) { + zend_check_generic_new_arguments(ce, attr->data->generic_arity, attr->data->generic_args); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + zval obj; if (SUCCESS != zend_get_attribute_object(&obj, ce, attr->data, attr->scope, attr->filename)) { @@ -7420,7 +8020,7 @@ ZEND_METHOD(ReflectionEnum, getBackingType) RETURN_NULL(); } else { zend_type type = ZEND_TYPE_INIT_CODE(ce->enum_backing_type, 0, 0); - reflection_type_factory(type, return_value, 0); + reflection_type_factory(type, return_value, false); } } @@ -7613,7 +8213,7 @@ ZEND_METHOD(ReflectionFiber, getCallable) ZEND_PARSE_PARAMETERS_NONE(); if (fiber == NULL || fiber->context.status == ZEND_FIBER_STATUS_DEAD) { - zend_throw_error(NULL, "Cannot fetch the callable from a fiber that has terminated"); \ + zend_throw_error(NULL, "Cannot fetch the callable from a fiber that has terminated"); RETURN_THROWS(); } @@ -7687,6 +8287,20 @@ ZEND_METHOD(ReflectionConstant, getName) RETURN_STR_COPY(const_->name); } +ZEND_METHOD(ReflectionConstant, inNamespace) +{ + reflection_object *intern; + zend_constant *const_; + + ZEND_PARSE_PARAMETERS_NONE(); + + GET_REFLECTION_OBJECT_PTR(const_); + + const char *backslash = zend_memrchr(ZSTR_VAL(const_->name), '\\', ZSTR_LEN(const_->name)); + RETURN_BOOL(backslash); +} +/* }}} */ + ZEND_METHOD(ReflectionConstant, getNamespaceName) { reflection_object *intern; @@ -7838,48 +8452,792 @@ ZEND_METHOD(ReflectionConstant, __toString) RETURN_STR(smart_str_extract(&str)); } -PHP_MINIT_FUNCTION(reflection) /* {{{ */ +ZEND_METHOD(ReflectionGenericTypeParameter, __construct) { - memcpy(&reflection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - reflection_object_handlers.offset = XtOffsetOf(reflection_object, zo); - reflection_object_handlers.free_obj = reflection_free_objects_storage; - reflection_object_handlers.clone_obj = NULL; - reflection_object_handlers.write_property = _reflection_write_property; - reflection_object_handlers.get_gc = reflection_get_gc; + zend_throw_exception(reflection_exception_ptr, + "Cannot directly instantiate ReflectionGenericTypeParameter", 0); +} - reflection_exception_ptr = register_class_ReflectionException(zend_ce_exception); +ZEND_METHOD(ReflectionTypeParameterReference, __construct) +{ + zend_throw_exception(reflection_exception_ptr, + "Cannot directly instantiate ReflectionTypeParameterReference", 0); +} - reflection_ptr = register_class_Reflection(); - reflector_ptr = register_class_Reflector(zend_ce_stringable); +static void reflection_generic_type_parameter_factory( + zend_generic_parameter *param, uint32_t index, zval *declaring, zval *object) +{ + reflection_object *intern; + generic_parameter_reference *reference; - reflection_function_abstract_ptr = register_class_ReflectionFunctionAbstract(reflector_ptr); - reflection_function_abstract_ptr->default_object_handlers = &reflection_object_handlers; - reflection_function_abstract_ptr->create_object = reflection_objects_new; + object_init_ex(object, reflection_generic_type_parameter_ptr); + intern = Z_REFLECTION_P(object); + reference = emalloc(sizeof(generic_parameter_reference)); + reference->param = param; + reference->index = index; + ZVAL_COPY(&reference->declaring, declaring); + intern->ptr = reference; + intern->ref_type = REF_TYPE_GENERIC_PARAMETER; - reflection_function_ptr = register_class_ReflectionFunction(reflection_function_abstract_ptr); - reflection_function_ptr->create_object = reflection_objects_new; - reflection_function_ptr->default_object_handlers = &reflection_object_handlers; + ZVAL_STR_COPY(reflection_prop_name(object), param->name); +} - reflection_generator_ptr = register_class_ReflectionGenerator(); - reflection_generator_ptr->create_object = reflection_objects_new; - reflection_generator_ptr->default_object_handlers = &reflection_object_handlers; +static void reflection_build_generic_parameters_array( + zend_generic_parameter_list *list, zval *declaring, zval *return_value) +{ + if (!list) { + array_init(return_value); + return; + } + array_init_size(return_value, list->count); + for (uint32_t i = 0; i < list->count; i++) { + zval entry; + reflection_generic_type_parameter_factory(&list->parameters[i], i, declaring, &entry); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &entry); + } +} - reflection_parameter_ptr = register_class_ReflectionParameter(reflector_ptr); - reflection_parameter_ptr->create_object = reflection_objects_new; - reflection_parameter_ptr->default_object_handlers = &reflection_object_handlers; +ZEND_METHOD(ReflectionFunctionAbstract, isGeneric) +{ + reflection_object *intern; + zend_function *fptr; - reflection_type_ptr = register_class_ReflectionType(zend_ce_stringable); - reflection_type_ptr->create_object = reflection_objects_new; - reflection_type_ptr->default_object_handlers = &reflection_object_handlers; + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(fptr); - reflection_named_type_ptr = register_class_ReflectionNamedType(reflection_type_ptr); - reflection_named_type_ptr->create_object = reflection_objects_new; - reflection_named_type_ptr->default_object_handlers = &reflection_object_handlers; + if (fptr->type != ZEND_USER_FUNCTION) { + RETURN_FALSE; + } + RETURN_BOOL(fptr->op_array.generic_parameters != NULL); +} - reflection_union_type_ptr = register_class_ReflectionUnionType(reflection_type_ptr); - reflection_union_type_ptr->create_object = reflection_objects_new; - reflection_union_type_ptr->default_object_handlers = &reflection_object_handlers; +ZEND_METHOD(ReflectionFunctionAbstract, getGenericParameters) +{ + reflection_object *intern; + zend_function *fptr; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(fptr); + + if (fptr->type != ZEND_USER_FUNCTION) { + array_init(return_value); + return; + } + reflection_build_generic_parameters_array(fptr->op_array.generic_parameters, ZEND_THIS, return_value); +} + +ZEND_METHOD(ReflectionClass, isGeneric) +{ + reflection_object *intern; + zend_class_entry *ce; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ce); + + RETURN_BOOL(ce->generic_parameters != NULL); +} + +ZEND_METHOD(ReflectionClass, getGenericParameters) +{ + reflection_object *intern; + zend_class_entry *ce; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ce); + + reflection_build_generic_parameters_array(ce->generic_parameters, ZEND_THIS, return_value); +} + +#define GET_GENERIC_PARAMETER_REFERENCE(intern, param_ref) \ + do { \ + (intern) = Z_REFLECTION_P(getThis()); \ + if ((intern)->ptr == NULL) { \ + zend_throw_error(NULL, "Internal error: Failed to retrieve the type parameter reference"); \ + RETURN_THROWS(); \ + } \ + (param_ref) = (generic_parameter_reference *) (intern)->ptr; \ + } while (0) + +ZEND_METHOD(ReflectionGenericTypeParameter, getName) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + RETURN_STR_COPY(ref->param->name); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, getPosition) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + RETURN_LONG((zend_long) ref->index); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, getVariance) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + + const char *case_name; + switch (ref->param->variance) { + case 1: case_name = "Covariant"; break; + case 2: case_name = "Contravariant"; break; + default: case_name = "Invariant"; break; + } + zend_object *case_obj = zend_enum_get_case_cstr(reflection_generic_variance_ptr, case_name); + if (!case_obj) { + zend_throw_error(NULL, "Internal error: ReflectionGenericVariance enum case not found"); + RETURN_THROWS(); + } + ZVAL_OBJ_COPY(return_value, case_obj); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, hasBound) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + RETURN_BOOL(ZEND_TYPE_IS_SET(ref->param->bound)); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, getBound) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + + if (!ZEND_TYPE_IS_SET(ref->param->bound)) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Type parameter %s has no bound", ZSTR_VAL(ref->param->name)); + RETURN_THROWS(); + } + zend_class_entry *declaring_class = NULL; + zend_function *declaring_fn = NULL; + if (Z_TYPE(ref->declaring) == IS_OBJECT) { + zend_object *obj = Z_OBJ(ref->declaring); + if (instanceof_function(obj->ce, reflection_class_ptr)) { + reflection_object *decl_intern = reflection_object_from_obj(obj); + declaring_class = decl_intern->ptr; + } else if (instanceof_function(obj->ce, reflection_function_abstract_ptr)) { + reflection_object *decl_intern = reflection_object_from_obj(obj); + declaring_fn = decl_intern->ptr; + } + } + zend_type primary = ZEND_TYPE_IS_SET(ref->param->bound_pre_erasure) + ? ref->param->bound_pre_erasure : ref->param->bound; + reflection_type_factory_ex(primary, return_value, false, + (zend_type) ZEND_TYPE_INIT_NONE(0), declaring_class, declaring_fn); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, hasDefault) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + RETURN_BOOL(ZEND_TYPE_IS_SET(ref->param->default_type)); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, getDefault) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + + if (!ZEND_TYPE_IS_SET(ref->param->default_type)) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Type parameter %s has no default", ZSTR_VAL(ref->param->name)); + RETURN_THROWS(); + } + + zend_class_entry *declaring_class = NULL; + zend_function *declaring_fn = NULL; + if (Z_TYPE(ref->declaring) == IS_OBJECT) { + zend_object *obj = Z_OBJ(ref->declaring); + if (instanceof_function(obj->ce, reflection_class_ptr)) { + reflection_object *decl_intern = reflection_object_from_obj(obj); + declaring_class = decl_intern->ptr; + } else if (instanceof_function(obj->ce, reflection_function_abstract_ptr)) { + reflection_object *decl_intern = reflection_object_from_obj(obj); + declaring_fn = decl_intern->ptr; + } + } + + zend_type primary = ZEND_TYPE_IS_SET(ref->param->default_pre_erasure) + ? ref->param->default_pre_erasure : ref->param->default_type; + reflection_type_factory_ex(primary, return_value, false, + (zend_type) ZEND_TYPE_INIT_NONE(0), declaring_class, declaring_fn); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, getDeclaringEntity) +{ + reflection_object *intern; + generic_parameter_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + ZVAL_COPY(return_value, &ref->declaring); +} + +ZEND_METHOD(ReflectionGenericTypeParameter, __toString) +{ + reflection_object *intern; + generic_parameter_reference *ref; + smart_str str = {0}; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_GENERIC_PARAMETER_REFERENCE(intern, ref); + + switch (ref->param->variance) { + case 1: + smart_str_appendc(&str, '+'); + break; + case 2: + smart_str_appendc(&str, '-'); + break; + default: + break; + } + smart_str_append(&str, ref->param->name); + if (ZEND_TYPE_IS_SET(ref->param->bound)) { + zend_string *bound = zend_type_to_string(ref->param->bound); + smart_str_appends(&str, " : "); + smart_str_append(&str, bound); + zend_string_release(bound); + } + if (ZEND_TYPE_IS_SET(ref->param->default_type)) { + zend_string *def = zend_type_to_string(ref->param->default_type); + smart_str_appends(&str, " = "); + smart_str_append(&str, def); + zend_string_release(def); + } + RETURN_NEW_STR(smart_str_extract(&str)); +} + +ZEND_METHOD(ReflectionTypeParameterReference, getName) +{ + reflection_object *intern; + type_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ref); + + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(ref->type)) { + zend_throw_error(NULL, "Type parameter reference has no parameter"); + RETURN_THROWS(); + } + zend_type_parameter_ref *tp = ZEND_TYPE_TYPE_PARAMETER(ref->type); + RETURN_STR_COPY(tp->name); +} + +ZEND_METHOD(ReflectionTypeParameterReference, getTypeParameter) +{ + reflection_object *intern; + type_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ref); + + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(ref->type)) { + zend_throw_error(NULL, "Type parameter reference has no parameter"); + RETURN_THROWS(); + } + + zend_type_parameter_ref *tp = ZEND_TYPE_TYPE_PARAMETER(ref->type); + + zend_generic_parameter_list *list = NULL; + zval declaring_zv; + ZVAL_UNDEF(&declaring_zv); + + if (tp->origin == ZEND_GENERIC_ORIGIN_CLASS_LIKE) { + if (!ref->declaring_class) { + zend_throw_error(NULL, + "Type parameter reference has no declaring class context"); + RETURN_THROWS(); + } + + list = ref->declaring_class->generic_parameters; + zend_reflection_class_factory(ref->declaring_class, &declaring_zv); + } else { + if (!ref->declaring_fn) { + zend_throw_error(NULL, + "Type parameter reference has no declaring function context"); + RETURN_THROWS(); + } + + list = ref->declaring_fn->op_array.generic_parameters; + if (ref->declaring_fn->op_array.scope) { + reflection_method_factory(ref->declaring_fn->op_array.scope, + ref->declaring_fn, NULL, &declaring_zv); + } else { + reflection_function_factory(ref->declaring_fn, NULL, &declaring_zv); + } + } + + if (!list || tp->index >= list->count) { + zval_ptr_dtor(&declaring_zv); + zend_throw_error(NULL, + "Type parameter index %u out of range for declaring entity", tp->index); + RETURN_THROWS(); + } + + reflection_generic_type_parameter_factory( + &list->parameters[tp->index], tp->index, &declaring_zv, return_value); + zval_ptr_dtor(&declaring_zv); +} + +ZEND_METHOD(ReflectionTypeParameterReference, allowsNull) +{ + ZEND_PARSE_PARAMETERS_NONE(); + RETURN_TRUE; +} + +ZEND_METHOD(ReflectionTypeParameterReference, __toString) +{ + reflection_object *intern; + type_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ref); + + if (!ZEND_TYPE_HAS_TYPE_PARAMETER(ref->type)) { + RETURN_EMPTY_STRING(); + } + zend_type_parameter_ref *tp = ZEND_TYPE_TYPE_PARAMETER(ref->type); + RETURN_STR_COPY(tp->name); +} + +ZEND_METHOD(ReflectionNamedType, hasGenericArguments) +{ + reflection_object *intern; + type_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ref); + RETURN_BOOL(ZEND_TYPE_HAS_NAMED_WITH_ARGS(ref->pre_erasure)); +} + +ZEND_METHOD(ReflectionNamedType, getGenericArguments) +{ + reflection_object *intern; + type_reference *ref; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ref); + + if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(ref->pre_erasure)) { + array_init(return_value); + return; + } + + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(ref->pre_erasure); + array_init_size(return_value, named->count); + for (uint32_t i = 0; i < named->count; i++) { + zval entry; + reflection_type_factory_ex_copy(named->args[i], &entry, false, + (zend_type) ZEND_TYPE_INIT_NONE(0), + ref->declaring_class, ref->declaring_fn); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &entry); + } +} + +static void reflection_build_args_list_ex(zval *return_value, const zend_type *args, + uint32_t count, zend_class_entry *declaring_class, bool copy_types) +{ + array_init_size(return_value, count); + for (uint32_t i = 0; i < count; i++) { + zval entry; + if (copy_types) { + reflection_type_factory_ex_copy(args[i], &entry, false, + (zend_type) ZEND_TYPE_INIT_NONE(0), + declaring_class, NULL); + } else { + reflection_type_factory_ex(args[i], &entry, false, + (zend_type) ZEND_TYPE_INIT_NONE(0), + declaring_class, NULL); + } + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &entry); + } +} + +static void reflection_build_args_list(zval *return_value, const zend_type *args, + uint32_t count, zend_class_entry *declaring_class) +{ + reflection_build_args_list_ex(return_value, args, count, declaring_class, false); +} + +static void reflection_build_named_args_list(zval *return_value, const zend_type *boxed, + zend_class_entry *declaring_class) +{ + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*boxed); + reflection_build_args_list(return_value, named->args, named->count, declaring_class); +} + +static void reflection_type_array_release(zend_type *args, uint32_t arity) +{ + for (uint32_t i = 0; i < arity; i++) { + zend_type_release(args[i], /* persistent */ false); + } +} + +static zend_class_entry *reflection_find_interface_by_name( + zend_class_entry *ce, zend_string *name) +{ + if (!(ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES)) { + return NULL; + } + + for (uint32_t i = 0; i < ce->num_interfaces; i++) { + if (ce->interfaces[i] && zend_string_equals_ci(ce->interfaces[i]->name, name)) { + return ce->interfaces[i]; + } + } + + return NULL; +} + +static bool reflection_get_direct_inheritance_binding( + zend_class_entry *ce, zend_class_entry *target, + const zend_type **out_args, uint32_t *out_arity) +{ + if (!ce->generic_types) { + return false; + } + + if (ce->generic_types->extends && ZEND_TYPE_HAS_NAMED_WITH_ARGS(*ce->generic_types->extends)) { + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*ce->generic_types->extends); + bool matches = (ce->ce_flags & ZEND_ACC_RESOLVED_PARENT) + ? ce->parent == target + : (named->name && target->name && zend_string_equals_ci(named->name, target->name)); + + if (matches) { + *out_args = named->args; + *out_arity = named->count; + return true; + } + } + + if (ce->generic_types->implements) { + zval *zv; + ZEND_HASH_FOREACH_VAL(ce->generic_types->implements, zv) { + zend_type *boxed = (zend_type *) Z_PTR_P(zv); + if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) { + continue; + } + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*boxed); + if (named->name && zend_string_equals_ci(named->name, target->name)) { + *out_args = named->args; + *out_arity = named->count; + return true; + } + } ZEND_HASH_FOREACH_END(); + } + + return false; +} + +static void reflection_append_binding( + zval *return_value, const zend_type *args, uint32_t arity, + const zend_type *ce_args, uint32_t ce_arity, + zend_class_entry *declaring_class) +{ + zval entry; + + if (!ce_args || arity == 0) { + reflection_build_args_list_ex(&entry, args, arity, declaring_class, true); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &entry); + return; + } + + ALLOCA_FLAG(use_heap) + zend_type *mapped = (zend_type *) do_alloca(sizeof(zend_type) * arity, use_heap); + for (uint32_t i = 0; i < arity; i++) { + mapped[i] = reflection_type_substitute_class_params(args[i], ce_args, ce_arity); + } + reflection_build_args_list_ex(&entry, mapped, arity, declaring_class, true); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &entry); + reflection_type_array_release(mapped, arity); + free_alloca(mapped, use_heap); +} + +static void reflection_collect_interface_bindings( + zval *return_value, zend_class_entry *ce, zend_class_entry *ancestor, + const zend_type *ce_args, uint32_t ce_arity, + zend_class_entry *declaring_class) +{ + if ((ce->ce_flags & ZEND_ACC_RESOLVED_PARENT) && ce->parent && ce->parent != ancestor) { + const zend_type *parent_args; + uint32_t parent_arity; + if (reflection_get_direct_inheritance_binding(ce, ce->parent, &parent_args, &parent_arity)) { + if (ce_args && parent_arity > 0) { + ALLOCA_FLAG(use_heap) + zend_type *mapped = (zend_type *) do_alloca(sizeof(zend_type) * parent_arity, use_heap); + for (uint32_t i = 0; i < parent_arity; i++) { + mapped[i] = reflection_type_substitute_class_params( + parent_args[i], ce_args, ce_arity); + } + reflection_collect_interface_bindings( + return_value, ce->parent, ancestor, mapped, parent_arity, declaring_class); + reflection_type_array_release(mapped, parent_arity); + free_alloca(mapped, use_heap); + } else { + reflection_collect_interface_bindings( + return_value, ce->parent, ancestor, parent_args, parent_arity, declaring_class); + } + } else { + reflection_collect_interface_bindings( + return_value, ce->parent, ancestor, NULL, 0, declaring_class); + } + } + + HashTable *generic_implements = ce->generic_types ? ce->generic_types->implements : NULL; + if (generic_implements) { + zval *zv; + ZEND_HASH_FOREACH_VAL(generic_implements, zv) { + zend_type *boxed = (zend_type *) Z_PTR_P(zv); + if (!ZEND_TYPE_HAS_NAMED_WITH_ARGS(*boxed)) { + continue; + } + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*boxed); + + if (named->name && zend_string_equals_ci(named->name, ancestor->name)) { + reflection_append_binding(return_value, named->args, named->count, + ce_args, ce_arity, declaring_class); + continue; + } + + zend_class_entry *intermediate = named->name + ? reflection_find_interface_by_name(ce, named->name) : NULL; + if (!intermediate || intermediate == ancestor) { + continue; + } + + if (ce_args && named->count > 0) { + ALLOCA_FLAG(use_heap) + zend_type *mapped = (zend_type *) do_alloca(sizeof(zend_type) * named->count, use_heap); + for (uint32_t i = 0; i < named->count; i++) { + mapped[i] = reflection_type_substitute_class_params( + named->args[i], ce_args, ce_arity); + } + reflection_collect_interface_bindings( + return_value, intermediate, ancestor, mapped, named->count, declaring_class); + reflection_type_array_release(mapped, named->count); + free_alloca(mapped, use_heap); + } else { + reflection_collect_interface_bindings( + return_value, intermediate, ancestor, named->args, named->count, declaring_class); + } + } ZEND_HASH_FOREACH_END(); + } + + if (ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES) { + uint32_t parent_count = ce->parent ? ce->parent->num_interfaces : 0; + for (uint32_t i = parent_count; i < ce->num_interfaces; i++) { + zend_class_entry *intermediate = ce->interfaces[i]; + if (!intermediate || intermediate == ancestor) { + continue; + } + if (zend_class_is_monomorph(intermediate)) { + continue; + } + if (generic_implements + && zend_hash_index_exists(generic_implements, i - parent_count)) { + continue; + } + + bool is_transitive = false; + for (uint32_t j = parent_count; j < i && !is_transitive; j++) { + zend_class_entry *earlier = ce->interfaces[j]; + if (!earlier) continue; + for (uint32_t k = 0; k < earlier->num_interfaces; k++) { + if (earlier->interfaces[k] == intermediate) { + is_transitive = true; + break; + } + } + } + if (is_transitive) { + continue; + } + + reflection_collect_interface_bindings( + return_value, intermediate, ancestor, NULL, 0, declaring_class); + } + } +} + +ZEND_METHOD(ReflectionClass, getGenericArgumentsForParentClass) +{ + reflection_object *intern; + zend_class_entry *ce; + + ZEND_PARSE_PARAMETERS_NONE(); + GET_REFLECTION_OBJECT_PTR(ce); + + bool has_parent = (ce->ce_flags & ZEND_ACC_LINKED) + ? ce->parent != NULL + : ce->parent_name != NULL; + if (!has_parent) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "Class %s has no parent class", ZSTR_VAL(ce->name)); + RETURN_THROWS(); + } + + if (ce->generic_types && ce->generic_types->extends) { + reflection_build_named_args_list(return_value, ce->generic_types->extends, ce); + return; + } + RETURN_EMPTY_ARRAY(); +} + +static bool reflection_try_build_named_args_from_table(HashTable *ht, zend_class_entry *ce, zend_string *name, zval *return_value) +{ + if (!ht) { + return false; + } + + zval *zv; + ZEND_HASH_FOREACH_VAL(ht, zv) { + zend_type *boxed = (zend_type *) Z_PTR_P(zv); + zend_type_named_with_args *named = ZEND_TYPE_NAMED_WITH_ARGS(*boxed); + if (zend_string_equals_ci(named->name, name)) { + reflection_build_named_args_list(return_value, boxed, ce); + return true; + } + } ZEND_HASH_FOREACH_END(); + return false; +} + +ZEND_METHOD(ReflectionClass, getGenericArgumentsForParentInterface) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_string *name; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(name) + ZEND_PARSE_PARAMETERS_END(); + GET_REFLECTION_OBJECT_PTR(ce); + + bool is_ancestor = false; + zend_class_entry *ancestor = NULL; + if (ce->ce_flags & ZEND_ACC_LINKED) { + for (uint32_t i = 0; i < ce->num_interfaces; i++) { + if (zend_string_equals_ci(ce->interfaces[i]->name, name)) { + is_ancestor = true; + ancestor = ce->interfaces[i]; + break; + } + } + } else { + for (uint32_t i = 0; i < ce->num_interfaces; i++) { + if (zend_string_equals_ci(ce->interface_names[i].name, name)) { + is_ancestor = true; + break; + } + } + } + if (!is_ancestor) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "%s is not an ancestor interface of %s", ZSTR_VAL(name), ZSTR_VAL(ce->name)); + RETURN_THROWS(); + } + + array_init(return_value); + if (ancestor) { + reflection_collect_interface_bindings(return_value, ce, ancestor, NULL, 0, ce); + } +} + +ZEND_METHOD(ReflectionClass, getGenericArgumentsForUsedTrait) +{ + reflection_object *intern; + zend_class_entry *ce; + zend_string *name; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(name) + ZEND_PARSE_PARAMETERS_END(); + GET_REFLECTION_OBJECT_PTR(ce); + + HashTable *ht = ce->generic_types ? ce->generic_types->trait_uses : NULL; + if (reflection_try_build_named_args_from_table(ht, ce, name, return_value)) { + return; + } + + bool is_used = false; + for (uint32_t i = 0; i < ce->num_traits; i++) { + if (zend_string_equals_ci(ce->trait_names[i].name, name)) { + is_used = true; + break; + } + } + if (!is_used) { + zend_throw_exception_ex(reflection_exception_ptr, 0, + "%s is not a trait used by %s", ZSTR_VAL(name), ZSTR_VAL(ce->name)); + RETURN_THROWS(); + } + RETURN_EMPTY_ARRAY(); +} + +PHP_MINIT_FUNCTION(reflection) /* {{{ */ +{ + memcpy(&reflection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + reflection_object_handlers.offset = offsetof(reflection_object, zo); + reflection_object_handlers.free_obj = reflection_free_objects_storage; + reflection_object_handlers.clone_obj = NULL; + reflection_object_handlers.write_property = _reflection_write_property; + reflection_object_handlers.get_gc = reflection_get_gc; + + reflection_exception_ptr = register_class_ReflectionException(zend_ce_exception); + + reflection_ptr = register_class_Reflection(); + + reflector_ptr = register_class_Reflector(zend_ce_stringable); + + reflection_function_abstract_ptr = register_class_ReflectionFunctionAbstract(reflector_ptr); + reflection_function_abstract_ptr->default_object_handlers = &reflection_object_handlers; + reflection_function_abstract_ptr->create_object = reflection_objects_new; + + reflection_function_ptr = register_class_ReflectionFunction(reflection_function_abstract_ptr); + reflection_function_ptr->create_object = reflection_objects_new; + reflection_function_ptr->default_object_handlers = &reflection_object_handlers; + + reflection_generator_ptr = register_class_ReflectionGenerator(); + reflection_generator_ptr->create_object = reflection_objects_new; + reflection_generator_ptr->default_object_handlers = &reflection_object_handlers; + + reflection_parameter_ptr = register_class_ReflectionParameter(reflector_ptr); + reflection_parameter_ptr->create_object = reflection_objects_new; + reflection_parameter_ptr->default_object_handlers = &reflection_object_handlers; + + reflection_type_ptr = register_class_ReflectionType(zend_ce_stringable); + reflection_type_ptr->create_object = reflection_objects_new; + reflection_type_ptr->default_object_handlers = &reflection_object_handlers; + + reflection_named_type_ptr = register_class_ReflectionNamedType(reflection_type_ptr); + reflection_named_type_ptr->create_object = reflection_objects_new; + reflection_named_type_ptr->default_object_handlers = &reflection_object_handlers; + + reflection_union_type_ptr = register_class_ReflectionUnionType(reflection_type_ptr); + reflection_union_type_ptr->create_object = reflection_objects_new; + reflection_union_type_ptr->default_object_handlers = &reflection_object_handlers; reflection_intersection_type_ptr = register_class_ReflectionIntersectionType(reflection_type_ptr); reflection_intersection_type_ptr->create_object = reflection_objects_new; @@ -7943,7 +9301,17 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ reflection_property_hook_type_ptr = register_class_PropertyHookType(); - REFLECTION_G(key_initialized) = 0; + reflection_generic_variance_ptr = register_class_ReflectionGenericVariance(); + + reflection_generic_type_parameter_ptr = register_class_ReflectionGenericTypeParameter(reflector_ptr); + reflection_generic_type_parameter_ptr->create_object = reflection_objects_new; + reflection_generic_type_parameter_ptr->default_object_handlers = &reflection_object_handlers; + + reflection_type_parameter_reference_ptr = register_class_ReflectionTypeParameterReference(reflection_type_ptr); + reflection_type_parameter_reference_ptr->create_object = reflection_objects_new; + reflection_type_parameter_reference_ptr->default_object_handlers = &reflection_object_handlers; + + REFLECTION_G(key_initialized) = false; return SUCCESS; } /* }}} */ diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h index d676597fd0be..ba03f1d9ac2d 100644 --- a/ext/reflection/php_reflection.h +++ b/ext/reflection/php_reflection.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: George Schlossnagle | +----------------------------------------------------------------------+ @@ -18,6 +16,7 @@ #define PHP_REFLECTION_H #include "php.h" +#include "php_reflection_decl.h" extern zend_module_entry reflection_module_entry; #define phpext_reflection_ptr &reflection_module_entry diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index 63518b446ad8..f6f7dacb00ed 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -1,6 +1,9 @@ */ + public function getGenericParameters(): array {} } class ReflectionFunction extends ReflectionFunctionAbstract @@ -226,6 +234,7 @@ public function getPrototype(): ReflectionMethod {} public function hasPrototype(): bool {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.1")] public function setAccessible(bool $accessible): void {} } @@ -432,6 +441,46 @@ public function getNamespaceName(): string {} public function getShortName(): string {} public function getAttributes(?string $name = null, int $flags = 0): array {} + + public function isGeneric(): bool {} + + /** @return list */ + public function getGenericParameters(): array {} + + /** + * Returns the type arguments this class supplies at the parent-class extends + * site, in source order. Returns an empty array if the extends clause + * specified no type arguments. + * + * @return list + * @throws ReflectionException if this class has no parent class + */ + public function getGenericArgumentsForParentClass(): array {} + + /** + * Returns every generic argument set this class supplies for the named + * ancestor interface, in inheritance traversal order. The outer list + * contains one entry per binding: a class may bind the same generic + * interface multiple times either directly (`implements Foo, + * Foo`) or transitively through different inheritance paths. + * Each inner list holds the type arguments for that binding in source + * order. Returns an empty outer list when no generic bindings to the + * ancestor exist. + * + * @return list> + * @throws ReflectionException if $name is not an ancestor interface + */ + public function getGenericArgumentsForParentInterface(string $name): array {} + + /** + * Returns the type arguments this class supplies at the use site for trait + * $name, in source order. Returns an empty array if no type arguments were + * specified at the use site. + * + * @return list + * @throws ReflectionException if $name is not a directly-used trait + */ + public function getGenericArgumentsForUsedTrait(string $name): array {} } class ReflectionObject extends ReflectionClass @@ -482,6 +531,8 @@ public function __toString(): string {} /** @tentative-return-type */ public function getName(): string {} + public function getMangledName(): string {} + /** @tentative-return-type */ public function getValue(?object $object = null): mixed {} @@ -540,6 +591,7 @@ public function getDeclaringClass(): ReflectionClass {} public function getDocComment(): string|false {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.1")] public function setAccessible(bool $accessible): void {} /** @tentative-return-type */ @@ -567,6 +619,10 @@ public function hasHook(PropertyHookType $type): bool {} public function getHook(PropertyHookType $type): ?ReflectionMethod {} public function isFinal(): bool {} + + public function isReadable(?string $scope, ?object $object = null): bool {} + + public function isWritable(?string $scope, ?object $object = null): bool {} } /** @not-serializable */ @@ -641,6 +697,8 @@ public function __construct($function, int|string $param) {} public function __toString(): string {} + public function getDocComment(): string|false {} + /** @tentative-return-type */ public function getName(): string {} @@ -728,6 +786,11 @@ public function getName(): string {} /** @tentative-return-type */ public function isBuiltin(): bool {} + + public function hasGenericArguments(): bool {} + + /** @return list */ + public function getGenericArguments(): array {} } class ReflectionUnionType extends ReflectionType @@ -740,6 +803,66 @@ class ReflectionIntersectionType extends ReflectionType public function getTypes(): array {} } +/** + * @strict-properties + * @not-serializable + */ +final class ReflectionTypeParameterReference extends ReflectionType +{ + public string $name; + + private function __construct() {} + + public function getName(): string {} + + public function getTypeParameter(): ReflectionGenericTypeParameter {} + + public function allowsNull(): bool {} + + public function __toString(): string {} +} + +enum ReflectionGenericVariance +{ + case Invariant; + case Covariant; + case Contravariant; +} + +/** + * @strict-properties + * @not-serializable + */ +final class ReflectionGenericTypeParameter implements Reflector +{ + public string $name; + + private function __construct() {} + + /** @implementation-alias ReflectionClass::__clone */ + private function __clone(): void {} + + public function getName(): string {} + + public function getPosition(): int {} + + public function getVariance(): ReflectionGenericVariance {} + + public function hasBound(): bool {} + + /** @throws ReflectionException if this type parameter has no bound; check hasBound() first */ + public function getBound(): ReflectionType {} + + public function hasDefault(): bool {} + + /** @throws ReflectionException if this type parameter has no default; check hasDefault() first */ + public function getDefault(): ReflectionType {} + + public function getDeclaringEntity(): ReflectionClass|ReflectionFunctionAbstract {} + + public function __toString(): string {} +} + /** @not-serializable */ class ReflectionExtension implements Reflector { @@ -900,7 +1023,7 @@ public function getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT): array { * @strict-properties * @not-serializable */ -final class ReflectionConstant implements Reflector +class ReflectionConstant implements Reflector { public string $name; @@ -908,6 +1031,8 @@ public function __construct(string $name) {} public function getName(): string {} + public function inNamespace(): bool {} + public function getNamespaceName(): string {} public function getShortName(): string {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index d50dc04ae3d1..2f73dbda3866 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,6 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7a8d126a96f0115783bd20a9adfc6bdc5ee88fda */ +/* This is a generated file, edit php_reflection.stub.php instead. + * Stub hash: e21013562d5d9f87a8707afdf579f799a858dba3 + * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -86,6 +87,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionFunctionAbstract ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionFunctionAbstract_isGeneric arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionFunctionAbstract_getGenericParameters arginfo_class_ReflectionFunctionAbstract_getClosureUsedVariables + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionFunction___construct, 0, 0, 1) ZEND_ARG_OBJ_TYPE_MASK(0, function, Closure, MAY_BE_STRING, NULL) ZEND_END_ARG_INFO() @@ -366,6 +371,18 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionClass_getAttributes arginfo_class_ReflectionFunctionAbstract_getAttributes +#define arginfo_class_ReflectionClass_isGeneric arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionClass_getGenericParameters arginfo_class_ReflectionFunctionAbstract_getClosureUsedVariables + +#define arginfo_class_ReflectionClass_getGenericArgumentsForParentClass arginfo_class_ReflectionFunctionAbstract_getClosureUsedVariables + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_getGenericArgumentsForParentInterface, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionClass_getGenericArgumentsForUsedTrait arginfo_class_ReflectionClass_getGenericArgumentsForParentInterface + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionObject___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0) ZEND_END_ARG_INFO() @@ -381,6 +398,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty_getName arginfo_class_ReflectionFunctionAbstract_getName +#define arginfo_class_ReflectionProperty_getMangledName arginfo_class_ReflectionFunction___toString + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_getValue, 0, 0, IS_MIXED, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, object, IS_OBJECT, 1, "null") ZEND_END_ARG_INFO() @@ -470,6 +489,13 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty_isFinal arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_isReadable, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, scope, IS_STRING, 1) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, object, IS_OBJECT, 1, "null") +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionProperty_isWritable arginfo_class_ReflectionProperty_isReadable + #define arginfo_class_ReflectionClassConstant___clone arginfo_class_ReflectionFunctionAbstract___clone ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionClassConstant___construct, 0, 0, 2) @@ -516,6 +542,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionParameter___toString arginfo_class_ReflectionFunction___toString +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ReflectionParameter_getDocComment, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) +ZEND_END_ARG_INFO() + #define arginfo_class_ReflectionParameter_getName arginfo_class_ReflectionFunctionAbstract_getName #define arginfo_class_ReflectionParameter_isPassedByReference arginfo_class_ReflectionFunctionAbstract_inNamespace @@ -568,10 +597,51 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionNamedType_isBuiltin arginfo_class_ReflectionFunctionAbstract_inNamespace +#define arginfo_class_ReflectionNamedType_hasGenericArguments arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionNamedType_getGenericArguments arginfo_class_ReflectionFunctionAbstract_getClosureUsedVariables + #define arginfo_class_ReflectionUnionType_getTypes arginfo_class_ReflectionFunctionAbstract_getClosureUsedVariables #define arginfo_class_ReflectionIntersectionType_getTypes arginfo_class_ReflectionFunctionAbstract_getClosureUsedVariables +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionTypeParameterReference___construct, 0, 0, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionTypeParameterReference_getName arginfo_class_ReflectionFunction___toString + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionTypeParameterReference_getTypeParameter, 0, 0, ReflectionGenericTypeParameter, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionTypeParameterReference_allowsNull arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionTypeParameterReference___toString arginfo_class_ReflectionFunction___toString + +#define arginfo_class_ReflectionGenericTypeParameter___construct arginfo_class_ReflectionTypeParameterReference___construct + +#define arginfo_class_ReflectionGenericTypeParameter___clone arginfo_class_ReflectionFunctionAbstract___clone + +#define arginfo_class_ReflectionGenericTypeParameter_getName arginfo_class_ReflectionFunction___toString + +#define arginfo_class_ReflectionGenericTypeParameter_getPosition arginfo_class_ReflectionGenerator_getExecutingLine + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionGenericTypeParameter_getVariance, 0, 0, ReflectionGenericVariance, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionGenericTypeParameter_hasBound arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionGenericTypeParameter_getBound, 0, 0, ReflectionType, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionGenericTypeParameter_hasDefault arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + +#define arginfo_class_ReflectionGenericTypeParameter_getDefault arginfo_class_ReflectionGenericTypeParameter_getBound + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_ReflectionGenericTypeParameter_getDeclaringEntity, 0, 0, ReflectionClass|ReflectionFunctionAbstract, 0) +ZEND_END_ARG_INFO() + +#define arginfo_class_ReflectionGenericTypeParameter___toString arginfo_class_ReflectionFunction___toString + #define arginfo_class_ReflectionExtension___clone arginfo_class_ReflectionFunctionAbstract___clone ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionExtension___construct, 0, 0, 1) @@ -628,8 +698,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionReference___clone arginfo_class_ReflectionFunctionAbstract___clone -ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionReference___construct, 0, 0, 0) -ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionReference___construct arginfo_class_ReflectionTypeParameterReference___construct #define arginfo_class_ReflectionAttribute_getName arginfo_class_ReflectionFunction___toString @@ -646,7 +715,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionAttribute___clone arginfo_class_ReflectionFunctionAbstract___clone -#define arginfo_class_ReflectionAttribute___construct arginfo_class_ReflectionReference___construct +#define arginfo_class_ReflectionAttribute___construct arginfo_class_ReflectionTypeParameterReference___construct #define arginfo_class_ReflectionEnum___construct arginfo_class_ReflectionClass___construct @@ -700,6 +769,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionConstant_getName arginfo_class_ReflectionFunction___toString +#define arginfo_class_ReflectionConstant_inNamespace arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType + #define arginfo_class_ReflectionConstant_getNamespaceName arginfo_class_ReflectionFunction___toString #define arginfo_class_ReflectionConstant_getShortName arginfo_class_ReflectionFunction___toString @@ -709,13 +780,12 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionConstant_isDeprecated arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ReflectionConstant_getFileName, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) -ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionConstant_getFileName arginfo_class_ReflectionParameter_getDocComment ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionConstant_getExtension, 0, 0, ReflectionExtension, 1) ZEND_END_ARG_INFO() -#define arginfo_class_ReflectionConstant_getExtensionName arginfo_class_ReflectionConstant_getFileName +#define arginfo_class_ReflectionConstant_getExtensionName arginfo_class_ReflectionParameter_getDocComment #define arginfo_class_ReflectionConstant___toString arginfo_class_ReflectionFunction___toString @@ -754,6 +824,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getReturnType); ZEND_METHOD(ReflectionFunctionAbstract, hasTentativeReturnType); ZEND_METHOD(ReflectionFunctionAbstract, getTentativeReturnType); ZEND_METHOD(ReflectionFunctionAbstract, getAttributes); +ZEND_METHOD(ReflectionFunctionAbstract, isGeneric); +ZEND_METHOD(ReflectionFunctionAbstract, getGenericParameters); ZEND_METHOD(ReflectionFunction, __construct); ZEND_METHOD(ReflectionFunction, __toString); ZEND_METHOD(ReflectionFunction, isAnonymous); @@ -849,10 +921,16 @@ ZEND_METHOD(ReflectionClass, inNamespace); ZEND_METHOD(ReflectionClass, getNamespaceName); ZEND_METHOD(ReflectionClass, getShortName); ZEND_METHOD(ReflectionClass, getAttributes); +ZEND_METHOD(ReflectionClass, isGeneric); +ZEND_METHOD(ReflectionClass, getGenericParameters); +ZEND_METHOD(ReflectionClass, getGenericArgumentsForParentClass); +ZEND_METHOD(ReflectionClass, getGenericArgumentsForParentInterface); +ZEND_METHOD(ReflectionClass, getGenericArgumentsForUsedTrait); ZEND_METHOD(ReflectionObject, __construct); ZEND_METHOD(ReflectionProperty, __construct); ZEND_METHOD(ReflectionProperty, __toString); ZEND_METHOD(ReflectionProperty, getName); +ZEND_METHOD(ReflectionProperty, getMangledName); ZEND_METHOD(ReflectionProperty, getValue); ZEND_METHOD(ReflectionProperty, setValue); ZEND_METHOD(ReflectionProperty, getRawValue); @@ -888,6 +966,8 @@ ZEND_METHOD(ReflectionProperty, getHooks); ZEND_METHOD(ReflectionProperty, hasHook); ZEND_METHOD(ReflectionProperty, getHook); ZEND_METHOD(ReflectionProperty, isFinal); +ZEND_METHOD(ReflectionProperty, isReadable); +ZEND_METHOD(ReflectionProperty, isWritable); ZEND_METHOD(ReflectionClassConstant, __construct); ZEND_METHOD(ReflectionClassConstant, __toString); ZEND_METHOD(ReflectionClassConstant, getName); @@ -906,6 +986,7 @@ ZEND_METHOD(ReflectionClassConstant, hasType); ZEND_METHOD(ReflectionClassConstant, getType); ZEND_METHOD(ReflectionParameter, __construct); ZEND_METHOD(ReflectionParameter, __toString); +ZEND_METHOD(ReflectionParameter, getDocComment); ZEND_METHOD(ReflectionParameter, getName); ZEND_METHOD(ReflectionParameter, isPassedByReference); ZEND_METHOD(ReflectionParameter, canBePassedByValue); @@ -930,8 +1011,25 @@ ZEND_METHOD(ReflectionType, allowsNull); ZEND_METHOD(ReflectionType, __toString); ZEND_METHOD(ReflectionNamedType, getName); ZEND_METHOD(ReflectionNamedType, isBuiltin); +ZEND_METHOD(ReflectionNamedType, hasGenericArguments); +ZEND_METHOD(ReflectionNamedType, getGenericArguments); ZEND_METHOD(ReflectionUnionType, getTypes); ZEND_METHOD(ReflectionIntersectionType, getTypes); +ZEND_METHOD(ReflectionTypeParameterReference, __construct); +ZEND_METHOD(ReflectionTypeParameterReference, getName); +ZEND_METHOD(ReflectionTypeParameterReference, getTypeParameter); +ZEND_METHOD(ReflectionTypeParameterReference, allowsNull); +ZEND_METHOD(ReflectionTypeParameterReference, __toString); +ZEND_METHOD(ReflectionGenericTypeParameter, __construct); +ZEND_METHOD(ReflectionGenericTypeParameter, getName); +ZEND_METHOD(ReflectionGenericTypeParameter, getPosition); +ZEND_METHOD(ReflectionGenericTypeParameter, getVariance); +ZEND_METHOD(ReflectionGenericTypeParameter, hasBound); +ZEND_METHOD(ReflectionGenericTypeParameter, getBound); +ZEND_METHOD(ReflectionGenericTypeParameter, hasDefault); +ZEND_METHOD(ReflectionGenericTypeParameter, getDefault); +ZEND_METHOD(ReflectionGenericTypeParameter, getDeclaringEntity); +ZEND_METHOD(ReflectionGenericTypeParameter, __toString); ZEND_METHOD(ReflectionExtension, __construct); ZEND_METHOD(ReflectionExtension, __toString); ZEND_METHOD(ReflectionExtension, getName); @@ -981,6 +1079,7 @@ ZEND_METHOD(ReflectionFiber, getCallable); ZEND_METHOD(ReflectionFiber, getTrace); ZEND_METHOD(ReflectionConstant, __construct); ZEND_METHOD(ReflectionConstant, getName); +ZEND_METHOD(ReflectionConstant, inNamespace); ZEND_METHOD(ReflectionConstant, getNamespaceName); ZEND_METHOD(ReflectionConstant, getShortName); ZEND_METHOD(ReflectionConstant, getValue); @@ -1029,6 +1128,8 @@ static const zend_function_entry class_ReflectionFunctionAbstract_methods[] = { ZEND_ME(ReflectionFunctionAbstract, hasTentativeReturnType, arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionFunctionAbstract, getTentativeReturnType, arginfo_class_ReflectionFunctionAbstract_getTentativeReturnType, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionFunctionAbstract, getAttributes, arginfo_class_ReflectionFunctionAbstract_getAttributes, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionFunctionAbstract, isGeneric, arginfo_class_ReflectionFunctionAbstract_isGeneric, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionFunctionAbstract, getGenericParameters, arginfo_class_ReflectionFunctionAbstract_getGenericParameters, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -1073,7 +1174,7 @@ static const zend_function_entry class_ReflectionMethod_methods[] = { ZEND_ME(ReflectionMethod, getDeclaringClass, arginfo_class_ReflectionMethod_getDeclaringClass, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, getPrototype, arginfo_class_ReflectionMethod_getPrototype, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionMethod, hasPrototype, arginfo_class_ReflectionMethod_hasPrototype, ZEND_ACC_PUBLIC) - ZEND_ME(ReflectionMethod, setAccessible, arginfo_class_ReflectionMethod_setAccessible, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionMethod, setAccessible, arginfo_class_ReflectionMethod_setAccessible, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) ZEND_FE_END }; @@ -1142,6 +1243,11 @@ static const zend_function_entry class_ReflectionClass_methods[] = { ZEND_ME(ReflectionClass, getNamespaceName, arginfo_class_ReflectionClass_getNamespaceName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getShortName, arginfo_class_ReflectionClass_getShortName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionClass, getAttributes, arginfo_class_ReflectionClass_getAttributes, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, isGeneric, arginfo_class_ReflectionClass_isGeneric, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getGenericParameters, arginfo_class_ReflectionClass_getGenericParameters, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getGenericArgumentsForParentClass, arginfo_class_ReflectionClass_getGenericArgumentsForParentClass, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getGenericArgumentsForParentInterface, arginfo_class_ReflectionClass_getGenericArgumentsForParentInterface, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionClass, getGenericArgumentsForUsedTrait, arginfo_class_ReflectionClass_getGenericArgumentsForUsedTrait, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -1155,6 +1261,7 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, __construct, arginfo_class_ReflectionProperty___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, __toString, arginfo_class_ReflectionProperty___toString, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getName, arginfo_class_ReflectionProperty_getName, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, getMangledName, arginfo_class_ReflectionProperty_getMangledName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getValue, arginfo_class_ReflectionProperty_getValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, setValue, arginfo_class_ReflectionProperty_setValue, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getRawValue, arginfo_class_ReflectionProperty_getRawValue, ZEND_ACC_PUBLIC) @@ -1178,7 +1285,7 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, getModifiers, arginfo_class_ReflectionProperty_getModifiers, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getDeclaringClass, arginfo_class_ReflectionProperty_getDeclaringClass, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getDocComment, arginfo_class_ReflectionProperty_getDocComment, ZEND_ACC_PUBLIC) - ZEND_ME(ReflectionProperty, setAccessible, arginfo_class_ReflectionProperty_setAccessible, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, setAccessible, arginfo_class_ReflectionProperty_setAccessible, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) ZEND_ME(ReflectionProperty, getType, arginfo_class_ReflectionProperty_getType, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getSettableType, arginfo_class_ReflectionProperty_getSettableType, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, hasType, arginfo_class_ReflectionProperty_hasType, ZEND_ACC_PUBLIC) @@ -1190,6 +1297,8 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, hasHook, arginfo_class_ReflectionProperty_hasHook, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getHook, arginfo_class_ReflectionProperty_getHook, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isFinal, arginfo_class_ReflectionProperty_isFinal, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, isReadable, arginfo_class_ReflectionProperty_isReadable, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, isWritable, arginfo_class_ReflectionProperty_isWritable, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -1218,6 +1327,7 @@ static const zend_function_entry class_ReflectionParameter_methods[] = { ZEND_RAW_FENTRY("__clone", zim_ReflectionClass___clone, arginfo_class_ReflectionParameter___clone, ZEND_ACC_PRIVATE, NULL, NULL) ZEND_ME(ReflectionParameter, __construct, arginfo_class_ReflectionParameter___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, __toString, arginfo_class_ReflectionParameter___toString, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionParameter, getDocComment, arginfo_class_ReflectionParameter_getDocComment, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, getName, arginfo_class_ReflectionParameter_getName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, isPassedByReference, arginfo_class_ReflectionParameter_isPassedByReference, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, canBePassedByValue, arginfo_class_ReflectionParameter_canBePassedByValue, ZEND_ACC_PUBLIC) @@ -1251,6 +1361,8 @@ static const zend_function_entry class_ReflectionType_methods[] = { static const zend_function_entry class_ReflectionNamedType_methods[] = { ZEND_ME(ReflectionNamedType, getName, arginfo_class_ReflectionNamedType_getName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionNamedType, isBuiltin, arginfo_class_ReflectionNamedType_isBuiltin, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionNamedType, hasGenericArguments, arginfo_class_ReflectionNamedType_hasGenericArguments, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionNamedType, getGenericArguments, arginfo_class_ReflectionNamedType_getGenericArguments, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -1264,6 +1376,30 @@ static const zend_function_entry class_ReflectionIntersectionType_methods[] = { ZEND_FE_END }; +static const zend_function_entry class_ReflectionTypeParameterReference_methods[] = { + ZEND_ME(ReflectionTypeParameterReference, __construct, arginfo_class_ReflectionTypeParameterReference___construct, ZEND_ACC_PRIVATE) + ZEND_ME(ReflectionTypeParameterReference, getName, arginfo_class_ReflectionTypeParameterReference_getName, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionTypeParameterReference, getTypeParameter, arginfo_class_ReflectionTypeParameterReference_getTypeParameter, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionTypeParameterReference, allowsNull, arginfo_class_ReflectionTypeParameterReference_allowsNull, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionTypeParameterReference, __toString, arginfo_class_ReflectionTypeParameterReference___toString, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static const zend_function_entry class_ReflectionGenericTypeParameter_methods[] = { + ZEND_ME(ReflectionGenericTypeParameter, __construct, arginfo_class_ReflectionGenericTypeParameter___construct, ZEND_ACC_PRIVATE) + ZEND_RAW_FENTRY("__clone", zim_ReflectionClass___clone, arginfo_class_ReflectionGenericTypeParameter___clone, ZEND_ACC_PRIVATE, NULL, NULL) + ZEND_ME(ReflectionGenericTypeParameter, getName, arginfo_class_ReflectionGenericTypeParameter_getName, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, getPosition, arginfo_class_ReflectionGenericTypeParameter_getPosition, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, getVariance, arginfo_class_ReflectionGenericTypeParameter_getVariance, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, hasBound, arginfo_class_ReflectionGenericTypeParameter_hasBound, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, getBound, arginfo_class_ReflectionGenericTypeParameter_getBound, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, hasDefault, arginfo_class_ReflectionGenericTypeParameter_hasDefault, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, getDefault, arginfo_class_ReflectionGenericTypeParameter_getDefault, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, getDeclaringEntity, arginfo_class_ReflectionGenericTypeParameter_getDeclaringEntity, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionGenericTypeParameter, __toString, arginfo_class_ReflectionGenericTypeParameter___toString, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + static const zend_function_entry class_ReflectionExtension_methods[] = { ZEND_RAW_FENTRY("__clone", zim_ReflectionClass___clone, arginfo_class_ReflectionExtension___clone, ZEND_ACC_PRIVATE, NULL, NULL) ZEND_ME(ReflectionExtension, __construct, arginfo_class_ReflectionExtension___construct, ZEND_ACC_PUBLIC) @@ -1350,6 +1486,7 @@ static const zend_function_entry class_ReflectionFiber_methods[] = { static const zend_function_entry class_ReflectionConstant_methods[] = { ZEND_ME(ReflectionConstant, __construct, arginfo_class_ReflectionConstant___construct, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionConstant, getName, arginfo_class_ReflectionConstant_getName, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionConstant, inNamespace, arginfo_class_ReflectionConstant_inNamespace, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionConstant, getNamespaceName, arginfo_class_ReflectionConstant_getNamespaceName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionConstant, getShortName, arginfo_class_ReflectionConstant_getShortName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionConstant, getValue, arginfo_class_ReflectionConstant_getValue, ZEND_ACC_PUBLIC) @@ -1417,21 +1554,16 @@ static zend_class_entry *register_class_ReflectionFunction(zend_class_entry *cla zval const_IS_DEPRECATED_value; ZVAL_LONG(&const_IS_DEPRECATED_value, ZEND_ACC_DEPRECATED); - zend_string *const_IS_DEPRECATED_name = zend_string_init_interned("IS_DEPRECATED", sizeof("IS_DEPRECATED") - 1, 1); + zend_string *const_IS_DEPRECATED_name = zend_string_init_interned("IS_DEPRECATED", sizeof("IS_DEPRECATED") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_DEPRECATED_name, &const_IS_DEPRECATED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_DEPRECATED_name); + zend_string_release_ex(const_IS_DEPRECATED_name, true); zend_attribute *attribute_Deprecated_func_isdisabled_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "isdisabled", sizeof("isdisabled") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_isdisabled_0_arg0; - zend_string *attribute_Deprecated_func_isdisabled_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_isdisabled_0_arg0, attribute_Deprecated_func_isdisabled_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_isdisabled_0->args[0].value, &attribute_Deprecated_func_isdisabled_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_isdisabled_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_isdisabled_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_isdisabled_0_arg1; zend_string *attribute_Deprecated_func_isdisabled_0_arg1_str = zend_string_init("as ReflectionFunction can no longer be constructed for disabled functions", strlen("as ReflectionFunction can no longer be constructed for disabled functions"), 1); - ZVAL_STR(&attribute_Deprecated_func_isdisabled_0_arg1, attribute_Deprecated_func_isdisabled_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_isdisabled_0->args[1].value, &attribute_Deprecated_func_isdisabled_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_isdisabled_0->args[1].value, attribute_Deprecated_func_isdisabled_0_arg1_str); attribute_Deprecated_func_isdisabled_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; @@ -1456,44 +1588,52 @@ static zend_class_entry *register_class_ReflectionMethod(zend_class_entry *class zval const_IS_STATIC_value; ZVAL_LONG(&const_IS_STATIC_value, ZEND_ACC_STATIC); - zend_string *const_IS_STATIC_name = zend_string_init_interned("IS_STATIC", sizeof("IS_STATIC") - 1, 1); + zend_string *const_IS_STATIC_name = zend_string_init_interned("IS_STATIC", sizeof("IS_STATIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_STATIC_name, &const_IS_STATIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_STATIC_name); + zend_string_release_ex(const_IS_STATIC_name, true); zval const_IS_PUBLIC_value; ZVAL_LONG(&const_IS_PUBLIC_value, ZEND_ACC_PUBLIC); - zend_string *const_IS_PUBLIC_name = zend_string_init_interned("IS_PUBLIC", sizeof("IS_PUBLIC") - 1, 1); + zend_string *const_IS_PUBLIC_name = zend_string_init_interned("IS_PUBLIC", sizeof("IS_PUBLIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PUBLIC_name, &const_IS_PUBLIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PUBLIC_name); + zend_string_release_ex(const_IS_PUBLIC_name, true); zval const_IS_PROTECTED_value; ZVAL_LONG(&const_IS_PROTECTED_value, ZEND_ACC_PROTECTED); - zend_string *const_IS_PROTECTED_name = zend_string_init_interned("IS_PROTECTED", sizeof("IS_PROTECTED") - 1, 1); + zend_string *const_IS_PROTECTED_name = zend_string_init_interned("IS_PROTECTED", sizeof("IS_PROTECTED") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PROTECTED_name, &const_IS_PROTECTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PROTECTED_name); + zend_string_release_ex(const_IS_PROTECTED_name, true); zval const_IS_PRIVATE_value; ZVAL_LONG(&const_IS_PRIVATE_value, ZEND_ACC_PRIVATE); - zend_string *const_IS_PRIVATE_name = zend_string_init_interned("IS_PRIVATE", sizeof("IS_PRIVATE") - 1, 1); + zend_string *const_IS_PRIVATE_name = zend_string_init_interned("IS_PRIVATE", sizeof("IS_PRIVATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PRIVATE_name, &const_IS_PRIVATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PRIVATE_name); + zend_string_release_ex(const_IS_PRIVATE_name, true); zval const_IS_ABSTRACT_value; ZVAL_LONG(&const_IS_ABSTRACT_value, ZEND_ACC_ABSTRACT); - zend_string *const_IS_ABSTRACT_name = zend_string_init_interned("IS_ABSTRACT", sizeof("IS_ABSTRACT") - 1, 1); + zend_string *const_IS_ABSTRACT_name = zend_string_init_interned("IS_ABSTRACT", sizeof("IS_ABSTRACT") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_ABSTRACT_name, &const_IS_ABSTRACT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_ABSTRACT_name); + zend_string_release_ex(const_IS_ABSTRACT_name, true); zval const_IS_FINAL_value; ZVAL_LONG(&const_IS_FINAL_value, ZEND_ACC_FINAL); - zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, 1); + zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_FINAL_name, &const_IS_FINAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_FINAL_name); + zend_string_release_ex(const_IS_FINAL_name, true); zval property_class_default_value; ZVAL_UNDEF(&property_class_default_value); zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_CLASS), &property_class_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + zend_attribute *attribute_Deprecated_func_setaccessible_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setaccessible", sizeof("setaccessible") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_setaccessible_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_setaccessible_0_arg1_str = zend_string_init("as it has no effect since PHP 8.1", strlen("as it has no effect since PHP 8.1"), 1); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[1].value, attribute_Deprecated_func_setaccessible_0_arg1_str); + attribute_Deprecated_func_setaccessible_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + return class_entry; } @@ -1507,39 +1647,39 @@ static zend_class_entry *register_class_ReflectionClass(zend_class_entry *class_ zval const_IS_IMPLICIT_ABSTRACT_value; ZVAL_LONG(&const_IS_IMPLICIT_ABSTRACT_value, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS); - zend_string *const_IS_IMPLICIT_ABSTRACT_name = zend_string_init_interned("IS_IMPLICIT_ABSTRACT", sizeof("IS_IMPLICIT_ABSTRACT") - 1, 1); + zend_string *const_IS_IMPLICIT_ABSTRACT_name = zend_string_init_interned("IS_IMPLICIT_ABSTRACT", sizeof("IS_IMPLICIT_ABSTRACT") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_IMPLICIT_ABSTRACT_name, &const_IS_IMPLICIT_ABSTRACT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_IMPLICIT_ABSTRACT_name); + zend_string_release_ex(const_IS_IMPLICIT_ABSTRACT_name, true); zval const_IS_EXPLICIT_ABSTRACT_value; ZVAL_LONG(&const_IS_EXPLICIT_ABSTRACT_value, ZEND_ACC_EXPLICIT_ABSTRACT_CLASS); - zend_string *const_IS_EXPLICIT_ABSTRACT_name = zend_string_init_interned("IS_EXPLICIT_ABSTRACT", sizeof("IS_EXPLICIT_ABSTRACT") - 1, 1); + zend_string *const_IS_EXPLICIT_ABSTRACT_name = zend_string_init_interned("IS_EXPLICIT_ABSTRACT", sizeof("IS_EXPLICIT_ABSTRACT") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_EXPLICIT_ABSTRACT_name, &const_IS_EXPLICIT_ABSTRACT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_EXPLICIT_ABSTRACT_name); + zend_string_release_ex(const_IS_EXPLICIT_ABSTRACT_name, true); zval const_IS_FINAL_value; ZVAL_LONG(&const_IS_FINAL_value, ZEND_ACC_FINAL); - zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, 1); + zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_FINAL_name, &const_IS_FINAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_FINAL_name); + zend_string_release_ex(const_IS_FINAL_name, true); zval const_IS_READONLY_value; ZVAL_LONG(&const_IS_READONLY_value, ZEND_ACC_READONLY_CLASS); - zend_string *const_IS_READONLY_name = zend_string_init_interned("IS_READONLY", sizeof("IS_READONLY") - 1, 1); + zend_string *const_IS_READONLY_name = zend_string_init_interned("IS_READONLY", sizeof("IS_READONLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_READONLY_name, &const_IS_READONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_READONLY_name); + zend_string_release_ex(const_IS_READONLY_name, true); zval const_SKIP_INITIALIZATION_ON_SERIALIZE_value; ZVAL_LONG(&const_SKIP_INITIALIZATION_ON_SERIALIZE_value, ZEND_LAZY_OBJECT_SKIP_INITIALIZATION_ON_SERIALIZE); - zend_string *const_SKIP_INITIALIZATION_ON_SERIALIZE_name = zend_string_init_interned("SKIP_INITIALIZATION_ON_SERIALIZE", sizeof("SKIP_INITIALIZATION_ON_SERIALIZE") - 1, 1); + zend_string *const_SKIP_INITIALIZATION_ON_SERIALIZE_name = zend_string_init_interned("SKIP_INITIALIZATION_ON_SERIALIZE", sizeof("SKIP_INITIALIZATION_ON_SERIALIZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_SKIP_INITIALIZATION_ON_SERIALIZE_name, &const_SKIP_INITIALIZATION_ON_SERIALIZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SKIP_INITIALIZATION_ON_SERIALIZE_name); + zend_string_release_ex(const_SKIP_INITIALIZATION_ON_SERIALIZE_name, true); zval const_SKIP_DESTRUCTOR_value; ZVAL_LONG(&const_SKIP_DESTRUCTOR_value, ZEND_LAZY_OBJECT_SKIP_DESTRUCTOR); - zend_string *const_SKIP_DESTRUCTOR_name = zend_string_init_interned("SKIP_DESTRUCTOR", sizeof("SKIP_DESTRUCTOR") - 1, 1); + zend_string *const_SKIP_DESTRUCTOR_name = zend_string_init_interned("SKIP_DESTRUCTOR", sizeof("SKIP_DESTRUCTOR") - 1, true); zend_declare_typed_class_constant(class_entry, const_SKIP_DESTRUCTOR_name, &const_SKIP_DESTRUCTOR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SKIP_DESTRUCTOR_name); + zend_string_release_ex(const_SKIP_DESTRUCTOR_name, true); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); @@ -1585,63 +1725,63 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla zval const_IS_STATIC_value; ZVAL_LONG(&const_IS_STATIC_value, ZEND_ACC_STATIC); - zend_string *const_IS_STATIC_name = zend_string_init_interned("IS_STATIC", sizeof("IS_STATIC") - 1, 1); + zend_string *const_IS_STATIC_name = zend_string_init_interned("IS_STATIC", sizeof("IS_STATIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_STATIC_name, &const_IS_STATIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_STATIC_name); + zend_string_release_ex(const_IS_STATIC_name, true); zval const_IS_READONLY_value; ZVAL_LONG(&const_IS_READONLY_value, ZEND_ACC_READONLY); - zend_string *const_IS_READONLY_name = zend_string_init_interned("IS_READONLY", sizeof("IS_READONLY") - 1, 1); + zend_string *const_IS_READONLY_name = zend_string_init_interned("IS_READONLY", sizeof("IS_READONLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_READONLY_name, &const_IS_READONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_READONLY_name); + zend_string_release_ex(const_IS_READONLY_name, true); zval const_IS_PUBLIC_value; ZVAL_LONG(&const_IS_PUBLIC_value, ZEND_ACC_PUBLIC); - zend_string *const_IS_PUBLIC_name = zend_string_init_interned("IS_PUBLIC", sizeof("IS_PUBLIC") - 1, 1); + zend_string *const_IS_PUBLIC_name = zend_string_init_interned("IS_PUBLIC", sizeof("IS_PUBLIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PUBLIC_name, &const_IS_PUBLIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PUBLIC_name); + zend_string_release_ex(const_IS_PUBLIC_name, true); zval const_IS_PROTECTED_value; ZVAL_LONG(&const_IS_PROTECTED_value, ZEND_ACC_PROTECTED); - zend_string *const_IS_PROTECTED_name = zend_string_init_interned("IS_PROTECTED", sizeof("IS_PROTECTED") - 1, 1); + zend_string *const_IS_PROTECTED_name = zend_string_init_interned("IS_PROTECTED", sizeof("IS_PROTECTED") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PROTECTED_name, &const_IS_PROTECTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PROTECTED_name); + zend_string_release_ex(const_IS_PROTECTED_name, true); zval const_IS_PRIVATE_value; ZVAL_LONG(&const_IS_PRIVATE_value, ZEND_ACC_PRIVATE); - zend_string *const_IS_PRIVATE_name = zend_string_init_interned("IS_PRIVATE", sizeof("IS_PRIVATE") - 1, 1); + zend_string *const_IS_PRIVATE_name = zend_string_init_interned("IS_PRIVATE", sizeof("IS_PRIVATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PRIVATE_name, &const_IS_PRIVATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PRIVATE_name); + zend_string_release_ex(const_IS_PRIVATE_name, true); zval const_IS_ABSTRACT_value; ZVAL_LONG(&const_IS_ABSTRACT_value, ZEND_ACC_ABSTRACT); - zend_string *const_IS_ABSTRACT_name = zend_string_init_interned("IS_ABSTRACT", sizeof("IS_ABSTRACT") - 1, 1); + zend_string *const_IS_ABSTRACT_name = zend_string_init_interned("IS_ABSTRACT", sizeof("IS_ABSTRACT") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_ABSTRACT_name, &const_IS_ABSTRACT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_ABSTRACT_name); + zend_string_release_ex(const_IS_ABSTRACT_name, true); zval const_IS_PROTECTED_SET_value; ZVAL_LONG(&const_IS_PROTECTED_SET_value, ZEND_ACC_PROTECTED_SET); - zend_string *const_IS_PROTECTED_SET_name = zend_string_init_interned("IS_PROTECTED_SET", sizeof("IS_PROTECTED_SET") - 1, 1); + zend_string *const_IS_PROTECTED_SET_name = zend_string_init_interned("IS_PROTECTED_SET", sizeof("IS_PROTECTED_SET") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PROTECTED_SET_name, &const_IS_PROTECTED_SET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PROTECTED_SET_name); + zend_string_release_ex(const_IS_PROTECTED_SET_name, true); zval const_IS_PRIVATE_SET_value; ZVAL_LONG(&const_IS_PRIVATE_SET_value, ZEND_ACC_PRIVATE_SET); - zend_string *const_IS_PRIVATE_SET_name = zend_string_init_interned("IS_PRIVATE_SET", sizeof("IS_PRIVATE_SET") - 1, 1); + zend_string *const_IS_PRIVATE_SET_name = zend_string_init_interned("IS_PRIVATE_SET", sizeof("IS_PRIVATE_SET") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PRIVATE_SET_name, &const_IS_PRIVATE_SET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PRIVATE_SET_name); + zend_string_release_ex(const_IS_PRIVATE_SET_name, true); zval const_IS_VIRTUAL_value; ZVAL_LONG(&const_IS_VIRTUAL_value, ZEND_ACC_VIRTUAL); - zend_string *const_IS_VIRTUAL_name = zend_string_init_interned("IS_VIRTUAL", sizeof("IS_VIRTUAL") - 1, 1); + zend_string *const_IS_VIRTUAL_name = zend_string_init_interned("IS_VIRTUAL", sizeof("IS_VIRTUAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_VIRTUAL_name, &const_IS_VIRTUAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_VIRTUAL_name); + zend_string_release_ex(const_IS_VIRTUAL_name, true); zval const_IS_FINAL_value; ZVAL_LONG(&const_IS_FINAL_value, ZEND_ACC_FINAL); - zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, 1); + zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_FINAL_name, &const_IS_FINAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_FINAL_name); + zend_string_release_ex(const_IS_FINAL_name, true); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); @@ -1651,6 +1791,14 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla ZVAL_UNDEF(&property_class_default_value); zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_CLASS), &property_class_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + zend_attribute *attribute_Deprecated_func_setaccessible_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setaccessible", sizeof("setaccessible") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_setaccessible_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_setaccessible_0_arg1_str = zend_string_init("as it has no effect since PHP 8.1", strlen("as it has no effect since PHP 8.1"), 1); + ZVAL_STR(&attribute_Deprecated_func_setaccessible_0->args[1].value, attribute_Deprecated_func_setaccessible_0_arg1_str); + attribute_Deprecated_func_setaccessible_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + return class_entry; } @@ -1664,27 +1812,27 @@ static zend_class_entry *register_class_ReflectionClassConstant(zend_class_entry zval const_IS_PUBLIC_value; ZVAL_LONG(&const_IS_PUBLIC_value, ZEND_ACC_PUBLIC); - zend_string *const_IS_PUBLIC_name = zend_string_init_interned("IS_PUBLIC", sizeof("IS_PUBLIC") - 1, 1); + zend_string *const_IS_PUBLIC_name = zend_string_init_interned("IS_PUBLIC", sizeof("IS_PUBLIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PUBLIC_name, &const_IS_PUBLIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PUBLIC_name); + zend_string_release_ex(const_IS_PUBLIC_name, true); zval const_IS_PROTECTED_value; ZVAL_LONG(&const_IS_PROTECTED_value, ZEND_ACC_PROTECTED); - zend_string *const_IS_PROTECTED_name = zend_string_init_interned("IS_PROTECTED", sizeof("IS_PROTECTED") - 1, 1); + zend_string *const_IS_PROTECTED_name = zend_string_init_interned("IS_PROTECTED", sizeof("IS_PROTECTED") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PROTECTED_name, &const_IS_PROTECTED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PROTECTED_name); + zend_string_release_ex(const_IS_PROTECTED_name, true); zval const_IS_PRIVATE_value; ZVAL_LONG(&const_IS_PRIVATE_value, ZEND_ACC_PRIVATE); - zend_string *const_IS_PRIVATE_name = zend_string_init_interned("IS_PRIVATE", sizeof("IS_PRIVATE") - 1, 1); + zend_string *const_IS_PRIVATE_name = zend_string_init_interned("IS_PRIVATE", sizeof("IS_PRIVATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_PRIVATE_name, &const_IS_PRIVATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_PRIVATE_name); + zend_string_release_ex(const_IS_PRIVATE_name, true); zval const_IS_FINAL_value; ZVAL_LONG(&const_IS_FINAL_value, ZEND_ACC_FINAL); - zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, 1); + zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_FINAL_name, &const_IS_FINAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_FINAL_name); + zend_string_release_ex(const_IS_FINAL_name, true); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); @@ -1711,39 +1859,22 @@ static zend_class_entry *register_class_ReflectionParameter(zend_class_entry *cl zend_attribute *attribute_Deprecated_func_getclass_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "getclass", sizeof("getclass") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_getclass_0_arg0; - zend_string *attribute_Deprecated_func_getclass_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_getclass_0_arg0, attribute_Deprecated_func_getclass_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_getclass_0->args[0].value, &attribute_Deprecated_func_getclass_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_getclass_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_getclass_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_getclass_0_arg1; zend_string *attribute_Deprecated_func_getclass_0_arg1_str = zend_string_init("use ReflectionParameter::getType() instead", strlen("use ReflectionParameter::getType() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_getclass_0_arg1, attribute_Deprecated_func_getclass_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_getclass_0->args[1].value, &attribute_Deprecated_func_getclass_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_getclass_0->args[1].value, attribute_Deprecated_func_getclass_0_arg1_str); attribute_Deprecated_func_getclass_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_isarray_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "isarray", sizeof("isarray") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_isarray_0_arg0; - zend_string *attribute_Deprecated_func_isarray_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_isarray_0_arg0, attribute_Deprecated_func_isarray_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_isarray_0->args[0].value, &attribute_Deprecated_func_isarray_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_isarray_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_isarray_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_isarray_0_arg1; - zend_string *attribute_Deprecated_func_isarray_0_arg1_str = zend_string_init("use ReflectionParameter::getType() instead", strlen("use ReflectionParameter::getType() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_isarray_0_arg1, attribute_Deprecated_func_isarray_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_isarray_0->args[1].value, &attribute_Deprecated_func_isarray_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_isarray_0->args[1].value, attribute_Deprecated_func_getclass_0_arg1_str); attribute_Deprecated_func_isarray_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_iscallable_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "iscallable", sizeof("iscallable") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_iscallable_0_arg0; - zend_string *attribute_Deprecated_func_iscallable_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_iscallable_0_arg0, attribute_Deprecated_func_iscallable_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_iscallable_0->args[0].value, &attribute_Deprecated_func_iscallable_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_iscallable_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_iscallable_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_iscallable_0_arg1; - zend_string *attribute_Deprecated_func_iscallable_0_arg1_str = zend_string_init("use ReflectionParameter::getType() instead", strlen("use ReflectionParameter::getType() instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_iscallable_0_arg1, attribute_Deprecated_func_iscallable_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_iscallable_0->args[1].value, &attribute_Deprecated_func_iscallable_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_iscallable_0->args[1].value, attribute_Deprecated_func_getclass_0_arg1_str); attribute_Deprecated_func_iscallable_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; @@ -1790,6 +1921,48 @@ static zend_class_entry *register_class_ReflectionIntersectionType(zend_class_en return class_entry; } +static zend_class_entry *register_class_ReflectionTypeParameterReference(zend_class_entry *class_entry_ReflectionType) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ReflectionTypeParameterReference", class_ReflectionTypeParameterReference_methods); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_ReflectionType, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); + + zval property_name_default_value; + ZVAL_UNDEF(&property_name_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + return class_entry; +} + +static zend_class_entry *register_class_ReflectionGenericVariance(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("ReflectionGenericVariance", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Invariant", NULL); + + zend_enum_add_case_cstr(class_entry, "Covariant", NULL); + + zend_enum_add_case_cstr(class_entry, "Contravariant", NULL); + + return class_entry; +} + +static zend_class_entry *register_class_ReflectionGenericTypeParameter(zend_class_entry *class_entry_Reflector) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ReflectionGenericTypeParameter", class_ReflectionGenericTypeParameter_methods); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); + zend_class_implements(class_entry, 1, class_entry_Reflector); + + zval property_name_default_value; + ZVAL_UNDEF(&property_name_default_value); + zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_NAME), &property_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + + return class_entry; +} + static zend_class_entry *register_class_ReflectionExtension(zend_class_entry *class_entry_Reflector) { zend_class_entry ce, *class_entry; @@ -1840,9 +2013,9 @@ static zend_class_entry *register_class_ReflectionAttribute(zend_class_entry *cl zval const_IS_INSTANCEOF_value; ZVAL_LONG(&const_IS_INSTANCEOF_value, REFLECTION_ATTRIBUTE_IS_INSTANCEOF); - zend_string *const_IS_INSTANCEOF_name = zend_string_init_interned("IS_INSTANCEOF", sizeof("IS_INSTANCEOF") - 1, 1); + zend_string *const_IS_INSTANCEOF_name = zend_string_init_interned("IS_INSTANCEOF", sizeof("IS_INSTANCEOF") - 1, true); zend_declare_typed_class_constant(class_entry, const_IS_INSTANCEOF_name, &const_IS_INSTANCEOF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IS_INSTANCEOF_name); + zend_string_release_ex(const_IS_INSTANCEOF_name, true); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); @@ -1896,7 +2069,7 @@ static zend_class_entry *register_class_ReflectionConstant(zend_class_entry *cla zend_class_entry ce, *class_entry; INIT_CLASS_ENTRY(ce, "ReflectionConstant", class_ReflectionConstant_methods); - class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); + class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); zend_class_implements(class_entry, 1, class_entry_Reflector); zval property_name_default_value; diff --git a/ext/reflection/php_reflection_decl.h b/ext/reflection/php_reflection_decl.h new file mode 100644 index 000000000000..43cec2cd9936 --- /dev/null +++ b/ext/reflection/php_reflection_decl.h @@ -0,0 +1,18 @@ +/* This is a generated file, edit php_reflection.stub.php instead. + * Stub hash: e21013562d5d9f87a8707afdf579f799a858dba3 */ + +#ifndef ZEND_PHP_REFLECTION_DECL_e21013562d5d9f87a8707afdf579f799a858dba3_H +#define ZEND_PHP_REFLECTION_DECL_e21013562d5d9f87a8707afdf579f799a858dba3_H + +typedef enum zend_enum_PropertyHookType { + ZEND_ENUM_PropertyHookType_Get = 1, + ZEND_ENUM_PropertyHookType_Set = 2, +} zend_enum_PropertyHookType; + +typedef enum zend_enum_ReflectionGenericVariance { + ZEND_ENUM_ReflectionGenericVariance_Invariant = 1, + ZEND_ENUM_ReflectionGenericVariance_Covariant = 2, + ZEND_ENUM_ReflectionGenericVariance_Contravariant = 3, +} zend_enum_ReflectionGenericVariance; + +#endif /* ZEND_PHP_REFLECTION_DECL_e21013562d5d9f87a8707afdf579f799a858dba3_H */ diff --git a/ext/reflection/tests/022.phpt b/ext/reflection/tests/022.phpt index 4a6738f97cd2..7a78397a76f0 100644 --- a/ext/reflection/tests/022.phpt +++ b/ext/reflection/tests/022.phpt @@ -9,6 +9,8 @@ $class = new ReflectionClass("Foo"); var_dump($class->getConstant("c1")); var_dump($class->getConstant("c2")); ?> ---EXPECT-- +--EXPECTF-- int(1) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt index 67d1eee7e837..a8864c5970a9 100644 --- a/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt +++ b/ext/reflection/tests/ReflectionClass_getConstant_basic.phpt @@ -23,19 +23,31 @@ foreach($classes as $class) { var_dump($rc->getConstant('doesnotexist')); } ?> ---EXPECT-- +--EXPECTF-- Reflecting on class C: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class D: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class E: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class F: string(12) "hello from F" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on class X: + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionClass_getConstant_error.phpt b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt index d143006af999..caadf2e3713f 100644 --- a/ext/reflection/tests/ReflectionClass_getConstant_error.phpt +++ b/ext/reflection/tests/ReflectionClass_getConstant_error.phpt @@ -12,8 +12,14 @@ var_dump($rc->getConstant(1)); var_dump($rc->getConstant(1.5)); var_dump($rc->getConstant(true)); ?> ---EXPECT-- +--EXPECTF-- Check invalid params: + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionClass_isIterable_gh20217.phpt b/ext/reflection/tests/ReflectionClass_isIterable_gh20217.phpt new file mode 100644 index 000000000000..f64fc1efcd41 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_isIterable_gh20217.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-20217 (ReflectionClass::isIterable() should return false for classes with property hooks) +--FILE-- + 'virtual'; + } +} + +class IterableClassWithPropertyHooks implements IteratorAggregate +{ + public string $name { + get => 'virtual'; + } + + public function getIterator(): Traversable + { + return new ArrayIterator([]); + } +} + +$classes = [ + 'ClassWithPropertyHooks' => false, + 'IterableClassWithPropertyHooks' => true, +]; + +foreach ($classes as $className => $expected) { + $status = (new ReflectionClass($className)->isIterable() === $expected) ? 'PASS' : 'FAIL'; + echo "$className: $status\n"; +} + +?> +--EXPECT-- +ClassWithPropertyHooks: PASS +IterableClassWithPropertyHooks: PASS diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index fd5d83e91741..01415d08aacb 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -30,7 +30,7 @@ Class [ class ReflectionClass implements Stringable, Refle Property [ public string $name ] } - - Methods [64] { + - Methods [69] { Method [ private method __clone ] { - Parameters [0] { @@ -514,5 +514,42 @@ Class [ class ReflectionClass implements Stringable, Refle } - Return [ array ] } + + Method [ public method isGeneric ] { + + - Parameters [0] { + } + - Return [ bool ] + } + + Method [ public method getGenericParameters ] { + + - Parameters [0] { + } + - Return [ array ] + } + + Method [ public method getGenericArgumentsForParentClass ] { + + - Parameters [0] { + } + - Return [ array ] + } + + Method [ public method getGenericArgumentsForParentInterface ] { + + - Parameters [1] { + Parameter #0 [ string $name ] + } + - Return [ array ] + } + + Method [ public method getGenericArgumentsForUsedTrait ] { + + - Parameters [1] { + Parameter #0 [ string $name ] + } + - Return [ array ] + } } } diff --git a/ext/reflection/tests/ReflectionClass_toString_008.phpt b/ext/reflection/tests/ReflectionClass_toString_008.phpt new file mode 100644 index 000000000000..15131cfd880a --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_toString_008.phpt @@ -0,0 +1,165 @@ +--TEST-- +Using ReflectionClass::__toString() with hooked properties (GH-17927) +--FILE-- + "always this string"; + } + public mixed $setOnly { + set => strtolower($value); + } + public mixed $both { + get => $this->prop3; + set => strtolower($value); + } +} +class WithFinalHooks { + public mixed $getOnly { + final get => "always this string"; + } + public mixed $setOnly { + final set => strtolower($value); + } + public mixed $both { + final get => $this->prop3; + final set => strtolower($value); + } +} +class WithMixedHooks { + public mixed $getIsFinal { + final get => "always this string"; + set => strtolower($value); + } + public mixed $setIsFinal { + get => $this->setIsFinal; + final set => strtolower($value); + } +} +$classes = [ + IHookedDemo::class, + HookedDemo::class, + WithHooks::class, + WithFinalHooks::class, + WithMixedHooks::class, +]; +foreach ( $classes as $clazz ) { + echo new ReflectionClass( $clazz ); +} +?> +--EXPECTF-- +Interface [ interface IHookedDemo ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ abstract public virtual mixed $getOnly { get; } ] + Property [ abstract public virtual mixed $setOnly { set; } ] + Property [ abstract public virtual mixed $both { get; set; } ] + } + + - Methods [0] { + } +} +Class [ abstract class HookedDemo ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ abstract public virtual mixed $getOnly { get; } ] + Property [ abstract public virtual mixed $setOnly { set; } ] + Property [ abstract public virtual mixed $both { get; set; } ] + } + + - Methods [0] { + } +} +Class [ class WithHooks ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ public virtual mixed $getOnly { get; } ] + Property [ public mixed $setOnly { set; } ] + Property [ public mixed $both { get; set; } ] + } + + - Methods [0] { + } +} +Class [ class WithFinalHooks ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ public virtual mixed $getOnly { final get; } ] + Property [ public mixed $setOnly { final set; } ] + Property [ public mixed $both { final get; final set; } ] + } + + - Methods [0] { + } +} +Class [ class WithMixedHooks ] { + @@ %s %d-%d + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [2] { + Property [ public mixed $getIsFinal { final get; set; } ] + Property [ public mixed $setIsFinal { get; final set; } ] + } + + - Methods [0] { + } +} diff --git a/ext/reflection/tests/ReflectionConstant_inNamespace.phpt b/ext/reflection/tests/ReflectionConstant_inNamespace.phpt new file mode 100644 index 000000000000..16001b5f9317 --- /dev/null +++ b/ext/reflection/tests/ReflectionConstant_inNamespace.phpt @@ -0,0 +1,39 @@ +--TEST-- +ReflectionConstant::inNamespace() +--FILE-- +inNamespace()); + var_dump($rc1->getNamespaceName()); + var_dump($rc1->getShortName()); + + $rc2 = new ReflectionConstant('Foo\Bar\NAMESPACED_CONST'); + var_dump($rc2->inNamespace()); + var_dump($rc2->getNamespaceName()); + var_dump($rc2->getShortName()); + + $rc3 = new ReflectionConstant('E_ERROR'); + var_dump($rc3->inNamespace()); + var_dump($rc3->getNamespaceName()); + var_dump($rc3->getShortName()); +} + +?> +--EXPECT-- +bool(false) +string(0) "" +string(12) "GLOBAL_CONST" +bool(true) +string(7) "Foo\Bar" +string(16) "NAMESPACED_CONST" +bool(false) +string(0) "" +string(7) "E_ERROR" diff --git a/ext/reflection/tests/ReflectionConstant_ns.phpt b/ext/reflection/tests/ReflectionConstant_ns.phpt index b047fc25dcf2..36bf8a08672a 100644 --- a/ext/reflection/tests/ReflectionConstant_ns.phpt +++ b/ext/reflection/tests/ReflectionConstant_ns.phpt @@ -14,6 +14,10 @@ namespace { var_dump(new \ReflectionConstant('\\C')); var_dump(new \ReflectionConstant('Foo\\C')); var_dump(new \ReflectionConstant('\\Foo\\C')); + var_dump((new \ReflectionConstant('C'))->inNamespace()); + var_dump((new \ReflectionConstant('\\C'))->inNamespace()); + var_dump((new \ReflectionConstant('Foo\\C'))->inNamespace()); + var_dump((new \ReflectionConstant('\\Foo\\C'))->inNamespace()); var_dump((new \ReflectionConstant('C'))->getNamespaceName()); var_dump((new \ReflectionConstant('\\C'))->getNamespaceName()); var_dump((new \ReflectionConstant('Foo\\C'))->getNamespaceName()); @@ -42,6 +46,10 @@ object(ReflectionConstant)#1 (1) { ["name"]=> string(6) "\Foo\C" } +bool(false) +bool(false) +bool(true) +bool(true) string(0) "" string(0) "" string(3) "Foo" diff --git a/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt index 47813255381e..9d1210705096 100644 --- a/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt +++ b/ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt @@ -15,6 +15,7 @@ foreach ($classNames as $className) { AssertionError Directory RoundingMode +SortDirection StreamBucket __PHP_Incomplete_Class php_user_filter diff --git a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt index 8ba243a503bd..e591c9b2f091 100644 --- a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt +++ b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt @@ -8,7 +8,7 @@ $ext = new ReflectionExtension('reflection'); var_dump($ext->getClasses()); ?> --EXPECTF-- -array(26) { +array(29) { ["ReflectionException"]=> object(ReflectionClass)#%d (1) { ["name"]=> @@ -139,4 +139,19 @@ array(26) { ["name"]=> string(16) "PropertyHookType" } + ["ReflectionGenericVariance"]=> + object(ReflectionEnum)#%d (1) { + ["name"]=> + string(25) "ReflectionGenericVariance" + } + ["ReflectionGenericTypeParameter"]=> + object(ReflectionClass)#%d (1) { + ["name"]=> + string(30) "ReflectionGenericTypeParameter" + } + ["ReflectionTypeParameterReference"]=> + object(ReflectionClass)#%d (1) { + ["name"]=> + string(32) "ReflectionTypeParameterReference" + } } diff --git a/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt b/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt index be13fe27a820..84d261e0a00e 100644 --- a/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt +++ b/ext/reflection/tests/ReflectionExtension_getDependencies_variation2.phpt @@ -7,8 +7,12 @@ Felix De Vliegher $standard = new ReflectionExtension('standard'); var_dump($standard->getDependencies()); ?> ---EXPECTF-- -array(1) { +--EXPECT-- +array(3) { + ["random"]=> + string(8) "Required" + ["uri"]=> + string(8) "Required" ["session"]=> - %s(8) "Optional" + string(8) "Optional" } diff --git a/ext/reflection/tests/ReflectionFunction__toString_bound_variables.phpt b/ext/reflection/tests/ReflectionFunction__toString_bound_variables.phpt new file mode 100644 index 000000000000..142e66136149 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction__toString_bound_variables.phpt @@ -0,0 +1,32 @@ +--TEST-- +ReflectionFunction::__toString() with bound variables +--FILE-- + 0; + +$rf = new ReflectionFunction($closure_without_bounds); +echo (string) $rf; + +$global = ""; +$closure_with_bounds = function() use($global) { + static $counter = 0; + return $counter++; +}; + +$rf = new ReflectionFunction($closure_with_bounds); +echo (string) $rf; + +?> +--EXPECTF-- +Closure [ function {closure:%s:%d} ] { + @@ %sReflectionFunction__toString_bound_variables.php 3 - 3 +} +Closure [ function {closure:%s:%d} ] { + @@ %sReflectionFunction__toString_bound_variables.php 9 - 12 + + - Bound Variables [2] { + Variable #0 [ $global ] + Variable #1 [ $counter ] + } +} diff --git a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt index 92312528a041..be720a4044c7 100644 --- a/ext/reflection/tests/ReflectionMethod_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionMethod_setAccessible.phpt @@ -37,7 +37,7 @@ $protected->invokeArgs(new A, array(NULL)); $protectedStatic->invoke(NULL, NULL); $protectedStatic->invokeArgs(NULL, array(NULL)); ?> ---EXPECT-- +--EXPECTF-- A::aPrivate A::aPrivate A::aPrivateStatic @@ -46,6 +46,14 @@ A::aProtected A::aProtected A::aProtectedStatic A::aProtectedStatic + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionMethod::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d A::aPrivate A::aPrivate A::aPrivateStatic diff --git a/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt index c132f1121a11..fec75b40eb2a 100644 --- a/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt +++ b/ext/reflection/tests/ReflectionObject_getConstant_basic.phpt @@ -23,19 +23,31 @@ foreach($classes as $class) { var_dump($rc->getConstant('doesNotexist')); } ?> ---EXPECT-- +--EXPECTF-- Reflecting on instance of class C: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class D: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class E: string(12) "hello from C" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class F: string(12) "hello from F" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Reflecting on instance of class X: + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) diff --git a/ext/reflection/tests/ReflectionParameter_getDocComment_basic.phpt b/ext/reflection/tests/ReflectionParameter_getDocComment_basic.phpt new file mode 100644 index 000000000000..46e47bf60324 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_getDocComment_basic.phpt @@ -0,0 +1,248 @@ +--TEST-- +Test ReflectionParameter::getDocComment() usage. +--INI-- +opcache.save_comments=1 +--FILE-- +property = $value; } +} +} + +function global_function( + /** + * My Doc Comment for $a + * + */ + $a, $b, $c, + /** + * My Doc Comment for $d + */ + $d, + // Not a doc comment + /**Not a doc comment */ + $e, + /** + * Doc comment for $f + */ + $f, + $g /** Doc comment for $g after parameter */, + /** Doc comment for $h */ + $h /** Doc comment for $h after parameter */, +) {} + +$closure = function( + /** + * My Doc Comment for $a + * + */ + $a, $b, $c, + /** + * My Doc Comment for $d + */ + $d, + // Not a doc comment + /**Not a doc comment */ + $e, + /** + * Doc comment for $f + */ + $f, + $g /** Doc comment for $g after parameter */, + /** Doc comment for $h */ + $h /** Doc comment for $h after parameter */, +) {}; + +$arrow_function = fn( + /** + * My Doc Comment for $a + * + */ + $a, $b, $c, + /** + * My Doc Comment for $d + */ + $d, + // Not a doc comment + /**Not a doc comment */ + $e, + /** + * Doc comment for $f + */ + $f, + $g /** Doc comment for $g after parameter */, + /** Doc comment for $h */ + $h /** Doc comment for $h after parameter */, +) => true; + +foreach([ + 'A::method' => (new ReflectionClass('A'))->getMethod('method'), + 'global_function' => new ReflectionFunction('global_function'), + 'closure' => new ReflectionFunction($closure), + 'arrow_function' => new ReflectionFunction($arrow_function), + 'property hook' => (new ReflectionClass('A'))->getProperty('property')->getHook(PropertyHookType::Set), + ] as $function => $rc) { + $rps = $rc->getParameters(); + foreach($rps as $rp) { + echo "\n---> Doc comment for $function parameter $" . $rp->getName() . ":\n"; + var_dump($rp->getDocComment()); + } +} + +?> +--EXPECTF-- +---> Doc comment for A::method parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for A::method parameter $b: +bool(false) + +---> Doc comment for A::method parameter $c: +bool(false) + +---> Doc comment for A::method parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for A::method parameter $e: +bool(false) + +---> Doc comment for A::method parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for A::method parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for A::method parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for global_function parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for global_function parameter $b: +bool(false) + +---> Doc comment for global_function parameter $c: +bool(false) + +---> Doc comment for global_function parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for global_function parameter $e: +bool(false) + +---> Doc comment for global_function parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for global_function parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for global_function parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for closure parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for closure parameter $b: +bool(false) + +---> Doc comment for closure parameter $c: +bool(false) + +---> Doc comment for closure parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for closure parameter $e: +bool(false) + +---> Doc comment for closure parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for closure parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for closure parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for arrow_function parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for arrow_function parameter $b: +bool(false) + +---> Doc comment for arrow_function parameter $c: +bool(false) + +---> Doc comment for arrow_function parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for arrow_function parameter $e: +bool(false) + +---> Doc comment for arrow_function parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for arrow_function parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for arrow_function parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for property hook parameter $value: +string(%d) "/** Doc Comment for property hook parameter $value */" + diff --git a/ext/reflection/tests/ReflectionParameter_getDocComment_indented.phpt b/ext/reflection/tests/ReflectionParameter_getDocComment_indented.phpt new file mode 100644 index 000000000000..ede7a00e0edd --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_getDocComment_indented.phpt @@ -0,0 +1,84 @@ +--TEST-- +Test ReflectionParameter::getDocComment() usage when methods are indented. +--INI-- +opcache.save_comments=1 +--FILE-- +property = $value; } + } +} + +foreach([ + 'A::method' => (new ReflectionClass('A'))->getMethod('method'), + 'property hook' => (new ReflectionClass('A'))->getProperty('property')->getHook(PropertyHookType::Set), + ] as $function => $rc) { + $rps = $rc->getParameters(); + foreach($rps as $rp) { + echo "\n---> Doc comment for $function parameter $" . $rp->getName() . ":\n"; + var_dump($rp->getDocComment()); + } +} + +?> +--EXPECTF-- +---> Doc comment for A::method parameter $a: +string(%d) "/** + * My Doc Comment for $a + * + */" + +---> Doc comment for A::method parameter $b: +bool(false) + +---> Doc comment for A::method parameter $c: +bool(false) + +---> Doc comment for A::method parameter $d: +string(%d) "/** + * My Doc Comment for $d + */" + +---> Doc comment for A::method parameter $e: +bool(false) + +---> Doc comment for A::method parameter $f: +string(%d) "/** + * Doc comment for $f + */" + +---> Doc comment for A::method parameter $g: +string(%d) "/** Doc comment for $g after parameter */" + +---> Doc comment for A::method parameter $h: +string(%d) "/** Doc comment for $h after parameter */" + +---> Doc comment for property hook parameter $value: +string(%d) "/** Doc Comment for property hook parameter $value */" diff --git a/ext/reflection/tests/ReflectionParameter_getDocComment_property_hooks.phpt b/ext/reflection/tests/ReflectionParameter_getDocComment_property_hooks.phpt new file mode 100644 index 000000000000..5689a2c46aca --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_getDocComment_property_hooks.phpt @@ -0,0 +1,143 @@ +--TEST-- +Test ReflectionParameter::getDocComment() usage for property with hook. +--INI-- +opcache.save_comments=1 +--FILE-- +getProperty('foo'); +echo "\n---> Doc comment for A::property $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Get); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Set); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rp = $rh->getParameters()[0]; +echo "\n---> Doc comment for A::property \$foo::set parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +// --------- + +$rp = $rc->getConstructor()->getParameters()[1]; +echo "\n---> Doc comment for A::constructor parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rp = $rc->getProperty('bar'); +echo "\n---> Doc comment for A::property $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Get); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Set); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rp = $rh->getParameters()[0]; +echo "\n---> Doc comment for A::property \$bar::set parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +// --------- + +$rp = $rc->getConstructor()->getParameters()[2]; +echo "\n---> Doc comment for A::constructor parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rp = $rc->getProperty('baz'); +echo "\n---> Doc comment for A::property $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Get); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rh = $rp->getHook(PropertyHookType::Set); +echo "\n---> Doc comment for A::property " . $rh->getName() . ":\n"; +var_dump($rh->getDocComment()); + +$rp = $rh->getParameters()[0]; +echo "\n---> Doc comment for A::property \$baz::set parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +$rp = $rc->getConstructor()->getParameters()[0]; +echo "\n---> Doc comment for A::constructor parameter $" . $rp->getName() . ":\n"; +var_dump($rp->getDocComment()); + +?> +--EXPECTF-- +---> Doc comment for A::property $foo: +string(11) "/** $foo */" + +---> Doc comment for A::property $foo::get: +string(13) "/** getter */" + +---> Doc comment for A::property $foo::set: +string(13) "/** setter */" + +---> Doc comment for A::property $foo::set parameter $value: +string(13) "/** $value */" + +---> Doc comment for A::constructor parameter $bar: +string(11) "/** $bar */" + +---> Doc comment for A::property $bar: +string(11) "/** $bar */" + +---> Doc comment for A::property $bar::get: +string(13) "/** getter */" + +---> Doc comment for A::property $bar::set: +string(13) "/** setter */" + +---> Doc comment for A::property $bar::set parameter $value: +string(13) "/** $value */" + +---> Doc comment for A::constructor parameter $baz: +bool(false) + +---> Doc comment for A::property $baz: +bool(false) + +---> Doc comment for A::property $baz::get: +string(13) "/** getter */" + +---> Doc comment for A::property $baz::set: +string(13) "/** setter */" + +---> Doc comment for A::property $baz::set parameter $value: +string(13) "/** $value */" + +---> Doc comment for A::constructor parameter $foo: +string(11) "/** $foo */" diff --git a/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt b/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt index 423edfe9faf0..d74e1f4bfe6c 100644 --- a/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt +++ b/ext/reflection/tests/ReflectionProperty_getDefaultValue.phpt @@ -60,15 +60,21 @@ $property = new ReflectionProperty($test, 'dynamic'); var_dump($property->getDefaultValue()); ?> ---EXPECT-- +--EXPECTF-- NULL string(3) "baz" NULL int(1234) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL int(1234) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL NULL int(4) int(42) + +Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists in %s on line %d NULL diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_basic.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_basic.phpt new file mode 100644 index 000000000000..473ac2c84b81 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test ReflectionProperty::getMangledName() method +--FILE-- +getName() . "\n"; + echo "getMangledName(): " . $reflection->getMangledName() . "\n"; + + $obj = new $class(); + $array = (array) $obj; + echo "In array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "found" : "not found") . "\n"; + echo "\n"; +} + +testMangledName('TestClass', 'publicProp'); +testMangledName('TestClass', 'protectedProp'); +testMangledName('TestClass', 'privateProp'); + +?> +--EXPECTF-- +Property: publicProp +getName(): publicProp +getMangledName(): publicProp +In array cast: found + +Property: protectedProp +getName(): protectedProp +getMangledName(): %0*%0protectedProp +In array cast: found + +Property: privateProp +getName(): privateProp +getMangledName(): %0TestClass%0privateProp +In array cast: found diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_dynamic.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_dynamic.phpt new file mode 100644 index 000000000000..271552ab46ae --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_dynamic.phpt @@ -0,0 +1,125 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with dynamic properties +--FILE-- +prop1 = 'value1'; +$stdObj->{'special-name'} = 'special value'; +$stdObj->{'123numeric'} = 'numeric start'; + +function testDynamicProperty($obj, $property, $description) { + try { + $reflection = new ReflectionProperty($obj, $property); + echo "$description:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "$description: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testDynamicProperty($stdObj, 'prop1', 'stdClass property prop1'); +testDynamicProperty($stdObj, 'special-name', 'stdClass property with special name'); +testDynamicProperty($stdObj, '123numeric', 'stdClass property starting with number'); + +echo "=== Testing edge cases ===\n"; +$numericObj = (object)[true]; +testDynamicProperty($numericObj, '0', 'Property name as number'); + +$nullByteObj = (object)["foo\0" => true]; +testDynamicProperty($nullByteObj, "foo\0", 'Property name with null byte'); + +$invalidObj = (object)["::" => true]; +testDynamicProperty($invalidObj, '::', 'Invalid property name'); + +echo "=== Testing regular class with dynamic properties ===\n"; +#[AllowDynamicProperties] +class TestClass { + public $existing = 'existing'; +} + +$obj = new TestClass(); +$obj->dynamic = 'dynamic value'; +$obj->anotherDynamic = 'another dynamic'; + +testDynamicProperty($obj, 'dynamic', 'Regular class dynamic property'); +testDynamicProperty($obj, 'anotherDynamic', 'Regular class another dynamic property'); + +$reflection = new ReflectionProperty($obj, 'existing'); +echo "Regular property:\n"; +echo " getName(): " . $reflection->getName() . "\n"; +echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + +echo "\n=== Testing ReflectionProperty from class vs instance ===\n"; +try { + $reflection = new ReflectionProperty('TestClass', 'dynamic'); + echo "This should not be reached\n"; +} catch (ReflectionException $e) { + echo "Expected exception for class-based reflection: " . $e->getMessage() . "\n"; +} + +try { + $reflection = new ReflectionProperty($obj, 'dynamic'); + echo "Instance-based reflection works: " . $reflection->getMangledName() . "\n"; +} catch (ReflectionException $e) { + echo "Unexpected exception: " . $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +=== Testing stdClass with dynamic properties === +stdClass property prop1: + getName(): prop1 + getMangledName(): prop1 + Found in array cast: yes + +stdClass property with special name: + getName(): special-name + getMangledName(): special-name + Found in array cast: yes + +stdClass property starting with number: + getName(): 123numeric + getMangledName(): 123numeric + Found in array cast: yes + +=== Testing edge cases === +Property name as number: + getName(): 0 + getMangledName(): 0 + Found in array cast: yes + +Property name with null byte: + getName(): foo%0 + getMangledName(): foo%0 + Found in array cast: yes + +Invalid property name: + getName(): :: + getMangledName(): :: + Found in array cast: yes + +=== Testing regular class with dynamic properties === +Regular class dynamic property: + getName(): dynamic + getMangledName(): dynamic + Found in array cast: yes + +Regular class another dynamic property: + getName(): anotherDynamic + getMangledName(): anotherDynamic + Found in array cast: yes + +Regular property: + getName(): existing + getMangledName(): existing + +=== Testing ReflectionProperty from class vs instance === +Expected exception for class-based reflection: Property TestClass::$dynamic does not exist +Instance-based reflection works: dynamic diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_hooks.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_hooks.phpt new file mode 100644 index 000000000000..da00a0da2912 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_hooks.phpt @@ -0,0 +1,82 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with property hooks +--FILE-- + "virtual"; + } + + public string $bar { + get => "hooked getter"; + set => throw new Exception("Cannot set bar"); + } + + public string $baz = "backed"; +} + +$d = new Demo(); + +function testHookedProperty($obj, $property, $description) { + try { + $reflection = new ReflectionProperty($obj, $property); + echo "$description:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo " Has hooks: " . ($reflection->hasHooks() ? "yes" : "no") . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "$description: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testHookedProperty($d, 'foo', 'Virtual hooked property (protected)'); +testHookedProperty($d, 'bar', 'Hooked property with getter/setter (public)'); +testHookedProperty($d, 'baz', 'Regular backed property'); + +echo "=== Object dump ===\n"; +var_dump($d); + +echo "\n=== Array cast ===\n"; +var_dump((array)$d); + +?> +--EXPECTF-- +=== Testing virtual hooked properties === +Virtual hooked property (protected): + getName(): foo + getMangledName(): %0*%0foo + Found in array cast: no + Has hooks: yes + +Hooked property with getter/setter (public): + getName(): bar + getMangledName(): bar + Found in array cast: no + Has hooks: yes + +Regular backed property: + getName(): baz + getMangledName(): baz + Found in array cast: yes + Has hooks: no + +=== Object dump === +object(Demo)#1 (1) { + ["bar"]=> + uninitialized(string) + ["baz"]=> + string(6) "backed" +} + +=== Array cast === +array(1) { + ["baz"]=> + string(6) "backed" +} diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_inheritance.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_inheritance.phpt new file mode 100644 index 000000000000..301756c8cbf2 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_inheritance.phpt @@ -0,0 +1,87 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with inheritance +--FILE-- +getMangledName() . "'\n"; + echo "Key exists in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; +} + +testProperty('ParentClass', 'public'); +testProperty('ParentClass', 'protected'); +testProperty('ParentClass', 'private'); + +testProperty('ChildClass', 'public'); +testProperty('ChildClass', 'protected'); +testProperty('ChildClass', 'childProp'); +testProperty('ChildClass', 'private'); + +echo "Access to parent's private property not in child:\n"; + +try { + $reflection = new ReflectionProperty('ChildClass', 'parentOnly'); + echo "ERROR: Should have failed\n"; +} catch (ReflectionException $e) { + echo "Instance-based creation failed as expected: " . $e->getMessage() . "\n"; +} + +try { + $obj = new ChildClass(); + $reflection = new ReflectionProperty($obj, 'parentOnly'); + echo "ERROR: Should have failed\n"; +} catch (ReflectionException $e) { + echo "Object-based creation failed as expected: " . $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Class: ParentClass, Property: $public +Mangled name: 'public' +Key exists in array cast: yes + +Class: ParentClass, Property: $protected +Mangled name: '%0*%0protected' +Key exists in array cast: yes + +Class: ParentClass, Property: $private +Mangled name: '%0ParentClass%0private' +Key exists in array cast: yes + +Class: ChildClass, Property: $public +Mangled name: 'public' +Key exists in array cast: yes + +Class: ChildClass, Property: $protected +Mangled name: '%0*%0protected' +Key exists in array cast: yes + +Class: ChildClass, Property: $childProp +Mangled name: '%0*%0childProp' +Key exists in array cast: yes + +Class: ChildClass, Property: $private +Mangled name: '%0ChildClass%0private' +Key exists in array cast: yes + +Access to parent's private property not in child: +Instance-based creation failed as expected: Property ChildClass::$parentOnly does not exist +Object-based creation failed as expected: Property ChildClass::$parentOnly does not exist diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_instance.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_instance.phpt new file mode 100644 index 000000000000..7c24ce85f173 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_instance.phpt @@ -0,0 +1,99 @@ +--TEST-- +Test ReflectionProperty::getMangledName() from instance vs class +--FILE-- +dynamic = 'dynamic'; + +echo "=== Testing ReflectionProperty from CLASS ===\n"; + +function testFromClass($property) { + try { + $reflection = new ReflectionProperty('TestClass', $property); + echo "Property $property from class:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "Property $property from class: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testFromClass('public'); +testFromClass('protected'); +testFromClass('private'); +testFromClass('dynamic'); + +echo "=== Testing ReflectionProperty from INSTANCE ===\n"; + +function testFromInstance($obj, $property) { + try { + $reflection = new ReflectionProperty($obj, $property); + echo "Property $property from instance:\n"; + echo " getName(): " . $reflection->getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; + } catch (ReflectionException $e) { + echo "Property $property from instance: EXCEPTION - " . $e->getMessage() . "\n\n"; + } +} + +testFromInstance($obj, 'public'); +testFromInstance($obj, 'protected'); +testFromInstance($obj, 'private'); + +echo "=== Instance array keys ===\n"; +$array = (array) $obj; +foreach (array_keys($array) as $key) { + echo "Key: '$key'\n"; +} + +?> +--EXPECTF-- +=== Testing ReflectionProperty from CLASS === +Property public from class: + getName(): public + getMangledName(): public + +Property protected from class: + getName(): protected + getMangledName(): %0*%0protected + +Property private from class: + getName(): private + getMangledName(): %0TestClass%0private + +Property dynamic from class: EXCEPTION - Property TestClass::$dynamic does not exist + +=== Testing ReflectionProperty from INSTANCE === +Property public from instance: + getName(): public + getMangledName(): public + Found in array cast: yes + +Property protected from instance: + getName(): protected + getMangledName(): %0*%0protected + Found in array cast: yes + +Property private from instance: + getName(): private + getMangledName(): %0TestClass%0private + Found in array cast: yes + +=== Instance array keys === +Key: 'public' +Key: '%0*%0protected' +Key: '%0TestClass%0private' +Key: 'dynamic' diff --git a/ext/reflection/tests/ReflectionProperty_getMangledName_override.phpt b/ext/reflection/tests/ReflectionProperty_getMangledName_override.phpt new file mode 100644 index 000000000000..3f6a3bfdcc5e --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_getMangledName_override.phpt @@ -0,0 +1,123 @@ +--TEST-- +Test ReflectionProperty::getMangledName() with property overrides and visibility changes +--FILE-- +getName() . "\n"; + echo " getMangledName(): " . $reflection->getMangledName() . "\n"; + echo " Visibility: " . ($reflection->isPublic() ? 'public' : ($reflection->isProtected() ? 'protected' : 'private')) . "\n"; + + $obj = new $class(); + $array = (array) $obj; + echo " Found in array cast: " . (array_key_exists($reflection->getMangledName(), $array) ? "yes" : "no") . "\n"; + echo "\n"; +} + +testPropertyOverride('Parent1', 'prop', 'Parent public property'); +testPropertyOverride('Child1', 'prop', 'Child public property (overrides parent public)'); + +testPropertyOverride('Parent1', 'protectedProp', 'Parent protected property'); +testPropertyOverride('Child1', 'protectedProp', 'Child public property (overrides parent protected)'); + +testPropertyOverride('Parent2', 'visibilityTest', 'Parent protected property'); +testPropertyOverride('Child2', 'visibilityTest', 'Child public property (overrides parent protected)'); + +testPropertyOverride('Parent1', 'privateProp', 'Parent private property'); + +echo "Child1 instance array keys:\n"; +$child1 = new Child1(); +$array = (array) $child1; +foreach (array_keys($array) as $key) { + echo " '$key'\n"; +} + +?> +--EXPECTF-- +Parent public property: + Class: Parent1 + Property: prop + getName(): prop + getMangledName(): prop + Visibility: public + Found in array cast: yes + +Child public property (overrides parent public): + Class: Child1 + Property: prop + getName(): prop + getMangledName(): prop + Visibility: public + Found in array cast: yes + +Parent protected property: + Class: Parent1 + Property: protectedProp + getName(): protectedProp + getMangledName(): %0*%0protectedProp + Visibility: protected + Found in array cast: yes + +Child public property (overrides parent protected): + Class: Child1 + Property: protectedProp + getName(): protectedProp + getMangledName(): protectedProp + Visibility: public + Found in array cast: yes + +Parent protected property: + Class: Parent2 + Property: visibilityTest + getName(): visibilityTest + getMangledName(): %0*%0visibilityTest + Visibility: protected + Found in array cast: yes + +Child public property (overrides parent protected): + Class: Child2 + Property: visibilityTest + getName(): visibilityTest + getMangledName(): visibilityTest + Visibility: public + Found in array cast: yes + +Parent private property: + Class: Parent1 + Property: privateProp + getName(): privateProp + getMangledName(): %0Parent1%0privateProp + Visibility: private + Found in array cast: yes + +Child1 instance array keys: + 'prop' + 'protectedProp' + '%0Parent1%0privateProp' diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_dynamic.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_dynamic.phpt new file mode 100644 index 000000000000..a4056a60555e --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_dynamic.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test ReflectionProperty::isReadable() dynamic +--FILE-- +a = 'a'; +$r = new ReflectionProperty($a, 'a'); + +var_dump($r->isReadable(null, $a)); +unset($a->a); +var_dump($r->isReadable(null, $a)); + +$a = new A; +var_dump($r->isReadable(null, $a)); + +var_dump($r->isReadable(null, null)); + +?> +--EXPECT-- +bool(true) +bool(false) +bool(false) +bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_hooks.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_hooks.phpt new file mode 100644 index 000000000000..5fc31b2163eb --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_hooks.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test ReflectionProperty::isReadable() hooks +--FILE-- + $this->a; } + public $b { get => 42; } + public $c { set => $value; } + public $d { set {} } + public $e { get => $this->e; set => $value; } + public $f { get {} set {} } +} + +function test($scope) { + $rc = new ReflectionClass(A::class); + foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from ' . ($scope ?? 'global') . ': '; + var_dump($rp->isReadable($scope, null)); + } +} + +test('A'); +test(null); + +?> +--EXPECT-- +a from A: bool(true) +b from A: bool(true) +c from A: bool(true) +d from A: bool(false) +e from A: bool(true) +f from A: bool(true) +a from global: bool(true) +b from global: bool(true) +c from global: bool(true) +d from global: bool(false) +e from global: bool(true) +f from global: bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_init.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_init.phpt new file mode 100644 index 000000000000..242f28b57a82 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_init.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test ReflectionProperty::isReadable() init +--FILE-- +e); + } +} + +class B { + public int $f; + public int $g; + public int $h; + + public function __construct() { + unset($this->g); + unset($this->h); + } + + public function __isset($name) { + return $name === 'h'; + } + + public function __get($name) {} +} + +class C { + public int $i; + public int $j; + public int $k; + + public function __construct() { + unset($this->j); + unset($this->k); + } + + public function __get($name) {} +} + +function test($class) { + $rc = new ReflectionClass($class); + foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from global: '; + var_dump($rp->isReadable(null, new $class)); + } +} + +test('A'); +test('B'); +test('C'); + +?> +--EXPECT-- +a from global: bool(true) +b from global: bool(false) +c from global: bool(true) +d from global: bool(false) +e from global: bool(false) +f from global: bool(false) +g from global: bool(false) +h from global: bool(true) +i from global: bool(false) +j from global: bool(true) +k from global: bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_invalid_scope.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_invalid_scope.phpt new file mode 100644 index 000000000000..ae9f446c6771 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_invalid_scope.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test ReflectionProperty::isReadable() invalid scope +--FILE-- +isReadable('B', null); +} catch (Error $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Error: Class "B" not found diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_lazy.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_lazy.phpt new file mode 100644 index 000000000000..214708cda6a1 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_lazy.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test ReflectionProperty::isReadable() lazy +--CREDITS-- +Arnaud Le Blanc (arnaud-lb) +--FILE-- +a = 1; + } +} + +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(fn() => new A()); + +$rp = new ReflectionProperty(A::class, 'a'); +var_dump($rp->isReadable(null, $obj)); + +$rp = new ReflectionProperty(A::class, 'b'); +var_dump($rp->isReadable(null, $obj)); + +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_lazy_dynamic.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_lazy_dynamic.phpt new file mode 100644 index 000000000000..a40b32f0abd9 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_lazy_dynamic.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test ReflectionProperty::isReadable() lazy dynamic +--CREDITS-- +Arnaud Le Blanc (arnaud-lb) +--FILE-- +prop = 1; + } +} + +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(fn() => new A()); + +$rp = new ReflectionProperty(new A, 'prop'); +var_dump($rp->isReadable(null, $obj)); + +?> +--EXPECT-- +bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_lazy_isset.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_lazy_isset.phpt new file mode 100644 index 000000000000..398c3311e499 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_lazy_isset.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test ReflectionProperty::isReadable() lazy isset +--CREDITS-- +Arnaud Le Blanc (arnaud-lb) +--FILE-- +prop = 1; + } + + public function __isset($name) { + return false; + } + + public function __get($name) { + return null; + } +} + +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(fn() => new A); + +$rp = new ReflectionProperty(new A, 'prop'); +var_dump($rp->isReadable(null, $obj)); + +?> +--EXPECT-- +bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_static.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_static.phpt new file mode 100644 index 000000000000..e927f428a1f8 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_static.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test ReflectionProperty::isReadable() static +--FILE-- +isReadable(null, new A); +} catch (Exception $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +$rc = new ReflectionClass('A'); +foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from global: '; + var_dump($rp->isReadable(null)); +} + +?> +--EXPECT-- +ReflectionException: null is expected as object argument for static properties +a from global: bool(true) +b from global: bool(false) +c from global: bool(true) +d from global: bool(false) +e from global: bool(false) +f from global: bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_unrelated_object.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_unrelated_object.phpt new file mode 100644 index 000000000000..ce48958c28ce --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_unrelated_object.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test ReflectionProperty::isReadable() unrelated object +--FILE-- +isReadable(null, $obj)); + } catch (Exception $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; + } +} + +test(new A); +test(new B); +test(new C); +test(new D); + +?> +--EXPECT-- +ReflectionException: Given object is not an instance of the class this property was declared in +bool(true) +bool(true) +ReflectionException: Given object is not an instance of the class this property was declared in diff --git a/ext/reflection/tests/ReflectionProperty_isReadable_visibility.phpt b/ext/reflection/tests/ReflectionProperty_isReadable_visibility.phpt new file mode 100644 index 000000000000..205ff85293ff --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isReadable_visibility.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test ReflectionProperty::isReadable() visibility +--FILE-- +getProperties() as $rp) { + echo $rp->getName() . ' from ' . ($scope ?? 'global') . ': '; + var_dump($rp->isReadable($scope, $scope && $scope !== 'A' ? new $scope : null)); + } +} + +foreach (['A', 'B', 'C', 'D', 'E'] as $scope) { + test($scope); +} +test(null); + +?> +--EXPECT-- +a from A: bool(true) +b from A: bool(true) +c from A: bool(false) +d from A: bool(true) +a from B: bool(true) +b from B: bool(true) +c from B: bool(true) +d from B: bool(true) +a from C: bool(true) +b from C: bool(true) +c from C: bool(false) +d from C: bool(true) +a from D: bool(true) +b from D: bool(true) +c from D: bool(true) +d from D: bool(true) +a from E: bool(true) +b from E: bool(true) +c from E: bool(false) +d from E: bool(true) +a from global: bool(true) +b from global: bool(false) +c from global: bool(false) +d from global: bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_dynamic.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_dynamic.phpt new file mode 100644 index 000000000000..e9da6675ddae --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_dynamic.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test ReflectionProperty::isWritable() dynamic +--FILE-- +isWritable(null, $a)); +var_dump($r->isWritable(null, null)); + +$a->b = 'b'; +$r = new ReflectionProperty($a, 'b'); +var_dump($r->isWritable(null, $a)); + +$a = new A; +var_dump($r->isWritable(null, $a)); + +var_dump($r->isWritable(null, null)); + +?> +--EXPECT-- +bool(false) +bool(false) +bool(true) +bool(true) +bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_hooks.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_hooks.phpt new file mode 100644 index 000000000000..2617ec65b9e7 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_hooks.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test ReflectionProperty::isWritable() visibility +--FILE-- + $this->a; } + public $b { get => 42; } + public $c { set => $value; } + public $d { set {} } + public $e { get => $this->e; set => $value; } + public $f { get {} set {} } +} + +function test($scope) { + $rc = new ReflectionClass(A::class); + foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from ' . ($scope ?? 'global') . ': '; + var_dump($rp->isWritable($scope, null)); + } +} + +test('A'); +test(null); + +?> +--EXPECT-- +a from A: bool(true) +b from A: bool(false) +c from A: bool(true) +d from A: bool(true) +e from A: bool(true) +f from A: bool(true) +a from global: bool(true) +b from global: bool(false) +c from global: bool(true) +d from global: bool(true) +e from global: bool(true) +f from global: bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_invalid_scope.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_invalid_scope.phpt new file mode 100644 index 000000000000..7474e521b35e --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_invalid_scope.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test ReflectionProperty::isWritable() invalid scope +--FILE-- +isWritable('B', null); +} catch (Error $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Error: Class "B" not found diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_lazy.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_lazy.phpt new file mode 100644 index 000000000000..91f305fef8af --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_lazy.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test ReflectionProperty::isWritable() lazy +--CREDITS-- +Arnaud Le Blanc (arnaud-lb) +--FILE-- +a = 1; + } +} + +$rc = new ReflectionClass(A::class); +$obj = $rc->newLazyProxy(fn() => new A()); + +$rp = new ReflectionProperty(A::class, 'a'); +var_dump($rp->isWritable(null, $obj)); + +$rp = new ReflectionProperty(A::class, 'b'); +var_dump($rp->isWritable(null, $obj)); + +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_readonly.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_readonly.phpt new file mode 100644 index 000000000000..256f14895908 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_readonly.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test ReflectionProperty::isWritable() readonly +--FILE-- +a = 42; + } + + public function __clone() { + test($this); + $this->a = 43; + test($this); + } +} + +function test($instance) { + $rc = new ReflectionClass($instance); + foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from A: '; + var_dump($rp->isWritable($instance::class, $instance)); + } +} + +test(new A); +clone new A; + +?> +--EXPECT-- +a from A: bool(false) +b from A: bool(true) +a from A: bool(true) +b from A: bool(true) +a from A: bool(false) +b from A: bool(true) diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_static.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_static.phpt new file mode 100644 index 000000000000..008d585c3153 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_static.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test ReflectionProperty::isWritable() static +--FILE-- +isWritable(null, new A); +} catch (Exception $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +$rc = new ReflectionClass('A'); +foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from global: '; + var_dump($rp->isWritable(null)); +} + +?> +--EXPECT-- +ReflectionException: null is expected as object argument for static properties +a from global: bool(true) +b from global: bool(true) +c from global: bool(true) +d from global: bool(false) +e from global: bool(false) +f from global: bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_unrelated_object.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_unrelated_object.phpt new file mode 100644 index 000000000000..3e1e6a394c8f --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_unrelated_object.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test ReflectionProperty::isWritable() unrelated object +--FILE-- +isWritable(null, $obj)); + } catch (Exception $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; + } +} + +test(new A); +test(new B); +test(new C); +test(new D); + +?> +--EXPECT-- +ReflectionException: Given object is not an instance of the class this property was declared in +bool(true) +bool(true) +ReflectionException: Given object is not an instance of the class this property was declared in diff --git a/ext/reflection/tests/ReflectionProperty_isWritable_visibility.phpt b/ext/reflection/tests/ReflectionProperty_isWritable_visibility.phpt new file mode 100644 index 000000000000..1585f4cba531 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_isWritable_visibility.phpt @@ -0,0 +1,68 @@ +--TEST-- +Test ReflectionProperty::isWritable() visibility +--FILE-- +getProperties() as $rp) { + echo $rp->getName() . ' from ' . ($scope ?? 'global') . ': '; + var_dump($rp->isWritable($scope, $scope && $scope !== 'A' ? new $scope : null)); + } +} + +test('A'); +test('B'); +test('C'); +test('D'); +test(null); + +?> +--EXPECT-- +a from A: bool(true) +b from A: bool(true) +c from A: bool(false) +d from A: bool(false) +e from A: bool(true) +f from A: bool(true) +a from B: bool(true) +b from B: bool(true) +c from B: bool(true) +d from B: bool(true) +e from B: bool(true) +f from B: bool(true) +a from C: bool(true) +b from C: bool(true) +c from C: bool(false) +d from C: bool(false) +e from C: bool(true) +f from C: bool(true) +a from D: bool(true) +b from D: bool(true) +c from D: bool(true) +d from D: bool(false) +e from D: bool(true) +f from D: bool(true) +a from global: bool(true) +b from global: bool(false) +c from global: bool(false) +d from global: bool(false) +e from global: bool(false) +f from global: bool(false) diff --git a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt index 4e12af87916f..5ccc1366060b 100644 --- a/ext/reflection/tests/ReflectionProperty_setAccessible.phpt +++ b/ext/reflection/tests/ReflectionProperty_setAccessible.phpt @@ -95,6 +95,14 @@ string(1) "e" string(1) "f" string(1) "g" string(1) "h" + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d string(1) "e" string(1) "f" string(1) "g" @@ -111,6 +119,12 @@ string(1) "c" string(1) "e" string(1) "f" string(1) "g" + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d + +Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in %s on line %d string(1) "e" string(1) "f" string(1) "g" diff --git a/ext/reflection/tests/ReflectionProperty_toString_001.phpt b/ext/reflection/tests/ReflectionProperty_toString_001.phpt new file mode 100644 index 000000000000..0af0283bb506 --- /dev/null +++ b/ext/reflection/tests/ReflectionProperty_toString_001.phpt @@ -0,0 +1,89 @@ +--TEST-- +Using ReflectionProperty::__toString() with hooked properties (GH-17927) +--FILE-- + "always this string"; + } + public mixed $setOnly { + set => strtolower($value); + } + public mixed $both { + get => $this->prop3; + set => strtolower($value); + } +} +class WithFinalHooks { + public mixed $getOnly { + final get => "always this string"; + } + public mixed $setOnly { + final set => strtolower($value); + } + public mixed $both { + final get => $this->prop3; + final set => strtolower($value); + } +} +class WithMixedHooks { + public mixed $getIsFinal { + final get => "always this string"; + set => strtolower($value); + } + public mixed $setIsFinal { + get => $this->setIsFinal; + final set => strtolower($value); + } +} +$classes = [ + IHookedDemo::class, + HookedDemo::class, + WithHooks::class, + WithFinalHooks::class, + WithMixedHooks::class, +]; +foreach ( $classes as $clazz ) { + echo "$clazz:\n"; + $ref = new ReflectionClass( $clazz ); + foreach ( $ref->getProperties() as $prop ) { + echo $prop; + } + echo "\n"; +} +?> +--EXPECT-- +IHookedDemo: +Property [ abstract public virtual mixed $getOnly { get; } ] +Property [ abstract public virtual mixed $setOnly { set; } ] +Property [ abstract public virtual mixed $both { get; set; } ] + +HookedDemo: +Property [ abstract public virtual mixed $getOnly { get; } ] +Property [ abstract public virtual mixed $setOnly { set; } ] +Property [ abstract public virtual mixed $both { get; set; } ] + +WithHooks: +Property [ public virtual mixed $getOnly { get; } ] +Property [ public mixed $setOnly { set; } ] +Property [ public mixed $both { get; set; } ] + +WithFinalHooks: +Property [ public virtual mixed $getOnly { final get; } ] +Property [ public mixed $setOnly { final set; } ] +Property [ public mixed $both { final get; final set; } ] + +WithMixedHooks: +Property [ public mixed $getIsFinal { final get; set; } ] +Property [ public mixed $setIsFinal { get; final set; } ] diff --git a/ext/reflection/tests/ReflectionZendExtension.phpt b/ext/reflection/tests/ReflectionZendExtension.phpt index c9c8f18cf553..a9825ff78abc 100644 --- a/ext/reflection/tests/ReflectionZendExtension.phpt +++ b/ext/reflection/tests/ReflectionZendExtension.phpt @@ -14,8 +14,8 @@ var_dump($reflection->getURL()); var_dump($reflection->getVersion() === PHP_VERSION); ?> --EXPECT-- -string(17) "Zend Technologies" -string(13) "Copyright (c)" +string(16) "Zend by Perforce" +string(12) "Copyright ©" string(12) "Zend OPcache" -string(20) "http://www.zend.com/" +string(21) "https://www.zend.com/" bool(true) diff --git a/ext/reflection/tests/Reflection_getModifierNames_001.phpt b/ext/reflection/tests/Reflection_getModifierNames_001.phpt index 918ef2f28000..78ba327df6f5 100644 --- a/ext/reflection/tests/Reflection_getModifierNames_001.phpt +++ b/ext/reflection/tests/Reflection_getModifierNames_001.phpt @@ -15,6 +15,8 @@ printModifiers(ReflectionMethod::IS_ABSTRACT | ReflectionMethod::IS_FINAL); printModifiers(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_STATIC | ReflectionProperty::IS_READONLY); printModifiers(ReflectionClass::IS_READONLY); printModifiers(ReflectionProperty::IS_VIRTUAL); +printModifiers(ReflectionProperty::IS_PROTECTED_SET); +printModifiers(ReflectionProperty::IS_PRIVATE_SET); ?> --EXPECT-- private @@ -25,3 +27,5 @@ abstract,final public,static,readonly readonly virtual +protected(set) +private(set) diff --git a/ext/reflection/tests/abstract_property_indicated.phpt b/ext/reflection/tests/abstract_property_indicated.phpt index a70d88b7ece2..23866be890d5 100644 --- a/ext/reflection/tests/abstract_property_indicated.phpt +++ b/ext/reflection/tests/abstract_property_indicated.phpt @@ -31,12 +31,12 @@ Class [ abstract class Demo ] { } - Properties [2] { - Property [ abstract public $a ] + Property [ abstract public virtual $a { get; } ] Property [ public $b = NULL ] } - Methods [0] { } } -Property [ abstract public $a ] +Property [ abstract public virtual $a { get; } ] Property [ public $b = NULL ] diff --git a/ext/reflection/tests/bug38653.phpt b/ext/reflection/tests/bug38653.phpt index 36504e7c7b66..e166546eeb9a 100644 --- a/ext/reflection/tests/bug38653.phpt +++ b/ext/reflection/tests/bug38653.phpt @@ -20,9 +20,11 @@ var_dump($foo->getConstant("no such const")); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- int(10) string(0) "" string(4) "test" + +Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists in %s on line %d bool(false) Done diff --git a/ext/reflection/tests/bug79683.phpt b/ext/reflection/tests/bug79683.phpt index 766571918afb..4eeafb6bb930 100644 --- a/ext/reflection/tests/bug79683.phpt +++ b/ext/reflection/tests/bug79683.phpt @@ -22,7 +22,6 @@ $b = new B(); $reflector = new ReflectionClass($b); $property = $reflector->getProperty('prop2'); -$property->setAccessible(true); $property->setValue($b, new A()); var_dump($b); diff --git a/ext/reflection/tests/generics/ancestor_args_composite.phpt b/ext/reflection/tests/generics/ancestor_args_composite.phpt new file mode 100644 index 000000000000..dbd45bd29c6a --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_composite.phpt @@ -0,0 +1,19 @@ +--TEST-- +Reflection: composite (union/intersection) type args inside extends/implements +--FILE-- + {} + +class C extends Pair {} + +$args = (new ReflectionClass('C'))->getGenericArgumentsForParentClass(); +echo "count: ", count($args), "\n"; +echo "[0] kind: ", get_class($args[0]), "\n"; +echo "[1] kind: ", get_class($args[1]), "\n"; +?> +--EXPECT-- +count: 2 +[0] kind: ReflectionUnionType +[1] kind: ReflectionIntersectionType diff --git a/ext/reflection/tests/generics/ancestor_args_duplicate_bindings.phpt b/ext/reflection/tests/generics/ancestor_args_duplicate_bindings.phpt new file mode 100644 index 000000000000..0135912d4cf5 --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_duplicate_bindings.phpt @@ -0,0 +1,64 @@ +--TEST-- +Reflection: getGenericArgumentsForParentInterface lists every binding when the same interface is bound more than once +--FILE-- + {} +interface Bar {} +interface Baz extends Bar {} + +interface DA<+T> {} +interface I1 extends DA {} +interface I2 extends DA {} + +class Box {} + +class DirectDup implements Foo, Foo {} + +class MixedDup implements Bar, Baz {} + +class ParentDup implements Foo, Foo {} +class ChildDup extends ParentDup {} + +class NestedDup implements Foo>, Foo> {} + +class DiamondVar implements I1, I2 {} + +function render(array $bindings): string { + return '[' . implode(', ', array_map( + static fn(array $b): string => '[' . implode(', ', array_map( + static function (ReflectionType $t): string { + if ($t instanceof ReflectionNamedType && $t->hasGenericArguments()) { + return $t->getName() . '<' . implode(', ', array_map( + static fn(ReflectionType $inner): string => $inner->getName(), + $t->getGenericArguments(), + )) . '>'; + } + return $t->getName(); + }, + $b, + )) . ']', + $bindings, + )) . ']'; +} + +function show(string $cls, string $ancestor): void { + $bindings = (new ReflectionClass($cls))->getGenericArgumentsForParentInterface($ancestor); + printf("%-12s -> %-5s = %s (count=%d)\n", $cls, $ancestor, render($bindings), count($bindings)); +} + +show('DirectDup', 'Foo'); +show('MixedDup', 'Bar'); +show('ChildDup', 'Foo'); +show('NestedDup', 'Foo'); +show('DiamondVar', 'DA'); + +class Single implements Foo {} +show('Single', 'Foo'); +?> +--EXPECT-- +DirectDup -> Foo = [[string], [int]] (count=2) +MixedDup -> Bar = [[string], [int]] (count=2) +ChildDup -> Foo = [[bool], [float]] (count=2) +NestedDup -> Foo = [[Box], [Box]] (count=2) +DiamondVar -> DA = [[int], [string]] (count=2) +Single -> Foo = [[int]] (count=1) diff --git a/ext/reflection/tests/generics/ancestor_args_nested.phpt b/ext/reflection/tests/generics/ancestor_args_nested.phpt new file mode 100644 index 000000000000..0cc893d12a4d --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_nested.phpt @@ -0,0 +1,41 @@ +--TEST-- +Reflection: nested generic arguments inside extends/implements/use are preserved +--FILE-- + {} +class Pair {} +interface I {} +trait T1 { public function noop(): void {} } + +class WithNested + extends Pair, string> + implements I> +{ + use T1>; +} + +$rc = new ReflectionClass('WithNested'); + +// Nested in extends +$args = $rc->getGenericArgumentsForParentClass(); +echo "parent[0]: ", $args[0]->getName(); +echo "<", $args[0]->getGenericArguments()[0]->getName(), ">\n"; +echo "parent[1]: ", $args[1]->getName(), "\n"; + +// Nested in implements +$bindings = $rc->getGenericArgumentsForParentInterface('I'); +echo "I bindings: ", count($bindings), "\n"; +echo "I[0][0]: ", $bindings[0][0]->getName(); +echo "<", $bindings[0][0]->getGenericArguments()[0]->getName(), ">\n"; + +// Nested in use +$args = $rc->getGenericArgumentsForUsedTrait('T1'); +echo "T1[0]: ", $args[0]->getName(); +echo "<", $args[0]->getGenericArguments()[0]->getName(), ">\n"; +?> +--EXPECT-- +parent[0]: Box +parent[1]: string +I bindings: 1 +I[0][0]: Box +T1[0]: Box diff --git a/ext/reflection/tests/generics/ancestor_args_nested_transitive.phpt b/ext/reflection/tests/generics/ancestor_args_nested_transitive.phpt new file mode 100644 index 000000000000..361f93a39019 --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_nested_transitive.phpt @@ -0,0 +1,49 @@ +--TEST-- +Reflection: transitive parent interface arguments substitute nested type parameters +--FILE-- + {} +interface Root {} +interface PairRoot {} +interface Mid extends Root> {} +interface Flip extends PairRoot, Box> {} + +class Concrete implements Mid {} +class Forwarded implements Mid {} +class Reordered implements Flip {} + +function show(string $class, string $interface): void { + $bindings = (new ReflectionClass($class))->getGenericArgumentsForParentInterface($interface); + echo "$class/$interface (", count($bindings), " binding)\n"; + foreach ($bindings as $args) { + foreach ($args as $arg) { + echo " ", $arg->getName(); + if ($arg instanceof ReflectionNamedType && $arg->hasGenericArguments()) { + echo "<", implode(", ", array_map( + static fn(ReflectionType $type): string => $type->getName(), + $arg->getGenericArguments(), + )), ">"; + } + echo "\n"; + } + } +} + +show(Concrete::class, Root::class); +show(Forwarded::class, Root::class); +show(Reordered::class, PairRoot::class); + +$forwardedBindings = (new ReflectionClass(Forwarded::class))->getGenericArgumentsForParentInterface(Root::class); +$forwardedInner = $forwardedBindings[0][0]->getGenericArguments()[0]; +echo "Forwarded nested parameter owner: ", + $forwardedInner->getTypeParameter()->getDeclaringEntity()->getName(), "\n"; +?> +--EXPECT-- +Concrete/Root (1 binding) + Box +Forwarded/Root (1 binding) + Box +Reordered/PairRoot (1 binding) + Box + Box +Forwarded nested parameter owner: Forwarded diff --git a/ext/reflection/tests/generics/ancestor_args_no_generics_class.phpt b/ext/reflection/tests/generics/ancestor_args_no_generics_class.phpt new file mode 100644 index 000000000000..b446b8b01789 --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_no_generics_class.phpt @@ -0,0 +1,47 @@ +--TEST-- +Reflection: classes with no generic content — empty array when ancestor without args, throw when not an ancestor +--FILE-- +getGenericArgumentsForParentClass(); + echo $cls, ": parent=", json_encode($p); + } catch (ReflectionException $e) { + echo $cls, ": parent=throw(", $e->getMessage(), ")"; + } + + try { + $i = $rc->getGenericArgumentsForParentInterface('IPlain'); + echo " iface=", json_encode($i); + } catch (ReflectionException $e) { + echo " iface=throw(", $e->getMessage(), ")"; + } + + try { + $t = $rc->getGenericArgumentsForUsedTrait('TPlain'); + echo " trait=", json_encode($t); + } catch (ReflectionException $e) { + echo " trait=throw(", $e->getMessage(), ")"; + } + + echo "\n"; +} + +foreach (['Plain', 'WithParent', 'WithIface', 'WithTrait'] as $cls) { + show($cls); +} +?> +--EXPECT-- +Plain: parent=throw(Class Plain has no parent class) iface=throw(IPlain is not an ancestor interface of Plain) trait=throw(TPlain is not a trait used by Plain) +WithParent: parent=[] iface=throw(IPlain is not an ancestor interface of WithParent) trait=throw(TPlain is not a trait used by WithParent) +WithIface: parent=throw(Class WithIface has no parent class) iface=[] trait=throw(TPlain is not a trait used by WithIface) +WithTrait: parent=throw(Class WithTrait has no parent class) iface=throw(IPlain is not an ancestor interface of WithTrait) trait=[] diff --git a/ext/reflection/tests/generics/ancestor_args_parent_class.phpt b/ext/reflection/tests/generics/ancestor_args_parent_class.phpt new file mode 100644 index 000000000000..16a3f48264cf --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_parent_class.phpt @@ -0,0 +1,39 @@ +--TEST-- +Reflection: getGenericArgumentsForParentClass returns args from extends clause, throws when no parent +--FILE-- + {} +class B {} + +class WithArgs extends A {} +class NoArgs extends A {} +class NoParent {} +class Multi extends B {} + +$cases = [ + 'WithArgs' => ['string'], + 'NoArgs' => [], + 'NoParent' => 'throw', + 'Multi' => ['int', 'float'], +]; + +foreach ($cases as $cls => $want) { + try { + $args = (new ReflectionClass($cls))->getGenericArgumentsForParentClass(); + } catch (ReflectionException $e) { + echo $cls, ": ", $want === 'throw' ? "throw OK ({$e->getMessage()})" : "FAIL (unexpected throw)", "\n"; + continue; + } + if ($want === 'throw') { + echo $cls, ": FAIL (expected throw)\n"; + } else { + $got = array_map(fn($t) => $t->getName(), $args); + echo $cls, ": ", $got === $want ? "OK" : ("FAIL got " . implode(",", $got)), "\n"; + } +} +?> +--EXPECT-- +WithArgs: OK +NoArgs: OK +NoParent: throw OK (Class NoParent has no parent class) +Multi: OK diff --git a/ext/reflection/tests/generics/ancestor_args_parent_interface.phpt b/ext/reflection/tests/generics/ancestor_args_parent_interface.phpt new file mode 100644 index 000000000000..7d561cc24f08 --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_parent_interface.phpt @@ -0,0 +1,59 @@ +--TEST-- +Reflection: getGenericArgumentsForParentInterface returns every binding to the ancestor interface; throws when not ancestor +--FILE-- + {} +interface J {} +interface K1 extends I {} +interface Forward extends J {} + +class WithArgs implements I {} +class WithoutArgs implements I {} +class NotImplements {} +class Multi implements I, J {} +class ViaK1 implements K1 {} +class ViaForward implements Forward {} +class ChildWithArgs extends WithArgs {} + +function render(array $bindings): string { + return '[' . implode(', ', array_map( + static fn(array $b): string => '[' . implode(',', array_map( + static fn(ReflectionType $t): string => $t->getName(), + $b, + )) . ']', + $bindings, + )) . ']'; +} + +function show(string $cls, string $iface): void { + try { + $bindings = (new ReflectionClass($cls))->getGenericArgumentsForParentInterface($iface); + } catch (ReflectionException $e) { + echo "$cls/$iface: throw ({$e->getMessage()})\n"; + return; + } + echo "$cls/$iface: ", render($bindings), "\n"; +} + +show('WithArgs', 'I'); +show('WithArgs', 'i'); // case insensitive +show('WithoutArgs', 'I'); +show('NotImplements', 'I'); +show('Multi', 'I'); +show('Multi', 'J'); +show('K1', 'I'); +show('ViaK1', 'I'); +show('ViaForward', 'J'); +show('ChildWithArgs', 'I'); +?> +--EXPECT-- +WithArgs/I: [[int,string]] +WithArgs/i: [[int,string]] +WithoutArgs/I: [] +NotImplements/I: throw (I is not an ancestor interface of NotImplements) +Multi/I: [[bool,float]] +Multi/J: [[string]] +K1/I: [[int,string]] +ViaK1/I: [[int,string]] +ViaForward/J: [[bool]] +ChildWithArgs/I: [[int,string]] diff --git a/ext/reflection/tests/generics/ancestor_args_transitive_paths.phpt b/ext/reflection/tests/generics/ancestor_args_transitive_paths.phpt new file mode 100644 index 000000000000..95e4a8839da4 --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_transitive_paths.phpt @@ -0,0 +1,77 @@ +--TEST-- +Reflection: getGenericArgumentsForParentInterface composes substitutions through transitive paths and exposes every diamond binding +--FILE-- + {} +interface Mid extends Root {} +interface DeepRoot {} +interface DeepMid extends DeepRoot {} +interface DeepLeaf extends DeepMid {} + +class FwdGeneric implements Mid {} + +class ConcreteThroughGeneric implements Mid {} + +class DeepFwd implements DeepLeaf {} + +class WithIfaceArgs implements Root {} +class ChildOfBound extends WithIfaceArgs {} +class GrandchildOfBound extends ChildOfBound {} + +class ForwardingChild extends WithIfaceArgs {} + +class BaseViaMid implements Mid {} +class ChildViaMid extends BaseViaMid {} + +interface Leaf extends Mid {} + +interface DA<+T> {} +interface I1 extends DA {} +interface I2 extends DA {} +class Diamond implements I1, I2 {} + +function render(array $bindings): string { + return '[' . implode(', ', array_map( + static fn(array $b): string => '[' . implode(', ', array_map( + static fn(ReflectionType $t): string => (string) $t, + $b, + )) . ']', + $bindings, + )) . ']'; +} + +function show(string $cls, string $ancestor): void { + $bindings = (new ReflectionClass($cls))->getGenericArgumentsForParentInterface($ancestor); + printf("%-30s -> %-10s = %s\n", $cls, $ancestor, render($bindings)); +} + +show('FwdGeneric', 'Root'); +show('FwdGeneric', 'Mid'); +show('ConcreteThroughGeneric', 'Root'); +show('DeepFwd', 'DeepRoot'); +show('DeepFwd', 'DeepMid'); +show('DeepFwd', 'DeepLeaf'); +show('ChildOfBound', 'Root'); +show('GrandchildOfBound', 'Root'); +show('ForwardingChild', 'Root'); +show('ChildViaMid', 'Root'); +show('ChildViaMid', 'Mid'); +show('Leaf', 'Root'); +show('Diamond', 'DA'); + +?> +--EXPECT-- +FwdGeneric -> Root = [[U]] +FwdGeneric -> Mid = [[U]] +ConcreteThroughGeneric -> Root = [[int]] +DeepFwd -> DeepRoot = [[U]] +DeepFwd -> DeepMid = [[U]] +DeepFwd -> DeepLeaf = [[U]] +ChildOfBound -> Root = [[int]] +GrandchildOfBound -> Root = [[int]] +ForwardingChild -> Root = [[V]] +ChildViaMid -> Root = [[string]] +ChildViaMid -> Mid = [[string]] +Leaf -> Root = [[bool]] +Diamond -> DA = [[int], [string]] diff --git a/ext/reflection/tests/generics/ancestor_args_type_param_refs.phpt b/ext/reflection/tests/generics/ancestor_args_type_param_refs.phpt new file mode 100644 index 000000000000..c75cdf2a359c --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_type_param_refs.phpt @@ -0,0 +1,26 @@ +--TEST-- +Reflection: type-parameter references inside extends/implements args resolve correctly +--FILE-- + {} +class Holder implements Container {} + +$rc = new ReflectionClass('Holder'); +$bindings = $rc->getGenericArgumentsForParentInterface('Container'); + +echo "bindings: ", count($bindings), "\n"; +echo "args in binding 0: ", count($bindings[0]), "\n"; +echo "class: ", get_class($bindings[0][0]), "\n"; +echo "name: ", $bindings[0][0]->getName(), "\n"; + +$param = $bindings[0][0]->getTypeParameter(); +echo "type param: ", $param->getName(), "\n"; +echo "declaring: ", $param->getDeclaringEntity()->getName(), "\n"; +?> +--EXPECT-- +bindings: 1 +args in binding 0: 1 +class: ReflectionTypeParameterReference +name: T +type param: T +declaring: Holder diff --git a/ext/reflection/tests/generics/ancestor_args_used_trait.phpt b/ext/reflection/tests/generics/ancestor_args_used_trait.phpt new file mode 100644 index 000000000000..322e0066061d --- /dev/null +++ b/ext/reflection/tests/generics/ancestor_args_used_trait.phpt @@ -0,0 +1,46 @@ +--TEST-- +Reflection: getGenericArgumentsForUsedTrait returns args from use clause; throws when trait not used +--FILE-- + { public T $val; } +trait Pair { public K $k; public V $v; } +trait Plain { public int $x; } + +class WithArgs { use Holder; } +class NoArgs { use Holder; } +class NoTrait {} +class Multi { use Holder, Pair; } +class Combo { use Holder, Plain; } + +function show(string $cls, string $tr): void { + try { + $args = (new ReflectionClass($cls))->getGenericArgumentsForUsedTrait($tr); + } catch (ReflectionException $e) { + echo "$cls/$tr: throw ({$e->getMessage()})\n"; + return; + } + if (!$args) { + echo "$cls/$tr: []\n"; + return; + } + echo "$cls/$tr: ", implode(",", array_map(fn($t)=>$t->getName(), $args)), "\n"; +} + +show('WithArgs', 'Holder'); +show('NoArgs', 'Holder'); +show('NoTrait', 'Holder'); +show('Multi', 'Holder'); +show('Multi', 'Pair'); +show('Combo', 'Holder'); +show('Combo', 'Plain'); +show('Combo', 'holder'); // case insensitive +?> +--EXPECT-- +WithArgs/Holder: string +NoArgs/Holder: [] +NoTrait/Holder: throw (Holder is not a trait used by NoTrait) +Multi/Holder: bool +Multi/Pair: int,float +Combo/Holder: string +Combo/Plain: [] +Combo/holder: string diff --git a/ext/reflection/tests/generics/arrow_fn_get_generic_params.phpt b/ext/reflection/tests/generics/arrow_fn_get_generic_params.phpt new file mode 100644 index 000000000000..829cdaaa8d2f --- /dev/null +++ b/ext/reflection/tests/generics/arrow_fn_get_generic_params.phpt @@ -0,0 +1,14 @@ +--TEST-- +Reflection: getGenericParameters on arrow function +--FILE-- +(T $x): T => $x; +$r = new ReflectionFunction($f); +echo $r->isGeneric() ? "gen\n" : "not\n"; +echo $r->getGenericParameters()[0]->getName(), "\n"; +echo $r->getGenericParameters()[0]->getBound()->getName(), "\n"; +?> +--EXPECT-- +gen +T +int diff --git a/ext/reflection/tests/generics/class_isgeneric_false.phpt b/ext/reflection/tests/generics/class_isgeneric_false.phpt new file mode 100644 index 000000000000..52f5ce8130d1 --- /dev/null +++ b/ext/reflection/tests/generics/class_isgeneric_false.phpt @@ -0,0 +1,9 @@ +--TEST-- +Reflection: ReflectionClass::isGeneric() returns false for non-generic class +--FILE-- +isGeneric()); +?> +--EXPECT-- +bool(false) diff --git a/ext/reflection/tests/generics/class_isgeneric_true.phpt b/ext/reflection/tests/generics/class_isgeneric_true.phpt new file mode 100644 index 000000000000..82eaeaec2247 --- /dev/null +++ b/ext/reflection/tests/generics/class_isgeneric_true.phpt @@ -0,0 +1,9 @@ +--TEST-- +Reflection: ReflectionClass::isGeneric() returns true for generic class +--FILE-- + {} +var_dump((new ReflectionClass('G'))->isGeneric()); +?> +--EXPECT-- +bool(true) diff --git a/ext/reflection/tests/generics/closure_get_generic_params.phpt b/ext/reflection/tests/generics/closure_get_generic_params.phpt new file mode 100644 index 000000000000..8a133191fe72 --- /dev/null +++ b/ext/reflection/tests/generics/closure_get_generic_params.phpt @@ -0,0 +1,16 @@ +--TEST-- +Reflection: getGenericParameters on closure +--FILE-- +(T $x): T { return $x; }; +$r = new ReflectionFunction($cl); +echo $r->isGeneric() ? "gen\n" : "not\n"; +echo count($r->getGenericParameters()), "\n"; +echo $r->getGenericParameters()[0]->getName(), "\n"; +echo $r->getGenericParameters()[0]->getBound()->getName(), "\n"; +?> +--EXPECT-- +gen +1 +T +object diff --git a/ext/reflection/tests/generics/composite_bound.phpt b/ext/reflection/tests/generics/composite_bound.phpt new file mode 100644 index 000000000000..c28ae671d2ad --- /dev/null +++ b/ext/reflection/tests/generics/composite_bound.phpt @@ -0,0 +1,12 @@ +--TEST-- +Reflection: composite (union) bound returned +--FILE-- +(T $x): T { return $x; } +$p = (new ReflectionFunction('f'))->getGenericParameters()[0]; +$b = $p->getBound(); +echo get_class($b), "\n"; +?> +--EXPECT-- +ReflectionUnionType diff --git a/ext/reflection/tests/generics/composite_type_arg.phpt b/ext/reflection/tests/generics/composite_type_arg.phpt new file mode 100644 index 000000000000..a482246b9306 --- /dev/null +++ b/ext/reflection/tests/generics/composite_type_arg.phpt @@ -0,0 +1,14 @@ +--TEST-- +Reflection: composite type as generic argument +--FILE-- + {} +function f(Pair $x): void {} +$pt = (new ReflectionFunction('f'))->getParameters()[0]->getType(); +$args = $pt->getGenericArguments(); +echo get_class($args[0]), "\n"; +echo get_class($args[1]), "\n"; +?> +--EXPECT-- +ReflectionUnionType +ReflectionIntersectionType diff --git a/ext/reflection/tests/generics/function_isgeneric.phpt b/ext/reflection/tests/generics/function_isgeneric.phpt new file mode 100644 index 000000000000..93998269ea55 --- /dev/null +++ b/ext/reflection/tests/generics/function_isgeneric.phpt @@ -0,0 +1,12 @@ +--TEST-- +Reflection: ReflectionFunction::isGeneric() +--FILE-- +(): void {} +function plain(): void {} +var_dump((new ReflectionFunction('gen'))->isGeneric()); +var_dump((new ReflectionFunction('plain'))->isGeneric()); +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/reflection/tests/generics/get_generic_parameters_count.phpt b/ext/reflection/tests/generics/get_generic_parameters_count.phpt new file mode 100644 index 000000000000..2f9341e4eace --- /dev/null +++ b/ext/reflection/tests/generics/get_generic_parameters_count.phpt @@ -0,0 +1,16 @@ +--TEST-- +Reflection: getGenericParameters returns correct count +--FILE-- + {} +$ps = (new ReflectionClass('A'))->getGenericParameters(); +echo count($ps), "\n"; +echo $ps[0]->getName(), "\n"; +echo $ps[1]->getName(), "\n"; +echo $ps[2]->getName(), "\n"; +?> +--EXPECT-- +3 +X +Y +Z diff --git a/ext/reflection/tests/generics/get_generic_parameters_empty.phpt b/ext/reflection/tests/generics/get_generic_parameters_empty.phpt new file mode 100644 index 000000000000..987c0ef16e15 --- /dev/null +++ b/ext/reflection/tests/generics/get_generic_parameters_empty.phpt @@ -0,0 +1,14 @@ +--TEST-- +Reflection: getGenericParameters on non-generic returns empty array +--FILE-- +getGenericParameters()); +var_dump((new ReflectionFunction('f'))->getGenericParameters()); +?> +--EXPECT-- +array(0) { +} +array(0) { +} diff --git a/ext/reflection/tests/generics/method_get_generic_params.phpt b/ext/reflection/tests/generics/method_get_generic_params.phpt new file mode 100644 index 000000000000..72f019cde580 --- /dev/null +++ b/ext/reflection/tests/generics/method_get_generic_params.phpt @@ -0,0 +1,16 @@ +--TEST-- +Reflection: method type parameters separate from class type parameters +--FILE-- + { + public function f(): void {} +} +$rc = new ReflectionClass('C'); +$class_ps = $rc->getGenericParameters(); +$method_ps = $rc->getMethod('f')->getGenericParameters(); +echo count($class_ps), ": ", $class_ps[0]->getName(), "\n"; +echo count($method_ps), ": ", $method_ps[0]->getName(), "\n"; +?> +--EXPECT-- +1: X +1: U diff --git a/ext/reflection/tests/generics/method_isgeneric.phpt b/ext/reflection/tests/generics/method_isgeneric.phpt new file mode 100644 index 000000000000..ad2014844029 --- /dev/null +++ b/ext/reflection/tests/generics/method_isgeneric.phpt @@ -0,0 +1,14 @@ +--TEST-- +Reflection: ReflectionMethod::isGeneric() +--FILE-- +(): void {} + public function plain(): void {} +} +var_dump((new ReflectionClass('C'))->getMethod('gen')->isGeneric()); +var_dump((new ReflectionClass('C'))->getMethod('plain')->isGeneric()); +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/reflection/tests/generics/named_type_get_name_erased.phpt b/ext/reflection/tests/generics/named_type_get_name_erased.phpt new file mode 100644 index 000000000000..91a12296d97c --- /dev/null +++ b/ext/reflection/tests/generics/named_type_get_name_erased.phpt @@ -0,0 +1,13 @@ +--TEST-- +Reflection: ReflectionNamedType::getName() returns the reified name with type arguments +--FILE-- + {} +function f(Box $x): Box { return $x; } +$r = new ReflectionFunction('f'); +echo $r->getParameters()[0]->getType()->getName(), "\n"; +echo $r->getReturnType()->getName(), "\n"; +?> +--EXPECT-- +Box +Box diff --git a/ext/reflection/tests/generics/named_type_has_args.phpt b/ext/reflection/tests/generics/named_type_has_args.phpt new file mode 100644 index 000000000000..d3e18b456259 --- /dev/null +++ b/ext/reflection/tests/generics/named_type_has_args.phpt @@ -0,0 +1,24 @@ +--TEST-- +Reflection: hasGenericArguments and getGenericArguments +--FILE-- + {} +function f(Box $x): Box { return $x; } +$r = new ReflectionFunction('f'); +$pt = $r->getParameters()[0]->getType(); +var_dump($pt->hasGenericArguments()); +$args = $pt->getGenericArguments(); +echo count($args), "\n"; +echo $args[0]->getName(), "\n"; + +$rt = $r->getReturnType(); +var_dump($rt->hasGenericArguments()); +$args2 = $rt->getGenericArguments(); +echo $args2[0]->getName(), "\n"; +?> +--EXPECT-- +bool(true) +1 +int +bool(true) +string diff --git a/ext/reflection/tests/generics/named_type_no_args.phpt b/ext/reflection/tests/generics/named_type_no_args.phpt new file mode 100644 index 000000000000..281e29060444 --- /dev/null +++ b/ext/reflection/tests/generics/named_type_no_args.phpt @@ -0,0 +1,12 @@ +--TEST-- +Reflection: hasGenericArguments returns false when no arguments +--FILE-- +getParameters()[0]->getType()->hasGenericArguments()); +var_dump($r->getReturnType()->hasGenericArguments()); +?> +--EXPECT-- +bool(false) +bool(false) diff --git a/ext/reflection/tests/generics/nested_args.phpt b/ext/reflection/tests/generics/nested_args.phpt new file mode 100644 index 000000000000..ba10c52ccfb1 --- /dev/null +++ b/ext/reflection/tests/generics/nested_args.phpt @@ -0,0 +1,17 @@ +--TEST-- +Reflection: nested generic arguments +--FILE-- + {} +function f(Box> $x): void {} +$pt = (new ReflectionFunction('f'))->getParameters()[0]->getType(); +echo $pt->getName(), "\n"; +$inner = $pt->getGenericArguments()[0]; +echo $inner->getName(), "\n"; +$inmost = $inner->getGenericArguments()[0]; +echo $inmost->getName(), "\n"; +?> +--EXPECT-- +Box> +Box +int diff --git a/ext/reflection/tests/generics/parameter_constructor_throws.phpt b/ext/reflection/tests/generics/parameter_constructor_throws.phpt new file mode 100644 index 000000000000..d33d9de36190 --- /dev/null +++ b/ext/reflection/tests/generics/parameter_constructor_throws.phpt @@ -0,0 +1,14 @@ +--TEST-- +Reflection: cannot instantiate ReflectionGenericTypeParameter directly +--FILE-- +newInstanceWithoutConstructor()->__construct(); + echo "no error\n"; +} catch (Throwable $e) { + echo "error: ", get_class($e), "\n"; +} +?> +--EXPECT-- +error: ReflectionException diff --git a/ext/reflection/tests/generics/parameter_get_bound.phpt b/ext/reflection/tests/generics/parameter_get_bound.phpt new file mode 100644 index 000000000000..c20c07ac2294 --- /dev/null +++ b/ext/reflection/tests/generics/parameter_get_bound.phpt @@ -0,0 +1,18 @@ +--TEST-- +Reflection: ReflectionGenericTypeParameter::getBound() returns the bound type or throws when no bound +--FILE-- + {} +$ps = (new ReflectionClass('A'))->getGenericParameters(); +var_dump($ps[0]->hasBound()); +try { + $ps[0]->getBound(); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} +echo $ps[1]->getBound()->getName(), "\n"; +?> +--EXPECT-- +bool(false) +Type parameter X has no bound +object diff --git a/ext/reflection/tests/generics/parameter_get_declaring_class.phpt b/ext/reflection/tests/generics/parameter_get_declaring_class.phpt new file mode 100644 index 000000000000..006bb99922d6 --- /dev/null +++ b/ext/reflection/tests/generics/parameter_get_declaring_class.phpt @@ -0,0 +1,13 @@ +--TEST-- +Reflection: getDeclaringEntity() returns the declaring class +--FILE-- + {} +$p = (new ReflectionClass('A'))->getGenericParameters()[0]; +$de = $p->getDeclaringEntity(); +echo get_class($de), "\n"; +echo $de->getName(), "\n"; +?> +--EXPECT-- +ReflectionClass +A diff --git a/ext/reflection/tests/generics/parameter_get_declaring_function.phpt b/ext/reflection/tests/generics/parameter_get_declaring_function.phpt new file mode 100644 index 000000000000..3ed7cfdc7625 --- /dev/null +++ b/ext/reflection/tests/generics/parameter_get_declaring_function.phpt @@ -0,0 +1,13 @@ +--TEST-- +Reflection: getDeclaringEntity() returns the declaring function +--FILE-- +(): void {} +$p = (new ReflectionFunction('f'))->getGenericParameters()[0]; +$de = $p->getDeclaringEntity(); +echo get_class($de), "\n"; +echo $de->getName(), "\n"; +?> +--EXPECT-- +ReflectionFunction +f diff --git a/ext/reflection/tests/generics/parameter_get_position.phpt b/ext/reflection/tests/generics/parameter_get_position.phpt new file mode 100644 index 000000000000..babf13acbd9c --- /dev/null +++ b/ext/reflection/tests/generics/parameter_get_position.phpt @@ -0,0 +1,14 @@ +--TEST-- +Reflection: ReflectionGenericTypeParameter::getPosition() +--FILE-- + {} +$ps = (new ReflectionClass('A'))->getGenericParameters(); +foreach ($ps as $p) { + echo $p->getName(), ": ", $p->getPosition(), "\n"; +} +?> +--EXPECT-- +X: 0 +Y: 1 +Z: 2 diff --git a/ext/reflection/tests/generics/parameter_get_variance.phpt b/ext/reflection/tests/generics/parameter_get_variance.phpt new file mode 100644 index 000000000000..61d39c1d802c --- /dev/null +++ b/ext/reflection/tests/generics/parameter_get_variance.phpt @@ -0,0 +1,13 @@ +--TEST-- +Reflection: ReflectionGenericTypeParameter::getVariance() +--FILE-- + {} +foreach ((new ReflectionClass('A'))->getGenericParameters() as $p) { + echo $p->getName(), ": ", $p->getVariance()->name, "\n"; +} +?> +--EXPECT-- +X: Covariant +Y: Contravariant +Z: Invariant diff --git a/ext/reflection/tests/generics/parameter_has_bound.phpt b/ext/reflection/tests/generics/parameter_has_bound.phpt new file mode 100644 index 000000000000..2e1732073de3 --- /dev/null +++ b/ext/reflection/tests/generics/parameter_has_bound.phpt @@ -0,0 +1,12 @@ +--TEST-- +Reflection: ReflectionGenericTypeParameter::hasBound() +--FILE-- + {} +$ps = (new ReflectionClass('A'))->getGenericParameters(); +echo $ps[0]->getName(), ": ", var_export($ps[0]->hasBound(), true), "\n"; +echo $ps[1]->getName(), ": ", var_export($ps[1]->hasBound(), true), "\n"; +?> +--EXPECT-- +X: false +Y: true diff --git a/ext/reflection/tests/generics/parameter_has_default.phpt b/ext/reflection/tests/generics/parameter_has_default.phpt new file mode 100644 index 000000000000..6e09af852391 --- /dev/null +++ b/ext/reflection/tests/generics/parameter_has_default.phpt @@ -0,0 +1,20 @@ +--TEST-- +Reflection: hasDefault() and getDefault() +--FILE-- + {} +$ps = (new ReflectionClass('A'))->getGenericParameters(); +var_dump($ps[0]->hasDefault()); +try { + $ps[0]->getDefault(); +} catch (ReflectionException $e) { + echo $e->getMessage(), "\n"; +} +var_dump($ps[1]->hasDefault()); +echo $ps[1]->getDefault()->getName(), "\n"; +?> +--EXPECT-- +bool(false) +Type parameter X has no default +bool(true) +int diff --git a/ext/reflection/tests/generics/parameter_to_string.phpt b/ext/reflection/tests/generics/parameter_to_string.phpt new file mode 100644 index 000000000000..60c441816533 --- /dev/null +++ b/ext/reflection/tests/generics/parameter_to_string.phpt @@ -0,0 +1,14 @@ +--TEST-- +Reflection: __toString on type parameter +--FILE-- + {} +foreach ((new ReflectionClass('A'))->getGenericParameters() as $p) { + echo $p, "\n"; +} +?> +--EXPECT-- +X +Y : object +Z = int ++W : object = stdClass diff --git a/ext/reflection/tests/generics/property_type_args.phpt b/ext/reflection/tests/generics/property_type_args.phpt new file mode 100644 index 000000000000..d201813592c9 --- /dev/null +++ b/ext/reflection/tests/generics/property_type_args.phpt @@ -0,0 +1,17 @@ +--TEST-- +Reflection: property type arguments via Reflection +--FILE-- + {} +class Holder { + public Box $b; +} +$rt = (new ReflectionClass('Holder'))->getProperty('b')->getType(); +echo $rt->getName(), "\n"; +echo count($rt->getGenericArguments()), "\n"; +echo $rt->getGenericArguments()[0]->getName(), "\n"; +?> +--EXPECT-- +Box +1 +int diff --git a/ext/reflection/tests/generics/type_parameter_ref_get_param.phpt b/ext/reflection/tests/generics/type_parameter_ref_get_param.phpt new file mode 100644 index 000000000000..642a5b7a79d3 --- /dev/null +++ b/ext/reflection/tests/generics/type_parameter_ref_get_param.phpt @@ -0,0 +1,19 @@ +--TEST-- +Reflection: ReflectionTypeParameterReference::getTypeParameter() +--FILE-- + {} +class Outer { + public Box $b; +} +$rt = (new ReflectionClass('Outer'))->getProperty('b')->getType(); +$ref = $rt->getGenericArguments()[0]; +$param = $ref->getTypeParameter(); +echo get_class($param), "\n"; +echo $param->getName(), "\n"; +echo $param->getDeclaringEntity()->getName(), "\n"; +?> +--EXPECT-- +ReflectionGenericTypeParameter +T +Outer diff --git a/ext/reflection/tests/generics/type_parameter_reference.phpt b/ext/reflection/tests/generics/type_parameter_reference.phpt new file mode 100644 index 000000000000..3ff5ae7d50e4 --- /dev/null +++ b/ext/reflection/tests/generics/type_parameter_reference.phpt @@ -0,0 +1,21 @@ +--TEST-- +Reflection: ReflectionTypeParameterReference appears inside getGenericArguments +--FILE-- + {} +class Outer { + public Box $b; +} +$rp = (new ReflectionClass('Outer'))->getProperty('b'); +$rt = $rp->getType(); +echo $rt->getName(), "\n"; +$args = $rt->getGenericArguments(); +echo count($args), "\n"; +echo get_class($args[0]), "\n"; +echo $args[0]->getName(), "\n"; +?> +--EXPECT-- +Box +1 +ReflectionTypeParameterReference +T diff --git a/ext/reflection/tests/generics/variance_enum.phpt b/ext/reflection/tests/generics/variance_enum.phpt new file mode 100644 index 000000000000..f05241526adb --- /dev/null +++ b/ext/reflection/tests/generics/variance_enum.phpt @@ -0,0 +1,18 @@ +--TEST-- +Reflection: ReflectionGenericVariance is a unit enum exposing three cases +--FILE-- +name, "\n"; +echo ReflectionGenericVariance::Covariant->name, "\n"; +echo ReflectionGenericVariance::Contravariant->name, "\n"; +var_dump(ReflectionGenericVariance::Invariant instanceof BackedEnum); +var_dump(ReflectionGenericVariance::Invariant === ReflectionGenericVariance::Invariant); +var_dump(ReflectionGenericVariance::Invariant === ReflectionGenericVariance::Covariant); +?> +--EXPECT-- +Invariant +Covariant +Contravariant +bool(false) +bool(true) +bool(false) diff --git a/ext/reflection/tests/gh18373.phpt b/ext/reflection/tests/gh18373.phpt new file mode 100644 index 000000000000..30aa1a0f5fe5 --- /dev/null +++ b/ext/reflection/tests/gh18373.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-18373: Don't substitute self/parent with anonymous class +--FILE-- +getMethod('test')->getReturnType()->getName(), "\n"; + +?> +--EXPECT-- +self diff --git a/ext/reflection/tests/gh19187.phpt b/ext/reflection/tests/gh19187.phpt new file mode 100644 index 000000000000..35a684aa6af7 --- /dev/null +++ b/ext/reflection/tests/gh19187.phpt @@ -0,0 +1,56 @@ +--TEST-- +GH-19187: ReflectionNamedType::getName() should not include nullable type +--FILE-- + $value; + } + public string|null $b { + set(string|null $value) => $value; + } + public string|null $c { + get => $this->c; + } +} + +foreach ((new ReflectionClass(C::class))->getProperties() as $r) { + $type = $r->getType(); + echo $type, "\n"; + echo $type->getName(), "\n"; + var_dump($type->allowsNull()); + echo "\n"; + + $settableType = $r->getSettableType(); + echo $settableType, "\n"; + echo $settableType->getName(), "\n"; + var_dump($settableType->allowsNull()); + echo "\n"; +} + +?> +--EXPECT-- +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) diff --git a/ext/reflection/tests/gh20895.phpt b/ext/reflection/tests/gh20895.phpt new file mode 100644 index 000000000000..f281078de446 --- /dev/null +++ b/ext/reflection/tests/gh20895.phpt @@ -0,0 +1,108 @@ +--TEST-- +GH-20895: ReflectionProperty does not return the PHPDoc of a property if it contains an attribute with a Closure +--FILE-- +getDocComment()); +foreach ((new ReflectionClass(Foo::class))->getAttributes() as $attribute) { + foreach ($attribute->getArguments() as $argument) { + var_dump((new ReflectionFunction($argument))->getDocComment()); + } +} +var_dump((new ReflectionProperty(Foo::class, 'bar'))->getDocComment()); +foreach ((new ReflectionProperty(Foo::class, 'bar'))->getAttributes() as $attribute) { + foreach ($attribute->getArguments() as $argument) { + var_dump((new ReflectionFunction($argument))->getDocComment()); + } +} +var_dump((new ReflectionMethod(Foo::class, 'bar'))->getDocComment()); +foreach ((new ReflectionMethod(Foo::class, 'bar'))->getAttributes() as $attribute) { + foreach ($attribute->getArguments() as $argument) { + var_dump((new ReflectionFunction($argument))->getDocComment()); + } +} +var_dump((new ReflectionFunction('foo'))->getDocComment()); +foreach ((new ReflectionFunction('foo'))->getAttributes() as $attribute) { + foreach ($attribute->getArguments() as $argument) { + var_dump((new ReflectionFunction($argument))->getDocComment()); + } +} +var_dump((new ReflectionFunction('bar'))->getDocComment()); +foreach ((new ReflectionFunction('bar'))->getAttributes() as $attribute) { + foreach ($attribute->getArguments() as $argument) { + var_dump((new ReflectionFunction($argument))->getDocComment()); + } +} +var_dump((new ReflectionFunction('baz'))->getDocComment()); +foreach ((new ReflectionFunction('baz'))->getAttributes() as $attribute) { + foreach ($attribute->getArguments() as $argument) { + var_dump((new ReflectionFunction($argument))->getDocComment()); + } +} + +?> +--EXPECT-- +string(10) "/** Foo */" +string(16) "/** Closure 1 */" +string(16) "/** Closure 2 */" +string(16) "/** Foo::$bar */" +string(16) "/** Closure 3 */" +string(16) "/** Closure 4 */" +string(16) "/** Closure 5 */" +string(17) "/** Foo::bar() */" +string(16) "/** Closure 6 */" +string(12) "/** foo() */" +string(16) "/** Closure 7 */" +string(12) "/** bar() */" +string(16) "/** Closure 8 */" +string(12) "/** baz() */" +bool(false) diff --git a/ext/reflection/tests/gh21362.phpt b/ext/reflection/tests/gh21362.phpt new file mode 100644 index 000000000000..1f5619ce779d --- /dev/null +++ b/ext/reflection/tests/gh21362.phpt @@ -0,0 +1,115 @@ +--TEST-- +GH-21362 (ReflectionMethod::invokeArgs() for Closure::__invoke() accepts objects from different Closures) +--FILE-- +invokeArgs($c1, ['foo' => 'FOO', 'bar' => 'BAR']); + +// invokeArgs with a different Closure should throw +try { + $m->invokeArgs($c2, ['foo' => 'FOO', 'bar' => 'BAR']); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// invoke with a different Closure should also throw +try { + $m->invoke($c2, 'FOO', 'BAR'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// Closures from the same source (e.g. loop) share the same op_array +// and should be allowed to invoke each other's ReflectionMethod +$closures = []; +for ($i = 0; $i < 3; $i++) { + $closures[] = function () use ($i) { return $i; }; +} + +$m2 = new ReflectionMethod($closures[0], '__invoke'); +foreach ($closures as $closure) { + var_dump($m2->invoke($closure)); +} + +// First-class callable of a userland function +function my_func($x) { return "my_func: $x"; } +function other_func($x) { return "other_func: $x"; } + +$mf = my_func(...); +$mf2 = my_func(...); +$of = other_func(...); + +$m3 = new ReflectionMethod($mf, '__invoke'); +var_dump($m3->invoke($mf, 'test')); +var_dump($m3->invoke($mf2, 'test')); + +try { + $m3->invoke($of, 'test'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// Internal closures (first-class callable syntax) should also be validated +$vd = var_dump(...); +$pr = print_r(...); + +$m4 = new ReflectionMethod($vd, '__invoke'); +$m4->invoke($vd, 'internal closure OK'); + +// Cloned internal closure is a different object but same function - should work +$vd2 = clone $vd; +$m4->invoke($vd2, 'cloned internal closure OK'); + +// Different internal closure should throw +try { + $m4->invoke($pr, 'should not print'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// Cross-type: userland Closure to internal Closure's invoke should throw +try { + $m4->invoke($c1, 'should not print'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} + +// Cross-type: internal Closure to userland Closure's invoke should throw +try { + $m->invoke($vd, 'should not print'); + echo "No exception thrown\n"; +} catch (ReflectionException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +c1: foo=FOO, bar=BAR +Given Closure is not the same as the reflected Closure +Given Closure is not the same as the reflected Closure +int(0) +int(1) +int(2) +string(13) "my_func: test" +string(13) "my_func: test" +Given Closure is not the same as the reflected Closure +string(19) "internal closure OK" +string(26) "cloned internal closure OK" +Given Closure is not the same as the reflected Closure +Given Closure is not the same as the reflected Closure +Given Closure is not the same as the reflected Closure diff --git a/ext/reflection/tests/gh22000.phpt b/ext/reflection/tests/gh22000.phpt new file mode 100644 index 000000000000..aee4863e9b7d --- /dev/null +++ b/ext/reflection/tests/gh22000.phpt @@ -0,0 +1,61 @@ +--TEST-- +GH-22000 - Ensure __isset returning a reference is supported by ReflectionProperty::isReadable() +--FILE-- +b); + unset($this->c); + } + + public function __isset($name) { + return $name === 'b'; + } + + public function __get($name) {} +} + +class TestClass2 { + public int $d; + public int $e; + public int $f; + + public function __construct() { + unset($this->e); + unset($this->f); + } + + public function &__isset($name) { + return $name === 'f'; + } + + public function __get($name) {} +} + + +function test($class) { + $rc = new ReflectionClass($class); + foreach ($rc->getProperties() as $rp) { + echo $rp->getName() . ' from global:'; + var_dump($rp->isReadable(null, new $class)); + } +} + +test('TestClass1'); +test('TestClass2'); +?> +--EXPECTF-- +a from global:bool(true) +b from global:bool(true) +c from global:bool(false) +d from global:bool(false) +e from global: +Notice: Only variable references should be returned by reference in %s on line %d +bool(false) +f from global: +Notice: Only variable references should be returned by reference in %s on line %d +bool(true) diff --git a/ext/reflection/tests/internal_parameter_default_value/check_all.phpt b/ext/reflection/tests/internal_parameter_default_value/check_all.phpt index 534f781c4fc1..241dea449b61 100644 --- a/ext/reflection/tests/internal_parameter_default_value/check_all.phpt +++ b/ext/reflection/tests/internal_parameter_default_value/check_all.phpt @@ -30,7 +30,7 @@ foreach (get_declared_classes() as $class) { ?> ===DONE=== --EXPECTF-- -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d -Deprecated: Constant SUNFUNCS_RET_STRING is deprecated in %s on line %d +Deprecated: Constant SUNFUNCS_RET_STRING is deprecated since 8.4, as date_sunrise() and date_sunset() were deprecated in 8.1 in %s on line %d ===DONE=== diff --git a/ext/reflection/tests/oss-fuzz-489355368.phpt b/ext/reflection/tests/oss-fuzz-489355368.phpt new file mode 100644 index 000000000000..1885f33476d4 --- /dev/null +++ b/ext/reflection/tests/oss-fuzz-489355368.phpt @@ -0,0 +1,17 @@ +--TEST-- +OSS-Fuzz #489355368: Incorrect assumption Z_PTR_P assumption +--FILE-- +prop = 0; + +$rp = new ReflectionProperty($obj, 'prop'); +var_dump($rp->isReadable(null, $obj)); + +?> +--EXPECT-- +bool(true) diff --git a/ext/reflection/tests/property_hooks/basics.phpt b/ext/reflection/tests/property_hooks/basics.phpt index 8c363dcc4bfb..6011018c64cf 100644 --- a/ext/reflection/tests/property_hooks/basics.phpt +++ b/ext/reflection/tests/property_hooks/basics.phpt @@ -47,7 +47,6 @@ try { } catch (ReflectionException $e) { echo $e->getMessage(), "\n"; } -$s->setAccessible(true); $s->invoke($test, 42); var_dump($test->prop2); dumpFlags($rp2); diff --git a/ext/session/config.m4 b/ext/session/config.m4 index 36cfdf10972a..cce00e585122 100644 --- a/ext/session/config.m4 +++ b/ext/session/config.m4 @@ -20,8 +20,6 @@ if test "$PHP_SESSION" != "no"; then [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_ADD_EXTENSION_DEP(session, date) - dnl https://bugs.php.net/53141 - PHP_ADD_EXTENSION_DEP(session, spl, true) PHP_SUBST([SESSION_SHARED_LIBADD]) PHP_INSTALL_HEADERS([ext/session], [php_session.h mod_files.h mod_user.h]) diff --git a/ext/session/config.w32 b/ext/session/config.w32 index 825bc8b61d29..50fdc087d4e9 100644 --- a/ext/session/config.w32 +++ b/ext/session/config.w32 @@ -3,10 +3,8 @@ ARG_ENABLE("session", "session support", "yes"); if (PHP_SESSION == "yes") { - EXTENSION("session", "mod_user_class.c session.c mod_files.c mod_mm.c mod_user.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + EXTENSION("session", "mod_user_class.c session.c mod_files.c mod_user.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); ADD_EXTENSION_DEP('session', 'date'); - // https://bugs.php.net/53141 - ADD_EXTENSION_DEP('session', 'spl', true); AC_DEFINE("HAVE_PHP_SESSION", 1, "Define to 1 if the PHP extension 'session' is available."); - PHP_INSTALL_HEADERS("ext/session", "mod_mm.h php_session.h mod_files.h mod_user.h"); + PHP_INSTALL_HEADERS("ext/session", "php_session.h mod_files.h mod_user.h"); } diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 74e77973405b..3a7f8aec4522 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -103,7 +101,6 @@ const ps_module ps_mod_files = { PS_MOD_UPDATE_TIMESTAMP(files) }; - static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, const zend_string *key) { const char *p; @@ -153,7 +150,7 @@ static void ps_files_open(ps_files *data, /* const */ zend_string *key) { char buf[MAXPATHLEN]; #if !defined(O_NOFOLLOW) || !defined(PHP_WIN32) - struct stat sbuf = {0}; + struct stat sbuf = {0}; #endif int ret; @@ -183,7 +180,7 @@ static void ps_files_open(ps_files *data, /* const */ zend_string *key) #else /* Check to make sure that the opened file is not outside of allowable dirs. This is not 100% safe but it's hard to do something better without O_NOFOLLOW */ - if(PG(open_basedir) && lstat(buf, &sbuf) == 0 && S_ISLNK(sbuf.st_mode) && php_check_open_basedir(buf)) { + if (PG(open_basedir) && lstat(buf, &sbuf) == 0 && S_ISLNK(sbuf.st_mode) && php_check_open_basedir(buf)) { return; } data->fd = VCWD_OPEN_MODE(buf, O_CREAT | O_RDWR | O_BINARY, data->filemode); @@ -230,7 +227,7 @@ static zend_result ps_files_write(ps_files *data, zend_string *key, zend_string /* PS(id) may be changed by calling session_regenerate_id(). Re-initialization should be tried here. ps_files_open() checks - data->last_key and reopen when it is needed. */ + data->last_key and reopen when it is needed. */ ps_files_open(data, key); if (data->fd < 0) { return FAILURE; @@ -258,7 +255,7 @@ static zend_result ps_files_write(ps_files *data, zend_string *key, zend_string buf = wrote > -1 ? buf + wrote : 0; to_write = wrote > -1 ? SESS_FILE_BUF_SIZE(ZSTR_LEN(val) - n) : 0; - } while(wrote > 0); + } while (wrote > 0); } #else n = write(data->fd, ZSTR_VAL(val), ZSTR_LEN(val)); @@ -277,7 +274,10 @@ static zend_result ps_files_write(ps_files *data, zend_string *key, zend_string return SUCCESS; } -static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetime) +/* Recursively remove expired session files. When dirdepth > 0 the + * cleanup descends into subdirectories up to that many levels before + * inspecting individual session files. */ +static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetime, size_t remaining_depth) { DIR *dir; struct dirent *entry; @@ -292,8 +292,6 @@ static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetim return -1; } - time(&now); - if (ZSTR_LEN(dirname) >= MAXPATHLEN) { php_error_docref(NULL, E_NOTICE, "ps_files_cleanup_dir: dirname(%s) is too long", ZSTR_VAL(dirname)); closedir(dir); @@ -305,31 +303,52 @@ static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetim buf[ZSTR_LEN(dirname)] = PHP_DIR_SEPARATOR; while ((entry = readdir(dir))) { - /* does the file start with our prefix? */ - if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) { - size_t entry_len = strlen(entry->d_name); - - /* does it fit into our buffer? */ - if (entry_len + ZSTR_LEN(dirname) + 2 < MAXPATHLEN) { - /* create the full path.. */ - memcpy(buf + ZSTR_LEN(dirname) + 1, entry->d_name, entry_len); - - /* NUL terminate it and */ - buf[ZSTR_LEN(dirname) + entry_len + 1] = '\0'; - - /* check whether its last access was more than maxlifetime ago */ - if (VCWD_STAT(buf, &sbuf) == 0 && - (now - sbuf.st_mtime) > maxlifetime) { - VCWD_UNLINK(buf); - nrdels++; + /* skip . and .. */ + if (entry->d_name[0] == '.' && + (entry->d_name[1] == '\0' || + (entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) { + continue; + } + size_t entry_len = strlen(entry->d_name); + /* does it fit into our buffer? */ + if (ZSTR_LEN(dirname) + 1 + entry_len >= MAXPATHLEN) { + continue; + } + /* create the full path and NUL-terminate it */ + memcpy(buf + ZSTR_LEN(dirname) + 1, entry->d_name, entry_len); + buf[ZSTR_LEN(dirname) + 1 + entry_len] = '\0'; + + if (remaining_depth == 0) { + /* target depth: delete expired session files */ + if (strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1) != 0) { + continue; + } + if (VCWD_STAT(buf, &sbuf) != 0) { + continue; + } + time(&now); + if ((now - sbuf.st_mtime) > maxlifetime) { + VCWD_UNLINK(buf); + nrdels++; + } + } else { + /* intermediate depth: recurse into subdirectories */ + if (VCWD_STAT(buf, &sbuf) != 0) { + continue; + } + if (S_ISDIR(sbuf.st_mode)) { + zend_string *subdir = zend_string_init(buf, ZSTR_LEN(dirname) + 1 + entry_len, 0); + int n = ps_files_cleanup_dir(subdir, maxlifetime, remaining_depth - 1); + zend_string_release(subdir); + if (n >= 0) { + nrdels += n; } } } } closedir(dir); - - return (nrdels); + return nrdels; } static zend_result ps_files_key_exists(ps_files *data, const zend_string *key) @@ -346,10 +365,8 @@ static zend_result ps_files_key_exists(ps_files *data, const zend_string *key) return SUCCESS; } - #define PS_FILES_DATA ps_files *data = PS_GET_MOD_DATA() - /* * Open save handler. Setup resources that are needed by the handler. * PARAMETERS: PS_OPEN_ARGS in php_session.h @@ -369,19 +386,22 @@ PS_OPEN_FUNC(files) int argc = 0; size_t dirdepth = 0; int filemode = 0600; + const char *used_save_path; - if (*save_path == '\0') { + if (ZSTR_LEN(save_path) == 0) { /* if save path is an empty string, determine the temporary dir */ - save_path = php_get_temporary_directory(); + used_save_path = php_get_temporary_directory(); - if (php_check_open_basedir(save_path)) { + if (php_check_open_basedir(used_save_path)) { return FAILURE; } + } else { + used_save_path = ZSTR_VAL(save_path); } /* split up input parameter */ - last = save_path; - p = strchr(save_path, ';'); + last = used_save_path; + p = strchr(used_save_path, ';'); while (p) { argv[argc++] = last; last = ++p; @@ -407,14 +427,14 @@ PS_OPEN_FUNC(files) return FAILURE; } } - save_path = argv[argc - 1]; + used_save_path = argv[argc - 1]; data = ecalloc(1, sizeof(*data)); data->fd = -1; data->dirdepth = dirdepth; data->filemode = filemode; - data->basedir = zend_string_init(save_path, strlen(save_path), /* persistent */ false); + data->basedir = zend_string_init(used_save_path, strlen(used_save_path), /* persistent */ false); if (PS_GET_MOD_DATA()) { ps_close_files(mod_data); @@ -424,7 +444,6 @@ PS_OPEN_FUNC(files) return SUCCESS; } - /* * Clean up opened resources. * PARAMETERS: PS_CLOSE_ARGS in php_session.h @@ -453,7 +472,6 @@ PS_CLOSE_FUNC(files) return SUCCESS; } - /* * Read session data from opened resource. * PARAMETERS: PS_READ_ARGS in php_session.h @@ -486,7 +504,7 @@ PS_READ_FUNC(files) return SUCCESS; } - *val = zend_string_alloc(sbuf.st_size, 0); + *val = zend_string_alloc(sbuf.st_size, false); #ifdef HAVE_PREAD n = pread(data->fd, ZSTR_VAL(*val), ZSTR_LEN(*val), 0); @@ -505,7 +523,7 @@ PS_READ_FUNC(files) buf = read_in > -1 ? buf + read_in : 0; to_read = read_in > -1 ? SESS_FILE_BUF_SIZE(ZSTR_LEN(*val) - n) : 0; - } while(read_in > 0); + } while (read_in > 0); } #else @@ -519,7 +537,7 @@ PS_READ_FUNC(files) } else { php_error_docref(NULL, E_WARNING, "Read returned less bytes than requested"); } - zend_string_release_ex(*val, 0); + zend_string_release_ex(*val, false); *val = ZSTR_EMPTY_ALLOC(); return FAILURE; } @@ -528,7 +546,6 @@ PS_READ_FUNC(files) return SUCCESS; } - /* * Write session data. * PARAMETERS: PS_WRITE_ARGS in php_session.h @@ -544,7 +561,6 @@ PS_WRITE_FUNC(files) return ps_files_write(data, key, val); } - /* * Update session data modification/access time stamp. * PARAMETERS: PS_UPDATE_TIMESTAMP_ARGS in php_session.h @@ -579,7 +595,6 @@ PS_UPDATE_TIMESTAMP_FUNC(files) return SUCCESS; } - /* * Delete session data. * PARAMETERS: PS_DESTROY_ARGS in php_session.h @@ -614,7 +629,6 @@ PS_DESTROY_FUNC(files) return SUCCESS; } - /* * Cleanup expired session data. * PARAMETERS: PS_GC_ARGS in php_session.h @@ -630,20 +644,11 @@ PS_GC_FUNC(files) { PS_FILES_DATA; - /* We don't perform any cleanup, if dirdepth is larger than 0. - we return SUCCESS, since all cleanup should be handled by - an external entity (i.e. find -ctime x | xargs rm) */ - - if (data->dirdepth == 0) { - *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime); - } else { - *nrdels = -1; // Cannot process multiple depth save dir - } + *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime, data->dirdepth); return *nrdels; } - /* * Create session ID. * PARAMETERS: PS_CREATE_SID_ARGS in php_session.h @@ -675,18 +680,17 @@ PS_CREATE_SID_FUNC(files) /* Check collision */ /* FIXME: mod_data(data) should not be NULL (User handler could be NULL) */ if (data && ps_files_key_exists(data, sid) == SUCCESS) { - zend_string_release_ex(sid, 0); + zend_string_release_ex(sid, false); sid = NULL; if (--maxfail < 0) { return NULL; } } - } while(!sid); + } while (!sid); return sid; } - /* * Check session ID existence for use_strict_mode support. * PARAMETERS: PS_VALIDATE_SID_ARGS in php_session.h diff --git a/ext/session/mod_files.h b/ext/session/mod_files.h index 31ed4afbffcc..9eae00fb9c7a 100644 --- a/ext/session/mod_files.h +++ b/ext/session/mod_files.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c index b997a2bdcff5..ff8664c981a0 100644 --- a/ext/session/mod_mm.c +++ b/ext/session/mod_mm.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -40,11 +38,11 @@ typedef struct ps_sd { struct ps_sd *next; - uint32_t hv; /* hash value of key */ - time_t ctime; /* time of last change */ + uint32_t hv; /* hash value of key */ + time_t ctime; /* time of last change */ void *data; - size_t datalen; /* amount of valid data */ - size_t alloclen; /* amount of allocated memory for data */ + size_t datalen; /* amount of valid data */ + size_t alloclen; /* amount of allocated memory for data */ zend_string *key; } ps_sd; @@ -207,7 +205,7 @@ static zend_result ps_mm_key_exists(ps_mm *data, const zend_string *key) if (!key) { return FAILURE; } - sd = ps_sd_lookup(data, key, 0); + sd = ps_sd_lookup(data, key, false); if (sd) { return SUCCESS; } @@ -215,7 +213,7 @@ static zend_result ps_mm_key_exists(ps_mm *data, const zend_string *key) } const ps_module ps_mod_mm = { - PS_MOD_SID(mm) + PS_MOD(mm) }; #define PS_MM_DATA ps_mm *data = PS_GET_MOD_DATA() @@ -264,7 +262,7 @@ static void ps_mm_destroy(ps_mm *data) PHP_MINIT_FUNCTION(ps_mm) { - size_t save_path_len = strlen(PS(save_path)); + size_t save_path_len = ZSTR_LEN(PS(save_path)); size_t mod_name_len = strlen(sapi_module.name); size_t euid_len; char *ps_mm_path, euid[30]; @@ -284,8 +282,8 @@ PHP_MINIT_FUNCTION(ps_mm) /* Directory + '/' + File + Module Name + Effective UID + \0 */ ps_mm_path = emalloc(save_path_len + 1 + (sizeof(PS_MM_FILE) - 1) + mod_name_len + euid_len + 1); - memcpy(ps_mm_path, PS(save_path), save_path_len); - if (save_path_len && PS(save_path)[save_path_len - 1] != DEFAULT_SLASH) { + memcpy(ps_mm_path, ZSTR_VAL(PS(save_path)), save_path_len); + if (save_path_len && ZSTR_VAL(PS(save_path))[save_path_len - 1] != DEFAULT_SLASH) { ps_mm_path[save_path_len] = DEFAULT_SLASH; save_path_len++; } @@ -346,28 +344,9 @@ PS_READ_FUNC(mm) mm_lock(data->mm, MM_LOCK_RD); - /* If there is an ID and strict mode, verify existence */ - if (PS(use_strict_mode) - && ps_mm_key_exists(data, key) == FAILURE) { - /* key points to PS(id), but cannot change here. */ - if (key) { - efree(PS(id)); - PS(id) = NULL; - } - PS(id) = PS(mod)->s_create_sid((void **)&data); - if (!PS(id)) { - return FAILURE; - } - if (PS(use_cookies)) { - PS(send_cookie) = 1; - } - php_session_reset_id(); - PS(session_status) = php_session_active; - } - - sd = ps_sd_lookup(data, PS(id), 0); + sd = ps_sd_lookup(data, key, false); if (sd) { - *val = zend_string_init(sd->data, sd->datalen, 0); + *val = zend_string_init(sd->data, sd->datalen, false); ret = SUCCESS; } @@ -383,7 +362,7 @@ PS_WRITE_FUNC(mm) mm_lock(data->mm, MM_LOCK_RW); - sd = ps_sd_lookup(data, key, 1); + sd = ps_sd_lookup(data, key, true); if (!sd) { sd = ps_sd_new(data, key); ps_mm_debug(("new entry for %s\n", ZSTR_VAL(key))); @@ -422,7 +401,7 @@ PS_DESTROY_FUNC(mm) mm_lock(data->mm, MM_LOCK_RW); - sd = ps_sd_lookup(data, key, 0); + sd = ps_sd_lookup(data, key, false); if (sd) { ps_sd_destroy(data, sd); } @@ -476,16 +455,35 @@ PS_CREATE_SID_FUNC(mm) /* Check collision */ if (ps_mm_key_exists(data, sid) == SUCCESS) { if (sid) { - zend_string_release_ex(sid, 0); + zend_string_release_ex(sid, false); sid = NULL; } if (!(maxfail--)) { return NULL; } } - } while(!sid); + } while (!sid); return sid; } +/* + * Check session ID existence for use_strict_mode support. + * PARAMETERS: PS_VALIDATE_SID_ARGS in php_session.h + * RETURN VALUE: SUCCESS or FAILURE. + * + * Return SUCCESS for valid key(already existing session). + * Return FAILURE for invalid key(non-existing session). + * *mod_data, *key are guaranteed to have non-NULL values. + */ +PS_VALIDATE_SID_FUNC(mm) +{ + PS_MM_DATA; + + mm_lock(data->mm, MM_LOCK_RD); + zend_result ret = ps_mm_key_exists(data, key) + mm_unlock(data->mm); + return ret; +} + #endif diff --git a/ext/session/mod_mm.h b/ext/session/mod_mm.h index b35e0b632ee9..990eab09147c 100644 --- a/ext/session/mod_mm.h +++ b/ext/session/mod_mm.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c index 168c5c7f1d44..c87e9654c4ea 100644 --- a/ext/session/mod_user.c +++ b/ext/session/mod_user.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -22,24 +20,23 @@ const ps_module ps_mod_user = { PS_MOD_UPDATE_TIMESTAMP(user) }; - static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval) { int i; if (PS(in_save_handler)) { - PS(in_save_handler) = 0; + PS(in_save_handler) = false; ZVAL_UNDEF(retval); php_error_docref(NULL, E_WARNING, "Cannot call session save handler in a recursive manner"); return; } - PS(in_save_handler) = 1; + PS(in_save_handler) = true; if (call_user_function(NULL, NULL, func, retval, argc, argv) == FAILURE) { zval_ptr_dtor(retval); ZVAL_UNDEF(retval); } else if (Z_ISUNDEF_P(retval)) { ZVAL_NULL(retval); } - PS(in_save_handler) = 0; + PS(in_save_handler) = false; for (i = 0; i < argc; i++) { zval_ptr_dtor(&argv[i]); } @@ -47,7 +44,7 @@ static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval) #define PSF(a) PS(mod_user_names).ps_##a -static zend_result verify_bool_return_type_userland_calls(const zval* value) +static zend_result verify_bool_return_type_userland_calls(const zval *value) { /* Exit or exception in userland call */ if (Z_TYPE_P(value) == IS_UNDEF) { @@ -75,20 +72,19 @@ static zend_result verify_bool_return_type_userland_calls(const zval* value) } if (!EG(exception)) { zend_type_error("Session callback must have a return value of type bool, %s returned", zend_zval_value_name(value)); \ - } - return FAILURE; + } + return FAILURE; } PS_OPEN_FUNC(user) { zval args[2]; zval retval; - zend_result ret = FAILURE; ZEND_ASSERT(!Z_ISUNDEF(PSF(open))); - ZVAL_STRING(&args[0], (char*)save_path); - ZVAL_STRING(&args[1], (char*)session_name); + ZVAL_STR(&args[0], zend_string_dup(save_path, false)); + ZVAL_STR(&args[1], zend_string_dup(session_name, false)); zend_try { ps_call_handler(&PSF(open), 2, args, &retval); @@ -100,16 +96,16 @@ PS_OPEN_FUNC(user) zend_bailout(); } zend_end_try(); - PS(mod_user_implemented) = 1; + PS(mod_user_implemented) = true; - ret = verify_bool_return_type_userland_calls(&retval); + zend_result ret = verify_bool_return_type_userland_calls(&retval); zval_ptr_dtor(&retval); return ret; } PS_CLOSE_FUNC(user) { - bool bailout = 0; + bool bailout = false; zval retval; zend_result ret = FAILURE; @@ -123,10 +119,10 @@ PS_CLOSE_FUNC(user) zend_try { ps_call_handler(&PSF(close), 0, NULL, &retval); } zend_catch { - bailout = 1; + bailout = true; } zend_end_try(); - PS(mod_user_implemented) = 0; + PS(mod_user_implemented) = false; if (bailout) { if (!Z_ISUNDEF(retval)) { @@ -218,6 +214,7 @@ PS_GC_FUNC(user) /* Anything else is some kind of error */ *nrdels = -1; // Error } + zval_ptr_dtor(&retval); return *nrdels; } diff --git a/ext/session/mod_user.h b/ext/session/mod_user.h index 58772b48ec82..9c36c315819a 100644 --- a/ext/session/mod_user.h +++ b/ext/session/mod_user.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c index 22be2cd15194..a6bd69c91a07 100644 --- a/ext/session/mod_user_class.c +++ b/ext/session/mod_user_class.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Arpad Ray | +----------------------------------------------------------------------+ @@ -17,7 +15,7 @@ #include "php.h" #include "php_session.h" -#define PS_SANITY_CHECK \ +#define PS_SANITY_CHECK \ if (PS(session_status) != php_session_active) { \ zend_throw_error(NULL, "Session is not active"); \ RETURN_THROWS(); \ @@ -27,20 +25,19 @@ RETURN_THROWS(); \ } -#define PS_SANITY_CHECK_IS_OPEN \ +#define PS_SANITY_CHECK_IS_OPEN \ PS_SANITY_CHECK; \ - if (!PS(mod_user_is_open)) { \ - php_error_docref(NULL, E_WARNING, "Parent session handler is not open"); \ - RETURN_FALSE; \ + if (!PS(mod_user_is_open)) { \ + php_error_docref(NULL, E_WARNING, "Parent session handler is not open"); \ + RETURN_FALSE; \ } PHP_METHOD(SessionHandler, open) { - char *save_path = NULL, *session_name = NULL; - size_t save_path_len, session_name_len; + zend_string *save_path, *session_name; zend_result ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &save_path, &save_path_len, &session_name, &session_name_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &save_path, &session_name) == FAILURE) { RETURN_THROWS(); } @@ -54,7 +51,7 @@ PHP_METHOD(SessionHandler, open) } zend_end_try(); if (SUCCESS == ret) { - PS(mod_user_is_open) = 1; + PS(mod_user_is_open) = true; } RETURN_BOOL(SUCCESS == ret); @@ -70,7 +67,7 @@ PHP_METHOD(SessionHandler, close) PS_SANITY_CHECK_IS_OPEN; - PS(mod_user_is_open) = 0; + PS(mod_user_is_open) = false; zend_try { ret = PS(default_mod)->s_close(&PS(mod_data)); @@ -147,9 +144,7 @@ PHP_METHOD(SessionHandler, create_sid) { zend_string *id; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PS_SANITY_CHECK; diff --git a/ext/session/php_session.h b/ext/session/php_session.h index dfa7632e5a44..08c08b9a024a 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -26,7 +24,7 @@ #define PHP_SESSION_VERSION PHP_VERSION /* save handler macros */ -#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name +#define PS_OPEN_ARGS void **mod_data, zend_string *save_path, zend_string *session_name #define PS_CLOSE_ARGS void **mod_data #define PS_READ_ARGS void **mod_data, zend_string *key, zend_string **val, zend_long maxlifetime #define PS_WRITE_ARGS void **mod_data, zend_string *key, zend_string *val, zend_long maxlifetime @@ -52,33 +50,18 @@ typedef struct ps_module_struct { #define PS_GET_MOD_DATA() *mod_data #define PS_SET_MOD_DATA(a) *mod_data = (a) -#define PS_OPEN_FUNC(x) zend_result ps_open_##x(PS_OPEN_ARGS) -#define PS_CLOSE_FUNC(x) zend_result ps_close_##x(PS_CLOSE_ARGS) -#define PS_READ_FUNC(x) zend_result ps_read_##x(PS_READ_ARGS) -#define PS_WRITE_FUNC(x) zend_result ps_write_##x(PS_WRITE_ARGS) -#define PS_DESTROY_FUNC(x) zend_result ps_delete_##x(PS_DESTROY_ARGS) -#define PS_GC_FUNC(x) zend_long ps_gc_##x(PS_GC_ARGS) -#define PS_CREATE_SID_FUNC(x) zend_string *ps_create_sid_##x(PS_CREATE_SID_ARGS) -#define PS_VALIDATE_SID_FUNC(x) zend_result ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) -#define PS_UPDATE_TIMESTAMP_FUNC(x) zend_result ps_update_timestamp_##x(PS_UPDATE_TIMESTAMP_ARGS) - -/* Legacy save handler module definitions */ +#define PS_OPEN_FUNC(x) zend_result ps_open_##x(PS_OPEN_ARGS) +#define PS_CLOSE_FUNC(x) zend_result ps_close_##x(PS_CLOSE_ARGS) +#define PS_READ_FUNC(x) zend_result ps_read_##x(PS_READ_ARGS) +#define PS_WRITE_FUNC(x) zend_result ps_write_##x(PS_WRITE_ARGS) +#define PS_DESTROY_FUNC(x) zend_result ps_delete_##x(PS_DESTROY_ARGS) +#define PS_GC_FUNC(x) zend_long ps_gc_##x(PS_GC_ARGS) +#define PS_CREATE_SID_FUNC(x) zend_string *ps_create_sid_##x(PS_CREATE_SID_ARGS) +#define PS_VALIDATE_SID_FUNC(x) zend_result ps_validate_sid_##x(PS_VALIDATE_SID_ARGS) +#define PS_UPDATE_TIMESTAMP_FUNC(x) zend_result ps_update_timestamp_##x(PS_UPDATE_TIMESTAMP_ARGS) + +/* Save handler module definitions without timestamp enabled */ #define PS_FUNCS(x) \ - PS_OPEN_FUNC(x); \ - PS_CLOSE_FUNC(x); \ - PS_READ_FUNC(x); \ - PS_WRITE_FUNC(x); \ - PS_DESTROY_FUNC(x); \ - PS_GC_FUNC(x); \ - PS_CREATE_SID_FUNC(x) - -#define PS_MOD(x) \ - #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ - ps_delete_##x, ps_gc_##x, php_session_create_id, \ - php_session_validate_sid, php_session_update_timestamp - -/* Legacy SID creation enabled save handler module definitions */ -#define PS_FUNCS_SID(x) \ PS_OPEN_FUNC(x); \ PS_CLOSE_FUNC(x); \ PS_READ_FUNC(x); \ @@ -86,16 +69,14 @@ typedef struct ps_module_struct { PS_DESTROY_FUNC(x); \ PS_GC_FUNC(x); \ PS_CREATE_SID_FUNC(x); \ - PS_VALIDATE_SID_FUNC(x); \ - PS_UPDATE_TIMESTAMP_FUNC(x); + PS_VALIDATE_SID_FUNC(x); -#define PS_MOD_SID(x) \ +#define PS_MOD(x) \ #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, \ - php_session_validate_sid, php_session_update_timestamp + ps_validate_sid_##x, NULL -/* Update timestamp enabled save handler module definitions - New save handlers should use this API */ +/* Save handlers with timestamp enabled, it is recommended to use this API */ #define PS_FUNCS_UPDATE_TIMESTAMP(x) \ PS_OPEN_FUNC(x); \ PS_CLOSE_FUNC(x); \ @@ -112,7 +93,6 @@ typedef struct ps_module_struct { ps_delete_##x, ps_gc_##x, ps_create_sid_##x, \ ps_validate_sid_##x, ps_update_timestamp_##x - typedef enum { php_session_disabled, php_session_none, @@ -120,7 +100,6 @@ typedef enum { } php_session_status; typedef struct _php_session_rfc1867_progress { - size_t sname_len; zval sid; smart_str key; @@ -133,27 +112,37 @@ typedef struct _php_session_rfc1867_progress { zval data; /* the array exported to session data */ zval files; /* data["files"] array */ - zval *post_bytes_processed; /* data["bytes_processed"] */ - zval *current_file_bytes_processed; + zval *post_bytes_processed; /* data["bytes_processed"] */ + zval *current_file_bytes_processed; zval current_file; /* array of currently uploading file */ } php_session_rfc1867_progress; typedef struct _php_ps_globals { - char *save_path; - char *session_name; + zend_string *save_path; + zend_string *session_name; zend_string *id; char *extern_referer_chk; - char *cache_limiter; + zend_string *cache_limiter; zend_long cookie_lifetime; - char *cookie_path; - char *cookie_domain; - char *cookie_samesite; + zend_string *cookie_path; + zend_string *cookie_domain; + zend_string *cookie_samesite; bool cookie_secure; bool cookie_httponly; + bool cookie_partitioned; + bool use_cookies; + bool use_only_cookies; + bool send_cookie; + bool auto_start; + bool define_sid; const ps_module *mod; const ps_module *default_mod; void *mod_data; php_session_status session_status; + bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + bool lazy_write; /* omit session write when it is possible */ + bool in_save_handler; /* state if session is in save handler or not */ + bool set_handler; /* state if session module i setting handler or not */ zend_string *session_started_filename; uint32_t session_started_lineno; int module_number; @@ -174,16 +163,8 @@ typedef struct _php_ps_globals { zval ps_validate_sid; zval ps_update_timestamp; } mod_user_names; - zend_string *mod_user_class_name; - bool mod_user_implemented; - bool mod_user_is_open; - bool auto_start; - bool use_cookies; - bool use_only_cookies; - bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ - bool send_cookie; - bool define_sid; + zend_string *session_vars; /* serialized original session data */ const struct ps_serializer_struct *serializer; zval http_session_vars; @@ -191,18 +172,17 @@ typedef struct _php_ps_globals { zend_long sid_bits_per_character; php_session_rfc1867_progress *rfc1867_progress; - char *rfc1867_prefix; /* session.upload_progress.prefix */ - char *rfc1867_name; /* session.upload_progress.name */ + zend_string *rfc1867_prefix; /* session.upload_progress.prefix */ + zend_string *rfc1867_name; /* session.upload_progress.name */ zend_long rfc1867_freq; /* session.upload_progress.freq */ double rfc1867_min_freq; /* session.upload_progress.min_freq */ bool rfc1867_enabled; /* session.upload_progress.enabled */ bool rfc1867_cleanup; /* session.upload_progress.cleanup */ - bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ - bool lazy_write; /* omit session write when it is possible */ - bool in_save_handler; /* state if session is in save handler or not */ - bool set_handler; /* state if session module i setting handler or not */ - zend_string *session_vars; /* serialized original session data */ + bool mod_user_implemented; + bool mod_user_is_open; + bool mod_user_uses_object_methods_as_handlers; + bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ } php_ps_globals; typedef php_ps_globals zend_ps_globals; @@ -249,8 +229,6 @@ PHPAPI zend_string *php_session_create_id(PS_CREATE_SID_ARGS); PHPAPI zend_result php_session_validate_sid(PS_VALIDATE_SID_ARGS); PHPAPI zend_result php_session_update_timestamp(PS_UPDATE_TIMESTAMP_ARGS); -PHPAPI void session_adapt_url(const char *url, size_t url_len, char **new_url, size_t *new_len); - PHPAPI zend_result php_session_destroy(void); PHPAPI void php_add_session_var(zend_string *name); PHPAPI zval *php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash); @@ -264,7 +242,7 @@ PHPAPI zend_result php_session_register_serializer(const char *name, zend_result (*decode)(PS_SERIALIZER_DECODE_ARGS)); PHPAPI zend_result php_session_start(void); -PHPAPI zend_result php_session_flush(int write); +PHPAPI bool php_session_flush(bool write); PHPAPI php_session_status php_get_session_status(void); PHPAPI const ps_module *_php_find_ps_module(const char *name); @@ -273,43 +251,25 @@ PHPAPI const ps_serializer *_php_find_ps_serializer(const char *name); PHPAPI zend_result php_session_valid_key(const char *key); PHPAPI zend_result php_session_reset_id(void); -#define PS_ADD_VARL(name) do { \ - php_add_session_var(name); \ -} while (0) - -#define PS_ADD_VAR(name) PS_ADD_VARL(name) - -#define PS_DEL_VARL(name) do { \ - if (!Z_ISNULL(PS(http_session_vars))) { \ - zend_hash_del(Z_ARRVAL(PS(http_session_vars)), name); \ - } \ -} while (0) - - -#define PS_ENCODE_VARS \ - zend_string *key; \ - zend_ulong num_key; \ - zval *struc; - /* Do not use a return statement in `code` because that may leak memory. * Break out of the loop instead. */ -#define PS_ENCODE_LOOP(code) do { \ - zval _zv; \ - /* protect against user interference */ \ - ZVAL_COPY(&_zv, Z_REFVAL(PS(http_session_vars))); \ - HashTable *_ht = Z_ARRVAL(_zv); \ - ZEND_HASH_FOREACH_KEY(_ht, num_key, key) { \ - if (key == NULL) { \ - php_error_docref(NULL, E_WARNING, \ - "Skipping numeric key " ZEND_LONG_FMT, num_key);\ - continue; \ - } \ - if ((struc = php_get_session_var(key))) { \ - code; \ - } \ - } ZEND_HASH_FOREACH_END(); \ - zval_ptr_dtor(&_zv); \ -} while(0) +#define PS_ENCODE_LOOP(code) do { \ + zval _zv; \ + /* protect against user interference */ \ + ZVAL_COPY(&_zv, Z_REFVAL(PS(http_session_vars))); \ + ZEND_HASH_FOREACH_KEY(Z_ARRVAL(_zv), zend_ulong num_key, zend_string * key) { \ + if (key == NULL) { \ + php_error_docref(NULL, E_WARNING, \ + "Skipping numeric key " ZEND_LONG_FMT, num_key); \ + continue; \ + } \ + zval *struc = php_get_session_var(key); \ + if (struc) { \ + code; \ + } \ + } ZEND_HASH_FOREACH_END(); \ + zval_ptr_dtor(&_zv); \ +} while (0) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(ps) diff --git a/ext/session/session.c b/ext/session/session.c index 7b677249fb41..1fdfc5d1073f 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sascha Schumann | | Andrei Zmievski | @@ -54,6 +52,8 @@ #include "mod_mm.h" #endif +#include "zend_attributes.h" + PHPAPI ZEND_DECLARE_MODULE_GLOBALS(ps) static zend_result php_session_rfc1867_callback(unsigned int event, void *event_data, void **extra); @@ -74,6 +74,7 @@ zend_class_entry *php_session_update_timestamp_iface_entry; #define PS_MAX_SID_LENGTH 256 + /* *********** * Helpers * *********** */ @@ -81,16 +82,16 @@ zend_class_entry *php_session_update_timestamp_iface_entry; #define IF_SESSION_VARS() \ if (Z_ISREF_P(&PS(http_session_vars)) && Z_TYPE_P(Z_REFVAL(PS(http_session_vars))) == IS_ARRAY) -#define SESSION_CHECK_ACTIVE_STATE \ - if (PS(session_status) == php_session_active) { \ - php_session_session_already_started_error(E_WARNING, "Session ini settings cannot be changed when a session is active"); \ - return FAILURE; \ +#define SESSION_CHECK_ACTIVE_STATE \ + if (PS(session_status) == php_session_active) { \ + php_session_session_already_started_error(E_WARNING, "Session ini settings cannot be changed when a session is active"); \ + return FAILURE; \ } -#define SESSION_CHECK_OUTPUT_STATE \ - if (SG(headers_sent) && stage != ZEND_INI_STAGE_DEACTIVATE) { \ - php_session_headers_already_sent_error(E_WARNING, "Session ini settings cannot be changed after headers have already been sent"); \ - return FAILURE; \ +#define SESSION_CHECK_OUTPUT_STATE \ + if (SG(headers_sent) && stage != ZEND_INI_STAGE_DEACTIVATE) { \ + php_session_headers_already_sent_error(E_WARNING, "Session ini settings cannot be changed after headers have already been sent"); \ + return FAILURE; \ } #define SESSION_FORBIDDEN_CHARS "=,;.[ \t\r\n\013\014" @@ -99,7 +100,8 @@ zend_class_entry *php_session_update_timestamp_iface_entry; #define APPLY_TRANS_SID (PS(use_trans_sid) && !PS(use_only_cookies)) static zend_result php_session_send_cookie(void); -static zend_result php_session_abort(void); +static bool php_session_abort(void); +static void proposed_session_id_to_session_id(const zval *proposed_session_id); /* Initialized in MINIT, readonly otherwise. */ static int my_module_number = 0; @@ -111,11 +113,12 @@ static inline void php_rinit_session_globals(void) /* TODO: These could be moved to MINIT and removed. These should be initialized by php_rshutdown_session_globals() always when execution is finished. */ PS(id) = NULL; PS(session_status) = php_session_none; - PS(in_save_handler) = 0; - PS(set_handler) = 0; + PS(in_save_handler) = false; + PS(set_handler) = false; PS(mod_data) = NULL; - PS(mod_user_is_open) = 0; - PS(define_sid) = 1; + PS(mod_user_is_open) = false; + PS(mod_user_uses_object_methods_as_handlers) = false; + PS(define_sid) = true; PS(session_vars) = NULL; PS(module_number) = my_module_number; ZVAL_UNDEF(&PS(http_session_vars)); @@ -165,20 +168,15 @@ static void php_rshutdown_session_globals(void) } zend_end_try(); } if (PS(id)) { - zend_string_release_ex(PS(id), 0); + zend_string_release_ex(PS(id), false); PS(id) = NULL; } if (PS(session_vars)) { - zend_string_release_ex(PS(session_vars), 0); + zend_string_release_ex(PS(session_vars), false); PS(session_vars) = NULL; } - if (PS(mod_user_class_name)) { - zend_string_release(PS(mod_user_class_name)); - PS(mod_user_class_name) = NULL; - } - php_session_cleanup_filename(); /* User save handlers may end up directly here by misuse, bugs in user script, etc. */ @@ -221,7 +219,7 @@ PHPAPI void php_add_session_var(zend_string *name) } } -PHPAPI zval* php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash) +PHPAPI zval *php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash) { IF_SESSION_VARS() { zval *sess_var = Z_REFVAL(PS(http_session_vars)); @@ -231,7 +229,7 @@ PHPAPI zval* php_set_session_var(zend_string *name, zval *state_val, php_unseria return NULL; } -PHPAPI zval* php_get_session_var(zend_string *name) +PHPAPI zval *php_get_session_var(zend_string *name) { IF_SESSION_VARS() { return zend_hash_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name); @@ -239,7 +237,7 @@ PHPAPI zval* php_get_session_var(zend_string *name) return NULL; } -PHPAPI zval* php_get_session_var_str(const char *name, size_t name_len) +PHPAPI zval *php_get_session_var_str(const char *name, size_t name_len) { IF_SESSION_VARS() { return zend_hash_str_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name, name_len); @@ -250,7 +248,7 @@ PHPAPI zval* php_get_session_var_str(const char *name, size_t name_len) static void php_session_track_init(void) { zval session_vars; - zend_string *var_name = ZSTR_INIT_LITERAL("_SESSION", 0); + zend_string *var_name = ZSTR_INIT_LITERAL("_SESSION", false); /* Unconditionally destroy existing array -- possible dirty data */ zend_delete_global_variable(var_name); @@ -262,13 +260,13 @@ static void php_session_track_init(void) ZVAL_NEW_REF(&PS(http_session_vars), &session_vars); Z_ADDREF_P(&PS(http_session_vars)); zend_hash_update_ind(&EG(symbol_table), var_name, &PS(http_session_vars)); - zend_string_release_ex(var_name, 0); + zend_string_release_ex(var_name, false); } static zend_string *php_session_encode(void) { IF_SESSION_VARS() { - ZEND_ASSERT(PS(serializer)); + ZEND_ASSERT(PS(serializer)); return PS(serializer)->encode(); } else { php_error_docref(NULL, E_WARNING, "Cannot encode non-existent session"); @@ -283,9 +281,9 @@ static ZEND_COLD void php_session_cancel_decode(void) php_error_docref(NULL, E_WARNING, "Failed to decode session object. Session has been destroyed"); } -static zend_result php_session_decode(zend_string *data) +static zend_result php_session_decode(const zend_string *data) { - ZEND_ASSERT(PS(serializer)); + ZEND_ASSERT(PS(serializer)); zend_result result = SUCCESS; zend_try { if (PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data)) == FAILURE) { @@ -307,23 +305,17 @@ static zend_result php_session_decode(zend_string *data) static const char hexconvtab[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-"; -static void bin_to_readable(unsigned char *in, size_t inlen, char *out, size_t outlen, char nbits) +static void bin_to_readable(const unsigned char *in, size_t inlen, char *out, size_t outlen, char nbits) { - unsigned char *p, *q; - unsigned short w; - int mask; - int have; - - p = (unsigned char *)in; - q = (unsigned char *)in + inlen; - - w = 0; - have = 0; - mask = (1 << nbits) - 1; + const unsigned char *p = in; + const unsigned char *end_p = in + inlen; + unsigned short w = 0; + int have = 0; + const int mask = (1 << nbits) - 1; while (outlen--) { if (have < nbits) { - if (p < q) { + if (p < end_p) { w |= *p++ << have; have += 8; } else { @@ -353,7 +345,7 @@ PHPAPI zend_string *php_session_create_id(PS_CREATE_SID_ARGS) return NULL; } - outid = zend_string_alloc(PS(sid_length), 0); + outid = zend_string_alloc(PS(sid_length), false); bin_to_readable( rbuf, PS(sid_length), ZSTR_VAL(outid), ZSTR_LEN(outid), @@ -367,7 +359,7 @@ PHPAPI zend_string *php_session_create_id(PS_CREATE_SID_ARGS) * ps_modules appropriately */ PHPAPI zend_result php_session_valid_key(const char *key) { - size_t len; + size_t key_len; const char *p; char c; @@ -382,34 +374,34 @@ PHPAPI zend_result php_session_valid_key(const char *key) } } - len = p - key; + key_len = p - key; /* Somewhat arbitrary length limit here, but should be way more than anyone needs and avoids file-level warnings later on if we exceed MAX_PATH */ - if (len == 0 || len > PS_MAX_SID_LENGTH) { + if (key_len == 0 || key_len > PS_MAX_SID_LENGTH) { return FAILURE; } return SUCCESS; } - static zend_long php_session_gc(bool immediate) { - zend_long num = -1; + zend_long sessions_deleted = -1; bool collect = immediate; /* GC must be done before reading session data. */ if ((PS(mod_data) || PS(mod_user_implemented))) { + /* Use probability-based GC if not forced and probability is configured */ if (!collect && PS(gc_probability) > 0) { collect = php_random_range(PS(random), 0, PS(gc_divisor) - 1) < PS(gc_probability); } if (collect) { - PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &num); + PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &sessions_deleted); } } - return num; + return sessions_deleted; } static zend_result php_session_initialize(void) @@ -430,7 +422,7 @@ static zend_result php_session_initialize(void) ) { php_session_abort(); if (!EG(exception)) { - php_error_docref(NULL, E_WARNING, "Failed to initialize storage module: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + php_error_docref(NULL, E_WARNING, "Failed to initialize storage module: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } return FAILURE; } @@ -438,31 +430,29 @@ static zend_result php_session_initialize(void) /* If there is no ID, use session module to create one */ if (!PS(id) || !ZSTR_VAL(PS(id))[0]) { if (PS(id)) { - zend_string_release_ex(PS(id), 0); + zend_string_release_ex(PS(id), false); } PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { php_session_abort(); if (!EG(exception)) { - zend_throw_error(NULL, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + zend_throw_error(NULL, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } return FAILURE; } if (PS(use_cookies)) { - PS(send_cookie) = 1; + PS(send_cookie) = true; } } else if (PS(use_strict_mode) && PS(mod)->s_validate_sid && PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == FAILURE ) { - if (PS(id)) { - zend_string_release_ex(PS(id), 0); - } + zend_string_release_ex(PS(id), false); PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { PS(id) = php_session_create_id(NULL); } if (PS(use_cookies)) { - PS(send_cookie) = 1; + PS(send_cookie) = true; } } @@ -477,16 +467,16 @@ static zend_result php_session_initialize(void) php_session_abort(); /* FYI: Some broken save handlers return FAILURE for non-existent session ID, this is incorrect */ if (!EG(exception)) { - php_error_docref(NULL, E_WARNING, "Failed to read session data: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + php_error_docref(NULL, E_WARNING, "Failed to read session data: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } return FAILURE; } /* GC must be done after read */ - php_session_gc(0); + php_session_gc(false); if (PS(session_vars)) { - zend_string_release_ex(PS(session_vars), 0); + zend_string_release_ex(PS(session_vars), false); PS(session_vars) = NULL; } if (val) { @@ -494,7 +484,7 @@ static zend_result php_session_initialize(void) PS(session_vars) = zend_string_copy(val); } php_session_decode(val); - zend_string_release_ex(val, 0); + zend_string_release_ex(val, false); } php_session_cleanup_filename(); @@ -506,36 +496,32 @@ static zend_result php_session_initialize(void) return SUCCESS; } -static void php_session_save_current_state(int write) +static void php_session_save_current_state(bool write) { zend_result ret = FAILURE; if (write) { IF_SESSION_VARS() { - zend_string *handler_class_name = PS(mod_user_class_name); - const char *handler_function_name; - + zval *handler_function = &PS(mod_user_names).ps_write; if (PS(mod_data) || PS(mod_user_implemented)) { - zend_string *val; - - val = php_session_encode(); - if (val) { - if (PS(lazy_write) && PS(session_vars) - && PS(mod)->s_update_timestamp - && PS(mod)->s_update_timestamp != php_session_update_timestamp - && zend_string_equals(val, PS(session_vars)) - ) { - ret = PS(mod)->s_update_timestamp(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); - handler_function_name = handler_class_name != NULL ? "updateTimestamp" : "update_timestamp"; - } else { - ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); - handler_function_name = "write"; - } - zend_string_release_ex(val, 0); + zend_string *val = php_session_encode(); + /* Not being able to encode the session data means there is some kind of issue that prevents a write + * (e.g. a key containing the '|' character with the default serialization) */ + if (UNEXPECTED(val == NULL)) { + return; + } + + if (PS(lazy_write) && PS(session_vars) + && PS(mod)->s_update_timestamp + && PS(mod)->s_update_timestamp != php_session_update_timestamp + && zend_string_equals(val, PS(session_vars)) + ) { + ret = PS(mod)->s_update_timestamp(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); + handler_function = &PS(mod_user_names).ps_update_timestamp; } else { - ret = PS(mod)->s_write(&PS(mod_data), PS(id), ZSTR_EMPTY_ALLOC(), PS(gc_maxlifetime)); - handler_function_name = "write"; + ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, PS(gc_maxlifetime)); } + zend_string_release_ex(val, false); } if ((ret == FAILURE) && !EG(exception)) { @@ -544,15 +530,13 @@ static void php_session_save_current_state(int write) "verify that the current setting of session.save_path " "is correct (%s)", PS(mod)->s_name, - PS(save_path)); - } else if (handler_class_name != NULL) { - php_error_docref(NULL, E_WARNING, "Failed to write session data using user " - "defined save handler. (session.save_path: %s, handler: %s::%s)", PS(save_path), - ZSTR_VAL(handler_class_name), handler_function_name); + ZSTR_VAL(PS(save_path))); } else { + zend_string *callable_name = zend_get_callable_name(handler_function); php_error_docref(NULL, E_WARNING, "Failed to write session data using user " - "defined save handler. (session.save_path: %s, handler: %s)", PS(save_path), - handler_function_name); + "defined save handler. (session.save_path: %s, handler: %s)", ZSTR_VAL(PS(save_path)), + ZSTR_VAL(callable_name)); + zend_string_release_ex(callable_name, false); } } } @@ -565,8 +549,6 @@ static void php_session_save_current_state(int write) static void php_session_normalize_vars(void) { - PS_ENCODE_VARS; - IF_SESSION_VARS() { PS_ENCODE_LOOP( if (Z_TYPE_P(struc) == IS_PTR) { @@ -578,25 +560,26 @@ static void php_session_normalize_vars(void) } } + /* ************************* * INI Settings/Handlers * ************************* */ static PHP_INI_MH(OnUpdateSaveHandler) { - const ps_module *tmp; + const ps_module *new_module; int err_type = E_ERROR; SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - tmp = _php_find_ps_module(ZSTR_VAL(new_value)); + new_module = _php_find_ps_module(ZSTR_VAL(new_value)); if (stage == ZEND_INI_STAGE_RUNTIME) { err_type = E_WARNING; } - if (PG(modules_activated) && !tmp) { + if (PG(modules_activated) && !new_module) { /* Do not output error when restoring ini options. */ if (stage != ZEND_INI_STAGE_DEACTIVATE) { php_error_docref(NULL, err_type, "Session save handler \"%s\" cannot be found", ZSTR_VAL(new_value)); @@ -606,27 +589,27 @@ static PHP_INI_MH(OnUpdateSaveHandler) } /* "user" save handler should not be set by user */ - if (!PS(set_handler) && tmp == ps_user_ptr) { + if (!PS(set_handler) && new_module == ps_user_ptr) { php_error_docref(NULL, err_type, "Session save handler \"user\" cannot be set by ini_set()"); return FAILURE; } PS(default_mod) = PS(mod); - PS(mod) = tmp; + PS(mod) = new_module; return SUCCESS; } static PHP_INI_MH(OnUpdateSerializer) { - const ps_serializer *tmp; + const ps_serializer *new_serializer; SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - tmp = _php_find_ps_serializer(ZSTR_VAL(new_value)); + new_serializer = _php_find_ps_serializer(ZSTR_VAL(new_value)); - if (PG(modules_activated) && !tmp) { + if (PG(modules_activated) && !new_serializer) { int err_type; if (stage == ZEND_INI_STAGE_RUNTIME) { @@ -641,7 +624,8 @@ static PHP_INI_MH(OnUpdateSerializer) } return FAILURE; } - PS(serializer) = tmp; + + PS(serializer) = new_serializer; return SUCCESS; } @@ -651,19 +635,19 @@ static PHP_INI_MH(OnUpdateSaveDir) SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - /* Only do the safemode/open_basedir check at runtime */ + /* Only do the open_basedir check at runtime */ if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) { - char *p; - - if (memchr(ZSTR_VAL(new_value), '\0', ZSTR_LEN(new_value)) != NULL) { + if (zend_str_has_nul_byte(new_value)) { return FAILURE; } /* we do not use zend_memrchr() since path can contain ; itself */ - if ((p = strchr(ZSTR_VAL(new_value), ';'))) { - char *p2; + const char *p = strchr(ZSTR_VAL(new_value), ';'); + if (p) { p++; - if ((p2 = strchr(p, ';'))) { + + const char *p2 = strchr(p, ';'); + if (p2) { p = p2 + 1; } } else { @@ -675,10 +659,9 @@ static PHP_INI_MH(OnUpdateSaveDir) } } - return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); + return OnUpdateStr(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateName) { SESSION_CHECK_ACTIVE_STATE; @@ -706,10 +689,9 @@ static PHP_INI_MH(OnUpdateName) return FAILURE; } - return OnUpdateStringUnempty(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); + return OnUpdateStrNotEmpty(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateCookieLifetime) { SESSION_CHECK_ACTIVE_STATE; @@ -720,40 +702,70 @@ static PHP_INI_MH(OnUpdateCookieLifetime) #else const zend_long maxcookie = ZEND_LONG_MAX / 2 - 1; #endif - zend_long v = (zend_long)atol(ZSTR_VAL(new_value)); - if (v < 0) { - php_error_docref(NULL, E_WARNING, "CookieLifetime cannot be negative"); + zend_long lval = 0; + int oflow = 0; + uint8_t type = is_numeric_string_ex(ZSTR_VAL(new_value), ZSTR_LEN(new_value), &lval, NULL, false, &oflow, NULL); + if (UNEXPECTED(type != IS_LONG)) { + if (oflow != 0) { + php_error_docref(NULL, E_WARNING, "session.cookie_lifetime must be between 0 and " ZEND_LONG_FMT, maxcookie); + } else { + php_error_docref(NULL, E_WARNING, "session.cookie_lifetime must be of type int"); + } return FAILURE; - } else if (v > maxcookie) { - return SUCCESS; } + if (lval < 0 || lval > maxcookie) { + php_error_docref(NULL, E_WARNING, "session.cookie_lifetime must be between 0 and " ZEND_LONG_FMT, maxcookie); + return FAILURE; + } + return OnUpdateLongGEZero(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateSessionLong) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + return OnUpdateLong(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } -static PHP_INI_MH(OnUpdateSessionString) +static PHP_INI_MH(OnUpdateSessionStr) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); + + if (new_value && zend_str_has_nul_byte(new_value)) { + if (stage != ZEND_INI_STAGE_DEACTIVATE) { + php_error_docref(NULL, E_WARNING, "\"%s\" must not contain null bytes", ZSTR_VAL(entry->name)); + } + return FAILURE; + } + + return OnUpdateStr(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } +static PHP_INI_MH(OnUpdateSessionSameSite) +{ + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; + + if (new_value && ZSTR_LEN(new_value) > 0 && !php_is_valid_samesite_value(new_value)) { + php_error_docref(NULL, E_WARNING, + "session.cookie_samesite must be \"Strict\", \"Lax\", \"None\", or \"\""); + return FAILURE; + } + + return OnUpdateStr(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} static PHP_INI_MH(OnUpdateSessionBool) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } - static PHP_INI_MH(OnUpdateSidLength) { zend_long val; @@ -761,19 +773,21 @@ static PHP_INI_MH(OnUpdateSidLength) SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + val = ZEND_STRTOL(ZSTR_VAL(new_value), &endptr, 10); + if (val != 32) { php_error_docref("session.configuration", E_DEPRECATED, "session.sid_length INI setting is deprecated"); } - if (endptr && (*endptr == '\0') - && val >= 22 && val <= PS_MAX_SID_LENGTH) { - /* Numeric value */ - PS(sid_length) = val; - return SUCCESS; + + if (!endptr || (*endptr != '\0') || (val < 22) || (val > PS_MAX_SID_LENGTH)) { + php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_length\" must be between 22 and 256"); + return FAILURE; } - php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_length\" must be between 22 and 256"); - return FAILURE; + PS(sid_length) = val; + + return SUCCESS; } static PHP_INI_MH(OnUpdateSidBits) @@ -783,73 +797,78 @@ static PHP_INI_MH(OnUpdateSidBits) SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + val = ZEND_STRTOL(ZSTR_VAL(new_value), &endptr, 10); + if (val != 4) { php_error_docref("session.configuration", E_DEPRECATED, "session.sid_bits_per_character INI setting is deprecated"); } - if (endptr && (*endptr == '\0') - && val >= 4 && val <=6) { - /* Numeric value */ - PS(sid_bits_per_character) = val; - return SUCCESS; + + if (!endptr || (*endptr != '\0') || (val < 4) || (val > 6)) { + php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_bits_per_character\" must be between 4 and 6"); + return FAILURE; } - php_error_docref(NULL, E_WARNING, "session.configuration \"session.sid_bits_per_character\" must be between 4 and 6"); - return FAILURE; + PS(sid_bits_per_character) = val; + + return SUCCESS; } static PHP_INI_MH(OnUpdateSessionGcProbability) { - SESSION_CHECK_ACTIVE_STATE; - SESSION_CHECK_OUTPUT_STATE; + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; - zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + zend_long new_probability = zend_ini_parse_quantity_warn(new_value, entry->name); - if (tmp < 0) { - php_error_docref("session.gc_probability", E_WARNING, "session.gc_probability must be greater than or equal to 0"); - return FAILURE; - } + if (new_probability < 0) { + php_error_docref("session.gc_probability", E_WARNING, "session.gc_probability must be greater than or equal to 0"); + return FAILURE; + } - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); - *p = tmp; + zend_long *p = ZEND_INI_GET_ADDR(); + *p = new_probability; - return SUCCESS; + return SUCCESS; } static PHP_INI_MH(OnUpdateSessionDivisor) { - SESSION_CHECK_ACTIVE_STATE; - SESSION_CHECK_OUTPUT_STATE; + SESSION_CHECK_ACTIVE_STATE; + SESSION_CHECK_OUTPUT_STATE; - zend_long tmp = zend_ini_parse_quantity_warn(new_value, entry->name); + zend_long new_divisor = zend_ini_parse_quantity_warn(new_value, entry->name); - if (tmp <= 0) { - php_error_docref("session.gc_divisor", E_WARNING, "session.gc_divisor must be greater than 0"); - return FAILURE; - } + if (new_divisor <= 0) { + php_error_docref("session.gc_divisor", E_WARNING, "session.gc_divisor must be greater than 0"); + return FAILURE; + } - zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); - *p = tmp; + zend_long *p = ZEND_INI_GET_ADDR(); + *p = new_divisor; - return SUCCESS; + return SUCCESS; } static PHP_INI_MH(OnUpdateRfc1867Freq) { - int tmp = ZEND_ATOL(ZSTR_VAL(new_value)); - if(tmp < 0) { + int new_freq = ZEND_ATOL(ZSTR_VAL(new_value)); + + if (new_freq < 0) { php_error_docref(NULL, E_WARNING, "session.upload_progress.freq must be greater than or equal to 0"); return FAILURE; } - if(ZSTR_LEN(new_value) > 0 && ZSTR_VAL(new_value)[ZSTR_LEN(new_value)-1] == '%') { - if(tmp > 100) { + + if (ZSTR_LEN(new_value) > 0 && ZSTR_VAL(new_value)[ZSTR_LEN(new_value) - 1] == '%') { + if (new_freq > 100) { php_error_docref(NULL, E_WARNING, "session.upload_progress.freq must be less than or equal to 100%%"); return FAILURE; } - PS(rfc1867_freq) = -tmp; + PS(rfc1867_freq) = -new_freq; } else { - PS(rfc1867_freq) = tmp; + PS(rfc1867_freq) = new_freq; } + return SUCCESS; } @@ -857,11 +876,14 @@ static PHP_INI_MH(OnUpdateUseOnlyCookies) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - bool *p = (bool *) ZEND_INI_GET_ADDR(); + + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); + if (!*p) { php_error_docref("session.configuration", E_DEPRECATED, "Disabling session.use_only_cookies INI setting is deprecated"); } + return SUCCESS; } @@ -869,11 +891,14 @@ static PHP_INI_MH(OnUpdateUseTransSid) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; - bool *p = (bool *) ZEND_INI_GET_ADDR(); + + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); + if (*p) { php_error_docref("session.configuration", E_DEPRECATED, "Enabling session.use_trans_sid INI setting is deprecated"); } + return SUCCESS; } @@ -881,37 +906,40 @@ static PHP_INI_MH(OnUpdateRefererCheck) { SESSION_CHECK_ACTIVE_STATE; SESSION_CHECK_OUTPUT_STATE; + if (ZSTR_LEN(new_value) != 0) { php_error_docref("session.configuration", E_DEPRECATED, "Usage of session.referer_check INI setting is deprecated"); } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("session.save_path", "", PHP_INI_ALL, OnUpdateSaveDir, save_path, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name, php_ps_globals, ps_globals) - PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL, OnUpdateSaveHandler) - STD_PHP_INI_BOOLEAN("session.auto_start", "0", PHP_INI_PERDIR, OnUpdateBool, auto_start, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionGcProbability, gc_probability, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionDivisor,gc_divisor, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.gc_maxlifetime", "1440", PHP_INI_ALL, OnUpdateSessionLong, gc_maxlifetime, php_ps_globals, ps_globals) - PHP_INI_ENTRY("session.serialize_handler", "php", PHP_INI_ALL, OnUpdateSerializer) - STD_PHP_INI_ENTRY("session.cookie_lifetime", "0", PHP_INI_ALL, OnUpdateCookieLifetime,cookie_lifetime, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cookie_path", "/", PHP_INI_ALL, OnUpdateSessionString, cookie_path, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cookie_domain", "", PHP_INI_ALL, OnUpdateSessionString, cookie_domain, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.cookie_secure", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_secure, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.cookie_httponly", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cookie_samesite", "", PHP_INI_ALL, OnUpdateSessionString, cookie_samesite, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateUseOnlyCookies, use_only_cookies, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateRefererCheck, extern_referer_chk, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionString, cache_limiter, php_ps_globals, ps_globals) - STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) - STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateUseTransSid, use_trans_sid, php_ps_globals, ps_globals) - PHP_INI_ENTRY("session.sid_length", "32", PHP_INI_ALL, OnUpdateSidLength) - PHP_INI_ENTRY("session.sid_bits_per_character", "4", PHP_INI_ALL, OnUpdateSidBits) - STD_PHP_INI_BOOLEAN("session.lazy_write", "1", PHP_INI_ALL, OnUpdateSessionBool, lazy_write, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.save_path", "", PHP_INI_ALL, OnUpdateSaveDir, save_path, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL, OnUpdateName, session_name, php_ps_globals, ps_globals) + PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL, OnUpdateSaveHandler) + STD_PHP_INI_BOOLEAN("session.auto_start", "0", PHP_INI_PERDIR, OnUpdateBool, auto_start, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_probability", "1", PHP_INI_ALL, OnUpdateSessionGcProbability, gc_probability, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_divisor", "100", PHP_INI_ALL, OnUpdateSessionDivisor, gc_divisor, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.gc_maxlifetime", "1440", PHP_INI_ALL, OnUpdateSessionLong, gc_maxlifetime, php_ps_globals, ps_globals) + PHP_INI_ENTRY("session.serialize_handler", "php", PHP_INI_ALL, OnUpdateSerializer) + STD_PHP_INI_ENTRY("session.cookie_lifetime", "0", PHP_INI_ALL, OnUpdateCookieLifetime, cookie_lifetime, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cookie_path", "/", PHP_INI_ALL, OnUpdateSessionStr, cookie_path, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cookie_domain", "", PHP_INI_ALL, OnUpdateSessionStr, cookie_domain, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.cookie_secure", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_secure, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.cookie_partitioned", "0", PHP_INI_ALL, OnUpdateSessionBool, cookie_partitioned, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.cookie_httponly", "1", PHP_INI_ALL, OnUpdateSessionBool, cookie_httponly, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cookie_samesite", "Lax", PHP_INI_ALL, OnUpdateSessionSameSite, cookie_samesite, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateSessionBool, use_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateUseOnlyCookies, use_only_cookies, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateSessionBool, use_strict_mode, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateRefererCheck, extern_referer_chk, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cache_limiter", "nocache", PHP_INI_ALL, OnUpdateSessionStr, cache_limiter, php_ps_globals, ps_globals) + STD_PHP_INI_ENTRY("session.cache_expire", "180", PHP_INI_ALL, OnUpdateSessionLong, cache_expire, php_ps_globals, ps_globals) + STD_PHP_INI_BOOLEAN("session.use_trans_sid", "0", PHP_INI_ALL, OnUpdateUseTransSid, use_trans_sid, php_ps_globals, ps_globals) + PHP_INI_ENTRY("session.sid_length", "32", PHP_INI_ALL, OnUpdateSidLength) + PHP_INI_ENTRY("session.sid_bits_per_character", "4", PHP_INI_ALL, OnUpdateSidBits) + STD_PHP_INI_BOOLEAN("session.lazy_write", "1", PHP_INI_ALL, OnUpdateSessionBool, lazy_write, php_ps_globals, ps_globals) /* Upload progress */ STD_PHP_INI_BOOLEAN("session.upload_progress.enabled", @@ -919,9 +947,9 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("session.upload_progress.cleanup", "1", ZEND_INI_PERDIR, OnUpdateBool, rfc1867_cleanup, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.upload_progress.prefix", - "upload_progress_", ZEND_INI_PERDIR, OnUpdateString, rfc1867_prefix, php_ps_globals, ps_globals) + "upload_progress_", ZEND_INI_PERDIR, OnUpdateStr, rfc1867_prefix, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.upload_progress.name", - "PHP_SESSION_UPLOAD_PROGRESS", ZEND_INI_PERDIR, OnUpdateString, rfc1867_name, php_ps_globals, ps_globals) + "PHP_SESSION_UPLOAD_PROGRESS", ZEND_INI_PERDIR, OnUpdateStr, rfc1867_name, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.upload_progress.freq", "1%", ZEND_INI_PERDIR, OnUpdateRfc1867Freq, rfc1867_freq, php_ps_globals, ps_globals) STD_PHP_INI_ENTRY("session.upload_progress.min_freq", "1", ZEND_INI_PERDIR, OnUpdateReal, rfc1867_min_freq,php_ps_globals, ps_globals) @@ -930,9 +958,11 @@ PHP_INI_BEGIN() /* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */ PHP_INI_END() + /* *************** * Serializers * *************** */ + PS_SERIALIZER_ENCODE_FUNC(php_serialize) { smart_str buf = {0}; @@ -943,7 +973,7 @@ PS_SERIALIZER_ENCODE_FUNC(php_serialize) php_var_serialize(&buf, Z_REFVAL(PS(http_session_vars)), &var_hash); PHP_VAR_SERIALIZE_DESTROY(var_hash); } - return buf.s; + return smart_str_extract(&buf); } PS_SERIALIZER_DECODE_FUNC(php_serialize) @@ -952,7 +982,7 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) zval session_vars; php_unserialize_data_t var_hash; bool result; - zend_string *var_name = ZSTR_INIT_LITERAL("_SESSION", 0); + zend_string *var_name = ZSTR_INIT_LITERAL("_SESSION", false); ZVAL_NULL(&session_vars); PHP_VAR_UNSERIALIZE_INIT(var_hash); @@ -973,7 +1003,7 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) ZVAL_NEW_REF(&PS(http_session_vars), &session_vars); Z_ADDREF_P(&PS(http_session_vars)); zend_hash_update_ind(&EG(symbol_table), var_name, &PS(http_session_vars)); - zend_string_release_ex(var_name, 0); + zend_string_release_ex(var_name, false); return result || !vallen ? SUCCESS : FAILURE; } @@ -985,34 +1015,28 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary) { smart_str buf = {0}; php_serialize_data_t var_hash; - PS_ENCODE_VARS; PHP_VAR_SERIALIZE_INIT(var_hash); PS_ENCODE_LOOP( if (ZSTR_LEN(key) > PS_BIN_MAX) continue; smart_str_appendc(&buf, (unsigned char)ZSTR_LEN(key)); - smart_str_appendl(&buf, ZSTR_VAL(key), ZSTR_LEN(key)); + smart_str_append(&buf, key); php_var_serialize(&buf, struc, &var_hash); ); - - smart_str_0(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); - return buf.s; + return smart_str_extract(&buf); } PS_SERIALIZER_DECODE_FUNC(php_binary) { - const char *p; const char *endptr = val + vallen; - zend_string *name; php_unserialize_data_t var_hash; - zval *current, rv; PHP_VAR_UNSERIALIZE_INIT(var_hash); - for (p = val; p < endptr; ) { + for (const char *p = val; p < endptr; ) { size_t namelen = ((unsigned char)(*p)) & (~PS_BIN_UNDEF); if (namelen > PS_BIN_MAX || (p + namelen) >= endptr) { @@ -1020,20 +1044,21 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) return FAILURE; } - name = zend_string_init(p + 1, namelen, 0); + zend_string *name = zend_string_init(p + 1, namelen, false); p += namelen + 1; - current = var_tmp_var(&var_hash); + zval *current = var_tmp_var(&var_hash); if (php_var_unserialize(current, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash)) { + zval rv; ZVAL_PTR(&rv, current); php_set_session_var(name, &rv, &var_hash); } else { - zend_string_release_ex(name, 0); + zend_string_release_ex(name, false); php_session_normalize_vars(); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return FAILURE; } - zend_string_release_ex(name, 0); + zend_string_release_ex(name, false); } php_session_normalize_vars(); @@ -1049,14 +1074,12 @@ PS_SERIALIZER_ENCODE_FUNC(php) smart_str buf = {0}; php_serialize_data_t var_hash; bool fail = false; - PS_ENCODE_VARS; PHP_VAR_SERIALIZE_INIT(var_hash); PS_ENCODE_LOOP( - smart_str_appendl(&buf, ZSTR_VAL(key), ZSTR_LEN(key)); + smart_str_append(&buf, key); if (memchr(ZSTR_VAL(key), PS_DELIMITER, ZSTR_LEN(key))) { - PHP_VAR_SERIALIZE_DESTROY(var_hash); smart_str_free(&buf); fail = true; php_error_docref(NULL, E_WARNING, "Failed to write session data. Data contains invalid key \"%s\"", ZSTR_VAL(key)); @@ -1065,15 +1088,15 @@ PS_SERIALIZER_ENCODE_FUNC(php) smart_str_appendc(&buf, PS_DELIMITER); php_var_serialize(&buf, struc, &var_hash); ); + PHP_VAR_SERIALIZE_DESTROY(var_hash); if (fail) { return NULL; } - smart_str_0(&buf); + zend_string *encoded = smart_str_extract(&buf); - PHP_VAR_SERIALIZE_DESTROY(var_hash); - return buf.s; + return encoded; } PS_SERIALIZER_DECODE_FUNC(php) @@ -1100,7 +1123,7 @@ PS_SERIALIZER_DECODE_FUNC(php) } namelen = q - p; - name = zend_string_init(p, namelen, 0); + name = zend_string_init(p, namelen, false); q++; current = var_tmp_var(&var_hash); @@ -1108,11 +1131,11 @@ PS_SERIALIZER_DECODE_FUNC(php) ZVAL_PTR(&rv, current); php_set_session_var(name, &rv, &var_hash); } else { - zend_string_release_ex(name, 0); + zend_string_release_ex(name, false); retval = FAILURE; goto break_outer_loop; } - zend_string_release_ex(name, 0); + zend_string_release_ex(name, false); p = q; } @@ -1150,6 +1173,7 @@ PHPAPI zend_result php_session_register_serializer(const char *name, zend_string return ret; } + /* ******************* * Storage Modules * ******************* */ @@ -1164,7 +1188,7 @@ static const ps_module *ps_modules[MAX_MODULES + 1] = { PHPAPI zend_result php_session_register_module(const ps_module *ptr) { - int ret = FAILURE; + zend_result ret = FAILURE; for (int i = 0; i < MAX_MODULES; i++) { if (!ps_modules[i]) { @@ -1194,7 +1218,7 @@ PHPAPI zend_result php_session_update_timestamp(PS_UPDATE_TIMESTAMP_ARGS) { ****************** */ typedef struct { - char *name; + const char *name; void (*func)(void); } php_session_cache_limiter_t; @@ -1204,16 +1228,16 @@ typedef struct { #define ADD_HEADER(a) sapi_add_header(a, strlen(a), 1); #define MAX_STR 512 -static const char *month_names[] = { +static const char *const month_names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static const char *week_days[] = { +static const char *const week_days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; -static inline void strcpy_gmt(char *ubuf, time_t *when) +static inline void strcpy_gmt(char *ubuf, const time_t *when) { char buf[MAX_STR]; struct tm tm, *res; @@ -1310,9 +1334,9 @@ static const php_session_cache_limiter_t php_session_cache_limiters[] = { static int php_session_cache_limiter(void) { - const php_session_cache_limiter_t *lim; - - if (PS(cache_limiter)[0] == '\0') return 0; + if (ZSTR_LEN(PS(cache_limiter)) == 0) { + return 0; + } if (PS(session_status) != php_session_active) return -1; if (SG(headers_sent)) { @@ -1321,8 +1345,8 @@ static int php_session_cache_limiter(void) return -2; } - for (lim = php_session_cache_limiters; lim->name; lim++) { - if (!strcasecmp(lim->name, PS(cache_limiter))) { + for (const php_session_cache_limiter_t *lim = php_session_cache_limiters; lim->name; lim++) { + if (!strcasecmp(lim->name, ZSTR_VAL(PS(cache_limiter)))) { lim->func(); return 0; } @@ -1331,50 +1355,24 @@ static int php_session_cache_limiter(void) return -1; } + /* ********************* * Cookie Management * ********************* */ -/* - * Remove already sent session ID cookie. - * It must be directly removed from SG(sapi_header) because sapi_add_header_ex() - * removes all of matching cookie. i.e. It deletes all of Set-Cookie headers. - */ static void php_session_remove_cookie(void) { - sapi_header_struct *header; - zend_llist *l = &SG(sapi_headers).headers; - zend_llist_element *next; - zend_llist_element *current; char *session_cookie; size_t session_cookie_len; - size_t len = sizeof("Set-Cookie")-1; - - ZEND_ASSERT(strpbrk(PS(session_name), SESSION_FORBIDDEN_CHARS) == NULL); - spprintf(&session_cookie, 0, "Set-Cookie: %s=", PS(session_name)); - - session_cookie_len = strlen(session_cookie); - current = l->head; - while (current) { - header = (sapi_header_struct *)(current->data); - next = current->next; - if (header->header_len > len && header->header[len] == ':' - && !strncmp(header->header, session_cookie, session_cookie_len)) { - if (current->prev) { - current->prev->next = next; - } else { - l->head = next; - } - if (next) { - next->prev = current->prev; - } else { - l->tail = current->prev; - } - sapi_free_header(header); - efree(current); - --l->count; - } - current = next; - } + sapi_header_line header_line = {0}; + + ZEND_ASSERT(strpbrk(ZSTR_VAL(PS(session_name)), SESSION_FORBIDDEN_CHARS) == NULL); + session_cookie_len = spprintf(&session_cookie, 0, "Set-Cookie: %s=", ZSTR_VAL(PS(session_name))); + + header_line.line = session_cookie; + header_line.line_len = session_cookie_len; + header_line.header_len = sizeof("Set-Cookie") - 1; + sapi_header_op(SAPI_HEADER_DELETE_PREFIX, &header_line); + efree(session_cookie); } @@ -1389,17 +1387,23 @@ static zend_result php_session_send_cookie(void) return FAILURE; } - ZEND_ASSERT(strpbrk(PS(session_name), SESSION_FORBIDDEN_CHARS) == NULL); + /* Check for invalid settings combinations */ + if (UNEXPECTED(PS(cookie_partitioned) && !PS(cookie_secure))) { + php_error_docref(NULL, E_WARNING, "Partitioned session cookie cannot be used without also configuring it as secure"); + return FAILURE; + } + + ZEND_ASSERT(strpbrk(ZSTR_VAL(PS(session_name)), SESSION_FORBIDDEN_CHARS) == NULL); /* URL encode id because it might be user supplied */ e_id = php_url_encode(ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id))); - smart_str_appendl(&ncookie, "Set-Cookie: ", sizeof("Set-Cookie: ")-1); - smart_str_appendl(&ncookie, PS(session_name), strlen(PS(session_name))); + smart_str_appends(&ncookie, "Set-Cookie: "); + smart_str_append(&ncookie, PS(session_name)); smart_str_appendc(&ncookie, '='); - smart_str_appendl(&ncookie, ZSTR_VAL(e_id), ZSTR_LEN(e_id)); + smart_str_append(&ncookie, e_id); - zend_string_release_ex(e_id, 0); + zend_string_release_ex(e_id, false); if (PS(cookie_lifetime) > 0) { struct timeval tv; @@ -1409,45 +1413,49 @@ static zend_result php_session_send_cookie(void) t = tv.tv_sec + PS(cookie_lifetime); if (t > 0) { - date_fmt = php_format_date("D, d M Y H:i:s \\G\\M\\T", sizeof("D, d M Y H:i:s \\G\\M\\T")-1, t, 0); + date_fmt = php_format_date(ZEND_STRL("D, d M Y H:i:s \\G\\M\\T"), t, false); smart_str_appends(&ncookie, COOKIE_EXPIRES); - smart_str_appendl(&ncookie, ZSTR_VAL(date_fmt), ZSTR_LEN(date_fmt)); - zend_string_release_ex(date_fmt, 0); + smart_str_append(&ncookie, date_fmt); + zend_string_release_ex(date_fmt, false); smart_str_appends(&ncookie, COOKIE_MAX_AGE); smart_str_append_long(&ncookie, PS(cookie_lifetime)); } } - if (PS(cookie_path)[0]) { + if (ZSTR_LEN(PS(cookie_path))) { smart_str_appends(&ncookie, COOKIE_PATH); - smart_str_appends(&ncookie, PS(cookie_path)); + smart_str_append(&ncookie, PS(cookie_path)); } - if (PS(cookie_domain)[0]) { + if (ZSTR_LEN(PS(cookie_domain))) { smart_str_appends(&ncookie, COOKIE_DOMAIN); - smart_str_appends(&ncookie, PS(cookie_domain)); + smart_str_append(&ncookie, PS(cookie_domain)); } if (PS(cookie_secure)) { smart_str_appends(&ncookie, COOKIE_SECURE); } + if (PS(cookie_partitioned)) { + smart_str_appends(&ncookie, COOKIE_PARTITIONED); + } + if (PS(cookie_httponly)) { smart_str_appends(&ncookie, COOKIE_HTTPONLY); } - if (PS(cookie_samesite)[0]) { + if (ZSTR_LEN(PS(cookie_samesite))) { smart_str_appends(&ncookie, COOKIE_SAMESITE); - smart_str_appends(&ncookie, PS(cookie_samesite)); + smart_str_append(&ncookie, PS(cookie_samesite)); } smart_str_0(&ncookie); php_session_remove_cookie(); /* remove already sent session ID cookie */ - /* 'replace' must be 0 here, else a previous Set-Cookie - header, probably sent with setcookie() will be replaced! */ - sapi_add_header_ex(estrndup(ZSTR_VAL(ncookie.s), ZSTR_LEN(ncookie.s)), ZSTR_LEN(ncookie.s), 0, 0); + /* 'replace' must be 0 here, else a previous Set-Cookie + header, probably sent with setcookie() will be replaced! */ + sapi_add_header_ex(estrndup(ZSTR_VAL(ncookie.s), ZSTR_LEN(ncookie.s)), ZSTR_LEN(ncookie.s), false, false); smart_str_free(&ncookie); return SUCCESS; @@ -1455,49 +1463,140 @@ static zend_result php_session_send_cookie(void) PHPAPI const ps_module *_php_find_ps_module(const char *name) { - const ps_module *ret = NULL; - const ps_module **mod; - int i; + const ps_module *found_module = NULL; + const ps_module **current_module; + int module_index; - for (i = 0, mod = ps_modules; i < MAX_MODULES; i++, mod++) { - if (*mod && !strcasecmp(name, (*mod)->s_name)) { - ret = *mod; + for (module_index = 0, current_module = ps_modules; module_index < MAX_MODULES; module_index++, current_module++) { + if (*current_module && !strcasecmp(name, (*current_module)->s_name)) { + found_module = *current_module; break; } } - return ret; + return found_module; } PHPAPI const ps_serializer *_php_find_ps_serializer(const char *name) { - const ps_serializer *ret = NULL; - const ps_serializer *mod; + const ps_serializer *found_serializer = NULL; - for (mod = ps_serializers; mod->name; mod++) { - if (!strcasecmp(name, mod->name)) { - ret = mod; + for (const ps_serializer *current_serializer = ps_serializers; current_serializer->name; current_serializer++) { + if (!strcasecmp(name, current_serializer->name)) { + found_serializer = current_serializer; break; } } - return ret; + return found_serializer; } -static void ppid2sid(zval *ppid) { - ZVAL_DEREF(ppid); - if (Z_TYPE_P(ppid) == IS_STRING) { - PS(id) = zend_string_init(Z_STRVAL_P(ppid), Z_STRLEN_P(ppid), 0); - PS(send_cookie) = 0; +static bool should_invalidate_session_for_external_referer(void) +{ + /* No external referer check configured */ + if (!PS(id) || PS(extern_referer_chk)[0] == '\0') { + return false; + } + + /* No SERVER globals available */ + if (Z_ISUNDEF(PG(http_globals)[TRACK_VARS_SERVER])) { + return false; + } + + /* Get HTTP_REFERER header */ + const zval *referer_data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), ZEND_STRL("HTTP_REFERER")); + if (!referer_data || Z_TYPE_P(referer_data) != IS_STRING || Z_STRLEN_P(referer_data) == 0) { + return false; + } + + /* Check if referer contains expected string */ + return strstr(Z_STRVAL_P(referer_data), PS(extern_referer_chk)) == NULL; +} + +static void try_find_session_id_in_global(const char *global_name, size_t global_name_len) +{ + zval *global_data; + + if (PS(id)) { + return; + } + + global_data = zend_hash_str_find(&EG(symbol_table), global_name, global_name_len); + if (!global_data) { + return; + } + + ZVAL_DEREF(global_data); + if (Z_TYPE_P(global_data) != IS_ARRAY) { + return; + } + + const zval *potential_session_id = zend_hash_find(Z_ARRVAL_P(global_data), PS(session_name)); + if (potential_session_id) { + proposed_session_id_to_session_id(potential_session_id); + } +} + +static bool php_can_change_session_setting(const char *setting_name, bool check_cookies) +{ + if (PS(session_status) == php_session_active) { + char error_msg[256]; + snprintf(error_msg, sizeof(error_msg), "Session %s cannot be changed when a session is active", setting_name); + php_session_session_already_started_error(E_WARNING, error_msg); + + return false; + } + + if (SG(headers_sent) && (!check_cookies || PS(use_cookies))) { + char error_msg[256]; + snprintf(error_msg, sizeof(error_msg), "Session %s cannot be changed after headers have already been sent", setting_name); + php_session_headers_already_sent_error(E_WARNING, error_msg); + + return false; + } + + return true; +} + +static void try_find_session_id_in_cookies(void) +{ + zval *cookie_data; + + if (!PS(use_cookies) || PS(id)) { + return; + } + + cookie_data = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_COOKIE")); + if (!cookie_data) { + return; + } + + ZVAL_DEREF(cookie_data); + if (Z_TYPE_P(cookie_data) != IS_ARRAY) { + return; + } + + const zval *potential_session_id = zend_hash_find(Z_ARRVAL_P(cookie_data), PS(session_name)); + if (potential_session_id) { + proposed_session_id_to_session_id(potential_session_id); + PS(send_cookie) = false; + PS(define_sid) = false; + } +} + +static void proposed_session_id_to_session_id(const zval *proposed_session_id) { + ZVAL_DEREF(proposed_session_id); + if (Z_TYPE_P(proposed_session_id) == IS_STRING) { + PS(id) = zend_string_copy(Z_STR_P(proposed_session_id)); + PS(send_cookie) = false; } else { PS(id) = NULL; - PS(send_cookie) = 1; + PS(send_cookie) = true; } } - PHPAPI zend_result php_session_reset_id(void) { int module_number = PS(module_number); - zval *sid, *data, *ppid; + zval *sid, *data, *potential_session_id; bool apply_trans_sid; if (!PS(id)) { @@ -1510,26 +1609,28 @@ PHPAPI zend_result php_session_reset_id(void) if (UNEXPECTED(cookies_sent == FAILURE)) { return FAILURE; } - PS(send_cookie) = 0; + PS(send_cookie) = false; } /* If the SID constant exists, destroy it. */ /* We must not delete any items in EG(zend_constants) */ - /* zend_hash_str_del(EG(zend_constants), "sid", sizeof("sid") - 1); */ - sid = zend_get_constant_str("SID", sizeof("SID") - 1); + /* zend_hash_str_del(EG(zend_constants), ZEND_STRL("sid")); */ + sid = zend_get_constant_str(ZEND_STRL("SID")); + + zend_constant *new_sid_constant = NULL; if (PS(define_sid)) { smart_str var = {0}; - smart_str_appends(&var, PS(session_name)); + smart_str_append(&var, PS(session_name)); smart_str_appendc(&var, '='); - smart_str_appends(&var, ZSTR_VAL(PS(id))); + smart_str_append(&var, PS(id)); smart_str_0(&var); if (sid) { zval_ptr_dtor(sid); ZVAL_STR(sid, smart_str_extract(&var)); } else { - REGISTER_STRINGL_CONSTANT("SID", ZSTR_VAL(var.s), ZSTR_LEN(var.s), CONST_DEPRECATED); + new_sid_constant = REGISTER_STRINGL_CONSTANT("SID", ZSTR_VAL(var.s), ZSTR_LEN(var.s), CONST_DEPRECATED); smart_str_free(&var); } } else { @@ -1537,50 +1638,48 @@ PHPAPI zend_result php_session_reset_id(void) zval_ptr_dtor(sid); ZVAL_EMPTY_STRING(sid); } else { - REGISTER_STRINGL_CONSTANT("SID", "", 0, CONST_DEPRECATED); + new_sid_constant = REGISTER_STRINGL_CONSTANT("SID", "", 0, CONST_DEPRECATED); } } + if (new_sid_constant != NULL) { + zend_string *deprecation_reason = zend_string_init("as GET/POST sessions were deprecated", strlen("as GET/POST sessions were deprecated"), false); + zend_attribute *deprecation_attrib = zend_add_attribute(&new_sid_constant->attributes, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2, 0, 0, 0); + ZVAL_STR(&deprecation_attrib->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + deprecation_attrib->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR(&deprecation_attrib->args[1].value, deprecation_reason); + deprecation_attrib->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + } /* Apply trans sid if sid cookie is not set */ - apply_trans_sid = 0; + apply_trans_sid = false; if (APPLY_TRANS_SID) { - apply_trans_sid = 1; + apply_trans_sid = true; if (PS(use_cookies) && - (data = zend_hash_str_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE") - 1))) { + (data = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_COOKIE")))) { ZVAL_DEREF(data); if (Z_TYPE_P(data) == IS_ARRAY && - (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), strlen(PS(session_name))))) { - ZVAL_DEREF(ppid); - apply_trans_sid = 0; + (potential_session_id = zend_hash_find(Z_ARRVAL_P(data), PS(session_name)))) { + ZVAL_DEREF(potential_session_id); + apply_trans_sid = false; } } } if (apply_trans_sid) { - zend_string *sname; - sname = zend_string_init(PS(session_name), strlen(PS(session_name)), 0); - php_url_scanner_reset_session_var(sname, 1); /* This may fail when session name has changed */ - zend_string_release_ex(sname, 0); - php_url_scanner_add_session_var(PS(session_name), strlen(PS(session_name)), ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)), 1); + php_url_scanner_reset_session_var(PS(session_name), true); /* This may fail when session name has changed */ + php_url_scanner_add_session_var(ZSTR_VAL(PS(session_name)), ZSTR_LEN(PS(session_name)), ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)), true); } return SUCCESS; } - PHPAPI zend_result php_session_start(void) { - zval *ppid; - zval *data; - char *value; - size_t lensess; - switch (PS(session_status)) { case php_session_active: php_session_session_already_started_error(E_NOTICE, "Ignoring session_start() because a session has already been started"); return FAILURE; - break; - case php_session_disabled: - value = zend_ini_string("session.save_handler", sizeof("session.save_handler") - 1, 0); + case php_session_disabled: { + const char *value = zend_ini_string_literal("session.save_handler"); if (!PS(mod) && value) { PS(mod) = _php_find_ps_module(value); if (!PS(mod)) { @@ -1588,7 +1687,7 @@ PHPAPI zend_result php_session_start(void) return FAILURE; } } - value = zend_ini_string("session.serialize_handler", sizeof("session.serialize_handler") - 1, 0); + value = zend_ini_string_literal("session.serialize_handler"); if (!PS(serializer) && value) { PS(serializer) = _php_find_ps_serializer(value); if (!PS(serializer)) { @@ -1598,6 +1697,7 @@ PHPAPI zend_result php_session_start(void) } PS(session_status) = php_session_none; ZEND_FALLTHROUGH; + } case php_session_none: default: @@ -1606,49 +1706,23 @@ PHPAPI zend_result php_session_start(void) PS(send_cookie) = PS(use_cookies) || PS(use_only_cookies); } - lensess = strlen(PS(session_name)); - /* * Cookies are preferred, because initially cookie and get * variables will be available. * URL/POST session ID may be used when use_only_cookies=Off. - * session.use_strice_mode=On prevents session adoption. + * session.use_strict_mode=On prevents session adoption. * Session based file upload progress uses non-cookie ID. */ if (!PS(id)) { - if (PS(use_cookies) && (data = zend_hash_str_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE") - 1))) { - ZVAL_DEREF(data); - if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))) { - ppid2sid(ppid); - PS(send_cookie) = 0; - PS(define_sid) = 0; - } - } - /* Initialize session ID from non cookie values */ + try_find_session_id_in_cookies(); + if (!PS(use_only_cookies)) { - if (!PS(id) && (data = zend_hash_str_find(&EG(symbol_table), "_GET", sizeof("_GET") - 1))) { - ZVAL_DEREF(data); - if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))) { - ppid2sid(ppid); - } - } - if (!PS(id) && (data = zend_hash_str_find(&EG(symbol_table), "_POST", sizeof("_POST") - 1))) { - ZVAL_DEREF(data); - if (Z_TYPE_P(data) == IS_ARRAY && (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))) { - ppid2sid(ppid); - } - } - /* Check whether the current request was referred to by - * an external site which invalidates the previously found id. */ - if (PS(id) && PS(extern_referer_chk)[0] != '\0' && - !Z_ISUNDEF(PG(http_globals)[TRACK_VARS_SERVER]) && - (data = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", sizeof("HTTP_REFERER") - 1)) && - Z_TYPE_P(data) == IS_STRING && - Z_STRLEN_P(data) != 0 && - strstr(Z_STRVAL_P(data), PS(extern_referer_chk)) == NULL - ) { - zend_string_release_ex(PS(id), 0); + try_find_session_id_in_global(ZEND_STRL("_GET")); + try_find_session_id_in_global(ZEND_STRL("_POST")); + + if (should_invalidate_session_for_external_referer()) { + zend_string_release_ex(PS(id), false); PS(id) = NULL; } } @@ -1657,7 +1731,7 @@ PHPAPI zend_result php_session_start(void) /* Finally check session id for dangerous characters * Security note: session id may be embedded in HTML pages.*/ if (PS(id) && strpbrk(ZSTR_VAL(PS(id)), "\r\n\t <>'\"\\")) { - zend_string_release_ex(PS(id), 0); + zend_string_release_ex(PS(id), false); PS(id) = NULL; } @@ -1665,7 +1739,7 @@ PHPAPI zend_result php_session_start(void) || php_session_cache_limiter() == -2) { PS(session_status) = php_session_none; if (PS(id)) { - zend_string_release_ex(PS(id), 0); + zend_string_release_ex(PS(id), false); PS(id) = NULL; } return FAILURE; @@ -1674,14 +1748,14 @@ PHPAPI zend_result php_session_start(void) return SUCCESS; } -PHPAPI zend_result php_session_flush(int write) +PHPAPI bool php_session_flush(bool write) { if (PS(session_status) == php_session_active) { php_session_save_current_state(write); PS(session_status) = php_session_none; - return SUCCESS; + return true; } - return FAILURE; + return false; } PHPAPI php_session_status php_get_session_status(void) @@ -1689,38 +1763,24 @@ PHPAPI php_session_status php_get_session_status(void) return PS(session_status); } -static zend_result php_session_abort(void) +static bool php_session_abort(void) { if (PS(session_status) == php_session_active) { if (PS(mod_data) || PS(mod_user_implemented)) { PS(mod)->s_close(&PS(mod_data)); } PS(session_status) = php_session_none; - return SUCCESS; + return true; } - return FAILURE; + return false; } -static zend_result php_session_reset(void) +static bool php_session_reset(void) { - if (PS(session_status) == php_session_active - && php_session_initialize() == SUCCESS) { - return SUCCESS; - } - return FAILURE; + return PS(session_status) == php_session_active && php_session_initialize() == SUCCESS; } -/* This API is not used by any PHP modules including session currently. - session_adapt_url() may be used to set Session ID to target url without - starting "URL-Rewriter" output handler. */ -PHPAPI void session_adapt_url(const char *url, size_t url_len, char **new_url, size_t *new_len) -{ - if (APPLY_TRANS_SID && (PS(session_status) == php_session_active)) { - *new_url = php_url_scanner_adapt_single_url(url, url_len, PS(session_name), ZSTR_VAL(PS(id)), new_len, 1); - } -} - /* ******************************** * Userspace exported functions * ******************************** */ @@ -1730,8 +1790,9 @@ PHP_FUNCTION(session_set_cookie_params) HashTable *options_ht; zend_long lifetime_long; zend_string *lifetime = NULL, *path = NULL, *domain = NULL, *samesite = NULL; - bool secure = 0, secure_null = 1; - bool httponly = 0, httponly_null = 1; + bool secure = false, secure_null = true; + bool httponly = false, httponly_null = true; + bool partitioned = false, partitioned_null = true; zend_string *ini_name; zend_result result; int found = 0; @@ -1761,9 +1822,6 @@ PHP_FUNCTION(session_set_cookie_params) } if (options_ht) { - zend_string *key; - zval *value; - if (path) { zend_argument_value_error(2, "must be null when argument #1 ($lifetime_or_options) is an array"); RETURN_THROWS(); @@ -1783,7 +1841,7 @@ PHP_FUNCTION(session_set_cookie_params) zend_argument_value_error(5, "must be null when argument #1 ($lifetime_or_options) is an array"); RETURN_THROWS(); } - ZEND_HASH_FOREACH_STR_KEY_VAL(options_ht, key, value) { + ZEND_HASH_FOREACH_STR_KEY_VAL(options_ht, zend_string *key, zval *value) { if (key) { ZVAL_DEREF(value); if (zend_string_equals_literal_ci(key, "lifetime")) { @@ -1796,12 +1854,16 @@ PHP_FUNCTION(session_set_cookie_params) domain = zval_get_string(value); found++; } else if (zend_string_equals_literal_ci(key, "secure")) { - secure = zval_is_true(value); - secure_null = 0; + secure = zend_is_true(value); + secure_null = false; + found++; + } else if (zend_string_equals_literal_ci(key, "partitioned")) { + partitioned = zend_is_true(value); + partitioned_null = false; found++; } else if (zend_string_equals_literal_ci(key, "httponly")) { - httponly = zval_is_true(value); - httponly_null = 0; + httponly = zend_is_true(value); + httponly_null = false; found++; } else if (zend_string_equals_literal_ci(key, "samesite")) { samesite = zval_get_string(value); @@ -1828,54 +1890,63 @@ PHP_FUNCTION(session_set_cookie_params) } if (lifetime) { - ini_name = ZSTR_INIT_LITERAL("session.cookie_lifetime", 0); + ini_name = ZSTR_INIT_LITERAL("session.cookie_lifetime", false); result = zend_alter_ini_entry(ini_name, lifetime, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; goto cleanup; } } if (path) { - ini_name = ZSTR_INIT_LITERAL("session.cookie_path", 0); + ini_name = ZSTR_INIT_LITERAL("session.cookie_path", false); result = zend_alter_ini_entry(ini_name, path, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; goto cleanup; } } if (domain) { - ini_name = ZSTR_INIT_LITERAL("session.cookie_domain", 0); + ini_name = ZSTR_INIT_LITERAL("session.cookie_domain", false); result = zend_alter_ini_entry(ini_name, domain, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; goto cleanup; } } if (!secure_null) { - ini_name = ZSTR_INIT_LITERAL("session.cookie_secure", 0); - result = zend_alter_ini_entry_chars(ini_name, secure ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + ini_name = ZSTR_INIT_LITERAL("session.cookie_secure", false); + result = zend_alter_ini_entry(ini_name, secure ? ZSTR_CHAR('1') : ZSTR_CHAR('0'), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_string_release_ex(ini_name, false); + if (result == FAILURE) { + RETVAL_FALSE; + goto cleanup; + } + } + if (!partitioned_null) { + ini_name = ZSTR_INIT_LITERAL("session.cookie_partitioned", false); + result = zend_alter_ini_entry(ini_name, partitioned ? ZSTR_CHAR('1') : ZSTR_CHAR('0'), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; goto cleanup; } } if (!httponly_null) { - ini_name = ZSTR_INIT_LITERAL("session.cookie_httponly", 0); - result = zend_alter_ini_entry_chars(ini_name, httponly ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + ini_name = ZSTR_INIT_LITERAL("session.cookie_httponly", false); + result = zend_alter_ini_entry(ini_name, httponly ? ZSTR_CHAR('1') : ZSTR_CHAR('0'), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; goto cleanup; } } if (samesite) { - ini_name = ZSTR_INIT_LITERAL("session.cookie_samesite", 0); + ini_name = ZSTR_INIT_LITERAL("session.cookie_samesite", false); result = zend_alter_ini_entry(ini_name, samesite, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); if (result == FAILURE) { RETVAL_FALSE; goto cleanup; @@ -1895,46 +1966,38 @@ PHP_FUNCTION(session_set_cookie_params) PHP_FUNCTION(session_get_cookie_params) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); add_assoc_long(return_value, "lifetime", PS(cookie_lifetime)); - add_assoc_string(return_value, "path", PS(cookie_path)); - add_assoc_string(return_value, "domain", PS(cookie_domain)); + add_assoc_str(return_value, "path", zend_string_dup(PS(cookie_path), false)); + add_assoc_str(return_value, "domain", zend_string_dup(PS(cookie_domain), false)); add_assoc_bool(return_value, "secure", PS(cookie_secure)); + add_assoc_bool(return_value, "partitioned", PS(cookie_partitioned)); add_assoc_bool(return_value, "httponly", PS(cookie_httponly)); - add_assoc_string(return_value, "samesite", PS(cookie_samesite)); + add_assoc_str(return_value, "samesite", zend_string_dup(PS(cookie_samesite), false)); } /* Return the current session name. If new name is given, the session name is replaced with new name */ PHP_FUNCTION(session_name) { zend_string *name = NULL; - zend_string *ini_name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!", &name) == FAILURE) { RETURN_THROWS(); } - if (name && PS(session_status) == php_session_active) { - php_session_session_already_started_error(E_WARNING, "Session name cannot be changed when a session is active"); + if (name && !php_can_change_session_setting("name", false)) { RETURN_FALSE; } - if (name && SG(headers_sent)) { - php_session_headers_already_sent_error(E_WARNING, "Session name cannot be changed after headers have already been sent"); - RETURN_FALSE; - } - - RETVAL_STRING(PS(session_name)); + RETVAL_STRINGL(ZSTR_VAL(PS(session_name)), ZSTR_LEN(PS(session_name))); if (name) { - ini_name = ZSTR_INIT_LITERAL("session.name", 0); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.name", false); zend_alter_ini_entry(ini_name, name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); } } @@ -1942,19 +2005,12 @@ PHP_FUNCTION(session_name) PHP_FUNCTION(session_module_name) { zend_string *name = NULL; - zend_string *ini_name; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &name) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!", &name) == FAILURE) { RETURN_THROWS(); } - if (name && PS(session_status) == php_session_active) { - php_session_session_already_started_error(E_WARNING, "Session save handler module cannot be changed when a session is active"); - RETURN_FALSE; - } - - if (name && SG(headers_sent)) { - php_session_headers_already_sent_error(E_WARNING, "Session save handler module cannot be changed after headers have already been sent"); + if (name && !php_can_change_session_setting("save handler module", false)) { RETURN_FALSE; } @@ -1967,7 +2023,7 @@ PHP_FUNCTION(session_module_name) if (name) { if (zend_string_equals_ci(name, ZSTR_KNOWN(ZEND_STR_USER))) { - zend_argument_value_error(1, "cannot be \"user\""); + zend_argument_value_error(1, "must not be \"user\""); RETURN_THROWS(); } if (!_php_find_ps_module(ZSTR_VAL(name))) { @@ -1981,9 +2037,9 @@ PHP_FUNCTION(session_module_name) } PS(mod_data) = NULL; - ini_name = ZSTR_INIT_LITERAL("session.save_handler", 0); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.save_handler", false); zend_alter_ini_entry(ini_name, name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); } } @@ -2002,15 +2058,13 @@ static bool can_session_handler_be_changed(void) { } static inline void set_user_save_handler_ini(void) { - zend_string *ini_name, *ini_val; + /* const */ zend_string *ini_val = ZSTR_KNOWN(ZEND_STR_USER); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.save_handler", false); - ini_name = ZSTR_INIT_LITERAL("session.save_handler", 0); - ini_val = ZSTR_KNOWN(ZEND_STR_USER); - PS(set_handler) = 1; + PS(set_handler) = true; zend_alter_ini_entry(ini_name, ini_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - PS(set_handler) = 0; - zend_string_release_ex(ini_val, 0); - zend_string_release_ex(ini_name, 0); + PS(set_handler) = false; + zend_string_release_ex(ini_name, false); } #define SESSION_RELEASE_USER_HANDLER_OO(struct_name) \ @@ -2050,7 +2104,7 @@ PHP_FUNCTION(session_set_save_handler) /* OOP Version */ if (ZEND_NUM_ARGS() <= 2) { zval *obj = NULL; - bool register_shutdown = 1; + bool register_shutdown = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b", &obj, php_session_iface_entry, ®ister_shutdown) == FAILURE) { RETURN_THROWS(); @@ -2060,11 +2114,6 @@ PHP_FUNCTION(session_set_save_handler) RETURN_FALSE; } - if (PS(mod_user_class_name)) { - zend_string_release(PS(mod_user_class_name)); - } - PS(mod_user_class_name) = zend_string_copy(Z_OBJCE_P(obj)->name); - /* Define mandatory handlers */ SESSION_SET_USER_HANDLER_OO_MANDATORY(ps_open, "open"); SESSION_SET_USER_HANDLER_OO_MANDATORY(ps_close, "close"); @@ -2099,7 +2148,8 @@ PHP_FUNCTION(session_set_save_handler) /* Validate ID handler */ SESSION_SET_USER_HANDLER_OO(ps_validate_sid, zend_string_copy(validate_sid_name)); /* Update Timestamp handler */ - SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, zend_string_copy(update_timestamp_name)); + /* We need to provide a new string with the correct casing so that error messages work */ + SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, ZSTR_INIT_LITERAL("updateTimestamp", false)); } else { /* For BC reasons we accept methods even if the class does not implement the interface */ if (zend_hash_find_ptr(object_methods, validate_sid_name)) { @@ -2108,12 +2158,14 @@ PHP_FUNCTION(session_set_save_handler) } if (zend_hash_find_ptr(object_methods, update_timestamp_name)) { /* For BC reasons we accept methods even if the class does not implement the interface */ - SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, zend_string_copy(update_timestamp_name)); + /* We need to provide a new string with the correct casing so that error messages work */ + SESSION_SET_USER_HANDLER_OO(ps_update_timestamp, ZSTR_INIT_LITERAL("updateTimestamp", false)); } } zend_string_release_ex(validate_sid_name, false); zend_string_release_ex(update_timestamp_name, false); + PS(mod_user_uses_object_methods_as_handlers) = true; if (register_shutdown) { /* create shutdown function */ php_shutdown_function_entry shutdown_function_entry = { @@ -2185,12 +2237,6 @@ PHP_FUNCTION(session_set_save_handler) RETURN_FALSE; } - /* If a custom session handler is already set, release relevant info */ - if (PS(mod_user_class_name)) { - zend_string_release(PS(mod_user_class_name)); - PS(mod_user_class_name) = NULL; - } - /* remove shutdown function */ remove_user_shutdown_function("session_shutdown", strlen("session_shutdown")); @@ -2211,6 +2257,7 @@ PHP_FUNCTION(session_set_save_handler) SESSION_SET_USER_HANDLER_PROCEDURAL_OPTIONAL(ps_validate_sid, validate_id_fci); SESSION_SET_USER_HANDLER_PROCEDURAL_OPTIONAL(ps_update_timestamp, update_timestamp_fci); + PS(mod_user_uses_object_methods_as_handlers) = false; RETURN_TRUE; } @@ -2218,28 +2265,21 @@ PHP_FUNCTION(session_set_save_handler) PHP_FUNCTION(session_save_path) { zend_string *name = NULL; - zend_string *ini_name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|P!", &name) == FAILURE) { RETURN_THROWS(); } - if (name && PS(session_status) == php_session_active) { - php_session_session_already_started_error(E_WARNING, "Session save path cannot be changed when a session is active"); - RETURN_FALSE; - } - - if (name && SG(headers_sent)) { - php_session_headers_already_sent_error(E_WARNING, "Session save path cannot be changed after headers have already been sent"); + if (name && !php_can_change_session_setting("save path", false)) { RETURN_FALSE; } - RETVAL_STRING(PS(save_path)); + RETVAL_STRINGL(ZSTR_VAL(PS(save_path)), ZSTR_LEN(PS(save_path))); if (name) { - ini_name = ZSTR_INIT_LITERAL("session.save_path", 0); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.save_path", false); zend_alter_ini_entry(ini_name, name, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); } } @@ -2252,13 +2292,7 @@ PHP_FUNCTION(session_id) RETURN_THROWS(); } - if (name && PS(session_status) == php_session_active) { - php_session_session_already_started_error(E_WARNING, "Session ID cannot be changed when a session is active"); - RETURN_FALSE; - } - - if (name && PS(use_cookies) && SG(headers_sent)) { - php_session_headers_already_sent_error(E_WARNING, "Session ID cannot be changed after headers have already been sent"); + if (name && !php_can_change_session_setting("ID", true)) { RETURN_FALSE; } @@ -2267,7 +2301,7 @@ PHP_FUNCTION(session_id) * see: ext/session/tests/session_id_error3.phpt */ size_t len = strlen(ZSTR_VAL(PS(id))); if (UNEXPECTED(len != ZSTR_LEN(PS(id)))) { - RETVAL_NEW_STR(zend_string_init(ZSTR_VAL(PS(id)), len, 0)); + RETVAL_NEW_STR(zend_string_init(ZSTR_VAL(PS(id)), len, false)); } else { RETVAL_STR_COPY(PS(id)); } @@ -2277,7 +2311,7 @@ PHP_FUNCTION(session_id) if (name) { if (PS(id)) { - zend_string_release_ex(PS(id), 0); + zend_string_release_ex(PS(id), false); } PS(id) = zend_string_copy(name); } @@ -2286,8 +2320,7 @@ PHP_FUNCTION(session_id) /* Update the current session id with a newly generated one. If delete_old_session is set to true, remove the old session. */ PHP_FUNCTION(session_regenerate_id) { - bool del_ses = 0; - zend_string *data; + bool del_ses = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &del_ses) == FAILURE) { RETURN_THROWS(); @@ -2309,23 +2342,26 @@ PHP_FUNCTION(session_regenerate_id) PS(mod)->s_close(&PS(mod_data)); PS(session_status) = php_session_none; if (!EG(exception)) { - php_error_docref(NULL, E_WARNING, "Session object destruction failed. ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + php_error_docref(NULL, E_WARNING, "Session object destruction failed. ID: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } RETURN_FALSE; } } else { - zend_result ret; - data = php_session_encode(); - if (data) { - ret = PS(mod)->s_write(&PS(mod_data), PS(id), data, PS(gc_maxlifetime)); - zend_string_release_ex(data, 0); - } else { - ret = PS(mod)->s_write(&PS(mod_data), PS(id), ZSTR_EMPTY_ALLOC(), PS(gc_maxlifetime)); + zend_string *old_session_data = php_session_encode(); + /* If we have no data we must destroy the related session ID */ + if (UNEXPECTED(old_session_data == NULL)) { + PS(mod)->s_close(&PS(mod_data)); + PS(session_status) = php_session_none; + RETURN_FALSE; } + + zend_result ret = PS(mod)->s_write(&PS(mod_data), PS(id), old_session_data, PS(gc_maxlifetime)); + zend_string_release_ex(old_session_data, false); + if (ret == FAILURE) { PS(mod)->s_close(&PS(mod_data)); PS(session_status) = php_session_none; - php_error_docref(NULL, E_WARNING, "Session write failed. ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + php_error_docref(NULL, E_WARNING, "Session write failed. ID: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); RETURN_FALSE; } } @@ -2333,16 +2369,16 @@ PHP_FUNCTION(session_regenerate_id) /* New session data */ if (PS(session_vars)) { - zend_string_release_ex(PS(session_vars), 0); + zend_string_release_ex(PS(session_vars), false); PS(session_vars) = NULL; } - zend_string_release_ex(PS(id), 0); + zend_string_release_ex(PS(id), false); PS(id) = NULL; if (PS(mod)->s_open(&PS(mod_data), PS(save_path), PS(session_name)) == FAILURE) { PS(session_status) = php_session_none; if (!EG(exception)) { - zend_throw_error(NULL, "Failed to open session: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + zend_throw_error(NULL, "Failed to open session: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } RETURN_THROWS(); } @@ -2351,7 +2387,7 @@ PHP_FUNCTION(session_regenerate_id) if (!PS(id)) { PS(session_status) = php_session_none; if (!EG(exception)) { - zend_throw_error(NULL, "Failed to create new session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + zend_throw_error(NULL, "Failed to create new session ID: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } RETURN_THROWS(); } @@ -2360,13 +2396,13 @@ PHP_FUNCTION(session_regenerate_id) int limit = 3; /* Try to generate non-existing ID */ while (limit-- && PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == SUCCESS) { - zend_string_release_ex(PS(id), 0); + zend_string_release_ex(PS(id), false); PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { PS(mod)->s_close(&PS(mod_data)); PS(session_status) = php_session_none; if (!EG(exception)) { - zend_throw_error(NULL, "Failed to create session ID by collision: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + zend_throw_error(NULL, "Failed to create session ID by collision: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } RETURN_THROWS(); } @@ -2375,26 +2411,24 @@ PHP_FUNCTION(session_regenerate_id) // TODO warn that ID cannot be verified? else { } } /* Read is required to make new session data at this point. */ + zend_string *data = NULL; if (PS(mod)->s_read(&PS(mod_data), PS(id), &data, PS(gc_maxlifetime)) == FAILURE) { PS(mod)->s_close(&PS(mod_data)); PS(session_status) = php_session_none; if (!EG(exception)) { - zend_throw_error(NULL, "Failed to create(read) session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + zend_throw_error(NULL, "Failed to create(read) session ID: %s (path: %s)", PS(mod)->s_name, ZSTR_VAL(PS(save_path))); } RETURN_THROWS(); } if (data) { - zend_string_release_ex(data, 0); + zend_string_release_ex(data, false); } if (PS(use_cookies)) { - PS(send_cookie) = 1; - } - if (php_session_reset_id() == FAILURE) { - RETURN_FALSE; + PS(send_cookie) = true; } - RETURN_TRUE; + RETURN_BOOL(php_session_reset_id() == SUCCESS); } /* Generate new session ID. Intended for user save handlers. */ @@ -2408,10 +2442,10 @@ PHP_FUNCTION(session_create_id) } if (prefix && ZSTR_LEN(prefix)) { - if (ZSTR_LEN(prefix) > PS_MAX_SID_LENGTH) { - zend_argument_value_error(1, "cannot be longer than %d characters", PS_MAX_SID_LENGTH); - RETURN_THROWS(); - } + if (ZSTR_LEN(prefix) > PS_MAX_SID_LENGTH) { + zend_argument_value_error(1, "cannot be longer than %d characters", PS_MAX_SID_LENGTH); + RETURN_THROWS(); + } if (php_session_valid_key(ZSTR_VAL(prefix)) == FAILURE) { /* E_ERROR raised for security reason. */ php_error_docref(NULL, E_WARNING, "Prefix cannot contain special characters. Only the A-Z, a-z, 0-9, \"-\", and \",\" characters are allowed"); @@ -2430,7 +2464,7 @@ PHP_FUNCTION(session_create_id) } else { /* Detect collision and retry */ if (PS(mod)->s_validate_sid(&PS(mod_data), new_id) == SUCCESS) { - zend_string_release_ex(new_id, 0); + zend_string_release_ex(new_id, false); new_id = NULL; continue; } @@ -2443,7 +2477,7 @@ PHP_FUNCTION(session_create_id) if (new_id) { smart_str_append(&id, new_id); - zend_string_release_ex(new_id, 0); + zend_string_release_ex(new_id, false); } else { smart_str_free(&id); php_error_docref(NULL, E_WARNING, "Failed to create new ID"); @@ -2456,7 +2490,6 @@ PHP_FUNCTION(session_create_id) PHP_FUNCTION(session_cache_limiter) { zend_string *limiter = NULL; - zend_string *ini_name; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &limiter) == FAILURE) { RETURN_THROWS(); @@ -2472,12 +2505,12 @@ PHP_FUNCTION(session_cache_limiter) RETURN_FALSE; } - RETVAL_STRING(PS(cache_limiter)); + RETVAL_STRINGL(ZSTR_VAL(PS(cache_limiter)), ZSTR_LEN(PS(cache_limiter))); if (limiter) { - ini_name = ZSTR_INIT_LITERAL("session.cache_limiter", 0); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.cache_limiter", false); zend_alter_ini_entry(ini_name, limiter, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); + zend_string_release_ex(ini_name, false); } } @@ -2485,7 +2518,7 @@ PHP_FUNCTION(session_cache_limiter) PHP_FUNCTION(session_cache_expire) { zend_long expires; - bool expires_is_null = 1; + bool expires_is_null = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &expires, &expires_is_null) == FAILURE) { RETURN_THROWS(); @@ -2504,11 +2537,11 @@ PHP_FUNCTION(session_cache_expire) RETVAL_LONG(PS(cache_expire)); if (!expires_is_null) { - zend_string *ini_name = ZSTR_INIT_LITERAL("session.cache_expire", 0); + zend_string *ini_name = ZSTR_INIT_LITERAL("session.cache_expire", false); zend_string *ini_value = zend_long_to_str(expires); zend_alter_ini_entry(ini_name, ini_value, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - zend_string_release_ex(ini_name, 0); - zend_string_release_ex(ini_value, 0); + zend_string_release_ex(ini_name, false); + zend_string_release_ex(ini_value, false); } } @@ -2517,9 +2550,7 @@ PHP_FUNCTION(session_encode) { zend_string *enc; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); enc = php_session_encode(); if (enc == NULL) { @@ -2543,20 +2574,17 @@ PHP_FUNCTION(session_decode) RETURN_FALSE; } - if (php_session_decode(str) == FAILURE) { - RETURN_FALSE; - } - RETURN_TRUE; + RETURN_BOOL(php_session_decode(str) == SUCCESS); } -static zend_result php_session_start_set_ini(zend_string *varname, zend_string *new_value) { +static zend_result php_session_start_set_ini(const zend_string *varname, zend_string *new_value) { zend_result ret; smart_str buf ={0}; smart_str_appends(&buf, "session"); smart_str_appendc(&buf, '.'); smart_str_append(&buf, varname); smart_str_0(&buf); - ret = zend_alter_ini_entry_ex(buf.s, new_value, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0); + ret = zend_alter_ini_entry_ex(buf.s, new_value, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, false); smart_str_free(&buf); return ret; } @@ -2564,8 +2592,6 @@ static zend_result php_session_start_set_ini(zend_string *varname, zend_string * PHP_FUNCTION(session_start) { zval *options = NULL; - zval *value; - zend_string *str_idx; bool read_and_close = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a", &options) == FAILURE) { @@ -2589,12 +2615,12 @@ PHP_FUNCTION(session_start) /* set options */ if (options) { - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), str_idx, value) { + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), zend_string *str_idx, zval *value) { if (UNEXPECTED(!str_idx)) { zend_argument_value_error(1, "must be of type array with keys as string"); RETURN_THROWS(); } - switch(Z_TYPE_P(value)) { + switch (Z_TYPE_P(value)) { case IS_STRING: case IS_TRUE: case IS_FALSE: @@ -2604,7 +2630,7 @@ PHP_FUNCTION(session_start) if (Z_TYPE_P(value) != IS_STRING) { tmp = zval_get_long(value); } else { - if (is_numeric_string(Z_STRVAL_P(value), Z_STRLEN_P(value), &tmp, NULL, false) != IS_LONG) { + if (is_numeric_str_function(Z_STR_P(value), &tmp, NULL) != IS_LONG) { zend_type_error("%s(): Option \"%s\" value must be of type compatible with int, \"%s\" given", get_active_function_name(), ZSTR_VAL(str_idx), Z_STRVAL_P(value) ); @@ -2643,7 +2669,7 @@ PHP_FUNCTION(session_start) } if (read_and_close) { - php_session_flush(0); + php_session_flush(false); } RETURN_TRUE; @@ -2651,18 +2677,14 @@ PHP_FUNCTION(session_start) PHP_FUNCTION(session_destroy) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(php_session_destroy() == SUCCESS); } PHP_FUNCTION(session_unset) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (PS(session_status) != php_session_active) { RETURN_FALSE; @@ -2682,16 +2704,14 @@ PHP_FUNCTION(session_gc) { zend_long num; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (PS(session_status) != php_session_active) { php_error_docref(NULL, E_WARNING, "Session cannot be garbage collected when there is no active session"); RETURN_FALSE; } - num = php_session_gc(1); + num = php_session_gc(true); if (num < 0) { RETURN_FALSE; } @@ -2699,53 +2719,32 @@ PHP_FUNCTION(session_gc) RETURN_LONG(num); } - PHP_FUNCTION(session_write_close) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); - if (PS(session_status) != php_session_active) { - RETURN_FALSE; - } - php_session_flush(1); - RETURN_TRUE; + RETURN_BOOL(php_session_flush(true)); } /* Abort session and end session. Session data will not be written */ PHP_FUNCTION(session_abort) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); - if (PS(session_status) != php_session_active) { - RETURN_FALSE; - } - php_session_abort(); - RETURN_TRUE; + RETURN_BOOL(php_session_abort()); } /* Reset session data from saved session data */ PHP_FUNCTION(session_reset) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); - if (PS(session_status) != php_session_active) { - RETURN_FALSE; - } - php_session_reset(); - RETURN_TRUE; + RETURN_BOOL(php_session_reset()); } PHP_FUNCTION(session_status) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(PS(session_status)); } @@ -2778,11 +2777,12 @@ PHP_FUNCTION(session_register_shutdown) * If the user does have a later shutdown function which needs the * session then tough luck. */ - php_session_flush(1); + php_session_flush(true); php_error_docref(NULL, E_WARNING, "Session shutdown function cannot be registered"); } } + /* ******************************** * Module Setup and Destruction * ******************************** */ @@ -2793,18 +2793,14 @@ static zend_result php_rinit_session(bool auto_start) PS(mod) = NULL; { - char *value; - - value = zend_ini_string("session.save_handler", sizeof("session.save_handler") - 1, 0); + const char *value = zend_ini_string_literal("session.save_handler"); if (value) { PS(mod) = _php_find_ps_module(value); } } if (PS(serializer) == NULL) { - char *value; - - value = zend_ini_string("session.serialize_handler", sizeof("session.serialize_handler") - 1, 0); + const char *value = zend_ini_string_literal("session.serialize_handler"); if (value) { PS(serializer) = _php_find_ps_serializer(value); } @@ -2834,12 +2830,11 @@ static PHP_RINIT_FUNCTION(session) ZVAL_UNDEF(&PS(mod_user_names).struct_name); \ } - static PHP_RSHUTDOWN_FUNCTION(session) { if (PS(session_status) == php_session_active) { zend_try { - php_session_flush(1); + php_session_flush(true); } zend_end_try(); } php_rshutdown_session_globals(); @@ -2873,11 +2868,11 @@ static PHP_GINIT_FUNCTION(ps) ps_globals->mod_data = NULL; ps_globals->session_status = php_session_none; ps_globals->default_mod = NULL; - ps_globals->mod_user_implemented = 0; - ps_globals->mod_user_class_name = NULL; - ps_globals->mod_user_is_open = 0; + ps_globals->mod_user_implemented = false; + ps_globals->mod_user_is_open = false; + ps_globals->mod_user_uses_object_methods_as_handlers = false; ps_globals->session_vars = NULL; - ps_globals->set_handler = 0; + ps_globals->set_handler = false; ps_globals->session_started_filename = NULL; ps_globals->session_started_lineno = 0; /* Unset user defined handlers */ @@ -2908,7 +2903,7 @@ static PHP_GINIT_FUNCTION(ps) static PHP_MINIT_FUNCTION(session) { - zend_register_auto_global(zend_string_init_interned("_SESSION", sizeof("_SESSION") - 1, 1), 0, NULL); + zend_register_auto_global(zend_string_init_interned(ZEND_STRL("_SESSION"), true), false, NULL); my_module_number = module_number; PS(module_number) = module_number; @@ -2959,24 +2954,24 @@ static PHP_MSHUTDOWN_FUNCTION(session) static PHP_MINFO_FUNCTION(session) { - const ps_module **mod; - ps_serializer *ser; + const ps_module **current_save_handler; + ps_serializer *current_serializer; smart_str save_handlers = {0}; smart_str ser_handlers = {0}; - int i; + int handler_index; - /* Get save handlers */ - for (i = 0, mod = ps_modules; i < MAX_MODULES; i++, mod++) { - if (*mod && (*mod)->s_name) { - smart_str_appends(&save_handlers, (*mod)->s_name); + /* Collect names of all available save handlers */ + for (handler_index = 0, current_save_handler = ps_modules; handler_index < MAX_MODULES; handler_index++, current_save_handler++) { + if (*current_save_handler && (*current_save_handler)->s_name) { + smart_str_appends(&save_handlers, (*current_save_handler)->s_name); smart_str_appendc(&save_handlers, ' '); } } - /* Get serializer handlers */ - for (i = 0, ser = ps_serializers; i < MAX_SERIALIZERS; i++, ser++) { - if (ser->name) { - smart_str_appends(&ser_handlers, ser->name); + /* Collect names of all available serializers */ + for (handler_index = 0, current_serializer = ps_serializers; handler_index < MAX_SERIALIZERS; handler_index++, current_serializer++) { + if (current_serializer->name) { + smart_str_appends(&ser_handlers, current_serializer->name); smart_str_appendc(&ser_handlers, ' '); } } @@ -3005,31 +3000,25 @@ static PHP_MINFO_FUNCTION(session) DISPLAY_INI_ENTRIES(); } -static const zend_module_dep session_deps[] = { - ZEND_MOD_OPTIONAL("spl") - ZEND_MOD_END -}; /* ************************ * Upload hook handling * ************************ */ -static bool early_find_sid_in(zval *dest, int where, php_session_rfc1867_progress *progress) +static bool early_find_sid_in(zval *dest, int where) { - zval *ppid; - if (Z_ISUNDEF(PG(http_globals)[where])) { - return 0; + return false; } - if ((ppid = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[where]), PS(session_name), progress->sname_len)) - && Z_TYPE_P(ppid) == IS_STRING) { + zval *potential_session_id = zend_hash_find(Z_ARRVAL(PG(http_globals)[where]), PS(session_name)); + if (potential_session_id && Z_TYPE_P(potential_session_id) == IS_STRING) { zval_ptr_dtor(dest); - ZVAL_COPY_DEREF(dest, ppid); - return 1; + ZVAL_COPY_DEREF(dest, potential_session_id); + return true; } - return 0; + return false; } static void php_session_rfc1867_early_find_sid(php_session_rfc1867_progress *progress) @@ -3037,8 +3026,8 @@ static void php_session_rfc1867_early_find_sid(php_session_rfc1867_progress *pro if (PS(use_cookies)) { sapi_module.treat_data(PARSE_COOKIE, NULL, NULL); - if (early_find_sid_in(&progress->sid, TRACK_VARS_COOKIE, progress)) { - progress->apply_trans_sid = 0; + if (early_find_sid_in(&progress->sid, TRACK_VARS_COOKIE)) { + progress->apply_trans_sid = false; return; } } @@ -3046,26 +3035,26 @@ static void php_session_rfc1867_early_find_sid(php_session_rfc1867_progress *pro return; } sapi_module.treat_data(PARSE_GET, NULL, NULL); - early_find_sid_in(&progress->sid, TRACK_VARS_GET, progress); + early_find_sid_in(&progress->sid, TRACK_VARS_GET); } -static bool php_check_cancel_upload(php_session_rfc1867_progress *progress) +static bool php_check_cancel_upload(const php_session_rfc1867_progress *progress) { - zval *progress_ary, *cancel_upload; - - if ((progress_ary = zend_symtable_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), progress->key.s)) == NULL) { - return 0; + const zval *progress_ary = zend_symtable_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), progress->key.s); + if (progress_ary == NULL) { + return false; } if (Z_TYPE_P(progress_ary) != IS_ARRAY) { - return 0; + return false; } - if ((cancel_upload = zend_hash_str_find(Z_ARRVAL_P(progress_ary), "cancel_upload", sizeof("cancel_upload") - 1)) == NULL) { - return 0; + const zval *cancel_upload = zend_hash_str_find(Z_ARRVAL_P(progress_ary), ZEND_STRL("cancel_upload")); + if (cancel_upload == NULL) { + return false; } return Z_TYPE_P(cancel_upload) == IS_TRUE; } -static void php_session_rfc1867_update(php_session_rfc1867_progress *progress, int force_update) +static void php_session_rfc1867_update(php_session_rfc1867_progress *progress, bool force_update) { if (!force_update) { if (Z_LVAL_P(progress->post_bytes_processed) < progress->next_update) { @@ -3096,10 +3085,10 @@ static void php_session_rfc1867_update(php_session_rfc1867_progress *progress, i Z_TRY_ADDREF(progress->data); zend_hash_update(Z_ARRVAL_P(sess_var), progress->key.s, &progress->data); } - php_session_flush(1); + php_session_flush(true); } -static void php_session_rfc1867_cleanup(php_session_rfc1867_progress *progress) +static void php_session_rfc1867_cleanup(const php_session_rfc1867_progress *progress) { php_session_initialize(); PS(session_status) = php_session_active; @@ -3108,7 +3097,7 @@ static void php_session_rfc1867_cleanup(php_session_rfc1867_progress *progress) SEPARATE_ARRAY(sess_var); zend_hash_del(Z_ARRVAL_P(sess_var), progress->key.s); } - php_session_flush(1); + php_session_flush(true); } static zend_result php_session_rfc1867_callback(unsigned int event, void *event_data, void **extra) @@ -3125,17 +3114,16 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ progress = PS(rfc1867_progress); - switch(event) { + switch (event) { case MULTIPART_EVENT_START: { - multipart_event_start *data = (multipart_event_start *) event_data; + const multipart_event_start *data = event_data; progress = ecalloc(1, sizeof(php_session_rfc1867_progress)); progress->content_length = data->content_length; - progress->sname_len = strlen(PS(session_name)); PS(rfc1867_progress) = progress; } break; case MULTIPART_EVENT_FORMDATA: { - multipart_event_formdata *data = (multipart_event_formdata *) event_data; + const multipart_event_formdata *data = event_data; size_t value_len; if (Z_TYPE(progress->sid) && progress->key.s) { @@ -3152,12 +3140,12 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ if (data->name && data->value && value_len) { size_t name_len = strlen(data->name); - if (name_len == progress->sname_len && memcmp(data->name, PS(session_name), name_len) == 0) { + if (zend_string_equals_cstr(PS(session_name), data->name, name_len)) { zval_ptr_dtor(&progress->sid); ZVAL_STRINGL(&progress->sid, (*data->value), value_len); - } else if (name_len == strlen(PS(rfc1867_name)) && memcmp(data->name, PS(rfc1867_name), name_len + 1) == 0) { + } else if (zend_string_equals_cstr(PS(rfc1867_name), data->name, name_len)) { smart_str_free(&progress->key); - smart_str_appends(&progress->key, PS(rfc1867_prefix)); + smart_str_append(&progress->key, PS(rfc1867_prefix)); smart_str_appendl(&progress->key, *data->value, value_len); smart_str_0(&progress->key); @@ -3168,7 +3156,7 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ } break; case MULTIPART_EVENT_FILE_START: { - multipart_event_file_start *data = (multipart_event_file_start *) event_data; + const multipart_event_file_start *data = event_data; /* Do nothing when $_POST["PHP_SESSION_UPLOAD_PROGRESS"] is not set * or when we have no session id */ @@ -3190,46 +3178,46 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ array_init(&progress->data); array_init(&progress->files); - add_assoc_long_ex(&progress->data, "start_time", sizeof("start_time") - 1, (zend_long)sapi_get_request_time()); - add_assoc_long_ex(&progress->data, "content_length", sizeof("content_length") - 1, progress->content_length); - add_assoc_long_ex(&progress->data, "bytes_processed", sizeof("bytes_processed") - 1, data->post_bytes_processed); - add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 0); - add_assoc_zval_ex(&progress->data, "files", sizeof("files") - 1, &progress->files); + add_assoc_long_ex(&progress->data, ZEND_STRL("start_time"), (zend_long)sapi_get_request_time()); + add_assoc_long_ex(&progress->data, ZEND_STRL("content_length"), progress->content_length); + add_assoc_long_ex(&progress->data, ZEND_STRL("bytes_processed"), data->post_bytes_processed); + add_assoc_bool_ex(&progress->data, ZEND_STRL("done"), false); + add_assoc_zval_ex(&progress->data, ZEND_STRL("files"), &progress->files); - progress->post_bytes_processed = zend_hash_str_find(Z_ARRVAL(progress->data), "bytes_processed", sizeof("bytes_processed") - 1); + progress->post_bytes_processed = zend_hash_str_find(Z_ARRVAL(progress->data), ZEND_STRL("bytes_processed")); - php_rinit_session(0); - PS(id) = zend_string_init(Z_STRVAL(progress->sid), Z_STRLEN(progress->sid), 0); + php_rinit_session(false); + PS(id) = zend_string_copy(Z_STR(progress->sid)); if (progress->apply_trans_sid) { /* Enable trans sid by modifying flags */ - PS(use_trans_sid) = 1; - PS(use_only_cookies) = 0; + PS(use_trans_sid) = true; + PS(use_only_cookies) = false; } - PS(send_cookie) = 0; + PS(send_cookie) = false; } array_init(&progress->current_file); /* Each uploaded file has its own array. Trying to make it close to $_FILES entries. */ - add_assoc_string_ex(&progress->current_file, "field_name", sizeof("field_name") - 1, data->name); - add_assoc_string_ex(&progress->current_file, "name", sizeof("name") - 1, *data->filename); - add_assoc_null_ex(&progress->current_file, "tmp_name", sizeof("tmp_name") - 1); - add_assoc_long_ex(&progress->current_file, "error", sizeof("error") - 1, 0); + add_assoc_string_ex(&progress->current_file, ZEND_STRL("field_name"), data->name); + add_assoc_string_ex(&progress->current_file, ZEND_STRL("name"), *data->filename); + add_assoc_null_ex(&progress->current_file, ZEND_STRL("tmp_name")); + add_assoc_long_ex(&progress->current_file, ZEND_STRL("error"), 0); - add_assoc_bool_ex(&progress->current_file, "done", sizeof("done") - 1, 0); - add_assoc_long_ex(&progress->current_file, "start_time", sizeof("start_time") - 1, (zend_long)time(NULL)); - add_assoc_long_ex(&progress->current_file, "bytes_processed", sizeof("bytes_processed") - 1, 0); + add_assoc_bool_ex(&progress->current_file, ZEND_STRL("done"), false); + add_assoc_long_ex(&progress->current_file, ZEND_STRL("start_time"), (zend_long)time(NULL)); + add_assoc_long_ex(&progress->current_file, ZEND_STRL("bytes_processed"), 0); add_next_index_zval(&progress->files, &progress->current_file); - progress->current_file_bytes_processed = zend_hash_str_find(Z_ARRVAL(progress->current_file), "bytes_processed", sizeof("bytes_processed") - 1); + progress->current_file_bytes_processed = zend_hash_str_find(Z_ARRVAL(progress->current_file), ZEND_STRL("bytes_processed")); Z_LVAL_P(progress->current_file_bytes_processed) = data->post_bytes_processed; - php_session_rfc1867_update(progress, 0); + php_session_rfc1867_update(progress, false); } break; case MULTIPART_EVENT_FILE_DATA: { - multipart_event_file_data *data = (multipart_event_file_data *) event_data; + const multipart_event_file_data *data = event_data; if (!Z_TYPE(progress->sid) || !progress->key.s) { break; @@ -3238,30 +3226,30 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ Z_LVAL_P(progress->current_file_bytes_processed) = data->offset + data->length; Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; - php_session_rfc1867_update(progress, 0); + php_session_rfc1867_update(progress, false); } break; case MULTIPART_EVENT_FILE_END: { - multipart_event_file_end *data = (multipart_event_file_end *) event_data; + const multipart_event_file_end *data = event_data; if (!Z_TYPE(progress->sid) || !progress->key.s) { break; } if (data->temp_filename) { - add_assoc_string_ex(&progress->current_file, "tmp_name", sizeof("tmp_name") - 1, data->temp_filename); + add_assoc_string_ex(&progress->current_file, ZEND_STRL("tmp_name"), data->temp_filename); } - add_assoc_long_ex(&progress->current_file, "error", sizeof("error") - 1, data->cancel_upload); - add_assoc_bool_ex(&progress->current_file, "done", sizeof("done") - 1, 1); + add_assoc_long_ex(&progress->current_file, ZEND_STRL("error"), data->cancel_upload); + add_assoc_bool_ex(&progress->current_file, ZEND_STRL("done"), true); Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; - php_session_rfc1867_update(progress, 0); + php_session_rfc1867_update(progress, false); } break; case MULTIPART_EVENT_END: { - multipart_event_end *data = (multipart_event_end *) event_data; + const multipart_event_end *data = event_data; if (Z_TYPE(progress->sid) && progress->key.s) { if (PS(rfc1867_cleanup)) { @@ -3269,9 +3257,9 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ } else { if (!Z_ISUNDEF(progress->data)) { SEPARATE_ARRAY(&progress->data); - add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1); + add_assoc_bool_ex(&progress->data, ZEND_STRL("done"), true); Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; - php_session_rfc1867_update(progress, 1); + php_session_rfc1867_update(progress, true); } } php_rshutdown_session_globals(); @@ -3296,9 +3284,7 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_ } zend_module_entry session_module_entry = { - STANDARD_MODULE_HEADER_EX, - NULL, - session_deps, + STANDARD_MODULE_HEADER, "session", ext_functions, PHP_MINIT(session), PHP_MSHUTDOWN(session), diff --git a/ext/session/session_arginfo.h b/ext/session/session_arginfo.h index 3e0c889ae3c5..3860731a535a 100644 --- a/ext/session/session_arginfo.h +++ b/ext/session/session_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit session.stub.php instead. * Stub hash: 6bbbdc8c4a33d1ff9984b3d81e4f5c9b76efcb14 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_session_name, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) diff --git a/ext/session/tests/015.phpt b/ext/session/tests/015.phpt index 3154022fae86..1a9285c33933 100644 --- a/ext/session/tests/015.phpt +++ b/ext/session/tests/015.phpt @@ -31,5 +31,5 @@ Deprecated: PHP Startup: Disabling session.use_only_cookies INI setting is depre Deprecated: PHP Startup: Enabling session.use_trans_sid INI setting is deprecated in Unknown on line 0 -Deprecated: Constant SID is deprecated in %s on line 6 +Deprecated: Constant SID is deprecated since 8.4, as GET/POST sessions were deprecated in %s on line %d diff --git a/ext/session/tests/bug53141.phpt b/ext/session/tests/bug53141.phpt index 849a35876040..81ce8e3bd0a8 100644 --- a/ext/session/tests/bug53141.phpt +++ b/ext/session/tests/bug53141.phpt @@ -13,10 +13,10 @@ spl_autoload_register(function ($class) { class Foo { - function __sleep() + function __serialize() { new Bar; - return array(); + return []; } } diff --git a/ext/session/tests/bug72940.phpt b/ext/session/tests/bug72940.phpt index 9a927a5419e4..4977b05a5523 100644 --- a/ext/session/tests/bug72940.phpt +++ b/ext/session/tests/bug72940.phpt @@ -34,12 +34,12 @@ session_destroy(); --EXPECTF-- Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 6 -Deprecated: Constant SID is deprecated in %s on line 8 +Deprecated: Constant SID is deprecated since 8.4, as GET/POST sessions were deprecated in %s on line %d string(12) "bug72940test" string(0) "" Deprecated: ini_set(): Disabling session.use_only_cookies INI setting is deprecated in %s on line 13 -Deprecated: Constant SID is deprecated in %s on line 15 +Deprecated: Constant SID is deprecated since 8.4, as GET/POST sessions were deprecated in %s on line %d string(11) "bug72940get" string(21) "PHPSESSID=bug72940get" diff --git a/ext/session/tests/bug73100.phpt b/ext/session/tests/bug73100.phpt index 21e698a14aba..fc9984428726 100644 --- a/ext/session/tests/bug73100.phpt +++ b/ext/session/tests/bug73100.phpt @@ -24,5 +24,5 @@ bool(true) Warning: session_module_name(): Session save handler module cannot be changed when a session is active (started from %s on line %d) in %s on line %d bool(true) -session_module_name(): Argument #1 ($module) cannot be "user" +session_module_name(): Argument #1 ($module) must not be "user" ===DONE=== diff --git a/ext/session/tests/bug74892.phpt b/ext/session/tests/bug74892.phpt index 916120cb4d44..7a2211210b45 100644 --- a/ext/session/tests/bug74892.phpt +++ b/ext/session/tests/bug74892.phpt @@ -4,6 +4,7 @@ Bug #74892 Url Rewriting (trans_sid) not working on urls that start with # session.use_cookies=0 session.use_only_cookies=0 session.use_trans_sid=1 +session.use_strict_mode=0 --EXTENSIONS-- session --SKIPIF-- diff --git a/ext/session/tests/bug80774.phpt b/ext/session/tests/bug80774.phpt index 7dd86add02b0..ba5d39e1953a 100644 --- a/ext/session/tests/bug80774.phpt +++ b/ext/session/tests/bug80774.phpt @@ -2,6 +2,8 @@ Bug #80774 (session_name() problem with backslash) --EXTENSIONS-- session +--INI-- +session.use_strict_mode=0 --FILE-- --EXPECTHEADERS-- -Set-Cookie: foo\bar=12345; path=/ +Set-Cookie: foo\bar=12345; path=/; HttpOnly; SameSite=Lax --EXPECT-- diff --git a/ext/session/tests/deprecations.phpt b/ext/session/tests/deprecations.phpt index 4a2337fb99da..0db8ce49b7d0 100644 --- a/ext/session/tests/deprecations.phpt +++ b/ext/session/tests/deprecations.phpt @@ -60,5 +60,5 @@ Deprecated: session_start(): Disabling session.use_only_cookies INI setting is d Deprecated: session_start(): Enabling session.use_trans_sid INI setting is deprecated in %s on line 32 -Deprecated: Constant SID is deprecated in %s on line 34 +Deprecated: Constant SID is deprecated since 8.4, as GET/POST sessions were deprecated in %s on line %d PHPSESSID=%s diff --git a/ext/session/tests/gh16290.phpt b/ext/session/tests/gh16290.phpt index d341eb47471b..df57b129649d 100644 --- a/ext/session/tests/gh16290.phpt +++ b/ext/session/tests/gh16290.phpt @@ -6,8 +6,11 @@ session --FILE-- ---EXPECT-- +--EXPECTF-- +Warning: session_set_cookie_params(): session.cookie_lifetime must be between 0 and %d in %s on line %d DONE diff --git a/ext/session/tests/gh9200.phpt b/ext/session/tests/gh9200.phpt index fd6e28ab8b90..7e458176d10f 100644 --- a/ext/session/tests/gh9200.phpt +++ b/ext/session/tests/gh9200.phpt @@ -2,6 +2,7 @@ GH-9200: setcookie has an obsolete expires date format --INI-- session.cookie_lifetime=3600 +session.use_strict_mode=0 --EXTENSIONS-- session --CGI-- @@ -12,7 +13,7 @@ session_id('bar'); session_start(); foreach (headers_list() as $header) { - if (preg_match('/^Set-Cookie: foo=bar; expires=(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2[0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] GMT; Max-Age=3600; path=\\/$/', $header)) { + if (preg_match('/^Set-Cookie: foo=bar; expires=(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2[0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] GMT; Max-Age=3600; path=\/; HttpOnly; SameSite=Lax$/', $header)) { echo "Success", PHP_EOL; exit; } diff --git a/ext/session/tests/mod_files/gc_dirdepth2.phpt b/ext/session/tests/mod_files/gc_dirdepth2.phpt new file mode 100644 index 000000000000..d858c1f95db8 --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth2.phpt @@ -0,0 +1,46 @@ +--TEST-- +session GC cleans expired sessions with save_path dirdepth=2 (two subdir levels) +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=10 +session.use_strict_mode=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +session_gc() return value: int(1) +expired file removed: bool(true) diff --git a/ext/session/tests/mod_files/gc_dirdepth_disabled.phpt b/ext/session/tests/mod_files/gc_dirdepth_disabled.phpt new file mode 100644 index 000000000000..dc3d4720dd23 --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth_disabled.phpt @@ -0,0 +1,69 @@ +--TEST-- +session GC correctly cleans expired sessions when save_path dirdepth > 0 +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=1 +session.use_strict_mode=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +dirdepth=1 — session_gc() return value: int(1) +dirdepth=1 — expired session file removed: bool(true) +dirdepth=0 — session_gc() return value: int(1) +dirdepth=0 — expired session file removed: bool(true) diff --git a/ext/session/tests/mod_files/gc_dirdepth_multi_subdir_count.phpt b/ext/session/tests/mod_files/gc_dirdepth_multi_subdir_count.phpt new file mode 100644 index 000000000000..c5e916c86fd2 --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth_multi_subdir_count.phpt @@ -0,0 +1,55 @@ +--TEST-- +session GC accumulates correct total count across multiple subdirs, including empty ones (dirdepth=1) +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=10 +session.use_strict_mode=0 +--FILE-- + +--CLEAN-- + +--EXPECT-- +session_gc() return value: int(3) +all expired files removed: bool(true) diff --git a/ext/session/tests/mod_files/gc_dirdepth_selective.phpt b/ext/session/tests/mod_files/gc_dirdepth_selective.phpt new file mode 100644 index 000000000000..1f0785d66fed --- /dev/null +++ b/ext/session/tests/mod_files/gc_dirdepth_selective.phpt @@ -0,0 +1,58 @@ +--TEST-- +session GC deletes only expired sess_* files and leaves all other files untouched (dirdepth=1) +--EXTENSIONS-- +session +--SKIPIF-- + +--INI-- +session.gc_probability=0 +session.gc_maxlifetime=10 +session.use_strict_mode=0 +--FILE-- + gc_maxlifetime=10 → deleted + +file_put_contents($fresh, 'user|s:5:"alice";'); +touch($fresh, time() - 1); // 1 s old < gc_maxlifetime=10 → kept + +file_put_contents($other, 'untouched'); +touch($other, time() - 100); // old but no sess_ prefix → kept + +session_id('a0000000000000000000000000'); // first char 'a' → $base/a/ +session_start(); +$result = session_gc(); // int(1): exactly one deletion proves selectivity +session_destroy(); + +echo "session_gc() return value: "; +var_dump($result); + +echo "expired sess_ file removed: "; +var_dump(!file_exists($expired)); + +echo "other file kept: "; +var_dump(file_exists($other)); +?> +--CLEAN-- + +--EXPECT-- +session_gc() return value: int(1) +expired sess_ file removed: bool(true) +other file kept: bool(true) diff --git a/ext/session/tests/session_cookie_lifetime_invalid.phpt b/ext/session/tests/session_cookie_lifetime_invalid.phpt new file mode 100644 index 000000000000..8665a53447b9 --- /dev/null +++ b/ext/session/tests/session_cookie_lifetime_invalid.phpt @@ -0,0 +1,55 @@ +--TEST-- +session.cookie_lifetime rejects invalid values +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: ini_set(): session.cookie_lifetime must be of type int in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be of type int in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be between 0 and %d in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be between 0 and %d in %s on line %d +string(3) "100" + +Warning: ini_set(): session.cookie_lifetime must be between 0 and %d in %s on line %d +string(3) "100" +string(3) "200" diff --git a/ext/session/tests/session_encode_error2.phpt b/ext/session/tests/session_encode_error2.phpt index e112d6935393..42f5c4dd6888 100644 --- a/ext/session/tests/session_encode_error2.phpt +++ b/ext/session/tests/session_encode_error2.phpt @@ -51,28 +51,28 @@ ob_end_flush(); bool(true) Warning: session_encode(): Skipping numeric key 0 in %s on line %d -bool(false) +string(0) "" bool(true) -- Iteration 2 -- bool(true) Warning: session_encode(): Skipping numeric key 1 in %s on line %d -bool(false) +string(0) "" bool(true) -- Iteration 3 -- bool(true) Warning: session_encode(): Skipping numeric key 12345 in %s on line %d -bool(false) +string(0) "" bool(true) -- Iteration 4 -- bool(true) Warning: session_encode(): Skipping numeric key -2345 in %s on line %d -bool(false) +string(0) "" bool(true) -- Iteration 5 -- diff --git a/ext/session/tests/session_encode_partial_data.phpt b/ext/session/tests/session_encode_partial_data.phpt new file mode 100644 index 000000000000..9236dbcb1111 --- /dev/null +++ b/ext/session/tests/session_encode_partial_data.phpt @@ -0,0 +1,30 @@ +--TEST-- +session_encode(): partial session data +--INI-- +serialize_precision=100 +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: session_encode(): Failed to write session data. Data contains invalid key "partial|data" in %s on line %d +bool(false) +bool(true) diff --git a/ext/session/tests/session_encode_variation1.phpt b/ext/session/tests/session_encode_variation1.phpt index 1b5be5e42dcb..4a948eba69c0 100644 --- a/ext/session/tests/session_encode_variation1.phpt +++ b/ext/session/tests/session_encode_variation1.phpt @@ -30,11 +30,11 @@ ob_end_flush(); Warning: session_encode(): Cannot encode non-existent session in %s on line %d bool(false) bool(true) -bool(false) +string(0) "" bool(true) -bool(false) +string(0) "" bool(true) -bool(false) +string(0) "" bool(true) Warning: session_encode(): Cannot encode non-existent session in %s on line %d diff --git a/ext/session/tests/session_encode_variation2.phpt b/ext/session/tests/session_encode_variation2.phpt index 8803c3080696..3984ec711008 100644 --- a/ext/session/tests/session_encode_variation2.phpt +++ b/ext/session/tests/session_encode_variation2.phpt @@ -22,7 +22,7 @@ ob_end_flush(); ?> --EXPECTF-- *** Testing session_encode() : variation *** -bool(false) +string(0) "" bool(true) Warning: session_encode(): Cannot encode non-existent session in %s on line %d diff --git a/ext/session/tests/session_encode_variation6.phpt b/ext/session/tests/session_encode_variation6.phpt index 301dbd61679a..2b3ab0e78a09 100644 --- a/ext/session/tests/session_encode_variation6.phpt +++ b/ext/session/tests/session_encode_variation6.phpt @@ -32,16 +32,16 @@ ob_end_flush(); bool(true) Warning: session_encode(): Skipping numeric key 0 in %s on line %d -bool(false) +string(0) "" bool(true) bool(true) Warning: session_encode(): Skipping numeric key 1234567890 in %s on line %d -bool(false) +string(0) "" bool(true) bool(true) Warning: session_encode(): Skipping numeric key -1234567890 in %s on line %d -bool(false) +string(0) "" bool(true) Done diff --git a/ext/session/tests/session_get_cookie_params_basic.phpt b/ext/session/tests/session_get_cookie_params_basic.phpt index 65b020d30b9e..8e7f8da4e3fb 100644 --- a/ext/session/tests/session_get_cookie_params_basic.phpt +++ b/ext/session/tests/session_get_cookie_params_basic.phpt @@ -9,6 +9,7 @@ session.cookie_lifetime=0 session.cookie_path="/" session.cookie_domain="" session.cookie_secure=0 +session.cookie_partitioned=0 session.cookie_httponly=0 session.cookie_samesite="" --FILE-- @@ -21,7 +22,7 @@ echo "*** Testing session_get_cookie_params() : basic functionality ***\n"; var_dump(session_get_cookie_params()); var_dump(session_set_cookie_params(3600, "/path", "blah", FALSE, FALSE)); var_dump(session_get_cookie_params()); -var_dump(session_set_cookie_params(1234567890, "/guff", "foo", TRUE, TRUE)); +var_dump(session_set_cookie_params(1000000000, "/guff", "foo", TRUE, TRUE)); var_dump(session_get_cookie_params()); var_dump(session_set_cookie_params([ "lifetime" => 123, @@ -29,15 +30,19 @@ var_dump(session_set_cookie_params([ "domain" => "baz", "secure" => FALSE, "httponly" => FALSE, - "samesite" => "please"])); + "samesite" => "Strict"])); +var_dump(session_get_cookie_params()); +var_dump(session_set_cookie_params([ + "secure" => TRUE, + "partitioned" => TRUE])); var_dump(session_get_cookie_params()); echo "Done"; ob_end_flush(); ?> ---EXPECTF-- +--EXPECT-- *** Testing session_get_cookie_params() : basic functionality *** -array(6) { +array(7) { ["lifetime"]=> int(0) ["path"]=> @@ -46,13 +51,15 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } bool(true) -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -61,28 +68,32 @@ array(6) { string(4) "blah" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } bool(true) -array(6) { +array(7) { ["lifetime"]=> - int(%d) + int(1000000000) ["path"]=> string(5) "/guff" ["domain"]=> string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(true) ["samesite"]=> string(0) "" } bool(true) -array(6) { +array(7) { ["lifetime"]=> int(123) ["path"]=> @@ -91,9 +102,28 @@ array(6) { string(3) "baz" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) + ["httponly"]=> + bool(false) + ["samesite"]=> + string(6) "Strict" +} +bool(true) +array(7) { + ["lifetime"]=> + int(123) + ["path"]=> + string(4) "/bar" + ["domain"]=> + string(3) "baz" + ["secure"]=> + bool(true) + ["partitioned"]=> + bool(true) ["httponly"]=> bool(false) ["samesite"]=> - string(6) "please" + string(6) "Strict" } Done diff --git a/ext/session/tests/session_get_cookie_params_variation1.phpt b/ext/session/tests/session_get_cookie_params_variation1.phpt index 4feb0d3ec81d..0ab0f233530b 100644 --- a/ext/session/tests/session_get_cookie_params_variation1.phpt +++ b/ext/session/tests/session_get_cookie_params_variation1.phpt @@ -9,6 +9,7 @@ session.cookie_lifetime=0 session.cookie_path="/" session.cookie_domain="" session.cookie_secure=0 +session.cookie_partitioned=0 session.cookie_httponly=0 session.cookie_samesite="" --FILE-- @@ -29,7 +30,9 @@ ini_set("session.cookie_secure", TRUE); var_dump(session_get_cookie_params()); ini_set("session.cookie_httponly", TRUE); var_dump(session_get_cookie_params()); -ini_set("session.cookie_samesite", "foo"); +ini_set("session.cookie_samesite", "Lax"); +var_dump(session_get_cookie_params()); +ini_set("session.cookie_partitioned", TRUE); var_dump(session_get_cookie_params()); echo "Done"; @@ -37,7 +40,7 @@ ob_end_flush(); ?> --EXPECT-- *** Testing session_get_cookie_params() : variation *** -array(6) { +array(7) { ["lifetime"]=> int(0) ["path"]=> @@ -46,12 +49,14 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -60,12 +65,14 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -74,12 +81,14 @@ array(6) { string(0) "" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -88,12 +97,14 @@ array(6) { string(3) "foo" ["secure"]=> bool(false) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -102,12 +113,14 @@ array(6) { string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(false) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -116,12 +129,14 @@ array(6) { string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(true) ["samesite"]=> string(0) "" } -array(6) { +array(7) { ["lifetime"]=> int(3600) ["path"]=> @@ -130,9 +145,27 @@ array(6) { string(3) "foo" ["secure"]=> bool(true) + ["partitioned"]=> + bool(false) ["httponly"]=> bool(true) ["samesite"]=> + string(3) "Lax" +} +array(7) { + ["lifetime"]=> + int(3600) + ["path"]=> + string(5) "/path" + ["domain"]=> string(3) "foo" + ["secure"]=> + bool(true) + ["partitioned"]=> + bool(true) + ["httponly"]=> + bool(true) + ["samesite"]=> + string(3) "Lax" } Done diff --git a/ext/session/tests/session_module_name_errors.phpt b/ext/session/tests/session_module_name_errors.phpt new file mode 100644 index 000000000000..f00171e6584a --- /dev/null +++ b/ext/session/tests/session_module_name_errors.phpt @@ -0,0 +1,22 @@ +--TEST-- +session_module_name(): errors +--EXTENSIONS-- +session +--FILE-- +getMessage(), PHP_EOL; +} +try { + var_dump(session_module_name("fi\0le")); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: session_module_name(): Argument #1 ($module) must not be "user" +ValueError: session_module_name(): Argument #1 ($module) must not contain any null bytes diff --git a/ext/session/tests/session_regenerate_id_cookie.phpt b/ext/session/tests/session_regenerate_id_cookie.phpt index f1dc0727205d..32706047539a 100644 --- a/ext/session/tests/session_regenerate_id_cookie.phpt +++ b/ext/session/tests/session_regenerate_id_cookie.phpt @@ -55,7 +55,7 @@ ob_end_flush(); ?>'); $extra_arguments = getenv('TEST_PHP_EXTRA_ARGS'); -var_dump(`$php $extra_arguments -d session.name=PHPSESSID $file`); +var_dump(shell_exec("$php $extra_arguments -d session.name=PHPSESSID $file")); unlink($file); @@ -67,14 +67,14 @@ string(%d) "X-Powered-By: PHP/%d.%d.%s Expires: %s Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache -Set-Cookie: PHPSESSID=%s; path=/ +Set-Cookie: PHPSESSID=%s; path=/; HttpOnly; SameSite=Lax Content-type: text/html; charset=UTF-8 bool(true) -Set-Cookie: PHPSESSID=%s; path=/ +Set-Cookie: PHPSESSID=%s; path=/; HttpOnly; SameSite=Lax bool(true) bool(true) -Set-Cookie: PHPSESSID=%s; path=/ +Set-Cookie: PHPSESSID=%s; path=/; HttpOnly; SameSite=Lax bool(true) bool(true) string(32) "%s" diff --git a/ext/session/tests/session_set_cookie_params_basic.phpt b/ext/session/tests/session_set_cookie_params_basic.phpt index 386280d17861..27cfd59b183e 100644 --- a/ext/session/tests/session_set_cookie_params_basic.phpt +++ b/ext/session/tests/session_set_cookie_params_basic.phpt @@ -15,7 +15,7 @@ var_dump(session_set_cookie_params(3600)); var_dump(session_start()); var_dump(session_set_cookie_params(1800)); var_dump(session_destroy()); -var_dump(session_set_cookie_params(1234567890)); +var_dump(session_set_cookie_params(1000000000)); echo "Done"; ob_end_flush(); diff --git a/ext/session/tests/session_set_cookie_params_invalid_ini.phpt b/ext/session/tests/session_set_cookie_params_invalid_ini.phpt new file mode 100644 index 000000000000..8ebef4a5209d --- /dev/null +++ b/ext/session/tests/session_set_cookie_params_invalid_ini.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test session.cookie_samesite with invalid INI value +--INI-- +session.cookie_samesite=Invalid +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: PHP Startup: session.cookie_samesite must be "Strict", "Lax", "None", or "" in Unknown on line 0 +string(3) "Lax" +Done diff --git a/ext/session/tests/session_set_cookie_params_variation1.phpt b/ext/session/tests/session_set_cookie_params_variation1.phpt index ed0b8dc9755d..ce4b98457bea 100644 --- a/ext/session/tests/session_set_cookie_params_variation1.phpt +++ b/ext/session/tests/session_set_cookie_params_variation1.phpt @@ -24,7 +24,7 @@ var_dump(ini_get("session.cookie_lifetime")); var_dump(session_destroy()); var_dump(ini_get("session.cookie_lifetime")); -var_dump(session_set_cookie_params(1234567890)); +var_dump(session_set_cookie_params(1000000000)); var_dump(ini_get("session.cookie_lifetime")); echo "Done"; @@ -44,5 +44,5 @@ string(4) "3600" bool(true) string(4) "3600" bool(true) -string(10) "1234567890" +string(10) "1000000000" Done diff --git a/ext/session/tests/session_set_cookie_params_variation6.phpt b/ext/session/tests/session_set_cookie_params_variation6.phpt index 61243f82751e..fbf958a0be07 100644 --- a/ext/session/tests/session_set_cookie_params_variation6.phpt +++ b/ext/session/tests/session_set_cookie_params_variation6.phpt @@ -1,7 +1,7 @@ --TEST-- -Test session_set_cookie_params() function : variation +Test session_set_cookie_params() samesite validation --INI-- -session.cookie_samesite=test +session.cookie_samesite=Lax --EXTENSIONS-- session --SKIPIF-- @@ -11,36 +11,56 @@ session ob_start(); -echo "*** Testing session_set_cookie_params() : variation ***\n"; - +echo "-- Valid values --\n"; var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["samesite" => "nothing"])); +var_dump(session_set_cookie_params(["samesite" => "Strict"])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_start()); +var_dump(session_set_cookie_params(["samesite" => "None"])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["samesite" => "test"])); +var_dump(session_set_cookie_params(["samesite" => ""])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_destroy()); + +echo "-- Invalid value via session_set_cookie_params --\n"; +var_dump(session_set_cookie_params(["samesite" => "Invalid"])); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["samesite" => "other"])); + +echo "-- Invalid value via ini_set --\n"; +var_dump(ini_set("session.cookie_samesite", "Invalid")); var_dump(ini_get("session.cookie_samesite")); +echo "-- Cannot change while session is active --\n"; +var_dump(session_set_cookie_params(["samesite" => "Lax"])); +var_dump(session_start()); +var_dump(session_set_cookie_params(["samesite" => "Strict"])); +var_dump(session_destroy()); + echo "Done"; ob_end_flush(); ?> --EXPECTF-- -*** Testing session_set_cookie_params() : variation *** -string(4) "test" +-- Valid values -- +string(3) "Lax" bool(true) -string(7) "nothing" +string(6) "Strict" bool(true) -string(7) "nothing" +string(4) "None" +bool(true) +string(0) "" +-- Invalid value via session_set_cookie_params -- -Warning: session_set_cookie_params(): Session cookie parameters cannot be changed when a session is active (started from %s on line %d) in %s on line %d +Warning: session_set_cookie_params(): session.cookie_samesite must be "Strict", "Lax", "None", or "" in %s on line %d +bool(false) +string(0) "" +-- Invalid value via ini_set -- + +Warning: ini_set(): session.cookie_samesite must be "Strict", "Lax", "None", or "" in %s on line %d bool(false) -string(7) "nothing" +string(0) "" +-- Cannot change while session is active -- bool(true) -string(7) "nothing" bool(true) -string(5) "other" + +Warning: session_set_cookie_params(): Session cookie parameters cannot be changed when a session is active (started from %s on line %d) in %s on line %d +bool(false) +bool(true) Done diff --git a/ext/session/tests/session_set_cookie_params_variation7.phpt b/ext/session/tests/session_set_cookie_params_variation7.phpt index 430c6efc36e9..3780fc0222f1 100644 --- a/ext/session/tests/session_set_cookie_params_variation7.phpt +++ b/ext/session/tests/session_set_cookie_params_variation7.phpt @@ -33,7 +33,7 @@ try { var_dump(ini_get("session.cookie_secure")); var_dump(ini_get("session.cookie_samesite")); -var_dump(session_set_cookie_params(["secure" => true, "samesite" => "please"])); +var_dump(session_set_cookie_params(["secure" => true, "samesite" => "Strict"])); var_dump(ini_get("session.cookie_secure")); var_dump(ini_get("session.cookie_samesite")); @@ -66,7 +66,7 @@ string(1) "0" string(0) "" bool(true) string(1) "1" -string(6) "please" +string(6) "Strict" string(1) "0" bool(true) string(2) "42" diff --git a/ext/session/tests/session_set_cookie_params_variation8.phpt b/ext/session/tests/session_set_cookie_params_variation8.phpt index 891133b5b01e..1497ded69d5f 100644 --- a/ext/session/tests/session_set_cookie_params_variation8.phpt +++ b/ext/session/tests/session_set_cookie_params_variation8.phpt @@ -25,7 +25,7 @@ bool(true) string(1) "0" string(1) "0" -Warning: session_set_cookie_params(): CookieLifetime cannot be negative in %s on line %d +Warning: session_set_cookie_params(): session.cookie_lifetime must be between 0 and %d in %s on line %d bool(false) string(1) "0" Done diff --git a/ext/session/tests/session_start_partitioned.phpt b/ext/session/tests/session_start_partitioned.phpt new file mode 100644 index 000000000000..c2c1b33ae074 --- /dev/null +++ b/ext/session/tests/session_start_partitioned.phpt @@ -0,0 +1,31 @@ +--TEST-- +session_start() with partitioned cookies +--INI-- +session.use_strict_mode=0 +session.save_handler=files +session.save_path= +session.cookie_secure=0 +session.cookie_partitioned=0 +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + true])); +var_dump(session_start(['cookie_partitioned' => true, 'cookie_secure' => false])); +var_dump(session_start(['cookie_partitioned' => true, 'cookie_secure' => true])); + +ob_end_flush(); + +?> +--EXPECTF-- +Warning: session_start(): Partitioned session cookie cannot be used without also configuring it as secure in %s on line %d +bool(false) + +Warning: session_start(): Partitioned session cookie cannot be used without also configuring it as secure in %s on line %d +bool(false) +bool(true) diff --git a/ext/session/tests/session_start_partitioned_headers.phpt b/ext/session/tests/session_start_partitioned_headers.phpt new file mode 100644 index 000000000000..4a2c7dcf878f --- /dev/null +++ b/ext/session/tests/session_start_partitioned_headers.phpt @@ -0,0 +1,15 @@ +--TEST-- +session_start() with partitioned cookies - header test +--EXTENSIONS-- +session +--INI-- +session.use_strict_mode=0 +--FILE-- + true, "partitioned" => true]); +session_start(); +?> +--EXPECTHEADERS-- +Set-Cookie: PHPSESSID=12345; path=/; secure; Partitioned; HttpOnly; SameSite=Lax +--EXPECT-- diff --git a/ext/session/tests/session_str_settings_null_byte.phpt b/ext/session/tests/session_str_settings_null_byte.phpt new file mode 100644 index 000000000000..693ec6971601 --- /dev/null +++ b/ext/session/tests/session_str_settings_null_byte.phpt @@ -0,0 +1,37 @@ +--TEST-- +session.cookie_path, session.cookie_domain, and session.cache_limiter must not contain null bytes +--EXTENSIONS-- +session +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: ini_set(): "session.cookie_path" must not contain null bytes in %s on line %d +bool(false) + +Warning: ini_set(): "session.cookie_domain" must not contain null bytes in %s on line %d +bool(false) + +Warning: ini_set(): "session.cache_limiter" must not contain null bytes in %s on line %d +bool(false) + +Warning: session_set_cookie_params(): "session.cookie_path" must not contain null bytes in %s on line %d +bool(false) + +Warning: session_set_cookie_params(): "session.cookie_domain" must not contain null bytes in %s on line %d +bool(false) +Done diff --git a/ext/session/tests/user_session_module/bug61728.phpt b/ext/session/tests/user_session_module/bug61728.phpt index fd79fa6b2bce..152cf9f42bee 100644 --- a/ext/session/tests/user_session_module/bug61728.phpt +++ b/ext/session/tests/user_session_module/bug61728.phpt @@ -5,7 +5,7 @@ session --FILE-- +--EXPECTF-- + +Deprecated: session_set_save_handler(): Providing individual callbacks instead of an object implementing SessionHandlerInterface is deprecated in %s on line %d +bool(false) diff --git a/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt b/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt index 9c584eec597b..a3e21c35e49d 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt @@ -83,7 +83,7 @@ Read [%s,PHPT-%d] GC [0] 1 deleted bool(true) -Write [%s,PHPT-%d,] +Update [%s,PHPT-%d] Close [%s,PHPSESSID] bool(true) string(%d) "PHPT-%d" diff --git a/ext/shmop/php_shmop.h b/ext/shmop/php_shmop.h index 8d1d3cd8fd44..265753ea454a 100644 --- a/ext/shmop/php_shmop.h +++ b/ext/shmop/php_shmop.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Slava Poliakov | | Ilia Alshanetsky | diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c index 67f060f3c82c..8721e4333ce8 100644 --- a/ext/shmop/shmop.c +++ b/ext/shmop/shmop.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | PHP version 7 | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Slava Poliakov | | Ilia Alshanetsky | @@ -74,7 +70,7 @@ static zend_object_handlers shmop_object_handlers; static inline php_shmop *shmop_from_obj(zend_object *obj) { - return (php_shmop *)((char *)(obj) - XtOffsetOf(php_shmop, std)); + return ZEND_CONTAINER_OF(obj, php_shmop, std); } #define Z_SHMOP_P(zv) shmop_from_obj(Z_OBJ_P(zv)) @@ -112,7 +108,7 @@ PHP_MINIT_FUNCTION(shmop) shmop_ce->default_object_handlers = &shmop_object_handlers; memcpy(&shmop_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - shmop_object_handlers.offset = XtOffsetOf(php_shmop, std); + shmop_object_handlers.offset = offsetof(php_shmop, std); shmop_object_handlers.free_obj = shmop_free_obj; shmop_object_handlers.get_constructor = shmop_get_constructor; shmop_object_handlers.clone_obj = NULL; diff --git a/ext/shmop/shmop_arginfo.h b/ext/shmop/shmop_arginfo.h index 54bb2e19d546..9d88fe63c32b 100644 --- a/ext/shmop/shmop_arginfo.h +++ b/ext/shmop/shmop_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit shmop.stub.php instead. * Stub hash: e7f250077b6721539caee96afe4ed392396018f9 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_shmop_open, 0, 4, Shmop, MAY_BE_FALSE) @@ -53,15 +53,10 @@ static void register_shmop_symbols(int module_number) { zend_attribute *attribute_Deprecated_func_shmop_close_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "shmop_close", sizeof("shmop_close") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_shmop_close_0_arg0; - zend_string *attribute_Deprecated_func_shmop_close_0_arg0_str = zend_string_init("8.0", strlen("8.0"), 1); - ZVAL_STR(&attribute_Deprecated_func_shmop_close_0_arg0, attribute_Deprecated_func_shmop_close_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_shmop_close_0->args[0].value, &attribute_Deprecated_func_shmop_close_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_shmop_close_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_0)); attribute_Deprecated_func_shmop_close_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_shmop_close_0_arg1; zend_string *attribute_Deprecated_func_shmop_close_0_arg1_str = zend_string_init("as Shmop objects are freed automatically", strlen("as Shmop objects are freed automatically"), 1); - ZVAL_STR(&attribute_Deprecated_func_shmop_close_0_arg1, attribute_Deprecated_func_shmop_close_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_shmop_close_0->args[1].value, &attribute_Deprecated_func_shmop_close_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_shmop_close_0->args[1].value, attribute_Deprecated_func_shmop_close_0_arg1_str); attribute_Deprecated_func_shmop_close_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/simplexml/config.w32 b/ext/simplexml/config.w32 index 8942e6c93e3b..0c2e7c5f5a79 100644 --- a/ext/simplexml/config.w32 +++ b/ext/simplexml/config.w32 @@ -6,7 +6,7 @@ if (PHP_SIMPLEXML == "yes") { if(PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('simplexml', 'libxml') && ADD_EXTENSION_DEP('simplexml', 'spl') && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_SIMPLEXML", PHP_PHP_BUILD + "\\include\\libxml2") + CHECK_HEADER("libxml/tree.h", "CFLAGS_SIMPLEXML", PHP_PHP_BUILD + "\\include\\libxml2") ) { EXTENSION("simplexml", "simplexml.c"); AC_DEFINE("HAVE_SIMPLEXML", 1, "Define to 1 if the PHP extension 'simplexml' is available."); diff --git a/ext/simplexml/php_simplexml.h b/ext/simplexml/php_simplexml.h index 5d16794fa644..f8d78937b9d9 100644 --- a/ext/simplexml/php_simplexml.h +++ b/ext/simplexml/php_simplexml.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sterling Hughes | +----------------------------------------------------------------------+ diff --git a/ext/simplexml/php_simplexml_exports.h b/ext/simplexml/php_simplexml_exports.h index 4ae02674d6da..8e07bbf19f2e 100644 --- a/ext/simplexml/php_simplexml_exports.h +++ b/ext/simplexml/php_simplexml_exports.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sterling Hughes | | Marcus Boerger | @@ -38,7 +36,7 @@ PHP_SXE_API zend_object *sxe_object_new(zend_class_entry *ce); static inline php_sxe_object *php_sxe_fetch_object(zend_object *obj) /* {{{ */ { - return (php_sxe_object *)((char*)(obj) - XtOffsetOf(php_sxe_object, zo)); + return ZEND_CONTAINER_OF(obj, php_sxe_object, zo); } /* }}} */ diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index db1d002b6697..d86198c7639e 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sterling Hughes | | Marcus Boerger | @@ -1179,12 +1177,12 @@ static HashTable *sxe_get_properties(zend_object *object) /* {{{ */ } /* }}} */ -static HashTable * sxe_get_debug_info(zend_object *object, int *is_temp) /* {{{ */ +/* This custom handler exists because the var_dump adds a pseudo "@attributes" key. */ +PHP_METHOD(SimpleXMLElement, __debugInfo) { - *is_temp = 1; - return sxe_get_prop_hash(object, 1); + ZEND_PARSE_PARAMETERS_NONE(); + RETURN_ARR(sxe_get_prop_hash(Z_OBJ_P(ZEND_THIS), 1)); } -/* }}} */ static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */ { @@ -1413,14 +1411,10 @@ PHP_METHOD(SimpleXMLElement, asXML) static inline void sxe_add_namespace_name_raw(zval *return_value, const char *prefix, const char *href) { - zend_string *key = zend_string_init(prefix, strlen(prefix), 0); - zval zv; - - if (!zend_hash_exists(Z_ARRVAL_P(return_value), key)) { - ZVAL_STRING(&zv, href); - zend_hash_add_new(Z_ARRVAL_P(return_value), key, &zv); + zval *zv = zend_hash_str_lookup(Z_ARRVAL_P(return_value), prefix, strlen(prefix)); + if (Z_ISNULL_P(zv)) { + ZVAL_STRING(zv, href); } - zend_string_release_ex(key, 0); } static inline void sxe_add_namespace_name(zval *return_value, xmlNsPtr ns) /* {{{ */ @@ -1489,7 +1483,7 @@ static inline void sxe_object_free_iterxpath(php_sxe_object *sxe) /* {{{ Return all namespaces in use */ PHP_METHOD(SimpleXMLElement, getNamespaces) { - bool recursive = 0; + bool recursive = false; php_sxe_object *sxe; xmlNodePtr node; @@ -1528,10 +1522,10 @@ static void sxe_add_registered_namespaces(php_sxe_object *sxe, xmlNodePtr node, /* Attributes in the xmlns namespace should be treated as namespace declarations too. */ if (attr->ns && xmlStrEqual(attr->ns->href, (const xmlChar *) "http://www.w3.org/2000/xmlns/")) { const char *prefix = attr->ns->prefix ? (const char *) attr->name : ""; - bool free; - xmlChar *href = php_libxml_attr_value(attr, &free); + bool should_free; + xmlChar *href = php_libxml_attr_value(attr, &should_free); sxe_add_namespace_name_raw(return_value, prefix, (const char *) href); - if (free) { + if (should_free) { xmlFree(href); } } @@ -1551,7 +1545,7 @@ static void sxe_add_registered_namespaces(php_sxe_object *sxe, xmlNodePtr node, /* {{{ Return all namespaces registered with document */ PHP_METHOD(SimpleXMLElement, getDocNamespaces) { - bool recursive = 0, from_root = 1; + bool recursive = false, from_root = true; php_sxe_object *sxe; xmlNodePtr node; @@ -1589,7 +1583,7 @@ PHP_METHOD(SimpleXMLElement, children) php_sxe_object *sxe; zend_string *nsprefix = NULL; xmlNodePtr node; - bool isprefix = 0; + bool isprefix = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!b", &nsprefix, &isprefix) == FAILURE) { RETURN_THROWS(); @@ -1618,9 +1612,7 @@ PHP_METHOD(SimpleXMLElement, getName) xmlNodePtr node; int namelen; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); sxe = Z_SXEOBJ_P(ZEND_THIS); @@ -1628,7 +1620,7 @@ PHP_METHOD(SimpleXMLElement, getName) node = php_sxe_get_first_node_non_destructive(sxe, node); if (node) { namelen = xmlStrlen(node->name); - RETURN_STRINGL((char*)node->name, namelen); + RETURN_STRINGL_FAST((const char *) node->name, namelen); } else { RETURN_EMPTY_STRING(); } @@ -1641,7 +1633,7 @@ PHP_METHOD(SimpleXMLElement, attributes) php_sxe_object *sxe; zend_string *nsprefix = NULL; xmlNodePtr node; - bool isprefix = 0; + bool isprefix = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!b", &nsprefix, &isprefix) == FAILURE) { RETURN_THROWS(); @@ -1904,9 +1896,7 @@ static zend_result sxe_object_cast(zend_object *readobj, zval *writeobj, int typ /* {{{ Returns the string content */ PHP_METHOD(SimpleXMLElement, __toString) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_result rv = sxe_object_cast_ex(Z_OBJ_P(ZEND_THIS), return_value, IS_STRING); ZEND_IGNORE_VALUE(rv); @@ -1954,9 +1944,7 @@ PHP_METHOD(SimpleXMLElement, count) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(php_sxe_count_elements_helper(sxe)); } @@ -1966,9 +1954,7 @@ PHP_METHOD(SimpleXMLElement, count) /* {{{ Rewind to first element */ PHP_METHOD(SimpleXMLElement, rewind) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); php_sxe_rewind_iterator(Z_SXEOBJ_P(ZEND_THIS)); } @@ -1979,9 +1965,7 @@ PHP_METHOD(SimpleXMLElement, valid) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(!Z_ISUNDEF(sxe->iter.data)); } @@ -1992,9 +1976,7 @@ PHP_METHOD(SimpleXMLElement, current) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data)) { zend_throw_error(NULL, "Iterator not initialized or already consumed"); @@ -2012,9 +1994,7 @@ PHP_METHOD(SimpleXMLElement, key) php_sxe_object *intern; php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data)) { zend_throw_error(NULL, "Iterator not initialized or already consumed"); @@ -2028,16 +2008,14 @@ PHP_METHOD(SimpleXMLElement, key) } curnode = intern->node->node; - RETURN_STRINGL((char*)curnode->name, xmlStrlen(curnode->name)); + RETURN_STRINGL_FAST((char*)curnode->name, xmlStrlen(curnode->name)); } /* }}} */ /* {{{ Move to next element */ PHP_METHOD(SimpleXMLElement, next) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); php_sxe_move_forward_iterator(Z_SXEOBJ_P(ZEND_THIS)); } @@ -2050,9 +2028,7 @@ PHP_METHOD(SimpleXMLElement, hasChildren) php_sxe_object *child; xmlNodePtr node; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) { RETURN_FALSE; @@ -2075,9 +2051,7 @@ PHP_METHOD(SimpleXMLElement, getChildren) { php_sxe_object *sxe = Z_SXEOBJ_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) { return; /* return NULL */ @@ -2208,7 +2182,7 @@ PHP_FUNCTION(simplexml_load_file) zend_long options = 0; zend_class_entry *ce= ce_SimpleXMLElement; zend_function *fptr_count; - bool isprefix = 0; + bool isprefix = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|C!lSb", &filename, &filename_len, &ce, &options, &ns, &isprefix) == FAILURE) { RETURN_THROWS(); @@ -2254,7 +2228,7 @@ PHP_FUNCTION(simplexml_load_string) zend_long options = 0; zend_class_entry *ce= ce_SimpleXMLElement; zend_function *fptr_count; - bool isprefix = 0; + bool isprefix = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|C!lSb", &data, &data_len, &ce, &options, &ns, &isprefix) == FAILURE) { RETURN_THROWS(); @@ -2306,7 +2280,7 @@ PHP_METHOD(SimpleXMLElement, __construct) size_t data_len; xmlDocPtr docp; zend_long options = 0; - bool is_url = 0, isprefix = 0; + bool is_url = false, isprefix = false; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lbSb", &data, &data_len, &options, &is_url, &ns, &isprefix) == FAILURE) { RETURN_THROWS(); @@ -2657,7 +2631,7 @@ PHP_MINIT_FUNCTION(simplexml) ce_SimpleXMLElement->get_iterator = php_sxe_get_iterator; memcpy(&sxe_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sxe_object_handlers.offset = XtOffsetOf(php_sxe_object, zo); + sxe_object_handlers.offset = offsetof(php_sxe_object, zo); sxe_object_handlers.free_obj = sxe_object_free_storage; sxe_object_handlers.clone_obj = sxe_object_clone; sxe_object_handlers.read_property = sxe_property_read; @@ -2673,7 +2647,6 @@ PHP_MINIT_FUNCTION(simplexml) sxe_object_handlers.compare = sxe_objects_compare; sxe_object_handlers.cast_object = sxe_object_cast; sxe_object_handlers.count_elements = sxe_count_elements; - sxe_object_handlers.get_debug_info = sxe_get_debug_info; sxe_object_handlers.get_closure = NULL; sxe_object_handlers.get_gc = sxe_get_gc; diff --git a/ext/simplexml/simplexml.stub.php b/ext/simplexml/simplexml.stub.php index 2053fec6fdd2..6faf873c885f 100644 --- a/ext/simplexml/simplexml.stub.php +++ b/ext/simplexml/simplexml.stub.php @@ -51,6 +51,8 @@ public function getName(): string {} public function __toString(): string {} + public function __debugInfo(): array {} + /** @tentative-return-type */ public function count(): int {} diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index 379307f953a1..5a62efbc7be5 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 36eac2dee86bcc386c24e2cc14caa7bd3d709e82 */ +/* This is a generated file, edit simplexml.stub.php instead. + * Stub hash: 83f1bd204b309a4558c1b09128fe29f972f54252 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_simplexml_load_file, 0, 1, SimpleXMLElement, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -79,6 +79,9 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___toString, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___debugInfo, 0, 0, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement_count, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -115,6 +118,7 @@ ZEND_METHOD(SimpleXMLElement, addChild); ZEND_METHOD(SimpleXMLElement, addAttribute); ZEND_METHOD(SimpleXMLElement, getName); ZEND_METHOD(SimpleXMLElement, __toString); +ZEND_METHOD(SimpleXMLElement, __debugInfo); ZEND_METHOD(SimpleXMLElement, count); ZEND_METHOD(SimpleXMLElement, rewind); ZEND_METHOD(SimpleXMLElement, valid); @@ -145,6 +149,7 @@ static const zend_function_entry class_SimpleXMLElement_methods[] = { ZEND_ME(SimpleXMLElement, addAttribute, arginfo_class_SimpleXMLElement_addAttribute, ZEND_ACC_PUBLIC) ZEND_ME(SimpleXMLElement, getName, arginfo_class_SimpleXMLElement_getName, ZEND_ACC_PUBLIC) ZEND_ME(SimpleXMLElement, __toString, arginfo_class_SimpleXMLElement___toString, ZEND_ACC_PUBLIC) + ZEND_ME(SimpleXMLElement, __debugInfo, arginfo_class_SimpleXMLElement___debugInfo, ZEND_ACC_PUBLIC) ZEND_ME(SimpleXMLElement, count, arginfo_class_SimpleXMLElement_count, ZEND_ACC_PUBLIC) ZEND_ME(SimpleXMLElement, rewind, arginfo_class_SimpleXMLElement_rewind, ZEND_ACC_PUBLIC) ZEND_ME(SimpleXMLElement, valid, arginfo_class_SimpleXMLElement_valid, ZEND_ACC_PUBLIC) diff --git a/ext/simplexml/tests/033.phpt b/ext/simplexml/tests/033.phpt index 6fd52750ee0b..6d681d7695ca 100644 --- a/ext/simplexml/tests/033.phpt +++ b/ext/simplexml/tests/033.phpt @@ -25,8 +25,8 @@ var_dump((bool)$foo); var_dump((bool)$people); var_dump((int)$foo); var_dump((int)$people); -var_dump((double)$foo); -var_dump((double)$people); +var_dump((float)$foo); +var_dump((float)$people); var_dump((string)$foo); var_dump((string)$people); var_dump((array)$foo); diff --git a/ext/simplexml/tests/bug54973.phpt b/ext/simplexml/tests/bug54973.phpt index 5c9f6ffaca22..ad8a986ff567 100644 --- a/ext/simplexml/tests/bug54973.phpt +++ b/ext/simplexml/tests/bug54973.phpt @@ -11,8 +11,8 @@ var_dump($xml->number); $int = $xml->number / 1024 / 1024 / 1024; var_dump($int); -$double = (double) $xml->number / 1024 / 1024 / 1024; -var_dump($double); +$float = (float) $xml->number / 1024 / 1024 / 1024; +var_dump($float); ?> --EXPECT-- object(SimpleXMLElement)#2 (1) { diff --git a/ext/simplexml/tests/gh15837.phpt b/ext/simplexml/tests/gh15837.phpt index 302db064ee0e..c654938e2c3c 100644 --- a/ext/simplexml/tests/gh15837.phpt +++ b/ext/simplexml/tests/gh15837.phpt @@ -2,6 +2,8 @@ GH-15837 (Segmentation fault in ext/simplexml/simplexml.c) --CREDITS-- YuanchengJiang +--EXTENSIONS-- +simplexml --FILE-- 1]; + } +} + +$sxe = simplexml_load_string('', MySXE::class); +var_dump($sxe); + +?> +--EXPECT-- +invoked +object(MySXE)#1 (1) { + ["x"]=> + int(1) +} diff --git a/ext/skeleton/composer.json.in b/ext/skeleton/composer.json.in new file mode 100644 index 000000000000..8f12bdee475b --- /dev/null +++ b/ext/skeleton/composer.json.in @@ -0,0 +1,19 @@ +{ + "name": "%VENDORNAME%/%EXTNAME%", + "type": "php-ext", + "license": "BSD-3-Clause", + "description": "Describe your extension here", + "require": { + "php": "^8.3" + }, + "php-ext": { + "extension-name": "%EXTNAME%", + "configure-options": [ + { + "name": "enable-%EXTNAME%", + "needs-value": false, + "description": "whether to enable %EXTNAME% support" + } + ] + } +} diff --git a/ext/skeleton/skeleton_arginfo.h b/ext/skeleton/skeleton_arginfo.h index 50b6b7793ef5..e74b28c0faa9 100644 --- a/ext/skeleton/skeleton_arginfo.h +++ b/ext/skeleton/skeleton_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit skeleton.stub.php instead. * Stub hash: 54b0ffc3af871b189435266df516f7575c1b9675 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_test1, 0, 0, IS_VOID, 0) diff --git a/ext/snmp/config.w32 b/ext/snmp/config.w32 index a2facb6946d6..bf63e89a9607 100644 --- a/ext/snmp/config.w32 +++ b/ext/snmp/config.w32 @@ -3,12 +3,13 @@ ARG_WITH("snmp", "SNMP support", "no"); if (PHP_SNMP != "no") { - if (CHECK_HEADER_ADD_INCLUDE("snmp.h", "CFLAGS_SNMP", PHP_PHP_BUILD + "\\include\\net-snmp;" + PHP_SNMP) && + if (CHECK_HEADER("snmp.h", "CFLAGS_SNMP", PHP_PHP_BUILD + "\\include\\net-snmp;" + PHP_SNMP) && SETUP_OPENSSL("snmp", PHP_SNMP) >= 2) { if (CHECK_LIB("netsnmp.lib", "snmp", PHP_SNMP)) { EXTENSION('snmp', 'snmp.c'); ADD_EXTENSION_DEP('snmp', 'spl'); AC_DEFINE('HAVE_SNMP', 1, "Define to 1 if the PHP extension 'snmp' is available."); + AC_DEFINE('HAVE_SHUTDOWN_SNMP_LOGGING', 1, "Define to 1 if SNMP library has the 'shutdown_snmp_logging' function."); } else { WARNING("snmp not enabled; libraries and headers not found"); } diff --git a/ext/snmp/php_snmp.h b/ext/snmp/php_snmp.h index ce9849588b19..40c5bebb0c04 100644 --- a/ext/snmp/php_snmp.h +++ b/ext/snmp/php_snmp.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Mike Jackson | @@ -59,7 +57,7 @@ typedef struct _php_snmp_object { } php_snmp_object; static inline php_snmp_object *php_snmp_fetch_object(zend_object *obj) { - return (php_snmp_object *)((char*)(obj) - XtOffsetOf(php_snmp_object, zo)); + return ZEND_CONTAINER_OF(obj, php_snmp_object, zo); } #define Z_SNMP_P(zv) php_snmp_fetch_object(Z_OBJ_P((zv))) diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 915c4a46e1b1..44f714bf0368 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Mike Jackson | @@ -34,7 +32,6 @@ #include "php_snmp.h" #include "zend_exceptions.h" -#include "zend_smart_string.h" #include "ext/spl/spl_exceptions.h" #ifdef HAVE_SNMP @@ -627,7 +624,7 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st, static void php_snmp_zend_string_release_from_char_pointer(char *ptr) { if (ptr) { - zend_string *pptr = (zend_string *)(ptr - XtOffsetOf(zend_string, val)); + zend_string *pptr = (zend_string *)(ptr - offsetof(zend_string, val)); zend_string_release(pptr); } } @@ -656,7 +653,8 @@ static void php_free_objid_query(struct objid_query *objid_query, HashTable* oid */ static bool php_snmp_parse_oid( zval *object, int st, struct objid_query *objid_query, zend_string *oid_str, HashTable *oid_ht, - zend_string *type_str, HashTable *type_ht, zend_string *value_str, HashTable *value_ht + zend_string *type_str, HashTable *type_ht, zend_string *value_str, HashTable *value_ht, + uint32_t oid_arg_num, uint32_t type_arg_num, uint32_t value_arg_num ) { char *pptr; uint32_t idx_type = 0, idx_value = 0; @@ -683,7 +681,7 @@ static bool php_snmp_parse_oid( ZEND_ASSERT(type_str && value_str); if (ZSTR_LEN(type_str) != 1) { - zend_value_error("Type must be a single character"); + zend_argument_value_error(type_arg_num, "must be a single character"); efree(objid_query->vars); return false; } @@ -694,7 +692,7 @@ static bool php_snmp_parse_oid( objid_query->count++; } else if (oid_ht) { /* we got objid array */ if (zend_hash_num_elements(oid_ht) == 0) { - zend_value_error("Array of object IDs must not be empty"); + zend_argument_value_error(oid_arg_num, "must not be empty when passed as an array"); return false; } objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0); @@ -739,14 +737,14 @@ static bool php_snmp_parse_oid( char ptype = *ZSTR_VAL(type); zend_string_release(type); if (len != 1) { - zend_value_error("Type must be a single character"); + zend_argument_value_error(type_arg_num, "must be a single character"); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } objid_query->vars[objid_query->count].type = ptype; idx_type++; } else { - php_error_docref(NULL, E_WARNING, "'%s': no type set", ZSTR_VAL(tmp)); + zend_argument_value_error(type_arg_num, "must contain a type for object ID '%s'", ZSTR_VAL(tmp)); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } @@ -781,7 +779,7 @@ static bool php_snmp_parse_oid( objid_query->vars[objid_query->count].value = ZSTR_VAL(tmp); idx_value++; } else { - php_error_docref(NULL, E_WARNING, "'%s': no value set", ZSTR_VAL(tmp)); + zend_argument_value_error(value_arg_num, "must contain a value for object ID '%s'", ZSTR_VAL(tmp)); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } @@ -828,7 +826,7 @@ static bool php_snmp_parse_oid( /* {{{ snmp_session_init allocates memory for session and session->peername, caller should free it manually using snmp_session_free() and efree() */ -static bool snmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, zend_long timeout, zend_long retries, int timeout_argument_offset) +static bool snmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, zend_long timeout, zend_long retries, uint32_t hostname_arg_num, uint32_t timeout_arg_num) { php_snmp_session *session; char *pptr, *host_ptr; @@ -842,34 +840,24 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st ZEND_ASSERT(hostname != NULL); ZEND_ASSERT(community != NULL); - if (zend_str_has_nul_byte(hostname)) { - zend_argument_value_error(2, "must not contain any null bytes"); - return false; - } - if (ZSTR_LEN(hostname) >= MAX_NAME_LEN) { - zend_argument_value_error(2, "length must be lower than %d", MAX_NAME_LEN); - return false; - } - - if (zend_str_has_nul_byte(community)) { - zend_argument_value_error(3, "must not contain any null bytes"); + zend_argument_value_error(hostname_arg_num, "length must be lower than %d", MAX_NAME_LEN); return false; } if (ZSTR_LEN(community) == 0) { - zend_argument_must_not_be_empty_error(3); + zend_argument_must_not_be_empty_error(hostname_arg_num + 1); return false; } - if (timeout_argument_offset != -1) { + if (timeout_arg_num != 0) { if (timeout < -1 || timeout > LONG_MAX) { - zend_argument_value_error(timeout_argument_offset, "must be between -1 and %ld", LONG_MAX); + zend_argument_value_error(timeout_arg_num, "must be between -1 and %ld", LONG_MAX); return false; } if (retries < -1 || retries > INT_MAX) { - zend_argument_value_error(timeout_argument_offset + 1, "must be between -1 and %d", INT_MAX); + zend_argument_value_error(timeout_arg_num + 1, "must be between -1 and %d", INT_MAX); return false; } } @@ -900,14 +888,14 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st char *pport = pptr + 2; tmp_port = atoi(pport); if (tmp_port < 0 || tmp_port > USHRT_MAX) { - zend_argument_value_error(2, "remote port must be between 0 and %u", USHRT_MAX); + zend_argument_value_error(hostname_arg_num, "remote port must be between 0 and %u", USHRT_MAX); return false; } remote_port = (unsigned short)tmp_port; } *pptr = '\0'; } else { - php_error_docref(NULL, E_WARNING, "Malformed IPv6 address, closing square bracket missing"); + zend_argument_value_error(hostname_arg_num, "has a malformed IPv6 address, closing square bracket missing"); return false; } } else { /* IPv4 address */ @@ -915,7 +903,7 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st char *pport = pptr + 1; tmp_port = atoi(pport); if (tmp_port < 0 || tmp_port > USHRT_MAX) { - zend_argument_value_error(2, "remote port must be between 0 and %u", USHRT_MAX); + zend_argument_value_error(hostname_arg_num, "remote port must be between 0 and %u", USHRT_MAX); return false; } remote_port = (unsigned short)tmp_port; @@ -1006,7 +994,7 @@ static bool snmp_session_set_sec_level(struct snmp_session *s, zend_string *leve /* }}} */ /* {{{ Set the authentication protocol in the snmpv3 session */ -static bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string *prot) +static ZEND_ATTRIBUTE_NONNULL bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string *prot) { #ifndef DISABLE_MD5 if (zend_string_equals_literal_ci(prot, "MD5")) { @@ -1038,27 +1026,24 @@ static bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string * } #endif - smart_string err = {0}; - - smart_string_appends(&err, "Authentication protocol must be \"SHA\""); + zend_value_error( + "Authentication protocol must be \"SHA\"" #ifdef HAVE_SNMP_SHA256 - smart_string_appends(&err, " or \"SHA256\""); + " or \"SHA256\"" #endif #ifdef HAVE_SNMP_SHA512 - smart_string_appends(&err, " or \"SHA512\""); + " or \"SHA512\"" #endif #ifndef DISABLE_MD5 - smart_string_appends(&err, " or \"MD5\""); + " or \"MD5\"" #endif - smart_string_0(&err); - zend_value_error("%s", err.c); - smart_string_free(&err); + ); return false; } /* }}} */ /* {{{ Set the security protocol in the snmpv3 session */ -static bool snmp_session_set_sec_protocol(struct snmp_session *s, zend_string *prot) +static ZEND_ATTRIBUTE_NONNULL bool snmp_session_set_sec_protocol(struct snmp_session *s, zend_string *prot) { #ifndef NETSNMP_DISABLE_DES if (zend_string_equals_literal_ci(prot, "DES")) { @@ -1095,9 +1080,10 @@ static bool snmp_session_set_sec_protocol(struct snmp_session *s, zend_string *p /* }}} */ /* {{{ Make key from pass phrase in the snmpv3 session */ -static bool snmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass) +static ZEND_ATTRIBUTE_NONNULL bool snmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass) { int snmp_errno; + s->securityAuthKeyLen = USM_AUTH_KU_LEN; if ((snmp_errno = generate_Ku(s->securityAuthProto, s->securityAuthProtoLen, (uint8_t *) ZSTR_VAL(pass), ZSTR_LEN(pass), @@ -1110,7 +1096,7 @@ static bool snmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass) /* }}} */ /* {{{ Make key from pass phrase in the snmpv3 session */ -static bool snmp_session_gen_sec_key(struct snmp_session *s, zend_string *pass) +static ZEND_ATTRIBUTE_NONNULL bool snmp_session_gen_sec_key(struct snmp_session *s, zend_string *pass) { int snmp_errno; @@ -1126,14 +1112,13 @@ static bool snmp_session_gen_sec_key(struct snmp_session *s, zend_string *pass) /* }}} */ /* {{{ Set context Engine Id in the snmpv3 session */ -static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string * contextEngineID) +static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string *contextEngineID, uint32_t context_engine_id_arg_num) { size_t ebuf_len = 32, eout_len = 0; uint8_t *ebuf = (uint8_t *) emalloc(ebuf_len); if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, ZSTR_VAL(contextEngineID))) { - // TODO Promote to Error? - php_error_docref(NULL, E_WARNING, "Bad engine ID value '%s'", ZSTR_VAL(contextEngineID)); + zend_argument_value_error(context_engine_id_arg_num, "must be a valid context engine ID"); efree(ebuf); return false; } @@ -1148,10 +1133,14 @@ static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string } /* }}} */ -/* {{{ Set all snmpv3-related security options */ -static bool snmp_session_set_security(struct snmp_session *session, zend_string *sec_level, +/* {{{ Set all snmpv3-related security options + * auth_protocol_arg_num and context_engine_id_arg_num are the userland + * argument numbers used for error reporting. + */ +static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp_session *session, zend_string *sec_level, zend_string *auth_protocol, zend_string *auth_passphrase, zend_string *priv_protocol, - zend_string *priv_passphrase, zend_string *contextName, zend_string *contextEngineID) + zend_string *priv_passphrase, zend_string *contextName, zend_string *contextEngineID, + uint32_t auth_protocol_arg_num, uint32_t context_engine_id_arg_num) { /* Setting the security level. */ @@ -1162,12 +1151,22 @@ static bool snmp_session_set_security(struct snmp_session *session, zend_string if (session->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { + if (!auth_protocol) { + zend_argument_value_error(auth_protocol_arg_num, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); + return false; + } + /* Setting the authentication protocol. */ if (!snmp_session_set_auth_protocol(session, auth_protocol)) { /* ValueError already generated, just bail out */ return false; } + if (!auth_passphrase) { + zend_argument_value_error(auth_protocol_arg_num + 1, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); + return false; + } + /* Setting the authentication passphrase. */ if (!snmp_session_gen_auth_key(session, auth_passphrase)) { /* Warning message sent already, just bail out */ @@ -1175,12 +1174,23 @@ static bool snmp_session_set_security(struct snmp_session *session, zend_string } if (session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { + + if (!priv_protocol) { + zend_argument_value_error(auth_protocol_arg_num + 2, "cannot be null when security level is \"authPriv\""); + return false; + } + /* Setting the security protocol. */ if (!snmp_session_set_sec_protocol(session, priv_protocol)) { /* ValueError already generated, just bail out */ return false; } + if (!priv_passphrase) { + zend_argument_value_error(auth_protocol_arg_num + 3, "cannot be null when security level is \"authPriv\""); + return false; + } + /* Setting the security protocol passphrase. */ if (!snmp_session_gen_sec_key(session, priv_passphrase)) { /* Warning message sent already, just bail out */ @@ -1196,7 +1206,7 @@ static bool snmp_session_set_security(struct snmp_session *session, zend_string } /* Setting contextEngineIS if specified */ - if (contextEngineID && ZSTR_LEN(contextEngineID) && !snmp_session_set_contextEngineID(session, contextEngineID)) { + if (contextEngineID && ZSTR_LEN(contextEngineID) && !snmp_session_set_contextEngineID(session, contextEngineID, context_engine_id_arg_num)) { /* Warning message sent already, just bail out */ return false; } @@ -1216,14 +1226,17 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) { zend_string *oid_str, *type_str = NULL, *value_str = NULL; HashTable *oid_ht, *type_ht = NULL, *value_ht = NULL; - zend_string *a1 = NULL, *a2 = NULL, *a3 = NULL, *a4 = NULL, *a5 = NULL, *a6 = NULL, *a7 = NULL; + zend_string *hostname = NULL, *community_or_security_name = NULL; + zend_string *security_level = NULL, *auth_protocol = NULL, *auth_passphrase = NULL; + zend_string *privacy_protocol = NULL, *privacy_passphrase = NULL; bool use_orignames = 0, suffix_keys = 0; zend_long timeout = SNMP_DEFAULT_TIMEOUT; zend_long retries = SNMP_DEFAULT_RETRIES; struct objid_query objid_query; php_snmp_session *session; int session_less_mode = (getThis() == NULL); - int timeout_argument_offset = -1; + uint32_t timeout_arg_num = 0; + uint32_t oid_arg_num = 1, type_arg_num = 0, value_arg_num = 0; php_snmp_object *snmp_object; php_snmp_object glob_snmp_object; @@ -1236,13 +1249,13 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) if (version == SNMP_VERSION_3) { if (st & SNMP_CMD_SET) { ZEND_PARSE_PARAMETERS_START(10, 12) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) - Z_PARAM_STR(a3) - Z_PARAM_STR(a4) - Z_PARAM_STR(a5) - Z_PARAM_STR(a6) - Z_PARAM_STR(a7) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) + Z_PARAM_STR(security_level) + Z_PARAM_STR(auth_protocol) + Z_PARAM_STR(auth_passphrase) + Z_PARAM_STR(privacy_protocol) + Z_PARAM_STR(privacy_passphrase) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) @@ -1251,33 +1264,37 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 10; + timeout_arg_num = 10; + oid_arg_num = 8; + type_arg_num = 9; + value_arg_num = 10; } else { /* SNMP_CMD_GET * SNMP_CMD_GETNEXT * SNMP_CMD_WALK */ ZEND_PARSE_PARAMETERS_START(8, 10) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) - Z_PARAM_STR(a3) - Z_PARAM_STR(a4) - Z_PARAM_STR(a5) - Z_PARAM_STR(a6) - Z_PARAM_STR(a7) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) + Z_PARAM_STR(security_level) + Z_PARAM_STR(auth_protocol) + Z_PARAM_STR(auth_passphrase) + Z_PARAM_STR(privacy_protocol) + Z_PARAM_STR(privacy_passphrase) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 9; + timeout_arg_num = 9; + oid_arg_num = 8; } } else { if (st & SNMP_CMD_SET) { ZEND_PARSE_PARAMETERS_START(5, 7) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) @@ -1286,22 +1303,26 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 6; + timeout_arg_num = 6; + oid_arg_num = 3; + type_arg_num = 4; + value_arg_num = 5; } else { /* SNMP_CMD_GET * SNMP_CMD_GETNEXT * SNMP_CMD_WALK */ ZEND_PARSE_PARAMETERS_START(3, 5) - Z_PARAM_STR(a1) - Z_PARAM_STR(a2) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 4; + timeout_arg_num = 4; + oid_arg_num = 3; } } } else { @@ -1311,6 +1332,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) ZEND_PARSE_PARAMETERS_END(); + type_arg_num = 2; + value_arg_num = 3; } else if (st & SNMP_CMD_WALK) { ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) @@ -1340,20 +1363,21 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) } } - if (!php_snmp_parse_oid(getThis(), st, &objid_query, oid_str, oid_ht, type_str, type_ht, value_str, value_ht)) { + if (!php_snmp_parse_oid(getThis(), st, &objid_query, oid_str, oid_ht, type_str, type_ht, value_str, value_ht, + oid_arg_num, type_arg_num, value_arg_num)) { RETURN_FALSE; } if (session_less_mode) { - if (!snmp_session_init(&session, version, a1, a2, timeout, retries, timeout_argument_offset)) { + if (!snmp_session_init(&session, version, hostname, community_or_security_name, timeout, retries, 1, timeout_arg_num)) { php_free_objid_query(&objid_query, oid_ht, value_ht, st); snmp_session_free(&session); RETURN_FALSE; } - if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL)) { + if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, security_level, auth_protocol, auth_passphrase, privacy_protocol, privacy_passphrase, NULL, NULL, 4, 0)) { php_free_objid_query(&objid_query, oid_ht, value_ht, st); snmp_session_free(&session); - /* Warning message sent already, just bail out */ + /* An error has already been emitted, just bail out. */ RETURN_FALSE; } } else { @@ -1438,9 +1462,7 @@ PHP_FUNCTION(snmpset) /* {{{ Return the current status of quick_print */ PHP_FUNCTION(snmp_get_quick_print) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT)); } @@ -1591,9 +1613,7 @@ PHP_FUNCTION(snmp_set_valueretrieval) /* {{{ Return the method how the SNMP values will be returned */ PHP_FUNCTION(snmp_get_valueretrieval) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(SNMP_G(valueretrieval)); } @@ -1630,7 +1650,7 @@ PHP_METHOD(SNMP, __construct) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lSS|ll", &version, &a1, &a2, &timeout, &retries) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lPP|ll", &version, &a1, &a2, &timeout, &retries) == FAILURE) { RETURN_THROWS(); } @@ -1649,7 +1669,7 @@ PHP_METHOD(SNMP, __construct) snmp_session_free(&(snmp_object->session)); } - if (!snmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries, 4)) { + if (!snmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries, 2, 4)) { return; } snmp_object->max_oids = 0; @@ -1670,9 +1690,7 @@ PHP_METHOD(SNMP, close) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); snmp_session_free(&(snmp_object->session)); @@ -1713,7 +1731,11 @@ PHP_METHOD(SNMP, setSecurity) { php_snmp_object *snmp_object; zval *object = ZEND_THIS; - zend_string *a1 = NULL, *a2 = NULL, *a3 = NULL, *a4 = NULL, *a5 = NULL, *a6 = NULL, *a7 = NULL; + zend_string *security_level = NULL, *auth_protocol = NULL, *auth_passphrase = NULL; + zend_string *privacy_protocol = NULL, *privacy_passphrase = NULL; + zend_string *context_name = NULL, *context_engine_id = NULL; + uint32_t auth_protocol_arg_num = 2; + uint32_t context_engine_id_arg_num = 7; snmp_object = Z_SNMP_P(object); if (!snmp_object->session) { @@ -1721,12 +1743,12 @@ PHP_METHOD(SNMP, setSecurity) RETURN_THROWS(); } - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SSSSSS", &a1, &a2, &a3, &a4,&a5, &a6, &a7) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SSSSSS", &security_level, &auth_protocol, &auth_passphrase, &privacy_protocol, &privacy_passphrase, &context_name, &context_engine_id) == FAILURE) { RETURN_THROWS(); } - if (!snmp_session_set_security(snmp_object->session, a1, a2, a3, a4, a5, a6, a7)) { - /* Warning message sent already, just bail out */ + if (!snmp_session_set_security(snmp_object->session, security_level, auth_protocol, auth_passphrase, privacy_protocol, privacy_passphrase, context_name, context_engine_id, auth_protocol_arg_num, context_engine_id_arg_num)) { + /* An error has already been emitted, just bail out. */ RETURN_FALSE; } RETURN_TRUE; @@ -1741,9 +1763,7 @@ PHP_METHOD(SNMP, getErrno) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(snmp_object->snmp_errno); } @@ -1757,9 +1777,7 @@ PHP_METHOD(SNMP, getError) snmp_object = Z_SNMP_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_STRING(snmp_object->snmp_errstr); } @@ -2126,7 +2144,7 @@ PHP_MINIT_FUNCTION(snmp) php_snmp_ce = register_class_SNMP(); php_snmp_ce->create_object = php_snmp_object_new; php_snmp_ce->default_object_handlers = &php_snmp_object_handlers; - php_snmp_object_handlers.offset = XtOffsetOf(php_snmp_object, zo); + php_snmp_object_handlers.offset = offsetof(php_snmp_object, zo); php_snmp_object_handlers.clone_obj = NULL; php_snmp_object_handlers.free_obj = php_snmp_object_free_storage; diff --git a/ext/snmp/snmp_arginfo.h b/ext/snmp/snmp_arginfo.h index 18ed9c735663..1ee821f0538d 100644 --- a/ext/snmp/snmp_arginfo.h +++ b/ext/snmp/snmp_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit snmp.stub.php instead. * Stub hash: e2451ac3ea0fa5eb1158e8b7252e61c6794d514f */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_snmpget, 0, 3, IS_MIXED, 0) @@ -270,123 +270,123 @@ static zend_class_entry *register_class_SNMP(void) zval const_VERSION_1_value; ZVAL_LONG(&const_VERSION_1_value, SNMP_VERSION_1); - zend_string *const_VERSION_1_name = zend_string_init_interned("VERSION_1", sizeof("VERSION_1") - 1, 1); + zend_string *const_VERSION_1_name = zend_string_init_interned("VERSION_1", sizeof("VERSION_1") - 1, true); zend_declare_typed_class_constant(class_entry, const_VERSION_1_name, &const_VERSION_1_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_VERSION_1_name); + zend_string_release_ex(const_VERSION_1_name, true); zval const_VERSION_2c_value; ZVAL_LONG(&const_VERSION_2c_value, SNMP_VERSION_2c); - zend_string *const_VERSION_2c_name = zend_string_init_interned("VERSION_2c", sizeof("VERSION_2c") - 1, 1); + zend_string *const_VERSION_2c_name = zend_string_init_interned("VERSION_2c", sizeof("VERSION_2c") - 1, true); zend_declare_typed_class_constant(class_entry, const_VERSION_2c_name, &const_VERSION_2c_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_VERSION_2c_name); + zend_string_release_ex(const_VERSION_2c_name, true); zval const_VERSION_2C_value; ZVAL_LONG(&const_VERSION_2C_value, SNMP_VERSION_2c); - zend_string *const_VERSION_2C_name = zend_string_init_interned("VERSION_2C", sizeof("VERSION_2C") - 1, 1); + zend_string *const_VERSION_2C_name = zend_string_init_interned("VERSION_2C", sizeof("VERSION_2C") - 1, true); zend_declare_typed_class_constant(class_entry, const_VERSION_2C_name, &const_VERSION_2C_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_VERSION_2C_name); + zend_string_release_ex(const_VERSION_2C_name, true); zval const_VERSION_3_value; ZVAL_LONG(&const_VERSION_3_value, SNMP_VERSION_3); - zend_string *const_VERSION_3_name = zend_string_init_interned("VERSION_3", sizeof("VERSION_3") - 1, 1); + zend_string *const_VERSION_3_name = zend_string_init_interned("VERSION_3", sizeof("VERSION_3") - 1, true); zend_declare_typed_class_constant(class_entry, const_VERSION_3_name, &const_VERSION_3_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_VERSION_3_name); + zend_string_release_ex(const_VERSION_3_name, true); zval const_ERRNO_NOERROR_value; ZVAL_LONG(&const_ERRNO_NOERROR_value, PHP_SNMP_ERRNO_NOERROR); - zend_string *const_ERRNO_NOERROR_name = zend_string_init_interned("ERRNO_NOERROR", sizeof("ERRNO_NOERROR") - 1, 1); + zend_string *const_ERRNO_NOERROR_name = zend_string_init_interned("ERRNO_NOERROR", sizeof("ERRNO_NOERROR") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_NOERROR_name, &const_ERRNO_NOERROR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_NOERROR_name); + zend_string_release_ex(const_ERRNO_NOERROR_name, true); zval const_ERRNO_ANY_value; ZVAL_LONG(&const_ERRNO_ANY_value, PHP_SNMP_ERRNO_ANY); - zend_string *const_ERRNO_ANY_name = zend_string_init_interned("ERRNO_ANY", sizeof("ERRNO_ANY") - 1, 1); + zend_string *const_ERRNO_ANY_name = zend_string_init_interned("ERRNO_ANY", sizeof("ERRNO_ANY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_ANY_name, &const_ERRNO_ANY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_ANY_name); + zend_string_release_ex(const_ERRNO_ANY_name, true); zval const_ERRNO_GENERIC_value; ZVAL_LONG(&const_ERRNO_GENERIC_value, PHP_SNMP_ERRNO_GENERIC); - zend_string *const_ERRNO_GENERIC_name = zend_string_init_interned("ERRNO_GENERIC", sizeof("ERRNO_GENERIC") - 1, 1); + zend_string *const_ERRNO_GENERIC_name = zend_string_init_interned("ERRNO_GENERIC", sizeof("ERRNO_GENERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_GENERIC_name, &const_ERRNO_GENERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_GENERIC_name); + zend_string_release_ex(const_ERRNO_GENERIC_name, true); zval const_ERRNO_TIMEOUT_value; ZVAL_LONG(&const_ERRNO_TIMEOUT_value, PHP_SNMP_ERRNO_TIMEOUT); - zend_string *const_ERRNO_TIMEOUT_name = zend_string_init_interned("ERRNO_TIMEOUT", sizeof("ERRNO_TIMEOUT") - 1, 1); + zend_string *const_ERRNO_TIMEOUT_name = zend_string_init_interned("ERRNO_TIMEOUT", sizeof("ERRNO_TIMEOUT") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_TIMEOUT_name, &const_ERRNO_TIMEOUT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_TIMEOUT_name); + zend_string_release_ex(const_ERRNO_TIMEOUT_name, true); zval const_ERRNO_ERROR_IN_REPLY_value; ZVAL_LONG(&const_ERRNO_ERROR_IN_REPLY_value, PHP_SNMP_ERRNO_ERROR_IN_REPLY); - zend_string *const_ERRNO_ERROR_IN_REPLY_name = zend_string_init_interned("ERRNO_ERROR_IN_REPLY", sizeof("ERRNO_ERROR_IN_REPLY") - 1, 1); + zend_string *const_ERRNO_ERROR_IN_REPLY_name = zend_string_init_interned("ERRNO_ERROR_IN_REPLY", sizeof("ERRNO_ERROR_IN_REPLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_ERROR_IN_REPLY_name, &const_ERRNO_ERROR_IN_REPLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_ERROR_IN_REPLY_name); + zend_string_release_ex(const_ERRNO_ERROR_IN_REPLY_name, true); zval const_ERRNO_OID_NOT_INCREASING_value; ZVAL_LONG(&const_ERRNO_OID_NOT_INCREASING_value, PHP_SNMP_ERRNO_OID_NOT_INCREASING); - zend_string *const_ERRNO_OID_NOT_INCREASING_name = zend_string_init_interned("ERRNO_OID_NOT_INCREASING", sizeof("ERRNO_OID_NOT_INCREASING") - 1, 1); + zend_string *const_ERRNO_OID_NOT_INCREASING_name = zend_string_init_interned("ERRNO_OID_NOT_INCREASING", sizeof("ERRNO_OID_NOT_INCREASING") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_OID_NOT_INCREASING_name, &const_ERRNO_OID_NOT_INCREASING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_OID_NOT_INCREASING_name); + zend_string_release_ex(const_ERRNO_OID_NOT_INCREASING_name, true); zval const_ERRNO_OID_PARSING_ERROR_value; ZVAL_LONG(&const_ERRNO_OID_PARSING_ERROR_value, PHP_SNMP_ERRNO_OID_PARSING_ERROR); - zend_string *const_ERRNO_OID_PARSING_ERROR_name = zend_string_init_interned("ERRNO_OID_PARSING_ERROR", sizeof("ERRNO_OID_PARSING_ERROR") - 1, 1); + zend_string *const_ERRNO_OID_PARSING_ERROR_name = zend_string_init_interned("ERRNO_OID_PARSING_ERROR", sizeof("ERRNO_OID_PARSING_ERROR") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_OID_PARSING_ERROR_name, &const_ERRNO_OID_PARSING_ERROR_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_OID_PARSING_ERROR_name); + zend_string_release_ex(const_ERRNO_OID_PARSING_ERROR_name, true); zval const_ERRNO_MULTIPLE_SET_QUERIES_value; ZVAL_LONG(&const_ERRNO_MULTIPLE_SET_QUERIES_value, PHP_SNMP_ERRNO_MULTIPLE_SET_QUERIES); - zend_string *const_ERRNO_MULTIPLE_SET_QUERIES_name = zend_string_init_interned("ERRNO_MULTIPLE_SET_QUERIES", sizeof("ERRNO_MULTIPLE_SET_QUERIES") - 1, 1); + zend_string *const_ERRNO_MULTIPLE_SET_QUERIES_name = zend_string_init_interned("ERRNO_MULTIPLE_SET_QUERIES", sizeof("ERRNO_MULTIPLE_SET_QUERIES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ERRNO_MULTIPLE_SET_QUERIES_name, &const_ERRNO_MULTIPLE_SET_QUERIES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ERRNO_MULTIPLE_SET_QUERIES_name); + zend_string_release_ex(const_ERRNO_MULTIPLE_SET_QUERIES_name, true); zval property_info_default_value; ZVAL_UNDEF(&property_info_default_value); - zend_string *property_info_name = zend_string_init("info", sizeof("info") - 1, 1); + zend_string *property_info_name = zend_string_init("info", sizeof("info") - 1, true); zend_declare_typed_property(class_entry, property_info_name, &property_info_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release(property_info_name); + zend_string_release_ex(property_info_name, true); zval property_max_oids_default_value; ZVAL_UNDEF(&property_max_oids_default_value); - zend_string *property_max_oids_name = zend_string_init("max_oids", sizeof("max_oids") - 1, 1); + zend_string *property_max_oids_name = zend_string_init("max_oids", sizeof("max_oids") - 1, true); zend_declare_typed_property(class_entry, property_max_oids_name, &property_max_oids_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property_max_oids_name); + zend_string_release_ex(property_max_oids_name, true); zval property_valueretrieval_default_value; ZVAL_UNDEF(&property_valueretrieval_default_value); - zend_string *property_valueretrieval_name = zend_string_init("valueretrieval", sizeof("valueretrieval") - 1, 1); + zend_string *property_valueretrieval_name = zend_string_init("valueretrieval", sizeof("valueretrieval") - 1, true); zend_declare_typed_property(class_entry, property_valueretrieval_name, &property_valueretrieval_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_valueretrieval_name); + zend_string_release_ex(property_valueretrieval_name, true); zval property_quick_print_default_value; ZVAL_UNDEF(&property_quick_print_default_value); - zend_string *property_quick_print_name = zend_string_init("quick_print", sizeof("quick_print") - 1, 1); + zend_string *property_quick_print_name = zend_string_init("quick_print", sizeof("quick_print") - 1, true); zend_declare_typed_property(class_entry, property_quick_print_name, &property_quick_print_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_quick_print_name); + zend_string_release_ex(property_quick_print_name, true); zval property_enum_print_default_value; ZVAL_UNDEF(&property_enum_print_default_value); - zend_string *property_enum_print_name = zend_string_init("enum_print", sizeof("enum_print") - 1, 1); + zend_string *property_enum_print_name = zend_string_init("enum_print", sizeof("enum_print") - 1, true); zend_declare_typed_property(class_entry, property_enum_print_name, &property_enum_print_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_enum_print_name); + zend_string_release_ex(property_enum_print_name, true); zval property_oid_output_format_default_value; ZVAL_UNDEF(&property_oid_output_format_default_value); - zend_string *property_oid_output_format_name = zend_string_init("oid_output_format", sizeof("oid_output_format") - 1, 1); + zend_string *property_oid_output_format_name = zend_string_init("oid_output_format", sizeof("oid_output_format") - 1, true); zend_declare_typed_property(class_entry, property_oid_output_format_name, &property_oid_output_format_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_oid_output_format_name); + zend_string_release_ex(property_oid_output_format_name, true); zval property_oid_increasing_check_default_value; ZVAL_UNDEF(&property_oid_increasing_check_default_value); - zend_string *property_oid_increasing_check_name = zend_string_init("oid_increasing_check", sizeof("oid_increasing_check") - 1, 1); + zend_string *property_oid_increasing_check_name = zend_string_init("oid_increasing_check", sizeof("oid_increasing_check") - 1, true); zend_declare_typed_property(class_entry, property_oid_increasing_check_name, &property_oid_increasing_check_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_oid_increasing_check_name); + zend_string_release_ex(property_oid_increasing_check_name, true); zval property_exceptions_enabled_default_value; ZVAL_UNDEF(&property_exceptions_enabled_default_value); - zend_string *property_exceptions_enabled_name = zend_string_init("exceptions_enabled", sizeof("exceptions_enabled") - 1, 1); + zend_string *property_exceptions_enabled_name = zend_string_init("exceptions_enabled", sizeof("exceptions_enabled") - 1, true); zend_declare_typed_property(class_entry, property_exceptions_enabled_name, &property_exceptions_enabled_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_exceptions_enabled_name); + zend_string_release_ex(property_exceptions_enabled_name, true); return class_entry; } diff --git a/ext/snmp/tests/gh16959.phpt b/ext/snmp/tests/gh16959.phpt index cabe0eb84b6c..f76fa61e1f73 100644 --- a/ext/snmp/tests/gh16959.phpt +++ b/ext/snmp/tests/gh16959.phpt @@ -66,5 +66,5 @@ array(4) { } Object of class stdClass could not be converted to string Object of class stdClass could not be converted to string -Type must be a single character -Type must be a single character +snmp2_set(): Argument #4 ($type) must be a single character +snmp2_set(): Argument #4 ($type) must be a single character diff --git a/ext/snmp/tests/gh21336.phpt b/ext/snmp/tests/gh21336.phpt new file mode 100644 index 000000000000..a4070136e550 --- /dev/null +++ b/ext/snmp/tests/gh21336.phpt @@ -0,0 +1,41 @@ +--TEST-- +GH-21336 (undefined behavior in snmp - NULL pointer dereference in setSecurity) +--EXTENSIONS-- +snmp +--FILE-- +setSecurity('authPriv'); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +// auth passphrase NULL +try { + $session->setSecurity('authNoPriv', 'MD5'); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +// priv protocol NULL +try { + $session->setSecurity('authPriv', 'MD5', 'test12345'); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +// priv passphrase NULL +try { + $session->setSecurity('authPriv', 'MD5', 'test12345', 'AES'); +} catch (ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} +?> +--EXPECT-- +SNMP::setSecurity(): Argument #2 ($authProtocol) cannot be null when security level is "authNoPriv" or "authPriv" +SNMP::setSecurity(): Argument #3 ($authPassphrase) cannot be null when security level is "authNoPriv" or "authPriv" +SNMP::setSecurity(): Argument #4 ($privacyProtocol) cannot be null when security level is "authPriv" +SNMP::setSecurity(): Argument #5 ($privacyPassphrase) cannot be null when security level is "authPriv" diff --git a/ext/snmp/tests/ipv6.phpt b/ext/snmp/tests/ipv6.phpt index c305fb15d4b8..93274fd7054f 100644 --- a/ext/snmp/tests/ipv6.phpt +++ b/ext/snmp/tests/ipv6.phpt @@ -22,10 +22,12 @@ snmp_set_quick_print(false); snmp_set_valueretrieval(SNMP_VALUE_PLAIN); var_dump(snmpget($hostname6_port, $community, '.1.3.6.1.2.1.1.1.0')); -var_dump(snmpget('[dead:beef::', $community, '.1.3.6.1.2.1.1.1.0')); +try { + var_dump(snmpget('[dead:beef::', $community, '.1.3.6.1.2.1.1.1.0')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> --EXPECTF-- string(%d) "%s" - -Warning: snmpget(): Malformed IPv6 address, closing square bracket missing in %s on line %d -bool(false) +snmpget(): Argument #1 ($hostname) has a malformed IPv6 address, closing square bracket missing diff --git a/ext/snmp/tests/snmp-object-setSecurity_error.phpt b/ext/snmp/tests/snmp-object-setSecurity_error.phpt index cf4f92883777..576ec8380804 100644 --- a/ext/snmp/tests/snmp-object-setSecurity_error.phpt +++ b/ext/snmp/tests/snmp-object-setSecurity_error.phpt @@ -53,7 +53,11 @@ try { var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', '')); var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'ty')); -var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'test12345', 'context', 'dsa')); +try { + var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'test12345', 'context', 'dsa')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump($session->close()); @@ -76,7 +80,5 @@ bool(false) Warning: SNMP::setSecurity(): Error generating a key for privacy pass phrase 'ty': Generic error (The supplied password length is too short.) in %s on line %d bool(false) - -Warning: SNMP::setSecurity(): Bad engine ID value 'dsa' in %s on line %d -bool(false) +SNMP::setSecurity(): Argument #7 ($contextEngineId) must be a valid context engine ID bool(true) diff --git a/ext/snmp/tests/snmp2_get.phpt b/ext/snmp/tests/snmp2_get.phpt index 30500eb5ca9b..e2cd1ef1b459 100644 --- a/ext/snmp/tests/snmp2_get.phpt +++ b/ext/snmp/tests/snmp2_get.phpt @@ -54,7 +54,7 @@ var_dump(snmp2_get($hostname, $community, array('.1.3.6.1.2.1.1.1.0', '.1.3.6.1. --EXPECTF-- Checking error handling Empty OID array -Array of object IDs must not be empty +snmp2_get(): Argument #3 ($object_id) must not be empty when passed as an array Checking working Single OID string(%d) "%s" diff --git a/ext/snmp/tests/snmp2_set.phpt b/ext/snmp/tests/snmp2_set.phpt index 11b1d94419f5..da94fe21f498 100644 --- a/ext/snmp/tests/snmp2_set.phpt +++ b/ext/snmp/tests/snmp2_set.phpt @@ -128,14 +128,22 @@ var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $ol var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID, single type in array, multiple value\n"; -$z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s'), array($newvalue1, $newvalue2), $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s'), array($newvalue1, $newvalue2), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID & type, single value in array\n"; -$z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); @@ -167,7 +175,7 @@ var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $ol --EXPECTF-- Check error handing No type & no value (timeout & retries instead) -Type must be a single character +snmp2_set(): Argument #4 ($type) must be a single character No value (timeout instead), retries instead of timeout Warning: snmp2_set(): Could not add variable: OID='%s' type='q' value='%i': Bad variable type ("q") in %s on line %d @@ -216,23 +224,19 @@ Value must be of type string when object ID is a string bool(true) bool(true) Multiple OID, 1st wrong type -Type must be a single character +snmp2_set(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, 2nd wrong type -Type must be a single character +snmp2_set(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, single type in array, multiple value - -Warning: snmp2_set(): '%s': no type set in %s on line %d -bool(false) +snmp2_set(): Argument #4 ($type) must contain a type for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID & type, single value in array - -Warning: snmp2_set(): '%s': no value set in %s on line %d -bool(false) +snmp2_set(): Argument #5 ($value) must contain a value for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID, 1st bogus, single type, multiple value diff --git a/ext/snmp/tests/snmpset.phpt b/ext/snmp/tests/snmpset.phpt index ca935cecf5ec..a4f89e78da93 100644 --- a/ext/snmp/tests/snmpset.phpt +++ b/ext/snmp/tests/snmpset.phpt @@ -122,14 +122,22 @@ var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $ol var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID, single type in array, multiple value\n"; -$z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s'), array($newvalue1, $newvalue2), $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s'), array($newvalue1, $newvalue2), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID & type, single value in array\n"; -$z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s', 's'), array($newvalue1), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); @@ -161,7 +169,7 @@ var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $ol --EXPECTF-- Check error handing No type & no value (timeout & retries instead) -Type must be a single character +snmpset(): Argument #4 ($type) must be a single character No value (timeout instead), retries instead of timeout Warning: snmpset(): Could not add variable: OID='%s' type='q' value='%i': Bad variable type ("q") in %s on line %d @@ -207,23 +215,19 @@ Value must be of type string when object ID is a string bool(true) bool(true) Multiple OID, 1st wrong type -Type must be a single character +snmpset(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, 2nd wrong type -Type must be a single character +snmpset(): Argument #4 ($type) must be a single character bool(true) bool(true) Multiple OID, single type in array, multiple value - -Warning: snmpset(): '%s': no type set in %s on line %d -bool(false) +snmpset(): Argument #4 ($type) must contain a type for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID & type, single value in array - -Warning: snmpset(): '%s': no value set in %s on line %d -bool(false) +snmpset(): Argument #5 ($value) must contain a value for object ID 'SNMPv2-MIB::sysLocation.0' bool(true) bool(true) Multiple OID, 1st bogus, single type, multiple value diff --git a/ext/soap/config.w32 b/ext/soap/config.w32 index 583f6a2b2e0d..7cecb8e8afed 100644 --- a/ext/soap/config.w32 +++ b/ext/soap/config.w32 @@ -5,8 +5,8 @@ ARG_ENABLE("soap", "SOAP support", "no"); if (PHP_SOAP != "no") { if (PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('soap', 'libxml') && - CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") && - CHECK_HEADER_ADD_INCLUDE("libxml/tree.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") + CHECK_HEADER("libxml/parser.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") && + CHECK_HEADER("libxml/tree.h", "CFLAGS_SOAP", PHP_PHP_BUILD + "\\include\\libxml2") ) { EXTENSION('soap', 'soap.c php_encoding.c php_http.c php_packet_soap.c php_schema.c php_sdl.c php_xml.c', null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE('HAVE_SOAP', 1, "Define to 1 if the PHP extension 'soap' is available."); diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 8423f50fd4b8..151fa811b0fa 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -16,6 +14,7 @@ +----------------------------------------------------------------------+ */ +#include #include #include "php_soap.h" @@ -278,13 +277,13 @@ static bool soap_check_zval_ref(zval *data, xmlNodePtr node) { if (Z_TYPE_P(data) == IS_OBJECT) { data = (zval*)Z_OBJ_P(data); } - if ((node_ptr = zend_hash_index_find_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)data)) != NULL) { + if ((node_ptr = zend_hash_index_find_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)data)) != NULL) { xmlAttrPtr attr = node_ptr->properties; char *id; smart_str prefix = {0}; if (node_ptr == node) { - return 0; + return false; } if (SOAP_GLOBAL(soap_version) == SOAP_1_1) { attr = get_attribute(attr, "id"); @@ -322,12 +321,12 @@ static bool soap_check_zval_ref(zval *data, xmlNodePtr node) { set_ns_prop(node, SOAP_1_2_ENC_NAMESPACE, "ref", id); } smart_str_free(&prefix); - return 1; + return true; } else { - zend_hash_index_update_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)data, node); + zend_hash_index_update_ptr(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)data, node); } } - return 0; + return false; } static bool soap_check_xml_ref(zval *data, xmlNodePtr node) @@ -335,23 +334,24 @@ static bool soap_check_xml_ref(zval *data, xmlNodePtr node) zval *data_ptr; if (SOAP_GLOBAL(ref_map)) { - if ((data_ptr = zend_hash_index_find(SOAP_GLOBAL(ref_map), (zend_ulong)node)) != NULL) { + if ((data_ptr = zend_hash_index_find(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)node)) != NULL) { if (!Z_REFCOUNTED_P(data) || !Z_REFCOUNTED_P(data_ptr) || Z_COUNTED_P(data) != Z_COUNTED_P(data_ptr)) { zval_ptr_dtor(data); ZVAL_COPY(data, data_ptr); - return 1; + return true; } } } - return 0; + return false; } static void soap_add_xml_ref(zval *data, xmlNodePtr node) { if (SOAP_GLOBAL(ref_map)) { - zend_hash_index_update(SOAP_GLOBAL(ref_map), (zend_ulong)node, data); + Z_TRY_ADDREF_P(data); + zend_hash_index_update(SOAP_GLOBAL(ref_map), (zend_ulong)(uintptr_t)node, data); } } @@ -598,7 +598,7 @@ xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr par zval_ptr_dtor(&return_value); } if (!ret) { - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); } xmlAddChild(parent, ret); if (style == SOAP_ENCODED) { @@ -855,7 +855,7 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo { xmlNodePtr ret, text; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -937,7 +937,7 @@ static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNo { xmlNodePtr ret, text; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -963,7 +963,7 @@ static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNo zval tmp; size_t i, j; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1066,7 +1066,7 @@ static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNode { xmlNodePtr ret; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1093,7 +1093,7 @@ static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNo zval tmp; char *str; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1141,7 +1141,7 @@ static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNode { xmlNodePtr ret; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); @@ -1168,7 +1168,7 @@ static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNode { xmlNodePtr ret; - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); if (style == SOAP_ENCODED) { set_xsi_nil(ret); @@ -1306,12 +1306,12 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr } master_to_zval(&val, model->u.element->encode, r_node); } else if (model->u.element->fixed) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); } else if (model->u.element->def && !model->u.element->nillable) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); @@ -1331,12 +1331,12 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr } master_to_zval(&val, model->u.element->encode, node); } else if (model->u.element->fixed) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); } else if (model->u.element->def && !model->u.element->nillable) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlNodePtr dummy = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def)); master_to_zval(&val, model->u.element->encode, dummy); xmlFreeNode(dummy); @@ -1541,7 +1541,7 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z xmlNodePtr dummy, text; zval data; - dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); + dummy = xmlNewDocNode(NULL, NULL, BAD_CAST("BOGUS"), NULL); text = xmlNewText(BAD_CAST(str_val)); xmlAddChild(dummy, text); ZVAL_NULL(&data); @@ -1646,7 +1646,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval * ZEND_HASH_FOREACH_VAL(ht, val) { ZVAL_DEREF(val); if (Z_TYPE_P(val) == IS_NULL && model->u.element->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); + property = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(node, property); set_xsi_nil(property); } else { @@ -1666,7 +1666,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval * } ZEND_HASH_FOREACH_END(); } else { if (Z_TYPE_P(data) == IS_NULL && model->u.element->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); + property = xmlNewDocNode(node->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(node, property); set_xsi_nil(property); } else if (Z_TYPE_P(data) == IS_NULL && model->min_occurs == 0) { @@ -1688,7 +1688,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval * } return 1; } else if (strict && model->u.element->nillable && model->min_occurs > 0) { - property = xmlNewNode(NULL, BAD_CAST(model->u.element->name)); + property = xmlNewDocNode(node->doc, NULL, BAD_CAST(model->u.element->name), NULL); xmlAddChild(node, property); set_xsi_nil(property); if (style == SOAP_LITERAL && @@ -1797,9 +1797,9 @@ static sdlTypePtr model_array_element(sdlContentModelPtr model) ZEND_HASH_FOREACH_PTR(model->u.content, tmp) { return model_array_element(tmp); } ZEND_HASH_FOREACH_END(); + + break; } - /* TODO Check this is correct */ - ZEND_FALLTHROUGH; case XSD_CONTENT_GROUP: { return model_array_element(model->u.group->model); } @@ -1816,7 +1816,7 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo sdlTypePtr sdlType = type->sdl_type; if (!data || Z_TYPE_P(data) == IS_NULL) { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); if (style == SOAP_ENCODED) { set_xsi_nil(xmlParam); @@ -1851,11 +1851,11 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo } else if (prop == NULL) { xmlParam = master_to_xml(enc, data, style, parent); } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION && @@ -1877,12 +1877,12 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo } else if (prop == NULL) { xmlParam = master_to_xml(sdlType->encode, data, style, parent); } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } } } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); } @@ -1903,7 +1903,7 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo xmlNodePtr property; ZVAL_DEREF(val); if (Z_TYPE_P(val) == IS_NULL && array_el->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); + property = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(xmlParam, property); set_xsi_nil(property); } else { @@ -1924,6 +1924,11 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo sdlAttributePtr attr; zval *zattr, rv; + /* Attributes can't refer to other attributes as there's nothing to attach the href to. */ + HashTable **ref_map = &SOAP_GLOBAL(ref_map); + HashTable *old_ref_map = *ref_map; + *ref_map = NULL; + ZEND_HASH_FOREACH_PTR(sdlType->attributes, attr) { if (attr->name) { zattr = get_zval_property(data, attr->name, &rv); @@ -1953,13 +1958,15 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo } } } ZEND_HASH_FOREACH_END(); + + *ref_map = old_ref_map; } } if (style == SOAP_ENCODED) { set_ns_and_type(xmlParam, type); } } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); if (soap_check_zval_ref(data, xmlParam)) { @@ -2042,6 +2049,15 @@ static int calc_dimension_12(const char* str) return i; } +static void soap_array_position_add_digit(int *position, int digit) +{ + if (*position > (INT_MAX - digit) / 10) { + soap_error0(E_ERROR, "Encoding: array index out of range"); + } + + *position = (*position * 10) + digit; +} + static int* get_position_12(int dimension, const char* str) { int *pos; @@ -2062,7 +2078,7 @@ static int* get_position_12(int dimension, const char* str) i++; flag = 1; } - pos[i] = (pos[i]*10)+(*str-'0'); + soap_array_position_add_digit(&pos[i], *str - '0'); } else if (*str == '*') { soap_error0(E_ERROR, "Encoding: '*' may only be first arraySize value in list"); } else { @@ -2092,7 +2108,7 @@ static void get_position_ex(int dimension, const char* str, int** pos) memset(*pos,0,sizeof(int)*dimension); while (*str != ']' && *str != '\0' && i < dimension) { if (*str >= '0' && *str <= '9') { - (*pos)[i] = ((*pos)[i]*10)+(*str-'0'); + soap_array_position_add_digit(&(*pos)[i], *str - '0'); } else if (*str == ',') { i++; } @@ -2159,7 +2175,7 @@ static void add_xml_array_elements(xmlNodePtr xmlParam, if (dimension == 1) { while (j < dims[0]) { - xparam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xparam = xmlNewDocNode(xmlParam->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(xmlParam, xparam); if (type) { @@ -2186,7 +2202,7 @@ static void add_xml_array_elements(xmlNodePtr xmlParam, if (dimension == 1) { xmlNodePtr xparam; - xparam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xparam = xmlNewDocNode(xmlParam->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(xmlParam, xparam); if (type) { xmlNodeSetName(xparam, BAD_CAST(type->name)); @@ -2219,7 +2235,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod ZVAL_UNDEF(&array_copy); soap_version = SOAP_GLOBAL(soap_version); - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); if (!data || Z_TYPE_P(data) == IS_NULL) { @@ -2432,13 +2448,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod if (style == SOAP_ENCODED) { if (soap_version == SOAP_1_1) { smart_str_0(&array_type); -#if defined(__GNUC__) && __GNUC__ >= 11 - ZEND_DIAGNOSTIC_IGNORED_START("-Wstringop-overread") -#endif - bool is_xsd_any_type = strcmp(ZSTR_VAL(array_type.s),"xsd:anyType") == 0; -#if defined(__GNUC__) && __GNUC__ >= 11 - ZEND_DIAGNOSTIC_IGNORED_END -#endif + bool is_xsd_any_type = zend_string_equals_literal(array_type.s, "xsd:anyType"); if (is_xsd_any_type) { smart_str_free(&array_type); smart_str_appendl(&array_type,"xsd:ur-type",sizeof("xsd:ur-type")-1); @@ -2522,19 +2532,20 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) xmlNsPtr nsptr; parse_namespace(attr->children->content, &type, &ns); + char *type_dup = estrdup(type); nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns)); - end = strrchr(type,'['); + end = strrchr(type_dup,'['); if (end) { *end = '\0'; dimension = calc_dimension(end+1); dims = get_position(dimension, end+1); } if (nsptr != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type); + enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type_dup); } if (ns) {efree(ns);} - + if (type_dup) efree(type_dup); } else if ((attr = get_soap_enc_attribute(data->properties,"itemType")) && attr->children && attr->children->content) { @@ -2684,16 +2695,20 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) /* Increment position */ i = dimension; while (i > 0) { - i--; - pos[i]++; - if (pos[i] >= dims[i]) { - if (i > 0) { - pos[i] = 0; - } else { - /* TODO: Array index overflow */ - } - } else { - break; + i--; + if (pos[i] == INT_MAX) { + efree(dims); + efree(pos); + zval_ptr_dtor(ret); + ZVAL_UNDEF(ret); + soap_error0(E_ERROR, "Encoding: array index out of range"); + } + pos[i]++; + if (pos[i] < dims[i]) { + break; + } + if (i > 0) { + pos[i] = 0; } } } @@ -2714,7 +2729,7 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP xmlNodePtr xparam, item; xmlNodePtr key; - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); FIND_ZVAL_NULL(data, xmlParam, style); @@ -2727,9 +2742,9 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP GC_TRY_PROTECT_RECURSION(Z_ARRVAL_P(data)); ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(data), int_val, key_val, temp_data) { - item = xmlNewNode(NULL, BAD_CAST("item")); + item = xmlNewDocNode(parent->doc, NULL, BAD_CAST("item"), NULL); xmlAddChild(xmlParam, item); - key = xmlNewNode(NULL, BAD_CAST("key")); + key = xmlNewDocNode(parent->doc, NULL, BAD_CAST("key"), NULL); xmlAddChild(item,key); if (key_val) { if (style == SOAP_ENCODED) { @@ -2783,7 +2798,7 @@ static zval *to_zval_map(zval *ret, encodeTypePtr type, xmlNodePtr data) } xmlValue = get_node(item->children, "value"); - if (!xmlKey) { + if (!xmlValue) { soap_error0(E_ERROR, "Encoding: Can't decode apache map, missing value"); } @@ -2920,7 +2935,7 @@ static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *forma xmlNodePtr xmlParam; - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); + xmlParam = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, xmlParam); FIND_ZVAL_NULL(data, xmlParam, style); @@ -2946,9 +2961,9 @@ static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *forma labs(ta->tm_gmtoff / 3600), labs( (ta->tm_gmtoff % 3600) / 60 )); #else # if defined(__CYGWIN__) || (defined(PHP_WIN32) && defined(_MSC_VER)) - snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", ((ta->tm_isdst ? _timezone - 3600:_timezone)>0)?'-':'+', abs((ta->tm_isdst ? _timezone - 3600 : _timezone) / 3600), abs(((ta->tm_isdst ? _timezone - 3600 : _timezone) % 3600) / 60)); + snprintf(tzbuf, sizeof(tzbuf), "%c%02ld:%02ld", ((ta->tm_isdst ? _timezone - 3600:_timezone)>0)?'-':'+', labs((ta->tm_isdst ? _timezone - 3600 : _timezone) / 3600), labs(((ta->tm_isdst ? _timezone - 3600 : _timezone) % 3600) / 60)); # else - snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", ((ta->tm_isdst ? timezone - 3600:timezone)>0)?'-':'+', abs((ta->tm_isdst ? timezone - 3600 : timezone) / 3600), abs(((ta->tm_isdst ? timezone - 3600 : timezone) % 3600) / 60)); + snprintf(tzbuf, sizeof(tzbuf), "%c%02ld:%02ld", ((ta->tm_isdst ? timezone - 3600:timezone)>0)?'-':'+', labs((ta->tm_isdst ? timezone - 3600 : timezone) / 3600), labs(((ta->tm_isdst ? timezone - 3600 : timezone) % 3600) / 60)); # endif #endif if (strcmp(tzbuf,"+00:00") == 0) { @@ -3052,9 +3067,15 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP } ZEND_HASH_FOREACH_END(); } - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); + ret = xmlNewDocNode(parent->doc, NULL, BAD_CAST("BOGUS"), NULL); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); + + /* Literals are unique and can't refer to other references via attributes. */ + HashTable **ref_map = &SOAP_GLOBAL(ref_map); + HashTable *old_ref_map = *ref_map; + *ref_map = NULL; + if (Z_TYPE_P(data) == IS_ARRAY) { zval *tmp; smart_str list = {0}; @@ -3129,6 +3150,7 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP zval_ptr_dtor_str(&tmp); } } + *ref_map = old_ref_map; return ret; } @@ -3513,7 +3535,7 @@ void encode_reset_ns(void) } else { SOAP_GLOBAL(ref_map) = emalloc(sizeof(HashTable)); } - zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, NULL, 0); + zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, ZVAL_PTR_DTOR, 0); } void encode_finish(void) @@ -3565,6 +3587,11 @@ static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *type) soap_error0(E_ERROR, "Encoding: SoapVar has no 'enc_type' property"); } cur_type = Z_LVAL_P(ztype); + if (cur_type == UNKNOWN_TYPE) { + /* Mimic guess_xml_convert() where we use the type of the data. + * UNDEFs are handled transparently as it will error out upon encoding the data. */ + cur_type = Z_TYPE_P(Z_VAR_ENC_VALUE_P(tmp)); + } zval *zstype = Z_VAR_ENC_STYPE_P(tmp); if (Z_TYPE_P(zstype) == IS_STRING) { diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index ef05c9ebe787..e01154e17456 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 84a10368d22f..1d030caf9d45 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -18,6 +16,7 @@ #include "php_soap.h" #include "ext/hash/php_hash.h" /* For php_hash_bin2hex() */ +#include "ext/uri/php_uri.h" static char *get_http_header_value_nodup(char *headers, char *type, size_t *len); static char *get_http_header_value(char *headers, char *type); @@ -162,7 +161,7 @@ void http_context_headers(php_stream_context* context, } } -static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, php_stream_context *context, int *use_proxy) +static php_stream* http_connect(zval* this_ptr, php_uri *uri, int use_ssl, php_stream_context *context, int *use_proxy) { php_stream *stream; zval *tmp, ssl_proxy_peer_name; @@ -182,8 +181,8 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph port = Z_LVAL_P(proxy_port); *use_proxy = 1; } else { - host = ZSTR_VAL(phpurl->host); - port = phpurl->port; + host = ZSTR_VAL(uri->host); + port = uri->port; } tmp = Z_CLIENT_CONNECTION_TIMEOUT_P(this_ptr); @@ -247,21 +246,21 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph /* Set peer_name or name verification will try to use the proxy server name */ if (!context || (tmp = php_stream_context_get_option(context, "ssl", "peer_name")) == NULL) { - ZVAL_STR_COPY(&ssl_proxy_peer_name, phpurl->host); + ZVAL_STR_COPY(&ssl_proxy_peer_name, uri->host); php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name", &ssl_proxy_peer_name); zval_ptr_dtor(&ssl_proxy_peer_name); } smart_str_append_const(&soap_headers, "CONNECT "); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); + smart_str_append(&soap_headers, uri->host); smart_str_appendc(&soap_headers, ':'); - smart_str_append_unsigned(&soap_headers, phpurl->port); + smart_str_append_unsigned(&soap_headers, uri->port); smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"); smart_str_append_const(&soap_headers, "Host: "); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); - if (phpurl->port != 80) { + smart_str_append(&soap_headers, uri->host); + if (uri->port != 80) { smart_str_appendc(&soap_headers, ':'); - smart_str_append_unsigned(&soap_headers, phpurl->port); + smart_str_append_unsigned(&soap_headers, uri->port); } smart_str_append_const(&soap_headers, "\r\n"); proxy_authentication(this_ptr, &soap_headers); @@ -328,25 +327,22 @@ static bool in_domain(const zend_string *host, const zend_string *domain) if (ZSTR_LEN(host) > ZSTR_LEN(domain)) { return strcmp(ZSTR_VAL(host)+ZSTR_LEN(host)-ZSTR_LEN(domain), ZSTR_VAL(domain)) == 0; } else { - return 0; + return false; } } else { return zend_string_equals(host,domain); } } -int make_http_soap_request(zval *this_ptr, - zend_string *buf, - char *location, - char *soapaction, - int soap_version, - zval *return_value) -{ +int make_http_soap_request( + zval *this_ptr, zend_string *buf, zend_string *location, char *soapaction, + int soap_version, zend_string *uri_parser_class, zval *return_value +) { zend_string *request; smart_str soap_headers = {0}; smart_str soap_headers_z = {0}; size_t err; - php_url *phpurl = NULL; + php_uri *uri = NULL; php_stream *stream; zval *tmp; int use_proxy = 0; @@ -365,9 +361,9 @@ int make_http_soap_request(zval *this_ptr, char *http_msg = NULL; bool old_allow_url_fopen; php_stream_context *context = NULL; - bool has_authorization = 0; - bool has_proxy_authorization = 0; - bool has_cookies = 0; + bool has_authorization = false; + bool has_proxy_authorization = false; + bool has_cookies = false; if (this_ptr == NULL || Z_TYPE_P(this_ptr) != IS_OBJECT) { return FALSE; @@ -432,8 +428,13 @@ int make_http_soap_request(zval *this_ptr, stream = NULL; } - if (location != NULL && location[0] != '\000') { - phpurl = php_url_parse(location); + if (location != NULL && ZSTR_VAL(location)[0] != '\000') { + const php_uri_parser *uri_parser = php_uri_get_parser(uri_parser_class); + if (uri_parser == NULL) { + zend_argument_value_error(6, "must be a valid URI parser name"); + return FALSE; + } + uri = php_uri_parse_to_struct(uri_parser, ZSTR_VAL(location), ZSTR_LEN(location), PHP_URI_COMPONENT_READ_MODE_RAW, true); } tmp = Z_CLIENT_STREAM_CONTEXT_P(this_ptr); @@ -450,26 +451,28 @@ int make_http_soap_request(zval *this_ptr, } try_again: - if (phpurl == NULL || phpurl->host == NULL) { - if (phpurl != NULL) {php_url_free(phpurl);} + if (uri == NULL || uri->host == NULL) { + if (uri != NULL) { + php_uri_struct_free(uri); + } if (request != buf) { zend_string_release_ex(request, 0); } - add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "Unable to parse URL", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); return FALSE; } use_ssl = 0; - if (phpurl->scheme != NULL && zend_string_equals_literal(phpurl->scheme, "https")) { + if (uri->scheme != NULL && zend_string_equals_literal(uri->scheme, "https")) { use_ssl = 1; - } else if (phpurl->scheme == NULL || !zend_string_equals_literal(phpurl->scheme, "http")) { - php_url_free(phpurl); + } else if (uri->scheme == NULL || !zend_string_equals_literal(uri->scheme, "http")) { + php_uri_struct_free(uri); if (request != buf) { zend_string_release_ex(request, 0); } - add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "Unknown protocol. Only http and https are allowed.", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); return FALSE; @@ -478,38 +481,38 @@ int make_http_soap_request(zval *this_ptr, old_allow_url_fopen = PG(allow_url_fopen); PG(allow_url_fopen) = 1; if (use_ssl && php_stream_locate_url_wrapper("https://", NULL, STREAM_LOCATE_WRAPPERS_ONLY) == NULL) { - php_url_free(phpurl); + php_uri_struct_free(uri); if (request != buf) { zend_string_release_ex(request, 0); } - add_soap_fault(this_ptr, "HTTP", "SSL support is not available in this build", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "SSL support is not available in this build", NULL, NULL, soap_lang_en); PG(allow_url_fopen) = old_allow_url_fopen; smart_str_free(&soap_headers_z); efree(http_msg); return FALSE; } - if (phpurl->port == 0) { - phpurl->port = use_ssl ? 443 : 80; + if (uri->port == 0) { + uri->port = use_ssl ? 443 : 80; } /* Check if request to the same host */ if (stream != NULL) { - php_url *orig; + php_uri *orig; tmp = Z_CLIENT_HTTPURL_P(this_ptr); if (Z_TYPE_P(tmp) == IS_OBJECT && instanceof_function(Z_OBJCE_P(tmp), soap_url_class_entry) && - (orig = Z_SOAP_URL_P(tmp)->url) != NULL && + (orig = Z_SOAP_URL_P(tmp)->uri) != NULL && ((use_proxy && !use_ssl) || (((use_ssl && orig->scheme != NULL && zend_string_equals_literal(orig->scheme, "https")) || (!use_ssl && orig->scheme == NULL) || (!use_ssl && !zend_string_equals_literal(orig->scheme, "https"))) && - zend_string_equals(orig->host, phpurl->host) && - orig->port == phpurl->port))) { + zend_string_equals(orig->host, uri->host) && + orig->port == uri->port))) { } else { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; use_proxy = 0; } @@ -517,27 +520,25 @@ int make_http_soap_request(zval *this_ptr, /* Check if keep-alive connection is still opened */ if (stream != NULL && php_stream_eof(stream)) { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; use_proxy = 0; } if (!stream) { - stream = http_connect(this_ptr, phpurl, use_ssl, context, &use_proxy); + stream = http_connect(this_ptr, uri, use_ssl, context, &use_proxy); if (stream) { - php_stream_auto_cleanup(stream); - ZVAL_RES(Z_CLIENT_HTTPSOCKET_P(this_ptr), stream->res); - GC_ADDREF(stream->res); + php_stream_to_zval(stream, Z_CLIENT_HTTPSOCKET_P(this_ptr)); ZVAL_LONG(Z_CLIENT_USE_PROXY_P(this_ptr), use_proxy); } else { - php_url_free(phpurl); + php_uri_struct_free(uri); if (request != buf) { zend_string_release_ex(request, 0); } - add_soap_fault(this_ptr, "HTTP", "Could not connect to host", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "Could not connect to host", NULL, NULL, soap_lang_en); PG(allow_url_fopen) = old_allow_url_fopen; smart_str_free(&soap_headers_z); efree(http_msg); @@ -558,7 +559,7 @@ int make_http_soap_request(zval *this_ptr, object_init_ex(url_zval, soap_url_class_entry); soap_url_object *url_obj = Z_SOAP_URL_P(url_zval); - url_obj->url = phpurl; + url_obj->uri = uri; if (context && (tmp = php_stream_context_get_option(context, "http", "protocol_version")) != NULL && @@ -571,24 +572,24 @@ int make_http_soap_request(zval *this_ptr, smart_str_append_const(&soap_headers, "POST "); if (use_proxy && !use_ssl) { - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->scheme)); + smart_str_append(&soap_headers, uri->scheme); smart_str_append_const(&soap_headers, "://"); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); + smart_str_append(&soap_headers, uri->host); smart_str_appendc(&soap_headers, ':'); - smart_str_append_unsigned(&soap_headers, phpurl->port); + smart_str_append_unsigned(&soap_headers, uri->port); } - if (phpurl->path) { - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->path)); + if (uri->path) { + smart_str_append(&soap_headers, uri->path); } else { smart_str_appendc(&soap_headers, '/'); } - if (phpurl->query) { + if (uri->query) { smart_str_appendc(&soap_headers, '?'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->query)); + smart_str_append(&soap_headers, uri->query); } - if (phpurl->fragment) { + if (uri->fragment) { smart_str_appendc(&soap_headers, '#'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->fragment)); + smart_str_append(&soap_headers, uri->fragment); } if (http_1_1) { smart_str_append_const(&soap_headers, " HTTP/1.1\r\n"); @@ -596,10 +597,10 @@ int make_http_soap_request(zval *this_ptr, smart_str_append_const(&soap_headers, " HTTP/1.0\r\n"); } smart_str_append_const(&soap_headers, "Host: "); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->host)); - if (phpurl->port != (use_ssl?443:80)) { + smart_str_append(&soap_headers, uri->host); + if (uri->port != (use_ssl?443:80)) { smart_str_appendc(&soap_headers, ':'); - smart_str_append_unsigned(&soap_headers, phpurl->port); + smart_str_append_unsigned(&soap_headers, uri->port); } if (!http_1_1 || Z_TYPE_P(Z_CLIENT_KEEP_ALIVE_P(this_ptr)) == IS_FALSE) { smart_str_append_const(&soap_headers, "\r\n" @@ -612,7 +613,7 @@ int make_http_soap_request(zval *this_ptr, if (Z_TYPE_P(tmp) == IS_STRING) { if (Z_STRLEN_P(tmp) > 0) { smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); smart_str_append_const(&soap_headers, "\r\n"); } } else if (context && @@ -620,7 +621,7 @@ int make_http_soap_request(zval *this_ptr, Z_TYPE_P(tmp) == IS_STRING) { if (Z_STRLEN_P(tmp) > 0) { smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); smart_str_append_const(&soap_headers, "\r\n"); } } else if (FG(user_agent)) { @@ -640,7 +641,7 @@ int make_http_soap_request(zval *this_ptr, Z_STRLEN_P(tmp) > 0 ) { smart_str_append_const(&soap_headers, "Content-Type: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } else { smart_str_append_const(&soap_headers, "Content-Type: application/soap+xml; charset=utf-8"); } @@ -657,7 +658,7 @@ int make_http_soap_request(zval *this_ptr, Z_STRLEN_P(tmp) > 0 ) { smart_str_append_const(&soap_headers, "Content-Type: "); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); smart_str_append_const(&soap_headers, "\r\n"); } else { smart_str_append_const(&soap_headers, "Content-Type: text/xml; charset=utf-8\r\n"); @@ -677,7 +678,7 @@ int make_http_soap_request(zval *this_ptr, if (Z_TYPE_P(login) == IS_STRING) { zval *digest = Z_CLIENT_DIGEST_P(this_ptr); - has_authorization = 1; + has_authorization = true; if (Z_TYPE_P(digest) == IS_ARRAY) { char HA1[33], HA2[33], response[33], cnonce[33], nc[9]; unsigned char nonce[16]; @@ -686,10 +687,10 @@ int make_http_soap_request(zval *this_ptr, if (UNEXPECTED(php_random_bytes_throw(&nonce, sizeof(nonce)) != SUCCESS)) { ZEND_ASSERT(EG(exception)); + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); smart_str_free(&soap_headers_z); smart_str_free(&soap_headers); efree(http_msg); @@ -741,14 +742,14 @@ int make_http_soap_request(zval *this_ptr, PHP_MD5Init(&md5ctx); PHP_MD5Update(&md5ctx, (unsigned char*)"POST:", sizeof("POST:")-1); - if (phpurl->path) { - PHP_MD5Update(&md5ctx, (unsigned char*)ZSTR_VAL(phpurl->path), ZSTR_LEN(phpurl->path)); + if (uri->path) { + PHP_MD5Update(&md5ctx, (unsigned char*)ZSTR_VAL(uri->path), ZSTR_LEN(uri->path)); } else { PHP_MD5Update(&md5ctx, (unsigned char*)"/", 1); } - if (phpurl->query) { + if (uri->query) { PHP_MD5Update(&md5ctx, (unsigned char*)"?", 1); - PHP_MD5Update(&md5ctx, (unsigned char*)ZSTR_VAL(phpurl->query), ZSTR_LEN(phpurl->query)); + PHP_MD5Update(&md5ctx, (unsigned char*)ZSTR_VAL(uri->query), ZSTR_LEN(uri->query)); } PHP_MD5Final(hash, &md5ctx); @@ -777,30 +778,30 @@ int make_http_soap_request(zval *this_ptr, make_digest(response, hash); smart_str_append_const(&soap_headers, "Authorization: Digest username=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(login), Z_STRLEN_P(login)); + smart_str_append(&soap_headers, Z_STR_P(login)); if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "realm", sizeof("realm")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", realm=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nonce", sizeof("nonce")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", nonce=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } smart_str_append_const(&soap_headers, "\", uri=\""); - if (phpurl->path) { - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->path)); + if (uri->path) { + smart_str_append(&soap_headers, uri->path); } else { smart_str_appendc(&soap_headers, '/'); } - if (phpurl->query) { + if (uri->query) { smart_str_appendc(&soap_headers, '?'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->query)); + smart_str_append(&soap_headers, uri->query); } - if (phpurl->fragment) { + if (uri->fragment) { smart_str_appendc(&soap_headers, '#'); - smart_str_appends(&soap_headers, ZSTR_VAL(phpurl->fragment)); + smart_str_append(&soap_headers, uri->fragment); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "qop", sizeof("qop")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { @@ -816,12 +817,12 @@ int make_http_soap_request(zval *this_ptr, if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "opaque", sizeof("opaque")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", opaque=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "algorithm", sizeof("algorithm")-1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) { smart_str_append_const(&soap_headers, "\", algorithm=\""); - smart_str_appendl(&soap_headers, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&soap_headers, Z_STR_P(tmp)); } smart_str_append_const(&soap_headers, "\"\r\n"); } else { @@ -855,7 +856,7 @@ int make_http_soap_request(zval *this_ptr, if (zend_hash_num_elements(Z_ARRVAL_P(cookies)) != 0 && !HT_IS_PACKED(Z_ARRVAL_P(cookies))) { zval *data; zend_string *key; - has_cookies = 1; + has_cookies = true; bool first_cookie = true; smart_str_append_const(&soap_headers, "Cookie: "); ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(cookies), key, data) { @@ -867,10 +868,10 @@ int make_http_soap_request(zval *this_ptr, zval *tmp; if (((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 1)) == NULL || Z_TYPE_P(tmp) != IS_STRING || - strncmp(phpurl->path?ZSTR_VAL(phpurl->path):"/",Z_STRVAL_P(tmp),Z_STRLEN_P(tmp)) == 0) && + strncmp(uri->path?ZSTR_VAL(uri->path):"/",Z_STRVAL_P(tmp),Z_STRLEN_P(tmp)) == 0) && ((tmp = zend_hash_index_find(Z_ARRVAL_P(data), 2)) == NULL || Z_TYPE_P(tmp) != IS_STRING || - in_domain(phpurl->host, Z_STR_P(tmp))) && + in_domain(uri->host, Z_STR_P(tmp))) && (use_ssl || (tmp = zend_hash_index_find(Z_ARRVAL_P(data), 3)) == NULL)) { if (!first_cookie) { smart_str_appends(&soap_headers, "; "); @@ -896,7 +897,7 @@ int make_http_soap_request(zval *this_ptr, ZVAL_STRINGL(Z_CLIENT_LAST_REQUEST_HEADERS_P(this_ptr), ZSTR_VAL(soap_headers.s), ZSTR_LEN(soap_headers.s)); } - smart_str_appendl(&soap_headers, request->val, request->len); + smart_str_append(&soap_headers, request); smart_str_0(&soap_headers); err = php_stream_write(stream, ZSTR_VAL(soap_headers.s), ZSTR_LEN(soap_headers.s)); @@ -904,18 +905,18 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); - add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL, SOAP_GLOBAL(lang_en)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); + add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); return FALSE; } smart_str_free(&soap_headers); } else { - add_soap_fault(this_ptr, "HTTP", "Failed to create stream??", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "Failed to create stream??", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); return FALSE; @@ -929,10 +930,10 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); - add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL, SOAP_GLOBAL(lang_en)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); + add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); return FALSE; @@ -982,12 +983,12 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); if (http_headers) { zend_string_release_ex(http_headers, 0); } - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); if (http_msg) { efree(http_msg); } @@ -1011,24 +1012,22 @@ int make_http_soap_request(zval *this_ptr, char *eqpos = strstr(cookie, "="); char *sempos = strstr(cookie, ";"); if (eqpos != NULL && (sempos == NULL || sempos > eqpos)) { - smart_str name = {0}; - int cookie_len; zval zcookie; + size_t cookie_value_len; if (sempos != NULL) { - cookie_len = sempos-(eqpos+1); + cookie_value_len = sempos-(eqpos+1); } else { - cookie_len = strlen(cookie)-(eqpos-cookie)-1; + cookie_value_len = strlen(cookie)-(eqpos-cookie)-1; } - smart_str_appendl(&name, cookie, eqpos - cookie); - smart_str_0(&name); + zend_string *name = zend_string_init(cookie, eqpos - cookie, false); array_init(&zcookie); - add_index_stringl(&zcookie, 0, eqpos + 1, cookie_len); + add_index_stringl(&zcookie, 0, eqpos + 1, cookie_value_len); if (sempos != NULL) { - char *options = cookie + cookie_len+1; + char *options = sempos + 1; while (*options) { while (*options == ' ') {options++;} sempos = strstr(options, ";"); @@ -1049,19 +1048,19 @@ int make_http_soap_request(zval *this_ptr, } } if (!zend_hash_index_exists(Z_ARRVAL(zcookie), 1)) { - char *t = phpurl->path?ZSTR_VAL(phpurl->path):"/"; + char *t = uri->path?ZSTR_VAL(uri->path):"/"; char *c = strrchr(t, '/'); if (c) { add_index_stringl(&zcookie, 1, t, c-t); } } if (!zend_hash_index_exists(Z_ARRVAL(zcookie), 2)) { - add_index_str(&zcookie, 2, phpurl->host); - GC_ADDREF(phpurl->host); + add_index_str(&zcookie, 2, uri->host); + GC_ADDREF(uri->host); } - zend_symtable_update(Z_ARRVAL_P(cookies), name.s, &zcookie); - smart_str_free(&name); + zend_symtable_update(Z_ARRVAL_P(cookies), name, &zcookie); + zend_string_release_ex(name, false); } cookie_itt = cookie_itt + cookie_len; @@ -1117,11 +1116,11 @@ int make_http_soap_request(zval *this_ptr, if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); zend_string_release_ex(http_headers, 0); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); - add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL, SOAP_GLOBAL(lang_en)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); + add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL, soap_lang_en); if (http_msg) { efree(http_msg); } @@ -1134,9 +1133,9 @@ int make_http_soap_request(zval *this_ptr, } if (http_close) { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); - convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + ZVAL_NULL(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; } @@ -1145,42 +1144,43 @@ int make_http_soap_request(zval *this_ptr, char *loc; if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location:")) != NULL) { - php_url *new_url = php_url_parse(loc); + const php_uri_parser *uri_parser = php_uri_get_parser(uri_parser_class); + if (uri_parser == NULL) { + efree(loc); + zend_argument_value_error(6, "must be a valid URI parser name"); + return FALSE; + } - if (new_url != NULL) { + php_uri *new_uri = php_uri_parse_to_struct(uri_parser, loc, strlen(loc), PHP_URI_COMPONENT_READ_MODE_RAW, true); + efree(loc); + + if (new_uri != NULL) { zend_string_release_ex(http_headers, 0); zend_string_release_ex(http_body, 0); - efree(loc); - if (new_url->scheme == NULL && new_url->path != NULL) { - new_url->scheme = phpurl->scheme ? zend_string_copy(phpurl->scheme) : NULL; - new_url->host = phpurl->host ? zend_string_copy(phpurl->host) : NULL; - new_url->port = phpurl->port; - if (new_url->path && ZSTR_VAL(new_url->path)[0] != '/') { - if (phpurl->path) { - char *t = ZSTR_VAL(phpurl->path); + if (new_uri->scheme == NULL && new_uri->path != NULL) { + new_uri->scheme = new_uri->scheme ? zend_string_copy(new_uri->scheme) : NULL; + new_uri->host = new_uri->host ? zend_string_copy(new_uri->host) : NULL; + new_uri->port = new_uri->port; + if (new_uri->path && ZSTR_VAL(new_uri->path)[0] != '/') { + if (new_uri->path) { + char *t = ZSTR_VAL(new_uri->path); char *p = strrchr(t, '/'); if (p) { - zend_string *s = zend_string_alloc((p - t) + ZSTR_LEN(new_url->path) + 2, 0); - strncpy(ZSTR_VAL(s), t, (p - t) + 1); - ZSTR_VAL(s)[(p - t) + 1] = 0; - strcat(ZSTR_VAL(s), ZSTR_VAL(new_url->path)); - zend_string_release_ex(new_url->path, 0); - new_url->path = s; + zend_string *s = zend_string_concat2(t, (p - t) + 1, ZSTR_VAL(new_uri->path), ZSTR_LEN(new_uri->path)); + zend_string_release_ex(new_uri->path, 0); + new_uri->path = s; } } else { - zend_string *s = zend_string_alloc(ZSTR_LEN(new_url->path) + 2, 0); - ZSTR_VAL(s)[0] = '/'; - ZSTR_VAL(s)[1] = 0; - strcat(ZSTR_VAL(s), ZSTR_VAL(new_url->path)); - zend_string_release_ex(new_url->path, 0); - new_url->path = s; + zend_string *s = zend_string_concat2("/", 1, ZSTR_VAL(new_uri->path), ZSTR_LEN(new_uri->path)); + zend_string_release_ex(new_uri->path, 0); + new_uri->path = s; } } } - phpurl = new_url; + uri = new_uri; if (--redirect_max < 1) { - add_soap_fault(this_ptr, "HTTP", "Redirection limit reached, aborting", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "Redirection limit reached, aborting", NULL, NULL, soap_lang_en); smart_str_free(&soap_headers_z); efree(http_msg); return FALSE; @@ -1237,20 +1237,20 @@ int make_http_soap_request(zval *this_ptr, } if (Z_TYPE(digest) != IS_UNDEF) { - php_url *new_url = emalloc(sizeof(php_url)); + php_uri *new_uri = emalloc(sizeof(php_uri)); zval_ptr_dtor(Z_CLIENT_DIGEST_P(this_ptr)); ZVAL_COPY_VALUE(Z_CLIENT_DIGEST_P(this_ptr), &digest); - *new_url = *phpurl; - if (phpurl->scheme) phpurl->scheme = zend_string_copy(phpurl->scheme); - if (phpurl->user) phpurl->user = zend_string_copy(phpurl->user); - if (phpurl->pass) phpurl->pass = zend_string_copy(phpurl->pass); - if (phpurl->host) phpurl->host = zend_string_copy(phpurl->host); - if (phpurl->path) phpurl->path = zend_string_copy(phpurl->path); - if (phpurl->query) phpurl->query = zend_string_copy(phpurl->query); - if (phpurl->fragment) phpurl->fragment = zend_string_copy(phpurl->fragment); - phpurl = new_url; + *new_uri = *uri; + if (uri->scheme) uri->scheme = zend_string_copy(uri->scheme); + if (uri->user) uri->user = zend_string_copy(uri->user); + if (uri->password) uri->password = zend_string_copy(uri->password); + if (uri->host) uri->host = zend_string_copy(uri->host); + if (uri->path) uri->path = zend_string_copy(uri->path); + if (uri->query) uri->query = zend_string_copy(uri->query); + if (uri->fragment) uri->fragment = zend_string_copy(uri->fragment); + uri = new_uri; efree(auth); zend_string_release_ex(http_headers, 0); @@ -1296,21 +1296,19 @@ int make_http_soap_request(zval *this_ptr, /* Decompress response */ content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding:"); if (content_encoding) { - zval func; zval retval; zval params[1]; + zend_function *decompression_fn; /* Warning: the zlib function names are chosen in an unfortunate manner. * Check zlib.c to see how a function corresponds with a particular format. */ if ((strcmp(content_encoding,"gzip") == 0 || strcmp(content_encoding,"x-gzip") == 0) && - zend_hash_str_exists(EG(function_table), "gzdecode", sizeof("gzdecode")-1)) { - ZVAL_STRING(&func, "gzdecode"); - ZVAL_STR_COPY(¶ms[0], http_body); + (decompression_fn = zend_hash_str_find_ptr(EG(function_table), "gzdecode", sizeof("gzdecode")-1))) { + ZVAL_STR(¶ms[0], http_body); } else if (strcmp(content_encoding,"deflate") == 0 && - zend_hash_str_exists(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1)) { - ZVAL_STRING(&func, "gzuncompress"); - ZVAL_STR_COPY(¶ms[0], http_body); + (decompression_fn = zend_hash_str_find_ptr(EG(function_table), "gzuncompress", sizeof("gzuncompress")-1))) { + ZVAL_STR(¶ms[0], http_body); } else { efree(content_encoding); zend_string_release_ex(http_headers, 0); @@ -1318,23 +1316,19 @@ int make_http_soap_request(zval *this_ptr, if (http_msg) { efree(http_msg); } - add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "Unknown Content-Encoding", NULL, NULL, soap_lang_en); return FALSE; } - if (call_user_function(CG(function_table), (zval*)NULL, &func, &retval, 1, params) == SUCCESS && - Z_TYPE(retval) == IS_STRING) { - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(&func); + zend_call_known_function(decompression_fn, NULL, NULL, &retval, 1, params, NULL); + if (Z_TYPE(retval) == IS_STRING) { zend_string_release_ex(http_body, 0); ZVAL_COPY_VALUE(return_value, &retval); } else { - zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(&func); zval_ptr_dtor(&retval); efree(content_encoding); zend_string_release_ex(http_headers, 0); zend_string_release_ex(http_body, 0); - add_soap_fault(this_ptr, "HTTP", "Can't uncompress compressed response", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", "Can't uncompress compressed response", NULL, NULL, soap_lang_en); if (http_msg) { efree(http_msg); } @@ -1368,7 +1362,7 @@ int make_http_soap_request(zval *this_ptr, if (error) { zval_ptr_dtor(return_value); ZVAL_UNDEF(return_value); - add_soap_fault(this_ptr, "HTTP", http_msg, NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "HTTP", http_msg, NULL, NULL, soap_lang_en); efree(http_msg); return FALSE; } diff --git a/ext/soap/php_http.h b/ext/soap/php_http.h index df24c0d26fa8..a01ea35f9849 100644 --- a/ext/soap/php_http.h +++ b/ext/soap/php_http.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -19,12 +17,10 @@ #ifndef PHP_HTTP_H #define PHP_HTTP_H -int make_http_soap_request(zval *this_ptr, - zend_string *request, - char *location, - char *soapaction, - int soap_version, - zval *response); +int make_http_soap_request( + zval *this_ptr, zend_string *buf, zend_string *location, char *soapaction, + int soap_version, zend_string *uri_parser_class, zval *return_value +); int proxy_authentication(zval* this_ptr, smart_str* soap_headers); int basic_authentication(zval* this_ptr, smart_str* soap_headers); diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c index 31ed094ef2fc..b3aceb413890 100644 --- a/ext/soap/php_packet_soap.c +++ b/ext/soap/php_packet_soap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -18,6 +16,28 @@ #include "php_soap.h" +static void master_to_zval_with_doc_cleanup(zval *ret, encodePtr encode, xmlNodePtr data, xmlDocPtr doc) +{ + bool bailout = false; + + ZVAL_UNDEF(ret); + + /* SoapClient can turn decode errors into a bailout before parse_packet_soap() frees the response doc. */ + zend_try { + master_to_zval(ret, encode, data); + } zend_catch { + bailout = true; + } zend_end_try(); + + if (bailout) { + if (!Z_ISUNDEF_P(ret)) { + zval_ptr_dtor(ret); + } + xmlFreeDoc(doc); + zend_bailout(); + } +} + /* SOAP client calls this function to parse response from SOAP server */ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval *return_value, zval *soap_headers) { @@ -31,7 +51,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio ZVAL_NULL(return_value); - /* Response for one-way opearation */ + /* Response for one-way operation */ if (buffer_size == 0) { return true; } @@ -40,11 +60,11 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio response = soap_xmlParseMemory(buffer, buffer_size); if (!response) { - add_soap_fault(this_ptr, "Client", "looks like we got no XML document", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "looks like we got no XML document", NULL, NULL, soap_lang_en); return false; } if (xmlGetIntSubset(response) != NULL) { - add_soap_fault(this_ptr, "Client", "DTD are not supported by SOAP", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "DTD are not supported by SOAP", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -63,7 +83,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio envelope_ns = SOAP_1_2_ENV_NAMESPACE; soap_version = SOAP_1_2; } else { - add_soap_fault(this_ptr, "VersionMismatch", "Wrong Version", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "VersionMismatch", "Wrong Version", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -71,7 +91,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio trav = trav->next; } if (env == NULL) { - add_soap_fault(this_ptr, "Client", "looks like we got XML without \"Envelope\" element", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "looks like we got XML without \"Envelope\" element", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -79,16 +99,16 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio attr = env->properties; while (attr != NULL) { if (attr->ns == NULL) { - add_soap_fault(this_ptr, "Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { if (soap_version == SOAP_1_2) { - add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) { - add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -120,7 +140,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio trav = trav->next; } if (body == NULL) { - add_soap_fault(this_ptr, "Client", "Body must be present in a SOAP envelope", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "Body must be present in a SOAP envelope", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -128,17 +148,17 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio while (attr != NULL) { if (attr->ns == NULL) { if (soap_version == SOAP_1_2) { - add_soap_fault(this_ptr, "Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { if (soap_version == SOAP_1_2) { - add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Body", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Body", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) { - add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -146,7 +166,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio attr = attr->next; } if (trav != NULL && soap_version == SOAP_1_2) { - add_soap_fault(this_ptr, "Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -155,16 +175,16 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio attr = head->properties; while (attr != NULL) { if (attr->ns == NULL) { - add_soap_fault(this_ptr, "Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) { if (soap_version == SOAP_1_2) { - add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Header", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Header", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) { - add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL, SOAP_GLOBAL(lang_en)); + add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL, soap_lang_en); xmlFreeDoc(response); return false; } @@ -192,7 +212,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio tmp = get_node(fault->children, "faultstring"); if (tmp != NULL && tmp->children != NULL) { zval zv; - master_to_zval(&zv, get_conversion(IS_STRING), tmp); + master_to_zval_with_doc_cleanup(&zv, get_conversion(IS_STRING), tmp, response); convert_to_string(&zv) faultstring = Z_STR(zv); } @@ -200,14 +220,14 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio tmp = get_node(fault->children, "faultactor"); if (tmp != NULL && tmp->children != NULL) { zval zv; - master_to_zval(&zv, get_conversion(IS_STRING), tmp); + master_to_zval_with_doc_cleanup(&zv, get_conversion(IS_STRING), tmp, response); convert_to_string(&zv) faultactor = Z_STR(zv); } tmp = get_node(fault->children, "detail"); if (tmp != NULL) { - master_to_zval(&details, NULL, tmp); + master_to_zval_with_doc_cleanup(&details, NULL, tmp, response); } } else { tmp = get_node(fault->children, "Code"); @@ -223,7 +243,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio tmp = get_node(tmp->children,"Text"); if (tmp != NULL && tmp->children != NULL) { zval zv; - master_to_zval(&zv, get_conversion(IS_STRING), tmp); + master_to_zval_with_doc_cleanup(&zv, get_conversion(IS_STRING), tmp, response); convert_to_string(&zv) faultstring = Z_STR(zv); @@ -238,7 +258,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio tmp = get_node(fault->children,"Detail"); if (tmp != NULL) { - master_to_zval(&details, NULL, tmp); + master_to_zval_with_doc_cleanup(&details, NULL, tmp, response); } } add_soap_fault(this_ptr, faultcode, faultstring ? ZSTR_VAL(faultstring) : NULL, faultactor ? ZSTR_VAL(faultactor) : NULL, &details, lang); @@ -332,9 +352,9 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio } else { /* Decoding value of parameter */ if (param != NULL) { - master_to_zval(&tmp, param->encode, val); + master_to_zval_with_doc_cleanup(&tmp, param->encode, val, response); } else { - master_to_zval(&tmp, NULL, val); + master_to_zval_with_doc_cleanup(&tmp, NULL, val, response); } } add_assoc_zval(return_value, param->paramName, &tmp); @@ -355,7 +375,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio zval tmp; zval *arr; - master_to_zval(&tmp, NULL, val); + master_to_zval_with_doc_cleanup(&tmp, NULL, val, response); if (val->name) { if ((arr = zend_hash_str_find(Z_ARRVAL_P(return_value), (char*)val->name, strlen((char*)val->name))) != NULL) { add_next_index_zval(arr, &tmp); @@ -420,7 +440,7 @@ bool parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctio } smart_str_free(&key); } - master_to_zval(&val, enc, trav); + master_to_zval_with_doc_cleanup(&val, enc, trav, response); add_assoc_zval(soap_headers, (char*)trav->name, &val); } trav = trav->next; diff --git a/ext/soap/php_packet_soap.h b/ext/soap/php_packet_soap.h index 5a9fc62418a6..569b23949659 100644 --- a/ext/soap/php_packet_soap.h +++ b/ext/soap/php_packet_soap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index dc6816034dea..73d6691af262 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | diff --git a/ext/soap/php_schema.h b/ext/soap/php_schema.h index 68035000e1e5..b92c8a8fb4c4 100644 --- a/ext/soap/php_schema.h +++ b/ext/soap/php_schema.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index cc01b598bd9c..07c5dbf4f12e 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -2433,7 +2431,6 @@ static HashTable* make_persistent_sdl_function_headers(HashTable *headers, HashT ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(headers, key, tmp) { pheader = malloc(sizeof(sdlSoapBindingFunctionHeader)); - memset(pheader, 0, sizeof(sdlSoapBindingFunctionHeader)); *pheader = *tmp; if (pheader->name) { @@ -2497,7 +2494,6 @@ static HashTable* make_persistent_sdl_parameters(HashTable *params, HashTable *p ZEND_HASH_FOREACH_STR_KEY_PTR(params, key, tmp) { pparam = malloc(sizeof(sdlParam)); - memset(pparam, 0, sizeof(sdlParam)); *pparam = *tmp; if (pparam->paramName) { @@ -2539,7 +2535,6 @@ static HashTable* make_persistent_sdl_function_faults(sdlFunctionPtr func, HashT ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(faults, key, tmp) { pfault = malloc(sizeof(sdlFault)); - memset(pfault, 0, sizeof(sdlFault)); *pfault = *tmp; if (pfault->name) { @@ -3157,8 +3152,8 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) smart_str headers = {0}; char* key = NULL; time_t t = time(0); - bool has_proxy_authorization = 0; - bool has_authorization = 0; + bool has_proxy_authorization = false; + bool has_authorization = false; ZVAL_UNDEF(&orig_context); ZVAL_UNDEF(&new_context); @@ -3243,7 +3238,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) tmp = Z_CLIENT_USER_AGENT_P(this_ptr); if (Z_TYPE_P(tmp) == IS_STRING && Z_STRLEN_P(tmp) > 0) { smart_str_appends(&headers, "User-Agent: "); - smart_str_appends(&headers, Z_STRVAL_P(tmp)); + smart_str_append(&headers, Z_STR_P(tmp)); smart_str_appends(&headers, "\r\n"); } @@ -3253,7 +3248,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) zval str_proxy; smart_str proxy = {0}; smart_str_appends(&proxy,"tcp://"); - smart_str_appends(&proxy,Z_STRVAL_P(proxy_host)); + smart_str_append(&proxy, Z_STR_P(proxy_host)); smart_str_appends(&proxy,":"); smart_str_append_long(&proxy,Z_LVAL_P(proxy_port)); ZVAL_STR(&str_proxy, smart_str_extract(&proxy)); @@ -3312,7 +3307,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) sdl = load_wsdl(this_ptr, uri); if (sdl) { - sdl->is_persistent = 0; + sdl->is_persistent = false; } SOAP_GLOBAL(error_code) = old_error_code; @@ -3359,13 +3354,13 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) } psdl = make_persistent_sdl(sdl); - psdl->is_persistent = 1; + psdl->is_persistent = true; p.time = t; p.sdl = psdl; zend_hash_str_update_mem(SOAP_GLOBAL(mem_cache), uri, uri_len, &p, sizeof(sdl_cache_bucket)); - /* remove non-persitent sdl structure */ + /* remove non-persistent sdl structure */ delete_sdl_impl(sdl); /* and replace it with persistent one */ sdl = psdl; diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index 3df4fbdca015..7c9d8ce7382b 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -166,7 +164,7 @@ struct _sdlContentModel { union { sdlTypePtr element; /* pointer to element */ sdlTypePtr group; /* pointer to group */ - HashTable *content; /* array of sdlContentModel for sequnce,all,choice*/ + HashTable *content; /* array of sdlContentModel for sequence,all,choice*/ char *group_ref; /* reference to group */ } u; }; diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 98e3d4af6f19..ce36dae11aec 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -27,6 +25,7 @@ #include "zend_smart_str.h" #include "php_ini.h" #include "SAPI.h" +#include "ext/uri/php_uri.h" #include #include @@ -170,9 +169,10 @@ ZEND_BEGIN_MODULE_GLOBALS(soap) HashTable wsdl_cache; int cur_uniq_ref; HashTable *ref_map; - zend_string *lang_en; ZEND_END_MODULE_GLOBALS(soap) +extern zend_string *soap_lang_en; + #ifdef ZTS #include "TSRM.h" #endif @@ -216,51 +216,51 @@ static zend_always_inline zval *php_soap_deref(zval *zv) { return zv; } -#define Z_CLIENT_URI_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 0)) -#define Z_CLIENT_STYLE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 1)) -#define Z_CLIENT_USE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 2)) -#define Z_CLIENT_LOCATION_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 3)) -#define Z_CLIENT_TRACE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 4)) -#define Z_CLIENT_COMPRESSION_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 5)) -#define Z_CLIENT_SDL_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 6)) -#define Z_CLIENT_TYPEMAP_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 7)) -#define Z_CLIENT_HTTPSOCKET_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 8)) -#define Z_CLIENT_HTTPURL_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 9)) -#define Z_CLIENT_LOGIN_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 10)) -#define Z_CLIENT_PASSWORD_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 11)) -#define Z_CLIENT_USE_DIGEST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 12)) -#define Z_CLIENT_DIGEST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 13)) -#define Z_CLIENT_PROXY_HOST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 14)) -#define Z_CLIENT_PROXY_PORT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 15)) -#define Z_CLIENT_PROXY_LOGIN_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 16)) -#define Z_CLIENT_PROXY_PASSWORD_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 17)) -#define Z_CLIENT_EXCEPTIONS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 18)) -#define Z_CLIENT_ENCODING_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 19)) -#define Z_CLIENT_CLASSMAP_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 20)) -#define Z_CLIENT_FEATURES_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 21)) -#define Z_CLIENT_CONNECTION_TIMEOUT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 22)) -#define Z_CLIENT_STREAM_CONTEXT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 23)) -#define Z_CLIENT_USER_AGENT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 24)) -#define Z_CLIENT_KEEP_ALIVE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 25)) -#define Z_CLIENT_SSL_METHOD_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 26)) -#define Z_CLIENT_SOAP_VERSION_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 27)) -#define Z_CLIENT_USE_PROXY_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 28)) -#define Z_CLIENT_COOKIES_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 29)) -#define Z_CLIENT_DEFAULT_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 30)) -#define Z_CLIENT_SOAP_FAULT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 31)) -#define Z_CLIENT_LAST_REQUEST_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 32)) -#define Z_CLIENT_LAST_RESPONSE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 33)) -#define Z_CLIENT_LAST_REQUEST_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 34)) -#define Z_CLIENT_LAST_RESPONSE_HEADERS_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 35)) +/* SoapClient's properties are all private and can't be references */ +#define Z_CLIENT_URI_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 0) +#define Z_CLIENT_STYLE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 1) +#define Z_CLIENT_USE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 2) +#define Z_CLIENT_LOCATION_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 3) +#define Z_CLIENT_TRACE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 4) +#define Z_CLIENT_COMPRESSION_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 5) +#define Z_CLIENT_SDL_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 6) +#define Z_CLIENT_HTTPSOCKET_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 7) +#define Z_CLIENT_HTTPURL_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 8) +#define Z_CLIENT_LOGIN_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 9) +#define Z_CLIENT_PASSWORD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 10) +#define Z_CLIENT_USE_DIGEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 11) +#define Z_CLIENT_DIGEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 12) +#define Z_CLIENT_PROXY_HOST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 13) +#define Z_CLIENT_PROXY_PORT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 14) +#define Z_CLIENT_PROXY_LOGIN_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 15) +#define Z_CLIENT_PROXY_PASSWORD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 16) +#define Z_CLIENT_EXCEPTIONS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 17) +#define Z_CLIENT_ENCODING_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 18) +#define Z_CLIENT_CLASSMAP_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 19) +#define Z_CLIENT_FEATURES_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 20) +#define Z_CLIENT_CONNECTION_TIMEOUT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 21) +#define Z_CLIENT_STREAM_CONTEXT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 22) +#define Z_CLIENT_USER_AGENT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 23) +#define Z_CLIENT_KEEP_ALIVE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 24) +#define Z_CLIENT_SSL_METHOD_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 25) +#define Z_CLIENT_SOAP_VERSION_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 26) +#define Z_CLIENT_USE_PROXY_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 27) +#define Z_CLIENT_COOKIES_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 28) +#define Z_CLIENT_DEFAULT_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 29) +#define Z_CLIENT_SOAP_FAULT_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 30) +#define Z_CLIENT_LAST_REQUEST_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 31) +#define Z_CLIENT_LAST_RESPONSE_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 32) +#define Z_CLIENT_LAST_REQUEST_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 33) +#define Z_CLIENT_LAST_RESPONSE_HEADERS_P(zv) OBJ_PROP_NUM(Z_OBJ_P(zv), 34) typedef struct soap_url_object { - php_url *url; + php_uri *uri; zend_object std; } soap_url_object; static inline soap_url_object *soap_url_object_fetch(zend_object *obj) { - return (soap_url_object *) ((char *) obj - XtOffsetOf(soap_url_object, std)); + return ZEND_CONTAINER_OF(obj, soap_url_object, std); } #define Z_SOAP_URL_P(zv) soap_url_object_fetch(Z_OBJ_P(zv)) diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index b6b0c09b9d48..d5daaef15983 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -79,12 +77,15 @@ static xmlDocPtr soap_xmlParse_ex(xmlParserCtxtPtr ctxt) { xmlDocPtr ret; if (ctxt) { +#if LIBXML_VERSION >= 21300 + xmlCtxtSetOptions(ctxt, XML_PARSE_HUGE | XML_PARSE_NO_XXE | XML_PARSE_NONET | XML_PARSE_NOBLANKS); +#else php_libxml_sanitize_parse_ctxt_options(ctxt); - /* TODO: In libxml2 2.14.0 change this to the new options API so we don't rely on deprecated APIs. */ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations") ctxt->keepBlanks = 0; ctxt->options |= XML_PARSE_HUGE; ZEND_DIAGNOSTIC_IGNORED_END +#endif ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; ctxt->sax->comment = soap_Comment; ctxt->sax->warning = NULL; diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index c967ac09d738..4a6d76427dd1 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | diff --git a/ext/soap/soap.c b/ext/soap/soap.c index cdb0216ebcf8..da5e10ac3258 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brad Lafountain | | Shane Caraveo | @@ -21,6 +19,7 @@ #endif #include "php_soap.h" #include "ext/session/php_session.h" +#include "zend_attributes.h" #include "soap_arginfo.h" #include "zend_exceptions.h" #include "zend_interfaces.h" @@ -189,17 +188,46 @@ zend_class_entry* soap_var_class_entry; zend_class_entry *soap_url_class_entry; zend_class_entry *soap_sdl_class_entry; +static zend_object_handlers soap_client_object_handlers; static zend_object_handlers soap_server_object_handlers; static zend_object_handlers soap_url_object_handlers; static zend_object_handlers soap_sdl_object_handlers; +zend_string *soap_lang_en; + typedef struct { soapServicePtr service; zend_object std; } soap_server_object; +typedef struct { + HashTable *typemap; + zend_object std; +} soap_client_object; + +static inline soap_client_object *soap_client_object_fetch(zend_object *obj) { + return ZEND_CONTAINER_OF(obj, soap_client_object, std); +} + static inline soap_server_object *soap_server_object_fetch(zend_object *obj) { - return (soap_server_object *) ((char *) obj - XtOffsetOf(soap_server_object, std)); + return ZEND_CONTAINER_OF(obj, soap_server_object, std); +} + +static zend_object *soap_client_object_create(zend_class_entry *ce) +{ + soap_client_object *obj = zend_object_alloc(sizeof(soap_client_object), ce); + zend_object_std_init(&obj->std, ce); + object_properties_init(&obj->std, ce); + return &obj->std; +} + +static void soap_client_object_free(zend_object *obj) { + soap_client_object *client_obj = soap_client_object_fetch(obj); + if (client_obj->typemap) { + zend_hash_destroy(client_obj->typemap); + FREE_HASHTABLE(client_obj->typemap); + } + zend_object_std_dtor(obj); } static zend_object *soap_server_object_create(zend_class_entry *ce) @@ -232,9 +260,9 @@ static void soap_url_object_free(zend_object *obj) { soap_url_object *url_obj = soap_url_object_fetch(obj); - if (url_obj->url) { - php_url_free(url_obj->url); - url_obj->url = NULL; + if (url_obj->uri) { + php_uri_struct_free(url_obj->uri); + url_obj->uri = NULL; } zend_object_std_dtor(&url_obj->std); @@ -260,7 +288,7 @@ static zend_result soap_url_cast_object(zend_object *obj, zval *result, int type static inline soap_sdl_object *soap_sdl_object_fetch(zend_object *obj) { - return (soap_sdl_object *) ((char *) obj - XtOffsetOf(soap_sdl_object, std)); + return ZEND_CONTAINER_OF(obj, soap_sdl_object, std); } #define Z_SOAP_SDL_P(zv) soap_sdl_object_fetch(Z_OBJ_P(zv)) @@ -346,7 +374,7 @@ ZEND_GET_MODULE(soap) ZEND_INI_MH(OnUpdateCacheMode) { - char *p = (char *) ZEND_INI_GET_ADDR(); + char *p = ZEND_INI_GET_ADDR(); *p = (char)atoi(ZSTR_VAL(new_value)); return SUCCESS; } @@ -357,7 +385,7 @@ static PHP_INI_MH(OnUpdateCacheDir) if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) { char *p; - if (memchr(ZSTR_VAL(new_value), '\0', ZSTR_LEN(new_value)) != NULL) { + if (zend_str_has_nul_byte(new_value)) { return FAILURE; } @@ -452,7 +480,6 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals) soap_globals->soap_version = SOAP_1_1; soap_globals->mem_cache = NULL; soap_globals->ref_map = NULL; - soap_globals->lang_en = zend_string_init_interned(ZEND_STRL("en"), true); } PHP_MSHUTDOWN_FUNCTION(soap) @@ -472,7 +499,7 @@ PHP_MSHUTDOWN_FUNCTION(soap) zend_hash_destroy(SOAP_GLOBAL(mem_cache)); free(SOAP_GLOBAL(mem_cache)); } - zend_string_release_ex(SOAP_GLOBAL(lang_en), true); + zend_string_release_ex(soap_lang_en, true); UNREGISTER_INI_ENTRIES(); return SUCCESS; } @@ -501,6 +528,13 @@ PHP_MINIT_FUNCTION(soap) /* Register SoapClient class */ soap_class_entry = register_class_SoapClient(); + soap_class_entry->create_object = soap_client_object_create; + soap_class_entry->default_object_handlers = &soap_client_object_handlers; + + memcpy(&soap_client_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + soap_client_object_handlers.offset = offsetof(soap_client_object, std); + soap_client_object_handlers.free_obj = soap_client_object_free; + soap_client_object_handlers.clone_obj = NULL; /* Register SoapVar class */ soap_var_class_entry = register_class_SoapVar(); @@ -511,7 +545,7 @@ PHP_MINIT_FUNCTION(soap) soap_server_class_entry->default_object_handlers = &soap_server_object_handlers; memcpy(&soap_server_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - soap_server_object_handlers.offset = XtOffsetOf(soap_server_object, std); + soap_server_object_handlers.offset = offsetof(soap_server_object, std); soap_server_object_handlers.free_obj = soap_server_object_free; soap_server_object_handlers.clone_obj = NULL; @@ -528,7 +562,7 @@ PHP_MINIT_FUNCTION(soap) soap_url_class_entry->default_object_handlers = &soap_url_object_handlers; memcpy(&soap_url_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - soap_url_object_handlers.offset = XtOffsetOf(soap_url_object, std); + soap_url_object_handlers.offset = offsetof(soap_url_object, std); soap_url_object_handlers.free_obj = soap_url_object_free; soap_url_object_handlers.get_constructor = soap_url_object_get_constructor; soap_url_object_handlers.clone_obj = NULL; @@ -540,7 +574,7 @@ PHP_MINIT_FUNCTION(soap) soap_sdl_class_entry->default_object_handlers = &soap_sdl_object_handlers; memcpy(&soap_sdl_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - soap_sdl_object_handlers.offset = XtOffsetOf(soap_sdl_object, std); + soap_sdl_object_handlers.offset = offsetof(soap_sdl_object, std); soap_sdl_object_handlers.free_obj = soap_sdl_object_free; soap_sdl_object_handlers.get_constructor = soap_sdl_object_get_constructor; soap_sdl_object_handlers.clone_obj = NULL; @@ -552,6 +586,8 @@ PHP_MINIT_FUNCTION(soap) old_error_handler = zend_error_cb; zend_error_cb = soap_error_handler; + soap_lang_en = zend_string_init_interned(ZEND_STRL("en"), true); + return SUCCESS; } @@ -710,7 +746,7 @@ PHP_METHOD(SoapFault, __construct) } this_ptr = ZEND_THIS; - set_soap_fault(this_ptr, fault_code_ns, fault_code, fault_string, fault_actor, details, name, lang); + set_soap_fault(this_ptr, fault_code_ns, fault_code, fault_string, fault_actor, details, name, soap_lang_en); if (headerfault != NULL) { ZVAL_COPY(Z_FAULT_HEADERFAULT_P(this_ptr), headerfault); } @@ -726,9 +762,7 @@ PHP_METHOD(SoapFault, __toString) zend_string *faultcode_val, *faultstring_val, *file_val; zend_long line_val; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); this_ptr = ZEND_THIS; faultcode = zend_read_property(soap_fault_class_entry, Z_OBJ_P(this_ptr), "faultcode", sizeof("faultcode")-1, 1, &rv1); @@ -763,7 +797,7 @@ PHP_METHOD(SoapVar, __construct) { zval *data, *this_ptr; zend_long type; - bool type_is_null = 1; + bool type_is_null = true; zend_string *stype = NULL, *ns = NULL, *name = NULL, *namens = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z!l!|S!S!S!S!", &data, &type, &type_is_null, &stype, &ns, &name, &namens) == FAILURE) { @@ -1011,7 +1045,13 @@ PHP_METHOD(SoapServer, __construct) service->soap_functions.ft = zend_new_array(0); if (wsdl) { - service->sdl = get_sdl(ZEND_THIS, ZSTR_VAL(wsdl), cache_wsdl); + zend_try { + service->sdl = get_sdl(ZEND_THIS, ZSTR_VAL(wsdl), cache_wsdl); + } zend_catch { + xmlCharEncCloseFunc(service->encoding); + service->encoding = NULL; + zend_bailout(); + } zend_end_try(); if (service->uri == NULL) { if (service->sdl->target_ns) { service->uri = estrdup(service->sdl->target_ns); @@ -1124,9 +1164,7 @@ PHP_METHOD(SoapServer, getFunctions) soapServicePtr service; HashTable *ft = NULL; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); FETCH_THIS_SERVICE_NO_BAILOUT(service); @@ -1554,12 +1592,20 @@ PHP_METHOD(SoapServer, handle) instanceof_function(Z_OBJCE(h->retval), soap_fault_class_entry)) { php_output_discard(); soap_server_fault_ex(function, &h->retval, h); - if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);} + if (service->type == SOAP_CLASS && soap_obj) { + if (service->soap_class.persistence != SOAP_PERSISTENCE_SESSION) { + zval_ptr_dtor(soap_obj); + } + } goto fail; } else if (EG(exception)) { php_output_discard(); _soap_server_exception(service, function, ZEND_THIS); - if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(soap_obj);} + if (service->type == SOAP_CLASS && soap_obj) { + if (service->soap_class.persistence != SOAP_PERSISTENCE_SESSION) { + zval_ptr_dtor(soap_obj); + } + } goto fail; } } else if (h->mustUnderstand) { @@ -1655,7 +1701,7 @@ PHP_METHOD(SoapServer, handle) sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1); } - if (INI_INT("zlib.output_compression")) { + if (zend_ini_long_literal("zlib.output_compression")) { sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1); } else { snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); @@ -1817,7 +1863,7 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade if (use_http_error_status) { sapi_add_header("HTTP/1.1 500 Internal Server Error", sizeof("HTTP/1.1 500 Internal Server Error")-1, 1); } - if (INI_INT("zlib.output_compression")) { + if (zend_ini_long_literal("zlib.output_compression")) { sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1); } else { snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); @@ -1851,7 +1897,7 @@ static ZEND_NORETURN void soap_server_fault(char* code, char* string, char *acto static ZEND_NORETURN void soap_server_fault_en(char* code, char* string, char *actor, zval* details, zend_string* name) { - soap_server_fault(code, string, actor, details, name, SOAP_GLOBAL(lang_en)); + soap_server_fault(code, string, actor, details, name, soap_lang_en); } static zend_never_inline ZEND_COLD void soap_real_error_handler(int error_num, zend_string *error_filename, const uint32_t error_lineno, zend_string *message) /* {{{ */ @@ -1911,7 +1957,7 @@ static zend_never_inline ZEND_COLD void soap_real_error_handler(int error_num, z } else { buffer = zend_string_copy(message); - /* Get output buffer and send as fault detials */ + /* Get output buffer and send as fault details */ zval outbuflen; if (php_output_get_length(&outbuflen) != FAILURE && Z_LVAL(outbuflen) != 0) { php_output_get_contents(&outbuf); @@ -1920,7 +1966,7 @@ static zend_never_inline ZEND_COLD void soap_real_error_handler(int error_num, z } ZVAL_NULL(&fault_obj); - set_soap_fault(&fault_obj, NULL, code, ZSTR_VAL(buffer), NULL, &outbuf, NULL, SOAP_GLOBAL(lang_en)); + set_soap_fault(&fault_obj, NULL, code, ZSTR_VAL(buffer), NULL, &outbuf, NULL, soap_lang_en); zend_string_release(buffer); fault = 1; } @@ -1961,7 +2007,7 @@ static void soap_error_handler(int error_num, zend_string *error_filename, const /* {{{ */ PHP_FUNCTION(use_soap_error_handler) { - bool handler = 1; + bool handler = true; ZVAL_BOOL(return_value, SOAP_GLOBAL(use_soap_error_handler)); if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &handler) == SUCCESS) { @@ -1987,6 +2033,7 @@ PHP_FUNCTION(is_soap_fault) /* SoapClient functions */ /* {{{ SoapClient constructor */ +/* FIXME: double construct call will break this class */ PHP_METHOD(SoapClient, __construct) { @@ -2210,10 +2257,7 @@ PHP_METHOD(SoapClient, __construct) } if (typemap_ht) { - HashTable *typemap = soap_create_typemap(sdl, typemap_ht); - if (typemap) { - ZVAL_ARR(Z_CLIENT_TYPEMAP_P(this_ptr), typemap); - } + soap_client_object_fetch(Z_OBJ_P(this_ptr))->typemap = soap_create_typemap(sdl, typemap_ht); } SOAP_CLIENT_END_CODE(); } @@ -2341,10 +2385,7 @@ static void do_soap_call(zend_execute_data *execute_data, sdl = Z_SOAP_SDL_P(tmp)->sdl; } - tmp = Z_CLIENT_TYPEMAP_P(this_ptr); - if (Z_TYPE_P(tmp) == IS_ARRAY) { - typemap = Z_ARR_P(tmp); - } + typemap = soap_client_object_fetch(Z_OBJ_P(this_ptr))->typemap; clear_soap_fault(this_ptr); @@ -2408,9 +2449,19 @@ static void do_soap_call(zend_execute_data *execute_data, request = NULL; if (ret && Z_TYPE(response) == IS_STRING) { + bool parse_bailout = false; + encode_reset_ns(); - ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers); + zend_try { + ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers); + } zend_catch { + parse_bailout = true; + } zend_end_try(); encode_finish(); + if (parse_bailout) { + zval_ptr_dtor(&response); + zend_bailout(); + } } zval_ptr_dtor(&response); @@ -2452,9 +2503,19 @@ static void do_soap_call(zend_execute_data *execute_data, request = NULL; if (ret && Z_TYPE(response) == IS_STRING) { + bool parse_bailout = false; + encode_reset_ns(); - ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, NULL, return_value, output_headers); + zend_try { + ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, NULL, return_value, output_headers); + } zend_catch { + parse_bailout = true; + } zend_end_try(); encode_finish(); + if (parse_bailout) { + zval_ptr_dtor(&response); + zend_bailout(); + } } zval_ptr_dtor(&response); @@ -2543,7 +2604,7 @@ static void soap_client_call_common( if (soap_headers) { if (!free_soap_headers) { soap_headers = zend_array_dup(soap_headers); - free_soap_headers = 1; + free_soap_headers = true; } ZEND_HASH_FOREACH_VAL(default_headers, tmp) { if(Z_TYPE_P(tmp) == IS_OBJECT) { @@ -2553,7 +2614,7 @@ static void soap_client_call_common( } ZEND_HASH_FOREACH_END(); } else { soap_headers = Z_ARRVAL_P(tmp); - free_soap_headers = 0; + free_soap_headers = false; } } @@ -2682,9 +2743,7 @@ PHP_METHOD(SoapClient, __soapCall) /* {{{ Returns list of SOAP functions */ PHP_METHOD(SoapClient, __getFunctions) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); sdl *sdl; FETCH_THIS_SDL(sdl); @@ -2707,9 +2766,7 @@ PHP_METHOD(SoapClient, __getFunctions) /* {{{ Returns list of SOAP types */ PHP_METHOD(SoapClient, __getTypes) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); sdl *sdl; FETCH_THIS_SDL(sdl); @@ -2734,9 +2791,7 @@ PHP_METHOD(SoapClient, __getTypes) /* {{{ Returns last SOAP request */ PHP_METHOD(SoapClient, __getLastRequest) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_REQUEST_P(ZEND_THIS)); } @@ -2746,9 +2801,7 @@ PHP_METHOD(SoapClient, __getLastRequest) /* {{{ Returns last SOAP response */ PHP_METHOD(SoapClient, __getLastResponse) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_RESPONSE_P(ZEND_THIS)); } @@ -2758,9 +2811,7 @@ PHP_METHOD(SoapClient, __getLastResponse) /* {{{ Returns last SOAP request headers */ PHP_METHOD(SoapClient, __getLastRequestHeaders) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_REQUEST_HEADERS_P(ZEND_THIS)); } @@ -2770,9 +2821,7 @@ PHP_METHOD(SoapClient, __getLastRequestHeaders) /* {{{ Returns last SOAP response headers */ PHP_METHOD(SoapClient, __getLastResponseHeaders) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_LAST_RESPONSE_HEADERS_P(ZEND_THIS)); } @@ -2782,28 +2831,28 @@ PHP_METHOD(SoapClient, __getLastResponseHeaders) /* {{{ SoapClient::__doRequest() */ PHP_METHOD(SoapClient, __doRequest) { - zend_string *buf; - char *location, *action; - size_t location_size, action_size; + zend_string *buf, *location, *uri_parser_class = NULL; + char *action; + size_t action_size; zend_long version; - bool one_way = 0; + bool one_way = false; zval *this_ptr = ZEND_THIS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sssl|b", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSsl|bS!", &buf, - &location, &location_size, + &location, &action, &action_size, - &version, &one_way) == FAILURE) { + &version, &one_way, &uri_parser_class) == FAILURE) { RETURN_THROWS(); } if (SOAP_GLOBAL(features) & SOAP_WAIT_ONE_WAY_CALLS) { - one_way = 0; + one_way = false; } if (one_way) { - if (make_http_soap_request(this_ptr, buf, location, action, version, NULL)) { + if (make_http_soap_request(this_ptr, buf, location, action, version, uri_parser_class, NULL)) { RETURN_EMPTY_STRING(); } - } else if (make_http_soap_request(this_ptr, buf, location, action, version, + } else if (make_http_soap_request(this_ptr, buf, location, action, version, uri_parser_class, return_value)) { return; } @@ -2811,7 +2860,7 @@ PHP_METHOD(SoapClient, __doRequest) } /* }}} */ -/* {{{ Sets cookie thet will sent with SOAP request. +/* {{{ Sets cookie that will sent with SOAP request. The call to this function will effect all following calls of SOAP methods. If value is not specified cookie is removed. */ PHP_METHOD(SoapClient, __setCookie) @@ -2825,12 +2874,12 @@ PHP_METHOD(SoapClient, __setCookie) zval *cookies = Z_CLIENT_COOKIES_P(ZEND_THIS); SEPARATE_ARRAY(cookies); if (val == NULL) { - zend_hash_del(Z_ARRVAL_P(cookies), name); + zend_symtable_del(Z_ARRVAL_P(cookies), name); } else { zval zcookie; array_init(&zcookie); add_index_str(&zcookie, 0, zend_string_copy(val)); - zend_hash_update(Z_ARRVAL_P(cookies), name, &zcookie); + zend_symtable_update(Z_ARRVAL_P(cookies), name, &zcookie); } } /* }}} */ @@ -2838,9 +2887,7 @@ PHP_METHOD(SoapClient, __setCookie) /* {{{ Returns list of cookies */ PHP_METHOD(SoapClient, __getCookies) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_COPY(Z_CLIENT_COOKIES_P(ZEND_THIS)); } @@ -2933,7 +2980,7 @@ static void add_soap_fault_ex(zval *fault, zval *obj, char *fault_code, char *fa static void add_soap_fault_ex_en(zval *fault, zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail) { - add_soap_fault_ex(fault, obj, fault_code, fault_string, fault_actor, fault_detail, SOAP_GLOBAL(lang_en)); + add_soap_fault_ex(fault, obj, fault_code, fault_string, fault_actor, fault_detail, soap_lang_en); } void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail, zend_string *lang) /* {{{ */ @@ -2945,7 +2992,7 @@ void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault static void add_soap_fault_en(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail) { - add_soap_fault(obj, fault_code, fault_string, fault_actor, fault_detail, SOAP_GLOBAL(lang_en)); + add_soap_fault(obj, fault_code, fault_string, fault_actor, fault_detail, soap_lang_en); } static void set_soap_fault(zval *obj, const char *fault_code_ns, const char *fault_code, const char *fault_string, const char *fault_actor, zval *fault_detail, zend_string *name, zend_string *lang) /* {{{ */ @@ -3380,7 +3427,7 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c smart_str_appends(&key, (char*)hdr_func->ns->href); smart_str_appendc(&key, ':'); } - smart_str_appendl(&key, Z_STRVAL(h->function_name), Z_STRLEN(h->function_name)); + smart_str_append(&key, Z_STR(h->function_name)); smart_str_0(&key); if ((hdr = zend_hash_find_ptr(fnb->input.headers, key.s)) != NULL) { h->hdr = hdr; @@ -3617,14 +3664,14 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu tmp = Z_HEADER_NAMESPACE_P(hdr_ret); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); smart_str_appendc(&key, ':'); hdr_ns = Z_STRVAL_P(tmp); } tmp = Z_HEADER_NAME_P(hdr_ret); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); hdr_name = Z_STRVAL_P(tmp); } smart_str_0(&key); @@ -3715,7 +3762,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu if (version == SOAP_1_1) { tmp = Z_FAULT_CODE_P(ret); if (Z_TYPE_P(tmp) == IS_STRING) { - xmlNodePtr node = xmlNewNode(NULL, BAD_CAST("faultcode")); + xmlNodePtr node = xmlNewDocNode(doc, NULL, BAD_CAST("faultcode"), NULL); zend_string *str = php_escape_html_entities((unsigned char*)Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), 0, 0, NULL); xmlAddChild(param, node); if (fault_ns) { @@ -3779,7 +3826,7 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu if (Z_TYPE_P(tmp) > IS_NULL) { detail = tmp; } - node = xmlNewNode(NULL, BAD_CAST(detail_name)); + node = xmlNewDocNode(doc, NULL, BAD_CAST(detail_name), NULL); xmlAddChild(param, node); zend_hash_internal_pointer_reset(fault->details); @@ -3850,13 +3897,13 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, const char *fu tmp = Z_HEADER_NAMESPACE_P(&h->retval); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); smart_str_appendc(&key, ':'); hdr_ns = Z_STRVAL_P(tmp); } tmp = Z_HEADER_NAME_P(&h->retval); if (Z_TYPE_P(tmp) == IS_STRING) { - smart_str_appendl(&key, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); + smart_str_append(&key, Z_STR_P(tmp)); hdr_name = Z_STRVAL_P(tmp); } smart_str_0(&key); @@ -4092,9 +4139,9 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function smart_str key = {0}; sdlSoapBindingFunctionHeaderPtr hdr; - smart_str_appendl(&key, Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + smart_str_append(&key, Z_STR_P(ns)); smart_str_appendc(&key, ':'); - smart_str_appendl(&key, Z_STRVAL_P(name), Z_STRLEN_P(name)); + smart_str_append(&key, Z_STR_P(name)); smart_str_0(&key); if ((hdr = zend_hash_find_ptr(hdrs, key.s)) != NULL) { hdr_use = hdr->use; @@ -4111,7 +4158,7 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function h = master_to_xml(enc, data, hdr_use, head); xmlNodeSetName(h, BAD_CAST(Z_STRVAL_P(name))); } else { - h = xmlNewNode(NULL, BAD_CAST(Z_STRVAL_P(name))); + h = xmlNewDocNode(doc, NULL, BAD_CAST(Z_STRVAL_P(name)), NULL); xmlAddChild(head, h); } nsptr = encode_add_ns(h, Z_STRVAL_P(ns)); @@ -4204,8 +4251,10 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, const char *param } xmlParam = master_to_xml(enc, val, style, parent); zval_ptr_dtor(&defval); - if (!strcmp((char*)xmlParam->name, "BOGUS")) { - xmlNodeSetName(xmlParam, BAD_CAST(paramName)); + if (xmlParam != NULL) { + if (xmlParam->name == NULL || strcmp((char*)xmlParam->name, "BOGUS") == 0) { + xmlNodeSetName(xmlParam, BAD_CAST(paramName)); + } } return xmlParam; } @@ -4332,7 +4381,7 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf) /* {{{ * zend_hash_internal_pointer_reset(function->responseParameters); param = zend_hash_get_current_data_ptr(function->responseParameters); if (param->encode && param->encode->details.type_str) { - smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str)); + smart_str_appends(buf, param->encode->details.type_str); smart_str_appendc(buf, ' '); } else { smart_str_appendl(buf, "UNKNOWN ", 8); @@ -4345,12 +4394,12 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf) /* {{{ * smart_str_appendl(buf, ", ", 2); } if (param->encode && param->encode->details.type_str) { - smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str)); + smart_str_appends(buf, param->encode->details.type_str); } else { smart_str_appendl(buf, "UNKNOWN", 7); } smart_str_appendl(buf, " $", 2); - smart_str_appendl(buf, param->paramName, strlen(param->paramName)); + smart_str_appends(buf, param->paramName); i++; } ZEND_HASH_FOREACH_END(); smart_str_appendl(buf, ") ", 2); @@ -4359,7 +4408,7 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf) /* {{{ * smart_str_appendl(buf, "void ", 5); } - smart_str_appendl(buf, function->functionName, strlen(function->functionName)); + smart_str_appends(buf, function->functionName); smart_str_appendc(buf, '('); if (function->requestParameters) { @@ -4369,12 +4418,12 @@ static void function_to_string(sdlFunctionPtr function, smart_str *buf) /* {{{ * smart_str_appendl(buf, ", ", 2); } if (param->encode && param->encode->details.type_str) { - smart_str_appendl(buf, param->encode->details.type_str, strlen(param->encode->details.type_str)); + smart_str_appends(buf, param->encode->details.type_str); } else { smart_str_appendl(buf, "UNKNOWN", 7); } smart_str_appendl(buf, " $", 2); - smart_str_appendl(buf, param->paramName, strlen(param->paramName)); + smart_str_appends(buf, param->paramName); i++; } ZEND_HASH_FOREACH_END(); } @@ -4425,17 +4474,17 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ smart_str_appendc(&spaces, ' '); } if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } switch (type->kind) { case XSD_TYPEKIND_SIMPLE: if (type->encode) { - smart_str_appendl(buf, type->encode->details.type_str, strlen(type->encode->details.type_str)); + smart_str_appends(buf, type->encode->details.type_str); smart_str_appendc(buf, ' '); } else { smart_str_appendl(buf, "anyType ", sizeof("anyType ")-1); } - smart_str_appendl(buf, type->name, strlen(type->name)); + smart_str_appends(buf, type->name); if (type->restrictions && type->restrictions->enumeration) { zend_string *key; @@ -4455,20 +4504,20 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ break; case XSD_TYPEKIND_LIST: smart_str_appendl(buf, "list ", 5); - smart_str_appendl(buf, type->name, strlen(type->name)); + smart_str_appends(buf, type->name); if (type->elements) { sdlTypePtr item_type; smart_str_appendl(buf, " {", 2); ZEND_HASH_FOREACH_PTR(type->elements, item_type) { - smart_str_appendl(buf, item_type->name, strlen(item_type->name)); + smart_str_appends(buf, item_type->name); } ZEND_HASH_FOREACH_END(); smart_str_appendc(buf, '}'); } break; case XSD_TYPEKIND_UNION: smart_str_appendl(buf, "union ", 6); - smart_str_appendl(buf, type->name, strlen(type->name)); + smart_str_appends(buf, type->name); if (type->elements) { sdlTypePtr item_type; int first = 0; @@ -4479,7 +4528,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ smart_str_appendc(buf, ','); first = 0; } - smart_str_appendl(buf, item_type->name, strlen(item_type->name)); + smart_str_appends(buf, item_type->name); } ZEND_HASH_FOREACH_END(); smart_str_appendc(buf, '}'); } @@ -4511,7 +4560,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ smart_str_appendl(buf, ext->val, len); } smart_str_appendc(buf, ' '); - smart_str_appendl(buf, type->name, strlen(type->name)); + smart_str_appends(buf, type->name); if (end != NULL) { smart_str_appends(buf, end); } @@ -4534,7 +4583,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ } else { smart_str_appendl(buf, "anyType ", 8); } - smart_str_appendl(buf, type->name, strlen(type->name)); + smart_str_appends(buf, type->name); if (type->attributes && (attr = zend_hash_str_find_ptr(type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize")-1)) != NULL && @@ -4549,7 +4598,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ } } else { smart_str_appendl(buf, "struct ", 7); - smart_str_appendl(buf, type->name, strlen(type->name)); + smart_str_appends(buf, type->name); smart_str_appendc(buf, ' '); smart_str_appendl(buf, "{\n", 2); if ((type->kind == XSD_TYPEKIND_RESTRICTION || @@ -4564,10 +4613,10 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ } if (enc) { if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } smart_str_appendc(buf, ' '); - smart_str_appendl(buf, type->encode->details.type_str, strlen(type->encode->details.type_str)); + smart_str_appends(buf, type->encode->details.type_str); smart_str_appendl(buf, " _;\n", 4); } } @@ -4579,7 +4628,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ ZEND_HASH_FOREACH_PTR(type->attributes, attr) { if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } smart_str_appendc(buf, ' '); if (attr->encode && attr->encode->details.type_str) { @@ -4593,7 +4642,7 @@ static void type_to_string(sdlTypePtr type, smart_str *buf, int level) /* {{{ */ } ZEND_HASH_FOREACH_END(); } if (spaces.s) { - smart_str_appendl(buf, ZSTR_VAL(spaces.s), ZSTR_LEN(spaces.s)); + smart_str_append(buf, spaces.s); } smart_str_appendc(buf, '}'); } diff --git a/ext/soap/soap.stub.php b/ext/soap/soap.stub.php index 2520bd134696..fdd4a46e109f 100644 --- a/ext/soap/soap.stub.php +++ b/ext/soap/soap.stub.php @@ -44,8 +44,8 @@ final class Sdl /** * @var int * @cvalue SOAP_FUNCTIONS_ALL - * @deprecated since 8.4 */ + #[\Deprecated(since: '8.4', message: 'as enabling all functions is a possible security concern')] const SOAP_FUNCTIONS_ALL = UNKNOWN; /** @@ -541,7 +541,6 @@ class SoapClient private bool $trace = false; private ?int $compression = null; private ?Soap\Sdl $sdl = null; - private ?array $typemap = null; /** @var resource|null */ private $httpsocket = null; private ?Soap\Url $httpurl = null; @@ -605,7 +604,7 @@ public function __getLastRequestHeaders(): ?string {} public function __getLastResponseHeaders(): ?string {} /** @tentative-return-type */ - public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false): ?string {} + public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false, ?string $uriParserClass = null): ?string {} /** @tentative-return-type */ public function __setCookie(string $name, ?string $value = null): void {} diff --git a/ext/soap/soap_arginfo.h b/ext/soap/soap_arginfo.h index e932f2af7109..2f7d56ca4221 100644 --- a/ext/soap/soap_arginfo.h +++ b/ext/soap/soap_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 78a27b18c6b4007494a6aed9acc5f6e99c6f0350 */ +/* This is a generated file, edit soap.stub.php instead. + * Stub hash: 14c74a5d6f547837f536920d5abb741e2b6e4373 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_use_soap_error_handler, 0, 0, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, enable, _IS_BOOL, 0, "true") @@ -124,6 +124,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SoapClient___doR ZEND_ARG_TYPE_INFO(0, action, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, version, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, oneWay, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, uriParserClass, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SoapClient___setCookie, 0, 1, IS_VOID, 0) @@ -238,7 +239,7 @@ static void register_soap_symbols(int module_number) REGISTER_LONG_CONSTANT("SOAP_1_2", SOAP_1_2, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_SESSION", SOAP_PERSISTENCE_SESSION, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_PERSISTENCE_REQUEST", SOAP_PERSISTENCE_REQUEST, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("SOAP_FUNCTIONS_ALL", SOAP_FUNCTIONS_ALL, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_SOAP_FUNCTIONS_ALL = REGISTER_LONG_CONSTANT("SOAP_FUNCTIONS_ALL", SOAP_FUNCTIONS_ALL, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("SOAP_ENCODED", SOAP_ENCODED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_LITERAL", SOAP_LITERAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_RPC", SOAP_RPC, CONST_PERSISTENT); @@ -315,6 +316,14 @@ static void register_soap_symbols(int module_number) REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv2", SOAP_SSL_METHOD_SSLv2, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv3", SOAP_SSL_METHOD_SSLv3, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv23", SOAP_SSL_METHOD_SSLv23, CONST_PERSISTENT); + + + zend_attribute *attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0 = zend_add_global_constant_attribute(const_SOAP_FUNCTIONS_ALL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); + attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1_str = zend_string_init("as enabling all functions is a possible security concern", strlen("as enabling all functions is a possible security concern"), 1); + ZVAL_STR(&attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[1].value, attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0_arg1_str); + attribute_Deprecated_const_SOAP_FUNCTIONS_ALL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } static zend_class_entry *register_class_Soap_Url(void) @@ -346,15 +355,15 @@ static zend_class_entry *register_class_SoapParam(void) zval property_param_name_default_value; ZVAL_UNDEF(&property_param_name_default_value); - zend_string *property_param_name_name = zend_string_init("param_name", sizeof("param_name") - 1, 1); + zend_string *property_param_name_name = zend_string_init("param_name", sizeof("param_name") - 1, true); zend_declare_typed_property(class_entry, property_param_name_name, &property_param_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_param_name_name); + zend_string_release_ex(property_param_name_name, true); zval property_param_data_default_value; ZVAL_UNDEF(&property_param_data_default_value); - zend_string *property_param_data_name = zend_string_init("param_data", sizeof("param_data") - 1, 1); + zend_string *property_param_data_name = zend_string_init("param_data", sizeof("param_data") - 1, true); zend_declare_typed_property(class_entry, property_param_data_name, &property_param_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); - zend_string_release(property_param_data_name); + zend_string_release_ex(property_param_data_name, true); return class_entry; } @@ -368,9 +377,9 @@ static zend_class_entry *register_class_SoapHeader(void) zval property_namespace_default_value; ZVAL_UNDEF(&property_namespace_default_value); - zend_string *property_namespace_name = zend_string_init("namespace", sizeof("namespace") - 1, 1); + zend_string *property_namespace_name = zend_string_init("namespace", sizeof("namespace") - 1, true); zend_declare_typed_property(class_entry, property_namespace_name, &property_namespace_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_namespace_name); + zend_string_release_ex(property_namespace_name, true); zval property_name_default_value; ZVAL_UNDEF(&property_name_default_value); @@ -378,21 +387,21 @@ static zend_class_entry *register_class_SoapHeader(void) zval property_data_default_value; ZVAL_NULL(&property_data_default_value); - zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); + zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, true); zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); - zend_string_release(property_data_name); + zend_string_release_ex(property_data_name, true); zval property_mustUnderstand_default_value; ZVAL_UNDEF(&property_mustUnderstand_default_value); - zend_string *property_mustUnderstand_name = zend_string_init("mustUnderstand", sizeof("mustUnderstand") - 1, 1); + zend_string *property_mustUnderstand_name = zend_string_init("mustUnderstand", sizeof("mustUnderstand") - 1, true); zend_declare_typed_property(class_entry, property_mustUnderstand_name, &property_mustUnderstand_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_mustUnderstand_name); + zend_string_release_ex(property_mustUnderstand_name, true); zval property_actor_default_value; ZVAL_UNDEF(&property_actor_default_value); - zend_string *property_actor_name = zend_string_init("actor", sizeof("actor") - 1, 1); + zend_string *property_actor_name = zend_string_init("actor", sizeof("actor") - 1, true); zend_declare_typed_property(class_entry, property_actor_name, &property_actor_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property_actor_name); + zend_string_release_ex(property_actor_name, true); return class_entry; } @@ -406,51 +415,51 @@ static zend_class_entry *register_class_SoapFault(zend_class_entry *class_entry_ zval property_faultstring_default_value; ZVAL_UNDEF(&property_faultstring_default_value); - zend_string *property_faultstring_name = zend_string_init("faultstring", sizeof("faultstring") - 1, 1); + zend_string *property_faultstring_name = zend_string_init("faultstring", sizeof("faultstring") - 1, true); zend_declare_typed_property(class_entry, property_faultstring_name, &property_faultstring_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_faultstring_name); + zend_string_release_ex(property_faultstring_name, true); zval property_faultcode_default_value; ZVAL_NULL(&property_faultcode_default_value); - zend_string *property_faultcode_name = zend_string_init("faultcode", sizeof("faultcode") - 1, 1); + zend_string *property_faultcode_name = zend_string_init("faultcode", sizeof("faultcode") - 1, true); zend_declare_typed_property(class_entry, property_faultcode_name, &property_faultcode_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_faultcode_name); + zend_string_release_ex(property_faultcode_name, true); zval property_faultcodens_default_value; ZVAL_NULL(&property_faultcodens_default_value); - zend_string *property_faultcodens_name = zend_string_init("faultcodens", sizeof("faultcodens") - 1, 1); + zend_string *property_faultcodens_name = zend_string_init("faultcodens", sizeof("faultcodens") - 1, true); zend_declare_typed_property(class_entry, property_faultcodens_name, &property_faultcodens_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_faultcodens_name); + zend_string_release_ex(property_faultcodens_name, true); zval property_faultactor_default_value; ZVAL_NULL(&property_faultactor_default_value); - zend_string *property_faultactor_name = zend_string_init("faultactor", sizeof("faultactor") - 1, 1); + zend_string *property_faultactor_name = zend_string_init("faultactor", sizeof("faultactor") - 1, true); zend_declare_typed_property(class_entry, property_faultactor_name, &property_faultactor_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_faultactor_name); + zend_string_release_ex(property_faultactor_name, true); zval property_detail_default_value; ZVAL_NULL(&property_detail_default_value); - zend_string *property_detail_name = zend_string_init("detail", sizeof("detail") - 1, 1); + zend_string *property_detail_name = zend_string_init("detail", sizeof("detail") - 1, true); zend_declare_typed_property(class_entry, property_detail_name, &property_detail_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); - zend_string_release(property_detail_name); + zend_string_release_ex(property_detail_name, true); zval property__name_default_value; ZVAL_NULL(&property__name_default_value); - zend_string *property__name_name = zend_string_init("_name", sizeof("_name") - 1, 1); + zend_string *property__name_name = zend_string_init("_name", sizeof("_name") - 1, true); zend_declare_typed_property(class_entry, property__name_name, &property__name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__name_name); + zend_string_release_ex(property__name_name, true); zval property_headerfault_default_value; ZVAL_NULL(&property_headerfault_default_value); - zend_string *property_headerfault_name = zend_string_init("headerfault", sizeof("headerfault") - 1, 1); + zend_string *property_headerfault_name = zend_string_init("headerfault", sizeof("headerfault") - 1, true); zend_declare_typed_property(class_entry, property_headerfault_name, &property_headerfault_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); - zend_string_release(property_headerfault_name); + zend_string_release_ex(property_headerfault_name, true); zval property_lang_default_value; ZVAL_EMPTY_STRING(&property_lang_default_value); - zend_string *property_lang_name = zend_string_init("lang", sizeof("lang") - 1, 1); + zend_string *property_lang_name = zend_string_init("lang", sizeof("lang") - 1, true); zend_declare_typed_property(class_entry, property_lang_name, &property_lang_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_lang_name); + zend_string_release_ex(property_lang_name, true); return class_entry; } @@ -464,39 +473,39 @@ static zend_class_entry *register_class_SoapVar(void) zval property_enc_type_default_value; ZVAL_UNDEF(&property_enc_type_default_value); - zend_string *property_enc_type_name = zend_string_init("enc_type", sizeof("enc_type") - 1, 1); + zend_string *property_enc_type_name = zend_string_init("enc_type", sizeof("enc_type") - 1, true); zend_declare_typed_property(class_entry, property_enc_type_name, &property_enc_type_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_enc_type_name); + zend_string_release_ex(property_enc_type_name, true); zval property_enc_value_default_value; ZVAL_NULL(&property_enc_value_default_value); - zend_string *property_enc_value_name = zend_string_init("enc_value", sizeof("enc_value") - 1, 1); + zend_string *property_enc_value_name = zend_string_init("enc_value", sizeof("enc_value") - 1, true); zend_declare_typed_property(class_entry, property_enc_value_name, &property_enc_value_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); - zend_string_release(property_enc_value_name); + zend_string_release_ex(property_enc_value_name, true); zval property_enc_stype_default_value; ZVAL_NULL(&property_enc_stype_default_value); - zend_string *property_enc_stype_name = zend_string_init("enc_stype", sizeof("enc_stype") - 1, 1); + zend_string *property_enc_stype_name = zend_string_init("enc_stype", sizeof("enc_stype") - 1, true); zend_declare_typed_property(class_entry, property_enc_stype_name, &property_enc_stype_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_enc_stype_name); + zend_string_release_ex(property_enc_stype_name, true); zval property_enc_ns_default_value; ZVAL_NULL(&property_enc_ns_default_value); - zend_string *property_enc_ns_name = zend_string_init("enc_ns", sizeof("enc_ns") - 1, 1); + zend_string *property_enc_ns_name = zend_string_init("enc_ns", sizeof("enc_ns") - 1, true); zend_declare_typed_property(class_entry, property_enc_ns_name, &property_enc_ns_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_enc_ns_name); + zend_string_release_ex(property_enc_ns_name, true); zval property_enc_name_default_value; ZVAL_NULL(&property_enc_name_default_value); - zend_string *property_enc_name_name = zend_string_init("enc_name", sizeof("enc_name") - 1, 1); + zend_string *property_enc_name_name = zend_string_init("enc_name", sizeof("enc_name") - 1, true); zend_declare_typed_property(class_entry, property_enc_name_name, &property_enc_name_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_enc_name_name); + zend_string_release_ex(property_enc_name_name, true); zval property_enc_namens_default_value; ZVAL_NULL(&property_enc_namens_default_value); - zend_string *property_enc_namens_name = zend_string_init("enc_namens", sizeof("enc_namens") - 1, 1); + zend_string *property_enc_namens_name = zend_string_init("enc_namens", sizeof("enc_namens") - 1, true); zend_declare_typed_property(class_entry, property_enc_namens_name, &property_enc_namens_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_enc_namens_name); + zend_string_release_ex(property_enc_namens_name, true); return class_entry; } @@ -510,10 +519,10 @@ static zend_class_entry *register_class_SoapServer(void) zval property___soap_fault_default_value; ZVAL_NULL(&property___soap_fault_default_value); - zend_string *property___soap_fault_name = zend_string_init("__soap_fault", sizeof("__soap_fault") - 1, 1); + zend_string *property___soap_fault_name = zend_string_init("__soap_fault", sizeof("__soap_fault") - 1, true); zend_string *property___soap_fault_class_SoapFault = zend_string_init("SoapFault", sizeof("SoapFault")-1, 1); zend_declare_typed_property(class_entry, property___soap_fault_name, &property___soap_fault_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property___soap_fault_class_SoapFault, 0, MAY_BE_NULL)); - zend_string_release(property___soap_fault_name); + zend_string_release_ex(property___soap_fault_name, true); return class_entry; } @@ -527,27 +536,27 @@ static zend_class_entry *register_class_SoapClient(void) zval property_uri_default_value; ZVAL_NULL(&property_uri_default_value); - zend_string *property_uri_name = zend_string_init("uri", sizeof("uri") - 1, 1); + zend_string *property_uri_name = zend_string_init("uri", sizeof("uri") - 1, true); zend_declare_typed_property(class_entry, property_uri_name, &property_uri_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_uri_name); + zend_string_release_ex(property_uri_name, true); zval property_style_default_value; ZVAL_NULL(&property_style_default_value); - zend_string *property_style_name = zend_string_init("style", sizeof("style") - 1, 1); + zend_string *property_style_name = zend_string_init("style", sizeof("style") - 1, true); zend_declare_typed_property(class_entry, property_style_name, &property_style_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property_style_name); + zend_string_release_ex(property_style_name, true); zval property_use_default_value; ZVAL_NULL(&property_use_default_value); - zend_string *property_use_name = zend_string_init("use", sizeof("use") - 1, 1); + zend_string *property_use_name = zend_string_init("use", sizeof("use") - 1, true); zend_declare_typed_property(class_entry, property_use_name, &property_use_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property_use_name); + zend_string_release_ex(property_use_name, true); zval property_location_default_value; ZVAL_NULL(&property_location_default_value); - zend_string *property_location_name = zend_string_init("location", sizeof("location") - 1, 1); + zend_string *property_location_name = zend_string_init("location", sizeof("location") - 1, true); zend_declare_typed_property(class_entry, property_location_name, &property_location_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_location_name); + zend_string_release_ex(property_location_name, true); zval property_trace_default_value; ZVAL_FALSE(&property_trace_default_value); @@ -555,192 +564,186 @@ static zend_class_entry *register_class_SoapClient(void) zval property_compression_default_value; ZVAL_NULL(&property_compression_default_value); - zend_string *property_compression_name = zend_string_init("compression", sizeof("compression") - 1, 1); + zend_string *property_compression_name = zend_string_init("compression", sizeof("compression") - 1, true); zend_declare_typed_property(class_entry, property_compression_name, &property_compression_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property_compression_name); + zend_string_release_ex(property_compression_name, true); zval property_sdl_default_value; ZVAL_NULL(&property_sdl_default_value); - zend_string *property_sdl_name = zend_string_init("sdl", sizeof("sdl") - 1, 1); + zend_string *property_sdl_name = zend_string_init("sdl", sizeof("sdl") - 1, true); zend_string *property_sdl_class_Soap_Sdl = zend_string_init("Soap\\Sdl", sizeof("Soap\\Sdl")-1, 1); zend_declare_typed_property(class_entry, property_sdl_name, &property_sdl_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_sdl_class_Soap_Sdl, 0, MAY_BE_NULL)); - zend_string_release(property_sdl_name); - - zval property_typemap_default_value; - ZVAL_NULL(&property_typemap_default_value); - zend_string *property_typemap_name = zend_string_init("typemap", sizeof("typemap") - 1, 1); - zend_declare_typed_property(class_entry, property_typemap_name, &property_typemap_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release(property_typemap_name); + zend_string_release_ex(property_sdl_name, true); zval property_httpsocket_default_value; ZVAL_NULL(&property_httpsocket_default_value); - zend_string *property_httpsocket_name = zend_string_init("httpsocket", sizeof("httpsocket") - 1, 1); + zend_string *property_httpsocket_name = zend_string_init("httpsocket", sizeof("httpsocket") - 1, true); zend_declare_typed_property(class_entry, property_httpsocket_name, &property_httpsocket_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); - zend_string_release(property_httpsocket_name); + zend_string_release_ex(property_httpsocket_name, true); zval property_httpurl_default_value; ZVAL_NULL(&property_httpurl_default_value); - zend_string *property_httpurl_name = zend_string_init("httpurl", sizeof("httpurl") - 1, 1); + zend_string *property_httpurl_name = zend_string_init("httpurl", sizeof("httpurl") - 1, true); zend_string *property_httpurl_class_Soap_Url = zend_string_init("Soap\\\125rl", sizeof("Soap\\\125rl")-1, 1); zend_declare_typed_property(class_entry, property_httpurl_name, &property_httpurl_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_httpurl_class_Soap_Url, 0, MAY_BE_NULL)); - zend_string_release(property_httpurl_name); + zend_string_release_ex(property_httpurl_name, true); zval property__login_default_value; ZVAL_NULL(&property__login_default_value); - zend_string *property__login_name = zend_string_init("_login", sizeof("_login") - 1, 1); + zend_string *property__login_name = zend_string_init("_login", sizeof("_login") - 1, true); zend_declare_typed_property(class_entry, property__login_name, &property__login_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__login_name); + zend_string_release_ex(property__login_name, true); zval property__password_default_value; ZVAL_NULL(&property__password_default_value); - zend_string *property__password_name = zend_string_init("_password", sizeof("_password") - 1, 1); + zend_string *property__password_name = zend_string_init("_password", sizeof("_password") - 1, true); zend_declare_typed_property(class_entry, property__password_name, &property__password_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__password_name); + zend_string_release_ex(property__password_name, true); zval property__use_digest_default_value; ZVAL_FALSE(&property__use_digest_default_value); - zend_string *property__use_digest_name = zend_string_init("_use_digest", sizeof("_use_digest") - 1, 1); + zend_string *property__use_digest_name = zend_string_init("_use_digest", sizeof("_use_digest") - 1, true); zend_declare_typed_property(class_entry, property__use_digest_name, &property__use_digest_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property__use_digest_name); + zend_string_release_ex(property__use_digest_name, true); zval property__digest_default_value; ZVAL_NULL(&property__digest_default_value); - zend_string *property__digest_name = zend_string_init("_digest", sizeof("_digest") - 1, 1); + zend_string *property__digest_name = zend_string_init("_digest", sizeof("_digest") - 1, true); zend_declare_typed_property(class_entry, property__digest_name, &property__digest_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__digest_name); + zend_string_release_ex(property__digest_name, true); zval property__proxy_host_default_value; ZVAL_NULL(&property__proxy_host_default_value); - zend_string *property__proxy_host_name = zend_string_init("_proxy_host", sizeof("_proxy_host") - 1, 1); + zend_string *property__proxy_host_name = zend_string_init("_proxy_host", sizeof("_proxy_host") - 1, true); zend_declare_typed_property(class_entry, property__proxy_host_name, &property__proxy_host_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__proxy_host_name); + zend_string_release_ex(property__proxy_host_name, true); zval property__proxy_port_default_value; ZVAL_NULL(&property__proxy_port_default_value); - zend_string *property__proxy_port_name = zend_string_init("_proxy_port", sizeof("_proxy_port") - 1, 1); + zend_string *property__proxy_port_name = zend_string_init("_proxy_port", sizeof("_proxy_port") - 1, true); zend_declare_typed_property(class_entry, property__proxy_port_name, &property__proxy_port_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property__proxy_port_name); + zend_string_release_ex(property__proxy_port_name, true); zval property__proxy_login_default_value; ZVAL_NULL(&property__proxy_login_default_value); - zend_string *property__proxy_login_name = zend_string_init("_proxy_login", sizeof("_proxy_login") - 1, 1); + zend_string *property__proxy_login_name = zend_string_init("_proxy_login", sizeof("_proxy_login") - 1, true); zend_declare_typed_property(class_entry, property__proxy_login_name, &property__proxy_login_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__proxy_login_name); + zend_string_release_ex(property__proxy_login_name, true); zval property__proxy_password_default_value; ZVAL_NULL(&property__proxy_password_default_value); - zend_string *property__proxy_password_name = zend_string_init("_proxy_password", sizeof("_proxy_password") - 1, 1); + zend_string *property__proxy_password_name = zend_string_init("_proxy_password", sizeof("_proxy_password") - 1, true); zend_declare_typed_property(class_entry, property__proxy_password_name, &property__proxy_password_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__proxy_password_name); + zend_string_release_ex(property__proxy_password_name, true); zval property__exceptions_default_value; ZVAL_TRUE(&property__exceptions_default_value); - zend_string *property__exceptions_name = zend_string_init("_exceptions", sizeof("_exceptions") - 1, 1); + zend_string *property__exceptions_name = zend_string_init("_exceptions", sizeof("_exceptions") - 1, true); zend_declare_typed_property(class_entry, property__exceptions_name, &property__exceptions_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property__exceptions_name); + zend_string_release_ex(property__exceptions_name, true); zval property__encoding_default_value; ZVAL_NULL(&property__encoding_default_value); - zend_string *property__encoding_name = zend_string_init("_encoding", sizeof("_encoding") - 1, 1); + zend_string *property__encoding_name = zend_string_init("_encoding", sizeof("_encoding") - 1, true); zend_declare_typed_property(class_entry, property__encoding_name, &property__encoding_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__encoding_name); + zend_string_release_ex(property__encoding_name, true); zval property__classmap_default_value; ZVAL_NULL(&property__classmap_default_value); - zend_string *property__classmap_name = zend_string_init("_classmap", sizeof("_classmap") - 1, 1); + zend_string *property__classmap_name = zend_string_init("_classmap", sizeof("_classmap") - 1, true); zend_declare_typed_property(class_entry, property__classmap_name, &property__classmap_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release(property__classmap_name); + zend_string_release_ex(property__classmap_name, true); zval property__features_default_value; ZVAL_NULL(&property__features_default_value); - zend_string *property__features_name = zend_string_init("_features", sizeof("_features") - 1, 1); + zend_string *property__features_name = zend_string_init("_features", sizeof("_features") - 1, true); zend_declare_typed_property(class_entry, property__features_name, &property__features_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property__features_name); + zend_string_release_ex(property__features_name, true); zval property__connection_timeout_default_value; ZVAL_LONG(&property__connection_timeout_default_value, 0); - zend_string *property__connection_timeout_name = zend_string_init("_connection_timeout", sizeof("_connection_timeout") - 1, 1); + zend_string *property__connection_timeout_name = zend_string_init("_connection_timeout", sizeof("_connection_timeout") - 1, true); zend_declare_typed_property(class_entry, property__connection_timeout_name, &property__connection_timeout_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property__connection_timeout_name); + zend_string_release_ex(property__connection_timeout_name, true); zval property__stream_context_default_value; ZVAL_NULL(&property__stream_context_default_value); - zend_string *property__stream_context_name = zend_string_init("_stream_context", sizeof("_stream_context") - 1, 1); + zend_string *property__stream_context_name = zend_string_init("_stream_context", sizeof("_stream_context") - 1, true); zend_declare_typed_property(class_entry, property__stream_context_name, &property__stream_context_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); - zend_string_release(property__stream_context_name); + zend_string_release_ex(property__stream_context_name, true); zval property__user_agent_default_value; ZVAL_NULL(&property__user_agent_default_value); - zend_string *property__user_agent_name = zend_string_init("_user_agent", sizeof("_user_agent") - 1, 1); + zend_string *property__user_agent_name = zend_string_init("_user_agent", sizeof("_user_agent") - 1, true); zend_declare_typed_property(class_entry, property__user_agent_name, &property__user_agent_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property__user_agent_name); + zend_string_release_ex(property__user_agent_name, true); zval property__keep_alive_default_value; ZVAL_TRUE(&property__keep_alive_default_value); - zend_string *property__keep_alive_name = zend_string_init("_keep_alive", sizeof("_keep_alive") - 1, 1); + zend_string *property__keep_alive_name = zend_string_init("_keep_alive", sizeof("_keep_alive") - 1, true); zend_declare_typed_property(class_entry, property__keep_alive_name, &property__keep_alive_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property__keep_alive_name); + zend_string_release_ex(property__keep_alive_name, true); zval property__ssl_method_default_value; ZVAL_NULL(&property__ssl_method_default_value); - zend_string *property__ssl_method_name = zend_string_init("_ssl_method", sizeof("_ssl_method") - 1, 1); + zend_string *property__ssl_method_name = zend_string_init("_ssl_method", sizeof("_ssl_method") - 1, true); zend_declare_typed_property(class_entry, property__ssl_method_name, &property__ssl_method_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property__ssl_method_name); + zend_string_release_ex(property__ssl_method_name, true); zval property__soap_version_default_value; ZVAL_UNDEF(&property__soap_version_default_value); - zend_string *property__soap_version_name = zend_string_init("_soap_version", sizeof("_soap_version") - 1, 1); + zend_string *property__soap_version_name = zend_string_init("_soap_version", sizeof("_soap_version") - 1, true); zend_declare_typed_property(class_entry, property__soap_version_name, &property__soap_version_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property__soap_version_name); + zend_string_release_ex(property__soap_version_name, true); zval property__use_proxy_default_value; ZVAL_NULL(&property__use_proxy_default_value); - zend_string *property__use_proxy_name = zend_string_init("_use_proxy", sizeof("_use_proxy") - 1, 1); + zend_string *property__use_proxy_name = zend_string_init("_use_proxy", sizeof("_use_proxy") - 1, true); zend_declare_typed_property(class_entry, property__use_proxy_name, &property__use_proxy_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property__use_proxy_name); + zend_string_release_ex(property__use_proxy_name, true); zval property__cookies_default_value; ZVAL_EMPTY_ARRAY(&property__cookies_default_value); - zend_string *property__cookies_name = zend_string_init("_cookies", sizeof("_cookies") - 1, 1); + zend_string *property__cookies_name = zend_string_init("_cookies", sizeof("_cookies") - 1, true); zend_declare_typed_property(class_entry, property__cookies_name, &property__cookies_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release(property__cookies_name); + zend_string_release_ex(property__cookies_name, true); zval property___default_headers_default_value; ZVAL_NULL(&property___default_headers_default_value); - zend_string *property___default_headers_name = zend_string_init("__default_headers", sizeof("__default_headers") - 1, 1); + zend_string *property___default_headers_name = zend_string_init("__default_headers", sizeof("__default_headers") - 1, true); zend_declare_typed_property(class_entry, property___default_headers_name, &property___default_headers_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release(property___default_headers_name); + zend_string_release_ex(property___default_headers_name, true); zval property___soap_fault_default_value; ZVAL_NULL(&property___soap_fault_default_value); - zend_string *property___soap_fault_name = zend_string_init("__soap_fault", sizeof("__soap_fault") - 1, 1); + zend_string *property___soap_fault_name = zend_string_init("__soap_fault", sizeof("__soap_fault") - 1, true); zend_string *property___soap_fault_class_SoapFault = zend_string_init("SoapFault", sizeof("SoapFault")-1, 1); zend_declare_typed_property(class_entry, property___soap_fault_name, &property___soap_fault_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property___soap_fault_class_SoapFault, 0, MAY_BE_NULL)); - zend_string_release(property___soap_fault_name); + zend_string_release_ex(property___soap_fault_name, true); zval property___last_request_default_value; ZVAL_NULL(&property___last_request_default_value); - zend_string *property___last_request_name = zend_string_init("__last_request", sizeof("__last_request") - 1, 1); + zend_string *property___last_request_name = zend_string_init("__last_request", sizeof("__last_request") - 1, true); zend_declare_typed_property(class_entry, property___last_request_name, &property___last_request_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property___last_request_name); + zend_string_release_ex(property___last_request_name, true); zval property___last_response_default_value; ZVAL_NULL(&property___last_response_default_value); - zend_string *property___last_response_name = zend_string_init("__last_response", sizeof("__last_response") - 1, 1); + zend_string *property___last_response_name = zend_string_init("__last_response", sizeof("__last_response") - 1, true); zend_declare_typed_property(class_entry, property___last_response_name, &property___last_response_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property___last_response_name); + zend_string_release_ex(property___last_response_name, true); zval property___last_request_headers_default_value; ZVAL_NULL(&property___last_request_headers_default_value); - zend_string *property___last_request_headers_name = zend_string_init("__last_request_headers", sizeof("__last_request_headers") - 1, 1); + zend_string *property___last_request_headers_name = zend_string_init("__last_request_headers", sizeof("__last_request_headers") - 1, true); zend_declare_typed_property(class_entry, property___last_request_headers_name, &property___last_request_headers_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property___last_request_headers_name); + zend_string_release_ex(property___last_request_headers_name, true); zval property___last_response_headers_default_value; ZVAL_NULL(&property___last_response_headers_default_value); - zend_string *property___last_response_headers_name = zend_string_init("__last_response_headers", sizeof("__last_response_headers") - 1, 1); + zend_string *property___last_response_headers_name = zend_string_init("__last_response_headers", sizeof("__last_response_headers") - 1, true); zend_declare_typed_property(class_entry, property___last_response_headers_name, &property___last_response_headers_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property___last_response_headers_name); + zend_string_release_ex(property___last_response_headers_name, true); return class_entry; } diff --git a/ext/soap/tests/GHSA-85c2-q967-79q5.phpt b/ext/soap/tests/GHSA-85c2-q967-79q5.phpt new file mode 100644 index 000000000000..8bcac26ad187 --- /dev/null +++ b/ext/soap/tests/GHSA-85c2-q967-79q5.phpt @@ -0,0 +1,61 @@ +--TEST-- +GHSA-85c2-q967-79q5: Stale SOAP_GLOBAL(ref_map) pointer with Apache Map +--CREDITS-- +brettgervasoni +--EXTENSIONS-- +soap +--FILE-- + + + + + + + + foo + bar + + + foo + baz + + + + + + +XML; + +$s = new SoapServer(null, ['uri' => 'urn:a']); +$s->setClass(Handler::class); +$s->handle($envelope); +var_dump($result); + +?> +--EXPECTF-- + + +array(2) { + [0]=> + array(1) { + ["foo"]=> + string(3) "baz" + } + [1]=> + object(stdClass)#%d (1) { + ["object"]=> + string(3) "bar" + } +} diff --git a/ext/soap/tests/GHSA-hmxp-6pc4-f3vv.phpt b/ext/soap/tests/GHSA-hmxp-6pc4-f3vv.phpt new file mode 100644 index 000000000000..e46ab2e4607d --- /dev/null +++ b/ext/soap/tests/GHSA-hmxp-6pc4-f3vv.phpt @@ -0,0 +1,39 @@ +--TEST-- +GHSA-hmxp-6pc4-f3vv: Null pointer dereference on missing Apache map value +--CREDITS-- +Ilia Alshanetsky (iliaal) +--EXTENSIONS-- +soap +--FILE-- + + + + + + + hello + + + + +XML; + +$server = new SoapServer(null, [ + 'uri' => 'urn:test', + 'typemap' => [['type_name' => 'anything']], +]); +$server->addFunction('test'); +function test($m) { return null; } +$server->handle($request); + +?> +--EXPECT-- + +SOAP-ENV:ServerSOAP-ERROR: Encoding: Can't decode apache map, missing value diff --git a/ext/soap/tests/GHSA-m33r-qmcv-p97q.phpt b/ext/soap/tests/GHSA-m33r-qmcv-p97q.phpt new file mode 100644 index 000000000000..bcf441ccd18a --- /dev/null +++ b/ext/soap/tests/GHSA-m33r-qmcv-p97q.phpt @@ -0,0 +1,58 @@ +--TEST-- +GHSA-m33r-qmcv-p97q: Use-after-free after header parsing failure with SOAP_PERSISTENCE_SESSION +--CREDITS-- +Ilia Alshanetsky (iliaal) +--EXTENSIONS-- +soap +session +--FILE-- + 'urn:a']); +$srv->setClass(Handler::class); +$srv->setPersistence(SOAP_PERSISTENCE_SESSION); + +$srv->handle(<< + + + + + + + + +XML); + +$srv->handle(<< + + + + + + + + +XML); + +?> +--EXPECT-- + +SOAP-ENV:Serverdenied + +SOAP-ENV:Serverdenied diff --git a/ext/soap/tests/SoapServer/__getLastResponse.phpt b/ext/soap/tests/SoapServer/__getLastResponse.phpt index 83c20d3c3a49..900a88035973 100644 --- a/ext/soap/tests/SoapServer/__getLastResponse.phpt +++ b/ext/soap/tests/SoapServer/__getLastResponse.phpt @@ -18,7 +18,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction("f"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/any.phpt b/ext/soap/tests/any.phpt index 6b08e395c2b1..c25748997aba 100644 --- a/ext/soap/tests/any.phpt +++ b/ext/soap/tests/any.phpt @@ -33,7 +33,7 @@ class TestSoapClient extends SoapClient { $this->server->addFunction('echoAnyElement'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug28969.phpt b/ext/soap/tests/bugs/bug28969.phpt index 71de59939f8d..661e1fc82277 100644 --- a/ext/soap/tests/bugs/bug28969.phpt +++ b/ext/soap/tests/bugs/bug28969.phpt @@ -18,7 +18,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction('test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug29795.phpt b/ext/soap/tests/bugs/bug29795.phpt index 1db3226ab171..395d3b6c7ec6 100644 --- a/ext/soap/tests/bugs/bug29795.phpt +++ b/ext/soap/tests/bugs/bug29795.phpt @@ -12,7 +12,7 @@ class LocalSoapClient extends SoapClient { parent::__construct($wsdl, $options); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { return <<server->addFunction('EchoString'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug29844.phpt b/ext/soap/tests/bugs/bug29844.phpt index 7f5178ec6db7..c98c3041bbb6 100644 --- a/ext/soap/tests/bugs/bug29844.phpt +++ b/ext/soap/tests/bugs/bug29844.phpt @@ -22,7 +22,7 @@ class LocalSoapClient extends SoapClient { $this->server->setClass('hello_world'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug30045.phpt b/ext/soap/tests/bugs/bug30045.phpt index a84b73a7830f..7dac3d026631 100644 --- a/ext/soap/tests/bugs/bug30045.phpt +++ b/ext/soap/tests/bugs/bug30045.phpt @@ -21,7 +21,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction('foo'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { $xml = simplexml_load_string($request); echo $xml->children("http://schemas.xmlsoap.org/soap/envelope/")->Body->children("http://test-uri")->children()->param1->asXML(),"\n"; unset($xml); diff --git a/ext/soap/tests/bugs/bug30106.phpt b/ext/soap/tests/bugs/bug30106.phpt index d924a5bb8b32..0a891b4cb59d 100644 --- a/ext/soap/tests/bugs/bug30106.phpt +++ b/ext/soap/tests/bugs/bug30106.phpt @@ -21,7 +21,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction("getContinentList"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo $request; ob_start(); $this->server->handle($request); diff --git a/ext/soap/tests/bugs/bug30175.phpt b/ext/soap/tests/bugs/bug30175.phpt index ab0ab5cc11c7..9f17f60162dd 100644 --- a/ext/soap/tests/bugs/bug30175.phpt +++ b/ext/soap/tests/bugs/bug30175.phpt @@ -9,7 +9,7 @@ soap.wsdl_cache_enabled=0 class LocalSoapClient extends SoapClient { - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { return << server->addFunction('test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug31695.phpt b/ext/soap/tests/bugs/bug31695.phpt index ba8a6ae00061..0d95cc6cfe67 100644 --- a/ext/soap/tests/bugs/bug31695.phpt +++ b/ext/soap/tests/bugs/bug31695.phpt @@ -19,7 +19,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction("Test"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo "$location\n"; ob_start(); $this->server->handle($request); diff --git a/ext/soap/tests/bugs/bug31755.phpt b/ext/soap/tests/bugs/bug31755.phpt index cf8987db3ee1..c4b2c622b6af 100644 --- a/ext/soap/tests/bugs/bug31755.phpt +++ b/ext/soap/tests/bugs/bug31755.phpt @@ -5,7 +5,7 @@ soap --FILE-- server->addFunction('test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug32941.phpt b/ext/soap/tests/bugs/bug32941.phpt index 0b4ac3ab30ef..85f4434f0659 100644 --- a/ext/soap/tests/bugs/bug32941.phpt +++ b/ext/soap/tests/bugs/bug32941.phpt @@ -5,7 +5,7 @@ soap --FILE-- server->addFunction('EchoString'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug34643.phpt b/ext/soap/tests/bugs/bug34643.phpt index 5c23cbd7c7b3..27542c2c2870 100644 --- a/ext/soap/tests/bugs/bug34643.phpt +++ b/ext/soap/tests/bugs/bug34643.phpt @@ -23,7 +23,7 @@ class LocalSoapClient extends SoapClient { $this->server->setClass('fp'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug35142.phpt b/ext/soap/tests/bugs/bug35142.phpt index 5f46bbf84113..d596c5eb5443 100644 --- a/ext/soap/tests/bugs/bug35142.phpt +++ b/ext/soap/tests/bugs/bug35142.phpt @@ -25,7 +25,7 @@ class TestSoapClient extends SoapClient { $this->server->addFunction('PostEvents'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo "$request\n"; ob_start(); $this->server->handle($request); diff --git a/ext/soap/tests/bugs/bug35273.phpt b/ext/soap/tests/bugs/bug35273.phpt index 93e54626c526..c35d545851fe 100644 --- a/ext/soap/tests/bugs/bug35273.phpt +++ b/ext/soap/tests/bugs/bug35273.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- server->addFunction('PostEvents'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo "$request\n"; $this->server->handle($request); return $response; diff --git a/ext/soap/tests/bugs/bug36226.phpt b/ext/soap/tests/bugs/bug36226.phpt index 38ece5d0b87a..c1d86ce4b3d9 100644 --- a/ext/soap/tests/bugs/bug36226.phpt +++ b/ext/soap/tests/bugs/bug36226.phpt @@ -25,7 +25,7 @@ class TestSoapClient extends SoapClient { $this->server->addFunction('PostEvents'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo "$request\n"; ob_start(); $this->server->handle($request); diff --git a/ext/soap/tests/bugs/bug36999.phpt b/ext/soap/tests/bugs/bug36999.phpt index 04673649da23..d4ed65621e2a 100644 --- a/ext/soap/tests/bugs/bug36999.phpt +++ b/ext/soap/tests/bugs/bug36999.phpt @@ -20,7 +20,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction('echoLong'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug37083.phpt b/ext/soap/tests/bugs/bug37083.phpt index 441b51022b8a..8e5326e03439 100644 --- a/ext/soap/tests/bugs/bug37083.phpt +++ b/ext/soap/tests/bugs/bug37083.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache=3 --FILE-- diff --git a/ext/soap/tests/bugs/bug38004.phpt b/ext/soap/tests/bugs/bug38004.phpt index 7953487ab1ec..3ca5aeda814f 100644 --- a/ext/soap/tests/bugs/bug38004.phpt +++ b/ext/soap/tests/bugs/bug38004.phpt @@ -21,7 +21,7 @@ class TestSoapClient extends SoapClient { $this->server->addFunction('Test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug38005.phpt b/ext/soap/tests/bugs/bug38005.phpt index ca3944ebc3db..dc2437baa9e1 100644 --- a/ext/soap/tests/bugs/bug38005.phpt +++ b/ext/soap/tests/bugs/bug38005.phpt @@ -19,7 +19,7 @@ class TestSoapClient extends SoapClient { $this->server->addFunction('Test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); @@ -42,4 +42,4 @@ echo($client->__getLastResponse()); --EXPECT-- This is our fault: -TestThis is our fault: Ä +TestThis is our fault: Ä diff --git a/ext/soap/tests/bugs/bug38055.phpt b/ext/soap/tests/bugs/bug38055.phpt index b066bf892e37..ad951b537f23 100644 --- a/ext/soap/tests/bugs/bug38055.phpt +++ b/ext/soap/tests/bugs/bug38055.phpt @@ -22,7 +22,7 @@ class TestSoapClient extends SoapClient { $this->server->addFunction('Test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug38067.phpt b/ext/soap/tests/bugs/bug38067.phpt index 2f25a87a1cf3..962e0c29d253 100644 --- a/ext/soap/tests/bugs/bug38067.phpt +++ b/ext/soap/tests/bugs/bug38067.phpt @@ -21,7 +21,7 @@ class TestSoapClient extends SoapClient { $this->server->addFunction('Test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = 0, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug38536.phpt b/ext/soap/tests/bugs/bug38536.phpt index 5865e6a904ab..c64772ccbc73 100644 --- a/ext/soap/tests/bugs/bug38536.phpt +++ b/ext/soap/tests/bugs/bug38536.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- diff --git a/ext/soap/tests/bugs/bug39815.phpt b/ext/soap/tests/bugs/bug39815.phpt index 51178e40e5b8..0eeb18cf416f 100644 --- a/ext/soap/tests/bugs/bug39815.phpt +++ b/ext/soap/tests/bugs/bug39815.phpt @@ -23,7 +23,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction('test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug42692.phpt b/ext/soap/tests/bugs/bug42692.phpt index 5ed9254b5172..fe4840d9268d 100644 --- a/ext/soap/tests/bugs/bug42692.phpt +++ b/ext/soap/tests/bugs/bug42692.phpt @@ -19,7 +19,7 @@ class TestSoap extends SoapClient { $this->server->addFunction("checkAuth"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug43045.phpt b/ext/soap/tests/bugs/bug43045.phpt index f1e3af7765b6..79a746e1692f 100644 --- a/ext/soap/tests/bugs/bug43045.phpt +++ b/ext/soap/tests/bugs/bug43045.phpt @@ -16,7 +16,7 @@ class TestSoapClient extends SoapClient { $this->server = new SoapServer($wsdl, $options); $this->server->addFunction('test'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug44882.phpt b/ext/soap/tests/bugs/bug44882.phpt index 73049602aaf9..93857fd3b27b 100644 --- a/ext/soap/tests/bugs/bug44882.phpt +++ b/ext/soap/tests/bugs/bug44882.phpt @@ -8,7 +8,7 @@ soap.wsdl_cache_enabled=0 diff --git a/ext/soap/tests/bugs/bug46419.phpt b/ext/soap/tests/bugs/bug46419.phpt index e12adfb08f20..090f4e08a5b8 100644 --- a/ext/soap/tests/bugs/bug46419.phpt +++ b/ext/soap/tests/bugs/bug46419.phpt @@ -17,7 +17,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction('bar'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug47021.phpt b/ext/soap/tests/bugs/bug47021.phpt index af12d7c4c39c..19b034b9eed2 100644 --- a/ext/soap/tests/bugs/bug47021.phpt +++ b/ext/soap/tests/bugs/bug47021.phpt @@ -57,9 +57,9 @@ $options = [ class BugSoapClient extends SoapClient { - public function __doRequest($request, $location, $action, $version, $one_way = null): string + public function __doRequest($request, $location, $action, $version, $one_way = null, ?string $uriParserClass = null): string { - $response = parent::__doRequest($request, $location, $action, $version, $one_way); + $response = parent::__doRequest($request, $location, $action, $version, $one_way, $uriParserClass); var_dump(strlen($response)); diff --git a/ext/soap/tests/bugs/bug50675.phpt b/ext/soap/tests/bugs/bug50675.phpt index e4bad4ffdfac..bc6a47577e2b 100644 --- a/ext/soap/tests/bugs/bug50675.phpt +++ b/ext/soap/tests/bugs/bug50675.phpt @@ -6,7 +6,7 @@ soap server->setObject(new testSoap()); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/bugs/bug54911.phpt b/ext/soap/tests/bugs/bug54911.phpt index 3247563dba49..0b1daec31345 100644 --- a/ext/soap/tests/bugs/bug54911.phpt +++ b/ext/soap/tests/bugs/bug54911.phpt @@ -5,7 +5,7 @@ soap --FILE-- diff --git a/ext/soap/tests/bugs/bug66049.phpt b/ext/soap/tests/bugs/bug66049.phpt index e48845a8a142..c31d0d7bcccd 100644 --- a/ext/soap/tests/bugs/bug66049.phpt +++ b/ext/soap/tests/bugs/bug66049.phpt @@ -15,7 +15,7 @@ function soap_string_from_xml($str) } class TestSoapClient extends SoapClient { - function __doRequest($request, $location, $action, $version, $one_way = 0): ?string { + function __doRequest($request, $location, $action, $version, $one_way = 0, ?string $uriParserClass = null): ?string { $res=' diff --git a/ext/soap/tests/bugs/bug68996.phpt b/ext/soap/tests/bugs/bug68996.phpt index bcc0e66cbebf..8aa858e6545e 100644 --- a/ext/soap/tests/bugs/bug68996.phpt +++ b/ext/soap/tests/bugs/bug68996.phpt @@ -56,4 +56,4 @@ handleFormatted($s, $HTTP_RAW_POST_DATA); some msg -some msg +some msg diff --git a/ext/soap/tests/bugs/bug69085.phpt b/ext/soap/tests/bugs/bug69085.phpt index 3572efa5e381..5974ce425319 100644 --- a/ext/soap/tests/bugs/bug69085.phpt +++ b/ext/soap/tests/bugs/bug69085.phpt @@ -9,7 +9,7 @@ soap.wsdl_cache_enabled=0 #[AllowDynamicProperties] class MySoapClient extends SoapClient { - public function __doRequest($request, $location, $action, $version, $one_way = 0): string { + public function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo $request, "\n"; return ''; } diff --git a/ext/soap/tests/bugs/bug69668.phpt b/ext/soap/tests/bugs/bug69668.phpt index b93163c164de..75fe05d5c2ed 100644 --- a/ext/soap/tests/bugs/bug69668.phpt +++ b/ext/soap/tests/bugs/bug69668.phpt @@ -5,7 +5,7 @@ soap --FILE-- '', 'uri' => 'http://example.org']) extends SoapClient { - public function __doRequest($request, $location, $action, $version, $one_way = 0): string { + public function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo $request; return ''; } diff --git a/ext/soap/tests/bugs/bug71996.phpt b/ext/soap/tests/bugs/bug71996.phpt index a6b2a71765b5..d78661ad3273 100644 --- a/ext/soap/tests/bugs/bug71996.phpt +++ b/ext/soap/tests/bugs/bug71996.phpt @@ -6,7 +6,7 @@ soap '', 'uri' => 'http://example.org']) extends SoapClient { - public function __doRequest($request, $location, $action, $version, $one_way = 0): string { + public function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo $request, "\n"; return ''; } diff --git a/ext/soap/tests/bugs/bug73237.phpt b/ext/soap/tests/bugs/bug73237.phpt index 643c99a8c22a..32ee05570635 100644 --- a/ext/soap/tests/bugs/bug73237.phpt +++ b/ext/soap/tests/bugs/bug73237.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- trueCampaignMember00vi0000011VMgeAAG00vi0000011VMgeAAG701i0000001lreeAAASent00Qi000001UrbYFEAZLeadangela.lansbury@cbs.com1 EOF; diff --git a/ext/soap/tests/bugs/bug77141.phpt b/ext/soap/tests/bugs/bug77141.phpt index 4a86b6af902b..67b07d598650 100644 --- a/ext/soap/tests/bugs/bug77141.phpt +++ b/ext/soap/tests/bugs/bug77141.phpt @@ -5,7 +5,7 @@ soap --FILE-- WSDL_CACHE_NONE, 'trace' => 1, ]) extends SoapClient { - public function __doRequest($request, $location, $action, $version, $one_way = 0): string { + public function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { echo $request, "\n"; return ''; } diff --git a/ext/soap/tests/bugs/cookie_parse_options_offset.phpt b/ext/soap/tests/bugs/cookie_parse_options_offset.phpt new file mode 100644 index 000000000000..988af9d31959 --- /dev/null +++ b/ext/soap/tests/bugs/cookie_parse_options_offset.phpt @@ -0,0 +1,61 @@ +--TEST-- +SOAP Set-Cookie option parsing starts at wrong offset due to variable shadowing +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- + + + + + + +XML; +PHP; + +php_cli_server_start($code, null, $args); + +$client = new SoapClient(null, [ + 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/test/endpoint', + 'uri' => 'test-uri', + 'trace' => true, +]); + +try { + $client->__soapCall("test", []); +} catch (SoapFault $e) { + // Response parsing may fault, cookies are still stored +} + +$cookies = $client->__getCookies(); + +// path should default to "/test" from the request URI, not "/evil" from the value. +echo "value: " . $cookies['sessionkey'][0] . "\n"; +echo "path: " . $cookies['sessionkey'][1] . "\n"; +echo "domain: " . $cookies['sessionkey'][2] . "\n"; +?> +--EXPECT-- +value: path=/evil +path: /test +domain: good.com diff --git a/ext/soap/tests/bugs/gh18640.phpt b/ext/soap/tests/bugs/gh18640.phpt new file mode 100644 index 000000000000..4e76d699b326 --- /dev/null +++ b/ext/soap/tests/bugs/gh18640.phpt @@ -0,0 +1,42 @@ +--TEST--- +GH-18640 (heap-use-after-free ext/soap/php_encoding.c:299:32 in soap_check_zval_ref) +--EXTENSIONS-- +soap +--CREDITS-- +YuanchengJiang +--FILE-- + 1, 'classmap' => ['logOnEvent' => 'LogOnEvent', 'events' => 'IVREvents']]); +$timestamp = new LogOnEvent(); // Bogus! +$logOffEvents[] = new LogOffEvent($timestamp); +$logOffEvents[] = new LogOffEvent($timestamp); +$ivrEvents = new IVREvents($logOffEvents); +$result = $soapClient->PostEvents($ivrEvents); + +class LogOffEvent { + function __construct(public $timestamp) { + $this->timestamp = $timestamp; + } +} + +class LogOnEvent { +} + +class IVREvents { + function __construct(public $logOffEvent) { + } +} +?> +--EXPECT-- +string(359) " + +" diff --git a/ext/soap/tests/bugs/gh18990.phpt b/ext/soap/tests/bugs/gh18990.phpt new file mode 100644 index 000000000000..30dbc0fe8b75 --- /dev/null +++ b/ext/soap/tests/bugs/gh18990.phpt @@ -0,0 +1,58 @@ +--TEST-- +GH-18990 (SOAP HTTP socket not closing on object destruction) +--INI-- +soap.wsdl_cache_enabled=0 +--EXTENSIONS-- +soap +--SKIPIF-- + +text0text1text2text3text4text5text6text7text8text9 +EOF; + +$responses = [ + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Connection: Keep-Alive\r\n". + "Content-Length: ".strlen($wsdl)."\r\n". + "\r\n". + $wsdl, + + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Connection: Keep-Alive\r\n". + "Content-Length: ".strlen($soap)."\r\n". + "\r\n". + $soap, +]; + +['pid' => $pid, 'uri' => $uri] = http_server($responses); + +$options = [ + 'trace' => false, + 'location' => $uri, +]; + +$cnt = count(get_resources()); + +$client = new SoapClient($uri, $options); + +var_dump(count($client->getItems())); + +http_server_kill($pid); + +unset($client); +var_dump(count(get_resources()) - $cnt); +?> +--EXPECT-- +int(10) +int(0) diff --git a/ext/soap/tests/bugs/gh19784.phpt b/ext/soap/tests/bugs/gh19784.phpt new file mode 100644 index 000000000000..1f718e74c459 --- /dev/null +++ b/ext/soap/tests/bugs/gh19784.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-19784 (SoapServer memory leak) +--EXTENSIONS-- +soap +--FILE-- + $v_5257); +new SoapServer('foobarbaz',$v_5238,); +?> +--EXPECTF-- + +%s%a diff --git a/ext/soap/tests/bugs/gh20011.phpt b/ext/soap/tests/bugs/gh20011.phpt new file mode 100644 index 000000000000..7cccc7619212 --- /dev/null +++ b/ext/soap/tests/bugs/gh20011.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-20011 (Array of SoapVar of unknown type causes crash) +--EXTENSIONS-- +soap +--FILE-- + 'test://', 'uri' => 'http://soapinterop.org/']); +$client->echoStringArray($array); +?> +--EXPECT-- + +test string diff --git a/ext/soap/tests/bugs/gh21421.phpt b/ext/soap/tests/bugs/gh21421.phpt new file mode 100644 index 000000000000..1b8bb3be716f --- /dev/null +++ b/ext/soap/tests/bugs/gh21421.phpt @@ -0,0 +1,90 @@ +--TEST-- +GH-21421 (SoapClient typemap property breaks engine assumptions) +--EXTENSIONS-- +soap +--FILE-- + 'http://schemas.nothing.com', +'location' => 'test://', +'typemap' => array(array("type_ns" => "http://schemas.nothing.com", +"type_name" => "book", +"from_xml" => "book_from_xml")) +); +$client = new SoapClient(NULL, $options); +var_dump($client); +?> +--EXPECTF-- +object(SoapClient)#%d (35) { + ["uri":"SoapClient":private]=> + string(26) "http://schemas.nothing.com" + ["style":"SoapClient":private]=> + NULL + ["use":"SoapClient":private]=> + NULL + ["location":"SoapClient":private]=> + string(7) "test://" + ["trace":"SoapClient":private]=> + bool(false) + ["compression":"SoapClient":private]=> + NULL + ["sdl":"SoapClient":private]=> + NULL + ["httpsocket":"SoapClient":private]=> + NULL + ["httpurl":"SoapClient":private]=> + NULL + ["_login":"SoapClient":private]=> + NULL + ["_password":"SoapClient":private]=> + NULL + ["_use_digest":"SoapClient":private]=> + bool(false) + ["_digest":"SoapClient":private]=> + NULL + ["_proxy_host":"SoapClient":private]=> + NULL + ["_proxy_port":"SoapClient":private]=> + NULL + ["_proxy_login":"SoapClient":private]=> + NULL + ["_proxy_password":"SoapClient":private]=> + NULL + ["_exceptions":"SoapClient":private]=> + bool(true) + ["_encoding":"SoapClient":private]=> + NULL + ["_classmap":"SoapClient":private]=> + NULL + ["_features":"SoapClient":private]=> + NULL + ["_connection_timeout":"SoapClient":private]=> + int(0) + ["_stream_context":"SoapClient":private]=> + resource(%d) of type (stream-context) + ["_user_agent":"SoapClient":private]=> + NULL + ["_keep_alive":"SoapClient":private]=> + bool(true) + ["_ssl_method":"SoapClient":private]=> + NULL + ["_soap_version":"SoapClient":private]=> + int(1) + ["_use_proxy":"SoapClient":private]=> + NULL + ["_cookies":"SoapClient":private]=> + array(0) { + } + ["__default_headers":"SoapClient":private]=> + NULL + ["__soap_fault":"SoapClient":private]=> + NULL + ["__last_request":"SoapClient":private]=> + NULL + ["__last_response":"SoapClient":private]=> + NULL + ["__last_request_headers":"SoapClient":private]=> + NULL + ["__last_response_headers":"SoapClient":private]=> + NULL +} diff --git a/ext/soap/tests/bugs/segfault_assertion_props.phpt b/ext/soap/tests/bugs/segfault_assertion_props.phpt index 75cefa57642e..f11ea61f7cd3 100644 --- a/ext/soap/tests/bugs/segfault_assertion_props.phpt +++ b/ext/soap/tests/bugs/segfault_assertion_props.phpt @@ -7,7 +7,7 @@ soap --FILE-- diff --git a/ext/soap/tests/classmap002.phpt b/ext/soap/tests/classmap002.phpt index 626b9f8ff66b..13c82c1b5383 100644 --- a/ext/soap/tests/classmap002.phpt +++ b/ext/soap/tests/classmap002.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- diff --git a/ext/soap/tests/classmap003.phpt b/ext/soap/tests/classmap003.phpt index 322445fa16af..31839f841f8f 100644 --- a/ext/soap/tests/classmap003.phpt +++ b/ext/soap/tests/classmap003.phpt @@ -34,7 +34,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction("f"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/classmap004.phpt b/ext/soap/tests/classmap004.phpt index 1fbf4c6ccad3..172a6db7b448 100644 --- a/ext/soap/tests/classmap004.phpt +++ b/ext/soap/tests/classmap004.phpt @@ -42,7 +42,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction("f"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/classmap005.phpt b/ext/soap/tests/classmap005.phpt index ce4aa2b66bb8..a39adfa85033 100644 --- a/ext/soap/tests/classmap005.phpt +++ b/ext/soap/tests/classmap005.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- diff --git a/ext/soap/tests/classmap006.phpt b/ext/soap/tests/classmap006.phpt index 817a3a883c7e..c56f876148a1 100644 --- a/ext/soap/tests/classmap006.phpt +++ b/ext/soap/tests/classmap006.phpt @@ -39,7 +39,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction("f"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/classmap007.phpt b/ext/soap/tests/classmap007.phpt index b6fe394eaeec..9a59e647bc96 100644 --- a/ext/soap/tests/classmap007.phpt +++ b/ext/soap/tests/classmap007.phpt @@ -39,7 +39,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction("f"); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/gh15711.phpt b/ext/soap/tests/gh15711.phpt index b72251cc6f95..17ff051698fd 100644 --- a/ext/soap/tests/gh15711.phpt +++ b/ext/soap/tests/gh15711.phpt @@ -28,7 +28,7 @@ enum NonBackedEnum } class TestSoapClient extends SoapClient { - function __doRequest($request, $location, $action, $version, $one_way = 0): ?string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): ?string { echo $request; } } diff --git a/ext/soap/tests/gh16318.phpt b/ext/soap/tests/gh16318.phpt index a0a4c925df05..0c38b6fc8de3 100644 --- a/ext/soap/tests/gh16318.phpt +++ b/ext/soap/tests/gh16318.phpt @@ -15,7 +15,7 @@ $test2["a"] = "a"; $test2[] =& $test2; class TestSoapClient extends SoapClient { - public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false): ?string + public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false, ?string $uriParserClass = null): ?string { die($request); } diff --git a/ext/soap/tests/server003.phpt b/ext/soap/tests/server003.phpt index 1425daf81940..c278ca23a195 100644 --- a/ext/soap/tests/server003.phpt +++ b/ext/soap/tests/server003.phpt @@ -27,7 +27,7 @@ $server->handle($HTTP_RAW_POST_DATA); echo "ok\n"; ?> --EXPECTF-- -Deprecated: Constant SOAP_FUNCTIONS_ALL is deprecated in %s on line %d +Deprecated: Constant SOAP_FUNCTIONS_ALL is deprecated since 8.4, as enabling all functions is a possible security concern in %s on line %d Deprecated: SoapServer::addFunction(): Enabling all functions via SOAP_FUNCTIONS_ALL is deprecated since 8.4, due to possible security concerns. If all PHP functions should be enabled, the flattened return value of get_defined_functions() can be used in %s on line %d diff --git a/ext/soap/tests/soap12/T63.phpt b/ext/soap/tests/soap12/T63.phpt index a8cf3c431b24..810207e50ee5 100644 --- a/ext/soap/tests/soap12/T63.phpt +++ b/ext/soap/tests/soap12/T63.phpt @@ -21,5 +21,5 @@ include "soap12-test.inc"; ?> --EXPECT-- -Country code must be 2 letters.env:SenderNot a valid country code +Country code must be 2 letters.env:SenderNot a valid country code ok diff --git a/ext/soap/tests/soap_array_index_overflow.phpt b/ext/soap/tests/soap_array_index_overflow.phpt new file mode 100644 index 000000000000..ae481ee317ff --- /dev/null +++ b/ext/soap/tests/soap_array_index_overflow.phpt @@ -0,0 +1,89 @@ +--TEST-- +SOAP array index overflow is rejected +--EXTENSIONS-- +soap +--FILE-- +response; + } +} + +function soap_response(string $attributes, string $itemAttributes = ''): string { + return << + + + + + value + + + + +XML; +} + +function test_overflow(string $name, string $response): void { + $client = new TestSoapClient(NULL, [ + 'location' => 'test://', + 'uri' => 'http://example.org/', + 'exceptions' => true, + ]); + $client->response = $response; + + try { + $client->test(); + echo "$name: no fault\n"; + } catch (SoapFault $e) { + echo "$name: $e->faultstring\n"; + } +} + +function test_boundary_position(): void { + $client = new TestSoapClient(NULL, [ + 'location' => 'test://', + 'uri' => 'http://example.org/', + 'exceptions' => true, + ]); + $client->response = soap_response( + 'SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array"', + 'SOAP-ENC:position="[2147483646]"' + ); + + var_dump($client->test()); +} + +test_overflow( + 'arrayType', + soap_response('SOAP-ENC:arrayType="xsd:string[2147483648]" xsi:type="SOAP-ENC:Array"') +); + +test_overflow( + 'offset', + soap_response('SOAP-ENC:arrayType="xsd:string[1]" SOAP-ENC:offset="[2147483648]" xsi:type="SOAP-ENC:Array"') +); + +test_overflow( + 'position', + soap_response('SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array"', 'SOAP-ENC:position="[2147483647]"') +); + +test_boundary_position(); +?> +--EXPECT-- +arrayType: SOAP-ERROR: Encoding: array index out of range +offset: SOAP-ERROR: Encoding: array index out of range +position: SOAP-ERROR: Encoding: array index out of range +array(1) { + [2147483646]=> + string(5) "value" +} diff --git a/ext/soap/tests/soap_qname_crash.phpt b/ext/soap/tests/soap_qname_crash.phpt new file mode 100644 index 000000000000..990062164f9e --- /dev/null +++ b/ext/soap/tests/soap_qname_crash.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test SoapClient with excessively large QName prefix in SoapVar +--EXTENSIONS-- +soap +--SKIPIF-- + +--INI-- +memory_limit=6144M +--FILE-- + 'http://127.0.0.1/', + 'uri' => 'urn:dummy', + 'trace' => 1, + 'exceptions' => true, +]; +$client = new TestSoapClient(null, $options); +$client->__soapCall("DummyFunction", [$var]); +?> +--EXPECT-- +Attempting to create SoapVar with very large QName +Attempting encoding + +value diff --git a/ext/soap/tests/soap_set_cookie.phpt b/ext/soap/tests/soap_set_cookie.phpt new file mode 100644 index 000000000000..a23aa18bb4b7 --- /dev/null +++ b/ext/soap/tests/soap_set_cookie.phpt @@ -0,0 +1,22 @@ +--TEST-- +SoapClient::__setCookie with numeric keys +--EXTENSIONS-- +soap +--FILE-- + 'mo:http://www.w3.org/', 'location' => 'http://example.com')); +$client->__setCookie("123", "456"); +var_dump($client->__getCookies()); +$client->__setCookie("123", NULL); +var_dump($client->__getCookies()); +?> +--EXPECT-- +array(1) { + [123]=> + array(1) { + [0]=> + string(3) "456" + } +} +array(0) { +} diff --git a/ext/soap/tests/transport001.phpt b/ext/soap/tests/transport001.phpt index 297d0e1288e7..c735b2e139d7 100644 --- a/ext/soap/tests/transport001.phpt +++ b/ext/soap/tests/transport001.phpt @@ -17,7 +17,7 @@ class LocalSoapClient extends SoapClient { $this->server->addFunction('Add'); } - function __doRequest($request, $location, $action, $version, $one_way = 0): string { + function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string { ob_start(); $this->server->handle($request); $response = ob_get_contents(); diff --git a/ext/soap/tests/typemap003.phpt b/ext/soap/tests/typemap003.phpt index a7b83b6348bb..3f4960f8d5d6 100644 --- a/ext/soap/tests/typemap003.phpt +++ b/ext/soap/tests/typemap003.phpt @@ -8,7 +8,7 @@ soap.wsdl_cache_enabled=0 --FILE-- diff --git a/ext/soap/tests/typemap004.phpt b/ext/soap/tests/typemap004.phpt index 61b62867205f..c0feb6b4ebbc 100644 --- a/ext/soap/tests/typemap004.phpt +++ b/ext/soap/tests/typemap004.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- diff --git a/ext/soap/tests/typemap008.phpt b/ext/soap/tests/typemap008.phpt index 8abd8039f8d5..7e7012b6ad5c 100644 --- a/ext/soap/tests/typemap008.phpt +++ b/ext/soap/tests/typemap008.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- diff --git a/ext/soap/tests/typemap012.phpt b/ext/soap/tests/typemap012.phpt index e31d3ffa0ac4..13bb0c898479 100644 --- a/ext/soap/tests/typemap012.phpt +++ b/ext/soap/tests/typemap012.phpt @@ -7,7 +7,7 @@ soap.wsdl_cache_enabled=0 --FILE-- . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifdef __sun /* to enable 'new' ancillary data layout instead */ # define _XPG4_2 @@ -571,7 +585,6 @@ static void to_zval_read_sin_addr(const char *data, zval *zv, res_context *ctx) const struct in_addr *addr = (const struct in_addr *)data; socklen_t size = INET_ADDRSTRLEN; zend_string *str = zend_string_alloc(size - 1, 0); - memset(ZSTR_VAL(str), '\0', size); ZVAL_NEW_STR(zv, str); @@ -581,7 +594,7 @@ static void to_zval_read_sin_addr(const char *data, zval *zv, res_context *ctx) return; } - Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv)); + Z_STR_P(zv) = zend_string_truncate(Z_STR_P(zv), strlen(Z_STRVAL_P(zv)), 0); } static const field_descriptor descriptors_sockaddr_in[] = { {"family", sizeof("family"), false, offsetof(struct sockaddr_in, sin_family), from_zval_write_sa_family, to_zval_read_sa_family}, @@ -611,7 +624,7 @@ static void from_zval_write_sin6_addr(const zval *zaddr_str, char *addr6, ser_co } else { /* error already emitted, but let's emit another more relevant */ do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET6 " - "address", Z_STRVAL_P(zaddr_str)); + "address", ZSTR_VAL(addr_str)); } zend_tmp_string_release(tmp_addr_str); @@ -622,8 +635,6 @@ static void to_zval_read_sin6_addr(const char *data, zval *zv, res_context *ctx) socklen_t size = INET6_ADDRSTRLEN; zend_string *str = zend_string_alloc(size - 1, 0); - memset(ZSTR_VAL(str), '\0', size); - ZVAL_NEW_STR(zv, str); if (inet_ntop(AF_INET6, addr, Z_STRVAL_P(zv), size) == NULL) { @@ -632,7 +643,7 @@ static void to_zval_read_sin6_addr(const char *data, zval *zv, res_context *ctx) return; } - Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv)); + Z_STR_P(zv) = zend_string_truncate(Z_STR_P(zv), strlen(Z_STRVAL_P(zv)), 0); } static const field_descriptor descriptors_sockaddr_in6[] = { {"family", sizeof("family"), false, offsetof(struct sockaddr_in6, sin6_family), from_zval_write_sa_family, to_zval_read_sa_family}, @@ -930,7 +941,7 @@ static void from_zval_write_control_array(const zval *arr, char *msghdr_c, ser_c char *bufp = buf; zval *elem; uint32_t i = 0; - int num_elems; + uint32_t num_elems; void *control_buf; zend_llist_element *alloc; size_t control_len, @@ -1102,7 +1113,7 @@ static void from_zval_write_iov_array_aux(zval *elem, unsigned i, void **args, s } static void from_zval_write_iov_array(const zval *arr, char *msghdr_c, ser_context *ctx) { - int num_elem; + uint32_t num_elem; struct msghdr *msg = (struct msghdr*)msghdr_c; if (Z_TYPE_P(arr) != IS_ARRAY) { @@ -1361,7 +1372,7 @@ void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx) #ifdef SCM_RIGHTS size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx) { - int num_elems; + uint32_t num_elems; if (Z_TYPE_P(arr) != IS_ARRAY) { do_from_zval_err(ctx, "%s", "expected an array here"); @@ -1374,7 +1385,7 @@ size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx) return (size_t)-1; } - return zend_hash_num_elements(Z_ARRVAL_P(arr)) * sizeof(int); + return num_elems * sizeof(int); } static void from_zval_write_fd_array_aux(zval *elem, unsigned i, void **args, ser_context *ctx) { @@ -1420,7 +1431,7 @@ void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx) void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx) { size_t *cmsg_len; - int num_elems, + uint32_t num_elems, i; struct cmsghdr *dummy_cmsg = 0; size_t data_offset; diff --git a/ext/sockets/conversions.h b/ext/sockets/conversions.h index 1f1fd29c5c05..1d3ce11463d8 100644 --- a/ext/sockets/conversions.h +++ b/ext/sockets/conversions.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifndef PHP_SOCK_CONVERSIONS_H #define PHP_SOCK_CONVERSIONS_H 1 diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index f331fd177ebf..88fcf21278d2 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -293,7 +291,7 @@ int php_do_setsockopt_ip_mcast(php_socket *php_sock, goto dosockopt; case IP_MULTICAST_LOOP: - ipv4_mcast_ttl_lback = (unsigned char) zval_is_true(arg4); + ipv4_mcast_ttl_lback = (unsigned char) zend_is_true(arg4); goto ipv4_loop_ttl; case IP_MULTICAST_TTL: @@ -357,7 +355,7 @@ int php_do_setsockopt_ipv6_mcast(php_socket *php_sock, goto dosockopt; case IPV6_MULTICAST_LOOP: - ov = (int) zval_is_true(arg4); + ov = (int) zend_is_true(arg4); goto ipv6_loop_hops; case IPV6_MULTICAST_HOPS: convert_to_long(arg4); diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h index f2232921c6b9..5a40147cdd6f 100644 --- a/ext/sockets/multicast.h +++ b/ext/sockets/multicast.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h index 89c613ba4307..bc8d4617f7f0 100644 --- a/ext/sockets/php_sockets.h +++ b/ext/sockets/php_sockets.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Chris Vandomelen | | Sterling Hughes | @@ -78,7 +76,7 @@ typedef struct { extern PHP_SOCKETS_API zend_class_entry *socket_ce; static inline php_socket *socket_from_obj(zend_object *obj) { - return (php_socket *)((char *)(obj) - XtOffsetOf(php_socket, std)); + return ZEND_CONTAINER_OF(obj, php_socket, std); } #define Z_SOCKET_P(zv) socket_from_obj(Z_OBJ_P(zv)) diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index cd7fd4839fb0..cc268bd68b0a 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ diff --git a/ext/sockets/sendrecvmsg.h b/ext/sockets/sendrecvmsg.h index fd68b178ce5c..f430affe6779 100644 --- a/ext/sockets/sendrecvmsg.h +++ b/ext/sockets/sendrecvmsg.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifndef PHP_SENDRECVMSG_H #define PHP_SENDRECVMSG_H 1 diff --git a/ext/sockets/sockaddr_conv.c b/ext/sockets/sockaddr_conv.c index 9840a98dbcb7..949639d475f2 100644 --- a/ext/sockets/sockaddr_conv.c +++ b/ext/sockets/sockaddr_conv.c @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #include #include #include "php_sockets.h" @@ -137,8 +151,7 @@ int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, zend_string } #endif else { - php_error_docref(NULL, E_WARNING, - "IP address used in the context of an unexpected type of socket"); + zend_value_error("IP address used in the context of an unexpected type of socket"); } return 0; } diff --git a/ext/sockets/sockaddr_conv.h b/ext/sockets/sockaddr_conv.h index 93104e6470fb..ebca73862ef8 100644 --- a/ext/sockets/sockaddr_conv.h +++ b/ext/sockets/sockaddr_conv.h @@ -1,3 +1,17 @@ +/* + +----------------------------------------------------------------------+ + | Copyright © The PHP Group and Contributors. | + +----------------------------------------------------------------------+ + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes | + +----------------------------------------------------------------------+ + */ + #ifndef PHP_SOCKADR_CONV_H #define PHP_SOCKADR_CONV_H diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 82634cc8f3e5..7b87a2a2f9bd 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Chris Vandomelen | | Sterling Hughes | @@ -18,6 +16,7 @@ +----------------------------------------------------------------------+ */ +#include "zend_exceptions.h" #ifdef HAVE_CONFIG_H #include #endif @@ -109,7 +108,9 @@ ZEND_DECLARE_MODULE_GLOBALS(sockets) } \ } while (0) #else -#define PHP_ETH_PROTO_CHECK(protocol, family) (0) +#define PHP_ETH_PROTO_CHECK(protocol, family) \ + (void)protocol; \ + (void)family #endif static PHP_GINIT_FUNCTION(sockets); @@ -180,7 +181,7 @@ zend_class_entry *address_info_ce; static zend_object_handlers address_info_object_handlers; static inline php_addrinfo *address_info_from_obj(zend_object *obj) { - return (php_addrinfo *)((char *)(obj) - XtOffsetOf(php_addrinfo, std)); + return ZEND_CONTAINER_OF(obj, php_addrinfo, std); } #define Z_ADDRESS_INFO_P(zv) address_info_from_obj(Z_OBJ_P(zv)) @@ -241,18 +242,9 @@ ZEND_GET_MODULE(sockets) static bool php_open_listen_sock(php_socket *sock, unsigned short port, int backlog) /* {{{ */ { struct sockaddr_in la = {0}; - struct hostent *hp; - -#ifndef PHP_WIN32 - if ((hp = php_network_gethostbyname("0.0.0.0")) == NULL) { -#else - if ((hp = php_network_gethostbyname("localhost")) == NULL) { -#endif - return 0; - } - memcpy((char *) &la.sin_addr, hp->h_addr, hp->h_length); - la.sin_family = hp->h_addrtype; + la.sin_addr.s_addr = htonl(INADDR_ANY); + la.sin_family = AF_INET; la.sin_port = htons(port); sock->bsd_socket = socket(PF_INET, SOCK_STREAM, 0); @@ -260,7 +252,7 @@ static bool php_open_listen_sock(php_socket *sock, unsigned short port, int back if (IS_INVALID_SOCKET(sock)) { PHP_SOCKET_ERROR(sock, "unable to create listening socket", errno); - return 0; + return false; } sock->type = PF_INET; @@ -268,38 +260,51 @@ static bool php_open_listen_sock(php_socket *sock, unsigned short port, int back if (bind(sock->bsd_socket, (struct sockaddr *)&la, sizeof(la)) != 0) { PHP_SOCKET_ERROR(sock, "unable to bind to given address", errno); close(sock->bsd_socket); - return 0; + return false; } if (listen(sock->bsd_socket, backlog) != 0) { PHP_SOCKET_ERROR(sock, "unable to listen on socket", errno); close(sock->bsd_socket); - return 0; + return false; } - return 1; + return true; } /* }}} */ static bool php_accept_connect(php_socket *in_sock, php_socket *out_sock, struct sockaddr *la, socklen_t *la_len) /* {{{ */ { +#if defined(HAVE_ACCEPT4) + int flags = SOCK_CLOEXEC; + if (!in_sock->blocking) { + flags |= SOCK_NONBLOCK; + } + + out_sock->bsd_socket = accept4(in_sock->bsd_socket, la, la_len, flags); + + if (IS_INVALID_SOCKET(out_sock)) { + PHP_SOCKET_ERROR(out_sock, "unable to accept incoming connection", errno); + return false; + } +#else out_sock->bsd_socket = accept(in_sock->bsd_socket, la, la_len); if (IS_INVALID_SOCKET(out_sock)) { PHP_SOCKET_ERROR(out_sock, "unable to accept incoming connection", errno); - return 0; + return false; } #if !defined(PHP_WIN32) /** - * accept4 could had been used but not all platforms support it (e.g. Haiku, solaris < 11.4, ...) + * for fewer and fewer platforms not supporting accept4 syscall we use fcntl instead, * win32, not having any concept of child process, has no need to address it. */ int mode; if ((mode = fcntl(out_sock->bsd_socket, F_GETFD)) < 0) { PHP_SOCKET_ERROR(out_sock, "unable to get fcntl mode on the socket", errno); - return 0; + return false; } int cloexec = (mode | FD_CLOEXEC); @@ -307,16 +312,17 @@ static bool php_accept_connect(php_socket *in_sock, php_socket *out_sock, struct if (mode != cloexec) { if (fcntl(out_sock->bsd_socket, F_SETFD, cloexec) < 0) { PHP_SOCKET_ERROR(out_sock, "unable to set cloexec mode on the socket", errno); - return 0; + return false; } } +#endif #endif out_sock->error = 0; out_sock->blocking = 1; out_sock->type = la->sa_family; - return 1; + return true; } /* }}} */ @@ -478,7 +484,7 @@ static PHP_MINIT_FUNCTION(sockets) socket_ce->default_object_handlers = &socket_object_handlers; memcpy(&socket_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - socket_object_handlers.offset = XtOffsetOf(php_socket, std); + socket_object_handlers.offset = offsetof(php_socket, std); socket_object_handlers.free_obj = socket_free_obj; socket_object_handlers.get_constructor = socket_get_constructor; socket_object_handlers.clone_obj = NULL; @@ -490,7 +496,7 @@ static PHP_MINIT_FUNCTION(sockets) address_info_ce->default_object_handlers = &address_info_object_handlers; memcpy(&address_info_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - address_info_object_handlers.offset = XtOffsetOf(php_addrinfo, std); + address_info_object_handlers.offset = offsetof(php_addrinfo, std); address_info_object_handlers.free_obj = address_info_free_obj; address_info_object_handlers.get_constructor = address_info_get_constructor; address_info_object_handlers.clone_obj = NULL; @@ -1025,7 +1031,6 @@ PHP_FUNCTION(socket_getsockname) ZEND_TRY_ASSIGN_REF_LONG(objint, htons(sin6->sin6_port)); } RETURN_TRUE; - break; #endif case AF_INET: sin = (struct sockaddr_in *) sa; @@ -1036,14 +1041,12 @@ PHP_FUNCTION(socket_getsockname) ZEND_TRY_ASSIGN_REF_LONG(objint, htons(sin->sin_port)); } RETURN_TRUE; - break; case AF_UNIX: s_un = (struct sockaddr_un *) sa; ZEND_TRY_ASSIGN_REF_STRING(addr, s_un->sun_path); RETURN_TRUE; - break; #ifdef AF_PACKET case AF_PACKET: sll = (struct sockaddr_ll *) sa; @@ -1059,7 +1062,6 @@ PHP_FUNCTION(socket_getsockname) ZEND_TRY_ASSIGN_REF_LONG(objint, sll->sll_ifindex); } RETURN_TRUE; - break; #endif default: @@ -1115,7 +1117,6 @@ PHP_FUNCTION(socket_getpeername) } RETURN_TRUE; - break; #endif case AF_INET: sin = (struct sockaddr_in *) sa; @@ -1127,14 +1128,12 @@ PHP_FUNCTION(socket_getpeername) } RETURN_TRUE; - break; case AF_UNIX: s_un = (struct sockaddr_un *) sa; ZEND_TRY_ASSIGN_REF_STRING(arg2, s_un->sun_path); RETURN_TRUE; - break; default: zend_argument_value_error(1, "must be one of AF_UNIX, AF_INET, or AF_INET6"); @@ -1232,8 +1231,6 @@ PHP_FUNCTION(socket_connect) RETURN_THROWS(); } - memset(&sin6, 0, sizeof(struct sockaddr_in6)); - sin6.sin6_family = AF_INET6; sin6.sin6_port = htons((unsigned short int)port); @@ -1275,7 +1272,7 @@ PHP_FUNCTION(socket_connect) s_un.sun_family = AF_UNIX; memcpy(&s_un.sun_path, ZSTR_VAL(addr), ZSTR_LEN(addr)); retval = connect(php_sock->bsd_socket, (struct sockaddr *) &s_un, - (socklen_t)(XtOffsetOf(struct sockaddr_un, sun_path) + ZSTR_LEN(addr))); + (socklen_t)(offsetof(struct sockaddr_un, sun_path) + ZSTR_LEN(addr))); break; } @@ -1564,7 +1561,11 @@ PHP_FUNCTION(socket_recvfrom) if (arg6 == NULL) { zend_string_efree(recv_buf); - WRONG_PARAM_COUNT; + zend_throw_exception( + zend_ce_argument_count_error, + "socket_recvfrom() expects exactly 6 arguments when argument #1 ($socket) is of type AF_INET or AF_INET6", + 0); + RETURN_THROWS(); } retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sin, (socklen_t *)&slen); @@ -1591,7 +1592,11 @@ PHP_FUNCTION(socket_recvfrom) if (arg6 == NULL) { zend_string_efree(recv_buf); - WRONG_PARAM_COUNT; + zend_throw_exception( + zend_ce_argument_count_error, + "socket_recvfrom() expects exactly 6 arguments when argument #1 ($socket) is of type AF_INET or AF_INET6", + 0); + RETURN_THROWS(); } retval = recvfrom(php_sock->bsd_socket, ZSTR_VAL(recv_buf), arg3, arg4, (struct sockaddr *)&sin6, (socklen_t *)&slen); @@ -1604,7 +1609,6 @@ PHP_FUNCTION(socket_recvfrom) ZSTR_LEN(recv_buf) = retval; ZSTR_VAL(recv_buf)[ZSTR_LEN(recv_buf)] = '\0'; - memset(addrbuf, 0, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &sin6.sin6_addr, addrbuf, sizeof(addrbuf)); ZEND_TRY_ASSIGN_REF_NEW_STR(arg2, recv_buf); @@ -1700,8 +1704,14 @@ PHP_FUNCTION(socket_sendto) switch (php_sock->type) { case AF_UNIX: memset(&s_un, 0, sizeof(s_un)); + + if (ZSTR_LEN(addr) >= sizeof(s_un.sun_path)) { + zend_argument_value_error(5, "must be less than %d", sizeof(s_un.sun_path)); + RETURN_THROWS(); + } + s_un.sun_family = AF_UNIX; - snprintf(s_un.sun_path, sizeof(s_un.sun_path), "%s", ZSTR_VAL(addr)); + memcpy(s_un.sun_path, ZSTR_VAL(addr), ZSTR_LEN(addr) + 1); retval = sendto(php_sock->bsd_socket, buf, ((size_t)len > buf_len) ? buf_len : (size_t)len, flags, (struct sockaddr *) &s_un, SUN_LEN(&s_un)); break; @@ -1748,7 +1758,7 @@ PHP_FUNCTION(socket_sendto) RETURN_THROWS(); } - memset(&sll, 0, sizeof(sll)); + memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = port; @@ -2105,6 +2115,28 @@ PHP_FUNCTION(socket_set_option) } #endif +#if defined(TCP_USER_TIMEOUT) + case TCP_USER_TIMEOUT: { + zend_long timeout = zval_get_long(arg4); + + // TCP_USER_TIMEOUT unsigned int + if (timeout < 0 || timeout > UINT_MAX) { + zend_argument_value_error(4, "must be of between 0 and %u", UINT_MAX); + RETURN_THROWS(); + } + + unsigned int val = (unsigned int)timeout; + optlen = sizeof(val); + opt_ptr = &val; + if (setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen) != 0) { + PHP_SOCKET_ERROR(php_sock, "Unable to set socket option", errno); + RETURN_FALSE; + } + + RETURN_TRUE; + } +#endif + } } @@ -2541,7 +2573,7 @@ bool socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock) retsock->type = addr.ss_family; } else { PHP_SOCKET_ERROR(retsock, "Unable to obtain socket family", errno); - return 0; + return false; } /* determine blocking mode */ @@ -2549,13 +2581,13 @@ bool socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock) t = fcntl(socket, F_GETFL); if (t == -1) { PHP_SOCKET_ERROR(retsock, "Unable to obtain blocking state", errno); - return 0; + return false; } else { retsock->blocking = !(t & O_NONBLOCK); } #endif - return 1; + return true; } /* {{{ Imports a stream that encapsulates a socket into a socket extension resource. */ @@ -2571,7 +2603,7 @@ PHP_FUNCTION(socket_import_stream) ZEND_PARSE_PARAMETERS_END(); php_stream_from_zval(stream, zstream); - if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void**)&socket, 1)) { + if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void**)&socket, 1) == FAILURE) { /* error supposedly already shown */ RETURN_FALSE; } @@ -2702,19 +2734,20 @@ PHP_FUNCTION(socket_export_stream) /* {{{ Gets array with contents of getaddrinfo about the given hostname. */ PHP_FUNCTION(socket_addrinfo_lookup) { - char *service = NULL; - size_t service_len = 0; + zend_string *service = NULL; zend_string *hostname, *key; - zval *hint, *zhints = NULL; + zval *hint, *zhints = NULL, *error_code = NULL; + int ret = 0; struct addrinfo hints, *result, *rp; php_addrinfo *res; - ZEND_PARSE_PARAMETERS_START(1, 3) + ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_STR(hostname) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(service, service_len) + Z_PARAM_STR_OR_NULL(service) Z_PARAM_ARRAY(zhints) + Z_PARAM_ZVAL_OR_NULL(error_code) ZEND_PARSE_PARAMETERS_END(); memset(&hints, 0, sizeof(hints)); @@ -2774,9 +2807,19 @@ PHP_FUNCTION(socket_addrinfo_lookup) zend_argument_type_error(3, "\"ai_family\" key must be of type int, %s given", zend_zval_type_name(hint)); RETURN_THROWS(); } - if (val < 0 || val >= AF_MAX) { - zend_argument_value_error(3, "\"ai_family\" key must be between 0 and %d", AF_MAX - 1); - RETURN_THROWS(); + // Some platforms support also PF_LOCAL/AF_UNIX (e.g. FreeBSD) but the security concerns implied + // make it not worth handling it (e.g. unwarranted write permissions on the socket). + // Note existing socket_addrinfo* api already forbid such case. + if (val != AF_UNSPEC) { +#ifdef HAVE_IPV6 + if (val != AF_INET && val != AF_INET6) { + zend_argument_value_error(3, "\"ai_family\" key must be AF_INET or AF_INET6"); +#else + if (val != AF_INET) { + zend_argument_value_error(3, "\"ai_family\" key must be AF_INET"); +#endif + RETURN_THROWS(); + } } hints.ai_family = (int)val; } else { @@ -2792,7 +2835,10 @@ PHP_FUNCTION(socket_addrinfo_lookup) } ZEND_HASH_FOREACH_END(); } - if (getaddrinfo(ZSTR_VAL(hostname), service, &hints, &result) != 0) { + if ((ret = getaddrinfo(ZSTR_VAL(hostname), service ? ZSTR_VAL(service) : NULL, &hints, &result)) != 0) { + if (error_code) { + ZEND_TRY_ASSIGN_REF_LONG(error_code, ret); + } RETURN_FALSE; } @@ -2800,7 +2846,11 @@ PHP_FUNCTION(socket_addrinfo_lookup) zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); for (rp = result; rp != NULL; rp = rp->ai_next) { - if (rp->ai_family != AF_UNSPEC) { + if (rp->ai_family == AF_INET +#ifdef HAVE_IPV6 + || rp->ai_family == AF_INET6 +#endif + ) { zval zaddr; object_init_ex(&zaddr, address_info_ce); @@ -2827,7 +2877,6 @@ PHP_FUNCTION(socket_addrinfo_lookup) PHP_FUNCTION(socket_addrinfo_bind) { zval *arg1; - int retval; php_addrinfo *ai; php_socket *php_sock; @@ -2837,6 +2886,8 @@ PHP_FUNCTION(socket_addrinfo_bind) ai = Z_ADDRESS_INFO_P(arg1); + ZEND_ASSERT(ai->addrinfo.ai_family == AF_INET || ai->addrinfo.ai_family == AF_INET6); + PHP_ETH_PROTO_CHECK(ai->addrinfo.ai_protocol, ai->addrinfo.ai_family); object_init_ex(return_value, socket_ce); @@ -2855,31 +2906,7 @@ PHP_FUNCTION(socket_addrinfo_bind) php_sock->error = 0; php_sock->blocking = 1; - switch(php_sock->type) { - case AF_UNIX: - { - // AF_UNIX sockets via getaddrino are not implemented due to security problems - close(php_sock->bsd_socket); - zval_ptr_dtor(return_value); - RETURN_FALSE; - } - - case AF_INET: -#ifdef HAVE_IPV6 - case AF_INET6: -#endif - { - retval = bind(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen); - break; - } - default: - close(php_sock->bsd_socket); - zval_ptr_dtor(return_value); - zend_argument_value_error(1, "must be one of AF_UNIX, AF_INET, or AF_INET6"); - RETURN_THROWS(); - } - - if (retval != 0) { + if (bind(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen) != 0) { PHP_SOCKET_ERROR(php_sock, "Unable to bind address", errno); close(php_sock->bsd_socket); zval_ptr_dtor(return_value); @@ -2892,7 +2919,6 @@ PHP_FUNCTION(socket_addrinfo_bind) PHP_FUNCTION(socket_addrinfo_connect) { zval *arg1; - int retval; php_addrinfo *ai; php_socket *php_sock; @@ -2902,6 +2928,8 @@ PHP_FUNCTION(socket_addrinfo_connect) ai = Z_ADDRESS_INFO_P(arg1); + ZEND_ASSERT(ai->addrinfo.ai_family == AF_INET || ai->addrinfo.ai_family == AF_INET6); + PHP_ETH_PROTO_CHECK(ai->addrinfo.ai_protocol, ai->addrinfo.ai_family); object_init_ex(return_value, socket_ce); @@ -2920,31 +2948,7 @@ PHP_FUNCTION(socket_addrinfo_connect) php_sock->error = 0; php_sock->blocking = 1; - switch(php_sock->type) { - case AF_UNIX: - { - // AF_UNIX sockets via getaddrino are not implemented due to security problems - close(php_sock->bsd_socket); - zval_ptr_dtor(return_value); - RETURN_FALSE; - } - - case AF_INET: -#ifdef HAVE_IPV6 - case AF_INET6: -#endif - { - retval = connect(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen); - break; - } - default: - zend_argument_value_error(1, "socket type must be one of AF_UNIX, AF_INET, or AF_INET6"); - close(php_sock->bsd_socket); - zval_ptr_dtor(return_value); - RETURN_THROWS(); - } - - if (retval != 0) { + if (connect(php_sock->bsd_socket, ai->addrinfo.ai_addr, ai->addrinfo.ai_addrlen) != 0) { PHP_SOCKET_ERROR(php_sock, "Unable to connect address", errno); close(php_sock->bsd_socket); zval_ptr_dtor(return_value); diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index 6050a8941456..56b2ac07e868 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -19,6 +19,13 @@ */ const AF_INET6 = UNKNOWN; #endif +#ifdef AF_UNSPEC +/** + * @var int + * @cvalue AF_UNSPEC + */ +const AF_UNSPEC = UNKNOWN; +#endif #ifdef AF_DIVERT /** * @var int @@ -602,6 +609,13 @@ */ const TCP_SYNCNT = UNKNOWN; #endif +#ifdef TCP_USER_TIMEOUT +/** + * @var int + * @cvalue TCP_USER_TIMEOUT + */ +const TCP_USER_TIMEOUT = UNKNOWN; +#endif #ifdef SO_ZEROCOPY /** * @var int @@ -643,11 +657,15 @@ * @cvalue TCP_KEEPIDLE */ const TCP_KEEPIDLE = UNKNOWN; +#endif +#ifdef TCP_KEEPINTVL /** * @var int * @cvalue TCP_KEEPINTVL */ const TCP_KEEPINTVL = UNKNOWN; +#endif +#ifdef TCP_KEEPCNT /** * @var int * @cvalue TCP_KEEPCNT @@ -2049,6 +2067,136 @@ const SHUT_RDWR = UNKNOWN; #endif + +#ifdef EAI_BADFLAGS +/** + * @var int + * @cvalue EAI_BADFLAGS + */ +const EAI_BADFLAGS = UNKNOWN; +#endif +#ifdef EAI_NONAME +/** + * @var int + * @cvalue EAI_NONAME + */ +const EAI_NONAME = UNKNOWN; +#endif +#ifdef EAI_AGAIN +/** + * @var int + * @cvalue EAI_AGAIN + */ +const EAI_AGAIN = UNKNOWN; +#endif +#ifdef EAI_FAIL +/** + * @var int + * @cvalue EAI_FAIL + */ +const EAI_FAIL = UNKNOWN; +#endif +#ifdef EAI_NODATA +/** + * @var int + * @cvalue EAI_NODATA + */ +const EAI_NODATA = UNKNOWN; +#endif +#ifdef EAI_FAMILY +/** + * @var int + * @cvalue EAI_FAMILY + */ +const EAI_FAMILY = UNKNOWN; +#endif +#ifdef EAI_SOCKTYPE +/** + * @var int + * @cvalue EAI_SOCKTYPE + */ +const EAI_SOCKTYPE = UNKNOWN; +#endif +#ifdef EAI_SERVICE +/** + * @var int + * @cvalue EAI_SERVICE + */ +const EAI_SERVICE = UNKNOWN; +#endif +#ifdef EAI_ADDRFAMILY +/** + * @var int + * @cvalue EAI_ADDRFAMILY + */ +const EAI_ADDRFAMILY = UNKNOWN; +#else +#ifdef EAI_FAMILY +/** + * @var int + * @cvalue EAI_FAMILY + */ +const EAI_ADDRFAMILY = UNKNOWN; +#else +#endif +#endif +#ifdef EAI_SYSTEM +/** + * @var int + * @cvalue EAI_SYSTEM + */ +const EAI_SYSTEM = UNKNOWN; +#endif +#ifdef EAI_OVERFLOW +/** + * @var int + * @cvalue EAI_OVERFLOW + */ +const EAI_OVERFLOW = UNKNOWN; +#endif +#ifdef EAI_INPROGRESS +/** + * @var int + * @cvalue EAI_INPROGRESS + */ +const EAI_INPROGRESS = UNKNOWN; +#endif +#ifdef EAI_CANCELED +/** + * @var int + * @cvalue EAI_CANCELED + */ +const EAI_CANCELED = UNKNOWN; +#endif +#ifdef EAI_NOTCANCELED +/** + * @var int + * @cvalue EAI_NOTCANCELED + */ +const EAI_NOTCANCELED = UNKNOWN; +#endif +#ifdef EAI_ALLDONE +/** + * @var int + * @cvalue EAI_ALLDONE + */ +const EAI_ALLDONE = UNKNOWN; +#endif +#ifdef EAI_INTR +/** + * @var int + * @cvalue EAI_INTR + */ +const EAI_INTR = UNKNOWN; +#endif +#ifdef EAI_IDN_ENCODE +/** + * @var int + * @cvalue EAI_IDN_ENCODE + */ +const EAI_IDN_ENCODE = UNKNOWN; +#endif + /** * @strict-properties * @not-serializable @@ -2169,9 +2317,10 @@ function socket_cmsg_space(int $level, int $type, int $num = 0): ?int {} /** * @return array|false + * @param int $error_code * @refcount 1 */ -function socket_addrinfo_lookup(string $host, ?string $service = null, array $hints = []): array|false {} +function socket_addrinfo_lookup(string $host, ?string $service = null, array $hints = [], &$error_code = null): array|false {} function socket_addrinfo_connect(AddressInfo $address): Socket|false {} diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index b7af6eb6b89a..2592cb740865 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7b1baf47dce2fb08faa5616068238ea078d1609b */ +/* This is a generated file, edit sockets.stub.php instead. + * Stub hash: 5e71ef16f2121bd6c75794673d0e0a394759ff8b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -184,6 +184,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_addrinfo_lookup, 0, 1, MA ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, service, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, hints, IS_ARRAY, 0, "[]") + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, error_code, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_socket_addrinfo_connect, 0, 1, Socket, MAY_BE_FALSE) @@ -317,6 +318,9 @@ static void register_sockets_symbols(int module_number) #if defined(HAVE_IPV6) REGISTER_LONG_CONSTANT("AF_INET6", AF_INET6, CONST_PERSISTENT); #endif +#if defined(AF_UNSPEC) + REGISTER_LONG_CONSTANT("AF_UNSPEC", AF_UNSPEC, CONST_PERSISTENT); +#endif #if defined(AF_DIVERT) REGISTER_LONG_CONSTANT("AF_DIVERT", AF_DIVERT, CONST_PERSISTENT); #endif @@ -527,6 +531,9 @@ static void register_sockets_symbols(int module_number) #if defined(TCP_SYNCNT) REGISTER_LONG_CONSTANT("TCP_SYNCNT", TCP_SYNCNT, CONST_PERSISTENT); #endif +#if defined(TCP_USER_TIMEOUT) + REGISTER_LONG_CONSTANT("TCP_USER_TIMEOUT", TCP_USER_TIMEOUT, CONST_PERSISTENT); +#endif #if defined(SO_ZEROCOPY) REGISTER_LONG_CONSTANT("SO_ZEROCOPY", SO_ZEROCOPY, CONST_PERSISTENT); #endif @@ -544,7 +551,11 @@ static void register_sockets_symbols(int module_number) #endif #if defined(TCP_KEEPIDLE) REGISTER_LONG_CONSTANT("TCP_KEEPIDLE", TCP_KEEPIDLE, CONST_PERSISTENT); +#endif +#if defined(TCP_KEEPINTVL) REGISTER_LONG_CONSTANT("TCP_KEEPINTVL", TCP_KEEPINTVL, CONST_PERSISTENT); +#endif +#if defined(TCP_KEEPCNT) REGISTER_LONG_CONSTANT("TCP_KEEPCNT", TCP_KEEPCNT, CONST_PERSISTENT); #endif #if defined(TCP_FUNCTION_BLK) @@ -1044,6 +1055,60 @@ static void register_sockets_symbols(int module_number) REGISTER_LONG_CONSTANT("SHUT_WR", SHUT_WR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SHUT_RDWR", SHUT_RDWR, CONST_PERSISTENT); #endif +#if defined(EAI_BADFLAGS) + REGISTER_LONG_CONSTANT("EAI_BADFLAGS", EAI_BADFLAGS, CONST_PERSISTENT); +#endif +#if defined(EAI_NONAME) + REGISTER_LONG_CONSTANT("EAI_NONAME", EAI_NONAME, CONST_PERSISTENT); +#endif +#if defined(EAI_AGAIN) + REGISTER_LONG_CONSTANT("EAI_AGAIN", EAI_AGAIN, CONST_PERSISTENT); +#endif +#if defined(EAI_FAIL) + REGISTER_LONG_CONSTANT("EAI_FAIL", EAI_FAIL, CONST_PERSISTENT); +#endif +#if defined(EAI_NODATA) + REGISTER_LONG_CONSTANT("EAI_NODATA", EAI_NODATA, CONST_PERSISTENT); +#endif +#if defined(EAI_FAMILY) + REGISTER_LONG_CONSTANT("EAI_FAMILY", EAI_FAMILY, CONST_PERSISTENT); +#endif +#if defined(EAI_SOCKTYPE) + REGISTER_LONG_CONSTANT("EAI_SOCKTYPE", EAI_SOCKTYPE, CONST_PERSISTENT); +#endif +#if defined(EAI_SERVICE) + REGISTER_LONG_CONSTANT("EAI_SERVICE", EAI_SERVICE, CONST_PERSISTENT); +#endif +#if defined(EAI_ADDRFAMILY) + REGISTER_LONG_CONSTANT("EAI_ADDRFAMILY", EAI_ADDRFAMILY, CONST_PERSISTENT); +#endif +#if !(defined(EAI_ADDRFAMILY)) && defined(EAI_FAMILY) + REGISTER_LONG_CONSTANT("EAI_ADDRFAMILY", EAI_FAMILY, CONST_PERSISTENT); +#endif +#if defined(EAI_SYSTEM) + REGISTER_LONG_CONSTANT("EAI_SYSTEM", EAI_SYSTEM, CONST_PERSISTENT); +#endif +#if defined(EAI_OVERFLOW) + REGISTER_LONG_CONSTANT("EAI_OVERFLOW", EAI_OVERFLOW, CONST_PERSISTENT); +#endif +#if defined(EAI_INPROGRESS) + REGISTER_LONG_CONSTANT("EAI_INPROGRESS", EAI_INPROGRESS, CONST_PERSISTENT); +#endif +#if defined(EAI_CANCELED) + REGISTER_LONG_CONSTANT("EAI_CANCELED", EAI_CANCELED, CONST_PERSISTENT); +#endif +#if defined(EAI_NOTCANCELED) + REGISTER_LONG_CONSTANT("EAI_NOTCANCELED", EAI_NOTCANCELED, CONST_PERSISTENT); +#endif +#if defined(EAI_ALLDONE) + REGISTER_LONG_CONSTANT("EAI_ALLDONE", EAI_ALLDONE, CONST_PERSISTENT); +#endif +#if defined(EAI_INTR) + REGISTER_LONG_CONSTANT("EAI_INTR", EAI_INTR, CONST_PERSISTENT); +#endif +#if defined(EAI_IDN_ENCODE) + REGISTER_LONG_CONSTANT("EAI_IDN_ENCODE", EAI_IDN_ENCODE, CONST_PERSISTENT); +#endif } static zend_class_entry *register_class_Socket(void) diff --git a/ext/sockets/tests/gh20532.phpt b/ext/sockets/tests/gh20532.phpt new file mode 100644 index 000000000000..360f9e7e11a8 --- /dev/null +++ b/ext/sockets/tests/gh20532.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-20562 - socket_addrinfo_lookup() returns error codes on resolution failures. +--EXTENSIONS-- +sockets +--FILE-- + AF_INET], $error_code) === false && in_array($error_code, [EAI_FAMILY, EAI_ADDRFAMILY, EAI_NONAME, EAI_NODATA])); +var_dump(socket_addrinfo_lookup("example.com", "http", ['ai_socktype' => SOCK_RAW, 'ai_flags' => 2147483647], $error_code) === false && in_array($error_code, [EAI_SOCKTYPE, EAI_SERVICE, EAI_BADFLAGS, EAI_NONAME])); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) + diff --git a/ext/sockets/tests/gh21161.phpt b/ext/sockets/tests/gh21161.phpt new file mode 100644 index 000000000000..8a3958a583d9 --- /dev/null +++ b/ext/sockets/tests/gh21161.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-21161 (IPV6_PKTINFO socket option crash with null addr array entry) +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + null, 'ifindex' => 0]); +?> +--EXPECTF-- +Warning: socket_set_option(): Host lookup failed [%i]: %s on line %d + +Warning: socket_set_option(): error converting user data (path: in6_pktinfo > addr): could not resolve address '' to get an AF_INET6 address in %s on line %d diff --git a/ext/sockets/tests/mcast_sockettype_error.phpt b/ext/sockets/tests/mcast_sockettype_error.phpt new file mode 100644 index 000000000000..56308534ebc4 --- /dev/null +++ b/ext/sockets/tests/mcast_sockettype_error.phpt @@ -0,0 +1,30 @@ +--TEST-- +Multicast attempt on unsupported socket type +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + '127.0.0.1', + "interface" => "lo", + )); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +IP address used in the context of an unexpected type of socket diff --git a/ext/sockets/tests/socket_addrinfo_explain.phpt b/ext/sockets/tests/socket_addrinfo_explain.phpt index e06ed36a64ec..ef516b966496 100644 --- a/ext/sockets/tests/socket_addrinfo_explain.phpt +++ b/ext/sockets/tests/socket_addrinfo_explain.phpt @@ -12,6 +12,11 @@ $result = socket_addrinfo_explain($addrinfo[0]); // Musl sets ai_canonname even if AI_CANONNAME is not specified. unset($result['ai_canonname']); var_dump($result); +// Solaris uses different numeric values for SOCK_* constants, +// so avoid comparing raw integers in EXPECTF. +if ($result['ai_socktype'] != SOCK_DGRAM) { + echo "Wrong socktype\n"; +} echo "Done"; ?> --EXPECTF-- @@ -21,7 +26,7 @@ array(5) { ["ai_family"]=> int(2) ["ai_socktype"]=> - int(2) + int(%s) ["ai_protocol"]=> int(%d) ["ai_addr"]=> diff --git a/ext/sockets/tests/socket_afpacket.phpt b/ext/sockets/tests/socket_afpacket.phpt index 2e83a654766e..a707ad48fa7a 100644 --- a/ext/sockets/tests/socket_afpacket.phpt +++ b/ext/sockets/tests/socket_afpacket.phpt @@ -9,6 +9,9 @@ posix if (!defined("AF_PACKET")) { die('SKIP AF_PACKET not supported on this platform.'); } +if (!defined("ETH_P_IP")) { + die('SKIP ETH_P_IP not available on this platform.'); +} if (!function_exists("posix_getuid") || posix_getuid() != 0) { die('SKIP AF_PACKET requires root permissions.'); } diff --git a/ext/sockets/tests/socket_create_listen-win32.phpt b/ext/sockets/tests/socket_create_listen-win32.phpt index 74e6d73212f1..bbdc3b1ee9de 100644 --- a/ext/sockets/tests/socket_create_listen-win32.phpt +++ b/ext/sockets/tests/socket_create_listen-win32.phpt @@ -15,7 +15,7 @@ socket_getsockname($sock, $addr, $port); var_dump($addr, $port); ?> --EXPECT-- -string(9) "127.0.0.1" +string(7) "0.0.0.0" int(31338) --CREDITS-- Till Klampaeckel, till@php.net diff --git a/ext/sockets/tests/socket_create_pair-wrongparams.phpt b/ext/sockets/tests/socket_create_pair-wrongparams.phpt index 8877e3d5b99e..1d0a6540841d 100644 --- a/ext/sockets/tests/socket_create_pair-wrongparams.phpt +++ b/ext/sockets/tests/socket_create_pair-wrongparams.phpt @@ -27,7 +27,7 @@ try { ?> --EXPECTF-- -Warning: socket_create_pair(): Unable to create socket pair [%d]: %s not supported in %s on line %d +Warning: socket_create_pair(): Unable to create socket pair [%d]: %s %r(not supported|wrong type for socket)%r in %s on line %d bool(false) socket_create_pair(): Argument #1 ($domain) must be one of AF_UNIX, AF_INET6, or AF_INET socket_create_pair(): Argument #2 ($type) must be one of SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, or SOCK_RDM%A diff --git a/ext/sockets/tests/socket_export_stream-4.phpt b/ext/sockets/tests/socket_export_stream-4.phpt index a3879a93b7cd..168671138680 100644 --- a/ext/sockets/tests/socket_export_stream-4.phpt +++ b/ext/sockets/tests/socket_export_stream-4.phpt @@ -32,7 +32,9 @@ function test($stream, $sock) { echo "\n"; echo "socket_get_option "; try { - print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); + // Solaris uses different numeric values for SOCK_* constants + $opt = socket_get_option($sock, SOL_SOCKET, SO_TYPE); + print_r($opt === SOCK_DGRAM ? "DGRAM" : $opt); } catch (Error $e) { echo get_class($e), ": ", $e->getMessage(), "\n"; } @@ -81,12 +83,12 @@ echo "Done.\n"; normal stream_set_blocking 1 socket_set_block 1 -socket_get_option 2 +socket_get_option DGRAM unset stream socket_set_block 1 -socket_get_option 2 +socket_get_option DGRAM unset socket diff --git a/ext/sockets/tests/socket_export_stream-5.phpt b/ext/sockets/tests/socket_export_stream-5.phpt deleted file mode 100644 index ffad1935b64b..000000000000 --- a/ext/sockets/tests/socket_export_stream-5.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -socket_export_stream: effects of leaked handles ---EXTENSIONS-- -sockets -zend_test ---INI-- -report_memleaks=0 ---FILE-- - ---EXPECT-- -Done. diff --git a/ext/sockets/tests/socket_getaddrinfo_error.phpt b/ext/sockets/tests/socket_getaddrinfo_error.phpt index c3488b540c69..a2455821e70e 100644 --- a/ext/sockets/tests/socket_getaddrinfo_error.phpt +++ b/ext/sockets/tests/socket_getaddrinfo_error.phpt @@ -110,7 +110,7 @@ socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be of type i socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be of type int, stdClass given socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be of type int, stdClass given socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be of type int, stdClass given -socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be between 0 and %d +socket_addrinfo_lookup(): Argument #3 ($hints) "ai_family" key must be AF_INET%A socket_addrinfo_lookup(): Argument #3 ($hints) "ai_socktype" key must be between 0 and %d socket_addrinfo_lookup(): Argument #3 ($hints) "ai_flags" key must be between 0 and %d socket_addrinfo_lookup(): Argument #3 ($hints) "ai_protocol" key must be between 0 and %d diff --git a/ext/sockets/tests/socket_import_stream-4.phpt b/ext/sockets/tests/socket_import_stream-4.phpt index efe987dfdce2..87ca608b862b 100644 --- a/ext/sockets/tests/socket_import_stream-4.phpt +++ b/ext/sockets/tests/socket_import_stream-4.phpt @@ -31,7 +31,9 @@ function test($stream, $sock) { echo "\n"; echo "socket_get_option "; try { - print_r(socket_get_option($sock, SOL_SOCKET, SO_TYPE)); + // Solaris uses different numeric values for SOCK_* constants + $opt = socket_get_option($sock, SOL_SOCKET, SO_TYPE); + print_r($opt === SOCK_DGRAM ? "DGRAM" : $opt); } catch (Error $e) { echo get_class($e), ": ", $e->getMessage(), "\n"; } @@ -75,12 +77,12 @@ echo "Done.\n"; normal stream_set_blocking 1 socket_set_block 1 -socket_get_option 2 +socket_get_option DGRAM unset stream socket_set_block 1 -socket_get_option 2 +socket_get_option DGRAM unset socket diff --git a/ext/sockets/tests/socket_import_stream-5.phpt b/ext/sockets/tests/socket_import_stream-5.phpt deleted file mode 100644 index 9a684d054ba0..000000000000 --- a/ext/sockets/tests/socket_import_stream-5.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -socket_import_stream: effects of leaked handles ---EXTENSIONS-- -sockets -zend_test ---INI-- -report_memleaks=0 ---FILE-- - ---EXPECT-- -Done. diff --git a/ext/sockets/tests/socket_recvfrom_ipv4_missing_port_arg.phpt b/ext/sockets/tests/socket_recvfrom_ipv4_missing_port_arg.phpt new file mode 100644 index 000000000000..0554818fb67c --- /dev/null +++ b/ext/sockets/tests/socket_recvfrom_ipv4_missing_port_arg.phpt @@ -0,0 +1,17 @@ +--TEST-- +socket_recvfrom() with IPv4 socket missing port argument +--EXTENSIONS-- +sockets +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ArgumentCountError: socket_recvfrom() expects exactly 6 arguments when argument #1 ($socket) is of type AF_INET or AF_INET6 diff --git a/ext/sockets/tests/socket_recvfrom_ipv6_missing_port_arg.phpt b/ext/sockets/tests/socket_recvfrom_ipv6_missing_port_arg.phpt new file mode 100644 index 000000000000..957751a94976 --- /dev/null +++ b/ext/sockets/tests/socket_recvfrom_ipv6_missing_port_arg.phpt @@ -0,0 +1,21 @@ +--TEST-- +socket_recvfrom() with IPv6 socket missing port argument +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ArgumentCountError: socket_recvfrom() expects exactly 6 arguments when argument #1 ($socket) is of type AF_INET or AF_INET6 diff --git a/ext/sockets/tests/socket_sendto_unix_addr_too_long.phpt b/ext/sockets/tests/socket_sendto_unix_addr_too_long.phpt new file mode 100644 index 000000000000..f2b62527e337 --- /dev/null +++ b/ext/sockets/tests/socket_sendto_unix_addr_too_long.phpt @@ -0,0 +1,29 @@ +--TEST-- +socket_sendto() with AF_UNIX rejects address exceeding sun_path limit +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- +getMessage() . PHP_EOL; +} + +socket_close($socket); +?> +--EXPECTF-- +socket_sendto(): Argument #5 ($address) must be less than %d diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt new file mode 100644 index 000000000000..3f12120e54d8 --- /dev/null +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test if socket_set_option() works, option:TCP_USER_TIMEOUT +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +$timeout = 200; +$retval_2 = socket_set_option($socket, SOL_TCP, TCP_USER_TIMEOUT, $timeout); +$retval_3 = socket_get_option($socket, SOL_TCP, TCP_USER_TIMEOUT); +var_dump($retval_2); +var_dump($retval_3 === $timeout); +socket_close($socket); +?> +--EXPECTF-- +socket_setopt(): Argument #4 ($value) must be of between 0 and %d +bool(true) +bool(true) diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt new file mode 100644 index 000000000000..8dbb7f80e48b --- /dev/null +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test if socket_set_option() works, option:TCP_USER_TIMEOUT +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + socket_setopt($socket, SOL_TCP, TCP_USER_TIMEOUT, PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + +$timeout = 200; +$retval_2 = socket_set_option($socket, SOL_TCP, TCP_USER_TIMEOUT, $timeout); +$retval_3 = socket_get_option($socket, SOL_TCP, TCP_USER_TIMEOUT); +var_dump($retval_2); +var_dump($retval_3 === $timeout); +socket_close($socket); +?> +--EXPECTF-- +socket_setopt(): Argument #4 ($value) must be of between 0 and %d +socket_setopt(): Argument #4 ($value) must be of between 0 and %d +bool(true) +bool(true) diff --git a/ext/sockets/tests/socket_tcp_congestion.phpt b/ext/sockets/tests/socket_tcp_congestion.phpt index 56b587618548..45853f6bf8ce 100644 --- a/ext/sockets/tests/socket_tcp_congestion.phpt +++ b/ext/sockets/tests/socket_tcp_congestion.phpt @@ -7,6 +7,9 @@ sockets if (!defined('TCP_CONGESTION')) { die('skip TCP_CONGESTION test'); } +if (PHP_OS_FAMILY === 'Solaris' ) { + die("skip Solaris does not allow setting TCP_CONGESTION"); +} ?> --FILE-- +--FILE-- + +--EXPECT-- +SO_KEEPALIVE: enabled +TCP_KEEPIDLE: 60 +TCP_KEEPINTVL: 10 +TCP_KEEPCNT: 5 diff --git a/ext/sockets/windows_common.h b/ext/sockets/windows_common.h index 0b8cdfe2e5d9..9c7e711ffe5b 100644 --- a/ext/sockets/windows_common.h +++ b/ext/sockets/windows_common.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ #ifndef WINDOWS_COMMON_H diff --git a/ext/sodium/config.m4 b/ext/sodium/config.m4 index 40da5e5bf2d1..178568d72aeb 100644 --- a/ext/sodium/config.m4 +++ b/ext/sodium/config.m4 @@ -19,8 +19,7 @@ if test "$PHP_SODIUM" != "no"; then AS_IF([test "$ac_cv_sizeof_long" -eq 4], [ SODIUM_COMPILER_FLAGS="$SODIUM_COMPILER_FLAGS -Wno-type-limits" AX_CHECK_COMPILE_FLAG([-Wno-logical-op], - [SODIUM_COMPILER_FLAGS="$SODIUM_COMPILER_FLAGS -Wno-logical-op"],, - [-Werror]) + [SODIUM_COMPILER_FLAGS="$SODIUM_COMPILER_FLAGS -Wno-logical-op"]) ]) PHP_NEW_EXTENSION([sodium], diff --git a/ext/sodium/config.w32 b/ext/sodium/config.w32 index bde640629460..19c548898ab9 100644 --- a/ext/sodium/config.w32 +++ b/ext/sodium/config.w32 @@ -3,7 +3,7 @@ ARG_WITH("sodium", "for libsodium support", "no"); if (PHP_SODIUM != "no") { - if (CHECK_LIB("libsodium.lib", "sodium", PHP_SODIUM) && CHECK_HEADER_ADD_INCLUDE("sodium.h", "CFLAGS_SODIUM")) { + if (CHECK_LIB("libsodium.lib", "sodium", PHP_SODIUM) && CHECK_HEADER("sodium.h", "CFLAGS_SODIUM")) { EXTENSION("sodium", "libsodium.c sodium_pwhash.c"); AC_DEFINE('HAVE_LIBSODIUMLIB', 1 , "Define to 1 if the PHP extension 'sodium' is available."); PHP_INSTALL_HEADERS("ext/sodium", "php_libsodium.h"); diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 2404f8aebb47..b6c3ae03f689 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Frank Denis | +----------------------------------------------------------------------+ @@ -571,9 +569,8 @@ PHP_FUNCTION(sodium_crypto_box_keypair) zend_string *keypair; size_t keypair_len; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + keypair_len = crypto_box_SECRETKEYBYTES + crypto_box_PUBLICKEYBYTES; keypair = zend_string_alloc(keypair_len, 0); if (crypto_box_keypair((unsigned char *) ZSTR_VAL(keypair) + @@ -891,9 +888,8 @@ PHP_FUNCTION(sodium_crypto_sign_keypair) zend_string *keypair; size_t keypair_len; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + keypair_len = crypto_sign_SECRETKEYBYTES + crypto_sign_PUBLICKEYBYTES; keypair = zend_string_alloc(keypair_len, 0); if (crypto_sign_keypair((unsigned char *) ZSTR_VAL(keypair) + @@ -1733,9 +1729,7 @@ PHP_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256_str_verify) PHP_FUNCTION(sodium_crypto_aead_aes256gcm_is_available) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); #ifdef HAVE_AESGCM RETURN_BOOL(crypto_aead_aes256gcm_is_available()); #else @@ -2603,7 +2597,7 @@ PHP_FUNCTION(sodium_crypto_scalarmult) RETURN_THROWS(); } if (p_len != crypto_scalarmult_BYTES) { - zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_SCALARMULT_SCALARBYTES bytes long"); + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_SCALARMULT_BYTES bytes long"); RETURN_THROWS(); } q = zend_string_alloc(crypto_scalarmult_BYTES, 0); @@ -2674,7 +2668,7 @@ PHP_FUNCTION(sodium_crypto_scalarmult_ristretto255_base) zend_argument_error(sodium_exception_ce, 1, "must not be zero", 0); RETURN_THROWS(); } - ZSTR_VAL(q)[crypto_scalarmult_BYTES] = 0; + ZSTR_VAL(q)[crypto_scalarmult_ristretto255_BYTES] = 0; RETURN_NEW_STR(q); } @@ -2719,9 +2713,8 @@ PHP_FUNCTION(sodium_crypto_kx_keypair) unsigned char *pk; zend_string *keypair; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + keypair = zend_string_alloc(crypto_kx_SECRETKEYBYTES + crypto_kx_PUBLICKEYBYTES, 0); sk = (unsigned char *) ZSTR_VAL(keypair); pk = sk + crypto_kx_SECRETKEYBYTES; @@ -3028,9 +3021,8 @@ PHP_FUNCTION(sodium_crypto_aead_aes256gcm_keygen) { unsigned char key[crypto_aead_aes256gcm_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3041,9 +3033,8 @@ PHP_FUNCTION(sodium_crypto_aead_aegis128l_keygen) { unsigned char key[crypto_aead_aegis128l_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + crypto_aead_aegis128l_keygen(key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3054,9 +3045,8 @@ PHP_FUNCTION(sodium_crypto_aead_aegis256_keygen) { unsigned char key[crypto_aead_aegis256_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + crypto_aead_aegis256_keygen(key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3066,9 +3056,8 @@ PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_keygen) { unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3077,9 +3066,8 @@ PHP_FUNCTION(sodium_crypto_aead_chacha20poly1305_ietf_keygen) { unsigned char key[crypto_aead_chacha20poly1305_IETF_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3089,9 +3077,8 @@ PHP_FUNCTION(sodium_crypto_aead_xchacha20poly1305_ietf_keygen) { unsigned char key[crypto_aead_xchacha20poly1305_IETF_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3101,9 +3088,8 @@ PHP_FUNCTION(sodium_crypto_auth_keygen) { unsigned char key[crypto_auth_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3112,9 +3098,8 @@ PHP_FUNCTION(sodium_crypto_generichash_keygen) { unsigned char key[crypto_generichash_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3123,9 +3108,8 @@ PHP_FUNCTION(sodium_crypto_kdf_keygen) { unsigned char key[crypto_kdf_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3134,9 +3118,8 @@ PHP_FUNCTION(sodium_crypto_secretbox_keygen) { unsigned char key[crypto_secretbox_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3145,9 +3128,8 @@ PHP_FUNCTION(sodium_crypto_shorthash_keygen) { unsigned char key[crypto_shorthash_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3156,9 +3138,8 @@ PHP_FUNCTION(sodium_crypto_stream_keygen) { unsigned char key[crypto_stream_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3167,9 +3148,8 @@ PHP_FUNCTION(sodium_crypto_stream_xchacha20_keygen) { unsigned char key[crypto_stream_xchacha20_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3214,7 +3194,7 @@ PHP_FUNCTION(sodium_crypto_kdf_derive_from_key) RETURN_THROWS(); } if (key_len != crypto_kdf_KEYBYTES) { - zend_argument_error(sodium_exception_ce, 4, "must be SODIUM_CRYPTO_KDF_BYTES_MIN bytes long"); + zend_argument_error(sodium_exception_ce, 4, "must be SODIUM_CRYPTO_KDF_KEYBYTES bytes long"); RETURN_THROWS(); } memcpy(ctx_padded, ctx, crypto_kdf_CONTEXTBYTES); @@ -3391,9 +3371,8 @@ PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_keygen) { unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + randombytes_buf(key, sizeof key); RETURN_STRINGL((const char *) key, sizeof key); } @@ -3679,9 +3658,8 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_random) { zend_string *r; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); crypto_core_ristretto255_random((unsigned char *) ZSTR_VAL(r)); ZSTR_VAL(r)[crypto_core_ristretto255_BYTES] = 0; @@ -3820,9 +3798,8 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_random) { zend_string *r; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - }; + ZEND_PARSE_PARAMETERS_NONE(); + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); crypto_core_ristretto255_scalar_random((unsigned char *) ZSTR_VAL(r)); ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; @@ -3913,3 +3890,913 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_sub) RETURN_NEW_STR(r); } #endif + +#ifdef crypto_ipcrypt_KEYBYTES +PHP_FUNCTION(sodium_crypto_ipcrypt_keygen) +{ + unsigned char key[crypto_ipcrypt_KEYBYTES]; + + ZEND_PARSE_PARAMETERS_NONE(); + + crypto_ipcrypt_keygen(key); + RETURN_STRINGL((const char *) key, sizeof key); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_encrypt) +{ + char *ip; + size_t ip_len; + unsigned char *key; + size_t key_len; + unsigned char bin[crypto_ipcrypt_BYTES]; + unsigned char encrypted[crypto_ipcrypt_BYTES]; + char ip_out[46]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ip, &ip_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (sodium_ip2bin(bin, ip, ip_len) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address"); + RETURN_THROWS(); + } + crypto_ipcrypt_encrypt(encrypted, bin, key); + if (sodium_bin2ip(ip_out, sizeof ip_out, encrypted) == NULL) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + RETURN_STRING(ip_out); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_decrypt) +{ + char *encrypted_ip; + size_t encrypted_ip_len; + unsigned char *key; + size_t key_len; + unsigned char bin[crypto_ipcrypt_BYTES]; + unsigned char decrypted[crypto_ipcrypt_BYTES]; + char ip_out[46]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &encrypted_ip, &encrypted_ip_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (sodium_ip2bin(bin, encrypted_ip, encrypted_ip_len) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address"); + RETURN_THROWS(); + } + crypto_ipcrypt_decrypt(decrypted, bin, key); + if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + RETURN_STRING(ip_out); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_nd_keygen) +{ + unsigned char key[crypto_ipcrypt_ND_KEYBYTES]; + + ZEND_PARSE_PARAMETERS_NONE(); + + randombytes_buf(key, sizeof key); + RETURN_STRINGL((const char *) key, sizeof key); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_nd_encrypt) +{ + char *ip; + size_t ip_len; + unsigned char *key; + size_t key_len; + unsigned char bin[crypto_ipcrypt_ND_INPUTBYTES]; + unsigned char tweak[crypto_ipcrypt_ND_TWEAKBYTES]; + unsigned char encrypted[crypto_ipcrypt_ND_OUTPUTBYTES]; + char hex_out[crypto_ipcrypt_ND_OUTPUTBYTES * 2 + 1]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ip, &ip_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_ND_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (sodium_ip2bin(bin, ip, ip_len) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address"); + RETURN_THROWS(); + } + randombytes_buf(tweak, sizeof tweak); + crypto_ipcrypt_nd_encrypt(encrypted, bin, tweak, key); + sodium_bin2hex(hex_out, sizeof hex_out, encrypted, sizeof encrypted); + RETURN_STRINGL(hex_out, crypto_ipcrypt_ND_OUTPUTBYTES * 2); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_nd_decrypt) +{ + char *ciphertext_hex; + size_t ciphertext_hex_len; + unsigned char *key; + size_t key_len; + unsigned char encrypted[crypto_ipcrypt_ND_OUTPUTBYTES]; + unsigned char decrypted[crypto_ipcrypt_ND_INPUTBYTES]; + char ip_out[46]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ciphertext_hex, &ciphertext_hex_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_ND_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (ciphertext_hex_len != crypto_ipcrypt_ND_OUTPUTBYTES * 2) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext"); + RETURN_THROWS(); + } + if (sodium_hex2bin(encrypted, sizeof encrypted, ciphertext_hex, ciphertext_hex_len, + NULL, NULL, NULL) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext"); + RETURN_THROWS(); + } + crypto_ipcrypt_nd_decrypt(decrypted, encrypted, key); + if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + RETURN_STRING(ip_out); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_ndx_keygen) +{ + unsigned char key[crypto_ipcrypt_NDX_KEYBYTES]; + + ZEND_PARSE_PARAMETERS_NONE(); + + crypto_ipcrypt_ndx_keygen(key); + RETURN_STRINGL((const char *) key, sizeof key); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_ndx_encrypt) +{ + char *ip; + size_t ip_len; + unsigned char *key; + size_t key_len; + unsigned char bin[crypto_ipcrypt_NDX_INPUTBYTES]; + unsigned char tweak[crypto_ipcrypt_NDX_TWEAKBYTES]; + unsigned char encrypted[crypto_ipcrypt_NDX_OUTPUTBYTES]; + char hex_out[crypto_ipcrypt_NDX_OUTPUTBYTES * 2 + 1]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ip, &ip_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_NDX_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (sodium_ip2bin(bin, ip, ip_len) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address"); + RETURN_THROWS(); + } + randombytes_buf(tweak, sizeof tweak); + crypto_ipcrypt_ndx_encrypt(encrypted, bin, tweak, key); + sodium_bin2hex(hex_out, sizeof hex_out, encrypted, sizeof encrypted); + RETURN_STRINGL(hex_out, crypto_ipcrypt_NDX_OUTPUTBYTES * 2); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_ndx_decrypt) +{ + char *ciphertext_hex; + size_t ciphertext_hex_len; + unsigned char *key; + size_t key_len; + unsigned char encrypted[crypto_ipcrypt_NDX_OUTPUTBYTES]; + unsigned char decrypted[crypto_ipcrypt_NDX_INPUTBYTES]; + char ip_out[46]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ciphertext_hex, &ciphertext_hex_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_NDX_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (ciphertext_hex_len != crypto_ipcrypt_NDX_OUTPUTBYTES * 2) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext"); + RETURN_THROWS(); + } + if (sodium_hex2bin(encrypted, sizeof encrypted, ciphertext_hex, ciphertext_hex_len, + NULL, NULL, NULL) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid hex-encoded ciphertext"); + RETURN_THROWS(); + } + crypto_ipcrypt_ndx_decrypt(decrypted, encrypted, key); + if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + RETURN_STRING(ip_out); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_pfx_keygen) +{ + unsigned char key[crypto_ipcrypt_PFX_KEYBYTES]; + + ZEND_PARSE_PARAMETERS_NONE(); + + crypto_ipcrypt_pfx_keygen(key); + RETURN_STRINGL((const char *) key, sizeof key); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_pfx_encrypt) +{ + char *ip; + size_t ip_len; + unsigned char *key; + size_t key_len; + unsigned char bin[crypto_ipcrypt_PFX_BYTES]; + unsigned char encrypted[crypto_ipcrypt_PFX_BYTES]; + char ip_out[46]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &ip, &ip_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_PFX_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (sodium_ip2bin(bin, ip, ip_len) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address"); + RETURN_THROWS(); + } + crypto_ipcrypt_pfx_encrypt(encrypted, bin, key); + if (sodium_bin2ip(ip_out, sizeof ip_out, encrypted) == NULL) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + RETURN_STRING(ip_out); +} + +PHP_FUNCTION(sodium_crypto_ipcrypt_pfx_decrypt) +{ + char *encrypted_ip; + size_t encrypted_ip_len; + unsigned char *key; + size_t key_len; + unsigned char bin[crypto_ipcrypt_PFX_BYTES]; + unsigned char decrypted[crypto_ipcrypt_PFX_BYTES]; + char ip_out[46]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &encrypted_ip, &encrypted_ip_len, &key, &key_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (key_len != crypto_ipcrypt_PFX_KEYBYTES) { + zend_argument_error(sodium_exception_ce, 2, "must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long"); + RETURN_THROWS(); + } + if (sodium_ip2bin(bin, encrypted_ip, encrypted_ip_len) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address"); + RETURN_THROWS(); + } + crypto_ipcrypt_pfx_decrypt(decrypted, bin, key); + if (sodium_bin2ip(ip_out, sizeof ip_out, decrypted) == NULL) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + RETURN_STRING(ip_out); +} + +PHP_FUNCTION(sodium_bin2ip) +{ + unsigned char *bin; + size_t bin_len; + char ip_out[46]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &bin, &bin_len) == FAILURE) { + RETURN_THROWS(); + } + if (bin_len != 16) { + zend_argument_error(sodium_exception_ce, 1, "must be 16 bytes long"); + RETURN_THROWS(); + } + if (sodium_bin2ip(ip_out, sizeof ip_out, bin) == NULL) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + RETURN_STRING(ip_out); +} + +PHP_FUNCTION(sodium_ip2bin) +{ + char *ip; + size_t ip_len; + unsigned char bin[16]; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &ip, &ip_len) == FAILURE) { + RETURN_THROWS(); + } + if (sodium_ip2bin(bin, ip, ip_len) != 0) { + zend_argument_error(sodium_exception_ce, 1, "must be a valid IP address"); + RETURN_THROWS(); + } + RETURN_STRINGL((const char *) bin, sizeof bin); +} +#endif + +#ifdef crypto_xof_shake128_STATEBYTES +PHP_FUNCTION(sodium_crypto_xof_shake128) +{ + zend_string *out; + unsigned char *msg; + zend_long out_len; + size_t msg_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", + &out_len, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 1, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + if (crypto_xof_shake128((unsigned char *) ZSTR_VAL(out), (size_t) out_len, + msg, (unsigned long long) msg_len) != 0) { + zend_string_efree(out); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} + +PHP_FUNCTION(sodium_crypto_xof_shake128_init) +{ + crypto_xof_shake128_state state_tmp; + zend_string *state; + zend_long domain = -1; + bool domain_is_null = 1; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(domain, domain_is_null) + ZEND_PARSE_PARAMETERS_END(); + + memset(&state_tmp, 0, sizeof state_tmp); + if (domain_is_null) { + if (crypto_xof_shake128_init(&state_tmp) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } else { + if (domain < 0x01 || domain > 0x7f) { + zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f"); + RETURN_THROWS(); + } + if (crypto_xof_shake128_init_with_domain(&state_tmp, (unsigned char) domain) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } + state = zend_string_alloc(sizeof state_tmp, 0); + memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(state)[sizeof state_tmp] = 0; + RETURN_STR(state); +} + +PHP_FUNCTION(sodium_crypto_xof_shake128_update) +{ + crypto_xof_shake128_state state_tmp; + zval *state_zv; + unsigned char *msg; + unsigned char *state; + size_t msg_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs", + &state_zv, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_shake128_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_shake128_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) { + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + RETURN_TRUE; +} + +PHP_FUNCTION(sodium_crypto_xof_shake128_squeeze) +{ + crypto_xof_shake128_state state_tmp; + zval *state_zv; + zend_string *out; + unsigned char *state; + zend_long out_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl", + &state_zv, &out_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_shake128_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 2, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_shake128_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) { + zend_string_efree(out); + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} + +PHP_FUNCTION(sodium_crypto_xof_shake256) +{ + zend_string *out; + unsigned char *msg; + zend_long out_len; + size_t msg_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", + &out_len, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 1, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + if (crypto_xof_shake256((unsigned char *) ZSTR_VAL(out), (size_t) out_len, + msg, (unsigned long long) msg_len) != 0) { + zend_string_efree(out); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} + +PHP_FUNCTION(sodium_crypto_xof_shake256_init) +{ + crypto_xof_shake256_state state_tmp; + zend_string *state; + zend_long domain = -1; + bool domain_is_null = 1; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(domain, domain_is_null) + ZEND_PARSE_PARAMETERS_END(); + + memset(&state_tmp, 0, sizeof state_tmp); + if (domain_is_null) { + if (crypto_xof_shake256_init(&state_tmp) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } else { + if (domain < 0x01 || domain > 0x7f) { + zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f"); + RETURN_THROWS(); + } + if (crypto_xof_shake256_init_with_domain(&state_tmp, (unsigned char) domain) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } + state = zend_string_alloc(sizeof state_tmp, 0); + memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(state)[sizeof state_tmp] = 0; + RETURN_STR(state); +} + +PHP_FUNCTION(sodium_crypto_xof_shake256_update) +{ + crypto_xof_shake256_state state_tmp; + zval *state_zv; + unsigned char *msg; + unsigned char *state; + size_t msg_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs", + &state_zv, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_shake256_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_shake256_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) { + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + RETURN_TRUE; +} + +PHP_FUNCTION(sodium_crypto_xof_shake256_squeeze) +{ + crypto_xof_shake256_state state_tmp; + zval *state_zv; + zend_string *out; + unsigned char *state; + zend_long out_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl", + &state_zv, &out_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_shake256_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 2, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_shake256_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) { + zend_string_efree(out); + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake128) +{ + zend_string *out; + unsigned char *msg; + zend_long out_len; + size_t msg_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", + &out_len, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 1, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + if (crypto_xof_turboshake128((unsigned char *) ZSTR_VAL(out), (size_t) out_len, + msg, (unsigned long long) msg_len) != 0) { + zend_string_efree(out); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake128_init) +{ + crypto_xof_turboshake128_state state_tmp; + zend_string *state; + zend_long domain = -1; + bool domain_is_null = 1; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(domain, domain_is_null) + ZEND_PARSE_PARAMETERS_END(); + + memset(&state_tmp, 0, sizeof state_tmp); + if (domain_is_null) { + if (crypto_xof_turboshake128_init(&state_tmp) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } else { + if (domain < 0x01 || domain > 0x7f) { + zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f"); + RETURN_THROWS(); + } + if (crypto_xof_turboshake128_init_with_domain(&state_tmp, (unsigned char) domain) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } + state = zend_string_alloc(sizeof state_tmp, 0); + memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(state)[sizeof state_tmp] = 0; + RETURN_STR(state); +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake128_update) +{ + crypto_xof_turboshake128_state state_tmp; + zval *state_zv; + unsigned char *msg; + unsigned char *state; + size_t msg_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs", + &state_zv, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_turboshake128_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_turboshake128_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) { + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + RETURN_TRUE; +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake128_squeeze) +{ + crypto_xof_turboshake128_state state_tmp; + zval *state_zv; + zend_string *out; + unsigned char *state; + zend_long out_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl", + &state_zv, &out_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_turboshake128_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 2, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_turboshake128_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) { + zend_string_efree(out); + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake256) +{ + zend_string *out; + unsigned char *msg; + zend_long out_len; + size_t msg_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", + &out_len, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 1, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + if (crypto_xof_turboshake256((unsigned char *) ZSTR_VAL(out), (size_t) out_len, + msg, (unsigned long long) msg_len) != 0) { + zend_string_efree(out); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake256_init) +{ + crypto_xof_turboshake256_state state_tmp; + zend_string *state; + zend_long domain = -1; + bool domain_is_null = 1; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(domain, domain_is_null) + ZEND_PARSE_PARAMETERS_END(); + + memset(&state_tmp, 0, sizeof state_tmp); + if (domain_is_null) { + if (crypto_xof_turboshake256_init(&state_tmp) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } else { + if (domain < 0x01 || domain > 0x7f) { + zend_argument_error(sodium_exception_ce, 1, "must be between 0x01 and 0x7f"); + RETURN_THROWS(); + } + if (crypto_xof_turboshake256_init_with_domain(&state_tmp, (unsigned char) domain) != 0) { + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + } + state = zend_string_alloc(sizeof state_tmp, 0); + memcpy(ZSTR_VAL(state), &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(state)[sizeof state_tmp] = 0; + RETURN_STR(state); +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake256_update) +{ + crypto_xof_turboshake256_state state_tmp; + zval *state_zv; + unsigned char *msg; + unsigned char *state; + size_t msg_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs", + &state_zv, &msg, &msg_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_turboshake256_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_turboshake256_update(&state_tmp, msg, (unsigned long long) msg_len) != 0) { + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + RETURN_TRUE; +} + +PHP_FUNCTION(sodium_crypto_xof_turboshake256_squeeze) +{ + crypto_xof_turboshake256_state state_tmp; + zval *state_zv; + zend_string *out; + unsigned char *state; + zend_long out_len; + size_t state_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl", + &state_zv, &out_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + ZVAL_DEREF(state_zv); + if (Z_TYPE_P(state_zv) != IS_STRING) { + zend_argument_error(sodium_exception_ce, 1, "must be a reference to a state"); + RETURN_THROWS(); + } + sodium_separate_string(state_zv); + state = (unsigned char *) Z_STRVAL(*state_zv); + state_len = Z_STRLEN(*state_zv); + if (state_len != sizeof (crypto_xof_turboshake256_state)) { + zend_argument_error(sodium_exception_ce, 1, "must have a correct state length"); + RETURN_THROWS(); + } + if (out_len <= 0 || out_len > ZSTR_MAX_LEN) { + zend_argument_error(sodium_exception_ce, 2, "must be a positive integer"); + RETURN_THROWS(); + } + out = zend_string_alloc((size_t) out_len, 0); + memcpy(&state_tmp, state, sizeof state_tmp); + if (crypto_xof_turboshake256_squeeze(&state_tmp, (unsigned char *) ZSTR_VAL(out), (size_t) out_len) != 0) { + zend_string_efree(out); + sodium_memzero(&state_tmp, sizeof state_tmp); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + memcpy(state, &state_tmp, sizeof state_tmp); + sodium_memzero(&state_tmp, sizeof state_tmp); + ZSTR_VAL(out)[out_len] = 0; + RETURN_NEW_STR(out); +} +#endif diff --git a/ext/sodium/libsodium.stub.php b/ext/sodium/libsodium.stub.php index 4bf6fade9136..9fda5f4ddd73 100644 --- a/ext/sodium/libsodium.stub.php +++ b/ext/sodium/libsodium.stub.php @@ -801,4 +801,170 @@ function sodium_base642bin(#[\SensitiveParameter] string $string, int $id, strin */ function sodium_crypto_scalarmult_base(#[\SensitiveParameter] string $secret_key): string {} +#ifdef crypto_ipcrypt_KEYBYTES +/** + * @var int + * @cvalue crypto_ipcrypt_BYTES + */ +const SODIUM_CRYPTO_IPCRYPT_BYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_KEYBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_KEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_ND_KEYBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_ND_TWEAKBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_ND_TWEAKBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_ND_INPUTBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_ND_INPUTBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_ND_OUTPUTBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_ND_OUTPUTBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_NDX_KEYBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_NDX_TWEAKBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_NDX_TWEAKBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_NDX_INPUTBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_NDX_INPUTBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_NDX_OUTPUTBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_PFX_KEYBYTES + */ +const SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_ipcrypt_PFX_BYTES + */ +const SODIUM_CRYPTO_IPCRYPT_PFX_BYTES = UNKNOWN; + +function sodium_crypto_ipcrypt_keygen(): string {} + +function sodium_crypto_ipcrypt_encrypt(string $ip, #[\SensitiveParameter] string $key): string {} + +function sodium_crypto_ipcrypt_decrypt(string $encrypted_ip, #[\SensitiveParameter] string $key): string {} + +function sodium_crypto_ipcrypt_nd_keygen(): string {} + +function sodium_crypto_ipcrypt_nd_encrypt(string $ip, #[\SensitiveParameter] string $key): string {} + +function sodium_crypto_ipcrypt_nd_decrypt(string $ciphertext_hex, #[\SensitiveParameter] string $key): string {} + +function sodium_crypto_ipcrypt_ndx_keygen(): string {} + +function sodium_crypto_ipcrypt_ndx_encrypt(string $ip, #[\SensitiveParameter] string $key): string {} + +function sodium_crypto_ipcrypt_ndx_decrypt(string $ciphertext_hex, #[\SensitiveParameter] string $key): string {} + +function sodium_crypto_ipcrypt_pfx_keygen(): string {} + +function sodium_crypto_ipcrypt_pfx_encrypt(string $ip, #[\SensitiveParameter] string $key): string {} + +function sodium_crypto_ipcrypt_pfx_decrypt(string $encrypted_ip, #[\SensitiveParameter] string $key): string {} + +function sodium_bin2ip(string $bin): string {} + +function sodium_ip2bin(string $ip): string {} +#endif + +#ifdef crypto_xof_shake128_STATEBYTES +/** + * @var int + * @cvalue crypto_xof_shake128_BLOCKBYTES + */ +const SODIUM_CRYPTO_XOF_SHAKE128_BLOCKBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_xof_shake128_STATEBYTES + */ +const SODIUM_CRYPTO_XOF_SHAKE128_STATEBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_xof_shake256_BLOCKBYTES + */ +const SODIUM_CRYPTO_XOF_SHAKE256_BLOCKBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_xof_shake256_STATEBYTES + */ +const SODIUM_CRYPTO_XOF_SHAKE256_STATEBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_xof_turboshake128_BLOCKBYTES + */ +const SODIUM_CRYPTO_XOF_TURBOSHAKE128_BLOCKBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_xof_turboshake128_STATEBYTES + */ +const SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_xof_turboshake256_BLOCKBYTES + */ +const SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES = UNKNOWN; +/** + * @var int + * @cvalue crypto_xof_turboshake256_STATEBYTES + */ +const SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES = UNKNOWN; + +function sodium_crypto_xof_shake128(int $length, string $message): string {} + +function sodium_crypto_xof_shake128_init(?int $domain = null): string {} + +function sodium_crypto_xof_shake128_update(string &$state, string $message): true {} + +function sodium_crypto_xof_shake128_squeeze(string &$state, int $length): string {} + +function sodium_crypto_xof_shake256(int $length, string $message): string {} + +function sodium_crypto_xof_shake256_init(?int $domain = null): string {} + +function sodium_crypto_xof_shake256_update(string &$state, string $message): true {} + +function sodium_crypto_xof_shake256_squeeze(string &$state, int $length): string {} + +function sodium_crypto_xof_turboshake128(int $length, string $message): string {} + +function sodium_crypto_xof_turboshake128_init(?int $domain = null): string {} + +function sodium_crypto_xof_turboshake128_update(string &$state, string $message): true {} + +function sodium_crypto_xof_turboshake128_squeeze(string &$state, int $length): string {} + +function sodium_crypto_xof_turboshake256(int $length, string $message): string {} + +function sodium_crypto_xof_turboshake256_init(?int $domain = null): string {} + +function sodium_crypto_xof_turboshake256_update(string &$state, string $message): true {} + +function sodium_crypto_xof_turboshake256_squeeze(string &$state, int $length): string {} +#endif + class SodiumException extends Exception {} diff --git a/ext/sodium/libsodium_arginfo.h b/ext/sodium/libsodium_arginfo.h index 5fbd831c22e4..1b291e9a2330 100644 --- a/ext/sodium/libsodium_arginfo.h +++ b/ext/sodium/libsodium_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 89cbb449ee6146dc8d50ba4bb1e76f83444a2db2 */ +/* This is a generated file, edit libsodium.stub.php instead. + * Stub hash: 7b337a297ae333dd8d0c232979b770332c9e7eb6 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_aead_aes256gcm_is_available, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -483,6 +483,95 @@ ZEND_END_ARG_INFO() #define arginfo_sodium_crypto_scalarmult_base arginfo_sodium_crypto_box_publickey_from_secretkey +#if defined(crypto_ipcrypt_KEYBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_keygen, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_encrypt, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, ip, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_decrypt, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, encrypted_ip, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_sodium_crypto_ipcrypt_nd_keygen arginfo_sodium_crypto_ipcrypt_keygen + +#define arginfo_sodium_crypto_ipcrypt_nd_encrypt arginfo_sodium_crypto_ipcrypt_encrypt + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_ipcrypt_nd_decrypt, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, ciphertext_hex, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) +ZEND_END_ARG_INFO() + +#define arginfo_sodium_crypto_ipcrypt_ndx_keygen arginfo_sodium_crypto_ipcrypt_keygen + +#define arginfo_sodium_crypto_ipcrypt_ndx_encrypt arginfo_sodium_crypto_ipcrypt_encrypt + +#define arginfo_sodium_crypto_ipcrypt_ndx_decrypt arginfo_sodium_crypto_ipcrypt_nd_decrypt + +#define arginfo_sodium_crypto_ipcrypt_pfx_keygen arginfo_sodium_crypto_ipcrypt_keygen + +#define arginfo_sodium_crypto_ipcrypt_pfx_encrypt arginfo_sodium_crypto_ipcrypt_encrypt + +#define arginfo_sodium_crypto_ipcrypt_pfx_decrypt arginfo_sodium_crypto_ipcrypt_decrypt + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_bin2ip, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, bin, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_ip2bin, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, ip, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_xof_shake128_STATEBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128_init, 0, 0, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_LONG, 1, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128_update, 0, 2, IS_TRUE, 0) + ZEND_ARG_TYPE_INFO(1, state, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_xof_shake128_squeeze, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(1, state, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_sodium_crypto_xof_shake256 arginfo_sodium_crypto_xof_shake128 + +#define arginfo_sodium_crypto_xof_shake256_init arginfo_sodium_crypto_xof_shake128_init + +#define arginfo_sodium_crypto_xof_shake256_update arginfo_sodium_crypto_xof_shake128_update + +#define arginfo_sodium_crypto_xof_shake256_squeeze arginfo_sodium_crypto_xof_shake128_squeeze + +#define arginfo_sodium_crypto_xof_turboshake128 arginfo_sodium_crypto_xof_shake128 + +#define arginfo_sodium_crypto_xof_turboshake128_init arginfo_sodium_crypto_xof_shake128_init + +#define arginfo_sodium_crypto_xof_turboshake128_update arginfo_sodium_crypto_xof_shake128_update + +#define arginfo_sodium_crypto_xof_turboshake128_squeeze arginfo_sodium_crypto_xof_shake128_squeeze + +#define arginfo_sodium_crypto_xof_turboshake256 arginfo_sodium_crypto_xof_shake128 + +#define arginfo_sodium_crypto_xof_turboshake256_init arginfo_sodium_crypto_xof_shake128_init + +#define arginfo_sodium_crypto_xof_turboshake256_update arginfo_sodium_crypto_xof_shake128_update + +#define arginfo_sodium_crypto_xof_turboshake256_squeeze arginfo_sodium_crypto_xof_shake128_squeeze +#endif + ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_is_available); #if defined(HAVE_AESGCM) ZEND_FUNCTION(sodium_crypto_aead_aes256gcm_decrypt); @@ -616,6 +705,40 @@ ZEND_FUNCTION(sodium_hex2bin); ZEND_FUNCTION(sodium_bin2base64); ZEND_FUNCTION(sodium_base642bin); #endif +#if defined(crypto_ipcrypt_KEYBYTES) +ZEND_FUNCTION(sodium_crypto_ipcrypt_keygen); +ZEND_FUNCTION(sodium_crypto_ipcrypt_encrypt); +ZEND_FUNCTION(sodium_crypto_ipcrypt_decrypt); +ZEND_FUNCTION(sodium_crypto_ipcrypt_nd_keygen); +ZEND_FUNCTION(sodium_crypto_ipcrypt_nd_encrypt); +ZEND_FUNCTION(sodium_crypto_ipcrypt_nd_decrypt); +ZEND_FUNCTION(sodium_crypto_ipcrypt_ndx_keygen); +ZEND_FUNCTION(sodium_crypto_ipcrypt_ndx_encrypt); +ZEND_FUNCTION(sodium_crypto_ipcrypt_ndx_decrypt); +ZEND_FUNCTION(sodium_crypto_ipcrypt_pfx_keygen); +ZEND_FUNCTION(sodium_crypto_ipcrypt_pfx_encrypt); +ZEND_FUNCTION(sodium_crypto_ipcrypt_pfx_decrypt); +ZEND_FUNCTION(sodium_bin2ip); +ZEND_FUNCTION(sodium_ip2bin); +#endif +#if defined(crypto_xof_shake128_STATEBYTES) +ZEND_FUNCTION(sodium_crypto_xof_shake128); +ZEND_FUNCTION(sodium_crypto_xof_shake128_init); +ZEND_FUNCTION(sodium_crypto_xof_shake128_update); +ZEND_FUNCTION(sodium_crypto_xof_shake128_squeeze); +ZEND_FUNCTION(sodium_crypto_xof_shake256); +ZEND_FUNCTION(sodium_crypto_xof_shake256_init); +ZEND_FUNCTION(sodium_crypto_xof_shake256_update); +ZEND_FUNCTION(sodium_crypto_xof_shake256_squeeze); +ZEND_FUNCTION(sodium_crypto_xof_turboshake128); +ZEND_FUNCTION(sodium_crypto_xof_turboshake128_init); +ZEND_FUNCTION(sodium_crypto_xof_turboshake128_update); +ZEND_FUNCTION(sodium_crypto_xof_turboshake128_squeeze); +ZEND_FUNCTION(sodium_crypto_xof_turboshake256); +ZEND_FUNCTION(sodium_crypto_xof_turboshake256_init); +ZEND_FUNCTION(sodium_crypto_xof_turboshake256_update); +ZEND_FUNCTION(sodium_crypto_xof_turboshake256_squeeze); +#endif static const zend_function_entry ext_functions[] = { ZEND_FE(sodium_crypto_aead_aes256gcm_is_available, arginfo_sodium_crypto_aead_aes256gcm_is_available) @@ -752,6 +875,40 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(sodium_base642bin, arginfo_sodium_base642bin) #endif ZEND_RAW_FENTRY("sodium_crypto_scalarmult_base", zif_sodium_crypto_box_publickey_from_secretkey, arginfo_sodium_crypto_scalarmult_base, 0, NULL, NULL) +#if defined(crypto_ipcrypt_KEYBYTES) + ZEND_FE(sodium_crypto_ipcrypt_keygen, arginfo_sodium_crypto_ipcrypt_keygen) + ZEND_FE(sodium_crypto_ipcrypt_encrypt, arginfo_sodium_crypto_ipcrypt_encrypt) + ZEND_FE(sodium_crypto_ipcrypt_decrypt, arginfo_sodium_crypto_ipcrypt_decrypt) + ZEND_FE(sodium_crypto_ipcrypt_nd_keygen, arginfo_sodium_crypto_ipcrypt_nd_keygen) + ZEND_FE(sodium_crypto_ipcrypt_nd_encrypt, arginfo_sodium_crypto_ipcrypt_nd_encrypt) + ZEND_FE(sodium_crypto_ipcrypt_nd_decrypt, arginfo_sodium_crypto_ipcrypt_nd_decrypt) + ZEND_FE(sodium_crypto_ipcrypt_ndx_keygen, arginfo_sodium_crypto_ipcrypt_ndx_keygen) + ZEND_FE(sodium_crypto_ipcrypt_ndx_encrypt, arginfo_sodium_crypto_ipcrypt_ndx_encrypt) + ZEND_FE(sodium_crypto_ipcrypt_ndx_decrypt, arginfo_sodium_crypto_ipcrypt_ndx_decrypt) + ZEND_FE(sodium_crypto_ipcrypt_pfx_keygen, arginfo_sodium_crypto_ipcrypt_pfx_keygen) + ZEND_FE(sodium_crypto_ipcrypt_pfx_encrypt, arginfo_sodium_crypto_ipcrypt_pfx_encrypt) + ZEND_FE(sodium_crypto_ipcrypt_pfx_decrypt, arginfo_sodium_crypto_ipcrypt_pfx_decrypt) + ZEND_FE(sodium_bin2ip, arginfo_sodium_bin2ip) + ZEND_FE(sodium_ip2bin, arginfo_sodium_ip2bin) +#endif +#if defined(crypto_xof_shake128_STATEBYTES) + ZEND_FE(sodium_crypto_xof_shake128, arginfo_sodium_crypto_xof_shake128) + ZEND_FE(sodium_crypto_xof_shake128_init, arginfo_sodium_crypto_xof_shake128_init) + ZEND_FE(sodium_crypto_xof_shake128_update, arginfo_sodium_crypto_xof_shake128_update) + ZEND_FE(sodium_crypto_xof_shake128_squeeze, arginfo_sodium_crypto_xof_shake128_squeeze) + ZEND_FE(sodium_crypto_xof_shake256, arginfo_sodium_crypto_xof_shake256) + ZEND_FE(sodium_crypto_xof_shake256_init, arginfo_sodium_crypto_xof_shake256_init) + ZEND_FE(sodium_crypto_xof_shake256_update, arginfo_sodium_crypto_xof_shake256_update) + ZEND_FE(sodium_crypto_xof_shake256_squeeze, arginfo_sodium_crypto_xof_shake256_squeeze) + ZEND_FE(sodium_crypto_xof_turboshake128, arginfo_sodium_crypto_xof_turboshake128) + ZEND_FE(sodium_crypto_xof_turboshake128_init, arginfo_sodium_crypto_xof_turboshake128_init) + ZEND_FE(sodium_crypto_xof_turboshake128_update, arginfo_sodium_crypto_xof_turboshake128_update) + ZEND_FE(sodium_crypto_xof_turboshake128_squeeze, arginfo_sodium_crypto_xof_turboshake128_squeeze) + ZEND_FE(sodium_crypto_xof_turboshake256, arginfo_sodium_crypto_xof_turboshake256) + ZEND_FE(sodium_crypto_xof_turboshake256_init, arginfo_sodium_crypto_xof_turboshake256_init) + ZEND_FE(sodium_crypto_xof_turboshake256_update, arginfo_sodium_crypto_xof_turboshake256_update) + ZEND_FE(sodium_crypto_xof_turboshake256_squeeze, arginfo_sodium_crypto_xof_turboshake256_squeeze) +#endif ZEND_FE_END }; @@ -883,6 +1040,30 @@ static void register_libsodium_symbols(int module_number) REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES", crypto_core_ristretto255_SCALARBYTES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES", crypto_core_ristretto255_NONREDUCEDSCALARBYTES, CONST_PERSISTENT); #endif +#if defined(crypto_ipcrypt_KEYBYTES) + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_BYTES", crypto_ipcrypt_BYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_KEYBYTES", crypto_ipcrypt_KEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES", crypto_ipcrypt_ND_KEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_TWEAKBYTES", crypto_ipcrypt_ND_TWEAKBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_INPUTBYTES", crypto_ipcrypt_ND_INPUTBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_ND_OUTPUTBYTES", crypto_ipcrypt_ND_OUTPUTBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES", crypto_ipcrypt_NDX_KEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_TWEAKBYTES", crypto_ipcrypt_NDX_TWEAKBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_INPUTBYTES", crypto_ipcrypt_NDX_INPUTBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES", crypto_ipcrypt_NDX_OUTPUTBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES", crypto_ipcrypt_PFX_KEYBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_IPCRYPT_PFX_BYTES", crypto_ipcrypt_PFX_BYTES, CONST_PERSISTENT); +#endif +#if defined(crypto_xof_shake128_STATEBYTES) + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE128_BLOCKBYTES", crypto_xof_shake128_BLOCKBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE128_STATEBYTES", crypto_xof_shake128_STATEBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE256_BLOCKBYTES", crypto_xof_shake256_BLOCKBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_SHAKE256_STATEBYTES", crypto_xof_shake256_STATEBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE128_BLOCKBYTES", crypto_xof_turboshake128_BLOCKBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE128_STATEBYTES", crypto_xof_turboshake128_STATEBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE256_BLOCKBYTES", crypto_xof_turboshake256_BLOCKBYTES, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_XOF_TURBOSHAKE256_STATEBYTES", crypto_xof_turboshake256_STATEBYTES, CONST_PERSISTENT); +#endif #if defined(HAVE_AESGCM) @@ -1060,6 +1241,24 @@ static void register_libsodium_symbols(int module_number) #endif zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_scalarmult_base", sizeof("sodium_crypto_scalarmult_base") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#if defined(crypto_ipcrypt_KEYBYTES) + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_encrypt", sizeof("sodium_crypto_ipcrypt_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_decrypt", sizeof("sodium_crypto_ipcrypt_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_nd_encrypt", sizeof("sodium_crypto_ipcrypt_nd_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_nd_decrypt", sizeof("sodium_crypto_ipcrypt_nd_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_ndx_encrypt", sizeof("sodium_crypto_ipcrypt_ndx_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_ndx_decrypt", sizeof("sodium_crypto_ipcrypt_ndx_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_pfx_encrypt", sizeof("sodium_crypto_ipcrypt_pfx_encrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "sodium_crypto_ipcrypt_pfx_decrypt", sizeof("sodium_crypto_ipcrypt_pfx_decrypt") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#endif } static zend_class_entry *register_class_SodiumException(zend_class_entry *class_entry_Exception) diff --git a/ext/sodium/php_libsodium.h b/ext/sodium/php_libsodium.h index 673541fe784c..8132472d684f 100644 --- a/ext/sodium/php_libsodium.h +++ b/ext/sodium/php_libsodium.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Frank Denis | +----------------------------------------------------------------------+ diff --git a/ext/sodium/sodium_pwhash.c b/ext/sodium/sodium_pwhash.c index eea7fe9eb0f1..ba48b0158cac 100644 --- a/ext/sodium/sodium_pwhash.c +++ b/ext/sodium/sodium_pwhash.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ @@ -87,7 +85,7 @@ static zend_string *php_sodium_argon2_hash(const zend_string *password, zend_arr static bool php_sodium_argon2_verify(const zend_string *password, const zend_string *hash) { if ((ZSTR_LEN(password) >= 0xffffffff) || (ZSTR_LEN(hash) >= 0xffffffff)) { - return 0; + return false; } return crypto_pwhash_str_verify(ZSTR_VAL(hash), ZSTR_VAL(password), ZSTR_LEN(password)) == 0; } @@ -96,7 +94,7 @@ static bool php_sodium_argon2_needs_rehash(const zend_string *hash, zend_array * size_t opslimit, memlimit; if (get_options(options, &memlimit, &opslimit) == FAILURE) { - return 1; + return true; } return crypto_pwhash_str_needs_rehash(ZSTR_VAL(hash), opslimit, memlimit); } diff --git a/ext/sodium/sodium_pwhash.stub.php b/ext/sodium/sodium_pwhash.stub.php index 58d7139c0ebc..82c04bfa4b1a 100644 --- a/ext/sodium/sodium_pwhash.stub.php +++ b/ext/sodium/sodium_pwhash.stub.php @@ -3,13 +3,7 @@ /** @generate-class-entries */ #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6) -/** - * @var string - */ const PASSWORD_ARGON2I = "argon2i"; -/** - * @var string - */ const PASSWORD_ARGON2ID = "argon2id"; /** * @var int @@ -26,8 +20,5 @@ * @cvalue PHP_SODIUM_PWHASH_THREADS */ const PASSWORD_ARGON2_DEFAULT_THREADS = UNKNOWN; -/** - * @var string - */ const PASSWORD_ARGON2_PROVIDER = "sodium"; #endif diff --git a/ext/sodium/sodium_pwhash_arginfo.h b/ext/sodium/sodium_pwhash_arginfo.h index 465f3090191d..6f4161900384 100644 --- a/ext/sodium/sodium_pwhash_arginfo.h +++ b/ext/sodium/sodium_pwhash_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: dd94e709f115ce05df0e25a8cb48c62438bb6d01 */ +/* This is a generated file, edit sodium_pwhash.stub.php instead. + * Stub hash: d1e804ceea5e18fc5a4eca50b318d98387b2a470 */ static void register_sodium_pwhash_symbols(int module_number) { diff --git a/ext/sodium/tests/crypto_ipcrypt.phpt b/ext/sodium/tests/crypto_ipcrypt.phpt new file mode 100644 index 000000000000..f398d21c70fc --- /dev/null +++ b/ext/sodium/tests/crypto_ipcrypt.phpt @@ -0,0 +1,63 @@ +--TEST-- +Check for libsodium ipcrypt +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +getMessage() . "\n"; +} + +/* Error: invalid IP */ +try { + sodium_crypto_ipcrypt_encrypt("not_an_ip", $key); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* Error: wrong key length for decrypt */ +try { + sodium_crypto_ipcrypt_decrypt("::1", "short"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +string(11) "192.168.1.1" +bool(true) +bool(true) +string(3) "::1" +bool(true) +sodium_crypto_ipcrypt_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long +sodium_crypto_ipcrypt_encrypt(): Argument #1 ($ip) must be a valid IP address +sodium_crypto_ipcrypt_decrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_KEYBYTES bytes long diff --git a/ext/sodium/tests/crypto_ipcrypt_nd.phpt b/ext/sodium/tests/crypto_ipcrypt_nd.phpt new file mode 100644 index 000000000000..fed36bbda444 --- /dev/null +++ b/ext/sodium/tests/crypto_ipcrypt_nd.phpt @@ -0,0 +1,98 @@ +--TEST-- +Check for libsodium ipcrypt non-deterministic (nd) and extended (ndx) +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +getMessage() . "\n"; +} + +/* ND error: invalid IP */ +try { + sodium_crypto_ipcrypt_nd_encrypt("bad", $nd_key); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* ND error: bad ciphertext hex length */ +try { + sodium_crypto_ipcrypt_nd_decrypt("tooshort", $nd_key); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* NDX: keygen, encrypt, decrypt roundtrip */ +$ndx_key = sodium_crypto_ipcrypt_ndx_keygen(); +var_dump(strlen($ndx_key) === SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES); + +$ct_ndx = sodium_crypto_ipcrypt_ndx_encrypt("10.0.0.1", $ndx_key); +var_dump(strlen($ct_ndx) === SODIUM_CRYPTO_IPCRYPT_NDX_OUTPUTBYTES * 2); +$pt_ndx = sodium_crypto_ipcrypt_ndx_decrypt($ct_ndx, $ndx_key); +var_dump($pt_ndx); + +/* NDX is non-deterministic */ +$ct_ndx2 = sodium_crypto_ipcrypt_ndx_encrypt("10.0.0.1", $ndx_key); +var_dump($ct_ndx !== $ct_ndx2); + +/* NDX: IPv6 */ +$ct_ndx6 = sodium_crypto_ipcrypt_ndx_encrypt("fe80::1", $ndx_key); +var_dump(sodium_crypto_ipcrypt_ndx_decrypt($ct_ndx6, $ndx_key)); + +/* NDX error: wrong key length */ +try { + sodium_crypto_ipcrypt_ndx_encrypt("10.0.0.1", "short"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* NDX error: bad ciphertext hex */ +try { + sodium_crypto_ipcrypt_ndx_decrypt("tooshort", $ndx_key); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +bool(true) +bool(true) +string(11) "192.168.1.1" +bool(true) +string(11) "192.168.1.1" +string(3) "::1" +sodium_crypto_ipcrypt_nd_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_ND_KEYBYTES bytes long +sodium_crypto_ipcrypt_nd_encrypt(): Argument #1 ($ip) must be a valid IP address +sodium_crypto_ipcrypt_nd_decrypt(): Argument #1 ($ciphertext_hex) must be a valid hex-encoded ciphertext +bool(true) +bool(true) +string(8) "10.0.0.1" +bool(true) +string(7) "fe80::1" +sodium_crypto_ipcrypt_ndx_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_NDX_KEYBYTES bytes long +sodium_crypto_ipcrypt_ndx_decrypt(): Argument #1 ($ciphertext_hex) must be a valid hex-encoded ciphertext diff --git a/ext/sodium/tests/crypto_ipcrypt_pfx.phpt b/ext/sodium/tests/crypto_ipcrypt_pfx.phpt new file mode 100644 index 000000000000..1ee51ef1f0e1 --- /dev/null +++ b/ext/sodium/tests/crypto_ipcrypt_pfx.phpt @@ -0,0 +1,65 @@ +--TEST-- +Check for libsodium ipcrypt prefix-preserving (pfx) +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +getMessage() . "\n"; +} + +/* PFX error: invalid IP */ +try { + sodium_crypto_ipcrypt_pfx_encrypt("not_an_ip", $key); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* PFX error: wrong key length for decrypt */ +try { + sodium_crypto_ipcrypt_pfx_decrypt("10.0.0.1", "short"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +string(8) "10.0.0.1" +bool(true) +bool(true) +string(3) "::1" +bool(true) +bool(true) +sodium_crypto_ipcrypt_pfx_encrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long +sodium_crypto_ipcrypt_pfx_encrypt(): Argument #1 ($ip) must be a valid IP address +sodium_crypto_ipcrypt_pfx_decrypt(): Argument #2 ($key) must be SODIUM_CRYPTO_IPCRYPT_PFX_KEYBYTES bytes long diff --git a/ext/sodium/tests/crypto_xof_shake128.phpt b/ext/sodium/tests/crypto_xof_shake128.phpt new file mode 100644 index 000000000000..cb075b7ec285 --- /dev/null +++ b/ext/sodium/tests/crypto_xof_shake128.phpt @@ -0,0 +1,104 @@ +--TEST-- +Check for libsodium XOF SHAKE128 +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +getMessage() . "\n"; +} + +/* Error: negative length */ +try { + sodium_crypto_xof_shake128(-1, "test"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* Error: domain out of range (0x00) */ +try { + sodium_crypto_xof_shake128_init(0); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* Error: domain out of range (0x80) */ +try { + sodium_crypto_xof_shake128_init(0x80); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* Error: bad state */ +try { + $bad = "not_a_state"; + sodium_crypto_xof_shake128_update($bad, "test"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +string(64) "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26" +string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8" +int(16) +int(64) +bool(true) +string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8" +string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8" +string(64) "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8" +string(64) "f3a3a89c329e644a7d2351744d9a28c953698b64102e912085ce1f6d79fa311e" +bool(true) +sodium_crypto_xof_shake128(): Argument #1 ($length) must be a positive integer +sodium_crypto_xof_shake128(): Argument #1 ($length) must be a positive integer +sodium_crypto_xof_shake128_init(): Argument #1 ($domain) must be between 0x01 and 0x7f +sodium_crypto_xof_shake128_init(): Argument #1 ($domain) must be between 0x01 and 0x7f +sodium_crypto_xof_shake128_update(): Argument #1 ($state) must have a correct state length diff --git a/ext/sodium/tests/crypto_xof_shake256.phpt b/ext/sodium/tests/crypto_xof_shake256.phpt new file mode 100644 index 000000000000..3e6916713328 --- /dev/null +++ b/ext/sodium/tests/crypto_xof_shake256.phpt @@ -0,0 +1,80 @@ +--TEST-- +Check for libsodium XOF SHAKE256 +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +getMessage() . "\n"; +} + +/* Error: bad state */ +try { + $bad = "not_a_state"; + sodium_crypto_xof_shake256_update($bad, "test"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* Error: squeeze bad length */ +try { + $state = sodium_crypto_xof_shake256_init(); + sodium_crypto_xof_shake256_update($state, "abc"); + sodium_crypto_xof_shake256_squeeze($state, 0); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +string(64) "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f" +string(64) "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739" +int(16) +int(64) +bool(true) +string(64) "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739" +string(64) "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739" +string(64) "1259d63c872d50fee4500685419f489966971c0a77e2058fab0e48dfb12d24bc" +sodium_crypto_xof_shake256(): Argument #1 ($length) must be a positive integer +sodium_crypto_xof_shake256_update(): Argument #1 ($state) must have a correct state length +sodium_crypto_xof_shake256_squeeze(): Argument #2 ($length) must be a positive integer diff --git a/ext/sodium/tests/crypto_xof_turboshake.phpt b/ext/sodium/tests/crypto_xof_turboshake.phpt new file mode 100644 index 000000000000..1f404140cc0b --- /dev/null +++ b/ext/sodium/tests/crypto_xof_turboshake.phpt @@ -0,0 +1,112 @@ +--TEST-- +Check for libsodium XOF TurboSHAKE128 and TurboSHAKE256 +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- +getMessage() . "\n"; +} + +/* TurboSHAKE256 error: bad state */ +try { + $bad = "not_a_state"; + sodium_crypto_xof_turboshake256_update($bad, "test"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* TurboSHAKE128 error: domain out of range */ +try { + sodium_crypto_xof_turboshake128_init(0); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +try { + sodium_crypto_xof_turboshake256_init(0x80); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +string(64) "1e415f1c5983aff2169217277d17bb538cd945a397ddec541f1ce41af2c1b74c" +string(64) "dcf1646dfe993a8eb6b782d1faaca6d82416a5dcf1de98ee3c6dbc5e1dc63018" +string(64) "367a329dafea871c7802ec67f905ae13c57695dc2c6663c61035f59a18f8e7db" +string(64) "63824b1431a7372e85edc022c9d7afdd027472fcfa33c887d6f5aaf8dc5d4db6" +string(64) "dcf1646dfe993a8eb6b782d1faaca6d82416a5dcf1de98ee3c6dbc5e1dc63018" +string(64) "63824b1431a7372e85edc022c9d7afdd027472fcfa33c887d6f5aaf8dc5d4db6" +string(64) "dcf1646dfe993a8eb6b782d1faaca6d82416a5dcf1de98ee3c6dbc5e1dc63018" +string(64) "63824b1431a7372e85edc022c9d7afdd027472fcfa33c887d6f5aaf8dc5d4db6" +string(64) "3f7566fb02630888cba2af090aaf544ac6e85484d8662335b0c0fd6b3c83ea1b" +string(64) "0137a7e8cca0b99e9bdd557a7caac1f21d65bc2a2ccbde1e1f8c702352a2bf30" +int(16) +int(64) +bool(true) +sodium_crypto_xof_turboshake128(): Argument #1 ($length) must be a positive integer +sodium_crypto_xof_turboshake256_update(): Argument #1 ($state) must have a correct state length +sodium_crypto_xof_turboshake128_init(): Argument #1 ($domain) must be between 0x01 and 0x7f +sodium_crypto_xof_turboshake256_init(): Argument #1 ($domain) must be between 0x01 and 0x7f diff --git a/ext/sodium/tests/sodium_bin2ip.phpt b/ext/sodium/tests/sodium_bin2ip.phpt new file mode 100644 index 000000000000..ab72b4b297ac --- /dev/null +++ b/ext/sodium/tests/sodium_bin2ip.phpt @@ -0,0 +1,69 @@ +--TEST-- +Check for libsodium bin2ip/ip2bin helpers +--EXTENSIONS-- +sodium +--SKIPIF-- += 1.0.21)"; +?> +--FILE-- + bin2ip roundtrip for various addresses */ +$addrs = ["0.0.0.0", "255.255.255.255", "127.0.0.1", "::ffff:192.168.0.1", "2001:db8::1"]; +foreach ($addrs as $addr) { + $result = sodium_bin2ip(sodium_ip2bin($addr)); + echo "$addr => $result\n"; +} + +/* Error: bin2ip wrong length */ +try { + sodium_bin2ip("short"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} + +/* Error: ip2bin invalid address */ +try { + sodium_ip2bin("not_an_ip"); +} catch (SodiumException $e) { + echo $e->getMessage() . "\n"; +} +?> +--EXPECT-- +int(16) +string(32) "00000000000000000000ffffc0a80101" +string(11) "192.168.1.1" +string(32) "00000000000000000000000000000001" +string(3) "::1" +string(32) "00000000000000000000ffff0a000001" +string(8) "10.0.0.1" +string(32) "fe800000000000000000000000000001" +string(7) "fe80::1" +0.0.0.0 => 0.0.0.0 +255.255.255.255 => 255.255.255.255 +127.0.0.1 => 127.0.0.1 +::ffff:192.168.0.1 => 192.168.0.1 +2001:db8::1 => 2001:db8::1 +sodium_bin2ip(): Argument #1 ($bin) must be 16 bytes long +sodium_ip2bin(): Argument #1 ($ip) must be a valid IP address diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 1149be29bd46..43fd04f7d021 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -32,12 +30,11 @@ #include "spl_dllist.h" #include "spl_fixedarray.h" #include "spl_heap.h" +#include "zend_autoload.h" #include "zend_exceptions.h" #include "zend_interfaces.h" -#include "main/snprintf.h" ZEND_TLS zend_string *spl_autoload_extensions; -ZEND_TLS HashTable *spl_autoload_functions; #define SPL_DEFAULT_FILE_EXTENSIONS ".inc,.php" @@ -61,12 +58,49 @@ static zend_class_entry * spl_find_ce_by_name(zend_string *name, bool autoload) return ce; } +static void spl_add_class_name(HashTable *list, zend_string *name) +{ + zval t; + ZVAL_STR_COPY(&t, name); + zend_hash_add(list, name, &t); +} + +static void spl_add_interfaces(HashTable *list, const zend_class_entry *pce) +{ + if (pce->num_interfaces) { + ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED); + for (uint32_t num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) { + spl_add_class_name(list, pce->interfaces[num_interfaces]->name); + } + } +} + +static void spl_add_traits(HashTable *list, const zend_class_entry *pce) +{ + for (uint32_t num_traits = 0; num_traits < pce->num_traits; num_traits++) { + spl_add_class_name(list, pce->trait_names[num_traits].name); + } +} + +static void spl_add_classes(HashTable *list, const zend_class_entry *pce, bool only_classes, bool only_interfaces) +{ + ZEND_ASSERT(pce); + ZEND_ASSERT(!(only_classes && only_interfaces) && "Cannot have both only classes and only interfaces be enabled"); + if ( + (only_classes && (pce->ce_flags & ZEND_ACC_INTERFACE) == ZEND_ACC_INTERFACE) + || (only_interfaces && (pce->ce_flags & ZEND_ACC_INTERFACE) == 0) + ) { + return; + } + spl_add_class_name(list, pce->name); +} + /* {{{ Return an array containing the names of all parent classes */ PHP_FUNCTION(class_parents) { zval *obj; - zend_class_entry *parent_class, *ce; - bool autoload = 1; + zend_class_entry *ce; + bool autoload = true; /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &obj, &autoload) == FAILURE) { @@ -87,9 +121,9 @@ PHP_FUNCTION(class_parents) } array_init(return_value); - parent_class = ce->parent; + const zend_class_entry *parent_class = ce->parent; while (parent_class) { - spl_add_class_name(return_value, parent_class, 0, 0); + spl_add_class_name(Z_ARR_P(return_value), parent_class->name); parent_class = parent_class->parent; } } @@ -99,8 +133,8 @@ PHP_FUNCTION(class_parents) PHP_FUNCTION(class_implements) { zval *obj; - bool autoload = 1; - zend_class_entry *ce; + bool autoload = true; + const zend_class_entry *ce; /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &obj, &autoload) == FAILURE) { @@ -120,7 +154,7 @@ PHP_FUNCTION(class_implements) } array_init(return_value); - spl_add_interfaces(return_value, ce, 1, ZEND_ACC_INTERFACE); + spl_add_interfaces(Z_ARR_P(return_value), ce); } /* }}} */ @@ -128,8 +162,8 @@ PHP_FUNCTION(class_implements) PHP_FUNCTION(class_uses) { zval *obj; - bool autoload = 1; - zend_class_entry *ce; + bool autoload = true; + const zend_class_entry *ce; /* We do not use Z_PARAM_OBJ_OR_STR here to be able to exclude int, float, and bool which are bogus class names */ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &obj, &autoload) == FAILURE) { @@ -149,98 +183,94 @@ PHP_FUNCTION(class_uses) } array_init(return_value); - spl_add_traits(return_value, ce, 1, ZEND_ACC_TRAIT); + spl_add_traits(Z_ARR_P(return_value), ce); } /* }}} */ -#define SPL_ADD_CLASS(class_name, z_list, sub, allow, ce_flags) \ - spl_add_classes(spl_ce_ ## class_name, z_list, sub, allow, ce_flags) - -#define SPL_LIST_CLASSES(z_list, sub, allow, ce_flags) \ - SPL_ADD_CLASS(AppendIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(ArrayIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(ArrayObject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(BadFunctionCallException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(BadMethodCallException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(CallbackFilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(DomainException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(EmptyIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(FilesystemIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(GlobIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(InfiniteIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(InvalidArgumentException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(IteratorIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(LengthException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(LimitIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(LogicException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(MultipleIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(NoRewindIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OuterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OutOfBoundsException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OutOfRangeException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(OverflowException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RangeException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveArrayIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveCachingIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveFilterIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveRegexIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RecursiveTreeIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RegexIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(RuntimeException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SeekableIterator, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplDoublyLinkedList, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplFileInfo, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplFileObject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplFixedArray, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplHeap, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplMinHeap, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplMaxHeap, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplObjectStorage, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplObserver, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplPriorityQueue, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplQueue, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplStack, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplSubject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(SplTempFileObject, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(UnderflowException, z_list, sub, allow, ce_flags); \ - SPL_ADD_CLASS(UnexpectedValueException, z_list, sub, allow, ce_flags); \ - -/* {{{ Return an array containing the names of all clsses and interfaces defined in SPL */ +#define SPL_ADD_CLASS(class_name, z_list, only_classes, only_interfaces) \ + spl_add_classes(Z_ARR_P(z_list), spl_ce_ ## class_name, only_classes, only_interfaces) + +#define SPL_LIST_CLASSES(z_list, only_classes, only_interfaces) \ + SPL_ADD_CLASS(AppendIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(ArrayIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(ArrayObject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(BadFunctionCallException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(BadMethodCallException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(CachingIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(CallbackFilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(DirectoryIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(DomainException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(EmptyIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(FilesystemIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(FilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(GlobIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(InfiniteIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(InvalidArgumentException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(IteratorIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(LengthException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(LimitIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(LogicException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(MultipleIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(NoRewindIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OuterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OutOfBoundsException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OutOfRangeException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(OverflowException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(ParentIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RangeException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveArrayIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveCachingIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveFilterIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveRegexIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RecursiveTreeIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RegexIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(RuntimeException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SeekableIterator, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplDoublyLinkedList, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplFileInfo, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplFileObject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplFixedArray, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplHeap, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplMinHeap, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplMaxHeap, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplObjectStorage, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplObserver, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplPriorityQueue, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplQueue, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplStack, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplSubject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(SplTempFileObject, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(UnderflowException, z_list, only_classes, only_interfaces); \ + SPL_ADD_CLASS(UnexpectedValueException, z_list, only_classes, only_interfaces); \ + +/* {{{ Return an array containing the names of all classes and interfaces defined in SPL */ PHP_FUNCTION(spl_classes) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); - SPL_LIST_CLASSES(return_value, 0, 0, 0) + SPL_LIST_CLASSES(return_value, false, false) } /* }}} */ -static int spl_autoload(zend_string *class_name, zend_string *lc_name, const char *ext, int ext_len) /* {{{ */ +static bool spl_autoload(zend_string *lc_name, const char *ext, size_t ext_len) /* {{{ */ { zend_string *class_file; zval dummy; zend_file_handle file_handle; - zend_op_array *new_op_array; zval result; - int ret; - class_file = zend_strpprintf(0, "%s%.*s", ZSTR_VAL(lc_name), ext_len, ext); + class_file = zend_string_concat2(ZSTR_VAL(lc_name), ZSTR_LEN(lc_name), ext, ext_len); #if DEFAULT_SLASH != '\\' { char *ptr = ZSTR_VAL(class_file); - char *end = ptr + ZSTR_LEN(class_file); + const char *end = ptr + ZSTR_LEN(class_file); while ((ptr = memchr(ptr, '\\', (end - ptr))) != NULL) { *ptr = DEFAULT_SLASH; @@ -248,22 +278,20 @@ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const cha } #endif + bool ret = false; zend_stream_init_filename_ex(&file_handle, class_file); - ret = php_stream_open_for_zend_ex(&file_handle, USE_PATH|STREAM_OPEN_FOR_INCLUDE); - - if (ret == SUCCESS) { + if (php_stream_open_for_zend_ex(&file_handle, USE_PATH|STREAM_OPEN_FOR_INCLUDE) == SUCCESS) { zend_string *opened_path; if (!file_handle.opened_path) { file_handle.opened_path = zend_string_copy(class_file); } opened_path = zend_string_copy(file_handle.opened_path); ZVAL_NULL(&dummy); + zend_op_array *new_op_array = NULL; if (zend_hash_add(&EG(included_files), opened_path, &dummy)) { new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE); - } else { - new_op_array = NULL; } - zend_string_release_ex(opened_path, 0); + zend_string_release_ex(opened_path, false); if (new_op_array) { uint32_t orig_jit_trace_num = EG(jit_trace_num); @@ -273,24 +301,20 @@ static int spl_autoload(zend_string *class_name, zend_string *lc_name, const cha destroy_op_array(new_op_array); efree(new_op_array); - if (!EG(exception)) { - zval_ptr_dtor(&result); - } + zval_ptr_dtor(&result); - zend_destroy_file_handle(&file_handle); - zend_string_release(class_file); - return zend_hash_exists(EG(class_table), lc_name); + ret = zend_hash_exists(EG(class_table), lc_name); } } zend_destroy_file_handle(&file_handle); zend_string_release(class_file); - return 0; + return ret; } /* }}} */ /* {{{ Default autoloader implementation */ PHP_FUNCTION(spl_autoload) { - int pos_len, pos1_len; + size_t pos_len, pos1_len; char *pos, *pos1; zend_string *class_name, *lc_name, *file_exts = NULL; @@ -307,18 +331,18 @@ PHP_FUNCTION(spl_autoload) pos_len = sizeof(SPL_DEFAULT_FILE_EXTENSIONS) - 1; } else { pos = ZSTR_VAL(file_exts); - pos_len = (int)ZSTR_LEN(file_exts); + pos_len = ZSTR_LEN(file_exts); } lc_name = zend_string_tolower(class_name); while (pos && *pos && !EG(exception)) { pos1 = strchr(pos, ','); if (pos1) { - pos1_len = (int)(pos1 - pos); + pos1_len = (size_t)(pos1 - pos); } else { pos1_len = pos_len; } - if (spl_autoload(class_name, lc_name, pos, pos1_len)) { + if (spl_autoload(lc_name, pos, pos1_len)) { break; /* loaded */ } pos = pos1 ? pos1 + 1 : NULL; @@ -351,113 +375,6 @@ PHP_FUNCTION(spl_autoload_extensions) } } /* }}} */ -typedef struct { - zend_function *func_ptr; - zend_object *obj; - zend_object *closure; - zend_class_entry *ce; -} autoload_func_info; - -static void autoload_func_info_destroy(autoload_func_info *alfi) { - if (alfi->obj) { - zend_object_release(alfi->obj); - } - if (alfi->func_ptr && - UNEXPECTED(alfi->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - zend_string_release_ex(alfi->func_ptr->common.function_name, 0); - zend_free_trampoline(alfi->func_ptr); - } - if (alfi->closure) { - zend_object_release(alfi->closure); - } - efree(alfi); -} - -static void autoload_func_info_zval_dtor(zval *element) -{ - autoload_func_info_destroy(Z_PTR_P(element)); -} - -static autoload_func_info *autoload_func_info_from_fci( - zend_fcall_info *fci, zend_fcall_info_cache *fcc) { - autoload_func_info *alfi = emalloc(sizeof(autoload_func_info)); - alfi->ce = fcc->calling_scope; - alfi->func_ptr = fcc->function_handler; - alfi->obj = fcc->object; - if (alfi->obj) { - GC_ADDREF(alfi->obj); - } - if (Z_TYPE(fci->function_name) == IS_OBJECT) { - alfi->closure = Z_OBJ(fci->function_name); - GC_ADDREF(alfi->closure); - } else { - alfi->closure = NULL; - } - return alfi; -} - -static bool autoload_func_info_equals( - const autoload_func_info *alfi1, const autoload_func_info *alfi2) { - if (UNEXPECTED( - (alfi1->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) && - (alfi2->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) - )) { - return alfi1->obj == alfi2->obj - && alfi1->ce == alfi2->ce - && alfi1->closure == alfi2->closure - && zend_string_equals(alfi1->func_ptr->common.function_name, alfi2->func_ptr->common.function_name) - ; - } - return alfi1->func_ptr == alfi2->func_ptr - && alfi1->obj == alfi2->obj - && alfi1->ce == alfi2->ce - && alfi1->closure == alfi2->closure; -} - -static zend_class_entry *spl_perform_autoload(zend_string *class_name, zend_string *lc_name) { - if (!spl_autoload_functions) { - return NULL; - } - - /* We don't use ZEND_HASH_MAP_FOREACH here, - * because autoloaders may be added/removed during autoloading. */ - HashPosition pos; - zend_hash_internal_pointer_reset_ex(spl_autoload_functions, &pos); - while (1) { - autoload_func_info *alfi = - zend_hash_get_current_data_ptr_ex(spl_autoload_functions, &pos); - if (!alfi) { - break; - } - - zend_function *func = alfi->func_ptr; - if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - func = emalloc(sizeof(zend_op_array)); - memcpy(func, alfi->func_ptr, sizeof(zend_op_array)); - zend_string_addref(func->op_array.function_name); - } - - zval param; - ZVAL_STR(¶m, class_name); - zend_call_known_function(func, alfi->obj, alfi->ce, NULL, 1, ¶m, NULL); - if (EG(exception)) { - break; - } - - if (ZSTR_HAS_CE_CACHE(class_name) && ZSTR_GET_CE_CACHE(class_name)) { - return (zend_class_entry*)ZSTR_GET_CE_CACHE(class_name); - } else { - zend_class_entry *ce = zend_hash_find_ptr(EG(class_table), lc_name); - if (ce) { - return ce; - } - } - - zend_hash_move_forward_ex(spl_autoload_functions, &pos); - } - return NULL; -} - /* {{{ Try all registered autoload function to load the requested class */ PHP_FUNCTION(spl_autoload_call) { @@ -468,34 +385,10 @@ PHP_FUNCTION(spl_autoload_call) } zend_string *lc_name = zend_string_tolower(class_name); - spl_perform_autoload(class_name, lc_name); + zend_perform_class_autoload(class_name, lc_name); zend_string_release(lc_name); } /* }}} */ -#define HT_MOVE_TAIL_TO_HEAD(ht) \ - ZEND_ASSERT(!HT_IS_PACKED(ht)); \ - do { \ - Bucket tmp = (ht)->arData[(ht)->nNumUsed-1]; \ - memmove((ht)->arData + 1, (ht)->arData, \ - sizeof(Bucket) * ((ht)->nNumUsed - 1)); \ - (ht)->arData[0] = tmp; \ - zend_hash_rehash(ht); \ - } while (0) - -static Bucket *spl_find_registered_function(autoload_func_info *find_alfi) { - if (!spl_autoload_functions) { - return NULL; - } - - autoload_func_info *alfi; - ZEND_HASH_MAP_FOREACH_PTR(spl_autoload_functions, alfi) { - if (autoload_func_info_equals(alfi, find_alfi)) { - return _p; - } - } ZEND_HASH_FOREACH_END(); - return NULL; -} - /* {{{ Register given function as autoloader */ PHP_FUNCTION(spl_autoload_register) { @@ -503,7 +396,6 @@ PHP_FUNCTION(spl_autoload_register) bool prepend = 0; zend_fcall_info fci = {0}; zend_fcall_info_cache fcc; - autoload_func_info *alfi; ZEND_PARSE_PARAMETERS_START(0, 3) Z_PARAM_OPTIONAL @@ -517,16 +409,9 @@ PHP_FUNCTION(spl_autoload_register) "spl_autoload_register() will always throw"); } - if (!spl_autoload_functions) { - ALLOC_HASHTABLE(spl_autoload_functions); - zend_hash_init(spl_autoload_functions, 1, NULL, autoload_func_info_zval_dtor, 0); - /* Initialize as non-packed hash table for prepend functionality. */ - zend_hash_real_init_mixed(spl_autoload_functions); - } - /* If first arg is not null */ if (ZEND_FCI_INITIALIZED(fci)) { - if (!fcc.function_handler) { + if (!ZEND_FCC_INITIALIZED(fcc)) { /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal * with it ourselves. It is important that it is not refetched on every call, * because calls may occur from different scopes. */ @@ -538,34 +423,12 @@ PHP_FUNCTION(spl_autoload_register) zend_argument_value_error(1, "must not be the spl_autoload_call() function"); RETURN_THROWS(); } - - alfi = autoload_func_info_from_fci(&fci, &fcc); - if (UNEXPECTED(alfi->func_ptr == &EG(trampoline))) { - zend_function *copy = emalloc(sizeof(zend_op_array)); - - memcpy(copy, alfi->func_ptr, sizeof(zend_op_array)); - alfi->func_ptr->common.function_name = NULL; - alfi->func_ptr = copy; - } } else { - alfi = emalloc(sizeof(autoload_func_info)); - alfi->func_ptr = zend_hash_str_find_ptr( - CG(function_table), "spl_autoload", sizeof("spl_autoload") - 1); - alfi->obj = NULL; - alfi->ce = NULL; - alfi->closure = NULL; + memset(&fcc, 0, sizeof(fcc)); + fcc.function_handler = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("spl_autoload")); } - if (spl_find_registered_function(alfi)) { - autoload_func_info_destroy(alfi); - RETURN_TRUE; - } - - zend_hash_next_index_insert_ptr(spl_autoload_functions, alfi); - if (prepend && spl_autoload_functions->nNumOfElements > 1) { - /* Move the newly created element to the head of the hashtable */ - HT_MOVE_TAIL_TO_HEAD(spl_autoload_functions); - } + zend_autoload_register_class_loader(&fcc, prepend); RETURN_TRUE; } /* }}} */ @@ -577,68 +440,34 @@ PHP_FUNCTION(spl_autoload_unregister) zend_fcall_info_cache fcc; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_FUNC(fci, fcc) + Z_PARAM_FUNC_NO_TRAMPOLINE_FREE(fci, fcc) ZEND_PARSE_PARAMETERS_END(); - if (fcc.function_handler && zend_string_equals_literal( - fcc.function_handler->common.function_name, "spl_autoload_call")) { - if (spl_autoload_functions) { - /* Don't destroy the hash table, as we might be iterating over it right now. */ - zend_hash_clean(spl_autoload_functions); + if (zend_string_equals_literal(fcc.function_handler->common.function_name, "spl_autoload_call")) { + /* Release trampoline */ + zend_release_fcall_info_cache(&fcc); + php_error_docref(NULL, E_DEPRECATED, + "Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated," + " to remove all registered autoloaders, call spl_autoload_unregister()" + " for all values returned from spl_autoload_functions()"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); } + zend_autoload_clean_class_loaders(); RETURN_TRUE; } - if (!fcc.function_handler) { - /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal - * with it ourselves. It is important that it is not refetched on every call, - * because calls may occur from different scopes. */ - zend_is_callable_ex(&fci.function_name, NULL, 0, NULL, &fcc, NULL); - } - - autoload_func_info *alfi = autoload_func_info_from_fci(&fci, &fcc); - Bucket *p = spl_find_registered_function(alfi); - autoload_func_info_destroy(alfi); - if (p) { - zend_hash_del_bucket(spl_autoload_functions, p); - RETURN_TRUE; - } - - RETURN_FALSE; + RETVAL_BOOL(zend_autoload_unregister_class_loader(&fcc)); + /* Release trampoline */ + zend_release_fcall_info_cache(&fcc); } /* }}} */ /* {{{ Return all registered autoloader functions */ PHP_FUNCTION(spl_autoload_functions) { - autoload_func_info *alfi; - - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); - array_init(return_value); - if (spl_autoload_functions) { - ZEND_HASH_MAP_FOREACH_PTR(spl_autoload_functions, alfi) { - if (alfi->closure) { - GC_ADDREF(alfi->closure); - add_next_index_object(return_value, alfi->closure); - } else if (alfi->func_ptr->common.scope) { - zval tmp; - - array_init(&tmp); - if (alfi->obj) { - GC_ADDREF(alfi->obj); - add_next_index_object(&tmp, alfi->obj); - } else { - add_next_index_str(&tmp, zend_string_copy(alfi->ce->name)); - } - add_next_index_str(&tmp, zend_string_copy(alfi->func_ptr->common.function_name)); - add_next_index_zval(return_value, &tmp); - } else { - add_next_index_str(return_value, zend_string_copy(alfi->func_ptr->common.function_name)); - } - } ZEND_HASH_FOREACH_END(); - } + zend_autoload_fcc_map_to_callable_zval_map(return_value); } /* }}} */ /* {{{ Return hash id for given object */ @@ -692,7 +521,7 @@ PHP_MINFO_FUNCTION(spl) php_info_print_table_row(2, "SPL support", "enabled"); array_init(&list); - SPL_LIST_CLASSES(&list, 0, 1, ZEND_ACC_INTERFACE) + SPL_LIST_CLASSES(&list, false, true) strg = estrdup(""); ZEND_HASH_MAP_FOREACH_VAL(Z_ARRVAL_P(&list), zv) { spl_build_class_list_string(zv, &strg); @@ -702,7 +531,7 @@ PHP_MINFO_FUNCTION(spl) efree(strg); array_init(&list); - SPL_LIST_CLASSES(&list, 0, -1, ZEND_ACC_INTERFACE) + SPL_LIST_CLASSES(&list, true, false) strg = estrdup(""); ZEND_HASH_MAP_FOREACH_VAL(Z_ARRVAL_P(&list), zv) { spl_build_class_list_string(zv, &strg); @@ -718,8 +547,6 @@ PHP_MINFO_FUNCTION(spl) /* {{{ PHP_MINIT_FUNCTION(spl) */ PHP_MINIT_FUNCTION(spl) { - zend_autoload = spl_perform_autoload; - PHP_MINIT(spl_exceptions)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(spl_iterators)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(spl_array)(INIT_FUNC_ARGS_PASSTHRU); @@ -736,7 +563,6 @@ PHP_MINIT_FUNCTION(spl) PHP_RINIT_FUNCTION(spl) /* {{{ */ { spl_autoload_extensions = NULL; - spl_autoload_functions = NULL; return SUCCESS; } /* }}} */ @@ -746,11 +572,6 @@ PHP_RSHUTDOWN_FUNCTION(spl) /* {{{ */ zend_string_release_ex(spl_autoload_extensions, 0); spl_autoload_extensions = NULL; } - if (spl_autoload_functions) { - zend_hash_destroy(spl_autoload_functions); - FREE_HASHTABLE(spl_autoload_functions); - spl_autoload_functions = NULL; - } return SUCCESS; } /* }}} */ diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index c2f7ebf9eee1..b1d4f4416a79 100644 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/php_spl_arginfo.h b/ext/spl/php_spl_arginfo.h index 68c71fc524bc..8b0ea4b7245b 100644 --- a/ext/spl/php_spl_arginfo.h +++ b/ext/spl/php_spl_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit php_spl.stub.php instead. * Stub hash: 21ec2dcca99c85c90afcd319da76016a9f678dc2 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_implements, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index b95033006192..0105af776137 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -44,8 +42,6 @@ typedef struct _spl_array_object { uint32_t ht_iter; int ar_flags; unsigned char nApplyCount; - bool is_child; - Bucket *bucket; zend_function *fptr_offset_get; zend_function *fptr_offset_set; zend_function *fptr_offset_has; @@ -56,7 +52,7 @@ typedef struct _spl_array_object { } spl_array_object; static inline spl_array_object *spl_array_from_obj(zend_object *obj) /* {{{ */ { - return (spl_array_object*)((char*)(obj) - XtOffsetOf(spl_array_object, std)); + return ZEND_CONTAINER_OF(obj, spl_array_object, std); } /* }}} */ @@ -157,7 +153,7 @@ static void spl_array_object_free_storage(zend_object *object) static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zend_object *orig, int clone_orig) { spl_array_object *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; int inherited = 0; intern = zend_object_alloc(sizeof(spl_array_object), parent); @@ -166,8 +162,6 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zend_o object_properties_init(&intern->std, class_type); intern->ar_flags = 0; - intern->is_child = false; - intern->bucket = NULL; intern->ce_get_iterator = spl_ce_ArrayIterator; if (orig) { spl_array_object *other = spl_array_from_obj(orig); @@ -280,6 +274,7 @@ static zend_result get_hash_key(spl_hash_key *key, spl_array_object *intern, zva try_again: switch (Z_TYPE_P(offset)) { case IS_NULL: + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); key->key = ZSTR_EMPTY_ALLOC(); return SUCCESS; case IS_STRING: @@ -464,22 +459,6 @@ static zval *spl_array_read_dimension(zend_object *object, zval *offset, int typ return spl_array_read_dimension_ex(1, object, offset, type, rv); } /* }}} */ -/* - * The assertion(HT_ASSERT_RC1(ht)) failed because the refcount was increased manually when intern->is_child is true. - * We have to set the refcount to 1 to make assertion success and restore the refcount to the original value after - * modifying the array when intern->is_child is true. - */ -static uint32_t spl_array_set_refcount(bool is_child, HashTable *ht, uint32_t refcount) /* {{{ */ -{ - uint32_t old_refcount = 0; - if (is_child) { - old_refcount = GC_REFCOUNT(ht); - GC_SET_REFCOUNT(ht, refcount); - } - - return old_refcount; -} /* }}} */ - static void spl_array_write_dimension_ex(int check_inherited, zend_object *object, zval *offset, zval *value) /* {{{ */ { spl_array_object *intern = spl_array_from_obj(object); @@ -503,19 +482,12 @@ static void spl_array_write_dimension_ex(int check_inherited, zend_object *objec } Z_TRY_ADDREF_P(value); - - uint32_t refcount = 0; if (!offset || Z_TYPE_P(offset) == IS_NULL) { ht = spl_array_get_hash_table(intern); if (UNEXPECTED(ht == intern->sentinel_array)) { return; } - refcount = spl_array_set_refcount(intern->is_child, ht, 1); zend_hash_next_index_insert(ht, value); - - if (refcount) { - spl_array_set_refcount(intern->is_child, ht, refcount); - } return; } @@ -530,17 +502,13 @@ static void spl_array_write_dimension_ex(int check_inherited, zend_object *objec spl_hash_key_release(&key); return; } - refcount = spl_array_set_refcount(intern->is_child, ht, 1); + if (key.key) { zend_hash_update_ind(ht, key.key, value); spl_hash_key_release(&key); } else { zend_hash_index_update(ht, key.h, value); } - - if (refcount) { - spl_array_set_refcount(intern->is_child, ht, refcount); - } } /* }}} */ static void spl_array_write_dimension(zend_object *object, zval *offset, zval *value) /* {{{ */ @@ -570,8 +538,6 @@ static void spl_array_unset_dimension_ex(int check_inherited, zend_object *objec } ht = spl_array_get_hash_table(intern); - uint32_t refcount = spl_array_set_refcount(intern->is_child, ht, 1); - if (key.key) { zval *data = zend_hash_find(ht, key.key); if (data) { @@ -596,10 +562,6 @@ static void spl_array_unset_dimension_ex(int check_inherited, zend_object *objec } else { zend_hash_index_del(ht, key.h); } - - if (refcount) { - spl_array_set_refcount(intern->is_child, ht, refcount); - } } /* }}} */ static void spl_array_unset_dimension(zend_object *object, zval *offset) /* {{{ */ @@ -620,13 +582,13 @@ static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object if (!zend_is_true(&rv)) { zval_ptr_dtor(&rv); - return 0; + return false; } zval_ptr_dtor(&rv); /* For isset calls we don't need to check the value, so return early */ if (!check_empty) { - return 1; + return true; } else if (intern->fptr_offset_get) { value = spl_array_read_dimension_ex(1, object, offset, BP_VAR_R, &rv); } @@ -638,7 +600,7 @@ static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object if (get_hash_key(&key, intern, offset) == FAILURE) { zend_illegal_container_offset(object->ce->name, offset, BP_VAR_IS); - return 0; + return false; } if (key.key) { @@ -649,13 +611,13 @@ static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object } if (!tmp) { - return 0; + return false; } /* check_empty is only equal to 2 if it is called from offsetExists on this class, * where it needs to report an offset exists even if the value is null */ if (check_empty == 2) { - return 1; + return true; } if (check_empty && check_inherited && intern->fptr_offset_get) { @@ -752,9 +714,7 @@ PHP_METHOD(ArrayObject, getArrayCopy) zval *object = ZEND_THIS; spl_array_object *intern = Z_SPLARRAY_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_ARR(zend_array_dup(spl_array_get_hash_table(intern))); } /* }}} */ @@ -776,11 +736,11 @@ static HashTable *spl_array_get_properties_for(zend_object *object, zend_prop_pu * meantime. */ switch (purpose) { case ZEND_PROP_PURPOSE_ARRAY_CAST: - dup = 1; + dup = true; break; case ZEND_PROP_PURPOSE_VAR_EXPORT: case ZEND_PROP_PURPOSE_JSON: - dup = 0; + dup = false; break; default: return zend_std_get_properties_for(object, purpose); @@ -874,7 +834,7 @@ static zval *spl_array_get_property_ptr_ptr(zend_object *object, zend_string *na return NULL; } ZVAL_STR(&member, name); - return spl_array_get_dimension_ptr(1, intern, object->ce->name, &member, type); + return spl_array_get_dimension_ptr(true, intern, object->ce->name, &member, type); } return zend_std_get_property_ptr_ptr(object, name, type, cache_slot); } /* }}} */ @@ -973,17 +933,14 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar } else { //??? TODO: try to avoid array duplication ZVAL_ARR(&intern->array, zend_array_dup(Z_ARR_P(array))); - - if (intern->is_child) { - Z_TRY_DELREF(intern->bucket->val); - /* - * replace bucket->val with copied array, so the changes between - * parent and child object can affect each other. - */ - ZVAL_COPY(&intern->bucket->val, &intern->array); - } } } else { + php_error_docref(NULL, E_DEPRECATED, + "Using an object as a backing array for %s is deprecated, as it allows violating class constraints and invariants", + instanceof_function(Z_OBJCE_P(object), spl_ce_ArrayIterator) ? "ArrayIterator" : "ArrayObject"); + if (UNEXPECTED(EG(exception))) { + return; + } if (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject) { ZVAL_COPY_VALUE(&garbage, &intern->array); if (just_array) { @@ -1079,9 +1036,7 @@ PHP_METHOD(ArrayObject, getIteratorClass) zval *object = ZEND_THIS; spl_array_object *intern = Z_SPLARRAY_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_string_addref(intern->ce_get_iterator->name); RETURN_STR(intern->ce_get_iterator->name); @@ -1094,9 +1049,7 @@ PHP_METHOD(ArrayObject, getFlags) zval *object = ZEND_THIS; spl_array_object *intern = Z_SPLARRAY_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(intern->ar_flags & ~SPL_ARRAY_INT_MASK); } @@ -1133,7 +1086,7 @@ PHP_METHOD(ArrayObject, exchangeArray) } RETVAL_ARR(zend_array_dup(spl_array_get_hash_table(intern))); - spl_array_set_array(object, intern, array, 0L, 1); + spl_array_set_array(object, intern, array, 0L, true); } /* }}} */ @@ -1143,9 +1096,7 @@ PHP_METHOD(ArrayObject, getIterator) zval *object = ZEND_THIS; spl_array_object *intern = Z_SPLARRAY_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_OBJ(spl_array_object_new_ex(intern->ce_get_iterator, Z_OBJ_P(object), 0)); } @@ -1196,50 +1147,59 @@ PHP_METHOD(ArrayObject, count) { spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(spl_array_object_count_elements_helper(intern)); } /* }}} */ -static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, size_t fname_len, int use_arg) /* {{{ */ +enum spl_array_object_sort_methods { + SPL_NAT_SORT, + SPL_CALLBACK_SORT, + SPL_OPTIONAL_FLAG_SORT +}; + +static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, const char *fname, size_t fname_len, enum spl_array_object_sort_methods use_arg) /* {{{ */ { spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS); HashTable **ht_ptr = spl_array_get_hash_table_ptr(intern); HashTable *aht = *ht_ptr; - zval function_name, params[2], *arg = NULL; + zval params[2], *arg = NULL; - ZVAL_STRINGL(&function_name, fname, fname_len); + zend_function *fn = zend_hash_str_find_ptr(EG(function_table), fname, fname_len); + if (UNEXPECTED(fn == NULL)) { + zend_throw_error(NULL, "Cannot call method %s when function %s is disabled", fname, fname); + RETURN_THROWS(); + } ZVAL_NEW_EMPTY_REF(¶ms[0]); ZVAL_ARR(Z_REFVAL(params[0]), aht); GC_ADDREF(aht); - if (!use_arg) { + if (use_arg == SPL_NAT_SORT) { if (zend_parse_parameters_none() == FAILURE) { goto exit; } intern->nApplyCount++; - call_user_function(EG(function_table), NULL, &function_name, return_value, 1, params); + zend_call_known_function(fn, NULL, NULL, return_value, 1, params, NULL); intern->nApplyCount--; - } else if (use_arg == SPL_ARRAY_METHOD_SORT_FLAGS_ARG) { + } else if (use_arg == SPL_OPTIONAL_FLAG_SORT) { zend_long sort_flags = 0; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &sort_flags) == FAILURE) { goto exit; } ZVAL_LONG(¶ms[1], sort_flags); intern->nApplyCount++; - call_user_function(EG(function_table), NULL, &function_name, return_value, 2, params); + zend_call_known_function(fn, NULL, NULL, return_value, 2, params, NULL); intern->nApplyCount--; } else { + ZEND_ASSERT(use_arg == SPL_CALLBACK_SORT); if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg) == FAILURE) { goto exit; } ZVAL_COPY_VALUE(¶ms[1], arg); intern->nApplyCount++; - call_user_function(EG(function_table), NULL, &function_name, return_value, 2, params); + zend_call_known_function(fn, NULL, NULL, return_value, 2, params, NULL); intern->nApplyCount--; } @@ -1251,7 +1211,6 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, size_t f *ht_ptr = Z_ARRVAL_P(ht_zv); ZVAL_NULL(ht_zv); zval_ptr_dtor(¶ms[0]); - zend_string_free(Z_STR(function_name)); } } /* }}} */ @@ -1261,23 +1220,23 @@ PHP_METHOD(cname, fname) \ spl_array_method(INTERNAL_FUNCTION_PARAM_PASSTHRU, #fname, sizeof(#fname)-1, use_arg); \ } -/* {{{ Sort the entries by values. */ -SPL_ARRAY_METHOD(ArrayObject, asort, SPL_ARRAY_METHOD_SORT_FLAGS_ARG) /* }}} */ +/* Sort the entries by values. */ +SPL_ARRAY_METHOD(ArrayObject, asort, SPL_OPTIONAL_FLAG_SORT) -/* {{{ Sort the entries by key. */ -SPL_ARRAY_METHOD(ArrayObject, ksort, SPL_ARRAY_METHOD_SORT_FLAGS_ARG) /* }}} */ +/* Sort the entries by key. */ +SPL_ARRAY_METHOD(ArrayObject, ksort, SPL_OPTIONAL_FLAG_SORT) -/* {{{ Sort the entries by values user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uasort, SPL_ARRAY_METHOD_CALLBACK_ARG) /* }}} */ +/* Sort the entries by values user defined function. */ +SPL_ARRAY_METHOD(ArrayObject, uasort, SPL_CALLBACK_SORT) -/* {{{ Sort the entries by key using user defined function. */ -SPL_ARRAY_METHOD(ArrayObject, uksort, SPL_ARRAY_METHOD_CALLBACK_ARG) /* }}} */ +/* Sort the entries by key using user defined function. */ +SPL_ARRAY_METHOD(ArrayObject, uksort, SPL_CALLBACK_SORT) -/* {{{ Sort the entries by values using "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natsort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */ +/* Sort the entries by values using "natural order" algorithm. */ +SPL_ARRAY_METHOD(ArrayObject, natsort, SPL_NAT_SORT) -/* {{{ Sort the entries by key using case insensitive "natural order" algorithm. */ -SPL_ARRAY_METHOD(ArrayObject, natcasesort, SPL_ARRAY_METHOD_NO_ARG) /* }}} */ +/* {{{ Sort the entries by key using case-insensitive "natural order" algorithm. */ +SPL_ARRAY_METHOD(ArrayObject, natcasesort, SPL_NAT_SORT) /* {{{ Serialize the object */ PHP_METHOD(ArrayObject, serialize) @@ -1288,9 +1247,7 @@ PHP_METHOD(ArrayObject, serialize) php_serialize_data_t var_hash; smart_str buf = {0}; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHP_VAR_SERIALIZE_INIT(var_hash); @@ -1396,7 +1353,7 @@ PHP_METHOD(ArrayObject, unserialize) ZVAL_NULL(array); SEPARATE_ARRAY(&intern->array); } else { - spl_array_set_array(object, intern, array, 0L, 1); + spl_array_set_array(object, intern, array, 0L, true); } if (*p != ';') { @@ -1436,9 +1393,7 @@ PHP_METHOD(ArrayObject, __serialize) spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS); zval tmp; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -1509,7 +1464,7 @@ PHP_METHOD(ArrayObject, __unserialize) zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object", 0); RETURN_THROWS(); } - spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, 1); + spl_array_set_array(ZEND_THIS, intern, storage_zv, 0L, true); } object_properties_load(&intern->std, Z_ARRVAL_P(members_zv)); @@ -1542,9 +1497,7 @@ PHP_METHOD(ArrayObject, __unserialize) /* {{{ */ PHP_METHOD(ArrayObject, __debugInfo) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_ARR(spl_array_get_debug_info(Z_OBJ_P(ZEND_THIS))); } /* }}} */ @@ -1722,9 +1675,7 @@ PHP_METHOD(ArrayIterator, rewind) zval *object = ZEND_THIS; spl_array_object *intern = Z_SPLARRAY_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_array_rewind(intern); } @@ -1766,9 +1717,7 @@ PHP_METHOD(ArrayIterator, current) zval *entry; HashTable *aht = spl_array_get_hash_table(intern); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if ((entry = zend_hash_get_current_data_ex(aht, spl_array_get_pos_ptr(aht, intern))) == NULL) { RETURN_NULL(); @@ -1795,9 +1744,7 @@ void spl_array_iterator_key(zval *object, zval *return_value) /* {{{ */ /* {{{ Return current array key */ PHP_METHOD(ArrayIterator, key) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_array_iterator_key(ZEND_THIS, return_value); } /* }}} */ @@ -1809,9 +1756,7 @@ PHP_METHOD(ArrayIterator, next) spl_array_object *intern = Z_SPLARRAY_P(object); HashTable *aht = spl_array_get_hash_table(intern); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_array_next_ex(intern, aht); } @@ -1824,9 +1769,7 @@ PHP_METHOD(ArrayIterator, valid) spl_array_object *intern = Z_SPLARRAY_P(object); HashTable *aht = spl_array_get_hash_table(intern); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(zend_hash_has_more_elements_ex(aht, spl_array_get_pos_ptr(aht, intern)) == SUCCESS); } @@ -1841,9 +1784,7 @@ PHP_METHOD(RecursiveArrayIterator, hasChildren) spl_array_object *intern = Z_SPLARRAY_P(object); HashTable *aht = spl_array_get_hash_table(intern); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if ((entry = zend_hash_get_current_data_ex(aht, spl_array_get_pos_ptr(aht, intern))) == NULL) { RETURN_FALSE; @@ -1861,15 +1802,6 @@ PHP_METHOD(RecursiveArrayIterator, hasChildren) static void spl_instantiate_child_arg(zend_class_entry *pce, zval *retval, zval *arg1, zval *arg2) /* {{{ */ { object_init_ex(retval, pce); - spl_array_object *new_intern = Z_SPLARRAY_P(retval); - /* - * set new_intern->is_child is true to indicate that the object was created by - * RecursiveArrayIterator::getChildren() method. - */ - new_intern->is_child = true; - - /* find the bucket of parent object. */ - new_intern->bucket = (Bucket *)((char *)(arg1) - XtOffsetOf(Bucket, val));; zend_call_known_instance_method_with_2_params(pce->constructor, Z_OBJ_P(retval), NULL, arg1, arg2); } /* }}} */ @@ -1881,9 +1813,7 @@ PHP_METHOD(RecursiveArrayIterator, getChildren) spl_array_object *intern = Z_SPLARRAY_P(object); HashTable *aht = spl_array_get_hash_table(intern); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if ((entry = zend_hash_get_current_data_ex(aht, spl_array_get_pos_ptr(aht, intern))) == NULL) { RETURN_NULL(); @@ -1917,7 +1847,7 @@ PHP_MINIT_FUNCTION(spl_array) memcpy(&spl_handler_ArrayObject, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_ArrayObject.offset = XtOffsetOf(spl_array_object, std); + spl_handler_ArrayObject.offset = offsetof(spl_array_object, std); spl_handler_ArrayObject.clone_obj = spl_array_object_clone; spl_handler_ArrayObject.read_dimension = spl_array_read_dimension; diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index f3577f4beeaa..f99bb3f6fe88 100644 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -27,10 +25,6 @@ #define SPL_ARRAY_INT_MASK 0xFFFF0000 #define SPL_ARRAY_CLONE_MASK 0x0100FFFF -#define SPL_ARRAY_METHOD_NO_ARG 0 -#define SPL_ARRAY_METHOD_CALLBACK_ARG 1 -#define SPL_ARRAY_METHOD_SORT_FLAGS_ARG 2 - extern PHPAPI zend_class_entry *spl_ce_ArrayObject; extern PHPAPI zend_class_entry *spl_ce_ArrayIterator; extern PHPAPI zend_class_entry *spl_ce_RecursiveArrayIterator; diff --git a/ext/spl/spl_array_arginfo.h b/ext/spl/spl_array_arginfo.h index 24dcadac661c..fbe290693640 100644 --- a/ext/spl/spl_array_arginfo.h +++ b/ext/spl/spl_array_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit spl_array.stub.php instead. * Stub hash: c52e89992bd3c04877daab47f4328af0b6ce619e */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ArrayObject___construct, 0, 0, 0) @@ -264,15 +264,15 @@ static zend_class_entry *register_class_ArrayObject(zend_class_entry *class_entr zval const_STD_PROP_LIST_value; ZVAL_LONG(&const_STD_PROP_LIST_value, SPL_ARRAY_STD_PROP_LIST); - zend_string *const_STD_PROP_LIST_name = zend_string_init_interned("STD_PROP_LIST", sizeof("STD_PROP_LIST") - 1, 1); + zend_string *const_STD_PROP_LIST_name = zend_string_init_interned("STD_PROP_LIST", sizeof("STD_PROP_LIST") - 1, true); zend_declare_typed_class_constant(class_entry, const_STD_PROP_LIST_name, &const_STD_PROP_LIST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_STD_PROP_LIST_name); + zend_string_release_ex(const_STD_PROP_LIST_name, true); zval const_ARRAY_AS_PROPS_value; ZVAL_LONG(&const_ARRAY_AS_PROPS_value, SPL_ARRAY_ARRAY_AS_PROPS); - zend_string *const_ARRAY_AS_PROPS_name = zend_string_init_interned("ARRAY_AS_PROPS", sizeof("ARRAY_AS_PROPS") - 1, 1); + zend_string *const_ARRAY_AS_PROPS_name = zend_string_init_interned("ARRAY_AS_PROPS", sizeof("ARRAY_AS_PROPS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ARRAY_AS_PROPS_name, &const_ARRAY_AS_PROPS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ARRAY_AS_PROPS_name); + zend_string_release_ex(const_ARRAY_AS_PROPS_name, true); return class_entry; } @@ -287,15 +287,15 @@ static zend_class_entry *register_class_ArrayIterator(zend_class_entry *class_en zval const_STD_PROP_LIST_value; ZVAL_LONG(&const_STD_PROP_LIST_value, SPL_ARRAY_STD_PROP_LIST); - zend_string *const_STD_PROP_LIST_name = zend_string_init_interned("STD_PROP_LIST", sizeof("STD_PROP_LIST") - 1, 1); + zend_string *const_STD_PROP_LIST_name = zend_string_init_interned("STD_PROP_LIST", sizeof("STD_PROP_LIST") - 1, true); zend_declare_typed_class_constant(class_entry, const_STD_PROP_LIST_name, &const_STD_PROP_LIST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_STD_PROP_LIST_name); + zend_string_release_ex(const_STD_PROP_LIST_name, true); zval const_ARRAY_AS_PROPS_value; ZVAL_LONG(&const_ARRAY_AS_PROPS_value, SPL_ARRAY_ARRAY_AS_PROPS); - zend_string *const_ARRAY_AS_PROPS_name = zend_string_init_interned("ARRAY_AS_PROPS", sizeof("ARRAY_AS_PROPS") - 1, 1); + zend_string *const_ARRAY_AS_PROPS_name = zend_string_init_interned("ARRAY_AS_PROPS", sizeof("ARRAY_AS_PROPS") - 1, true); zend_declare_typed_class_constant(class_entry, const_ARRAY_AS_PROPS_name, &const_ARRAY_AS_PROPS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ARRAY_AS_PROPS_name); + zend_string_release_ex(const_ARRAY_AS_PROPS_name, true); return class_entry; } @@ -310,9 +310,9 @@ static zend_class_entry *register_class_RecursiveArrayIterator(zend_class_entry zval const_CHILD_ARRAYS_ONLY_value; ZVAL_LONG(&const_CHILD_ARRAYS_ONLY_value, SPL_ARRAY_CHILD_ARRAYS_ONLY); - zend_string *const_CHILD_ARRAYS_ONLY_name = zend_string_init_interned("CHILD_ARRAYS_ONLY", sizeof("CHILD_ARRAYS_ONLY") - 1, 1); + zend_string *const_CHILD_ARRAYS_ONLY_name = zend_string_init_interned("CHILD_ARRAYS_ONLY", sizeof("CHILD_ARRAYS_ONLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHILD_ARRAYS_ONLY_name, &const_CHILD_ARRAYS_ONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHILD_ARRAYS_ONLY_name); + zend_string_release_ex(const_CHILD_ARRAYS_ONLY_name, true); return class_entry; } diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 8c59e9624a33..95fc5e25be4b 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Marcus Boerger | +----------------------------------------------------------------------+ @@ -52,7 +50,7 @@ PHPAPI zend_class_entry *spl_ce_SplTempFileObject; /* Object helper */ static inline spl_filesystem_object *spl_filesystem_from_obj(zend_object *obj) /* {{{ */ { - return (spl_filesystem_object*)((char*)(obj) - XtOffsetOf(spl_filesystem_object, std)); + return ZEND_CONTAINER_OF(obj, spl_filesystem_object, std); } /* }}} */ @@ -190,8 +188,8 @@ static zend_object *spl_filesystem_object_new(zend_class_entry *class_type) intern = emalloc(sizeof(spl_filesystem_object) + zend_object_properties_size(class_type)); /* Avoid initializing the entirety of spl_filesystem_object.u.dir.entry. */ memset(intern, 0, - MAX(XtOffsetOf(spl_filesystem_object, u.dir.entry), - XtOffsetOf(spl_filesystem_object, u.file.escape) + sizeof(int))); + MAX(offsetof(spl_filesystem_object, u.dir.entry), + offsetof(spl_filesystem_object, u.file.escape) + sizeof(int))); /* intern->type = SPL_FS_INFO; done by set 0 */ intern->file_class = spl_ce_SplFileObject; intern->info_class = spl_ce_SplFileInfo; @@ -260,19 +258,16 @@ static zend_result spl_filesystem_object_get_file_name(spl_filesystem_object *in return SUCCESS; } /* }}} */ -/* TODO Make void or have callers check return value */ -static bool spl_filesystem_dir_read(spl_filesystem_object *intern) /* {{{ */ +static void spl_filesystem_dir_read(spl_filesystem_object *intern) /* {{{ */ { if (intern->file_name) { /* invalidate */ zend_string_release(intern->file_name); intern->file_name = NULL; } + if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { intern->u.dir.entry.d_name[0] = '\0'; - return 0; - } else { - return 1; } } /* }}} */ @@ -295,6 +290,11 @@ static void spl_filesystem_dir_open(spl_filesystem_object* intern, zend_string * intern->type = SPL_FS_DIR; intern->u.dir.dirp = php_stream_opendir(ZSTR_VAL(path), REPORT_ERRORS, FG(default_context)); + if (intern->u.dir.dirp) { + /* we prevent potential UAF with conflicting explicit fclose(), relying on the object destructor for this */ + intern->u.dir.dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE; + } + if (ZSTR_LEN(path) > 1 && IS_SLASH_AT(ZSTR_VAL(path), ZSTR_LEN(path)-1)) { intern->path = zend_string_init(ZSTR_VAL(path), ZSTR_LEN(path)-1, 0); } else { @@ -412,7 +412,7 @@ static zend_object *spl_filesystem_object_clone(zend_object *old_object) spl_filesystem_dir_open(intern, source->path); /* read until we hit the position in which we were before */ bool skip_dots = SPL_HAS_FLAG(source->flags, SPL_FILE_DIR_SKIPDOTS); - int index; + zend_long index; for (index = 0; index < source->u.dir.index; ++index) { do { spl_filesystem_dir_read(intern); @@ -483,9 +483,8 @@ static spl_filesystem_object *spl_filesystem_object_create_info(zend_string *fil RETVAL_OBJ(&intern->std); if (ce->constructor->common.scope != spl_ce_SplFileInfo) { - ZVAL_STR_COPY(&arg1, file_path); + ZVAL_STR(&arg1, file_path); zend_call_method_with_1_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1); - zval_ptr_dtor(&arg1); } else { spl_filesystem_info_set_filename(intern, file_path); } @@ -496,7 +495,7 @@ static spl_filesystem_object *spl_filesystem_object_create_info(zend_string *fil static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, spl_filesystem_object *source, int type, zend_class_entry *ce, zval *return_value) /* {{{ */ { spl_filesystem_object *intern; - bool use_include_path = 0; + bool use_include_path = false; zval arg1, arg2; zend_error_handling error_handling; @@ -523,9 +522,8 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp } if (ce->constructor->common.scope != spl_ce_SplFileInfo) { - ZVAL_STR_COPY(&arg1, source->file_name); + ZVAL_STR(&arg1, source->file_name); zend_call_method_with_1_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1); - zval_ptr_dtor(&arg1); } else { intern->file_name = zend_string_copy(source->file_name); intern->path = spl_filesystem_object_get_path(source); @@ -552,11 +550,9 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp } if (ce->constructor->common.scope != spl_ce_SplFileObject) { - ZVAL_STR_COPY(&arg1, source->file_name); - ZVAL_STR_COPY(&arg2, open_mode); + ZVAL_STR(&arg1, source->file_name); + ZVAL_STR(&arg2, open_mode); zend_call_method_with_2_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1, &arg2); - zval_ptr_dtor(&arg1); - zval_ptr_dtor(&arg2); } else { intern->file_name = source->file_name; intern->path = spl_filesystem_object_get_path(source); @@ -740,9 +736,7 @@ PHP_METHOD(DirectoryIterator, rewind) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(intern); intern->u.dir.index = 0; @@ -756,9 +750,7 @@ PHP_METHOD(DirectoryIterator, key) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(intern); RETURN_LONG(intern->u.dir.index); @@ -768,9 +760,7 @@ PHP_METHOD(DirectoryIterator, key) /* {{{ Return this (needed for Iterator interface) */ PHP_METHOD(DirectoryIterator, current) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS))); RETURN_OBJ_COPY(Z_OBJ_P(ZEND_THIS)); @@ -783,9 +773,7 @@ PHP_METHOD(DirectoryIterator, next) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); bool skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(intern); intern->u.dir.index++; @@ -834,9 +822,7 @@ PHP_METHOD(DirectoryIterator, valid) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(intern); RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0'); @@ -849,9 +835,7 @@ PHP_METHOD(SplFileInfo, getPath) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); zend_string *path; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); path = spl_filesystem_object_get_path(intern); if (path) { @@ -868,9 +852,7 @@ PHP_METHOD(SplFileInfo, getFilename) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); zend_string *path; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!intern->file_name) { zend_throw_error(NULL, "Object not initialized"); @@ -897,9 +879,7 @@ PHP_METHOD(DirectoryIterator, getFilename) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(intern); RETURN_STRING(intern->u.dir.entry.d_name); @@ -917,9 +897,7 @@ PHP_METHOD(SplFileInfo, getExtension) size_t idx; zend_string *ret; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!intern->file_name) { zend_throw_error(NULL, "Object not initialized"); @@ -962,9 +940,7 @@ PHP_METHOD(DirectoryIterator, getExtension) size_t idx; zend_string *fname; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(intern); fname = php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), NULL, 0); @@ -1042,9 +1018,7 @@ PHP_METHOD(SplFileInfo, getPathname) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); zend_string *path; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); path = spl_filesystem_object_get_pathname(intern); if (path) { RETURN_STR_COPY(path); @@ -1059,9 +1033,7 @@ PHP_METHOD(FilesystemIterator, key) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (SPL_FILE_DIR_KEY(intern, SPL_FILE_DIR_KEY_AS_FILENAME)) { RETURN_STRING(intern->u.dir.entry.d_name); @@ -1079,9 +1051,7 @@ PHP_METHOD(FilesystemIterator, current) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (SPL_FILE_DIR_CURRENT(intern, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) { if (spl_filesystem_object_get_file_name(intern) == FAILURE) { @@ -1104,9 +1074,7 @@ PHP_METHOD(DirectoryIterator, isDot) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_DIRECTORY_ITERATOR_IS_INITIALIZED(intern); RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name)); @@ -1140,9 +1108,7 @@ PHP_METHOD(SplFileInfo, func_name) \ { \ spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); \ zend_error_handling error_handling; \ - if (zend_parse_parameters_none() == FAILURE) { \ - RETURN_THROWS(); \ - } \ + ZEND_PARSE_PARAMETERS_NONE(); \ if (spl_filesystem_object_get_file_name(intern) == FAILURE) { \ RETURN_THROWS(); \ } \ @@ -1219,9 +1185,7 @@ PHP_METHOD(SplFileInfo, getLinkTarget) ssize_t ret; char buff[MAXPATHLEN]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (intern->file_name == NULL) { if (spl_filesystem_object_get_file_name(intern) == FAILURE) { @@ -1266,9 +1230,7 @@ PHP_METHOD(SplFileInfo, getRealPath) char buff[MAXPATHLEN]; char *filename; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (intern->type == SPL_FS_DIR && !intern->file_name && intern->u.dir.entry.d_name[0]) { if (spl_filesystem_object_get_file_name(intern) == FAILURE) { @@ -1378,9 +1340,7 @@ PHP_METHOD(SplFileInfo, getPathInfo) /* {{{ */ PHP_METHOD(SplFileInfo, __debugInfo) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_ARR(spl_filesystem_object_get_debug_info(Z_OBJ_P(ZEND_THIS))); } /* }}} */ @@ -1388,9 +1348,7 @@ PHP_METHOD(SplFileInfo, __debugInfo) /* {{{ */ PHP_METHOD(SplFileInfo, _bad_state_ex) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_throw_error(NULL, "The parent constructor was not called: the object is in an invalid state"); RETURN_THROWS(); } @@ -1409,9 +1367,7 @@ PHP_METHOD(FilesystemIterator, rewind) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); bool skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern->u.dir.index = 0; if (intern->u.dir.dirp) { @@ -1428,9 +1384,7 @@ PHP_METHOD(FilesystemIterator, getFlags) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(intern->flags & (SPL_FILE_DIR_KEY_MODE_MASK | SPL_FILE_DIR_CURRENT_MODE_MASK | SPL_FILE_DIR_OTHERS_MASK)); } /* }}} */ @@ -1494,9 +1448,7 @@ PHP_METHOD(RecursiveDirectoryIterator, getChildren) spl_filesystem_object *subdir; char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (spl_filesystem_object_get_file_name(intern) == FAILURE) { RETURN_THROWS(); @@ -1516,11 +1468,11 @@ PHP_METHOD(RecursiveDirectoryIterator, getChildren) if (subdir) { size_t name_len = strlen(intern->u.dir.entry.d_name); if (intern->u.dir.sub_path && ZSTR_LEN(intern->u.dir.sub_path)) { - zend_string *sub_path = zend_string_alloc(ZSTR_LEN(intern->u.dir.sub_path) + 1 + name_len, 0); - memcpy(ZSTR_VAL(sub_path), ZSTR_VAL(intern->u.dir.sub_path), ZSTR_LEN(intern->u.dir.sub_path)); - ZSTR_VAL(sub_path)[ZSTR_LEN(intern->u.dir.sub_path)] = slash; - memcpy(ZSTR_VAL(sub_path) + ZSTR_LEN(intern->u.dir.sub_path) + 1, intern->u.dir.entry.d_name, name_len); - ZSTR_VAL(sub_path)[ZSTR_LEN(intern->u.dir.sub_path) + 1 + name_len] = 0; + zend_string *sub_path = zend_string_concat3( + ZSTR_VAL(intern->u.dir.sub_path), ZSTR_LEN(intern->u.dir.sub_path), + &slash, 1, + intern->u.dir.entry.d_name, name_len + ); subdir->u.dir.sub_path = sub_path; } else { subdir->u.dir.sub_path = zend_string_init(intern->u.dir.entry.d_name, name_len, 0); @@ -1537,9 +1489,7 @@ PHP_METHOD(RecursiveDirectoryIterator, getSubPath) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (intern->u.dir.sub_path) { RETURN_STR_COPY(intern->u.dir.sub_path); @@ -1555,9 +1505,7 @@ PHP_METHOD(RecursiveDirectoryIterator, getSubPathname) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (intern->u.dir.sub_path) { RETURN_NEW_STR(strpprintf(0, "%s%c%s", ZSTR_VAL(intern->u.dir.sub_path), slash, intern->u.dir.entry.d_name)); @@ -1586,9 +1534,7 @@ PHP_METHOD(GlobIterator, count) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (EXPECTED(spl_intern_is_glob(intern))) { RETURN_LONG(php_glob_stream_get_count(intern->u.dir.dirp, NULL)); @@ -1865,21 +1811,24 @@ static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bo } if (!buf) { - intern->u.file.current_line = ZSTR_EMPTY_ALLOC(); - } else { - if (!csv && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) { - if (line_len > 0 && buf[line_len - 1] == '\n') { + if (!silent) { + spl_filesystem_file_cannot_read(intern); + } + return FAILURE; + } + + if (!csv && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) { + if (line_len > 0 && buf[line_len - 1] == '\n') { + line_len--; + if (line_len > 0 && buf[line_len - 1] == '\r') { line_len--; - if (line_len > 0 && buf[line_len - 1] == '\r') { - line_len--; - } - buf[line_len] = '\0'; } + buf[line_len] = '\0'; } - - intern->u.file.current_line = zend_string_init(buf, line_len, /* persistent */ false); - efree(buf); } + + intern->u.file.current_line = zend_string_init(buf, line_len, /* persistent */ false); + efree(buf); intern->u.file.current_line_num += line_add; return SUCCESS; @@ -2017,7 +1966,7 @@ PHP_METHOD(SplFileObject, __construct) zend_string *file_name = NULL; zend_string *open_mode = ZSTR_CHAR('r'); zval *stream_context = NULL; - bool use_include_path = 0; + bool use_include_path = false; size_t path_len; zend_error_handling error_handling; @@ -2103,9 +2052,7 @@ PHP_METHOD(SplFileObject, rewind) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_filesystem_file_rewind(ZEND_THIS, intern); } /* }}} */ @@ -2115,9 +2062,7 @@ PHP_METHOD(SplFileObject, eof) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); @@ -2129,9 +2074,7 @@ PHP_METHOD(SplFileObject, valid) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { RETURN_BOOL(intern->u.file.current_line || !Z_ISUNDEF(intern->u.file.current_zval)); @@ -2147,16 +2090,25 @@ PHP_METHOD(SplFileObject, fgets) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); - if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1, /* csv */ false) == FAILURE) { - RETURN_THROWS(); + if (intern->u.file.current_line) { + RETVAL_STR_COPY(intern->u.file.current_line); + spl_filesystem_file_free_line(intern); + intern->u.file.current_line_num++; + } else { + if (spl_filesystem_file_read_ex(intern, /* silent */ true, /* line_add */ 1, /* csv */ false) == FAILURE) { + if (php_stream_eof(intern->u.file.stream)) { + RETURN_EMPTY_STRING(); + } + spl_filesystem_file_cannot_read(intern); + RETURN_THROWS(); + } + RETVAL_STR_COPY(intern->u.file.current_line); + spl_filesystem_file_free_line(intern); } - RETURN_STR_COPY(intern->u.file.current_line); } /* }}} */ /* {{{ Return current line from file */ @@ -2164,9 +2116,7 @@ PHP_METHOD(SplFileObject, current) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); @@ -2188,9 +2138,7 @@ PHP_METHOD(SplFileObject, key) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); /* Do not read the next line to support correct counting with fgetc() if (!intern->u.file.current_line) { @@ -2204,8 +2152,12 @@ PHP_METHOD(SplFileObject, next) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); + ZEND_PARSE_PARAMETERS_NONE(); + + if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) { + if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { + return; + } } spl_filesystem_file_free_line(intern); @@ -2230,9 +2182,7 @@ PHP_METHOD(SplFileObject, getFlags) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(intern->flags & SPL_FILE_OBJECT_MASK); } /* }}} */ @@ -2261,9 +2211,7 @@ PHP_METHOD(SplFileObject, getMaxLineLen) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG((zend_long)intern->u.file.max_line_len); } /* }}} */ @@ -2271,9 +2219,7 @@ PHP_METHOD(SplFileObject, getMaxLineLen) /* {{{ Return false */ PHP_METHOD(SplFileObject, hasChildren) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_FALSE; } /* }}} */ @@ -2281,9 +2227,7 @@ PHP_METHOD(SplFileObject, hasChildren) /* {{{ Read NULL */ PHP_METHOD(SplFileObject, getChildren) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); /* return NULL */ } /* }}} */ @@ -2434,9 +2378,7 @@ PHP_METHOD(SplFileObject, getCsvControl) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); char delimiter[2], enclosure[2], escape[2]; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -2479,9 +2421,7 @@ PHP_METHOD(SplFileObject, fflush) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); @@ -2494,9 +2434,7 @@ PHP_METHOD(SplFileObject, ftell) spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); zend_long ret; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); @@ -2530,9 +2468,7 @@ PHP_METHOD(SplFileObject, fgetc) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); @@ -2555,9 +2491,7 @@ PHP_METHOD(SplFileObject, fpassthru) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); @@ -2586,7 +2520,8 @@ PHP_METHOD(SplFileObject, fscanf) int result = php_sscanf_internal(ZSTR_VAL(intern->u.file.current_line), ZSTR_VAL(format_str), (int)num_varargs, varargs, 0, return_value); if (SCAN_ERROR_WRONG_PARAM_COUNT == result) { - WRONG_PARAM_COUNT; + zend_wrong_param_count(); + RETURN_THROWS(); } } /* }}} */ @@ -2657,9 +2592,7 @@ PHP_METHOD(SplFileObject, fstat) { spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); @@ -2714,7 +2647,7 @@ PHP_METHOD(SplFileObject, seek) for (i = 0; i < line_pos; i++) { if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { - return; + break; } } if (line_pos > 0 && !SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { @@ -2725,9 +2658,7 @@ PHP_METHOD(SplFileObject, seek) PHP_METHOD(SplFileObject, __toString) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS)); @@ -2735,9 +2666,8 @@ PHP_METHOD(SplFileObject, __toString) if (!intern->u.file.current_line) { ZEND_ASSERT(Z_ISUNDEF(intern->u.file.current_zval)); - zend_result result = spl_filesystem_file_read_line(ZEND_THIS, intern, false); - if (UNEXPECTED(result != SUCCESS)) { - RETURN_THROWS(); + if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { + RETURN_EMPTY_STRING(); } } @@ -2752,7 +2682,7 @@ PHP_MINIT_FUNCTION(spl_directory) spl_ce_SplFileInfo->default_object_handlers = &spl_filesystem_object_handlers; memcpy(&spl_filesystem_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - spl_filesystem_object_handlers.offset = XtOffsetOf(spl_filesystem_object, std); + spl_filesystem_object_handlers.offset = offsetof(spl_filesystem_object, std); spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone; spl_filesystem_object_handlers.dtor_obj = spl_filesystem_object_destroy_object; spl_filesystem_object_handlers.free_obj = spl_filesystem_object_free_storage; diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 549dfb1dc4d0..6d940e8aa8ef 100644 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -62,7 +60,7 @@ struct _spl_filesystem_object { struct { php_stream *dirp; zend_string *sub_path; - int index; + zend_long index; zend_function *func_rewind; zend_function *func_next; zend_function *func_valid; diff --git a/ext/spl/spl_directory_arginfo.h b/ext/spl/spl_directory_arginfo.h index 55606b1a1539..16860be558d7 100644 --- a/ext/spl/spl_directory_arginfo.h +++ b/ext/spl/spl_directory_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit spl_directory.stub.php instead. * Stub hash: 802429d736404c2d66601f640942c827b6e6e94b */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo___construct, 0, 0, 1) @@ -482,10 +482,7 @@ static zend_class_entry *register_class_SplFileInfo(zend_class_entry *class_entr zend_attribute *attribute_Deprecated_func__bad_state_ex_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "_bad_state_ex", sizeof("_bad_state_ex") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func__bad_state_ex_0_arg0; - zend_string *attribute_Deprecated_func__bad_state_ex_0_arg0_str = zend_string_init("8.2", strlen("8.2"), 1); - ZVAL_STR(&attribute_Deprecated_func__bad_state_ex_0_arg0, attribute_Deprecated_func__bad_state_ex_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func__bad_state_ex_0->args[0].value, &attribute_Deprecated_func__bad_state_ex_0_arg0); + ZVAL_STR(&attribute_Deprecated_func__bad_state_ex_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func__bad_state_ex_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); return class_entry; @@ -511,75 +508,75 @@ static zend_class_entry *register_class_FilesystemIterator(zend_class_entry *cla zval const_CURRENT_MODE_MASK_value; ZVAL_LONG(&const_CURRENT_MODE_MASK_value, SPL_FILE_DIR_CURRENT_MODE_MASK); - zend_string *const_CURRENT_MODE_MASK_name = zend_string_init_interned("CURRENT_MODE_MASK", sizeof("CURRENT_MODE_MASK") - 1, 1); + zend_string *const_CURRENT_MODE_MASK_name = zend_string_init_interned("CURRENT_MODE_MASK", sizeof("CURRENT_MODE_MASK") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENT_MODE_MASK_name, &const_CURRENT_MODE_MASK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENT_MODE_MASK_name); + zend_string_release_ex(const_CURRENT_MODE_MASK_name, true); zval const_CURRENT_AS_PATHNAME_value; ZVAL_LONG(&const_CURRENT_AS_PATHNAME_value, SPL_FILE_DIR_CURRENT_AS_PATHNAME); - zend_string *const_CURRENT_AS_PATHNAME_name = zend_string_init_interned("CURRENT_AS_PATHNAME", sizeof("CURRENT_AS_PATHNAME") - 1, 1); + zend_string *const_CURRENT_AS_PATHNAME_name = zend_string_init_interned("CURRENT_AS_PATHNAME", sizeof("CURRENT_AS_PATHNAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENT_AS_PATHNAME_name, &const_CURRENT_AS_PATHNAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENT_AS_PATHNAME_name); + zend_string_release_ex(const_CURRENT_AS_PATHNAME_name, true); zval const_CURRENT_AS_FILEINFO_value; ZVAL_LONG(&const_CURRENT_AS_FILEINFO_value, SPL_FILE_DIR_CURRENT_AS_FILEINFO); - zend_string *const_CURRENT_AS_FILEINFO_name = zend_string_init_interned("CURRENT_AS_FILEINFO", sizeof("CURRENT_AS_FILEINFO") - 1, 1); + zend_string *const_CURRENT_AS_FILEINFO_name = zend_string_init_interned("CURRENT_AS_FILEINFO", sizeof("CURRENT_AS_FILEINFO") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENT_AS_FILEINFO_name, &const_CURRENT_AS_FILEINFO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENT_AS_FILEINFO_name); + zend_string_release_ex(const_CURRENT_AS_FILEINFO_name, true); zval const_CURRENT_AS_SELF_value; ZVAL_LONG(&const_CURRENT_AS_SELF_value, SPL_FILE_DIR_CURRENT_AS_SELF); - zend_string *const_CURRENT_AS_SELF_name = zend_string_init_interned("CURRENT_AS_SELF", sizeof("CURRENT_AS_SELF") - 1, 1); + zend_string *const_CURRENT_AS_SELF_name = zend_string_init_interned("CURRENT_AS_SELF", sizeof("CURRENT_AS_SELF") - 1, true); zend_declare_typed_class_constant(class_entry, const_CURRENT_AS_SELF_name, &const_CURRENT_AS_SELF_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CURRENT_AS_SELF_name); + zend_string_release_ex(const_CURRENT_AS_SELF_name, true); zval const_KEY_MODE_MASK_value; ZVAL_LONG(&const_KEY_MODE_MASK_value, SPL_FILE_DIR_KEY_MODE_MASK); - zend_string *const_KEY_MODE_MASK_name = zend_string_init_interned("KEY_MODE_MASK", sizeof("KEY_MODE_MASK") - 1, 1); + zend_string *const_KEY_MODE_MASK_name = zend_string_init_interned("KEY_MODE_MASK", sizeof("KEY_MODE_MASK") - 1, true); zend_declare_typed_class_constant(class_entry, const_KEY_MODE_MASK_name, &const_KEY_MODE_MASK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_KEY_MODE_MASK_name); + zend_string_release_ex(const_KEY_MODE_MASK_name, true); zval const_KEY_AS_PATHNAME_value; ZVAL_LONG(&const_KEY_AS_PATHNAME_value, SPL_FILE_DIR_KEY_AS_PATHNAME); - zend_string *const_KEY_AS_PATHNAME_name = zend_string_init_interned("KEY_AS_PATHNAME", sizeof("KEY_AS_PATHNAME") - 1, 1); + zend_string *const_KEY_AS_PATHNAME_name = zend_string_init_interned("KEY_AS_PATHNAME", sizeof("KEY_AS_PATHNAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_KEY_AS_PATHNAME_name, &const_KEY_AS_PATHNAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_KEY_AS_PATHNAME_name); + zend_string_release_ex(const_KEY_AS_PATHNAME_name, true); zval const_FOLLOW_SYMLINKS_value; ZVAL_LONG(&const_FOLLOW_SYMLINKS_value, SPL_FILE_DIR_FOLLOW_SYMLINKS); - zend_string *const_FOLLOW_SYMLINKS_name = zend_string_init_interned("FOLLOW_SYMLINKS", sizeof("FOLLOW_SYMLINKS") - 1, 1); + zend_string *const_FOLLOW_SYMLINKS_name = zend_string_init_interned("FOLLOW_SYMLINKS", sizeof("FOLLOW_SYMLINKS") - 1, true); zend_declare_typed_class_constant(class_entry, const_FOLLOW_SYMLINKS_name, &const_FOLLOW_SYMLINKS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FOLLOW_SYMLINKS_name); + zend_string_release_ex(const_FOLLOW_SYMLINKS_name, true); zval const_KEY_AS_FILENAME_value; ZVAL_LONG(&const_KEY_AS_FILENAME_value, SPL_FILE_DIR_KEY_AS_FILENAME); - zend_string *const_KEY_AS_FILENAME_name = zend_string_init_interned("KEY_AS_FILENAME", sizeof("KEY_AS_FILENAME") - 1, 1); + zend_string *const_KEY_AS_FILENAME_name = zend_string_init_interned("KEY_AS_FILENAME", sizeof("KEY_AS_FILENAME") - 1, true); zend_declare_typed_class_constant(class_entry, const_KEY_AS_FILENAME_name, &const_KEY_AS_FILENAME_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_KEY_AS_FILENAME_name); + zend_string_release_ex(const_KEY_AS_FILENAME_name, true); zval const_NEW_CURRENT_AND_KEY_value; ZVAL_LONG(&const_NEW_CURRENT_AND_KEY_value, SPL_FILE_NEW_CURRENT_AND_KEY); - zend_string *const_NEW_CURRENT_AND_KEY_name = zend_string_init_interned("NEW_CURRENT_AND_KEY", sizeof("NEW_CURRENT_AND_KEY") - 1, 1); + zend_string *const_NEW_CURRENT_AND_KEY_name = zend_string_init_interned("NEW_CURRENT_AND_KEY", sizeof("NEW_CURRENT_AND_KEY") - 1, true); zend_declare_typed_class_constant(class_entry, const_NEW_CURRENT_AND_KEY_name, &const_NEW_CURRENT_AND_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_NEW_CURRENT_AND_KEY_name); + zend_string_release_ex(const_NEW_CURRENT_AND_KEY_name, true); zval const_OTHER_MODE_MASK_value; ZVAL_LONG(&const_OTHER_MODE_MASK_value, SPL_FILE_DIR_OTHERS_MASK); - zend_string *const_OTHER_MODE_MASK_name = zend_string_init_interned("OTHER_MODE_MASK", sizeof("OTHER_MODE_MASK") - 1, 1); + zend_string *const_OTHER_MODE_MASK_name = zend_string_init_interned("OTHER_MODE_MASK", sizeof("OTHER_MODE_MASK") - 1, true); zend_declare_typed_class_constant(class_entry, const_OTHER_MODE_MASK_name, &const_OTHER_MODE_MASK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OTHER_MODE_MASK_name); + zend_string_release_ex(const_OTHER_MODE_MASK_name, true); zval const_SKIP_DOTS_value; ZVAL_LONG(&const_SKIP_DOTS_value, SPL_FILE_DIR_SKIPDOTS); - zend_string *const_SKIP_DOTS_name = zend_string_init_interned("SKIP_DOTS", sizeof("SKIP_DOTS") - 1, 1); + zend_string *const_SKIP_DOTS_name = zend_string_init_interned("SKIP_DOTS", sizeof("SKIP_DOTS") - 1, true); zend_declare_typed_class_constant(class_entry, const_SKIP_DOTS_name, &const_SKIP_DOTS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SKIP_DOTS_name); + zend_string_release_ex(const_SKIP_DOTS_name, true); zval const_UNIX_PATHS_value; ZVAL_LONG(&const_UNIX_PATHS_value, SPL_FILE_DIR_UNIXPATHS); - zend_string *const_UNIX_PATHS_name = zend_string_init_interned("UNIX_PATHS", sizeof("UNIX_PATHS") - 1, 1); + zend_string *const_UNIX_PATHS_name = zend_string_init_interned("UNIX_PATHS", sizeof("UNIX_PATHS") - 1, true); zend_declare_typed_class_constant(class_entry, const_UNIX_PATHS_name, &const_UNIX_PATHS_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UNIX_PATHS_name); + zend_string_release_ex(const_UNIX_PATHS_name, true); return class_entry; } @@ -616,27 +613,27 @@ static zend_class_entry *register_class_SplFileObject(zend_class_entry *class_en zval const_DROP_NEW_LINE_value; ZVAL_LONG(&const_DROP_NEW_LINE_value, SPL_FILE_OBJECT_DROP_NEW_LINE); - zend_string *const_DROP_NEW_LINE_name = zend_string_init_interned("DROP_NEW_LINE", sizeof("DROP_NEW_LINE") - 1, 1); + zend_string *const_DROP_NEW_LINE_name = zend_string_init_interned("DROP_NEW_LINE", sizeof("DROP_NEW_LINE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_NEW_LINE_name, &const_DROP_NEW_LINE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_NEW_LINE_name); + zend_string_release_ex(const_DROP_NEW_LINE_name, true); zval const_READ_AHEAD_value; ZVAL_LONG(&const_READ_AHEAD_value, SPL_FILE_OBJECT_READ_AHEAD); - zend_string *const_READ_AHEAD_name = zend_string_init_interned("READ_AHEAD", sizeof("READ_AHEAD") - 1, 1); + zend_string *const_READ_AHEAD_name = zend_string_init_interned("READ_AHEAD", sizeof("READ_AHEAD") - 1, true); zend_declare_typed_class_constant(class_entry, const_READ_AHEAD_name, &const_READ_AHEAD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_READ_AHEAD_name); + zend_string_release_ex(const_READ_AHEAD_name, true); zval const_SKIP_EMPTY_value; ZVAL_LONG(&const_SKIP_EMPTY_value, SPL_FILE_OBJECT_SKIP_EMPTY); - zend_string *const_SKIP_EMPTY_name = zend_string_init_interned("SKIP_EMPTY", sizeof("SKIP_EMPTY") - 1, 1); + zend_string *const_SKIP_EMPTY_name = zend_string_init_interned("SKIP_EMPTY", sizeof("SKIP_EMPTY") - 1, true); zend_declare_typed_class_constant(class_entry, const_SKIP_EMPTY_name, &const_SKIP_EMPTY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SKIP_EMPTY_name); + zend_string_release_ex(const_SKIP_EMPTY_name, true); zval const_READ_CSV_value; ZVAL_LONG(&const_READ_CSV_value, SPL_FILE_OBJECT_READ_CSV); - zend_string *const_READ_CSV_name = zend_string_init_interned("READ_CSV", sizeof("READ_CSV") - 1, 1); + zend_string *const_READ_CSV_name = zend_string_init_interned("READ_CSV", sizeof("READ_CSV") - 1, true); zend_declare_typed_class_constant(class_entry, const_READ_CSV_name, &const_READ_CSV_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_READ_CSV_name); + zend_string_release_ex(const_READ_CSV_name, true); return class_entry; } diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 0f525e627d30..39d2592b79a9 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ @@ -75,12 +73,7 @@ struct _spl_dllist_object { spl_ptr_llist_element *traverse_pointer; int traverse_position; int flags; - zend_function *fptr_offset_get; - zend_function *fptr_offset_set; - zend_function *fptr_offset_has; - zend_function *fptr_offset_del; zend_function *fptr_count; - zend_class_entry *ce_get_iterator; zend_object std; }; @@ -93,7 +86,7 @@ struct _spl_dllist_it { }; static inline spl_dllist_object *spl_dllist_from_obj(zend_object *obj) /* {{{ */ { - return (spl_dllist_object*)((char*)(obj) - XtOffsetOf(spl_dllist_object, std)); + return ZEND_CONTAINER_OF(obj, spl_dllist_object, std); } /* }}} */ @@ -309,7 +302,7 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zend_object *orig, int clone_orig) /* {{{ */ { spl_dllist_object *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; int inherited = 0; intern = zend_object_alloc(sizeof(spl_dllist_object), parent); @@ -321,8 +314,7 @@ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zend_ intern->traverse_position = 0; if (orig) { - spl_dllist_object *other = spl_dllist_from_obj(orig); - intern->ce_get_iterator = other->ce_get_iterator; + const spl_dllist_object *other = spl_dllist_from_obj(orig); if (clone_orig) { intern->llist = spl_ptr_llist_init(); @@ -360,22 +352,6 @@ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zend_ ZEND_ASSERT(parent); if (inherited) { - intern->fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1); - if (intern->fptr_offset_get->common.scope == parent) { - intern->fptr_offset_get = NULL; - } - intern->fptr_offset_set = zend_hash_str_find_ptr(&class_type->function_table, "offsetset", sizeof("offsetset") - 1); - if (intern->fptr_offset_set->common.scope == parent) { - intern->fptr_offset_set = NULL; - } - intern->fptr_offset_has = zend_hash_str_find_ptr(&class_type->function_table, "offsetexists", sizeof("offsetexists") - 1); - if (intern->fptr_offset_has->common.scope == parent) { - intern->fptr_offset_has = NULL; - } - intern->fptr_offset_del = zend_hash_str_find_ptr(&class_type->function_table, "offsetunset", sizeof("offsetunset") - 1); - if (intern->fptr_offset_del->common.scope == parent) { - intern->fptr_offset_del = NULL; - } /* Find count() method */ intern->fptr_count = zend_hash_find_ptr(&class_type->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); if (intern->fptr_count->common.scope == parent) { @@ -511,9 +487,7 @@ PHP_METHOD(SplDoublyLinkedList, pop) { spl_dllist_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLDLLIST_P(ZEND_THIS); spl_ptr_llist_pop(intern->llist, return_value); @@ -530,9 +504,7 @@ PHP_METHOD(SplDoublyLinkedList, shift) { spl_dllist_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLDLLIST_P(ZEND_THIS); spl_ptr_llist_shift(intern->llist, return_value); @@ -550,9 +522,7 @@ PHP_METHOD(SplDoublyLinkedList, top) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLDLLIST_P(ZEND_THIS); value = spl_ptr_llist_last(intern->llist); @@ -572,9 +542,7 @@ PHP_METHOD(SplDoublyLinkedList, bottom) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLDLLIST_P(ZEND_THIS); value = spl_ptr_llist_first(intern->llist); @@ -594,9 +562,7 @@ PHP_METHOD(SplDoublyLinkedList, count) zend_long count; spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); count = spl_ptr_llist_count(intern->llist); RETURN_LONG(count); @@ -608,9 +574,7 @@ PHP_METHOD(SplDoublyLinkedList, isEmpty) { zend_long count; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_dllist_object_count_elements(Z_OBJ_P(ZEND_THIS), &count); RETURN_BOOL(count == 0); @@ -646,9 +610,7 @@ PHP_METHOD(SplDoublyLinkedList, getIteratorMode) { spl_dllist_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLDLLIST_P(ZEND_THIS); @@ -702,7 +664,7 @@ PHP_METHOD(SplDoublyLinkedList, offsetGet) PHP_METHOD(SplDoublyLinkedList, offsetSet) { zend_long index; - bool index_is_null = 1; + bool index_is_null = true; zval *value; spl_dllist_object *intern; @@ -764,11 +726,10 @@ PHP_METHOD(SplDoublyLinkedList, offsetUnset) element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO); if (element != NULL) { - /* connect the neighbors */ + /* disconnect the neighbours */ if (element->prev) { element->prev->next = element->next; } - if (element->next) { element->next->prev = element->prev; } @@ -782,6 +743,10 @@ PHP_METHOD(SplDoublyLinkedList, offsetUnset) llist->tail = element->prev; } + /* Keep consistency if element is kept alive. */ + element->prev = NULL; + element->next = NULL; + /* finally, delete the element */ llist->count--; @@ -833,6 +798,7 @@ static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_p if (flags & SPL_DLLIST_IT_LIFO) { *traverse_pointer_ptr = old->prev; + SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); (*traverse_position_ptr)--; if (flags & SPL_DLLIST_IT_DELETE) { @@ -843,6 +809,7 @@ static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_p } } else { *traverse_pointer_ptr = old->next; + SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); if (flags & SPL_DLLIST_IT_DELETE) { zval prev; @@ -855,7 +822,6 @@ static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_p } SPL_LLIST_DELREF(old); - SPL_LLIST_CHECK_ADDREF(*traverse_pointer_ptr); } } /* }}} */ @@ -914,9 +880,7 @@ PHP_METHOD(SplDoublyLinkedList, key) { spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(intern->traverse_position); } @@ -927,9 +891,7 @@ PHP_METHOD(SplDoublyLinkedList, prev) { spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_dllist_it_helper_move_forward(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags ^ SPL_DLLIST_IT_LIFO); } @@ -940,9 +902,7 @@ PHP_METHOD(SplDoublyLinkedList, next) { spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_dllist_it_helper_move_forward(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags); } @@ -953,9 +913,7 @@ PHP_METHOD(SplDoublyLinkedList, valid) { spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(intern->traverse_pointer != NULL); } @@ -966,9 +924,7 @@ PHP_METHOD(SplDoublyLinkedList, rewind) { spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_dllist_it_helper_rewind(&intern->traverse_pointer, &intern->traverse_position, intern->llist, intern->flags); } @@ -980,9 +936,7 @@ PHP_METHOD(SplDoublyLinkedList, current) spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); spl_ptr_llist_element *element = intern->traverse_pointer; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (element == NULL || Z_ISUNDEF(element->data)) { RETURN_NULL(); @@ -1001,9 +955,7 @@ PHP_METHOD(SplDoublyLinkedList, serialize) zval flags; php_serialize_data_t var_hash; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHP_VAR_SERIALIZE_INIT(var_hash); @@ -1099,9 +1051,7 @@ PHP_METHOD(SplDoublyLinkedList, __serialize) spl_ptr_llist_element *current = intern->llist->head; zval tmp; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -1205,9 +1155,7 @@ PHP_METHOD(SplDoublyLinkedList, add) /* {{{ */ PHP_METHOD(SplDoublyLinkedList, __debugInfo) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_ARR(spl_dllist_object_get_debug_info(Z_OBJ_P(ZEND_THIS))); } /* }}} */ @@ -1260,7 +1208,7 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */ memcpy(&spl_handler_SplDoublyLinkedList, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplDoublyLinkedList.offset = XtOffsetOf(spl_dllist_object, std); + spl_handler_SplDoublyLinkedList.offset = offsetof(spl_dllist_object, std); spl_handler_SplDoublyLinkedList.clone_obj = spl_dllist_object_clone; spl_handler_SplDoublyLinkedList.count_elements = spl_dllist_object_count_elements; spl_handler_SplDoublyLinkedList.get_gc = spl_dllist_object_get_gc; diff --git a/ext/spl/spl_dllist.h b/ext/spl/spl_dllist.h index 1ade7c44a3f0..fb2204b2aca9 100644 --- a/ext/spl/spl_dllist.h +++ b/ext/spl/spl_dllist.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_dllist_arginfo.h b/ext/spl/spl_dllist_arginfo.h index a5b151065513..0f0872b0f047 100644 --- a/ext/spl/spl_dllist_arginfo.h +++ b/ext/spl/spl_dllist_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit spl_dllist.stub.php instead. * Stub hash: 45e42d3a0589031651daee5653900d5a4fb61c3d */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplDoublyLinkedList_add, 0, 2, IS_VOID, 0) @@ -156,27 +156,27 @@ static zend_class_entry *register_class_SplDoublyLinkedList(zend_class_entry *cl zval const_IT_MODE_LIFO_value; ZVAL_LONG(&const_IT_MODE_LIFO_value, SPL_DLLIST_IT_LIFO); - zend_string *const_IT_MODE_LIFO_name = zend_string_init_interned("IT_MODE_LIFO", sizeof("IT_MODE_LIFO") - 1, 1); + zend_string *const_IT_MODE_LIFO_name = zend_string_init_interned("IT_MODE_LIFO", sizeof("IT_MODE_LIFO") - 1, true); zend_declare_typed_class_constant(class_entry, const_IT_MODE_LIFO_name, &const_IT_MODE_LIFO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IT_MODE_LIFO_name); + zend_string_release_ex(const_IT_MODE_LIFO_name, true); zval const_IT_MODE_FIFO_value; ZVAL_LONG(&const_IT_MODE_FIFO_value, SPL_DLLIST_IT_FIFO); - zend_string *const_IT_MODE_FIFO_name = zend_string_init_interned("IT_MODE_FIFO", sizeof("IT_MODE_FIFO") - 1, 1); + zend_string *const_IT_MODE_FIFO_name = zend_string_init_interned("IT_MODE_FIFO", sizeof("IT_MODE_FIFO") - 1, true); zend_declare_typed_class_constant(class_entry, const_IT_MODE_FIFO_name, &const_IT_MODE_FIFO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IT_MODE_FIFO_name); + zend_string_release_ex(const_IT_MODE_FIFO_name, true); zval const_IT_MODE_DELETE_value; ZVAL_LONG(&const_IT_MODE_DELETE_value, SPL_DLLIST_IT_DELETE); - zend_string *const_IT_MODE_DELETE_name = zend_string_init_interned("IT_MODE_DELETE", sizeof("IT_MODE_DELETE") - 1, 1); + zend_string *const_IT_MODE_DELETE_name = zend_string_init_interned("IT_MODE_DELETE", sizeof("IT_MODE_DELETE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IT_MODE_DELETE_name, &const_IT_MODE_DELETE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IT_MODE_DELETE_name); + zend_string_release_ex(const_IT_MODE_DELETE_name, true); zval const_IT_MODE_KEEP_value; ZVAL_LONG(&const_IT_MODE_KEEP_value, SPL_DLLIST_IT_KEEP); - zend_string *const_IT_MODE_KEEP_name = zend_string_init_interned("IT_MODE_KEEP", sizeof("IT_MODE_KEEP") - 1, 1); + zend_string *const_IT_MODE_KEEP_name = zend_string_init_interned("IT_MODE_KEEP", sizeof("IT_MODE_KEEP") - 1, true); zend_declare_typed_class_constant(class_entry, const_IT_MODE_KEEP_name, &const_IT_MODE_KEEP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IT_MODE_KEEP_name); + zend_string_release_ex(const_IT_MODE_KEEP_name, true); return class_entry; } diff --git a/ext/spl/spl_exceptions.c b/ext/spl/spl_exceptions.c index 79449f35d840..8ceba1f7a6a5 100644 --- a/ext/spl/spl_exceptions.c +++ b/ext/spl/spl_exceptions.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_exceptions.h b/ext/spl/spl_exceptions.h index 8c390f7646ec..be1de4f51d1b 100644 --- a/ext/spl/spl_exceptions.h +++ b/ext/spl/spl_exceptions.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_exceptions_arginfo.h b/ext/spl/spl_exceptions_arginfo.h index 568a91719aee..759602783066 100644 --- a/ext/spl/spl_exceptions_arginfo.h +++ b/ext/spl/spl_exceptions_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit spl_exceptions.stub.php instead. * Stub hash: 07475caecc81ab3b38a04905f874615af1126289 */ static zend_class_entry *register_class_LogicException(zend_class_entry *class_entry_Exception) diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index dc32045ba0ff..cfaf209a56e1 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Antony Dovgal | | Etienne Kneuss | @@ -57,7 +55,7 @@ typedef struct _spl_fixedarray_it { static spl_fixedarray_object *spl_fixed_array_from_obj(zend_object *obj) { - return (spl_fixedarray_object*)((char*)(obj) - XtOffsetOf(spl_fixedarray_object, std)); + return ZEND_CONTAINER_OF(obj, spl_fixedarray_object, std); } #define Z_SPLFIXEDARRAY_P(zv) spl_fixed_array_from_obj(Z_OBJ_P((zv))) @@ -172,18 +170,18 @@ static void spl_fixedarray_resize(spl_fixedarray *array, zend_long size) return; } - /* first initialization */ - if (array->size == 0) { - spl_fixedarray_init(array, size); - return; - } - if (UNEXPECTED(array->cached_resize >= 0)) { /* We're already resizing, so just remember the desired size. * The resize will happen later. */ array->cached_resize = size; return; } + /* first initialization */ + if (array->size == 0) { + spl_fixedarray_init(array, size); + return; + } + array->cached_resize = size; /* clearing the array */ @@ -303,12 +301,12 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z static zend_object *spl_fixedarray_new(zend_class_entry *class_type) { - return spl_fixedarray_object_new_ex(class_type, NULL, 0); + return spl_fixedarray_object_new_ex(class_type, NULL, false); } static zend_object *spl_fixedarray_object_clone(zend_object *old_object) { - zend_object *new_object = spl_fixedarray_object_new_ex(old_object->ce, old_object, 1); + zend_object *new_object = spl_fixedarray_object_new_ex(old_object->ce, old_object, true); zend_objects_clone_members(new_object, old_object); @@ -562,9 +560,7 @@ PHP_METHOD(SplFixedArray, __wakeup) HashTable *intern_ht = zend_std_get_properties(Z_OBJ_P(ZEND_THIS)); zval *data; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (intern->array.size == 0) { int index = 0; @@ -589,9 +585,7 @@ PHP_METHOD(SplFixedArray, __serialize) zval *current; zend_string *key; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); HashTable *ht = zend_std_get_properties(&intern->std); uint32_t num_properties = zend_hash_num_elements(ht); @@ -639,7 +633,7 @@ PHP_METHOD(SplFixedArray, __unserialize) intern->array.size = 0; ZEND_HASH_FOREACH_STR_KEY_VAL(data, key, elem) { if (key == NULL) { - ZVAL_COPY(&intern->array.elements[intern->array.size], elem); + ZVAL_COPY_DEREF(&intern->array.elements[intern->array.size], elem); intern->array.size++; } else { Z_TRY_ADDREF_P(elem); @@ -666,9 +660,7 @@ PHP_METHOD(SplFixedArray, count) zval *object = ZEND_THIS; spl_fixedarray_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLFIXEDARRAY_P(object); RETURN_LONG(intern->array.size); @@ -678,9 +670,7 @@ PHP_METHOD(SplFixedArray, toArray) { spl_fixedarray_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLFIXEDARRAY_P(ZEND_THIS); @@ -706,7 +696,7 @@ PHP_METHOD(SplFixedArray, fromArray) spl_fixedarray array; spl_fixedarray_object *intern; int num; - bool save_indexes = 1; + bool save_indexes = true; if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|b", &data, &save_indexes) == FAILURE) { RETURN_THROWS(); @@ -774,9 +764,7 @@ PHP_METHOD(SplFixedArray, getSize) zval *object = ZEND_THIS; spl_fixedarray_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLFIXEDARRAY_P(object); RETURN_LONG(intern->array.size); @@ -815,7 +803,7 @@ PHP_METHOD(SplFixedArray, offsetExists) intern = Z_SPLFIXEDARRAY_P(ZEND_THIS); - RETURN_BOOL(spl_fixedarray_object_has_dimension_helper(intern, zindex, 0)); + RETURN_BOOL(spl_fixedarray_object_has_dimension_helper(intern, zindex, false)); } /* Returns the value at the specified $index. */ @@ -832,7 +820,7 @@ PHP_METHOD(SplFixedArray, offsetGet) value = spl_fixedarray_object_read_dimension_helper(intern, zindex); if (value) { - RETURN_COPY_DEREF(value); + RETURN_COPY(value); } else { RETURN_NULL(); } @@ -871,9 +859,7 @@ PHP_METHOD(SplFixedArray, offsetUnset) /* Create a new iterator from a SplFixedArray instance. */ PHP_METHOD(SplFixedArray, getIterator) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_create_internal_iterator_zval(return_value, ZEND_THIS); } @@ -966,7 +952,7 @@ PHP_MINIT_FUNCTION(spl_fixedarray) memcpy(&spl_handler_SplFixedArray, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplFixedArray.offset = XtOffsetOf(spl_fixedarray_object, std); + spl_handler_SplFixedArray.offset = offsetof(spl_fixedarray_object, std); spl_handler_SplFixedArray.clone_obj = spl_fixedarray_object_clone; spl_handler_SplFixedArray.read_dimension = spl_fixedarray_object_read_dimension; spl_handler_SplFixedArray.write_dimension = spl_fixedarray_object_write_dimension; diff --git a/ext/spl/spl_fixedarray.h b/ext/spl/spl_fixedarray.h index a6cb838b9fc9..e0661a95d872 100644 --- a/ext/spl/spl_fixedarray.h +++ b/ext/spl/spl_fixedarray.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Antony Dovgal | | Etienne Kneuss | diff --git a/ext/spl/spl_fixedarray_arginfo.h b/ext/spl/spl_fixedarray_arginfo.h index c2ff9a77ac40..1c5545ab3e52 100644 --- a/ext/spl/spl_fixedarray_arginfo.h +++ b/ext/spl/spl_fixedarray_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit spl_fixedarray.stub.php instead. * Stub hash: 0c838fed60b29671fe04e63315ab662d8cb16f0c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFixedArray___construct, 0, 0, 0) @@ -98,15 +98,10 @@ static zend_class_entry *register_class_SplFixedArray(zend_class_entry *class_en zend_attribute *attribute_Deprecated_func___wakeup_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "__wakeup", sizeof("__wakeup") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func___wakeup_0_arg0; - zend_string *attribute_Deprecated_func___wakeup_0_arg0_str = zend_string_init("8.4", strlen("8.4"), 1); - ZVAL_STR(&attribute_Deprecated_func___wakeup_0_arg0, attribute_Deprecated_func___wakeup_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func___wakeup_0->args[0].value, &attribute_Deprecated_func___wakeup_0_arg0); + ZVAL_STR(&attribute_Deprecated_func___wakeup_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_4)); attribute_Deprecated_func___wakeup_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func___wakeup_0_arg1; zend_string *attribute_Deprecated_func___wakeup_0_arg1_str = zend_string_init("this method is obsolete, as serialization hooks are provided by __unserialize() and __serialize()", strlen("this method is obsolete, as serialization hooks are provided by __unserialize() and __serialize()"), 1); - ZVAL_STR(&attribute_Deprecated_func___wakeup_0_arg1, attribute_Deprecated_func___wakeup_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func___wakeup_0->args[1].value, &attribute_Deprecated_func___wakeup_0_arg1); + ZVAL_STR(&attribute_Deprecated_func___wakeup_0->args[1].value, attribute_Deprecated_func___wakeup_0_arg1_str); attribute_Deprecated_func___wakeup_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); return class_entry; diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index e7ecbc33f92e..2e04baa26dee 100644 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -20,63 +18,6 @@ #include "php.h" -/* {{{ spl_add_class_name */ -void spl_add_class_name(zval *list, zend_class_entry *pce, int allow, int ce_flags) -{ - if (!allow || (allow > 0 && (pce->ce_flags & ce_flags)) || (allow < 0 && !(pce->ce_flags & ce_flags))) { - zval *tmp; - - if ((tmp = zend_hash_find(Z_ARRVAL_P(list), pce->name)) == NULL) { - zval t; - ZVAL_STR_COPY(&t, pce->name); - zend_hash_add(Z_ARRVAL_P(list), pce->name, &t); - } - } -} -/* }}} */ - -/* {{{ spl_add_interfaces */ -void spl_add_interfaces(zval *list, zend_class_entry * pce, int allow, int ce_flags) -{ - if (pce->num_interfaces) { - ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED); - for (uint32_t num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) { - spl_add_class_name(list, pce->interfaces[num_interfaces], allow, ce_flags); - } - } -} -/* }}} */ - -/* {{{ spl_add_traits */ -void spl_add_traits(zval *list, zend_class_entry * pce, int allow, int ce_flags) -{ - zend_class_entry *trait; - - for (uint32_t num_traits = 0; num_traits < pce->num_traits; num_traits++) { - trait = zend_fetch_class_by_name(pce->trait_names[num_traits].name, - pce->trait_names[num_traits].lc_name, ZEND_FETCH_CLASS_TRAIT); - ZEND_ASSERT(trait); - spl_add_class_name(list, trait, allow, ce_flags); - } -} -/* }}} */ - - -/* {{{ spl_add_classes */ -void spl_add_classes(zend_class_entry *pce, zval *list, bool sub, int allow, int ce_flags) -{ - ZEND_ASSERT(pce); - spl_add_class_name(list, pce, allow, ce_flags); - if (sub) { - spl_add_interfaces(list, pce, allow, ce_flags); - while (pce->parent) { - pce = pce->parent; - spl_add_classes(pce, list, sub, allow, ce_flags); - } - } -} -/* }}} */ - void spl_set_private_debug_info_property( const zend_class_entry *ce, const char *property, diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h index eb81a8b8f818..1d5010030564 100644 --- a/ext/spl/spl_functions.h +++ b/ext/spl/spl_functions.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -19,16 +17,6 @@ #include "php.h" -/* sub: whether to allow subclasses/interfaces - allow = 0: allow all classes and interfaces - allow > 0: allow all that match and mask ce_flags - allow < 0: disallow all that match and mask ce_flags - */ -void spl_add_class_name(zval * list, zend_class_entry * pce, int allow, int ce_flags); -void spl_add_interfaces(zval * list, zend_class_entry * pce, int allow, int ce_flags); -void spl_add_traits(zval * list, zend_class_entry * pce, int allow, int ce_flags); -void spl_add_classes(zend_class_entry *pce, zval *list, bool sub, int allow, int ce_flags); - void spl_set_private_debug_info_property(const zend_class_entry *ce, const char *property, size_t property_len, HashTable *debug_info, zval *value); #endif /* PHP_FUNCTIONS_H */ diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index d4450da42009..cce07f4d91f3 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ @@ -50,7 +48,7 @@ typedef struct _spl_ptr_heap { spl_ptr_heap_ctor_func ctor; spl_ptr_heap_dtor_func dtor; spl_ptr_heap_cmp_func cmp; - int count; + size_t count; int flags; size_t max_size; size_t elem_size; @@ -73,7 +71,7 @@ typedef struct _spl_pqueue_elem { } spl_pqueue_elem; static inline spl_heap_object *spl_heap_from_obj(zend_object *obj) /* {{{ */ { - return (spl_heap_object*)((char*)(obj) - XtOffsetOf(spl_heap_object, std)); + return ZEND_CONTAINER_OF(obj, spl_heap_object, std); } /* }}} */ @@ -267,8 +265,6 @@ static spl_ptr_heap *spl_ptr_heap_init(spl_ptr_heap_cmp_func cmp, spl_ptr_heap_c /* }}} */ static void spl_ptr_heap_insert(spl_ptr_heap *heap, void *elem, void *cmp_userdata) { /* {{{ */ - int i; - if (heap->count+1 > heap->max_size) { size_t alloc_size = heap->max_size * heap->elem_size; /* we need to allocate more memory */ @@ -280,8 +276,9 @@ static void spl_ptr_heap_insert(spl_ptr_heap *heap, void *elem, void *cmp_userda heap->flags |= SPL_HEAP_WRITE_LOCKED; /* sifting up */ - for (i = heap->count; i > 0 && heap->cmp(spl_heap_elem(heap, (i-1)/2), elem, cmp_userdata) < 0; i = (i-1)/2) { - spl_heap_elem_copy(heap, spl_heap_elem(heap, i), spl_heap_elem(heap, (i-1)/2)); + size_t pos; + for (pos = heap->count; pos > 0 && heap->cmp(spl_heap_elem(heap, (pos-1)/2), elem, cmp_userdata) < 0; pos = (pos-1)/2) { + spl_heap_elem_copy(heap, spl_heap_elem(heap, pos), spl_heap_elem(heap, (pos-1)/2)); } heap->count++; @@ -292,7 +289,7 @@ static void spl_ptr_heap_insert(spl_ptr_heap *heap, void *elem, void *cmp_userda heap->flags |= SPL_HEAP_CORRUPTED; } - spl_heap_elem_copy(heap, spl_heap_elem(heap, i), elem); + spl_heap_elem_copy(heap, spl_heap_elem(heap, pos), elem); } /* }}} */ @@ -306,8 +303,7 @@ static void *spl_ptr_heap_top(spl_ptr_heap *heap) { /* {{{ */ /* }}} */ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void *cmp_userdata) { /* {{{ */ - int i, j; - const int limit = (heap->count-1)/2; + const size_t limit = (heap->count-1)/2; void *bottom; if (heap->count == 0) { @@ -324,16 +320,17 @@ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void bottom = spl_heap_elem(heap, --heap->count); - for (i = 0; i < limit; i = j) { + size_t parent_idx, child_idx; + for (parent_idx = 0; parent_idx < limit; parent_idx = child_idx) { /* Find smaller child */ - j = i * 2 + 1; - if (j != heap->count && heap->cmp(spl_heap_elem(heap, j+1), spl_heap_elem(heap, j), cmp_userdata) > 0) { - j++; /* next child is bigger */ + child_idx = parent_idx * 2 + 1; + if (child_idx != heap->count && heap->cmp(spl_heap_elem(heap, child_idx+1), spl_heap_elem(heap, child_idx), cmp_userdata) > 0) { + child_idx++; /* next child is bigger */ } /* swap elements between two levels */ - if(heap->cmp(bottom, spl_heap_elem(heap, j), cmp_userdata) < 0) { - spl_heap_elem_copy(heap, spl_heap_elem(heap, i), spl_heap_elem(heap, j)); + if(heap->cmp(bottom, spl_heap_elem(heap, child_idx), cmp_userdata) < 0) { + spl_heap_elem_copy(heap, spl_heap_elem(heap, parent_idx), spl_heap_elem(heap, child_idx)); } else { break; } @@ -346,7 +343,7 @@ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void heap->flags |= SPL_HEAP_CORRUPTED; } - void *to = spl_heap_elem(heap, i); + void *to = spl_heap_elem(heap, parent_idx); if (to != bottom) { spl_heap_elem_copy(heap, to, bottom); } @@ -355,8 +352,6 @@ static zend_result spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *elem, void /* }}} */ static spl_ptr_heap *spl_ptr_heap_clone(spl_ptr_heap *from) { /* {{{ */ - int i; - spl_ptr_heap *heap = emalloc(sizeof(spl_ptr_heap)); heap->dtor = from->dtor; @@ -370,7 +365,7 @@ static spl_ptr_heap *spl_ptr_heap_clone(spl_ptr_heap *from) { /* {{{ */ heap->elements = safe_emalloc(from->elem_size, from->max_size, 0); memcpy(heap->elements, from->elements, from->elem_size * from->max_size); - for (i = 0; i < heap->count; ++i) { + for (size_t i = 0; i < heap->count; ++i) { heap->ctor(spl_heap_elem(heap, i)); } @@ -384,11 +379,9 @@ static void spl_ptr_heap_destroy(spl_ptr_heap *heap) { /* {{{ */ return; } - int i; - heap->flags |= SPL_HEAP_WRITE_LOCKED; - for (i = 0; i < heap->count; ++i) { + for (size_t i = 0; i < heap->count; ++i) { heap->dtor(spl_heap_elem(heap, i)); } @@ -399,7 +392,7 @@ static void spl_ptr_heap_destroy(spl_ptr_heap *heap) { /* {{{ */ } /* }}} */ -static int spl_ptr_heap_count(spl_ptr_heap *heap) { /* {{{ */ +static size_t spl_ptr_heap_count(spl_ptr_heap *heap) { /* {{{ */ return heap->count; } /* }}} */ @@ -417,7 +410,7 @@ static void spl_heap_object_free_storage(zend_object *object) /* {{{ */ static zend_object *spl_heap_object_new_ex(zend_class_entry *class_type, zend_object *orig, int clone_orig) /* {{{ */ { spl_heap_object *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; int inherited = 0; intern = zend_object_alloc(sizeof(spl_heap_object), parent); @@ -534,7 +527,7 @@ static HashTable* spl_heap_object_get_debug_info(const zend_class_entry *ce, zen array_init(&heap_array); - for (zend_ulong i = 0; i < intern->heap->count; ++i) { + for (size_t i = 0; i < intern->heap->count; ++i) { if (ce == spl_ce_SplPriorityQueue) { spl_pqueue_elem *pq_elem = spl_heap_elem(intern->heap, i); zval elem; @@ -580,9 +573,7 @@ PHP_METHOD(SplHeap, count) zend_long count; spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); count = spl_ptr_heap_count(intern->heap); RETURN_LONG(count); @@ -594,9 +585,7 @@ PHP_METHOD(SplHeap, isEmpty) { spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(spl_ptr_heap_count(intern->heap) == 0); } @@ -645,9 +634,7 @@ PHP_METHOD(SplHeap, extract) { spl_heap_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLHEAP_P(ZEND_THIS); @@ -710,9 +697,7 @@ PHP_METHOD(SplPriorityQueue, extract) spl_pqueue_elem elem; spl_heap_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLHEAP_P(ZEND_THIS); @@ -736,9 +721,7 @@ PHP_METHOD(SplPriorityQueue, top) spl_heap_object *intern; spl_pqueue_elem *elem; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLHEAP_P(ZEND_THIS); @@ -785,9 +768,7 @@ PHP_METHOD(SplPriorityQueue, getExtractFlags) { spl_heap_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLHEAP_P(ZEND_THIS); @@ -800,9 +781,7 @@ PHP_METHOD(SplHeap, recoverFromCorruption) { spl_heap_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLHEAP_P(ZEND_THIS); @@ -817,9 +796,7 @@ PHP_METHOD(SplHeap, isCorrupted) { spl_heap_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLHEAP_P(ZEND_THIS); @@ -846,9 +823,7 @@ PHP_METHOD(SplHeap, top) zval *value; spl_heap_object *intern; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); intern = Z_SPLHEAP_P(ZEND_THIS); @@ -961,7 +936,7 @@ static void spl_heap_it_move_forward(zend_object_iterator *iter) /* {{{ */ { spl_heap_object *object = Z_SPLHEAP_P(&iter->data); - if (UNEXPECTED(spl_heap_consistency_validations(object, false) != SUCCESS)) { + if (UNEXPECTED(spl_heap_consistency_validations(object, true) != SUCCESS)) { return; } @@ -975,9 +950,7 @@ PHP_METHOD(SplHeap, key) { spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(intern->heap->count - 1); } @@ -988,7 +961,9 @@ PHP_METHOD(SplHeap, next) { spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { + ZEND_PARSE_PARAMETERS_NONE(); + + if (UNEXPECTED(spl_heap_consistency_validations(intern, true) != SUCCESS)) { RETURN_THROWS(); } @@ -1001,9 +976,7 @@ PHP_METHOD(SplHeap, valid) { spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(intern->heap->count != 0); } @@ -1012,9 +985,7 @@ PHP_METHOD(SplHeap, valid) /* {{{ Rewind the datastructure back to the start */ PHP_METHOD(SplHeap, rewind) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); /* do nothing, the iterator always points to the top element */ } /* }}} */ @@ -1024,9 +995,7 @@ PHP_METHOD(SplHeap, current) { spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!intern->heap->count) { RETURN_NULL(); @@ -1042,9 +1011,7 @@ PHP_METHOD(SplPriorityQueue, current) { spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!intern->heap->count) { RETURN_NULL(); @@ -1058,9 +1025,7 @@ PHP_METHOD(SplPriorityQueue, current) /* {{{ */ PHP_METHOD(SplHeap, __debugInfo) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_ARR(spl_heap_object_get_debug_info(spl_ce_SplHeap, Z_OBJ_P(ZEND_THIS))); } /* }}} */ @@ -1068,13 +1033,235 @@ PHP_METHOD(SplHeap, __debugInfo) /* {{{ */ PHP_METHOD(SplPriorityQueue, __debugInfo) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_ARR(spl_heap_object_get_debug_info(spl_ce_SplPriorityQueue, Z_OBJ_P(ZEND_THIS))); } /* }}} */ +static void spl_heap_serialize_internal_state(zval *return_value, spl_heap_object *intern, bool is_pqueue) +{ + zval heap_elements; + int heap_count = intern->heap->count; + + array_init(return_value); + add_assoc_long(return_value, "flags", intern->flags); + + array_init_size(&heap_elements, heap_count); + + if (heap_count == 0) { + add_assoc_zval(return_value, "heap_elements", &heap_elements); + return; + } + + for (int heap_idx = 0; heap_idx < heap_count; ++heap_idx) { + if (is_pqueue) { + spl_pqueue_elem *elem = spl_heap_elem(intern->heap, heap_idx); + zval entry; + array_init(&entry); + add_assoc_zval_ex(&entry, "data", strlen("data"), &elem->data); + Z_TRY_ADDREF(elem->data); + add_assoc_zval_ex(&entry, "priority", strlen("priority"), &elem->priority); + Z_TRY_ADDREF(elem->priority); + zend_hash_next_index_insert(Z_ARRVAL(heap_elements), &entry); + } else { + zval *elem = spl_heap_elem(intern->heap, heap_idx); + zend_hash_next_index_insert(Z_ARRVAL(heap_elements), elem); + Z_TRY_ADDREF_P(elem); + } + } + + add_assoc_zval(return_value, "heap_elements", &heap_elements); +} + +static zend_result spl_heap_unserialize_internal_state(HashTable *state_ht, spl_heap_object *intern, zval *this_ptr, bool is_pqueue) +{ + zval *flags_val = zend_hash_str_find(state_ht, "flags", strlen("flags")); + if (!flags_val || Z_TYPE_P(flags_val) != IS_LONG) { + return FAILURE; + } + + zend_long flags_value = Z_LVAL_P(flags_val); + + if (is_pqueue) { + flags_value &= SPL_PQUEUE_EXTR_MASK; + if (!flags_value) { + return FAILURE; + } + } else if (flags_value != 0) { /* Regular heaps should not have user-visible flags */ + return FAILURE; + } + + intern->flags = (int) flags_value; + + zval *heap_elements = zend_hash_str_find(state_ht, "heap_elements", strlen("heap_elements")); + if (!heap_elements) { + return FAILURE; + } + + if (Z_TYPE_P(heap_elements) != IS_ARRAY) { + return FAILURE; + } + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(heap_elements), zval *val) { + if (is_pqueue) { + /* PriorityQueue elements are serialized as arrays with 'data' and 'priority' keys */ + if (Z_TYPE_P(val) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL_P(val)) != 2) { + return FAILURE; + } + + zval *data_val = zend_hash_str_find(Z_ARRVAL_P(val), "data", strlen("data") ); + zval *priority_val = zend_hash_str_find(Z_ARRVAL_P(val), "priority", strlen("priority")); + + if (!data_val || !priority_val) { + return FAILURE; + } + + spl_pqueue_elem elem; + ZVAL_COPY(&elem.data, data_val); + ZVAL_COPY(&elem.priority, priority_val); + spl_ptr_heap_insert(intern->heap, &elem, this_ptr); + if (EG(exception)) { + return FAILURE; + } + } else { + Z_TRY_ADDREF_P(val); + spl_ptr_heap_insert(intern->heap, val, this_ptr); + if (EG(exception)) { + return FAILURE; + } + } + } ZEND_HASH_FOREACH_END(); + + return SUCCESS; +} + +static void spl_heap_serialize_internal(INTERNAL_FUNCTION_PARAMETERS, bool is_pqueue) +{ + spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); + zval props, state; + + ZEND_PARSE_PARAMETERS_NONE(); + + if (UNEXPECTED(spl_heap_consistency_validations(intern, false) != SUCCESS)) { + RETURN_THROWS(); + } + + if (intern->heap->flags & SPL_HEAP_WRITE_LOCKED) { + zend_throw_exception(spl_ce_RuntimeException, "Cannot serialize heap while it is being modified.", 0); + RETURN_THROWS(); + } + + array_init(return_value); + + ZVAL_ARR(&props, zend_array_dup(zend_std_get_properties(&intern->std))); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &props); + + spl_heap_serialize_internal_state(&state, intern, is_pqueue); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &state); +} + +PHP_METHOD(SplPriorityQueue, __serialize) +{ + spl_heap_serialize_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); +} + +PHP_METHOD(SplPriorityQueue, __unserialize) +{ + HashTable *data; + spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(data) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_hash_num_elements(data) != 2) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + zval *props = zend_hash_index_find(data, 0); + if (!props || Z_TYPE_P(props) != IS_ARRAY) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + object_properties_load(&intern->std, Z_ARRVAL_P(props)); + if (EG(exception)) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + zval *state = zend_hash_index_find(data, 1); + if (!state || Z_TYPE_P(state) != IS_ARRAY) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + if (spl_heap_unserialize_internal_state(Z_ARRVAL_P(state), intern, ZEND_THIS, true) != SUCCESS) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + if (EG(exception)) { + RETURN_THROWS(); + } + + if (UNEXPECTED(spl_heap_consistency_validations(intern, false) != SUCCESS)) { + RETURN_THROWS(); + } +} + +PHP_METHOD(SplHeap, __serialize) +{ + spl_heap_serialize_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); +} + +PHP_METHOD(SplHeap, __unserialize) +{ + HashTable *data; + spl_heap_object *intern = Z_SPLHEAP_P(ZEND_THIS); + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_HT(data) + ZEND_PARSE_PARAMETERS_END(); + + if (UNEXPECTED(spl_heap_consistency_validations(intern, true) != SUCCESS)) { + RETURN_THROWS(); + } + + if (zend_hash_num_elements(data) != 2) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + zval *props = zend_hash_index_find(data, 0); + if (!props || Z_TYPE_P(props) != IS_ARRAY) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + object_properties_load(&intern->std, Z_ARRVAL_P(props)); + if (EG(exception)) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + zval *state = zend_hash_index_find(data, 1); + if (!state || Z_TYPE_P(state) != IS_ARRAY) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + if (spl_heap_unserialize_internal_state(Z_ARRVAL_P(state), intern, ZEND_THIS, false) != SUCCESS) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(intern->std.ce->name)); + RETURN_THROWS(); + } + + if (UNEXPECTED(spl_heap_consistency_validations(intern, false) != SUCCESS)) { + RETURN_THROWS(); + } +} + /* iterator handler table */ static const zend_object_iterator_funcs spl_heap_it_funcs = { spl_heap_it_dtor, @@ -1145,7 +1332,7 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */ memcpy(&spl_handler_SplHeap, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplHeap.offset = XtOffsetOf(spl_heap_object, std); + spl_handler_SplHeap.offset = offsetof(spl_heap_object, std); spl_handler_SplHeap.clone_obj = spl_heap_object_clone; spl_handler_SplHeap.count_elements = spl_heap_object_count_elements; spl_handler_SplHeap.get_gc = spl_heap_object_get_gc; @@ -1166,7 +1353,7 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */ memcpy(&spl_handler_SplPriorityQueue, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplPriorityQueue.offset = XtOffsetOf(spl_heap_object, std); + spl_handler_SplPriorityQueue.offset = offsetof(spl_heap_object, std); spl_handler_SplPriorityQueue.clone_obj = spl_heap_object_clone; spl_handler_SplPriorityQueue.count_elements = spl_heap_object_count_elements; spl_handler_SplPriorityQueue.get_gc = spl_pqueue_object_get_gc; diff --git a/ext/spl/spl_heap.h b/ext/spl/spl_heap.h index ccc0dd706bfe..153af1171544 100644 --- a/ext/spl/spl_heap.h +++ b/ext/spl/spl_heap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Etienne Kneuss | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_heap.stub.php b/ext/spl/spl_heap.stub.php index c545d27dfc0f..dd38cfb98343 100644 --- a/ext/spl/spl_heap.stub.php +++ b/ext/spl/spl_heap.stub.php @@ -82,6 +82,12 @@ public function getExtractFlags(): int {} /** @tentative-return-type */ public function __debugInfo(): array {} + + /** @tentative-return-type */ + public function __serialize(): array {} + + /** @tentative-return-type */ + public function __unserialize(array $data): void {} } abstract class SplHeap implements Iterator, Countable @@ -127,6 +133,12 @@ public function isCorrupted(): bool {} /** @tentative-return-type */ public function __debugInfo(): array {} + + /** @tentative-return-type */ + public function __serialize(): array {} + + /** @tentative-return-type */ + public function __unserialize(array $data): void {} } class SplMinHeap extends SplHeap diff --git a/ext/spl/spl_heap_arginfo.h b/ext/spl/spl_heap_arginfo.h index 31a3f79fe2c7..010d911ecb83 100644 --- a/ext/spl/spl_heap_arginfo.h +++ b/ext/spl/spl_heap_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 47273e114c9c7089bf708a2f18f2e9e522abceb6 */ +/* This is a generated file, edit spl_heap.stub.php instead. + * Stub hash: 3256398ed9e798f141fd3cb73370c0d8b2dbd0f1 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplPriorityQueue_compare, 0, 2, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, priority1, IS_MIXED, 0) @@ -47,6 +47,12 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplPriorityQueue___debugInfo, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() +#define arginfo_class_SplPriorityQueue___serialize arginfo_class_SplPriorityQueue___debugInfo + +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplPriorityQueue___unserialize, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + #define arginfo_class_SplHeap_extract arginfo_class_SplPriorityQueue_top ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplHeap_insert, 0, 1, IS_TRUE, 0) @@ -80,6 +86,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_SplHeap___debugInfo arginfo_class_SplPriorityQueue___debugInfo +#define arginfo_class_SplHeap___serialize arginfo_class_SplPriorityQueue___debugInfo + +#define arginfo_class_SplHeap___unserialize arginfo_class_SplPriorityQueue___unserialize + #define arginfo_class_SplMinHeap_compare arginfo_class_SplHeap_compare #define arginfo_class_SplMaxHeap_compare arginfo_class_SplHeap_compare @@ -100,11 +110,15 @@ ZEND_METHOD(SplHeap, recoverFromCorruption); ZEND_METHOD(SplHeap, isCorrupted); ZEND_METHOD(SplPriorityQueue, getExtractFlags); ZEND_METHOD(SplPriorityQueue, __debugInfo); +ZEND_METHOD(SplPriorityQueue, __serialize); +ZEND_METHOD(SplPriorityQueue, __unserialize); ZEND_METHOD(SplHeap, extract); ZEND_METHOD(SplHeap, insert); ZEND_METHOD(SplHeap, top); ZEND_METHOD(SplHeap, current); ZEND_METHOD(SplHeap, __debugInfo); +ZEND_METHOD(SplHeap, __serialize); +ZEND_METHOD(SplHeap, __unserialize); ZEND_METHOD(SplMinHeap, compare); ZEND_METHOD(SplMaxHeap, compare); @@ -125,6 +139,8 @@ static const zend_function_entry class_SplPriorityQueue_methods[] = { ZEND_RAW_FENTRY("isCorrupted", zim_SplHeap_isCorrupted, arginfo_class_SplPriorityQueue_isCorrupted, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(SplPriorityQueue, getExtractFlags, arginfo_class_SplPriorityQueue_getExtractFlags, ZEND_ACC_PUBLIC) ZEND_ME(SplPriorityQueue, __debugInfo, arginfo_class_SplPriorityQueue___debugInfo, ZEND_ACC_PUBLIC) + ZEND_ME(SplPriorityQueue, __serialize, arginfo_class_SplPriorityQueue___serialize, ZEND_ACC_PUBLIC) + ZEND_ME(SplPriorityQueue, __unserialize, arginfo_class_SplPriorityQueue___unserialize, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -143,6 +159,8 @@ static const zend_function_entry class_SplHeap_methods[] = { ZEND_RAW_FENTRY("compare", NULL, arginfo_class_SplHeap_compare, ZEND_ACC_PROTECTED|ZEND_ACC_ABSTRACT, NULL, NULL) ZEND_ME(SplHeap, isCorrupted, arginfo_class_SplHeap_isCorrupted, ZEND_ACC_PUBLIC) ZEND_ME(SplHeap, __debugInfo, arginfo_class_SplHeap___debugInfo, ZEND_ACC_PUBLIC) + ZEND_ME(SplHeap, __serialize, arginfo_class_SplHeap___serialize, ZEND_ACC_PUBLIC) + ZEND_ME(SplHeap, __unserialize, arginfo_class_SplHeap___unserialize, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -166,21 +184,21 @@ static zend_class_entry *register_class_SplPriorityQueue(zend_class_entry *class zval const_EXTR_BOTH_value; ZVAL_LONG(&const_EXTR_BOTH_value, SPL_PQUEUE_EXTR_BOTH); - zend_string *const_EXTR_BOTH_name = zend_string_init_interned("EXTR_BOTH", sizeof("EXTR_BOTH") - 1, 1); + zend_string *const_EXTR_BOTH_name = zend_string_init_interned("EXTR_BOTH", sizeof("EXTR_BOTH") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXTR_BOTH_name, &const_EXTR_BOTH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXTR_BOTH_name); + zend_string_release_ex(const_EXTR_BOTH_name, true); zval const_EXTR_PRIORITY_value; ZVAL_LONG(&const_EXTR_PRIORITY_value, SPL_PQUEUE_EXTR_PRIORITY); - zend_string *const_EXTR_PRIORITY_name = zend_string_init_interned("EXTR_PRIORITY", sizeof("EXTR_PRIORITY") - 1, 1); + zend_string *const_EXTR_PRIORITY_name = zend_string_init_interned("EXTR_PRIORITY", sizeof("EXTR_PRIORITY") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXTR_PRIORITY_name, &const_EXTR_PRIORITY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXTR_PRIORITY_name); + zend_string_release_ex(const_EXTR_PRIORITY_name, true); zval const_EXTR_DATA_value; ZVAL_LONG(&const_EXTR_DATA_value, SPL_PQUEUE_EXTR_DATA); - zend_string *const_EXTR_DATA_name = zend_string_init_interned("EXTR_DATA", sizeof("EXTR_DATA") - 1, 1); + zend_string *const_EXTR_DATA_name = zend_string_init_interned("EXTR_DATA", sizeof("EXTR_DATA") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXTR_DATA_name, &const_EXTR_DATA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXTR_DATA_name); + zend_string_release_ex(const_EXTR_DATA_name, true); return class_entry; } diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 677590cc8951..bc4bfd759400 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ @@ -139,14 +137,14 @@ static zend_object_handlers spl_handlers_rec_it_it; static zend_object_handlers spl_handlers_dual_it; static inline spl_recursive_it_object *spl_recursive_it_from_obj(zend_object *obj) /* {{{ */ { - return (spl_recursive_it_object*)((char*)(obj) - XtOffsetOf(spl_recursive_it_object, std)); + return ZEND_CONTAINER_OF(obj, spl_recursive_it_object, std); } /* }}} */ #define Z_SPLRECURSIVE_IT_P(zv) spl_recursive_it_from_obj(Z_OBJ_P((zv))) static inline spl_dual_it_object *spl_dual_it_from_obj(zend_object *obj) /* {{{ */ { - return (spl_dual_it_object*)((char*)(obj) - XtOffsetOf(spl_dual_it_object, std)); + return ZEND_CONTAINER_OF(obj, spl_dual_it_object, std); } /* }}} */ #define Z_SPLDUAL_IT_P(zv) spl_dual_it_from_obj(Z_OBJ_P((zv))) @@ -222,7 +220,7 @@ static zend_result spl_recursive_it_valid_ex(spl_recursive_it_object *object, zv if (object->endIteration && object->in_iteration) { zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->endIteration, "endIteration", NULL); } - object->in_iteration = 0; + object->in_iteration = false; return FAILURE; } @@ -460,7 +458,7 @@ static void spl_recursive_it_rewind_ex(spl_recursive_it_object *object, zval *zt if (!EG(exception) && object->beginIteration && !object->in_iteration) { zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->beginIteration, "beginIteration", NULL); } - object->in_iteration = 1; + object->in_iteration = true; spl_recursive_it_move_forward_ex(object, zthis); } @@ -614,7 +612,7 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla intern->mode = mode; intern->flags = (int)flags; intern->max_depth = -1; - intern->in_iteration = 0; + intern->in_iteration = false; intern->ce = Z_OBJCE_P(object); intern->beginIteration = zend_hash_str_find_ptr(&intern->ce->function_table, "beginiteration", sizeof("beginiteration") - 1); @@ -740,7 +738,7 @@ PHP_METHOD(RecursiveIteratorIterator, getSubIterator) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(ZEND_THIS); zend_long level; - bool level_is_null = 1; + bool level_is_null = true; zval *value; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &level, &level_is_null) == FAILURE) { @@ -1341,15 +1339,6 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z } break; } - case DIT_AppendIterator: - if (zend_parse_parameters_none() == FAILURE) { - return NULL; - } - intern->dit_type = DIT_AppendIterator; - object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator); - zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL); - intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0); - return intern; case DIT_RegexIterator: case DIT_RecursiveRegexIterator: { zend_string *regex; @@ -2115,14 +2104,27 @@ static zend_object *spl_dual_it_new(zend_class_entry *class_type) } /* }}} */ +/* Returns the relative position for the current iterator position. */ +static zend_long spl_limit_it_relative_pos(spl_dual_it_object *intern) +{ + return intern->current.pos - intern->u.limit.offset; +} + +/* Returns the relative position for an arbitrary position. */ +static zend_long spl_limit_it_relative_pos_for(spl_dual_it_object *intern, zend_long pos) +{ + return pos - intern->u.limit.offset; +} + static inline zend_result spl_limit_it_valid(spl_dual_it_object *intern) { /* FAILURE / SUCCESS */ - if (intern->u.limit.count != -1 && intern->current.pos >= intern->u.limit.offset + intern->u.limit.count) { + if (intern->u.limit.count != -1 && + spl_limit_it_relative_pos(intern) >= intern->u.limit.count) { return FAILURE; - } else { - return spl_dual_it_valid(intern); } + + return spl_dual_it_valid(intern); } static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos) @@ -2134,7 +2136,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos) zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Cannot seek to " ZEND_LONG_FMT " which is below the offset " ZEND_LONG_FMT, pos, intern->u.limit.offset); return; } - if (pos - intern->u.limit.offset >= intern->u.limit.count && intern->u.limit.count != -1) { + if (spl_limit_it_relative_pos_for(intern, pos) >= intern->u.limit.count && intern->u.limit.count != -1) { zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Cannot seek to " ZEND_LONG_FMT " which is behind offset " ZEND_LONG_FMT " plus count " ZEND_LONG_FMT, pos, intern->u.limit.offset, intern->u.limit.count); return; } @@ -2191,7 +2193,7 @@ PHP_METHOD(LimitIterator, valid) SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS); /* RETURN_BOOL(spl_limit_it_valid(intern) == SUCCESS);*/ - RETURN_BOOL((intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF); + RETURN_BOOL((intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF); } /* }}} */ /* {{{ Move the iterator forward */ @@ -2204,7 +2206,7 @@ PHP_METHOD(LimitIterator, next) SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS); spl_dual_it_next(intern, 1); - if (intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) { + if (intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) { spl_dual_it_fetch(intern, 1); } } /* }}} */ @@ -2801,7 +2803,21 @@ static void spl_append_it_next(spl_dual_it_object *intern) /* {{{ */ /* {{{ Create an AppendIterator */ PHP_METHOD(AppendIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_AppendIterator, zend_ce_iterator, DIT_AppendIterator); + ZEND_PARSE_PARAMETERS_NONE(); + + spl_dual_it_object *intern = Z_SPLDUAL_IT_P(ZEND_THIS); + + /* TODO: This should be converted to a normal Error as this is triggered when calling the constructor twice */ + if (intern->dit_type != DIT_Unknown) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s::getIterator() must be called exactly once per instance", ZSTR_VAL(spl_ce_AppendIterator->name)); + RETURN_THROWS(); + } + + intern->dit_type = DIT_AppendIterator; + object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator); + zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL); + intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0); + } /* }}} */ /* {{{ Append an iterator */ @@ -3118,14 +3134,14 @@ PHP_MINIT_FUNCTION(spl_iterators) spl_ce_RecursiveIteratorIterator->get_iterator = spl_recursive_it_get_iterator; memcpy(&spl_handlers_rec_it_it, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handlers_rec_it_it.offset = XtOffsetOf(spl_recursive_it_object, std); + spl_handlers_rec_it_it.offset = offsetof(spl_recursive_it_object, std); spl_handlers_rec_it_it.get_method = spl_recursive_it_get_method; spl_handlers_rec_it_it.clone_obj = NULL; spl_handlers_rec_it_it.free_obj = spl_RecursiveIteratorIterator_free_storage; spl_handlers_rec_it_it.get_gc = spl_RecursiveIteratorIterator_get_gc; memcpy(&spl_handlers_dual_it, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handlers_dual_it.offset = XtOffsetOf(spl_dual_it_object, std); + spl_handlers_dual_it.offset = offsetof(spl_dual_it_object, std); spl_handlers_dual_it.get_method = spl_dual_it_get_method; spl_handlers_dual_it.clone_obj = NULL; spl_handlers_dual_it.free_obj = spl_dual_it_free_storage; diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index e77e34fb20c8..5b60705e9b23 100644 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_iterators_arginfo.h b/ext/spl/spl_iterators_arginfo.h index 439236643471..23a5b6db33df 100644 --- a/ext/spl/spl_iterators_arginfo.h +++ b/ext/spl/spl_iterators_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit spl_iterators.stub.php instead. * Stub hash: ab66d2fff7ac7556d4244582a2bd3e83a3f95243 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_EmptyIterator_current, 0, 0, IS_NEVER, 0) @@ -653,27 +653,27 @@ static zend_class_entry *register_class_RecursiveIteratorIterator(zend_class_ent zval const_LEAVES_ONLY_value; ZVAL_LONG(&const_LEAVES_ONLY_value, RIT_LEAVES_ONLY); - zend_string *const_LEAVES_ONLY_name = zend_string_init_interned("LEAVES_ONLY", sizeof("LEAVES_ONLY") - 1, 1); + zend_string *const_LEAVES_ONLY_name = zend_string_init_interned("LEAVES_ONLY", sizeof("LEAVES_ONLY") - 1, true); zend_declare_typed_class_constant(class_entry, const_LEAVES_ONLY_name, &const_LEAVES_ONLY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_LEAVES_ONLY_name); + zend_string_release_ex(const_LEAVES_ONLY_name, true); zval const_SELF_FIRST_value; ZVAL_LONG(&const_SELF_FIRST_value, RIT_SELF_FIRST); - zend_string *const_SELF_FIRST_name = zend_string_init_interned("SELF_FIRST", sizeof("SELF_FIRST") - 1, 1); + zend_string *const_SELF_FIRST_name = zend_string_init_interned("SELF_FIRST", sizeof("SELF_FIRST") - 1, true); zend_declare_typed_class_constant(class_entry, const_SELF_FIRST_name, &const_SELF_FIRST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SELF_FIRST_name); + zend_string_release_ex(const_SELF_FIRST_name, true); zval const_CHILD_FIRST_value; ZVAL_LONG(&const_CHILD_FIRST_value, RIT_CHILD_FIRST); - zend_string *const_CHILD_FIRST_name = zend_string_init_interned("CHILD_FIRST", sizeof("CHILD_FIRST") - 1, 1); + zend_string *const_CHILD_FIRST_name = zend_string_init_interned("CHILD_FIRST", sizeof("CHILD_FIRST") - 1, true); zend_declare_typed_class_constant(class_entry, const_CHILD_FIRST_name, &const_CHILD_FIRST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CHILD_FIRST_name); + zend_string_release_ex(const_CHILD_FIRST_name, true); zval const_CATCH_GET_CHILD_value; ZVAL_LONG(&const_CATCH_GET_CHILD_value, RIT_CATCH_GET_CHILD); - zend_string *const_CATCH_GET_CHILD_name = zend_string_init_interned("CATCH_GET_CHILD", sizeof("CATCH_GET_CHILD") - 1, 1); + zend_string *const_CATCH_GET_CHILD_name = zend_string_init_interned("CATCH_GET_CHILD", sizeof("CATCH_GET_CHILD") - 1, true); zend_declare_typed_class_constant(class_entry, const_CATCH_GET_CHILD_name, &const_CATCH_GET_CHILD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CATCH_GET_CHILD_name); + zend_string_release_ex(const_CATCH_GET_CHILD_name, true); return class_entry; } @@ -762,39 +762,39 @@ static zend_class_entry *register_class_CachingIterator(zend_class_entry *class_ zval const_CALL_TOSTRING_value; ZVAL_LONG(&const_CALL_TOSTRING_value, CIT_CALL_TOSTRING); - zend_string *const_CALL_TOSTRING_name = zend_string_init_interned("CALL_TOSTRING", sizeof("CALL_TOSTRING") - 1, 1); + zend_string *const_CALL_TOSTRING_name = zend_string_init_interned("CALL_TOSTRING", sizeof("CALL_TOSTRING") - 1, true); zend_declare_typed_class_constant(class_entry, const_CALL_TOSTRING_name, &const_CALL_TOSTRING_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CALL_TOSTRING_name); + zend_string_release_ex(const_CALL_TOSTRING_name, true); zval const_CATCH_GET_CHILD_value; ZVAL_LONG(&const_CATCH_GET_CHILD_value, CIT_CATCH_GET_CHILD); - zend_string *const_CATCH_GET_CHILD_name = zend_string_init_interned("CATCH_GET_CHILD", sizeof("CATCH_GET_CHILD") - 1, 1); + zend_string *const_CATCH_GET_CHILD_name = zend_string_init_interned("CATCH_GET_CHILD", sizeof("CATCH_GET_CHILD") - 1, true); zend_declare_typed_class_constant(class_entry, const_CATCH_GET_CHILD_name, &const_CATCH_GET_CHILD_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CATCH_GET_CHILD_name); + zend_string_release_ex(const_CATCH_GET_CHILD_name, true); zval const_TOSTRING_USE_KEY_value; ZVAL_LONG(&const_TOSTRING_USE_KEY_value, CIT_TOSTRING_USE_KEY); - zend_string *const_TOSTRING_USE_KEY_name = zend_string_init_interned("TOSTRING_USE_KEY", sizeof("TOSTRING_USE_KEY") - 1, 1); + zend_string *const_TOSTRING_USE_KEY_name = zend_string_init_interned("TOSTRING_USE_KEY", sizeof("TOSTRING_USE_KEY") - 1, true); zend_declare_typed_class_constant(class_entry, const_TOSTRING_USE_KEY_name, &const_TOSTRING_USE_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TOSTRING_USE_KEY_name); + zend_string_release_ex(const_TOSTRING_USE_KEY_name, true); zval const_TOSTRING_USE_CURRENT_value; ZVAL_LONG(&const_TOSTRING_USE_CURRENT_value, CIT_TOSTRING_USE_CURRENT); - zend_string *const_TOSTRING_USE_CURRENT_name = zend_string_init_interned("TOSTRING_USE_CURRENT", sizeof("TOSTRING_USE_CURRENT") - 1, 1); + zend_string *const_TOSTRING_USE_CURRENT_name = zend_string_init_interned("TOSTRING_USE_CURRENT", sizeof("TOSTRING_USE_CURRENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_TOSTRING_USE_CURRENT_name, &const_TOSTRING_USE_CURRENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TOSTRING_USE_CURRENT_name); + zend_string_release_ex(const_TOSTRING_USE_CURRENT_name, true); zval const_TOSTRING_USE_INNER_value; ZVAL_LONG(&const_TOSTRING_USE_INNER_value, CIT_TOSTRING_USE_INNER); - zend_string *const_TOSTRING_USE_INNER_name = zend_string_init_interned("TOSTRING_USE_INNER", sizeof("TOSTRING_USE_INNER") - 1, 1); + zend_string *const_TOSTRING_USE_INNER_name = zend_string_init_interned("TOSTRING_USE_INNER", sizeof("TOSTRING_USE_INNER") - 1, true); zend_declare_typed_class_constant(class_entry, const_TOSTRING_USE_INNER_name, &const_TOSTRING_USE_INNER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TOSTRING_USE_INNER_name); + zend_string_release_ex(const_TOSTRING_USE_INNER_name, true); zval const_FULL_CACHE_value; ZVAL_LONG(&const_FULL_CACHE_value, CIT_FULL_CACHE); - zend_string *const_FULL_CACHE_name = zend_string_init_interned("FULL_CACHE", sizeof("FULL_CACHE") - 1, 1); + zend_string *const_FULL_CACHE_name = zend_string_init_interned("FULL_CACHE", sizeof("FULL_CACHE") - 1, true); zend_declare_typed_class_constant(class_entry, const_FULL_CACHE_name, &const_FULL_CACHE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FULL_CACHE_name); + zend_string_release_ex(const_FULL_CACHE_name, true); return class_entry; } @@ -849,51 +849,51 @@ static zend_class_entry *register_class_RegexIterator(zend_class_entry *class_en zval const_USE_KEY_value; ZVAL_LONG(&const_USE_KEY_value, REGIT_USE_KEY); - zend_string *const_USE_KEY_name = zend_string_init_interned("USE_KEY", sizeof("USE_KEY") - 1, 1); + zend_string *const_USE_KEY_name = zend_string_init_interned("USE_KEY", sizeof("USE_KEY") - 1, true); zend_declare_typed_class_constant(class_entry, const_USE_KEY_name, &const_USE_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_USE_KEY_name); + zend_string_release_ex(const_USE_KEY_name, true); zval const_INVERT_MATCH_value; ZVAL_LONG(&const_INVERT_MATCH_value, REGIT_INVERTED); - zend_string *const_INVERT_MATCH_name = zend_string_init_interned("INVERT_MATCH", sizeof("INVERT_MATCH") - 1, 1); + zend_string *const_INVERT_MATCH_name = zend_string_init_interned("INVERT_MATCH", sizeof("INVERT_MATCH") - 1, true); zend_declare_typed_class_constant(class_entry, const_INVERT_MATCH_name, &const_INVERT_MATCH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_INVERT_MATCH_name); + zend_string_release_ex(const_INVERT_MATCH_name, true); zval const_MATCH_value; ZVAL_LONG(&const_MATCH_value, REGIT_MODE_MATCH); - zend_string *const_MATCH_name = zend_string_init_interned("MATCH", sizeof("MATCH") - 1, 1); + zend_string *const_MATCH_name = zend_string_init_interned("MATCH", sizeof("MATCH") - 1, true); zend_declare_typed_class_constant(class_entry, const_MATCH_name, &const_MATCH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MATCH_name); + zend_string_release_ex(const_MATCH_name, true); zval const_GET_MATCH_value; ZVAL_LONG(&const_GET_MATCH_value, REGIT_MODE_GET_MATCH); - zend_string *const_GET_MATCH_name = zend_string_init_interned("GET_MATCH", sizeof("GET_MATCH") - 1, 1); + zend_string *const_GET_MATCH_name = zend_string_init_interned("GET_MATCH", sizeof("GET_MATCH") - 1, true); zend_declare_typed_class_constant(class_entry, const_GET_MATCH_name, &const_GET_MATCH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_GET_MATCH_name); + zend_string_release_ex(const_GET_MATCH_name, true); zval const_ALL_MATCHES_value; ZVAL_LONG(&const_ALL_MATCHES_value, REGIT_MODE_ALL_MATCHES); - zend_string *const_ALL_MATCHES_name = zend_string_init_interned("ALL_MATCHES", sizeof("ALL_MATCHES") - 1, 1); + zend_string *const_ALL_MATCHES_name = zend_string_init_interned("ALL_MATCHES", sizeof("ALL_MATCHES") - 1, true); zend_declare_typed_class_constant(class_entry, const_ALL_MATCHES_name, &const_ALL_MATCHES_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ALL_MATCHES_name); + zend_string_release_ex(const_ALL_MATCHES_name, true); zval const_SPLIT_value; ZVAL_LONG(&const_SPLIT_value, REGIT_MODE_SPLIT); - zend_string *const_SPLIT_name = zend_string_init_interned("SPLIT", sizeof("SPLIT") - 1, 1); + zend_string *const_SPLIT_name = zend_string_init_interned("SPLIT", sizeof("SPLIT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SPLIT_name, &const_SPLIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SPLIT_name); + zend_string_release_ex(const_SPLIT_name, true); zval const_REPLACE_value; ZVAL_LONG(&const_REPLACE_value, REGIT_MODE_REPLACE); - zend_string *const_REPLACE_name = zend_string_init_interned("REPLACE", sizeof("REPLACE") - 1, 1); + zend_string *const_REPLACE_name = zend_string_init_interned("REPLACE", sizeof("REPLACE") - 1, true); zend_declare_typed_class_constant(class_entry, const_REPLACE_name, &const_REPLACE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REPLACE_name); + zend_string_release_ex(const_REPLACE_name, true); zval property_replacement_default_value; ZVAL_NULL(&property_replacement_default_value); - zend_string *property_replacement_name = zend_string_init("replacement", sizeof("replacement") - 1, 1); + zend_string *property_replacement_name = zend_string_init("replacement", sizeof("replacement") - 1, true); zend_declare_typed_property(class_entry, property_replacement_name, &property_replacement_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_replacement_name); + zend_string_release_ex(property_replacement_name, true); return class_entry; } @@ -918,51 +918,51 @@ static zend_class_entry *register_class_RecursiveTreeIterator(zend_class_entry * zval const_BYPASS_CURRENT_value; ZVAL_LONG(&const_BYPASS_CURRENT_value, RTIT_BYPASS_CURRENT); - zend_string *const_BYPASS_CURRENT_name = zend_string_init_interned("BYPASS_CURRENT", sizeof("BYPASS_CURRENT") - 1, 1); + zend_string *const_BYPASS_CURRENT_name = zend_string_init_interned("BYPASS_CURRENT", sizeof("BYPASS_CURRENT") - 1, true); zend_declare_typed_class_constant(class_entry, const_BYPASS_CURRENT_name, &const_BYPASS_CURRENT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BYPASS_CURRENT_name); + zend_string_release_ex(const_BYPASS_CURRENT_name, true); zval const_BYPASS_KEY_value; ZVAL_LONG(&const_BYPASS_KEY_value, RTIT_BYPASS_KEY); - zend_string *const_BYPASS_KEY_name = zend_string_init_interned("BYPASS_KEY", sizeof("BYPASS_KEY") - 1, 1); + zend_string *const_BYPASS_KEY_name = zend_string_init_interned("BYPASS_KEY", sizeof("BYPASS_KEY") - 1, true); zend_declare_typed_class_constant(class_entry, const_BYPASS_KEY_name, &const_BYPASS_KEY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_BYPASS_KEY_name); + zend_string_release_ex(const_BYPASS_KEY_name, true); zval const_PREFIX_LEFT_value; ZVAL_LONG(&const_PREFIX_LEFT_value, 0); - zend_string *const_PREFIX_LEFT_name = zend_string_init_interned("PREFIX_LEFT", sizeof("PREFIX_LEFT") - 1, 1); + zend_string *const_PREFIX_LEFT_name = zend_string_init_interned("PREFIX_LEFT", sizeof("PREFIX_LEFT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PREFIX_LEFT_name, &const_PREFIX_LEFT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PREFIX_LEFT_name); + zend_string_release_ex(const_PREFIX_LEFT_name, true); zval const_PREFIX_MID_HAS_NEXT_value; ZVAL_LONG(&const_PREFIX_MID_HAS_NEXT_value, 1); - zend_string *const_PREFIX_MID_HAS_NEXT_name = zend_string_init_interned("PREFIX_MID_HAS_NEXT", sizeof("PREFIX_MID_HAS_NEXT") - 1, 1); + zend_string *const_PREFIX_MID_HAS_NEXT_name = zend_string_init_interned("PREFIX_MID_HAS_NEXT", sizeof("PREFIX_MID_HAS_NEXT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PREFIX_MID_HAS_NEXT_name, &const_PREFIX_MID_HAS_NEXT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PREFIX_MID_HAS_NEXT_name); + zend_string_release_ex(const_PREFIX_MID_HAS_NEXT_name, true); zval const_PREFIX_MID_LAST_value; ZVAL_LONG(&const_PREFIX_MID_LAST_value, 2); - zend_string *const_PREFIX_MID_LAST_name = zend_string_init_interned("PREFIX_MID_LAST", sizeof("PREFIX_MID_LAST") - 1, 1); + zend_string *const_PREFIX_MID_LAST_name = zend_string_init_interned("PREFIX_MID_LAST", sizeof("PREFIX_MID_LAST") - 1, true); zend_declare_typed_class_constant(class_entry, const_PREFIX_MID_LAST_name, &const_PREFIX_MID_LAST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PREFIX_MID_LAST_name); + zend_string_release_ex(const_PREFIX_MID_LAST_name, true); zval const_PREFIX_END_HAS_NEXT_value; ZVAL_LONG(&const_PREFIX_END_HAS_NEXT_value, 3); - zend_string *const_PREFIX_END_HAS_NEXT_name = zend_string_init_interned("PREFIX_END_HAS_NEXT", sizeof("PREFIX_END_HAS_NEXT") - 1, 1); + zend_string *const_PREFIX_END_HAS_NEXT_name = zend_string_init_interned("PREFIX_END_HAS_NEXT", sizeof("PREFIX_END_HAS_NEXT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PREFIX_END_HAS_NEXT_name, &const_PREFIX_END_HAS_NEXT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PREFIX_END_HAS_NEXT_name); + zend_string_release_ex(const_PREFIX_END_HAS_NEXT_name, true); zval const_PREFIX_END_LAST_value; ZVAL_LONG(&const_PREFIX_END_LAST_value, 4); - zend_string *const_PREFIX_END_LAST_name = zend_string_init_interned("PREFIX_END_LAST", sizeof("PREFIX_END_LAST") - 1, 1); + zend_string *const_PREFIX_END_LAST_name = zend_string_init_interned("PREFIX_END_LAST", sizeof("PREFIX_END_LAST") - 1, true); zend_declare_typed_class_constant(class_entry, const_PREFIX_END_LAST_name, &const_PREFIX_END_LAST_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PREFIX_END_LAST_name); + zend_string_release_ex(const_PREFIX_END_LAST_name, true); zval const_PREFIX_RIGHT_value; ZVAL_LONG(&const_PREFIX_RIGHT_value, 5); - zend_string *const_PREFIX_RIGHT_name = zend_string_init_interned("PREFIX_RIGHT", sizeof("PREFIX_RIGHT") - 1, 1); + zend_string *const_PREFIX_RIGHT_name = zend_string_init_interned("PREFIX_RIGHT", sizeof("PREFIX_RIGHT") - 1, true); zend_declare_typed_class_constant(class_entry, const_PREFIX_RIGHT_name, &const_PREFIX_RIGHT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PREFIX_RIGHT_name); + zend_string_release_ex(const_PREFIX_RIGHT_name, true); return class_entry; } diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index e6e6786c1c23..7d565714afd6 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | | Etienne Kneuss | @@ -25,6 +23,7 @@ #include "zend_smart_str.h" #include "zend_interfaces.h" #include "zend_exceptions.h" +#include "zend_attributes.h" #include "php_spl.h" /* For php_spl_object_hash() */ #include "spl_observer.h" @@ -39,12 +38,15 @@ PHPAPI zend_class_entry *spl_ce_SplObjectStorage; PHPAPI zend_class_entry *spl_ce_MultipleIterator; static zend_object_handlers spl_handler_SplObjectStorage; +static zend_object_handlers spl_handler_MultipleIterator; /* Bit flags for marking internal functionality overridden by SplObjectStorage subclasses. */ #define SOS_OVERRIDDEN_READ_DIMENSION 1 #define SOS_OVERRIDDEN_WRITE_DIMENSION 2 #define SOS_OVERRIDDEN_UNSET_DIMENSION 4 +ZEND_TLS uint32_t spl_object_storage_get_hash_depth; + typedef struct _spl_SplObjectStorage { /* {{{ */ HashTable storage; zend_long index; @@ -63,12 +65,22 @@ typedef struct _spl_SplObjectStorageElement { } spl_SplObjectStorageElement; /* }}} */ static inline spl_SplObjectStorage *spl_object_storage_from_obj(zend_object *obj) /* {{{ */ { - return (spl_SplObjectStorage*)((char*)(obj) - XtOffsetOf(spl_SplObjectStorage, std)); + return ZEND_CONTAINER_OF(obj, spl_SplObjectStorage, std); } /* }}} */ #define Z_SPLOBJSTORAGE_P(zv) spl_object_storage_from_obj(Z_OBJ_P((zv))) +static zend_always_inline bool spl_object_storage_is_mutating_within_get_hash_call(void) +{ + if (UNEXPECTED(spl_object_storage_get_hash_depth)) { + zend_throw_error(NULL, "Modification of SplObjectStorage during getHash() is prohibited"); + return true; + } + + return false; +} + static void spl_SplObjectStorage_free_storage(zend_object *object) /* {{{ */ { spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); @@ -83,7 +95,10 @@ static zend_result spl_object_storage_get_hash(zend_hash_key *key, spl_SplObject zval param; zval rv; ZVAL_OBJ(¶m, obj); + ZVAL_UNDEF(&rv); + spl_object_storage_get_hash_depth++; zend_call_method_with_1_params(&intern->std, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, ¶m); + spl_object_storage_get_hash_depth--; if (UNEXPECTED(Z_ISUNDEF(rv))) { /* An exception has occurred */ return FAILURE; @@ -176,6 +191,10 @@ static spl_SplObjectStorageElement *spl_object_storage_attach_handle(spl_SplObje static spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *intern, zend_object *obj, zval *inf) /* {{{ */ { + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return NULL; + } + if (EXPECTED(!(intern->flags & SOS_OVERRIDDEN_WRITE_DIMENSION))) { return spl_object_storage_attach_handle(intern, obj, inf); } @@ -221,6 +240,10 @@ static spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStora static zend_result spl_object_storage_detach(spl_SplObjectStorage *intern, zend_object *obj) /* {{{ */ { + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return FAILURE; + } + if (EXPECTED(!(intern->flags & SOS_OVERRIDDEN_UNSET_DIMENSION))) { return zend_hash_index_del(&intern->storage, obj->handle); } @@ -239,14 +262,32 @@ static zend_result spl_object_storage_detach(spl_SplObjectStorage *intern, zend_ return ret; } /* }}}*/ -static void spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjectStorage *other) { /* {{{ */ +/* TODO: make this an official Zend API? */ +#define SPL_SAFE_HASH_FOREACH_PTR(_ht, _ptr) do { \ + const HashTable *__ht = (_ht); \ + zval *_z = __ht->arPacked; \ + for (uint32_t _idx = 0; _idx < __ht->nNumUsed; _idx++, _z = ZEND_HASH_ELEMENT(__ht, _idx)) { \ + if (UNEXPECTED(Z_ISUNDEF_P(_z))) continue; \ + _ptr = Z_PTR_P(_z); + +static zend_result spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjectStorage *other) { /* {{{ */ spl_SplObjectStorageElement *element; - ZEND_HASH_FOREACH_PTR(&other->storage, element) { - spl_object_storage_attach(intern, element->obj, &element->inf); + SPL_SAFE_HASH_FOREACH_PTR(&other->storage, element) { + zval zv; + zend_object *obj = element->obj; + GC_ADDREF(obj); + ZVAL_COPY(&zv, &element->inf); + spl_SplObjectStorageElement *attached = spl_object_storage_attach(intern, obj, &zv); + zval_ptr_dtor(&zv); + OBJ_RELEASE(obj); + if (UNEXPECTED(!attached)) { + return FAILURE; + } } ZEND_HASH_FOREACH_END(); intern->index = 0; + return SUCCESS; } /* }}} */ #define SPL_OBJECT_STORAGE_CLASS_HAS_OVERRIDE(class_type, zstr_method) \ @@ -255,7 +296,7 @@ static void spl_object_storage_addall(spl_SplObjectStorage *intern, spl_SplObjec static zend_object *spl_object_storage_new_ex(zend_class_entry *class_type, zend_object *orig) /* {{{ */ { spl_SplObjectStorage *intern; - zend_class_entry *parent = class_type; + const zend_class_entry *parent = class_type; intern = zend_object_alloc(sizeof(spl_SplObjectStorage), parent); intern->pos = 0; @@ -432,6 +473,9 @@ PHP_METHOD(SplObjectStorage, attach) Z_PARAM_ZVAL(inf) ZEND_PARSE_PARAMETERS_END(); spl_object_storage_attach(intern, obj, inf); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } /* }}} */ // todo: make spl_object_storage_has_dimension return bool as well @@ -480,6 +524,10 @@ static zval *spl_object_storage_read_dimension(zend_object *object, zval *offset static void spl_object_storage_write_dimension(zend_object *object, zval *offset, zval *inf) { spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return; + } + if (UNEXPECTED(offset == NULL || Z_TYPE_P(offset) != IS_OBJECT || (intern->flags & SOS_OVERRIDDEN_WRITE_DIMENSION))) { zend_std_write_dimension(object, offset, inf); return; @@ -487,9 +535,31 @@ static void spl_object_storage_write_dimension(zend_object *object, zval *offset spl_object_storage_attach_handle(intern, Z_OBJ_P(offset), inf); } +static void spl_multiple_iterator_write_dimension(zend_object *object, zval *offset, zval *inf) +{ + spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return; + } + + if (UNEXPECTED(offset == NULL || Z_TYPE_P(offset) != IS_OBJECT || (intern->flags & SOS_OVERRIDDEN_WRITE_DIMENSION))) { + zend_std_write_dimension(object, offset, inf); + return; + } + if (UNEXPECTED(!Z_OBJCE_P(offset)->iterator_funcs_ptr || !Z_OBJCE_P(offset)->iterator_funcs_ptr->zf_valid)) { + zend_type_error("Can only attach objects that implement the Iterator interface"); + return; + } + spl_object_storage_attach_handle(intern, Z_OBJ_P(offset), inf); +} + static void spl_object_storage_unset_dimension(zend_object *object, zval *offset) { spl_SplObjectStorage *intern = spl_object_storage_from_obj(object); + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + return; + } + if (UNEXPECTED(Z_TYPE_P(offset) != IS_OBJECT || (intern->flags & SOS_OVERRIDDEN_UNSET_DIMENSION))) { zend_std_unset_dimension(object, offset); return; @@ -507,6 +577,9 @@ PHP_METHOD(SplObjectStorage, detach) Z_PARAM_OBJ(obj) ZEND_PARSE_PARAMETERS_END(); spl_object_storage_detach(intern, obj); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); intern->index = 0; @@ -538,6 +611,7 @@ PHP_METHOD(SplObjectStorage, offsetGet) ZEND_PARSE_PARAMETERS_END(); if (spl_object_storage_get_hash(&key, intern, obj) == FAILURE) { + /* This may be the old NULL fallback, or an exception thrown by getHash(). */ RETURN_NULL(); } @@ -564,7 +638,9 @@ PHP_METHOD(SplObjectStorage, addAll) other = Z_SPLOBJSTORAGE_P(obj); - spl_object_storage_addall(intern, other); + if (UNEXPECTED(spl_object_storage_addall(intern, other) == FAILURE)) { + RETURN_THROWS(); + } RETURN_LONG(zend_hash_num_elements(&intern->storage)); } /* }}} */ @@ -586,6 +662,9 @@ PHP_METHOD(SplObjectStorage, removeAll) zend_hash_internal_pointer_reset(&other->storage); while ((element = zend_hash_get_current_data_ptr(&other->storage)) != NULL) { if (spl_object_storage_detach(intern, element->obj) == FAILURE) { + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } zend_hash_move_forward(&other->storage); } } @@ -610,10 +689,24 @@ PHP_METHOD(SplObjectStorage, removeAllExcept) other = Z_SPLOBJSTORAGE_P(obj); - ZEND_HASH_FOREACH_PTR(&intern->storage, element) { - if (!spl_object_storage_contains(other, element->obj)) { - spl_object_storage_detach(intern, element->obj); + SPL_SAFE_HASH_FOREACH_PTR(&intern->storage, element) { + zend_object *elem_obj = element->obj; + GC_ADDREF(elem_obj); + bool contains = spl_object_storage_contains(other, elem_obj); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(elem_obj); + RETURN_THROWS(); } + if (!contains) { + if (spl_object_storage_detach(intern, elem_obj) == FAILURE) { + OBJ_RELEASE(elem_obj); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + continue; + } + } + OBJ_RELEASE(elem_obj); } ZEND_HASH_FOREACH_END(); zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); @@ -632,7 +725,13 @@ PHP_METHOD(SplObjectStorage, contains) ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_OBJ(obj) ZEND_PARSE_PARAMETERS_END(); - RETURN_BOOL(spl_object_storage_contains(intern, obj)); + + bool contains = spl_object_storage_contains(intern, obj); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + + RETURN_BOOL(contains); } /* }}} */ /* {{{ Determine number of objects in storage */ @@ -657,9 +756,7 @@ PHP_METHOD(SplObjectStorage, rewind) { spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); intern->index = 0; @@ -670,9 +767,7 @@ PHP_METHOD(SplObjectStorage, valid) { spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_BOOL(zend_hash_has_more_elements_ex(&intern->storage, &intern->pos) == SUCCESS); } /* }}} */ @@ -682,9 +777,7 @@ PHP_METHOD(SplObjectStorage, key) { spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(intern->index); } /* }}} */ @@ -695,9 +788,7 @@ PHP_METHOD(SplObjectStorage, current) spl_SplObjectStorageElement *element; spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) { zend_throw_exception(spl_ce_RuntimeException, "Called current() on invalid iterator", 0); @@ -712,9 +803,7 @@ PHP_METHOD(SplObjectStorage, getInfo) spl_SplObjectStorageElement *element; spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) { RETURN_NULL(); @@ -732,6 +821,9 @@ PHP_METHOD(SplObjectStorage, setInfo) if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &inf) == FAILURE) { RETURN_THROWS(); } + if (UNEXPECTED(spl_object_storage_is_mutating_within_get_hash_call())) { + RETURN_THROWS(); + } if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) { RETURN_NULL(); @@ -747,9 +839,7 @@ PHP_METHOD(SplObjectStorage, next) { spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_hash_move_forward_ex(&intern->storage, &intern->pos); intern->index++; @@ -809,9 +899,7 @@ PHP_METHOD(SplObjectStorage, serialize) php_serialize_data_t var_hash; smart_str buf = {0}; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); PHP_VAR_SERIALIZE_INIT(var_hash); @@ -930,6 +1018,10 @@ PHP_METHOD(SplObjectStorage, unserialize) if (spl_object_storage_get_hash(&key, intern, Z_OBJ_P(entry)) == FAILURE) { zval_ptr_dtor(&inf); + if (EG(exception)) { + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + RETURN_THROWS(); + } goto outexcept; } pelement = spl_object_storage_get(intern, &key); @@ -943,6 +1035,14 @@ PHP_METHOD(SplObjectStorage, unserialize) var_push_dtor(&var_hash, &obj); } element = spl_object_storage_attach(intern, Z_OBJ_P(entry), Z_ISUNDEF(inf)?NULL:&inf); + if (UNEXPECTED(!element)) { + zval_ptr_dtor(&inf); + if (EG(exception)) { + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + RETURN_THROWS(); + } + goto outexcept; + } var_replace(&var_hash, &inf, &element->inf); zval_ptr_dtor(&inf); } @@ -983,9 +1083,7 @@ PHP_METHOD(SplObjectStorage, __serialize) spl_SplObjectStorageElement *elem; zval tmp; - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -1040,7 +1138,9 @@ PHP_METHOD(SplObjectStorage, __unserialize) } ZVAL_DEREF(val); - spl_object_storage_attach(intern, Z_OBJ_P(key), val); + if (UNEXPECTED(!spl_object_storage_attach(intern, Z_OBJ_P(key), val))) { + RETURN_THROWS(); + } key = NULL; } else { key = val; @@ -1053,9 +1153,7 @@ PHP_METHOD(SplObjectStorage, __unserialize) /* {{{ */ PHP_METHOD(SplObjectStorage, __debugInfo) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_ARR(spl_object_storage_debug_info(Z_OBJ_P(ZEND_THIS))); } @@ -1084,9 +1182,7 @@ PHP_METHOD(MultipleIterator, getFlags) { spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(intern->flags); } /* }}} */ @@ -1140,8 +1236,14 @@ PHP_METHOD(MultipleIterator, attachIterator) } spl_object_storage_attach(intern, iterator, &zinfo); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } else { spl_object_storage_attach(intern, iterator, NULL); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } } /* }}} */ @@ -1156,6 +1258,9 @@ PHP_METHOD(MultipleIterator, detachIterator) RETURN_THROWS(); } spl_object_storage_detach(intern, Z_OBJ_P(iterator)); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); intern->index = 0; @@ -1177,9 +1282,7 @@ PHP_METHOD(MultipleIterator, countIterators) { spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); RETURN_LONG(zend_hash_num_elements(&intern->storage)); } @@ -1192,14 +1295,14 @@ PHP_METHOD(MultipleIterator, rewind) intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + GC_ADDREF(it); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_rewind, it, NULL); + OBJ_RELEASE(it); zend_hash_move_forward_ex(&intern->storage, &intern->pos); } } @@ -1213,14 +1316,14 @@ PHP_METHOD(MultipleIterator, next) intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + GC_ADDREF(it); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_next, it, NULL); + OBJ_RELEASE(it); zend_hash_move_forward_ex(&intern->storage, &intern->pos); } } @@ -1236,9 +1339,7 @@ PHP_METHOD(MultipleIterator, valid) intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!zend_hash_num_elements(&intern->storage)) { RETURN_FALSE; @@ -1249,7 +1350,9 @@ PHP_METHOD(MultipleIterator, valid) zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + GC_ADDREF(it); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_valid, it, &retval); + OBJ_RELEASE(it); if (!Z_ISUNDEF(retval)) { valid = (Z_TYPE(retval) == IS_TRUE); @@ -1287,6 +1390,9 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) { zend_object *it = element->obj; + zval inf; + GC_ADDREF(it); + ZVAL_COPY(&inf, &element->inf); zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_valid, it, &retval); if (!Z_ISUNDEF(retval)) { @@ -1303,10 +1409,14 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_key, it, &retval); } if (Z_ISUNDEF(retval)) { + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); zend_throw_exception(spl_ce_RuntimeException, "Failed to call sub iterator method", 0); return; } } else if (intern->flags & MIT_NEED_ALL) { + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) { zend_throw_exception(spl_ce_RuntimeException, "Called current() with non valid sub iterator", 0); } else { @@ -1318,15 +1428,17 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ } if (intern->flags & MIT_KEYS_ASSOC) { - switch (Z_TYPE(element->inf)) { + switch (Z_TYPE(inf)) { case IS_LONG: - add_index_zval(return_value, Z_LVAL(element->inf), &retval); + add_index_zval(return_value, Z_LVAL(inf), &retval); break; case IS_STRING: - zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR(element->inf), &retval); + zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR(inf), &retval); break; default: zval_ptr_dtor(&retval); + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); zend_throw_exception(spl_ce_InvalidArgumentException, "Sub-Iterator is associated with NULL", 0); return; } @@ -1334,6 +1446,8 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ add_next_index_zval(return_value, &retval); } + OBJ_RELEASE(it); + zval_ptr_dtor(&inf); zend_hash_move_forward_ex(&intern->storage, &intern->pos); } } @@ -1345,9 +1459,7 @@ PHP_METHOD(MultipleIterator, current) spl_SplObjectStorage *intern; intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_multiple_iterator_get_all(intern, SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT, return_value); } @@ -1359,9 +1471,7 @@ PHP_METHOD(MultipleIterator, key) spl_SplObjectStorage *intern; intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); spl_multiple_iterator_get_all(intern, SPL_MULTIPLE_ITERATOR_GET_ALL_KEY, return_value); } @@ -1379,7 +1489,7 @@ PHP_MINIT_FUNCTION(spl_observer) memcpy(&spl_handler_SplObjectStorage, &std_object_handlers, sizeof(zend_object_handlers)); - spl_handler_SplObjectStorage.offset = XtOffsetOf(spl_SplObjectStorage, std); + spl_handler_SplObjectStorage.offset = offsetof(spl_SplObjectStorage, std); spl_handler_SplObjectStorage.compare = spl_object_storage_compare_objects; spl_handler_SplObjectStorage.clone_obj = spl_object_storage_clone; spl_handler_SplObjectStorage.get_gc = spl_object_storage_get_gc; @@ -1389,9 +1499,13 @@ PHP_MINIT_FUNCTION(spl_observer) spl_handler_SplObjectStorage.has_dimension = spl_object_storage_has_dimension; spl_handler_SplObjectStorage.unset_dimension = spl_object_storage_unset_dimension; + memcpy(&spl_handler_MultipleIterator, &spl_handler_SplObjectStorage, sizeof(zend_object_handlers)); + + spl_handler_MultipleIterator.write_dimension = spl_multiple_iterator_write_dimension; + spl_ce_MultipleIterator = register_class_MultipleIterator(zend_ce_iterator); spl_ce_MultipleIterator->create_object = spl_SplObjectStorage_new; - spl_ce_MultipleIterator->default_object_handlers = &spl_handler_SplObjectStorage; + spl_ce_MultipleIterator->default_object_handlers = &spl_handler_MultipleIterator; return SUCCESS; } diff --git a/ext/spl/spl_observer.h b/ext/spl/spl_observer.h index b7c22b2dfca0..08d3126d9c8b 100644 --- a/ext/spl/spl_observer.h +++ b/ext/spl/spl_observer.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Marcus Boerger | +----------------------------------------------------------------------+ diff --git a/ext/spl/spl_observer.stub.php b/ext/spl/spl_observer.stub.php index 9e78272cf350..1a3c1f68433b 100644 --- a/ext/spl/spl_observer.stub.php +++ b/ext/spl/spl_observer.stub.php @@ -23,12 +23,15 @@ public function notify(): void; class SplObjectStorage implements Countable, SeekableIterator, Serializable, ArrayAccess { /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "use method SplObjectStorage::offsetSet() instead")] public function attach(object $object, mixed $info = null): void {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "use method SplObjectStorage::offsetUnset() instead")] public function detach(object $object): void {} /** @tentative-return-type */ + #[\Deprecated(since: '8.5', message: "use method SplObjectStorage::offsetExists() instead")] public function contains(object $object): bool {} /** @tentative-return-type */ diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index be12c594e014..142c400bcfe8 100644 --- a/ext/spl/spl_observer_arginfo.h +++ b/ext/spl/spl_observer_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: a846c9dd240b6f0666cd5e805abfacabe360cf4c */ +/* This is a generated file, edit spl_observer.stub.php instead. + * Stub hash: 9dfd8bcf8946cbee550c9a46da07c424c3505408 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObserver_update, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, subject, SplSubject, 0) @@ -185,9 +185,9 @@ static const zend_function_entry class_SplSubject_methods[] = { }; static const zend_function_entry class_SplObjectStorage_methods[] = { - ZEND_ME(SplObjectStorage, attach, arginfo_class_SplObjectStorage_attach, ZEND_ACC_PUBLIC) - ZEND_ME(SplObjectStorage, detach, arginfo_class_SplObjectStorage_detach, ZEND_ACC_PUBLIC) - ZEND_ME(SplObjectStorage, contains, arginfo_class_SplObjectStorage_contains, ZEND_ACC_PUBLIC) + ZEND_ME(SplObjectStorage, attach, arginfo_class_SplObjectStorage_attach, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) + ZEND_ME(SplObjectStorage, detach, arginfo_class_SplObjectStorage_detach, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) + ZEND_ME(SplObjectStorage, contains, arginfo_class_SplObjectStorage_contains, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED) ZEND_ME(SplObjectStorage, addAll, arginfo_class_SplObjectStorage_addAll, ZEND_ACC_PUBLIC) ZEND_ME(SplObjectStorage, removeAll, arginfo_class_SplObjectStorage_removeAll, ZEND_ACC_PUBLIC) ZEND_ME(SplObjectStorage, removeAllExcept, arginfo_class_SplObjectStorage_removeAllExcept, ZEND_ACC_PUBLIC) @@ -258,6 +258,28 @@ static zend_class_entry *register_class_SplObjectStorage(zend_class_entry *class class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0); zend_class_implements(class_entry, 4, class_entry_Countable, class_entry_SeekableIterator, class_entry_Serializable, class_entry_ArrayAccess); + + zend_attribute *attribute_Deprecated_func_attach_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "attach", sizeof("attach") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_attach_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_attach_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_attach_0_arg1_str = zend_string_init("use method SplObjectStorage::offsetSet() instead", strlen("use method SplObjectStorage::offsetSet() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_attach_0->args[1].value, attribute_Deprecated_func_attach_0_arg1_str); + attribute_Deprecated_func_attach_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_detach_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "detach", sizeof("detach") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_detach_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_detach_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_detach_0_arg1_str = zend_string_init("use method SplObjectStorage::offsetUnset() instead", strlen("use method SplObjectStorage::offsetUnset() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_detach_0->args[1].value, attribute_Deprecated_func_detach_0_arg1_str); + attribute_Deprecated_func_detach_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_func_contains_0 = zend_add_function_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "contains", sizeof("contains") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_contains_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_contains_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_contains_0_arg1_str = zend_string_init("use method SplObjectStorage::offsetExists() instead", strlen("use method SplObjectStorage::offsetExists() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_contains_0->args[1].value, attribute_Deprecated_func_contains_0_arg1_str); + attribute_Deprecated_func_contains_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + return class_entry; } @@ -271,27 +293,27 @@ static zend_class_entry *register_class_MultipleIterator(zend_class_entry *class zval const_MIT_NEED_ANY_value; ZVAL_LONG(&const_MIT_NEED_ANY_value, MIT_NEED_ANY); - zend_string *const_MIT_NEED_ANY_name = zend_string_init_interned("MIT_NEED_ANY", sizeof("MIT_NEED_ANY") - 1, 1); + zend_string *const_MIT_NEED_ANY_name = zend_string_init_interned("MIT_NEED_ANY", sizeof("MIT_NEED_ANY") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIT_NEED_ANY_name, &const_MIT_NEED_ANY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIT_NEED_ANY_name); + zend_string_release_ex(const_MIT_NEED_ANY_name, true); zval const_MIT_NEED_ALL_value; ZVAL_LONG(&const_MIT_NEED_ALL_value, MIT_NEED_ALL); - zend_string *const_MIT_NEED_ALL_name = zend_string_init_interned("MIT_NEED_ALL", sizeof("MIT_NEED_ALL") - 1, 1); + zend_string *const_MIT_NEED_ALL_name = zend_string_init_interned("MIT_NEED_ALL", sizeof("MIT_NEED_ALL") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIT_NEED_ALL_name, &const_MIT_NEED_ALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIT_NEED_ALL_name); + zend_string_release_ex(const_MIT_NEED_ALL_name, true); zval const_MIT_KEYS_NUMERIC_value; ZVAL_LONG(&const_MIT_KEYS_NUMERIC_value, MIT_KEYS_NUMERIC); - zend_string *const_MIT_KEYS_NUMERIC_name = zend_string_init_interned("MIT_KEYS_NUMERIC", sizeof("MIT_KEYS_NUMERIC") - 1, 1); + zend_string *const_MIT_KEYS_NUMERIC_name = zend_string_init_interned("MIT_KEYS_NUMERIC", sizeof("MIT_KEYS_NUMERIC") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIT_KEYS_NUMERIC_name, &const_MIT_KEYS_NUMERIC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIT_KEYS_NUMERIC_name); + zend_string_release_ex(const_MIT_KEYS_NUMERIC_name, true); zval const_MIT_KEYS_ASSOC_value; ZVAL_LONG(&const_MIT_KEYS_ASSOC_value, MIT_KEYS_ASSOC); - zend_string *const_MIT_KEYS_ASSOC_name = zend_string_init_interned("MIT_KEYS_ASSOC", sizeof("MIT_KEYS_ASSOC") - 1, 1); + zend_string *const_MIT_KEYS_ASSOC_name = zend_string_init_interned("MIT_KEYS_ASSOC", sizeof("MIT_KEYS_ASSOC") - 1, true); zend_declare_typed_class_constant(class_entry, const_MIT_KEYS_ASSOC_name, &const_MIT_KEYS_ASSOC_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_MIT_KEYS_ASSOC_name); + zend_string_release_ex(const_MIT_KEYS_ASSOC_name, true); return class_entry; } diff --git a/ext/spl/tests/ArrayObject__serialize_saves_iterator_class.phpt b/ext/spl/tests/ArrayObject/ArrayObject__serialize_saves_iterator_class.phpt similarity index 100% rename from ext/spl/tests/ArrayObject__serialize_saves_iterator_class.phpt rename to ext/spl/tests/ArrayObject/ArrayObject__serialize_saves_iterator_class.phpt diff --git a/ext/spl/tests/ArrayObject/ArrayObject_clone_other_std_props.phpt b/ext/spl/tests/ArrayObject/ArrayObject_clone_other_std_props.phpt new file mode 100644 index 000000000000..f527f5b66458 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_clone_other_std_props.phpt @@ -0,0 +1,24 @@ +--TEST-- +Clone ArrayObject using other with STD_PROP_LIST +--FILE-- + +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(ArrayObject)#3 (1) { + ["storage":"ArrayObject":private]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} diff --git a/ext/spl/tests/ArrayObject_dump_during_sort.phpt b/ext/spl/tests/ArrayObject/ArrayObject_dump_during_sort.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_dump_during_sort.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_dump_during_sort.phpt diff --git a/ext/spl/tests/ArrayObject/ArrayObject_enum.phpt b/ext/spl/tests/ArrayObject/ArrayObject_enum.phpt new file mode 100644 index 000000000000..a88da8fc5539 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_enum.phpt @@ -0,0 +1,17 @@ +--TEST-- +Enums are not compatible with ArrayObject +--FILE-- + +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Fatal error: Uncaught InvalidArgumentException: Enums are not compatible with ArrayObject in %s:%d +%a diff --git a/ext/spl/tests/ArrayObject_exchange_array_during_sorting.phpt b/ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_exchange_array_during_sorting.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt diff --git a/ext/spl/tests/ArrayObject/ArrayObject_get_object_vars.phpt b/ext/spl/tests/ArrayObject/ArrayObject_get_object_vars.phpt new file mode 100644 index 000000000000..2e6b3d27f156 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_get_object_vars.phpt @@ -0,0 +1,31 @@ +--TEST-- +get_object_vars() on ArrayObject works on the properties of the ArrayObject itself +--FILE-- +getObjectVars()); + +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +array(0) { +} +array(1) { + ["test"]=> + NULL +} diff --git a/ext/spl/tests/ArrayObject_illegal_offset.phpt b/ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_illegal_offset.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt diff --git a/ext/spl/tests/ArrayObject/ArrayObject_modify_shared_object_properties.phpt b/ext/spl/tests/ArrayObject/ArrayObject_modify_shared_object_properties.phpt new file mode 100644 index 000000000000..69424204456b --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_modify_shared_object_properties.phpt @@ -0,0 +1,20 @@ +--TEST-- +Modifications to ArrayObjects should not affect shared properties tables +--FILE-- + 1, 'b' => 2]; +$ao = new ArrayObject($obj); +$arr = (array) $obj; +$ao['a'] = 42; +var_dump($arr); + +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +array(2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} diff --git a/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt new file mode 100644 index 000000000000..13065b4ac38a --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt @@ -0,0 +1,17 @@ +--TEST-- +SplFixedArray properties is incompatible with ArrayObject +--FILE-- +exchangeArray($fixedArray); +} catch (InvalidArgumentException $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +Overloaded object of type SplFixedArray is not compatible with ArrayObject diff --git a/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt new file mode 100644 index 000000000000..8cc66facc005 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt @@ -0,0 +1,28 @@ +--TEST-- +Objects with overloaded get_properties are incompatible with ArrayObject +--FILE-- +exchangeArray(new DateInterval('P1D')); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} +var_dump($ao); + +?> +--EXPECTF-- +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +Overloaded object of type DateInterval is not compatible with ArrayObject +object(ArrayObject)#1 (1) { + ["storage":"ArrayObject":private]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} diff --git a/ext/spl/tests/ArrayObject/ArrayObject_proptable_canonicalization.phpt b/ext/spl/tests/ArrayObject/ArrayObject_proptable_canonicalization.phpt new file mode 100644 index 000000000000..fd10797f72b0 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_proptable_canonicalization.phpt @@ -0,0 +1,34 @@ +--TEST-- +When ArrayObject wraps an object, we should use prop table canonicalization +--FILE-- + +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(stdClass)#1 (1) { + ["0"]=> + int(1) +} +object(stdClass)#1 (1) { + ["0"]=> + int(2) +} +bool(true) +array(1) { + [0]=> + int(2) +} +object(stdClass)#1 (0) { +} diff --git a/ext/spl/tests/ArrayObject/ArrayObject_sort_different_backing_storage.phpt b/ext/spl/tests/ArrayObject/ArrayObject_sort_different_backing_storage.phpt new file mode 100644 index 000000000000..34ecc1018c06 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_sort_different_backing_storage.phpt @@ -0,0 +1,81 @@ +--TEST-- +Test sorting of various ArrayObject backing storage +--FILE-- + 2, 'b' => 1]; +$ao = new ArrayObject($obj); +$ao->uasort(function($a, $b) { return $a <=> $b; }); +var_dump($ao); + +$ao2 = new ArrayObject($ao); +$ao2->uasort(function($a, $b) { return $b <=> $a; }); +var_dump($ao2); + +$ao3 = new ArrayObject(); +$ao3->exchangeArray($ao3); +$ao3->a = 2; +$ao3->b = 1; +$ao3->uasort(function($a, $b) { return $a <=> $b; }); +var_dump($ao3); + +$ao4 = new ArrayObject([]); +$ao4->uasort(function($a, $b) { return $a <=> $b; }); +var_dump($ao4); + +$ao5 = new ArrayObject(['a' => 2, 'b' => 1]); +$ao5->uasort(function($a, $b) { return $a <=> $b; }); +var_dump($ao5); + +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + object(stdClass)#1 (2) { + ["b"]=> + int(1) + ["a"]=> + int(2) + } +} + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(ArrayObject)#3 (1) { + ["storage":"ArrayObject":private]=> + object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + object(stdClass)#1 (2) { + ["a"]=> + int(2) + ["b"]=> + int(1) + } + } +} + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: Creation of dynamic property ArrayObject::$a is deprecated in %s on line %d + +Deprecated: Creation of dynamic property ArrayObject::$b is deprecated in %s on line %d +object(ArrayObject)#4 (2) { + ["b"]=> + int(1) + ["a"]=> + int(2) +} +object(ArrayObject)#5 (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } +} +object(ArrayObject)#6 (1) { + ["storage":"ArrayObject":private]=> + array(2) { + ["b"]=> + int(1) + ["a"]=> + int(2) + } +} diff --git a/ext/spl/tests/ArrayObject/ArrayObject_std_props_no_recursion.phpt b/ext/spl/tests/ArrayObject/ArrayObject_std_props_no_recursion.phpt new file mode 100644 index 000000000000..56f54844580d --- /dev/null +++ b/ext/spl/tests/ArrayObject/ArrayObject_std_props_no_recursion.phpt @@ -0,0 +1,37 @@ +--TEST-- +Don't recurse into USE_OTHER when checking for STD_PROP_LIST +--FILE-- +prop = 'a'; +$b = new ArrayObject($a, 0); +$b->prop = 'b'; +var_dump((array) $b); +$c = new ArrayObject($a); +$c->prop = 'c'; +var_dump((array) $c); + +?> +--EXPECTF-- +Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d +array(1) { + ["prop"]=> + string(1) "c" +} diff --git a/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt b/ext/spl/tests/ArrayObject/ArrayObject_unserialize_empty_string.phpt similarity index 100% rename from ext/spl/tests/ArrayObject_unserialize_empty_string.phpt rename to ext/spl/tests/ArrayObject/ArrayObject_unserialize_empty_string.phpt diff --git a/ext/spl/tests/arrayIterator_ksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayIterator_ksort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayIterator_ksort_basic1.phpt diff --git a/ext/spl/tests/ArrayObject/arrayObject___construct_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic1.phpt new file mode 100644 index 000000000000..744a936276bd --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic1.phpt @@ -0,0 +1,58 @@ +--TEST-- +SPL: ArrayObject::__construct basic usage. +--FILE-- + No arguments:\n"; +var_dump(new ArrayObject()); + +echo "--> Object argument:\n"; +$a = new stdClass; +$a->p = 'hello'; +var_dump(new ArrayObject($a)); + +echo "--> Array argument:\n"; +var_dump(new ArrayObject(array('key1' => 'val1'))); + +echo "--> Nested ArrayObject argument:\n"; +var_dump(new ArrayObject(new ArrayObject($a))); +?> +--EXPECTF-- +--> No arguments: +object(ArrayObject)#1 (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } +} +--> Object argument: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + object(stdClass)#1 (1) { + ["p"]=> + string(5) "hello" + } +} +--> Array argument: +object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + array(1) { + ["key1"]=> + string(4) "val1" + } +} +--> Nested ArrayObject argument: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + object(ArrayObject)#3 (1) { + ["storage":"ArrayObject":private]=> + object(stdClass)#1 (1) { + ["p"]=> + string(5) "hello" + } + } +} diff --git a/ext/spl/tests/arrayObject___construct_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic2.phpt similarity index 85% rename from ext/spl/tests/arrayObject___construct_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic2.phpt index 0d993a14e786..e1d9718b4e62 100644 --- a/ext/spl/tests/arrayObject___construct_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic2.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -78,6 +80,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic3.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic3.phpt similarity index 86% rename from ext/spl/tests/arrayObject___construct_basic3.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic3.phpt index 3fb4dda5a6e9..135d87e6a843 100644 --- a/ext/spl/tests/arrayObject___construct_basic3.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic3.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -78,6 +80,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic4.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic4.phpt similarity index 86% rename from ext/spl/tests/arrayObject___construct_basic4.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic4.phpt index dd8e75af9318..2aeed29178a0 100644 --- a/ext/spl/tests/arrayObject___construct_basic4.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic4.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -76,6 +78,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject with ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic5.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic5.phpt similarity index 87% rename from ext/spl/tests/arrayObject___construct_basic5.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic5.phpt index e10dcd8a8d01..125f55d06371 100644 --- a/ext/spl/tests/arrayObject___construct_basic5.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic5.phpt @@ -48,6 +48,8 @@ function testAccess($c, $ao) { ?> --EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: @@ -76,6 +78,8 @@ object(C)#1 (0) { } --> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d - Iteration: prop=>C::prop.orig - Read: diff --git a/ext/spl/tests/arrayObject___construct_basic6.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic6.phpt similarity index 100% rename from ext/spl/tests/arrayObject___construct_basic6.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_basic6.phpt diff --git a/ext/spl/tests/ArrayObject/arrayObject___construct_basic7.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_basic7.phpt new file mode 100644 index 000000000000..98131c8c6b4d --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject___construct_basic7.phpt @@ -0,0 +1,35 @@ +--TEST-- +SPL: ArrayObject::__construct: Using object with shared properties +--FILE-- +asort(); +var_dump($a, $o, $ao); +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +array(2) { + [0]=> + int(2) + [1]=> + int(1) +} +object(stdClass)#1 (2) { + ["1"]=> + int(1) + ["0"]=> + int(2) +} +object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + object(stdClass)#1 (2) { + ["1"]=> + int(1) + ["0"]=> + int(2) + } +} diff --git a/ext/spl/tests/arrayObject___construct_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject___construct_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt diff --git a/ext/spl/tests/arrayObject___construct_error2.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt similarity index 100% rename from ext/spl/tests/arrayObject___construct_error2.phpt rename to ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt diff --git a/ext/spl/tests/arrayObject_asort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_asort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_asort_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_asort_basic2.phpt similarity index 83% rename from ext/spl/tests/arrayObject_asort_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_asort_basic2.phpt index 21f0dee95007..772b370ad677 100644 --- a/ext/spl/tests/arrayObject_asort_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_asort_basic2.phpt @@ -20,8 +20,10 @@ $ao1 = new ArrayObject($c); var_dump($ao1->asort()); var_dump($ao1, $c); ?> ---EXPECT-- +--EXPECTF-- *** Testing ArrayObject::asort() : basic functionality *** + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d bool(true) object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject_clone_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_clone_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_clone_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_clone_basic1.phpt diff --git a/ext/spl/tests/arrayObject_clone_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_clone_basic2.phpt similarity index 84% rename from ext/spl/tests/arrayObject_clone_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_clone_basic2.phpt index b0a82ccfbc34..9cca59b60a9b 100644 --- a/ext/spl/tests/arrayObject_clone_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_clone_basic2.phpt @@ -17,7 +17,8 @@ $ao1['new.ao1'] = 'new element added to ao1'; $ao2['new.ao2'] = 'new element added to ao2'; var_dump($c, $ao1, $ao2); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(C)#1 (3) { ["p1"]=> string(32) "new prop added to c before clone" diff --git a/ext/spl/tests/arrayObject_clone_basic3.phpt b/ext/spl/tests/ArrayObject/arrayObject_clone_basic3.phpt similarity index 86% rename from ext/spl/tests/arrayObject_clone_basic3.phpt rename to ext/spl/tests/ArrayObject/arrayObject_clone_basic3.phpt index 214a2b87b869..26e633bdd06a 100644 --- a/ext/spl/tests/arrayObject_clone_basic3.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_clone_basic3.phpt @@ -23,7 +23,10 @@ $clonedOuterArrayObject['new.coAO'] = 'new element added to $clonedOuterArrayObj var_dump($wrappedObject, $innerArrayObject, $outerArrayObject, $clonedOuterArrayObject); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(C)#1 (5) { ["p"]=> string(9) "C::p.orig" diff --git a/ext/spl/tests/arrayObject_count_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_count_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_count_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_count_basic1.phpt diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_exchangeArray_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic1.phpt diff --git a/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt new file mode 100644 index 000000000000..4ba09cd388f2 --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt @@ -0,0 +1,107 @@ +--TEST-- +SPL: ArrayObject::exchangeArray() with various object arguments +--FILE-- + exchangeArray(array):\n"; +$ao = new ArrayObject(); +$ao->exchangeArray(array('key'=>'original')); +var_dump($ao['key']); +var_dump($ao); + +echo "\n--> exchangeArray(normal object):\n"; +$obj = new stdClass; +$obj->key = 'normal object prop'; +$ao->exchangeArray($obj); +var_dump($ao['key']); +var_dump($ao); + +echo "\n--> exchangeArray(ArrayObject):\n"; +$obj = new ArrayObject(array('key'=>'ArrayObject element')); +$ao->exchangeArray($obj); +var_dump($ao['key']); +var_dump($ao); + +echo "\n--> exchangeArray(ArrayIterator):\n"; +$obj = new ArrayIterator(array('key'=>'ArrayIterator element')); +$ao->exchangeArray($obj); +var_dump($ao['key']); +var_dump($ao); + +echo "\n--> exchangeArray(nested ArrayObject):\n"; +$obj = new ArrayObject(new ArrayObject(array('key'=>'nested ArrayObject element'))); +$ao->exchangeArray($obj); +var_dump($ao['key']); +var_dump($ao); +?> +--EXPECTF-- +--> exchangeArray(array): +string(8) "original" +object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + array(1) { + ["key"]=> + string(8) "original" + } +} + +--> exchangeArray(normal object): + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +string(18) "normal object prop" +object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + object(stdClass)#%d (1) { + ["key"]=> + string(18) "normal object prop" + } +} + +--> exchangeArray(ArrayObject): + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +string(19) "ArrayObject element" +object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + array(1) { + ["key"]=> + string(19) "ArrayObject element" + } + } +} + +--> exchangeArray(ArrayIterator): + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +string(21) "ArrayIterator element" +object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + object(ArrayIterator)#%d (1) { + ["storage":"ArrayIterator":private]=> + array(1) { + ["key"]=> + string(21) "ArrayIterator element" + } + } +} + +--> exchangeArray(nested ArrayObject): + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +string(26) "nested ArrayObject element" +object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + array(1) { + ["key"]=> + string(26) "nested ArrayObject element" + } + } + } +} \ No newline at end of file diff --git a/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt new file mode 100644 index 000000000000..8db9b016fda8 --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt @@ -0,0 +1,141 @@ +--TEST-- +SPL: ArrayObject::exchangeArray() basic usage with object as underlying data store. +--FILE-- + exchangeArray() with objects:\n"; +$original = new C; +$ao = new ArrayObject($original); +$swapIn = new C; +try { + $copy = $ao->exchangeArray($swapIn); + $copy['addedToCopy'] = 'added To Copy'; +} catch (Exception $e) { + echo "Exception:" . $e->getMessage() . "\n"; +} +$swapIn->addedToSwapIn = 'added To Swap-In'; +$original->addedToOriginal = 'added To Original'; +var_dump($ao, $original, $swapIn, $copy); + + +echo "\n\n--> exchangeArray() with no arg:\n"; +unset($original, $ao, $swapIn, $copy); +$original = new C; +$ao = new ArrayObject($original); +try { + $copy = $ao->exchangeArray(); + $copy['addedToCopy'] = 'added To Copy'; +} catch (TypeError $e) { + echo "Exception: " . $e->getMessage() . "\n"; +} +$original->addedToOriginal = 'added To Original'; +var_dump($ao, $original, $copy); + +echo "\n\n--> exchangeArray() with bad arg type:\n"; +unset($original, $ao, $swapIn, $copy); +$original = new C; +$ao = new ArrayObject($original); +try { + $copy = $ao->exchangeArray(null); + $copy['addedToCopy'] = 'added To Copy'; +} catch (TypeError $e) { + echo $e->getMessage() . "\n"; +} +$original->addedToOriginal = 'added To Original'; +var_dump($ao, $original, $copy); + +?> +--EXPECTF-- +--> exchangeArray() with objects: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: Creation of dynamic property C::$addedToSwapIn is deprecated in %s on line %d + +Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d +object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + object(C)#3 (2) { + ["pub1"]=> + string(7) "public1" + ["addedToSwapIn"]=> + string(16) "added To Swap-In" + } +} +object(C)#1 (2) { + ["pub1"]=> + string(7) "public1" + ["addedToOriginal"]=> + string(17) "added To Original" +} +object(C)#3 (2) { + ["pub1"]=> + string(7) "public1" + ["addedToSwapIn"]=> + string(16) "added To Swap-In" +} +array(2) { + ["pub1"]=> + string(7) "public1" + ["addedToCopy"]=> + string(13) "added To Copy" +} + + +--> exchangeArray() with no arg: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +Exception: ArrayObject::exchangeArray() expects exactly 1 argument, 0 given + +Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d + +Warning: Undefined variable $copy in %s on line %d +object(ArrayObject)#2 (1) { + ["storage":"ArrayObject":private]=> + object(C)#3 (2) { + ["pub1"]=> + string(7) "public1" + ["addedToOriginal"]=> + string(17) "added To Original" + } +} +object(C)#3 (2) { + ["pub1"]=> + string(7) "public1" + ["addedToOriginal"]=> + string(17) "added To Original" +} +NULL + + +--> exchangeArray() with bad arg type: + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +ArrayObject::exchangeArray(): Argument #1 ($array) must be of type array, null given + +Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d + +Warning: Undefined variable $copy in %s on line %d +object(ArrayObject)#3 (1) { + ["storage":"ArrayObject":private]=> + object(C)#2 (2) { + ["pub1"]=> + string(7) "public1" + ["addedToOriginal"]=> + string(17) "added To Original" + } +} +object(C)#2 (2) { + ["pub1"]=> + string(7) "public1" + ["addedToOriginal"]=> + string(17) "added To Original" +} +NULL diff --git a/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic1.phpt new file mode 100644 index 000000000000..35ae39862111 --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic1.phpt @@ -0,0 +1,36 @@ +--TEST-- +SPL: ArrayObject::getFlags() basic usage +--FILE-- +getFlags()); + +$ao = new ArrayObject(new ArrayObject(array(1,2,3)), ArrayObject::STD_PROP_LIST); +var_dump($ao->getFlags()); + +$ao = new ArrayObject(new ArrayIterator(new ArrayObject()), ArrayObject::ARRAY_AS_PROPS); +var_dump($ao->getFlags()); + +$ao = new ArrayObject(new ArrayObject(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); +var_dump($ao->getFlags()); + +$cao = clone $ao; +var_dump($cao->getFlags()); +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(0) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(1) + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(2) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(3) +int(3) diff --git a/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt new file mode 100644 index 000000000000..0d0111edd1ec --- /dev/null +++ b/ext/spl/tests/ArrayObject/arrayObject_getFlags_basic2.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: ArrayObject::getFlags() - ensure flags are passed on to nested array objects and iterators. +--FILE-- +getFlags()); + +$ao2 = new ArrayObject($ao); +var_dump($ao2->getFlags()); +var_dump($ao2->getIterator()->getFlags()); + +$ai = new ArrayIterator($ao); +var_dump($ai->getFlags()); + +$ao2 = new ArrayObject($ao, 0); +var_dump($ao2->getFlags()); + +?> +--EXPECTF-- +int(3) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(3) +int(3) + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(3) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(0) diff --git a/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_getIteratorClass_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_getIteratorClass_basic1.phpt diff --git a/ext/spl/tests/arrayObject_ksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_ksort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_ksort_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic2.phpt similarity index 82% rename from ext/spl/tests/arrayObject_ksort_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_ksort_basic2.phpt index 1ac3029543d8..6e64a1c64f0d 100644 --- a/ext/spl/tests/arrayObject_ksort_basic2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic2.phpt @@ -20,8 +20,10 @@ $ao1 = new ArrayObject($c); var_dump($ao1->ksort()); var_dump($ao1, $c); ?> ---EXPECT-- +--EXPECTF-- *** Testing ArrayObject::ksort() : basic functionality *** + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d bool(true) object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject_magicMethods1.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods1.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods1.phpt index ce29beb7177f..7acf8787d4ab 100644 --- a/ext/spl/tests/arrayObject_magicMethods1.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods1.phpt @@ -68,6 +68,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(UsesMagic)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods2.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods2.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods2.phpt index d28c234d54f9..da3cb624b9b5 100644 --- a/ext/spl/tests/arrayObject_magicMethods2.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods2.phpt @@ -68,6 +68,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Deprecated: Creation of dynamic property ArrayObject::$a is deprecated in %s on line %d diff --git a/ext/spl/tests/arrayObject_magicMethods3.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods3.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods3.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods3.phpt index 2ff0531e01d4..04ecfde195e7 100644 --- a/ext/spl/tests/arrayObject_magicMethods3.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods3.phpt @@ -68,6 +68,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(UsesMagic)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods4.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods4.phpt similarity index 96% rename from ext/spl/tests/arrayObject_magicMethods4.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods4.phpt index e68ef1fc4777..a4dabb86ec7c 100644 --- a/ext/spl/tests/arrayObject_magicMethods4.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods4.phpt @@ -71,6 +71,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(C)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods5.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods5.phpt similarity index 95% rename from ext/spl/tests/arrayObject_magicMethods5.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods5.phpt index c0393ffea48f..569d9c0bb543 100644 --- a/ext/spl/tests/arrayObject_magicMethods5.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods5.phpt @@ -70,7 +70,9 @@ var_dump($obj); echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: In UsesMagic::__set(a,changed) In UsesMagic::__set(dynamic,new) diff --git a/ext/spl/tests/arrayObject_magicMethods6.phpt b/ext/spl/tests/ArrayObject/arrayObject_magicMethods6.phpt similarity index 96% rename from ext/spl/tests/arrayObject_magicMethods6.phpt rename to ext/spl/tests/ArrayObject/arrayObject_magicMethods6.phpt index 75151902210f..ae4379c09094 100644 --- a/ext/spl/tests/arrayObject_magicMethods6.phpt +++ b/ext/spl/tests/ArrayObject/arrayObject_magicMethods6.phpt @@ -71,6 +71,8 @@ echo " Wrapping ArrayObject:\n"; var_dump($ao); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + --> Write existent, non-existent and dynamic: Original wrapped object: object(C)#1 (5) { diff --git a/ext/spl/tests/arrayObject_natcasesort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_natcasesort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_natsort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_natsort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_offsetExists_nullcheck.phpt b/ext/spl/tests/ArrayObject/arrayObject_offsetExists_nullcheck.phpt similarity index 100% rename from ext/spl/tests/arrayObject_offsetExists_nullcheck.phpt rename to ext/spl/tests/ArrayObject/arrayObject_offsetExists_nullcheck.phpt diff --git a/ext/spl/tests/arrayObject_setFlags_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_setFlags_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_setFlags_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_setFlags_basic1.phpt diff --git a/ext/spl/tests/arrayObject_setFlags_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_setFlags_basic2.phpt similarity index 100% rename from ext/spl/tests/arrayObject_setFlags_basic2.phpt rename to ext/spl/tests/ArrayObject/arrayObject_setFlags_basic2.phpt diff --git a/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_setIteratorClass_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt diff --git a/ext/spl/tests/arrayObject_uasort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uasort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uasort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uasort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_uasort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uasort_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uasort_error1.phpt diff --git a/ext/spl/tests/arrayObject_uksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uksort_basic1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uksort_basic1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uksort_basic1.phpt diff --git a/ext/spl/tests/arrayObject_uksort_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt similarity index 100% rename from ext/spl/tests/arrayObject_uksort_error1.phpt rename to ext/spl/tests/ArrayObject/arrayObject_uksort_error1.phpt diff --git a/ext/spl/tests/array_001.phpt b/ext/spl/tests/ArrayObject/array_001.phpt similarity index 100% rename from ext/spl/tests/array_001.phpt rename to ext/spl/tests/ArrayObject/array_001.phpt diff --git a/ext/spl/tests/array_002.phpt b/ext/spl/tests/ArrayObject/array_002.phpt similarity index 78% rename from ext/spl/tests/array_002.phpt rename to ext/spl/tests/ArrayObject/array_002.phpt index 94559f5bf755..a305770edf90 100644 --- a/ext/spl/tests/array_002.phpt +++ b/ext/spl/tests/ArrayObject/array_002.phpt @@ -18,6 +18,7 @@ var_dump($arrayObject); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> object(ArrayObject)#1 (1) { diff --git a/ext/spl/tests/array_003.phpt b/ext/spl/tests/ArrayObject/array_003.phpt similarity index 84% rename from ext/spl/tests/array_003.phpt rename to ext/spl/tests/ArrayObject/array_003.phpt index 3ca23f09dc7c..38db05625049 100644 --- a/ext/spl/tests/array_003.phpt +++ b/ext/spl/tests/ArrayObject/array_003.phpt @@ -35,7 +35,7 @@ foreach($test as $key => $val) } ?> ---EXPECT-- +--EXPECTF-- test Object ( [pub] => public @@ -44,6 +44,8 @@ test Object [imp] => implicit [dyn] => dynamic ) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayObject Object ( [storage:ArrayObject:private] => test Object diff --git a/ext/spl/tests/array_004.phpt b/ext/spl/tests/ArrayObject/array_004.phpt similarity index 100% rename from ext/spl/tests/array_004.phpt rename to ext/spl/tests/ArrayObject/array_004.phpt diff --git a/ext/spl/tests/array_005.phpt b/ext/spl/tests/ArrayObject/array_005.phpt similarity index 100% rename from ext/spl/tests/array_005.phpt rename to ext/spl/tests/ArrayObject/array_005.phpt diff --git a/ext/spl/tests/array_006.phpt b/ext/spl/tests/ArrayObject/array_006.phpt similarity index 100% rename from ext/spl/tests/array_006.phpt rename to ext/spl/tests/ArrayObject/array_006.phpt diff --git a/ext/spl/tests/array_007.phpt b/ext/spl/tests/ArrayObject/array_007.phpt similarity index 78% rename from ext/spl/tests/array_007.phpt rename to ext/spl/tests/ArrayObject/array_007.phpt index 3cdd40a1dbc7..de492257c65f 100644 --- a/ext/spl/tests/array_007.phpt +++ b/ext/spl/tests/ArrayObject/array_007.phpt @@ -39,7 +39,7 @@ foreach($test as $key => $val) } ?> ---EXPECT-- +--EXPECTF-- test Object ( [pub] => public @@ -48,6 +48,8 @@ test Object [imp] => implicit [dyn] => dynamic ) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIterator Object ( [storage:ArrayIterator:private] => ArrayObject Object @@ -64,6 +66,8 @@ ArrayIterator Object ) ) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d pub => public imp => implicit dyn => dynamic diff --git a/ext/spl/tests/array_008.phpt b/ext/spl/tests/ArrayObject/array_008.phpt similarity index 100% rename from ext/spl/tests/array_008.phpt rename to ext/spl/tests/ArrayObject/array_008.phpt diff --git a/ext/spl/tests/array_009.phpt b/ext/spl/tests/ArrayObject/array_009.phpt similarity index 100% rename from ext/spl/tests/array_009.phpt rename to ext/spl/tests/ArrayObject/array_009.phpt diff --git a/ext/spl/tests/array_009a.phpt b/ext/spl/tests/ArrayObject/array_009a.phpt similarity index 100% rename from ext/spl/tests/array_009a.phpt rename to ext/spl/tests/ArrayObject/array_009a.phpt diff --git a/ext/spl/tests/array_010.phpt b/ext/spl/tests/ArrayObject/array_010.phpt similarity index 100% rename from ext/spl/tests/array_010.phpt rename to ext/spl/tests/ArrayObject/array_010.phpt diff --git a/ext/spl/tests/array_011.phpt b/ext/spl/tests/ArrayObject/array_011.phpt similarity index 100% rename from ext/spl/tests/array_011.phpt rename to ext/spl/tests/ArrayObject/array_011.phpt diff --git a/ext/spl/tests/array_012.phpt b/ext/spl/tests/ArrayObject/array_012.phpt similarity index 79% rename from ext/spl/tests/array_012.phpt rename to ext/spl/tests/ArrayObject/array_012.phpt index 5d5993d93694..f3b0fa9813b0 100644 --- a/ext/spl/tests/array_012.phpt +++ b/ext/spl/tests/ArrayObject/array_012.phpt @@ -39,7 +39,7 @@ foreach($it as $key => $val) var_dump($it->count()); ?> ---EXPECT-- +--EXPECTF-- ===Array=== int(3) zero=>0 @@ -50,6 +50,8 @@ two=>2 int(3) int(3) ===Object=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d int(3) zero=>0 int(3) diff --git a/ext/spl/tests/array_013.phpt b/ext/spl/tests/ArrayObject/array_013.phpt similarity index 87% rename from ext/spl/tests/array_013.phpt rename to ext/spl/tests/ArrayObject/array_013.phpt index 9ad11c8f38c7..01097bac04dc 100644 --- a/ext/spl/tests/array_013.phpt +++ b/ext/spl/tests/ArrayObject/array_013.phpt @@ -70,6 +70,8 @@ var_dump($o->{0}); /* doesn't wotk anyway */ 3=>three 4=>four ===Object=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d zero=>0 one=>1 two=>2 diff --git a/ext/spl/tests/array_014.phpt b/ext/spl/tests/ArrayObject/array_014.phpt similarity index 100% rename from ext/spl/tests/array_014.phpt rename to ext/spl/tests/ArrayObject/array_014.phpt diff --git a/ext/spl/tests/array_015.phpt b/ext/spl/tests/ArrayObject/array_015.phpt similarity index 100% rename from ext/spl/tests/array_015.phpt rename to ext/spl/tests/ArrayObject/array_015.phpt diff --git a/ext/spl/tests/array_016.phpt b/ext/spl/tests/ArrayObject/array_016.phpt similarity index 100% rename from ext/spl/tests/array_016.phpt rename to ext/spl/tests/ArrayObject/array_016.phpt diff --git a/ext/spl/tests/array_017.phpt b/ext/spl/tests/ArrayObject/array_017.phpt similarity index 88% rename from ext/spl/tests/array_017.phpt rename to ext/spl/tests/ArrayObject/array_017.phpt index ba4842dce20c..2a80386b6f73 100644 --- a/ext/spl/tests/array_017.phpt +++ b/ext/spl/tests/ArrayObject/array_017.phpt @@ -177,6 +177,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -245,6 +247,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -366,6 +370,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -434,6 +440,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -512,6 +520,8 @@ int(1) bool(true) #####EXCHANGE##### ArrayObjectEx::exchange() + +Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d ===CHECK=== ArrayObjectEx::setFlags(0) ArrayObjectEx::dump() @@ -548,6 +558,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -607,6 +619,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -710,6 +724,8 @@ array(3) { ArrayObjectEx::show() ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> @@ -769,6 +785,8 @@ array(1) { ===FOREACH=== ArrayObjectEx::getIterator() ArrayIteratorEx::__construct() + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d ArrayIteratorEx::dump() array(3) { ["Flags"]=> diff --git a/ext/spl/tests/array_018.phpt b/ext/spl/tests/ArrayObject/array_018.phpt similarity index 100% rename from ext/spl/tests/array_018.phpt rename to ext/spl/tests/ArrayObject/array_018.phpt diff --git a/ext/spl/tests/array_019.phpt b/ext/spl/tests/ArrayObject/array_019.phpt similarity index 100% rename from ext/spl/tests/array_019.phpt rename to ext/spl/tests/ArrayObject/array_019.phpt diff --git a/ext/spl/tests/array_020.phpt b/ext/spl/tests/ArrayObject/array_020.phpt similarity index 100% rename from ext/spl/tests/array_020.phpt rename to ext/spl/tests/ArrayObject/array_020.phpt diff --git a/ext/spl/tests/array_021.phpt b/ext/spl/tests/ArrayObject/array_021.phpt similarity index 100% rename from ext/spl/tests/array_021.phpt rename to ext/spl/tests/ArrayObject/array_021.phpt diff --git a/ext/spl/tests/ArrayObject/array_022.phpt b/ext/spl/tests/ArrayObject/array_022.phpt new file mode 100644 index 000000000000..4e8c94fd1181 --- /dev/null +++ b/ext/spl/tests/ArrayObject/array_022.phpt @@ -0,0 +1,72 @@ +--TEST-- +SPL: ArrayObject/Iterator and reference to self +--FILE-- +==ArrayObject=== + +==ArrayIterator=== + +--EXPECTF-- +==ArrayObject=== + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(MyArrayObject)#%d (1) { + ["bar"]=> + string(3) "baz" +} +object(MyArrayObject)#%d (2) { + ["bar"]=> + string(3) "baz" + ["baz"]=> + string(3) "Foo" +} +==ArrayIterator=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(MyArrayIterator)#%d (1) { + ["bar"]=> + string(3) "baz" +} +object(MyArrayIterator)#%d (2) { + ["bar"]=> + string(3) "baz" + ["baz"]=> + string(3) "Foo" +} diff --git a/ext/spl/tests/array_023.phpt b/ext/spl/tests/ArrayObject/array_023.phpt similarity index 100% rename from ext/spl/tests/array_023.phpt rename to ext/spl/tests/ArrayObject/array_023.phpt diff --git a/ext/spl/tests/array_024.phpt b/ext/spl/tests/ArrayObject/array_024.phpt similarity index 100% rename from ext/spl/tests/array_024.phpt rename to ext/spl/tests/ArrayObject/array_024.phpt diff --git a/ext/spl/tests/ArrayObject/array_025.phpt b/ext/spl/tests/ArrayObject/array_025.phpt new file mode 100644 index 000000000000..4bd4c434f480 --- /dev/null +++ b/ext/spl/tests/ArrayObject/array_025.phpt @@ -0,0 +1,43 @@ +--TEST-- +SPL: ArrayObject serialize with an object as storage +--FILE-- + +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayObject::__unserialize(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +ArrayObject Object +( + [storage:ArrayObject:private] => ArrayObject Object + ( + [storage:ArrayObject:private] => Array + ( + [0] => 1 + [1] => 2 + ) + + ) + +) +O:11:"ArrayObject":4:{i:0;i:0;i:1;O:11:"ArrayObject":4:{i:0;i:0;i:1;a:2:{i:0;i:1;i:1;i:2;}i:2;a:0:{}i:3;N;}i:2;a:0:{}i:3;N;} +ArrayObject Object +( + [storage:ArrayObject:private] => ArrayObject Object + ( + [storage:ArrayObject:private] => Array + ( + [0] => 1 + [1] => 2 + ) + + ) + +) diff --git a/ext/spl/tests/array_026.phpt b/ext/spl/tests/ArrayObject/array_026.phpt similarity index 100% rename from ext/spl/tests/array_026.phpt rename to ext/spl/tests/ArrayObject/array_026.phpt diff --git a/ext/spl/tests/array_027.phpt b/ext/spl/tests/ArrayObject/array_027.phpt similarity index 100% rename from ext/spl/tests/array_027.phpt rename to ext/spl/tests/ArrayObject/array_027.phpt diff --git a/ext/spl/tests/ArrayObject/array_028.phpt b/ext/spl/tests/ArrayObject/array_028.phpt new file mode 100644 index 000000000000..1e422fe2f990 --- /dev/null +++ b/ext/spl/tests/ArrayObject/array_028.phpt @@ -0,0 +1,29 @@ +--TEST-- +ArrayObject/Iterator on array with NUL bytes +--FILE-- + "bar", +]; + +$it = new ArrayIterator($array); +foreach ($it as $v) { + var_dump($v); +} + +$obj = new ArrayObject($array); +foreach ($obj as $v) { + var_dump($v); +} + +$obj = new ArrayObject($it); +foreach ($obj as $v) { + var_dump($v); +} +?> +--EXPECTF-- +string(3) "bar" +string(3) "bar" + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +string(3) "bar" diff --git a/ext/spl/tests/ArrayObject/asort_disabled.phpt b/ext/spl/tests/ArrayObject/asort_disabled.phpt new file mode 100644 index 000000000000..8f2241332f72 --- /dev/null +++ b/ext/spl/tests/ArrayObject/asort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function asort() is disabled +--INI-- +disable_functions=asort +--FILE-- +asort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method asort when function asort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->asort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/bug31346.phpt b/ext/spl/tests/ArrayObject/bug31346.phpt new file mode 100644 index 000000000000..a1088dfd013e --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug31346.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #31486 (ArrayIterator::next segfaults) +--FILE-- +var1=1; + +$ao = new ArrayObject($obj); + +$i = $ao->getIterator(); + +$ao->offsetUnset($i->key()); +$i->next(); + +?> +===DONE=== +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +===DONE=== diff --git a/ext/spl/tests/ArrayObject/bug38618.phpt b/ext/spl/tests/ArrayObject/bug38618.phpt new file mode 100644 index 000000000000..5a865f12d636 --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug38618.phpt @@ -0,0 +1,108 @@ +--TEST-- +Bug #38618 (RecursiveArrayIterator::hasChildren() follows objects) +--FILE-- +title = $title; + } + + public function __toString() + { + return $this->title; + } +} + +class FruitProtected +{ + protected $title; + + public function __construct($title) + { + $this->title = $title; + } + + public function __toString() + { + return $this->title; + } +} + +function test_array($array, $which, $flags = 0) +{ + echo "===$which===\n"; + $it = new RecursiveArrayIterator($array, $flags); + foreach (new RecursiveIteratorIterator($it) as $k => $fruit) { + echo $k , ' => ', $fruit, "\n"; + } +} + +$array = array( + 1 => array( + 1 => array( + 1 => 'apple', + ), + 2 => array( + 1 => 'grape', + ), + ), +); + +test_array($array, 'Default with array'); + +$array = array( + 1 => array( + 1 => array( + 1 => new FruitPublic('apple'), + ), + 2 => array( + 1 => new FruitPublic('grape'), + ), + ), +); + +test_array($array, 'Public Property'); + +$array = array( + 1 => array( + 1 => array( + 1 => new FruitProtected('apple'), + ), + 2 => array( + 1 => new FruitProtected('grape'), + ), + ), +); + +test_array($array, 'Protected Property'); + +test_array($array, 'Public Property New', RecursiveArrayIterator::CHILD_ARRAYS_ONLY); +test_array($array, 'Protected Property New', RecursiveArrayIterator::CHILD_ARRAYS_ONLY); +?> +--EXPECTF-- +===Default with array=== +1 => apple +1 => grape +===Public Property=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +title => apple + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +title => grape +===Protected Property=== + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +===Public Property New=== +1 => apple +1 => grape +===Protected Property New=== +1 => apple +1 => grape diff --git a/ext/spl/tests/ArrayObject/bug41691.phpt b/ext/spl/tests/ArrayObject/bug41691.phpt new file mode 100644 index 000000000000..c808d59c2022 --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug41691.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #41691 (ArrayObject::exchangeArray hangs Apache) +--FILE-- +exchangeArray(array('a'=>1,'b'=>1,'c'=>1))); + +echo "Done\n"; +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +array(3) { + ["a"]=> + NULL + ["b"]=> + NULL + ["c"]=> + NULL +} +Done diff --git a/ext/spl/tests/bug44615.phpt b/ext/spl/tests/ArrayObject/bug44615.phpt similarity index 76% rename from ext/spl/tests/bug44615.phpt rename to ext/spl/tests/ArrayObject/bug44615.phpt index 0b9aa82bc300..3ac30192170c 100644 --- a/ext/spl/tests/bug44615.phpt +++ b/ext/spl/tests/ArrayObject/bug44615.phpt @@ -20,7 +20,7 @@ foreach (new RecursiveIteratorIterator($rai) as $t) { var_dump($t); } ?> ---EXPECT-- +--EXPECTF-- string(1) "z" object(stdClass)#1 (0) { } @@ -28,5 +28,7 @@ string(1) "q" string(1) "s" Second: string(1) "z" + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d string(1) "q" string(1) "s" diff --git a/ext/spl/tests/bug45614.phpt b/ext/spl/tests/ArrayObject/bug45614.phpt similarity index 87% rename from ext/spl/tests/bug45614.phpt rename to ext/spl/tests/ArrayObject/bug45614.phpt index 8c688555d379..04c463815535 100644 --- a/ext/spl/tests/bug45614.phpt +++ b/ext/spl/tests/ArrayObject/bug45614.phpt @@ -39,7 +39,8 @@ $ai->rewind(); $ai->seek(0); showFirstTwoItems($ai); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d --> Show the first two items: pub1 => public1 pub2 => public2 diff --git a/ext/spl/tests/ArrayObject/bug54323.phpt b/ext/spl/tests/ArrayObject/bug54323.phpt new file mode 100644 index 000000000000..fa1e64f4947c --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug54323.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #54323 (Accessing unset()'ed ArrayObject's property causes crash) +--FILE-- +$value) { + } + unset($ao['prop']); + var_dump($c->prop, $ao['prop']); +} +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + +Warning: Undefined property: C::$prop in %s on line %d + +Warning: Undefined array key "prop" in %s on line %d +NULL +NULL diff --git a/ext/spl/tests/ArrayObject/bug62672.phpt b/ext/spl/tests/ArrayObject/bug62672.phpt new file mode 100644 index 000000000000..2d70ca71a1bd --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug62672.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #62672 (Error on serialize of ArrayObject) +--FILE-- +_varA = $source; + } +} + +class ObjB extends ObjA +{ + private $_varB; + + public function __construct(ArrayObject $keys) + { + $this->_varB = $keys; + parent::__construct($keys->getIterator()); + } +} + +$obj = new ObjB(new ArrayObject()); + +var_dump($obj == unserialize(serialize($obj))); +?> +--EXPECTF-- +Deprecated: ArrayIterator::__unserialize(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +bool(true) diff --git a/ext/spl/tests/ArrayObject/bug69845.phpt b/ext/spl/tests/ArrayObject/bug69845.phpt new file mode 100644 index 000000000000..6554e290e03a --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug69845.phpt @@ -0,0 +1,16 @@ +--TEST-- +Fixed bug #69845 (ArrayObject with ARRAY_AS_PROPS broken) +--FILE-- +itemType = 'bulletin'; + var_dump(!is_null($data['itemType'])); +} +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +bool(true) + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +bool(true) diff --git a/ext/spl/tests/bug70155.phpt b/ext/spl/tests/ArrayObject/bug70155.phpt similarity index 75% rename from ext/spl/tests/bug70155.phpt rename to ext/spl/tests/ArrayObject/bug70155.phpt index a609205aca27..27521015c487 100644 --- a/ext/spl/tests/bug70155.phpt +++ b/ext/spl/tests/ArrayObject/bug70155.phpt @@ -9,6 +9,8 @@ $data = unserialize($exploit); var_dump($data); ?> --EXPECTF-- +Deprecated: ArrayObject::unserialize(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Deprecated: Creation of dynamic property ArrayObject::$0 is deprecated in %s on line %d Fatal error: Uncaught InvalidArgumentException: Overloaded object of type DateInterval is not compatible with ArrayObject in %s diff --git a/ext/spl/tests/ArrayObject/bug73209.phpt b/ext/spl/tests/ArrayObject/bug73209.phpt new file mode 100644 index 000000000000..7da582b13523 --- /dev/null +++ b/ext/spl/tests/ArrayObject/bug73209.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #73209: RecursiveArrayIterator does not iterate object properties +--FILE-- +props = ['hello' => 5, 'props' => ['keyme' => ['test' => 5]]]; + } +} +$data = new hello(); + +$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data), RecursiveIteratorIterator::SELF_FIRST); +echo "Expect to see all keys in ->props here: \n"; + +foreach($iterator as $k=>$v) { + echo $k . "\n"; +} + +?> +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +Expect to see all keys in ->props here: +props +hello +props +keyme +test diff --git a/ext/spl/tests/bug74669.phpt b/ext/spl/tests/ArrayObject/bug74669.phpt similarity index 76% rename from ext/spl/tests/bug74669.phpt rename to ext/spl/tests/ArrayObject/bug74669.phpt index 597e694296d2..17f622aaaf9d 100644 --- a/ext/spl/tests/bug74669.phpt +++ b/ext/spl/tests/ArrayObject/bug74669.phpt @@ -93,13 +93,20 @@ var_dump($selfArray['foo']); ?> --EXPECTF-- +Deprecated: ArrayIterator::__unserialize(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d 0 => test1 1 => test2 + +Deprecated: ArrayIterator::__unserialize(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d 0 => test1 1 => test2 +Deprecated: ArrayObject::unserialize(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d + Warning: Undefined array key "foo" in %s on line %d NULL + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d object(SelfArray)#9 (1) { ["foo"]=> string(3) "bar" diff --git a/ext/spl/tests/gh10519.phpt b/ext/spl/tests/ArrayObject/gh10519.phpt similarity index 87% rename from ext/spl/tests/gh10519.phpt rename to ext/spl/tests/ArrayObject/gh10519.phpt index 1f7572d6e8ca..fbb66c166802 100644 --- a/ext/spl/tests/gh10519.phpt +++ b/ext/spl/tests/ArrayObject/gh10519.phpt @@ -1,5 +1,7 @@ --TEST-- Bug GH-10519 (Array Data Address Reference Issue) +--XFAIL-- +The fix for this was bad --FILE-- bugySetMethod(5, 'must be here'); var_dump(json_encode($example)); var_dump(json_encode($b)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d string(51) "{"test":{"a":{"2":"","3":"","4":"","5":"in here"}}}" string(51) "{"test":{"a":{"2":"","3":"","4":"","5":"in here"}}}" string(56) "{"test":{"b":{"2":"","3":"","4":"","5":"must be here"}}}" diff --git a/ext/spl/tests/ArrayObject/gh11178.phpt b/ext/spl/tests/ArrayObject/gh11178.phpt new file mode 100644 index 000000000000..91ac55d6f814 --- /dev/null +++ b/ext/spl/tests/ArrayObject/gh11178.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-11178 (Segmentation fault in spl_array_it_get_current_data (PHP 8.1.18)) +--FILE-- +{'x'} = 1; + } + + function getIterator(): Traversable { + return new ArrayIterator($this); + } +} + +$obj = new A; + +foreach ($obj as $k => &$v) { + $v = 3; +} + +var_dump($obj); +?> +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +object(A)#1 (1) { + ["x"]=> + &int(3) +} diff --git a/ext/spl/tests/ArrayObject/gh15833_1.phpt b/ext/spl/tests/ArrayObject/gh15833_1.phpt new file mode 100644 index 000000000000..5ee4b69e3256 --- /dev/null +++ b/ext/spl/tests/ArrayObject/gh15833_1.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-15833 (Segmentation fault (access null pointer) in ext/spl/spl_array.c) +--CREDITS-- +YuanchengJiang +--FILE-- +newLazyProxy(function ($obj) { + $obj = new C(); + return $obj; +}); +$recursiveArrayIterator = new RecursiveArrayIterator($obj); +var_dump($recursiveArrayIterator->current()); +$recursiveArrayIterator->next(); +var_dump($recursiveArrayIterator->current()); +?> +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d +int(1) +NULL diff --git a/ext/spl/tests/gh15833_2.phpt b/ext/spl/tests/ArrayObject/gh15833_2.phpt similarity index 81% rename from ext/spl/tests/gh15833_2.phpt rename to ext/spl/tests/ArrayObject/gh15833_2.phpt index 8f30921741fe..5d7721e25dd2 100644 --- a/ext/spl/tests/gh15833_2.phpt +++ b/ext/spl/tests/ArrayObject/gh15833_2.phpt @@ -34,7 +34,8 @@ try { echo $e->getMessage(), "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d nope 0 nope 1 nope 2 diff --git a/ext/spl/tests/ArrayObject/gh15918.phpt b/ext/spl/tests/ArrayObject/gh15918.phpt new file mode 100644 index 000000000000..5efdb887f9b5 --- /dev/null +++ b/ext/spl/tests/ArrayObject/gh15918.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-15918 (Assertion failure in ext/spl/spl_fixedarray.c) +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +Overloaded object of type SplFixedArray is not compatible with ArrayObject diff --git a/ext/spl/tests/ArrayObject/gh16646.phpt b/ext/spl/tests/ArrayObject/gh16646.phpt new file mode 100644 index 000000000000..f572346ea5df --- /dev/null +++ b/ext/spl/tests/ArrayObject/gh16646.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-16646: Use-after-free in ArrayObject::unset() with destructor +--FILE-- +b = $arg; + } +} + +class C { + function __destruct() { + global $arr; + echo __METHOD__, "\n"; + $arr->exchangeArray([]); + } +} + +$arr = new ArrayObject(new B(new C)); +unset($arr["b"]); +var_dump($arr); + +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +C::__destruct +object(ArrayObject)#1 (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } +} diff --git a/ext/spl/tests/ArrayObject/gh16646_2.phpt b/ext/spl/tests/ArrayObject/gh16646_2.phpt new file mode 100644 index 000000000000..035087fbe22b --- /dev/null +++ b/ext/spl/tests/ArrayObject/gh16646_2.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-16646: Use-after-free in ArrayObject::exchangeArray() with destructor +--FILE-- +exchangeArray([]); + } +} + +$arr = new ArrayObject(new C); +$arr->exchangeArray([]); +var_dump($arr); + +?> +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d +C::__destruct +object(ArrayObject)#1 (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } +} diff --git a/ext/spl/tests/ArrayObject/ksort_disabled.phpt b/ext/spl/tests/ArrayObject/ksort_disabled.phpt new file mode 100644 index 000000000000..258057ad64d3 --- /dev/null +++ b/ext/spl/tests/ArrayObject/ksort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function ksort() is disabled +--INI-- +disable_functions=ksort +--FILE-- +ksort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method ksort when function ksort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->ksort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/natcasesort_disabled.phpt b/ext/spl/tests/ArrayObject/natcasesort_disabled.phpt new file mode 100644 index 000000000000..336e1245dabc --- /dev/null +++ b/ext/spl/tests/ArrayObject/natcasesort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function natcasesort() is disabled +--INI-- +disable_functions=natcasesort +--FILE-- +natcasesort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method natcasesort when function natcasesort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->natcasesort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/natsort_disabled.phpt b/ext/spl/tests/ArrayObject/natsort_disabled.phpt new file mode 100644 index 000000000000..b674235627ad --- /dev/null +++ b/ext/spl/tests/ArrayObject/natsort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function natsort() is disabled +--INI-- +disable_functions=natsort +--FILE-- +natsort(); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method natsort when function natsort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->natsort() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/property_hooks.phpt b/ext/spl/tests/ArrayObject/property_hooks.phpt index c0b2a372ebe4..dfed649e7c63 100644 --- a/ext/spl/tests/ArrayObject/property_hooks.phpt +++ b/ext/spl/tests/ArrayObject/property_hooks.phpt @@ -63,6 +63,7 @@ var_dump($o->username); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d Check object properties directly string(5) "FIRST" string(4) "last" diff --git a/ext/spl/tests/ArrayObject/uasort_disabled.phpt b/ext/spl/tests/ArrayObject/uasort_disabled.phpt new file mode 100644 index 000000000000..5a5e9aa57b21 --- /dev/null +++ b/ext/spl/tests/ArrayObject/uasort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function uasort() is disabled +--INI-- +disable_functions=uasort +--FILE-- +uasort(fn ($l, $r) => $l <=> $r); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method uasort when function uasort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->uasort(Object(Closure)) +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject/uksort_disabled.phpt b/ext/spl/tests/ArrayObject/uksort_disabled.phpt new file mode 100644 index 000000000000..af703883a3f5 --- /dev/null +++ b/ext/spl/tests/ArrayObject/uksort_disabled.phpt @@ -0,0 +1,18 @@ +--TEST-- +ArrayObject when function uksort() is disabled +--INI-- +disable_functions=uksort +--FILE-- +uksort(fn ($l, $r) => $l <=> $r); +var_dump($ao); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call method uksort when function uksort is disabled in %s:%d +Stack trace: +#0 %s(%d): ArrayObject->uksort(Object(Closure)) +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/ArrayObject_clone_other_std_props.phpt b/ext/spl/tests/ArrayObject_clone_other_std_props.phpt deleted file mode 100644 index 688954c3d7b1..000000000000 --- a/ext/spl/tests/ArrayObject_clone_other_std_props.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -Clone ArrayObject using other with STD_PROP_LIST ---FILE-- - ---EXPECT-- -object(ArrayObject)#3 (1) { - ["storage":"ArrayObject":private]=> - array(3) { - [0]=> - int(1) - [1]=> - int(2) - [2]=> - int(3) - } -} diff --git a/ext/spl/tests/ArrayObject_enum.phpt b/ext/spl/tests/ArrayObject_enum.phpt deleted file mode 100644 index 906c89b54dff..000000000000 --- a/ext/spl/tests/ArrayObject_enum.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Enums are not compatible with ArrayObject ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught InvalidArgumentException: Enums are not compatible with ArrayObject in %s:%d -%a diff --git a/ext/spl/tests/ArrayObject_get_object_vars.phpt b/ext/spl/tests/ArrayObject_get_object_vars.phpt deleted file mode 100644 index a80add6b95ad..000000000000 --- a/ext/spl/tests/ArrayObject_get_object_vars.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -get_object_vars() on ArrayObject works on the properties of the ArrayObject itself ---FILE-- -getObjectVars()); - -?> ---EXPECT-- -array(0) { -} -array(1) { - ["test"]=> - NULL -} diff --git a/ext/spl/tests/ArrayObject_modify_shared_object_properties.phpt b/ext/spl/tests/ArrayObject_modify_shared_object_properties.phpt deleted file mode 100644 index 24c247cabd9d..000000000000 --- a/ext/spl/tests/ArrayObject_modify_shared_object_properties.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -Modifications to ArrayObjects should not affect shared properties tables ---FILE-- - 1, 'b' => 2]; -$ao = new ArrayObject($obj); -$arr = (array) $obj; -$ao['a'] = 42; -var_dump($arr); - -?> ---EXPECT-- -array(2) { - ["a"]=> - int(1) - ["b"]=> - int(2) -} diff --git a/ext/spl/tests/ArrayObject_overloaded_SplFixedArray.phpt b/ext/spl/tests/ArrayObject_overloaded_SplFixedArray.phpt deleted file mode 100644 index f46e4cc1c9aa..000000000000 --- a/ext/spl/tests/ArrayObject_overloaded_SplFixedArray.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -SplFixedArray properties is incompatible with ArrayObject ---FILE-- -exchangeArray($fixedArray); -} catch (InvalidArgumentException $e) { - echo $e->getMessage(), "\n"; -} -?> ---EXPECT-- -Overloaded object of type SplFixedArray is not compatible with ArrayObject diff --git a/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt b/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt deleted file mode 100644 index 67267f0ec6a1..000000000000 --- a/ext/spl/tests/ArrayObject_overloaded_object_incompatible.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Objects with overloaded get_properties are incompatible with ArrayObject ---FILE-- -exchangeArray(new DateInterval('P1D')); -} catch (Exception $e) { - echo $e->getMessage(), "\n"; -} -var_dump($ao); - -?> ---EXPECT-- -Overloaded object of type DateInterval is not compatible with ArrayObject -object(ArrayObject)#1 (1) { - ["storage":"ArrayObject":private]=> - array(3) { - [0]=> - int(1) - [1]=> - int(2) - [2]=> - int(3) - } -} diff --git a/ext/spl/tests/ArrayObject_proptable_canonicalization.phpt b/ext/spl/tests/ArrayObject_proptable_canonicalization.phpt deleted file mode 100644 index 006a15260268..000000000000 --- a/ext/spl/tests/ArrayObject_proptable_canonicalization.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -When ArrayObject wraps an object, we should use proptable canonicalization ---FILE-- - ---EXPECT-- -object(stdClass)#1 (1) { - ["0"]=> - int(1) -} -object(stdClass)#1 (1) { - ["0"]=> - int(2) -} -bool(true) -array(1) { - [0]=> - int(2) -} -object(stdClass)#1 (0) { -} diff --git a/ext/spl/tests/ArrayObject_sort_different_backing_storage.phpt b/ext/spl/tests/ArrayObject_sort_different_backing_storage.phpt deleted file mode 100644 index 93dd6570791c..000000000000 --- a/ext/spl/tests/ArrayObject_sort_different_backing_storage.phpt +++ /dev/null @@ -1,76 +0,0 @@ ---TEST-- -Test sorting of various ArrayObject backing storage ---FILE-- - 2, 'b' => 1]; -$ao = new ArrayObject($obj); -$ao->uasort(function($a, $b) { return $a <=> $b; }); -var_dump($ao); - -$ao2 = new ArrayObject($ao); -$ao2->uasort(function($a, $b) { return $b <=> $a; }); -var_dump($ao2); - -$ao3 = new ArrayObject(); -$ao3->exchangeArray($ao3); -$ao3->a = 2; -$ao3->b = 1; -$ao3->uasort(function($a, $b) { return $a <=> $b; }); -var_dump($ao3); - -$ao4 = new ArrayObject([]); -$ao4->uasort(function($a, $b) { return $a <=> $b; }); -var_dump($ao4); - -$ao5 = new ArrayObject(['a' => 2, 'b' => 1]); -$ao5->uasort(function($a, $b) { return $a <=> $b; }); -var_dump($ao5); - -?> ---EXPECTF-- -object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - object(stdClass)#1 (2) { - ["b"]=> - int(1) - ["a"]=> - int(2) - } -} -object(ArrayObject)#3 (1) { - ["storage":"ArrayObject":private]=> - object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - object(stdClass)#1 (2) { - ["a"]=> - int(2) - ["b"]=> - int(1) - } - } -} - -Deprecated: Creation of dynamic property ArrayObject::$a is deprecated in %s on line %d - -Deprecated: Creation of dynamic property ArrayObject::$b is deprecated in %s on line %d -object(ArrayObject)#4 (2) { - ["b"]=> - int(1) - ["a"]=> - int(2) -} -object(ArrayObject)#5 (1) { - ["storage":"ArrayObject":private]=> - array(0) { - } -} -object(ArrayObject)#6 (1) { - ["storage":"ArrayObject":private]=> - array(2) { - ["b"]=> - int(1) - ["a"]=> - int(2) - } -} diff --git a/ext/spl/tests/ArrayObject_std_props_no_recursion.phpt b/ext/spl/tests/ArrayObject_std_props_no_recursion.phpt deleted file mode 100644 index 55ec57762fa4..000000000000 --- a/ext/spl/tests/ArrayObject_std_props_no_recursion.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -Don't recurse into USE_OTHER when checking for STD_PROP_LIST ---FILE-- -prop = 'a'; -$b = new ArrayObject($a, 0); -$b->prop = 'b'; -var_dump((array) $b); -$c = new ArrayObject($a); -$c->prop = 'c'; -var_dump((array) $c); - -?> ---EXPECTF-- -Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d - -Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d -array(3) { - [0]=> - int(1) - [1]=> - int(2) - [2]=> - int(3) -} - -Deprecated: Creation of dynamic property ArrayObject::$prop is deprecated in %s on line %d -array(1) { - ["prop"]=> - string(1) "c" -} diff --git a/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt b/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt index 0c21d0b905e9..7d0e3ae8d969 100644 --- a/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt +++ b/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt @@ -18,5 +18,5 @@ var_dump($s->key()); var_dump($s->valid()); ?> --EXPECT-- -int(14) +int(12) bool(false) diff --git a/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt b/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt index 8fc9b7fef0a5..0834dbc0524f 100644 --- a/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt +++ b/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt @@ -18,5 +18,5 @@ var_dump($s->key()); var_dump($s->valid()); ?> --EXPECT-- -int(13) +int(12) bool(false) diff --git a/ext/spl/tests/SplFileObject/bug81477.phpt b/ext/spl/tests/SplFileObject/bug81477.phpt index f7730a791aa0..421c74dc4d68 100644 --- a/ext/spl/tests/SplFileObject/bug81477.phpt +++ b/ext/spl/tests/SplFileObject/bug81477.phpt @@ -21,7 +21,6 @@ string(8) "baz,bat " string(10) "more,data " -string(0) "" --CLEAN-- rewind(); var_dump($file->fgetcsv()); ?> --EXPECT-- -array(1) { - [0]=> - NULL -} +bool(false) bool(false) diff --git a/ext/spl/tests/SplFileObject/gh21742.phpt b/ext/spl/tests/SplFileObject/gh21742.phpt new file mode 100644 index 000000000000..7ea60b53915a --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh21742.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-21742 (SplFileObject::fgets() throws at EOF in while (!$spl->eof()) loop) +--FILE-- +eof()) { + echo $spl->fgets(); +} +echo "clean exit\n"; + +$empty = tempnam(sys_get_temp_dir(), 'spl'); +file_put_contents($empty, ''); +$spl2 = new SplFileObject($empty, 'r'); +$iter = 0; +while (!$spl2->eof()) { + $iter++; + $spl2->fgets(); + if ($iter > 3) break; +} +echo "empty-file iters=$iter\n"; + +unlink($file); +unlink($empty); +?> +--EXPECT-- +Line 0 +Line 1 +Line 2 +Line 3 +Line 4 +clean exit +empty-file iters=1 diff --git a/ext/spl/tests/SplFileObject/gh8561.phpt b/ext/spl/tests/SplFileObject/gh8561.phpt new file mode 100644 index 000000000000..adf36afb8b29 --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8561.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-8561 (SplFileObject: key() and current() unsynchronized after fgets()) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +// Case 1: rewind + fgets, then key/current +$file->rewind(); +$file->fgets(); +echo "After rewind+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +// Case 2: multiple fgets +$file->rewind(); +$file->fgets(); +$file->fgets(); +echo "After rewind+fgets+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +// Case 3: current then fgets +$file->rewind(); +$file->current(); +$file->fgets(); +echo "After current+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; +?> +--EXPECT-- +After rewind+fgets: key=1 current=line 1 +After rewind+fgets+fgets: key=2 current=line 2 +After current+fgets: key=1 current=line 1 diff --git a/ext/spl/tests/SplFileObject/gh8563.phpt b/ext/spl/tests/SplFileObject/gh8563.phpt new file mode 100644 index 000000000000..03891750f8bf --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8563.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-8563 (Different results for seek() on SplFileObject and SplTempFileObject) +--FILE-- +fwrite("line {$i}" . PHP_EOL); + $file_02->fwrite("line {$i}" . PHP_EOL); +} + +$file_01->rewind(); +$file_02->rewind(); + +$file_01->seek(10); +$file_02->seek(10); + +echo 'SplFileObject: ' . $file_01->key() . "\n"; +echo 'SplTempFileObject: ' . $file_02->key() . "\n"; +?> +--CLEAN-- + +--EXPECT-- +SplFileObject: 5 +SplTempFileObject: 5 diff --git a/ext/spl/tests/SplFileObject/gh8564.phpt b/ext/spl/tests/SplFileObject/gh8564.phpt new file mode 100644 index 000000000000..ff16893c4c6b --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8564.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-8564 (SplFileObject: next() moves to nonexistent indexes) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +$file->rewind(); +for ($i = 0; $i < 10; $file->next(), $i++); +echo "next() 10x: key=" . $file->key() . " valid=" . var_export($file->valid(), true) . "\n"; + +$file->rewind(); +$file->seek(10); +echo "seek(10): key=" . $file->key() . " valid=" . var_export($file->valid(), true) . "\n"; +?> +--EXPECT-- +next() 10x: key=5 valid=false +seek(10): key=5 valid=false diff --git a/ext/spl/tests/SplFixedArray_setSize_destruct_grow_during_clear.phpt b/ext/spl/tests/SplFixedArray_setSize_destruct_grow_during_clear.phpt new file mode 100644 index 000000000000..f0982364afa8 --- /dev/null +++ b/ext/spl/tests/SplFixedArray_setSize_destruct_grow_during_clear.phpt @@ -0,0 +1,28 @@ +--TEST-- +SplFixedArray::setSize: grow re-entrantly during clear (setSize(0)) +--FILE-- +arr !== null) { + $this->arr->setSize(5); + } + } +} + +$arr = new SplFixedArray(2); +$r = new Reentrant(); +$r->arr = $arr; +$arr[0] = $r; +unset($r); +$arr[1] = "tail"; + +$arr->setSize(0); +echo "size: ", $arr->getSize(), "\n"; +$arr[0] = "ok"; +var_dump($arr[0]); +?> +--EXPECT-- +size: 5 +string(2) "ok" diff --git a/ext/spl/tests/SplHeap_serialize_corrupted.phpt b/ext/spl/tests/SplHeap_serialize_corrupted.phpt new file mode 100644 index 000000000000..8763a4c08293 --- /dev/null +++ b/ext/spl/tests/SplHeap_serialize_corrupted.phpt @@ -0,0 +1,67 @@ +--TEST-- +SplHeap and SplPriorityQueue serialization fails when corrupted +--FILE-- +insert(1); +$heap->insert(2); + +try { + $heap->insert('throw'); +} catch (Exception $e) { + // no-op, heap should now be corrupted +} + +echo "Heap is corrupted: " . ($heap->isCorrupted() ? 'YES' : 'NO') . "\n"; + +try { + serialize($heap); + echo "FAIL: Serialization should have thrown\n"; +} catch (Exception $e) { + echo "Serialization failed: " . $e->getMessage() . "\n"; +} + +class ThrowingPQ extends SplPriorityQueue { + public function compare($priority1, $priority2): int { + if ($priority1 === 'throw' || $priority2 === 'throw') { + throw new Exception('Priority comparison failed'); + } + return parent::compare($priority1, $priority2); + } +} + +$pq = new ThrowingPQ(); +$pq->insert('data1', 1); +$pq->insert('data2', 2); + +try { + $pq->insert('data3', 'throw'); +} catch (Exception $e) { + // no-op, queue is corrupted +} + +echo "PriorityQueue is corrupted: " . ($pq->isCorrupted() ? 'YES' : 'NO') . "\n"; + +try { + serialize($pq); + echo "FAIL: PQ Serialization should have thrown\n"; +} catch (Exception $e) { + echo "PQ Serialization failed: " . $e->getMessage() . "\n"; +} + +?> +--EXPECT-- +Heap is corrupted: YES +Serialization failed: Heap is corrupted, heap properties are no longer ensured. +PriorityQueue is corrupted: YES +PQ Serialization failed: Heap is corrupted, heap properties are no longer ensured. diff --git a/ext/spl/tests/SplHeap_serialize_error_handling.phpt b/ext/spl/tests/SplHeap_serialize_error_handling.phpt new file mode 100644 index 000000000000..458f27db5ce0 --- /dev/null +++ b/ext/spl/tests/SplHeap_serialize_error_handling.phpt @@ -0,0 +1,84 @@ +--TEST-- +SplHeap and SplPriorityQueue unserialization error handling +--FILE-- + 'not_int']], + + // Missing heap_elements + [[], ['flags' => 0]], + + // Invalid heap_elements type + [[], ['flags' => 0, 'heap_elements' => 'not_array']], + [[], ['flags' => 0, 'heap_elements' => 123]], +]; + +foreach ($invalid_cases as $i => $case) { + try { + $heap = new SplMaxHeap(); + $heap->__unserialize($case); + echo "Case $i: UNEXPECTED SUCCESS\n"; + } catch (Exception $e) { + echo "Case $i: " . $e->getMessage() . "\n"; + } +} + +$pq_invalid_cases = [ + // Invalid flags for PQ + [[], ['flags' => 0]], + + // Invalid element structure + [[], ['flags' => 1, 'heap_elements' => ['not_array']]], + + // Missing data/priority keys + [[], ['flags' => 1, 'heap_elements' => [['data' => 'test']]]], + [[], ['flags' => 1, 'heap_elements' => [['priority' => 1]]]], + [[], ['flags' => 1, 'heap_elements' => [[]]]], +]; + +foreach ($pq_invalid_cases as $i => $case) { + try { + $pq = new SplPriorityQueue(); + $pq->__unserialize($case); + echo "PQ Case $i: UNEXPECTED SUCCESS\n"; + } catch (Exception $e) { + echo "PQ Case $i: " . $e->getMessage() . "\n"; + } +} + +?> +--EXPECT-- +Case 0: Invalid serialization data for SplMaxHeap object +Case 1: Invalid serialization data for SplMaxHeap object +Case 2: Invalid serialization data for SplMaxHeap object +Case 3: Invalid serialization data for SplMaxHeap object +Case 4: Invalid serialization data for SplMaxHeap object +Case 5: Invalid serialization data for SplMaxHeap object +Case 6: Invalid serialization data for SplMaxHeap object +Case 7: Invalid serialization data for SplMaxHeap object +Case 8: Invalid serialization data for SplMaxHeap object +Case 9: Invalid serialization data for SplMaxHeap object +Case 10: Invalid serialization data for SplMaxHeap object +PQ Case 0: Invalid serialization data for SplPriorityQueue object +PQ Case 1: Invalid serialization data for SplPriorityQueue object +PQ Case 2: Invalid serialization data for SplPriorityQueue object +PQ Case 3: Invalid serialization data for SplPriorityQueue object +PQ Case 4: Invalid serialization data for SplPriorityQueue object diff --git a/ext/spl/tests/SplHeap_serialize_format.phpt b/ext/spl/tests/SplHeap_serialize_format.phpt new file mode 100644 index 000000000000..aaa1b56e2695 --- /dev/null +++ b/ext/spl/tests/SplHeap_serialize_format.phpt @@ -0,0 +1,131 @@ +--TEST-- +SplHeap serialization binary format +--FILE-- +insert(100); +$heap->insert(50); +$heap->insert(200); +$s = serialize($heap); +echo $s . "\n"; +$unserialized = unserialize($s); +var_dump($unserialized); + +// Test SplMinHeap +$min = new SplMinHeap(); +$min->insert(30); +$min->insert(10); +$min->insert(20); +$s = serialize($min); +echo $s . "\n"; +var_dump(unserialize($s)); + +// Test SplPriorityQueue empty +$pq = new SplPriorityQueue(); +$s = serialize($pq); +echo $s . "\n"; +var_dump(unserialize($s)); + +// Test SplPriorityQueue with data +$pq = new SplPriorityQueue(); +$pq->insert('low', 1); +$pq->insert('high', 10); +$pq->insert('medium', 5); +$pq->setExtractFlags(SplPriorityQueue::EXTR_BOTH); +$s = serialize($pq); +echo $s . "\n"; +var_dump(unserialize($s)); + +?> +--EXPECT-- +O:10:"SplMaxHeap":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:0;s:13:"heap_elements";a:0:{}}} +object(SplMaxHeap)#2 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(0) { + } +} +O:10:"SplMaxHeap":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:0;s:13:"heap_elements";a:3:{i:0;i:200;i:1;i:50;i:2;i:100;}}} +object(SplMaxHeap)#1 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(3) { + [0]=> + int(200) + [1]=> + int(50) + [2]=> + int(100) + } +} +O:10:"SplMinHeap":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:0;s:13:"heap_elements";a:3:{i:0;i:10;i:1;i:30;i:2;i:20;}}} +object(SplMinHeap)#4 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(3) { + [0]=> + int(10) + [1]=> + int(30) + [2]=> + int(20) + } +} +O:16:"SplPriorityQueue":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:1;s:13:"heap_elements";a:0:{}}} +object(SplPriorityQueue)#5 (3) { + ["flags":"SplPriorityQueue":private]=> + int(1) + ["isCorrupted":"SplPriorityQueue":private]=> + bool(false) + ["heap":"SplPriorityQueue":private]=> + array(0) { + } +} +O:16:"SplPriorityQueue":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:3;s:13:"heap_elements";a:3:{i:0;a:2:{s:4:"data";s:4:"high";s:8:"priority";i:10;}i:1;a:2:{s:4:"data";s:3:"low";s:8:"priority";i:1;}i:2;a:2:{s:4:"data";s:6:"medium";s:8:"priority";i:5;}}}} +object(SplPriorityQueue)#4 (3) { + ["flags":"SplPriorityQueue":private]=> + int(3) + ["isCorrupted":"SplPriorityQueue":private]=> + bool(false) + ["heap":"SplPriorityQueue":private]=> + array(3) { + [0]=> + array(2) { + ["data"]=> + string(4) "high" + ["priority"]=> + int(10) + } + [1]=> + array(2) { + ["data"]=> + string(3) "low" + ["priority"]=> + int(1) + } + [2]=> + array(2) { + ["data"]=> + string(6) "medium" + ["priority"]=> + int(5) + } + } +} diff --git a/ext/spl/tests/SplHeap_serialize_indexed_format.phpt b/ext/spl/tests/SplHeap_serialize_indexed_format.phpt new file mode 100644 index 000000000000..21ea74c6bff9 --- /dev/null +++ b/ext/spl/tests/SplHeap_serialize_indexed_format.phpt @@ -0,0 +1,91 @@ +--TEST-- +SplHeap serialization format - indexed array format prevents conflicts +--FILE-- +insert(100); +$heap->insert(50); +$heap->insert(200); + +$serialized_data = $heap->__serialize(); +var_dump($serialized_data); + +$pq = new SplPriorityQueue(); +$pq->insert('data', 10); +$pq->setExtractFlags(SplPriorityQueue::EXTR_DATA); + +$pq_data = $pq->__serialize(); +var_dump($pq_data); + +class CustomHeap extends SplMaxHeap { + public $flags = 'user_property'; + public $heap_elements = 'user_property'; +} + +$custom = new CustomHeap(); +$custom->insert(42); + +$custom_data = $custom->__serialize(); +var_dump($custom_data); + +?> +--EXPECT-- +array(2) { + [0]=> + array(0) { + } + [1]=> + array(2) { + ["flags"]=> + int(0) + ["heap_elements"]=> + array(3) { + [0]=> + int(200) + [1]=> + int(50) + [2]=> + int(100) + } + } +} +array(2) { + [0]=> + array(0) { + } + [1]=> + array(2) { + ["flags"]=> + int(1) + ["heap_elements"]=> + array(1) { + [0]=> + array(2) { + ["data"]=> + string(4) "data" + ["priority"]=> + int(10) + } + } + } +} +array(2) { + [0]=> + array(2) { + ["flags"]=> + string(13) "user_property" + ["heap_elements"]=> + string(13) "user_property" + } + [1]=> + array(2) { + ["flags"]=> + int(0) + ["heap_elements"]=> + array(1) { + [0]=> + int(42) + } + } +} diff --git a/ext/spl/tests/SplHeap_serialize_inheritance_safety.phpt b/ext/spl/tests/SplHeap_serialize_inheritance_safety.phpt new file mode 100644 index 000000000000..c90b278e45b6 --- /dev/null +++ b/ext/spl/tests/SplHeap_serialize_inheritance_safety.phpt @@ -0,0 +1,117 @@ +--TEST-- +SplHeap and SplPriorityQueue inheritance safety with conflicting property names +--FILE-- +flags = 'modified_user_flags'; +$heap->heap_elements = 'modified_user_elements'; +$heap->custom_prop = 'modified_custom'; + +$heap->insert(100); +$heap->insert(50); +$heap->insert(200); + +$serialized = serialize($heap); +echo $serialized . "\n"; +$unserialized = unserialize($serialized); +var_dump($unserialized); + +class CustomPriorityQueue extends SplPriorityQueue { + public $flags = 'user_flags_property'; + public $heap_elements = 'user_heap_elements_property'; + public $custom_data = 'custom_data_value'; + protected $protected_priority = 'protected_priority_value'; +} + +$pq = new CustomPriorityQueue(); +$pq->flags = 'modified_user_flags'; +$pq->heap_elements = 'modified_user_elements'; +$pq->custom_data = 'modified_custom_data'; + +$pq->insert('low_priority', 1); +$pq->insert('high_priority', 10); +$pq->insert('medium_priority', 5); + +$pq->setExtractFlags(SplPriorityQueue::EXTR_BOTH); + +$serialized_pq = serialize($pq); +echo $serialized_pq . "\n"; +$unserialized_pq = unserialize($serialized_pq); +var_dump($unserialized_pq); + +?> +--EXPECTF-- +O:10:"CustomHeap":2:{i:0;a:5:{s:5:"flags";s:19:"modified_user_flags";s:13:"heap_elements";s:22:"modified_user_elements";s:11:"custom_prop";s:15:"modified_custom";s:17:"%0*%0protected_prop";s:15:"protected_value";s:24:"%0CustomHeap%0private_prop";s:13:"private_value";}i:1;a:2:{s:5:"flags";i:0;s:13:"heap_elements";a:3:{i:0;i:200;i:1;i:50;i:2;i:100;}}} +object(CustomHeap)#2 (8) { + ["flags"]=> + string(19) "modified_user_flags" + ["heap_elements"]=> + string(22) "modified_user_elements" + ["custom_prop"]=> + string(15) "modified_custom" + ["protected_prop":protected]=> + string(15) "protected_value" + ["private_prop":"CustomHeap":private]=> + string(13) "private_value" + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(3) { + [0]=> + int(200) + [1]=> + int(50) + [2]=> + int(100) + } +} +O:19:"CustomPriorityQueue":2:{i:0;a:4:{s:5:"flags";s:19:"modified_user_flags";s:13:"heap_elements";s:22:"modified_user_elements";s:11:"custom_data";s:20:"modified_custom_data";s:21:"%0*%0protected_priority";s:24:"protected_priority_value";}i:1;a:2:{s:5:"flags";i:3;s:13:"heap_elements";a:3:{i:0;a:2:{s:4:"data";s:13:"high_priority";s:8:"priority";i:10;}i:1;a:2:{s:4:"data";s:12:"low_priority";s:8:"priority";i:1;}i:2;a:2:{s:4:"data";s:15:"medium_priority";s:8:"priority";i:5;}}}} +object(CustomPriorityQueue)#4 (7) { + ["flags"]=> + string(19) "modified_user_flags" + ["heap_elements"]=> + string(22) "modified_user_elements" + ["custom_data"]=> + string(20) "modified_custom_data" + ["protected_priority":protected]=> + string(24) "protected_priority_value" + ["flags":"SplPriorityQueue":private]=> + int(3) + ["isCorrupted":"SplPriorityQueue":private]=> + bool(false) + ["heap":"SplPriorityQueue":private]=> + array(3) { + [0]=> + array(2) { + ["data"]=> + string(13) "high_priority" + ["priority"]=> + int(10) + } + [1]=> + array(2) { + ["data"]=> + string(12) "low_priority" + ["priority"]=> + int(1) + } + [2]=> + array(2) { + ["data"]=> + string(15) "medium_priority" + ["priority"]=> + int(5) + } + } +} diff --git a/ext/spl/tests/SplMaxHeap_serialize_complex.phpt b/ext/spl/tests/SplMaxHeap_serialize_complex.phpt new file mode 100644 index 000000000000..9e83d779c416 --- /dev/null +++ b/ext/spl/tests/SplMaxHeap_serialize_complex.phpt @@ -0,0 +1,89 @@ +--TEST-- +SplMaxHeap serialization with complex data types +--FILE-- +insert(['type' => 'array1', 'value' => 10]); +$heap->insert(['type' => 'array2', 'value' => 20]); +$heap->insert(['type' => 'array3', 'value' => 5]); + +$serialized = serialize($heap); +echo $serialized . "\n"; + +$unserialized = unserialize($serialized); +var_dump($unserialized); + +class TestObj { + public $val; + public function __construct($v) { $this->val = $v; } +} + +$heap2 = new SplMaxHeap(); +$heap2->insert(new TestObj(30)); +$heap2->insert(new TestObj(10)); +$heap2->insert(new TestObj(20)); + +$serialized2 = serialize($heap2); +echo $serialized2 . "\n"; + +$unserialized2 = unserialize($serialized2); +var_dump($unserialized2); + +?> +--EXPECT-- +O:10:"SplMaxHeap":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:0;s:13:"heap_elements";a:3:{i:0;a:2:{s:4:"type";s:6:"array3";s:5:"value";i:5;}i:1;a:2:{s:4:"type";s:6:"array1";s:5:"value";i:10;}i:2;a:2:{s:4:"type";s:6:"array2";s:5:"value";i:20;}}}} +object(SplMaxHeap)#2 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(3) { + [0]=> + array(2) { + ["type"]=> + string(6) "array3" + ["value"]=> + int(5) + } + [1]=> + array(2) { + ["type"]=> + string(6) "array1" + ["value"]=> + int(10) + } + [2]=> + array(2) { + ["type"]=> + string(6) "array2" + ["value"]=> + int(20) + } + } +} +O:10:"SplMaxHeap":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:0;s:13:"heap_elements";a:3:{i:0;O:7:"TestObj":1:{s:3:"val";i:30;}i:1;O:7:"TestObj":1:{s:3:"val";i:10;}i:2;O:7:"TestObj":1:{s:3:"val";i:20;}}}} +object(SplMaxHeap)#7 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(3) { + [0]=> + object(TestObj)#8 (1) { + ["val"]=> + int(30) + } + [1]=> + object(TestObj)#9 (1) { + ["val"]=> + int(10) + } + [2]=> + object(TestObj)#10 (1) { + ["val"]=> + int(20) + } + } +} diff --git a/ext/spl/tests/SplMinHeap_serialize_complex.phpt b/ext/spl/tests/SplMinHeap_serialize_complex.phpt new file mode 100644 index 000000000000..0f33fa3ae700 --- /dev/null +++ b/ext/spl/tests/SplMinHeap_serialize_complex.phpt @@ -0,0 +1,63 @@ +--TEST-- +SplMinHeap serialization with nested arrays +--FILE-- +insert(['name' => 'Alice', 'nested' => ['age' => 25, 'city' => 'NYC']]); +$heap->insert(['name' => 'Bob', 'nested' => ['age' => 30, 'city' => 'LA']]); +$heap->insert(['name' => 'Charlie', 'nested' => ['age' => 35, 'city' => 'SF']]); + +$serialized = serialize($heap); +echo $serialized . "\n"; + +$unserialized = unserialize($serialized); +var_dump($unserialized); + +?> +--EXPECT-- +O:10:"SplMinHeap":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:0;s:13:"heap_elements";a:3:{i:0;a:2:{s:4:"name";s:5:"Alice";s:6:"nested";a:2:{s:3:"age";i:25;s:4:"city";s:3:"NYC";}}i:1;a:2:{s:4:"name";s:3:"Bob";s:6:"nested";a:2:{s:3:"age";i:30;s:4:"city";s:2:"LA";}}i:2;a:2:{s:4:"name";s:7:"Charlie";s:6:"nested";a:2:{s:3:"age";i:35;s:4:"city";s:2:"SF";}}}}} +object(SplMinHeap)#2 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(3) { + [0]=> + array(2) { + ["name"]=> + string(5) "Alice" + ["nested"]=> + array(2) { + ["age"]=> + int(25) + ["city"]=> + string(3) "NYC" + } + } + [1]=> + array(2) { + ["name"]=> + string(3) "Bob" + ["nested"]=> + array(2) { + ["age"]=> + int(30) + ["city"]=> + string(2) "LA" + } + } + [2]=> + array(2) { + ["name"]=> + string(7) "Charlie" + ["nested"]=> + array(2) { + ["age"]=> + int(35) + ["city"]=> + string(2) "SF" + } + } + } +} diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt index 5a89b46be6b8..d4075018d341 100644 --- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt +++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt @@ -19,15 +19,17 @@ var_dump(isset($s[$o2])); var_dump(empty($s[$o2])); $s[$o2] = null; var_dump($s[$o2] ?? new stdClass()); -echo "check isset/empty/contains for null. offsetExists returns true as long as the entry is there.\n"; +echo "check isset/empty/contains/offsetExists for null. offsetExists returns true as long as the entry is there.\n"; var_dump(isset($s[$o2])); var_dump(empty($s[$o2])); var_dump($s->contains($o2)); -echo "check isset/empty/contains for false.\n"; +var_dump($s->offsetExists($o2)); +echo "check isset/empty/contains/offsetExists for false.\n"; $s[$o2] = false; var_dump(isset($s[$o2])); var_dump(empty($s[$o2])); var_dump($s->contains($o2)); +var_dump($s->offsetExists($o2)); try { $s['invalid'] = 123; } catch (Error $e) { @@ -56,18 +58,24 @@ bool(false) bool(true) object(stdClass)#4 (0) { } -check isset/empty/contains for null. offsetExists returns true as long as the entry is there. +check isset/empty/contains/offsetExists for null. offsetExists returns true as long as the entry is there. bool(true) bool(true) + +Deprecated: Method SplObjectStorage::contains() is deprecated since 8.5, use method SplObjectStorage::offsetExists() instead in %s on line %d +bool(true) bool(true) -check isset/empty/contains for false. +check isset/empty/contains/offsetExists for false. bool(true) bool(true) + +Deprecated: Method SplObjectStorage::contains() is deprecated since 8.5, use method SplObjectStorage::offsetExists() instead in %s on line %d +bool(true) bool(true) TypeError: SplObjectStorage::offsetSet(): Argument #1 ($object) must be of type object, string given TypeError: SplObjectStorage::offsetExists(): Argument #1 ($object) must be of type object, string given -Notice: Indirect modification of overloaded element of SplObjectStorage has no effect in %s on line 38 +Notice: Indirect modification of overloaded element of SplObjectStorage has no effect in %s on line %d object(SplObjectStorage)#1 (1) { ["storage":"SplObjectStorage":private]=> array(2) { diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt index a6059da2958f..fa7fdf367fa9 100644 --- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt +++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_removeAllExcept_basic.phpt @@ -10,16 +10,16 @@ $b = (object) 'b'; $c = (object) 'c'; $foo = new SplObjectStorage; -$foo->attach($a); -$foo->attach($b); +$foo->offsetSet($a); +$foo->offsetSet($b); $bar = new SplObjectStorage; -$bar->attach($b); -$bar->attach($c); +$bar->offsetSet($b); +$bar->offsetSet($c); $foo->removeAllExcept($bar); -var_dump($foo->contains($a)); -var_dump($foo->contains($b)); +var_dump($foo->offsetExists($a)); +var_dump($foo->offsetExists($b)); ?> --EXPECT-- diff --git a/ext/spl/tests/SplObjectStorage_seek.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt similarity index 97% rename from ext/spl/tests/SplObjectStorage_seek.phpt rename to ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt index f51a285d0600..ce21b2a621fe 100644 --- a/ext/spl/tests/SplObjectStorage_seek.phpt +++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt @@ -64,8 +64,8 @@ var_dump($storage->current()); echo "--- With holes cases ---\n"; -$storage->detach($b); -$storage->detach($d); +$storage->offsetUnset($b); +$storage->offsetUnset($d); foreach (range(0, 2) as $index) { $storage->seek($index); diff --git a/ext/spl/tests/SplObjectStorage/bug49263.phpt b/ext/spl/tests/SplObjectStorage/bug49263.phpt index 23bd0b272a74..a8088f180790 100644 --- a/ext/spl/tests/SplObjectStorage/bug49263.phpt +++ b/ext/spl/tests/SplObjectStorage/bug49263.phpt @@ -7,8 +7,8 @@ $o2 = new stdClass; $s = new SplObjectStorage(); -$s->attach($o1, array('prev' => 2, 'next' => $o2)); -$s->attach($o2, array('prev' => $o1)); +$s->offsetSet($o1, array('prev' => 2, 'next' => $o2)); +$s->offsetSet($o2, array('prev' => $o1)); $ss = serialize($s); unset($s,$o1,$o2); diff --git a/ext/spl/tests/SplObjectStorage/bug53071.phpt b/ext/spl/tests/SplObjectStorage/bug53071.phpt index e3bd5e1155b3..0f0800d13efa 100644 --- a/ext/spl/tests/SplObjectStorage/bug53071.phpt +++ b/ext/spl/tests/SplObjectStorage/bug53071.phpt @@ -13,8 +13,8 @@ function LimitedScope() $myB = new SplObjectStorage(); $myC = new myClass(); $myC->member = $myA; // myC has a reference to myA - $myB->Attach($myC); // myB attaches myC - $myA->member = $myB; // myA has myB, comleting the cycle + $myB->offsetSet($myC); // myB attaches myC + $myA->member = $myB; // myA has myB, completing the cycle } LimitedScope(); var_dump(gc_collect_cycles()); diff --git a/ext/spl/tests/SplObjectStorage/bug67582.phpt b/ext/spl/tests/SplObjectStorage/bug67582.phpt index dc0cd532321e..86a11e516ae1 100644 --- a/ext/spl/tests/SplObjectStorage/bug67582.phpt +++ b/ext/spl/tests/SplObjectStorage/bug67582.phpt @@ -11,7 +11,7 @@ class MyObjectStorage extends SplObjectStorage { class TestObject {} $list = new MyObjectStorage(); -$list->attach(new TestObject()); +$list->offsetSet(new TestObject()); foreach($list as $x) var_dump($list->offsetExists($x)); diff --git a/ext/spl/tests/SplObjectStorage/bug69108.phpt b/ext/spl/tests/SplObjectStorage/bug69108.phpt index 3122da599c64..3579164791d6 100644 --- a/ext/spl/tests/SplObjectStorage/bug69108.phpt +++ b/ext/spl/tests/SplObjectStorage/bug69108.phpt @@ -9,7 +9,7 @@ $b = new SplObjectStorage(); for ($i = 10000; $i > 0; $i--) { $object = new StdClass(); $a[] = $object; - $b->attach($object); + $b->offsetSet($object); } $c = serialize(array($a, $b)); diff --git a/ext/spl/tests/SplObjectStorage/bug69227.phpt b/ext/spl/tests/SplObjectStorage/bug69227.phpt index 812d8bafd8a3..5a527d17df3a 100644 --- a/ext/spl/tests/SplObjectStorage/bug69227.phpt +++ b/ext/spl/tests/SplObjectStorage/bug69227.phpt @@ -6,7 +6,7 @@ zend.enable_gc=1 attach($s); +$s->offsetSet($s); gc_collect_cycles(); echo "ok"; ?> diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt new file mode 100644 index 000000000000..9da6270b6d7d --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt @@ -0,0 +1,62 @@ +--TEST-- +SplObjectStorage: Mutation during getHash is prohibited +--CREDITS-- +cnitlrt +--FILE-- +mutate) { + $victim[new stdClass()] = null; + } + return spl_object_hash($obj); + } +} + +function populate(SplObjectStorage $victim, SplObjectStorage $other): void { + for ($i = 0; $i < 1024; $i++) { + $o = new stdClass(); + $victim[$o] = null; + $other[$o] = null; + } +} + +$victim = new SplObjectStorage(); +$other = new EvilStorage(); + +populate($victim, $other); +$other->mutate = true; + +try { + $victim->removeAllExcept($other); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($victim), count($other)); + +unset($victim, $other); +$victim = new SplObjectStorage(); +$other = new EvilStorage(); + +populate($victim, $other); +$other->mutate = true; + +try { + $other->addAll($victim); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($victim), count($other)); +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(1024) +int(1024) +Modification of SplObjectStorage during getHash() is prohibited +int(1024) +int(1024) diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt new file mode 100644 index 000000000000..aadbe2acba27 --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt @@ -0,0 +1,32 @@ +--TEST-- +SplObjectStorage: Mutation during getHash is prohibited during addAll +--CREDITS-- +cnitlrt +--FILE-- +addAll($storage); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($evil), count($storage)); + +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(0) +int(1) diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt new file mode 100644 index 000000000000..2602bc9e1f03 --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt @@ -0,0 +1,32 @@ +--TEST-- +SplObjectStorage: Mutation during getHash is prohibited during removeAllExcept +--CREDITS-- +cnitlrt +--FILE-- +removeAllExcept($evil); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($evil), count($storage)); + +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(0) +int(1) diff --git a/ext/spl/tests/gh14639.phpt b/ext/spl/tests/SplObjectStorage/gh14639.phpt similarity index 94% rename from ext/spl/tests/gh14639.phpt rename to ext/spl/tests/SplObjectStorage/gh14639.phpt index 1b6f621d27bd..41260855b252 100644 --- a/ext/spl/tests/gh14639.phpt +++ b/ext/spl/tests/SplObjectStorage/gh14639.phpt @@ -14,7 +14,7 @@ $b = new SplObjectStorage(); for ($i = 10000; $i > 0; $i--) { $object = new StdClass(); $object->a = str_repeat("a", 2); - $b->attach($object); + $b->offsetSet($object); } ?> --EXPECTF-- diff --git a/ext/spl/tests/SplObjectStorage/gh21831.phpt b/ext/spl/tests/SplObjectStorage/gh21831.phpt new file mode 100644 index 000000000000..581012d86a4f --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/gh21831.phpt @@ -0,0 +1,36 @@ +--TEST-- +GH-21831: SplObjectStorage::getHash() cannot mutate storage during removeAllExcept() +--FILE-- +other) { + $this->other->offsetUnset($obj); + $this->other = null; + } + + return 'x'; + } +} + +$storage = new SplObjectStorage(); +$storage[new stdClass()] = null; + +$filter = new FilterStorage(); +$filter->other = $storage; + +try { + $storage->removeAllExcept($filter); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +var_dump(count($storage)); + +?> +--EXPECT-- +Modification of SplObjectStorage during getHash() is prohibited +int(1) diff --git a/ext/spl/tests/observer_001.phpt b/ext/spl/tests/SplObjectStorage/observer_001.phpt similarity index 100% rename from ext/spl/tests/observer_001.phpt rename to ext/spl/tests/SplObjectStorage/observer_001.phpt diff --git a/ext/spl/tests/observer_002.phpt b/ext/spl/tests/SplObjectStorage/observer_002.phpt similarity index 96% rename from ext/spl/tests/observer_002.phpt rename to ext/spl/tests/SplObjectStorage/observer_002.phpt index 74bf3d4b930b..227122b637de 100644 --- a/ext/spl/tests/observer_002.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_002.phpt @@ -70,13 +70,13 @@ class SubjectImpl implements SplSubject function attach(SplObserver $observer): void { echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n"; - $this->observers->attach($observer); + $this->observers->offsetSet($observer); } function detach(SplObserver $observer): void { echo $this->name . '->' . __METHOD__ . '(' . $observer->getName() . ");\n"; - $this->observers->detach($observer); + $this->observers->offsetUnset($observer); } function count(): int @@ -100,7 +100,7 @@ class SubjectImpl implements SplSubject function contains($obj) { - return $this->observers->contains($obj); + return $this->observers->offsetExists($obj); } } diff --git a/ext/spl/tests/observer_003.phpt b/ext/spl/tests/SplObjectStorage/observer_003.phpt similarity index 93% rename from ext/spl/tests/observer_003.phpt rename to ext/spl/tests/SplObjectStorage/observer_003.phpt index 36ead9233658..7708c526f947 100644 --- a/ext/spl/tests/observer_003.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_003.phpt @@ -17,7 +17,7 @@ $storage = new SplObjectStorage(); foreach(array(1,"2","foo",true) as $value) { - $storage->attach(new TestClass($value)); + $storage->offsetSet(new TestClass($value)); } var_dump(count($storage)); diff --git a/ext/spl/tests/observer_004.phpt b/ext/spl/tests/SplObjectStorage/observer_004.phpt similarity index 97% rename from ext/spl/tests/observer_004.phpt rename to ext/spl/tests/SplObjectStorage/observer_004.phpt index b0b25ec117a7..96d2e5b99998 100644 --- a/ext/spl/tests/observer_004.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_004.phpt @@ -27,7 +27,7 @@ $storage = new MyStorage(); foreach(array(1,2) as $value) { - $storage->attach(new TestClass($value)); + $storage->offsetSet(new TestClass($value)); } var_dump(count($storage)); diff --git a/ext/spl/tests/observer_005.phpt b/ext/spl/tests/SplObjectStorage/observer_005.phpt similarity index 97% rename from ext/spl/tests/observer_005.phpt rename to ext/spl/tests/SplObjectStorage/observer_005.phpt index 833b978d7252..b5b3669b870a 100644 --- a/ext/spl/tests/observer_005.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_005.phpt @@ -45,7 +45,7 @@ $storage = new MyStorage(1,2,3); foreach(array(array(4,5,6),array(7,8,9)) as $value) { - $storage->attach(new TestClass($value[0], $value[1], $value[2])); + $storage->offsetSet(new TestClass($value[0], $value[1], $value[2])); } var_dump(count($storage)); diff --git a/ext/spl/tests/observer_006.phpt b/ext/spl/tests/SplObjectStorage/observer_006.phpt similarity index 95% rename from ext/spl/tests/observer_006.phpt rename to ext/spl/tests/SplObjectStorage/observer_006.phpt index d1e535227970..afd40e9b122a 100644 --- a/ext/spl/tests/observer_006.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_006.phpt @@ -27,7 +27,7 @@ $storage = new MyStorage(); foreach(array(1=>"foo",2=>42) as $key => $value) { - $storage->attach(new TestClass($key), $value); + $storage->offsetSet(new TestClass($key), $value); } var_dump(count($storage)); @@ -52,8 +52,8 @@ foreach($storage2 as $object) } var_dump($storage2); -$storage->attach(new TestClass(3), new stdClass); -$storage->attach(new TestClass(4), new TestClass(5)); +$storage->offsetSet(new TestClass(3), new stdClass); +$storage->offsetSet(new TestClass(4), new TestClass(5)); echo "===UNSERIALIZE2===\n"; var_dump(unserialize(serialize($storage))); $storage->rewind(); @@ -70,7 +70,7 @@ $storage->next(); $storage->next(); var_dump($storage->key()); var_dump($storage->current()); -$storage->attach($storage->current(), "replaced"); +$storage->offsetSet($storage->current(), "replaced"); echo "===UNSERIALIZE4===\n"; var_dump(unserialize(serialize($storage))); diff --git a/ext/spl/tests/observer_007.phpt b/ext/spl/tests/SplObjectStorage/observer_007.phpt similarity index 100% rename from ext/spl/tests/observer_007.phpt rename to ext/spl/tests/SplObjectStorage/observer_007.phpt diff --git a/ext/spl/tests/SplObjectStorage/observer_008.phpt b/ext/spl/tests/SplObjectStorage/observer_008.phpt new file mode 100644 index 000000000000..36769c57d524 --- /dev/null +++ b/ext/spl/tests/SplObjectStorage/observer_008.phpt @@ -0,0 +1,32 @@ +--TEST-- +SPL: SplObjectStorage addAll/removeAll +--FILE-- +offsetSet($o1); +$a->offsetSet($o2); + +$b = new SplObjectStorage(); +$b->offsetSet($o2); +$b->offsetSet($o3); + +$a->offsetUnset($b); + +var_dump($a->count()); + +$a->offsetUnset($o3); +var_dump($a->count()); + +$a->removeAll($b); +var_dump($a->count()); +?> +--EXPECT-- +int(2) +int(2) +int(1) diff --git a/ext/spl/tests/observer_009.phpt b/ext/spl/tests/SplObjectStorage/observer_009.phpt similarity index 87% rename from ext/spl/tests/observer_009.phpt rename to ext/spl/tests/SplObjectStorage/observer_009.phpt index 58f49980846b..0b402c1d31e0 100644 --- a/ext/spl/tests/observer_009.phpt +++ b/ext/spl/tests/SplObjectStorage/observer_009.phpt @@ -5,8 +5,8 @@ SPL: SplObjectStorage addAll/removeAll class Foo {} $storageA = new \SplObjectStorage(); -$storageA->attach(new \Foo); -$storageA->attach(new \Foo); +$storageA->offsetSet(new \Foo); +$storageA->offsetSet(new \Foo); echo ("Count storage A: " . count($storageA)); foreach ($storageA as $object) { diff --git a/ext/spl/tests/observer_010.phpt b/ext/spl/tests/SplObjectStorage/observer_010.phpt similarity index 100% rename from ext/spl/tests/observer_010.phpt rename to ext/spl/tests/SplObjectStorage/observer_010.phpt diff --git a/ext/spl/tests/SplPriorityQueue_serialize_complex.phpt b/ext/spl/tests/SplPriorityQueue_serialize_complex.phpt new file mode 100644 index 000000000000..61a3cb1aa869 --- /dev/null +++ b/ext/spl/tests/SplPriorityQueue_serialize_complex.phpt @@ -0,0 +1,113 @@ +--TEST-- +SplPriorityQueue serialization with mixed data types and extract flags +--FILE-- +setExtractFlags(SplPriorityQueue::EXTR_BOTH); + +$array1 = ['name' => 'John', 'hobbies' => ['reading', 'gaming']]; +$queue->insert($array1, 10); + +class TestClass { + public $prop = 'test'; +} +$obj1 = new TestClass(); +$queue->insert($obj1, 15); + +$queue->insert(3.14159, 12); +$queue->insert(true, 20); +$queue->insert(null, 3); + +$serialized = serialize($queue); +echo $serialized . "\n"; + +$unserialized = unserialize($serialized); +var_dump($unserialized); + +$queue2 = new SplPriorityQueue(); +$queue2->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY); +$queue2->insert("data", 42); + +$serialized2 = serialize($queue2); +echo $serialized2 . "\n"; + +$unserialized2 = unserialize($serialized2); +var_dump($unserialized2); + +?> +--EXPECT-- +O:16:"SplPriorityQueue":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:3;s:13:"heap_elements";a:5:{i:0;a:2:{s:4:"data";b:1;s:8:"priority";i:20;}i:1;a:2:{s:4:"data";O:9:"TestClass":1:{s:4:"prop";s:4:"test";}s:8:"priority";i:15;}i:2;a:2:{s:4:"data";d:3.14159;s:8:"priority";i:12;}i:3;a:2:{s:4:"data";a:2:{s:4:"name";s:4:"John";s:7:"hobbies";a:2:{i:0;s:7:"reading";i:1;s:6:"gaming";}}s:8:"priority";i:10;}i:4;a:2:{s:4:"data";N;s:8:"priority";i:3;}}}} +object(SplPriorityQueue)#3 (3) { + ["flags":"SplPriorityQueue":private]=> + int(3) + ["isCorrupted":"SplPriorityQueue":private]=> + bool(false) + ["heap":"SplPriorityQueue":private]=> + array(5) { + [0]=> + array(2) { + ["data"]=> + bool(true) + ["priority"]=> + int(20) + } + [1]=> + array(2) { + ["data"]=> + object(TestClass)#4 (1) { + ["prop"]=> + string(4) "test" + } + ["priority"]=> + int(15) + } + [2]=> + array(2) { + ["data"]=> + float(3.14159) + ["priority"]=> + int(12) + } + [3]=> + array(2) { + ["data"]=> + array(2) { + ["name"]=> + string(4) "John" + ["hobbies"]=> + array(2) { + [0]=> + string(7) "reading" + [1]=> + string(6) "gaming" + } + } + ["priority"]=> + int(10) + } + [4]=> + array(2) { + ["data"]=> + NULL + ["priority"]=> + int(3) + } + } +} +O:16:"SplPriorityQueue":2:{i:0;a:0:{}i:1;a:2:{s:5:"flags";i:2;s:13:"heap_elements";a:1:{i:0;a:2:{s:4:"data";s:4:"data";s:8:"priority";i:42;}}}} +object(SplPriorityQueue)#6 (3) { + ["flags":"SplPriorityQueue":private]=> + int(2) + ["isCorrupted":"SplPriorityQueue":private]=> + bool(false) + ["heap":"SplPriorityQueue":private]=> + array(1) { + [0]=> + array(2) { + ["data"]=> + string(4) "data" + ["priority"]=> + int(42) + } + } +} diff --git a/ext/spl/tests/SplPriorityQueue_unserialize_invalid_flags.phpt b/ext/spl/tests/SplPriorityQueue_unserialize_invalid_flags.phpt new file mode 100644 index 000000000000..8c785606c7fe --- /dev/null +++ b/ext/spl/tests/SplPriorityQueue_unserialize_invalid_flags.phpt @@ -0,0 +1,80 @@ +--TEST-- +SplPriorityQueue unserialization with invalid flags should throw exception +--FILE-- + 4, // invalid flag value (4 & 3 = 0) + 'heap_elements' => [] + ] + ]; + + $queue = new SplPriorityQueue(); + $queue->__unserialize($data); + echo "Should have thrown exception for invalid flags\n"; +} catch (Exception $e) { + echo "Exception thrown for invalid flags: " . $e->getMessage() . "\n"; +} + +try { + $data = [ + [], + [ + 'flags' => 0, + 'heap_elements' => [] + ] + ]; + + $queue = new SplPriorityQueue(); + $queue->__unserialize($data); + echo "Should have thrown exception for zero flags\n"; +} catch (Exception $e) { + echo "Exception thrown for zero flags: " . $e->getMessage() . "\n"; +} + +try { + $data = [ + [], + [ + 'flags' => SplPriorityQueue::EXTR_DATA, + 'heap_elements' => [] + ] + ]; + + $queue = new SplPriorityQueue(); + $queue->__unserialize($data); + echo "Valid flags accepted\n"; +} catch (Exception $e) { + echo "Valid flags rejected: " . $e->getMessage() . "\n"; +} + +try { + $data = [ + [], + [ + 'flags' => 999, // extra bits that should be masked to 3 (EXTR_BOTH) + 'heap_elements' => [] + ] + ]; + + $queue = new SplPriorityQueue(); + $queue->__unserialize($data); + + if ($queue->getExtractFlags() === SplPriorityQueue::EXTR_BOTH) { + echo "Flags properly masked\n"; + } else { + echo "Flags not properly masked, got: " . $queue->getExtractFlags() . "\n"; + } +} catch (Exception $e) { + echo "Flags with extra bits should be masked: " . $e->getMessage() . "\n"; +} + +?> +--EXPECT-- +Exception thrown for invalid flags: Invalid serialization data for SplPriorityQueue object +Exception thrown for zero flags: Invalid serialization data for SplPriorityQueue object +Valid flags accepted +Flags properly masked diff --git a/ext/spl/tests/arrayObject___construct_basic1.phpt b/ext/spl/tests/arrayObject___construct_basic1.phpt deleted file mode 100644 index a14166c35e30..000000000000 --- a/ext/spl/tests/arrayObject___construct_basic1.phpt +++ /dev/null @@ -1,52 +0,0 @@ ---TEST-- -SPL: ArrayObject::__construct basic usage. ---FILE-- - No arguments:\n"; -var_dump(new ArrayObject()); - -echo "--> Object argument:\n"; -$a = new stdClass; -$a->p = 'hello'; -var_dump(new ArrayObject($a)); - -echo "--> Array argument:\n"; -var_dump(new ArrayObject(array('key1' => 'val1'))); - -echo "--> Nested ArrayObject argument:\n"; -var_dump(new ArrayObject(new ArrayObject($a))); -?> ---EXPECT-- ---> No arguments: -object(ArrayObject)#1 (1) { - ["storage":"ArrayObject":private]=> - array(0) { - } -} ---> Object argument: -object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - object(stdClass)#1 (1) { - ["p"]=> - string(5) "hello" - } -} ---> Array argument: -object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - array(1) { - ["key1"]=> - string(4) "val1" - } -} ---> Nested ArrayObject argument: -object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - object(ArrayObject)#3 (1) { - ["storage":"ArrayObject":private]=> - object(stdClass)#1 (1) { - ["p"]=> - string(5) "hello" - } - } -} diff --git a/ext/spl/tests/arrayObject___construct_basic7.phpt b/ext/spl/tests/arrayObject___construct_basic7.phpt deleted file mode 100644 index dd10b5fb6b99..000000000000 --- a/ext/spl/tests/arrayObject___construct_basic7.phpt +++ /dev/null @@ -1,34 +0,0 @@ ---TEST-- -SPL: ArrayObject::__construct: Using object with shared properties ---FILE-- -asort(); -var_dump($a, $o, $ao); -?> ---EXPECT-- -array(2) { - [0]=> - int(2) - [1]=> - int(1) -} -object(stdClass)#1 (2) { - ["1"]=> - int(1) - ["0"]=> - int(2) -} -object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - object(stdClass)#1 (2) { - ["1"]=> - int(1) - ["0"]=> - int(2) - } -} diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic2.phpt b/ext/spl/tests/arrayObject_exchangeArray_basic2.phpt deleted file mode 100644 index 1f037e90735b..000000000000 --- a/ext/spl/tests/arrayObject_exchangeArray_basic2.phpt +++ /dev/null @@ -1,97 +0,0 @@ ---TEST-- -SPL: ArrayObject::exchangeArray() with various object arguments ---FILE-- - exchangeArray(array):\n"; -$ao = new ArrayObject(); -$ao->exchangeArray(array('key'=>'original')); -var_dump($ao['key']); -var_dump($ao); - -echo "\n--> exchangeArray(normal object):\n"; -$obj = new stdClass; -$obj->key = 'normal object prop'; -$ao->exchangeArray($obj); -var_dump($ao['key']); -var_dump($ao); - -echo "\n--> exchangeArray(ArrayObject):\n"; -$obj = new ArrayObject(array('key'=>'ArrayObject element')); -$ao->exchangeArray($obj); -var_dump($ao['key']); -var_dump($ao); - -echo "\n--> exchangeArray(ArrayIterator):\n"; -$obj = new ArrayIterator(array('key'=>'ArrayIterator element')); -$ao->exchangeArray($obj); -var_dump($ao['key']); -var_dump($ao); - -echo "\n--> exchangeArray(nested ArrayObject):\n"; -$obj = new ArrayObject(new ArrayObject(array('key'=>'nested ArrayObject element'))); -$ao->exchangeArray($obj); -var_dump($ao['key']); -var_dump($ao); -?> ---EXPECTF-- ---> exchangeArray(array): -string(8) "original" -object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - array(1) { - ["key"]=> - string(8) "original" - } -} - ---> exchangeArray(normal object): -string(18) "normal object prop" -object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - object(stdClass)#%d (1) { - ["key"]=> - string(18) "normal object prop" - } -} - ---> exchangeArray(ArrayObject): -string(19) "ArrayObject element" -object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - array(1) { - ["key"]=> - string(19) "ArrayObject element" - } - } -} - ---> exchangeArray(ArrayIterator): -string(21) "ArrayIterator element" -object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - object(ArrayIterator)#%d (1) { - ["storage":"ArrayIterator":private]=> - array(1) { - ["key"]=> - string(21) "ArrayIterator element" - } - } -} - ---> exchangeArray(nested ArrayObject): -string(26) "nested ArrayObject element" -object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - object(ArrayObject)#%d (1) { - ["storage":"ArrayObject":private]=> - array(1) { - ["key"]=> - string(26) "nested ArrayObject element" - } - } - } -} diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt b/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt deleted file mode 100644 index 49b990be8bdf..000000000000 --- a/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt +++ /dev/null @@ -1,125 +0,0 @@ ---TEST-- -SPL: ArrayObject::exchangeArray() basic usage with object as underlying data store. ---FILE-- - exchangeArray() with objects:\n"; -$original = new C; -$ao = new ArrayObject($original); -$swapIn = new C; -try { - $copy = $ao->exchangeArray($swapIn); - $copy['addedToCopy'] = 'added To Copy'; -} catch (Exception $e) { - echo "Exception:" . $e->getMessage() . "\n"; -} -$swapIn->addedToSwapIn = 'added To Swap-In'; -$original->addedToOriginal = 'added To Original'; -var_dump($ao, $original, $swapIn, $copy); - - -echo "\n\n--> exchangeArray() with no arg:\n"; -unset($original, $ao, $swapIn, $copy); -$original = new C; -$ao = new ArrayObject($original); -try { - $copy = $ao->exchangeArray(); - $copy['addedToCopy'] = 'added To Copy'; -} catch (TypeError $e) { - echo "Exception: " . $e->getMessage() . "\n"; -} -$original->addedToOriginal = 'added To Original'; -var_dump($ao, $original, $copy); - -echo "\n\n--> exchangeArray() with bad arg type:\n"; -unset($original, $ao, $swapIn, $copy); -$original = new C; -$ao = new ArrayObject($original); -try { - $copy = $ao->exchangeArray(null); - $copy['addedToCopy'] = 'added To Copy'; -} catch (TypeError $e) { - echo $e->getMessage() . "\n"; -} -$original->addedToOriginal = 'added To Original'; -var_dump($ao, $original, $copy); - -?> ---EXPECTF-- ---> exchangeArray() with objects: -object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - object(C)#3 (2) { - ["pub1"]=> - string(7) "public1" - ["addedToSwapIn"]=> - string(16) "added To Swap-In" - } -} -object(C)#1 (2) { - ["pub1"]=> - string(7) "public1" - ["addedToOriginal"]=> - string(17) "added To Original" -} -object(C)#3 (2) { - ["pub1"]=> - string(7) "public1" - ["addedToSwapIn"]=> - string(16) "added To Swap-In" -} -array(2) { - ["pub1"]=> - string(7) "public1" - ["addedToCopy"]=> - string(13) "added To Copy" -} - - ---> exchangeArray() with no arg: -Exception: ArrayObject::exchangeArray() expects exactly 1 argument, 0 given - -Warning: Undefined variable $copy in %s on line %d -object(ArrayObject)#2 (1) { - ["storage":"ArrayObject":private]=> - object(C)#3 (2) { - ["pub1"]=> - string(7) "public1" - ["addedToOriginal"]=> - string(17) "added To Original" - } -} -object(C)#3 (2) { - ["pub1"]=> - string(7) "public1" - ["addedToOriginal"]=> - string(17) "added To Original" -} -NULL - - ---> exchangeArray() with bad arg type: -ArrayObject::exchangeArray(): Argument #1 ($array) must be of type array, null given - -Warning: Undefined variable $copy in %s on line %d -object(ArrayObject)#3 (1) { - ["storage":"ArrayObject":private]=> - object(C)#2 (2) { - ["pub1"]=> - string(7) "public1" - ["addedToOriginal"]=> - string(17) "added To Original" - } -} -object(C)#2 (2) { - ["pub1"]=> - string(7) "public1" - ["addedToOriginal"]=> - string(17) "added To Original" -} -NULL diff --git a/ext/spl/tests/arrayObject_getFlags_basic1.phpt b/ext/spl/tests/arrayObject_getFlags_basic1.phpt deleted file mode 100644 index 612a753680a3..000000000000 --- a/ext/spl/tests/arrayObject_getFlags_basic1.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---TEST-- -SPL: ArrayObject::getFlags() basic usage ---FILE-- -getFlags()); - -$ao = new ArrayObject(new ArrayObject(array(1,2,3)), ArrayObject::STD_PROP_LIST); -var_dump($ao->getFlags()); - -$ao = new ArrayObject(new ArrayIterator(new ArrayObject()), ArrayObject::ARRAY_AS_PROPS); -var_dump($ao->getFlags()); - -$ao = new ArrayObject(new ArrayObject(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); -var_dump($ao->getFlags()); - -$cao = clone $ao; -var_dump($cao->getFlags()); -?> ---EXPECT-- -int(0) -int(1) -int(2) -int(3) -int(3) diff --git a/ext/spl/tests/arrayObject_getFlags_basic2.phpt b/ext/spl/tests/arrayObject_getFlags_basic2.phpt deleted file mode 100644 index db44322d674f..000000000000 --- a/ext/spl/tests/arrayObject_getFlags_basic2.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -SPL: ArrayObject::getFlags() - ensure flags are passed on to nested array objects and iterators. ---FILE-- -getFlags()); - -$ao2 = new ArrayObject($ao); -var_dump($ao2->getFlags()); -var_dump($ao2->getIterator()->getFlags()); - -$ai = new ArrayIterator($ao); -var_dump($ai->getFlags()); - -$ao2 = new ArrayObject($ao, 0); -var_dump($ao2->getFlags()); - -?> ---EXPECT-- -int(3) -int(3) -int(3) -int(3) -int(0) diff --git a/ext/spl/tests/array_022.phpt b/ext/spl/tests/array_022.phpt deleted file mode 100644 index f7407bf602c7..000000000000 --- a/ext/spl/tests/array_022.phpt +++ /dev/null @@ -1,68 +0,0 @@ ---TEST-- -SPL: ArrayObject/Iterator and reference to self ---FILE-- -==ArrayObject=== - -==ArrayIterator=== - ---EXPECTF-- -==ArrayObject=== -object(MyArrayObject)#%d (1) { - ["bar"]=> - string(3) "baz" -} -object(MyArrayObject)#%d (2) { - ["bar"]=> - string(3) "baz" - ["baz"]=> - string(3) "Foo" -} -==ArrayIterator=== -object(MyArrayIterator)#%d (1) { - ["bar"]=> - string(3) "baz" -} -object(MyArrayIterator)#%d (2) { - ["bar"]=> - string(3) "baz" - ["baz"]=> - string(3) "Foo" -} diff --git a/ext/spl/tests/array_025.phpt b/ext/spl/tests/array_025.phpt deleted file mode 100644 index d64f8f04c1e1..000000000000 --- a/ext/spl/tests/array_025.phpt +++ /dev/null @@ -1,40 +0,0 @@ ---TEST-- -SPL: ArrayObject serialize with an object as storage ---FILE-- - ---EXPECT-- -ArrayObject Object -( - [storage:ArrayObject:private] => ArrayObject Object - ( - [storage:ArrayObject:private] => Array - ( - [0] => 1 - [1] => 2 - ) - - ) - -) -O:11:"ArrayObject":4:{i:0;i:0;i:1;O:11:"ArrayObject":4:{i:0;i:0;i:1;a:2:{i:0;i:1;i:1;i:2;}i:2;a:0:{}i:3;N;}i:2;a:0:{}i:3;N;} -ArrayObject Object -( - [storage:ArrayObject:private] => ArrayObject Object - ( - [storage:ArrayObject:private] => Array - ( - [0] => 1 - [1] => 2 - ) - - ) - -) diff --git a/ext/spl/tests/array_028.phpt b/ext/spl/tests/array_028.phpt deleted file mode 100644 index 1adcdd3f9071..000000000000 --- a/ext/spl/tests/array_028.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -ArrayObject/Iterator on array with NUL bytes ---FILE-- - "bar", -]; - -$it = new ArrayIterator($array); -foreach ($it as $v) { - var_dump($v); -} - -$obj = new ArrayObject($array); -foreach ($obj as $v) { - var_dump($v); -} - -$obj = new ArrayObject($it); -foreach ($obj as $v) { - var_dump($v); -} -?> ---EXPECT-- -string(3) "bar" -string(3) "bar" -string(3) "bar" diff --git a/ext/spl/tests/bug38325.phpt b/ext/spl/tests/autoloading/bug38325.phpt similarity index 100% rename from ext/spl/tests/bug38325.phpt rename to ext/spl/tests/autoloading/bug38325.phpt diff --git a/ext/spl/tests/bug40091.phpt b/ext/spl/tests/autoloading/bug40091.phpt similarity index 100% rename from ext/spl/tests/bug40091.phpt rename to ext/spl/tests/autoloading/bug40091.phpt diff --git a/ext/spl/tests/bug44144.phpt b/ext/spl/tests/autoloading/bug44144.phpt similarity index 100% rename from ext/spl/tests/bug44144.phpt rename to ext/spl/tests/autoloading/bug44144.phpt diff --git a/ext/spl/tests/bug48023.phpt b/ext/spl/tests/autoloading/bug48023.phpt similarity index 100% rename from ext/spl/tests/bug48023.phpt rename to ext/spl/tests/autoloading/bug48023.phpt diff --git a/ext/spl/tests/bug48493.phpt b/ext/spl/tests/autoloading/bug48493.phpt similarity index 100% rename from ext/spl/tests/bug48493.phpt rename to ext/spl/tests/autoloading/bug48493.phpt diff --git a/ext/spl/tests/bug52339.phpt b/ext/spl/tests/autoloading/bug52339.phpt similarity index 100% rename from ext/spl/tests/bug52339.phpt rename to ext/spl/tests/autoloading/bug52339.phpt diff --git a/ext/spl/tests/bug61697.phpt b/ext/spl/tests/autoloading/bug61697.phpt similarity index 100% rename from ext/spl/tests/bug61697.phpt rename to ext/spl/tests/autoloading/bug61697.phpt diff --git a/ext/spl/tests/bug65006.phpt b/ext/spl/tests/autoloading/bug65006.phpt similarity index 100% rename from ext/spl/tests/bug65006.phpt rename to ext/spl/tests/autoloading/bug65006.phpt diff --git a/ext/spl/tests/bug71202.phpt b/ext/spl/tests/autoloading/bug71202.phpt similarity index 100% rename from ext/spl/tests/bug71202.phpt rename to ext/spl/tests/autoloading/bug71202.phpt diff --git a/ext/spl/tests/autoloading/bug71204.phpt b/ext/spl/tests/autoloading/bug71204.phpt new file mode 100644 index 000000000000..3669597a0844 --- /dev/null +++ b/ext/spl/tests/autoloading/bug71204.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #71204 (segfault if clean spl_autoload_funcs while autoloading ) +--FILE-- + +--EXPECTF-- +Deprecated: spl_autoload_unregister(): Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated, to remove all registered autoloaders, call spl_autoload_unregister() for all values returned from spl_autoload_functions() in %s on line %d + +Fatal error: Uncaught Error: Class "A" not found in %s:%d +Stack trace: +#0 {main} + thrown in %sbug71204.php on line %d diff --git a/ext/spl/tests/bug71236.phpt b/ext/spl/tests/autoloading/bug71236.phpt similarity index 100% rename from ext/spl/tests/bug71236.phpt rename to ext/spl/tests/autoloading/bug71236.phpt diff --git a/ext/spl/tests/bug73896.phpt b/ext/spl/tests/autoloading/bug73896.phpt similarity index 100% rename from ext/spl/tests/bug73896.phpt rename to ext/spl/tests/autoloading/bug73896.phpt diff --git a/ext/spl/tests/bug74372.phpt b/ext/spl/tests/autoloading/bug74372.phpt similarity index 100% rename from ext/spl/tests/bug74372.phpt rename to ext/spl/tests/autoloading/bug74372.phpt diff --git a/ext/spl/tests/bug75049.phpt b/ext/spl/tests/autoloading/bug75049.phpt similarity index 100% rename from ext/spl/tests/bug75049.phpt rename to ext/spl/tests/autoloading/bug75049.phpt diff --git a/ext/spl/tests/gh10011.phpt b/ext/spl/tests/autoloading/gh10011.phpt similarity index 100% rename from ext/spl/tests/gh10011.phpt rename to ext/spl/tests/autoloading/gh10011.phpt diff --git a/ext/spl/tests/spl_autoload_001.phpt b/ext/spl/tests/autoloading/spl_autoload_001.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_001.phpt rename to ext/spl/tests/autoloading/spl_autoload_001.phpt diff --git a/ext/spl/tests/spl_autoload_002.phpt b/ext/spl/tests/autoloading/spl_autoload_002.phpt similarity index 79% rename from ext/spl/tests/spl_autoload_002.phpt rename to ext/spl/tests/autoloading/spl_autoload_002.phpt index 1a67baabd0b3..2739e56e3bed 100644 --- a/ext/spl/tests/spl_autoload_002.phpt +++ b/ext/spl/tests/autoloading/spl_autoload_002.phpt @@ -35,7 +35,7 @@ spl_autoload_unregister('spl_autoload'); var_dump(spl_autoload_functions()); ?> ---EXPECT-- +--EXPECTF-- array(0) { } array(1) { @@ -56,6 +56,8 @@ array(2) { [1]=> string(16) "SplAutoloadTest2" } + +Deprecated: spl_autoload_unregister(): Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated, to remove all registered autoloaders, call spl_autoload_unregister() for all values returned from spl_autoload_functions() in %s on line %d array(0) { } array(1) { diff --git a/ext/spl/tests/spl_autoload_003.phpt b/ext/spl/tests/autoloading/spl_autoload_003.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_003.phpt rename to ext/spl/tests/autoloading/spl_autoload_003.phpt diff --git a/ext/spl/tests/spl_autoload_004.phpt b/ext/spl/tests/autoloading/spl_autoload_004.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_004.phpt rename to ext/spl/tests/autoloading/spl_autoload_004.phpt diff --git a/ext/spl/tests/spl_autoload_005.phpt b/ext/spl/tests/autoloading/spl_autoload_005.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_005.phpt rename to ext/spl/tests/autoloading/spl_autoload_005.phpt diff --git a/ext/spl/tests/spl_autoload_006.phpt b/ext/spl/tests/autoloading/spl_autoload_006.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_006.phpt rename to ext/spl/tests/autoloading/spl_autoload_006.phpt diff --git a/ext/spl/tests/spl_autoload_007.phpt b/ext/spl/tests/autoloading/spl_autoload_007.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_007.phpt rename to ext/spl/tests/autoloading/spl_autoload_007.phpt diff --git a/ext/spl/tests/spl_autoload_008.phpt b/ext/spl/tests/autoloading/spl_autoload_008.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_008.phpt rename to ext/spl/tests/autoloading/spl_autoload_008.phpt diff --git a/ext/spl/tests/spl_autoload_009.phpt b/ext/spl/tests/autoloading/spl_autoload_009.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_009.phpt rename to ext/spl/tests/autoloading/spl_autoload_009.phpt diff --git a/ext/spl/tests/spl_autoload_010.phpt b/ext/spl/tests/autoloading/spl_autoload_010.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_010.phpt rename to ext/spl/tests/autoloading/spl_autoload_010.phpt diff --git a/ext/spl/tests/spl_autoload_011.phpt b/ext/spl/tests/autoloading/spl_autoload_011.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_011.phpt rename to ext/spl/tests/autoloading/spl_autoload_011.phpt diff --git a/ext/spl/tests/spl_autoload_012.phpt b/ext/spl/tests/autoloading/spl_autoload_012.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_012.phpt rename to ext/spl/tests/autoloading/spl_autoload_012.phpt diff --git a/ext/spl/tests/spl_autoload_013.phpt b/ext/spl/tests/autoloading/spl_autoload_013.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_013.phpt rename to ext/spl/tests/autoloading/spl_autoload_013.phpt diff --git a/ext/spl/tests/spl_autoload_014.phpt b/ext/spl/tests/autoloading/spl_autoload_014.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_014.phpt rename to ext/spl/tests/autoloading/spl_autoload_014.phpt diff --git a/ext/spl/tests/spl_autoload_bug48541.phpt b/ext/spl/tests/autoloading/spl_autoload_bug48541.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_bug48541.phpt rename to ext/spl/tests/autoloading/spl_autoload_bug48541.phpt diff --git a/ext/spl/tests/spl_autoload_call_basic.phpt b/ext/spl/tests/autoloading/spl_autoload_call_basic.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_call_basic.phpt rename to ext/spl/tests/autoloading/spl_autoload_call_basic.phpt diff --git a/ext/spl/tests/spl_autoload_called_scope.phpt b/ext/spl/tests/autoloading/spl_autoload_called_scope.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_called_scope.phpt rename to ext/spl/tests/autoloading/spl_autoload_called_scope.phpt diff --git a/ext/spl/tests/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt b/ext/spl/tests/autoloading/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt rename to ext/spl/tests/autoloading/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt diff --git a/ext/spl/tests/autoloading/spl_autoload_unregister_without_registrations.phpt b/ext/spl/tests/autoloading/spl_autoload_unregister_without_registrations.phpt new file mode 100644 index 000000000000..867a67e6eb52 --- /dev/null +++ b/ext/spl/tests/autoloading/spl_autoload_unregister_without_registrations.phpt @@ -0,0 +1,12 @@ +--TEST-- +spl_autoload_unregister("spl_autoload_call") without registrations +--FILE-- + +Done +--EXPECTF-- + +Deprecated: spl_autoload_unregister(): Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated, to remove all registered autoloaders, call spl_autoload_unregister() for all values returned from spl_autoload_functions() in %s on line %d +bool(true) +Done diff --git a/ext/spl/tests/spl_autoload_warn_on_false_do_throw.phpt b/ext/spl/tests/autoloading/spl_autoload_warn_on_false_do_throw.phpt similarity index 100% rename from ext/spl/tests/spl_autoload_warn_on_false_do_throw.phpt rename to ext/spl/tests/autoloading/spl_autoload_warn_on_false_do_throw.phpt diff --git a/ext/spl/tests/testclass b/ext/spl/tests/autoloading/testclass similarity index 100% rename from ext/spl/tests/testclass rename to ext/spl/tests/autoloading/testclass diff --git a/ext/spl/tests/testclass.class.inc b/ext/spl/tests/autoloading/testclass.class.inc similarity index 100% rename from ext/spl/tests/testclass.class.inc rename to ext/spl/tests/autoloading/testclass.class.inc diff --git a/ext/spl/tests/testclass.inc b/ext/spl/tests/autoloading/testclass.inc similarity index 100% rename from ext/spl/tests/testclass.inc rename to ext/spl/tests/autoloading/testclass.inc diff --git a/ext/spl/tests/testclass.php.inc b/ext/spl/tests/autoloading/testclass.php.inc similarity index 100% rename from ext/spl/tests/testclass.php.inc rename to ext/spl/tests/autoloading/testclass.php.inc diff --git a/ext/spl/tests/bug31346.phpt b/ext/spl/tests/bug31346.phpt deleted file mode 100644 index b2d29905ac76..000000000000 --- a/ext/spl/tests/bug31346.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -Bug #31486 (ArrayIterator::next segfaults) ---FILE-- -var1=1; - -$ao = new ArrayObject($obj); - -$i = $ao->getIterator(); - -$ao->offsetUnset($i->key()); -$i->next(); - -?> -===DONE=== ---EXPECT-- -===DONE=== diff --git a/ext/spl/tests/bug38618.phpt b/ext/spl/tests/bug38618.phpt deleted file mode 100644 index 71a09111a4b8..000000000000 --- a/ext/spl/tests/bug38618.phpt +++ /dev/null @@ -1,100 +0,0 @@ ---TEST-- -Bug #38618 (RecursiveArrayIterator::hasChildren() follows objects) ---FILE-- -title = $title; - } - - public function __toString() - { - return $this->title; - } -} - -class FruitProtected -{ - protected $title; - - public function __construct($title) - { - $this->title = $title; - } - - public function __toString() - { - return $this->title; - } -} - -function test_array($array, $which, $flags = 0) -{ - echo "===$which===\n"; - $it = new RecursiveArrayIterator($array, $flags); - foreach (new RecursiveIteratorIterator($it) as $k => $fruit) { - echo $k , ' => ', $fruit, "\n"; - } -} - -$array = array( - 1 => array( - 1 => array( - 1 => 'apple', - ), - 2 => array( - 1 => 'grape', - ), - ), -); - -test_array($array, 'Default with array'); - -$array = array( - 1 => array( - 1 => array( - 1 => new FruitPublic('apple'), - ), - 2 => array( - 1 => new FruitPublic('grape'), - ), - ), -); - -test_array($array, 'Public Property'); - -$array = array( - 1 => array( - 1 => array( - 1 => new FruitProtected('apple'), - ), - 2 => array( - 1 => new FruitProtected('grape'), - ), - ), -); - -test_array($array, 'Protected Property'); - -test_array($array, 'Public Property New', RecursiveArrayIterator::CHILD_ARRAYS_ONLY); -test_array($array, 'Protected Property New', RecursiveArrayIterator::CHILD_ARRAYS_ONLY); -?> ---EXPECT-- -===Default with array=== -1 => apple -1 => grape -===Public Property=== -title => apple -title => grape -===Protected Property=== -===Public Property New=== -1 => apple -1 => grape -===Protected Property New=== -1 => apple -1 => grape diff --git a/ext/spl/tests/bug41691.phpt b/ext/spl/tests/bug41691.phpt deleted file mode 100644 index 93af430b4884..000000000000 --- a/ext/spl/tests/bug41691.phpt +++ /dev/null @@ -1,29 +0,0 @@ ---TEST-- -Bug #41691 (ArrayObject::exchangeArray hangs Apache) ---FILE-- -exchangeArray(array('a'=>1,'b'=>1,'c'=>1))); - -echo "Done\n"; -?> ---EXPECT-- -array(3) { - ["a"]=> - NULL - ["b"]=> - NULL - ["c"]=> - NULL -} -Done diff --git a/ext/spl/tests/bug42654.phpt b/ext/spl/tests/bug42654.phpt index eb72863e0875..20aad74b7342 100644 --- a/ext/spl/tests/bug42654.phpt +++ b/ext/spl/tests/bug42654.phpt @@ -110,11 +110,11 @@ object(RecursiveArrayIterator)#%d (1) { [2]=> array(2) { [2]=> - string(5) "alter" + string(4) "val2" [3]=> array(1) { [3]=> - string(5) "alter" + string(4) "val3" } } [4]=> @@ -129,11 +129,11 @@ object(RecursiveArrayIterator)#%d (1) { [2]=> array(2) { [2]=> - string(5) "alter" + string(4) "val2" [3]=> array(1) { [3]=> - string(5) "alter" + string(4) "val3" } } [4]=> @@ -146,11 +146,11 @@ array(3) { [2]=> array(2) { [2]=> - string(5) "alter" + string(4) "val2" [3]=> array(1) { [3]=> - string(5) "alter" + string(4) "val3" } } [4]=> diff --git a/ext/spl/tests/bug42654_2.phpt b/ext/spl/tests/bug42654_2.phpt deleted file mode 100644 index bd290247dbdc..000000000000 --- a/ext/spl/tests/bug42654_2.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -Bug #42654 (RecursiveIteratorIterator modifies only part of leaves) ---FILE-- - 'val1', array('key2' => 'val2'), 'key3' => 'val3'); - -$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data)); -foreach($iterator as $foo) { - $key = $iterator->key(); - switch($key) { - case 'key1': // first level - case 'key2': // recursive level - echo "update $key".PHP_EOL; - $iterator->offsetSet($key, 'alter'); - } -} -$copy = $iterator->getArrayCopy(); -var_dump($copy); -?> ---EXPECT-- -update key1 -update key2 -array(3) { - ["key1"]=> - string(5) "alter" - [0]=> - array(1) { - ["key2"]=> - string(5) "alter" - } - ["key3"]=> - string(4) "val3" -} diff --git a/ext/spl/tests/bug54323.phpt b/ext/spl/tests/bug54323.phpt deleted file mode 100644 index 7431c9c47348..000000000000 --- a/ext/spl/tests/bug54323.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---TEST-- -Bug #54323 (Accessing unset()'ed ArrayObject's property causes crash) ---FILE-- -$value) { - } - unset($ao['prop']); - var_dump($c->prop, $ao['prop']); -} -?> ---EXPECTF-- -Warning: Undefined property: C::$prop in %s on line %d - -Warning: Undefined array key "prop" in %s on line %d -NULL -NULL diff --git a/ext/spl/tests/bug62672.phpt b/ext/spl/tests/bug62672.phpt deleted file mode 100644 index ec40ee695504..000000000000 --- a/ext/spl/tests/bug62672.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -Bug #62672 (Error on serialize of ArrayObject) ---FILE-- -_varA = $source; - } -} - -class ObjB extends ObjA -{ - private $_varB; - - public function __construct(ArrayObject $keys) - { - $this->_varB = $keys; - parent::__construct($keys->getIterator()); - } -} - -$obj = new ObjB(new ArrayObject()); - -var_dump($obj == unserialize(serialize($obj))); -?> ---EXPECT-- -bool(true) diff --git a/ext/spl/tests/bug62978.phpt b/ext/spl/tests/bug62978.phpt index 758649e23169..5c5ca05d366b 100644 --- a/ext/spl/tests/bug62978.phpt +++ b/ext/spl/tests/bug62978.phpt @@ -26,6 +26,8 @@ var_dump($a[$fp]); fclose($fp); ?> --EXPECTF-- +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + Warning: Undefined array key "epic_magic" in %s on line %d NULL diff --git a/ext/spl/tests/bug69845.phpt b/ext/spl/tests/bug69845.phpt deleted file mode 100644 index 09c9f2356d44..000000000000 --- a/ext/spl/tests/bug69845.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -Fixed bug #69845 (ArrayObject with ARRAY_AS_PROPS broken) ---FILE-- -itemType = 'bulletin'; - var_dump(!is_null($data['itemType'])); -} -?> ---EXPECT-- -bool(true) -bool(true) diff --git a/ext/spl/tests/bug70852.phpt b/ext/spl/tests/bug70852.phpt index 44168f990320..008a7c0ca4af 100644 --- a/ext/spl/tests/bug70852.phpt +++ b/ext/spl/tests/bug70852.phpt @@ -8,8 +8,12 @@ var_dump($y[NULL]); var_dump($y[NULL]++); ?> --EXPECTF-- +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + Warning: Undefined array key "" in %s on line %d NULL +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + Warning: Undefined array key "" in %s on line %d NULL diff --git a/ext/spl/tests/bug71204.phpt b/ext/spl/tests/bug71204.phpt deleted file mode 100644 index 8d1c721c100b..000000000000 --- a/ext/spl/tests/bug71204.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -Bug #71204 (segfault if clean spl_autoload_funcs while autoloading ) ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught Error: Class "A" not found in %s:%d -Stack trace: -#0 {main} - thrown in %sbug71204.php on line %d diff --git a/ext/spl/tests/bug73209.phpt b/ext/spl/tests/bug73209.phpt deleted file mode 100644 index 738394093668..000000000000 --- a/ext/spl/tests/bug73209.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -Bug #73209: RecursiveArrayIterator does not iterate object properties ---FILE-- -props = ['hello' => 5, 'props' => ['keyme' => ['test' => 5]]]; - } -} -$data = new hello(); - -$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data), RecursiveIteratorIterator::SELF_FIRST); -echo "Expect to see all keys in ->props here: \n"; - -foreach($iterator as $k=>$v) { - echo $k . "\n"; -} - -?> ---EXPECT-- -Expect to see all keys in ->props here: -props -hello -props -keyme -test diff --git a/ext/spl/tests/gh11178.phpt b/ext/spl/tests/gh11178.phpt deleted file mode 100644 index 3732c57a59d1..000000000000 --- a/ext/spl/tests/gh11178.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -GH-11178 (Segmentation fault in spl_array_it_get_current_data (PHP 8.1.18)) ---FILE-- -{'x'} = 1; - } - - function getIterator(): Traversable { - return new ArrayIterator($this); - } -} - -$obj = new A; - -foreach ($obj as $k => &$v) { - $v = 3; -} - -var_dump($obj); -?> ---EXPECT-- -object(A)#1 (1) { - ["x"]=> - &int(3) -} diff --git a/ext/spl/tests/gh13685.phpt b/ext/spl/tests/gh13685.phpt index 0f679d0e93fc..2bdddec4584e 100644 --- a/ext/spl/tests/gh13685.phpt +++ b/ext/spl/tests/gh13685.phpt @@ -44,9 +44,9 @@ try { string(14) ""A", "B", "C" " string(13) ""D", "E", "F"" -Cannot read from file php://temp +string(0) "" --- Use csv control --- string(14) ""A", "B", "C" " string(13) ""D", "E", "F"" -Cannot read from file php://temp +string(0) "" diff --git a/ext/spl/tests/gh15833_1.phpt b/ext/spl/tests/gh15833_1.phpt deleted file mode 100644 index d658a770e80f..000000000000 --- a/ext/spl/tests/gh15833_1.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -GH-15833 (Segmentation fault (access null pointer) in ext/spl/spl_array.c) ---CREDITS-- -YuanchengJiang ---FILE-- -newLazyProxy(function ($obj) { - $obj = new C(); - return $obj; -}); -$recursiveArrayIterator = new RecursiveArrayIterator($obj); -var_dump($recursiveArrayIterator->current()); -$recursiveArrayIterator->next(); -var_dump($recursiveArrayIterator->current()); -?> ---EXPECT-- -int(1) -NULL diff --git a/ext/spl/tests/gh15918.phpt b/ext/spl/tests/gh15918.phpt deleted file mode 100644 index b26ff8adfc14..000000000000 --- a/ext/spl/tests/gh15918.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -GH-15918 (Assertion failure in ext/spl/spl_fixedarray.c) ---FILE-- -getMessage(), "\n"; -} -?> ---EXPECT-- -Overloaded object of type SplFixedArray is not compatible with ArrayObject diff --git a/ext/spl/tests/gh16646.phpt b/ext/spl/tests/gh16646.phpt deleted file mode 100644 index b6cb503d8ed0..000000000000 --- a/ext/spl/tests/gh16646.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -GH-16646: Use-after-free in ArrayObject::unset() with destructor ---FILE-- -b = $arg; - } -} - -class C { - function __destruct() { - global $arr; - echo __METHOD__, "\n"; - $arr->exchangeArray([]); - } -} - -$arr = new ArrayObject(new B(new C)); -unset($arr["b"]); -var_dump($arr); - -?> ---EXPECT-- -C::__destruct -object(ArrayObject)#1 (1) { - ["storage":"ArrayObject":private]=> - array(0) { - } -} diff --git a/ext/spl/tests/gh16646_2.phpt b/ext/spl/tests/gh16646_2.phpt deleted file mode 100644 index d00658350081..000000000000 --- a/ext/spl/tests/gh16646_2.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---TEST-- -GH-16646: Use-after-free in ArrayObject::exchangeArray() with destructor ---FILE-- -exchangeArray([]); - } -} - -$arr = new ArrayObject(new C); -$arr->exchangeArray([]); -var_dump($arr); - -?> ---EXPECT-- -C::__destruct -object(ArrayObject)#1 (1) { - ["storage":"ArrayObject":private]=> - array(0) { - } -} diff --git a/ext/spl/tests/gh19094.phpt b/ext/spl/tests/gh19094.phpt new file mode 100644 index 000000000000..d0665c3e8f06 --- /dev/null +++ b/ext/spl/tests/gh19094.phpt @@ -0,0 +1,56 @@ +--TEST-- +GH-19094 (Attaching class with no Iterator implementation to MultipleIterator causes crash) +--FILE-- +getMessage(), "\n"; +} +try { + $cls[new MyAggregate] = 1; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +$cls[new MyIterator] = 1; +try { + $cls->key(); +} catch (RuntimeException $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Can only attach objects that implement the Iterator interface +Can only attach objects that implement the Iterator interface +Called key() with non valid sub iterator diff --git a/ext/spl/tests/gh19577.phpt b/ext/spl/tests/gh19577.phpt new file mode 100644 index 000000000000..641cfa57e065 --- /dev/null +++ b/ext/spl/tests/gh19577.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-19577: Integer overflow in LimitIterator with small offset and PHP_INT_MAX count +--FILE-- + 'A', 1 => 'B', 2 => 'C', 3 => 'D')); +$it = new LimitIterator($it, 2, PHP_INT_MAX); + +foreach($it as $val => $key) { + echo "Key: $val, Value: $key\n"; +} + +?> +--EXPECT-- +Key: 2, Value: C +Key: 3, Value: D diff --git a/ext/spl/tests/gh20101.phpt b/ext/spl/tests/gh20101.phpt new file mode 100644 index 000000000000..ad2399d76c8e --- /dev/null +++ b/ext/spl/tests/gh20101.phpt @@ -0,0 +1,49 @@ +--TEST-- +GH-20101 (SplHeap/SplPriorityQueue serialization exposes INDIRECTs) +--FILE-- +__serialize(); +var_dump($data); + +class CustomPriorityQueue extends SplPriorityQueue { + public $field = 0; +} +$pqueue = new CustomPriorityQueue(); +$data = $pqueue->__serialize(); +var_dump($data); +?> +--EXPECT-- +array(2) { + [0]=> + array(1) { + ["field"]=> + int(0) + } + [1]=> + array(2) { + ["flags"]=> + int(0) + ["heap_elements"]=> + array(0) { + } + } +} +array(2) { + [0]=> + array(1) { + ["field"]=> + int(0) + } + [1]=> + array(2) { + ["flags"]=> + int(1) + ["heap_elements"]=> + array(0) { + } + } +} diff --git a/ext/spl/tests/gh20614.phpt b/ext/spl/tests/gh20614.phpt new file mode 100644 index 000000000000..c13630d76469 --- /dev/null +++ b/ext/spl/tests/gh20614.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-20614 (SplFixedArray incorrectly handles references in deserialization) +--FILE-- +__unserialize($array); +var_dump($fa); +unset($fa[0]); +var_dump($fa); + +?> +--EXPECT-- +object(SplFixedArray)#1 (1) { + [0]=> + int(1) +} +object(SplFixedArray)#1 (1) { + [0]=> + NULL +} diff --git a/ext/spl/tests/gh20678.phpt b/ext/spl/tests/gh20678.phpt new file mode 100644 index 000000000000..00364db7f804 --- /dev/null +++ b/ext/spl/tests/gh20678.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-20678 (resource created by GlobalIterator crashes when it is called with fclose()) +--CREDITS-- +chongwick +--FILE-- + +--EXPECTF-- +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d diff --git a/ext/spl/tests/gh20856.phpt b/ext/spl/tests/gh20856.phpt new file mode 100644 index 000000000000..8bc1b3c95827 --- /dev/null +++ b/ext/spl/tests/gh20856.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-20856 (heap-use-after-free in SplDoublyLinkedList iterator when modifying during iteration) +--CREDITS-- +vi3tL0u1s +iluuu1994 +--FILE-- + +--EXPECTF-- +object(SplStack)#%d (%d) { + ["flags":"SplDoublyLinkedList":private]=> + int(6) + ["dllist":"SplDoublyLinkedList":private]=> + array(0) { + } +} diff --git a/ext/spl/tests/gh21499.phpt b/ext/spl/tests/gh21499.phpt new file mode 100644 index 000000000000..719da0094a6d --- /dev/null +++ b/ext/spl/tests/gh21499.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-21499 (RecursiveArrayIterator getChildren UAF after parent free) +--FILE-- +getChildren(); +unset($it); +$child->__construct([2, 3]); +var_dump($child->getArrayCopy()); +?> +--EXPECT-- +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} diff --git a/ext/spl/tests/gh21927.phpt b/ext/spl/tests/gh21927.phpt new file mode 100644 index 000000000000..a60ea5ca1025 --- /dev/null +++ b/ext/spl/tests/gh21927.phpt @@ -0,0 +1,151 @@ +--TEST-- +GH-21927: Use-after-free of self-freeing MultipleIterator children +--FILE-- +parent->detachIterator($this); + echo "rewind: still alive\n"; + } + public function next(): void {} + public function current(): mixed { return 0; } + public function key(): mixed { return 0; } + public function valid(): bool { return false; } +} + +class DetachOnNext implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void { + $this->parent->detachIterator($this); + echo "next: still alive\n"; + } + public function current(): mixed { return 0; } + public function key(): mixed { return 0; } + public function valid(): bool { return true; } +} + +class DetachOnValid implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void {} + public function current(): mixed { return 0; } + public function key(): mixed { return 0; } + public function valid(): bool { + $this->parent->detachIterator($this); + echo "valid: still alive\n"; + return true; + } +} + +class DetachOnCurrent implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void {} + public function current(): mixed { + $this->parent->detachIterator($this); + echo "current: still alive\n"; + return 'C'; + } + public function key(): mixed { return 'k'; } + public function valid(): bool { return true; } +} + +class DetachOnKey implements Iterator { + public function __construct(private MultipleIterator $parent) {} + public function rewind(): void {} + public function next(): void {} + public function current(): mixed { return 'C'; } + public function key(): mixed { + $this->parent->detachIterator($this); + echo "key: still alive\n"; + return 'K'; + } + public function valid(): bool { return true; } +} + +echo "-- detach inside rewind --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnRewind($mi)); +$mi->rewind(); +var_dump($mi->countIterators()); + +echo "-- detach inside next --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnNext($mi)); +$mi->rewind(); +$mi->next(); +var_dump($mi->countIterators()); + +echo "-- detach inside valid --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnValid($mi)); +var_dump($mi->valid()); +var_dump($mi->countIterators()); + +echo "-- detach inside current (numeric keys) --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnCurrent($mi)); +var_dump($mi->current()); +var_dump($mi->countIterators()); + +echo "-- detach inside key (numeric keys) --\n"; +$mi = new MultipleIterator(); +$mi->attachIterator(new DetachOnKey($mi)); +var_dump($mi->key()); +var_dump($mi->countIterators()); + +echo "-- detach inside current (assoc keys, refcounted inf) --\n"; +$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC); +$mi->attachIterator(new DetachOnCurrent($mi), 'cur_info_string'); +var_dump($mi->current()); +var_dump($mi->countIterators()); + +echo "-- detach inside key (assoc keys, refcounted inf) --\n"; +$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC); +$mi->attachIterator(new DetachOnKey($mi), 'key_info_string'); +var_dump($mi->key()); +var_dump($mi->countIterators()); + +?> +--EXPECT-- +-- detach inside rewind -- +rewind: still alive +int(0) +-- detach inside next -- +next: still alive +int(0) +-- detach inside valid -- +valid: still alive +bool(true) +int(0) +-- detach inside current (numeric keys) -- +current: still alive +array(1) { + [0]=> + string(1) "C" +} +int(0) +-- detach inside key (numeric keys) -- +key: still alive +array(1) { + [0]=> + string(1) "K" +} +int(0) +-- detach inside current (assoc keys, refcounted inf) -- +current: still alive +array(1) { + ["cur_info_string"]=> + string(1) "C" +} +int(0) +-- detach inside key (assoc keys, refcounted inf) -- +key: still alive +array(1) { + ["key_info_string"]=> + string(1) "K" +} +int(0) diff --git a/ext/spl/tests/gh22062.phpt b/ext/spl/tests/gh22062.phpt new file mode 100644 index 000000000000..ea67a9983a3d --- /dev/null +++ b/ext/spl/tests/gh22062.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-22062 (SplDoublyLinkedList iterator UAF via destructor releasing next node) +--FILE-- +setIteratorMode( + SplDoublyLinkedList::IT_MODE_FIFO | + SplDoublyLinkedList::IT_MODE_DELETE +); + +$list->push(new class($list) { + public function __construct(private SplDoublyLinkedList $list) {} + public function __destruct() { + if ($this->list->count() > 0) { + $this->list->offsetUnset(0); + } + } +}); + +$list->push(new stdClass()); + +foreach ($list as $item) { + unset($item); +} + +var_dump($list->count()); +?> +--EXPECT-- +int(0) diff --git a/ext/spl/tests/gh8562.phpt b/ext/spl/tests/gh8562.phpt new file mode 100644 index 000000000000..40b2554f5794 --- /dev/null +++ b/ext/spl/tests/gh8562.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-8562 (SplFileObject::current() returns wrong result after call to next()) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +$file->rewind(); +$file->next(); +echo "After rewind+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +$file->rewind(); +$file->next(); +$file->next(); +echo "After rewind+next+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +$file->rewind(); +$file->current(); +$file->next(); +echo "After current+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; +?> +--EXPECT-- +After rewind+next: key=1 current=line 1 +After rewind+next+next: key=2 current=line 2 +After current+next: key=1 current=line 1 diff --git a/ext/spl/tests/heap_next_write_lock.phpt b/ext/spl/tests/heap_next_write_lock.phpt new file mode 100644 index 000000000000..fcad94f3ccd3 --- /dev/null +++ b/ext/spl/tests/heap_next_write_lock.phpt @@ -0,0 +1,34 @@ +--TEST-- +SplHeap::next() write lock +--CREDITS-- +cnitlrt +--FILE-- +did) { + $this->did = true; + // Re-entrant write during internal heap insertion comparison. + if (!$this->isEmpty()) { + $this->next(); // no write-lock validation + } + } + return parent::compare($p1, $p2); + } +} + +$q = new EvilPQ(); +try { + for ($i = 0; $i < 200; $i++) { + $q->insert("d$i", 100 - $i); + } +} catch (RuntimeException $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +RuntimeException: Heap cannot be changed when it is already being modified. diff --git a/ext/spl/tests/heap_unserialize_under_corruption_or_modification.phpt b/ext/spl/tests/heap_unserialize_under_corruption_or_modification.phpt new file mode 100644 index 000000000000..2e54be09ad1a --- /dev/null +++ b/ext/spl/tests/heap_unserialize_under_corruption_or_modification.phpt @@ -0,0 +1,30 @@ +--TEST-- +SplHeap should not accept unserialize data when it is corrupted or under modification +--FILE-- +__unserialize($array); + return $a < $b ? -1 : ($a == $b ? 0 : 1); + } +} + +$heap = new SplMaxHeap; +$heap->insert(1); +$array = $heap->__serialize(); + +$heap = new MyHeap; +$heap->insert(0); +try { + $heap->insert(2); +} catch (RuntimeException $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Heap cannot be changed when it is already being modified. diff --git a/ext/spl/tests/iterator_016.phpt b/ext/spl/tests/iterator_016.phpt index abc81c165ae6..33ee78064201 100644 --- a/ext/spl/tests/iterator_016.phpt +++ b/ext/spl/tests/iterator_016.phpt @@ -8,7 +8,7 @@ class Menu extends ArrayObject function getIterator(): RecursiveArrayIterator { echo __METHOD__ . "\n"; - return new RecursiveArrayIterator($this); + return new RecursiveArrayIterator($this->getArrayCopy()); } } @@ -42,7 +42,18 @@ class MenuOutput extends RecursiveIteratorIterator } } -$arr = array("a", array("ba", array("bba", "bbb"), array(array("bcaa"))), array("ca"), "d"); +$arr = [ + "a", + [ + "ba", + ["bba", "bbb"], + [ + ["bcaa"] + ] + ], + ["ca"], + "d", +]; $obj = new Menu($arr); $rit = new MenuOutput($obj); foreach($rit as $k=>$v) diff --git a/ext/spl/tests/iterator_031.phpt b/ext/spl/tests/iterator_031.phpt index 610e056f5380..c2b5885dd23e 100644 --- a/ext/spl/tests/iterator_031.phpt +++ b/ext/spl/tests/iterator_031.phpt @@ -3,6 +3,13 @@ SPL: AppendIterator::append() rewinds when necessary --FILE-- __construct(); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + class MyArrayIterator extends ArrayIterator { function rewind(): void @@ -14,8 +21,7 @@ class MyArrayIterator extends ArrayIterator $it = new MyArrayIterator(array(1,2)); -foreach($it as $k=>$v) -{ +foreach($it as $k=>$v) { echo "$k=>$v\n"; } @@ -44,31 +50,24 @@ class MyAppendIterator extends AppendIterator parent::append($what); } - function parent__construct() - { + function parent__construct() { parent::__construct(); } } $ap = new MyAppendIterator; -try -{ +try { $ap->append($it); -} -catch(\Error $e) -{ +} catch(\Error $e) { echo $e->getMessage() . "\n"; } $ap->parent__construct(); -try -{ +try { $ap->parent__construct($it); -} -catch(BadMethodCallException $e) -{ +} catch(BadMethodCallException $e) { echo $e->getMessage() . "\n"; } @@ -76,13 +75,13 @@ $ap->append($it); $ap->append($it); $ap->append($it); -foreach($ap as $k=>$v) -{ +foreach($ap as $k=>$v) { echo "$k=>$v\n"; } ?> --EXPECT-- +BadMethodCallException: AppendIterator::getIterator() must be called exactly once per instance MyArrayIterator::rewind 0=>1 1=>2 diff --git a/ext/spl/tests/iterator_049.phpt b/ext/spl/tests/iterator_049.phpt index e9b81fbff39b..6fccbd591162 100644 --- a/ext/spl/tests/iterator_049.phpt +++ b/ext/spl/tests/iterator_049.phpt @@ -1,10 +1,10 @@ --TEST-- -SPL: ArrayIterator with NULL key +SPL: ArrayIterator with empty string key --FILE-- NULL)); -@var_dump($ar); +$ar = new ArrayIterator(array(''=>NULL)); +var_dump($ar); var_dump($ar->getArrayCopy()); ?> diff --git a/ext/spl/tests/iterator_049b.phpt b/ext/spl/tests/iterator_049b.phpt index 1e1176c7169f..7a957aa70c5c 100644 --- a/ext/spl/tests/iterator_049b.phpt +++ b/ext/spl/tests/iterator_049b.phpt @@ -1,17 +1,17 @@ --TEST-- -SPL: ArrayIterator with NULL key +SPL: ArrayIterator with empty string key --FILE-- 1, + ''=>1, "\0"=>2, "\0\0"=>3, "\0\0\0"=>4, "\0*"=>5, "\0*\0"=>6, )); -@var_dump($ar); +var_dump($ar); var_dump($ar->getArrayCopy()); ?> diff --git a/ext/spl/tests/iterator_069.phpt b/ext/spl/tests/iterator_069.phpt index b9ee3f4b820d..e30251fa9162 100644 --- a/ext/spl/tests/iterator_069.phpt +++ b/ext/spl/tests/iterator_069.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator cannot be used with foreach by reference --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); $recItIt = new RecursiveIteratorIterator($recArrIt); diff --git a/ext/spl/tests/iterator_071.phpt b/ext/spl/tests/iterator_071.phpt index 7f525eb2c61d..4f9b18d0c074 100644 --- a/ext/spl/tests/iterator_071.phpt +++ b/ext/spl/tests/iterator_071.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Test where the case is RS_SELF and mode is CHIL --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { @@ -29,4 +29,8 @@ MyRecursiveIteratorIterator::nextelement MyRecursiveIteratorIterator::nextelement 0 MyRecursiveIteratorIterator::nextelement +0 +MyRecursiveIteratorIterator::nextelement +1 +MyRecursiveIteratorIterator::nextelement 1 diff --git a/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt b/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt index 44b4e2a0ebcb..c5fc21ea8bc7 100644 --- a/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt +++ b/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt @@ -21,4 +21,6 @@ try { ?> --EXPECTF-- Deprecated: Implicit conversion from float 2.5 to int loses precision in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d Cannot access offset of type array on array diff --git a/ext/spl/tests/observer_008.phpt b/ext/spl/tests/observer_008.phpt deleted file mode 100644 index 0f6f0d263b9e..000000000000 --- a/ext/spl/tests/observer_008.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -SPL: SplObjectStorage addAll/removeAll ---FILE-- -attach($o1); -$a->attach($o2); - -$b = new SplObjectStorage(); -$b->attach($o2); -$b->attach($o3); - -$a->addAll($b); - -var_dump($a->count()); - -$a->detach($o3); -var_dump($a->count()); - -$a->removeAll($b); -var_dump($a->count()); -?> ---EXPECT-- -int(3) -int(2) -int(1) diff --git a/ext/spl/tests/phpinfo_out.phpt b/ext/spl/tests/phpinfo_out.phpt new file mode 100644 index 000000000000..8be1a2dead41 --- /dev/null +++ b/ext/spl/tests/phpinfo_out.phpt @@ -0,0 +1,16 @@ +--TEST-- +phpinfo() SPL extension information +--FILE-- + +--EXPECT-- +SPL + +SPL support => enabled +Interfaces => OuterIterator, RecursiveIterator, SeekableIterator, SplObserver, SplSubject +Classes => AppendIterator, ArrayIterator, ArrayObject, BadFunctionCallException, BadMethodCallException, CachingIterator, CallbackFilterIterator, DirectoryIterator, DomainException, EmptyIterator, FilesystemIterator, FilterIterator, GlobIterator, InfiniteIterator, InvalidArgumentException, IteratorIterator, LengthException, LimitIterator, LogicException, MultipleIterator, NoRewindIterator, OutOfBoundsException, OutOfRangeException, OverflowException, ParentIterator, RangeException, RecursiveArrayIterator, RecursiveCachingIterator, RecursiveCallbackFilterIterator, RecursiveDirectoryIterator, RecursiveFilterIterator, RecursiveIteratorIterator, RecursiveRegexIterator, RecursiveTreeIterator, RegexIterator, RuntimeException, SplDoublyLinkedList, SplFileInfo, SplFileObject, SplFixedArray, SplHeap, SplMinHeap, SplMaxHeap, SplObjectStorage, SplPriorityQueue, SplQueue, SplStack, SplTempFileObject, UnderflowException, UnexpectedValueException diff --git a/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt b/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt index 6a7d3eb8a514..76bacc3615f7 100644 --- a/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_beginchildren_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in beginchildren which should --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { diff --git a/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt b/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt index 1c96ee9fcd0b..9256e9e3b1b2 100644 --- a/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_callHasChildren_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in callHasChildren which shoul --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { diff --git a/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt b/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt index 13af7ce01986..07dee9c4acbb 100644 --- a/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_endchildren_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in endchildren which should be --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { @@ -30,6 +30,8 @@ foreach ($recItIt2 as $val) echo "$val\n"; --EXPECTF-- 1 2 +a +b ===NEXT LOOP=== 1 2 diff --git a/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt b/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt index d92d309c754b..f89f47e849b2 100644 --- a/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt +++ b/ext/spl/tests/recursiveIteratorIterator_nextelement_error.phpt @@ -3,10 +3,10 @@ SPL: RecursiveIteratorIterator - Exception thrown in nextelement which should be --FILE-- getIterator()); +$recArrIt = new RecursiveArrayIterator([ + [1, 2], + ['a', 'b'], +]); class MyRecursiveIteratorIterator extends RecursiveIteratorIterator { diff --git a/ext/spl/tests/recursive_tree_iterator_005.phpt b/ext/spl/tests/recursive_tree_iterator_005.phpt deleted file mode 100644 index a63b26685c56..000000000000 --- a/ext/spl/tests/recursive_tree_iterator_005.phpt +++ /dev/null @@ -1,114 +0,0 @@ ---TEST-- -SPL: RecursiveTreeIterator and binary vs unicode (PHP 6.0+) ---INI-- -error_reporting=E_ALL&~E_NOTICE ---FILE-- - array( - (binary) "binary", - "abc2", - 1, - ), - (binary) "binary" => array( - 2, - "b", - 3 => array( - 4, - "c", - ), - "4abc" => array( - 4, - "c", - ), - ), -); - -$it = new RecursiveTreeIterator(new RecursiveArrayIterator($ary), 0); -foreach($it as $k => $v) { - var_dump($v); -} -echo "\n----------------\n\n"; -foreach($it as $k => $v) { - var_dump($k); -} -echo "\n----------------\n\n"; -echo "key, getEntry, current:\n"; -foreach($it as $k => $v) { - var_dump($it->key(), $it->getEntry(), $it->current()); -} -?> ---EXPECT-- -string(7) "|-Array" -string(10) "| |-binary" -string(8) "| |-abc2" -string(5) "| \-1" -string(7) "\-Array" -string(5) " |-2" -string(5) " |-b" -string(9) " |-Array" -string(7) " | |-4" -string(7) " | \-c" -string(9) " \-Array" -string(7) " |-4" -string(7) " \-c" - ----------------- - -string(3) "|-0" -string(5) "| |-0" -string(5) "| |-1" -string(5) "| \-2" -string(8) "\-binary" -string(5) " |-0" -string(5) " |-1" -string(5) " |-3" -string(7) " | |-0" -string(7) " | \-1" -string(8) " \-4abc" -string(7) " |-0" -string(7) " \-1" - ----------------- - -key, getEntry, current: -string(3) "|-0" -string(5) "Array" -string(7) "|-Array" -string(5) "| |-0" -string(6) "binary" -string(10) "| |-binary" -string(5) "| |-1" -string(4) "abc2" -string(8) "| |-abc2" -string(5) "| \-2" -string(1) "1" -string(5) "| \-1" -string(8) "\-binary" -string(5) "Array" -string(7) "\-Array" -string(5) " |-0" -string(1) "2" -string(5) " |-2" -string(5) " |-1" -string(1) "b" -string(5) " |-b" -string(5) " |-3" -string(5) "Array" -string(9) " |-Array" -string(7) " | |-0" -string(1) "4" -string(7) " | |-4" -string(7) " | \-1" -string(1) "c" -string(7) " | \-c" -string(8) " \-4abc" -string(5) "Array" -string(9) " \-Array" -string(7) " |-0" -string(1) "4" -string(7) " |-4" -string(7) " \-1" -string(1) "c" -string(7) " \-c" diff --git a/ext/spl/tests/recursive_tree_iterator_007.phpt b/ext/spl/tests/recursive_tree_iterator_007.phpt index 2907f39f2657..75f1e6386c8e 100644 --- a/ext/spl/tests/recursive_tree_iterator_007.phpt +++ b/ext/spl/tests/recursive_tree_iterator_007.phpt @@ -1,15 +1,16 @@ --TEST-- SPL: RecursiveTreeIterator and Exception from getEntry() ---INI-- -error_reporting=E_ALL&~E_NOTICE --FILE-- it = new RecursiveArrayIterator($it); } function getIterator(): Traversable { @@ -27,5 +28,10 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +[0] => |-Array +[0] => | \-string +[1] => \-Array + +Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d Object of class stdClass could not be converted to string diff --git a/ext/spl/tests/spl_autoload_unregister_without_registrations.phpt b/ext/spl/tests/spl_autoload_unregister_without_registrations.phpt deleted file mode 100644 index 0a7ca5a1352f..000000000000 --- a/ext/spl/tests/spl_autoload_unregister_without_registrations.phpt +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -spl_autoload_unregister("spl_autoload_call") without registrations ---FILE-- - -Done ---EXPECT-- -bool(true) -Done diff --git a/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt b/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt index 4b8cfaa53d81..257a961cee80 100644 --- a/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt +++ b/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt @@ -5,7 +5,7 @@ Rohan Abraham (rohanabrahams@gmail.com) TestFest London May 2009 --FILE-- 1, "two"=>2, "three"=>array("four"=>4, "five"=>5, "six"=>array("seven"=>7)), "eight"=>8, -100 => 10, NULL => "null"); + $ar = array("one"=>1, "two"=>2, "three"=>array("four"=>4, "five"=>5, "six"=>array("seven"=>7)), "eight"=>8, -100 => 10, '' => "null"); $it = new RecursiveArrayIterator($ar); $it = new RecursiveIteratorIterator($it); foreach($it as $k=>$v) diff --git a/ext/sqlite3/config.w32 b/ext/sqlite3/config.w32 index f99e4eb281dc..98b46715d2fe 100644 --- a/ext/sqlite3/config.w32 +++ b/ext/sqlite3/config.w32 @@ -7,7 +7,6 @@ if (PHP_SQLITE3 != "no") { EXTENSION("sqlite3", "sqlite3.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("HAVE_SQLITE3", 1, "Define to 1 if the PHP extension 'sqlite3' is available."); - AC_DEFINE("HAVE_SQLITE3_ERRSTR", 1, "Define to 1 if SQLite library has the 'sqlite3_errstr' function."); AC_DEFINE("HAVE_SQLITE3_EXPANDED_SQL", 1, "Define to 1 if SQLite library has the 'sqlite3_expanded_sql' function."); } else { WARNING("sqlite3 not enabled; libraries and/or headers not found"); diff --git a/ext/sqlite3/config0.m4 b/ext/sqlite3/config0.m4 index 453108f692a6..ada1e351d436 100644 --- a/ext/sqlite3/config0.m4 +++ b/ext/sqlite3/config0.m4 @@ -9,12 +9,6 @@ if test $PHP_SQLITE3 != "no"; then AC_DEFINE([HAVE_SQLITE3], [1], [Define to 1 if the PHP extension 'sqlite3' is available.]) - PHP_CHECK_LIBRARY([sqlite3], [sqlite3_errstr], - [AC_DEFINE([HAVE_SQLITE3_ERRSTR], [1], - [Define to 1 if SQLite library has the 'sqlite3_errstr' function.])], - [], - [$SQLITE3_SHARED_LIBADD]) - PHP_CHECK_LIBRARY([sqlite3], [sqlite3_expanded_sql], [AC_DEFINE([HAVE_SQLITE3_EXPANDED_SQL], [1], [Define to 1 if SQLite library has the 'sqlite3_expanded_sql' function.])], diff --git a/ext/sqlite3/php_sqlite3.h b/ext/sqlite3/php_sqlite3.h index 79f8cf436030..8a9cf3af1598 100644 --- a/ext/sqlite3/php_sqlite3.h +++ b/ext/sqlite3/php_sqlite3.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ diff --git a/ext/sqlite3/php_sqlite3_structs.h b/ext/sqlite3/php_sqlite3_structs.h index 5d9f69cc5770..8012def8ea65 100644 --- a/ext/sqlite3/php_sqlite3_structs.h +++ b/ext/sqlite3/php_sqlite3_structs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -75,7 +73,7 @@ typedef struct _php_sqlite3_db_object { } php_sqlite3_db_object; static inline php_sqlite3_db_object *php_sqlite3_db_from_obj(zend_object *obj) { - return (php_sqlite3_db_object*)((char*)(obj) - XtOffsetOf(php_sqlite3_db_object, zo)); + return ZEND_CONTAINER_OF(obj, php_sqlite3_db_object, zo); } #define Z_SQLITE3_DB_P(zv) php_sqlite3_db_from_obj(Z_OBJ_P((zv))) @@ -104,7 +102,7 @@ struct _php_sqlite3_result_object { }; static inline php_sqlite3_result *php_sqlite3_result_from_obj(zend_object *obj) { - return (php_sqlite3_result*)((char*)(obj) - XtOffsetOf(php_sqlite3_result, zo)); + return ZEND_CONTAINER_OF(obj, php_sqlite3_result, zo); } #define Z_SQLITE3_RESULT_P(zv) php_sqlite3_result_from_obj(Z_OBJ_P((zv))) @@ -122,7 +120,7 @@ struct _php_sqlite3_stmt_object { }; static inline php_sqlite3_stmt *php_sqlite3_stmt_from_obj(zend_object *obj) { - return (php_sqlite3_stmt*)((char*)(obj) - XtOffsetOf(php_sqlite3_stmt, zo)); + return ZEND_CONTAINER_OF(obj, php_sqlite3_stmt, zo); } #define Z_SQLITE3_STMT_P(zv) php_sqlite3_stmt_from_obj(Z_OBJ_P((zv))) diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 5e402300980b..d257703f17ac 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Scott MacVicar | +----------------------------------------------------------------------+ @@ -38,7 +36,7 @@ ZEND_DECLARE_MODULE_GLOBALS(sqlite3) static PHP_GINIT_FUNCTION(sqlite3); static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4); static void sqlite3_param_dtor(zval *data); -static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement); +static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, php_sqlite3_stmt *statement); static zend_always_inline void php_sqlite3_fetch_one(int n_cols, php_sqlite3_result *result_obj, zend_long mode, zval *result); #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \ @@ -143,11 +141,7 @@ PHP_METHOD(SQLite3, open) rc = sqlite3_open_v2(fullpath, &(db_obj->db), flags, NULL); if (rc != SQLITE_OK) { zend_throw_exception_ex(zend_ce_exception, 0, "Unable to open database: %s", -#ifdef HAVE_SQLITE3_ERRSTR - db_obj->db ? sqlite3_errmsg(db_obj->db) : sqlite3_errstr(rc)); -#else - db_obj->db ? sqlite3_errmsg(db_obj->db) : ""); -#endif + db_obj->db ? sqlite3_errmsg(db_obj->db) : sqlite3_errstr(rc)); sqlite3_close(db_obj->db); if (fullpath != filename) { efree(fullpath); @@ -190,9 +184,7 @@ PHP_METHOD(SQLite3, close) int errcode; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (db_obj->initialised) { zend_llist_clean(&(db_obj->free_list)); @@ -241,9 +233,7 @@ PHP_METHOD(SQLite3, exec) /* {{{ Returns the SQLite3 Library version as a string constant and as a number. */ PHP_METHOD(SQLite3, version) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); array_init(return_value); @@ -261,9 +251,7 @@ PHP_METHOD(SQLite3, lastInsertRowID) zval *object = ZEND_THIS; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) @@ -278,9 +266,7 @@ PHP_METHOD(SQLite3, lastErrorCode) zval *object = ZEND_THIS; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3) @@ -299,9 +285,7 @@ PHP_METHOD(SQLite3, lastExtendedErrorCode) zval *object = ZEND_THIS; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3) @@ -318,7 +302,7 @@ PHP_METHOD(SQLite3, enableExtendedResultCodes) { php_sqlite3_db_object *db_obj; zval *object = ZEND_THIS; - bool enable = 1; + bool enable = true; db_obj = Z_SQLITE3_DB_P(object); int ret; @@ -347,9 +331,7 @@ PHP_METHOD(SQLite3, lastErrorMsg) zval *object = ZEND_THIS; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3) @@ -473,9 +455,7 @@ PHP_METHOD(SQLite3, changes) zval *object = ZEND_THIS; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3) @@ -498,6 +478,9 @@ PHP_METHOD(SQLite3, escapeString) if (ret) { RETVAL_STRING(ret); sqlite3_free(ret); + } else { + zend_throw_exception_ex(php_sqlite3_exception_ce, 0, "Unable to escape string"); + RETURN_THROWS(); } } else { RETURN_EMPTY_STRING(); @@ -648,7 +631,7 @@ static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* break; case SQLITE3_TEXT: - ZVAL_STRING(data, (char*)sqlite3_column_text(stmt, column)); + ZVAL_STRINGL(data, (const char *) sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column)); break; case SQLITE_BLOB: @@ -666,7 +649,7 @@ PHP_METHOD(SQLite3, querySingle) zend_string *sql; char *errtext = NULL; int return_code; - bool entire_row = 0; + bool entire_row = false; sqlite3_stmt *stmt; db_obj = Z_SQLITE3_DB_P(object); @@ -1270,13 +1253,10 @@ PHP_METHOD(SQLite3, openBlob) mode = "r+b"; } + // since it is not persistent, php_stream_alloc can't fail stream = php_stream_alloc(&php_stream_sqlite3_ops, sqlite3_stream, 0, mode); - - if (stream) { - php_stream_to_zval(stream, return_value); - } else { - RETURN_FALSE; - } + ZEND_ASSERT(stream != NULL); + php_stream_to_zval(stream, return_value); } /* }}} */ @@ -1285,7 +1265,7 @@ PHP_METHOD(SQLite3, enableExceptions) { php_sqlite3_db_object *db_obj; zval *object = ZEND_THIS; - bool enableExceptions = 0; + bool enableExceptions = false; db_obj = Z_SQLITE3_DB_P(object); @@ -1332,7 +1312,6 @@ PHP_METHOD(SQLite3, setAuthorizer) /* }}} */ -#if SQLITE_VERSION_NUMBER >= 3006011 /* {{{ Backups the current database to another one. */ PHP_METHOD(SQLite3, backup) { @@ -1386,7 +1365,6 @@ PHP_METHOD(SQLite3, backup) RETURN_TRUE; } /* }}} */ -#endif /* {{{ Returns the number of parameters within the prepared statement. */ PHP_METHOD(SQLite3Stmt, paramCount) @@ -1916,7 +1894,6 @@ PHP_METHOD(SQLite3Stmt, __construct) errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL); if (errcode != SQLITE_OK) { php_sqlite3_error(db_obj, errcode, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db)); - zval_ptr_dtor(return_value); RETURN_FALSE; } stmt_obj->initialised = true; @@ -1987,6 +1964,16 @@ PHP_METHOD(SQLite3Result, columnType) } /* }}} */ +static void sqlite3result_fill_column_names_cache(php_sqlite3_result *result_obj, int nb_cols) +{ + result_obj->column_names = safe_emalloc(nb_cols, sizeof(zend_string*), 0); + + for (int i = 0; i < nb_cols; i++) { + const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i); + result_obj->column_names[i] = zend_string_init(column, strlen(column), 0); + } +} + /* {{{ Fetch a result row as both an associative or numerically indexed array or both. */ PHP_METHOD(SQLite3Result, fetchArray) { @@ -2019,12 +2006,7 @@ PHP_METHOD(SQLite3Result, fetchArray) /* Cache column names to speed up repeated fetchArray calls. */ if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) { - result_obj->column_names = emalloc(n_cols * sizeof(zend_string*)); - - for (int i = 0; i < n_cols; i++) { - const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i); - result_obj->column_names[i] = zend_string_init(column, strlen(column), 0); - } + sqlite3result_fill_column_names_cache(result_obj, n_cols); } array_init(return_value); @@ -2035,10 +2017,10 @@ PHP_METHOD(SQLite3Result, fetchArray) case SQLITE_DONE: RETURN_FALSE; - break; default: php_sqlite3_error(result_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(result_obj->stmt_obj->stmt)), "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt))); + RETURN_FALSE; } } /* }}} */ @@ -2056,7 +2038,7 @@ static void sqlite3result_clear_column_names_cache(php_sqlite3_result *result) { PHP_METHOD(SQLite3Result, fetchAll) { - int i, nb_cols; + int nb_cols; bool done = false; php_sqlite3_result *result_obj; zval *object = ZEND_THIS; @@ -2071,14 +2053,8 @@ PHP_METHOD(SQLite3Result, fetchAll) SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result) nb_cols = sqlite3_column_count(result_obj->stmt_obj->stmt); - if (mode & PHP_SQLITE3_ASSOC) { - sqlite3result_clear_column_names_cache(result_obj); - result_obj->column_names = emalloc(nb_cols * sizeof(zend_string*)); - - for (i = 0; i < nb_cols; i++) { - const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i); - result_obj->column_names[i] = zend_string_init(column, strlen(column), 0); - } + if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) { + sqlite3result_fill_column_names_cache(result_obj, nb_cols); } result_obj->column_count = nb_cols; array_init(return_value); @@ -2145,7 +2121,7 @@ PHP_METHOD(SQLite3Result, finalize) /* We need to finalize an internal statement */ if (!result_obj->is_prepared_statement) { - zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj, + zend_llist_del_element(&(result_obj->db_obj->free_list), result_obj->stmt_obj, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); } else { sqlite3_reset(result_obj->stmt_obj->stmt); @@ -2260,9 +2236,9 @@ static void php_sqlite3_free_list_dtor(void **item) } /* }}} */ -static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, sqlite3_stmt *statement ) /* {{{ */ +static int php_sqlite3_compare_stmt_free(php_sqlite3_stmt **stmt_obj_ptr, php_sqlite3_stmt *statement ) /* {{{ */ { - return ((*stmt_obj_ptr)->initialised && statement == (*stmt_obj_ptr)->stmt); + return ((*stmt_obj_ptr)->initialised && statement == *stmt_obj_ptr); } /* }}} */ @@ -2376,7 +2352,7 @@ static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */ } if (intern->initialised) { - zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt, + zend_llist_del_element(&(intern->db_obj->free_list), intern, (int (*)(void *, void *)) php_sqlite3_compare_stmt_free); } @@ -2479,9 +2455,7 @@ static zend_always_inline void php_sqlite3_fetch_one(int n_cols, php_sqlite3_res if (mode & PHP_SQLITE3_ASSOC) { if (mode & PHP_SQLITE3_NUM) { - if (Z_REFCOUNTED(data)) { - Z_ADDREF(data); - } + Z_TRY_ADDREF(data); } /* Note: we can't use the "add_new" variant here instead of "update" because * when the same column name is encountered, the last result should be taken. */ @@ -2509,7 +2483,7 @@ PHP_MINIT_FUNCTION(sqlite3) memcpy(&sqlite3_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); /* Register SQLite 3 Class */ - sqlite3_object_handlers.offset = XtOffsetOf(php_sqlite3_db_object, zo); + sqlite3_object_handlers.offset = offsetof(php_sqlite3_db_object, zo); sqlite3_object_handlers.clone_obj = NULL; sqlite3_object_handlers.free_obj = php_sqlite3_object_free_storage; sqlite3_object_handlers.get_gc = php_sqlite3_get_gc; @@ -2518,7 +2492,7 @@ PHP_MINIT_FUNCTION(sqlite3) php_sqlite3_sc_entry->default_object_handlers = &sqlite3_object_handlers; /* Register SQLite 3 Prepared Statement Class */ - sqlite3_stmt_object_handlers.offset = XtOffsetOf(php_sqlite3_stmt, zo); + sqlite3_stmt_object_handlers.offset = offsetof(php_sqlite3_stmt, zo); sqlite3_stmt_object_handlers.clone_obj = NULL; sqlite3_stmt_object_handlers.free_obj = php_sqlite3_stmt_object_free_storage; php_sqlite3_stmt_entry = register_class_SQLite3Stmt(); @@ -2526,7 +2500,7 @@ PHP_MINIT_FUNCTION(sqlite3) php_sqlite3_stmt_entry->default_object_handlers = &sqlite3_stmt_object_handlers; /* Register SQLite 3 Result Class */ - sqlite3_result_object_handlers.offset = XtOffsetOf(php_sqlite3_result, zo); + sqlite3_result_object_handlers.offset = offsetof(php_sqlite3_result, zo); sqlite3_result_object_handlers.clone_obj = NULL; sqlite3_result_object_handlers.free_obj = php_sqlite3_result_object_free_storage; php_sqlite3_result_entry = register_class_SQLite3Result(); diff --git a/ext/sqlite3/sqlite3.stub.php b/ext/sqlite3/sqlite3.stub.php index 54a7b41ec557..1a51f9dc3d85 100644 --- a/ext/sqlite3/sqlite3.stub.php +++ b/ext/sqlite3/sqlite3.stub.php @@ -199,10 +199,8 @@ public function busyTimeout(int $milliseconds): bool {} public function loadExtension(string $name): bool {} #endif -#if SQLITE_VERSION_NUMBER >= 3006011 /** @tentative-return-type */ public function backup(SQLite3 $destination, string $sourceDatabase = "main", string $destinationDatabase = "main"): bool {} -#endif /** @tentative-return-type */ public static function escapeString(string $string): string {} diff --git a/ext/sqlite3/sqlite3_arginfo.h b/ext/sqlite3/sqlite3_arginfo.h index 54ca70cad5c5..60f63cb1094e 100644 --- a/ext/sqlite3/sqlite3_arginfo.h +++ b/ext/sqlite3/sqlite3_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: da91c32c6070c808d6e1b01894b5f8beedda7b45 */ +/* This is a generated file, edit sqlite3.stub.php instead. + * Stub hash: 247f02e9b12b901b36bb863cf2a8e73b3d97a191 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SQLite3___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -41,13 +41,11 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SQLite3_loadExte ZEND_END_ARG_INFO() #endif -#if SQLITE_VERSION_NUMBER >= 3006011 ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SQLite3_backup, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, destination, SQLite3, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sourceDatabase, IS_STRING, 0, "\"main\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, destinationDatabase, IS_STRING, 0, "\"main\"") ZEND_END_ARG_INFO() -#endif ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SQLite3_escapeString, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) @@ -193,9 +191,7 @@ ZEND_METHOD(SQLite3, busyTimeout); #if !defined(SQLITE_OMIT_LOAD_EXTENSION) ZEND_METHOD(SQLite3, loadExtension); #endif -#if SQLITE_VERSION_NUMBER >= 3006011 ZEND_METHOD(SQLite3, backup); -#endif ZEND_METHOD(SQLite3, escapeString); ZEND_METHOD(SQLite3, prepare); ZEND_METHOD(SQLite3, exec); @@ -246,9 +242,7 @@ static const zend_function_entry class_SQLite3_methods[] = { #if !defined(SQLITE_OMIT_LOAD_EXTENSION) ZEND_ME(SQLite3, loadExtension, arginfo_class_SQLite3_loadExtension, ZEND_ACC_PUBLIC) #endif -#if SQLITE_VERSION_NUMBER >= 3006011 ZEND_ME(SQLite3, backup, arginfo_class_SQLite3_backup, ZEND_ACC_PUBLIC) -#endif ZEND_ME(SQLite3, escapeString, arginfo_class_SQLite3_escapeString, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(SQLite3, prepare, arginfo_class_SQLite3_prepare, ZEND_ACC_PUBLIC) ZEND_ME(SQLite3, exec, arginfo_class_SQLite3_exec, ZEND_ACC_PUBLIC) @@ -332,226 +326,226 @@ static zend_class_entry *register_class_SQLite3(void) zval const_OK_value; ZVAL_LONG(&const_OK_value, SQLITE_OK); - zend_string *const_OK_name = zend_string_init_interned("OK", sizeof("OK") - 1, 1); + zend_string *const_OK_name = zend_string_init_interned("OK", sizeof("OK") - 1, true); zend_declare_typed_class_constant(class_entry, const_OK_name, &const_OK_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_OK_name); + zend_string_release_ex(const_OK_name, true); zval const_DENY_value; ZVAL_LONG(&const_DENY_value, SQLITE_DENY); - zend_string *const_DENY_name = zend_string_init_interned("DENY", sizeof("DENY") - 1, 1); + zend_string *const_DENY_name = zend_string_init_interned("DENY", sizeof("DENY") - 1, true); zend_declare_typed_class_constant(class_entry, const_DENY_name, &const_DENY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DENY_name); + zend_string_release_ex(const_DENY_name, true); zval const_IGNORE_value; ZVAL_LONG(&const_IGNORE_value, SQLITE_IGNORE); - zend_string *const_IGNORE_name = zend_string_init_interned("IGNORE", sizeof("IGNORE") - 1, 1); + zend_string *const_IGNORE_name = zend_string_init_interned("IGNORE", sizeof("IGNORE") - 1, true); zend_declare_typed_class_constant(class_entry, const_IGNORE_name, &const_IGNORE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_IGNORE_name); + zend_string_release_ex(const_IGNORE_name, true); zval const_CREATE_INDEX_value; ZVAL_LONG(&const_CREATE_INDEX_value, SQLITE_CREATE_INDEX); - zend_string *const_CREATE_INDEX_name = zend_string_init_interned("CREATE_INDEX", sizeof("CREATE_INDEX") - 1, 1); + zend_string *const_CREATE_INDEX_name = zend_string_init_interned("CREATE_INDEX", sizeof("CREATE_INDEX") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_INDEX_name, &const_CREATE_INDEX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_INDEX_name); + zend_string_release_ex(const_CREATE_INDEX_name, true); zval const_CREATE_TABLE_value; ZVAL_LONG(&const_CREATE_TABLE_value, SQLITE_CREATE_TABLE); - zend_string *const_CREATE_TABLE_name = zend_string_init_interned("CREATE_TABLE", sizeof("CREATE_TABLE") - 1, 1); + zend_string *const_CREATE_TABLE_name = zend_string_init_interned("CREATE_TABLE", sizeof("CREATE_TABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_TABLE_name, &const_CREATE_TABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_TABLE_name); + zend_string_release_ex(const_CREATE_TABLE_name, true); zval const_CREATE_TEMP_INDEX_value; ZVAL_LONG(&const_CREATE_TEMP_INDEX_value, SQLITE_CREATE_TEMP_INDEX); - zend_string *const_CREATE_TEMP_INDEX_name = zend_string_init_interned("CREATE_TEMP_INDEX", sizeof("CREATE_TEMP_INDEX") - 1, 1); + zend_string *const_CREATE_TEMP_INDEX_name = zend_string_init_interned("CREATE_TEMP_INDEX", sizeof("CREATE_TEMP_INDEX") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_TEMP_INDEX_name, &const_CREATE_TEMP_INDEX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_TEMP_INDEX_name); + zend_string_release_ex(const_CREATE_TEMP_INDEX_name, true); zval const_CREATE_TEMP_TABLE_value; ZVAL_LONG(&const_CREATE_TEMP_TABLE_value, SQLITE_CREATE_TEMP_TABLE); - zend_string *const_CREATE_TEMP_TABLE_name = zend_string_init_interned("CREATE_TEMP_TABLE", sizeof("CREATE_TEMP_TABLE") - 1, 1); + zend_string *const_CREATE_TEMP_TABLE_name = zend_string_init_interned("CREATE_TEMP_TABLE", sizeof("CREATE_TEMP_TABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_TEMP_TABLE_name, &const_CREATE_TEMP_TABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_TEMP_TABLE_name); + zend_string_release_ex(const_CREATE_TEMP_TABLE_name, true); zval const_CREATE_TEMP_TRIGGER_value; ZVAL_LONG(&const_CREATE_TEMP_TRIGGER_value, SQLITE_CREATE_TEMP_TRIGGER); - zend_string *const_CREATE_TEMP_TRIGGER_name = zend_string_init_interned("CREATE_TEMP_TRIGGER", sizeof("CREATE_TEMP_TRIGGER") - 1, 1); + zend_string *const_CREATE_TEMP_TRIGGER_name = zend_string_init_interned("CREATE_TEMP_TRIGGER", sizeof("CREATE_TEMP_TRIGGER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_TEMP_TRIGGER_name, &const_CREATE_TEMP_TRIGGER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_TEMP_TRIGGER_name); + zend_string_release_ex(const_CREATE_TEMP_TRIGGER_name, true); zval const_CREATE_TEMP_VIEW_value; ZVAL_LONG(&const_CREATE_TEMP_VIEW_value, SQLITE_CREATE_TEMP_VIEW); - zend_string *const_CREATE_TEMP_VIEW_name = zend_string_init_interned("CREATE_TEMP_VIEW", sizeof("CREATE_TEMP_VIEW") - 1, 1); + zend_string *const_CREATE_TEMP_VIEW_name = zend_string_init_interned("CREATE_TEMP_VIEW", sizeof("CREATE_TEMP_VIEW") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_TEMP_VIEW_name, &const_CREATE_TEMP_VIEW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_TEMP_VIEW_name); + zend_string_release_ex(const_CREATE_TEMP_VIEW_name, true); zval const_CREATE_TRIGGER_value; ZVAL_LONG(&const_CREATE_TRIGGER_value, SQLITE_CREATE_TRIGGER); - zend_string *const_CREATE_TRIGGER_name = zend_string_init_interned("CREATE_TRIGGER", sizeof("CREATE_TRIGGER") - 1, 1); + zend_string *const_CREATE_TRIGGER_name = zend_string_init_interned("CREATE_TRIGGER", sizeof("CREATE_TRIGGER") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_TRIGGER_name, &const_CREATE_TRIGGER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_TRIGGER_name); + zend_string_release_ex(const_CREATE_TRIGGER_name, true); zval const_CREATE_VIEW_value; ZVAL_LONG(&const_CREATE_VIEW_value, SQLITE_CREATE_VIEW); - zend_string *const_CREATE_VIEW_name = zend_string_init_interned("CREATE_VIEW", sizeof("CREATE_VIEW") - 1, 1); + zend_string *const_CREATE_VIEW_name = zend_string_init_interned("CREATE_VIEW", sizeof("CREATE_VIEW") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_VIEW_name, &const_CREATE_VIEW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_VIEW_name); + zend_string_release_ex(const_CREATE_VIEW_name, true); zval const_DELETE_value; ZVAL_LONG(&const_DELETE_value, SQLITE_DELETE); - zend_string *const_DELETE_name = zend_string_init_interned("DELETE", sizeof("DELETE") - 1, 1); + zend_string *const_DELETE_name = zend_string_init_interned("DELETE", sizeof("DELETE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DELETE_name, &const_DELETE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DELETE_name); + zend_string_release_ex(const_DELETE_name, true); zval const_DROP_INDEX_value; ZVAL_LONG(&const_DROP_INDEX_value, SQLITE_DROP_INDEX); - zend_string *const_DROP_INDEX_name = zend_string_init_interned("DROP_INDEX", sizeof("DROP_INDEX") - 1, 1); + zend_string *const_DROP_INDEX_name = zend_string_init_interned("DROP_INDEX", sizeof("DROP_INDEX") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_INDEX_name, &const_DROP_INDEX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_INDEX_name); + zend_string_release_ex(const_DROP_INDEX_name, true); zval const_DROP_TABLE_value; ZVAL_LONG(&const_DROP_TABLE_value, SQLITE_DROP_TABLE); - zend_string *const_DROP_TABLE_name = zend_string_init_interned("DROP_TABLE", sizeof("DROP_TABLE") - 1, 1); + zend_string *const_DROP_TABLE_name = zend_string_init_interned("DROP_TABLE", sizeof("DROP_TABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_TABLE_name, &const_DROP_TABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_TABLE_name); + zend_string_release_ex(const_DROP_TABLE_name, true); zval const_DROP_TEMP_INDEX_value; ZVAL_LONG(&const_DROP_TEMP_INDEX_value, SQLITE_DROP_TEMP_INDEX); - zend_string *const_DROP_TEMP_INDEX_name = zend_string_init_interned("DROP_TEMP_INDEX", sizeof("DROP_TEMP_INDEX") - 1, 1); + zend_string *const_DROP_TEMP_INDEX_name = zend_string_init_interned("DROP_TEMP_INDEX", sizeof("DROP_TEMP_INDEX") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_TEMP_INDEX_name, &const_DROP_TEMP_INDEX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_TEMP_INDEX_name); + zend_string_release_ex(const_DROP_TEMP_INDEX_name, true); zval const_DROP_TEMP_TABLE_value; ZVAL_LONG(&const_DROP_TEMP_TABLE_value, SQLITE_DROP_TEMP_TABLE); - zend_string *const_DROP_TEMP_TABLE_name = zend_string_init_interned("DROP_TEMP_TABLE", sizeof("DROP_TEMP_TABLE") - 1, 1); + zend_string *const_DROP_TEMP_TABLE_name = zend_string_init_interned("DROP_TEMP_TABLE", sizeof("DROP_TEMP_TABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_TEMP_TABLE_name, &const_DROP_TEMP_TABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_TEMP_TABLE_name); + zend_string_release_ex(const_DROP_TEMP_TABLE_name, true); zval const_DROP_TEMP_TRIGGER_value; ZVAL_LONG(&const_DROP_TEMP_TRIGGER_value, SQLITE_DROP_TEMP_TRIGGER); - zend_string *const_DROP_TEMP_TRIGGER_name = zend_string_init_interned("DROP_TEMP_TRIGGER", sizeof("DROP_TEMP_TRIGGER") - 1, 1); + zend_string *const_DROP_TEMP_TRIGGER_name = zend_string_init_interned("DROP_TEMP_TRIGGER", sizeof("DROP_TEMP_TRIGGER") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_TEMP_TRIGGER_name, &const_DROP_TEMP_TRIGGER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_TEMP_TRIGGER_name); + zend_string_release_ex(const_DROP_TEMP_TRIGGER_name, true); zval const_DROP_TEMP_VIEW_value; ZVAL_LONG(&const_DROP_TEMP_VIEW_value, SQLITE_DROP_TEMP_VIEW); - zend_string *const_DROP_TEMP_VIEW_name = zend_string_init_interned("DROP_TEMP_VIEW", sizeof("DROP_TEMP_VIEW") - 1, 1); + zend_string *const_DROP_TEMP_VIEW_name = zend_string_init_interned("DROP_TEMP_VIEW", sizeof("DROP_TEMP_VIEW") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_TEMP_VIEW_name, &const_DROP_TEMP_VIEW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_TEMP_VIEW_name); + zend_string_release_ex(const_DROP_TEMP_VIEW_name, true); zval const_DROP_TRIGGER_value; ZVAL_LONG(&const_DROP_TRIGGER_value, SQLITE_DROP_TRIGGER); - zend_string *const_DROP_TRIGGER_name = zend_string_init_interned("DROP_TRIGGER", sizeof("DROP_TRIGGER") - 1, 1); + zend_string *const_DROP_TRIGGER_name = zend_string_init_interned("DROP_TRIGGER", sizeof("DROP_TRIGGER") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_TRIGGER_name, &const_DROP_TRIGGER_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_TRIGGER_name); + zend_string_release_ex(const_DROP_TRIGGER_name, true); zval const_DROP_VIEW_value; ZVAL_LONG(&const_DROP_VIEW_value, SQLITE_DROP_VIEW); - zend_string *const_DROP_VIEW_name = zend_string_init_interned("DROP_VIEW", sizeof("DROP_VIEW") - 1, 1); + zend_string *const_DROP_VIEW_name = zend_string_init_interned("DROP_VIEW", sizeof("DROP_VIEW") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_VIEW_name, &const_DROP_VIEW_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_VIEW_name); + zend_string_release_ex(const_DROP_VIEW_name, true); zval const_INSERT_value; ZVAL_LONG(&const_INSERT_value, SQLITE_INSERT); - zend_string *const_INSERT_name = zend_string_init_interned("INSERT", sizeof("INSERT") - 1, 1); + zend_string *const_INSERT_name = zend_string_init_interned("INSERT", sizeof("INSERT") - 1, true); zend_declare_typed_class_constant(class_entry, const_INSERT_name, &const_INSERT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_INSERT_name); + zend_string_release_ex(const_INSERT_name, true); zval const_PRAGMA_value; ZVAL_LONG(&const_PRAGMA_value, SQLITE_PRAGMA); - zend_string *const_PRAGMA_name = zend_string_init_interned("PRAGMA", sizeof("PRAGMA") - 1, 1); + zend_string *const_PRAGMA_name = zend_string_init_interned("PRAGMA", sizeof("PRAGMA") - 1, true); zend_declare_typed_class_constant(class_entry, const_PRAGMA_name, &const_PRAGMA_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_PRAGMA_name); + zend_string_release_ex(const_PRAGMA_name, true); zval const_READ_value; ZVAL_LONG(&const_READ_value, SQLITE_READ); - zend_string *const_READ_name = zend_string_init_interned("READ", sizeof("READ") - 1, 1); + zend_string *const_READ_name = zend_string_init_interned("READ", sizeof("READ") - 1, true); zend_declare_typed_class_constant(class_entry, const_READ_name, &const_READ_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_READ_name); + zend_string_release_ex(const_READ_name, true); zval const_SELECT_value; ZVAL_LONG(&const_SELECT_value, SQLITE_SELECT); - zend_string *const_SELECT_name = zend_string_init_interned("SELECT", sizeof("SELECT") - 1, 1); + zend_string *const_SELECT_name = zend_string_init_interned("SELECT", sizeof("SELECT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SELECT_name, &const_SELECT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SELECT_name); + zend_string_release_ex(const_SELECT_name, true); zval const_TRANSACTION_value; ZVAL_LONG(&const_TRANSACTION_value, SQLITE_TRANSACTION); - zend_string *const_TRANSACTION_name = zend_string_init_interned("TRANSACTION", sizeof("TRANSACTION") - 1, 1); + zend_string *const_TRANSACTION_name = zend_string_init_interned("TRANSACTION", sizeof("TRANSACTION") - 1, true); zend_declare_typed_class_constant(class_entry, const_TRANSACTION_name, &const_TRANSACTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_TRANSACTION_name); + zend_string_release_ex(const_TRANSACTION_name, true); zval const_UPDATE_value; ZVAL_LONG(&const_UPDATE_value, SQLITE_UPDATE); - zend_string *const_UPDATE_name = zend_string_init_interned("UPDATE", sizeof("UPDATE") - 1, 1); + zend_string *const_UPDATE_name = zend_string_init_interned("UPDATE", sizeof("UPDATE") - 1, true); zend_declare_typed_class_constant(class_entry, const_UPDATE_name, &const_UPDATE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_UPDATE_name); + zend_string_release_ex(const_UPDATE_name, true); zval const_ATTACH_value; ZVAL_LONG(&const_ATTACH_value, SQLITE_ATTACH); - zend_string *const_ATTACH_name = zend_string_init_interned("ATTACH", sizeof("ATTACH") - 1, 1); + zend_string *const_ATTACH_name = zend_string_init_interned("ATTACH", sizeof("ATTACH") - 1, true); zend_declare_typed_class_constant(class_entry, const_ATTACH_name, &const_ATTACH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ATTACH_name); + zend_string_release_ex(const_ATTACH_name, true); zval const_DETACH_value; ZVAL_LONG(&const_DETACH_value, SQLITE_DETACH); - zend_string *const_DETACH_name = zend_string_init_interned("DETACH", sizeof("DETACH") - 1, 1); + zend_string *const_DETACH_name = zend_string_init_interned("DETACH", sizeof("DETACH") - 1, true); zend_declare_typed_class_constant(class_entry, const_DETACH_name, &const_DETACH_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DETACH_name); + zend_string_release_ex(const_DETACH_name, true); zval const_ALTER_TABLE_value; ZVAL_LONG(&const_ALTER_TABLE_value, SQLITE_ALTER_TABLE); - zend_string *const_ALTER_TABLE_name = zend_string_init_interned("ALTER_TABLE", sizeof("ALTER_TABLE") - 1, 1); + zend_string *const_ALTER_TABLE_name = zend_string_init_interned("ALTER_TABLE", sizeof("ALTER_TABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ALTER_TABLE_name, &const_ALTER_TABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ALTER_TABLE_name); + zend_string_release_ex(const_ALTER_TABLE_name, true); zval const_REINDEX_value; ZVAL_LONG(&const_REINDEX_value, SQLITE_REINDEX); - zend_string *const_REINDEX_name = zend_string_init_interned("REINDEX", sizeof("REINDEX") - 1, 1); + zend_string *const_REINDEX_name = zend_string_init_interned("REINDEX", sizeof("REINDEX") - 1, true); zend_declare_typed_class_constant(class_entry, const_REINDEX_name, &const_REINDEX_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_REINDEX_name); + zend_string_release_ex(const_REINDEX_name, true); zval const_ANALYZE_value; ZVAL_LONG(&const_ANALYZE_value, SQLITE_ANALYZE); - zend_string *const_ANALYZE_name = zend_string_init_interned("ANALYZE", sizeof("ANALYZE") - 1, 1); + zend_string *const_ANALYZE_name = zend_string_init_interned("ANALYZE", sizeof("ANALYZE") - 1, true); zend_declare_typed_class_constant(class_entry, const_ANALYZE_name, &const_ANALYZE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_ANALYZE_name); + zend_string_release_ex(const_ANALYZE_name, true); zval const_CREATE_VTABLE_value; ZVAL_LONG(&const_CREATE_VTABLE_value, SQLITE_CREATE_VTABLE); - zend_string *const_CREATE_VTABLE_name = zend_string_init_interned("CREATE_VTABLE", sizeof("CREATE_VTABLE") - 1, 1); + zend_string *const_CREATE_VTABLE_name = zend_string_init_interned("CREATE_VTABLE", sizeof("CREATE_VTABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_CREATE_VTABLE_name, &const_CREATE_VTABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_CREATE_VTABLE_name); + zend_string_release_ex(const_CREATE_VTABLE_name, true); zval const_DROP_VTABLE_value; ZVAL_LONG(&const_DROP_VTABLE_value, SQLITE_DROP_VTABLE); - zend_string *const_DROP_VTABLE_name = zend_string_init_interned("DROP_VTABLE", sizeof("DROP_VTABLE") - 1, 1); + zend_string *const_DROP_VTABLE_name = zend_string_init_interned("DROP_VTABLE", sizeof("DROP_VTABLE") - 1, true); zend_declare_typed_class_constant(class_entry, const_DROP_VTABLE_name, &const_DROP_VTABLE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_DROP_VTABLE_name); + zend_string_release_ex(const_DROP_VTABLE_name, true); zval const_FUNCTION_value; ZVAL_LONG(&const_FUNCTION_value, SQLITE_FUNCTION); - zend_string *const_FUNCTION_name = zend_string_init_interned("FUNCTION", sizeof("FUNCTION") - 1, 1); + zend_string *const_FUNCTION_name = zend_string_init_interned("FUNCTION", sizeof("FUNCTION") - 1, true); zend_declare_typed_class_constant(class_entry, const_FUNCTION_name, &const_FUNCTION_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_FUNCTION_name); + zend_string_release_ex(const_FUNCTION_name, true); zval const_SAVEPOINT_value; ZVAL_LONG(&const_SAVEPOINT_value, SQLITE_SAVEPOINT); - zend_string *const_SAVEPOINT_name = zend_string_init_interned("SAVEPOINT", sizeof("SAVEPOINT") - 1, 1); + zend_string *const_SAVEPOINT_name = zend_string_init_interned("SAVEPOINT", sizeof("SAVEPOINT") - 1, true); zend_declare_typed_class_constant(class_entry, const_SAVEPOINT_name, &const_SAVEPOINT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_SAVEPOINT_name); + zend_string_release_ex(const_SAVEPOINT_name, true); zval const_COPY_value; ZVAL_LONG(&const_COPY_value, SQLITE_COPY); - zend_string *const_COPY_name = zend_string_init_interned("COPY", sizeof("COPY") - 1, 1); + zend_string *const_COPY_name = zend_string_init_interned("COPY", sizeof("COPY") - 1, true); zend_declare_typed_class_constant(class_entry, const_COPY_name, &const_COPY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_COPY_name); + zend_string_release_ex(const_COPY_name, true); #if defined(SQLITE_RECURSIVE) zval const_RECURSIVE_value; ZVAL_LONG(&const_RECURSIVE_value, SQLITE_RECURSIVE); - zend_string *const_RECURSIVE_name = zend_string_init_interned("RECURSIVE", sizeof("RECURSIVE") - 1, 1); + zend_string *const_RECURSIVE_name = zend_string_init_interned("RECURSIVE", sizeof("RECURSIVE") - 1, true); zend_declare_typed_class_constant(class_entry, const_RECURSIVE_name, &const_RECURSIVE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_RECURSIVE_name); + zend_string_release_ex(const_RECURSIVE_name, true); #endif return class_entry; @@ -567,21 +561,21 @@ static zend_class_entry *register_class_SQLite3Stmt(void) zval const_EXPLAIN_MODE_PREPARED_value; ZVAL_LONG(&const_EXPLAIN_MODE_PREPARED_value, 0); - zend_string *const_EXPLAIN_MODE_PREPARED_name = zend_string_init_interned("EXPLAIN_MODE_PREPARED", sizeof("EXPLAIN_MODE_PREPARED") - 1, 1); + zend_string *const_EXPLAIN_MODE_PREPARED_name = zend_string_init_interned("EXPLAIN_MODE_PREPARED", sizeof("EXPLAIN_MODE_PREPARED") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXPLAIN_MODE_PREPARED_name, &const_EXPLAIN_MODE_PREPARED_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXPLAIN_MODE_PREPARED_name); + zend_string_release_ex(const_EXPLAIN_MODE_PREPARED_name, true); zval const_EXPLAIN_MODE_EXPLAIN_value; ZVAL_LONG(&const_EXPLAIN_MODE_EXPLAIN_value, 1); - zend_string *const_EXPLAIN_MODE_EXPLAIN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN", sizeof("EXPLAIN_MODE_EXPLAIN") - 1, 1); + zend_string *const_EXPLAIN_MODE_EXPLAIN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN", sizeof("EXPLAIN_MODE_EXPLAIN") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXPLAIN_MODE_EXPLAIN_name, &const_EXPLAIN_MODE_EXPLAIN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXPLAIN_MODE_EXPLAIN_name); + zend_string_release_ex(const_EXPLAIN_MODE_EXPLAIN_name, true); zval const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_value; ZVAL_LONG(&const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_value, 2); - zend_string *const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN", sizeof("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN") - 1, 1); + zend_string *const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name = zend_string_init_interned("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN", sizeof("EXPLAIN_MODE_EXPLAIN_QUERY_PLAN") - 1, true); zend_declare_typed_class_constant(class_entry, const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name, &const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name); + zend_string_release_ex(const_EXPLAIN_MODE_EXPLAIN_QUERY_PLAN_name, true); #endif return class_entry; diff --git a/ext/sqlite3/tests/bug72668.phpt b/ext/sqlite3/tests/bug72668.phpt index 40ede8883cc2..7f33338eb5e6 100644 --- a/ext/sqlite3/tests/bug72668.phpt +++ b/ext/sqlite3/tests/bug72668.phpt @@ -12,20 +12,20 @@ $db = new SQLite3(':memory:'); $db->createFunction('my_udf_md5', 'my_udf_md5'); try { - $result = $db->query('SELECT my_udf_md5("test")'); + $result = $db->query("SELECT my_udf_md5('test')"); var_dump($result); } catch(\Exception $e) { echo "Exception: ".$e->getMessage(); } try { - $result = $db->querySingle('SELECT my_udf_md5("test")'); + $result = $db->querySingle("SELECT my_udf_md5('test')"); var_dump($result); } catch(\Exception $e) { echo "Exception: ".$e->getMessage(); } -$statement = $db->prepare('SELECT my_udf_md5("test")'); +$statement = $db->prepare("SELECT my_udf_md5('test')"); try { $result = $statement->execute(); var_dump($result); diff --git a/ext/sqlite3/tests/gh20699.phpt b/ext/sqlite3/tests/gh20699.phpt new file mode 100644 index 000000000000..1b53bfc98e39 --- /dev/null +++ b/ext/sqlite3/tests/gh20699.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-20699 (SQLite3Result fetchArray return array|false, null returned) +--EXTENSIONS-- +sqlite3 +--CREDITS-- +plusminmax +--FILE-- +prepare('BEGIN;')->execute()->fetchArray()); +?> +--EXPECTF-- +Warning: SQLite3Result::fetchArray(): Unable to execute statement: cannot start a transaction within a transaction in %s on line %d +bool(false) diff --git a/ext/sqlite3/tests/sqlite3_11_numrows.phpt b/ext/sqlite3/tests/sqlite3_11_numrows.phpt deleted file mode 100644 index 29faea68f8eb..000000000000 --- a/ext/sqlite3/tests/sqlite3_11_numrows.phpt +++ /dev/null @@ -1,48 +0,0 @@ ---TEST-- -SQLite3::prepare number of rows ---EXTENSIONS-- -sqlite3 ---SKIPIF-- - ---FILE-- -exec('CREATE TABLE test (time INTEGER, id STRING)')); - -echo "INSERT into table\n"; -var_dump($db->exec("INSERT INTO test (time, id) VALUES (" . TIMENOW . ", 'a')")); -var_dump($db->exec("INSERT INTO test (time, id) VALUES (" . TIMENOW . ", 'b')")); - -echo "SELECTING results\n"; -$results = $db->query("SELECT * FROM test ORDER BY id ASC"); -echo "Number of rows\n"; -var_dump($results->numRows()); -$results->finalize(); - -echo "Closing database\n"; -var_dump($db->close()); -echo "Done\n"; -?> ---EXPECT-- -Creating Table -bool(true) -INSERT into table -bool(true) -bool(true) -SELECTING results -Number of rows -int(2) -Closing database -bool(true) -Done diff --git a/ext/sqlite3/tests/sqlite3_29_createfunction.phpt b/ext/sqlite3/tests/sqlite3_29_createfunction.phpt index ef28b3b62def..1a511ee13996 100644 --- a/ext/sqlite3/tests/sqlite3_29_createfunction.phpt +++ b/ext/sqlite3/tests/sqlite3_29_createfunction.phpt @@ -9,14 +9,14 @@ require_once(__DIR__ . '/new_db.inc'); $func = 'strtoupper'; var_dump($db->createfunction($func, $func)); -var_dump($db->querySingle('SELECT strtoupper("test")')); +var_dump($db->querySingle("SELECT strtoupper('test')")); $func2 = 'strtolower'; var_dump($db->createfunction($func2, $func2)); -var_dump($db->querySingle('SELECT strtolower("TEST")')); +var_dump($db->querySingle("SELECT strtolower('TEST')")); var_dump($db->createfunction($func, $func2)); -var_dump($db->querySingle('SELECT strtoupper("tEst")')); +var_dump($db->querySingle("SELECT strtoupper('tEst')")); ?> diff --git a/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt b/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt index 49f029d5854f..e07d5b73e999 100644 --- a/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt +++ b/ext/sqlite3/tests/sqlite3_35_stmt_readonly.phpt @@ -2,13 +2,6 @@ SQLite3_stmt::readOnly check --EXTENSIONS-- sqlite3 ---SKIPIF-- - --FILE-- = 3.8.3'); ?> --FILE-- createfunction($func, $func, 1, SQLITE3_DETERMINISTIC)); -var_dump($db->querySingle('SELECT strtoupper("test")')); +var_dump($db->querySingle("SELECT strtoupper('test')")); $func2 = 'strtolower'; var_dump($db->createfunction($func2, $func2, 1, SQLITE3_DETERMINISTIC)); -var_dump($db->querySingle('SELECT strtolower("TEST")')); +var_dump($db->querySingle("SELECT strtolower('TEST')")); var_dump($db->createfunction($func, $func2, 1, SQLITE3_DETERMINISTIC)); -var_dump($db->querySingle('SELECT strtoupper("tEst")')); +var_dump($db->querySingle("SELECT strtoupper('tEst')")); ?> diff --git a/ext/sqlite3/tests/sqlite3_dqs.phpt b/ext/sqlite3/tests/sqlite3_dqs.phpt new file mode 100644 index 000000000000..1efa8ad475fe --- /dev/null +++ b/ext/sqlite3/tests/sqlite3_dqs.phpt @@ -0,0 +1,28 @@ +--TEST-- +SQLite3 DQS +--EXTENSIONS-- +sqlite3 +--SKIPIF-- +enableExceptions(true); + $db->exec('SELECT "test"'); +} catch (\SQLite3Exception) { + die('skip SQLite is lacking DQS'); +} +?> +--FILE-- +exec('CREATE TABLE test (s1 VARCHAR(255), s2 VARCHAR(255))'); +$db->exec('INSERT INTO test VALUES (\'test\', "test")'); +var_dump($db->prepare('SELECT * FROM test')->execute()->fetchArray(SQLITE3_ASSOC)); +?> +--EXPECT-- +array(2) { + ["s1"]=> + string(4) "test" + ["s2"]=> + string(4) "test" +} diff --git a/ext/sqlite3/tests/sqlite3_explain.phpt b/ext/sqlite3/tests/sqlite3_explain.phpt index f580783ca1d1..1f9d4fc940e4 100644 --- a/ext/sqlite3/tests/sqlite3_explain.phpt +++ b/ext/sqlite3/tests/sqlite3_explain.phpt @@ -14,7 +14,7 @@ if ($version <= 3043000) die("skip for sqlite3 < 3.43.0"); require_once(__DIR__ . '/new_db.inc'); $db->exec('CREATE TABLE test_explain (a string);'); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setExplain(Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN); var_dump($stmt->explain() == Sqlite3Stmt::EXPLAIN_MODE_EXPLAIN); $r = $stmt->execute(); @@ -28,7 +28,7 @@ $result = []; while (($arr = $r->fetchArray(SQLITE3_ASSOC)) !== false) $result[] = $arr; var_dump($result); -$stmt = $db->prepare('INSERT INTO test_explain VALUES ("first insert"), ("second_insert")'); +$stmt = $db->prepare("INSERT INTO test_explain VALUES ('first insert'), ('second_insert')"); $stmt->setExplain(Sqlite3Stmt::EXPLAIN_MODE_PREPARED); $stmt->execute(); $stmts = $db->prepare('SELECT * FROM test_explain'); @@ -79,15 +79,15 @@ array(%d) { ["addr"]=> int(1) ["opcode"]=> - string(13) "InitCoroutine" + string(%d) "%s" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> int(2) ["p4"]=> - NULL + %s ["p5"]=> int(0) ["comment"]=> @@ -102,7 +102,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -119,7 +119,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -140,7 +140,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(2) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -157,7 +157,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -176,7 +176,7 @@ array(%d) { ["opcode"]=> string(12) "EndCoroutine" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(0) ["p3"]=> @@ -214,7 +214,7 @@ array(%d) { ["opcode"]=> string(5) "Yield" ["p1"]=> - int(3) + int(%d) ["p2"]=> int(%d) ["p3"]=> @@ -235,7 +235,7 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(1) + int(%d) ["p3"]=> int(0) ["p4"]=> @@ -252,11 +252,11 @@ array(%d) { ["opcode"]=> string(10) "MakeRecord" ["p1"]=> - int(2) + int(%d) ["p2"]=> int(1) ["p3"]=> - int(4) + int(%d) ["p4"]=> string(1) "C" ["p5"]=> @@ -273,9 +273,9 @@ array(%d) { ["p1"]=> int(0) ["p2"]=> - int(4) + int(%d) ["p3"]=> - int(1) + int(%d) ["p4"]=> string(12) "test_explain" ["p5"]=> @@ -368,7 +368,7 @@ array(1) { ["parent"]=> int(0) ["notused"]=> - int(0) + int(%d) ["detail"]=> string(17) "SCAN test_explain" } diff --git a/ext/sqlite3/tests/sqlite3_rename_column.phpt b/ext/sqlite3/tests/sqlite3_rename_column.phpt index 6b4e23bc7186..a3a4caef3ce6 100644 --- a/ext/sqlite3/tests/sqlite3_rename_column.phpt +++ b/ext/sqlite3/tests/sqlite3_rename_column.phpt @@ -14,7 +14,7 @@ if (SQLite3::version()['versionNumber'] < 3025000) { $db = new SQLite3(':memory:'); $db->exec('CREATE TABLE tbl (orig text)'); -$db->exec('insert into tbl values ("one"), ("two")'); +$db->exec("insert into tbl values ('one'), ('two')"); $res1 = $db->prepare('select * from tbl')->execute(); $res2 = $db->prepare('select * from tbl')->execute(); diff --git a/ext/sqlite3/tests/sqlite3_stmt_busy.phpt b/ext/sqlite3/tests/sqlite3_stmt_busy.phpt index 8110d374afe6..eb278561b575 100644 --- a/ext/sqlite3/tests/sqlite3_stmt_busy.phpt +++ b/ext/sqlite3/tests/sqlite3_stmt_busy.phpt @@ -2,17 +2,12 @@ SQLite3_stmt::busy --EXTENSIONS-- sqlite3 ---SKIPIF-- - --FILE-- exec('CREATE TABLE test_busy (a string);'); -$db->exec('INSERT INTO test_busy VALUES ("interleaved"), ("statements")'); +$db->exec("INSERT INTO test_busy VALUES ('interleaved'), ('statements')"); $st = $db->prepare('SELECT a FROM test_busy'); var_dump($st->busy()); $r = $st->execute(); diff --git a/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt b/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt index 81245f5b4bef..52d5b726415e 100644 --- a/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt +++ b/ext/sqlite3/tests/sqlite3_trampoline_createfunction.phpt @@ -16,8 +16,8 @@ class TrampolineTest { $o = new TrampolineTest(); $callback = [$o, 'strtoupper']; var_dump($db->createfunction('strtoupper', $callback)); -var_dump($db->querySingle('SELECT strtoupper("test")')); -var_dump($db->querySingle('SELECT strtoupper("test")')); +var_dump($db->querySingle("SELECT strtoupper('test')")); +var_dump($db->querySingle("SELECT strtoupper('test')")); ?> --EXPECT-- diff --git a/ext/sqlite3/tests/text_column_NUL_bytes.phpt b/ext/sqlite3/tests/text_column_NUL_bytes.phpt new file mode 100644 index 000000000000..cf9403d91302 --- /dev/null +++ b/ext/sqlite3/tests/text_column_NUL_bytes.phpt @@ -0,0 +1,38 @@ +--TEST-- +Text column with NUL bytes +--EXTENSIONS-- +sqlite3 +--FILE-- +exec( + 'CREATE TABLE messages ( + content TEXT + )' +); + +$insert = $db->prepare( + 'INSERT INTO messages (content) VALUES (:content)' +); + +$insert->bindValue(':content', "with\0null", SQLITE3_TEXT); +$insert->execute(); +$insert->bindValue(':content', "\0", SQLITE3_TEXT); +$insert->execute(); + +$result = $db->query('SELECT * FROM messages'); +while ($row = $result->fetchArray(SQLITE3_ASSOC)) { + var_dump($row); +} + +?> +--EXPECTF-- +array(1) { + ["content"]=> + string(9) "with%0null" +} +array(1) { + ["content"]=> + string(1) "%0" +} diff --git a/ext/standard/array.c b/ext/standard/array.c index 522e7f715acb..25259c47d61b 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -60,6 +58,7 @@ /* }}} */ ZEND_DECLARE_MODULE_GLOBALS(array) +PHPAPI zend_class_entry *sort_direction_ce; /* {{{ php_array_init_globals */ static void php_array_init_globals(zend_array_globals *array_globals) @@ -214,7 +213,7 @@ static zend_always_inline int php_array_key_compare_string_unstable_i(Bucket *f, } /* }}} */ -static int php_array_key_compare_string_natural_general(Bucket *f, Bucket *s, int fold_case) /* {{{ */ +static int php_array_key_compare_string_natural_general(Bucket *f, Bucket *s, bool fold_case) /* {{{ */ { const char *s1, *s2; size_t l1, l2; @@ -241,25 +240,25 @@ static int php_array_key_compare_string_natural_general(Bucket *f, Bucket *s, in static int php_array_key_compare_string_natural_case(Bucket *a, Bucket *b) /* {{{ */ { - RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(a, b, 1)); + RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(a, b, true)); } /* }}} */ static int php_array_reverse_key_compare_string_natural_case(Bucket *a, Bucket *b) /* {{{ */ { - RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(b, a, 1)); + RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(b, a, true)); } /* }}} */ static int php_array_key_compare_string_natural(Bucket *a, Bucket *b) /* {{{ */ { - RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(a, b, 0)); + RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(a, b, false)); } /* }}} */ static int php_array_reverse_key_compare_string_natural(Bucket *a, Bucket *b) /* {{{ */ { - RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(b, a, 0)); + RETURN_STABLE_SORT(a, b, php_array_key_compare_string_natural_general(b, a, false)); } /* }}} */ @@ -327,7 +326,7 @@ static zend_always_inline int php_array_data_compare_string_unstable_i(Bucket *f } /* }}} */ -static int php_array_natural_general_compare(Bucket *f, Bucket *s, int fold_case) /* {{{ */ +static int php_array_natural_general_compare(Bucket *f, Bucket *s, bool fold_case) /* {{{ */ { zend_string *tmp_str1, *tmp_str2; zend_string *str1 = zval_get_tmp_string(&f->val, &tmp_str1); @@ -343,13 +342,13 @@ static int php_array_natural_general_compare(Bucket *f, Bucket *s, int fold_case static zend_always_inline int php_array_natural_compare_unstable_i(Bucket *a, Bucket *b) /* {{{ */ { - return php_array_natural_general_compare(a, b, 0); + return php_array_natural_general_compare(a, b, false); } /* }}} */ static zend_always_inline int php_array_natural_case_compare_unstable_i(Bucket *a, Bucket *b) /* {{{ */ { - return php_array_natural_general_compare(a, b, 1); + return php_array_natural_general_compare(a, b, true); } /* }}} */ @@ -372,135 +371,127 @@ DEFINE_SORT_VARIANTS(data_compare_string_locale); DEFINE_SORT_VARIANTS(natural_compare); DEFINE_SORT_VARIANTS(natural_case_compare); -static bucket_compare_func_t php_get_key_compare_func(zend_long sort_type, int reverse) /* {{{ */ +static bucket_compare_func_t php_get_key_compare_func(zend_long sort_type) { switch (sort_type & ~PHP_SORT_FLAG_CASE) { case PHP_SORT_NUMERIC: - if (reverse) { - return php_array_reverse_key_compare_numeric; - } else { - return php_array_key_compare_numeric; - } - break; + return php_array_key_compare_numeric; case PHP_SORT_STRING: if (sort_type & PHP_SORT_FLAG_CASE) { - if (reverse) { - return php_array_reverse_key_compare_string_case; - } else { - return php_array_key_compare_string_case; - } + return php_array_key_compare_string_case; } else { - if (reverse) { - return php_array_reverse_key_compare_string; - } else { - return php_array_key_compare_string; - } + return php_array_key_compare_string; } - break; case PHP_SORT_NATURAL: if (sort_type & PHP_SORT_FLAG_CASE) { - if (reverse) { - return php_array_reverse_key_compare_string_natural_case; - } else { - return php_array_key_compare_string_natural_case; - } + return php_array_key_compare_string_natural_case; } else { - if (reverse) { - return php_array_reverse_key_compare_string_natural; - } else { - return php_array_key_compare_string_natural; - } + return php_array_key_compare_string_natural; } - break; case PHP_SORT_LOCALE_STRING: - if (reverse) { - return php_array_reverse_key_compare_string_locale; - } else { - return php_array_key_compare_string_locale; - } - break; + return php_array_key_compare_string_locale; case PHP_SORT_REGULAR: default: - if (reverse) { - return php_array_reverse_key_compare; - } else { - return php_array_key_compare; - } - break; + return php_array_key_compare; } return NULL; } -/* }}} */ -static bucket_compare_func_t php_get_data_compare_func(zend_long sort_type, int reverse) /* {{{ */ +static bucket_compare_func_t php_get_key_reverse_compare_func(zend_long sort_type) { switch (sort_type & ~PHP_SORT_FLAG_CASE) { case PHP_SORT_NUMERIC: - if (reverse) { - return php_array_reverse_data_compare_numeric; - } else { - return php_array_data_compare_numeric; - } - break; + return php_array_reverse_key_compare_numeric; case PHP_SORT_STRING: if (sort_type & PHP_SORT_FLAG_CASE) { - if (reverse) { - return php_array_reverse_data_compare_string_case; - } else { - return php_array_data_compare_string_case; - } + return php_array_reverse_key_compare_string_case; } else { - if (reverse) { - return php_array_reverse_data_compare_string; - } else { - return php_array_data_compare_string; - } + return php_array_reverse_key_compare_string; } - break; case PHP_SORT_NATURAL: if (sort_type & PHP_SORT_FLAG_CASE) { - if (reverse) { - return php_array_reverse_natural_case_compare; - } else { - return php_array_natural_case_compare; - } + return php_array_reverse_key_compare_string_natural_case; } else { - if (reverse) { - return php_array_reverse_natural_compare; - } else { - return php_array_natural_compare; - } + return php_array_reverse_key_compare_string_natural; } - break; case PHP_SORT_LOCALE_STRING: - if (reverse) { - return php_array_reverse_data_compare_string_locale; + return php_array_reverse_key_compare_string_locale; + + case PHP_SORT_REGULAR: + default: + return php_array_reverse_key_compare; + } + return NULL; +} + +static bucket_compare_func_t php_get_data_compare_func(zend_long sort_type) /* {{{ */ +{ + switch (sort_type & ~PHP_SORT_FLAG_CASE) { + case PHP_SORT_NUMERIC: + return php_array_data_compare_numeric; + + case PHP_SORT_STRING: + if (sort_type & PHP_SORT_FLAG_CASE) { + return php_array_data_compare_string_case; } else { - return php_array_data_compare_string_locale; + return php_array_data_compare_string; } - break; + + case PHP_SORT_NATURAL: + if (sort_type & PHP_SORT_FLAG_CASE) { + return php_array_natural_case_compare; + } else { + return php_array_natural_compare; + } + + case PHP_SORT_LOCALE_STRING: + return php_array_data_compare_string_locale; case PHP_SORT_REGULAR: default: - if (reverse) { - return php_array_reverse_data_compare; + return php_array_data_compare; + } + return NULL; +} + +static bucket_compare_func_t php_get_data_reverse_compare_func(zend_long sort_type) /* {{{ */ +{ + switch (sort_type & ~PHP_SORT_FLAG_CASE) { + case PHP_SORT_NUMERIC: + return php_array_reverse_data_compare_numeric; + + case PHP_SORT_STRING: + if (sort_type & PHP_SORT_FLAG_CASE) { + return php_array_reverse_data_compare_string_case; } else { - return php_array_data_compare; + return php_array_reverse_data_compare_string; } - break; + + case PHP_SORT_NATURAL: + if (sort_type & PHP_SORT_FLAG_CASE) { + return php_array_reverse_natural_case_compare; + } else { + return php_array_reverse_natural_compare; + } + + case PHP_SORT_LOCALE_STRING: + return php_array_reverse_data_compare_string_locale; + + case PHP_SORT_REGULAR: + default: + return php_array_reverse_data_compare; } return NULL; } -/* }}} */ -static bucket_compare_func_t php_get_data_compare_func_unstable(zend_long sort_type, int reverse) /* {{{ */ +static bucket_compare_func_t php_get_data_compare_func_unstable(zend_long sort_type, bool reverse) /* {{{ */ { switch (sort_type & ~PHP_SORT_FLAG_CASE) { case PHP_SORT_NUMERIC: @@ -564,48 +555,6 @@ static bucket_compare_func_t php_get_data_compare_func_unstable(zend_long sort_t } /* }}} */ -/* {{{ Sort an array by key value in reverse order */ -PHP_FUNCTION(krsort) -{ - zval *array; - zend_long sort_type = PHP_SORT_REGULAR; - bucket_compare_func_t cmp; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY_EX(array, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(sort_type) - ZEND_PARSE_PARAMETERS_END(); - - cmp = php_get_key_compare_func(sort_type, 1); - - zend_hash_sort(Z_ARRVAL_P(array), cmp, 0); - - RETURN_TRUE; -} -/* }}} */ - -/* {{{ Sort an array by key */ -PHP_FUNCTION(ksort) -{ - zval *array; - zend_long sort_type = PHP_SORT_REGULAR; - bucket_compare_func_t cmp; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY_EX(array, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(sort_type) - ZEND_PARSE_PARAMETERS_END(); - - cmp = php_get_key_compare_func(sort_type, 0); - - zend_hash_sort(Z_ARRVAL_P(array), cmp, 0); - - RETURN_TRUE; -} -/* }}} */ - PHPAPI zend_long php_count_recursive(HashTable *ht) /* {{{ */ { zend_long cnt = 0; @@ -670,7 +619,6 @@ PHP_FUNCTION(count) cnt = php_count_recursive(Z_ARRVAL_P(array)); } RETURN_LONG(cnt); - break; case IS_OBJECT: { zval retval; /* first, we check if the handler is defined */ @@ -702,119 +650,92 @@ PHP_FUNCTION(count) } /* }}} */ -static void php_natsort(INTERNAL_FUNCTION_PARAMETERS, int fold_case) /* {{{ */ +static void php_natsort(INTERNAL_FUNCTION_PARAMETERS, bucket_compare_func_t sort_fn) { - zval *array; + HashTable *array; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY_EX(array, 0, 1) + Z_PARAM_ARRAY_HT_EX(array, 0, 1) ZEND_PARSE_PARAMETERS_END(); - if (fold_case) { - zend_array_sort(Z_ARRVAL_P(array), php_array_natural_case_compare, 0); - } else { - zend_array_sort(Z_ARRVAL_P(array), php_array_natural_compare, 0); - } + zend_array_sort(array, sort_fn, false); RETURN_TRUE; } -/* }}} */ /* {{{ Sort an array using natural sort */ PHP_FUNCTION(natsort) { - php_natsort(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_natsort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_natural_compare); } /* }}} */ /* {{{ Sort an array using case-insensitive natural sort */ PHP_FUNCTION(natcasesort) { - php_natsort(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_natsort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_natural_case_compare); } /* }}} */ -/* {{{ Sort an array and maintain index association */ -PHP_FUNCTION(asort) -{ - zval *array; +typedef bucket_compare_func_t(*get_compare_function)(zend_long); + +static zend_always_inline void php_sort(INTERNAL_FUNCTION_PARAMETERS, get_compare_function get_cmp, bool renumber) { + HashTable *array; zend_long sort_type = PHP_SORT_REGULAR; bucket_compare_func_t cmp; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY_EX(array, 0, 1) + Z_PARAM_ARRAY_HT_EX(array, 0, 1) Z_PARAM_OPTIONAL Z_PARAM_LONG(sort_type) ZEND_PARSE_PARAMETERS_END(); - cmp = php_get_data_compare_func(sort_type, 0); + cmp = get_cmp(sort_type); - zend_array_sort(Z_ARRVAL_P(array), cmp, 0); + zend_array_sort(array, cmp, renumber); RETURN_TRUE; } + +/* {{{ Sort an array and maintain index association */ +PHP_FUNCTION(asort) +{ + php_sort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_get_data_compare_func, false); +} /* }}} */ /* {{{ Sort an array in reverse order and maintain index association */ PHP_FUNCTION(arsort) { - zval *array; - zend_long sort_type = PHP_SORT_REGULAR; - bucket_compare_func_t cmp; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY_EX(array, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(sort_type) - ZEND_PARSE_PARAMETERS_END(); - - cmp = php_get_data_compare_func(sort_type, 1); - - zend_array_sort(Z_ARRVAL_P(array), cmp, 0); - - RETURN_TRUE; + php_sort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_get_data_reverse_compare_func, false); } /* }}} */ /* {{{ Sort an array */ PHP_FUNCTION(sort) { - zval *array; - zend_long sort_type = PHP_SORT_REGULAR; - bucket_compare_func_t cmp; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY_EX(array, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(sort_type) - ZEND_PARSE_PARAMETERS_END(); - - cmp = php_get_data_compare_func(sort_type, 0); - - zend_array_sort(Z_ARRVAL_P(array), cmp, 1); - - RETURN_TRUE; + php_sort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_get_data_compare_func, true); } /* }}} */ /* {{{ Sort an array in reverse order */ PHP_FUNCTION(rsort) { - zval *array; - zend_long sort_type = PHP_SORT_REGULAR; - bucket_compare_func_t cmp; - - ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_ARRAY_EX(array, 0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(sort_type) - ZEND_PARSE_PARAMETERS_END(); - - cmp = php_get_data_compare_func(sort_type, 1); + php_sort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_get_data_reverse_compare_func, true); +} +/* }}} */ - zend_array_sort(Z_ARRVAL_P(array), cmp, 1); +/* {{{ Sort an array by key value in reverse order */ +PHP_FUNCTION(krsort) +{ + php_sort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_get_key_reverse_compare_func, false); +} +/* }}} */ - RETURN_TRUE; +/* {{{ Sort an array by key */ +PHP_FUNCTION(ksort) +{ + php_sort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_get_key_compare_func, false); } /* }}} */ @@ -912,14 +833,14 @@ static void php_usort(INTERNAL_FUNCTION_PARAMETERS, bucket_compare_func_t compar /* {{{ Sort an array by values using a user-defined comparison function */ PHP_FUNCTION(usort) { - php_usort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_user_compare, 1); + php_usort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_user_compare, true); } /* }}} */ /* {{{ Sort an array with a user-defined comparison function and maintain index association */ PHP_FUNCTION(uasort) { - php_usort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_user_compare, 0); + php_usort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_user_compare, false); } /* }}} */ @@ -986,7 +907,7 @@ static int php_array_user_key_compare(Bucket *a, Bucket *b) /* {{{ */ /* {{{ Sort an array by keys using a user-defined comparison function */ PHP_FUNCTION(uksort) { - php_usort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_user_key_compare, 0); + php_usort(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_array_user_key_compare, false); } /* }}} */ @@ -1219,7 +1140,7 @@ PHP_FUNCTION(min) min_lval = Z_LVAL(args[i]); min = &args[i]; } - } else if (Z_TYPE(args[i]) == IS_DOUBLE && (zend_dval_to_lval((double) min_lval) == min_lval)) { + } else if (Z_TYPE(args[i]) == IS_DOUBLE && (zend_dval_to_lval_silent((double) min_lval) == min_lval)) { /* if min_lval can be exactly represented as a double, go to double dedicated code */ min_dval = (double) min_lval; goto double_compare; @@ -1239,7 +1160,7 @@ PHP_FUNCTION(min) min_dval = Z_DVAL(args[i]); min = &args[i]; } - } else if (Z_TYPE(args[i]) == IS_LONG && (zend_dval_to_lval((double) Z_LVAL(args[i])) == Z_LVAL(args[i]))) { + } else if (Z_TYPE(args[i]) == IS_LONG && (zend_dval_to_lval_silent((double) Z_LVAL(args[i])) == Z_LVAL(args[i]))) { /* if the value can be exactly represented as a double, use double dedicated code otherwise generic */ if (min_dval > (double)Z_LVAL(args[i])) { min_dval = (double)Z_LVAL(args[i]); @@ -1277,7 +1198,7 @@ ZEND_FRAMELESS_FUNCTION(min, 2) if (EXPECTED(Z_TYPE_P(rhs) == IS_LONG)) { RETURN_COPY_VALUE(lhs_lval < Z_LVAL_P(rhs) ? lhs : rhs); - } else if (Z_TYPE_P(rhs) == IS_DOUBLE && (zend_dval_to_lval((double) lhs_lval) == lhs_lval)) { + } else if (Z_TYPE_P(rhs) == IS_DOUBLE && (zend_dval_to_lval_silent((double) lhs_lval) == lhs_lval)) { /* if lhs_lval can be exactly represented as a double, go to double dedicated code */ lhs_dval = (double) lhs_lval; goto double_compare; @@ -1290,7 +1211,7 @@ ZEND_FRAMELESS_FUNCTION(min, 2) if (EXPECTED(Z_TYPE_P(rhs) == IS_DOUBLE)) { double_compare: RETURN_COPY_VALUE(lhs_dval < Z_DVAL_P(rhs) ? lhs : rhs); - } else if (Z_TYPE_P(rhs) == IS_LONG && (zend_dval_to_lval((double) Z_LVAL_P(rhs)) == Z_LVAL_P(rhs))) { + } else if (Z_TYPE_P(rhs) == IS_LONG && (zend_dval_to_lval_silent((double) Z_LVAL_P(rhs)) == Z_LVAL_P(rhs))) { /* if the value can be exactly represented as a double, use double dedicated code otherwise generic */ RETURN_COPY_VALUE(lhs_dval < (double)Z_LVAL_P(rhs) ? lhs : rhs); } else { @@ -1347,7 +1268,7 @@ PHP_FUNCTION(max) max_lval = Z_LVAL(args[i]); max = &args[i]; } - } else if (Z_TYPE(args[i]) == IS_DOUBLE && (zend_dval_to_lval((double) max_lval) == max_lval)) { + } else if (Z_TYPE(args[i]) == IS_DOUBLE && (zend_dval_to_lval_silent((double) max_lval) == max_lval)) { /* if max_lval can be exactly represented as a double, go to double dedicated code */ max_dval = (double) max_lval; goto double_compare; @@ -1367,7 +1288,7 @@ PHP_FUNCTION(max) max_dval = Z_DVAL(args[i]); max = &args[i]; } - } else if (Z_TYPE(args[i]) == IS_LONG && (zend_dval_to_lval((double) Z_LVAL(args[i])) == Z_LVAL(args[i]))) { + } else if (Z_TYPE(args[i]) == IS_LONG && (zend_dval_to_lval_silent((double) Z_LVAL(args[i])) == Z_LVAL(args[i]))) { /* if the value can be exactly represented as a double, use double dedicated code otherwise generic */ if (max_dval < (double)Z_LVAL(args[i])) { max_dval = (double)Z_LVAL(args[i]); @@ -1405,7 +1326,7 @@ ZEND_FRAMELESS_FUNCTION(max, 2) if (EXPECTED(Z_TYPE_P(rhs) == IS_LONG)) { RETURN_COPY_VALUE(lhs_lval >= Z_LVAL_P(rhs) ? lhs : rhs); - } else if (Z_TYPE_P(rhs) == IS_DOUBLE && (zend_dval_to_lval((double) lhs_lval) == lhs_lval)) { + } else if (Z_TYPE_P(rhs) == IS_DOUBLE && (zend_dval_to_lval_silent((double) lhs_lval) == lhs_lval)) { /* if lhs_lval can be exactly represented as a double, go to double dedicated code */ lhs_dval = (double) lhs_lval; goto double_compare; @@ -1418,7 +1339,7 @@ ZEND_FRAMELESS_FUNCTION(max, 2) if (EXPECTED(Z_TYPE_P(rhs) == IS_DOUBLE)) { double_compare: RETURN_COPY_VALUE(lhs_dval >= Z_DVAL_P(rhs) ? lhs : rhs); - } else if (Z_TYPE_P(rhs) == IS_LONG && (zend_dval_to_lval((double) Z_LVAL_P(rhs)) == Z_LVAL_P(rhs))) { + } else if (Z_TYPE_P(rhs) == IS_LONG && (zend_dval_to_lval_silent((double) Z_LVAL_P(rhs)) == Z_LVAL_P(rhs))) { /* if the value can be exactly represented as a double, use double dedicated code otherwise generic */ RETURN_COPY_VALUE(lhs_dval >= (double)Z_LVAL_P(rhs) ? lhs : rhs); } else { @@ -1457,7 +1378,7 @@ static zend_result php_array_walk( /* Set up known arguments */ ZVAL_UNDEF(&args[1]); if (userdata) { - ZVAL_COPY(&args[2], userdata); + ZVAL_COPY_VALUE(&args[2], userdata); } fci.retval = &retval; @@ -1531,21 +1452,14 @@ static zend_result php_array_walk( } zval_ptr_dtor(&ref); } else { - ZVAL_COPY(&args[0], zv); + ZVAL_COPY_VALUE(&args[0], zv); /* Call the userland function */ result = zend_call_function(&fci, &context->fci_cache); - if (result == SUCCESS) { - zval_ptr_dtor(&retval); - } - - zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&retval); } - if (Z_TYPE(args[1]) != IS_UNDEF) { - zval_ptr_dtor(&args[1]); - ZVAL_UNDEF(&args[1]); - } + zval_ptr_dtor_str(&args[1]); if (result == FAILURE) { break; @@ -1565,9 +1479,6 @@ static zend_result php_array_walk( } } while (!EG(exception)); - if (userdata) { - zval_ptr_dtor(&args[2]); - } zend_hash_iterator_del(ht_iter); return result; } @@ -1614,7 +1525,7 @@ PHP_FUNCTION(array_walk_recursive) * 0 = return boolean * 1 = return key */ -static inline void _php_search_array(zval *return_value, zval *value, zval *array, bool strict, int behavior) /* {{{ */ +static zend_always_inline void _php_search_array(zval *return_value, zval *value, zval *array, bool strict, int behavior) /* {{{ */ { zval *entry; /* pointer to array entry */ zend_ulong num_idx; @@ -1762,9 +1673,8 @@ PHP_FUNCTION(array_search) } /* }}} */ -static zend_always_inline int php_valid_var_name(const char *var_name, size_t var_name_len) /* {{{ */ +static zend_always_inline bool php_valid_var_name(const zend_string *var_name) /* {{{ */ { -#if 1 /* first 256 bits for first character, and second 256 bits for the next */ static const uint32_t charset[8] = { /* 31 0 63 32 95 64 127 96 */ @@ -1774,67 +1684,37 @@ static zend_always_inline int php_valid_var_name(const char *var_name, size_t va /* 31 0 63 32 95 64 127 96 */ 0x00000000, 0x03ff0000, 0x87fffffe, 0x07fffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; -#endif - size_t i; - uint32_t ch; - if (UNEXPECTED(!var_name_len)) { - return 0; + if (UNEXPECTED(!ZSTR_LEN(var_name))) { + return false; } /* These are allowed as first char: [a-zA-Z_\x7f-\xff] */ - ch = (uint32_t)((unsigned char *)var_name)[0]; -#if 1 + uint32_t ch = (uint32_t)((unsigned char *)ZSTR_VAL(var_name))[0]; if (UNEXPECTED(!ZEND_BIT_TEST(charset, ch))) { -#else - if (var_name[0] != '_' && - (ch < 65 /* A */ || /* Z */ ch > 90) && - (ch < 97 /* a */ || /* z */ ch > 122) && - (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) - ) { -#endif - return 0; + return false; } /* And these as the rest: [a-zA-Z0-9_\x7f-\xff] */ - if (var_name_len > 1) { - i = 1; + if (ZSTR_LEN(var_name) > 1) { + size_t i = 1; do { - ch = (uint32_t)((unsigned char *)var_name)[i]; -#if 1 + ch = (uint32_t)((unsigned char *)ZSTR_VAL(var_name))[i]; if (UNEXPECTED(!ZEND_BIT_TEST(charset2, ch))) { -#else - if (var_name[i] != '_' && - (ch < 48 /* 0 */ || /* 9 */ ch > 57) && - (ch < 65 /* A */ || /* Z */ ch > 90) && - (ch < 97 /* a */ || /* z */ ch > 122) && - (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) - ) { -#endif - return 0; + return false; } - } while (++i < var_name_len); + } while (++i < ZSTR_LEN(var_name)); } - return 1; + return true; } /* }}} */ -PHPAPI int php_prefix_varname(zval *result, zend_string *prefix, const char *var_name, size_t var_name_len, bool add_underscore) /* {{{ */ +static zend_string* php_prefix_varname(const zend_string *prefix, const zend_string *var_name) { - ZVAL_NEW_STR(result, zend_string_alloc(ZSTR_LEN(prefix) + (add_underscore ? 1 : 0) + var_name_len, 0)); - memcpy(Z_STRVAL_P(result), ZSTR_VAL(prefix), ZSTR_LEN(prefix)); - - if (add_underscore) { - Z_STRVAL_P(result)[ZSTR_LEN(prefix)] = '_'; - } - - memcpy(Z_STRVAL_P(result) + ZSTR_LEN(prefix) + (add_underscore ? 1 : 0), var_name, var_name_len + 1); - - return SUCCESS; + return zend_string_concat3(ZSTR_VAL(prefix), ZSTR_LEN(prefix), ZEND_STRL("_"), ZSTR_VAL(var_name), ZSTR_LEN(var_name)); } -/* }}} */ -static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_table) /* {{{ */ +static zend_long php_extract_ref_if_exists(const zend_array *arr, const zend_array *symbol_table) /* {{{ */ { zend_long count = 0; zend_string *var_name; @@ -1855,7 +1735,7 @@ static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_t continue; } } - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals_literal(var_name, "GLOBALS")) { @@ -1880,7 +1760,7 @@ static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_t } /* }}} */ -static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table) /* {{{ */ +static zend_long php_extract_if_exists(const zend_array *arr, const zend_array *symbol_table) /* {{{ */ { zend_long count = 0; zend_string *var_name; @@ -1901,7 +1781,7 @@ static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table continue; } } - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals_literal(var_name, "GLOBALS")) { @@ -1924,7 +1804,7 @@ static zend_long php_extract_if_exists(zend_array *arr, zend_array *symbol_table } /* }}} */ -static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_table) /* {{{ */ +static zend_long php_extract_ref_overwrite(const zend_array *arr, zend_array *symbol_table) /* {{{ */ { zend_long count = 0; zend_string *var_name; @@ -1937,7 +1817,7 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t if (!var_name) { continue; } - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { @@ -1976,7 +1856,7 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t } /* }}} */ -static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table) /* {{{ */ +static zend_long php_extract_overwrite(const zend_array *arr, zend_array *symbol_table) /* {{{ */ { zend_long count = 0; zend_string *var_name; @@ -1989,7 +1869,7 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table if (!var_name) { continue; } - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { @@ -2021,11 +1901,11 @@ static zend_long php_extract_overwrite(zend_array *arr, zend_array *symbol_table } /* }}} */ -static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_ref_prefix_if_exists(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; if (HT_IS_PACKED(arr)) { return 0; @@ -2049,30 +1929,28 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s continue; } } - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); - if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; + zend_string *final_name = php_prefix_varname(prefix, var_name); + if (php_valid_var_name(final_name)) { + /* Prefixed varname cannot be equal to "this" due to underscore between prefix and name */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + if (Z_ISREF_P(entry)) { + Z_ADDREF_P(entry); } else { - if (Z_ISREF_P(entry)) { - Z_ADDREF_P(entry); - } else { - ZVAL_MAKE_REF_EX(entry, 2); - } - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - zval_ptr_dtor(orig_var); - ZVAL_REF(orig_var, Z_REF_P(entry)); - } else { - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); + ZVAL_MAKE_REF_EX(entry, 2); + } + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + zval_ptr_dtor(orig_var); + ZVAL_REF(orig_var, Z_REF_P(entry)); + } else { + zend_hash_add_new(symbol_table, final_name, entry); } + count++; } - zval_ptr_dtor_str(&final_name); + zend_string_release_ex(final_name, false); } } ZEND_HASH_FOREACH_END(); @@ -2080,11 +1958,11 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s } /* }}} */ -static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_prefix_if_exists(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; if (HT_IS_PACKED(arr)) { return 0; @@ -2103,30 +1981,28 @@ static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbo continue; } } - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); - if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; - } else { - ZVAL_DEREF(entry); - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); - if (UNEXPECTED(EG(exception))) { - zend_string_release_ex(Z_STR(final_name), 0); - return -1; - } - } else { - Z_TRY_ADDREF_P(entry); - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); + zend_string *final_name = php_prefix_varname(prefix, var_name); + if (php_valid_var_name(final_name)) { + /* Prefixed varname cannot be equal to "this" due to underscore between prefix and name */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + ZVAL_DEREF(entry); + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); + if (UNEXPECTED(EG(exception))) { + zend_string_release_ex(final_name, 0); + return -1; + } + } else { + Z_TRY_ADDREF_P(entry); + zend_hash_add_new(symbol_table, final_name, entry); } + count++; } - zval_ptr_dtor_str(&final_name); + zend_string_release_ex(final_name, false); } } ZEND_HASH_FOREACH_END(); @@ -2134,11 +2010,11 @@ static zend_long php_extract_prefix_if_exists(zend_array *arr, zend_array *symbo } /* }}} */ -static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_ref_prefix_same(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; if (HT_IS_PACKED(arr)) { return 0; @@ -2165,33 +2041,31 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol continue; } } -prefix: - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); - if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; +prefix:; + zend_string *final_name = php_prefix_varname(prefix, var_name); + if (php_valid_var_name(final_name)) { + /* Prefixed varname cannot be equal to "this" due to underscore between prefix and name */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + if (Z_ISREF_P(entry)) { + Z_ADDREF_P(entry); } else { - if (Z_ISREF_P(entry)) { - Z_ADDREF_P(entry); - } else { - ZVAL_MAKE_REF_EX(entry, 2); - } - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - zval_ptr_dtor(orig_var); - ZVAL_REF(orig_var, Z_REF_P(entry)); - } else { - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); + ZVAL_MAKE_REF_EX(entry, 2); + } + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + zval_ptr_dtor(orig_var); + ZVAL_REF(orig_var, Z_REF_P(entry)); + } else { + zend_hash_add_new(symbol_table, final_name, entry); } + count++; } - zval_ptr_dtor_str(&final_name); + zend_string_release_ex(final_name, false); } else { - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { @@ -2211,11 +2085,11 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol } /* }}} */ -static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_prefix_same(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; if (HT_IS_PACKED(arr)) { return 0; @@ -2237,33 +2111,31 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab continue; } } -prefix: - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); - if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; - } else { - ZVAL_DEREF(entry); - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); - if (UNEXPECTED(EG(exception))) { - zend_string_release_ex(Z_STR(final_name), 0); - return -1; - } - } else { - Z_TRY_ADDREF_P(entry); - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); +prefix:; + zend_string *final_name = php_prefix_varname(prefix, var_name); + if (php_valid_var_name(final_name)) { + /* Prefixed varname cannot be equal to "this" due to underscore between prefix and name */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + ZVAL_DEREF(entry); + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); + if (UNEXPECTED(EG(exception))) { + zend_string_release_ex(final_name, false); + return -1; + } + } else { + Z_TRY_ADDREF_P(entry); + zend_hash_add_new(symbol_table, final_name, entry); } + count++; } - zval_ptr_dtor_str(&final_name); + zend_string_release_ex(final_name, false); } else { - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { @@ -2280,211 +2152,210 @@ static zend_long php_extract_prefix_same(zend_array *arr, zend_array *symbol_tab } /* }}} */ -static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_ref_prefix_all(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; zend_ulong num_key; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, var_name, entry) { + zend_string *final_name; if (var_name) { if (ZSTR_LEN(var_name) == 0) { continue; } - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); + final_name = php_prefix_varname(prefix, var_name); } else { zend_string *str = zend_long_to_str(num_key); - php_prefix_varname(&final_name, prefix, ZSTR_VAL(str), ZSTR_LEN(str), 1); - zend_string_release_ex(str, 0); + final_name = php_prefix_varname(prefix, str); + zend_string_release_ex(str, false); } - if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; + if (php_valid_var_name(final_name)) { + /* Prefixed varname cannot be equal to "this" due to underscore between prefix and name */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + if (Z_ISREF_P(entry)) { + Z_ADDREF_P(entry); } else { - if (Z_ISREF_P(entry)) { - Z_ADDREF_P(entry); - } else { - ZVAL_MAKE_REF_EX(entry, 2); - } - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - zval_ptr_dtor(orig_var); - ZVAL_REF(orig_var, Z_REF_P(entry)); - } else { - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); + ZVAL_MAKE_REF_EX(entry, 2); + } + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + zval_ptr_dtor(orig_var); + ZVAL_REF(orig_var, Z_REF_P(entry)); + } else { + zend_hash_add_new(symbol_table, final_name, entry); } + count++; } - zval_ptr_dtor_str(&final_name); + zend_string_release_ex(final_name, false); } ZEND_HASH_FOREACH_END(); return count; } /* }}} */ -static zend_long php_extract_prefix_all(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_prefix_all(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; zend_ulong num_key; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, var_name, entry) { + zend_string *final_name; if (var_name) { if (ZSTR_LEN(var_name) == 0) { continue; } - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); + final_name = php_prefix_varname(prefix, var_name); } else { zend_string *str = zend_long_to_str(num_key); - php_prefix_varname(&final_name, prefix, ZSTR_VAL(str), ZSTR_LEN(str), 1); - zend_string_release_ex(str, 0); + final_name = php_prefix_varname(prefix, str); + zend_string_release_ex(str, false); } - if (php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; - } else { - ZVAL_DEREF(entry); - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); - if (UNEXPECTED(EG(exception))) { - zend_string_release_ex(Z_STR(final_name), 0); - return -1; - } - } else { - Z_TRY_ADDREF_P(entry); - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); + if (php_valid_var_name(final_name)) { + /* Prefixed varname cannot be equal to "this" due to underscore between prefix and name */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + ZVAL_DEREF(entry); + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); + if (UNEXPECTED(EG(exception))) { + zend_string_release_ex(final_name, false); + return -1; + } + } else { + Z_TRY_ADDREF_P(entry); + zend_hash_add_new(symbol_table, final_name, entry); } + count++; } - zval_ptr_dtor_str(&final_name); + zend_string_release_ex(final_name, false); } ZEND_HASH_FOREACH_END(); return count; } /* }}} */ -static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_ref_prefix_invalid(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; zend_ulong num_key; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, var_name, entry) { + zend_string *final_name; if (var_name) { - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name)) - || zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); - if (!php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - zval_ptr_dtor_str(&final_name); + if (!php_valid_var_name(var_name) || zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { + final_name = php_prefix_varname(prefix, var_name); + + if (!php_valid_var_name(final_name)) { + zend_string_release_ex(final_name, false); continue; } } else { - ZVAL_STR_COPY(&final_name, var_name); + final_name = zend_string_copy(var_name); } } else { zend_string *str = zend_long_to_str(num_key); - php_prefix_varname(&final_name, prefix, ZSTR_VAL(str), ZSTR_LEN(str), 1); - zend_string_release_ex(str, 0); - if (!php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - zval_ptr_dtor_str(&final_name); + final_name = php_prefix_varname(prefix, str); + zend_string_release_ex(str, false); + if (!php_valid_var_name(final_name)) { + zend_string_release_ex(final_name, false); continue; } } - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; + + /* We previously checked if the var name is "this" to prefix it */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + if (Z_ISREF_P(entry)) { + Z_ADDREF_P(entry); } else { - if (Z_ISREF_P(entry)) { - Z_ADDREF_P(entry); - } else { - ZVAL_MAKE_REF_EX(entry, 2); - } - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - zval_ptr_dtor(orig_var); - ZVAL_REF(orig_var, Z_REF_P(entry)); - } else { - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); + ZVAL_MAKE_REF_EX(entry, 2); + } + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + zval_ptr_dtor(orig_var); + ZVAL_REF(orig_var, Z_REF_P(entry)); + } else { + zend_hash_add_new(symbol_table, final_name, entry); } - zval_ptr_dtor_str(&final_name); + count++; + + zend_string_release_ex(final_name, false); } ZEND_HASH_FOREACH_END(); return count; } /* }}} */ -static zend_long php_extract_prefix_invalid(zend_array *arr, zend_array *symbol_table, zend_string *prefix) /* {{{ */ +static zend_long php_extract_prefix_invalid(const zend_array *arr, zend_array *symbol_table, const zend_string *prefix) /* {{{ */ { zend_long count = 0; zend_string *var_name; zend_ulong num_key; - zval *entry, *orig_var, final_name; + zval *entry, *orig_var; ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, var_name, entry) { + zend_string *final_name; if (var_name) { - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name)) - || zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { - php_prefix_varname(&final_name, prefix, ZSTR_VAL(var_name), ZSTR_LEN(var_name), 1); - if (!php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - zval_ptr_dtor_str(&final_name); + if (!php_valid_var_name(var_name) || zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { + final_name = php_prefix_varname(prefix, var_name); + if (!php_valid_var_name(final_name)) { + zend_string_release_ex(final_name, false); continue; } } else { - ZVAL_STR_COPY(&final_name, var_name); + final_name = zend_string_copy(var_name); } } else { zend_string *str = zend_long_to_str(num_key); - php_prefix_varname(&final_name, prefix, ZSTR_VAL(str), ZSTR_LEN(str), 1); + final_name = php_prefix_varname(prefix, str); zend_string_release_ex(str, 0); - if (!php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { - zval_ptr_dtor_str(&final_name); + if (!php_valid_var_name(final_name)) { + zend_string_release_ex(final_name, false); continue; } } - if (zend_string_equals(Z_STR(final_name), ZSTR_KNOWN(ZEND_STR_THIS))) { - zend_throw_error(NULL, "Cannot re-assign $this"); - return -1; - } else { - ZVAL_DEREF(entry); - if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) { - if (Z_TYPE_P(orig_var) == IS_INDIRECT) { - orig_var = Z_INDIRECT_P(orig_var); - } - ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); - if (UNEXPECTED(EG(exception))) { - zend_string_release_ex(Z_STR(final_name), 0); - return -1; - } - } else { - Z_TRY_ADDREF_P(entry); - zend_hash_add_new(symbol_table, Z_STR(final_name), entry); + + /* We previously checked if the var name is "this" to prefix it */ + ZEND_ASSERT(!zend_string_equals(final_name, ZSTR_KNOWN(ZEND_STR_THIS))); + + ZVAL_DEREF(entry); + if ((orig_var = zend_hash_find(symbol_table, final_name)) != NULL) { + if (Z_TYPE_P(orig_var) == IS_INDIRECT) { + orig_var = Z_INDIRECT_P(orig_var); } - count++; + ZEND_TRY_ASSIGN_COPY_EX(orig_var, entry, 0); + if (UNEXPECTED(EG(exception))) { + zend_string_release_ex(final_name, false); + return -1; + } + } else { + Z_TRY_ADDREF_P(entry); + zend_hash_add_new(symbol_table, final_name, entry); } - zval_ptr_dtor_str(&final_name); + count++; + + zend_string_release_ex(final_name, false); } ZEND_HASH_FOREACH_END(); return count; } /* }}} */ -static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table) /* {{{ */ +static zend_long php_extract_ref_skip(const zend_array *arr, zend_array *symbol_table) /* {{{ */ { zend_long count = 0; zend_string *var_name; @@ -2497,7 +2368,7 @@ static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table) if (!var_name) { continue; } - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { @@ -2532,7 +2403,7 @@ static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table) } /* }}} */ -static zend_long php_extract_skip(zend_array *arr, zend_array *symbol_table) /* {{{ */ +static zend_long php_extract_skip(const zend_array *arr, zend_array *symbol_table) /* {{{ */ { zend_long count = 0; zend_string *var_name; @@ -2545,7 +2416,7 @@ static zend_long php_extract_skip(zend_array *arr, zend_array *symbol_table) /* if (!var_name) { continue; } - if (!php_valid_var_name(ZSTR_VAL(var_name), ZSTR_LEN(var_name))) { + if (!php_valid_var_name(var_name)) { continue; } if (zend_string_equals(var_name, ZSTR_KNOWN(ZEND_STR_THIS))) { @@ -2606,7 +2477,7 @@ PHP_FUNCTION(extract) } if (prefix) { - if (ZSTR_LEN(prefix) && !php_valid_var_name(ZSTR_VAL(prefix), ZSTR_LEN(prefix))) { + if (ZSTR_LEN(prefix) && !php_valid_var_name(prefix)) { zend_argument_value_error(3, "must be a valid identifier"); RETURN_THROWS(); } @@ -2830,16 +2701,19 @@ PHP_FUNCTION(array_fill_keys) ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) { ZVAL_DEREF(entry); - Z_TRY_ADDREF_P(val); if (Z_TYPE_P(entry) == IS_LONG) { - zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val); + zend_hash_index_add(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val); } else { zend_string *tmp_key; zend_string *key = zval_get_tmp_string(entry, &tmp_key); - zend_symtable_update(Z_ARRVAL_P(return_value), key, val); + zend_symtable_add(Z_ARRVAL_P(return_value), key, val); zend_tmp_string_release(tmp_key); } } ZEND_HASH_FOREACH_END(); + + if (Z_REFCOUNTED_P(val)) { + GC_ADDREF_EX(Z_COUNTED_P(val), zend_hash_num_elements(Z_ARRVAL_P(return_value))); + } } /* }}} */ @@ -2942,7 +2816,7 @@ static uint8_t php_range_process_input(const zval *input, uint32_t arg_num, zend *dval = 0.0; return IS_STRING; } - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } @@ -2980,7 +2854,7 @@ PHP_FUNCTION(range) is_step_negative = true; step_double *= -1; } - step = zend_dval_to_lval(step_double); + step = zend_dval_to_lval_silent(step_double); if (!zend_is_long_compatible(step_double, step)) { is_step_double = true; } @@ -3047,18 +2921,18 @@ PHP_FUNCTION(range) if (start_type == IS_STRING || end_type == IS_STRING) { php_error_docref(NULL, E_WARNING, "Argument #3 ($step) must be of type int when generating an array" " of characters, inputs converted to 0"); - } - if (UNEXPECTED(EG(exception))) { - RETURN_THROWS(); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } } end_type = IS_LONG; start_type = IS_LONG; goto handle_numeric_inputs; } - /* Generate array of characters */ - unsigned char low = (unsigned char)Z_STRVAL_P(user_start)[0]; - unsigned char high = (unsigned char)Z_STRVAL_P(user_end)[0]; + /* Generate array of characters, as zero-extended ints to make bounds checking possible in the loop condition */ + int low = (unsigned char) Z_STRVAL_P(user_start)[0]; + int high = (unsigned char) Z_STRVAL_P(user_end)[0]; /* Decreasing char range */ if (low > high) { @@ -3069,12 +2943,9 @@ PHP_FUNCTION(range) array_init_size(return_value, (uint32_t)(((low - high) / step) + 1)); zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { - for (; low >= high; low -= (unsigned int)step) { + for (; low >= high; low -= step) { ZEND_HASH_FILL_SET_INTERNED_STR(ZSTR_CHAR(low)); ZEND_HASH_FILL_NEXT(); - if (((signed int)low - step) < 0) { - break; - } } } ZEND_HASH_FILL_END(); } else if (high > low) { /* Increasing char range */ @@ -3087,12 +2958,9 @@ PHP_FUNCTION(range) array_init_size(return_value, (uint32_t)(((high - low) / step) + 1)); zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { - for (; low <= high; low += (unsigned int)step) { + for (; low <= high; low += step) { ZEND_HASH_FILL_SET_INTERNED_STR(ZSTR_CHAR(low)); ZEND_HASH_FILL_NEXT(); - if (((signed int)low + step) > 255) { - break; - } } } ZEND_HASH_FILL_END(); } else { @@ -3318,6 +3186,9 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H zval *entry; /* Hash entry */ uint32_t iter_pos = zend_hash_iterators_lower_pos(in_hash, 0); + GC_ADDREF(in_hash); + HT_ALLOW_COW_VIOLATION(in_hash); /* Will be reset when setting the flags for in_hash */ + /* Get number of entries in the input hash */ num_in = zend_hash_num_elements(in_hash); @@ -3485,6 +3356,21 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H HT_SET_ITERATORS_COUNT(&out_hash, HT_ITERATORS_COUNT(in_hash)); HT_SET_ITERATORS_COUNT(in_hash, 0); in_hash->pDestructor = NULL; + + /* Set internal pointer to 0 directly instead of calling zend_hash_internal_pointer_reset(). + * This avoids the COW violation assertion and delays advancing to the first valid position + * until after we've switched to the new array structure (out_hash). The iterator will be + * advanced when actually accessed, at which point it will find valid indexes in the new array. */ + in_hash->nInternalPointer = 0; + + if (UNEXPECTED(GC_DELREF(in_hash) == 0)) { + /* Array was completely deallocated during the operation */ + zend_array_destroy(in_hash); + zend_hash_destroy(&out_hash); + zend_throw_error(NULL, "Array was modified during array_splice operation"); + return; + } + zend_hash_destroy(in_hash); HT_FLAGS(in_hash) = HT_FLAGS(&out_hash); @@ -3495,8 +3381,6 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H in_hash->nNextFreeElement = out_hash.nNextFreeElement; in_hash->arData = out_hash.arData; in_hash->pDestructor = out_hash.pDestructor; - - zend_hash_internal_pointer_reset(in_hash); } /* }}} */ @@ -3734,18 +3618,34 @@ PHP_FUNCTION(array_unshift) ZEND_PARSE_PARAMETERS_END(); zend_hash_init(&new_hash, zend_hash_num_elements(Z_ARRVAL_P(stack)) + argc, NULL, ZVAL_PTR_DTOR, 0); - for (uint32_t i = 0; i < argc; i++) { - Z_TRY_ADDREF(args[i]); - zend_hash_next_index_insert_new(&new_hash, &args[i]); - } - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(stack), key, value) { - if (key) { - zend_hash_add_new(&new_hash, key, value); - } else { - zend_hash_next_index_insert_new(&new_hash, value); + if (HT_IS_PACKED(Z_ARRVAL_P(stack))) { + zend_hash_real_init_packed(&new_hash); + + ZEND_HASH_FILL_PACKED(&new_hash) { + for (uint32_t i = 0; i < argc; i++) { + Z_TRY_ADDREF(args[i]); + ZEND_HASH_FILL_ADD(&args[i]); + } + + ZEND_HASH_PACKED_FOREACH_VAL(Z_ARRVAL_P(stack), value) { + ZEND_HASH_FILL_ADD(value); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FILL_END(); + } else { + for (uint32_t i = 0; i < argc; i++) { + Z_TRY_ADDREF(args[i]); + zend_hash_next_index_insert_new(&new_hash, &args[i]); } - } ZEND_HASH_FOREACH_END(); + + ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(stack), key, value) { + if (key) { + zend_hash_add_new(&new_hash, key, value); + } else { + zend_hash_next_index_insert_new(&new_hash, value); + } + } ZEND_HASH_FOREACH_END(); + } if (UNEXPECTED(HT_HAS_ITERATORS(Z_ARRVAL_P(stack)))) { zend_hash_iterators_advance(Z_ARRVAL_P(stack), argc); @@ -3844,7 +3744,6 @@ static inline Bucket* find_bucket_at_offset(HashTable* ht, zend_long offset) ZEND_ASSERT(offset >= 0 && offset <= ht->nNumOfElements); if (HT_IS_WITHOUT_HOLES(ht)) { /* There's no need to iterate over the array to filter out holes if there are no holes */ - /* This properly handles both packed and unpacked arrays. */ return ht->arData + offset; } /* Otherwise, this code has to iterate over the HashTable and skip holes in the array. */ @@ -3871,7 +3770,6 @@ static inline zval* find_packed_val_at_offset(HashTable* ht, zend_long offset) ZEND_ASSERT(offset >= 0 && offset <= ht->nNumOfElements); if (HT_IS_WITHOUT_HOLES(ht)) { /* There's no need to iterate over the array to filter out holes if there are no holes */ - /* This properly handles both packed and unpacked arrays. */ return ht->arPacked + offset; } /* Otherwise, this code has to iterate over the HashTable and skip holes in the array. */ @@ -4256,7 +4154,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET uint32_t argc, i; zval *src_entry; HashTable *src, *dest; - uint32_t count = 0; + uint64_t count = 0; ZEND_PARSE_PARAMETERS_START(0, -1) Z_PARAM_VARIADIC('+', args, argc) @@ -4276,6 +4174,11 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET count += zend_hash_num_elements(Z_ARRVAL_P(arg)); } + if (UNEXPECTED(count >= HT_MAX_SIZE)) { + zend_throw_error(NULL, "The total number of elements must be lower than %u", HT_MAX_SIZE); + RETURN_THROWS(); + } + if (argc == 2) { zval *ret = NULL; @@ -4287,22 +4190,20 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET if (ret) { if (HT_IS_PACKED(Z_ARRVAL_P(ret))) { if (HT_IS_WITHOUT_HOLES(Z_ARRVAL_P(ret))) { - ZVAL_COPY(return_value, ret); - return; + RETURN_COPY(ret); } } else { - bool copy = 1; + bool copy = true; zend_string *string_key; - ZEND_HASH_FOREACH_STR_KEY(Z_ARRVAL_P(ret), string_key) { + ZEND_HASH_MAP_FOREACH_STR_KEY(Z_ARRVAL_P(ret), string_key) { if (!string_key) { - copy = 0; + copy = false; break; } } ZEND_HASH_FOREACH_END(); if (copy) { - ZVAL_COPY(return_value, ret); - return; + RETURN_COPY(ret); } } } @@ -4317,7 +4218,7 @@ static zend_always_inline void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMET if (HT_IS_WITHOUT_HOLES(src) && zend_may_modify_arg_in_place(arg)) { dest = src; in_place = true; - ZVAL_ARR(return_value, dest); + RETVAL_ARR(dest); } else { array_init_size(return_value, count); dest = Z_ARRVAL_P(return_value); @@ -4591,7 +4492,7 @@ PHP_FUNCTION(array_count_values) if ((tmp = zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_P(entry))) == NULL) { zval data; ZVAL_LONG(&data, 1); - zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data); + zend_hash_index_add_new(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data); } else { Z_LVAL_P(tmp)++; } @@ -4599,7 +4500,7 @@ PHP_FUNCTION(array_count_values) if ((tmp = zend_symtable_find(Z_ARRVAL_P(return_value), Z_STR_P(entry))) == NULL) { zval data; ZVAL_LONG(&data, 1); - zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); + zend_symtable_add_new(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } else { Z_LVAL_P(tmp)++; } @@ -4896,7 +4797,7 @@ PHP_FUNCTION(array_change_key_case) zend_string *string_key; zend_string *new_key; zend_ulong num_key; - zend_long change_to_upper=0; + zend_long change_to_upper = PHP_CASE_LOWER; ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_ARRAY(array) @@ -4904,13 +4805,18 @@ PHP_FUNCTION(array_change_key_case) Z_PARAM_LONG(change_to_upper) ZEND_PARSE_PARAMETERS_END(); + if (change_to_upper != PHP_CASE_LOWER && change_to_upper != PHP_CASE_UPPER) { + zend_argument_value_error(2, "must be either CASE_LOWER or CASE_UPPER"); + RETURN_THROWS(); + } + array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array))); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) { if (!string_key) { entry = zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); } else { - if (change_to_upper) { + if (change_to_upper == PHP_CASE_UPPER) { new_key = zend_string_toupper(string_key); } else { new_key = zend_string_tolower(string_key); @@ -4999,7 +4905,7 @@ PHP_FUNCTION(array_unique) return; } - cmp = php_get_data_compare_func_unstable(sort_type, 0); + cmp = php_get_data_compare_func_unstable(sort_type, false); bool in_place = zend_may_modify_arg_in_place(array); if (in_place) { @@ -5032,6 +4938,11 @@ PHP_FUNCTION(array_unique) ZVAL_UNDEF(&arTmp[i].b.val); zend_sort((void *) arTmp, i, sizeof(struct bucketindex), (compare_func_t) cmp, (swap_func_t) array_bucketindex_swap); + + if (UNEXPECTED(EG(exception))) { + goto out; + } + /* go through the sorted array and delete duplicates from the copy */ lastkept = arTmp; for (cmpdata = arTmp + 1; Z_TYPE(cmpdata->b.val) != IS_UNDEF; cmpdata++) { @@ -5051,6 +4962,8 @@ PHP_FUNCTION(array_unique) } } } + +out: pefree(arTmp, GC_FLAGS(Z_ARRVAL_P(array)) & IS_ARRAY_PERSISTENT); if (in_place) { @@ -5129,13 +5042,13 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa val = Z_REFVAL_P(val); } if (key == NULL) { - ok = 1; + ok = true; for (i = 1; i < argc; i++) { if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), h)) == NULL || (intersect_data_compare_func && intersect_data_compare_func(val, data) != 0) ) { - ok = 0; + ok = false; break; } } @@ -5144,13 +5057,13 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa zend_hash_index_add_new(Z_ARRVAL_P(return_value), h, val); } } else { - ok = 1; + ok = true; for (i = 1; i < argc; i++) { if ((data = zend_hash_find_known_hash(Z_ARRVAL(args[i]), key)) == NULL || (intersect_data_compare_func && intersect_data_compare_func(val, data) != 0) ) { - ok = 0; + ok = false; break; } } @@ -5525,13 +5438,13 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty val = Z_REFVAL_P(val); } if (key == NULL) { - ok = 1; + ok = true; for (i = 1; i < argc; i++) { if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), h)) != NULL && (!diff_data_compare_func || diff_data_compare_func(val, data) == 0) ) { - ok = 0; + ok = false; break; } } @@ -5540,13 +5453,13 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty zend_hash_index_add_new(Z_ARRVAL_P(return_value), h, val); } } else { - ok = 1; + ok = true; for (i = 1; i < argc; i++) { if ((data = zend_hash_find_known_hash(Z_ARRVAL(args[i]), key)) != NULL && (!diff_data_compare_func || diff_data_compare_func(val, data) == 0) ) { - ok = 0; + ok = false; break; } } @@ -5831,7 +5744,7 @@ PHP_FUNCTION(array_diff) { zval *args; uint32_t argc, i; - uint32_t num; + uint64_t num; HashTable exclude; zval *value; zend_string *str, *tmp_str, *key; @@ -5879,6 +5792,7 @@ PHP_FUNCTION(array_diff) for (i = 1; i < argc; i++) { if (Z_TYPE(args[i]) != IS_ARRAY) { + zend_tmp_string_release(tmp_search_str); zend_argument_type_error(i + 1, "must be of type array, %s given", zend_zval_value_name(&args[i])); RETURN_THROWS(); } @@ -5920,6 +5834,11 @@ PHP_FUNCTION(array_diff) return; } + if (UNEXPECTED(num >= HT_MAX_SIZE)) { + zend_throw_error(NULL, "The total number of elements must be lower than %u", HT_MAX_SIZE); + RETURN_THROWS(); + } + ZVAL_NULL(&dummy); /* create exclude map */ zend_hash_init(&exclude, num, NULL, NULL, 0); @@ -6051,7 +5970,7 @@ PHP_FUNCTION(array_multisort) for (i = 0; i < MULTISORT_LAST; i++) { parse_state[i] = 0; } - func = ARRAYG(multisort_func) = ecalloc(argc, sizeof(bucket_compare_func_t)); + func = ecalloc(argc, sizeof(bucket_compare_func_t)); /* Here we go through the input arguments and parse them. Each one can * be either an array or a sort flag which follows an array. If not @@ -6067,7 +5986,7 @@ PHP_FUNCTION(array_multisort) /* We see the next array, so we update the sort flags of * the previous array and reset the sort flags. */ if (i > 0) { - ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); + func[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); sort_order = PHP_SORT_ASC; sort_type = PHP_SORT_REGULAR; } @@ -6119,8 +6038,6 @@ PHP_FUNCTION(array_multisort) MULTISORT_ABORT; } } - /* Take care of the last array sort flags. */ - ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); /* Make sure the arrays are of the same size. */ array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0])); @@ -6138,6 +6055,11 @@ PHP_FUNCTION(array_multisort) RETURN_TRUE; } + /* Take care of the last array sort flags. */ + func[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC); + bucket_compare_func_t *old_multisort_func = ARRAYG(multisort_func); + ARRAYG(multisort_func) = func; + /* Create the indirection array. This array is of size MxN, where * M is the number of entries in each input array and N is the number * of the input arrays + 1. The last column is UNDEF to indicate the end @@ -6214,6 +6136,7 @@ PHP_FUNCTION(array_multisort) efree(indirect); efree(func); efree(arrays); + ARRAYG(multisort_func) = old_multisort_func; } /* }}} */ @@ -6391,11 +6314,50 @@ PHP_FUNCTION(array_rand) } /* }}} */ +/* Apply a single array_sum/array_product step to return_value. */ +static zend_always_inline void php_array_binop_apply( + zval *return_value, zval *entry, const char *op_name, binary_op_type op) +{ + /* For objects we try to cast them to a numeric type */ + if (Z_TYPE_P(entry) == IS_OBJECT) { + zval dst; + zend_result status = Z_OBJ_HT_P(entry)->cast_object(Z_OBJ_P(entry), &dst, _IS_NUMBER); + + /* Do not type error for BC */ + if (status == FAILURE || (Z_TYPE(dst) != IS_LONG && Z_TYPE(dst) != IS_DOUBLE)) { + php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", + op_name, zend_zval_type_name(entry)); + return; + } + op(return_value, return_value, &dst); + return; + } + + zend_result status = op(return_value, return_value, entry); + if (status == FAILURE) { + ZEND_ASSERT(EG(exception)); + zend_clear_exception(); + /* BC resources: previously resources were cast to int */ + if (Z_TYPE_P(entry) == IS_RESOURCE) { + zval tmp; + ZVAL_LONG(&tmp, Z_RES_HANDLE_P(entry)); + op(return_value, return_value, &tmp); + } + /* BC non numeric strings: previously were cast to 0 */ + else if (Z_TYPE_P(entry) == IS_STRING) { + zval tmp; + ZVAL_LONG(&tmp, 0); + op(return_value, return_value, &tmp); + } + php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", + op_name, zend_zval_type_name(entry)); + } +} + /* Wrapper for array_sum and array_product */ -static void php_array_binop(INTERNAL_FUNCTION_PARAMETERS, const char *op_name, binary_op_type op, zend_long initial) +static zend_always_inline void php_array_binop(INTERNAL_FUNCTION_PARAMETERS, const char *op_name, binary_op_type op, zend_long initial) { HashTable *input; - zval *entry; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ARRAY_HT(input) @@ -6406,42 +6368,39 @@ static void php_array_binop(INTERNAL_FUNCTION_PARAMETERS, const char *op_name, b } ZVAL_LONG(return_value, initial); - ZEND_HASH_FOREACH_VAL(input, entry) { - /* For objects we try to cast them to a numeric type */ - if (Z_TYPE_P(entry) == IS_OBJECT) { - zval dst; - zend_result status = Z_OBJ_HT_P(entry)->cast_object(Z_OBJ_P(entry), &dst, _IS_NUMBER); - - /* Do not type error for BC */ - if (status == FAILURE || (Z_TYPE(dst) != IS_LONG && Z_TYPE(dst) != IS_DOUBLE)) { - php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", - op_name, zend_zval_type_name(entry)); - continue; - } - op(return_value, return_value, &dst); - continue; - } - zend_result status = op(return_value, return_value, entry); - if (status == FAILURE) { - ZEND_ASSERT(EG(exception)); - zend_clear_exception(); - /* BC resources: previously resources were cast to int */ - if (Z_TYPE_P(entry) == IS_RESOURCE) { - zval tmp; - ZVAL_LONG(&tmp, Z_RES_HANDLE_P(entry)); - op(return_value, return_value, &tmp); + if (op == add_function) { + zval *entry; + ZEND_HASH_FOREACH_VAL(input, entry) { + if (EXPECTED(Z_TYPE_P(entry) == IS_LONG) && EXPECTED(Z_TYPE_P(return_value) == IS_LONG)) { + fast_long_add_function(return_value, return_value, entry); + continue; } - /* BC non numeric strings: previously were cast to 0 */ - else if (Z_TYPE_P(entry) == IS_STRING) { - zval tmp; - ZVAL_LONG(&tmp, 0); - op(return_value, return_value, &tmp); + php_array_binop_apply(return_value, entry, op_name, op); + } ZEND_HASH_FOREACH_END(); + } else if (op == mul_function) { + zval *entry; + ZEND_HASH_FOREACH_VAL(input, entry) { + if (EXPECTED(Z_TYPE_P(entry) == IS_LONG) && EXPECTED(Z_TYPE_P(return_value) == IS_LONG)) { + zend_long lval; + double dval; + int overflow; + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(return_value), Z_LVAL_P(entry), lval, dval, overflow); + if (UNEXPECTED(overflow)) { + ZVAL_DOUBLE(return_value, dval); + } else { + Z_LVAL_P(return_value) = lval; + } + continue; } - php_error_docref(NULL, E_WARNING, "%s is not supported on type %s", - op_name, zend_zval_type_name(entry)); - } - } ZEND_HASH_FOREACH_END(); + php_array_binop_apply(return_value, entry, op_name, op); + } ZEND_HASH_FOREACH_END(); + } else { + zval *entry; + ZEND_HASH_FOREACH_VAL(input, entry) { + php_array_binop_apply(return_value, entry, op_name, op); + } ZEND_HASH_FOREACH_END(); + } } /* {{{ Returns the sum of the array entries */ @@ -6494,6 +6453,7 @@ PHP_FUNCTION(array_reduce) fci.retval = return_value; fci.param_count = 2; fci.params = args; + fci.consumed_args = zend_fci_consumed_arg(0); ZEND_HASH_FOREACH_VAL(htbl, operand) { ZVAL_COPY_VALUE(&args[0], return_value); @@ -6538,7 +6498,7 @@ PHP_FUNCTION(array_filter) zval args[2]; zval retval; bool have_callback = 0; - zend_long use_type = 0; + zend_long use_type = ARRAY_FILTER_USE_VALUE; zend_string *string_key; zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fci_cache; @@ -6551,9 +6511,18 @@ PHP_FUNCTION(array_filter) Z_PARAM_LONG(use_type) ZEND_PARSE_PARAMETERS_END(); + switch (use_type) { + case ARRAY_FILTER_USE_VALUE: + case ARRAY_FILTER_USE_BOTH: + case ARRAY_FILTER_USE_KEY: + break; + default: + zend_argument_value_error(3, "must be one of ARRAY_FILTER_USE_VALUE, ARRAY_FILTER_USE_KEY, or ARRAY_FILTER_USE_BOTH"); + RETURN_THROWS(); + } + if (zend_hash_num_elements(Z_ARRVAL_P(array)) == 0) { - RETVAL_EMPTY_ARRAY(); - return; + RETURN_EMPTY_ARRAY(); } array_init(return_value); @@ -6571,7 +6540,7 @@ PHP_FUNCTION(array_filter) ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, operand) { if (have_callback) { - if (use_type) { + if (use_type != ARRAY_FILTER_USE_VALUE) { /* Set up the key */ if (!string_key) { ZVAL_LONG(key, num_key); @@ -6738,11 +6707,11 @@ PHP_FUNCTION(array_all) PHP_FUNCTION(array_map) { zval *arrays = NULL; - int n_arrays = 0; + uint32_t n_arrays = 0; zval result; zend_fcall_info fci; zend_fcall_info_cache fci_cache; - int i; + uint32_t i; uint32_t k, maxlen = 0; ZEND_PARSE_PARAMETERS_START(2, -1) @@ -6784,8 +6753,7 @@ PHP_FUNCTION(array_map) ZEND_IGNORE_VALUE(ret); if (UNEXPECTED(Z_ISUNDEF(result))) { ZEND_HASH_FILL_FINISH(); - zend_array_destroy(output); - RETURN_NULL(); + RETURN_THROWS(); } } else { ZVAL_UNDEF(&result); @@ -6808,8 +6776,7 @@ PHP_FUNCTION(array_map) ZEND_ASSERT(ret == SUCCESS); ZEND_IGNORE_VALUE(ret); if (UNEXPECTED(Z_ISUNDEF(result))) { - zend_array_destroy(output); - RETURN_NULL(); + RETURN_THROWS(); } if (str_key) { _zend_hash_append(output, str_key, &result); @@ -6819,12 +6786,9 @@ PHP_FUNCTION(array_map) } ZEND_HASH_FOREACH_END(); } } else { - uint32_t *array_pos = (HashPosition *)ecalloc(n_arrays, sizeof(HashPosition)); - for (i = 0; i < n_arrays; i++) { if (Z_TYPE(arrays[i]) != IS_ARRAY) { zend_argument_type_error(i + 2, "must be of type array, %s given", zend_zval_value_name(&arrays[i])); - efree(array_pos); RETURN_THROWS(); } if (zend_hash_num_elements(Z_ARRVAL(arrays[i])) > maxlen) { @@ -6835,6 +6799,7 @@ PHP_FUNCTION(array_map) array_init_size(return_value, maxlen); if (!ZEND_FCI_INITIALIZED(fci)) { + uint32_t *array_pos = ecalloc(n_arrays, sizeof(HashPosition)); zval zv; /* We iterate through all the arrays at once. */ @@ -6878,23 +6843,34 @@ PHP_FUNCTION(array_map) zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &result); } + + efree(array_pos); } else { zval *params = (zval *)safe_emalloc(n_arrays, sizeof(zval), 0); + /* Remember next starting point in the array, initialize those as zeros. */ + for (i = 0; i < n_arrays; i++) { + Z_EXTRA(params[i]) = 0; + } + + fci.retval = &result; + fci.param_count = n_arrays; + fci.params = params; + /* We iterate through all the arrays at once. */ for (k = 0; k < maxlen; k++) { for (i = 0; i < n_arrays; i++) { /* If this array still has elements, add the current one to the * parameter list, otherwise use null value. */ - uint32_t pos = array_pos[i]; + uint32_t pos = Z_EXTRA(params[i]); if (HT_IS_PACKED(Z_ARRVAL(arrays[i]))) { while (1) { if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) { ZVAL_NULL(¶ms[i]); break; } else if (Z_TYPE(Z_ARRVAL(arrays[i])->arPacked[pos]) != IS_UNDEF) { - ZVAL_COPY(¶ms[i], &Z_ARRVAL(arrays[i])->arPacked[pos]); - array_pos[i] = pos + 1; + ZVAL_COPY_VALUE(¶ms[i], &Z_ARRVAL(arrays[i])->arPacked[pos]); + Z_EXTRA(params[i]) = pos + 1; break; } pos++; @@ -6905,8 +6881,8 @@ PHP_FUNCTION(array_map) ZVAL_NULL(¶ms[i]); break; } else if (Z_TYPE(Z_ARRVAL(arrays[i])->arData[pos].val) != IS_UNDEF) { - ZVAL_COPY(¶ms[i], &Z_ARRVAL(arrays[i])->arData[pos].val); - array_pos[i] = pos + 1; + ZVAL_COPY_VALUE(¶ms[i], &Z_ARRVAL(arrays[i])->arData[pos].val); + Z_EXTRA(params[i]) = pos + 1; break; } pos++; @@ -6914,26 +6890,13 @@ PHP_FUNCTION(array_map) } } - fci.retval = &result; - fci.param_count = n_arrays; - fci.params = params; - zend_result ret = zend_call_function(&fci, &fci_cache); ZEND_ASSERT(ret == SUCCESS); ZEND_IGNORE_VALUE(ret); if (Z_TYPE(result) == IS_UNDEF) { - efree(array_pos); - zend_array_destroy(Z_ARR_P(return_value)); - for (i = 0; i < n_arrays; i++) { - zval_ptr_dtor(¶ms[i]); - } efree(params); - RETURN_NULL(); - } else { - for (i = 0; i < n_arrays; i++) { - zval_ptr_dtor(¶ms[i]); - } + RETURN_THROWS(); } zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &result); @@ -6941,7 +6904,6 @@ PHP_FUNCTION(array_map) efree(params); } - efree(array_pos); } } /* }}} */ @@ -6965,6 +6927,7 @@ PHP_FUNCTION(array_key_exists) RETVAL_BOOL(zend_hash_index_exists(ht, Z_LVAL_P(key))); break; case IS_NULL: + zend_error(E_DEPRECATED, "Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead"); RETVAL_BOOL(zend_hash_exists(ht, ZSTR_EMPTY_ALLOC())); break; case IS_DOUBLE: @@ -7016,20 +6979,19 @@ PHP_FUNCTION(array_chunk) if (size > num_in) { if (num_in == 0) { - RETVAL_EMPTY_ARRAY(); - return; + RETURN_EMPTY_ARRAY(); } size = num_in; } array_init_size(return_value, (uint32_t)(((num_in - 1) / size) + 1)); - - ZVAL_UNDEF(&chunk); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) { /* If new chunk, create and initialize it. */ - if (Z_TYPE(chunk) == IS_UNDEF) { + if (current == 0) { array_init_size(&chunk, (uint32_t)size); + add_next_index_zval(return_value, &chunk); } /* Add entry to the chunk, preserving keys if necessary. */ @@ -7044,18 +7006,10 @@ PHP_FUNCTION(array_chunk) } zval_add_ref(entry); - /* If reached the chunk size, add it to the result array, and reset the - * pointer. */ - if (!(++current % size)) { - add_next_index_zval(return_value, &chunk); - ZVAL_UNDEF(&chunk); + if (++current == size) { + current = 0; } } ZEND_HASH_FOREACH_END(); - - /* Add the final chunk if there is one. */ - if (Z_TYPE(chunk) != IS_UNDEF) { - add_next_index_zval(return_value, &chunk); - } } /* }}} */ diff --git a/ext/standard/assert.c b/ext/standard/assert.c index 258447576e1f..a976aeda1494 100644 --- a/ext/standard/assert.c +++ b/ext/standard/assert.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -79,7 +77,7 @@ static PHP_INI_MH(OnChangeCallback) /* {{{ */ static PHP_INI_MH(OnUpdateActiveBool) { - bool *p = (bool *) ZEND_INI_GET_ADDR(); + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); if (php_must_emit_ini_deprecation(stage) && !*p) { php_error_docref(NULL, E_DEPRECATED, "assert.active INI setting is deprecated"); @@ -89,7 +87,7 @@ static PHP_INI_MH(OnUpdateActiveBool) static PHP_INI_MH(OnUpdateBailBool) { - bool *p = (bool *) ZEND_INI_GET_ADDR(); + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); if (php_must_emit_ini_deprecation(stage) && *p) { php_error_docref(NULL, E_DEPRECATED, "assert.bail INI setting is deprecated"); @@ -99,7 +97,7 @@ static PHP_INI_MH(OnUpdateBailBool) static PHP_INI_MH(OnUpdateExceptionBool) { - bool *p = (bool *) ZEND_INI_GET_ADDR(); + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); if (php_must_emit_ini_deprecation(stage) && !*p) { php_error_docref(NULL, E_DEPRECATED, "assert.exception INI setting is deprecated"); @@ -110,7 +108,7 @@ static PHP_INI_MH(OnUpdateExceptionBool) static PHP_INI_MH(OnUpdateWarningBool) { - bool *p = (bool *) ZEND_INI_GET_ADDR(); + bool *p = ZEND_INI_GET_ADDR(); *p = zend_ini_parse_bool(new_value); if (php_must_emit_ini_deprecation(stage) && !*p) { php_error_docref(NULL, E_DEPRECATED, "assert.warning INI setting is deprecated"); @@ -285,7 +283,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(value_str, 0); } RETURN_LONG(oldint); - break; case PHP_ASSERT_BAIL: oldint = ASSERTG(bail); @@ -301,7 +298,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(value_str, 0); } RETURN_LONG(oldint); - break; case PHP_ASSERT_WARNING: oldint = ASSERTG(warning); @@ -317,7 +313,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(value_str, 0); } RETURN_LONG(oldint); - break; case PHP_ASSERT_CALLBACK: if (Z_TYPE(ASSERTG(callback)) != IS_UNDEF) { @@ -352,7 +347,6 @@ PHP_FUNCTION(assert_options) zend_string_release_ex(key, 0); } RETURN_LONG(oldint); - break; default: zend_argument_value_error(1, "must be an ASSERT_* constant"); diff --git a/ext/standard/base64.c b/ext/standard/base64.c index 8d4feee84975..5c3f876ef2b9 100644 --- a/ext/standard/base64.c +++ b/ext/standard/base64.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | | Xinchen Hui | @@ -536,7 +534,7 @@ zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t leng /* Step 2: splitting 24-bit words into 32-bit lanes */ str = _mm512_permutexvar_epi8(shuffle_splitting, str); - /* Step 3: moving 6-bit word to sperate bytes */ + /* Step 3: moving 6-bit word to separate bytes */ str = _mm512_multishift_epi64_epi8(multi_shifts, str); /* Step 4: conversion to ASCII */ @@ -643,7 +641,7 @@ zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length, z /* [D1 D2 D0 D1|C1 C2 C0 C1|B1 B2 B0 B1|A1 A2 A0 A1] x 4 */ str = _mm512_shuffle_epi8(str, _mm512_set4_epi32(0x0a0b090a, 0x07080607, 0x04050304, 0x01020001)); - /* Step 3: moving 6-bit word to sperate bytes */ + /* Step 3: moving 6-bit word to separate bytes */ /* in: [bbbbcccc|ccdddddd|aaaaaabb|bbbbcccc] */ /* t0: [0000cccc|cc000000|aaaaaa00|00000000] */ const __m512i t0 = _mm512_and_si512(str, _mm512_set1_epi32(0x0fc0fc00)); diff --git a/ext/standard/base64.h b/ext/standard/base64.h index 19ff0b60d252..a866541b727b 100644 --- a/ext/standard/base64.h +++ b/ext/standard/base64.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | | Xinchen Hui | diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index f26bef3daa4e..2a0e7a786738 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -102,7 +100,6 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #include "zend_globals.h" -#include "php_globals.h" #include "SAPI.h" #include "php_ticks.h" @@ -141,6 +138,8 @@ static void user_shutdown_function_dtor(zval *zv); static void user_tick_function_dtor(user_tick_function_entry *tick_function_entry); static const zend_module_dep standard_deps[] = { /* {{{ */ + ZEND_MOD_REQUIRED("random") + ZEND_MOD_REQUIRED("uri") ZEND_MOD_OPTIONAL("session") ZEND_MOD_END }; @@ -296,14 +295,15 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ assertion_error_ce = register_class_AssertionError(zend_ce_error); rounding_mode_ce = register_class_RoundingMode(); + sort_direction_ce = register_class_SortDirection(); BASIC_MINIT_SUBMODULE(var) BASIC_MINIT_SUBMODULE(file) - BASIC_MINIT_SUBMODULE(pack) BASIC_MINIT_SUBMODULE(browscap) BASIC_MINIT_SUBMODULE(standard_filters) BASIC_MINIT_SUBMODULE(user_filters) BASIC_MINIT_SUBMODULE(password) + BASIC_MINIT_SUBMODULE(image) #ifdef ZTS BASIC_MINIT_SUBMODULE(localeconv) @@ -377,6 +377,7 @@ PHP_MSHUTDOWN_FUNCTION(basic) /* {{{ */ #endif BASIC_MSHUTDOWN_SUBMODULE(crypt) BASIC_MSHUTDOWN_SUBMODULE(password) + BASIC_MSHUTDOWN_SUBMODULE(image) return SUCCESS; } @@ -559,7 +560,7 @@ PHP_FUNCTION(inet_pton) char buffer[17]; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(address, address_len) + Z_PARAM_PATH(address, address_len) ZEND_PARSE_PARAMETERS_END(); memset(buffer, 0, sizeof(buffer)); @@ -591,12 +592,26 @@ PHP_FUNCTION(ip2long) struct in_addr ip; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(addr, addr_len) + Z_PARAM_PATH(addr, addr_len) ZEND_PARSE_PARAMETERS_END(); if (addr_len == 0 || inet_pton(AF_INET, addr, &ip) != 1) { RETURN_FALSE; } +#ifdef _AIX + /* + AIX accepts IP strings with extraneous 0 (192.168.042.42 will be treated as + 192.168.42.42), while Linux doesn't. + For consistency, we convert back the IP to a string and check if it is equal to + the original string. If not, the IP should be considered invalid. + */ + char str[INET_ADDRSTRLEN]; + const char* result = inet_ntop(AF_INET, &ip, str, sizeof(str)); + ZEND_ASSERT(result != NULL); + if (strcmp(addr, result) != 0) { + RETURN_FALSE; + } +#endif RETURN_LONG(ntohl(ip.s_addr)); } /* }}} */ @@ -695,7 +710,7 @@ PHP_FUNCTION(getenv) ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(str, str_len) + Z_PARAM_PATH_OR_NULL(str, str_len) Z_PARAM_BOOL(local_only) ZEND_PARSE_PARAMETERS_END(); @@ -738,7 +753,7 @@ PHP_FUNCTION(putenv) #endif ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(setting, setting_len) + Z_PARAM_PATH(setting, setting_len) ZEND_PARSE_PARAMETERS_END(); if (setting_len == 0 || setting[0] == '=') { @@ -1280,9 +1295,9 @@ static void add_config_entries(HashTable *hash, zval *return_value) /* {{{ */ zend_string *key; zval *zv; - ZEND_HASH_FOREACH_KEY_VAL(hash, h, key, zv) + ZEND_HASH_FOREACH_KEY_VAL(hash, h, key, zv) { add_config_entry(h, key, zv, return_value); - ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -1328,42 +1343,36 @@ error options: /* {{{ Send an error message somewhere */ PHP_FUNCTION(error_log) { - char *message, *opt = NULL, *headers = NULL; - size_t message_len, opt_len = 0, headers_len = 0; + zend_string *message, *opt = NULL, *headers = NULL; zend_long erropt = 0; ZEND_PARSE_PARAMETERS_START(1, 4) - Z_PARAM_STRING(message, message_len) + Z_PARAM_STR(message) Z_PARAM_OPTIONAL Z_PARAM_LONG(erropt) - Z_PARAM_PATH_OR_NULL(opt, opt_len) - Z_PARAM_STRING_OR_NULL(headers, headers_len) + Z_PARAM_PATH_STR_OR_NULL(opt) + Z_PARAM_STR_OR_NULL(headers) ZEND_PARSE_PARAMETERS_END(); - if (_php_error_log_ex((int) erropt, message, message_len, opt, headers) == FAILURE) { - RETURN_FALSE; - } - - RETURN_TRUE; -} -/* }}} */ - -/* For BC (not binary-safe!) */ -PHPAPI int _php_error_log(int opt_err, const char *message, const char *opt, const char *headers) /* {{{ */ -{ - return _php_error_log_ex(opt_err, message, (opt_err == 3) ? strlen(message) : 0, opt, headers); + RETURN_BOOL(_php_error_log((int) erropt, message, opt, headers) == SUCCESS); } /* }}} */ -PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_len, const char *opt, const char *headers) /* {{{ */ +PHPAPI zend_result _php_error_log(int opt_err, const zend_string *message, const zend_string *opt, const zend_string *headers) /* {{{ */ { php_stream *stream = NULL; size_t nbytes; + const char *hdrs = NULL; switch (opt_err) { case 1: /*send an email */ - if (!php_mail(opt, "PHP error_log message", message, headers, NULL)) { + if (!opt) { + return FAILURE; + } + + hdrs = headers ? ZSTR_VAL(headers) : NULL; + if (!php_mail(ZSTR_VAL(opt), "PHP error_log message", ZSTR_VAL(message), hdrs, NULL)) { return FAILURE; } break; @@ -1373,27 +1382,27 @@ PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_le return FAILURE; case 3: /*save to a file */ - stream = php_stream_open_wrapper(opt, "a", REPORT_ERRORS, NULL); + stream = php_stream_open_wrapper(opt ? ZSTR_VAL(opt) : NULL, "a", REPORT_ERRORS, NULL); if (!stream) { return FAILURE; } - nbytes = php_stream_write(stream, message, message_len); + nbytes = php_stream_write(stream, ZSTR_VAL(message), ZSTR_LEN(message)); php_stream_close(stream); - if (nbytes != message_len) { + if (nbytes != ZSTR_LEN(message)) { return FAILURE; } break; case 4: /* send to SAPI */ if (sapi_module.log_message) { - sapi_module.log_message(message, -1); + sapi_module.log_message(ZSTR_VAL(message), -1); } else { return FAILURE; } break; default: - php_log_err_with_severity(message, LOG_NOTICE); + php_log_err_with_severity(ZSTR_VAL(message), LOG_NOTICE); break; } return SUCCESS; @@ -1721,11 +1730,11 @@ PHPAPI bool append_user_shutdown_function(php_shutdown_function_entry *shutdown_ ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini) /* {{{ */ { - syntax_highlighter_ini->highlight_comment = INI_STR("highlight.comment"); - syntax_highlighter_ini->highlight_default = INI_STR("highlight.default"); - syntax_highlighter_ini->highlight_html = INI_STR("highlight.html"); - syntax_highlighter_ini->highlight_keyword = INI_STR("highlight.keyword"); - syntax_highlighter_ini->highlight_string = INI_STR("highlight.string"); + syntax_highlighter_ini->highlight_comment = zend_ini_string_literal("highlight.comment"); + syntax_highlighter_ini->highlight_default = zend_ini_string_literal("highlight.default"); + syntax_highlighter_ini->highlight_html = zend_ini_string_literal("highlight.html"); + syntax_highlighter_ini->highlight_keyword = zend_ini_string_literal("highlight.keyword"); + syntax_highlighter_ini->highlight_string = zend_ini_string_literal("highlight.string"); } /* }}} */ @@ -1749,7 +1758,10 @@ PHP_FUNCTION(highlight_file) } if (i) { - php_output_start_default(); + if (UNEXPECTED(php_output_start_default() != SUCCESS)) { + zend_throw_error(NULL, "Unable to start output handler"); + RETURN_THROWS(); + } } php_get_highlight_struct(&syntax_highlighter_ini); @@ -1784,7 +1796,10 @@ PHP_FUNCTION(php_strip_whitespace) Z_PARAM_PATH_STR(filename) ZEND_PARSE_PARAMETERS_END(); - php_output_start_default(); + if (UNEXPECTED(php_output_start_default() != SUCCESS)) { + zend_throw_error(NULL, "Unable to start output handler"); + RETURN_THROWS(); + } zend_stream_init_filename_ex(&file_handle, filename); zend_save_lexical_state(&original_lex_state); @@ -1821,7 +1836,10 @@ PHP_FUNCTION(highlight_string) ZEND_PARSE_PARAMETERS_END(); if (i) { - php_output_start_default(); + if (UNEXPECTED(php_output_start_default() != SUCCESS)) { + zend_throw_error(NULL, "Unable to start output handler"); + RETURN_THROWS(); + } } EG(error_reporting) = E_ERROR; @@ -1937,6 +1955,12 @@ PHP_FUNCTION(ini_get_all) add_assoc_null(&option, "local_value"); } + if (ini_entry->def->value) { + add_assoc_stringl(&option, "builtin_default_value", ini_entry->def->value, ini_entry->def->value_length); + } else { + add_assoc_null(&option, "builtin_default_value"); + } + add_assoc_long(&option, "access", ini_entry->modifiable); zend_symtable_update(Z_ARRVAL_P(return_value), ini_entry->name, &option); @@ -1986,10 +2010,8 @@ PHP_FUNCTION(ini_set) /* open basedir check */ if (PG(open_basedir)) { if ( - zend_string_equals_literal(varname, "error_log") - || zend_string_equals_literal(varname, "java.class.path") + zend_string_equals_literal(varname, "java.class.path") || zend_string_equals_literal(varname, "java.home") - || zend_string_equals_literal(varname, "mail.log") || zend_string_equals_literal(varname, "java.library.path") || zend_string_equals_literal(varname, "vpopmail.directory") ) { @@ -2026,17 +2048,16 @@ PHP_FUNCTION(ini_restore) PHP_FUNCTION(set_include_path) { zend_string *new_value; - char *old_value; zend_string *key; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_PATH_STR(new_value) ZEND_PARSE_PARAMETERS_END(); - old_value = zend_ini_string("include_path", sizeof("include_path") - 1, 0); + zend_string *old_value = zend_ini_str_literal("include_path"); /* copy to return here, because alter might free it! */ if (old_value) { - RETVAL_STRING(old_value); + RETVAL_STR_COPY(old_value); } else { RETVAL_FALSE; } @@ -2056,7 +2077,7 @@ PHP_FUNCTION(get_include_path) { ZEND_PARSE_PARAMETERS_NONE(); - zend_string *str = zend_ini_str("include_path", sizeof("include_path") - 1, 0); + zend_string *str = zend_ini_str_literal("include_path"); if (str == NULL) { RETURN_FALSE; @@ -2139,8 +2160,8 @@ PHP_FUNCTION(getservbyname) struct servent *serv; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STR(name) - Z_PARAM_STRING(proto, proto_len) + Z_PARAM_PATH_STR(name) + Z_PARAM_PATH(proto, proto_len) ZEND_PARSE_PARAMETERS_END(); @@ -2183,7 +2204,7 @@ PHP_FUNCTION(getservbyport) ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_LONG(port) - Z_PARAM_STRING(proto, proto_len) + Z_PARAM_PATH(proto, proto_len) ZEND_PARSE_PARAMETERS_END(); serv = getservbyport(htons((unsigned short) port), proto); @@ -2210,7 +2231,7 @@ PHP_FUNCTION(getprotobyname) struct protoent *ent; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(name, name_len) + Z_PARAM_PATH(name, name_len) ZEND_PARSE_PARAMETERS_END(); ent = getprotobyname(name); @@ -2322,11 +2343,7 @@ PHP_FUNCTION(is_uploaded_file) RETURN_FALSE; } - if (zend_hash_exists(SG(rfc1867_uploaded_files), path)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_hash_exists(SG(rfc1867_uploaded_files), path)); } /* }}} */ diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index bad6fcf4e645..6bd227eac5d2 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -27,6 +25,8 @@ #include "url_scanner_ex.h" +#include "basic_functions_decl.h" + #if defined(_WIN32) && !defined(__clang__) #include #endif @@ -46,10 +46,7 @@ PHP_MINIT_FUNCTION(user_filters); PHP_RSHUTDOWN_FUNCTION(user_filters); PHP_RSHUTDOWN_FUNCTION(browscap); -/* Left for BC (not binary safe!) */ -PHPAPI int _php_error_log(int opt_err, const char *message, const char *opt, const char *headers); -PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_len, const char *opt, const char *headers); -PHPAPI int php_prefix_varname(zval *result, zend_string *prefix, const char *var_name, size_t var_name_len, bool add_underscore); +PHPAPI zend_result _php_error_log(int opt_err, const zend_string *message, const zend_string *opt, const zend_string *headers); typedef struct _php_basic_globals { HashTable *user_shutdown_function_names; diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 09f63860f116..1999c9b92be1 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1,6 +1,9 @@ * @refcount 1 + * @forbid-dynamic-calls */ function compact($var_name, ...$var_names): array {} @@ -1686,13 +1691,11 @@ function array_merge_recursive(array ...$arrays): array {} /** * @compile-time-eval - * @refcount 1 */ function array_replace(array $array, array ...$replacements): array {} /** * @compile-time-eval - * @refcount 1 */ function array_replace_recursive(array $array, array ...$replacements): array {} @@ -1775,19 +1778,16 @@ function array_intersect_key(array $array, array ...$arrays): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_intersect_ukey(array $array, ...$rest): array {} /** * @compile-time-eval - * @refcount 1 */ function array_intersect(array $array, array ...$arrays): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_uintersect(array $array, ...$rest): array {} @@ -1805,13 +1805,11 @@ function array_uintersect_assoc(array $array, ...$rest): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_intersect_uassoc(array $array, ...$rest): array {} /** * @param array|callable $rest - * @refcount 1 */ function array_uintersect_uassoc(array $array, ...$rest): array {} @@ -1885,7 +1883,7 @@ function array_product(array $array): int|float {} function array_reduce(array $array, callable $callback, mixed $initial = null): mixed {} -function array_filter(array $array, ?callable $callback = null, int $mode = 0): array {} +function array_filter(array $array, ?callable $callback = null, int $mode = ARRAY_FILTER_USE_VALUE): array {} function array_find(array $array, callable $callback): mixed {} @@ -2329,16 +2327,16 @@ function strcoll(string $string1, string $string2): int {} * @frameless-function {"arity": 1} * @frameless-function {"arity": 2} */ -function trim(string $string, string $characters = " \n\r\t\v\0"): string {} +function trim(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** @compile-time-eval */ -function rtrim(string $string, string $characters = " \n\r\t\v\0"): string {} +function rtrim(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** @alias rtrim */ -function chop(string $string, string $characters = " \n\r\t\v\0"): string {} +function chop(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** @compile-time-eval */ -function ltrim(string $string, string $characters = " \n\r\t\v\0"): string {} +function ltrim(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** * @compile-time-eval @@ -2562,8 +2560,8 @@ function nl2br(string $string, bool $use_xhtml = true): string {} function strip_tags(string $string, array|string|null $allowed_tags = null): string {} /** - * @param array|string $locales - * @param string $rest + * @param array|string|null $locales + * @param string|null $rest */ function setlocale(int $category, $locales, ...$rest): string|false {} @@ -2699,7 +2697,6 @@ function scandir(string $directory, int $sorting_order = SCANDIR_SORT_ASCENDING, /** * @return array|false - * @refcount 1 */ function glob(string $pattern, int $flags = 0): array|false {} @@ -3589,6 +3586,7 @@ function stream_set_timeout($stream, int $seconds, int $microseconds = 0): bool * @param resource $stream * @alias stream_set_timeout */ +#[\Deprecated(since: '8.5', message: "use stream_set_timeout() instead")] function socket_set_timeout($stream, int $seconds, int $microseconds = 0): bool {} #endif diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 37df4de7bdfc..e51a837ffa4d 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,6 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: dfd7d2cfd31312f7f6c5074c10cab54e9d1fbccc */ +/* This is a generated file, edit basic_functions.stub.php instead. + * Stub hash: 36b71aa7bbfe478a5e4af400b2822a77067efa2f + * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -138,6 +139,12 @@ ZEND_END_ARG_INFO() #define arginfo_max arginfo_min +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_clamp, 0, 3, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, min, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, max, IS_MIXED, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_walk, 0, 2, IS_TRUE, 0) ZEND_ARG_TYPE_MASK(1, array, MAY_BE_ARRAY|MAY_BE_OBJECT, NULL) ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) @@ -339,7 +346,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_filter, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "ARRAY_FILTER_USE_VALUE") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_find, 0, 2, IS_MIXED, 0) @@ -832,7 +839,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_trim, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, characters, IS_STRING, 0, "\" \\n\\r\\t\\v\\x00\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, characters, IS_STRING, 0, "\" \\f\\n\\r\\t\\v\\x00\"") ZEND_END_ARG_INFO() #define arginfo_rtrim arginfo_trim @@ -2197,6 +2204,12 @@ static const zend_frameless_function_info frameless_function_infos_max[] = { { 0 }, }; +ZEND_FRAMELESS_FUNCTION(clamp, 3); +static const zend_frameless_function_info frameless_function_infos_clamp[] = { + { ZEND_FRAMELESS_FUNCTION_NAME(clamp, 3), 3 }, + { 0 }, +}; + ZEND_FRAMELESS_FUNCTION(in_array, 2); ZEND_FRAMELESS_FUNCTION(in_array, 3); static const zend_frameless_function_info frameless_function_infos_in_array[] = { @@ -2332,6 +2345,7 @@ ZEND_FUNCTION(current); ZEND_FUNCTION(key); ZEND_FUNCTION(min); ZEND_FUNCTION(max); +ZEND_FUNCTION(clamp); ZEND_FUNCTION(array_walk); ZEND_FUNCTION(array_walk_recursive); ZEND_FUNCTION(in_array); @@ -2925,12 +2939,21 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(key, arginfo_key) ZEND_RAW_FENTRY("min", zif_min, arginfo_min, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_min, NULL) ZEND_RAW_FENTRY("max", zif_max, arginfo_max, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_max, NULL) + ZEND_RAW_FENTRY("clamp", zif_clamp, arginfo_clamp, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_clamp, NULL) ZEND_FE(array_walk, arginfo_array_walk) ZEND_FE(array_walk_recursive, arginfo_array_walk_recursive) ZEND_RAW_FENTRY("in_array", zif_in_array, arginfo_in_array, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_in_array, NULL) ZEND_RAW_FENTRY("array_search", zif_array_search, arginfo_array_search, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) - ZEND_FE(extract, arginfo_extract) - ZEND_FE(compact, arginfo_compact) +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("extract", zif_extract, arginfo_extract, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("extract", zif_extract, arginfo_extract, 0, NULL, NULL) +#endif +#if (PHP_VERSION_ID >= 80600) + ZEND_RAW_FENTRY("compact", zif_compact, arginfo_compact, ZEND_FENTRY_FLAGS(0, ZEND_ACC2_FORBID_DYN_CALLS), NULL, NULL) +#elif (PHP_VERSION_ID >= 80400) + ZEND_RAW_FENTRY("compact", zif_compact, arginfo_compact, 0, NULL, NULL) +#endif ZEND_FE(array_fill, arginfo_array_fill) ZEND_FE(array_fill_keys, arginfo_array_fill_keys) ZEND_FE(range, arginfo_range) @@ -3431,7 +3454,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(stream_set_chunk_size, arginfo_stream_set_chunk_size) #if (defined(HAVE_SYS_TIME_H) || defined(PHP_WIN32)) ZEND_FE(stream_set_timeout, arginfo_stream_set_timeout) - ZEND_RAW_FENTRY("socket_set_timeout", zif_stream_set_timeout, arginfo_socket_set_timeout, 0, NULL, NULL) + ZEND_RAW_FENTRY("socket_set_timeout", zif_stream_set_timeout, arginfo_socket_set_timeout, ZEND_ACC_DEPRECATED, NULL, NULL) #endif ZEND_RAW_FENTRY("gettype", zif_gettype, arginfo_gettype, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("get_debug_type", zif_get_debug_type, arginfo_get_debug_type, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) @@ -3516,13 +3539,14 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("CASE_UPPER", PHP_CASE_UPPER, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("COUNT_NORMAL", PHP_COUNT_NORMAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("COUNT_RECURSIVE", PHP_COUNT_RECURSIVE, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_VALUE", ARRAY_FILTER_USE_VALUE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_BOTH", ARRAY_FILTER_USE_BOTH, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_KEY", ARRAY_FILTER_USE_KEY, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("ASSERT_ACTIVE", PHP_ASSERT_ACTIVE, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("ASSERT_CALLBACK", PHP_ASSERT_CALLBACK, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("ASSERT_BAIL", PHP_ASSERT_BAIL, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("ASSERT_WARNING", PHP_ASSERT_WARNING, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("ASSERT_EXCEPTION", PHP_ASSERT_EXCEPTION, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_ASSERT_ACTIVE = REGISTER_LONG_CONSTANT("ASSERT_ACTIVE", PHP_ASSERT_ACTIVE, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_ASSERT_CALLBACK = REGISTER_LONG_CONSTANT("ASSERT_CALLBACK", PHP_ASSERT_CALLBACK, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_ASSERT_BAIL = REGISTER_LONG_CONSTANT("ASSERT_BAIL", PHP_ASSERT_BAIL, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_ASSERT_WARNING = REGISTER_LONG_CONSTANT("ASSERT_WARNING", PHP_ASSERT_WARNING, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_ASSERT_EXCEPTION = REGISTER_LONG_CONSTANT("ASSERT_EXCEPTION", PHP_ASSERT_EXCEPTION, CONST_PERSISTENT | CONST_DEPRECATED); REGISTER_LONG_CONSTANT("CONNECTION_ABORTED", PHP_CONNECTION_ABORTED, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CONNECTION_NORMAL", PHP_CONNECTION_NORMAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CONNECTION_TIMEOUT", PHP_CONNECTION_TIMEOUT, CONST_PERSISTENT); @@ -3645,8 +3669,9 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("IMAGETYPE_ICO", IMAGE_FILETYPE_ICO, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_AVIF", IMAGE_FILETYPE_AVIF, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_HEIF", IMAGE_FILETYPE_HEIF, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_FIXED_COUNT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_GENERAL", PHP_INFO_GENERAL, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_CREDITS", PHP_INFO_CREDITS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_CONFIGURATION", PHP_INFO_CONFIGURATION, CONST_PERSISTENT); @@ -3894,52 +3919,84 @@ static void register_basic_functions_symbols(int module_number) #if defined(HAVE_STRPTIME) zend_attribute *attribute_Deprecated_func_strptime_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "strptime", sizeof("strptime") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_strptime_0_arg0; - zend_string *attribute_Deprecated_func_strptime_0_arg0_str = zend_string_init("8.2", strlen("8.2"), 1); - ZVAL_STR(&attribute_Deprecated_func_strptime_0_arg0, attribute_Deprecated_func_strptime_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_strptime_0->args[0].value, &attribute_Deprecated_func_strptime_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_strptime_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func_strptime_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_strptime_0_arg1; zend_string *attribute_Deprecated_func_strptime_0_arg1_str = zend_string_init("use date_parse_from_format() (for locale-independent parsing), or IntlDateFormatter::parse() (for locale-dependent parsing) instead", strlen("use date_parse_from_format() (for locale-independent parsing), or IntlDateFormatter::parse() (for locale-dependent parsing) instead"), 1); - ZVAL_STR(&attribute_Deprecated_func_strptime_0_arg1, attribute_Deprecated_func_strptime_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_strptime_0->args[1].value, &attribute_Deprecated_func_strptime_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_strptime_0->args[1].value, attribute_Deprecated_func_strptime_0_arg1_str); attribute_Deprecated_func_strptime_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); #endif zend_attribute *attribute_Deprecated_func_assert_options_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "assert_options", sizeof("assert_options") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 1); - zval attribute_Deprecated_func_assert_options_0_arg0; - zend_string *attribute_Deprecated_func_assert_options_0_arg0_str = zend_string_init("8.3", strlen("8.3"), 1); - ZVAL_STR(&attribute_Deprecated_func_assert_options_0_arg0, attribute_Deprecated_func_assert_options_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_assert_options_0->args[0].value, &attribute_Deprecated_func_assert_options_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_assert_options_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); attribute_Deprecated_func_assert_options_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); zend_attribute *attribute_Deprecated_func_utf8_encode_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "utf8_encode", sizeof("utf8_encode") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_utf8_encode_0_arg0; - zend_string *attribute_Deprecated_func_utf8_encode_0_arg0_str = zend_string_init("8.2", strlen("8.2"), 1); - ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0_arg0, attribute_Deprecated_func_utf8_encode_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_utf8_encode_0->args[0].value, &attribute_Deprecated_func_utf8_encode_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func_utf8_encode_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_utf8_encode_0_arg1; zend_string *attribute_Deprecated_func_utf8_encode_0_arg1_str = zend_string_init("visit the php.net documentation for various alternatives", strlen("visit the php.net documentation for various alternatives"), 1); - ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0_arg1, attribute_Deprecated_func_utf8_encode_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_utf8_encode_0->args[1].value, &attribute_Deprecated_func_utf8_encode_0_arg1); + ZVAL_STR(&attribute_Deprecated_func_utf8_encode_0->args[1].value, attribute_Deprecated_func_utf8_encode_0_arg1_str); attribute_Deprecated_func_utf8_encode_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_attribute *attribute_Deprecated_func_utf8_decode_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "utf8_decode", sizeof("utf8_decode") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); - zval attribute_Deprecated_func_utf8_decode_0_arg0; - zend_string *attribute_Deprecated_func_utf8_decode_0_arg0_str = zend_string_init("8.2", strlen("8.2"), 1); - ZVAL_STR(&attribute_Deprecated_func_utf8_decode_0_arg0, attribute_Deprecated_func_utf8_decode_0_arg0_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_utf8_decode_0->args[0].value, &attribute_Deprecated_func_utf8_decode_0_arg0); + ZVAL_STR(&attribute_Deprecated_func_utf8_decode_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_2)); attribute_Deprecated_func_utf8_decode_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); - zval attribute_Deprecated_func_utf8_decode_0_arg1; - zend_string *attribute_Deprecated_func_utf8_decode_0_arg1_str = zend_string_init("visit the php.net documentation for various alternatives", strlen("visit the php.net documentation for various alternatives"), 1); - ZVAL_STR(&attribute_Deprecated_func_utf8_decode_0_arg1, attribute_Deprecated_func_utf8_decode_0_arg1_str); - ZVAL_COPY_VALUE(&attribute_Deprecated_func_utf8_decode_0->args[1].value, &attribute_Deprecated_func_utf8_decode_0_arg1); + ZVAL_STR_COPY(&attribute_Deprecated_func_utf8_decode_0->args[1].value, attribute_Deprecated_func_utf8_encode_0_arg1_str); attribute_Deprecated_func_utf8_decode_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "password_hash", sizeof("password_hash") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "password_verify", sizeof("password_verify") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#if (defined(HAVE_SYS_TIME_H) || defined(PHP_WIN32)) + + zend_attribute *attribute_Deprecated_func_socket_set_timeout_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "socket_set_timeout", sizeof("socket_set_timeout") - 1), ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_func_socket_set_timeout_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_5)); + attribute_Deprecated_func_socket_set_timeout_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_func_socket_set_timeout_0_arg1_str = zend_string_init("use stream_set_timeout() instead", strlen("use stream_set_timeout() instead"), 1); + ZVAL_STR(&attribute_Deprecated_func_socket_set_timeout_0->args[1].value, attribute_Deprecated_func_socket_set_timeout_0_arg1_str); + attribute_Deprecated_func_socket_set_timeout_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +#endif + + zend_attribute *attribute_Deprecated_const_ASSERT_ACTIVE_0 = zend_add_global_constant_attribute(const_ASSERT_ACTIVE, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); + attribute_Deprecated_const_ASSERT_ACTIVE_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str = zend_string_init("as assert_options() is deprecated", strlen("as assert_options() is deprecated"), 1); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_ACTIVE_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); + attribute_Deprecated_const_ASSERT_ACTIVE_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_ASSERT_CALLBACK_0 = zend_add_global_constant_attribute(const_ASSERT_CALLBACK, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_CALLBACK_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); + attribute_Deprecated_const_ASSERT_CALLBACK_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_CALLBACK_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); + attribute_Deprecated_const_ASSERT_CALLBACK_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_ASSERT_BAIL_0 = zend_add_global_constant_attribute(const_ASSERT_BAIL, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_BAIL_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); + attribute_Deprecated_const_ASSERT_BAIL_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_BAIL_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); + attribute_Deprecated_const_ASSERT_BAIL_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_ASSERT_WARNING_0 = zend_add_global_constant_attribute(const_ASSERT_WARNING, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_WARNING_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); + attribute_Deprecated_const_ASSERT_WARNING_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_WARNING_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); + attribute_Deprecated_const_ASSERT_WARNING_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_ASSERT_EXCEPTION_0 = zend_add_global_constant_attribute(const_ASSERT_EXCEPTION, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_3)); + attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[1].value, attribute_Deprecated_const_ASSERT_ACTIVE_0_arg1_str); + attribute_Deprecated_const_ASSERT_EXCEPTION_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); +} + +static zend_class_entry *register_class_SortDirection(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("SortDirection", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Ascending", NULL); + + zend_enum_add_case_cstr(class_entry, "Descending", NULL); + + return class_entry; } static zend_class_entry *register_class___PHP_Incomplete_Class(void) @@ -3949,9 +4006,9 @@ static zend_class_entry *register_class___PHP_Incomplete_Class(void) INIT_CLASS_ENTRY(ce, "__PHP_Incomplete_Class", NULL); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES); - zend_string *attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, 1); + zend_string *attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0 = zend_string_init_interned("AllowDynamicProperties", sizeof("AllowDynamicProperties") - 1, true); zend_add_class_attribute(class_entry, attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0, 0); - zend_string_release(attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0); + zend_string_release_ex(attribute_name_AllowDynamicProperties_class___PHP_Incomplete_Class_0, true); return class_entry; } diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h new file mode 100644 index 000000000000..b3eb25c5d988 --- /dev/null +++ b/ext/standard/basic_functions_decl.h @@ -0,0 +1,23 @@ +/* This is a generated file, edit basic_functions.stub.php instead. + * Stub hash: 36b71aa7bbfe478a5e4af400b2822a77067efa2f */ + +#ifndef ZEND_BASIC_FUNCTIONS_DECL_36b71aa7bbfe478a5e4af400b2822a77067efa2f_H +#define ZEND_BASIC_FUNCTIONS_DECL_36b71aa7bbfe478a5e4af400b2822a77067efa2f_H + +typedef enum zend_enum_SortDirection { + ZEND_ENUM_SortDirection_Ascending = 1, + ZEND_ENUM_SortDirection_Descending = 2, +} zend_enum_SortDirection; + +typedef enum zend_enum_RoundingMode { + ZEND_ENUM_RoundingMode_HalfAwayFromZero = 1, + ZEND_ENUM_RoundingMode_HalfTowardsZero = 2, + ZEND_ENUM_RoundingMode_HalfEven = 3, + ZEND_ENUM_RoundingMode_HalfOdd = 4, + ZEND_ENUM_RoundingMode_TowardsZero = 5, + ZEND_ENUM_RoundingMode_AwayFromZero = 6, + ZEND_ENUM_RoundingMode_NegativeInfinity = 7, + ZEND_ENUM_RoundingMode_PositiveInfinity = 8, +} zend_enum_RoundingMode; + +#endif /* ZEND_BASIC_FUNCTIONS_DECL_36b71aa7bbfe478a5e4af400b2822a77067efa2f_H */ diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 685fe09357d0..7534615a946b 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ @@ -277,7 +275,7 @@ static HashTable *browscap_entry_to_array(browser_data *bdata, browscap_entry *e zval tmp; HashTable *ht = zend_new_array(2 + (entry->parent ? 1 : 0) + (entry->kv_end - entry->kv_start)); - ZVAL_STR(&tmp, browscap_convert_pattern(entry->pattern, 0)); + ZVAL_STR(&tmp, browscap_convert_pattern(entry->pattern, false)); zend_string *key = ZSTR_INIT_LITERAL("browser_name_regex", 0); ZSTR_H(key) = zend_inline_hash_func("browser_name_regex", sizeof("browser_name_regex")-1); zend_hash_add_new(ht, key, &tmp); @@ -337,7 +335,7 @@ static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callb ) { zend_error(E_CORE_ERROR, "Invalid browscap ini file: " "'Parent' value cannot be same as the section name: %s " - "(in file %s)", ZSTR_VAL(ctx->current_section_name), INI_STR("browscap")); + "(in file %s)", ZSTR_VAL(ctx->current_section_name), zend_ini_string_literal("browscap")); return; } @@ -399,7 +397,7 @@ static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callb } /* }}} */ -static zend_result browscap_read_file(char *filename, browser_data *browdata, bool persistent) /* {{{ */ +static zend_result browscap_read_file(const char *filename, browser_data *browdata, bool persistent) /* {{{ */ { zend_file_handle fh; browscap_parser_ctx ctx = {0}; @@ -485,7 +483,7 @@ PHP_INI_MH(OnChangeBrowscap) } else if (stage == PHP_INI_STAGE_ACTIVATE) { browser_data *bdata = &BROWSCAP_G(activation_bdata); if (bdata->filename[0] != '\0') { - browscap_bdata_dtor(bdata, 0); + browscap_bdata_dtor(bdata, false); } if (VCWD_REALPATH(ZSTR_VAL(new_value), bdata->filename) == NULL) { return FAILURE; @@ -499,7 +497,7 @@ PHP_INI_MH(OnChangeBrowscap) PHP_MINIT_FUNCTION(browscap) /* {{{ */ { - char *browscap = INI_STR("browscap"); + const char *browscap = zend_ini_string_literal("browscap"); #ifdef ZTS ts_allocate_id(&browscap_globals_id, sizeof(browser_data), (ts_allocate_ctor) browscap_globals_ctor, NULL); @@ -520,7 +518,7 @@ PHP_RSHUTDOWN_FUNCTION(browscap) /* {{{ */ { browser_data *bdata = &BROWSCAP_G(activation_bdata); if (bdata->filename[0] != '\0') { - browscap_bdata_dtor(bdata, 0); + browscap_bdata_dtor(bdata, false); } return SUCCESS; @@ -529,7 +527,7 @@ PHP_RSHUTDOWN_FUNCTION(browscap) /* {{{ */ PHP_MSHUTDOWN_FUNCTION(browscap) /* {{{ */ { - browscap_bdata_dtor(&global_bdata, 1); + browscap_bdata_dtor(&global_bdata, true); return SUCCESS; } diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index ef6b3c5a0101..1d64c7ff6968 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -328,7 +328,7 @@ dnl PHP_CHECK_FUNC(res_search, resolv, socket) -AC_CHECK_FUNCS([posix_spawn_file_actions_addchdir_np elf_aux_info]) +AC_CHECK_FUNCS([posix_spawn_file_actions_addchdir posix_spawn_file_actions_addchdir_np elf_aux_info]) dnl dnl Obsolete check for strptime() declaration. The strptime, where available, diff --git a/ext/standard/config.w32 b/ext/standard/config.w32 index c7c14b8705ca..589929027f65 100644 --- a/ext/standard/config.w32 +++ b/ext/standard/config.w32 @@ -4,8 +4,8 @@ ARG_WITH("password-argon2", "Argon2 support", "no"); if (PHP_PASSWORD_ARGON2 != "no") { if (CHECK_LIB("argon2_a.lib;argon2.lib", null, PHP_PASSWORD_ARGON2) - && CHECK_HEADER_ADD_INCLUDE("argon2.h", "CFLAGS")) { - if (!CHECK_FUNC_IN_HEADER("argon2.h", "argon2id_hash_raw", PHP_PHP_BUILD + "\\include", "CFLAGS")) { + && CHECK_HEADER("argon2.h", "CFLAGS")) { + if (!GREP_HEADER("argon2.h", "argon2id_hash_raw", PHP_PHP_BUILD + "\\include")) { ERROR("Please verify that Argon2 header and libraries >= 20161029 are installed"); } AC_DEFINE('HAVE_ARGON2LIB', 1, "Define to 1 if the system has the 'libargon2' library."); @@ -19,7 +19,7 @@ ARG_WITH("config-file-scan-dir", "Dir to check for additional php ini files", "" AC_DEFINE("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR); AC_DEFINE("PHP_USE_PHP_CRYPT_R", 1, "Define to 1 if PHP uses its own crypt_r, and to 0 if using the external crypt library."); -CHECK_HEADER_ADD_INCLUDE("timelib_config.h", "CFLAGS_STANDARD", "ext/date/lib"); +CHECK_HEADER("timelib_config.h", "CFLAGS_STANDARD", "ext/date/lib"); ADD_FLAG("LIBS_STANDARD", "iphlpapi.lib"); diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index e99c3ca9f5a0..fdf9df37c337 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/crc32.h b/ext/standard/crc32.h index 261acdeb1fec..97f2bc01a282 100644 --- a/ext/standard/crc32.h +++ b/ext/standard/crc32.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/crc32_x86.c b/ext/standard/crc32_x86.c index 0b655fd6a483..5a6debc6f410 100644 --- a/ext/standard/crc32_x86.c +++ b/ext/standard/crc32_x86.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Frank Du | +----------------------------------------------------------------------+ diff --git a/ext/standard/crc32_x86.h b/ext/standard/crc32_x86.h index 91b5ba80e691..c46775f1af22 100644 --- a/ext/standard/crc32_x86.h +++ b/ext/standard/crc32_x86.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Frank Du | +----------------------------------------------------------------------+ diff --git a/ext/standard/credits.c b/ext/standard/credits.c index 4e8722db4d66..2b38cbf3b4e9 100644 --- a/ext/standard/credits.c +++ b/ext/standard/credits.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | diff --git a/ext/standard/credits.h b/ext/standard/credits.h index a0c5d1e7d90c..2a346dd06ddd 100644 --- a/ext/standard/credits.h +++ b/ext/standard/credits.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 54687f6cdf30..d8a9905cfc13 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Bakken | | Zeev Suraski | diff --git a/ext/standard/crypt_sha256.c b/ext/standard/crypt_sha256.c index 5bc3e93fe15f..2673dcf2b08e 100644 --- a/ext/standard/crypt_sha256.c +++ b/ext/standard/crypt_sha256.c @@ -338,7 +338,7 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b char *s_bytes; /* Default number of rounds. */ size_t rounds = ROUNDS_DEFAULT; - bool rounds_custom = 0; + bool rounds_custom = false; /* Find beginning of salt string. The prefix should normally always be present. Just in case it is not. */ @@ -358,7 +358,7 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b } rounds = srounds; - rounds_custom = 1; + rounds_custom = true; } } diff --git a/ext/standard/crypt_sha512.c b/ext/standard/crypt_sha512.c index e6410fb91622..e8cedaa55c20 100644 --- a/ext/standard/crypt_sha512.c +++ b/ext/standard/crypt_sha512.c @@ -375,7 +375,7 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) char *s_bytes; /* Default number of rounds. */ size_t rounds = ROUNDS_DEFAULT; - bool rounds_custom = 0; + bool rounds_custom = false; /* Find beginning of salt string. The prefix should normally always be present. Just in case it is not. */ @@ -396,7 +396,7 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) } rounds = srounds; - rounds_custom = 1; + rounds_custom = true; } } diff --git a/ext/standard/css.c b/ext/standard/css.c index 41efc028ff72..87387c9a3826 100644 --- a/ext/standard/css.c +++ b/ext/standard/css.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Colin Viebrock | +----------------------------------------------------------------------+ diff --git a/ext/standard/css.h b/ext/standard/css.h index 6771541f5fc5..59dbef62204c 100644 --- a/ext/standard/css.h +++ b/ext/standard/css.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Colin Viebrock | +----------------------------------------------------------------------+ diff --git a/ext/standard/datetime.c b/ext/standard/datetime.c index 93f47f0f858b..b60182ee7f33 100644 --- a/ext/standard/datetime.c +++ b/ext/standard/datetime.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | diff --git a/ext/standard/dir.c b/ext/standard/dir.c index cced88e4ac8a..f313d5f539d1 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -160,6 +158,8 @@ PHP_FUNCTION(dir) static php_stream* php_dir_get_directory_stream_from_user_arg(php_stream *dir_stream) { if (dir_stream == NULL) { + php_error_docref(NULL, E_DEPRECATED, + "Passing null is deprecated, instead the last opened directory stream should be provided"); if (UNEXPECTED(DIRG(default_dir) == NULL)) { zend_type_error("No resource supplied"); return NULL; @@ -398,13 +398,34 @@ PHP_FUNCTION(getcwd) /* }}} */ /* {{{ Find pathnames matching a pattern */ +#if defined(ZTS) && defined(PHP_GLOB_ALTDIRFUNC) +static void *php_glob_opendir_wrapper(const char *path) +{ + return VCWD_OPENDIR(path); +} + +static void php_glob_closedir_wrapper(void *dir) +{ + (void) closedir(dir); +} + +static int php_glob_lstat_wrapper(const char *buf, zend_stat_t *sb) +{ + return VCWD_LSTAT(buf, sb); +} + +static int php_glob_stat_wrapper(const char *buf, zend_stat_t *sb) +{ + return VCWD_STAT(buf, sb); +} +#endif + PHP_FUNCTION(glob) { size_t cwd_skip = 0; -#ifdef ZTS +#if defined(ZTS) && !defined(PHP_GLOB_ALTDIRFUNC) char cwd[MAXPATHLEN]; char work_pattern[MAXPATHLEN]; - char *result; #endif char *pattern = NULL; size_t pattern_len; @@ -431,28 +452,45 @@ PHP_FUNCTION(glob) RETURN_FALSE; } + memset(&globbuf, 0, sizeof(globbuf)); + + int passed_glob_flags = flags & PHP_GLOB_FLAGMASK; + #ifdef ZTS if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) { - result = VCWD_GETCWD(cwd, MAXPATHLEN); + /* System glob uses the current work directory which is not thread safe. + * The first fix is to override the functions used to open/read/... paths + * with the VCWD ones used in PHP. + * If that functionality is unavailable for whatever reason, fall back + * to prepending the current working directory to the passed path. + * However, that comes with limitations regarding meta characters + * that is not solvable in general (GH-13204). */ +# ifdef PHP_GLOB_ALTDIRFUNC + globbuf.gl_opendir = php_glob_opendir_wrapper; + globbuf.gl_readdir = (struct dirent *(*)(void *)) readdir; + globbuf.gl_closedir = php_glob_closedir_wrapper; + globbuf.gl_lstat = php_glob_lstat_wrapper; + globbuf.gl_stat = php_glob_stat_wrapper; + passed_glob_flags |= PHP_GLOB_ALTDIRFUNC; +# else + char *result = VCWD_GETCWD(cwd, MAXPATHLEN); if (!result) { cwd[0] = '\0'; } -#ifdef PHP_WIN32 +# ifdef PHP_WIN32 if (IS_SLASH(*pattern)) { cwd[2] = '\0'; } -#endif +# endif cwd_skip = strlen(cwd)+1; snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern); pattern = work_pattern; +# endif } #endif - - memset(&globbuf, 0, sizeof(globbuf)); - globbuf.gl_offs = 0; - if (0 != (ret = php_glob(pattern, flags & PHP_GLOB_FLAGMASK, NULL, &globbuf))) { + if (0 != (ret = php_glob(pattern, passed_glob_flags, NULL, &globbuf))) { #ifdef PHP_GLOB_NOMATCH if (PHP_GLOB_NOMATCH == ret) { /* Some glob implementation simply return no data if no matches @@ -474,8 +512,7 @@ PHP_FUNCTION(glob) #ifdef PHP_GLOB_NOMATCH no_results: #endif - array_init(return_value); - return; + RETURN_EMPTY_ARRAY(); } array_init(return_value); @@ -549,19 +586,27 @@ PHP_FUNCTION(scandir) n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort); } else if (flags == PHP_SCANDIR_SORT_NONE) { n = php_stream_scandir(dirn, &namelist, context, NULL); - } else { + } else if (flags == PHP_SCANDIR_SORT_DESCENDING) { n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr); - } + } else { + zend_argument_value_error(2, "must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants"); + RETURN_THROWS(); + } + if (n < 0) { php_error_docref(NULL, E_WARNING, "(errno %d): %s", errno, strerror(errno)); RETURN_FALSE; } - array_init(return_value); + array_init_size(return_value, n); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); - for (i = 0; i < n; i++) { - add_next_index_str(return_value, namelist[i]); - } + ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { + for (i = 0; i < n; i++) { + ZEND_HASH_FILL_SET_STR(namelist[i]); + ZEND_HASH_FILL_NEXT(); + } + } ZEND_HASH_FILL_END(); if (n) { efree(namelist); diff --git a/ext/standard/dir_arginfo.h b/ext/standard/dir_arginfo.h index 703088d1eb0d..7ff39528d526 100644 --- a/ext/standard/dir_arginfo.h +++ b/ext/standard/dir_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit dir.stub.php instead. * Stub hash: e21d382cd4001001874c49d8c5244efb57613910 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Directory_close, 0, 0, IS_VOID, 0) @@ -66,9 +66,9 @@ static zend_class_entry *register_class_Directory(void) zval property_handle_default_value; ZVAL_UNDEF(&property_handle_default_value); - zend_string *property_handle_name = zend_string_init("handle", sizeof("handle") - 1, 1); + zend_string *property_handle_name = zend_string_init("handle", sizeof("handle") - 1, true); zend_declare_typed_property(class_entry, property_handle_name, &property_handle_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); - zend_string_release(property_handle_name); + zend_string_release_ex(property_handle_name, true); return class_entry; } diff --git a/ext/standard/dl.c b/ext/standard/dl.c index 31adbceac8c2..a6d0ced6fa86 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brian Schaffner | | Shane Caraveo | @@ -93,7 +91,7 @@ PHPAPI void *php_load_shlib(const char *path, char **errp) size_t i = strlen(err); (*errp)=estrdup(err); php_win32_error_msg_free(err); - while (i > 0 && isspace((*errp)[i-1])) { (*errp)[i-1] = '\0'; i--; } + while (i > 0 && isspace((unsigned char)(*errp)[i-1])) { (*errp)[i-1] = '\0'; i--; } } else { (*errp) = estrdup(""); } @@ -114,11 +112,11 @@ PHPAPI int php_load_extension(const char *filename, int type, int start_now) zend_module_entry *module_entry; zend_module_entry *(*get_module)(void); int error_type, slash_suffix = 0; - char *extension_dir; + const char *extension_dir; char *err1, *err2; if (type == MODULE_PERSISTENT) { - extension_dir = INI_STR("extension_dir"); + extension_dir = zend_ini_string_literal("extension_dir"); } else { extension_dir = PG(extension_dir); } diff --git a/ext/standard/dl.h b/ext/standard/dl.h index 58de973bf4b5..9354caa2ca8d 100644 --- a/ext/standard/dl.h +++ b/ext/standard/dl.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Brian Schaffner | | Shane Caraveo | diff --git a/ext/standard/dl_arginfo.h b/ext/standard/dl_arginfo.h index 5a0780d28c1c..d982c3aa4cdf 100644 --- a/ext/standard/dl_arginfo.h +++ b/ext/standard/dl_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit dl.stub.php instead. * Stub hash: 7dac6edd98e3e17669ae4bf0be7db89678059ca0 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl, 0, 1, _IS_BOOL, 0) diff --git a/ext/standard/dns.c b/ext/standard/dns.c index bd5720210fda..b3fcc1d236af 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: The typical suspects | | Pollita | @@ -382,7 +380,7 @@ PHP_FUNCTION(dns_check_record) #endif ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(hostname, hostname_len) + Z_PARAM_PATH(hostname, hostname_len) Z_PARAM_OPTIONAL Z_PARAM_STR(rectype) ZEND_PARSE_PARAMETERS_END(); @@ -829,7 +827,7 @@ PHP_FUNCTION(dns_get_record) bool raw = 0; ZEND_PARSE_PARAMETERS_START(1, 5) - Z_PARAM_STRING(hostname, hostname_len) + Z_PARAM_PATH(hostname, hostname_len) Z_PARAM_OPTIONAL Z_PARAM_LONG(type_param) Z_PARAM_ZVAL(authns) @@ -1067,7 +1065,7 @@ PHP_FUNCTION(dns_get_mx) #endif ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_STRING(hostname, hostname_len) + Z_PARAM_PATH(hostname, hostname_len) Z_PARAM_ZVAL(mx_list) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(weight_list) diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index 26c6487902e1..c9ff67e47b1e 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Pierre A. Joye | +----------------------------------------------------------------------+ @@ -32,7 +30,7 @@ PHP_FUNCTION(dns_get_mx) /* {{{ */ DNS_STATUS status; /* Return value of DnsQuery_A() function */ PDNS_RECORD pResult, pRec; /* Pointer to DNS_RECORD structure */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "pz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) { RETURN_THROWS(); } @@ -86,7 +84,7 @@ PHP_FUNCTION(dns_check_record) DNS_STATUS status; /* Return value of DnsQuery_A() function */ PDNS_RECORD pResult; /* Pointer to DNS_RECORD structure */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|S", &hostname, &hostname_len, &rectype) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|S", &hostname, &hostname_len, &rectype) == FAILURE) { RETURN_THROWS(); } @@ -116,11 +114,7 @@ PHP_FUNCTION(dns_check_record) status = DnsQuery_A(hostname, type, DNS_QUERY_STANDARD, NULL, &pResult, NULL); - if (status) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(!status); } /* }}} */ @@ -341,9 +335,9 @@ PHP_FUNCTION(dns_get_record) zend_long type_param = PHP_DNS_ANY; zval *authns = NULL, *addtl = NULL; int type, type_to_fetch, first_query = 1, store_results = 1; - bool raw = 0; + bool raw = false; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz!z!b", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|lz!z!b", &hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) { RETURN_THROWS(); } diff --git a/ext/standard/exec.c b/ext/standard/exec.c index ce3e8565ad20..5c9e5c6076a8 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | | Ilia Alshanetsky | @@ -81,7 +79,7 @@ PHP_MINIT_FUNCTION(exec) static size_t strip_trailing_whitespace(char *buf, size_t bufl) { size_t l = bufl; - while (l-- > 0 && isspace(((unsigned char *)buf)[l])); + while (l-- > 0 && isspace((unsigned char)buf[l])); if (l != (bufl - 1)) { bufl = l + 1; buf[bufl] = '\0'; @@ -199,13 +197,12 @@ PHPAPI int php_exec(int type, const char *cmd, zval *array, zval *return_value) static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ { - char *cmd; - size_t cmd_len; + zend_string *cmd; zval *ret_code=NULL, *ret_array=NULL; int ret; ZEND_PARSE_PARAMETERS_START(1, (mode ? 2 : 3)) - Z_PARAM_STRING(cmd, cmd_len) + Z_PARAM_PATH_STR(cmd) Z_PARAM_OPTIONAL if (!mode) { Z_PARAM_ZVAL(ret_array) @@ -213,17 +210,13 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ Z_PARAM_ZVAL(ret_code) ZEND_PARSE_PARAMETERS_END(); - if (!cmd_len) { + if (UNEXPECTED(!ZSTR_LEN(cmd))) { zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } - if (strlen(cmd) != cmd_len) { - zend_argument_value_error(1, "must not contain any null bytes"); - RETURN_THROWS(); - } if (!ret_array) { - ret = php_exec(mode, cmd, NULL, return_value); + ret = php_exec(mode, ZSTR_VAL(cmd), NULL, return_value); } else { if (Z_TYPE_P(Z_REFVAL_P(ret_array)) == IS_ARRAY) { ZVAL_DEREF(ret_array); @@ -235,7 +228,7 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ } } - ret = php_exec(2, cmd, ret_array, return_value); + ret = php_exec(2, ZSTR_VAL(cmd), ret_array, return_value); } if (ret_code) { ZEND_TRY_ASSIGN_REF_LONG(ret_code, ret); @@ -277,10 +270,10 @@ PHPAPI zend_string *php_escape_shell_cmd(const zend_string *unescaped_cmd) size_t x, y; zend_string *cmd; #ifndef PHP_WIN32 - char *p = NULL; + const char *p = NULL; #endif - ZEND_ASSERT(ZSTR_LEN(unescaped_cmd) == strlen(ZSTR_VAL(unescaped_cmd)) && "Must be a binary safe string"); + ZEND_ASSERT(!zend_str_has_nul_byte(unescaped_cmd) && "Must be a binary safe string"); size_t l = ZSTR_LEN(unescaped_cmd); const char *str = ZSTR_VAL(unescaped_cmd); @@ -387,7 +380,7 @@ PHPAPI zend_string *php_escape_shell_arg(const zend_string *unescaped_arg) size_t x, y = 0; zend_string *cmd; - ZEND_ASSERT(ZSTR_LEN(unescaped_arg) == strlen(ZSTR_VAL(unescaped_arg)) && "Must be a binary safe string"); + ZEND_ASSERT(!zend_str_has_nul_byte(unescaped_arg) && "Must be a binary safe string"); size_t l = ZSTR_LEN(unescaped_arg); const char *str = ZSTR_VAL(unescaped_arg); diff --git a/ext/standard/exec.h b/ext/standard/exec.h index 1ad755363e3d..879334285020 100644 --- a/ext/standard/exec.h +++ b/ext/standard/exec.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/file.c b/ext/standard/file.c index 4e136bedf5fa..ba5b26f6d222 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Bakken | @@ -98,6 +96,7 @@ php_file_globals file_globals; # include #endif +#include "zend_attributes.h" #include "file_arginfo.h" /* }}} */ @@ -662,11 +661,10 @@ PHP_FUNCTION(file) p = e; goto parse_eol; } - } - if (target_buf) { - zend_string_free(target_buf); + zend_string_efree(target_buf); } + php_stream_close(stream); } /* }}} */ @@ -960,7 +958,8 @@ PHP_FUNCTION(fscanf) efree(buf); if (SCAN_ERROR_WRONG_PARAM_COUNT == result) { - WRONG_PARAM_COUNT; + zend_wrong_param_count(); + RETURN_THROWS(); } } /* }}} */ @@ -1015,10 +1014,8 @@ PHPAPI PHP_FUNCTION(fflush) ZEND_PARSE_PARAMETERS_END(); ret = php_stream_flush(stream); - if (ret) { - RETURN_FALSE; - } - RETURN_TRUE; + + RETURN_BOOL(!ret); } /* }}} */ @@ -1031,10 +1028,7 @@ PHPAPI PHP_FUNCTION(rewind) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - if (-1 == php_stream_rewind(stream)) { - RETURN_FALSE; - } - RETURN_TRUE; + RETURN_BOOL(-1 != php_stream_rewind(stream)); } /* }}} */ @@ -1454,7 +1448,6 @@ PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_ case -1: /* non-statable stream */ goto safe_to_copy; - break; case 0: break; default: /* failed to stat file, does not exist? */ @@ -1469,7 +1462,6 @@ PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_ case -1: /* non-statable stream */ goto safe_to_copy; - break; case 0: break; default: /* failed to stat file, does not exist? */ @@ -1553,7 +1545,6 @@ PHPAPI PHP_FUNCTION(fread) str = php_stream_read_to_str(stream, len); if (!str) { - zval_ptr_dtor_str(return_value); RETURN_FALSE; } @@ -1869,7 +1860,7 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); if (inc_len == 1) { char *tmp = bptr; - while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) { + while ((*tmp != delimiter) && isspace((unsigned char)*tmp)) { tmp++; } if (*tmp == enclosure && tmp < limit) { @@ -2153,18 +2144,14 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data *md) switch (ch) { case '<': return TOK_OPENTAG; - break; case '>': return TOK_CLOSETAG; - break; case '=': return TOK_EQUAL; - break; case '/': return TOK_SLASH; - break; case '\'': case '"': @@ -2191,7 +2178,6 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data *md) } return TOK_STRING; - break; case '\n': case '\r': @@ -2200,7 +2186,6 @@ php_meta_tags_token php_next_meta_token(php_meta_tags_data *md) case ' ': return TOK_SPACE; - break; default: if (isalnum(ch)) { diff --git a/ext/standard/file.h b/ext/standard/file.h index f8faebd02829..3c6160fd4bb1 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/file.stub.php b/ext/standard/file.stub.php index 591169a37e00..5e12c43f397c 100644 --- a/ext/standard/file.stub.php +++ b/ext/standard/file.stub.php @@ -444,15 +444,10 @@ */ const FILE_NO_DEFAULT_CONTEXT = UNKNOWN; -/** - * @var int - * @deprecated - */ +#[\Deprecated(since: '8.1', message: 'as the constant has no effect')] const FILE_TEXT = 0; -/** - * @var int - * @deprecated - */ + +#[\Deprecated(since: '8.1', message: 'as the constant has no effect')] const FILE_BINARY = 0; #ifdef HAVE_FNMATCH diff --git a/ext/standard/file_arginfo.h b/ext/standard/file_arginfo.h index 7dc8fcf80aab..b3888925ee9a 100644 --- a/ext/standard/file_arginfo.h +++ b/ext/standard/file_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: e9a566d5ef96f781074027b1b3ff1824d0208b47 */ +/* This is a generated file, edit file.stub.php instead. + * Stub hash: c394e14cd32587ce9ad0503e21c6c4cf5b301697 */ static void register_file_symbols(int module_number) { @@ -108,8 +108,8 @@ static void register_file_symbols(int module_number) REGISTER_LONG_CONSTANT("FILE_SKIP_EMPTY_LINES", PHP_FILE_SKIP_EMPTY_LINES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILE_APPEND", PHP_FILE_APPEND, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILE_NO_DEFAULT_CONTEXT", PHP_FILE_NO_DEFAULT_CONTEXT, CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("FILE_TEXT", 0, CONST_PERSISTENT | CONST_DEPRECATED); - REGISTER_LONG_CONSTANT("FILE_BINARY", 0, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_FILE_TEXT = REGISTER_LONG_CONSTANT("FILE_TEXT", 0, CONST_PERSISTENT | CONST_DEPRECATED); + zend_constant *const_FILE_BINARY = REGISTER_LONG_CONSTANT("FILE_BINARY", 0, CONST_PERSISTENT | CONST_DEPRECATED); #if defined(HAVE_FNMATCH) REGISTER_LONG_CONSTANT("FNM_NOESCAPE", FNM_NOESCAPE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FNM_PATHNAME", FNM_PATHNAME, CONST_PERSISTENT); @@ -118,4 +118,18 @@ static void register_file_symbols(int module_number) #if defined(HAVE_FNMATCH) && defined(FNM_CASEFOLD) REGISTER_LONG_CONSTANT("FNM_CASEFOLD", FNM_CASEFOLD, CONST_PERSISTENT); #endif + + + zend_attribute *attribute_Deprecated_const_FILE_TEXT_0 = zend_add_global_constant_attribute(const_FILE_TEXT, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_FILE_TEXT_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_FILE_TEXT_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + zend_string *attribute_Deprecated_const_FILE_TEXT_0_arg1_str = zend_string_init("as the constant has no effect", strlen("as the constant has no effect"), 1); + ZVAL_STR(&attribute_Deprecated_const_FILE_TEXT_0->args[1].value, attribute_Deprecated_const_FILE_TEXT_0_arg1_str); + attribute_Deprecated_const_FILE_TEXT_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); + + zend_attribute *attribute_Deprecated_const_FILE_BINARY_0 = zend_add_global_constant_attribute(const_FILE_BINARY, ZSTR_KNOWN(ZEND_STR_DEPRECATED_CAPITALIZED), 2); + ZVAL_STR(&attribute_Deprecated_const_FILE_BINARY_0->args[0].value, ZSTR_KNOWN(ZEND_STR_8_DOT_1)); + attribute_Deprecated_const_FILE_BINARY_0->args[0].name = ZSTR_KNOWN(ZEND_STR_SINCE); + ZVAL_STR_COPY(&attribute_Deprecated_const_FILE_BINARY_0->args[1].value, attribute_Deprecated_const_FILE_TEXT_0_arg1_str); + attribute_Deprecated_const_FILE_BINARY_0->args[1].name = ZSTR_KNOWN(ZEND_STR_MESSAGE); } diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 7cb54aa0aca4..e41f6d1abb61 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ @@ -749,7 +747,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) php_stream_wrapper *wrapper = NULL; if (IS_ACCESS_CHECK(type)) { - if (!ZSTR_LEN(filename) || CHECK_NULL_PATH(ZSTR_VAL(filename), ZSTR_LEN(filename))) { + if (!ZSTR_LEN(filename) || zend_str_has_nul_byte(filename)) { if (ZSTR_LEN(filename) && !IS_EXISTS_CHECK(type)) { php_error_docref(NULL, E_WARNING, "Filename contains null byte"); } @@ -774,22 +772,18 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) #ifdef F_OK case FS_EXISTS: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, F_OK) == 0); - break; #endif #ifdef W_OK case FS_IS_W: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, W_OK) == 0); - break; #endif #ifdef R_OK case FS_IS_R: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, R_OK) == 0); - break; #endif #ifdef X_OK case FS_IS_X: RETURN_BOOL(VCWD_ACCESS(file_path_to_check, X_OK) == 0); - break; #endif } } @@ -821,7 +815,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) } if (!wrapper) { - if (!ZSTR_LEN(filename) || CHECK_NULL_PATH(ZSTR_VAL(filename), ZSTR_LEN(filename))) { + if (!ZSTR_LEN(filename) || zend_str_has_nul_byte(filename)) { if (ZSTR_LEN(filename) && !IS_EXISTS_CHECK(type)) { php_error_docref(NULL, E_WARNING, "Filename contains null byte"); } diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 3dcbc4bc320a..d26429704e26 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: | | Wez Furlong (wez@thebrainroom.com) | @@ -59,12 +57,14 @@ static php_stream_filter_status_t strfilter_rot13_filter( static const php_stream_filter_ops strfilter_rot13_ops = { strfilter_rot13_filter, NULL, + NULL, "string.rot13" }; -static php_stream_filter *strfilter_rot13_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_rot13_create(const char *filtername, zval *filterparams, bool persistent) { - return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent); + return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent, + PSFS_SEEKABLE_ALWAYS, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory strfilter_rot13_factory = { @@ -135,23 +135,27 @@ static php_stream_filter_status_t strfilter_tolower_filter( static const php_stream_filter_ops strfilter_toupper_ops = { strfilter_toupper_filter, NULL, + NULL, "string.toupper" }; static const php_stream_filter_ops strfilter_tolower_ops = { strfilter_tolower_filter, NULL, + NULL, "string.tolower" }; -static php_stream_filter *strfilter_toupper_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_toupper_create(const char *filtername, zval *filterparams, bool persistent) { - return php_stream_filter_alloc(&strfilter_toupper_ops, NULL, persistent); + return php_stream_filter_alloc(&strfilter_toupper_ops, NULL, persistent, + PSFS_SEEKABLE_ALWAYS, PSFS_SEEKABLE_ALWAYS); } -static php_stream_filter *strfilter_tolower_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_tolower_create(const char *filtername, zval *filterparams, bool persistent) { - return php_stream_filter_alloc(&strfilter_tolower_ops, NULL, persistent); + return php_stream_filter_alloc(&strfilter_tolower_ops, NULL, persistent, + PSFS_SEEKABLE_ALWAYS, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory strfilter_toupper_factory = { @@ -181,14 +185,17 @@ typedef struct _php_conv php_conv; typedef php_conv_err_t (*php_conv_convert_func)(php_conv *, const char **, size_t *, char **, size_t *); typedef void (*php_conv_dtor_func)(php_conv *); +typedef php_conv_err_t (*php_conv_reset_func)(php_conv *); struct _php_conv { php_conv_convert_func convert_op; php_conv_dtor_func dtor; + php_conv_reset_func reset_op; }; #define php_conv_convert(a, b, c, d, e) ((php_conv *)(a))->convert_op((php_conv *)(a), (b), (c), (d), (e)) #define php_conv_dtor(a) ((php_conv *)a)->dtor((a)) +#define php_conv_reset(a) (((php_conv *)(a))->reset_op ? ((php_conv *)(a))->reset_op((php_conv *)(a)) : PHP_CONV_ERR_SUCCESS) /* {{{ php_conv_base64_encode */ typedef struct _php_conv_base64_encode { @@ -206,6 +213,7 @@ typedef struct _php_conv_base64_encode { static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *inst, const char **in_p, size_t *in_left, char **out_p, size_t *out_left); static void php_conv_base64_encode_dtor(php_conv_base64_encode *inst); +static php_conv_err_t php_conv_base64_encode_reset(php_conv_base64_encode *inst); static const unsigned char b64_tbl_enc[256] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', @@ -226,10 +234,19 @@ static const unsigned char b64_tbl_enc[256] = { 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; +static php_conv_err_t php_conv_base64_encode_reset(php_conv_base64_encode *inst) +{ + /* Reset only mutable state, preserve configuration (lbchars, line_len, etc.) */ + inst->erem_len = 0; + inst->line_ccnt = inst->line_len; + return PHP_CONV_ERR_SUCCESS; +} + static php_conv_err_t php_conv_base64_encode_ctor(php_conv_base64_encode *inst, unsigned int line_len, const char *lbchars, size_t lbchars_len, int lbchars_dup, bool persistent) { inst->_super.convert_op = (php_conv_convert_func) php_conv_base64_encode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_base64_encode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_base64_encode_reset; inst->erem_len = 0; inst->line_ccnt = line_len; inst->line_len = line_len; @@ -449,6 +466,7 @@ typedef struct _php_conv_base64_decode { static php_conv_err_t php_conv_base64_decode_convert(php_conv_base64_decode *inst, const char **in_p, size_t *in_left, char **out_p, size_t *out_left); static void php_conv_base64_decode_dtor(php_conv_base64_decode *inst); +static php_conv_err_t php_conv_base64_decode_reset(php_conv_base64_decode *inst); static unsigned int b64_tbl_dec[256] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, @@ -469,10 +487,21 @@ static unsigned int b64_tbl_dec[256] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }; +static php_conv_err_t php_conv_base64_decode_reset(php_conv_base64_decode *inst) +{ + /* Reset only mutable state */ + inst->urem = 0; + inst->urem_nbits = 0; + inst->ustat = 0; + inst->eos = 0; + return PHP_CONV_ERR_SUCCESS; +} + static void php_conv_base64_decode_ctor(php_conv_base64_decode *inst) { inst->_super.convert_op = (php_conv_convert_func) php_conv_base64_decode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_base64_decode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_base64_decode_reset; inst->urem = 0; inst->urem_nbits = 0; @@ -618,6 +647,7 @@ typedef struct _php_conv_qprint_encode { static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst); static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p); +static php_conv_err_t php_conv_qprint_encode_reset(php_conv_qprint_encode *inst); static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst) { @@ -627,6 +657,15 @@ static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst) } } +static php_conv_err_t php_conv_qprint_encode_reset(php_conv_qprint_encode *inst) +{ + /* Reset only mutable state, preserve configuration */ + inst->line_ccnt = inst->line_len; + inst->lb_ptr = 0; + inst->lb_cnt = 0; + return PHP_CONV_ERR_SUCCESS; +} + #define NEXT_CHAR(ps, icnt, lb_ptr, lb_cnt, lbchars) \ ((lb_ptr) < (lb_cnt) ? (lbchars)[(lb_ptr)] : *(ps)) @@ -832,6 +871,7 @@ static php_conv_err_t php_conv_qprint_encode_ctor(php_conv_qprint_encode *inst, } inst->_super.convert_op = (php_conv_convert_func) php_conv_qprint_encode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_qprint_encode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_qprint_encode_reset; inst->line_ccnt = line_len; inst->line_len = line_len; if (lbchars != NULL) { @@ -862,6 +902,10 @@ typedef struct _php_conv_qprint_decode { unsigned int lb_cnt; } php_conv_qprint_decode; +static void php_conv_qprint_decode_dtor(php_conv_qprint_decode *inst); +static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p); +static php_conv_err_t php_conv_qprint_decode_reset(php_conv_qprint_decode *inst); + static void php_conv_qprint_decode_dtor(php_conv_qprint_decode *inst) { assert(inst != NULL); @@ -870,6 +914,16 @@ static void php_conv_qprint_decode_dtor(php_conv_qprint_decode *inst) } } +static php_conv_err_t php_conv_qprint_decode_reset(php_conv_qprint_decode *inst) +{ + /* Reset only mutable state, preserve configuration */ + inst->scan_stat = 0; + inst->next_char = 0; + inst->lb_ptr = 0; + inst->lb_cnt = 0; + return PHP_CONV_ERR_SUCCESS; +} + static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p) { php_conv_err_t err = PHP_CONV_ERR_SUCCESS; @@ -949,7 +1003,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins goto out; } - if (!isxdigit((int) *ps)) { + if (!isxdigit(*ps)) { err = PHP_CONV_ERR_INVALID_SEQ; goto out; } @@ -1040,10 +1094,12 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins return err; } + static php_conv_err_t php_conv_qprint_decode_ctor(php_conv_qprint_decode *inst, const char *lbchars, size_t lbchars_len, int lbchars_dup, bool persistent) { inst->_super.convert_op = (php_conv_convert_func) php_conv_qprint_decode_convert; inst->_super.dtor = (php_conv_dtor_func) php_conv_qprint_decode_dtor; + inst->_super.reset_op = (php_conv_reset_func) php_conv_qprint_decode_reset; inst->scan_stat = 0; inst->next_char = 0; inst->lb_ptr = inst->lb_cnt = 0; @@ -1540,6 +1596,29 @@ static php_stream_filter_status_t strfilter_convert_filter( return PSFS_ERR_FATAL; } +static zend_result strfilter_convert_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + php_convert_filter *inst = (php_convert_filter *)Z_PTR(thisfilter->abstract); + + /* Reset stub buffer */ + inst->stub_len = 0; + + /* Reset the converter state - preserves all configuration/options */ + if (inst->cd != NULL) { + php_conv_err_t err = php_conv_reset(inst->cd); + if (err != PHP_CONV_ERR_SUCCESS) { + return FAILURE; + } + } + + return SUCCESS; +} + static void strfilter_convert_dtor(php_stream_filter *thisfilter) { assert(Z_PTR(thisfilter->abstract) != NULL); @@ -1550,16 +1629,16 @@ static void strfilter_convert_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops strfilter_convert_ops = { strfilter_convert_filter, + strfilter_convert_seek, strfilter_convert_dtor, "convert.*" }; -static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, bool persistent) { php_convert_filter *inst; - php_stream_filter *retval = NULL; - - char *dot; + php_stream_filter_seekable_t write_seekable; + const char *dot; int conv_mode = 0; if (filterparams != NULL && Z_TYPE_P(filterparams) != IS_ARRAY) { @@ -1572,6 +1651,10 @@ static php_stream_filter *strfilter_convert_create(const char *filtername, zval } ++dot; + if (php_stream_filter_parse_write_seek_mode(filterparams, &write_seekable) == FAILURE) { + return NULL; + } + inst = pemalloc(sizeof(php_convert_filter), persistent); if (strcasecmp(dot, "base64-encode") == 0) { @@ -1587,16 +1670,11 @@ static php_stream_filter *strfilter_convert_create(const char *filtername, zval if (php_convert_filter_ctor(inst, conv_mode, (filterparams != NULL ? Z_ARRVAL_P(filterparams) : NULL), filtername, persistent) != SUCCESS) { - goto out; - } - - retval = php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent); -out: - if (retval == NULL) { pefree(inst, persistent); + return NULL; } - return retval; + return php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent, PSFS_SEEKABLE_START, write_seekable); } static const php_stream_filter_factory strfilter_convert_factory = { @@ -1643,6 +1721,22 @@ static php_stream_filter_status_t consumed_filter_filter( return PSFS_PASS_ON; } +static zend_result consumed_filter_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + php_consumed_filter_data *data = (php_consumed_filter_data *)Z_PTR(thisfilter->abstract); + + /* Reset consumed state */ + data->consumed = 0; + data->offset = ~0; + + return SUCCESS; +} + static void consumed_filter_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { @@ -1653,11 +1747,12 @@ static void consumed_filter_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops consumed_filter_ops = { consumed_filter_filter, + consumed_filter_seek, consumed_filter_dtor, "consumed" }; -static php_stream_filter *consumed_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *consumed_filter_create(const char *filtername, zval *filterparams, bool persistent) { const php_stream_filter_ops *fops = NULL; php_consumed_filter_data *data; @@ -1673,7 +1768,7 @@ static php_stream_filter *consumed_filter_create(const char *filtername, zval *f data->offset = ~0; fops = &consumed_filter_ops; - return php_stream_filter_alloc(fops, data, persistent); + return php_stream_filter_alloc(fops, data, persistent, PSFS_SEEKABLE_START, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory consumed_filter_factory = { @@ -1857,6 +1952,22 @@ static php_stream_filter_status_t php_chunked_filter( return PSFS_PASS_ON; } +static zend_result php_chunked_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + php_chunked_filter_data *data = (php_chunked_filter_data *)Z_PTR(thisfilter->abstract); + + /* Reset chunked decoder state */ + data->state = CHUNK_SIZE_START; + data->chunk_size = 0; + + return SUCCESS; +} + static void php_chunked_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { @@ -1867,11 +1978,12 @@ static void php_chunked_dtor(php_stream_filter *thisfilter) static const php_stream_filter_ops chunked_filter_ops = { php_chunked_filter, + php_chunked_seek, php_chunked_dtor, "dechunk" }; -static php_stream_filter *chunked_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) +static php_stream_filter *chunked_filter_create(const char *filtername, zval *filterparams, bool persistent) { const php_stream_filter_ops *fops = NULL; php_chunked_filter_data *data; @@ -1887,7 +1999,7 @@ static php_stream_filter *chunked_filter_create(const char *filtername, zval *fi data->persistent = persistent; fops = &chunked_filter_ops; - return php_stream_filter_alloc(fops, data, persistent); + return php_stream_filter_alloc(fops, data, persistent, PSFS_SEEKABLE_START, PSFS_SEEKABLE_ALWAYS); } static const php_stream_filter_factory chunked_filter_factory = { diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c index b7e1df7cbc98..6967c4358901 100644 --- a/ext/standard/flock_compat.c +++ b/ext/standard/flock_compat.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/flock_compat.h b/ext/standard/flock_compat.h index af0739bf1528..cfb6d82ba085 100644 --- a/ext/standard/flock_compat.h +++ b/ext/standard/flock_compat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 9a74ae6c877f..f35d196fb971 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -1,16 +1,14 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ - | Author: Stig S�ther Bakken | + | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ */ @@ -103,7 +101,7 @@ php_sprintf_appendstring(zend_string **buffer, size_t *pos, char *add, if (req_size > ZSTR_LEN(*buffer)) { size_t size = ZSTR_LEN(*buffer); while (req_size > size) { - if (size > ZEND_SIZE_MAX/2) { + if (size > SIZE_MAX/2) { zend_error_noreturn(E_ERROR, "Field width %zd is too long", req_size); } size <<= 1; @@ -298,9 +296,9 @@ php_sprintf_appenddouble(zend_string **buffer, size_t *pos, char exp_char = fmt == 'G' || fmt == 'H' ? 'E' : 'e'; /* We use &num_buf[ 1 ], so that we have room for the sign. */ s = zend_gcvt(number, precision, decimal_point, exp_char, &num_buf[1]); - is_negative = 0; + is_negative = false; if (*s == '-') { - is_negative = 1; + is_negative = true; s = &num_buf[1]; } else if (always_sign) { num_buf[0] = '+'; @@ -376,7 +374,7 @@ php_sprintf_getnumber(char **buffer, size_t *len) int php_sprintf_get_argnum(char **format, size_t *format_len) { char *temppos = *format; - while (isdigit((int) *temppos)) temppos++; + while (isdigit((unsigned char)*temppos)) temppos++; if (*temppos != '$') { return ARG_NUM_NEXT; } @@ -468,7 +466,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%zu\n", *format, format - format_orig)); - if (isalpha((int)*format)) { + if (isalpha((unsigned char)*format)) { width = precision = 0; argnum = ARG_NUM_NEXT; } else { @@ -537,7 +535,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n } width = Z_LVAL_P(tmp); adjusting |= ADJ_WIDTH; - } else if (isdigit((int)*format)) { + } else if (isdigit((unsigned char)*format)) { PRINTF_DEBUG(("sprintf: getting width\n")); if ((width = php_sprintf_getnumber(&format, &format_len)) < 0) { zend_value_error("Width must be between 0 and %d", INT_MAX); @@ -582,7 +580,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n precision = Z_LVAL_P(tmp); adjusting |= ADJ_PRECISION; expprec = 1; - } else if (isdigit((int)*format)) { + } else if (isdigit((unsigned char)*format)) { if ((precision = php_sprintf_getnumber(&format, &format_len)) < 0) { zend_value_error("Precision must be between 0 and %d", INT_MAX); goto fail; @@ -591,6 +589,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n expprec = 1; } else { precision = 0; + adjusting |= ADJ_PRECISION; } } else { precision = 0; diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index cb7a471e935a..0b27a13e624c 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Paul Panotzki - Bunyip Information Systems | | Jim Winstead | @@ -23,6 +21,28 @@ #include "php_network.h" #include "file.h" +static size_t php_fsockopen_format_host_port(char **message, const char *prefix, size_t prefix_len, + const char *host, size_t host_len, zend_long port) +{ + char portbuf[32]; + int portlen = snprintf(portbuf, sizeof(portbuf), ":" ZEND_LONG_FMT, port); + size_t total_len = prefix_len + host_len + portlen; + + char *result = emalloc(total_len + 1); + + if (prefix_len > 0) { + memcpy(result, prefix, prefix_len); + } + memcpy(result + prefix_len, host, host_len); + memcpy(result + prefix_len + host_len, portbuf, portlen); + + result[total_len] = '\0'; + + *message = result; + + return total_len; +} + /* {{{ php_fsockopen() */ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) @@ -62,11 +82,12 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) } if (persistent) { - spprintf(&hashkey, 0, "pfsockopen__%s:" ZEND_LONG_FMT, host, port); + php_fsockopen_format_host_port(&hashkey, "pfsockopen__", strlen("pfsockopen__"), host, + host_len, port); } if (port > 0) { - hostname_len = spprintf(&hostname, 0, "%s:" ZEND_LONG_FMT, host, port); + hostname_len = php_fsockopen_format_host_port(&hostname, "", 0, host, host_len, port); } else { hostname_len = host_len; hostname = host; diff --git a/ext/standard/fsock.h b/ext/standard/fsock.h index 3789a01b7ea0..849d5052238c 100644 --- a/ext/standard/fsock.h +++ b/ext/standard/fsock.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Paul Panotzki - Bunyip Information Systems | | Jim Winstead | diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 98715b2ee8a0..7f8702adbf84 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrew Sitnikov | +----------------------------------------------------------------------+ diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 51b7b311a954..e1f3a88d2497 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | @@ -21,6 +19,7 @@ #include "php_globals.h" #include "php_network.h" #include "php_ini.h" +#include "zend_exceptions.h" #include #include @@ -38,8 +37,8 @@ #endif #include "php_standard.h" +#include "ext/uri/php_uri.h" -#include #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -78,8 +77,8 @@ static inline int get_ftp_result(php_stream *stream, char *buffer, size_t buffer { buffer[0] = '\0'; /* in case read fails to read anything */ while (php_stream_gets(stream, buffer, buffer_size-1) && - !(isdigit((int) buffer[0]) && isdigit((int) buffer[1]) && - isdigit((int) buffer[2]) && buffer[3] == ' ')); + !(isdigit((unsigned char)buffer[0]) && isdigit((unsigned char)buffer[1]) && + isdigit((unsigned char)buffer[2]) && buffer[3] == ' ')); return strtol(buffer, NULL, 10); } /* }}} */ @@ -124,16 +123,22 @@ static int php_stream_ftp_stream_close(php_stream_wrapper *wrapper, php_stream * /* {{{ php_ftp_fopen_connect */ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context, php_stream **preuseid, - php_url **presource, int *puse_ssl, int *puse_ssl_on_data) + php_uri **presource, int *puse_ssl, int *puse_ssl_on_data) { php_stream *stream = NULL, *reuseid = NULL; - php_url *resource = NULL; + php_uri *resource = NULL; int result, use_ssl, use_ssl_on_data = 0; char tmp_line[512]; char *transport; int transport_len; - resource = php_url_parse(path); + const php_uri_parser *uri_parser = php_stream_context_get_uri_parser("ftp", context); + if (uri_parser == NULL) { + zend_value_error("%s(): Provided stream context has invalid value for the \"uri_parser_class\" option", get_active_function_name()); + return NULL; + } + + resource = php_uri_parse_to_struct(uri_parser, path, strlen(path), PHP_URI_COMPONENT_READ_MODE_RAW, true); if (resource == NULL || resource->path == NULL) { if (resource && presource) { *presource = resource; @@ -147,7 +152,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char if (resource->port == 0) resource->port = 21; - transport_len = (int)spprintf(&transport, 0, "tcp://%s:%d", ZSTR_VAL(resource->host), resource->port); + transport_len = (int)spprintf(&transport, 0, "tcp://%s:" ZEND_LONG_FMT, ZSTR_VAL(resource->host), resource->port); stream = php_stream_xport_create(transport, transport_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, context, NULL, NULL); efree(transport); if (stream == NULL) { @@ -228,7 +233,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char #define PHP_FTP_CNTRL_CHK(val, val_len, err_msg) { \ unsigned char *s = (unsigned char *) val, *e = (unsigned char *) s + val_len; \ while (s < e) { \ - if (iscntrl(*s)) { \ + if (iscntrl((unsigned char)*s)) { \ php_stream_wrapper_log_error(wrapper, options, err_msg, val); \ goto connect_errexit; \ } \ @@ -254,12 +259,12 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char if (result >= 300 && result <= 399) { php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, tmp_line, 0); - if (resource->pass != NULL) { - ZSTR_LEN(resource->pass) = php_raw_url_decode(ZSTR_VAL(resource->pass), ZSTR_LEN(resource->pass)); + if (resource->password != NULL) { + ZSTR_LEN(resource->password) = php_raw_url_decode(ZSTR_VAL(resource->password), ZSTR_LEN(resource->password)); - PHP_FTP_CNTRL_CHK(ZSTR_VAL(resource->pass), ZSTR_LEN(resource->pass), "Invalid password %s") + PHP_FTP_CNTRL_CHK(ZSTR_VAL(resource->password), ZSTR_LEN(resource->password), "Invalid password %s") - php_stream_printf(stream, "PASS %s\r\n", ZSTR_VAL(resource->pass)); + php_stream_printf(stream, "PASS %s\r\n", ZSTR_VAL(resource->password)); } else { /* if the user has configured who they are, send that as the password */ @@ -299,7 +304,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char return stream; connect_errexit: - php_url_free(resource); + php_uri_struct_free(resource); if (stream) { php_stream_close(stream); @@ -337,14 +342,14 @@ static unsigned short php_fopen_do_pasv(php_stream *stream, char *ip, size_t ip_ /* parse pasv command (129, 80, 95, 25, 13, 221) */ tpath = tmp_line; /* skip over the "227 Some message " part */ - for (tpath += 4; *tpath && !isdigit((int) *tpath); tpath++); + for (tpath += 4; *tpath && !isdigit((unsigned char)*tpath); tpath++); if (!*tpath) { return 0; } /* skip over the host ip, to get the port */ hoststart = tpath; for (i = 0; i < 4; i++) { - for (; isdigit((int) *tpath); tpath++); + for (; isdigit((unsigned char)*tpath); tpath++); if (*tpath != ',') { return 0; } @@ -404,7 +409,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) { php_stream *stream = NULL, *datastream = NULL; - php_url *resource = NULL; + php_uri *resource = NULL; char tmp_line[512]; char ip[sizeof("123.123.123.123")]; unsigned short portno; @@ -413,7 +418,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa php_stream *reuseid=NULL; size_t file_size = 0; zval *tmpzval; - bool allow_overwrite = 0; + bool allow_overwrite = false; int8_t read_write = 0; char *transport; int transport_len; @@ -579,12 +584,12 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa /* remember control stream */ datastream->wrapperthis = stream; - php_url_free(resource); + php_uri_struct_free(resource); return datastream; errexit: if (resource) { - php_url_free(resource); + php_uri_struct_free(resource); } if (stream) { php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, result); @@ -683,7 +688,7 @@ static php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const ch { php_stream *stream, *reuseid, *datastream = NULL; php_ftp_dirstream_data *dirsdata; - php_url *resource = NULL; + php_uri *resource = NULL; int result = 0, use_ssl, use_ssl_on_data = 0; char *hoststart = NULL, tmp_line[512]; char ip[sizeof("123.123.123.123")]; @@ -745,7 +750,7 @@ static php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const ch goto opendir_errexit; } - php_url_free(resource); + php_uri_struct_free(resource); dirsdata = emalloc(sizeof *dirsdata); dirsdata->datastream = datastream; @@ -756,7 +761,7 @@ static php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const ch opendir_errexit: if (resource) { - php_url_free(resource); + php_uri_struct_free(resource); } if (stream) { php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, result); @@ -773,7 +778,7 @@ static php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const ch static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context) { php_stream *stream = NULL; - php_url *resource = NULL; + php_uri *resource = NULL; int result; char tmp_line[512]; @@ -825,7 +830,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, struct tm tm, tmbuf, *gmt; time_t stamp; - while ((size_t)(p - tmp_line) < sizeof(tmp_line) && !isdigit(*p)) { + while ((size_t)(p - tmp_line) < sizeof(tmp_line) && !isdigit((unsigned char)*p)) { p++; } @@ -877,12 +882,12 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, #endif #endif php_stream_close(stream); - php_url_free(resource); + php_uri_struct_free(resource); return 0; stat_errexit: if (resource) { - php_url_free(resource); + php_uri_struct_free(resource); } if (stream) { php_stream_close(stream); @@ -895,7 +900,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) { php_stream *stream = NULL; - php_url *resource = NULL; + php_uri *resource = NULL; int result; char tmp_line[512]; @@ -925,13 +930,13 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, i goto unlink_errexit; } - php_url_free(resource); + php_uri_struct_free(resource); php_stream_close(stream); return 1; unlink_errexit: if (resource) { - php_url_free(resource); + php_uri_struct_free(resource); } if (stream) { php_stream_close(stream); @@ -944,18 +949,30 @@ static int php_stream_ftp_unlink(php_stream_wrapper *wrapper, const char *url, i static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context) { php_stream *stream = NULL; - php_url *resource_from = NULL, *resource_to = NULL; + php_uri *resource_from = NULL, *resource_to = NULL; int result; char tmp_line[512]; - resource_from = php_url_parse(url_from); - resource_to = php_url_parse(url_to); + const php_uri_parser *uri_parser = php_stream_context_get_uri_parser("ftp", context); + if (uri_parser == NULL) { + zend_value_error("%s(): Provided stream context has invalid value for the \"uri_parser_class\" option", get_active_function_name()); + return 0; + } + + resource_from = php_uri_parse_to_struct(uri_parser, url_from, strlen(url_from), PHP_URI_COMPONENT_READ_MODE_RAW, true); + if (!resource_from) { + return 0; + } + + resource_to = php_uri_parse_to_struct(uri_parser, url_to, strlen(url_to), PHP_URI_COMPONENT_READ_MODE_RAW, true); + if (!resource_to) { + goto rename_errexit; + } + /* Must be same scheme (ftp/ftp or ftps/ftps), same host, and same port (or a 21/0 0/21 combination which is also "same") Also require paths to/from */ - if (!resource_from || - !resource_to || - !resource_from->scheme || + if (!resource_from->scheme || !resource_to->scheme || !zend_string_equals(resource_from->scheme, resource_to->scheme) || !resource_from->host || @@ -999,17 +1016,15 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr goto rename_errexit; } - php_url_free(resource_from); - php_url_free(resource_to); + php_uri_struct_free(resource_from); + php_uri_struct_free(resource_to); php_stream_close(stream); return 1; rename_errexit: - if (resource_from) { - php_url_free(resource_from); - } + php_uri_struct_free(resource_from); if (resource_to) { - php_url_free(resource_to); + php_uri_struct_free(resource_to); } if (stream) { php_stream_close(stream); @@ -1022,7 +1037,7 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context) { php_stream *stream = NULL; - php_url *resource = NULL; + php_uri *resource = NULL; int result, recursive = options & PHP_STREAM_MKDIR_RECURSIVE; char tmp_line[512]; @@ -1089,7 +1104,7 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in efree(buf); } - php_url_free(resource); + php_uri_struct_free(resource); php_stream_close(stream); if (result < 200 || result > 299) { @@ -1101,7 +1116,7 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in mkdir_errexit: if (resource) { - php_url_free(resource); + php_uri_struct_free(resource); } if (stream) { php_stream_close(stream); @@ -1114,7 +1129,7 @@ static int php_stream_ftp_mkdir(php_stream_wrapper *wrapper, const char *url, in static int php_stream_ftp_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) { php_stream *stream = NULL; - php_url *resource = NULL; + php_uri *resource = NULL; int result; char tmp_line[512]; @@ -1143,14 +1158,14 @@ static int php_stream_ftp_rmdir(php_stream_wrapper *wrapper, const char *url, in goto rmdir_errexit; } - php_url_free(resource); + php_uri_struct_free(resource); php_stream_close(stream); return 1; rmdir_errexit: if (resource) { - php_url_free(resource); + php_uri_struct_free(resource); } if (stream) { php_stream_close(stream); diff --git a/ext/standard/head.c b/ext/standard/head.c index ccef4be16bdf..03f2e6189ee5 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -76,10 +74,17 @@ PHPAPI bool php_header(void) } } +PHPAPI bool php_is_valid_samesite_value(zend_string *value) +{ + return zend_string_equals_literal_ci(value, "Strict") + || zend_string_equals_literal_ci(value, "Lax") + || zend_string_equals_literal_ci(value, "None"); +} + #define ILLEGAL_COOKIE_CHARACTER "\",\", \";\", \" \", \"\\t\", \"\\r\", \"\\n\", \"\\013\", or \"\\014\"" PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t expires, zend_string *path, zend_string *domain, bool secure, bool httponly, - zend_string *samesite, bool url_encode) + zend_string *samesite, bool partitioned, bool url_encode) { zend_string *dt; sapi_header_line ctr = {0}; @@ -117,8 +122,17 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e return FAILURE; } #endif + if (partitioned && !secure) { + zend_value_error("%s(): \"partitioned\" option cannot be used without \"secure\" option", + get_active_function_name()); + return FAILURE; + } - /* Should check value of SameSite? */ + if (samesite && ZSTR_LEN(samesite) > 0 && !php_is_valid_samesite_value(samesite)) { + zend_value_error("%s(): \"samesite\" option must be \"Strict\", \"Lax\", \"None\", or \"\"", + get_active_function_name()); + return FAILURE; + } if (value == NULL || ZSTR_LEN(value) == 0) { /* @@ -126,13 +140,9 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date in the past */ - dt = php_format_date("D, d M Y H:i:s \\G\\M\\T", sizeof("D, d M Y H:i:s \\G\\M\\T")-1, 1, 0); smart_str_appends(&buf, "Set-Cookie: "); smart_str_append(&buf, name); - smart_str_appends(&buf, "=deleted; expires="); - smart_str_append(&buf, dt); - smart_str_appends(&buf, "; Max-Age=0"); - zend_string_free(dt); + smart_str_appends(&buf, "=deleted; expires=Thu, 01 Jan 1970 00:00:01 GMT; Max-Age=0"); } else { smart_str_appends(&buf, "Set-Cookie: "); smart_str_append(&buf, name); @@ -182,6 +192,9 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e smart_str_appends(&buf, COOKIE_SAMESITE); smart_str_append(&buf, samesite); } + if (partitioned) { + smart_str_appends(&buf, COOKIE_PARTITIONED); + } ctr.line = ZSTR_VAL(buf.s); ctr.line_len = (uint32_t) ZSTR_LEN(buf.s); @@ -192,7 +205,7 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e } static zend_result php_head_parse_cookie_options_array(HashTable *options, zend_long *expires, zend_string **path, - zend_string **domain, bool *secure, bool *httponly, zend_string **samesite) + zend_string **domain, bool *secure, bool *httponly, zend_string **samesite, bool *partitioned) { zend_string *key; zval *value; @@ -209,11 +222,13 @@ static zend_result php_head_parse_cookie_options_array(HashTable *options, zend_ } else if (zend_string_equals_literal_ci(key, "domain")) { *domain = zval_get_string(value); } else if (zend_string_equals_literal_ci(key, "secure")) { - *secure = zval_is_true(value); + *secure = zend_is_true(value); } else if (zend_string_equals_literal_ci(key, "httponly")) { - *httponly = zval_is_true(value); + *httponly = zend_is_true(value); } else if (zend_string_equals_literal_ci(key, "samesite")) { *samesite = zval_get_string(value); + } else if (zend_string_equals_literal_ci(key, "partitioned")) { + *partitioned = zend_is_true(value); } else { zend_value_error("%s(): option \"%s\" is invalid", get_active_function_name(), ZSTR_VAL(key)); return FAILURE; @@ -227,7 +242,7 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw) HashTable *options = NULL; zend_long expires = 0; zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL; - bool secure = 0, httponly = 0; + bool secure = 0, httponly = 0, partitioned = false; ZEND_PARSE_PARAMETERS_START(1, 7) Z_PARAM_STR(name) @@ -248,17 +263,13 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw) } if (FAILURE == php_head_parse_cookie_options_array(options, &expires, &path, - &domain, &secure, &httponly, &samesite) + &domain, &secure, &httponly, &samesite, &partitioned) ) { goto cleanup; } } - if (php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, !is_raw) == SUCCESS) { - RETVAL_TRUE; - } else { - RETVAL_FALSE; - } + RETVAL_BOOL(php_setcookie(name, value, expires, path, domain, secure, httponly, samesite, partitioned, !is_raw) == SUCCESS); if (options) { cleanup: @@ -322,11 +333,7 @@ PHP_FUNCTION(headers_sent) break; } - if (SG(headers_sent)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(SG(headers_sent)); } /* }}} */ @@ -375,6 +382,14 @@ PHP_FUNCTION(http_response_code) } RETURN_FALSE; } + + if (SG(sapi_headers).http_status_line) { + php_error_docref(NULL, E_WARNING, "Calling http_response_code() after header('HTTP/...') has no effect"); + // If it is decided that this should have effect in the future, replace warning with + // efree(SG(sapi_headers).http_status_line); + // SG(sapi_headers).http_status_line = NULL; + } + zend_long old_response_code; old_response_code = SG(sapi_headers).http_response_code; diff --git a/ext/standard/head.h b/ext/standard/head.h index 32c2570a5325..8b91371a46e2 100644 --- a/ext/standard/head.h +++ b/ext/standard/head.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -17,19 +15,22 @@ #ifndef HEAD_H #define HEAD_H -#define COOKIE_EXPIRES "; expires=" -#define COOKIE_MAX_AGE "; Max-Age=" -#define COOKIE_DOMAIN "; domain=" -#define COOKIE_PATH "; path=" -#define COOKIE_SECURE "; secure" -#define COOKIE_HTTPONLY "; HttpOnly" -#define COOKIE_SAMESITE "; SameSite=" +#define COOKIE_EXPIRES "; expires=" +#define COOKIE_MAX_AGE "; Max-Age=" +#define COOKIE_DOMAIN "; domain=" +#define COOKIE_PATH "; path=" +#define COOKIE_SECURE "; secure" +#define COOKIE_HTTPONLY "; HttpOnly" +#define COOKIE_SAMESITE "; SameSite=" +#define COOKIE_PARTITIONED "; Partitioned" + +PHPAPI bool php_is_valid_samesite_value(zend_string *value); extern PHP_RINIT_FUNCTION(head); PHPAPI bool php_header(void); PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t expires, zend_string *path, zend_string *domain, bool secure, bool httponly, - zend_string *samesite, bool url_encode); + zend_string *samesite, bool partitioned, bool url_encode); #endif diff --git a/ext/standard/hrtime.c b/ext/standard/hrtime.c index f8d5e3179136..216810b7df1b 100644 --- a/ext/standard/hrtime.c +++ b/ext/standard/hrtime.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Niklas Keller | | Author: Anatol Belski | @@ -31,9 +29,9 @@ } while (0) #endif #define PHP_RETURN_HRTIME(t) do { \ - char _a[ZEND_LTOA_BUF_LEN]; \ + char _a[65]; \ double _d; \ - HRTIME_U64A(t, _a, ZEND_LTOA_BUF_LEN); \ + HRTIME_U64A(t, _a, sizeof(_a)); \ _d = zend_strtod(_a, NULL); \ RETURN_DOUBLE(_d); \ } while (0) @@ -46,7 +44,6 @@ delivered timestamp is monotonic and cannot be adjusted. */ PHP_FUNCTION(hrtime) { -#if ZEND_HRTIME_AVAILABLE bool get_as_num = 0; zend_hrtime_t t = zend_hrtime(); @@ -55,6 +52,7 @@ PHP_FUNCTION(hrtime) Z_PARAM_BOOL(get_as_num) ZEND_PARSE_PARAMETERS_END(); +#if ZEND_HRTIME_AVAILABLE if (UNEXPECTED(get_as_num)) { PHP_RETURN_HRTIME(t); } else { diff --git a/ext/standard/html.c b/ext/standard/html.c index 0c6231d590d8..1e761c971eda 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jaakko Hyvätti | @@ -678,8 +676,8 @@ static inline zend_result process_numeric_entity(const char **buf, unsigned *cod /* strtol allows whitespace and other stuff in the beginning * we're not interested */ - if ((hexadecimal && !isxdigit(**buf)) || - (!hexadecimal && !isdigit(**buf))) { + if ((hexadecimal && !isxdigit((unsigned char)**buf)) || + (!hexadecimal && !isdigit((unsigned char)**buf))) { return FAILURE; } @@ -809,112 +807,148 @@ static inline size_t write_octet_sequence(unsigned char *buf, enum entity_charse /* +2 is 1 because of rest (probably unnecessary), 1 because of terminating 0 */ #define TRAVERSE_FOR_ENTITIES_EXPAND_SIZE(oldlen) ((oldlen) + (oldlen) / 5 + 2) static void traverse_for_entities( - const char *old, - size_t oldlen, - zend_string *ret, /* should have allocated TRAVERSE_FOR_ENTITIES_EXPAND_SIZE(olden) */ - int all, - int flags, + const zend_string *input, + zend_string *output, /* should have allocated TRAVERSE_FOR_ENTITIES_EXPAND_SIZE(olden) */ + const int all, + const int flags, const entity_ht *inv_map, - enum entity_charset charset) + const enum entity_charset charset) { - const char *p, - *lim; - char *q; - int doctype = flags & ENT_HTML_DOC_TYPE_MASK; - - lim = old + oldlen; /* terminator address */ - assert(*lim == '\0'); - - for (p = old, q = ZSTR_VAL(ret); p < lim;) { - unsigned code, code2 = 0; - const char *next = NULL; /* when set, next > p, otherwise possible inf loop */ - - /* Shift JIS, Big5 and HKSCS use multi-byte encodings where an - * ASCII range byte can be part of a multi-byte sequence. - * However, they start at 0x40, therefore if we find a 0x26 byte, - * we're sure it represents the '&' character. */ + const char *current_ptr = ZSTR_VAL(input); + const char *input_end = current_ptr + ZSTR_LEN(input); /* terminator address */ + char *output_ptr = ZSTR_VAL(output); + const int doctype = flags & ENT_HTML_DOC_TYPE_MASK; + + while (current_ptr < input_end) { + const char *ampersand_ptr = memchr(current_ptr, '&', input_end - current_ptr); + if (!ampersand_ptr) { + const size_t tail_len = input_end - current_ptr; + if (tail_len > 0) { + memcpy(output_ptr, current_ptr, tail_len); + output_ptr += tail_len; + } + break; + } - /* assumes there are no single-char entities */ - if (p[0] != '&' || (p + 3 >= lim)) { - *(q++) = *(p++); - continue; + /* Copy everything up to the found '&' */ + const size_t chunk_len = ampersand_ptr - current_ptr; + if (chunk_len > 0) { + memcpy(output_ptr, current_ptr, chunk_len); + output_ptr += chunk_len; } - /* now p[3] is surely valid and is no terminator */ - - /* numerical entity */ - if (p[1] == '#') { - next = &p[2]; - if (process_numeric_entity(&next, &code) == FAILURE) - goto invalid_code; - - /* If we're in htmlspecialchars_decode, we're only decoding entities - * that represent &, <, >, " and '. Is this one of them? */ - if (!all && (code > 63U || - stage3_table_be_apos_00000[code].data.ent.entity == NULL)) - goto invalid_code; - - /* are we allowed to decode this entity in this document type? - * HTML 5 is the only that has a character that cannot be used in - * a numeric entity but is allowed literally (U+000D). The - * unoptimized version would be ... || !numeric_entity_is_allowed(code) */ - if (!unicode_cp_is_allowed(code, doctype) || - (doctype == ENT_HTML_DOC_HTML5 && code == 0x0D)) - goto invalid_code; - } else { - const char *start; - size_t ent_len; + /* Now current_ptr points to the '&' character. */ + current_ptr = ampersand_ptr; - next = &p[1]; - start = next; + /* If there are less than 4 bytes remaining, there isn't enough for an entity - + * copy '&' as a normal character. */ + if (input_end - current_ptr < 4) { + const size_t remaining = input_end - current_ptr; + memcpy(output_ptr, current_ptr, remaining); + output_ptr += remaining; + break; + } - if (process_named_entity_html(&next, &start, &ent_len) == FAILURE) - goto invalid_code; + unsigned code = 0, code2 = 0; + const char *entity_end_ptr = NULL; - if (resolve_named_entity_html(start, ent_len, inv_map, &code, &code2) == FAILURE) { - if (doctype == ENT_HTML_DOC_XHTML && ent_len == 4 && start[0] == 'a' - && start[1] == 'p' && start[2] == 'o' && start[3] == 's') { - /* uses html4 inv_map, which doesn't include apos;. This is a - * hack to support it */ - code = (unsigned) '\''; + if (current_ptr[1] == '#') { + /* Processing numeric entity */ + const char *num_start = current_ptr + 2; + entity_end_ptr = num_start; + if (process_numeric_entity(&entity_end_ptr, &code) == FAILURE) { + goto invalid_incomplete_entity; + } + if (!all && (code > 63U || stage3_table_be_apos_00000[code].data.ent.entity == NULL)) { + /* If we're in htmlspecialchars_decode, we're only decoding entities + * that represent &, <, >, " and '. Is this one of them? */ + goto invalid_incomplete_entity; + } else if (!unicode_cp_is_allowed(code, doctype) || + (doctype == ENT_HTML_DOC_HTML5 && code == 0x0D)) { + /* are we allowed to decode this entity in this document type? + * HTML 5 is the only that has a character that cannot be used in + * a numeric entity but is allowed literally (U+000D). The + * unoptimized version would be ... || !numeric_entity_is_allowed(code) */ + goto invalid_incomplete_entity; + } + } else { + /* Processing named entity */ + const char *name_start = current_ptr + 1; + /* Search for ';' */ + const size_t max_search_len = MIN(LONGEST_ENTITY_LENGTH + 1, input_end - name_start); + const char *semi_colon_ptr = memchr(name_start, ';', max_search_len); + if (!semi_colon_ptr) { + goto invalid_incomplete_entity; + } else { + const size_t name_len = semi_colon_ptr - name_start; + if (name_len == 0) { + goto invalid_incomplete_entity; } else { - goto invalid_code; + if (resolve_named_entity_html(name_start, name_len, inv_map, &code, &code2) == FAILURE) { + if (doctype == ENT_HTML_DOC_XHTML && name_len == 4 && + name_start[0] == 'a' && name_start[1] == 'p' && + name_start[2] == 'o' && name_start[3] == 's') + { + /* uses html4 inv_map, which doesn't include apos;. This is a + * hack to support it */ + code = (unsigned)'\''; + } else { + goto invalid_incomplete_entity; + } + } + entity_end_ptr = semi_colon_ptr; } } } - assert(*next == ';'); + /* At this stage the entity_end_ptr should be always set. */ + ZEND_ASSERT(entity_end_ptr != NULL); - if (((code == '\'' && !(flags & ENT_HTML_QUOTE_SINGLE)) || - (code == '"' && !(flags & ENT_HTML_QUOTE_DOUBLE))) - /* && code2 == '\0' always true for current maps */) - goto invalid_code; + /* Check if quotes are allowed for entities representing ' or " */ + if ((code == '\'' && !(flags & ENT_HTML_QUOTE_SINGLE)) || + (code == '"' && !(flags & ENT_HTML_QUOTE_DOUBLE))) + { + goto invalid_complete_entity; + } /* UTF-8 doesn't need mapping (ISO-8859-1 doesn't either, but * the call is needed to ensure the codepoint <= U+00FF) */ if (charset != cs_utf_8) { /* replace unicode code point */ - if (map_from_unicode(code, charset, &code) == FAILURE || code2 != 0) - goto invalid_code; /* not representable in target charset */ + if (map_from_unicode(code, charset, &code) == FAILURE || code2 != 0) { + goto invalid_complete_entity; + } } - q += write_octet_sequence((unsigned char*)q, charset, code); + /* Write the parsed entity into the output buffer */ + output_ptr += write_octet_sequence((unsigned char*)output_ptr, charset, code); if (code2) { - q += write_octet_sequence((unsigned char*)q, charset, code2); + output_ptr += write_octet_sequence((unsigned char*)output_ptr, charset, code2); } + /* Move current_ptr past the semicolon */ + current_ptr = entity_end_ptr + 1; + continue; - /* jump over the valid entity; may go beyond size of buffer; np */ - p = next + 1; +invalid_incomplete_entity: + /* If the entity is invalid at parse stage or entity_end_ptr was never found, copy '&' as normal */ + *output_ptr++ = *current_ptr++; continue; -invalid_code: - for (; p < next; p++) { - *(q++) = *p; +invalid_complete_entity: + /* If the entity became invalid after we found entity_end_ptr */ + if (entity_end_ptr) { + const size_t len = entity_end_ptr - current_ptr; + memcpy(output_ptr, current_ptr, len); + output_ptr += len; + current_ptr = entity_end_ptr; + } else { + *output_ptr++ = *current_ptr++; } + continue; } - *q = '\0'; - ZSTR_LEN(ret) = (size_t)(q - ZSTR_VAL(ret)); + *output_ptr = '\0'; + ZSTR_LEN(output) = (size_t)(output_ptr - ZSTR_VAL(output)); } /* }}} */ @@ -981,7 +1015,7 @@ PHPAPI zend_string *php_unescape_html_entities(zend_string *str, int all, int fl } if (all) { - charset = determine_charset(hint_charset, /* quiet */ 0); + charset = determine_charset(hint_charset, /* quiet */ false); } else { charset = cs_8859_1; /* charset shouldn't matter, use ISO-8859-1 for performance */ } @@ -999,7 +1033,7 @@ PHPAPI zend_string *php_unescape_html_entities(zend_string *str, int all, int fl inverse_map = unescape_inverse_map(all, flags); /* replace numeric entities */ - traverse_for_entities(ZSTR_VAL(str), ZSTR_LEN(str), ret, all, flags, inverse_map, charset); + traverse_for_entities(str, ret, all, flags, inverse_map, charset); return ret; } @@ -1007,7 +1041,7 @@ PHPAPI zend_string *php_unescape_html_entities(zend_string *str, int all, int fl PHPAPI zend_string *php_escape_html_entities(const unsigned char *old, size_t oldlen, int all, int flags, const char *hint_charset) { - return php_escape_html_entities_ex(old, oldlen, all, flags, hint_charset, 1, /* quiet */ 0); + return php_escape_html_entities_ex(old, oldlen, all, flags, hint_charset, true, /* quiet */ false); } /* {{{ find_entity_for_char */ @@ -1320,6 +1354,9 @@ static void php_html_entities(INTERNAL_FUNCTION_PARAMETERS, int all) Z_PARAM_BOOL(double_encode); ZEND_PARSE_PARAMETERS_END(); + if (ZSTR_LEN(str) == 0) { + RETURN_EMPTY_STRING(); + } replaced = php_escape_html_entities_ex( (unsigned char*)ZSTR_VAL(str), ZSTR_LEN(str), all, (int) flags, hint_charset ? ZSTR_VAL(hint_charset) : NULL, double_encode, /* quiet */ 0); diff --git a/ext/standard/html.h b/ext/standard/html.h index 40c595ba5d89..8576a5c8b9ce 100644 --- a/ext/standard/html.h +++ b/ext/standard/html.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ diff --git a/ext/standard/html_tables.h b/ext/standard/html_tables.h index 2d17d3fa44be..16f30283fdd4 100644 --- a/ext/standard/html_tables.h +++ b/ext/standard/html_tables.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/standard/html_tables/html_table_gen.php b/ext/standard/html_tables/html_table_gen.php index 02fc0c26d3d8..a3b2d8807d70 100755 --- a/ext/standard/html_tables/html_table_gen.php +++ b/ext/standard/html_tables/html_table_gen.php @@ -2,15 +2,13 @@ . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Gustavo Lopes | +----------------------------------------------------------------------+ @@ -22,15 +20,13 @@ $t = <<. | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -180,7 +176,7 @@ enum entity_charset charset; /* process file */ $map = array(); - $lines = explode("\n", file_get_contents($e{'file'})); + $lines = explode("\n", file_get_contents($e['file'])); foreach ($lines as $l) { if (preg_match("/^0x([0-9A-Z]{2})\t0x([0-9A-Z]{2,})/i", $l, $matches)) $map[] = array($matches[1], $matches[2]); @@ -323,7 +319,7 @@ enum entity_charset charset; /* process file */ $map = array(); - $lines = explode("\n", file_get_contents($e{'file'})); + $lines = explode("\n", file_get_contents($e['file'])); foreach ($lines as $l) { if (preg_match("/^0x([0-9A-Z]{2})\t0x([0-9A-Z]{2,})\s+#\s*(.*)$/i", $l, $matches)) $map[] = array($matches[1], $matches[2], rtrim($matches[3])); diff --git a/ext/standard/http.c b/ext/standard/http.c index ae6f668e0cb8..99509e7ceb04 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ @@ -79,10 +77,19 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str, scalar = zend_enum_fetch_case_value(Z_OBJ_P(scalar)); goto try_again; /* All possible types are either handled here or previously */ - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } +static zend_always_inline bool php_url_check_stack_limit(void) +{ +#ifdef ZEND_CHECK_STACK_LIMIT + return zend_call_stack_overflowed(EG(stack_limit)); +#else + return false; +#endif +} + /* {{{ php_url_encode_hash */ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, size_t num_prefix_len, @@ -101,6 +108,12 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, return; } + /* Very deeply structured data could trigger a stack overflow, even without recursion. */ + if (UNEXPECTED(php_url_check_stack_limit())) { + zend_throw_error(NULL, "Maximum call stack size reached."); + return; + } + if (!arg_sep) { arg_sep = PG(arg_separator).output; if (ZSTR_LEN(arg_sep) == 0) { @@ -109,14 +122,14 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } ZEND_HASH_FOREACH_KEY_VAL(ht, idx, key, zdata) { - bool is_dynamic = 1; + bool is_dynamic = true; if (Z_TYPE_P(zdata) == IS_INDIRECT) { zdata = Z_INDIRECT_P(zdata); if (Z_ISUNDEF_P(zdata)) { continue; } - is_dynamic = 0; + is_dynamic = false; } /* handling for private & protected object properties */ @@ -359,9 +372,7 @@ PHP_FUNCTION(request_parse_body) PHP_FUNCTION(http_get_last_response_headers) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); if (!Z_ISUNDEF(BG(last_http_headers))) { RETURN_COPY(&BG(last_http_headers)); @@ -372,9 +383,7 @@ PHP_FUNCTION(http_get_last_response_headers) PHP_FUNCTION(http_clear_last_response_headers) { - if (zend_parse_parameters_none() == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_NONE(); zval_ptr_dtor(&BG(last_http_headers)); ZVAL_UNDEF(&BG(last_http_headers)); diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 9fefe153622f..f3172180bed9 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | @@ -20,11 +18,13 @@ #include "php.h" #include "php_globals.h" +#include "ext/uri/php_uri.h" #include "php_streams.h" #include "php_network.h" #include "php_ini.h" #include "ext/standard/basic_functions.h" #include "zend_smart_str.h" +#include "zend_exceptions.h" #include #include @@ -42,7 +42,6 @@ #include "php_standard.h" -#include #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -109,11 +108,11 @@ static bool check_has_header(const char *headers, const char *header) { const char *s = headers; while ((s = strstr(s, header))) { if (s == headers || (*(s-1) == '\n' && *(s-2) == '\r')) { - return 1; + return true; } s++; } - return 0; + return false; } static zend_result php_stream_handle_proxy_authorization_header(const char *s, smart_str *header) @@ -157,7 +156,7 @@ static void php_stream_http_response_header_info_init( php_stream_http_response_header_info *header_info) { memset(header_info, 0, sizeof(php_stream_http_response_header_info)); - header_info->follow_location = 1; + header_info->follow_location = true; } /* Trim white spaces from response header line and update its length */ @@ -274,14 +273,14 @@ static zend_string *php_stream_http_response_headers_parse(php_stream_wrapper *w if (!strncasecmp(last_header_line, "Location:", sizeof("Location:")-1)) { /* Check if the location should be followed. */ if (context && (tmpzval = php_stream_context_get_option(context, "http", "follow_location")) != NULL) { - header_info->follow_location = zval_is_true(tmpzval); + header_info->follow_location = zend_is_true(tmpzval); } else if (!((response_code >= 300 && response_code < 304) || 307 == response_code || 308 == response_code)) { /* The redirection should not be automatic if follow_location is not set and * response_code not in (300, 301, 302, 303 and 307) * see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 * RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */ - header_info->follow_location = 0; + header_info->follow_location = false; } size_t last_header_value_len = strlen(last_header_value); if (last_header_value_len > HTTP_HEADER_MAX_LOCATION_SIZE) { @@ -358,7 +357,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, zval *response_header STREAMS_DC) /* {{{ */ { php_stream *stream = NULL; - php_url *resource = NULL; + php_uri *resource = NULL; int use_ssl; int use_proxy = 0; zend_string *tmp = NULL; @@ -391,7 +390,12 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, return NULL; } - resource = php_url_parse(path); + const php_uri_parser *uri_parser = php_stream_context_get_uri_parser("http", context); + if (uri_parser == NULL) { + zend_value_error("%s(): Provided stream context has invalid value for the \"uri_parser_class\" option", get_active_function_name()); + return NULL; + } + resource = php_uri_parse_to_struct(uri_parser, path, strlen(path), PHP_URI_COMPONENT_READ_MODE_RAW, true); if (resource == NULL) { return NULL; } @@ -403,7 +407,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, (tmpzval = php_stream_context_get_option(context, wrapper->wops->label, "proxy")) == NULL || Z_TYPE_P(tmpzval) != IS_STRING || Z_STRLEN_P(tmpzval) == 0) { - php_url_free(resource); + php_uri_struct_free(resource); return php_stream_open_wrapper_ex(path, mode, REPORT_ERRORS, NULL, context); } /* Called from a non-http wrapper with http proxying requested (i.e. ftp) */ @@ -416,7 +420,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (strpbrk(mode, "awx+")) { php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper does not support writeable connections"); - php_url_free(resource); + php_uri_struct_free(resource); return NULL; } @@ -439,13 +443,13 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, use_proxy = 1; transport_string = zend_string_copy(Z_STR_P(tmpzval)); } else { - transport_string = zend_strpprintf(0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", ZSTR_VAL(resource->host), resource->port); + transport_string = zend_strpprintf(0, "%s://%s:" ZEND_LONG_FMT, use_ssl ? "ssl" : "tcp", ZSTR_VAL(resource->host), resource->port); } } if (request_fulluri && (strchr(path, '\n') != NULL || strchr(path, '\r') != NULL)) { php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper full URI path does not allow CR or LF characters"); - php_url_free(resource); + php_uri_struct_free(resource); zend_string_release(transport_string); return NULL; } @@ -461,7 +465,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, if (d > timeoutmax) { php_stream_wrapper_log_error(wrapper, options, "timeout must be lower than " ZEND_ULONG_FMT, (zend_ulong)timeoutmax); zend_string_release(transport_string); - php_url_free(resource); + php_uri_struct_free(resource); return NULL; } #ifndef PHP_WIN32 @@ -509,7 +513,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1); - smart_str_appends(&header, ZSTR_VAL(resource->host)); + smart_str_append(&header, resource->host); smart_str_appendc(&header, ':'); smart_str_append_unsigned(&header, resource->port); smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1); @@ -540,6 +544,10 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); if (php_stream_write(stream, ZSTR_VAL(header.s), ZSTR_LEN(header.s)) != ZSTR_LEN(header.s)) { + if (reset_ssl_peer_name) { + php_stream_context_unset_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name"); + } + php_stream_wrapper_log_error(wrapper, options, "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; @@ -561,16 +569,18 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* enable SSL transport layer */ if (stream) { + php_stream_context *old_context = PHP_STREAM_CONTEXT(stream); + if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL) < 0 || php_stream_xport_crypto_enable(stream, 1) < 0) { php_stream_wrapper_log_error(wrapper, options, "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; } - } - if (reset_ssl_peer_name) { - php_stream_context_unset_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name"); + if (reset_ssl_peer_name) { + php_stream_context_unset_option(old_context, "ssl", "peer_name"); + } } } @@ -596,7 +606,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, redirect_max = (int)zval_get_long(tmpzval); } - custom_request_method = 0; + custom_request_method = false; if (context && (tmpzval = php_stream_context_get_option(context, "http", "method")) != NULL) { if (Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval) > 0) { /* As per the RFC, automatically redirected requests MUST NOT use other methods than @@ -605,7 +615,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, || zend_string_equals_literal(Z_STR_P(tmpzval), "GET") || zend_string_equals_literal(Z_STR_P(tmpzval), "HEAD") ) { - custom_request_method = 1; + custom_request_method = true; smart_str_append(&req_buf, Z_STR_P(tmpzval)); smart_str_appendc(&req_buf, ' '); } @@ -624,7 +634,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* file */ if (resource->path && ZSTR_LEN(resource->path)) { - smart_str_appends(&req_buf, ZSTR_VAL(resource->path)); + smart_str_append(&req_buf, resource->path); } else { smart_str_appendc(&req_buf, '/'); } @@ -632,19 +642,15 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* query string */ if (resource->query) { smart_str_appendc(&req_buf, '?'); - smart_str_appends(&req_buf, ZSTR_VAL(resource->query)); + smart_str_append(&req_buf, resource->query); } } /* protocol version we are speaking */ if (context && (tmpzval = php_stream_context_get_option(context, "http", "protocol_version")) != NULL) { - char *protocol_version; - spprintf(&protocol_version, 0, "%.1F", zval_get_double(tmpzval)); - smart_str_appends(&req_buf, " HTTP/"); - smart_str_appends(&req_buf, protocol_version); + smart_str_append_printf(&req_buf, "%.1F", zval_get_double(tmpzval)); smart_str_appends(&req_buf, "\r\n"); - efree(protocol_version); } else { smart_str_appends(&req_buf, " HTTP/1.1\r\n"); } @@ -746,33 +752,31 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* auth header if it was specified */ if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user) { - /* make scratch large enough to hold the whole URL (over-estimate) */ - size_t scratch_len = strlen(path) + 1; - char *scratch = emalloc(scratch_len); - zend_string *stmp; + smart_str scratch = {0}; /* decode the strings first */ php_url_decode(ZSTR_VAL(resource->user), ZSTR_LEN(resource->user)); - strcpy(scratch, ZSTR_VAL(resource->user)); - strcat(scratch, ":"); + smart_str_append(&scratch, resource->user); + smart_str_appendc(&scratch, ':'); /* Note: password is optional! */ - if (resource->pass) { - php_url_decode(ZSTR_VAL(resource->pass), ZSTR_LEN(resource->pass)); - strcat(scratch, ZSTR_VAL(resource->pass)); + if (resource->password) { + php_url_decode(ZSTR_VAL(resource->password), ZSTR_LEN(resource->password)); + smart_str_append(&scratch, resource->password); } - stmp = php_base64_encode((unsigned char*)scratch, strlen(scratch)); + zend_string *scratch_str = smart_str_extract(&scratch); + zend_string *stmp = php_base64_encode((unsigned char*)ZSTR_VAL(scratch_str), ZSTR_LEN(scratch_str)); smart_str_appends(&req_buf, "Authorization: Basic "); - smart_str_appends(&req_buf, ZSTR_VAL(stmp)); + smart_str_append(&req_buf, stmp); smart_str_appends(&req_buf, "\r\n"); php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0); + zend_string_efree(scratch_str); zend_string_free(stmp); - efree(scratch); } /* if the user has configured who they are, send a From: line */ @@ -785,7 +789,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* Send Host: header so name-based virtual hosts work */ if ((have_header & HTTP_HEADER_HOST) == 0) { smart_str_appends(&req_buf, "Host: "); - smart_str_appends(&req_buf, ZSTR_VAL(resource->host)); + smart_str_append(&req_buf, resource->host); if ((use_ssl && resource->port != 443 && resource->port != 0) || (!use_ssl && resource->port != 80 && resource->port != 0)) { smart_str_appendc(&req_buf, ':'); @@ -868,7 +872,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, php_error_docref(NULL, E_NOTICE, "Content-type not specified assuming application/x-www-form-urlencoded"); } smart_str_appends(&req_buf, "\r\n"); - smart_str_appendl(&req_buf, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval)); + smart_str_append(&req_buf, Z_STR_P(tmpzval)); } else { smart_str_appends(&req_buf, "\r\n"); } @@ -1082,7 +1086,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, header_info.location = NULL; } if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { - spprintf(&new_path, 0, "%s://%s:%d%s", ZSTR_VAL(resource->scheme), + spprintf(&new_path, 0, "%s://%s:" ZEND_LONG_FMT "%s", ZSTR_VAL(resource->scheme), ZSTR_VAL(resource->host), resource->port, loc_path); } else { spprintf(&new_path, 0, "%s://%s%s", ZSTR_VAL(resource->scheme), @@ -1094,9 +1098,9 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, header_info.location = NULL; } - php_url_free(resource); + php_uri_struct_free(resource); /* check for invalid redirection URLs */ - if ((resource = php_url_parse(new_path)) == NULL) { + if ((resource = php_uri_parse_to_struct(uri_parser, new_path, strlen(new_path), PHP_URI_COMPONENT_READ_MODE_RAW, true)) == NULL) { php_stream_wrapper_log_error(wrapper, options, "Invalid redirect URL! %s", new_path); efree(new_path); goto out; @@ -1120,7 +1124,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, /* check for control characters in login, password & path */ if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) { CHECK_FOR_CNTRL_CHARS(resource->user); - CHECK_FOR_CNTRL_CHARS(resource->pass); + CHECK_FOR_CNTRL_CHARS(resource->password); CHECK_FOR_CNTRL_CHARS(resource->path); } int new_flags = HTTP_WRAPPER_REDIRECTED; @@ -1151,7 +1155,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, } if (resource) { - php_url_free(resource); + php_uri_struct_free(resource); } if (stream) { diff --git a/ext/standard/image.c b/ext/standard/image.c index eeb1f1fa2813..869371842006 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | @@ -51,24 +49,22 @@ PHPAPI const char php_sig_iff[4] = {'F','O','R','M'}; PHPAPI const char php_sig_ico[4] = {(char)0x00, (char)0x00, (char)0x01, (char)0x00}; PHPAPI const char php_sig_riff[4] = {'R', 'I', 'F', 'F'}; PHPAPI const char php_sig_webp[4] = {'W', 'E', 'B', 'P'}; +PHPAPI const char php_sig_ftyp[4] = {'f', 't', 'y', 'p'}; +PHPAPI const char php_sig_mif1[4] = {'m', 'i', 'f', '1'}; +PHPAPI const char php_sig_heic[4] = {'h', 'e', 'i', 'c'}; +PHPAPI const char php_sig_heix[4] = {'h', 'e', 'i', 'x'}; + +static zend_array php_image_handlers; +static int php_image_handler_next_id = IMAGE_FILETYPE_FIXED_COUNT; /* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */ /* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */ -/* return info as a struct, to make expansion easier */ - -struct gfxinfo { - unsigned int width; - unsigned int height; - unsigned int bits; - unsigned int channels; -}; - /* {{{ php_handle_gif * routine to handle GIF files. If only everything were that easy... ;} */ -static struct gfxinfo *php_handle_gif (php_stream * stream) +static struct php_gfxinfo *php_handle_gif (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[5]; if (php_stream_seek(stream, 3, SEEK_CUR)) @@ -77,7 +73,7 @@ static struct gfxinfo *php_handle_gif (php_stream * stream) if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim)) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->width = (unsigned int)dim[0] | (((unsigned int)dim[1])<<8); result->height = (unsigned int)dim[2] | (((unsigned int)dim[3])<<8); result->bits = dim[4]&0x80 ? ((((unsigned int)dim[4])&0x07) + 1) : 0; @@ -88,9 +84,9 @@ static struct gfxinfo *php_handle_gif (php_stream * stream) /* }}} */ /* {{{ php_handle_psd */ -static struct gfxinfo *php_handle_psd (php_stream * stream) +static struct php_gfxinfo *php_handle_psd (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[8]; if (php_stream_seek(stream, 11, SEEK_CUR)) @@ -99,7 +95,7 @@ static struct gfxinfo *php_handle_psd (php_stream * stream) if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim)) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->height = (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]); result->width = (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]); @@ -108,9 +104,9 @@ static struct gfxinfo *php_handle_psd (php_stream * stream) /* }}} */ /* {{{ php_handle_bmp */ -static struct gfxinfo *php_handle_bmp (php_stream * stream) +static struct php_gfxinfo *php_handle_bmp (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[16]; int size; @@ -122,12 +118,12 @@ static struct gfxinfo *php_handle_bmp (php_stream * stream) size = (((unsigned int)dim[ 3]) << 24) + (((unsigned int)dim[ 2]) << 16) + (((unsigned int)dim[ 1]) << 8) + ((unsigned int) dim[ 0]); if (size == 12) { - result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof(struct php_gfxinfo)); result->width = (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]); result->height = (((unsigned int)dim[ 7]) << 8) + ((unsigned int) dim[ 6]); result->bits = ((unsigned int)dim[11]); } else if (size > 12 && (size <= 64 || size == 108 || size == 124)) { - result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof(struct php_gfxinfo)); result->width = (((unsigned int)dim[ 7]) << 24) + (((unsigned int)dim[ 6]) << 16) + (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]); result->height = (((unsigned int)dim[11]) << 24) + (((unsigned int)dim[10]) << 16) + (((unsigned int)dim[ 9]) << 8) + ((unsigned int) dim[ 8]); result->height = abs((int32_t)result->height); @@ -158,9 +154,9 @@ static unsigned long int php_swf_get_bits (unsigned char* buffer, unsigned int p #if defined(HAVE_ZLIB) && !defined(COMPILE_DL_ZLIB) /* {{{ php_handle_swc */ -static struct gfxinfo *php_handle_swc(php_stream * stream) +static struct php_gfxinfo *php_handle_swc(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; long bits; unsigned char a[64]; @@ -227,7 +223,7 @@ static struct gfxinfo *php_handle_swc(php_stream * stream) } if (!status) { - result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof (struct php_gfxinfo)); bits = php_swf_get_bits (b, 0, 5); result->width = (php_swf_get_bits (b, 5 + bits, bits) - php_swf_get_bits (b, 5, bits)) / 20; @@ -244,9 +240,9 @@ static struct gfxinfo *php_handle_swc(php_stream * stream) #endif /* {{{ php_handle_swf */ -static struct gfxinfo *php_handle_swf (php_stream * stream) +static struct php_gfxinfo *php_handle_swf (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; long bits; unsigned char a[32]; @@ -256,7 +252,7 @@ static struct gfxinfo *php_handle_swf (php_stream * stream) if (php_stream_read(stream, (char*)a, sizeof(a)) != sizeof(a)) return NULL; - result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc (1, sizeof (struct php_gfxinfo)); bits = php_swf_get_bits (a, 0, 5); result->width = (php_swf_get_bits (a, 5 + bits, bits) - php_swf_get_bits (a, 5, bits)) / 20; @@ -270,9 +266,9 @@ static struct gfxinfo *php_handle_swf (php_stream * stream) /* {{{ php_handle_png * routine to handle PNG files */ -static struct gfxinfo *php_handle_png (php_stream * stream) +static struct php_gfxinfo *php_handle_png (php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[9]; /* Width: 4 bytes * Height: 4 bytes @@ -289,7 +285,7 @@ static struct gfxinfo *php_handle_png (php_stream * stream) if((php_stream_read(stream, (char*)dim, sizeof(dim))) < sizeof(dim)) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->width = (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]); result->height = (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]); result->bits = (unsigned int)dim[8]; @@ -408,6 +404,7 @@ static size_t php_read_stream_all_chunks(php_stream *stream, char *buffer, size_ if (read_now < stream->chunk_size && read_total != length) { return 0; } + buffer += read_now; } while (read_total < length); return read_total; @@ -448,9 +445,9 @@ static int php_read_APP(php_stream * stream, unsigned int marker, zval *info) /* {{{ php_handle_jpeg main loop to parse JPEG structure */ -static struct gfxinfo *php_handle_jpeg (php_stream * stream, zval *info) +static struct php_gfxinfo *php_handle_jpeg (php_stream * stream, zval *info) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned int marker = M_PSEUDO; unsigned short length, ff_read=1; @@ -473,7 +470,7 @@ static struct gfxinfo *php_handle_jpeg (php_stream * stream, zval *info) case M_SOF15: if (result == NULL) { /* handle SOFn block */ - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); length = php_read2(stream); result->bits = php_stream_getc(stream); result->height = php_read2(stream); @@ -576,9 +573,9 @@ static unsigned int php_read4(php_stream * stream) /* {{{ php_handle_jpc Main loop to parse JPEG2000 raw codestream structure */ -static struct gfxinfo *php_handle_jpc(php_stream * stream) +static struct php_gfxinfo *php_handle_jpc(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; int highest_bit_depth, bit_depth; unsigned char first_marker_id; unsigned int i; @@ -599,7 +596,7 @@ static struct gfxinfo *php_handle_jpc(php_stream * stream) return NULL; } - result = (struct gfxinfo *)ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *)ecalloc(1, sizeof(struct php_gfxinfo)); php_read2(stream); /* Lsiz */ php_read2(stream); /* Rsiz */ @@ -647,9 +644,9 @@ static struct gfxinfo *php_handle_jpc(php_stream * stream) /* {{{ php_handle_jp2 main loop to parse JPEG 2000 JP2 wrapper format structure */ -static struct gfxinfo *php_handle_jp2(php_stream *stream) +static struct php_gfxinfo *php_handle_jp2(php_stream *stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned int box_length; unsigned int box_type; char jp2c_box_id[] = {(char)0x6a, (char)0x70, (char)0x32, (char)0x63}; @@ -773,9 +770,9 @@ static unsigned php_ifd_get32u(void *Long, int motorola_intel) /* {{{ php_handle_tiff main loop to parse TIFF structure */ -static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int motorola_intel) +static struct php_gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int motorola_intel) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; int i, num_entries; unsigned char *dir_entry; size_t ifd_size, dir_size, entry_value, width=0, height=0, ifd_addr; @@ -841,7 +838,7 @@ static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int mot efree(ifd_data); if ( width && height) { /* not the same when in for-loop */ - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->height = height; result->width = width; result->bits = 0; @@ -853,9 +850,9 @@ static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int mot /* }}} */ /* {{{ php_handle_psd */ -static struct gfxinfo *php_handle_iff(php_stream * stream) +static struct php_gfxinfo *php_handle_iff(php_stream * stream) { - struct gfxinfo * result; + struct php_gfxinfo * result; unsigned char a[10]; int chunkId; int size; @@ -889,7 +886,7 @@ static struct gfxinfo *php_handle_iff(php_stream * stream) height = php_ifd_get16s(a+2, 1); bits = a[8] & 0xff; if (width > 0 && height > 0 && bits > 0 && bits < 33) { - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); result->width = width; result->height = height; result->bits = bits; @@ -914,7 +911,7 @@ static struct gfxinfo *php_handle_iff(php_stream * stream) * int Number of columns * int Number of rows */ -static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check) +static int php_get_wbmp(php_stream *stream, struct php_gfxinfo **result, int check) { int i, width = 0, height = 0; @@ -975,9 +972,9 @@ static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check) /* }}} */ /* {{{ php_handle_wbmp */ -static struct gfxinfo *php_handle_wbmp(php_stream * stream) +static struct php_gfxinfo *php_handle_wbmp(php_stream * stream) { - struct gfxinfo *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + struct php_gfxinfo *result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); if (!php_get_wbmp(stream, &result, 0)) { efree(result); @@ -989,7 +986,7 @@ static struct gfxinfo *php_handle_wbmp(php_stream * stream) /* }}} */ /* {{{ php_get_xbm */ -static int php_get_xbm(php_stream *stream, struct gfxinfo **result) +static int php_get_xbm(php_stream *stream, struct php_gfxinfo **result) { char *fline; char *iname; @@ -1036,7 +1033,7 @@ static int php_get_xbm(php_stream *stream, struct gfxinfo **result) if (width && height) { if (result) { - *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + *result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); (*result)->width = width; (*result)->height = height; } @@ -1048,18 +1045,18 @@ static int php_get_xbm(php_stream *stream, struct gfxinfo **result) /* }}} */ /* {{{ php_handle_xbm */ -static struct gfxinfo *php_handle_xbm(php_stream * stream) +static struct php_gfxinfo *php_handle_xbm(php_stream * stream) { - struct gfxinfo *result; + struct php_gfxinfo *result; php_get_xbm(stream, &result); return result; } /* }}} */ /* {{{ php_handle_ico */ -static struct gfxinfo *php_handle_ico(php_stream * stream) +static struct php_gfxinfo *php_handle_ico(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; unsigned char dim[16]; int num_icons = 0; @@ -1071,7 +1068,7 @@ static struct gfxinfo *php_handle_ico(php_stream * stream) if (num_icons < 1 || num_icons > 255) return NULL; - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); while (num_icons > 0) { @@ -1098,9 +1095,9 @@ static struct gfxinfo *php_handle_ico(php_stream * stream) /* }}} */ /* {{{ php_handle_webp */ -static struct gfxinfo *php_handle_webp(php_stream * stream) +static struct php_gfxinfo *php_handle_webp(php_stream * stream) { - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; const char sig[3] = {'V', 'P', '8'}; unsigned char buf[18]; char format; @@ -1121,7 +1118,7 @@ static struct gfxinfo *php_handle_webp(php_stream * stream) return NULL; } - result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo *) ecalloc(1, sizeof(struct php_gfxinfo)); switch (format) { case ' ': @@ -1183,14 +1180,14 @@ static void php_avif_stream_skip(void* stream, size_t num_bytes) { * declared as invalid. Around 450 bytes are usually enough. * Transforms such as mirror and rotation are not applied on width and height. */ -static struct gfxinfo *php_handle_avif(php_stream * stream) { - struct gfxinfo* result = NULL; +static struct php_gfxinfo *php_handle_avif(php_stream * stream) { + struct php_gfxinfo* result = NULL; AvifInfoFeatures features; struct php_avif_stream avif_stream; avif_stream.stream = stream; if (AvifInfoGetFeaturesStream(&avif_stream, php_avif_stream_read, php_avif_stream_skip, &features) == kAvifInfoOk) { - result = (struct gfxinfo*)ecalloc(1, sizeof(struct gfxinfo)); + result = (struct php_gfxinfo*)ecalloc(1, sizeof(struct php_gfxinfo)); result->width = features.width; result->height = features.height; result->bits = features.bit_depth; @@ -1200,7 +1197,7 @@ static struct gfxinfo *php_handle_avif(php_stream * stream) { } /* }}} */ -/* {{{ php_is_image_avif +/* * Detect whether an image is of type AVIF * * Only the first "ftyp" box is read. @@ -1210,16 +1207,12 @@ bool php_is_image_avif(php_stream* stream) { struct php_avif_stream avif_stream; avif_stream.stream = stream; - if (AvifInfoIdentifyStream(&avif_stream, php_avif_stream_read, php_avif_stream_skip) == kAvifInfoOk) { - return 1; - } - return 0; + return AvifInfoIdentifyStream(&avif_stream, php_avif_stream_read, php_avif_stream_skip) == kAvifInfoOk; } -/* }}} */ /* {{{ php_image_type_to_mime_type * Convert internal image_type to mime type */ -PHPAPI char * php_image_type_to_mime_type(int image_type) +PHPAPI const char * php_image_type_to_mime_type(int image_type) { switch( image_type) { case IMAGE_FILETYPE_GIF: @@ -1254,7 +1247,15 @@ PHPAPI char * php_image_type_to_mime_type(int image_type) return "image/webp"; case IMAGE_FILETYPE_AVIF: return "image/avif"; - default: + case IMAGE_FILETYPE_HEIF: + return "image/heif"; + default: { + const struct php_image_handler *handler = zend_hash_index_find_ptr(&php_image_handlers, (zend_ulong) image_type); + if (handler) { + return handler->mime_type; + } + ZEND_FALLTHROUGH; + } case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */ } @@ -1270,7 +1271,7 @@ PHP_FUNCTION(image_type_to_mime_type) Z_PARAM_LONG(p_image_type) ZEND_PARSE_PARAMETERS_END(); - ZVAL_STRING(return_value, (char*)php_image_type_to_mime_type(p_image_type)); + ZVAL_STRING(return_value, php_image_type_to_mime_type(p_image_type)); } /* }}} */ @@ -1339,6 +1340,16 @@ PHP_FUNCTION(image_type_to_extension) case IMAGE_FILETYPE_AVIF: imgext = ".avif"; break; + case IMAGE_FILETYPE_HEIF: + imgext = ".heif"; + break; + default: { + const struct php_image_handler *handler = zend_hash_index_find_ptr(&php_image_handlers, (zend_ulong) image_type); + if (handler) { + imgext = handler->extension; + } + break; + } } if (imgext) { @@ -1427,6 +1438,12 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp return IMAGE_FILETYPE_AVIF; } + /* See GH-20201: this needs to be after avif checks to avoid identifying avif as heif. */ + if (twelve_bytes_read && !memcmp(filetype + 4, php_sig_ftyp, 4) && + (!memcmp(filetype + 8, php_sig_mif1, 4) || !memcmp(filetype + 8, php_sig_heic, 4) || !memcmp(filetype + 8, php_sig_heix, 4))) { + return IMAGE_FILETYPE_HEIF; + } + /* AFTER ALL ABOVE FAILED */ if (php_get_wbmp(stream, NULL, 1)) { return IMAGE_FILETYPE_WBMP; @@ -1441,6 +1458,15 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp return IMAGE_FILETYPE_XBM; } + zend_ulong h; + zval *zv; + ZEND_HASH_FOREACH_NUM_KEY_VAL(&php_image_handlers, h, zv) { + const struct php_image_handler *handler = Z_PTR_P(zv); + if (handler->identify(stream) == SUCCESS) { + return (int) h; + } + } ZEND_HASH_FOREACH_END(); + return IMAGE_FILETYPE_UNKNOWN; } /* }}} */ @@ -1448,7 +1474,8 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp static void php_getimagesize_from_stream(php_stream *stream, char *input, zval *info, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { int itype = 0; - struct gfxinfo *result = NULL; + struct php_gfxinfo *result = NULL; + const char *mime_type = NULL; if (!stream) { RETURN_FALSE; @@ -1473,6 +1500,7 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * result = php_handle_swf(stream); break; case IMAGE_FILETYPE_SWC: + /* TODO: with the new php_image_register_handler() APIs, this restriction could be solved */ #if defined(HAVE_ZLIB) && !defined(COMPILE_DL_ZLIB) result = php_handle_swc(stream); #else @@ -1515,19 +1543,35 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * case IMAGE_FILETYPE_AVIF: result = php_handle_avif(stream); break; - default: + case IMAGE_FILETYPE_HEIF: + if (!php_stream_rewind(stream)) { + result = php_handle_avif(stream); + } + break; + default: { + struct php_image_handler* handler = zend_hash_index_find_ptr(&php_image_handlers, (zend_ulong) itype); + if (handler) { + result = handler->get_info(stream); + mime_type = handler->mime_type; + break; + } + ZEND_FALLTHROUGH; + } case IMAGE_FILETYPE_UNKNOWN: break; } if (result) { - char temp[MAX_LENGTH_OF_LONG * 2 + sizeof("width=\"\" height=\"\"")]; array_init(return_value); add_index_long(return_value, 0, result->width); add_index_long(return_value, 1, result->height); add_index_long(return_value, 2, itype); - snprintf(temp, sizeof(temp), "width=\"%d\" height=\"%d\"", result->width, result->height); - add_index_string(return_value, 3, temp); + if ((!result->width_unit || zend_string_equals_literal(result->width_unit, "px")) + && (!result->height_unit || zend_string_equals_literal(result->height_unit, "px"))) { + char temp[MAX_LENGTH_OF_LONG * 2 + sizeof("width=\"\" height=\"\"")]; + snprintf(temp, sizeof(temp), "width=\"%d\" height=\"%d\"", result->width, result->height); + add_index_string(return_value, 3, temp); + } if (result->bits != 0) { add_assoc_long(return_value, "bits", result->bits); @@ -1535,7 +1579,19 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * if (result->channels != 0) { add_assoc_long(return_value, "channels", result->channels); } - add_assoc_string(return_value, "mime", (char*)php_image_type_to_mime_type(itype)); + add_assoc_string(return_value, "mime", mime_type ? mime_type : php_image_type_to_mime_type(itype)); + + if (result->width_unit) { + add_assoc_str(return_value, "width_unit", result->width_unit); + } else { + add_assoc_string(return_value, "width_unit", "px"); + } + if (result->height_unit) { + add_assoc_str(return_value, "height_unit", result->height_unit); + } else { + add_assoc_string(return_value, "height_unit", "px"); + } + efree(result); } else { RETURN_FALSE; @@ -1558,7 +1614,7 @@ static void php_getimagesize_from_any(INTERNAL_FUNCTION_PARAMETERS, int mode) { Z_PARAM_ZVAL(info) ZEND_PARSE_PARAMETERS_END(); - if (mode == FROM_PATH && CHECK_NULL_PATH(ZSTR_VAL(input), ZSTR_LEN(input))) { + if (mode == FROM_PATH && zend_str_has_nul_byte(input)) { zend_argument_value_error(1, "must not contain any null bytes"); RETURN_THROWS(); } @@ -1598,3 +1654,36 @@ PHP_FUNCTION(getimagesizefromstring) php_getimagesize_from_any(INTERNAL_FUNCTION_PARAM_PASSTHRU, FROM_DATA); } /* }}} */ + +PHP_MINIT_FUNCTION(image) +{ + zend_hash_init(&php_image_handlers, 4, NULL, NULL, true); + return SUCCESS; +} + +PHP_MSHUTDOWN_FUNCTION(image) +{ +#ifdef ZTS + if (!tsrm_is_main_thread()) { + return SUCCESS; + } +#endif + zend_hash_destroy(&php_image_handlers); + return SUCCESS; +} + +extern zend_module_entry basic_functions_module; + +int php_image_register_handler(const struct php_image_handler *handler) +{ + zend_hash_index_add_ptr(&php_image_handlers, (zend_ulong) php_image_handler_next_id, (void *) handler); + zend_register_long_constant(handler->const_name, strlen(handler->const_name), php_image_handler_next_id, CONST_PERSISTENT, basic_functions_module.module_number); + Z_LVAL_P(zend_get_constant_str(ZEND_STRL("IMAGETYPE_COUNT")))++; + return php_image_handler_next_id++; +} + +zend_result php_image_unregister_handler(int image_type) +{ + ZEND_ASSERT(image_type >= IMAGE_FILETYPE_FIXED_COUNT); + return zend_hash_index_del(&php_image_handlers, (zend_ulong) image_type); +} diff --git a/ext/standard/incomplete_class.c b/ext/standard/incomplete_class.c index 228e03fbe863..d794612f429d 100644 --- a/ext/standard/incomplete_class.c +++ b/ext/standard/incomplete_class.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/info.c b/ext/standard/info.c index 952f0f92fe6e..dcb01bc08220 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | @@ -1021,35 +1019,78 @@ PHPAPI ZEND_COLD void php_print_info(int flag) if (flag & PHP_INFO_LICENSE) { if (!sapi_module.phpinfo_as_text) { - SECTION("PHP License"); + SECTION("License"); php_info_print_box_start(0); php_info_print("

\n"); - php_info_print("This program is free software; you can redistribute it and/or modify "); - php_info_print("it under the terms of the PHP License as published by the PHP Group "); - php_info_print("and included in the distribution in the file: LICENSE\n"); + php_info_print("PHP is free software. You may redistribute it and/or modify it under the "); + php_info_print("terms of the Modified BSD License (SPDX-License-Identifier: BSD-3-Clause).\n"); php_info_print("

\n"); - php_info_print("

"); - php_info_print("This program is distributed in the hope that it will be useful, "); - php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of "); - php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + php_info_print("

\n"); + php_info_print("Copyright © The PHP Group and Contributors.
\n"); + php_info_print("Copyright © Zend Technologies Ltd., a subsidiary company of Perforce Software, Inc.\n"); php_info_print("

\n"); - php_info_print("

"); - php_info_print("If you did not receive a copy of the PHP license, or have any questions about "); - php_info_print("PHP licensing, please contact license@php.net.\n"); + php_info_print("

\n"); + php_info_print("Redistribution and use in source and binary forms, with or without "); + php_info_print("modification, are permitted provided that the following conditions are met:\n"); + php_info_print("

\n"); + php_info_print("
    \n"); + php_info_print("
  1. Redistributions of source code must retain the above copyright notice, this "); + php_info_print("list of conditions and the following disclaimer.
  2. \n"); + php_info_print("
  3. Redistributions in binary form must reproduce the above copyright notice, "); + php_info_print("this list of conditions and the following disclaimer in the documentation "); + php_info_print("and/or other materials provided with the distribution.
  4. \n"); + php_info_print("
  5. Neither the name of the copyright holder nor the names of its "); + php_info_print("contributors may be used to endorse or promote products derived from "); + php_info_print("this software without specific prior written permission.
  6. \n"); + php_info_print("
\n"); + php_info_print("

\n"); + php_info_print("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" "); + php_info_print("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE "); + php_info_print("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE "); + php_info_print("DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE "); + php_info_print("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL "); + php_info_print("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR "); + php_info_print("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER "); + php_info_print("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, "); + php_info_print("OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE "); + php_info_print("OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"); php_info_print("

\n"); php_info_print_box_end(); } else { - php_info_print("\nPHP License\n"); - php_info_print("This program is free software; you can redistribute it and/or modify\n"); - php_info_print("it under the terms of the PHP License as published by the PHP Group\n"); - php_info_print("and included in the distribution in the file: LICENSE\n"); php_info_print("\n"); - php_info_print("This program is distributed in the hope that it will be useful,\n"); - php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); - php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + php_info_print("License\n"); + php_info_print("\n"); + php_info_print("PHP is free software. You may redistribute it and/or modify it under the\n"); + php_info_print("terms of the Modified BSD License (SPDX-License-Identifier: BSD-3-Clause).\n"); + php_info_print("\n"); + php_info_print("Copyright © The PHP Group and Contributors.\n"); + php_info_print("Copyright © Zend Technologies Ltd., a subsidiary company of\n"); + php_info_print(" Perforce Software, Inc.\n"); + php_info_print("\n"); + php_info_print("Redistribution and use in source and binary forms, with or without\n"); + php_info_print("modification, are permitted provided that the following conditions are met:\n"); + php_info_print("\n"); + php_info_print("1. Redistributions of source code must retain the above copyright notice, this\n"); + php_info_print(" list of conditions and the following disclaimer.\n"); + php_info_print("\n"); + php_info_print("2. Redistributions in binary form must reproduce the above copyright notice,\n"); + php_info_print(" this list of conditions and the following disclaimer in the documentation\n"); + php_info_print(" and/or other materials provided with the distribution.\n"); + php_info_print("\n"); + php_info_print("3. Neither the name of the copyright holder nor the names of its\n"); + php_info_print(" contributors may be used to endorse or promote products derived from\n"); + php_info_print(" this software without specific prior written permission.\n"); php_info_print("\n"); - php_info_print("If you did not receive a copy of the PHP license, or have any\n"); - php_info_print("questions about PHP licensing, please contact license@php.net.\n"); + php_info_print("THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n"); + php_info_print("AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"); + php_info_print("IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"); + php_info_print("DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n"); + php_info_print("FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"); + php_info_print("DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n"); + php_info_print("SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n"); + php_info_print("CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n"); + php_info_print("OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"); + php_info_print("OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"); } } diff --git a/ext/standard/info.h b/ext/standard/info.h index 380d2b6e042a..6d1603dd8346 100644 --- a/ext/standard/info.h +++ b/ext/standard/info.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Zeev Suraski | diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c index 44dd33bab10a..59db612a7337 100644 --- a/ext/standard/iptc.c +++ b/ext/standard/iptc.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -73,19 +71,24 @@ #define M_APP15 0xef /* {{{ php_iptc_put1 */ -static int php_iptc_put1(FILE *fp, int spool, unsigned char c, unsigned char **spoolbuf) +static int php_iptc_put1(FILE *fp, int spool, unsigned char c, unsigned char **spoolbuf, const unsigned char *spoolbuf_end) { if (spool > 0) PUTC(c); - if (spoolbuf) *(*spoolbuf)++ = c; + if (spoolbuf) { + if (UNEXPECTED(*spoolbuf >= spoolbuf_end)) { + return EOF; + } + *(*spoolbuf)++ = c; + } return c; } /* }}} */ /* {{{ php_iptc_get1 */ -static int php_iptc_get1(FILE *fp, int spool, unsigned char **spoolbuf) +static int php_iptc_get1(FILE *fp, int spool, unsigned char **spoolbuf, const unsigned char *spoolbuf_end) { int c; char cc; @@ -99,66 +102,71 @@ static int php_iptc_get1(FILE *fp, int spool, unsigned char **spoolbuf) PUTC(cc); } - if (spoolbuf) *(*spoolbuf)++ = c; + if (spoolbuf) { + if (UNEXPECTED(*spoolbuf >= spoolbuf_end)) { + return EOF; + } + *(*spoolbuf)++ = c; + } return c; } /* }}} */ /* {{{ php_iptc_read_remaining */ -static int php_iptc_read_remaining(FILE *fp, int spool, unsigned char **spoolbuf) +static int php_iptc_read_remaining(FILE *fp, int spool, unsigned char **spoolbuf, const unsigned char *spoolbuf_end) { - while (php_iptc_get1(fp, spool, spoolbuf) != EOF) continue; + while (php_iptc_get1(fp, spool, spoolbuf, spoolbuf_end) != EOF) continue; return M_EOI; } /* }}} */ /* {{{ php_iptc_skip_variable */ -static int php_iptc_skip_variable(FILE *fp, int spool, unsigned char **spoolbuf) +static int php_iptc_skip_variable(FILE *fp, int spool, unsigned char **spoolbuf, const unsigned char *spoolbuf_end) { unsigned int length; int c1, c2; - if ((c1 = php_iptc_get1(fp, spool, spoolbuf)) == EOF) return M_EOI; + if ((c1 = php_iptc_get1(fp, spool, spoolbuf, spoolbuf_end)) == EOF) return M_EOI; - if ((c2 = php_iptc_get1(fp, spool, spoolbuf)) == EOF) return M_EOI; + if ((c2 = php_iptc_get1(fp, spool, spoolbuf, spoolbuf_end)) == EOF) return M_EOI; length = (((unsigned char) c1) << 8) + ((unsigned char) c2); length -= 2; while (length--) - if (php_iptc_get1(fp, spool, spoolbuf) == EOF) return M_EOI; + if (php_iptc_get1(fp, spool, spoolbuf, spoolbuf_end) == EOF) return M_EOI; return 0; } /* }}} */ /* {{{ php_iptc_next_marker */ -static int php_iptc_next_marker(FILE *fp, int spool, unsigned char **spoolbuf) +static int php_iptc_next_marker(FILE *fp, int spool, unsigned char **spoolbuf, const unsigned char *spoolbuf_end) { int c; /* skip unimportant stuff */ - c = php_iptc_get1(fp, spool, spoolbuf); + c = php_iptc_get1(fp, spool, spoolbuf, spoolbuf_end); if (c == EOF) return M_EOI; while (c != 0xff) { - if ((c = php_iptc_get1(fp, spool, spoolbuf)) == EOF) + if ((c = php_iptc_get1(fp, spool, spoolbuf, spoolbuf_end)) == EOF) return M_EOI; /* we hit EOF */ } /* get marker byte, swallowing possible padding */ do { - c = php_iptc_get1(fp, 0, 0); + c = php_iptc_get1(fp, 0, 0, NULL); if (c == EOF) return M_EOI; /* we hit EOF */ else if (c == 0xff) - php_iptc_put1(fp, spool, (unsigned char)c, spoolbuf); + php_iptc_put1(fp, spool, (unsigned char)c, spoolbuf, spoolbuf_end); } while (c == 0xff); return (unsigned int) c; @@ -178,6 +186,7 @@ PHP_FUNCTION(iptcembed) size_t inx; zend_string *spoolbuf = NULL; unsigned char *poi = NULL; + unsigned char *spoolbuf_end = NULL; zend_stat_t sb = {0}; bool written = 0; @@ -210,10 +219,11 @@ PHP_FUNCTION(iptcembed) spoolbuf = zend_string_safe_alloc(1, iptcdata_len + sizeof(psheader) + 1024 + 1, sb.st_size, 0); poi = (unsigned char*)ZSTR_VAL(spoolbuf); + spoolbuf_end = poi + ZSTR_LEN(spoolbuf); memset(poi, 0, iptcdata_len + sizeof(psheader) + sb.st_size + 1024 + 1); } - if (php_iptc_get1(fp, spool, poi?&poi:0) != 0xFF) { + if (php_iptc_get1(fp, spool, poi?&poi:0, spoolbuf_end) != 0xFF) { fclose(fp); if (spoolbuf) { zend_string_efree(spoolbuf); @@ -221,7 +231,8 @@ PHP_FUNCTION(iptcembed) RETURN_FALSE; } - if (php_iptc_get1(fp, spool, poi?&poi:0) != 0xD8) { + if (php_iptc_get1(fp, spool, poi?&poi:0, spoolbuf_end) != 0xD8) { +err: fclose(fp); if (spoolbuf) { zend_string_efree(spoolbuf); @@ -230,20 +241,22 @@ PHP_FUNCTION(iptcembed) } while (!done) { - marker = php_iptc_next_marker(fp, spool, poi?&poi:0); + marker = php_iptc_next_marker(fp, spool, poi?&poi:0, spoolbuf_end); if (marker == M_EOI) { /* EOF */ break; } else if (marker != M_APP13) { - php_iptc_put1(fp, spool, (unsigned char)marker, poi?&poi:0); + if (php_iptc_put1(fp, spool, (unsigned char)marker, poi?&poi:0, spoolbuf_end) < 0) { + goto err; + } } switch (marker) { case M_APP13: /* we are going to write a new APP13 marker, so don't output the old one */ - php_iptc_skip_variable(fp, 0, 0); + php_iptc_skip_variable(fp, 0, 0, spoolbuf_end); fgetc(fp); /* skip already copied 0xFF byte */ - php_iptc_read_remaining(fp, spool, poi?&poi:0); + php_iptc_read_remaining(fp, spool, poi?&poi:0, spoolbuf_end); done = 1; break; @@ -256,7 +269,7 @@ PHP_FUNCTION(iptcembed) } written = 1; - php_iptc_skip_variable(fp, spool, poi?&poi:0); + php_iptc_skip_variable(fp, spool, poi?&poi:0, spoolbuf_end); if (iptcdata_len & 1) { iptcdata_len++; /* make the length even */ @@ -266,25 +279,33 @@ PHP_FUNCTION(iptcembed) psheader[ 3 ] = (iptcdata_len+28)&0xff; for (inx = 0; inx < 28; inx++) { - php_iptc_put1(fp, spool, psheader[inx], poi?&poi:0); + if (php_iptc_put1(fp, spool, psheader[inx], poi?&poi:0, spoolbuf_end) < 0) { + goto err; + } } - php_iptc_put1(fp, spool, (unsigned char)(iptcdata_len>>8), poi?&poi:0); - php_iptc_put1(fp, spool, (unsigned char)(iptcdata_len&0xff), poi?&poi:0); + if (php_iptc_put1(fp, spool, (unsigned char)(iptcdata_len>>8), poi?&poi:0, spoolbuf_end) < 0) { + goto err; + } + if (php_iptc_put1(fp, spool, (unsigned char)(iptcdata_len&0xff), poi?&poi:0, spoolbuf_end) < 0) { + goto err; + } for (inx = 0; inx < iptcdata_len; inx++) { - php_iptc_put1(fp, spool, iptcdata[inx], poi?&poi:0); + if (php_iptc_put1(fp, spool, iptcdata[inx], poi?&poi:0, spoolbuf_end) < 0) { + goto err; + } } break; case M_SOS: /* we hit data, no more marker-inserting can be done! */ - php_iptc_read_remaining(fp, spool, poi?&poi:0); + php_iptc_read_remaining(fp, spool, poi?&poi:0, spoolbuf_end); done = 1; break; default: - php_iptc_skip_variable(fp, spool, poi?&poi:0); + php_iptc_skip_variable(fp, spool, poi?&poi:0, spoolbuf_end); break; } } @@ -292,6 +313,7 @@ PHP_FUNCTION(iptcembed) fclose(fp); if (spool < 2) { + *poi = '\0'; spoolbuf = zend_string_truncate(spoolbuf, poi - (unsigned char*)ZSTR_VAL(spoolbuf), 0); RETURN_NEW_STR(spoolbuf); } else { @@ -308,7 +330,6 @@ PHP_FUNCTION(iptcparse) unsigned char *buffer, recnum, dataset; char *str, key[16]; size_t str_len; - zval values, *element; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STRING(str, str_len) @@ -357,10 +378,9 @@ PHP_FUNCTION(iptcparse) array_init(return_value); } - if ((element = zend_hash_str_find(Z_ARRVAL_P(return_value), key, strlen(key))) == NULL) { - array_init(&values); - - element = zend_hash_str_update(Z_ARRVAL_P(return_value), key, strlen(key), &values); + zval *element = zend_hash_str_lookup(Z_ARRVAL_P(return_value), key, strlen(key)); + if (Z_ISNULL_P(element)) { + array_init(element); } add_next_index_stringl(element, (char *) buffer+inx, len); diff --git a/ext/standard/levenshtein.c b/ext/standard/levenshtein.c index d4688dcb9c13..efc71d2a2828 100644 --- a/ext/standard/levenshtein.c +++ b/ext/standard/levenshtein.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Hartmut Holzgraefe | +----------------------------------------------------------------------+ diff --git a/ext/standard/libavifinfo/README.md b/ext/standard/libavifinfo/README.md index a08c29067f4b..945f2282b6ec 100644 --- a/ext/standard/libavifinfo/README.md +++ b/ext/standard/libavifinfo/README.md @@ -7,5 +7,5 @@ partially parse an AVIF payload and to extract the width, height, bit depth and channel count without depending on the full libavif library. `avifinfo.h`, `avifinfo.c`, `LICENSE` and `PATENTS` were copied verbatim from: \ -https://aomedia.googlesource.com/libavifinfo/+/96f34d945ac7dac229feddfa94dbae66e202b838 \ +https://aomedia.googlesource.com/libavifinfo/+/2b924defa4c2cd227540efe164067a8cc913eeba \ They can easily be kept up-to-date the same way. diff --git a/ext/standard/libavifinfo/avifinfo.c b/ext/standard/libavifinfo/avifinfo.c index 5b93d1997be3..f8f7a04697f0 100644 --- a/ext/standard/libavifinfo/avifinfo.c +++ b/ext/standard/libavifinfo/avifinfo.c @@ -34,14 +34,15 @@ static AvifInfoStatus AvifInfoInternalConvertStatus(AvifInfoInternalStatus s) { // uint32_t is used everywhere in this file. It is unlikely to be insufficient // to parse AVIF headers. #define AVIFINFO_MAX_SIZE UINT32_MAX -// AvifInfoInternalFeatures uses uint8_t to store values and the number of -// values is clamped to 32 to limit the stack size. +// Be reasonable. Avoid timeouts and out-of-memory. +#define AVIFINFO_MAX_NUM_BOXES 4096 +// AvifInfoInternalFeatures uses uint8_t to store values. #define AVIFINFO_MAX_VALUE UINT8_MAX -#define AVIFINFO_UNDEFINED 0 // Maximum number of stored associations. Past that, they are skipped. #define AVIFINFO_MAX_TILES 16 #define AVIFINFO_MAX_PROPS 32 #define AVIFINFO_MAX_FEATURES 8 +#define AVIFINFO_UNDEFINED 0 // Reads an unsigned integer from 'input' with most significant bits first. // 'input' must be at least 'num_bytes'-long. @@ -93,6 +94,12 @@ static void AvifInfoInternalLogError(const char* file, int line, #define AVIFINFO_CHECK_NOT_FOUND(check_status) \ AVIFINFO_CHECK_STATUS_IS((check_status), kNotFound) +#if defined(AVIFINFO_ENABLE_DEBUG_LOG) +#define AVIF_DEBUG_LOG(...) printf(__VA_ARGS__) +#else +#define AVIF_DEBUG_LOG(...) +#endif + //------------------------------------------------------------------------------ // Streamed input struct and helper functions. @@ -101,6 +108,7 @@ typedef struct { read_stream_t read; // Used to fetch more bytes from the 'stream'. skip_stream_t skip; // Used to advance the position in the 'stream'. // Fallback to 'read' if 'skip' is null. + uint64_t num_read_bytes; // Number of bytes read or skipped. } AvifInfoInternalStream; // Reads 'num_bytes' from the 'stream'. They are available at '*data'. @@ -109,6 +117,7 @@ static AvifInfoInternalStatus AvifInfoInternalRead( AvifInfoInternalStream* stream, uint32_t num_bytes, const uint8_t** data) { *data = stream->read(stream->stream, num_bytes); AVIFINFO_CHECK(*data != NULL, kTruncated); + stream->num_read_bytes += num_bytes; return kFound; } @@ -127,6 +136,7 @@ static AvifInfoInternalStatus AvifInfoInternalSkip( return AvifInfoInternalRead(stream, num_bytes, &unused); } stream->skip(stream->stream, num_bytes); + stream->num_read_bytes += num_bytes; } return kFound; } @@ -137,6 +147,7 @@ static AvifInfoInternalStatus AvifInfoInternalSkip( typedef struct { uint8_t tile_item_id; uint8_t parent_item_id; + uint8_t dimg_idx; // Index of this association in the dimg box (0-based). } AvifInfoInternalTile; // Tile item id <-> parent item id associations. typedef struct { @@ -156,10 +167,15 @@ typedef struct { typedef struct { uint8_t has_primary_item; // True if "pitm" was parsed. - uint8_t has_alpha; // True if an alpha "auxC" was parsed. + uint8_t has_alpha; // True if an alpha "auxC" was parsed. + // Index of the gain map auxC property. + uint8_t gainmap_property_index; uint8_t primary_item_id; AvifInfoFeatures primary_item_features; // Deduced from the data below. uint8_t data_was_skipped; // True if some loops/indices were skipped. + uint8_t tone_mapped_item_id; // Id of the "tmap" box, > 0 if present. + uint8_t iinf_parsed; // True if the "iinf" (item info) box was parsed. + uint8_t iref_parsed; // True if the "iref" (item reference) box was parsed. uint8_t num_tiles; AvifInfoInternalTile tiles[AVIFINFO_MAX_TILES]; @@ -227,6 +243,36 @@ static AvifInfoInternalStatus AvifInfoInternalGetPrimaryItemFeatures( AVIFINFO_CHECK(f->has_primary_item, kNotFound); // Early exit. AVIFINFO_CHECK(f->num_dim_props > 0 && f->num_chan_props, kNotFound); + + // Look for a gain map. + // HEIF scheme: gain map is a hidden input of a derived item. + if (f->tone_mapped_item_id) { + for (uint32_t tile = 0; tile < f->num_tiles; ++tile) { + if (f->tiles[tile].parent_item_id == f->tone_mapped_item_id && + f->tiles[tile].dimg_idx == 1) { + f->primary_item_features.has_gainmap = 1; + f->primary_item_features.gainmap_item_id = f->tiles[tile].tile_item_id; + break; + } + } + } + // Adobe scheme: gain map is an auxiliary item. + if (!f->primary_item_features.has_gainmap && f->gainmap_property_index > 0) { + for (uint32_t prop_item = 0; prop_item < f->num_props; ++prop_item) { + if (f->props[prop_item].property_index == f->gainmap_property_index) { + f->primary_item_features.has_gainmap = 1; + f->primary_item_features.gainmap_item_id = f->props[prop_item].item_id; + break; + } + } + } + // If the gain map has not been found but we haven't read all the relevant + // metadata, we might still find one later and cannot stop now. + if (!f->primary_item_features.has_gainmap && + (!f->iinf_parsed || (f->tone_mapped_item_id && !f->iref_parsed))) { + return kNotFound; + } + AVIFINFO_CHECK_FOUND( AvifInfoInternalGetItemFeatures(f, f->primary_item_id, /*tile_depth=*/0)); @@ -250,8 +296,9 @@ typedef struct { // 'num_remaining_bytes' is the remaining size of the container of the 'box' // (either the file size itself or the content size of the parent of the 'box'). static AvifInfoInternalStatus AvifInfoInternalParseBox( - AvifInfoInternalStream* stream, uint32_t num_remaining_bytes, - uint32_t* num_parsed_boxes, AvifInfoInternalBox* box) { + int nesting_level, AvifInfoInternalStream* stream, + uint32_t num_remaining_bytes, uint32_t* num_parsed_boxes, + AvifInfoInternalBox* box) { const uint8_t* data; // See ISO/IEC 14496-12:2012(E) 4.2 uint32_t box_header_size = 8; // box 32b size + 32b type (at least) @@ -271,22 +318,38 @@ static AvifInfoInternalStatus AvifInfoInternalParseBox( // Read the 32 least-significant bits. box->size = AvifInfoInternalReadBigEndian(data + 4, sizeof(uint32_t)); } else if (box->size == 0) { + // ISO/IEC 14496-12 4.2.2: + // if size is 0, then this box shall be in a top-level box + // (i.e. not contained in another box) + AVIFINFO_CHECK(nesting_level == 0, kInvalid); box->size = num_remaining_bytes; } AVIFINFO_CHECK(box->size >= box_header_size, kInvalid); AVIFINFO_CHECK(box->size <= num_remaining_bytes, kInvalid); + // 16 bytes of usertype should be read here if the box type is 'uuid'. + // 'uuid' boxes are skipped so usertype is part of the skipped body. + const int has_fullbox_header = !memcmp(box->type, "meta", 4) || !memcmp(box->type, "pitm", 4) || !memcmp(box->type, "ipma", 4) || !memcmp(box->type, "ispe", 4) || !memcmp(box->type, "pixi", 4) || !memcmp(box->type, "iref", 4) || - !memcmp(box->type, "auxC", 4); + !memcmp(box->type, "auxC", 4) || !memcmp(box->type, "iinf", 4) || + !memcmp(box->type, "infe", 4); if (has_fullbox_header) box_header_size += 4; AVIFINFO_CHECK(box->size >= box_header_size, kInvalid); box->content_size = box->size - box_header_size; - // Avoid timeouts. The maximum number of parsed boxes is arbitrary. - ++*num_parsed_boxes; - AVIFINFO_CHECK(*num_parsed_boxes < 4096, kAborted); + // AvifInfoGetFeaturesStream() can be called on a full stream or on a stream + // where the 'ftyp' box was already read. Do not count 'ftyp' boxes towards + // AVIFINFO_MAX_NUM_BOXES, so that this function returns the same status in + // both situations (because of the AVIFINFO_MAX_NUM_BOXES check that would + // compare a different box count otherwise). This is fine because top-level + // 'ftyp' boxes are just skipped anyway. + if (nesting_level != 0 || memcmp(box->type, "ftyp", 4)) { + // Avoid timeouts. The maximum number of parsed boxes is arbitrary. + ++*num_parsed_boxes; + AVIFINFO_CHECK(*num_parsed_boxes < AVIFINFO_MAX_NUM_BOXES, kAborted); + } box->version = 0; box->flags = 0; @@ -297,17 +360,22 @@ static AvifInfoInternalStatus AvifInfoInternalParseBox( // See AV1 Image File Format (AVIF) 8.1 // at https://aomediacodec.github.io/av1-avif/#avif-boxes (available when // https://github.com/AOMediaCodec/av1-avif/pull/170 is merged). - uint32_t is_parsable = 1; - if (!memcmp(box->type, "meta", 4)) is_parsable = (box->version <= 0); - if (!memcmp(box->type, "pitm", 4)) is_parsable = (box->version <= 1); - if (!memcmp(box->type, "ipma", 4)) is_parsable = (box->version <= 1); - if (!memcmp(box->type, "ispe", 4)) is_parsable = (box->version <= 0); - if (!memcmp(box->type, "pixi", 4)) is_parsable = (box->version <= 0); - if (!memcmp(box->type, "iref", 4)) is_parsable = (box->version <= 1); - if (!memcmp(box->type, "auxC", 4)) is_parsable = (box->version <= 0); + const uint32_t is_parsable = + (!memcmp(box->type, "meta", 4) && box->version <= 0) || + (!memcmp(box->type, "pitm", 4) && box->version <= 1) || + (!memcmp(box->type, "ipma", 4) && box->version <= 1) || + (!memcmp(box->type, "ispe", 4) && box->version <= 0) || + (!memcmp(box->type, "pixi", 4) && box->version <= 0) || + (!memcmp(box->type, "iref", 4) && box->version <= 1) || + (!memcmp(box->type, "auxC", 4) && box->version <= 0) || + (!memcmp(box->type, "iinf", 4) && box->version <= 1) || + (!memcmp(box->type, "infe", 4) && box->version >= 2 && + box->version <= 3); // Instead of considering this file as invalid, skip unparsable boxes. - if (!is_parsable) memcpy(box->type, "\0skp", 4); // \0 so not a valid type + if (!is_parsable) memcpy(box->type, "skip", 4); // FreeSpaceBox } + AVIF_DEBUG_LOG("%*c", nesting_level * 2, ' '); + AVIF_DEBUG_LOG("Box type %.4s size %d\n", box->type, box->size); return kFound; } @@ -316,15 +384,16 @@ static AvifInfoInternalStatus AvifInfoInternalParseBox( // Parses a 'stream' of an "ipco" box into 'features'. // "ispe" is used for width and height, "pixi" and "av1C" are used for bit depth // and number of channels, and "auxC" is used for alpha. -static AvifInfoInternalStatus ParseIpco(AvifInfoInternalStream* stream, +static AvifInfoInternalStatus ParseIpco(int nesting_level, + AvifInfoInternalStream* stream, uint32_t num_remaining_bytes, uint32_t* num_parsed_boxes, AvifInfoInternalFeatures* features) { uint32_t box_index = 1; // 1-based index. Used for iterating over properties. do { AvifInfoInternalBox box; - AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, num_remaining_bytes, - num_parsed_boxes, &box)); + AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox( + nesting_level, stream, num_remaining_bytes, num_parsed_boxes, &box)); if (!memcmp(box.type, "ispe", 4)) { // See ISO/IEC 23008-12:2017(E) 6.5.3.2 @@ -407,21 +476,43 @@ static AvifInfoInternalStatus ParseIpco(AvifInfoInternalStream* stream, // at https://aomediacodec.github.io/av1-avif/#auxiliary-images const char* kAlphaStr = "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha"; const uint32_t kAlphaStrLength = 44; // Includes terminating character. - if (box.content_size >= kAlphaStrLength) { + const char* kGainmapStr = "urn:com:photo:aux:hdrgainmap"; + const uint32_t kGainmapStrLength = 29; // Includes terminating character. + uint32_t num_read_bytes = 0; + // Check for a gain map or for an alpha plane. Start with the gain map + // since the identifier is shorter. + if (box.content_size >= kGainmapStrLength) { const uint8_t* data; AVIFINFO_CHECK_FOUND( - AvifInfoInternalRead(stream, kAlphaStrLength, &data)); + AvifInfoInternalRead(stream, kGainmapStrLength, &data)); + num_read_bytes = kGainmapStrLength; const char* const aux_type = (const char*)data; - if (strcmp(aux_type, kAlphaStr) == 0) { - // Note: It is unlikely but it is possible that this alpha plane does - // not belong to the primary item or a tile. Ignore this issue. - features->has_alpha = 1; + if (strcmp(aux_type, kGainmapStr) == 0) { + // Note: It is unlikely but it is possible that this gain map + // does not belong to the primary item or a tile. Ignore this issue. + if (box_index <= AVIFINFO_MAX_VALUE) { + features->gainmap_property_index = (uint8_t)box_index; + } else { + features->data_was_skipped = 1; + } + } else if (box.content_size >= kAlphaStrLength && + memcmp(aux_type, kAlphaStr, kGainmapStrLength) == 0) { + // The beginning of the aux type matches the alpha aux type string. + // Check the end as well. + const uint8_t* data2; + const uint32_t kEndLength = kAlphaStrLength - kGainmapStrLength; + AVIFINFO_CHECK_FOUND( + AvifInfoInternalRead(stream, kEndLength, &data2)); + num_read_bytes = kAlphaStrLength; + if (strcmp((const char*)data2, &kAlphaStr[kGainmapStrLength]) == 0) { + // Note: It is unlikely but it is possible that this alpha plane + // does not belong to the primary item or a tile. Ignore this issue. + features->has_alpha = 1; + } } - AVIFINFO_CHECK_FOUND( - AvifInfoInternalSkip(stream, box.content_size - kAlphaStrLength)); - } else { - AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, box.content_size)); } + AVIFINFO_CHECK_FOUND( + AvifInfoInternalSkip(stream, box.content_size - num_read_bytes)); } else { AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, box.content_size)); } @@ -431,20 +522,22 @@ static AvifInfoInternalStatus ParseIpco(AvifInfoInternalStream* stream, AVIFINFO_RETURN(kNotFound); } -// Parses a 'stream' of an "iprp" box into 'features'. The "ipco" box contain +// Parses a 'stream' of an "iprp" box into 'features'. The "ipco" box contains // the properties which are linked to items by the "ipma" box. -static AvifInfoInternalStatus ParseIprp(AvifInfoInternalStream* stream, +static AvifInfoInternalStatus ParseIprp(int nesting_level, + AvifInfoInternalStream* stream, uint32_t num_remaining_bytes, uint32_t* num_parsed_boxes, AvifInfoInternalFeatures* features) { do { AvifInfoInternalBox box; - AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, num_remaining_bytes, - num_parsed_boxes, &box)); + AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox( + nesting_level, stream, num_remaining_bytes, num_parsed_boxes, &box)); if (!memcmp(box.type, "ipco", 4)) { - AVIFINFO_CHECK_NOT_FOUND( - ParseIpco(stream, box.content_size, num_parsed_boxes, features)); + AVIFINFO_CHECK_NOT_FOUND(ParseIpco(nesting_level + 1, stream, + box.content_size, num_parsed_boxes, + features)); } else if (!memcmp(box.type, "ipma", 4)) { // See ISO/IEC 23008-12:2017(E) 9.3.2 uint32_t num_read_bytes = 4; @@ -503,6 +596,7 @@ static AvifInfoInternalStatus ParseIprp(AvifInfoInternalStream* stream, AVIFINFO_CHECK_NOT_FOUND( AvifInfoInternalGetPrimaryItemFeatures(features)); + // Mostly if 'data_was_skipped'. AVIFINFO_CHECK_FOUND( AvifInfoInternalSkip(stream, box.content_size - num_read_bytes)); } else { @@ -519,14 +613,17 @@ static AvifInfoInternalStatus ParseIprp(AvifInfoInternalStream* stream, // The "dimg" boxes contain links between tiles and their parent items, which // can be used to infer bit depth and number of channels for the primary item // when the latter does not have these properties. -static AvifInfoInternalStatus ParseIref(AvifInfoInternalStream* stream, +static AvifInfoInternalStatus ParseIref(int nesting_level, + AvifInfoInternalStream* stream, uint32_t num_remaining_bytes, uint32_t* num_parsed_boxes, AvifInfoInternalFeatures* features) { - do { + features->iref_parsed = 1; + + while (num_remaining_bytes > 0) { AvifInfoInternalBox box; - AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, num_remaining_bytes, - num_parsed_boxes, &box)); + AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox( + nesting_level, stream, num_remaining_bytes, num_parsed_boxes, &box)); if (!memcmp(box.type, "dimg", 4)) { // See ISO/IEC 14496-12:2015(E) 8.11.12.2 @@ -557,6 +654,7 @@ static AvifInfoInternalStatus ParseIref(AvifInfoInternalStream* stream, features->num_tiles < AVIFINFO_MAX_TILES) { features->tiles[features->num_tiles].tile_item_id = to_item_id; features->tiles[features->num_tiles].parent_item_id = from_item_id; + features->tiles[features->num_tiles].dimg_idx = i; ++features->num_tiles; } else { features->data_was_skipped = 1; @@ -566,11 +664,77 @@ static AvifInfoInternalStatus ParseIref(AvifInfoInternalStream* stream, // If all features are available now, do not look further. AVIFINFO_CHECK_NOT_FOUND( AvifInfoInternalGetPrimaryItemFeatures(features)); + + // Mostly if 'data_was_skipped'. + AVIFINFO_CHECK_FOUND( + AvifInfoInternalSkip(stream, box.content_size - num_read_bytes)); } else { AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, box.content_size)); } num_remaining_bytes -= box.size; - } while (num_remaining_bytes > 0); + } + AVIFINFO_RETURN(kNotFound); +} + +//------------------------------------------------------------------------------ + +// Parses a 'stream' of an "iinf" box into 'features'. +static AvifInfoInternalStatus ParseIinf(int nesting_level, + AvifInfoInternalStream* stream, + uint32_t num_remaining_bytes, + uint32_t box_version, + uint32_t* num_parsed_boxes, + AvifInfoInternalFeatures* features) { + features->iinf_parsed = 1; + + const uint32_t num_bytes_per_entry_count = box_version == 0 ? 2 : 4; + AVIFINFO_CHECK(num_bytes_per_entry_count <= num_remaining_bytes, kInvalid); + const uint8_t* data; + AVIFINFO_CHECK_FOUND( + AvifInfoInternalRead(stream, num_bytes_per_entry_count, &data)); + num_remaining_bytes -= num_bytes_per_entry_count; + const uint32_t entry_count = + AvifInfoInternalReadBigEndian(data, num_bytes_per_entry_count); + + for (int i = 0; i < entry_count; ++i) { + AvifInfoInternalBox box; + AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox( + nesting_level, stream, num_remaining_bytes, num_parsed_boxes, &box)); + + if (!memcmp(box.type, "infe", 4)) { + // See ISO/IEC 14496-12:2015(E) 8.11.6.2 + const uint32_t num_bytes_per_id = (box.version == 2) ? 2 : 4; + const uint8_t* data; + // item_ID (16 or 32) + item_protection_index (16) + item_type (32). + AVIFINFO_CHECK(num_bytes_per_id + 2 + 4 <= box.content_size, kInvalid); + AVIFINFO_CHECK_FOUND( + AvifInfoInternalRead(stream, num_bytes_per_id, &data)); + const uint32_t item_id = + AvifInfoInternalReadBigEndian(data, num_bytes_per_id); + + // Skip item_protection_index. + AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, 2)); + + const uint8_t* item_type; + AVIFINFO_CHECK_FOUND(AvifInfoInternalRead(stream, 4, &item_type)); + if (!memcmp(item_type, "tmap", 4)) { + // Tone Mapped Image: indicates the presence of a gain map. + if (item_id <= AVIFINFO_MAX_VALUE) { + features->tone_mapped_item_id = (uint8_t)item_id; + } else { + features->data_was_skipped = 1; + } + } + + AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip( + stream, box.content_size - (num_bytes_per_id + 2 + 4))); + } else { + AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, box.content_size)); + } + + num_remaining_bytes -= box.size; + if (num_remaining_bytes == 0) break; // Ignore entry_count bigger than box. + } AVIFINFO_RETURN(kNotFound); } @@ -578,18 +742,19 @@ static AvifInfoInternalStatus ParseIref(AvifInfoInternalStream* stream, // Parses a 'stream' of a "meta" box. It looks for the primary item ID in the // "pitm" box and recurses into other boxes to find its 'features'. -static AvifInfoInternalStatus ParseMeta(AvifInfoInternalStream* stream, +static AvifInfoInternalStatus ParseMeta(int nesting_level, + AvifInfoInternalStream* stream, uint32_t num_remaining_bytes, uint32_t* num_parsed_boxes, AvifInfoInternalFeatures* features) { do { AvifInfoInternalBox box; - AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, num_remaining_bytes, - num_parsed_boxes, &box)); - + AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox( + nesting_level, stream, num_remaining_bytes, num_parsed_boxes, &box)); if (!memcmp(box.type, "pitm", 4)) { // See ISO/IEC 14496-12:2015(E) 8.11.4.2 const uint32_t num_bytes_per_id = (box.version == 0) ? 2 : 4; + const uint64_t primary_item_id_location = stream->num_read_bytes; const uint8_t* data; AVIFINFO_CHECK(num_bytes_per_id <= num_remaining_bytes, kInvalid); AVIFINFO_CHECK_FOUND( @@ -599,14 +764,23 @@ static AvifInfoInternalStatus ParseMeta(AvifInfoInternalStream* stream, AVIFINFO_CHECK(primary_item_id <= AVIFINFO_MAX_VALUE, kAborted); features->has_primary_item = 1; features->primary_item_id = primary_item_id; + features->primary_item_features.primary_item_id_location = + primary_item_id_location; + features->primary_item_features.primary_item_id_bytes = num_bytes_per_id; AVIFINFO_CHECK_FOUND( AvifInfoInternalSkip(stream, box.content_size - num_bytes_per_id)); } else if (!memcmp(box.type, "iprp", 4)) { - AVIFINFO_CHECK_NOT_FOUND( - ParseIprp(stream, box.content_size, num_parsed_boxes, features)); + AVIFINFO_CHECK_NOT_FOUND(ParseIprp(nesting_level + 1, stream, + box.content_size, num_parsed_boxes, + features)); } else if (!memcmp(box.type, "iref", 4)) { - AVIFINFO_CHECK_NOT_FOUND( - ParseIref(stream, box.content_size, num_parsed_boxes, features)); + AVIFINFO_CHECK_NOT_FOUND(ParseIref(nesting_level + 1, stream, + box.content_size, num_parsed_boxes, + features)); + } else if (!memcmp(box.type, "iinf", 4)) { + AVIFINFO_CHECK_NOT_FOUND(ParseIinf(nesting_level + 1, stream, + box.content_size, box.version, + num_parsed_boxes, features)); } else { AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, box.content_size)); } @@ -622,8 +796,9 @@ static AvifInfoInternalStatus ParseMeta(AvifInfoInternalStream* stream, static AvifInfoInternalStatus ParseFtyp(AvifInfoInternalStream* stream) { AvifInfoInternalBox box; uint32_t num_parsed_boxes = 0; - AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, AVIFINFO_MAX_SIZE, - &num_parsed_boxes, &box)); + const int nesting_level = 0; + AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox( + nesting_level, stream, AVIFINFO_MAX_SIZE, &num_parsed_boxes, &box)); AVIFINFO_CHECK(!memcmp(box.type, "ftyp", 4), kInvalid); // Iterate over brands. See ISO/IEC 14496-12:2012(E) 4.3.1 AVIFINFO_CHECK(box.content_size >= 8, kInvalid); // major_brand,minor_version @@ -647,15 +822,16 @@ static AvifInfoInternalStatus ParseFile(AvifInfoInternalStream* stream, AvifInfoInternalFeatures* features) { while (1) { AvifInfoInternalBox box; - AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox(stream, AVIFINFO_MAX_SIZE, - num_parsed_boxes, &box)); + AVIFINFO_CHECK_FOUND(AvifInfoInternalParseBox( + /*nesting_level=*/0, stream, AVIFINFO_MAX_SIZE, num_parsed_boxes, + &box)); if (!memcmp(box.type, "meta", 4)) { - return ParseMeta(stream, box.content_size, num_parsed_boxes, features); + return ParseMeta(/*nesting_level=*/1, stream, box.content_size, + num_parsed_boxes, features); } else { AVIFINFO_CHECK_FOUND(AvifInfoInternalSkip(stream, box.content_size)); } } - AVIFINFO_RETURN(kInvalid); // No "meta" no good. } //------------------------------------------------------------------------------ @@ -698,6 +874,11 @@ AvifInfoStatus AvifInfoIdentify(const uint8_t* data, size_t data_size) { AvifInfoStatus AvifInfoGetFeatures(const uint8_t* data, size_t data_size, AvifInfoFeatures* features) { + const AvifInfoStatus status = AvifInfoIdentify(data, data_size); + if (status != kAvifInfoOk) { + if (features != NULL) memset(features, 0, sizeof(*features)); + return status; + } AvifInfoInternalForward stream; stream.data = data; stream.data_size = data_size; @@ -710,19 +891,20 @@ AvifInfoStatus AvifInfoGetFeatures(const uint8_t* data, size_t data_size, // Streamed input API AvifInfoStatus AvifInfoIdentifyStream(void* stream, read_stream_t read, - skip_stream_t skip) { + skip_stream_t skip) { if (read == NULL) return kAvifInfoNotEnoughData; AvifInfoInternalStream internal_stream; internal_stream.stream = stream; internal_stream.read = read; internal_stream.skip = skip; // Fallbacks to 'read' if null. + internal_stream.num_read_bytes = 0; return AvifInfoInternalConvertStatus(ParseFtyp(&internal_stream)); } AvifInfoStatus AvifInfoGetFeaturesStream(void* stream, read_stream_t read, - skip_stream_t skip, - AvifInfoFeatures* features) { + skip_stream_t skip, + AvifInfoFeatures* features) { if (features != NULL) memset(features, 0, sizeof(*features)); if (read == NULL) return kAvifInfoNotEnoughData; @@ -730,6 +912,7 @@ AvifInfoStatus AvifInfoGetFeaturesStream(void* stream, read_stream_t read, internal_stream.stream = stream; internal_stream.read = read; internal_stream.skip = skip; // Fallbacks to 'read' if null. + internal_stream.num_read_bytes = 0; uint32_t num_parsed_boxes = 0; AvifInfoInternalFeatures internal_features; memset(&internal_features, AVIFINFO_UNDEFINED, sizeof(internal_features)); diff --git a/ext/standard/libavifinfo/avifinfo.h b/ext/standard/libavifinfo/avifinfo.h index 4c898c2efcc5..bc17df19a558 100644 --- a/ext/standard/libavifinfo/avifinfo.h +++ b/ext/standard/libavifinfo/avifinfo.h @@ -35,10 +35,22 @@ typedef enum { } AvifInfoStatus; typedef struct { - uint32_t width, height; // In number of pixels. Ignores mirror and rotation. - uint32_t bit_depth; // Likely 8, 10 or 12 bits per channel per pixel. - uint32_t num_channels; // Likely 1, 2, 3 or 4 channels: - // (1 monochrome or 3 colors) + (0 or 1 alpha) + uint32_t width, height; // In number of pixels. Ignores crop and rotation. + uint32_t bit_depth; // Likely 8, 10 or 12 bits per channel per pixel. + uint32_t num_channels; // Likely 1, 2, 3 or 4 channels: + // (1 monochrome or 3 colors) + (0 or 1 alpha) + uint8_t has_gainmap; // True if a gain map was found. + // Id of the gain map item. Assumes there is at most one. If there are several + // gain map items (e.g. because the main image is tiled and each tile has an + // independent gain map), then this is one of the ids, arbitrarily chosen. + uint8_t gainmap_item_id; + // Start location in bytes of the primary item id, relative to the beginning + // of the given payload. The primary item id is a big endian number stored on + // bytes primary_item_id_location to + // primary_item_id_location+primary_item_id_bytes-1 inclusive. + uint64_t primary_item_id_location; + // Number of bytes of the primary item id. + uint8_t primary_item_id_bytes; } AvifInfoFeatures; //------------------------------------------------------------------------------ @@ -46,13 +58,19 @@ typedef struct { // Use this API if a raw byte array of fixed size is available as input. // Parses the 'data' and returns kAvifInfoOk if it is identified as an AVIF. +// 'data' can be partial but must point to the beginning of the AVIF file. // The file type can be identified in the first 12 bytes of most AVIF files. AvifInfoStatus AvifInfoIdentify(const uint8_t* data, size_t data_size); -// Parses the identified AVIF 'data' and extracts its 'features'. +// Parses the 'data' and returns kAvifInfoOk and its 'features' if it is +// identified as an AVIF file. // 'data' can be partial but must point to the beginning of the AVIF file. // The 'features' can be parsed in the first 450 bytes of most AVIF files. // 'features' are set to 0 unless kAvifInfoOk is returned. +// There is no need to call AvifInfoIdentify() before AvifInfoGetFeatures(). +// AvifInfoGetFeatures() parses the file further than AvifInfoIdentify() so it +// is possible that AvifInfoGetFeatures() returns errors while +// AvifInfoIdentify() returns kAvifInfoOk on the same given input bytes. AvifInfoStatus AvifInfoGetFeatures(const uint8_t* data, size_t data_size, AvifInfoFeatures* features); @@ -78,7 +96,15 @@ typedef void (*skip_stream_t)(void* stream, size_t num_bytes); // 'read' cannot be null. If 'skip' is null, 'read' is called instead. AvifInfoStatus AvifInfoIdentifyStream(void* stream, read_stream_t read, skip_stream_t skip); -// Can be called right after AvifInfoIdentifyStream() with the same 'stream'. + +// Can be called right after AvifInfoIdentifyStream() with the same 'stream' +// object if AvifInfoIdentifyStream() returned kAvifInfoOk. +// Any location-dependent feature such as 'primary_item_id_location' is relative +// to the given 'stream', and must be offset by the number of bytes read or +// skipped during AvifInfoIdentifyStream() if it was called prior to +// AvifInfoGetFeaturesStream() on the same 'stream' object. +// AvifInfoGetFeaturesStream() should only be called if AvifInfoIdentifyStream() +// returned kAvifInfoOk with the same input bytes. AvifInfoStatus AvifInfoGetFeaturesStream(void* stream, read_stream_t read, skip_stream_t skip, AvifInfoFeatures* features); diff --git a/ext/standard/link.c b/ext/standard/link.c index 24e3b515dc80..dfd92a0a8709 100644 --- a/ext/standard/link.c +++ b/ext/standard/link.c @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -88,7 +84,11 @@ PHP_FUNCTION(linkinfo) Z_PARAM_PATH(link, link_len) ZEND_PARSE_PARAMETERS_END(); - // TODO Check for empty string + if (UNEXPECTED(link_len == 0)) { + zend_argument_must_not_be_empty_error(1); + RETURN_THROWS(); + } + dirname = estrndup(link, link_len); zend_dirname(dirname, link_len); diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 0243ec897a05..6aac0d364cf0 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -25,6 +23,10 @@ #include "ext/date/php_date.h" #include "zend_smart_str.h" +#ifdef HAVE_SYS_WAIT_H +#include +#endif + #ifdef HAVE_SYSEXITS_H # include #endif @@ -64,21 +66,20 @@ typedef enum { CONTAINS_NULL } php_mail_header_value_error_type; -static php_mail_header_value_error_type php_mail_build_headers_check_field_value(zval *val) +static php_mail_header_value_error_type php_mail_build_headers_check_field_value(const zend_string *value) { size_t len = 0; - zend_string *value = Z_STR_P(val); /* https://tools.ietf.org/html/rfc2822#section-2.2.1 */ /* https://tools.ietf.org/html/rfc2822#section-2.2.3 */ - while (len < value->len) { - if (*(value->val+len) == '\r') { - if (*(value->val+len+1) != '\n') { + while (len < ZSTR_LEN(value)) { + if (*(ZSTR_VAL(value)+len) == '\r') { + if (*(ZSTR_VAL(value)+len+1) != '\n') { return CONTAINS_CR_ONLY; } - if (value->len - len >= 3 - && (*(value->val+len+2) == ' ' || *(value->val+len+2) == '\t')) { + if (ZSTR_LEN(value) - len >= 3 + && (*(ZSTR_VAL(value)+len+2) == ' ' || *(ZSTR_VAL(value)+len+2) == '\t')) { len += 3; continue; } @@ -92,15 +93,15 @@ static php_mail_header_value_error_type php_mail_build_headers_check_field_value * Therefore, considering such an environment, folding with LF alone * is allowed. */ - if (*(value->val+len) == '\n') { - if (value->len - len >= 2 - && (*(value->val+len+1) == ' ' || *(value->val+len+1) == '\t')) { + if (*(ZSTR_VAL(value)+len) == '\n') { + if (ZSTR_LEN(value) - len >= 2 + && (*(ZSTR_VAL(value)+len+1) == ' ' || *(ZSTR_VAL(value)+len+1) == '\t')) { len += 2; continue; } return CONTAINS_LF_ONLY; } - if (*(value->val+len) == '\0') { + if (*(ZSTR_VAL(value)+len) == '\0') { return CONTAINS_NULL; } len++; @@ -108,14 +109,13 @@ static php_mail_header_value_error_type php_mail_build_headers_check_field_value return NO_HEADER_ERROR; } - -static bool php_mail_build_headers_check_field_name(zend_string *key) +static zend_result php_mail_build_headers_check_field_name(const zend_string *key) { size_t len = 0; /* https://tools.ietf.org/html/rfc2822#section-2.2 */ - while (len < key->len) { - if (*(key->val+len) < 33 || *(key->val+len) > 126 || *(key->val+len) == ':') { + while (len < ZSTR_LEN(key)) { + if (*(ZSTR_VAL(key)+len) < 33 || *(ZSTR_VAL(key)+len) > 126 || *(ZSTR_VAL(key)+len) == ':') { return FAILURE; } len++; @@ -124,9 +124,9 @@ static bool php_mail_build_headers_check_field_name(zend_string *key) } -static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *val); +static void php_mail_build_headers_elems(smart_str *s, const zend_string *key, zval *val); -static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *val) +static void php_mail_build_headers_elem(smart_str *s, const zend_string *key, zval *val) { switch(Z_TYPE_P(val)) { case IS_STRING: @@ -135,7 +135,8 @@ static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *va return; } - php_mail_header_value_error_type error_type = php_mail_build_headers_check_field_value(val); + zend_string *str_value = Z_STR_P(val); + php_mail_header_value_error_type error_type = php_mail_build_headers_check_field_value(str_value); switch (error_type) { case NO_HEADER_ERROR: break; @@ -158,7 +159,7 @@ static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *va } smart_str_append(s, key); smart_str_appendl(s, ": ", 2); - smart_str_appends(s, Z_STRVAL_P(val)); + smart_str_append(s, str_value); smart_str_appendl(s, "\r\n", 2); break; case IS_ARRAY: @@ -170,7 +171,7 @@ static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *va } -static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *val) +static void php_mail_build_headers_elems(smart_str *s, const zend_string *key, zval *val) { zend_string *tmp_key; zval *tmp_val; @@ -204,7 +205,7 @@ do { \ } \ } while(0) -PHPAPI zend_string *php_mail_build_headers(HashTable *headers) +PHPAPI zend_string *php_mail_build_headers(const HashTable *headers) { zend_ulong idx; zend_string *key; @@ -214,7 +215,8 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers) ZEND_HASH_FOREACH_KEY_VAL(headers, idx, key, val) { if (!key) { zend_type_error("Header name cannot be numeric, " ZEND_LONG_FMT " given", idx); - break; + smart_str_free(&s); + return NULL; } ZVAL_DEREF(val); /* https://tools.ietf.org/html/rfc2822#section-3.6 */ @@ -241,13 +243,7 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers) } else if (zend_string_equals_literal_ci(key, "subject")) { zend_value_error("The additional headers cannot contain the \"Subject\" header"); } else { - if (Z_TYPE_P(val) == IS_STRING) { - php_mail_build_headers_elem(&s, key, val); - } else if (Z_TYPE_P(val) == IS_ARRAY) { - php_mail_build_headers_elems(&s, key, val); - } else { - zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); - } + php_mail_build_headers_elem(&s, key, val); } if (EG(exception)) { @@ -286,7 +282,7 @@ PHP_FUNCTION(mail) ZEND_PARSE_PARAMETERS_END(); if (headers_str) { - if (strlen(ZSTR_VAL(headers_str)) != ZSTR_LEN(headers_str)) { + if (UNEXPECTED(zend_str_has_nul_byte(headers_str))) { zend_argument_value_error(4, "must not contain any null bytes"); RETURN_THROWS(); } @@ -338,14 +334,14 @@ PHP_FUNCTION(mail) subject_r = subject; } - zend_string *force_extra_parameters = zend_ini_str_ex("mail.force_extra_parameters", strlen("mail.force_extra_parameters"), false, NULL); - if (force_extra_parameters) { + zend_string *force_extra_parameters = zend_ini_str_literal("mail.force_extra_parameters"); + if (force_extra_parameters && ZSTR_LEN(force_extra_parameters) > 0) { extra_cmd = php_escape_shell_cmd(force_extra_parameters); } else if (extra_cmd) { extra_cmd = php_escape_shell_cmd(extra_cmd); } - if (php_mail(to_r, subject_r, message, headers_str && ZSTR_LEN(headers_str) ? ZSTR_VAL(headers_str) : NULL, extra_cmd ? ZSTR_VAL(extra_cmd) : NULL)) { + if (php_mail(to_r, subject_r, message, headers_str && ZSTR_LEN(headers_str) ? ZSTR_VAL(headers_str) : NULL, extra_cmd)) { RETVAL_TRUE; } else { RETVAL_FALSE; @@ -387,10 +383,10 @@ static void php_mail_log_to_syslog(char *message) { } -static void php_mail_log_to_file(char *filename, char *message, size_t message_size) { +static void php_mail_log_to_file(const zend_string *filename, const char *message, size_t message_size) { /* Write 'message' to the given file. */ uint32_t flags = REPORT_ERRORS | STREAM_DISABLE_OPEN_BASEDIR; - php_stream *stream = php_stream_open_wrapper(filename, "a", flags, NULL); + php_stream *stream = php_stream_open_wrapper(ZSTR_VAL(filename), "a", flags, NULL); if (stream) { php_stream_write(stream, message, message_size); php_stream_close(stream); @@ -436,12 +432,12 @@ static int php_mail_detect_multiple_crlf(const char *hdr) { /* {{{ php_mail */ -PHPAPI bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd) +PHPAPI bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const zend_string *extra_cmd) { FILE *sendmail; - char *sendmail_path = INI_STR("sendmail_path"); + const char *sendmail_path = zend_ini_string_literal("sendmail_path"); char *sendmail_cmd = NULL; - char *mail_log = INI_STR("mail.log"); + const zend_string *mail_log = zend_ini_str_literal("mail.log"); const char *hdr = headers; char *ahdr = NULL; #if PHP_SIGCHILD @@ -454,7 +450,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c } \ return val; \ - if (mail_log && *mail_log) { + if (mail_log && ZSTR_LEN(mail_log)) { char *logline; spprintf(&logline, 0, "mail() on [%s:%d]: To: %s -- Headers: %s -- Subject: %s", zend_get_executed_filename(), zend_get_executed_lineno(), to, hdr ? hdr : "", subject); @@ -463,7 +459,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c php_mail_log_crlf_to_spaces(logline); } - if (!strcmp(mail_log, "syslog")) { + if (zend_string_equals_literal(mail_log, "syslog")) { php_mail_log_to_syslog(logline); } else { /* Add date when logging to file */ @@ -490,7 +486,27 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c MAIL_RET(false); } - char *line_sep = PG(mail_mixed_lf_and_crlf) ? "\n" : "\r\n"; + const char *line_sep; + zend_string *cr_lf_mode = PG(mail_cr_lf_mode); + + if (cr_lf_mode && !zend_string_equals_literal(cr_lf_mode, "crlf")) { + if (zend_string_equals_literal(cr_lf_mode, "lf")) { + line_sep = "\n"; + } else if (zend_string_equals_literal(cr_lf_mode, "mixed")) { + line_sep = "\n"; + } else if (zend_string_equals_literal(cr_lf_mode, "os")) { +#ifdef PHP_WIN32 + line_sep = "\r\n"; +#else + line_sep = "\n"; +#endif + } else { + ZEND_ASSERT(0 && "Unexpected cr_lf_mode value"); + } + } else { + /* CRLF is default mode, but respect mail.mixed_lf_and_crlf for backward compatibility */ + line_sep = PG(mail_mixed_lf_and_crlf) ? "\n" : "\r\n"; + } if (PG(mail_x_header)) { const char *tmp = zend_get_executed_filename(); @@ -518,7 +534,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c char *tsm_errmsg = NULL; /* handle old style win smtp sending */ - if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message, NULL, NULL, NULL) == FAILURE) { + if (TSendMail(zend_ini_string_literal("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message) == FAILURE) { if (tsm_errmsg) { php_error_docref(NULL, E_WARNING, "%s", tsm_errmsg); efree(tsm_errmsg); @@ -533,9 +549,9 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c #endif } if (extra_cmd != NULL) { - spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd); + spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, ZSTR_VAL(extra_cmd)); } else { - sendmail_cmd = sendmail_path; + sendmail_cmd = (char*)sendmail_path; } #if PHP_SIGCHILD @@ -558,10 +574,11 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c sendmail = popen(sendmail_cmd, "w"); #endif if (extra_cmd != NULL) { - efree (sendmail_cmd); + efree(sendmail_cmd); } if (sendmail) { + int ret; #ifndef PHP_WIN32 if (EACCES == errno) { php_error_docref(NULL, E_WARNING, "Permission denied: unable to execute shell to run mail delivery binary '%s'", sendmail_path); @@ -581,27 +598,86 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c if (hdr != NULL) { fprintf(sendmail, "%s%s", hdr, line_sep); } - fprintf(sendmail, "%s%s%s", line_sep, message, line_sep); - int ret = pclose(sendmail); + + fprintf(sendmail, "%s", line_sep); + + if (cr_lf_mode && zend_string_equals_literal(cr_lf_mode, "lf")) { + char *converted_message = NULL; + size_t msg_len = strlen(message); + size_t new_len = 0; + + if (msg_len > 0) { + for (size_t i = 0; i < msg_len - 1; ++i) { + if (message[i] == '\r' && message[i + 1] == '\n') { + ++new_len; + } + } + + if (new_len == 0) { + fprintf(sendmail, "%s", message); + } else { + converted_message = emalloc(msg_len - new_len + 1); + size_t j = 0; + for (size_t i = 0; i < msg_len; ++i) { + if (i < msg_len - 1 && message[i] == '\r' && message[i + 1] == '\n') { + converted_message[j++] = '\n'; + ++i; /* skip LF part */ + } else { + converted_message[j++] = message[i]; + } + } + + converted_message[j] = '\0'; + fprintf(sendmail, "%s", converted_message); + efree(converted_message); + } + } + } else { + fprintf(sendmail, "%s", message); + } + + fprintf(sendmail, "%s", line_sep); +#ifdef PHP_WIN32 + ret = pclose(sendmail); #if PHP_SIGCHILD if (sig_handler) { signal(SIGCHLD, sig_handler); } #endif - -#ifdef PHP_WIN32 - if (ret == -1) #else + int wstatus = pclose(sendmail); +#if PHP_SIGCHILD + if (sig_handler) { + signal(SIGCHLD, sig_handler); + } +#endif + /* Determine the wait(2) exit status */ + if (wstatus == -1) { + php_error_docref(NULL, E_WARNING, "Sendmail pclose failed %d (%s)", errno, strerror(errno)); + MAIL_RET(false); + } else if (WIFSIGNALED(wstatus)) { + php_error_docref(NULL, E_WARNING, "Sendmail killed by signal %d (%s)", WTERMSIG(wstatus), strsignal(WTERMSIG(wstatus))); + MAIL_RET(false); + } else { + if (WIFEXITED(wstatus)) { + ret = WEXITSTATUS(wstatus); + } else { + php_error_docref(NULL, E_WARNING, "Sendmail did not exit"); + MAIL_RET(false); + } + } +#endif + #if defined(EX_TEMPFAIL) if ((ret != EX_OK)&&(ret != EX_TEMPFAIL)) #elif defined(EX_OK) if (ret != EX_OK) #else if (ret != 0) -#endif #endif { + php_error_docref(NULL, E_WARNING, "Sendmail exited with non-zero exit code %d", ret); MAIL_RET(false); } else { MAIL_RET(true); @@ -623,7 +699,7 @@ PHPAPI bool php_mail(const char *to, const char *subject, const char *message, c /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(mail) { - char *sendmail_path = INI_STR("sendmail_path"); + const char *sendmail_path = zend_ini_string_literal("sendmail_path"); #ifdef PHP_WIN32 if (!sendmail_path) { diff --git a/ext/standard/math.c b/ext/standard/math.c index 142d473864f7..1898d210ce65 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jim Winstead | | Stig Sæther Bakken | @@ -152,7 +150,7 @@ static inline double php_round_helper(double integral, double value, double expo return integral; - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } // FIXME: GCC bug, branch is considered reachable. ZEND_UNREACHABLE(); @@ -261,7 +259,7 @@ PHP_FUNCTION(abs) } case IS_DOUBLE: RETURN_DOUBLE(fabs(Z_DVAL_P(value))); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -280,7 +278,7 @@ PHP_FUNCTION(ceil) RETURN_DOUBLE(zval_get_double(value)); case IS_DOUBLE: RETURN_DOUBLE(ceil(Z_DVAL_P(value))); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ @@ -299,35 +297,33 @@ PHP_FUNCTION(floor) RETURN_DOUBLE(zval_get_double(value)); case IS_DOUBLE: RETURN_DOUBLE(floor(Z_DVAL_P(value))); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ -PHPAPI int php_math_round_mode_from_enum(zend_object *mode) +PHPAPI int php_math_round_mode_from_enum(zend_enum_RoundingMode mode) { - zval *case_name = zend_enum_fetch_case_name(mode); - zend_string *mode_name = Z_STR_P(case_name); - - switch (ZSTR_VAL(mode_name)[0] + ZSTR_VAL(mode_name)[4]) { - case 'H' + 'A': + switch (mode) { + case ZEND_ENUM_RoundingMode_HalfAwayFromZero: return PHP_ROUND_HALF_UP; - case 'H' + 'T': + case ZEND_ENUM_RoundingMode_HalfTowardsZero: return PHP_ROUND_HALF_DOWN; - case 'H' + 'E': + case ZEND_ENUM_RoundingMode_HalfEven: return PHP_ROUND_HALF_EVEN; - case 'H' + 'O': + case ZEND_ENUM_RoundingMode_HalfOdd: return PHP_ROUND_HALF_ODD; - case 'T' + 'r': + case ZEND_ENUM_RoundingMode_TowardsZero: return PHP_ROUND_TOWARD_ZERO; - case 'A' + 'F': + case ZEND_ENUM_RoundingMode_AwayFromZero: return PHP_ROUND_AWAY_FROM_ZERO; - case 'N' + 't': + case ZEND_ENUM_RoundingMode_NegativeInfinity: return PHP_ROUND_FLOOR; - case 'P' + 't': + case ZEND_ENUM_RoundingMode_PositiveInfinity: return PHP_ROUND_CEILING; - EMPTY_SWITCH_DEFAULT_CASE(); } + + ZEND_UNREACHABLE(); } /* {{{ Returns the number rounded to specified precision */ @@ -355,7 +351,7 @@ PHP_FUNCTION(round) } if (mode_object != NULL) { - mode = php_math_round_mode_from_enum(mode_object); + mode = php_math_round_mode_from_enum(zend_enum_fetch_case_id(mode_object)); } switch (mode) { @@ -384,11 +380,67 @@ PHP_FUNCTION(round) case IS_DOUBLE: RETURN_DOUBLE(_php_math_round(zval_get_double(value), (int)places, (int)mode)); - EMPTY_SWITCH_DEFAULT_CASE(); + default: ZEND_UNREACHABLE(); } } /* }}} */ +/* Return the given value if in range of min and max */ +static void php_math_clamp(zval *return_value, zval *value, zval *min, zval *max) +{ + if (Z_TYPE_P(min) == IS_DOUBLE && UNEXPECTED(zend_isnan(Z_DVAL_P(min)))) { + zend_argument_value_error(2, "must not be NAN"); + RETURN_THROWS(); + } + + if (Z_TYPE_P(max) == IS_DOUBLE && UNEXPECTED(zend_isnan(Z_DVAL_P(max)))) { + zend_argument_value_error(3, "must not be NAN"); + RETURN_THROWS(); + } + + if (zend_compare(max, min) == -1) { + zend_argument_value_error(2, "must be smaller than or equal to argument #3 ($max)"); + RETURN_THROWS(); + } + + if (zend_compare(max, value) == -1) { + RETURN_COPY(max); + } + + if (zend_compare(value, min) == -1) { + RETURN_COPY(min); + } + + RETURN_COPY(value); +} + +/* {{{ Return the given value if in range of min and max */ +PHP_FUNCTION(clamp) +{ + zval *zvalue, *zmin, *zmax; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_ZVAL(zvalue) + Z_PARAM_ZVAL(zmin) + Z_PARAM_ZVAL(zmax) + ZEND_PARSE_PARAMETERS_END(); + + php_math_clamp(return_value, zvalue, zmin, zmax); +} +/* }}} */ + +/* {{{ Return the given value if in range of min and max */ +ZEND_FRAMELESS_FUNCTION(clamp, 3) +{ + zval *zvalue, *zmin, *zmax; + Z_FLF_PARAM_ZVAL(1, zvalue); + Z_FLF_PARAM_ZVAL(2, zmin); + Z_FLF_PARAM_ZVAL(3, zmax); + + php_math_clamp(return_value, zvalue, zmin, zmax); +} +/* }}} */ + /* {{{ Returns the sine of the number in radians */ PHP_FUNCTION(sin) { @@ -807,9 +859,9 @@ PHPAPI void _php_math_basetozval(zend_string *str, int base, zval *ret) e = s + ZSTR_LEN(str); /* Skip leading whitespace */ - while (s < e && isspace(*s)) s++; + while (s < e && isspace((unsigned char)*s)) s++; /* Skip trailing whitespace */ - while (s < e && isspace(*(e-1))) e--; + while (s < e && isspace((unsigned char)e[-1])) e--; if (e - s >= 2) { if (base == 16 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) s += 2; @@ -1122,7 +1174,7 @@ PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, const char *de tmpbuf = strpprintf(0, "%.*F", dec, d); if (tmpbuf == NULL) { return NULL; - } else if (!isdigit((int)ZSTR_VAL(tmpbuf)[0])) { + } else if (!isdigit((unsigned char)ZSTR_VAL(tmpbuf)[0])) { return tmpbuf; } @@ -1365,7 +1417,6 @@ PHP_FUNCTION(number_format) switch (Z_TYPE_P(num)) { case IS_LONG: RETURN_STR(_php_math_number_format_long(Z_LVAL_P(num), dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len)); - break; case IS_DOUBLE: // double values of >= 2^52 can not have fractional digits anymore @@ -1375,7 +1426,6 @@ PHP_FUNCTION(number_format) && ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(num)) )) { RETURN_STR(_php_math_number_format_long((zend_long)Z_DVAL_P(num), dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len)); - break; } if (dec >= 0) { @@ -1384,9 +1434,8 @@ PHP_FUNCTION(number_format) dec_int = ZEND_LONG_INT_UDFL(dec) ? INT_MIN : (int)dec; } RETURN_STR(_php_math_number_format_ex(Z_DVAL_P(num), dec_int, dec_point, dec_point_len, thousand_sep, thousand_sep_len)); - break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } /* }}} */ diff --git a/ext/standard/md5.c b/ext/standard/md5.c index 9d0f5f886a6b..204514053cf0 100644 --- a/ext/standard/md5.c +++ b/ext/standard/md5.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alexander Peslyak (Solar Designer) | | Lachlan Roche | diff --git a/ext/standard/md5.h b/ext/standard/md5.h index 5444abf46aec..30faa0ac258a 100644 --- a/ext/standard/md5.h +++ b/ext/standard/md5.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Alexander Peslyak (Solar Designer) | | Rasmus Lerdorf | diff --git a/ext/standard/metaphone.c b/ext/standard/metaphone.c index 149f95c127c6..8f33057de5ac 100644 --- a/ext/standard/metaphone.c +++ b/ext/standard/metaphone.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ @@ -80,7 +78,7 @@ static const char _codes[26] = /* Note: these functions require an uppercase letter input! */ static zend_always_inline char encode(char c) { - if (isalpha(c)) { + if (isalpha((unsigned char)c)) { ZEND_ASSERT(c >= 'A' && c <= 'Z'); return _codes[(c - 'A')]; } else { @@ -107,9 +105,9 @@ static zend_always_inline char encode(char c) { /*----------------------------- */ /* I suppose I could have been using a character pointer instead of - * accesssing the array directly... */ + * accessing the array directly... */ -#define Convert_Raw(c) toupper(c) +#define Convert_Raw(c) toupper((unsigned char)c) /* Look at the next letter in the word */ #define Read_Raw_Next_Letter (word[w_idx+1]) #define Read_Next_Letter (Convert_Raw(Read_Raw_Next_Letter)) @@ -123,14 +121,14 @@ static zend_always_inline char encode(char c) { /* Look two letters down. It makes sure you don't walk off the string. */ #define Read_After_Next_Letter (Read_Raw_Next_Letter != '\0' ? Convert_Raw(word[w_idx+2]) \ : '\0') -#define Look_Ahead_Letter(n) (toupper(Lookahead((char *) word+w_idx, n))) +#define Look_Ahead_Letter(n) (toupper((unsigned char)Lookahead((char *) word+w_idx, n))) /* Allows us to safely look ahead an arbitrary # of letters */ /* I probably could have just used strlen... */ -static char Lookahead(char *word, int how_far) +static char Lookahead(char *word, size_t how_far) { - int idx; + size_t idx; for (idx = 0; word[idx] != '\0' && idx < how_far; idx++); /* Edge forward in the string... */ @@ -165,12 +163,12 @@ static char Lookahead(char *word, int how_far) #define Phone_Len (p_idx) /* Note is a letter is a 'break' in the word */ -#define Isbreak(c) (!isalpha(c)) +#define Isbreak(c) (!isalpha((unsigned char)(c))) /* {{{ metaphone */ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonemes, zend_string **phoned_word, int traditional) { - int w_idx = 0; /* point in the phonization we're at. */ + size_t w_idx = 0; /* point in the phonization we're at. */ size_t p_idx = 0; /* end of the phoned phrase */ size_t max_buffer_len = 0; /* maximum length of the destination buffer */ char curr_letter; @@ -189,7 +187,7 @@ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonem /*-- The first phoneme has to be processed specially. --*/ /* Find our first letter */ - for (; !isalpha(curr_letter = Read_Raw_Curr_Letter); w_idx++) { + for (; !isalpha((unsigned char)(curr_letter = Read_Raw_Curr_Letter)); w_idx++) { /* On the off chance we were given nothing but crap... */ if (curr_letter == '\0') { End_Phoned_Word(); @@ -264,7 +262,7 @@ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonem for (; (curr_letter = Read_Raw_Curr_Letter) != '\0' && (max_phonemes == 0 || Phone_Len < (size_t)max_phonemes); w_idx++) { - /* How many letters to skip because an eariler encoding handled + /* How many letters to skip because an earlier encoding handled * multiple letters */ unsigned short int skip_letter = 0; @@ -277,7 +275,7 @@ static void metaphone(unsigned char *word, size_t word_len, zend_long max_phonem */ /* Ignore non-alphas */ - if (!isalpha(curr_letter)) + if (!isalpha((unsigned char)curr_letter)) continue; curr_letter = Convert_Raw(curr_letter); diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c index ca8643eb5196..46e770dec3ee 100644 --- a/ext/standard/microtime.c +++ b/ext/standard/microtime.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Paul Panotzki - Bunyip Information Systems | +----------------------------------------------------------------------+ diff --git a/ext/standard/net.c b/ext/standard/net.c index 942d804d42a4..199db6e80943 100644 --- a/ext/standard/net.c +++ b/ext/standard/net.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/standard/pack.c b/ext/standard/pack.c index d4c5cc1f04cf..1ab5d4858cbe 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Chris Schneider | +----------------------------------------------------------------------+ @@ -19,7 +17,6 @@ #include #include #include -#include "pack.h" #define INC_OUTPUTPOS(a,b) \ if ((a) < 0 || ((INT_MAX - outputpos)/((int)b)) < (a)) { \ @@ -30,10 +27,23 @@ } \ outputpos += (a)*(b); +typedef enum { + PHP_LITTLE_ENDIAN, + PHP_BIG_ENDIAN, +} php_pack_endianness; + #ifdef WORDS_BIGENDIAN -#define MACHINE_LITTLE_ENDIAN 0 +# define MACHINE_LITTLE_ENDIAN 0 +# define PHP_MACHINE_ENDIAN PHP_BIG_ENDIAN #else -#define MACHINE_LITTLE_ENDIAN 1 +# define MACHINE_LITTLE_ENDIAN 1 +# define PHP_MACHINE_ENDIAN PHP_LITTLE_ENDIAN +#endif + +#ifdef ZEND_ENABLE_ZVAL_LONG64 +# define PHP_LONG_BSWAP(u) ZEND_BYTES_SWAP64(u) +#else +# define PHP_LONG_BSWAP(u) ZEND_BYTES_SWAP32(u) #endif typedef ZEND_SET_ALIGNED(1, uint16_t unaligned_uint16_t); @@ -42,41 +52,23 @@ typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t); typedef ZEND_SET_ALIGNED(1, unsigned int unaligned_uint); typedef ZEND_SET_ALIGNED(1, int unaligned_int); -/* Mapping of byte from char (8bit) to long for machine endian */ -static int byte_map[1]; - -/* Mappings of bytes from int (machine dependent) to int for machine endian */ -static int int_map[sizeof(int)]; - -/* Mappings of bytes from shorts (16bit) for all endian environments */ -static int machine_endian_short_map[2]; -static int big_endian_short_map[2]; -static int little_endian_short_map[2]; - -/* Mappings of bytes from longs (32bit) for all endian environments */ -static int machine_endian_long_map[4]; -static int big_endian_long_map[4]; -static int little_endian_long_map[4]; - -#if SIZEOF_ZEND_LONG > 4 -/* Mappings of bytes from quads (64bit) for all endian environments */ -static int machine_endian_longlong_map[8]; -static int big_endian_longlong_map[8]; -static int little_endian_longlong_map[8]; -#endif - /* {{{ php_pack */ -static void php_pack(zval *val, size_t size, int *map, char *output) +static void php_pack(const zval *val, size_t size, php_pack_endianness endianness, char *output) { - size_t i; - char *v; - - convert_to_long(val); - v = (char *) &Z_LVAL_P(val); + zend_ulong zl = zval_get_long(val); - for (i = 0; i < size; i++) { - *output++ = v[map[i]]; + if ((endianness == PHP_LITTLE_ENDIAN) != MACHINE_LITTLE_ENDIAN) { + zl = PHP_LONG_BSWAP(zl); +#if MACHINE_LITTLE_ENDIAN + zl >>= (sizeof(zl) - size) * 8; +#endif + } else { +#if !MACHINE_LITTLE_ENDIAN + zl <<= (sizeof(zl) - size) * 8; +#endif } + + memcpy(output, (const char *) &zl, size); } /* }}} */ @@ -88,10 +80,7 @@ ZEND_ATTRIBUTE_CONST static inline uint16_t php_pack_reverse_int16(uint16_t arg) /* {{{ php_pack_reverse_int32 */ ZEND_ATTRIBUTE_CONST static inline uint32_t php_pack_reverse_int32(uint32_t arg) { - uint32_t result; - result = ((arg & 0xFF) << 24) | ((arg & 0xFF00) << 8) | ((arg >> 8) & 0xFF00) | ((arg >> 24) & 0xFF); - - return result; + return ZEND_BYTES_SWAP32(arg); } /* }}} */ @@ -366,7 +355,7 @@ PHP_FUNCTION(pack) switch (code) { case 'h': case 'H': - INC_OUTPUTPOS((arg + (arg % 2)) / 2,1) /* 4 bit per arg */ + INC_OUTPUTPOS((arg / 2) + (arg % 2),1) /* 4 bit per arg */ break; case 'a': @@ -509,7 +498,7 @@ PHP_FUNCTION(pack) case 'c': case 'C': while (arg-- > 0) { - php_pack(&argv[currentarg++], 1, byte_map, &ZSTR_VAL(output)[outputpos]); + php_pack(&argv[currentarg++], 1, PHP_MACHINE_ENDIAN, &ZSTR_VAL(output)[outputpos]); outputpos++; } break; @@ -518,16 +507,16 @@ PHP_FUNCTION(pack) case 'S': case 'n': case 'v': { - int *map = machine_endian_short_map; + php_pack_endianness endianness = PHP_MACHINE_ENDIAN; if (code == 'n') { - map = big_endian_short_map; + endianness = PHP_BIG_ENDIAN; } else if (code == 'v') { - map = little_endian_short_map; + endianness = PHP_LITTLE_ENDIAN; } while (arg-- > 0) { - php_pack(&argv[currentarg++], 2, map, &ZSTR_VAL(output)[outputpos]); + php_pack(&argv[currentarg++], 2, endianness, &ZSTR_VAL(output)[outputpos]); outputpos += 2; } break; @@ -536,7 +525,7 @@ PHP_FUNCTION(pack) case 'i': case 'I': while (arg-- > 0) { - php_pack(&argv[currentarg++], sizeof(int), int_map, &ZSTR_VAL(output)[outputpos]); + php_pack(&argv[currentarg++], sizeof(int), PHP_MACHINE_ENDIAN, &ZSTR_VAL(output)[outputpos]); outputpos += sizeof(int); } break; @@ -545,16 +534,16 @@ PHP_FUNCTION(pack) case 'L': case 'N': case 'V': { - int *map = machine_endian_long_map; + php_pack_endianness endianness = PHP_MACHINE_ENDIAN; if (code == 'N') { - map = big_endian_long_map; + endianness = PHP_BIG_ENDIAN; } else if (code == 'V') { - map = little_endian_long_map; + endianness = PHP_LITTLE_ENDIAN; } while (arg-- > 0) { - php_pack(&argv[currentarg++], 4, map, &ZSTR_VAL(output)[outputpos]); + php_pack(&argv[currentarg++], 4, endianness, &ZSTR_VAL(output)[outputpos]); outputpos += 4; } break; @@ -565,16 +554,16 @@ PHP_FUNCTION(pack) case 'Q': case 'J': case 'P': { - int *map = machine_endian_longlong_map; + php_pack_endianness endianness = PHP_MACHINE_ENDIAN; if (code == 'J') { - map = big_endian_longlong_map; + endianness = PHP_BIG_ENDIAN; } else if (code == 'P') { - map = little_endian_longlong_map; + endianness = PHP_LITTLE_ENDIAN; } while (arg-- > 0) { - php_pack(&argv[currentarg++], 8, map, &ZSTR_VAL(output)[outputpos]); + php_pack(&argv[currentarg++], 8, endianness, &ZSTR_VAL(output)[outputpos]); outputpos += 8; } break; @@ -1178,127 +1167,3 @@ PHP_FUNCTION(unpack) } } /* }}} */ - -/* {{{ PHP_MINIT_FUNCTION */ -PHP_MINIT_FUNCTION(pack) -{ - int i; - - if (MACHINE_LITTLE_ENDIAN) { - /* Where to get lo to hi bytes from */ - byte_map[0] = 0; - - for (i = 0; i < (int)sizeof(int); i++) { - int_map[i] = i; - } - - machine_endian_short_map[0] = 0; - machine_endian_short_map[1] = 1; - big_endian_short_map[0] = 1; - big_endian_short_map[1] = 0; - little_endian_short_map[0] = 0; - little_endian_short_map[1] = 1; - - machine_endian_long_map[0] = 0; - machine_endian_long_map[1] = 1; - machine_endian_long_map[2] = 2; - machine_endian_long_map[3] = 3; - big_endian_long_map[0] = 3; - big_endian_long_map[1] = 2; - big_endian_long_map[2] = 1; - big_endian_long_map[3] = 0; - little_endian_long_map[0] = 0; - little_endian_long_map[1] = 1; - little_endian_long_map[2] = 2; - little_endian_long_map[3] = 3; - -#if SIZEOF_ZEND_LONG > 4 - machine_endian_longlong_map[0] = 0; - machine_endian_longlong_map[1] = 1; - machine_endian_longlong_map[2] = 2; - machine_endian_longlong_map[3] = 3; - machine_endian_longlong_map[4] = 4; - machine_endian_longlong_map[5] = 5; - machine_endian_longlong_map[6] = 6; - machine_endian_longlong_map[7] = 7; - big_endian_longlong_map[0] = 7; - big_endian_longlong_map[1] = 6; - big_endian_longlong_map[2] = 5; - big_endian_longlong_map[3] = 4; - big_endian_longlong_map[4] = 3; - big_endian_longlong_map[5] = 2; - big_endian_longlong_map[6] = 1; - big_endian_longlong_map[7] = 0; - little_endian_longlong_map[0] = 0; - little_endian_longlong_map[1] = 1; - little_endian_longlong_map[2] = 2; - little_endian_longlong_map[3] = 3; - little_endian_longlong_map[4] = 4; - little_endian_longlong_map[5] = 5; - little_endian_longlong_map[6] = 6; - little_endian_longlong_map[7] = 7; -#endif - } - else { - zval val; - int size = sizeof(Z_LVAL(val)); - Z_LVAL(val)=0; /*silence a warning*/ - - /* Where to get hi to lo bytes from */ - byte_map[0] = size - 1; - - for (i = 0; i < (int)sizeof(int); i++) { - int_map[i] = size - (sizeof(int) - i); - } - - machine_endian_short_map[0] = size - 2; - machine_endian_short_map[1] = size - 1; - big_endian_short_map[0] = size - 2; - big_endian_short_map[1] = size - 1; - little_endian_short_map[0] = size - 1; - little_endian_short_map[1] = size - 2; - - machine_endian_long_map[0] = size - 4; - machine_endian_long_map[1] = size - 3; - machine_endian_long_map[2] = size - 2; - machine_endian_long_map[3] = size - 1; - big_endian_long_map[0] = size - 4; - big_endian_long_map[1] = size - 3; - big_endian_long_map[2] = size - 2; - big_endian_long_map[3] = size - 1; - little_endian_long_map[0] = size - 1; - little_endian_long_map[1] = size - 2; - little_endian_long_map[2] = size - 3; - little_endian_long_map[3] = size - 4; - -#if SIZEOF_ZEND_LONG > 4 - machine_endian_longlong_map[0] = size - 8; - machine_endian_longlong_map[1] = size - 7; - machine_endian_longlong_map[2] = size - 6; - machine_endian_longlong_map[3] = size - 5; - machine_endian_longlong_map[4] = size - 4; - machine_endian_longlong_map[5] = size - 3; - machine_endian_longlong_map[6] = size - 2; - machine_endian_longlong_map[7] = size - 1; - big_endian_longlong_map[0] = size - 8; - big_endian_longlong_map[1] = size - 7; - big_endian_longlong_map[2] = size - 6; - big_endian_longlong_map[3] = size - 5; - big_endian_longlong_map[4] = size - 4; - big_endian_longlong_map[5] = size - 3; - big_endian_longlong_map[6] = size - 2; - big_endian_longlong_map[7] = size - 1; - little_endian_longlong_map[0] = size - 1; - little_endian_longlong_map[1] = size - 2; - little_endian_longlong_map[2] = size - 3; - little_endian_longlong_map[3] = size - 4; - little_endian_longlong_map[4] = size - 5; - little_endian_longlong_map[5] = size - 6; - little_endian_longlong_map[6] = size - 7; - little_endian_longlong_map[7] = size - 8; -#endif - } - - return SUCCESS; -} -/* }}} */ diff --git a/ext/standard/pack.h b/ext/standard/pack.h deleted file mode 100644 index 5e12d55e0bc6..000000000000 --- a/ext/standard/pack.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Rasmus Lerdorf | - +----------------------------------------------------------------------+ -*/ - -#ifndef PACK_H -#define PACK_H - -PHP_MINIT_FUNCTION(pack); - -#endif /* PACK_H */ diff --git a/ext/standard/pageinfo.c b/ext/standard/pageinfo.c index c1cbc59bfaa1..3ddda25ef0b7 100644 --- a/ext/standard/pageinfo.c +++ b/ext/standard/pageinfo.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ diff --git a/ext/standard/pageinfo.h b/ext/standard/pageinfo.h index 029ce8b97981..5ce81685f9ec 100644 --- a/ext/standard/pageinfo.h +++ b/ext/standard/pageinfo.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ diff --git a/ext/standard/password.c b/ext/standard/password.c index 1e647bb301c3..a28ceb7e0ced 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Anthony Ferrara | | Charles R. Portwood II | @@ -86,18 +84,18 @@ static zend_string* php_password_make_salt(size_t length) /* {{{ */ buffer = zend_string_alloc(length * 3 / 4 + 1, 0); if (FAILURE == php_random_bytes_throw(ZSTR_VAL(buffer), ZSTR_LEN(buffer))) { zend_value_error("Unable to generate salt"); - zend_string_release_ex(buffer, 0); + zend_string_efree(buffer); return NULL; } ret = zend_string_alloc(length, 0); if (php_password_salt_to64(ZSTR_VAL(buffer), ZSTR_LEN(buffer), length, ZSTR_VAL(ret)) == FAILURE) { zend_value_error("Generated salt too short"); - zend_string_release_ex(buffer, 0); - zend_string_release_ex(ret, 0); + zend_string_efree(buffer); + zend_string_efree(ret); return NULL; } - zend_string_release_ex(buffer, 0); + zend_string_efree(buffer); ZSTR_VAL(ret)[length] = 0; return ret; } @@ -140,7 +138,7 @@ static bool php_password_bcrypt_needs_rehash(const zend_string *hash, zend_array if (!php_password_bcrypt_valid(hash)) { /* Should never get called this way. */ - return 1; + return true; } sscanf(ZSTR_VAL(hash), "$2y$" ZEND_LONG_FMT "$", &old_cost); @@ -156,12 +154,12 @@ static bool php_password_bcrypt_verify(const zend_string *password, const zend_s zend_string *ret = php_crypt(ZSTR_VAL(password), (int)ZSTR_LEN(password), ZSTR_VAL(hash), (int)ZSTR_LEN(hash), 1); if (!ret) { - return 0; + return false; } if (ZSTR_LEN(hash) < 13) { zend_string_free(ret); - return 0; + return false; } /* We're using this method instead of == in order to provide diff --git a/ext/standard/password.stub.php b/ext/standard/password.stub.php index c3c99117d514..b4758ef54b12 100644 --- a/ext/standard/password.stub.php +++ b/ext/standard/password.stub.php @@ -2,13 +2,7 @@ /** @generate-class-entries */ -/** - * @var string - */ const PASSWORD_DEFAULT = "2y"; -/** - * @var string - */ const PASSWORD_BCRYPT = "2y"; /** * @var int @@ -17,17 +11,8 @@ const PASSWORD_BCRYPT_DEFAULT_COST = UNKNOWN; #ifdef HAVE_ARGON2LIB -/** - * @var string - */ const PASSWORD_ARGON2I = "argon2i"; -/** - * @var string - */ const PASSWORD_ARGON2ID = "argon2id"; -/** - * @var string - */ const PASSWORD_ARGON2_PROVIDER = "standard"; /** * @var int diff --git a/ext/standard/password_arginfo.h b/ext/standard/password_arginfo.h index fd25fbed6773..f3d74a96d318 100644 --- a/ext/standard/password_arginfo.h +++ b/ext/standard/password_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: aab38646ace967e985c348b78251474693da95a7 */ +/* This is a generated file, edit password.stub.php instead. + * Stub hash: f61df8d477588718e0eb1b055e5a3e138e6bcad3 */ static void register_password_symbols(int module_number) { diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h index 2a35af603808..ab6c8494dd4e 100644 --- a/ext/standard/php_array.h +++ b/ext/standard/php_array.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Andi Gutmans | | Zeev Suraski | @@ -59,9 +57,12 @@ PHPAPI bool php_array_pick_keys(php_random_algo_with_state engine, zval *input, #define PHP_COUNT_NORMAL 0 #define PHP_COUNT_RECURSIVE 1 +#define ARRAY_FILTER_USE_VALUE 0 #define ARRAY_FILTER_USE_BOTH 1 #define ARRAY_FILTER_USE_KEY 2 +extern PHPAPI zend_class_entry *sort_direction_ce; + ZEND_BEGIN_MODULE_GLOBALS(array) bucket_compare_func_t *multisort_func; bool compare_deprecation_thrown; diff --git a/ext/standard/php_assert.h b/ext/standard/php_assert.h index 103a770e7601..c26e1f11681c 100644 --- a/ext/standard/php_assert.h +++ b/ext/standard/php_assert.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_browscap.h b/ext/standard/php_browscap.h index 4fc4f66a9233..85225bca0244 100644 --- a/ext/standard/php_browscap.h +++ b/ext/standard/php_browscap.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Zeev Suraski | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h index b7111dfd21b1..19c20c4a6c16 100644 --- a/ext/standard/php_crypt.h +++ b/ext/standard/php_crypt.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Stig Bakken | | Zeev Suraski | diff --git a/ext/standard/php_crypt_r.c b/ext/standard/php_crypt_r.c index bd30ce9ce8cb..15a1508be1cb 100644 --- a/ext/standard/php_crypt_r.c +++ b/ext/standard/php_crypt_r.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Pierre Alain Joye . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Pierre Alain Joye . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Thies C. Arntzen | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_dir_int.h b/ext/standard/php_dir_int.h index 06faf4e678f4..17fcbab7e1cb 100644 --- a/ext/standard/php_dir_int.h +++ b/ext/standard/php_dir_int.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ diff --git a/ext/standard/php_dns.h b/ext/standard/php_dns.h index 4e04799cdb8a..5b0a29f32bd1 100644 --- a/ext/standard/php_dns.h +++ b/ext/standard/php_dns.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: The typical suspects | | Marcus Boerger | diff --git a/ext/standard/php_ext_syslog.h b/ext/standard/php_ext_syslog.h index fd7958fad292..44c5ad1c02f4 100644 --- a/ext/standard/php_ext_syslog.h +++ b/ext/standard/php_ext_syslog.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h index ef3c1cd60c72..c2ea6eed66e2 100644 --- a/ext/standard/php_filestat.h +++ b/ext/standard/php_filestat.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index ea33ba490434..89c2d9c49b0c 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | diff --git a/ext/standard/php_fopen_wrappers.h b/ext/standard/php_fopen_wrappers.h index 885e31ffa730..a7e027dcf89f 100644 --- a/ext/standard/php_fopen_wrappers.h +++ b/ext/standard/php_fopen_wrappers.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | diff --git a/ext/standard/php_http.h b/ext/standard/php_http.h index 9350be597ea1..6192d0e63cee 100644 --- a/ext/standard/php_http.h +++ b/ext/standard/php_http.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_image.h b/ext/standard/php_image.h index a41273e6745a..ea57214bda0b 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Marcus Boerger | @@ -18,6 +16,9 @@ #ifndef PHP_IMAGE_H #define PHP_IMAGE_H +PHP_MINIT_FUNCTION(image); +PHP_MSHUTDOWN_FUNCTION(image); + /* {{{ enum image_filetype This enum is used to have ext/standard/image.c and ext/exif/exif.c use the same constants for file types. @@ -44,15 +45,44 @@ typedef enum IMAGE_FILETYPE_ICO, IMAGE_FILETYPE_WEBP, IMAGE_FILETYPE_AVIF, + IMAGE_FILETYPE_HEIF, /* WHEN EXTENDING: PLEASE ALSO REGISTER IN basic_function.stub.php */ - IMAGE_FILETYPE_COUNT + IMAGE_FILETYPE_FIXED_COUNT } image_filetype; /* }}} */ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetype); -PHPAPI char * php_image_type_to_mime_type(int image_type); +PHPAPI const char * php_image_type_to_mime_type(int image_type); PHPAPI bool php_is_image_avif(php_stream *stream); +/* return info as a struct, to make expansion easier */ +struct php_gfxinfo { + unsigned int width; + unsigned int height; + zend_string *width_unit; + zend_string *height_unit; + unsigned int bits; + unsigned int channels; +}; + +typedef zend_result (*php_image_identify)(php_stream *stream); +typedef struct php_gfxinfo *(*php_image_get_info)(php_stream *stream); + +struct php_image_handler { + const char *mime_type; + const char *extension; + const char *const_name; + php_image_identify identify; + php_image_get_info get_info; +}; + +#define PHP_IMAGE_CONST_NAME(suffix) ("IMAGETYPE_" suffix) + +/* This should only be called on module init */ +PHPAPI int php_image_register_handler(const struct php_image_handler *handler); +/* This should only be called on module shutdown */ +PHPAPI zend_result php_image_unregister_handler(int image_type); + #endif /* PHP_IMAGE_H */ diff --git a/ext/standard/php_incomplete_class.h b/ext/standard/php_incomplete_class.h index 07eabf60d5dc..fb49eaf1b693 100644 --- a/ext/standard/php_incomplete_class.h +++ b/ext/standard/php_incomplete_class.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index c2e22240c48e..f7320f1d0700 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -19,7 +17,7 @@ PHP_MINFO_FUNCTION(mail); -PHPAPI zend_string *php_mail_build_headers(HashTable *headers); -PHPAPI extern bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const char *extra_cmd); +PHPAPI zend_string *php_mail_build_headers(const HashTable *headers); +PHPAPI extern bool php_mail(const char *to, const char *subject, const char *message, const char *headers, const zend_string *extra_cmd); #endif /* PHP_MAIL_H */ diff --git a/ext/standard/php_math.h b/ext/standard/php_math.h index 9ebd600537fd..cb0b9db21599 100644 --- a/ext/standard/php_math.h +++ b/ext/standard/php_math.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jim Winstead | | Stig Sæther Bakken | diff --git a/ext/standard/php_math_round_mode.h b/ext/standard/php_math_round_mode.h index e8cbec640668..abc3c7e284a5 100644 --- a/ext/standard/php_math_round_mode.h +++ b/ext/standard/php_math_round_mode.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jim Winstead | | Stig Sæther Bakken | @@ -16,6 +14,7 @@ */ #include "php.h" +#include "basic_functions_decl.h" /* Define rounding modes (all are round-to-nearest) */ #ifndef PHP_ROUND_HALF_UP @@ -52,4 +51,4 @@ extern PHPAPI zend_class_entry *rounding_mode_ce; -PHPAPI int php_math_round_mode_from_enum(zend_object *mode); +PHPAPI int php_math_round_mode_from_enum(zend_enum_RoundingMode mode); diff --git a/ext/standard/php_net.h b/ext/standard/php_net.h index 58739131232d..beabb12caac9 100644 --- a/ext/standard/php_net.h +++ b/ext/standard/php_net.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Sara Golemon | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_password.h b/ext/standard/php_password.h index 5a6f3b2af5c9..6442b782c256 100644 --- a/ext/standard/php_password.h +++ b/ext/standard/php_password.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Anthony Ferrara | | Charles R. Portwood II | diff --git a/ext/standard/php_smart_string.h b/ext/standard/php_smart_string.h deleted file mode 100644 index 0013775d18f8..000000000000 --- a/ext/standard/php_smart_string.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Sascha Schumann | - | Xinchen Hui | - +----------------------------------------------------------------------+ - */ - -/* Header moved to Zend. This file is retained for BC. */ -#include "zend_smart_string.h" diff --git a/ext/standard/php_smart_string_public.h b/ext/standard/php_smart_string_public.h deleted file mode 100644 index 264723e28e1b..000000000000 --- a/ext/standard/php_smart_string_public.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Sascha Schumann | - | Xinchen Hui | - +----------------------------------------------------------------------+ - */ - -/* Header moved to Zend. This file is retained for BC. */ -#include "zend_smart_string_public.h" diff --git a/ext/standard/php_standard.h b/ext/standard/php_standard.h index 78eba25f11a5..34715e966683 100644 --- a/ext/standard/php_standard.h +++ b/ext/standard/php_standard.h @@ -1,16 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ */ @@ -29,7 +25,6 @@ #include "php_ext_syslog.h" #include "php_filestat.h" #include "php_browscap.h" -#include "pack.h" #include "url.h" #include "pageinfo.h" #include "fsock.h" diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 51c537de6e62..86c331f8a7c5 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Sæther Bakken | @@ -29,9 +27,9 @@ PHP_MINIT_FUNCTION(string_intrin); #endif #define strnatcmp(a, b) \ - strnatcmp_ex(a, strlen(a), b, strlen(b), 0) + strnatcmp_ex(a, strlen(a), b, strlen(b), false) #define strnatcasecmp(a, b) \ - strnatcmp_ex(a, strlen(a), b, strlen(b), 1) + strnatcmp_ex(a, strlen(a), b, strlen(b), true) PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, bool is_case_insensitive); PHPAPI struct lconv *localeconv_r(struct lconv *out); PHPAPI char *php_strtr(char *str, size_t len, const char *str_from, const char *str_to, size_t trlen); diff --git a/ext/standard/php_uuencode.h b/ext/standard/php_uuencode.h index da3d601851d9..e3d810f1c95f 100644 --- a/ext/standard/php_uuencode.h +++ b/ext/standard/php_uuencode.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h index d70bbfed814a..8839a2f3df73 100644 --- a/ext/standard/php_var.h +++ b/ext/standard/php_var.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jani Lehtimäki | +----------------------------------------------------------------------+ diff --git a/ext/standard/php_versioning.h b/ext/standard/php_versioning.h index 307ac1234a8c..da3748079aa3 100644 --- a/ext/standard/php_versioning.h +++ b/ext/standard/php_versioning.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 06a3f916a849..111111406799 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -35,7 +33,7 @@ #include #endif -#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP +#if defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) || defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) /* Only defined on glibc >= 2.29, FreeBSD CURRENT, musl >= 1.1.24, * MacOS Catalina or later.. * It should be possible to modify this so it is also @@ -45,6 +43,13 @@ */ #include #define USE_POSIX_SPAWN + +/* The non-_np variant is in macOS 26 (and _np deprecated) */ +#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir +#else +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir_np +#endif #endif /* This symbol is defined in ext/standard/config.m4. @@ -136,11 +141,11 @@ int openpty(int *master, int *slave, char *name, struct termios *termp, struct w static int le_proc_open; /* Resource number for `proc` resources */ -/* {{{ _php_array_to_envp +/* {{{ php_array_to_envp * Process the `environment` argument to `proc_open` * Convert into data structures which can be passed to underlying OS APIs like `exec` on POSIX or * `CreateProcessW` on Win32 */ -static php_process_env _php_array_to_envp(zval *environment) +ZEND_ATTRIBUTE_NONNULL static php_process_env php_array_to_envp(const HashTable *environment) { zval *element; php_process_env env; @@ -154,13 +159,9 @@ static php_process_env _php_array_to_envp(zval *environment) memset(&env, 0, sizeof(env)); - if (!environment) { - return env; - } - - uint32_t cnt = zend_hash_num_elements(Z_ARRVAL_P(environment)); + uint32_t cnt = zend_hash_num_elements(environment); - if (cnt < 1) { + if (cnt == 0) { #ifndef PHP_WIN32 env.envarray = (char **) ecalloc(1, sizeof(char *)); #endif @@ -172,7 +173,7 @@ static php_process_env _php_array_to_envp(zval *environment) zend_hash_init(env_hash, cnt, NULL, NULL, 0); /* first, we have to get the size of all the elements in the hash */ - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(environment), key, element) { + ZEND_HASH_FOREACH_STR_KEY_VAL(environment, key, element) { str = zval_get_string(element); if (ZSTR_LEN(str) == 0) { @@ -221,7 +222,7 @@ static php_process_env _php_array_to_envp(zval *environment) /* }}} */ /* {{{ _php_free_envp - * Free the structures allocated by `_php_array_to_envp` */ + * Free the structures allocated by php_array_to_envp */ static void _php_free_envp(php_process_env env) { #ifndef PHP_WIN32 @@ -506,8 +507,8 @@ typedef struct _descriptorspec_item { int mode_flags; /* mode for opening FDs: r/o, r/w, binary (on Win32), etc */ } descriptorspec_item; -static zend_string *get_valid_arg_string(zval *zv, int elem_num) { - zend_string *str = zval_get_string(zv); +static zend_string *get_valid_arg_string(zval *zv, uint32_t elem_num) { + zend_string *str = zval_try_get_string(zv); if (!str) { return NULL; } @@ -518,7 +519,7 @@ static zend_string *get_valid_arg_string(zval *zv, int elem_num) { return NULL; } - if (strlen(ZSTR_VAL(str)) != ZSTR_LEN(str)) { + if (zend_str_has_nul_byte(str)) { zend_value_error("Command array element %d contains a null byte", elem_num); zend_string_release(str); return NULL; @@ -630,7 +631,7 @@ static zend_string *create_win_command_from_args(HashTable *args) zval *arg_zv; bool is_prog_name = true; bool is_cmd_execution = false; - int elem_num = 0; + uint32_t elem_num = 0; ZEND_HASH_FOREACH_VAL(args, arg_zv) { zend_string *arg_str = get_valid_arg_string(arg_zv, ++elem_num); @@ -647,7 +648,7 @@ static zend_string *create_win_command_from_args(HashTable *args) append_win_escaped_arg(&str, arg_str, !is_prog_name && is_cmd_execution); - is_prog_name = 0; + is_prog_name = false; zend_string_release(arg_str); } ZEND_HASH_FOREACH_END(); smart_str_0(&str); @@ -778,11 +779,11 @@ static zend_result convert_command_to_use_shell(wchar_t **cmdw, size_t cmdw_len) #ifndef PHP_WIN32 /* Convert command parameter array passed as first argument to `proc_open` into command string */ -static zend_string* get_command_from_array(HashTable *array, char ***argv, int num_elems) +static zend_string* get_command_from_array(const HashTable *array, char ***argv, uint32_t num_elems) { zval *arg_zv; zend_string *command = NULL; - int i = 0; + uint32_t i = 0; *argv = safe_emalloc(sizeof(char *), num_elems + 1, 0); @@ -810,16 +811,16 @@ static zend_string* get_command_from_array(HashTable *array, char ***argv, int n } #endif -static descriptorspec_item* alloc_descriptor_array(HashTable *descriptorspec) +static descriptorspec_item* alloc_descriptor_array(const HashTable *descriptorspec) { uint32_t ndescriptors = zend_hash_num_elements(descriptorspec); return ecalloc(ndescriptors, sizeof(descriptorspec_item)); } -static zend_string* get_string_parameter(zval *array, int index, char *param_name) +static zend_string* get_string_parameter(const HashTable *ht, unsigned int index, const char *param_name) { zval *array_item; - if ((array_item = zend_hash_index_find(Z_ARRVAL_P(array), index)) == NULL) { + if ((array_item = zend_hash_index_find(ht, index)) == NULL) { zend_value_error("Missing %s", param_name); return NULL; } @@ -995,7 +996,7 @@ static zend_result dup_proc_descriptor(php_file_descriptor_t from, php_file_desc } static zend_result redirect_proc_descriptor(descriptorspec_item *desc, int target, - descriptorspec_item *descriptors, int ndesc, int nindex) + const descriptorspec_item *descriptors, int ndesc, int nindex) { php_file_descriptor_t redirect_to = PHP_INVALID_FD; @@ -1021,7 +1022,7 @@ static zend_result redirect_proc_descriptor(descriptorspec_item *desc, int targe case 0: redirect_to = GetStdHandle(STD_INPUT_HANDLE); break; case 1: redirect_to = GetStdHandle(STD_OUTPUT_HANDLE); break; case 2: redirect_to = GetStdHandle(STD_ERROR_HANDLE); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } #endif } @@ -1030,9 +1031,9 @@ static zend_result redirect_proc_descriptor(descriptorspec_item *desc, int targe } /* Process one item from `$descriptorspec` argument to `proc_open` */ -static zend_result set_proc_descriptor_from_array(zval *descitem, descriptorspec_item *descriptors, +static zend_result set_proc_descriptor_from_array(const HashTable *ht, descriptorspec_item *descriptors, int ndesc, int nindex, int *pty_master_fd, int *pty_slave_fd) { - zend_string *ztype = get_string_parameter(descitem, 0, "handle qualifier"); + zend_string *ztype = get_string_parameter(ht, 0, "handle qualifier"); if (!ztype) { return FAILURE; } @@ -1042,7 +1043,7 @@ static zend_result set_proc_descriptor_from_array(zval *descitem, descriptorspec if (zend_string_equals_literal(ztype, "pipe")) { /* Set descriptor to pipe */ - zmode = get_string_parameter(descitem, 1, "mode parameter for 'pipe'"); + zmode = get_string_parameter(ht, 1, "mode parameter for 'pipe'"); if (zmode == NULL) { goto finish; } @@ -1052,16 +1053,16 @@ static zend_result set_proc_descriptor_from_array(zval *descitem, descriptorspec retval = set_proc_descriptor_to_socket(&descriptors[ndesc]); } else if (zend_string_equals(ztype, ZSTR_KNOWN(ZEND_STR_FILE))) { /* Set descriptor to file */ - if ((zfile = get_string_parameter(descitem, 1, "file name parameter for 'file'")) == NULL) { + if ((zfile = get_string_parameter(ht, 1, "file name parameter for 'file'")) == NULL) { goto finish; } - if ((zmode = get_string_parameter(descitem, 2, "mode parameter for 'file'")) == NULL) { + if ((zmode = get_string_parameter(ht, 2, "mode parameter for 'file'")) == NULL) { goto finish; } retval = set_proc_descriptor_to_file(&descriptors[ndesc], zfile, zmode); } else if (zend_string_equals_literal(ztype, "redirect")) { /* Redirect descriptor to whatever another descriptor is set to */ - zval *ztarget = zend_hash_index_find_deref(Z_ARRVAL_P(descitem), 1); + zval *ztarget = zend_hash_index_find_deref(ht, 1); if (!ztarget) { zend_value_error("Missing redirection target"); goto finish; @@ -1116,7 +1117,7 @@ static zend_result set_proc_descriptor_from_resource(zval *resource, descriptors #ifndef PHP_WIN32 #if defined(USE_POSIX_SPAWN) -static zend_result close_parentends_of_pipes(posix_spawn_file_actions_t * actions, descriptorspec_item *descriptors, int ndesc) +static zend_result close_parentends_of_pipes(posix_spawn_file_actions_t * actions, const descriptorspec_item *descriptors, int ndesc) { int r; for (int i = 0; i < ndesc; i++) { @@ -1200,9 +1201,10 @@ PHP_FUNCTION(proc_open) HashTable *command_ht; HashTable *descriptorspec; /* Mandatory argument */ zval *pipes; /* Mandatory argument */ - char *cwd = NULL; /* Optional argument */ - size_t cwd_len = 0; /* Optional argument */ - zval *environment = NULL, *other_options = NULL; /* Optional arguments */ + char *cwd = NULL; /* Optional argument */ + size_t cwd_len = 0; /* Optional argument */ + HashTable *environment = NULL; /* Optional arguments */ + zval *other_options = NULL; /* Optional arguments */ php_process_env env; int ndesc = 0; @@ -1238,8 +1240,8 @@ PHP_FUNCTION(proc_open) Z_PARAM_ARRAY_HT(descriptorspec) Z_PARAM_ZVAL(pipes) Z_PARAM_OPTIONAL - Z_PARAM_STRING_OR_NULL(cwd, cwd_len) - Z_PARAM_ARRAY_OR_NULL(environment) + Z_PARAM_PATH_OR_NULL(cwd, cwd_len) + Z_PARAM_ARRAY_HT_OR_NULL(environment) Z_PARAM_ARRAY_OR_NULL(other_options) ZEND_PARSE_PARAMETERS_END(); @@ -1282,7 +1284,7 @@ PHP_FUNCTION(proc_open) #endif if (environment) { - env = _php_array_to_envp(environment); + env = php_array_to_envp(environment); } descriptors = alloc_descriptor_array(descriptorspec); @@ -1302,7 +1304,7 @@ PHP_FUNCTION(proc_open) goto exit_fail; } } else if (Z_TYPE_P(descitem) == IS_ARRAY) { - if (set_proc_descriptor_from_array(descitem, descriptors, ndesc, (int)nindex, + if (set_proc_descriptor_from_array(Z_ARRVAL_P(descitem), descriptors, ndesc, (int)nindex, &pty_master_fd, &pty_slave_fd) == FAILURE) { goto exit_fail; } @@ -1397,9 +1399,9 @@ PHP_FUNCTION(proc_open) } if (cwd) { - r = posix_spawn_file_actions_addchdir_np(&factions, cwd); + r = POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR(&factions, cwd); if (r != 0) { - php_error_docref(NULL, E_WARNING, "posix_spawn_file_actions_addchdir_np() failed: %s", strerror(r)); + php_error_docref(NULL, E_WARNING, ZEND_TOSTR(POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) "() failed: %s", strerror(r)); } } diff --git a/ext/standard/proc_open.h b/ext/standard/proc_open.h index 2dba712f995f..6a9e0533bfd2 100644 --- a/ext/standard/proc_open.h +++ b/ext/standard/proc_open.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/standard/quot_print.c b/ext/standard/quot_print.c index a7132df2f7fd..e9d8fafb9987 100644 --- a/ext/standard/quot_print.c +++ b/ext/standard/quot_print.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kirill Maximov | +----------------------------------------------------------------------+ @@ -212,11 +210,11 @@ PHP_FUNCTION(quoted_printable_decode) switch (str_in[i]) { case '=': if (str_in[i + 1] && str_in[i + 2] && - isxdigit((int) str_in[i + 1]) && - isxdigit((int) str_in[i + 2])) + isxdigit((unsigned char)str_in[i + 1]) && + isxdigit((unsigned char)str_in[i + 2])) { - ZSTR_VAL(str_out)[j++] = (php_hex2int((int) str_in[i + 1]) << 4) - + php_hex2int((int) str_in[i + 2]); + ZSTR_VAL(str_out)[j++] = (php_hex2int((unsigned char)str_in[i + 1]) << 4) + + php_hex2int((unsigned char)str_in[i + 2]); i += 3; } else /* check for soft line break according to RFC 2045*/ { k = 1; diff --git a/ext/standard/quot_print.h b/ext/standard/quot_print.h index 11b829d974b8..faf515210695 100644 --- a/ext/standard/quot_print.h +++ b/ext/standard/quot_print.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Kirill Maximov (kir@rus.net) | +----------------------------------------------------------------------+ diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index 408e5ede8881..5aeb585fea23 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Clayton Collie | +----------------------------------------------------------------------+ @@ -345,7 +343,7 @@ PHPAPI int ValidateFormat(char *format, int numVars, int *totalSubs) goto xpgCheckDone; } - if ( isdigit( (int)*ch ) ) { + if ( isdigit( (unsigned char)*ch ) ) { /* * Check for an XPG3-style %n$ specification. Note: there * must not be a mixture of XPG3 specs and non-XPG3 specs @@ -656,9 +654,9 @@ PHPAPI int php_sscanf_internal( char *string, char *format, /* * If we see whitespace in the format, skip whitespace in the string. */ - if ( isspace( (int)*ch ) ) { + if ( isspace( (unsigned char)*ch ) ) { sch = *string; - while ( isspace( (int)sch ) ) { + while ( isspace( (unsigned char)sch ) ) { if (*string == '\0') { goto done; } @@ -809,7 +807,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format, if (!(flags & SCAN_NOSKIP)) { while (*string != '\0') { sch = *string; - if (! isspace((int)sch) ) { + if (! isspace((unsigned char)sch) ) { break; } string++; @@ -835,7 +833,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format, end = string; while (*end != '\0') { sch = *end; - if ( isspace( (int)sch ) ) { + if ( isspace( (unsigned char)sch ) ) { break; } end++; diff --git a/ext/standard/scanf.h b/ext/standard/scanf.h index d2ef2fc0f2e8..c60a2b664ad4 100644 --- a/ext/standard/scanf.h +++ b/ext/standard/scanf.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Clayton Collie | +----------------------------------------------------------------------+ diff --git a/ext/standard/sha1.c b/ext/standard/sha1.c index 95f2b54d0fd0..4832756f577a 100644 --- a/ext/standard/sha1.c +++ b/ext/standard/sha1.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ diff --git a/ext/standard/sha1.h b/ext/standard/sha1.h index 046d6db2cc47..a1f4801736b1 100644 --- a/ext/standard/sha1.h +++ b/ext/standard/sha1.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stefan Esser | +----------------------------------------------------------------------+ diff --git a/ext/standard/soundex.c b/ext/standard/soundex.c index 5c45f4d3ef67..f06c3ac98572 100644 --- a/ext/standard/soundex.c +++ b/ext/standard/soundex.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Bjørn Borud - Guardian Networks AS | +----------------------------------------------------------------------+ @@ -65,7 +63,7 @@ PHP_FUNCTION(soundex) /* BUG: should also map here accented letters used in non */ /* English words or names (also found in English text!): */ /* esstsett, thorn, n-tilde, c-cedilla, s-caron, ... */ - code = toupper((int)(unsigned char)str[i]); + code = toupper((unsigned char)str[i]); if (code >= 'A' && code <= 'Z') { if (_small == 0) { /* remember first valid char */ diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 818a645086b0..68f79783c6f8 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Sara Golemon | @@ -99,7 +97,6 @@ PHP_FUNCTION(stream_socket_client) zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL; double timeout; bool timeout_is_null = 1; - php_timeout_ull conv; struct timeval tv; char *hashkey = NULL; php_stream *stream = NULL; @@ -138,7 +135,7 @@ PHP_FUNCTION(stream_socket_client) if (timeout < 0.0 || timeout >= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0) { tv_pointer = NULL; } else { - conv = (php_timeout_ull) (timeout * 1000000.0); + php_timeout_ull conv = (php_timeout_ull) (timeout * 1000000.0); #ifdef PHP_WIN32 tv.tv_sec = (long)(conv / 1000000); tv.tv_usec = (long)(conv % 1000000); @@ -262,7 +259,6 @@ PHP_FUNCTION(stream_socket_accept) bool timeout_is_null = 1; zval *zpeername = NULL; zend_string *peername = NULL; - php_timeout_ull conv; struct timeval tv; php_stream *stream = NULL, *clistream = NULL; zend_string *errstr = NULL; @@ -286,7 +282,7 @@ PHP_FUNCTION(stream_socket_accept) if (timeout < 0.0 || timeout >= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0) { tv_pointer = NULL; } else { - conv = (php_timeout_ull) (timeout * 1000000.0); + php_timeout_ull conv = (php_timeout_ull) (timeout * 1000000.0); #ifdef PHP_WIN32 tv.tv_sec = (long)(conv / 1000000); tv.tv_usec = (long)(conv % 1000000); @@ -484,7 +480,6 @@ PHP_FUNCTION(stream_copy_to_stream) zend_long maxlen, pos = 0; bool maxlen_is_null = 1; size_t len; - int ret; ZEND_PARSE_PARAMETERS_START(2, 4) PHP_Z_PARAM_STREAM(src) @@ -503,9 +498,7 @@ PHP_FUNCTION(stream_copy_to_stream) RETURN_FALSE; } - ret = php_stream_copy_to_stream_ex(src, dest, maxlen, &len); - - if (ret != SUCCESS) { + if (php_stream_copy_to_stream_ex(src, dest, maxlen, &len) != SUCCESS) { RETURN_FALSE; } RETURN_LONG(len); @@ -534,9 +527,9 @@ PHP_FUNCTION(stream_get_meta_data) add_assoc_zval(return_value, "wrapper_data", &stream->wrapperdata); } if (stream->wrapper) { - add_assoc_string(return_value, "wrapper_type", (char *)stream->wrapper->wops->label); + add_assoc_string(return_value, "wrapper_type", stream->wrapper->wops->label); } - add_assoc_string(return_value, "stream_type", (char *)stream->ops->label); + add_assoc_string(return_value, "stream_type", stream->ops->label); add_assoc_string(return_value, "mode", stream->mode); @@ -548,7 +541,7 @@ PHP_FUNCTION(stream_get_meta_data) array_init(newval); for (filter = stream->filterhead; filter != NULL; filter = filter->next) { - add_next_index_string(newval, (char *)filter->fops->label); + add_next_index_string(newval, filter->fops->label); } add_assoc_zval(return_value, "filters", newval); @@ -568,13 +561,13 @@ PHP_FUNCTION(stream_get_meta_data) /* {{{ Retrieves list of registered socket transports */ PHP_FUNCTION(stream_get_transports) { - HashTable *stream_xport_hash; - zend_string *stream_xport; ZEND_PARSE_PARAMETERS_NONE(); - stream_xport_hash = php_stream_xport_get_hash(); array_init(return_value); + + const HashTable *stream_xport_hash = php_stream_xport_get_hash(); + zend_string *stream_xport; ZEND_HASH_MAP_FOREACH_STR_KEY(stream_xport_hash, stream_xport) { add_next_index_str(return_value, zend_string_copy(stream_xport)); } ZEND_HASH_FOREACH_END(); @@ -584,13 +577,12 @@ PHP_FUNCTION(stream_get_transports) /* {{{ Retrieves list of registered stream wrappers */ PHP_FUNCTION(stream_get_wrappers) { - HashTable *url_stream_wrappers_hash; - zend_string *stream_protocol; - ZEND_PARSE_PARAMETERS_NONE(); - url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash(); array_init(return_value); + + const HashTable *url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash(); + zend_string *stream_protocol; ZEND_HASH_MAP_FOREACH_STR_KEY(url_stream_wrappers_hash, stream_protocol) { if (stream_protocol) { add_next_index_str(return_value, zend_string_copy(stream_protocol)); @@ -601,17 +593,13 @@ PHP_FUNCTION(stream_get_wrappers) /* }}} */ /* {{{ stream_select related functions */ -static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t *max_fd) +static int stream_array_to_fd_set(const HashTable *stream_array, fd_set *fds, php_socket_t *max_fd) { zval *elem; php_stream *stream; int cnt = 0; - if (Z_TYPE_P(stream_array) != IS_ARRAY) { - return 0; - } - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) { + ZEND_HASH_FOREACH_VAL(stream_array, elem) { /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast() would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave the higher bits of a SOCKET variable uninitialized on systems with little endian. */ @@ -640,7 +628,7 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t return cnt ? 1 : 0; } -static int stream_array_from_fd_set(zval *stream_array, fd_set *fds) +static int stream_array_from_fd_set(zval *stream_array, const fd_set *fds) { zval *elem, *dest_elem; HashTable *ht; @@ -649,9 +637,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds) zend_string *key; zend_ulong num_ind; - if (Z_TYPE_P(stream_array) != IS_ARRAY) { - return 0; - } + ZEND_ASSERT(Z_TYPE_P(stream_array) == IS_ARRAY); ht = zend_new_array(zend_hash_num_elements(Z_ARRVAL_P(stream_array))); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) { @@ -677,7 +663,6 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds) zval_add_ref(dest_elem); ret++; - continue; } } } ZEND_HASH_FOREACH_END(); @@ -698,9 +683,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array) zend_ulong num_ind; zend_string *key; - if (Z_TYPE_P(stream_array) != IS_ARRAY) { - return 0; - } + ZEND_ASSERT(Z_TYPE_P(stream_array) == IS_ARRAY); ht = zend_new_array(zend_hash_num_elements(Z_ARRVAL_P(stream_array))); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) { @@ -723,7 +706,6 @@ static int stream_array_emulate_read_fd_set(zval *stream_array) } zval_add_ref(dest_elem); ret++; - continue; } } ZEND_HASH_FOREACH_END(); @@ -766,21 +748,21 @@ PHP_FUNCTION(stream_select) FD_ZERO(&efds); if (r_array != NULL) { - set_count = stream_array_to_fd_set(r_array, &rfds, &max_fd); + set_count = stream_array_to_fd_set(Z_ARR_P(r_array), &rfds, &max_fd); if (set_count > max_set_count) max_set_count = set_count; sets += set_count; } if (w_array != NULL) { - set_count = stream_array_to_fd_set(w_array, &wfds, &max_fd); + set_count = stream_array_to_fd_set(Z_ARR_P(w_array), &wfds, &max_fd); if (set_count > max_set_count) max_set_count = set_count; sets += set_count; } if (e_array != NULL) { - set_count = stream_array_to_fd_set(e_array, &efds, &max_fd); + set_count = stream_array_to_fd_set(Z_ARR_P(e_array), &efds, &max_fd); if (set_count > max_set_count) max_set_count = set_count; sets += set_count; @@ -856,10 +838,7 @@ PHP_FUNCTION(stream_select) static void user_space_stream_notifier(php_stream_context *context, int notifycode, int severity, char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr) { - zval *callback = &context->notifier->ptr; - zval retval; zval zvs[6]; - int i; ZVAL_LONG(&zvs[0], notifycode); ZVAL_LONG(&zvs[1], severity); @@ -872,24 +851,20 @@ static void user_space_stream_notifier(php_stream_context *context, int notifyco ZVAL_LONG(&zvs[4], bytes_sofar); ZVAL_LONG(&zvs[5], bytes_max); - if (FAILURE == call_user_function(NULL, NULL, callback, &retval, 6, zvs)) { - php_error_docref(NULL, E_WARNING, "Failed to call user notifier"); - } - for (i = 0; i < 6; i++) { - zval_ptr_dtor(&zvs[i]); - } - zval_ptr_dtor(&retval); + zend_call_known_fcc(context->notifier->ptr, NULL, 6, zvs, NULL); + /* Free refcounted string parameter */ + zval_ptr_dtor_str(&zvs[2]); } static void user_space_stream_notifier_dtor(php_stream_notifier *notifier) { - if (notifier && Z_TYPE(notifier->ptr) != IS_UNDEF) { - zval_ptr_dtor(¬ifier->ptr); - ZVAL_UNDEF(¬ifier->ptr); - } + zend_fcall_info_cache *fcc = notifier->ptr; + zend_fcc_dtor(fcc); + efree(notifier->ptr); + notifier->ptr = NULL; } -static zend_result parse_context_options(php_stream_context *context, HashTable *options) +static zend_result parse_context_options(php_stream_context *context, const HashTable *options) { zval *wval, *oval; zend_string *wkey, *okey; @@ -913,7 +888,7 @@ static zend_result parse_context_options(php_stream_context *context, HashTable return SUCCESS; } -static zend_result parse_context_params(php_stream_context *context, HashTable *params) +static zend_result parse_context_params(php_stream_context *context, const HashTable *params) { zval *tmp; @@ -924,9 +899,19 @@ static zend_result parse_context_params(php_stream_context *context, HashTable * context->notifier = NULL; } + zend_fcall_info_cache *fcc = emalloc(sizeof(*fcc)); + char *error; + if (!zend_is_callable_ex(tmp, NULL, 0, NULL, fcc, &error)) { + zend_argument_type_error(1, "must be an array with valid callbacks as values, %s", error); + efree(fcc); + efree(error); + return FAILURE; + } + zend_fcc_addref(fcc); + context->notifier = php_stream_notification_alloc(); context->notifier->func = user_space_stream_notifier; - ZVAL_COPY(&context->notifier->ptr, tmp); + context->notifier->ptr = fcc; context->notifier->dtor = user_space_stream_notifier_dtor; } if (NULL != (tmp = zend_hash_str_find(params, "options", sizeof("options")-1))) { @@ -1123,9 +1108,11 @@ PHP_FUNCTION(stream_context_get_params) } array_init(return_value); - if (context->notifier && Z_TYPE(context->notifier->ptr) != IS_UNDEF && context->notifier->func == user_space_stream_notifier) { - Z_TRY_ADDREF(context->notifier->ptr); - add_assoc_zval_ex(return_value, "notification", sizeof("notification")-1, &context->notifier->ptr); + if (context->notifier && context->notifier->func == user_space_stream_notifier) { + zend_fcall_info_cache *fcc = context->notifier->ptr; + zval fn; + zend_get_callable_zval_from_fcc(fcc, &fn); + add_assoc_zval_ex(return_value, ZEND_STRL("notification"), &fn); } Z_TRY_ADDREF(context->options); add_assoc_zval_ex(return_value, "options", sizeof("options")-1, &context->options); @@ -1213,7 +1200,7 @@ PHP_FUNCTION(stream_context_create) /* }}} */ /* {{{ streams filter functions */ -static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) +static void apply_filter_to_stream(bool append, INTERNAL_FUNCTION_PARAMETERS) { php_stream *stream; char *filtername; @@ -1221,7 +1208,6 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) zend_long read_write = 0; zval *filterparams = NULL; php_stream_filter *filter = NULL; - int ret; ZEND_PARSE_PARAMETERS_START(2, 4) PHP_Z_PARAM_STREAM(stream) @@ -1252,13 +1238,13 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) } if (append) { - ret = php_stream_filter_append_ex(&stream->readfilters, filter); + zend_result ret = php_stream_filter_append_ex(&stream->readfilters, filter); + if (ret != SUCCESS) { + php_stream_filter_remove(filter, 1); + RETURN_FALSE; + } } else { - ret = php_stream_filter_prepend_ex(&stream->readfilters, filter); - } - if (ret != SUCCESS) { - php_stream_filter_remove(filter, 1); - RETURN_FALSE; + php_stream_filter_prepend_ex(&stream->readfilters, filter); } } @@ -1269,13 +1255,13 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) } if (append) { - ret = php_stream_filter_append_ex(&stream->writefilters, filter); + zend_result ret = php_stream_filter_append_ex(&stream->writefilters, filter); + if (ret != SUCCESS) { + php_stream_filter_remove(filter, 1); + RETURN_FALSE; + } } else { - ret = php_stream_filter_prepend_ex(&stream->writefilters, filter); - } - if (ret != SUCCESS) { - php_stream_filter_remove(filter, 1); - RETURN_FALSE; + php_stream_filter_prepend_ex(&stream->writefilters, filter); } } @@ -1373,11 +1359,7 @@ PHP_FUNCTION(stream_set_blocking) Z_PARAM_BOOL(block) ZEND_PARSE_PARAMETERS_END(); - if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL) == -1) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(-1 != php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL)); } /* }}} */ @@ -1418,11 +1400,7 @@ PHP_FUNCTION(stream_set_timeout) } #endif - if (PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)) { - RETURN_TRUE; - } - - RETURN_FALSE; + RETURN_BOOL(PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &t)); } #endif /* HAVE_SYS_TIME_H || defined(PHP_WIN32) */ /* }}} */ @@ -1598,11 +1576,7 @@ PHP_FUNCTION(stream_is_local) wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(zstream), NULL, 0); } - if (!wrapper) { - RETURN_FALSE; - } - - RETURN_BOOL(wrapper->is_url==0); + RETURN_BOOL(wrapper && wrapper->is_url == 0); } /* }}} */ @@ -1615,11 +1589,7 @@ PHP_FUNCTION(stream_supports_lock) PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - if (!php_stream_supports_lock(stream)) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(php_stream_supports_lock(stream)); } /* {{{ Check if a stream is a TTY. */ @@ -1646,15 +1616,13 @@ PHP_FUNCTION(stream_isatty) #ifdef PHP_WIN32 /* Check if the Windows standard handle is redirected to file */ - RETVAL_BOOL(php_win32_console_fileno_is_console(fileno)); + RETURN_BOOL(php_win32_console_fileno_is_console(fileno)); #elif defined(HAVE_UNISTD_H) /* Check if the file descriptor identifier is a terminal */ - RETVAL_BOOL(isatty(fileno)); + RETURN_BOOL(isatty(fileno)); #else - { - zend_stat_t stat = {0}; - RETVAL_BOOL(zend_fstat(fileno, &stat) == 0 && (stat.st_mode & /*S_IFMT*/0170000) == /*S_IFCHR*/0020000); - } + zend_stat_t stat = {0}; + RETURN_BOOL(zend_fstat(fileno, &stat) == 0 && (stat.st_mode & /*S_IFMT*/0170000) == /*S_IFCHR*/0020000); #endif } @@ -1700,21 +1668,10 @@ PHP_FUNCTION(sapi_windows_vt100_support) if (enable_is_null) { /* Check if the Windows standard handle has VT100 control codes enabled */ - if (php_win32_console_fileno_has_vt100(fileno)) { - RETURN_TRUE; - } - else { - RETURN_FALSE; - } - } - else { + RETURN_BOOL(php_win32_console_fileno_has_vt100(fileno)); + } else { /* Enable/disable VT100 control codes support for the specified Windows standard handle */ - if (php_win32_console_fileno_set_vt100(fileno, enable ? TRUE : FALSE)) { - RETURN_TRUE; - } - else { - RETURN_FALSE; - } + RETURN_BOOL(php_win32_console_fileno_set_vt100(fileno, enable ? TRUE : FALSE)); } } #endif diff --git a/ext/standard/streamsfuncs.h b/ext/standard/streamsfuncs.h index 41058472473d..7d6f523bfcd0 100644 --- a/ext/standard/streamsfuncs.h +++ b/ext/standard/streamsfuncs.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/standard/string.c b/ext/standard/string.c index 36903b3c5c7b..7ded14366a9f 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Stig Sæther Bakken | @@ -515,11 +513,16 @@ static inline zend_result php_charmask(const unsigned char *input, size_t len, c } /* }}} */ +static zend_always_inline bool php_is_whitespace(unsigned char c) +{ + return c <= ' ' && (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0'); +} + /* {{{ php_trim_int() * mode 1 : trim left * mode 2 : trim right * mode 3 : trim left and right - * what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') + * what indicates which chars are to be trimmed. NULL->default (' \f\t\n\r\v\0') */ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char *what, size_t what_len, int mode) { @@ -573,10 +576,7 @@ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char } else { if (mode & 1) { while (start != end) { - unsigned char c = (unsigned char)*start; - - if (c <= ' ' && - (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0')) { + if (php_is_whitespace((unsigned char)*start)) { start++; } else { break; @@ -585,10 +585,7 @@ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char } if (mode & 2) { while (start != end) { - unsigned char c = (unsigned char)*(end-1); - - if (c <= ' ' && - (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0')) { + if (php_is_whitespace((unsigned char)*(end-1))) { end--; } else { break; @@ -611,7 +608,7 @@ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char * mode 1 : trim left * mode 2 : trim right * mode 3 : trim left and right - * what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') + * what indicates which chars are to be trimmed. NULL->default (' \f\t\n\r\v\0') */ PHPAPI zend_string *php_trim(zend_string *str, const char *what, size_t what_len, int mode) { @@ -1026,7 +1023,11 @@ PHPAPI void php_implode(const zend_string *glue, HashTable *pieces, zval *return } cptr -= ZSTR_LEN(glue); - memcpy(cptr, ZSTR_VAL(glue), ZSTR_LEN(glue)); + if (ZSTR_LEN(glue) == 1) { + *cptr = ZSTR_VAL(glue)[0]; + } else { + memcpy(cptr, ZSTR_VAL(glue), ZSTR_LEN(glue)); + } } free_alloca(strings, use_heap); @@ -1344,15 +1345,15 @@ static bool _is_basename_start(const char *start, const char *pos) && *(pos-1) != '/' && *(pos-1) != '\\') { if (pos - start == 1) { - return 1; + return true; } else if (*(pos-2) == '/' || *(pos-2) == '\\') { - return 1; + return true; } else if (*(pos-2) == ':' && _is_basename_start(start, pos - 2)) { - return 1; + return true; } } - return 0; + return false; } #endif @@ -1496,7 +1497,7 @@ PHPAPI size_t php_dirname(char *path, size_t len) } /* }}} */ -static inline void _zend_dirname(zval *return_value, zend_string *str, zend_long levels) +static zend_always_inline void _zend_dirname(zval *return_value, zend_string *str, zend_long levels) { zend_string *ret; @@ -1588,6 +1589,16 @@ PHP_FUNCTION(pathinfo) Z_PARAM_LONG(opt) ZEND_PARSE_PARAMETERS_END(); + if (opt < PHP_PATHINFO_DIRNAME || opt > PHP_PATHINFO_ALL) { + zend_argument_value_error(2, "must be one of the PATHINFO_* constants"); + RETURN_THROWS(); + } + + if (opt < PHP_PATHINFO_ALL && (opt & (opt - 1))) { + zend_argument_value_error(2, "must be only one of the PATHINFO_* constants"); + RETURN_THROWS(); + } + have_basename = (opt & PHP_PATHINFO_BASENAME); array_init(&tmp); @@ -1741,7 +1752,7 @@ PHP_FUNCTION(stristr) } /* }}} */ -static inline void _zend_strstr(zval *return_value, zend_string *haystack, zend_string *needle, bool part) +static zend_always_inline void _zend_strstr(zval *return_value, zend_string *haystack, zend_string *needle, bool part) { const char *found = NULL; zend_long found_offset; @@ -1885,7 +1896,7 @@ PHP_FUNCTION(str_ends_with) } /* }}} */ -static inline void _zend_strpos(zval *return_value, zend_string *haystack, zend_string *needle, zend_long offset) +static zend_always_inline void _zend_strpos(zval *return_value, zend_string *haystack, zend_string *needle, zend_long offset) { const char *found = NULL; @@ -2105,13 +2116,11 @@ PHP_FUNCTION(strripos) needle_dup = zend_string_tolower(needle); if ((found = (char *)zend_memnrstr(p, ZSTR_VAL(needle_dup), ZSTR_LEN(needle_dup), e))) { RETVAL_LONG(found - ZSTR_VAL(haystack_dup)); - zend_string_release_ex(needle_dup, 0); - zend_string_release_ex(haystack_dup, 0); } else { - zend_string_release_ex(needle_dup, 0); - zend_string_release_ex(haystack_dup, 0); - RETURN_FALSE; + RETVAL_FALSE; } + zend_string_release_ex(needle_dup, false); + zend_string_release_ex(haystack_dup, false); } /* }}} */ @@ -2202,10 +2211,10 @@ PHP_FUNCTION(chunk_split) if ((size_t)chunklen > ZSTR_LEN(str)) { /* to maintain BC, we must return original string + ending */ - result = zend_string_safe_alloc(ZSTR_LEN(str), 1, endlen, 0); - memcpy(ZSTR_VAL(result), ZSTR_VAL(str), ZSTR_LEN(str)); - memcpy(ZSTR_VAL(result) + ZSTR_LEN(str), end, endlen); - ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0'; + result = zend_string_concat2( + ZSTR_VAL(str), ZSTR_LEN(str), + end, endlen + ); RETURN_NEW_STR(result); } @@ -2404,7 +2413,7 @@ PHP_FUNCTION(substr_replace) if (repl_idx < repl_ht->nNumUsed) { repl_str = zval_get_tmp_string(tmp_repl, &tmp_repl_str); } else { - repl_str = STR_EMPTY_ALLOC(); + repl_str = ZSTR_EMPTY_ALLOC(); } } @@ -2651,6 +2660,15 @@ PHP_FUNCTION(ord) Z_PARAM_STR(str) ZEND_PARSE_PARAMETERS_END(); + if (UNEXPECTED(ZSTR_LEN(str) != 1)) { + if (ZSTR_LEN(str) == 0) { + php_error_docref(NULL, E_DEPRECATED, + "Providing an empty string is deprecated"); + } else { + php_error_docref(NULL, E_DEPRECATED, + "Providing a string that is not one byte long is deprecated. Use ord($str[0]) instead"); + } + } RETURN_LONG((unsigned char) ZSTR_VAL(str)[0]); } /* }}} */ @@ -2665,6 +2683,12 @@ PHP_FUNCTION(chr) Z_PARAM_LONG(c) ZEND_PARSE_PARAMETERS_END(); + if (UNEXPECTED(c < 0 || c > 255)) { + php_error_docref(NULL, E_DEPRECATED, + "Providing a value not in-between 0 and 255 is deprecated," + " this is because a byte value must be in the [0, 255] interval." + " The value used will be constrained using %% 256"); + } c &= 0xff; RETURN_CHAR(c); } @@ -2953,7 +2977,7 @@ static void php_strtr_array_ex(zval *return_value, zend_string *input, HashTable len = ZSTR_LEN(key_used); if (UNEXPECTED(len > slen)) { /* skip long patterns */ - zend_string_release(key_used); + zend_string_release_ex(key_used, false); continue; } if (len > maxlen) { @@ -3736,9 +3760,9 @@ PHPAPI void php_stripcslashes(zend_string *str) case 'f': *target++='\f'; nlen--; break; case '\\': *target++='\\'; nlen--; break; case 'x': - if (source+1 < end && isxdigit((int)(*(source+1)))) { + if (source+1 < end && isxdigit((unsigned char)source[1])) { numtmp[0] = *++source; - if (source+1 < end && isxdigit((int)(*(source+1)))) { + if (source+1 < end && isxdigit((unsigned char)source[1])) { numtmp[1] = *++source; numtmp[2] = '\0'; nlen-=3; @@ -4593,7 +4617,7 @@ PHP_FUNCTION(hebrev) do { if (block_type == _HEB_BLOCK_TYPE_HEB) { - while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end block_start) { + while ((_isblank((int)*tmp) || ispunct((unsigned char)*tmp)) && *tmp!='/' && *tmp!='-' && block_end > block_start) { tmp--; block_end--; } @@ -4937,17 +4961,18 @@ PHP_FUNCTION(setlocale) zend_string **strings = do_alloca(sizeof(zend_string *) * num_args, use_heap); for (uint32_t i = 0; i < num_args; i++) { - if (UNEXPECTED(Z_TYPE(args[i]) != IS_ARRAY && !zend_parse_arg_str(&args[i], &strings[i], false, i + 2))) { - zend_wrong_parameter_type_error(i + 2, Z_EXPECTED_ARRAY_OR_STRING, &args[i]); + if (UNEXPECTED(Z_TYPE(args[i]) != IS_ARRAY && !zend_parse_arg_str(&args[i], &strings[i], true, i + 2))) { + zend_wrong_parameter_type_error(i + 2, Z_EXPECTED_ARRAY_OR_STRING_OR_NULL, &args[i]); goto out; } } for (uint32_t i = 0; i < num_args; i++) { + zend_string *result; if (Z_TYPE(args[i]) == IS_ARRAY) { zval *elem; ZEND_HASH_FOREACH_VAL(Z_ARRVAL(args[i]), elem) { - zend_string *result = try_setlocale_zval(cat, elem); + result = try_setlocale_zval(cat, elem); if (EG(exception)) { goto out; } @@ -4956,15 +4981,18 @@ PHP_FUNCTION(setlocale) goto out; } } ZEND_HASH_FOREACH_END(); + continue; + } else if (Z_ISNULL(args[i])) { + result = try_setlocale_str(cat, ZSTR_EMPTY_ALLOC()); } else { - zend_string *result = try_setlocale_str(cat, strings[i]); - if (EG(exception)) { - goto out; - } - if (result) { - RETVAL_STR(result); - goto out; - } + result = try_setlocale_str(cat, strings[i]); + } + if (EG(exception)) { + goto out; + } + if (result) { + RETVAL_STR(result); + goto out; } } @@ -4984,7 +5012,7 @@ PHP_FUNCTION(parse_str) size_t arglen; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_STRING(arg, arglen) + Z_PARAM_PATH(arg, arglen) Z_PARAM_ZVAL(arrayArg) ZEND_PARSE_PARAMETERS_END(); @@ -5013,11 +5041,11 @@ static bool php_tag_find(char *tag, size_t len, const char *set) { char c, *n; const char *t; int state = 0; - bool done = 0; + bool done = false; char *norm; if (len == 0) { - return 0; + return false; } norm = emalloc(len+1); @@ -5036,10 +5064,10 @@ static bool php_tag_find(char *tag, size_t len, const char *set) { *(n++) = c; break; case '>': - done =1; + done = true; break; default: - if (!isspace((int)c)) { + if (!isspace((unsigned char)c)) { if (state == 0) { state=1; } @@ -5048,7 +5076,7 @@ static bool php_tag_find(char *tag, size_t len, const char *set) { } } else { if (state == 1) - done=1; + done = true; } break; } @@ -5057,9 +5085,9 @@ static bool php_tag_find(char *tag, size_t len, const char *set) { *(n++) = '>'; *n = '\0'; if (strstr(set, norm)) { - done=1; + done = true; } else { - done=0; + done = false; } efree(norm); return done; @@ -5068,7 +5096,7 @@ static bool php_tag_find(char *tag, size_t len, const char *set) { PHPAPI size_t php_strip_tags(char *rbuf, size_t len, const char *allow, size_t allow_len) /* {{{ */ { - return php_strip_tags_ex(rbuf, len, allow, allow_len, 0); + return php_strip_tags_ex(rbuf, len, allow, allow_len, false); } /* }}} */ @@ -5129,7 +5157,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_ if (in_q) { break; } - if (isspace(*(p + 1)) && !allow_tag_spaces) { + if (isspace((unsigned char)p[1]) && !allow_tag_spaces) { *(rp++) = c; break; } @@ -5176,7 +5204,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_ if (in_q) { break; } - if (isspace(*(p + 1)) && !allow_tag_spaces) { + if (isspace((unsigned char)p[1]) && !allow_tag_spaces) { goto reg_char_1; } depth++; @@ -5733,6 +5761,27 @@ PHP_FUNCTION(substr_count) } /* }}} */ +static void php_str_pad_fill(zend_string *result, size_t pad_chars, const char *pad_str, size_t pad_str_len) { + char *p = ZSTR_VAL(result) + ZSTR_LEN(result); + + if (pad_str_len == 1) { + memset(p, pad_str[0], pad_chars); + ZSTR_LEN(result) += pad_chars; + return; + } + + const char *end = p + pad_chars; + while (p + pad_str_len <= end) { + p = zend_mempcpy(p, pad_str, pad_str_len); + } + + if (p < end) { + memcpy(p, pad_str, end - p); + } + + ZSTR_LEN(result) += pad_chars; +} + /* {{{ Returns input string padded on the left or right to specified length with pad_string */ PHP_FUNCTION(str_pad) { @@ -5745,7 +5794,7 @@ PHP_FUNCTION(str_pad) char *pad_str = " "; /* Pointer to padding string */ size_t pad_str_len = 1; zend_long pad_type_val = PHP_STR_PAD_RIGHT; /* The padding type value */ - size_t i, left_pad=0, right_pad=0; + size_t left_pad=0, right_pad=0; zend_string *result = NULL; /* Resulting string */ ZEND_PARSE_PARAMETERS_START(2, 4) @@ -5795,16 +5844,18 @@ PHP_FUNCTION(str_pad) } /* First we pad on the left. */ - for (i = 0; i < left_pad; i++) - ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len]; + if (left_pad > 0) { + php_str_pad_fill(result, left_pad, pad_str, pad_str_len); + } /* Then we copy the input string. */ memcpy(ZSTR_VAL(result) + ZSTR_LEN(result), ZSTR_VAL(input), ZSTR_LEN(input)); ZSTR_LEN(result) += ZSTR_LEN(input); /* Finally, we pad on the right. */ - for (i = 0; i < right_pad; i++) - ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len]; + if (right_pad > 0) { + php_str_pad_fill(result, right_pad, pad_str, pad_str_len); + } ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0'; @@ -5829,7 +5880,8 @@ PHP_FUNCTION(sscanf) result = php_sscanf_internal(str, format, num_args, args, 0, return_value); if (SCAN_ERROR_WRONG_PARAM_COUNT == result) { - WRONG_PARAM_COUNT; + zend_wrong_param_count(); + RETURN_THROWS(); } } /* }}} */ @@ -6108,23 +6160,31 @@ PHP_FUNCTION(str_split) } array_init_size(return_value, 1); - add_next_index_stringl(return_value, ZSTR_VAL(str), ZSTR_LEN(str)); + GC_TRY_ADDREF(str); + add_next_index_str(return_value, str); return; } array_init_size(return_value, (uint32_t)(((ZSTR_LEN(str) - 1) / split_length) + 1)); + zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); n_reg_segments = ZSTR_LEN(str) / split_length; p = ZSTR_VAL(str); - while (n_reg_segments-- > 0) { - add_next_index_stringl(return_value, p, split_length); - p += split_length; - } + ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { + zval zv; + while (n_reg_segments-- > 0) { + ZEND_ASSERT(split_length > 0); + ZVAL_STRINGL_FAST(&zv, p, split_length); + ZEND_HASH_FILL_ADD(&zv); + p += split_length; + } - if (p != (ZSTR_VAL(str) + ZSTR_LEN(str))) { - add_next_index_stringl(return_value, p, (ZSTR_VAL(str) + ZSTR_LEN(str) - p)); - } + if (p != (ZSTR_VAL(str) + ZSTR_LEN(str))) { + ZVAL_STRINGL_FAST(&zv, p, (ZSTR_VAL(str) + ZSTR_LEN(str) - p)); + ZEND_HASH_FILL_ADD(&zv); + } + } ZEND_HASH_FILL_END(); } /* }}} */ diff --git a/ext/standard/strnatcmp.c b/ext/standard/strnatcmp.c index 3c3f5a99232f..583cbb5dc47a 100644 --- a/ext/standard/strnatcmp.c +++ b/ext/standard/strnatcmp.c @@ -40,12 +40,12 @@ compare_right(char const **a, char const *aend, char const **b, char const *bend both numbers to know that they have the same magnitude, so we remember it in BIAS. */ for(;; (*a)++, (*b)++) { - if ((*a == aend || !isdigit((int)(unsigned char)**a)) && - (*b == bend || !isdigit((int)(unsigned char)**b))) + if ((*a == aend || !isdigit((unsigned char)**a)) && + (*b == bend || !isdigit((unsigned char)**b))) return bias; - else if (*a == aend || !isdigit((int)(unsigned char)**a)) + else if (*a == aend || !isdigit((unsigned char)**a)) return -1; - else if (*b == bend || !isdigit((int)(unsigned char)**b)) + else if (*b == bend || !isdigit((unsigned char)**b)) return +1; else if (**a < **b) { if (!bias) @@ -67,12 +67,12 @@ compare_left(char const **a, char const *aend, char const **b, char const *bend) /* Compare two left-aligned numbers: the first to have a different value wins. */ for(;; (*a)++, (*b)++) { - if ((*a == aend || !isdigit((int)(unsigned char)**a)) && - (*b == bend || !isdigit((int)(unsigned char)**b))) + if ((*a == aend || !isdigit((unsigned char)**a)) && + (*b == bend || !isdigit((unsigned char)**b))) return 0; - else if (*a == aend || !isdigit((int)(unsigned char)**a)) + else if (*a == aend || !isdigit((unsigned char)**a)) return -1; - else if (*b == bend || !isdigit((int)(unsigned char)**b)) + else if (*b == bend || !isdigit((unsigned char)**b)) return +1; else if (**a < **b) return -1; @@ -103,27 +103,27 @@ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len ca = *ap; cb = *bp; /* skip over leading zeros */ - while (ca == '0' && (ap+1 < aend) && isdigit((int)(unsigned char)*(ap+1))) { + while (ca == '0' && (ap+1 < aend) && isdigit((unsigned char)ap[1])) { ca = *++ap; } - while (cb == '0' && (bp+1 < bend) && isdigit((int)(unsigned char)*(bp+1))) { + while (cb == '0' && (bp+1 < bend) && isdigit((unsigned char)bp[1])) { cb = *++bp; } while (1) { /* Skip consecutive whitespace */ - while (isspace((int)(unsigned char)ca)) { + while (isspace(ca)) { ca = *++ap; } - while (isspace((int)(unsigned char)cb)) { + while (isspace(cb)) { cb = *++bp; } /* process run of digits */ - if (isdigit((int)(unsigned char)ca) && isdigit((int)(unsigned char)cb)) { + if (isdigit(ca) && isdigit(cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) @@ -147,8 +147,8 @@ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len } if (is_case_insensitive) { - ca = toupper((int)(unsigned char)ca); - cb = toupper((int)(unsigned char)cb); + ca = toupper(ca); + cb = toupper(cb); } if (ca < cb) diff --git a/ext/standard/syslog.c b/ext/standard/syslog.c index c5d73eb008ec..44b902bf50b8 100644 --- a/ext/standard/syslog.c +++ b/ext/standard/syslog.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt b/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt new file mode 100644 index 000000000000..cf9a40062f84 --- /dev/null +++ b/ext/standard/tests/GHSA-96wq-48vp-hh57.phpt @@ -0,0 +1,22 @@ +--TEST-- +GHSA-96wq-48vp-hh57: signed integer overflow of char array offset +--CREDITS-- +Aleksey Solovev (Positive Technologies) +--INI-- +memory_limit=3G +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/standard/tests/array/005.phpt b/ext/standard/tests/array/005.phpt index 40e9eac265fe..1980d4ba14bf 100644 --- a/ext/standard/tests/array/005.phpt +++ b/ext/standard/tests/array/005.phpt @@ -18,7 +18,7 @@ $mixed_array = array( array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL), array( 12, "name", 'age', '45' ), array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, @@ -202,7 +202,7 @@ array(12) { [4]=> int(6) [""]=> - int(3) + string(5) "blank" [2]=> string(5) "float" ["F"]=> diff --git a/ext/standard/tests/array/GHSA-h96m-rvf9-jgm2.phpt b/ext/standard/tests/array/GHSA-h96m-rvf9-jgm2.phpt new file mode 100644 index 000000000000..2e3e85357e13 --- /dev/null +++ b/ext/standard/tests/array/GHSA-h96m-rvf9-jgm2.phpt @@ -0,0 +1,16 @@ +--TEST-- +GHSA-h96m-rvf9-jgm2 +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECTF-- +The total number of elements must be lower than %d diff --git a/ext/standard/tests/array/array_change_key_case_flag_error.phpt b/ext/standard/tests/array/array_change_key_case_flag_error.phpt new file mode 100644 index 000000000000..e83a21815c99 --- /dev/null +++ b/ext/standard/tests/array/array_change_key_case_flag_error.phpt @@ -0,0 +1,14 @@ +--TEST-- +array_change_key_case(): invalid $case argument +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +ValueError: array_change_key_case(): Argument #2 ($case) must be either CASE_LOWER or CASE_UPPER diff --git a/ext/standard/tests/array/array_change_key_case_variation.phpt b/ext/standard/tests/array/array_change_key_case_variation.phpt deleted file mode 100644 index c221a3f34101..000000000000 --- a/ext/standard/tests/array/array_change_key_case_variation.phpt +++ /dev/null @@ -1,50 +0,0 @@ ---TEST-- -Test array_change_key_case() function - 2 ---FILE-- - 1, "two" => 2, "THREE" => 3, "FOUR" => "four"); - -/* use 'case' argument other than CASE_LOWER & CASE_UPPER */ -try { - var_dump(array_change_key_case($item, "CASE_UPPER")); -} catch (TypeError $e) { - echo $e->getMessage(), "\n"; -} -var_dump(array_change_key_case($item, 5)); - -/* when keys are different in terms of only case */ -/* should return one value key pair with key being in lowercase */ -var_dump( array_change_key_case( array("ONE" => 1, "one" => 3, "One" => 4) ) ); - -/* should return one value key pair with key being in uppercase */ -var_dump( array_change_key_case( array("ONE" => 1, "one" => 2, "One" => 3), CASE_UPPER ) ); -var_dump( array_change_key_case( array("ONE" => 1, "one" => 1, "One" => 2), 5 ) ); - -echo "end\n"; -?> ---EXPECT-- -array_change_key_case(): Argument #2 ($case) must be of type int, string given -array(4) { - ["ONE"]=> - int(1) - ["TWO"]=> - int(2) - ["THREE"]=> - int(3) - ["FOUR"]=> - string(4) "four" -} -array(1) { - ["one"]=> - int(4) -} -array(1) { - ["ONE"]=> - int(3) -} -array(1) { - ["ONE"]=> - int(2) -} -end diff --git a/ext/standard/tests/array/array_change_key_case_variation3.phpt b/ext/standard/tests/array/array_change_key_case_variation3.phpt index 0c3ed4eb0dea..886eed3862c7 100644 --- a/ext/standard/tests/array/array_change_key_case_variation3.phpt +++ b/ext/standard/tests/array/array_change_key_case_variation3.phpt @@ -9,76 +9,28 @@ Test array_change_key_case() function : usage variations - different data types echo "*** Testing array_change_key_case() : usage variations ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -// heredoc string -$heredoc = << array( +$inputs = [ + 'int' => [ 0 => 'zero', 1 => 'one', 12345 => 'positive', -2345 => 'negative', - ), - - // null data -/*3*/ 'null uppercase' => array( - NULL => 'null 1', - ), - 'null lowercase' => array( - null => 'null 2', - ), - - // boolean data -/*4*/ 'bool lowercase' => array( - true => 'lowert', - false => 'lowerf', - ), - 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), - - // empty data -/*5*/ 'empty double quotes' => array( - "" => 'emptyd', - ), - 'empty single quotes' => array( - '' => 'emptys', - ), - - // string data -/*6*/ 'string' => array( - "stringd" => 'stringd', + ], + 'bool' => [ + true => 'true', + false => 'false', + ], + 'string' => [ 'strings' => 'strings', - $heredoc => 'stringh', - ), - - // undefined data -/*8*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*9*/ 'unset' => array( - @$unset_var => 'unset', - ), -); + '' => 'emptys', + ], +]; // loop through each sub-array of $inputs to check the behavior of array_change_key_case() -$iterator = 1; foreach($inputs as $key => $input) { - echo "\n-- Iteration $iterator : $key data --\n"; + echo "\n-- $key data --\n"; var_dump( array_change_key_case($input, CASE_UPPER) ); - $iterator++; }; echo "Done"; @@ -86,7 +38,7 @@ echo "Done"; --EXPECT-- *** Testing array_change_key_case() : usage variations *** --- Iteration 1 : int data -- +-- int data -- array(4) { [0]=> string(4) "zero" @@ -98,65 +50,19 @@ array(4) { string(8) "negative" } --- Iteration 2 : null uppercase data -- -array(1) { - [""]=> - string(6) "null 1" -} - --- Iteration 3 : null lowercase data -- -array(1) { - [""]=> - string(6) "null 2" -} - --- Iteration 4 : bool lowercase data -- +-- bool data -- array(2) { [1]=> - string(6) "lowert" + string(4) "true" [0]=> - string(6) "lowerf" + string(5) "false" } --- Iteration 5 : bool uppercase data -- +-- string data -- array(2) { - [1]=> - string(6) "uppert" - [0]=> - string(6) "upperf" -} - --- Iteration 6 : empty double quotes data -- -array(1) { - [""]=> - string(6) "emptyd" -} - --- Iteration 7 : empty single quotes data -- -array(1) { - [""]=> - string(6) "emptys" -} - --- Iteration 8 : string data -- -array(3) { - ["STRINGD"]=> - string(7) "stringd" ["STRINGS"]=> string(7) "strings" - ["HELLO WORLD"]=> - string(7) "stringh" -} - --- Iteration 9 : undefined data -- -array(1) { [""]=> - string(9) "undefined" -} - --- Iteration 10 : unset data -- -array(1) { - [""]=> - string(5) "unset" + string(6) "emptys" } Done diff --git a/ext/standard/tests/array/array_change_key_case_variation4.phpt b/ext/standard/tests/array/array_change_key_case_variation4.phpt deleted file mode 100644 index 82d211451638..000000000000 --- a/ext/standard/tests/array/array_change_key_case_variation4.phpt +++ /dev/null @@ -1,132 +0,0 @@ ---TEST-- -Test array_change_key_case() function : usage variations - different int values for $case ---FILE-- - 'un', 'TWO' => 'deux', 'three' => 'trois'); -for ($i = -5; $i <=5; $i += 1){ - echo "\n-- \$sort argument is $i --\n"; - $temp = $input; - var_dump(array_change_key_case($temp, $i)); -} - -echo "Done"; -?> ---EXPECT-- -*** Testing array_change_key_case() : usage variations *** - --- $sort argument is -5 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -4 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -3 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -2 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is -1 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 0 -- -array(3) { - ["one"]=> - string(2) "un" - ["two"]=> - string(4) "deux" - ["three"]=> - string(5) "trois" -} - --- $sort argument is 1 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 2 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 3 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 4 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} - --- $sort argument is 5 -- -array(3) { - ["ONE"]=> - string(2) "un" - ["TWO"]=> - string(4) "deux" - ["THREE"]=> - string(5) "trois" -} -Done diff --git a/ext/standard/tests/array/array_change_key_case_variation8.phpt b/ext/standard/tests/array/array_change_key_case_variation8.phpt index bb4dbc4af60f..892cda2818ff 100644 --- a/ext/standard/tests/array/array_change_key_case_variation8.phpt +++ b/ext/standard/tests/array/array_change_key_case_variation8.phpt @@ -10,7 +10,7 @@ echo "*** Testing array_change_key_case() : usage variations ***\n"; $inputs = array ( // group of escape sequences - array(null => 1, NULL => 2, "\a" => 3, "\cx" => 4, "\e" => 5, "\f" => 6, "\n" => 7, "\t" => 8, "\xhh" => 9, "\ddd" => 10, "\v" => 11), + array("\a" => 3, "\cx" => 4, "\e" => 5, "\f" => 6, "\n" => 7, "\t" => 8, "\xhh" => 9, "\ddd" => 10, "\v" => 11), // array contains combination of capital/small letters array("lemoN" => 1, "Orange" => 2, "banana" => 3, "apple" => 4, "Test" => 5, "TTTT" => 6, "ttt" => 7, "ww" => 8, "x" => 9, "X" => 10, "oraNGe" => 11, "BANANA" => 12) @@ -29,9 +29,7 @@ echo "Done"; *** Testing array_change_key_case() : usage variations *** -- $case = default -- -array(10) { - [""]=> - int(2) +array(9) { ["\a"]=> int(3) ["\cx"]=> @@ -53,9 +51,7 @@ array(10) { int(11) } -- $case = upper -- -array(10) { - [""]=> - int(2) +array(9) { ["\A"]=> int(3) ["\CX"]=> diff --git a/ext/standard/tests/array/array_combine_variation3.phpt b/ext/standard/tests/array/array_combine_variation3.phpt index 94901eedf649..241ead058c80 100644 --- a/ext/standard/tests/array/array_combine_variation3.phpt +++ b/ext/standard/tests/array/array_combine_variation3.phpt @@ -23,13 +23,6 @@ the lazy dog This is a double quoted string EOT; -// heredoc with different whitespaces -$diff_whitespaces = <<22 @@ -45,9 +38,9 @@ $arrays = array ( array(false,true), // with default keys and boolean values array(), // empty array /*5*/ array(NULL), // with NULL - array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings - array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings - array("h1" => $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // with heredocs + array("a\v\f","aaaa\n","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings + array('a\v\f','aaaa\n','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings + array("h1" => $blank_line, "h2" => $multiline_string, $numeric_string), // with heredocs // associative arrays /*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values @@ -57,11 +50,11 @@ $arrays = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -113,8 +106,10 @@ array(1) { array(6) { ["a "]=> string(3) "a " - ["aaaa "]=> - string(5) "aaaa " + ["aaaa +"]=> + string(5) "aaaa +" ["b"]=> string(1) "b" ["b bbb"]=> @@ -128,8 +123,8 @@ array(6) { array(6) { ["a\v\f"]=> string(5) "a\v\f" - ["aaaa\r"]=> - string(6) "aaaa\r" + ["aaaa\n"]=> + string(6) "aaaa\n" ["b"]=> string(1) "b" ["b\tbbb"]=> @@ -140,7 +135,7 @@ array(6) { string(28) "\[\]\!\@\#\$\%\^\&\*\(\)\{\}" } -- Iteration 8 -- -array(4) { +array(3) { [" "]=> string(1) " @@ -153,14 +148,6 @@ This is a double quoted string"]=> The quick brown fox jumped over; the lazy dog This is a double quoted string" - ["hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces"]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" ["11 < 12. 123 >22 'single quoted string' "double quoted string" @@ -220,13 +207,6 @@ array(3) { string(4) "four" } -- Iteration 14 -- -array(2) { - ["null"]=> - string(4) "null" - [""]=> - NULL -} --- Iteration 15 -- array(4) { ["true"]=> string(4) "true" @@ -237,30 +217,30 @@ array(4) { [1]=> bool(true) } --- Iteration 16 -- +-- Iteration 15 -- array(2) { ["emptys"]=> string(6) "emptys" [""]=> string(0) "" } --- Iteration 17 -- +-- Iteration 16 -- array(2) { [""]=> bool(false) [1]=> bool(true) } --- Iteration 18 -- +-- Iteration 17 -- array(3) { - [4]=> - int(4) + [2]=> + int(2) [5]=> int(5) [6]=> int(6) } --- Iteration 19 -- +-- Iteration 18 -- array(3) { [10]=> int(10) diff --git a/ext/standard/tests/array/array_combine_variation4.phpt b/ext/standard/tests/array/array_combine_variation4.phpt index 1ff6b64f175e..993119edcedf 100644 --- a/ext/standard/tests/array/array_combine_variation4.phpt +++ b/ext/standard/tests/array/array_combine_variation4.phpt @@ -9,9 +9,6 @@ Test array_combine() function : usage variations - associative array with differ */ echo "*** Testing array_combine() : assoc array with diff keys to both \$keys and \$values argument ***\n"; -// get an unset variable -$unset_var = 10; -unset ($unset_var); // get a resource variable $fp = fopen(__FILE__, "r"); @@ -24,11 +21,6 @@ class classA } } -// get a heredoc string -$heredoc = << 2.2, 'pen\n' => 33), array("\tHello" => 111, "re\td" => "color", "\v\fworld" => 2.2, "pen\n" => 33), - array("hello", $heredoc => "string"), // heredoc // array with object, unset variable and resource variable -/*10*/ array(@$unset_var => "hello", $fp => 'resource'), +/*10*/ array($fp => 'resource'), // array with mixed keys /*11*/ array('hello' => 1, "fruit" => 2.2, $fp => 'resource', 133 => "int", - @$unset_var => "unset", $heredoc => "heredoc") + ) ); // array to be passsed to $arr2 argument @@ -128,21 +119,12 @@ array(4) { int(33) } -- Iteration 7 -- -array(2) { - ["hello"]=> - string(5) "hello" - ["string"]=> - string(6) "string" -} --- Iteration 8 -- -array(2) { - ["hello"]=> - string(5) "hello" +array(1) { ["resource"]=> string(8) "resource" } --- Iteration 9 -- -array(6) { +-- Iteration 8 -- +array(4) { [1]=> int(1) ["2.2"]=> @@ -151,9 +133,5 @@ array(6) { string(8) "resource" ["int"]=> string(3) "int" - ["unset"]=> - string(5) "unset" - ["heredoc"]=> - string(7) "heredoc" } Done diff --git a/ext/standard/tests/array/array_diff_assoc_variation1.phpt b/ext/standard/tests/array/array_diff_assoc_variation1.phpt deleted file mode 100644 index b16baa300f57..000000000000 --- a/ext/standard/tests/array/array_diff_assoc_variation1.phpt +++ /dev/null @@ -1,179 +0,0 @@ ---TEST-- -Test array_diff_assoc() function : usage variations - unexpected values for 'array1' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff_assoc() : usage variations *** - --- Iteration 1 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 2 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 3 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 4 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, int given - --- Iteration 5 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 6 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 7 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 8 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 9 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, float given - --- Iteration 10 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 11 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 12 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, true given - --- Iteration 13 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, false given - --- Iteration 14 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, true given - --- Iteration 15 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, false given - --- Iteration 16 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 17 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 18 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 19 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 20 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 21 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 22 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, string given - --- Iteration 23 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, classA given - --- Iteration 24 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 25 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, null given - --- Iteration 26 -- -array_diff_assoc(): Argument #1 ($array) must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_assoc_variation2.phpt b/ext/standard/tests/array/array_diff_assoc_variation2.phpt deleted file mode 100644 index a0b1bac329d9..000000000000 --- a/ext/standard/tests/array/array_diff_assoc_variation2.phpt +++ /dev/null @@ -1,179 +0,0 @@ ---TEST-- -Test array_diff_assoc() function : usage variations - unexpected values for 'array1' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff_assoc() : usage variations *** - --- Iteration 1 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 2 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 3 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 4 -- -array_diff_assoc(): Argument #2 must be of type array, int given - --- Iteration 5 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 6 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 7 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 8 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 9 -- -array_diff_assoc(): Argument #2 must be of type array, float given - --- Iteration 10 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 11 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 12 -- -array_diff_assoc(): Argument #2 must be of type array, true given - --- Iteration 13 -- -array_diff_assoc(): Argument #2 must be of type array, false given - --- Iteration 14 -- -array_diff_assoc(): Argument #2 must be of type array, true given - --- Iteration 15 -- -array_diff_assoc(): Argument #2 must be of type array, false given - --- Iteration 16 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 17 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 18 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 19 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 20 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 21 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 22 -- -array_diff_assoc(): Argument #2 must be of type array, string given - --- Iteration 23 -- -array_diff_assoc(): Argument #2 must be of type array, classA given - --- Iteration 24 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 25 -- -array_diff_assoc(): Argument #2 must be of type array, null given - --- Iteration 26 -- -array_diff_assoc(): Argument #2 must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_assoc_variation3.phpt b/ext/standard/tests/array/array_diff_assoc_variation3.phpt index b32e484fd190..4833725ffe4e 100644 --- a/ext/standard/tests/array/array_diff_assoc_variation3.phpt +++ b/ext/standard/tests/array/array_diff_assoc_variation3.phpt @@ -10,10 +10,6 @@ echo "\n*** Testing array_diff_assoc() : usage variations ***\n"; $array = array(1, 2, 3); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a class class classA { @@ -22,11 +18,6 @@ class classA } } -// heredoc string -$heredoc = << array( - NULL, null), // boolean data /*4*/ 'bool' => array( true, - false, - TRUE, - FALSE), + false), // empty data /*5*/ 'empty' => array( - "", ''), // string data /*6*/ 'string' => array( - "string", - 'string', - $heredoc), - - // binary data -/*7*/ -'binary' => array( - b"binary", - (binary)"binary"), + 'string'), // object data /*8*/ 'object' => array( new classA()), - - // undefined data -/*9*/ -'undefined' => array( - @$undefined_var), - - // unset data -/*10*/ -'unset' => array( - @$unset_var), ); // loop through each element of $inputs to check the behavior of array_diff_assoc @@ -135,65 +104,33 @@ array(5) { } -- Iteration 3 -- -array(2) { +array(1) { [0]=> NULL - [1]=> - NULL } -- Iteration 4 -- -array(3) { +array(1) { [1]=> bool(false) - [2]=> - bool(true) - [3]=> - bool(false) } -- Iteration 5 -- -array(2) { +array(1) { [0]=> string(0) "" - [1]=> - string(0) "" } -- Iteration 6 -- -array(3) { +array(1) { [0]=> string(6) "string" - [1]=> - string(6) "string" - [2]=> - string(11) "hello world" } -- Iteration 7 -- -array(2) { - [0]=> - string(6) "binary" - [1]=> - string(6) "binary" -} - --- Iteration 8 -- array(1) { [0]=> object(classA)#%d (0) { } } - --- Iteration 9 -- -array(1) { - [0]=> - NULL -} - --- Iteration 10 -- -array(1) { - [0]=> - NULL -} Done diff --git a/ext/standard/tests/array/array_diff_assoc_variation4.phpt b/ext/standard/tests/array/array_diff_assoc_variation4.phpt index 65b76dd9ebf9..794a367368ee 100644 --- a/ext/standard/tests/array/array_diff_assoc_variation4.phpt +++ b/ext/standard/tests/array/array_diff_assoc_variation4.phpt @@ -11,15 +11,6 @@ echo "\n*** Testing array_diff_assoc() : usage variations ***\n"; $array = array(1, 2, 3); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -// heredoc string -$heredoc = << 'positive', -2345 => 'negative'), - // null data -/*3*/ -'null' => array( - NULL => 'null 1', - null => 'null 2'), - - // boolean data -/*4*/ -'bool' => array( - true => 'boolt', - false => 'boolf', - TRUE => 'boolT', - FALSE => 'boolF'), - // empty data /*5*/ 'empty' => array( - "" => 'emptyd', - '' => 'emptys'), + '' => 'empty'), // string data /*6*/ 'string' => array( - "string" => 'stringd', - 'string' => 'strings', - $heredoc => 'stringh'), - - // binary data -/*7*/ -'binary' => array( - b"binary1" => 'binary 1', - (binary)"binary2" => 'binary 2'), - - // undefined data -/*8*/ -'undefined' => array( - @$undefined_var => 'undefined'), - - // unset data -/*9*/ -'unset' => array( - @$unset_var => 'unset'), + 'string' => 'strings'), ); @@ -104,48 +62,12 @@ array(4) { -- Iteration 2 -- array(1) { [""]=> - string(6) "null 2" + string(5) "empty" } -- Iteration 3 -- -array(2) { - [1]=> - string(5) "boolT" - [0]=> - string(5) "boolF" -} - --- Iteration 4 -- array(1) { - [""]=> - string(6) "emptys" -} - --- Iteration 5 -- -array(2) { ["string"]=> string(7) "strings" - ["hello world"]=> - string(7) "stringh" -} - --- Iteration 6 -- -array(2) { - ["binary1"]=> - string(8) "binary 1" - ["binary2"]=> - string(8) "binary 2" -} - --- Iteration 7 -- -array(1) { - [""]=> - string(9) "undefined" -} - --- Iteration 8 -- -array(1) { - [""]=> - string(5) "unset" } Done diff --git a/ext/standard/tests/array/array_diff_key_variation7.phpt b/ext/standard/tests/array/array_diff_key_variation7.phpt deleted file mode 100644 index 9ca74cccb959..000000000000 --- a/ext/standard/tests/array/array_diff_key_variation7.phpt +++ /dev/null @@ -1,52 +0,0 @@ ---TEST-- -Test array_diff_key() function : usage variation - Passing null,unset and undefined variable indexed array ---FILE-- - '10', "" => 'empty'); - -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -$input_arrays = array( - 'null indexed' => array(NULL => 'null 1', null => 'null 2'), - 'undefined indexed' => array(@$undefined_var => 'undefined'), - 'unset indexed' => array(@$unset_var => 'unset'), -); - -foreach($input_arrays as $key =>$value) { - echo "\n--$key--\n"; - // loop through each element of the array for arr1 - var_dump( array_diff_key($input_array, $value) ); - var_dump( array_diff_key($value, $input_array) ); -} -?> ---EXPECT-- -*** Testing array_diff_key() : usage variation *** - ---null indexed-- -array(1) { - [10]=> - string(2) "10" -} -array(0) { -} - ---undefined indexed-- -array(1) { - [10]=> - string(2) "10" -} -array(0) { -} - ---unset indexed-- -array(1) { - [10]=> - string(2) "10" -} -array(0) { -} diff --git a/ext/standard/tests/array/array_diff_leak_custom_type_checks.phpt b/ext/standard/tests/array/array_diff_leak_custom_type_checks.phpt new file mode 100644 index 000000000000..77aef0ccc08b --- /dev/null +++ b/ext/standard/tests/array/array_diff_leak_custom_type_checks.phpt @@ -0,0 +1,14 @@ +--TEST-- +array_diff() memory leak with custom type checks +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +array_diff(): Argument #2 must be of type array, string given diff --git a/ext/standard/tests/array/array_diff_max_elements.phpt b/ext/standard/tests/array/array_diff_max_elements.phpt new file mode 100644 index 000000000000..4c65cd049b33 --- /dev/null +++ b/ext/standard/tests/array/array_diff_max_elements.phpt @@ -0,0 +1,16 @@ +--TEST-- +array_diff(): Max elements +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECTF-- +The total number of elements must be lower than %d diff --git a/ext/standard/tests/array/array_diff_uassoc_variation12.phpt b/ext/standard/tests/array/array_diff_uassoc_variation12.phpt deleted file mode 100644 index d5681c94cbde..000000000000 --- a/ext/standard/tests/array/array_diff_uassoc_variation12.phpt +++ /dev/null @@ -1,52 +0,0 @@ ---TEST-- -Test array_diff_uassoc() function : usage variation - Passing null,unset and undefined variable indexed array ---FILE-- - '10', "" => ''); - -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -$input_arrays = array( - 'null indexed' => array(NULL => NULL, null => null), - 'undefined indexed' => array(@$undefined_var => @$undefined_var), - 'unset indexed' => array(@$unset_var => @$unset_var), -); - -foreach($input_arrays as $key =>$value) { - echo "\n--$key--\n"; - var_dump( array_diff_uassoc($input_array, $value, "strcasecmp") ); - var_dump( array_diff_uassoc($value, $input_array, "strcasecmp") ); -} - -?> ---EXPECT-- -*** Testing array_diff_uassoc() : usage variation *** - ---null indexed-- -array(1) { - [10]=> - string(2) "10" -} -array(0) { -} - ---undefined indexed-- -array(1) { - [10]=> - string(2) "10" -} -array(0) { -} - ---unset indexed-- -array(1) { - [10]=> - string(2) "10" -} -array(0) { -} diff --git a/ext/standard/tests/array/array_diff_ukey_variation9.phpt b/ext/standard/tests/array/array_diff_ukey_variation9.phpt deleted file mode 100644 index 22cd3d45fdf8..000000000000 --- a/ext/standard/tests/array/array_diff_ukey_variation9.phpt +++ /dev/null @@ -1,52 +0,0 @@ ---TEST-- -Test array_diff_ukey() function : usage variation - Passing null,unset and undefined variable indexed array ---FILE-- - '10', "" => 'empty'); - -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -$input_arrays = array( - 'null indexed' => array(NULL => 'null 1', null => 'null 2'), - 'undefined indexed' => array(@$undefined_var => 'undefined'), - 'unset indexed' => array(@$unset_var => 'unset'), -); - -foreach($input_arrays as $key =>$value) { - echo "\n--$key--\n"; - var_dump( array_diff_ukey($value, $input_array, 'strcasecmp') ); - var_dump( array_diff_ukey($input_array, $value, 'strcasecmp') ); -} - -?> ---EXPECT-- -*** Testing array_diff_ukey() : usage variation *** - ---null indexed-- -array(0) { -} -array(1) { - [10]=> - string(2) "10" -} - ---undefined indexed-- -array(0) { -} -array(1) { - [10]=> - string(2) "10" -} - ---unset indexed-- -array(0) { -} -array(1) { - [10]=> - string(2) "10" -} diff --git a/ext/standard/tests/array/array_diff_variation1.phpt b/ext/standard/tests/array/array_diff_variation1.phpt deleted file mode 100644 index 1031b6f947e0..000000000000 --- a/ext/standard/tests/array/array_diff_variation1.phpt +++ /dev/null @@ -1,154 +0,0 @@ ---TEST-- -Test array_diff() function : usage variations - unexpected values for 'array1' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; - -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff() : usage variations *** - --- Iteration 1 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 2 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 3 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 4 --array_diff(): Argument #1 ($array) must be of type array, int given - --- Iteration 5 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 6 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 7 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 8 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 9 --array_diff(): Argument #1 ($array) must be of type array, float given - --- Iteration 10 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 11 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 12 --array_diff(): Argument #1 ($array) must be of type array, true given - --- Iteration 13 --array_diff(): Argument #1 ($array) must be of type array, false given - --- Iteration 14 --array_diff(): Argument #1 ($array) must be of type array, true given - --- Iteration 15 --array_diff(): Argument #1 ($array) must be of type array, false given - --- Iteration 16 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 17 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 18 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 19 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 20 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 21 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 22 --array_diff(): Argument #1 ($array) must be of type array, string given - --- Iteration 23 --array_diff(): Argument #1 ($array) must be of type array, classA given - --- Iteration 24 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 25 --array_diff(): Argument #1 ($array) must be of type array, null given - --- Iteration 26 --array_diff(): Argument #1 ($array) must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_variation2.phpt b/ext/standard/tests/array/array_diff_variation2.phpt deleted file mode 100644 index 2b03f2251369..000000000000 --- a/ext/standard/tests/array/array_diff_variation2.phpt +++ /dev/null @@ -1,153 +0,0 @@ ---TEST-- -Test array_diff() function : usage variations - unexpected values for 'array2' argument ---FILE-- -getMessage(), "\n"; - } - $iterator++; -}; -fclose($fp); -echo "Done"; -?> ---EXPECT-- -*** Testing array_diff() : usage variations *** - --- Iteration 1 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 2 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 3 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 4 --array_diff(): Argument #2 must be of type array, int given - --- Iteration 5 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 6 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 7 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 8 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 9 --array_diff(): Argument #2 must be of type array, float given - --- Iteration 10 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 11 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 12 --array_diff(): Argument #2 must be of type array, true given - --- Iteration 13 --array_diff(): Argument #2 must be of type array, false given - --- Iteration 14 --array_diff(): Argument #2 must be of type array, true given - --- Iteration 15 --array_diff(): Argument #2 must be of type array, false given - --- Iteration 16 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 17 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 18 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 19 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 20 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 21 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 22 --array_diff(): Argument #2 must be of type array, string given - --- Iteration 23 --array_diff(): Argument #2 must be of type array, classA given - --- Iteration 24 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 25 --array_diff(): Argument #2 must be of type array, null given - --- Iteration 26 --array_diff(): Argument #2 must be of type array, resource given -Done diff --git a/ext/standard/tests/array/array_diff_variation3.phpt b/ext/standard/tests/array/array_diff_variation3.phpt index 37b295b0bd69..649dcb5c92ab 100644 --- a/ext/standard/tests/array/array_diff_variation3.phpt +++ b/ext/standard/tests/array/array_diff_variation3.phpt @@ -12,15 +12,6 @@ echo "*** Testing array_diff() : usage variations ***\n"; // Initialise function arguments not being substituted (if any) $array = array(1, 2); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -//get heredoc -$heredoc = << array( // null data - NULL, null), /*5*/ "boolean" => array( // boolean data true, - false, - TRUE, - FALSE), + false), /*6*/ -"empty" => array( - // empty data - "", - ''), +"empty" => array(''), /*7*/ -"string" => array( - // string data - "string", - 'string', - $heredoc), - -/*8*/ -"binary" => array( - // binary data - b"binary", - (binary)"binary"), - -/*9*/ -"undefined" => array( - // undefined data - @$undefined_var), - -/*10*/ -"unset" => array( - // unset data - @$unset_var) +"string" => array('string'), ); // loop through each element of the array for arr1 $iterator = 1; foreach($values as $value) { - echo "\n Iteration: $iterator \n"; + echo "Iteration: $iterator\n"; var_dump( array_diff($value, $array) ); $iterator++; }; @@ -99,12 +64,10 @@ echo "Done"; ?> --EXPECT-- *** Testing array_diff() : usage variations *** - - Iteration: 1 +Iteration: 1 array(0) { } - - Iteration: 2 +Iteration: 2 array(3) { [0]=> int(0) @@ -113,8 +76,7 @@ array(3) { [3]=> int(-2345) } - - Iteration: 3 +Iteration: 3 array(5) { [0]=> float(10.5) @@ -127,58 +89,24 @@ array(5) { [4]=> float(0.5) } - - Iteration: 4 -array(2) { +Iteration: 4 +array(1) { [0]=> NULL - [1]=> - NULL } - - Iteration: 5 -array(2) { +Iteration: 5 +array(1) { [1]=> bool(false) - [3]=> - bool(false) -} - - Iteration: 6 -array(2) { - [0]=> - string(0) "" - [1]=> - string(0) "" -} - - Iteration: 7 -array(3) { - [0]=> - string(6) "string" - [1]=> - string(6) "string" - [2]=> - string(17) "This is a heredoc" } - - Iteration: 8 -array(2) { - [0]=> - string(6) "binary" - [1]=> - string(6) "binary" -} - - Iteration: 9 +Iteration: 6 array(1) { [0]=> - NULL + string(0) "" } - - Iteration: 10 +Iteration: 7 array(1) { [0]=> - NULL + string(6) "string" } Done diff --git a/ext/standard/tests/array/array_diff_variation4.phpt b/ext/standard/tests/array/array_diff_variation4.phpt index 090f162bc7d9..301280bcea51 100644 --- a/ext/standard/tests/array/array_diff_variation4.phpt +++ b/ext/standard/tests/array/array_diff_variation4.phpt @@ -12,15 +12,6 @@ echo "*** Testing array_diff() : usage variations ***\n"; // Initialise function arguments not being substituted (if any) $array = array(1, 2); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -//get heredoc -$heredoc = << array( // null data - NULL, null), /*5*/ "boolean" => array( // boolean data true, - false, - TRUE, - FALSE), + false), /*6*/ "empty" => array( // empty data - "", ''), /*7*/ "string" => array( // string data - "string", - 'string', - $heredoc), - -/*8*/ -"binary" => array( - // binary data - b"binary", - (binary)"binary"), - -/*9*/ -"undefined" => array( - // undefined data - @$undefined_var), - -/*10*/ -"unset" => array( - // unset data - @$unset_var) + 'string'), ); // loop through each element of the array for $arr2 @@ -151,28 +120,4 @@ array(2) { [1]=> int(2) } - - Iteration: 8 -array(2) { - [0]=> - int(1) - [1]=> - int(2) -} - - Iteration: 9 -array(2) { - [0]=> - int(1) - [1]=> - int(2) -} - - Iteration: 10 -array(2) { - [0]=> - int(1) - [1]=> - int(2) -} Done diff --git a/ext/standard/tests/array/array_fill_variation5.phpt b/ext/standard/tests/array/array_fill_variation5.phpt index f984a0967597..4f8b48d30838 100644 --- a/ext/standard/tests/array/array_fill_variation5.phpt +++ b/ext/standard/tests/array/array_fill_variation5.phpt @@ -23,10 +23,9 @@ $values = array( /* 5 */ array('color' => 'red' , 'item' => 'pen'), array( 'color' => 'red' , 2 => 'green ' ), array("colour" => "red" , "item" => "pen"), - array( TRUE => "red" , FALSE => "green" ), - array( true => "red" , FALSE => "green" ), + array( true => "red" , false => "green" ), /* 10 */ array( 1 => "Hi" , "color" => "red" , 'item' => 'pen'), - array( NULL => "Hi", '1' => "Hello" , "1" => "Green"), + array( '' => "Hi", '1' => "Hello" , "1" => "Green"), array( ""=>1, "color" => "green"), /* 13 */ array('Saffron' , 'White' , 'Green') ); @@ -191,23 +190,6 @@ array(2) { } } -- Iteration 9 -- -array(2) { - [0]=> - array(2) { - [1]=> - string(3) "red" - [0]=> - string(5) "green" - } - [1]=> - array(2) { - [1]=> - string(3) "red" - [0]=> - string(5) "green" - } -} --- Iteration 10 -- array(2) { [0]=> array(3) { @@ -228,7 +210,7 @@ array(2) { string(3) "pen" } } --- Iteration 11 -- +-- Iteration 10 -- array(2) { [0]=> array(2) { @@ -245,7 +227,7 @@ array(2) { string(5) "Green" } } --- Iteration 12 -- +-- Iteration 11 -- array(2) { [0]=> array(2) { @@ -262,7 +244,7 @@ array(2) { string(5) "green" } } --- Iteration 13 -- +-- Iteration 12 -- array(2) { [0]=> array(3) { diff --git a/ext/standard/tests/array/array_filter_invalid_mode.phpt b/ext/standard/tests/array/array_filter_invalid_mode.phpt new file mode 100644 index 000000000000..b312bcfe5a23 --- /dev/null +++ b/ext/standard/tests/array/array_filter_invalid_mode.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test array_filter() function : usage variations - mode exception +--FILE-- +getMessage(), "\n"; +} + +echo "Done" +?> +--EXPECT-- +ValueError: array_filter(): Argument #3 ($mode) must be one of ARRAY_FILTER_USE_VALUE, ARRAY_FILTER_USE_KEY, or ARRAY_FILTER_USE_BOTH +Done diff --git a/ext/standard/tests/array/array_filter_variation3.phpt b/ext/standard/tests/array/array_filter_variation3.phpt index a81bb3595143..c5e6c121965b 100644 --- a/ext/standard/tests/array/array_filter_variation3.phpt +++ b/ext/standard/tests/array/array_filter_variation3.phpt @@ -24,11 +24,10 @@ $input_values = array( array(0, 1, 2, -1, 034, 0X4A), // integer values array(0.0, 1.2, 1.2e3, 1.2e-3), // float values array('value1', "value2", '', " ", ""), // string values - array(true, false, TRUE, FALSE), // bool values - array(null, NULL), // null values + array(true, false), // bool values array(1 => 'one', 'zero' => 0, -2 => "value"), //associative array - array("one" => 1, null => 'null', 5 => "float", true => 1, "" => 'empty'), // associative array with different keys - array(1 => 'one', 2, "key" => 'value') // combinition of associative and non-associative array + array("one" => 1, 5 => "float", true => 1, "" => 'empty'), // associative array with different keys + array(1 => 'one', 2, "key" => 'value') // combination of associative and non-associative array ); @@ -119,36 +118,19 @@ array(5) { array(0) { } -- Iteration 4 -- -array(2) { +array(1) { [0]=> bool(true) - [2]=> - bool(true) } -array(4) { +array(2) { [0]=> bool(true) [1]=> bool(false) - [2]=> - bool(true) - [3]=> - bool(false) } array(0) { } -- Iteration 5 -- -array(0) { -} -array(2) { - [0]=> - NULL - [1]=> - NULL -} -array(0) { -} --- Iteration 6 -- array(2) { [1]=> string(3) "one" @@ -165,30 +147,30 @@ array(3) { } array(0) { } --- Iteration 7 -- +-- Iteration 6 -- array(4) { ["one"]=> int(1) - [""]=> - string(5) "empty" [5]=> string(5) "float" [1]=> int(1) + [""]=> + string(5) "empty" } array(4) { ["one"]=> int(1) - [""]=> - string(5) "empty" [5]=> string(5) "float" [1]=> int(1) + [""]=> + string(5) "empty" } array(0) { } --- Iteration 8 -- +-- Iteration 7 -- array(3) { [1]=> string(3) "one" diff --git a/ext/standard/tests/array/array_filter_variation9.phpt b/ext/standard/tests/array/array_filter_variation9.phpt index ff0dc7711718..2e6efc0eda5d 100644 --- a/ext/standard/tests/array/array_filter_variation9.phpt +++ b/ext/standard/tests/array/array_filter_variation9.phpt @@ -8,7 +8,7 @@ Test array_filter() function : usage variations - built-in functions as 'callbac echo "*** Testing array_filter() : usage variations - built-in functions as 'callback' argument ***\n"; -$input = array(0, 1, -1, 10, 100, 1000); +$input = array(0, 1, 10, 100); // using built-in function 'is_int' as 'callback' var_dump( array_filter($input, 'is_int') ); @@ -34,33 +34,25 @@ echo "Done" ?> --EXPECT-- *** Testing array_filter() : usage variations - built-in functions as 'callback' argument *** -array(6) { +array(4) { [0]=> int(0) [1]=> int(1) [2]=> - int(-1) - [3]=> int(10) - [4]=> + [3]=> int(100) - [5]=> - int(1000) } -array(6) { +array(4) { [0]=> int(0) [1]=> int(1) [2]=> - int(-1) - [3]=> int(10) - [4]=> + [3]=> int(100) - [5]=> - int(1000) } array_filter(): Argument #2 ($callback) must be a valid callback or null, function "echo" not found or invalid function name array_filter(): Argument #2 ($callback) must be a valid callback or null, function "isset" not found or invalid function name diff --git a/ext/standard/tests/array/array_flip_variation2.phpt b/ext/standard/tests/array/array_flip_variation2.phpt index 9cf90905c15f..bd433db9dd5a 100644 --- a/ext/standard/tests/array/array_flip_variation2.phpt +++ b/ext/standard/tests/array/array_flip_variation2.phpt @@ -8,25 +8,12 @@ Test array_flip() function : usage variations - 'input' array with different key echo "*** Testing array_flip() : different keys for 'input' array argument ***\n"; -// different heredoc strings -$empty_heredoc = << 'int_key', // expected: value will be replaced by 'bool_key3' + 1 => 'int_key', // expected: value will be replaced by 'bool_key1' -2 => 'negative_key', 012 => 'octal_key', 0x34 => 'hex_key', @@ -41,21 +28,10 @@ $input = array( // bool keys true => 'bool_key1', false => 'bool_key2', - TRUE => 'bool_key3', - FALSE => 'bool_key4', - - // null keys - null => 'null_key1', // expected: value will be replaced by 'null_key2' - NULL => 'null_key2', // binary key "a".chr(0)."b" => 'binary_key1', b"binary" => 'binary_key2', - - //heredoc keys - $empty_heredoc => 'empty_heredoc', - $simple_heredoc => 'simple_heredoc', - $multiline_heredoc => 'multiline_heredoc', ); var_dump( array_flip($input) ); @@ -64,10 +40,10 @@ echo "Done" ?> --EXPECTF-- *** Testing array_flip() : different keys for 'input' array argument *** -array(13) { - ["bool_key4"]=> +array(11) { + ["bool_key2"]=> int(0) - ["bool_key3"]=> + ["bool_key1"]=> int(1) ["negative_key"]=> int(-2) @@ -79,7 +55,7 @@ array(13) { string(3) "key" ["string_key2"]=> string(3) "two" - ["empty_heredoc"]=> + ["string_key4"]=> string(0) "" ["string_key5"]=> string(1) " " @@ -87,11 +63,5 @@ array(13) { string(3) "a%0b" ["binary_key2"]=> string(6) "binary" - ["simple_heredoc"]=> - string(6) "simple" - ["multiline_heredoc"]=> - string(6%d) "multiline heredoc with 123 and -speci@! ch@r$...checking -and also" } Done diff --git a/ext/standard/tests/array/array_flip_variation5.phpt b/ext/standard/tests/array/array_flip_variation5.phpt index e7c47dffa521..49876f35a82f 100644 --- a/ext/standard/tests/array/array_flip_variation5.phpt +++ b/ext/standard/tests/array/array_flip_variation5.phpt @@ -3,39 +3,35 @@ Test array_flip() function : usage variations - 'input' argument with repeatitiv --FILE-- 'value', 2 => 'VALUE', 1 => "VaLuE", 3 => 4, 3 => 5); var_dump( array_flip($input) ); -// array with string key repeatition +// array with string key repetition $input = array("key" => 1, "two" => 'TWO', 'three' => 3, 'key' => "FOUR"); var_dump( array_flip($input) ); -// array with bool key repeatition +// array with bool key repetition $input = array(true => 1, false => 0, TRUE => -1); var_dump( array_flip($input) ); -// array with null key repeatition -$input = array(null => "Hello", NULL => 0); -var_dump( array_flip($input) ); - -// array with numeric value repeatition +// array with numeric value repetition $input = array('one' => 1, 'two' => 2, 3 => 1, "index" => 1); var_dump( array_flip($input) ); -//array with string value repeatition +//array with string value repetition $input = array('key1' => "value1", "key2" => '2', 'key3' => 'value1'); var_dump( array_flip($input) ); echo "Done" ?> --EXPECT-- -*** Testing array_flip() : 'input' array with repeatitive keys/values *** +*** Testing array_flip() : 'input' array with repetitive keys/values *** array(3) { ["VaLuE"]=> int(1) @@ -58,10 +54,6 @@ array(2) { [0]=> int(0) } -array(1) { - [0]=> - string(0) "" -} array(2) { [1]=> string(5) "index" diff --git a/ext/standard/tests/array/array_intersect_assoc_variation3.phpt b/ext/standard/tests/array/array_intersect_assoc_variation3.phpt index bb439a053bd2..532a79e688fa 100644 --- a/ext/standard/tests/array/array_intersect_assoc_variation3.phpt +++ b/ext/standard/tests/array/array_intersect_assoc_variation3.phpt @@ -25,13 +25,6 @@ the lazy dog This is a double quoted string EOT; -// heredoc with different whitespaces -$diff_whitespaces = <<22 @@ -49,7 +42,7 @@ $arrays = array ( /*5*/ array(NULL), // with NULL array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings - array("h1" => $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // with heredocs + array("h1" => $blank_line, "h2" => $multiline_string, $numeric_string), // with heredocs // associative arrays /*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values @@ -59,11 +52,10 @@ $arrays = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), - array(true => "true", false => "false", "false" => false, "true" => true), +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -74,9 +66,9 @@ $arrays = array ( $arr2 = array ( 1, 1.1, 2.2, "hello", "one", NULL, 2, 'world', true,5 => false, 1 => 'aaaa\r', "aaaa\r", - 'h3' => $diff_whitespaces, $numeric_string, + $numeric_string, "one" => "ten", 4 => "four", "two" => 2, - '', null => "null", '' => 'emptys', "emptyd" => "", + '', '' => 'emptys', "emptyd" => "", ); // loop through each sub-array within $arrays to check the behavior of array_intersect_assoc() @@ -141,19 +133,9 @@ array(1) { string(6) "aaaa\r" } -- Iteration 8 -- -array(1) { - ["h3"]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" +array(0) { } -array(1) { - ["h3"]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" +array(0) { } -- Iteration 9 -- array(0) { @@ -198,11 +180,6 @@ array(0) { array(0) { } -- Iteration 15 -- -array(0) { -} -array(0) { -} --- Iteration 16 -- array(2) { [""]=> string(6) "emptys" @@ -215,7 +192,7 @@ array(2) { ["emptyd"]=> string(0) "" } --- Iteration 17 -- +-- Iteration 16 -- array(1) { [5]=> bool(false) @@ -224,12 +201,12 @@ array(1) { [5]=> bool(false) } --- Iteration 18 -- +-- Iteration 17 -- array(0) { } array(0) { } --- Iteration 19 -- +-- Iteration 18 -- array(0) { } array(0) { diff --git a/ext/standard/tests/array/array_intersect_assoc_variation4.phpt b/ext/standard/tests/array/array_intersect_assoc_variation4.phpt index 859b7280d8ee..91b64869c373 100644 --- a/ext/standard/tests/array/array_intersect_assoc_variation4.phpt +++ b/ext/standard/tests/array/array_intersect_assoc_variation4.phpt @@ -25,13 +25,6 @@ the lazy dog This is a double quoted string EOT; -// heredoc with different whitespaces -$diff_whitespaces = <<22 @@ -40,13 +33,13 @@ $numeric_string = << true, "hello", "one", NULL, 2, 'world', true, false, 3 => "b\tbbb", "aaaa\r", - $numeric_string, "h3" => $diff_whitespaces, "true" => true, + $numeric_string, "true" => true, "one" => "ten", 4 => "four", "two" => 2, 6 => "six", - '', null => "null", '' => 'emptys' + '', '' => 'emptys' ); // arrays to be passed to $arr2 argument @@ -58,7 +51,7 @@ $arrays = array ( /*5*/ array(NULL), // array with NULL array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings - array($blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // array with heredocs + array($blank_line, "h2" => $multiline_string, $numeric_string), // array with heredocs // associative arrays /*9*/ array(1 => "one", 2 => "two", 6 => "six"), // explicit numeric keys, string values @@ -68,11 +61,10 @@ $arrays = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), - array(true => "true", false => "false", "false" => false, "true" => true), +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -148,19 +140,9 @@ array(0) { array(0) { } -- Iteration 8 -- -array(1) { - ["h3"]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" +array(0) { } -array(1) { - ["h3"]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" +array(0) { } -- Iteration 9 -- array(1) { @@ -204,11 +186,6 @@ array(1) { string(4) "four" } -- Iteration 14 -- -array(0) { -} -array(0) { -} --- Iteration 15 -- array(1) { ["true"]=> bool(true) @@ -217,7 +194,7 @@ array(1) { ["true"]=> bool(true) } --- Iteration 16 -- +-- Iteration 15 -- array(1) { [""]=> string(6) "emptys" @@ -226,7 +203,7 @@ array(1) { [""]=> string(6) "emptys" } --- Iteration 17 -- +-- Iteration 16 -- array(1) { [5]=> NULL @@ -235,12 +212,12 @@ array(1) { [5]=> NULL } --- Iteration 18 -- +-- Iteration 17 -- array(0) { } array(0) { } --- Iteration 19 -- +-- Iteration 18 -- array(0) { } array(0) { diff --git a/ext/standard/tests/array/array_intersect_assoc_variation5.phpt b/ext/standard/tests/array/array_intersect_assoc_variation5.phpt index 65ce1dae17d1..64cfdbb52940 100644 --- a/ext/standard/tests/array/array_intersect_assoc_variation5.phpt +++ b/ext/standard/tests/array/array_intersect_assoc_variation5.phpt @@ -10,10 +10,6 @@ Test array_intersect_assoc() function : usage variations - assoc array with diff echo "*** Testing array_intersect_assoc() : assoc array with diff keys to \$arr1 argument ***\n"; -// get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a heredoc string $heredoc = << 2.2, "pen\n" => 33), array("hello", $heredoc => "string"), // heredoc - // array with object, unset variable and resource variable -/*10*/ array(@$unset_var => "hello"), - // array with mixed keys /*11*/ array('hello' => 1, "fruit" => 2.2, 133 => "int", - @$unset_var => "unset", $heredoc => "heredoc") + $heredoc => "heredoc") ); // array to be passed to $arr2 argument @@ -123,11 +116,6 @@ array(1) { string(6) "string" } -- Iteration 8 -- -array(0) { -} -array(0) { -} --- Iteration 9 -- array(1) { [133]=> string(3) "int" diff --git a/ext/standard/tests/array/array_intersect_assoc_variation6.phpt b/ext/standard/tests/array/array_intersect_assoc_variation6.phpt index f446c6870419..92664a83b79d 100644 --- a/ext/standard/tests/array/array_intersect_assoc_variation6.phpt +++ b/ext/standard/tests/array/array_intersect_assoc_variation6.phpt @@ -10,10 +10,6 @@ Test array_intersect_assoc() function : usage variations - assoc array with diff echo "*** Testing array_intersect_assoc() : assoc array with diff keys to \$arr2 argument ***\n"; -// get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a heredoc string $heredoc = << "string"), // heredoc // array with unset variable -/*10*/ array( @$unset_var => "hello"), // array with mixed keys /*11*/ array('hello' => 1, "fruit" => 2.2, 133 => "int", - @$unset_var => "unset", $heredoc => "heredoc") + $heredoc => "heredoc") ); // array to be passed to $arr1 argument @@ -123,11 +118,6 @@ array(1) { string(6) "string" } -- Iteration 8 -- -array(0) { -} -array(0) { -} --- Iteration 9 -- array(1) { [133]=> string(3) "int" diff --git a/ext/standard/tests/array/array_intersect_key_variation7.phpt b/ext/standard/tests/array/array_intersect_key_variation7.phpt deleted file mode 100644 index 2b6ead7919ad..000000000000 --- a/ext/standard/tests/array/array_intersect_key_variation7.phpt +++ /dev/null @@ -1,56 +0,0 @@ ---TEST-- -Test array_intersect_key() function : usage variation - Passing null,unset and undefeined variable indexed array ---FILE-- - '0', 1 => '1' , -10 => '-10' , null => 'null'); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - -$input_arrays = array( - 'null indexed' => array(NULL => 'null 1', null => 'null 2'), - 'undefined indexed' => array(@$undefined_var => 'undefined'), - 'unset indexed' => array(@$unset_var => 'unset'), -); - -foreach($input_arrays as $key =>$value) { - echo "\n--$key--\n"; - var_dump( array_intersect_key($input_array, $value) ); - var_dump( array_intersect_key($value,$input_array ) ); -} -?> ---EXPECT-- -*** Testing array_intersect_key() : usage variation *** - ---null indexed-- -array(1) { - [""]=> - string(4) "null" -} -array(1) { - [""]=> - string(6) "null 2" -} - ---undefined indexed-- -array(1) { - [""]=> - string(4) "null" -} -array(1) { - [""]=> - string(9) "undefined" -} - ---unset indexed-- -array(1) { - [""]=> - string(4) "null" -} -array(1) { - [""]=> - string(5) "unset" -} diff --git a/ext/standard/tests/array/array_intersect_variation3.phpt b/ext/standard/tests/array/array_intersect_variation3.phpt index 1f3258ae8326..05584ae0a49c 100644 --- a/ext/standard/tests/array/array_intersect_variation3.phpt +++ b/ext/standard/tests/array/array_intersect_variation3.phpt @@ -25,13 +25,6 @@ the lazy dog This is a double quoted string EOT; -// heredoc with different whitespaces -$diff_whitespaces = <<22 @@ -47,9 +40,9 @@ $arrays = array ( array(false,true), // array with default keys and boolean values array(), // empty array /*5*/ array(NULL), // array with NULL - array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings - array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings - array($blank_line, $multiline_string, $diff_whitespaces, $numeric_string), // array with heredocs + array("a\v\f","aaaa\n","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings + array('a\v\f','aaaa\n','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings + array($blank_line, $multiline_string, $numeric_string), // array with heredocs // associative arrays /*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values @@ -58,25 +51,24 @@ $arrays = array ( array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value array("one" => 1, 2 => "two", 4 => "four"), //mixed - // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), - array(true => "true", false => "false", "false" => false, "true" => true), + // associative array, containing empty/boolean values as key/value +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) ); -// array to be passsed to $arr2 argument +// array to be passed to $arr2 argument $arr2 = array ( 1, 1.1, "hello", "one", NULL, 2, - 'world', true, false, false => 5, 'aaaa\r', "aaaa\r", - $numeric_string, $diff_whitespaces, + 'world', true, false, false => 5, 'aaaa\n', "aaaa\n", + $numeric_string, "one" => "ten", 4 => "four", "two" => 2, 2 => "two", - '', null => "null", '' => 'emptys' + '', '' => 'emptys' ); // loop through each sub-array within $arrays to check the behavior of array_intersect() @@ -149,42 +141,34 @@ array(1) { -- Iterator 6 -- array(1) { [1]=> - string(5) "aaaa " + string(5) "aaaa +" } array(1) { [1]=> - string(5) "aaaa " + string(5) "aaaa +" } -- Iterator 7 -- array(1) { [1]=> - string(6) "aaaa\r" + string(6) "aaaa\n" } array(1) { [1]=> - string(6) "aaaa\r" + string(6) "aaaa\n" } -- Iterator 8 -- -array(2) { +array(1) { [2]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" - [3]=> string(90) "11 < 12. 123 >22 'single quoted string' "double quoted string" 2222 != 1111. 0000 = 0000 " } -array(2) { +array(1) { [2]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" - [3]=> string(90) "11 < 12. 123 >22 'single quoted string' "double quoted string" @@ -249,19 +233,6 @@ array(3) { string(4) "four" } -- Iterator 14 -- -array(2) { - ["NULL"]=> - NULL - ["null"]=> - NULL -} -array(2) { - ["NULL"]=> - NULL - ["null"]=> - NULL -} --- Iterator 15 -- array(2) { ["false"]=> bool(false) @@ -274,7 +245,7 @@ array(2) { ["true"]=> bool(true) } --- Iterator 16 -- +-- Iterator 15 -- array(3) { [""]=> string(6) "emptys" @@ -291,45 +262,41 @@ array(3) { ["emptys"]=> string(0) "" } --- Iterator 17 -- -array(6) { +-- Iterator 16 -- +array(4) { [1]=> string(0) "" [2]=> string(0) "" - [3]=> - NULL - [4]=> - NULL [5]=> bool(false) [6]=> bool(true) } -array(6) { +array(4) { [1]=> string(0) "" [2]=> string(0) "" - [3]=> - NULL - [4]=> - NULL [5]=> bool(false) [6]=> bool(true) } --- Iterator 18 -- -array(1) { +-- Iterator 17 -- +array(2) { + [""]=> + int(2) [0]=> int(5) } -array(1) { +array(2) { + [""]=> + int(2) [0]=> int(5) } --- Iterator 19 -- +-- Iterator 18 -- array(0) { } array(0) { diff --git a/ext/standard/tests/array/array_intersect_variation4.phpt b/ext/standard/tests/array/array_intersect_variation4.phpt index ce0fa47b03f3..cb41dcd02904 100644 --- a/ext/standard/tests/array/array_intersect_variation4.phpt +++ b/ext/standard/tests/array/array_intersect_variation4.phpt @@ -25,13 +25,6 @@ the lazy dog This is a double quoted string EOT; -// heredoc with different whitespaces -$diff_whitespaces = <<22 @@ -43,10 +36,10 @@ EOT; // array to be passsed to $arr1 argument $arr1 = array ( 1, 1.1, "hello", "one", NULL, 2, - 'world', true, false, false => 5, 'aaaa\r', "aaaa\r", - $numeric_string, $diff_whitespaces, + 'world', true, false, false => 5, 'aaaa\n', "aaaa\n", + $numeric_string, "one" => "ten", 4 => "four", "two" => 2, 2 => "two", - '', null => "null", '' => 'emptys' + '', '' => 'emptys' ); // arrays to be passed to $arr2 argument @@ -56,9 +49,9 @@ $arrays = array ( array(false,true), // array with default keys and boolean values array(), // empty array /*5*/ array(NULL), // array with NULL - array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings - array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings - array($blank_line, $multiline_string, $diff_whitespaces, $numeric_string), // array with heredocs + array("a\v\f","aaaa\n","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings + array('a\v\f','aaaa\n','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings + array($blank_line, $multiline_string, $numeric_string), // array with heredocs // associative arrays /*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values @@ -68,11 +61,11 @@ $arrays = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -128,7 +121,7 @@ array(3) { bool(true) [8]=> bool(false) - [13]=> + [12]=> string(0) "" } array(3) { @@ -136,7 +129,7 @@ array(3) { bool(true) [8]=> bool(false) - [13]=> + [12]=> string(0) "" } -- Iteration 4 -- @@ -148,59 +141,51 @@ array(0) { array(2) { [8]=> bool(false) - [13]=> + [12]=> string(0) "" } array(2) { [8]=> bool(false) - [13]=> + [12]=> string(0) "" } -- Iteration 6 -- array(1) { [10]=> - string(5) "aaaa " + string(5) "aaaa +" } array(1) { [10]=> - string(5) "aaaa " + string(5) "aaaa +" } -- Iteration 7 -- array(1) { [9]=> - string(6) "aaaa\r" + string(6) "aaaa\n" } array(1) { [9]=> - string(6) "aaaa\r" + string(6) "aaaa\n" } -- Iteration 8 -- -array(2) { +array(1) { [11]=> string(90) "11 < 12. 123 >22 'single quoted string' "double quoted string" 2222 != 1111. 0000 = 0000 " - [12]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" } -array(2) { +array(1) { [11]=> string(90) "11 < 12. 123 >22 'single quoted string' "double quoted string" 2222 != 1111. 0000 = 0000 " - [12]=> - string(88) "hello world -1111 != 2222 -heredoc -double quoted string. with different white spaces" } -- Iteration 9 -- array(2) { @@ -264,25 +249,12 @@ array(3) { bool(true) } -- Iteration 14 -- -array(2) { - [8]=> - bool(false) - [13]=> - string(0) "" -} -array(2) { - [8]=> - bool(false) - [13]=> - string(0) "" -} --- Iteration 15 -- array(3) { [7]=> bool(true) [8]=> bool(false) - [13]=> + [12]=> string(0) "" } array(3) { @@ -290,14 +262,14 @@ array(3) { bool(true) [8]=> bool(false) - [13]=> + [12]=> string(0) "" } --- Iteration 16 -- +-- Iteration 15 -- array(3) { [8]=> bool(false) - [13]=> + [12]=> string(0) "" [""]=> string(6) "emptys" @@ -305,18 +277,18 @@ array(3) { array(3) { [8]=> bool(false) - [13]=> + [12]=> string(0) "" [""]=> string(6) "emptys" } --- Iteration 17 -- +-- Iteration 16 -- array(3) { [7]=> bool(true) [8]=> bool(false) - [13]=> + [12]=> string(0) "" } array(3) { @@ -324,19 +296,27 @@ array(3) { bool(true) [8]=> bool(false) - [13]=> + [12]=> string(0) "" } --- Iteration 18 -- -array(1) { +-- Iteration 17 -- +array(3) { [0]=> int(5) + [5]=> + int(2) + ["two"]=> + int(2) } -array(1) { +array(3) { [0]=> int(5) + [5]=> + int(2) + ["two"]=> + int(2) } --- Iteration 19 -- +-- Iteration 18 -- array(0) { } array(0) { diff --git a/ext/standard/tests/array/array_intersect_variation5.phpt b/ext/standard/tests/array/array_intersect_variation5.phpt index 12edea88196e..f394a030bd78 100644 --- a/ext/standard/tests/array/array_intersect_variation5.phpt +++ b/ext/standard/tests/array/array_intersect_variation5.phpt @@ -10,10 +10,6 @@ Test array_intersect() function : usage variations - assoc array with diff keys echo "*** Testing array_intersect() : assoc array with diff keys to \$arr1 argument ***\n"; -// get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a heredoc string $heredoc = << 2.2, "pen\n" => 33), array("hello", $heredoc => "string"), // heredoc - // array with unset variable -/*10*/ array( @$unset_var => "hello"), - // array with mixed keys /*11*/ array('hello' => 1, "fruit" => 2.2, 133 => "int", - @$unset_var => "unset", $heredoc => "heredoc") + $heredoc => "heredoc") ); // array to be passed to $arr2 argument @@ -135,15 +128,6 @@ array(2) { string(6) "string" } -- Iterator 8 -- -array(1) { - [""]=> - string(5) "hello" -} -array(1) { - [""]=> - string(5) "hello" -} --- Iterator 9 -- array(2) { ["hello"]=> int(1) diff --git a/ext/standard/tests/array/array_intersect_variation6.phpt b/ext/standard/tests/array/array_intersect_variation6.phpt index 93ff4271d70a..7bad0b25b958 100644 --- a/ext/standard/tests/array/array_intersect_variation6.phpt +++ b/ext/standard/tests/array/array_intersect_variation6.phpt @@ -10,10 +10,6 @@ Test array_intersect() function : usage variations - assoc array with diff keys echo "*** Testing array_intersect() : assoc array with diff keys to \$arr2 argument ***\n"; -// get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a heredoc string $heredoc = << 2.2, "pen\n" => 33), array("hello", $heredoc => "string"), // heredoc - // array with unset variable -/*10*/ array( @$unset_var => "hello"), - // array with mixed keys /*11*/ array('hello' => 1, "fruit" => 2.2, 133 => "int", - @$unset_var => "unset", $heredoc => "heredoc") + $heredoc => "heredoc") ); // array to be passed to $arr1 argument @@ -135,15 +128,6 @@ array(2) { string(6) "string" } -- Iterator 8 -- -array(1) { - [3]=> - string(5) "hello" -} -array(1) { - [3]=> - string(5) "hello" -} --- Iterator 9 -- array(2) { [0]=> int(1) diff --git a/ext/standard/tests/array/array_key_exists.phpt b/ext/standard/tests/array/array_key_exists.phpt index 8cc2f9c5207c..92373b04bb45 100644 --- a/ext/standard/tests/array/array_key_exists.phpt +++ b/ext/standard/tests/array/array_key_exists.phpt @@ -44,7 +44,7 @@ $search_arrays_v = array ( array(), array(NULL), array(array(), 1, 2), - array(1,2,3, "" => "value", NULL => "value", true => "value" ), + array(1,2,3, "" => "value", true => "value" ), array( array(2,4,5), array ("a","b","d") ) ); // search for $key_variations in each sub array of $search_arrays_v @@ -82,7 +82,7 @@ try { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- *** Testing basic functionalities *** -- Iteration 1 -- bool(true) @@ -104,7 +104,11 @@ bool(true) ** Variation loop 1 ** -- Iteration 1 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -112,7 +116,11 @@ bool(false) bool(true) -- Iteration 2 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -120,7 +128,11 @@ bool(false) bool(true) -- Iteration 3 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -128,7 +140,11 @@ bool(false) bool(true) -- Iteration 4 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -136,7 +152,11 @@ bool(false) bool(true) -- Iteration 5 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -144,7 +164,11 @@ bool(false) bool(false) -- Iteration 6 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -152,7 +176,11 @@ bool(false) bool(false) -- Iteration 7 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -162,7 +190,11 @@ bool(true) ** Variation loop 2 ** -- Iteration 1 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -170,7 +202,11 @@ bool(false) bool(false) -- Iteration 2 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -178,7 +214,11 @@ bool(false) bool(false) -- Iteration 3 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) @@ -186,7 +226,11 @@ bool(false) bool(true) -- Iteration 4 -- bool(true) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(true) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(true) bool(false) bool(true) @@ -194,7 +238,11 @@ bool(false) bool(true) -- Iteration 5 -- bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) bool(false) bool(false) diff --git a/ext/standard/tests/array/array_key_exists_variation1.phpt b/ext/standard/tests/array/array_key_exists_variation1.phpt index e3133cfc8eb1..d12fbc839b79 100644 --- a/ext/standard/tests/array/array_key_exists_variation1.phpt +++ b/ext/standard/tests/array/array_key_exists_variation1.phpt @@ -105,9 +105,13 @@ bool(false) bool(false) -- Iteration 5 -- + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) -- Iteration 6 -- + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) -- Iteration 7 -- @@ -144,9 +148,13 @@ bool(true) Cannot access offset of type classA on array -- Iteration 18 -- + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) -- Iteration 19 -- + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(false) -- Iteration 20 -- diff --git a/ext/standard/tests/array/array_key_exists_variation6.phpt b/ext/standard/tests/array/array_key_exists_variation6.phpt index fe16478833c5..8c98a6971c02 100644 --- a/ext/standard/tests/array/array_key_exists_variation6.phpt +++ b/ext/standard/tests/array/array_key_exists_variation6.phpt @@ -36,54 +36,110 @@ foreach($array as $name => $input) { echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing array_key_exists() : usage variations *** -- Key in $search array is : null -- -Iteration 1: bool(true) -Iteration 2: bool(true) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +Iteration 1: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 2: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) Iteration 3: bool(true) Iteration 4: bool(true) -Iteration 5: bool(true) -Iteration 6: bool(true) +Iteration 5: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 6: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) -- Key in $search array is : NULL -- -Iteration 1: bool(true) -Iteration 2: bool(true) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +Iteration 1: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 2: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) Iteration 3: bool(true) Iteration 4: bool(true) -Iteration 5: bool(true) -Iteration 6: bool(true) +Iteration 5: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 6: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) -- Key in $search array is : empty single quoted string -- -Iteration 1: bool(true) -Iteration 2: bool(true) +Iteration 1: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 2: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) Iteration 3: bool(true) Iteration 4: bool(true) -Iteration 5: bool(true) -Iteration 6: bool(true) +Iteration 5: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 6: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) -- Key in $search array is : empty double quoted string -- -Iteration 1: bool(true) -Iteration 2: bool(true) +Iteration 1: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 2: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) Iteration 3: bool(true) Iteration 4: bool(true) -Iteration 5: bool(true) -Iteration 6: bool(true) +Iteration 5: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 6: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) -- Key in $search array is : undefined variable -- -Iteration 1: bool(true) -Iteration 2: bool(true) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +Iteration 1: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 2: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) Iteration 3: bool(true) Iteration 4: bool(true) -Iteration 5: bool(true) -Iteration 6: bool(true) +Iteration 5: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 6: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) -- Key in $search array is : unset variable -- -Iteration 1: bool(true) -Iteration 2: bool(true) + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d +Iteration 1: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 2: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) Iteration 3: bool(true) Iteration 4: bool(true) -Iteration 5: bool(true) -Iteration 6: bool(true) +Iteration 5: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) +Iteration 6: +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d +bool(true) Done diff --git a/ext/standard/tests/array/array_key_exists_variation8.phpt b/ext/standard/tests/array/array_key_exists_variation8.phpt index 417b56aae845..23a7212bbae1 100644 --- a/ext/standard/tests/array/array_key_exists_variation8.phpt +++ b/ext/standard/tests/array/array_key_exists_variation8.phpt @@ -10,10 +10,6 @@ Test array_key_exists() function : usage variations - array keys are different d echo "*** Testing array_key_exists() : usage variations ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // heredoc string $heredoc = << 'negative', ), - // null data -/*3*/ 'null uppercase' => array( - NULL => 'null 1', - ), - 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*4*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), - 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), // empty data -/*5*/ 'empty double quotes' => array( - "" => 'emptyd', - ), - 'empty single quotes' => array( +/*5*/ 'empty single quotes' => array( '' => 'emptys', ), @@ -62,22 +43,12 @@ $inputs = array( 'strings' => 'strings', $heredoc => 'stringh', ), - - // undefined data -/*8*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*9*/ 'unset' => array( - @$unset_var => 'unset', - ), ); // loop through each element of $inputs to check the behavior of array_key_exists() $iterator = 1; foreach($inputs as $type => $input) { - echo "\n-- Iteration $iterator: $type data --\n"; + echo "\n-- $type data --\n"; //iterate over again to get all different key values foreach ($inputs as $new_type => $new_input) { @@ -94,293 +65,67 @@ echo "Done"; --EXPECT-- *** Testing array_key_exists() : usage variations *** --- Iteration 1: int data -- +-- int data -- -- $key arguments are int data: bool(true) bool(true) bool(true) bool(true) --- $key arguments are null uppercase data: -bool(false) --- $key arguments are null lowercase data: -bool(false) -- $key arguments are bool lowercase data: bool(true) bool(true) --- $key arguments are bool uppercase data: -bool(true) -bool(true) --- $key arguments are empty double quotes data: -bool(false) -- $key arguments are empty single quotes data: bool(false) -- $key arguments are string data: bool(false) bool(false) bool(false) --- $key arguments are undefined data: -bool(false) --- $key arguments are unset data: -bool(false) --- Iteration 2: null uppercase data -- +-- bool lowercase data -- -- $key arguments are int data: -bool(false) -bool(false) -bool(false) -bool(false) --- $key arguments are null uppercase data: -bool(true) --- $key arguments are null lowercase data: -bool(true) --- $key arguments are bool lowercase data: -bool(false) -bool(false) --- $key arguments are bool uppercase data: -bool(false) -bool(false) --- $key arguments are empty double quotes data: -bool(true) --- $key arguments are empty single quotes data: -bool(true) --- $key arguments are string data: -bool(false) -bool(false) -bool(false) --- $key arguments are undefined data: -bool(true) --- $key arguments are unset data: -bool(true) - --- Iteration 3: null lowercase data -- --- $key arguments are int data: -bool(false) -bool(false) -bool(false) -bool(false) --- $key arguments are null uppercase data: bool(true) --- $key arguments are null lowercase data: bool(true) --- $key arguments are bool lowercase data: -bool(false) -bool(false) --- $key arguments are bool uppercase data: -bool(false) -bool(false) --- $key arguments are empty double quotes data: -bool(true) --- $key arguments are empty single quotes data: -bool(true) --- $key arguments are string data: -bool(false) -bool(false) -bool(false) --- $key arguments are undefined data: -bool(true) --- $key arguments are unset data: -bool(true) - --- Iteration 4: bool lowercase data -- --- $key arguments are int data: -bool(true) -bool(true) -bool(false) -bool(false) --- $key arguments are null uppercase data: -bool(false) --- $key arguments are null lowercase data: -bool(false) --- $key arguments are bool lowercase data: -bool(true) -bool(true) --- $key arguments are bool uppercase data: -bool(true) -bool(true) --- $key arguments are empty double quotes data: -bool(false) --- $key arguments are empty single quotes data: -bool(false) --- $key arguments are string data: -bool(false) -bool(false) -bool(false) --- $key arguments are undefined data: -bool(false) --- $key arguments are unset data: -bool(false) - --- Iteration 5: bool uppercase data -- --- $key arguments are int data: -bool(true) -bool(true) -bool(false) -bool(false) --- $key arguments are null uppercase data: bool(false) --- $key arguments are null lowercase data: bool(false) -- $key arguments are bool lowercase data: bool(true) bool(true) --- $key arguments are bool uppercase data: -bool(true) -bool(true) --- $key arguments are empty double quotes data: -bool(false) -- $key arguments are empty single quotes data: bool(false) -- $key arguments are string data: bool(false) bool(false) bool(false) --- $key arguments are undefined data: -bool(false) --- $key arguments are unset data: -bool(false) --- Iteration 6: empty double quotes data -- +-- empty single quotes data -- -- $key arguments are int data: bool(false) bool(false) bool(false) bool(false) --- $key arguments are null uppercase data: -bool(true) --- $key arguments are null lowercase data: -bool(true) -- $key arguments are bool lowercase data: bool(false) bool(false) --- $key arguments are bool uppercase data: -bool(false) -bool(false) --- $key arguments are empty double quotes data: -bool(true) -- $key arguments are empty single quotes data: bool(true) -- $key arguments are string data: bool(false) bool(false) bool(false) --- $key arguments are undefined data: -bool(true) --- $key arguments are unset data: -bool(true) --- Iteration 7: empty single quotes data -- +-- string data -- -- $key arguments are int data: bool(false) bool(false) bool(false) bool(false) --- $key arguments are null uppercase data: -bool(true) --- $key arguments are null lowercase data: -bool(true) -- $key arguments are bool lowercase data: bool(false) bool(false) --- $key arguments are bool uppercase data: -bool(false) -bool(false) --- $key arguments are empty double quotes data: -bool(true) --- $key arguments are empty single quotes data: -bool(true) --- $key arguments are string data: -bool(false) -bool(false) -bool(false) --- $key arguments are undefined data: -bool(true) --- $key arguments are unset data: -bool(true) - --- Iteration 8: string data -- --- $key arguments are int data: -bool(false) -bool(false) -bool(false) -bool(false) --- $key arguments are null uppercase data: -bool(false) --- $key arguments are null lowercase data: -bool(false) --- $key arguments are bool lowercase data: -bool(false) -bool(false) --- $key arguments are bool uppercase data: -bool(false) -bool(false) --- $key arguments are empty double quotes data: -bool(false) -- $key arguments are empty single quotes data: bool(false) -- $key arguments are string data: bool(true) bool(true) bool(true) --- $key arguments are undefined data: -bool(false) --- $key arguments are unset data: -bool(false) - --- Iteration 9: undefined data -- --- $key arguments are int data: -bool(false) -bool(false) -bool(false) -bool(false) --- $key arguments are null uppercase data: -bool(true) --- $key arguments are null lowercase data: -bool(true) --- $key arguments are bool lowercase data: -bool(false) -bool(false) --- $key arguments are bool uppercase data: -bool(false) -bool(false) --- $key arguments are empty double quotes data: -bool(true) --- $key arguments are empty single quotes data: -bool(true) --- $key arguments are string data: -bool(false) -bool(false) -bool(false) --- $key arguments are undefined data: -bool(true) --- $key arguments are unset data: -bool(true) - --- Iteration 10: unset data -- --- $key arguments are int data: -bool(false) -bool(false) -bool(false) -bool(false) --- $key arguments are null uppercase data: -bool(true) --- $key arguments are null lowercase data: -bool(true) --- $key arguments are bool lowercase data: -bool(false) -bool(false) --- $key arguments are bool uppercase data: -bool(false) -bool(false) --- $key arguments are empty double quotes data: -bool(true) --- $key arguments are empty single quotes data: -bool(true) --- $key arguments are string data: -bool(false) -bool(false) -bool(false) --- $key arguments are undefined data: -bool(true) --- $key arguments are unset data: -bool(true) Done diff --git a/ext/standard/tests/array/array_key_first.phpt b/ext/standard/tests/array/array_key_first.phpt index d3360f6bfe9f..c0aa1d770097 100644 --- a/ext/standard/tests/array/array_key_first.phpt +++ b/ext/standard/tests/array/array_key_first.phpt @@ -15,7 +15,7 @@ $mixed_array = array( array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL ), array( 12, "name", 'age', '45' ), array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, @@ -174,7 +174,7 @@ array(12) { [4]=> int(6) [""]=> - int(3) + string(5) "blank" [2]=> string(5) "float" ["F"]=> diff --git a/ext/standard/tests/array/array_key_last.phpt b/ext/standard/tests/array/array_key_last.phpt index c325be656002..14c4bfe9a2e6 100644 --- a/ext/standard/tests/array/array_key_last.phpt +++ b/ext/standard/tests/array/array_key_last.phpt @@ -15,7 +15,7 @@ $mixed_array = array( array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL ), array( 12, "name", 'age', '45' ), array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, @@ -174,7 +174,7 @@ array(12) { [4]=> int(6) [""]=> - int(3) + string(5) "blank" [2]=> string(5) "float" ["F"]=> diff --git a/ext/standard/tests/array/array_keys_variation_001.phpt b/ext/standard/tests/array/array_keys_variation_001.phpt index fdba88afbdd5..4727beefa073 100644 --- a/ext/standard/tests/array/array_keys_variation_001.phpt +++ b/ext/standard/tests/array/array_keys_variation_001.phpt @@ -14,7 +14,7 @@ $arrays = array( array("a" => 1, "b" => 2, "c" =>3, "d" => array()), array(0 => 0, 1 => 1, 2 => 2, 3 => 3), array(0 =>3.000, 1 =>2, 1 =>3, "a"=>3, 3=>5, "5"=>3.000), - array(TRUE => TRUE, FALSE => FALSE, NULL => NULL, "\x000", "\000"), + array(TRUE => TRUE, FALSE => FALSE, "\x000", "\000"), array("a" => "abcd", "a" => "", "ab" => -6, "cd" => -0.5 ), array(0 => array(), 1=> array(0), 2 => array(1), ""=> array(),""=>"" ) ); @@ -110,16 +110,14 @@ array(5) { } -- Iteration 9 -- -array(5) { +array(4) { [0]=> int(1) [1]=> int(0) [2]=> - string(0) "" - [3]=> int(2) - [4]=> + [3]=> int(3) } diff --git a/ext/standard/tests/array/array_map_variation3.phpt b/ext/standard/tests/array/array_map_variation3.phpt index e252c5a7c5a5..10b1793df025 100644 --- a/ext/standard/tests/array/array_map_variation3.phpt +++ b/ext/standard/tests/array/array_map_variation3.phpt @@ -31,11 +31,11 @@ $arrays = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*13*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), +/*13*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*18*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -158,15 +158,6 @@ array(3) { string(4) "four" } -- Iteration 13 -- -array(3) { - [""]=> - string(4) "null" - ["NULL"]=> - NULL - ["null"]=> - NULL -} --- Iteration 14 -- array(4) { [1]=> string(4) "true" @@ -177,7 +168,7 @@ array(4) { ["true"]=> bool(true) } --- Iteration 15 -- +-- Iteration 14 -- array(3) { [""]=> string(6) "emptys" @@ -186,31 +177,27 @@ array(3) { ["emptys"]=> string(0) "" } --- Iteration 16 -- -array(6) { +-- Iteration 15 -- +array(4) { [1]=> string(0) "" [2]=> string(0) "" - [3]=> - NULL - [4]=> - NULL [5]=> bool(false) [6]=> bool(true) } --- Iteration 17 -- +-- Iteration 16 -- array(3) { [""]=> - int(4) + int(2) [0]=> int(5) [1]=> int(6) } --- Iteration 18 -- +-- Iteration 17 -- array(3) { ["One"]=> int(10) diff --git a/ext/standard/tests/array/array_map_variation4.phpt b/ext/standard/tests/array/array_map_variation4.phpt index d75a0bcf2610..2062588fc4e5 100644 --- a/ext/standard/tests/array/array_map_variation4.phpt +++ b/ext/standard/tests/array/array_map_variation4.phpt @@ -46,12 +46,12 @@ $arrays = array ( array("hello", $heredoc => "string"), // heredoc // array with object, unset variable and resource variable - array(@$unset_var => "hello", STDERR => 'resource'), + array(STDERR => 'resource'), // array with mixed values /*11*/ array('hello' => 1, "fruit" => 2.2, STDERR => 'resource', 133 => "int", - @$unset_var => "unset", $heredoc => "heredoc") + $heredoc => "heredoc") ); // loop through the various elements of $arrays to test array_map() @@ -125,14 +125,12 @@ array(2) { string(6) "string" } -- Iteration 8 -- -array(2) { - [""]=> - string(5) "hello" +array(1) { [3]=> string(8) "resource" } -- Iteration 9 -- -array(6) { +array(5) { ["hello"]=> int(1) ["fruit"]=> @@ -141,8 +139,6 @@ array(6) { string(8) "resource" [133]=> string(3) "int" - [""]=> - string(5) "unset" ["Hello world"]=> string(7) "heredoc" } diff --git a/ext/standard/tests/array/array_map_variation7.phpt b/ext/standard/tests/array/array_map_variation7.phpt index 30e6f9d91d61..811219b6bb83 100644 --- a/ext/standard/tests/array/array_map_variation7.phpt +++ b/ext/standard/tests/array/array_map_variation7.phpt @@ -27,7 +27,7 @@ var_dump( array_map('callback', array(), array(1, 2, 3), array('a', 'b')) ); // echo "Done"; ?> ---EXPECT-- +--EXPECTF-- *** Testing array_map() : arrays with diff. size *** array(3) { [0]=> @@ -46,6 +46,12 @@ array(3) { NULL } } + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d array(3) { [0]=> array(1) { @@ -97,6 +103,12 @@ array(3) { NULL } } + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d array(3) { [0]=> array(1) { diff --git a/ext/standard/tests/array/array_merge_recursive_variation3.phpt b/ext/standard/tests/array/array_merge_recursive_variation3.phpt index 214d7654426b..a7f746d1076a 100644 --- a/ext/standard/tests/array/array_merge_recursive_variation3.phpt +++ b/ext/standard/tests/array/array_merge_recursive_variation3.phpt @@ -27,7 +27,7 @@ EOT; // heredoc with different whitespaces $diff_whitespaces = << $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces), // with heredocs // associative arrays @@ -59,11 +59,11 @@ $arrays = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array containing embedded arrays /*15*/ array("str1", "array" => array("hello", 'world'), array(1, 2)) @@ -236,7 +236,8 @@ array(4) { [0]=> string(3) "a " [1]=> - string(5) "aaaa " + string(5) "aaaa +" [2]=> string(1) "b" [3]=> @@ -247,7 +248,8 @@ array(8) { [0]=> string(3) "a " [1]=> - string(5) "aaaa " + string(5) "aaaa +" [2]=> string(1) "b" [3]=> @@ -274,7 +276,7 @@ array(4) { [0]=> string(5) "a\v\f" [1]=> - string(6) "aaaa\r" + string(6) "aaaa\n" [2]=> string(1) "b" [3]=> @@ -285,7 +287,7 @@ array(8) { [0]=> string(5) "a\v\f" [1]=> - string(6) "aaaa\r" + string(6) "aaaa\n" [2]=> string(1) "b" [3]=> @@ -318,7 +320,8 @@ The quick brown fox jumped over; the lazy dog This is a double quoted string" ["h3"]=> - string(88) "hello world + string(88) "hello + world 1111 != 2222 heredoc double quoted string. with different white spaces" @@ -334,7 +337,8 @@ The quick brown fox jumped over; the lazy dog This is a double quoted string" ["h3"]=> - string(88) "hello world + string(88) "hello + world 1111 != 2222 heredoc double quoted string. with different white spaces" @@ -518,40 +522,6 @@ array(7) { } -- Iteration 14 -- -- With default argument -- -array(3) { - [""]=> - string(4) "null" - ["NULL"]=> - NULL - ["null"]=> - NULL -} --- With more arguments -- -array(7) { - [""]=> - string(4) "null" - ["NULL"]=> - NULL - ["null"]=> - NULL - [0]=> - string(3) "one" - [1]=> - int(2) - ["string"]=> - string(5) "hello" - ["array"]=> - array(3) { - [0]=> - string(1) "a" - [1]=> - string(1) "b" - [2]=> - string(1) "c" - } -} --- Iteration 15 -- --- With default argument -- array(4) { [0]=> string(4) "true" @@ -588,7 +558,7 @@ array(8) { string(1) "c" } } --- Iteration 16 -- +-- Iteration 15 -- -- With default argument -- array(3) { [""]=> @@ -622,39 +592,31 @@ array(7) { string(1) "c" } } --- Iteration 17 -- +-- Iteration 16 -- -- With default argument -- -array(6) { +array(4) { [0]=> string(0) "" [1]=> string(0) "" [2]=> - NULL - [3]=> - NULL - [4]=> bool(false) - [5]=> + [3]=> bool(true) } -- With more arguments -- -array(10) { +array(8) { [0]=> string(0) "" [1]=> string(0) "" [2]=> - NULL - [3]=> - NULL - [4]=> bool(false) - [5]=> + [3]=> bool(true) - [6]=> + [4]=> string(3) "one" - [7]=> + [5]=> int(2) ["string"]=> string(5) "hello" @@ -668,11 +630,11 @@ array(10) { string(1) "c" } } --- Iteration 18 -- +-- Iteration 17 -- -- With default argument -- array(3) { [""]=> - int(4) + int(2) [0]=> int(5) [1]=> @@ -681,7 +643,7 @@ array(3) { -- With more arguments -- array(7) { [""]=> - int(4) + int(2) [0]=> int(5) [1]=> @@ -702,7 +664,7 @@ array(7) { string(1) "c" } } --- Iteration 19 -- +-- Iteration 18 -- -- With default argument -- array(3) { [0]=> diff --git a/ext/standard/tests/array/array_merge_recursive_variation4.phpt b/ext/standard/tests/array/array_merge_recursive_variation4.phpt index 71f4a4d66fbc..e5dcc5b9cc25 100644 --- a/ext/standard/tests/array/array_merge_recursive_variation4.phpt +++ b/ext/standard/tests/array/array_merge_recursive_variation4.phpt @@ -9,10 +9,6 @@ Test array_merge_recursive() function : usage variations - associative array wit echo "*** Testing array_merge_recursive() : assoc. array with diff. keys to \$arr1 argument ***\n"; -// get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a resource variable $fp = fopen(__FILE__, "r"); @@ -41,7 +37,7 @@ $arrays = array ( array("hello", $heredoc => array("heredoc", 'string'), "string"), // array with object, unset variable and resource variable -/*8*/ array(@$unset_var => array("unset"), $fp => 'resource', 11, "hello") +/*8*/ array($fp => 'resource', 11, "hello") ); // initialise the second array @@ -292,12 +288,7 @@ array(7) { } -- Iteration 6 -- -- With default argument -- -array(4) { - [""]=> - array(1) { - [0]=> - string(5) "unset" - } +array(3) { [0]=> string(8) "resource" [1]=> @@ -306,12 +297,7 @@ array(4) { string(5) "hello" } -- With more arguments -- -array(8) { - [""]=> - array(1) { - [0]=> - string(5) "unset" - } +array(7) { [0]=> string(8) "resource" [1]=> diff --git a/ext/standard/tests/array/array_merge_variation4.phpt b/ext/standard/tests/array/array_merge_variation4.phpt index e34bf7352688..ad4ee5b24817 100644 --- a/ext/standard/tests/array/array_merge_variation4.phpt +++ b/ext/standard/tests/array/array_merge_variation4.phpt @@ -12,10 +12,6 @@ echo "*** Testing array_merge() : usage variations ***\n"; // Initialise function arguments not being substituted $arr = array ('one' => 1, 'two' => 2); -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // heredoc string $heredoc = << 'negative', ), - // null data -/*4*/ 'null uppercase' => array( - NULL => 'null 1', - ), - -/*5*/ 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*6*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), -/*7*/ 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), - // empty data -/*8*/ 'empty double quotes' => array( - "" => 'emptyd', - ), - /*9*/ 'empty single quotes' => array( '' => 'emptys', ), @@ -67,16 +45,6 @@ $inputs = array( 'strings' => 'strings', $heredoc => 'stringh', ), - - // undefined data -/*11*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*12*/ 'unset' => array( - @$unset_var => 'unset', - ), ); // loop through each element of $inputs to check the behavior of array_merge @@ -123,43 +91,7 @@ array(6) { string(8) "negative" } --- Iteration 2: null uppercase data -- -array(3) { - [""]=> - string(6) "null 1" - ["one"]=> - int(1) - ["two"]=> - int(2) -} -array(3) { - ["one"]=> - int(1) - ["two"]=> - int(2) - [""]=> - string(6) "null 1" -} - --- Iteration 3: null lowercase data -- -array(3) { - [""]=> - string(6) "null 2" - ["one"]=> - int(1) - ["two"]=> - int(2) -} -array(3) { - ["one"]=> - int(1) - ["two"]=> - int(2) - [""]=> - string(6) "null 2" -} - --- Iteration 4: bool lowercase data -- +-- Iteration 2: bool lowercase data -- array(4) { [0]=> string(6) "lowert" @@ -181,47 +113,7 @@ array(4) { string(6) "lowerf" } --- Iteration 5: bool uppercase data -- -array(4) { - [0]=> - string(6) "uppert" - [1]=> - string(6) "upperf" - ["one"]=> - int(1) - ["two"]=> - int(2) -} -array(4) { - ["one"]=> - int(1) - ["two"]=> - int(2) - [0]=> - string(6) "uppert" - [1]=> - string(6) "upperf" -} - --- Iteration 6: empty double quotes data -- -array(3) { - [""]=> - string(6) "emptyd" - ["one"]=> - int(1) - ["two"]=> - int(2) -} -array(3) { - ["one"]=> - int(1) - ["two"]=> - int(2) - [""]=> - string(6) "emptyd" -} - --- Iteration 7: empty single quotes data -- +-- Iteration 3: empty single quotes data -- array(3) { [""]=> string(6) "emptys" @@ -239,7 +131,7 @@ array(3) { string(6) "emptys" } --- Iteration 8: string data -- +-- Iteration 4: string data -- array(5) { ["stringd"]=> string(7) "stringd" @@ -264,40 +156,4 @@ array(5) { ["hello world"]=> string(7) "stringh" } - --- Iteration 9: undefined data -- -array(3) { - [""]=> - string(9) "undefined" - ["one"]=> - int(1) - ["two"]=> - int(2) -} -array(3) { - ["one"]=> - int(1) - ["two"]=> - int(2) - [""]=> - string(9) "undefined" -} - --- Iteration 10: unset data -- -array(3) { - [""]=> - string(5) "unset" - ["one"]=> - int(1) - ["two"]=> - int(2) -} -array(3) { - ["one"]=> - int(1) - ["two"]=> - int(2) - [""]=> - string(5) "unset" -} Done diff --git a/ext/standard/tests/array/array_merge_variation7.phpt b/ext/standard/tests/array/array_merge_variation7.phpt index a196effc75bd..546206872730 100644 --- a/ext/standard/tests/array/array_merge_variation7.phpt +++ b/ext/standard/tests/array/array_merge_variation7.phpt @@ -11,7 +11,7 @@ echo "*** Testing array_merge() : usage variations ***\n"; //mixed keys $arr1 = array('zero', 20 => 'twenty', 'thirty' => 30, true => 'bool'); -$arr2 = array(0, 1, 2, null => 'null', 0 => 'float'); +$arr2 = array(0, 1, 2, 0 => 'float'); var_dump(array_merge($arr1, $arr2)); var_dump(array_merge($arr2, $arr1)); @@ -20,7 +20,7 @@ echo "Done"; ?> --EXPECT-- *** Testing array_merge() : usage variations *** -array(8) { +array(7) { [0]=> string(4) "zero" [1]=> @@ -35,18 +35,14 @@ array(8) { int(1) [5]=> int(2) - [""]=> - string(4) "null" } -array(8) { +array(7) { [0]=> string(5) "float" [1]=> int(1) [2]=> int(2) - [""]=> - string(4) "null" [3]=> string(4) "zero" [4]=> diff --git a/ext/standard/tests/array/array_pad_variation6.phpt b/ext/standard/tests/array/array_pad_variation6.phpt index fc2d705dbe0f..800f03ca9153 100644 --- a/ext/standard/tests/array/array_pad_variation6.phpt +++ b/ext/standard/tests/array/array_pad_variation6.phpt @@ -28,7 +28,7 @@ EOT; // heredoc with different whitespaces $diff_whitespaces = << $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // with heredocs // associative arrays @@ -60,11 +60,11 @@ $inputs = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -237,7 +237,8 @@ array(6) { [0]=> string(3) "a " [1]=> - string(5) "aaaa " + string(5) "aaaa +" [2]=> string(5) "b bbb" [3]=> @@ -255,7 +256,8 @@ array(6) { [2]=> string(3) "a " [3]=> - string(5) "aaaa " + string(5) "aaaa +" [4]=> string(5) "b bbb" [5]=> @@ -266,7 +268,7 @@ array(6) { [0]=> string(5) "a\v\f" [1]=> - string(6) "aaaa\r" + string(6) "aaaa\n" [2]=> string(6) "b\tbbb" [3]=> @@ -284,7 +286,7 @@ array(6) { [2]=> string(5) "a\v\f" [3]=> - string(6) "aaaa\r" + string(6) "aaaa\n" [4]=> string(6) "b\tbbb" [5]=> @@ -301,7 +303,8 @@ The big brown fox jumped over; the lazy dog This is a double quoted string" ["h3"]=> - string(88) "hello world + string(88) "hello + world 1111 != 2222 heredoc double quoted string. with different white spaces" @@ -330,7 +333,8 @@ The big brown fox jumped over; the lazy dog This is a double quoted string" ["h3"]=> - string(88) "hello world + string(88) "hello + world 1111 != 2222 heredoc double quoted string. with different white spaces" @@ -487,35 +491,6 @@ array(6) { string(4) "four" } -- Iteration 14 -- -array(6) { - [""]=> - string(4) "null" - ["NULL"]=> - NULL - ["null"]=> - NULL - [0]=> - string(5) "HELLO" - [1]=> - string(5) "HELLO" - [2]=> - string(5) "HELLO" -} -array(6) { - [0]=> - string(5) "HELLO" - [1]=> - string(5) "HELLO" - [2]=> - string(5) "HELLO" - [""]=> - string(4) "null" - ["NULL"]=> - NULL - ["null"]=> - NULL -} --- Iteration 15 -- array(6) { [0]=> string(4) "true" @@ -544,7 +519,7 @@ array(6) { ["true"]=> bool(true) } --- Iteration 16 -- +-- Iteration 15 -- array(6) { [""]=> string(6) "emptys" @@ -573,39 +548,39 @@ array(6) { ["emptys"]=> string(0) "" } --- Iteration 17 -- +-- Iteration 16 -- array(6) { + [0]=> + string(0) "" [1]=> string(0) "" [2]=> - string(0) "" + bool(false) [3]=> - NULL + bool(true) [4]=> - NULL + string(5) "HELLO" [5]=> - bool(false) - [6]=> - bool(true) + string(5) "HELLO" } array(6) { + [0]=> + string(5) "HELLO" [1]=> - string(0) "" + string(5) "HELLO" [2]=> string(0) "" [3]=> - NULL + string(0) "" [4]=> - NULL - [5]=> bool(false) - [6]=> + [5]=> bool(true) } --- Iteration 18 -- +-- Iteration 17 -- array(6) { [""]=> - int(4) + int(2) [0]=> int(5) [1]=> @@ -625,13 +600,13 @@ array(6) { [2]=> string(5) "HELLO" [""]=> - int(4) + int(2) [3]=> int(5) [4]=> int(6) } --- Iteration 19 -- +-- Iteration 18 -- array(6) { ["One"]=> int(10) diff --git a/ext/standard/tests/array/array_pop.phpt b/ext/standard/tests/array/array_pop.phpt index 2066f1acb667..7125a3e6f7f3 100644 --- a/ext/standard/tests/array/array_pop.phpt +++ b/ext/standard/tests/array/array_pop.phpt @@ -18,7 +18,7 @@ $mixed_array = array( array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL ), array( 12, "name", 'age', '45' ), array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, @@ -175,7 +175,7 @@ array(12) { [4]=> int(6) [""]=> - int(3) + string(5) "blank" [2]=> string(5) "float" ["F"]=> diff --git a/ext/standard/tests/array/array_pop_variation.phpt b/ext/standard/tests/array/array_pop_variation.phpt index af8b0cc0f9a9..c36f17baf0a6 100644 --- a/ext/standard/tests/array/array_pop_variation.phpt +++ b/ext/standard/tests/array/array_pop_variation.phpt @@ -13,7 +13,7 @@ $mixed_array = array( array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL ), array( 12, "name", 'age', '45' ), array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, diff --git a/ext/standard/tests/array/array_product_packed_long_overflow.phpt b/ext/standard/tests/array/array_product_packed_long_overflow.phpt new file mode 100644 index 000000000000..7c1d8a0adebd --- /dev/null +++ b/ext/standard/tests/array/array_product_packed_long_overflow.phpt @@ -0,0 +1,22 @@ +--TEST-- +array_product() packed long overflow continues in double mode +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/array/array_push.phpt b/ext/standard/tests/array/array_push.phpt index 1c560adc518a..f65f4b35e8d0 100644 --- a/ext/standard/tests/array/array_push.phpt +++ b/ext/standard/tests/array/array_push.phpt @@ -18,7 +18,7 @@ $mixed_array = array( array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL), array( 12, "name", 'age', '45' ), array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, @@ -198,7 +198,7 @@ array(12) { [4]=> int(6) [""]=> - int(3) + string(5) "blank" [2]=> string(5) "float" ["F"]=> diff --git a/ext/standard/tests/array/array_push_variation6.phpt b/ext/standard/tests/array/array_push_variation6.phpt index 610e4efaa0e3..38801e75da57 100644 --- a/ext/standard/tests/array/array_push_variation6.phpt +++ b/ext/standard/tests/array/array_push_variation6.phpt @@ -11,10 +11,6 @@ echo "*** Testing array_push() : usage variations ***\n"; // Initialise function arguments not being substituted $var = 'value'; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // heredoc string $heredoc = << 'negative', ), - // null data -/*3*/ 'null uppercase' => array( - NULL => 'null 1', - ), - 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*4*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), - 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), // empty data -/*5*/ 'empty double quotes' => array( - "" => 'emptyd', - ), 'empty single quotes' => array( '' => 'emptys', ), @@ -63,27 +44,15 @@ $inputs = array( 'strings' => 'strings', $heredoc => 'stringh', ), - - // undefined data -/*8*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*9*/ 'unset' => array( - @$unset_var => 'unset', - ), ); // loop through each sub-array of $inputs to check the behavior of array_push() -$iterator = 1; foreach($inputs as $key => $input) { - echo "\n-- Iteration $iterator : $key data --\n"; + echo "\n-- $key data --\n"; echo "Before : "; var_dump(count($input)); echo "After : "; var_dump( array_push($input, $var) ); - $iterator++; }; echo "Done"; @@ -91,43 +60,19 @@ echo "Done"; --EXPECT-- *** Testing array_push() : usage variations *** --- Iteration 1 : int data -- +-- int data -- Before : int(4) After : int(5) --- Iteration 2 : null uppercase data -- -Before : int(1) -After : int(2) - --- Iteration 3 : null lowercase data -- -Before : int(1) -After : int(2) - --- Iteration 4 : bool lowercase data -- +-- bool lowercase data -- Before : int(2) After : int(3) --- Iteration 5 : bool uppercase data -- -Before : int(2) -After : int(3) - --- Iteration 6 : empty double quotes data -- -Before : int(1) -After : int(2) - --- Iteration 7 : empty single quotes data -- +-- empty single quotes data -- Before : int(1) After : int(2) --- Iteration 8 : string data -- +-- string data -- Before : int(3) After : int(4) - --- Iteration 9 : undefined data -- -Before : int(1) -After : int(2) - --- Iteration 10 : unset data -- -Before : int(1) -After : int(2) Done diff --git a/ext/standard/tests/array/array_reduce_accumulator_refcount.phpt b/ext/standard/tests/array/array_reduce_accumulator_refcount.phpt new file mode 100644 index 000000000000..f2a0639b3456 --- /dev/null +++ b/ext/standard/tests/array/array_reduce_accumulator_refcount.phpt @@ -0,0 +1,35 @@ +--TEST-- +array_reduce(): accumulator refcount stays low during callback +--FILE-- + +--EXPECT-- +array(0) interned { +} +array(1) packed refcount(2){ + [0]=> + int(1) +} +array(2) packed refcount(2){ + [0]=> + int(1) + [1]=> + int(2) +} +array(3) packed refcount(2){ + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} diff --git a/ext/standard/tests/array/array_reverse_variation3.phpt b/ext/standard/tests/array/array_reverse_variation3.phpt index b5c222684ee6..087c10ba8dd1 100644 --- a/ext/standard/tests/array/array_reverse_variation3.phpt +++ b/ext/standard/tests/array/array_reverse_variation3.phpt @@ -9,10 +9,6 @@ Test array_reverse() function : usage variations - different array values for 'a echo "*** Testing array_reverse() : usage variations ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - //get a resource variable $fp = fopen(__FILE__, "r"); @@ -46,11 +42,11 @@ $arrays = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*13*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), +/*13*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*18*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -404,34 +400,6 @@ array(3) { } -- Iteration 13 -- - with default argument - -array(3) { - ["null"]=> - NULL - ["NULL"]=> - NULL - [""]=> - string(4) "null" -} -- with $preserve keys = true - -array(3) { - ["null"]=> - NULL - ["NULL"]=> - NULL - [""]=> - string(4) "null" -} -- with $preserve_keys = false - -array(3) { - ["null"]=> - NULL - ["NULL"]=> - NULL - [""]=> - string(4) "null" -} --- Iteration 14 -- -- with default argument - array(4) { ["true"]=> bool(true) @@ -464,7 +432,7 @@ array(4) { [1]=> string(4) "true" } --- Iteration 15 -- +-- Iteration 14 -- - with default argument - array(3) { ["emptys"]=> @@ -492,53 +460,41 @@ array(3) { [""]=> string(6) "emptys" } --- Iteration 16 -- +-- Iteration 15 -- - with default argument - -array(6) { +array(4) { [0]=> bool(true) [1]=> bool(false) [2]=> - NULL - [3]=> - NULL - [4]=> string(0) "" - [5]=> + [3]=> string(0) "" } - with $preserve keys = true - -array(6) { +array(4) { [6]=> bool(true) [5]=> bool(false) - [4]=> - NULL - [3]=> - NULL [2]=> string(0) "" [1]=> string(0) "" } - with $preserve_keys = false - -array(6) { +array(4) { [0]=> bool(true) [1]=> bool(false) [2]=> - NULL - [3]=> - NULL - [4]=> string(0) "" - [5]=> + [3]=> string(0) "" } --- Iteration 17 -- +-- Iteration 16 -- - with default argument - array(3) { [0]=> @@ -546,7 +502,7 @@ array(3) { [1]=> int(5) [""]=> - int(4) + int(2) } - with $preserve keys = true - array(3) { @@ -555,7 +511,7 @@ array(3) { [0]=> int(5) [""]=> - int(4) + int(2) } - with $preserve_keys = false - array(3) { @@ -564,9 +520,9 @@ array(3) { [1]=> int(5) [""]=> - int(4) + int(2) } --- Iteration 18 -- +-- Iteration 17 -- - with default argument - array(3) { ["three"]=> diff --git a/ext/standard/tests/array/array_reverse_variation4.phpt b/ext/standard/tests/array/array_reverse_variation4.phpt index 4967f6e4dacb..2cf8d3a68d2f 100644 --- a/ext/standard/tests/array/array_reverse_variation4.phpt +++ b/ext/standard/tests/array/array_reverse_variation4.phpt @@ -9,10 +9,6 @@ Test array_reverse() function : usage variations - assoc. array with diff. keys echo "*** Testing array_reverse() : usage variations ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - //get a class class classA{ public function __toString(){ @@ -42,10 +38,10 @@ $arrays = array ( array("hello", $heredoc => "string"), // heredoc // array with object, unset variable and resource variable - array(@$unset_var => "hello", STDERR => 'resource'), + array(STDERR => 'resource'), // array with mixed values -/*11*/ array('hello' => 1, "fruit" => 2.2, STDERR => 'resource', 133 => "int", @$unset_var => "unset", $heredoc => "heredoc") +/*11*/ array('hello' => 1, "fruit" => 2.2, STDERR => 'resource', 133 => "int", $heredoc => "heredoc") ); // loop through the various elements of $arrays to test array_reverse() @@ -245,33 +241,25 @@ array(2) { } -- Iteration 8 -- - default argument - -array(2) { +array(1) { [0]=> string(8) "resource" - [""]=> - string(5) "hello" } - $preserve keys = true - -array(2) { +array(1) { [3]=> string(8) "resource" - [""]=> - string(5) "hello" } - $preserve_keys = false - -array(2) { +array(1) { [0]=> string(8) "resource" - [""]=> - string(5) "hello" } -- Iteration 9 -- - default argument - -array(6) { +array(5) { ["Hello world"]=> string(7) "heredoc" - [""]=> - string(5) "unset" [0]=> string(3) "int" [1]=> @@ -282,11 +270,9 @@ array(6) { int(1) } - $preserve keys = true - -array(6) { +array(5) { ["Hello world"]=> string(7) "heredoc" - [""]=> - string(5) "unset" [133]=> string(3) "int" [3]=> @@ -297,11 +283,9 @@ array(6) { int(1) } - $preserve_keys = false - -array(6) { +array(5) { ["Hello world"]=> string(7) "heredoc" - [""]=> - string(5) "unset" [0]=> string(3) "int" [1]=> diff --git a/ext/standard/tests/array/array_search_variation2.phpt b/ext/standard/tests/array/array_search_variation2.phpt index c391989f320d..1f1cec9b64b5 100644 --- a/ext/standard/tests/array/array_search_variation2.phpt +++ b/ext/standard/tests/array/array_search_variation2.phpt @@ -15,7 +15,7 @@ $misc_array = array ( 0 =>"-.08", "e" =>"5", "y" =>NULL, - NULL =>"", + '' =>"", 0, TRUE, FALSE, diff --git a/ext/standard/tests/array/array_shift_variation3.phpt b/ext/standard/tests/array/array_shift_variation3.phpt index e43bc86858d7..394901561218 100644 --- a/ext/standard/tests/array/array_shift_variation3.phpt +++ b/ext/standard/tests/array/array_shift_variation3.phpt @@ -8,10 +8,6 @@ Test array_shift() function : usage variations - Pass array with different data echo "*** Testing array_shift() : usage variations ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // heredoc string $heredoc = << 'negative', ), - // null data -/*4*/ 'null uppercase' => array( - NULL => 'null 1', - ), - -/*5*/ 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*6*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), -/*7*/ 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), - // empty data -/*8*/ 'empty double quotes' => array( - "" => 'emptyd', - ), /*9*/ 'empty single quotes' => array( '' => 'emptys', @@ -63,16 +42,6 @@ $inputs = array( 'strings' => 'strings', $heredoc => 'stringh', ), - - // undefined data -/*11*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*12*/ 'unset' => array( - @$unset_var => 'unset', - ), ); // loop through each element of $inputs to check the behavior of array_shift() @@ -100,41 +69,19 @@ array(3) { string(8) "negative" } --- Iteration 2 : null uppercase data -- -string(6) "null 1" -array(0) { -} - --- Iteration 3 : null lowercase data -- -string(6) "null 2" -array(0) { -} - --- Iteration 4 : bool lowercase data -- +-- Iteration 2 : bool lowercase data -- string(6) "lowert" array(1) { [0]=> string(6) "lowerf" } --- Iteration 5 : bool uppercase data -- -string(6) "uppert" -array(1) { - [0]=> - string(6) "upperf" -} - --- Iteration 6 : empty double quotes data -- -string(6) "emptyd" -array(0) { -} - --- Iteration 7 : empty single quotes data -- +-- Iteration 3 : empty single quotes data -- string(6) "emptys" array(0) { } --- Iteration 8 : string data -- +-- Iteration 4 : string data -- string(7) "stringd" array(2) { ["strings"]=> @@ -142,14 +89,4 @@ array(2) { ["hello world"]=> string(7) "stringh" } - --- Iteration 9 : undefined data -- -string(9) "undefined" -array(0) { -} - --- Iteration 10 : unset data -- -string(5) "unset" -array(0) { -} Done diff --git a/ext/standard/tests/array/array_slice_variation7.phpt b/ext/standard/tests/array/array_slice_variation7.phpt index d0db376ad583..53cf70e18578 100644 --- a/ext/standard/tests/array/array_slice_variation7.phpt +++ b/ext/standard/tests/array/array_slice_variation7.phpt @@ -13,10 +13,6 @@ echo "*** Testing array_slice() : usage variations ***\n"; $offset = 0; $length = 10; // to ensure all elements are displayed -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // heredoc string $heredoc = << 'negative', ), - // null data -/*4*/ 'null uppercase' => array( - NULL => 'null 1', - ), - -/*5*/ 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*6*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), -/*7*/ 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), - // empty data -/*8*/ 'empty double quotes' => array( - "" => 'emptyd', - ), /*9*/ 'empty single quotes' => array( '' => 'emptys', @@ -68,16 +47,6 @@ $inputs = array( 'strings' => 'strings', $heredoc => 'stringh', ), - - // undefined data -/*11*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*12*/ 'unset' => array( - @$unset_var => 'unset', - ), ); // loop through each element of $inputs to check the behavior of array_slice() @@ -120,31 +89,7 @@ array(4) { string(8) "negative" } --- Iteration 2 : key type is null uppercase -- -$preserve_keys = TRUE -array(1) { - [""]=> - string(6) "null 1" -} -$preserve_keys = FALSE -array(1) { - [""]=> - string(6) "null 1" -} - --- Iteration 3 : key type is null lowercase -- -$preserve_keys = TRUE -array(1) { - [""]=> - string(6) "null 2" -} -$preserve_keys = FALSE -array(1) { - [""]=> - string(6) "null 2" -} - --- Iteration 4 : key type is bool lowercase -- +-- Iteration 2 : key type is bool lowercase -- $preserve_keys = TRUE array(2) { [1]=> @@ -160,35 +105,7 @@ array(2) { string(6) "lowerf" } --- Iteration 5 : key type is bool uppercase -- -$preserve_keys = TRUE -array(2) { - [1]=> - string(6) "uppert" - [0]=> - string(6) "upperf" -} -$preserve_keys = FALSE -array(2) { - [0]=> - string(6) "uppert" - [1]=> - string(6) "upperf" -} - --- Iteration 6 : key type is empty double quotes -- -$preserve_keys = TRUE -array(1) { - [""]=> - string(6) "emptyd" -} -$preserve_keys = FALSE -array(1) { - [""]=> - string(6) "emptyd" -} - --- Iteration 7 : key type is empty single quotes -- +-- Iteration 3 : key type is empty single quotes -- $preserve_keys = TRUE array(1) { [""]=> @@ -200,7 +117,7 @@ array(1) { string(6) "emptys" } --- Iteration 8 : key type is string -- +-- Iteration 4 : key type is string -- $preserve_keys = TRUE array(3) { ["stringd"]=> @@ -219,28 +136,4 @@ array(3) { ["hello world"]=> string(7) "stringh" } - --- Iteration 9 : key type is undefined -- -$preserve_keys = TRUE -array(1) { - [""]=> - string(9) "undefined" -} -$preserve_keys = FALSE -array(1) { - [""]=> - string(9) "undefined" -} - --- Iteration 10 : key type is unset -- -$preserve_keys = TRUE -array(1) { - [""]=> - string(5) "unset" -} -$preserve_keys = FALSE -array(1) { - [""]=> - string(5) "unset" -} Done diff --git a/ext/standard/tests/array/array_sum_packed_long_overflow.phpt b/ext/standard/tests/array/array_sum_packed_long_overflow.phpt new file mode 100644 index 000000000000..22e4f3be52aa --- /dev/null +++ b/ext/standard/tests/array/array_sum_packed_long_overflow.phpt @@ -0,0 +1,22 @@ +--TEST-- +array_sum() packed long overflow continues in double mode +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/array/array_sum_product_integration.phpt b/ext/standard/tests/array/array_sum_product_integration.phpt new file mode 100644 index 000000000000..4b83042a3b45 --- /dev/null +++ b/ext/standard/tests/array/array_sum_product_integration.phpt @@ -0,0 +1,32 @@ +--TEST-- +array_sum()/array_product(): PHP 8.3 nested-array warning and array_column() integration +--FILE-- + 'Pen', 'price' => 3], + ['name' => 'Paper', 'price' => 5], +]; +$prices = array_column($products, 'price'); +var_dump($prices === [3, 5]); +var_dump(array_sum($prices) === 8); +var_dump(array_product($prices) === 15); + +echo "-- PHP 8.3: nested array emits warning and is skipped --\n"; +var_dump(array_sum([1, [2], 3])); +var_dump(array_product([2, [3], 4])); + +?> +--EXPECTF-- +-- array_column() + array_sum()/array_product() integration -- +bool(true) +bool(true) +bool(true) +-- PHP 8.3: nested array emits warning and is skipped -- + +Warning: array_sum(): Addition is not supported on type array in %s on line %d +int(4) + +Warning: array_product(): Multiplication is not supported on type array in %s on line %d +int(8) diff --git a/ext/standard/tests/array/array_unique_variation2.phpt b/ext/standard/tests/array/array_unique_variation2.phpt index 6a9d8e36fd2b..ca6b33434044 100644 --- a/ext/standard/tests/array/array_unique_variation2.phpt +++ b/ext/standard/tests/array/array_unique_variation2.phpt @@ -26,7 +26,7 @@ EOT; // heredoc with different whitespaces $diff_whitespaces = << $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $blank_line), // with heredocs // associative arrays @@ -58,11 +58,11 @@ $inputs = array ( array("one" => 1, 2 => "two", 4 => "four"), //mixed // associative array, containing null/empty/boolean values as key/value -/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), +/*14*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), -/*18*/ array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), +/*18*/ array('' => 1, "" => 2, false => 5, true => 6), ); // loop through each sub-array of $inputs to check the behavior of array_unique() @@ -111,7 +111,8 @@ array(4) { [0]=> string(3) "a " [1]=> - string(5) "aaaa " + string(5) "aaaa +" [2]=> string(1) "b" [4]=> @@ -122,7 +123,7 @@ array(4) { [0]=> string(5) "a\v\f" [1]=> - string(6) "aaaa\r" + string(6) "aaaa\n" [2]=> string(1) "b" [4]=> @@ -139,7 +140,8 @@ The quick brown fox jumped over; the lazy dog This is a double quoted string" ["h3"]=> - string(88) "hello world + string(88) "hello + world 1111 != 2222 heredoc double quoted string. with different white spaces" @@ -184,13 +186,6 @@ array(3) { string(4) "four" } -- Iteration 14 -- -array(2) { - [""]=> - string(4) "null" - ["NULL"]=> - NULL -} --- Iteration 15 -- array(4) { [1]=> string(4) "true" @@ -201,24 +196,24 @@ array(4) { ["true"]=> bool(true) } --- Iteration 16 -- +-- Iteration 15 -- array(2) { [""]=> string(6) "emptys" ["emptyd"]=> string(0) "" } --- Iteration 17 -- +-- Iteration 16 -- array(2) { [1]=> string(0) "" [6]=> bool(true) } --- Iteration 18 -- +-- Iteration 17 -- array(3) { [""]=> - int(4) + int(2) [0]=> int(5) [1]=> diff --git a/ext/standard/tests/array/array_unique_variation3.phpt b/ext/standard/tests/array/array_unique_variation3.phpt index 91b551bb6040..3c1b0f2e35ff 100644 --- a/ext/standard/tests/array/array_unique_variation3.phpt +++ b/ext/standard/tests/array/array_unique_variation3.phpt @@ -9,10 +9,6 @@ Test array_unique() function : usage variations - associative array with differe echo "*** Testing array_unique() : assoc. array with diff. keys passed to \$input argument ***\n"; -// get an unset variable -$unset_var = 10; -unset ($unset_var); - // get a class class classA { @@ -38,7 +34,7 @@ $inputs = array ( array("hello", $heredoc => "string", "string"), // array with object, unset variable and resource variable -/*8*/ array(@$unset_var => "hello", STDERR => 'resource', 11, "hello"), +/*8*/ array(STDERR => 'resource', 11, "hello"), ); // loop through each sub-array of $inputs to check the behavior of array_unique() @@ -96,11 +92,11 @@ array(2) { } -- Iteration 6 -- array(3) { - [""]=> - string(5) "hello" [3]=> string(8) "resource" [4]=> int(11) + [5]=> + string(5) "hello" } Done diff --git a/ext/standard/tests/array/array_unshift_variation3.phpt b/ext/standard/tests/array/array_unshift_variation3.phpt index 75e39600e1f8..7af0690d7575 100644 --- a/ext/standard/tests/array/array_unshift_variation3.phpt +++ b/ext/standard/tests/array/array_unshift_variation3.phpt @@ -29,12 +29,11 @@ $arrays = array ( array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value array("one" => 1, 2 => "two", 4 => "four"), //mixed - // associative array, containing null/empty/boolean values as key/value -/*13*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), - array(true => "true", false => "false", "false" => false, "true" => true), + // associative array, containing empty/boolean values as key/value +/*13*/ array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys /*18*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -386,33 +385,6 @@ array(6) { string(4) "four" } -- Iteration 13 -- -int(4) -array(4) { - [0]=> - int(10) - [""]=> - string(4) "null" - ["NULL"]=> - NULL - ["null"]=> - NULL -} -int(6) -array(6) { - [0]=> - int(10) - [1]=> - string(5) "hello" - [2]=> - string(5) "world" - [""]=> - string(4) "null" - ["NULL"]=> - NULL - ["null"]=> - NULL -} --- Iteration 14 -- int(5) array(5) { [0]=> @@ -443,7 +415,7 @@ array(7) { ["true"]=> bool(true) } --- Iteration 15 -- +-- Iteration 14 -- int(4) array(4) { [0]=> @@ -470,9 +442,9 @@ array(6) { ["emptys"]=> string(0) "" } --- Iteration 16 -- -int(7) -array(7) { +-- Iteration 15 -- +int(5) +array(5) { [0]=> int(10) [1]=> @@ -480,16 +452,12 @@ array(7) { [2]=> string(0) "" [3]=> - NULL - [4]=> - NULL - [5]=> bool(false) - [6]=> + [4]=> bool(true) } -int(9) -array(9) { +int(7) +array(7) { [0]=> int(10) [1]=> @@ -501,21 +469,17 @@ array(9) { [4]=> string(0) "" [5]=> - NULL - [6]=> - NULL - [7]=> bool(false) - [8]=> + [6]=> bool(true) } --- Iteration 17 -- +-- Iteration 16 -- int(4) array(4) { [0]=> int(10) [""]=> - int(4) + int(2) [1]=> int(5) [2]=> @@ -530,13 +494,13 @@ array(6) { [2]=> string(5) "world" [""]=> - int(4) + int(2) [3]=> int(5) [4]=> int(6) } --- Iteration 18 -- +-- Iteration 17 -- int(4) array(4) { [0]=> diff --git a/ext/standard/tests/array/array_unshift_variation4.phpt b/ext/standard/tests/array/array_unshift_variation4.phpt index ed89e0631177..2af08f15717e 100644 --- a/ext/standard/tests/array/array_unshift_variation4.phpt +++ b/ext/standard/tests/array/array_unshift_variation4.phpt @@ -10,10 +10,6 @@ Test array_unshift() function : usage variations - assoc. array with diff. keys echo "*** Testing array_unshift() : associative array with different keys ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - //get a resource variable $fp = fopen(__FILE__, "r"); @@ -52,12 +48,12 @@ $arrays = array ( array("hello", $heredoc => "string"), // heredoc // array with object, unset variable and resource variable - array(@$unset_var => "hello", $fp => 'resource'), + array($fp => 'resource'), // array with mixed keys /*11*/ array('hello' => 1, "fruit" => 2.2, $fp => 'resource', 133 => "int", - @$unset_var => "unset", $heredoc => "heredoc") + $heredoc => "heredoc") ); // loop through the various elements of $arrays to test array_unshift() @@ -265,31 +261,27 @@ array(5) { string(6) "string" } -- Iteration 8 -- -int(3) -array(3) { +int(2) +array(2) { [0]=> int(10) - [""]=> - string(5) "hello" [1]=> string(8) "resource" } -int(5) -array(5) { +int(4) +array(4) { [0]=> int(10) [1]=> string(5) "hello" [2]=> string(5) "world" - [""]=> - string(5) "hello" [3]=> string(8) "resource" } -- Iteration 9 -- -int(7) -array(7) { +int(6) +array(6) { [0]=> int(10) ["hello"]=> @@ -300,13 +292,11 @@ array(7) { string(8) "resource" [2]=> string(3) "int" - [""]=> - string(5) "unset" ["Hello world"]=> string(7) "heredoc" } -int(9) -array(9) { +int(8) +array(8) { [0]=> int(10) [1]=> @@ -321,8 +311,6 @@ array(9) { string(8) "resource" [4]=> string(3) "int" - [""]=> - string(5) "unset" ["Hello world"]=> string(7) "heredoc" } diff --git a/ext/standard/tests/array/array_values_variation3.phpt b/ext/standard/tests/array/array_values_variation3.phpt index 4d09a31fb8ee..e7ee302b3d15 100644 --- a/ext/standard/tests/array/array_values_variation3.phpt +++ b/ext/standard/tests/array/array_values_variation3.phpt @@ -9,10 +9,6 @@ Test array_values() function : usage variations - array keys different data type echo "*** Testing array_values() : usage variations ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // heredoc string $heredoc = << 'negative', ), - // null data -/*4*/ 'null uppercase' => array( - NULL => 'null 1', - ), - -/*5*/ 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*6*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), -/*7*/ 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), - - // empty data -/*8*/ 'empty double quotes' => array( - "" => 'emptyd', - ), - /*9*/ 'empty single quotes' => array( '' => 'emptys', ), @@ -64,31 +41,19 @@ $inputs = array( 'strings' => 'strings', $heredoc => 'stringh', ), - - // undefined data -/*11*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*12*/ 'unset' => array( - @$unset_var => 'unset', - ), ); // loop through each element of $inputs to check the behavior of array_values() -$iterator = 1; foreach($inputs as $key => $input) { - echo "\n-- Iteration $iterator: $key data --\n"; + echo "\n-- $key data --\n"; var_dump( array_values($input) ); - $iterator++; }; echo "Done"; ?> --EXPECT-- *** Testing array_values() : usage variations *** --- Iteration 1: int data -- +-- int data -- array(4) { [0]=> string(4) "zero" @@ -100,19 +65,7 @@ array(4) { string(8) "negative" } --- Iteration 2: null uppercase data -- -array(1) { - [0]=> - string(6) "null 1" -} - --- Iteration 3: null lowercase data -- -array(1) { - [0]=> - string(6) "null 2" -} - --- Iteration 4: bool lowercase data -- +-- bool lowercase data -- array(2) { [0]=> string(6) "lowert" @@ -120,27 +73,13 @@ array(2) { string(6) "lowerf" } --- Iteration 5: bool uppercase data -- -array(2) { - [0]=> - string(6) "uppert" - [1]=> - string(6) "upperf" -} - --- Iteration 6: empty double quotes data -- -array(1) { - [0]=> - string(6) "emptyd" -} - --- Iteration 7: empty single quotes data -- +-- empty single quotes data -- array(1) { [0]=> string(6) "emptys" } --- Iteration 8: string data -- +-- string data -- array(3) { [0]=> string(7) "stringd" @@ -149,16 +88,4 @@ array(3) { [2]=> string(7) "stringh" } - --- Iteration 9: undefined data -- -array(1) { - [0]=> - string(9) "undefined" -} - --- Iteration 10: unset data -- -array(1) { - [0]=> - string(5) "unset" -} Done diff --git a/ext/standard/tests/array/bug20865.phpt b/ext/standard/tests/array/bug20865.phpt index 6dfad2bcec05..7401e98b1ab0 100644 --- a/ext/standard/tests/array/bug20865.phpt +++ b/ext/standard/tests/array/bug20865.phpt @@ -7,5 +7,8 @@ Bug #20865 (array_key_exists and NULL key) var_dump(array_key_exists(NULL, $ta)); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in %s on line %d bool(true) diff --git a/ext/standard/tests/array/bug68553.phpt b/ext/standard/tests/array/bug68553.phpt index f16c94699d5a..d309171096c9 100644 --- a/ext/standard/tests/array/bug68553.phpt +++ b/ext/standard/tests/array/bug68553.phpt @@ -37,6 +37,10 @@ try { Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d Deprecated: Implicit conversion from float 7.38 to int loses precision in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d + +Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d array(8) { [10]=> array(1) { diff --git a/ext/standard/tests/array/count_recursive.phpt b/ext/standard/tests/array/count_recursive.phpt index 27896ba2c7fa..598bbe1efef2 100644 --- a/ext/standard/tests/array/count_recursive.phpt +++ b/ext/standard/tests/array/count_recursive.phpt @@ -17,7 +17,7 @@ print "COUNT_RECURSIVE: should be 6, is ".count($arr, COUNT_RECURSIVE)."\n"; print "-- Testing various types with no second argument --\n"; print "COUNT_NORMAL: should be 2, is ".count(array("a", array("b")))."\n"; -$arr = array('a'=>array(NULL, NULL, NULL), 1=>array(NULL=>1, 1=>NULL), +$arr = array('a'=>array(NULL, NULL, NULL), 1=>array(''=>1, 1=>NULL), array(array(array(array(array(NULL)))))); print "-- Testing really cool arrays --\n"; print "COUNT_NORMAL: should be 3, is ".count($arr, COUNT_NORMAL)."\n"; @@ -27,14 +27,14 @@ echo "\n*** Testing possible variations of count() function on arrays ***"; $count_array = array( array(), array( 1 => "string"), - array( "" => "string", 0 => "a", NULL => "b", -1 => "c", + array( "" => "string", 0 => "a", -1 => "c", array(array(array(NULL)))), array( -2 => 12, array(array(1, 2, array(array("0"))))), array( "a" => 1, "b" => -2.344, "b" => "string", "c" => NULL, "d" => -2.344), array( 4 => 1, 3 => -2.344, "3" => "string", "2" => NULL, 1 => -2.344, array()), array( TRUE => TRUE, FALSE => FALSE, "" => "", " " => " ", - NULL => NULL, "\x000" => "\x000", "\000" => "\000"), + "\x000" => "\x000", "\000" => "\000"), array( NULL, 1 => "Hi", "string" => "hello", array("" => "World", "-2.34" => "a", "0" => "b")) ); diff --git a/ext/standard/tests/array/extract_negative_keys.phpt b/ext/standard/tests/array/extract_negative_keys.phpt new file mode 100644 index 000000000000..55fce2a65657 --- /dev/null +++ b/ext/standard/tests/array/extract_negative_keys.phpt @@ -0,0 +1,31 @@ +--TEST-- +extract() with negative keys +--FILE-- + 'hello', 'world', 2 => 'positive', 'check' => 'extracted']; + +function foo(array $a) { + extract($a, EXTR_PREFIX_ALL, 'prefix'); + var_dump(get_defined_vars()); +} + +foo($a); +?> +--EXPECT-- +array(3) { + ["a"]=> + array(4) { + [-5]=> + string(5) "hello" + [-4]=> + string(5) "world" + [2]=> + string(8) "positive" + ["check"]=> + string(9) "extracted" + } + ["prefix_2"]=> + string(8) "positive" + ["prefix_check"]=> + string(9) "extracted" +} diff --git a/ext/standard/tests/array/extract_negative_keys2.phpt b/ext/standard/tests/array/extract_negative_keys2.phpt new file mode 100644 index 000000000000..dd2a1fa7a18a --- /dev/null +++ b/ext/standard/tests/array/extract_negative_keys2.phpt @@ -0,0 +1,11 @@ +--TEST-- +extract() with negative keys +--FILE-- + "foo"]; +var_dump(extract($arr, EXTR_PREFIX_ALL | EXTR_REFS, "prefix")); + +?> +--EXPECT-- +int(0) diff --git a/ext/standard/tests/array/extract_variation4.phpt b/ext/standard/tests/array/extract_variation4.phpt index cdbbce225cb0..86dbdcf6419f 100644 --- a/ext/standard/tests/array/extract_variation4.phpt +++ b/ext/standard/tests/array/extract_variation4.phpt @@ -6,7 +6,7 @@ Test extract() function (variation 4) $mixed_array = array( array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL), array( 12, "name", 'age', '45' ), ); diff --git a/ext/standard/tests/array/extract_variation7.phpt b/ext/standard/tests/array/extract_variation7.phpt index 268a24773643..3cf80c3ecb1e 100644 --- a/ext/standard/tests/array/extract_variation7.phpt +++ b/ext/standard/tests/array/extract_variation7.phpt @@ -9,7 +9,7 @@ $a = array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "f var_dump ( extract($a, EXTR_PREFIX_ALL, "same")); $b = array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", - "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ); + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL); var_dump ( extract($b, EXTR_PREFIX_ALL, "same")); var_dump ( extract($b, EXTR_PREFIX_ALL, "diff")); diff --git a/ext/standard/tests/array/gh16649/array_splice_normal_destructor.phpt b/ext/standard/tests/array/gh16649/array_splice_normal_destructor.phpt new file mode 100644 index 000000000000..59c0b316f54d --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_normal_destructor.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-16649: array_splice with normal destructor should work fine +--FILE-- + +--EXPECT-- +Destructor called +array(1) { + [0]=> + string(1) "1" +} diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_add_elements.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_add_elements.phpt new file mode 100644 index 000000000000..f5e538122f41 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_add_elements.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-16649: array_splice UAF when destructor adds elements to array +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_array_deallocated.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_array_deallocated.phpt new file mode 100644 index 000000000000..1874ddad8934 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_array_deallocated.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-16649: array_splice UAF when array is released entirely +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_complex_modification.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_complex_modification.phpt new file mode 100644 index 000000000000..8ad4133300ec --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_complex_modification.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-16649: array_splice UAF with complex array modification +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_multiple_destructors.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_multiple_destructors.phpt new file mode 100644 index 000000000000..9e2c6cf8fc71 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_multiple_destructors.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-16649: array_splice UAF with multiple destructors +--FILE-- +id = $id; + } + + function __destruct() { + global $arr; + echo "Destructor {$this->id} called\n"; + if ($this->id == 2) { + $arr = null; + } + } +} + +$arr = ["start", new MultiDestructor(1), new MultiDestructor(2), "end"]; + +try { + array_splice($arr, 1, 2); + echo "ERROR: Should have thrown exception\n"; +} catch (Error $e) { + echo "Exception caught: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Destructor 1 called +Destructor 2 called +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt new file mode 100644 index 000000000000..4a82d5893157 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_original_case.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-16649: array_splice UAF with destructor modifying array (original case) +--FILE-- + "1", "3" => new C, "2" => "2"]; + +try { + array_splice($arr, 1, 2); + echo "ERROR: Should have thrown exception\n"; +} catch (Error $e) { + echo "Exception caught: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_uaf_packed_to_hash.phpt b/ext/standard/tests/array/gh16649/array_splice_uaf_packed_to_hash.phpt new file mode 100644 index 000000000000..bd8f511b6253 --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_uaf_packed_to_hash.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-16649: array_splice UAF when array is converted from packed to hash +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh16649/array_splice_with_replacement.phpt b/ext/standard/tests/array/gh16649/array_splice_with_replacement.phpt new file mode 100644 index 000000000000..8754a913a24e --- /dev/null +++ b/ext/standard/tests/array/gh16649/array_splice_with_replacement.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-16649: array_splice with replacement array when destructor modifies array +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/ext/standard/tests/array/gh19300_1.phpt b/ext/standard/tests/array/gh19300_1.phpt new file mode 100644 index 000000000000..18b639bf425b --- /dev/null +++ b/ext/standard/tests/array/gh19300_1.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-19300 (Nested array_multisort invocation with error breaks) - correct invocation variation +--FILE-- +data; + } +} + +$inputs = [ + new MyStringable('3'), + new MyStringable('1'), + new MyStringable('2'), +]; + +var_dump(array_multisort($inputs, SORT_STRING)); +var_dump($inputs); +?> +--EXPECT-- +bool(true) +array(3) { + [0]=> + object(MyStringable)#2 (1) { + ["data":"MyStringable":private]=> + string(1) "1" + } + [1]=> + object(MyStringable)#3 (1) { + ["data":"MyStringable":private]=> + string(1) "2" + } + [2]=> + object(MyStringable)#1 (1) { + ["data":"MyStringable":private]=> + string(1) "3" + } +} diff --git a/ext/standard/tests/array/gh19300_2.phpt b/ext/standard/tests/array/gh19300_2.phpt new file mode 100644 index 000000000000..41ae7e82bb79 --- /dev/null +++ b/ext/standard/tests/array/gh19300_2.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-19300 (Nested array_multisort invocation with error breaks) - error variation +--FILE-- +getMessage(), "\n"; + } +} +set_error_handler('error_handle'); + +$inputs = [ + new stdClass, + new stdClass, + new stdClass, +]; + +var_dump(array_multisort($inputs, SORT_NUMERIC)); +var_dump($inputs); +?> +--EXPECT-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +bool(true) +array(3) { + [0]=> + object(stdClass)#1 (0) { + } + [1]=> + object(stdClass)#2 (0) { + } + [2]=> + object(stdClass)#3 (0) { + } +} diff --git a/ext/standard/tests/array/gh19926.phpt b/ext/standard/tests/array/gh19926.phpt new file mode 100644 index 000000000000..b714db9eb2b3 --- /dev/null +++ b/ext/standard/tests/array/gh19926.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-19926 (Assertion failure zend_hash_internal_pointer_reset_ex) +--FILE-- + +--EXPECT-- +Exception caught, no assertion failure diff --git a/ext/standard/tests/array/gh19926_pointer.phpt b/ext/standard/tests/array/gh19926_pointer.phpt new file mode 100644 index 000000000000..c134f3b594b3 --- /dev/null +++ b/ext/standard/tests/array/gh19926_pointer.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-19926 (internal pointer behavior after array_splice) +--FILE-- + +--EXPECT-- +Before array_splice: int(3) +After array_splice: int(999) diff --git a/ext/standard/tests/array/gh20043.phpt b/ext/standard/tests/array/gh20043.phpt new file mode 100644 index 000000000000..d5c7e06417f1 --- /dev/null +++ b/ext/standard/tests/array/gh20043.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-20043 (array_unique assertion failure with RC1 array causing an exception on sort) +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Object of class stdClass could not be converted to string diff --git a/ext/standard/tests/array/in_array/in_array_variation1_bool.phpt b/ext/standard/tests/array/in_array/in_array_variation1_bool.phpt new file mode 100644 index 000000000000..9b9475dec90e --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_bool.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with booleans +--FILE-- + $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string '4' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_data.inc b/ext/standard/tests/array/in_array/in_array_variation1_data.inc new file mode 100644 index 000000000000..150b8c4d3194 --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_data.inc @@ -0,0 +1,28 @@ + 4, + "string '4'" => "4", + "float 4.00" => 4.00, + "string 'b'" => "b", + "string '5'" => "5", + "integer -2" => -2, + "float -2.0" => -2.0, + "float -2.98989" => -2.98989, + "string '-.9'" => "-.9", + "string 'True'" => "True", + "empty string" => "", + "empty array" => [], + "null" => NULL, + "string 'ab'" => "ab", + "string 'abcd'" => "abcd", + "float 0.0" => 0.0, + "integer -0" => -0, + "string with null bytes" => "abcd\x00abcd\x00abcd", + "enum Sample::A" => Sample::A, + "enum Sample::B" => Sample::B, +]; diff --git a/ext/standard/tests/array/in_array/in_array_variation1_empty.phpt b/ext/standard/tests/array/in_array/in_array_variation1_empty.phpt new file mode 100644 index 000000000000..e661dcf299b9 --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_empty.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with empty string and array +--FILE-- + $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '4' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- empty array -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- null -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_enum.phpt b/ext/standard/tests/array/in_array/in_array_variation1_enum.phpt new file mode 100644 index 000000000000..ed21aa52b26a --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_enum.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with enum values +--FILE-- + $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '4' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_mixed.phpt b/ext/standard/tests/array/in_array/in_array_variation1_mixed.phpt new file mode 100644 index 000000000000..2655484ce7ea --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_mixed.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with mixed string/int keys +--FILE-- + "A", 2 => "B", "C" => 3, 4 => 4, "one" => 1, "" => NULL, "b", "ab", "abcd"]; + +foreach ($values as $desc => $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string '4' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string '5' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string 'ab' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string 'abcd' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- float 0.0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_negative.phpt b/ext/standard/tests/array/in_array/in_array_variation1_negative.phpt new file mode 100644 index 000000000000..90c30f40f187 --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_negative.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with negative numbers/floats +--FILE-- + "neg0.005", 2 => "float2", "-.9" => -.9]; + +foreach ($values as $desc => $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '4' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- float -2.0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_nested.phpt b/ext/standard/tests/array/in_array/in_array_variation1_nested.phpt new file mode 100644 index 000000000000..bfbe0dde347d --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_nested.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with nested arrays +--FILE-- + 3], "one" => 1, "5" => 5]; + +foreach ($values as $desc => $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string '4' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_null_bytes.phpt b/ext/standard/tests/array/in_array/in_array_variation1_null_bytes.phpt new file mode 100644 index 000000000000..0b4369b241a3 --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_null_bytes.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with null byte strings +--FILE-- + $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '4' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- enum Sample::A -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_special_chars.phpt b/ext/standard/tests/array/in_array/in_array_variation1_special_chars.phpt new file mode 100644 index 000000000000..d424093c86ed --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_special_chars.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with special character strings +--FILE-- + $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '4' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array/in_array_variation1_zero.phpt b/ext/standard/tests/array/in_array/in_array_variation1_zero.phpt new file mode 100644 index 000000000000..695b417eaa99 --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_variation1_zero.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test in_array() function : usage variations - haystack with zero element +--FILE-- + $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $haystack)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $haystack, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '4' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- null -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'ab' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string with null bytes -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) +-- enum Sample::B -- +in_array() strict=false +bool(false) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array_variation2.phpt b/ext/standard/tests/array/in_array/in_array_variation2.phpt similarity index 99% rename from ext/standard/tests/array/in_array_variation2.phpt rename to ext/standard/tests/array/in_array/in_array_variation2.phpt index 3976232243c4..2b4ac3cfe3a0 100644 --- a/ext/standard/tests/array/in_array_variation2.phpt +++ b/ext/standard/tests/array/in_array/in_array_variation2.phpt @@ -14,7 +14,7 @@ $misc_array = array ( 0 =>"-.08", "e" =>"5", "y" =>NULL, - NULL =>"", + '' =>"", 0, TRUE, FALSE, diff --git a/ext/standard/tests/array/in_array_variation3.phpt b/ext/standard/tests/array/in_array/in_array_variation3.phpt similarity index 100% rename from ext/standard/tests/array/in_array_variation3.phpt rename to ext/standard/tests/array/in_array/in_array_variation3.phpt diff --git a/ext/standard/tests/array/in_array_variation4.phpt b/ext/standard/tests/array/in_array/in_array_variation4.phpt similarity index 100% rename from ext/standard/tests/array/in_array_variation4.phpt rename to ext/standard/tests/array/in_array/in_array_variation4.phpt diff --git a/ext/standard/tests/array/in_array/in_array_with_ref.phpt b/ext/standard/tests/array/in_array/in_array_with_ref.phpt new file mode 100644 index 000000000000..e2134dda5a82 --- /dev/null +++ b/ext/standard/tests/array/in_array/in_array_with_ref.phpt @@ -0,0 +1,125 @@ +--TEST-- +in_array() with references +--FILE-- + $needle) { + echo "-- $desc --\n"; + echo "in_array() strict=false\n"; + var_dump(in_array($needle, $array)); + echo "in_array() strict=true\n"; + var_dump(in_array($needle, $array, TRUE)); +} + +?> +--EXPECT-- +-- integer 4 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string '4' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float 4.00 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'b' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string '5' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- integer -2 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float -2.0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float -2.98989 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string '-.9' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'True' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- empty string -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- empty array -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- null -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- string 'ab' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string 'abcd' -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- float 0.0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- integer -0 -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- string with null bytes -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) +-- enum Sample::A -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(true) +-- enum Sample::B -- +in_array() strict=false +bool(true) +in_array() strict=true +bool(false) diff --git a/ext/standard/tests/array/in_array_variation1.phpt b/ext/standard/tests/array/in_array_variation1.phpt deleted file mode 100644 index 0c88a4533206..000000000000 --- a/ext/standard/tests/array/in_array_variation1.phpt +++ /dev/null @@ -1,635 +0,0 @@ ---TEST-- -Test in_array() function : usage variations - different needdle values ---FILE-- - "A", 2 => "B", "C" => 3, 4 => 4, "one" => 1, "" => NULL, "b", "ab", "abcd"), - array(4, array(1, 2 => 3), "one" => 1, "5" => 5 ), - array(-1, -2, -3, -4, -2.989888, "-0.005" => "neg0.005", 2 => "float2", "-.9" => -.9), - array(TRUE, FALSE), - array("", array()), - array("abcd\x00abcd\x00abcd"), - array("abcd\tabcd\nabcd\rabcd\0abcdefghij") -); - -$array_compare = array ( - 4, - "4", - 4.00, - "b", - "5", - -2, - -2.0, - -2.98989, - "-.9", - "True", - "", - array(), - NULL, - "ab", - "abcd", - 0.0, - -0, - "abcd\x00abcd\x00abcd" -); -/* loop to check if elements in $array_compare exist in $arrays - using in_array() */ -$counter = 1; -foreach($arrays as $array) { - foreach($array_compare as $compare) { - echo "-- Iteration $counter --\n"; - //strict option OFF - var_dump(in_array($compare,$array)); - //strict option ON - var_dump(in_array($compare,$array,TRUE)); - //strict option OFF - var_dump(in_array($compare,$array,FALSE)); - $counter++; - } -} - -echo "Done\n"; -?> ---EXPECT-- -*** Testing in_array() with different needle values *** --- Iteration 1 -- -bool(false) -bool(false) -bool(false) --- Iteration 2 -- -bool(false) -bool(false) -bool(false) --- Iteration 3 -- -bool(false) -bool(false) -bool(false) --- Iteration 4 -- -bool(false) -bool(false) -bool(false) --- Iteration 5 -- -bool(false) -bool(false) -bool(false) --- Iteration 6 -- -bool(false) -bool(false) -bool(false) --- Iteration 7 -- -bool(false) -bool(false) -bool(false) --- Iteration 8 -- -bool(false) -bool(false) -bool(false) --- Iteration 9 -- -bool(false) -bool(false) -bool(false) --- Iteration 10 -- -bool(false) -bool(false) -bool(false) --- Iteration 11 -- -bool(false) -bool(false) -bool(false) --- Iteration 12 -- -bool(false) -bool(false) -bool(false) --- Iteration 13 -- -bool(true) -bool(false) -bool(true) --- Iteration 14 -- -bool(false) -bool(false) -bool(false) --- Iteration 15 -- -bool(false) -bool(false) -bool(false) --- Iteration 16 -- -bool(true) -bool(false) -bool(true) --- Iteration 17 -- -bool(true) -bool(true) -bool(true) --- Iteration 18 -- -bool(false) -bool(false) -bool(false) --- Iteration 19 -- -bool(true) -bool(true) -bool(true) --- Iteration 20 -- -bool(true) -bool(false) -bool(true) --- Iteration 21 -- -bool(true) -bool(false) -bool(true) --- Iteration 22 -- -bool(true) -bool(true) -bool(true) --- Iteration 23 -- -bool(false) -bool(false) -bool(false) --- Iteration 24 -- -bool(false) -bool(false) -bool(false) --- Iteration 25 -- -bool(false) -bool(false) -bool(false) --- Iteration 26 -- -bool(false) -bool(false) -bool(false) --- Iteration 27 -- -bool(false) -bool(false) -bool(false) --- Iteration 28 -- -bool(false) -bool(false) -bool(false) --- Iteration 29 -- -bool(true) -bool(false) -bool(true) --- Iteration 30 -- -bool(true) -bool(false) -bool(true) --- Iteration 31 -- -bool(true) -bool(true) -bool(true) --- Iteration 32 -- -bool(true) -bool(true) -bool(true) --- Iteration 33 -- -bool(true) -bool(true) -bool(true) --- Iteration 34 -- -bool(true) -bool(false) -bool(true) --- Iteration 35 -- -bool(true) -bool(false) -bool(true) --- Iteration 36 -- -bool(false) -bool(false) -bool(false) --- Iteration 37 -- -bool(true) -bool(true) -bool(true) --- Iteration 38 -- -bool(true) -bool(false) -bool(true) --- Iteration 39 -- -bool(true) -bool(false) -bool(true) --- Iteration 40 -- -bool(false) -bool(false) -bool(false) --- Iteration 41 -- -bool(true) -bool(false) -bool(true) --- Iteration 42 -- -bool(false) -bool(false) -bool(false) --- Iteration 43 -- -bool(false) -bool(false) -bool(false) --- Iteration 44 -- -bool(false) -bool(false) -bool(false) --- Iteration 45 -- -bool(false) -bool(false) -bool(false) --- Iteration 46 -- -bool(false) -bool(false) -bool(false) --- Iteration 47 -- -bool(false) -bool(false) -bool(false) --- Iteration 48 -- -bool(false) -bool(false) -bool(false) --- Iteration 49 -- -bool(false) -bool(false) -bool(false) --- Iteration 50 -- -bool(false) -bool(false) -bool(false) --- Iteration 51 -- -bool(false) -bool(false) -bool(false) --- Iteration 52 -- -bool(false) -bool(false) -bool(false) --- Iteration 53 -- -bool(false) -bool(false) -bool(false) --- Iteration 54 -- -bool(false) -bool(false) -bool(false) --- Iteration 55 -- -bool(false) -bool(false) -bool(false) --- Iteration 56 -- -bool(false) -bool(false) -bool(false) --- Iteration 57 -- -bool(false) -bool(false) -bool(false) --- Iteration 58 -- -bool(false) -bool(false) -bool(false) --- Iteration 59 -- -bool(false) -bool(false) -bool(false) --- Iteration 60 -- -bool(true) -bool(true) -bool(true) --- Iteration 61 -- -bool(true) -bool(false) -bool(true) --- Iteration 62 -- -bool(false) -bool(false) -bool(false) --- Iteration 63 -- -bool(true) -bool(false) -bool(true) --- Iteration 64 -- -bool(false) -bool(false) -bool(false) --- Iteration 65 -- -bool(false) -bool(false) -bool(false) --- Iteration 66 -- -bool(false) -bool(false) -bool(false) --- Iteration 67 -- -bool(false) -bool(false) -bool(false) --- Iteration 68 -- -bool(false) -bool(false) -bool(false) --- Iteration 69 -- -bool(false) -bool(false) -bool(false) --- Iteration 70 -- -bool(false) -bool(false) -bool(false) --- Iteration 71 -- -bool(false) -bool(false) -bool(false) --- Iteration 72 -- -bool(false) -bool(false) -bool(false) --- Iteration 73 -- -bool(true) -bool(false) -bool(true) --- Iteration 74 -- -bool(true) -bool(false) -bool(true) --- Iteration 75 -- -bool(true) -bool(false) -bool(true) --- Iteration 76 -- -bool(true) -bool(false) -bool(true) --- Iteration 77 -- -bool(true) -bool(false) -bool(true) --- Iteration 78 -- -bool(true) -bool(false) -bool(true) --- Iteration 79 -- -bool(true) -bool(false) -bool(true) --- Iteration 80 -- -bool(true) -bool(false) -bool(true) --- Iteration 81 -- -bool(true) -bool(false) -bool(true) --- Iteration 82 -- -bool(true) -bool(false) -bool(true) --- Iteration 83 -- -bool(true) -bool(false) -bool(true) --- Iteration 84 -- -bool(true) -bool(false) -bool(true) --- Iteration 85 -- -bool(true) -bool(false) -bool(true) --- Iteration 86 -- -bool(true) -bool(false) -bool(true) --- Iteration 87 -- -bool(true) -bool(false) -bool(true) --- Iteration 88 -- -bool(true) -bool(false) -bool(true) --- Iteration 89 -- -bool(true) -bool(false) -bool(true) --- Iteration 90 -- -bool(true) -bool(false) -bool(true) --- Iteration 91 -- -bool(false) -bool(false) -bool(false) --- Iteration 92 -- -bool(false) -bool(false) -bool(false) --- Iteration 93 -- -bool(false) -bool(false) -bool(false) --- Iteration 94 -- -bool(false) -bool(false) -bool(false) --- Iteration 95 -- -bool(false) -bool(false) -bool(false) --- Iteration 96 -- -bool(false) -bool(false) -bool(false) --- Iteration 97 -- -bool(false) -bool(false) -bool(false) --- Iteration 98 -- -bool(false) -bool(false) -bool(false) --- Iteration 99 -- -bool(false) -bool(false) -bool(false) --- Iteration 100 -- -bool(false) -bool(false) -bool(false) --- Iteration 101 -- -bool(true) -bool(true) -bool(true) --- Iteration 102 -- -bool(true) -bool(true) -bool(true) --- Iteration 103 -- -bool(true) -bool(false) -bool(true) --- Iteration 104 -- -bool(false) -bool(false) -bool(false) --- Iteration 105 -- -bool(false) -bool(false) -bool(false) --- Iteration 106 -- -bool(false) -bool(false) -bool(false) --- Iteration 107 -- -bool(false) -bool(false) -bool(false) --- Iteration 108 -- -bool(false) -bool(false) -bool(false) --- Iteration 109 -- -bool(false) -bool(false) -bool(false) --- Iteration 110 -- -bool(false) -bool(false) -bool(false) --- Iteration 111 -- -bool(false) -bool(false) -bool(false) --- Iteration 112 -- -bool(false) -bool(false) -bool(false) --- Iteration 113 -- -bool(false) -bool(false) -bool(false) --- Iteration 114 -- -bool(false) -bool(false) -bool(false) --- Iteration 115 -- -bool(false) -bool(false) -bool(false) --- Iteration 116 -- -bool(false) -bool(false) -bool(false) --- Iteration 117 -- -bool(false) -bool(false) -bool(false) --- Iteration 118 -- -bool(false) -bool(false) -bool(false) --- Iteration 119 -- -bool(false) -bool(false) -bool(false) --- Iteration 120 -- -bool(false) -bool(false) -bool(false) --- Iteration 121 -- -bool(false) -bool(false) -bool(false) --- Iteration 122 -- -bool(false) -bool(false) -bool(false) --- Iteration 123 -- -bool(false) -bool(false) -bool(false) --- Iteration 124 -- -bool(false) -bool(false) -bool(false) --- Iteration 125 -- -bool(false) -bool(false) -bool(false) --- Iteration 126 -- -bool(true) -bool(true) -bool(true) --- Iteration 127 -- -bool(false) -bool(false) -bool(false) --- Iteration 128 -- -bool(false) -bool(false) -bool(false) --- Iteration 129 -- -bool(false) -bool(false) -bool(false) --- Iteration 130 -- -bool(false) -bool(false) -bool(false) --- Iteration 131 -- -bool(false) -bool(false) -bool(false) --- Iteration 132 -- -bool(false) -bool(false) -bool(false) --- Iteration 133 -- -bool(false) -bool(false) -bool(false) --- Iteration 134 -- -bool(false) -bool(false) -bool(false) --- Iteration 135 -- -bool(false) -bool(false) -bool(false) --- Iteration 136 -- -bool(false) -bool(false) -bool(false) --- Iteration 137 -- -bool(false) -bool(false) -bool(false) --- Iteration 138 -- -bool(false) -bool(false) -bool(false) --- Iteration 139 -- -bool(false) -bool(false) -bool(false) --- Iteration 140 -- -bool(false) -bool(false) -bool(false) --- Iteration 141 -- -bool(false) -bool(false) -bool(false) --- Iteration 142 -- -bool(false) -bool(false) -bool(false) --- Iteration 143 -- -bool(false) -bool(false) -bool(false) --- Iteration 144 -- -bool(false) -bool(false) -bool(false) -Done diff --git a/ext/standard/tests/array/in_array_with_ref.phpt b/ext/standard/tests/array/in_array_with_ref.phpt deleted file mode 100644 index 2ad3667d2326..000000000000 --- a/ext/standard/tests/array/in_array_with_ref.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -in_array() with references ---FILE-- - ---EXPECT-- -bool(true) -bool(true) diff --git a/ext/standard/tests/array/key_variation2.phpt b/ext/standard/tests/array/key_variation2.phpt index d1eed890ffc5..bb0ca07b2738 100644 --- a/ext/standard/tests/array/key_variation2.phpt +++ b/ext/standard/tests/array/key_variation2.phpt @@ -28,31 +28,12 @@ $inputs = array( -2345 => 'negative', ), - // null data -/*4*/ 'null uppercase' => array( - NULL => 'null 1', - ), - -/*5*/ 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*6*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), -/*7*/ 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), - - // empty data -/*8*/ 'empty double quotes' => array( - "" => 'emptyd', - ), - /*9*/ 'empty single quotes' => array( '' => 'emptys', ), @@ -63,16 +44,6 @@ $inputs = array( 'strings' => 'strings', $heredoc => 'stringh', ), - - // undefined data -/*11*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*12*/ 'unset' => array( - @$unset_var => 'unset', - ), ); // loop through each element of $inputs to check the behavior of key() @@ -95,33 +66,14 @@ int(1) int(12345) int(-2345) --- Iteration 2 : null uppercase data -- -string(0) "" - --- Iteration 3 : null lowercase data -- -string(0) "" - --- Iteration 4 : bool lowercase data -- -int(1) -int(0) - --- Iteration 5 : bool uppercase data -- +-- Iteration 2 : bool lowercase data -- int(1) int(0) --- Iteration 6 : empty double quotes data -- +-- Iteration 3 : empty single quotes data -- string(0) "" --- Iteration 7 : empty single quotes data -- -string(0) "" - --- Iteration 8 : string data -- +-- Iteration 4 : string data -- string(7) "stringd" string(7) "strings" string(11) "hello world" - --- Iteration 9 : undefined data -- -string(0) "" - --- Iteration 10 : unset data -- -string(0) "" diff --git a/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt b/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt index 03ed069fd893..cbfd2e914413 100644 --- a/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt +++ b/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt @@ -16,9 +16,16 @@ var_dump($f3); $fs = [$f1, $f2, $f3, 5.5]; +function safe_to_string(int|float $number): string { + if (is_nan($number)) { + return 'NAN'; + } + return $number; +} + foreach ($fs as $s) { foreach ($fs as $e) { - echo "range($s, $e);\n"; + echo 'range(', safe_to_string($s), ', ', safe_to_string($e), ");\n"; try { var_dump( range($s, $e) ); } catch (\ValueError $e) { diff --git a/ext/standard/tests/array/rcn_in_place.phpt b/ext/standard/tests/array/rcn_in_place.phpt new file mode 100644 index 000000000000..e6a7b5b6d695 --- /dev/null +++ b/ext/standard/tests/array/rcn_in_place.phpt @@ -0,0 +1,57 @@ +--TEST-- +RCN check for in-place array modifications +--FILE-- + 0)); +var_dump(array_intersect(range(0, 1), [])); +var_dump(array_uintersect(range(0, 1), [], fn () => 0)); +var_dump(array_intersect_uassoc(range(0, 1), [], fn () => 0)); +var_dump(array_uintersect_uassoc(range(0, 1), [], fn () => 0, fn () => 0)); +?> +--EXPECT-- +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} diff --git a/ext/standard/tests/array/sort/arsort_variation11.phpt b/ext/standard/tests/array/sort/arsort_variation11.phpt index b5405ac3d55e..af72a4599f58 100644 --- a/ext/standard/tests/array/sort/arsort_variation11.phpt +++ b/ext/standard/tests/array/sort/arsort_variation11.phpt @@ -17,7 +17,7 @@ $mixed_values = array ( "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() ), 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, - -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 ); diff --git a/ext/standard/tests/array/sort/arsort_variation_escape_sequences.phpt b/ext/standard/tests/array/sort/arsort_variation_escape_sequences.phpt index b4a533c42114..db60f7c93f5a 100644 --- a/ext/standard/tests/array/sort/arsort_variation_escape_sequences.phpt +++ b/ext/standard/tests/array/sort/arsort_variation_escape_sequences.phpt @@ -14,11 +14,9 @@ const EXPECTED_RESULT = [ "\v" => "\v", "\n" => "\n", "\t" => "\t", - null => null, ]; $array = [ - null => null, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", diff --git a/ext/standard/tests/array/sort/asort_variation11.phpt b/ext/standard/tests/array/sort/asort_variation11.phpt index 82eab55993ac..e9f3a438e5f1 100644 --- a/ext/standard/tests/array/sort/asort_variation11.phpt +++ b/ext/standard/tests/array/sort/asort_variation11.phpt @@ -17,7 +17,7 @@ $mixed_values = array ( "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() ), 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, - -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 ); diff --git a/ext/standard/tests/array/sort/asort_variation_escape_sequences.phpt b/ext/standard/tests/array/sort/asort_variation_escape_sequences.phpt index 6de02b66ae0a..1a33fd197c0f 100644 --- a/ext/standard/tests/array/sort/asort_variation_escape_sequences.phpt +++ b/ext/standard/tests/array/sort/asort_variation_escape_sequences.phpt @@ -4,7 +4,6 @@ Test asort() function: sorting escape sequences null, "\t" => "\t", "\n" => "\n", "\v" => "\v", @@ -18,7 +17,6 @@ const EXPECTED_RESULT = [ ]; $array = [ - null => null, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", diff --git a/ext/standard/tests/array/sort/krsort_variation8.phpt b/ext/standard/tests/array/sort/krsort_variation8.phpt index 4c1c6f2173d2..9379cf4ec4ff 100644 --- a/ext/standard/tests/array/sort/krsort_variation8.phpt +++ b/ext/standard/tests/array/sort/krsort_variation8.phpt @@ -18,7 +18,7 @@ $mixed_values = array ( "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() ), 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, - -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 ); diff --git a/ext/standard/tests/array/sort/krsort_variation_escape_sequences.phpt b/ext/standard/tests/array/sort/krsort_variation_escape_sequences.phpt index ac56df76ed7c..371980293a0e 100644 --- a/ext/standard/tests/array/sort/krsort_variation_escape_sequences.phpt +++ b/ext/standard/tests/array/sort/krsort_variation_escape_sequences.phpt @@ -14,11 +14,9 @@ const EXPECTED_RESULT = [ "\v" => "\v", "\n" => "\n", "\t" => "\t", - null => null, ]; $array = [ - null => null, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", diff --git a/ext/standard/tests/array/sort/ksort_variation8.phpt b/ext/standard/tests/array/sort/ksort_variation8.phpt index 236c405c64b9..e04abcfbc473 100644 --- a/ext/standard/tests/array/sort/ksort_variation8.phpt +++ b/ext/standard/tests/array/sort/ksort_variation8.phpt @@ -17,7 +17,7 @@ $mixed_values = array ( "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() ), 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, - -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 ); diff --git a/ext/standard/tests/array/sort/ksort_variation_escape_sequences.phpt b/ext/standard/tests/array/sort/ksort_variation_escape_sequences.phpt index e880227b1c9e..acbcde58defe 100644 --- a/ext/standard/tests/array/sort/ksort_variation_escape_sequences.phpt +++ b/ext/standard/tests/array/sort/ksort_variation_escape_sequences.phpt @@ -4,7 +4,6 @@ Test ksort() function: sorting escape sequences null, "\t" => "\t", "\n" => "\n", "\v" => "\v", @@ -18,7 +17,6 @@ const EXPECTED_RESULT = [ ]; $array = [ - null => null, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", diff --git a/ext/standard/tests/array/sort/natcasesort_variation11.phpt b/ext/standard/tests/array/sort/natcasesort_variation11.phpt index 5934b5230c51..bc86669a5452 100644 --- a/ext/standard/tests/array/sort/natcasesort_variation11.phpt +++ b/ext/standard/tests/array/sort/natcasesort_variation11.phpt @@ -8,10 +8,6 @@ Test natcasesort() function : usage variations - Different array keys echo "*** Testing natcasesort() : usage variations ***\n"; -//get an unset variable -$unset_var = 10; -unset ($unset_var); - // heredoc string $heredoc = << 'negative', ), - // null data -/*4*/ 'null uppercase' => array( - NULL => 'null 1', - ), - -/*5*/ 'null lowercase' => array( - null => 'null 2', - ), - // boolean data /*6*/ 'bool lowercase' => array( true => 'lowert', false => 'lowerf', ), -/*7*/ 'bool uppercase' => array( - TRUE => 'uppert', - FALSE => 'upperf', - ), - - // empty data -/*8*/ 'empty double quotes' => array( - "" => 'emptyd', - ), - /*9*/ 'empty single quotes' => array( '' => 'emptys', ), @@ -64,16 +41,6 @@ $inputs = array( $heredoc => 'stringh', ), - // undefined data -/*11*/ 'undefined' => array( - @$undefined_var => 'undefined', - ), - - // unset data -/*12*/ 'unset' => array( - @$unset_var => 'unset', - ), - // duplicate values /*13*/ 'duplicate' => array( 'foo' => 'bar', @@ -112,20 +79,6 @@ array(4) { -- Iteration 2 -- bool(true) -array(1) { - [""]=> - string(6) "null 1" -} - --- Iteration 3 -- -bool(true) -array(1) { - [""]=> - string(6) "null 2" -} - --- Iteration 4 -- -bool(true) array(2) { [0]=> string(6) "lowerf" @@ -133,30 +86,14 @@ array(2) { string(6) "lowert" } --- Iteration 5 -- -bool(true) -array(2) { - [0]=> - string(6) "upperf" - [1]=> - string(6) "uppert" -} - --- Iteration 6 -- -bool(true) -array(1) { - [""]=> - string(6) "emptyd" -} - --- Iteration 7 -- +-- Iteration 3 -- bool(true) array(1) { [""]=> string(6) "emptys" } --- Iteration 8 -- +-- Iteration 4 -- bool(true) array(3) { ["stringd"]=> @@ -167,21 +104,7 @@ array(3) { string(7) "strings" } --- Iteration 9 -- -bool(true) -array(1) { - [""]=> - string(9) "undefined" -} - --- Iteration 10 -- -bool(true) -array(1) { - [""]=> - string(5) "unset" -} - --- Iteration 11 -- +-- Iteration 5 -- bool(true) array(3) { ["foo"]=> diff --git a/ext/standard/tests/array/sort/shuffle_variation4.phpt b/ext/standard/tests/array/sort/shuffle_variation4.phpt index 1d3269e76e93..e2736379624c 100644 --- a/ext/standard/tests/array/sort/shuffle_variation4.phpt +++ b/ext/standard/tests/array/sort/shuffle_variation4.phpt @@ -33,7 +33,7 @@ $array_arg = array( /*7*/ array("hex1" => 0x123, 'hex2' => 0xabc, "hex\t3" => 0xABC, "hex\04" => 0xAb1), // array with negative hexa values - array(NULL => -0x123, "NULL" => -0xabc, "-ABC" => -0xABC, -0xAB1 => -0xAb1), + array('' => -0x123, "NULL" => -0xabc, "-ABC" => -0xABC, -0xAB1 => -0xAb1), // array with positive octal values /*9*/ array(0123 => 0123, "0234" => 0234, '034' => 034, 00 => 00), @@ -41,9 +41,6 @@ $array_arg = array( // array with negative octal values array(-0123 => -0123, "-0234" => -0234, '-034' => -034), - // array with null values -/*11*/ array(NULL => NULL, "null" => NULL, "NULL" => NULL) - ); // looping to test shuffle() with each sub-array in the $array_arg array @@ -209,17 +206,4 @@ array(3) { [2]=> int(-%d) } - --- Iteration 11 -- -bool(true) - -The output array is: -array(3) { - [0]=> - NULL - [1]=> - NULL - [2]=> - NULL -} Done diff --git a/ext/standard/tests/array/sort/uasort_variation3.phpt b/ext/standard/tests/array/sort/uasort_variation3.phpt index 1b690e4dfd03..75e6e3993fbc 100644 --- a/ext/standard/tests/array/sort/uasort_variation3.phpt +++ b/ext/standard/tests/array/sort/uasort_variation3.phpt @@ -51,19 +51,12 @@ $array_arg = array( // string keys 'key' => 5, //single quoted key "two" => 4, //double quoted key - '' => 3, - "" => 2, + '' => 35, " " => 0, // space as key // bool keys - true => 15, - false => 5, - TRUE => 100, - FALSE => 25, - - // null keys - null => 20, // expecting: value will be replaced by 'NULL' - NULL => 35, + true => 100, + false => 25, // binary key "a".chr(0)."b" => 45, diff --git a/ext/standard/tests/array/sort/usort_variation3.phpt b/ext/standard/tests/array/sort/usort_variation3.phpt index 5478ca09abe2..7987fe3eecda 100644 --- a/ext/standard/tests/array/sort/usort_variation3.phpt +++ b/ext/standard/tests/array/sort/usort_variation3.phpt @@ -45,14 +45,12 @@ $array_arg = array( 'key' => 5, //single quoted key "two" => 4, //double quoted key " " => 0, // space as key + '' => 35, // bool keys TRUE => 100, FALSE => 25, - // null keys - NULL => 35, - // binary key "a".chr(0)."b" => 45, b"binary" => 30, diff --git a/ext/standard/tests/assert/assert.phpt b/ext/standard/tests/assert/assert.phpt index 4649e9a59be9..a275b9949cbe 100644 --- a/ext/standard/tests/assert/assert.phpt +++ b/ext/standard/tests/assert/assert.phpt @@ -41,25 +41,25 @@ Deprecated: PHP Startup: assert.active INI setting is deprecated in Unknown on l Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assertion failed 21,"assert($a != 0)" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d class assertion failed 24,"assert($a != 0)" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d class assertion failed 28,"assert($a != 0)" diff --git a/ext/standard/tests/assert/assert03.phpt b/ext/standard/tests/assert/assert03.phpt index 2a62665893a8..968af8306503 100644 --- a/ext/standard/tests/assert/assert03.phpt +++ b/ext/standard/tests/assert/assert03.phpt @@ -36,15 +36,15 @@ Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assertion failed - a - 18,"assert($a != 0)" diff --git a/ext/standard/tests/assert/assert04.phpt b/ext/standard/tests/assert/assert04.phpt index 9935d4c6a123..744633c197be 100644 --- a/ext/standard/tests/assert/assert04.phpt +++ b/ext/standard/tests/assert/assert04.phpt @@ -29,17 +29,17 @@ echo "not reached\n"; --EXPECTF-- Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Warning: assert(): assert(0) failed in %s on line %d -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d diff --git a/ext/standard/tests/assert/assert_basic2.phpt b/ext/standard/tests/assert/assert_basic2.phpt index fdd1c53b93dd..6bca82a91f53 100644 --- a/ext/standard/tests/assert/assert_basic2.phpt +++ b/ext/standard/tests/assert/assert_basic2.phpt @@ -30,7 +30,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f1" @@ -38,12 +38,12 @@ f1 called Warning: assert(): assert(0) failed in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f1" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f2" diff --git a/ext/standard/tests/assert/assert_basic3.phpt b/ext/standard/tests/assert/assert_basic3.phpt index 0849f16e6f20..4e281ef50424 100644 --- a/ext/standard/tests/assert/assert_basic3.phpt +++ b/ext/standard/tests/assert/assert_basic3.phpt @@ -23,7 +23,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(0) diff --git a/ext/standard/tests/assert/assert_basic4.phpt b/ext/standard/tests/assert/assert_basic4.phpt index 76ade8d00f40..cc9ec6432886 100644 --- a/ext/standard/tests/assert/assert_basic4.phpt +++ b/ext/standard/tests/assert/assert_basic4.phpt @@ -28,22 +28,22 @@ Deprecated: PHP Startup: assert.warning INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_ACTIVE is deprecated in %s on line %d +Deprecated: Constant ASSERT_ACTIVE is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_ACTIVE) => [0] -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_WARNING) => [0] -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_BAIL) => [0] -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_CALLBACK) => [f1] diff --git a/ext/standard/tests/assert/assert_basic5.phpt b/ext/standard/tests/assert/assert_basic5.phpt index 6ba70d94cdf3..66858eed5cb8 100644 --- a/ext/standard/tests/assert/assert_basic5.phpt +++ b/ext/standard/tests/assert/assert_basic5.phpt @@ -28,7 +28,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(0) @@ -38,7 +38,7 @@ Warning: assert(): assert(0 != 0) failed in %s on line %d bool(false) bool(true) -Deprecated: Constant ASSERT_WARNING is deprecated in %s on line %d +Deprecated: Constant ASSERT_WARNING is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(1) diff --git a/ext/standard/tests/assert/assert_basic6.phpt b/ext/standard/tests/assert/assert_basic6.phpt index 4e95fdb01dc4..b531425912c2 100644 --- a/ext/standard/tests/assert/assert_basic6.phpt +++ b/ext/standard/tests/assert/assert_basic6.phpt @@ -32,11 +32,11 @@ try { ?> --EXPECTF-- -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f1" @@ -44,11 +44,11 @@ foo assert(false) -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d NULL diff --git a/ext/standard/tests/assert/assert_closures.phpt b/ext/standard/tests/assert/assert_closures.phpt index aa7246ee21be..ecce04986023 100644 --- a/ext/standard/tests/assert/assert_closures.phpt +++ b/ext/standard/tests/assert/assert_closures.phpt @@ -13,7 +13,7 @@ assert(0); --EXPECTF-- Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Hello World! diff --git a/ext/standard/tests/assert/assert_closures_multiple.phpt b/ext/standard/tests/assert/assert_closures_multiple.phpt index 078674015557..8f0cb9551ab9 100644 --- a/ext/standard/tests/assert/assert_closures_multiple.phpt +++ b/ext/standard/tests/assert/assert_closures_multiple.phpt @@ -32,7 +32,7 @@ try { ?> DONE --EXPECTF-- -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d DONE diff --git a/ext/standard/tests/assert/assert_error2.phpt b/ext/standard/tests/assert/assert_error2.phpt index eaa62523845d..6cfa5a6ce444 100644 --- a/ext/standard/tests/assert/assert_error2.phpt +++ b/ext/standard/tests/assert/assert_error2.phpt @@ -25,7 +25,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_BAIL is deprecated in %s on line %d +Deprecated: Constant ASSERT_BAIL is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d int(0) diff --git a/ext/standard/tests/assert/assert_variation.phpt b/ext/standard/tests/assert/assert_variation.phpt index 494f6cd57938..6824f7246d5b 100644 --- a/ext/standard/tests/assert/assert_variation.phpt +++ b/ext/standard/tests/assert/assert_variation.phpt @@ -85,7 +85,7 @@ Deprecated: PHP Startup: assert.callback INI setting is deprecated in Unknown on Deprecated: PHP Startup: assert.exception INI setting is deprecated in Unknown on line 0 -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d Initial values: assert_options(ASSERT_CALLBACK) => [f1] @@ -98,7 +98,7 @@ Change callback function using ini.set and test return value Deprecated: ini_set(): assert.callback INI setting is deprecated in %s on line %d string(2) "f1" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assert_options(ASSERT_CALLBACK) => [f2] @@ -108,12 +108,12 @@ bool(false) Change callback function using assert_options and test return value -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f2" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assert_options(ASSERT_CALLBACK) => [f3] @@ -123,12 +123,12 @@ bool(false) Reset the name of the callback routine to a class method -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "f3" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d assert_options(ASSERT_CALLBACK) => [c1] @@ -137,12 +137,12 @@ Invalid callback c1, function "c1" not found or invalid function name Reset callback options to use a class method -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(2) "c1" -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d array(2) { @@ -158,7 +158,7 @@ bool(false) Reset callback options to use an object method -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d array(2) { @@ -168,7 +168,7 @@ array(2) { string(6) "assert" } -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d array(2) { @@ -185,11 +185,11 @@ bool(false) Set callback to something silly -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d float(3.141) diff --git a/ext/standard/tests/assert/bug80290.phpt b/ext/standard/tests/assert/bug80290.phpt index 8b737f33043f..112dbde1a4e4 100644 --- a/ext/standard/tests/assert/bug80290.phpt +++ b/ext/standard/tests/assert/bug80290.phpt @@ -12,7 +12,7 @@ assert(false, 'Dynamic message: ' . $x); ?> --EXPECTF-- -Deprecated: Constant ASSERT_CALLBACK is deprecated in %s on line %d +Deprecated: Constant ASSERT_CALLBACK is deprecated since 8.3, as assert_options() is deprecated in %s on line %d Deprecated: Function assert_options() is deprecated since 8.3 in %s on line %d string(18) "Dynamic message: x" diff --git a/ext/standard/tests/class_object/get_object_vars_variation_005.phpt b/ext/standard/tests/class_object/get_object_vars_variation_005.phpt index 1ad1bb393329..2fed6468c530 100644 --- a/ext/standard/tests/class_object/get_object_vars_variation_005.phpt +++ b/ext/standard/tests/class_object/get_object_vars_variation_005.phpt @@ -25,6 +25,7 @@ var_dump(get_object_vars($obj)); ?> --EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(3) { ["%0A%0b"]=> int(42) @@ -33,6 +34,8 @@ array(3) { [12]=> int(6) } + +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d array(4) { ["prop"]=> NULL diff --git a/ext/standard/tests/dir/bug73877.phpt b/ext/standard/tests/dir/bug73877.phpt index ceb272ea6527..e538bed0d890 100644 --- a/ext/standard/tests/dir/bug73877.phpt +++ b/ext/standard/tests/dir/bug73877.phpt @@ -18,7 +18,7 @@ $junk0 = $base . DIRECTORY_SEPARATOR . "Серёжка2"; mkdir($base); mkdir($dir0); mkdir($dir1); -`mklink /J $junk0 $dir0`; +shell_exec("mklink /J $junk0 $dir0"); var_dump( readlink($dir0), diff --git a/ext/standard/tests/dir/closedir_basic-win32-mb.phpt b/ext/standard/tests/dir/closedir_basic-win32-mb.phpt index 05cb1889c948..3754963a8500 100644 --- a/ext/standard/tests/dir/closedir_basic-win32-mb.phpt +++ b/ext/standard/tests/dir/closedir_basic-win32-mb.phpt @@ -44,6 +44,8 @@ rmdir($dir_path); *** Testing closedir() : basic functionality *** -- Call closedir() with no arguments: -- + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL -- Check Directory Handle: -- resource(%d) of type (Unknown) diff --git a/ext/standard/tests/dir/closedir_basic.phpt b/ext/standard/tests/dir/closedir_basic.phpt index aa4be6fbaf27..82065f01419a 100644 --- a/ext/standard/tests/dir/closedir_basic.phpt +++ b/ext/standard/tests/dir/closedir_basic.phpt @@ -38,6 +38,8 @@ rmdir($dir_path); *** Testing closedir() : basic functionality *** -- Call closedir() with no arguments: -- + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL -- Check Directory Handle: -- resource(%d) of type (Unknown) diff --git a/ext/standard/tests/dir/closedir_without_arg.phpt b/ext/standard/tests/dir/closedir_without_arg.phpt index 27884c1a2b64..f248764ed2a6 100644 --- a/ext/standard/tests/dir/closedir_without_arg.phpt +++ b/ext/standard/tests/dir/closedir_without_arg.phpt @@ -8,5 +8,6 @@ try { echo $e->getMessage(), "\n"; } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d No resource supplied diff --git a/ext/standard/tests/dir/readdir_basic-win32-mb.phpt b/ext/standard/tests/dir/readdir_basic-win32-mb.phpt index d7e0804d57b3..dd97566db079 100644 --- a/ext/standard/tests/dir/readdir_basic-win32-mb.phpt +++ b/ext/standard/tests/dir/readdir_basic-win32-mb.phpt @@ -65,6 +65,18 @@ string(9) "file3.tmp" -- Call readdir() without $path argument -- resource(%d) of type (stream) + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(9) "file1.tmp" diff --git a/ext/standard/tests/dir/readdir_basic.phpt b/ext/standard/tests/dir/readdir_basic.phpt index 01ddd694adcb..fbabfc6e9b2b 100644 --- a/ext/standard/tests/dir/readdir_basic.phpt +++ b/ext/standard/tests/dir/readdir_basic.phpt @@ -59,6 +59,18 @@ string(9) "file3.tmp" -- Call readdir() without $path argument -- resource(%d) of type (stream) + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(9) "file1.tmp" diff --git a/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt b/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt index 91062e76bd4f..c2bfe7d1a2b4 100644 --- a/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt +++ b/ext/standard/tests/dir/readdir_variation6-win32-mb.phpt @@ -61,7 +61,7 @@ closedir(); $dir_path = __DIR__ . "/私はガラスを食べられますreaddir_variation6"; rmdir($dir_path); ?> ---EXPECT-- +--EXPECTF-- *** Testing readdir() : usage variations *** -- Reading Directory Contents with Previous Handle -- @@ -72,8 +72,22 @@ string(59) "私はガラスを食べられますreaddir_variation62.tmp" string(59) "私はガラスを食べられますreaddir_variation63.tmp" -- Reading Directory Contents with Current Handle (no arguments supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(59) "私はガラスを食べられますreaddir_variation61.tmp" string(59) "私はガラスを食べられますreaddir_variation62.tmp" string(59) "私はガラスを食べられますreaddir_variation63.tmp" + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d diff --git a/ext/standard/tests/dir/readdir_variation6.phpt b/ext/standard/tests/dir/readdir_variation6.phpt index b017789f31ac..9865a1d4fc60 100644 --- a/ext/standard/tests/dir/readdir_variation6.phpt +++ b/ext/standard/tests/dir/readdir_variation6.phpt @@ -55,7 +55,7 @@ closedir(); $dir_path = __DIR__ . "/readdir_variation6"; rmdir($dir_path); ?> ---EXPECT-- +--EXPECTF-- *** Testing readdir() : usage variations *** -- Reading Directory Contents with Previous Handle -- @@ -66,8 +66,22 @@ string(23) "readdir_variation62.tmp" string(23) "readdir_variation63.tmp" -- Reading Directory Contents with Current Handle (no arguments supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d string(1) "." string(2) ".." string(23) "readdir_variation61.tmp" string(23) "readdir_variation62.tmp" string(23) "readdir_variation63.tmp" + +Deprecated: closedir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d diff --git a/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt b/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt index a20501d3cade..2ec56418c85b 100644 --- a/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt +++ b/ext/standard/tests/dir/rewinddir_basic-win32-mb.phpt @@ -82,6 +82,14 @@ NULL bool(true) -- Read and rewind second directory (no argument supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d array(3) { [0]=> string(1) "." @@ -90,5 +98,9 @@ array(3) { [2]=> string(45) "私はガラスを食べられますfile2.tmp" } + +Deprecated: rewinddir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d bool(true) diff --git a/ext/standard/tests/dir/rewinddir_basic.phpt b/ext/standard/tests/dir/rewinddir_basic.phpt index faee6b9bd64a..106c00051d6e 100644 --- a/ext/standard/tests/dir/rewinddir_basic.phpt +++ b/ext/standard/tests/dir/rewinddir_basic.phpt @@ -76,6 +76,14 @@ NULL bool(true) -- Read and rewind second directory (no argument supplied) -- + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d array(3) { [0]=> string(1) "." @@ -84,5 +92,9 @@ array(3) { [2]=> string(9) "file2.tmp" } + +Deprecated: rewinddir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d NULL + +Deprecated: readdir(): Passing null is deprecated, instead the last opened directory stream should be provided in %s on line %d bool(true) diff --git a/ext/standard/tests/dir/scandir_invalid_flag.phpt b/ext/standard/tests/dir/scandir_invalid_flag.phpt new file mode 100644 index 000000000000..76838dc869b8 --- /dev/null +++ b/ext/standard/tests/dir/scandir_invalid_flag.phpt @@ -0,0 +1,12 @@ +--TEST-- +Provide wrong flags to scandir() +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +scandir(): Argument #2 ($sorting_order) must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants diff --git a/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt b/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt deleted file mode 100644 index 44d8b6daa5f9..000000000000 --- a/ext/standard/tests/dir/scandir_variation9-win32-mb.phpt +++ /dev/null @@ -1,71 +0,0 @@ ---TEST-- -Test scandir() function : usage variations - different ints as $sorting_order arg ---SKIPIF-- - ---FILE-- - ---CLEAN-- - ---EXPECT-- -*** Testing scandir() : usage variations *** -array(4) { - [0]=> - string(45) "私はガラスを食べられますfile2.tmp" - [1]=> - string(45) "私はガラスを食べられますfile1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(45) "私はガラスを食べられますfile2.tmp" - [1]=> - string(45) "私はガラスを食べられますfile1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(1) "." - [1]=> - string(2) ".." - [2]=> - string(45) "私はガラスを食べられますfile1.tmp" - [3]=> - string(45) "私はガラスを食べられますfile2.tmp" -} diff --git a/ext/standard/tests/dir/scandir_variation9.phpt b/ext/standard/tests/dir/scandir_variation9.phpt deleted file mode 100644 index 56e5575e5590..000000000000 --- a/ext/standard/tests/dir/scandir_variation9.phpt +++ /dev/null @@ -1,65 +0,0 @@ ---TEST-- -Test scandir() function : usage variations - different ints as $sorting_order arg ---FILE-- - ---CLEAN-- - ---EXPECT-- -*** Testing scandir() : usage variations *** -array(4) { - [0]=> - string(9) "file2.tmp" - [1]=> - string(9) "file1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(9) "file2.tmp" - [1]=> - string(9) "file1.tmp" - [2]=> - string(2) ".." - [3]=> - string(1) "." -} -array(4) { - [0]=> - string(1) "." - [1]=> - string(2) ".." - [2]=> - string(9) "file1.tmp" - [3]=> - string(9) "file2.tmp" -} diff --git a/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt b/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt index 91416f2c7120..5af789ff424a 100644 --- a/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt +++ b/ext/standard/tests/directory/DirectoryClass_readonly_handle_by_pass_via_ArrayObject.phpt @@ -28,7 +28,8 @@ try { } ?> ---EXPECT-- +--EXPECTF-- +Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d resource(3) of type (stream) Error: Internal directory stream has been altered Error: Typed property Directory::$handle must not be accessed before initialization diff --git a/ext/standard/tests/file/005_variation2.phpt b/ext/standard/tests/file/005_variation2.phpt index 270a6cfbdd84..42b0fd1904d7 100644 --- a/ext/standard/tests/file/005_variation2.phpt +++ b/ext/standard/tests/file/005_variation2.phpt @@ -52,6 +52,7 @@ stat_fn('|'); var_dump(unlink(' ')); var_dump(unlink('|')); +chdir(__DIR__); // Solaris cannot remove CWD rmdir($dir); echo "Done"; diff --git a/ext/standard/tests/file/007_variation1.phpt b/ext/standard/tests/file/007_variation1.phpt index 09960a08f6d7..11fef2967f71 100644 --- a/ext/standard/tests/file/007_variation1.phpt +++ b/ext/standard/tests/file/007_variation1.phpt @@ -39,7 +39,7 @@ string(20) "line line of text li" -Notice: fwrite(): Write of 37 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 37 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) bool(true) string(7) "Unknown" diff --git a/ext/standard/tests/file/007_variation11.phpt b/ext/standard/tests/file/007_variation11.phpt index 202837e12120..2672f3e661d2 100644 --- a/ext/standard/tests/file/007_variation11.phpt +++ b/ext/standard/tests/file/007_variation11.phpt @@ -57,7 +57,7 @@ int(0) int(37) int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation13.phpt b/ext/standard/tests/file/007_variation13.phpt index 0d28522e7b7f..1bc80e7578af 100644 --- a/ext/standard/tests/file/007_variation13.phpt +++ b/ext/standard/tests/file/007_variation13.phpt @@ -47,7 +47,7 @@ resource(%d) of type (stream) string(6) "stream" int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation15.phpt b/ext/standard/tests/file/007_variation15.phpt index 0b1efdcfb5fb..54e89d95f373 100644 --- a/ext/standard/tests/file/007_variation15.phpt +++ b/ext/standard/tests/file/007_variation15.phpt @@ -49,7 +49,7 @@ int(0) int(37) int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation17.phpt b/ext/standard/tests/file/007_variation17.phpt index 466f39eec1ee..884ce2c855ae 100644 --- a/ext/standard/tests/file/007_variation17.phpt +++ b/ext/standard/tests/file/007_variation17.phpt @@ -39,7 +39,7 @@ string(20) "line line of text li" -Notice: fwrite(): Write of 37 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 37 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) bool(true) string(7) "Unknown" diff --git a/ext/standard/tests/file/007_variation19.phpt b/ext/standard/tests/file/007_variation19.phpt index d40f188bbc42..7740ea3059c1 100644 --- a/ext/standard/tests/file/007_variation19.phpt +++ b/ext/standard/tests/file/007_variation19.phpt @@ -52,7 +52,7 @@ int(0) int(37) int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation21.phpt b/ext/standard/tests/file/007_variation21.phpt index 4506df61ff8c..eb6b780dec79 100644 --- a/ext/standard/tests/file/007_variation21.phpt +++ b/ext/standard/tests/file/007_variation21.phpt @@ -42,7 +42,7 @@ resource(%d) of type (stream) string(6) "stream" int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation23.phpt b/ext/standard/tests/file/007_variation23.phpt index 3d2fd40b3753..f080596a2cd0 100644 --- a/ext/standard/tests/file/007_variation23.phpt +++ b/ext/standard/tests/file/007_variation23.phpt @@ -40,7 +40,7 @@ int(0) int(37) int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation3.phpt b/ext/standard/tests/file/007_variation3.phpt index 5b8ac4c7ae08..8bd0ac454fda 100644 --- a/ext/standard/tests/file/007_variation3.phpt +++ b/ext/standard/tests/file/007_variation3.phpt @@ -52,7 +52,7 @@ int(0) int(37) int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation5.phpt b/ext/standard/tests/file/007_variation5.phpt index ce2243719fcd..86e009ee2113 100644 --- a/ext/standard/tests/file/007_variation5.phpt +++ b/ext/standard/tests/file/007_variation5.phpt @@ -42,7 +42,7 @@ resource(%d) of type (stream) string(6) "stream" int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation7.phpt b/ext/standard/tests/file/007_variation7.phpt index 154454736e3a..e25c1dd90830 100644 --- a/ext/standard/tests/file/007_variation7.phpt +++ b/ext/standard/tests/file/007_variation7.phpt @@ -40,7 +40,7 @@ int(0) int(37) int(37) -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(true) diff --git a/ext/standard/tests/file/007_variation9.phpt b/ext/standard/tests/file/007_variation9.phpt index 1cc1670df661..ec9b8c963081 100644 --- a/ext/standard/tests/file/007_variation9.phpt +++ b/ext/standard/tests/file/007_variation9.phpt @@ -39,7 +39,7 @@ string(20) "line line of text li" -Notice: fwrite(): Write of 37 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 37 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) bool(true) string(7) "Unknown" diff --git a/ext/standard/tests/file/bug35781.phpt b/ext/standard/tests/file/bug35781.phpt index c07900e9d708..5b65b7d6b7a6 100644 --- a/ext/standard/tests/file/bug35781.phpt +++ b/ext/standard/tests/file/bug35781.phpt @@ -19,7 +19,7 @@ var_dump(file_get_contents($filename)); echo "Done\n"; ?> --EXPECTF-- -Notice: fpassthru(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fpassthru(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d string(15) "Guvf vf n grfg " Done diff --git a/ext/standard/tests/file/bug46347.phpt b/ext/standard/tests/file/bug46347.phpt index 903a6e35cc2b..e337ade9eb8f 100644 --- a/ext/standard/tests/file/bug46347.phpt +++ b/ext/standard/tests/file/bug46347.phpt @@ -8,14 +8,14 @@ $str = <<< EOF part1.*.part2 = 1 EOF; -$file = __DIR__ . '/parse.ini'; +$file = __DIR__ . '/bug46347.ini'; file_put_contents($file, $str); var_dump(parse_ini_file($file)); ?> --CLEAN-- --EXPECT-- array(1) { diff --git a/ext/standard/tests/file/bug52820.phpt b/ext/standard/tests/file/bug52820.phpt index 2d3cedad8794..1157d8cb2db3 100644 --- a/ext/standard/tests/file/bug52820.phpt +++ b/ext/standard/tests/file/bug52820.phpt @@ -45,22 +45,18 @@ echo "\nDone.\n"; --EXPECTREGEX-- temp stream \(close after\): About to rewind! -(\* processing: file:\/\/\/i_dont_exist\/\n)?\* Couldn't open file \/i_dont_exist\/ -\* [Cc]losing connection( #?-?\d+)? +(\* processing: file:\/\/\/i_dont_exist\/\n)?\* (Couldn't|Could not) open file \/i_dont_exist\/(\n\* [Cc]losing connection( #?-?\d+)?)? memory stream \(close after\): About to rewind! -(\* processing: file:\/\/\/i_dont_exist\/\n)?\* Couldn't open file \/i_dont_exist\/ -\* [Cc]losing connection( #?-?\d+)? +(\* processing: file:\/\/\/i_dont_exist\/\n)?\* (Couldn't|Could not) open file \/i_dont_exist\/(\n\* [Cc]losing connection( #?-?\d+)?)? temp stream \(leak\): About to rewind! -(\* processing: file:\/\/\/i_dont_exist\/\n)?\* Couldn't open file \/i_dont_exist\/ -\* [Cc]losing connection( #?-?\d+)? +(\* processing: file:\/\/\/i_dont_exist\/\n)?\* (Couldn't|Could not) open file \/i_dont_exist\/(\n\* [Cc]losing connection( #?-?\d+)?)? memory stream \(leak\): About to rewind! -(\* processing: file:\/\/\/i_dont_exist\/\n)?\* Couldn't open file \/i_dont_exist\/ -\* [Cc]losing connection( #?-?\d+)? +(\* processing: file:\/\/\/i_dont_exist\/\n)?\* (Couldn't|Could not) open file \/i_dont_exist\/(\n\* [Cc]losing connection( #?-?\d+)?)? Done\. diff --git a/ext/standard/tests/file/bug65272.phpt b/ext/standard/tests/file/bug65272.phpt index 24e50d15bee3..0419a7023d69 100644 --- a/ext/standard/tests/file/bug65272.phpt +++ b/ext/standard/tests/file/bug65272.phpt @@ -1,5 +1,11 @@ --TEST-- Bug #65272: flock() correctly sets wouldblock out param in windows +--SKIPIF-- + --FILE-- +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(1000) diff --git a/ext/standard/tests/file/bug81145.phpt b/ext/standard/tests/file/bug81145.phpt index f3258ff6019e..27026176193f 100644 --- a/ext/standard/tests/file/bug81145.phpt +++ b/ext/standard/tests/file/bug81145.phpt @@ -9,8 +9,8 @@ if (PHP_OS_FAMILY !== "Windows") { $src = __DIR__ . "/bug81145_src.bin"; define('SIZE_4G', 0x100000000); exec("fallocate -l " . (SIZE_4G-0x100) . " " . escapeshellarg($src), $output, $status); - if ($status !== 0) die("skip fallocate() not supported"); @unlink(__DIR__ . "/bug81145_src.bin"); + if ($status !== 0) die("skip fallocate() not supported"); } ?> --CONFLICTS-- diff --git a/ext/standard/tests/file/chmod_variation2.phpt b/ext/standard/tests/file/chmod_variation2.phpt index e96af25ec469..c2b6c2e810a3 100644 --- a/ext/standard/tests/file/chmod_variation2.phpt +++ b/ext/standard/tests/file/chmod_variation2.phpt @@ -34,7 +34,7 @@ clearstatcache(); printf("%o\n", fileperms($filepath) & PERMISSIONS_MASK); echo "\nchmod() on a linked file\n"; -$linkname = "somelink"; +$linkname = "somelink2"; var_dump(symlink($filepath, $linkname)); var_dump(chmod($filepath, 0777)); var_dump(chmod($linkname, 0755)); diff --git a/ext/standard/tests/file/fdatasync.phpt b/ext/standard/tests/file/fdatasync.phpt index 235669a9943f..e1fa47583452 100644 --- a/ext/standard/tests/file/fdatasync.phpt +++ b/ext/standard/tests/file/fdatasync.phpt @@ -34,7 +34,12 @@ fclose($file_handle); echo "\n*** Testing fdatasync(): attempting to sync stdin ***\n"; $file_handle = fopen("php://stdin", "w"); -var_dump(fdatasync($file_handle)); +// On Solaris, fdatasync() on stdin returns true +if (PHP_OS_FAMILY === 'Solaris') { + var_dump(!fdatasync($file_handle)); +} else { + var_dump(fdatasync($file_handle)); +} fclose($file_handle); echo "\n*** Testing fdatasync(): for non-file stream ***\n"; diff --git a/ext/standard/tests/file/fgetc_variation3.phpt b/ext/standard/tests/file/fgetc_variation3.phpt index ba47e303f78b..0f9b69bd302c 100644 --- a/ext/standard/tests/file/fgetc_variation3.phpt +++ b/ext/standard/tests/file/fgetc_variation3.phpt @@ -55,7 +55,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -64,7 +64,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -73,7 +73,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -82,7 +82,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -91,7 +91,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -100,7 +100,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -109,7 +109,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -118,7 +118,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -127,7 +127,7 @@ bool(true) int(0) bool(false) -Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgetc(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) diff --git a/ext/standard/tests/file/fgets_variation1.phpt b/ext/standard/tests/file/fgets_variation1.phpt index 0c07c7a76cab..f0ff2fd7d589 100644 --- a/ext/standard/tests/file/fgets_variation1.phpt +++ b/ext/standard/tests/file/fgets_variation1.phpt @@ -51,7 +51,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -60,7 +60,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -69,7 +69,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -78,7 +78,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -87,7 +87,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -96,7 +96,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -105,7 +105,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -114,7 +114,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) @@ -123,7 +123,7 @@ bool(true) int(0) bool(false) -Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fgets(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) diff --git a/ext/standard/tests/file/file_binary_text_deprecated.phpt b/ext/standard/tests/file/file_binary_text_deprecated.phpt index cbc57809c617..b6967c596710 100644 --- a/ext/standard/tests/file/file_binary_text_deprecated.phpt +++ b/ext/standard/tests/file/file_binary_text_deprecated.phpt @@ -8,8 +8,8 @@ var_dump(FILE_TEXT); ?> --EXPECTF-- -Deprecated: Constant FILE_BINARY is deprecated in %s on line %d +Deprecated: Constant FILE_BINARY is deprecated since 8.1, as the constant has no effect in %s on line %d int(0) -Deprecated: Constant FILE_TEXT is deprecated in %s on line %d +Deprecated: Constant FILE_TEXT is deprecated since 8.1, as the constant has no effect in %s on line %d int(0) diff --git a/ext/standard/tests/file/file_get_contents_file_put_contents_5gb.phpt b/ext/standard/tests/file/file_get_contents_file_put_contents_5gb.phpt index 854996a6481e..dd16e885f6e1 100644 --- a/ext/standard/tests/file/file_get_contents_file_put_contents_5gb.phpt +++ b/ext/standard/tests/file/file_get_contents_file_put_contents_5gb.phpt @@ -2,6 +2,7 @@ Test file_put_contents() and file_get_contents() functions with 5GB string --SKIPIF-- [ + "uri_parser_class" => "not-exists", + ], + ]); + var_dump(file_get_contents("http://example.com", context: $context)); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +$context = stream_context_create([ + "http" => [ + "uri_parser_class" => null, + ], +]); +var_dump(file_get_contents("http:///example.com", context: $context)); // invalid for parse_url only, valid for the other handlers + +$context = stream_context_create([ + "http" => [ + "uri_parser_class" => \Uri\Rfc3986\Uri::class, + ], +]); +var_dump(file_get_contents("http://éxamplé.com", context: $context)); // invalid for RFC 3986 only, valid for the other handlers + +$context = stream_context_create([ + "http" => [ + "uri_parser_class" => \Uri\WhatWg\Url::class, + ], +]); +var_dump(file_get_contents("http://exa%23mple.org", context: $context)); // invalid for WHATWG only, valid for the other handlers + +?> +--EXPECTF-- +file_get_contents(): Provided stream context has invalid value for the "uri_parser_class" option + +Warning: file_get_contents(http:///example.com): Failed to open stream: operation failed in %s on line %d +bool(false) + +Warning: file_get_contents(http://éxamplé.com): Failed to open stream: operation failed in %s on line %d +bool(false) + +Warning: file_get_contents(http://exa%23mple.org): Failed to open stream: operation failed in %s on line %d +bool(false) diff --git a/ext/standard/tests/file/file_variation5.phpt b/ext/standard/tests/file/file_variation5.phpt index d1c5e1498beb..3db848cdbbfb 100644 --- a/ext/standard/tests/file/file_variation5.phpt +++ b/ext/standard/tests/file/file_variation5.phpt @@ -27,7 +27,7 @@ echo "\nfile() on a path containing .. with invalid directories\n"; var_dump(file("./$test_dirname/bad_dir/../../$filename")); echo "\nfile() on a linked file\n"; -$linkname = "somelink"; +$linkname = "somelink5"; var_dump(symlink($filepath, $linkname)); var_dump(file($linkname)); var_dump(unlink($linkname)); diff --git a/ext/standard/tests/file/filetype_variation2.phpt b/ext/standard/tests/file/filetype_variation2.phpt index 8ea1e16b22c8..ca33417332ba 100644 --- a/ext/standard/tests/file/filetype_variation2.phpt +++ b/ext/standard/tests/file/filetype_variation2.phpt @@ -13,8 +13,14 @@ if (!file_exists("/dev/null")) { ?> --FILE-- --EXPECT-- -- Checking for char -- diff --git a/ext/standard/tests/file/flock.phpt b/ext/standard/tests/file/flock.phpt index a3c180458402..0e07114f9cd4 100644 --- a/ext/standard/tests/file/flock.phpt +++ b/ext/standard/tests/file/flock.phpt @@ -14,7 +14,13 @@ try { echo $e->getMessage(), "\n"; } -$fp = fopen($file, "w"); +/* + On Solaris, flock() is emulated via fcntl(). A shared lock (LOCK_SH) maps to + F_RDLCK, which requires the file descriptor to be open for reading. Using "w" + opens write-only and causes EBADF on Solaris. Open with "w+" so LOCK_SH works + portably across platforms. +*/ +$fp = fopen($file, "w+"); var_dump(flock($fp, LOCK_SH|LOCK_NB)); var_dump(flock($fp, LOCK_UN)); diff --git a/ext/standard/tests/file/flock_basic.phpt b/ext/standard/tests/file/flock_basic.phpt index 8b4ae30e0fd4..4fd4ea1e931f 100644 --- a/ext/standard/tests/file/flock_basic.phpt +++ b/ext/standard/tests/file/flock_basic.phpt @@ -11,7 +11,13 @@ echo "*** Testing flock() fun with file and dir ***\n"; $lock_file = preg_replace("~\.phpt?$~", '', __FILE__); -$file_handle = fopen($lock_file, "w"); +/* + On Solaris, flock() is emulated via fcntl(). A shared lock (LOCK_SH) maps to + F_RDLCK, which requires the file descriptor to be open for reading. Using "w" + opens write-only and causes EBADF on Solaris. Open with "w+" so LOCK_SH works + portably across platforms. +*/ +$file_handle = fopen($lock_file, "w+"); var_dump(flock($file_handle, LOCK_SH|LOCK_NB)); var_dump(flock($file_handle, LOCK_UN)); var_dump(flock($file_handle, LOCK_EX)); diff --git a/ext/standard/tests/file/flock_variation.phpt b/ext/standard/tests/file/flock_variation.phpt index 1d73e90d254d..1b17635db1cb 100644 --- a/ext/standard/tests/file/flock_variation.phpt +++ b/ext/standard/tests/file/flock_variation.phpt @@ -6,7 +6,13 @@ echo "*** Testing flock() fun with the various operation and wouldblock values ***\n"; $file = preg_replace("~\.phpt?$~", '', __FILE__); -$fp = fopen($file, "w"); +/* + On Solaris, flock() is emulated via fcntl(). A shared lock (LOCK_SH) maps to + F_RDLCK, which requires the file descriptor to be open for reading. Using "w" + opens write-only and causes EBADF on Solaris. Open with "w+" so LOCK_SH works + portably across platforms. +*/ +$fp = fopen($file, "w+"); /* array of operations */ $operations = array( diff --git a/ext/standard/tests/file/fread_socket_variation1.phpt b/ext/standard/tests/file/fread_socket_variation1.phpt index 09b3d65393ab..62d4b33ba486 100644 --- a/ext/standard/tests/file/fread_socket_variation1.phpt +++ b/ext/standard/tests/file/fread_socket_variation1.phpt @@ -12,7 +12,7 @@ for ($i=0; $i<100; $i++) { } } -socket_set_timeout($server, 0, 1000); +stream_set_timeout($server, 0, 1000); var_dump(fread($server, 1)); diff --git a/ext/standard/tests/file/fread_variation2.phpt b/ext/standard/tests/file/fread_variation2.phpt index a16c97a745ae..1fee493c4b69 100644 --- a/ext/standard/tests/file/fread_variation2.phpt +++ b/ext/standard/tests/file/fread_variation2.phpt @@ -104,7 +104,7 @@ echo "Done\n"; int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -113,7 +113,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -123,7 +123,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -132,7 +132,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -142,7 +142,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -151,7 +151,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -161,7 +161,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -170,7 +170,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -180,7 +180,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -189,7 +189,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -199,7 +199,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -208,7 +208,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -218,7 +218,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -227,7 +227,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -237,7 +237,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -246,7 +246,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -256,7 +256,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -265,7 +265,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -277,7 +277,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -286,7 +286,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -296,7 +296,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -305,7 +305,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -315,7 +315,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -324,7 +324,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -334,7 +334,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -343,7 +343,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -353,7 +353,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -362,7 +362,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -372,7 +372,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -381,7 +381,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -391,7 +391,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -400,7 +400,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -410,7 +410,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -419,7 +419,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -429,7 +429,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -438,7 +438,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -450,7 +450,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -459,7 +459,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -469,7 +469,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -478,7 +478,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -488,7 +488,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -497,7 +497,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -507,7 +507,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -516,7 +516,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -526,7 +526,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -535,7 +535,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -545,7 +545,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -554,7 +554,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -564,7 +564,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -573,7 +573,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -583,7 +583,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -592,7 +592,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -602,7 +602,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -611,7 +611,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -623,7 +623,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -632,7 +632,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -642,7 +642,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -651,7 +651,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -661,7 +661,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -670,7 +670,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -680,7 +680,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -689,7 +689,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -699,7 +699,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -708,7 +708,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -718,7 +718,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -727,7 +727,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -737,7 +737,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -746,7 +746,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -756,7 +756,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -765,7 +765,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -775,7 +775,7 @@ bool(false) int(0) bool(false) Reading 1024 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -784,7 +784,7 @@ bool(false) int(0) bool(false) Reading 1000 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) diff --git a/ext/standard/tests/file/fread_variation4.phpt b/ext/standard/tests/file/fread_variation4.phpt index 97c6c39f9c8c..1ed43464f88f 100644 --- a/ext/standard/tests/file/fread_variation4.phpt +++ b/ext/standard/tests/file/fread_variation4.phpt @@ -102,7 +102,7 @@ echo"Done\n"; int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -110,7 +110,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -119,7 +119,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -127,7 +127,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -136,7 +136,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -144,7 +144,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -153,7 +153,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -161,7 +161,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -170,7 +170,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -178,7 +178,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -187,7 +187,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -195,7 +195,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -204,7 +204,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -212,7 +212,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -221,7 +221,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -229,7 +229,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -238,7 +238,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -246,7 +246,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -257,7 +257,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -265,7 +265,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -274,7 +274,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -282,7 +282,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -291,7 +291,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -299,7 +299,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -308,7 +308,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -316,7 +316,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -325,7 +325,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -333,7 +333,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -342,7 +342,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -350,7 +350,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -359,7 +359,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -367,7 +367,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -376,7 +376,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -384,7 +384,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -393,7 +393,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -401,7 +401,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -412,7 +412,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -420,7 +420,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -429,7 +429,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -437,7 +437,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -446,7 +446,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -454,7 +454,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -463,7 +463,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -471,7 +471,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -480,7 +480,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -488,7 +488,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -497,7 +497,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -505,7 +505,7 @@ bool(false) int(%r1024|1137%r) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(%r1024|1137%r) bool(false) @@ -514,7 +514,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -522,7 +522,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -531,7 +531,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -539,7 +539,7 @@ bool(false) int(1024) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(1024) bool(false) @@ -548,7 +548,7 @@ bool(false) int(0) bool(false) Reading 1030 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(0) bool(false) @@ -556,7 +556,7 @@ bool(false) int(%r1024|1137%r) bool(false) Reading 10 bytes from file, expecting 0 bytes ... -Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d OK int(%r1024|1137%r) bool(false) diff --git a/ext/standard/tests/file/fscanf_variation51.phpt b/ext/standard/tests/file/fscanf_variation51.phpt index fad613274828..97e56c1bab8d 100644 --- a/ext/standard/tests/file/fscanf_variation51.phpt +++ b/ext/standard/tests/file/fscanf_variation51.phpt @@ -65,209 +65,209 @@ if(file_exists($filename)) { -- iteration 1 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 2 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 3 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 4 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 5 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 6 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 7 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 8 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -- iteration 9 -- -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) -Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fscanf(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) *** Done *** diff --git a/ext/standard/tests/file/fsync.phpt b/ext/standard/tests/file/fsync.phpt index 7a036a55d4d0..dfa7404caa57 100644 --- a/ext/standard/tests/file/fsync.phpt +++ b/ext/standard/tests/file/fsync.phpt @@ -34,7 +34,12 @@ fclose($file_handle); echo "\n*** Testing fsync(): attempting to sync stdin ***\n"; $file_handle = fopen("php://stdin", "w"); -var_dump(fsync($file_handle)); +// On Solaris, fsync() on stdin returns success +if (PHP_OS_FAMILY === 'Solaris') { + var_dump(!fsync($file_handle)); +} else { + var_dump(fsync($file_handle)); +} fclose($file_handle); echo "\n*** Testing fsync(): for non-file stream ***\n"; diff --git a/ext/standard/tests/file/fwrite.phpt b/ext/standard/tests/file/fwrite.phpt index 12bfb6727ec3..e29c6a3507de 100644 --- a/ext/standard/tests/file/fwrite.phpt +++ b/ext/standard/tests/file/fwrite.phpt @@ -29,7 +29,7 @@ $filename = __DIR__."/fwrite.dat"; --EXPECTF-- int(0) -Notice: fwrite(): Write of 4 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 4 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) int(4) diff --git a/ext/standard/tests/file/fwrite_variation1.phpt b/ext/standard/tests/file/fwrite_variation1.phpt index 34a1c89c6939..3660cffae8fe 100644 --- a/ext/standard/tests/file/fwrite_variation1.phpt +++ b/ext/standard/tests/file/fwrite_variation1.phpt @@ -68,13 +68,13 @@ echo "Done\n"; -- Opening file in r -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -84,13 +84,13 @@ string(32) "950b7457d1deb6332f2fc5d42f3129d6" -- Opening file in rb -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -100,13 +100,13 @@ string(32) "950b7457d1deb6332f2fc5d42f3129d6" -- Opening file in rt -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -118,13 +118,13 @@ string(32) "950b7457d1deb6332f2fc5d42f3129d6" -- Opening file in r -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -134,13 +134,13 @@ string(32) "e486000c4c8452774f746a27658d87fa" -- Opening file in rb -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -150,13 +150,13 @@ string(32) "e486000c4c8452774f746a27658d87fa" -- Opening file in rt -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -168,13 +168,13 @@ string(32) "e486000c4c8452774f746a27658d87fa" -- Opening file in r -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -184,13 +184,13 @@ string(32) "b09c8026a64a88d36d4c2f17983964bb" -- Opening file in rb -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -200,13 +200,13 @@ string(32) "b09c8026a64a88d36d4c2f17983964bb" -- Opening file in rt -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -218,13 +218,13 @@ string(32) "b09c8026a64a88d36d4c2f17983964bb" -- Opening file in r -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -234,13 +234,13 @@ string(32) "3fabd48d8eaa65c14e0d93d6880c560c" -- Opening file in rb -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) @@ -250,13 +250,13 @@ string(32) "3fabd48d8eaa65c14e0d93d6880c560c" -- Opening file in rt -- int(0) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(0) bool(false) int(2) -Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: fwrite(): Write of 1024 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d bool(false) int(2) bool(false) diff --git a/ext/standard/tests/file/gh13204.phpt b/ext/standard/tests/file/gh13204.phpt new file mode 100644 index 000000000000..1af66539195a --- /dev/null +++ b/ext/standard/tests/file/gh13204.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-13204 (glob() fails if square bracket is in current directory) +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(11) "./empty.txt" +} diff --git a/ext/standard/tests/file/gh13204[brackets]/empty.txt b/ext/standard/tests/file/gh13204[brackets]/empty.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/ext/standard/tests/file/lstat_stat_variation18.phpt b/ext/standard/tests/file/lstat_stat_variation18.phpt index e3c8386e70f1..9291de269396 100644 --- a/ext/standard/tests/file/lstat_stat_variation18.phpt +++ b/ext/standard/tests/file/lstat_stat_variation18.phpt @@ -62,7 +62,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> @@ -118,7 +118,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> diff --git a/ext/standard/tests/file/lstat_stat_variation19.phpt b/ext/standard/tests/file/lstat_stat_variation19.phpt index 18ad03e52d29..24af43599efa 100644 --- a/ext/standard/tests/file/lstat_stat_variation19.phpt +++ b/ext/standard/tests/file/lstat_stat_variation19.phpt @@ -63,7 +63,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> @@ -117,7 +117,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> @@ -173,7 +173,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> @@ -227,7 +227,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> diff --git a/ext/standard/tests/file/lstat_stat_variation20.phpt b/ext/standard/tests/file/lstat_stat_variation20.phpt index 5bff0456eba5..cfff4571ae16 100644 --- a/ext/standard/tests/file/lstat_stat_variation20.phpt +++ b/ext/standard/tests/file/lstat_stat_variation20.phpt @@ -72,7 +72,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> @@ -128,7 +128,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> @@ -182,7 +182,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> @@ -236,7 +236,7 @@ array(26) { [5]=> int(%d) [6]=> - int(%d) + int(%i) [7]=> int(%d) [8]=> diff --git a/ext/standard/tests/file/mkdir-002.phpt b/ext/standard/tests/file/mkdir-002.phpt index f4a42a7d6198..d48b19e645ba 100644 --- a/ext/standard/tests/file/mkdir-002.phpt +++ b/ext/standard/tests/file/mkdir-002.phpt @@ -11,13 +11,13 @@ if (substr(PHP_OS, 0, 3) == 'WIN') { var_dump(mkdir("mkdir-002", 0777)); var_dump(mkdir("mkdir-002/subdir", 0777)); -var_dump(`ls -l mkdir-002`); +var_dump(shell_exec("ls -l mkdir-002")); var_dump(rmdir("mkdir-002/subdir")); var_dump(rmdir("mkdir-002")); var_dump(mkdir("./mkdir-002", 0777)); var_dump(mkdir("./mkdir-002/subdir", 0777)); -var_dump(`ls -l ./mkdir-002`); +var_dump(shell_exec("ls -l ./mkdir-002")); var_dump(rmdir("./mkdir-002/subdir")); var_dump(rmdir("./mkdir-002")); @@ -25,7 +25,7 @@ var_dump(mkdir(__DIR__."/mkdir-002", 0777)); var_dump(mkdir(__DIR__."/mkdir-002/subdir", 0777)); $dirname = __DIR__."/mkdir-002"; $dirname_escaped = escapeshellarg($dirname); -var_dump(`ls -l $dirname_escaped`); +var_dump(shell_exec("ls -l $dirname_escaped")); var_dump(rmdir(__DIR__."/mkdir-002/subdir")); var_dump(rmdir(__DIR__."/mkdir-002")); diff --git a/ext/standard/tests/file/open_basedir_cwd_resolve.phpt b/ext/standard/tests/file/open_basedir_cwd_resolve.phpt index 753e21d997dd..9c95e4904fa0 100644 --- a/ext/standard/tests/file/open_basedir_cwd_resolve.phpt +++ b/ext/standard/tests/file/open_basedir_cwd_resolve.phpt @@ -11,5 +11,5 @@ var_dump(file_get_contents('/some/path/outside/open/basedir')); --EXPECTF-- Warning: file_get_contents(): open_basedir restriction in effect. File(/some/path/outside/open/basedir) is not within the allowed path(s): (%s) in %s on line %d -Warning: file_get_contents(/some/path/outside/open/basedir): Failed to open stream: Operation not permitted in %s on line %d +Warning: file_get_contents(/some/path/outside/open/basedir): Failed to open stream: %r(Operation not permitted|Insufficient privileges)%r in %s on line %d bool(false) diff --git a/ext/standard/tests/file/parse_ini_file_variation3.phpt b/ext/standard/tests/file/parse_ini_file_variation3.phpt index 29e620dc8da3..8485e8d01ef0 100644 --- a/ext/standard/tests/file/parse_ini_file_variation3.phpt +++ b/ext/standard/tests/file/parse_ini_file_variation3.phpt @@ -35,7 +35,6 @@ display_startup_errors = Off log_errors = Off ignore_repeated_errors = Off ignore_repeated_source = Off -report_memleaks = On docref_root = "/phpmanual/" docref_ext = .html @@ -68,7 +67,7 @@ foreach($newdirs as $newdir) { --EXPECTF-- *** Testing parse_ini_file() : variation *** New include path is : %sparse_ini_file_variation3.dir1%sparse_ini_file_variation3.dir2%sparse_ini_file_variation3.dir3%S -array(9) { +array(8) { ["error_reporting"]=> string(5) "30719" ["display_errors"]=> @@ -81,8 +80,6 @@ array(9) { string(0) "" ["ignore_repeated_source"]=> string(0) "" - ["report_memleaks"]=> - string(1) "1" ["docref_root"]=> string(11) "/phpmanual/" ["docref_ext"]=> diff --git a/ext/standard/tests/file/pathinfo_variation3.phpt b/ext/standard/tests/file/pathinfo_variation3.phpt index aa1494b57997..86f88677d813 100644 --- a/ext/standard/tests/file/pathinfo_variation3.phpt +++ b/ext/standard/tests/file/pathinfo_variation3.phpt @@ -15,15 +15,37 @@ var_dump(pathinfo($testfile, PATHINFO_BASENAME)); var_dump(pathinfo($testfile, PATHINFO_FILENAME)); var_dump(pathinfo($testfile, PATHINFO_EXTENSION)); var_dump(pathinfo($testfile, PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME)); -var_dump(pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_EXTENSION)); -var_dump(pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_BASENAME)); +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_FILENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_EXTENSION|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_FILENAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_EXTENSION); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo($testfile, PATHINFO_DIRNAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} ?> --EXPECTF-- @@ -62,11 +84,9 @@ string(6) "inet.h" string(4) "inet" string(1) "h" string(17) "/usr/include/arpa" -string(17) "/usr/include/arpa" -string(6) "inet.h" -string(1) "h" -string(6) "inet.h" -string(17) "/usr/include/arpa" -string(6) "inet.h" -string(17) "/usr/include/arpa" -string(17) "/usr/include/arpa" +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants diff --git a/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt b/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt index 7bb4c1be02c7..b0a28055893a 100644 --- a/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt +++ b/ext/standard/tests/file/popen_pclose_basic-win32-mb.phpt @@ -35,8 +35,8 @@ $sysroot = exec('echo %SYSTEMROOT%'); $file_handle = popen("$sysroot/system32/sort", "w"); $newline = "\n"; foreach($arr as $str) { - fwrite($file_handle, (binary)$str); - fwrite($file_handle, (binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)$newline); + fwrite($file_handle, $str); + fwrite($file_handle, $newline); } pclose($file_handle); diff --git a/ext/standard/tests/file/popen_pclose_basic-win32.phpt b/ext/standard/tests/file/popen_pclose_basic-win32.phpt index 61f2fa302bf9..e5f155be3299 100644 --- a/ext/standard/tests/file/popen_pclose_basic-win32.phpt +++ b/ext/standard/tests/file/popen_pclose_basic-win32.phpt @@ -35,8 +35,8 @@ $sysroot = exec('echo %SYSTEMROOT%'); $file_handle = popen("$sysroot/system32/sort", "w"); $newline = "\n"; foreach($arr as $str) { - fwrite($file_handle, (binary)$str); - fwrite($file_handle, (binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)(binary)$newline); + fwrite($file_handle, $str); + fwrite($file_handle, $newline); } pclose($file_handle); diff --git a/ext/standard/tests/file/popen_pclose_error-sunos.phpt b/ext/standard/tests/file/popen_pclose_error-sunos.phpt deleted file mode 100644 index 981f1d5a6e6a..000000000000 --- a/ext/standard/tests/file/popen_pclose_error-sunos.phpt +++ /dev/null @@ -1,48 +0,0 @@ ---TEST-- -Test popen() and pclose function: error conditions ---SKIPIF-- - ---FILE-- - ---CLEAN-- - ---EXPECTF-- -*** Testing for error conditions *** - -Warning: Wrong parameter count for popen() in %s on line %d -NULL - -Warning: Wrong parameter count for popen() in %s on line %d -NULL -sh: abc.txt: not found -resource(%d) of type (stream) - -Warning: Wrong parameter count for pclose() in %s on line %d -NULL - -Warning: Wrong parameter count for pclose() in %s on line %d -NULL - -Warning: pclose(): supplied argument is not a valid stream resource in %s on line %d -bool(false) - ---- Done --- diff --git a/ext/standard/tests/file/realpath_bug77484.phpt b/ext/standard/tests/file/realpath_bug77484.phpt index 9aa3a335c2a9..0b78a2aad26f 100644 --- a/ext/standard/tests/file/realpath_bug77484.phpt +++ b/ext/standard/tests/file/realpath_bug77484.phpt @@ -2,8 +2,8 @@ Bug #77484 Zend engine crashes when calling realpath in invalid working dir --SKIPIF-- getMessage() . "\n"; +} echo "Done\n"; ?> @@ -53,10 +56,5 @@ Warning: symlink(): %s in %s on line %d bool(false) *** Testing linkinfo() for error conditions *** - -Warning: linkinfo(): %s in %s on line %d -int(-1) - -Warning: linkinfo(): %s in %s on line %d -int(-1) +linkinfo(): Argument #1 ($path) must not be empty Done diff --git a/ext/standard/tests/file/userstreams_005.phpt b/ext/standard/tests/file/userstreams_005.phpt index 8d37040e1950..11dc8d45b0cd 100644 --- a/ext/standard/tests/file/userstreams_005.phpt +++ b/ext/standard/tests/file/userstreams_005.phpt @@ -65,5 +65,5 @@ ftruncate(): Argument #2 ($size) must be greater than or equal to 0 ------ stream_truncate bad return: ------- truncation with new_size=0 -Warning: ftruncate(): test_wrapper_bad::stream_truncate did not return a boolean! in %s on line %d +Warning: ftruncate(): test_wrapper_bad::stream_truncate value must be of type bool, string given in %s on line %d bool(false) diff --git a/ext/standard/tests/file/windows_mb_path/bug54028.phpt b/ext/standard/tests/file/windows_mb_path/bug54028.phpt index 61913a1a7218..3603bced34d8 100644 --- a/ext/standard/tests/file/windows_mb_path/bug54028.phpt +++ b/ext/standard/tests/file/windows_mb_path/bug54028.phpt @@ -4,12 +4,8 @@ Bug #54028 Directory::read() cannot handle non-unicode chars properly mbstring --SKIPIF-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- ---EXPECTF-- +--EXPECT-- Active code page: 65001 filetype()[dir ] == is_dir()[dir ] -> OK: . filetype()[dir ] == is_dir()[dir ] -> OK: .. @@ -58,4 +55,3 @@ filetype()[dir ] == is_dir()[dir ] -> OK: ソ filetype()[dir ] == is_dir()[dir ] -> OK: ゾ filetype()[dir ] == is_dir()[dir ] -> OK: 多国語 filetype()[dir ] == is_dir()[dir ] -> OK: 表 -Active code page: %d diff --git a/ext/standard/tests/file/windows_mb_path/bug70903.phpt b/ext/standard/tests/file/windows_mb_path/bug70903.phpt index 48cbf524c96d..25a6f92b0abc 100644 --- a/ext/standard/tests/file/windows_mb_path/bug70903.phpt +++ b/ext/standard/tests/file/windows_mb_path/bug70903.phpt @@ -2,12 +2,8 @@ Bug #70903 scandir wrongly interprets the Turkish "ı" character --SKIPIF-- --FILE-- --CONFLICTS-- bug71509 diff --git a/ext/standard/tests/file/windows_mb_path/bug74923.phpt b/ext/standard/tests/file/windows_mb_path/bug74923.phpt index 9cffd5860f60..fb87f2b266d5 100644 --- a/ext/standard/tests/file/windows_mb_path/bug74923.phpt +++ b/ext/standard/tests/file/windows_mb_path/bug74923.phpt @@ -2,11 +2,8 @@ Bug #74923 Crash when crawling through network share --SKIPIF-- --FILE-- --INI-- default_charset=cp1251 diff --git a/ext/standard/tests/file/windows_mb_path/bug75063_utf8.phpt b/ext/standard/tests/file/windows_mb_path/bug75063_utf8.phpt index a1878bb88a37..615b76d196fb 100644 --- a/ext/standard/tests/file/windows_mb_path/bug75063_utf8.phpt +++ b/ext/standard/tests/file/windows_mb_path/bug75063_utf8.phpt @@ -2,12 +2,8 @@ Bug #75063 Many filesystem-related functions do not work with multibyte file names, UTF-8 --SKIPIF-- --FILE-- 259) die("skip Unsuitable starting path length"); ?> --FILE-- diff --git a/ext/standard/tests/file/windows_mb_path/test_big5_0.phpt b/ext/standard/tests/file/windows_mb_path/test_big5_0.phpt index 794c1a2f7b87..7dc11a6167b5 100644 --- a/ext/standard/tests/file/windows_mb_path/test_big5_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_big5_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading big5 path diff --git a/ext/standard/tests/file/windows_mb_path/test_big5_1.phpt b/ext/standard/tests/file/windows_mb_path/test_big5_1.phpt index d4821b23be0e..7a88f57b7cf0 100644 --- a/ext/standard/tests/file/windows_mb_path/test_big5_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_big5_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir big5 path diff --git a/ext/standard/tests/file/windows_mb_path/test_big5_2.phpt b/ext/standard/tests/file/windows_mb_path/test_big5_2.phpt index d7652615dea4..89a897034481 100644 --- a/ext/standard/tests/file/windows_mb_path/test_big5_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_big5_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write big5 to UTF-8 path diff --git a/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_0.phpt index b355267f851d..c68bd58be0fc 100644 --- a/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_0.phpt @@ -2,12 +2,8 @@ Test fopen() for reading big5 to UTF-8 path --SKIPIF-- --CONFLICTS-- file_big5 diff --git a/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_1.phpt index 5076768c955b..33573f04ec39 100644 --- a/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_1.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir big5 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_big5 diff --git a/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_2.phpt index 4f94f898796f..2451ebca18e9 100644 --- a/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_big5_to_utf8_2.phpt @@ -2,12 +2,8 @@ Test fopen() for write big5 to UTF-8 path --SKIPIF-- --CONFLICTS-- file_big5 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_0.phpt index 98c716678a6d..20e5de98e07f 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_0.phpt @@ -2,12 +2,8 @@ Test fopen() for reading UTF-8 path with cp1250 specific symbols --SKIPIF-- --CONFLICTS-- file_cp1250 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_1.phpt index ad09ff1967ca..1411911f6d54 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_1.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir UTF-8 path with cp1250 specific symbols --SKIPIF-- --CONFLICTS-- dir_cp1250 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_2.phpt index 61e1b4eaa598..72cf60068d24 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_2.phpt @@ -2,12 +2,8 @@ Test fopen() for write to UTF-8 path with cp1250 specific symbols --SKIPIF-- --CONFLICTS-- dir_cp1250 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_3.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_3.phpt index 2f3ae9afd608..4c07d5a6de65 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_3.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_3.phpt @@ -2,12 +2,8 @@ Test fopen() for reading UTF-8 path with cp1250 specific symbols --SKIPIF-- --CONFLICTS-- file_cp1250 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_4.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_4.phpt index 8992a847eb50..9d2a13de2b94 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_4.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_4.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir UTF-8 path with cp1250 specific symbols --SKIPIF-- --CONFLICTS-- dir_cp1250 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_5.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_5.phpt index 392c486a767f..4ed862f08b08 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_5.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1250_to_utf8_5.phpt @@ -2,12 +2,8 @@ Test fopen() for write to UTF-8 path with cp1250 specific symbols --SKIPIF-- --CONFLICTS-- dir_cp1250 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_0.phpt index bf30b4baeb04..7766d6dfd327 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading CP1251 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_1.phpt index 0ea67f575e56..1ea343ae30ce 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir CP1251 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_2.phpt index f65b38eafdad..60a7dbf07fd8 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write CP1251 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_0.phpt index 0cd657e94c59..6cb74e468eae 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_0.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for reading CP1251 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file_cp1251 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_1.phpt index 6e53ff48c99d..7776b908a8de 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_1.phpt @@ -1,13 +1,11 @@ --TEST-- Test mkdir/rmdir CP1251 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_cp1251 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_2.phpt index 95b75985c618..90c9ddf01254 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_to_utf8_2.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for write CP1251 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file_cp1251 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_0.phpt index 8b800ed3bdea..f962c5c0b024 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_0.phpt @@ -7,12 +7,8 @@ zend.multibyte=1 zend.script_encoding=cp1251 --SKIPIF-- --CONFLICTS-- file_cp1251 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_1.phpt index 31db615f4d2c..6d8a1f5d0050 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_1.phpt @@ -7,12 +7,8 @@ zend.multibyte=1 zend.script_encoding=cp1251 --SKIPIF-- --CONFLICTS-- dir_cp1251 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_2.phpt index d6075da559c9..63745231771d 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1251_zend_multibyte_2.phpt @@ -7,12 +7,8 @@ zend.multibyte=1 zend.script_encoding=cp1251 --SKIPIF-- --CONFLICTS-- file_cp1251 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1252_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1252_0.phpt index f2671aa6054a..aa3bc38dded2 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1252_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1252_0.phpt @@ -4,9 +4,8 @@ cp1252 cmd test diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_0.phpt index 45234243cee4..c7631eb60153 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_0.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for reading cp1252 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file_cp1252 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_1.phpt index 5f5a6a78385a..ea14608ad4c0 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_1.phpt @@ -1,13 +1,11 @@ --TEST-- Test mkdir/rmdir cp1252 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_cp1252 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_2.phpt index 04baef95b025..381b64eda604 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_2.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for write cp1252 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_cp1252 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_3.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_3.phpt index f6559253d2de..ef441bcbbfdd 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_3.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_3.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for reading cp1252 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file2_cp1252 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_4.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_4.phpt index a3359f686c1b..739413dd7484 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_4.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_4.phpt @@ -1,13 +1,11 @@ --TEST-- Test mkdir/rmdir cp1252 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir2_cp1252 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_5.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_5.phpt index 42212d027126..9cf7a31feea1 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_5.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1252_to_utf8_5.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for write cp1252 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir2_cp1252 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1253_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1253_0.phpt index 93b63a536e83..11116849036b 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1253_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1253_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading cp1253 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1253_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1253_1.phpt index 9ffdb11b2b83..998ab348a0dc 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1253_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1253_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir cp1253 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1253_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1253_2.phpt index 642e4aaabd19..01177620bd54 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1253_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1253_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write cp1253 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_0.phpt index d12a174a7fea..a592ed1f85bc 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_0.phpt @@ -2,12 +2,8 @@ Test fopen() for reading cp1253 to UTF-8 path --SKIPIF-- --CONFLICTS-- file_cp1253 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_1.phpt index c84e9c95b369..addc407f3e97 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_1.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir cp1253 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1253 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_2.phpt index c0723d18b122..cf88d95a4c69 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1253_to_utf8_2.phpt @@ -2,12 +2,8 @@ Test fopen() for write cp1253 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1253 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_0.phpt index 77b52e0f1a2d..83a413549ab3 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading cp1254 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_1.phpt index 82d74c750961..9dc822559835 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir cp1254 to UTF-8 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_2.phpt index f14a4c3de086..2e386b3af45b 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write cp1254 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_3.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_3.phpt index 0e0e83d285a3..076bf2eba50e 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_3.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_3.phpt @@ -4,9 +4,8 @@ cp1254 cmd test diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_0.phpt index 211233de1c8e..8dff7615dbfb 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_0.phpt @@ -2,12 +2,8 @@ Test fopen() for reading cp1254 to UTF-8 path --SKIPIF-- --CONFLICTS-- file_cp1254 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_1.phpt index 42b241176ffb..7b83cdbb395b 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_1.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir cp1254 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1254 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_2.phpt index b0c4f5ec83f0..5ec63de4bc6e 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_2.phpt @@ -2,12 +2,8 @@ Test fopen() for write cp1254 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1254 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_3.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_3.phpt index 67549daf601d..1e70dc8fe5b1 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_3.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1254_to_utf8_3.phpt @@ -2,12 +2,8 @@ cp1254 cmd test --SKIPIF-- --CONFLICTS-- file_cp1254 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1255_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1255_0.phpt index e9adaf843fb6..61bb6b4155dc 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1255_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1255_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading cp1255 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1255_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1255_1.phpt index 2cf42239267a..a539ce8fd34e 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1255_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1255_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir cp1255 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1255_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1255_2.phpt index e4779b721ba9..7fe2fecb7ea3 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1255_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1255_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write cp1255 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_0.phpt index 1b6514355342..e8b35687e2fa 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_0.phpt @@ -2,12 +2,8 @@ Test fopen() for reading cp1255 to UTF-8 path --SKIPIF-- --CONFLICTS-- file_cp1255 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_1.phpt index 356143ca7876..48fa4f26a4b7 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_1.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir cp1255 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1255 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_2.phpt index b378a7231d15..358908ae56bd 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1255_to_utf8_2.phpt @@ -2,12 +2,8 @@ Test fopen() for write cp1255 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1255 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1256_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1256_0.phpt index 40910894b8ee..9c0abe4c8326 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1256_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1256_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading cp1256 to UTF-8 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1256_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1256_1.phpt index 244758fe7bd6..f19bd04e9da9 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1256_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1256_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir cp1256 to UTF-8 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1256_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1256_2.phpt index f5b5db893527..c734e24205d6 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1256_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1256_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write cp1256 to UTF-8 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_0.phpt index 901026f3899b..9af7d83df2ad 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_0.phpt @@ -2,12 +2,8 @@ Test fopen() for reading cp1256 to UTF-8 path --SKIPIF-- --CONFLICTS-- file_cp1256 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_1.phpt index b630f37648bc..6da6d789e45e 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_1.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir cp1256 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1256 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_2.phpt index 6aa29f43c426..2cce0b541116 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp1256_to_utf8_2.phpt @@ -2,12 +2,8 @@ Test fopen() for write cp1256 to UTF-8 path --SKIPIF-- --CONFLICTS-- dir_cp1256 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp874_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp874_0.phpt index e8bc394a5d0d..cbab58e84855 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp874_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp874_0.phpt @@ -4,9 +4,8 @@ Thai cp874 basic test diff --git a/ext/standard/tests/file/windows_mb_path/test_cp874_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp874_1.phpt index 9d948d4023aa..cd438c52f361 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp874_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp874_1.phpt @@ -4,9 +4,8 @@ Thai cp874 cmd test diff --git a/ext/standard/tests/file/windows_mb_path/test_cp874_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp874_to_utf8_0.phpt index c21f124b6e19..b8ed1c23758a 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp874_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp874_to_utf8_0.phpt @@ -2,12 +2,8 @@ Thai UTF-8 basic test --SKIPIF-- --FILE-- --CONFLICTS-- file_cp874 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp932_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp932_0.phpt index ccb273a94ce0..d2a8e06a61cb 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp932_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp932_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading cp932 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp932_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp932_1.phpt index 744d1a592be9..3f58aa5614f5 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp932_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp932_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir cp932 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp932_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp932_2.phpt index 737a4d3eb869..dc474cf9dff3 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp932_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp932_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write to cp932 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp932_3.phpt b/ext/standard/tests/file/windows_mb_path/test_cp932_3.phpt index 4fdfb925a82d..d54d90e17bee 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp932_3.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp932_3.phpt @@ -4,9 +4,8 @@ cp932 cmd test diff --git a/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_0.phpt index df855aaca4e3..925e0558ab26 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_0.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for reading cp932 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file_cp932 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_1.phpt index b9575302c8ab..8346c86a4d19 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_1.phpt @@ -1,13 +1,11 @@ --TEST-- Test mkdir/rmdir cp932 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_cp932 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_2.phpt index 7c3870593692..5d0f10f647ac 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp932_to_utf8_2.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for write cp932 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_cp932 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp936_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp936_0.phpt index b1a4f8744f94..3199aa979355 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp936_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp936_0.phpt @@ -4,9 +4,8 @@ Test fopen() for reading cp936 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp936_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp936_1.phpt index 529808aad5fb..8ee68392ff31 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp936_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp936_1.phpt @@ -4,9 +4,8 @@ Test mkdir/rmdir cp936 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp936_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp936_2.phpt index e872c05942a6..024e84d4317f 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp936_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp936_2.phpt @@ -4,9 +4,8 @@ Test fopen() for write cp936 path diff --git a/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_0.phpt index 2797d25904f7..39f989371968 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_0.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for reading cp936 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file_cp936 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_1.phpt index f9730b6fe9a0..7321ea0ed9d5 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_1.phpt @@ -1,13 +1,11 @@ --TEST-- Test mkdir/rmdir cp936 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_cp936 diff --git a/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_2.phpt index 31ff1db318b8..8b3eb208f12f 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cp936_to_utf8_2.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for write cp936 to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file_cp936 diff --git a/ext/standard/tests/file/windows_mb_path/test_cwd_mb_names.phpt b/ext/standard/tests/file/windows_mb_path/test_cwd_mb_names.phpt index 3cb09f777d37..9f9d1f24e6cd 100644 --- a/ext/standard/tests/file/windows_mb_path/test_cwd_mb_names.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_cwd_mb_names.phpt @@ -2,15 +2,8 @@ Test chdir()/getcwd() with a dir for multibyte filenames --SKIPIF-- --CONFLICTS-- dir_mb @@ -24,8 +17,9 @@ $prefix = create_data("dir_mb"); $dirw = $prefix . DIRECTORY_SEPARATOR . "テストマルチバイト・パス42"; touch($dirw . DIRECTORY_SEPARATOR . "dummy.txt"); -$old_cp = get_active_cp(); -set_active_cp(65001); +$old_cp = sapi_windows_cp_get(); +sapi_windows_cp_set(65001); +echo "Active code page: ", sapi_windows_cp_get(), "\n"; $oldcwd = getcwd(); var_dump(chdir($dirw)); @@ -33,7 +27,7 @@ var_dump(getcwd()); var_dump(file_exists("dummy.txt")); -set_active_cp($old_cp); +sapi_windows_cp_set($old_cp); chdir($oldcwd); remove_data("dir_mb"); @@ -44,4 +38,3 @@ Active code page: 65001 bool(true) string(%d) "%s\テストマルチバイト・パス42" bool(true) -Active code page: %d diff --git a/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_0.phpt index 7a06f53b7dd0..48f2443017d6 100644 --- a/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_0.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for reading eucjp to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- file_eucjp diff --git a/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_1.phpt index e3111ba33af7..922f9e829064 100644 --- a/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_1.phpt @@ -1,13 +1,11 @@ --TEST-- Test mkdir/rmdir eucjp to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_eucjp diff --git a/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_2.phpt index 9425a1cc1cea..b4a9895428d5 100644 --- a/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_eucjp_to_utf8_2.phpt @@ -1,13 +1,11 @@ --TEST-- Test fopen() for write eucjp to UTF-8 path +--EXTENSIONS-- +iconv --SKIPIF-- --CONFLICTS-- dir_eucjp diff --git a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_0.phpt b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_0.phpt index 0840610c2058..f3c4f18131fa 100644 --- a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_0.phpt @@ -2,12 +2,8 @@ Test fopen() for reading Kartuli UTF-8 path --SKIPIF-- --CONFLICTS-- file_kartuli diff --git a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_1.phpt b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_1.phpt index d348ccfd3c8f..16f68f0f0ecb 100644 --- a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_1.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_1.phpt @@ -2,12 +2,8 @@ Test mkdir/rmdir Kartuli UTF-8 path --SKIPIF-- --CONFLICTS-- dir_kartuli diff --git a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_2.phpt b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_2.phpt index 2e57dc0c91fa..ca6c887a24ed 100644 --- a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_2.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_2.phpt @@ -2,12 +2,8 @@ Test fopen() for write Kartuli UTF-8 path --SKIPIF-- --CONFLICTS-- dir_kartuli diff --git a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_3.phpt b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_3.phpt index 8d498d19907b..e0984b0dd73b 100644 --- a/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_3.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_kartuli_utf8_3.phpt @@ -2,12 +2,8 @@ Kartuli UTF-8 cmd test --SKIPIF-- --CONFLICTS-- file_kartuli diff --git a/ext/standard/tests/file/windows_mb_path/test_long_path_0.phpt b/ext/standard/tests/file/windows_mb_path/test_long_path_0.phpt index 6a5b60f08bbe..daabfaad17fe 100644 --- a/ext/standard/tests/file/windows_mb_path/test_long_path_0.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_long_path_0.phpt @@ -4,12 +4,8 @@ Basic long path test mbstring --SKIPIF-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- 248 has be a long path --SKIPIF-- 260 || strlen($start) > 248) { +if (strlen($start) > 260 || strlen($start) < 248) { die("skip the starting path length is unsuitable for this test"); } diff --git a/ext/standard/tests/file/windows_mb_path/test_readdir_mb_names.phpt b/ext/standard/tests/file/windows_mb_path/test_readdir_mb_names.phpt index 84fe5e327335..65a0dada9f4c 100644 --- a/ext/standard/tests/file/windows_mb_path/test_readdir_mb_names.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_readdir_mb_names.phpt @@ -2,12 +2,8 @@ Test readdir() with a dir for multibyte filenames --SKIPIF-- --CONFLICTS-- mb_names @@ -38,8 +34,9 @@ create_verify_dir($prefix, "żółć"); $dirw = $prefix . DIRECTORY_SEPARATOR; -$old_cp = get_active_cp(); -set_active_cp(65001); +$old_cp = sapi_windows_cp_get(); +sapi_windows_cp_set(65001); +echo "Active code page: ", sapi_windows_cp_get(), "\n"; if (is_dir($dirw)) { if ($dh = opendir($dirw)) { @@ -51,12 +48,12 @@ if (is_dir($dirw)) { } else { echo "is_dir failed\n"; } -set_active_cp($old_cp); +sapi_windows_cp_set($old_cp); remove_data("mb_names"); ?> ---EXPECTF-- +--EXPECT-- Active code page: 65001 filename: . : filetype: dir filename: .. : filetype: dir @@ -76,4 +73,3 @@ filename: テストマルチバイト・パス : filetype: file filename: テストマルチバイト・パス42 : filetype: dir filename: 測試多字節路徑 : filetype: file filename: 測試多字節路徑5 : filetype: dir -Active code page: %d diff --git a/ext/standard/tests/file/windows_mb_path/test_rename_mb_names.phpt b/ext/standard/tests/file/windows_mb_path/test_rename_mb_names.phpt index 53dd1bd3ea86..ce040d1eda54 100644 --- a/ext/standard/tests/file/windows_mb_path/test_rename_mb_names.phpt +++ b/ext/standard/tests/file/windows_mb_path/test_rename_mb_names.phpt @@ -2,62 +2,42 @@ Test rename() with a dir for multibyte filenames --SKIPIF-- --CONFLICTS-- file2_mb --FILE-- ---EXPECTF-- +--EXPECT-- Active code page: 65001 bool(true) string(21) "Ελλάδα_copy.txt" @@ -66,4 +46,3 @@ bool(true) string(27) "測試多字節路徑17.txt" bool(true) bool(true) -Active code page: %d diff --git a/ext/standard/tests/file/windows_mb_path/util.inc b/ext/standard/tests/file/windows_mb_path/util.inc index a26a66c01751..c8f0f6c586cb 100644 --- a/ext/standard/tests/file/windows_mb_path/util.inc +++ b/ext/standard/tests/file/windows_mb_path/util.inc @@ -1,36 +1,7 @@ +--EXPECT-- +string(5) "Hello" +string(12) "Hello, World" +string(12) "Hello, World" +string(5) "Hello" +int(5) diff --git a/ext/standard/tests/filters/convert.phpt b/ext/standard/tests/filters/convert.phpt new file mode 100644 index 000000000000..a99579b5dd8f --- /dev/null +++ b/ext/standard/tests/filters/convert.phpt @@ -0,0 +1,130 @@ +--TEST-- +convert stream filter tests +--FILE-- + 20, 'line-break-chars' => "\n"); +test_roundtrip("Long text that will be wrapped", "convert.base64-encode", "convert.base64-decode", $opts); + +$opts2 = array('binary' => true); +test_roundtrip("Text\t\r\n", "convert.quoted-printable-encode", "convert.quoted-printable-decode", $opts2); + +$fp = tmpfile(); +fwrite($fp, "Test"); +rewind($fp); +stream_filter_prepend($fp, 'convert.base64-encode', STREAM_FILTER_READ); +$result = stream_get_contents($fp); +fclose($fp); +var_dump($result === base64_encode("Test")); + +?> +--EXPECTF-- +Filter: convert.base64-encode +Original: Hello World! +Encoded: SGVsbG8gV29ybGQh +Decoded: Hello World! +bool(true) + +Filter: convert.base64-encode +Original (hex): 414243ff +Encoded: QUJD/w== +Decoded (hex): 414243ff +bool(true) + +Filter: convert.base64-encode +Original: +Encoded: +Decoded: +bool(true) + +Filter: convert.base64-encode +Original: A +Encoded: QQ== +Decoded: A +bool(true) + +Filter: convert.quoted-printable-encode +Original: Hello World! +Encoded: Hello World! +Decoded: Hello World! +bool(true) + +Filter: convert.quoted-printable-encode +Original: Line1 +Line2 +Encoded: Line1=0D=0ALine2 +Decoded: Line1 +Line2 +bool(true) + +Filter: convert.base64-encode +Original: Long text that will be wrapped +Encoded: TG9uZyB0ZXh0IHRoYXQg +d2lsbCBiZSB3cmFwcGVk +Decoded: Long text that will be wrapped +bool(true) + +Filter: convert.quoted-printable-encode +Original: Text + +Encoded: Text=09=0D=0A +Decoded: Text + +bool(true) + +bool(true) diff --git a/ext/standard/tests/filters/convert_filter_seek.phpt b/ext/standard/tests/filters/convert_filter_seek.phpt new file mode 100644 index 000000000000..6cbcd7b843f3 --- /dev/null +++ b/ext/standard/tests/filters/convert_filter_seek.phpt @@ -0,0 +1,75 @@ +--TEST-- +convert filters (base64, quoted-printable) with seek to start only +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Testing convert.base64-encode/decode +First read (20 bytes): Hello World! This is +Seek to start: SUCCESS +Content matches: YES + +Warning: fseek(): Stream filter convert.* is seekable only to start position in %s on line %d +Seek to middle: FAILURE + +Testing convert.quoted-printable-encode/decode +First read (10 bytes): 4c696e65310d0a4c696e +Seek to start: SUCCESS +Content matches: YES + +Warning: fseek(): Stream filter convert.* is seekable only to start position in %s on line %d +Seek to middle: FAILURE diff --git a/ext/standard/tests/filters/convert_filter_write_seek_modes.phpt b/ext/standard/tests/filters/convert_filter_write_seek_modes.phpt new file mode 100644 index 000000000000..0a2d4114bf3c --- /dev/null +++ b/ext/standard/tests/filters/convert_filter_write_seek_modes.phpt @@ -0,0 +1,61 @@ +--TEST-- +convert.* write filter: write_seek_mode parameter +--FILE-- + 'preserve']); + fwrite($fp, 'Hello'); + var_dump(fseek($fp, 0, SEEK_SET) === 0); + var_dump(fseek($fp, 100, SEEK_SET) === 0); + fclose($fp); + + /* reset: seeks succeed, callback dispatched */ + $fp = fopen('php://memory', 'w+'); + stream_filter_append($fp, $name, STREAM_FILTER_WRITE, + ['write_seek_mode' => 'reset']); + fwrite($fp, 'Hello'); + var_dump(fseek($fp, 0, SEEK_SET) === 0); + fclose($fp); + + /* strict: seek fails */ + $fp = fopen('php://memory', 'w+'); + stream_filter_append($fp, $name, STREAM_FILTER_WRITE, + ['write_seek_mode' => 'strict']); + fwrite($fp, 'Hello'); + var_dump(@fseek($fp, 0, SEEK_SET) === -1); + fclose($fp); + + /* invalid: ValueError */ + $fp = fopen('php://memory', 'w+'); + stream_filter_append($fp, $name, STREAM_FILTER_WRITE, + ['write_seek_mode' => 42]); + if ($fp) { + fclose($fp); + } +} +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) + +Warning: stream_filter_append(): "write_seek_mode" filter parameter must be one of "preserve", "reset", or "strict" in %s + +Warning: stream_filter_append(): Unable to create or locate filter "convert.base64-encode" in %s +bool(true) +bool(true) +bool(true) +bool(true) + +Warning: stream_filter_append(): "write_seek_mode" filter parameter must be one of "preserve", "reset", or "strict" in %s + +Warning: stream_filter_append(): Unable to create or locate filter "convert.quoted-printable-encode" in %s diff --git a/ext/standard/tests/filters/filter_errors.inc b/ext/standard/tests/filters/filter_errors.inc index 18711844f834..e933eea725e2 100644 --- a/ext/standard/tests/filters/filter_errors.inc +++ b/ext/standard/tests/filters/filter_errors.inc @@ -1,16 +1,5 @@ --FILE-- +--EXTENSIONS-- +zlib --FILE-- +--EXTENSIONS-- +zlib --FILE-- data = strtoupper($bucket->data); + $consumed += $bucket->datalen; + stream_bucket_prepend($out, $bucket); + // Interleave new bucket + stream_bucket_prepend($out, clone $bucket); + stream_bucket_prepend($out, $bucket); + } + return PSFS_PASS_ON; + } + + function onCreate(): bool + { + echo "fffffffffff\n"; + return true; + } + + function onClose(): void + { + echo "hello\n"; + } +} + +stream_filter_register("strtoupper", "strtoupper_filter"); +$fp=fopen($file, "w"); +stream_filter_append($fp, "strtoupper"); +fread($fp, 1024); +fwrite($fp, "Thank you\n"); +fclose($fp); +readfile($file); +unlink($file); +?> +--EXPECTF-- +fffffffffff + +Notice: fread(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d +hello +THANK YOU diff --git a/ext/standard/tests/streams/gh17650.phpt b/ext/standard/tests/filters/gh17650.phpt similarity index 100% rename from ext/standard/tests/streams/gh17650.phpt rename to ext/standard/tests/filters/gh17650.phpt diff --git a/ext/standard/tests/filters/gh20370.phpt b/ext/standard/tests/filters/gh20370.phpt new file mode 100644 index 000000000000..abcf49bfc9f4 --- /dev/null +++ b/ext/standard/tests/filters/gh20370.phpt @@ -0,0 +1,44 @@ +--TEST-- +GH-20370 (User filters should respect typed properties) +--FILE-- +datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } +} + +stream_filter_register("pass", "pass_filter"); +$fp = fopen("php://memory", "w"); +stream_filter_append($fp, "pass"); + +try { + fwrite($fp, "data"); +} catch (TypeError $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +try { + fclose($fp); +} catch (TypeError $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} + +unset($fp); // prevent cleanup at shutdown + +?> +--EXPECTF-- +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d +TypeError: Cannot assign resource to property pass_filter::$stream of type int +TypeError: Cannot assign resource to property pass_filter::$stream of type int diff --git a/ext/standard/tests/filters/gh20370_dynamic_stream_property.phpt b/ext/standard/tests/filters/gh20370_dynamic_stream_property.phpt new file mode 100644 index 000000000000..97f24b854c5e --- /dev/null +++ b/ext/standard/tests/filters/gh20370_dynamic_stream_property.phpt @@ -0,0 +1,51 @@ +--TEST-- +GH-20370 (User filters should update dynamic stream property if it exists) +--FILE-- +stream = null; + return true; + } + + function filter($in, $out, &$consumed, $closing): int + { + while ($bucket = stream_bucket_make_writeable($in)) { + $consumed += $bucket->datalen; + stream_bucket_append($out, $bucket); + } + var_dump(property_exists($this, 'stream')); + if (is_resource($this->stream)) { + var_dump(get_resource_type($this->stream)); + } + return PSFS_PASS_ON; + } +} + +stream_filter_register("pass", "pass_filter"); +$fp = fopen("php://memory", "w"); +stream_filter_append($fp, "pass"); + +fwrite($fp, "data"); +rewind($fp); +echo fread($fp, 1024) . "\n"; + +?> +--EXPECTF-- +bool(true) +string(6) "stream" +bool(true) +string(6) "stream" +bool(true) +string(6) "stream" +bool(true) +string(6) "stream" +data +bool(true) diff --git a/ext/standard/tests/filters/gh20370_no_stream_property.phpt b/ext/standard/tests/filters/gh20370_no_stream_property.phpt new file mode 100644 index 000000000000..1b52c4c4155b --- /dev/null +++ b/ext/standard/tests/filters/gh20370_no_stream_property.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-20370 (User filters should not create stream property if not declared) +--FILE-- +datalen; + stream_bucket_append($out, $bucket); + } + + var_dump(property_exists($this, 'stream')); + return PSFS_PASS_ON; + } +} + +stream_filter_register("pass", "pass_filter"); +$fp = fopen("php://memory", "w"); +stream_filter_append($fp, "pass"); +fwrite($fp, "data"); +rewind($fp); +echo fread($fp, 1024) . "\n"; + +?> +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(false) +data +bool(false) diff --git a/ext/standard/tests/filters/gh20370_private_stream_property.phpt b/ext/standard/tests/filters/gh20370_private_stream_property.phpt new file mode 100644 index 000000000000..bfbbba6099ad --- /dev/null +++ b/ext/standard/tests/filters/gh20370_private_stream_property.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-20370 (User filters should handle private stream property correctly) +--FILE-- +datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } + + function onClose() + { + var_dump($this->stream); // should be null + } +} + +stream_filter_register("pass", "pass_filter"); +$fp = fopen("php://memory", "w"); +stream_filter_append($fp, "pass", STREAM_FILTER_WRITE); + +fwrite($fp, "data"); +rewind($fp); +echo fread($fp, 1024) . "\n"; + +?> +--EXPECT-- +data +NULL diff --git a/ext/standard/tests/filters/oss_fuzz_385993744.phpt b/ext/standard/tests/filters/oss_fuzz_385993744.phpt new file mode 100644 index 000000000000..bfed9e57a918 --- /dev/null +++ b/ext/standard/tests/filters/oss_fuzz_385993744.phpt @@ -0,0 +1,28 @@ +--TEST-- +OSS-Fuzz #385993744 +--FILE-- +data .= $bucket->data; + } + + $bucket = stream_bucket_new($this->stream, $this->data); + stream_bucket_append($out, $bucket); + + return PSFS_FEED_ME; + } +} +stream_filter_register('sample.filter', SampleFilter::class); +var_dump(file_get_contents('php://filter/read=sample.filter/resource='. __FILE__)); + +?> +--EXPECT-- +string(0) "" diff --git a/ext/standard/tests/filters/php_user_filter_04.phpt b/ext/standard/tests/filters/php_user_filter_04.phpt new file mode 100644 index 000000000000..6dc62779aa90 --- /dev/null +++ b/ext/standard/tests/filters/php_user_filter_04.phpt @@ -0,0 +1,28 @@ +--TEST-- +php_user_filter with invalid seek signature +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of InvalidSeekFilter::seek($offset): bool must be compatible with php_user_filter::seek(int $offset, int $whence, int $chain): bool in %s on line %d diff --git a/ext/standard/tests/streams/stream_filter_register.phpt b/ext/standard/tests/filters/stream_filter_register.phpt similarity index 100% rename from ext/standard/tests/streams/stream_filter_register.phpt rename to ext/standard/tests/filters/stream_filter_register.phpt diff --git a/ext/standard/tests/filters/stream_filter_register_class_coerce_consumed_by_ref_param.phpt b/ext/standard/tests/filters/stream_filter_register_class_coerce_consumed_by_ref_param.phpt new file mode 100644 index 000000000000..f5f0ecca7975 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_class_coerce_consumed_by_ref_param.phpt @@ -0,0 +1,32 @@ +--TEST-- +stream_filter_register() with a class that coerces the $consumed parameter of filter method +--XFAIL-- +This leaks memory +--FILE-- + +--EXPECTF-- +bool(true) +resource(4) of type (stream filter) + +Warning: Object of class stdClass could not be converted to int in %s on line %d + +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d +int(1) + +Warning: Object of class stdClass could not be converted to int in Unknown on line 0 diff --git a/ext/standard/tests/filters/stream_filter_register_class_completely_invalid.phpt b/ext/standard/tests/filters/stream_filter_register_class_completely_invalid.phpt new file mode 100644 index 000000000000..6bd3e7bc1c9d --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_class_completely_invalid.phpt @@ -0,0 +1,33 @@ +--TEST-- +stream_filter_register() with a class name that exist but does not extend php_user_filter nor mock anything +--FILE-- + +--EXPECTF-- +bool(true) + +Deprecated: Creation of dynamic property foo::$filtername is deprecated in %s on line %d + +Deprecated: Creation of dynamic property foo::$params is deprecated in %s on line %d +resource(%d) of type (stream filter) + +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d + +Fatal error: Uncaught Error: Invalid callback foo::filter, class foo does not have a method "filter" in %s:%d +Stack trace: +#0 %s(%d): fwrite(Resource id #%d, 'Hello\n') +#1 {main} + thrown in %s on line %d + +Fatal error: Invalid callback foo::filter, class foo does not have a method "filter" in Unknown on line 0 diff --git a/ext/standard/tests/filters/stream_filter_register_class_completely_invalid_filtername_prop_type.phpt b/ext/standard/tests/filters/stream_filter_register_class_completely_invalid_filtername_prop_type.phpt new file mode 100644 index 000000000000..793c112791a9 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_class_completely_invalid_filtername_prop_type.phpt @@ -0,0 +1,28 @@ +--TEST-- +stream_filter_register() with a class name exist but does not extend php_user_filter and defines a $filtername prop with different type +--FILE-- + +--EXPECTF-- +bool(true) + +Deprecated: Creation of dynamic property foo::$params is deprecated in %s on line %d + +Fatal error: Uncaught TypeError: Cannot assign string to property foo::$filtername of type array in %s:%d +Stack trace: +#0 %s(%d): stream_filter_append(Resource id #2, 'invalid_filter') +#1 {main} + thrown in %s on line %d + +Fatal error: Invalid callback foo::filter, class foo does not have a method "filter" in Unknown on line 0 diff --git a/ext/standard/tests/filters/stream_filter_register_class_completely_invalid_no_dynamic_props.phpt b/ext/standard/tests/filters/stream_filter_register_class_completely_invalid_no_dynamic_props.phpt new file mode 100644 index 000000000000..86994d5c1b66 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_class_completely_invalid_no_dynamic_props.phpt @@ -0,0 +1,28 @@ +--TEST-- +stream_filter_register() with a class name exist but does not extend php_user_filter and cannot have dynamic properties +--FILE-- + +--EXPECTF-- +bool(true) + +Fatal error: Uncaught Error: Cannot create dynamic property SensitiveParameter::$filtername in %s:%d +Stack trace: +#0 %s(%d): stream_filter_append(Resource id #%d, 'invalid_filter') +#1 {main} + +Next Error: Cannot create dynamic property SensitiveParameter::$params in %s:%d +Stack trace: +#0 %s(%d): stream_filter_append(Resource id #%d, 'invalid_filter') +#1 {main} + thrown in %s on line %d + +Fatal error: Invalid callback SensitiveParameter::filter, class SensitiveParameter does not have a method "filter" in Unknown on line 0 diff --git a/ext/standard/tests/filters/stream_filter_register_class_private_filtername_prop.phpt b/ext/standard/tests/filters/stream_filter_register_class_private_filtername_prop.phpt new file mode 100644 index 000000000000..6b9be4bbbb4b --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_class_private_filtername_prop.phpt @@ -0,0 +1,28 @@ +--TEST-- +stream_filter_register() with a class name exist but does not extend php_user_filter and defines a private $filtername prop +--FILE-- + +--EXPECTF-- +bool(true) + +Deprecated: Creation of dynamic property foo::$params is deprecated in %s on line %d + +Fatal error: Uncaught Error: Cannot access private property foo::$filtername in %s:%d +Stack trace: +#0 %s(%d): stream_filter_append(Resource id #2, 'invalid_filter') +#1 {main} + thrown in %s on line %d + +Fatal error: Invalid callback foo::filter, class foo does not have a method "filter" in Unknown on line 0 diff --git a/ext/standard/tests/filters/stream_filter_register_class_throwing_onclose.phpt b/ext/standard/tests/filters/stream_filter_register_class_throwing_onclose.phpt new file mode 100644 index 000000000000..76b925cc0483 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_class_throwing_onclose.phpt @@ -0,0 +1,30 @@ +--TEST-- +stream_filter_register() with a class that has a onclose method that throws +--FILE-- + +--EXPECTF-- +bool(true) +resource(4) of type (stream filter) + +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d +bool(false) + +Fatal error: Uncaught Exception: No in %s:%d +Stack trace: +#0 [internal function]: foo->onclose() +#1 {main} + thrown in %s on line %d diff --git a/ext/standard/tests/filters/stream_filter_register_class_throwing_oncreate.phpt b/ext/standard/tests/filters/stream_filter_register_class_throwing_oncreate.phpt new file mode 100644 index 000000000000..3e429a2cc343 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_class_throwing_oncreate.phpt @@ -0,0 +1,27 @@ +--TEST-- +stream_filter_register() with a class that has a oncreate method that throws +--FILE-- + +--EXPECTF-- +bool(true) + +Fatal error: Uncaught Exception: No in %s:%d +Stack trace: +#0 [internal function]: foo->oncreate() +#1 %s(%d): stream_filter_append(Resource id #2, 'invalid_filter') +#2 {main} + thrown in %s on line %d diff --git a/ext/standard/tests/filters/stream_filter_register_filter_always_feed.phpt b/ext/standard/tests/filters/stream_filter_register_filter_always_feed.phpt new file mode 100644 index 000000000000..7a3d3f889993 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_filter_always_feed.phpt @@ -0,0 +1,24 @@ +--TEST-- +stream_filter_register() with a filter method always returning PSFS_FEED_ME +--FILE-- + +--EXPECTF-- +bool(true) +resource(4) of type (stream filter) + +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d +int(0) diff --git a/ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt b/ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt new file mode 100644 index 000000000000..4d2309a718eb --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_mock_class_filter.phpt @@ -0,0 +1,30 @@ +--TEST-- +stream_filter_register() with a class name exist that mocks php_user_filter with a filter method +--XFAIL-- +This leaks memory +--FILE-- + +--EXPECTF-- +bool(true) +resource(4) of type (stream filter) + +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d +int(0) diff --git a/ext/standard/tests/filters/stream_filter_register_mock_class_filter_incorect_return_type.phpt b/ext/standard/tests/filters/stream_filter_register_mock_class_filter_incorect_return_type.phpt new file mode 100644 index 000000000000..b5ec8da3dde1 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_mock_class_filter_incorect_return_type.phpt @@ -0,0 +1,32 @@ +--TEST-- +stream_filter_register() with a class name exist that mocks php_user_filter with a filter method returning not an int +--FILE-- + +--EXPECTF-- +bool(true) +resource(4) of type (stream filter) + +Warning: Object of class stdClass could not be converted to int in %s on line %d + +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d +int(0) + +Warning: Object of class stdClass could not be converted to int in Unknown on line 0 diff --git a/ext/standard/tests/filters/stream_filter_register_mock_class_filter_is_private.phpt b/ext/standard/tests/filters/stream_filter_register_mock_class_filter_is_private.phpt new file mode 100644 index 000000000000..6abffe1ff5f8 --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_mock_class_filter_is_private.phpt @@ -0,0 +1,35 @@ +--TEST-- +stream_filter_register() with a class name exist that mocks php_user_filter with a private filter method +--FILE-- + +--EXPECTF-- +bool(true) +resource(%d) of type (stream filter) + +Warning: fwrite(): Unprocessed filter buckets remaining on input brigade in %s on line %d + +Fatal error: Uncaught Error: Invalid callback foo::filter, cannot access private method foo::filter() in %s:%d +Stack trace: +#0 %s(%d): fwrite(Resource id #%d, 'Hello\n') +#1 {main} + thrown in %s on line %d + +Fatal error: Invalid callback foo::filter, cannot access private method foo::filter() in Unknown on line 0 diff --git a/ext/standard/tests/filters/stream_filter_register_non_existing_class.phpt b/ext/standard/tests/filters/stream_filter_register_non_existing_class.phpt new file mode 100644 index 000000000000..1c08201cff0c --- /dev/null +++ b/ext/standard/tests/filters/stream_filter_register_non_existing_class.phpt @@ -0,0 +1,21 @@ +--TEST-- +stream_filter_register() with a class name that does not exist +--FILE-- + +--EXPECTF-- +bool(true) + +Warning: stream_filter_append(): User-filter "not_existing_filter" requires class "not_existing", but that class is not defined in %s on line %d + +Warning: stream_filter_append(): Unable to create or locate filter "not_existing_filter" in %s on line %d +Hello +int(6) diff --git a/ext/standard/tests/streams/stream_multi_filters_close.phpt b/ext/standard/tests/filters/stream_multi_filters_close.phpt similarity index 100% rename from ext/standard/tests/streams/stream_multi_filters_close.phpt rename to ext/standard/tests/filters/stream_multi_filters_close.phpt diff --git a/ext/standard/tests/filters/string_filters_seek.phpt b/ext/standard/tests/filters/string_filters_seek.phpt new file mode 100644 index 000000000000..60eab2ccb84a --- /dev/null +++ b/ext/standard/tests/filters/string_filters_seek.phpt @@ -0,0 +1,68 @@ +--TEST-- +string filters (rot13, toupper, tolower) with seek - fully seekable +--FILE-- + 'Uryyb Jbeyq! Guvf vf n grfg sbe fgevat svygre frrxvat.', + 'string.toupper' => 'HELLO WORLD! THIS IS A TEST FOR STRING FILTER SEEKING.', + 'string.tolower' => 'hello world! this is a test for string filter seeking.' +]; + +foreach ($filters as $filter) { + echo "Testing filter: $filter\n"; + + file_put_contents($file, $text); + + $fp = fopen($file, 'r'); + stream_filter_append($fp, $filter, STREAM_FILTER_READ); + + $partial = fread($fp, 20); + echo "First read (20 bytes): $partial\n"; + + $result = fseek($fp, 0, SEEK_SET); + echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + + $full = fread($fp, strlen($text)); + echo "Content matches: " . ($full === $expected[$filter] ? "YES" : "NO") . "\n"; + + $result = fseek($fp, 13, SEEK_SET); + echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + + $from_middle = fread($fp, 10); + $expected_middle = substr($expected[$filter], 13, 10); + echo "Read from middle matches: " . ($from_middle === $expected_middle ? "YES" : "NO") . "\n"; + + fclose($fp); + echo "\n"; +} +?> +--CLEAN-- + +--EXPECT-- +Testing filter: string.rot13 +First read (20 bytes): Uryyb Jbeyq! Guvf vf +Seek to start: SUCCESS +Content matches: YES +Seek to middle: SUCCESS +Read from middle matches: YES + +Testing filter: string.toupper +First read (20 bytes): HELLO WORLD! THIS IS +Seek to start: SUCCESS +Content matches: YES +Seek to middle: SUCCESS +Read from middle matches: YES + +Testing filter: string.tolower +First read (20 bytes): hello world! this is +Seek to start: SUCCESS +Content matches: YES +Seek to middle: SUCCESS +Read from middle matches: YES diff --git a/ext/standard/tests/filters/user_filter_seek_01.phpt b/ext/standard/tests/filters/user_filter_seek_01.phpt new file mode 100644 index 000000000000..6023ced1d0ee --- /dev/null +++ b/ext/standard/tests/filters/user_filter_seek_01.phpt @@ -0,0 +1,83 @@ +--TEST-- +php_user_filter with seek method - always seekable (stateless filter) +--EXTENSIONS-- +ctype +--FILE-- +data); $i++) { + $char = $bucket->data[$i]; + if (ctype_alpha($char)) { + $base = ctype_upper($char) ? ord('A') : ord('a'); + $rotated .= chr($base + (ord($char) - $base + $this->rotation) % 26); + } else { + $rotated .= $char; + } + } + $bucket->data = $rotated; + $consumed += $bucket->datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } + + public function onCreate(): bool + { + if (isset($this->params['rotation'])) { + $this->rotation = (int)$this->params['rotation']; + } + return true; + } + + public function onClose(): void {} + + public function seek(int $offset, int $whence, int $chain): bool + { + // Stateless filter - always seekable to any position + return true; + } +} + +stream_filter_register('test.rotate', 'RotateFilter'); + +$file = __DIR__ . '/user_filter_seek_001.txt'; +$text = 'Hello World'; + +file_put_contents($file, $text); + +$fp = fopen($file, 'r'); +stream_filter_append($fp, 'test.rotate', STREAM_FILTER_READ, ['rotation' => 13]); + +$partial = fread($fp, 5); +echo "First read: $partial\n"; + +$result = fseek($fp, 0, SEEK_SET); +echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +$full = fread($fp, strlen($text)); +echo "Full content: $full\n"; + +$result = fseek($fp, 6, SEEK_SET); +echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +$from_middle = fread($fp, 5); +echo "Read from middle: $from_middle\n"; + +fclose($fp); +unlink($file); + +?> +--EXPECT-- +First read: Uryyb +Seek to start: SUCCESS +Full content: Uryyb Jbeyq +Seek to middle: SUCCESS +Read from middle: Jbeyq diff --git a/ext/standard/tests/filters/user_filter_seek_02.phpt b/ext/standard/tests/filters/user_filter_seek_02.phpt new file mode 100644 index 000000000000..f728e75cdca9 --- /dev/null +++ b/ext/standard/tests/filters/user_filter_seek_02.phpt @@ -0,0 +1,75 @@ +--TEST-- +php_user_filter with seek method - stateful filter +--FILE-- +data); $i++) { + $modified .= $bucket->data[$i] . $this->count++; + } + $bucket->data = $modified; + $consumed += $bucket->datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } + + public function onCreate(): bool + { + return true; + } + + public function onClose(): void {} + + public function seek(int $offset, int $whence, int $chain): bool + { + if ($offset === 0 && $whence === SEEK_SET) { + $this->count = 0; + return true; + } + return false; + } +} + +stream_filter_register('test.counting', 'CountingFilter'); + +$file = __DIR__ . '/user_filter_seek_002.txt'; +$text = 'ABC'; + +file_put_contents($file, $text); + +$fp = fopen($file, 'r'); +stream_filter_append($fp, 'test.counting', STREAM_FILTER_READ); + +$first = fread($fp, 10); +echo "First read: $first\n"; + +$result = fseek($fp, 0, SEEK_SET); +echo "Seek to start: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +$second = fread($fp, 10); +echo "Second read after seek: $second\n"; +echo "Counts reset: " . ($first === $second ? "YES" : "NO") . "\n"; + +$result = fseek($fp, 1, SEEK_SET); +echo "Seek to middle: " . ($result === 0 ? "SUCCESS" : "FAILURE") . "\n"; + +fclose($fp); +unlink($file); + +?> +--EXPECTF-- +First read: A0B1C2 +Seek to start: SUCCESS +Second read after seek: A0B1C2 +Counts reset: YES + +Warning: fseek(): Stream filter seeking for user-filter failed in %s on line %d +Seek to middle: FAILURE diff --git a/ext/standard/tests/filters/user_filter_seek_03.phpt b/ext/standard/tests/filters/user_filter_seek_03.phpt new file mode 100644 index 000000000000..bc814e8ed160 --- /dev/null +++ b/ext/standard/tests/filters/user_filter_seek_03.phpt @@ -0,0 +1,67 @@ +--TEST-- +php_user_filter::seek receives chain identifier (read vs write) +--FILE-- +datalen; + stream_bucket_append($out, $bucket); + } + return PSFS_PASS_ON; + } + + public function onCreate(): bool + { + return true; + } + + public function onClose(): void {} + + public function seek(int $offset, int $whence, int $chain): bool + { + $name = match ($chain) { + STREAM_FILTER_READ => 'read', + STREAM_FILTER_WRITE => 'write', + default => 'other', + }; + self::$log[] = "$name:$offset:$whence"; + return true; + } +} + +stream_filter_register('test.tracking', 'TrackingFilter'); + +$file = __DIR__ . '/user_filter_seek_03.txt'; +file_put_contents($file, "abcdefghij"); + +/* Read chain: seek-to-start should dispatch with STREAM_FILTER_READ */ +TrackingFilter::$log = []; +$fp = fopen($file, 'r'); +stream_filter_append($fp, 'test.tracking', STREAM_FILTER_READ); +fread($fp, 4); +fseek($fp, 0, SEEK_SET); +fclose($fp); +echo "Read chain log: " . implode(',', TrackingFilter::$log) . "\n"; + +/* Write chain: any seek should dispatch with STREAM_FILTER_WRITE */ +TrackingFilter::$log = []; +$fp = fopen($file, 'w+'); +stream_filter_append($fp, 'test.tracking', STREAM_FILTER_WRITE); +fwrite($fp, "xyz"); +fseek($fp, 0, SEEK_SET); +fseek($fp, 5, SEEK_SET); +fclose($fp); +echo "Write chain log: " . implode(',', TrackingFilter::$log) . "\n"; + +unlink($file); + +?> +--EXPECT-- +Read chain log: read:0:0 +Write chain log: write:0:0,write:5:0 diff --git a/ext/standard/tests/streams/user_streams_consumed_bug.phpt b/ext/standard/tests/filters/user_streams_consumed_bug.phpt similarity index 100% rename from ext/standard/tests/streams/user_streams_consumed_bug.phpt rename to ext/standard/tests/filters/user_streams_consumed_bug.phpt diff --git a/ext/standard/tests/file/userfilters.phpt b/ext/standard/tests/filters/userfilters.phpt similarity index 100% rename from ext/standard/tests/file/userfilters.phpt rename to ext/standard/tests/filters/userfilters.phpt diff --git a/ext/standard/tests/general_functions/bug43293_1.phpt b/ext/standard/tests/general_functions/bug43293_1.phpt index c1f618f2bd0e..fce2ac482cd8 100644 --- a/ext/standard/tests/general_functions/bug43293_1.phpt +++ b/ext/standard/tests/general_functions/bug43293_1.phpt @@ -21,4 +21,5 @@ array(3) { [2]=> int(3) } -bool(false) +array(0) { +} diff --git a/ext/standard/tests/general_functions/debug_zval_dump_gh19801_memory_leak.phpt b/ext/standard/tests/general_functions/debug_zval_dump_gh19801_memory_leak.phpt new file mode 100644 index 000000000000..cf2f1d444f1d --- /dev/null +++ b/ext/standard/tests/general_functions/debug_zval_dump_gh19801_memory_leak.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-19801 (debug_zval_dump() leak with __debugInfo() that modifies circular references) +--FILE-- +a = null; + gc_collect_cycles(); + return []; + } + }, +]; + +$b = new stdClass; +$b->a = &$a; + +debug_zval_dump($b); +?> +--EXPECTF-- +object(stdClass)#2 (1) refcount(%d){ + ["a"]=> + reference refcount(%d) { + array(1) packed refcount(%d){ + [0]=> + object(class@anonymous)#1 (0) refcount(%d){ + } + } + } +} diff --git a/ext/standard/tests/general_functions/get_defined_constants_basic.phpt b/ext/standard/tests/general_functions/get_defined_constants_basic.phpt index b89cc937aae8..f701945fb0e7 100644 --- a/ext/standard/tests/general_functions/get_defined_constants_basic.phpt +++ b/ext/standard/tests/general_functions/get_defined_constants_basic.phpt @@ -9,7 +9,7 @@ var_dump(gettype(get_defined_constants())); $arr1 = get_defined_constants(false); $arr2 = get_defined_constants(); -var_dump(array_diff($arr1, $arr2)); +var_dump(array_diff_key($arr1, $arr2)); $n1 = count(get_defined_constants()); define("USER_CONSTANT", "test"); diff --git a/ext/standard/tests/general_functions/getservbyname_basic.phpt b/ext/standard/tests/general_functions/getservbyname_basic.phpt index 6d26cfedc385..db08f8e0c3da 100644 --- a/ext/standard/tests/general_functions/getservbyname_basic.phpt +++ b/ext/standard/tests/general_functions/getservbyname_basic.phpt @@ -10,6 +10,9 @@ Simone Gentili (sensorario@gmail.com) if(in_array(PHP_OS_FAMILY, ['BSD', 'Darwin', 'Solaris', 'Linux'])){ if (!file_exists("/etc/services")) die("skip reason: missing /etc/services"); } +if (PHP_OS_FAMILY === 'Solaris') { + die("skip Solaris has incomplete /etc/services"); +} if (getenv('SKIP_MSAN')) die('skip msan missing interceptor for getservbyname()'); ?> --FILE-- diff --git a/ext/standard/tests/general_functions/gettype_settype_variation2.phpt b/ext/standard/tests/general_functions/gettype_settype_variation2.phpt index 12f001e924e4..d7839020299a 100644 --- a/ext/standard/tests/general_functions/gettype_settype_variation2.phpt +++ b/ext/standard/tests/general_functions/gettype_settype_variation2.phpt @@ -424,11 +424,13 @@ int(2147483647) string(7) "integer" -- Iteration 50 -- string(6) "double" +2: The float 2147483649 is not representable as an int, cast occurred bool(true) int(-2147483647) string(7) "integer" -- Iteration 51 -- string(6) "double" +2: The float 1232147483649 is not representable as an int, cast occurred bool(true) int(-508130303) string(7) "integer" @@ -439,6 +441,7 @@ int(85) string(7) "integer" -- Iteration 53 -- string(6) "double" +2: The float 1058513956921 is not representable as an int, cast occurred bool(true) int(1952002105) string(7) "integer" @@ -459,6 +462,7 @@ int(-365) string(7) "integer" -- Iteration 57 -- string(6) "double" +2: The float 80561044571754 is not representable as an int, cast occurred bool(true) int(343000682) string(7) "integer" @@ -819,11 +823,13 @@ int(2147483647) string(7) "integer" -- Iteration 50 -- string(6) "double" +2: The float 2147483649 is not representable as an int, cast occurred bool(true) int(-2147483647) string(7) "integer" -- Iteration 51 -- string(6) "double" +2: The float 1232147483649 is not representable as an int, cast occurred bool(true) int(-508130303) string(7) "integer" @@ -834,6 +840,7 @@ int(85) string(7) "integer" -- Iteration 53 -- string(6) "double" +2: The float 1058513956921 is not representable as an int, cast occurred bool(true) int(1952002105) string(7) "integer" @@ -854,6 +861,7 @@ int(-365) string(7) "integer" -- Iteration 57 -- string(6) "double" +2: The float 80561044571754 is not representable as an int, cast occurred bool(true) int(343000682) string(7) "integer" diff --git a/ext/standard/tests/general_functions/gh20840.phpt b/ext/standard/tests/general_functions/gh20840.phpt new file mode 100644 index 000000000000..35d72cf0fb5d --- /dev/null +++ b/ext/standard/tests/general_functions/gh20840.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-20840 (var_dump() crash with nested objects) +--CREDITS-- +bendrissou +--SKIPIF-- + +--INI-- +zend.max_allowed_stack_size=256K +--FILE-- +next = $newNode; + $node = $newNode; +} + +$buffer = ''; +ob_start(function ($chunk) use (&$buffer) { + $buffer .= $chunk; + $buffer = preg_replace('(\s*object\(Node\)#\d+ \(\d+\) \{\s*)', '', $buffer); + $buffer = preg_replace('(\s*\["next"\]=>\s*)', '', $buffer); + $buffer = preg_replace('(\s*\}\s*)', '', $buffer); +}); +var_dump($firstNode); +ob_end_flush(); +echo $buffer; + +while ($next = $firstNode->next) { + $firstNode->next = $next->next; +} +?> +--EXPECT-- +nesting level too deep diff --git a/ext/standard/tests/general_functions/gh21018.phpt b/ext/standard/tests/general_functions/gh21018.phpt new file mode 100644 index 000000000000..249cfb515aeb --- /dev/null +++ b/ext/standard/tests/general_functions/gh21018.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21018 (header() removes headers with the same prefix) +--INI-- +expose_php=On +--CGI-- +--FILE-- + +--EXPECTF-- +array(3) { + [0]=> + string(%d) "X-Powered-By: PHP/%s" + [1]=> + string(9) "a-test: 1" + [2]=> + string(4) "a: 1" +} diff --git a/ext/standard/tests/general_functions/gh21058.phpt b/ext/standard/tests/general_functions/gh21058.phpt new file mode 100644 index 000000000000..598625a2017e --- /dev/null +++ b/ext/standard/tests/general_functions/gh21058.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-21058 (error_log() crash with null destination and message type 3) +--FILE-- +getMessage(), PHP_EOL; +} +?> +--EXPECT-- +Path must not be empty diff --git a/ext/standard/tests/general_functions/ini_get_all.phpt b/ext/standard/tests/general_functions/ini_get_all.phpt index 2b71b474a013..c54b39ac3325 100644 --- a/ext/standard/tests/general_functions/ini_get_all.phpt +++ b/ext/standard/tests/general_functions/ini_get_all.phpt @@ -33,29 +33,35 @@ array(0) { } array(3) { ["pcre.backtrack_limit"]=> - array(3) { + array(4) { ["global_value"]=> string(7) "1000000" ["local_value"]=> string(7) "1000000" + ["builtin_default_value"]=> + string(7) "1000000" ["access"]=> int(7) } ["pcre.jit"]=> - array(3) { + array(4) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" + ["builtin_default_value"]=> + string(1) "1" ["access"]=> int(7) } ["pcre.recursion_limit"]=> - array(3) { + array(4) { ["global_value"]=> string(6) "100000" ["local_value"]=> string(6) "100000" + ["builtin_default_value"]=> + string(6) "100000" ["access"]=> int(7) } diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt new file mode 100644 index 000000000000..82de8781caa7 --- /dev/null +++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt @@ -0,0 +1,33 @@ +--TEST-- +ini_get_all() exposes the built-in default value independent of configuration and runtime changes +--INI-- +precision=8 +--FILE-- + +--EXPECT-- +string(1) "8" +string(1) "8" +string(2) "14" +string(1) "8" +string(1) "3" +string(2) "14" +Done diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt new file mode 100644 index 000000000000..efd86eb947e4 --- /dev/null +++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt @@ -0,0 +1,33 @@ +--TEST-- +ini_get_all() reports a null built-in default value for a directive that has no compiled-in default +--INI-- +error_append_string=FOO +--FILE-- + +--EXPECT-- +string(3) "FOO" +string(3) "FOO" +NULL +string(3) "FOO" +string(3) "BAR" +NULL +Done diff --git a/ext/standard/tests/general_functions/intval.phpt b/ext/standard/tests/general_functions/intval.phpt index 51d3b128f479..c570d8f36ae5 100644 --- a/ext/standard/tests/general_functions/intval.phpt +++ b/ext/standard/tests/general_functions/intval.phpt @@ -94,13 +94,10 @@ $not_int_types = array ( array(), array(0), array(1), - array(NULL), array(null), array("string"), array(true), - array(TRUE), array(false), - array(FALSE), array(1,2,3,4), array(1 => "One", "two" => 2), @@ -127,12 +124,6 @@ $not_int_types = array ( /* booleans */ true, false, - TRUE, - FALSE, - - /* undefined and unset vars */ - @$unset_var, - @$undefined_var ); @@ -256,9 +247,6 @@ int(1) int(1) int(1) int(1) -int(1) -int(1) -int(1) int(0) int(0) int(0) @@ -279,9 +267,5 @@ int(0) int(0) int(1) int(0) -int(1) -int(0) -int(0) -int(0) --- Done --- diff --git a/ext/standard/tests/general_functions/phpinfo.phpt b/ext/standard/tests/general_functions/phpinfo.phpt index ac7cabd340d8..a7503ec0bc41 100644 --- a/ext/standard/tests/general_functions/phpinfo.phpt +++ b/ext/standard/tests/general_functions/phpinfo.phpt @@ -57,7 +57,7 @@ Environment %r(.*?)%r PHP Variables %r(.*?)%r -PHP License +License %r(.*?)%r bool(true) -- @@ -66,6 +66,6 @@ bool(true) -- phpinfo() -PHP License +License %r(.+?)%r bool(true) diff --git a/ext/standard/tests/general_functions/proc_nice_basic.phpt b/ext/standard/tests/general_functions/proc_nice_basic.phpt index 9e73a7f890b1..107f6d186514 100644 --- a/ext/standard/tests/general_functions/proc_nice_basic.phpt +++ b/ext/standard/tests/general_functions/proc_nice_basic.phpt @@ -9,6 +9,7 @@ Simone Gentili (sensorario@gmail.com) +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +proc_open(): Argument #4 ($cwd) must not contain any null bytes diff --git a/ext/standard/tests/general_functions/proc_open_multiplex.phpt b/ext/standard/tests/general_functions/proc_open_multiplex.phpt index 63e856b29c31..798b5e74c475 100644 --- a/ext/standard/tests/general_functions/proc_open_multiplex.phpt +++ b/ext/standard/tests/general_functions/proc_open_multiplex.phpt @@ -1,5 +1,11 @@ --TEST-- Multiplexing of child output +--SKIPIF-- + --FILE-- getMessage() . "\n"; + } +} + +$var_name = 'PHP_PUTENV_NUL_TEST'; + +foreach ([ + $var_name . "\0SUFFIX=value", + $var_name . "=va\0lue", +] as $assignment) { + try { + putenv($assignment); + } catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; + } +} + +var_dump(getenv($var_name)); + +?> +--EXPECT-- +getenv(): Argument #1 ($name) must not contain any null bytes +getenv(): Argument #1 ($name) must not contain any null bytes +putenv(): Argument #1 ($assignment) must not contain any null bytes +putenv(): Argument #1 ($assignment) must not contain any null bytes +bool(false) diff --git a/ext/standard/tests/general_functions/var_dump_gh19801_memory_leak.phpt b/ext/standard/tests/general_functions/var_dump_gh19801_memory_leak.phpt new file mode 100644 index 000000000000..f0522916de4e --- /dev/null +++ b/ext/standard/tests/general_functions/var_dump_gh19801_memory_leak.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-19801 (var_dump() memory leak with __debugInfo() that modifies circular references) +--FILE-- +a = null; + gc_collect_cycles(); + return []; + } + }, +]; + +$b = new stdClass; +$b->a = &$a; + +var_dump($b); +?> +--EXPECTF-- +object(stdClass)#2 (1) { + ["a"]=> + &array(1) { + [0]=> + object(class@anonymous)#1 (0) { + } + } +} diff --git a/ext/standard/tests/gh20695.phpt b/ext/standard/tests/gh20695.phpt new file mode 100644 index 000000000000..64c81ab9fdb5 --- /dev/null +++ b/ext/standard/tests/gh20695.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-20695 (Assertion failure in normalize_value() when parsing malformed INI input via parse_ini_string()) +--FILE-- + +--EXPECT-- +array(1) { + [8]=> + array(1) { + ["["]=> + int(0) + } +} diff --git a/ext/standard/tests/gh21221.phpt b/ext/standard/tests/gh21221.phpt new file mode 100644 index 000000000000..8435b4803470 --- /dev/null +++ b/ext/standard/tests/gh21221.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-21221: Prevent closing of innerstream of php://temp stream +--CREDITS-- +chongwick +--FILE-- + +--EXPECTF-- +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d diff --git a/ext/standard/tests/http/bug75535.phpt b/ext/standard/tests/http/bug75535.phpt index 94348d1a027a..6f16baa242ff 100644 --- a/ext/standard/tests/http/bug75535.phpt +++ b/ext/standard/tests/http/bug75535.phpt @@ -15,7 +15,7 @@ $responses = array( ['pid' => $pid, 'uri' => $uri] = http_server($responses, $output); var_dump(file_get_contents($uri)); -var_dump($http_response_header); +var_dump(http_get_last_response_headers()); http_server_kill($pid); diff --git a/ext/standard/tests/http/bug80838.phpt b/ext/standard/tests/http/bug80838.phpt index 7171ad173fb6..8e7578ca025d 100644 --- a/ext/standard/tests/http/bug80838.phpt +++ b/ext/standard/tests/http/bug80838.phpt @@ -33,7 +33,8 @@ var_dump(http_get_last_response_headers()); http_server_kill($pid); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 23 NULL array(3) { [0]=> diff --git a/ext/standard/tests/http/gh9316.phpt b/ext/standard/tests/http/gh9316.phpt index 2f4a637f83e3..355769d5db1b 100644 --- a/ext/standard/tests/http/gh9316.phpt +++ b/ext/standard/tests/http/gh9316.phpt @@ -30,7 +30,8 @@ for ($i = 0; $i < count($responses); ++$i) { http_server_kill($pid); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 17 http_get_last_response_headers() before stream layer call: NULL $http_response_header diff --git a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt index 744cff9cc72f..73e1408c370b 100644 --- a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt +++ b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-001.phpt @@ -36,7 +36,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt index bc71fd4e4116..cde5aff0afe1 100644 --- a/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt +++ b/ext/standard/tests/http/ghsa-52jp-hrpf-2jff-002.phpt @@ -36,7 +36,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt index c40123560ef1..0bd496ca72d0 100644 --- a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt +++ b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-001.phpt @@ -33,7 +33,7 @@ $clientCode = <<<'CODE' ]; $ctx = stream_context_create($opts); var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx)))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt index f3302d77c1d6..d470cdda3f5c 100644 --- a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt +++ b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-002.phpt @@ -33,7 +33,7 @@ $clientCode = <<<'CODE' ]; $ctx = stream_context_create($opts); var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx)))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-003.phpt b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-003.phpt index 30d20f855419..594dc8d14e35 100644 --- a/ext/standard/tests/http/ghsa-hgf5-96fm-v528-003.phpt +++ b/ext/standard/tests/http/ghsa-hgf5-96fm-v528-003.phpt @@ -33,7 +33,7 @@ $clientCode = <<<'CODE' ]; $ctx = stream_context_create($opts); var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx)))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt index bb7945ce62d0..471f44745ed3 100644 --- a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt +++ b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-001.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt index 1d0e4fa70a2c..67ce5517ce3c 100644 --- a/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt +++ b/ext/standard/tests/http/ghsa-pcmh-g36c-qc44-002.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-001.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-001.phpt index f935b5a02ca9..94439534d9a5 100644 --- a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-001.phpt +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-001.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-002.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-002.phpt index 078d605b6718..6ad3e1bc2ca3 100644 --- a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-002.phpt +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-002.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-003.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-003.phpt index ad5ddc879cea..497d6d92fbd2 100644 --- a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-003.phpt +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-003.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx))); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt index d0396e819fbd..e6382420954f 100644 --- a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-004.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt index 037d2002cc53..c0ee01671460 100644 --- a/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt +++ b/ext/standard/tests/http/ghsa-v8xr-gpvj-cx9g-005.phpt @@ -32,7 +32,7 @@ $clientCode = <<<'CODE' $ctx = stream_context_create(); stream_context_set_params($ctx, array("notification" => "stream_notification_callback")); var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx)); - var_dump($http_response_header); + var_dump(http_get_last_response_headers()); CODE; include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__); diff --git a/ext/standard/tests/http/http_build_query/gh20583.phpt b/ext/standard/tests/http/http_build_query/gh20583.phpt new file mode 100644 index 000000000000..2d93d3b6f448 --- /dev/null +++ b/ext/standard/tests/http/http_build_query/gh20583.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-20583 (Stack overflow in http_build_query via deep structures) +--SKIPIF-- + +--INI-- +zend.max_allowed_stack_size=256K +--FILE-- + $a]; +} +try { + http_build_query($a, 'p'); +} catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Error: Maximum call stack size reached. diff --git a/ext/standard/tests/http/http_response_header_01.phpt b/ext/standard/tests/http/http_response_header_01.phpt index 4c494f0960ff..324e00adf770 100644 --- a/ext/standard/tests/http/http_response_header_01.phpt +++ b/ext/standard/tests/http/http_response_header_01.phpt @@ -24,7 +24,8 @@ var_dump(http_get_last_response_headers()); http_server_kill($pid); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 14 NULL string(4) "Body" array(3) { diff --git a/ext/standard/tests/http/http_response_header_02.phpt b/ext/standard/tests/http/http_response_header_02.phpt index 56eb2868b6d1..779edfcac1eb 100644 --- a/ext/standard/tests/http/http_response_header_02.phpt +++ b/ext/standard/tests/http/http_response_header_02.phpt @@ -26,7 +26,8 @@ var_dump(http_get_last_response_headers()); http_server_kill($pid); ?> ---EXPECT-- +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 16 NULL string(4) "Body" array(5) { diff --git a/ext/standard/tests/http/http_response_header_03.phpt b/ext/standard/tests/http/http_response_header_03.phpt index f7fa7e00c60a..5bddc304c724 100644 --- a/ext/standard/tests/http/http_response_header_03.phpt +++ b/ext/standard/tests/http/http_response_header_03.phpt @@ -27,6 +27,7 @@ http_server_kill($pid); ?> --EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 16 NULL Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found%a diff --git a/ext/standard/tests/http/http_response_header_04.phpt b/ext/standard/tests/http/http_response_header_04.phpt index a8a285fb7ad9..5cc6920b610c 100644 --- a/ext/standard/tests/http/http_response_header_04.phpt +++ b/ext/standard/tests/http/http_response_header_04.phpt @@ -24,7 +24,9 @@ var_dump(http_get_last_response_headers()); http_server_kill($pid); ?> ---EXPECT-- + +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 14 NULL string(4) "Body" array(2) { diff --git a/ext/standard/tests/http/http_response_header_deprecated_bypass.phpt b/ext/standard/tests/http/http_response_header_deprecated_bypass.phpt new file mode 100644 index 000000000000..91f1957737a6 --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_bypass.phpt @@ -0,0 +1,40 @@ +--TEST-- +Ensure suggested cross-version compatible code for $http_reponse_header provided by the RFC works +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + $pid, 'uri' => $uri] = http_server($responses, $output); + +var_dump(http_get_last_response_headers()); + +$f = file_get_contents($uri); +var_dump($f); + +if (function_exists('http_get_last_response_headers')) { + $http_response_header = http_get_last_response_headers(); +} +var_dump($http_response_header); + +http_server_kill($pid); + +?> +--EXPECT-- +NULL +string(4) "Body" +array(3) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(12) "Some: Header" + [2]=> + string(12) "Some: Header" +} diff --git a/ext/standard/tests/http/http_response_header_deprecated_dynamic_fetch.phpt b/ext/standard/tests/http/http_response_header_deprecated_dynamic_fetch.phpt new file mode 100644 index 000000000000..e6b90355a4c3 --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_dynamic_fetch.phpt @@ -0,0 +1,16 @@ +--TEST-- +$http_response_header dynamic fetch should warn +--FILE-- + +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line %d +string(2) "OK" diff --git a/ext/standard/tests/http/http_response_header_deprecated_multiple_files.phpt b/ext/standard/tests/http/http_response_header_deprecated_multiple_files.phpt new file mode 100644 index 000000000000..826ec554bf9b --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_multiple_files.phpt @@ -0,0 +1,33 @@ +--TEST-- +$http_reponse_header should warn once per file +--SKIPIF-- + +--INI-- +allow_url_fopen=1 +--FILE-- + +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %shttp_response_header_deprecated_multiple_files_1.inc on line %d +string(6) "Body11" +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(13) "Some: Header1" +} + +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %shttp_response_header_deprecated_multiple_files_2.inc on line %d +string(5) "Body2" +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(13) "Some: Header2" +} diff --git a/ext/standard/tests/http/http_response_header_deprecated_multiple_files_1.inc b/ext/standard/tests/http/http_response_header_deprecated_multiple_files_1.inc new file mode 100644 index 000000000000..68d0ff31729a --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_multiple_files_1.inc @@ -0,0 +1,13 @@ + $pid, 'uri' => $uri] = http_server($responses, $output); + +$f = file_get_contents($uri); +var_dump($f); +var_dump($http_response_header); + +http_server_kill($pid); diff --git a/ext/standard/tests/http/http_response_header_deprecated_multiple_files_2.inc b/ext/standard/tests/http/http_response_header_deprecated_multiple_files_2.inc new file mode 100644 index 000000000000..ba00ff7a06be --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_multiple_files_2.inc @@ -0,0 +1,13 @@ + $pid, 'uri' => $uri] = http_server($responses, $output); + +$f = file_get_contents($uri); +var_dump($f); +var_dump($http_response_header); + +http_server_kill($pid); diff --git a/ext/standard/tests/http/http_response_header_deprecated_multiple_op_arrays.phpt b/ext/standard/tests/http/http_response_header_deprecated_multiple_op_arrays.phpt new file mode 100644 index 000000000000..aa2334dad6d7 --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_multiple_op_arrays.phpt @@ -0,0 +1,20 @@ +--TEST-- +$http_reponse_header should warn once per oparray +--FILE-- + +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 4 + +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 9 diff --git a/ext/standard/tests/http/http_response_header_deprecated_nested_op_arrays.phpt b/ext/standard/tests/http/http_response_header_deprecated_nested_op_arrays.phpt new file mode 100644 index 000000000000..0f05e689c341 --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_nested_op_arrays.phpt @@ -0,0 +1,16 @@ +--TEST-- +$http_reponse_header should warn once per oparray even if nested +--FILE-- + +--EXPECTF-- +Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 6 diff --git a/ext/standard/tests/http/http_response_header_deprecated_parameter.phpt b/ext/standard/tests/http/http_response_header_deprecated_parameter.phpt new file mode 100644 index 000000000000..1dd032a30527 --- /dev/null +++ b/ext/standard/tests/http/http_response_header_deprecated_parameter.phpt @@ -0,0 +1,14 @@ +--TEST-- +$http_reponse_header as a parameter name should not warn +--FILE-- + +--EXPECT-- +string(2) "OK" diff --git a/ext/standard/tests/image/bug13213.phpt b/ext/standard/tests/image/bug13213.phpt index 61fe245efed2..dd5821a83035 100644 --- a/ext/standard/tests/image/bug13213.phpt +++ b/ext/standard/tests/image/bug13213.phpt @@ -6,7 +6,7 @@ var_dump(GetImageSize(__DIR__.'/bug13213.jpg')); ?> --EXPECTF-- Warning: getimagesize(): Corrupt JPEG data: 2 extraneous bytes before marker in %s%ebug13213.php on line %d -array(7) { +array(9) { [0]=> int(1) [1]=> @@ -21,4 +21,8 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/bug70052.phpt b/ext/standard/tests/image/bug70052.phpt index 76ebda92b220..252f8921e292 100644 --- a/ext/standard/tests/image/bug70052.phpt +++ b/ext/standard/tests/image/bug70052.phpt @@ -7,7 +7,7 @@ var_dump(getimagesize(__DIR__ . '/bug70052_2.wbmp')); ?> --EXPECT-- bool(false) -array(5) { +array(7) { [0]=> int(3) [1]=> @@ -18,4 +18,8 @@ array(5) { string(20) "width="3" height="3"" ["mime"]=> string(18) "image/vnd.wap.wbmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/bug70096.phpt b/ext/standard/tests/image/bug70096.phpt index 53ceddea06a8..757287d5aed2 100644 --- a/ext/standard/tests/image/bug70096.phpt +++ b/ext/standard/tests/image/bug70096.phpt @@ -11,7 +11,6 @@ if (!function_exists('imagejpeg')) die('skip imagejpeg not available'); $filename = __DIR__ . '/bug70096.jpg'; $im = imagecreatetruecolor(10, 10); imagejpeg($im, $filename); -imagedestroy($im); $data = "\x1C\x02x\x00\x0ATest image" . "\x1C\x02t\x00\x22Copyright 2008-2009, The PHP Group"; $content1 = iptcembed($data, $filename); diff --git a/ext/standard/tests/image/bug71848.phpt b/ext/standard/tests/image/bug71848.phpt index 25c05689e6e9..1c15c87011cf 100644 --- a/ext/standard/tests/image/bug71848.phpt +++ b/ext/standard/tests/image/bug71848.phpt @@ -6,7 +6,7 @@ var_dump(getimagesize(__DIR__ . '/bug71848.jpg', $info)); var_dump(array_keys($info)); ?> --EXPECT-- -array(7) { +array(9) { [0]=> int(8) [1]=> @@ -21,6 +21,10 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(2) { [0]=> diff --git a/ext/standard/tests/image/bug72278.phpt b/ext/standard/tests/image/bug72278.phpt index 074338c18aeb..21079246a5d7 100644 --- a/ext/standard/tests/image/bug72278.phpt +++ b/ext/standard/tests/image/bug72278.phpt @@ -8,7 +8,7 @@ var_dump(getimagesize(FILENAME)); ?> --EXPECTF-- Warning: getimagesize(): Corrupt JPEG data: 3 extraneous bytes before marker in %s%ebug72278.php on line %d -array(7) { +array(9) { [0]=> int(300) [1]=> @@ -23,4 +23,8 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/bug75708.phpt b/ext/standard/tests/image/bug75708.phpt index 3c81c67cf5dd..b1a5ee6116c7 100644 --- a/ext/standard/tests/image/bug75708.phpt +++ b/ext/standard/tests/image/bug75708.phpt @@ -41,7 +41,7 @@ var_dump(getimagesize('fs://bug75708.jpg', $info)); ?> --EXPECT-- -array(7) { +array(9) { [0]=> int(10) [1]=> @@ -56,5 +56,8 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } - diff --git a/ext/standard/tests/image/getimagesize.phpt b/ext/standard/tests/image/getimagesize.phpt index 472be1d25e36..81c4f8dc6b5c 100644 --- a/ext/standard/tests/image/getimagesize.phpt +++ b/ext/standard/tests/image/getimagesize.phpt @@ -23,9 +23,9 @@ GetImageSize() var_dump($result); ?> --EXPECT-- -array(17) { +array(18) { ["test-1pix.bmp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -38,9 +38,13 @@ array(17) { int(24) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test12pix.webp"]=> - array(6) { + array(8) { [0]=> int(4) [1]=> @@ -53,9 +57,13 @@ array(17) { int(8) ["mime"]=> string(10) "image/webp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1bpix.bmp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -68,9 +76,13 @@ array(17) { int(32) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.avif"]=> - array(7) { + array(9) { [0]=> int(102) [1]=> @@ -85,9 +97,13 @@ array(17) { int(4) ["mime"]=> string(10) "image/avif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.bmp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -100,9 +116,13 @@ array(17) { int(24) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.jp2"]=> - array(7) { + array(9) { [0]=> int(1) [1]=> @@ -117,9 +137,13 @@ array(17) { int(3) ["mime"]=> string(9) "image/jp2" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.jpc"]=> - array(7) { + array(9) { [0]=> int(1) [1]=> @@ -134,9 +158,13 @@ array(17) { int(3) ["mime"]=> string(24) "application/octet-stream" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test1pix.jpg"]=> - array(7) { + array(9) { [0]=> int(1) [1]=> @@ -151,9 +179,13 @@ array(17) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test2pix.gif"]=> - array(7) { + array(9) { [0]=> int(2) [1]=> @@ -168,9 +200,13 @@ array(17) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test3llpix.webp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -183,9 +219,13 @@ array(17) { int(8) ["mime"]=> string(10) "image/webp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test3pix.webp"]=> - array(6) { + array(8) { [0]=> int(1) [1]=> @@ -198,9 +238,13 @@ array(17) { int(8) ["mime"]=> string(10) "image/webp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.gif"]=> - array(7) { + array(9) { [0]=> int(4) [1]=> @@ -215,9 +259,34 @@ array(17) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" + } + ["test4pix.heic"]=> + array(9) { + [0]=> + int(54) + [1]=> + int(84) + [2]=> + int(20) + [3]=> + string(22) "width="54" height="84"" + ["bits"]=> + int(8) + ["channels"]=> + int(3) + ["mime"]=> + string(10) "image/heif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.iff"]=> - array(6) { + array(8) { [0]=> int(4) [1]=> @@ -230,9 +299,13 @@ array(17) { int(4) ["mime"]=> string(9) "image/iff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.png"]=> - array(6) { + array(8) { [0]=> int(4) [1]=> @@ -245,9 +318,13 @@ array(17) { int(4) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.psd"]=> - array(5) { + array(7) { [0]=> int(4) [1]=> @@ -258,9 +335,13 @@ array(17) { string(20) "width="4" height="1"" ["mime"]=> string(9) "image/psd" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.swf"]=> - array(5) { + array(7) { [0]=> int(550) [1]=> @@ -271,9 +352,13 @@ array(17) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ["test4pix.tiff"]=> - array(5) { + array(7) { [0]=> int(4) [1]=> @@ -284,5 +369,9 @@ array(17) { string(20) "width="4" height="1"" ["mime"]=> string(10) "image/tiff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } } diff --git a/ext/standard/tests/image/getimagesize_246x247.phpt b/ext/standard/tests/image/getimagesize_246x247.phpt index c716ac3aebc0..abf5bec0412a 100644 --- a/ext/standard/tests/image/getimagesize_246x247.phpt +++ b/ext/standard/tests/image/getimagesize_246x247.phpt @@ -25,7 +25,7 @@ GetImageSize() with 246x247 pixels --EXPECT-- array(1) { ["246x247.png"]=> - array(6) { + array(8) { [0]=> int(246) [1]=> @@ -38,5 +38,9 @@ array(1) { int(4) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } } diff --git a/ext/standard/tests/image/getimagesize_256_ico.phpt b/ext/standard/tests/image/getimagesize_256_ico.phpt index 770985c6aec5..7f1fff07a3a2 100644 --- a/ext/standard/tests/image/getimagesize_256_ico.phpt +++ b/ext/standard/tests/image/getimagesize_256_ico.phpt @@ -9,7 +9,7 @@ var_dump(getimagesize(__DIR__ . "/32x256.ico")); ===DONE=== --EXPECT-- *** Testing getimagesize() : 256px ico *** -array(6) { +array(8) { [0]=> int(32) [1]=> @@ -22,5 +22,9 @@ array(6) { int(8) ["mime"]=> string(24) "image/vnd.microsoft.icon" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } ===DONE=== diff --git a/ext/standard/tests/image/getimagesize_384x385.phpt b/ext/standard/tests/image/getimagesize_384x385.phpt index 57dc8a719215..69705080cad0 100644 --- a/ext/standard/tests/image/getimagesize_384x385.phpt +++ b/ext/standard/tests/image/getimagesize_384x385.phpt @@ -25,7 +25,7 @@ GetImageSize() with 384x385 pixels --EXPECT-- array(1) { ["384x385.png"]=> - array(6) { + array(8) { [0]=> int(384) [1]=> @@ -38,5 +38,9 @@ array(1) { int(1) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } } diff --git a/ext/standard/tests/image/getimagesize_basic.phpt b/ext/standard/tests/image/getimagesize_basic.phpt index f1a6d108d31b..3dd1823437c2 100644 --- a/ext/standard/tests/image/getimagesize_basic.phpt +++ b/ext/standard/tests/image/getimagesize_basic.phpt @@ -44,7 +44,7 @@ foreach($imagetype_filenames as $key => $filename) { *** Testing getimagesize() : basic functionality *** -- GIF image file (200x100.gif) -- -array(7) { +array(9) { [0]=> int(200) [1]=> @@ -59,12 +59,16 @@ array(7) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- JPEG image file (200x100.jpg) -- -array(7) { +array(9) { [0]=> int(200) [1]=> @@ -79,6 +83,10 @@ array(7) { int(3) ["mime"]=> string(10) "image/jpeg" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(1) { ["APP0"]=> @@ -86,7 +94,7 @@ array(1) { } -- PNG image file (200x100.png) -- -array(6) { +array(8) { [0]=> int(200) [1]=> @@ -99,12 +107,16 @@ array(6) { int(8) ["mime"]=> string(9) "image/png" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- SWF image file (200x100.swf) -- -array(5) { +array(7) { [0]=> int(200) [1]=> @@ -115,12 +127,16 @@ array(5) { string(24) "width="200" height="100"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- BMP image file (200x100.bmp) -- -array(6) { +array(8) { [0]=> int(200) [1]=> @@ -133,12 +149,16 @@ array(6) { int(24) ["mime"]=> string(9) "image/bmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- TIFF intel byte order image file (200x100.tiff) -- -array(5) { +array(7) { [0]=> int(200) [1]=> @@ -149,12 +169,16 @@ array(5) { string(24) "width="200" height="100"" ["mime"]=> string(10) "image/tiff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- JPC image file (test1pix.jpc) -- -array(7) { +array(9) { [0]=> int(1) [1]=> @@ -169,12 +193,16 @@ array(7) { int(3) ["mime"]=> string(24) "application/octet-stream" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- JP2 image file (test1pix.jp2) -- -array(7) { +array(9) { [0]=> int(1) [1]=> @@ -189,12 +217,16 @@ array(7) { int(3) ["mime"]=> string(9) "image/jp2" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } -- IFF image file (test4pix.iff) -- -array(6) { +array(8) { [0]=> int(4) [1]=> @@ -207,6 +239,10 @@ array(6) { int(4) ["mime"]=> string(9) "image/iff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_swc.phpt b/ext/standard/tests/image/getimagesize_swc.phpt index 7dff107d477e..f5031e7a223c 100644 --- a/ext/standard/tests/image/getimagesize_swc.phpt +++ b/ext/standard/tests/image/getimagesize_swc.phpt @@ -13,7 +13,7 @@ if (!defined("IMAGETYPE_SWC")) { var_dump(getimagesize(__DIR__ . "/test13pix.swf")); ?> --EXPECT-- -array(5) { +array(7) { [0]=> int(550) [1]=> @@ -24,4 +24,8 @@ array(5) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/getimagesize_tif_mm.phpt b/ext/standard/tests/image/getimagesize_tif_mm.phpt index cd6f32f4d378..58047f6134dc 100644 --- a/ext/standard/tests/image/getimagesize_tif_mm.phpt +++ b/ext/standard/tests/image/getimagesize_tif_mm.phpt @@ -9,7 +9,7 @@ var_dump($arr); ?> --EXPECT-- *** Testing getimagesize() : tiff_mm format *** -array(5) { +array(7) { [0]=> int(2) [1]=> @@ -20,6 +20,10 @@ array(5) { string(20) "width="2" height="2"" ["mime"]=> string(10) "image/tiff" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_variation4.phpt b/ext/standard/tests/image/getimagesize_variation4.phpt index 658ce84d518c..49b924ffe77b 100644 --- a/ext/standard/tests/image/getimagesize_variation4.phpt +++ b/ext/standard/tests/image/getimagesize_variation4.phpt @@ -17,7 +17,7 @@ var_dump( $info ); ?> --EXPECT-- *** Testing getimagesize() : variation *** -array(5) { +array(7) { [0]=> int(550) [1]=> @@ -28,6 +28,10 @@ array(5) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_variation_005.phpt b/ext/standard/tests/image/getimagesize_variation_005.phpt index 8e471e50a23a..c6d083b23b5e 100644 --- a/ext/standard/tests/image/getimagesize_variation_005.phpt +++ b/ext/standard/tests/image/getimagesize_variation_005.phpt @@ -17,7 +17,7 @@ var_dump( $info ); ?> --EXPECT-- *** Testing getimagesize() : basic functionality *** -array(5) { +array(7) { [0]=> int(550) [1]=> @@ -28,6 +28,10 @@ array(5) { string(24) "width="550" height="400"" ["mime"]=> string(29) "application/x-shockwave-flash" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_wbmp.phpt b/ext/standard/tests/image/getimagesize_wbmp.phpt index 0b0ebe52347d..97151d841246 100644 --- a/ext/standard/tests/image/getimagesize_wbmp.phpt +++ b/ext/standard/tests/image/getimagesize_wbmp.phpt @@ -9,7 +9,7 @@ var_dump($arr); ?> --EXPECT-- *** Testing getimagesize() : wbmp format *** -array(5) { +array(7) { [0]=> int(75) [1]=> @@ -20,6 +20,10 @@ array(5) { string(22) "width="75" height="50"" ["mime"]=> string(18) "image/vnd.wap.wbmp" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesize_xbm.phpt b/ext/standard/tests/image/getimagesize_xbm.phpt index 5ecd6ad20634..4f7f7965dd65 100644 --- a/ext/standard/tests/image/getimagesize_xbm.phpt +++ b/ext/standard/tests/image/getimagesize_xbm.phpt @@ -9,7 +9,7 @@ var_dump($arr); ?> --EXPECT-- *** Testing getimagesize() : xbm format *** -array(5) { +array(7) { [0]=> int(75) [1]=> @@ -20,6 +20,10 @@ array(5) { string(22) "width="75" height="50"" ["mime"]=> string(9) "image/xbm" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } array(0) { } diff --git a/ext/standard/tests/image/getimagesizefromstring1.phpt b/ext/standard/tests/image/getimagesizefromstring1.phpt index 6202b38e8965..0037c292f700 100644 --- a/ext/standard/tests/image/getimagesizefromstring1.phpt +++ b/ext/standard/tests/image/getimagesizefromstring1.phpt @@ -14,7 +14,7 @@ var_dump($i1); var_dump($i2); ?> --EXPECT-- -array(7) { +array(9) { [0]=> int(120) [1]=> @@ -29,8 +29,12 @@ array(7) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } -array(7) { +array(9) { [0]=> int(120) [1]=> @@ -45,4 +49,8 @@ array(7) { int(3) ["mime"]=> string(9) "image/gif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" } diff --git a/ext/standard/tests/image/gh20201.avif b/ext/standard/tests/image/gh20201.avif new file mode 100644 index 000000000000..3cf1ffdec181 Binary files /dev/null and b/ext/standard/tests/image/gh20201.avif differ diff --git a/ext/standard/tests/image/gh20201.phpt b/ext/standard/tests/image/gh20201.phpt new file mode 100644 index 000000000000..272eb1d8dd16 --- /dev/null +++ b/ext/standard/tests/image/gh20201.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-20201 (AVIF images misdetected as HEIF after introducing HEIF support in getimagesize()) +--FILE-- + +--EXPECT-- +array(9) { + [0]=> + int(8) + [1]=> + int(8) + [2]=> + int(19) + [3]=> + string(20) "width="8" height="8"" + ["bits"]=> + int(8) + ["channels"]=> + int(3) + ["mime"]=> + string(10) "image/avif" + ["width_unit"]=> + string(2) "px" + ["height_unit"]=> + string(2) "px" +} diff --git a/ext/standard/tests/image/gh20582.phpt b/ext/standard/tests/image/gh20582.phpt new file mode 100644 index 000000000000..499f70e37260 --- /dev/null +++ b/ext/standard/tests/image/gh20582.phpt @@ -0,0 +1,54 @@ +--TEST-- +GH-20582 (Heap Buffer Overflow in iptcembed) +--CREDITS-- +Nikita Sveshnikov (Positive Technologies) +ndossche +--SKIPIF-- + +--FILE-- + STDIN, + 1 => STDOUT, + 2 => STDOUT, +); +$pipes = []; +$proc = proc_open([PHP_BINARY, '-n', '-r', "var_dump(iptcembed('A', '$pipe'));"], $descriptorspec, $pipes); + +// Blocks until a reader opens it +$fp = fopen($pipe, 'wb') or die("Failed to open FIFO"); + +// Write header +$data = "\xFF\xD8"; // SOI marker +$data .= "\xFF\xE0\x00\x10"; // APP0 marker (JFIF) +$data .= "JFIF" . str_repeat("\x00", 9); +$data .= "\xFF\xDA\x00\x08"; // SOS marker +$data .= str_repeat("\x00", 6); +fwrite($fp, $data); + +// Write garbage +fwrite($fp, str_repeat("A", 5120)); + +fclose($fp); + +?> +--CLEAN-- + +--EXPECTF-- +string(1055) "%0JFIF%0%0%0%0%0%0%0%0%0%0Photoshop 3.0%08BIM%0%0%0%0%0A%0%0%0%0%0%0%0%0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" diff --git a/ext/standard/tests/image/gh20584.phpt b/ext/standard/tests/image/gh20584.phpt new file mode 100644 index 000000000000..d117f2182026 --- /dev/null +++ b/ext/standard/tests/image/gh20584.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-20584 (Information Leak of Memory) +--CREDITS-- +Nikita Sveshnikov (Positive Technologies) +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) diff --git a/ext/standard/tests/image/image_type_to_extension.phpt b/ext/standard/tests/image/image_type_to_extension.phpt index 9b0d991d070f..3f3e5f280511 100644 --- a/ext/standard/tests/image/image_type_to_extension.phpt +++ b/ext/standard/tests/image/image_type_to_extension.phpt @@ -25,6 +25,7 @@ image_type_to_extension() "IMAGETYPE_XBM" => IMAGETYPE_XBM, "IMAGETYPE_WEBP" => IMAGETYPE_WEBP, "IMAGETYPE_AVIF" => IMAGETYPE_AVIF, + "IMAGETYPE_HEIF" => IMAGETYPE_HEIF, ); foreach($constants as $name => $constant) { printf("Constant: %s\n\tWith dot: %s\n\tWithout dot: %s\n", $name, image_type_to_extension($constant), image_type_to_extension($constant, false)); @@ -89,6 +90,9 @@ Constant: IMAGETYPE_WEBP Constant: IMAGETYPE_AVIF With dot: .avif Without dot: avif +Constant: IMAGETYPE_HEIF + With dot: .heif + Without dot: heif bool(false) bool(false) Done diff --git a/ext/standard/tests/image/image_type_to_mime_type.phpt b/ext/standard/tests/image/image_type_to_mime_type.phpt index 5877efe531fd..0102955babe7 100644 --- a/ext/standard/tests/image/image_type_to_mime_type.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type.phpt @@ -24,7 +24,7 @@ image_type_to_mime_type() var_dump($result); ?> --EXPECT-- -array(17) { +array(18) { ["test-1pix.bmp"]=> string(9) "image/bmp" ["test12pix.webp"]=> @@ -49,6 +49,8 @@ array(17) { string(10) "image/webp" ["test4pix.gif"]=> string(9) "image/gif" + ["test4pix.heic"]=> + string(10) "image/heif" ["test4pix.iff"]=> string(9) "image/iff" ["test4pix.png"]=> diff --git a/ext/standard/tests/image/image_type_to_mime_type_basic.phpt b/ext/standard/tests/image/image_type_to_mime_type_basic.phpt index bf5a1ee25099..a393c3e83dc2 100644 --- a/ext/standard/tests/image/image_type_to_mime_type_basic.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type_basic.phpt @@ -21,8 +21,10 @@ $image_types = array ( IMAGETYPE_IFF, IMAGETYPE_WBMP, IMAGETYPE_JPEG2000, + IMAGETYPE_HEIF, IMAGETYPE_XBM, - IMAGETYPE_WEBP + IMAGETYPE_WEBP, + IMAGETYPE_HEIF, ); foreach($image_types as $image_type) { @@ -49,7 +51,9 @@ string(24) "application/octet-stream" string(9) "image/iff" string(18) "image/vnd.wap.wbmp" string(24) "application/octet-stream" +string(10) "image/heif" string(9) "image/xbm" string(10) "image/webp" +string(10) "image/heif" Done image_type_to_mime_type() test diff --git a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt index fc17cb5ecd94..8bd62188d216 100644 --- a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt @@ -1,78 +1,84 @@ --TEST-- -image_type_to_mime_type() (passinf equivalent integer values) +image_type_to_mime_type() (passing equivalent integer values) --CREDITS-- Sanjay Mantoor --FILE-- ---EXPECTREGEX-- -\*\*\* Testing image_type_to_mime_type\(\) : usage variations \*\*\* +--EXPECT-- +*** Testing image_type_to_mime_type() : usage variations *** -- Iteration 0 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 1 -- -string\(9\) "image\/gif" +string(9) "image/gif" -- Iteration 2 -- -string\(10\) "image\/jpeg" +string(10) "image/jpeg" -- Iteration 3 -- -string\(9\) "image\/png" +string(9) "image/png" -- Iteration 4 -- -string\(29\) "application\/x-shockwave-flash" +string(29) "application/x-shockwave-flash" -- Iteration 5 -- -string\(9\) "image\/psd" +string(9) "image/psd" -- Iteration 6 -- -string\(9\) "image\/bmp" +string(9) "image/bmp" -- Iteration 7 -- -string\(10\) "image\/tiff" +string(10) "image/tiff" -- Iteration 8 -- -string\(10\) "image\/tiff" +string(10) "image/tiff" -- Iteration 9 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 10 -- -string\(9\) "image\/jp2" +string(9) "image/jp2" -- Iteration 11 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 12 -- -string\(24\) "application\/octet-stream" +string(24) "application/octet-stream" -- Iteration 13 -- -string\(2[49]\) "application\/(x-shockwave-flash|octet-stream)" +string(29) "application/x-shockwave-flash" -- Iteration 14 -- -string\(9\) "image\/iff" +string(9) "image/iff" -- Iteration 15 -- -string\(18\) "image\/vnd.wap.wbmp" +string(18) "image/vnd.wap.wbmp" -- Iteration 16 -- -string\(9\) "image\/xbm" +string(9) "image/xbm" -- Iteration 17 -- -string\(24\) "image\/vnd.microsoft.icon" +string(24) "image/vnd.microsoft.icon" -- Iteration 18 -- -string\(10\) "image\/webp" +string(10) "image/webp" -- Iteration 19 -- -string\(10\) "image\/avif" +string(10) "image/avif" -- Iteration 20 -- -string\(24\) "application\/octet-stream" +string(10) "image/heif" + +-- Iteration 999 -- +string(24) "application/octet-stream" diff --git a/ext/standard/tests/image/test4pix.heic b/ext/standard/tests/image/test4pix.heic new file mode 100644 index 000000000000..93ca3ed1faf9 Binary files /dev/null and b/ext/standard/tests/image/test4pix.heic differ diff --git a/ext/standard/tests/mail/gh10990.phpt b/ext/standard/tests/mail/gh10990.phpt index 4f74c17c22bd..ee28f3031385 100644 --- a/ext/standard/tests/mail/gh10990.phpt +++ b/ext/standard/tests/mail/gh10990.phpt @@ -13,5 +13,6 @@ $from = 'test@example.com'; $headers = ['From' => &$from]; var_dump(mail('test@example.com', 'Test', 'Test', $headers)); ?> ---EXPECT-- +--EXPECTF-- +Warning: mail(): Sendmail exited with non-zero exit code 127 in %sgh10990.php on line %d bool(false) diff --git a/ext/standard/tests/mail/gh19188_cr_lf_mode.phpt b/ext/standard/tests/mail/gh19188_cr_lf_mode.phpt new file mode 100644 index 000000000000..15c9aa2aa28f --- /dev/null +++ b/ext/standard/tests/mail/gh19188_cr_lf_mode.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-19188: new INI mail.cr_lf_mode +--INI-- +sendmail_path={MAIL:gh19188_cr_lf_mode.out} +mail.cr_lf_mode=crlf +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +CRLF mode: +int(5) +int(0) diff --git a/ext/standard/tests/mail/gh19188_invalid_mode.phpt b/ext/standard/tests/mail/gh19188_invalid_mode.phpt new file mode 100644 index 000000000000..fb1baa3d4702 --- /dev/null +++ b/ext/standard/tests/mail/gh19188_invalid_mode.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-19188: mail.cr_lf_mode runtime changes should fail +--FILE-- + +--EXPECT-- +bool(false) +string(4) "crlf" +bool(false) +string(4) "crlf" +bool(false) +string(4) "crlf" +bool(false) +string(4) "crlf" diff --git a/ext/standard/tests/mail/gh19188_lf_mode.phpt b/ext/standard/tests/mail/gh19188_lf_mode.phpt new file mode 100644 index 000000000000..bd69cc42b62d --- /dev/null +++ b/ext/standard/tests/mail/gh19188_lf_mode.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-19188: mail.cr_lf_mode=lf +--INI-- +sendmail_path={MAIL:gh19188_lf_mode.out} +mail.cr_lf_mode=lf +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +LF mode: +int(0) +int(6) diff --git a/ext/standard/tests/mail/gh19188_mixed_mode.phpt b/ext/standard/tests/mail/gh19188_mixed_mode.phpt new file mode 100644 index 000000000000..fa5eb63bd4fe --- /dev/null +++ b/ext/standard/tests/mail/gh19188_mixed_mode.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-19188: mail.cr_lf_mode=mixed +--INI-- +sendmail_path={MAIL:gh19188_mixed_mode.out} +mail.cr_lf_mode=mixed +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +Mixed mode: +int(5) diff --git a/ext/standard/tests/mail/gh19188_os_mode_unix.phpt b/ext/standard/tests/mail/gh19188_os_mode_unix.phpt new file mode 100644 index 000000000000..b365e3a671b0 --- /dev/null +++ b/ext/standard/tests/mail/gh19188_os_mode_unix.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-19188: mail.cr_lf_mode=os (Unix) +--SKIPIF-- + +--INI-- +sendmail_path={MAIL:gh19188_os_mode.out} +mail.cr_lf_mode=os +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +OS mode: +CRLF count: int(0) +LF-only count: int(5) diff --git a/ext/standard/tests/mail/gh19188_os_mode_windows.phpt b/ext/standard/tests/mail/gh19188_os_mode_windows.phpt new file mode 100644 index 000000000000..c3c3e7c08ee9 --- /dev/null +++ b/ext/standard/tests/mail/gh19188_os_mode_windows.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-19188: mail.cr_lf_mode=os (Windows) +--SKIPIF-- + +--INI-- +sendmail_path={MAIL:gh19188_os_mode.out} +mail.cr_lf_mode=os +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +OS mode: +CRLF count: int(5) +LF-only count: int(0) diff --git a/ext/standard/tests/mail/gh20257.phpt b/ext/standard/tests/mail/gh20257.phpt new file mode 100644 index 000000000000..68374173413f --- /dev/null +++ b/ext/standard/tests/mail/gh20257.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-20257: heap overflow with empty message and mail.cr_lf_mode=lf set +--INI-- +sendmail_path="exit 1" +mail.cr_lf_mode=lf +--CREDITS-- +YuanchengJiang +--FILE-- + +--EXPECTF-- + +Warning: mail(): Sendmail exited with non-zero exit code 1 in %s on line %d +bool(false) diff --git a/ext/standard/tests/mail/gh20776.phpt b/ext/standard/tests/mail/gh20776.phpt new file mode 100644 index 000000000000..aec68c471920 --- /dev/null +++ b/ext/standard/tests/mail/gh20776.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-20776: mail() memory leak when header array contains numeric keys +--FILE-- + 'Value', 5 => 'invalid key'])); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +TypeError: Header name cannot be numeric, 5 given diff --git a/ext/standard/tests/mail/mail_basic2.phpt b/ext/standard/tests/mail/mail_basic2.phpt index 44d8d86310b0..96a5a4a10a11 100644 --- a/ext/standard/tests/mail/mail_basic2.phpt +++ b/ext/standard/tests/mail/mail_basic2.phpt @@ -20,14 +20,17 @@ $message = 'A Message'; $additional_headers = 'KHeaders'; $additional_parameters = "-n"; $outFile = "/tmp/php_test_mailBasic2.out"; -@unlink($outFile); echo "-- extra parameters --\n"; // Calling mail() with all possible arguments var_dump( mail($to, $subject, $message, $additional_headers, $additional_parameters) ); echo file_get_contents($outFile); -unlink($outFile); + +?> +--CLEAN-- + --EXPECTF-- *** Testing mail() : basic functionality *** diff --git a/ext/standard/tests/mail/mail_basic5.phpt b/ext/standard/tests/mail/mail_basic5.phpt index b427fbeb670a..73be1e1eaa1a 100644 --- a/ext/standard/tests/mail/mail_basic5.phpt +++ b/ext/standard/tests/mail/mail_basic5.phpt @@ -20,7 +20,9 @@ $message = 'A Message'; echo "-- failure --\n"; var_dump( mail($to, $subject, $message) ); ?> ---EXPECT-- +--EXPECTF-- *** Testing mail() : basic functionality *** -- failure -- + +Warning: mail(): Sendmail exited with non-zero exit code 1 in %smail_basic5.php on line %d bool(false) diff --git a/ext/standard/tests/mail/mail_variation1.phpt b/ext/standard/tests/mail/mail_variation1.phpt index 75adc6282235..16779bcf455e 100644 --- a/ext/standard/tests/mail/mail_variation1.phpt +++ b/ext/standard/tests/mail/mail_variation1.phpt @@ -17,6 +17,8 @@ $subject = 'Test Subject'; $message = 'A Message'; var_dump( mail($to, $subject, $message) ); ?> ---EXPECT-- +--EXPECTF-- *** Testing mail() : variation *** + +Warning: mail(): Sendmail exited with non-zero exit code 127 in %smail_variation1.php on line %d bool(false) diff --git a/ext/standard/tests/mail/mail_variation3.phpt b/ext/standard/tests/mail/mail_variation3.phpt new file mode 100644 index 000000000000..03908242d88e --- /dev/null +++ b/ext/standard/tests/mail/mail_variation3.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test mail() function : variation sendmail temp fail +--INI-- +sendmail_path=exit 75 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing mail() : variation *** +bool(true) diff --git a/ext/standard/tests/mail/mail_variation4.phpt b/ext/standard/tests/mail/mail_variation4.phpt new file mode 100644 index 000000000000..c761e3bdbd19 --- /dev/null +++ b/ext/standard/tests/mail/mail_variation4.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test mail() function : variation sigterm +--INI-- +sendmail_path="kill \$\$" +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing mail() : variation *** + +Warning: mail(): Sendmail killed by signal %d (%s) in %smail_variation4.php on line %d +bool(false) diff --git a/ext/standard/tests/mail/mail_variation5.phpt b/ext/standard/tests/mail/mail_variation5.phpt new file mode 100644 index 000000000000..9e430f40c5df --- /dev/null +++ b/ext/standard/tests/mail/mail_variation5.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test mail() function : variation non-zero exit +--INI-- +sendmail_path="exit 123" +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing mail() : variation *** + +Warning: mail(): Sendmail exited with non-zero exit code 123 in %smail_variation5.php on line %d +bool(false) diff --git a/ext/standard/tests/math/bug30695.phpt b/ext/standard/tests/math/bug30695.phpt index 82771d0e0ab9..a2ac79c11262 100644 --- a/ext/standard/tests/math/bug30695.phpt +++ b/ext/standard/tests/math/bug30695.phpt @@ -53,22 +53,22 @@ if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); echo "\n", toUTF8(65), "\n", toUTF8(233), "\n", toUTF8(1252), "\n", toUTF8(20095), "\n"; ?> --EXPECTF-- -Deprecated: Implicit conversion from float 4294967168 to int loses precision in %s on line %d +Warning: The float 4294967168 is not representable as an int, cast occurred in %s on line %d A -Deprecated: Implicit conversion from float 4294967168 to int loses precision in %s on line %d +Warning: The float 4294967168 is not representable as an int, cast occurred in %s on line %d -Deprecated: Implicit conversion from float 4294965248 to int loses precision in %s on line %d +Warning: The float 4294965248 is not representable as an int, cast occurred in %s on line %d é -Deprecated: Implicit conversion from float 4294967168 to int loses precision in %s on line %d +Warning: The float 4294967168 is not representable as an int, cast occurred in %s on line %d -Deprecated: Implicit conversion from float 4294965248 to int loses precision in %s on line %d +Warning: The float 4294965248 is not representable as an int, cast occurred in %s on line %d Ӥ -Deprecated: Implicit conversion from float 4294967168 to int loses precision in %s on line %d +Warning: The float 4294967168 is not representable as an int, cast occurred in %s on line %d -Deprecated: Implicit conversion from float 4294965248 to int loses precision in %s on line %d +Warning: The float 4294965248 is not representable as an int, cast occurred in %s on line %d -Deprecated: Implicit conversion from float 4294901760 to int loses precision in %s on line %d +Warning: The float 4294901760 is not representable as an int, cast occurred in %s on line %d 乿 diff --git a/ext/standard/tests/math/clamp.phpt b/ext/standard/tests/math/clamp.phpt new file mode 100644 index 000000000000..beb4c8d53148 --- /dev/null +++ b/ext/standard/tests/math/clamp.phpt @@ -0,0 +1,104 @@ +--TEST-- +clamp() tests +--INI-- +precision=14 +date.timezone=UTC +zend.assertions=1 +--FILE-- +getMessage(), "\n"; + } + + try { + var_dump(make_clamp_fcc()($value, $min, $max)); + } catch (ValueError $error) { + echo $error->getMessage(), "\n"; + } +} + +var_dump(check_clamp_result(2, 1, 3)); +var_dump(check_clamp_result(0, 1, 3)); +var_dump(check_clamp_result(6, 1, 3)); +var_dump(check_clamp_result(2, 1.3, 3.4)); +var_dump(check_clamp_result(2.5, 1, 3)); +var_dump(check_clamp_result(2.5, 1.3, 3.4)); +var_dump(check_clamp_result(0, 1.3, 3.4)); +var_dump(check_clamp_result(M_PI, -INF, INF)); +var_dump(check_clamp_result(NAN, 4, 6)); +var_dump(check_clamp_result("a", "c", "g")); +var_dump(check_clamp_result("d", "c", "g")); +echo check_clamp_result('2025-08-01', '2025-08-15', '2025-09-15'), "\n"; +echo check_clamp_result('2025-08-20', '2025-08-15', '2025-09-15'), "\n"; +echo check_clamp_result(new \DateTimeImmutable('2025-08-01'), new \DateTimeImmutable('2025-08-15'), new \DateTimeImmutable('2025-09-15'))->format('Y-m-d'), "\n"; +echo check_clamp_result(new \DateTimeImmutable('2025-08-20'), new \DateTimeImmutable('2025-08-15'), new \DateTimeImmutable('2025-09-15'))->format('Y-m-d'), "\n"; +var_dump(check_clamp_result(null, -1, 1)); +var_dump(check_clamp_result(null, 1, 3)); +var_dump(check_clamp_result(null, -3, -1)); +var_dump(check_clamp_result(-9999, null, 10)); +var_dump(check_clamp_result(12, null, 10)); + +$a = new \InvalidArgumentException('a'); +$b = new \RuntimeException('b'); +$c = new \LogicException('c'); +echo check_clamp_result($a, $b, $c)::class, "\n"; +echo check_clamp_result($b, $a, $c)::class, "\n"; +echo check_clamp_result($c, $a, $b)::class, "\n"; + +check_clamp_exception(4, NAN, 6); +check_clamp_exception(7, 6, NAN); +check_clamp_exception(1, 3, 2); +check_clamp_exception(-9999, 5, null); +check_clamp_exception(12, -5, null); + +?> +--EXPECT-- +int(2) +int(1) +int(3) +int(2) +float(2.5) +float(2.5) +float(1.3) +float(3.141592653589793) +float(NAN) +string(1) "c" +string(1) "d" +2025-08-15 +2025-08-20 +2025-08-15 +2025-08-20 +int(-1) +int(1) +int(-3) +int(-9999) +int(10) +InvalidArgumentException +RuntimeException +LogicException +clamp(): Argument #2 ($min) must not be NAN +clamp(): Argument #2 ($min) must not be NAN +clamp(): Argument #3 ($max) must not be NAN +clamp(): Argument #3 ($max) must not be NAN +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) +clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max) diff --git a/ext/standard/tests/math/fpow.phpt b/ext/standard/tests/math/fpow.phpt index 3f3c64862e81..524051ba26c4 100644 --- a/ext/standard/tests/math/fpow.phpt +++ b/ext/standard/tests/math/fpow.phpt @@ -24,13 +24,20 @@ $numbers = [ NAN, ]; +function safe_to_string(int|float $number): string { + if (is_nan($number)) { + return 'NAN'; + } + return $number; +} + foreach ($numbers as $base) { foreach ($numbers as $exp) { - print str_pad($base, 4, " ", STR_PAD_LEFT) . - " ** " . - str_pad($exp, 4) . - " = " . - fpow($base, $exp) . + echo str_pad(safe_to_string($base), 4, " ", STR_PAD_LEFT), + " ** ", + str_pad(safe_to_string($exp), 4), + " = ", + safe_to_string(fpow($base, $exp)), PHP_EOL; } } diff --git a/ext/standard/tests/math/pi_basic.phpt b/ext/standard/tests/math/pi_basic.phpt index 10814ae8e819..acb95ceb62e7 100644 --- a/ext/standard/tests/math/pi_basic.phpt +++ b/ext/standard/tests/math/pi_basic.phpt @@ -7,7 +7,7 @@ precision=14 echo pi(), "\n"; echo M_PI, "\n"; // N.B pi() ignores all specified arguments no error -// messages are produced if arguments are spcified. +// messages are produced if arguments are specified. ?> --EXPECT-- 3.1415926535898 diff --git a/ext/standard/tests/math/pow_basic.phpt b/ext/standard/tests/math/pow_basic.phpt index bc594b27c631..847e569a4799 100644 --- a/ext/standard/tests/math/pow_basic.phpt +++ b/ext/standard/tests/math/pow_basic.phpt @@ -8,40 +8,51 @@ if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); ?> --FILE-- --FILE-- +--EXPECTF-- + +Warning: fsockopen(): Unable to connect to localhost:%d (The hostname must not contain null bytes) in %s +bool(false) diff --git a/ext/standard/tests/network/ghsa-www2-q4fc-65wf.phpt b/ext/standard/tests/network/ghsa-www2-q4fc-65wf.phpt new file mode 100644 index 000000000000..3d082c8e9522 --- /dev/null +++ b/ext/standard/tests/network/ghsa-www2-q4fc-65wf.phpt @@ -0,0 +1,62 @@ +--TEST-- +GHSA-www2-q4fc-65wf +--DESCRIPTION-- +This is a ZPP test but *keep* this as it is security-sensitive! +--FILE-- +getMessage(), "\n"; +} +try { + dns_get_mx("\0", $out); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + dns_get_record("\0"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + getprotobyname("\0"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + getservbyname("\0", "tcp"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + getservbyname("x", "tcp\0"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + getservbyport(0, "tcp\0"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + inet_pton("\0"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + ip2long("\0"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +dns_check_record(): Argument #1 ($hostname) must not contain any null bytes +dns_get_mx(): Argument #1 ($hostname) must not contain any null bytes +dns_get_record(): Argument #1 ($hostname) must not contain any null bytes +getprotobyname(): Argument #1 ($protocol) must not contain any null bytes +getservbyname(): Argument #1 ($service) must not contain any null bytes +getservbyname(): Argument #2 ($protocol) must not contain any null bytes +getservbyport(): Argument #2 ($protocol) must not contain any null bytes +inet_pton(): Argument #1 ($ip) must not contain any null bytes +ip2long(): Argument #1 ($ip) must not contain any null bytes diff --git a/ext/standard/tests/network/ip2long_variation2_x64.phpt b/ext/standard/tests/network/ip2long_variation2_x64.phpt index b69cc9e4d90e..ffa0827c9447 100644 --- a/ext/standard/tests/network/ip2long_variation2_x64.phpt +++ b/ext/standard/tests/network/ip2long_variation2_x64.phpt @@ -9,6 +9,7 @@ Test ip2long() function : usage variation 2, 64 bit */ if(PHP_OS == 'Darwin') die("skip - inet_pton behaves differently on Darwin"); if(PHP_OS == 'OpenBSD') die("skip - inet_pton accepts leading zeros on OpenBSD"); +if(PHP_OS_FAMILY === 'Solaris') die("skip - Solaris inet_aton accepts invalid octal as decimal"); if(PHP_INT_SIZE != 8) {die('skip 64 bit only');} ?> --FILE-- diff --git a/ext/standard/tests/network/setcookie.phpt b/ext/standard/tests/network/setcookie.phpt index f43680a5bcea..caf9aa9ae076 100644 --- a/ext/standard/tests/network/setcookie.phpt +++ b/ext/standard/tests/network/setcookie.phpt @@ -19,6 +19,7 @@ setcookie('name', 'value', 0, '', '', FALSE, TRUE); setcookie('name', 'value', ['expires' => $tsp]); setcookie('name', 'value', ['expires' => $tsn, 'path' => '/path/', 'domain' => 'domain.tld', 'secure' => true, 'httponly' => true, 'samesite' => 'Strict']); +setcookie('name', 'value', ['secure' => true, 'partitioned' => true]); $expected = array( 'Set-Cookie: name=deleted; expires='.date('D, d M Y H:i:s', 1).' GMT; Max-Age=0', @@ -34,7 +35,8 @@ $expected = array( 'Set-Cookie: name=value; secure', 'Set-Cookie: name=value; HttpOnly', 'Set-Cookie: name=value; expires='.date('D, d M Y H:i:s', $tsp).' GMT; Max-Age=5', - 'Set-Cookie: name=value; expires='.date('D, d M Y H:i:s', $tsn).' GMT; Max-Age=0; path=/path/; domain=domain.tld; secure; HttpOnly; SameSite=Strict' + 'Set-Cookie: name=value; expires='.date('D, d M Y H:i:s', $tsn).' GMT; Max-Age=0; path=/path/; domain=domain.tld; secure; HttpOnly; SameSite=Strict', + 'Set-Cookie: name=value; secure; Partitioned' ); $headers = headers_list(); diff --git a/ext/standard/tests/network/setcookie_array_option_error.phpt b/ext/standard/tests/network/setcookie_array_option_error.phpt index ad4caf35108f..0fb2ae011c31 100644 --- a/ext/standard/tests/network/setcookie_array_option_error.phpt +++ b/ext/standard/tests/network/setcookie_array_option_error.phpt @@ -37,6 +37,12 @@ try { } catch (\ValueError $e) { echo $e->getMessage() . "\n"; } +// Partitioned without secure +try { + setcookie('name', 'value', ['partitioned' => true]); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} // Arguments after options array (will not be set) try { @@ -66,6 +72,7 @@ setcookie(): option array cannot have numeric keys setcookie(): option "foo" is invalid setcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" setcookie(): "domain" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014" +setcookie(): "partitioned" option cannot be used without "secure" option setcookie(): Expects exactly 3 arguments when argument #3 ($expires_or_options) is an array bool(true) array(1) { diff --git a/ext/standard/tests/network/so_keepalive.phpt b/ext/standard/tests/network/so_keepalive.phpt new file mode 100644 index 000000000000..a437d16694b3 --- /dev/null +++ b/ext/standard/tests/network/so_keepalive.phpt @@ -0,0 +1,151 @@ +--TEST-- +stream_socket_server() and stream_socket_client() SO_KEEPALIVE context option test +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + [ + 'so_keepalive' => true, + 'tcp_keepidle' => 60, + 'tcp_keepintvl' => 10, + 'tcp_keepcnt' => 5, + ] +]); + +$server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $server_context); + +if (!$server) { + die('Unable to create server'); +} + +$addr = stream_socket_get_name($server, false); +$port = (int)substr(strrchr($addr, ':'), 1); + +// Test client with SO_KEEPALIVE enabled +$client_context = stream_context_create([ + 'socket' => [ + 'so_keepalive' => true, + 'tcp_keepidle' => 30, + 'tcp_keepintvl' => 5, + 'tcp_keepcnt' => 3, + ] +]); + +$client = stream_socket_client("tcp://127.0.0.1:$port", $errno, $errstr, 30, + STREAM_CLIENT_CONNECT, $client_context); + +if (!$client) { + die('Unable to create client'); +} + +$accepted = stream_socket_accept($server, 1); + +if (!$accepted) { + die('Unable to accept connection'); +} + +// Verify server side (accepted connection) +$server_sock = socket_import_stream($accepted); +$server_keepalive = socket_get_option($server_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Server SO_KEEPALIVE: " . ($server_keepalive ? "enabled" : "disabled") . "\n"; + +if (defined('TCP_KEEPIDLE')) { + $server_idle = socket_get_option($server_sock, SOL_TCP, TCP_KEEPIDLE); + echo "Server TCP_KEEPIDLE: $server_idle\n"; +} else { + $server_idle = socket_get_option($server_sock, SOL_TCP, TCP_KEEPALIVE); + echo "Server TCP_KEEPIDLE: $server_idle\n"; +} + +$server_intvl = socket_get_option($server_sock, SOL_TCP, TCP_KEEPINTVL); +echo "Server TCP_KEEPINTVL: $server_intvl\n"; + +$server_cnt = socket_get_option($server_sock, SOL_TCP, TCP_KEEPCNT); +echo "Server TCP_KEEPCNT: $server_cnt\n"; + +// Verify client side +$client_sock = socket_import_stream($client); +$client_keepalive = socket_get_option($client_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Client SO_KEEPALIVE: " . ($client_keepalive ? "enabled" : "disabled") . "\n"; + +if (defined('TCP_KEEPIDLE')) { + $client_idle = socket_get_option($client_sock, SOL_TCP, TCP_KEEPIDLE); + echo "Client TCP_KEEPIDLE: $client_idle\n"; +} else { + $client_idle = socket_get_option($client_sock, SOL_TCP, TCP_KEEPALIVE); + echo "Client TCP_KEEPIDLE: $client_idle\n"; +} + +$client_intvl = socket_get_option($client_sock, SOL_TCP, TCP_KEEPINTVL); +echo "Client TCP_KEEPINTVL: $client_intvl\n"; + +$client_cnt = socket_get_option($client_sock, SOL_TCP, TCP_KEEPCNT); +echo "Client TCP_KEEPCNT: $client_cnt\n"; + +fclose($accepted); +fclose($client); +fclose($server); + +// Test server with SO_KEEPALIVE disabled +$server2_context = stream_context_create(['socket' => ['so_keepalive' => false]]); +$server2 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $server2_context); + +$addr2 = stream_socket_get_name($server2, false); +$port2 = (int)substr(strrchr($addr2, ':'), 1); + +$client2 = stream_socket_client("tcp://127.0.0.1:$port2"); +$accepted2 = stream_socket_accept($server2, 1); + +$server2_sock = socket_import_stream($accepted2); +$server2_keepalive = socket_get_option($server2_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Server disabled SO_KEEPALIVE: " . ($server2_keepalive ? "enabled" : "disabled") . "\n"; + +fclose($accepted2); +fclose($client2); +fclose($server2); + +// Test client with SO_KEEPALIVE disabled +$server3 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN); + +$addr3 = stream_socket_get_name($server3, false); +$port3 = (int)substr(strrchr($addr3, ':'), 1); + +$client3_context = stream_context_create(['socket' => ['so_keepalive' => false]]); +$client3 = stream_socket_client("tcp://127.0.0.1:$port3", $errno, $errstr, 30, + STREAM_CLIENT_CONNECT, $client3_context); + +$client3_sock = socket_import_stream($client3); +$client3_keepalive = socket_get_option($client3_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Client disabled SO_KEEPALIVE: " . ($client3_keepalive ? "enabled" : "disabled") . "\n"; + +fclose($client3); +fclose($server3); +?> +--EXPECT-- +Server SO_KEEPALIVE: enabled +Server TCP_KEEPIDLE: 60 +Server TCP_KEEPINTVL: 10 +Server TCP_KEEPCNT: 5 +Client SO_KEEPALIVE: enabled +Client TCP_KEEPIDLE: 30 +Client TCP_KEEPINTVL: 5 +Client TCP_KEEPCNT: 3 +Server disabled SO_KEEPALIVE: disabled +Client disabled SO_KEEPALIVE: disabled diff --git a/ext/standard/tests/network/so_keepalive_string.phpt b/ext/standard/tests/network/so_keepalive_string.phpt new file mode 100644 index 000000000000..19cb2f9c6dec --- /dev/null +++ b/ext/standard/tests/network/so_keepalive_string.phpt @@ -0,0 +1,151 @@ +--TEST-- +stream_socket_server() and stream_socket_client() keepalive option test with string values +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- + [ + 'so_keepalive' => true, + 'tcp_keepidle' => '80', + 'tcp_keepintvl' => '12', + 'tcp_keepcnt' => '6', + ] +]); + +$server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $server_context); + +if (!$server) { + die('Unable to create server'); +} + +$addr = stream_socket_get_name($server, false); +$port = (int)substr(strrchr($addr, ':'), 1); + +// Test client with SO_KEEPALIVE enabled +$client_context = stream_context_create([ + 'socket' => [ + 'so_keepalive' => true, + 'tcp_keepidle' => '31', + 'tcp_keepintvl' => '6', + 'tcp_keepcnt' => '4', + ] +]); + +$client = stream_socket_client("tcp://127.0.0.1:$port", $errno, $errstr, 30, + STREAM_CLIENT_CONNECT, $client_context); + +if (!$client) { + die('Unable to create client'); +} + +$accepted = stream_socket_accept($server, 1); + +if (!$accepted) { + die('Unable to accept connection'); +} + +// Verify server side (accepted connection) +$server_sock = socket_import_stream($accepted); +$server_keepalive = socket_get_option($server_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Server SO_KEEPALIVE: " . ($server_keepalive ? "enabled" : "disabled") . "\n"; + +if (defined('TCP_KEEPIDLE')) { + $server_idle = socket_get_option($server_sock, SOL_TCP, TCP_KEEPIDLE); + echo "Server TCP_KEEPIDLE: $server_idle\n"; +} else { + $server_idle = socket_get_option($server_sock, SOL_TCP, TCP_KEEPALIVE); + echo "Server TCP_KEEPIDLE: $server_idle\n"; +} + +$server_intvl = socket_get_option($server_sock, SOL_TCP, TCP_KEEPINTVL); +echo "Server TCP_KEEPINTVL: $server_intvl\n"; + +$server_cnt = socket_get_option($server_sock, SOL_TCP, TCP_KEEPCNT); +echo "Server TCP_KEEPCNT: $server_cnt\n"; + +// Verify client side +$client_sock = socket_import_stream($client); +$client_keepalive = socket_get_option($client_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Client SO_KEEPALIVE: " . ($client_keepalive ? "enabled" : "disabled") . "\n"; + +if (defined('TCP_KEEPIDLE')) { + $client_idle = socket_get_option($client_sock, SOL_TCP, TCP_KEEPIDLE); + echo "Client TCP_KEEPIDLE: $client_idle\n"; +} else { + $client_idle = socket_get_option($client_sock, SOL_TCP, TCP_KEEPALIVE); + echo "Client TCP_KEEPIDLE: $client_idle\n"; +} + +$client_intvl = socket_get_option($client_sock, SOL_TCP, TCP_KEEPINTVL); +echo "Client TCP_KEEPINTVL: $client_intvl\n"; + +$client_cnt = socket_get_option($client_sock, SOL_TCP, TCP_KEEPCNT); +echo "Client TCP_KEEPCNT: $client_cnt\n"; + +fclose($accepted); +fclose($client); +fclose($server); + +// Test server with SO_KEEPALIVE disabled +$server2_context = stream_context_create(['socket' => ['so_keepalive' => false]]); +$server2 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $server2_context); + +$addr2 = stream_socket_get_name($server2, false); +$port2 = (int)substr(strrchr($addr2, ':'), 1); + +$client2 = stream_socket_client("tcp://127.0.0.1:$port2"); +$accepted2 = stream_socket_accept($server2, 1); + +$server2_sock = socket_import_stream($accepted2); +$server2_keepalive = socket_get_option($server2_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Server disabled SO_KEEPALIVE: " . ($server2_keepalive ? "enabled" : "disabled") . "\n"; + +fclose($accepted2); +fclose($client2); +fclose($server2); + +// Test client with SO_KEEPALIVE disabled +$server3 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN); + +$addr3 = stream_socket_get_name($server3, false); +$port3 = (int)substr(strrchr($addr3, ':'), 1); + +$client3_context = stream_context_create(['socket' => ['so_keepalive' => false]]); +$client3 = stream_socket_client("tcp://127.0.0.1:$port3", $errno, $errstr, 30, + STREAM_CLIENT_CONNECT, $client3_context); + +$client3_sock = socket_import_stream($client3); +$client3_keepalive = socket_get_option($client3_sock, SOL_SOCKET, SO_KEEPALIVE); +echo "Client disabled SO_KEEPALIVE: " . ($client3_keepalive ? "enabled" : "disabled") . "\n"; + +fclose($client3); +fclose($server3); +?> +--EXPECT-- +Server SO_KEEPALIVE: enabled +Server TCP_KEEPIDLE: 80 +Server TCP_KEEPINTVL: 12 +Server TCP_KEEPCNT: 6 +Client SO_KEEPALIVE: enabled +Client TCP_KEEPIDLE: 31 +Client TCP_KEEPINTVL: 6 +Client TCP_KEEPCNT: 4 +Server disabled SO_KEEPALIVE: disabled +Client disabled SO_KEEPALIVE: disabled diff --git a/ext/standard/tests/network/so_reuseaddr.phpt b/ext/standard/tests/network/so_reuseaddr.phpt new file mode 100644 index 000000000000..d400a81ac33d --- /dev/null +++ b/ext/standard/tests/network/so_reuseaddr.phpt @@ -0,0 +1,73 @@ +--TEST-- +stream_socket_server() SO_REUSEADDR context option test +--FILE-- + ['so_reuseaddr' => false]]); +$server3 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context); +if (!$server3) { + die('Unable to create server3'); +} + +$addr = stream_socket_get_name($server3, false); +$port = (int)substr(strrchr($addr, ':'), 1); + +$client3 = stream_socket_client("tcp://127.0.0.1:$port"); +$accepted = stream_socket_accept($server3, 1); + +// Force real TCP connection with data +fwrite($client3, "test"); +fread($accepted, 4); +fwrite($accepted, "response"); +fread($client3, 8); + +// Client closes first (becomes active closer) +fclose($client3); // This enters TIME_WAIT +if (!$is_win) { // Windows would always succeed if server is closed + fclose($server3); +} + +// Try immediate bind with SO_REUSEADDR disabled (should fail) +$server4 = @stream_socket_server("tcp://127.0.0.1:$port", $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context); +if ($server4) { + echo "Disabled: Server restart succeeded\n"; + fclose($server4); +} else { + echo "Disabled: Server restart failed\n"; +} +?> +--EXPECT-- +Default: Server restart succeeded +Disabled: Server restart failed diff --git a/ext/standard/tests/network/so_reuseport.phpt b/ext/standard/tests/network/so_reuseport.phpt new file mode 100644 index 000000000000..12a07bbd4236 --- /dev/null +++ b/ext/standard/tests/network/so_reuseport.phpt @@ -0,0 +1,136 @@ +--TEST-- +stream_socket_server() SO_REUSEPORT context option test +--SKIPIF-- + +--FILE-- + ['so_reuseport' => true]]); +$server1 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context1); + +if (!$server1) { + die('Unable to create server1'); +} + +$addr = stream_socket_get_name($server1, false); +$port = (int)substr(strrchr($addr, ':'), 1); + +// Establish actual connection on server1 +$client1 = stream_socket_client("tcp://127.0.0.1:$port"); +$accepted1 = stream_socket_accept($server1, 1); + +// Force real TCP connection with data +fwrite($client1, "test"); +fread($accepted1, 4); +fwrite($accepted1, "response"); +fread($client1, 8); + +// Try to bind second server to SAME port with SO_REUSEPORT (while server1 still active) +$context2 = stream_context_create(['socket' => ['so_reuseport' => true]]); +$server2 = @stream_socket_server("tcp://127.0.0.1:$port", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context2); + +if ($server2) { + echo "SO_REUSEPORT enabled: Multiple servers succeeded\n"; + + // Verify server2 can also accept connections + $client2 = stream_socket_client("tcp://127.0.0.1:$port"); + $accepted2_on_srv1 = @stream_socket_accept($server1, 0.1); + $accepted2_on_srv2 = @stream_socket_accept($server2, 0.1); + + if ($accepted2_on_srv1 || $accepted2_on_srv2) { + echo "SO_REUSEPORT enabled: Connections accepted\n"; + } + + if ($accepted2_on_srv1) fclose($accepted2_on_srv1); + if ($accepted2_on_srv2) fclose($accepted2_on_srv2); + if ($client2) fclose($client2); + + fclose($server2); +} else { + echo "SO_REUSEPORT enabled: Multiple servers failed\n"; +} + +fclose($accepted1); +fclose($client1); +fclose($server1); + +// SO_REUSEPORT disabled (default) - should NOT allow multiple servers +$server3 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN); + +if (!$server3) { + die('Unable to create server3'); +} + +$addr = stream_socket_get_name($server3, false); +$port = (int)substr(strrchr($addr, ':'), 1); + +$client3 = stream_socket_client("tcp://127.0.0.1:$port"); +$accepted3 = stream_socket_accept($server3, 1); + +fwrite($client3, "test"); +fread($accepted3, 4); +fwrite($accepted3, "response"); +fread($client3, 8); + +// Try to bind second server WITHOUT SO_REUSEPORT (while server3 still active) +$server4 = @stream_socket_server("tcp://127.0.0.1:$port", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN); + +if ($server4) { + echo "SO_REUSEPORT disabled: Multiple servers succeeded\n"; + fclose($server4); +} else { + echo "SO_REUSEPORT disabled: Multiple servers failed\n"; +} + +fclose($accepted3); +fclose($client3); +fclose($server3); + +// SO_REUSEPORT explicitly disabled +$context3 = stream_context_create(['socket' => ['so_reuseport' => false]]); +$server5 = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context3); + +if (!$server5) { + die('Unable to create server5'); +} + +$addr = stream_socket_get_name($server5, false); +$port = (int)substr(strrchr($addr, ':'), 1); + +$client5 = stream_socket_client("tcp://127.0.0.1:$port"); +$accepted5 = stream_socket_accept($server5, 1); + +fwrite($client5, "test"); +fread($accepted5, 4); +fwrite($accepted5, "response"); +fread($client5, 8); + +$context4 = stream_context_create(['socket' => ['so_reuseport' => false]]); +$server6 = @stream_socket_server("tcp://127.0.0.1:$port", $errno, $errstr, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context4); + +if ($server6) { + echo "SO_REUSEPORT explicitly disabled: Multiple servers succeeded\n"; + fclose($server6); +} else { + echo "SO_REUSEPORT explicitly disabled: Multiple servers failed\n"; +} + +fclose($accepted5); +fclose($client5); +fclose($server5); +?> +--EXPECT-- +SO_REUSEPORT enabled: Multiple servers succeeded +SO_REUSEPORT enabled: Connections accepted +SO_REUSEPORT disabled: Multiple servers failed +SO_REUSEPORT explicitly disabled: Multiple servers failed diff --git a/ext/standard/tests/network/stream_socket_server_bind_error.phpt b/ext/standard/tests/network/stream_socket_server_bind_error.phpt new file mode 100644 index 000000000000..2f5becb66a91 --- /dev/null +++ b/ext/standard/tests/network/stream_socket_server_bind_error.phpt @@ -0,0 +1,19 @@ +--TEST-- +stream_socket_server() bind error +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: stream_socket_server(): Unable to connect to tcp://0.0.0.0:%d (Address %r(already )?%rin use) in %s on line %d diff --git a/ext/standard/tests/network/syslog_new_line.phpt b/ext/standard/tests/network/syslog_new_line.phpt index 69eb9c1d67e7..d63f5714c79c 100644 --- a/ext/standard/tests/network/syslog_new_line.phpt +++ b/ext/standard/tests/network/syslog_new_line.phpt @@ -4,6 +4,8 @@ Test syslog() function : new line in message --FILE-- --FILE-- new A($this)]; + } +} + +class C { + public B $b; + + public function __construct() { + $this->b = new B; + } +} + +$b = new B(); +$sb = serialize($b); +$stb = serialize(new B); + +printf("serialized original: %s\n", $sb); +printf("serialized temp : %s\n", $stb); + +$c = new C; +$sc = serialize($c); +$stc = serialize(new C); + +printf("serialized original: %s\n", $sc); +printf("serialized temp : %s\n", $stc); + +?> +--EXPECT-- +serialized original: O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:1;}} +serialized temp : O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:1;}} +serialized original: O:1:"C":1:{s:1:"b";O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:2;}}} +serialized temp : O:1:"C":1:{s:1:"b";O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:2;}}} diff --git a/ext/standard/tests/serialize/gh12265b.phpt b/ext/standard/tests/serialize/gh12265b.phpt new file mode 100644 index 000000000000..22246b4e4792 --- /dev/null +++ b/ext/standard/tests/serialize/gh12265b.phpt @@ -0,0 +1,48 @@ +--TEST-- +GH-12265 (Cloning an object breaks serialization recursion) - __sleep variation +--FILE-- +a = new A($this); + return ['a']; + } +} + +class C { + public B $b; + + public function __construct() { + $this->b = new B; + } +} + +$b = new B(); +$sb = serialize($b); +$stb = serialize(new B); + +printf("serialized original: %s\n", $sb); +printf("serialized temp : %s\n", $stb); + +$c = new C; +$sc = serialize($c); +$stc = serialize(new C); + +printf("serialized original: %s\n", $sc); +printf("serialized temp : %s\n", $stc); + +?> +--EXPECTF-- +serialized original: O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:1;}} +serialized temp : O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:1;}} +serialized original: O:1:"C":1:{s:1:"b";O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:2;}}} +serialized temp : O:1:"C":1:{s:1:"b";O:1:"B":1:{s:1:"a";O:1:"A":1:{s:1:"x";r:2;}}} diff --git a/ext/standard/tests/serialize/gh19701.phpt b/ext/standard/tests/serialize/gh19701.phpt new file mode 100644 index 000000000000..d7ef08e20331 --- /dev/null +++ b/ext/standard/tests/serialize/gh19701.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-19701 (Serialize/deserialize loses some data) +--CREDITS-- +cuchac +DanielEScherzer +--FILE-- +parent = $baseProduct; +$baseProduct->children = [ $child ]; + +$data = [clone $baseProduct, $baseProduct]; + +echo serialize($data), "\n"; + +?> +--EXPECTF-- +a:2:{i:0;O:4:"Item":2:{s:8:"children";a:1:{i:0;O:4:"Item":2:{s:8:"children";a:0:{}s:6:"parent";O:4:"Item":2:{s:8:"children";a:1:{i:0;r:4;}s:6:"parent";N;}}}s:6:"parent";N;}i:1;r:6;} diff --git a/ext/standard/tests/serialize/oss_fuzz_433303828.phpt b/ext/standard/tests/serialize/oss_fuzz_433303828.phpt new file mode 100644 index 000000000000..fb90b51d4dad --- /dev/null +++ b/ext/standard/tests/serialize/oss_fuzz_433303828.phpt @@ -0,0 +1,13 @@ +--TEST-- +OSS-Fuzz #433303828 +--FILE-- + +--EXPECTF-- +Warning: unserialize(): Error at offset 9 of 10 bytes in %s on line %d + +Warning: unserialize(): Error at offset 10 of 11 bytes in %s on line %d diff --git a/ext/standard/tests/serialize/shm_corruption_coercion_unserialize_options.phpt b/ext/standard/tests/serialize/shm_corruption_coercion_unserialize_options.phpt new file mode 100644 index 000000000000..6a24a0137526 --- /dev/null +++ b/ext/standard/tests/serialize/shm_corruption_coercion_unserialize_options.phpt @@ -0,0 +1,14 @@ +--TEST-- +Shm corruption with coercion in options of unserialize() +--FILE-- + [new MyStringable]]); +?> +--EXPECTF-- +Warning: unserialize(): Error at offset 0 of 2 bytes in %s on line %d diff --git a/ext/standard/tests/serialize/unserialize_mem_leak.phpt b/ext/standard/tests/serialize/unserialize_mem_leak.phpt index 3ddb74a273df..bad689c3705a 100644 --- a/ext/standard/tests/serialize/unserialize_mem_leak.phpt +++ b/ext/standard/tests/serialize/unserialize_mem_leak.phpt @@ -1,7 +1,5 @@ --TEST-- Memleaks if unserialize return a self-referenced array/object ---INI-- -report_memleaks=1 --FILE-- 'Strict'])); +var_dump(setcookie('test', 'value', ['samesite' => 'Lax'])); +var_dump(setcookie('test', 'value', ['samesite' => 'None'])); +var_dump(setcookie('test', 'value', ['samesite' => ''])); + +// Case-insensitive +var_dump(setcookie('test', 'value', ['samesite' => 'strict'])); +var_dump(setcookie('test', 'value', ['samesite' => 'LAX'])); +var_dump(setcookie('test', 'value', ['samesite' => 'NONE'])); + +// setrawcookie uses the same validation +var_dump(setrawcookie('test', 'value', ['samesite' => 'Lax'])); + +// Invalid values +try { + setcookie('test', 'value', ['samesite' => 'Invalid']); +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + setcookie('test', 'value', ['samesite' => "Strict\r\nX-Injected: evil"]); +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + setrawcookie('test', 'value', ['samesite' => 'Invalid']); +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +setcookie(): "samesite" option must be "Strict", "Lax", "None", or "" +setcookie(): "samesite" option must be "Strict", "Lax", "None", or "" +setrawcookie(): "samesite" option must be "Strict", "Lax", "None", or "" diff --git a/ext/standard/tests/skipif_no_root.inc b/ext/standard/tests/skipif_no_root.inc new file mode 100644 index 000000000000..ef60c14745ba --- /dev/null +++ b/ext/standard/tests/skipif_no_root.inc @@ -0,0 +1,16 @@ + --EXPECTF-- -Notice: stream_get_contents(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: stream_get_contents(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d string(0) "" -Notice: stream_get_contents(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: stream_get_contents(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d string(0) "" -Notice: stream_get_contents(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d +Notice: stream_get_contents(): Read of 8192 bytes failed with errno=9 Bad file %r(descriptor|number)%r in %s on line %d string(0) "" diff --git a/ext/standard/tests/streams/bug60602.phpt b/ext/standard/tests/streams/bug60602.phpt index b3795414e4f1..ae1d65d45bd9 100644 --- a/ext/standard/tests/streams/bug60602.phpt +++ b/ext/standard/tests/streams/bug60602.phpt @@ -9,7 +9,7 @@ $descs = array( 2 => array('pipe', 'w'), // strerr ); -$environment = array('test' => array(1, 2, 3)); +$environment = array('test' => array(1, 2, 3), 'PATH' => getenv('PATH')); $cmd = (substr(PHP_OS, 0, 3) == 'WIN') ? 'dir' : 'ls'; $p = proc_open($cmd, $descs, $pipes, '.', $environment); diff --git a/ext/standard/tests/streams/bug69521.phpt b/ext/standard/tests/streams/bug69521.phpt index 9ec244f79963..d335a68736eb 100644 --- a/ext/standard/tests/streams/bug69521.phpt +++ b/ext/standard/tests/streams/bug69521.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #69521 Segfault in gc_collect_cycles() +Bug #69521 (Segfault in gc_collect_cycles()) --FILE-- getMessage(), "\n"; +} +fflush($readStream); +try { + fclose($readStream); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d + +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d + +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d + +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d + +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d + +Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d + +Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d + +Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d +No stream arrays were passed +fclose(): Argument #1 ($stream) must be an open stream resource diff --git a/ext/standard/tests/streams/gh19570.phpt b/ext/standard/tests/streams/gh19570.phpt new file mode 100644 index 000000000000..e3d486ea83cf --- /dev/null +++ b/ext/standard/tests/streams/gh19570.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-19570 (unable to fseek in /dev/zero and /dev/null) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(0) +int(0) +int(0) diff --git a/ext/standard/tests/streams/gh19705.phpt b/ext/standard/tests/streams/gh19705.phpt new file mode 100644 index 000000000000..d34cfc700596 --- /dev/null +++ b/ext/standard/tests/streams/gh19705.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-19705 segmentation fault with non writable stream at stream_filter_append call. +--EXTENSIONS-- +zlib +--FILE-- + +--EXPECTF-- +resource(%d) of type (stream filter) diff --git a/ext/standard/tests/streams/gh20286.phpt b/ext/standard/tests/streams/gh20286.phpt new file mode 100644 index 000000000000..6d15e167aee9 --- /dev/null +++ b/ext/standard/tests/streams/gh20286.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-20286 use after destroy on userland stream_close +--CREDITS-- +vi3tL0u1s +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d + +Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d + +Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d + +Fatal error: Cannot redeclare function a() (previously declared in %s:%d) in %s on line %d diff --git a/ext/standard/tests/streams/gh9590-001.phpt b/ext/standard/tests/streams/gh9590-001.phpt index 558e4660a65f..8f5691af1ade 100644 --- a/ext/standard/tests/streams/gh9590-001.phpt +++ b/ext/standard/tests/streams/gh9590-001.phpt @@ -7,6 +7,8 @@ posix if (!function_exists('posix_setrlimit') || !posix_setrlimit(POSIX_RLIMIT_NOFILE, 2048, -1)) { die('skip Failed to set POSIX_RLIMIT_NOFILE'); } +if (PHP_OS_FAMILY === 'Solaris' && PHP_INT_SIZE === 8) + die('skip Solaris LP64 FD_SETSIZE=65536 not practically exceedable here'); ?> --FILE-- --FILE-- +--EXPECTF-- + +Warning: stream_socket_client(): Unable to connect to tcp://localhost\0.example.com:%d (The hostname must not contain null bytes) in %s +bool(false) diff --git a/ext/standard/tests/streams/glob-wrapper.phpt b/ext/standard/tests/streams/glob-wrapper.phpt index 212a33f1440c..9be0fce6b710 100644 --- a/ext/standard/tests/streams/glob-wrapper.phpt +++ b/ext/standard/tests/streams/glob-wrapper.phpt @@ -27,7 +27,7 @@ foreach ( [ __DIR__, "glob://".__DIR__ ] as $spec) { Warning: opendir(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (/does_not_exist) in %s%eglob-wrapper.php on line 5 -Warning: opendir(%s): Failed to open directory: Operation not permitted in %s%eglob-wrapper.php on line 5 +Warning: opendir(%s): Failed to open directory: %r(Operation not permitted|Insufficient privileges)%r in %s%eglob-wrapper.php on line 5 Failed to open %s ** Opening glob://%s No files in glob://%s diff --git a/ext/standard/tests/streams/stream_context_get_params_001.phpt b/ext/standard/tests/streams/stream_context_get_params_001.phpt index e8b107ccfe95..aaed575314e5 100644 --- a/ext/standard/tests/streams/stream_context_get_params_001.phpt +++ b/ext/standard/tests/streams/stream_context_get_params_001.phpt @@ -4,16 +4,19 @@ stream_context_get_params() "stream_notification_callback"))); var_dump(stream_context_get_params($ctx)); -var_dump(stream_context_set_params($ctx, array("notification" => array("stream","notification_callback")))); +class MyStream { + public static function notification_callback() {} +} +var_dump(stream_context_set_params($ctx, array("notification" => ["MyStream", "notification_callback"]))); var_dump(stream_context_get_params($ctx)); var_dump(stream_context_get_params($ctx)); @@ -22,8 +25,7 @@ var_dump(stream_context_get_params($ctx)); var_dump(stream_context_get_options($ctx)); ?> ---EXPECTF-- -resource(%d) of type (stream-context) +--EXPECT-- array(1) { ["options"]=> array(0) { @@ -58,7 +60,7 @@ array(2) { ["notification"]=> array(2) { [0]=> - string(6) "stream" + string(8) "MyStream" [1]=> string(21) "notification_callback" } @@ -75,7 +77,7 @@ array(2) { ["notification"]=> array(2) { [0]=> - string(6) "stream" + string(8) "MyStream" [1]=> string(21) "notification_callback" } @@ -99,7 +101,7 @@ array(2) { ["notification"]=> array(2) { [0]=> - string(6) "stream" + string(8) "MyStream" [1]=> string(21) "notification_callback" } diff --git a/ext/standard/tests/streams/stream_context_set_params_notification_error.phpt b/ext/standard/tests/streams/stream_context_set_params_notification_error.phpt new file mode 100644 index 000000000000..32af36d0d477 --- /dev/null +++ b/ext/standard/tests/streams/stream_context_set_params_notification_error.phpt @@ -0,0 +1,21 @@ +--TEST-- +stream_context_set_params() with invalid notification option +--FILE-- + "fn_not_exist"])); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +try { + var_dump(stream_context_set_params($ctx, ["notification" => ["myclass", "fn_not_exist"]])); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +TypeError: stream_context_set_params(): Argument #1 ($context) must be an array with valid callbacks as values, function "fn_not_exist" not found or invalid function name +TypeError: stream_context_set_params(): Argument #1 ($context) must be an array with valid callbacks as values, class "myclass" not found diff --git a/ext/standard/tests/streams/stream_context_set_params_notification_valid_then_invalid.phpt b/ext/standard/tests/streams/stream_context_set_params_notification_valid_then_invalid.phpt new file mode 100644 index 000000000000..9f654d61761e --- /dev/null +++ b/ext/standard/tests/streams/stream_context_set_params_notification_valid_then_invalid.phpt @@ -0,0 +1,20 @@ +--TEST-- +stream_context_set_params() with valid, then invalid notification option +--FILE-- + "foo"])); + +try { + var_dump(stream_context_set_params($ctx, ["notification" => "fn_not_exist"])); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +bool(true) +TypeError: stream_context_set_params(): Argument #1 ($context) must be an array with valid callbacks as values, function "fn_not_exist" not found or invalid function name diff --git a/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt b/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt index cd1ba6b41dd8..1ac08dd5c841 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt @@ -18,7 +18,7 @@ $socket = stream_socket_accept($server); var_dump(stream_get_meta_data($client)); echo "\n\nSet a timeout on the client and attempt a read:\n"; -socket_set_timeout($client, 0, 1000); +stream_set_timeout($client, 0, 1000); fread($client, 1); var_dump(stream_get_meta_data($client)); diff --git a/ext/standard/tests/streams/stream_select_filtered_base64_basic.phpt b/ext/standard/tests/streams/stream_select_filtered_base64_basic.phpt new file mode 100644 index 000000000000..f7ec2b6a4b54 --- /dev/null +++ b/ext/standard/tests/streams/stream_select_filtered_base64_basic.phpt @@ -0,0 +1,32 @@ +--TEST-- +stream_select() base64-decode filter basic usage +--FILE-- + 0) { + echo fread($file, 1024) . "\n"; + } +} else { + echo "stream_select failed\n"; +} + +fclose($file); +?> +--EXPECT-- +stream_select succeeded +Hello World diff --git a/ext/standard/tests/streams/stream_select_filtered_base64_buffered.phpt b/ext/standard/tests/streams/stream_select_filtered_base64_buffered.phpt new file mode 100644 index 000000000000..4d11bf718a1b --- /dev/null +++ b/ext/standard/tests/streams/stream_select_filtered_base64_buffered.phpt @@ -0,0 +1,59 @@ +--TEST-- +stream_select() base64-decode filter buffered data usage +--FILE-- + 0) { + $content = fread($read_pipe, 1024); + echo "Decoded content: " . $content . "\n"; +} + +fclose($read_pipe); +fclose($write_pipe); +?> +--EXPECT-- +Decoded content (before select): Hel +After incomplete data - select result: 0 +After incomplete data - readable streams: 0 +After complete data - select result: 1 +After complete data - readable streams: 1 +Decoded content: lo diff --git a/ext/standard/tests/streams/user-stream-dir-open-bailout.phpt b/ext/standard/tests/streams/user-stream-dir-open-bailout.phpt new file mode 100644 index 000000000000..d7421ee9dea8 --- /dev/null +++ b/ext/standard/tests/streams/user-stream-dir-open-bailout.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bailout (E_ERROR) during UserStream Dir Open +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECTF-- +Fatal error: Bailout in %s on line %d diff --git a/ext/standard/tests/streams/user-stream-error.phpt b/ext/standard/tests/streams/user-stream-error.phpt deleted file mode 100644 index 8ad4be644181..000000000000 --- a/ext/standard/tests/streams/user-stream-error.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -E_ERROR during UserStream Open ---FILE-- - ---EXPECTF-- -Fatal error: Uncaught Error: Call to undefined function _some_undefined_function() in %s%euser-stream-error.php:%d -Stack trace: -#0 [internal function]: FailStream->stream_open('mystream://foo', 'r', 0, NULL) -#1 %s%euser-stream-error.php(%d): fopen('mystream://foo', 'r') -#2 {main} - thrown in %s%euser-stream-error.php on line %d diff --git a/ext/standard/tests/streams/user-stream-open-bailout.phpt b/ext/standard/tests/streams/user-stream-open-bailout.phpt new file mode 100644 index 000000000000..552e32a04a23 --- /dev/null +++ b/ext/standard/tests/streams/user-stream-open-bailout.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bailout (E_ERROR) during UserStream Open +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECTF-- +Fatal error: Bailout in %s on line %d diff --git a/ext/standard/tests/strings/bug47842.phpt b/ext/standard/tests/strings/bug47842.phpt index fe97308ea53a..1c8da881e7ce 100644 --- a/ext/standard/tests/strings/bug47842.phpt +++ b/ext/standard/tests/strings/bug47842.phpt @@ -23,12 +23,14 @@ printf("printf 64-bit signed int '18446744073709551615' (2^64)-1 = %u\n", 184467 echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- -Test sscanf 32-bit signed int '2147483647' (2^31)-1 = 2147483647 sscanf 32-bit unsign int '4294967295' (2^32)-1 = 4294967295 sscanf 64-bit signed int '9223372036854775807' (2^63)-1 = 9223372036854775807 sscanf 64-bit unsign int '18446744073709551615' (2^64)-1 = 18446744073709551615 printf 64-bit signed int '9223372036854775807' (2^63)-1 = 9223372036854775807 + +Warning: The float 1.8446744073709552E+19 is not representable as an int, cast occurred in %s on line %d printf 64-bit signed int '18446744073709551615' (2^64)-1 = 0 Done diff --git a/ext/standard/tests/strings/chr_out_of_range.phpt b/ext/standard/tests/strings/chr_out_of_range.phpt new file mode 100644 index 000000000000..8381850e8065 --- /dev/null +++ b/ext/standard/tests/strings/chr_out_of_range.phpt @@ -0,0 +1,15 @@ +--TEST-- +chr() with out of range values +--FILE-- + +--EXPECTF-- +Deprecated: chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using % 256 in %s on line 3 +bool(true) + +Deprecated: chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using % 256 in %s on line 4 +bool(true) diff --git a/ext/standard/tests/strings/chr_variation1.phpt b/ext/standard/tests/strings/chr_variation1.phpt index f045fdb54a00..d181e752c2aa 100644 --- a/ext/standard/tests/strings/chr_variation1.phpt +++ b/ext/standard/tests/strings/chr_variation1.phpt @@ -5,36 +5,17 @@ Test chr() function : usage variations - test values for $ascii argument echo "*** Testing chr() function: with unexpected inputs for 'ascii' argument ***\n"; -//defining a class -class sample { - public function __toString() { - return "sample object"; - } -} - -//getting the resource -$file_handle = fopen(__FILE__, "r"); - // array with different values for $input -$inputs = array ( - - // integer values -/*1*/ 0, - 1, - 255, - 256, - - // float values -/*5*/ 10.5, - -20.5, - 1.1234e6, - - // boolean values -/*11*/ true, - false, - TRUE, - FALSE, -); +$inputs = [ + 0, + 1, + 255, + // float values + 10.5, + // bool values + true, + false, +]; // loop through with each element of the $inputs array to test chr() function $count = 1; @@ -44,8 +25,6 @@ foreach($inputs as $input) { $count ++; } -fclose($file_handle); //closing the file handle - ?> --EXPECTF-- *** Testing chr() function: with unexpected inputs for 'ascii' argument *** @@ -56,22 +35,10 @@ string(2) "01" -- Iteration 3 -- string(2) "ff" -- Iteration 4 -- -string(2) "00" --- Iteration 5 -- Deprecated: Implicit conversion from float 10.5 to int loses precision in %s on line %d string(2) "0a" --- Iteration 6 -- - -Deprecated: Implicit conversion from float -20.5 to int loses precision in %s on line %d -string(2) "ec" --- Iteration 7 -- -string(2) "48" --- Iteration 8 -- -string(2) "01" --- Iteration 9 -- -string(2) "00" --- Iteration 10 -- +-- Iteration 5 -- string(2) "01" --- Iteration 11 -- +-- Iteration 6 -- string(2) "00" diff --git a/ext/standard/tests/strings/get_html_translation_table_basic6.phpt b/ext/standard/tests/strings/get_html_translation_table_basic6.phpt index 1715b0852bfa..f4fadf7134c3 100644 --- a/ext/standard/tests/strings/get_html_translation_table_basic6.phpt +++ b/ext/standard/tests/strings/get_html_translation_table_basic6.phpt @@ -3,7 +3,7 @@ Test get_html_translation_table() function : basic functionality - HTML 5/Window --FILE-- --INI-- diff --git a/ext/standard/tests/strings/gh18823_strict.phpt b/ext/standard/tests/strings/gh18823_strict.phpt index 80b21d209317..3735eab00670 100644 --- a/ext/standard/tests/strings/gh18823_strict.phpt +++ b/ext/standard/tests/strings/gh18823_strict.phpt @@ -15,5 +15,5 @@ try { } ?> --EXPECT-- -setlocale(): Argument #2 ($locales) must be of type array|string, int given -setlocale(): Argument #3 must be of type array|string, int given +setlocale(): Argument #2 ($locales) must be of type array|string|null, int given +setlocale(): Argument #3 must be of type array|string|null, int given diff --git a/ext/standard/tests/strings/gh18823_weak.phpt b/ext/standard/tests/strings/gh18823_weak.phpt index bc9611098a8d..2a2b82d9aaa3 100644 --- a/ext/standard/tests/strings/gh18823_weak.phpt +++ b/ext/standard/tests/strings/gh18823_weak.phpt @@ -27,6 +27,5 @@ try { echo $e->getMessage(), "\n"; } ?> ---EXPECTF-- -Deprecated: setlocale(): Passing null to parameter #2 ($locales) of type string is deprecated in %s on line %d +--EXPECT-- no diff --git a/ext/standard/tests/strings/gh18897.phpt b/ext/standard/tests/strings/gh18897.phpt new file mode 100644 index 000000000000..328ea7161e02 --- /dev/null +++ b/ext/standard/tests/strings/gh18897.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-18897 (printf: empty precision is interpreted as precision 6, not as precision 0) +--FILE-- + +--EXPECT-- +3 +3 diff --git a/ext/standard/tests/strings/gh18976.phpt b/ext/standard/tests/strings/gh18976.phpt new file mode 100644 index 000000000000..099ff94cc24d --- /dev/null +++ b/ext/standard/tests/strings/gh18976.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-18976 (pack overflow with h/H format) +--INI-- +memory_limit=-1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: pack(): Type h: not enough characters in string in %s on line %d + +Warning: pack(): Type H: not enough characters in string in %s on line %d diff --git a/ext/standard/tests/strings/gh19070.phpt b/ext/standard/tests/strings/gh19070.phpt new file mode 100644 index 000000000000..e44696443cc9 --- /dev/null +++ b/ext/standard/tests/strings/gh19070.phpt @@ -0,0 +1,8 @@ +--TEST-- +GH-19070 (setlocale($type, NULL) should not be deprecated) +--FILE-- + +--EXPECTF-- +string(%d) "%s" diff --git a/ext/standard/tests/strings/gh20906_1.phpt b/ext/standard/tests/strings/gh20906_1.phpt new file mode 100644 index 000000000000..ccb0dfbee566 --- /dev/null +++ b/ext/standard/tests/strings/gh20906_1.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-20906 (Assertion failure when messing up output buffers) - php_strip_whitespace +--CREDITS-- +vi3tL0u1s +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECTF-- +%a +Fatal error: php_strip_whitespace(): Cannot use output buffering in output buffering display handlers in %s on line %d diff --git a/ext/standard/tests/strings/gh20906_2.phpt b/ext/standard/tests/strings/gh20906_2.phpt new file mode 100644 index 000000000000..b3ea5cf6ef74 --- /dev/null +++ b/ext/standard/tests/strings/gh20906_2.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-20906 (Assertion failure when messing up output buffers) - highlight_file +--CREDITS-- +vi3tL0u1s +--FILE-- + +--EXPECTF-- +%a +Fatal error: highlight_file(): Cannot use output buffering in output buffering display handlers in %s on line %d diff --git a/ext/standard/tests/strings/gh20906_3.phpt b/ext/standard/tests/strings/gh20906_3.phpt new file mode 100644 index 000000000000..a26fc61bed65 --- /dev/null +++ b/ext/standard/tests/strings/gh20906_3.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-20906 (Assertion failure when messing up output buffers) - highlight_string +--CREDITS-- +vi3tL0u1s +--FILE-- + +--EXPECTF-- +%a +Fatal error: highlight_string(): Cannot use output buffering in output buffering display handlers in %s on line %d diff --git a/ext/standard/tests/strings/htmlentities06.phpt b/ext/standard/tests/strings/htmlentities06.phpt index c046c798d9a7..4066b6c2e680 100644 --- a/ext/standard/tests/strings/htmlentities06.phpt +++ b/ext/standard/tests/strings/htmlentities06.phpt @@ -7,7 +7,6 @@ internal_encoding=ISO-8859-15 mbstring --FILE-- diff --git a/ext/standard/tests/strings/htmlentities07.phpt b/ext/standard/tests/strings/htmlentities07.phpt index 421a1c7c7abe..7e735a434ab8 100644 --- a/ext/standard/tests/strings/htmlentities07.phpt +++ b/ext/standard/tests/strings/htmlentities07.phpt @@ -7,7 +7,6 @@ internal_encoding=ISO-8859-1 mbstring --FILE-- diff --git a/ext/standard/tests/strings/htmlentities08.phpt b/ext/standard/tests/strings/htmlentities08.phpt index 38d1d1008cad..3b177a4b9945 100644 --- a/ext/standard/tests/strings/htmlentities08.phpt +++ b/ext/standard/tests/strings/htmlentities08.phpt @@ -7,7 +7,6 @@ internal_encoding=EUC-JP mbstring --FILE-- diff --git a/ext/standard/tests/strings/htmlentities09.phpt b/ext/standard/tests/strings/htmlentities09.phpt index bdd5aa39e4aa..891cababb55a 100644 --- a/ext/standard/tests/strings/htmlentities09.phpt +++ b/ext/standard/tests/strings/htmlentities09.phpt @@ -7,7 +7,6 @@ internal_encoding=Shift_JIS mbstring --FILE-- diff --git a/ext/standard/tests/strings/join_variation3.phpt b/ext/standard/tests/strings/join_variation3.phpt index dc6661f3bf55..6e4ba433c957 100644 --- a/ext/standard/tests/strings/join_variation3.phpt +++ b/ext/standard/tests/strings/join_variation3.phpt @@ -24,12 +24,11 @@ $pieces_arrays = array ( array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value array("one" => 1, 2 => "two", 4 => "four"), //mixed - // associative array, containing null/empty/boolean values as key/value - array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + // associative array, containing empty/boolean values as key/value array(true => "true", false => "false", "false" => false, "true" => true), array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), - array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), - array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + array(1 => '', 2 => "", 5 => false, 6 => true), + array('' => 1, "" => 2, false => 5, true => 6), // array with repetitive keys array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) @@ -79,15 +78,13 @@ string(23) "ten], [twenty], [thirty" -- Iteration 12 -- string(16) "1], [two], [four" -- Iteration 13 -- -string(12) "null], [], [" --- Iteration 14 -- string(22) "true], [false], [], [1" --- Iteration 15 -- +-- Iteration 14 -- string(14) "emptys], [], [" +-- Iteration 15 -- +string(13) "], [], [], [1" -- Iteration 16 -- -string(21) "], [], [], [], [], [1" +string(11) "2], [5], [6" -- Iteration 17 -- -string(11) "4], [5], [6" --- Iteration 18 -- string(13) "10], [20], [3" Done diff --git a/ext/standard/tests/strings/ord_basic.phpt b/ext/standard/tests/strings/ord_basic.phpt index 0921dfda55aa..4e00bd0b22f5 100644 --- a/ext/standard/tests/strings/ord_basic.phpt +++ b/ext/standard/tests/strings/ord_basic.phpt @@ -15,7 +15,6 @@ var_dump(ord("@")); var_dump(ord("\n")); var_dump(ord("\x0A")); var_dump(ord("\xFF")); -var_dump(ord("Hello")); // Make sure all valid ascii chars round trip for ($i = 0; $i < 255; $i++) { @@ -37,4 +36,3 @@ int(64) int(10) int(10) int(255) -int(72) diff --git a/ext/standard/tests/strings/ord_not_1_byte.phpt b/ext/standard/tests/strings/ord_not_1_byte.phpt new file mode 100644 index 000000000000..ba019cf3dd4a --- /dev/null +++ b/ext/standard/tests/strings/ord_not_1_byte.phpt @@ -0,0 +1,15 @@ +--TEST-- +ord() with values not one byte long +--FILE-- + +--EXPECTF-- +Deprecated: ord(): Providing an empty string is deprecated in %s on line 3 +int(0) + +Deprecated: ord(): Providing a string that is not one byte long is deprecated. Use ord($str[0]) instead in %s on line 4 +int(72) diff --git a/ext/standard/tests/strings/pack.phpt b/ext/standard/tests/strings/pack.phpt index af449266671d..e71f9ce37a96 100644 --- a/ext/standard/tests/strings/pack.phpt +++ b/ext/standard/tests/strings/pack.phpt @@ -97,7 +97,7 @@ print_r(unpack("v", pack("v", -1000))); print_r(unpack("v", pack("v", -64434))); print_r(unpack("v", pack("v", -65535))); ?> ---EXPECT-- +--EXPECTF-- Array ( [1] => h @@ -143,10 +143,14 @@ Array ( [1] => -64434 ) + +Warning: The float 4294967296 is not representable as an int, cast occurred in %s on line %d Array ( [1] => 0 ) + +Warning: The float -4294967296 is not representable as an int, cast occurred in %s on line %d Array ( [1] => 0 @@ -159,10 +163,14 @@ Array ( [1] => 0 ) + +Warning: The float 2147483650 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -2147483646 ) + +Warning: The float 4294967295 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -1 @@ -179,10 +187,14 @@ Array ( [1] => 0 ) + +Warning: The float 2147483650 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -2147483646 ) + +Warning: The float 4294967296 is not representable as an int, cast occurred in %s on line %d Array ( [1] => 0 @@ -227,10 +239,14 @@ Array ( [1] => 0 ) + +Warning: The float 2147483650 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -2147483646 ) + +Warning: The float 4294967296 is not representable as an int, cast occurred in %s on line %d Array ( [1] => 0 @@ -299,10 +315,14 @@ Array ( [1] => 0 ) + +Warning: The float 2147483650 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -2147483646 ) + +Warning: The float 4294967296 is not representable as an int, cast occurred in %s on line %d Array ( [1] => 0 diff --git a/ext/standard/tests/strings/pack64.phpt b/ext/standard/tests/strings/pack64.phpt index 84e69008284d..238195287b2b 100644 --- a/ext/standard/tests/strings/pack64.phpt +++ b/ext/standard/tests/strings/pack64.phpt @@ -37,7 +37,7 @@ print_r(unpack("i", pack("i", -2147483647))); print_r(unpack("i", pack("i", -2147483648))); // Min int32 print_r(unpack("I", pack("I", 4294967295))); // Max uint32 ?> ---EXPECT-- +--EXPECTF-- Array ( [1] => 281474976710654 @@ -46,6 +46,8 @@ Array ( [1] => 0 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 @@ -54,6 +56,8 @@ Array ( [1] => -1 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 @@ -66,6 +70,8 @@ Array ( [1] => 0 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 @@ -74,6 +80,8 @@ Array ( [1] => -1 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 @@ -86,6 +94,8 @@ Array ( [1] => 0 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 @@ -94,6 +104,8 @@ Array ( [1] => -1 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 @@ -106,6 +118,8 @@ Array ( [1] => 0 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 @@ -114,6 +128,8 @@ Array ( [1] => -1 ) + +Warning: The float 9.223372036854776E+18 is not representable as an int, cast occurred in %s on line %d Array ( [1] => -9223372036854775808 diff --git a/ext/standard/tests/strings/parse_str_null_bytes.phpt b/ext/standard/tests/strings/parse_str_null_bytes.phpt new file mode 100644 index 000000000000..fd0d94bb0fc8 --- /dev/null +++ b/ext/standard/tests/strings/parse_str_null_bytes.phpt @@ -0,0 +1,14 @@ +--TEST-- +parse_str() rejects null bytes +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +parse_str(): Argument #1 ($string) must not contain any null bytes diff --git a/ext/standard/tests/strings/pathinfo.phpt b/ext/standard/tests/strings/pathinfo.phpt index 2bbea73588cb..1ff42a66121c 100644 --- a/ext/standard/tests/strings/pathinfo.phpt +++ b/ext/standard/tests/strings/pathinfo.phpt @@ -14,14 +14,48 @@ var_dump(pathinfo(__FILE__, PATHINFO_BASENAME)); var_dump(pathinfo(__FILE__, PATHINFO_FILENAME)); var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION)); var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_DIRNAME)); -var_dump(pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_BASENAME)); -var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_EXTENSION)); -var_dump(pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_BASENAME)); + +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_FILENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_EXTENSION|PATHINFO_DIRNAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_FILENAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_EXTENSION); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_DIRNAME|PATHINFO_BASENAME); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} + +try { + pathinfo(__FILE__, PATHINFO_DIRNAME-1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +try { + pathinfo(__FILE__, PATHINFO_ALL+1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} echo "Done\n"; ?> @@ -94,12 +128,12 @@ string(12) "pathinfo.php" string(8) "pathinfo" string(3) "php" string(%d) "%s%estrings" -string(%d) "%s%estrings" -string(12) "pathinfo.php" -string(3) "php" -string(12) "pathinfo.php" -string(%d) "%s%estrings" -string(12) "pathinfo.php" -string(%d) "%s%estrings" -string(%d) "%s%estrings" +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants +pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants Done diff --git a/ext/standard/tests/strings/setlocale_basic1.phpt b/ext/standard/tests/strings/setlocale_basic1.phpt index aeacba8cbe97..42d5b196ed5e 100644 --- a/ext/standard/tests/strings/setlocale_basic1.phpt +++ b/ext/standard/tests/strings/setlocale_basic1.phpt @@ -75,7 +75,11 @@ $all_system_locales = list_system_locales(); echo "Setting system locale(LC_ALL) to "; foreach($common_locales as $value) { // check if a commonly used locale is installed in the system - if(in_array($value, $all_system_locales)){ + // Solaris uses .UTF-8 canonical form, so normalize + $normalized = preg_replace('/\.utf8$/i', '.UTF-8', $value); + + if (in_array($value, $all_system_locales) || + in_array($normalized, $all_system_locales)) { echo "$value\n"; // print, this is found // set the found locale as current locale var_dump(setlocale(LC_ALL, $value )); diff --git a/ext/standard/tests/strings/setlocale_basic2.phpt b/ext/standard/tests/strings/setlocale_basic2.phpt index ab29b2647583..1e98942ae78f 100644 --- a/ext/standard/tests/strings/setlocale_basic2.phpt +++ b/ext/standard/tests/strings/setlocale_basic2.phpt @@ -75,7 +75,12 @@ $all_system_locales = list_system_locales(); // checking the currency setting of the system(use localconv()) $list_of_locales = array(); foreach($common_locales as $value) { - if( in_array($value, $all_system_locales) ) { + // Solaris uses canonical .UTF-8 form, so normalize the name + $normalized = preg_replace('/\.utf8$/i', '.UTF-8', $value); + + if (in_array($value, $all_system_locales) || + in_array($normalized, $all_system_locales)) { + $list_of_locales[] = $value; } } diff --git a/ext/standard/tests/strings/setlocale_basic3.phpt b/ext/standard/tests/strings/setlocale_basic3.phpt index de2e0bb4cc6c..c33691fec13f 100644 --- a/ext/standard/tests/strings/setlocale_basic3.phpt +++ b/ext/standard/tests/strings/setlocale_basic3.phpt @@ -37,32 +37,37 @@ function list_system_locales() { pass as argument to setlocale() */ echo "*** Testing setlocale() by passing multiple locales as argument ***\n"; +if (PHP_OS_FAMILY === 'Solaris') { + $utfending = "UTF-8"; +} else { + $utfending = "utf8"; +} //set of currency symbol according to above list of locales $currency_symbol = array( - "en_US.utf8" => "USD", - "en_AU.utf8" => "AUD", - "ko_KR.utf8" => "KRW", - "zh_CN.utf8" => "CNY", - "de_DE.utf8" => "EUR", - "es_EC.utf8" => "USD", - "fr_FR.utf8" => "EUR", - "ja_JP.utf8" => "JPY", - "el_GR.utf8" => "EUR", - "nl_NL.utf8" =>"EUR" + "en_US.$utfending" => "USD", + "en_AU.$utfending" => "AUD", + "ko_KR.$utfending" => "KRW", + "zh_CN.$utfending" => "CNY", + "de_DE.$utfending" => "EUR", + "es_EC.$utfending" => "USD", + "fr_FR.$utfending" => "EUR", + "ja_JP.$utfending" => "JPY", + "el_GR.$utfending" => "EUR", + "nl_NL.$utfending" =>"EUR" ); // gather all the locales installed in the system $all_system_locales = list_system_locales(); // Now check for three locales that is present in the system and use that as argument to setlocale() -if( in_array("en_US.utf8",$all_system_locales) || - in_array("Ko_KR.utf8",$all_system_locales) || - in_array("zh_CN.utf8",$all_system_locales) ) { +if( in_array("en_US.$utfending",$all_system_locales) || + in_array("Ko_KR.$utfending",$all_system_locales) || + in_array("zh_CN.$utfending",$all_system_locales) ) { echo "-- Testing setlocale() by giving 'category' as LC_ALL & multiple locales(en_US.utf8, Ko_KR.utf8, zh_CN.utf8) --\n"; // call setlocale() - $new_locale = setlocale(LC_ALL, "en_US.utf8", "Ko_KR.utf8", "zh_CN.utf8"); + $new_locale = setlocale(LC_ALL, "en_US.$utfending", "Ko_KR.$utfending", "zh_CN.$utfending"); // dump the name of the new locale set by setlocale() var_dump($new_locale); diff --git a/ext/standard/tests/strings/setlocale_variation1.phpt b/ext/standard/tests/strings/setlocale_variation1.phpt index 4f81fca7c461..c3709a8cfcff 100644 --- a/ext/standard/tests/strings/setlocale_variation1.phpt +++ b/ext/standard/tests/strings/setlocale_variation1.phpt @@ -37,31 +37,37 @@ function list_system_locales() { pass as argument to setlocale(), pass 2 invalid arguments along with two valid arguments*/ echo "*** Testing setlocale() by passing multiple valid/invalid locales as argument ***\n"; +if (PHP_OS_FAMILY === 'Solaris') { + $utfending = "UTF-8"; +} else { + $utfending = "utf8"; +} + //set of currency symbol according to above list of locales $currency_symbol = array( - "en_US.utf8" => "USD", - "en_AU.utf8" => "AUD", - "ko_KR.utf8" => "KRW", - "zh_CN.utf8" => "CNY", - "de_DE.utf8" => "EUR", - "es_EC.utf8" => "USD", - "fr_FR.utf8" => "EUR", - "ja_JP.utf8" => "JPY", - "el_GR.utf8" => "EUR", - "nl_NL.utf8" =>"EUR" + "en_US.$utfending" => "USD", + "en_AU.$utfending" => "AUD", + "ko_KR.$utfending" => "KRW", + "zh_CN.$utfending" => "CNY", + "de_DE.$utfending" => "EUR", + "es_EC.$utfending" => "USD", + "fr_FR.$utfending" => "EUR", + "ja_JP.$utfending" => "JPY", + "el_GR.$utfending" => "EUR", + "nl_NL.$utfending" =>"EUR" ); // gather all the locales installed in the system $all_system_locales = list_system_locales(); // Now check for three locales that is present in the system and use that as argument to setlocale() -if( in_array("en_US.utf8",$all_system_locales) || - in_array("Ko_KR.utf8",$all_system_locales) || - in_array("zh_CN.utf8",$all_system_locales) ) { +if( in_array("en_US.$utfending",$all_system_locales) || + in_array("Ko_KR.$utfending",$all_system_locales) || + in_array("zh_CN.$utfending",$all_system_locales) ) { echo "-- Testing setlocale() by giving 'category' as LC_ALL & multiple locales(en_US.invalid, en_US.utf8, Ko_KR.utf8, KO_KR.invalid, zh_CN.utf8) --\n"; // call setlocale() - $new_locale = setlocale(LC_ALL, "en_US.invalid", "en_US.utf8", "Ko_KR.utf8", "KO_KR.invalid", "zh_CN.utf8"); + $new_locale = setlocale(LC_ALL, "en_US.invalid", "en_US.$utfending", "Ko_KR.$utfending", "KO_KR.invalid", "zh_CN.$utfending"); // dump the name of the new locale set by setlocale() var_dump($new_locale); diff --git a/ext/standard/tests/strings/setlocale_variation2.phpt b/ext/standard/tests/strings/setlocale_variation2.phpt index 6f62f71ac1f2..c6d44c4a54c2 100644 --- a/ext/standard/tests/strings/setlocale_variation2.phpt +++ b/ext/standard/tests/strings/setlocale_variation2.phpt @@ -5,6 +5,9 @@ Test setlocale() function : usage variations - Setting all available locales in if (substr(PHP_OS, 0, 3) == 'WIN') { die('skip Not valid for windows'); } +if (PHP_OS_FAMILY === 'Solaris') { + die("skip Some locales on Solaris (e.g. iso_8859_1) are incomplete, cannot test LC_ALL"); +} exec("locale -a", $output, $exit_code); if ($exit_code !== 0) { die("skip locale -a not available"); diff --git a/ext/standard/tests/strings/str_increment_polyfill.phpt b/ext/standard/tests/strings/str_increment_polyfill.phpt index 36ad262598f4..1f9f948aa200 100644 --- a/ext/standard/tests/strings/str_increment_polyfill.phpt +++ b/ext/standard/tests/strings/str_increment_polyfill.phpt @@ -10,9 +10,9 @@ function polyfill(string $s): string { /* Using increment operator would cast the string to float * Therefore we manually increment it to convert it to an "f"/"F" that doesn't get affected */ $c = $s[$offset]; - $c++; + @$c++; $s[$offset] = $c; - $s++; + @$s++; $s[$offset] = match ($s[$offset]) { 'f' => 'e', 'F' => 'E', @@ -22,7 +22,7 @@ function polyfill(string $s): string { return $s; } } - return ++$s; + return @++$s; } $strictlyAlphaNumeric = [ diff --git a/ext/standard/tests/strings/str_replace_variation2.phpt b/ext/standard/tests/strings/str_replace_variation2.phpt index 957c990555ea..d8dcd58e1b60 100644 --- a/ext/standard/tests/strings/str_replace_variation2.phpt +++ b/ext/standard/tests/strings/str_replace_variation2.phpt @@ -12,7 +12,7 @@ precision=14 echo "\n*** Testing str_replace() with various subjects ***"; $subject = "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE\000 \x000\x5ACD\0abcd \xXYZ\tabcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)"; + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)"; /* needles in an array to be compared in the string $string */ $search_str = array ( @@ -48,7 +48,7 @@ $search_str = array ( 'b', '\t', "\t", - chr(128).chr(234).chr(65).chr(255).chr(256), + chr(128).chr(234).chr(65).chr(255).chr(0), $subject ); @@ -65,233 +65,233 @@ for( $i = 0; $i < count($search_str); $i++ ) { *** Testing str_replace() with various subjects *** --- Iteration 0 --- -- String after replacing the search value is => -- -string(181) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(179) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!FOUND - ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 1 --- -- String after replacing the search value is => -- -string(181) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(179) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!FOUND - ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?FOUND chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 2 --- -- String after replacing the search value is => -- -string(186) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(184) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: FOUND - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 3 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 4 --- -- String after replacing the search value is => -- -string(186) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(184) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $FOUND: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 5 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 6 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 7 --- -- String after replacing the search value is => -- -string(193) "Hello, world,0120333.3445FOUND67 NULL TRUE FALSE%0 +string(191) "Hello, world,0120333.3445FOUND67 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 8 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 9 --- -- String after replacing the search value is => -- -string(197) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0FOUND \xXYZ FOUND $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 10 --- -- String after replacing the search value is => -- -string(197) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xFOUND abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 11 --- -- String after replacing the search value is => -- -string(196) "Hello, world,0120333.3445-1.234567 FOUND TRUE FALSE%0 +string(194) "Hello, world,0120333.3445-1.234567 FOUND TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 12 --- -- String after replacing the search value is => -- -string(211) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 +string(213) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 %0FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '4' times + ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(FOUND)" +-- search string has found '5' times --- Iteration 13 --- -- String after replacing the search value is => -- -string(211) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 +string(213) "Hello, world,FOUND12FOUND333.3445-1.234567 NULL TRUE FALSE%0 %0FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(256)" --- search string has found '4' times + ?Hello, World chr(FOUND).chr(128).chr(234).chr(65).chr(255).chr(FOUND)" +-- search string has found '5' times --- Iteration 14 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 15 --- -- String after replacing the search value is => -- -string(335) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 +string(333) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND%00ZCD%0abcdFOUND\xXYZ abcdFOUND$$@#%^&*!~,.:;?:FOUND!!Hello,FOUNDWorld -FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" +FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '35' times --- Iteration 16 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSEFOUND +string(205) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSEFOUND FOUND0ZCDFOUNDabcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 17 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 18 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00FOUNDD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 19 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 FOUNDZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 20 --- -- String after replacing the search value is => -- -string(198) "Hello, world,0120333FOUND445-1.234567 NULL TRUE FALSE%0 +string(196) "Hello, world,0120333FOUND445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 21 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 +string(205) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 22 --- -- String after replacing the search value is => -- -string(196) "Hello, world,0120333.3445-1.234567 NULL FOUND FALSE%0 +string(194) "Hello, world,0120333.3445-1.234567 NULL FOUND FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 23 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 +string(205) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 24 --- -- String after replacing the search value is => -- -string(207) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 +string(205) "Hello, world,0FOUND20333.3445-FOUND.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(FOUND28).chr(234).chr(65).chr(255).chr(0)" -- search string has found '3' times --- Iteration 25 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 26 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FOUND%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FOUND%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 27 --- -- String after replacing the search value is => -- -string(335) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 +string(333) "Hello,FOUNDworld,0120333.3445-1.234567FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDNULLFOUNDTRUEFOUNDFALSE%0 FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND%00ZCD%0abcdFOUND\xXYZ abcdFOUND$$@#%^&*!~,.:;?:FOUND!!Hello,FOUNDWorld -FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" +FOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUNDFOUND?Hello,FOUNDWorldFOUNDchr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '35' times --- Iteration 28 --- -- String after replacing the search value is => -- -string(190) "Hello, world,0120333.3445-1.234567FOUNDNULL TRUE FALSE%0 +string(188) "Hello, world,0120333.3445-1.234567FOUNDNULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 29 --- -- String after replacing the search value is => -- -string(203) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(201) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0aFOUNDcd \xXYZ aFOUNDcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '2' times --- Iteration 30 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 31 --- -- String after replacing the search value is => -- -string(199) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(197) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZFOUNDabcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '1' times --- Iteration 32 --- -- String after replacing the search value is => -- -string(195) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 +string(193) "Hello, world,0120333.3445-1.234567 NULL TRUE FALSE%0 %00ZCD%0abcd \xXYZ abcd $$@#%^&*!~,.:;?: !!Hello, World - ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(256)" + ?Hello, World chr(0).chr(128).chr(234).chr(65).chr(255).chr(0)" -- search string has found '0' times --- Iteration 33 --- diff --git a/ext/standard/tests/strings/strcasecmp.phpt b/ext/standard/tests/strings/strcasecmp.phpt index e55b2a684fb2..1136774b38ac 100644 --- a/ext/standard/tests/strings/strcasecmp.phpt +++ b/ext/standard/tests/strings/strcasecmp.phpt @@ -9,7 +9,7 @@ precision = 12 echo "#### Basic and Possible operations ####"; /* creating an array of strings to be compared */ $arrays = array( - array("a", 'A', chr(128), chr(255), chr(256)), + array("a", 'A', chr(128), chr(255), chr(0)), array("acc", "Acc", 'aC', "acCc", 'acd', "?acc", 'Acc!', "$!acc", ";acc"), array("1", "0", 0, "-1", -1, "", TRUE, true, FALSE, "string"), array(10.5, 1.5, 9.5, 11.5, 100.5, 10.5E1, -10.5, 10, 0.5) diff --git a/ext/standard/tests/strings/strcmp.phpt b/ext/standard/tests/strings/strcmp.phpt index 5310566d53b6..fa94a9cc3a01 100644 --- a/ext/standard/tests/strings/strcmp.phpt +++ b/ext/standard/tests/strings/strcmp.phpt @@ -9,7 +9,7 @@ precision = 12 echo "#### Basic and Possible operations ####"; /* creating an array of strings to be compared */ $arrays = array( - array("a", "A", 'a', 'A', chr(128), chr(255), chr(256)), + array("a", "A", 'a', 'A', chr(128), chr(255), chr(0)), array("acc", "Acc", 'ac', "accc", 'acd', "?acc", 'acc!', "$!acc", ";acc"), array("1", "0", 0, "-1", -1, "", TRUE, FALSE, "string"), array(10.5, 1.5, 9.5, 11.5, 100.5, 10.5E1, -10.5, 10, 0.5) diff --git a/ext/standard/tests/strings/strlen.phpt b/ext/standard/tests/strings/strlen.phpt index b98111f15e67..b1ff4f4e74d9 100644 --- a/ext/standard/tests/strings/strlen.phpt +++ b/ext/standard/tests/strings/strlen.phpt @@ -24,8 +24,8 @@ $strings = array( "Hello, World", "\0000", // len = 2 "0", 0, - "\t", // len = 1 - '\t', // len = 2 + "\t", // len = 1 + '\t', // len = 2 TRUE, FALSE, "Hello, World\0", @@ -36,7 +36,7 @@ $strings = array( "Hello, World", "Hello, World\t", "Hello, World\\", " ", - chr(128).chr(234).chr(65).chr(255).chr(256), + chr(128).chr(234).chr(65).chr(255).chr(0), "abcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_+=|?><-;:$ []{}{{{}}}[[[[]][]]]***&&&^^%$###@@!!@#$%&^&**/////|\\\\\\ @@ -113,11 +113,11 @@ var_dump(strlen("{$str}S")); echo "\n--- strlen for long float values ---\n"; /* Here two different outputs, which depends on the rounding value before converting to string. Here Precision = 12 */ -var_dump(strlen(10.55555555555555555555555555)); // len = 13 -var_dump(strlen(10.55555555595555555555555555)); // len = 12 +var_dump(strlen(10.55555555555555555555555555)); // len = 13 +var_dump(strlen(10.55555555595555555555555555)); // len = 12 echo "\n--- Nested strlen() ---\n"; -var_dump(strlen(strlen("Hello"))); // len=1 +var_dump(strlen(strlen("Hello"))); // len=1 echo "Done\n"; ?> diff --git a/ext/standard/tests/strings/strncasecmp_variation6.phpt b/ext/standard/tests/strings/strncasecmp_variation6.phpt index 78a0ddd549bf..3a7b90616a2d 100644 --- a/ext/standard/tests/strings/strncasecmp_variation6.phpt +++ b/ext/standard/tests/strings/strncasecmp_variation6.phpt @@ -10,7 +10,7 @@ echo "*** Test strncasecmp() function: with binary inputs ***\n"; echo "\n-- Checking with all 256 characters given, in binary format --\n"; /* loop through to get all 256 character's equivalent binary value, and check working of strncasecmp() */ $count = 1; -for($ASCII = 0; $ASCII <= 255; $ASCII++) { +for($ASCII = 0; $ASCII < 255; $ASCII++) { $str1 = decbin($ASCII); //ASCII value in binary form $str2 = decbin( ord( chr($ASCII) ) ); //Getting equivalent ASCII value for the character in binary form echo "-- Iteration $count --\n"; @@ -21,7 +21,7 @@ for($ASCII = 0; $ASCII <= 255; $ASCII++) { echo "\n-- Checking with out of character's range, given in binary format --\n"; $str1 = decbin(256); -$str2 = decbin( ord( chr(256) )); +$str2 = decbin( ord( chr(0) )); var_dump( strncasecmp($str1, $str2, 8) ); //comparing all the 8-bits; expected: int(1) echo "\n*** Done ***\n"; @@ -795,9 +795,6 @@ int(0) -- Iteration 255 -- int(0) int(0) --- Iteration 256 -- -int(0) -int(0) -- Checking with out of character's range, given in binary format -- int(1) diff --git a/ext/standard/tests/strings/strpos_variation1.phpt b/ext/standard/tests/strings/strpos_variation1.phpt index f28517316dc4..d01b9eba24d7 100644 --- a/ext/standard/tests/strings/strpos_variation1.phpt +++ b/ext/standard/tests/strings/strpos_variation1.phpt @@ -9,8 +9,8 @@ echo bin2hex( chr(128) ) ." => "; var_dump( strpos($string, chr(128)) ); echo bin2hex( chr(255) ) ." => "; var_dump( strpos($string, chr(255), 3) ); -echo bin2hex( chr(256) ) ." => "; -var_dump( strpos($string, chr(256)) ); +echo bin2hex( chr(0) ) ." => "; +var_dump( strpos($string, chr(0)) ); ?> DONE diff --git a/ext/standard/tests/strings/strstr_variation1.phpt b/ext/standard/tests/strings/strstr_variation1.phpt index aade1fd5f85d..30699702f889 100644 --- a/ext/standard/tests/strings/strstr_variation1.phpt +++ b/ext/standard/tests/strings/strstr_variation1.phpt @@ -9,8 +9,8 @@ echo bin2hex( chr(128) ) ." => "; var_dump( bin2hex( strstr($string, chr(128) ) ) ); echo bin2hex( chr(255) ) ." => "; var_dump( bin2hex( strstr($string, chr(255) ) ) ); -echo bin2hex( chr(256) ) ." => "; -var_dump( bin2hex( strstr($string, chr(256) ) ) ); +echo bin2hex( chr(0) ) ." => "; +var_dump( bin2hex( strstr($string, chr(0) ) ) ); ?> DONE diff --git a/ext/standard/tests/strings/substr_count_variation_001.phpt b/ext/standard/tests/strings/substr_count_variation_001.phpt index d76c56d60fb2..d7ac3dcd22d6 100644 --- a/ext/standard/tests/strings/substr_count_variation_001.phpt +++ b/ext/standard/tests/strings/substr_count_variation_001.phpt @@ -14,10 +14,10 @@ var_dump( substr_count("abcabcabcabcabc", "abca") ); var_dump( substr_count("abcabcabcabcabc", "abca", 2) ); echo "\n-- complex strings containing other than 7-bit chars --\n"; -$str = chr(128).chr(129).chr(128).chr(256).chr(255).chr(254).chr(255); +$str = chr(128).chr(129).chr(128).chr(0).chr(255).chr(254).chr(255); var_dump(substr_count($str, chr(128))); var_dump(substr_count($str, chr(255))); -var_dump(substr_count($str, chr(256))); +var_dump(substr_count($str, chr(0))); echo "\n-- heredoc string --\n"; $string = << --EXPECT-- @@ -36,3 +39,6 @@ bool(true) bool(true) bool(true) bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/strings/vprintf_variation12.phpt b/ext/standard/tests/strings/vprintf_variation12.phpt index cac53da18f4d..f2e4270af310 100644 --- a/ext/standard/tests/strings/vprintf_variation12.phpt +++ b/ext/standard/tests/strings/vprintf_variation12.phpt @@ -74,10 +74,16 @@ foreach($args_array as $args) { } ?> ---EXPECT-- +--EXPECTF-- *** Testing vprintf() : octal formats and non-octal values *** -- Iteration 1 -- + +Warning: The float 20000000000 is not representable as an int, cast occurred in %s on line %d + +Warning: The float 2000000000000 is not representable as an int, cast occurred in %s on line %d + +Warning: The float 22000000000000 is not representable as an int, cast occurred in %s on line %d 2 0 12 361100 37777775456 2322 diff --git a/ext/standard/tests/strings/vprintf_variation14.phpt b/ext/standard/tests/strings/vprintf_variation14.phpt index ce65e8726d87..4bda95917770 100644 --- a/ext/standard/tests/strings/vprintf_variation14.phpt +++ b/ext/standard/tests/strings/vprintf_variation14.phpt @@ -75,10 +75,16 @@ foreach($args_array as $args) { } ?> ---EXPECT-- +--EXPECTF-- *** Testing vprintf() : hexa formats and non-hexa values *** -- Iteration 1 -- + +Warning: The float 20000000000 is not representable as an int, cast occurred in %s on line %d + +Warning: The float 2000000000000 is not representable as an int, cast occurred in %s on line %d + +Warning: The float 22000000000000 is not representable as an int, cast occurred in %s on line %d 2 0 a 1e240 x fffffb2e 4d2 diff --git a/ext/standard/tests/strings/vprintf_variation15.phpt b/ext/standard/tests/strings/vprintf_variation15.phpt index c8ae74f2aa75..2eda443ebb95 100644 --- a/ext/standard/tests/strings/vprintf_variation15.phpt +++ b/ext/standard/tests/strings/vprintf_variation15.phpt @@ -44,7 +44,7 @@ foreach($formats as $format) { } ?> ---EXPECT-- +--EXPECTF-- *** Testing vprintf() : unsigned formats and unsigned values *** -- Iteration 1 -- @@ -52,10 +52,14 @@ foreach($formats as $format) { int(16) -- Iteration 2 -- + +Warning: The float 12345678900 is not representable as an int, cast occurred in %s on line %d 3755744308 1234 12345 int(21) -- Iteration 3 -- + +Warning: The float 101234567000 is not representable as an int, cast occurred in %s on line %d 1234000 2450319192 120 int(25) diff --git a/ext/standard/tests/strings/vprintf_variation15_64bit.phpt b/ext/standard/tests/strings/vprintf_variation15_64bit.phpt index 2729e8f54af7..0ccb490095aa 100644 --- a/ext/standard/tests/strings/vprintf_variation15_64bit.phpt +++ b/ext/standard/tests/strings/vprintf_variation15_64bit.phpt @@ -44,7 +44,7 @@ foreach($formats as $format) { } ?> ---EXPECT-- +--EXPECTF-- *** Testing vprintf() : unsigned formats and unsigned values *** -- Iteration 1 -- @@ -56,6 +56,8 @@ int(16) int(22) -- Iteration 3 -- + +Warning: The float 1.0E+21 is not representable as an int, cast occurred in %s on line %d 1234000 3875820019684212736 120 int(34) diff --git a/ext/standard/tests/strings/vprintf_variation16.phpt b/ext/standard/tests/strings/vprintf_variation16.phpt index 70ecdab99e07..c064b7c4f0c7 100644 --- a/ext/standard/tests/strings/vprintf_variation16.phpt +++ b/ext/standard/tests/strings/vprintf_variation16.phpt @@ -66,10 +66,16 @@ foreach($args_array as $args) { $counter++; } ?> ---EXPECT-- +--EXPECTF-- *** Testing vprintf() : unsigned formats and signed & other types of values *** -- Iteration 1 -- + +Warning: The float 20000000000 is not representable as an int, cast occurred in %s on line %d + +Warning: The float 2000000000000 is not representable as an int, cast occurred in %s on line %d + +Warning: The float 22000000000000 is not representable as an int, cast occurred in %s on line %d 2 0 10 123456 123456 1234 2820130816 2840207360 1177509888 diff --git a/ext/standard/tests/strings/vprintf_variation4.phpt b/ext/standard/tests/strings/vprintf_variation4.phpt index 63018a9db8a8..96836f83ee61 100644 --- a/ext/standard/tests/strings/vprintf_variation4.phpt +++ b/ext/standard/tests/strings/vprintf_variation4.phpt @@ -67,10 +67,12 @@ foreach($args_array as $args) { } ?> ---EXPECT-- +--EXPECTF-- *** Testing vprintf() : int formats and non-integer values *** -- Iteration 1 -- + +Warning: The float 20000000000 is not representable as an int, cast occurred in %s on line %d 2 +0 10 123456 -1234 1234 -1474836480 200000 4000 22000000 diff --git a/ext/standard/tests/time/strptime_basic.phpt b/ext/standard/tests/time/strptime_basic.phpt index 17008e97d81c..cbb713471349 100644 --- a/ext/standard/tests/time/strptime_basic.phpt +++ b/ext/standard/tests/time/strptime_basic.phpt @@ -5,8 +5,8 @@ Test strptime() function : basic functionality if (!function_exists('strptime')) { die("skip - strptime() function not available in this build"); } -if (PHP_OS_FAMILY == 'Darwin' || PHP_OS_FAMILY == 'BSD') { - die("skip strptime() behaves differently on Darwin/BSD"); +if (PHP_OS_FAMILY == 'Darwin' || PHP_OS_FAMILY == 'BSD' || PHP_OS_FAMILY == 'Solaris' ) { + die("skip strptime() behaves differently on Darwin/BSD/Solaris"); } if (!@strftime('%Z')) die('skip strftime does not support %Z'); ?> diff --git a/ext/standard/tests/versioning/version_compare.phpt b/ext/standard/tests/versioning/version_compare.phpt index 07550dd410f4..e22ddabfa56b 100644 --- a/ext/standard/tests/versioning/version_compare.phpt +++ b/ext/standard/tests/versioning/version_compare.phpt @@ -22,6 +22,9 @@ foreach ($special_forms as $f1) { test("1.0$f1", "1.0$f2"); } } +test("1.2.", "1.2."); +test("1.2..", "1.2.."); + print "TESTING OPERATORS\n"; foreach ($special_forms as $f1) { foreach ($special_forms as $f2) { @@ -106,6 +109,8 @@ TESTING COMPARE 1.0pl1 > 1.0rc1 1.0pl1 > 1.0 1.0pl1 = 1.0pl1 +1.2. = 1.2. +1.2.. = 1.2.. TESTING OPERATORS 1.0-dev lt 1.0-dev : false 1.0-dev < 1.0-dev : false diff --git a/ext/standard/type.c b/ext/standard/type.c index 4557014ff5a3..fc681a3c50a7 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ @@ -105,7 +103,7 @@ PHP_FUNCTION(settype) convert_to_long(ptr); } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_FLOAT))) { convert_to_double(ptr); - } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_DOUBLE))) { /* deprecated */ + } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_DOUBLE))) { convert_to_double(ptr); } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_STRING))) { convert_to_string(ptr); @@ -151,8 +149,7 @@ PHP_FUNCTION(intval) ZEND_PARSE_PARAMETERS_END(); if (Z_TYPE_P(num) != IS_STRING || base == 10) { - RETVAL_LONG(zval_get_long(num)); - return; + RETURN_LONG(zval_get_long(num)); } @@ -160,7 +157,7 @@ PHP_FUNCTION(intval) char *strval = Z_STRVAL_P(num); size_t strlen = Z_STRLEN_P(num); - while (isspace(*strval) && strlen) { + while (isspace((unsigned char)*strval) && strlen) { strval++; strlen--; } @@ -173,14 +170,17 @@ PHP_FUNCTION(intval) } if (strval[offset] == '0' && (strval[offset + 1] == 'b' || strval[offset + 1] == 'B')) { + if (strval[0] != '-') { + /* Either "+0b", or "0b" */ + RETURN_LONG(ZEND_STRTOL(strval + 2 + offset, NULL, 2)); + } + char *tmpval; strlen -= 2; /* Removing "0b" */ tmpval = emalloc(strlen + 1); - /* Place the unary symbol at pos 0 if there was one */ - if (offset) { - tmpval[0] = strval[0]; - } + /* Place the unary symbol at pos 0 */ + tmpval[0] = '-'; /* Copy the data from after "0b" to the end of the buffer */ memcpy(tmpval + offset, strval + offset + 2, strlen - offset); @@ -341,13 +341,12 @@ PHP_FUNCTION(is_object) } /* }}} */ -static inline void _zend_is_numeric(zval *return_value, zval *arg) +static zend_always_inline void _zend_is_numeric(zval *return_value, zval *arg) { switch (Z_TYPE_P(arg)) { case IS_LONG: case IS_DOUBLE: RETURN_TRUE; - break; case IS_STRING: if (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), NULL, NULL, 0)) { @@ -359,7 +358,6 @@ static inline void _zend_is_numeric(zval *return_value, zval *arg) default: RETURN_FALSE; - break; } } @@ -401,11 +399,9 @@ PHP_FUNCTION(is_scalar) case IS_LONG: case IS_STRING: RETURN_TRUE; - break; default: RETURN_FALSE; - break; } } /* }}} */ diff --git a/ext/standard/uniqid.c b/ext/standard/uniqid.c index c0b9555ccefd..267851cd73ac 100644 --- a/ext/standard/uniqid.c +++ b/ext/standard/uniqid.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ diff --git a/ext/standard/url.c b/ext/standard/url.c index 504805484ef2..ac303027a722 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ @@ -93,7 +91,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port php_url *ret = ecalloc(1, sizeof(php_url)); char const *s, *e, *p, *pp, *ue; - *has_port = 0; + *has_port = false; s = str; ue = s + length; @@ -103,7 +101,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port p = s; while (p < e) { /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */ - if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') { + if (!isalpha((unsigned char)*p) && !isdigit((unsigned char)*p) && *p != '+' && *p != '.' && *p != '-') { if (e + 1 < ue && e < binary_strcspn(s, ue, "?#")) { goto parse_port; } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ @@ -132,7 +130,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port * correctly parse things like a.com:80 */ p = e + 1; - while (p < ue && isdigit(*p)) { + while (p < ue && isdigit((unsigned char)*p)) { p++; } @@ -172,7 +170,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port p = e + 1; pp = p; - while (pp < ue && pp - p < 6 && isdigit(*pp)) { + while (pp < ue && pp - p < 6 && isdigit((unsigned char)*pp)) { pp++; } @@ -183,7 +181,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port port_buf[pp - p] = '\0'; port = ZEND_STRTOL(port_buf, &end, 10); if (port >= 0 && port <= 65535 && end != port_buf) { - *has_port = 1; + *has_port = true; ret->port = (unsigned short) port; if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ s += 2; @@ -249,7 +247,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port port_buf[e - p] = '\0'; port = ZEND_STRTOL(port_buf, &end, 10); if (port >= 0 && port <= 65535 && end != port_buf) { - *has_port = 1; + *has_port = true; ret->port = (unsigned short)port; } else { php_url_free(ret); @@ -591,8 +589,8 @@ PHPAPI size_t php_url_decode_ex(char *dest, const char *src, size_t src_len) if (*data == '+') { *dest = ' '; } - else if (*data == '%' && src_len >= 2 && isxdigit((int) *(data + 1)) - && isxdigit((int) *(data + 2))) { + else if (*data == '%' && src_len >= 2 && isxdigit((unsigned char)data[1]) + && isxdigit((unsigned char)data[2])) { *dest = (char) php_htoi(data + 1); data += 2; src_len -= 2; @@ -664,8 +662,8 @@ PHPAPI size_t php_raw_url_decode_ex(char *dest, const char *src, size_t src_len) const char *data = src; while (src_len--) { - if (*data == '%' && src_len >= 2 && isxdigit((int) *(data + 1)) - && isxdigit((int) *(data + 2))) { + if (*data == '%' && src_len >= 2 && isxdigit((unsigned char)data[1]) + && isxdigit((unsigned char)data[2])) { *dest = (char) php_htoi(data + 1); data += 2; src_len -= 2; @@ -732,7 +730,7 @@ PHP_FUNCTION(get_headers) c = *p; *p = '\0'; s = p + 1; - while (isspace((int)*(unsigned char *)s)) { + while (isspace((unsigned char)*s)) { s++; } diff --git a/ext/standard/url.h b/ext/standard/url.h index 3885ecece578..f807ed67cf9b 100644 --- a/ext/standard/url.h +++ b/ext/standard/url.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Jim Winstead | +----------------------------------------------------------------------+ diff --git a/ext/standard/url_scanner_ex.h b/ext/standard/url_scanner_ex.h index e6b296324298..c39b71eebf8c 100644 --- a/ext/standard/url_scanner_ex.h +++ b/ext/standard/url_scanner_ex.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index e3c4477cde36..506f2d08378e 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | | Yasuo Ohgaki | @@ -85,7 +83,7 @@ static zend_result php_ini_on_update_tags(zend_ini_entry *entry, zend_string *ne *val++ = '\0'; for (q = key; *q; q++) { - *q = tolower(*q); + *q = tolower((unsigned char)*q); } keylen = q - key; str = zend_string_init(key, keylen, 1); @@ -137,7 +135,7 @@ static zend_result php_ini_on_update_hosts(zend_ini_entry *entry, zend_string *n char *q; for (q = key; *q; q++) { - *q = tolower(*q); + *q = tolower((unsigned char)*q); } keylen = q - key; if (keylen > 0) { @@ -245,32 +243,32 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->scheme) { - smart_str_appends(dest, ZSTR_VAL(url_parts->scheme)); + smart_str_append(dest, url_parts->scheme); smart_str_appends(dest, "://"); } else if (*(ZSTR_VAL(url->s)) == '/' && *(ZSTR_VAL(url->s)+1) == '/') { smart_str_appends(dest, "//"); } if (url_parts->user) { - smart_str_appends(dest, ZSTR_VAL(url_parts->user)); + smart_str_append(dest, url_parts->user); if (url_parts->pass) { - smart_str_appends(dest, ZSTR_VAL(url_parts->pass)); + smart_str_append(dest, url_parts->pass); smart_str_appendc(dest, ':'); } smart_str_appendc(dest, '@'); } if (url_parts->host) { - smart_str_appends(dest, ZSTR_VAL(url_parts->host)); + smart_str_append(dest, url_parts->host); } if (url_parts->port) { smart_str_appendc(dest, ':'); smart_str_append_unsigned(dest, (long)url_parts->port); } if (url_parts->path) { - smart_str_appends(dest, ZSTR_VAL(url_parts->path)); + smart_str_append(dest, url_parts->path); } smart_str_appendc(dest, '?'); if (url_parts->query) { - smart_str_appends(dest, ZSTR_VAL(url_parts->query)); + smart_str_append(dest, url_parts->query); smart_str_append(dest, separator); smart_str_append_smart_str(dest, url_app); } else { @@ -278,7 +276,7 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st } if (url_parts->fragment) { smart_str_appendc(dest, '#'); - smart_str_appends(dest, ZSTR_VAL(url_parts->fragment)); + smart_str_append(dest, url_parts->fragment); } php_url_free(url_parts); } @@ -463,7 +461,7 @@ static inline void handle_tag(STD_PARA) } smart_str_appendl(&ctx->tag, start, YYCURSOR - start); for (i = 0; i < ZSTR_LEN(ctx->tag.s); i++) - ZSTR_VAL(ctx->tag.s)[i] = tolower((int)(unsigned char)ZSTR_VAL(ctx->tag.s)[i]); + ZSTR_VAL(ctx->tag.s)[i] = tolower((unsigned char)ZSTR_VAL(ctx->tag.s)[i]); /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */ if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ZSTR_VAL(ctx->tag.s), ZSTR_LEN(ctx->tag.s))) != NULL) { ok = 1; @@ -601,7 +599,7 @@ PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, co if (encode) { encoded = php_raw_url_encode(name, strlen(name)); - smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&url_app, encoded); zend_string_free(encoded); } else { smart_str_appends(&url_app, name); @@ -609,7 +607,7 @@ PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, co smart_str_appendc(&url_app, '='); if (encode) { encoded = php_raw_url_encode(value, strlen(value)); - smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&url_app, encoded); zend_string_free(encoded); } else { smart_str_appends(&url_app, value); @@ -663,7 +661,7 @@ static void php_url_scanner_ex_activate(bool is_session) ctx = &BG(url_adapt_output_ex); } - memset(ctx, 0, XtOffsetOf(url_adapt_state_ex_t, tags)); + memset(ctx, 0, offsetof(url_adapt_state_ex_t, tags)); } static void php_url_scanner_ex_deactivate(bool is_session) @@ -701,7 +699,7 @@ static inline void php_url_scanner_session_handler_impl(char *output, size_t out len = UINT_MAX; } *handled_output_len = len; - } else if (ZSTR_LEN(url_state->url_app.s) == 0) { + } else { url_adapt_state_ex_t *ctx = url_state; if (ctx->buf.s && ZSTR_LEN(ctx->buf.s)) { smart_str_append(&ctx->result, ctx->buf.s); @@ -715,8 +713,6 @@ static inline void php_url_scanner_session_handler_impl(char *output, size_t out } else { *handled_output = estrndup(output, *handled_output_len = output_len); } - } else { - *handled_output = NULL; } } @@ -762,13 +758,13 @@ static inline void php_url_scanner_add_var_impl(const char *name, size_t name_le if (encode) { encoded = php_raw_url_encode(name, name_len); - smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&sname, encoded); zend_string_free(encoded); encoded = php_raw_url_encode(value, value_len); - smart_str_appendl(&svalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&svalue, encoded); zend_string_free(encoded); encoded = php_escape_html_entities_ex((const unsigned char *) name, name_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, NULL, /* double_encode */ 0, /* quiet */ 1); - smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&hname, encoded); zend_string_free(encoded); encoded = php_escape_html_entities_ex((const unsigned char *) value, value_len, 0, ENT_QUOTES|ENT_SUBSTITUTE, NULL, /* double_encode */ 0, /* quiet */ 1); - smart_str_appendl(&hvalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); zend_string_free(encoded); + smart_str_append(&hvalue, encoded); zend_string_free(encoded); } else { smart_str_appendl(&sname, name, name_len); smart_str_appendl(&svalue, value, value_len); @@ -869,14 +865,14 @@ static inline zend_result php_url_scanner_reset_var_impl(zend_string *name, int if (encode) { encoded = php_raw_url_encode(ZSTR_VAL(name), ZSTR_LEN(name)); - smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&sname, encoded); zend_string_free(encoded); encoded = php_escape_html_entities_ex((const unsigned char *) ZSTR_VAL(name), ZSTR_LEN(name), 0, ENT_QUOTES|ENT_SUBSTITUTE, SG(default_charset), /* double_encode */ 0, /* quiet */ 1); - smart_str_appendl(&hname, ZSTR_VAL(encoded), ZSTR_LEN(encoded)); + smart_str_append(&hname, encoded); zend_string_free(encoded); } else { - smart_str_appendl(&sname, ZSTR_VAL(name), ZSTR_LEN(name)); - smart_str_appendl(&hname, ZSTR_VAL(name), ZSTR_LEN(name)); + smart_str_append(&sname, name); + smart_str_append(&hname, name); } smart_str_0(&sname); smart_str_0(&hname); diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index d91e168ce53a..ae4132733bec 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: | | Wez Furlong (wez@thebrainroom.com) | @@ -48,6 +46,17 @@ PHP_METHOD(php_user_filter, filter) RETURN_LONG(PSFS_ERR_FATAL); } +PHP_METHOD(php_user_filter, seek) +{ + zend_long offset, whence, chain; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &offset, &whence, &chain) == FAILURE) { + RETURN_THROWS(); + } + + RETURN_TRUE; +} + PHP_METHOD(php_user_filter, onCreate) { ZEND_PARSE_PARAMETERS_NONE(); @@ -123,6 +132,36 @@ static void userfilter_dtor(php_stream_filter *thisfilter) zval_ptr_dtor(obj); } +static zend_result userfilter_assign_stream(php_stream *stream, zval *obj, + zend_string **stream_name_p, uint32_t orig_no_fclose) +{ + /* Give the userfilter class a hook back to the stream */ + const zend_class_entry *old_scope = EG(fake_scope); + EG(fake_scope) = Z_OBJCE_P(obj); + + zend_string *stream_name = ZSTR_INIT_LITERAL("stream", false); + bool stream_property_exists = Z_OBJ_HT_P(obj)->has_property(Z_OBJ_P(obj), stream_name, ZEND_PROPERTY_EXISTS, NULL); + if (stream_property_exists) { + zval stream_zval; + php_stream_to_zval(stream, &stream_zval); + zend_update_property_ex(Z_OBJCE_P(obj), Z_OBJ_P(obj), stream_name, &stream_zval); + /* If property update threw an exception, skip filter execution */ + if (EG(exception)) { + EG(fake_scope) = old_scope; + zend_string_release(stream_name); + stream->flags &= ~PHP_STREAM_FLAG_NO_FCLOSE; + stream->flags |= orig_no_fclose; + return FAILURE; + } + *stream_name_p = stream_name; + } else { + zend_string_release(stream_name); + } + EG(fake_scope) = old_scope; + + return SUCCESS; +} + static php_stream_filter_status_t userfilter_filter( php_stream *stream, php_stream_filter *thisfilter, @@ -148,12 +187,12 @@ static php_stream_filter_status_t userfilter_filter( uint32_t orig_no_fclose = stream->flags & PHP_STREAM_FLAG_NO_FCLOSE; stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE; - zval *stream_prop = zend_hash_str_find_ind(Z_OBJPROP_P(obj), "stream", sizeof("stream")-1); - if (stream_prop) { - /* Give the userfilter class a hook back to the stream */ - zval_ptr_dtor(stream_prop); - php_stream_to_zval(stream, stream_prop); - Z_ADDREF_P(stream_prop); + zend_string *stream_name = NULL; + if (userfilter_assign_stream(stream, obj, &stream_name, orig_no_fclose) == FAILURE) { + if (buckets_in->head) { + php_error_docref(NULL, E_WARNING, "Unprocessed filter buckets remaining on input brigade"); + } + return PSFS_ERR_FATAL; } ZVAL_STRINGL(&func_name, "filter", sizeof("filter")-1); @@ -196,9 +235,13 @@ static php_stream_filter_status_t userfilter_filter( /* filter resources are cleaned up by the stream destructor, * keeping a reference to the stream resource here would prevent it - * from being destroyed properly */ - if (stream_prop) { - convert_to_null(stream_prop); + * from being destroyed properly. + * Since the property accepted a resource assignment above, it must have + * no type hint or be typed as mixed, so we can safely assign null. + */ + if (stream_name != NULL) { + zend_update_property_null(Z_OBJCE_P(obj), Z_OBJ_P(obj), ZSTR_VAL(stream_name), ZSTR_LEN(stream_name)); + zend_string_release(stream_name); } zval_ptr_dtor(&args[3]); @@ -212,14 +255,74 @@ static php_stream_filter_status_t userfilter_filter( return ret; } +static zend_result userfilter_seek( + php_stream *stream, + php_stream_filter *thisfilter, + zend_off_t offset, + int whence + ) +{ + zval *obj = &thisfilter->abstract; + zval retval; + zval args[3]; + + /* the userfilter object probably doesn't exist anymore */ + if (CG(unclean_shutdown)) { + return FAILURE; + } + + /* Check if the seek method exists */ + zend_function *seek_method = zend_hash_str_find_ptr(&Z_OBJCE_P(obj)->function_table, ZEND_STRL("seek")); + if (seek_method == NULL) { + /* Method doesn't exist - consider this a successful seek for BC */ + return SUCCESS; + } + + /* Make sure the stream is not closed while the filter callback executes. */ + uint32_t orig_no_fclose = stream->flags & PHP_STREAM_FLAG_NO_FCLOSE; + stream->flags |= PHP_STREAM_FLAG_NO_FCLOSE; + + zend_string *stream_name = NULL; + if (userfilter_assign_stream(stream, obj, &stream_name, orig_no_fclose) == FAILURE) { + return FAILURE; + } + + /* Setup calling arguments */ + ZVAL_LONG(&args[0], offset); + ZVAL_LONG(&args[1], whence); + ZVAL_LONG(&args[2], php_stream_filter_get_chain_type(stream, thisfilter)); + + zend_call_known_function(seek_method, Z_OBJ_P(obj), Z_OBJCE_P(obj), &retval, 3, args, NULL); + + zend_result ret = FAILURE; + if (Z_TYPE(retval) != IS_UNDEF) { + ret = zend_is_true(&retval) ? SUCCESS : FAILURE; + zval_ptr_dtor(&retval); + } + + /* filter resources are cleaned up by the stream destructor, + * keeping a reference to the stream resource here would prevent it + * from being destroyed properly */ + if (stream_name != NULL) { + zend_update_property_null(Z_OBJCE_P(obj), Z_OBJ_P(obj), ZSTR_VAL(stream_name), ZSTR_LEN(stream_name)); + zend_string_release(stream_name); + } + + stream->flags &= ~PHP_STREAM_FLAG_NO_FCLOSE; + stream->flags |= orig_no_fclose; + + return ret; +} + static const php_stream_filter_ops userfilter_ops = { userfilter_filter, + userfilter_seek, userfilter_dtor, "user-filter" }; static php_stream_filter *user_filter_factory_create(const char *filtername, - zval *filterparams, uint8_t persistent) + zval *filterparams, bool persistent) { struct php_user_filter_data *fdat = NULL; php_stream_filter *filter; @@ -237,8 +340,8 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, len = strlen(filtername); /* determine the classname/class entry */ - if (NULL == (fdat = zend_hash_str_find_ptr(BG(user_filter_map), (char*)filtername, len))) { - char *period; + if (NULL == (fdat = zend_hash_str_find_ptr(BG(user_filter_map), filtername, len))) { + const char *period; /* Userspace Filters using ambiguous wildcards could cause problems. i.e.: myfilter.foo.bar will always call into myfilter.foo.* @@ -250,16 +353,16 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, /* Search for wildcard matches instead */ memcpy(wildcard, filtername, len + 1); /* copy \0 */ - period = wildcard + (period - filtername); - while (period) { - ZEND_ASSERT(period[0] == '.'); - period[1] = '*'; - period[2] = '\0'; + char *new_period = wildcard + (period - filtername); + while (new_period) { + ZEND_ASSERT(new_period[0] == '.'); + new_period[1] = '*'; + new_period[2] = '\0'; if (NULL != (fdat = zend_hash_str_find_ptr(BG(user_filter_map), wildcard, strlen(wildcard)))) { - period = NULL; + new_period = NULL; } else { - *period = '\0'; - period = strrchr(wildcard, '.'); + *new_period = '\0'; + new_period = strrchr(wildcard, '.'); } } efree(wildcard); @@ -282,14 +385,11 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, return NULL; } - filter = php_stream_filter_alloc(&userfilter_ops, NULL, 0); - if (filter == NULL) { - zval_ptr_dtor(&obj); - return NULL; - } + filter = php_stream_filter_alloc(&userfilter_ops, NULL, false, + PSFS_SEEKABLE_CHECK, PSFS_SEEKABLE_CHECK); /* filtername */ - add_property_string(&obj, "filtername", (char*)filtername); + add_property_string(&obj, "filtername", filtername); /* and the parameters, if any */ if (filterparams) { @@ -305,9 +405,6 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, if (Z_TYPE(retval) != IS_UNDEF) { if (Z_TYPE(retval) == IS_FALSE) { - /* User reported filter creation error "return false;" */ - zval_ptr_dtor(&retval); - /* Kill the filter (safely) */ ZVAL_UNDEF(&filter->abstract); php_stream_filter_free(filter); @@ -408,17 +505,19 @@ static void php_stream_bucket_attach(int append, INTERNAL_FUNCTION_PARAMETERS) memcpy(bucket->buf, Z_STRVAL_P(pzdata), bucket->buflen); } + /* If the bucket is already on a brigade we have to unlink it first to keep the + * linked list consistent. Furthermore, we can transfer the refcount in that case. */ + if (bucket->brigade) { + php_stream_bucket_unlink(bucket); + } else { + bucket->refcount++; + } + if (append) { php_stream_bucket_append(brigade, bucket); } else { php_stream_bucket_prepend(brigade, bucket); } - /* This is a hack necessary to accommodate situations where bucket is appended to the stream - * multiple times. See bug35916.phpt for reference. - */ - if (bucket->refcount == 1) { - bucket->refcount++; - } } /* }}} */ diff --git a/ext/standard/user_filters.stub.php b/ext/standard/user_filters.stub.php index acaa42bb33c8..8696845b78c8 100644 --- a/ext/standard/user_filters.stub.php +++ b/ext/standard/user_filters.stub.php @@ -49,6 +49,9 @@ class php_user_filter */ public function filter($in, $out, &$consumed, bool $closing): int {} + /** @tentative-return-type */ + public function seek(int $offset, int $whence, int $chain): bool {} + /** @tentative-return-type */ public function onCreate(): bool {} diff --git a/ext/standard/user_filters_arginfo.h b/ext/standard/user_filters_arginfo.h index 0411355b7122..f5b8a7dfa472 100644 --- a/ext/standard/user_filters_arginfo.h +++ b/ext/standard/user_filters_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 33264435fe01a2cc9aa21a4a087dbbf3c4007206 */ +/* This is a generated file, edit user_filters.stub.php instead. + * Stub hash: 01be6d52377ecd1940c14e3d508df28a70456c58 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_filter, 0, 4, IS_LONG, 0) ZEND_ARG_INFO(0, in) @@ -8,6 +8,12 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_ ZEND_ARG_TYPE_INFO(0, closing, _IS_BOOL, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_seek, 0, 3, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, whence, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, chain, IS_LONG, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_onCreate, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -15,11 +21,13 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_php_user_filter_ ZEND_END_ARG_INFO() ZEND_METHOD(php_user_filter, filter); +ZEND_METHOD(php_user_filter, seek); ZEND_METHOD(php_user_filter, onCreate); ZEND_METHOD(php_user_filter, onClose); static const zend_function_entry class_php_user_filter_methods[] = { ZEND_ME(php_user_filter, filter, arginfo_class_php_user_filter_filter, ZEND_ACC_PUBLIC) + ZEND_ME(php_user_filter, seek, arginfo_class_php_user_filter_seek, ZEND_ACC_PUBLIC) ZEND_ME(php_user_filter, onCreate, arginfo_class_php_user_filter_onCreate, ZEND_ACC_PUBLIC) ZEND_ME(php_user_filter, onClose, arginfo_class_php_user_filter_onClose, ZEND_ACC_PUBLIC) ZEND_FE_END @@ -44,21 +52,21 @@ static zend_class_entry *register_class_php_user_filter(void) zval property_filtername_default_value; ZVAL_EMPTY_STRING(&property_filtername_default_value); - zend_string *property_filtername_name = zend_string_init("filtername", sizeof("filtername") - 1, 1); + zend_string *property_filtername_name = zend_string_init("filtername", sizeof("filtername") - 1, true); zend_declare_typed_property(class_entry, property_filtername_name, &property_filtername_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_filtername_name); + zend_string_release_ex(property_filtername_name, true); zval property_params_default_value; ZVAL_EMPTY_STRING(&property_params_default_value); - zend_string *property_params_name = zend_string_init("params", sizeof("params") - 1, 1); + zend_string *property_params_name = zend_string_init("params", sizeof("params") - 1, true); zend_declare_typed_property(class_entry, property_params_name, &property_params_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ANY)); - zend_string_release(property_params_name); + zend_string_release_ex(property_params_name, true); zval property_stream_default_value; ZVAL_NULL(&property_stream_default_value); - zend_string *property_stream_name = zend_string_init("stream", sizeof("stream") - 1, 1); + zend_string *property_stream_name = zend_string_init("stream", sizeof("stream") - 1, true); zend_declare_typed_property(class_entry, property_stream_name, &property_stream_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); - zend_string_release(property_stream_name); + zend_string_release_ex(property_stream_name, true); return class_entry; } @@ -72,27 +80,27 @@ static zend_class_entry *register_class_StreamBucket(void) zval property_bucket_default_value; ZVAL_NULL(&property_bucket_default_value); - zend_string *property_bucket_name = zend_string_init("bucket", sizeof("bucket") - 1, 1); + zend_string *property_bucket_name = zend_string_init("bucket", sizeof("bucket") - 1, true); zend_declare_typed_property(class_entry, property_bucket_name, &property_bucket_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_NONE(0)); - zend_string_release(property_bucket_name); + zend_string_release_ex(property_bucket_name, true); zval property_data_default_value; ZVAL_UNDEF(&property_data_default_value); - zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, 1); + zend_string *property_data_name = zend_string_init("data", sizeof("data") - 1, true); zend_declare_typed_property(class_entry, property_data_name, &property_data_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_data_name); + zend_string_release_ex(property_data_name, true); zval property_datalen_default_value; ZVAL_UNDEF(&property_datalen_default_value); - zend_string *property_datalen_name = zend_string_init("datalen", sizeof("datalen") - 1, 1); + zend_string *property_datalen_name = zend_string_init("datalen", sizeof("datalen") - 1, true); zend_declare_typed_property(class_entry, property_datalen_name, &property_datalen_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_datalen_name); + zend_string_release_ex(property_datalen_name, true); zval property_dataLength_default_value; ZVAL_UNDEF(&property_dataLength_default_value); - zend_string *property_dataLength_name = zend_string_init("dataLength", sizeof("dataLength") - 1, 1); + zend_string *property_dataLength_name = zend_string_init("dataLength", sizeof("dataLength") - 1, true); zend_declare_typed_property(class_entry, property_dataLength_name, &property_dataLength_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_dataLength_name); + zend_string_release_ex(property_dataLength_name, true); return class_entry; } diff --git a/ext/standard/uuencode.c b/ext/standard/uuencode.c index 0389fdd9f979..af70e3a2aa2c 100644 --- a/ext/standard/uuencode.c +++ b/ext/standard/uuencode.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Ilia Alshanetsky | +----------------------------------------------------------------------+ diff --git a/ext/standard/var.c b/ext/standard/var.c index 1c2b0eb164a1..3137a270f661 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Jani Lehtimäki | | Thies C. Arntzen | @@ -56,6 +54,12 @@ static void php_object_property_dump(zend_property_info *prop_info, zval *zv, ze { const char *prop_name, *class_name; +#ifdef ZEND_CHECK_STACK_LIMIT + if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) { + php_printf("%*cnesting level too deep", level + 1, ' '); + return; + } +#endif if (key == NULL) { /* numeric key */ php_printf("%*c[" ZEND_LONG_FMT "]=>\n", level + 1, ' ', index); } else { /* string key */ @@ -153,7 +157,7 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ } ZEND_HASH_FOREACH_END(); if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) { GC_UNPROTECT_RECURSION(myht); - GC_DELREF(myht); + GC_DTOR_NO_REF(myht); } if (level > 1) { php_printf("%*c", level-1, ' '); @@ -162,7 +166,7 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ break; case IS_OBJECT: { zend_class_entry *ce = Z_OBJCE_P(struc); - if (ce->ce_flags & ZEND_ACC_ENUM) { + if ((ce->ce_flags & ZEND_ACC_ENUM) && ce->__debugInfo == NULL) { zval *case_name_zval = zend_enum_fetch_case_name(Z_OBJ_P(struc)); php_printf("%senum(%s::%s)\n", COMMON, ZSTR_VAL(ce->name), Z_STRVAL_P(case_name_zval)); return; @@ -176,11 +180,16 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ ZEND_GUARD_OR_GC_PROTECT_RECURSION(guard, DEBUG, zobj); myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); - class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); + if (ce->ce_flags & ZEND_ACC_ENUM) { + zval *case_name_zval = zend_enum_fetch_case_name(Z_OBJ_P(struc)); + php_printf("%senum(%s::%s) (%d) {\n", COMMON, ZSTR_VAL(ce->name), Z_STRVAL_P(case_name_zval), myht ? zend_array_count(myht) : 0); + } else { + class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); + const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); - php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); - zend_string_release_ex(class_name, 0); + php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); + zend_string_release_ex(class_name, 0); + } if (myht) { zend_ulong num; @@ -222,7 +231,6 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ } struc = Z_REFVAL_P(struc); goto again; - break; default: php_printf("%sUNKNOWN:0\n", COMMON); break; @@ -354,7 +362,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */ } ZEND_HASH_FOREACH_END(); if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) { GC_UNPROTECT_RECURSION(myht); - GC_DELREF(myht); + GC_DTOR_NO_REF(myht); } if (level > 1) { php_printf("%*c", level - 1, ' '); @@ -668,7 +676,6 @@ PHPAPI zend_result php_var_export_ex(zval *struc, int level, smart_str *buf) /* case IS_REFERENCE: struc = Z_REFVAL_P(struc); goto again; - break; default: smart_str_appendl(buf, "NULL", 4); break; @@ -737,7 +744,10 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var, b return 0; } else if (!in_rcn_array && Z_REFCOUNT_P(var) == 1 - && (Z_OBJ_P(var)->properties == NULL || GC_REFCOUNT(Z_OBJ_P(var)->properties) == 1)) { + && (Z_OBJ_P(var)->properties == NULL || GC_REFCOUNT(Z_OBJ_P(var)->properties) == 1) + /* __serialize and __sleep may arbitrarily increase the refcount */ + && Z_OBJCE_P(var)->__serialize == NULL + && zend_hash_find_known_hash(&Z_OBJCE_P(var)->function_table, ZSTR_KNOWN(ZEND_STR_SLEEP)) == NULL) { return 0; } @@ -931,7 +941,7 @@ static int php_var_serialize_get_sleep_props( priv_name = zend_mangle_property_name( ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), - ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS); + ZSTR_VAL(name), ZSTR_LEN(name), ce->type == ZEND_INTERNAL_CLASS); if (php_var_serialize_try_add_sleep_prop(ht, props, priv_name, name, struc) == SUCCESS) { zend_tmp_string_release(tmp_name); zend_string_release(priv_name); @@ -946,7 +956,7 @@ static int php_var_serialize_get_sleep_props( } prot_name = zend_mangle_property_name( - "*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS); + "*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type == ZEND_INTERNAL_CLASS); if (php_var_serialize_try_add_sleep_prop(ht, props, prot_name, name, struc) == SUCCESS) { zend_tmp_string_release(tmp_name); zend_string_release(prot_name); @@ -981,7 +991,7 @@ static void php_var_serialize_nested_data(smart_str *buf, zval *struc, HashTable ZEND_HASH_FOREACH_KEY_VAL_IND(ht, index, key, data) { if (incomplete_class && zend_string_equals_literal(key, MAGIC_MEMBER)) { - incomplete_class = 0; + incomplete_class = false; continue; } @@ -998,18 +1008,11 @@ static void php_var_serialize_nested_data(smart_str *buf, zval *struc, HashTable /* we should still add element even if it's not OK, * since we already wrote the length of the array before */ if (Z_TYPE_P(data) == IS_ARRAY) { - if (UNEXPECTED(Z_IS_RECURSIVE_P(data)) - || UNEXPECTED(Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))) { + if (UNEXPECTED(Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))) { php_add_var_hash(var_hash, struc, in_rcn_array); smart_str_appendl(buf, "N;", 2); } else { - if (Z_REFCOUNTED_P(data)) { - Z_PROTECT_RECURSION_P(data); - } php_var_serialize_intern(buf, data, var_hash, in_rcn_array, false); - if (Z_REFCOUNTED_P(data)) { - Z_UNPROTECT_RECURSION_P(data); - } } } else { php_var_serialize_intern(buf, data, var_hash, in_rcn_array, false); @@ -1027,7 +1030,8 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, HashTable *ht, if (php_var_serialize_get_sleep_props(&props, struc, ht) == SUCCESS) { php_var_serialize_class_name(buf, struc); php_var_serialize_nested_data( - buf, struc, &props, zend_hash_num_elements(&props), /* incomplete_class */ 0, var_hash, GC_REFCOUNT(&props) > 1); + buf, struc, &props, zend_hash_num_elements(&props), /* incomplete_class */ false, var_hash, + GC_REFCOUNT(&props) > 1); } zend_hash_destroy(&props); } @@ -1241,7 +1245,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ && Z_OBJ_HT_P(struc)->get_properties_for == NULL && Z_OBJ_HT_P(struc)->get_properties == zend_std_get_properties && !zend_object_is_lazy(Z_OBJ_P(struc))) { - /* Optimized version without rebulding properties HashTable */ + /* Optimized version without rebuilding properties HashTable */ zend_object *obj = Z_OBJ_P(struc); zend_class_entry *ce = obj->ce; zend_property_info *prop_info; @@ -1303,8 +1307,8 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ smart_str_appendl(buf, "a:", 2); myht = Z_ARRVAL_P(struc); php_var_serialize_nested_data( - buf, struc, myht, zend_array_count(myht), /* incomplete_class */ 0, var_hash, - !is_root && (in_rcn_array || GC_REFCOUNT(myht) > 1)); + buf, struc, myht, zend_array_count(myht), /* incomplete_class */ false, var_hash, + !is_root && (in_rcn_array || GC_REFCOUNT(myht) > 1)); return; case IS_REFERENCE: struc = Z_REFVAL_P(struc); @@ -1418,19 +1422,20 @@ PHPAPI void php_unserialize_with_options(zval *return_value, const char *buf, co function_name, zend_zval_value_name(entry)); goto cleanup; } - zend_string *name = zval_try_get_string(entry); + zend_string *tmp_str; + zend_string *name = zval_try_get_tmp_string(entry, &tmp_str); if (UNEXPECTED(name == NULL)) { goto cleanup; } if (UNEXPECTED(!zend_is_valid_class_name(name))) { zend_value_error("%s(): Option \"allowed_classes\" must be an array of class names, \"%s\" given", function_name, ZSTR_VAL(name)); - zend_string_release_ex(name, false); + zend_tmp_string_release(tmp_str); goto cleanup; } zend_string *lcname = zend_string_tolower(name); zend_hash_add_empty_element(class_hash, lcname); - zend_string_release_ex(name, false); zend_string_release_ex(lcname, false); + zend_tmp_string_release(tmp_str); } ZEND_HASH_FOREACH_END(); } php_var_unserialize_set_allowed_classes(var_hash, class_hash); diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index cbd457e16fdb..7ac76683a326 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ @@ -19,6 +17,7 @@ #include "php_incomplete_class.h" #include "zend_portability.h" #include "zend_exceptions.h" +#include "zend_inheritance.h" /* {{{ reference-handling for unserializer: var_* */ #define VAR_ENTRIES_MAX 1018 /* 1024 - offsetof(php_unserialize_data, entries) / sizeof(void*) */ @@ -1197,7 +1196,8 @@ object ":" uiv ":" ["] { lc_name = zend_string_tolower(class_name); if(!unserialize_allowed_class(lc_name, var_hash)) { zend_string_release_ex(lc_name, 0); - if (!zend_is_valid_class_name(class_name)) { + if (!zend_is_valid_class_name(class_name) + && !zend_class_name_is_monomorph(class_name)) { zend_string_release_ex(class_name, 0); return 0; } @@ -1222,7 +1222,13 @@ object ":" uiv ":" ["] { break; } - if (!ZSTR_HAS_CE_CACHE(class_name) && !zend_is_valid_class_name(class_name)) { + /* Canonical monomorph names ("Box") contain characters that + * zend_is_valid_class_name() rejects. zend_lookup_class_ex() has a + * dedicated monomorphization hook for these names, so accept them + * here and let the lookup either synthesize the monomorph or fail. */ + if (!ZSTR_HAS_CE_CACHE(class_name) + && !zend_is_valid_class_name(class_name) + && !zend_class_name_is_monomorph(class_name)) { zend_string_release_ex(lc_name, 0); zend_string_release_ex(class_name, 0); return 0; @@ -1312,10 +1318,12 @@ object ":" uiv ":" ["] { YYCURSOR = *p; if (*(YYCURSOR) != ':') { + zend_string_release_ex(class_name, 0); return 0; } if (*(YYCURSOR+1) != '{') { *p = YYCURSOR+1; + zend_string_release_ex(class_name, 0); return 0; } diff --git a/ext/standard/versioning.c b/ext/standard/versioning.c index 6995569fbf87..dc7ca71af469 100644 --- a/ext/standard/versioning.c +++ b/ext/standard/versioning.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Stig Sæther Bakken | +----------------------------------------------------------------------+ @@ -45,8 +43,8 @@ php_canonicalize_version(const char *version) * s/([^\d\.])([^\D\.])/$1.$2/g; * s/([^\D\.])([^\d\.])/$1.$2/g; */ -#define isdig(x) (isdigit(x)&&(x)!='.') -#define isndig(x) (!isdigit(x)&&(x)!='.') +#define isdig(x) (isdigit((unsigned char)(x))&&(x)!='.') +#define isndig(x) (!isdigit((unsigned char)(x))&&(x)!='.') #define isspecialver(x) ((x)=='-'||(x)=='_'||(x)=='+') lq = *(q - 1); @@ -59,7 +57,7 @@ php_canonicalize_version(const char *version) *q++ = '.'; } *q++ = *p; - } else if (!isalnum(*p)) { + } else if (!isalnum((unsigned char)*p)) { if (lq != '.') { *q++ = '.'; } @@ -68,7 +66,15 @@ php_canonicalize_version(const char *version) } lp = *p++; } - *q++ = '\0'; + + /* Check if the last component is empty (i.e. the last character is a dot) + * and remove it if it is. */ + if (*(q - 1) == '.') { + *(q - 1) = '\0'; + } else { + *q = '\0'; + } + return buf; } @@ -152,17 +158,17 @@ php_version_compare(const char *orig_ver1, const char *orig_ver2) if ((n2 = strchr(p2, '.')) != NULL) { *n2 = '\0'; } - if (isdigit(*p1) && isdigit(*p2)) { + if (isdigit((unsigned char)*p1) && isdigit((unsigned char)*p2)) { /* compare element numerically */ l1 = strtol(p1, NULL, 10); l2 = strtol(p2, NULL, 10); compare = ZEND_NORMALIZE_BOOL(l1 - l2); - } else if (!isdigit(*p1) && !isdigit(*p2)) { + } else if (!isdigit((unsigned char)*p1) && !isdigit((unsigned char)*p2)) { /* compare element names */ compare = compare_special_version_forms(p1, p2); } else { /* mix of names and numbers */ - if (isdigit(*p1)) { + if (isdigit((unsigned char)*p1)) { compare = compare_special_version_forms("#N#", p2); } else { compare = compare_special_version_forms(p1, "#N#"); @@ -180,13 +186,13 @@ php_version_compare(const char *orig_ver1, const char *orig_ver2) } if (compare == 0) { if (n1 != NULL) { - if (isdigit(*p1)) { + if (isdigit((unsigned char)*p1)) { compare = 1; } else { compare = php_version_compare(p1, "#N#"); } } else if (n2 != NULL) { - if (isdigit(*p2)) { + if (isdigit((unsigned char)*p2)) { compare = -1; } else { compare = php_version_compare("#N#", p2); diff --git a/ext/sysvmsg/php_sysvmsg.h b/ext/sysvmsg/php_sysvmsg.h index e3be3ed32e31..c82cb09934da 100644 --- a/ext/sysvmsg/php_sysvmsg.h +++ b/ext/sysvmsg/php_sysvmsg.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ diff --git a/ext/sysvmsg/sysvmsg.c b/ext/sysvmsg/sysvmsg.c index 1f4cafd2bce0..16b4ffec50ee 100644 --- a/ext/sysvmsg/sysvmsg.c +++ b/ext/sysvmsg/sysvmsg.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Wez Furlong | +----------------------------------------------------------------------+ @@ -68,7 +66,7 @@ zend_class_entry *sysvmsg_queue_ce; static zend_object_handlers sysvmsg_queue_object_handlers; static inline sysvmsg_queue_t *sysvmsg_queue_from_obj(zend_object *obj) { - return (sysvmsg_queue_t *)((char *)(obj) - XtOffsetOf(sysvmsg_queue_t, std)); + return ZEND_CONTAINER_OF(obj, sysvmsg_queue_t, std); } #define Z_SYSVMSG_QUEUE_P(zv) sysvmsg_queue_from_obj(Z_OBJ_P(zv)) @@ -103,7 +101,7 @@ PHP_MINIT_FUNCTION(sysvmsg) sysvmsg_queue_ce->default_object_handlers = &sysvmsg_queue_object_handlers; memcpy(&sysvmsg_queue_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sysvmsg_queue_object_handlers.offset = XtOffsetOf(sysvmsg_queue_t, std); + sysvmsg_queue_object_handlers.offset = offsetof(sysvmsg_queue_t, std); sysvmsg_queue_object_handlers.free_obj = sysvmsg_queue_free_obj; sysvmsg_queue_object_handlers.get_constructor = sysvmsg_queue_get_constructor; sysvmsg_queue_object_handlers.clone_obj = NULL; @@ -127,32 +125,32 @@ PHP_MINFO_FUNCTION(sysvmsg) /* {{{ Set information for a message queue */ PHP_FUNCTION(msg_set_queue) { - zval *queue, *data; + zval *queue; + HashTable *data; sysvmsg_queue_t *mq = NULL; struct msqid_ds stat; - RETVAL_FALSE; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa", &queue, sysvmsg_queue_ce, &data) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oh", &queue, sysvmsg_queue_ce, &data) == FAILURE) { RETURN_THROWS(); } mq = Z_SYSVMSG_QUEUE_P(queue); + RETVAL_FALSE; if (msgctl(mq->id, IPC_STAT, &stat) == 0) { zval *item; /* now pull out members of data and set them in the stat buffer */ - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_perm.uid", sizeof("msg_perm.uid") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_perm.uid"))) != NULL) { stat.msg_perm.uid = zval_get_long(item); } - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_perm.gid", sizeof("msg_perm.gid") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_perm.gid"))) != NULL) { stat.msg_perm.gid = zval_get_long(item); } - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_perm.mode", sizeof("msg_perm.mode") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_perm.mode"))) != NULL) { stat.msg_perm.mode = zval_get_long(item); } - if ((item = zend_hash_str_find(Z_ARRVAL_P(data), "msg_qbytes", sizeof("msg_qbytes") - 1)) != NULL) { + if ((item = zend_hash_str_find(data, ZEND_STRL("msg_qbytes"))) != NULL) { stat.msg_qbytes = zval_get_long(item); } if (msgctl(mq->id, IPC_SET, &stat) == 0) { @@ -169,28 +167,27 @@ PHP_FUNCTION(msg_stat_queue) sysvmsg_queue_t *mq = NULL; struct msqid_ds stat; - RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &queue, sysvmsg_queue_ce) == FAILURE) { RETURN_THROWS(); } mq = Z_SYSVMSG_QUEUE_P(queue); - if (msgctl(mq->id, IPC_STAT, &stat) == 0) { - array_init(return_value); - - add_assoc_long(return_value, "msg_perm.uid", stat.msg_perm.uid); - add_assoc_long(return_value, "msg_perm.gid", stat.msg_perm.gid); - add_assoc_long(return_value, "msg_perm.mode", stat.msg_perm.mode); - add_assoc_long(return_value, "msg_stime", stat.msg_stime); - add_assoc_long(return_value, "msg_rtime", stat.msg_rtime); - add_assoc_long(return_value, "msg_ctime", stat.msg_ctime); - add_assoc_long(return_value, "msg_qnum", stat.msg_qnum); - add_assoc_long(return_value, "msg_qbytes", stat.msg_qbytes); - add_assoc_long(return_value, "msg_lspid", stat.msg_lspid); - add_assoc_long(return_value, "msg_lrpid", stat.msg_lrpid); + if (msgctl(mq->id, IPC_STAT, &stat) != 0) { + RETURN_FALSE; } + + array_init_size(return_value, 10); + add_assoc_long(return_value, "msg_perm.uid", stat.msg_perm.uid); + add_assoc_long(return_value, "msg_perm.gid", stat.msg_perm.gid); + add_assoc_long(return_value, "msg_perm.mode", stat.msg_perm.mode); + add_assoc_long(return_value, "msg_stime", stat.msg_stime); + add_assoc_long(return_value, "msg_rtime", stat.msg_rtime); + add_assoc_long(return_value, "msg_ctime", stat.msg_ctime); + add_assoc_long(return_value, "msg_qnum", stat.msg_qnum); + add_assoc_long(return_value, "msg_qbytes", stat.msg_qbytes); + add_assoc_long(return_value, "msg_lspid", stat.msg_lspid); + add_assoc_long(return_value, "msg_lrpid", stat.msg_lrpid); } /* }}} */ @@ -203,11 +200,7 @@ PHP_FUNCTION(msg_queue_exists) RETURN_THROWS(); } - if (msgget(key, 0) < 0) { - RETURN_FALSE; - } - - RETURN_TRUE; + RETURN_BOOL(msgget(key, 0) >= 0); } /* }}} */ @@ -251,11 +244,7 @@ PHP_FUNCTION(msg_remove_queue) mq = Z_SYSVMSG_QUEUE_P(queue); - if (msgctl(mq->id, IPC_RMID, NULL) == 0) { - RETVAL_TRUE; - } else { - RETVAL_FALSE; - } + RETURN_BOOL(msgctl(mq->id, IPC_RMID, NULL) == 0); } /* }}} */ @@ -265,13 +254,11 @@ PHP_FUNCTION(msg_receive) zval *out_message, *queue, *out_msgtype, *zerrcode = NULL; zend_long desiredmsgtype, maxsize, flags = 0; zend_long realflags = 0; - bool do_unserialize = 1; + bool do_unserialize = true; sysvmsg_queue_t *mq = NULL; struct php_msgbuf *messagebuffer = NULL; /* buffer to transmit */ int result; - RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olzlz|blz", &queue, sysvmsg_queue_ce, &desiredmsgtype, &out_msgtype, &maxsize, &out_message, &do_unserialize, &flags, &zerrcode) == FAILURE) { @@ -337,6 +324,7 @@ PHP_FUNCTION(msg_receive) if (zerrcode) { ZEND_TRY_ASSIGN_REF_LONG(zerrcode, errno); } + RETVAL_FALSE; } efree(messagebuffer); } @@ -347,14 +335,12 @@ PHP_FUNCTION(msg_send) { zval *message, *queue, *zerror=NULL; zend_long msgtype; - bool do_serialize = 1, blocking = 1; + bool do_serialize = true, blocking = true; sysvmsg_queue_t * mq = NULL; struct php_msgbuf * messagebuffer = NULL; /* buffer to transmit */ int result; size_t message_len = 0; - RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olz|bbz", &queue, sysvmsg_queue_ce, &msgtype, &message, &do_serialize, &blocking, &zerror) == FAILURE) { RETURN_THROWS(); @@ -395,10 +381,12 @@ PHP_FUNCTION(msg_send) message_len = spprintf(&p, 0, ZEND_LONG_FMT, Z_LVAL_P(message)); break; case IS_FALSE: - message_len = spprintf(&p, 0, "0"); + p = "0"; + message_len = 1; break; case IS_TRUE: - message_len = spprintf(&p, 0, "1"); + p = "1"; + message_len = 1; break; case IS_DOUBLE: message_len = spprintf(&p, 0, "%F", Z_DVAL_P(message)); @@ -412,7 +400,7 @@ PHP_FUNCTION(msg_send) messagebuffer = safe_emalloc(message_len, 1, sizeof(struct php_msgbuf)); memcpy(messagebuffer->mtext, p, message_len + 1); - if (Z_TYPE_P(message) != IS_STRING) { + if (Z_TYPE_P(message) == IS_LONG || Z_TYPE_P(message) == IS_DOUBLE) { efree(p); } } @@ -429,8 +417,9 @@ PHP_FUNCTION(msg_send) if (zerror) { ZEND_TRY_ASSIGN_REF_LONG(zerror, errno); } + RETURN_FALSE; } else { - RETVAL_TRUE; + RETURN_TRUE; } } /* }}} */ diff --git a/ext/sysvmsg/sysvmsg_arginfo.h b/ext/sysvmsg/sysvmsg_arginfo.h index 26f81c0295be..9dee3e0f4840 100644 --- a/ext/sysvmsg/sysvmsg_arginfo.h +++ b/ext/sysvmsg/sysvmsg_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit sysvmsg.stub.php instead. * Stub hash: ed5b1e4e5dda6a65ce336fc4daa975520c354f17 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_msg_get_queue, 0, 1, SysvMessageQueue, MAY_BE_FALSE) diff --git a/ext/sysvsem/php_sysvsem.h b/ext/sysvsem/php_sysvsem.h index 05d420bf42a4..c40d6dde5f1c 100644 --- a/ext/sysvsem/php_sysvsem.h +++ b/ext/sysvsem/php_sysvsem.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Tom May | +----------------------------------------------------------------------+ diff --git a/ext/sysvsem/sysvsem.c b/ext/sysvsem/sysvsem.c index 481d8ce28cc3..9d3990d0bdc0 100644 --- a/ext/sysvsem/sysvsem.c +++ b/ext/sysvsem/sysvsem.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Tom May | | Gavin Sherry | @@ -85,7 +83,7 @@ zend_class_entry *sysvsem_ce; static zend_object_handlers sysvsem_object_handlers; static inline sysvsem_sem *sysvsem_from_obj(zend_object *obj) { - return (sysvsem_sem *)((char *)(obj) - XtOffsetOf(sysvsem_sem, std)); + return ZEND_CONTAINER_OF(obj, sysvsem_sem, std); } #define Z_SYSVSEM_P(zv) sysvsem_from_obj(Z_OBJ_P(zv)) @@ -149,7 +147,7 @@ PHP_MINIT_FUNCTION(sysvsem) sysvsem_ce->default_object_handlers = &sysvsem_object_handlers; memcpy(&sysvsem_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sysvsem_object_handlers.offset = XtOffsetOf(sysvsem_sem, std); + sysvsem_object_handlers.offset = offsetof(sysvsem_sem, std); sysvsem_object_handlers.free_obj = sysvsem_free_obj; sysvsem_object_handlers.get_constructor = sysvsem_get_constructor; sysvsem_object_handlers.clone_obj = NULL; @@ -172,7 +170,7 @@ PHP_MINFO_FUNCTION(sysvsem) PHP_FUNCTION(sem_get) { zend_long key, max_acquire = 1, perm = 0666; - bool auto_release = 1; + bool auto_release = true; int semid; struct sembuf sop[3]; int count; @@ -266,10 +264,10 @@ PHP_FUNCTION(sem_get) /* }}} */ /* {{{ php_sysvsem_semop */ -static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire) +static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, bool acquire) { zval *arg_id; - bool nowait = 0; + bool nowait = false; sysvsem_sem *sem_ptr; struct sembuf sop; @@ -311,14 +309,14 @@ static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire) /* {{{ Acquires the semaphore with the given id, blocking if necessary */ PHP_FUNCTION(sem_acquire) { - php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } /* }}} */ /* {{{ Releases the semaphore with the given id */ PHP_FUNCTION(sem_release) { - php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + php_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); } /* }}} */ diff --git a/ext/sysvsem/sysvsem_arginfo.h b/ext/sysvsem/sysvsem_arginfo.h index 55bca0539fdd..b7643a926b14 100644 --- a/ext/sysvsem/sysvsem_arginfo.h +++ b/ext/sysvsem/sysvsem_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit sysvsem.stub.php instead. * Stub hash: 946ea9d0d2156ced1bac460d7d5fc3420e1934bb */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_sem_get, 0, 1, SysvSemaphore, MAY_BE_FALSE) diff --git a/ext/sysvshm/php_sysvshm.h b/ext/sysvshm/php_sysvshm.h index e11caa6c61b3..b47a70c4e5e1 100644 --- a/ext/sysvshm/php_sysvshm.h +++ b/ext/sysvshm/php_sysvshm.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Christian Cartus | +----------------------------------------------------------------------+ @@ -41,17 +39,17 @@ typedef struct { typedef struct { zend_long key; - zend_long length; - zend_long next; + size_t length; + size_t next; char mem; } sysvshm_chunk; typedef struct { char magic[8]; - zend_long start; - zend_long end; - zend_long free; - zend_long total; + size_t start; + size_t end; + size_t free; + size_t total; } sysvshm_chunk_head; typedef struct { diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 332a8b47af1b..96324e67c44d 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Christian Cartus | +----------------------------------------------------------------------+ @@ -36,7 +34,7 @@ zend_class_entry *sysvshm_ce; static zend_object_handlers sysvshm_object_handlers; static inline sysvshm_shm *sysvshm_from_obj(zend_object *obj) { - return (sysvshm_shm *)((char *)(obj) - XtOffsetOf(sysvshm_shm, std)); + return ZEND_CONTAINER_OF(obj, sysvshm_shm, std); } #define Z_SYSVSHM_P(zv) sysvshm_from_obj(Z_OBJ_P(zv)) @@ -90,9 +88,9 @@ ZEND_GET_MODULE(sysvshm) /* TODO: Make this thread-safe. */ sysvshm_module php_sysvshm; -static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len); -static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key); -static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos); +static bool php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const zend_string *data); +static ssize_t php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key); +static void php_remove_shm_data(sysvshm_chunk_head *ptr, size_t shm_varpos); /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(sysvshm) @@ -102,7 +100,7 @@ PHP_MINIT_FUNCTION(sysvshm) sysvshm_ce->default_object_handlers = &sysvshm_object_handlers; memcpy(&sysvshm_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - sysvshm_object_handlers.offset = XtOffsetOf(sysvshm_shm, std); + sysvshm_object_handlers.offset = offsetof(sysvshm_shm, std); sysvshm_object_handlers.free_obj = sysvshm_free_obj; sysvshm_object_handlers.get_constructor = sysvshm_get_constructor; sysvshm_object_handlers.clone_obj = NULL; @@ -131,7 +129,7 @@ PHP_FUNCTION(shm_attach) char *shm_ptr; sysvshm_chunk_head *chunk_ptr; zend_long shm_key, shm_id, shm_size, shm_flag = 0666; - bool shm_size_is_null = 1; + bool shm_size_is_null = true; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|l!l", &shm_key, &shm_size, &shm_size_is_null, &shm_flag)) { RETURN_THROWS(); @@ -235,7 +233,6 @@ PHP_FUNCTION(shm_remove) PHP_FUNCTION(shm_put_var) { zval *shm_id, *arg_var; - int ret; zend_long shm_key; sysvshm_shm *shm_list_ptr; smart_str shm_var = {0}; @@ -262,13 +259,17 @@ PHP_FUNCTION(shm_put_var) RETURN_THROWS(); } + if (UNEXPECTED(shm_var.s == NULL)) { + RETURN_THROWS(); + } + /* insert serialized variable into shared memory */ - ret = php_put_shm_data(shm_list_ptr->ptr, shm_key, shm_var.s? ZSTR_VAL(shm_var.s) : NULL, shm_var.s? ZSTR_LEN(shm_var.s) : 0); + bool ret = php_put_shm_data(shm_list_ptr->ptr, shm_key, shm_var.s); /* free string */ smart_str_free(&shm_var); - if (ret == -1) { + if (!ret) { php_error_docref(NULL, E_WARNING, "Not enough shared memory left"); RETURN_FALSE; } @@ -283,7 +284,6 @@ PHP_FUNCTION(shm_get_var) zend_long shm_key; sysvshm_shm *shm_list_ptr; char *shm_data; - zend_long shm_varpos; sysvshm_chunk *shm_var; php_unserialize_data_t var_hash; @@ -299,9 +299,9 @@ PHP_FUNCTION(shm_get_var) /* setup string-variable and serialize */ /* get serialized variable from shared memory */ - shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); + ssize_t shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); - if (shm_varpos < 0) { + if (shm_varpos == -1) { php_error_docref(NULL, E_WARNING, "Variable key " ZEND_LONG_FMT " doesn't exist", shm_key); RETURN_FALSE; } @@ -309,11 +309,13 @@ PHP_FUNCTION(shm_get_var) shm_data = &shm_var->mem; PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash) != 1) { + int res = php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + if (res != 1) { php_error_docref(NULL, E_WARNING, "Variable data in shared memory is corrupted"); - RETVAL_FALSE; + zval_ptr_dtor(return_value); + RETURN_FALSE; } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); } /* }}} */ @@ -342,7 +344,7 @@ PHP_FUNCTION(shm_has_var) PHP_FUNCTION(shm_remove_var) { zval *shm_id; - zend_long shm_key, shm_varpos; + zend_long shm_key; sysvshm_shm *shm_list_ptr; if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &shm_id, sysvshm_ce, &shm_key)) { @@ -355,9 +357,9 @@ PHP_FUNCTION(shm_remove_var) RETURN_THROWS(); } - shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); + ssize_t shm_varpos = php_check_shm_data(shm_list_ptr->ptr, shm_key); - if (shm_varpos < 0) { + if (shm_varpos == -1) { php_error_docref(NULL, E_WARNING, "Variable key " ZEND_LONG_FMT " doesn't exist", shm_key); RETURN_FALSE; } @@ -366,44 +368,41 @@ PHP_FUNCTION(shm_remove_var) } /* }}} */ -/* {{{ php_put_shm_data +/* {{{ * inserts an ascii-string into shared memory */ -static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len) +static bool php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const zend_string *data) { sysvshm_chunk *shm_var; - zend_long total_size; - zend_long shm_varpos; + ssize_t shm_varpos; - total_size = ((zend_long) (len + sizeof(sysvshm_chunk) - 1) / sizeof(zend_long)) * sizeof(zend_long) + sizeof(zend_long); /* zend_long alligment */ + size_t total_size = ((zend_long) (ZSTR_LEN(data) + sizeof(sysvshm_chunk) - 1) / sizeof(zend_long)) * sizeof(zend_long) + sizeof(zend_long); /* zend_long alligment */ if ((shm_varpos = php_check_shm_data(ptr, key)) > 0) { php_remove_shm_data(ptr, shm_varpos); } if (ptr->free < total_size) { - return -1; /* not enough memory */ + return false; /* not enough memory */ } shm_var = (sysvshm_chunk *) ((char *) ptr + ptr->end); shm_var->key = key; - shm_var->length = len; + shm_var->length = ZSTR_LEN(data); shm_var->next = total_size; - memcpy(&(shm_var->mem), data, len); + memcpy(&(shm_var->mem), ZSTR_VAL(data), ZSTR_LEN(data)); ptr->end += total_size; ptr->free -= total_size; - return 0; + return true; } /* }}} */ -/* {{{ php_check_shm_data */ -static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key) +static ssize_t php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key) { - zend_long pos; sysvshm_chunk *shm_var; ZEND_ASSERT(ptr); - pos = ptr->start; + size_t pos = ptr->start; for (;;) { if (pos >= ptr->end) { @@ -421,27 +420,22 @@ static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key) } return -1; } -/* }}} */ -/* {{{ php_remove_shm_data */ -static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos) +static void php_remove_shm_data(sysvshm_chunk_head *ptr, size_t shm_varpos) { sysvshm_chunk *chunk_ptr, *next_chunk_ptr; - zend_long memcpy_len; ZEND_ASSERT(ptr); chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos); next_chunk_ptr = (sysvshm_chunk *) ((char *) ptr + shm_varpos + chunk_ptr->next); - memcpy_len = ptr->end-shm_varpos - chunk_ptr->next; + size_t memcpy_len = ptr->end-shm_varpos - chunk_ptr->next; ptr->free += chunk_ptr->next; ptr->end -= chunk_ptr->next; if (memcpy_len > 0) { memmove(chunk_ptr, next_chunk_ptr, memcpy_len); } - return 0; } -/* }}} */ #endif /* HAVE_SYSVSHM */ diff --git a/ext/sysvshm/sysvshm.stub.php b/ext/sysvshm/sysvshm.stub.php index 4b6770063a31..c89f67bc068a 100644 --- a/ext/sysvshm/sysvshm.stub.php +++ b/ext/sysvshm/sysvshm.stub.php @@ -12,7 +12,7 @@ final class SysvSharedMemory function shm_attach(int $key, ?int $size = null, int $permissions = 0666): SysvSharedMemory|false {} -function shm_detach(SysvSharedMemory $shm): bool {} +function shm_detach(SysvSharedMemory $shm): true {} function shm_has_var(SysvSharedMemory $shm, int $key): bool {} diff --git a/ext/sysvshm/sysvshm_arginfo.h b/ext/sysvshm/sysvshm_arginfo.h index bca40b0e0944..aade5b8276a4 100644 --- a/ext/sysvshm/sysvshm_arginfo.h +++ b/ext/sysvshm/sysvshm_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: 93677b78d9aaa4d6dbb5d1dcf3e79a8418add5c0 */ +/* This is a generated file, edit sysvshm.stub.php instead. + * Stub hash: 792c695a705678a3779d62cef8a5136069f98dee */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_shm_attach, 0, 1, SysvSharedMemory, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0) @@ -7,7 +7,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_shm_attach, 0, 1, SysvShared ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, permissions, IS_LONG, 0, "0666") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_detach, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_detach, 0, 1, IS_TRUE, 0) ZEND_ARG_OBJ_INFO(0, shm, SysvSharedMemory, 0) ZEND_END_ARG_INFO() @@ -16,7 +16,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_has_var, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0) ZEND_END_ARG_INFO() -#define arginfo_shm_remove arginfo_shm_detach +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_remove, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, shm, SysvSharedMemory, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_put_var, 0, 3, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, shm, SysvSharedMemory, 0) diff --git a/ext/sysvshm/tests/serialize_exception.phpt b/ext/sysvshm/tests/serialize_exception.phpt new file mode 100644 index 000000000000..aae237e0fb38 --- /dev/null +++ b/ext/sysvshm/tests/serialize_exception.phpt @@ -0,0 +1,27 @@ +--TEST-- +__serialize() exception in shm_put_var() +--EXTENSIONS-- +sysvshm +--FILE-- +getMessage() . "\n"; +} + +shm_remove($s); + +?> +--EXPECT-- +no diff --git a/ext/sysvshm/tests/shm_get_var_leak.phpt b/ext/sysvshm/tests/shm_get_var_leak.phpt new file mode 100644 index 000000000000..037bad7c41d7 --- /dev/null +++ b/ext/sysvshm/tests/shm_get_var_leak.phpt @@ -0,0 +1,37 @@ +--TEST-- +shm_get_var() leaks if variable is corrupted +--EXTENSIONS-- +sysvshm +ffi +--INI-- +ffi.enable=1 +--SKIPIF-- + +--FILE-- +shmat($ffi->shmget($key, 0, 0), $ffi->new('void *'), 0); + +$ptr[0x40 + 13] = 0; // Corrupt first byte of second element of serialized data + +var_dump(shm_get_var($s, 0)); + +shm_remove($s); + +?> +--EXPECTF-- +Warning: shm_get_var(): Variable data in shared memory is corrupted in %s on line %d +bool(false) diff --git a/ext/tidy/config.m4 b/ext/tidy/config.m4 index bb8523634659..18fa9acb3d4b 100644 --- a/ext/tidy/config.m4 +++ b/ext/tidy/config.m4 @@ -57,17 +57,35 @@ if test "$PHP_TIDY" != "no"; then [], [-L$TIDY_LIBDIR]) - PHP_CHECK_LIBRARY([$TIDY_LIB_NAME], [tidyOptGetCategory], - [AC_DEFINE([HAVE_TIDYOPTGETCATEGORY], [1], - [Define to 1 if Tidy library has the 'tidyOptGetCategory' function.])], - [], - [-L$TIDY_LIBDIR]) - PHP_ADD_LIBRARY_WITH_PATH([$TIDY_LIB_NAME], [$TIDY_LIBDIR], [TIDY_SHARED_LIBADD]) PHP_ADD_INCLUDE([$TIDY_INCDIR]) + old_CPPFLAGS=$CPPFLAGS + CPPFLAGS=-I$TIDY_INCDIR + + dnl The tidyOptGetCategory function (added in tidy-html5 5.4.0) is only + dnl useable if TidyInternalCategory (added in tidy-html5 5.6.0) is also + dnl present. + AC_CACHE_CHECK([for tidyOptGetCategory], [php_ac_cv_have_tidyoptgetcategory], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ],[ + TidyDoc doc = tidyCreate(); + TidyOption badopt = tidyGetOptionByName(doc, ""); + Bool v = (tidyOptGetCategory(badopt) == TidyInternalCategory); + (void)v; + tidyRelease(doc); + ])], + [php_ac_cv_have_tidyoptgetcategory=yes], + [php_ac_cv_have_tidyoptgetcategory=no]) + ]) + AS_VAR_IF([php_ac_cv_have_tidyoptgetcategory], [yes], + [AC_DEFINE([HAVE_TIDYOPTGETCATEGORY], [1], + [Define to 1 if Tidy library has the 'tidyOptGetCategory' function and + supports the 'TidyInternalCategory' enumeration.])]) + + CPPFLAGS=$old_CPPFLAGS + dnl Add -Wno-ignored-qualifiers as this is an issue upstream. Fixed in dnl tidy-html5 5.7.20: https://github.com/htacg/tidy-html5/issues/866 PHP_NEW_EXTENSION([tidy], diff --git a/ext/tidy/config.w32 b/ext/tidy/config.w32 index a1f93f2976af..8cbb5b9e681c 100644 --- a/ext/tidy/config.w32 +++ b/ext/tidy/config.w32 @@ -7,12 +7,12 @@ if (PHP_TIDY != "no") { if ((CHECK_LIB("libtidy_a.lib;tidy_a.lib", "tidy", PHP_TIDY) && (tidy_static = true) || CHECK_LIB("libtidy.lib;tidy.lib", "tidy", PHP_TIDY)) && ( - CHECK_HEADER_ADD_INCLUDE("tidy.h", "CFLAGS_TIDY") || - CHECK_HEADER_ADD_INCLUDE("tidy/tidy.h", "CFLAGS_TIDY", null, null, true) || - CHECK_HEADER_ADD_INCLUDE("libtidy/tidy.h", "CFLAGS_TIDY", null, null, true) + CHECK_HEADER("tidy.h", "CFLAGS_TIDY") || + CHECK_HEADER("tidy/tidy.h", "CFLAGS_TIDY", null, null, true) || + CHECK_HEADER("libtidy/tidy.h", "CFLAGS_TIDY", null, null, true) )) { - if (CHECK_HEADER_ADD_INCLUDE("tidybuffio.h", "CFLAGS_TIDY")) { + if (CHECK_HEADER("tidybuffio.h", "CFLAGS_TIDY")) { AC_DEFINE('HAVE_TIDYBUFFIO_H', 1, 'Define to 1 if you have the header file.'); } @@ -21,6 +21,7 @@ if (PHP_TIDY != "no") { AC_DEFINE('HAVE_TIDY_H', 1, "Define to 1 if you have the header file.") AC_DEFINE('HAVE_TIDYOPTGETDOC', 1, "Define to 1 if Tidy library has the 'tidyOptGetDoc' function.") AC_DEFINE('HAVE_TIDYRELEASEDATE', 1, "Define to 1 if Tidy library has the 'tidyReleaseDate' function.") + AC_DEFINE('HAVE_TIDYOPTGETCATEGORY', 1, "Define to 1 if Tidy library has the 'tidyOptGetCategory' function and supports the 'TidyInternalCategory' enumeration.") ADD_FLAG('CFLAGS_TIDY', '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); if (!PHP_TIDY_SHARED) { ADD_DEF_FILE("ext\\tidy\\php_tidy.def"); diff --git a/ext/tidy/php_tidy.h b/ext/tidy/php_tidy.h index 2c31a92a8370..9449580a7ace 100644 --- a/ext/tidy/php_tidy.h +++ b/ext/tidy/php_tidy.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: John Coggeshall | +----------------------------------------------------------------------+ diff --git a/ext/tidy/tests/018.phpt b/ext/tidy/tests/018.phpt index b07770eebb2b..e3934aa6d9fa 100644 --- a/ext/tidy/tests/018.phpt +++ b/ext/tidy/tests/018.phpt @@ -7,7 +7,7 @@ tidy $x = tidy_repair_string("

abra\0cadabra

", array( 'show-body-only' => true, 'clean' => false, - 'newline' => "\n") + 'newline' => "LF") ); var_dump($x); ?> diff --git a/ext/tidy/tests/025.phpt b/ext/tidy/tests/025.phpt index eda79a988517..d64199349110 100644 --- a/ext/tidy/tests/025.phpt +++ b/ext/tidy/tests/025.phpt @@ -19,7 +19,7 @@ $n = $tidy->Root()->child[0]->child[1]->child[0]; var_dump($n->isComment()); var_dump((string)$n); var_dump((bool)$n); -var_dump((double)$n); +var_dump((float)$n); var_dump((int)$n); var_dump($tidy->Root()->child[0]->child[0]->hasSiblings()); diff --git a/ext/tidy/tests/031.phpt b/ext/tidy/tests/031.phpt index e41d94be2f79..3b0ac39b209e 100644 --- a/ext/tidy/tests/031.phpt +++ b/ext/tidy/tests/031.phpt @@ -7,7 +7,7 @@ tidy --FILE-- '; -$config = array('doctype' => 'php'); +$config = array('doctype' => 'auto'); $tidy = tidy_parse_string($buffer, $config); var_dump(tidy_config_count($tidy)); diff --git a/ext/tidy/tests/gh20374.phpt b/ext/tidy/tests/gh20374.phpt new file mode 100644 index 000000000000..73299856b081 --- /dev/null +++ b/ext/tidy/tests/gh20374.phpt @@ -0,0 +1,173 @@ +--TEST-- +GH-20374 (PHP with tidy and custom-tags) +--EXTENSIONS-- +tidy +--CREDITS-- +franck-paul +--FILE-- +ret; + } +} + +class MyThrowingStringable { + public function __toString(): string { + throw new Error('no'); + } +} + +$values = [ + 'string blocklevel' => 'blocklevel', + 'int' => 1, + 'double overflow' => (string) (2.0**80.0), + 'numeric string int 1' => '1', + 'numeric string double 1.0' => '1.0', + 'false' => false, + 'true' => true, + 'NAN' => NAN, + 'INF' => INF, + 'object with numeric string int 0' => new MyStringable('0'), + 'object with string blocklevel' => new MyStringable('blocklevel'), + 'object with string empty' => new MyStringable('empty'), + 'object with exception' => new MyThrowingStringable, +]; + +foreach ($values as $key => $value) { + echo "--- $key ---\n"; + $str = 'test'; + + $config = [ + 'custom-tags' => $value, + ]; + + $tidy = new tidy(); + try { + $tidy->parseString($str, $config, 'utf8'); + echo $tidy->value, "\n"; + } catch (Throwable $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; + } +} + +?> +--EXPECTF-- +--- string blocklevel --- + + + + + +test + + +--- int --- + + + + + +test + + +--- double overflow --- + + + + + +test + + +--- numeric string int 1 --- + + + + + +test + + +--- numeric string double 1.0 --- + + + + + +test + + +--- false --- + + + + + +test + + +--- true --- + + + + + +test + + +--- NAN --- + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d + + + + + +test + + +--- INF --- + +Warning: The float INF is not representable as an int, cast occurred in %s on line %d + + + + + +test + + +--- object with numeric string int 0 --- + + + + + +test + + +--- object with string blocklevel --- + + + + + +test + + +--- object with string empty --- + + + + + + +test + + +--- object with exception --- +Error: no diff --git a/ext/tidy/tests/parsing_file_too_large.phpt b/ext/tidy/tests/parsing_file_too_large.phpt index efb539e528e0..8827ebb4af3a 100644 --- a/ext/tidy/tests/parsing_file_too_large.phpt +++ b/ext/tidy/tests/parsing_file_too_large.phpt @@ -4,6 +4,7 @@ Trying to parse a file that is too large (over 4GB) tidy --SKIPIF-- getMessage(), PHP_EOL; } -$config = ['doctype' => 'php', 0 => 'value2']; +$config = ['doctype' => 'php']; + +try { + var_dump($tidy->parseString($buffer, $config)); +} catch (\TypeError $e) { + echo $e::class, ": ", $e->getMessage(), PHP_EOL; +} + +$config = ['doctype' => 'auto', 0 => 'value2']; try { var_dump($tidy->parseString($buffer, $config)); @@ -45,4 +53,5 @@ try { ValueError: tidy::parseString(): Argument #2 ($config) Unknown Tidy configuration option "bogus" TypeError: tidy::parseString(): Argument #2 ($config) must be of type array with keys as string ValueError: tidy::parseString(): Argument #2 ($config) Attempting to set read-only option "doctype-mode" +TypeError: tidy::parseString(): Argument #2 ($config) option "doctype" does not accept "php" as a value TypeError: tidy::parseString(): Argument #2 ($config) must be of type array with keys as string diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index fe2a0648af68..cff4ad703418 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: John Coggeshall | +----------------------------------------------------------------------+ @@ -107,14 +105,14 @@ struct _PHPTidyObj { }; static inline PHPTidyObj *php_tidy_fetch_object(zend_object *obj) { - return (PHPTidyObj *)((char*)(obj) - XtOffsetOf(PHPTidyObj, std)); + return ZEND_CONTAINER_OF(obj, PHPTidyObj, std); } #define Z_TIDY_P(zv) php_tidy_fetch_object(Z_OBJ_P((zv))) /* }}} */ /* {{{ ext/tidy prototypes */ -static zend_string *php_tidy_file_to_mem(const char *, bool); +static zend_string *php_tidy_file_to_mem(const zend_string *, bool); static void tidy_object_free_storage(zend_object *); static zend_object *tidy_object_new_node(zend_class_entry *); static zend_object *tidy_object_new_doc(zend_class_entry *); @@ -124,7 +122,6 @@ static void tidy_doc_update_properties(PHPTidyObj *); static void tidy_add_node_default_properties(PHPTidyObj *); static void *php_tidy_get_opt_val(const PHPTidyDoc *, TidyOption, TidyOptionType *); static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes); -static zend_result _php_tidy_set_tidy_opt(TidyDoc, const char *, zval *, uint32_t arg); static zend_result _php_tidy_apply_config_array(TidyDoc doc, const HashTable *ht_options, uint32_t arg); static PHP_INI_MH(php_tidy_set_clean_output); static void php_tidy_clean_output_start(const char *name, size_t name_len); @@ -216,58 +213,6 @@ static zend_result php_tidy_apply_config(TidyDoc doc, const zend_string *str_str return SUCCESS; } -static zend_result _php_tidy_set_tidy_opt(TidyDoc doc, const char *optname, zval *value, uint32_t arg) -{ - TidyOption opt = tidyGetOptionByName(doc, optname); - zend_string *str, *tmp_str; - zend_long lval; - - if (!opt) { - zend_argument_value_error(arg, "Unknown Tidy configuration option \"%s\"", optname); - return FAILURE; - } - -#if defined(HAVE_TIDYOPTGETCATEGORY) - if (tidyOptGetCategory(opt) == TidyInternalCategory) { -#else - if (tidyOptIsReadOnly(opt)) { -#endif - zend_argument_value_error(arg, "Attempting to set read-only option \"%s\"", optname); - return FAILURE; - } - - switch(tidyOptGetType(opt)) { - case TidyString: - str = zval_get_tmp_string(value, &tmp_str); - if (tidyOptSetValue(doc, tidyOptGetId(opt), ZSTR_VAL(str))) { - zend_tmp_string_release(tmp_str); - return SUCCESS; - } - zend_tmp_string_release(tmp_str); - break; - - case TidyInteger: - lval = zval_get_long(value); - if (tidyOptSetInt(doc, tidyOptGetId(opt), lval)) { - return SUCCESS; - } - break; - - case TidyBoolean: - lval = zval_get_long(value); - if (tidyOptSetBool(doc, tidyOptGetId(opt), lval)) { - return SUCCESS; - } - break; - - default: - php_error_docref(NULL, E_WARNING, "Unable to determine type of configuration option"); - break; - } - - return FAILURE; -} - static void tidy_create_node_object(zval *zv, PHPTidyDoc *ptdoc, TidyNode node) { object_init_ex(zv, tidy_ce_node); @@ -299,7 +244,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, bool is_file) Z_PARAM_BOOL(use_include_path) ZEND_PARSE_PARAMETERS_END(); - if (!(data = php_tidy_file_to_mem(ZSTR_VAL(arg1), use_include_path))) { + if (!(data = php_tidy_file_to_mem(arg1, use_include_path))) { RETURN_FALSE; } } else { @@ -381,12 +326,12 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, bool is_file) tidyRelease(doc); } -static zend_string *php_tidy_file_to_mem(const char *filename, bool use_include_path) +static zend_string *php_tidy_file_to_mem(const zend_string *filename, bool use_include_path) { php_stream *stream; zend_string *data = NULL; - if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0), NULL))) { + if (!(stream = php_stream_open_wrapper(ZSTR_VAL(filename), "rb", (use_include_path ? USE_PATH : 0), NULL))) { return NULL; } if ((data = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) == NULL) { @@ -440,7 +385,7 @@ static zend_object *tidy_object_new(zend_class_entry *class_type, const zend_obj efree(intern->ptdoc->errbuf); tidyRelease(intern->ptdoc->doc); efree(intern->ptdoc); - efree(intern); + /* TODO: convert to exception */ php_error_docref(NULL, E_ERROR, "Could not set Tidy error buffer"); } @@ -526,8 +471,7 @@ static zend_result tidy_node_cast_handler(zend_object *in, zval *out, int type) case IS_STRING: obj = php_tidy_fetch_object(in); tidyBufInit(&buf); - if (obj->ptdoc) { - tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); + if (obj->ptdoc && tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf)) { ZVAL_STRINGL(out, (const char *) buf.bp, buf.size-1); } else { ZVAL_EMPTY_STRING(out); @@ -583,7 +527,7 @@ static void tidy_add_node_default_properties(PHPTidyObj *obj) const char *name; tidyBufInit(&buf); - tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); + (void) tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); zend_update_property_stringl( tidy_ce_node, @@ -669,12 +613,14 @@ static void tidy_add_node_default_properties(PHPTidyObj *obj) do { const char *attr_name = tidyAttrName(tempattr); if (attr_name) { + zval value; const char *val = tidyAttrValue(tempattr); if (val) { - add_assoc_string(&attribute, attr_name, val); + ZVAL_STRING_FAST(&value, val); } else { - add_assoc_str(&attribute, attr_name, zend_empty_string); + ZVAL_EMPTY_STRING(&value); } + zend_hash_str_add_new(Z_ARRVAL(attribute), attr_name, strlen(attr_name), &value); } } while((tempattr = tidyAttrNext(tempattr))); } else { @@ -720,28 +666,19 @@ static void *php_tidy_get_opt_val(const PHPTidyDoc *ptdoc, TidyOption opt, TidyO { *type = tidyOptGetType(opt); - switch (*type) { - case TidyString: { - const char *val = tidyOptGetValue(ptdoc->doc, tidyOptGetId(opt)); - if (val) { - return (void *) zend_string_init(val, strlen(val), 0); - } else { - return (void *) ZSTR_EMPTY_ALLOC(); - } + if (*type == TidyString) { + const char *val = tidyOptGetValue(ptdoc->doc, tidyOptGetId(opt)); + if (val) { + return (void *) zend_string_init(val, strlen(val), 0); + } else { + return (void *) ZSTR_EMPTY_ALLOC(); } - break; - - case TidyInteger: - return (void *) (uintptr_t) tidyOptGetInt(ptdoc->doc, tidyOptGetId(opt)); - break; - - case TidyBoolean: - return (void *) tidyOptGetBool(ptdoc->doc, tidyOptGetId(opt)); - break; + } else if (*type == TidyInteger) { + return (void *) (uintptr_t) tidyOptGetInt(ptdoc->doc, tidyOptGetId(opt)); + } else { + ZEND_ASSERT(*type == TidyBoolean); + return (void *) tidyOptGetBool(ptdoc->doc, tidyOptGetId(opt)); } - - /* should not happen */ - return NULL; } static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetypes node_type) @@ -766,7 +703,7 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp node = tidyGetBody(obj->ptdoc->doc); break; - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } if (!node) { @@ -776,31 +713,100 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp tidy_create_node_object(return_value, obj->ptdoc, node); } + +static bool php_tidy_set_tidy_opt(TidyDoc doc, const char *optname, zval *value, uint32_t arg) +{ + TidyOption opt = tidyGetOptionByName(doc, optname); + zend_long lval; + zend_string *tmp_str; + + if (!opt) { + zend_argument_value_error(arg, "Unknown Tidy configuration option \"%s\"", optname); + return false; + } + +#if defined(HAVE_TIDYOPTGETCATEGORY) + if (tidyOptGetCategory(opt) == TidyInternalCategory) { +#else + if (tidyOptIsReadOnly(opt)) { +#endif + zend_argument_value_error(arg, "Attempting to set read-only option \"%s\"", optname); + return false; + } + + TidyOptionType type = tidyOptGetType(opt); + if (type == TidyString) { + const zend_string *str = zval_get_tmp_string(value, &tmp_str); + const bool result = tidyOptSetValue(doc, tidyOptGetId(opt), ZSTR_VAL(str)); + if (UNEXPECTED(!result)) { + zend_argument_type_error(arg, "option \"%s\" does not accept \"%s\" as a value", optname, ZSTR_VAL(str)); + } + zend_tmp_string_release(tmp_str); + return result; + } else if (type == TidyInteger) { /* integer or enum */ + ZVAL_DEREF(value); + /* Enum will correspond to a non-numeric string or object */ + if (Z_TYPE_P(value) == IS_STRING || Z_TYPE_P(value) == IS_OBJECT) { + double dval; + bool result; + const zend_string *str = zval_try_get_tmp_string(value, &tmp_str); + if (UNEXPECTED(!str)) { + return false; + } + uint8_t type = is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &lval, &dval, true); + if (type == IS_DOUBLE) { + lval = zend_dval_to_lval_cap(dval); + type = IS_LONG; + } + if (type == IS_LONG) { + result = tidyOptSetInt(doc, tidyOptGetId(opt), lval); + } else { + result = tidyOptSetValue(doc, tidyOptGetId(opt), ZSTR_VAL(str)); + if (UNEXPECTED(!result)) { + zend_argument_type_error(arg, "option \"%s\" does not accept \"%s\" as a value", optname, ZSTR_VAL(str)); + } + } + zend_tmp_string_release(tmp_str); + return result; + } else { + lval = zval_get_long(value); + return tidyOptSetInt(doc, tidyOptGetId(opt), lval); + } + } else { + ZEND_ASSERT(type == TidyBoolean); + lval = zval_get_long(value); + return tidyOptSetBool(doc, tidyOptGetId(opt), lval); + } +} + static zend_result _php_tidy_apply_config_array(TidyDoc doc, const HashTable *ht_options, uint32_t arg) { zval *opt_val; zend_string *opt_name; if (!HT_IS_PACKED(ht_options)) { + bool has_failures = false; ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht_options, opt_name, opt_val) { if (opt_name == NULL) { zend_argument_type_error(arg, "must be of type array with keys as string"); return FAILURE; } - _php_tidy_set_tidy_opt(doc, ZSTR_VAL(opt_name), opt_val, arg); + has_failures = has_failures || !php_tidy_set_tidy_opt(doc, ZSTR_VAL(opt_name), opt_val, arg); } ZEND_HASH_FOREACH_END(); - return SUCCESS; + return has_failures ? FAILURE : SUCCESS; } else { zend_argument_type_error(arg, "must be of type array with keys as string"); return FAILURE; } } -static zend_result php_tidy_parse_string(PHPTidyObj *obj, const char *string, uint32_t len, const char *enc) +static zend_result php_tidy_parse_string(PHPTidyObj *obj, const zend_string *string, const char *enc) { TidyBuffer buf; - if(enc) { + ZEND_ASSERT(!ZEND_SIZE_T_UINT_OVFL(ZSTR_LEN(string))); + + if (enc) { if (tidySetCharEncoding(obj->ptdoc->doc, enc) < 0) { php_error_docref(NULL, E_WARNING, "Could not set encoding \"%s\"", enc); return FAILURE; @@ -810,9 +816,9 @@ static zend_result php_tidy_parse_string(PHPTidyObj *obj, const char *string, ui obj->ptdoc->initialized = true; tidyBufInit(&buf); - tidyBufAttach(&buf, (byte *) string, len); + tidyBufAttach(&buf, (byte *) ZSTR_VAL(string), (unsigned int) ZSTR_LEN(string)); if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) { - php_error_docref(NULL, E_WARNING, "%s", obj->ptdoc->errbuf->bp); + php_error_docref(NULL, E_WARNING, "%s", (const char*) obj->ptdoc->errbuf->bp); return FAILURE; } tidy_doc_update_properties(obj); @@ -842,7 +848,7 @@ static PHP_MINIT_FUNCTION(tidy) tidy_object_handlers_doc.cast_object = tidy_doc_cast_handler; tidy_object_handlers_node.cast_object = tidy_node_cast_handler; - tidy_object_handlers_node.offset = tidy_object_handlers_doc.offset = XtOffsetOf(PHPTidyObj, std); + tidy_object_handlers_node.offset = tidy_object_handlers_doc.offset = offsetof(PHPTidyObj, std); tidy_object_handlers_node.free_obj = tidy_object_handlers_doc.free_obj = tidy_object_free_storage; register_tidy_symbols(module_number); @@ -865,7 +871,7 @@ static PHP_RINIT_FUNCTION(tidy) static PHP_RSHUTDOWN_FUNCTION(tidy) { - TG(clean_output) = INI_ORIG_BOOL("tidy.clean_output"); + TG(clean_output) = zend_ini_parse_bool(zend_ini_str(ZEND_STRL("tidy.clean_output"), /* orig */ true)); return SUCCESS; } @@ -1016,7 +1022,7 @@ PHP_FUNCTION(tidy_parse_string) obj = Z_TIDY_P(return_value); if (php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) != SUCCESS - || php_tidy_parse_string(obj, ZSTR_VAL(input), (uint32_t)ZSTR_LEN(input), enc) != SUCCESS) { + || php_tidy_parse_string(obj, input, enc) != SUCCESS) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -1069,7 +1075,7 @@ PHP_FUNCTION(tidy_parse_file) Z_PARAM_BOOL(use_include_path) ZEND_PARSE_PARAMETERS_END(); - if (!(contents = php_tidy_file_to_mem(ZSTR_VAL(inputfile), use_include_path))) { + if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path))) { php_error_docref(NULL, E_WARNING, "Cannot load \"%s\" into memory%s", ZSTR_VAL(inputfile), (use_include_path) ? " (using include path)" : ""); RETURN_FALSE; } @@ -1084,7 +1090,7 @@ PHP_FUNCTION(tidy_parse_file) obj = Z_TIDY_P(return_value); if (php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) != SUCCESS - || php_tidy_parse_string(obj, ZSTR_VAL(contents), (uint32_t)ZSTR_LEN(contents), enc) != SUCCESS) { + || php_tidy_parse_string(obj, contents, enc) != SUCCESS) { zval_ptr_dtor(return_value); RETVAL_FALSE; } @@ -1322,18 +1328,10 @@ PHP_FUNCTION(tidy_getopt) case TidyInteger: RETURN_LONG((zend_long)optval); - break; case TidyBoolean: RETURN_BOOL(optval); - break; - - default: - php_error_docref(NULL, E_WARNING, "Unable to determine type of configuration option"); - break; } - - RETURN_FALSE; } /* }}} */ @@ -1357,7 +1355,7 @@ PHP_METHOD(tidy, __construct) obj = Z_TIDY_P(ZEND_THIS); if (inputfile) { - if (!(contents = php_tidy_file_to_mem(ZSTR_VAL(inputfile), use_include_path))) { + if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path))) { zend_throw_error(zend_ce_exception, "Cannot load \"%s\" into memory%s", ZSTR_VAL(inputfile), (use_include_path) ? " (using include path)" : ""); RETURN_THROWS(); } @@ -1377,7 +1375,7 @@ PHP_METHOD(tidy, __construct) } zend_restore_error_handling(&error_handling); - php_tidy_parse_string(obj, ZSTR_VAL(contents), (uint32_t)ZSTR_LEN(contents), enc); + php_tidy_parse_string(obj, contents, enc); zend_string_release_ex(contents, 0); } @@ -1402,7 +1400,7 @@ PHP_METHOD(tidy, parseFile) obj = Z_TIDY_P(ZEND_THIS); - if (!(contents = php_tidy_file_to_mem(ZSTR_VAL(inputfile), use_include_path))) { + if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path))) { php_error_docref(NULL, E_WARNING, "Cannot load \"%s\" into memory%s", ZSTR_VAL(inputfile), (use_include_path) ? " (using include path)" : ""); RETURN_FALSE; } @@ -1414,7 +1412,7 @@ PHP_METHOD(tidy, parseFile) } RETVAL_BOOL(php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) == SUCCESS - && php_tidy_parse_string(obj, ZSTR_VAL(contents), (uint32_t)ZSTR_LEN(contents), enc) == SUCCESS); + && php_tidy_parse_string(obj, contents, enc) == SUCCESS); zend_string_release_ex(contents, 0); } @@ -1442,7 +1440,7 @@ PHP_METHOD(tidy, parseString) obj = Z_TIDY_P(ZEND_THIS); RETURN_BOOL(php_tidy_apply_config(obj->ptdoc->doc, options_str, options_ht, 2) == SUCCESS - && php_tidy_parse_string(obj, ZSTR_VAL(input), (uint32_t)ZSTR_LEN(input), enc) == SUCCESS); + && php_tidy_parse_string(obj, input, enc) == SUCCESS); } diff --git a/ext/tidy/tidy_arginfo.h b/ext/tidy/tidy_arginfo.h index 4084a29f4d90..22336502bfd5 100644 --- a/ext/tidy/tidy_arginfo.h +++ b/ext/tidy/tidy_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit tidy.stub.php instead. * Stub hash: 0e6561410a63658f76011c1ddcecdd1e68757f0a */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_tidy_parse_string, 0, 1, tidy, MAY_BE_FALSE) @@ -476,9 +476,9 @@ static zend_class_entry *register_class_tidy(void) zval property_errorBuffer_default_value; ZVAL_NULL(&property_errorBuffer_default_value); - zend_string *property_errorBuffer_name = zend_string_init("errorBuffer", sizeof("errorBuffer") - 1, 1); + zend_string *property_errorBuffer_name = zend_string_init("errorBuffer", sizeof("errorBuffer") - 1, true); zend_declare_typed_property(class_entry, property_errorBuffer_name, &property_errorBuffer_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL)); - zend_string_release(property_errorBuffer_name); + zend_string_release_ex(property_errorBuffer_name, true); zval property_value_default_value; ZVAL_NULL(&property_value_default_value); @@ -512,33 +512,33 @@ static zend_class_entry *register_class_tidyNode(void) zval property_column_default_value; ZVAL_UNDEF(&property_column_default_value); - zend_string *property_column_name = zend_string_init("column", sizeof("column") - 1, 1); + zend_string *property_column_name = zend_string_init("column", sizeof("column") - 1, true); zend_declare_typed_property(class_entry, property_column_name, &property_column_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_column_name); + zend_string_release_ex(property_column_name, true); zval property_proprietary_default_value; ZVAL_UNDEF(&property_proprietary_default_value); - zend_string *property_proprietary_name = zend_string_init("proprietary", sizeof("proprietary") - 1, 1); + zend_string *property_proprietary_name = zend_string_init("proprietary", sizeof("proprietary") - 1, true); zend_declare_typed_property(class_entry, property_proprietary_name, &property_proprietary_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_proprietary_name); + zend_string_release_ex(property_proprietary_name, true); zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); - zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG|MAY_BE_NULL)); - zend_string_release(property_id_name); + zend_string_release_ex(property_id_name, true); zval property_attribute_default_value; ZVAL_UNDEF(&property_attribute_default_value); - zend_string *property_attribute_name = zend_string_init("attribute", sizeof("attribute") - 1, 1); + zend_string *property_attribute_name = zend_string_init("attribute", sizeof("attribute") - 1, true); zend_declare_typed_property(class_entry, property_attribute_name, &property_attribute_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release(property_attribute_name); + zend_string_release_ex(property_attribute_name, true); zval property_child_default_value; ZVAL_UNDEF(&property_child_default_value); - zend_string *property_child_name = zend_string_init("child", sizeof("child") - 1, 1); + zend_string *property_child_name = zend_string_init("child", sizeof("child") - 1, true); zend_declare_typed_property(class_entry, property_child_name, &property_child_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY|MAY_BE_NULL)); - zend_string_release(property_child_name); + zend_string_release_ex(property_child_name, true); return class_entry; } diff --git a/ext/tokenizer/php_tokenizer.h b/ext/tokenizer/php_tokenizer.h index edc715de8d71..3acdebc4ac66 100644 --- a/ext/tokenizer/php_tokenizer.h +++ b/ext/tokenizer/php_tokenizer.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ diff --git a/ext/tokenizer/tests/gh19507_eval.phpt b/ext/tokenizer/tests/gh19507_eval.phpt new file mode 100644 index 000000000000..e731cf818afb --- /dev/null +++ b/ext/tokenizer/tests/gh19507_eval.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-19507: Corrupted result after recursive tokenization during token_get_all() (error handler with eval) +--EXTENSIONS-- +tokenizer +--FILE-- +getTokenName(), "\n"; +} +?> +--EXPECT-- +error handler called: Non-canonical cast (double) is deprecated, use the (float) cast instead +T_OPEN_TAG +T_DOUBLE_CAST +T_WHITESPACE +T_VARIABLE +; diff --git a/ext/tokenizer/tests/gh19507_throw.phpt b/ext/tokenizer/tests/gh19507_throw.phpt new file mode 100644 index 000000000000..4449fe430538 --- /dev/null +++ b/ext/tokenizer/tests/gh19507_throw.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19507: Corrupted result after recursive tokenization during token_get_all() (error handler with throw) +--EXTENSIONS-- +tokenizer +--FILE-- +getTokenName(), "\n"; +} +?> +--EXPECTF-- +Fatal error: Uncaught RuntimeException: error handler called: Non-canonical cast (double) is deprecated, use the (float) cast instead in %s:%d +Stack trace: +#0 [internal function]: {closure:%s:%d}(%d, 'Non-canonical c...', '', 1) +#1 %s(%d): PhpToken::tokenize('. | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Andrei Zmievski | +----------------------------------------------------------------------+ @@ -381,7 +379,7 @@ static bool tokenize(zval *return_value, zend_string *source, zend_class_entry * zend_restore_lexical_state(&original_lex_state); zend_hash_destroy(&interned_strings); - return 1; + return true; } struct event_context { diff --git a/ext/tokenizer/tokenizer_arginfo.h b/ext/tokenizer/tokenizer_arginfo.h index b98a5655b6c7..d2f8f9254f73 100644 --- a/ext/tokenizer/tokenizer_arginfo.h +++ b/ext/tokenizer/tokenizer_arginfo.h @@ -1,4 +1,4 @@ -/* This is a generated file, edit the .stub.php file instead. +/* This is a generated file, edit tokenizer.stub.php instead. * Stub hash: a89f03303f8a7d254509ae2bc46a36bb79a3c900 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_token_get_all, 0, 1, IS_ARRAY, 0) @@ -72,15 +72,15 @@ static zend_class_entry *register_class_PhpToken(zend_class_entry *class_entry_S zval property_id_default_value; ZVAL_UNDEF(&property_id_default_value); - zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, 1); + zend_string *property_id_name = zend_string_init("id", sizeof("id") - 1, true); zend_declare_typed_property(class_entry, property_id_name, &property_id_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_id_name); + zend_string_release_ex(property_id_name, true); zval property_text_default_value; ZVAL_UNDEF(&property_text_default_value); - zend_string *property_text_name = zend_string_init("text", sizeof("text") - 1, 1); + zend_string *property_text_name = zend_string_init("text", sizeof("text") - 1, true); zend_declare_typed_property(class_entry, property_text_name, &property_text_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_text_name); + zend_string_release_ex(property_text_name, true); zval property_line_default_value; ZVAL_UNDEF(&property_line_default_value); @@ -88,9 +88,9 @@ static zend_class_entry *register_class_PhpToken(zend_class_entry *class_entry_S zval property_pos_default_value; ZVAL_UNDEF(&property_pos_default_value); - zend_string *property_pos_name = zend_string_init("pos", sizeof("pos") - 1, 1); + zend_string *property_pos_name = zend_string_init("pos", sizeof("pos") - 1, true); zend_declare_typed_property(class_entry, property_pos_name, &property_pos_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); - zend_string_release(property_pos_name); + zend_string_release_ex(property_pos_name, true); return class_entry; } diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index 0900c51d3d95..38f5c5910876 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Johannes Schlueter | +----------------------------------------------------------------------+ @@ -168,6 +166,7 @@ char *get_token_type_name(int token_type) case T_DOLLAR_OPEN_CURLY_BRACES: return "T_DOLLAR_OPEN_CURLY_BRACES"; case T_CURLY_OPEN: return "T_CURLY_OPEN"; case T_PAAMAYIM_NEKUDOTAYIM: return "T_DOUBLE_COLON"; + case T_TURBOFISH: return "T_TURBOFISH"; case T_NS_SEPARATOR: return "T_NS_SEPARATOR"; case T_ELLIPSIS: return "T_ELLIPSIS"; case T_COALESCE: return "T_COALESCE"; diff --git a/ext/tokenizer/tokenizer_data.stub.php b/ext/tokenizer/tokenizer_data.stub.php index 57c8edad8acb..e3dffb5e8979 100644 --- a/ext/tokenizer/tokenizer_data.stub.php +++ b/ext/tokenizer/tokenizer_data.stub.php @@ -717,6 +717,11 @@ * @cvalue T_PAAMAYIM_NEKUDOTAYIM */ const T_PAAMAYIM_NEKUDOTAYIM = UNKNOWN; +/** + * @var int + * @cvalue T_TURBOFISH + */ +const T_TURBOFISH = UNKNOWN; /** * @var int * @cvalue T_NS_SEPARATOR diff --git a/ext/tokenizer/tokenizer_data_arginfo.h b/ext/tokenizer/tokenizer_data_arginfo.h index 3a3cdaa46813..4c5f81240ae5 100644 --- a/ext/tokenizer/tokenizer_data_arginfo.h +++ b/ext/tokenizer/tokenizer_data_arginfo.h @@ -1,5 +1,5 @@ -/* This is a generated file, edit the .stub.php file instead. - * Stub hash: c5235344b7c651d27c2c33c90696a418a9c96837 */ +/* This is a generated file, edit tokenizer_data.stub.php instead. + * Stub hash: 34e6a9cb933770d8434820f2e7b567a05ed95c9e */ static void register_tokenizer_data_symbols(int module_number) { @@ -146,6 +146,7 @@ static void register_tokenizer_data_symbols(int module_number) REGISTER_LONG_CONSTANT("T_DOLLAR_OPEN_CURLY_BRACES", T_DOLLAR_OPEN_CURLY_BRACES, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CURLY_OPEN", T_CURLY_OPEN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PAAMAYIM_NEKUDOTAYIM", T_PAAMAYIM_NEKUDOTAYIM, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_TURBOFISH", T_TURBOFISH, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NS_SEPARATOR", T_NS_SEPARATOR, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_ELLIPSIS", T_ELLIPSIS, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_COALESCE", T_COALESCE, CONST_PERSISTENT); diff --git a/ext/tokenizer/tokenizer_data_gen.php b/ext/tokenizer/tokenizer_data_gen.php index 79753b6e81a5..0119b0cc0237 100755 --- a/ext/tokenizer/tokenizer_data_gen.php +++ b/ext/tokenizer/tokenizer_data_gen.php @@ -39,15 +39,13 @@ $result = <<. | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Author: Johannes Schlueter | +----------------------------------------------------------------------+ diff --git a/ext/uri/config.m4 b/ext/uri/config.m4 index 08dc044d8d29..31d6c0e10c84 100644 --- a/ext/uri/config.m4 +++ b/ext/uri/config.m4 @@ -1,22 +1,48 @@ dnl Configure options dnl +PHP_ARG_WITH([external-uriparser], + [for external/system liburiparser], + [AS_HELP_STRING([--with-external-uriparser], + [Use external/system liburiparser])], + [no], + [no]) + PHP_INSTALL_HEADERS([ext/uri], m4_normalize([ - php_lexbor.h php_uri.h php_uri_common.h + php_uri_decl.h + uri_parser_rfc3986.h + uri_parser_whatwg.h + uri_parser_php_parse_url.h ])) + AC_DEFINE([URI_ENABLE_ANSI], [1], [Define to 1 for enabling ANSI support of uriparser.]) AC_DEFINE([URI_NO_UNICODE], [1], [Define to 1 for disabling unicode support of uriparser.]) -URIPARSER_DIR="uriparser" -URIPARSER_SOURCES="$URIPARSER_DIR/src/UriCommon.c $URIPARSER_DIR/src/UriCompare.c $URIPARSER_DIR/src/UriEscape.c \ -$URIPARSER_DIR/src/UriFile.c $URIPARSER_DIR/src/UriIp4.c $URIPARSER_DIR/src/UriIp4Base.c \ -$URIPARSER_DIR/src/UriMemory.c $URIPARSER_DIR/src/UriNormalize.c $URIPARSER_DIR/src/UriNormalizeBase.c \ -$URIPARSER_DIR/src/UriParse.c $URIPARSER_DIR/src/UriParseBase.c $URIPARSER_DIR/src/UriQuery.c \ -$URIPARSER_DIR/src/UriRecompose.c $URIPARSER_DIR/src/UriResolve.c $URIPARSER_DIR/src/UriShorten.c" +if test "$PHP_EXTERNAL_URIPARSER" = "no"; then + URIPARSER_DIR="uriparser" + URIPARSER_SOURCES="$URIPARSER_DIR/src/UriCommon.c $URIPARSER_DIR/src/UriCompare.c $URIPARSER_DIR/src/UriCopy.c \ + $URIPARSER_DIR/src/UriEscape.c $URIPARSER_DIR/src/UriFile.c $URIPARSER_DIR/src/UriIp4.c $URIPARSER_DIR/src/UriIp4Base.c \ + $URIPARSER_DIR/src/UriMemory.c $URIPARSER_DIR/src/UriNormalize.c $URIPARSER_DIR/src/UriNormalizeBase.c \ + $URIPARSER_DIR/src/UriParse.c $URIPARSER_DIR/src/UriParseBase.c $URIPARSER_DIR/src/UriQuery.c \ + $URIPARSER_DIR/src/UriRecompose.c $URIPARSER_DIR/src/UriResolve.c $URIPARSER_DIR/src/UriSetFragment.c \ + $URIPARSER_DIR/src/UriSetHostAuto.c $URIPARSER_DIR/src/UriSetHostCommon.c $URIPARSER_DIR/src/UriSetHostIp4.c \ + $URIPARSER_DIR/src/UriSetHostIp6.c $URIPARSER_DIR/src/UriSetHostIpFuture.c $URIPARSER_DIR/src/UriSetHostRegName.c \ + $URIPARSER_DIR/src/UriSetPath.c $URIPARSER_DIR/src/UriSetPort.c $URIPARSER_DIR/src/UriSetQuery.c \ + $URIPARSER_DIR/src/UriSetScheme.c $URIPARSER_DIR/src/UriSetUserInfo.c $URIPARSER_DIR/src/UriShorten.c $URIPARSER_DIR/src/UriVersion.c" + URI_CFLAGS="-DURI_STATIC_BUILD" +else + PKG_CHECK_MODULES([LIBURIPARSER], [liburiparser >= 1.0.0]) + PHP_EVAL_LIBLINE([$LIBURIPARSER_LIBS]) + PHP_EVAL_INCLINE([$LIBURIPARSER_CFLAGS]) +fi -PHP_NEW_EXTENSION(uri, [php_lexbor.c php_uri.c php_uri_common.c $URIPARSER_SOURCES], [no],,[-I$ext_srcdir/$URIPARSER_DIR/include -DURI_STATIC_BUILD -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) +PHP_NEW_EXTENSION(uri, [php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c $URIPARSER_SOURCES], [no],,[$URI_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_ADD_EXTENSION_DEP(uri, lexbor) -PHP_ADD_BUILD_DIR($ext_builddir/$URIPARSER_DIR/src $ext_builddir/$URIPARSER_DIR/include) + +if test "$PHP_EXTERNAL_URIPARSER" = "no"; then + PHP_ADD_BUILD_DIR($ext_builddir/$URIPARSER_DIR/src $ext_builddir/$URIPARSER_DIR/include) + PHP_ADD_INCLUDE([$ext_srcdir/$URIPARSER_DIR/include]) +fi diff --git a/ext/uri/config.w32 b/ext/uri/config.w32 index 9c6af0cc5fa7..b7c4bfbd2246 100644 --- a/ext/uri/config.w32 +++ b/ext/uri/config.w32 @@ -1,9 +1,12 @@ -EXTENSION("uri", "php_lexbor.c php_uri.c php_uri_common.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("uri", "php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("URI_ENABLE_ANSI", 1, "Define to 1 for enabling ANSI support of uriparser.") AC_DEFINE("URI_NO_UNICODE", 1, "Define to 1 for disabling unicode support of uriparser.") ADD_FLAG("CFLAGS_URI", "/D URI_STATIC_BUILD"); ADD_EXTENSION_DEP('uri', 'lexbor'); -ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c UriMemory.c UriNormalize.c UriNormalizeBase.c UriParse.c UriParseBase.c UriQuery.c UriRecompose.c UriShorten.c", "uri"); -PHP_INSTALL_HEADERS("ext/uri", "php_lexbor.h php_uri.h php_uri_common.h uriparser/src uriparser/include"); +ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriCopy.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c \ + UriMemory.c UriNormalize.c UriNormalizeBase.c UriParse.c UriParseBase.c UriQuery.c UriRecompose.c UriResolve.c \ + UriSetFragment.c UriSetHostAuto.c UriSetHostCommon.c UriSetHostIp4.c UriSetHostIp6.c UriSetHostIpFuture.c UriSetHostRegName.c \ + UriSetPath.c UriSetPort.c UriSetQuery.c UriSetScheme.c UriSetUserInfo.c UriShorten.c UriVersion.c", "uri"); +PHP_INSTALL_HEADERS("ext/uri", "php_uri.h php_uri_common.h php_uri_decl.h uri_parser_rfc3986.h uri_parser_whatwg.h uri_parser_php_parse_url.h uriparser/src uriparser/include"); diff --git a/ext/uri/php_lexbor.c b/ext/uri/php_lexbor.c deleted file mode 100644 index 44bca30f8fda..000000000000 --- a/ext/uri/php_lexbor.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Máté Kocsis | - +----------------------------------------------------------------------+ -*/ - -#include "php.h" -#include "php_lexbor.h" -#include "php_uri_common.h" -#include "Zend/zend_enum.h" -#include "Zend/zend_smart_str.h" -#include "Zend/zend_exceptions.h" -#ifdef HAVE_ARPA_INET_H -#include -#endif - -ZEND_TLS lxb_url_parser_t lexbor_parser; -ZEND_TLS unsigned short int lexbor_urls; - -#define LEXBOR_MAX_URL_COUNT 500 -#define LEXBOR_MRAW_BYTE_SIZE 8192 - -static zend_always_inline void zval_string_or_null_to_lexbor_str(zval *value, lexbor_str_t *lexbor_str) -{ - if (Z_TYPE_P(value) == IS_STRING && Z_STRLEN_P(value) > 0) { - lexbor_str->data = (lxb_char_t *) Z_STRVAL_P(value); - lexbor_str->length = Z_STRLEN_P(value); - } else { - ZEND_ASSERT(Z_ISNULL_P(value) || (Z_TYPE_P(value) == IS_STRING && Z_STRLEN_P(value) == 0)); - lexbor_str->data = (lxb_char_t *) ""; - lexbor_str->length = 0; - } -} - -static zend_always_inline void zval_long_or_null_to_lexbor_str(zval *value, lexbor_str_t *lexbor_str) -{ - if (Z_TYPE_P(value) == IS_LONG) { - ZVAL_STR(value, zend_long_to_str(Z_LVAL_P(value))); - lexbor_str_init_append(lexbor_str, lexbor_parser.mraw, (const lxb_char_t *) Z_STRVAL_P(value), Z_STRLEN_P(value)); - zval_ptr_dtor_str(value); - } else { - ZEND_ASSERT(Z_ISNULL_P(value)); - lexbor_str->data = (lxb_char_t *) ""; - lexbor_str->length = 0; - } -} - -static void lexbor_cleanup_parser(void) -{ - if (++lexbor_urls % LEXBOR_MAX_URL_COUNT == 0) { - lexbor_mraw_clean(lexbor_parser.mraw); - lexbor_urls = 0; - } - - lxb_url_parser_clean(&lexbor_parser); -} - -/** - * Creates a Uri\WhatWg\UrlValidationError class by mapping error codes listed in - * https://url.spec.whatwg.org/#writing to a Uri\WhatWg\UrlValidationErrorType enum. - * The result is passed by reference to the errors parameter. - * - * When errors is NULL, the caller is not interested in the additional error information, - * so the function does nothing. - */ -static zend_string *fill_errors(zval *errors) -{ - if (errors == NULL) { - return NULL; - } - - ZEND_ASSERT(Z_ISUNDEF_P(errors)); - - array_init(errors); - - if (lexbor_parser.log == NULL) { - return NULL; - } - - zend_string *result = NULL; - lexbor_plog_entry_t *lxb_error; - while ((lxb_error = lexbor_array_obj_pop(&lexbor_parser.log->list)) != NULL) { - zval error; - object_init_ex(&error, uri_whatwg_url_validation_error_ce); - zend_update_property_string(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("context"), (const char *) lxb_error->data); - - zend_string *error_str; - zval failure; - switch (lxb_error->id) { - case LXB_URL_ERROR_TYPE_DOMAIN_TO_ASCII: - error_str = ZSTR_INIT_LITERAL("DomainToAscii", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_DOMAIN_TO_UNICODE: - error_str = ZSTR_INIT_LITERAL("DomainToUnicode", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_DOMAIN_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("DomainInvalidCodePoint", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_HOST_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("HostInvalidCodePoint", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_EMPTY_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4EmptyPart", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_TOO_MANY_PARTS: - error_str = ZSTR_INIT_LITERAL("Ipv4TooManyParts", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_NON_NUMERIC_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4NonNumericPart", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_NON_DECIMAL_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4NonDecimalPart", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_OUT_OF_RANGE_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4OutOfRangePart", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV6_UNCLOSED: - error_str = ZSTR_INIT_LITERAL("Ipv6Unclosed", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV6_INVALID_COMPRESSION: - error_str = ZSTR_INIT_LITERAL("Ipv6InvalidCompression", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV6_TOO_MANY_PIECES: - error_str = ZSTR_INIT_LITERAL("Ipv6TooManyPieces", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV6_MULTIPLE_COMPRESSION: - error_str = ZSTR_INIT_LITERAL("Ipv6MultipleCompression", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV6_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("Ipv6InvalidCodePoint", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV6_TOO_FEW_PIECES: - error_str = ZSTR_INIT_LITERAL("Ipv6TooFewPieces", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_TOO_MANY_PIECES: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6TooManyPieces", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_INVALID_CODE_POINT: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6InvalidCodePoint", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_OUT_OF_RANGE_PART: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6OutOfRangePart", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_TOO_FEW_PARTS: - error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6TooFewParts", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_INVALID_URL_UNIT: - error_str = ZSTR_INIT_LITERAL("InvalidUrlUnit", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_SPECIAL_SCHEME_MISSING_FOLLOWING_SOLIDUS: - error_str = ZSTR_INIT_LITERAL("SpecialSchemeMissingFollowingSolidus", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_MISSING_SCHEME_NON_RELATIVE_URL: - error_str = ZSTR_INIT_LITERAL("MissingSchemeNonRelativeUrl", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_INVALID_REVERSE_SOLIDUS: - error_str = ZSTR_INIT_LITERAL("InvalidReverseSoldius", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_INVALID_CREDENTIALS: - error_str = ZSTR_INIT_LITERAL("InvalidCredentials", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_HOST_MISSING: - error_str = ZSTR_INIT_LITERAL("HostMissing", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_PORT_OUT_OF_RANGE: - error_str = ZSTR_INIT_LITERAL("PortOutOfRange", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_PORT_INVALID: - error_str = ZSTR_INIT_LITERAL("PortInvalid", false); - ZVAL_TRUE(&failure); - break; - case LXB_URL_ERROR_TYPE_FILE_INVALID_WINDOWS_DRIVE_LETTER: - error_str = ZSTR_INIT_LITERAL("FileInvalidWindowsDriveLetter", false); - ZVAL_FALSE(&failure); - break; - case LXB_URL_ERROR_TYPE_FILE_INVALID_WINDOWS_DRIVE_LETTER_HOST: - error_str = ZSTR_INIT_LITERAL("FileInvalidWindowsDriveLetterHost", false); - ZVAL_FALSE(&failure); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - - zval error_type; - zend_enum_new(&error_type, uri_whatwg_url_validation_error_type_ce, error_str, NULL); - zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZSTR_KNOWN(ZEND_STR_TYPE), &error_type); - zend_string_release_ex(error_str, false); - zval_ptr_dtor(&error_type); - - zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("failure"), &failure); - - if (Z_TYPE(failure) == IS_TRUE) { - result = error_str; - } - - add_next_index_zval(errors, &error); - } - - return result; -} - -static void throw_invalid_url_exception_during_write(zval *errors, const char *component) -{ - zend_string *reason = fill_errors(errors); - zend_object *exception = zend_throw_exception_ex( - uri_whatwg_invalid_url_exception_ce, - 0, - "The specified %s is malformed%s%s%s", - component, - reason ? " (" : "", - reason ? ZSTR_VAL(reason) : "", - reason ? ")" : "" - ); - zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors); -} - -static lxb_status_t lexbor_serialize_callback(const lxb_char_t *data, size_t length, void *ctx) -{ - smart_str *uri_str = ctx; - - if (data != NULL && length > 0) { - smart_str_appendl(uri_str, (const char *) data, length); - } - - return LXB_STATUS_OK; -} - -static zend_result lexbor_read_scheme(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - ZEND_ASSERT(lexbor_uri->scheme.type != LXB_URL_SCHEMEL_TYPE__UNDEF); - - ZVAL_STRINGL(retval, (const char *) lexbor_uri->scheme.name.data, lexbor_uri->scheme.name.length); - - return SUCCESS; -} - -static zend_result lexbor_write_scheme(struct uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_string_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_protocol_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "scheme"); - - return FAILURE; - } - - return SUCCESS; -} - -static zend_result lexbor_read_username(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - if (lexbor_uri->username.length) { - ZVAL_STRINGL(retval, (const char *) lexbor_uri->username.data, lexbor_uri->username.length); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result lexbor_write_username(uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_string_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_username_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "username"); - - return FAILURE; - } - - return SUCCESS; -} - -static zend_result lexbor_read_password(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - if (lexbor_uri->password.length > 0) { - ZVAL_STRINGL(retval, (const char *) lexbor_uri->password.data, lexbor_uri->password.length); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result lexbor_write_password(struct uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_string_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_password_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "password"); - - return FAILURE; - } - - return SUCCESS; -} - -static zend_result init_idna(void) -{ - if (lexbor_parser.idna != NULL) { - return SUCCESS; - } - - lexbor_parser.idna = lxb_unicode_idna_create(); - - return lxb_unicode_idna_init(lexbor_parser.idna) == LXB_STATUS_OK ? SUCCESS : FAILURE; -} - -static zend_result lexbor_read_host(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - if (lexbor_uri->host.type == LXB_URL_HOST_TYPE_IPV4) { - smart_str host_str = {0}; - - lxb_url_serialize_host_ipv4(lexbor_uri->host.u.ipv4, lexbor_serialize_callback, &host_str); - - ZVAL_NEW_STR(retval, smart_str_extract(&host_str)); - } else if (lexbor_uri->host.type == LXB_URL_HOST_TYPE_IPV6) { - smart_str host_str = {0}; - - smart_str_appendc(&host_str, '['); - lxb_url_serialize_host_ipv6(lexbor_uri->host.u.ipv6, lexbor_serialize_callback, &host_str); - smart_str_appendc(&host_str, ']'); - - ZVAL_NEW_STR(retval, smart_str_extract(&host_str)); - } else if (lexbor_uri->host.type != LXB_URL_HOST_TYPE_EMPTY && lexbor_uri->host.type != LXB_URL_HOST_TYPE__UNDEF) { - switch (read_mode) { - case URI_COMPONENT_READ_NORMALIZED_UNICODE: { - smart_str host_str = {0}; - if (init_idna() == FAILURE) { - return FAILURE; - } - lxb_url_serialize_host_unicode(lexbor_parser.idna, &lexbor_uri->host, lexbor_serialize_callback, &host_str); - lxb_unicode_idna_clean(lexbor_parser.idna); - - ZVAL_NEW_STR(retval, smart_str_extract(&host_str)); - break; - } - case URI_COMPONENT_READ_NORMALIZED_ASCII: - ZEND_FALLTHROUGH; - case URI_COMPONENT_READ_RAW: - ZVAL_STRINGL(retval, (const char *) lexbor_uri->host.u.domain.data, lexbor_uri->host.u.domain.length); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result lexbor_write_host(struct uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_string_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_hostname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "host"); - - return FAILURE; - } - - return SUCCESS; -} - -static zend_result lexbor_read_port(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - if (lexbor_uri->has_port) { - ZVAL_LONG(retval, lexbor_uri->port); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result lexbor_write_port(struct uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_long_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_port_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "port"); - - return FAILURE; - } - - return SUCCESS; -} - -static zend_result lexbor_read_path(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - if (lexbor_uri->path.str.length) { - ZVAL_STRINGL(retval, (const char *) lexbor_uri->path.str.data, lexbor_uri->path.str.length); - } else { - ZVAL_EMPTY_STRING(retval); - } - - return SUCCESS; -} - -static zend_result lexbor_write_path(struct uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_string_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_pathname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "path"); - - return FAILURE; - } - - return SUCCESS; -} - -static zend_result lexbor_read_query(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - if (lexbor_uri->query.length) { - ZVAL_STRINGL(retval, (const char *) lexbor_uri->query.data, lexbor_uri->query.length); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result lexbor_write_query(struct uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_string_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_search_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "query string"); - - return FAILURE; - } - - return SUCCESS; -} - -static zend_result lexbor_read_fragment(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - - if (lexbor_uri->fragment.length) { - ZVAL_STRINGL(retval, (const char *) lexbor_uri->fragment.data, lexbor_uri->fragment.length); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result lexbor_write_fragment(struct uri_internal_t *internal_uri, zval *value, zval *errors) -{ - lxb_url_t *lexbor_uri = internal_uri->uri; - lexbor_str_t str = {0}; - - zval_string_or_null_to_lexbor_str(value, &str); - - if (lxb_url_api_hash_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) { - throw_invalid_url_exception_during_write(errors, "fragment"); - - return FAILURE; - } - - return SUCCESS; -} - -zend_result lexbor_request_init(void) -{ - lexbor_mraw_t *mraw = lexbor_mraw_create(); - lxb_status_t status = lexbor_mraw_init(mraw, LEXBOR_MRAW_BYTE_SIZE); - if (status != LXB_STATUS_OK) { - lexbor_mraw_destroy(mraw, true); - return FAILURE; - } - - status = lxb_url_parser_init(&lexbor_parser, mraw); - if (status != LXB_STATUS_OK) { - lxb_url_parser_destroy(&lexbor_parser, false); - lexbor_mraw_destroy(mraw, true); - return FAILURE; - } - - lexbor_urls = 0; - - return SUCCESS; -} - -void lexbor_request_shutdown(void) -{ - lxb_url_parser_memory_destroy(&lexbor_parser); - lxb_url_parser_destroy(&lexbor_parser, false); - - lexbor_urls = 0; -} - -lxb_url_t *lexbor_parse_uri_ex(const zend_string *uri_str, const lxb_url_t *lexbor_base_url, zval *errors, bool silent) -{ - lexbor_cleanup_parser(); - - lxb_url_t *url = lxb_url_parse(&lexbor_parser, lexbor_base_url, (unsigned char *) ZSTR_VAL(uri_str), ZSTR_LEN(uri_str)); - zend_string *reason = fill_errors(errors); - - if (url == NULL && !silent) { - zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? ZSTR_VAL(reason) : "", reason ? ")" : ""); - zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors); - } - - return url; -} - -static void *lexbor_parse_uri(const zend_string *uri_str, const void *base_url, zval *errors, bool silent) -{ - return lexbor_parse_uri_ex(uri_str, base_url, errors, silent); -} - -static void *lexbor_clone_uri(void *uri) -{ - lxb_url_t *lexbor_uri = (lxb_url_t *) uri; - - return lxb_url_clone(lexbor_parser.mraw, lexbor_uri); -} - -static zend_string *lexbor_uri_to_string(void *uri, uri_recomposition_mode_t recomposition_mode, bool exclude_fragment) -{ - lxb_url_t *lexbor_uri = (lxb_url_t *) uri; - smart_str uri_str = {0}; - - switch (recomposition_mode) { - case URI_RECOMPOSITION_RAW_UNICODE: - ZEND_FALLTHROUGH; - case URI_RECOMPOSITION_NORMALIZED_UNICODE: - if (init_idna() == FAILURE) { - return NULL; - } - lxb_url_serialize_idna(lexbor_parser.idna, lexbor_uri, lexbor_serialize_callback, &uri_str, exclude_fragment); - lxb_unicode_idna_clean(lexbor_parser.idna); - break; - case URI_RECOMPOSITION_RAW_ASCII: - ZEND_FALLTHROUGH; - case URI_RECOMPOSITION_NORMALIZED_ASCII: - lxb_url_serialize(lexbor_uri, lexbor_serialize_callback, &uri_str, exclude_fragment); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - - return smart_str_extract(&uri_str); -} - -static void lexbor_free_uri(void *uri) -{ -} - -const uri_handler_t lexbor_uri_handler = { - .name = URI_PARSER_WHATWG, - .parse_uri = lexbor_parse_uri, - .clone_uri = lexbor_clone_uri, - .uri_to_string = lexbor_uri_to_string, - .free_uri = lexbor_free_uri, - { - .scheme = {.read_func = lexbor_read_scheme, .write_func = lexbor_write_scheme}, - .username = {.read_func = lexbor_read_username, .write_func = lexbor_write_username}, - .password = {.read_func = lexbor_read_password, .write_func = lexbor_write_password}, - .host = {.read_func = lexbor_read_host, .write_func = lexbor_write_host}, - .port = {.read_func = lexbor_read_port, .write_func = lexbor_write_port}, - .path = {.read_func = lexbor_read_path, .write_func = lexbor_write_path}, - .query = {.read_func = lexbor_read_query, .write_func = lexbor_write_query}, - .fragment = {.read_func = lexbor_read_fragment, .write_func = lexbor_write_fragment}, - } -}; diff --git a/ext/uri/php_lexbor.h b/ext/uri/php_lexbor.h deleted file mode 100644 index 30d68b5cdf68..000000000000 --- a/ext/uri/php_lexbor.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Máté Kocsis | - +----------------------------------------------------------------------+ -*/ - -#ifndef PHP_LEXBOR_H -#define PHP_LEXBOR_H - -#include "php_uri_common.h" -#include "lexbor/url/url.h" - -extern const uri_handler_t lexbor_uri_handler; - -lxb_url_t *lexbor_parse_uri_ex(const zend_string *uri_str, const lxb_url_t *lexbor_base_url, zval *errors, bool silent); - -zend_result lexbor_request_init(void); -void lexbor_request_shutdown(void); - -#endif diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 5b2e21b1625a..58f34a370151 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -26,143 +24,267 @@ #include "ext/standard/info.h" #include "php_uri.h" -#include "php_uri_common.h" -#include "php_lexbor.h" +#include "uri_parser_whatwg.h" +#include "uri_parser_rfc3986.h" +#include "uri_parser_php_parse_url.h" #include "php_uri_arginfo.h" -#include "uriparser/src/UriConfig.h" - -zend_class_entry *uri_whatwg_url_ce; -zend_object_handlers uri_whatwg_uri_object_handlers; -zend_class_entry *uri_comparison_mode_ce; -zend_class_entry *uri_exception_ce; -zend_class_entry *uri_invalid_uri_exception_ce; -zend_class_entry *uri_whatwg_invalid_url_exception_ce; -zend_class_entry *uri_whatwg_url_validation_error_type_ce; -zend_class_entry *uri_whatwg_url_validation_error_ce; - -#define URIPARSER_VERSION PACKAGE_VERSION +#include "uriparser/Uri.h" + +zend_class_entry *php_uri_ce_rfc3986_uri; +zend_class_entry *php_uri_ce_rfc3986_uri_type; +zend_class_entry *php_uri_ce_rfc3986_uri_host_type; +zend_class_entry *php_uri_ce_whatwg_url; +zend_class_entry *php_uri_ce_comparison_mode; +zend_class_entry *php_uri_ce_exception; +zend_class_entry *php_uri_ce_error; +zend_class_entry *php_uri_ce_invalid_uri_exception; +zend_class_entry *php_uri_ce_whatwg_url_host_type; +zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; +zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; +zend_class_entry *php_uri_ce_whatwg_url_validation_error; + +static zend_object_handlers object_handlers_rfc3986_uri; +static zend_object_handlers object_handlers_whatwg_uri; static const zend_module_dep uri_deps[] = { ZEND_MOD_REQUIRED("lexbor") ZEND_MOD_END }; -static zend_array uri_handlers; +static zend_array uri_parsers; -static uri_handler_t *uri_handler_by_name(const char *handler_name, size_t handler_name_len) +static HashTable *uri_get_debug_properties(php_uri_object *object) { - return zend_hash_str_find_ptr(&uri_handlers, handler_name, handler_name_len); -} - -static HashTable *uri_get_debug_properties(zend_object *object) -{ - uri_internal_t *internal_uri = uri_internal_from_obj(object); - ZEND_ASSERT(internal_uri != NULL); - - HashTable *std_properties = zend_std_get_properties(object); + const HashTable *std_properties = zend_std_get_properties(&object->std); HashTable *result = zend_array_dup(std_properties); - if (UNEXPECTED(internal_uri->uri == NULL)) { + const php_uri_parser * const parser = object->parser; + void * const uri = object->uri; + + if (UNEXPECTED(uri == NULL)) { return result; } - const uri_property_handlers_t property_handlers = internal_uri->handler->property_handlers; - zval tmp; - if (property_handlers.scheme.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.scheme.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_SCHEME), &tmp); } - if (property_handlers.username.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.username.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_USERNAME), &tmp); } - if (property_handlers.password.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.password.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_PASSWORD), &tmp); } - if (property_handlers.host.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.host.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_HOST), &tmp); } - if (property_handlers.port.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.port.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_PORT), &tmp); } - if (property_handlers.path.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.path.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_PATH), &tmp); } - if (property_handlers.query.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.query.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_QUERY), &tmp); } - if (property_handlers.fragment.read_func(internal_uri, URI_COMPONENT_READ_RAW, &tmp) == SUCCESS) { + if (parser->property_handler.fragment.read(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &tmp) == SUCCESS) { zend_hash_update(result, ZSTR_KNOWN(ZEND_STR_FRAGMENT), &tmp); } return result; } -PHP_METHOD(Uri_WhatWg_InvalidUrlException, __construct) +PHPAPI const php_uri_parser *php_uri_get_parser(zend_string *uri_parser_name) { - zend_string *message = NULL; - zval *errors = NULL; - zend_long code = 0; - zval *previous = NULL; + if (uri_parser_name == NULL) { + return zend_hash_str_find_ptr(&uri_parsers, PHP_URI_PARSER_PHP_PARSE_URL, sizeof(PHP_URI_PARSER_PHP_PARSE_URL) - 1); + } - ZEND_PARSE_PARAMETERS_START(0, 4) - Z_PARAM_OPTIONAL - Z_PARAM_STR(message) - Z_PARAM_ARRAY(errors) - Z_PARAM_LONG(code) - Z_PARAM_OBJECT_OF_CLASS_OR_NULL(previous, zend_ce_throwable) - ZEND_PARSE_PARAMETERS_END(); + return zend_hash_find_ptr(&uri_parsers, uri_parser_name); +} - if (zend_update_exception_properties(INTERNAL_FUNCTION_PARAM_PASSTHRU, message, code, previous) == FAILURE) { - RETURN_THROWS(); - } +ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri_internal *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent) +{ + void *uri = uri_parser->parse(uri_str, uri_str_len, NULL, NULL, silent); - if (errors == NULL) { - zval tmp; - ZVAL_EMPTY_ARRAY(&tmp); - zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), &tmp); - } else { - zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), errors); - } - if (EG(exception)) { - RETURN_THROWS(); + if (uri == NULL) { + return NULL; } + + php_uri_internal *internal_uri = emalloc(sizeof(*internal_uri)); + internal_uri->parser = uri_parser; + internal_uri->uri = uri; + + return internal_uri; } -PHP_METHOD(Uri_WhatWg_UrlValidationError, __construct) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { - zend_string *context; - zval *type; - bool failure; + return internal_uri->parser->property_handler.scheme.read(internal_uri->uri, read_mode, zv); +} - ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_STR(context) - Z_PARAM_OBJECT_OF_CLASS(type, uri_whatwg_url_validation_error_type_ce) - Z_PARAM_BOOL(failure) - ZEND_PARSE_PARAMETERS_END(); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_username(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +{ + return internal_uri->parser->property_handler.username.read(internal_uri->uri, read_mode, zv); +} - zend_update_property_str(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("context"), context); - if (EG(exception)) { - RETURN_THROWS(); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_password(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +{ + return internal_uri->parser->property_handler.password.read(internal_uri->uri, read_mode, zv); +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_host(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +{ + return internal_uri->parser->property_handler.host.read(internal_uri->uri, read_mode, zv); +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_port(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +{ + return internal_uri->parser->property_handler.port.read(internal_uri->uri, read_mode, zv); +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_path(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +{ + return internal_uri->parser->property_handler.path.read(internal_uri->uri, read_mode, zv); +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +{ + return internal_uri->parser->property_handler.query.read(internal_uri->uri, read_mode, zv); +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +{ + return internal_uri->parser->property_handler.fragment.read(internal_uri->uri, read_mode, zv); +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(php_uri_internal *internal_uri) +{ + internal_uri->parser->destroy(internal_uri->uri); + internal_uri->uri = NULL; + internal_uri->parser = NULL; + efree(internal_uri); +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri *php_uri_parse_to_struct( + const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, php_uri_component_read_mode read_mode, bool silent +) { + php_uri_internal *uri_internal = php_uri_parse(uri_parser, uri_str, uri_str_len, silent); + if (uri_internal == NULL) { + return NULL; } - zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_TYPE), type); - if (EG(exception)) { - RETURN_THROWS(); + php_uri *uri = ecalloc(1, sizeof(*uri)); + zval tmp; + zend_result result; + + result = php_uri_get_scheme(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_STRING) { + uri->scheme = Z_STR(tmp); } - zval failure_zv; - ZVAL_BOOL(&failure_zv, failure); - zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("failure"), &failure_zv); - if (EG(exception)) { - RETURN_THROWS(); + result = php_uri_get_username(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_STRING) { + uri->user = Z_STR(tmp); + } + + result = php_uri_get_password(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_STRING) { + uri->password = Z_STR(tmp); + } + + result = php_uri_get_host(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_STRING) { + uri->host = Z_STR(tmp); + } + + result = php_uri_get_port(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_LONG) { + uri->port = Z_LVAL(tmp); + } + + result = php_uri_get_path(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_STRING) { + uri->path = Z_STR(tmp); + } + + result = php_uri_get_query(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_STRING) { + uri->query = Z_STR(tmp); + } + + result = php_uri_get_fragment(uri_internal, read_mode, &tmp); + if (result == FAILURE) { + goto error; + } + if (Z_TYPE(tmp) == IS_STRING) { + uri->fragment = Z_STR(tmp); + } + + php_uri_free(uri_internal); + + return uri; + +error: + php_uri_free(uri_internal); + php_uri_struct_free(uri); + + return NULL; +} + +ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_struct_free(php_uri *uri) +{ + if (uri->scheme) { + zend_string_release(uri->scheme); + } + if (uri->user) { + zend_string_release(uri->user); + } + if (uri->password) { + zend_string_release(uri->password); + } + if (uri->host) { + zend_string_release(uri->host); } + if (uri->path) { + zend_string_release(uri->path); + } + if (uri->query) { + zend_string_release(uri->query); + } + if (uri->fragment) { + zend_string_release(uri->fragment); + } + + efree(uri); } /** @@ -186,30 +308,49 @@ static zend_result pass_errors_by_ref_and_free(zval *errors_zv, zval *errors) return SUCCESS; } - ZEND_TRY_ASSIGN_REF_ARR(errors_zv, Z_ARRVAL_P(errors)); + ZEND_TRY_ASSIGN_REF_TMP(errors_zv, errors); if (EG(exception)) { - zval_ptr_dtor(errors); return FAILURE; } return SUCCESS; } -PHPAPI void php_uri_instantiate_uri( - INTERNAL_FUNCTION_PARAMETERS, const uri_handler_t *handler, const zend_string *uri_str, const zend_object *base_url_object, - bool should_throw, bool should_update_this_object, zval *errors_zv +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri( + INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const php_uri_object *base_url_object, + bool should_throw, bool should_update_this_object, zval *errors_zv ) { + + php_uri_object *uri_object; + if (should_update_this_object) { + uri_object = Z_URI_OBJECT_P(ZEND_THIS); + if (uri_object->uri != NULL) { + zend_throw_error(NULL, "Cannot modify readonly object of class %s", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)); + RETURN_THROWS(); + } + } else { + if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) { + object_init_ex(return_value, Z_CE_P(ZEND_THIS)); + } else { + object_init_ex(return_value, Z_OBJCE_P(ZEND_THIS)); + } + uri_object = Z_URI_OBJECT_P(return_value); + } + + const php_uri_parser *uri_parser = uri_object->parser; + zval errors; ZVAL_UNDEF(&errors); void *base_url = NULL; if (base_url_object != NULL) { - uri_internal_t *internal_base_url = uri_internal_from_obj(base_url_object); - URI_ASSERT_INITIALIZATION(internal_base_url); - base_url = internal_base_url->uri; + ZEND_ASSERT(base_url_object->std.ce == uri_object->std.ce); + ZEND_ASSERT(base_url_object->uri != NULL); + ZEND_ASSERT(base_url_object->parser == uri_parser); + base_url = base_url_object->uri; } - void *uri = handler->parse_uri(uri_str, base_url, should_throw || errors_zv != NULL ? &errors : NULL, !should_throw); + void *uri = uri_parser->parse(ZSTR_VAL(uri_str), ZSTR_LEN(uri_str), base_url, errors_zv != NULL ? &errors : NULL, !should_throw); if (UNEXPECTED(uri == NULL)) { if (should_throw) { zval_ptr_dtor(&errors); @@ -218,28 +359,129 @@ PHPAPI void php_uri_instantiate_uri( if (pass_errors_by_ref_and_free(errors_zv, &errors) == FAILURE) { RETURN_THROWS(); } + zval_ptr_dtor(return_value); RETURN_NULL(); } } if (pass_errors_by_ref_and_free(errors_zv, &errors) == FAILURE) { + uri_parser->destroy(uri); RETURN_THROWS(); } - uri_object_t *uri_object; - if (should_update_this_object) { - uri_object = Z_URI_OBJECT_P(ZEND_THIS); + uri_object->uri = uri; +} + +static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) +{ + zend_string *uri_str; + zend_object *base_url_object = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(uri_str) + Z_PARAM_OPTIONAL + Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, php_uri_ce_rfc3986_uri) + ZEND_PARSE_PARAMETERS_END(); + + php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, + uri_str, base_url_object ? php_uri_object_from_obj(base_url_object) : NULL, is_constructor, is_constructor, NULL); +} + +static bool is_list_of_whatwg_validation_errors(const HashTable *array) +{ + if (!zend_array_is_list(array)) { + return false; + } + + ZEND_HASH_FOREACH_VAL(array, zval *val) { + /* Do not allow references as they may change types after checking. */ + + if (Z_TYPE_P(val) != IS_OBJECT) { + return false; + } + + if (!instanceof_function(Z_OBJCE_P(val), php_uri_ce_whatwg_url_validation_error)) { + return false; + } + } ZEND_HASH_FOREACH_END(); + + return true; +} + +PHP_METHOD(Uri_Rfc3986_Uri, parse) +{ + create_rfc3986_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, false); +} + +PHP_METHOD(Uri_Rfc3986_Uri, __construct) +{ + create_rfc3986_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); +} + +PHP_METHOD(Uri_WhatWg_InvalidUrlException, __construct) +{ + zend_string *message = NULL; + zval *errors = NULL; + zend_long code = 0; + zval *previous = NULL; + + ZEND_PARSE_PARAMETERS_START(0, 4) + Z_PARAM_OPTIONAL + Z_PARAM_STR(message) + Z_PARAM_ARRAY(errors) + Z_PARAM_LONG(code) + Z_PARAM_OBJECT_OF_CLASS_OR_NULL(previous, zend_ce_throwable) + ZEND_PARSE_PARAMETERS_END(); + + if (zend_update_exception_properties(INTERNAL_FUNCTION_PARAM_PASSTHRU, message, code, previous) == FAILURE) { + RETURN_THROWS(); + } + + if (errors == NULL) { + zval tmp; + ZVAL_EMPTY_ARRAY(&tmp); + zend_update_property(php_uri_ce_whatwg_invalid_url_exception, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), &tmp); } else { - if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) { - object_init_ex(return_value, Z_CE_P(ZEND_THIS)); - } else { - object_init_ex(return_value, Z_OBJCE_P(ZEND_THIS)); + if (!is_list_of_whatwg_validation_errors(Z_ARR_P(errors))) { + zend_argument_value_error(2, "must be a list of %s", ZSTR_VAL(php_uri_ce_whatwg_url_validation_error->name)); + RETURN_THROWS(); } - uri_object = Z_URI_OBJECT_P(return_value); + + zend_update_property(php_uri_ce_whatwg_invalid_url_exception, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), errors); } + if (EG(exception)) { + RETURN_THROWS(); + } +} - uri_object->internal.handler = handler; - uri_object->internal.uri = uri; +PHP_METHOD(Uri_WhatWg_UrlValidationError, __construct) +{ + zend_string *context; + zval *type; + bool failure; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_STR(context) + Z_PARAM_OBJECT_OF_CLASS(type, php_uri_ce_whatwg_url_validation_error_type) + Z_PARAM_BOOL(failure) + ZEND_PARSE_PARAMETERS_END(); + + zend_update_property_str(php_uri_ce_whatwg_url_validation_error, Z_OBJ_P(ZEND_THIS), ZEND_STRL("context"), context); + if (EG(exception)) { + RETURN_THROWS(); + } + + zend_update_property_ex(php_uri_ce_whatwg_url_validation_error, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_TYPE), type); + if (EG(exception)) { + RETURN_THROWS(); + } + + zval failure_zv; + ZVAL_BOOL(&failure_zv, failure); + zend_update_property(php_uri_ce_whatwg_url_validation_error, Z_OBJ_P(ZEND_THIS), ZEND_STRL("failure"), &failure_zv); + if (EG(exception)) { + RETURN_THROWS(); + } } static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) @@ -249,13 +491,14 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) zval *errors = NULL; ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_PATH_STR(uri_str) + Z_PARAM_STR(uri_str) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, uri_whatwg_url_ce) + Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, php_uri_ce_whatwg_url) Z_PARAM_ZVAL(errors) ZEND_PARSE_PARAMETERS_END(); - php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &lexbor_uri_handler, uri_str, base_url_object, is_constructor, is_constructor, errors); + php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, + uri_str, base_url_object ? php_uri_object_from_obj(base_url_object) : NULL, is_constructor, is_constructor, errors); } PHP_METHOD(Uri_WhatWg_Url, parse) @@ -268,40 +511,221 @@ PHP_METHOD(Uri_WhatWg_Url, __construct) create_whatwg_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } -static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, zend_object *comparison_mode) +PHP_METHOD(Uri_Rfc3986_Uri, getUriType) { - zend_object *this_object = Z_OBJ_P(ZEND_THIS); - uri_internal_t *this_internal_uri = uri_internal_from_obj(this_object); - URI_ASSERT_INITIALIZATION(this_internal_uri); + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); - uri_internal_t *that_internal_uri = uri_internal_from_obj(that_object); - URI_ASSERT_INITIALIZATION(that_internal_uri); + php_uri_parser_rfc3986_uri_type_read(uri_object->uri, return_value); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getScheme) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawScheme) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, withScheme) +{ + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); +} + +static void rfc3986_userinfo_read(INTERNAL_FUNCTION_PARAMETERS, php_uri_component_read_mode read_mode) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + if (UNEXPECTED(php_uri_parser_rfc3986_userinfo_read(uri_object->uri, read_mode, return_value) == FAILURE)) { + zend_throw_error(NULL, "The userinfo component cannot be retrieved"); + RETURN_THROWS(); + } +} + +PHP_METHOD(Uri_Rfc3986_Uri, getUserInfo) +{ + rfc3986_userinfo_read(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawUserInfo) +{ + rfc3986_userinfo_read(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, withUserInfo) +{ + zend_string *value; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR_OR_NULL(value) + ZEND_PARSE_PARAMETERS_END(); + + zval zv; + if (value == NULL) { + ZVAL_NULL(&zv); + } else { + ZVAL_STR(&zv, value); + } + + php_uri_object *old_uri_object = php_uri_object_from_obj(Z_OBJ_P(ZEND_THIS)); + ZEND_ASSERT(old_uri_object->uri != NULL); + + zend_object *new_object = old_uri_object->std.handlers->clone_obj(&old_uri_object->std); + if (new_object == NULL) { + RETURN_THROWS(); + } + + /* Assign the object early. The engine will take care of destruction in + * case of an exception being thrown. */ + RETVAL_OBJ(new_object); + + php_uri_object *new_uri_object = php_uri_object_from_obj(new_object); + ZEND_ASSERT(new_uri_object->uri != NULL); + + if (UNEXPECTED(php_uri_parser_rfc3986_userinfo_write(new_uri_object->uri, &zv, NULL) == FAILURE)) { + RETURN_THROWS(); + } +} + +PHP_METHOD(Uri_Rfc3986_Uri, getUsername) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawUsername) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getPassword) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawPassword) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getHost) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawHost) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getHostType) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + php_uri_parser_rfc3986_host_type_read(uri_object->uri, return_value); +} + +PHP_METHOD(Uri_Rfc3986_Uri, withHost) +{ + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST); +} - if (this_object->ce != that_object->ce && - !instanceof_function(this_object->ce, that_object->ce) && - !instanceof_function(that_object->ce, this_object->ce) +PHP_METHOD(Uri_Rfc3986_Uri, getPort) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PORT, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, withPort) +{ + php_uri_property_write_long_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PORT); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getPath) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawPath) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, withPath) +{ + php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getQuery) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawQuery) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, withQuery) +{ + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getFragment) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); +} + +PHP_METHOD(Uri_Rfc3986_Uri, getRawFragment) +{ + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_RAW); +} + +PHP_METHOD(Uri_Rfc3986_Uri, withFragment) +{ + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT); +} + +static void throw_cannot_recompose_uri_to_string(php_uri_object *object) +{ + zend_throw_exception_ex(php_uri_ce_error, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->std.ce->name)); +} + +static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, php_uri_object *that_object, zend_enum_Uri_UriComparisonMode comparison_mode) +{ + php_uri_object *this_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(this_object->uri != NULL); + ZEND_ASSERT(that_object->uri != NULL); + + if (this_object->std.ce != that_object->std.ce && + !instanceof_function(this_object->std.ce, that_object->std.ce) && + !instanceof_function(that_object->std.ce, this_object->std.ce) ) { RETURN_FALSE; } - bool exclude_fragment = true; - if (comparison_mode) { - zval *case_name = zend_enum_fetch_case_name(comparison_mode); - exclude_fragment = zend_string_equals_literal(Z_STR_P(case_name), "ExcludeFragment"); - } + bool exclude_fragment = comparison_mode == ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment; - zend_string *this_str = this_internal_uri->handler->uri_to_string( - this_internal_uri->uri, URI_RECOMPOSITION_NORMALIZED_ASCII, exclude_fragment); + zend_string *this_str = this_object->parser->to_string( + this_object->uri, PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII, exclude_fragment); if (this_str == NULL) { - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to string", ZSTR_VAL(this_object->ce->name)); + throw_cannot_recompose_uri_to_string(this_object); RETURN_THROWS(); } - zend_string *that_str = that_internal_uri->handler->uri_to_string( - that_internal_uri->uri, URI_RECOMPOSITION_NORMALIZED_ASCII, exclude_fragment); + zend_string *that_str = that_object->parser->to_string( + that_object->uri, PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII, exclude_fragment); if (that_str == NULL) { zend_string_release(this_str); - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to string", ZSTR_VAL(that_object->ce->name)); + throw_cannot_recompose_uri_to_string(that_object); RETURN_THROWS(); } @@ -311,7 +735,93 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, z zend_string_release(that_str); } -static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *handler_name) +PHP_METHOD(Uri_Rfc3986_Uri, equals) +{ + zend_object *that_object; + zend_enum_Uri_UriComparisonMode comparison_mode = ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJ_OF_CLASS(that_object, php_uri_ce_rfc3986_uri) + Z_PARAM_OPTIONAL + Z_PARAM_ENUM(comparison_mode, php_uri_ce_comparison_mode) + ZEND_PARSE_PARAMETERS_END(); + + uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_uri_object_from_obj(that_object), comparison_mode); +} + +PHP_METHOD(Uri_Rfc3986_Uri, toRawString) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + zend_string *uri_str = uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, false); + if (uri_str == NULL) { + throw_cannot_recompose_uri_to_string(uri_object); + RETURN_THROWS(); + } + + RETURN_STR(uri_str); +} + +PHP_METHOD(Uri_Rfc3986_Uri, toString) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + zend_string *uri_str = uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII, false); + if (uri_str == NULL) { + throw_cannot_recompose_uri_to_string(uri_object); + RETURN_THROWS(); + } + + RETURN_STR(uri_str); +} + +PHP_METHOD(Uri_Rfc3986_Uri, resolve) +{ + zend_string *uri_str; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(uri_str) + ZEND_PARSE_PARAMETERS_END(); + + php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, + uri_str, Z_URI_OBJECT_P(ZEND_THIS), true, false, NULL); +} + +PHP_METHOD(Uri_Rfc3986_Uri, __serialize) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + /* Serialize state: "uri" key in the first array */ + zend_string *uri_str = uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, false); + if (uri_str == NULL) { + throw_cannot_recompose_uri_to_string(uri_object); + RETURN_THROWS(); + } + zval tmp; + ZVAL_STR(&tmp, uri_str); + + array_init(return_value); + + zval arr; + array_init(&arr); + zend_hash_str_add_new(Z_ARRVAL(arr), PHP_URI_SERIALIZE_URI_FIELD_NAME, sizeof(PHP_URI_SERIALIZE_URI_FIELD_NAME) - 1, &tmp); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); + + /* Serialize regular properties: second array */ + ZVAL_EMPTY_ARRAY(&arr); + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); +} + +static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS) { HashTable *data; @@ -319,155 +829,140 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *handler_na Z_PARAM_ARRAY_HT(data) ZEND_PARSE_PARAMETERS_END(); - zend_object *object = Z_OBJ_P(ZEND_THIS); + php_uri_object *uri_object = php_uri_object_from_obj(Z_OBJ_P(ZEND_THIS)); + if (uri_object->uri != NULL) { + /* Intentionally throw two exceptions for proper chaining. */ + zend_throw_error(NULL, "Cannot modify readonly object of class %s", ZSTR_VAL(uri_object->std.ce->name)); + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); + RETURN_THROWS(); + } /* Verify the expected number of elements, this implicitly ensures that no additional elements are present. */ if (zend_hash_num_elements(data) != 2) { - zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); } /* Unserialize state: "uri" key in the first array */ zval *arr = zend_hash_index_find(data, 0); if (arr == NULL || Z_TYPE_P(arr) != IS_ARRAY) { - zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); } /* Verify the expected number of elements inside the first array, this implicitly ensures that no additional elements are present. */ if (zend_hash_num_elements(Z_ARRVAL_P(arr)) != 1) { - zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); } - zval *uri_zv = zend_hash_str_find_ind(Z_ARRVAL_P(arr), ZEND_STRL(URI_SERIALIZED_PROPERTY_NAME)); + zval *uri_zv = zend_hash_str_find(Z_ARRVAL_P(arr), ZEND_STRL(PHP_URI_SERIALIZE_URI_FIELD_NAME)); if (uri_zv == NULL || Z_TYPE_P(uri_zv) != IS_STRING) { - zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); } - uri_internal_t *internal_uri = uri_internal_from_obj(object); - internal_uri->handler = uri_handler_by_name(handler_name, strlen(handler_name)); - if (internal_uri->uri != NULL) { - internal_uri->handler->free_uri(internal_uri->uri); - } - internal_uri->uri = internal_uri->handler->parse_uri(Z_STR_P(uri_zv), NULL, NULL, true); - if (internal_uri->uri == NULL) { - zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name)); + uri_object->uri = uri_object->parser->parse(Z_STRVAL_P(uri_zv), Z_STRLEN_P(uri_zv), NULL, NULL, true); + if (uri_object->uri == NULL) { + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); } /* Unserialize regular properties: second array */ arr = zend_hash_index_find(data, 1); if (arr == NULL || Z_TYPE_P(arr) != IS_ARRAY) { - zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); } /* Verify that there is no regular property in the second array, because the URI classes have no properties and they are final. */ if (zend_hash_num_elements(Z_ARRVAL_P(arr)) > 0) { - zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); } } -PHP_METHOD(Uri_WhatWg_Url, getScheme) +PHP_METHOD(Uri_Rfc3986_Uri, __unserialize) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME, URI_COMPONENT_READ_NORMALIZED_ASCII); + uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU); } -PHP_METHOD(Uri_WhatWg_Url, withScheme) +PHP_METHOD(Uri_Rfc3986_Uri, __debugInfo) { - uri_write_component_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_SCHEME); -} + ZEND_PARSE_PARAMETERS_NONE(); -PHP_METHOD(Uri_WhatWg_Url, getUsername) -{ - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_USERNAME, URI_COMPONENT_READ_NORMALIZED_ASCII); -} + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); -PHP_METHOD(Uri_WhatWg_Url, withUsername) -{ - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_USERNAME); + RETURN_ARR(uri_get_debug_properties(uri_object)); } -PHP_METHOD(Uri_WhatWg_Url, getPassword) +PHP_METHOD(Uri_WhatWg_Url, getScheme) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PASSWORD, URI_COMPONENT_READ_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } -PHP_METHOD(Uri_WhatWg_Url, withPassword) +PHP_METHOD(Uri_WhatWg_Url, withScheme) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PASSWORD); + php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); } -PHP_METHOD(Uri_WhatWg_Url, getAsciiHost) +PHP_METHOD(Uri_WhatWg_Url, isSpecialScheme) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_HOST, URI_COMPONENT_READ_NORMALIZED_ASCII); -} + ZEND_PARSE_PARAMETERS_NONE(); -PHP_METHOD(Uri_WhatWg_Url, getUnicodeHost) -{ - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_HOST, URI_COMPONENT_READ_NORMALIZED_UNICODE); -} + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); -PHP_METHOD(Uri_WhatWg_Url, withHost) -{ - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_HOST); + RETVAL_BOOL(php_uri_parser_whatwg_is_special(uri_object->uri)); } -PHP_METHOD(Uri_WhatWg_Url, getPort) +PHP_METHOD(Uri_WhatWg_Url, withUsername) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PORT, URI_COMPONENT_READ_NORMALIZED_ASCII); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME); } -PHP_METHOD(Uri_WhatWg_Url, withPort) +PHP_METHOD(Uri_WhatWg_Url, withPassword) { - uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PORT); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD); } -PHP_METHOD(Uri_WhatWg_Url, getPath) +PHP_METHOD(Uri_WhatWg_Url, getAsciiHost) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PATH, URI_COMPONENT_READ_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } -PHP_METHOD(Uri_WhatWg_Url, withPath) +PHP_METHOD(Uri_WhatWg_Url, getUnicodeHost) { - uri_write_component_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_PATH); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); } -PHP_METHOD(Uri_WhatWg_Url, getQuery) +PHP_METHOD(Uri_WhatWg_Url, getHostType) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_QUERY, URI_COMPONENT_READ_NORMALIZED_ASCII); -} + ZEND_PARSE_PARAMETERS_NONE(); -PHP_METHOD(Uri_WhatWg_Url, withQuery) -{ - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_QUERY); -} + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); -PHP_METHOD(Uri_WhatWg_Url, getFragment) -{ - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_FRAGMENT, URI_COMPONENT_READ_NORMALIZED_ASCII); + php_uri_parser_whatwg_host_type_read(uri_object->uri, return_value); } -PHP_METHOD(Uri_WhatWg_Url, withFragment) +PHP_METHOD(Uri_WhatWg_Url, getFragment) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PROPERTY_NAME_FRAGMENT); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); } PHP_METHOD(Uri_WhatWg_Url, equals) { zend_object *that_object; - zend_object *comparison_mode = NULL; + zend_enum_Uri_UriComparisonMode comparison_mode = ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJ_OF_CLASS(that_object, uri_whatwg_url_ce) + Z_PARAM_OBJ_OF_CLASS(that_object, php_uri_ce_whatwg_url) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OF_CLASS(comparison_mode, uri_comparison_mode_ce) + Z_PARAM_ENUM(comparison_mode, php_uri_ce_comparison_mode) ZEND_PARSE_PARAMETERS_END(); - uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, that_object, comparison_mode); + uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_uri_object_from_obj(that_object), comparison_mode); } PHP_METHOD(Uri_WhatWg_Url, toUnicodeString) @@ -475,10 +970,10 @@ PHP_METHOD(Uri_WhatWg_Url, toUnicodeString) ZEND_PARSE_PARAMETERS_NONE(); zend_object *this_object = Z_OBJ_P(ZEND_THIS); - uri_internal_t *internal_uri = uri_internal_from_obj(this_object); - URI_ASSERT_INITIALIZATION(internal_uri); + php_uri_object *uri_object = php_uri_object_from_obj(this_object); + ZEND_ASSERT(uri_object->uri != NULL); - RETURN_STR(internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_RAW_UNICODE, false)); + RETURN_STR(uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_UNICODE, false)); } PHP_METHOD(Uri_WhatWg_Url, toAsciiString) @@ -486,10 +981,10 @@ PHP_METHOD(Uri_WhatWg_Url, toAsciiString) ZEND_PARSE_PARAMETERS_NONE(); zend_object *this_object = Z_OBJ_P(ZEND_THIS); - uri_internal_t *internal_uri = uri_internal_from_obj(this_object); - URI_ASSERT_INITIALIZATION(internal_uri); + php_uri_object *uri_object = php_uri_object_from_obj(this_object); + ZEND_ASSERT(uri_object->uri != NULL); - RETURN_STR(internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_RAW_ASCII, false)); + RETURN_STR(uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, false)); } PHP_METHOD(Uri_WhatWg_Url, resolve) @@ -498,30 +993,26 @@ PHP_METHOD(Uri_WhatWg_Url, resolve) zval *errors = NULL; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_PATH_STR(uri_str) + Z_PARAM_STR(uri_str) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(errors) ZEND_PARSE_PARAMETERS_END(); - zend_object *this_object = Z_OBJ_P(ZEND_THIS); - uri_internal_t *internal_uri = uri_internal_from_obj(this_object); - URI_ASSERT_INITIALIZATION(internal_uri); - - php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->handler, uri_str, this_object, true, false, errors); + php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, + uri_str, Z_URI_OBJECT_P(ZEND_THIS), true, false, errors); } PHP_METHOD(Uri_WhatWg_Url, __serialize) { ZEND_PARSE_PARAMETERS_NONE(); - zend_object *this_object = Z_OBJ_P(ZEND_THIS); - uri_internal_t *internal_uri = uri_internal_from_obj(this_object); - URI_ASSERT_INITIALIZATION(internal_uri); + php_uri_object *this_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(this_object->uri != NULL); /* Serialize state: "uri" key in the first array */ - zend_string *uri_str = internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_RAW_ASCII, false); + zend_string *uri_str = this_object->parser->to_string(this_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, false); if (uri_str == NULL) { - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to string", ZSTR_VAL(this_object->ce->name)); + throw_cannot_recompose_uri_to_string(this_object); RETURN_THROWS(); } zval tmp; @@ -531,96 +1022,89 @@ PHP_METHOD(Uri_WhatWg_Url, __serialize) zval arr; array_init(&arr); - zend_hash_str_add_new(Z_ARRVAL(arr), ZEND_STRL(URI_SERIALIZED_PROPERTY_NAME), &tmp); + zend_hash_str_add_new(Z_ARRVAL(arr), ZEND_STRL(PHP_URI_SERIALIZE_URI_FIELD_NAME), &tmp); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); /* Serialize regular properties: second array */ - ZVAL_ARR(&arr, this_object->handlers->get_properties(this_object)); - Z_ADDREF(arr); + ZVAL_EMPTY_ARRAY(&arr); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); } PHP_METHOD(Uri_WhatWg_Url, __unserialize) { - uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PARSER_WHATWG); + uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU); } PHP_METHOD(Uri_WhatWg_Url, __debugInfo) { ZEND_PARSE_PARAMETERS_NONE(); - zend_object *object = Z_OBJ_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); - RETURN_ARR(uri_get_debug_properties(object)); + RETURN_ARR(uri_get_debug_properties(uri_object)); } -static zend_object *uri_create_object_handler(zend_class_entry *class_type) +PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser) { - uri_object_t *uri_object = zend_object_alloc(sizeof(uri_object_t), class_type); + php_uri_object *uri_object = zend_object_alloc(sizeof(*uri_object), class_type); zend_object_std_init(&uri_object->std, class_type); object_properties_init(&uri_object->std, class_type); - return &uri_object->std; + uri_object->parser = parser; + uri_object->uri = NULL; + + return uri_object; } -static void uri_free_obj_handler(zend_object *object) +static zend_object *php_uri_object_create_rfc3986(zend_class_entry *ce) { - uri_object_t *uri_object = uri_object_from_obj(object); + return &php_uri_object_create(ce, &php_uri_parser_rfc3986)->std; +} - if (UNEXPECTED(uri_object->internal.uri != NULL)) { - uri_object->internal.handler->free_uri(uri_object->internal.uri); - uri_object->internal.handler = NULL; - uri_object->internal.uri = NULL; - } +static zend_object *php_uri_object_create_whatwg(zend_class_entry *ce) +{ + return &php_uri_object_create(ce, &php_uri_parser_whatwg)->std; +} +PHPAPI void php_uri_object_handler_free(zend_object *object) +{ + php_uri_object *uri_object = php_uri_object_from_obj(object); + + uri_object->parser->destroy(uri_object->uri); zend_object_std_dtor(&uri_object->std); } -zend_object *uri_clone_obj_handler(zend_object *object) +PHPAPI zend_object *php_uri_object_handler_clone(zend_object *object) { - uri_object_t *uri_object = uri_object_from_obj(object); - uri_internal_t *internal_uri = uri_internal_from_obj(object); - - URI_ASSERT_INITIALIZATION(internal_uri); + const php_uri_object *uri_object = php_uri_object_from_obj(object); - zend_object *new_object = uri_create_object_handler(object->ce); - ZEND_ASSERT(new_object != NULL); - uri_object_t *new_uri_object = uri_object_from_obj(new_object); + ZEND_ASSERT(uri_object->uri != NULL); - new_uri_object->internal.handler = internal_uri->handler; + php_uri_object *new_uri_object = php_uri_object_from_obj(object->ce->create_object(object->ce)); + ZEND_ASSERT(new_uri_object->parser == uri_object->parser); - void *uri = internal_uri->handler->clone_uri(internal_uri->uri); + void *uri = uri_object->parser->clone(uri_object->uri); ZEND_ASSERT(uri != NULL); - new_uri_object->internal.uri = uri; + new_uri_object->uri = uri; zend_objects_clone_members(&new_uri_object->std, &uri_object->std); return &new_uri_object->std; } -PHPAPI void php_uri_implementation_set_object_handlers(zend_class_entry *ce, zend_object_handlers *object_handlers) +PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser) { - ce->create_object = uri_create_object_handler; - ce->default_object_handlers = object_handlers; - memcpy(object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); - object_handlers->offset = XtOffsetOf(uri_object_t, std); - object_handlers->free_obj = uri_free_obj_handler; - object_handlers->clone_obj = uri_clone_obj_handler; -} + zend_string *key = zend_string_init_interned(uri_parser->name, strlen(uri_parser->name), true); -zend_result uri_handler_register(const uri_handler_t *uri_handler) -{ - zend_string *key = zend_string_init_interned(uri_handler->name, strlen(uri_handler->name), 1); + ZEND_ASSERT(uri_parser->name != NULL); + ZEND_ASSERT(uri_parser->parse != NULL); + ZEND_ASSERT(uri_parser->clone != NULL || strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0); + ZEND_ASSERT(uri_parser->to_string != NULL || strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0); + ZEND_ASSERT(uri_parser->destroy != NULL); - ZEND_ASSERT(uri_handler->name != NULL); - ZEND_ASSERT(uri_handler->parse_uri != NULL); - ZEND_ASSERT(uri_handler->clone_uri != NULL); - ZEND_ASSERT(uri_handler->uri_to_string != NULL); - ZEND_ASSERT(uri_handler->free_uri != NULL); - - zend_result result = zend_hash_add_ptr(&uri_handlers, key, (void *) uri_handler) != NULL ? SUCCESS : FAILURE; + zend_result result = zend_hash_add_ptr(&uri_parsers, key, (void *) uri_parser) != NULL ? SUCCESS : FAILURE; zend_string_release_ex(key, true); @@ -629,19 +1113,45 @@ zend_result uri_handler_register(const uri_handler_t *uri_handler) static PHP_MINIT_FUNCTION(uri) { - uri_whatwg_url_ce = register_class_Uri_WhatWg_Url(); - php_uri_implementation_set_object_handlers(uri_whatwg_url_ce, &uri_whatwg_uri_object_handlers); - - uri_comparison_mode_ce = register_class_Uri_UriComparisonMode(); - uri_exception_ce = register_class_Uri_UriException(zend_ce_exception); - uri_invalid_uri_exception_ce = register_class_Uri_InvalidUriException(uri_exception_ce); - uri_whatwg_invalid_url_exception_ce = register_class_Uri_WhatWg_InvalidUrlException(uri_invalid_uri_exception_ce); - uri_whatwg_url_validation_error_ce = register_class_Uri_WhatWg_UrlValidationError(); - uri_whatwg_url_validation_error_type_ce = register_class_Uri_WhatWg_UrlValidationErrorType(); + php_uri_ce_rfc3986_uri = register_class_Uri_Rfc3986_Uri(); + php_uri_ce_rfc3986_uri->create_object = php_uri_object_create_rfc3986; + php_uri_ce_rfc3986_uri->default_object_handlers = &object_handlers_rfc3986_uri; + memcpy(&object_handlers_rfc3986_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + object_handlers_rfc3986_uri.offset = offsetof(php_uri_object, std); + object_handlers_rfc3986_uri.free_obj = php_uri_object_handler_free; + object_handlers_rfc3986_uri.clone_obj = php_uri_object_handler_clone; + + php_uri_ce_rfc3986_uri_type = register_class_Uri_Rfc3986_UriType(); + php_uri_ce_rfc3986_uri_host_type = register_class_Uri_Rfc3986_UriHostType(); + + php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url(); + php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg; + php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri; + memcpy(&object_handlers_whatwg_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + object_handlers_whatwg_uri.offset = offsetof(php_uri_object, std); + object_handlers_whatwg_uri.free_obj = php_uri_object_handler_free; + object_handlers_whatwg_uri.clone_obj = php_uri_object_handler_clone; + + php_uri_ce_comparison_mode = register_class_Uri_UriComparisonMode(); + php_uri_ce_exception = register_class_Uri_UriException(zend_ce_exception); + php_uri_ce_error = register_class_Uri_UriError(zend_ce_error); + php_uri_ce_invalid_uri_exception = register_class_Uri_InvalidUriException(php_uri_ce_exception); + php_uri_ce_whatwg_invalid_url_exception = register_class_Uri_WhatWg_InvalidUrlException(php_uri_ce_invalid_uri_exception); + php_uri_ce_whatwg_url_host_type = register_class_Uri_WhatWg_UrlHostType(); + php_uri_ce_whatwg_url_validation_error = register_class_Uri_WhatWg_UrlValidationError(); + php_uri_ce_whatwg_url_validation_error_type = register_class_Uri_WhatWg_UrlValidationErrorType(); + + zend_hash_init(&uri_parsers, 4, NULL, NULL, true); + + if (php_uri_parser_register(&php_uri_parser_rfc3986) == FAILURE) { + return FAILURE; + } - zend_hash_init(&uri_handlers, 4, NULL, NULL, true); + if (php_uri_parser_register(&php_uri_parser_whatwg) == FAILURE) { + return FAILURE; + } - if (uri_handler_register(&lexbor_uri_handler) == FAILURE) { + if (php_uri_parser_register(&php_uri_parser_php_parse_url) == FAILURE) { return FAILURE; } @@ -651,30 +1161,37 @@ static PHP_MINIT_FUNCTION(uri) static PHP_MINFO_FUNCTION(uri) { php_info_print_table_start(); - php_info_print_table_row(2, "uri support", "active"); - php_info_print_table_row(2, "uriparser library version", URIPARSER_VERSION); + php_info_print_table_row(2, "URI support", "active"); +#ifdef URI_STATIC_BUILD + php_info_print_table_row(2, "uriparser bundled version", URI_VER_ANSI); +#else + php_info_print_table_row(2, "uriparser compiled version", URI_VER_ANSI); + php_info_print_table_row(2, "uriparser loaded version", uriBaseRuntimeVersionA()); +#endif php_info_print_table_end(); } static PHP_MSHUTDOWN_FUNCTION(uri) { - zend_hash_destroy(&uri_handlers); + zend_hash_destroy(&uri_parsers); return SUCCESS; } PHP_RINIT_FUNCTION(uri) { - if (lexbor_request_init() == FAILURE) { + if (PHP_RINIT(uri_parser_whatwg)(INIT_FUNC_ARGS_PASSTHRU) == FAILURE) { return FAILURE; } return SUCCESS; } -PHP_RSHUTDOWN_FUNCTION(uri) +ZEND_MODULE_POST_ZEND_DEACTIVATE_D(uri) { - lexbor_request_shutdown(); + if (ZEND_MODULE_POST_ZEND_DEACTIVATE_N(uri_parser_whatwg)() == FAILURE) { + return FAILURE; + } return SUCCESS; } @@ -687,8 +1204,10 @@ zend_module_entry uri_module_entry = { PHP_MINIT(uri), /* PHP_MINIT - Module initialization */ PHP_MSHUTDOWN(uri), /* PHP_MSHUTDOWN - Module shutdown */ PHP_RINIT(uri), /* PHP_RINIT - Request initialization */ - PHP_RSHUTDOWN(uri), /* PHP_RSHUTDOWN - Request shutdown */ + NULL, /* PHP_RSHUTDOWN - Request shutdown */ PHP_MINFO(uri), /* PHP_MINFO - Module info */ PHP_VERSION, /* Version */ - STANDARD_MODULE_PROPERTIES + NO_MODULE_GLOBALS, + ZEND_MODULE_POST_ZEND_DEACTIVATE_N(uri), + STANDARD_MODULE_PROPERTIES_EX }; diff --git a/ext/uri/php_uri.h b/ext/uri/php_uri.h index 9e22c227cbf8..2c8516585c0f 100644 --- a/ext/uri/php_uri.h +++ b/ext/uri/php_uri.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -22,6 +20,193 @@ extern zend_module_entry uri_module_entry; #define phpext_uri_ptr &uri_module_entry -PHPAPI void php_uri_implementation_set_object_handlers(zend_class_entry *ce, zend_object_handlers *object_handlers); +typedef struct php_uri { + zend_string *scheme; + zend_string *user; + zend_string *password; + zend_string *host; + /* port is a zend_long to match the userland port getter, which + * returns the port in zval. */ + zend_long port; + zend_string *path; + zend_string *query; + zend_string *fragment; +} php_uri; + +/** + * Registers a URI parser. The parser must have a unique name. + * + * @param uri_parser The URI parser + * @return SUCCESS in case of success, FAILURE otherwise + */ +PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser); + +/** + * Returns the registered URI parser based on uri_parser_name. + * + * @param uri_parser_name The URI parser name + * @return The URI parser + */ +PHPAPI const php_uri_parser *php_uri_get_parser(zend_string *uri_parser_name); + +ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri_internal *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent); + +/** + * Retrieves the scheme component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Retrieves the username component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_username(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Retrieves the password component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_password(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Retrieves the host component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_host(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Retrieves the port component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_LONG or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_port(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Retrieves the path component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_path(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Retrieves the query component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Retrieves the fragment component based on the read_mode and passes it to the zv ZVAL in case of success. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param internal_uri The internal URI whose uri member is used to retrieve the component + * @param read_mode The read mode + * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). + * @return SUCCESS in case of success, FAILURE otherwise. + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); + +/** + * Frees the uri member within the provided internal URI. + * + * @param internal_uri The internal URI + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(php_uri_internal *internal_uri); + +/** + * Creates a new php_uri struct containing all the URI components. The components are retrieved based on the read_mode parameter. + * + * Read_mode can be one of the following: + * - PHP_URI_COMPONENT_READ_MODE_RAW: Retrieves the raw, non-normalized variant of the URI component + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII: Retrieves the normalized variant of the requested URI component that must only contain ASCII characters + * - PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: Retrieves the normalized variant of the requested URI component that may contain Unicode codepoints + * + * @param uri_parser The URI parser whose parse() handler is called + * @param uri_str The input string that is going to be parsed + * @param uri_str_len Length of the input string + * @param read_mode The read mode based on which components are retrieved + * @param silent Whether to throw a Uri\InvalidUriException in case of failure + * @return The created php_uri struct in case of success, NULL otherwise + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri *php_uri_parse_to_struct( + const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, php_uri_component_read_mode read_mode, bool silent +); + +/** + * Frees the provided php_uri struct. + * + * @param uri The php_uri struct to free + */ +ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_struct_free(php_uri *uri); + +ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri( + INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const php_uri_object *base_url_object, + bool should_throw, bool should_update_this_object, zval *errors_zv +); #endif diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index ef49e4ba6f96..b0b83fcf83ec 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -1,6 +1,9 @@ function_table, "withuserinfo", sizeof("withuserinfo") - 1), 0, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); + + return class_entry; +} + static zend_class_entry *register_class_Uri_WhatWg_InvalidUrlException(zend_class_entry *class_entry_Uri_InvalidUriException) { zend_class_entry ce, *class_entry; @@ -211,9 +425,9 @@ static zend_class_entry *register_class_Uri_WhatWg_InvalidUrlException(zend_clas zval property_errors_default_value; ZVAL_UNDEF(&property_errors_default_value); - zend_string *property_errors_name = zend_string_init("errors", sizeof("errors") - 1, 1); + zend_string *property_errors_name = zend_string_init("errors", sizeof("errors") - 1, true); zend_declare_typed_property(class_entry, property_errors_name, &property_errors_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); - zend_string_release(property_errors_name); + zend_string_release_ex(property_errors_name, true); return class_entry; } @@ -292,9 +506,9 @@ static zend_class_entry *register_class_Uri_WhatWg_UrlValidationError(void) zval property_context_default_value; ZVAL_UNDEF(&property_context_default_value); - zend_string *property_context_name = zend_string_init("context", sizeof("context") - 1, 1); + zend_string *property_context_name = zend_string_init("context", sizeof("context") - 1, true); zend_declare_typed_property(class_entry, property_context_name, &property_context_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); - zend_string_release(property_context_name); + zend_string_release_ex(property_context_name, true); zval property_type_default_value; ZVAL_UNDEF(&property_type_default_value); @@ -303,9 +517,26 @@ static zend_class_entry *register_class_Uri_WhatWg_UrlValidationError(void) zval property_failure_default_value; ZVAL_UNDEF(&property_failure_default_value); - zend_string *property_failure_name = zend_string_init("failure", sizeof("failure") - 1, 1); + zend_string *property_failure_name = zend_string_init("failure", sizeof("failure") - 1, true); zend_declare_typed_property(class_entry, property_failure_name, &property_failure_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_BOOL)); - zend_string_release(property_failure_name); + zend_string_release_ex(property_failure_name, true); + + return class_entry; +} + +static zend_class_entry *register_class_Uri_WhatWg_UrlHostType(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\WhatWg\\UrlHostType", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "IPv4", NULL); + + zend_enum_add_case_cstr(class_entry, "IPv6", NULL); + + zend_enum_add_case_cstr(class_entry, "Domain", NULL); + + zend_enum_add_case_cstr(class_entry, "Opaque", NULL); + + zend_enum_add_case_cstr(class_entry, "Empty", NULL); return class_entry; } diff --git a/ext/uri/php_uri_common.c b/ext/uri/php_uri_common.c index 9128b942e57b..5d87b7847b34 100644 --- a/ext/uri/php_uri_common.c +++ b/ext/uri/php_uri_common.c @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -19,124 +17,98 @@ #include "Zend/zend_exceptions.h" #include "php_uri_common.h" -const uri_property_handler_t *uri_property_handler_from_internal_uri(const uri_internal_t *internal_uri, uri_property_name_t property_name) +static zend_string *get_known_string_by_property_name(php_uri_property_name property_name) { switch (property_name) { - case URI_PROPERTY_NAME_SCHEME: - return &internal_uri->handler->property_handlers.scheme; - case URI_PROPERTY_NAME_USERNAME: - return &internal_uri->handler->property_handlers.username; - case URI_PROPERTY_NAME_PASSWORD: - return &internal_uri->handler->property_handlers.password; - case URI_PROPERTY_NAME_HOST: - return &internal_uri->handler->property_handlers.host; - case URI_PROPERTY_NAME_PORT: - return &internal_uri->handler->property_handlers.port; - case URI_PROPERTY_NAME_PATH: - return &internal_uri->handler->property_handlers.path; - case URI_PROPERTY_NAME_QUERY: - return &internal_uri->handler->property_handlers.query; - case URI_PROPERTY_NAME_FRAGMENT: - return &internal_uri->handler->property_handlers.fragment; - EMPTY_SWITCH_DEFAULT_CASE() - } -} - -static zend_string *get_known_string_by_property_name(uri_property_name_t property_name) -{ - switch (property_name) { - case URI_PROPERTY_NAME_SCHEME: + case PHP_URI_PROPERTY_NAME_SCHEME: return ZSTR_KNOWN(ZEND_STR_SCHEME); - case URI_PROPERTY_NAME_USERNAME: + case PHP_URI_PROPERTY_NAME_USERNAME: return ZSTR_KNOWN(ZEND_STR_USERNAME); - case URI_PROPERTY_NAME_PASSWORD: + case PHP_URI_PROPERTY_NAME_PASSWORD: return ZSTR_KNOWN(ZEND_STR_PASSWORD); - case URI_PROPERTY_NAME_HOST: + case PHP_URI_PROPERTY_NAME_HOST: return ZSTR_KNOWN(ZEND_STR_HOST); - case URI_PROPERTY_NAME_PORT: + case PHP_URI_PROPERTY_NAME_PORT: return ZSTR_KNOWN(ZEND_STR_PORT); - case URI_PROPERTY_NAME_PATH: + case PHP_URI_PROPERTY_NAME_PATH: return ZSTR_KNOWN(ZEND_STR_PATH); - case URI_PROPERTY_NAME_QUERY: + case PHP_URI_PROPERTY_NAME_QUERY: return ZSTR_KNOWN(ZEND_STR_QUERY); - case URI_PROPERTY_NAME_FRAGMENT: + case PHP_URI_PROPERTY_NAME_FRAGMENT: return ZSTR_KNOWN(ZEND_STR_FRAGMENT); - EMPTY_SWITCH_DEFAULT_CASE() + default: ZEND_UNREACHABLE(); } } -void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name, uri_component_read_mode_t component_read_mode) +void php_uri_property_read_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode) { ZEND_PARSE_PARAMETERS_NONE(); - uri_internal_t *internal_uri = Z_URI_INTERNAL_P(ZEND_THIS); - URI_ASSERT_INITIALIZATION(internal_uri); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); - const uri_property_handler_t *property_handler = uri_property_handler_from_internal_uri(internal_uri, property_name); - ZEND_ASSERT(property_handler != NULL); + const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(uri_object->parser, property_name); - if (UNEXPECTED(property_handler->read_func(internal_uri, component_read_mode, return_value) == FAILURE)) { - zend_throw_error(NULL, "%s::$%s property cannot be retrieved", ZSTR_VAL(Z_OBJ_P(ZEND_THIS)->ce->name), - ZSTR_VAL(get_known_string_by_property_name(property_name))); + if (UNEXPECTED(property_handler->read(uri_object->uri, component_read_mode, return_value) == FAILURE)) { + zend_throw_exception_ex(php_uri_ce_error, 0, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); RETURN_THROWS(); } } -static void uri_write_component_ex(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name, zval *property_zv) +static void php_uri_property_write_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, zval *property_zv) { - uri_internal_t *internal_uri = Z_URI_INTERNAL_P(ZEND_THIS); - URI_ASSERT_INITIALIZATION(internal_uri); + php_uri_object *old_uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(old_uri_object->uri != NULL); - const uri_property_handler_t *property_handler = uri_property_handler_from_internal_uri(internal_uri, property_name); - ZEND_ASSERT(property_handler != NULL); - - zend_object *new_object = uri_clone_obj_handler(Z_OBJ_P(ZEND_THIS)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_object_release(new_object); + zend_object *new_object = old_uri_object->std.handlers->clone_obj(&old_uri_object->std); + if (new_object == NULL) { RETURN_THROWS(); } - uri_internal_t *new_internal_uri = uri_internal_from_obj(new_object); - URI_ASSERT_INITIALIZATION(new_internal_uri); - if (property_handler->write_func == NULL) { - zend_readonly_property_modification_error_ex(ZSTR_VAL(Z_OBJ_P(ZEND_THIS)->ce->name), + /* Assign the object early. The engine will take care of destruction in + * case of an exception being thrown. */ + RETVAL_OBJ(new_object); + + const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(old_uri_object->parser, property_name); + + php_uri_object *new_uri_object = php_uri_object_from_obj(new_object); + ZEND_ASSERT(new_uri_object->uri != NULL); + if (UNEXPECTED(property_handler->write == NULL)) { + zend_readonly_property_modification_error_ex(ZSTR_VAL(old_uri_object->std.ce->name), ZSTR_VAL(get_known_string_by_property_name(property_name))); - zend_object_release(new_object); RETURN_THROWS(); } zval errors; ZVAL_UNDEF(&errors); - if (property_handler->write_func(new_internal_uri, property_zv, &errors) == FAILURE) { + if (UNEXPECTED(property_handler->write(new_uri_object->uri, property_zv, &errors) == FAILURE)) { zval_ptr_dtor(&errors); - zend_object_release(new_object); RETURN_THROWS(); } ZEND_ASSERT(Z_ISUNDEF(errors)); - RETVAL_OBJ(new_object); } -void uri_write_component_str(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name) +void php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) { zend_string *value; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH_STR(value) + Z_PARAM_STR(value) ZEND_PARSE_PARAMETERS_END(); zval zv; ZVAL_STR(&zv, value); - uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); + php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); } -void uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name) +void php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) { zend_string *value; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_PATH_STR_OR_NULL(value) + Z_PARAM_STR_OR_NULL(value) ZEND_PARSE_PARAMETERS_END(); zval zv; @@ -146,10 +118,10 @@ void uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAMETERS, uri_property_ ZVAL_STR(&zv, value); } - uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); + php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); } -void uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name) +void php_uri_property_write_long_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) { zend_long value; bool value_is_null; @@ -165,5 +137,5 @@ void uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAMETERS, uri_property ZVAL_LONG(&zv, value); } - uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); + php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); } diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index 1aee1cd51247..c9f5e81075fe 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -1,14 +1,12 @@ /* +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | + | Copyright © The PHP Group and Contributors. | +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | https://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | + | This source file is subject to the Modified BSD License that is | + | bundled with this package in the file LICENSE, and is available | + | through the World Wide Web at . | + | | + | SPDX-License-Identifier: BSD-3-Clause | +----------------------------------------------------------------------+ | Authors: Máté Kocsis | +----------------------------------------------------------------------+ @@ -17,67 +15,62 @@ #ifndef PHP_URI_COMMON_H #define PHP_URI_COMMON_H -extern zend_class_entry *uri_whatwg_url_ce; -extern zend_object_handlers uri_whatwg_uri_object_handlers; -extern zend_class_entry *uri_comparison_mode_ce; -extern zend_class_entry *uri_exception_ce; -extern zend_class_entry *uri_invalid_uri_exception_ce; -extern zend_class_entry *uri_whatwg_invalid_url_exception_ce; -extern zend_class_entry *uri_whatwg_url_validation_error_type_ce; -extern zend_class_entry *uri_whatwg_url_validation_error_ce; -extern zend_object *uri_clone_obj_handler(zend_object *object); - -typedef enum { - URI_RECOMPOSITION_RAW_ASCII, - URI_RECOMPOSITION_RAW_UNICODE, - URI_RECOMPOSITION_NORMALIZED_ASCII, - URI_RECOMPOSITION_NORMALIZED_UNICODE, -} uri_recomposition_mode_t; - -typedef enum { - URI_COMPONENT_READ_RAW, - URI_COMPONENT_READ_NORMALIZED_ASCII, - URI_COMPONENT_READ_NORMALIZED_UNICODE, -} uri_component_read_mode_t; - -struct uri_internal_t; - -typedef zend_result (*uri_read_t)(const struct uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval); - -typedef zend_result (*uri_write_t)(struct uri_internal_t *internal_uri, zval *value, zval *errors); - -typedef enum { - URI_PROPERTY_NAME_SCHEME, - URI_PROPERTY_NAME_USERNAME, - URI_PROPERTY_NAME_PASSWORD, - URI_PROPERTY_NAME_HOST, - URI_PROPERTY_NAME_PORT, - URI_PROPERTY_NAME_PATH, - URI_PROPERTY_NAME_QUERY, - URI_PROPERTY_NAME_FRAGMENT, -} uri_property_name_t; - -typedef struct uri_property_handler_t { - uri_read_t read_func; - uri_write_t write_func; -} uri_property_handler_t; - -typedef struct uri_property_handlers_t { - uri_property_handler_t scheme; - uri_property_handler_t username; - uri_property_handler_t password; - uri_property_handler_t host; - uri_property_handler_t port; - uri_property_handler_t path; - uri_property_handler_t query; - uri_property_handler_t fragment; -} uri_property_handlers_t; - -typedef struct uri_handler_t { +#include "php_uri_decl.h" + +extern zend_class_entry *php_uri_ce_rfc3986_uri; +extern zend_class_entry *php_uri_ce_rfc3986_uri_type; +extern zend_class_entry *php_uri_ce_rfc3986_uri_host_type; +extern zend_class_entry *php_uri_ce_whatwg_url; +extern zend_class_entry *php_uri_ce_comparison_mode; +extern zend_class_entry *php_uri_ce_exception; +extern zend_class_entry *php_uri_ce_error; +extern zend_class_entry *php_uri_ce_invalid_uri_exception; +extern zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; +extern zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; +extern zend_class_entry *php_uri_ce_whatwg_url_validation_error; +extern zend_class_entry *php_uri_ce_whatwg_url_host_type; + +typedef enum php_uri_recomposition_mode { + PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, + PHP_URI_RECOMPOSITION_MODE_RAW_UNICODE, + PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII, + PHP_URI_RECOMPOSITION_MODE_NORMALIZED_UNICODE, +} php_uri_recomposition_mode; + +typedef enum php_uri_component_read_mode { + PHP_URI_COMPONENT_READ_MODE_RAW, + PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, + PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE, +} php_uri_component_read_mode; + +typedef zend_result (*php_uri_property_handler_read)(void *uri, php_uri_component_read_mode read_mode, zval *retval); + +typedef zend_result (*php_uri_property_handler_write)(void *uri, zval *value, zval *errors); + +typedef enum php_uri_property_name { + PHP_URI_PROPERTY_NAME_SCHEME, + PHP_URI_PROPERTY_NAME_USERNAME, + PHP_URI_PROPERTY_NAME_PASSWORD, + PHP_URI_PROPERTY_NAME_HOST, + PHP_URI_PROPERTY_NAME_PORT, + PHP_URI_PROPERTY_NAME_PATH, + PHP_URI_PROPERTY_NAME_QUERY, + PHP_URI_PROPERTY_NAME_FRAGMENT, +} php_uri_property_name; + +typedef struct php_uri_property_handler { + php_uri_property_handler_read read; + php_uri_property_handler_write write; +} php_uri_property_handler; + +typedef struct php_uri_parser { + /** + * Name (the FQCN) of the URI parser. The "" name is reserved for the handler of the legacy parse_url(). + */ const char *name; /** - * Parse a URI string into a URI. + * Parses a URI string into a URI. * * If the URI string is valid, a URI is returned. In case of failure, NULL is * returned. @@ -91,48 +84,112 @@ typedef struct uri_handler_t { * * If the silent parameter is true, a Uri\InvalidUriException instance must be thrown. * If the parameter is false, the possible errors should be handled by the caller. + * + * @param uri_str The input string that is going to be parsed + * @param uri_str_len Length of the input string + * @param base_url The base URI if reference resolution should be performed, otherwise NULL + * @param errors An out parameter that stores additional error information + * @param silent Whether to throw a Uri\InvalidUriException in case of failure */ - void *(*parse_uri)(const zend_string *uri_str, const void *base_url, zval *errors, bool silent); - void *(*clone_uri)(void *uri); - zend_string *(*uri_to_string)(void *uri, uri_recomposition_mode_t recomposition_mode, bool exclude_fragment); - void (*free_uri)(void *uri); + void *(*parse)(const char *uri_str, size_t uri_str_len, const void *base_url, zval *errors, bool silent); - const uri_property_handlers_t property_handlers; -} uri_handler_t; + /** + * Clones a URI to a new URI. + * + * A deep-clone must be performed that copies all pointer members to a new memory address. + * @param uri The input URI + * @return The cloned URI + */ + void *(*clone)(void *uri); + + /** + * Recomposes a URI as a string according to the recomposition_mode and exclude_fragment parameters. + * The returned zend_string must not be persistent. + * + * Recomposition_mode can be one of the following: + * - PHP_URI_RECOMPOSITION_MODE_RAW_ASCII: Recomposes the raw, non-normalized variant of the URI as a string that must only contain ASCII characters + * - PHP_URI_RECOMPOSITION_MODE_RAW_UNICODE: Recomposes the raw, non-normalized variant of the URI as a string that may contain Unicode codepoints + * - PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII: Recomposes the normalized variant of the URI as a string that must only contain ASCII characters + * - PHP_URI_RECOMPOSITION_MODE_NORMALIZED_UNICODE: Recomposes the normalized variant of the URI as a string that may contain Unicode codepoints + * + * @param uri The input URI + * @param recomposition_mode The type of recomposition + * @param exclude_fragment Whether the fragment component should be part of the recomposed URI + * @return The recomposed URI as a non-persistent zend_string + */ + zend_string *(*to_string)(void *uri, php_uri_recomposition_mode recomposition_mode, bool exclude_fragment); -typedef struct uri_internal_t { - const uri_handler_t *handler; + /** + * Destroy (free) the provided URI. + * + * @param uri The URI to free. Must do nothing if NULL. + */ + void (*destroy)(void *uri); + + struct { + php_uri_property_handler scheme; + php_uri_property_handler username; + php_uri_property_handler password; + php_uri_property_handler host; + php_uri_property_handler port; + php_uri_property_handler path; + php_uri_property_handler query; + php_uri_property_handler fragment; + } property_handler; +} php_uri_parser; + +typedef struct php_uri_internal { + const php_uri_parser *parser; void *uri; -} uri_internal_t; +} php_uri_internal; -typedef struct uri_object_t { - uri_internal_t internal; +typedef struct php_uri_object { + const php_uri_parser *parser; + void *uri; zend_object std; -} uri_object_t; +} php_uri_object; -static inline uri_object_t *uri_object_from_obj(const zend_object *object) { - return (uri_object_t*)((char*)(object) - XtOffsetOf(uri_object_t, std)); +static inline php_uri_object *php_uri_object_from_obj(zend_object *object) { + return ZEND_CONTAINER_OF(object, php_uri_object, std); } -static inline uri_internal_t *uri_internal_from_obj(const zend_object *object) { - return &(uri_object_from_obj(object)->internal); +#define Z_URI_OBJECT_P(zv) php_uri_object_from_obj(Z_OBJ_P((zv))) + +PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser); +PHPAPI void php_uri_object_handler_free(zend_object *object); +PHPAPI zend_object *php_uri_object_handler_clone(zend_object *object); + +#define PHP_URI_PARSER_RFC3986 "Uri\\Rfc3986\\Uri" +#define PHP_URI_PARSER_WHATWG "Uri\\WhatWg\\Url" +#define PHP_URI_PARSER_PHP_PARSE_URL "parse_url" +#define PHP_URI_SERIALIZE_URI_FIELD_NAME "uri" + +static inline const php_uri_property_handler *php_uri_parser_property_handler_by_name(const php_uri_parser *parser, php_uri_property_name property_name) +{ + switch (property_name) { + case PHP_URI_PROPERTY_NAME_SCHEME: + return &parser->property_handler.scheme; + case PHP_URI_PROPERTY_NAME_USERNAME: + return &parser->property_handler.username; + case PHP_URI_PROPERTY_NAME_PASSWORD: + return &parser->property_handler.password; + case PHP_URI_PROPERTY_NAME_HOST: + return &parser->property_handler.host; + case PHP_URI_PROPERTY_NAME_PORT: + return &parser->property_handler.port; + case PHP_URI_PROPERTY_NAME_PATH: + return &parser->property_handler.path; + case PHP_URI_PROPERTY_NAME_QUERY: + return &parser->property_handler.query; + case PHP_URI_PROPERTY_NAME_FRAGMENT: + return &parser->property_handler.fragment; + default: ZEND_UNREACHABLE(); + } } -#define Z_URI_OBJECT_P(zv) uri_object_from_obj(Z_OBJ_P((zv))) -#define Z_URI_INTERNAL_P(zv) uri_internal_from_obj(Z_OBJ_P((zv))) - -#define URI_PARSER_WHATWG "Uri\\WhatWg\\Url" -#define URI_SERIALIZED_PROPERTY_NAME "uri" - -zend_result uri_handler_register(const uri_handler_t *uri_handler); -const uri_property_handler_t *uri_property_handler_from_internal_uri(const uri_internal_t *internal_uri, uri_property_name_t property_name); -void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name, uri_component_read_mode_t component_read_mode); -void uri_write_component_str(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name); -void uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name); -void uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAMETERS, uri_property_name_t property_name); - -#define URI_ASSERT_INITIALIZATION(internal_uri) do { \ - ZEND_ASSERT(internal_uri != NULL && internal_uri->uri != NULL); \ -} while (0) +void php_uri_property_read_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode); +void php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); +void php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); +void php_uri_property_write_long_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); #endif diff --git a/ext/uri/php_uri_decl.h b/ext/uri/php_uri_decl.h new file mode 100644 index 000000000000..d1fd58d04b2c --- /dev/null +++ b/ext/uri/php_uri_decl.h @@ -0,0 +1,66 @@ +/* This is a generated file, edit php_uri.stub.php instead. + * Stub hash: a3b4696ac001d537cc34b818715c7eb382c17c5b */ + +#ifndef ZEND_PHP_URI_DECL_a3b4696ac001d537cc34b818715c7eb382c17c5b_H +#define ZEND_PHP_URI_DECL_a3b4696ac001d537cc34b818715c7eb382c17c5b_H + +typedef enum zend_enum_Uri_UriComparisonMode { + ZEND_ENUM_Uri_UriComparisonMode_IncludeFragment = 1, + ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment = 2, +} zend_enum_Uri_UriComparisonMode; + +typedef enum zend_enum_Uri_Rfc3986_UriType { + ZEND_ENUM_Uri_Rfc3986_UriType_AbsolutePathReference = 1, + ZEND_ENUM_Uri_Rfc3986_UriType_RelativePathReference = 2, + ZEND_ENUM_Uri_Rfc3986_UriType_NetworkPathReference = 3, + ZEND_ENUM_Uri_Rfc3986_UriType_Uri = 4, +} zend_enum_Uri_Rfc3986_UriType; + +typedef enum zend_enum_Uri_Rfc3986_UriHostType { + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv4 = 1, + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv6 = 2, + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPvFuture = 3, + ZEND_ENUM_Uri_Rfc3986_UriHostType_RegisteredName = 4, +} zend_enum_Uri_Rfc3986_UriHostType; + +typedef enum zend_enum_Uri_WhatWg_UrlValidationErrorType { + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToAscii = 1, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToUnicode = 2, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainInvalidCodePoint = 3, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_HostInvalidCodePoint = 4, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4EmptyPart = 5, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4TooManyParts = 6, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4NonNumericPart = 7, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4NonDecimalPart = 8, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4OutOfRangePart = 9, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv6Unclosed = 10, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv6InvalidCompression = 11, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv6TooManyPieces = 12, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv6MultipleCompression = 13, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv6InvalidCodePoint = 14, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv6TooFewPieces = 15, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4InIpv6TooManyPieces = 16, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4InIpv6InvalidCodePoint = 17, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4InIpv6OutOfRangePart = 18, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_Ipv4InIpv6TooFewParts = 19, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_InvalidUrlUnit = 20, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_SpecialSchemeMissingFollowingSolidus = 21, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_MissingSchemeNonRelativeUrl = 22, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_InvalidReverseSoldius = 23, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_InvalidCredentials = 24, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_HostMissing = 25, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_PortOutOfRange = 26, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_PortInvalid = 27, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_FileInvalidWindowsDriveLetter = 28, + ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_FileInvalidWindowsDriveLetterHost = 29, +} zend_enum_Uri_WhatWg_UrlValidationErrorType; + +typedef enum zend_enum_Uri_WhatWg_UrlHostType { + ZEND_ENUM_Uri_WhatWg_UrlHostType_IPv4 = 1, + ZEND_ENUM_Uri_WhatWg_UrlHostType_IPv6 = 2, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Domain = 3, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Opaque = 4, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Empty = 5, +} zend_enum_Uri_WhatWg_UrlHostType; + +#endif /* ZEND_PHP_URI_DECL_a3b4696ac001d537cc34b818715c7eb382c17c5b_H */ diff --git a/ext/uri/tests/003.phpt b/ext/uri/tests/003.phpt index bcd6e417441c..a1918f7a838b 100644 --- a/ext/uri/tests/003.phpt +++ b/ext/uri/tests/003.phpt @@ -1,16 +1,21 @@ --TEST-- -Parse URL exotic URLs +Parse special URIs --EXTENSIONS-- uri --FILE-- --EXPECTF-- +NULL object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(4) "http" @@ -29,4 +34,58 @@ object(Uri\WhatWg\Url)#%d (%d) { ["fragment"]=> string(6) "anchor" } +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(7) "host123" + ["port"]=> + NULL + ["path"]=> + string(1) "/" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(0) "" + ["port"]=> + NULL + ["path"]=> + string(5) "/foo/" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(7) "/page:1" + ["query"]=> + NULL + ["fragment"]=> + NULL +} NULL diff --git a/ext/uri/tests/004.phpt b/ext/uri/tests/004.phpt index abbad59fee2e..d22f52f30c48 100644 --- a/ext/uri/tests/004.phpt +++ b/ext/uri/tests/004.phpt @@ -5,6 +5,9 @@ uri --FILE-- ---EXPECT-- +--EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} The specified URI is malformed (MissingSchemeNonRelativeUrl) NULL +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + NULL + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(20) "192.168/contact.html" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +NULL NULL NULL diff --git a/ext/uri/tests/005.phpt b/ext/uri/tests/005.phpt index 262d43a75406..6db6c4a56ee5 100644 --- a/ext/uri/tests/005.phpt +++ b/ext/uri/tests/005.phpt @@ -5,6 +5,8 @@ uri --FILE-- getAsciiHost()); @@ -14,6 +16,7 @@ var_dump($url->toUnicodeString()); ?> --EXPECTF-- +NULL object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(4) "http" diff --git a/ext/uri/tests/006.phpt b/ext/uri/tests/006.phpt index 0aba3e9e46b5..c4da9db905c8 100644 --- a/ext/uri/tests/006.phpt +++ b/ext/uri/tests/006.phpt @@ -5,11 +5,32 @@ uri --FILE-- --EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(5) "https" + ["username"]=> + string(8) "username" + ["password"]=> + string(8) "password" + ["host"]=> + string(11) "example.com" + ["port"]=> + int(8080) + ["path"]=> + string(5) "/path" + ["query"]=> + string(3) "q=r" + ["fragment"]=> + string(8) "fragment" +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(5) "https" diff --git a/ext/uri/tests/007.phpt b/ext/uri/tests/007.phpt index cb445fcf71a4..54151f2dfcb1 100644 --- a/ext/uri/tests/007.phpt +++ b/ext/uri/tests/007.phpt @@ -5,6 +5,12 @@ uri --FILE-- getMessage() . "\n"; +} + try { new Uri\WhatWg\Url("https://example.com:8080@username:password/path?q=r#fragment"); } catch (Uri\WhatWg\InvalidUrlException $e) { @@ -19,6 +25,7 @@ var_dump($failures); ?> --EXPECTF-- +The specified URI is malformed The specified URI is malformed (PortInvalid) array(%d) { [0]=> diff --git a/ext/uri/tests/008.phpt b/ext/uri/tests/008.phpt index f4fddcd8eb77..133f225aabf4 100644 --- a/ext/uri/tests/008.phpt +++ b/ext/uri/tests/008.phpt @@ -5,6 +5,27 @@ uri --FILE-- getScheme()); + var_dump($uri->getRawScheme()); + var_dump($uri->getUsername()); + var_dump($uri->getRawUsername()); + var_dump($uri->getPassword()); + var_dump($uri->getRawPassword()); + var_dump($uri->getUserInfo()); + var_dump($uri->getRawUserInfo()); + var_dump($uri->getHost()); + var_dump($uri->getRawHost()); + var_dump($uri->getPort()); + var_dump($uri->getPath()); + var_dump($uri->getRawPath()); + var_dump($uri->getQuery()); + var_dump($uri->getRawQuery()); + var_dump($uri->getFragment()); + var_dump($uri->getRawFragment()); +} + function callWhatWgGetters($url) { var_dump($url->getScheme()); @@ -18,16 +39,39 @@ function callWhatWgGetters($url) var_dump($url->getFragment()); } -$url = Uri\WhatWg\Url::parse("https://username:password@www.google.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); +$uri = Uri\Rfc3986\Uri::parse("https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); +callRfc3986Getters($uri); + +echo "\n"; + +$url = Uri\WhatWg\Url::parse("https://username:password@www.example.com:8080/pathname1/pathname2/pathname3?query=true#hash-exists"); callWhatWgGetters($url); ?> --EXPECT-- +string(5) "https" +string(5) "https" +string(8) "username" +string(8) "username" +string(8) "password" +string(8) "password" +string(17) "username:password" +string(17) "username:password" +string(15) "www.example.com" +string(15) "www.example.com" +int(8080) +string(30) "/pathname1/pathname2/pathname3" +string(30) "/pathname1/pathname2/pathname3" +string(10) "query=true" +string(10) "query=true" +string(11) "hash-exists" +string(11) "hash-exists" + string(5) "https" string(8) "username" string(8) "password" -string(14) "www.google.com" -string(14) "www.google.com" +string(15) "www.example.com" +string(15) "www.example.com" int(8080) string(30) "/pathname1/pathname2/pathname3" string(10) "query=true" diff --git a/ext/uri/tests/009.phpt b/ext/uri/tests/009.phpt index 1b279588c016..05f2820bb3fc 100644 --- a/ext/uri/tests/009.phpt +++ b/ext/uri/tests/009.phpt @@ -5,10 +5,29 @@ uri --FILE-- --EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(16) "chrome-extension" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "example.com" + ["port"]=> + NULL + ["path"]=> + string(0) "" + ["query"]=> + NULL + ["fragment"]=> + NULL +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(16) "chrome-extension" diff --git a/ext/uri/tests/010.phpt b/ext/uri/tests/010.phpt index 4ec13f652f60..2ca071eb2ca3 100644 --- a/ext/uri/tests/010.phpt +++ b/ext/uri/tests/010.phpt @@ -5,11 +5,49 @@ uri --FILE-- --EXPECTF-- +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(4) "http" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(11) "example.com" + ["port"]=> + NULL + ["path"]=> + string(14) "/path/to/file2" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { + ["scheme"]=> + string(5) "https" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(8) "test.com" + ["port"]=> + NULL + ["path"]=> + string(14) "/path/to/file2" + ["query"]=> + NULL + ["fragment"]=> + NULL +} object(Uri\WhatWg\Url)#%d (%d) { ["scheme"]=> string(4) "http" diff --git a/ext/uri/tests/011.phpt b/ext/uri/tests/011.phpt index 283886fb34fb..49b915fa22a3 100644 --- a/ext/uri/tests/011.phpt +++ b/ext/uri/tests/011.phpt @@ -5,6 +5,12 @@ uri --FILE-- toRawString()); +var_dump(Uri\Rfc3986\Uri::parse("https://www.example.com/dir1/../dir2")->toRawString()); +var_dump(Uri\Rfc3986\Uri::parse("https://你好你好")); +var_dump(Uri\Rfc3986\Uri::parse("https://0Xc0.0250.01")); +var_dump(Uri\Rfc3986\Uri::parse("HttPs://0300.0250.0000.0001/path?query=foo%20bar")->toRawString()); + var_dump(Uri\WhatWg\Url::parse("http://////www.EXAMPLE.com:80")->toAsciiString()); var_dump(Uri\WhatWg\Url::parse("https://www.example.com:443/dir1/../dir2")->toAsciiString()); var_dump(Uri\WhatWg\Url::parse("https://你好你好")->toAsciiString()); @@ -14,6 +20,11 @@ var_dump(Uri\WhatWg\Url::parse("HttPs://0300.0250.0000.0001/path?query=foo%20bar ?> --EXPECT-- +string(29) "http://////www.EXAMPLE.com:80" +string(36) "https://www.example.com/dir1/../dir2" +NULL +NULL +string(48) "HttPs://0300.0250.0000.0001/path?query=foo%20bar" string(23) "http://www.example.com/" string(28) "https://www.example.com/dir2" string(23) "https://xn--6qqa088eba/" diff --git a/ext/uri/tests/012.phpt b/ext/uri/tests/012.phpt index 0784a74e625f..3eb343af535c 100644 --- a/ext/uri/tests/012.phpt +++ b/ext/uri/tests/012.phpt @@ -5,13 +5,15 @@ uri --FILE-- --EXPECTF-- -object(Uri\WhatWg\Url)#%d (%d) { +object(Uri\Rfc3986\Uri)#%d (%d) { ["scheme"]=> string(6) "mailto" ["username"]=> @@ -30,6 +32,24 @@ object(Uri\WhatWg\Url)#%d (%d) { NULL } object(Uri\WhatWg\Url)#%d (%d) { + ["scheme"]=> + string(6) "mailto" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + NULL + ["port"]=> + NULL + ["path"]=> + string(15) "Joe@Example.COM" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\Rfc3986\Uri)#%d (%d) { ["scheme"]=> string(4) "file" ["username"]=> @@ -37,7 +57,25 @@ object(Uri\WhatWg\Url)#%d (%d) { ["password"]=> NULL ["host"]=> + string(0) "" + ["port"]=> NULL + ["path"]=> + string(30) "/E:/Documents%20and%20Settings" + ["query"]=> + NULL + ["fragment"]=> + NULL +} +object(Uri\WhatWg\Url)#%d (%d) { + ["scheme"]=> + string(4) "file" + ["username"]=> + NULL + ["password"]=> + NULL + ["host"]=> + string(0) "" ["port"]=> NULL ["path"]=> diff --git a/ext/uri/tests/013.phpt b/ext/uri/tests/013.phpt index 016fe6632782..6a5bb31870fb 100644 --- a/ext/uri/tests/013.phpt +++ b/ext/uri/tests/013.phpt @@ -5,14 +5,39 @@ uri --FILE-- + @")); + var_dump(Uri\WhatWg\Url::parse("http://example.com?foobar=%27%3Cscript%3E+%2B+%40")); var_dump(Uri\WhatWg\Url::parse("http://example.com?foobar='', 'query' => ''], + ['uri' => '/status', 'query' => 'full&html', 'delay' => 100000], + ]); +var_dump(strpos($responses[1]->getBody(), '